From 80d09acfca31dffb14f6f79e64b3b7ca98ff869c Mon Sep 17 00:00:00 2001 From: Markus Becker Date: Thu, 25 Sep 2025 11:03:50 +0200 Subject: [PATCH 0001/3659] drivers: Typo in Interrupt Trivial typo fix. Signed-off-by: Markus Becker --- drivers/interrupt_controller/Kconfig.clic | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/interrupt_controller/Kconfig.clic b/drivers/interrupt_controller/Kconfig.clic index aba90ff0086e..1bae5b36ebe3 100644 --- a/drivers/interrupt_controller/Kconfig.clic +++ b/drivers/interrupt_controller/Kconfig.clic @@ -22,7 +22,7 @@ config NUCLEI_ECLIC Interrupt controller for Nuclei SoC core. config NRFX_CLIC - bool "VPR Core Local Interrpt Controller (CLIC)" + bool "VPR Core Local Interrupt Controller (CLIC)" default y depends on DT_HAS_NORDIC_NRF_CLIC_ENABLED select GEN_IRQ_VECTOR_TABLE From 336a25c1eba3ddd004c1bc773cc36e53d5581257 Mon Sep 17 00:00:00 2001 From: Peter Wang Date: Thu, 4 Dec 2025 10:29:25 +0800 Subject: [PATCH 0002/3659] drivers: hwinfo: add mcxa577 support into mcux_mcx_cmc 1. add mcxa577 support into hwinfo_mcux_mcx_cmc Signed-off-by: Peter Wang --- drivers/hwinfo/hwinfo_mcux_mcx_cmc.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/hwinfo/hwinfo_mcux_mcx_cmc.c b/drivers/hwinfo/hwinfo_mcux_mcx_cmc.c index d3bb2bc57300..7e7fc58824f2 100644 --- a/drivers/hwinfo/hwinfo_mcux_mcx_cmc.c +++ b/drivers/hwinfo/hwinfo_mcux_mcx_cmc.c @@ -24,7 +24,11 @@ LOG_MODULE_REGISTER(hwinfo_cmc, CONFIG_HWINFO_LOG_LEVEL); #ifdef CMC_SRS_WWDT1_MASK #define CMC_RESET_MASK_WATCHDOG (CMC_SRS_WWDT0_MASK | CMC_SRS_WWDT1_MASK) #else +#ifdef CMC_SRS_WWDT0_MASK #define CMC_RESET_MASK_WATCHDOG CMC_SRS_WWDT0_MASK +#else +#define CMC_RESET_MASK_WATCHDOG CMC_SRS_WDOG0_MASK +#endif #endif #ifdef CMC_SRS_CDOG1_MASK @@ -33,6 +37,12 @@ LOG_MODULE_REGISTER(hwinfo_cmc, CONFIG_HWINFO_LOG_LEVEL); #define CMC_RESET_MASK_CDOG CMC_SRS_CDOG0_MASK #endif +#ifdef CMC_SRS_VD_MASK +#define CMC_RESET_MASK_BROWNOUT CMC_SRS_VD_MASK +#else +#define CMC_RESET_MASK_BROWNOUT CMC_SRS_LVD_MASK +#endif + /** * @brief Translate from CMC reset source mask to Zephyr hwinfo sources mask. * @@ -55,7 +65,7 @@ static uint32_t hwinfo_mcux_cmc_xlate_reset_sources(uint32_t sources) mask |= RESET_POR; } - if (sources & CMC_SRS_VD_MASK) { + if (sources & CMC_RESET_MASK_BROWNOUT) { mask |= RESET_BROWNOUT; } From a249d79afe99bd25c590ddcdd86f8b7e3347da84 Mon Sep 17 00:00:00 2001 From: Peter Wang Date: Thu, 20 Nov 2025 11:55:37 +0800 Subject: [PATCH 0003/3659] boards: frdm_mcxa577: add frdm_mcxa577 board 1. add soc mcxa577 2. add board frdm_mcxa577 Signed-off-by: Peter Wang --- boards/nxp/frdm_mcxa577/CMakeLists.txt | 8 + boards/nxp/frdm_mcxa577/Kconfig | 5 + boards/nxp/frdm_mcxa577/Kconfig.frdm_mcxa577 | 6 + boards/nxp/frdm_mcxa577/board.c | 152 ++++ boards/nxp/frdm_mcxa577/board.cmake | 13 + boards/nxp/frdm_mcxa577/board.yml | 6 + boards/nxp/frdm_mcxa577/doc/frdm_mcxa577.webp | Bin 0 -> 63790 bytes boards/nxp/frdm_mcxa577/doc/index.rst | 160 ++++ .../frdm_mcxa577/frdm_mcxa577-pinctrl.dtsi | 18 + boards/nxp/frdm_mcxa577/frdm_mcxa577.dts | 156 ++++ boards/nxp/frdm_mcxa577/frdm_mcxa577.yaml | 19 + .../nxp/frdm_mcxa577/frdm_mcxa577_defconfig | 18 + dts/arm/nxp/nxp_mcxa5x.dtsi | 26 + dts/arm/nxp/nxp_mcxa5x_common.dtsi | 733 ++++++++++++++++++ dts/arm/nxp/nxp_mcxa5x_ns.dtsi | 26 + .../dt-bindings/clock/mcux_lpc_syscon_clock.h | 8 + soc/nxp/mcx/mcxa/Kconfig | 9 + soc/nxp/mcx/mcxa/Kconfig.defconfig | 1 + soc/nxp/mcx/mcxa/Kconfig.soc | 17 + soc/nxp/mcx/soc.yml | 5 + 20 files changed, 1386 insertions(+) create mode 100644 boards/nxp/frdm_mcxa577/CMakeLists.txt create mode 100644 boards/nxp/frdm_mcxa577/Kconfig create mode 100644 boards/nxp/frdm_mcxa577/Kconfig.frdm_mcxa577 create mode 100644 boards/nxp/frdm_mcxa577/board.c create mode 100644 boards/nxp/frdm_mcxa577/board.cmake create mode 100644 boards/nxp/frdm_mcxa577/board.yml create mode 100644 boards/nxp/frdm_mcxa577/doc/frdm_mcxa577.webp create mode 100644 boards/nxp/frdm_mcxa577/doc/index.rst create mode 100644 boards/nxp/frdm_mcxa577/frdm_mcxa577-pinctrl.dtsi create mode 100644 boards/nxp/frdm_mcxa577/frdm_mcxa577.dts create mode 100644 boards/nxp/frdm_mcxa577/frdm_mcxa577.yaml create mode 100644 boards/nxp/frdm_mcxa577/frdm_mcxa577_defconfig create mode 100644 dts/arm/nxp/nxp_mcxa5x.dtsi create mode 100644 dts/arm/nxp/nxp_mcxa5x_common.dtsi create mode 100644 dts/arm/nxp/nxp_mcxa5x_ns.dtsi diff --git a/boards/nxp/frdm_mcxa577/CMakeLists.txt b/boards/nxp/frdm_mcxa577/CMakeLists.txt new file mode 100644 index 000000000000..c06b9273965c --- /dev/null +++ b/boards/nxp/frdm_mcxa577/CMakeLists.txt @@ -0,0 +1,8 @@ +# +# Copyright 2025 NXP +# +# SPDX-License-Identifier: Apache-2.0 +# + +zephyr_library() +zephyr_library_sources(board.c) diff --git a/boards/nxp/frdm_mcxa577/Kconfig b/boards/nxp/frdm_mcxa577/Kconfig new file mode 100644 index 000000000000..d7c509900da3 --- /dev/null +++ b/boards/nxp/frdm_mcxa577/Kconfig @@ -0,0 +1,5 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_FRDM_MCXA577 + select BOARD_EARLY_INIT_HOOK diff --git a/boards/nxp/frdm_mcxa577/Kconfig.frdm_mcxa577 b/boards/nxp/frdm_mcxa577/Kconfig.frdm_mcxa577 new file mode 100644 index 000000000000..f27d6eff76fc --- /dev/null +++ b/boards/nxp/frdm_mcxa577/Kconfig.frdm_mcxa577 @@ -0,0 +1,6 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_FRDM_MCXA577 + select SOC_MCXA577 + select SOC_PART_NUMBER_MCXA577VLL diff --git a/boards/nxp/frdm_mcxa577/board.c b/boards/nxp/frdm_mcxa577/board.c new file mode 100644 index 000000000000..f54374693bea --- /dev/null +++ b/boards/nxp/frdm_mcxa577/board.c @@ -0,0 +1,152 @@ +/* + * Copyright 2025 NXP + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include +#include +#include +#include + +/* Core clock frequency: 12MHz in FPGA */ +#define CLOCK_INIT_CORE_CLOCK 12000000U +/* System clock frequency. */ +extern uint32_t SystemCoreClock; + +void board_early_init_hook(void) +{ + /* Get the CPU Core frequency */ + CLOCK_SetupFRO12MClocking(); + CLOCK_AttachClk(kFRO12M_to_MAIN_CLK); + CLOCK_SetClockDiv(kCLOCK_DivFRO_HF, 1); + CLOCK_SetClockDiv(kCLOCK_DivFRO_LF, 1); + +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(porta)) + RESET_ReleasePeripheralReset(kPORT0_RST_SHIFT_RSTn); + CLOCK_EnableClock(kCLOCK_GatePORT0); +#endif + +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(portb)) + RESET_ReleasePeripheralReset(kPORT1_RST_SHIFT_RSTn); + CLOCK_EnableClock(kCLOCK_GatePORT1); +#endif + +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(portc)) + RESET_ReleasePeripheralReset(kPORT2_RST_SHIFT_RSTn); + CLOCK_EnableClock(kCLOCK_GatePORT2); +#endif + +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(portd)) + RESET_ReleasePeripheralReset(kPORT3_RST_SHIFT_RSTn); + CLOCK_EnableClock(kCLOCK_GatePORT3); +#endif + +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(porte)) + RESET_ReleasePeripheralReset(kPORT4_RST_SHIFT_RSTn); + CLOCK_EnableClock(kCLOCK_GatePORT4); +#endif + +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(portf)) + CLOCK_EnableClock(kCLOCK_GatePORT5); +#endif + +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(gpio0)) + RESET_ReleasePeripheralReset(kGPIO0_RST_SHIFT_RSTn); + CLOCK_EnableClock(kCLOCK_GateGPIO0); +#endif + +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(gpio1)) + RESET_ReleasePeripheralReset(kGPIO1_RST_SHIFT_RSTn); + CLOCK_EnableClock(kCLOCK_GateGPIO1); +#endif + +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(gpio2)) + RESET_ReleasePeripheralReset(kGPIO2_RST_SHIFT_RSTn); + CLOCK_EnableClock(kCLOCK_GateGPIO2); +#endif + +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(gpio3)) + RESET_ReleasePeripheralReset(kGPIO3_RST_SHIFT_RSTn); + CLOCK_EnableClock(kCLOCK_GateGPIO3); +#endif + +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(gpio4)) + RESET_ReleasePeripheralReset(kGPIO4_RST_SHIFT_RSTn); + CLOCK_EnableClock(kCLOCK_GateGPIO4); +#endif + +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(gpio5)) + RESET_ReleasePeripheralReset(kGPIO5_RST_SHIFT_RSTn); + CLOCK_EnableClock(kCLOCK_GateGPIO5); +#endif + +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(lpuart0)) + CLOCK_SetClockDiv(kCLOCK_DivLPUART0, 1u); + CLOCK_AttachClk(kFRO_LF_DIV_to_LPUART0); + RESET_ReleasePeripheralReset(kLPUART0_RST_SHIFT_RSTn); +#endif + +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(lpuart1)) + CLOCK_SetClockDiv(kCLOCK_DivLPUART1, 1u); + CLOCK_AttachClk(kFRO_LF_DIV_to_LPUART1); + RESET_ReleasePeripheralReset(kLPUART1_RST_SHIFT_RSTn); +#endif + +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(lpuart2)) + CLOCK_SetClockDiv(kCLOCK_DivLPUART2, 1u); + CLOCK_AttachClk(kFRO_LF_DIV_to_LPUART2); + RESET_ReleasePeripheralReset(kLPUART2_RST_SHIFT_RSTn); +#endif + +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(lpuart3)) + CLOCK_SetClockDiv(kCLOCK_DivLPUART3, 1u); + CLOCK_AttachClk(kFRO_LF_DIV_to_LPUART3); + RESET_ReleasePeripheralReset(kLPUART3_RST_SHIFT_RSTn); +#endif + +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(lpuart4)) + CLOCK_SetClockDiv(kCLOCK_DivLPUART4, 1u); + CLOCK_AttachClk(kFRO_LF_DIV_to_LPUART4); + RESET_ReleasePeripheralReset(kLPUART4_RST_SHIFT_RSTn); +#endif + +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(lpuart5)) + CLOCK_SetClockDiv(kCLOCK_DivLPUART5, 1u); + CLOCK_AttachClk(kFRO_LF_DIV_to_LPUART5); + RESET_ReleasePeripheralReset(kLPUART5_RST_SHIFT_RSTn); +#endif + +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(lpi2c0)) + CLOCK_SetClockDiv(kCLOCK_DivLPI2C0, 1u); + CLOCK_AttachClk(kFRO_LF_DIV_to_LPI2C0); + RESET_ReleasePeripheralReset(kLPI2C0_RST_SHIFT_RSTn); +#endif + +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(lpi2c1)) + CLOCK_SetClockDiv(kCLOCK_DivLPI2C1, 1u); + CLOCK_AttachClk(kFRO_LF_DIV_to_LPI2C1); + RESET_ReleasePeripheralReset(kLPI2C1_RST_SHIFT_RSTn); +#endif + +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(lpi2c2)) + CLOCK_SetClockDiv(kCLOCK_DivLPI2C2, 1u); + CLOCK_AttachClk(kFRO_LF_DIV_to_LPI2C2); + RESET_ReleasePeripheralReset(kLPI2C2_RST_SHIFT_RSTn); +#endif + +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(lpi2c3)) + CLOCK_SetClockDiv(kCLOCK_DivLPI2C3, 1u); + CLOCK_AttachClk(kFRO_LF_DIV_to_LPI2C3); + RESET_ReleasePeripheralReset(kLPI2C3_RST_SHIFT_RSTn); +#endif + +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(lpi2c4)) + CLOCK_SetClockDiv(kCLOCK_DivLPI2C4, 1u); + CLOCK_AttachClk(kFRO_LF_DIV_to_LPI2C4); + RESET_ReleasePeripheralReset(kLPI2C4_RST_SHIFT_RSTn); +#endif + + /* Set SystemCoreClock variable. */ + SystemCoreClock = CLOCK_INIT_CORE_CLOCK; +} diff --git a/boards/nxp/frdm_mcxa577/board.cmake b/boards/nxp/frdm_mcxa577/board.cmake new file mode 100644 index 000000000000..661ad2e4f430 --- /dev/null +++ b/boards/nxp/frdm_mcxa577/board.cmake @@ -0,0 +1,13 @@ +# +# Copyright 2025 NXP +# +# SPDX-License-Identifier: Apache-2.0 +# + +board_runner_args(jlink "--device=MCXA577") +board_runner_args(linkserver "--device=MCXA577:FRDM-MCXA577") +board_runner_args(pyocd "--target=MCXA577") + +include(${ZEPHYR_BASE}/boards/common/linkserver.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) +include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake) diff --git a/boards/nxp/frdm_mcxa577/board.yml b/boards/nxp/frdm_mcxa577/board.yml new file mode 100644 index 000000000000..67736950e571 --- /dev/null +++ b/boards/nxp/frdm_mcxa577/board.yml @@ -0,0 +1,6 @@ +board: + name: frdm_mcxa577 + full_name: FRDM-MCXA577 + vendor: nxp + socs: + - name: mcxa577 diff --git a/boards/nxp/frdm_mcxa577/doc/frdm_mcxa577.webp b/boards/nxp/frdm_mcxa577/doc/frdm_mcxa577.webp new file mode 100644 index 0000000000000000000000000000000000000000..7412adb76ac8a515ccff4bd6b236513f80591ddf GIT binary patch literal 63790 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 zsymPHcky~5fX&=aihkuEN;p5_9RzRl3*pcJ000000000000000000000000000000 L0000000000r`BId literal 0 HcmV?d00001 diff --git a/boards/nxp/frdm_mcxa577/doc/index.rst b/boards/nxp/frdm_mcxa577/doc/index.rst new file mode 100644 index 000000000000..fccd20ed043c --- /dev/null +++ b/boards/nxp/frdm_mcxa577/doc/index.rst @@ -0,0 +1,160 @@ +.. zephyr:board:: frdm_mcxa577 + +Overview +******** + +FRDM-MCXA577 is a compact and scalable development board for rapid prototyping of MCX A577 +MCUs. They offer industry standard headers for easy access to the MCUs input/output (I/O), +integrated open-standard serial interfaces, external flash memory and an onboard MCU-Link +debugger. + +Hardware +******** + +- MCX-A577 Arm Cortex-M33 microcontroller running at 12MHz +- 2048KB dual-bank on chip Flash +- 640 KB RAM +- 2x FlexCAN with FD, 1x RGB LED, 3x SW buttons +- On-board MCU-Link debugger with CMSIS-DAP +- Arduino Header, SmartDMA/Camera Header, mikroBUS + +For more information about the MCX-A577 SoC and FRDM-MCXA577 board, see: + +- `MCX-A577 SoC Website`_ +- `FRDM-MCXA577 Website`_ +- `FRDM-MCXA577 User Guide`_ + +Supported Features +================== + +.. zephyr:board-supported-hw:: + +Connections and IOs +=================== + +The MCX-A577 SoC has 5 gpio controllers and has pinmux registers which +can be used to configure the functionality of a pin. + ++------------+-----------------+----------------------------+ +| Name | Function | Usage | ++============+=================+============================+ +| PIO0_2 | UART | UART RX | ++------------+-----------------+----------------------------+ +| PIO0_3 | UART | UART TX | ++------------+-----------------+----------------------------+ + +System Clock +============ + +The MCX-A577 SoC is configured to use FRO LF running at 12MHz as a source for +the system clock. + +Serial Port +=========== + +The FRDM-MCXA577 SoC has 6 LPUART interfaces for serial communication. +LPUART0 is configured as UART for the console. + +Programming and Debugging +************************* + +.. zephyr:board-supported-runners:: + +Build and flash applications as usual (see :ref:`build_an_application` and +:ref:`application_run` for more details). + +Configuring a Debug Probe +========================= + +A debug probe is used for both flashing and debugging the board. This board is +configured by default to use the MCU-Link CMSIS-DAP Onboard Debug Probe. + +Using LinkServer +---------------- + +Linkserver is the default runner for this board, and supports the factory +default MCU-Link firmware. Follow the instructions in +:ref:`mcu-link-cmsis-onboard-debug-probe` to reprogram the default MCU-Link +firmware. This only needs to be done if the default onboard debug circuit +firmware was changed. To put the board in ``ISP mode`` to program the firmware, +short jumper JP4. + +Using J-Link +------------ + +There are two options. The onboard debug circuit can be updated with Segger +J-Link firmware by following the instructions in +:ref:`mcu-link-jlink-onboard-debug-probe`. +To be able to program the firmware, you need to put the board in ``ISP mode`` +by shortening the jumper JP4. +The second option is to attach a :ref:`jlink-external-debug-probe` to the +10-pin SWD connector (J11) of the board. Additionally, the jumper JP6 must +be shorted. +For both options use the ``-r jlink`` option with west to use the jlink runner. + +.. code-block:: console + + west flash -r jlink + +Configuring a Console +===================== + +Connect a USB cable from your PC to J13, and use the serial terminal of your choice +(minicom, putty, etc.) with the following settings: + +- Speed: 115200 +- Data: 8 bits +- Parity: None +- Stop bits: 1 + +Flashing +======== + +Here is an example for the :zephyr:code-sample:`hello_world` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: frdm_mcxa577 + :goals: flash + +Open a serial terminal, reset the board (press the RESET button), and you should +see the following message in the terminal: + +.. code-block:: console + + *** Booting Zephyr OS build v3.6.0-4478-ge6c3a42f5f52 *** + Hello World! frdm_mcxa577/mcxa577 + +Debugging +========= + +Here is an example for the :zephyr:code-sample:`hello_world` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: frdm_mcxa577/mcxa577 + :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-4478-ge6c3a42f5f52 *** + Hello World! frdm_mcxa577/mcxa577 + +Troubleshooting +=============== + +.. include:: ../../common/segger-ecc-systemview.rst.inc + +.. include:: ../../common/board-footer.rst.inc + +.. _MCX-A577 SoC Website: + https://www.nxp.com/products/MCX-A57X + +.. _FRDM-MCXA577 Website: + https://www.nxp.com/design/design-center/development-boards-and-designs/FRDM-MCXA577 + +.. _FRDM-MCXA577 User Guide: + https://www.nxp.com/document/guide/getting-started-with-frdm-mcxa577:GS-FRDM-MCXA577 diff --git a/boards/nxp/frdm_mcxa577/frdm_mcxa577-pinctrl.dtsi b/boards/nxp/frdm_mcxa577/frdm_mcxa577-pinctrl.dtsi new file mode 100644 index 000000000000..4e4641a26382 --- /dev/null +++ b/boards/nxp/frdm_mcxa577/frdm_mcxa577-pinctrl.dtsi @@ -0,0 +1,18 @@ +/* + * Copyright 2025 NXP + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&pinctrl { + pinmux_lpuart0: pinmux_lpuart0 { + group0 { + pinmux = , + ; + drive-strength = "low"; + slew-rate = "fast"; + input-enable; + }; + }; +}; diff --git a/boards/nxp/frdm_mcxa577/frdm_mcxa577.dts b/boards/nxp/frdm_mcxa577/frdm_mcxa577.dts new file mode 100644 index 000000000000..d395e97c3e2a --- /dev/null +++ b/boards/nxp/frdm_mcxa577/frdm_mcxa577.dts @@ -0,0 +1,156 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include "frdm_mcxa577-pinctrl.dtsi" +#include +#include + +/ { + model = "NXP FRDM_MCXA577 board"; + compatible = "nxp,mcxa577", "nxp,mcx"; + + aliases { + led0 = &red_led; + led1 = &green_led; + led2 = &blue_led; + sw0 = &user_button_2; + sw1 = &user_button_3; + }; + + chosen { + zephyr,sram = &sram0; + zephyr,flash = &flash; + zephyr,flash-controller = &fmu; + zephyr,code-partition = &slot0_partition; + zephyr,console = &lpuart0; + zephyr,shell-uart = &lpuart0; + }; + + leds { + compatible = "gpio-leds"; + + red_led: led_0 { + gpios = <&gpio2 14 GPIO_ACTIVE_LOW>; + label = "Red LED"; + }; + + green_led: led_1 { + gpios = <&gpio2 22 GPIO_ACTIVE_LOW>; + label = "Green LED"; + }; + + blue_led: led_2 { + gpios = <&gpio2 23 GPIO_ACTIVE_LOW>; + label = "Blue LED"; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + + user_button_2: button_2 { + label = "User SW2"; + gpios = <&gpio3 17 GPIO_ACTIVE_LOW>; + zephyr,code = ; + }; + + user_button_3: button_3 { + label = "User SW3"; + gpios = <&gpio0 6 GPIO_ACTIVE_LOW>; + zephyr,code = ; + }; + }; + + arduino_header: arduino-connector { + compatible = "arduino-header-r3"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; + }; +}; + +&cpu0 { + clock-frequency = <12000000>; +}; + +&gpio0 { + status = "okay"; +}; + +&gpio1 { + status = "okay"; +}; + +&gpio2 { + status = "okay"; +}; + +&gpio3 { + status = "okay"; +}; + +&gpio4 { + status = "okay"; +}; + +&lpuart0 { + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&pinmux_lpuart0>; + pinctrl-names = "default"; +}; + +&flash { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 DT_SIZE_K(128)>; + read-only; + }; + + slot0_partition: partition@20000 { + label = "image-0"; + reg = <0x00020000 DT_SIZE_K(896)>; + }; + + slot1_partition: partition@100000 { + label = "image-1"; + reg = <0x00100000 DT_SIZE_K(896)>; + }; + + storage_partition: partition@1E0000 { + label = "storage"; + reg = <0x001E0000 DT_SIZE_K(128)>; + }; + }; +}; diff --git a/boards/nxp/frdm_mcxa577/frdm_mcxa577.yaml b/boards/nxp/frdm_mcxa577/frdm_mcxa577.yaml new file mode 100644 index 000000000000..8fb1dcea4493 --- /dev/null +++ b/boards/nxp/frdm_mcxa577/frdm_mcxa577.yaml @@ -0,0 +1,19 @@ +# +# Copyright 2025 NXP +# +# SPDX-License-Identifier: Apache-2.0 +# + +identifier: frdm_mcxa577 +name: NXP FRDM MCXA577 +type: mcu +arch: arm +ram: 640 +flash: 2048 +toolchain: + - zephyr + - gnuarmemb +supported: + - gpio + - uart +vendor: nxp diff --git a/boards/nxp/frdm_mcxa577/frdm_mcxa577_defconfig b/boards/nxp/frdm_mcxa577/frdm_mcxa577_defconfig new file mode 100644 index 000000000000..9c025d7429c2 --- /dev/null +++ b/boards/nxp/frdm_mcxa577/frdm_mcxa577_defconfig @@ -0,0 +1,18 @@ +# +# Copyright 2025 NXP +# +# SPDX-License-Identifier: Apache-2.0 +# + +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_UART_INTERRUPT_DRIVEN=y +CONFIG_GPIO=y +CONFIG_LPADC_DO_OFFSET_CALIBRATION=y + +CONFIG_ARM_MPU=y +CONFIG_HW_STACK_PROTECTION=y + +# Enable TrustZone-M +CONFIG_TRUSTED_EXECUTION_SECURE=y diff --git a/dts/arm/nxp/nxp_mcxa5x.dtsi b/dts/arm/nxp/nxp_mcxa5x.dtsi new file mode 100644 index 000000000000..a802589bec93 --- /dev/null +++ b/dts/arm/nxp/nxp_mcxa5x.dtsi @@ -0,0 +1,26 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + soc { + sram: sram@14000000 { + ranges = <0x4000000 0x14000000 0x20000000>; + }; + + peripheral: peripheral@50000000 { + ranges = <0x0 0x50000000 0x10000000>; + }; + + flexspi: spi@50020000 { + reg = <0x50020000 0x1000>, <0x90000000 DT_SIZE_M(8)>; + }; + }; +}; + +#include "nxp_mcxa5x_common.dtsi" diff --git a/dts/arm/nxp/nxp_mcxa5x_common.dtsi b/dts/arm/nxp/nxp_mcxa5x_common.dtsi new file mode 100644 index 000000000000..31f1564c6d17 --- /dev/null +++ b/dts/arm/nxp/nxp_mcxa5x_common.dtsi @@ -0,0 +1,733 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/ { + cpus: cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + compatible = "arm,cortex-m33f"; + reg = <0>; + #address-cells = <1>; + #size-cells = <1>; + + mpu: mpu@e000ed90 { + compatible = "arm,armv8m-mpu"; + reg = <0xe000ed90 0x40>; + }; + }; + }; + + cmc { + compatible = "nxp,cmc-reset-cause"; + }; + + /* Dummy pinctrl node, filled with pin mux options at board level */ + pinctrl: pinctrl { + compatible = "nxp,port-pinctrl"; + status = "okay"; + }; +}; + +&sram { + #address-cells = <1>; + #size-cells = <1>; + + sramx: memory@4000000 { + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x4000000 DT_SIZE_K(96)>; + zephyr,memory-region = "SRAMX"; + zephyr,memory-attr = ; + }; + + /* Memory configurations: + * + * RAM 512K + * + * 8 K SRAM A0 + * 4 K SRAM A1 and PKC SRAM 0 + * 4 K SRAM A2 and PKC SRAM 1 + * 16K SRAM A3 + * 16K SRAM A4 + * 16K SRAM A5 + * 32K SRAM A6 + * 32K SRAM A7 + * 32K SRAM A8 + * 32K SRAM A9 + * 32K SRAM A10 + * 32K SRAM A11 + * 32K SRAM B0 + * 32K SRAM B1 + * 32K SRAM B2 + * 32K SRAM B3 + * 32K SRAM B4 + * 32K SRAM B5 + * 32K SRAM B6 + * 32K SRAM B7 + */ + sram0: memory@20000000 { + compatible = "mmio-sram"; + reg = <0x20000000 DT_SIZE_K(512)>; + }; +}; + +&peripheral { + #address-cells = <1>; + #size-cells = <1>; + + syscon: syscon@91000 { + compatible = "nxp,lpc-syscon"; + reg = <0x91000 0x4000>; + #clock-cells = <1>; + + reset: reset { + compatible = "nxp,lpc-syscon-reset"; + #reset-cells = <1>; + }; + }; + + porta: pinmux@bc000 { + compatible = "nxp,port-pinmux"; + reg = <0xbc000 0x1000>; + clocks = <&syscon MCUX_PORT0_CLK>; + }; + + portb: pinmux@bd000 { + compatible = "nxp,port-pinmux"; + reg = <0xbd000 0x1000>; + clocks = <&syscon MCUX_PORT1_CLK>; + }; + + portc: pinmux@be000 { + compatible = "nxp,port-pinmux"; + reg = <0xbe000 0x1000>; + clocks = <&syscon MCUX_PORT2_CLK>; + }; + + portd: pinmux@bf000 { + compatible = "nxp,port-pinmux"; + reg = <0xbf000 0x1000>; + clocks = <&syscon MCUX_PORT3_CLK>; + }; + + porte: pinmux@c0000 { + compatible = "nxp,port-pinmux"; + reg = <0xc0000 0x1000>; + clocks = <&syscon MCUX_PORT4_CLK>; + }; + + portf: pinmux@e3000 { + compatible = "nxp,port-pinmux"; + reg = <0xe3000 0x1000>; + clocks = <&syscon MCUX_PORT5_CLK>; + }; + + gpio0: gpio@48000 { + compatible = "nxp,kinetis-gpio"; + status = "disabled"; + reg = <0x48000 0x1000>; + interrupts = <71 0>, <126 0>; + gpio-controller; + #gpio-cells = <2>; + nxp,kinetis-port = <&porta>; + }; + + gpio1: gpio@4A000 { + compatible = "nxp,kinetis-gpio"; + status = "disabled"; + reg = <0x4A000 0x1000>; + interrupts = <72 0>, <127 0>; + gpio-controller; + #gpio-cells = <2>; + nxp,kinetis-port = <&portb>; + }; + + gpio2: gpio@4C000 { + compatible = "nxp,kinetis-gpio"; + status = "disabled"; + reg = <0x4C000 0x1000>; + interrupts = <73 0>, <128 0>; + gpio-controller; + #gpio-cells = <2>; + nxp,kinetis-port = <&portc>; + }; + + gpio3: gpio@4E000 { + compatible = "nxp,kinetis-gpio"; + status = "disabled"; + reg = <0x4E000 0x1000>; + interrupts = <74 0>, <129 0>; + gpio-controller; + #gpio-cells = <2>; + nxp,kinetis-port = <&portd>; + }; + + gpio4: gpio@50000 { + compatible = "nxp,kinetis-gpio"; + status = "disabled"; + reg = <0x50000 0x1000>; + interrupts = <75 0>, <130 0>; + gpio-controller; + #gpio-cells = <2>; + nxp,kinetis-port = <&porte>; + }; + + gpio5: gpio@df000 { + compatible = "nxp,kinetis-gpio"; + status = "disabled"; + reg = <0xdf000 0x1000>; + interrupts = <76 0>, <131 0>; + gpio-controller; + #gpio-cells = <2>; + nxp,kinetis-port = <&portf>; + }; + + lpuart0: lpuart@9f000 { + compatible = "nxp,lpuart"; + status = "disabled"; + reg = <0x9f000 0x1000>; + interrupts = <31 0>; + clocks = <&syscon MCUX_LPUART0_CLK>; + /* DMA channels 0 and 1, muxed to LPUART RX and TX */ + dmas = <&edma0 0 21>, <&edma0 1 22>; + dma-names = "rx", "tx"; + }; + + lpuart1: lpuart@a0000 { + compatible = "nxp,lpuart"; + status = "disabled"; + reg = <0xa0000 0x1000>; + interrupts = <32 0>; + clocks = <&syscon MCUX_LPUART1_CLK>; + /* DMA channels 2 and 3, muxed to LPUART RX and TX */ + dmas = <&edma0 2 23>, <&edma0 3 24>; + dma-names = "rx", "tx"; + }; + + lpuart2: lpuart@a1000 { + compatible = "nxp,lpuart"; + status = "disabled"; + reg = <0xa1000 0x1000>; + interrupts = <33 0>; + clocks = <&syscon MCUX_LPUART2_CLK>; + /* DMA channels 4 and 5, muxed to LPUART RX and TX */ + dmas = <&edma0 4 25>, <&edma0 5 26>; + dma-names = "rx", "tx"; + }; + + lpuart3: lpuart@a2000 { + compatible = "nxp,lpuart"; + status = "disabled"; + reg = <0xa2000 0x1000>; + interrupts = <34 0>; + clocks = <&syscon MCUX_LPUART3_CLK>; + /* DMA channels 6 and 7, muxed to LPUART RX and TX */ + dmas = <&edma0 6 27>, <&edma0 7 28>; + dma-names = "rx", "tx"; + }; + + lpuart4: lpuart@a3000 { + compatible = "nxp,lpuart"; + status = "disabled"; + reg = <0xa3000 0x1000>; + interrupts = <35 0>; + clocks = <&syscon MCUX_LPUART4_CLK>; + /* DMA channels 8 and 9, muxed to LPUART RX and TX */ + dmas = <&edma0 8 29>, <&edma0 9 30>; + dma-names = "rx", "tx"; + }; + + lpuart5: lpuart@da000 { + compatible = "nxp,lpuart"; + status = "disabled"; + reg = <0xda000 0x1000>; + interrupts = <95 0>; + clocks = <&syscon MCUX_LPUART5_CLK>; + /* DMA channels 10 and 11, muxed to LPUART RX and TX */ + dmas = <&edma0 10 102>, <&edma0 11 103>; + dma-names = "rx", "tx"; + }; + + edma0: dma-controller@80000 { + #dma-cells = <2>; + compatible = "nxp,mcux-edma"; + nxp,version = <4>; + dma-channels = <12>; + dma-requests = <121>; + + reg = <0x80000 0x1000>; + interrupts = <2 0>, <3 0>, <4 0>, + <5 0>, <6 0>, <7 0>, <8 0>, + <9 0>, <134 0>, <135 0>, <136 0>, + <137 0>; + no-error-irq; + status = "disabled"; + }; + + edma1: dma-controller@13000 { + #dma-cells = <2>; + compatible = "nxp,mcux-edma"; + nxp,version = <4>; + dma-channels = <4>; + dma-requests = <121>; + + reg = <0x13000 0x1000>; + interrupts = <142 0>, <143 0>, <144 0>, <145 0>; + no-error-irq; + status = "disabled"; + }; + + fmu: flash-controller@95000 { + compatible = "nxp,msf1"; + reg = <0x95000 0x1000>; + interrupts = <12 0>; + status = "disabled"; + + #address-cells = <1>; + #size-cells = <1>; + + flash: flash@0 { + compatible = "soc-nv-flash"; + reg = <0 DT_SIZE_M(2)>; + erase-block-size = ; + write-block-size = <16>; + }; + + uuid: uuid@1100000 { + compatible = "nxp,lpc-uid"; + reg = <0x1100000 0x10>; + }; + }; + + os_timer: timers@ad000 { + compatible = "nxp,os-timer"; + reg = <0xad000 0x1000>; + interrupts = <57 0>; + status = "disabled"; + }; + + dac0: dac@b4000 { + compatible = "nxp,lpdac"; + reg = <0xb4000 0x1000>; + interrupts = <67 0>; + status = "disabled"; + voltage-reference = <0>; + #io-channel-cells = <1>; + }; + + dac1: dac@b5000 { + compatible = "nxp,lpdac"; + reg = <0xb5000 0x1000>; + interrupts = <68 0>; + status = "disabled"; + voltage-reference = <0>; + #io-channel-cells = <1>; + }; + + wwdt0: watchdog@c000 { + compatible = "nxp,lpc-wwdt"; + reg = <0xc000 0x1000>; + interrupts = <60 0>; + status = "disabled"; + clk-divider = <1>; + }; + + wwdt1: watchdog@d000 { + compatible = "nxp,lpc-wwdt"; + reg = <0xd000 0x1000>; + interrupts = <61 0>; + status = "disabled"; + clk-divider = <1>; + }; + + ewm0: ewm@10000 { + compatible = "nxp,ewm"; + reg = <0x10000 0x6>; + interrupts = <123 0>; + status = "disabled"; + clk-divider = <0x0>; + }; + + ctimer0: ctimer@4000 { + compatible = "nxp,lpc-ctimer"; + reg = <0x4000 0x1000>; + interrupts = <39 0>; + status = "disabled"; + clk-source = <1>; + clocks = <&syscon MCUX_CTIMER0_CLK>; + mode = <0>; + input = <0>; + prescale = <0>; + }; + + ctimer1: ctimer@5000 { + compatible = "nxp,lpc-ctimer"; + reg = <0x5000 0x1000>; + interrupts = <40 0>; + status = "disabled"; + clk-source = <1>; + clocks = <&syscon MCUX_CTIMER1_CLK>; + mode = <0>; + input = <0>; + prescale = <0>; + }; + + ctimer2: ctimer@6000 { + compatible = "nxp,lpc-ctimer"; + reg = <0x6000 0x1000>; + interrupts = <41 0>; + status = "disabled"; + clk-source = <1>; + clocks = <&syscon MCUX_CTIMER2_CLK>; + mode = <0>; + input = <0>; + prescale = <0>; + }; + + ctimer3: ctimer@7000 { + compatible = "nxp,lpc-ctimer"; + reg = <0x7000 0x1000>; + interrupts = <42 0>; + status = "disabled"; + clk-source = <1>; + clocks = <&syscon MCUX_CTIMER3_CLK>; + mode = <0>; + input = <0>; + prescale = <0>; + }; + + ctimer4: ctimer@80000 { + compatible = "nxp,lpc-ctimer"; + reg = <0x80000 0x1000>; + interrupts = <43 0>; + status = "disabled"; + clk-source = <1>; + clocks = <&syscon MCUX_CTIMER4_CLK>; + mode = <0>; + input = <0>; + prescale = <0>; + }; + + smartdma: smartdma@e000 { + compatible = "nxp,smartdma"; + reg = <0xe000 0x1000>; + status = "disabled"; + interrupts = <108 0>; + program-mem = <0x4000000>; + #dma-cells = <0>; + }; + + lpadc0: adc@af000 { + compatible = "nxp,lpc-lpadc"; + reg = <0xaf000 0x1000>; + interrupts = <62 0>; + status = "disabled"; + voltage-ref = <1>; + calibration-average = <128>; + power-level = <0>; + offset-value-a = <0>; + offset-value-b = <0>; + #io-channel-cells = <1>; + clocks = <&syscon MCUX_LPADC1_CLK>; + }; + + lpadc1: adc@b0000 { + compatible = "nxp,lpc-lpadc"; + reg = <0xb0000 0x1000>; + interrupts = <63 0>; + status = "disabled"; + voltage-ref = <0>; + calibration-average = <128>; + power-level = <1>; + offset-value-a = <0>; + offset-value-b = <0>; + #io-channel-cells = <1>; + clocks = <&syscon MCUX_LPADC2_CLK>; + }; + + usb0: usbd@2e000 { + compatible = "nxp,ehci"; + reg = <0x2e000 0x1000>; + interrupts = <103 0>; + interrupt-names = "usb_otg"; + num-bidir-endpoints = <8>; + status = "disabled"; + }; + + usbphy1: usbphy@2f000 { + compatible = "nxp,usbphy"; + reg = <0x2f000 0x1000>; + status = "disabled"; + }; + + lpcmp0: lpcmp@b1000 { + compatible = "nxp,lpcmp"; + reg = <0xb1000 0x1000>; + interrupts = <64 0>; + status = "disabled"; + #io-channel-cells = <2>; + }; + + flexcan0: can@cc000 { + compatible = "nxp,flexcan"; + reg = <0xcc000 0x4000>; + interrupts = <19 0>; + interrupt-names = "common"; + clocks = <&syscon MCUX_FLEXCAN0_CLK>; + clk-source = <0>; + status = "disabled"; + }; + + flexcan1: can@d0000 { + compatible = "nxp,flexcan"; + reg = <0xd0000 0x4000>; + interrupts = <20 0>; + interrupt-names = "common"; + clocks = <&syscon MCUX_FLEXCAN1_CLK>; + clk-source = <0>; + status = "disabled"; + }; + + lptmr0: lptmr@ab000 { + compatible = "nxp,lptmr"; + reg = <0xab000 0x1000>; + interrupts = <55 0>; + clock-frequency = ; + prescale-glitch-filter = <0>; + clk-source = <1>; + resolution = <32>; + }; + + i3c0: i3c@2000 { + compatible = "nxp,mcux-i3c"; + reg = <0x2000 0x1000>; + interrupts = <24 0>; + clocks = <&syscon MCUX_I3C_CLK>; + clk-divider = <6>; + clk-divider-slow = <1>; + clk-divider-tc = <1>; + status = "disabled"; + #address-cells = <3>; + #size-cells = <0>; + }; + + i3c1: i3c@3000 { + compatible = "nxp,mcux-i3c"; + reg = <0x3000 0x1000>; + interrupts = <25 0>; + clocks = <&syscon MCUX_I3C2_CLK>; + clk-divider = <6>; + clk-divider-slow = <1>; + clk-divider-tc = <1>; + status = "disabled"; + #address-cells = <3>; + #size-cells = <0>; + }; + + i3c2: i3c@9e000 { + compatible = "nxp,mcux-i3c"; + reg = <0x9e000 0x1000>; + interrupts = <110 0>; + clocks = <&syscon MCUX_I3C3_CLK>; + clk-divider = <6>; + clk-divider-slow = <1>; + clk-divider-tc = <1>; + status = "disabled"; + #address-cells = <3>; + #size-cells = <0>; + }; + + i3c3: i3c@de000 { + compatible = "nxp,mcux-i3c"; + reg = <0xde000 0x1000>; + interrupts = <117 0>; + clocks = <&syscon MCUX_I3C4_CLK>; + clk-divider = <6>; + clk-divider-slow = <1>; + clk-divider-tc = <1>; + status = "disabled"; + #address-cells = <3>; + #size-cells = <0>; + }; + + flexio0: flexio@99000 { + compatible = "nxp,flexio"; + reg = <0x99000 0x1000>; + status = "disabled"; + interrupts = <105 0>; + clocks = <&syscon MCUX_FLEXIO0_CLK>; + + flexio0_lcd: flexio0-lcd { + compatible = "nxp,mipi-dbi-flexio-lcdif"; + status = "disabled"; + }; + }; + + rtc: rtc@ee000 { + compatible = "nxp,irtc"; + reg = <0xee000 0x1000>; + status = "disabled"; + interrupts = <119 0>; + prescaler = <1>; + clock-frequency = <16384>; + clock-src = <0>; + alarms-count = <1>; + }; + + lpspi0: spi@9c000 { + compatible = "nxp,lpspi"; + reg = <0x9c000 0x1000>; + interrupts = <28 0>; + clocks = <&syscon MCUX_LPSPI0_CLK>; + tx-fifo-size = <4>; + rx-fifo-size = <4>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + lpspi1: spi@9d000 { + compatible = "nxp,lpspi"; + reg = <0x9d000 0x1000>; + interrupts = <29 0>; + clocks = <&syscon MCUX_LPSPI1_CLK>; + tx-fifo-size = <4>; + rx-fifo-size = <4>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + lpspi2: spi@21000 { + compatible = "nxp,lpspi"; + reg = <0x21000 0x1000>; + interrupts = <30 0>; + clocks = <&syscon MCUX_LPSPI2_CLK>; + tx-fifo-size = <4>; + rx-fifo-size = <4>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + lpspi3: spi@22000 { + compatible = "nxp,lpspi"; + reg = <0x22000 0x1000>; + interrupts = <97 0>; + clocks = <&syscon MCUX_LPSPI3_CLK>; + tx-fifo-size = <4>; + rx-fifo-size = <4>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + lpspi4: spi@23000 { + compatible = "nxp,lpspi"; + reg = <0x23000 0x1000>; + interrupts = <98 0>; + clocks = <&syscon MCUX_LPSPI4_CLK>; + tx-fifo-size = <4>; + rx-fifo-size = <4>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + lpspi5: spi@24000 { + compatible = "nxp,lpspi"; + reg = <0x24000 0x1000>; + interrupts = <99 0>; + clocks = <&syscon MCUX_LPSPI5_CLK>; + tx-fifo-size = <4>; + rx-fifo-size = <4>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + lpi2c0: i2c@9a000 { + compatible = "nxp,lpi2c"; + clock-frequency = ; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x9a000 0x1000>; + interrupts = <26 0>; + clocks = <&syscon MCUX_LPI2C0_CLK>; + status = "disabled"; + }; + + lpi2c1: i2c@9b000 { + compatible = "nxp,lpi2c"; + clock-frequency = ; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x9b000 0x1000>; + interrupts = <27 0>; + clocks = <&syscon MCUX_LPI2C1_CLK>; + status = "disabled"; + }; + + lpi2c2: i2c@d4000 { + compatible = "nxp,lpi2c"; + clock-frequency = ; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xd4000 0x1000>; + interrupts = <77 0>; + clocks = <&syscon MCUX_LPI2C2_CLK>; + status = "disabled"; + }; + + lpi2c3: i2c@d5000 { + compatible = "nxp,lpi2c"; + clock-frequency = ; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xd5000 0x1000>; + interrupts = <78 0>; + clocks = <&syscon MCUX_LPI2C3_CLK>; + status = "disabled"; + }; + + lpi2c4: i2c@d6000 { + compatible = "nxp,lpi2c"; + clock-frequency = ; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xd6000 0x1000>; + interrupts = <116 0>; + clocks = <&syscon MCUX_LPI2C4_CLK>; + status = "disabled"; + }; +}; + +&systick { + status = "okay"; +}; + +&flexspi { + compatible = "nxp,imx-flexspi"; + interrupts = <106 0>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + clocks = <&syscon MCUX_FLEXSPI_CLK>; +}; + +&nvic { + arm,num-irq-priority-bits = <3>; +}; diff --git a/dts/arm/nxp/nxp_mcxa5x_ns.dtsi b/dts/arm/nxp/nxp_mcxa5x_ns.dtsi new file mode 100644 index 000000000000..62f6ee2b1546 --- /dev/null +++ b/dts/arm/nxp/nxp_mcxa5x_ns.dtsi @@ -0,0 +1,26 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + soc { + sram: sram@4000000 { + ranges = <0x4000000 0x4000000 0x20000000>; + }; + + peripheral: peripheral@40000000 { + ranges = <0x0 0x40000000 0x10000000>; + }; + + flexspi: spi@40020000 { + reg = <0x40020000 0x1000>, <0x80000000 DT_SIZE_M(8)>; + }; + }; +}; + +#include "nxp_mcxa5x_common.dtsi" 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 03c2e9653203..36c2679a43b5 100644 --- a/include/zephyr/dt-bindings/clock/mcux_lpc_syscon_clock.h +++ b/include/zephyr/dt-bindings/clock/mcux_lpc_syscon_clock.h @@ -66,6 +66,8 @@ #define MCUX_I3C_CLK MCUX_LPC_CLK_ID(0x06, 0x00) #define MCUX_I3C2_CLK MCUX_LPC_CLK_ID(0x06, 0x01) +#define MCUX_I3C3_CLK MCUX_LPC_CLK_ID(0x06, 0x02) +#define MCUX_I3C4_CLK MCUX_LPC_CLK_ID(0x06, 0x03) #define MCUX_MIPI_DSI_DPHY_CLK MCUX_LPC_CLK_ID(0x07, 0x00) #define MCUX_MIPI_DSI_ESC_CLK MCUX_LPC_CLK_ID(0x07, 0x01) @@ -111,11 +113,13 @@ #define MCUX_LPUART2_CLK MCUX_LPC_CLK_ID(0x13, 0x02) #define MCUX_LPUART3_CLK MCUX_LPC_CLK_ID(0x13, 0x03) #define MCUX_LPUART4_CLK MCUX_LPC_CLK_ID(0x13, 0x04) +#define MCUX_LPUART5_CLK MCUX_LPC_CLK_ID(0x13, 0x05) #define MCUX_LPI2C0_CLK MCUX_LPC_CLK_ID(0x14, 0x00) #define MCUX_LPI2C1_CLK MCUX_LPC_CLK_ID(0x14, 0x01) #define MCUX_LPI2C2_CLK MCUX_LPC_CLK_ID(0x14, 0x02) #define MCUX_LPI2C3_CLK MCUX_LPC_CLK_ID(0x14, 0x03) +#define MCUX_LPI2C4_CLK MCUX_LPC_CLK_ID(0x14, 0x04) #define MCUX_XSPI_CLK MCUX_LPC_CLK_ID(0x15, 0x00) #define MCUX_XSPI0_CLK MCUX_LPC_CLK_ID(0x15, 0x00) @@ -128,6 +132,10 @@ #define MCUX_LPSPI0_CLK MCUX_LPC_CLK_ID(0x17, 0x00) #define MCUX_LPSPI1_CLK MCUX_LPC_CLK_ID(0x17, 0x01) +#define MCUX_LPSPI2_CLK MCUX_LPC_CLK_ID(0x17, 0x02) +#define MCUX_LPSPI3_CLK MCUX_LPC_CLK_ID(0x17, 0x03) +#define MCUX_LPSPI4_CLK MCUX_LPC_CLK_ID(0x17, 0x04) +#define MCUX_LPSPI5_CLK MCUX_LPC_CLK_ID(0x17, 0x05) #define MCUX_OPAMP0_CLK MCUX_LPC_CLK_ID(0x18, 0x00) #define MCUX_OPAMP1_CLK MCUX_LPC_CLK_ID(0x18, 0x01) diff --git a/soc/nxp/mcx/mcxa/Kconfig b/soc/nxp/mcx/mcxa/Kconfig index df1092cda6a0..035899face46 100644 --- a/soc/nxp/mcx/mcxa/Kconfig +++ b/soc/nxp/mcx/mcxa/Kconfig @@ -41,6 +41,15 @@ config SOC_MCXA366 select ARMV8_M_DSP select HAS_MCUX_CACHE +config SOC_MCXA577 + select CPU_CORTEX_M33 + select CPU_HAS_ARM_SAU + select CPU_HAS_ARM_MPU + select CPU_HAS_FPU + select ARMV8_M_DSP + select ARM_TRUSTZONE_M + select HAS_MCUX_CACHE + config SOC_MCXA344 select CPU_CORTEX_M33 select CPU_HAS_ARM_MPU diff --git a/soc/nxp/mcx/mcxa/Kconfig.defconfig b/soc/nxp/mcx/mcxa/Kconfig.defconfig index 0d2b2496654d..3e36c85a7e57 100644 --- a/soc/nxp/mcx/mcxa/Kconfig.defconfig +++ b/soc/nxp/mcx/mcxa/Kconfig.defconfig @@ -10,6 +10,7 @@ config NUM_IRQS default 80 if SOC_MCXA153 default 89 if SOC_MCXA156 default 122 if (SOC_MCXA346 || SOC_MCXA266 || SOC_MCXA366) + default 164 if (SOC_MCXA577) default 88 config SYS_CLOCK_HW_CYCLES_PER_SEC diff --git a/soc/nxp/mcx/mcxa/Kconfig.soc b/soc/nxp/mcx/mcxa/Kconfig.soc index 549204be406e..e0e94968d5d9 100644 --- a/soc/nxp/mcx/mcxa/Kconfig.soc +++ b/soc/nxp/mcx/mcxa/Kconfig.soc @@ -27,6 +27,10 @@ config SOC_MCXA366 bool select SOC_FAMILY_MCXA +config SOC_MCXA577 + bool + select SOC_FAMILY_MCXA + config SOC_MCXA344 bool select SOC_FAMILY_MCXA @@ -38,6 +42,7 @@ config SOC default "mcxa266" if SOC_MCXA266 default "mcxa366" if SOC_MCXA366 default "mcxa344" if SOC_MCXA344 + default "mcxa577" if SOC_MCXA577 config SOC_PART_NUMBER_MCXA153VFM bool @@ -108,6 +113,15 @@ config SOC_PART_NUMBER_MCXA344VLH config SOC_PART_NUMBER_MCXA344VLL bool +config SOC_PART_NUMBER_MCXA577VLQ + bool + +config SOC_PART_NUMBER_MCXA577VLL + bool + +config SOC_PART_NUMBER_MCXA577VPN + bool + config SOC_PART_NUMBER default "MCXA153VFM" if SOC_PART_NUMBER_MCXA153VFM default "MCXA153VFT" if SOC_PART_NUMBER_MCXA153VFT @@ -128,6 +142,9 @@ config SOC_PART_NUMBER default "MCXA366VLL" if SOC_PART_NUMBER_MCXA366VLL default "MCXA366VLH" if SOC_PART_NUMBER_MCXA366VLH default "MCXA366VPN" if SOC_PART_NUMBER_MCXA366VPN + default "MCXA577VLL" if SOC_PART_NUMBER_MCXA577VLL + default "MCXA577VLQ" if SOC_PART_NUMBER_MCXA577VLQ + default "MCXA577VPN" if SOC_PART_NUMBER_MCXA577VPN default "MCXA344VFM" if SOC_PART_NUMBER_MCXA344VFM default "MCXA344VLF" if SOC_PART_NUMBER_MCXA344VLF default "MCXA344VLH" if SOC_PART_NUMBER_MCXA344VLH diff --git a/soc/nxp/mcx/soc.yml b/soc/nxp/mcx/soc.yml index de513776a4c8..6fb9da915331 100644 --- a/soc/nxp/mcx/soc.yml +++ b/soc/nxp/mcx/soc.yml @@ -39,6 +39,7 @@ family: - name: mcxa266 - name: mcxa366 - name: mcxa344 + - name: mcxa577 - name: mcxw series: - name: mcxw2xx @@ -82,6 +83,8 @@ runners: - mcxa266 - qualifiers: - mcxa366 + - qualifiers: + - mcxa577 - qualifiers: - mcxw716c - qualifiers: @@ -116,6 +119,8 @@ runners: - mcxa266 - qualifiers: - mcxa366 + - qualifiers: + - mcxa577 - qualifiers: - mcxw716c - qualifiers: From 9bdafbf23b49880dadac7083e95082fed75494ba Mon Sep 17 00:00:00 2001 From: Qingsong Gou Date: Tue, 2 Dec 2025 19:08:40 +0800 Subject: [PATCH 0004/3659] drivers: clock_control: sf32lb: fix GPTIM2 clock rate Fix GPTIM2 clock rate Signed-off-by: Qingsong Gou --- drivers/clock_control/clock_control_sf32lb_rcc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/clock_control/clock_control_sf32lb_rcc.c b/drivers/clock_control/clock_control_sf32lb_rcc.c index c84a8f4eeef3..9d160d6e9986 100644 --- a/drivers/clock_control/clock_control_sf32lb_rcc.c +++ b/drivers/clock_control/clock_control_sf32lb_rcc.c @@ -287,10 +287,12 @@ int clock_control_sf32lb_rcc_get_rate(const struct device *dev, clock_control_su case SF32LB52X_CLOCK_GPADC: case SF32LB52X_CLOCK_TSEN: case SF32LB52X_CLOCK_GPTIM1: - case SF32LB52X_CLOCK_GPTIM2: case SF32LB52X_CLOCK_ATIM1: *rate = sf32lb_get_pclk1(config); return 0; + case SF32LB52X_CLOCK_GPTIM2: + *rate = 24000000U; + return 0; case SF32LB52X_CLOCK_BTIM1: case SF32LB52X_CLOCK_BTIM2: *rate = sf32lb_get_pclk1(config) / 2U; From 2a2d5b7be469656e3447dd6413b55124cb223dea Mon Sep 17 00:00:00 2001 From: Haoran Jiang Date: Fri, 5 Dec 2025 17:24:22 +0800 Subject: [PATCH 0005/3659] drivers: crc: sf32lb: Fix crc calculation error When the number of input bits changes, the value in the `CR_DATASIZE` register should be modified accordingly. The CRC32_C algorithm does not require the result to be XOR Signed-off-by: Haoran Jiang --- drivers/crc/crc_sf32lb.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/crc/crc_sf32lb.c b/drivers/crc/crc_sf32lb.c index 63ca5535f00a..0f19b01d3637 100644 --- a/drivers/crc/crc_sf32lb.c +++ b/drivers/crc/crc_sf32lb.c @@ -85,13 +85,13 @@ static int crc_sf32lb_prepare_config(const struct crc_ctx *ctx, uint8_t *polysiz *width = 16U; *xor_out = 0U; break; - case CRC32_C: - __fallthrough; case CRC32_IEEE: *polysize = CRC_POLYSIZE_32; *width = 32U; *xor_out = 0xFFFFFFFFU; break; + case CRC32_C: + __fallthrough; case CRC32_K_4_2: *polysize = CRC_POLYSIZE_32; *width = 32U; @@ -151,8 +151,7 @@ static int crc_sf32lb_begin(const struct device *dev, struct crc_ctx *ctx) data->xor_out = xor_out; mask = crc_sf32lb_mask(width); - cr = FIELD_PREP(CRC_CR_DATASIZE_Msk, CRC_DATASIZE_8) | - FIELD_PREP(CRC_CR_POLYSIZE_Msk, polysize); + cr = FIELD_PREP(CRC_CR_POLYSIZE_Msk, polysize); if ((ctx->reversed & CRC_FLAG_REVERSE_INPUT) != 0U) { cr |= FIELD_PREP(CRC_CR_REV_IN_Msk, CRC_REV_IN_BYTE); @@ -196,6 +195,7 @@ static int crc_sf32lb_update(const struct device *dev, struct crc_ctx *ctx, cons size_t idx = 0U; for (; idx < aligned_len; idx += sizeof(uint32_t)) { + sys_set_bits(config->base + CRC_CR_OFFSET, CRC_CR_DATASIZE_Msk); uint32_t data = sys_get_le32(&data_buf[idx]); sys_write32(data, config->base + CRC_DR_OFFSET); @@ -213,6 +213,10 @@ static int crc_sf32lb_update(const struct device *dev, struct crc_ctx *ctx, cons uint32_t rem = 0U; size_t rem_bytes = bufsize - idx; + sys_clear_bits(config->base + CRC_CR_OFFSET, CRC_CR_DATASIZE_Msk); + sys_set_bits(config->base + CRC_CR_OFFSET, + FIELD_PREP(CRC_CR_DATASIZE_Msk, (rem_bytes - 1U))); + sys_get_le(&rem, &data_buf[idx], rem_bytes); sys_write32(rem, config->base + CRC_DR_OFFSET); From 8422e7ed4f867ad70efbfd116f0741b32018ec87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Fri, 5 Dec 2025 10:26:22 +0100 Subject: [PATCH 0006/3659] tests: arch: arm: Increase kobject text area when no optimization MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When CONFIG_NO_OPTIMIZATIONS=n then kobject area can get inflated. Some targets are currently fail to compile due to that. Signed-off-by: Krzysztof Chruściński --- tests/arch/arm/arm_interrupt/testcase.yaml | 1 + tests/arch/arm/arm_thread_swap/testcase.yaml | 2 ++ 2 files changed, 3 insertions(+) diff --git a/tests/arch/arm/arm_interrupt/testcase.yaml b/tests/arch/arm/arm_interrupt/testcase.yaml index df47b02fccd9..5836a20b9565 100644 --- a/tests/arch/arm/arm_interrupt/testcase.yaml +++ b/tests/arch/arm/arm_interrupt/testcase.yaml @@ -17,6 +17,7 @@ tests: - CONFIG_IDLE_STACK_SIZE=512 - CONFIG_MAIN_STACK_SIZE=2048 - CONFIG_ZTEST_STACK_SIZE=1280 + - CONFIG_KOBJECT_TEXT_AREA=32768 arch.arm.interrupt.extra_exception_info: filter: not CONFIG_TRUSTED_EXECUTION_NONSECURE extra_configs: diff --git a/tests/arch/arm/arm_thread_swap/testcase.yaml b/tests/arch/arm/arm_thread_swap/testcase.yaml index e26d88429050..b60ad6f705d8 100644 --- a/tests/arch/arm/arm_thread_swap/testcase.yaml +++ b/tests/arch/arm/arm_thread_swap/testcase.yaml @@ -14,6 +14,7 @@ tests: - CONFIG_ZTEST_WARN_NO_OPTIMIZATIONS=n - CONFIG_IDLE_STACK_SIZE=512 - CONFIG_MAIN_STACK_SIZE=2048 + - CONFIG_KOBJECT_TEXT_AREA=32768 min_flash: 192 arch.arm.swap.common.fpu_sharing: filter: not CONFIG_TRUSTED_EXECUTION_NONSECURE and CONFIG_ARMV7_M_ARMV8_M_FP @@ -29,4 +30,5 @@ tests: - CONFIG_ZTEST_WARN_NO_OPTIMIZATIONS=n - CONFIG_IDLE_STACK_SIZE=512 - CONFIG_MAIN_STACK_SIZE=2048 + - CONFIG_KOBJECT_TEXT_AREA=32768 min_flash: 192 From 3546e73cdae6169a60c8f85cce3f1cc0b3b6b927 Mon Sep 17 00:00:00 2001 From: Mathieu Choplain Date: Fri, 5 Dec 2025 10:44:03 +0100 Subject: [PATCH 0007/3659] drivers: flash: stm32_ospi: cleanup STM32H5-related quirks STM32H5 series now uses the dedicated `flash_stm32_xspi` driver instead. Remove all quirks related to H5 in the STM32 OSPI driver. Signed-off-by: Mathieu Choplain --- drivers/flash/Kconfig.stm32_ospi | 5 +- drivers/flash/flash_stm32_ospi.c | 31 --------- drivers/flash/flash_stm32_ospi.h | 106 ------------------------------- 3 files changed, 2 insertions(+), 140 deletions(-) delete mode 100644 drivers/flash/flash_stm32_ospi.h diff --git a/drivers/flash/Kconfig.stm32_ospi b/drivers/flash/Kconfig.stm32_ospi index 4b62bdcd23ee..4ab9371278f6 100644 --- a/drivers/flash/Kconfig.stm32_ospi +++ b/drivers/flash/Kconfig.stm32_ospi @@ -9,9 +9,8 @@ config FLASH_STM32_OSPI bool "STM32 Octo SPI Flash driver" default y depends on DT_HAS_ST_STM32_OSPI_NOR_ENABLED - select USE_STM32_HAL_OSPI if !SOC_SERIES_STM32H5X - select USE_STM32_HAL_XSPI if SOC_SERIES_STM32H5X - select USE_STM32_LL_DLYB if (SOC_SERIES_STM32H5X || SOC_SERIES_STM32U5X) + select USE_STM32_HAL_OSPI + select USE_STM32_LL_DLYB if SOC_SERIES_STM32U5X select USE_STM32_HAL_MDMA if SOC_SERIES_STM32H7X select FLASH_HAS_DRIVER_ENABLED select FLASH_JESD216 diff --git a/drivers/flash/flash_stm32_ospi.c b/drivers/flash/flash_stm32_ospi.c index a22e9fb7928a..3f092ee129a9 100644 --- a/drivers/flash/flash_stm32_ospi.c +++ b/drivers/flash/flash_stm32_ospi.c @@ -25,8 +25,6 @@ #include "spi_nor.h" #include "jesd216.h" -#include "flash_stm32_ospi.h" - #include LOG_MODULE_REGISTER(flash_stm32_ospi, CONFIG_FLASH_LOG_LEVEL); @@ -57,17 +55,10 @@ LOG_MODULE_REGISTER(flash_stm32_ospi, CONFIG_FLASH_LOG_LEVEL); #define STM32_OSPI_FIFO_THRESHOLD 4 -#if defined(CONFIG_SOC_SERIES_STM32H5X) -/* Valid range is [0, 255] */ -#define STM32_OSPI_CLOCK_PRESCALER_MIN 0U -#define STM32_OSPI_CLOCK_PRESCALER_MAX 255U -#define STM32_OSPI_CLOCK_COMPUTE(bus_freq, prescaler) ((bus_freq) / ((prescaler) + 1U)) -#else /* Valid range is [1, 256] */ #define STM32_OSPI_CLOCK_PRESCALER_MIN 1U #define STM32_OSPI_CLOCK_PRESCALER_MAX 256U #define STM32_OSPI_CLOCK_COMPUTE(bus_freq, prescaler) ((bus_freq) / (prescaler)) -#endif /* Max Time value during reset or erase operation */ #define STM32_OSPI_RESET_MAX_TIME 100U @@ -2355,13 +2346,8 @@ static int flash_stm32_ospi_init(const struct device *dev) /* Initialize OSPI HAL structure completely */ dev_data->hospi.Init.FifoThreshold = 4; dev_data->hospi.Init.ClockPrescaler = prescaler; -#if defined(CONFIG_SOC_SERIES_STM32H5X) - /* The stm32h5xx_hal_xspi does not reduce DEVSIZE before writing the DCR1 */ - dev_data->hospi.Init.DeviceSize = find_lsb_set(dev_cfg->flash_size) - 2; -#else /* Give a bit position from 0 to 31 to the HAL init for the DCR1 reg */ dev_data->hospi.Init.DeviceSize = find_lsb_set(dev_cfg->flash_size) - 1; -#endif /* CONFIG_SOC_SERIES_STM32U5X */ dev_data->hospi.Init.DualQuad = HAL_OSPI_DUALQUAD_DISABLE; dev_data->hospi.Init.ChipSelectHighTime = 2; dev_data->hospi.Init.FreeRunningClock = HAL_OSPI_FREERUNCLK_DISABLE; @@ -2437,23 +2423,6 @@ static int flash_stm32_ospi_init(const struct device *dev) #endif /* OCTOSPIM */ -#if defined(CONFIG_SOC_SERIES_STM32H5X) - /* OCTOSPI1 delay block init Function */ - HAL_XSPI_DLYB_CfgTypeDef xspi_delay_block_cfg = {0}; - - (void)HAL_XSPI_DLYB_GetClockPeriod(&dev_data->hospi, &xspi_delay_block_cfg); - /* with DTR, set the PhaseSel/4 (empiric value from stm32Cube) */ - xspi_delay_block_cfg.PhaseSel /= 4; - - if (HAL_XSPI_DLYB_SetConfig(&dev_data->hospi, &xspi_delay_block_cfg) != HAL_OK) { - LOG_ERR("XSPI DelayBlock failed"); - return -EIO; - } - - LOG_DBG("Delay Block Init"); - -#endif /* CONFIG_SOC_SERIES_STM32H5X */ - /* Initialize semaphores */ k_sem_init(&dev_data->sem, 1, 1); k_sem_init(&dev_data->sync, 0, 1); diff --git a/drivers/flash/flash_stm32_ospi.h b/drivers/flash/flash_stm32_ospi.h deleted file mode 100644 index 52221ba84bb5..000000000000 --- a/drivers/flash/flash_stm32_ospi.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (c) 2023 STMicroelectronics - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef ZEPHYR_DRIVERS_FLASH_OSPI_STM32_H_ -#define ZEPHYR_DRIVERS_FLASH_OSPI_STM32_H_ - -#if defined(CONFIG_SOC_SERIES_STM32H5X) - -#define NbData DataLength -#define AddressSize AddressWidth -#define InstructionDtrMode InstructionDTRMode -#define AddressDtrMode AddressDTRMode -#define DataDtrMode DataDTRMode -#define InstructionSize InstructionWidth -#define FifoThreshold FifoThresholdByte -#define ChipSelectHighTime ChipSelectHighTimeCycle -#define FlashId IOSelect -#define Match MatchValue -#define Mask MatchMask -#define Interval IntervalTime -#define DeviceSize MemorySize -#define DualQuad MemoryMode - -#define OSPI_InitTypeDef XSPI_InitTypeDef -#define OSPI_HandleTypeDef XSPI_HandleTypeDef -#define OSPI_RegularCmdTypeDef XSPI_RegularCmdTypeDef -#define OSPI_AutoPollingTypeDef XSPI_AutoPollingTypeDef - -#define HAL_OSPI_Init HAL_XSPI_Init -#define HAL_OSPI_Command HAL_XSPI_Command -#define HAL_OSPI_Receive HAL_XSPI_Receive -#define HAL_OSPI_Receive_DMA HAL_XSPI_Receive_DMA -#define HAL_OSPI_Receive_IT HAL_XSPI_Receive_IT -#define HAL_OSPI_Transmit HAL_XSPI_Transmit -#define HAL_OSPI_Transmit_DMA HAL_XSPI_Transmit_DMA -#define HAL_OSPI_Transmit_IT HAL_XSPI_Transmit_IT -#define HAL_OSPI_AutoPolling HAL_XSPI_AutoPolling -#define HAL_OSPI_AutoPolling_IT HAL_XSPI_AutoPolling_IT -#define HAL_OSPI_IRQHandler HAL_XSPI_IRQHandler -#define HAL_OSPI_Abort HAL_XSPI_Abort - -#define HAL_OSPI_ErrorCallback HAL_XSPI_ErrorCallback -#define HAL_OSPI_CmdCpltCallback HAL_XSPI_CmdCpltCallback -#define HAL_OSPI_RxCpltCallback HAL_XSPI_RxCpltCallback -#define HAL_OSPI_TxCpltCallback HAL_XSPI_TxCpltCallback -#define HAL_OSPI_StatusMatchCallback HAL_XSPI_StatusMatchCallback -#define HAL_OSPI_TimeOutCallback HAL_XSPI_TimeOutCallback - -#define HAL_OSPI_ADDRESS_NONE HAL_XSPI_ADDRESS_NONE -#define HAL_OSPI_ADDRESS_8_LINES HAL_XSPI_ADDRESS_8_LINES -#define HAL_OSPI_ADDRESS_4_LINES HAL_XSPI_ADDRESS_4_LINES -#define HAL_OSPI_ADDRESS_2_LINES HAL_XSPI_ADDRESS_2_LINES -#define HAL_OSPI_ADDRESS_1_LINE HAL_XSPI_ADDRESS_1_LINE -#define HAL_OSPI_ADDRESS_32_BITS HAL_XSPI_ADDRESS_32_BITS -#define HAL_OSPI_ADDRESS_24_BITS HAL_XSPI_ADDRESS_24_BITS -#define HAL_OSPI_ADDRESS_16_BITS HAL_XSPI_ADDRESS_16_BITS -#define HAL_OSPI_ADDRESS_8_BITS HAL_XSPI_ADDRESS_8_BITS -#define HAL_OSPI_ADDRESS_DTR_ENABLE HAL_XSPI_ADDRESS_DTR_ENABLE -#define HAL_OSPI_ADDRESS_DTR_DISABLE HAL_XSPI_ADDRESS_DTR_DISABLE -#define HAL_OSPI_INSTRUCTION_8_LINES HAL_XSPI_INSTRUCTION_8_LINES -#define HAL_OSPI_INSTRUCTION_4_LINES HAL_XSPI_INSTRUCTION_4_LINES -#define HAL_OSPI_INSTRUCTION_2_LINES HAL_XSPI_INSTRUCTION_2_LINES -#define HAL_OSPI_INSTRUCTION_1_LINE HAL_XSPI_INSTRUCTION_1_LINE -#define HAL_OSPI_INSTRUCTION_32_BITS HAL_XSPI_INSTRUCTION_32_BITS -#define HAL_OSPI_INSTRUCTION_16_BITS HAL_XSPI_INSTRUCTION_16_BITS -#define HAL_OSPI_INSTRUCTION_8_BITS HAL_XSPI_INSTRUCTION_8_BITS -#define HAL_OSPI_INSTRUCTION_DTR_ENABLE HAL_XSPI_INSTRUCTION_DTR_ENABLE -#define HAL_OSPI_INSTRUCTION_DTR_DISABLE HAL_XSPI_INSTRUCTION_DTR_DISABLE - -#define HAL_OSPI_ALTERNATE_BYTES_NONE HAL_XSPI_ALT_BYTES_NONE -#define HAL_OSPI_DATA_NONE HAL_XSPI_DATA_NONE -#define HAL_OSPI_DATA_8_LINES HAL_XSPI_DATA_8_LINES -#define HAL_OSPI_DATA_4_LINES HAL_XSPI_DATA_4_LINES -#define HAL_OSPI_DATA_2_LINES HAL_XSPI_DATA_2_LINES -#define HAL_OSPI_DATA_1_LINE HAL_XSPI_DATA_1_LINE -#define HAL_OSPI_DATA_DTR_ENABLE HAL_XSPI_DATA_DTR_ENABLE -#define HAL_OSPI_DATA_DTR_DISABLE HAL_XSPI_DATA_DTR_DISABLE -#define HAL_OSPI_DQS_ENABLE HAL_XSPI_DQS_ENABLE -#define HAL_OSPI_DQS_DISABLE HAL_XSPI_DQS_DISABLE - -#define HAL_OSPI_MATCH_MODE_AND HAL_XSPI_MATCH_MODE_AND -#define HAL_OSPI_SIOO_INST_EVERY_CMD HAL_XSPI_SIOO_INST_EVERY_CMD -#define HAL_OSPI_AUTOMATIC_STOP_ENABLE HAL_XSPI_AUTOMATIC_STOP_ENABLE -#define HAL_OSPI_OPTYPE_COMMON_CFG HAL_XSPI_OPTYPE_COMMON_CFG -#define HAL_OSPI_TIMEOUT_DEFAULT_VALUE HAL_XSPI_TIMEOUT_DEFAULT_VALUE - -#define HAL_OSPI_CLOCK_MODE_0 HAL_XSPI_CLOCK_MODE_0 -#define HAL_OSPI_FLASH_ID_1 HAL_XSPI_SELECT_IO_7_0 -#define HAL_OSPI_DUALQUAD_DISABLE HAL_XSPI_SINGLE_MEM -#define HAL_OSPI_DUALQUAD_ENABLE HAL_XSPI_DUAL_MEM -#define HAL_OSPI_SAMPLE_SHIFTING_NONE HAL_XSPI_SAMPLE_SHIFT_NONE -#define HAL_OSPI_SAMPLE_SHIFTING_HALFCYCLE HAL_XSPI_SAMPLE_SHIFT_HALFCYCLE -#define HAL_OSPI_DELAY_BLOCK_USED HAL_XSPI_DELAY_BLOCK_ON -#define HAL_OSPI_DELAY_BLOCK_BYPASSED HAL_XSPI_DELAY_BLOCK_BYPASS -#define HAL_OSPI_MEMTYPE_MICRON HAL_XSPI_MEMTYPE_MICRON -#define HAL_OSPI_MEMTYPE_MACRONIX HAL_XSPI_MEMTYPE_MACRONIX -#define HAL_OSPI_DHQC_ENABLE HAL_XSPI_DHQC_ENABLE -#define HAL_OSPI_DHQC_DISABLE HAL_XSPI_DHQC_DISABLE -#define HAL_OSPI_WRAP_NOT_SUPPORTED HAL_XSPI_WRAP_NOT_SUPPORTED -#define HAL_OSPI_FREERUNCLK_DISABLE HAL_XSPI_FREERUNCLK_DISABLE -#endif /* CONFIG_SOC_SERIES_STM32H5X */ - -#endif /* ZEPHYR_DRIVERS_FLASH_OSPIH_STM32_H_ */ From aaf69f5cef89bee9a9a56316e838232c8cea92ed Mon Sep 17 00:00:00 2001 From: Mathieu Choplain Date: Fri, 5 Dec 2025 10:53:16 +0100 Subject: [PATCH 0008/3659] drivers: rtc: stm32: don't enable LL full driver module The RTC driver does not use any of the functions implemented in the LL full driver module (`stm32XXxx_ll_rtc.c`), only those provided by the LL header (`stm32XXxx_ll_rtc.h`). Disable compilation of the unnecessary full driver module. Signed-off-by: Mathieu Choplain --- drivers/rtc/Kconfig.stm32 | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/rtc/Kconfig.stm32 b/drivers/rtc/Kconfig.stm32 index 777343c5286f..cb8e32353a99 100644 --- a/drivers/rtc/Kconfig.stm32 +++ b/drivers/rtc/Kconfig.stm32 @@ -5,6 +5,5 @@ config RTC_STM32 bool "STM32 RTC driver" default y if !COUNTER depends on DT_HAS_ST_STM32_RTC_ENABLED && !SOC_SERIES_STM32F1X - select USE_STM32_LL_RTC help Build RTC driver for STM32 SoCs, excluding STM32F1 series. From 923ece1eea7d303d06b617bb85159832c6b9c12e Mon Sep 17 00:00:00 2001 From: Mathieu Choplain Date: Fri, 5 Dec 2025 10:59:33 +0100 Subject: [PATCH 0009/3659] drivers: sensor: qdec_stm32: don't enable LL full driver module The QDEC driver does not use any of the functions implemented in the TIM LL full driver module (`stm32XXxx_ll_tim.c`), only those provided by the LL header (`stm32XXxx_ll_tim.h`). Disable compilation of the unnecessary full driver module. Signed-off-by: Mathieu Choplain --- drivers/sensor/st/qdec_stm32/Kconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/sensor/st/qdec_stm32/Kconfig b/drivers/sensor/st/qdec_stm32/Kconfig index 8decf2c4d5d9..626e6fa30819 100644 --- a/drivers/sensor/st/qdec_stm32/Kconfig +++ b/drivers/sensor/st/qdec_stm32/Kconfig @@ -7,6 +7,5 @@ config QDEC_STM32 default y depends on DT_HAS_ST_STM32_QDEC_ENABLED select PINCTRL - select USE_STM32_LL_TIM help STM32 family Quadrature Decoder driver. From 223e521275589b550e12fef3f96f1791988b5916 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Tue, 9 Dec 2025 11:33:04 +0100 Subject: [PATCH 0010/3659] scripts: ci: refresh requirements-actions.txt pinned versions and SHAs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This ensures, we pick a `urllib` version >2.6.0. See: - CVE-2025-66418 High severity - CVE-2025-66471 High severity Signed-off-by: Benjamin Cabé --- scripts/requirements-actions.txt | 1668 ++++++++++++++++-------------- 1 file changed, 885 insertions(+), 783 deletions(-) diff --git a/scripts/requirements-actions.txt b/scripts/requirements-actions.txt index 8bfb956fb831..c7d48b0e8486 100644 --- a/scripts/requirements-actions.txt +++ b/scripts/requirements-actions.txt @@ -4,56 +4,50 @@ anytree==2.13.0 \ --hash=sha256:4cbcf10df36b1f1cba131b7e487ff3edafc9d6e932a3c70071b5b768bab901ff \ --hash=sha256:c9d3aa6825fdd06af7ebb05b4ef291d2db63e62bb1f9b7d9b71354be9d362714 # via -r requirements-actions.in -arrow==1.3.0 \ - --hash=sha256:c728b120ebc00eb84e01882a6f5e7927a53960aa990ce7dd2b10f39005a67f80 \ - --hash=sha256:d4540617648cb5f895730f1ad8c82a65f2dad0166f57b75f3ca54759c4d67a85 +arrow==1.4.0 \ + --hash=sha256:749f0769958ebdc79c173ff0b0670d59051a535fa26e8eba02953dc19eb43205 \ + --hash=sha256:ed0cc050e98001b8779e84d461b0098c4ac597e88704a655582b21d116e526d7 # via gitlint-core -astroid==3.3.11 \ - --hash=sha256:1e5a5011af2920c7c67a53f65d536d65bfa7116feeaf2354d8b94f29573bb0ce \ - --hash=sha256:54c760ae8322ece1abd213057c4b5bba7c49818853fc901ef09719a60dbf9dec +astroid==4.0.2 \ + --hash=sha256:ac8fb7ca1c08eb9afec91ccc23edbd8ac73bb22cbdd7da1d488d9fb8d6579070 \ + --hash=sha256:d7546c00a12efc32650b19a2bb66a153883185d3179ab0d4868086f807338b9b # via pylint -attrs==25.3.0 \ - --hash=sha256:427318ce031701fea540783410126f03899a97ffc6f61596ad581ac2e40e3bc3 \ - --hash=sha256:75d7cefc7fb576747b2c81b4442d4d4a1ce0900973527c011d1030fd3bf4af1b +attrs==25.4.0 \ + --hash=sha256:16d5969b87f0859ef33a48b35d55ac1be6e42ae49d5e853b597db70c35c57e11 \ + --hash=sha256:adcf7e2a1fb3b36ac48d97835bb6d8ade15b8dcce26aba8bf1d14847b57a3373 # via # jsonschema # referencing # reuse -awscli==1.42.42 \ - --hash=sha256:3924a1d1cef0e79fa77ced138ded610c4eb50e6fb55387ac31f53afaefe7c3f0 \ - --hash=sha256:d33eaa041eeb0e91c3b350b6d642de7c60c7ec252895a89bf1077a4b0bc92c0c +awscli==1.43.11 \ + --hash=sha256:68a89867e83a65c52e73ec44234e88e6b8e3b32fe1707f0d1e09be0fee1b981a \ + --hash=sha256:c86cc6d674f28e04fce2639f60c74f6e6d58402ddc443e8ece75c2e828a6c706 # via -r requirements-actions.in -beartype==0.21.0 \ - --hash=sha256:b6a1bd56c72f31b0a496a36cc55df6e2f475db166ad07fa4acc7e74f4c7f34c0 \ - --hash=sha256:f9a5078f5ce87261c2d22851d19b050b64f6a805439e8793aecf01ce660d3244 +beartype==0.22.8 \ + --hash=sha256:b19b21c9359722ee3f7cc433f063b3e13997b27ae8226551ea5062e621f61165 \ + --hash=sha256:b832882d04e41a4097bab9f63e6992bc6de58c414ee84cba9b45b67314f5ab2e # via spdx-tools -binaryornot==0.4.4 \ - --hash=sha256:359501dfc9d40632edc9fac890e19542db1a287bbcfa58175b66658392018061 \ - --hash=sha256:b8b71173c917bddcd2c16070412e369c3ed7f0528926f70cac18a6c97fd563e4 - # via reuse boolean-py==5.0 \ --hash=sha256:60cbc4bad079753721d32649545505362c754e121570ada4658b852a3a318d95 \ --hash=sha256:ef28a70bd43115208441b53a045d1549e2f0ec6e3d08a9d142cbc41c1938e8d9 - # via - # license-expression - # reuse -botocore==1.40.42 \ - --hash=sha256:2682a4120be21234036003a806206b6b3963ba53a495d0a57d40d67fce4497a9 \ - --hash=sha256:41bea751685fb2a51b4fc6be329a0cd0a285dbeb0686a21099e87ef146664bc0 + # via license-expression +botocore==1.42.5 \ + --hash=sha256:37bfc487f14286d9795920807fcb8318b940835b18fff6bec5253449f377136f \ + --hash=sha256:6aa487f1876c881e2143f6a186b7d8faaf042fc05e0ba7421d821f145356a0c9 # via # awscli # s3transfer -cachetools==6.2.0 \ - --hash=sha256:1c76a8960c0041fcc21097e357f882197c79da0dbff766e7317890a65d7d8ba6 \ - --hash=sha256:38b328c0889450f05f5e120f56ab68c8abaf424e1275522b138ffc93253f7e32 +cachetools==6.2.2 \ + --hash=sha256:6c09c98183bf58560c97b2abfcedcbaf6a896a490f534b031b661d3723b45ace \ + --hash=sha256:8e6d266b25e539df852251cfd6f990b4bc3a141db73b939058d809ebd2590fc6 # via tox canopen==2.4.1 \ --hash=sha256:20a84bc498b34dadd79cece467d3bbe19591c1c02a8f39331bcc6065c4d8b2eb \ --hash=sha256:651dfb189978fb9083f491128e9fb8cb0e85dc8ccb82b12dd7139236d0080b77 # via -r requirements-actions.in -certifi==2025.8.3 \ - --hash=sha256:e564105f78ded564e3ae7c923924435e1daa7463faeab5bb932bc53ffae63407 \ - --hash=sha256:f6c12493cfb1b06ba2ff328595af9350c65d6644968e5d3a2ffd78699af217a5 +certifi==2025.11.12 \ + --hash=sha256:97de8790030bbd5c2d96b7ec782fc2f7820ef8dba6db909ccf95449f2d062d4b \ + --hash=sha256:d8ab5478f2ecd78af242878415affce761ca6bc54a22a27e026d7c25357c3316 # via # elastic-transport # requests @@ -148,115 +142,147 @@ cffi==2.0.0 ; platform_python_implementation != 'PyPy' \ chardet==5.2.0 \ --hash=sha256:1b3b6ff479a8c414bc3fa2c0852995695c4a026dcd6d0633b2dd092ca39c1cf7 \ --hash=sha256:e1cf59446890a00105fe7b7912492ea04b6e6f06d4b742b2c788469e34c82970 - # via - # binaryornot - # tox -charset-normalizer==3.4.3 \ - --hash=sha256:00237675befef519d9af72169d8604a067d92755e84fe76492fef5441db05b91 \ - --hash=sha256:02425242e96bcf29a49711b0ca9f37e451da7c70562bc10e8ed992a5a7a25cc0 \ - --hash=sha256:027b776c26d38b7f15b26a5da1044f376455fb3766df8fc38563b4efbc515154 \ - --hash=sha256:07a0eae9e2787b586e129fdcbe1af6997f8d0e5abaa0bc98c0e20e124d67e601 \ - --hash=sha256:0cacf8f7297b0c4fcb74227692ca46b4a5852f8f4f24b3c766dd94a1075c4884 \ - --hash=sha256:0e78314bdc32fa80696f72fa16dc61168fda4d6a0c014e0380f9d02f0e5d8a07 \ - --hash=sha256:0f2be7e0cf7754b9a30eb01f4295cc3d4358a479843b31f328afd210e2c7598c \ - --hash=sha256:13faeacfe61784e2559e690fc53fa4c5ae97c6fcedb8eb6fb8d0a15b475d2c64 \ - --hash=sha256:14c2a87c65b351109f6abfc424cab3927b3bdece6f706e4d12faaf3d52ee5efe \ - --hash=sha256:1606f4a55c0fd363d754049cdf400175ee96c992b1f8018b993941f221221c5f \ - --hash=sha256:16a8770207946ac75703458e2c743631c79c59c5890c80011d536248f8eaa432 \ - --hash=sha256:18343b2d246dc6761a249ba1fb13f9ee9a2bcd95decc767319506056ea4ad4dc \ - --hash=sha256:18b97b8404387b96cdbd30ad660f6407799126d26a39ca65729162fd810a99aa \ - --hash=sha256:1bb60174149316da1c35fa5233681f7c0f9f514509b8e399ab70fea5f17e45c9 \ - --hash=sha256:1e8ac75d72fa3775e0b7cb7e4629cec13b7514d928d15ef8ea06bca03ef01cae \ - --hash=sha256:1ef99f0456d3d46a50945c98de1774da86f8e992ab5c77865ea8b8195341fc19 \ - --hash=sha256:2001a39612b241dae17b4687898843f254f8748b796a2e16f1051a17078d991d \ - --hash=sha256:23b6b24d74478dc833444cbd927c338349d6ae852ba53a0d02a2de1fce45b96e \ - --hash=sha256:252098c8c7a873e17dd696ed98bbe91dbacd571da4b87df3736768efa7a792e4 \ - --hash=sha256:257f26fed7d7ff59921b78244f3cd93ed2af1800ff048c33f624c87475819dd7 \ - --hash=sha256:2c322db9c8c89009a990ef07c3bcc9f011a3269bc06782f916cd3d9eed7c9312 \ - --hash=sha256:30a96e1e1f865f78b030d65241c1ee850cdf422d869e9028e2fc1d5e4db73b92 \ - --hash=sha256:30d006f98569de3459c2fc1f2acde170b7b2bd265dc1943e87e1a4efe1b67c31 \ - --hash=sha256:31a9a6f775f9bcd865d88ee350f0ffb0e25936a7f930ca98995c05abf1faf21c \ - --hash=sha256:320e8e66157cc4e247d9ddca8e21f427efc7a04bbd0ac8a9faf56583fa543f9f \ - --hash=sha256:34a7f768e3f985abdb42841e20e17b330ad3aaf4bb7e7aeeb73db2e70f077b99 \ - --hash=sha256:3653fad4fe3ed447a596ae8638b437f827234f01a8cd801842e43f3d0a6b281b \ - --hash=sha256:3cd35b7e8aedeb9e34c41385fda4f73ba609e561faedfae0a9e75e44ac558a15 \ - --hash=sha256:3cfb2aad70f2c6debfbcb717f23b7eb55febc0bb23dcffc0f076009da10c6392 \ - --hash=sha256:416175faf02e4b0810f1f38bcb54682878a4af94059a1cd63b8747244420801f \ - --hash=sha256:41d1fc408ff5fdfb910200ec0e74abc40387bccb3252f3f27c0676731df2b2c8 \ - --hash=sha256:42e5088973e56e31e4fa58eb6bd709e42fc03799c11c42929592889a2e54c491 \ - --hash=sha256:4ca4c094de7771a98d7fbd67d9e5dbf1eb73efa4f744a730437d8a3a5cf994f0 \ - --hash=sha256:511729f456829ef86ac41ca78c63a5cb55240ed23b4b737faca0eb1abb1c41bc \ - --hash=sha256:53cd68b185d98dde4ad8990e56a58dea83a4162161b1ea9272e5c9182ce415e0 \ - --hash=sha256:585f3b2a80fbd26b048a0be90c5aae8f06605d3c92615911c3a2b03a8a3b796f \ - --hash=sha256:5b413b0b1bfd94dbf4023ad6945889f374cd24e3f62de58d6bb102c4d9ae534a \ - --hash=sha256:5d8d01eac18c423815ed4f4a2ec3b439d654e55ee4ad610e153cf02faf67ea40 \ - --hash=sha256:6aab0f181c486f973bc7262a97f5aca3ee7e1437011ef0c2ec04b5a11d16c927 \ - --hash=sha256:6cf8fd4c04756b6b60146d98cd8a77d0cdae0e1ca20329da2ac85eed779b6849 \ - --hash=sha256:6fb70de56f1859a3f71261cbe41005f56a7842cc348d3aeb26237560bfa5e0ce \ - --hash=sha256:6fce4b8500244f6fcb71465d4a4930d132ba9ab8e71a7859e6a5d59851068d14 \ - --hash=sha256:70bfc5f2c318afece2f5838ea5e4c3febada0be750fcf4775641052bbba14d05 \ - --hash=sha256:73dc19b562516fc9bcf6e5d6e596df0b4eb98d87e4f79f3ae71840e6ed21361c \ - --hash=sha256:74d77e25adda8581ffc1c720f1c81ca082921329452eba58b16233ab1842141c \ - --hash=sha256:78deba4d8f9590fe4dae384aeff04082510a709957e968753ff3c48399f6f92a \ - --hash=sha256:86df271bf921c2ee3818f0522e9a5b8092ca2ad8b065ece5d7d9d0e9f4849bcc \ - --hash=sha256:88ab34806dea0671532d3f82d82b85e8fc23d7b2dd12fa837978dad9bb392a34 \ - --hash=sha256:8999f965f922ae054125286faf9f11bc6932184b93011d138925a1773830bbe9 \ - --hash=sha256:8dcfc373f888e4fb39a7bc57e93e3b845e7f462dacc008d9749568b1c4ece096 \ - --hash=sha256:939578d9d8fd4299220161fdd76e86c6a251987476f5243e8864a7844476ba14 \ - --hash=sha256:96b2b3d1a83ad55310de8c7b4a2d04d9277d5591f40761274856635acc5fcb30 \ - --hash=sha256:a2d08ac246bb48479170408d6c19f6385fa743e7157d716e144cad849b2dd94b \ - --hash=sha256:b256ee2e749283ef3ddcff51a675ff43798d92d746d1a6e4631bf8c707d22d0b \ - --hash=sha256:b5e3b2d152e74e100a9e9573837aba24aab611d39428ded46f4e4022ea7d1942 \ - --hash=sha256:b89bc04de1d83006373429975f8ef9e7932534b8cc9ca582e4db7d20d91816db \ - --hash=sha256:bd28b817ea8c70215401f657edef3a8aa83c29d447fb0b622c35403780ba11d5 \ - --hash=sha256:c60e092517a73c632ec38e290eba714e9627abe9d301c8c8a12ec32c314a2a4b \ - --hash=sha256:c6dbd0ccdda3a2ba7c2ecd9d77b37f3b5831687d8dc1b6ca5f56a4880cc7b7ce \ - --hash=sha256:c6e490913a46fa054e03699c70019ab869e990270597018cef1d8562132c2669 \ - --hash=sha256:c6f162aabe9a91a309510d74eeb6507fab5fff92337a15acbe77753d88d9dcf0 \ - --hash=sha256:c6fd51128a41297f5409deab284fecbe5305ebd7e5a1f959bee1c054622b7018 \ - --hash=sha256:cc34f233c9e71701040d772aa7490318673aa7164a0efe3172b2981218c26d93 \ - --hash=sha256:cc9370a2da1ac13f0153780040f465839e6cccb4a1e44810124b4e22483c93fe \ - --hash=sha256:ccf600859c183d70eb47e05a44cd80a4ce77394d1ac0f79dbd2dd90a69a3a049 \ - --hash=sha256:ce571ab16d890d23b5c278547ba694193a45011ff86a9162a71307ed9f86759a \ - --hash=sha256:cf1ebb7d78e1ad8ec2a8c4732c7be2e736f6e5123a4146c5b89c9d1f585f8cef \ - --hash=sha256:d0e909868420b7049dafd3a31d45125b31143eec59235311fc4c57ea26a4acd2 \ - --hash=sha256:d22dbedd33326a4a5190dd4fe9e9e693ef12160c77382d9e87919bce54f3d4ca \ - --hash=sha256:d716a916938e03231e86e43782ca7878fb602a125a91e7acb8b5112e2e96ac16 \ - --hash=sha256:d79c198e27580c8e958906f803e63cddb77653731be08851c7df0b1a14a8fc0f \ - --hash=sha256:d95bfb53c211b57198bb91c46dd5a2d8018b3af446583aab40074bf7988401cb \ - --hash=sha256:e28e334d3ff134e88989d90ba04b47d84382a828c061d0d1027b1b12a62b39b1 \ - --hash=sha256:ec557499516fc90fd374bf2e32349a2887a876fbf162c160e3c01b6849eaf557 \ - --hash=sha256:fb6fecfd65564f208cbf0fba07f107fb661bcd1a7c389edbced3f7a493f70e37 \ - --hash=sha256:fb731e5deb0c7ef82d698b0f4c5bb724633ee2a489401594c5c88b02e6cb15f7 \ - --hash=sha256:fb7f67a1bfa6e40b438170ebdc8158b78dc465a5a67b6dde178a46987b244a72 \ - --hash=sha256:fd10de089bcdcd1be95a2f73dbe6254798ec1bda9f450d5828c96f93e2536b9c \ - --hash=sha256:fdabf8315679312cfa71302f9bd509ded4f2f263fb5b765cf1433b39106c3cc9 + # via tox +charset-normalizer==3.4.4 \ + --hash=sha256:027f6de494925c0ab2a55eab46ae5129951638a49a34d87f4c3eda90f696b4ad \ + --hash=sha256:077fbb858e903c73f6c9db43374fd213b0b6a778106bc7032446a8e8b5b38b93 \ + --hash=sha256:0a98e6759f854bd25a58a73fa88833fba3b7c491169f86ce1180c948ab3fd394 \ + --hash=sha256:0d3d8f15c07f86e9ff82319b3d9ef6f4bf907608f53fe9d92b28ea9ae3d1fd89 \ + --hash=sha256:0f04b14ffe5fdc8c4933862d8306109a2c51e0704acfa35d51598eb45a1e89fc \ + --hash=sha256:11d694519d7f29d6cd09f6ac70028dba10f92f6cdd059096db198c283794ac86 \ + --hash=sha256:194f08cbb32dc406d6e1aea671a68be0823673db2832b38405deba2fb0d88f63 \ + --hash=sha256:1bee1e43c28aa63cb16e5c14e582580546b08e535299b8b6158a7c9c768a1f3d \ + --hash=sha256:21d142cc6c0ec30d2efee5068ca36c128a30b0f2c53c1c07bd78cb6bc1d3be5f \ + --hash=sha256:2437418e20515acec67d86e12bf70056a33abdacb5cb1655042f6538d6b085a8 \ + --hash=sha256:244bfb999c71b35de57821b8ea746b24e863398194a4014e4c76adc2bbdfeff0 \ + --hash=sha256:2677acec1a2f8ef614c6888b5b4ae4060cc184174a938ed4e8ef690e15d3e505 \ + --hash=sha256:277e970e750505ed74c832b4bf75dac7476262ee2a013f5574dd49075879e161 \ + --hash=sha256:2aaba3b0819274cc41757a1da876f810a3e4d7b6eb25699253a4effef9e8e4af \ + --hash=sha256:2b7d8f6c26245217bd2ad053761201e9f9680f8ce52f0fcd8d0755aeae5b2152 \ + --hash=sha256:2c9d3c380143a1fedbff95a312aa798578371eb29da42106a29019368a475318 \ + --hash=sha256:3162d5d8ce1bb98dd51af660f2121c55d0fa541b46dff7bb9b9f86ea1d87de72 \ + --hash=sha256:31fd66405eaf47bb62e8cd575dc621c56c668f27d46a61d975a249930dd5e2a4 \ + --hash=sha256:362d61fd13843997c1c446760ef36f240cf81d3ebf74ac62652aebaf7838561e \ + --hash=sha256:376bec83a63b8021bb5c8ea75e21c4ccb86e7e45ca4eb81146091b56599b80c3 \ + --hash=sha256:44c2a8734b333e0578090c4cd6b16f275e07aa6614ca8715e6c038e865e70576 \ + --hash=sha256:47cc91b2f4dd2833fddaedd2893006b0106129d4b94fdb6af1f4ce5a9965577c \ + --hash=sha256:4902828217069c3c5c71094537a8e623f5d097858ac6ca8252f7b4d10b7560f1 \ + --hash=sha256:4bd5d4137d500351a30687c2d3971758aac9a19208fc110ccb9d7188fbe709e8 \ + --hash=sha256:4fe7859a4e3e8457458e2ff592f15ccb02f3da787fcd31e0183879c3ad4692a1 \ + --hash=sha256:542d2cee80be6f80247095cc36c418f7bddd14f4a6de45af91dfad36d817bba2 \ + --hash=sha256:554af85e960429cf30784dd47447d5125aaa3b99a6f0683589dbd27e2f45da44 \ + --hash=sha256:5833d2c39d8896e4e19b689ffc198f08ea58116bee26dea51e362ecc7cd3ed26 \ + --hash=sha256:5947809c8a2417be3267efc979c47d76a079758166f7d43ef5ae8e9f92751f88 \ + --hash=sha256:5ae497466c7901d54b639cf42d5b8c1b6a4fead55215500d2f486d34db48d016 \ + --hash=sha256:5bd2293095d766545ec1a8f612559f6b40abc0eb18bb2f5d1171872d34036ede \ + --hash=sha256:5bfbb1b9acf3334612667b61bd3002196fe2a1eb4dd74d247e0f2a4d50ec9bbf \ + --hash=sha256:5cb4d72eea50c8868f5288b7f7f33ed276118325c1dfd3957089f6b519e1382a \ + --hash=sha256:5dbe56a36425d26d6cfb40ce79c314a2e4dd6211d51d6d2191c00bed34f354cc \ + --hash=sha256:5f819d5fe9234f9f82d75bdfa9aef3a3d72c4d24a6e57aeaebba32a704553aa0 \ + --hash=sha256:64b55f9dce520635f018f907ff1b0df1fdc31f2795a922fb49dd14fbcdf48c84 \ + --hash=sha256:6515f3182dbe4ea06ced2d9e8666d97b46ef4c75e326b79bb624110f122551db \ + --hash=sha256:65e2befcd84bc6f37095f5961e68a6f077bf44946771354a28ad434c2cce0ae1 \ + --hash=sha256:6aee717dcfead04c6eb1ce3bd29ac1e22663cdea57f943c87d1eab9a025438d7 \ + --hash=sha256:6b39f987ae8ccdf0d2642338faf2abb1862340facc796048b604ef14919e55ed \ + --hash=sha256:6e1fcf0720908f200cd21aa4e6750a48ff6ce4afe7ff5a79a90d5ed8a08296f8 \ + --hash=sha256:74018750915ee7ad843a774364e13a3db91682f26142baddf775342c3f5b1133 \ + --hash=sha256:74664978bb272435107de04e36db5a9735e78232b85b77d45cfb38f758efd33e \ + --hash=sha256:74bb723680f9f7a6234dcf67aea57e708ec1fbdf5699fb91dfd6f511b0a320ef \ + --hash=sha256:752944c7ffbfdd10c074dc58ec2d5a8a4cd9493b314d367c14d24c17684ddd14 \ + --hash=sha256:778d2e08eda00f4256d7f672ca9fef386071c9202f5e4607920b86d7803387f2 \ + --hash=sha256:780236ac706e66881f3b7f2f32dfe90507a09e67d1d454c762cf642e6e1586e0 \ + --hash=sha256:798d75d81754988d2565bff1b97ba5a44411867c0cf32b77a7e8f8d84796b10d \ + --hash=sha256:799a7a5e4fb2d5898c60b640fd4981d6a25f1c11790935a44ce38c54e985f828 \ + --hash=sha256:7a32c560861a02ff789ad905a2fe94e3f840803362c84fecf1851cb4cf3dc37f \ + --hash=sha256:7c308f7e26e4363d79df40ca5b2be1c6ba9f02bdbccfed5abddb7859a6ce72cf \ + --hash=sha256:7fa17817dc5625de8a027cb8b26d9fefa3ea28c8253929b8d6649e705d2835b6 \ + --hash=sha256:81d5eb2a312700f4ecaa977a8235b634ce853200e828fbadf3a9c50bab278328 \ + --hash=sha256:82004af6c302b5d3ab2cfc4cc5f29db16123b1a8417f2e25f9066f91d4411090 \ + --hash=sha256:837c2ce8c5a65a2035be9b3569c684358dfbf109fd3b6969630a87535495ceaa \ + --hash=sha256:840c25fb618a231545cbab0564a799f101b63b9901f2569faecd6b222ac72381 \ + --hash=sha256:8a6562c3700cce886c5be75ade4a5db4214fda19fede41d9792d100288d8f94c \ + --hash=sha256:8af65f14dc14a79b924524b1e7fffe304517b2bff5a58bf64f30b98bbc5079eb \ + --hash=sha256:8ef3c867360f88ac904fd3f5e1f902f13307af9052646963ee08ff4f131adafc \ + --hash=sha256:94537985111c35f28720e43603b8e7b43a6ecfb2ce1d3058bbe955b73404e21a \ + --hash=sha256:99ae2cffebb06e6c22bdc25801d7b30f503cc87dbd283479e7b606f70aff57ec \ + --hash=sha256:9a26f18905b8dd5d685d6d07b0cdf98a79f3c7a918906af7cc143ea2e164c8bc \ + --hash=sha256:9b35f4c90079ff2e2edc5b26c0c77925e5d2d255c42c74fdb70fb49b172726ac \ + --hash=sha256:9cd98cdc06614a2f768d2b7286d66805f94c48cde050acdbbb7db2600ab3197e \ + --hash=sha256:9d1bb833febdff5c8927f922386db610b49db6e0d4f4ee29601d71e7c2694313 \ + --hash=sha256:9f7fcd74d410a36883701fafa2482a6af2ff5ba96b9a620e9e0721e28ead5569 \ + --hash=sha256:a59cb51917aa591b1c4e6a43c132f0cdc3c76dbad6155df4e28ee626cc77a0a3 \ + --hash=sha256:a61900df84c667873b292c3de315a786dd8dac506704dea57bc957bd31e22c7d \ + --hash=sha256:a79cfe37875f822425b89a82333404539ae63dbdddf97f84dcbc3d339aae9525 \ + --hash=sha256:a8a8b89589086a25749f471e6a900d3f662d1d3b6e2e59dcecf787b1cc3a1894 \ + --hash=sha256:a8bf8d0f749c5757af2142fe7903a9df1d2e8aa3841559b2bad34b08d0e2bcf3 \ + --hash=sha256:a9768c477b9d7bd54bc0c86dbaebdec6f03306675526c9927c0e8a04e8f94af9 \ + --hash=sha256:ac1c4a689edcc530fc9d9aa11f5774b9e2f33f9a0c6a57864e90908f5208d30a \ + --hash=sha256:af2d8c67d8e573d6de5bc30cdb27e9b95e49115cd9baad5ddbd1a6207aaa82a9 \ + --hash=sha256:b435cba5f4f750aa6c0a0d92c541fb79f69a387c91e61f1795227e4ed9cece14 \ + --hash=sha256:b5b290ccc2a263e8d185130284f8501e3e36c5e02750fc6b6bdeb2e9e96f1e25 \ + --hash=sha256:b5d84d37db046c5ca74ee7bb47dd6cbc13f80665fdde3e8040bdd3fb015ecb50 \ + --hash=sha256:b7cf1017d601aa35e6bb650b6ad28652c9cd78ee6caff19f3c28d03e1c80acbf \ + --hash=sha256:bc7637e2f80d8530ee4a78e878bce464f70087ce73cf7c1caf142416923b98f1 \ + --hash=sha256:c0463276121fdee9c49b98908b3a89c39be45d86d1dbaa22957e38f6321d4ce3 \ + --hash=sha256:c4ef880e27901b6cc782f1b95f82da9313c0eb95c3af699103088fa0ac3ce9ac \ + --hash=sha256:c8ae8a0f02f57a6e61203a31428fa1d677cbe50c93622b4149d5c0f319c1d19e \ + --hash=sha256:ca5862d5b3928c4940729dacc329aa9102900382fea192fc5e52eb69d6093815 \ + --hash=sha256:cb01158d8b88ee68f15949894ccc6712278243d95f344770fa7593fa2d94410c \ + --hash=sha256:cb6254dc36b47a990e59e1068afacdcd02958bdcce30bb50cc1700a8b9d624a6 \ + --hash=sha256:cc00f04ed596e9dc0da42ed17ac5e596c6ccba999ba6bd92b0e0aef2f170f2d6 \ + --hash=sha256:cd09d08005f958f370f539f186d10aec3377d55b9eeb0d796025d4886119d76e \ + --hash=sha256:cd4b7ca9984e5e7985c12bc60a6f173f3c958eae74f3ef6624bb6b26e2abbae4 \ + --hash=sha256:ce8a0633f41a967713a59c4139d29110c07e826d131a316b50ce11b1d79b4f84 \ + --hash=sha256:cead0978fc57397645f12578bfd2d5ea9138ea0fac82b2f63f7f7c6877986a69 \ + --hash=sha256:d055ec1e26e441f6187acf818b73564e6e6282709e9bcb5b63f5b23068356a15 \ + --hash=sha256:d1f13550535ad8cff21b8d757a3257963e951d96e20ec82ab44bc64aeb62a191 \ + --hash=sha256:d9c7f57c3d666a53421049053eaacdd14bbd0a528e2186fcb2e672effd053bb0 \ + --hash=sha256:d9e45d7faa48ee908174d8fe84854479ef838fc6a705c9315372eacbc2f02897 \ + --hash=sha256:da3326d9e65ef63a817ecbcc0df6e94463713b754fe293eaa03da99befb9a5bd \ + --hash=sha256:de00632ca48df9daf77a2c65a484531649261ec9f25489917f09e455cb09ddb2 \ + --hash=sha256:e1f185f86a6f3403aa2420e815904c67b2f9ebc443f045edd0de921108345794 \ + --hash=sha256:e824f1492727fa856dd6eda4f7cee25f8518a12f3c4a56a74e8095695089cf6d \ + --hash=sha256:e912091979546adf63357d7e2ccff9b44f026c075aeaf25a52d0e95ad2281074 \ + --hash=sha256:eaabd426fe94daf8fd157c32e571c85cb12e66692f15516a83a03264b08d06c3 \ + --hash=sha256:ebf3e58c7ec8a8bed6d66a75d7fb37b55e5015b03ceae72a8e7c74495551e224 \ + --hash=sha256:ecaae4149d99b1c9e7b88bb03e3221956f68fd6d50be2ef061b2381b61d20838 \ + --hash=sha256:eecbc200c7fd5ddb9a7f16c7decb07b566c29fa2161a16cf67b8d068bd21690a \ + --hash=sha256:f155a433c2ec037d4e8df17d18922c3a0d9b3232a396690f17175d2946f0218d \ + --hash=sha256:f1e34719c6ed0b92f418c7c780480b26b5d9c50349e9a9af7d76bf757530350d \ + --hash=sha256:f34be2938726fc13801220747472850852fe6b1ea75869a048d6f896838c896f \ + --hash=sha256:f820802628d2694cb7e56db99213f930856014862f3fd943d290ea8438d07ca8 \ + --hash=sha256:f8bf04158c6b607d747e93949aa60618b61312fe647a6369f88ce2ff16043490 \ + --hash=sha256:f8e160feb2aed042cd657a72acc0b481212ed28b1b9a95c0cee1621b524e1966 \ + --hash=sha256:f9d332f8c2a2fcbffe1378594431458ddbef721c1769d78e2cbc06280d8155f9 \ + --hash=sha256:fa09f53c465e532f4d3db095e0c55b615f010ad81803d383195b6b5ca6cbf5f3 \ + --hash=sha256:faa3a41b2b66b6e50f84ae4a68c64fcd0c44355741c6374813a800cd6695db9e \ + --hash=sha256:fd44c878ea55ba351104cb93cc85e74916eb8fa440ca7903e57575e97394f608 # via # python-debian # requests -clang-format==21.1.2 \ - --hash=sha256:00498efb43d60d7ac4195362009a79936d26145a9a90cdfa7a6013a62ab3c40c \ - --hash=sha256:00f4459773ee3e8c0e20578ee800da1fa7fac98c4b0053e13afa450baca0764c \ - --hash=sha256:2d27cf0914430a73886d9a754f08ebccc21048196d958a21d9d47e2632f14b23 \ - --hash=sha256:4071409d8b2cadeab72b0d56111c1703731ee954b686ad0e532c25d9652c3d14 \ - --hash=sha256:5ddf9afd329c2788998a1563f98cc2a0b911497bc79bc22b7d44fd1471c047de \ - --hash=sha256:6d7caf74fe89154258ddfd63984c98ffe902ef98f013ac517178fc44d72861ff \ - --hash=sha256:7e0e98f39f16b93c8740028148c72f9ba64d0a43f51a15fb0e861610c1e1e573 \ - --hash=sha256:8a72398bdcd5e3465dbf10882672f8a51b0beb7a6d8cf4f945d00b6523b4cf91 \ - --hash=sha256:8d54ab01eec27899d104f32f3e7f02032174f88d4f72ba1781b209898ae5407c \ - --hash=sha256:95e74c050cb5246a88ba7306c82dc3a7d6adb5145f49d188d5602967e4133336 \ - --hash=sha256:a1fe2ad12b6779b0e60e43ffe57947f51ea9fe4d5887452a31266bb6bb966195 \ - --hash=sha256:c840849580eb5ad937f0a7fb1b938609e905756ad27d7e63f20ab929d6c0fc8d \ - --hash=sha256:c98e195a50c0fa40bb058449511b1b681ca7ad553579aa32425f0cfeca8d81ce \ - --hash=sha256:ddd64f677912253801e639f2bbe19dfe4b2ac645ddcac340f784b290603c6dd1 \ - --hash=sha256:f316245a46dd9b26baaed33de149e06155ac09166846d9340107779306448b7d \ - --hash=sha256:f66d2bcf98df1373df6ab4544a2b881e9816985b606e1144e4c77dc8ac87b826 \ - --hash=sha256:fbf860495fa096cacd8496d5220b69d2af66f8a55291d09cc03e54ad0e48aac0 \ - --hash=sha256:fc034652dee24583633177d800bc9deebcc9c65eb7ab53b25bbd0fbd443392a9 +clang-format==21.1.7 \ + --hash=sha256:04ff3007e8d77f8232f2ba10a0553d3123423488ec789c1240222a2348f39eba \ + --hash=sha256:1915fc0e0161ddeedb0a83be3a15fe9d6a8529d0f1bbdb59ac1ee58328c5960b \ + --hash=sha256:217b4a9e55d2014797319d99a27acc4dccbe4ab8530f7b18e06e3fb0657aafa5 \ + --hash=sha256:353f400124ae27b1d3f354e64bd1525d5a765f81adc155568c9332ed9ef291b6 \ + --hash=sha256:3ef0603809f2684cb9eea8898f5cc5ac9e2d3ff3f49e3038aef05edf45286c8b \ + --hash=sha256:48d0bba35eb95781dab9f6c49fedf69399ad55469bff63153886950b499b5030 \ + --hash=sha256:4fa43c8ecbf59b49c2eff6ced59e1c8adbd4643cb702393b3937bbbf32a7ab35 \ + --hash=sha256:58ec6d955f1e8bf14a871562d961db114025a74bb990cdcbeb88d8563dd6f8a9 \ + --hash=sha256:69b5ea0d2380c8a6318af4e4f306ccbecfee4d11e896dc59294e60b5f357e3e0 \ + --hash=sha256:6d08f8a279061f63e4ecb30bcd3283b4fd8d1ba532e90be69cb7b270c450890e \ + --hash=sha256:80488d0cd061ac143b71cced03677b0059de4a7fbe69e38ad2c009c03febeb02 \ + --hash=sha256:8e40d359abbd9a280b12b93ce8a6fb73c1f72c32c0a7d5c3843fccc848f6ab24 \ + --hash=sha256:9f024d47ca28663d419d833ab0f950589ffcae40c191f31357533b59fbf9f6f3 \ + --hash=sha256:b915e27db1e4e6ad71db6d34936efcf6f05e751cc32cde1e5596bb26b2dd4d1f \ + --hash=sha256:c57dd938d405c0594a97c7a78391fe96f1ebd76facf67fa305415b1a923a8748 \ + --hash=sha256:c8728aa97cd7cce8c38f7d10c4cd7eca87530553dbf9bf17d7713a2b174a2ede \ + --hash=sha256:cbb6ca72d5198ffaf03fa997c6955f45a26929ba64c057dd7fce3fc7b2ec08a1 \ + --hash=sha256:ee4f47db1c226d9ffd07a4c8a265d7f894149854d0fae72f89a854875bfdf67d # via -r requirements-actions.in -click==8.3.0 \ - --hash=sha256:9b9f285302c6e3064f4330c05f05b81945b2a39544279343e6e7c5f27a9baddc \ - --hash=sha256:e7b8232224eba16f4ebe410c25ced9f7875cb5f3263ffc93cc3e8da705e229c4 +click==8.3.1 \ + --hash=sha256:12ff4785d337a1bb490bb7e9c2b1ee5da3112e94a8622f26a6c77f5d2fc6842a \ + --hash=sha256:981153a64e25f12d547d3426c367a4857371575ee7ad18df2a6183ab0545b2a6 # via # gitlint-core # reuse @@ -272,61 +298,61 @@ colorama==0.4.6 \ # tox # tqdm # west -cryptography==46.0.2 \ - --hash=sha256:04911b149eae142ccd8c9a68892a70c21613864afb47aba92d8c7ed9cc001023 \ - --hash=sha256:07c0eb6657c0e9cca5891f4e35081dbf985c8131825e21d99b4f440a8f496f36 \ - --hash=sha256:0b507c8e033307e37af61cb9f7159b416173bdf5b41d11c4df2e499a1d8e007c \ - --hash=sha256:0c7ffe8c9b1fcbb07a26d7c9fa5e857c2fe80d72d7b9e0353dcf1d2180ae60ee \ - --hash=sha256:1a88634851d9b8de8bb53726f4300ab191d3b2f42595e2581a54b26aba71b7cc \ - --hash=sha256:1d3b3edd145953832e09607986f2bd86f85d1dc9c48ced41808b18009d9f30e5 \ - --hash=sha256:1e3b6428a3d56043bff0bb85b41c535734204e599c1c0977e1d0f261b02f3ad5 \ - --hash=sha256:1fd1a69086926b623ef8126b4c33d5399ce9e2f3fac07c9c734c2a4ec38b6d02 \ - --hash=sha256:218abd64a2e72f8472c2102febb596793347a3e65fafbb4ad50519969da44470 \ - --hash=sha256:21b6fc8c71a3f9a604f028a329e5560009cc4a3a828bfea5fcba8eb7647d88fe \ - --hash=sha256:27c53b4f6a682a1b645fbf1cd5058c72cf2f5aeba7d74314c36838c7cbc06e0f \ - --hash=sha256:2b9cad9cf71d0c45566624ff76654e9bae5f8a25970c250a26ccfc73f8553e2d \ - --hash=sha256:2fafb6aa24e702bbf74de4cb23bfa2c3beb7ab7683a299062b69724c92e0fa73 \ - --hash=sha256:3f37aa12b2d91e157827d90ce78f6180f0c02319468a0aea86ab5a9566da644b \ - --hash=sha256:48b983089378f50cba258f7f7aa28198c3f6e13e607eaf10472c26320332ca9a \ - --hash=sha256:48c01988ecbb32979bb98731f5c2b2f79042a6c58cc9a319c8c2f9987c7f68f9 \ - --hash=sha256:4a766d2a5d8127364fd936572c6e6757682fc5dfcbdba1632d4554943199f2fa \ - --hash=sha256:512c0250065e0a6b286b2db4bbcc2e67d810acd53eb81733e71314340366279e \ - --hash=sha256:5840f05518caa86b09d23f8b9405a7b6d5400085aa14a72a98fdf5cf1568c0d2 \ - --hash=sha256:5e38f203160a48b93010b07493c15f2babb4e0f2319bbd001885adb3f3696d21 \ - --hash=sha256:6b275e398ab3a7905e168c036aad54b5969d63d3d9099a0a66cc147a3cc983be \ - --hash=sha256:7282d8f092b5be7172d6472f29b0631f39f18512a3642aefe52c3c0e0ccfad5a \ - --hash=sha256:747b6f4a4a23d5a215aadd1d0b12233b4119c4313df83ab4137631d43672cc90 \ - --hash=sha256:758cfc7f4c38c5c5274b55a57ef1910107436f4ae842478c4989abbd24bd5acb \ - --hash=sha256:8b16c1ede6a937c291d41176934268e4ccac2c6521c69d3f5961c5a1e11e039e \ - --hash=sha256:8b9bf67b11ef9e28f4d78ff88b04ed0929fcd0e4f70bb0f704cfc32a5c6311ee \ - --hash=sha256:8e2ad4d1a5899b7caa3a450e33ee2734be7cc0689010964703a7c4bcc8dd4fd0 \ - --hash=sha256:9066cfd7f146f291869a9898b01df1c9b0e314bfa182cef432043f13fc462c92 \ - --hash=sha256:91447f2b17e83c9e0c89f133119d83f94ce6e0fb55dd47da0a959316e6e9cfa1 \ - --hash=sha256:97e83bf4f2f2c084d8dd792d13841d0a9b241643151686010866bbd076b19659 \ - --hash=sha256:9bd26f2f75a925fdf5e0a446c0de2714f17819bf560b44b7480e4dd632ad6c46 \ - --hash=sha256:9bdc25e4e01b261a8fda4e98618f1c9515febcecebc9566ddf4a70c63967043b \ - --hash=sha256:9ec3f2e2173f36a9679d3b06d3d01121ab9b57c979de1e6a244b98d51fea1b20 \ - --hash=sha256:9f13b040649bc18e7eb37936009b24fd31ca095a5c647be8bb6aaf1761142bd1 \ - --hash=sha256:a08e7401a94c002e79dc3bc5231b6558cd4b2280ee525c4673f650a37e2c7685 \ - --hash=sha256:a61c154cc5488272a6c4b86e8d5beff4639cdb173d75325ce464d723cda0052b \ - --hash=sha256:bb7fb9cd44c2582aa5990cf61a4183e6f54eea3172e54963787ba47287edd135 \ - --hash=sha256:bca3f0ce67e5a2a2cf524e86f44697c4323a86e0fd7ba857de1c30d52c11ede1 \ - --hash=sha256:bda55e8dbe8533937956c996beaa20266a8eca3570402e52ae52ed60de1faca8 \ - --hash=sha256:be939b99d4e091eec9a2bcf41aaf8f351f312cd19ff74b5c83480f08a8a43e0b \ - --hash=sha256:c4b93af7920cdf80f71650769464ccf1fb49a4b56ae0024173c24c48eb6b1612 \ - --hash=sha256:cb5e8daac840e8879407acbe689a174f5ebaf344a062f8918e526824eb5d97af \ - --hash=sha256:d19f5f48883752b5ab34cff9e2f7e4a7f216296f33714e77d1beb03d108632b6 \ - --hash=sha256:d30bc11d35743bf4ddf76674a0a369ec8a21f87aaa09b0661b04c5f6c46e8d7b \ - --hash=sha256:e12b61e0b86611e3f4c1756686d9086c1d36e6fd15326f5658112ad1f1cc8807 \ - --hash=sha256:e6f6775eaaa08c0eec73e301f7592f4367ccde5e4e4df8e58320f2ebf161ea2c \ - --hash=sha256:e7155c0b004e936d381b15425273aee1cebc94f879c0ce82b0d7fecbf755d53a \ - --hash=sha256:e8633996579961f9b5a3008683344c2558d38420029d3c0bc7ff77c17949a4e1 \ - --hash=sha256:f25a41f5b34b371a06dad3f01799706631331adc7d6c05253f5bca22068c7a34 \ - --hash=sha256:f3e32ab7dd1b1ef67b9232c4cf5e2ee4cd517d4316ea910acaaa9c5712a1c663 \ - --hash=sha256:f9b2dc7668418fb6f221e4bf701f716e05e8eadb4f1988a2487b11aedf8abe62 \ - --hash=sha256:fab8f805e9675e61ed8538f192aad70500fa6afb33a8803932999b1049363a08 \ - --hash=sha256:fe245cf4a73c20592f0f48da39748b3513db114465be78f0a36da847221bd1b4 \ - --hash=sha256:ff798ad7a957a5021dcbab78dfff681f0cf15744d0e6af62bd6746984d9c9e9c +cryptography==46.0.3 \ + --hash=sha256:00a5e7e87938e5ff9ff5447ab086a5706a957137e6e433841e9d24f38a065217 \ + --hash=sha256:01ca9ff2885f3acc98c29f1860552e37f6d7c7d013d7334ff2a9de43a449315d \ + --hash=sha256:09859af8466b69bc3c27bdf4f5d84a665e0f7ab5088412e9e2ec49758eca5cbc \ + --hash=sha256:0abf1ffd6e57c67e92af68330d05760b7b7efb243aab8377e583284dbab72c71 \ + --hash=sha256:1000713389b75c449a6e979ffc7dcc8ac90b437048766cef052d4d30b8220971 \ + --hash=sha256:109d4ddfadf17e8e7779c39f9b18111a09efb969a301a31e987416a0191ed93a \ + --hash=sha256:10b01676fc208c3e6feeb25a8b83d81767e8059e1fe86e1dc62d10a3018fa926 \ + --hash=sha256:10ca84c4668d066a9878890047f03546f3ae0a6b8b39b697457b7757aaf18dbc \ + --hash=sha256:15ab9b093e8f09daab0f2159bb7e47532596075139dd74365da52ecc9cb46c5d \ + --hash=sha256:191bb60a7be5e6f54e30ba16fdfae78ad3a342a0599eb4193ba88e3f3d6e185b \ + --hash=sha256:22d7e97932f511d6b0b04f2bfd818d73dcd5928db509460aaf48384778eb6d20 \ + --hash=sha256:23b1a8f26e43f47ceb6d6a43115f33a5a37d57df4ea0ca295b780ae8546e8044 \ + --hash=sha256:36e627112085bb3b81b19fed209c05ce2a52ee8b15d161b7c643a7d5a88491f3 \ + --hash=sha256:39b6755623145ad5eff1dab323f4eae2a32a77a7abef2c5089a04a3d04366715 \ + --hash=sha256:3b51b8ca4f1c6453d8829e1eb7299499ca7f313900dd4d89a24b8b87c0a780d4 \ + --hash=sha256:402b58fc32614f00980b66d6e56a5b4118e6cb362ae8f3fda141ba4689bd4506 \ + --hash=sha256:416260257577718c05135c55958b674000baef9a1c7d9e8f306ec60d71db850f \ + --hash=sha256:46acf53b40ea38f9c6c229599a4a13f0d46a6c3fa9ef19fc1a124d62e338dfa0 \ + --hash=sha256:4b7387121ac7d15e550f5cb4a43aef2559ed759c35df7336c402bb8275ac9683 \ + --hash=sha256:50fc3343ac490c6b08c0cf0d704e881d0d660be923fd3076db3e932007e726e3 \ + --hash=sha256:516ea134e703e9fe26bcd1277a4b59ad30586ea90c365a87781d7887a646fe21 \ + --hash=sha256:549e234ff32571b1f4076ac269fcce7a808d3bf98b76c8dd560e42dbc66d7d91 \ + --hash=sha256:5d7f93296ee28f68447397bf5198428c9aeeab45705a55d53a6343455dcb2c3c \ + --hash=sha256:5ecfccd2329e37e9b7112a888e76d9feca2347f12f37918facbb893d7bb88ee8 \ + --hash=sha256:6276eb85ef938dc035d59b87c8a7dc559a232f954962520137529d77b18ff1df \ + --hash=sha256:6b5063083824e5509fdba180721d55909ffacccc8adbec85268b48439423d78c \ + --hash=sha256:6eae65d4c3d33da080cff9c4ab1f711b15c1d9760809dad6ea763f3812d254cb \ + --hash=sha256:6f61efb26e76c45c4a227835ddeae96d83624fb0d29eb5df5b96e14ed1a0afb7 \ + --hash=sha256:71e842ec9bc7abf543b47cf86b9a743baa95f4677d22baa4c7d5c69e49e9bc04 \ + --hash=sha256:760f83faa07f8b64e9c33fc963d790a2edb24efb479e3520c14a45741cd9b2db \ + --hash=sha256:78a97cf6a8839a48c49271cdcbd5cf37ca2c1d6b7fdd86cc864f302b5e9bf459 \ + --hash=sha256:7ce938a99998ed3c8aa7e7272dca1a610401ede816d36d0693907d863b10d9ea \ + --hash=sha256:8a6e050cb6164d3f830453754094c086ff2d0b2f3a897a1d9820f6139a1f0914 \ + --hash=sha256:9394673a9f4de09e28b5356e7fff97d778f8abad85c9d5ac4a4b7e25a0de7717 \ + --hash=sha256:94cd0549accc38d1494e1f8de71eca837d0509d0d44bf11d158524b0e12cebf9 \ + --hash=sha256:a04bee9ab6a4da801eb9b51f1b708a1b5b5c9eb48c03f74198464c66f0d344ac \ + --hash=sha256:a23582810fedb8c0bc47524558fb6c56aac3fc252cb306072fd2815da2a47c32 \ + --hash=sha256:a2c0cd47381a3229c403062f764160d57d4d175e022c1df84e168c6251a22eec \ + --hash=sha256:a8b17438104fed022ce745b362294d9ce35b4c2e45c1d958ad4a4b019285f4a1 \ + --hash=sha256:a9a3008438615669153eb86b26b61e09993921ebdd75385ddd748702c5adfddb \ + --hash=sha256:b02cf04496f6576afffef5ddd04a0cb7d49cf6be16a9059d793a30b035f6b6ac \ + --hash=sha256:b419ae593c86b87014b9be7396b385491ad7f320bde96826d0dd174459e54665 \ + --hash=sha256:c0a7bb1a68a5d3471880e264621346c48665b3bf1c3759d682fc0864c540bd9e \ + --hash=sha256:c70cc23f12726be8f8bc72e41d5065d77e4515efae3690326764ea1b07845cfb \ + --hash=sha256:c8daeb2d2174beb4575b77482320303f3d39b8e81153da4f0fb08eb5fe86a6c5 \ + --hash=sha256:cb3d760a6117f621261d662bccc8ef5bc32ca673e037c83fbe565324f5c46936 \ + --hash=sha256:d55f3dffadd674514ad19451161118fd010988540cee43d8bc20675e775925de \ + --hash=sha256:d89c3468de4cdc4f08a57e214384d0471911a3830fcdaf7a8cc587e42a866372 \ + --hash=sha256:db391fa7c66df6762ee3f00c95a89e6d428f4d60e7abc8328f4fe155b5ac6e54 \ + --hash=sha256:dfb781ff7eaa91a6f7fd41776ec37c5853c795d3b358d4896fdbb5df168af422 \ + --hash=sha256:e5bf0ed4490068a2e72ac03d786693adeb909981cc596425d09032d372bcc849 \ + --hash=sha256:e7aec276d68421f9574040c26e2a7c3771060bc0cff408bae1dcb19d3ab1e63c \ + --hash=sha256:ef639cb3372f69ec44915fafcd6698b6cc78fbe0c2ea41be867f6ed612811963 \ + --hash=sha256:f260d0d41e9b4da1ed1e0f1ce571f97fe370b152ab18778e9e8f67d6af432018 # via pyjwt dill==0.4.0 \ --hash=sha256:0633f1d2df477324f53a895b02c901fb961bdbf65a17122586ea7019292cbcf0 \ @@ -347,19 +373,19 @@ elastic-transport==8.17.1 \ --hash=sha256:192718f498f1d10c5e9aa8b9cf32aed405e469a7f0e9d6a8923431dbb2c59fb8 \ --hash=sha256:5edef32ac864dca8e2f0a613ef63491ee8d6b8cfb52881fa7313ba9290cac6d2 # via elasticsearch -elasticsearch==8.19.1 \ - --hash=sha256:7192cd6eff2d6ab48f2858265dea717d15ab42f04cfdc4f571a811bcfcbc7a3a \ - --hash=sha256:b511dd4cc26aef1fc02c1b5c1eefe9f16d76127d8f133b0f6900fd052c48d2a4 +elasticsearch==8.19.2 \ + --hash=sha256:622efa6a3e662db45285f16ab57bf198ea73ac9e137e7ed8b1d1d1e47638959d \ + --hash=sha256:c16ba20c4c76cf6952e836dae7f4e724e00ba7bf31b94b79472b873683accdd4 # via -r requirements-actions.in -exceptiongroup==1.3.0 \ - --hash=sha256:4d111e6e0c13d0644cad6ddaa7ed0261a0b36971f6d23e7ec9b4b9097da78a10 \ - --hash=sha256:b241f5885f560bc56a59ee63ca4c6a8bfa46ae4ad651af316d4e81817bb9fd88 +exceptiongroup==1.3.1 \ + --hash=sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219 \ + --hash=sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598 # via # -r requirements-actions.in # pytest -filelock==3.19.1 \ - --hash=sha256:66eda1888b0171c998b35be2bcc0f6d75c388a7ce20c3f3f37aa8e96c2dddf58 \ - --hash=sha256:d38e30481def20772f5baf097c122c3babc4fcdb7e14e57049eb9d88c6dc017d +filelock==3.20.0 \ + --hash=sha256:339b4732ffda5cd79b13f4e2711a31b0365ce445d95d243bb996273d072546a2 \ + --hash=sha256:711e943b4ec6be42e1d4e6690b48dc175c822967466bb31c0c293f34334c13f4 # via # tox # virtualenv @@ -379,100 +405,110 @@ gitpython==3.1.45 \ --hash=sha256:85b0ee964ceddf211c41b9f27a49086010a190fd8132a24e21f362a4b36a791c \ --hash=sha256:8908cb2e02fb3b93b7eb0f2827125cb699869470432cc885f019b8fd0fccff77 # via -r requirements-actions.in -idna==3.10 \ - --hash=sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9 \ - --hash=sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3 +idna==3.11 \ + --hash=sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea \ + --hash=sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902 # via requests -ijson==3.4.0 \ - --hash=sha256:06b89960f5c721106394c7fba5760b3f67c515b8eb7d80f612388f5eca2f4621 \ - --hash=sha256:0772638efa1f3b72b51736833404f1cbd2f5beeb9c1a3d392e7d385b9160cba7 \ - --hash=sha256:0ab00d75d61613a125fbbb524551658b1ad6919a52271ca16563ca5bc2737bb1 \ - --hash=sha256:0b1be1781792291e70d2e177acf564ec672a7907ba74f313583bdf39fe81f9b7 \ - --hash=sha256:0b67727aaee55d43b2e82b6a866c3cbcb2b66a5e9894212190cbd8773d0d9857 \ - --hash=sha256:0bed8bcb84d3468940f97869da323ba09ae3e6b950df11dea9b62e2b231ca1e3 \ - --hash=sha256:0f79b2cd52bd220fff83b3ee4ef89b54fd897f57cc8564a6d8ab7ac669de3930 \ - --hash=sha256:13fb6d5c35192c541421f3ee81239d91fc15a8d8f26c869250f941f4b346a86c \ - --hash=sha256:1504cec7fe04be2bb0cc33b50c9dd3f83f98c0540ad4991d4017373b7853cfe6 \ - --hash=sha256:160b09273cb42019f1811469508b0a057d19f26434d44752bde6f281da6d3f32 \ - --hash=sha256:17994696ec895d05e0cfa21b11c68c920c82634b4a3d8b8a1455d6fe9fdee8f7 \ - --hash=sha256:1c28c7f604729be22aa453e604e9617b665fa0c24cd25f9f47a970e8130c571a \ - --hash=sha256:1eebd9b6c20eb1dffde0ae1f0fbb4aeacec2eb7b89adb5c7c0449fc9fd742760 \ - --hash=sha256:2019ff4e6f354aa00c76c8591bd450899111c61f2354ad55cc127e2ce2492c44 \ - --hash=sha256:26e7da0a3cd2a56a1fde1b34231867693f21c528b683856f6691e95f9f39caec \ - --hash=sha256:28b7196ff7b37c4897c547a28fa4876919696739fc91c1f347651c9736877c69 \ - --hash=sha256:296bc824f4088f2af814aaf973b0435bc887ce3d9f517b1577cc4e7d1afb1cb7 \ - --hash=sha256:2a753be681ac930740a4af9c93cfb4edc49a167faed48061ea650dc5b0f406f1 \ - --hash=sha256:2d9ca52f5650d820a2e7aa672dea1c560f609e165337e5b3ed7cf56d696bf309 \ - --hash=sha256:2dcb190227b09dd171bdcbfe4720fddd574933c66314818dfb3960c8a6246a77 \ - --hash=sha256:2f2ff456adeb216603e25d7915f10584c1b958b6eafa60038d76d08fc8a5fb06 \ - --hash=sha256:3c2691d2da42629522140f77b99587d6f5010440d58d36616f33bc7bdc830cc3 \ - --hash=sha256:3d8a0d67f36e4fb97c61a724456ef0791504b16ce6f74917a31c2e92309bbeb9 \ - --hash=sha256:3e3ddd46d16b8542c63b1b8af7006c758d4e21cc1b86122c15f8530fae773461 \ - --hash=sha256:41dbb525666017ad856ac9b4f0f4b87d3e56b7dfde680d5f6d123556b22e2172 \ - --hash=sha256:42ace5e940e0cf58c9de72f688d6829ddd815096d07927ee7e77df2648006365 \ - --hash=sha256:4563e603e56f4451572d96b47311dffef5b933d825f3417881d4d3630c6edac2 \ - --hash=sha256:494eeb8e87afef22fbb969a4cb81ac2c535f30406f334fb6136e9117b0bb5380 \ - --hash=sha256:49bf8eac1c7b7913073865a859c215488461f7591b4fa6a33c14b51cb73659d0 \ - --hash=sha256:4ab4bc2119b35c4363ea49f29563612237cae9413d2fbe54b223be098b97bc9e \ - --hash=sha256:54e989c35dba9cf163d532c14bcf0c260897d5f465643f0cd1fba9c908bed7ef \ - --hash=sha256:56679ee133470d0f1f598a8ad109d760fcfebeef4819531e29335aefb7e4cb1a \ - --hash=sha256:583c15ded42ba80104fa1d0fa0dfdd89bb47922f3bb893a931bb843aeb55a3f3 \ - --hash=sha256:5be39a0df4cd3f02b304382ea8885391900ac62e95888af47525a287c50005e9 \ - --hash=sha256:5d05bd8fa6a8adefb32bbf7b993d2a2f4507db08453dd1a444c281413a6d9685 \ - --hash=sha256:5f74dcbad9d592c428d3ca3957f7115a42689ee7ee941458860900236ae9bb13 \ - --hash=sha256:68c83161b052e9f5dc8191acbc862bb1e63f8a35344cb5cd0db1afd3afd487a6 \ - --hash=sha256:6b3aac1d7a27e1e3bdec5bd0689afe55c34aa499baa06a80852eda31f1ffa6dc \ - --hash=sha256:71523f2b64cb856a820223e94d23e88369f193017ecc789bb4de198cc9d349eb \ - --hash=sha256:72e92de999977f4c6b660ffcf2b8d59604ccd531edcbfde05b642baf283e0de8 \ - --hash=sha256:784ae654aa9851851e87f323e9429b20b58a5399f83e6a7e348e080f2892081f \ - --hash=sha256:7ca72ca12e9a1dd4252c97d952be34282907f263f7e28fcdff3a01b83981e837 \ - --hash=sha256:80f50e0f5da4cd6b65e2d8ff38cb61b26559608a05dd3a3f9cfa6f19848e6f22 \ - --hash=sha256:8100f9885eff1f38d35cef80ef759a1bbf5fc946349afa681bd7d0e681b7f1a0 \ - --hash=sha256:8145f8f40617b6a8aa24e28559d0adc8b889e56a203725226a8a60fa3501073f \ - --hash=sha256:81603de95de1688958af65cd2294881a4790edae7de540b70c65c8253c5dc44a \ - --hash=sha256:8524be12c1773e1be466034cc49c1ecbe3d5b47bb86217bd2a57f73f970a6c19 \ - --hash=sha256:8a990401dc7350c1739f42187823e68d2ef6964b55040c6e9f3a29461f9929e2 \ - --hash=sha256:8bc731cf1c3282b021d3407a601a5a327613da9ad3c4cecb1123232623ae1826 \ - --hash=sha256:8c75e82cec05d00ed3a4af5f4edf08f59d536ed1a86ac7e84044870872d82a33 \ - --hash=sha256:8e6b44b6ec45d5b1a0ee9d97e0e65ab7f62258727004cbbe202bf5f198bc21f7 \ - --hash=sha256:915a65e3f3c0eee2ea937bc62aaedb6c14cc1e8f0bb9f3f4fb5a9e2bbfa4b480 \ - --hash=sha256:931c007bf6bb8330705429989b2deed6838c22b63358a330bf362b6e458ba0bf \ - --hash=sha256:940c8c5fd20fb89b56dde9194a4f1c7b779149f1ab26af6d8dc1da51a95d26dd \ - --hash=sha256:956b148f88259a80a9027ffbe2d91705fae0c004fbfba3e5a24028fbe72311a9 \ - --hash=sha256:97b0a9b5a15e61dfb1f14921ea4e0dba39f3a650df6d8f444ddbc2b19b479ff1 \ - --hash=sha256:9a0bb591cf250dd7e9dfab69d634745a7f3272d31cfe879f9156e0a081fd97ee \ - --hash=sha256:9c55f48181e11c597cd7146fb31edc8058391201ead69f8f40d2ecbb0b3e4fc6 \ - --hash=sha256:9e369bf5a173ca51846c243002ad8025d32032532523b06510881ecc8723ee54 \ - --hash=sha256:9e9602157a5b869d44b6896e64f502c712a312fcde044c2e586fccb85d3e316e \ - --hash=sha256:a07c47aed534e0ec198e6a2d4360b259d32ac654af59c015afc517ad7973b7fb \ - --hash=sha256:a9f84f5e2eea5c2d271c97221c382db005534294d1175ddd046a12369617c41c \ - --hash=sha256:abd5669f96f79d8a2dd5ae81cbd06770a4d42c435fd4a75c74ef28d9913b697d \ - --hash=sha256:ada421fd59fe2bfa4cfa64ba39aeba3f0753696cdcd4d50396a85f38b1d12b01 \ - --hash=sha256:afbe9748707684b6c5adc295c4fdcf27765b300aec4d484e14a13dca4e5c0afa \ - --hash=sha256:b1e83660edb931a425b7ff662eb49db1f10d30ca6d4d350e5630edbed098bc01 \ - --hash=sha256:b51e239e4cb537929796e840d349fc731fdc0d58b1a0683ce5465ad725321e0f \ - --hash=sha256:b5a05fd935cc28786b88c16976313086cd96414c6a3eb0a3822c47ab48b1793e \ - --hash=sha256:b674a97bd503ea21bc85103e06b6493b1b2a12da3372950f53e1c664566a33a4 \ - --hash=sha256:b8a0a2c54f3becf76881188beefd98b484b1d3bd005769a740d5b433b089fa23 \ - --hash=sha256:c0cd126c11835839bba8ac0baaba568f67d701fc4f717791cf37b10b74a2ebd7 \ - --hash=sha256:c4554718c275a044c47eb3874f78f2c939f300215d9031e785a6711cc51b83fc \ - --hash=sha256:c45906ce2c1d3b62f15645476fc3a6ca279549127f01662a39ca5ed334a00cf9 \ - --hash=sha256:cdc8c5ca0eec789ed99db29c68012dda05027af0860bb360afd28d825238d69d \ - --hash=sha256:ced19a83ab09afa16257a0b15bc1aa888dbc555cb754be09d375c7f8d41051f2 \ - --hash=sha256:cfeca1aaa59d93fd0a3718cbe5f7ef0effff85cf837e0bceb71831a47f39cc14 \ - --hash=sha256:d16eed737610ad5ad8989b5864fbe09c64133129734e840c29085bb0d497fb03 \ - --hash=sha256:d7bcc3f7f21b0f703031ecd15209b1284ea51b2a329d66074b5261de3916c1eb \ - --hash=sha256:d823f8f321b4d8d5fa020d0a84f089fec5d52b7c0762430476d9f8bf95bbc1a9 \ - --hash=sha256:e27e50f6dcdee648f704abc5d31b976cd2f90b4642ed447cf03296d138433d09 \ - --hash=sha256:e3047bb994dabedf11de11076ed1147a307924b6e5e2df6784fb2599c4ad8c60 \ - --hash=sha256:e8d96f88d75196a61c9d9443de2b72c2d4a7ba9456ff117b57ae3bba23a54256 \ - --hash=sha256:ed05d43ec02be8ddb1ab59579761f6656b25d241a77fd74f4f0f7ec09074318a \ - --hash=sha256:eda4cfb1d49c6073a901735aaa62e39cb7ab47f3ad7bb184862562f776f1fa8a \ - --hash=sha256:f9a9d3bbc6d91c24a2524a189d2aca703cb5f7e8eb34ad0aff3c91702404a983 +ijson==3.4.0.post0 \ + --hash=sha256:01767fcbd75a5fa5a626069787b41f04681216b798510d5f63bcf66884386368 \ + --hash=sha256:043f9b7cf9cc744263a78175e769947733710d2412d25180df44b1086b23ebd5 \ + --hash=sha256:04ac9ca54db20f82aeda6379b5f4f6112fdb150d09ebce04affeab98a17b4ed3 \ + --hash=sha256:05807edc0bcbd222dc6ea32a2b897f0c81dc7f12c8580148bc82f6d7f5e7ec7b \ + --hash=sha256:0634b21188c67e5cf471cc1d30d193d19f521d89e2125ab1fb602aa8ae61e050 \ + --hash=sha256:07f20ecd748602ac7f18c617637e53bd73ded7f3b22260bba3abe401a7fc284e \ + --hash=sha256:09127c06e5dec753feb9e4b8c5f6a23603d1cd672d098159a17e53a73b898eec \ + --hash=sha256:0b473112e72c0c506da425da3278367b6680f340ecc093084693a1e819d28435 \ + --hash=sha256:0d3e82963096579d1385c06b2559570d7191e225664b7fa049617da838e1a4a4 \ + --hash=sha256:103a0838061297d063bca81d724b0958b616f372bd893bbc278320152252c652 \ + --hash=sha256:114ed248166ac06377e87a245a158d6b98019d2bdd3bb93995718e0bd996154f \ + --hash=sha256:11f13b73194ea2a5a8b4a2863f25b0b4624311f10db3a75747b510c4958179b0 \ + --hash=sha256:1709171023ce82651b2f132575c2e6282e47f64ad67bd3260da476418d0e7895 \ + --hash=sha256:17e45262a5ddef39894013fb1548ee7094e444c8389eb1a97f86708b19bea03e \ + --hash=sha256:226447e40ca9340a39ed07d68ea02ee14b52cb4fe649425b256c1f0073531c83 \ + --hash=sha256:254cfb8c124af68327a0e7a49b50bbdacafd87c4690a3d62c96eb01020a685ef \ + --hash=sha256:27aa193d47ffc6bc4e45453896ad98fb089a367e8283b973f1fe5c0198b60b4e \ + --hash=sha256:2c88f0669d45d4b1aa017c9b68d378e7cd15d188dfb6f0209adc78b7f45590a7 \ + --hash=sha256:2f8b9ffa2c2dfe3289da9aec4e5ab52684fa2b2da2c853c7891b360ec46fba07 \ + --hash=sha256:339d49f6c5d24051c85d9226be96d2d56e633cb8b7d09dd8099de8d8b51a97e2 \ + --hash=sha256:3505dff18bdeb8b171eb28af6df34857e2be80dc01e2e3b624e77215ad58897f \ + --hash=sha256:35aaa979da875fa92bea5dc5969b1541b4912b165091761785459a43f0c20946 \ + --hash=sha256:35eb2760a42fd9461358b4be131287587b49ff504fc37fa3014dca6c27c343f4 \ + --hash=sha256:3752dd6f51ef58a71799de745649deff293e959700f1b7f5b1989618da366f24 \ + --hash=sha256:3ed19b1e4349240773a8ce4a4bfa450892d4a57949c02c515cd6be5a46b7696a \ + --hash=sha256:40007c977e230e04118b27322f25a72ae342a3d61464b2057fcd9b21eeb7427a \ + --hash=sha256:43059ae0d657b11c5ddb11d149bc400c44f9e514fb8663057e9b2ea4d8d44c1f \ + --hash=sha256:432fb60ffb952926f9438e0539011e2dfcd108f8426ee826ccc6173308c3ff2c \ + --hash=sha256:435270a4b75667305f6df3226e5224e83cd6906022d7fdcc9df05caae725f796 \ + --hash=sha256:45a0b1c833ed2620eaf8da958f06ac8351c59e5e470e078400d23814670ed708 \ + --hash=sha256:461acf4320219459dabe5ed90a45cb86c9ba8cc6d6db9dad0d9427d42f57794c \ + --hash=sha256:461ce4e87a21a261b60c0a68a2ad17c7dd214f0b90a0bec7e559a66b6ae3bd7e \ + --hash=sha256:47352563e8c594360bacee2e0753e97025f0861234722d02faace62b1b6d2b2a \ + --hash=sha256:4810546e66128af51fd4a0c9a640e84e8508e9c15c4f247d8a3e3253b20e1465 \ + --hash=sha256:4827d9874a6a81625412c59f7ca979a84d01f7f6bfb3c6d4dc4c46d0382b14e0 \ + --hash=sha256:4e39bfdc36b0b460ef15a06550a6a385c64c81f7ac205ccff39bd45147918912 \ + --hash=sha256:54a0e3e05d9a0c95ecba73d9579f146cf6d5c5874116c849dba2d39a5f30380e \ + --hash=sha256:55f7f656b5986326c978cbb3a9eea9e33f3ef6ecc4535b38f1d452c731da39ab \ + --hash=sha256:56169e298c5a2e7196aaa55da78ddc2415876a74fe6304f81b1eb0d3273346f7 \ + --hash=sha256:56b3089dc28c12492d92cc4896d2be585a89ecae34e25d08c1df88f21815cb50 \ + --hash=sha256:57db77f4ea3eca09f519f627d9f9c76eb862b30edef5d899f031feeed94f05a1 \ + --hash=sha256:5a48b9486242d1295abe7fd0fbb6308867da5ca3f69b55c77922a93c2b6847aa \ + --hash=sha256:5f0a72b1e3c0f78551670c12b2fdc1bf05f2796254d9c2055ba319bec2216020 \ + --hash=sha256:61ab0b8c5bf707201dc67e02c116f4b6545c4afd7feb2264b989d242d9c4348a \ + --hash=sha256:636b6eca96c6c43c04629c6b37fad0181662eaacf9877c71c698485637f752f9 \ + --hash=sha256:6458bd8e679cdff459a0a5e555b107c3bbacb1f382da3fe0f40e392871eb518d \ + --hash=sha256:659acb2843433e080c271ecedf7d19c71adde1ee5274fc7faa2fec0a793f9f1c \ + --hash=sha256:6793c29a5728e7751a7df01be58ba7da9b9690c12bf79d32094c70a908fa02b9 \ + --hash=sha256:69718ed41710dfcaa7564b0af42abc05875d4f7aaa24627c808867ef32634bc7 \ + --hash=sha256:7206afcb396aaef66c2b066997b4e9d9042c4b7d777f4d994e9cec6d322c2fe6 \ + --hash=sha256:742c211b004ab51ccad2b301525d8a6eb2cf68a5fb82d78836f3a351eec44d4e \ + --hash=sha256:7809ec8c8f40228edaaa089f33e811dff4c5b8509702652870d3f286c9682e27 \ + --hash=sha256:8311f48db6a33116db5c81682f08b6e2405501a4b4e460193ae69fec3cd1f87a \ + --hash=sha256:83fc738d81c9ea686b452996110b8a6678296c481e0546857db24785bff8da92 \ + --hash=sha256:890cf6610c9554efcb9765a93e368efeb5bb6135f59ce0828d92eaefff07fde5 \ + --hash=sha256:8f904a405b58a04b6ef0425f1babbc5c65feb66b0a4cc7f214d4ad7de106f77d \ + --hash=sha256:91c61a3e63e04da648737e6b4abd537df1b46fb8cdf3219b072e790bb3c1a46b \ + --hash=sha256:97f5ef3d839fc24b0ad47e8b31b4751ae72c5d83606e3ee4c92bb25965c03a4f \ + --hash=sha256:9aa02dc70bb245670a6ca7fba737b992aeeb4895360980622f7e568dbf23e41e \ + --hash=sha256:9c0886234d1fae15cf4581a430bdba03d79251c1ab3b07e30aa31b13ef28d01c \ + --hash=sha256:a07dcc1a8a1ddd76131a7c7528cbd12951c2e34eb3c3d63697b905069a2d65b1 \ + --hash=sha256:a0fedf09c0f6ffa2a99e7e7fd9c5f3caf74e655c1ee015a0797383e99382ebc3 \ + --hash=sha256:a2c873742e9f7e21378516217d81d6fa11d34bae860ed364832c00ab1dbf37ed \ + --hash=sha256:a39d5d36067604b26b78de70b8951c90e9272450642661fe531a8f7a6936a7fa \ + --hash=sha256:a5269af16f715855d9864937f9dd5c348ca1ac49cee6a2c7a1b7091c159e874f \ + --hash=sha256:a56b6674d7feec0401c91f86c376f4e3d8ff8129128a8ad21ca43ec0b1242f79 \ + --hash=sha256:a603d7474bf35e7b3a8e49c8dabfc4751841931301adff3f3318171c4e407f32 \ + --hash=sha256:ab3be841b8c430c1883b8c0775eb551f21b5500c102c7ee828afa35ddd701bdd \ + --hash=sha256:add9242f886eae844a7410b84aee2bbb8bdc83c624f227cb1fdb2d0476a96cb1 \ + --hash=sha256:b005ce84e82f28b00bf777a464833465dfe3efa43a0a26c77b5ac40723e1a728 \ + --hash=sha256:b200df83c901f5bfa416d069ac71077aa1608f854a4c50df1b84ced560e9c9ec \ + --hash=sha256:b2a81aee91633868f5b40280e2523f7c5392e920a5082f47c5e991e516b483f6 \ + --hash=sha256:b39dbf87071f23a23c8077eea2ae7cfeeca9ff9ffec722dfc8b5f352e4dd729c \ + --hash=sha256:b55e49045f4c8031f3673f56662fd828dc9e8d65bd3b03a9420dda0d370e64ba \ + --hash=sha256:b607a500fca26101be47d2baf7cddb457b819ab60a75ce51ed1092a40da8b2f9 \ + --hash=sha256:b982a3597b0439ce9c8f4cfc929d86c6ed43907908be1e8463a34dc35fe5b258 \ + --hash=sha256:ba3478ff0bb49d7ba88783f491a99b6e3fa929c930ab062d2bb7837e6a38fe88 \ + --hash=sha256:c117321cfa7b749cc1213f9b4c80dc958f0a206df98ec038ae4bcbbdb8463a15 \ + --hash=sha256:c8dd327da225887194fe8b93f2b3c9c256353e14a6b9eefc940ed17fde38f5b8 \ + --hash=sha256:ccddb2894eb7af162ba43b9475ac5825d15d568832f82eb8783036e5d2aebd42 \ + --hash=sha256:cf24a48a1c3ca9d44a04feb59ccefeb9aa52bb49b9cb70ad30518c25cce74bb7 \ + --hash=sha256:cf4a34c2cfe852aee75c89c05b0a4531c49dc0be27eeed221afd6fbf9c3e149c \ + --hash=sha256:d14427d366f95f21adcb97d0ed1f6d30f6fdc04d0aa1e4de839152c50c2b8d65 \ + --hash=sha256:d4d4afec780881edb2a0d2dd40b1cdbe246e630022d5192f266172a0307986a7 \ + --hash=sha256:da6a21b88cbf5ecbc53371283988d22c9643aa71ae2873bbeaefd2dea3b6160b \ + --hash=sha256:deda4cfcaafa72ca3fa845350045b1d0fef9364ec9f413241bb46988afbe6ee6 \ + --hash=sha256:e15833dcf6f6d188fdc624a31cd0520c3ba21b6855dc304bc7c1a8aeca02d4ac \ + --hash=sha256:eb5e73028f6e63d27b3d286069fe350ed80a4ccc493b022b590fea4bb086710d \ + --hash=sha256:ec5bb1520cb212ebead7dba048bb9b70552c3440584f83b01b0abc96862e2a09 \ + --hash=sha256:eeb9540f0b1a575cbb5968166706946458f98c16e7accc6f2fe71efa29864241 \ + --hash=sha256:f82ca7abfb3ef3cf2194c71dad634572bcccd62a5dd466649f78fe73d492c860 \ + --hash=sha256:f932969fc1fd4449ca141cf5f47ff357656a154a361f28d9ebca0badc5b02297 \ + --hash=sha256:fe9c84c9b1c8798afa407be1cea1603401d99bfc7c34497e19f4f5e5ddc9b441 \ + --hash=sha256:fecae19b5187d92900c73debb3a979b0b3290a53f85df1f8f3c5ba7d1e9fb9cb \ + --hash=sha256:ffb21203736b08fe27cb30df6a4f802fafb9ef7646c5ff7ef79569b63ea76c57 # via -r requirements-actions.in -iniconfig==2.1.0 \ - --hash=sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7 \ - --hash=sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760 +iniconfig==2.3.0 \ + --hash=sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730 \ + --hash=sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12 # via pytest intelhex==2.3.0 \ --hash=sha256:87cc5225657524ec6361354be928adfd56bcf2a3dcc646c40f8f094c39c07db4 \ @@ -482,9 +518,9 @@ isodate==0.7.2 ; python_full_version < '3.11' \ --hash=sha256:28009937d8031054830160fce6d409ed342816b543597cece116d966c6d99e15 \ --hash=sha256:4cd1aa0f43ca76f4a6c6c0292a85f40b35ec2e43e315b59f06e6d32171a953e6 # via rdflib -isort==6.1.0 \ - --hash=sha256:58d8927ecce74e5087aef019f778d4081a3b6c98f15a80ba35782ca8a2097784 \ - --hash=sha256:9b8f96a14cfee0677e78e941ff62f03769a06d412aabb9e2a90487b3b7e8d481 +isort==7.0.0 \ + --hash=sha256:1bcabac8bc3c36c7fb7b98a76c8abb18e0f841a3ba81decac7691008592499c1 \ + --hash=sha256:5513527951aadb3ac4292a41a16cbc50dd1642432f5e8c20057d414bdafb4187 # via pylint jinja2==3.1.6 \ --hash=sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d \ @@ -505,13 +541,91 @@ jsonschema-specifications==2025.9.1 \ --hash=sha256:98802fee3a11ee76ecaca44429fda8a41bff98b00a0f2838151b113f210cc6fe \ --hash=sha256:b540987f239e745613c7a9176f3edb72b832a4ac465cf02712288397832b5e8d # via jsonschema -junit2html==31.0.2 \ - --hash=sha256:c7fd1f253d423f0df031d0cee8ef7d4d98d9f8bf6383a2d40dca639686814866 +junit2html==31.0.5 \ + --hash=sha256:7e9872325b99348f51cd1c6446f5d2426e96263cdbcf1e394191429d6a9af9f6 # via -r requirements-actions.in junitparser==4.0.2 \ --hash=sha256:94c3570e41fcaedc64cc3c634ca99457fe41a84dd1aa8ff74e9e12e66223a155 \ --hash=sha256:d5d07cece6d4a600ff3b7b96c8db5ffa45a91eed695cb86c45c3db113c1ca0f8 # via -r requirements-actions.in +librt==0.7.3 \ + --hash=sha256:020c6db391268bcc8ce75105cb572df8cb659a43fd347366aaa407c366e5117a \ + --hash=sha256:0fa9ac2e49a6bee56e47573a6786cb635e128a7b12a0dc7851090037c0d397a3 \ + --hash=sha256:11ad45122bbed42cfc8b0597450660126ef28fd2d9ae1a219bc5af8406f95678 \ + --hash=sha256:120dd21d46ff875e849f1aae19346223cf15656be489242fe884036b23d39e93 \ + --hash=sha256:14569ac5dd38cfccf0a14597a88038fb16811a6fede25c67b79c6d50fc2c8fdc \ + --hash=sha256:1617bea5ab31266e152871208502ee943cb349c224846928a1173c864261375e \ + --hash=sha256:170cdb8436188347af17bf9cccf3249ba581c933ed56d926497119d4cf730cec \ + --hash=sha256:1975eda520957c6e0eb52d12968dd3609ffb7eef05d4223d097893d6daf1d8a7 \ + --hash=sha256:1fe603877e1865b5fd047a5e40379509a4a60204aa7aa0f72b16f7a41c3f0712 \ + --hash=sha256:24d70810f6e2ea853ff79338001533716b373cc0f63e2a0be5bc96129edb5fb5 \ + --hash=sha256:256793988bff98040de23c57cf36e1f4c2f2dc3dcd17537cdac031d3b681db71 \ + --hash=sha256:25711f364c64cab2c910a0247e90b51421e45dbc8910ceeb4eac97a9e132fc6f \ + --hash=sha256:2682162855a708e3270eba4b92026b93f8257c3e65278b456c77631faf0f4f7a \ + --hash=sha256:2cf9d73499486ce39eebbff5f42452518cc1f88d8b7ea4a711ab32962b176ee2 \ + --hash=sha256:2e40520c37926166c24d0c2e0f3bc3a5f46646c34bdf7b4ea9747c297d6ee809 \ + --hash=sha256:2e980cf1ed1a2420a6424e2ed884629cdead291686f1048810a817de07b5eb18 \ + --hash=sha256:2f03484b54bf4ae80ab2e504a8d99d20d551bfe64a7ec91e218010b467d77093 \ + --hash=sha256:35f1609e3484a649bb80431310ddbec81114cd86648f1d9482bc72a3b86ded2e \ + --hash=sha256:399938edbd3d78339f797d685142dd8a623dfaded023cf451033c85955e4838a \ + --hash=sha256:399bbd7bcc1633c3e356ae274a1deb8781c7bf84d9c7962cc1ae0c6e87837292 \ + --hash=sha256:3ec50cf65235ff5c02c5b747748d9222e564ad48597122a361269dd3aa808798 \ + --hash=sha256:3edbf257c40d21a42615e9e332a6b10a8bacaaf58250aed8552a14a70efd0d65 \ + --hash=sha256:440c788f707c061d237c1e83edf6164ff19f5c0f823a3bf054e88804ebf971ec \ + --hash=sha256:44b3689b040df57f492e02cd4f0bacd1b42c5400e4b8048160c9d5e866de8abe \ + --hash=sha256:4887c29cadbdc50640179e3861c276325ff2986791e6044f73136e6e798ff806 \ + --hash=sha256:5460d99ed30f043595bbdc888f542bad2caeb6226b01c33cda3ae444e8f82d42 \ + --hash=sha256:550fdbfbf5bba6a2960b27376ca76d6aaa2bd4b1a06c4255edd8520c306fcfc0 \ + --hash=sha256:56f2a47beda8409061bc1c865bef2d4bd9ff9255219402c0817e68ab5ad89aed \ + --hash=sha256:572a24fc5958c61431da456a0ef1eeea6b4989d81eeb18b8e5f1f3077592200b \ + --hash=sha256:59cb0470612d21fa1efddfa0dd710756b50d9c7fb6c1236bbf8ef8529331dc70 \ + --hash=sha256:6038ccbd5968325a5d6fd393cf6e00b622a8de545f0994b89dd0f748dcf3e19e \ + --hash=sha256:6488e69d408b492e08bfb68f20c4a899a354b4386a446ecd490baff8d0862720 \ + --hash=sha256:687403cced6a29590e6be6964463835315905221d797bc5c934a98750fe1a9af \ + --hash=sha256:6b407c23f16ccc36614c136251d6b32bf30de7a57f8e782378f1107be008ddb0 \ + --hash=sha256:6b4e7bff1d76dd2b46443078519dc75df1b5e01562345f0bb740cea5266d8218 \ + --hash=sha256:6bdd9adfca615903578d2060ee8a6eb1c24eaf54919ff0ddc820118e5718931b \ + --hash=sha256:6eb9295c730e26b849ed1f4022735f36863eb46b14b6e10604c1c39b8b5efaea \ + --hash=sha256:703456146dc2bf430f7832fd1341adac5c893ec3c1430194fdcefba00012555c \ + --hash=sha256:754a0d09997095ad764ccef050dd5bf26cbf457aab9effcba5890dad081d879e \ + --hash=sha256:7af7785f5edd1f418da09a8cdb9ec84b0213e23d597413e06525340bcce1ea4f \ + --hash=sha256:7b29e97273bd6999e2bfe9fe3531b1f4f64effd28327bced048a33e49b99674a \ + --hash=sha256:7b4f57f7a0c65821c5441d98c47ff7c01d359b1e12328219709bdd97fdd37f90 \ + --hash=sha256:8837d5a52a2d7aa9f4c3220a8484013aed1d8ad75240d9a75ede63709ef89055 \ + --hash=sha256:8ccadf260bb46a61b9c7e89e2218f6efea9f3eeaaab4e3d1f58571890e54858e \ + --hash=sha256:8d8cf653e798ee4c4e654062b633db36984a1572f68c3aa25e364a0ddfbbb910 \ + --hash=sha256:93b2a1f325fefa1482516ced160c8c7b4b8d53226763fa6c93d151fa25164207 \ + --hash=sha256:9f0e0927efe87cd42ad600628e595a1a0aa1c64f6d0b55f7e6059079a428641a \ + --hash=sha256:a59a69deeb458c858b8fea6acf9e2acd5d755d76cd81a655256bc65c20dfff5b \ + --hash=sha256:a9f9b661f82693eb56beb0605156c7fca57f535704ab91837405913417d6990b \ + --hash=sha256:abfc57cab3c53c4546aee31859ef06753bfc136c9d208129bad23e2eca39155a \ + --hash=sha256:aca73d70c3f553552ba9133d4a09e767dcfeee352d8d8d3eb3f77e38a3beb3ed \ + --hash=sha256:adeaa886d607fb02563c1f625cf2ee58778a2567c0c109378da8f17ec3076ad7 \ + --hash=sha256:b278a9248a4e3260fee3db7613772ca9ab6763a129d6d6f29555e2f9b168216d \ + --hash=sha256:b7c1239b64b70be7759554ad1a86288220bbb04d68518b527783c4ad3fb4f80b \ + --hash=sha256:bf8c7735fbfc0754111f00edda35cf9e98a8d478de6c47b04eaa9cef4300eaa7 \ + --hash=sha256:c634a0a6db395fdaba0361aa78395597ee72c3aad651b9a307a3a7eaf5efd67e \ + --hash=sha256:cad9971881e4fec00d96af7eaf4b63aa7a595696fc221808b0d3ce7ca9743258 \ + --hash=sha256:cbdb3f337c88b43c3b49ca377731912c101178be91cb5071aac48faa898e6f8e \ + --hash=sha256:cd8551aa21df6c60baa2624fd086ae7486bdde00c44097b32e1d1b1966e365e0 \ + --hash=sha256:d09f677693328503c9e492e33e9601464297c01f9ebd966ea8fc5308f3069bfd \ + --hash=sha256:d376a35c6561e81d2590506804b428fc1075fcc6298fc5bb49b771534c0ba010 \ + --hash=sha256:d39079379a9a28e74f4d57dc6357fa310a1977b51ff12239d7271ec7e71d67f5 \ + --hash=sha256:d86f94743a11873317094326456b23f8a5788bad9161fd2f0e52088c33564620 \ + --hash=sha256:d91e60ac44bbe3a77a67af4a4c13114cbe9f6d540337ce22f2c9eaf7454ca71f \ + --hash=sha256:d9883b2d819ce83f87ba82a746c81d14ada78784db431e57cc9719179847376e \ + --hash=sha256:e094e445c37c57e9ec612847812c301840239d34ccc5d153a982fa9814478c60 \ + --hash=sha256:e19acfde38cb532a560b98f473adc741c941b7a9bc90f7294bc273d08becb58b \ + --hash=sha256:e32d43610dff472eab939f4d7fbdd240d1667794192690433672ae22d7af8445 \ + --hash=sha256:ed028fc3d41adda916320712838aec289956c89b4f0a361ceadf83a53b4c047a \ + --hash=sha256:ef59c938f72bdbc6ab52dc50f81d0637fde0f194b02d636987cea2ab30f8f55a \ + --hash=sha256:f3d4801db8354436fd3936531e7f0e4feb411f62433a6b6cb32bb416e20b529f \ + --hash=sha256:f57aca20e637750a2c18d979f7096e2c2033cc40cf7ed201494318de1182f135 \ + --hash=sha256:f9da128d0edf990cf0d2ca011b02cd6f639e79286774bd5b0351245cbb5a6e51 \ + --hash=sha256:fbd7351d43b80d9c64c3cfcb50008f786cc82cba0450e8599fdd64f264320bd3 \ + --hash=sha256:fcb72249ac4ea81a7baefcbff74df7029c3cb1cf01a711113fa052d563639c9c \ + --hash=sha256:ff21c554304e8226bf80c3a7754be27c6c3549a9fec563a03c06ee8f494da8fc + # via mypy license-expression==30.4.4 \ --hash=sha256:421788fdcadb41f049d2dc934ce666626265aeccefddd25e162a26f23bcbf8a4 \ --hash=sha256:73448f0aacd8d0808895bdc4b2c8e01a8d67646e4188f887375398c761f340fd @@ -755,45 +869,45 @@ mccabe==0.7.0 \ --hash=sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325 \ --hash=sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e # via pylint -mypy==1.18.2 \ - --hash=sha256:01199871b6110a2ce984bde85acd481232d17413868c9807e95c1b0739a58914 \ - --hash=sha256:030c52d0ea8144e721e49b1f68391e39553d7451f0c3f8a7565b59e19fcb608b \ - --hash=sha256:06a398102a5f203d7477b2923dda3634c36727fa5c237d8f859ef90c42a9924b \ - --hash=sha256:07b8b0f580ca6d289e69209ec9d3911b4a26e5abfde32228a288eb79df129fcc \ - --hash=sha256:0e2785a84b34a72ba55fb5daf079a1003a34c05b22238da94fcae2bbe46f3544 \ - --hash=sha256:1331eb7fd110d60c24999893320967594ff84c38ac6d19e0a76c5fd809a84c86 \ - --hash=sha256:1379451880512ffce14505493bd9fe469e0697543717298242574882cf8cdb8d \ - --hash=sha256:20c02215a080e3a2be3aa50506c67242df1c151eaba0dcbc1e4e557922a26075 \ - --hash=sha256:22a1748707dd62b58d2ae53562ffc4d7f8bcc727e8ac7cbc69c053ddc874d47e \ - --hash=sha256:22f27105f1525ec024b5c630c0b9f36d5c1cc4d447d61fe51ff4bd60633f47ac \ - --hash=sha256:25a9c8fb67b00599f839cf472713f54249a62efd53a54b565eb61956a7e3296b \ - --hash=sha256:33eca32dd124b29400c31d7cf784e795b050ace0e1f91b8dc035672725617e34 \ - --hash=sha256:3ca30b50a51e7ba93b00422e486cbb124f1c56a535e20eff7b2d6ab72b3b2e37 \ - --hash=sha256:448acd386266989ef11662ce3c8011fd2a7b632e0ec7d61a98edd8e27472225b \ - --hash=sha256:592ec214750bc00741af1f80cbf96b5013d81486b7bb24cb052382c19e40b428 \ - --hash=sha256:5d6c838e831a062f5f29d11c9057c6009f60cb294fea33a98422688181fe2893 \ - --hash=sha256:62f0e1e988ad41c2a110edde6c398383a889d95b36b3e60bcf155f5164c4fdce \ - --hash=sha256:664dc726e67fa54e14536f6e1224bcfce1d9e5ac02426d2326e2bb4e081d1ce8 \ - --hash=sha256:6ca1e64b24a700ab5ce10133f7ccd956a04715463d30498e64ea8715236f9c9c \ - --hash=sha256:749b5f83198f1ca64345603118a6f01a4e99ad4bf9d103ddc5a3200cc4614adf \ - --hash=sha256:776bb00de1778caf4db739c6e83919c1d85a448f71979b6a0edd774ea8399341 \ - --hash=sha256:7a780ca61fc239e4865968ebc5240bb3bf610ef59ac398de9a7421b54e4a207e \ - --hash=sha256:7ab28cc197f1dd77a67e1c6f35cd1f8e8b73ed2217e4fc005f9e6a504e46e7ba \ - --hash=sha256:7fb95f97199ea11769ebe3638c29b550b5221e997c63b14ef93d2e971606ebed \ - --hash=sha256:807d9315ab9d464125aa9fcf6d84fde6e1dc67da0b6f80e7405506b8ac72bc7f \ - --hash=sha256:8795a039bab805ff0c1dfdb8cd3344642c2b99b8e439d057aba30850b8d3423d \ - --hash=sha256:a2afc0fa0b0e91b4599ddfe0f91e2c26c2b5a5ab263737e998d6817874c5f7c8 \ - --hash=sha256:a3c47adf30d65e89b2dcd2fa32f3aeb5e94ca970d2c15fcb25e297871c8e4764 \ - --hash=sha256:a431a6f1ef14cf8c144c6b14793a23ec4eae3db28277c358136e79d7d062f62d \ - --hash=sha256:aa5e07ac1a60a253445797e42b8b2963c9675563a94f11291ab40718b016a7a0 \ - --hash=sha256:c1eab0cf6294dafe397c261a75f96dc2c31bffe3b944faa24db5def4e2b0f77c \ - --hash=sha256:c2b9c7e284ee20e7598d6f42e13ca40b4928e6957ed6813d1ab6348aa3f47133 \ - --hash=sha256:c3ad2afadd1e9fea5cf99a45a822346971ede8685cc581ed9cd4d42eaf940986 \ - --hash=sha256:d6985ed057513e344e43a26cc1cd815c7a94602fb6a3130a34798625bc2f07b6 \ - --hash=sha256:d8068d0afe682c7c4897c0f7ce84ea77f6de953262b12d07038f4d296d547074 \ - --hash=sha256:d924eef3795cc89fecf6bedc6ed32b33ac13e8321344f6ddbf8ee89f706c05cb \ - --hash=sha256:ed4482847168439651d3feee5833ccedbf6657e964572706a2adb1f7fa4dfe2e \ - --hash=sha256:f9e171c465ad3901dc652643ee4bffa8e9fef4d7d0eece23b428908c77a76a66 +mypy==1.19.0 \ + --hash=sha256:0c01c99d626380752e527d5ce8e69ffbba2046eb8a060db0329690849cf9b6f9 \ + --hash=sha256:0dde5cb375cb94deff0d4b548b993bec52859d1651e073d63a1386d392a95495 \ + --hash=sha256:0e3c3d1e1d62e678c339e7ade72746a9e0325de42cd2cccc51616c7b2ed1a018 \ + --hash=sha256:0ea4fd21bb48f0da49e6d3b37ef6bd7e8228b9fe41bbf4d80d9364d11adbd43c \ + --hash=sha256:0fb3115cb8fa7c5f887c8a8d81ccdcb94cff334684980d847e5a62e926910e1d \ + --hash=sha256:11f7254c15ab3f8ed68f8e8f5cbe88757848df793e31c36aaa4d4f9783fd08ab \ + --hash=sha256:120cffe120cca5c23c03c77f84abc0c14c5d2e03736f6c312480020082f1994b \ + --hash=sha256:16f76ff3f3fd8137aadf593cb4607d82634fca675e8211ad75c43d86033ee6c6 \ + --hash=sha256:1cf9c59398db1c68a134b0b5354a09a1e124523f00bacd68e553b8bd16ff3299 \ + --hash=sha256:318ba74f75899b0e78b847d8c50821e4c9637c79d9a59680fc1259f29338cb3e \ + --hash=sha256:3210d87b30e6af9c8faed61be2642fcbe60ef77cec64fa1ef810a630a4cf671c \ + --hash=sha256:34ec1ac66d31644f194b7c163d7f8b8434f1b49719d403a5d26c87fff7e913f7 \ + --hash=sha256:37af5166f9475872034b56c5efdcf65ee25394e9e1d172907b84577120714364 \ + --hash=sha256:3ad925b14a0bb99821ff6f734553294aa6a3440a8cb082fe1f5b84dfb662afb1 \ + --hash=sha256:510c014b722308c9bd377993bcbf9a07d7e0692e5fa8fc70e639c1eb19fc6bee \ + --hash=sha256:6016c52ab209919b46169651b362068f632efcd5eb8ef9d1735f6f86da7853b2 \ + --hash=sha256:6148ede033982a8c5ca1143de34c71836a09f105068aaa8b7d5edab2b053e6c8 \ + --hash=sha256:63ea6a00e4bd6822adbfc75b02ab3653a17c02c4347f5bb0cf1d5b9df3a05835 \ + --hash=sha256:7686ed65dbabd24d20066f3115018d2dce030d8fa9db01aa9f0a59b6813e9f9e \ + --hash=sha256:7a500ab5c444268a70565e374fc803972bfd1f09545b13418a5174e29883dab7 \ + --hash=sha256:8f44f2ae3c58421ee05fe609160343c25f70e3967f6e32792b5a78006a9d850f \ + --hash=sha256:a18d8abdda14035c5718acb748faec09571432811af129bf0d9e7b2d6699bf18 \ + --hash=sha256:a31e4c28e8ddb042c84c5e977e28a21195d086aaffaf08b016b78e19c9ef8106 \ + --hash=sha256:a9ac09e52bb0f7fb912f5d2a783345c72441a08ef56ce3e17c1752af36340a39 \ + --hash=sha256:b9d491295825182fba01b6ffe2c6fe4e5a49dbf4e2bb4d1217b6ced3b4797bc6 \ + --hash=sha256:c14a98bc63fd867530e8ec82f217dae29d0550c86e70debc9667fff1ec83284e \ + --hash=sha256:c3385246593ac2b97f155a0e9639be906e73534630f663747c71908dfbf26134 \ + --hash=sha256:cabbee74f29aa9cd3b444ec2f1e4fa5a9d0d746ce7567a6a609e224429781f53 \ + --hash=sha256:cb64b0ba5980466a0f3f9990d1c582bcab8db12e29815ecb57f1408d99b4bff7 \ + --hash=sha256:cf7d84f497f78b682edd407f14a7b6e1a2212b433eedb054e2081380b7395aa3 \ + --hash=sha256:e2c1101ab41d01303103ab6ef82cbbfedb81c1a060c868fa7cc013d573d37ab5 \ + --hash=sha256:f188dcf16483b3e59f9278c4ed939ec0254aa8a60e8fc100648d9ab5ee95a431 \ + --hash=sha256:f2e36bed3c6d9b5f35d28b63ca4b727cb0228e480826ffc8953d1892ddc8999d \ + --hash=sha256:f3e19e3b897562276bb331074d64c076dbdd3e79213f36eed4e592272dabd760 \ + --hash=sha256:f6b874ca77f733222641e5c46e4711648c4037ea13646fd0cdc814c2eaec2528 \ + --hash=sha256:f75e60aca3723a23511948539b0d7ed514dda194bc3755eae0bfc7a6b4887aa7 \ + --hash=sha256:fc51a5b864f73a3a182584b1ac75c404396a17eced54341629d8bdcb644a5bba \ + --hash=sha256:fd4a985b2e32f23bead72e2fb4bbe5d6aceee176be471243bd831d5b2644672d # via -r requirements-actions.in mypy-extensions==1.1.0 \ --hash=sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505 \ @@ -818,9 +932,9 @@ pathspec==0.12.1 \ # via # mypy # yamllint -platformdirs==4.4.0 \ - --hash=sha256:abd01743f24e5287cd7a5db3752faf1a2d65353f38ec26d98e25a6db65958c85 \ - --hash=sha256:ca753cf4d81dc309bc67b0ea38fd15dc97bc30ce419a7f58d13eb3bf14c4febf +platformdirs==4.5.1 \ + --hash=sha256:61d5cdcc6065745cdd94f0f878977f8de9437be93de97c1c12f853c9c0cdcbda \ + --hash=sha256:d03afa3963c806a9bed9d5125c8f4cb2fdaf74a55ab60e5d59b3fde758104d31 # via # pylint # tox @@ -841,16 +955,26 @@ polib==1.2.0 \ --hash=sha256:1c77ee1b81feb31df9bca258cbc58db1bbb32d10214b173882452c73af06d62d \ --hash=sha256:f3ef94aefed6e183e342a8a269ae1fc4742ba193186ad76f175938621dbfc26b # via sphinx-lint -psutil==7.1.0 \ - --hash=sha256:09ad740870c8d219ed8daae0ad3b726d3bf9a028a198e7f3080f6a1888b99bca \ - --hash=sha256:22e4454970b32472ce7deaa45d045b34d3648ce478e26a04c7e858a0a6e75ff3 \ - --hash=sha256:57f5e987c36d3146c0dd2528cd42151cf96cd359b9d67cfff836995cc5df9a3d \ - --hash=sha256:5d007560c8c372efdff9e4579c2846d71de737e4605f611437255e81efcca2c5 \ - --hash=sha256:655708b3c069387c8b77b072fc429a57d0e214221d01c0a772df7dfedcb3bcd2 \ - --hash=sha256:6937cb68133e7c97b6cc9649a570c9a18ba0efebed46d8c5dae4c07fa1b67a07 \ - --hash=sha256:76168cef4397494250e9f4e73eb3752b146de1dd950040b29186d0cce1d5ca13 \ - --hash=sha256:7d4a113425c037300de3ac8b331637293da9be9713855c4fc9d2d97436d7259d \ - --hash=sha256:8c70e113920d51e89f212dd7be06219a9b88014e63a4cec69b684c327bc474e3 +psutil==7.1.3 \ + --hash=sha256:0005da714eee687b4b8decd3d6cc7c6db36215c9e74e5ad2264b90c3df7d92dc \ + --hash=sha256:1068c303be3a72f8e18e412c5b2a8f6d31750fb152f9cb106b54090296c9d251 \ + --hash=sha256:18349c5c24b06ac5612c0428ec2a0331c26443d259e2a0144a9b24b4395b58fa \ + --hash=sha256:19644c85dcb987e35eeeaefdc3915d059dac7bd1167cdcdbf27e0ce2df0c08c0 \ + --hash=sha256:2bdbcd0e58ca14996a42adf3621a6244f1bb2e2e528886959c72cf1e326677ab \ + --hash=sha256:31d77fcedb7529f27bb3a0472bea9334349f9a04160e8e6e5020f22c59893264 \ + --hash=sha256:3792983e23b69843aea49c8f5b8f115572c5ab64c153bada5270086a2123c7e7 \ + --hash=sha256:3bb428f9f05c1225a558f53e30ccbad9930b11c3fc206836242de1091d3e7dd3 \ + --hash=sha256:56d974e02ca2c8eb4812c3f76c30e28836fffc311d55d979f1465c1feeb2b68b \ + --hash=sha256:6c86281738d77335af7aec228328e944b30930899ea760ecf33a4dba66be5e74 \ + --hash=sha256:8f33a3702e167783a9213db10ad29650ebf383946e91bc77f28a5eb083496bc9 \ + --hash=sha256:95ef04cf2e5ba0ab9eaafc4a11eaae91b44f4ef5541acd2ee91d9108d00d59a7 \ + --hash=sha256:ad81425efc5e75da3f39b3e636293360ad8d0b49bed7df824c79764fb4ba9b8b \ + --hash=sha256:b403da1df4d6d43973dc004d19cee3b848e998ae3154cc8097d139b77156c353 \ + --hash=sha256:bc31fa00f1fbc3c3802141eede66f3a2d51d89716a194bf2cd6fc68310a19880 \ + --hash=sha256:bd0d69cee829226a761e92f28140bec9a5ee9d5b4fb4b0cc589068dbfff559b1 \ + --hash=sha256:c525ffa774fe4496282fb0b1187725793de3e7c6b29e41562733cae9ada151ee \ + --hash=sha256:f39c2c19fe824b47484b96f9692932248a54c43799a84282cfe58d05a6449efd \ + --hash=sha256:fac9cd332c67f4422504297889da5ab7e05fd11e3c4392140f7370f4208ded1f # via -r requirements-actions.in pyasn1==0.6.1 \ --hash=sha256:0d632f46f2ba09143da3a8afe9e33fb6f92fa2320ab7e886e2d0f7672af84629 \ @@ -884,54 +1008,54 @@ pykwalify==1.8.0 \ # via # -r requirements-actions.in # west -pylint==3.3.8 \ - --hash=sha256:26698de19941363037e2937d3db9ed94fb3303fdadf7d98847875345a8bb6b05 \ - --hash=sha256:7ef94aa692a600e82fabdd17102b73fc226758218c97473c7ad67bd4cb905d83 +pylint==4.0.4 \ + --hash=sha256:63e06a37d5922555ee2c20963eb42559918c20bd2b21244e4ef426e7c43b92e0 \ + --hash=sha256:d9b71674e19b1c36d79265b5887bf8e55278cbe236c9e95d22dc82cf044fdbd2 # via -r requirements-actions.in -pynacl==1.6.0 \ - --hash=sha256:04f20784083014e265ad58c1b2dd562c3e35864b5394a14ab54f5d150ee9e53e \ - --hash=sha256:10d755cf2a455d8c0f8c767a43d68f24d163b8fe93ccfaabfa7bafd26be58d73 \ - --hash=sha256:140373378e34a1f6977e573033d1dd1de88d2a5d90ec6958c9485b2fd9f3eb90 \ - --hash=sha256:16c60daceee88d04f8d41d0a4004a7ed8d9a5126b997efd2933e08e93a3bd850 \ - --hash=sha256:16dd347cdc8ae0b0f6187a2608c0af1c8b7ecbbe6b4a06bff8253c192f696990 \ - --hash=sha256:25720bad35dfac34a2bcdd61d9e08d6bfc6041bebc7751d9c9f2446cf1e77d64 \ - --hash=sha256:2d6cd56ce4998cb66a6c112fda7b1fdce5266c9f05044fa72972613bef376d15 \ - --hash=sha256:347dcddce0b4d83ed3f32fd00379c83c425abee5a9d2cd0a2c84871334eaff64 \ - --hash=sha256:4853c154dc16ea12f8f3ee4b7e763331876316cc3a9f06aeedf39bcdca8f9995 \ - --hash=sha256:49c336dd80ea54780bcff6a03ee1a476be1612423010472e60af83452aa0f442 \ - --hash=sha256:4a25cfede801f01e54179b8ff9514bd7b5944da560b7040939732d1804d25419 \ - --hash=sha256:51fed9fe1bec9e7ff9af31cd0abba179d0e984a2960c77e8e5292c7e9b7f7b5d \ - --hash=sha256:536703b8f90e911294831a7fbcd0c062b837f3ccaa923d92a6254e11178aaf42 \ - --hash=sha256:5789f016e08e5606803161ba24de01b5a345d24590a80323379fc4408832d290 \ - --hash=sha256:6b08eab48c9669d515a344fb0ef27e2cbde847721e34bba94a343baa0f33f1f4 \ - --hash=sha256:6b393bc5e5a0eb86bb85b533deb2d2c815666665f840a09e0aa3362bb6088736 \ - --hash=sha256:84709cea8f888e618c21ed9a0efdb1a59cc63141c403db8bf56c469b71ad56f2 \ - --hash=sha256:8bfaa0a28a1ab718bad6239979a5a57a8d1506d0caf2fba17e524dbb409441cf \ - --hash=sha256:bbcc4452a1eb10cd5217318c822fde4be279c9de8567f78bad24c773c21254f8 \ - --hash=sha256:cb36deafe6e2bce3b286e5d1f3e1c246e0ccdb8808ddb4550bb2792f2df298f2 \ - --hash=sha256:cf831615cc16ba324240de79d925eacae8265b7691412ac6b24221db157f6bd1 \ - --hash=sha256:dcdeb41c22ff3c66eef5e63049abf7639e0db4edee57ba70531fc1b6b133185d \ - --hash=sha256:dea103a1afcbc333bc0e992e64233d360d393d1e63d0bc88554f572365664348 \ - --hash=sha256:ef214b90556bb46a485b7da8258e59204c244b1b5b576fb71848819b468c44a7 \ - --hash=sha256:f3482abf0f9815e7246d461fab597aa179b7524628a4bc36f86a7dc418d2608d \ - --hash=sha256:f46386c24a65383a9081d68e9c2de909b1834ec74ff3013271f1bca9c2d233eb \ - --hash=sha256:f4b3824920e206b4f52abd7de621ea7a44fd3cb5c8daceb7c3612345dfc54f2e +pynacl==1.6.1 \ + --hash=sha256:262a8de6bba4aee8a66f5edf62c214b06647461c9b6b641f8cd0cb1e3b3196fe \ + --hash=sha256:2b12f1b97346f177affcdfdc78875ff42637cb40dcf79484a97dae3448083a78 \ + --hash=sha256:319de653ef84c4f04e045eb250e6101d23132372b0a61a7acf91bac0fda8e58c \ + --hash=sha256:3206fa98737fdc66d59b8782cecc3d37d30aeec4593d1c8c145825a345bba0f0 \ + --hash=sha256:3384a454adf5d716a9fadcb5eb2e3e72cd49302d1374a60edc531c9957a9b014 \ + --hash=sha256:3cd787ec1f5c155dc8ecf39b1333cfef41415dc96d392f1ce288b4fe970df489 \ + --hash=sha256:4ce50d19f1566c391fedc8dc2f2f5be265ae214112ebe55315e41d1f36a7f0a9 \ + --hash=sha256:53543b4f3d8acb344f75fd4d49f75e6572fce139f4bfb4815a9282296ff9f4c0 \ + --hash=sha256:543f869140f67d42b9b8d47f922552d7a967e6c116aad028c9bfc5f3f3b3a7b7 \ + --hash=sha256:5953e8b8cfadb10889a6e7bd0f53041a745d1b3d30111386a1bb37af171e6daf \ + --hash=sha256:5a3becafc1ee2e5ea7f9abc642f56b82dcf5be69b961e782a96ea52b55d8a9fc \ + --hash=sha256:5f5b35c1a266f8a9ad22525049280a600b19edd1f785bccd01ae838437dcf935 \ + --hash=sha256:6b35d93ab2df03ecb3aa506be0d3c73609a51449ae0855c2e89c7ed44abde40b \ + --hash=sha256:7713f8977b5d25f54a811ec9efa2738ac592e846dd6e8a4d3f7578346a841078 \ + --hash=sha256:7d7c09749450c385301a3c20dca967a525152ae4608c0a096fe8464bfc3df93d \ + --hash=sha256:8d361dac0309f2b6ad33b349a56cd163c98430d409fa503b10b70b3ad66eaa1d \ + --hash=sha256:9fd1a4eb03caf8a2fe27b515a998d26923adb9ddb68db78e35ca2875a3830dde \ + --hash=sha256:a2bb472458c7ca959aeeff8401b8efef329b0fc44a89d3775cffe8fad3398ad8 \ + --hash=sha256:a569a4069a7855f963940040f35e87d8bc084cb2d6347428d5ad20550a0a1a21 \ + --hash=sha256:a6f9fd6d6639b1e81115c7f8ff16b8dedba1e8098d2756275d63d208b0e32021 \ + --hash=sha256:c2228054f04bf32d558fb89bb99f163a8197d5a9bf4efa13069a7fa8d4b93fc3 \ + --hash=sha256:d8615ee34d01c8e0ab3f302dcdd7b32e2bcf698ba5f4809e7cc407c8cdea7717 \ + --hash=sha256:d984c91fe3494793b2a1fb1e91429539c6c28e9ec8209d26d25041ec599ccf63 \ + --hash=sha256:dece79aecbb8f4640a1adbb81e4aa3bfb0e98e99834884a80eb3f33c7c30e708 \ + --hash=sha256:e49a3f3d0da9f79c1bec2aa013261ab9fa651c7da045d376bd306cf7c1792993 \ + --hash=sha256:e735c3a1bdfde3834503baf1a6d74d4a143920281cb724ba29fb84c9f49b9c48 \ + --hash=sha256:fc734c1696ffd49b40f7c1779c89ba908157c57345cf626be2e0719488a076d3 # via pygithub pyparsing==3.2.5 \ --hash=sha256:2df8d5b7b2802ef88e8d016a2eb9c7aeaa923529cd251ed0fe4608275d4105b6 \ --hash=sha256:e38a4f02064cf41fe6593d328d0512495ad1f3d8a91c4f73fc401b3079a59a5e # via rdflib -pyproject-api==1.9.1 \ - --hash=sha256:43c9918f49daab37e302038fc1aed54a8c7a91a9fa935d00b9a485f37e0f5335 \ - --hash=sha256:7d6238d92f8962773dd75b5f0c4a6a27cce092a14b623b811dba656f3b628948 +pyproject-api==1.10.0 \ + --hash=sha256:40c6f2d82eebdc4afee61c773ed208c04c19db4c4a60d97f8d7be3ebc0bbb330 \ + --hash=sha256:8757c41a79c0f4ab71b99abed52b97ecf66bd20b04fa59da43b5840bac105a09 # via tox pyserial==3.5 \ --hash=sha256:3c77e014170dfffbd816e6ffc205e9842efb10be9f58ec16d3e8675b4925cddb \ --hash=sha256:c4451db6ba391ca6ca299fb3ec7bae67a5c55dde170964c7a14ceefec02f2cf0 # via -r requirements-actions.in -pytest==8.4.2 \ - --hash=sha256:86c0d0b93306b961d58d62a4db4879f27fe25513d4b969df351abdddb3c30e01 \ - --hash=sha256:872f880de3fc3a5bdc88a11b39c9710c3497a547cfa9320bc3c5e62fbf272e79 +pytest==9.0.2 \ + --hash=sha256:711ffd45bf766d5264d487b917733b453d917afd2b0ad65223959f59089f875b \ + --hash=sha256:75186651a92bd89611d1d9fc20f0b4345fd827c41ccd5c299a868a05d70edf11 # via -r requirements-actions.in python-can==4.6.1 \ --hash=sha256:17f95255868a95108dcfcb90565a684dad32d5a3ebb35afd14f739e18c84ff6c \ @@ -949,14 +1073,16 @@ python-debian==1.0.1 \ --hash=sha256:3ada9b83a3d671b58081782c0969cffa0102f6ce433fbbc7cf21275b8b5cc771 \ --hash=sha256:8f137c230c1d9279c2ac892b35915068b2aca090c9fd3da5671ff87af32af12c # via reuse -python-dotenv==1.1.1 \ - --hash=sha256:31f23644fe2602f88ff55e1f5c79ba497e01224ee7737937930c448e4d0e24dc \ - --hash=sha256:a8a6399716257f45be6a007360200409fce5cda2661e3dec71d23dc15f6189ab +python-dotenv==1.2.1 \ + --hash=sha256:42667e897e16ab0d66954af0e60a9caa94f0fd4ecf3aaf6d2d260eec1aa36ad6 \ + --hash=sha256:b81ee9561e9ca4004139c6cbba3a238c32b03e4894671e181b671e8cb8425d61 # via -r requirements-actions.in -python-magic==0.4.27 ; sys_platform != 'win32' \ +python-magic==0.4.27 \ --hash=sha256:c1ba14b08e4a5f5c31a302b7721239695b2f0f058d125bd5ce1ee36b9d9d3c3b \ --hash=sha256:c212960ad306f700aa0d01e5d7a325d20548ff97eb9920dcd29513174f0294d3 - # via -r requirements-actions.in + # via + # -r requirements-actions.in + # reuse python-magic-bin==0.4.14 ; sys_platform == 'win32' \ --hash=sha256:34a788c03adde7608028203e2dbb208f1f62225ad91518787ae26d603ae68892 \ --hash=sha256:7b1743b3dbf16601d6eedf4e7c2c9a637901b0faaf24ad4df4d4527e7d8f66a4 \ @@ -1042,297 +1168,257 @@ pyyaml==6.0.3 \ # spdx-tools # west # yamllint -rdflib==7.2.1 \ - --hash=sha256:1a175bc1386a167a42fbfaba003bfa05c164a2a3ca3cb9c0c97f9c9638ca6ac2 \ - --hash=sha256:cf9b7fa25234e8925da8b1fb09700f8349b5f0f100e785fb4260e737308292ac +rdflib==7.5.0 \ + --hash=sha256:663083443908b1830e567350d72e74d9948b310f827966358d76eebdc92bf592 \ + --hash=sha256:b011dfc40d0fc8a44252e906dcd8fc806a7859bc231be190c37e9568a31ac572 # via spdx-tools -referencing==0.36.2 \ - --hash=sha256:df2e89862cd09deabbdba16944cc3f10feb6b3e6f18e902f7cc25609a34775aa \ - --hash=sha256:e8699adbbf8b5c7de96d8ffa0eb5c158b3beafce084968e2ea8bb08c6794dcd0 +referencing==0.37.0 \ + --hash=sha256:381329a9f99628c9069361716891d34ad94af76e461dcb0335825aecc7692231 \ + --hash=sha256:44aefc3142c5b842538163acb373e24cce6632bd54bdb01b21ad5863489f50d8 # via # jsonschema # jsonschema-specifications -regex==2025.9.18 \ - --hash=sha256:032720248cbeeae6444c269b78cb15664458b7bb9ed02401d3da59fe4d68c3a5 \ - --hash=sha256:039a9d7195fd88c943d7c777d4941e8ef736731947becce773c31a1009cb3c35 \ - --hash=sha256:039f11b618ce8d71a1c364fdee37da1012f5a3e79b1b2819a9f389cd82fd6282 \ - --hash=sha256:05440bc172bc4b4b37fb9667e796597419404dbba62e171e1f826d7d2a9ebcef \ - --hash=sha256:06104cd203cdef3ade989a1c45b6215bf42f8b9dd705ecc220c173233f7cba41 \ - --hash=sha256:065b6956749379d41db2625f880b637d4acc14c0a4de0d25d609a62850e96d36 \ - --hash=sha256:0716e4d6e58853d83f6563f3cf25c281ff46cf7107e5f11879e32cb0b59797d9 \ - --hash=sha256:0ac936537ad87cef9e0e66c5144484206c1354224ee811ab1519a32373e411f3 \ - --hash=sha256:0c3506682ea19beefe627a38872d8da65cc01ffa25ed3f2e422dffa1474f0788 \ - --hash=sha256:0cc3521060162d02bd36927e20690129200e5ac9d2c6d32b70368870b122db25 \ - --hash=sha256:0dc6893b1f502d73037cf807a321cdc9be29ef3d6219f7970f842475873712ac \ - --hash=sha256:0f0d676522d68c207828dcd01fb6f214f63f238c283d9f01d85fc664c7c85b56 \ - --hash=sha256:0ffd9e230b826b15b369391bec167baed57c7ce39efc35835448618860995946 \ - --hash=sha256:1137cabc0f38807de79e28d3f6e3e3f2cc8cfb26bead754d02e6d1de5f679203 \ - --hash=sha256:12296202480c201c98a84aecc4d210592b2f55e200a1d193235c4db92b9f6788 \ - --hash=sha256:13202e4c4ac0ef9a317fff817674b293c8f7e8c68d3190377d8d8b749f566e12 \ - --hash=sha256:168be0d2f9b9d13076940b1ed774f98595b4e3c7fc54584bba81b3cc4181742e \ - --hash=sha256:16bd2944e77522275e5ee36f867e19995bcaa533dcb516753a26726ac7285442 \ - --hash=sha256:16eaf74b3c4180ede88f620f299e474913ab6924d5c4b89b3833bc2345d83b3d \ - --hash=sha256:1a351aff9e07a2dabb5022ead6380cff17a4f10e4feb15f9100ee56c4d6d06af \ - --hash=sha256:1b9d9a2d6cda6621551ca8cf7a06f103adf72831153f3c0d982386110870c4d3 \ - --hash=sha256:1e85f73ef7095f0380208269055ae20524bfde3f27c5384126ddccf20382a638 \ - --hash=sha256:1ef86a9ebc53f379d921fb9a7e42b92059ad3ee800fcd9e0fe6181090e9f6c23 \ - --hash=sha256:220381f1464a581f2ea988f2220cf2a67927adcef107d47d6897ba5a2f6d51a4 \ - --hash=sha256:274687e62ea3cf54846a9b25fc48a04459de50af30a7bd0b61a9e38015983494 \ - --hash=sha256:29cd86aa7cb13a37d0f0d7c21d8d949fe402ffa0ea697e635afedd97ab4b69f1 \ - --hash=sha256:2a40f929cd907c7e8ac7566ac76225a77701a6221bca937bdb70d56cb61f57b2 \ - --hash=sha256:2e1eddc06eeaffd249c0adb6fafc19e2118e6308c60df9db27919e96b5656096 \ - --hash=sha256:300e25dbbf8299d87205e821a201057f2ef9aa3deb29caa01cd2cac669e508d5 \ - --hash=sha256:34d674cbba70c9398074c8a1fcc1a79739d65d1105de2a3c695e2b05ea728251 \ - --hash=sha256:3810a65675845c3bdfa58c3c7d88624356dd6ee2fc186628295e0969005f928d \ - --hash=sha256:385c9b769655cb65ea40b6eea6ff763cbb6d69b3ffef0b0db8208e1833d4e746 \ - --hash=sha256:3acc471d1dd7e5ff82e6cacb3b286750decd949ecd4ae258696d04f019817ef8 \ - --hash=sha256:3b524d010973f2e1929aeb635418d468d869a5f77b52084d9f74c272189c251d \ - --hash=sha256:3d86b5247bf25fa3715e385aa9ff272c307e0636ce0c9595f64568b41f0a9c77 \ - --hash=sha256:3dbcfcaa18e9480669030d07371713c10b4f1a41f791ffa5cb1a99f24e777f40 \ - --hash=sha256:40532bff8a1a0621e7903ae57fce88feb2e8a9a9116d341701302c9302aef06e \ - --hash=sha256:431bd2a8726b000eb6f12429c9b438a24062a535d06783a93d2bcbad3698f8a8 \ - --hash=sha256:436e1b31d7efd4dcd52091d076482031c611dde58bf9c46ca6d0a26e33053a7e \ - --hash=sha256:47acd811589301298c49db2c56bde4f9308d6396da92daf99cba781fa74aa450 \ - --hash=sha256:48317233294648bf7cd068857f248e3a57222259a5304d32c7552e2284a1b2ad \ - --hash=sha256:4a12a06c268a629cb67cc1d009b7bb0be43e289d00d5111f86a2efd3b1949444 \ - --hash=sha256:4b8cdbddf2db1c5e80338ba2daa3cfa3dec73a46fff2a7dda087c8efbf12d62f \ - --hash=sha256:4baeb1b16735ac969a7eeecc216f1f8b7caf60431f38a2671ae601f716a32d25 \ - --hash=sha256:4dc98ba7dd66bd1261927a9f49bd5ee2bcb3660f7962f1ec02617280fc00f5eb \ - --hash=sha256:4f130c3a7845ba42de42f380fff3c8aebe89a810747d91bcf56d40a069f15352 \ - --hash=sha256:50e8290707f2fb8e314ab3831e594da71e062f1d623b05266f8cfe4db4949afd \ - --hash=sha256:51076980cd08cd13c88eb7365427ae27f0d94e7cebe9ceb2bb9ffdae8fc4d82a \ - --hash=sha256:5514b8e4031fdfaa3d27e92c75719cbe7f379e28cacd939807289bce76d0e35a \ - --hash=sha256:57929d0f92bebb2d1a83af372cd0ffba2263f13f376e19b1e4fa32aec4efddc3 \ - --hash=sha256:57a161bd3acaa4b513220b49949b07e252165e6b6dc910ee7617a37ff4f5b425 \ - --hash=sha256:5adf266f730431e3be9021d3e5b8d5ee65e563fec2883ea8093944d21863b379 \ - --hash=sha256:5db95ff632dbabc8c38c4e82bf545ab78d902e81160e6e455598014f0abe66b9 \ - --hash=sha256:5f96fa342b6f54dcba928dd452e8d8cb9f0d63e711d1721cd765bb9f73bb048d \ - --hash=sha256:6479d5555122433728760e5f29edb4c2b79655a8deb681a141beb5c8a025baea \ - --hash=sha256:65d3c38c39efce73e0d9dc019697b39903ba25b1ad45ebbd730d2cf32741f40d \ - --hash=sha256:6a4b44df31d34fa51aa5c995d3aa3c999cec4d69b9bd414a8be51984d859f06d \ - --hash=sha256:6a52219a93dd3d92c675383efff6ae18c982e2d7651c792b1e6d121055808743 \ - --hash=sha256:6b498437c026a3d5d0be0020023ff76d70ae4d77118e92f6f26c9d0423452446 \ - --hash=sha256:726177ade8e481db669e76bf99de0b278783be8acd11cef71165327abd1f170a \ - --hash=sha256:7b47fcf9f5316c0bdaf449e879407e1b9937a23c3b369135ca94ebc8d74b1742 \ - --hash=sha256:7c9f285a071ee55cd9583ba24dde006e53e17780bb309baa8e4289cd472bcc47 \ - --hash=sha256:7cc9e5525cada99699ca9223cce2d52e88c52a3d2a0e842bd53de5497c604164 \ - --hash=sha256:7e2b414deae99166e22c005e154a5513ac31493db178d8aec92b3269c9cce8c9 \ - --hash=sha256:828446870bd7dee4e0cbeed767f07961aa07f0ea3129f38b3ccecebc9742e0b8 \ - --hash=sha256:8620d247fb8c0683ade51217b459cb4a1081c0405a3072235ba43a40d355c09a \ - --hash=sha256:874ff523b0fecffb090f80ae53dc93538f8db954c8bb5505f05b7787ab3402a0 \ - --hash=sha256:87f681bfca84ebd265278b5daa1dcb57f4db315da3b5d044add7c30c10442e61 \ - --hash=sha256:8900b3208e022570ae34328712bef6696de0804c122933414014bae791437ab2 \ - --hash=sha256:895197241fccf18c0cea7550c80e75f185b8bd55b6924fcae269a1a92c614a07 \ - --hash=sha256:8e5f41ad24a1e0b5dfcf4c4e5d9f5bd54c895feb5708dd0c1d0d35693b24d478 \ - --hash=sha256:8f9698b6f6895d6db810e0bda5364f9ceb9e5b11328700a90cae573574f61eea \ - --hash=sha256:9098e29b3ea4ffffeade423f6779665e2a4f8db64e699c0ed737ef0db6ba7b12 \ - --hash=sha256:90b6b7a2d0f45b7ecaaee1aec6b362184d6596ba2092dd583ffba1b78dd0231c \ - --hash=sha256:92a8e375ccdc1256401c90e9dc02b8642894443d549ff5e25e36d7cf8a80c783 \ - --hash=sha256:9feb29817df349c976da9a0debf775c5c33fc1c8ad7b9f025825da99374770b7 \ - --hash=sha256:a021217b01be2d51632ce056d7a837d3fa37c543ede36e39d14063176a26ae29 \ - --hash=sha256:a276937d9d75085b2c91fb48244349c6954f05ee97bba0963ce24a9d915b8b68 \ - --hash=sha256:a295916890f4df0902e4286bc7223ee7f9e925daa6dcdec4192364255b70561a \ - --hash=sha256:a61e85bfc63d232ac14b015af1261f826260c8deb19401c0597dbb87a864361e \ - --hash=sha256:a78722c86a3e7e6aadf9579e3b0ad78d955f2d1f1a8ca4f67d7ca258e8719d4b \ - --hash=sha256:ae77e447ebc144d5a26d50055c6ddba1d6ad4a865a560ec7200b8b06bc529368 \ - --hash=sha256:ae9b3840c5bd456780e3ddf2f737ab55a79b790f6409182012718a35c6d43282 \ - --hash=sha256:b176326bcd544b5e9b17d6943f807697c0cb7351f6cfb45bf5637c95ff7e6306 \ - --hash=sha256:b7531a8ef61de2c647cdf68b3229b071e46ec326b3138b2180acb4275f470b01 \ - --hash=sha256:b80fa342ed1ea095168a3f116637bd1030d39c9ff38dc04e54ef7c521e01fc95 \ - --hash=sha256:bbb9246568f72dce29bcd433517c2be22c7791784b223a810225af3b50d1aafb \ - --hash=sha256:bc4b8e9d16e20ddfe16430c23468a8707ccad3365b06d4536142e71823f3ca29 \ - --hash=sha256:c190af81e5576b9c5fdc708f781a52ff20f8b96386c6e2e0557a78402b029f4a \ - --hash=sha256:c204e93bf32cd7a77151d44b05eb36f469d0898e3fba141c026a26b79d9914a0 \ - --hash=sha256:c28821d5637866479ec4cc23b8c990f5bc6dd24e5e4384ba4a11d38a526e1414 \ - --hash=sha256:c5ba23274c61c6fef447ba6a39333297d0c247f53059dba0bca415cac511edc4 \ - --hash=sha256:c6db75b51acf277997f3adcd0ad89045d856190d13359f15ab5dda21581d9129 \ - --hash=sha256:c81b892af4a38286101502eae7aec69f7cd749a893d9987a92776954f3943408 \ - --hash=sha256:c90471671c2cdf914e58b6af62420ea9ecd06d1554d7474d50133ff26ae88feb \ - --hash=sha256:d13ab0490128f2bb45d596f754148cd750411afc97e813e4b3a61cf278a23bb6 \ - --hash=sha256:d3bc882119764ba3a119fbf2bd4f1b47bc56c1da5d42df4ed54ae1e8e66fdf8f \ - --hash=sha256:d488c236ac497c46a5ac2005a952c1a0e22a07be9f10c3e735bc7d1209a34773 \ - --hash=sha256:d4a691494439287c08ddb9b5793da605ee80299dd31e95fa3f323fac3c33d9d4 \ - --hash=sha256:d59ecf3bb549e491c8104fea7313f3563c7b048e01287db0a90485734a70a730 \ - --hash=sha256:dbef80defe9fb21310948a2595420b36c6d641d9bea4c991175829b2cc4bc06a \ - --hash=sha256:dec57f96d4def58c422d212d414efe28218d58537b5445cf0c33afb1b4768571 \ - --hash=sha256:dfbde38f38004703c35666a1e1c088b778e35d55348da2b7b278914491698d6a \ - --hash=sha256:e1dd06f981eb226edf87c55d523131ade7285137fbde837c34dc9d1bf309f459 \ - --hash=sha256:e3ef8cf53dc8df49d7e28a356cf824e3623764e9833348b655cfed4524ab8a90 \ - --hash=sha256:e4121f1ce2b2b5eec4b397cc1b277686e577e658d8f5870b7eb2d726bd2300ab \ - --hash=sha256:ec46332c41add73f2b57e2f5b642f991f6b15e50e9f86285e08ffe3a512ac39f \ - --hash=sha256:ef8d10cc0989565bcbe45fb4439f044594d5c2b8919d3d229ea2c4238f1d55b0 \ - --hash=sha256:f04d2f20da4053d96c08f7fde6e1419b7ec9dbcee89c96e3d731fca77f411b95 \ - --hash=sha256:f2f422214a03fab16bfa495cfec72bee4aaa5731843b771860a471282f1bf74f \ - --hash=sha256:f4d97071c0ba40f0cf2a93ed76e660654c399a0a04ab7d85472239460f3da84b \ - --hash=sha256:f5cca697da89b9f8ea44115ce3130f6c54c22f541943ac8e9900461edc2b8bd4 \ - --hash=sha256:fb137ec7c5c54f34a25ff9b31f6b7b0c2757be80176435bf367111e3f71d72df \ - --hash=sha256:fb967eb441b0f15ae610b7069bdb760b929f267efbf522e814bbbfffdf125ce2 \ - --hash=sha256:fe5d50572bc885a0a799410a717c42b1a6b50e2f45872e2b40f4f288f9bce8a2 +regex==2025.11.3 \ + --hash=sha256:04d2765516395cf7dda331a244a3282c0f5ae96075f728629287dfa6f76ba70a \ + --hash=sha256:087511f5c8b7dfbe3a03f5d5ad0c2a33861b1fc387f21f6f60825a44865a385a \ + --hash=sha256:08b884f4226602ad40c5d55f52bf91a9df30f513864e0054bad40c0e9cf1afb7 \ + --hash=sha256:0d31e08426ff4b5b650f68839f5af51a92a5b51abd8554a60c2fbc7c71f25d0b \ + --hash=sha256:0f9397d561a4c16829d4e6ff75202c1c08b68a3bdbfe29dbfcdb31c9830907c6 \ + --hash=sha256:10483eefbfb0adb18ee9474498c9a32fcf4e594fbca0543bb94c48bac6183e2e \ + --hash=sha256:149eb0bba95231fb4f6d37c8f760ec9fa6fabf65bab555e128dde5f2475193ec \ + --hash=sha256:1e00ec2970aab10dc5db34af535f21fcf32b4a31d99e34963419636e2f85ae39 \ + --hash=sha256:1eb1ebf6822b756c723e09f5186473d93236c06c579d2cc0671a722d2ab14281 \ + --hash=sha256:1fedc720f9bb2494ce31a58a1631f9c82df6a09b49c19517ea5cc280b4541e01 \ + --hash=sha256:1ff0d190c7f68ae7769cd0313fe45820ba07ffebfddfaa89cc1eb70827ba0ddc \ + --hash=sha256:2292cd5a90dab247f9abe892ac584cb24f0f54680c73fcb4a7493c66c2bf2467 \ + --hash=sha256:22b29dda7e1f7062a52359fca6e58e548e28c6686f205e780b02ad8ef710de36 \ + --hash=sha256:22c12d837298651e5550ac1d964e4ff57c3f56965fc1812c90c9fb2028eaf267 \ + --hash=sha256:22dd622a402aad4558277305350699b2be14bc59f64d64ae1d928ce7d072dced \ + --hash=sha256:22e7d1cdfa88ef33a2ae6aa0d707f9255eb286ffbd90045f1088246833223aee \ + --hash=sha256:28ba4d69171fc6e9896337d4fc63a43660002b7da53fc15ac992abcf3410917c \ + --hash=sha256:2ab815eb8a96379a27c3b6157fcb127c8f59c36f043c1678110cea492868f1d5 \ + --hash=sha256:2b441a4ae2c8049106e8b39973bfbddfb25a179dda2bdb99b0eeb60c40a6a3af \ + --hash=sha256:2fa2eed3f76677777345d2f81ee89f5de2f5745910e805f7af7386a920fa7313 \ + --hash=sha256:32f74f35ff0f25a5021373ac61442edcb150731fbaa28286bbc8bb1582c89d02 \ + --hash=sha256:3809988f0a8b8c9dcc0f92478d6501fac7200b9ec56aecf0ec21f4a2ec4b6009 \ + --hash=sha256:3839967cf4dc4b985e1570fd8d91078f0c519f30491c60f9ac42a8db039be204 \ + --hash=sha256:38af559ad934a7b35147716655d4a2f79fcef2d695ddfe06a06ba40ae631fa7e \ + --hash=sha256:3a91e4a29938bc1a082cc28fdea44be420bf2bebe2665343029723892eb073e1 \ + --hash=sha256:3b30bc921d50365775c09a7ed446359e5c0179e9e2512beec4a60cbcef6ddd50 \ + --hash=sha256:3b3a5f320136873cc5561098dfab677eea139521cb9a9e8db98b7e64aef44cbc \ + --hash=sha256:3bf28b1873a8af8bbb58c26cc56ea6e534d80053b41fb511a35795b6de507e6a \ + --hash=sha256:3e0b11b2b2433d1c39c7c7a30e3f3d0aeeea44c2a8d0bae28f6b95f639927a69 \ + --hash=sha256:3e816cc9aac1cd3cc9a4ec4d860f06d40f994b5c7b4d03b93345f44e08cc68bf \ + --hash=sha256:3f8bf11a4827cc7ce5a53d4ef6cddd5ad25595d3c1435ef08f76825851343154 \ + --hash=sha256:435bbad13e57eb5606a68443af62bed3556de2f46deb9f7d4237bc2f1c9fb3a0 \ + --hash=sha256:43b4fb020e779ca81c1b5255015fe2b82816c76ec982354534ad9ec09ad7c9e3 \ + --hash=sha256:442d86cf1cfe4faabf97db7d901ef58347efd004934da045c745e7b5bd57ac49 \ + --hash=sha256:44f264d4bf02f3176467d90b294d59bf1db9fe53c141ff772f27a8b456b2a9ed \ + --hash=sha256:454d9b4ae7881afbc25015b8627c16d88a597479b9dea82b8c6e7e2e07240dc7 \ + --hash=sha256:4aecb6f461316adf9f1f0f6a4a1a3d79e045f9b71ec76055a791affa3b285850 \ + --hash=sha256:4bf146dca15cdd53224a1bf46d628bd7590e4a07fbb69e720d561aea43a32b38 \ + --hash=sha256:4c5238d32f3c5269d9e87be0cf096437b7622b6920f5eac4fd202468aaeb34d2 \ + --hash=sha256:4e1e592789704459900728d88d41a46fe3969b82ab62945560a31732ffc19a6d \ + --hash=sha256:509dc827f89c15c66a0c216331260d777dd6c81e9a4e4f830e662b0bb296c313 \ + --hash=sha256:51c1c1847128238f54930edb8805b660305dca164645a9fd29243f5610beea34 \ + --hash=sha256:5cf77eac15bd264986c4a2c63353212c095b40f3affb2bc6b4ef80c4776c1a28 \ + --hash=sha256:5d9903ca42bfeec4cebedba8022a7c97ad2aab22e09573ce9976ba01b65e4361 \ + --hash=sha256:61a08bcb0ec14ff4e0ed2044aad948d0659604f824cbd50b55e30b0ec6f09c73 \ + --hash=sha256:62ba394a3dda9ad41c7c780f60f6e4a70988741415ae96f6d1bf6c239cf01379 \ + --hash=sha256:639431bdc89d6429f6721625e8129413980ccd62e9d3f496be618a41d205f160 \ + --hash=sha256:64350685ff08b1d3a6fff33f45a9ca183dc1d58bbfe4981604e70ec9801bbc26 \ + --hash=sha256:6538241f45eb5a25aa575dbba1069ad786f68a4f2773a29a2bd3dd1f9de787be \ + --hash=sha256:669dcfb2e38f9e8c69507bace46f4889e3abbfd9b0c29719202883c0a603598f \ + --hash=sha256:66d559b21d3640203ab9075797a55165d79017520685fb407b9234d72ab63c62 \ + --hash=sha256:6dd329a1b61c0ee95ba95385fb0c07ea0d3fe1a21e1349fa2bec272636217118 \ + --hash=sha256:728a9d2d173a65b62bdc380b7932dd8e74ed4295279a8fe1021204ce210803e7 \ + --hash=sha256:732aea6de26051af97b94bc98ed86448821f839d058e5d259c72bf6d73ad0fc0 \ + --hash=sha256:74d04244852ff73b32eeede4f76f51c5bcf44bc3c207bc3e6cf1c5c45b890708 \ + --hash=sha256:7521684c8c7c4f6e88e35ec89680ee1aa8358d3f09d27dfbdf62c446f5d4c695 \ + --hash=sha256:75fa6f0056e7efb1f42a1c34e58be24072cb9e61a601340cc1196ae92326a4f9 \ + --hash=sha256:78c2d02bb6e1da0720eedc0bad578049cad3f71050ef8cd065ecc87691bed2b0 \ + --hash=sha256:795ea137b1d809eb6836b43748b12634291c0ed55ad50a7d72d21edf1cd565c4 \ + --hash=sha256:7a50cd39f73faa34ec18d6720ee25ef10c4c1839514186fcda658a06c06057a2 \ + --hash=sha256:7a7c7fdf755032ffdd72c77e3d8096bdcb0eb92e89e17571a196f03d88b11b3c \ + --hash=sha256:7be0277469bf3bd7a34a9c57c1b6a724532a0d235cd0dc4e7f4316f982c28b19 \ + --hash=sha256:7eb542fd347ce61e1321b0a6b945d5701528dca0cd9759c2e3bb8bd57e47964d \ + --hash=sha256:7fe6e5440584e94cc4b3f5f4d98a25e29ca12dccf8873679a635638349831b98 \ + --hash=sha256:81519e25707fc076978c6143b81ea3dc853f176895af05bf7ec51effe818aeec \ + --hash=sha256:838441333bc90b829406d4a03cb4b8bf7656231b84358628b0406d803931ef32 \ + --hash=sha256:849202cd789e5f3cf5dcc7822c34b502181b4824a65ff20ce82da5524e45e8e9 \ + --hash=sha256:856a25c73b697f2ce2a24e7968285579e62577a048526161a2c0f53090bea9f9 \ + --hash=sha256:87eb52a81ef58c7ba4d45c3ca74e12aa4b4e77816f72ca25258a85b3ea96cb48 \ + --hash=sha256:885b26aa3ee56433b630502dc3d36ba78d186a00cc535d3806e6bfd9ed3c70ab \ + --hash=sha256:8a3d571bd95fade53c86c0517f859477ff3a93c3fde10c9e669086f038e0f207 \ + --hash=sha256:8e026094aa12b43f4fd74576714e987803a315c76edb6b098b9809db5de58f74 \ + --hash=sha256:9697a52e57576c83139d7c6f213d64485d3df5bf84807c35fa409e6c970801c6 \ + --hash=sha256:9b5aca4d5dfd7fbfbfbdaf44850fcc7709a01146a797536a8f84952e940cca76 \ + --hash=sha256:9ddc42e68114e161e51e272f667d640f97e84a2b9ef14b7477c53aac20c2d59a \ + --hash=sha256:9f95fbaa0ee1610ec0fc6b26668e9917a582ba80c52cc6d9ada15e30aa9ab9ad \ + --hash=sha256:a12ab1f5c29b4e93db518f5e3872116b7e9b1646c9f9f426f777b50d44a09e8c \ + --hash=sha256:a295ca2bba5c1c885826ce3125fa0b9f702a1be547d821c01d65f199e10c01e2 \ + --hash=sha256:a4cb042b615245d5ff9b3794f56be4138b5adc35a4166014d31d1814744148c7 \ + --hash=sha256:adad1a1bcf1c9e76346e091d22d23ac54ef28e1365117d99521631078dfec9de \ + --hash=sha256:b4774ff32f18e0504bfc4e59a3e71e18d83bc1e171a3c8ed75013958a03b2f14 \ + --hash=sha256:b6f78f98741dcc89607c16b1e9426ee46ce4bf31ac5e6b0d40e81c89f3481ea5 \ + --hash=sha256:b7f9ee819f94c6abfa56ec7b1dbab586f41ebbdc0a57e6524bd5e7f487a878c7 \ + --hash=sha256:ba0d8a5d7f04f73ee7d01d974d47c5834f8a1b0224390e4fe7c12a3a92a78ecc \ + --hash=sha256:bac4200befe50c670c405dc33af26dad5a3b6b255dd6c000d92fe4629f9ed6a5 \ + --hash=sha256:bc8ab71e2e31b16e40868a40a69007bc305e1109bd4658eb6cad007e0bf67c41 \ + --hash=sha256:bce22519c989bb72a7e6b36a199384c53db7722fe669ba891da75907fe3587db \ + --hash=sha256:bf3490bcbb985a1ae97b2ce9ad1c0f06a852d5b19dde9b07bdf25bf224248c95 \ + --hash=sha256:c1e448051717a334891f2b9a620fe36776ebf3dd8ec46a0b877c8ae69575feb4 \ + --hash=sha256:c54f768482cef41e219720013cd05933b6f971d9562544d691c68699bf2b6801 \ + --hash=sha256:c56b4d162ca2b43318ac671c65bd4d563e841a694ac70e1a976ac38fcf4ca1d2 \ + --hash=sha256:c9c30003b9347c24bcc210958c5d167b9e4f9be786cb380a7d32f14f9b84674f \ + --hash=sha256:cc4076a5b4f36d849fd709284b4a3b112326652f3b0466f04002a6c15a0c96c1 \ + --hash=sha256:cfe6d3f0c9e3b7e8c0c694b24d25e677776f5ca26dce46fd6b0489f9c8339391 \ + --hash=sha256:d6c2d5919075a1f2e413c00b056ea0c2f065b3f5fe83c3d07d325ab92dce51d6 \ + --hash=sha256:d8b4a27eebd684319bdf473d39f1d79eed36bf2cd34bd4465cdb4618d82b3d56 \ + --hash=sha256:dbe6095001465294f13f1adcd3311e50dd84e5a71525f20a10bd16689c61ce0b \ + --hash=sha256:dd16e78eb18ffdb25ee33a0682d17912e8cc8a770e885aeee95020046128f1ce \ + --hash=sha256:ddd76a9f58e6a00f8772e72cff8ebcff78e022be95edf018766707c730593e1e \ + --hash=sha256:df9eb838c44f570283712e7cff14c16329a9f0fb19ca492d21d4b7528ee6821e \ + --hash=sha256:dfec44d532be4c07088c3de2876130ff0fbeeacaa89a137decbbb5f665855a0f \ + --hash=sha256:e18bc3f73bd41243c9b38a6d9f2366cd0e0137a9aebe2d8ff76c5b67d4c0a3f4 \ + --hash=sha256:e43586ce5bd28f9f285a6e729466841368c4a0353f6fd08d4ce4630843d3648a \ + --hash=sha256:e6b49cd2aad93a1790ce9cffb18964f6d3a4b0b3dbdbd5de094b65296fce6e58 \ + --hash=sha256:e6c7a21dffba883234baefe91bc3388e629779582038f75d2a5be918e250f0ed \ + --hash=sha256:e721d1b46e25c481dc5ded6f4b3f66c897c58d2e8cfdf77bbced84339108b0b9 \ + --hash=sha256:eadade04221641516fa25139273505a1c19f9bf97589a05bc4cfcd8b4a618031 \ + --hash=sha256:ee3a83ce492074c35a74cc76cf8235d49e77b757193a5365ff86e3f2f93db9fd \ + --hash=sha256:f117efad42068f9715677c8523ed2be1518116d1c49b1dd17987716695181efe \ + --hash=sha256:f3b5a391c7597ffa96b41bd5cbd2ed0305f515fcbb367dfa72735679d5502364 \ + --hash=sha256:f4ff94e58e84aedb9c9fce66d4ef9f27a190285b451420f297c9a09f2b9abee9 \ + --hash=sha256:f99be08cfead2020c7ca6e396c13543baea32343b7a9a5780c462e323bd8872f \ + --hash=sha256:fd0a5e563c756de210bb964789b5abe4f114dacae9104a47e1a649b910361536 \ + --hash=sha256:feff9e54ec0dd3833d659257f5c3f5322a12eee58ffa360984b716f8b92983f4 \ + --hash=sha256:ffcca5b9efe948ba0661e9df0fa50d2bc4b097c70b9810212d6b62f05d83b2dd # via sphinx-lint requests==2.32.5 \ --hash=sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6 \ --hash=sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf # via pygithub -reuse==5.1.1 \ - --hash=sha256:15a68341949b7ddb3630d8d3a49d9537bbc143ee235dca77cc3f4047237c8299 \ - --hash=sha256:a13914ed8b66b8e5956e96c63203c63d72b55280d348849ccc0eb314c73248cb +reuse==6.2.0 \ + --hash=sha256:12b68549bb9d5f4957f06d726a83a9780628810008fb732bb0d0f21607f8c6d6 \ + --hash=sha256:4feae057a2334c9a513e6933cdb9be819d8b822f3b5b435a36138bd218897d23 # via -r requirements-actions.in -rpds-py==0.27.1 \ - --hash=sha256:008b839781d6c9bf3b6a8984d1d8e56f0ec46dc56df61fd669c49b58ae800400 \ - --hash=sha256:037a2361db72ee98d829bc2c5b7cc55598ae0a5e0ec1823a56ea99374cfd73c1 \ - --hash=sha256:079bc583a26db831a985c5257797b2b5d3affb0386e7ff886256762f82113b5e \ - --hash=sha256:08f1e20bccf73b08d12d804d6e1c22ca5530e71659e6673bce31a6bb71c1e73f \ - --hash=sha256:0b08d152555acf1f455154d498ca855618c1378ec810646fcd7c76416ac6dc60 \ - --hash=sha256:0d807710df3b5faa66c731afa162ea29717ab3be17bdc15f90f2d9f183da4059 \ - --hash=sha256:0dc5dceeaefcc96dc192e3a80bbe1d6c410c469e97bdd47494a7d930987f18b2 \ - --hash=sha256:12ed005216a51b1d6e2b02a7bd31885fe317e45897de81d86dcce7d74618ffff \ - --hash=sha256:134fae0e36022edad8290a6661edf40c023562964efea0cc0ec7f5d392d2aaef \ - --hash=sha256:13e608ac9f50a0ed4faec0e90ece76ae33b34c0e8656e3dceb9a7db994c692cd \ - --hash=sha256:1441811a96eadca93c517d08df75de45e5ffe68aa3089924f963c782c4b898cf \ - --hash=sha256:15d3b4d83582d10c601f481eca29c3f138d44c92187d197aff663a269197c02d \ - --hash=sha256:16323f674c089b0360674a4abd28d5042947d54ba620f72514d69be4ff64845e \ - --hash=sha256:168b025f8fd8d8d10957405f3fdcef3dc20f5982d398f90851f4abc58c566c52 \ - --hash=sha256:1b207d881a9aef7ba753d69c123a35d96ca7cb808056998f6b9e8747321f03b8 \ - --hash=sha256:1fea2b1a922c47c51fd07d656324531adc787e415c8b116530a1d29c0516c62d \ - --hash=sha256:23f6b69d1c26c4704fec01311963a41d7de3ee0570a84ebde4d544e5a1859ffc \ - --hash=sha256:2643400120f55c8a96f7c9d858f7be0c88d383cd4653ae2cf0d0c88f668073e5 \ - --hash=sha256:26a1c73171d10b7acccbded82bf6a586ab8203601e565badc74bbbf8bc5a10f8 \ - --hash=sha256:2bde09cbcf2248b73c7c323be49b280180ff39fadcfe04e7b6f54a678d02a7cf \ - --hash=sha256:2c426b99a068601b5f4623573df7a7c3d72e87533a2dd2253353a03e7502566c \ - --hash=sha256:2efe4eb1d01b7f5f1939f4ef30ecea6c6b3521eec451fb93191bf84b2a522418 \ - --hash=sha256:2f57af9b4d0793e53266ee4325535a31ba48e2f875da81a9177c9926dfa60746 \ - --hash=sha256:2fd50659a069c15eef8aa3d64bbef0d69fd27bb4a50c9ab4f17f83a16cbf8905 \ - --hash=sha256:3020724ade63fe320a972e2ffd93b5623227e684315adce194941167fee02688 \ - --hash=sha256:3182af66048c00a075010bc7f4860f33913528a4b6fc09094a6e7598e462fe39 \ - --hash=sha256:31d3ebadefcd73b73928ed0b2fd696f7fefda8629229f81929ac9c1854d0cffb \ - --hash=sha256:33aa65b97826a0e885ef6e278fbd934e98cdcfed80b63946025f01e2f5b29502 \ - --hash=sha256:387ce8c44ae94e0ec50532d9cb0edce17311024c9794eb196b90e1058aadeb66 \ - --hash=sha256:3adc388fc3afb6540aec081fa59e6e0d3908722771aa1e37ffe22b220a436f0b \ - --hash=sha256:3c64d07e95606ec402a0a1c511fe003873fa6af630bda59bac77fac8b4318ebc \ - --hash=sha256:3ce0cac322b0d69b63c9cdb895ee1b65805ec9ffad37639f291dd79467bee675 \ - --hash=sha256:3d905d16f77eb6ab2e324e09bfa277b4c8e5e6b8a78a3e7ff8f3cdf773b4c013 \ - --hash=sha256:3deab27804d65cd8289eb814c2c0e807c4b9d9916c9225e363cb0cf875eb67c1 \ - --hash=sha256:3e039aabf6d5f83c745d5f9a0a381d031e9ed871967c0a5c38d201aca41f3ba1 \ - --hash=sha256:41e532bbdcb57c92ba3be62c42e9f096431b4cf478da9bc3bc6ce5c38ab7ba7a \ - --hash=sha256:42a89282d711711d0a62d6f57d81aa43a1368686c45bc1c46b7f079d55692734 \ - --hash=sha256:466bfe65bd932da36ff279ddd92de56b042f2266d752719beb97b08526268ec5 \ - --hash=sha256:4708c5c0ceb2d034f9991623631d3d23cb16e65c83736ea020cdbe28d57c0a0e \ - --hash=sha256:47162fdab9407ec3f160805ac3e154df042e577dd53341745fc7fb3f625e6d92 \ - --hash=sha256:4848ca84d6ded9b58e474dfdbad4b8bfb450344c0551ddc8d958bf4b36aa837c \ - --hash=sha256:4b507d19f817ebaca79574b16eb2ae412e5c0835542c93fe9983f1e432aca195 \ - --hash=sha256:4e44099bd522cba71a2c6b97f68e19f40e7d85399de899d66cdb67b32d7cb786 \ - --hash=sha256:4ed2e16abbc982a169d30d1a420274a709949e2cbdef119fe2ec9d870b42f274 \ - --hash=sha256:4f75e4bd8ab8db624e02c8e2fc4063021b58becdbe6df793a8111d9343aec1e3 \ - --hash=sha256:4fc9b7fe29478824361ead6e14e4f5aed570d477e06088826537e202d25fe859 \ - --hash=sha256:50c946f048209e6362e22576baea09193809f87687a95a8db24e5fbdb307b93a \ - --hash=sha256:5281ed1cc1d49882f9997981c88df1a22e140ab41df19071222f7e5fc4e72125 \ - --hash=sha256:530064db9146b247351f2a0250b8f00b289accea4596a033e94be2389977de71 \ - --hash=sha256:55266dafa22e672f5a4f65019015f90336ed31c6383bd53f5e7826d21a0e0b83 \ - --hash=sha256:5b640501be9288c77738b5492b3fd3abc4ba95c50c2e41273c8a1459f08298d3 \ - --hash=sha256:62ac3d4e3e07b58ee0ddecd71d6ce3b1637de2d373501412df395a0ec5f9beb5 \ - --hash=sha256:62f85b665cedab1a503747617393573995dac4600ff51869d69ad2f39eb5e817 \ - --hash=sha256:639fd5efec029f99b79ae47e5d7e00ad8a773da899b6309f6786ecaf22948c48 \ - --hash=sha256:6567d2bb951e21232c2f660c24cf3470bb96de56cdcb3f071a83feeaff8a2772 \ - --hash=sha256:67ce7620704745881a3d4b0ada80ab4d99df390838839921f99e63c474f82cf2 \ - --hash=sha256:689fb5200a749db0415b092972e8eba85847c23885c8543a8b0f5c009b1a5948 \ - --hash=sha256:68afeec26d42ab3b47e541b272166a0b4400313946871cba3ed3a4fc0cab1cef \ - --hash=sha256:6e5e54da1e74b91dbc7996b56640f79b195d5925c2b78efaa8c5d53e1d88edde \ - --hash=sha256:6f4461bf931108c9fa226ffb0e257c1b18dc2d44cd72b125bec50ee0ab1248a9 \ - --hash=sha256:6f5b7bd8e219ed50299e58551a410b64daafb5017d54bbe822e003856f06a802 \ - --hash=sha256:70d0738ef8fee13c003b100c2fbd667ec4f133468109b3472d249231108283a3 \ - --hash=sha256:71108900c9c3c8590697244b9519017a400d9ba26a36c48381b3f64743a44aab \ - --hash=sha256:74e5b2f7bb6fa38b1b10546d27acbacf2a022a8b5543efb06cfebc72a59c85be \ - --hash=sha256:78af06ddc7fe5cc0e967085a9115accee665fb912c22a3f54bad70cc65b05fe6 \ - --hash=sha256:7b002cab05d6339716b03a4a3a2ce26737f6231d7b523f339fa061d53368c9d8 \ - --hash=sha256:7b90b0496570bd6b0321724a330d8b545827c4df2034b6ddfc5f5275f55da2ad \ - --hash=sha256:7ba22cb9693df986033b91ae1d7a979bc399237d45fccf875b76f62bb9e52ddf \ - --hash=sha256:7ba32c16b064267b22f1850a34051121d423b6f7338a12b9459550eb2096e7ec \ - --hash=sha256:7e32721e5d4922deaaf963469d795d5bde6093207c52fec719bd22e5d1bedbc4 \ - --hash=sha256:7ee6521b9baf06085f62ba9c7a3e5becffbc32480d2f1b351559c001c38ce4c1 \ - --hash=sha256:80c60cfb5310677bd67cb1e85a1e8eb52e12529545441b43e6f14d90b878775a \ - --hash=sha256:8177002868d1426305bb5de1e138161c2ec9eb2d939be38291d7c431c4712df8 \ - --hash=sha256:819064fa048ba01b6dadc5116f3ac48610435ac9a0058bbde98e569f9e785c39 \ - --hash=sha256:84f7d509870098de0e864cad0102711c1e24e9b1a50ee713b65928adb22269e4 \ - --hash=sha256:879b0e14a2da6a1102a3fc8af580fc1ead37e6d6692a781bd8c83da37429b5ab \ - --hash=sha256:8a3f29aba6e2d7d90528d3c792555a93497fe6538aa65eb675b44505be747808 \ - --hash=sha256:8a63b640a7845f2bdd232eb0d0a4a2dd939bcdd6c57e6bb134526487f3160ec5 \ - --hash=sha256:8b61097f7488de4be8244c89915da8ed212832ccf1e7c7753a25a394bf9b1f10 \ - --hash=sha256:8ee50c3e41739886606388ba3ab3ee2aae9f35fb23f833091833255a31740797 \ - --hash=sha256:8fabb8fd848a5f75a2324e4a84501ee3a5e3c78d8603f83475441866e60b94a3 \ - --hash=sha256:9024de74731df54546fab0bfbcdb49fae19159ecaecfc8f37c18d2c7e2c0bd61 \ - --hash=sha256:92022bbbad0d4426e616815b16bc4127f83c9a74940e1ccf3cfe0b387aba0228 \ - --hash=sha256:93a2ed40de81bcff59aabebb626562d48332f3d028ca2036f1d23cbb52750be4 \ - --hash=sha256:94c44ee01fd21c9058f124d2d4f0c9dc7634bec93cd4b38eefc385dabe71acbf \ - --hash=sha256:9a1f4814b65eacac94a00fc9a526e3fdafd78e439469644032032d0d63de4881 \ - --hash=sha256:9d992ac10eb86d9b6f369647b6a3f412fc0075cfd5d799530e84d335e440a002 \ - --hash=sha256:9e71f5a087ead99563c11fdaceee83ee982fd39cf67601f4fd66cb386336ee52 \ - --hash=sha256:a205fdfe55c90c2cd8e540ca9ceba65cbe6629b443bc05db1f590a3db8189ff9 \ - --hash=sha256:a46fdec0083a26415f11d5f236b79fa1291c32aaa4a17684d82f7017a1f818b1 \ - --hash=sha256:a50431bf02583e21bf273c71b89d710e7a710ad5e39c725b14e685610555926f \ - --hash=sha256:a512c8263249a9d68cac08b05dd59d2b3f2061d99b322813cbcc14c3c7421998 \ - --hash=sha256:a55b9132bb1ade6c734ddd2759c8dc132aa63687d259e725221f106b83a0e485 \ - --hash=sha256:a6e57b0abfe7cc513450fcf529eb486b6e4d3f8aee83e92eb5f1ef848218d456 \ - --hash=sha256:a75f305c9b013289121ec0f1181931975df78738cdf650093e6b86d74aa7d8dd \ - --hash=sha256:a9e960fc78fecd1100539f14132425e1d5fe44ecb9239f8f27f079962021523e \ - --hash=sha256:aa8933159edc50be265ed22b401125c9eebff3171f570258854dbce3ecd55475 \ - --hash=sha256:aaf94f812c95b5e60ebaf8bfb1898a7d7cb9c1af5744d4a67fa47796e0465d4e \ - --hash=sha256:abfa1171a9952d2e0002aba2ad3780820b00cc3d9c98c6630f2e93271501f66c \ - --hash=sha256:acb9aafccaae278f449d9c713b64a9e68662e7799dbd5859e2c6b3c67b56d334 \ - --hash=sha256:ae2775c1973e3c30316892737b91f9283f9908e3cc7625b9331271eaaed7dc90 \ - --hash=sha256:ae92443798a40a92dc5f0b01d8a7c93adde0c4dc965310a29ae7c64d72b9fad2 \ - --hash=sha256:b2e7f8f169d775dd9092a1743768d771f1d1300453ddfe6325ae3ab5332b4657 \ - --hash=sha256:b4938466c6b257b2f5c4ff98acd8128ec36b5059e5c8f8372d79316b1c36bb15 \ - --hash=sha256:b6dfb0e058adb12d8b1d1b25f686e94ffa65d9995a5157afe99743bf7369d62b \ - --hash=sha256:b7fb801aa7f845ddf601c49630deeeccde7ce10065561d92729bfe81bd21fb33 \ - --hash=sha256:ba81d2b56b6d4911ce735aad0a1d4495e808b8ee4dc58715998741a26874e7c2 \ - --hash=sha256:bbf94c58e8e0cd6b6f38d8de67acae41b3a515c26169366ab58bdca4a6883bb8 \ - --hash=sha256:be898f271f851f68b318872ce6ebebbc62f303b654e43bf72683dbdc25b7c881 \ - --hash=sha256:bf876e79763eecf3e7356f157540d6a093cef395b65514f17a356f62af6cc136 \ - --hash=sha256:c1476d6f29eb81aa4151c9a31219b03f1f798dc43d8af1250a870735516a1212 \ - --hash=sha256:c2a8fed130ce946d5c585eddc7c8eeef0051f58ac80a8ee43bd17835c144c2cc \ - --hash=sha256:c46c9dd2403b66a2a3b9720ec4b74d4ab49d4fabf9f03dfdce2d42af913fe8d0 \ - --hash=sha256:c4b676c4ae3921649a15d28ed10025548e9b561ded473aa413af749503c6737e \ - --hash=sha256:c796c0c1cc68cb08b0284db4229f5af76168172670c74908fdbd4b7d7f515819 \ - --hash=sha256:c918c65ec2e42c2a78d19f18c553d77319119bf43aa9e2edf7fb78d624355527 \ - --hash=sha256:cb56c6210ef77caa58e16e8c17d35c63fe3f5b60fd9ba9d424470c3400bcf9ed \ - --hash=sha256:cdfe4bb2f9fe7458b7453ad3c33e726d6d1c7c0a72960bcc23800d77384e42df \ - --hash=sha256:cf9931f14223de59551ab9d38ed18d92f14f055a5f78c1d8ad6493f735021bbb \ - --hash=sha256:d252f2d8ca0195faa707f8eb9368955760880b2b42a8ee16d382bf5dd807f89a \ - --hash=sha256:d5fa0ee122dc09e23607a28e6d7b150da16c662e66409bbe85230e4c85bb528a \ - --hash=sha256:d76f9cc8665acdc0c9177043746775aa7babbf479b5520b78ae4002d889f5c21 \ - --hash=sha256:d78827d7ac08627ea2c8e02c9e5b41180ea5ea1f747e9db0915e3adf36b62dcf \ - --hash=sha256:d7ff07d696a7a38152ebdb8212ca9e5baab56656749f3d6004b34ab726b550b8 \ - --hash=sha256:d9199717881f13c32c4046a15f024971a3b78ad4ea029e8da6b86e5aa9cf4594 \ - --hash=sha256:dc23e6820e3b40847e2f4a7726462ba0cf53089512abe9ee16318c366494c17a \ - --hash=sha256:dce51c828941973a5684d458214d3a36fcd28da3e1875d659388f4f9f12cc33e \ - --hash=sha256:dd2135527aa40f061350c3f8f89da2644de26cd73e4de458e79606384f4f68e7 \ - --hash=sha256:dd6cd0485b7d347304067153a6dc1d73f7d4fd995a396ef32a24d24b8ac63ac8 \ - --hash=sha256:df8b74962e35c9249425d90144e721eed198e6555a0e22a563d29fe4486b51f6 \ - --hash=sha256:dfbfac137d2a3d0725758cd141f878bf4329ba25e34979797c89474a89a8a3a3 \ - --hash=sha256:e202e6d4188e53c6661af813b46c37ca2c45e497fc558bacc1a7630ec2695aec \ - --hash=sha256:e2f6fd8a1cea5bbe599b6e78a6e5ee08db434fc8ffea51ff201c8765679698b3 \ - --hash=sha256:e48af21883ded2b3e9eb48cb7880ad8598b31ab752ff3be6457001d78f416723 \ - --hash=sha256:e4b9fcfbc021633863a37e92571d6f91851fa656f0180246e84cbd8b3f6b329b \ - --hash=sha256:e5c20f33fd10485b80f65e800bbe5f6785af510b9f4056c5a3c612ebc83ba6cb \ - --hash=sha256:eb11a4f1b2b63337cfd3b4d110af778a59aae51c81d195768e353d8b52f88081 \ - --hash=sha256:ed090ccd235f6fa8bb5861684567f0a83e04f52dfc2e5c05f2e4b1309fcf85e7 \ - --hash=sha256:ed10dc32829e7d222b7d3b93136d25a406ba9788f6a7ebf6809092da1f4d279d \ - --hash=sha256:eda8719d598f2f7f3e0f885cba8646644b55a187762bec091fa14a2b819746a9 \ - --hash=sha256:ee4308f409a40e50593c7e3bb8cbe0b4d4c66d1674a316324f0c2f5383b486f9 \ - --hash=sha256:ee5422d7fb21f6a00c1901bf6559c49fee13a5159d0288320737bbf6585bd3e4 \ - --hash=sha256:f149826d742b406579466283769a8ea448eed82a789af0ed17b0cd5770433444 \ - --hash=sha256:f2729615f9d430af0ae6b36cf042cb55c0936408d543fb691e1a9e36648fd35a \ - --hash=sha256:f39f58a27cc6e59f432b568ed8429c7e1641324fbe38131de852cd77b2d534b0 \ - --hash=sha256:f41f814b8eaa48768d1bb551591f6ba45f87ac76899453e8ccd41dba1289b04b \ - --hash=sha256:f9025faafc62ed0b75a53e541895ca272815bec18abe2249ff6501c8f2e12b83 \ - --hash=sha256:faf8d146f3d476abfee026c4ae3bdd9ca14236ae4e4c310cbd1cf75ba33d24a3 \ - --hash=sha256:fb08b65b93e0c6dd70aac7f7890a9c0938d5ec71d5cb32d45cf844fb8ae47636 \ - --hash=sha256:fb7c72262deae25366e3b6c0c0ba46007967aea15d1eea746e44ddba8ec58dcc \ - --hash=sha256:fb89bec23fddc489e5d78b550a7b773557c9ab58b7946154a10a6f7a214a48b2 \ - --hash=sha256:fe0dd05afb46597b9a2e11c351e5e4283c741237e7f617ffb3252780cca9336a \ - --hash=sha256:fecc80cb2a90e28af8a9b366edacf33d7a91cbfe4c2c4544ea1246e949cfebeb \ - --hash=sha256:fed467af29776f6556250c9ed85ea5a4dd121ab56a5f8b206e3e7a4c551e48ec \ - --hash=sha256:ffce0481cc6e95e5b3f0a47ee17ffbd234399e6d532f394c8dce320c3b089c21 +rpds-py==0.30.0 \ + --hash=sha256:07ae8a593e1c3c6b82ca3292efbe73c30b61332fd612e05abee07c79359f292f \ + --hash=sha256:0a59119fc6e3f460315fe9d08149f8102aa322299deaa5cab5b40092345c2136 \ + --hash=sha256:0c0e95f6819a19965ff420f65578bacb0b00f251fefe2c8b23347c37174271f3 \ + --hash=sha256:0d08f00679177226c4cb8c5265012eea897c8ca3b93f429e546600c971bcbae7 \ + --hash=sha256:0ed177ed9bded28f8deb6ab40c183cd1192aa0de40c12f38be4d59cd33cb5c65 \ + --hash=sha256:12f90dd7557b6bd57f40abe7747e81e0c0b119bef015ea7726e69fe550e394a4 \ + --hash=sha256:1726859cd0de969f88dc8673bdd954185b9104e05806be64bcd87badbe313169 \ + --hash=sha256:1ab5b83dbcf55acc8b08fc62b796ef672c457b17dbd7820a11d6c52c06839bdf \ + --hash=sha256:1b151685b23929ab7beec71080a8889d4d6d9fa9a983d213f07121205d48e2c4 \ + --hash=sha256:1f3587eb9b17f3789ad50824084fa6f81921bbf9a795826570bda82cb3ed91f2 \ + --hash=sha256:250fa00e9543ac9b97ac258bd37367ff5256666122c2d0f2bc97577c60a1818c \ + --hash=sha256:2771c6c15973347f50fece41fc447c054b7ac2ae0502388ce3b6738cd366e3d4 \ + --hash=sha256:27f4b0e92de5bfbc6f86e43959e6edd1425c33b5e69aab0984a72047f2bcf1e3 \ + --hash=sha256:2e6ecb5a5bcacf59c3f912155044479af1d0b6681280048b338b28e364aca1f6 \ + --hash=sha256:32c8528634e1bf7121f3de08fa85b138f4e0dc47657866630611b03967f041d7 \ + --hash=sha256:33f559f3104504506a44bb666b93a33f5d33133765b0c216a5bf2f1e1503af89 \ + --hash=sha256:3896fa1be39912cf0757753826bc8bdc8ca331a28a7c4ae46b7a21280b06bb85 \ + --hash=sha256:389a2d49eded1896c3d48b0136ead37c48e221b391c052fba3f4055c367f60a6 \ + --hash=sha256:39c02563fc592411c2c61d26b6c5fe1e51eaa44a75aa2c8735ca88b0d9599daa \ + --hash=sha256:3adbb8179ce342d235c31ab8ec511e66c73faa27a47e076ccc92421add53e2bb \ + --hash=sha256:3d4a69de7a3e50ffc214ae16d79d8fbb0922972da0356dcf4d0fdca2878559c6 \ + --hash=sha256:3e62880792319dbeb7eb866547f2e35973289e7d5696c6e295476448f5b63c87 \ + --hash=sha256:3e8eeb0544f2eb0d2581774be4c3410356eba189529a6b3e36bbbf9696175856 \ + --hash=sha256:422c3cb9856d80b09d30d2eb255d0754b23e090034e1deb4083f8004bd0761e4 \ + --hash=sha256:4559c972db3a360808309e06a74628b95eaccbf961c335c8fe0d590cf587456f \ + --hash=sha256:46e83c697b1f1c72b50e5ee5adb4353eef7406fb3f2043d64c33f20ad1c2fc53 \ + --hash=sha256:47b0ef6231c58f506ef0b74d44e330405caa8428e770fec25329ed2cb971a229 \ + --hash=sha256:47e77dc9822d3ad616c3d5759ea5631a75e5809d5a28707744ef79d7a1bcfcad \ + --hash=sha256:47f236970bccb2233267d89173d3ad2703cd36a0e2a6e92d0560d333871a3d23 \ + --hash=sha256:47f9a91efc418b54fb8190a6b4aa7813a23fb79c51f4bb84e418f5476c38b8db \ + --hash=sha256:495aeca4b93d465efde585977365187149e75383ad2684f81519f504f5c13038 \ + --hash=sha256:4c5f36a861bc4b7da6516dbdf302c55313afa09b81931e8280361a4f6c9a2d27 \ + --hash=sha256:4cc2206b76b4f576934f0ed374b10d7ca5f457858b157ca52064bdfc26b9fc00 \ + --hash=sha256:4e7fc54e0900ab35d041b0601431b0a0eb495f0851a0639b6ef90f7741b39a18 \ + --hash=sha256:51a1234d8febafdfd33a42d97da7a43f5dcb120c1060e352a3fbc0c6d36e2083 \ + --hash=sha256:55f66022632205940f1827effeff17c4fa7ae1953d2b74a8581baaefb7d16f8c \ + --hash=sha256:58edca431fb9b29950807e301826586e5bbf24163677732429770a697ffe6738 \ + --hash=sha256:5965af57d5848192c13534f90f9dd16464f3c37aaf166cc1da1cae1fd5a34898 \ + --hash=sha256:5ba103fb455be00f3b1c2076c9d4264bfcb037c976167a6047ed82f23153f02e \ + --hash=sha256:5d4c2aa7c50ad4728a094ebd5eb46c452e9cb7edbfdb18f9e1221f597a73e1e7 \ + --hash=sha256:61046904275472a76c8c90c9ccee9013d70a6d0f73eecefd38c1ae7c39045a08 \ + --hash=sha256:613aa4771c99f03346e54c3f038e4cc574ac09a3ddfb0e8878487335e96dead6 \ + --hash=sha256:626a7433c34566535b6e56a1b39a7b17ba961e97ce3b80ec62e6f1312c025551 \ + --hash=sha256:669b1805bd639dd2989b281be2cfd951c6121b65e729d9b843e9639ef1fd555e \ + --hash=sha256:679ae98e00c0e8d68a7fda324e16b90fd5260945b45d3b824c892cec9eea3288 \ + --hash=sha256:67b02ec25ba7a9e8fa74c63b6ca44cf5707f2fbfadae3ee8e7494297d56aa9df \ + --hash=sha256:68f19c879420aa08f61203801423f6cd5ac5f0ac4ac82a2368a9fcd6a9a075e0 \ + --hash=sha256:692bef75a5525db97318e8cd061542b5a79812d711ea03dbc1f6f8dbb0c5f0d2 \ + --hash=sha256:6abc8880d9d036ecaafe709079969f56e876fcf107f7a8e9920ba6d5a3878d05 \ + --hash=sha256:6bdfdb946967d816e6adf9a3d8201bfad269c67efe6cefd7093ef959683c8de0 \ + --hash=sha256:6de2a32a1665b93233cde140ff8b3467bdb9e2af2b91079f0333a0974d12d464 \ + --hash=sha256:73c67f2db7bc334e518d097c6d1e6fed021bbc9b7d678d6cc433478365d1d5f5 \ + --hash=sha256:74a3243a411126362712ee1524dfc90c650a503502f135d54d1b352bd01f2404 \ + --hash=sha256:76fec018282b4ead0364022e3c54b60bf368b9d926877957a8624b58419169b7 \ + --hash=sha256:7c64d38fb49b6cdeda16ab49e35fe0da2e1e9b34bc38bd78386530f218b37139 \ + --hash=sha256:7cee9c752c0364588353e627da8a7e808a66873672bcb5f52890c33fd965b394 \ + --hash=sha256:7e6ecfcb62edfd632e56983964e6884851786443739dbfe3582947e87274f7cb \ + --hash=sha256:806f36b1b605e2d6a72716f321f20036b9489d29c51c91f4dd29a3e3afb73b15 \ + --hash=sha256:858738e9c32147f78b3ac24dc0edb6610000e56dc0f700fd5f651d0a0f0eb9ff \ + --hash=sha256:8d6d1cc13664ec13c1b84241204ff3b12f9bb82464b8ad6e7a5d3486975c2eed \ + --hash=sha256:9027da1ce107104c50c81383cae773ef5c24d296dd11c99e2629dbd7967a20c6 \ + --hash=sha256:922e10f31f303c7c920da8981051ff6d8c1a56207dbdf330d9047f6d30b70e5e \ + --hash=sha256:945dccface01af02675628334f7cf49c2af4c1c904748efc5cf7bbdf0b579f95 \ + --hash=sha256:946fe926af6e44f3697abbc305ea168c2c31d3e3ef1058cf68f379bf0335a78d \ + --hash=sha256:95f0802447ac2d10bcc69f6dc28fe95fdf17940367b21d34e34c737870758950 \ + --hash=sha256:9854cf4f488b3d57b9aaeb105f06d78e5529d3145b1e4a41750167e8c213c6d3 \ + --hash=sha256:993914b8e560023bc0a8bf742c5f303551992dcb85e247b1e5c7f4a7d145bda5 \ + --hash=sha256:99b47d6ad9a6da00bec6aabe5a6279ecd3c06a329d4aa4771034a21e335c3a97 \ + --hash=sha256:9a4e86e34e9ab6b667c27f3211ca48f73dba7cd3d90f8d5b11be56e5dbc3fb4e \ + --hash=sha256:9cf69cdda1f5968a30a359aba2f7f9aa648a9ce4b580d6826437f2b291cfc86e \ + --hash=sha256:a090322ca841abd453d43456ac34db46e8b05fd9b3b4ac0c78bcde8b089f959b \ + --hash=sha256:a1010ed9524c73b94d15919ca4d41d8780980e1765babf85f9a2f90d247153dd \ + --hash=sha256:a161f20d9a43006833cd7068375a94d035714d73a172b681d8881820600abfad \ + --hash=sha256:a1d0bc22a7cdc173fedebb73ef81e07faef93692b8c1ad3733b67e31e1b6e1b8 \ + --hash=sha256:a2bffea6a4ca9f01b3f8e548302470306689684e61602aa3d141e34da06cf425 \ + --hash=sha256:a452763cc5198f2f98898eb98f7569649fe5da666c2dc6b5ddb10fde5a574221 \ + --hash=sha256:a4796a717bf12b9da9d3ad002519a86063dcac8988b030e405704ef7d74d2d9d \ + --hash=sha256:a51033ff701fca756439d641c0ad09a41d9242fa69121c7d8769604a0a629825 \ + --hash=sha256:a8fa71a2e078c527c3e9dc9fc5a98c9db40bcc8a92b4e8858e36d329f8684b51 \ + --hash=sha256:ac37f9f516c51e5753f27dfdef11a88330f04de2d564be3991384b2f3535d02e \ + --hash=sha256:ac98b175585ecf4c0348fd7b29c3864bda53b805c773cbf7bfdaffc8070c976f \ + --hash=sha256:acd7eb3f4471577b9b5a41baf02a978e8bdeb08b4b355273994f8b87032000a8 \ + --hash=sha256:ad1fa8db769b76ea911cb4e10f049d80bf518c104f15b3edb2371cc65375c46f \ + --hash=sha256:b40fb160a2db369a194cb27943582b38f79fc4887291417685f3ad693c5a1d5d \ + --hash=sha256:b4dc1a6ff022ff85ecafef7979a2c6eb423430e05f1165d6688234e62ba99a07 \ + --hash=sha256:ba3af48635eb83d03f6c9735dfb21785303e73d22ad03d489e88adae6eab8877 \ + --hash=sha256:ba81a9203d07805435eb06f536d95a266c21e5b2dfbf6517748ca40c98d19e31 \ + --hash=sha256:c2262bdba0ad4fc6fb5545660673925c2d2a5d9e2e0fb603aad545427be0fc58 \ + --hash=sha256:c77afbd5f5250bf27bf516c7c4a016813eb2d3e116139aed0096940c5982da94 \ + --hash=sha256:ca28829ae5f5d569bb62a79512c842a03a12576375d5ece7d2cadf8abe96ec28 \ + --hash=sha256:cdc62c8286ba9bf7f47befdcea13ea0e26bf294bda99758fd90535cbaf408000 \ + --hash=sha256:d948b135c4693daff7bc2dcfc4ec57237a29bd37e60c2fabf5aff2bbacf3e2f1 \ + --hash=sha256:d96c2086587c7c30d44f31f42eae4eac89b60dabbac18c7669be3700f13c3ce1 \ + --hash=sha256:d9a0ca5da0386dee0655b4ccdf46119df60e0f10da268d04fe7cc87886872ba7 \ + --hash=sha256:da279aa314f00acbb803da1e76fa18666778e8a8f83484fba94526da5de2cba7 \ + --hash=sha256:dbd936cde57abfee19ab3213cf9c26be06d60750e60a8e4dd85d1ab12c8b1f40 \ + --hash=sha256:dc4f992dfe1e2bc3ebc7444f6c7051b4bc13cd8e33e43511e8ffd13bf407010d \ + --hash=sha256:dc824125c72246d924f7f796b4f63c1e9dc810c7d9e2355864b3c3a73d59ade0 \ + --hash=sha256:dd8ff7cf90014af0c0f787eea34794ebf6415242ee1d6fa91eaba725cc441e84 \ + --hash=sha256:dea5b552272a944763b34394d04577cf0f9bd013207bc32323b5a89a53cf9c2f \ + --hash=sha256:dff13836529b921e22f15cb099751209a60009731a68519630a24d61f0b1b30a \ + --hash=sha256:e0b65193a413ccc930671c55153a03ee57cecb49e6227204b04fae512eb657a7 \ + --hash=sha256:e5d3e6b26f2c785d65cc25ef1e5267ccbe1b069c5c21b8cc724efee290554419 \ + --hash=sha256:e7536cd91353c5273434b4e003cbda89034d67e7710eab8761fd918ec6c69cf8 \ + --hash=sha256:eb0b93f2e5c2189ee831ee43f156ed34e2a89a78a66b98cadad955972548be5a \ + --hash=sha256:eb2c4071ab598733724c08221091e8d80e89064cd472819285a9ab0f24bcedb9 \ + --hash=sha256:ec7c4490c672c1a0389d319b3a9cfcd098dcdc4783991553c332a15acf7249be \ + --hash=sha256:ee454b2a007d57363c2dfd5b6ca4a5d7e2c518938f8ed3b706e37e5d470801ed \ + --hash=sha256:ee6af14263f25eedc3bb918a3c04245106a42dfd4f5c2285ea6f997b1fc3f89a \ + --hash=sha256:f14fc5df50a716f7ece6a80b6c78bb35ea2ca47c499e422aa4463455dd96d56d \ + --hash=sha256:f207f69853edd6f6700b86efb84999651baf3789e78a466431df1331608e5324 \ + --hash=sha256:f251c812357a3fed308d684a5079ddfb9d933860fc6de89f2b7ab00da481e65f \ + --hash=sha256:f83424d738204d9770830d35290ff3273fbb02b41f919870479fab14b9d303b2 \ + --hash=sha256:f8d1736cfb49381ba528cd5baa46f82fdc65c06e843dab24dd70b63d09121b3f \ + --hash=sha256:fe5fa731a1fa8a0a56b0977413f8cacac1768dad38d16b3a296712709476fbd5 # via # jsonschema # referencing @@ -1340,66 +1426,72 @@ rsa==4.7.2 \ --hash=sha256:78f9a9bf4e7be0c5ded4583326e7461e3a3c5aae24073648b4bdfa797d78c9d2 \ --hash=sha256:9d689e6ca1b3038bc82bf8d23e944b6b6037bc02301a574935b2dd946e0353b9 # via awscli -ruamel-yaml==0.18.15 \ - --hash=sha256:148f6488d698b7a5eded5ea793a025308b25eca97208181b6a026037f391f701 \ - --hash=sha256:dbfca74b018c4c3fba0b9cc9ee33e53c371194a9000e694995e620490fd40700 +ruamel-yaml==0.18.16 \ + --hash=sha256:048f26d64245bae57a4f9ef6feb5b552a386830ef7a826f235ffb804c59efbba \ + --hash=sha256:a6e587512f3c998b2225d68aa1f35111c29fad14aed561a26e73fab729ec5e5a # via pykwalify -ruamel-yaml-clib==0.2.14 ; python_full_version < '3.14' and platform_python_implementation == 'CPython' \ - --hash=sha256:090782b5fb9d98df96509eecdbcaffd037d47389a89492320280d52f91330d78 \ - --hash=sha256:0a54e5e40a7a691a426c2703b09b0d61a14294d25cfacc00631aa6f9c964df0d \ - --hash=sha256:10d9595b6a19778f3269399eff6bab642608e5966183abc2adbe558a42d4efc9 \ - --hash=sha256:16a60d69f4057ad9a92f3444e2367c08490daed6428291aa16cefb445c29b0e9 \ - --hash=sha256:18c041b28f3456ddef1f1951d4492dbebe0f8114157c1b3c981a4611c2020792 \ - --hash=sha256:1c1acc3a0209ea9042cc3cfc0790edd2eddd431a2ec3f8283d081e4d5018571e \ - --hash=sha256:1f118b707eece8cf84ecbc3e3ec94d9db879d85ed608f95870d39b2d2efa5dca \ - --hash=sha256:2070bf0ad1540d5c77a664de07ebcc45eebd1ddcab71a7a06f26936920692beb \ - --hash=sha256:26a8de280ab0d22b6e3ec745b4a5a07151a0f74aad92dd76ab9c8d8d7087720d \ - --hash=sha256:275f938692013a3883edbd848edde6d9f26825d65c9a2eb1db8baa1adc96a05d \ - --hash=sha256:27c070cf3888e90d992be75dd47292ff9aa17dafd36492812a6a304a1aedc182 \ - --hash=sha256:29757bdb7c142f9595cc1b62ec49a3d1c83fab9cef92db52b0ccebaad4eafb98 \ - --hash=sha256:4ccba93c1e5a40af45b2f08e4591969fa4697eae951c708f3f83dcbf9f6c6bb1 \ - --hash=sha256:4f4a150a737fccae13fb51234d41304ff2222e3b7d4c8e9428ed1a6ab48389b8 \ - --hash=sha256:557df28dbccf79b152fe2d1b935f6063d9cc431199ea2b0e84892f35c03bb0ee \ - --hash=sha256:5ac5ff9425d8acb8f59ac5b96bcb7fd3d272dc92d96a7c730025928ffcc88a7a \ - --hash=sha256:5bae1a073ca4244620425cd3d3aa9746bde590992b98ee8c7c8be8c597ca0d4e \ - --hash=sha256:5e56ac47260c0eed992789fa0b8efe43404a9adb608608631a948cee4fc2b052 \ - --hash=sha256:6aeadc170090ff1889f0d2c3057557f9cd71f975f17535c26a5d37af98f19c27 \ - --hash=sha256:6d5472f63a31b042aadf5ed28dd3ef0523da49ac17f0463e10fda9c4a2773352 \ - --hash=sha256:70eda7703b8126f5e52fcf276e6c0f40b0d314674f896fc58c47b0aef2b9ae83 \ - --hash=sha256:7df6f6e9d0e33c7b1d435defb185095386c469109de723d514142632a7b9d07f \ - --hash=sha256:7e4f9da7e7549946e02a6122dcad00b7c1168513acb1f8a726b1aaf504a99d32 \ - --hash=sha256:803f5044b13602d58ea378576dd75aa759f52116a0232608e8fdada4da33752e \ - --hash=sha256:808c7190a0fe7ae7014c42f73897cf8e9ef14ff3aa533450e51b1e72ec5239ad \ - --hash=sha256:81f6d3b19bc703679a5705c6a16dabdc79823c71d791d73c65949be7f3012c02 \ - --hash=sha256:83bbd8354f6abb3fdfb922d1ed47ad8d1db3ea72b0523dac8d07cdacfe1c0fcf \ - --hash=sha256:8dd3c2cc49caa7a8d64b67146462aed6723a0495e44bf0aa0a2e94beaa8432f6 \ - --hash=sha256:915748cfc25b8cfd81b14d00f4bfdb2ab227a30d6d43459034533f4d1c207a2a \ - --hash=sha256:94f3efb718f8f49b031f2071ec7a27dd20cbfe511b4dfd54ecee54c956da2b31 \ - --hash=sha256:9bd8fe07f49c170e09d76773fb86ad9135e0beee44f36e1576a201b0676d3d1d \ - --hash=sha256:9bf6b699223afe6c7fe9f2ef76e0bfa6dd892c21e94ce8c957478987ade76cd8 \ - --hash=sha256:a05ba88adf3d7189a974b2de7a9d56731548d35dc0a822ec3dc669caa7019b29 \ - --hash=sha256:a0ac90efbc7a77b0d796c03c8cc4e62fd710b3f1e4c32947713ef2ef52e09543 \ - --hash=sha256:a0cb71ccc6ef9ce36eecb6272c81afdc2f565950cdcec33ae8e6cd8f7fc86f27 \ - --hash=sha256:a37f40a859b503304dd740686359fcf541d6fb3ff7fc10f539af7f7150917c68 \ - --hash=sha256:a911aa73588d9a8b08d662b9484bc0567949529824a55d3885b77e8dd62a127a \ - --hash=sha256:aef953f3b8bd0b50bd52a2e52fb54a6a2171a1889d8dea4a5959d46c6624c451 \ - --hash=sha256:b28caeaf3e670c08cb7e8de221266df8494c169bd6ed8875493fab45be9607a4 \ - --hash=sha256:b30110b29484adc597df6bd92a37b90e63a8c152ca8136aad100a02f8ba6d1b6 \ - --hash=sha256:b5b0f7e294700b615a3bcf6d28b26e6da94e8eba63b079f4ec92e9ba6c0d6b54 \ - --hash=sha256:c099cafc1834d3c5dac305865d04235f7c21c167c8dd31ebc3d6bbc357e2f023 \ - --hash=sha256:d73a0187718f6eec5b2f729b0f98e4603f7bd9c48aa65d01227d1a5dcdfbe9e8 \ - --hash=sha256:d8354515ab62f95a07deaf7f845886cc50e2f345ceab240a3d2d09a9f7d77853 \ - --hash=sha256:dba72975485f2b87b786075e18a6e5d07dc2b4d8973beb2732b9b2816f1bad70 \ - --hash=sha256:dd7546c851e59c06197a7c651335755e74aa383a835878ca86d2c650c07a2f85 \ - --hash=sha256:df3ec9959241d07bc261f4983d25a1205ff37703faf42b474f15d54d88b4f8c9 \ - --hash=sha256:e1d1735d97fd8a48473af048739379975651fab186f8a25a9f683534e6904179 \ - --hash=sha256:e501c096aa3889133d674605ebd018471bc404a59cbc17da3c5924421c54d97c \ - --hash=sha256:e7cb9ad1d525d40f7d87b6df7c0ff916a66bc52cb61b66ac1b2a16d0c1b07640 \ - --hash=sha256:f4e97a1cf0b7a30af9e1d9dad10a5671157b9acee790d9e26996391f49b965a2 \ - --hash=sha256:f8b2acb0ffdd2ce8208accbec2dca4a06937d556fdcaefd6473ba1b5daa7e3c4 \ - --hash=sha256:fb04c5650de6668b853623eceadcdb1a9f2fee381f5d7b6bc842ee7c239eeec4 \ - --hash=sha256:fbc08c02e9b147a11dfcaa1ac8a83168b699863493e183f7c0c8b12850b7d259 \ - --hash=sha256:ff86876889ea478b1381089e55cf9e345707b312beda4986f823e1d95e8c0f59 +ruamel-yaml-clib==0.2.15 ; python_full_version < '3.14' and platform_python_implementation == 'CPython' \ + --hash=sha256:014181cdec565c8745b7cbc4de3bf2cc8ced05183d986e6d1200168e5bb59490 \ + --hash=sha256:04d21dc9c57d9608225da28285900762befbb0165ae48482c15d8d4989d4af14 \ + --hash=sha256:05c70f7f86be6f7bee53794d80050a28ae7e13e4a0087c1839dcdefd68eb36b6 \ + --hash=sha256:0ba6604bbc3dfcef844631932d06a1a4dcac3fee904efccf582261948431628a \ + --hash=sha256:11e5499db1ccbc7f4b41f0565e4f799d863ea720e01d3e99fa0b7b5fcd7802c9 \ + --hash=sha256:1b45498cc81a4724a2d42273d6cfc243c0547ad7c6b87b4f774cb7bcc131c98d \ + --hash=sha256:1bb7b728fd9f405aa00b4a0b17ba3f3b810d0ccc5f77f7373162e9b5f0ff75d5 \ + --hash=sha256:1f66f600833af58bea694d5892453f2270695b92200280ee8c625ec5a477eed3 \ + --hash=sha256:27dc656e84396e6d687f97c6e65fb284d100483628f02d95464fd731743a4afe \ + --hash=sha256:2812ff359ec1f30129b62372e5f22a52936fac13d5d21e70373dbca5d64bb97c \ + --hash=sha256:2b216904750889133d9222b7b873c199d48ecbb12912aca78970f84a5aa1a4bc \ + --hash=sha256:331fb180858dd8534f0e61aa243b944f25e73a4dae9962bd44c46d1761126bbf \ + --hash=sha256:3cb75a3c14f1d6c3c2a94631e362802f70e83e20d1f2b2ef3026c05b415c4900 \ + --hash=sha256:3eb199178b08956e5be6288ee0b05b2fb0b5c1f309725ad25d9c6ea7e27f962a \ + --hash=sha256:424ead8cef3939d690c4b5c85ef5b52155a231ff8b252961b6516ed7cf05f6aa \ + --hash=sha256:45702dfbea1420ba3450bb3dd9a80b33f0badd57539c6aac09f42584303e0db6 \ + --hash=sha256:468858e5cbde0198337e6a2a78eda8c3fb148bdf4c6498eaf4bc9ba3f8e780bd \ + --hash=sha256:46895c17ead5e22bea5e576f1db7e41cb273e8d062c04a6a49013d9f60996c25 \ + --hash=sha256:46e4cc8c43ef6a94885f72512094e482114a8a706d3c555a34ed4b0d20200600 \ + --hash=sha256:480894aee0b29752560a9de46c0e5f84a82602f2bc5c6cde8db9a345319acfdf \ + --hash=sha256:4b293a37dc97e2b1e8a1aec62792d1e52027087c8eea4fc7b5abd2bdafdd6642 \ + --hash=sha256:4be366220090d7c3424ac2b71c90d1044ea34fca8c0b88f250064fd06087e614 \ + --hash=sha256:4d1032919280ebc04a80e4fb1e93f7a738129857eaec9448310e638c8bccefcf \ + --hash=sha256:4d3b58ab2454b4747442ac76fab66739c72b1e2bb9bd173d7694b9f9dbc9c000 \ + --hash=sha256:4dcec721fddbb62e60c2801ba08c87010bd6b700054a09998c4d09c08147b8fb \ + --hash=sha256:512571ad41bba04eac7268fe33f7f4742210ca26a81fe0c75357fa682636c690 \ + --hash=sha256:542d77b72786a35563f97069b9379ce762944e67055bea293480f7734b2c7e5e \ + --hash=sha256:56ea19c157ed8c74b6be51b5fa1c3aff6e289a041575f0556f66e5fb848bb137 \ + --hash=sha256:5d3c9210219cbc0f22706f19b154c9a798ff65a6beeafbf77fc9c057ec806f7d \ + --hash=sha256:5fea0932358e18293407feb921d4f4457db837b67ec1837f87074667449f9401 \ + --hash=sha256:617d35dc765715fa86f8c3ccdae1e4229055832c452d4ec20856136acc75053f \ + --hash=sha256:64da03cbe93c1e91af133f5bec37fd24d0d4ba2418eaf970d7166b0a26a148a2 \ + --hash=sha256:65f48245279f9bb301d1276f9679b82e4c080a1ae25e679f682ac62446fac471 \ + --hash=sha256:6f1d38cbe622039d111b69e9ca945e7e3efebb30ba998867908773183357f3ed \ + --hash=sha256:713cd68af9dfbe0bb588e144a61aad8dcc00ef92a82d2e87183ca662d242f524 \ + --hash=sha256:71845d377c7a47afc6592aacfea738cc8a7e876d586dfba814501d8c53c1ba60 \ + --hash=sha256:753faf20b3a5906faf1fc50e4ddb8c074cb9b251e00b14c18b28492f933ac8ef \ + --hash=sha256:7e74ea87307303ba91073b63e67f2c667e93f05a8c63079ee5b7a5c8d0d7b043 \ + --hash=sha256:88eea8baf72f0ccf232c22124d122a7f26e8a24110a0273d9bcddcb0f7e1fa03 \ + --hash=sha256:923816815974425fbb1f1bf57e85eca6e14d8adc313c66db21c094927ad01815 \ + --hash=sha256:9b6f7d74d094d1f3a4e157278da97752f16ee230080ae331fcc219056ca54f77 \ + --hash=sha256:a8220fd4c6f98485e97aea65e1df76d4fed1678ede1fe1d0eed2957230d287c4 \ + --hash=sha256:ab0df0648d86a7ecbd9c632e8f8d6b21bb21b5fc9d9e095c796cacf32a728d2d \ + --hash=sha256:ac9b8d5fa4bb7fd2917ab5027f60d4234345fd366fe39aa711d5dca090aa1467 \ + --hash=sha256:badd1d7283f3e5894779a6ea8944cc765138b96804496c91812b2829f70e18a7 \ + --hash=sha256:bdc06ad71173b915167702f55d0f3f027fc61abd975bd308a0968c02db4a4c3e \ + --hash=sha256:bf0846d629e160223805db9fe8cc7aec16aaa11a07310c50c8c7164efa440aec \ + --hash=sha256:bfd309b316228acecfa30670c3887dcedf9b7a44ea39e2101e75d2654522acd4 \ + --hash=sha256:c583229f336682b7212a43d2fa32c30e643d3076178fb9f7a6a14dde85a2d8bd \ + --hash=sha256:cb15a2e2a90c8475df45c0949793af1ff413acfb0a716b8b94e488ea95ce7cff \ + --hash=sha256:d290eda8f6ada19e1771b54e5706b8f9807e6bb08e873900d5ba114ced13e02c \ + --hash=sha256:da3d6adadcf55a93c214d23941aef4abfd45652110aed6580e814152f385b862 \ + --hash=sha256:dcc7f3162d3711fd5d52e2267e44636e3e566d1e5675a5f0b30e98f2c4af7974 \ + --hash=sha256:def5663361f6771b18646620fca12968aae730132e104688766cf8a3b1d65922 \ + --hash=sha256:e5e9f630c73a490b758bf14d859a39f375e6999aea5ddd2e2e9da89b9953486a \ + --hash=sha256:e9fde97ecb7bb9c41261c2ce0da10323e9227555c674989f8d9eb7572fc2098d \ + --hash=sha256:ef71831bd61fbdb7aa0399d5c4da06bea37107ab5c79ff884cc07f2450910262 \ + --hash=sha256:f4421ab780c37210a07d138e56dd4b51f8642187cdfb433eb687fe8c11de0144 \ + --hash=sha256:f6d3655e95a80325b84c4e14c080b2470fe4f33b6846f288379ce36154993fb1 \ + --hash=sha256:fd4c928ddf6bce586285daa6d90680b9c291cfd045fc40aad34e445d57b1bf51 \ + --hash=sha256:fe239bdfdae2302e93bd6e8264bd9b71290218fff7084a9db250b55caaccf43f # via ruamel-yaml ruff==0.14.2 \ --hash=sha256:0df3424aa5c3c08b34ed8ce099df1021e3adaca6e90229273496b839e5a7e1af \ @@ -1422,9 +1514,9 @@ ruff==0.14.2 \ --hash=sha256:e681c5bc777de5af898decdcb6ba3321d0d466f4cb43c3e7cc2c3b4e7b843a05 \ --hash=sha256:ea9d635e83ba21569fbacda7e78afbfeb94911c9434aff06192d9bc23fd5495a # via -r requirements-actions.in -s3transfer==0.14.0 \ - --hash=sha256:ea3b790c7077558ed1f02a3072fb3cb992bbbd253392f4b6e9e8976941c7d456 \ - --hash=sha256:eff12264e7c8b4985074ccce27a3b38a485bb7f7422cc8046fee9be4983e4125 +s3transfer==0.16.0 \ + --hash=sha256:18e25d66fed509e3868dc1572b3f427ff947dd2c56f844a5bf09481ad3f3b2fe \ + --hash=sha256:8e990f13268025792229cd52fa10cb7163744bf56e719e0b9cb925ab79abf920 # via awscli semantic-version==2.10.0 \ --hash=sha256:bdabb6d336998cbb378d4b9db3a4b56a1e3235701dc05ea2690d9a997ed5041c \ @@ -1450,47 +1542,57 @@ spdx-tools==0.8.3 \ --hash=sha256:638fd9bd8be61901316eb6d063574e16d5403a1870073ec4d9241426a997501a \ --hash=sha256:68b8f9ce2893b5216bd90b2e63f1c821c2884e4ebc4fd295ebbf1fa8b8a94b93 # via -r requirements-actions.in -sphinx-lint==1.0.0 \ - --hash=sha256:6117a0f340b2dc73eadfc57db7531d4477e0929f92a0c1a2f61e6edbc272f0bc \ - --hash=sha256:6eafdb44172ce526f405bf36c713eb246f1340ec2d667e7298e2487ed76decd2 +sphinx-lint==1.0.2 \ + --hash=sha256:4e7fc12f44f750b0006eaad237d7db9b1d8aba92adda9c838af891654b371d35 \ + --hash=sha256:edcd0fa4d916386c5a3ef7ef0f5136f0bb4a15feefc83c1068ba15bc16eec652 # via -r requirements-actions.in tabulate==0.9.0 \ --hash=sha256:0095b12bf5966de529c0feb1fa08671671b3368eec77d7ef7ab114be2c068b3c \ --hash=sha256:024ca478df22e9340661486f85298cff5f6dcdba14f3813e8830015b9ed1948f # via -r requirements-actions.in -tomli==2.2.1 ; python_full_version < '3.11' \ - --hash=sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6 \ - --hash=sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd \ - --hash=sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c \ - --hash=sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b \ - --hash=sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8 \ - --hash=sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6 \ - --hash=sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77 \ - --hash=sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff \ - --hash=sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea \ - --hash=sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192 \ - --hash=sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249 \ - --hash=sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee \ - --hash=sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4 \ - --hash=sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98 \ - --hash=sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8 \ - --hash=sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4 \ - --hash=sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281 \ - --hash=sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744 \ - --hash=sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69 \ - --hash=sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13 \ - --hash=sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140 \ - --hash=sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e \ - --hash=sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e \ - --hash=sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc \ - --hash=sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff \ - --hash=sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec \ - --hash=sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2 \ - --hash=sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222 \ - --hash=sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106 \ - --hash=sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272 \ - --hash=sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a \ - --hash=sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7 +tomli==2.3.0 ; python_full_version < '3.11' \ + --hash=sha256:00b5f5d95bbfc7d12f91ad8c593a1659b6387b43f054104cda404be6bda62456 \ + --hash=sha256:0a154a9ae14bfcf5d8917a59b51ffd5a3ac1fd149b71b47a3a104ca4edcfa845 \ + --hash=sha256:0c95ca56fbe89e065c6ead5b593ee64b84a26fca063b5d71a1122bf26e533999 \ + --hash=sha256:0eea8cc5c5e9f89c9b90c4896a8deefc74f518db5927d0e0e8d4a80953d774d0 \ + --hash=sha256:1cb4ed918939151a03f33d4242ccd0aa5f11b3547d0cf30f7c74a408a5b99878 \ + --hash=sha256:4021923f97266babc6ccab9f5068642a0095faa0a51a246a6a02fccbb3514eaf \ + --hash=sha256:4c2ef0244c75aba9355561272009d934953817c49f47d768070c3c94355c2aa3 \ + --hash=sha256:4dc4ce8483a5d429ab602f111a93a6ab1ed425eae3122032db7e9acf449451be \ + --hash=sha256:4f195fe57ecceac95a66a75ac24d9d5fbc98ef0962e09b2eddec5d39375aae52 \ + --hash=sha256:5192f562738228945d7b13d4930baffda67b69425a7f0da96d360b0a3888136b \ + --hash=sha256:5e01decd096b1530d97d5d85cb4dff4af2d8347bd35686654a004f8dea20fc67 \ + --hash=sha256:64be704a875d2a59753d80ee8a533c3fe183e3f06807ff7dc2232938ccb01549 \ + --hash=sha256:70a251f8d4ba2d9ac2542eecf008b3c8a9fc5c3f9f02c56a9d7952612be2fdba \ + --hash=sha256:73ee0b47d4dad1c5e996e3cd33b8a76a50167ae5f96a2607cbe8cc773506ab22 \ + --hash=sha256:74bf8464ff93e413514fefd2be591c3b0b23231a77f901db1eb30d6f712fc42c \ + --hash=sha256:792262b94d5d0a466afb5bc63c7daa9d75520110971ee269152083270998316f \ + --hash=sha256:7b0882799624980785240ab732537fcfc372601015c00f7fc367c55308c186f6 \ + --hash=sha256:883b1c0d6398a6a9d29b508c331fa56adbcdff647f6ace4dfca0f50e90dfd0ba \ + --hash=sha256:88bd15eb972f3664f5ed4b57c1634a97153b4bac4479dcb6a495f41921eb7f45 \ + --hash=sha256:8a35dd0e643bb2610f156cca8db95d213a90015c11fee76c946aa62b7ae7e02f \ + --hash=sha256:940d56ee0410fa17ee1f12b817b37a4d4e4dc4d27340863cc67236c74f582e77 \ + --hash=sha256:97d5eec30149fd3294270e889b4234023f2c69747e555a27bd708828353ab606 \ + --hash=sha256:a0e285d2649b78c0d9027570d4da3425bdb49830a6156121360b3f8511ea3441 \ + --hash=sha256:a1f7f282fe248311650081faafa5f4732bdbfef5d45fe3f2e702fbc6f2d496e0 \ + --hash=sha256:a4ea38c40145a357d513bffad0ed869f13c1773716cf71ccaa83b0fa0cc4e42f \ + --hash=sha256:a56212bdcce682e56b0aaf79e869ba5d15a6163f88d5451cbde388d48b13f530 \ + --hash=sha256:ad805ea85eda330dbad64c7ea7a4556259665bdf9d2672f5dccc740eb9d3ca05 \ + --hash=sha256:b273fcbd7fc64dc3600c098e39136522650c49bca95df2d11cf3b626422392c8 \ + --hash=sha256:b5870b50c9db823c595983571d1296a6ff3e1b88f734a4c8f6fc6188397de005 \ + --hash=sha256:b74a0e59ec5d15127acdabd75ea17726ac4c5178ae51b85bfe39c4f8a278e879 \ + --hash=sha256:be71c93a63d738597996be9528f4abe628d1adf5e6eb11607bc8fe1a510b5dae \ + --hash=sha256:c22a8bf253bacc0cf11f35ad9808b6cb75ada2631c2d97c971122583b129afbc \ + --hash=sha256:c4665508bcbac83a31ff8ab08f424b665200c0e1e645d2bd9ab3d3e557b6185b \ + --hash=sha256:c5f3ffd1e098dfc032d4d3af5c0ac64f6d286d98bc148698356847b80fa4de1b \ + --hash=sha256:cebc6fe843e0733ee827a282aca4999b596241195f43b4cc371d64fc6639da9e \ + --hash=sha256:d1381caf13ab9f300e30dd8feadb3de072aeb86f1d34a8569453ff32a7dea4bf \ + --hash=sha256:d7d86942e56ded512a594786a5ba0a5e521d02529b3826e7761a05138341a2ac \ + --hash=sha256:e31d432427dcbf4d86958c184b9bfd1e96b5b71f8eb17e6d02531f434fd335b8 \ + --hash=sha256:e95b1af3c5b07d9e643909b5abbec77cd9f1217e6d0bca72b0234736b9fb1f1b \ + --hash=sha256:f85209946d1fe94416debbb88d00eb92ce9cd5266775424ff81bc959e001acaf \ + --hash=sha256:feb0dacc61170ed7ab602d3d972a58f14ee3ee60494292d384649a3dc38ef463 \ + --hash=sha256:ff72b71b5d10d22ecb084d345fc26f42b5143c5533db5e2eaba7d2d335358876 # via # mypy # pylint @@ -1503,18 +1605,14 @@ tomlkit==0.13.3 \ # via # pylint # reuse -tox==4.30.2 \ - --hash=sha256:772925ad6c57fe35c7ed5ac3e958ac5ced21dff597e76fc40c1f5bf3cd1b6a2e \ - --hash=sha256:efd261a42e8c82a59f9026320a80a067f27f44cad2e72a6712010c311d31176b +tox==4.32.0 \ + --hash=sha256:1ad476b5f4d3679455b89a992849ffc3367560bbc7e9495ee8a3963542e7c8ff \ + --hash=sha256:451e81dc02ba8d1ed20efd52ee409641ae4b5d5830e008af10fe8823ef1bd551 # via -r requirements-actions.in tqdm==4.67.1 \ --hash=sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2 \ --hash=sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2 # via -r requirements-actions.in -types-python-dateutil==2.9.0.20250822 \ - --hash=sha256:849d52b737e10a6dc6621d2bd7940ec7c65fcb69e6aa2882acf4e56b2b508ddc \ - --hash=sha256:84c92c34bd8e68b117bff742bc00b692a1e8531262d4507b33afcc9f7716cd53 - # via arrow typing-extensions==4.15.0 \ --hash=sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466 \ --hash=sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548 @@ -1529,6 +1627,10 @@ typing-extensions==4.15.0 \ # referencing # tox # virtualenv +tzdata==2025.2 \ + --hash=sha256:1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8 \ + --hash=sha256:b60a638fcc0daffadf82fe0f57e53d06bdec2f36c4df66280ae79bce6bd6f2b9 + # via arrow unidiff==0.7.5 \ --hash=sha256:2e5f0162052248946b9f0970a40e9e124236bf86c82b70821143a6fc1dea2574 \ --hash=sha256:c93bf2265cc1ba2a520e415ab05da587370bc2a3ae9e0414329f54f0c2fc09e8 @@ -1537,9 +1639,9 @@ uritools==5.0.0 \ --hash=sha256:68180cad154062bd5b5d9ffcdd464f8de6934414b25462ae807b00b8df9345de \ --hash=sha256:cead3a49ba8fbca3f91857343849d506d8639718f4a2e51b62e87393b493bd6f # via spdx-tools -urllib3==2.5.0 \ - --hash=sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760 \ - --hash=sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc +urllib3==2.6.1 \ + --hash=sha256:5379eb6e1aba4088bae84f8242960017ec8d8e3decf30480b3a1abdaa9671a3f \ + --hash=sha256:e67d06fe947c36a7ca39f4994b08d73922d40e6cca949907be05efa6fd75110b # via # botocore # elastic-transport @@ -1549,9 +1651,9 @@ vermin==1.8.0 \ --hash=sha256:3621955ac2a2950175c5b4a9b2fc3bd24bd416da0388893c9eb6971264e4ca1f \ --hash=sha256:6f2b98ad697a16ed3442e81a0f0baabfc38c185b78aaab1b1fecd87bdd6640b8 # via -r requirements-actions.in -virtualenv==20.34.0 \ - --hash=sha256:341f5afa7eee943e4984a9207c025feedd768baff6753cd660c857ceb3e36026 \ - --hash=sha256:44815b2c9dee7ed86e387b842a84f20b93f7f417f95886ca1996a72a4138eb1a +virtualenv==20.35.4 \ + --hash=sha256:643d3914d73d3eeb0c552cbb12d7e82adf0e504dbf86a3182f8771a153a1971c \ + --hash=sha256:c21c9cede36c9753eeade68ba7d523529f228a403463376cf821eaae2b650f1b # via tox west==1.5.0 \ --hash=sha256:7088fe0e9afe0719ebee95c51c529149f7bcfc919d83a8206d35fa9c683ed0a5 \ From a297a65e6055ecfd7f67ad08810099c3cf4d0c83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Tue, 9 Dec 2025 11:34:08 +0100 Subject: [PATCH 0011/3659] doc: ci: refresh requirements.txt pinned versions and SHAs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This ensures, we pick a `urllib` version >2.6.0. See: - CVE-2025-66418 High severity - CVE-2025-66471 High severity Signed-off-by: Benjamin Cabé --- doc/requirements.txt | 629 +++++++++++++++++++++++++++---------------- 1 file changed, 402 insertions(+), 227 deletions(-) diff --git a/doc/requirements.txt b/doc/requirements.txt index 98940ca47d53..f5e7c5bca2a4 100644 --- a/doc/requirements.txt +++ b/doc/requirements.txt @@ -4,9 +4,9 @@ alabaster==1.0.0 \ --hash=sha256:c00dca57bca26fa62a6d7d0a9fcce65f3e026e9bfe33e9c538fd3fbb2144fd9e \ --hash=sha256:fc6786402dc3fcb2de3cabd5fe455a2db534b371124f1f21de8731783dec828b # via sphinx -anyio==4.11.0 \ - --hash=sha256:0287e96f4d26d4149305414d4e3bc32f0dcd0862365a4bddea19d7a1ec38c4fc \ - --hash=sha256:82a8d0b81e318cc5ce71a5f1f8b5c4e63619620b63141ef8c995fa0db95a57c4 +anyio==4.12.0 \ + --hash=sha256:73c693b567b0c55130c104d0b43a9baf3aa6a31fc6110116509f27bf75e21ec0 \ + --hash=sha256:dad2376a628f98eeca4881fc56cd06affd18f659b17a747d3ff0307ced94b1bb # via # starlette # watchfiles @@ -18,94 +18,128 @@ babel==2.17.0 \ --hash=sha256:0c54cffb19f690cdcc52a3b50bcbf71e07a808d1c80d549f2459b9d2cf0afb9d \ --hash=sha256:4d0b53093fdfb4b21c92b5213dba5a1b23885afa8383709427046b21c366e5f2 # via sphinx -certifi==2025.8.3 \ - --hash=sha256:e564105f78ded564e3ae7c923924435e1daa7463faeab5bb932bc53ffae63407 \ - --hash=sha256:f6c12493cfb1b06ba2ff328595af9350c65d6644968e5d3a2ffd78699af217a5 +certifi==2025.11.12 \ + --hash=sha256:97de8790030bbd5c2d96b7ec782fc2f7820ef8dba6db909ccf95449f2d062d4b \ + --hash=sha256:d8ab5478f2ecd78af242878415affce761ca6bc54a22a27e026d7c25357c3316 # via requests -charset-normalizer==3.4.3 \ - --hash=sha256:00237675befef519d9af72169d8604a067d92755e84fe76492fef5441db05b91 \ - --hash=sha256:02425242e96bcf29a49711b0ca9f37e451da7c70562bc10e8ed992a5a7a25cc0 \ - --hash=sha256:027b776c26d38b7f15b26a5da1044f376455fb3766df8fc38563b4efbc515154 \ - --hash=sha256:07a0eae9e2787b586e129fdcbe1af6997f8d0e5abaa0bc98c0e20e124d67e601 \ - --hash=sha256:0cacf8f7297b0c4fcb74227692ca46b4a5852f8f4f24b3c766dd94a1075c4884 \ - --hash=sha256:0e78314bdc32fa80696f72fa16dc61168fda4d6a0c014e0380f9d02f0e5d8a07 \ - --hash=sha256:0f2be7e0cf7754b9a30eb01f4295cc3d4358a479843b31f328afd210e2c7598c \ - --hash=sha256:13faeacfe61784e2559e690fc53fa4c5ae97c6fcedb8eb6fb8d0a15b475d2c64 \ - --hash=sha256:14c2a87c65b351109f6abfc424cab3927b3bdece6f706e4d12faaf3d52ee5efe \ - --hash=sha256:1606f4a55c0fd363d754049cdf400175ee96c992b1f8018b993941f221221c5f \ - --hash=sha256:16a8770207946ac75703458e2c743631c79c59c5890c80011d536248f8eaa432 \ - --hash=sha256:18343b2d246dc6761a249ba1fb13f9ee9a2bcd95decc767319506056ea4ad4dc \ - --hash=sha256:18b97b8404387b96cdbd30ad660f6407799126d26a39ca65729162fd810a99aa \ - --hash=sha256:1bb60174149316da1c35fa5233681f7c0f9f514509b8e399ab70fea5f17e45c9 \ - --hash=sha256:1e8ac75d72fa3775e0b7cb7e4629cec13b7514d928d15ef8ea06bca03ef01cae \ - --hash=sha256:1ef99f0456d3d46a50945c98de1774da86f8e992ab5c77865ea8b8195341fc19 \ - --hash=sha256:2001a39612b241dae17b4687898843f254f8748b796a2e16f1051a17078d991d \ - --hash=sha256:23b6b24d74478dc833444cbd927c338349d6ae852ba53a0d02a2de1fce45b96e \ - --hash=sha256:252098c8c7a873e17dd696ed98bbe91dbacd571da4b87df3736768efa7a792e4 \ - --hash=sha256:257f26fed7d7ff59921b78244f3cd93ed2af1800ff048c33f624c87475819dd7 \ - --hash=sha256:2c322db9c8c89009a990ef07c3bcc9f011a3269bc06782f916cd3d9eed7c9312 \ - --hash=sha256:30a96e1e1f865f78b030d65241c1ee850cdf422d869e9028e2fc1d5e4db73b92 \ - --hash=sha256:30d006f98569de3459c2fc1f2acde170b7b2bd265dc1943e87e1a4efe1b67c31 \ - --hash=sha256:31a9a6f775f9bcd865d88ee350f0ffb0e25936a7f930ca98995c05abf1faf21c \ - --hash=sha256:320e8e66157cc4e247d9ddca8e21f427efc7a04bbd0ac8a9faf56583fa543f9f \ - --hash=sha256:34a7f768e3f985abdb42841e20e17b330ad3aaf4bb7e7aeeb73db2e70f077b99 \ - --hash=sha256:3653fad4fe3ed447a596ae8638b437f827234f01a8cd801842e43f3d0a6b281b \ - --hash=sha256:3cd35b7e8aedeb9e34c41385fda4f73ba609e561faedfae0a9e75e44ac558a15 \ - --hash=sha256:3cfb2aad70f2c6debfbcb717f23b7eb55febc0bb23dcffc0f076009da10c6392 \ - --hash=sha256:416175faf02e4b0810f1f38bcb54682878a4af94059a1cd63b8747244420801f \ - --hash=sha256:41d1fc408ff5fdfb910200ec0e74abc40387bccb3252f3f27c0676731df2b2c8 \ - --hash=sha256:42e5088973e56e31e4fa58eb6bd709e42fc03799c11c42929592889a2e54c491 \ - --hash=sha256:4ca4c094de7771a98d7fbd67d9e5dbf1eb73efa4f744a730437d8a3a5cf994f0 \ - --hash=sha256:511729f456829ef86ac41ca78c63a5cb55240ed23b4b737faca0eb1abb1c41bc \ - --hash=sha256:53cd68b185d98dde4ad8990e56a58dea83a4162161b1ea9272e5c9182ce415e0 \ - --hash=sha256:585f3b2a80fbd26b048a0be90c5aae8f06605d3c92615911c3a2b03a8a3b796f \ - --hash=sha256:5b413b0b1bfd94dbf4023ad6945889f374cd24e3f62de58d6bb102c4d9ae534a \ - --hash=sha256:5d8d01eac18c423815ed4f4a2ec3b439d654e55ee4ad610e153cf02faf67ea40 \ - --hash=sha256:6aab0f181c486f973bc7262a97f5aca3ee7e1437011ef0c2ec04b5a11d16c927 \ - --hash=sha256:6cf8fd4c04756b6b60146d98cd8a77d0cdae0e1ca20329da2ac85eed779b6849 \ - --hash=sha256:6fb70de56f1859a3f71261cbe41005f56a7842cc348d3aeb26237560bfa5e0ce \ - --hash=sha256:6fce4b8500244f6fcb71465d4a4930d132ba9ab8e71a7859e6a5d59851068d14 \ - --hash=sha256:70bfc5f2c318afece2f5838ea5e4c3febada0be750fcf4775641052bbba14d05 \ - --hash=sha256:73dc19b562516fc9bcf6e5d6e596df0b4eb98d87e4f79f3ae71840e6ed21361c \ - --hash=sha256:74d77e25adda8581ffc1c720f1c81ca082921329452eba58b16233ab1842141c \ - --hash=sha256:78deba4d8f9590fe4dae384aeff04082510a709957e968753ff3c48399f6f92a \ - --hash=sha256:86df271bf921c2ee3818f0522e9a5b8092ca2ad8b065ece5d7d9d0e9f4849bcc \ - --hash=sha256:88ab34806dea0671532d3f82d82b85e8fc23d7b2dd12fa837978dad9bb392a34 \ - --hash=sha256:8999f965f922ae054125286faf9f11bc6932184b93011d138925a1773830bbe9 \ - --hash=sha256:8dcfc373f888e4fb39a7bc57e93e3b845e7f462dacc008d9749568b1c4ece096 \ - --hash=sha256:939578d9d8fd4299220161fdd76e86c6a251987476f5243e8864a7844476ba14 \ - --hash=sha256:96b2b3d1a83ad55310de8c7b4a2d04d9277d5591f40761274856635acc5fcb30 \ - --hash=sha256:a2d08ac246bb48479170408d6c19f6385fa743e7157d716e144cad849b2dd94b \ - --hash=sha256:b256ee2e749283ef3ddcff51a675ff43798d92d746d1a6e4631bf8c707d22d0b \ - --hash=sha256:b5e3b2d152e74e100a9e9573837aba24aab611d39428ded46f4e4022ea7d1942 \ - --hash=sha256:b89bc04de1d83006373429975f8ef9e7932534b8cc9ca582e4db7d20d91816db \ - --hash=sha256:bd28b817ea8c70215401f657edef3a8aa83c29d447fb0b622c35403780ba11d5 \ - --hash=sha256:c60e092517a73c632ec38e290eba714e9627abe9d301c8c8a12ec32c314a2a4b \ - --hash=sha256:c6dbd0ccdda3a2ba7c2ecd9d77b37f3b5831687d8dc1b6ca5f56a4880cc7b7ce \ - --hash=sha256:c6e490913a46fa054e03699c70019ab869e990270597018cef1d8562132c2669 \ - --hash=sha256:c6f162aabe9a91a309510d74eeb6507fab5fff92337a15acbe77753d88d9dcf0 \ - --hash=sha256:c6fd51128a41297f5409deab284fecbe5305ebd7e5a1f959bee1c054622b7018 \ - --hash=sha256:cc34f233c9e71701040d772aa7490318673aa7164a0efe3172b2981218c26d93 \ - --hash=sha256:cc9370a2da1ac13f0153780040f465839e6cccb4a1e44810124b4e22483c93fe \ - --hash=sha256:ccf600859c183d70eb47e05a44cd80a4ce77394d1ac0f79dbd2dd90a69a3a049 \ - --hash=sha256:ce571ab16d890d23b5c278547ba694193a45011ff86a9162a71307ed9f86759a \ - --hash=sha256:cf1ebb7d78e1ad8ec2a8c4732c7be2e736f6e5123a4146c5b89c9d1f585f8cef \ - --hash=sha256:d0e909868420b7049dafd3a31d45125b31143eec59235311fc4c57ea26a4acd2 \ - --hash=sha256:d22dbedd33326a4a5190dd4fe9e9e693ef12160c77382d9e87919bce54f3d4ca \ - --hash=sha256:d716a916938e03231e86e43782ca7878fb602a125a91e7acb8b5112e2e96ac16 \ - --hash=sha256:d79c198e27580c8e958906f803e63cddb77653731be08851c7df0b1a14a8fc0f \ - --hash=sha256:d95bfb53c211b57198bb91c46dd5a2d8018b3af446583aab40074bf7988401cb \ - --hash=sha256:e28e334d3ff134e88989d90ba04b47d84382a828c061d0d1027b1b12a62b39b1 \ - --hash=sha256:ec557499516fc90fd374bf2e32349a2887a876fbf162c160e3c01b6849eaf557 \ - --hash=sha256:fb6fecfd65564f208cbf0fba07f107fb661bcd1a7c389edbced3f7a493f70e37 \ - --hash=sha256:fb731e5deb0c7ef82d698b0f4c5bb724633ee2a489401594c5c88b02e6cb15f7 \ - --hash=sha256:fb7f67a1bfa6e40b438170ebdc8158b78dc465a5a67b6dde178a46987b244a72 \ - --hash=sha256:fd10de089bcdcd1be95a2f73dbe6254798ec1bda9f450d5828c96f93e2536b9c \ - --hash=sha256:fdabf8315679312cfa71302f9bd509ded4f2f263fb5b765cf1433b39106c3cc9 +charset-normalizer==3.4.4 \ + --hash=sha256:027f6de494925c0ab2a55eab46ae5129951638a49a34d87f4c3eda90f696b4ad \ + --hash=sha256:077fbb858e903c73f6c9db43374fd213b0b6a778106bc7032446a8e8b5b38b93 \ + --hash=sha256:0a98e6759f854bd25a58a73fa88833fba3b7c491169f86ce1180c948ab3fd394 \ + --hash=sha256:0d3d8f15c07f86e9ff82319b3d9ef6f4bf907608f53fe9d92b28ea9ae3d1fd89 \ + --hash=sha256:0f04b14ffe5fdc8c4933862d8306109a2c51e0704acfa35d51598eb45a1e89fc \ + --hash=sha256:11d694519d7f29d6cd09f6ac70028dba10f92f6cdd059096db198c283794ac86 \ + --hash=sha256:194f08cbb32dc406d6e1aea671a68be0823673db2832b38405deba2fb0d88f63 \ + --hash=sha256:1bee1e43c28aa63cb16e5c14e582580546b08e535299b8b6158a7c9c768a1f3d \ + --hash=sha256:21d142cc6c0ec30d2efee5068ca36c128a30b0f2c53c1c07bd78cb6bc1d3be5f \ + --hash=sha256:2437418e20515acec67d86e12bf70056a33abdacb5cb1655042f6538d6b085a8 \ + --hash=sha256:244bfb999c71b35de57821b8ea746b24e863398194a4014e4c76adc2bbdfeff0 \ + --hash=sha256:2677acec1a2f8ef614c6888b5b4ae4060cc184174a938ed4e8ef690e15d3e505 \ + --hash=sha256:277e970e750505ed74c832b4bf75dac7476262ee2a013f5574dd49075879e161 \ + --hash=sha256:2aaba3b0819274cc41757a1da876f810a3e4d7b6eb25699253a4effef9e8e4af \ + --hash=sha256:2b7d8f6c26245217bd2ad053761201e9f9680f8ce52f0fcd8d0755aeae5b2152 \ + --hash=sha256:2c9d3c380143a1fedbff95a312aa798578371eb29da42106a29019368a475318 \ + --hash=sha256:3162d5d8ce1bb98dd51af660f2121c55d0fa541b46dff7bb9b9f86ea1d87de72 \ + --hash=sha256:31fd66405eaf47bb62e8cd575dc621c56c668f27d46a61d975a249930dd5e2a4 \ + --hash=sha256:362d61fd13843997c1c446760ef36f240cf81d3ebf74ac62652aebaf7838561e \ + --hash=sha256:376bec83a63b8021bb5c8ea75e21c4ccb86e7e45ca4eb81146091b56599b80c3 \ + --hash=sha256:44c2a8734b333e0578090c4cd6b16f275e07aa6614ca8715e6c038e865e70576 \ + --hash=sha256:47cc91b2f4dd2833fddaedd2893006b0106129d4b94fdb6af1f4ce5a9965577c \ + --hash=sha256:4902828217069c3c5c71094537a8e623f5d097858ac6ca8252f7b4d10b7560f1 \ + --hash=sha256:4bd5d4137d500351a30687c2d3971758aac9a19208fc110ccb9d7188fbe709e8 \ + --hash=sha256:4fe7859a4e3e8457458e2ff592f15ccb02f3da787fcd31e0183879c3ad4692a1 \ + --hash=sha256:542d2cee80be6f80247095cc36c418f7bddd14f4a6de45af91dfad36d817bba2 \ + --hash=sha256:554af85e960429cf30784dd47447d5125aaa3b99a6f0683589dbd27e2f45da44 \ + --hash=sha256:5833d2c39d8896e4e19b689ffc198f08ea58116bee26dea51e362ecc7cd3ed26 \ + --hash=sha256:5947809c8a2417be3267efc979c47d76a079758166f7d43ef5ae8e9f92751f88 \ + --hash=sha256:5ae497466c7901d54b639cf42d5b8c1b6a4fead55215500d2f486d34db48d016 \ + --hash=sha256:5bd2293095d766545ec1a8f612559f6b40abc0eb18bb2f5d1171872d34036ede \ + --hash=sha256:5bfbb1b9acf3334612667b61bd3002196fe2a1eb4dd74d247e0f2a4d50ec9bbf \ + --hash=sha256:5cb4d72eea50c8868f5288b7f7f33ed276118325c1dfd3957089f6b519e1382a \ + --hash=sha256:5dbe56a36425d26d6cfb40ce79c314a2e4dd6211d51d6d2191c00bed34f354cc \ + --hash=sha256:5f819d5fe9234f9f82d75bdfa9aef3a3d72c4d24a6e57aeaebba32a704553aa0 \ + --hash=sha256:64b55f9dce520635f018f907ff1b0df1fdc31f2795a922fb49dd14fbcdf48c84 \ + --hash=sha256:6515f3182dbe4ea06ced2d9e8666d97b46ef4c75e326b79bb624110f122551db \ + --hash=sha256:65e2befcd84bc6f37095f5961e68a6f077bf44946771354a28ad434c2cce0ae1 \ + --hash=sha256:6aee717dcfead04c6eb1ce3bd29ac1e22663cdea57f943c87d1eab9a025438d7 \ + --hash=sha256:6b39f987ae8ccdf0d2642338faf2abb1862340facc796048b604ef14919e55ed \ + --hash=sha256:6e1fcf0720908f200cd21aa4e6750a48ff6ce4afe7ff5a79a90d5ed8a08296f8 \ + --hash=sha256:74018750915ee7ad843a774364e13a3db91682f26142baddf775342c3f5b1133 \ + --hash=sha256:74664978bb272435107de04e36db5a9735e78232b85b77d45cfb38f758efd33e \ + --hash=sha256:74bb723680f9f7a6234dcf67aea57e708ec1fbdf5699fb91dfd6f511b0a320ef \ + --hash=sha256:752944c7ffbfdd10c074dc58ec2d5a8a4cd9493b314d367c14d24c17684ddd14 \ + --hash=sha256:778d2e08eda00f4256d7f672ca9fef386071c9202f5e4607920b86d7803387f2 \ + --hash=sha256:780236ac706e66881f3b7f2f32dfe90507a09e67d1d454c762cf642e6e1586e0 \ + --hash=sha256:798d75d81754988d2565bff1b97ba5a44411867c0cf32b77a7e8f8d84796b10d \ + --hash=sha256:799a7a5e4fb2d5898c60b640fd4981d6a25f1c11790935a44ce38c54e985f828 \ + --hash=sha256:7a32c560861a02ff789ad905a2fe94e3f840803362c84fecf1851cb4cf3dc37f \ + --hash=sha256:7c308f7e26e4363d79df40ca5b2be1c6ba9f02bdbccfed5abddb7859a6ce72cf \ + --hash=sha256:7fa17817dc5625de8a027cb8b26d9fefa3ea28c8253929b8d6649e705d2835b6 \ + --hash=sha256:81d5eb2a312700f4ecaa977a8235b634ce853200e828fbadf3a9c50bab278328 \ + --hash=sha256:82004af6c302b5d3ab2cfc4cc5f29db16123b1a8417f2e25f9066f91d4411090 \ + --hash=sha256:837c2ce8c5a65a2035be9b3569c684358dfbf109fd3b6969630a87535495ceaa \ + --hash=sha256:840c25fb618a231545cbab0564a799f101b63b9901f2569faecd6b222ac72381 \ + --hash=sha256:8a6562c3700cce886c5be75ade4a5db4214fda19fede41d9792d100288d8f94c \ + --hash=sha256:8af65f14dc14a79b924524b1e7fffe304517b2bff5a58bf64f30b98bbc5079eb \ + --hash=sha256:8ef3c867360f88ac904fd3f5e1f902f13307af9052646963ee08ff4f131adafc \ + --hash=sha256:94537985111c35f28720e43603b8e7b43a6ecfb2ce1d3058bbe955b73404e21a \ + --hash=sha256:99ae2cffebb06e6c22bdc25801d7b30f503cc87dbd283479e7b606f70aff57ec \ + --hash=sha256:9a26f18905b8dd5d685d6d07b0cdf98a79f3c7a918906af7cc143ea2e164c8bc \ + --hash=sha256:9b35f4c90079ff2e2edc5b26c0c77925e5d2d255c42c74fdb70fb49b172726ac \ + --hash=sha256:9cd98cdc06614a2f768d2b7286d66805f94c48cde050acdbbb7db2600ab3197e \ + --hash=sha256:9d1bb833febdff5c8927f922386db610b49db6e0d4f4ee29601d71e7c2694313 \ + --hash=sha256:9f7fcd74d410a36883701fafa2482a6af2ff5ba96b9a620e9e0721e28ead5569 \ + --hash=sha256:a59cb51917aa591b1c4e6a43c132f0cdc3c76dbad6155df4e28ee626cc77a0a3 \ + --hash=sha256:a61900df84c667873b292c3de315a786dd8dac506704dea57bc957bd31e22c7d \ + --hash=sha256:a79cfe37875f822425b89a82333404539ae63dbdddf97f84dcbc3d339aae9525 \ + --hash=sha256:a8a8b89589086a25749f471e6a900d3f662d1d3b6e2e59dcecf787b1cc3a1894 \ + --hash=sha256:a8bf8d0f749c5757af2142fe7903a9df1d2e8aa3841559b2bad34b08d0e2bcf3 \ + --hash=sha256:a9768c477b9d7bd54bc0c86dbaebdec6f03306675526c9927c0e8a04e8f94af9 \ + --hash=sha256:ac1c4a689edcc530fc9d9aa11f5774b9e2f33f9a0c6a57864e90908f5208d30a \ + --hash=sha256:af2d8c67d8e573d6de5bc30cdb27e9b95e49115cd9baad5ddbd1a6207aaa82a9 \ + --hash=sha256:b435cba5f4f750aa6c0a0d92c541fb79f69a387c91e61f1795227e4ed9cece14 \ + --hash=sha256:b5b290ccc2a263e8d185130284f8501e3e36c5e02750fc6b6bdeb2e9e96f1e25 \ + --hash=sha256:b5d84d37db046c5ca74ee7bb47dd6cbc13f80665fdde3e8040bdd3fb015ecb50 \ + --hash=sha256:b7cf1017d601aa35e6bb650b6ad28652c9cd78ee6caff19f3c28d03e1c80acbf \ + --hash=sha256:bc7637e2f80d8530ee4a78e878bce464f70087ce73cf7c1caf142416923b98f1 \ + --hash=sha256:c0463276121fdee9c49b98908b3a89c39be45d86d1dbaa22957e38f6321d4ce3 \ + --hash=sha256:c4ef880e27901b6cc782f1b95f82da9313c0eb95c3af699103088fa0ac3ce9ac \ + --hash=sha256:c8ae8a0f02f57a6e61203a31428fa1d677cbe50c93622b4149d5c0f319c1d19e \ + --hash=sha256:ca5862d5b3928c4940729dacc329aa9102900382fea192fc5e52eb69d6093815 \ + --hash=sha256:cb01158d8b88ee68f15949894ccc6712278243d95f344770fa7593fa2d94410c \ + --hash=sha256:cb6254dc36b47a990e59e1068afacdcd02958bdcce30bb50cc1700a8b9d624a6 \ + --hash=sha256:cc00f04ed596e9dc0da42ed17ac5e596c6ccba999ba6bd92b0e0aef2f170f2d6 \ + --hash=sha256:cd09d08005f958f370f539f186d10aec3377d55b9eeb0d796025d4886119d76e \ + --hash=sha256:cd4b7ca9984e5e7985c12bc60a6f173f3c958eae74f3ef6624bb6b26e2abbae4 \ + --hash=sha256:ce8a0633f41a967713a59c4139d29110c07e826d131a316b50ce11b1d79b4f84 \ + --hash=sha256:cead0978fc57397645f12578bfd2d5ea9138ea0fac82b2f63f7f7c6877986a69 \ + --hash=sha256:d055ec1e26e441f6187acf818b73564e6e6282709e9bcb5b63f5b23068356a15 \ + --hash=sha256:d1f13550535ad8cff21b8d757a3257963e951d96e20ec82ab44bc64aeb62a191 \ + --hash=sha256:d9c7f57c3d666a53421049053eaacdd14bbd0a528e2186fcb2e672effd053bb0 \ + --hash=sha256:d9e45d7faa48ee908174d8fe84854479ef838fc6a705c9315372eacbc2f02897 \ + --hash=sha256:da3326d9e65ef63a817ecbcc0df6e94463713b754fe293eaa03da99befb9a5bd \ + --hash=sha256:de00632ca48df9daf77a2c65a484531649261ec9f25489917f09e455cb09ddb2 \ + --hash=sha256:e1f185f86a6f3403aa2420e815904c67b2f9ebc443f045edd0de921108345794 \ + --hash=sha256:e824f1492727fa856dd6eda4f7cee25f8518a12f3c4a56a74e8095695089cf6d \ + --hash=sha256:e912091979546adf63357d7e2ccff9b44f026c075aeaf25a52d0e95ad2281074 \ + --hash=sha256:eaabd426fe94daf8fd157c32e571c85cb12e66692f15516a83a03264b08d06c3 \ + --hash=sha256:ebf3e58c7ec8a8bed6d66a75d7fb37b55e5015b03ceae72a8e7c74495551e224 \ + --hash=sha256:ecaae4149d99b1c9e7b88bb03e3221956f68fd6d50be2ef061b2381b61d20838 \ + --hash=sha256:eecbc200c7fd5ddb9a7f16c7decb07b566c29fa2161a16cf67b8d068bd21690a \ + --hash=sha256:f155a433c2ec037d4e8df17d18922c3a0d9b3232a396690f17175d2946f0218d \ + --hash=sha256:f1e34719c6ed0b92f418c7c780480b26b5d9c50349e9a9af7d76bf757530350d \ + --hash=sha256:f34be2938726fc13801220747472850852fe6b1ea75869a048d6f896838c896f \ + --hash=sha256:f820802628d2694cb7e56db99213f930856014862f3fd943d290ea8438d07ca8 \ + --hash=sha256:f8bf04158c6b607d747e93949aa60618b61312fe647a6369f88ce2ff16043490 \ + --hash=sha256:f8e160feb2aed042cd657a72acc0b481212ed28b1b9a95c0cee1621b524e1966 \ + --hash=sha256:f9d332f8c2a2fcbffe1378594431458ddbef721c1769d78e2cbc06280d8155f9 \ + --hash=sha256:fa09f53c465e532f4d3db095e0c55b615f010ad81803d383195b6b5ca6cbf5f3 \ + --hash=sha256:faa3a41b2b66b6e50f84ae4a68c64fcd0c44355741c6374813a800cd6695db9e \ + --hash=sha256:fd44c878ea55ba351104cb93cc85e74916eb8fa440ca7903e57575e97394f608 # via requests -click==8.3.0 \ - --hash=sha256:9b9f285302c6e3064f4330c05f05b81945b2a39544279343e6e7c5f27a9baddc \ - --hash=sha256:e7b8232224eba16f4ebe410c25ced9f7875cb5f3263ffc93cc3e8da705e229c4 +click==8.3.1 \ + --hash=sha256:12ff4785d337a1bb490bb7e9c2b1ee5da3112e94a8622f26a6c77f5d2fc6842a \ + --hash=sha256:981153a64e25f12d547d3426c367a4857371575ee7ad18df2a6183ab0545b2a6 # via uvicorn colorama==0.4.6 \ --hash=sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44 \ @@ -132,13 +166,19 @@ docutils==0.21.2 \ doxmlparser==1.15.0 \ --hash=sha256:a5107dbc96577c1078377790df9332d91845ce0f07c93b3fa393023195a4fe34 # via -r requirements.in +exceptiongroup==1.3.1 ; python_full_version < '3.11' \ + --hash=sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219 \ + --hash=sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598 + # via + # anyio + # pytest h11==0.16.0 \ --hash=sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1 \ --hash=sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86 # via uvicorn -idna==3.10 \ - --hash=sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9 \ - --hash=sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3 +idna==3.11 \ + --hash=sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea \ + --hash=sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902 # via # anyio # requests @@ -146,9 +186,9 @@ imagesize==1.4.1 \ --hash=sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b \ --hash=sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a # via sphinx -iniconfig==2.1.0 \ - --hash=sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7 \ - --hash=sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760 +iniconfig==2.3.0 \ + --hash=sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730 \ + --hash=sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12 # via pytest jinja2==3.1.6 \ --hash=sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d \ @@ -413,9 +453,9 @@ pyserial==3.5 \ --hash=sha256:3c77e014170dfffbd816e6ffc205e9842efb10be9f58ec16d3e8675b4925cddb \ --hash=sha256:c4451db6ba391ca6ca299fb3ec7bae67a5c55dde170964c7a14ceefec02f2cf0 # via -r requirements.in -pytest==9.0.1 \ - --hash=sha256:3e9c069ea73583e255c3b21cf46b8d3c56f6e3a1a8f6da94ccb0fcf57b9d73c8 \ - --hash=sha256:67be0030d194df2dfa7b556f2e56fb3c3315bd5c8822c6951162b92b32ce7dad +pytest==9.0.2 \ + --hash=sha256:711ffd45bf766d5264d487b917733b453d917afd2b0ad65223959f59089f875b \ + --hash=sha256:75186651a92bd89611d1d9fc20f0b4345fd827c41ccd5c299a868a05d70edf11 # via -r requirements.in python-dateutil==2.9.0.post0 \ --hash=sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3 \ @@ -504,14 +544,77 @@ requests==2.32.5 \ --hash=sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6 \ --hash=sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf # via sphinx -roman-numerals-py==3.1.0 \ +roman-numerals-py==3.1.0 ; python_full_version >= '3.11' \ --hash=sha256:9da2ad2fb670bcf24e81070ceb3be72f6c11c440d73bd579fbeca1e9f330954c \ --hash=sha256:be4bf804f083a4ce001b5eb7e3c0862479d10f94c936f6c4e5f250aa5ff5bd2d # via sphinx -ruamel-yaml==0.18.15 \ - --hash=sha256:148f6488d698b7a5eded5ea793a025308b25eca97208181b6a026037f391f701 \ - --hash=sha256:dbfca74b018c4c3fba0b9cc9ee33e53c371194a9000e694995e620490fd40700 +ruamel-yaml==0.18.16 \ + --hash=sha256:048f26d64245bae57a4f9ef6feb5b552a386830ef7a826f235ffb804c59efbba \ + --hash=sha256:a6e587512f3c998b2225d68aa1f35111c29fad14aed561a26e73fab729ec5e5a # via pykwalify +ruamel-yaml-clib==0.2.15 ; python_full_version < '3.14' and platform_python_implementation == 'CPython' \ + --hash=sha256:014181cdec565c8745b7cbc4de3bf2cc8ced05183d986e6d1200168e5bb59490 \ + --hash=sha256:04d21dc9c57d9608225da28285900762befbb0165ae48482c15d8d4989d4af14 \ + --hash=sha256:05c70f7f86be6f7bee53794d80050a28ae7e13e4a0087c1839dcdefd68eb36b6 \ + --hash=sha256:0ba6604bbc3dfcef844631932d06a1a4dcac3fee904efccf582261948431628a \ + --hash=sha256:11e5499db1ccbc7f4b41f0565e4f799d863ea720e01d3e99fa0b7b5fcd7802c9 \ + --hash=sha256:1b45498cc81a4724a2d42273d6cfc243c0547ad7c6b87b4f774cb7bcc131c98d \ + --hash=sha256:1bb7b728fd9f405aa00b4a0b17ba3f3b810d0ccc5f77f7373162e9b5f0ff75d5 \ + --hash=sha256:1f66f600833af58bea694d5892453f2270695b92200280ee8c625ec5a477eed3 \ + --hash=sha256:27dc656e84396e6d687f97c6e65fb284d100483628f02d95464fd731743a4afe \ + --hash=sha256:2812ff359ec1f30129b62372e5f22a52936fac13d5d21e70373dbca5d64bb97c \ + --hash=sha256:2b216904750889133d9222b7b873c199d48ecbb12912aca78970f84a5aa1a4bc \ + --hash=sha256:331fb180858dd8534f0e61aa243b944f25e73a4dae9962bd44c46d1761126bbf \ + --hash=sha256:3cb75a3c14f1d6c3c2a94631e362802f70e83e20d1f2b2ef3026c05b415c4900 \ + --hash=sha256:3eb199178b08956e5be6288ee0b05b2fb0b5c1f309725ad25d9c6ea7e27f962a \ + --hash=sha256:424ead8cef3939d690c4b5c85ef5b52155a231ff8b252961b6516ed7cf05f6aa \ + --hash=sha256:45702dfbea1420ba3450bb3dd9a80b33f0badd57539c6aac09f42584303e0db6 \ + --hash=sha256:468858e5cbde0198337e6a2a78eda8c3fb148bdf4c6498eaf4bc9ba3f8e780bd \ + --hash=sha256:46895c17ead5e22bea5e576f1db7e41cb273e8d062c04a6a49013d9f60996c25 \ + --hash=sha256:46e4cc8c43ef6a94885f72512094e482114a8a706d3c555a34ed4b0d20200600 \ + --hash=sha256:480894aee0b29752560a9de46c0e5f84a82602f2bc5c6cde8db9a345319acfdf \ + --hash=sha256:4b293a37dc97e2b1e8a1aec62792d1e52027087c8eea4fc7b5abd2bdafdd6642 \ + --hash=sha256:4be366220090d7c3424ac2b71c90d1044ea34fca8c0b88f250064fd06087e614 \ + --hash=sha256:4d1032919280ebc04a80e4fb1e93f7a738129857eaec9448310e638c8bccefcf \ + --hash=sha256:4d3b58ab2454b4747442ac76fab66739c72b1e2bb9bd173d7694b9f9dbc9c000 \ + --hash=sha256:4dcec721fddbb62e60c2801ba08c87010bd6b700054a09998c4d09c08147b8fb \ + --hash=sha256:512571ad41bba04eac7268fe33f7f4742210ca26a81fe0c75357fa682636c690 \ + --hash=sha256:542d77b72786a35563f97069b9379ce762944e67055bea293480f7734b2c7e5e \ + --hash=sha256:56ea19c157ed8c74b6be51b5fa1c3aff6e289a041575f0556f66e5fb848bb137 \ + --hash=sha256:5d3c9210219cbc0f22706f19b154c9a798ff65a6beeafbf77fc9c057ec806f7d \ + --hash=sha256:5fea0932358e18293407feb921d4f4457db837b67ec1837f87074667449f9401 \ + --hash=sha256:617d35dc765715fa86f8c3ccdae1e4229055832c452d4ec20856136acc75053f \ + --hash=sha256:64da03cbe93c1e91af133f5bec37fd24d0d4ba2418eaf970d7166b0a26a148a2 \ + --hash=sha256:65f48245279f9bb301d1276f9679b82e4c080a1ae25e679f682ac62446fac471 \ + --hash=sha256:6f1d38cbe622039d111b69e9ca945e7e3efebb30ba998867908773183357f3ed \ + --hash=sha256:713cd68af9dfbe0bb588e144a61aad8dcc00ef92a82d2e87183ca662d242f524 \ + --hash=sha256:71845d377c7a47afc6592aacfea738cc8a7e876d586dfba814501d8c53c1ba60 \ + --hash=sha256:753faf20b3a5906faf1fc50e4ddb8c074cb9b251e00b14c18b28492f933ac8ef \ + --hash=sha256:7e74ea87307303ba91073b63e67f2c667e93f05a8c63079ee5b7a5c8d0d7b043 \ + --hash=sha256:88eea8baf72f0ccf232c22124d122a7f26e8a24110a0273d9bcddcb0f7e1fa03 \ + --hash=sha256:923816815974425fbb1f1bf57e85eca6e14d8adc313c66db21c094927ad01815 \ + --hash=sha256:9b6f7d74d094d1f3a4e157278da97752f16ee230080ae331fcc219056ca54f77 \ + --hash=sha256:a8220fd4c6f98485e97aea65e1df76d4fed1678ede1fe1d0eed2957230d287c4 \ + --hash=sha256:ab0df0648d86a7ecbd9c632e8f8d6b21bb21b5fc9d9e095c796cacf32a728d2d \ + --hash=sha256:ac9b8d5fa4bb7fd2917ab5027f60d4234345fd366fe39aa711d5dca090aa1467 \ + --hash=sha256:badd1d7283f3e5894779a6ea8944cc765138b96804496c91812b2829f70e18a7 \ + --hash=sha256:bdc06ad71173b915167702f55d0f3f027fc61abd975bd308a0968c02db4a4c3e \ + --hash=sha256:bf0846d629e160223805db9fe8cc7aec16aaa11a07310c50c8c7164efa440aec \ + --hash=sha256:bfd309b316228acecfa30670c3887dcedf9b7a44ea39e2101e75d2654522acd4 \ + --hash=sha256:c583229f336682b7212a43d2fa32c30e643d3076178fb9f7a6a14dde85a2d8bd \ + --hash=sha256:cb15a2e2a90c8475df45c0949793af1ff413acfb0a716b8b94e488ea95ce7cff \ + --hash=sha256:d290eda8f6ada19e1771b54e5706b8f9807e6bb08e873900d5ba114ced13e02c \ + --hash=sha256:da3d6adadcf55a93c214d23941aef4abfd45652110aed6580e814152f385b862 \ + --hash=sha256:dcc7f3162d3711fd5d52e2267e44636e3e566d1e5675a5f0b30e98f2c4af7974 \ + --hash=sha256:def5663361f6771b18646620fca12968aae730132e104688766cf8a3b1d65922 \ + --hash=sha256:e5e9f630c73a490b758bf14d859a39f375e6999aea5ddd2e2e9da89b9953486a \ + --hash=sha256:e9fde97ecb7bb9c41261c2ce0da10323e9227555c674989f8d9eb7572fc2098d \ + --hash=sha256:ef71831bd61fbdb7aa0399d5c4da06bea37107ab5c79ff884cc07f2450910262 \ + --hash=sha256:f4421ab780c37210a07d138e56dd4b51f8642187cdfb433eb687fe8c11de0144 \ + --hash=sha256:f6d3655e95a80325b84c4e14c080b2470fe4f33b6846f288379ce36154993fb1 \ + --hash=sha256:fd4c928ddf6bce586285daa6d90680b9c291cfd045fc40aad34e445d57b1bf51 \ + --hash=sha256:fe239bdfdae2302e93bd6e8264bd9b71290218fff7084a9db250b55caaccf43f + # via ruamel-yaml setuptools==80.9.0 \ --hash=sha256:062d34222ad13e0cc312a4c02d73f059e86a4acbfbdea8f8f76b28c99f306922 \ --hash=sha256:f36b47402ecde768dbfafc46e8e4207b4360c654f1f3bb84475f0a28628fb19c @@ -522,15 +625,26 @@ six==1.17.0 \ # via # doxmlparser # python-dateutil -sniffio==1.3.1 \ - --hash=sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2 \ - --hash=sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc - # via anyio snowballstemmer==3.0.1 \ --hash=sha256:6cd7b3897da8d6c9ffb968a6781fa6532dce9c3618a4b127d920dab764a19064 \ --hash=sha256:6d5eeeec8e9f84d4d56b847692bacf79bc2c8e90c7f80ca4444ff8b6f2e52895 # via sphinx -sphinx==8.2.3 \ +sphinx==8.1.3 ; python_full_version < '3.11' \ + --hash=sha256:09719015511837b76bf6e03e42eb7595ac8c2e41eeb9c29c5b755c6b677992a2 \ + --hash=sha256:43c1911eecb0d3e161ad78611bc905d1ad0e523e4ddc202a58a821773dc4c927 + # via + # -r requirements.in + # sphinx-autobuild + # sphinx-copybutton + # sphinx-last-updated-by-git + # sphinx-notfound-page + # sphinx-rtd-theme + # sphinx-tabs + # sphinx-togglebutton + # sphinxcontrib-jquery + # sphinxcontrib-programoutput + # sphinxcontrib-svg2pdfconverter +sphinx==8.2.3 ; python_full_version >= '3.11' \ --hash=sha256:398ad29dee7f63a75888314e9424d40f52ce5a6a87ae88e7071e80af296ec348 \ --hash=sha256:4405915165f13521d875a8c29c8970800a0141c14cc5416a38feca4ea5d9b9c3 # via @@ -545,7 +659,11 @@ sphinx==8.2.3 \ # sphinxcontrib-jquery # sphinxcontrib-programoutput # sphinxcontrib-svg2pdfconverter -sphinx-autobuild==2025.8.25 \ +sphinx-autobuild==2024.10.3 ; python_full_version < '3.11' \ + --hash=sha256:158e16c36f9d633e613c9aaf81c19b0fc458ca78b112533b20dafcda430d60fa \ + --hash=sha256:248150f8f333e825107b6d4b86113ab28fa51750e5f9ae63b59dc339be951fb1 + # via -r requirements.in +sphinx-autobuild==2025.8.25 ; python_full_version >= '3.11' \ --hash=sha256:9cf5aab32853c8c31af572e4fecdc09c997e2b8be5a07daf2a389e270e85b213 \ --hash=sha256:b750ac7d5a18603e4665294323fd20f6dcc0a984117026d1986704fa68f0379a # via -r requirements.in @@ -609,129 +727,186 @@ sphinxcontrib-serializinghtml==2.0.0 \ --hash=sha256:6e2cb0eef194e10c27ec0023bfeb25badbbb5868244cf5bc5bdc04e4464bf331 \ --hash=sha256:e9d912827f872c029017a53f0ef2180b327c3f7fd23c87229f7a8e8b70031d4d # via sphinx -sphinxcontrib-svg2pdfconverter==1.3.0 \ - --hash=sha256:5df6b0895e2e2101d720bfd08841bb56d74c57b1f86229a7c18b771dfdf4ffbb \ - --hash=sha256:6411a4cc2f57eed96a0d7bbfa139f68cbe7983018881e1e6d7c46053cd69911f +sphinxcontrib-svg2pdfconverter==2.0.0 \ + --hash=sha256:ab9c8f1080391e231812d20abf2657a69ee35574563b1014414f953964a95fa3 \ + --hash=sha256:b23bfda91aecd24287bfcf1b30dd728086a205decc5a46cf2f4b2aa4a0d1f447 # via -r requirements.in -starlette==0.49.1 \ - --hash=sha256:481a43b71e24ed8c43b11ea02f5353d77840e01480881b8cb5a26b8cae64a8cb \ - --hash=sha256:d92ce9f07e4a3caa3ac13a79523bd18e3bc0042bb8ff2d759a8e7dd0e1859875 +starlette==0.50.0 \ + --hash=sha256:9e5391843ec9b6e472eed1365a78c8098cfceb7a74bfd4d6b1c0c0095efb3bca \ + --hash=sha256:a2a17b22203254bcbc2e1f926d2d55f3f9497f769416b3190768befe598fa3ca # via sphinx-autobuild -urllib3==2.5.0 \ - --hash=sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760 \ - --hash=sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc +tomli==2.3.0 ; python_full_version < '3.11' \ + --hash=sha256:00b5f5d95bbfc7d12f91ad8c593a1659b6387b43f054104cda404be6bda62456 \ + --hash=sha256:0a154a9ae14bfcf5d8917a59b51ffd5a3ac1fd149b71b47a3a104ca4edcfa845 \ + --hash=sha256:0c95ca56fbe89e065c6ead5b593ee64b84a26fca063b5d71a1122bf26e533999 \ + --hash=sha256:0eea8cc5c5e9f89c9b90c4896a8deefc74f518db5927d0e0e8d4a80953d774d0 \ + --hash=sha256:1cb4ed918939151a03f33d4242ccd0aa5f11b3547d0cf30f7c74a408a5b99878 \ + --hash=sha256:4021923f97266babc6ccab9f5068642a0095faa0a51a246a6a02fccbb3514eaf \ + --hash=sha256:4c2ef0244c75aba9355561272009d934953817c49f47d768070c3c94355c2aa3 \ + --hash=sha256:4dc4ce8483a5d429ab602f111a93a6ab1ed425eae3122032db7e9acf449451be \ + --hash=sha256:4f195fe57ecceac95a66a75ac24d9d5fbc98ef0962e09b2eddec5d39375aae52 \ + --hash=sha256:5192f562738228945d7b13d4930baffda67b69425a7f0da96d360b0a3888136b \ + --hash=sha256:5e01decd096b1530d97d5d85cb4dff4af2d8347bd35686654a004f8dea20fc67 \ + --hash=sha256:64be704a875d2a59753d80ee8a533c3fe183e3f06807ff7dc2232938ccb01549 \ + --hash=sha256:70a251f8d4ba2d9ac2542eecf008b3c8a9fc5c3f9f02c56a9d7952612be2fdba \ + --hash=sha256:73ee0b47d4dad1c5e996e3cd33b8a76a50167ae5f96a2607cbe8cc773506ab22 \ + --hash=sha256:74bf8464ff93e413514fefd2be591c3b0b23231a77f901db1eb30d6f712fc42c \ + --hash=sha256:792262b94d5d0a466afb5bc63c7daa9d75520110971ee269152083270998316f \ + --hash=sha256:7b0882799624980785240ab732537fcfc372601015c00f7fc367c55308c186f6 \ + --hash=sha256:883b1c0d6398a6a9d29b508c331fa56adbcdff647f6ace4dfca0f50e90dfd0ba \ + --hash=sha256:88bd15eb972f3664f5ed4b57c1634a97153b4bac4479dcb6a495f41921eb7f45 \ + --hash=sha256:8a35dd0e643bb2610f156cca8db95d213a90015c11fee76c946aa62b7ae7e02f \ + --hash=sha256:940d56ee0410fa17ee1f12b817b37a4d4e4dc4d27340863cc67236c74f582e77 \ + --hash=sha256:97d5eec30149fd3294270e889b4234023f2c69747e555a27bd708828353ab606 \ + --hash=sha256:a0e285d2649b78c0d9027570d4da3425bdb49830a6156121360b3f8511ea3441 \ + --hash=sha256:a1f7f282fe248311650081faafa5f4732bdbfef5d45fe3f2e702fbc6f2d496e0 \ + --hash=sha256:a4ea38c40145a357d513bffad0ed869f13c1773716cf71ccaa83b0fa0cc4e42f \ + --hash=sha256:a56212bdcce682e56b0aaf79e869ba5d15a6163f88d5451cbde388d48b13f530 \ + --hash=sha256:ad805ea85eda330dbad64c7ea7a4556259665bdf9d2672f5dccc740eb9d3ca05 \ + --hash=sha256:b273fcbd7fc64dc3600c098e39136522650c49bca95df2d11cf3b626422392c8 \ + --hash=sha256:b5870b50c9db823c595983571d1296a6ff3e1b88f734a4c8f6fc6188397de005 \ + --hash=sha256:b74a0e59ec5d15127acdabd75ea17726ac4c5178ae51b85bfe39c4f8a278e879 \ + --hash=sha256:be71c93a63d738597996be9528f4abe628d1adf5e6eb11607bc8fe1a510b5dae \ + --hash=sha256:c22a8bf253bacc0cf11f35ad9808b6cb75ada2631c2d97c971122583b129afbc \ + --hash=sha256:c4665508bcbac83a31ff8ab08f424b665200c0e1e645d2bd9ab3d3e557b6185b \ + --hash=sha256:c5f3ffd1e098dfc032d4d3af5c0ac64f6d286d98bc148698356847b80fa4de1b \ + --hash=sha256:cebc6fe843e0733ee827a282aca4999b596241195f43b4cc371d64fc6639da9e \ + --hash=sha256:d1381caf13ab9f300e30dd8feadb3de072aeb86f1d34a8569453ff32a7dea4bf \ + --hash=sha256:d7d86942e56ded512a594786a5ba0a5e521d02529b3826e7761a05138341a2ac \ + --hash=sha256:e31d432427dcbf4d86958c184b9bfd1e96b5b71f8eb17e6d02531f434fd335b8 \ + --hash=sha256:e95b1af3c5b07d9e643909b5abbec77cd9f1217e6d0bca72b0234736b9fb1f1b \ + --hash=sha256:f85209946d1fe94416debbb88d00eb92ce9cd5266775424ff81bc959e001acaf \ + --hash=sha256:feb0dacc61170ed7ab602d3d972a58f14ee3ee60494292d384649a3dc38ef463 \ + --hash=sha256:ff72b71b5d10d22ecb084d345fc26f42b5143c5533db5e2eaba7d2d335358876 + # via + # pytest + # sphinx +typing-extensions==4.15.0 ; python_full_version < '3.13' \ + --hash=sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466 \ + --hash=sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548 + # via + # anyio + # exceptiongroup + # starlette + # uvicorn +urllib3==2.6.1 \ + --hash=sha256:5379eb6e1aba4088bae84f8242960017ec8d8e3decf30480b3a1abdaa9671a3f \ + --hash=sha256:e67d06fe947c36a7ca39f4994b08d73922d40e6cca949907be05efa6fd75110b # via requests -uvicorn==0.37.0 \ - --hash=sha256:4115c8add6d3fd536c8ee77f0e14a7fd2ebba939fed9b02583a97f80648f9e13 \ - --hash=sha256:913b2b88672343739927ce381ff9e2ad62541f9f8289664fa1d1d3803fa2ce6c +uvicorn==0.38.0 \ + --hash=sha256:48c0afd214ceb59340075b4a052ea1ee91c16fbc2a9b1469cca0e54566977b02 \ + --hash=sha256:fd97093bdd120a2609fc0d3afe931d4d4ad688b6e75f0f929fde1bc36fe0e91d # via sphinx-autobuild -watchfiles==1.1.0 \ - --hash=sha256:00645eb79a3faa70d9cb15c8d4187bb72970b2470e938670240c7998dad9f13a \ - --hash=sha256:04e4ed5d1cd3eae68c89bcc1a485a109f39f2fd8de05f705e98af6b5f1861f1f \ - --hash=sha256:0a7d40b77f07be87c6faa93d0951a0fcd8cbca1ddff60a1b65d741bac6f3a9f6 \ - --hash=sha256:0ece16b563b17ab26eaa2d52230c9a7ae46cf01759621f4fbbca280e438267b3 \ - --hash=sha256:11ee4444250fcbeb47459a877e5e80ed994ce8e8d20283857fc128be1715dac7 \ - --hash=sha256:12b0a02a91762c08f7264e2e79542f76870c3040bbc847fb67410ab81474932a \ - --hash=sha256:12fe8eaffaf0faa7906895b4f8bb88264035b3f0243275e0bf24af0436b27259 \ - --hash=sha256:130fc497b8ee68dce163e4254d9b0356411d1490e868bd8790028bc46c5cc297 \ - --hash=sha256:17ab167cca6339c2b830b744eaf10803d2a5b6683be4d79d8475d88b4a8a4be1 \ - --hash=sha256:199207b2d3eeaeb80ef4411875a6243d9ad8bc35b07fc42daa6b801cc39cc41c \ - --hash=sha256:20ecc8abbd957046f1fe9562757903f5eaf57c3bce70929fda6c7711bb58074a \ - --hash=sha256:239736577e848678e13b201bba14e89718f5c2133dfd6b1f7846fa1b58a8532b \ - --hash=sha256:249590eb75ccc117f488e2fabd1bfa33c580e24b96f00658ad88e38844a040bb \ - --hash=sha256:27f30e14aa1c1e91cb653f03a63445739919aef84c8d2517997a83155e7a2fcc \ - --hash=sha256:29e7bc2eee15cbb339c68445959108803dc14ee0c7b4eea556400131a8de462b \ - --hash=sha256:328dbc9bff7205c215a7807da7c18dce37da7da718e798356212d22696404339 \ - --hash=sha256:32d6d4e583593cb8576e129879ea0991660b935177c0f93c6681359b3654bfa9 \ - --hash=sha256:3366f56c272232860ab45c77c3ca7b74ee819c8e1f6f35a7125556b198bbc6df \ - --hash=sha256:3434e401f3ce0ed6b42569128b3d1e3af773d7ec18751b918b89cd49c14eaafb \ - --hash=sha256:37d3d3f7defb13f62ece99e9be912afe9dd8a0077b7c45ee5a57c74811d581a4 \ - --hash=sha256:3a6fd40bbb50d24976eb275ccb55cd1951dfb63dbc27cae3066a6ca5f4beabd5 \ - --hash=sha256:3aba215958d88182e8d2acba0fdaf687745180974946609119953c0e112397dc \ - --hash=sha256:406520216186b99374cdb58bc48e34bb74535adec160c8459894884c983a149c \ - --hash=sha256:4281cd9fce9fc0a9dbf0fc1217f39bf9cf2b4d315d9626ef1d4e87b84699e7e8 \ - --hash=sha256:42f92befc848bb7a19658f21f3e7bae80d7d005d13891c62c2cd4d4d0abb3433 \ - --hash=sha256:48aa25e5992b61debc908a61ab4d3f216b64f44fdaa71eb082d8b2de846b7d12 \ - --hash=sha256:5007f860c7f1f8df471e4e04aaa8c43673429047d63205d1630880f7637bca30 \ - --hash=sha256:50a51a90610d0845a5931a780d8e51d7bd7f309ebc25132ba975aca016b576a0 \ - --hash=sha256:51556d5004887045dba3acdd1fdf61dddea2be0a7e18048b5e853dcd37149b86 \ - --hash=sha256:51b81e55d40c4b4aa8658427a3ee7ea847c591ae9e8b81ef94a90b668999353c \ - --hash=sha256:5366164391873ed76bfdf618818c82084c9db7fac82b64a20c44d335eec9ced5 \ - --hash=sha256:54062ef956807ba806559b3c3d52105ae1827a0d4ab47b621b31132b6b7e2866 \ - --hash=sha256:60022527e71d1d1fda67a33150ee42869042bce3d0fcc9cc49be009a9cded3fb \ - --hash=sha256:622d6b2c06be19f6e89b1d951485a232e3b59618def88dbeda575ed8f0d8dbf2 \ - --hash=sha256:62cc7a30eeb0e20ecc5f4bd113cd69dcdb745a07c68c0370cea919f373f65d9e \ - --hash=sha256:693ed7ec72cbfcee399e92c895362b6e66d63dac6b91e2c11ae03d10d503e575 \ - --hash=sha256:6d2404af8db1329f9a3c9b79ff63e0ae7131986446901582067d9304ae8aaf7f \ - --hash=sha256:7049e52167fc75fc3cc418fc13d39a8e520cbb60ca08b47f6cedb85e181d2f2a \ - --hash=sha256:7080c4bb3efd70a07b1cc2df99a7aa51d98685be56be6038c3169199d0a1c69f \ - --hash=sha256:7738027989881e70e3723c75921f1efa45225084228788fc59ea8c6d732eb30d \ - --hash=sha256:7a7bd57a1bb02f9d5c398c0c1675384e7ab1dd39da0ca50b7f09af45fa435277 \ - --hash=sha256:7b3443f4ec3ba5aa00b0e9fa90cf31d98321cbff8b925a7c7b84161619870bc9 \ - --hash=sha256:7c55b0f9f68590115c25272b06e63f0824f03d4fc7d6deed43d8ad5660cabdbf \ - --hash=sha256:7fd1b3879a578a8ec2076c7961076df540b9af317123f84569f5a9ddee64ce92 \ - --hash=sha256:8076a5769d6bdf5f673a19d51da05fc79e2bbf25e9fe755c47595785c06a8c72 \ - --hash=sha256:80f811146831c8c86ab17b640801c25dc0a88c630e855e2bef3568f30434d52b \ - --hash=sha256:8412eacef34cae2836d891836a7fff7b754d6bcac61f6c12ba5ca9bc7e427b68 \ - --hash=sha256:865c8e95713744cf5ae261f3067861e9da5f1370ba91fc536431e29b418676fa \ - --hash=sha256:86b1e28d4c37e89220e924305cd9f82866bb0ace666943a6e4196c5df4d58dcc \ - --hash=sha256:891c69e027748b4a73847335d208e374ce54ca3c335907d381fde4e41661b13b \ - --hash=sha256:8ac164e20d17cc285f2b94dc31c384bc3aa3dd5e7490473b3db043dd70fbccfd \ - --hash=sha256:8c5701dc474b041e2934a26d31d39f90fac8a3dee2322b39f7729867f932b1d4 \ - --hash=sha256:90ebb429e933645f3da534c89b29b665e285048973b4d2b6946526888c3eb2c7 \ - --hash=sha256:923fec6e5461c42bd7e3fd5ec37492c6f3468be0499bc0707b4bbbc16ac21792 \ - --hash=sha256:935f9edd022ec13e447e5723a7d14456c8af254544cefbc533f6dd276c9aa0d9 \ - --hash=sha256:95ab1594377effac17110e1352989bdd7bdfca9ff0e5eeccd8c69c5389b826d0 \ - --hash=sha256:9974d2f7dc561cce3bb88dfa8eb309dab64c729de85fba32e98d75cf24b66297 \ - --hash=sha256:9c733cda03b6d636b4219625a4acb5c6ffb10803338e437fb614fef9516825ef \ - --hash=sha256:9dc001c3e10de4725c749d4c2f2bdc6ae24de5a88a339c4bce32300a31ede179 \ - --hash=sha256:9f811079d2f9795b5d48b55a37aa7773680a5659afe34b54cc1d86590a51507d \ - --hash=sha256:a2726d7bfd9f76158c84c10a409b77a320426540df8c35be172444394b17f7ea \ - --hash=sha256:a479466da6db5c1e8754caee6c262cd373e6e6c363172d74394f4bff3d84d7b5 \ - --hash=sha256:a543492513a93b001975ae283a51f4b67973662a375a403ae82f420d2c7205ee \ - --hash=sha256:a89c75a5b9bc329131115a409d0acc16e8da8dfd5867ba59f1dd66ae7ea8fa82 \ - --hash=sha256:a8f6f72974a19efead54195bc9bed4d850fc047bb7aa971268fd9a8387c89011 \ - --hash=sha256:a9ccbf1f129480ed3044f540c0fdbc4ee556f7175e5ab40fe077ff6baf286d4e \ - --hash=sha256:aa0cc8365ab29487eb4f9979fd41b22549853389e22d5de3f134a6796e1b05a4 \ - --hash=sha256:adb4167043d3a78280d5d05ce0ba22055c266cf8655ce942f2fb881262ff3cdf \ - --hash=sha256:af06c863f152005c7592df1d6a7009c836a247c9d8adb78fef8575a5a98699db \ - --hash=sha256:b067915e3c3936966a8607f6fe5487df0c9c4afb85226613b520890049deea20 \ - --hash=sha256:b7c5f6fe273291f4d414d55b2c80d33c457b8a42677ad14b4b47ff025d0893e4 \ - --hash=sha256:b915daeb2d8c1f5cee4b970f2e2c988ce6514aace3c9296e58dd64dc9aa5d575 \ - --hash=sha256:ba0e3255b0396cac3cc7bbace76404dd72b5438bf0d8e7cefa2f79a7f3649caa \ - --hash=sha256:bda8136e6a80bdea23e5e74e09df0362744d24ffb8cd59c4a95a6ce3d142f79c \ - --hash=sha256:bfe3c517c283e484843cb2e357dd57ba009cff351edf45fb455b5fbd1f45b15f \ - --hash=sha256:c588c45da9b08ab3da81d08d7987dae6d2a3badd63acdb3e206a42dbfa7cb76f \ - --hash=sha256:c600e85f2ffd9f1035222b1a312aff85fd11ea39baff1d705b9b047aad2ce267 \ - --hash=sha256:c68e9f1fcb4d43798ad8814c4c1b61547b014b667216cb754e606bfade587018 \ - --hash=sha256:c9649dfc57cc1f9835551deb17689e8d44666315f2e82d337b9f07bd76ae3aa2 \ - --hash=sha256:cb45350fd1dc75cd68d3d72c47f5b513cb0578da716df5fba02fff31c69d5f2d \ - --hash=sha256:cbcf8630ef4afb05dc30107bfa17f16c0896bb30ee48fc24bf64c1f970f3b1fd \ - --hash=sha256:cbd949bdd87567b0ad183d7676feb98136cde5bb9025403794a4c0db28ed3a47 \ - --hash=sha256:cc08ef8b90d78bfac66f0def80240b0197008e4852c9f285907377b2947ffdcb \ - --hash=sha256:cd17a1e489f02ce9117b0de3c0b1fab1c3e2eedc82311b299ee6b6faf6c23a29 \ - --hash=sha256:d05686b5487cfa2e2c28ff1aa370ea3e6c5accfe6435944ddea1e10d93872147 \ - --hash=sha256:d0e10e6f8f6dc5762adee7dece33b722282e1f59aa6a55da5d493a97282fedd8 \ - --hash=sha256:d181ef50923c29cf0450c3cd47e2f0557b62218c50b2ab8ce2ecaa02bd97e670 \ - --hash=sha256:d1caf40c1c657b27858f9774d5c0e232089bca9cb8ee17ce7478c6e9264d2587 \ - --hash=sha256:d7642b9bc4827b5518ebdb3b82698ada8c14c7661ddec5fe719f3e56ccd13c97 \ - --hash=sha256:d9481174d3ed982e269c090f780122fb59cee6c3796f74efe74e70f7780ed94c \ - --hash=sha256:d9ba68ec283153dead62cbe81872d28e053745f12335d037de9cbd14bd1877f5 \ - --hash=sha256:da71945c9ace018d8634822f16cbc2a78323ef6c876b1d34bbf5d5222fd6a72e \ - --hash=sha256:dc44678a72ac0910bac46fa6a0de6af9ba1355669b3dfaf1ce5f05ca7a74364e \ - --hash=sha256:df32d59cb9780f66d165a9a7a26f19df2c7d24e3bd58713108b41d0ff4f929c6 \ - --hash=sha256:df670918eb7dd719642e05979fc84704af913d563fd17ed636f7c4783003fdcc \ - --hash=sha256:e78b6ed8165996013165eeabd875c5dfc19d41b54f94b40e9fff0eb3193e5e8e \ - --hash=sha256:ed8fc66786de8d0376f9f913c09e963c66e90ced9aa11997f93bdb30f7c872a8 \ - --hash=sha256:eff4b8d89f444f7e49136dc695599a591ff769300734446c0a86cba2eb2f9895 \ - --hash=sha256:f21af781a4a6fbad54f03c598ab620e3a77032c5878f3d780448421a6e1818c7 \ - --hash=sha256:f2bcdc54ea267fe72bfc7d83c041e4eb58d7d8dc6f578dfddb52f037ce62f432 \ - --hash=sha256:f2f0498b7d2a3c072766dba3274fe22a183dbea1f99d188f1c6c72209a1063dc \ - --hash=sha256:f7208ab6e009c627b7557ce55c465c98967e8caa8b11833531fdf95799372633 \ - --hash=sha256:f7590d5a455321e53857892ab8879dce62d1f4b04748769f5adf2e707afb9d4f \ - --hash=sha256:fa257a4d0d21fcbca5b5fcba9dca5a78011cb93c0323fb8855c6d2dfbc76eb77 \ - --hash=sha256:fba9b62da882c1be1280a7584ec4515d0a6006a94d6e5819730ec2eab60ffe12 \ - --hash=sha256:fe4371595edf78c41ef8ac8df20df3943e13defd0efcb732b2e393b5a8a7a71f +watchfiles==1.1.1 \ + --hash=sha256:00485f441d183717038ed2e887a7c868154f216877653121068107b227a2f64c \ + --hash=sha256:03fa0f5237118a0c5e496185cafa92878568b652a2e9a9382a5151b1a0380a43 \ + --hash=sha256:04e78dd0b6352db95507fd8cb46f39d185cf8c74e4cf1e4fbad1d3df96faf510 \ + --hash=sha256:059098c3a429f62fc98e8ec62b982230ef2c8df68c79e826e37b895bc359a9c0 \ + --hash=sha256:08af70fd77eee58549cd69c25055dc344f918d992ff626068242259f98d598a2 \ + --hash=sha256:0b495de0bb386df6a12b18335a0285dda90260f51bdb505503c02bcd1ce27a8b \ + --hash=sha256:130e4876309e8686a5e37dba7d5e9bc77e6ed908266996ca26572437a5271e18 \ + --hash=sha256:14e0b1fe858430fc0251737ef3824c54027bedb8c37c38114488b8e131cf8219 \ + --hash=sha256:17ef139237dfced9da49fb7f2232c86ca9421f666d78c264c7ffca6601d154c3 \ + --hash=sha256:1a0bb430adb19ef49389e1ad368450193a90038b5b752f4ac089ec6942c4dff4 \ + --hash=sha256:1db5d7ae38ff20153d542460752ff397fcf5c96090c1230803713cf3147a6803 \ + --hash=sha256:28475ddbde92df1874b6c5c8aaeb24ad5be47a11f87cde5a28ef3835932e3e94 \ + --hash=sha256:2edc3553362b1c38d9f06242416a5d8e9fe235c204a4072e988ce2e5bb1f69f6 \ + --hash=sha256:30f7da3fb3f2844259cba4720c3fc7138eb0f7b659c38f3bfa65084c7fc7abce \ + --hash=sha256:311ff15a0bae3714ffb603e6ba6dbfba4065ab60865d15a6ec544133bdb21099 \ + --hash=sha256:319b27255aacd9923b8a276bb14d21a5f7ff82564c744235fc5eae58d95422ae \ + --hash=sha256:35c53bd62a0b885bf653ebf6b700d1bf05debb78ad9292cf2a942b23513dc4c4 \ + --hash=sha256:36193ed342f5b9842edd3532729a2ad55c4160ffcfa3700e0d54be496b70dd43 \ + --hash=sha256:39574d6370c4579d7f5d0ad940ce5b20db0e4117444e39b6d8f99db5676c52fd \ + --hash=sha256:399600947b170270e80134ac854e21b3ccdefa11a9529a3decc1327088180f10 \ + --hash=sha256:3a476189be23c3686bc2f4321dd501cb329c0a0469e77b7b534ee10129ae6374 \ + --hash=sha256:3ad9fe1dae4ab4212d8c91e80b832425e24f421703b5a42ef2e4a1e215aff051 \ + --hash=sha256:3bc570d6c01c206c46deb6e935a260be44f186a2f05179f52f7fcd2be086a94d \ + --hash=sha256:3dbd8cbadd46984f802f6d479b7e3afa86c42d13e8f0f322d669d79722c8ec34 \ + --hash=sha256:3e6f39af2eab0118338902798b5aa6664f46ff66bc0280de76fca67a7f262a49 \ + --hash=sha256:3f53fa183d53a1d7a8852277c92b967ae99c2d4dcee2bfacff8868e6e30b15f7 \ + --hash=sha256:3f6d37644155fb5beca5378feb8c1708d5783145f2a0f1c4d5a061a210254844 \ + --hash=sha256:3f7eb7da0eb23aa2ba036d4f616d46906013a68caf61b7fdbe42fc8b25132e77 \ + --hash=sha256:3fa0b59c92278b5a7800d3ee7733da9d096d4aabcfabb9a928918bd276ef9b9b \ + --hash=sha256:421e29339983e1bebc281fab40d812742268ad057db4aee8c4d2bce0af43b741 \ + --hash=sha256:4b943d3668d61cfa528eb949577479d3b077fd25fb83c641235437bc0b5bc60e \ + --hash=sha256:526e86aced14a65a5b0ec50827c745597c782ff46b571dbfe46192ab9e0b3c33 \ + --hash=sha256:52e06553899e11e8074503c8e716d574adeeb7e68913115c4b3653c53f9bae42 \ + --hash=sha256:544364b2b51a9b0c7000a4b4b02f90e9423d97fbbf7e06689236443ebcad81ab \ + --hash=sha256:5524298e3827105b61951a29c3512deb9578586abf3a7c5da4a8069df247cccc \ + --hash=sha256:55c7475190662e202c08c6c0f4d9e345a29367438cf8e8037f3155e10a88d5a5 \ + --hash=sha256:563b116874a9a7ce6f96f87cd0b94f7faf92d08d0021e837796f0a14318ef8da \ + --hash=sha256:57ca5281a8b5e27593cb7d82c2ac927ad88a96ed406aa446f6344e4328208e9e \ + --hash=sha256:5c85794a4cfa094714fb9c08d4a218375b2b95b8ed1666e8677c349906246c05 \ + --hash=sha256:5f3bde70f157f84ece3765b42b4a52c6ac1a50334903c6eaf765362f6ccca88a \ + --hash=sha256:5f3f58818dc0b07f7d9aa7fe9eb1037aecb9700e63e1f6acfed13e9fef648f5d \ + --hash=sha256:5fac835b4ab3c6487b5dbad78c4b3724e26bcc468e886f8ba8cc4306f68f6701 \ + --hash=sha256:620bae625f4cb18427b1bb1a2d9426dc0dd5a5ba74c7c2cdb9de405f7b129863 \ + --hash=sha256:672b8adf25b1a0d35c96b5888b7b18699d27d4194bac8beeae75be4b7a3fc9b2 \ + --hash=sha256:6aae418a8b323732fa89721d86f39ec8f092fc2af67f4217a2b07fd3e93c6101 \ + --hash=sha256:6c3631058c37e4a0ec440bf583bc53cdbd13e5661bb6f465bc1d88ee9a0a4d02 \ + --hash=sha256:6c9c9262f454d1c4d8aaa7050121eb4f3aea197360553699520767daebf2180b \ + --hash=sha256:6e43d39a741e972bab5d8100b5cdacf69db64e34eb19b6e9af162bccf63c5cc6 \ + --hash=sha256:7365b92c2e69ee952902e8f70f3ba6360d0d596d9299d55d7d386df84b6941fb \ + --hash=sha256:743185e7372b7bc7c389e1badcc606931a827112fbbd37f14c537320fca08620 \ + --hash=sha256:74472234c8370669850e1c312490f6026d132ca2d396abfad8830b4f1c096957 \ + --hash=sha256:74d5012b7630714b66be7b7b7a78855ef7ad58e8650c73afc4c076a1f480a8d6 \ + --hash=sha256:77a13aea58bc2b90173bc69f2a90de8e282648939a00a602e1dc4ee23e26b66d \ + --hash=sha256:79ff6c6eadf2e3fc0d7786331362e6ef1e51125892c75f1004bd6b52155fb956 \ + --hash=sha256:831a62658609f0e5c64178211c942ace999517f5770fe9436be4c2faeba0c0ef \ + --hash=sha256:836398932192dae4146c8f6f737d74baeac8b70ce14831a239bdb1ca882fc261 \ + --hash=sha256:842178b126593addc05acf6fce960d28bc5fae7afbaa2c6c1b3a7b9460e5be02 \ + --hash=sha256:8526e8f916bb5b9a0a777c8317c23ce65de259422bba5b31325a6fa6029d33af \ + --hash=sha256:859e43a1951717cc8de7f4c77674a6d389b106361585951d9e69572823f311d9 \ + --hash=sha256:88863fbbc1a7312972f1c511f202eb30866370ebb8493aef2812b9ff28156a21 \ + --hash=sha256:89eef07eee5e9d1fda06e38822ad167a044153457e6fd997f8a858ab7564a336 \ + --hash=sha256:8c89f9f2f740a6b7dcc753140dd5e1ab9215966f7a3530d0c0705c83b401bd7d \ + --hash=sha256:8c91ed27800188c2ae96d16e3149f199d62f86c7af5f5f4d2c61a3ed8cd3666c \ + --hash=sha256:8ca65483439f9c791897f7db49202301deb6e15fe9f8fe2fed555bf986d10c31 \ + --hash=sha256:8fbe85cb3201c7d380d3d0b90e63d520f15d6afe217165d7f98c9c649654db81 \ + --hash=sha256:91d4c9a823a8c987cce8fa2690923b069966dabb196dd8d137ea2cede885fde9 \ + --hash=sha256:9bb9f66367023ae783551042d31b1d7fd422e8289eedd91f26754a66f44d5cff \ + --hash=sha256:a173cb5c16c4f40ab19cecf48a534c409f7ea983ab8fed0741304a1c0a31b3f2 \ + --hash=sha256:a36d8efe0f290835fd0f33da35042a1bb5dc0e83cbc092dcf69bce442579e88e \ + --hash=sha256:a55f3e9e493158d7bfdb60a1165035f1cf7d320914e7b7ea83fe22c6023b58fc \ + --hash=sha256:a625815d4a2bdca61953dbba5a39d60164451ef34c88d751f6c368c3ea73d404 \ + --hash=sha256:a916a2932da8f8ab582f242c065f5c81bed3462849ca79ee357dd9551b0e9b01 \ + --hash=sha256:ac3cc5759570cd02662b15fbcd9d917f7ecd47efe0d6b40474eafd246f91ea18 \ + --hash=sha256:acb08650863767cbc58bca4813b92df4d6c648459dcaa3d4155681962b2aa2d3 \ + --hash=sha256:aebfd0861a83e6c3d1110b78ad54704486555246e542be3e2bb94195eabb2606 \ + --hash=sha256:afaeff7696e0ad9f02cbb8f56365ff4686ab205fcf9c4c5b6fdfaaa16549dd04 \ + --hash=sha256:b27cf2eb1dda37b2089e3907d8ea92922b673c0c427886d4edc6b94d8dfe5db3 \ + --hash=sha256:b2cd9e04277e756a2e2d2543d65d1e2166d6fd4c9b183f8808634fda23f17b14 \ + --hash=sha256:b9c4702f29ca48e023ffd9b7ff6b822acdf47cb1ff44cb490a3f1d5ec8987e9c \ + --hash=sha256:bbe1ef33d45bc71cf21364df962af171f96ecaeca06bd9e3d0b583efb12aec82 \ + --hash=sha256:bd404be08018c37350f0d6e34676bd1e2889990117a2b90070b3007f172d0610 \ + --hash=sha256:bf0a91bfb5574a2f7fc223cf95eeea79abfefa404bf1ea5e339c0c1560ae99a0 \ + --hash=sha256:bfb5862016acc9b869bb57284e6cb35fdf8e22fe59f7548858e2f971d045f150 \ + --hash=sha256:bfff9740c69c0e4ed32416f013f3c45e2ae42ccedd1167ef2d805c000b6c71a5 \ + --hash=sha256:c1f5210f1b8fc91ead1283c6fd89f70e76fb07283ec738056cf34d51e9c1d62c \ + --hash=sha256:c2047d0b6cea13b3316bdbafbfa0c4228ae593d995030fda39089d36e64fc03a \ + --hash=sha256:c22c776292a23bfc7237a98f791b9ad3144b02116ff10d820829ce62dff46d0b \ + --hash=sha256:c755367e51db90e75b19454b680903631d41f9e3607fbd941d296a020c2d752d \ + --hash=sha256:c882d69f6903ef6092bedfb7be973d9319940d56b8427ab9187d1ecd73438a70 \ + --hash=sha256:cb467c999c2eff23a6417e58d75e5828716f42ed8289fe6b77a7e5a91036ca70 \ + --hash=sha256:cdab464fee731e0884c35ae3588514a9bcf718d0e2c82169c1c4a85cc19c3c7f \ + --hash=sha256:ce19e06cbda693e9e7686358af9cd6f5d61312ab8b00488bc36f5aabbaf77e24 \ + --hash=sha256:ce70f96a46b894b36eba678f153f052967a0d06d5b5a19b336ab0dbbd029f73e \ + --hash=sha256:cf57a27fb986c6243d2ee78392c503826056ffe0287e8794503b10fb51b881be \ + --hash=sha256:d1715143123baeeaeadec0528bb7441103979a1d5f6fd0e1f915383fea7ea6d5 \ + --hash=sha256:d6ff426a7cb54f310d51bfe83fe9f2bbe40d540c741dc974ebc30e6aa238f52e \ + --hash=sha256:d7e7067c98040d646982daa1f37a33d3544138ea155536c2e0e63e07ff8a7e0f \ + --hash=sha256:db476ab59b6765134de1d4fe96a1a9c96ddf091683599be0f26147ea1b2e4b88 \ + --hash=sha256:dcc5c24523771db3a294c77d94771abcfcb82a0e0ee8efd910c37c59ec1b31bb \ + --hash=sha256:de6da501c883f58ad50db3a32ad397b09ad29865b5f26f64c24d3e3281685849 \ + --hash=sha256:e84087b432b6ac94778de547e08611266f1f8ffad28c0ee4c82e028b0fc5966d \ + --hash=sha256:eef58232d32daf2ac67f42dea51a2c80f0d03379075d44a587051e63cc2e368c \ + --hash=sha256:f096076119da54a6080e8920cbdaac3dbee667eb91dcc5e5b78840b87415bd44 \ + --hash=sha256:f0ab1c1af0cb38e3f598244c17919fb1a84d1629cc08355b0074b6d7f53138ac \ + --hash=sha256:f27db948078f3823a6bb3b465180db8ebecf26dd5dae6f6180bd87383b6b4428 \ + --hash=sha256:f537afb3276d12814082a2e9b242bdcf416c2e8fd9f799a737990a1dbe906e5b \ + --hash=sha256:f57b396167a2565a4e8b5e56a5a1c537571733992b226f4f1197d79e94cf0ae5 \ + --hash=sha256:f8979280bdafff686ba5e4d8f97840f929a87ed9cdf133cbbd42f7766774d2aa \ + --hash=sha256:f9a2ae5c91cecc9edd47e041a930490c31c3afb1f5e6d71de3dc671bfaca02bf # via sphinx-autobuild websockets==15.0.1 \ --hash=sha256:0701bc3cfcb9164d04a14b149fd74be7347a530ad3bbf15ab2c678a2cd3dd9a2 \ From d6062435ff9379ccbf1016c8d937b291fb139b4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Stasiak?= Date: Fri, 29 Aug 2025 15:15:34 +0200 Subject: [PATCH 0012/3659] tests: drivers: timer: nrf_grtc_timer: wait for coverage dump MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If test is to be run in coverage mode, wait for output to dump at the end of a failing testcase. Signed-off-by: Michał Stasiak --- tests/drivers/timer/nrf_grtc_timer/src/main.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/drivers/timer/nrf_grtc_timer/src/main.c b/tests/drivers/timer/nrf_grtc_timer/src/main.c index a6c3867ec314..bea349eb7eae 100644 --- a/tests/drivers/timer/nrf_grtc_timer/src/main.c +++ b/tests/drivers/timer/nrf_grtc_timer/src/main.c @@ -397,6 +397,13 @@ static void grtc_stress_test(bool busy_sim_en) if (counter_dev) { counter_stop(counter_dev); } + +#ifdef CONFIG_COVERAGE + /* Wait a few seconds before exit, giving the test the + * opportunity to dump some output before coverage data gets emitted + */ + k_sleep(K_MSEC(5000)); +#endif } ZTEST(nrf_grtc_timer, test_stress) From 6a336abb3c2ce3a5d2be010d1bbd6b56fc2e936d Mon Sep 17 00:00:00 2001 From: Alain Volmat Date: Mon, 10 Nov 2025 19:20:43 +0100 Subject: [PATCH 0013/3659] boards: stm32: correct LTDC panel pixel-format to RGB888 LTDC pixel-format property has been wrongly set to various values so far without being actually used by the LTDC driver itself. This property describes the format of the output of the LTDC (aka format of data between the LTDC and a panel or between the LTDC and the MIPI-DSI block). Currently only RGB888 is supported. Signed-off-by: Alain Volmat --- boards/ruiside/art_pi/art_pi.dts | 2 +- .../boards/arduino_giga_r1_m7.overlay | 2 +- boards/shields/st_lcd_dsi_mb1835/st_lcd_dsi_mb1835.overlay | 2 +- boards/st/stm32f429i_disc1/stm32f429i_disc1.dts | 2 +- boards/st/stm32f746g_disco/stm32f746g_disco.dts | 2 +- boards/st/stm32f7508_dk/stm32f7508_dk.dts | 2 +- boards/st/stm32h750b_dk/stm32h750b_dk-common.dtsi | 2 +- boards/st/stm32h7b3i_dk/stm32h7b3i_dk.dts | 2 +- boards/st/stm32h7s78_dk/stm32h7s78_dk-common.dtsi | 2 +- boards/st/stm32mp135f_dk/stm32mp135f_dk.dts | 2 +- boards/st/stm32n6570_dk/stm32n6570_dk_common.dtsi | 2 +- boards/witte/linum/linum.dts | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-) diff --git a/boards/ruiside/art_pi/art_pi.dts b/boards/ruiside/art_pi/art_pi.dts index bf5836571e86..64d71fb2a341 100644 --- a/boards/ruiside/art_pi/art_pi.dts +++ b/boards/ruiside/art_pi/art_pi.dts @@ -195,7 +195,7 @@ clocks = <&rcc STM32_CLOCK(APB3, 3)>, <&rcc STM32_SRC_PLL3_R NO_SEL>; width = <800>; height = <480>; - pixel-format = ; + pixel-format = ; def-back-color-red = <0X00>; def-back-color-green = <0X00>; def-back-color-blue = <0X00>; diff --git a/boards/shields/arduino_giga_display_shield/boards/arduino_giga_r1_m7.overlay b/boards/shields/arduino_giga_display_shield/boards/arduino_giga_r1_m7.overlay index 6ad74c37e098..b13586a53865 100644 --- a/boards/shields/arduino_giga_display_shield/boards/arduino_giga_r1_m7.overlay +++ b/boards/shields/arduino_giga_display_shield/boards/arduino_giga_r1_m7.overlay @@ -30,7 +30,7 @@ def-back-color-red = <0>; def-back-color-green = <0>; def-back-color-blue = <0>; - pixel-format = ; + pixel-format = ; disp-on-gpios = <&gpioc 6 GPIO_ACTIVE_HIGH>; bl-ctrl-gpios = <&gpiob 12 GPIO_ACTIVE_HIGH>; diff --git a/boards/shields/st_lcd_dsi_mb1835/st_lcd_dsi_mb1835.overlay b/boards/shields/st_lcd_dsi_mb1835/st_lcd_dsi_mb1835.overlay index a75f8b0316fa..83ed47ed47cc 100644 --- a/boards/shields/st_lcd_dsi_mb1835/st_lcd_dsi_mb1835.overlay +++ b/boards/shields/st_lcd_dsi_mb1835/st_lcd_dsi_mb1835.overlay @@ -89,7 +89,7 @@ status = "okay"; width = <480>; height = <480>; - pixel-format = ; + pixel-format = ; bl-ctrl-gpios = <&dsi_lcd_qsh_030 53 GPIO_ACTIVE_HIGH>; diff --git a/boards/st/stm32f429i_disc1/stm32f429i_disc1.dts b/boards/st/stm32f429i_disc1/stm32f429i_disc1.dts index 1b08ed28a637..e1b2b01f196e 100644 --- a/boards/st/stm32f429i_disc1/stm32f429i_disc1.dts +++ b/boards/st/stm32f429i_disc1/stm32f429i_disc1.dts @@ -248,7 +248,7 @@ width = <240>; height = <320>; - pixel-format = ; + pixel-format = ; display-timings { compatible = "zephyr,panel-timing"; diff --git a/boards/st/stm32f746g_disco/stm32f746g_disco.dts b/boards/st/stm32f746g_disco/stm32f746g_disco.dts index b235b8caaf79..70a3c642b70e 100644 --- a/boards/st/stm32f746g_disco/stm32f746g_disco.dts +++ b/boards/st/stm32f746g_disco/stm32f746g_disco.dts @@ -298,7 +298,7 @@ zephyr_udc0: &usbotg_fs { width = <480>; height = <272>; - pixel-format = ; + pixel-format = ; display-timings { compatible = "zephyr,panel-timing"; diff --git a/boards/st/stm32f7508_dk/stm32f7508_dk.dts b/boards/st/stm32f7508_dk/stm32f7508_dk.dts index 4ac9c1c36b35..e51f027ce091 100644 --- a/boards/st/stm32f7508_dk/stm32f7508_dk.dts +++ b/boards/st/stm32f7508_dk/stm32f7508_dk.dts @@ -285,7 +285,7 @@ zephyr_udc0: &usbotg_fs { width = <480>; height = <272>; - pixel-format = ; + pixel-format = ; display-timings { compatible = "zephyr,panel-timing"; diff --git a/boards/st/stm32h750b_dk/stm32h750b_dk-common.dtsi b/boards/st/stm32h750b_dk/stm32h750b_dk-common.dtsi index 57957b224180..3e4349c33bb2 100644 --- a/boards/st/stm32h750b_dk/stm32h750b_dk-common.dtsi +++ b/boards/st/stm32h750b_dk/stm32h750b_dk-common.dtsi @@ -99,7 +99,7 @@ width = <480>; height = <272>; - pixel-format = ; + pixel-format = ; display-timings { compatible = "zephyr,panel-timing"; diff --git a/boards/st/stm32h7b3i_dk/stm32h7b3i_dk.dts b/boards/st/stm32h7b3i_dk/stm32h7b3i_dk.dts index a19e67548d3f..043368160055 100644 --- a/boards/st/stm32h7b3i_dk/stm32h7b3i_dk.dts +++ b/boards/st/stm32h7b3i_dk/stm32h7b3i_dk.dts @@ -254,7 +254,7 @@ st_cam_i2c: &i2c4 { width = <480>; height = <272>; - pixel-format = ; + pixel-format = ; display-timings { compatible = "zephyr,panel-timing"; diff --git a/boards/st/stm32h7s78_dk/stm32h7s78_dk-common.dtsi b/boards/st/stm32h7s78_dk/stm32h7s78_dk-common.dtsi index 7b53339adace..07a1ac1807f6 100644 --- a/boards/st/stm32h7s78_dk/stm32h7s78_dk-common.dtsi +++ b/boards/st/stm32h7s78_dk/stm32h7s78_dk-common.dtsi @@ -332,7 +332,7 @@ zephyr_udc0: &usb2 {}; width = <800>; height = <480>; - pixel-format = ; + pixel-format = ; display-timings { compatible = "zephyr,panel-timing"; diff --git a/boards/st/stm32mp135f_dk/stm32mp135f_dk.dts b/boards/st/stm32mp135f_dk/stm32mp135f_dk.dts index 09cd25a7ee63..5fd5373323e8 100644 --- a/boards/st/stm32mp135f_dk/stm32mp135f_dk.dts +++ b/boards/st/stm32mp135f_dk/stm32mp135f_dk.dts @@ -247,7 +247,7 @@ csi_interface: &dcmipp { width = <480>; height = <272>; - pixel-format = ; + pixel-format = ; display-timings { compatible = "zephyr,panel-timing"; diff --git a/boards/st/stm32n6570_dk/stm32n6570_dk_common.dtsi b/boards/st/stm32n6570_dk/stm32n6570_dk_common.dtsi index ecb543d69ca2..ded1c0219998 100644 --- a/boards/st/stm32n6570_dk/stm32n6570_dk_common.dtsi +++ b/boards/st/stm32n6570_dk/stm32n6570_dk_common.dtsi @@ -503,7 +503,7 @@ zephyr_udc0: &usbotg_hs1 { width = <800>; height = <480>; - pixel-format = ; + pixel-format = ; display-timings { compatible = "zephyr,panel-timing"; diff --git a/boards/witte/linum/linum.dts b/boards/witte/linum/linum.dts index 312326fc5637..5bca36dd8e86 100644 --- a/boards/witte/linum/linum.dts +++ b/boards/witte/linum/linum.dts @@ -389,7 +389,7 @@ zephyr_udc0: &usbotg_fs { status = "okay"; width = <1024>; height = <600>; - pixel-format = ; + pixel-format = ; display-timings { compatible = "zephyr,panel-timing"; From 73ca8c9f76d3de661178ee1b8431a2c7dc3429a8 Mon Sep 17 00:00:00 2001 From: Alain Volmat Date: Mon, 10 Nov 2025 19:07:07 +0100 Subject: [PATCH 0014/3659] display: stm32-ltdc: clarify pixel-format property of lcd_controller So far the LTDC driver has not be using the pixel-format property defined in the lcd_controller bindings. This property describes the format of the panel connected to the LTDC output. It is not to be confused with the format of the LTDC layers (aka format of data stored into the framebuffer). The LTDC accepts various input formats while in most cases only RGB888 is supported for output. RGB666 is also supported by enabling Dithering however it is not supported currently by the driver. Enforce verification of the pixel-format given to the LTDC device-tree by checking that it matches with the platform supported formats. Signed-off-by: Alain Volmat --- drivers/display/display_stm32_ltdc.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/display/display_stm32_ltdc.c b/drivers/display/display_stm32_ltdc.c index 5d1ac60d8182..da4c26ab8b96 100644 --- a/drivers/display/display_stm32_ltdc.c +++ b/drivers/display/display_stm32_ltdc.c @@ -573,6 +573,11 @@ static DEVICE_API(display, stm32_ltdc_display_api) = { frame_buffer_##inst[CONFIG_STM32_LTDC_FB_NUM * STM32_LTDC_FRAME_BUFFER_LEN(inst)]; #endif +/* LTDC supports RGB888 and RGB666 for output however only RGB_888 is supported for now */ +#if DT_INST_PROP(0, pixel_format) != PANEL_PIXEL_FORMAT_RGB_888 +#error "Only RGB_888 is supported as a LTDC output (aka panel or mipi-dsi input format)" +#endif + #define STM32_LTDC_DEVICE(inst) \ STM32_LTDC_FRAME_BUFFER_DEFINE(inst); \ STM32_LTDC_DEVICE_PINCTRL_INIT(inst); \ From d0c45d981a709224624aa30451e44535787110ad Mon Sep 17 00:00:00 2001 From: Alain Volmat Date: Mon, 10 Nov 2025 21:33:17 +0100 Subject: [PATCH 0015/3659] drivers: mipi_dsi: configure DSI host using pixelformat from panel Use the pixelformat information provided by the DSI panel in order to control the color coding of the DSI host. Signed-off-by: Alain Volmat --- drivers/mipi_dsi/dsi_stm32.c | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/drivers/mipi_dsi/dsi_stm32.c b/drivers/mipi_dsi/dsi_stm32.c index 95be4b74b9c1..cb1ffbb56c48 100644 --- a/drivers/mipi_dsi/dsi_stm32.c +++ b/drivers/mipi_dsi/dsi_stm32.c @@ -21,16 +21,6 @@ LOG_MODULE_REGISTER(dsi_stm32, CONFIG_MIPI_DSI_LOG_LEVEL); -#if defined(CONFIG_STM32_LTDC_ARGB8888) -#define STM32_DSI_INIT_PIXEL_FORMAT DSI_RGB888 -#elif defined(CONFIG_STM32_LTDC_RGB888) -#define STM32_DSI_INIT_PIXEL_FORMAT DSI_RGB888 -#elif defined(CONFIG_STM32_LTDC_RGB565) -#define STM32_DSI_INIT_PIXEL_FORMAT DSI_RGB565 -#else -#error "Invalid LTDC pixel format chosen" -#endif /* CONFIG_STM32_LTDC_ARGB8888 */ - #define MAX_TX_ESC_CLK_KHZ 20000 #define MAX_TX_ESC_CLK_DIV 8 @@ -272,6 +262,21 @@ static int mipi_dsi_stm32_host_init(const struct device *dev) return 0; } +static int mipi_dsi_stm32_set_colorcoding(uint32_t pixfmt, uint32_t *colorcoding) +{ + switch (pixfmt) { + case MIPI_DSI_PIXFMT_RGB888: + *colorcoding = DSI_RGB888; + break; + case MIPI_DSI_PIXFMT_RGB565: + *colorcoding = DSI_RGB565; + break; + default: + return -EINVAL; + } + + return 0; +} static int mipi_dsi_stm32_attach(const struct device *dev, uint8_t channel, const struct mipi_dsi_device *mdev) @@ -287,7 +292,10 @@ static int mipi_dsi_stm32_attach(const struct device *dev, uint8_t channel, } vcfg->VirtualChannelID = channel; - vcfg->ColorCoding = STM32_DSI_INIT_PIXEL_FORMAT; + if (mipi_dsi_stm32_set_colorcoding(mdev->pixfmt, &vcfg->ColorCoding) < 0) { + LOG_ERR("MIPI PIXFMT not supported by the DSI host"); + return -ENOTSUP; + } if (mdev->mode_flags & MIPI_DSI_MODE_VIDEO_BURST) { vcfg->Mode = DSI_VID_MODE_BURST; From 366f337743868adf830533103b614856174f29ce Mon Sep 17 00:00:00 2001 From: Alain Volmat Date: Fri, 5 Dec 2025 21:40:57 +0100 Subject: [PATCH 0016/3659] dts: bindings: display: clarify lcd-controller pixel-format Clarify the pixel-format property of a lcd-controller in order to indicate that this is the pixel-format of data generated by the lcd-controller, not only for a panel attached to this controller but also for another device such as interface converter which would be receiving the data from the lcd-controller. Signed-off-by: Alain Volmat --- dts/bindings/display/lcd-controller.yaml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dts/bindings/display/lcd-controller.yaml b/dts/bindings/display/lcd-controller.yaml index 02bfb11ca8da..e4d983e7639f 100644 --- a/dts/bindings/display/lcd-controller.yaml +++ b/dts/bindings/display/lcd-controller.yaml @@ -10,5 +10,6 @@ properties: type: int required: true description: | - Initial Pixel format for panel attached to this controller. - See dt-bindings/display/panel.h for a list + Initial Pixel format of this controller's output data, which is sent + to a panel directly or to an adapter. + See dt-bindings/display/panel.h for a list of pixel format. From 452e0019321dcddfd2d001498f869632006d91b9 Mon Sep 17 00:00:00 2001 From: cyliang tw Date: Fri, 14 Nov 2025 16:42:26 +0800 Subject: [PATCH 0017/3659] dts: arm: nuvoton: add adc node of numaker m333x Update m333x.dtsi, to add adc node for adc driver support. Signed-off-by: cyliang tw --- dts/arm/nuvoton/m333x.dtsi | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/dts/arm/nuvoton/m333x.dtsi b/dts/arm/nuvoton/m333x.dtsi index 495286d210f2..d171127313d8 100644 --- a/dts/arm/nuvoton/m333x.dtsi +++ b/dts/arm/nuvoton/m333x.dtsi @@ -11,6 +11,7 @@ #include #include #include +#include / { chosen { @@ -325,6 +326,19 @@ #size-cells = <0>; status = "disabled"; }; + + eadc0: eadc@40043000 { + compatible = "nuvoton,numaker-adc"; + reg = <0x40043000 0x1000>; + interrupts = <42 0>; + resets = <&rst NUMAKER_EADC0_RST>; + clocks = <&pcc NUMAKER_EADC0_MODULE + NUMAKER_CLK_CLKSEL0_EADC0SEL_HCLK + NUMAKER_CLK_CLKDIV0_EADC0(12)>; + channels = <19>; + status = "disabled"; + #io-channel-cells = <1>; + }; }; }; From 8f13b37763293aa30d5f938f8e03353e88a94279 Mon Sep 17 00:00:00 2001 From: cyliang tw Date: Fri, 14 Nov 2025 16:44:58 +0800 Subject: [PATCH 0018/3659] tests: drivers: adc: adc_api: support numaker_m3334ki Add support for Nuvoton numaker board numaker_m3334ki. Signed-off-by: cyliang tw --- .../adc/adc_api/boards/numaker_m3334ki.conf | 1 + .../adc_api/boards/numaker_m3334ki.overlay | 40 +++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 tests/drivers/adc/adc_api/boards/numaker_m3334ki.conf create mode 100644 tests/drivers/adc/adc_api/boards/numaker_m3334ki.overlay diff --git a/tests/drivers/adc/adc_api/boards/numaker_m3334ki.conf b/tests/drivers/adc/adc_api/boards/numaker_m3334ki.conf new file mode 100644 index 000000000000..9fb2581d7f4a --- /dev/null +++ b/tests/drivers/adc/adc_api/boards/numaker_m3334ki.conf @@ -0,0 +1 @@ +CONFIG_TEST_USERSPACE=n diff --git a/tests/drivers/adc/adc_api/boards/numaker_m3334ki.overlay b/tests/drivers/adc/adc_api/boards/numaker_m3334ki.overlay new file mode 100644 index 000000000000..518379facf09 --- /dev/null +++ b/tests/drivers/adc/adc_api/boards/numaker_m3334ki.overlay @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +/ { + zephyr,user { + io-channels = <&eadc0 0>, <&eadc0 2>; + }; +}; + +&pinctrl { + /* EVB's UNO Pin A4 & D0 for channel 0 & 2 --> PB0, PB2 */ + eadc0_default: eadc0_default { + group0 { + pinmux = , ; + }; + }; +}; + +&eadc0 { + status = "okay"; + pinctrl-0 = <&eadc0_default>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + + channel@0 { + reg = <0>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <10>; + }; + + channel@2 { + reg = <2>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <10>; + }; +}; From 88495301d359d57ebd0e0b0a5b95fd8fbbe5084f Mon Sep 17 00:00:00 2001 From: Tomasz Chyrowicz Date: Fri, 21 Nov 2025 12:05:44 +0100 Subject: [PATCH 0019/3659] flash_map: Add a macro to fetch controller ID Add a macro that allows to get the node identifier of the flash controller the area/partition resides on. Signed-off-by: Tomasz Chyrowicz --- include/zephyr/storage/flash_map.h | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/include/zephyr/storage/flash_map.h b/include/zephyr/storage/flash_map.h index 6ce33c859632..7771e14a0e7b 100644 --- a/include/zephyr/storage/flash_map.h +++ b/include/zephyr/storage/flash_map.h @@ -19,7 +19,7 @@ * * @defgroup flash_area_api flash area Interface * @since 1.11 - * @version 1.0.0 + * @version 1.1.0 * @ingroup storage_apis * @{ */ @@ -465,6 +465,32 @@ uint8_t flash_area_erased_val(const struct flash_area *fa); (DT_MTD_FROM_FIXED_SUBPARTITION(node)), \ (DT_MTD_FROM_FIXED_PARTITION(node)))) +/** + * Get the node identifier of the flash controller the area/partition resides on + * + * @param label DTS node label of a partition + * + * @return Pointer to a device. + */ +#define FIXED_PARTITION_MTD(label) \ + COND_CODE_1( \ + DT_FIXED_SUBPARTITION_EXISTS(DT_NODELABEL(label)), \ + (DT_MTD_FROM_FIXED_SUBPARTITION(DT_NODELABEL(label))), \ + (DT_MTD_FROM_FIXED_PARTITION(DT_NODELABEL(label)))) + +/** + * Get the node identifier of the flash controller the area/partition resides on + * + * @param node DTS node of a partition + * + * @return Pointer to a device. + */ +#define FIXED_PARTITION_NODE_MTD(node) \ + COND_CODE_1( \ + DT_FIXED_SUBPARTITION_EXISTS(node), \ + (DT_MTD_FROM_FIXED_SUBPARTITION(node)), \ + (DT_MTD_FROM_FIXED_PARTITION(node))) + /** * Get pointer to flash_area object by partition label * From f7e1d0c768f06ab0795e3d4a71b31472da44d1c9 Mon Sep 17 00:00:00 2001 From: Tomasz Chyrowicz Date: Thu, 20 Nov 2025 15:18:09 +0100 Subject: [PATCH 0020/3659] soc: Use absolute address in active partition Use absolute addresses while determining a running application partition. Signed-off-by: Tomasz Chyrowicz --- soc/nordic/nrf54h/soc.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/soc/nordic/nrf54h/soc.c b/soc/nordic/nrf54h/soc.c index 5bf3dfad1f12..c52456f03be6 100644 --- a/soc/nordic/nrf54h/soc.c +++ b/soc/nordic/nrf54h/soc.c @@ -40,14 +40,20 @@ LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); DT_REG_ADDR(COND_CODE_1(DT_FIXED_SUBPARTITION_EXISTS(DT_NODELABEL(label)), \ (DT_GPARENT(DT_PARENT(DT_NODELABEL(label)))), \ (DT_GPARENT(DT_NODELABEL(label)))))) +#define FIXED_PARTITION_NODE_MTD(node) \ + COND_CODE_1( \ + DT_FIXED_SUBPARTITION_EXISTS(node), \ + (DT_MTD_FROM_FIXED_SUBPARTITION(node)), \ + (DT_MTD_FROM_FIXED_PARTITION(node))) #ifdef CONFIG_USE_DT_CODE_PARTITION #define FLASH_LOAD_OFFSET DT_REG_ADDR(DT_CHOSEN(zephyr_code_partition)) #elif defined(CONFIG_FLASH_LOAD_OFFSET) #define FLASH_LOAD_OFFSET CONFIG_FLASH_LOAD_OFFSET #endif - -#define PARTITION_IS_RUNNING_APP_PARTITION(label) \ +#define FIXED_PARTITION_IS_RUNNING_APP_PARTITION(label) \ + DT_SAME_NODE(FIXED_PARTITION_NODE_MTD(DT_CHOSEN(zephyr_code_partition)), \ + FIXED_PARTITION_NODE_MTD(DT_NODELABEL(label))) && \ (DT_REG_ADDR(DT_NODELABEL(label)) <= FLASH_LOAD_OFFSET && \ DT_REG_ADDR(DT_NODELABEL(label)) + DT_REG_SIZE(DT_NODELABEL(label)) > FLASH_LOAD_OFFSET) @@ -198,7 +204,7 @@ void soc_late_init_hook(void) void *radiocore_address = NULL; #if DT_NODE_EXISTS(DT_NODELABEL(cpurad_slot1_partition)) - if (PARTITION_IS_RUNNING_APP_PARTITION(cpuapp_slot1_partition)) { + if (FIXED_PARTITION_IS_RUNNING_APP_PARTITION(cpuapp_slot1_partition)) { radiocore_address = (void *)(FIXED_PARTITION_ADDRESS(cpurad_slot1_partition) + CONFIG_ROM_START_OFFSET); } else { From 276ebfcf2490b88064bf48ff2c375c5b15b5dc93 Mon Sep 17 00:00:00 2001 From: Tomasz Chyrowicz Date: Thu, 20 Nov 2025 15:19:09 +0100 Subject: [PATCH 0021/3659] img_util: Use absolute address in active partition Use absolute addresses while determining a running application partition. Signed-off-by: Tomasz Chyrowicz --- subsys/dfu/img_util/flash_img.c | 8 ++------ tests/subsys/dfu/img_util/src/main.c | 8 ++------ 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/subsys/dfu/img_util/flash_img.c b/subsys/dfu/img_util/flash_img.c index 152aaabe17ae..d3c9749401b2 100644 --- a/subsys/dfu/img_util/flash_img.c +++ b/subsys/dfu/img_util/flash_img.c @@ -24,13 +24,9 @@ LOG_MODULE_REGISTER(flash_img, CONFIG_IMG_MANAGER_LOG_LEVEL); #include #endif -#define FIXED_PARTITION_GET_FLASH_NODE(node_id) \ - COND_CODE_1(DT_NODE_HAS_COMPAT(DT_PARENT(node_id), fixed_subpartitions), \ - (DT_PARENT(DT_GPARENT(node_id))), (DT_GPARENT(node_id))) - #define FIXED_PARTITION_IS_RUNNING_APP_PARTITION(label) \ - DT_SAME_NODE(FIXED_PARTITION_GET_FLASH_NODE(DT_CHOSEN(zephyr_code_partition)), \ - FIXED_PARTITION_GET_FLASH_NODE(DT_NODELABEL(label))) && \ + DT_SAME_NODE(FIXED_PARTITION_NODE_MTD(DT_CHOSEN(zephyr_code_partition)), \ + FIXED_PARTITION_MTD(label)) && \ (FIXED_PARTITION_OFFSET(label) <= CONFIG_FLASH_LOAD_OFFSET && \ FIXED_PARTITION_OFFSET(label) + FIXED_PARTITION_SIZE(label) > CONFIG_FLASH_LOAD_OFFSET) diff --git a/tests/subsys/dfu/img_util/src/main.c b/tests/subsys/dfu/img_util/src/main.c index 013498f49bd3..c0b5d96daeb1 100644 --- a/tests/subsys/dfu/img_util/src/main.c +++ b/tests/subsys/dfu/img_util/src/main.c @@ -13,13 +13,9 @@ #define SLOT0_PARTITION slot0_partition #define SLOT1_PARTITION slot1_partition -#define FIXED_PARTITION_GET_FLASH_NODE(node_id) \ - COND_CODE_1(DT_NODE_HAS_COMPAT(DT_PARENT(node_id), fixed_subpartitions), \ - (DT_PARENT(DT_GPARENT(node_id))), (DT_GPARENT(node_id))) - #define FIXED_PARTITION_IS_RUNNING_APP_PARTITION(label) \ - DT_SAME_NODE(FIXED_PARTITION_GET_FLASH_NODE(DT_CHOSEN(zephyr_code_partition)), \ - FIXED_PARTITION_GET_FLASH_NODE(DT_NODELABEL(label))) && \ + DT_SAME_NODE(FIXED_PARTITION_NODE_MTD(DT_CHOSEN(zephyr_code_partition)), \ + FIXED_PARTITION_MTD(label)) && \ (FIXED_PARTITION_OFFSET(label) <= CONFIG_FLASH_LOAD_OFFSET && \ FIXED_PARTITION_OFFSET(label) + FIXED_PARTITION_SIZE(label) > CONFIG_FLASH_LOAD_OFFSET) From 764f0d183bc06d92acf6fb5ebabd17ef1a913add Mon Sep 17 00:00:00 2001 From: Tomasz Chyrowicz Date: Thu, 20 Nov 2025 15:20:23 +0100 Subject: [PATCH 0022/3659] img_mgmt: Use absolute address in active partition Use absolute addresses while determining a running application partition. Signed-off-by: Tomasz Chyrowicz --- subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c index b25b42fa09f8..7947b89bcdaf 100644 --- a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c +++ b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c @@ -48,13 +48,9 @@ to be able to figure out application running slot. #endif -#define FIXED_PARTITION_GET_FLASH_NODE(node_id) \ - COND_CODE_1(DT_NODE_HAS_COMPAT(DT_PARENT(node_id), fixed_subpartitions), \ - (DT_PARENT(DT_GPARENT(node_id))), (DT_GPARENT(node_id))) - #define FIXED_PARTITION_IS_RUNNING_APP_PARTITION(label) \ - DT_SAME_NODE(FIXED_PARTITION_GET_FLASH_NODE(DT_CHOSEN(zephyr_code_partition)), \ - FIXED_PARTITION_GET_FLASH_NODE(DT_NODELABEL(label))) && \ + DT_SAME_NODE(FIXED_PARTITION_NODE_MTD(DT_CHOSEN(zephyr_code_partition)), \ + FIXED_PARTITION_MTD(label)) && \ (FIXED_PARTITION_OFFSET(label) <= CONFIG_FLASH_LOAD_OFFSET && \ FIXED_PARTITION_OFFSET(label) + FIXED_PARTITION_SIZE(label) > CONFIG_FLASH_LOAD_OFFSET) From 75ff93ae211c8dd66de53f764f4bdd098aafe0fe Mon Sep 17 00:00:00 2001 From: Lyle Zhu Date: Wed, 26 Nov 2025 11:37:36 +0800 Subject: [PATCH 0023/3659] Bluetooth: Classic: HFP: Fix SCO conn cannot be released issue There is an issue found that the sco conn cannot be released when the SCO has been disconnected. The sco conn count is referred in the sco connected callback due to the `sco_conn` is NULL while `sco_conn` should not be NULL when the sco connected callback is triggered. It is a race condition issue where the sco connected callback is triggered before `sco_conn` is updated. The sco conn reference count has been referred incorrectly, actually it should not be referred. Replace direct pointer access to `sco_conn` with atomic operations to prevent race conditions in concurrent SCO connection scenarios. If the value of `sco_conn` is not NULL when trying to set the return value of `bt_conn_create_sco()` to `sco_conn`, it means the race condition occurs. In this situation, discount the sco conn reference count to fix the issue. Signed-off-by: Lyle Zhu --- subsys/bluetooth/host/classic/hfp_ag.c | 81 ++++++++++++------- .../bluetooth/host/classic/hfp_ag_internal.h | 2 +- subsys/bluetooth/host/classic/hfp_hf.c | 38 ++++++--- .../bluetooth/host/classic/hfp_hf_internal.h | 2 +- 4 files changed, 79 insertions(+), 44 deletions(-) diff --git a/subsys/bluetooth/host/classic/hfp_ag.c b/subsys/bluetooth/host/classic/hfp_ag.c index 2a0754eac377..9b7b639e7219 100644 --- a/subsys/bluetooth/host/classic/hfp_ag.c +++ b/subsys/bluetooth/host/classic/hfp_ag.c @@ -772,7 +772,7 @@ static void bt_hfp_ag_set_call_state(struct bt_hfp_ag_call *call, bt_hfp_call_st static void hfp_ag_close_sco(struct bt_hfp_ag *ag) { - struct bt_conn *sco = NULL; + struct bt_conn *sco; int call_count; LOG_DBG(""); @@ -785,9 +785,9 @@ static void hfp_ag_close_sco(struct bt_hfp_ag *ag) return; } - if (ag->sco_conn != NULL) { - bt_conn_unref(ag->sco_conn); - ag->sco_conn = NULL; + sco = atomic_ptr_set(&ag->sco_conn, NULL); + if (sco != NULL) { + bt_conn_unref(sco); sco = ag->sco_chan.sco; } hfp_ag_unlock(ag); @@ -1450,8 +1450,8 @@ static void hfp_ag_sco_connected(struct bt_sco_chan *chan) { struct bt_hfp_ag *ag = CONTAINER_OF(chan, struct bt_hfp_ag, sco_chan); - if (ag->sco_conn == NULL) { - ag->sco_conn = bt_conn_ref(chan->sco); + if (atomic_ptr_cas(&ag->sco_conn, NULL, chan->sco)) { + bt_conn_ref(chan->sco); } if ((bt_ag) && bt_ag->sco_connected) { @@ -1462,14 +1462,15 @@ static void hfp_ag_sco_connected(struct bt_sco_chan *chan) static void hfp_ag_sco_disconnected(struct bt_sco_chan *chan, uint8_t reason) { struct bt_hfp_ag *ag = CONTAINER_OF(chan, struct bt_hfp_ag, sco_chan); + struct bt_conn *sco; if ((bt_ag != NULL) && bt_ag->sco_disconnected) { bt_ag->sco_disconnected(chan->sco, reason); } - if (ag->sco_conn != NULL) { - bt_conn_unref(ag->sco_conn); - ag->sco_conn = NULL; + sco = atomic_ptr_set(&ag->sco_conn, NULL); + if (sco != NULL) { + bt_conn_unref(sco); } } @@ -1506,32 +1507,51 @@ static struct bt_conn *bt_hfp_ag_create_sco(struct bt_hfp_ag *ag) .connected = hfp_ag_sco_connected, .disconnected = hfp_ag_sco_disconnected, }; + struct bt_conn *sco; + int err; + bool updated; LOG_DBG(""); - if (ag->sco_conn == NULL) { - int err; + sco = atomic_ptr_get(&ag->sco_conn); + if (sco != NULL) { + return sco; + } - ag->sco_chan.ops = &ops; + ag->sco_chan.ops = &ops; - err = hfp_ag_set_voice_setting(ag); - if (err < 0) { - LOG_ERR("Fail to set voice setting :(%d)", err); - return NULL; + err = hfp_ag_set_voice_setting(ag); + if (err < 0) { + LOG_ERR("Fail to set voice setting :(%d)", err); + return NULL; + } + + /* create SCO connection*/ + sco = bt_conn_create_sco(&ag->acl_conn->br.dst, &ag->sco_chan); + updated = atomic_ptr_cas(&ag->sco_conn, NULL, sco); + if (!updated) { + LOG_WRN("SCO is not NULL (%p), target (%p)", atomic_ptr_get(&ag->sco_conn), sco); + __ASSERT(atomic_ptr_get(&ag->sco_conn) == sco, + "Concurrent SCO connection creation detected"); + /* The `ag->sco_conn` has been updated in callback `hfp_ag_sco_connected()`. + * The reference count has been increased in callback `hfp_ag_sco_connected()`. + * The reference count should be decreased in this case. + */ + if (sco != NULL) { + LOG_DBG("Unreference SCO connection %p", sco); + bt_conn_unref(sco); } + } - /* create SCO connection*/ - ag->sco_conn = bt_conn_create_sco(&ag->acl_conn->br.dst, &ag->sco_chan); - if (ag->sco_conn != NULL) { - LOG_DBG("Created sco %p", ag->sco_conn); - if (ag->sco_chan.sco == NULL) { - /* SCO connection exists */ - LOG_WRN("SCO conn has been created outside"); - } + if (sco != NULL) { + LOG_DBG("Created sco %p", sco); + if (ag->sco_chan.sco == NULL) { + /* SCO connection exists */ + LOG_WRN("SCO conn has been created outside"); } } - return ag->sco_conn; + return sco; } static int hfp_ag_open_sco(struct bt_hfp_ag *ag, struct bt_hfp_ag_call *call) @@ -1544,7 +1564,7 @@ static int hfp_ag_open_sco(struct bt_hfp_ag *ag, struct bt_hfp_ag_call *call) } hfp_ag_lock(ag); - create_sco = (ag->sco_conn == NULL) ? true : false; + create_sco = atomic_ptr_get(&ag->sco_conn) == NULL ? true : false; if (create_sco) { atomic_set_bit(ag->flags, BT_HFP_AG_CREATING_SCO); } @@ -2702,7 +2722,7 @@ static int bt_hfp_ag_bcc_handler(struct bt_hfp_ag *ag, struct net_buf *buf) return -ENOTSUP; } - if (ag->sco_conn != NULL) { + if (atomic_ptr_get(&ag->sco_conn) != NULL) { hfp_ag_unlock(ag); return -ECONNREFUSED; } @@ -4300,9 +4320,8 @@ static void ag_sco_disconnected(struct bt_conn *conn, uint8_t reason) __ASSERT(conn != NULL, "Invalid SCO conn"); ARRAY_FOR_EACH(bt_hfp_ag_pool, i) { - if (bt_hfp_ag_pool[i].sco_conn == conn) { - bt_conn_unref(bt_hfp_ag_pool[i].sco_conn); - bt_hfp_ag_pool[i].sco_conn = NULL; + if (atomic_ptr_cas(&bt_hfp_ag_pool[i].sco_conn, conn, NULL)) { + bt_conn_unref(conn); } } } @@ -5127,7 +5146,7 @@ int bt_hfp_ag_audio_connect(struct bt_hfp_ag *ag, uint8_t id) } } - if (ag->sco_conn != NULL) { + if (atomic_ptr_get(&ag->sco_conn) != NULL) { LOG_ERR("Audio conenction has been connected"); hfp_ag_unlock(ag); return -ECONNREFUSED; diff --git a/subsys/bluetooth/host/classic/hfp_ag_internal.h b/subsys/bluetooth/host/classic/hfp_ag_internal.h index ba28f93b577f..fdc8d3006508 100644 --- a/subsys/bluetooth/host/classic/hfp_ag_internal.h +++ b/subsys/bluetooth/host/classic/hfp_ag_internal.h @@ -291,7 +291,7 @@ struct bt_hfp_ag { struct bt_sco_chan sco_chan; /* SCO connect */ - struct bt_conn *sco_conn; + atomic_ptr_t sco_conn; /* SDP discover params */ struct bt_sdp_discover_params sdp_param; diff --git a/subsys/bluetooth/host/classic/hfp_hf.c b/subsys/bluetooth/host/classic/hfp_hf.c index b0c65b40f5e1..42fbc6a714cf 100644 --- a/subsys/bluetooth/host/classic/hfp_hf.c +++ b/subsys/bluetooth/host/classic/hfp_hf.c @@ -3446,8 +3446,8 @@ static void hfp_hf_sco_connected(struct bt_sco_chan *chan) { struct bt_hfp_hf *hf = CONTAINER_OF(chan, struct bt_hfp_hf, chan); - if (hf->sco_conn == NULL) { - hf->sco_conn = bt_conn_ref(chan->sco); + if (atomic_ptr_cas(&hf->sco_conn, NULL, chan->sco)) { + bt_conn_ref(chan->sco); } if ((bt_hf != NULL) && (bt_hf->sco_connected != NULL)) { @@ -3458,14 +3458,15 @@ static void hfp_hf_sco_connected(struct bt_sco_chan *chan) static void hfp_hf_sco_disconnected(struct bt_sco_chan *chan, uint8_t reason) { struct bt_hfp_hf *hf = CONTAINER_OF(chan, struct bt_hfp_hf, chan); + struct bt_conn *sco; if ((bt_hf != NULL) && (bt_hf->sco_disconnected != NULL)) { bt_hf->sco_disconnected(chan->sco, reason); } - if (hf->sco_conn != NULL) { - bt_conn_unref(hf->sco_conn); - hf->sco_conn = NULL; + sco = atomic_ptr_set(&hf->sco_conn, NULL); + if (sco != NULL) { + bt_conn_unref(sco); } } @@ -3512,7 +3513,9 @@ static int hfp_hf_create_sco(struct bt_hfp_hf *hf) .connected = hfp_hf_sco_connected, .disconnected = hfp_hf_sco_disconnected, }; + struct bt_conn *sco; int err; + bool updated; LOG_DBG("Creating SCO connection"); @@ -3524,8 +3527,22 @@ static int hfp_hf_create_sco(struct bt_hfp_hf *hf) return err; } - hf->sco_conn = bt_conn_create_sco(&hf->acl->br.dst, &hf->chan); - if (hf->sco_conn == NULL) { + sco = bt_conn_create_sco(&hf->acl->br.dst, &hf->chan); + updated = atomic_ptr_cas(&hf->sco_conn, NULL, sco); + if (!updated) { + LOG_WRN("SCO is not NULL (%p), target (%p)", atomic_ptr_get(&hf->sco_conn), sco); + __ASSERT(atomic_ptr_get(&hf->sco_conn) == sco, + "Concurrent SCO connection creation detected"); + /* The `hf->sco_conn` has been udpated in callback `hfp_hf_sco_connected()`. + * The refernce count has been updated in callback `hfp_hf_sco_connected()`. + * The refernce count should be unreferred in this case. + */ + if (sco != NULL) { + bt_conn_unref(sco); + } + } + + if (sco == NULL) { LOG_ERR("Failed to create SCO"); return -ENOMEM; } @@ -3544,7 +3561,7 @@ int bt_hfp_hf_audio_connect(struct bt_hfp_hf *hf) return -ENOTCONN; } - if (hf->sco_conn != NULL) { + if (atomic_ptr_get(&hf->sco_conn) != NULL) { LOG_ERR("Audio conenction has been connected"); return -ECONNREFUSED; } @@ -4487,9 +4504,8 @@ static void hf_sco_disconnected(struct bt_conn *conn, uint8_t reason) __ASSERT(conn != NULL, "Invalid SCO conn"); ARRAY_FOR_EACH(bt_hfp_hf_pool, i) { - if (bt_hfp_hf_pool[i].sco_conn == conn) { - bt_conn_unref(bt_hfp_hf_pool[i].sco_conn); - bt_hfp_hf_pool[i].sco_conn = NULL; + if (atomic_ptr_cas(&bt_hfp_hf_pool[i].sco_conn, conn, NULL)) { + bt_conn_unref(conn); } } } diff --git a/subsys/bluetooth/host/classic/hfp_hf_internal.h b/subsys/bluetooth/host/classic/hfp_hf_internal.h index 96ef9f51bd94..26b9b90ae4b1 100644 --- a/subsys/bluetooth/host/classic/hfp_hf_internal.h +++ b/subsys/bluetooth/host/classic/hfp_hf_internal.h @@ -215,7 +215,7 @@ struct bt_hfp_hf { /* SCO Channel */ struct bt_sco_chan chan; /* SCO connect */ - struct bt_conn *sco_conn; + atomic_ptr_t sco_conn; /* SDP discover params */ struct bt_sdp_discover_params sdp_param; From 2571b7efa31c25c81c947caa26663ca1234f69b9 Mon Sep 17 00:00:00 2001 From: Lyle Zhu Date: Thu, 27 Nov 2025 16:05:42 +0800 Subject: [PATCH 0024/3659] Bluetooth: Classic: HFP_HF: Fix invalid indicator index issue A invalid indicator index will cause the underflow of the array `ag_ind` if the indicator index is not returned by AG in the response of AT command `AT+CIND=?`. Replace hardcoded `-1` values with HFP_HF_INDICATOR_INVALID constant for better code readability and maintainability. Add proper bounds checking to validate indicator indices before accessing the `ag_ind` array using the `ind_table` mapping. Signed-off-by: Lyle Zhu --- subsys/bluetooth/host/classic/hfp_hf.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/subsys/bluetooth/host/classic/hfp_hf.c b/subsys/bluetooth/host/classic/hfp_hf.c index 42fbc6a714cf..0caebcb34ca9 100644 --- a/subsys/bluetooth/host/classic/hfp_hf.c +++ b/subsys/bluetooth/host/classic/hfp_hf.c @@ -34,6 +34,8 @@ LOG_MODULE_REGISTER(bt_hfp_hf); #define MAX_IND_STR_LEN 17 +#define HFP_HF_INDICATOR_INVALID -1 + struct bt_hfp_hf_cb *bt_hf; NET_BUF_POOL_FIXED_DEFINE(hf_pool, CONFIG_BT_MAX_CONN + 1, @@ -1336,7 +1338,17 @@ void ag_indicator_handle_values(struct at_client *hf_at, uint32_t index, LOG_DBG("Index :%u, Value :%u", index, value); - if (index >= ARRAY_SIZE(ag_ind)) { + if (index >= ARRAY_SIZE(hf->ind_table)) { + LOG_ERR("Invalid indicator index: %u", index); + return; + } + + if (hf->ind_table[index] == HFP_HF_INDICATOR_INVALID) { + LOG_ERR("Indicator index %u not found", index); + return; + } + + if (hf->ind_table[index] >= ARRAY_SIZE(ag_ind)) { LOG_ERR("Max only %zu indicators are supported", ARRAY_SIZE(ag_ind)); return; } @@ -2790,7 +2802,8 @@ int bt_hfp_hf_indicator_status(struct bt_hfp_hf *hf, uint8_t status) bia_status = &buffer[0]; for (index = 0; index < ARRAY_SIZE(hf->ind_table); index++) { - if ((hf->ind_table[index] != -1) && (index < NUM_BITS(sizeof(status)))) { + if ((hf->ind_table[index] != HFP_HF_INDICATOR_INVALID) && + (index < NUM_BITS(sizeof(status)))) { if (status & BIT(hf->ind_table[index])) { *bia_status = '1'; } else { @@ -4433,8 +4446,8 @@ static struct bt_hfp_hf *hfp_hf_create(struct bt_conn *conn) k_work_init_delayable(&hf->deferred_work, bt_hf_deferred_work); - for (index = 0; index < ARRAY_SIZE(hf->ind_table); index++) { - hf->ind_table[index] = -1; + ARRAY_FOR_EACH(hf->ind_table, i) { + hf->ind_table[i] = HFP_HF_INDICATOR_INVALID; } return hf; From 7ebf2b337511ec4b12af49d44e0240b17350b004 Mon Sep 17 00:00:00 2001 From: Tony Han Date: Sun, 26 Oct 2025 07:00:00 +0800 Subject: [PATCH 0025/3659] dts: arm: microchip: sama7g5: reorganize and add dtsi files for SiPs Add dtsi files for SiPs and put all the dtsi files for sama7g5 to "dts/arm/microchip/sam/sama7/sama7g5". Update the path of dtsi in the board dts file accordingly. URL for SiP (System-in-Package): https://ww1.microchip.com/downloads/aemDocuments/documents/MPU32/ProductDocuments/DataSheets/SAMA7G5-SIP-Series-Data-Sheet-DS50003577.pdf Signed-off-by: Tony Han --- boards/microchip/sam/sama7g54_ek/sama7g54_ek.dts | 2 +- .../sam/{ => sama7/sama7g5}/sama7g5.dtsi | 0 dts/arm/microchip/sam/sama7/sama7g5/sama7g54.dtsi | 8 ++++++++ .../microchip/sam/sama7/sama7g5/sama7g54d1g.dtsi | 15 +++++++++++++++ .../microchip/sam/sama7/sama7g5/sama7g54d2g.dtsi | 15 +++++++++++++++ .../microchip/sam/sama7/sama7g5/sama7g54d4g.dtsi | 15 +++++++++++++++ 6 files changed, 54 insertions(+), 1 deletion(-) rename dts/arm/microchip/sam/{ => sama7/sama7g5}/sama7g5.dtsi (100%) create mode 100644 dts/arm/microchip/sam/sama7/sama7g5/sama7g54.dtsi create mode 100644 dts/arm/microchip/sam/sama7/sama7g5/sama7g54d1g.dtsi create mode 100644 dts/arm/microchip/sam/sama7/sama7g5/sama7g54d2g.dtsi create mode 100644 dts/arm/microchip/sam/sama7/sama7g5/sama7g54d4g.dtsi diff --git a/boards/microchip/sam/sama7g54_ek/sama7g54_ek.dts b/boards/microchip/sam/sama7g54_ek/sama7g54_ek.dts index 8a6a9695a595..9642f55d3049 100644 --- a/boards/microchip/sam/sama7g54_ek/sama7g54_ek.dts +++ b/boards/microchip/sam/sama7g54_ek/sama7g54_ek.dts @@ -13,7 +13,7 @@ #include #include #include -#include +#include / { model = "SAMA7G54-EK board"; diff --git a/dts/arm/microchip/sam/sama7g5.dtsi b/dts/arm/microchip/sam/sama7/sama7g5/sama7g5.dtsi similarity index 100% rename from dts/arm/microchip/sam/sama7g5.dtsi rename to dts/arm/microchip/sam/sama7/sama7g5/sama7g5.dtsi diff --git a/dts/arm/microchip/sam/sama7/sama7g5/sama7g54.dtsi b/dts/arm/microchip/sam/sama7/sama7g5/sama7g54.dtsi new file mode 100644 index 000000000000..ab1506ffbf62 --- /dev/null +++ b/dts/arm/microchip/sam/sama7/sama7g5/sama7g54.dtsi @@ -0,0 +1,8 @@ +/* + * Copyright (C) 2025 Microchip Technology Inc. and its subsidiaries + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +#include diff --git a/dts/arm/microchip/sam/sama7/sama7g5/sama7g54d1g.dtsi b/dts/arm/microchip/sam/sama7/sama7g5/sama7g54d1g.dtsi new file mode 100644 index 000000000000..eb09cf6fa6ee --- /dev/null +++ b/dts/arm/microchip/sam/sama7/sama7g5/sama7g54d1g.dtsi @@ -0,0 +1,15 @@ +/* + * Copyright (C) 2025 Microchip Technology Inc. and its subsidiaries + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +#include + +/ { + ddram: ddram@60000000 { + compatible = "ddram"; + reg = <0x60000000 DT_SIZE_M(128)>; + }; +}; diff --git a/dts/arm/microchip/sam/sama7/sama7g5/sama7g54d2g.dtsi b/dts/arm/microchip/sam/sama7/sama7g5/sama7g54d2g.dtsi new file mode 100644 index 000000000000..6854aaf19e7a --- /dev/null +++ b/dts/arm/microchip/sam/sama7/sama7g5/sama7g54d2g.dtsi @@ -0,0 +1,15 @@ +/* + * Copyright (C) 2025 Microchip Technology Inc. and its subsidiaries + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +#include + +/ { + ddram: ddram@60000000 { + compatible = "ddram"; + reg = <0x60000000 DT_SIZE_M(256)>; + }; +}; diff --git a/dts/arm/microchip/sam/sama7/sama7g5/sama7g54d4g.dtsi b/dts/arm/microchip/sam/sama7/sama7g5/sama7g54d4g.dtsi new file mode 100644 index 000000000000..6cb27b0a998b --- /dev/null +++ b/dts/arm/microchip/sam/sama7/sama7g5/sama7g54d4g.dtsi @@ -0,0 +1,15 @@ +/* + * Copyright (C) 2025 Microchip Technology Inc. and its subsidiaries + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +#include + +/ { + ddram: ddram@60000000 { + compatible = "ddram"; + reg = <0x60000000 DT_SIZE_M(512)>; + }; +}; From dc3a7199172be16dcfc26eda3774983d0e3088be Mon Sep 17 00:00:00 2001 From: Tony Han Date: Wed, 3 Dec 2025 10:22:02 +0800 Subject: [PATCH 0026/3659] dts: arm: microchip: sama7d6: reorganize and add dtsi files for SiPs Add dtsi files for SiPs and put all the dtsi files for sama7d6 to "dts/arm/microchip/sam/sama7/sama7d6". Update the path of dtsi in the board dts file accordingly. URL for SiP (System-in-Package): https://ww1.microchip.com/downloads/aemDocuments/documents/MPU32/ProductDocuments/DataSheets/SAMA7D6-Series-SiP-Data-Sheet-DS60001853.pdf Signed-off-by: Tony Han --- .../sam/sama7d65_curiosity/sama7d65_curiosity.dts | 2 +- .../sam/{ => sama7/sama7d6}/sama7d6.dtsi | 0 dts/arm/microchip/sam/sama7/sama7d6/sama7d65.dtsi | 8 ++++++++ .../microchip/sam/sama7/sama7d6/sama7d65d1g.dtsi | 15 +++++++++++++++ .../microchip/sam/sama7/sama7d6/sama7d65d2g.dtsi | 15 +++++++++++++++ .../microchip/sam/sama7/sama7d6/sama7d65d4g.dtsi | 15 +++++++++++++++ .../microchip/sam/sama7/sama7d6/sama7d65d5m.dtsi | 15 +++++++++++++++ 7 files changed, 69 insertions(+), 1 deletion(-) rename dts/arm/microchip/sam/{ => sama7/sama7d6}/sama7d6.dtsi (100%) create mode 100644 dts/arm/microchip/sam/sama7/sama7d6/sama7d65.dtsi create mode 100644 dts/arm/microchip/sam/sama7/sama7d6/sama7d65d1g.dtsi create mode 100644 dts/arm/microchip/sam/sama7/sama7d6/sama7d65d2g.dtsi create mode 100644 dts/arm/microchip/sam/sama7/sama7d6/sama7d65d4g.dtsi create mode 100644 dts/arm/microchip/sam/sama7/sama7d6/sama7d65d5m.dtsi diff --git a/boards/microchip/sam/sama7d65_curiosity/sama7d65_curiosity.dts b/boards/microchip/sam/sama7d65_curiosity/sama7d65_curiosity.dts index e6885b731319..04e03cce0f19 100644 --- a/boards/microchip/sam/sama7d65_curiosity/sama7d65_curiosity.dts +++ b/boards/microchip/sam/sama7d65_curiosity/sama7d65_curiosity.dts @@ -9,7 +9,7 @@ #include #include #include -#include +#include / { model = "SAMA7D65-Curiosity board"; diff --git a/dts/arm/microchip/sam/sama7d6.dtsi b/dts/arm/microchip/sam/sama7/sama7d6/sama7d6.dtsi similarity index 100% rename from dts/arm/microchip/sam/sama7d6.dtsi rename to dts/arm/microchip/sam/sama7/sama7d6/sama7d6.dtsi diff --git a/dts/arm/microchip/sam/sama7/sama7d6/sama7d65.dtsi b/dts/arm/microchip/sam/sama7/sama7d6/sama7d65.dtsi new file mode 100644 index 000000000000..46724720617c --- /dev/null +++ b/dts/arm/microchip/sam/sama7/sama7d6/sama7d65.dtsi @@ -0,0 +1,8 @@ +/* + * Copyright (C) 2025 Microchip Technology Inc. and its subsidiaries + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +#include diff --git a/dts/arm/microchip/sam/sama7/sama7d6/sama7d65d1g.dtsi b/dts/arm/microchip/sam/sama7/sama7d6/sama7d65d1g.dtsi new file mode 100644 index 000000000000..e89b439adb85 --- /dev/null +++ b/dts/arm/microchip/sam/sama7/sama7d6/sama7d65d1g.dtsi @@ -0,0 +1,15 @@ +/* + * Copyright (C) 2025 Microchip Technology Inc. and its subsidiaries + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +#include + +/ { + ddram: ddram@60000000 { + compatible = "ddram"; + reg = <0x60000000 DT_SIZE_M(128)>; + }; +}; diff --git a/dts/arm/microchip/sam/sama7/sama7d6/sama7d65d2g.dtsi b/dts/arm/microchip/sam/sama7/sama7d6/sama7d65d2g.dtsi new file mode 100644 index 000000000000..2093dc5f8f33 --- /dev/null +++ b/dts/arm/microchip/sam/sama7/sama7d6/sama7d65d2g.dtsi @@ -0,0 +1,15 @@ +/* + * Copyright (C) 2025 Microchip Technology Inc. and its subsidiaries + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +#include + +/ { + ddram: ddram@60000000 { + compatible = "ddram"; + reg = <0x60000000 DT_SIZE_M(256)>; + }; +}; diff --git a/dts/arm/microchip/sam/sama7/sama7d6/sama7d65d4g.dtsi b/dts/arm/microchip/sam/sama7/sama7d6/sama7d65d4g.dtsi new file mode 100644 index 000000000000..7531d8a52e3d --- /dev/null +++ b/dts/arm/microchip/sam/sama7/sama7d6/sama7d65d4g.dtsi @@ -0,0 +1,15 @@ +/* + * Copyright (C) 2025 Microchip Technology Inc. and its subsidiaries + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +#include + +/ { + ddram: ddram@60000000 { + compatible = "ddram"; + reg = <0x60000000 DT_SIZE_M(512)>; + }; +}; diff --git a/dts/arm/microchip/sam/sama7/sama7d6/sama7d65d5m.dtsi b/dts/arm/microchip/sam/sama7/sama7d6/sama7d65d5m.dtsi new file mode 100644 index 000000000000..3d603faea161 --- /dev/null +++ b/dts/arm/microchip/sam/sama7/sama7d6/sama7d65d5m.dtsi @@ -0,0 +1,15 @@ +/* + * Copyright (C) 2025 Microchip Technology Inc. and its subsidiaries + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +#include + +/ { + ddram: ddram@60000000 { + compatible = "ddram"; + reg = <0x60000000 DT_SIZE_M(64)>; + }; +}; From eef720ff3f2ee86c2bfc65aa032af6a3e7694f36 Mon Sep 17 00:00:00 2001 From: Julien Vermillard Date: Thu, 4 Dec 2025 14:59:54 +0100 Subject: [PATCH 0027/3659] net: lwm2m: add send scheduler helper objects Introduce the optional OMA 10523/10524 send scheduler extension to manage cached resources, including control and sampling rule objects, cache filter with gt/lt/st and pmin/pmax handling, max-age/max-sample limits, and registration flush helper. Add an overlay to the LWM2M client sample. Add a fake humidity sensor. Signed-off-by: Julien Vermillard --- doc/connectivity/networking/api/lwm2m.rst | 53 + include/zephyr/net/lwm2m_send_scheduler.h | 46 + samples/net/lwm2m_client/README.rst | 3 + .../lwm2m_client/overlay-send-scheduler.conf | 12 + samples/net/lwm2m_client/sample.yaml | 12 + samples/net/lwm2m_client/src/humidity.c | 60 ++ samples/net/lwm2m_client/src/lwm2m-client.c | 37 +- samples/net/lwm2m_client/src/modules.h | 4 + samples/net/lwm2m_client/src/temperature.c | 19 + subsys/net/lib/lwm2m/CMakeLists.txt | 4 + subsys/net/lib/lwm2m/Kconfig | 17 + .../send_scheduler/lwm2m_obj_send_scheduler.c | 640 ++++++++++++ .../send_scheduler/send_scheduler_core.c | 933 ++++++++++++++++++ .../send_scheduler/send_scheduler_internal.h | 74 ++ 14 files changed, 1913 insertions(+), 1 deletion(-) create mode 100644 include/zephyr/net/lwm2m_send_scheduler.h create mode 100644 samples/net/lwm2m_client/overlay-send-scheduler.conf create mode 100644 samples/net/lwm2m_client/src/humidity.c create mode 100644 subsys/net/lib/lwm2m/send_scheduler/lwm2m_obj_send_scheduler.c create mode 100644 subsys/net/lib/lwm2m/send_scheduler/send_scheduler_core.c create mode 100644 subsys/net/lib/lwm2m/send_scheduler/send_scheduler_internal.h diff --git a/doc/connectivity/networking/api/lwm2m.rst b/doc/connectivity/networking/api/lwm2m.rst index 3a69a15cd582..73d9dd8f244b 100644 --- a/doc/connectivity/networking/api/lwm2m.rst +++ b/doc/connectivity/networking/api/lwm2m.rst @@ -546,6 +546,59 @@ Limitations Cache size should be manually set so small that the content can fit normal packets sizes. When cache is full, new values are dropped. +Send scheduler helper objects +***************************** + +The optional SEND scheduler extension exposes two objects (Send scheduler Control ``10523`` and +Sampling Rules ``10524``) that sit on top of cached resources to decide when samples should be kept +and when the client should trigger a LWM2M SEND. + +Enabling and wiring +=================== + +* Select :kconfig:option:`CONFIG_LWM2M_SEND_SCHEDULER` (requires LwM2M 1.1 SEND support and + :kconfig:option:`CONFIG_LWM2M_RESOURCE_DATA_CACHE_SUPPORT`). +* Send-scheduler objects register automatically; ensure caches are configured before starting the + RD client. +* Attach :c:func:`lwm2m_send_sched_cache_filter` to every cached resource that should be governed by + the scheduler using :c:func:`lwm2m_set_cache_filter`. +* Call :c:func:`lwm2m_send_sched_handle_registration_event` from the RD client callback when + registration or registration-update completes (on + ``LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE`` and ``LWM2M_RD_CLIENT_EVENT_REG_UPDATE_COMPLETE``) + so cached samples are sent right after the registration exchange. + +Scheduler Control object (10523) +================================ + +The single-instance control object configures global behaviour: + +* ``0: paused`` – stop accepting samples in cache. +* ``1: max-samples`` – upper limit for cached samples across all resources; a SEND is forced when + the limit is reached (``0`` disables). +* ``2: max-age`` – maximum age in seconds of the oldest cached sample before a SEND is triggered + (``0`` disables). +* ``3: flush`` – Execute resource that immediately triggers a SEND for all configured rule paths. +* ``4: flush-on-update`` – when enabled (default), a successful registration or registration-update + event triggers a SEND of cached resources. + +Sampling Rules object (10524) +============================= + +Each instance describes one cached resource to watch. ``/10524/X/0`` holds the resource path +and ``/10524/X/1`` contains up to four rule strings. Supported attributes: + +* ``gt=`` – trigger when the sample crosses above the threshold. +* ``lt=`` – trigger when the sample crosses below the threshold. +* ``st=`` – trigger when the absolute delta from the last reported value is greater than or + equal to the threshold. +* ``pmin=`` – minimum seconds between accepted samples. +* ``pmax=`` – force a cached sample to be kept at least every ``pmax`` seconds, even without + changes. + +When no rules are configured for an instance, every incoming sample is cached. The scheduler also +forces a SEND when a cache for a controlled resource runs out of space or when the global +``max-samples``/``max-age`` limits are reached. + LwM2M engine and application events *********************************** diff --git a/include/zephyr/net/lwm2m_send_scheduler.h b/include/zephyr/net/lwm2m_send_scheduler.h new file mode 100644 index 000000000000..c901f5d9aa02 --- /dev/null +++ b/include/zephyr/net/lwm2m_send_scheduler.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2025 Clunky Machines + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_NET_LWM2M_SEND_SCHEDULER_H_ +#define ZEPHYR_NET_LWM2M_SEND_SCHEDULER_H_ + +#include +#include + +/** + * @brief Register the send scheduler LwM2M objects and initialise state. + * + * This installs the Scheduler Control (10523) and Sampling Rules (10524) + * objects and prepares bookkeeping needed by the cache filter helpers. + * + * @return 0 on success, or a negative errno if object registration fails. + */ +int lwm2m_send_sched_init(void); + +/** + * @brief Cache filter that enforces the configured scheduler rules. + * + * Hook this up via @ref lwm2m_set_cache_filter for each cached resource you + * want the scheduler to control. + * + * @param path LwM2M path of the cached resource. + * @param element Candidate sample about to be cached. + * + * @return true to keep the sample in the cache, false to drop or defer it. + */ +bool lwm2m_send_sched_cache_filter(const struct lwm2m_obj_path *path, + const struct lwm2m_time_series_elem *element); + +/** + * @brief Handle a registration or registration-update completion event. + * + * Applications should call this when their LwM2M RD client reports a successful + * registration or registration update so the send scheduler can apply its + * flush-on-update policy. + */ +void lwm2m_send_sched_handle_registration_event(void); + +#endif /* ZEPHYR_NET_LWM2M_SEND_SCHEDULER_H_ */ diff --git a/samples/net/lwm2m_client/README.rst b/samples/net/lwm2m_client/README.rst index 42759f6b204f..bc0658a1d805 100644 --- a/samples/net/lwm2m_client/README.rst +++ b/samples/net/lwm2m_client/README.rst @@ -52,6 +52,9 @@ samples/net/lwm2m_client directory: * - :file:`overlay-queue.conf` - This overlay config can be added to enable LWM2M Queue Mode support. + * - :file:`overlay-send-scheduler.conf` + - This overlay config enables LwM2M send scheduler support and activate caching for the temperature and humidity IPSO objects. + * - :file:`overlay-tickless.conf` - This overlay config can be used to stop LwM2M engine for periodically interrupting socket polls. It can have significant effect on power usage on certain devices. diff --git a/samples/net/lwm2m_client/overlay-send-scheduler.conf b/samples/net/lwm2m_client/overlay-send-scheduler.conf new file mode 100644 index 000000000000..def2d98c26d2 --- /dev/null +++ b/samples/net/lwm2m_client/overlay-send-scheduler.conf @@ -0,0 +1,12 @@ +CONFIG_LWM2M_VERSION_1_1=y + +# Enable caching so the send scheduler can govern cached samples +CONFIG_LWM2M_RESOURCE_DATA_CACHE_SUPPORT=y +CONFIG_LWM2M_RW_SENML_CBOR_SUPPORT=y +CONFIG_ZCBOR=y +CONFIG_ZCBOR_CANONICAL=y +CONFIG_LWM2M_IPSO_HUMIDITY_SENSOR=y + +# Send scheduler helper objects and enough composite slots for a few rules +CONFIG_LWM2M_SEND_SCHEDULER=y +CONFIG_LWM2M_COMPOSITE_PATH_LIST_SIZE=4 diff --git a/samples/net/lwm2m_client/sample.yaml b/samples/net/lwm2m_client/sample.yaml index a3f21d89a01c..1627211816d4 100644 --- a/samples/net/lwm2m_client/sample.yaml +++ b/samples/net/lwm2m_client/sample.yaml @@ -76,6 +76,18 @@ tests: tags: - net - lwm2m + sample.net.lwm2m_client.send_scheduler: + harness: net + depends_on: netif + extra_args: EXTRA_CONF_FILE=overlay-send-scheduler.conf + platform_allow: + - qemu_x86 + - native_sim + integration_platforms: + - qemu_x86 + tags: + - net + - lwm2m sample.net.lwm2m_client.wnc_m14a2a: harness: net extra_args: SHIELD=wnc_m14a2a diff --git a/samples/net/lwm2m_client/src/humidity.c b/samples/net/lwm2m_client/src/humidity.c new file mode 100644 index 000000000000..7cc6b1eec1b7 --- /dev/null +++ b/samples/net/lwm2m_client/src/humidity.c @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2025 Clunky Machines + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#if defined(CONFIG_LWM2M_IPSO_HUMIDITY_SENSOR) + +#define LOG_MODULE_NAME app_humidity +#include +LOG_MODULE_REGISTER(LOG_MODULE_NAME); + +#include "modules.h" + +#include +#include +#include +#include +#include + +static struct k_work_delayable humidity_work; +#define HUMIDITY_PERIOD K_MINUTES(2) + +static struct lwm2m_time_series_elem humidity_cache[8]; + +static void humidity_work_cb(struct k_work *work) +{ + double v; + + v = 40.0 + (double)sys_rand32_get() / UINT32_MAX * 20.0; + + lwm2m_set_f64(&LWM2M_OBJ(3304, 0, 5700), v); + + k_work_schedule(&humidity_work, HUMIDITY_PERIOD); +} + +void init_humidity_sensor(void) +{ + if (lwm2m_create_object_inst(&LWM2M_OBJ(3304, 0)) == 0) { + if (IS_ENABLED(CONFIG_LWM2M_RESOURCE_DATA_CACHE_SUPPORT)) { + int ret; + + ret = lwm2m_enable_cache(&LWM2M_OBJ(3304, 0, 5700), humidity_cache, + ARRAY_SIZE(humidity_cache)); + if (ret < 0) { + LOG_WRN("Failed to enable cache for humidity sensor (%d)", ret); + } + + if (IS_ENABLED(CONFIG_LWM2M_SEND_SCHEDULER)) { + lwm2m_set_cache_filter(&LWM2M_OBJ(3304, 0, 5700), + lwm2m_send_sched_cache_filter); + } + } + + k_work_init_delayable(&humidity_work, humidity_work_cb); + k_work_schedule(&humidity_work, K_NO_WAIT); + } +} + +#endif /* CONFIG_LWM2M_IPSO_HUMIDITY_SENSOR */ diff --git a/samples/net/lwm2m_client/src/lwm2m-client.c b/samples/net/lwm2m_client/src/lwm2m-client.c index 7c15f84502c7..d91b07608458 100644 --- a/samples/net/lwm2m_client/src/lwm2m-client.c +++ b/samples/net/lwm2m_client/src/lwm2m-client.c @@ -15,6 +15,7 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #include #include #include +#include #include #include #include "modules.h" @@ -52,6 +53,10 @@ static int mem_free = 15; static int mem_total = 25; static double min_range = 0.0; static double max_range = 100; +#if defined(CONFIG_LWM2M_IPSO_HUMIDITY_SENSOR) +static double humidity_min_range = 0.0; +static double humidity_max_range = 100.0; +#endif static struct lwm2m_ctx client_ctx; @@ -105,6 +110,7 @@ static int lwm2m_setup(void) {&LWM2M_OBJ(IPSO_OBJECT_TEMP_SENSOR_ID, 0, SENSOR_UNITS_RID), TEMP_SENSOR_UNITS, sizeof(TEMP_SENSOR_UNITS)} }; + int err; /* setup SECURITY object */ @@ -185,8 +191,31 @@ static int lwm2m_setup(void) /* setup TEMP SENSOR object */ init_temp_sensor(); +#if defined(CONFIG_LWM2M_IPSO_HUMIDITY_SENSOR) + /* setup HUMIDITY SENSOR object */ + init_humidity_sensor(); + + /* setup HUMIDITY SENSOR resources */ + { + struct lwm2m_res_item humidity_items[] = { + {&LWM2M_OBJ(IPSO_OBJECT_HUMIDITY_SENSOR_ID, 0, MIN_RANGE_VALUE_RID), + &humidity_min_range, sizeof(humidity_min_range)}, + {&LWM2M_OBJ(IPSO_OBJECT_HUMIDITY_SENSOR_ID, 0, MAX_RANGE_VALUE_RID), + &humidity_max_range, sizeof(humidity_max_range)}, + {&LWM2M_OBJ(IPSO_OBJECT_HUMIDITY_SENSOR_ID, 0, SENSOR_UNITS_RID), + "Percent", sizeof("Percent")} + }; + + err = lwm2m_set_bulk(humidity_items, ARRAY_SIZE(humidity_items)); + if (err) { + LOG_ERR("Failed to set HUMIDITY SENSOR resources"); + return err; + } + } +#endif + /* Set multiple TEMP SENSOR resource values in one function call. */ - int err = lwm2m_set_bulk(temp_sensor_items, ARRAY_SIZE(temp_sensor_items)); + err = lwm2m_set_bulk(temp_sensor_items, ARRAY_SIZE(temp_sensor_items)); if (err) { LOG_ERR("Failed to set TEMP SENSOR resources"); @@ -233,6 +262,9 @@ static void rd_client_event(struct lwm2m_ctx *client, case LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE: LOG_DBG("Registration complete"); +#if defined(CONFIG_LWM2M_SEND_SCHEDULER) + lwm2m_send_sched_handle_registration_event(); +#endif break; case LWM2M_RD_CLIENT_EVENT_REG_TIMEOUT: @@ -241,6 +273,9 @@ static void rd_client_event(struct lwm2m_ctx *client, case LWM2M_RD_CLIENT_EVENT_REG_UPDATE_COMPLETE: LOG_DBG("Registration update complete"); +#if defined(CONFIG_LWM2M_SEND_SCHEDULER) + lwm2m_send_sched_handle_registration_event(); +#endif break; case LWM2M_RD_CLIENT_EVENT_DEREGISTER_FAILURE: diff --git a/samples/net/lwm2m_client/src/modules.h b/samples/net/lwm2m_client/src/modules.h index 4e9befcfd978..21ec7de0de77 100644 --- a/samples/net/lwm2m_client/src/modules.h +++ b/samples/net/lwm2m_client/src/modules.h @@ -12,4 +12,8 @@ void init_timer_object(void); void init_temp_sensor(void); void init_firmware_update(void); +#if defined(CONFIG_LWM2M_IPSO_HUMIDITY_SENSOR) +void init_humidity_sensor(void); +#endif + #endif diff --git a/samples/net/lwm2m_client/src/temperature.c b/samples/net/lwm2m_client/src/temperature.c index 6d251fafbdbc..2a1b9b49b807 100644 --- a/samples/net/lwm2m_client/src/temperature.c +++ b/samples/net/lwm2m_client/src/temperature.c @@ -13,6 +13,7 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #include #include #include +#include #include #include #include @@ -20,6 +21,9 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); static struct k_work_delayable temp_work; #define PERIOD K_MINUTES(2) +/* Cache slots used by the send scheduler for the temperature sensor */ +static struct lwm2m_time_series_elem temp_cache[8]; + static void temp_work_cb(struct k_work *work) { double v; @@ -54,6 +58,21 @@ static void temp_work_cb(struct k_work *work) void init_temp_sensor(void) { if (lwm2m_create_object_inst(&LWM2M_OBJ(3303, 0)) == 0) { + if (IS_ENABLED(CONFIG_LWM2M_RESOURCE_DATA_CACHE_SUPPORT)) { + int ret; + + ret = lwm2m_enable_cache(&LWM2M_OBJ(3303, 0, 5700), temp_cache, + ARRAY_SIZE(temp_cache)); + if (ret < 0) { + LOG_WRN("Failed to enable cache for temp sensor (%d)", ret); + } + + if (IS_ENABLED(CONFIG_LWM2M_SEND_SCHEDULER)) { + lwm2m_set_cache_filter(&LWM2M_OBJ(3303, 0, 5700), + lwm2m_send_sched_cache_filter); + } + } + k_work_init_delayable(&temp_work, temp_work_cb); k_work_schedule(&temp_work, K_NO_WAIT); } diff --git a/subsys/net/lib/lwm2m/CMakeLists.txt b/subsys/net/lib/lwm2m/CMakeLists.txt index 9971283cffd3..962822b291d9 100644 --- a/subsys/net/lib/lwm2m/CMakeLists.txt +++ b/subsys/net/lib/lwm2m/CMakeLists.txt @@ -35,6 +35,10 @@ zephyr_library_sources_ifdef(CONFIG_LWM2M_FIRMWARE_UPDATE_PULL_SUPPORT lwm2m_obj_firmware_pull.c lwm2m_pull_context.c ) +zephyr_library_sources_ifdef(CONFIG_LWM2M_SEND_SCHEDULER + send_scheduler/send_scheduler_core.c + send_scheduler/lwm2m_obj_send_scheduler.c + ) zephyr_library_sources_ifdef(CONFIG_LWM2M_LOCATION_OBJ_SUPPORT lwm2m_obj_location.c ) diff --git a/subsys/net/lib/lwm2m/Kconfig b/subsys/net/lib/lwm2m/Kconfig index 3d89075a8571..95011437b686 100644 --- a/subsys/net/lib/lwm2m/Kconfig +++ b/subsys/net/lib/lwm2m/Kconfig @@ -253,6 +253,23 @@ endchoice endif # LWM2M_RESOURCE_DATA_CACHE_SUPPORT +config LWM2M_SEND_SCHEDULER + bool "LwM2M send scheduler helper objects (10523/10524)" + depends on LWM2M_VERSION_1_1 + depends on LWM2M_RESOURCE_DATA_CACHE_SUPPORT + help + Enable the optional send scheduler extension which exposes vendor + objects to configure sampling rules, buffer limits, and SEND trigger + policies on top of cached resources. Requires LwM2M 1.1 SEND support + and resource data caching. + +if LWM2M_SEND_SCHEDULER +module = LWM2M_SEND_SCHEDULER +module-str = Log level for LwM2M send scheduler helper +module-dep = LOG +source "subsys/net/Kconfig.template.log_config.net" +endif # LWM2M_SEND_SCHEDULER + endmenu # "Engine features" menu "Memory and buffer size configuration" diff --git a/subsys/net/lib/lwm2m/send_scheduler/lwm2m_obj_send_scheduler.c b/subsys/net/lib/lwm2m/send_scheduler/lwm2m_obj_send_scheduler.c new file mode 100644 index 000000000000..f5409930d52a --- /dev/null +++ b/subsys/net/lib/lwm2m/send_scheduler/lwm2m_obj_send_scheduler.c @@ -0,0 +1,640 @@ +/* + * Copyright (c) 2025 Clunky Machines + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +LOG_MODULE_DECLARE(lwm2m_send_sched, CONFIG_LWM2M_SEND_SCHEDULER_LOG_LEVEL); + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "lwm2m_engine.h" +#include "lwm2m_object.h" +#include "lwm2m_registry.h" + +#include +#include "send_scheduler_internal.h" + +/* Official OMA object IDs (reserved via OMA issue #858) */ +#define SEND_SCHED_CTRL_OBJECT_ID 10523 +#define SEND_SCHED_RULES_OBJECT_ID 10524 + +/* resource IDs */ +#define SEND_SCHED_CTRL_RES_PAUSED 0 +#define SEND_SCHED_CTRL_RES_MAX_SAMPLES 1 +#define SEND_SCHED_CTRL_RES_MAX_AGE 2 +#define SEND_SCHED_CTRL_RES_FLUSH 3 +#define SEND_SCHED_CTRL_RES_FLUSH_ON_UPDATE 4 +#define SEND_SCHED_RULES_RES_PATH 0 +#define SEND_SCHED_RULES_RES_RULES 1 + +#define SEND_SCHED_CTRL_RES_COUNT 5 +#define SEND_SCHED_CTRL_RES_INST_COUNT SEND_SCHED_CTRL_RES_COUNT + +#define SEND_SCHED_RULES_RES_COUNT 2 +#define SEND_SCHED_RULES_RES_INST_COUNT (1 + LWM2M_SEND_SCHED_MAX_RULE_STRINGS) + +static struct lwm2m_engine_obj send_sched_ctrl_obj; +static struct lwm2m_engine_obj_field send_sched_ctrl_fields[] = { + OBJ_FIELD(SEND_SCHED_CTRL_RES_PAUSED, RW, BOOL), + OBJ_FIELD(SEND_SCHED_CTRL_RES_MAX_SAMPLES, RW, S32), + OBJ_FIELD(SEND_SCHED_CTRL_RES_MAX_AGE, RW, S32), + OBJ_FIELD_EXECUTE(SEND_SCHED_CTRL_RES_FLUSH), + OBJ_FIELD(SEND_SCHED_CTRL_RES_FLUSH_ON_UPDATE, RW, BOOL), +}; +static struct lwm2m_engine_res send_sched_ctrl_res[SEND_SCHED_CTRL_RES_COUNT]; +static struct lwm2m_engine_res_inst send_sched_ctrl_res_inst[SEND_SCHED_CTRL_RES_INST_COUNT]; +static struct lwm2m_engine_obj_inst send_sched_ctrl_inst; + +static struct lwm2m_engine_obj send_sched_rules_obj; +static struct lwm2m_engine_obj_field send_sched_rules_fields[] = { + OBJ_FIELD(SEND_SCHED_RULES_RES_PATH, RW, STRING), + OBJ_FIELD(SEND_SCHED_RULES_RES_RULES, RW, STRING), +}; +static struct lwm2m_engine_res send_sched_rules_res[LWM2M_SEND_SCHED_RULES_MAX_INSTANCES] + [SEND_SCHED_RULES_RES_COUNT]; +static struct lwm2m_engine_res_inst send_sched_rules_res_inst[LWM2M_SEND_SCHED_RULES_MAX_INSTANCES] + [SEND_SCHED_RULES_RES_INST_COUNT]; +static struct lwm2m_engine_obj_inst send_sched_rules_inst[LWM2M_SEND_SCHED_RULES_MAX_INSTANCES]; + +static bool scheduler_max_age_cb_registered; +static bool scheduler_max_samples_cb_registered; + +/* Find the internal rule slot used by an object instance */ +static int send_sched_rules_index_for_inst(uint16_t obj_inst_id) +{ + for (int idx = 0; idx < LWM2M_SEND_SCHED_RULES_MAX_INSTANCES; idx++) { + if (send_sched_rules_inst[idx].obj && + send_sched_rules_inst[idx].obj_inst_id == obj_inst_id) { + return idx; + } + } + + return -1; +} + +/* Check whether the attribute expects an integer value */ +static bool send_sched_attribute_requires_integer(const char *attr) +{ + return (!strcmp(attr, "pmin") || !strcmp(attr, "pmax") || !strcmp(attr, "epmin") || + !strcmp(attr, "epmax")); +} + +/* Check whether the attribute expects a floating-point value */ +static bool send_sched_attribute_requires_float(const char *attr) +{ + return (!strcmp(attr, "gt") || !strcmp(attr, "lt") || !strcmp(attr, "st")); +} + +/* Validate that the string can be parsed as a decimal integer */ +static bool send_sched_is_valid_integer(const char *value) +{ + char *end = NULL; + long parsed; + + if (value == NULL || *value == '\0') { + return false; + } + + errno = 0; + parsed = strtol(value, &end, 10); + if (errno == ERANGE) { + return false; + } + + if (end == value || (end && *end != '\0')) { + return false; + } + + ARG_UNUSED(parsed); + + return true; +} + +/* Validate that the string can be parsed as a floating-point number */ +static bool send_sched_is_valid_float(const char *value) +{ + char *end = NULL; + double parsed; + + if (value == NULL || *value == '\0') { + return false; + } + + errno = 0; + parsed = strtod(value, &end); + if (errno == ERANGE) { + return false; + } + + if (end == value || (end && *end != '\0')) { + return false; + } + + ARG_UNUSED(parsed); + + return true; +} + +/* Determine whether the attribute is supported by the scheduler */ +static bool send_sched_attribute_is_allowed(const char *attr) +{ + return send_sched_attribute_requires_integer(attr) || + send_sched_attribute_requires_float(attr); +} + +/* Ensure the configured path string references a resource */ +static int send_sched_validate_path(uint16_t obj_inst_id, uint16_t res_id, uint16_t res_inst_id, + uint8_t *data, uint16_t data_len, bool last_block, + size_t total_size, size_t offset) +{ + char path_buf[LWM2M_SEND_SCHED_RULE_STRING_SIZE]; + size_t copy_len; + int segments = 0; + + ARG_UNUSED(res_id); + ARG_UNUSED(res_inst_id); + ARG_UNUSED(last_block); + ARG_UNUSED(total_size); + ARG_UNUSED(offset); + + if (!data || data_len == 0) { + LOG_WRN("Sampling rule path cannot be empty"); + return -EINVAL; + } + + if (data_len >= sizeof(path_buf)) { + LOG_WRN("Sampling rule path too long (%u)", data_len); + return -ENOBUFS; + } + + int entry_idx = send_sched_rules_index_for_inst(obj_inst_id); + + if (entry_idx >= 0) { + send_sched_cancel_pmax_timer(&rule_entries[entry_idx]); + rule_entries[entry_idx].pmax_deadline_ms = 0; + rule_entries[entry_idx].has_cached_path = false; + rule_entries[entry_idx].has_configured_path = false; + rule_entries[entry_idx].has_last_reported = false; + rule_entries[entry_idx].has_last_observed = false; + send_sched_schedule_age_check(); + } + + copy_len = MIN((size_t)data_len, sizeof(path_buf) - 1U); + memcpy(path_buf, data, copy_len); + path_buf[copy_len] = '\0'; + + if (path_buf[0] != '/') { + LOG_WRN("Sampling rule path must start with '/'"); + return -EINVAL; + } + + for (char *cursor = path_buf + 1; *cursor != '\0';) { + char *next = strchr(cursor, '/'); + size_t seg_len = next ? (size_t)(next - cursor) : strlen(cursor); + + if (seg_len == 0) { + LOG_WRN("Sampling rule path contains empty segment"); + return -EINVAL; + } + + for (size_t idx = 0; idx < seg_len; idx++) { + if (!isdigit((unsigned char)cursor[idx])) { + LOG_WRN("Sampling rule path segment must be numeric"); + return -EINVAL; + } + } + + segments++; + if (!next) { + break; + } + cursor = next + 1; + } + + if (segments != 3) { + LOG_WRN("Sampling rule path must reference a resource (/obj/inst/res)"); + return -EINVAL; + } + + if (entry_idx >= 0) { + struct lwm2m_obj_path parsed_path; + int ret = send_sched_parse_path(path_buf, &parsed_path); + + if (ret < 0) { + LOG_WRN("Sampling rule path failed to parse (%d)", ret); + return ret; + } + + rule_entries[entry_idx].configured_path = parsed_path; + rule_entries[entry_idx].has_configured_path = true; + } + + return 0; +} + +/* Check rule syntax and enforce per-instance attribute uniqueness */ +static int send_sched_validate_rule(uint16_t obj_inst_id, uint16_t res_id, uint16_t res_inst_id, + uint8_t *data, uint16_t data_len, bool last_block, + size_t total_size, size_t offset) +{ + char rule_buf[LWM2M_SEND_SCHED_RULE_STRING_SIZE]; + char *eq = NULL; + const char *attr; + const char *value; + size_t attr_len; + int entry_idx; + int current_slot = -1; + struct send_sched_rule_entry *entry; + + ARG_UNUSED(res_id); + ARG_UNUSED(last_block); + ARG_UNUSED(total_size); + ARG_UNUSED(offset); + + entry_idx = send_sched_rules_index_for_inst(obj_inst_id); + if (entry_idx < 0) { + LOG_ERR("Sampling rule instance %u not found", obj_inst_id); + return -ENOENT; + } + + entry = &rule_entries[entry_idx]; + + if (res_inst_id < LWM2M_SEND_SCHED_MAX_RULE_STRINGS) { + current_slot = res_inst_id; + } + + if (current_slot < 0) { + for (int idx = 0; idx < LWM2M_SEND_SCHED_MAX_RULE_STRINGS; idx++) { + if (&entry->rules[idx][0] == (char *)data) { + current_slot = idx; + break; + } + } + } + + if (current_slot < 0 || current_slot >= LWM2M_SEND_SCHED_MAX_RULE_STRINGS) { + LOG_ERR("Sampling rule index out of range (%d)", current_slot); + return -EINVAL; + } + + if (!data) { + return -EINVAL; + } + + if (data_len == 0U) { + const char *existing = entry->rules[current_slot]; + + if (existing[0] != '\0') { + int32_t tmp; + + if (send_sched_rule_parse_int(existing, "pmin", &tmp)) { + entry->pmin_waiting = false; + entry->pmin_deadline_ms = 0; + entry->has_pmin = false; + entry->pmin_seconds = 0; + } + + if (send_sched_rule_parse_int(existing, "pmax", &tmp)) { + entry->pmax_seconds = 0; + entry->pmax_deadline_ms = 0; + send_sched_cancel_pmax_timer(entry); + } + } + + entry->rules[current_slot][0] = '\0'; + send_sched_rules_res_inst[entry_idx][current_slot].data_len = 0U; + entry->has_last_reported = false; + entry->has_last_observed = false; + entry->rules_dirty = true; + return 0; + } + + if (data_len >= sizeof(rule_buf)) { + LOG_WRN("Sampling rule string too long (%u)", data_len); + return -ENOBUFS; + } + + memcpy(rule_buf, data, data_len); + rule_buf[data_len] = '\0'; + + eq = strchr(rule_buf, '='); + if (!eq || strchr(eq + 1, '=')) { + LOG_WRN("Sampling rule must be formatted as attribute=value"); + return -EINVAL; + } + + *eq = '\0'; + attr = rule_buf; + value = eq + 1; + attr_len = strlen(attr); + + if (attr_len == 0U || *value == '\0') { + LOG_WRN("Sampling rule requires both attribute and value"); + return -EINVAL; + } + + for (size_t idx = 0; idx < attr_len; idx++) { + if (!islower((unsigned char)attr[idx])) { + LOG_WRN("Sampling rule attribute contains invalid characters"); + return -EINVAL; + } + } + + if (!send_sched_attribute_is_allowed(attr)) { + LOG_WRN("Sampling rule attribute '%s' is not supported", attr); + return -EINVAL; + } + + if (send_sched_attribute_requires_integer(attr)) { + if (!send_sched_is_valid_integer(value)) { + LOG_WRN("Sampling rule attribute '%s' expects integer value", attr); + return -EINVAL; + } + } else if (send_sched_attribute_requires_float(attr)) { + if (!send_sched_is_valid_float(value)) { + LOG_WRN("Sampling rule attribute '%s' expects floating-point value", attr); + return -EINVAL; + } + } + + for (int idx = 0; idx < LWM2M_SEND_SCHED_MAX_RULE_STRINGS; idx++) { + const struct lwm2m_engine_res_inst *res_inst; + const char *existing_eq; + + if (idx == current_slot) { + continue; + } + + res_inst = &send_sched_rules_res_inst[entry_idx][idx]; + if (res_inst->res_inst_id == RES_INSTANCE_NOT_CREATED || res_inst->data_len == 0U) { + continue; + } + + existing_eq = strchr(entry->rules[idx], '='); + if (!existing_eq) { + continue; + } + + if ((size_t)(existing_eq - entry->rules[idx]) == attr_len && + strncmp(entry->rules[idx], attr, attr_len) == 0) { + LOG_WRN("Sampling rule attribute '%s' already defined", attr); + return -EEXIST; + } + } + + entry->rules_dirty = true; + return 0; +} + +static int send_sched_flush_cb(uint16_t obj_inst_id, uint8_t *args, uint16_t args_len) +{ + ARG_UNUSED(obj_inst_id); + ARG_UNUSED(args); + ARG_UNUSED(args_len); + + LOG_DBG("Manual flush requested"); + return send_sched_flush_all(); +} + +static struct lwm2m_engine_obj_inst *send_sched_ctrl_create(uint16_t obj_inst_id) +{ + static bool created; + int i = 0; + int j = 0; + + if (created || obj_inst_id != 0U) { + LOG_WRN("Scheduler control instance %u already exists or not 0", obj_inst_id); + return NULL; + } + + created = true; + + (void)memset(&send_sched_ctrl_inst, 0, sizeof(send_sched_ctrl_inst)); + init_res_instance(send_sched_ctrl_res_inst, ARRAY_SIZE(send_sched_ctrl_res_inst)); + (void)memset(send_sched_ctrl_res, 0, sizeof(send_sched_ctrl_res)); + + INIT_OBJ_RES_DATA(SEND_SCHED_CTRL_RES_PAUSED, send_sched_ctrl_res, i, + send_sched_ctrl_res_inst, j, &scheduler_paused, sizeof(scheduler_paused)); + INIT_OBJ_RES_DATA(SEND_SCHED_CTRL_RES_MAX_SAMPLES, send_sched_ctrl_res, i, + send_sched_ctrl_res_inst, j, &scheduler_max_samples, + sizeof(scheduler_max_samples)); + INIT_OBJ_RES_DATA(SEND_SCHED_CTRL_RES_MAX_AGE, send_sched_ctrl_res, i, + send_sched_ctrl_res_inst, j, &scheduler_max_age, + sizeof(scheduler_max_age)); + INIT_OBJ_RES_EXECUTE(SEND_SCHED_CTRL_RES_FLUSH, send_sched_ctrl_res, i, + send_sched_flush_cb); + INIT_OBJ_RES_DATA(SEND_SCHED_CTRL_RES_FLUSH_ON_UPDATE, send_sched_ctrl_res, i, + send_sched_ctrl_res_inst, j, &send_sched_flush_on_update, + sizeof(send_sched_flush_on_update)); + + send_sched_ctrl_inst.resources = send_sched_ctrl_res; + send_sched_ctrl_inst.resource_count = i; + + return &send_sched_ctrl_inst; +} + +static int send_sched_ctrl_delete(uint16_t obj_inst_id) +{ + ARG_UNUSED(obj_inst_id); + LOG_WRN("Scheduler control object cannot be deleted"); + return -EBUSY; +} + +static int send_sched_ctrl_max_age_post_write_cb(uint16_t obj_inst_id, uint16_t res_id, + uint16_t res_inst_id, uint8_t *data, + uint16_t data_len, bool last_block, + size_t total_size, size_t offset) +{ + ARG_UNUSED(obj_inst_id); + ARG_UNUSED(res_id); + ARG_UNUSED(res_inst_id); + ARG_UNUSED(data); + ARG_UNUSED(data_len); + ARG_UNUSED(last_block); + ARG_UNUSED(total_size); + ARG_UNUSED(offset); + + send_sched_process_max_age(true); + + return 0; +} + +static int send_sched_ctrl_max_samples_post_write_cb(uint16_t obj_inst_id, uint16_t res_id, + uint16_t res_inst_id, uint8_t *data, + uint16_t data_len, bool last_block, + size_t total_size, size_t offset) +{ + ARG_UNUSED(obj_inst_id); + ARG_UNUSED(res_id); + ARG_UNUSED(res_inst_id); + ARG_UNUSED(data); + ARG_UNUSED(data_len); + ARG_UNUSED(last_block); + ARG_UNUSED(total_size); + ARG_UNUSED(offset); + + if (scheduler_max_samples <= 0) { + send_sched_reset_accumulated_samples(); + return 0; + } + + send_sched_enforce_max_sample_limit(); + + return 0; +} + +/* Create a new rules object instance and wire resources */ +static struct lwm2m_engine_obj_inst *send_sched_rules_create(uint16_t obj_inst_id) +{ + int avail = -1; + int i = 0; + int j = 0; + + for (int idx = 0; idx < LWM2M_SEND_SCHED_RULES_MAX_INSTANCES; idx++) { + if (send_sched_rules_inst[idx].obj && + send_sched_rules_inst[idx].obj_inst_id == obj_inst_id) { + LOG_WRN("Sampling rules instance %u already exists", obj_inst_id); + return NULL; + } + + if (avail < 0 && send_sched_rules_inst[idx].obj == NULL) { + avail = idx; + } + } + + if (avail < 0) { + LOG_WRN("No slot available for sampling rules instance %u", obj_inst_id); + return NULL; + } + + (void)memset(&send_sched_rules_res[avail], 0, sizeof(send_sched_rules_res[avail])); + (void)memset(&rule_entries[avail], 0, sizeof(rule_entries[avail])); + (void)memset(&send_sched_rules_inst[avail], 0, sizeof(send_sched_rules_inst[avail])); + + k_work_init_delayable(&rule_entries[avail].pmax_work, send_sched_pmax_work_handler); + + init_res_instance(send_sched_rules_res_inst[avail], + ARRAY_SIZE(send_sched_rules_res_inst[avail])); + + INIT_OBJ_RES_LEN(SEND_SCHED_RULES_RES_PATH, send_sched_rules_res[avail], i, + send_sched_rules_res_inst[avail], j, 1U, false, true, + rule_entries[avail].path, sizeof(rule_entries[avail].path), 0, NULL, NULL, + send_sched_validate_path, NULL, NULL); + + INIT_OBJ_RES_LEN(SEND_SCHED_RULES_RES_RULES, send_sched_rules_res[avail], i, + send_sched_rules_res_inst[avail], j, LWM2M_SEND_SCHED_MAX_RULE_STRINGS, + true, false, rule_entries[avail].rules, + sizeof(rule_entries[avail].rules[0]), 0, NULL, NULL, + send_sched_validate_rule, NULL, NULL); + + send_sched_rules_inst[avail].resources = send_sched_rules_res[avail]; + send_sched_rules_inst[avail].resource_count = i; + send_sched_rules_inst[avail].obj = &send_sched_rules_obj; + send_sched_rules_inst[avail].obj_inst_id = obj_inst_id; + + return &send_sched_rules_inst[avail]; +} + +/* Reset rule bookkeeping when the instance is deleted */ +static int send_sched_rules_delete(uint16_t obj_inst_id) +{ + int idx = send_sched_rules_index_for_inst(obj_inst_id); + struct send_sched_rule_entry *entry; + + if (idx < 0) { + return -ENOENT; + } + + entry = &rule_entries[idx]; + send_sched_cancel_pmax_timer(entry); + + memset(entry, 0, sizeof(*entry)); + k_work_init_delayable(&entry->pmax_work, send_sched_pmax_work_handler); + + memset(&send_sched_rules_res[idx], 0, sizeof(send_sched_rules_res[idx])); + memset(&send_sched_rules_inst[idx], 0, sizeof(send_sched_rules_inst[idx])); + init_res_instance(send_sched_rules_res_inst[idx], + ARRAY_SIZE(send_sched_rules_res_inst[idx])); + + send_sched_schedule_age_check(); + + return 0; +} + +/* Register the scheduler objects and instantiate defaults */ +int lwm2m_send_sched_init(void) +{ + static bool registered; + struct lwm2m_engine_obj_inst *obj_inst = NULL; + int ret; + + if (!registered) { + send_sched_ctrl_obj.obj_id = SEND_SCHED_CTRL_OBJECT_ID; + send_sched_ctrl_obj.version_major = 1; + send_sched_ctrl_obj.version_minor = 0; + send_sched_ctrl_obj.is_core = false; + send_sched_ctrl_obj.fields = send_sched_ctrl_fields; + send_sched_ctrl_obj.field_count = ARRAY_SIZE(send_sched_ctrl_fields); + send_sched_ctrl_obj.max_instance_count = 1U; + send_sched_ctrl_obj.create_cb = send_sched_ctrl_create; + send_sched_ctrl_obj.delete_cb = send_sched_ctrl_delete; + lwm2m_register_obj(&send_sched_ctrl_obj); + + send_sched_rules_obj.obj_id = SEND_SCHED_RULES_OBJECT_ID; + send_sched_rules_obj.version_major = 1; + send_sched_rules_obj.version_minor = 0; + send_sched_rules_obj.is_core = false; + send_sched_rules_obj.fields = send_sched_rules_fields; + send_sched_rules_obj.field_count = ARRAY_SIZE(send_sched_rules_fields); + send_sched_rules_obj.max_instance_count = LWM2M_SEND_SCHED_RULES_MAX_INSTANCES; + send_sched_rules_obj.create_cb = send_sched_rules_create; + send_sched_rules_obj.delete_cb = send_sched_rules_delete; + lwm2m_register_obj(&send_sched_rules_obj); + + registered = true; + } else { + LOG_DBG("already registered send scheduler objects"); + } + + ret = lwm2m_create_obj_inst(SEND_SCHED_CTRL_OBJECT_ID, 0, &obj_inst); + if (ret < 0 && ret != -EEXIST) { + LOG_ERR("Failed to instantiate scheduler control object (%d)", ret); + return ret; + } + + if (!scheduler_max_samples_cb_registered) { + int cb_ret = lwm2m_register_post_write_callback( + &LWM2M_OBJ(SEND_SCHED_CTRL_OBJECT_ID, 0, SEND_SCHED_CTRL_RES_MAX_SAMPLES), + send_sched_ctrl_max_samples_post_write_cb); + if (cb_ret < 0) { + LOG_ERR("Failed to register max-samples callback (%d)", cb_ret); + return cb_ret; + } + scheduler_max_samples_cb_registered = true; + } + + if (!scheduler_max_age_cb_registered) { + int cb_ret = lwm2m_register_post_write_callback( + &LWM2M_OBJ(SEND_SCHED_CTRL_OBJECT_ID, 0, SEND_SCHED_CTRL_RES_MAX_AGE), + send_sched_ctrl_max_age_post_write_cb); + if (cb_ret < 0) { + LOG_ERR("Failed to register max-age callback (%d)", cb_ret); + return cb_ret; + } + scheduler_max_age_cb_registered = true; + } + + return 0; +} + +LWM2M_OBJ_INIT(lwm2m_send_sched_init); diff --git a/subsys/net/lib/lwm2m/send_scheduler/send_scheduler_core.c b/subsys/net/lib/lwm2m/send_scheduler/send_scheduler_core.c new file mode 100644 index 000000000000..2af1a3890956 --- /dev/null +++ b/subsys/net/lib/lwm2m/send_scheduler/send_scheduler_core.c @@ -0,0 +1,933 @@ +/* + * Copyright (c) 2025 Clunky Machines + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define LOG_MODULE_NAME lwm2m_send_sched +#include +LOG_MODULE_REGISTER(LOG_MODULE_NAME, CONFIG_LWM2M_SEND_SCHEDULER_LOG_LEVEL); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "lwm2m_engine.h" +#include "lwm2m_object.h" +#include "lwm2m_registry.h" + +#include +#include "send_scheduler_internal.h" + +BUILD_ASSERT(CONFIG_LWM2M_COMPOSITE_PATH_LIST_SIZE >= LWM2M_SEND_SCHED_RULES_MAX_INSTANCES, + "Composite path list too small for send scheduler rules"); + +bool scheduler_paused; +int32_t scheduler_max_samples; +int32_t scheduler_max_age; +bool send_sched_flush_on_update = true; + +static struct k_work_delayable scheduler_age_work; +static bool scheduler_age_work_initialized; +static int32_t scheduler_accumulated_samples; + +struct send_sched_rule_entry rule_entries[LWM2M_SEND_SCHED_RULES_MAX_INSTANCES]; + +static int send_sched_collect_paths(struct lwm2m_obj_path *paths, size_t max_paths); +static const struct lwm2m_obj_path * +send_sched_get_configured_path(struct send_sched_rule_entry *entry); +static int send_sched_find_rule_entry(const struct lwm2m_obj_path *path, + struct lwm2m_obj_path *parsed_path); +void send_sched_pmax_work_handler(struct k_work *work); +static void send_sched_record_cached_sample(void); +static void send_sched_maybe_flush_on_full(struct send_sched_rule_entry *entry); +static void send_sched_ensure_age_work_initialized(void); +static bool send_sched_find_oldest_timestamp(time_t *out_ts); +static void send_sched_age_work_handler(struct k_work *work); +static void send_sched_clear_cached_rules(struct send_sched_rule_entry *entry); +static void send_sched_refresh_cached_rules(struct send_sched_rule_entry *entry); + +static void send_sched_log_decision(const char *verb, const char *path_str, const char *reason) +{ + LOG_DBG("%s %s: %s", verb, path_str, reason); +} + +/* Compare two LwM2M paths for equality */ +static bool send_sched_paths_equal(const struct lwm2m_obj_path *lhs, + const struct lwm2m_obj_path *rhs) +{ + return lhs->obj_id == rhs->obj_id && lhs->obj_inst_id == rhs->obj_inst_id && + lhs->res_id == rhs->res_id && lhs->res_inst_id == rhs->res_inst_id && + lhs->level == rhs->level; +} + +/* Parse a textual object path into a LwM2M obj path structure */ +int send_sched_parse_path(const char *path, struct lwm2m_obj_path *out) +{ + const char *cursor = path; + unsigned long segments[3]; + char *end = NULL; + + if (!path || path[0] != '/') { + return -EINVAL; + } + + cursor++; + + for (int idx = 0; idx < ARRAY_SIZE(segments); idx++) { + unsigned long value; + + if (*cursor == '\0') { + return -EINVAL; + } + + errno = 0; + value = strtoul(cursor, &end, 10); + if (errno == ERANGE || value > UINT16_MAX) { + return -ERANGE; + } + + if (end == cursor) { + return -EINVAL; + } + + segments[idx] = value; + + if (idx < (ARRAY_SIZE(segments) - 1)) { + if (*end != '/') { + return -EINVAL; + } + + cursor = end + 1; + } else if (*end != '\0') { + return -EINVAL; + } + } + + *out = LWM2M_OBJ((uint16_t)segments[0], (uint16_t)segments[1], (uint16_t)segments[2]); + + return 0; +} + +/* Gather unique rule paths into the provided array */ +static int send_sched_collect_paths(struct lwm2m_obj_path *paths, size_t max_paths) +{ + int count = 0; + + if (!paths || max_paths == 0U) { + return 0; + } + + for (int idx = 0; idx < LWM2M_SEND_SCHED_RULES_MAX_INSTANCES; idx++) { + const struct lwm2m_obj_path *candidate; + bool duplicate = false; + + if (count >= (int)max_paths) { + LOG_WRN("Flush path list full (%zu entries)", max_paths); + break; + } + + if (rule_entries[idx].path[0] == '\0') { + continue; + } + + candidate = send_sched_get_configured_path(&rule_entries[idx]); + if (!candidate) { + LOG_WRN("Skipping invalid rule path '%s'", rule_entries[idx].path); + continue; + } + + struct lwm2m_time_series_resource *cache_entry = + lwm2m_cache_entry_get_by_object(candidate); + + if (!cache_entry || lwm2m_cache_size(cache_entry) == 0) { + LOG_DBG("No cached samples for %s, skipping", rule_entries[idx].path); + continue; + } + + for (int j = 0; j < count; j++) { + if (send_sched_paths_equal(&paths[j], candidate)) { + duplicate = true; + break; + } + } + + if (duplicate) { + continue; + } + + paths[count++] = *candidate; + } + + return count; +} + +/* Locate the configured path for a rule entry (parsing on demand) */ +static const struct lwm2m_obj_path * +send_sched_get_configured_path(struct send_sched_rule_entry *entry) +{ + struct lwm2m_obj_path parsed; + + if (!entry || entry->path[0] == '\0') { + return NULL; + } + + if (entry->has_configured_path) { + return &entry->configured_path; + } + + if (send_sched_parse_path(entry->path, &parsed) < 0) { + return NULL; + } + + entry->configured_path = parsed; + entry->has_configured_path = true; + + return &entry->configured_path; +} + +/* Locate the rule entry matching the given path */ +static int send_sched_find_rule_entry(const struct lwm2m_obj_path *path, + struct lwm2m_obj_path *parsed_path) +{ + for (int idx = 0; idx < LWM2M_SEND_SCHED_RULES_MAX_INSTANCES; idx++) { + struct send_sched_rule_entry *entry = &rule_entries[idx]; + const struct lwm2m_obj_path *candidate; + + if (entry->path[0] == '\0') { + continue; + } + + candidate = send_sched_get_configured_path(entry); + if (!candidate) { + continue; + } + + if (send_sched_paths_equal(path, candidate)) { + if (parsed_path) { + *parsed_path = *candidate; + } + return idx; + } + } + + return -ENOENT; +} + +/* Extract a floating-point value from a rule string */ +static bool send_sched_rule_parse_double(const char *rule, const char *attr, double *out_value) +{ + size_t attr_len; + char *end = NULL; + double value; + + if (!rule || !attr || !out_value) { + return false; + } + + attr_len = strlen(attr); + if (strncmp(rule, attr, attr_len) != 0) { + return false; + } + + if (rule[attr_len] != '=') { + return false; + } + + errno = 0; + value = strtod(&rule[attr_len + 1], &end); + if (errno == ERANGE) { + return false; + } + + if (end == &rule[attr_len + 1] || (end && *end != '\0')) { + return false; + } + + *out_value = value; + + return true; +} + +/* Extract an integer value from a rule string */ +bool send_sched_rule_parse_int(const char *rule, const char *attr, int32_t *out_value) +{ + size_t attr_len; + char *end = NULL; + long value; + + if (!rule || !attr || !out_value) { + return false; + } + + attr_len = strlen(attr); + if (strncmp(rule, attr, attr_len) != 0) { + return false; + } + + if (rule[attr_len] != '=') { + return false; + } + + errno = 0; + value = strtol(&rule[attr_len + 1], &end, 10); + if (errno == ERANGE || value < INT32_MIN || value > INT32_MAX) { + return false; + } + + if (end == &rule[attr_len + 1] || (end && *end != '\0')) { + return false; + } + + *out_value = (int32_t)value; + + return true; +} + +/* Cancel any pending pmax timer */ +void send_sched_cancel_pmax_timer(struct send_sched_rule_entry *entry) +{ + if (!entry) { + return; + } + + if (entry->pmax_timer_active) { + (void)k_work_cancel_delayable(&entry->pmax_work); + entry->pmax_timer_active = false; + } +} + +/* Arm (or re-arm) the pmax timer if configured */ +static void send_sched_arm_pmax_timer(struct send_sched_rule_entry *entry) +{ + if (!entry) { + return; + } + + if (entry->pmax_seconds <= 0) { + send_sched_cancel_pmax_timer(entry); + return; + } + + send_sched_cancel_pmax_timer(entry); + + int64_t now_ms = k_uptime_get(); + int64_t deadline_ms = entry->pmax_deadline_ms; + int64_t required_ms = (int64_t)entry->pmax_seconds * 1000LL; + + if (deadline_ms <= 0) { + deadline_ms = now_ms + required_ms; + entry->pmax_deadline_ms = deadline_ms; + } + + int64_t delay_ms = deadline_ms - now_ms; + + if (delay_ms < 0) { + delay_ms = 0; + } + + k_timeout_t timeout = K_MSEC((uint32_t)MIN(delay_ms, INT32_MAX)); + + if (k_work_schedule(&entry->pmax_work, timeout) < 0) { + LOG_WRN("Failed to schedule pmax timer for %s", entry->path); + entry->pmax_timer_active = false; + return; + } + + entry->pmax_timer_active = true; +} + +/* Work handler that forces a SEND when pmax expires */ +void send_sched_pmax_work_handler(struct k_work *work) +{ + struct k_work_delayable *dwork = CONTAINER_OF(work, struct k_work_delayable, work); + struct send_sched_rule_entry *entry = + CONTAINER_OF(dwork, struct send_sched_rule_entry, pmax_work); + struct lwm2m_obj_path path; + struct lwm2m_time_series_resource *cache_entry; + int ret; + int64_t now_ms; + char path_buf[LWM2M_MAX_PATH_STR_SIZE]; + + entry->pmax_timer_active = false; + + if (entry->path[0] == '\0') { + return; + } + + ret = send_sched_parse_path(entry->path, &path); + if (ret < 0) { + LOG_WRN("Skipping pmax cache refresh for invalid path '%s' (%d)", entry->path, ret); + return; + } + + cache_entry = lwm2m_cache_entry_get_by_object(&path); + if (!cache_entry) { + LOG_WRN("No cache entry available for %s when pmax expired", entry->path); + return; + } + + now_ms = k_uptime_get(); + + if (entry->has_last_reported) { + struct lwm2m_time_series_elem elem = entry->last_reported; + const char *path_str = lwm2m_path_log_buf(path_buf, &path); + char reason[64]; + time_t ts = time(NULL); + + if (ts <= 0) { + LOG_WRN("time() unavailable for pmax cache refresh on %s", entry->path); + } else { + elem.t = ts; + } + + if (!lwm2m_cache_write(cache_entry, &elem)) { + LOG_WRN("Failed to append cached sample for %s on pmax expiry", + entry->path); + } else { + entry->last_reported = elem; + entry->has_last_reported = true; + snprintk(reason, sizeof(reason), "pmax %d expired (cached)", + entry->pmax_seconds); + send_sched_log_decision("Cache", path_str, reason); + send_sched_schedule_age_check(); + } + } else { + LOG_DBG("pmax timer fired for %s before any sample cached", entry->path); + } + + entry->last_accept_ms = now_ms; + entry->has_last_accept_ms = true; + + if (entry->has_pmin && entry->pmin_seconds > 0) { + entry->pmin_deadline_ms = now_ms + ((int64_t)entry->pmin_seconds * 1000LL); + entry->pmin_waiting = false; + } else { + entry->pmin_waiting = false; + entry->pmin_deadline_ms = 0; + } + + if (entry->pmax_seconds > 0) { + entry->pmax_deadline_ms = now_ms + ((int64_t)entry->pmax_seconds * 1000LL); + send_sched_arm_pmax_timer(entry); + } else { + entry->pmax_deadline_ms = 0; + } +} + +/* Trigger a composite SEND for cached resources */ +int send_sched_flush_all(void) +{ + struct lwm2m_ctx *ctx; + struct lwm2m_obj_path path_list[LWM2M_SEND_SCHED_RULES_MAX_INSTANCES]; + int path_count; + int ret; + + ctx = lwm2m_rd_client_ctx(); + if (!ctx) { + LOG_WRN("Cannot flush caches: LwM2M context unavailable"); + return -ENODEV; + } + + path_count = send_sched_collect_paths(path_list, ARRAY_SIZE(path_list)); + if (path_count <= 0) { + LOG_WRN("No cached resources registered for flush"); + return -ENOENT; + } + + if (path_count > CONFIG_LWM2M_COMPOSITE_PATH_LIST_SIZE) { + LOG_WRN("Limiting flush to %d path(s)", CONFIG_LWM2M_COMPOSITE_PATH_LIST_SIZE); + path_count = CONFIG_LWM2M_COMPOSITE_PATH_LIST_SIZE; + } + + ret = lwm2m_send_cb(ctx, path_list, (uint8_t)path_count, NULL); + if (ret < 0) { + LOG_ERR("Failed to flush cached data (%d)", ret); + } else { + LOG_INF("Triggered LwM2M send for %d cached path(s)", path_count); + } + + send_sched_reset_accumulated_samples(); + send_sched_schedule_age_check(); + + return ret; +} + +void send_sched_reset_accumulated_samples(void) +{ + scheduler_accumulated_samples = 0; +} + +void send_sched_enforce_max_sample_limit(void) +{ + if (scheduler_max_samples <= 0) { + return; + } + + if (scheduler_accumulated_samples >= scheduler_max_samples) { + LOG_INF("Accumulated %d samples (limit %d), forcing SEND", + scheduler_accumulated_samples, scheduler_max_samples); + scheduler_accumulated_samples = 0; + (void)send_sched_flush_all(); + } +} + +static void send_sched_record_cached_sample(void) +{ + if (scheduler_accumulated_samples < INT32_MAX) { + scheduler_accumulated_samples++; + } + + send_sched_enforce_max_sample_limit(); +} + +static void send_sched_maybe_flush_on_full(struct send_sched_rule_entry *entry) +{ + int slots; + + if (!entry || !entry->has_cached_path) { + return; + } + + slots = lwm2m_cache_free_slots_get(&entry->cached_path); + if (slots < 0) { + /* No cache entry or API failure, nothing to do */ + return; + } + + if (slots == 0) { + LOG_DBG("Cache full for %s, triggering global SEND", entry->path); + (void)send_sched_flush_all(); + } +} + +static void send_sched_ensure_age_work_initialized(void) +{ + if (!scheduler_age_work_initialized) { + k_work_init_delayable(&scheduler_age_work, send_sched_age_work_handler); + scheduler_age_work_initialized = true; + } +} + +static bool send_sched_find_oldest_timestamp(time_t *out_ts) +{ + bool found = false; + time_t oldest = 0; + + for (int idx = 0; idx < LWM2M_SEND_SCHED_RULES_MAX_INSTANCES; idx++) { + struct send_sched_rule_entry *entry = &rule_entries[idx]; + struct lwm2m_obj_path path; + struct lwm2m_time_series_resource *cache_entry; + struct lwm2m_time_series_elem elem; + + if (entry->path[0] == '\0') { + continue; + } + + if (entry->has_cached_path) { + path = entry->cached_path; + } else if (send_sched_parse_path(entry->path, &path) < 0) { + continue; + } + + cache_entry = lwm2m_cache_entry_get_by_object(&path); + if (!cache_entry || ring_buf_is_empty(&cache_entry->rb)) { + continue; + } + + if (ring_buf_peek(&cache_entry->rb, (uint8_t *)&elem, sizeof(elem)) != + sizeof(elem)) { + continue; + } + + if (!found || elem.t < oldest) { + oldest = elem.t; + found = true; + } + } + + if (found && out_ts) { + *out_ts = oldest; + } + + return found; +} + +void send_sched_process_max_age(bool allow_flush) +{ + if (scheduler_max_age <= 0) { + if (scheduler_age_work_initialized) { + k_work_cancel_delayable(&scheduler_age_work); + } + return; + } + + send_sched_ensure_age_work_initialized(); + + time_t now = time(NULL); + time_t oldest_ts; + + if (now <= 0 || !send_sched_find_oldest_timestamp(&oldest_ts)) { + if (scheduler_age_work_initialized) { + k_work_cancel_delayable(&scheduler_age_work); + } + return; + } + + int64_t age = (int64_t)now - (int64_t)oldest_ts; + + if (age < 0) { + age = 0; + } + + if (allow_flush && age >= scheduler_max_age) { + LOG_INF("Oldest cached sample age %llds exceeds max %ds, forcing SEND", + (long long)age, scheduler_max_age); + (void)send_sched_flush_all(); + send_sched_schedule_age_check(); + return; + } + + int64_t remaining = (int64_t)scheduler_max_age - age; + + if (remaining < 1) { + remaining = 1; + } + + int64_t delay_ms = remaining * 1000LL; + + if (delay_ms > INT32_MAX) { + delay_ms = INT32_MAX; + } + + k_work_reschedule(&scheduler_age_work, K_MSEC((uint32_t)delay_ms)); +} + +void send_sched_schedule_age_check(void) +{ + if (scheduler_max_age <= 0) { + if (scheduler_age_work_initialized) { + k_work_cancel_delayable(&scheduler_age_work); + } + return; + } + + send_sched_process_max_age(false); +} + +static void send_sched_age_work_handler(struct k_work *work) +{ + ARG_UNUSED(work); + + send_sched_process_max_age(true); +} + +static void send_sched_clear_cached_rules(struct send_sched_rule_entry *entry) +{ + entry->has_rule_gt = false; + entry->has_rule_lt = false; + entry->has_rule_st = false; + entry->has_rule_pmin = false; + entry->has_rule_pmax = false; + entry->rule_gt_value = 0.0; + entry->rule_lt_value = 0.0; + entry->rule_st_value = 0.0; + entry->rule_pmin_seconds = 0; + entry->rule_pmax_seconds = 0; + entry->rules_dirty = false; +} + +static void send_sched_refresh_cached_rules(struct send_sched_rule_entry *entry) +{ + send_sched_clear_cached_rules(entry); + + for (int idx = 0; idx < LWM2M_SEND_SCHED_MAX_RULE_STRINGS; idx++) { + const char *rule = entry->rules[idx]; + + if (rule[0] == '\0') { + continue; + } + + if (!entry->has_rule_gt && + send_sched_rule_parse_double(rule, "gt", &entry->rule_gt_value)) { + entry->has_rule_gt = true; + continue; + } + + if (!entry->has_rule_lt && + send_sched_rule_parse_double(rule, "lt", &entry->rule_lt_value)) { + entry->has_rule_lt = true; + continue; + } + + if (!entry->has_rule_st && + send_sched_rule_parse_double(rule, "st", &entry->rule_st_value)) { + entry->has_rule_st = true; + continue; + } + + if (!entry->has_rule_pmin && + send_sched_rule_parse_int(rule, "pmin", &entry->rule_pmin_seconds)) { + if (entry->rule_pmin_seconds < 0) { + entry->rule_pmin_seconds = 0; + } + entry->has_rule_pmin = true; + continue; + } + + if (!entry->has_rule_pmax && + send_sched_rule_parse_int(rule, "pmax", &entry->rule_pmax_seconds)) { + if (entry->rule_pmax_seconds < 0) { + entry->rule_pmax_seconds = 0; + } + entry->has_rule_pmax = true; + continue; + } + } + + entry->rules_dirty = false; +} + +void lwm2m_send_sched_handle_registration_event(void) +{ + if (!send_sched_flush_on_update) { + return; + } + + (void)send_sched_flush_all(); +} + +/* Decide whether a sample should be cached for the configured path */ +bool lwm2m_send_sched_cache_filter(const struct lwm2m_obj_path *path, + const struct lwm2m_time_series_elem *element) +{ + int entry_idx; + struct lwm2m_obj_path entry_path; + struct send_sched_rule_entry *entry; + double sample_value; + bool trigger = false; + bool trigger_due_to_pmin_expiry = false; + char path_buf[LWM2M_MAX_PATH_STR_SIZE]; + struct lwm2m_obj_path path_copy; + const char *path_str = "unknown"; + char keep_reason[96] = {0}; + char drop_reason[96] = {0}; + bool drop_reason_set = false; + int64_t now_ms; + + if (!path || !element) { + return true; + } + + path_copy = *path; + path_str = lwm2m_path_log_buf(path_buf, &path_copy); + sample_value = element->f; + now_ms = k_uptime_get(); + + if (scheduler_paused) { + send_sched_log_decision("Drop", path_str, "scheduler paused"); + return false; + } + + entry_idx = send_sched_find_rule_entry(path, &entry_path); + if (entry_idx < 0) { + send_sched_log_decision("Drop", path_str, "no rule entry"); + return false; + } + + entry = &rule_entries[entry_idx]; + + if (!entry->has_cached_path || !send_sched_paths_equal(&entry->cached_path, &entry_path)) { + entry->cached_path = entry_path; + entry->has_cached_path = true; + entry->has_last_reported = false; + entry->has_last_observed = false; + } + + if (entry->rules_dirty) { + send_sched_refresh_cached_rules(entry); + } + + bool has_gt = entry->has_rule_gt; + bool has_lt = entry->has_rule_lt; + bool has_st = entry->has_rule_st; + bool has_pmin_rule = entry->has_rule_pmin; + bool has_pmax_rule = entry->has_rule_pmax; + double gt_value = entry->rule_gt_value; + double lt_value = entry->rule_lt_value; + double st_value = entry->rule_st_value; + int32_t pmin_seconds = entry->rule_pmin_seconds; + int32_t pmax_seconds = entry->rule_pmax_seconds; + + bool effective_has_pmin = (has_pmin_rule && pmin_seconds > 0); + bool effective_has_pmax = (has_pmax_rule && pmax_seconds > 0); + int64_t pmin_required_ms = 0; + int64_t pmax_required_ms = 0; + + if (effective_has_pmin) { + pmin_required_ms = (int64_t)pmin_seconds * 1000LL; + } + + if (effective_has_pmax && effective_has_pmin && pmax_seconds <= pmin_seconds) { + LOG_WRN("Ignoring pmax <= pmin for path %s", entry->path); + effective_has_pmax = false; + } + + entry->has_pmin = effective_has_pmin; + entry->pmin_seconds = effective_has_pmin ? pmin_seconds : 0; + if (!effective_has_pmin) { + entry->pmin_waiting = false; + entry->pmin_deadline_ms = 0; + } + + entry->pmax_seconds = effective_has_pmax ? pmax_seconds : 0; + if (effective_has_pmax) { + pmax_required_ms = (int64_t)pmax_seconds * 1000LL; + if (entry->has_last_accept_ms) { + entry->pmax_deadline_ms = entry->last_accept_ms + pmax_required_ms; + } else if (entry->pmax_deadline_ms == 0) { + entry->pmax_deadline_ms = now_ms + pmax_required_ms; + } + send_sched_arm_pmax_timer(entry); + } else { + send_sched_cancel_pmax_timer(entry); + entry->pmax_deadline_ms = 0; + } + + if (effective_has_pmin && entry->pmin_waiting && now_ms >= entry->pmin_deadline_ms) { + trigger = true; + trigger_due_to_pmin_expiry = true; + entry->pmin_waiting = false; + snprintk(keep_reason, sizeof(keep_reason), "pmin %d expired", pmin_seconds); + } + + if (effective_has_pmax && entry->pmax_deadline_ms > 0 && + now_ms >= entry->pmax_deadline_ms) { + trigger = true; + if (keep_reason[0] == '\0') { + snprintk(keep_reason, sizeof(keep_reason), "pmax %d expired", pmax_seconds); + } + } + + if (!has_gt && !has_lt && !has_st) { + trigger = true; + snprintk(keep_reason, sizeof(keep_reason), "no threshold rules configured"); + } + + if (has_gt) { + if (sample_value > gt_value) { + if (!entry->has_last_observed || entry->last_observed <= gt_value) { + trigger = true; + snprintk(keep_reason, sizeof(keep_reason), "crossed gt threshold"); + } else { + snprintk(drop_reason, sizeof(drop_reason), + "above gt threshold but already above"); + drop_reason_set = true; + } + } + } + + if (!trigger && has_lt) { + if (sample_value < lt_value) { + if (!entry->has_last_observed || entry->last_observed >= lt_value) { + trigger = true; + snprintk(keep_reason, sizeof(keep_reason), "crossed lt threshold"); + } else if (!drop_reason_set) { + snprintk(drop_reason, sizeof(drop_reason), + "below lt threshold but already below"); + drop_reason_set = true; + } + } + } + + if (!trigger && has_st) { + if (!entry->has_last_reported) { + trigger = true; + snprintk(keep_reason, sizeof(keep_reason), "no prior sample, st rule set"); + } else { + double delta = sample_value - entry->last_reported.f; + + if (delta < 0.0) { + delta = -delta; + } + + if (delta >= st_value) { + trigger = true; + snprintk(keep_reason, sizeof(keep_reason), + "delta exceeded st threshold"); + } else if (!drop_reason_set) { + snprintk(drop_reason, sizeof(drop_reason), + "delta below st threshold"); + drop_reason_set = true; + } + } + } + + entry->last_observed = sample_value; + entry->has_last_observed = true; + + if (!trigger) { + if (!drop_reason_set) { + snprintk(drop_reason, sizeof(drop_reason), "no rule triggered"); + } + send_sched_log_decision("Drop", path_str, drop_reason); + return false; + } + + if (effective_has_pmin && entry->has_last_accept_ms && !trigger_due_to_pmin_expiry) { + int64_t elapsed_ms = now_ms - entry->last_accept_ms; + + if (elapsed_ms < pmin_required_ms) { + int64_t remaining_ms = pmin_required_ms - elapsed_ms; + + entry->pmin_waiting = true; + entry->pmin_deadline_ms = entry->last_accept_ms + pmin_required_ms; + + snprintk(drop_reason, sizeof(drop_reason), + "pmin %d active (%lld ms remaining)", pmin_seconds, + (long long)remaining_ms); + send_sched_log_decision("Defer", path_str, drop_reason); + return false; + } + } + + entry->last_reported = *element; + entry->has_last_reported = true; + entry->last_accept_ms = now_ms; + entry->has_last_accept_ms = true; + + if (effective_has_pmin) { + entry->pmin_deadline_ms = entry->last_accept_ms + pmin_required_ms; + entry->pmin_waiting = false; + } else { + entry->pmin_waiting = false; + entry->pmin_deadline_ms = 0; + } + + if (entry->pmax_seconds > 0) { + entry->pmax_deadline_ms = + entry->last_accept_ms + ((int64_t)entry->pmax_seconds * 1000LL); + send_sched_arm_pmax_timer(entry); + } else { + send_sched_cancel_pmax_timer(entry); + entry->pmax_deadline_ms = 0; + } + + if (keep_reason[0] == '\0') { + snprintk(keep_reason, sizeof(keep_reason), "rule triggered"); + } + + send_sched_log_decision("Keep", path_str, keep_reason); + send_sched_record_cached_sample(); + send_sched_maybe_flush_on_full(entry); + send_sched_schedule_age_check(); + + return true; +} diff --git a/subsys/net/lib/lwm2m/send_scheduler/send_scheduler_internal.h b/subsys/net/lib/lwm2m/send_scheduler/send_scheduler_internal.h new file mode 100644 index 000000000000..493ae0c5e351 --- /dev/null +++ b/subsys/net/lib/lwm2m/send_scheduler/send_scheduler_internal.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2025 Clunky Machines + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_LWM2M_SEND_SCHEDULER_INTERNAL_H_ +#define ZEPHYR_LWM2M_SEND_SCHEDULER_INTERNAL_H_ + +#include +#include +#include +#include + +/* Provide a small buffer for rule definitions that the engine can mutate */ +#define LWM2M_SEND_SCHED_MAX_RULE_STRINGS 4 +#define LWM2M_SEND_SCHED_RULE_STRING_SIZE 64 +#define LWM2M_SEND_SCHED_RULES_MAX_INSTANCES 4 + +/* Aggregated bookkeeping for one scheduler rule instance */ +struct send_sched_rule_entry { + char path[LWM2M_SEND_SCHED_RULE_STRING_SIZE]; /* LwM2M path string (/obj/inst/res) */ + struct lwm2m_obj_path cached_path; /* Parsed path for cache lookups */ + bool has_cached_path; /* Guard for cached_path validity */ + struct lwm2m_obj_path configured_path; /* Parsed resource path from */ + /* /20001/X/0 */ + bool has_configured_path; /* Guard for configured_path validity */ + char rules[LWM2M_SEND_SCHED_MAX_RULE_STRINGS][LWM2M_SEND_SCHED_RULE_STRING_SIZE]; + /* Raw rule strings (gt/lt/st/pmin/pmax) */ + double last_observed; /* Most recent sample seen, even if dropped */ + bool has_last_observed; /* Guard for last_observed validity */ + struct lwm2m_time_series_elem last_reported; /* Last sample committed */ + bool has_last_reported; /* Guard for last_reported validity */ + int64_t last_accept_ms; /* Monotonic timestamp (ms) of last accepted sample */ + bool has_last_accept_ms; /* Guard for last_accept_ms */ + int64_t pmin_deadline_ms; /* Next time pmin allows a sample */ + bool pmin_waiting; /* True when we are deferring because of pmin */ + bool has_pmin; /* pmin is configured (>0) */ + int32_t pmin_seconds; /* Cached pmin seconds value */ + int64_t pmax_deadline_ms; /* Next time pmax requires a cached refresh */ + int32_t pmax_seconds; /* Cached pmax seconds value */ + struct k_work_delayable pmax_work; /* Work item used to enforce pmax */ + bool pmax_timer_active; /* True if the pmax timer is scheduled */ + bool rules_dirty; /* True when parsed rule cache needs refresh */ + bool has_rule_gt; + bool has_rule_lt; + bool has_rule_st; + bool has_rule_pmin; + bool has_rule_pmax; + double rule_gt_value; + double rule_lt_value; + double rule_st_value; + int32_t rule_pmin_seconds; + int32_t rule_pmax_seconds; +}; + +extern bool scheduler_paused; +extern int32_t scheduler_max_samples; +extern int32_t scheduler_max_age; +extern bool send_sched_flush_on_update; +extern struct send_sched_rule_entry rule_entries[LWM2M_SEND_SCHED_RULES_MAX_INSTANCES]; + +int send_sched_parse_path(const char *path, struct lwm2m_obj_path *out); +bool send_sched_rule_parse_int(const char *rule, const char *attr, int32_t *out_value); +void send_sched_cancel_pmax_timer(struct send_sched_rule_entry *entry); +void send_sched_pmax_work_handler(struct k_work *work); +int send_sched_flush_all(void); +void send_sched_schedule_age_check(void); +void send_sched_process_max_age(bool allow_flush); +void send_sched_enforce_max_sample_limit(void); +void send_sched_reset_accumulated_samples(void); +void lwm2m_send_sched_handle_registration_event(void); + +#endif /* ZEPHYR_LWM2M_SEND_SCHEDULER_INTERNAL_H_ */ From 19666bb12ed98c3ae2b17484c3333d596da39a17 Mon Sep 17 00:00:00 2001 From: Mathieu Choplain Date: Thu, 4 Dec 2025 15:07:53 +0100 Subject: [PATCH 0028/3659] drivers: gpio: stm32: bubble-up wake-up pin configuration error When an error occurs while attempting to configure a GPIO pin as wake-up pin, return the error to the caller instead of merely printing a log message which may not even be displayed. Signed-off-by: Mathieu Choplain --- drivers/gpio/gpio_stm32.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpio/gpio_stm32.c b/drivers/gpio/gpio_stm32.c index e58183b81258..b64f7a8a0bea 100644 --- a/drivers/gpio/gpio_stm32.c +++ b/drivers/gpio/gpio_stm32.c @@ -530,9 +530,11 @@ static int gpio_stm32_config(const struct device *dev, .dt_flags = (gpio_dt_flags_t)flags, }; - if (stm32_pwr_wkup_pin_cfg_gpio((const struct gpio_dt_spec *)&gpio_dt_cfg)) { + err = stm32_pwr_wkup_pin_cfg_gpio(&gpio_dt_cfg); + if (err < 0) { LOG_ERR("Could not configure GPIO %s pin %d as a wake-up source", gpio_dt_cfg.port->name, gpio_dt_cfg.pin); + return err; } #else LOG_DBG("STM32_GPIO_WKUP flag has no effect when CONFIG_POWEROFF=n"); From 65f710f6f4b33e97bf067d4dd6e30030f41bf907 Mon Sep 17 00:00:00 2001 From: Mathieu Choplain Date: Thu, 4 Dec 2025 15:19:42 +0100 Subject: [PATCH 0029/3659] drivers: gpio: stm32: return error on invalid WKUP configuration for WBA When an invalid GPIO configuration is provided for a wake-up pin on STM32WBA series, display a series-specific message and return an error. Signed-off-by: Mathieu Choplain --- drivers/gpio/gpio_stm32.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/drivers/gpio/gpio_stm32.c b/drivers/gpio/gpio_stm32.c index b64f7a8a0bea..a90228943dfa 100644 --- a/drivers/gpio/gpio_stm32.c +++ b/drivers/gpio/gpio_stm32.c @@ -524,6 +524,24 @@ static int gpio_stm32_config(const struct device *dev, #ifdef CONFIG_STM32_WKUP_PINS if (flags & STM32_GPIO_WKUP) { #ifdef CONFIG_POWEROFF + /* + * On some series, wake-up pins must have a specific configuration + * to work properly. The following per-series checks validate that + * the configuration provided by caller is correct. + */ + if (IS_ENABLED(CONFIG_SOC_SERIES_STM32WBAX) && + (flags & GPIO_OUTPUT) == 0 && + ((flags & GPIO_INPUT) == 0 || (flags & (GPIO_PULL_DOWN | GPIO_PULL_UP)) == 0)) { + /* + * RM0493 Rev. 7 Table 93 / RM0515 Rev. 3 Table 95: + * Only input pins with PU/PD and output pins are retained in Standby. + * Other pins are placed in High-Z state and can't be used for wake-up. + */ + LOG_ERR("STM32WBA: wake-up pin must be configured as " + "output, or input+pull-up/pull-down"); + return -EINVAL; + } + struct gpio_dt_spec gpio_dt_cfg = { .port = dev, .pin = pin, From dc7f445dbd1d20f0a36038e2148b2a8cc7d09037 Mon Sep 17 00:00:00 2001 From: Julien Racki Date: Tue, 9 Dec 2025 10:56:25 +0100 Subject: [PATCH 0030/3659] drivers: ethernet: stm32: Add generic helper functions This commit introduces helper functions to avoid having large #if DT_HAS_COMPAT_STATUS_OKAY ... #else blocks, improving readability. Signed-off-by: Julien Racki --- drivers/ethernet/eth_stm32_hal_ptp.c | 126 +++++++++++++++------------ drivers/ethernet/eth_stm32_hal_v2.c | 76 +++++++++------- 2 files changed, 116 insertions(+), 86 deletions(-) diff --git a/drivers/ethernet/eth_stm32_hal_ptp.c b/drivers/ethernet/eth_stm32_hal_ptp.c index 7a4ae0574d17..b6dea8ef3652 100644 --- a/drivers/ethernet/eth_stm32_hal_ptp.c +++ b/drivers/ethernet/eth_stm32_hal_ptp.c @@ -212,6 +212,72 @@ static int ptp_clock_stm32_rate_adjust(const struct device *dev, double ratio) return ret; } +static void eth_stm32_ptp_enable_timestamping(ETH_HandleTypeDef *heth) +{ + /* Mask the Timestamp Trigger interrupt and enable timestamping */ +#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) + heth->Instance->MACIER &= ~(ETH_MACIER_TSIE); + heth->Instance->MACTSCR |= ETH_MACTSCR_TSENA; +#else + heth->Instance->MACIMR &= ~(ETH_MACIMR_TSTIM); + heth->Instance->PTPTSCR |= ETH_PTPTSCR_TSE; +#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) */ +} + +static void eth_stm32_ptp_set_addend(ETH_HandleTypeDef *heth, uint32_t addend_val) +{ +#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) + heth->Instance->MACTSAR = addend_val; + heth->Instance->MACTSCR |= ETH_MACTSCR_TSADDREG; + while (heth->Instance->MACTSCR & ETH_MACTSCR_TSADDREG_Msk) { + k_yield(); + } +#else + heth->Instance->PTPTSAR = addend_val; + heth->Instance->PTPTSCR |= ETH_PTPTSCR_TSARU; + while (heth->Instance->PTPTSCR & ETH_PTPTSCR_TSARU_Msk) { + k_yield(); + } +#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) */ +} + +static void eth_stm32_ptp_enable_fine_timestamp_update(ETH_HandleTypeDef *heth) +{ +#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) + heth->Instance->MACTSCR |= ETH_MACTSCR_TSCFUPDT; +#else + heth->Instance->PTPTSCR |= ETH_PTPTSCR_TSFCU; +#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) */ +} + +static void eth_stm32_ptp_enable_nsec_rollover(ETH_HandleTypeDef *heth) +{ +#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) + heth->Instance->MACTSCR |= ETH_MACTSCR_TSCTRLSSR; +#else + heth->Instance->PTPTSCR |= ETH_PTPTSCR_TSSSR; +#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) */ +} + +static void eth_stm32_ptp_init_timestamp(ETH_HandleTypeDef *heth) +{ +#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) + heth->Instance->MACSTSUR = 0; + heth->Instance->MACSTNUR = 0; + heth->Instance->MACTSCR |= ETH_MACTSCR_TSINIT; + while (heth->Instance->MACTSCR & ETH_MACTSCR_TSINIT_Msk) { + k_yield(); + } +#else + heth->Instance->PTPTSHUR = 0; + heth->Instance->PTPTSLUR = 0; + heth->Instance->PTPTSCR |= ETH_PTPTSCR_TSSTI; + while (heth->Instance->PTPTSCR & ETH_PTPTSCR_TSSTI_Msk) { + k_yield(); + } +#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) */ +} + static DEVICE_API(ptp_clock, api) = { .set = ptp_clock_stm32_set, .get = ptp_clock_stm32_get, @@ -234,19 +300,7 @@ static int ptp_stm32_init(const struct device *port) eth_dev_data->ptp_clock = port; ptp_context->eth_dev_data = eth_dev_data; - /* Mask the Timestamp Trigger interrupt */ -#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) - heth->Instance->MACIER &= ~(ETH_MACIER_TSIE); -#else - heth->Instance->MACIMR &= ~(ETH_MACIMR_TSTIM); -#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) */ - - /* Enable timestamping */ -#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) - heth->Instance->MACTSCR |= ETH_MACTSCR_TSENA; -#else - heth->Instance->PTPTSCR |= ETH_PTPTSCR_TSE; -#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) */ + eth_stm32_ptp_enable_timestamping(heth); /* Query ethernet clock rate */ ret = clock_control_get_rate(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE), @@ -288,50 +342,14 @@ static int ptp_stm32_init(const struct device *port) */ addend_val = UINT32_MAX * eth_dev_data->clk_ratio; -#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) - heth->Instance->MACTSAR = addend_val; - heth->Instance->MACTSCR |= ETH_MACTSCR_TSADDREG; - while (heth->Instance->MACTSCR & ETH_MACTSCR_TSADDREG_Msk) { - k_yield(); - } -#else - heth->Instance->PTPTSAR = addend_val; - heth->Instance->PTPTSCR |= ETH_PTPTSCR_TSARU; - while (heth->Instance->PTPTSCR & ETH_PTPTSCR_TSARU_Msk) { - k_yield(); - } -#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) */ - /* Enable fine timestamp correction method */ -#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) - heth->Instance->MACTSCR |= ETH_MACTSCR_TSCFUPDT; -#else - heth->Instance->PTPTSCR |= ETH_PTPTSCR_TSFCU; -#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) */ + eth_stm32_ptp_set_addend(heth, addend_val); - /* Enable nanosecond rollover into a new second */ -#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) - heth->Instance->MACTSCR |= ETH_MACTSCR_TSCTRLSSR; -#else - heth->Instance->PTPTSCR |= ETH_PTPTSCR_TSSSR; -#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) */ + eth_stm32_ptp_enable_fine_timestamp_update(heth); - /* Initialize timestamp */ -#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) - heth->Instance->MACSTSUR = 0; - heth->Instance->MACSTNUR = 0; - heth->Instance->MACTSCR |= ETH_MACTSCR_TSINIT; - while (heth->Instance->MACTSCR & ETH_MACTSCR_TSINIT_Msk) { - k_yield(); - } -#else - heth->Instance->PTPTSHUR = 0; - heth->Instance->PTPTSLUR = 0; - heth->Instance->PTPTSCR |= ETH_PTPTSCR_TSSTI; - while (heth->Instance->PTPTSCR & ETH_PTPTSCR_TSSTI_Msk) { - k_yield(); - } -#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) */ + eth_stm32_ptp_enable_nsec_rollover(heth); + + eth_stm32_ptp_init_timestamp(heth); /* Set PTP Configuration done */ heth->IsPtpConfigured = ETH_STM32_PTP_CONFIGURED; diff --git a/drivers/ethernet/eth_stm32_hal_v2.c b/drivers/ethernet/eth_stm32_hal_v2.c index 8be6ac034aef..9992d15b930b 100644 --- a/drivers/ethernet/eth_stm32_hal_v2.c +++ b/drivers/ethernet/eth_stm32_hal_v2.c @@ -490,6 +490,47 @@ void HAL_ETH_TxCpltCallback(ETH_HandleTypeDef *heth_handle) } +#if defined(CONFIG_NET_STATISTICS_ETHERNET) +static void eth_stm32_update_dma_error(struct eth_stm32_hal_dev_data *dev_data, uint32_t dma_error) +{ +#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) + if ((dma_error & ETH_DMA_RX_WATCHDOG_TIMEOUT_FLAG) || + (dma_error & ETH_DMA_RX_PROCESS_STOPPED_FLAG) || + (dma_error & ETH_DMA_RX_BUFFER_UNAVAILABLE_FLAG)) { + eth_stats_update_errors_rx(dev_data->iface); + } + if ((dma_error & ETH_DMA_EARLY_TX_IT_FLAG) || + (dma_error & ETH_DMA_TX_PROCESS_STOPPED_FLAG)) { + eth_stats_update_errors_tx(dev_data->iface); + } +#else + if ((dma_error & ETH_DMASR_RWTS) || (dma_error & ETH_DMASR_RPSS) || + (dma_error & ETH_DMASR_RBUS)) { + eth_stats_update_errors_rx(dev_data->iface); + } + if ((dma_error & ETH_DMASR_ETS) || (dma_error & ETH_DMASR_TPSS) || + (dma_error & ETH_DMASR_TJTS)) { + eth_stats_update_errors_tx(dev_data->iface); + } +#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) */ +} + +static void eth_stm32_update_rx_error_details(ETH_HandleTypeDef *heth, + struct eth_stm32_hal_dev_data *dev_data) +{ +#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32mp13_ethernet) + dev_data->stats.error_details.rx_crc_errors = heth->Instance->MMCRXCRCEPR; + dev_data->stats.error_details.rx_align_errors = heth->Instance->MMCRXAEPR; +#elif DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) + dev_data->stats.error_details.rx_crc_errors = heth->Instance->MMCRCRCEPR; + dev_data->stats.error_details.rx_align_errors = heth->Instance->MMCRAEPR; +#else + dev_data->stats.error_details.rx_crc_errors = heth->Instance->MMCRFCECR; + dev_data->stats.error_details.rx_align_errors = heth->Instance->MMCRFAECR; +#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32mp13_ethernet) */ +} +#endif /* CONFIG_NET_STATISTICS_ETHERNET */ + void HAL_ETH_ErrorCallback(ETH_HandleTypeDef *heth) { /* Do not log errors. If errors are reported due to high traffic, @@ -516,28 +557,8 @@ void HAL_ETH_ErrorCallback(ETH_HandleTypeDef *heth) #endif dma_error = HAL_ETH_GetDMAError(heth); -#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) - if ((dma_error & ETH_DMA_RX_WATCHDOG_TIMEOUT_FLAG) || - (dma_error & ETH_DMA_RX_PROCESS_STOPPED_FLAG) || - (dma_error & ETH_DMA_RX_BUFFER_UNAVAILABLE_FLAG)) { - eth_stats_update_errors_rx(dev_data->iface); - } - if ((dma_error & ETH_DMA_EARLY_TX_IT_FLAG) || - (dma_error & ETH_DMA_TX_PROCESS_STOPPED_FLAG)) { - eth_stats_update_errors_tx(dev_data->iface); - } -#else - if ((dma_error & ETH_DMASR_RWTS) || - (dma_error & ETH_DMASR_RPSS) || - (dma_error & ETH_DMASR_RBUS)) { - eth_stats_update_errors_rx(dev_data->iface); - } - if ((dma_error & ETH_DMASR_ETS) || - (dma_error & ETH_DMASR_TPSS) || - (dma_error & ETH_DMASR_TJTS)) { - eth_stats_update_errors_tx(dev_data->iface); - } -#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) */ + eth_stm32_update_dma_error(dev_data, dma_error); + break; #if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) @@ -560,16 +581,7 @@ void HAL_ETH_ErrorCallback(ETH_HandleTypeDef *heth) #endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) */ } -#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32mp13_ethernet) - dev_data->stats.error_details.rx_crc_errors = heth->Instance->MMCRXCRCEPR; - dev_data->stats.error_details.rx_align_errors = heth->Instance->MMCRXAEPR; -#elif DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) - dev_data->stats.error_details.rx_crc_errors = heth->Instance->MMCRCRCEPR; - dev_data->stats.error_details.rx_align_errors = heth->Instance->MMCRAEPR; -#else - dev_data->stats.error_details.rx_crc_errors = heth->Instance->MMCRFCECR; - dev_data->stats.error_details.rx_align_errors = heth->Instance->MMCRFAECR; -#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) */ + eth_stm32_update_rx_error_details(heth, dev_data); #endif /* CONFIG_NET_STATISTICS_ETHERNET */ } From 3e081acf9c9cadf466dd5683383504e43ebb8a82 Mon Sep 17 00:00:00 2001 From: Jonathan Nilsen Date: Fri, 5 Dec 2025 12:47:46 +0100 Subject: [PATCH 0031/3659] soc: nordic: uicr: fix pin function ignore handling in CTRLSEL lookup Selecting the correct CTRLSEL value for VPR IO pins relies on mapping any pinctrl psel value with the correct port/pin set on the VPR nodes in devicetree to the same CTRLSEL value, to avoid enumerating all permutations of (pin function, port, pin). However, the mechanism did not work as intended and ended up mapping all these pins to GPIO instead, which meant that the pins did not behave as expected. Update the handling so that it works as intended. Signed-off-by: Jonathan Nilsen --- soc/nordic/common/uicr/periphconf/builder.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/soc/nordic/common/uicr/periphconf/builder.py b/soc/nordic/common/uicr/periphconf/builder.py index 06d8c9413dcf..34ccc6f7b497 100644 --- a/soc/nordic/common/uicr/periphconf/builder.py +++ b/soc/nordic/common/uicr/periphconf/builder.py @@ -1115,19 +1115,21 @@ def lookup_ctrlsel_for_property(self, prop: Property, psel: tuple[int, int]) -> def lookup_ctrlsel_for_pinctrl(self, prop: PinCtrl, psel: NrfPsel) -> Ctrlsel | None: """Find the appopriate CTRLSEL value for a given pinctrl.""" + ctrlsel_default = None if psel.fun == NrfFun.ASSUMED_GPIO: # We map unsupported values to GPIO CTRLSEL - return CTRLSEL_DEFAULT + ctrlsel_default = CTRLSEL_DEFAULT periph_addr = dt_reg_addr(prop.node, secure=True) - return self._lookup_ctrlsel(periph_addr, psel) + return self._lookup_ctrlsel(periph_addr, psel, ctrlsel_default=ctrlsel_default) def _lookup_ctrlsel( self, periph_addr: int, prop_or_psel: NrfPsel | GpiosProp, + ctrlsel_default: Ctrlsel | None = None, ) -> Ctrlsel | None: - ctrlsel = None + ctrlsel = ctrlsel_default if periph_addr in self.ctrlsel_lookup: ident_lut = self.ctrlsel_lookup[periph_addr] From 15a347b4051651a02598d604f89a4d7982216b5e Mon Sep 17 00:00:00 2001 From: Yassine El Aissaoui Date: Fri, 5 Dec 2025 14:54:30 +0100 Subject: [PATCH 0032/3659] drivers: mcux_os_timer: Add Kconfig option for MIN_DELAY configuration Introduce CONFIG_MCUX_OS_TIMER_MIN_DELAY to allow the configuration of the minimum delay cycles. Signed-off-by: Yassine El Aissaoui --- drivers/timer/Kconfig.mcux_os | 10 ++++++++++ drivers/timer/mcux_os_timer.c | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/timer/Kconfig.mcux_os b/drivers/timer/Kconfig.mcux_os index ed2920bf3001..26a3ac9885f4 100644 --- a/drivers/timer/Kconfig.mcux_os +++ b/drivers/timer/Kconfig.mcux_os @@ -21,4 +21,14 @@ config MCUX_OS_TIMER_PM_POWERED_OFF OS Timer is turned off in certain low power modes. When this option is picked, OS Timer will take steps to store state and reinitialize on wakeups. +config MCUX_OS_TIMER_MIN_DELAY + int "Minimum delay cycles for OS timer match value" + default 1000 + help + Timer hardware requires a minimum setup time to reliably trigger + interrupts. If a match value is set too close to the current timer + count, the hardware may not have enough time to process it. + Lower values can improve timing precision but may be less reliable. + Higher values provide more safety margin but slightly reduce timing accuracy. + endif # MCUX_OS_TIMER diff --git a/drivers/timer/mcux_os_timer.c b/drivers/timer/mcux_os_timer.c index bbadcece8a37..a2b761e32bab 100644 --- a/drivers/timer/mcux_os_timer.c +++ b/drivers/timer/mcux_os_timer.c @@ -28,7 +28,7 @@ #define CYC_PER_US ((uint32_t)((uint64_t)sys_clock_hw_cycles_per_sec() / (uint64_t)USEC_PER_SEC)) #define MAX_CYC INT_MAX #define MAX_TICKS ((MAX_CYC - CYC_PER_TICK) / CYC_PER_TICK) -#define MIN_DELAY 1000 +#define MIN_DELAY CONFIG_MCUX_OS_TIMER_MIN_DELAY static struct k_spinlock lock; static uint64_t last_count; From 79b90253151e0b3b79cf8c6dd2e1b11b6dd1aac5 Mon Sep 17 00:00:00 2001 From: Joakim Andersson Date: Fri, 5 Dec 2025 14:57:53 +0100 Subject: [PATCH 0033/3659] drivers: modem: Include empty string arguments in argument parsing When parsing AT command responses, empty string arguments were being ignored if they occur it the end of the response. This is not only iconsistent behavior, but also causes issues when parsing responses where we need to know the number of arguments. For example, the +CEREG response and unsolicited command response which we need to know if it is response or unsolicited command response to correctly parse the it, as the first argument will be different. Example: Response: +CEREG: 5,4,\"0A0B\",\"FFFFFFFF\",9,0,0,, Notification: +CEREG: 4,\"0A0B\",\"FFFFFFFF\",9,0,0,, Here we want to know that response has 8 arguments, not 7, or we will confuse it with the notification. Signed-off-by: Joakim Andersson --- drivers/modem/modem_cmd_handler.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/modem/modem_cmd_handler.c b/drivers/modem/modem_cmd_handler.c index 2893f7369473..75e322bf6da7 100644 --- a/drivers/modem/modem_cmd_handler.c +++ b/drivers/modem/modem_cmd_handler.c @@ -150,8 +150,8 @@ static int parse_params(struct modem_cmd_handler_data *data, size_t match_len, end++; } - /* consider the ending portion a param if end > begin */ - if (end > begin) { + /* consider the ending portion a param if end >= begin (includes empty string arguments). */ + if (end >= begin && *argc < argv_len && count < cmd->arg_count_max) { /* mark a parameter beginning */ argv[*argc] = &data->match_buf[begin]; /* end parameter with NUL char From 2226ba877843d3642d970bbfdbb8f04757c68482 Mon Sep 17 00:00:00 2001 From: Joakim Andersson Date: Sat, 6 Dec 2025 15:19:37 +0100 Subject: [PATCH 0034/3659] test: drivers: modem: Test modem cmd send and parse response Add test cases to verify modem_cmd_send functionality, including parsing of response parameters. Signed-off-by: Joakim Andersson --- .../modem/modem_cmd_handler/CMakeLists.txt | 12 + .../drivers/modem/modem_cmd_handler/prj.conf | 11 + .../modem/modem_cmd_handler/src/main.c | 448 ++++++++++++++++++ .../modem/modem_cmd_handler/testcase.yaml | 9 + 4 files changed, 480 insertions(+) create mode 100644 tests/drivers/modem/modem_cmd_handler/CMakeLists.txt create mode 100644 tests/drivers/modem/modem_cmd_handler/prj.conf create mode 100644 tests/drivers/modem/modem_cmd_handler/src/main.c create mode 100644 tests/drivers/modem/modem_cmd_handler/testcase.yaml diff --git a/tests/drivers/modem/modem_cmd_handler/CMakeLists.txt b/tests/drivers/modem/modem_cmd_handler/CMakeLists.txt new file mode 100644 index 000000000000..ecd54e1fb4f3 --- /dev/null +++ b/tests/drivers/modem/modem_cmd_handler/CMakeLists.txt @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(device) + +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources}) + +target_include_directories(app PRIVATE + ${ZEPHYR_BASE}/drivers/modem +) diff --git a/tests/drivers/modem/modem_cmd_handler/prj.conf b/tests/drivers/modem/modem_cmd_handler/prj.conf new file mode 100644 index 000000000000..670bf58f3788 --- /dev/null +++ b/tests/drivers/modem/modem_cmd_handler/prj.conf @@ -0,0 +1,11 @@ +CONFIG_ZTEST=y + +CONFIG_NETWORKING=y +CONFIG_NET_SOCKETS=y + +CONFIG_MODEM=y +CONFIG_MODEM_CMD_HANDLER=y +CONFIG_MODEM_CONTEXT=y + +# Default y, not needed. +CONFIG_ETH_DRIVER=n diff --git a/tests/drivers/modem/modem_cmd_handler/src/main.c b/tests/drivers/modem/modem_cmd_handler/src/main.c new file mode 100644 index 000000000000..a992ab97160a --- /dev/null +++ b/tests/drivers/modem/modem_cmd_handler/src/main.c @@ -0,0 +1,448 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (C) 2025, Joakim Andersson + */ + +/** + * @addtogroup t_modem_driver + * @{ + * @defgroup t_modem_cmd_handler test_modem_cmd_handler + * @} + */ + + +#include +#include +#include + +DEFINE_FFF_GLOBALS; + +static struct modem_cmd_handler_data cmd_handler_data; +static struct modem_cmd_handler cmd_handler; +static struct modem_iface mock_modem_iface; +static struct k_sem sem_response; +#define MDM_RECV_BUF_SIZE 512 +NET_BUF_POOL_DEFINE(_mdm_recv_pool, 10, MDM_RECV_BUF_SIZE, 0, NULL); + +uint8_t cmd_match_buf[MDM_RECV_BUF_SIZE + 1]; + +MODEM_CMD_DEFINE(mock_on_cmd_ok) +{ + modem_cmd_handler_set_error(data, 0); + k_sem_give(&sem_response); + return 0; +} + +MODEM_CMD_DEFINE(mock_on_cmd_error) +{ + modem_cmd_handler_set_error(data, -EIO); + k_sem_give(&sem_response); + return 0; +} + +static const struct modem_cmd mock_response_cmds[] = { + MODEM_CMD("OK", mock_on_cmd_ok, 0U, ""), /* 3GPP */ + MODEM_CMD("ERROR", mock_on_cmd_error, 0U, ""), /* 3GPP */ +}; + +static const struct modem_cmd_handler_config cmd_handler_config = { + .match_buf = &cmd_match_buf[0], + .match_buf_len = sizeof(cmd_match_buf), + .buf_pool = &_mdm_recv_pool, + .alloc_timeout = K_NO_WAIT, + .eol = "\r", + .user_data = NULL, + .response_cmds = mock_response_cmds, + .response_cmds_len = ARRAY_SIZE(mock_response_cmds), + .unsol_cmds = NULL, + .unsol_cmds_len = 0, +}; + +static const char *response_delayed; +size_t mock_write_expected_data_count; +static const char *mock_write_expected_data[10]; + +FAKE_VALUE_FUNC(int, mock_read, struct modem_iface *, uint8_t *, size_t, size_t *); +FAKE_VALUE_FUNC(int, mock_write, struct modem_iface *, const uint8_t *, size_t); +FAKE_VALUE_FUNC(int, mock_on_response, struct modem_cmd_handler_data *, uint16_t, + uint8_t **, uint16_t); + +static void mock_modem_iface_init(struct modem_iface *iface) +{ + iface->read = mock_read; + iface->write = mock_write; +} + +static int mock_modem_iface_receive_data(struct modem_iface *iface, + uint8_t *data, + size_t len, size_t *bytes_read) +{ + if (!response_delayed) { + *bytes_read = 0; + return mock_read_fake.return_val; + } + + size_t response_delayed_len = strlen(response_delayed); + + zassert_true(len > response_delayed_len, "Insufficient data length for response"); + memcpy(data, response_delayed, response_delayed_len); + *bytes_read = response_delayed_len; + response_delayed = NULL; + + return mock_read_fake.return_val; +} + +static void _send_response_delayed_work(struct k_work *work) +{ + mock_read_fake.custom_fake = mock_modem_iface_receive_data; + modem_cmd_handler_process(&cmd_handler, &mock_modem_iface); +} + +K_WORK_DELAYABLE_DEFINE(response_delayable, _send_response_delayed_work); + +void recv_data_delayed(const char *str, k_timeout_t delay) +{ + response_delayed = str; + k_work_schedule(&response_delayable, delay); +} + +static int modem_modem_iface_send_data(struct modem_iface *iface, + const uint8_t *data, + size_t len) +{ + zassert_true(strncmp((const char *)data, + mock_write_expected_data[mock_write_fake.call_count - 1], len) == 0, + "Sent command does not match expected"); + return mock_write_fake.return_val; +} + +void send_data_verify(const char *expected_cmd) +{ + mock_write_expected_data[mock_write_expected_data_count++] = expected_cmd; + mock_write_fake.custom_fake = modem_modem_iface_send_data; +} + +ZTEST(suite_modem_cmd_send, test_recv_ok) +{ + int ret = modem_cmd_handler_init(&cmd_handler, + &cmd_handler_data, + &cmd_handler_config); + zassert_equal(ret, 0, "modem_cmd_handler_init should return 0 on success"); + + send_data_verify("AT+INIT"); + send_data_verify("\r"); + + recv_data_delayed("OK\r", K_MSEC(100)); + + ret = modem_cmd_send(&mock_modem_iface, &cmd_handler, + NULL, 0U, "AT+INIT", &sem_response, + K_SECONDS(1)); + zassert_equal(ret, 0, "modem_cmd_send should return 0 on success"); +} + +ZTEST(suite_modem_cmd_send, test_recv_error) +{ + int ret = modem_cmd_handler_init(&cmd_handler, + &cmd_handler_data, + &cmd_handler_config); + zassert_equal(ret, 0, "modem_cmd_handler_init should return 0 on success"); + + send_data_verify("AT+INIT"); + send_data_verify("\r"); + + recv_data_delayed("ERROR\r", K_MSEC(100)); + + ret = modem_cmd_send(&mock_modem_iface, &cmd_handler, + NULL, 0U, "AT+INIT", &sem_response, + K_SECONDS(1)); + zassert_equal(ret, -EIO, "modem_cmd_send should return -EIO on error"); +} + +ZTEST(suite_modem_cmd_send, test_recv_timeout) +{ + int ret = modem_cmd_handler_init(&cmd_handler, + &cmd_handler_data, + &cmd_handler_config); + zassert_equal(ret, 0, "modem_cmd_handler_init should return 0 on success"); + + send_data_verify("AT+INIT"); + send_data_verify("\r"); + + /* No response is sent to trigger timeout */ + + ret = modem_cmd_send(&mock_modem_iface, &cmd_handler, + NULL, 0U, "AT+INIT", &sem_response, + K_SECONDS(1)); + zassert_equal(ret, -ETIMEDOUT, "modem_cmd_send should return -ETIMEDOUT on timeout"); +} + +MODEM_CMD_DEFINE(on_cmd_response) +{ + zassert_equal(argc, 1); + zassert_equal(strcmp(argv[0], "123"), 0); + return 0; +} + +ZTEST(suite_modem_cmd_send, test_recv_response) +{ + int ret = modem_cmd_handler_init(&cmd_handler, + &cmd_handler_data, + &cmd_handler_config); + zassert_equal(ret, 0, "modem_cmd_handler_init should return 0 on success"); + + send_data_verify("AT+CMD"); + send_data_verify("\r"); + + recv_data_delayed("+CMD: 123\r" + "OK\r", + K_MSEC(100)); + + mock_on_response_fake.custom_fake = on_cmd_response; + struct modem_cmd cmd[] = { + MODEM_CMD("+CMD: ", mock_on_response, 1, ""), + }; + + ret = modem_cmd_send(&mock_modem_iface, &cmd_handler, + cmd, ARRAY_SIZE(cmd), "AT+CMD", &sem_response, + K_SECONDS(1)); + zassert_equal(ret, 0, "modem_cmd_send should return 0 on success"); + zassert_equal(mock_on_response_fake.call_count, 1); +} + +MODEM_CMD_DEFINE(on_cmd_response_parse_args) +{ + zassert_equal(argc, 4); + zassert_equal(strcmp(argv[0], "1"), 0); + zassert_equal(strcmp(argv[1], "\"two\""), 0); + zassert_equal(strcmp(argv[2], "\"three\""), 0); + zassert_equal(strcmp(argv[3], "4"), 0); + return 0; +} + +ZTEST(suite_modem_cmd_send, test_recv_response_parse_args) +{ + int ret = modem_cmd_handler_init(&cmd_handler, + &cmd_handler_data, + &cmd_handler_config); + zassert_equal(ret, 0, "modem_cmd_handler_init should return 0 on success"); + + send_data_verify("AT+CMD"); + send_data_verify("\r"); + + recv_data_delayed("+CMD: 1,\"two\",\"three\",4\r" + "OK\r", + K_MSEC(100)); + + mock_on_response_fake.custom_fake = on_cmd_response_parse_args; + struct modem_cmd cmd[] = { + MODEM_CMD("+CMD: ", mock_on_response, 4, ","), + }; + + ret = modem_cmd_send(&mock_modem_iface, &cmd_handler, + cmd, ARRAY_SIZE(cmd), "AT+CMD", &sem_response, + K_SECONDS(1)); + zassert_equal(ret, 0, "modem_cmd_send should return 0 on success"); + zassert_equal(mock_on_response_fake.call_count, 1); +} + +MODEM_CMD_DEFINE(on_cmd_response_parse_args_quoted_delim) +{ + zassert_equal(argc, 4); + zassert_equal(strcmp(argv[0], "1"), 0); + zassert_equal(strcmp(argv[1], "\"two\""), 0); + zassert_equal(strcmp(argv[2], "\"thr,ee\""), 0); + zassert_equal(strcmp(argv[3], "4"), 0); + return 0; +} + +ZTEST(suite_modem_cmd_send, test_recv_response_parse_args_quoted_delim) +{ + int ret = modem_cmd_handler_init(&cmd_handler, + &cmd_handler_data, + &cmd_handler_config); + zassert_equal(ret, 0, "modem_cmd_handler_init should return 0 on success"); + + send_data_verify("AT+CMD"); + send_data_verify("\r"); + + recv_data_delayed("+CMD: 1,\"two\",\"thr,ee\",4\r" + "OK\r", + K_MSEC(100)); + + mock_on_response_fake.custom_fake = on_cmd_response_parse_args_quoted_delim; + struct modem_cmd cmd[] = { + MODEM_CMD("+CMD: ", mock_on_response, 4, ","), + }; + + ret = modem_cmd_send(&mock_modem_iface, &cmd_handler, + cmd, ARRAY_SIZE(cmd), "AT+CMD", &sem_response, + K_SECONDS(1)); + zassert_equal(ret, 0, "modem_cmd_send should return 0 on success"); + zassert_equal(mock_on_response_fake.call_count, 1); +} + +MODEM_CMD_DEFINE(on_cmd_response_parse_args_empty_arg) +{ + zassert_equal(argc, 4); + zassert_equal(strcmp(argv[0], "1"), 0); + zassert_equal(strcmp(argv[1], "\"two\""), 0); + zassert_equal(strcmp(argv[2], ""), 0); + zassert_equal(strcmp(argv[3], "4"), 0); + return 0; +} + +ZTEST(suite_modem_cmd_send, test_recv_response_parse_args_empty_arg) +{ + int ret = modem_cmd_handler_init(&cmd_handler, + &cmd_handler_data, + &cmd_handler_config); + zassert_equal(ret, 0, "modem_cmd_handler_init should return 0 on success"); + + send_data_verify("AT+CMD"); + send_data_verify("\r"); + + recv_data_delayed("+CMD: 1,\"two\",,4\r" + "OK\r", + K_MSEC(100)); + + mock_on_response_fake.custom_fake = on_cmd_response_parse_args_empty_arg; + struct modem_cmd cmd[] = { + MODEM_CMD("+CMD: ", mock_on_response, 4, ","), + }; + + ret = modem_cmd_send(&mock_modem_iface, &cmd_handler, + cmd, ARRAY_SIZE(cmd), "AT+CMD", &sem_response, + K_SECONDS(1)); + zassert_equal(ret, 0, "modem_cmd_send should return 0 on success"); + zassert_equal(mock_on_response_fake.call_count, 1); +} + +MODEM_CMD_DEFINE(on_cmd_response_parse_args_empty_arg_end) +{ + zassert_equal(argc, 4); + zassert_equal(strcmp(argv[0], "1"), 0); + zassert_equal(strcmp(argv[1], "\"two\""), 0); + zassert_equal(strcmp(argv[2], "\"three\""), 0); + zassert_equal(strcmp(argv[3], ""), 0); + return 0; +} + +ZTEST(suite_modem_cmd_send, test_recv_response_parse_args_empty_arg_end) +{ + int ret = modem_cmd_handler_init(&cmd_handler, + &cmd_handler_data, + &cmd_handler_config); + zassert_equal(ret, 0, "modem_cmd_handler_init should return 0 on success"); + + send_data_verify("AT+CMD"); + send_data_verify("\r"); + + recv_data_delayed("+CMD: 1,\"two\",\"three\",\r" + "OK\r", + K_MSEC(100)); + + mock_on_response_fake.custom_fake = on_cmd_response_parse_args_empty_arg_end; + struct modem_cmd cmd[] = { + MODEM_CMD("+CMD: ", mock_on_response, 4, ","), + }; + + ret = modem_cmd_send(&mock_modem_iface, &cmd_handler, + cmd, ARRAY_SIZE(cmd), "AT+CMD", &sem_response, + K_SECONDS(1)); + zassert_equal(ret, 0, "modem_cmd_send should return 0 on success"); + zassert_equal(mock_on_response_fake.call_count, 1); +} + +MODEM_CMD_DEFINE(on_cmd_response_parse_args_empty_arg_begin) +{ + zassert_equal(argc, 4); + zassert_equal(strcmp(argv[0], ""), 0); + zassert_equal(strcmp(argv[1], "\"two\""), 0); + zassert_equal(strcmp(argv[2], "\"three\""), 0); + zassert_equal(strcmp(argv[3], "4"), 0); + return 0; +} + +ZTEST(suite_modem_cmd_send, test_recv_response_parse_args_empty_arg_begin) +{ + int ret = modem_cmd_handler_init(&cmd_handler, + &cmd_handler_data, + &cmd_handler_config); + zassert_equal(ret, 0, "modem_cmd_handler_init should return 0 on success"); + + send_data_verify("AT+CMD"); + send_data_verify("\r"); + + recv_data_delayed("+CMD: ,\"two\",\"three\",4\r" + "OK\r", + K_MSEC(100)); + + mock_on_response_fake.custom_fake = on_cmd_response_parse_args_empty_arg_begin; + struct modem_cmd cmd[] = { + MODEM_CMD("+CMD: ", mock_on_response, 4, ","), + }; + + ret = modem_cmd_send(&mock_modem_iface, &cmd_handler, + cmd, ARRAY_SIZE(cmd), "AT+CMD", &sem_response, + K_SECONDS(1)); + zassert_equal(ret, 0, "modem_cmd_send should return 0 on success"); + zassert_equal(mock_on_response_fake.call_count, 1); +} + +MODEM_CMD_DEFINE(on_cmd_response_parse_args_multi_delim) +{ + zassert_equal(argc, 4); + zassert_equal(strcmp(argv[0], "1"), 0); + zassert_equal(strcmp(argv[1], "\"two\""), 0); + zassert_equal(strcmp(argv[2], "\"three\""), 0); + zassert_equal(strcmp(argv[3], "4"), 0); + return 0; +} + +ZTEST(suite_modem_cmd_send, test_recv_response_parse_args_multi_delim) +{ + int ret = modem_cmd_handler_init(&cmd_handler, + &cmd_handler_data, + &cmd_handler_config); + zassert_equal(ret, 0, "modem_cmd_handler_init should return 0 on success"); + + send_data_verify("AT+CMD"); + send_data_verify("\r"); + + recv_data_delayed("+CMD: 1:\"two\";\"three\",4\r" + "OK\r", + K_MSEC(100)); + + mock_on_response_fake.custom_fake = on_cmd_response_parse_args_multi_delim; + struct modem_cmd cmd[] = { + MODEM_CMD("+CMD: ", mock_on_response, 4, ",;:"), + }; + + ret = modem_cmd_send(&mock_modem_iface, &cmd_handler, + cmd, ARRAY_SIZE(cmd), "AT+CMD", &sem_response, + K_SECONDS(1)); + zassert_equal(ret, 0, "modem_cmd_send should return 0 on success"); + zassert_equal(mock_on_response_fake.call_count, 1); +} + +static void test_setup(void *fixture) +{ + mock_write_expected_data_count = 0; + + RESET_FAKE(mock_read); + RESET_FAKE(mock_write); + RESET_FAKE(mock_on_response); + + k_sem_init(&sem_response, 0, 1); + + mock_modem_iface_init(&mock_modem_iface); +} + +static void test_teardown(void *fixture) +{ + zassert_equal(mock_write_fake.call_count, mock_write_expected_data_count, + "Not all expected commands were sent"); +} + +ZTEST_SUITE(suite_modem_cmd_send, NULL, NULL, test_setup, test_teardown, NULL); diff --git a/tests/drivers/modem/modem_cmd_handler/testcase.yaml b/tests/drivers/modem/modem_cmd_handler/testcase.yaml new file mode 100644 index 000000000000..9cd030f40140 --- /dev/null +++ b/tests/drivers/modem/modem_cmd_handler/testcase.yaml @@ -0,0 +1,9 @@ +tests: + drivers.modem.modem_cmd_handler: + tags: + - drivers + - modem + platform_allow: + - native_sim + integration_platforms: + - native_sim From 4e98b057557e5ebb6b2cfc8ff9302cd2923e2165 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Thu, 4 Dec 2025 15:37:58 +0100 Subject: [PATCH 0035/3659] tests: Bluetooth: Tester: Fix bad BIS sync shift The shift is an old leftover from when the BAP API was different and BIT(1) means BIS Index 1, but now BIT(0) means BIT Index 1. Signed-off-by: Emil Gydesen --- tests/bluetooth/tester/src/audio/btp_bap_broadcast.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/tests/bluetooth/tester/src/audio/btp_bap_broadcast.c b/tests/bluetooth/tester/src/audio/btp_bap_broadcast.c index d301fac6c31f..ec5125522bd0 100644 --- a/tests/bluetooth/tester/src/audio/btp_bap_broadcast.c +++ b/tests/bluetooth/tester/src/audio/btp_bap_broadcast.c @@ -1680,12 +1680,6 @@ uint8_t btp_bap_broadcast_assistant_add_src(const void *cmd, uint16_t cmd_len, v struct bt_bap_bass_subgroup *subgroup = &delegator_subgroups[i]; subgroup->bis_sync = sys_get_le32(ptr); - if (subgroup->bis_sync != BT_BAP_BIS_SYNC_NO_PREF) { - /* For semantic purposes Zephyr API uses BIS Index bitfield - * where BIT(1) means BIS Index 1 - */ - subgroup->bis_sync <<= 1; - } ptr += sizeof(subgroup->bis_sync); subgroup->metadata_len = *ptr; @@ -1751,12 +1745,6 @@ uint8_t btp_bap_broadcast_assistant_modify_src(const void *cmd, uint16_t cmd_len struct bt_bap_bass_subgroup *subgroup = &delegator_subgroups[i]; subgroup->bis_sync = sys_get_le32(ptr); - if (subgroup->bis_sync != BT_BAP_BIS_SYNC_NO_PREF) { - /* For semantic purposes Zephyr API uses BIS Index bitfield - * where BIT(1) means BIS Index 1 - */ - subgroup->bis_sync <<= 1; - } ptr += sizeof(subgroup->bis_sync); subgroup->metadata_len = *ptr; From ae25d71a63e29c9327144055a30009b64e2ac2c3 Mon Sep 17 00:00:00 2001 From: Qingsong Gou Date: Thu, 27 Nov 2025 12:12:42 +0800 Subject: [PATCH 0036/3659] dts: bingdings: timer: add sifli,sf32lb-atim add sifli,sf32lb-atim bingdings Signed-off-by: Qingsong Gou --- dts/bindings/timer/sifli,sf32lb-atim.yaml | 28 +++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 dts/bindings/timer/sifli,sf32lb-atim.yaml diff --git a/dts/bindings/timer/sifli,sf32lb-atim.yaml b/dts/bindings/timer/sifli,sf32lb-atim.yaml new file mode 100644 index 000000000000..34c8049f5139 --- /dev/null +++ b/dts/bindings/timer/sifli,sf32lb-atim.yaml @@ -0,0 +1,28 @@ +# Copyright (c) 2025, Qingsong Gou +# SPDX-License-Identifier: Apache-2.0 + +description: Sifli SF32LB ATIM + +compatible: "sifli,sf32lb-atim" + +include: base.yaml + +properties: + reg: + required: true + + interrupts: + required: true + + clocks: + required: true + + sifli,prescaler: + type: int + default: 0 + required: true + description: | + Counter prescaler from 0 to 65535. default reset value is 'not divided' + The clock frequency to the counter is the input frequency divided by (prescaler + 1). + For example, if the input clock is 48 MHz and the desired counter clock is 1 MHz, + set this property to 47. From 8d331b7b0841e070789dc4fee303b71a38a4dd04 Mon Sep 17 00:00:00 2001 From: Qingsong Gou Date: Thu, 27 Nov 2025 12:13:25 +0800 Subject: [PATCH 0037/3659] dts: bingdings: pwm: add sifli,sf32lb-atim-pwm add sifli,sf32lb-atim-pwm bingdings Signed-off-by: Qingsong Gou --- dts/bindings/pwm/sifli,sf32lb-atim-pwm.yaml | 23 +++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 dts/bindings/pwm/sifli,sf32lb-atim-pwm.yaml diff --git a/dts/bindings/pwm/sifli,sf32lb-atim-pwm.yaml b/dts/bindings/pwm/sifli,sf32lb-atim-pwm.yaml new file mode 100644 index 000000000000..bbb0610438a8 --- /dev/null +++ b/dts/bindings/pwm/sifli,sf32lb-atim-pwm.yaml @@ -0,0 +1,23 @@ +# Copyright (c) 2025, Qingsong Gou +# SPDX-License-Identifier: Apache-2.0 + +description: SF32LB ATIM PWM controller + +compatible: "sifli,sf32lb-atim-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 From 01a7b9e2d8e646868ae6932ec6f60233f23b710c Mon Sep 17 00:00:00 2001 From: Qingsong Gou Date: Thu, 27 Nov 2025 12:14:28 +0800 Subject: [PATCH 0038/3659] dts: arm: sifli: sf32lb52x: add atim node add atim timer node for sf32lb platform Signed-off-by: Qingsong Gou --- dts/arm/sifli/sf32lb52x.dtsi | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/dts/arm/sifli/sf32lb52x.dtsi b/dts/arm/sifli/sf32lb52x.dtsi index c3d462c7b364..d568962346f1 100644 --- a/dts/arm/sifli/sf32lb52x.dtsi +++ b/dts/arm/sifli/sf32lb52x.dtsi @@ -106,6 +106,20 @@ status = "disabled"; }; + atim: timer@50004000 { + compatible = "sifli,sf32lb-atim"; + reg = <0x50004000 0x1000>; + interrupts = <94 0>; + clocks = <&rcc_clk SF32LB52X_CLOCK_ATIM1>; + status = "disabled"; + + pwm { + compatible = "sifli,sf32lb-atim-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + trng: trng@5000f000 { compatible = "sifli,sf32lb-trng"; reg = <0x5000f000 0x1000>; From 7c39469e1757bde345e20124f33fca6600f49dd5 Mon Sep 17 00:00:00 2001 From: Qingsong Gou Date: Thu, 27 Nov 2025 12:15:32 +0800 Subject: [PATCH 0039/3659] drivers: pwm: sf32lb: add atim based pwm driver add atim based pwm driver for sf32lb platform Signed-off-by: Qingsong Gou --- drivers/pwm/CMakeLists.txt | 1 + drivers/pwm/Kconfig.sf32lb | 8 ++ drivers/pwm/pwm_sf32lb_atim.c | 174 ++++++++++++++++++++++++++++++++++ 3 files changed, 183 insertions(+) create mode 100644 drivers/pwm/pwm_sf32lb_atim.c diff --git a/drivers/pwm/CMakeLists.txt b/drivers/pwm/CMakeLists.txt index 1a547fd597d3..2cd435b65b6f 100644 --- a/drivers/pwm/CMakeLists.txt +++ b/drivers/pwm/CMakeLists.txt @@ -58,6 +58,7 @@ zephyr_library_sources_ifdef(CONFIG_PWM_RV32M1_TPM pwm_rv32m1_tpm.c) zephyr_library_sources_ifdef(CONFIG_PWM_SAM pwm_sam.c) zephyr_library_sources_ifdef(CONFIG_PWM_SAM0_TC pwm_sam0_tc.c) zephyr_library_sources_ifdef(CONFIG_PWM_SAM0_TCC pwm_sam0_tcc.c) +zephyr_library_sources_ifdef(CONFIG_PWM_SF32LB_ATIM pwm_sf32lb_atim.c) zephyr_library_sources_ifdef(CONFIG_PWM_SF32LB_GPT pwm_sf32lb_gpt.c) zephyr_library_sources_ifdef(CONFIG_PWM_SIFIVE pwm_sifive.c) zephyr_library_sources_ifdef(CONFIG_PWM_SILABS_LETIMER pwm_silabs_letimer.c) diff --git a/drivers/pwm/Kconfig.sf32lb b/drivers/pwm/Kconfig.sf32lb index 721284e132f7..0808d00bfc2c 100644 --- a/drivers/pwm/Kconfig.sf32lb +++ b/drivers/pwm/Kconfig.sf32lb @@ -8,3 +8,11 @@ config PWM_SF32LB_GPT help Enable PWM driver for SF32LB series of MCUs. This driver uses the timer peripheral to implement PWM functionality. + +config PWM_SF32LB_ATIM + bool "ATIM based PWM driver for SF32LB family of MCUs" + default y + depends on DT_HAS_SIFLI_SF32LB_ATIM_PWM_ENABLED + help + Enable PWM driver for SF32LB series of MCUs. This driver uses + the advanced timer peripheral to implement PWM functionality. diff --git a/drivers/pwm/pwm_sf32lb_atim.c b/drivers/pwm/pwm_sf32lb_atim.c new file mode 100644 index 000000000000..6126c647fe8a --- /dev/null +++ b/drivers/pwm/pwm_sf32lb_atim.c @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2025, Qingsong Gou + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT sifli_sf32lb_atim_pwm + +#include +#include +#include +#include +#include + +#include + +LOG_MODULE_REGISTER(pwm_sf32lb_atim, CONFIG_PWM_LOG_LEVEL); + +#define CR1 offsetof(ATIM_TypeDef, CR1) +#define CR2 offsetof(ATIM_TypeDef, CR2) +#define DIER offsetof(ATIM_TypeDef, DIER) +#define SR offsetof(ATIM_TypeDef, SR) +#define EGR offsetof(ATIM_TypeDef, EGR) +#define CCMR1 offsetof(ATIM_TypeDef, CCMR1) +#define CCMR2 offsetof(ATIM_TypeDef, CCMR2) +#define CCER offsetof(ATIM_TypeDef, CCER) +#define PSC offsetof(ATIM_TypeDef, PSC) +#define ARR offsetof(ATIM_TypeDef, ARR) +#define CCR1 offsetof(ATIM_TypeDef, CCR1) +#define CCR2 offsetof(ATIM_TypeDef, CCR2) +#define CCR3 offsetof(ATIM_TypeDef, CCR3) +#define CCR4 offsetof(ATIM_TypeDef, CCR4) +#define BDTR offsetof(ATIM_TypeDef, BDTR) + +#define ATIM_PWM_MODE1 (6U) + +#define CCMRX(ch) ((ch) <= 1 ? CCMR1 : CCMR2) + +#define MAX_CH_NUM 4U + +struct pwm_sf32lb_atim_config { + uintptr_t base; + const struct pinctrl_dev_config *pincfg; + struct sf32lb_clock_dt_spec clock; + uint32_t prescaler; +}; + +static int pwm_sf32lb_atim_set_cycles(const struct device *dev, uint32_t channel, + uint32_t period_cycles, uint32_t pulse_cycles, + pwm_flags_t flags) +{ + const struct pwm_sf32lb_atim_config *cfg = dev->config; + uint32_t ccmr; + + if (channel >= MAX_CH_NUM) { + return -EINVAL; + } + + /* disable the channel */ + sys_clear_bit(cfg->base + CCER, channel * 4); + + sys_write32(period_cycles - 1, cfg->base + ARR); + + switch (channel) { + case 0: + sys_write32(pulse_cycles, cfg->base + CCR1); + ccmr = sys_read32(cfg->base + CCMRX(channel)); + ccmr &= ~ATIM_CCMR1_OC1M_Msk; + ccmr |= FIELD_PREP(ATIM_CCMR1_OC1M_Msk, ATIM_PWM_MODE1); + ccmr |= ATIM_CCMR1_OC1PE; + sys_write32(ccmr, cfg->base + CCMRX(channel)); + break; + case 1: + sys_write32(pulse_cycles, cfg->base + CCR2); + ccmr = sys_read32(cfg->base + CCMRX(channel)); + ccmr &= ~ATIM_CCMR1_OC2M_Msk; + ccmr |= FIELD_PREP(ATIM_CCMR1_OC2M_Msk, ATIM_PWM_MODE1); + ccmr |= ATIM_CCMR1_OC2PE; + sys_write32(ccmr, cfg->base + CCMRX(channel)); + break; + case 2: + sys_write32(pulse_cycles, cfg->base + CCR3); + ccmr = sys_read32(cfg->base + CCMRX(channel)); + ccmr &= ~ATIM_CCMR2_OC3M_Msk; + ccmr |= FIELD_PREP(ATIM_CCMR2_OC3M_Msk, ATIM_PWM_MODE1); + ccmr |= ATIM_CCMR2_OC3PE; + sys_write32(ccmr, cfg->base + CCMRX(channel)); + break; + case 3: + sys_write32(pulse_cycles, cfg->base + CCR4); + ccmr = sys_read32(cfg->base + CCMRX(channel)); + ccmr &= ~ATIM_CCMR2_OC4M_Msk; + ccmr |= FIELD_PREP(ATIM_CCMR2_OC4M_Msk, ATIM_PWM_MODE1); + ccmr |= ATIM_CCMR2_OC4PE; + sys_write32(ccmr, cfg->base + CCMRX(channel)); + break; + default: + return -EINVAL; + } + + if (flags & PWM_POLARITY_INVERTED) { + sys_set_bit(cfg->base + CCER, channel * 4 + 1); + } + + /* enable the channel */ + sys_set_bit(cfg->base + CCER, channel * 4); + + return 0; +} + +static int pwm_sf32lb_atim_get_cycles_per_sec(const struct device *dev, uint32_t channel, + uint64_t *cycles) +{ + const struct pwm_sf32lb_atim_config *cfg = dev->config; + uint32_t clk_rate; + + if (sf32lb_clock_control_get_rate_dt(&cfg->clock, &clk_rate)) { + return -EIO; + } + + *cycles = clk_rate / (cfg->prescaler + 1); + + return 0; +} + +static const struct pwm_driver_api pwm_sf32lb_atim_api = { + .set_cycles = pwm_sf32lb_atim_set_cycles, + .get_cycles_per_sec = pwm_sf32lb_atim_get_cycles_per_sec, +}; + +static int pwm_sf32lb_atim_init(const struct device *dev) +{ + const struct pwm_sf32lb_atim_config *cfg = dev->config; + int err; + + err = pinctrl_apply_state(cfg->pincfg, PINCTRL_STATE_DEFAULT); + if (err < 0) { + return err; + } + + if (!sf32lb_clock_is_ready_dt(&cfg->clock)) { + return -ENODEV; + } + + err = sf32lb_clock_control_on_dt(&cfg->clock); + if (err < 0) { + return err; + } + + sys_write32(cfg->prescaler, cfg->base + PSC); + sys_set_bit(cfg->base + EGR, ATIM_EGR_UG_Pos); + + /* enable auto-reload preload */ + sys_set_bit(cfg->base + CR1, ATIM_CR1_ARPE_Pos); + + /* enable timer */ + sys_set_bit(cfg->base + CR1, ATIM_CR1_CEN_Pos); + sys_set_bit(cfg->base + BDTR, ATIM_BDTR_MOE_Pos); + + return err; +} + +#define PWM_SF32LB_ATIM_DEFINE(n) \ + PINCTRL_DT_INST_DEFINE(n); \ + static const struct pwm_sf32lb_atim_config pwm_sf32lb_atim_config_##n = { \ + .base = DT_REG_ADDR(DT_INST_PARENT(n)), \ + .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ + .clock = SF32LB_CLOCK_DT_INST_PARENT_SPEC_GET(n), \ + .prescaler = DT_PROP(DT_INST_PARENT(n), sifli_prescaler), \ + }; \ + DEVICE_DT_INST_DEFINE(n, pwm_sf32lb_atim_init, NULL, NULL, \ + &pwm_sf32lb_atim_config_##n, POST_KERNEL, CONFIG_PWM_INIT_PRIORITY, \ + &pwm_sf32lb_atim_api); + +DT_INST_FOREACH_STATUS_OKAY(PWM_SF32LB_ATIM_DEFINE) From 7c87f23c9b2d700ee4218fb3cd2c7da6569551ea Mon Sep 17 00:00:00 2001 From: Martin Hoff Date: Fri, 5 Dec 2025 18:00:13 +0100 Subject: [PATCH 0040/3659] boards: silabs: add missing clock frequency on spi eusart node This patch add the clock-frequency property for two board. Without this patch, the frequency is silently set to 1 Mhz which can introduce some lack of understanding. Signed-off-by: Martin Hoff --- boards/silabs/radio_boards/xg23_rb4210a/xg23_rb4210a.dts | 1 + boards/silabs/radio_boards/xg28_rb4401c/xg28_rb4401c.dts | 1 + 2 files changed, 2 insertions(+) diff --git a/boards/silabs/radio_boards/xg23_rb4210a/xg23_rb4210a.dts b/boards/silabs/radio_boards/xg23_rb4210a/xg23_rb4210a.dts index eee786a0a5ad..b98eb3d568dd 100644 --- a/boards/silabs/radio_boards/xg23_rb4210a/xg23_rb4210a.dts +++ b/boards/silabs/radio_boards/xg23_rb4210a/xg23_rb4210a.dts @@ -181,6 +181,7 @@ &eusart1 { #address-cells = <1>; #size-cells = <0>; + clock-frequency = ; pinctrl-0 = <&eusart1_default>; pinctrl-names = "default"; status = "okay"; diff --git a/boards/silabs/radio_boards/xg28_rb4401c/xg28_rb4401c.dts b/boards/silabs/radio_boards/xg28_rb4401c/xg28_rb4401c.dts index f39530d3aff4..abbf9dcf8e45 100644 --- a/boards/silabs/radio_boards/xg28_rb4401c/xg28_rb4401c.dts +++ b/boards/silabs/radio_boards/xg28_rb4401c/xg28_rb4401c.dts @@ -134,6 +134,7 @@ &eusart1 { #address-cells = <1>; #size-cells = <0>; + clock-frequency = ; pinctrl-0 = <&eusart1_default>; pinctrl-names = "default"; cs-gpios = <&gpioc 8 GPIO_ACTIVE_HIGH>, <&gpioc 4 GPIO_ACTIVE_LOW>; From 4333f98b2cac24350243370521560511f577d8ed Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Fri, 5 Dec 2025 15:05:25 +0000 Subject: [PATCH 0041/3659] drivers: can: loopback: use proper namespace for Kconfig symbols Use proper namespace for the CAN loopback driver Kconfig symbols, renaming CONFIG_CAN_MAX_FILTER to CONFIG_CAN_LOOPBACK_MAX_FILTERS. This prevents Kconfig symbol clashes between different CAN controller drivers. Signed-off-by: Henrik Brix Andersen --- drivers/can/Kconfig.loopback | 2 +- drivers/can/can_loopback.c | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/can/Kconfig.loopback b/drivers/can/Kconfig.loopback index fd0d7731ef83..8c1d8149c817 100644 --- a/drivers/can/Kconfig.loopback +++ b/drivers/can/Kconfig.loopback @@ -12,7 +12,7 @@ config CAN_LOOPBACK if CAN_LOOPBACK -config CAN_MAX_FILTER +config CAN_LOOPBACK_MAX_FILTERS int "Maximum number of concurrent active filters" default 16 range 1 1024 diff --git a/drivers/can/can_loopback.c b/drivers/can/can_loopback.c index 9d0322abbc08..9744b0456151 100644 --- a/drivers/can/can_loopback.c +++ b/drivers/can/can_loopback.c @@ -35,7 +35,7 @@ struct can_loopback_config { struct can_loopback_data { struct can_driver_data common; - struct can_loopback_filter filters[CONFIG_CAN_MAX_FILTER]; + struct can_loopback_filter filters[CONFIG_CAN_LOOPBACK_MAX_FILTERS]; struct k_mutex mtx; struct k_msgq tx_msgq; char msgq_buffer[CONFIG_CAN_LOOPBACK_TX_MSGQ_SIZE * sizeof(struct can_loopback_frame)]; @@ -90,7 +90,7 @@ static void tx_thread(void *arg1, void *arg2, void *arg3) k_mutex_lock(&data->mtx, K_FOREVER); - for (int i = 0; i < CONFIG_CAN_MAX_FILTER; i++) { + for (int i = 0; i < CONFIG_CAN_LOOPBACK_MAX_FILTERS; i++) { filter = &data->filters[i]; if (filter->rx_cb != NULL && can_frame_matches_filter(&frame.frame, &filter->filter)) { @@ -163,7 +163,7 @@ static int can_loopback_send(const struct device *dev, static inline int get_free_filter(struct can_loopback_filter *filters) { - for (int i = 0; i < CONFIG_CAN_MAX_FILTER; i++) { + for (int i = 0; i < CONFIG_CAN_LOOPBACK_MAX_FILTERS; i++) { if (filters[i].rx_cb == NULL) { return i; } @@ -362,7 +362,7 @@ static int can_loopback_get_max_filters(const struct device *dev, bool ide) { ARG_UNUSED(ide); - return CONFIG_CAN_MAX_FILTER; + return CONFIG_CAN_LOOPBACK_MAX_FILTERS; } static DEVICE_API(can, can_loopback_driver_api) = { @@ -420,7 +420,7 @@ static int can_loopback_init(const struct device *dev) k_mutex_init(&data->mtx); - for (int i = 0; i < CONFIG_CAN_MAX_FILTER; i++) { + for (int i = 0; i < CONFIG_CAN_LOOPBACK_MAX_FILTERS; i++) { data->filters[i].rx_cb = NULL; } From 62f7dfa4be47faa5075a840e6622480ef6086281 Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Fri, 5 Dec 2025 15:12:27 +0000 Subject: [PATCH 0042/3659] drivers: can: native_linux: use proper namespace for Kconfig symbols Use proper namespace for the CAN native_linux driver Kconfig symbols, renaming CONFIG_CAN_MAX_FILTER to CONFIG_CAN_NATIVE_LINUX_MAX_FILTERS. This prevents Kconfig symbol clashes between different CAN controller drivers. Signed-off-by: Henrik Brix Andersen --- drivers/can/Kconfig.native_linux | 2 +- drivers/can/can_native_linux.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/can/Kconfig.native_linux b/drivers/can/Kconfig.native_linux index 54969fd7de11..4d5f5b42ede7 100644 --- a/drivers/can/Kconfig.native_linux +++ b/drivers/can/Kconfig.native_linux @@ -20,7 +20,7 @@ config CAN_NATIVE_LINUX_RX_THREAD_PRIORITY Priority level of the internal thread which is run for handling of incoming packets. -config CAN_MAX_FILTER +config CAN_NATIVE_LINUX_MAX_FILTERS int "Maximum number of concurrent active filters" default 5 range 1 32 diff --git a/drivers/can/can_native_linux.c b/drivers/can/can_native_linux.c index b4f8c8e52537..66d732680d49 100644 --- a/drivers/can/can_native_linux.c +++ b/drivers/can/can_native_linux.c @@ -33,7 +33,7 @@ struct can_filter_context { struct can_native_linux_data { struct can_driver_data common; - struct can_filter_context filters[CONFIG_CAN_MAX_FILTER]; + struct can_filter_context filters[CONFIG_CAN_NATIVE_LINUX_MAX_FILTERS]; struct k_mutex filter_mutex; struct k_sem tx_idle; can_tx_callback_t tx_callback; @@ -399,7 +399,7 @@ static int can_native_linux_get_max_filters(const struct device *dev, bool ide) { ARG_UNUSED(ide); - return CONFIG_CAN_MAX_FILTER; + return CONFIG_CAN_NATIVE_LINUX_MAX_FILTERS; } static DEVICE_API(can, can_native_linux_driver_api) = { From 8b52241c06223880df0d8e430f6896984f02c533 Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Fri, 5 Dec 2025 15:15:19 +0000 Subject: [PATCH 0043/3659] drivers: can: sja1000: use proper namespace for Kconfig symbols Use proper namespace for the CAN sja1000 Kconfig symbols, renaming CONFIG_CAN_MAX_FILTER to CONFIG_CAN_SJA1000_MAX_FILTERS. This prevents Kconfig symbol clashes between different CAN controller drivers. Signed-off-by: Henrik Brix Andersen --- drivers/can/Kconfig.sja1000 | 2 +- drivers/can/can_sja1000.c | 2 +- include/zephyr/drivers/can/can_sja1000.h | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/can/Kconfig.sja1000 b/drivers/can/Kconfig.sja1000 index 97ca0ba20990..8966e6a07c78 100644 --- a/drivers/can/Kconfig.sja1000 +++ b/drivers/can/Kconfig.sja1000 @@ -8,7 +8,7 @@ config CAN_SJA1000 help This enables support for the shared NXP SJA1000 CAN driver. -config CAN_MAX_FILTER +config CAN_SJA1000_MAX_FILTERS int "Maximum number of concurrent active RX filters" depends on CAN_SJA1000 default 5 diff --git a/drivers/can/can_sja1000.c b/drivers/can/can_sja1000.c index 937217b3551f..43f2b6461f1e 100644 --- a/drivers/can/can_sja1000.c +++ b/drivers/can/can_sja1000.c @@ -550,7 +550,7 @@ int can_sja1000_get_max_filters(const struct device *dev, bool ide) ARG_UNUSED(dev); ARG_UNUSED(ide); - return CONFIG_CAN_MAX_FILTER; + return CONFIG_CAN_SJA1000_MAX_FILTERS; } static void can_sja1000_handle_receive_irq(const struct device *dev) diff --git a/include/zephyr/drivers/can/can_sja1000.h b/include/zephyr/drivers/can/can_sja1000.h index fa9647bd9b53..3a3e7c99e4f8 100644 --- a/include/zephyr/drivers/can/can_sja1000.h +++ b/include/zephyr/drivers/can/can_sja1000.h @@ -163,8 +163,8 @@ struct can_sja1000_rx_filter { */ struct can_sja1000_data { struct can_driver_data common; - ATOMIC_DEFINE(rx_allocs, CONFIG_CAN_MAX_FILTER); - struct can_sja1000_rx_filter filters[CONFIG_CAN_MAX_FILTER]; + ATOMIC_DEFINE(rx_allocs, CONFIG_CAN_SJA1000_MAX_FILTERS); + struct can_sja1000_rx_filter filters[CONFIG_CAN_SJA1000_MAX_FILTERS]; struct k_mutex mod_lock; enum can_state state; struct k_sem tx_idle; From 6234480a5739f831db94d9ff5e8954bf5f62c17a Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Fri, 5 Dec 2025 15:19:48 +0000 Subject: [PATCH 0044/3659] drivers: can: mcp2515: use proper namespace for Kconfig symbols Use proper namespace for the CAN mcp2515 Kconfig symbols, renaming CONFIG_CAN_MAX_FILTER to CONFIG_CAN_MCP2515_MAX_FILTERS. This prevents Kconfig symbol clashes between different CAN controller drivers. Signed-off-by: Henrik Brix Andersen --- drivers/can/Kconfig.mcp2515 | 2 +- drivers/can/can_mcp2515.c | 11 ++++++----- drivers/can/can_mcp2515.h | 6 +++--- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/drivers/can/Kconfig.mcp2515 b/drivers/can/Kconfig.mcp2515 index 56eb9506d7a8..732e322de254 100644 --- a/drivers/can/Kconfig.mcp2515 +++ b/drivers/can/Kconfig.mcp2515 @@ -27,7 +27,7 @@ config CAN_MCP2515_INT_THREAD_PRIO Priority level of the internal thread which is ran for interrupt handling and incoming packets. -config CAN_MAX_FILTER +config CAN_MCP2515_MAX_FILTERS int "Maximum number of concurrent active filters" default 5 range 1 32 diff --git a/drivers/can/can_mcp2515.c b/drivers/can/can_mcp2515.c index 697940188427..273609abe65c 100644 --- a/drivers/can/can_mcp2515.c +++ b/drivers/can/can_mcp2515.c @@ -338,7 +338,7 @@ static int mcp2515_get_max_filters(const struct device *dev, bool ide) { ARG_UNUSED(ide); - return CONFIG_CAN_MAX_FILTER; + return CONFIG_CAN_MCP2515_MAX_FILTERS; } static int mcp2515_set_timing(const struct device *dev, const struct can_timing *timing) @@ -622,12 +622,13 @@ static int mcp2515_add_rx_filter(const struct device *dev, can_rx_callback_t rx_ k_mutex_lock(&dev_data->mutex, K_FOREVER); /* find free filter */ - while ((BIT(filter_id) & dev_data->filter_usage) && (filter_id < CONFIG_CAN_MAX_FILTER)) { + while ((BIT(filter_id) & dev_data->filter_usage) && + (filter_id < CONFIG_CAN_MCP2515_MAX_FILTERS)) { filter_id++; } /* setup filter */ - if (filter_id < CONFIG_CAN_MAX_FILTER) { + if (filter_id < CONFIG_CAN_MCP2515_MAX_FILTERS) { dev_data->filter_usage |= BIT(filter_id); dev_data->filter[filter_id] = *filter; @@ -647,7 +648,7 @@ static void mcp2515_remove_rx_filter(const struct device *dev, int filter_id) { struct mcp2515_data *dev_data = dev->data; - if (filter_id < 0 || filter_id >= CONFIG_CAN_MAX_FILTER) { + if (filter_id < 0 || filter_id >= CONFIG_CAN_MCP2515_MAX_FILTERS) { LOG_ERR("filter ID %d out of bounds", filter_id); return; } @@ -681,7 +682,7 @@ static void mcp2515_rx_filter(const struct device *dev, struct can_frame *frame) k_mutex_lock(&dev_data->mutex, K_FOREVER); - for (; filter_id < CONFIG_CAN_MAX_FILTER; filter_id++) { + for (; filter_id < CONFIG_CAN_MCP2515_MAX_FILTERS; filter_id++) { if (!(BIT(filter_id) & dev_data->filter_usage)) { continue; /* filter slot empty */ } diff --git a/drivers/can/can_mcp2515.h b/drivers/can/can_mcp2515.h index c71a8f0f76d6..84c561148772 100644 --- a/drivers/can/can_mcp2515.h +++ b/drivers/can/can_mcp2515.h @@ -37,9 +37,9 @@ struct mcp2515_data { /* filter data */ uint32_t filter_usage; - can_rx_callback_t rx_cb[CONFIG_CAN_MAX_FILTER]; - void *cb_arg[CONFIG_CAN_MAX_FILTER]; - struct can_filter filter[CONFIG_CAN_MAX_FILTER]; + can_rx_callback_t rx_cb[CONFIG_CAN_MCP2515_MAX_FILTERS]; + void *cb_arg[CONFIG_CAN_MCP2515_MAX_FILTERS]; + struct can_filter filter[CONFIG_CAN_MCP2515_MAX_FILTERS]; /* general data */ struct k_mutex mutex; From 4ec070570bd3e0d41b73430c4a8999ffb9ed9290 Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Fri, 5 Dec 2025 15:23:40 +0000 Subject: [PATCH 0045/3659] drivers: can: max32: use proper namespace for Kconfig symbols Use proper namespace for the CAN max32 Kconfig symbols, renaming CONFIG_CAN_MAX_FILTER to CONFIG_CAN_MAX32_MAX_FILTERS. This prevents Kconfig symbol clashes between different CAN controller drivers. Signed-off-by: Henrik Brix Andersen --- drivers/can/Kconfig.max32 | 2 +- drivers/can/can_max32.c | 16 +++++++++------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/drivers/can/Kconfig.max32 b/drivers/can/Kconfig.max32 index e3be7c17b1d5..165437ef3c38 100644 --- a/drivers/can/Kconfig.max32 +++ b/drivers/can/Kconfig.max32 @@ -11,7 +11,7 @@ config CAN_MAX32 if CAN_MAX32 -config CAN_MAX_FILTER +config CAN_MAX32_MAX_FILTERS int "Maximum number of concurrent active filters" default 5 range 1 32 diff --git a/drivers/can/can_max32.c b/drivers/can/can_max32.c index f7b621778947..04d13caece0b 100644 --- a/drivers/can/can_max32.c +++ b/drivers/can/can_max32.c @@ -54,7 +54,7 @@ struct max32_can_data { struct max32_req_data tx_data; uint32_t filter_usage; - struct max32_can_rx_callback rx_callbacks[CONFIG_CAN_MAX_FILTER]; + struct max32_can_rx_callback rx_callbacks[CONFIG_CAN_MAX32_MAX_FILTERS]; struct max32_req_data rx_data; }; @@ -352,12 +352,13 @@ static int can_max32_add_rx_filter(const struct device *dev, can_rx_callback_t c k_mutex_lock(&dev_data->inst_mutex, K_FOREVER); /* find free filter */ - while ((BIT(filter_idx) & dev_data->filter_usage) && (filter_idx < CONFIG_CAN_MAX_FILTER)) { + while ((BIT(filter_idx) & dev_data->filter_usage) && + (filter_idx < CONFIG_CAN_MAX32_MAX_FILTERS)) { filter_idx++; } /* setup filter */ - if (filter_idx < CONFIG_CAN_MAX_FILTER) { + if (filter_idx < CONFIG_CAN_MAX32_MAX_FILTERS) { unsigned int key = irq_lock(); dev_data->filter_usage |= BIT(filter_idx); @@ -371,7 +372,8 @@ static int can_max32_add_rx_filter(const struct device *dev, can_rx_callback_t c LOG_DBG("Set filter id:%08X mask:%08X", filter->id, filter->mask); } else { filter_idx = -ENOSPC; - LOG_WRN("All filters are used CONFIG_CAN_MAX_FILTER=%d", CONFIG_CAN_MAX_FILTER); + LOG_WRN("All filters are used CONFIG_CAN_MAX32_MAX_FILTERS=%d", + CONFIG_CAN_MAX32_MAX_FILTERS); } k_mutex_unlock(&dev_data->inst_mutex); @@ -384,7 +386,7 @@ static void can_max32_remove_rx_filter(const struct device *dev, int filter_idx) struct max32_can_data *dev_data = dev->data; unsigned int key; - if ((filter_idx < 0) || (filter_idx >= CONFIG_CAN_MAX_FILTER)) { + if ((filter_idx < 0) || (filter_idx >= CONFIG_CAN_MAX32_MAX_FILTERS)) { LOG_ERR("Filter ID %d out of bounds", filter_idx); return; } @@ -465,7 +467,7 @@ static int can_max32_get_max_filters(const struct device *dev, bool ide) ARG_UNUSED(dev); ARG_UNUSED(ide); - return CONFIG_CAN_MAX_FILTER; + return CONFIG_CAN_MAX32_MAX_FILTERS; } #ifdef CONFIG_CAN_MANUAL_RECOVERY_MODE @@ -510,7 +512,7 @@ static void can_max32_rx_soft_filter(const struct device *dev, struct can_frame } #endif /* !CONFIG_CAN_ACCEPT_RTR */ - for (; filter_id < CONFIG_CAN_MAX_FILTER; filter_id++) { + for (; filter_id < CONFIG_CAN_MAX32_MAX_FILTERS; filter_id++) { if (!(BIT(filter_id) & dev_data->filter_usage)) { continue; /* filter slot empty */ } From f2e49c8d55661b4d5e994ab238a4f90be0f883d6 Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Fri, 5 Dec 2025 15:27:59 +0000 Subject: [PATCH 0046/3659] drivers: can: mcp251xfd: use proper namespace for Kconfig symbols Use proper namespace for the CAN mcp251xfd Kconfig symbols, renaming CONFIG_CAN_MAX_FILTER to CONFIG_CAN_MCP251XFD_MAX_FILTERS. This prevents Kconfig symbol clashes between different CAN controller drivers. Signed-off-by: Henrik Brix Andersen --- drivers/can/Kconfig.mcp251xfd | 2 +- drivers/can/can_mcp251xfd.c | 8 ++++---- drivers/can/can_mcp251xfd.h | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/can/Kconfig.mcp251xfd b/drivers/can/Kconfig.mcp251xfd index 128becf8e95b..c6762c345807 100644 --- a/drivers/can/Kconfig.mcp251xfd +++ b/drivers/can/Kconfig.mcp251xfd @@ -51,7 +51,7 @@ config CAN_MCP251XFD_READ_CRC_RETRIES help Number of retries during SFR register read if CRC fails. -config CAN_MAX_FILTER +config CAN_MCP251XFD_MAX_FILTERS int "Maximum number of concurrent active filters" default 5 range 1 32 diff --git a/drivers/can/can_mcp251xfd.c b/drivers/can/can_mcp251xfd.c index 893ff63e980e..a6bc2c926777 100644 --- a/drivers/can/can_mcp251xfd.c +++ b/drivers/can/can_mcp251xfd.c @@ -556,13 +556,13 @@ static int mcp251xfd_add_rx_filter(const struct device *dev, can_rx_callback_t r k_mutex_lock(&dev_data->mutex, K_FOREVER); - for (filter_idx = 0; filter_idx < CONFIG_CAN_MAX_FILTER ; filter_idx++) { + for (filter_idx = 0; filter_idx < CONFIG_CAN_MCP251XFD_MAX_FILTERS ; filter_idx++) { if ((BIT(filter_idx) & dev_data->filter_usage) == 0) { break; } } - if (filter_idx >= CONFIG_CAN_MAX_FILTER) { + if (filter_idx >= CONFIG_CAN_MCP251XFD_MAX_FILTERS) { filter_idx = -ENOSPC; goto done; } @@ -629,7 +629,7 @@ static void mcp251xfd_remove_rx_filter(const struct device *dev, int filter_idx) uint32_t *reg; int ret; - if (filter_idx < 0 || filter_idx >= CONFIG_CAN_MAX_FILTER) { + if (filter_idx < 0 || filter_idx >= CONFIG_CAN_MCP251XFD_MAX_FILTERS) { LOG_ERR("Filter ID %d out of bounds", filter_idx); return; } @@ -731,7 +731,7 @@ static int mcp251xfd_get_max_filters(const struct device *dev, bool ide) { ARG_UNUSED(ide); - return CONFIG_CAN_MAX_FILTER; + return CONFIG_CAN_MCP251XFD_MAX_FILTERS; } static int mcp251xfd_handle_fifo_read(const struct device *dev, const struct mcp251xfd_fifo *fifo, diff --git a/drivers/can/can_mcp251xfd.h b/drivers/can/can_mcp251xfd.h index 439207968564..353902032fba 100644 --- a/drivers/can/can_mcp251xfd.h +++ b/drivers/can/can_mcp251xfd.h @@ -499,9 +499,9 @@ struct mcp251xfd_data { /* Filter Data */ uint32_t filter_usage; - struct can_filter filter[CONFIG_CAN_MAX_FILTER]; - can_rx_callback_t rx_cb[CONFIG_CAN_MAX_FILTER]; - void *cb_arg[CONFIG_CAN_MAX_FILTER]; + struct can_filter filter[CONFIG_CAN_MCP251XFD_MAX_FILTERS]; + can_rx_callback_t rx_cb[CONFIG_CAN_MCP251XFD_MAX_FILTERS]; + void *cb_arg[CONFIG_CAN_MCP251XFD_MAX_FILTERS]; const struct device *dev; From 89a238d74cc866c731a805d0d4d8e40658a92434 Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Fri, 5 Dec 2025 15:36:24 +0000 Subject: [PATCH 0047/3659] drivers: can: mcux: flexcan: use proper namespace for Kconfig symbols Use proper namespace for the MCUX FlexCAN Kconfig symbols, renaming CONFIG_CAN_MAX_FILTER to CONFIG_CAN_MCUX_FLEXCAN_MAX_FILTERS and CONFIG_CAN_MAX_MB to CONFIG_CAN_MCUX_FLEXCAN_MAX_MB. This prevents Kconfig symbol clashes between different CAN controller drivers. Signed-off-by: Henrik Brix Andersen --- boards/nxp/mr_canhubk3/doc/index.rst | 6 +++--- drivers/can/Kconfig.mcux | 4 ++-- drivers/can/can_mcux_flexcan.c | 8 ++++---- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/boards/nxp/mr_canhubk3/doc/index.rst b/boards/nxp/mr_canhubk3/doc/index.rst index 570a2157c630..1c5a5e6a06de 100644 --- a/boards/nxp/mr_canhubk3/doc/index.rst +++ b/boards/nxp/mr_canhubk3/doc/index.rst @@ -143,11 +143,11 @@ flexcan5 | PTC11 | PTC11_CAN0_RX P22/P23 and support maximum 32 message buffers for concurrent active instances with 8 bytes payload. We need to pay attention to configuration options: - 1. :kconfig:option:`CONFIG_CAN_MAX_MB` must be less or equal than the + 1. :kconfig:option:`CONFIG_CAN_MCUX_FLEXCAN_MAX_MB` must be less or equal than the maximum number of message buffers that is according to the table below. - 2. :kconfig:option:`CONFIG_CAN_MAX_FILTER` must be less or equal than - :kconfig:option:`CONFIG_CAN_MAX_MB`. + 2. :kconfig:option:`CONFIG_CAN_MCUX_FLEXCAN_MAX_FILTERS` must be less or equal than + :kconfig:option:`CONFIG_CAN_MCUX_FLEXCAN_MAX_MB`. =============== ========== ================ ================ Devicetree node Payload Hardware support Software support diff --git a/drivers/can/Kconfig.mcux b/drivers/can/Kconfig.mcux index e2ee5a8d27d8..aeb98b447845 100644 --- a/drivers/can/Kconfig.mcux +++ b/drivers/can/Kconfig.mcux @@ -28,7 +28,7 @@ config CAN_MCUX_FLEXCAN_WAIT_TIMEOUT Maximum number of wait loop iterations for the MCUX FlexCAN HAL when entering/leaving freeze mode. -config CAN_MAX_MB +config CAN_MCUX_FLEXCAN_MAX_MB int "Maximum number of message buffers for concurrent active instances" default 16 depends on SOC_SERIES_S32K3 || SOC_SERIES_S32K1 || SOC_SERIES_S32ZE @@ -39,7 +39,7 @@ config CAN_MAX_MB help Defines maximum number of message buffers for concurrent active instances. -config CAN_MAX_FILTER +config CAN_MCUX_FLEXCAN_MAX_FILTERS int "Maximum number of concurrent active RX filters" default 5 range 1 15 if SOC_SERIES_KINETIS_KE1XF || SOC_SERIES_KINETIS_K6X diff --git a/drivers/can/can_mcux_flexcan.c b/drivers/can/can_mcux_flexcan.c index 7a6c72e3eb3d..57ab127bbd9c 100644 --- a/drivers/can/can_mcux_flexcan.c +++ b/drivers/can/can_mcux_flexcan.c @@ -34,8 +34,8 @@ LOG_MODULE_REGISTER(can_mcux_flexcan, CONFIG_CAN_LOG_LEVEL); #endif /* The maximum number of message buffers for concurrent active instances */ -#ifdef CONFIG_CAN_MAX_MB -#define MCUX_FLEXCAN_MAX_MB CONFIG_CAN_MAX_MB +#ifdef CONFIG_CAN_MCUX_FLEXCAN_MAX_MB +#define MCUX_FLEXCAN_MAX_MB CONFIG_CAN_MCUX_FLEXCAN_MAX_MB #else #define MCUX_FLEXCAN_MAX_MB FSL_FEATURE_FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBERn(0) #endif @@ -44,7 +44,7 @@ LOG_MODULE_REGISTER(can_mcux_flexcan, CONFIG_CAN_LOG_LEVEL); * RX message buffers (filters) will take up the first N message * buffers. The rest are available for TX use. */ -#define MCUX_FLEXCAN_MAX_RX (CONFIG_CAN_MAX_FILTER + RX_START_IDX) +#define MCUX_FLEXCAN_MAX_RX (CONFIG_CAN_MCUX_FLEXCAN_MAX_FILTERS + RX_START_IDX) #define MCUX_FLEXCAN_MAX_TX (MCUX_FLEXCAN_MAX_MB - MCUX_FLEXCAN_MAX_RX) /* @@ -144,7 +144,7 @@ static int mcux_flexcan_get_max_filters(const struct device *dev, bool ide) { ARG_UNUSED(ide); - return CONFIG_CAN_MAX_FILTER; + return CONFIG_CAN_MCUX_FLEXCAN_MAX_FILTERS; } static int mcux_flexcan_set_timing(const struct device *dev, From f2a6a191cf5f18ac2d26edc3518277725fd565fd Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Fri, 5 Dec 2025 15:44:12 +0000 Subject: [PATCH 0048/3659] drivers: can: stm32: bxcan: use proper namespace for Kconfig symbols Use proper namespace for the STM32 bxCAN Kconfig symbols, renaming CONFIG_CAN_MAX_STD_ID_FILTER to CONFIG_CAN_STM32_BXCAN_MAX_STD_ID_FILTERS and CONFIG_CAN_MAX_EXT_ID_FILTER to CONFIG_CAN_STM32_BXCAN_MAX_EXT_ID_FILTERS. This prevents Kconfig symbol clashes between different CAN controller drivers. Signed-off-by: Henrik Brix Andersen --- drivers/can/Kconfig.stm32 | 8 ++--- drivers/can/can_stm32_bxcan.c | 58 +++++++++++++++++++---------------- 2 files changed, 35 insertions(+), 31 deletions(-) diff --git a/drivers/can/Kconfig.stm32 b/drivers/can/Kconfig.stm32 index 7a9bfae3a731..bc6b0173754a 100644 --- a/drivers/can/Kconfig.stm32 +++ b/drivers/can/Kconfig.stm32 @@ -14,7 +14,7 @@ config CAN_STM32_BXCAN if CAN_STM32_BXCAN -config CAN_MAX_STD_ID_FILTER +config CAN_STM32_BXCAN_MAX_STD_ID_FILTERS int "Maximum number of standard (11-bit) ID filters" default 14 range 0 28 @@ -28,9 +28,9 @@ config CAN_MAX_STD_ID_FILTER The following equation determines the maximum total number of filters: - CAN_MAX_STD_ID_FILTER + CAN_MAX_EXT_ID_FILTER * 2 <= 28 + CAN_STM32_BXCAN_MAX_STD_ID_FILTERS + CAN_STM32_BXCAN_MAX_EXT_ID_FILTERS * 2 <= 28 -config CAN_MAX_EXT_ID_FILTER +config CAN_STM32_BXCAN_MAX_EXT_ID_FILTERS int "Maximum number of extended (29-bit) ID filters" default 7 range 0 14 @@ -44,7 +44,7 @@ config CAN_MAX_EXT_ID_FILTER The following equation determines the maximum total number of filters: - CAN_MAX_STD_ID_FILTER + CAN_MAX_EXT_ID_FILTER * 2 <= 28 + CAN_STM32_BXCAN_MAX_STD_ID_FILTERS + CAN_STM32_BXCAN_MAX_EXT_ID_FILTERS * 2 <= 28 endif # CAN_STM32_BXCAN diff --git a/drivers/can/can_stm32_bxcan.c b/drivers/can/can_stm32_bxcan.c index 678ed8fc3ebf..a6ddc854f282 100644 --- a/drivers/can/can_stm32_bxcan.c +++ b/drivers/can/can_stm32_bxcan.c @@ -26,7 +26,7 @@ LOG_MODULE_REGISTER(can_stm32, CONFIG_CAN_LOG_LEVEL); #define CAN_STM32_NUM_FILTER_BANKS (14) #define CAN_STM32_MAX_FILTER_ID \ - (CONFIG_CAN_MAX_EXT_ID_FILTER + CONFIG_CAN_MAX_STD_ID_FILTER * 2) + (CONFIG_CAN_STM32_BXCAN_MAX_EXT_ID_FILTERS + CONFIG_CAN_STM32_BXCAN_MAX_STD_ID_FILTERS * 2) #define CAN_STM32_FIRX_STD_IDE_POS (3U) #define CAN_STM32_FIRX_STD_RTR_POS (4U) @@ -37,7 +37,7 @@ LOG_MODULE_REGISTER(can_stm32, CONFIG_CAN_LOG_LEVEL); #define CAN_STM32_FIRX_EXT_STD_ID_POS (21U) #define CAN_STM32_FIRX_EXT_EXT_ID_POS (3U) -#if (CONFIG_CAN_MAX_STD_ID_FILTER + CONFIG_CAN_MAX_EXT_ID_FILTER * 2) > \ +#if (CONFIG_CAN_STM32_BXCAN_MAX_STD_ID_FILTERS + CONFIG_CAN_STM32_BXCAN_MAX_EXT_ID_FILTERS * 2) > \ (CAN_STM32_NUM_FILTER_BANKS * 2) #error Number of configured filters exceeds available filter bank slots. #endif @@ -54,10 +54,10 @@ struct can_stm32_data { struct can_stm32_mailbox mb0; struct can_stm32_mailbox mb1; struct can_stm32_mailbox mb2; - can_rx_callback_t rx_cb_std[CONFIG_CAN_MAX_STD_ID_FILTER]; - can_rx_callback_t rx_cb_ext[CONFIG_CAN_MAX_EXT_ID_FILTER]; - void *cb_arg_std[CONFIG_CAN_MAX_STD_ID_FILTER]; - void *cb_arg_ext[CONFIG_CAN_MAX_EXT_ID_FILTER]; + can_rx_callback_t rx_cb_std[CONFIG_CAN_STM32_BXCAN_MAX_STD_ID_FILTERS]; + can_rx_callback_t rx_cb_ext[CONFIG_CAN_STM32_BXCAN_MAX_EXT_ID_FILTERS]; + void *cb_arg_std[CONFIG_CAN_STM32_BXCAN_MAX_STD_ID_FILTERS]; + void *cb_arg_ext[CONFIG_CAN_STM32_BXCAN_MAX_EXT_ID_FILTERS]; enum can_state state; }; @@ -130,11 +130,11 @@ static inline void can_stm32_rx_isr_handler(const struct device *dev) can_stm32_rx_fifo_pop(mbox, &frame); - if (filter_id < CONFIG_CAN_MAX_EXT_ID_FILTER) { + if (filter_id < CONFIG_CAN_STM32_BXCAN_MAX_EXT_ID_FILTERS) { callback = data->rx_cb_ext[filter_id]; cb_arg = data->cb_arg_ext[filter_id]; } else if (filter_id < CAN_STM32_MAX_FILTER_ID) { - index = filter_id - CONFIG_CAN_MAX_EXT_ID_FILTER; + index = filter_id - CONFIG_CAN_STM32_BXCAN_MAX_EXT_ID_FILTERS; callback = data->rx_cb_std[index]; cb_arg = data->cb_arg_std[index]; } @@ -586,9 +586,9 @@ static int can_stm32_get_max_filters(const struct device *dev, bool ide) ARG_UNUSED(dev); if (ide) { - return CONFIG_CAN_MAX_EXT_ID_FILTER; + return CONFIG_CAN_STM32_BXCAN_MAX_EXT_ID_FILTERS; } else { - return CONFIG_CAN_MAX_STD_ID_FILTER; + return CONFIG_CAN_STM32_BXCAN_MAX_STD_ID_FILTERS; } } @@ -643,15 +643,17 @@ static int can_stm32_init(const struct device *dev) return ret; } - /* configure scale of filter banks < CONFIG_CAN_MAX_EXT_ID_FILTER for ext ids */ - /* We have to have set filters after initializing master CAN */ + /* + * Configure scale of filter banks < CONFIG_CAN_STM32_BXCAN_MAX_EXT_ID_FILTERS for ext ids + * We have to have set filters after initializing master CAN + */ if (cfg->can == cfg->master_can) { cfg->master_can->FMR |= CAN_FMR_FINIT; - cfg->master_can->FS1R |= ((1U << CONFIG_CAN_MAX_EXT_ID_FILTER) - 1); + cfg->master_can->FS1R |= ((1U << CONFIG_CAN_STM32_BXCAN_MAX_EXT_ID_FILTERS) - 1); #if DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) > 1 /* reserve ext_id filters on slave CAN device */ - cfg->master_can->FS1R |= ((1U << CONFIG_CAN_MAX_EXT_ID_FILTER) - 1) + cfg->master_can->FS1R |= ((1U << CONFIG_CAN_STM32_BXCAN_MAX_EXT_ID_FILTERS) - 1) << CAN_STM32_NUM_FILTER_BANKS; #endif /* DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) > 1 */ @@ -863,7 +865,7 @@ static void can_stm32_set_filter_bank(int filter_id, CAN_FilterRegister_TypeDef filter_reg->FR1 = id; filter_reg->FR2 = mask; } else { - if ((filter_id - CONFIG_CAN_MAX_EXT_ID_FILTER) % 2 == 0) { + if ((filter_id - CONFIG_CAN_STM32_BXCAN_MAX_EXT_ID_FILTERS) % 2 == 0) { /* even std filter id: first 1/2 bank */ filter_reg->FR1 = id | (mask << 16); } else { @@ -919,7 +921,7 @@ static inline int can_stm32_set_filter(const struct device *dev, const struct ca } if ((filter->flags & CAN_FILTER_IDE) != 0) { - for (int i = 0; i < CONFIG_CAN_MAX_EXT_ID_FILTER; i++) { + for (int i = 0; i < CONFIG_CAN_STM32_BXCAN_MAX_EXT_ID_FILTERS; i++) { if (data->rx_cb_ext[i] == NULL) { id = can_stm32_filter_to_ext_id(filter); mask = can_stm32_filter_to_ext_mask(filter); @@ -929,12 +931,13 @@ static inline int can_stm32_set_filter(const struct device *dev, const struct ca } } } else { - for (int i = 0; i < CONFIG_CAN_MAX_STD_ID_FILTER; i++) { + for (int i = 0; i < CONFIG_CAN_STM32_BXCAN_MAX_STD_ID_FILTERS; i++) { if (data->rx_cb_std[i] == NULL) { id = can_stm32_filter_to_std_id(filter); mask = can_stm32_filter_to_std_mask(filter); - filter_id = CONFIG_CAN_MAX_EXT_ID_FILTER + i; - bank_num = bank_offset + CONFIG_CAN_MAX_EXT_ID_FILTER + i / 2; + filter_id = CONFIG_CAN_STM32_BXCAN_MAX_EXT_ID_FILTERS + i; + bank_num = bank_offset + CONFIG_CAN_STM32_BXCAN_MAX_EXT_ID_FILTERS + + i / 2; break; } } @@ -965,7 +968,7 @@ static inline int can_stm32_set_filter(const struct device *dev, const struct ca * This driver uses masked mode for all filters (CAN_FM1R left at reset value * 0x00) in order to simplify mapping between filter match index from the FIFOs * and array index for the callbacks. All ext ID filters are stored in the - * banks below CONFIG_CAN_MAX_EXT_ID_FILTER, followed by the std ID filters, + * banks below CONFIG_CAN_STM32_BXCAN_MAX_EXT_ID_FILTERS, followed by the std ID filters, * which consume only 1/2 bank per filter. * * The more complicated list mode must be implemented if someone requires more @@ -993,8 +996,9 @@ static int can_stm32_add_rx_filter(const struct device *dev, can_rx_callback_t c data->rx_cb_ext[filter_id] = cb; data->cb_arg_ext[filter_id] = cb_arg; } else { - data->rx_cb_std[filter_id - CONFIG_CAN_MAX_EXT_ID_FILTER] = cb; - data->cb_arg_std[filter_id - CONFIG_CAN_MAX_EXT_ID_FILTER] = cb_arg; + data->rx_cb_std[filter_id - CONFIG_CAN_STM32_BXCAN_MAX_EXT_ID_FILTERS] = cb; + data->cb_arg_std[filter_id - CONFIG_CAN_STM32_BXCAN_MAX_EXT_ID_FILTERS] = + cb_arg; } } @@ -1026,7 +1030,7 @@ static void can_stm32_remove_rx_filter(const struct device *dev, int filter_id) bank_offset = CAN_STM32_NUM_FILTER_BANKS; } - if (filter_id < CONFIG_CAN_MAX_EXT_ID_FILTER) { + if (filter_id < CONFIG_CAN_STM32_BXCAN_MAX_EXT_ID_FILTERS) { ide = true; bank_num = bank_offset + filter_id; @@ -1035,18 +1039,18 @@ static void can_stm32_remove_rx_filter(const struct device *dev, int filter_id) bank_unused = true; } else { - int filter_index = filter_id - CONFIG_CAN_MAX_EXT_ID_FILTER; + int filter_index = filter_id - CONFIG_CAN_STM32_BXCAN_MAX_EXT_ID_FILTERS; ide = false; - bank_num = bank_offset + CONFIG_CAN_MAX_EXT_ID_FILTER + - (filter_id - CONFIG_CAN_MAX_EXT_ID_FILTER) / 2; + bank_num = bank_offset + CONFIG_CAN_STM32_BXCAN_MAX_EXT_ID_FILTERS + + (filter_id - CONFIG_CAN_STM32_BXCAN_MAX_EXT_ID_FILTERS) / 2; data->rx_cb_std[filter_index] = NULL; data->cb_arg_std[filter_index] = NULL; if (filter_index % 2 == 1) { bank_unused = data->rx_cb_std[filter_index - 1] == NULL; - } else if (filter_index + 1 < CONFIG_CAN_MAX_STD_ID_FILTER) { + } else if (filter_index + 1 < CONFIG_CAN_STM32_BXCAN_MAX_STD_ID_FILTERS) { bank_unused = data->rx_cb_std[filter_index + 1] == NULL; } else { bank_unused = true; From 38c329742146682822d17743fa724dc93f703fe6 Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Fri, 5 Dec 2025 15:50:40 +0000 Subject: [PATCH 0049/3659] drivers: can: stm32: fdcan: use proper namespace for Kconfig symbols Use proper namespace for the STM32 FDCAN Kconfig symbols, renaming CONFIG_CAN_MAX_STD_ID_FILTER to CONFIG_CAN_STM32_FDCAN_MAX_STD_ID_FILTERS and CONFIG_CAN_MAX_EXT_ID_FILTER to CONFIG_CAN_STM32_FDCAN_MAX_EXT_ID_FILTERS. This prevents Kconfig symbol clashes between different CAN controller drivers. Signed-off-by: Henrik Brix Andersen --- drivers/can/Kconfig.stm32 | 4 ++-- drivers/can/can_stm32_fdcan.c | 14 ++++++++------ 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/drivers/can/Kconfig.stm32 b/drivers/can/Kconfig.stm32 index bc6b0173754a..4fa75466d373 100644 --- a/drivers/can/Kconfig.stm32 +++ b/drivers/can/Kconfig.stm32 @@ -57,7 +57,7 @@ config CAN_STM32_FDCAN if CAN_STM32_FDCAN -config CAN_MAX_STD_ID_FILTER +config CAN_STM32_FDCAN_MAX_STD_ID_FILTERS int "Maximum number of standard (11-bit) ID filters" default 28 range 0 28 @@ -65,7 +65,7 @@ config CAN_MAX_STD_ID_FILTER Defines the maximum number of filters with standard ID (11-bit) that can be added by the application. -config CAN_MAX_EXT_ID_FILTER +config CAN_STM32_FDCAN_MAX_EXT_ID_FILTERS int "Maximum number of extended (29-bit) ID filters" default 8 range 0 8 diff --git a/drivers/can/can_stm32_fdcan.c b/drivers/can/can_stm32_fdcan.c index ee54d38c263b..8a5021cf2953 100644 --- a/drivers/can/can_stm32_fdcan.c +++ b/drivers/can/can_stm32_fdcan.c @@ -361,8 +361,10 @@ static int can_stm32fd_write_reg(const struct device *dev, uint16_t reg, uint32_ break; case CAN_MCAN_GFC: /* Map fields to RXGFC including STM32 FDCAN LSS and LSE fields */ - bits |= FIELD_PREP(CAN_STM32FD_RXGFC_LSS, CONFIG_CAN_MAX_STD_ID_FILTER) | - FIELD_PREP(CAN_STM32FD_RXGFC_LSE, CONFIG_CAN_MAX_EXT_ID_FILTER); + bits |= FIELD_PREP(CAN_STM32FD_RXGFC_LSS, + CONFIG_CAN_STM32_FDCAN_MAX_STD_ID_FILTERS); + bits |= FIELD_PREP(CAN_STM32FD_RXGFC_LSE, + CONFIG_CAN_STM32_FDCAN_MAX_EXT_ID_FILTERS); bits |= val & (CAN_MCAN_GFC_ANFS | CAN_MCAN_GFC_ANFE | CAN_MCAN_GFC_RRFS | CAN_MCAN_GFC_RRFE); break; @@ -499,8 +501,8 @@ static int can_stm32fd_init(const struct device *dev) return ret; } - rxgfc |= FIELD_PREP(CAN_STM32FD_RXGFC_LSS, CONFIG_CAN_MAX_STD_ID_FILTER) | - FIELD_PREP(CAN_STM32FD_RXGFC_LSE, CONFIG_CAN_MAX_EXT_ID_FILTER); + rxgfc |= FIELD_PREP(CAN_STM32FD_RXGFC_LSS, CONFIG_CAN_STM32_FDCAN_MAX_STD_ID_FILTERS) | + FIELD_PREP(CAN_STM32FD_RXGFC_LSE, CONFIG_CAN_STM32_FDCAN_MAX_EXT_ID_FILTERS); ret = can_mcan_write_reg(dev, CAN_STM32FD_RXGFC, rxgfc); if (ret != 0) { @@ -594,8 +596,8 @@ static const struct can_mcan_ops can_stm32fd_ops = { PINCTRL_DT_INST_DEFINE(inst); \ CAN_MCAN_CALLBACKS_DEFINE(can_stm32fd_cbs_##inst, \ CAN_MCAN_DT_INST_MRAM_TX_BUFFER_ELEMENTS(inst), \ - CONFIG_CAN_MAX_STD_ID_FILTER, \ - CONFIG_CAN_MAX_EXT_ID_FILTER); \ + CONFIG_CAN_STM32_FDCAN_MAX_STD_ID_FILTERS, \ + CONFIG_CAN_STM32_FDCAN_MAX_EXT_ID_FILTERS); \ \ static const struct stm32_pclken can_stm32fd_pclken_##inst[] = \ STM32_DT_INST_CLOCKS(inst); \ From d3104b9f6dcd8a289bc2d245d712efb31735283f Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Fri, 5 Dec 2025 15:58:13 +0000 Subject: [PATCH 0050/3659] drivers: can: xmc4xxx: use proper namespace for Kconfig symbols Use proper namespace for the CAN xmc4xxx Kconfig symbols, renaming CONFIG_CAN_MAX_FILTER to CONFIG_CAN_XMC4XXX_MAX_FILTERS. This prevents Kconfig symbol clashes between different CAN controller drivers. Signed-off-by: Henrik Brix Andersen --- drivers/can/Kconfig.xmc4xxx | 2 +- drivers/can/can_xmc4xxx.c | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/can/Kconfig.xmc4xxx b/drivers/can/Kconfig.xmc4xxx index 39fbc34a7cc5..e052fcff54d2 100644 --- a/drivers/can/Kconfig.xmc4xxx +++ b/drivers/can/Kconfig.xmc4xxx @@ -35,7 +35,7 @@ config CAN_XMC4XXX_INTERNAL_BUS_MODE Connects all XMC4XXX CAN devices to an internal bus. Enables message exchange between MCU CAN devices without any external connectors. -config CAN_MAX_FILTER +config CAN_XMC4XXX_MAX_FILTERS int "Maximum number of concurrent active filters" default 4 range 1 32 diff --git a/drivers/can/can_xmc4xxx.c b/drivers/can/can_xmc4xxx.c index 894bf5f10b6e..fc758cc6909a 100644 --- a/drivers/can/can_xmc4xxx.c +++ b/drivers/can/can_xmc4xxx.c @@ -65,10 +65,10 @@ struct can_xmc4xxx_data { struct can_xmc4xxx_tx_callback tx_callbacks[CONFIG_CAN_XMC4XXX_MAX_TX_QUEUE]; uint32_t filter_usage; - struct can_xmc4xxx_rx_callback rx_callbacks[CONFIG_CAN_MAX_FILTER]; - struct can_xmc4xxx_rx_fifo rx_fifos[CONFIG_CAN_MAX_FILTER]; + struct can_xmc4xxx_rx_callback rx_callbacks[CONFIG_CAN_XMC4XXX_MAX_FILTERS]; + struct can_xmc4xxx_rx_fifo rx_fifos[CONFIG_CAN_XMC4XXX_MAX_FILTERS]; #if defined(CONFIG_CAN_ACCEPT_RTR) - struct can_xmc4xxx_rx_fifo rtr_fifos[CONFIG_CAN_MAX_FILTER]; + struct can_xmc4xxx_rx_fifo rtr_fifos[CONFIG_CAN_XMC4XXX_MAX_FILTERS]; #endif CAN_MO_TypeDef *tx_mo[CONFIG_CAN_XMC4XXX_MAX_TX_QUEUE]; @@ -362,13 +362,13 @@ static int can_xmc4xxx_add_rx_filter(const struct device *dev, can_rx_callback_t k_mutex_lock(&dev_data->mutex, K_FOREVER); - for (filter_idx = 0; filter_idx < CONFIG_CAN_MAX_FILTER; filter_idx++) { + for (filter_idx = 0; filter_idx < CONFIG_CAN_XMC4XXX_MAX_FILTERS; filter_idx++) { if ((BIT(filter_idx) & dev_data->filter_usage) == 0) { break; } } - if (filter_idx >= CONFIG_CAN_MAX_FILTER) { + if (filter_idx >= CONFIG_CAN_XMC4XXX_MAX_FILTERS) { filter_idx = -ENOSPC; } else { unsigned int key = irq_lock(); @@ -408,7 +408,7 @@ static void can_xmc4xxx_remove_rx_filter(const struct device *dev, int filter_id struct can_xmc4xxx_data *dev_data = dev->data; unsigned int key; - if (filter_idx < 0 || filter_idx >= CONFIG_CAN_MAX_FILTER) { + if (filter_idx < 0 || filter_idx >= CONFIG_CAN_XMC4XXX_MAX_FILTERS) { LOG_ERR("Filter ID %d out of bounds", filter_idx); return; } @@ -509,7 +509,7 @@ static int can_xmc4xxx_get_max_filters(const struct device *dev, bool ide) { ARG_UNUSED(ide); - return CONFIG_CAN_MAX_FILTER; + return CONFIG_CAN_XMC4XXX_MAX_FILTERS; } static void can_xmc4xxx_reset_tx_fifos(const struct device *dev, int status) @@ -640,7 +640,7 @@ static void can_xmc4xxx_rx_handler(const struct device *dev) { struct can_xmc4xxx_data *dev_data = dev->data; - for (int i = 0; i < CONFIG_CAN_MAX_FILTER; i++) { + for (int i = 0; i < CONFIG_CAN_XMC4XXX_MAX_FILTERS; i++) { if ((BIT(i) & dev_data->filter_usage) == 0) { continue; } From 479666f26f7b9cd1b20356d4fe8271781572d73b Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Sat, 6 Dec 2025 10:52:49 +0000 Subject: [PATCH 0051/3659] drivers: can: rcar: rename CONFIG_CAN_RCAR_MAX_FILTER Kconfig option Rename Kconfig option CONFIG_CAN_RCAR_MAX_FILTER to CONFIG_CAN_RCAR_MAX_FILTERS to match remaining CAN driver Kconfig option naming. Signed-off-by: Henrik Brix Andersen --- drivers/can/Kconfig.rcar | 2 +- drivers/can/can_rcar.c | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/can/Kconfig.rcar b/drivers/can/Kconfig.rcar index 7ae2e1e927ea..4bc7864a5937 100644 --- a/drivers/can/Kconfig.rcar +++ b/drivers/can/Kconfig.rcar @@ -11,7 +11,7 @@ config CAN_RCAR help Enable Renesas R-Car CAN Driver. -config CAN_RCAR_MAX_FILTER +config CAN_RCAR_MAX_FILTERS int "Maximum number of concurrent active filters" depends on CAN_RCAR default 5 diff --git a/drivers/can/can_rcar.c b/drivers/can/can_rcar.c index 8ac6be729cc9..f9c5aa7328c0 100644 --- a/drivers/can/can_rcar.c +++ b/drivers/can/can_rcar.c @@ -190,9 +190,9 @@ struct can_rcar_data { uint8_t tx_tail; uint8_t tx_unsent; struct k_mutex rx_mutex; - can_rx_callback_t rx_callback[CONFIG_CAN_RCAR_MAX_FILTER]; - void *rx_callback_arg[CONFIG_CAN_RCAR_MAX_FILTER]; - struct can_filter filter[CONFIG_CAN_RCAR_MAX_FILTER]; + can_rx_callback_t rx_callback[CONFIG_CAN_RCAR_MAX_FILTERS]; + void *rx_callback_arg[CONFIG_CAN_RCAR_MAX_FILTERS]; + struct can_filter filter[CONFIG_CAN_RCAR_MAX_FILTERS]; enum can_state state; }; @@ -364,7 +364,7 @@ static void can_rcar_rx_filter_isr(const struct device *dev, } #endif /* !CONFIG_CAN_ACCEPT_RTR */ - for (i = 0; i < CONFIG_CAN_RCAR_MAX_FILTER; i++) { + for (i = 0; i < CONFIG_CAN_RCAR_MAX_FILTERS; i++) { if (data->rx_callback[i] == NULL) { continue; } @@ -957,7 +957,7 @@ static inline int can_rcar_add_rx_filter_unlocked(const struct device *dev, struct can_rcar_data *data = dev->data; int i; - for (i = 0; i < CONFIG_CAN_RCAR_MAX_FILTER; i++) { + for (i = 0; i < CONFIG_CAN_RCAR_MAX_FILTERS; i++) { if (data->rx_callback[i] == NULL) { data->rx_callback_arg[i] = cb_arg; data->filter[i] = *filter; @@ -991,7 +991,7 @@ static void can_rcar_remove_rx_filter(const struct device *dev, int filter_id) { struct can_rcar_data *data = dev->data; - if (filter_id < 0 || filter_id >= CONFIG_CAN_RCAR_MAX_FILTER) { + if (filter_id < 0 || filter_id >= CONFIG_CAN_RCAR_MAX_FILTERS) { LOG_ERR("filter ID %d out of bounds", filter_id); return; } @@ -1142,7 +1142,7 @@ static int can_rcar_get_max_filters(const struct device *dev, bool ide) { ARG_UNUSED(ide); - return CONFIG_CAN_RCAR_MAX_FILTER; + return CONFIG_CAN_RCAR_MAX_FILTERS; } static DEVICE_API(can, can_rcar_driver_api) = { From 65eee6d3d9be8808cb9de565267042bfb693ee80 Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Fri, 5 Dec 2025 16:15:17 +0000 Subject: [PATCH 0052/3659] drivers: can: increase default setting for software-limited RX filters Increase the default number of software-limited CAN RX filters across the drivers. Some of these were chosen quite conservative, requiring custom configuration for even simple in-tree samples. Users can reduce the number of available RX filters to reduce RAM footprint as needed. Signed-off-by: Henrik Brix Andersen --- drivers/can/Kconfig.max32 | 2 +- drivers/can/Kconfig.mcp2515 | 2 +- drivers/can/Kconfig.mcp251xfd | 2 +- drivers/can/Kconfig.mcux | 2 +- drivers/can/Kconfig.native_linux | 2 +- drivers/can/Kconfig.rcar | 2 +- drivers/can/Kconfig.sja1000 | 2 +- drivers/can/Kconfig.xmc4xxx | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/can/Kconfig.max32 b/drivers/can/Kconfig.max32 index 165437ef3c38..5beb8c95f36f 100644 --- a/drivers/can/Kconfig.max32 +++ b/drivers/can/Kconfig.max32 @@ -13,7 +13,7 @@ if CAN_MAX32 config CAN_MAX32_MAX_FILTERS int "Maximum number of concurrent active filters" - default 5 + default 16 range 1 32 help Maximum number of filters supported by the can_add_rx_callback() API call. diff --git a/drivers/can/Kconfig.mcp2515 b/drivers/can/Kconfig.mcp2515 index 732e322de254..b14f841780a2 100644 --- a/drivers/can/Kconfig.mcp2515 +++ b/drivers/can/Kconfig.mcp2515 @@ -29,7 +29,7 @@ config CAN_MCP2515_INT_THREAD_PRIO config CAN_MCP2515_MAX_FILTERS int "Maximum number of concurrent active filters" - default 5 + default 16 range 1 32 help Defines the array size of the callback/msgq pointers. diff --git a/drivers/can/Kconfig.mcp251xfd b/drivers/can/Kconfig.mcp251xfd index c6762c345807..f924c7b40735 100644 --- a/drivers/can/Kconfig.mcp251xfd +++ b/drivers/can/Kconfig.mcp251xfd @@ -53,7 +53,7 @@ config CAN_MCP251XFD_READ_CRC_RETRIES config CAN_MCP251XFD_MAX_FILTERS int "Maximum number of concurrent active filters" - default 5 + default 16 range 1 32 help Maximum number of filters supported by the can_add_rx_callback() API call. diff --git a/drivers/can/Kconfig.mcux b/drivers/can/Kconfig.mcux index aeb98b447845..723cd6108545 100644 --- a/drivers/can/Kconfig.mcux +++ b/drivers/can/Kconfig.mcux @@ -41,7 +41,7 @@ config CAN_MCUX_FLEXCAN_MAX_MB config CAN_MCUX_FLEXCAN_MAX_FILTERS int "Maximum number of concurrent active RX filters" - default 5 + default 13 range 1 15 if SOC_SERIES_KINETIS_KE1XF || SOC_SERIES_KINETIS_K6X range 1 13 if (SOC_SERIES_IMXRT10XX || SOC_SERIES_IMXRT11XX) && CAN_MCUX_FLEXCAN_FD range 1 63 if SOC_SERIES_IMXRT10XX || SOC_SERIES_IMXRT11XX diff --git a/drivers/can/Kconfig.native_linux b/drivers/can/Kconfig.native_linux index 4d5f5b42ede7..1de766bb8f2d 100644 --- a/drivers/can/Kconfig.native_linux +++ b/drivers/can/Kconfig.native_linux @@ -22,7 +22,7 @@ config CAN_NATIVE_LINUX_RX_THREAD_PRIORITY config CAN_NATIVE_LINUX_MAX_FILTERS int "Maximum number of concurrent active filters" - default 5 + default 16 range 1 32 help Defines the array size of the callback/msgq pointers. diff --git a/drivers/can/Kconfig.rcar b/drivers/can/Kconfig.rcar index 4bc7864a5937..f1392a45562f 100644 --- a/drivers/can/Kconfig.rcar +++ b/drivers/can/Kconfig.rcar @@ -14,7 +14,7 @@ config CAN_RCAR config CAN_RCAR_MAX_FILTERS int "Maximum number of concurrent active filters" depends on CAN_RCAR - default 5 + default 16 range 1 32 help Defines the array size of the callback/msgq pointers. diff --git a/drivers/can/Kconfig.sja1000 b/drivers/can/Kconfig.sja1000 index 8966e6a07c78..ce253479b203 100644 --- a/drivers/can/Kconfig.sja1000 +++ b/drivers/can/Kconfig.sja1000 @@ -11,7 +11,7 @@ config CAN_SJA1000 config CAN_SJA1000_MAX_FILTERS int "Maximum number of concurrent active RX filters" depends on CAN_SJA1000 - default 5 + default 16 range 1 32 help As the NXP SJA1000 only supports one full-width RX filter, filtering of received CAN diff --git a/drivers/can/Kconfig.xmc4xxx b/drivers/can/Kconfig.xmc4xxx index e052fcff54d2..3f65f1edf307 100644 --- a/drivers/can/Kconfig.xmc4xxx +++ b/drivers/can/Kconfig.xmc4xxx @@ -37,7 +37,7 @@ config CAN_XMC4XXX_INTERNAL_BUS_MODE config CAN_XMC4XXX_MAX_FILTERS int "Maximum number of concurrent active filters" - default 4 + default 16 range 1 32 help Maximum number of filters supported by the can_add_rx_callback() API call. From d672bdbdcc3d54fc0669c92a8743ac2ab15b5681 Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Fri, 5 Dec 2025 16:21:49 +0000 Subject: [PATCH 0053/3659] samples: can: remove CONFIG_CAN_MAX_FILTER setting Remove setting of CONFIG_CAN_MAX_FILTER and rely on driver defaults. Signed-off-by: Henrik Brix Andersen --- samples/drivers/can/counter/prj.conf | 1 - samples/modules/canopennode/prj.conf | 1 - samples/modules/canopennode/prj_img_mgmt.conf | 1 - samples/modules/canopennode/prj_no_storage.conf | 1 - samples/net/sockets/can/prj.conf | 1 - samples/subsys/canbus/isotp/prj.conf | 1 - 6 files changed, 6 deletions(-) diff --git a/samples/drivers/can/counter/prj.conf b/samples/drivers/can/counter/prj.conf index 7345dfaba83c..1b7858867b65 100644 --- a/samples/drivers/can/counter/prj.conf +++ b/samples/drivers/can/counter/prj.conf @@ -1,7 +1,6 @@ CONFIG_POLL=y CONFIG_CAN=y CONFIG_CAN_INIT_PRIORITY=80 -CONFIG_CAN_MAX_FILTER=5 CONFIG_SHELL=y CONFIG_CAN_SHELL=y diff --git a/samples/modules/canopennode/prj.conf b/samples/modules/canopennode/prj.conf index 905a1934f499..7df1d4fbad03 100644 --- a/samples/modules/canopennode/prj.conf +++ b/samples/modules/canopennode/prj.conf @@ -4,7 +4,6 @@ CONFIG_CANOPEN_LOG_LEVEL_DBG=y CONFIG_GPIO=y CONFIG_CAN=y -CONFIG_CAN_MAX_FILTER=13 CONFIG_FLASH=y CONFIG_NVS=y diff --git a/samples/modules/canopennode/prj_img_mgmt.conf b/samples/modules/canopennode/prj_img_mgmt.conf index c837ad05a941..7ef604d92b5b 100644 --- a/samples/modules/canopennode/prj_img_mgmt.conf +++ b/samples/modules/canopennode/prj_img_mgmt.conf @@ -4,7 +4,6 @@ CONFIG_CANOPEN_LOG_LEVEL_DBG=y CONFIG_GPIO=y CONFIG_CAN=y -CONFIG_CAN_MAX_FILTER=13 CONFIG_FLASH=y CONFIG_FLASH_MAP=y diff --git a/samples/modules/canopennode/prj_no_storage.conf b/samples/modules/canopennode/prj_no_storage.conf index b296e8c08320..3e9177c26da6 100644 --- a/samples/modules/canopennode/prj_no_storage.conf +++ b/samples/modules/canopennode/prj_no_storage.conf @@ -4,7 +4,6 @@ CONFIG_CANOPEN_LOG_LEVEL_DBG=y CONFIG_GPIO=y CONFIG_CAN=y -CONFIG_CAN_MAX_FILTER=13 CONFIG_CANOPEN=y CONFIG_CANOPENNODE_SYNC_THREAD=y diff --git a/samples/net/sockets/can/prj.conf b/samples/net/sockets/can/prj.conf index 04ea69917edd..2ba72a0957f3 100644 --- a/samples/net/sockets/can/prj.conf +++ b/samples/net/sockets/can/prj.conf @@ -1,6 +1,5 @@ CONFIG_CAN=y CONFIG_NET_L2_ETHERNET=n -CONFIG_CAN_MAX_FILTER=5 CONFIG_NETWORKING=y CONFIG_NET_DRIVERS=y diff --git a/samples/subsys/canbus/isotp/prj.conf b/samples/subsys/canbus/isotp/prj.conf index 04c9fc95d130..3250795716dc 100644 --- a/samples/subsys/canbus/isotp/prj.conf +++ b/samples/subsys/canbus/isotp/prj.conf @@ -1,7 +1,6 @@ CONFIG_LOG=y CONFIG_CAN=y -CONFIG_CAN_MAX_FILTER=8 CONFIG_ISOTP=y # We have two receiving contexts that are bound to a single address. From 8f7861fbd7f7666dc95993fbadd113c6895b695b Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Fri, 5 Dec 2025 16:35:50 +0000 Subject: [PATCH 0054/3659] doc: releases: migration guide: 4.4: add entry for CAN Kconfig changes Mention the CAN controller driver Kconfig namespace changes in the migration guide. Signed-off-by: Henrik Brix Andersen --- doc/releases/migration-guide-4.4.rst | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/doc/releases/migration-guide-4.4.rst b/doc/releases/migration-guide-4.4.rst index e01816350c3a..f24fe700ae46 100644 --- a/doc/releases/migration-guide-4.4.rst +++ b/doc/releases/migration-guide-4.4.rst @@ -39,6 +39,31 @@ Device Drivers and Devicetree .. zephyr-keep-sorted-start re(^\w) +Controller Area Network (CAN) +============================= + +* Removed ``CONFIG_CAN_MAX_FILTER``, ``CONFIG_CAN_MAX_STD_ID_FILTER``, + ``CONFIG_CAN_MAX_EXT_ID_FILTER``, and ``CONFIG_CAN_MAX_MB`` (:github:`100596`). These are replaced + by the following driver-specific Kconfig symbols, some of which have had their default value + increased to meet typical software needs: + + * :kconfig:option:`CONFIG_CAN_LOOPBACK_MAX_FILTERS` for :dtcompatible:`zephyr,can-loopback` + * :kconfig:option:`CONFIG_CAN_MAX32_MAX_FILTERS` for :dtcompatible:`adi,max32-can` + * :kconfig:option:`CONFIG_CAN_MCP2515_MAX_FILTERS` for :dtcompatible:`microchip,mcp2515` + * :kconfig:option:`CONFIG_CAN_MCP251XFD_MAX_FILTERS` for :dtcompatible:`microchip,mcp251xfd` + * :kconfig:option:`CONFIG_CAN_MCUX_FLEXCAN_MAX_FILTERS` for :dtcompatible:`nxp,flexcan` + * :kconfig:option:`CONFIG_CAN_MCUX_FLEXCAN_MAX_MB` for :dtcompatible:`nxp,flexcan` + * :kconfig:option:`CONFIG_CAN_NATIVE_LINUX_MAX_FILTERS` for + :dtcompatible:`zephyr,native-linux-can` + * :kconfig:option:`CONFIG_CAN_RCAR_MAX_FILTERS` for :dtcompatible:`renesas,rcar-can` + * :kconfig:option:`CONFIG_CAN_SJA1000_MAX_FILTERS` for :dtcompatible:`kvaser,pcican` and + :dtcompatible:`espressif,esp32-twai` + * :kconfig:option:`CONFIG_CAN_STM32_BXCAN_MAX_EXT_ID_FILTERS` for :dtcompatible:`st,stm32-bxcan` + * :kconfig:option:`CONFIG_CAN_STM32_BXCAN_MAX_STD_ID_FILTERS` for :dtcompatible:`st,stm32-bxcan` + * :kconfig:option:`CONFIG_CAN_STM32_FDCAN_MAX_EXT_ID_FILTERS` for :dtcompatible:`st,stm32-fdcan` + * :kconfig:option:`CONFIG_CAN_STM32_FDCAN_MAX_STD_ID_FILTERS` for :dtcompatible:`st,stm32-fdcan` + * :kconfig:option:`CONFIG_CAN_XMC4XXX_MAX_FILTERS` for :dtcompatible:`infineon,xmc4xxx-can-node` + Ethernet ======== From a0602f035803982fb7bb2d22899597ee914f600b Mon Sep 17 00:00:00 2001 From: Martin Hoff Date: Fri, 5 Dec 2025 17:03:23 +0100 Subject: [PATCH 0055/3659] tests: driver: spi: add overlay for xg23_rb4210a board This patch introduces overlay for xg23_rb4210a for the spi_loopback test. It is needed because it has another peripheral ip version than all the other already tested board. Signed-off-by: Martin Hoff --- .../spi/spi_loopback/boards/xg23_rb4210a.conf | 2 ++ .../spi_loopback/boards/xg23_rb4210a.overlay | 35 +++++++++++++++++++ tests/drivers/spi/spi_loopback/testcase.yaml | 2 ++ 3 files changed, 39 insertions(+) create mode 100644 tests/drivers/spi/spi_loopback/boards/xg23_rb4210a.conf create mode 100644 tests/drivers/spi/spi_loopback/boards/xg23_rb4210a.overlay diff --git a/tests/drivers/spi/spi_loopback/boards/xg23_rb4210a.conf b/tests/drivers/spi/spi_loopback/boards/xg23_rb4210a.conf new file mode 100644 index 000000000000..1e3c5f17bfc3 --- /dev/null +++ b/tests/drivers/spi/spi_loopback/boards/xg23_rb4210a.conf @@ -0,0 +1,2 @@ +CONFIG_DMA_MAX_DESCRIPTOR=16 +CONFIG_SPI_SILABS_EUSART_DMA_MAX_BLOCKS=10 diff --git a/tests/drivers/spi/spi_loopback/boards/xg23_rb4210a.overlay b/tests/drivers/spi/spi_loopback/boards/xg23_rb4210a.overlay new file mode 100644 index 000000000000..455e05c3b29e --- /dev/null +++ b/tests/drivers/spi/spi_loopback/boards/xg23_rb4210a.overlay @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2025 Silicon Laboratories Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&eusart1 { + dmas = <&dma0 DMA_REQSEL_EUSART1TXFL>, + <&dma0 DMA_REQSEL_EUSART1RXFL>; + dma-names = "tx", "rx"; + #address-cells = <1>; + #size-cells = <0>; + pinctrl-0 = <&eusart1_default>; + pinctrl-names = "default"; + status = "okay"; + cs-gpios = <&gpioc 0 GPIO_ACTIVE_LOW>; + + slow@0 { + compatible = "test-spi-loopback-slow"; + reg = <0>; + spi-max-frequency = <500000>; + }; + + fast@1 { + compatible = "test-spi-loopback-fast"; + reg = <1>; + spi-max-frequency = <10000000>; + }; +}; + +&dma0 { + status = "okay"; +}; diff --git a/tests/drivers/spi/spi_loopback/testcase.yaml b/tests/drivers/spi/spi_loopback/testcase.yaml index 30d3c9528ce5..e46ace151095 100644 --- a/tests/drivers/spi/spi_loopback/testcase.yaml +++ b/tests/drivers/spi/spi_loopback/testcase.yaml @@ -341,6 +341,7 @@ tests: drivers.spi.silabs_s2.loopback.no_async: filter: CONFIG_SOC_FAMILY_SILABS_S2 platform_allow: + - xg23_rb4210a - xg24_rb4187c - xg29_rb4412a - bg29_rb4420a @@ -350,6 +351,7 @@ tests: drivers.spi.silabs_s2.loopback.dma.no_async: filter: CONFIG_SOC_FAMILY_SILABS_S2 platform_allow: + - xg23_rb4210a - xg24_rb4187c - xg29_rb4412a - bg29_rb4420a From e784d3bc0d88d6a0144fdb663196eb04025f753f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Ju=C5=99ena?= Date: Fri, 5 Dec 2025 16:42:12 +0100 Subject: [PATCH 0056/3659] boards: st: Add stlink_dbgserver to multiple boards MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Allow to use `stlink_gdbserver` as a gdb server when running `west debug -r stlink_gdbserver`. This is helpful when OpenOCD does not yet support the chip, for example, **nucleo_c071rb**. In my tests, I have flashed the debug build of *blinky* sample and used GDB to add a temporary hardware breakpoint to the main function. When I reached there, I stepped through the code. I have tested this with the following boards: - disco_l475_iot1 - nucleo_c071rb - nucleo_f042k6 - nucleo_f303k8 - nucleo_f303re - nucleo_f411re - nucleo_l432kc - nucleo_l452re - nucleo_wl55jc - stm32f0_disco - stm32f3_disco - stm32f411e_disco - stm32f412g_disco - stm32f429i_disc1 - stm32f4_disco - stm32f769i_disco - stm32l1_disco - stm32l476g_disco Signed-off-by: Tomáš Juřena --- boards/st/disco_l475_iot1/board.cmake | 1 + boards/st/nucleo_c071rb/board.cmake | 1 + boards/st/nucleo_f042k6/board.cmake | 1 + boards/st/nucleo_f303k8/board.cmake | 1 + boards/st/nucleo_f303re/board.cmake | 1 + boards/st/nucleo_f411re/board.cmake | 1 + boards/st/nucleo_l432kc/board.cmake | 1 + boards/st/nucleo_l452re/board.cmake | 1 + boards/st/nucleo_wl55jc/board.cmake | 1 + boards/st/stm32f0_disco/board.cmake | 1 + boards/st/stm32f3_disco/board.cmake | 1 + boards/st/stm32f411e_disco/board.cmake | 1 + boards/st/stm32f412g_disco/board.cmake | 1 + boards/st/stm32f429i_disc1/board.cmake | 1 + boards/st/stm32f4_disco/board.cmake | 1 + boards/st/stm32f769i_disco/board.cmake | 1 + boards/st/stm32l1_disco/board.cmake | 1 + boards/st/stm32l476g_disco/board.cmake | 1 + 18 files changed, 18 insertions(+) diff --git a/boards/st/disco_l475_iot1/board.cmake b/boards/st/disco_l475_iot1/board.cmake index 6ef3d18c39c0..9893cc2bcdaf 100644 --- a/boards/st/disco_l475_iot1/board.cmake +++ b/boards/st/disco_l475_iot1/board.cmake @@ -8,3 +8,4 @@ board_runner_args(jlink "--device=STM32L475VG" "--speed=4000") include(${ZEPHYR_BASE}/boards/common/stm32cubeprogrammer.board.cmake) include(${ZEPHYR_BASE}/boards/common/openocd-stm32.board.cmake) include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) +include(${ZEPHYR_BASE}/boards/common/stlink_gdbserver.board.cmake) diff --git a/boards/st/nucleo_c071rb/board.cmake b/boards/st/nucleo_c071rb/board.cmake index daa77274ae17..659df8023c81 100644 --- a/boards/st/nucleo_c071rb/board.cmake +++ b/boards/st/nucleo_c071rb/board.cmake @@ -6,3 +6,4 @@ board_runner_args(stm32cubeprogrammer "--port=swd" "--reset-mode=hw") # keep first include(${ZEPHYR_BASE}/boards/common/stm32cubeprogrammer.board.cmake) include(${ZEPHYR_BASE}/boards/common/openocd-stm32.board.cmake) +include(${ZEPHYR_BASE}/boards/common/stlink_gdbserver.board.cmake) diff --git a/boards/st/nucleo_f042k6/board.cmake b/boards/st/nucleo_f042k6/board.cmake index fd92c7b5edc3..96992536e1b2 100644 --- a/boards/st/nucleo_f042k6/board.cmake +++ b/boards/st/nucleo_f042k6/board.cmake @@ -8,3 +8,4 @@ board_runner_args(jlink "--device=STM32F042K6" "--speed=4000") include(${ZEPHYR_BASE}/boards/common/stm32cubeprogrammer.board.cmake) include(${ZEPHYR_BASE}/boards/common/openocd-stm32.board.cmake) include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) +include(${ZEPHYR_BASE}/boards/common/stlink_gdbserver.board.cmake) diff --git a/boards/st/nucleo_f303k8/board.cmake b/boards/st/nucleo_f303k8/board.cmake index 2ee7dcf79ead..2cbbb0d203f8 100644 --- a/boards/st/nucleo_f303k8/board.cmake +++ b/boards/st/nucleo_f303k8/board.cmake @@ -12,3 +12,4 @@ include(${ZEPHYR_BASE}/boards/common/stm32cubeprogrammer.board.cmake) include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake) include(${ZEPHYR_BASE}/boards/common/openocd-stm32.board.cmake) include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) +include(${ZEPHYR_BASE}/boards/common/stlink_gdbserver.board.cmake) diff --git a/boards/st/nucleo_f303re/board.cmake b/boards/st/nucleo_f303re/board.cmake index f7b8c33c3186..ffbbe3e13cc2 100644 --- a/boards/st/nucleo_f303re/board.cmake +++ b/boards/st/nucleo_f303re/board.cmake @@ -8,3 +8,4 @@ board_runner_args(jlink "--device=STM32F303RE" "--speed=4000") include(${ZEPHYR_BASE}/boards/common/stm32cubeprogrammer.board.cmake) include(${ZEPHYR_BASE}/boards/common/openocd-stm32.board.cmake) include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) +include(${ZEPHYR_BASE}/boards/common/stlink_gdbserver.board.cmake) diff --git a/boards/st/nucleo_f411re/board.cmake b/boards/st/nucleo_f411re/board.cmake index a1e8a2d1e07a..b1a805ce5d84 100644 --- a/boards/st/nucleo_f411re/board.cmake +++ b/boards/st/nucleo_f411re/board.cmake @@ -8,3 +8,4 @@ board_runner_args(jlink "--device=STM32F411RE" "--speed=4000") include(${ZEPHYR_BASE}/boards/common/stm32cubeprogrammer.board.cmake) include(${ZEPHYR_BASE}/boards/common/openocd-stm32.board.cmake) include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) +include(${ZEPHYR_BASE}/boards/common/stlink_gdbserver.board.cmake) diff --git a/boards/st/nucleo_l432kc/board.cmake b/boards/st/nucleo_l432kc/board.cmake index b7b34dd5ac45..864f0b3108a7 100644 --- a/boards/st/nucleo_l432kc/board.cmake +++ b/boards/st/nucleo_l432kc/board.cmake @@ -8,3 +8,4 @@ board_runner_args(jlink "--device=STM32L432KC" "--speed=4000") include(${ZEPHYR_BASE}/boards/common/stm32cubeprogrammer.board.cmake) include(${ZEPHYR_BASE}/boards/common/openocd-stm32.board.cmake) include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) +include(${ZEPHYR_BASE}/boards/common/stlink_gdbserver.board.cmake) diff --git a/boards/st/nucleo_l452re/board.cmake b/boards/st/nucleo_l452re/board.cmake index c5c4870747c1..b5fe10a1c144 100644 --- a/boards/st/nucleo_l452re/board.cmake +++ b/boards/st/nucleo_l452re/board.cmake @@ -8,3 +8,4 @@ board_runner_args(jlink "--device=STM32L452RE" "--speed=4000") include(${ZEPHYR_BASE}/boards/common/stm32cubeprogrammer.board.cmake) include(${ZEPHYR_BASE}/boards/common/openocd-stm32.board.cmake) include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) +include(${ZEPHYR_BASE}/boards/common/stlink_gdbserver.board.cmake) diff --git a/boards/st/nucleo_wl55jc/board.cmake b/boards/st/nucleo_wl55jc/board.cmake index daa77274ae17..659df8023c81 100644 --- a/boards/st/nucleo_wl55jc/board.cmake +++ b/boards/st/nucleo_wl55jc/board.cmake @@ -6,3 +6,4 @@ board_runner_args(stm32cubeprogrammer "--port=swd" "--reset-mode=hw") # keep first include(${ZEPHYR_BASE}/boards/common/stm32cubeprogrammer.board.cmake) include(${ZEPHYR_BASE}/boards/common/openocd-stm32.board.cmake) +include(${ZEPHYR_BASE}/boards/common/stlink_gdbserver.board.cmake) diff --git a/boards/st/stm32f0_disco/board.cmake b/boards/st/stm32f0_disco/board.cmake index 888d731fe97d..e2b7fe576379 100644 --- a/boards/st/stm32f0_disco/board.cmake +++ b/boards/st/stm32f0_disco/board.cmake @@ -8,3 +8,4 @@ board_runner_args(jlink "--device=STM32F051R8" "--speed=4000") include(${ZEPHYR_BASE}/boards/common/stm32cubeprogrammer.board.cmake) include(${ZEPHYR_BASE}/boards/common/openocd-stm32.board.cmake) include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) +include(${ZEPHYR_BASE}/boards/common/stlink_gdbserver.board.cmake) diff --git a/boards/st/stm32f3_disco/board.cmake b/boards/st/stm32f3_disco/board.cmake index b2747a7cc46f..abb6568458fd 100644 --- a/boards/st/stm32f3_disco/board.cmake +++ b/boards/st/stm32f3_disco/board.cmake @@ -8,3 +8,4 @@ board_runner_args(jlink "--device=STM32F303VC" "--speed=4000") include(${ZEPHYR_BASE}/boards/common/stm32cubeprogrammer.board.cmake) include(${ZEPHYR_BASE}/boards/common/openocd-stm32.board.cmake) include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) +include(${ZEPHYR_BASE}/boards/common/stlink_gdbserver.board.cmake) diff --git a/boards/st/stm32f411e_disco/board.cmake b/boards/st/stm32f411e_disco/board.cmake index 64d7eeb27d43..8cbbdd546edf 100644 --- a/boards/st/stm32f411e_disco/board.cmake +++ b/boards/st/stm32f411e_disco/board.cmake @@ -8,3 +8,4 @@ board_runner_args(jlink "--device=STM32F411VE" "--speed=4000") include(${ZEPHYR_BASE}/boards/common/stm32cubeprogrammer.board.cmake) include(${ZEPHYR_BASE}/boards/common/openocd-stm32.board.cmake) include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) +include(${ZEPHYR_BASE}/boards/common/stlink_gdbserver.board.cmake) diff --git a/boards/st/stm32f412g_disco/board.cmake b/boards/st/stm32f412g_disco/board.cmake index 2aa3b0baed3a..491601459458 100644 --- a/boards/st/stm32f412g_disco/board.cmake +++ b/boards/st/stm32f412g_disco/board.cmake @@ -8,3 +8,4 @@ board_runner_args(jlink "--device=STM32F412ZG" "--speed=4000") include(${ZEPHYR_BASE}/boards/common/stm32cubeprogrammer.board.cmake) include(${ZEPHYR_BASE}/boards/common/openocd-stm32.board.cmake) include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) +include(${ZEPHYR_BASE}/boards/common/stlink_gdbserver.board.cmake) diff --git a/boards/st/stm32f429i_disc1/board.cmake b/boards/st/stm32f429i_disc1/board.cmake index 836afa988e33..68addc600f85 100644 --- a/boards/st/stm32f429i_disc1/board.cmake +++ b/boards/st/stm32f429i_disc1/board.cmake @@ -12,3 +12,4 @@ include(${ZEPHYR_BASE}/boards/common/stm32cubeprogrammer.board.cmake) include(${ZEPHYR_BASE}/boards/common/openocd-stm32.board.cmake) include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake) +include(${ZEPHYR_BASE}/boards/common/stlink_gdbserver.board.cmake) diff --git a/boards/st/stm32f4_disco/board.cmake b/boards/st/stm32f4_disco/board.cmake index 3788e6369a8a..9e03314d41b8 100644 --- a/boards/st/stm32f4_disco/board.cmake +++ b/boards/st/stm32f4_disco/board.cmake @@ -8,3 +8,4 @@ board_runner_args(jlink "--device=STM32F407VG" "--speed=4000") include(${ZEPHYR_BASE}/boards/common/stm32cubeprogrammer.board.cmake) include(${ZEPHYR_BASE}/boards/common/openocd-stm32.board.cmake) include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) +include(${ZEPHYR_BASE}/boards/common/stlink_gdbserver.board.cmake) diff --git a/boards/st/stm32f769i_disco/board.cmake b/boards/st/stm32f769i_disco/board.cmake index ba101beac083..e00201744a3f 100644 --- a/boards/st/stm32f769i_disco/board.cmake +++ b/boards/st/stm32f769i_disco/board.cmake @@ -8,3 +8,4 @@ board_runner_args(jlink "--device=STM32F769NI" "--speed=4000") include(${ZEPHYR_BASE}/boards/common/stm32cubeprogrammer.board.cmake) include(${ZEPHYR_BASE}/boards/common/openocd-stm32.board.cmake) include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) +include(${ZEPHYR_BASE}/boards/common/stlink_gdbserver.board.cmake) diff --git a/boards/st/stm32l1_disco/board.cmake b/boards/st/stm32l1_disco/board.cmake index 502c057f7c0f..e85b7f116eb4 100644 --- a/boards/st/stm32l1_disco/board.cmake +++ b/boards/st/stm32l1_disco/board.cmake @@ -8,3 +8,4 @@ board_runner_args(jlink "--device=STM32L151RB" "--speed=4000") include(${ZEPHYR_BASE}/boards/common/stm32cubeprogrammer.board.cmake) include(${ZEPHYR_BASE}/boards/common/openocd-stm32.board.cmake) include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) +include(${ZEPHYR_BASE}/boards/common/stlink_gdbserver.board.cmake) diff --git a/boards/st/stm32l476g_disco/board.cmake b/boards/st/stm32l476g_disco/board.cmake index 8b833a9e8ccb..2b7f9d82783d 100644 --- a/boards/st/stm32l476g_disco/board.cmake +++ b/boards/st/stm32l476g_disco/board.cmake @@ -8,3 +8,4 @@ board_runner_args(jlink "--device=STM32L476VG" "--speed=4000") include(${ZEPHYR_BASE}/boards/common/stm32cubeprogrammer.board.cmake) include(${ZEPHYR_BASE}/boards/common/openocd-stm32.board.cmake) include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) +include(${ZEPHYR_BASE}/boards/common/stlink_gdbserver.board.cmake) From ee02e088aeec757258028bc01ef02639d376267d Mon Sep 17 00:00:00 2001 From: Sylvio Alves Date: Fri, 5 Dec 2025 12:21:17 -0300 Subject: [PATCH 0057/3659] west.yml: hal_espressif: fix ESP32-C3 linker for ECO7 Fix missing linker file when ESP32-C3 SOC_REV_1_1 is used. Signed-off-by: Sylvio Alves --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index e2b326daa9da..0811215b3063 100644 --- a/west.yml +++ b/west.yml @@ -169,7 +169,7 @@ manifest: groups: - hal - name: hal_espressif - revision: 78f88d79bfdca7e84ec7aafb12c0ddd7440bf3d1 + revision: 51544259fc62153df6142279bc55ee8ef40172ac path: modules/hal/espressif west-commands: west/west-commands.yml groups: From f507f0975b44c7d4f5abbfe755116ed8fe6a49d7 Mon Sep 17 00:00:00 2001 From: Mathieu Choplain Date: Fri, 5 Dec 2025 15:32:26 +0100 Subject: [PATCH 0058/3659] dts: arm: st: stm32{f3,f4}: rename CCM memory region for `zephyr,dtcm` Rename the CCM memory region for STM32F3 and STM32F4 series such that the CCM node can be used as a `zephyr,dtcm`. Signed-off-by: Mathieu Choplain --- dts/arm/st/f3/stm32f303X8.dtsi | 2 +- dts/arm/st/f3/stm32f303Xb.dtsi | 2 +- dts/arm/st/f3/stm32f303Xe.dtsi | 2 +- dts/arm/st/f3/stm32f334X8.dtsi | 2 +- dts/arm/st/f4/stm32f405Xg.dtsi | 2 +- dts/arm/st/f4/stm32f407Xe.dtsi | 2 +- dts/arm/st/f4/stm32f407Xg.dtsi | 2 +- dts/arm/st/f4/stm32f415Rg.dtsi | 2 +- dts/arm/st/f4/stm32f417Xe.dtsi | 2 +- dts/arm/st/f4/stm32f417Xg.dtsi | 2 +- dts/arm/st/f4/stm32f427Xi.dtsi | 2 +- dts/arm/st/f4/stm32f427vi.dtsi | 2 +- dts/arm/st/f4/stm32f429Xi.dtsi | 2 +- dts/arm/st/f4/stm32f429vi.dtsi | 2 +- dts/arm/st/f4/stm32f437Xi.dtsi | 2 +- dts/arm/st/f4/stm32f439Xi.dtsi | 2 +- dts/arm/st/f4/stm32f439vi.dtsi | 2 +- dts/arm/st/f4/stm32f469Xi.dtsi | 2 +- dts/arm/st/f4/stm32f479Xi.dtsi | 2 +- 19 files changed, 19 insertions(+), 19 deletions(-) diff --git a/dts/arm/st/f3/stm32f303X8.dtsi b/dts/arm/st/f3/stm32f303X8.dtsi index 3395b9470a03..2d2280add2ef 100644 --- a/dts/arm/st/f3/stm32f303X8.dtsi +++ b/dts/arm/st/f3/stm32f303X8.dtsi @@ -10,7 +10,7 @@ ccm0: memory@10000000 { compatible = "zephyr,memory-region", "st,stm32-ccm"; reg = <0x10000000 DT_SIZE_K(8)>; - zephyr,memory-region = "CCM"; + zephyr,memory-region = "DTCM"; }; sram0: memory@20000000 { diff --git a/dts/arm/st/f3/stm32f303Xb.dtsi b/dts/arm/st/f3/stm32f303Xb.dtsi index 87d93bff213c..439dab0a378a 100644 --- a/dts/arm/st/f3/stm32f303Xb.dtsi +++ b/dts/arm/st/f3/stm32f303Xb.dtsi @@ -11,7 +11,7 @@ ccm0: memory@10000000 { compatible = "zephyr,memory-region", "st,stm32-ccm"; reg = <0x10000000 DT_SIZE_K(8)>; - zephyr,memory-region = "CCM"; + zephyr,memory-region = "DTCM"; }; sram0: memory@20000000 { diff --git a/dts/arm/st/f3/stm32f303Xe.dtsi b/dts/arm/st/f3/stm32f303Xe.dtsi index be958e5dc775..07df23c933c8 100644 --- a/dts/arm/st/f3/stm32f303Xe.dtsi +++ b/dts/arm/st/f3/stm32f303Xe.dtsi @@ -11,7 +11,7 @@ ccm0: memory@10000000 { compatible = "zephyr,memory-region", "st,stm32-ccm"; reg = <0x10000000 DT_SIZE_K(16)>; - zephyr,memory-region = "CCM"; + zephyr,memory-region = "DTCM"; }; sram0: memory@20000000 { diff --git a/dts/arm/st/f3/stm32f334X8.dtsi b/dts/arm/st/f3/stm32f334X8.dtsi index 827d6e0504d5..5f0235da0102 100644 --- a/dts/arm/st/f3/stm32f334X8.dtsi +++ b/dts/arm/st/f3/stm32f334X8.dtsi @@ -10,7 +10,7 @@ ccm0: memory@10000000 { compatible = "zephyr,memory-region", "st,stm32-ccm"; reg = <0x10000000 DT_SIZE_K(4)>; - zephyr,memory-region = "CCM"; + zephyr,memory-region = "DTCM"; }; sram0: memory@20000000 { diff --git a/dts/arm/st/f4/stm32f405Xg.dtsi b/dts/arm/st/f4/stm32f405Xg.dtsi index 368640e2752d..648e0ef92f9b 100644 --- a/dts/arm/st/f4/stm32f405Xg.dtsi +++ b/dts/arm/st/f4/stm32f405Xg.dtsi @@ -10,7 +10,7 @@ ccm0: memory@10000000 { compatible = "zephyr,memory-region", "st,stm32-ccm"; reg = <0x10000000 DT_SIZE_K(64)>; - zephyr,memory-region = "CCM"; + zephyr,memory-region = "DTCM"; }; sram0: memory@20000000 { diff --git a/dts/arm/st/f4/stm32f407Xe.dtsi b/dts/arm/st/f4/stm32f407Xe.dtsi index 95f4e8ced6c5..42b869b088a7 100644 --- a/dts/arm/st/f4/stm32f407Xe.dtsi +++ b/dts/arm/st/f4/stm32f407Xe.dtsi @@ -10,7 +10,7 @@ ccm0: memory@10000000 { compatible = "zephyr,memory-region", "st,stm32-ccm"; reg = <0x10000000 DT_SIZE_K(64)>; - zephyr,memory-region = "CCM"; + zephyr,memory-region = "DTCM"; }; sram0: memory@20000000 { diff --git a/dts/arm/st/f4/stm32f407Xg.dtsi b/dts/arm/st/f4/stm32f407Xg.dtsi index 1e5005ff0859..b89535c97b7f 100644 --- a/dts/arm/st/f4/stm32f407Xg.dtsi +++ b/dts/arm/st/f4/stm32f407Xg.dtsi @@ -10,7 +10,7 @@ ccm0: memory@10000000 { compatible = "zephyr,memory-region", "st,stm32-ccm"; reg = <0x10000000 DT_SIZE_K(64)>; - zephyr,memory-region = "CCM"; + zephyr,memory-region = "DTCM"; }; sram0: memory@20000000 { diff --git a/dts/arm/st/f4/stm32f415Rg.dtsi b/dts/arm/st/f4/stm32f415Rg.dtsi index 4f430d88037a..8cbabe880764 100644 --- a/dts/arm/st/f4/stm32f415Rg.dtsi +++ b/dts/arm/st/f4/stm32f415Rg.dtsi @@ -10,7 +10,7 @@ ccm0: memory@10000000 { compatible = "zephyr,memory-region", "st,stm32-ccm"; reg = <0x10000000 DT_SIZE_K(64)>; - zephyr,memory-region = "CCM"; + zephyr,memory-region = "DTCM"; }; sram0: memory@20000000 { diff --git a/dts/arm/st/f4/stm32f417Xe.dtsi b/dts/arm/st/f4/stm32f417Xe.dtsi index aab4fc20deaf..8bbe00babdce 100644 --- a/dts/arm/st/f4/stm32f417Xe.dtsi +++ b/dts/arm/st/f4/stm32f417Xe.dtsi @@ -10,7 +10,7 @@ ccm0: memory@10000000 { compatible = "zephyr,memory-region", "st,stm32-ccm"; reg = <0x10000000 DT_SIZE_K(64)>; - zephyr,memory-region = "CCM"; + zephyr,memory-region = "DTCM"; }; sram0: memory@20000000 { diff --git a/dts/arm/st/f4/stm32f417Xg.dtsi b/dts/arm/st/f4/stm32f417Xg.dtsi index c272f7b235f4..a8f613b069a7 100644 --- a/dts/arm/st/f4/stm32f417Xg.dtsi +++ b/dts/arm/st/f4/stm32f417Xg.dtsi @@ -10,7 +10,7 @@ ccm0: memory@10000000 { compatible = "zephyr,memory-region", "st,stm32-ccm"; reg = <0x10000000 DT_SIZE_K(64)>; - zephyr,memory-region = "CCM"; + zephyr,memory-region = "DTCM"; }; sram0: memory@20000000 { diff --git a/dts/arm/st/f4/stm32f427Xi.dtsi b/dts/arm/st/f4/stm32f427Xi.dtsi index fd5264e8fd41..0ced6ff40047 100644 --- a/dts/arm/st/f4/stm32f427Xi.dtsi +++ b/dts/arm/st/f4/stm32f427Xi.dtsi @@ -10,7 +10,7 @@ ccm0: memory@10000000 { compatible = "zephyr,memory-region", "st,stm32-ccm"; reg = <0x10000000 DT_SIZE_K(64)>; - zephyr,memory-region = "CCM"; + zephyr,memory-region = "DTCM"; }; sram0: memory@20000000 { diff --git a/dts/arm/st/f4/stm32f427vi.dtsi b/dts/arm/st/f4/stm32f427vi.dtsi index 2355bc1603b9..f20bfed0cba3 100644 --- a/dts/arm/st/f4/stm32f427vi.dtsi +++ b/dts/arm/st/f4/stm32f427vi.dtsi @@ -10,7 +10,7 @@ ccm0: memory@10000000 { compatible = "zephyr,memory-region", "st,stm32-ccm"; reg = <0x10000000 DT_SIZE_K(64)>; - zephyr,memory-region = "CCM"; + zephyr,memory-region = "DTCM"; }; sram0: memory@20000000 { diff --git a/dts/arm/st/f4/stm32f429Xi.dtsi b/dts/arm/st/f4/stm32f429Xi.dtsi index eee3f6d04c9c..2a0a58f43f71 100644 --- a/dts/arm/st/f4/stm32f429Xi.dtsi +++ b/dts/arm/st/f4/stm32f429Xi.dtsi @@ -10,7 +10,7 @@ ccm0: memory@10000000 { compatible = "zephyr,memory-region", "st,stm32-ccm"; reg = <0x10000000 DT_SIZE_K(64)>; - zephyr,memory-region = "CCM"; + zephyr,memory-region = "DTCM"; }; sram0: memory@20000000 { diff --git a/dts/arm/st/f4/stm32f429vi.dtsi b/dts/arm/st/f4/stm32f429vi.dtsi index 3acbf5e0c983..bbe3854b1f98 100644 --- a/dts/arm/st/f4/stm32f429vi.dtsi +++ b/dts/arm/st/f4/stm32f429vi.dtsi @@ -10,7 +10,7 @@ ccm0: memory@10000000 { compatible = "zephyr,memory-region", "st,stm32-ccm"; reg = <0x10000000 DT_SIZE_K(64)>; - zephyr,memory-region = "CCM"; + zephyr,memory-region = "DTCM"; }; sram0: memory@20000000 { diff --git a/dts/arm/st/f4/stm32f437Xi.dtsi b/dts/arm/st/f4/stm32f437Xi.dtsi index c64a2e90fa64..06d0bc7b66bb 100644 --- a/dts/arm/st/f4/stm32f437Xi.dtsi +++ b/dts/arm/st/f4/stm32f437Xi.dtsi @@ -10,7 +10,7 @@ ccm0: memory@10000000 { compatible = "zephyr,memory-region", "st,stm32-ccm"; reg = <0x10000000 DT_SIZE_K(64)>; - zephyr,memory-region = "CCM"; + zephyr,memory-region = "DTCM"; }; sram0: memory@20000000 { diff --git a/dts/arm/st/f4/stm32f439Xi.dtsi b/dts/arm/st/f4/stm32f439Xi.dtsi index 1dc2f756c758..af3845b0b3e8 100644 --- a/dts/arm/st/f4/stm32f439Xi.dtsi +++ b/dts/arm/st/f4/stm32f439Xi.dtsi @@ -10,7 +10,7 @@ ccm0: memory@10000000 { compatible = "zephyr,memory-region", "st,stm32-ccm"; reg = <0x10000000 DT_SIZE_K(64)>; - zephyr,memory-region = "CCM"; + zephyr,memory-region = "DTCM"; }; sram0: memory@20000000 { diff --git a/dts/arm/st/f4/stm32f439vi.dtsi b/dts/arm/st/f4/stm32f439vi.dtsi index 3c5bd4c99fcf..829cc8bac152 100644 --- a/dts/arm/st/f4/stm32f439vi.dtsi +++ b/dts/arm/st/f4/stm32f439vi.dtsi @@ -10,7 +10,7 @@ ccm0: memory@10000000 { compatible = "zephyr,memory-region", "st,stm32-ccm"; reg = <0x10000000 DT_SIZE_K(64)>; - zephyr,memory-region = "CCM"; + zephyr,memory-region = "DTCM"; }; sram0: memory@20000000 { diff --git a/dts/arm/st/f4/stm32f469Xi.dtsi b/dts/arm/st/f4/stm32f469Xi.dtsi index 3172e37e776e..8d4ea54ff65c 100644 --- a/dts/arm/st/f4/stm32f469Xi.dtsi +++ b/dts/arm/st/f4/stm32f469Xi.dtsi @@ -10,7 +10,7 @@ ccm0: memory@10000000 { compatible = "zephyr,memory-region", "st,stm32-ccm"; reg = <0x10000000 DT_SIZE_K(64)>; - zephyr,memory-region = "CCM"; + zephyr,memory-region = "DTCM"; }; sram0: memory@20000000 { diff --git a/dts/arm/st/f4/stm32f479Xi.dtsi b/dts/arm/st/f4/stm32f479Xi.dtsi index 4f7db423c8c2..3fa2853b1260 100644 --- a/dts/arm/st/f4/stm32f479Xi.dtsi +++ b/dts/arm/st/f4/stm32f479Xi.dtsi @@ -10,7 +10,7 @@ ccm0: memory@10000000 { compatible = "zephyr,memory-region", "st,stm32-ccm"; reg = <0x10000000 DT_SIZE_K(64)>; - zephyr,memory-region = "CCM"; + zephyr,memory-region = "DTCM"; }; sram0: memory@20000000 { From 2d4feea8cea7c93d0b16b9544110ad0adc90e350 Mon Sep 17 00:00:00 2001 From: Mathieu Choplain Date: Fri, 5 Dec 2025 15:34:54 +0100 Subject: [PATCH 0059/3659] boards: (STM32F4 based): replace `zephyr,ccm` chosen with `zephyr,dtcm` The STM32 CCM can be used as `/chosen/zephyr,dtcm` - transition all boards to this chosen to allow deprecation/removal of the legacy `zephyr,ccm`. Signed-off-by: Mathieu Choplain --- boards/96boards/aerocore2/96b_aerocore2.dts | 2 +- .../adafruit/feather_stm32f405/adafruit_feather_stm32f405.dts | 2 +- boards/adi/sdp_k1/adi_sdp_k1.dts | 2 +- boards/iar/stm32f429ii_aca/stm32f429ii_aca.dts | 2 +- boards/mikroe/clicker_2/mikroe_clicker_2.dts | 2 +- boards/mikroe/mini_m4_for_stm32/mikroe_mini_m4_for_stm32.dts | 2 +- boards/mikroe/quail/mikroe_quail.dts | 2 +- boards/olimex/stm32_e407/olimex_stm32_e407.dts | 2 +- boards/olimex/stm32_h405/olimex_stm32_h405.dts | 2 +- boards/olimex/stm32_h407/olimex_stm32_h407.dts | 2 +- boards/olimex/stm32_p405/olimex_stm32_p405.dts | 2 +- boards/others/black_f407ve/black_f407ve.dts | 2 +- boards/others/black_f407zg_pro/black_f407zg_pro.dts | 2 +- boards/segger/trb_stm32f407/segger_trb_stm32f407.dts | 2 +- boards/st/nucleo_f429zi/nucleo_f429zi.dts | 2 +- boards/st/nucleo_f439zi/nucleo_f439zi.dts | 2 +- boards/st/stm32f429i_disc1/stm32f429i_disc1.dts | 2 +- boards/st/stm32f469i_disco/stm32f469i_disco.dts | 2 +- boards/st/stm32f4_disco/stm32f4_disco.dts | 2 +- boards/weact/stm32f405_core/weact_stm32f405_core.dts | 2 +- 20 files changed, 20 insertions(+), 20 deletions(-) diff --git a/boards/96boards/aerocore2/96b_aerocore2.dts b/boards/96boards/aerocore2/96b_aerocore2.dts index 339f61df6e03..225e99c0f8cc 100644 --- a/boards/96boards/aerocore2/96b_aerocore2.dts +++ b/boards/96boards/aerocore2/96b_aerocore2.dts @@ -18,7 +18,7 @@ zephyr,shell-uart = &uart7; zephyr,sram = &sram0; zephyr,flash = &flash0; - zephyr,ccm = &ccm0; + zephyr,dtcm = &ccm0; }; leds { diff --git a/boards/adafruit/feather_stm32f405/adafruit_feather_stm32f405.dts b/boards/adafruit/feather_stm32f405/adafruit_feather_stm32f405.dts index afa61648790a..bc53c5a583e5 100644 --- a/boards/adafruit/feather_stm32f405/adafruit_feather_stm32f405.dts +++ b/boards/adafruit/feather_stm32f405/adafruit_feather_stm32f405.dts @@ -18,7 +18,7 @@ zephyr,shell-uart = &usart3; zephyr,sram = &sram0; zephyr,flash = &flash0; - zephyr,ccm = &ccm0; + zephyr,dtcm = &ccm0; }; leds { diff --git a/boards/adi/sdp_k1/adi_sdp_k1.dts b/boards/adi/sdp_k1/adi_sdp_k1.dts index de7d9836bf55..7fc3e01b2f19 100644 --- a/boards/adi/sdp_k1/adi_sdp_k1.dts +++ b/boards/adi/sdp_k1/adi_sdp_k1.dts @@ -19,7 +19,7 @@ zephyr,shell-uart = &uart5; zephyr,sram = &sram0; zephyr,flash = &flash0; - zephyr,ccm = &ccm0; + zephyr,dtcm = &ccm0; }; leds { diff --git a/boards/iar/stm32f429ii_aca/stm32f429ii_aca.dts b/boards/iar/stm32f429ii_aca/stm32f429ii_aca.dts index 2ef4de73bf06..4df791a7319e 100644 --- a/boards/iar/stm32f429ii_aca/stm32f429ii_aca.dts +++ b/boards/iar/stm32f429ii_aca/stm32f429ii_aca.dts @@ -18,7 +18,7 @@ chosen { zephyr,sram = &sram0; zephyr,flash = &flash0; - zephyr,ccm = &ccm0; + zephyr,dtcm = &ccm0; }; sdram2: sdram@d0000000 { diff --git a/boards/mikroe/clicker_2/mikroe_clicker_2.dts b/boards/mikroe/clicker_2/mikroe_clicker_2.dts index fd088435d83a..4022b279a358 100644 --- a/boards/mikroe/clicker_2/mikroe_clicker_2.dts +++ b/boards/mikroe/clicker_2/mikroe_clicker_2.dts @@ -18,7 +18,7 @@ zephyr,shell-uart = &uart4; zephyr,sram = &sram0; zephyr,flash = &flash0; - zephyr,ccm = &ccm0; + zephyr,dtcm = &ccm0; }; leds { diff --git a/boards/mikroe/mini_m4_for_stm32/mikroe_mini_m4_for_stm32.dts b/boards/mikroe/mini_m4_for_stm32/mikroe_mini_m4_for_stm32.dts index c4fcefacb5b4..6b57785a196d 100644 --- a/boards/mikroe/mini_m4_for_stm32/mikroe_mini_m4_for_stm32.dts +++ b/boards/mikroe/mini_m4_for_stm32/mikroe_mini_m4_for_stm32.dts @@ -17,7 +17,7 @@ zephyr,shell-uart = &usart2; zephyr,sram = &sram0; zephyr,flash = &flash0; - zephyr,ccm = &ccm0; + zephyr,dtcm = &ccm0; }; leds { diff --git a/boards/mikroe/quail/mikroe_quail.dts b/boards/mikroe/quail/mikroe_quail.dts index 2064b9be0777..3b22131acd5c 100644 --- a/boards/mikroe/quail/mikroe_quail.dts +++ b/boards/mikroe/quail/mikroe_quail.dts @@ -17,7 +17,7 @@ zephyr,sram = &sram0; zephyr,flash = &flash0; zephyr,flash-controller = &flash1; - zephyr,ccm = &ccm0; + zephyr,dtcm = &ccm0; }; leds { diff --git a/boards/olimex/stm32_e407/olimex_stm32_e407.dts b/boards/olimex/stm32_e407/olimex_stm32_e407.dts index 6bcf16b54faa..3887d4af347f 100644 --- a/boards/olimex/stm32_e407/olimex_stm32_e407.dts +++ b/boards/olimex/stm32_e407/olimex_stm32_e407.dts @@ -18,7 +18,7 @@ zephyr,shell-uart = &usart1; zephyr,sram = &sram0; zephyr,flash = &flash0; - zephyr,ccm = &ccm0; + zephyr,dtcm = &ccm0; }; leds { diff --git a/boards/olimex/stm32_h405/olimex_stm32_h405.dts b/boards/olimex/stm32_h405/olimex_stm32_h405.dts index bdb5e1b588fd..95a4a82defd1 100644 --- a/boards/olimex/stm32_h405/olimex_stm32_h405.dts +++ b/boards/olimex/stm32_h405/olimex_stm32_h405.dts @@ -18,7 +18,7 @@ zephyr,shell-uart = &usart2; zephyr,sram = &sram0; zephyr,flash = &flash0; - zephyr,ccm = &ccm0; + zephyr,dtcm = &ccm0; }; leds { diff --git a/boards/olimex/stm32_h407/olimex_stm32_h407.dts b/boards/olimex/stm32_h407/olimex_stm32_h407.dts index dc2ea9a3c71f..78c5fef78761 100644 --- a/boards/olimex/stm32_h407/olimex_stm32_h407.dts +++ b/boards/olimex/stm32_h407/olimex_stm32_h407.dts @@ -18,7 +18,7 @@ zephyr,shell-uart = &usart2; zephyr,sram = &sram0; zephyr,flash = &flash0; - zephyr,ccm = &ccm0; + zephyr,dtcm = &ccm0; }; leds { diff --git a/boards/olimex/stm32_p405/olimex_stm32_p405.dts b/boards/olimex/stm32_p405/olimex_stm32_p405.dts index 6257a0ee97dc..e69c347f83a3 100644 --- a/boards/olimex/stm32_p405/olimex_stm32_p405.dts +++ b/boards/olimex/stm32_p405/olimex_stm32_p405.dts @@ -18,7 +18,7 @@ zephyr,shell-uart = &usart2; zephyr,sram = &sram0; zephyr,flash = &flash0; - zephyr,ccm = &ccm0; + zephyr,dtcm = &ccm0; zephyr,canbus = &can1; }; diff --git a/boards/others/black_f407ve/black_f407ve.dts b/boards/others/black_f407ve/black_f407ve.dts index 1026096069d0..83e843cde303 100644 --- a/boards/others/black_f407ve/black_f407ve.dts +++ b/boards/others/black_f407ve/black_f407ve.dts @@ -18,7 +18,7 @@ zephyr,shell-uart = &usart1; zephyr,sram = &sram0; zephyr,flash = &flash0; - zephyr,ccm = &ccm0; + zephyr,dtcm = &ccm0; zephyr,canbus = &can2; }; diff --git a/boards/others/black_f407zg_pro/black_f407zg_pro.dts b/boards/others/black_f407zg_pro/black_f407zg_pro.dts index 0673d17c38de..9d224a47e35e 100644 --- a/boards/others/black_f407zg_pro/black_f407zg_pro.dts +++ b/boards/others/black_f407zg_pro/black_f407zg_pro.dts @@ -18,7 +18,7 @@ zephyr,shell-uart = &usart2; zephyr,sram = &sram0; zephyr,flash = &flash0; - zephyr,ccm = &ccm0; + zephyr,dtcm = &ccm0; zephyr,canbus = &can2; }; diff --git a/boards/segger/trb_stm32f407/segger_trb_stm32f407.dts b/boards/segger/trb_stm32f407/segger_trb_stm32f407.dts index 505a154f44f1..6779c3f868ba 100644 --- a/boards/segger/trb_stm32f407/segger_trb_stm32f407.dts +++ b/boards/segger/trb_stm32f407/segger_trb_stm32f407.dts @@ -14,7 +14,7 @@ chosen { zephyr,sram = &sram0; zephyr,flash = &flash0; - zephyr,ccm = &ccm0; + zephyr,dtcm = &ccm0; }; aliases { diff --git a/boards/st/nucleo_f429zi/nucleo_f429zi.dts b/boards/st/nucleo_f429zi/nucleo_f429zi.dts index 21fbb2cbde39..c3ec146f1344 100644 --- a/boards/st/nucleo_f429zi/nucleo_f429zi.dts +++ b/boards/st/nucleo_f429zi/nucleo_f429zi.dts @@ -19,7 +19,7 @@ zephyr,shell-uart = &usart3; zephyr,sram = &sram0; zephyr,flash = &flash0; - zephyr,ccm = &ccm0; + zephyr,dtcm = &ccm0; zephyr,code-partition = &slot0_partition; }; diff --git a/boards/st/nucleo_f439zi/nucleo_f439zi.dts b/boards/st/nucleo_f439zi/nucleo_f439zi.dts index 9cd4c9b6ada7..74bf2706e4eb 100644 --- a/boards/st/nucleo_f439zi/nucleo_f439zi.dts +++ b/boards/st/nucleo_f439zi/nucleo_f439zi.dts @@ -19,7 +19,7 @@ zephyr,shell-uart = &usart3; zephyr,sram = &sram0; zephyr,flash = &flash0; - zephyr,ccm = &ccm0; + zephyr,dtcm = &ccm0; zephyr,code-partition = &slot0_partition; }; diff --git a/boards/st/stm32f429i_disc1/stm32f429i_disc1.dts b/boards/st/stm32f429i_disc1/stm32f429i_disc1.dts index e1b2b01f196e..79596438f7fa 100644 --- a/boards/st/stm32f429i_disc1/stm32f429i_disc1.dts +++ b/boards/st/stm32f429i_disc1/stm32f429i_disc1.dts @@ -20,7 +20,7 @@ zephyr,shell-uart = &usart1; zephyr,sram = &sram0; zephyr,flash = &flash0; - zephyr,ccm = &ccm0; + zephyr,dtcm = &ccm0; zephyr,display = <dc; zephyr,touch = &stmpe811; }; diff --git a/boards/st/stm32f469i_disco/stm32f469i_disco.dts b/boards/st/stm32f469i_disco/stm32f469i_disco.dts index b13221f1c06f..17022e34ecd2 100644 --- a/boards/st/stm32f469i_disco/stm32f469i_disco.dts +++ b/boards/st/stm32f469i_disco/stm32f469i_disco.dts @@ -19,7 +19,7 @@ zephyr,shell-uart = &usart3; zephyr,sram = &sram0; zephyr,flash = &flash0; - zephyr,ccm = &ccm0; + zephyr,dtcm = &ccm0; zephyr,display = <dc; zephyr,touch = &ft5336; }; diff --git a/boards/st/stm32f4_disco/stm32f4_disco.dts b/boards/st/stm32f4_disco/stm32f4_disco.dts index 88890a93b34f..67b58aef8628 100644 --- a/boards/st/stm32f4_disco/stm32f4_disco.dts +++ b/boards/st/stm32f4_disco/stm32f4_disco.dts @@ -18,7 +18,7 @@ zephyr,shell-uart = &usart2; zephyr,sram = &sram0; zephyr,flash = &flash0; - zephyr,ccm = &ccm0; + zephyr,dtcm = &ccm0; zephyr,canbus = &can2; }; diff --git a/boards/weact/stm32f405_core/weact_stm32f405_core.dts b/boards/weact/stm32f405_core/weact_stm32f405_core.dts index cc2d19063bda..0cc4a990e6fc 100644 --- a/boards/weact/stm32f405_core/weact_stm32f405_core.dts +++ b/boards/weact/stm32f405_core/weact_stm32f405_core.dts @@ -18,7 +18,7 @@ zephyr,shell-uart = &usart1; zephyr,sram = &sram0; zephyr,flash = &flash0; - zephyr,ccm = &ccm0; + zephyr,dtcm = &ccm0; }; leds { From f7d75fc991f6f8e71b57e839f5953f02ecc918d4 Mon Sep 17 00:00:00 2001 From: Mathieu Choplain Date: Fri, 5 Dec 2025 15:46:14 +0100 Subject: [PATCH 0060/3659] samples: board: st: ccm: update sample for `zephyr,dtcm` usage Update the ST CCM usage sample to be compatible with CCM as `zephyr,dtcm`. Signed-off-by: Mathieu Choplain --- samples/boards/st/ccm/README.rst | 20 +++++++++++--------- samples/boards/st/ccm/src/main.c | 22 +++++++++++----------- 2 files changed, 22 insertions(+), 20 deletions(-) diff --git a/samples/boards/st/ccm/README.rst b/samples/boards/st/ccm/README.rst index 6b49ce522536..9cab3b43e8eb 100644 --- a/samples/boards/st/ccm/README.rst +++ b/samples/boards/st/ccm/README.rst @@ -10,18 +10,20 @@ Show usage of the Core Coupled Memory (CCM) that is available on several STM32 devices. The very important difference with normal RAM is that CCM can not be used for DMA. -By prefixing a variable with __ccm_data_section, __ccm_bss_section, -or __ccm_noinit_section those variables are placed in the CCM. +In this sample, the CCM is used to store data (i.e., as a DTCM). +By prefixing a variable with ``__dtcm_data_section``, +``__dtcm_bss_section`` or ``__dtcm_noinit_section``, +those variables are placed in the CCM. -The __ccm_data_section prefix should be used for variables that -are initialized. Like the normal data section the initial +The ``__dtcm_data_section`` prefix should be used for variables +that are initialized. Like the normal data section the initial values take up space in the FLASH image. -The __ccm_bss_section prefix should be used for variables that -should be initialized to 0. Like the normal bss section they -do not take up FLASH space. +The ``__dtcm_bss_section`` prefix should be used for variables +that should be initialized to 0. Like the normal bss section +they do not take up FLASH space. -The __ccm_noinit_section prefix should be used for variables +The ``__dtcm_noinit_section`` prefix should be used for variables that don't need to have a defined initial value (for example buffers that will receive data). Compared to bss or data the kernel does not need to initialize the noinit section making @@ -32,7 +34,7 @@ board's DTS file ``chosen`` section: .. code-block:: console - zephyr,ccm = &ccm0; + zephyr,dtcm = &ccm0; For example the olimex STM32 E407 DTS file looks like this: diff --git a/samples/boards/st/ccm/src/main.c b/samples/boards/st/ccm/src/main.c index 36630d02858b..fb70332bee99 100644 --- a/samples/boards/st/ccm/src/main.c +++ b/samples/boards/st/ccm/src/main.c @@ -21,19 +21,19 @@ #define CCM_DATA_ARRAY_VAL(i) (((i)+1)*0x11) -uint8_t __ccm_data_section ccm_data_var_8 = CCM_DATA_VAR_8_VAL; -uint16_t __ccm_data_section ccm_data_var_16 = CCM_DATA_VAR_16_VAL; -uint32_t __ccm_data_section ccm_data_var_32 = CCM_DATA_VAR_32_VAL; +uint8_t __dtcm_data_section ccm_data_var_8 = CCM_DATA_VAR_8_VAL; +uint16_t __dtcm_data_section ccm_data_var_16 = CCM_DATA_VAR_16_VAL; +uint32_t __dtcm_data_section ccm_data_var_32 = CCM_DATA_VAR_32_VAL; -uint8_t __ccm_data_section ccm_data_array[CCM_DATA_ARRAY_SIZE] = { +uint8_t __dtcm_data_section ccm_data_array[CCM_DATA_ARRAY_SIZE] = { CCM_DATA_ARRAY_VAL(0), CCM_DATA_ARRAY_VAL(1), CCM_DATA_ARRAY_VAL(2), CCM_DATA_ARRAY_VAL(3), CCM_DATA_ARRAY_VAL(4), }; -uint8_t __ccm_bss_section ccm_bss_array[CCM_BSS_ARRAY_SIZE]; -uint8_t __ccm_noinit_section ccm_noinit_array[CCM_NOINIT_ARRAY_SIZE]; +uint8_t __dtcm_bss_section ccm_bss_array[CCM_BSS_ARRAY_SIZE]; +uint8_t __dtcm_noinit_section ccm_noinit_array[CCM_NOINIT_ARRAY_SIZE]; void print_array(const void *array, uint32_t size) { @@ -117,15 +117,15 @@ int main(void) printf("\nCCM (Core Coupled Memory) usage example\n\n"); printf("The total used CCM area : [%p, %p)\n", - &__ccm_start, &__ccm_end); + &__dtcm_start, &__dtcm_end); printf("Zero initialized BSS area : [%p, %p)\n", - &__ccm_bss_start, &__ccm_bss_end); + &__dtcm_bss_start, &__dtcm_bss_end); printf("Uninitialized NOINIT area : [%p, %p)\n", - &__ccm_noinit_start, &__ccm_noinit_end); + &__dtcm_noinit_start, &__dtcm_noinit_end); printf("Initialised DATA area : [%p, %p)\n", - &__ccm_data_start, &__ccm_data_end); + &__dtcm_data_start, &__dtcm_data_end); printf("Start of DATA in FLASH : %p\n", - &__ccm_data_load_start); + &__dtcm_data_load_start); check_initial_var_values(); From dc5e85a8d0e391f3991f53a6ff10987986570bd1 Mon Sep 17 00:00:00 2001 From: Mathieu Choplain Date: Fri, 5 Dec 2025 15:50:25 +0100 Subject: [PATCH 0061/3659] kernel/arch: remove `zephyr,ccm` initialization code doc: dts: api: remove documentation of chosen `zephyr,ccm` The `zephyr,ccm` chosen was an ST-specific property which has been replaced by the generic `zephyr,dtcm`. Remove region initialization code from the common arch init code (+ BSS zeroing from common XIP init code). Signed-off-by: Mathieu Choplain --- arch/common/init.c | 5 ----- arch/common/xip.c | 4 ---- 2 files changed, 9 deletions(-) diff --git a/arch/common/init.c b/arch/common/init.c index b5e83a0b8dc1..802c21464a93 100644 --- a/arch/common/init.c +++ b/arch/common/init.c @@ -55,11 +55,6 @@ void arch_bss_zero(void) } arch_early_memset(__bss_start, 0, __bss_end - __bss_start); -#if DT_NODE_HAS_STATUS_OKAY(DT_CHOSEN(zephyr_ccm)) - arch_early_memset(&__ccm_bss_start, 0, - (uintptr_t) &__ccm_bss_end - - (uintptr_t) &__ccm_bss_start); -#endif #if DT_NODE_HAS_STATUS_OKAY(DT_CHOSEN(zephyr_dtcm)) arch_early_memset(&__dtcm_bss_start, 0, (uintptr_t) &__dtcm_bss_end diff --git a/arch/common/xip.c b/arch/common/xip.c index 234d323118b5..10b8fda1d336 100644 --- a/arch/common/xip.c +++ b/arch/common/xip.c @@ -38,10 +38,6 @@ void arch_data_copy(void) (uintptr_t) &_nocache_load_ram_size); #endif /* CONFIG_NOCACHE_MEMORY */ #endif /* CONFIG_ARCH_HAS_NOCACHE_MEMORY_SUPPORT */ -#if DT_NODE_HAS_STATUS_OKAY(DT_CHOSEN(zephyr_ccm)) - arch_early_memcpy(&__ccm_data_start, &__ccm_data_load_start, - __ccm_data_end - __ccm_data_start); -#endif #if DT_NODE_HAS_STATUS_OKAY(DT_CHOSEN(zephyr_itcm)) arch_early_memcpy(&__itcm_start, &__itcm_load_start, (uintptr_t) &__itcm_size); From 63081242b99bff28436cd5464215ef65851bfbbc Mon Sep 17 00:00:00 2001 From: Mathieu Choplain Date: Fri, 5 Dec 2025 15:39:27 +0100 Subject: [PATCH 0062/3659] linker: remove STM32 CCM sections Remove section names and symbols relating to the STM32 CCM region, `/chosen/zephyr,ccm`, which is replaced by the standard DTCM region `/chosen/zephyr,dtcm`. For backwards compatibility, the old `__ccm_<...>_section` attribute macros are aliased to `__dtcm_<...>_section` (until release 4.5). Signed-off-by: Mathieu Choplain --- include/zephyr/linker/linker-defs.h | 12 ------------ include/zephyr/linker/section_tags.h | 11 ++++++++--- include/zephyr/linker/sections.h | 4 ---- 3 files changed, 8 insertions(+), 19 deletions(-) diff --git a/include/zephyr/linker/linker-defs.h b/include/zephyr/linker/linker-defs.h index 635b418897c8..2d4efeebe69f 100644 --- a/include/zephyr/linker/linker-defs.h +++ b/include/zephyr/linker/linker-defs.h @@ -191,18 +191,6 @@ extern char __gcov_bss_size[]; /* end address of image, used by newlib for the heap */ extern char _end[]; -#if (DT_NODE_HAS_STATUS_OKAY(DT_CHOSEN(zephyr_ccm))) -extern char __ccm_data_load_start[]; -extern char __ccm_start[]; -extern char __ccm_data_start[]; -extern char __ccm_data_end[]; -extern char __ccm_bss_start[]; -extern char __ccm_bss_end[]; -extern char __ccm_noinit_start[]; -extern char __ccm_noinit_end[]; -extern char __ccm_end[]; -#endif - #if (DT_NODE_HAS_STATUS_OKAY(DT_CHOSEN(zephyr_itcm))) extern char __itcm_start[]; extern char __itcm_end[]; diff --git a/include/zephyr/linker/section_tags.h b/include/zephyr/linker/section_tags.h index 5b51f0421c90..14bc9f573806 100644 --- a/include/zephyr/linker/section_tags.h +++ b/include/zephyr/linker/section_tags.h @@ -31,9 +31,6 @@ #if defined(CONFIG_ARM) #define __kinetis_flash_config_section __in_section_unique(_KINETIS_FLASH_CONFIG_SECTION_NAME) #define __ti_ccfg_section Z_GENERIC_SECTION(_TI_CCFG_SECTION_NAME) -#define __ccm_data_section Z_GENERIC_SECTION(_CCM_DATA_SECTION_NAME) -#define __ccm_bss_section Z_GENERIC_SECTION(_CCM_BSS_SECTION_NAME) -#define __ccm_noinit_section Z_GENERIC_SECTION(_CCM_NOINIT_SECTION_NAME) #define __itcm_section Z_GENERIC_SECTION(_ITCM_SECTION_NAME) #define __dtcm_data_section Z_GENERIC_SECTION(_DTCM_DATA_SECTION_NAME) #define __dtcm_bss_section Z_GENERIC_SECTION(_DTCM_BSS_SECTION_NAME) @@ -46,6 +43,14 @@ #define __imx_boot_dcd_section Z_GENERIC_SECTION(_IMX_BOOT_DCD_SECTION_NAME) #define __imx_boot_container_section Z_GENERIC_SECTION(_IMX_BOOT_CONTAINER_SECTION_NAME) #define __stm32_backup_sram_section Z_GENERIC_SECTION(_STM32_BACKUP_SRAM_SECTION_NAME) + +/* + * Deprecated aliases, provided for backwards compatibility. + * These aliases will be removed in Zephyr v4.5. + */ +#define __ccm_data_section __dtcm_data_section __DEPRECATED_MACRO +#define __ccm_bss_section __dtcm_bss_section __DEPRECATED_MACRO +#define __ccm_noinit_section __dtcm_noinit_section __DEPRECATED_MACRO #endif /* CONFIG_ARM */ #if defined(CONFIG_NOCACHE_MEMORY) diff --git a/include/zephyr/linker/sections.h b/include/zephyr/linker/sections.h index d58e206486e8..c665fa7bf843 100644 --- a/include/zephyr/linker/sections.h +++ b/include/zephyr/linker/sections.h @@ -49,10 +49,6 @@ #define _KINETIS_FLASH_CONFIG_SECTION_NAME kinetis_flash_config #define _TI_CCFG_SECTION_NAME .ti_ccfg -#define _CCM_DATA_SECTION_NAME .ccm_data -#define _CCM_BSS_SECTION_NAME .ccm_bss -#define _CCM_NOINIT_SECTION_NAME .ccm_noinit - #define _ITCM_SECTION_NAME .itcm #define _DTCM_DATA_SECTION_NAME .dtcm_data From 7323d50fc53bfe4886acb7826361d09cf6c23e4e Mon Sep 17 00:00:00 2001 From: Mathieu Choplain Date: Fri, 5 Dec 2025 15:42:13 +0100 Subject: [PATCH 0063/3659] soc: st: stm32: remove CCM handling code The `st,stm32-ccm` is now used though the generic DTCM mechanism: remove all SoC-specific code which was used to implement support for it. Signed-off-by: Mathieu Choplain --- soc/st/stm32/common/CMakeLists.txt | 9 -------- soc/st/stm32/common/Kconfig | 6 ------ soc/st/stm32/common/ccm.ld | 34 ------------------------------ 3 files changed, 49 deletions(-) delete mode 100644 soc/st/stm32/common/ccm.ld diff --git a/soc/st/stm32/common/CMakeLists.txt b/soc/st/stm32/common/CMakeLists.txt index fbc92c6c8368..38b0b614cbf4 100644 --- a/soc/st/stm32/common/CMakeLists.txt +++ b/soc/st/stm32/common/CMakeLists.txt @@ -7,15 +7,6 @@ zephyr_sources( soc_config.c ) -if(DEFINED CONFIG_STM32_CCM) - zephyr_linker_group(NAME CCM_REGION VMA CCM LMA ROM_REGION) - zephyr_linker_section(NAME .ccm_bss GROUP CCM_REGION SUBALIGN 4 TYPE BSS ) - zephyr_linker_section(NAME .ccm_noinit GROUP CCM_REGION SUBALIGN 4 TYPE NOLOAD NOINIT) - zephyr_linker_section(NAME .ccm_data GROUP CCM_REGION SUBALIGN 4) - - zephyr_linker_sources(SECTIONS ccm.ld) -endif() - zephyr_sources_ifdef(CONFIG_STM32_BACKUP_SRAM stm32_backup_sram.c) zephyr_linker_sources_ifdef(CONFIG_STM32_BACKUP_SRAM SECTIONS stm32_backup_sram.ld) diff --git a/soc/st/stm32/common/Kconfig b/soc/st/stm32/common/Kconfig index 797f9847e8c6..a463e276dada 100644 --- a/soc/st/stm32/common/Kconfig +++ b/soc/st/stm32/common/Kconfig @@ -8,12 +8,6 @@ # multiple STM32 series. # -# Workaround for not being able to have commas in macro arguments -DT_CHOSEN_Z_CCM := zephyr,ccm - -config STM32_CCM - def_bool $(dt_chosen_enabled,$(DT_CHOSEN_Z_CCM)) - config STM32_BACKUP_SRAM bool "STM32 Backup SRAM" default y diff --git a/soc/st/stm32/common/ccm.ld b/soc/st/stm32/common/ccm.ld deleted file mode 100644 index bf9cf65d0306..000000000000 --- a/soc/st/stm32/common/ccm.ld +++ /dev/null @@ -1,34 +0,0 @@ -/* Copied from linker.ld */ - -GROUP_START(CCM) - - SECTION_PROLOGUE(_CCM_BSS_SECTION_NAME, (NOLOAD),SUBALIGN(4)) - { - __ccm_start = .; - __ccm_bss_start = .; - *(.ccm_bss) - *(".ccm_bss.*") - __ccm_bss_end = .; - } GROUP_LINK_IN(LINKER_DT_NODE_REGION_NAME_TOKEN(DT_CHOSEN(zephyr_ccm))) - - SECTION_PROLOGUE(_CCM_NOINIT_SECTION_NAME, (NOLOAD),SUBALIGN(4)) - { - __ccm_noinit_start = .; - *(.ccm_noinit) - *(".ccm_noinit.*") - __ccm_noinit_end = .; - } GROUP_LINK_IN(LINKER_DT_NODE_REGION_NAME_TOKEN(DT_CHOSEN(zephyr_ccm))) - - SECTION_PROLOGUE(_CCM_DATA_SECTION_NAME,,SUBALIGN(4)) - { - __ccm_data_start = .; - *(.ccm_data) - *(".ccm_data.*") - __ccm_data_end = .; - } GROUP_LINK_IN(LINKER_DT_NODE_REGION_NAME_TOKEN(DT_CHOSEN(zephyr_ccm)) AT> ROMABLE_REGION) - - __ccm_end = .; - - __ccm_data_load_start = LOADADDR(_CCM_DATA_SECTION_NAME); - -GROUP_END(CCM) From 9a54da0c349128963ae4bdcc799c52e5a18051c7 Mon Sep 17 00:00:00 2001 From: Mathieu Choplain Date: Fri, 5 Dec 2025 15:41:00 +0100 Subject: [PATCH 0064/3659] doc: dts: api: remove documentation of chosen `zephyr,ccm` The `zephyr,ccm` chosen was an ST-specific property which has been replaced by the generic `zephyr,dtcm`. Remove it from the DTS documentation. Signed-off-by: Mathieu Choplain --- doc/build/dts/api/api.rst | 2 -- 1 file changed, 2 deletions(-) diff --git a/doc/build/dts/api/api.rst b/doc/build/dts/api/api.rst index a9b8ffe834d6..0a7296831d93 100644 --- a/doc/build/dts/api/api.rst +++ b/doc/build/dts/api/api.rst @@ -392,8 +392,6 @@ device. - Video input device, typically a camera. * - zephyr,canbus - Sets the default CAN controller - * - zephyr,ccm - - Core-Coupled Memory node on some STM32 SoCs * - zephyr,code-partition - Flash partition that the Zephyr image's text section should be linked into From 7af28275f041787b1b17234f7076dfd7579db703 Mon Sep 17 00:00:00 2001 From: Mathieu Choplain Date: Fri, 5 Dec 2025 15:55:44 +0100 Subject: [PATCH 0065/3659] migration-guide: 4.4: document remplacement of `zephyr,ccm` Document remplacement of the ST-specific `zephyr,ccm` by `zephyr,dtcm` along with actions to take in application code in the migration guide. Signed-off-by: Mathieu Choplain --- doc/releases/migration-guide-4.4.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/doc/releases/migration-guide-4.4.rst b/doc/releases/migration-guide-4.4.rst index f24fe700ae46..cc6549e5335f 100644 --- a/doc/releases/migration-guide-4.4.rst +++ b/doc/releases/migration-guide-4.4.rst @@ -140,6 +140,11 @@ STM32 * ``CONFIG_POWER_SUPPLY_EXTERNAL_SOURCE`` +* The ST-specific chosen property ``/chosen/zephyr,ccm`` is replaced by ``/chosen/zephyr,dtcm``. + Attribute macros ``__ccm_data_section``, ``__ccm_bss_section`` and ``__ccm_noinit_section`` are + deprecated, but retained for backwards compatibility; **they will be removed in Zephyr 4.5**. + The generic ``__dtcm_{data,bss,noinit}_section`` macros should be used instead. (:github:`100590`) + Shell ===== From 308c40c111f27d5f202c9b6dfe5f15d2e0f4e9c6 Mon Sep 17 00:00:00 2001 From: Ederson de Souza Date: Fri, 14 Nov 2025 16:16:48 -0800 Subject: [PATCH 0066/3659] samples/subsys/pmci/mctp: Add npcx4m8f_evb overlays So that one can run the host/endpoint sample on them. Signed-off-by: Ederson de Souza --- .../subsys/pmci/mctp/endpoint/boards/npcx4m8f_evb.conf | 1 + .../subsys/pmci/mctp/endpoint/boards/npcx4m8f_evb.overlay | 8 ++++++++ samples/subsys/pmci/mctp/host/boards/npcx4m8f_evb.conf | 1 + samples/subsys/pmci/mctp/host/boards/npcx4m8f_evb.overlay | 8 ++++++++ 4 files changed, 18 insertions(+) create mode 100644 samples/subsys/pmci/mctp/endpoint/boards/npcx4m8f_evb.conf create mode 100644 samples/subsys/pmci/mctp/endpoint/boards/npcx4m8f_evb.overlay create mode 100644 samples/subsys/pmci/mctp/host/boards/npcx4m8f_evb.conf create mode 100644 samples/subsys/pmci/mctp/host/boards/npcx4m8f_evb.overlay diff --git a/samples/subsys/pmci/mctp/endpoint/boards/npcx4m8f_evb.conf b/samples/subsys/pmci/mctp/endpoint/boards/npcx4m8f_evb.conf new file mode 100644 index 000000000000..3d154194699d --- /dev/null +++ b/samples/subsys/pmci/mctp/endpoint/boards/npcx4m8f_evb.conf @@ -0,0 +1 @@ +CONFIG_UART_NPCX_USE_MDMA=y diff --git a/samples/subsys/pmci/mctp/endpoint/boards/npcx4m8f_evb.overlay b/samples/subsys/pmci/mctp/endpoint/boards/npcx4m8f_evb.overlay new file mode 100644 index 000000000000..2c30c7e5d04e --- /dev/null +++ b/samples/subsys/pmci/mctp/endpoint/boards/npcx4m8f_evb.overlay @@ -0,0 +1,8 @@ +&uart2 { + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&uart2_sin_gp75 &uart2_sout_gp86>; + pinctrl-names = "default"; +}; + +arduino_serial: &uart2 {}; diff --git a/samples/subsys/pmci/mctp/host/boards/npcx4m8f_evb.conf b/samples/subsys/pmci/mctp/host/boards/npcx4m8f_evb.conf new file mode 100644 index 000000000000..3d154194699d --- /dev/null +++ b/samples/subsys/pmci/mctp/host/boards/npcx4m8f_evb.conf @@ -0,0 +1 @@ +CONFIG_UART_NPCX_USE_MDMA=y diff --git a/samples/subsys/pmci/mctp/host/boards/npcx4m8f_evb.overlay b/samples/subsys/pmci/mctp/host/boards/npcx4m8f_evb.overlay new file mode 100644 index 000000000000..2c30c7e5d04e --- /dev/null +++ b/samples/subsys/pmci/mctp/host/boards/npcx4m8f_evb.overlay @@ -0,0 +1,8 @@ +&uart2 { + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&uart2_sin_gp75 &uart2_sout_gp86>; + pinctrl-names = "default"; +}; + +arduino_serial: &uart2 {}; From 2bfe6c498b4f03a1f447aaede3812b3f72a5f2d2 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Tue, 2 Dec 2025 09:53:51 -0500 Subject: [PATCH 0067/3659] tracing: move event ids from uint8_t to uint16_t We are hitting the limit of 256 events possible with event id right now defined as uint8_t. The bandwidth increase is minimal (2 bytes per event) compared to the payload data, and the scalability benefits far outweigh the costs. Existing CTF traces with 8-bit IDs won't be compatible. Signed-off-by: Anas Nashif --- subsys/tracing/ctf/ctf_top.h | 486 ++++++++++++++++--------------- subsys/tracing/ctf/tsdl/metadata | 2 +- 2 files changed, 245 insertions(+), 243 deletions(-) diff --git a/subsys/tracing/ctf/ctf_top.h b/subsys/tracing/ctf/ctf_top.h index 24f7d04108a2..60316aa04d00 100644 --- a/subsys/tracing/ctf/ctf_top.h +++ b/subsys/tracing/ctf/ctf_top.h @@ -344,775 +344,776 @@ typedef struct { static inline void ctf_top_thread_switched_out(uint32_t thread_id, ctf_bounded_string_t name) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_THREAD_SWITCHED_OUT), thread_id, name); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_THREAD_SWITCHED_OUT), thread_id, name); } static inline void ctf_top_thread_switched_in(uint32_t thread_id, ctf_bounded_string_t name) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_THREAD_SWITCHED_IN), thread_id, name); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_THREAD_SWITCHED_IN), thread_id, name); } static inline void ctf_top_thread_priority_set(uint32_t thread_id, int8_t prio, ctf_bounded_string_t name) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_THREAD_PRIORITY_SET), thread_id, name, prio); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_THREAD_PRIORITY_SET), thread_id, name, prio); } static inline void ctf_top_thread_sleep_enter(uint32_t timeout) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_THREAD_SLEEP_ENTER), timeout); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_THREAD_SLEEP_ENTER), timeout); } static inline void ctf_top_thread_sleep_exit(uint32_t timeout, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_THREAD_SLEEP_EXIT), timeout, ret); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_THREAD_SLEEP_EXIT), timeout, ret); } static inline void ctf_top_thread_create(uint32_t thread_id, int8_t prio, ctf_bounded_string_t name) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_THREAD_CREATE), thread_id, name); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_THREAD_CREATE), thread_id, name); } static inline void ctf_top_thread_abort(uint32_t thread_id, ctf_bounded_string_t name) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_THREAD_ABORT), thread_id, name); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_THREAD_ABORT), thread_id, name); } static inline void ctf_top_thread_suspend(uint32_t thread_id, ctf_bounded_string_t name) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_THREAD_SUSPEND), thread_id, name); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_THREAD_SUSPEND), thread_id, name); } static inline void ctf_top_thread_resume(uint32_t thread_id, ctf_bounded_string_t name) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_THREAD_RESUME), thread_id, name); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_THREAD_RESUME), thread_id, name); } static inline void ctf_top_thread_ready(uint32_t thread_id, ctf_bounded_string_t name) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_THREAD_READY), thread_id, name); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_THREAD_READY), thread_id, name); } static inline void ctf_top_thread_pend(uint32_t thread_id, ctf_bounded_string_t name) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_THREAD_PENDING), thread_id, name); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_THREAD_PENDING), thread_id, name); } static inline void ctf_top_thread_info(uint32_t thread_id, ctf_bounded_string_t name, uint32_t stack_base, uint32_t stack_size) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_THREAD_INFO), thread_id, name, stack_base, + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_THREAD_INFO), thread_id, name, stack_base, stack_size); } static inline void ctf_top_thread_name_set(uint32_t thread_id, ctf_bounded_string_t name) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_THREAD_NAME_SET), thread_id, name); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_THREAD_NAME_SET), thread_id, name); } static inline void ctf_top_thread_user_mode_enter(uint32_t thread_id, ctf_bounded_string_t name) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_THREAD_USER_MODE_ENTER), thread_id, name); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_THREAD_USER_MODE_ENTER), thread_id, name); } static inline void ctf_top_thread_wakeup(uint32_t thread_id, ctf_bounded_string_t name) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_THREAD_WAKEUP), thread_id, name); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_THREAD_WAKEUP), thread_id, name); } /* Thread Extended Functions */ static inline void ctf_top_thread_foreach_enter(void) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_THREAD_FOREACH_ENTER)); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_THREAD_FOREACH_ENTER)); } static inline void ctf_top_thread_foreach_exit(void) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_THREAD_FOREACH_EXIT)); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_THREAD_FOREACH_EXIT)); } static inline void ctf_top_thread_foreach_unlocked_enter(void) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_THREAD_FOREACH_UNLOCKED_ENTER)); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_THREAD_FOREACH_UNLOCKED_ENTER)); } static inline void ctf_top_thread_foreach_unlocked_exit(void) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_THREAD_FOREACH_UNLOCKED_EXIT)); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_THREAD_FOREACH_UNLOCKED_EXIT)); } static inline void ctf_top_thread_heap_assign(uint32_t thread_id, uint32_t heap_id) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_THREAD_HEAP_ASSIGN), thread_id, heap_id); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_THREAD_HEAP_ASSIGN), thread_id, heap_id); } static inline void ctf_top_thread_join_enter(uint32_t thread_id, uint32_t timeout) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_THREAD_JOIN_ENTER), thread_id, timeout); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_THREAD_JOIN_ENTER), thread_id, timeout); } static inline void ctf_top_thread_join_blocking(uint32_t thread_id, uint32_t timeout) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_THREAD_JOIN_BLOCKING), thread_id, timeout); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_THREAD_JOIN_BLOCKING), thread_id, timeout); } static inline void ctf_top_thread_join_exit(uint32_t thread_id, uint32_t timeout, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_THREAD_JOIN_EXIT), thread_id, timeout, ret); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_THREAD_JOIN_EXIT), thread_id, timeout, ret); } static inline void ctf_top_thread_msleep_enter(int32_t ms) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_THREAD_MSLEEP_ENTER), ms); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_THREAD_MSLEEP_ENTER), ms); } static inline void ctf_top_thread_msleep_exit(int32_t ms, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_THREAD_MSLEEP_EXIT), ms, ret); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_THREAD_MSLEEP_EXIT), ms, ret); } static inline void ctf_top_thread_usleep_enter(int32_t us) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_THREAD_USLEEP_ENTER), us); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_THREAD_USLEEP_ENTER), us); } static inline void ctf_top_thread_usleep_exit(int32_t us, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_THREAD_USLEEP_EXIT), us, ret); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_THREAD_USLEEP_EXIT), us, ret); } static inline void ctf_top_thread_busy_wait_enter(uint32_t usec_to_wait) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_THREAD_BUSY_WAIT_ENTER), usec_to_wait); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_THREAD_BUSY_WAIT_ENTER), usec_to_wait); } static inline void ctf_top_thread_busy_wait_exit(uint32_t usec_to_wait) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_THREAD_BUSY_WAIT_EXIT), usec_to_wait); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_THREAD_BUSY_WAIT_EXIT), usec_to_wait); } static inline void ctf_top_thread_yield(void) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_THREAD_YIELD)); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_THREAD_YIELD)); } static inline void ctf_top_thread_suspend_exit(uint32_t thread_id, ctf_bounded_string_t name) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_THREAD_SUSPEND_EXIT), thread_id, name); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_THREAD_SUSPEND_EXIT), thread_id, name); } static inline void ctf_top_thread_sched_lock(void) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_THREAD_SCHED_LOCK)); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_THREAD_SCHED_LOCK)); } static inline void ctf_top_thread_sched_unlock(void) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_THREAD_SCHED_UNLOCK)); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_THREAD_SCHED_UNLOCK)); } static inline void ctf_top_thread_sched_wakeup(uint32_t thread_id, ctf_bounded_string_t name) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_THREAD_SCHED_WAKEUP), thread_id, name); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_THREAD_SCHED_WAKEUP), thread_id, name); } static inline void ctf_top_thread_sched_abort(uint32_t thread_id, ctf_bounded_string_t name) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_THREAD_SCHED_ABORT), thread_id, name); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_THREAD_SCHED_ABORT), thread_id, name); } static inline void ctf_top_thread_sched_priority_set(uint32_t thread_id, int8_t prio, ctf_bounded_string_t name) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_THREAD_SCHED_PRIORITY_SET), thread_id, prio, name); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_THREAD_SCHED_PRIORITY_SET), thread_id, prio, + name); } static inline void ctf_top_thread_sched_ready(uint32_t thread_id, ctf_bounded_string_t name) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_THREAD_SCHED_READY), thread_id, name); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_THREAD_SCHED_READY), thread_id, name); } static inline void ctf_top_thread_sched_pend(uint32_t thread_id, ctf_bounded_string_t name) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_THREAD_SCHED_PEND), thread_id, name); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_THREAD_SCHED_PEND), thread_id, name); } static inline void ctf_top_thread_sched_resume(uint32_t thread_id, ctf_bounded_string_t name) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_THREAD_SCHED_RESUME), thread_id, name); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_THREAD_SCHED_RESUME), thread_id, name); } static inline void ctf_top_thread_sched_suspend(uint32_t thread_id, ctf_bounded_string_t name) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_THREAD_SCHED_SUSPEND), thread_id, name); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_THREAD_SCHED_SUSPEND), thread_id, name); } static inline void ctf_top_isr_enter(void) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_ISR_ENTER)); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_ISR_ENTER)); } static inline void ctf_top_isr_exit(void) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_ISR_EXIT)); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_ISR_EXIT)); } static inline void ctf_top_isr_exit_to_scheduler(void) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_ISR_EXIT_TO_SCHEDULER)); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_ISR_EXIT_TO_SCHEDULER)); } static inline void ctf_top_idle(void) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_IDLE)); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_IDLE)); } static inline void ctf_top_void(uint32_t id) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_ID_START_CALL), id); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_ID_START_CALL), id); } static inline void ctf_top_end_call(uint32_t id) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_ID_END_CALL), id); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_ID_END_CALL), id); } /* Memory Slabs */ static inline void ctf_top_mem_slab_init(uint32_t slab_id, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_MEM_SLAB_INIT), slab_id, ret); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_MEM_SLAB_INIT), slab_id, ret); } static inline void ctf_top_mem_slab_alloc_enter(uint32_t slab_id, uint32_t timeout) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_MEM_SLAB_ALLOC_ENTER), slab_id, timeout); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_MEM_SLAB_ALLOC_ENTER), slab_id, timeout); } static inline void ctf_top_mem_slab_alloc_blocking(uint32_t slab_id, uint32_t timeout) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_MEM_SLAB_ALLOC_BLOCKING), slab_id, timeout); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_MEM_SLAB_ALLOC_BLOCKING), slab_id, timeout); } static inline void ctf_top_mem_slab_alloc_exit(uint32_t slab_id, uint32_t timeout, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_MEM_SLAB_ALLOC_EXIT), slab_id, timeout, ret); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_MEM_SLAB_ALLOC_EXIT), slab_id, timeout, ret); } static inline void ctf_top_mem_slab_free_enter(uint32_t slab_id) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_MEM_SLAB_FREE_ENTER), slab_id); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_MEM_SLAB_FREE_ENTER), slab_id); } static inline void ctf_top_mem_slab_free_exit(uint32_t slab_id) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_MEM_SLAB_FREE_EXIT), slab_id); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_MEM_SLAB_FREE_EXIT), slab_id); } /* Message Queues*/ static inline void ctf_top_msgq_init(uint32_t msgq_id) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_MSGQ_INIT), msgq_id); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_MSGQ_INIT), msgq_id); } static inline void ctf_top_msgq_alloc_init_enter(uint32_t msgq_id) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_MSGQ_ALLOC_INIT_ENTER), msgq_id); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_MSGQ_ALLOC_INIT_ENTER), msgq_id); } static inline void ctf_top_msgq_alloc_init_exit(uint32_t msgq_id, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_MSGQ_ALLOC_INIT_EXIT), msgq_id, ret); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_MSGQ_ALLOC_INIT_EXIT), msgq_id, ret); } static inline void ctf_top_msgq_put_enter(uint32_t msgq_id, uint32_t timeout) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_MSGQ_PUT_ENTER), msgq_id, timeout); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_MSGQ_PUT_ENTER), msgq_id, timeout); } static inline void ctf_top_msgq_put_blocking(uint32_t msgq_id, uint32_t timeout) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_MSGQ_PUT_BLOCKING), msgq_id, timeout); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_MSGQ_PUT_BLOCKING), msgq_id, timeout); } static inline void ctf_top_msgq_put_exit(uint32_t msgq_id, uint32_t timeout, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_MSGQ_PUT_EXIT), msgq_id, timeout, ret); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_MSGQ_PUT_EXIT), msgq_id, timeout, ret); } static inline void ctf_top_msgq_get_enter(uint32_t msgq_id, uint32_t timeout) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_MSGQ_GET_ENTER), msgq_id, timeout); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_MSGQ_GET_ENTER), msgq_id, timeout); } static inline void ctf_top_msgq_get_blocking(uint32_t msgq_id, uint32_t timeout) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_MSGQ_GET_BLOCKING), msgq_id, timeout); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_MSGQ_GET_BLOCKING), msgq_id, timeout); } static inline void ctf_top_msgq_get_exit(uint32_t msgq_id, uint32_t timeout, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_MSGQ_GET_EXIT), msgq_id, timeout, ret); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_MSGQ_GET_EXIT), msgq_id, timeout, ret); } static inline void ctf_top_msgq_peek(uint32_t msgq_id, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_MSGQ_PEEK), msgq_id, ret); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_MSGQ_PEEK), msgq_id, ret); } static inline void ctf_top_msgq_purge(uint32_t msgq_id) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_MSGQ_PURGE), msgq_id); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_MSGQ_PURGE), msgq_id); } static inline void ctf_top_msgq_put_front_enter(uint32_t msgq_id, uint32_t timeout) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_MSGQ_PUT_FRONT_ENTER), msgq_id, timeout); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_MSGQ_PUT_FRONT_ENTER), msgq_id, timeout); } static inline void ctf_top_msgq_put_front_exit(uint32_t msgq_id, uint32_t timeout, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_MSGQ_PUT_FRONT_EXIT), msgq_id, timeout, ret); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_MSGQ_PUT_FRONT_EXIT), msgq_id, timeout, ret); } static inline void ctf_top_msgq_put_front_blocking(uint32_t msgq_id, uint32_t timeout) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_MSGQ_PUT_FRONT_BLOCKING), msgq_id, timeout); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_MSGQ_PUT_FRONT_BLOCKING), msgq_id, timeout); } static inline void ctf_top_msgq_cleanup_enter(uint32_t msgq_id) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_MSGQ_CLEANUP_ENTER), msgq_id); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_MSGQ_CLEANUP_ENTER), msgq_id); } static inline void ctf_top_msgq_cleanup_exit(uint32_t msgq_id, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_MSGQ_CLEANUP_EXIT), msgq_id, ret); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_MSGQ_CLEANUP_EXIT), msgq_id, ret); } /* Condition Variables */ static inline void ctf_top_condvar_init(uint32_t condvar_id, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_CONDVAR_INIT), condvar_id, ret); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_CONDVAR_INIT), condvar_id, ret); } static inline void ctf_top_condvar_signal_enter(uint32_t condvar_id) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_CONDVAR_SIGNAL_ENTER), condvar_id); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_CONDVAR_SIGNAL_ENTER), condvar_id); } static inline void ctf_top_condvar_signal_blocking(uint32_t condvar_id, uint32_t timeout) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_CONDVAR_SIGNAL_BLOCKING), condvar_id, timeout); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_CONDVAR_SIGNAL_BLOCKING), condvar_id, timeout); } static inline void ctf_top_condvar_signal_exit(uint32_t condvar_id, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_CONDVAR_SIGNAL_EXIT), condvar_id, ret); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_CONDVAR_SIGNAL_EXIT), condvar_id, ret); } static inline void ctf_top_condvar_broadcast_enter(uint32_t condvar_id) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_CONDVAR_BROADCAST_ENTER), condvar_id); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_CONDVAR_BROADCAST_ENTER), condvar_id); } static inline void ctf_top_condvar_broadcast_exit(uint32_t condvar_id, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_CONDVAR_BROADCAST_EXIT), condvar_id, ret); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_CONDVAR_BROADCAST_EXIT), condvar_id, ret); } static inline void ctf_top_condvar_wait_enter(uint32_t condvar_id, uint32_t timeout) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_CONDVAR_WAIT_ENTER), condvar_id, timeout); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_CONDVAR_WAIT_ENTER), condvar_id, timeout); } static inline void ctf_top_condvar_wait_exit(uint32_t condvar_id, uint32_t timeout, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_CONDVAR_WAIT_EXIT), condvar_id, timeout, ret); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_CONDVAR_WAIT_EXIT), condvar_id, timeout, ret); } /* Work Queue */ static inline void ctf_top_work_init(uint32_t work_id) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_WORK_INIT), work_id); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_WORK_INIT), work_id); } static inline void ctf_top_work_submit_to_queue_enter(uint32_t queue_id, uint32_t work_id) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_WORK_SUBMIT_TO_QUEUE_ENTER), queue_id, work_id); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_WORK_SUBMIT_TO_QUEUE_ENTER), queue_id, work_id); } static inline void ctf_top_work_submit_to_queue_exit(uint32_t queue_id, uint32_t work_id, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_WORK_SUBMIT_TO_QUEUE_EXIT), queue_id, work_id, + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_WORK_SUBMIT_TO_QUEUE_EXIT), queue_id, work_id, ret); } static inline void ctf_top_work_submit_enter(uint32_t work_id) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_WORK_SUBMIT_ENTER), work_id); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_WORK_SUBMIT_ENTER), work_id); } static inline void ctf_top_work_submit_exit(uint32_t work_id, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_WORK_SUBMIT_EXIT), work_id, ret); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_WORK_SUBMIT_EXIT), work_id, ret); } static inline void ctf_top_work_flush_enter(uint32_t work_id) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_WORK_FLUSH_ENTER), work_id); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_WORK_FLUSH_ENTER), work_id); } static inline void ctf_top_work_flush_blocking(uint32_t work_id, uint32_t timeout) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_WORK_FLUSH_BLOCKING), work_id, timeout); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_WORK_FLUSH_BLOCKING), work_id, timeout); } static inline void ctf_top_work_flush_exit(uint32_t work_id, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_WORK_FLUSH_EXIT), work_id, ret); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_WORK_FLUSH_EXIT), work_id, ret); } static inline void ctf_top_work_cancel_enter(uint32_t work_id) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_WORK_CANCEL_ENTER), work_id); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_WORK_CANCEL_ENTER), work_id); } static inline void ctf_top_work_cancel_exit(uint32_t work_id, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_WORK_CANCEL_EXIT), work_id, ret); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_WORK_CANCEL_EXIT), work_id, ret); } static inline void ctf_top_work_cancel_sync_enter(uint32_t work_id, uint32_t sync_id) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_WORK_CANCEL_SYNC_ENTER), work_id, sync_id); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_WORK_CANCEL_SYNC_ENTER), work_id, sync_id); } static inline void ctf_top_work_cancel_sync_blocking(uint32_t work_id, uint32_t sync_id) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_WORK_CANCEL_SYNC_BLOCKING), work_id, sync_id); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_WORK_CANCEL_SYNC_BLOCKING), work_id, sync_id); } static inline void ctf_top_work_cancel_sync_exit(uint32_t work_id, uint32_t sync_id, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_WORK_CANCEL_SYNC_EXIT), work_id, sync_id, ret); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_WORK_CANCEL_SYNC_EXIT), work_id, sync_id, ret); } /* Work Queue Management */ static inline void ctf_top_work_queue_init(uint32_t queue_id) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_WORK_QUEUE_INIT), queue_id); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_WORK_QUEUE_INIT), queue_id); } static inline void ctf_top_work_queue_start_enter(uint32_t queue_id) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_WORK_QUEUE_START_ENTER), queue_id); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_WORK_QUEUE_START_ENTER), queue_id); } static inline void ctf_top_work_queue_start_exit(uint32_t queue_id) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_WORK_QUEUE_START_EXIT), queue_id); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_WORK_QUEUE_START_EXIT), queue_id); } static inline void ctf_top_work_queue_stop_enter(uint32_t queue_id, uint32_t timeout) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_WORK_QUEUE_STOP_ENTER), queue_id, timeout); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_WORK_QUEUE_STOP_ENTER), queue_id, timeout); } static inline void ctf_top_work_queue_stop_blocking(uint32_t queue_id, uint32_t timeout) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_WORK_QUEUE_STOP_BLOCKING), queue_id, timeout); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_WORK_QUEUE_STOP_BLOCKING), queue_id, timeout); } static inline void ctf_top_work_queue_stop_exit(uint32_t queue_id, uint32_t timeout, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_WORK_QUEUE_STOP_EXIT), queue_id, timeout, ret); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_WORK_QUEUE_STOP_EXIT), queue_id, timeout, ret); } static inline void ctf_top_work_queue_drain_enter(uint32_t queue_id) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_WORK_QUEUE_DRAIN_ENTER), queue_id); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_WORK_QUEUE_DRAIN_ENTER), queue_id); } static inline void ctf_top_work_queue_drain_exit(uint32_t queue_id, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_WORK_QUEUE_DRAIN_EXIT), queue_id, ret); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_WORK_QUEUE_DRAIN_EXIT), queue_id, ret); } static inline void ctf_top_work_queue_unplug_enter(uint32_t queue_id) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_WORK_QUEUE_UNPLUG_ENTER), queue_id); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_WORK_QUEUE_UNPLUG_ENTER), queue_id); } static inline void ctf_top_work_queue_unplug_exit(uint32_t queue_id, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_WORK_QUEUE_UNPLUG_EXIT), queue_id, ret); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_WORK_QUEUE_UNPLUG_EXIT), queue_id, ret); } /* Delayable Work */ static inline void ctf_top_work_delayable_init(uint32_t dwork_id) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_WORK_DELAYABLE_INIT), dwork_id); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_WORK_DELAYABLE_INIT), dwork_id); } static inline void ctf_top_work_schedule_for_queue_enter(uint32_t queue_id, uint32_t dwork_id, uint32_t delay) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_WORK_SCHEDULE_FOR_QUEUE_ENTER), queue_id, dwork_id, - delay); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_WORK_SCHEDULE_FOR_QUEUE_ENTER), queue_id, + dwork_id, delay); } static inline void ctf_top_work_schedule_for_queue_exit(uint32_t queue_id, uint32_t dwork_id, uint32_t delay, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_WORK_SCHEDULE_FOR_QUEUE_EXIT), queue_id, dwork_id, + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_WORK_SCHEDULE_FOR_QUEUE_EXIT), queue_id, dwork_id, delay, ret); } static inline void ctf_top_work_schedule_enter(uint32_t dwork_id, uint32_t delay) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_WORK_SCHEDULE_ENTER), dwork_id, delay); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_WORK_SCHEDULE_ENTER), dwork_id, delay); } static inline void ctf_top_work_schedule_exit(uint32_t dwork_id, uint32_t delay, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_WORK_SCHEDULE_EXIT), dwork_id, delay, ret); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_WORK_SCHEDULE_EXIT), dwork_id, delay, ret); } static inline void ctf_top_work_reschedule_for_queue_enter(uint32_t queue_id, uint32_t dwork_id, uint32_t delay) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_WORK_RESCHEDULE_FOR_QUEUE_ENTER), queue_id, + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_WORK_RESCHEDULE_FOR_QUEUE_ENTER), queue_id, dwork_id, delay); } static inline void ctf_top_work_reschedule_for_queue_exit(uint32_t queue_id, uint32_t dwork_id, uint32_t delay, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_WORK_RESCHEDULE_FOR_QUEUE_EXIT), queue_id, + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_WORK_RESCHEDULE_FOR_QUEUE_EXIT), queue_id, dwork_id, delay, ret); } static inline void ctf_top_work_reschedule_enter(uint32_t dwork_id, uint32_t delay) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_WORK_RESCHEDULE_ENTER), dwork_id, delay); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_WORK_RESCHEDULE_ENTER), dwork_id, delay); } static inline void ctf_top_work_reschedule_exit(uint32_t dwork_id, uint32_t delay, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_WORK_RESCHEDULE_EXIT), dwork_id, delay, ret); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_WORK_RESCHEDULE_EXIT), dwork_id, delay, ret); } static inline void ctf_top_work_flush_delayable_enter(uint32_t dwork_id, uint32_t sync_id) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_WORK_FLUSH_DELAYABLE_ENTER), dwork_id, sync_id); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_WORK_FLUSH_DELAYABLE_ENTER), dwork_id, sync_id); } static inline void ctf_top_work_flush_delayable_exit(uint32_t dwork_id, uint32_t sync_id, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_WORK_FLUSH_DELAYABLE_EXIT), dwork_id, sync_id, + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_WORK_FLUSH_DELAYABLE_EXIT), dwork_id, sync_id, ret); } static inline void ctf_top_work_cancel_delayable_enter(uint32_t dwork_id) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_WORK_CANCEL_DELAYABLE_ENTER), dwork_id); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_WORK_CANCEL_DELAYABLE_ENTER), dwork_id); } static inline void ctf_top_work_cancel_delayable_exit(uint32_t dwork_id, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_WORK_CANCEL_DELAYABLE_EXIT), dwork_id, ret); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_WORK_CANCEL_DELAYABLE_EXIT), dwork_id, ret); } static inline void ctf_top_work_cancel_delayable_sync_enter(uint32_t dwork_id, uint32_t sync_id) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_WORK_CANCEL_DELAYABLE_SYNC_ENTER), dwork_id, + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_WORK_CANCEL_DELAYABLE_SYNC_ENTER), dwork_id, sync_id); } static inline void ctf_top_work_cancel_delayable_sync_exit(uint32_t dwork_id, uint32_t sync_id, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_WORK_CANCEL_DELAYABLE_SYNC_EXIT), dwork_id, + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_WORK_CANCEL_DELAYABLE_SYNC_EXIT), dwork_id, sync_id, ret); } /* Poll Work */ static inline void ctf_top_work_poll_init_enter(uint32_t work_id) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_WORK_POLL_INIT_ENTER), work_id); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_WORK_POLL_INIT_ENTER), work_id); } static inline void ctf_top_work_poll_init_exit(uint32_t work_id) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_WORK_POLL_INIT_EXIT), work_id); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_WORK_POLL_INIT_EXIT), work_id); } static inline void ctf_top_work_poll_submit_to_queue_enter(uint32_t work_q_id, uint32_t work_id, uint32_t timeout) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_WORK_POLL_SUBMIT_TO_QUEUE_ENTER), work_q_id, + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_WORK_POLL_SUBMIT_TO_QUEUE_ENTER), work_q_id, work_id, timeout); } static inline void ctf_top_work_poll_submit_to_queue_blocking(uint32_t work_q_id, uint32_t work_id, uint32_t timeout) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_WORK_POLL_SUBMIT_TO_QUEUE_BLOCKING), work_q_id, + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_WORK_POLL_SUBMIT_TO_QUEUE_BLOCKING), work_q_id, work_id, timeout); } static inline void ctf_top_work_poll_submit_to_queue_exit(uint32_t work_q_id, uint32_t work_id, uint32_t timeout, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_WORK_POLL_SUBMIT_TO_QUEUE_EXIT), work_q_id, + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_WORK_POLL_SUBMIT_TO_QUEUE_EXIT), work_q_id, work_id, timeout, ret); } static inline void ctf_top_work_poll_submit_enter(uint32_t work_id, uint32_t timeout) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_WORK_POLL_SUBMIT_ENTER), work_id, timeout); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_WORK_POLL_SUBMIT_ENTER), work_id, timeout); } static inline void ctf_top_work_poll_submit_exit(uint32_t work_id, uint32_t timeout, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_WORK_POLL_SUBMIT_EXIT), work_id, timeout, ret); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_WORK_POLL_SUBMIT_EXIT), work_id, timeout, ret); } static inline void ctf_top_work_poll_cancel_enter(uint32_t work_id) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_WORK_POLL_CANCEL_ENTER), work_id); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_WORK_POLL_CANCEL_ENTER), work_id); } static inline void ctf_top_work_poll_cancel_exit(uint32_t work_id, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_WORK_POLL_CANCEL_EXIT), work_id, ret); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_WORK_POLL_CANCEL_EXIT), work_id, ret); } /* Poll API */ static inline void ctf_top_poll_event_init(uint32_t event_id) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_POLL_EVENT_INIT), event_id); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_POLL_EVENT_INIT), event_id); } static inline void ctf_top_poll_enter(uint32_t events_id) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_POLL_ENTER), events_id); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_POLL_ENTER), events_id); } static inline void ctf_top_poll_exit(uint32_t events_id, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_POLL_EXIT), events_id, ret); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_POLL_EXIT), events_id, ret); } static inline void ctf_top_poll_signal_init(uint32_t signal_id) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_POLL_SIGNAL_INIT), signal_id); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_POLL_SIGNAL_INIT), signal_id); } static inline void ctf_top_poll_signal_reset(uint32_t signal_id) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_POLL_SIGNAL_RESET), signal_id); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_POLL_SIGNAL_RESET), signal_id); } static inline void ctf_top_poll_signal_check(uint32_t signal_id) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_POLL_SIGNAL_CHECK), signal_id); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_POLL_SIGNAL_CHECK), signal_id); } static inline void ctf_top_poll_signal_raise(uint32_t signal_id, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_POLL_SIGNAL_RAISE), signal_id, ret); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_POLL_SIGNAL_RAISE), signal_id, ret); } /* Semaphore */ static inline void ctf_top_semaphore_init(uint32_t sem_id, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_SEMAPHORE_INIT), sem_id, ret); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_SEMAPHORE_INIT), sem_id, ret); } static inline void ctf_top_semaphore_reset(uint32_t sem_id) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_SEMAPHORE_RESET), sem_id); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_SEMAPHORE_RESET), sem_id); } static inline void ctf_top_semaphore_take_enter(uint32_t sem_id, uint32_t timeout) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_SEMAPHORE_TAKE_ENTER), sem_id, timeout); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_SEMAPHORE_TAKE_ENTER), sem_id, timeout); } static inline void ctf_top_semaphore_take_blocking(uint32_t sem_id, uint32_t timeout) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_SEMAPHORE_TAKE_BLOCKING), sem_id, timeout); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_SEMAPHORE_TAKE_BLOCKING), sem_id, timeout); } static inline void ctf_top_semaphore_take_exit(uint32_t sem_id, uint32_t timeout, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_SEMAPHORE_TAKE_EXIT), sem_id, timeout, ret); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_SEMAPHORE_TAKE_EXIT), sem_id, timeout, ret); } static inline void ctf_top_semaphore_give_enter(uint32_t sem_id) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_SEMAPHORE_GIVE_ENTER), sem_id); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_SEMAPHORE_GIVE_ENTER), sem_id); } static inline void ctf_top_semaphore_give_exit(uint32_t sem_id) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_SEMAPHORE_GIVE_EXIT), sem_id); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_SEMAPHORE_GIVE_EXIT), sem_id); } /* Mutex */ static inline void ctf_top_mutex_init(uint32_t mutex_id, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_MUTEX_INIT), mutex_id, ret); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_MUTEX_INIT), mutex_id, ret); } static inline void ctf_top_mutex_lock_enter(uint32_t mutex_id, uint32_t timeout) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_MUTEX_LOCK_ENTER), mutex_id, timeout); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_MUTEX_LOCK_ENTER), mutex_id, timeout); } static inline void ctf_top_mutex_lock_blocking(uint32_t mutex_id, uint32_t timeout) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_MUTEX_LOCK_BLOCKING), mutex_id, timeout); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_MUTEX_LOCK_BLOCKING), mutex_id, timeout); } static inline void ctf_top_mutex_lock_exit(uint32_t mutex_id, uint32_t timeout, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_MUTEX_LOCK_EXIT), mutex_id, timeout, ret); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_MUTEX_LOCK_EXIT), mutex_id, timeout, ret); } static inline void ctf_top_mutex_unlock_enter(uint32_t mutex_id) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_MUTEX_UNLOCK_ENTER), mutex_id); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_MUTEX_UNLOCK_ENTER), mutex_id); } static inline void ctf_top_mutex_unlock_exit(uint32_t mutex_id, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_MUTEX_UNLOCK_EXIT), mutex_id, ret); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_MUTEX_UNLOCK_EXIT), mutex_id, ret); } /* Timer */ static inline void ctf_top_timer_init(uint32_t timer) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_TIMER_INIT), timer); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_TIMER_INIT), timer); } static inline void ctf_top_timer_start(uint32_t timer, uint32_t duration, uint32_t period) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_TIMER_START), timer, duration, period); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_TIMER_START), timer, duration, period); } static inline void ctf_top_timer_stop(uint32_t timer) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_TIMER_STOP), timer); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_TIMER_STOP), timer); } static inline void ctf_top_timer_status_sync_enter(uint32_t timer) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_TIMER_STATUS_SYNC_ENTER), timer); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_TIMER_STATUS_SYNC_ENTER), timer); } static inline void ctf_top_timer_status_sync_blocking(uint32_t timer, uint32_t timeout) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_TIMER_STATUS_SYNC_BLOCKING), timer, timeout); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_TIMER_STATUS_SYNC_BLOCKING), timer, timeout); } static inline void ctf_top_timer_status_sync_exit(uint32_t timer, uint32_t result) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_TIMER_STATUS_SYNC_EXIT), timer, result); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_TIMER_STATUS_SYNC_EXIT), timer, result); } /* Network socket */ @@ -1122,505 +1123,506 @@ typedef struct { static inline void ctf_top_socket_init(int32_t sock, uint32_t family, uint32_t type, uint32_t proto) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_SOCKET_INIT), sock, family, type, proto); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_SOCKET_INIT), sock, family, type, proto); } static inline void ctf_top_socket_close_enter(int32_t sock) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_SOCKET_CLOSE_ENTER), sock); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_SOCKET_CLOSE_ENTER), sock); } static inline void ctf_top_socket_close_exit(int32_t sock, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_SOCKET_CLOSE_EXIT), sock, ret); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_SOCKET_CLOSE_EXIT), sock, ret); } static inline void ctf_top_socket_shutdown_enter(int32_t sock, int32_t how) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_SOCKET_SHUTDOWN_ENTER), sock, how); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_SOCKET_SHUTDOWN_ENTER), sock, how); } static inline void ctf_top_socket_shutdown_exit(int32_t sock, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_SOCKET_SHUTDOWN_EXIT), sock, ret); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_SOCKET_SHUTDOWN_EXIT), sock, ret); } static inline void ctf_top_socket_bind_enter(int32_t sock, ctf_net_bounded_string_t addr, uint32_t addrlen, uint16_t port) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_SOCKET_BIND_ENTER), sock, addr, addrlen, port); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_SOCKET_BIND_ENTER), sock, addr, addrlen, port); } static inline void ctf_top_socket_bind_exit(int32_t sock, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_SOCKET_BIND_EXIT), sock, ret); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_SOCKET_BIND_EXIT), sock, ret); } static inline void ctf_top_socket_connect_enter(int32_t sock, ctf_net_bounded_string_t addr, uint32_t addrlen) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_SOCKET_CONNECT_ENTER), sock, addr, addrlen); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_SOCKET_CONNECT_ENTER), sock, addr, addrlen); } static inline void ctf_top_socket_connect_exit(int32_t sock, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_SOCKET_CONNECT_EXIT), sock, ret); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_SOCKET_CONNECT_EXIT), sock, ret); } static inline void ctf_top_socket_listen_enter(int32_t sock, uint32_t backlog) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_SOCKET_LISTEN_ENTER), sock, backlog); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_SOCKET_LISTEN_ENTER), sock, backlog); } static inline void ctf_top_socket_listen_exit(int32_t sock, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_SOCKET_LISTEN_EXIT), sock, ret); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_SOCKET_LISTEN_EXIT), sock, ret); } static inline void ctf_top_socket_accept_enter(int32_t sock) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_SOCKET_ACCEPT_ENTER), sock); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_SOCKET_ACCEPT_ENTER), sock); } static inline void ctf_top_socket_accept_exit(int32_t sock, ctf_net_bounded_string_t addr, uint32_t addrlen, uint16_t port, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_SOCKET_ACCEPT_EXIT), sock, addr, addrlen, port, + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_SOCKET_ACCEPT_EXIT), sock, addr, addrlen, port, ret); } static inline void ctf_top_socket_sendto_enter(int32_t sock, uint32_t len, uint32_t flags, ctf_net_bounded_string_t addr, uint32_t addrlen) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_SOCKET_SENDTO_ENTER), sock, len, flags, addr, + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_SOCKET_SENDTO_ENTER), sock, len, flags, addr, addrlen); } static inline void ctf_top_socket_sendto_exit(int32_t sock, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_SOCKET_SENDTO_EXIT), sock, ret); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_SOCKET_SENDTO_EXIT), sock, ret); } static inline void ctf_top_socket_sendmsg_enter(int32_t sock, uint32_t flags, uint32_t msg, ctf_net_bounded_string_t addr, uint32_t len) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_SOCKET_SENDMSG_ENTER), sock, flags, msg, addr, + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_SOCKET_SENDMSG_ENTER), sock, flags, msg, addr, len); } static inline void ctf_top_socket_sendmsg_exit(int32_t sock, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_SOCKET_SENDMSG_EXIT), sock, ret); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_SOCKET_SENDMSG_EXIT), sock, ret); } static inline void ctf_top_socket_recvfrom_enter(int32_t sock, uint32_t max_len, uint32_t flags, uint32_t addr, uint32_t addrlen) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_SOCKET_RECVFROM_ENTER), sock, max_len, flags, addr, - addrlen); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_SOCKET_RECVFROM_ENTER), sock, max_len, flags, + addr, addrlen); } static inline void ctf_top_socket_recvfrom_exit(int32_t sock, ctf_net_bounded_string_t addr, uint32_t addrlen, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_SOCKET_RECVFROM_EXIT), sock, addr, addrlen, ret); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_SOCKET_RECVFROM_EXIT), sock, addr, addrlen, ret); } static inline void ctf_top_socket_recvmsg_enter(int32_t sock, uint32_t msg, uint32_t max_len, uint32_t flags) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_SOCKET_RECVMSG_ENTER), sock, msg, max_len, flags); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_SOCKET_RECVMSG_ENTER), sock, msg, max_len, flags); } static inline void ctf_top_socket_recvmsg_exit(int32_t sock, uint32_t len, ctf_net_bounded_string_t addr, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_SOCKET_RECVMSG_EXIT), sock, len, addr, ret); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_SOCKET_RECVMSG_EXIT), sock, len, addr, ret); } static inline void ctf_top_socket_fcntl_enter(int32_t sock, uint32_t cmd, uint32_t flags) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_SOCKET_FCNTL_ENTER), sock, cmd, flags); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_SOCKET_FCNTL_ENTER), sock, cmd, flags); } static inline void ctf_top_socket_fcntl_exit(int32_t sock, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_SOCKET_FCNTL_EXIT), sock, ret); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_SOCKET_FCNTL_EXIT), sock, ret); } static inline void ctf_top_socket_ioctl_enter(int32_t sock, uint32_t req) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_SOCKET_IOCTL_ENTER), sock, req); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_SOCKET_IOCTL_ENTER), sock, req); } static inline void ctf_top_socket_ioctl_exit(int32_t sock, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_SOCKET_IOCTL_EXIT), sock, ret); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_SOCKET_IOCTL_EXIT), sock, ret); } static inline void ctf_top_socket_poll_enter(uint32_t fds, uint32_t nfds, int32_t timeout) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_SOCKET_POLL_ENTER), fds, nfds, timeout); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_SOCKET_POLL_ENTER), fds, nfds, timeout); } static inline void ctf_top_socket_poll_value(int32_t fd, uint16_t flag) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_SOCKET_POLL_VALUE), fd, flag); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_SOCKET_POLL_VALUE), fd, flag); } static inline void ctf_top_socket_poll_exit(uint32_t fds, int nfds, int ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_SOCKET_POLL_EXIT), fds, nfds, ret); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_SOCKET_POLL_EXIT), fds, nfds, ret); } static inline void ctf_top_socket_getsockopt_enter(int32_t sock, uint32_t level, uint32_t optname) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_SOCKET_GETSOCKOPT_ENTER), sock, level, optname); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_SOCKET_GETSOCKOPT_ENTER), sock, level, optname); } static inline void ctf_top_socket_getsockopt_exit(int32_t sock, uint32_t level, uint32_t optname, uint32_t optval, uint32_t optlen, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_SOCKET_GETSOCKOPT_EXIT), sock, level, optname, + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_SOCKET_GETSOCKOPT_EXIT), sock, level, optname, optval, optlen, ret); } static inline void ctf_top_socket_setsockopt_enter(int32_t sock, uint32_t level, uint32_t optname, uint32_t optval, uint32_t optlen) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_SOCKET_SETSOCKOPT_ENTER), sock, level, optname, + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_SOCKET_SETSOCKOPT_ENTER), sock, level, optname, optval, optlen); } static inline void ctf_top_socket_setsockopt_exit(int32_t sock, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_SOCKET_SETSOCKOPT_EXIT), sock, ret); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_SOCKET_SETSOCKOPT_EXIT), sock, ret); } static inline void ctf_top_socket_getpeername_enter(int32_t sock) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_SOCKET_GETPEERNAME_ENTER), sock); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_SOCKET_GETPEERNAME_ENTER), sock); } static inline void ctf_top_socket_getpeername_exit(int32_t sock, ctf_net_bounded_string_t addr, uint32_t addrlen, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_SOCKET_GETPEERNAME_EXIT), sock, addr, addrlen, + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_SOCKET_GETPEERNAME_EXIT), sock, addr, addrlen, ret); } static inline void ctf_top_socket_getsockname_enter(int32_t sock) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_SOCKET_GETSOCKNAME_ENTER), sock); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_SOCKET_GETSOCKNAME_ENTER), sock); } static inline void ctf_top_socket_getsockname_exit(int32_t sock, ctf_net_bounded_string_t addr, uint32_t addrlen, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_SOCKET_GETSOCKNAME_EXIT), sock, addr, addrlen, + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_SOCKET_GETSOCKNAME_EXIT), sock, addr, addrlen, ret); } static inline void ctf_top_socket_socketpair_enter(uint32_t family, uint32_t type, uint32_t proto, uint32_t sv) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_SOCKET_SOCKETPAIR_ENTER), family, type, proto, sv); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_SOCKET_SOCKETPAIR_ENTER), family, type, proto, + sv); } static inline void ctf_top_socket_socketpair_exit(int32_t sock_A, int32_t sock_B, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_SOCKET_SOCKETPAIR_EXIT), sock_A, sock_B, ret); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_SOCKET_SOCKETPAIR_EXIT), sock_A, sock_B, ret); } static inline void ctf_top_net_recv_data_enter(int32_t if_index, uint32_t iface, uint32_t pkt, uint32_t len) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_NET_RECV_DATA_ENTER), if_index, iface, pkt, len); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_NET_RECV_DATA_ENTER), if_index, iface, pkt, len); } static inline void ctf_top_net_recv_data_exit(int32_t if_index, uint32_t iface, uint32_t pkt, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_NET_RECV_DATA_EXIT), if_index, iface, pkt, ret); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_NET_RECV_DATA_EXIT), if_index, iface, pkt, ret); } static inline void ctf_top_net_send_data_enter(int32_t if_index, uint32_t iface, uint32_t pkt, uint32_t len) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_NET_SEND_DATA_ENTER), if_index, iface, pkt, len); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_NET_SEND_DATA_ENTER), if_index, iface, pkt, len); } static inline void ctf_top_net_send_data_exit(int32_t if_index, uint32_t iface, uint32_t pkt, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_NET_SEND_DATA_EXIT), if_index, iface, pkt, ret); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_NET_SEND_DATA_EXIT), if_index, iface, pkt, ret); } static inline void ctf_top_net_rx_time(int32_t if_index, uint32_t iface, uint32_t pkt, uint32_t priority, uint32_t tc, uint32_t duration) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_NET_RX_TIME), if_index, iface, pkt, priority, tc, + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_NET_RX_TIME), if_index, iface, pkt, priority, tc, duration); } static inline void ctf_top_net_tx_time(int32_t if_index, uint32_t iface, uint32_t pkt, uint32_t priority, uint32_t tc, uint32_t duration) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_NET_TX_TIME), if_index, iface, pkt, priority, tc, + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_NET_TX_TIME), if_index, iface, pkt, priority, tc, duration); } static inline void ctf_named_event(ctf_bounded_string_t name, uint32_t arg0, uint32_t arg1) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_NAMED_EVENT), name, arg0, arg1); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_NAMED_EVENT), name, arg0, arg1); } /* GPIO */ static inline void ctf_top_gpio_pin_interrupt_configure_enter(uint32_t port, uint32_t pin, uint32_t flags) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_GPIO_PIN_CONFIGURE_INTERRUPT_ENTER), port, pin, + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_GPIO_PIN_CONFIGURE_INTERRUPT_ENTER), port, pin, flags); } static inline void ctf_top_gpio_pin_interrupt_configure_exit(uint32_t port, uint32_t pin, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_GPIO_PIN_CONFIGURE_INTERRUPT_EXIT), port, pin, + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_GPIO_PIN_CONFIGURE_INTERRUPT_EXIT), port, pin, ret); } static inline void ctf_top_gpio_pin_configure_enter(uint32_t port, uint32_t pin, uint32_t flags) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_GPIO_PIN_CONFIGURE_ENTER), port, pin, flags); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_GPIO_PIN_CONFIGURE_ENTER), port, pin, flags); } static inline void ctf_top_gpio_pin_configure_exit(uint32_t port, uint32_t pin, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_GPIO_PIN_CONFIGURE_EXIT), port, pin, ret); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_GPIO_PIN_CONFIGURE_EXIT), port, pin, ret); } static inline void ctf_top_gpio_port_get_direction_enter(uint32_t port, uint32_t map, uint32_t inputs, uint32_t outputs) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_GPIO_PORT_GET_DIRECTION_ENTER), port, map, inputs, + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_GPIO_PORT_GET_DIRECTION_ENTER), port, map, inputs, outputs); } static inline void ctf_top_gpio_port_get_direction_exit(uint32_t port, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_GPIO_PORT_GET_DIRECTION_EXIT), port, ret); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_GPIO_PORT_GET_DIRECTION_EXIT), port, ret); } static inline void ctf_top_gpio_pin_get_config_enter(uint32_t port, uint32_t pin, uint32_t flags) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_GPIO_PIN_GET_CONFIG_ENTER), port, pin, flags); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_GPIO_PIN_GET_CONFIG_ENTER), port, pin, flags); } static inline void ctf_top_gpio_pin_get_config_exit(uint32_t port, uint32_t pin, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_GPIO_PIN_GET_CONFIG_EXIT), port, pin, ret); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_GPIO_PIN_GET_CONFIG_EXIT), port, pin, ret); } static inline void ctf_top_gpio_port_get_raw_enter(uint32_t port, uint32_t value) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_GPIO_PORT_GET_RAW_ENTER), port, value); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_GPIO_PORT_GET_RAW_ENTER), port, value); } static inline void ctf_top_gpio_port_get_raw_exit(uint32_t port, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_GPIO_PORT_GET_RAW_EXIT), port, ret); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_GPIO_PORT_GET_RAW_EXIT), port, ret); } static inline void ctf_top_gpio_port_set_masked_raw_enter(uint32_t port, uint32_t mask, uint32_t value) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_GPIO_PORT_SET_MASKED_RAW_ENTER), port, mask, + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_GPIO_PORT_SET_MASKED_RAW_ENTER), port, mask, value); } static inline void ctf_top_gpio_port_set_masked_raw_exit(uint32_t port, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_GPIO_PORT_SET_MASKED_RAW_EXIT), port, ret); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_GPIO_PORT_SET_MASKED_RAW_EXIT), port, ret); } static inline void ctf_top_gpio_port_set_bits_raw_enter(uint32_t port, uint32_t pins) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_GPIO_PORT_SET_BITS_RAW_ENTER), port, pins); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_GPIO_PORT_SET_BITS_RAW_ENTER), port, pins); } static inline void ctf_top_gpio_port_set_bits_raw_exit(uint32_t port, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_GPIO_PORT_SET_BITS_RAW_EXIT), port, ret); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_GPIO_PORT_SET_BITS_RAW_EXIT), port, ret); } static inline void ctf_top_gpio_port_clear_bits_raw_enter(uint32_t port, uint32_t pins) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_GPIO_PORT_CLEAR_BITS_RAW_ENTER), port, pins); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_GPIO_PORT_CLEAR_BITS_RAW_ENTER), port, pins); } static inline void ctf_top_gpio_port_clear_bits_raw_exit(uint32_t port, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_GPIO_PORT_CLEAR_BITS_RAW_EXIT), port, ret); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_GPIO_PORT_CLEAR_BITS_RAW_EXIT), port, ret); } static inline void ctf_top_gpio_port_toggle_bits_enter(uint32_t port, uint32_t pins) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_GPIO_PORT_TOGGLE_BITS_ENTER), port, pins); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_GPIO_PORT_TOGGLE_BITS_ENTER), port, pins); } static inline void ctf_top_gpio_port_toggle_bits_exit(uint32_t port, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_GPIO_PORT_TOGGLE_BITS_EXIT), port, ret); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_GPIO_PORT_TOGGLE_BITS_EXIT), port, ret); } static inline void ctf_top_gpio_init_callback_enter(uint32_t callback, uint32_t handler, uint32_t pin_mask) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_GPIO_INIT_CALLBACK_ENTER), callback, handler, + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_GPIO_INIT_CALLBACK_ENTER), callback, handler, pin_mask); } static inline void ctf_top_gpio_init_callback_exit(uint32_t callback) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_GPIO_INIT_CALLBACK_EXIT), callback); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_GPIO_INIT_CALLBACK_EXIT), callback); } static inline void ctf_top_gpio_add_callback_enter(uint32_t port, uint32_t callback) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_GPIO_ADD_CALLBACK_ENTER), port, callback); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_GPIO_ADD_CALLBACK_ENTER), port, callback); } static inline void ctf_top_gpio_add_callback_exit(uint32_t port, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_GPIO_ADD_CALLBACK_EXIT), port, ret); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_GPIO_ADD_CALLBACK_EXIT), port, ret); } static inline void ctf_top_gpio_remove_callback_enter(uint32_t port, uint32_t callback) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_GPIO_REMOVE_CALLBACK_ENTER), port, callback); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_GPIO_REMOVE_CALLBACK_ENTER), port, callback); } static inline void ctf_top_gpio_remove_callback_exit(uint32_t port, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_GPIO_REMOVE_CALLBACK_EXIT), port, ret); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_GPIO_REMOVE_CALLBACK_EXIT), port, ret); } static inline void ctf_top_gpio_get_pending_int_enter(uint32_t dev) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_GPIO_GET_PENDING_INT_ENTER), dev); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_GPIO_GET_PENDING_INT_ENTER), dev); } static inline void ctf_top_gpio_get_pending_int_exit(uint32_t dev, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_GPIO_GET_PENDING_INT_EXIT), dev, ret); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_GPIO_GET_PENDING_INT_EXIT), dev, ret); } static inline void ctf_top_gpio_fire_callbacks_enter(uint32_t list, uint32_t port, uint32_t pins) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_GPIO_FIRE_CALLBACKS_ENTER), list, port, pins); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_GPIO_FIRE_CALLBACKS_ENTER), list, port, pins); } static inline void ctf_top_gpio_fire_callback(uint32_t port, uint32_t cb) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_GPIO_FIRE_CALLBACK), port, cb); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_GPIO_FIRE_CALLBACK), port, cb); } /* Mailbox */ static inline void ctf_top_mbox_init(uint32_t mbox_id) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_MBOX_INIT), mbox_id); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_MBOX_INIT), mbox_id); } static inline void ctf_top_mbox_message_put_enter(uint32_t mbox_id, uint32_t timeout) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_MBOX_MESSAGE_PUT_ENTER), mbox_id, timeout); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_MBOX_MESSAGE_PUT_ENTER), mbox_id, timeout); } static inline void ctf_top_mbox_message_put_blocking(uint32_t mbox_id, uint32_t timeout) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_MBOX_MESSAGE_PUT_BLOCKING), mbox_id, timeout); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_MBOX_MESSAGE_PUT_BLOCKING), mbox_id, timeout); } static inline void ctf_top_mbox_message_put_exit(uint32_t mbox_id, uint32_t timeout, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_MBOX_MESSAGE_PUT_EXIT), mbox_id, timeout, ret); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_MBOX_MESSAGE_PUT_EXIT), mbox_id, timeout, ret); } static inline void ctf_top_mbox_put_enter(uint32_t mbox_id, uint32_t timeout) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_MBOX_PUT_ENTER), mbox_id, timeout); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_MBOX_PUT_ENTER), mbox_id, timeout); } static inline void ctf_top_mbox_put_exit(uint32_t mbox_id, uint32_t timeout, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_MBOX_PUT_EXIT), mbox_id, timeout, ret); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_MBOX_PUT_EXIT), mbox_id, timeout, ret); } static inline void ctf_top_mbox_async_put_enter(uint32_t mbox_id, uint32_t sem_id) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_MBOX_ASYNC_PUT_ENTER), mbox_id, sem_id); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_MBOX_ASYNC_PUT_ENTER), mbox_id, sem_id); } static inline void ctf_top_mbox_async_put_exit(uint32_t mbox_id, uint32_t sem_id) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_MBOX_ASYNC_PUT_EXIT), mbox_id, sem_id); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_MBOX_ASYNC_PUT_EXIT), mbox_id, sem_id); } static inline void ctf_top_mbox_get_enter(uint32_t mbox_id, uint32_t timeout) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_MBOX_GET_ENTER), mbox_id, timeout); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_MBOX_GET_ENTER), mbox_id, timeout); } static inline void ctf_top_mbox_get_blocking(uint32_t mbox_id, uint32_t timeout) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_MBOX_GET_BLOCKING), mbox_id, timeout); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_MBOX_GET_BLOCKING), mbox_id, timeout); } static inline void ctf_top_mbox_get_exit(uint32_t mbox_id, uint32_t timeout, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_MBOX_GET_EXIT), mbox_id, timeout, ret); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_MBOX_GET_EXIT), mbox_id, timeout, ret); } static inline void ctf_top_mbox_data_get(uint32_t msg_id) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_MBOX_DATA_GET), msg_id); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_MBOX_DATA_GET), msg_id); } /* Event */ static inline void ctf_top_event_init(uint32_t event_id) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_EVENT_INIT), event_id); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_EVENT_INIT), event_id); } static inline void ctf_top_event_post_enter(uint32_t event_id, uint32_t events, uint32_t events_mask) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_EVENT_POST_ENTER), event_id, events, events_mask); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_EVENT_POST_ENTER), event_id, events, events_mask); } static inline void ctf_top_event_post_exit(uint32_t event_id, uint32_t events, uint32_t events_mask) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_EVENT_POST_EXIT), event_id, events, events_mask); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_EVENT_POST_EXIT), event_id, events, events_mask); } static inline void ctf_top_event_wait_enter(uint32_t event_id, uint32_t events, uint32_t options, uint32_t timeout) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_EVENT_WAIT_ENTER), event_id, events, options, + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_EVENT_WAIT_ENTER), event_id, events, options, timeout); } static inline void ctf_top_event_wait_blocking(uint32_t event_id, uint32_t events, uint32_t options, uint32_t timeout) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_EVENT_WAIT_BLOCKING), event_id, events, options, + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_EVENT_WAIT_BLOCKING), event_id, events, options, timeout); } static inline void ctf_top_event_wait_exit(uint32_t event_id, uint32_t events, int32_t ret) { - CTF_EVENT(CTF_LITERAL(uint8_t, CTF_EVENT_EVENT_WAIT_EXIT), event_id, events, ret); + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_EVENT_WAIT_EXIT), event_id, events, ret); } #endif /* SUBSYS_DEBUG_TRACING_CTF_TOP_H */ diff --git a/subsys/tracing/ctf/tsdl/metadata b/subsys/tracing/ctf/tsdl/metadata index ca55f1c30df9..972d8d8b9924 100644 --- a/subsys/tracing/ctf/tsdl/metadata +++ b/subsys/tracing/ctf/tsdl/metadata @@ -9,7 +9,7 @@ typealias integer { size = 8; align = 8; signed = false; encoding = ASCII; } := struct event_header { uint32_t timestamp; - uint8_t id; + uint16_t id; }; trace { From 7aeddc3386354a886e7cc4aa3bb1207846a27fcd Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Tue, 2 Dec 2025 10:06:18 -0500 Subject: [PATCH 0068/3659] doc: tracing: add a note about compatibility Add a note about compatibility with older traces. Signed-off-by: Anas Nashif --- doc/releases/migration-guide-4.4.rst | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/doc/releases/migration-guide-4.4.rst b/doc/releases/migration-guide-4.4.rst index cc6549e5335f..d3f4985e9205 100644 --- a/doc/releases/migration-guide-4.4.rst +++ b/doc/releases/migration-guide-4.4.rst @@ -244,6 +244,14 @@ Libsbc * Libsbc (sbc.c and sbc.h) is moved under the Bluetooth subsystem. The sbc.h is in include/zephyr/bluetooth now. +Tracing +======== + +* CTF: Changed uint8_t id to uint16_t id in the CTF metadata event header. This + doubles the space used for event IDs but allows 65,535 events instead of 255. + + With this change, existing CTF traces with 8-bit IDs won't be compatible. + Modules ******* From 3376da8a90a1de8c2c99ece051bf793273397e9e Mon Sep 17 00:00:00 2001 From: Ederson de Souza Date: Thu, 13 Nov 2025 10:31:38 -0800 Subject: [PATCH 0069/3659] samples/subsys/pmci/mctp: Endpoint needs to reply to host But it was sending the reply to its own endpoint ID, thus the host was ignoring it. Signed-off-by: Ederson de Souza --- samples/subsys/pmci/mctp/endpoint/src/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/subsys/pmci/mctp/endpoint/src/main.c b/samples/subsys/pmci/mctp/endpoint/src/main.c index 66a2afa465a5..c005ef4c2065 100644 --- a/samples/subsys/pmci/mctp/endpoint/src/main.c +++ b/samples/subsys/pmci/mctp/endpoint/src/main.c @@ -33,7 +33,7 @@ static void rx_message(uint8_t eid, bool tag_owner, uint8_t msg_tag, void *data, case REMOTE_HELLO_EID: LOG_INF("got mctp message %s for eid %d, replying to 5 with \"world\"", (char *)msg, eid); - mctp_message_tx(mctp_ctx, LOCAL_HELLO_EID, false, 0, "world", sizeof("world")); + mctp_message_tx(mctp_ctx, REMOTE_HELLO_EID, false, 0, "world", sizeof("world")); break; default: LOG_INF("Unknown endpoint %d", eid); From b6d0ac47dce089aaeaad0b168c8bd3e077360c43 Mon Sep 17 00:00:00 2001 From: Ederson de Souza Date: Thu, 13 Nov 2025 10:32:30 -0800 Subject: [PATCH 0070/3659] samples/subsys/pmci/mctp: Do not repeatedly start RX It only needs to be started once - all subsequent start will fail with -EBUSY and possibly print some error message. Signed-off-by: Ederson de Souza --- samples/subsys/pmci/mctp/endpoint/src/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/subsys/pmci/mctp/endpoint/src/main.c b/samples/subsys/pmci/mctp/endpoint/src/main.c index c005ef4c2065..1a19c3715401 100644 --- a/samples/subsys/pmci/mctp/endpoint/src/main.c +++ b/samples/subsys/pmci/mctp/endpoint/src/main.c @@ -58,8 +58,8 @@ int main(void) mctp_set_rx_all(mctp_ctx, rx_message, NULL); /* MCTP poll loop */ + mctp_uart_start_rx(&mctp_endpoint); while (true) { - mctp_uart_start_rx(&mctp_endpoint); k_sem_take(&mctp_rx, K_FOREVER); } From bc480ca3f42014a901fbacc4fdb7c3bc1ed291e5 Mon Sep 17 00:00:00 2001 From: Ederson de Souza Date: Thu, 13 Nov 2025 10:31:51 -0800 Subject: [PATCH 0071/3659] samples/subsys/pmci/mctp: Make host/endpoint sample messages friendly This patch achieves that by: - Waiting one second between each message sent by the host, so people can actually follow what's going on; - Wraping the content of the messages (strings "hello" and "world") in quotes, so it's clear what they are; - Toning down the logging to INF - no need for DBG; - Removing astray `\n` - LOG_XXX already takes care of that. Signed-off-by: Ederson de Souza --- samples/subsys/pmci/mctp/endpoint/prj.conf | 1 - samples/subsys/pmci/mctp/endpoint/src/main.c | 2 +- samples/subsys/pmci/mctp/host/prj.conf | 1 - samples/subsys/pmci/mctp/host/src/main.c | 6 ++++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/samples/subsys/pmci/mctp/endpoint/prj.conf b/samples/subsys/pmci/mctp/endpoint/prj.conf index 495c9ca12fa9..17deea64f6eb 100644 --- a/samples/subsys/pmci/mctp/endpoint/prj.conf +++ b/samples/subsys/pmci/mctp/endpoint/prj.conf @@ -4,5 +4,4 @@ CONFIG_MCTP=y CONFIG_MCTP_UART=y CONFIG_LOG=y CONFIG_LOG_BUFFER_SIZE=4096 -CONFIG_MCTP_LOG_LEVEL_DBG=y CONFIG_ISR_STACK_SIZE=4096 diff --git a/samples/subsys/pmci/mctp/endpoint/src/main.c b/samples/subsys/pmci/mctp/endpoint/src/main.c index 1a19c3715401..6eaa0a67193f 100644 --- a/samples/subsys/pmci/mctp/endpoint/src/main.c +++ b/samples/subsys/pmci/mctp/endpoint/src/main.c @@ -31,7 +31,7 @@ static void rx_message(uint8_t eid, bool tag_owner, uint8_t msg_tag, void *data, { switch (eid) { case REMOTE_HELLO_EID: - LOG_INF("got mctp message %s for eid %d, replying to 5 with \"world\"", (char *)msg, + LOG_INF("got mctp message \"%s\" from eid %d, replying with \"world\"", (char *)msg, eid); mctp_message_tx(mctp_ctx, REMOTE_HELLO_EID, false, 0, "world", sizeof("world")); break; diff --git a/samples/subsys/pmci/mctp/host/prj.conf b/samples/subsys/pmci/mctp/host/prj.conf index 341787ecbd3e..af10601c9772 100644 --- a/samples/subsys/pmci/mctp/host/prj.conf +++ b/samples/subsys/pmci/mctp/host/prj.conf @@ -3,6 +3,5 @@ CONFIG_SERIAL=y CONFIG_UART_ASYNC_API=y CONFIG_MCTP=y CONFIG_MCTP_UART=y -CONFIG_MCTP_LOG_LEVEL_DBG=y CONFIG_LOG=y CONFIG_LOG_BUFFER_SIZE=4096 diff --git a/samples/subsys/pmci/mctp/host/src/main.c b/samples/subsys/pmci/mctp/host/src/main.c index 8a2fd4e9e648..7b9e5112c177 100644 --- a/samples/subsys/pmci/mctp/host/src/main.c +++ b/samples/subsys/pmci/mctp/host/src/main.c @@ -25,7 +25,7 @@ K_SEM_DEFINE(mctp_rx, 0, 1); static void rx_message(uint8_t eid, bool tag_owner, uint8_t msg_tag, void *data, void *msg, size_t len) { - LOG_INF("received message %s for endpoint %d, msg_tag %d, len %zu", (char *)msg, eid, + LOG_INF("received message \"%s\" from endpoint %d, msg_tag %d, len %zu", (char *)msg, eid, msg_tag, len); k_sem_give(&mctp_rx); } @@ -48,10 +48,12 @@ int main(void) /* MCTP poll loop, send "hello" and get "world" back */ while (true) { + k_sleep(K_MSEC(1000)); + LOG_INF("Sending message \"hello\" to endpoint %d", REMOTE_HELLO_EID); rc = mctp_message_tx(mctp_ctx, REMOTE_HELLO_EID, false, 0, "hello", sizeof("hello")); if (rc != 0) { - LOG_WRN("Failed to send message, errno %d\n", rc); + LOG_WRN("Failed to send message, errno %d", rc); k_msleep(1000); } else { k_sem_take(&mctp_rx, K_MSEC(10)); From 3b38d6cc71002a9e4818f613cab8a7a62500d1d1 Mon Sep 17 00:00:00 2001 From: Jacky Lee Date: Tue, 9 Dec 2025 10:12:11 +0800 Subject: [PATCH 0072/3659] drivers: serial: ns16550: Fix TX IRQ not triggered when FIFO is empty When uart_ns16550_irq_tx_enable() is called and the TX FIFO is already empty, no new interrupt is generated, causing data transmission to stall in some cases. This patch introduces a workaround to simulate an ISR callback if the FIFO is empty when enabling the TX IRQ. Signed-off-by: Jacky Lee --- drivers/serial/Kconfig.ns16550 | 11 ++++++++ drivers/serial/uart_ns16550.c | 49 ++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/drivers/serial/Kconfig.ns16550 b/drivers/serial/Kconfig.ns16550 index 4c6676cdab64..8a36c20e4323 100644 --- a/drivers/serial/Kconfig.ns16550 +++ b/drivers/serial/Kconfig.ns16550 @@ -103,6 +103,17 @@ config UART_NS16550_WA_ISR_REENABLE_INTERRUPT the IER is being toggled to re-assert interrupts at the end of ISR to nudge the host interrupt controller to fire the ISR again. +config UART_NS16550_WA_TX_FIFO_EMPTY_INTERRUPT + bool "Callback directly when the TX FIFO is already empty" + depends on UART_INTERRUPT_DRIVEN + default y if (SHELL_BACKEND_SERIAL && SOC_EGIS_ET171) + help + When calling uart_ns16550_irq_tx_enable() to wait for the TX FIFO + ready interrupt, but this interrupt will only be triggered if the + current state is not empty. Therefore, if the current state is + empty, you need to solve this problem by calling the callback + function directly. + endmenu endif # UART_NS16550 diff --git a/drivers/serial/uart_ns16550.c b/drivers/serial/uart_ns16550.c index 66156b7cb322..46a32e896eee 100644 --- a/drivers/serial/uart_ns16550.c +++ b/drivers/serial/uart_ns16550.c @@ -370,6 +370,10 @@ struct uart_ns16550_dev_data { void *cb_data; /**< Callback function arg */ #endif +#ifdef CONFIG_UART_NS16550_WA_TX_FIFO_EMPTY_INTERRUPT + uint8_t sw_tx_irq; /**< software tx ready flag */ +#endif + #if UART_NS16550_DLF_ENABLED uint8_t dlf; /**< DLF value */ #endif @@ -966,6 +970,10 @@ static void uart_ns16550_poll_out(const struct device *dev, ns16550_outbyte(dev_cfg, THR(dev), c); +#ifdef CONFIG_UART_NS16550_WA_TX_FIFO_EMPTY_INTERRUPT + data->sw_tx_irq = 0; /**< clean up */ +#endif + k_spin_unlock(&data->lock, key); } @@ -1013,6 +1021,12 @@ static int uart_ns16550_fifo_fill(const struct device *dev, ns16550_outbyte(dev_cfg, THR(dev), tx_data[i]); } +#ifdef CONFIG_UART_NS16550_WA_TX_FIFO_EMPTY_INTERRUPT + if (i != 0) { + data->sw_tx_irq = 0; /**< clean up */ + } +#endif + k_spin_unlock(&data->lock, key); return i; @@ -1075,6 +1089,26 @@ static void uart_ns16550_irq_tx_enable(const struct device *dev) #endif ns16550_outbyte(dev_cfg, IER(dev), ns16550_inbyte(dev_cfg, IER(dev)) | IER_TBE); +#ifdef CONFIG_UART_NS16550_WA_TX_FIFO_EMPTY_INTERRUPT + if (ns16550_inbyte(dev_cfg, LSR(dev)) & LSR_THRE) { + k_spin_unlock(&data->lock, key); + /* + * The TX FIFO ready interrupt will be triggered if only if + * when the pre-state is not empty. Thus, if the pre-state is + * already empty, try to call the callback routine directly + * to resolve it. + */ + int irq_lock_key = arch_irq_lock(); + + if (data->cb && (ns16550_inbyte(dev_cfg, LSR(dev)) & LSR_THRE)) { + data->sw_tx_irq = 1; /**< set tx ready */ + data->cb(dev, data->cb_data); + } + arch_irq_unlock(irq_lock_key); + return; + } +#endif + k_spin_unlock(&data->lock, key); } @@ -1089,6 +1123,10 @@ static void uart_ns16550_irq_tx_disable(const struct device *dev) const struct uart_ns16550_dev_config * const dev_cfg = dev->config; k_spinlock_key_t key = k_spin_lock(&data->lock); +#ifdef CONFIG_UART_NS16550_WA_TX_FIFO_EMPTY_INTERRUPT + data->sw_tx_irq = 0; /**< clean up */ +#endif + ns16550_outbyte(dev_cfg, IER(dev), ns16550_inbyte(dev_cfg, IER(dev)) & (~IER_TBE)); @@ -1129,6 +1167,17 @@ static int uart_ns16550_irq_tx_ready(const struct device *dev) int ret = ((IIRC(dev) & IIR_ID) == IIR_THRE) ? 1 : 0; +#ifdef CONFIG_UART_NS16550_WA_TX_FIFO_EMPTY_INTERRUPT + if (ret == 0 && data->sw_tx_irq) { + /**< replace resoult when there is a software solution */ + const struct uart_ns16550_dev_config * const dev_cfg = dev->config; + + if (ns16550_inbyte(dev_cfg, IER(dev)) & IER_TBE) { + ret = 1; + } + } +#endif + k_spin_unlock(&data->lock, key); return ret; From e82a8a612f7f084251545d49130b0152b379e632 Mon Sep 17 00:00:00 2001 From: Lauren Murphy Date: Tue, 9 Dec 2025 09:50:40 -0800 Subject: [PATCH 0073/3659] MAINTAINERS: add laurenmurphyx64 to LLEXT Adds Lauren Murphy as a LLEXT collaborator. Signed-off-by: Lauren Murphy --- MAINTAINERS.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index d3a54df7b78d..8dbc3da1c4d1 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -3147,6 +3147,7 @@ Kernel: collaborators: - lyakh - pillo79 + - laurenmurphyx64 files: - cmake/llext-edk.cmake - samples/subsys/llext/ From d59b2a29b425fd681eaf91626e301770e361def2 Mon Sep 17 00:00:00 2001 From: Peter Mitsis Date: Fri, 5 Dec 2025 13:08:43 -0800 Subject: [PATCH 0074/3659] sys: sys_heap: Fix _system_heap type Changes the type used in _system_heap extern declarations to use k_heap instead of sys_heap. Fixes #100530 Signed-off-by: Peter Mitsis --- modules/nrf_wifi/os/shim.c | 2 +- samples/subsys/zbus/msg_subscriber/src/main.c | 7 ++++--- subsys/shell/modules/kernel_service/heap.c | 6 ++---- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/modules/nrf_wifi/os/shim.c b/modules/nrf_wifi/os/shim.c index eee7039bc06f..7fe6373b485d 100644 --- a/modules/nrf_wifi/os/shim.c +++ b/modules/nrf_wifi/os/shim.c @@ -37,7 +37,7 @@ LOG_MODULE_REGISTER(wifi_nrf, CONFIG_WIFI_NRF70_LOG_LEVEL); /* Memory pool management - unified pool-based API */ #if defined(CONFIG_NRF_WIFI_GLOBAL_HEAP) /* Use global system heap */ -extern struct sys_heap _system_heap; +extern struct k_heap _system_heap; static struct k_heap * const wifi_ctrl_pool = &_system_heap; static struct k_heap * const wifi_data_pool = &_system_heap; #else diff --git a/samples/subsys/zbus/msg_subscriber/src/main.c b/samples/subsys/zbus/msg_subscriber/src/main.c index 48ce4a016500..e82a86c5cef1 100644 --- a/samples/subsys/zbus/msg_subscriber/src/main.c +++ b/samples/subsys/zbus/msg_subscriber/src/main.c @@ -9,7 +9,7 @@ #include LOG_MODULE_REGISTER(sample, CONFIG_LOG_MAX_LEVEL); -extern struct sys_heap _system_heap; +extern struct k_heap _system_heap; static size_t total_allocated; void on_heap_alloc(uintptr_t heap_id, void *mem, size_t bytes) @@ -28,10 +28,11 @@ void on_heap_free(uintptr_t heap_id, void *mem, size_t bytes) #if defined(CONFIG_ZBUS_MSG_SUBSCRIBER_BUF_ALLOC_DYNAMIC) -HEAP_LISTENER_ALLOC_DEFINE(my_heap_listener_alloc, HEAP_ID_FROM_POINTER(&_system_heap), +HEAP_LISTENER_ALLOC_DEFINE(my_heap_listener_alloc, HEAP_ID_FROM_POINTER(&_system_heap.heap), on_heap_alloc); -HEAP_LISTENER_FREE_DEFINE(my_heap_listener_free, HEAP_ID_FROM_POINTER(&_system_heap), on_heap_free); +HEAP_LISTENER_FREE_DEFINE(my_heap_listener_free, HEAP_ID_FROM_POINTER(&_system_heap.heap), + on_heap_free); #endif /* CONFIG_ZBUS_MSG_SUBSCRIBER_BUF_ALLOC_DYNAMIC */ struct acc_msg { diff --git a/subsys/shell/modules/kernel_service/heap.c b/subsys/shell/modules/kernel_service/heap.c index 23a5ee114105..52d31e412fe5 100644 --- a/subsys/shell/modules/kernel_service/heap.c +++ b/subsys/shell/modules/kernel_service/heap.c @@ -8,9 +8,7 @@ #if K_HEAP_MEM_POOL_SIZE > 0 #include "kernel_shell.h" -#include - -extern struct sys_heap _system_heap; +extern struct k_heap _system_heap; static int cmd_kernel_heap(const struct shell *sh, size_t argc, char **argv) { @@ -20,7 +18,7 @@ static int cmd_kernel_heap(const struct shell *sh, size_t argc, char **argv) int err; struct sys_memory_stats stats; - err = sys_heap_runtime_stats_get(&_system_heap, &stats); + err = sys_heap_runtime_stats_get(&_system_heap.heap, &stats); if (err) { shell_error(sh, "Failed to read kernel system heap statistics (err %d)", err); return -ENOEXEC; From 3b39e3dca4d6cad67ac79a0740265d3dc25a0119 Mon Sep 17 00:00:00 2001 From: Sylvio Alves Date: Fri, 5 Dec 2025 17:12:37 -0300 Subject: [PATCH 0075/3659] soc: espressif: power: register power log module All power.c files in Espressif SoCs depends on un-registered soc log module. When CONFIG_LOG=y and CONFIG_LOG_DEFAULT_LEVEL=4, build fails as LOG_DBG used in those files won't have its proper declaration. Signed-off-by: Sylvio Alves --- soc/espressif/esp32/power.c | 2 +- soc/espressif/esp32c2/power.c | 2 +- soc/espressif/esp32c3/power.c | 2 +- soc/espressif/esp32c6/power.c | 2 +- soc/espressif/esp32h2/power.c | 2 +- soc/espressif/esp32s2/power.c | 2 +- soc/espressif/esp32s3/power.c | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/soc/espressif/esp32/power.c b/soc/espressif/esp32/power.c index 996ca8964f0b..48fe92409524 100644 --- a/soc/espressif/esp32/power.c +++ b/soc/espressif/esp32/power.c @@ -11,7 +11,7 @@ #include #include -LOG_MODULE_DECLARE(soc, CONFIG_SOC_LOG_LEVEL); +LOG_MODULE_REGISTER(soc_pm, CONFIG_SOC_LOG_LEVEL); static uint32_t intenable; diff --git a/soc/espressif/esp32c2/power.c b/soc/espressif/esp32c2/power.c index cd8eec723d01..b3e414116ef4 100644 --- a/soc/espressif/esp32c2/power.c +++ b/soc/espressif/esp32c2/power.c @@ -9,7 +9,7 @@ #include #include -LOG_MODULE_DECLARE(soc, CONFIG_SOC_LOG_LEVEL); +LOG_MODULE_REGISTER(soc_pm, CONFIG_SOC_LOG_LEVEL); /* Invoke Low Power/System Off specific Tasks */ void pm_state_set(enum pm_state state, uint8_t substate_id) diff --git a/soc/espressif/esp32c3/power.c b/soc/espressif/esp32c3/power.c index c11c8b90a057..77cedcca3b4f 100644 --- a/soc/espressif/esp32c3/power.c +++ b/soc/espressif/esp32c3/power.c @@ -9,7 +9,7 @@ #include #include -LOG_MODULE_DECLARE(soc, CONFIG_SOC_LOG_LEVEL); +LOG_MODULE_REGISTER(soc_pm, CONFIG_SOC_LOG_LEVEL); /* Invoke Low Power/System Off specific Tasks */ void pm_state_set(enum pm_state state, uint8_t substate_id) diff --git a/soc/espressif/esp32c6/power.c b/soc/espressif/esp32c6/power.c index b3d9782e9fe3..c72888c88948 100644 --- a/soc/espressif/esp32c6/power.c +++ b/soc/espressif/esp32c6/power.c @@ -9,7 +9,7 @@ #include #include -LOG_MODULE_DECLARE(soc, CONFIG_SOC_LOG_LEVEL); +LOG_MODULE_REGISTER(soc_pm, CONFIG_SOC_LOG_LEVEL); /* Invoke Low Power/System Off specific Tasks */ void pm_state_set(enum pm_state state, uint8_t substate_id) diff --git a/soc/espressif/esp32h2/power.c b/soc/espressif/esp32h2/power.c index cd8eec723d01..b3e414116ef4 100644 --- a/soc/espressif/esp32h2/power.c +++ b/soc/espressif/esp32h2/power.c @@ -9,7 +9,7 @@ #include #include -LOG_MODULE_DECLARE(soc, CONFIG_SOC_LOG_LEVEL); +LOG_MODULE_REGISTER(soc_pm, CONFIG_SOC_LOG_LEVEL); /* Invoke Low Power/System Off specific Tasks */ void pm_state_set(enum pm_state state, uint8_t substate_id) diff --git a/soc/espressif/esp32s2/power.c b/soc/espressif/esp32s2/power.c index 7523aa907978..993b09291610 100644 --- a/soc/espressif/esp32s2/power.c +++ b/soc/espressif/esp32s2/power.c @@ -9,7 +9,7 @@ #include #include -LOG_MODULE_DECLARE(soc, CONFIG_SOC_LOG_LEVEL); +LOG_MODULE_REGISTER(soc_pm, CONFIG_SOC_LOG_LEVEL); static uint32_t intenable; diff --git a/soc/espressif/esp32s3/power.c b/soc/espressif/esp32s3/power.c index f292774bc11a..6756574e2999 100644 --- a/soc/espressif/esp32s3/power.c +++ b/soc/espressif/esp32s3/power.c @@ -9,7 +9,7 @@ #include #include -LOG_MODULE_DECLARE(soc, CONFIG_SOC_LOG_LEVEL); +LOG_MODULE_REGISTER(soc_pm, CONFIG_SOC_LOG_LEVEL); static uint32_t intenable; From 67e6720b310bbf01f5d8daa57e0e18bcfddcc111 Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Fri, 5 Dec 2025 11:43:02 -0800 Subject: [PATCH 0076/3659] coredump: gdbstubs: x86: disable pylint duplicate code warnings This disables the duplicate code warnings on x86 and x86_64 gdbstubs. The exception vector tables may look the same now but can deviate depending on supported features on architecture. Signed-off-by: Daniel Leung --- scripts/coredump/gdbstubs/arch/x86.py | 2 ++ scripts/coredump/gdbstubs/arch/x86_64.py | 2 ++ 2 files changed, 4 insertions(+) diff --git a/scripts/coredump/gdbstubs/arch/x86.py b/scripts/coredump/gdbstubs/arch/x86.py index 64c1956db1be..8a71b9b4ed4e 100644 --- a/scripts/coredump/gdbstubs/arch/x86.py +++ b/scripts/coredump/gdbstubs/arch/x86.py @@ -3,6 +3,8 @@ # Copyright (c) 2020 Intel Corporation # # SPDX-License-Identifier: Apache-2.0 +# +# pylint: disable=duplicate-code import binascii import logging diff --git a/scripts/coredump/gdbstubs/arch/x86_64.py b/scripts/coredump/gdbstubs/arch/x86_64.py index 58faebf21330..65ae868bd767 100644 --- a/scripts/coredump/gdbstubs/arch/x86_64.py +++ b/scripts/coredump/gdbstubs/arch/x86_64.py @@ -3,6 +3,8 @@ # Copyright (c) 2020 Intel Corporation # # SPDX-License-Identifier: Apache-2.0 +# +# pylint: disable=duplicate-code import binascii import logging From 37b8402668e435f43723c8f63fa36305029f1fab Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Fri, 5 Dec 2025 10:28:35 -0800 Subject: [PATCH 0077/3659] coredump: run ruff format on scripts This is done via "ruff format" without any manual editing. Signed-off-by: Daniel Leung --- .ruff-excludes.toml | 11 --- scripts/coredump/coredump_gdbserver.py | 12 +-- .../coredump/coredump_parser/elf_parser.py | 79 +++++++++++++------ .../coredump/coredump_parser/log_parser.py | 25 +++--- .../coredump/coredump_serial_log_parser.py | 3 +- scripts/coredump/gdbstubs/arch/arm64.py | 61 +++++++------- .../coredump/gdbstubs/arch/arm_cortex_m.py | 38 +++++---- scripts/coredump/gdbstubs/arch/risc_v.py | 7 +- scripts/coredump/gdbstubs/arch/x86.py | 4 +- scripts/coredump/gdbstubs/arch/x86_64.py | 12 +-- scripts/coredump/gdbstubs/arch/xtensa.py | 33 ++++---- scripts/coredump/gdbstubs/gdbstub.py | 58 ++++++++++---- 12 files changed, 198 insertions(+), 145 deletions(-) diff --git a/.ruff-excludes.toml b/.ruff-excludes.toml index 05c5eb408ed2..2c68048e4666 100644 --- a/.ruff-excludes.toml +++ b/.ruff-excludes.toml @@ -965,17 +965,6 @@ exclude = [ "./samples/subsys/zbus/remote_mock/remote_mock.py", "./scripts/check_maintainers.py", "./scripts/ci/upload_test_results_es.py", - "./scripts/coredump/coredump_gdbserver.py", - "./scripts/coredump/coredump_parser/elf_parser.py", - "./scripts/coredump/coredump_parser/log_parser.py", - "./scripts/coredump/coredump_serial_log_parser.py", - "./scripts/coredump/gdbstubs/arch/arm64.py", - "./scripts/coredump/gdbstubs/arch/arm_cortex_m.py", - "./scripts/coredump/gdbstubs/arch/risc_v.py", - "./scripts/coredump/gdbstubs/arch/x86.py", - "./scripts/coredump/gdbstubs/arch/x86_64.py", - "./scripts/coredump/gdbstubs/arch/xtensa.py", - "./scripts/coredump/gdbstubs/gdbstub.py", "./scripts/dts/gen_defines.py", "./scripts/dts/gen_driver_kconfig_dts.py", "./scripts/dts/gen_dts_cmake.py", diff --git a/scripts/coredump/coredump_gdbserver.py b/scripts/coredump/coredump_gdbserver.py index 3ffe3d9cfb92..e6e55d2b9cd4 100755 --- a/scripts/coredump/coredump_gdbserver.py +++ b/scripts/coredump/coredump_gdbserver.py @@ -43,14 +43,10 @@ def parse_args(): parser.add_argument("elffile", help="Zephyr ELF binary") parser.add_argument("logfile", help="Coredump binary log file") - parser.add_argument("--debug", action="store_true", - help="Print extra debugging information") - parser.add_argument("--port", type=int, default=1234, - help="GDB server port") - parser.add_argument("--pipe", action="store_true", - help="Use stdio to communicate with gdb") - parser.add_argument("-v", "--verbose", action="store_true", - help="Print more information") + parser.add_argument("--debug", action="store_true", help="Print extra debugging information") + parser.add_argument("--port", type=int, default=1234, help="GDB server port") + parser.add_argument("--pipe", action="store_true", help="Use stdio to communicate with gdb") + parser.add_argument("-v", "--verbose", action="store_true", help="Print more information") return parser.parse_args() diff --git a/scripts/coredump/coredump_parser/elf_parser.py b/scripts/coredump/coredump_parser/elf_parser.py index 277c62f57469..a2cac745af5e 100644 --- a/scripts/coredump/coredump_parser/elf_parser.py +++ b/scripts/coredump/coredump_parser/elf_parser.py @@ -19,6 +19,7 @@ SHF_WRITE_ALLOC = SHF_WRITE | SHF_ALLOC SHF_ALLOC_EXEC = SHF_ALLOC | SHF_EXEC + # Must match enum in thread_info.c class ThreadInfoOffset(IntEnum): THREAD_INFO_OFFSET_VERSION = 0 @@ -44,7 +45,7 @@ def __int__(self): logger = logging.getLogger("parser") -class CoredumpElfFile(): +class CoredumpElfFile: """ Class to parse ELF file for memory content in various sections. There are read-only sections (e.g. text and rodata) where @@ -78,7 +79,11 @@ def has_kernel_thread_info(self): return self.kernel_thread_info_offsets is not None def get_kernel_thread_info_offset(self, thread_info_offset_index): - if self.has_kernel_thread_info() and thread_info_offset_index <= ThreadInfoOffset.THREAD_INFO_OFFSET_T_ARC_RELINQUISH_CAUSE: + if ( + self.has_kernel_thread_info() + and thread_info_offset_index + <= ThreadInfoOffset.THREAD_INFO_OFFSET_T_ARC_RELINQUISH_CAUSE + ): return self.kernel_thread_info_offsets[thread_info_offset_index] else: return None @@ -96,14 +101,20 @@ def parse(self): for section in self.elf.iter_sections(): # Find symbols for _kernel_thread_info data if isinstance(section, elftools.elf.sections.SymbolTableSection): - _kernel_thread_info_offsets = section.get_symbol_by_name("_kernel_thread_info_offsets") - _kernel_thread_info_num_offsets = section.get_symbol_by_name("_kernel_thread_info_num_offsets") - _kernel_thread_info_size_t_size = section.get_symbol_by_name("_kernel_thread_info_size_t_size") + _kernel_thread_info_offsets = section.get_symbol_by_name( + "_kernel_thread_info_offsets" + ) + _kernel_thread_info_num_offsets = section.get_symbol_by_name( + "_kernel_thread_info_num_offsets" + ) + _kernel_thread_info_size_t_size = section.get_symbol_by_name( + "_kernel_thread_info_size_t_size" + ) # REALLY NEED to match exact type as all other sections # (debug, text, etc.) are descendants where # isinstance() would match. - if type(section) is not elftools.elf.sections.Section: # pylint: disable=unidiomatic-typecheck + if type(section) is not elftools.elf.sections.Section: # pylint: disable=unidiomatic-typecheck continue size = section['sh_size'] @@ -132,37 +143,49 @@ def parse(self): if store: mem_region = {"start": sec_start, "end": sec_end, "data": section.data()} - logger.info("ELF Section: 0x%x to 0x%x of size %d (%s)" % - (mem_region["start"], - mem_region["end"], - len(mem_region["data"]), - sect_desc)) + logger.info( + "ELF Section: 0x%x to 0x%x of size %d (%s)" + % (mem_region["start"], mem_region["end"], len(mem_region["data"]), sect_desc) + ) self.memory_regions.append(mem_region) - if _kernel_thread_info_size_t_size is not None and \ - _kernel_thread_info_num_offsets is not None and \ - _kernel_thread_info_offsets is not None: + if ( + _kernel_thread_info_size_t_size is not None + and _kernel_thread_info_num_offsets is not None + and _kernel_thread_info_offsets is not None + ): for seg in self.elf.iter_segments(): if seg.header['p_type'] != 'PT_LOAD': continue # Store segment of kernel_thread_info_offsets info_offsets_symbol = _kernel_thread_info_offsets[0] - if info_offsets_symbol['st_value'] >= seg['p_vaddr'] and info_offsets_symbol['st_value'] < seg['p_vaddr'] + seg['p_filesz']: + if ( + info_offsets_symbol['st_value'] >= seg['p_vaddr'] + and info_offsets_symbol['st_value'] < seg['p_vaddr'] + seg['p_filesz'] + ): kernel_thread_info_offsets_segment = seg # Store segment of kernel_thread_info_num_offsets num_offsets_symbol = _kernel_thread_info_num_offsets[0] - if num_offsets_symbol['st_value'] >= seg['p_vaddr'] and num_offsets_symbol['st_value'] < seg['p_vaddr'] + seg['p_filesz']: + if ( + num_offsets_symbol['st_value'] >= seg['p_vaddr'] + and num_offsets_symbol['st_value'] < seg['p_vaddr'] + seg['p_filesz'] + ): kernel_thread_info_num_offsets_segment = seg # Read and store size_t size size_t_size_symbol = _kernel_thread_info_size_t_size[0] - if size_t_size_symbol['st_value'] >= seg['p_vaddr'] and size_t_size_symbol['st_value'] < seg['p_vaddr'] + seg['p_filesz']: + if ( + size_t_size_symbol['st_value'] >= seg['p_vaddr'] + and size_t_size_symbol['st_value'] < seg['p_vaddr'] + seg['p_filesz'] + ): offset = size_t_size_symbol['st_value'] - seg['p_vaddr'] + seg['p_offset'] self.elf.stream.seek(offset) - self.kernel_thread_info_size_t_size = struct.unpack('B', self.elf.stream.read(size_t_size_symbol['st_size']))[0] + self.kernel_thread_info_size_t_size = struct.unpack( + 'B', self.elf.stream.read(size_t_size_symbol['st_size']) + )[0] struct_format = "I" if self.kernel_thread_info_size_t_size == 8: @@ -170,9 +193,15 @@ def parse(self): # Read and store count of offset values num_offsets_symbol = _kernel_thread_info_num_offsets[0] - offset = num_offsets_symbol['st_value'] - kernel_thread_info_num_offsets_segment['p_vaddr'] + kernel_thread_info_num_offsets_segment['p_offset'] + offset = ( + num_offsets_symbol['st_value'] + - kernel_thread_info_num_offsets_segment['p_vaddr'] + + kernel_thread_info_num_offsets_segment['p_offset'] + ) self.elf.stream.seek(offset) - self.kernel_thread_info_num_offsets = struct.unpack(struct_format, self.elf.stream.read(num_offsets_symbol['st_size']))[0] + self.kernel_thread_info_num_offsets = struct.unpack( + struct_format, self.elf.stream.read(num_offsets_symbol['st_size']) + )[0] array_format = "" for _ in range(self.kernel_thread_info_num_offsets): @@ -180,8 +209,14 @@ def parse(self): # Read and store array of offset values info_offsets_symbol = _kernel_thread_info_offsets[0] - offset = info_offsets_symbol['st_value'] - kernel_thread_info_offsets_segment['p_vaddr'] + kernel_thread_info_offsets_segment['p_offset'] + offset = ( + info_offsets_symbol['st_value'] + - kernel_thread_info_offsets_segment['p_vaddr'] + + kernel_thread_info_offsets_segment['p_offset'] + ) self.elf.stream.seek(offset) - self.kernel_thread_info_offsets = struct.unpack(array_format, self.elf.stream.read(info_offsets_symbol['st_size'])) + self.kernel_thread_info_offsets = struct.unpack( + array_format, self.elf.stream.read(info_offsets_symbol['st_size']) + ) return True diff --git a/scripts/coredump/coredump_parser/log_parser.py b/scripts/coredump/coredump_parser/log_parser.py index 409ee7ff568c..ba6346512db7 100644 --- a/scripts/coredump/coredump_parser/log_parser.py +++ b/scripts/coredump/coredump_parser/log_parser.py @@ -62,7 +62,7 @@ def __init__(self, logfile): self.log_hdr = None self.arch_data = list() self.memory_regions = list() - self.threads_metadata = {"hdr_ver" : None, "data" : None} + self.threads_metadata = {"hdr_ver": None, "data": None} def open(self): self.fd = open(self.logfile, "rb") @@ -85,7 +85,7 @@ def parse_arch_section(self): arch_data = self.fd.read(num_bytes) - self.arch_data = {"hdr_ver" : hdr_ver, "data" : arch_data} + self.arch_data = {"hdr_ver": hdr_ver, "data": arch_data} return True @@ -95,7 +95,7 @@ def parse_threads_metadata_section(self): data = self.fd.read(num_bytes) - self.threads_metadata = {"hdr_ver" : hdr_ver, "data" : data} + self.threads_metadata = {"hdr_ver": hdr_ver, "data": data} return True @@ -126,8 +126,7 @@ def parse_memory_section(self): mem = {"start": saddr, "end": eaddr, "data": data} self.memory_regions.append(mem) - logger.info("Memory: 0x%x to 0x%x of size %d" % - (saddr, eaddr, size)) + logger.info("Memory: 0x%x to 0x%x of size %d" % (saddr, eaddr, size)) return True @@ -147,15 +146,15 @@ def parse(self): logger.error(f"Log version: {hdr_ver}, expected: {COREDUMP_HDR_VER}!") return False - ptr_size = 2 ** ptr_size + ptr_size = 2**ptr_size self.log_hdr = { - "hdr_version": hdr_ver, - "tgt_code": tgt_code, - "ptr_size": ptr_size, - "flags": flags, - "reason": reason, - } + "hdr_version": hdr_ver, + "tgt_code": tgt_code, + "ptr_size": ptr_size, + "flags": flags, + "reason": reason, + } logger.info("Reason: {0}".format(reason_string(reason))) logger.info(f"Pointer size {ptr_size}") @@ -168,7 +167,7 @@ def parse(self): # no more data to read break - self.fd.seek(-1, 1) # go back 1 byte + self.fd.seek(-1, 1) # go back 1 byte if section_id == COREDUMP_ARCH_HDR_ID: if not self.parse_arch_section(): logger.error("Cannot parse architecture section") diff --git a/scripts/coredump/coredump_serial_log_parser.py b/scripts/coredump/coredump_serial_log_parser.py index 43e2900c66c3..8b186ceddee0 100755 --- a/scripts/coredump/coredump_serial_log_parser.py +++ b/scripts/coredump/coredump_serial_log_parser.py @@ -20,8 +20,7 @@ def parse_args(): parser = argparse.ArgumentParser(allow_abbrev=False) parser.add_argument("infile", help="Serial Log File") - parser.add_argument("outfile", - help="Output file for use with coredump GDB server") + parser.add_argument("outfile", help="Output file for use with coredump GDB server") return parser.parse_args() diff --git a/scripts/coredump/gdbstubs/arch/arm64.py b/scripts/coredump/gdbstubs/arch/arm64.py index 7f4c03eb375e..9560146d493f 100644 --- a/scripts/coredump/gdbstubs/arch/arm64.py +++ b/scripts/coredump/gdbstubs/arch/arm64.py @@ -14,8 +14,8 @@ logger = logging.getLogger("gdbstub") -class RegNum(): - X0 = 0 # X0-X29 - 30 GP registers +class RegNum: + X0 = 0 # X0-X29 - 30 GP registers X1 = 1 X2 = 2 X3 = 3 @@ -44,14 +44,14 @@ class RegNum(): X26 = 26 X27 = 27 X28 = 28 - X29 = 29 # Frame pointer register - LR = 30 # X30 Link Register(LR) - SP_EL0 = 31 # Stack pointer EL0 (SP_EL0) - PC = 32 # Program Counter (PC) + X29 = 29 # Frame pointer register + LR = 30 # X30 Link Register(LR) + SP_EL0 = 31 # Stack pointer EL0 (SP_EL0) + PC = 32 # Program Counter (PC) class GdbStub_ARM64(GdbStub): - ARCH_DATA_BLK_STRUCT = " 1: - self.registers[RegNum.R4] = tu[9] - self.registers[RegNum.R5] = tu[10] - self.registers[RegNum.R6] = tu[11] - self.registers[RegNum.R7] = tu[12] - self.registers[RegNum.R8] = tu[13] - self.registers[RegNum.R9] = tu[14] + self.registers[RegNum.R4] = tu[9] + self.registers[RegNum.R5] = tu[10] + self.registers[RegNum.R6] = tu[11] + self.registers[RegNum.R7] = tu[12] + self.registers[RegNum.R8] = tu[13] + self.registers[RegNum.R9] = tu[14] self.registers[RegNum.R10] = tu[15] self.registers[RegNum.R11] = tu[16] @@ -121,7 +121,9 @@ def handle_register_single_write_packet(self, pkt): raise ValueError(f"Malformed register write packet: {pkt_str}") reg = int(pkt_str[1:separator_index], 16) - self.registers[reg] = int.from_bytes(binascii.unhexlify(pkt[(separator_index + 1):]), byteorder = 'little') + self.registers[reg] = int.from_bytes( + binascii.unhexlify(pkt[(separator_index + 1) :]), byteorder='little' + ) self.put_gdb_packet(b'+') def arch_supports_thread_operations(self): @@ -135,7 +137,9 @@ def handle_thread_register_group_read_packet(self): thread_ptr = self.thread_ptrs[self.selected_thread] # Get stack pointer out of thread struct - t_stack_ptr_offset = self.elffile.get_kernel_thread_info_offset(ThreadInfoOffset.THREAD_INFO_OFFSET_T_STACK_PTR) + t_stack_ptr_offset = self.elffile.get_kernel_thread_info_offset( + ThreadInfoOffset.THREAD_INFO_OFFSET_T_STACK_PTR + ) size_t_size = self.elffile.get_kernel_thread_info_size_t_size() stack_ptr_bytes = self.get_memory(thread_ptr + t_stack_ptr_offset, size_t_size) @@ -161,12 +165,18 @@ def handle_thread_register_group_read_packet(self): thread_registers[RegNum.SP] = stack_ptr + 32 # Read the exc_return value from the thread's arch struct - t_arch_offset = self.elffile.get_kernel_thread_info_offset(ThreadInfoOffset.THREAD_INFO_OFFSET_T_ARCH) - t_exc_return_offset = self.elffile.get_kernel_thread_info_offset(ThreadInfoOffset.THREAD_INFO_OFFSET_T_ARM_EXC_RETURN) + t_arch_offset = self.elffile.get_kernel_thread_info_offset( + ThreadInfoOffset.THREAD_INFO_OFFSET_T_ARCH + ) + t_exc_return_offset = self.elffile.get_kernel_thread_info_offset( + ThreadInfoOffset.THREAD_INFO_OFFSET_T_ARM_EXC_RETURN + ) # Value of 0xffffffff indicates THREAD_INFO_UNIMPLEMENTED - if t_exc_return_offset != 0xffffffff: - exc_return_bytes = self.get_memory(thread_ptr + t_arch_offset + t_exc_return_offset, 1) + if t_exc_return_offset != 0xFFFFFFFF: + exc_return_bytes = self.get_memory( + thread_ptr + t_arch_offset + t_exc_return_offset, 1 + ) exc_return = int.from_bytes(exc_return_bytes, "little") # If the bit 4 is not set, the stack frame is extended for floating point data, adjust the SP accordingly diff --git a/scripts/coredump/gdbstubs/arch/risc_v.py b/scripts/coredump/gdbstubs/arch/risc_v.py index 60c5fcdf63ab..cf1d33619653 100644 --- a/scripts/coredump/gdbstubs/arch/risc_v.py +++ b/scripts/coredump/gdbstubs/arch/risc_v.py @@ -13,7 +13,8 @@ logger = logging.getLogger("gdbstub") -class RegNum(): + +class RegNum: ZERO = 0 RA = 1 SP = 2 @@ -50,8 +51,8 @@ class RegNum(): class GdbStub_RISC_V(GdbStub): - ARCH_DATA_BLK_STRUCT = " overlays/xtensa_intel_apl/gdb/gdb/xtensa-config.c class GdbRegDef_Intel_Adsp_CAVS_Zephyr: ARCH_DATA_BLK_STRUCT_REGS = ' overlays/xtensa_dc233c/gdb/gdb/xtensa-config.c class GdbRegDef_DC233C: ARCH_DATA_BLK_STRUCT_REGS = ' thread_id: thread_info_bytes += b'name: ' thread_ptr = self.thread_ptrs[thread_id - 1] - t_name_offset = self.elffile.get_kernel_thread_info_offset(ThreadInfoOffset.THREAD_INFO_OFFSET_T_NAME) + t_name_offset = self.elffile.get_kernel_thread_info_offset( + ThreadInfoOffset.THREAD_INFO_OFFSET_T_NAME + ) thread_name_next_byte = self.get_memory(thread_ptr + t_name_offset, 1) index = 0 - while (thread_name_next_byte is not None) and (thread_name_next_byte != b'\x00'): + while (thread_name_next_byte is not None) and ( + thread_name_next_byte != b'\x00' + ): thread_info_bytes += thread_name_next_byte index += 1 - thread_name_next_byte = self.get_memory(thread_ptr + t_name_offset + index, 1) + thread_name_next_byte = self.get_memory( + thread_ptr + t_name_offset + index, 1 + ) - t_state_offset = self.elffile.get_kernel_thread_info_offset(ThreadInfoOffset.THREAD_INFO_OFFSET_T_STATE) + t_state_offset = self.elffile.get_kernel_thread_info_offset( + ThreadInfoOffset.THREAD_INFO_OFFSET_T_STATE + ) thread_state_byte = self.get_memory(thread_ptr + t_state_offset, 1) if thread_state_byte is not None: thread_state = int.from_bytes(thread_state_byte, "little") thread_info_bytes += b', state: ' + bytes(hex(thread_state), 'ascii') - t_user_options_offset = self.elffile.get_kernel_thread_info_offset(ThreadInfoOffset.THREAD_INFO_OFFSET_T_USER_OPTIONS) - thread_user_options_byte = self.get_memory(thread_ptr + t_user_options_offset, 1) + t_user_options_offset = self.elffile.get_kernel_thread_info_offset( + ThreadInfoOffset.THREAD_INFO_OFFSET_T_USER_OPTIONS + ) + thread_user_options_byte = self.get_memory( + thread_ptr + t_user_options_offset, 1 + ) if thread_user_options_byte is not None: thread_user_options = int.from_bytes(thread_user_options_byte, "little") - thread_info_bytes += b', user_options: ' + bytes(hex(thread_user_options), 'ascii') + thread_info_bytes += b', user_options: ' + bytes( + hex(thread_user_options), 'ascii' + ) - t_prio_offset = self.elffile.get_kernel_thread_info_offset(ThreadInfoOffset.THREAD_INFO_OFFSET_T_PRIO) + t_prio_offset = self.elffile.get_kernel_thread_info_offset( + ThreadInfoOffset.THREAD_INFO_OFFSET_T_PRIO + ) thread_prio_byte = self.get_memory(thread_ptr + t_prio_offset, 1) if thread_prio_byte is not None: thread_prio = int.from_bytes(thread_prio_byte, "little") From 79a5783a4b638aade7e295f7028cf225bd1ac2ad Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Fri, 5 Dec 2025 10:31:13 -0800 Subject: [PATCH 0078/3659] coredump: fix ruff warnings on top level scripts This fixes ruff warnings on top level coredump scripts. This is done via "ruff check --fix" without manual editing. Note SIM115 is not fixed yet as it requires more intrusive changes to handle opened file with context manager. Signed-off-by: Daniel Leung --- .ruff-excludes.toml | 5 ----- scripts/coredump/coredump_gdbserver.py | 5 ++--- scripts/coredump/coredump_serial_log_parser.py | 3 +-- 3 files changed, 3 insertions(+), 10 deletions(-) diff --git a/.ruff-excludes.toml b/.ruff-excludes.toml index 2c68048e4666..53a4d2336da5 100644 --- a/.ruff-excludes.toml +++ b/.ruff-excludes.toml @@ -128,9 +128,6 @@ "I001", # https://docs.astral.sh/ruff/rules/unsorted-imports "UP015", # https://docs.astral.sh/ruff/rules/redundant-open-modes ] -"./scripts/coredump/coredump_gdbserver.py" = [ - "I001", # https://docs.astral.sh/ruff/rules/unsorted-imports -] "./scripts/coredump/coredump_parser/elf_parser.py" = [ "E501", # https://docs.astral.sh/ruff/rules/line-too-long "I001", # https://docs.astral.sh/ruff/rules/unsorted-imports @@ -146,9 +143,7 @@ "UP032", # https://docs.astral.sh/ruff/rules/f-string ] "./scripts/coredump/coredump_serial_log_parser.py" = [ - "I001", # https://docs.astral.sh/ruff/rules/unsorted-imports "SIM115", # https://docs.astral.sh/ruff/rules/open-file-with-context-handler - "UP015", # https://docs.astral.sh/ruff/rules/redundant-open-modes ] "./scripts/coredump/gdbstubs/arch/arm64.py" = [ "I001", # https://docs.astral.sh/ruff/rules/unsorted-imports diff --git a/scripts/coredump/coredump_gdbserver.py b/scripts/coredump/coredump_gdbserver.py index e6e55d2b9cd4..191e27d19a58 100755 --- a/scripts/coredump/coredump_gdbserver.py +++ b/scripts/coredump/coredump_gdbserver.py @@ -10,10 +10,9 @@ import socket import sys -from coredump_parser.log_parser import CoredumpLogFile -from coredump_parser.elf_parser import CoredumpElfFile - import gdbstubs +from coredump_parser.elf_parser import CoredumpElfFile +from coredump_parser.log_parser import CoredumpLogFile LOGGING_FORMAT = "[%(levelname)s][%(name)s] %(message)s" diff --git a/scripts/coredump/coredump_serial_log_parser.py b/scripts/coredump/coredump_serial_log_parser.py index 8b186ceddee0..761fce770caf 100755 --- a/scripts/coredump/coredump_serial_log_parser.py +++ b/scripts/coredump/coredump_serial_log_parser.py @@ -8,7 +8,6 @@ import binascii import sys - COREDUMP_PREFIX_STR = "#CD:" COREDUMP_BEGIN_STR = COREDUMP_PREFIX_STR + "BEGIN#" @@ -28,7 +27,7 @@ def parse_args(): def main(): args = parse_args() - infile = open(args.infile, "r") + infile = open(args.infile) if not infile: print(f"ERROR: Cannot open input file: {args.infile}, exiting...") sys.exit(1) From 9ace08210e1deb4035675edc723b6d4370017938 Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Fri, 5 Dec 2025 10:36:37 -0800 Subject: [PATCH 0079/3659] coredump: fix ruff warnings on parser scripts This fixes ruff warnings on coredump parser scripts. Note SIM115 is not fixed yet as it requires more intrusive changes to handle opened file with context manager. Signed-off-by: Daniel Leung --- .ruff-excludes.toml | 8 -------- scripts/coredump/coredump_parser/elf_parser.py | 7 +++---- scripts/coredump/coredump_parser/log_parser.py | 5 ++--- 3 files changed, 5 insertions(+), 15 deletions(-) diff --git a/.ruff-excludes.toml b/.ruff-excludes.toml index 53a4d2336da5..fe3f2174afad 100644 --- a/.ruff-excludes.toml +++ b/.ruff-excludes.toml @@ -129,18 +129,10 @@ "UP015", # https://docs.astral.sh/ruff/rules/redundant-open-modes ] "./scripts/coredump/coredump_parser/elf_parser.py" = [ - "E501", # https://docs.astral.sh/ruff/rules/line-too-long - "I001", # https://docs.astral.sh/ruff/rules/unsorted-imports "SIM115", # https://docs.astral.sh/ruff/rules/open-file-with-context-handler - "UP031", # https://docs.astral.sh/ruff/rules/printf-string-formatting - "UP039", # https://docs.astral.sh/ruff/rules/unnecessary-class-parentheses ] "./scripts/coredump/coredump_parser/log_parser.py" = [ - "I001", # https://docs.astral.sh/ruff/rules/unsorted-imports "SIM115", # https://docs.astral.sh/ruff/rules/open-file-with-context-handler - "UP030", # https://docs.astral.sh/ruff/rules/format-literals - "UP031", # https://docs.astral.sh/ruff/rules/printf-string-formatting - "UP032", # https://docs.astral.sh/ruff/rules/f-string ] "./scripts/coredump/coredump_serial_log_parser.py" = [ "SIM115", # https://docs.astral.sh/ruff/rules/open-file-with-context-handler diff --git a/scripts/coredump/coredump_parser/elf_parser.py b/scripts/coredump/coredump_parser/elf_parser.py index a2cac745af5e..73cf7268809c 100644 --- a/scripts/coredump/coredump_parser/elf_parser.py +++ b/scripts/coredump/coredump_parser/elf_parser.py @@ -6,11 +6,10 @@ import logging import struct +from enum import IntEnum import elftools from elftools.elf.elffile import ELFFile -from enum import IntEnum - # ELF section flags SHF_WRITE = 0x1 @@ -144,8 +143,8 @@ def parse(self): if store: mem_region = {"start": sec_start, "end": sec_end, "data": section.data()} logger.info( - "ELF Section: 0x%x to 0x%x of size %d (%s)" - % (mem_region["start"], mem_region["end"], len(mem_region["data"]), sect_desc) + f'ELF Section: 0x{mem_region["start"]:x} to 0x{mem_region["end"]:x} ' + f'of size {mem_region["data"]:d} ({sect_desc:s})' ) self.memory_regions.append(mem_region) diff --git a/scripts/coredump/coredump_parser/log_parser.py b/scripts/coredump/coredump_parser/log_parser.py index ba6346512db7..45d2a0ce7e77 100644 --- a/scripts/coredump/coredump_parser/log_parser.py +++ b/scripts/coredump/coredump_parser/log_parser.py @@ -7,7 +7,6 @@ import logging import struct - # Note: keep sync with C code COREDUMP_HDR_ID = b'ZE' COREDUMP_HDR_VER = 2 @@ -126,7 +125,7 @@ def parse_memory_section(self): mem = {"start": saddr, "end": eaddr, "data": data} self.memory_regions.append(mem) - logger.info("Memory: 0x%x to 0x%x of size %d" % (saddr, eaddr, size)) + logger.info(f"Memory: 0x{saddr:x} to 0x{eaddr:x} of size {size:d}") return True @@ -156,7 +155,7 @@ def parse(self): "reason": reason, } - logger.info("Reason: {0}".format(reason_string(reason))) + logger.info(f"Reason: {reason_string(reason)}") logger.info(f"Pointer size {ptr_size}") del id1, id2, hdr_ver, tgt_code, ptr_size, flags, reason From bf44a017a62c1106ff202fb17b0d32de9364ce6d Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Fri, 5 Dec 2025 10:41:48 -0800 Subject: [PATCH 0080/3659] coredump: fix ruff warnings on gdbstuc scripts This fixes ruff warnings on coredump gdbstuc scripts. Signed-off-by: Daniel Leung --- .ruff-excludes.toml | 30 ------------------- scripts/coredump/gdbstubs/arch/arm64.py | 1 - .../coredump/gdbstubs/arch/arm_cortex_m.py | 5 ++-- scripts/coredump/gdbstubs/arch/risc_v.py | 1 - scripts/coredump/gdbstubs/arch/x86.py | 1 - scripts/coredump/gdbstubs/arch/x86_64.py | 1 - scripts/coredump/gdbstubs/arch/xtensa.py | 10 +++---- scripts/coredump/gdbstubs/gdbstub.py | 7 +++-- 8 files changed, 12 insertions(+), 44 deletions(-) diff --git a/.ruff-excludes.toml b/.ruff-excludes.toml index fe3f2174afad..57fbe6eb5646 100644 --- a/.ruff-excludes.toml +++ b/.ruff-excludes.toml @@ -137,36 +137,6 @@ "./scripts/coredump/coredump_serial_log_parser.py" = [ "SIM115", # https://docs.astral.sh/ruff/rules/open-file-with-context-handler ] -"./scripts/coredump/gdbstubs/arch/arm64.py" = [ - "I001", # https://docs.astral.sh/ruff/rules/unsorted-imports - "UP039", # https://docs.astral.sh/ruff/rules/unnecessary-class-parentheses -] -"./scripts/coredump/gdbstubs/arch/arm_cortex_m.py" = [ - "E501", # https://docs.astral.sh/ruff/rules/line-too-long - "I001", # https://docs.astral.sh/ruff/rules/unsorted-imports - "UP039", # https://docs.astral.sh/ruff/rules/unnecessary-class-parentheses -] -"./scripts/coredump/gdbstubs/arch/risc_v.py" = [ - "I001", # https://docs.astral.sh/ruff/rules/unsorted-imports - "UP039", # https://docs.astral.sh/ruff/rules/unnecessary-class-parentheses -] -"./scripts/coredump/gdbstubs/arch/x86.py" = [ - "I001", # https://docs.astral.sh/ruff/rules/unsorted-imports - "UP039", # https://docs.astral.sh/ruff/rules/unnecessary-class-parentheses -] -"./scripts/coredump/gdbstubs/arch/x86_64.py" = [ - "I001", # https://docs.astral.sh/ruff/rules/unsorted-imports - "UP039", # https://docs.astral.sh/ruff/rules/unnecessary-class-parentheses -] -"./scripts/coredump/gdbstubs/arch/xtensa.py" = [ - "I001", # https://docs.astral.sh/ruff/rules/unsorted-imports - "SIM113", # https://docs.astral.sh/ruff/rules/enumerate-for-loop - "UP031", # https://docs.astral.sh/ruff/rules/printf-string-formatting -] -"./scripts/coredump/gdbstubs/gdbstub.py" = [ - "E501", # https://docs.astral.sh/ruff/rules/line-too-long - "I001", # https://docs.astral.sh/ruff/rules/unsorted-imports -] "./scripts/dts/gen_defines.py" = [ "B007", # https://docs.astral.sh/ruff/rules/unused-loop-control-variable "E501", # https://docs.astral.sh/ruff/rules/line-too-long diff --git a/scripts/coredump/gdbstubs/arch/arm64.py b/scripts/coredump/gdbstubs/arch/arm64.py index 9560146d493f..db849a9b4caf 100644 --- a/scripts/coredump/gdbstubs/arch/arm64.py +++ b/scripts/coredump/gdbstubs/arch/arm64.py @@ -10,7 +10,6 @@ from gdbstubs.gdbstub import GdbStub - logger = logging.getLogger("gdbstub") diff --git a/scripts/coredump/gdbstubs/arch/arm_cortex_m.py b/scripts/coredump/gdbstubs/arch/arm_cortex_m.py index f4db8d490db6..310f55df70ba 100644 --- a/scripts/coredump/gdbstubs/arch/arm_cortex_m.py +++ b/scripts/coredump/gdbstubs/arch/arm_cortex_m.py @@ -9,8 +9,8 @@ import struct from coredump_parser.elf_parser import ThreadInfoOffset -from gdbstubs.gdbstub import GdbStub +from gdbstubs.gdbstub import GdbStub logger = logging.getLogger("gdbstub") @@ -179,7 +179,8 @@ def handle_thread_register_group_read_packet(self): ) exc_return = int.from_bytes(exc_return_bytes, "little") - # If the bit 4 is not set, the stack frame is extended for floating point data, adjust the SP accordingly + # If the bit 4 is not set, the stack frame is extended for floating point + # data, adjust the SP accordingly if (exc_return & (1 << 4)) == 0: thread_registers[RegNum.SP] = thread_registers[RegNum.SP] + 72 diff --git a/scripts/coredump/gdbstubs/arch/risc_v.py b/scripts/coredump/gdbstubs/arch/risc_v.py index cf1d33619653..f00c7cceaa25 100644 --- a/scripts/coredump/gdbstubs/arch/risc_v.py +++ b/scripts/coredump/gdbstubs/arch/risc_v.py @@ -10,7 +10,6 @@ from gdbstubs.gdbstub import GdbStub - logger = logging.getLogger("gdbstub") diff --git a/scripts/coredump/gdbstubs/arch/x86.py b/scripts/coredump/gdbstubs/arch/x86.py index 97c9bb851445..1d3c6f98973f 100644 --- a/scripts/coredump/gdbstubs/arch/x86.py +++ b/scripts/coredump/gdbstubs/arch/x86.py @@ -12,7 +12,6 @@ from gdbstubs.gdbstub import GdbStub - logger = logging.getLogger("gdbstub") diff --git a/scripts/coredump/gdbstubs/arch/x86_64.py b/scripts/coredump/gdbstubs/arch/x86_64.py index 0dccf4cb6a0c..c7a20694b211 100644 --- a/scripts/coredump/gdbstubs/arch/x86_64.py +++ b/scripts/coredump/gdbstubs/arch/x86_64.py @@ -12,7 +12,6 @@ from gdbstubs.gdbstub import GdbStub - logger = logging.getLogger("gdbstub") diff --git a/scripts/coredump/gdbstubs/arch/xtensa.py b/scripts/coredump/gdbstubs/arch/xtensa.py index 872fe5a6ef2c..432e0fb42649 100644 --- a/scripts/coredump/gdbstubs/arch/xtensa.py +++ b/scripts/coredump/gdbstubs/arch/xtensa.py @@ -8,8 +8,8 @@ import logging import struct import sys - from enum import Enum + from gdbstubs.gdbstub import GdbStub logger = logging.getLogger("gdbstub") @@ -155,11 +155,11 @@ def parse_arch_data_block(self): arch_data_blk = self.logfile.get_arch_data()['data'] self.version = struct.unpack('H', arch_data_blk[1:3])[0] - logger.debug("Xtensa GDB stub version: %d" % self.version) + logger.debug(f"Xtensa GDB stub version: {self.version}") # Get SOC and toolchain to get correct format for unpack self.soc = XtensaSoc(bytearray(arch_data_blk)[0]) - logger.debug("Xtensa SOC: %s" % self.soc.name) + logger.debug(f"Xtensa SOC: {self.soc.name}") if self.version >= 2: self.toolchain = XtensaToolchain(bytearray(arch_data_blk)[3]) @@ -173,7 +173,7 @@ def parse_arch_data_block(self): self.toolchain = XtensaToolchain.ZEPHYR arch_data_blk_regs = arch_data_blk[3:] - logger.debug("Xtensa toolchain: %s" % self.toolchain.name) + logger.debug(f"Xtensa toolchain: {self.toolchain.name}") self.gdb_reg_def = get_gdb_reg_definition(self.soc, self.toolchain) @@ -198,7 +198,7 @@ def map_registers(self, tu): if r == self.gdb_reg_def.RegNum.EXCCAUSE: self.exception_code = tu[i] self.registers[reg_num] = tu[i] - i += 1 + i = i + 1 def compute_signal(self): sig = self.GDB_SIGNAL_DEFAULT diff --git a/scripts/coredump/gdbstubs/gdbstub.py b/scripts/coredump/gdbstubs/gdbstub.py index bff47777af85..e5499607389d 100644 --- a/scripts/coredump/gdbstubs/gdbstub.py +++ b/scripts/coredump/gdbstubs/gdbstub.py @@ -10,7 +10,6 @@ from coredump_parser.elf_parser import ThreadInfoOffset - logger = logging.getLogger("gdbstub") @@ -213,7 +212,8 @@ def handle_general_query_packet(self, pkt): thread_count += 1 response += b"," + bytes(str(thread_count), 'ascii') - # Next walk the linked list, counting the number of threads and construct the response for qfThreadInfo along the way + # Next walk the linked list, counting the number of threads and construct + # the response for qfThreadInfo along the way t_next_thread_offset = self.elffile.get_kernel_thread_info_offset( ThreadInfoOffset.THREAD_INFO_OFFSET_T_NEXT_THREAD ) @@ -239,7 +239,8 @@ def handle_general_query_packet(self, pkt): elif pkt[0:12] == b"qsThreadInfo": self.put_gdb_packet(b"l") - # For qThreadExtraInfo, obtain a printable string description of thread attributes for the provided thread + # For qThreadExtraInfo, obtain a printable string description of thread attributes for + # the provided thread elif pkt[0:16] == b"qThreadExtraInfo": thread_info_bytes = b'' From 88cc16191b4950f8a9fa7d019a6a0be98085614e Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Mon, 1 Dec 2025 18:08:59 +0100 Subject: [PATCH 0081/3659] manifest: psa-arch-tests: support for STM32U5 and STM32WBA65 Update PSA-Arch-tests to support testing STM32U585 and STM32WBA based boards. Signed-off-by: Etienne Carriere --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 0811215b3063..48e1d5834fc4 100644 --- a/west.yml +++ b/west.yml @@ -359,7 +359,7 @@ manifest: path: modules/lib/picolibc revision: ca8b6ebba5226a75545e57a140443168a26ba664 - name: psa-arch-tests - revision: afeed6ed87146d9828e0ff862f3533790df8c421 + revision: 941cd8436a2e0f1da9d8584b83a403930826899d path: modules/tee/tf-m/psa-arch-tests groups: - testing From d41d915330d0b6ea21b273294db7dc7f1be75423 Mon Sep 17 00:00:00 2001 From: John Chung Date: Fri, 31 Oct 2025 14:24:29 -0500 Subject: [PATCH 0082/3659] pmci: mctp: Fix MCTP USB Packet Length Issue According to DSP0283 1.0.1, Length byte in MCTP over USB header fields should start from the "MCTP over USB Header" to the last byte in the "MCTP packet payload" Signed-off-by: John Chung --- samples/subsys/pmci/mctp/usb_endpoint/usb_host_tester.py | 8 ++++---- subsys/pmci/mctp/mctp_usb.c | 7 ++++--- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/samples/subsys/pmci/mctp/usb_endpoint/usb_host_tester.py b/samples/subsys/pmci/mctp/usb_endpoint/usb_host_tester.py index 6931002f9e7a..509a5299a4f3 100644 --- a/samples/subsys/pmci/mctp/usb_endpoint/usb_host_tester.py +++ b/samples/subsys/pmci/mctp/usb_endpoint/usb_host_tester.py @@ -69,14 +69,14 @@ def disconnect(self): print("Sending message with size smaller than USB FS MPS (<64b)") usb_dev.send_data( - b'\x1a\xb4\x00\x0f\x01\x0a\x14\xc0\x48\x65\x6c\x6c\x6f\x2c\x20\x4d\x43\x58\x00' + b'\x1a\xb4\x00\x13\x01\x0a\x14\xc0\x48\x65\x6c\x6c\x6f\x2c\x20\x4d\x43\x58\x00' ) response = usb_dev.receive_data() print("Received:", bytes(response)) print("Sending message spanning two USB FS packets (>64b)") usb_dev.send_data( - b'\x1a\xb4\x00\x4c\x01\x0a\x14\xc0\x48\x65\x6c\x6c\x6f\x2c\x20\x4d\x43\x58\x2e\x20' + b'\x1a\xb4\x00\x50\x01\x0a\x14\xc0\x48\x65\x6c\x6c\x6f\x2c\x20\x4d\x43\x58\x2e\x20' b'\x4c\x65\x74\x27\x73\x20\x74\x65\x73\x74\x20\x61\x20\x6d\x75\x6c\x74\x69\x2d\x70' b'\x61\x63\x6b\x65\x74\x20\x6d\x65\x73\x73\x61\x67\x65\x20\x74\x6f\x20\x73\x65\x65' b'\x20\x68\x6f\x77\x20\x79\x6f\x75\x20\x68\x61\x6e\x64\x6c\x65\x20\x69\x74\x2e\x00' @@ -86,8 +86,8 @@ def disconnect(self): print("Sending message with two MCTP messages in a single USB FS packet") usb_dev.send_data( - b'\x1a\xb4\x00\x12\x01\x0a\x14\xc0\x48\x65\x6c\x6c\x6f\x2c\x20\x4d\x43\x58\x2c\x20' - b'\x31\x00\x1a\xb4\x00\x12\x01\x0a\x14\xc0\x48\x65\x6c\x6c\x6f\x2c\x20\x4d\x43\x58' + b'\x1a\xb4\x00\x16\x01\x0a\x14\xc0\x48\x65\x6c\x6c\x6f\x2c\x20\x4d\x43\x58\x2c\x20' + b'\x31\x00\x1a\xb4\x00\x16\x01\x0a\x14\xc0\x48\x65\x6c\x6c\x6f\x2c\x20\x4d\x43\x58' b'\x2c\x20\x32\x00' ) response = usb_dev.receive_data() diff --git a/subsys/pmci/mctp/mctp_usb.c b/subsys/pmci/mctp/mctp_usb.c index 7a8712ef18ac..2b884ebda9b8 100644 --- a/subsys/pmci/mctp/mctp_usb.c +++ b/subsys/pmci/mctp/mctp_usb.c @@ -128,7 +128,7 @@ int mctp_usb_tx(struct mctp_binding *binding, struct mctp_pktbuf *pkt) usb->tx_buf[0] = MCTP_USB_DMTF_0; usb->tx_buf[1] = MCTP_USB_DMTF_1; usb->tx_buf[2] = 0; - usb->tx_buf[3] = len; + usb->tx_buf[3] = len + MCTP_USB_HEADER_SIZE; memcpy((void *)&usb->tx_buf[MCTP_USB_HEADER_SIZE], pkt->data, len); @@ -244,7 +244,8 @@ static void mctp_usb_class_out_work(struct k_work *work) } usb->rx_data_idx = 0; - usb->rx_pkt = mctp_pktbuf_alloc(&usb->binding, ctx->out_buf[i]); + usb->rx_pkt = mctp_pktbuf_alloc(&usb->binding, + ctx->out_buf[i] - MCTP_USB_HEADER_SIZE); if (usb->rx_pkt == NULL) { LOG_ERR("Could not allocate PKT buffer"); mctp_usb_reset_rx_state(usb); @@ -253,7 +254,7 @@ static void mctp_usb_class_out_work(struct k_work *work) usb->rx_state = STATE_DATA; - LOG_DBG("Expecting LEN=%d", (int)ctx->out_buf[i]); + LOG_DBG("Expecting LEN=%d", (int)ctx->out_buf[i] - MCTP_USB_HEADER_SIZE); break; } From f08ec232b2080d6cd53fffca22125b420af36bcf Mon Sep 17 00:00:00 2001 From: Zhaoxiang Jin Date: Sun, 7 Dec 2025 22:36:13 +0800 Subject: [PATCH 0083/3659] soc: lpc55xxx: update NUM_IRQS for SOC_LPC55S36 SOC_LPC55S36 has 119 IRQs. Signed-off-by: Zhaoxiang Jin --- soc/nxp/lpc/lpc55xxx/Kconfig.defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/soc/nxp/lpc/lpc55xxx/Kconfig.defconfig b/soc/nxp/lpc/lpc55xxx/Kconfig.defconfig index f100f34326aa..d3a1f30ddc7e 100644 --- a/soc/nxp/lpc/lpc55xxx/Kconfig.defconfig +++ b/soc/nxp/lpc/lpc55xxx/Kconfig.defconfig @@ -5,6 +5,7 @@ if SOC_SERIES_LPC55XXX config NUM_IRQS # must be >= the highest interrupt number used + default 119 if SOC_LPC55S36 default 60 config SYS_CLOCK_HW_CYCLES_PER_SEC From bc935705840700cea65567616d3c052e19f54460 Mon Sep 17 00:00:00 2001 From: Zhaoxiang Jin Date: Sun, 7 Dec 2025 22:41:32 +0800 Subject: [PATCH 0084/3659] drivers: clock_control_mcux_syscon: add HSCMP clock support add HSCMP clock support. Signed-off-by: Zhaoxiang Jin --- .../clock_control/clock_control_mcux_syscon.c | 18 ++++++++++++++++++ .../dt-bindings/clock/mcux_lpc_syscon_clock.h | 4 ++++ 2 files changed, 22 insertions(+) diff --git a/drivers/clock_control/clock_control_mcux_syscon.c b/drivers/clock_control/clock_control_mcux_syscon.c index 464e19457659..62817337dab9 100644 --- a/drivers/clock_control/clock_control_mcux_syscon.c +++ b/drivers/clock_control/clock_control_mcux_syscon.c @@ -176,6 +176,24 @@ static int mcux_lpc_syscon_clock_control_on(const struct device *dev, } #endif +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(hscmp0)) + if ((uint32_t)sub_system == MCUX_HSCMP0_CLK) { + CLOCK_EnableClock(kCLOCK_Hscmp0); + } +#endif + +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(hscmp1)) + if ((uint32_t)sub_system == MCUX_HSCMP1_CLK) { + CLOCK_EnableClock(kCLOCK_Hscmp1); + } +#endif + +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(hscmp2)) + if ((uint32_t)sub_system == MCUX_HSCMP2_CLK) { + CLOCK_EnableClock(kCLOCK_Hscmp2); + } +#endif + #ifdef CONFIG_SOC_FAMILY_MCXN #if DT_NODE_HAS_STATUS(DT_NODELABEL(trng), okay) if ((uint32_t)sub_system == MCUX_ELS_CLK) { 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 36c2679a43b5..1b7949707821 100644 --- a/include/zephyr/dt-bindings/clock/mcux_lpc_syscon_clock.h +++ b/include/zephyr/dt-bindings/clock/mcux_lpc_syscon_clock.h @@ -148,4 +148,8 @@ #define MCUX_MICFIL_CLK MCUX_LPC_CLK_ID(0x20, 0x00) +#define MCUX_HSCMP0_CLK MCUX_LPC_CLK_ID(0x21, 0x00) +#define MCUX_HSCMP1_CLK MCUX_LPC_CLK_ID(0x21, 0x01) +#define MCUX_HSCMP2_CLK MCUX_LPC_CLK_ID(0x21, 0x02) + #endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_MCUX_LPC_SYSCON_H_ */ From a62bf4b9788d0f3ca6018ae7eb4f93090bbc1249 Mon Sep 17 00:00:00 2001 From: Zhaoxiang Jin Date: Sun, 7 Dec 2025 22:43:09 +0800 Subject: [PATCH 0085/3659] drivers: comparator: Add high-speed comparator support Add high-speed comparator support Signed-off-by: Zhaoxiang Jin --- drivers/comparator/CMakeLists.txt | 1 + drivers/comparator/Kconfig | 1 + drivers/comparator/Kconfig.nxp_hscmp | 11 + drivers/comparator/comparator_nxp_hscmp.c | 367 ++++++++++++++++++++++ dts/bindings/comparator/nxp,hscmp.yaml | 124 ++++++++ 5 files changed, 504 insertions(+) create mode 100644 drivers/comparator/Kconfig.nxp_hscmp create mode 100644 drivers/comparator/comparator_nxp_hscmp.c create mode 100644 dts/bindings/comparator/nxp,hscmp.yaml diff --git a/drivers/comparator/CMakeLists.txt b/drivers/comparator/CMakeLists.txt index a2a2ed31b476..6802cc894c83 100644 --- a/drivers/comparator/CMakeLists.txt +++ b/drivers/comparator/CMakeLists.txt @@ -15,6 +15,7 @@ zephyr_library_sources_ifdef(CONFIG_COMPARATOR_MCUX_ACMP comparator_mcux_acmp.c) zephyr_library_sources_ifdef(CONFIG_COMPARATOR_NRF_COMP comparator_nrf_comp.c) zephyr_library_sources_ifdef(CONFIG_COMPARATOR_NRF_LPCOMP comparator_nrf_lpcomp.c) zephyr_library_sources_ifdef(CONFIG_COMPARATOR_NXP_CMP comparator_nxp_cmp.c) +zephyr_library_sources_ifdef(CONFIG_COMPARATOR_NXP_HSCMP comparator_nxp_hscmp.c) zephyr_library_sources_ifdef(CONFIG_COMPARATOR_RENESAS_RA comparator_renesas_ra.c) zephyr_library_sources_ifdef(CONFIG_COMPARATOR_RENESAS_RA_LVD comparator_renesas_ra_lvd.c) zephyr_library_sources_ifdef(CONFIG_COMPARATOR_RENESAS_RX_LVD comparator_renesas_rx_lvd.c) diff --git a/drivers/comparator/Kconfig b/drivers/comparator/Kconfig index c2e6d7ca9a55..2069bcde171e 100644 --- a/drivers/comparator/Kconfig +++ b/drivers/comparator/Kconfig @@ -26,6 +26,7 @@ rsource "Kconfig.mcux_acmp" rsource "Kconfig.nrf_comp" rsource "Kconfig.nrf_lpcomp" rsource "Kconfig.nxp_cmp" +rsource "Kconfig.nxp_hscmp" rsource "Kconfig.renesas_ra" rsource "Kconfig.renesas_rx" rsource "Kconfig.shell" diff --git a/drivers/comparator/Kconfig.nxp_hscmp b/drivers/comparator/Kconfig.nxp_hscmp new file mode 100644 index 000000000000..d1780cad3938 --- /dev/null +++ b/drivers/comparator/Kconfig.nxp_hscmp @@ -0,0 +1,11 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +config COMPARATOR_NXP_HSCMP + bool "NXP HSCMP comparator driver" + default y + depends on DT_HAS_NXP_HSCMP_ENABLED + select PINCTRL + select CLOCK_CONTROL + select RESET + select REGULATOR diff --git a/drivers/comparator/comparator_nxp_hscmp.c b/drivers/comparator/comparator_nxp_hscmp.c new file mode 100644 index 000000000000..5587c1548b25 --- /dev/null +++ b/drivers/comparator/comparator_nxp_hscmp.c @@ -0,0 +1,367 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(nxp_hscmp, CONFIG_COMPARATOR_LOG_LEVEL); + +#define DT_DRV_COMPAT nxp_hscmp + +struct nxp_hscmp_config { + HSCMP_Type *base; + bool enable_stop_mode; + bool invert_output; + bool enable_pin_out; + bool use_unfiltered_output; + bool positive_mux_is_dac; + bool negative_mux_is_dac; + uint8_t filter_count; + uint8_t filter_period; + uint8_t positive_mux_input; + uint8_t negative_mux_input; + uint8_t dac_value; + uint8_t dac_vref_source; + uint8_t hysteresis_mode; + uint8_t power_mode; + const struct device *clock_dev; + clock_control_subsys_t clock_subsys; + struct reset_dt_spec reset; + void (*irq_config_func)(const struct device *dev); + const struct pinctrl_dev_config *pcfg; + const struct device *ref_supplies; + int32_t ref_supply_val; +}; + +struct nxp_hscmp_data { + uint8_t interrupt_mask; + comparator_callback_t callback; + void *user_data; +}; + +static int nxp_hscmp_get_output(const struct device *dev) +{ + const struct nxp_hscmp_config *config = dev->config; + + return (config->base->CSR & HSCMP_CSR_COUT_MASK) ? 1 : 0; +} + +static int nxp_hscmp_set_trigger(const struct device *dev, + enum comparator_trigger trigger) +{ + const struct nxp_hscmp_config *config = dev->config; + struct nxp_hscmp_data *data = dev->data; + + config->base->IER &= ~(HSCMP_IER_CFR_IE_MASK | HSCMP_IER_CFF_IE_MASK); + data->interrupt_mask = 0U; + + switch (trigger) { + case COMPARATOR_TRIGGER_NONE: + break; + case COMPARATOR_TRIGGER_RISING_EDGE: + data->interrupt_mask = HSCMP_IER_CFR_IE_MASK; + break; + case COMPARATOR_TRIGGER_FALLING_EDGE: + data->interrupt_mask = HSCMP_IER_CFF_IE_MASK; + break; + case COMPARATOR_TRIGGER_BOTH_EDGES: + data->interrupt_mask = HSCMP_IER_CFR_IE_MASK | HSCMP_IER_CFF_IE_MASK; + break; + default: + LOG_ERR("Invalid trigger type."); + return -EINVAL; + } + + /* Clear latched status flags before enabling interrupts. */ + config->base->CSR |= (HSCMP_CSR_CFF_MASK | HSCMP_CSR_CFR_MASK); + + if ((data->interrupt_mask != 0U) && (data->callback != NULL)) { + config->base->IER |= data->interrupt_mask; + } + + return 0; +} + +static int nxp_hscmp_trigger_is_pending(const struct device *dev) +{ + const struct nxp_hscmp_config *config = dev->config; + struct nxp_hscmp_data *data = dev->data; + uint32_t status_flags; + + status_flags = config->base->CSR & (HSCMP_CSR_CFF_MASK | HSCMP_CSR_CFR_MASK); + config->base->CSR |= (HSCMP_CSR_CFF_MASK | HSCMP_CSR_CFR_MASK); + + if (((data->interrupt_mask & HSCMP_IER_CFF_IE_MASK) != 0U) && + ((status_flags & HSCMP_CSR_CFF_MASK) != 0U)) { + return 1; + } + + if (((data->interrupt_mask & HSCMP_IER_CFR_IE_MASK) != 0U) && + ((status_flags & HSCMP_CSR_CFR_MASK) != 0U)) { + return 1; + } + + return 0; +} + +static int nxp_hscmp_set_trigger_callback(const struct device *dev, + comparator_callback_t callback, + void *user_data) +{ + const struct nxp_hscmp_config *config = dev->config; + struct nxp_hscmp_data *data = dev->data; + + config->base->CCR0 &= ~HSCMP_CCR0_CMP_EN_MASK; + + data->callback = callback; + data->user_data = user_data; + + /* Clear any pending flags when (re)arming the callback. */ + config->base->CSR |= (HSCMP_CSR_CFF_MASK | HSCMP_CSR_CFR_MASK); + + if ((data->callback != NULL) && (data->interrupt_mask != 0U)) { + config->base->IER |= data->interrupt_mask; + } else { + config->base->IER &= ~(HSCMP_IER_CFR_IE_MASK | HSCMP_IER_CFF_IE_MASK); + } + + config->base->CCR0 |= HSCMP_CCR0_CMP_EN_MASK; + + return 0; +} + +static void nxp_hscmp_irq_handler(const struct device *dev) +{ + const struct nxp_hscmp_config *config = dev->config; + struct nxp_hscmp_data *data = dev->data; + + /* Clear interrupt status flags */ + config->base->CSR |= (HSCMP_CSR_CFF_MASK | HSCMP_CSR_CFR_MASK); + + if (data->callback == NULL) { + LOG_WRN("No callback can be executed."); + return; + } + + data->callback(dev, data->user_data); +} + +#if CONFIG_PM_DEVICE +static int nxp_hscmp_pm_callback(const struct device *dev, + enum pm_device_action action) +{ + const struct nxp_hscmp_config *config = dev->config; + + if (action == PM_DEVICE_ACTION_RESUME) { + config->base->CCR0 |= HSCMP_CCR0_CMP_EN_MASK; + return 0; + } + + if (action == PM_DEVICE_ACTION_SUSPEND) { + config->base->CCR0 &= ~HSCMP_CCR0_CMP_EN_MASK; + return 0; + } + + return -ENOTSUP; +} +#endif + +static int nxp_hscmp_init(const struct device *dev) +{ + const struct nxp_hscmp_config *config = dev->config; + const struct device *regulator = config->ref_supplies; + int32_t vref_uv = config->ref_supply_val * 1000; + HSCMP_Type *base = config->base; + int ret; + + if (!device_is_ready(config->clock_dev)) { + LOG_ERR("Clock device is not ready"); + return -ENODEV; + } + + ret = clock_control_on(config->clock_dev, config->clock_subsys); + if (ret != 0) { + LOG_ERR("Device clock turn on failed (%d)", ret); + return ret; + } + + if (!device_is_ready(config->reset.dev)) { + LOG_ERR("Reset device is not ready"); + return -ENODEV; + } + + ret = reset_line_assert(config->reset.dev, config->reset.id); + if (ret != 0) { + LOG_ERR("Failed to assert reset line (%d)", ret); + return ret; + } + + ret = reset_line_deassert(config->reset.dev, config->reset.id); + if (ret != 0) { + LOG_ERR("Failed to deassert reset line (%d)", ret); + return ret; + } + + ret = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT); + if (ret < 0) { + LOG_ERR("Failed to configure pins (%d)", ret); + return ret; + } + + if (regulator != NULL) { + ret = regulator_enable(regulator); + if (ret) { + LOG_ERR("Failed to enable regulator (%d)", ret); + return ret; + } + ret = regulator_set_voltage(regulator, vref_uv, vref_uv); + if (ret < 0) { + LOG_ERR("Failed to set regulator voltage (%d)", ret); + return ret; + } + } + + /* Disable comparator before configuring. */ + base->CCR0 &= ~HSCMP_CCR0_CMP_EN_MASK; + + base->CCR0 = ((base->CCR0 & ~(HSCMP_CCR0_CMP_STOP_EN_MASK)) | + HSCMP_CCR0_CMP_STOP_EN(config->enable_stop_mode ? 1U : 0U)); + + base->CCR1 = ((base->CCR1 & ~(HSCMP_CCR1_COUT_INV_MASK | HSCMP_CCR1_COUT_PEN_MASK | + HSCMP_CCR1_COUT_SEL_MASK | HSCMP_CCR1_FILT_CNT_MASK | + HSCMP_CCR1_FILT_PER_MASK | HSCMP_CCR1_SAMPLE_EN_MASK | + HSCMP_CCR1_WINDOW_EN_MASK)) | + HSCMP_CCR1_COUT_INV(config->invert_output ? 1U : 0U) | + HSCMP_CCR1_COUT_PEN(config->enable_pin_out ? 1U : 0U)); + + if (config->use_unfiltered_output) { + base->CCR1 |= HSCMP_CCR1_COUT_SEL_MASK; + } else { + base->CCR1 &= ~HSCMP_CCR1_COUT_SEL_MASK; + if (config->filter_count != 0U) { + base->CCR1 |= HSCMP_CCR1_FILT_CNT(config->filter_count); + base->CCR1 |= HSCMP_CCR1_FILT_PER(config->filter_period); + } + } + + /* Configure inputmux, input source, hysteresis, and power mode. */ + base->CCR2 = ((base->CCR2 & ~(HSCMP_CCR2_CMP_HPMD_MASK | HSCMP_CCR2_CMP_NPMD_MASK | + HSCMP_CCR2_HYSTCTR_MASK | HSCMP_CCR2_PSEL_MASK | HSCMP_CCR2_MSEL_MASK)) | + HSCMP_CCR2_PSEL(config->positive_mux_is_dac ? 5U : config->positive_mux_input) | + HSCMP_CCR2_MSEL(config->negative_mux_is_dac ? 5U : config->negative_mux_input) | + HSCMP_CCR2_HYSTCTR(config->hysteresis_mode)); + + switch (config->power_mode) { + case 1U: /* high speed */ + base->CCR2 |= HSCMP_CCR2_CMP_HPMD_MASK; + break; + case 2U: /* nano power */ + base->CCR2 |= HSCMP_CCR2_CMP_NPMD_MASK; + break; + default: /* low power */ + break; + } + + /* Configure DAC if needed. */ + base->DCR &= ~(HSCMP_DCR_DAC_EN_MASK | HSCMP_DCR_DAC_HPMD_MASK | HSCMP_DCR_VRSEL_MASK | + HSCMP_DCR_DAC_DATA_MASK); + + if (config->positive_mux_is_dac || config->negative_mux_is_dac) { + base->DCR |= (HSCMP_DCR_VRSEL(config->dac_vref_source) | + HSCMP_DCR_DAC_DATA(config->dac_value) | HSCMP_DCR_DAC_EN_MASK); + } + + /* Clear status flags before enabling interrupts or the comparator. */ + base->CSR = (HSCMP_CSR_CFF_MASK | HSCMP_CSR_CFR_MASK); + base->IER &= ~(HSCMP_IER_CFR_IE_MASK | HSCMP_IER_CFF_IE_MASK); + + config->irq_config_func(dev); + + base->CCR0 |= HSCMP_CCR0_CMP_EN_MASK; + +#if CONFIG_PM_DEVICE + return pm_device_driver_init(dev, nxp_hscmp_pm_callback); +#else + return 0; +#endif +} + +static DEVICE_API(comparator, nxp_hscmp_api) = { + .get_output = nxp_hscmp_get_output, + .set_trigger = nxp_hscmp_set_trigger, + .set_trigger_callback = nxp_hscmp_set_trigger_callback, + .trigger_is_pending = nxp_hscmp_trigger_is_pending, +}; + +#define HSCMP_DT_ENUM_IDX(inst, prop, default_val) \ + DT_ENUM_IDX_OR(DT_DRV_INST(inst), prop, default_val) + +#define HSCMP_DT_MUX_IS_DAC(inst, prop) DT_ENUM_HAS_VALUE(DT_DRV_INST(inst), prop, dac) +#define HSCMP_DT_MUX_IDX(inst, prop) HSCMP_DT_ENUM_IDX(inst, prop, 0) + +#if CONFIG_PM_DEVICE +#define HSCMP_PM_DEVICE_DEFINE PM_DEVICE_DT_INST_DEFINE(inst, nxp_hscmp_pm_callback); +#define HSCMP_PM_DEVICE_GET PM_DEVICE_DT_INST_GET(inst) +#else +#define HSCMP_PM_DEVICE_DEFINE +#define HSCMP_PM_DEVICE_GET NULL +#endif + +#define NXP_HSCMP_DEVICE_INIT(inst) \ + PINCTRL_DT_INST_DEFINE(inst); \ + \ + static struct nxp_hscmp_data _CONCAT(data, inst) = { \ + .interrupt_mask = 0U, \ + }; \ + \ + HSCMP_PM_DEVICE_DEFINE \ + \ + static void _CONCAT(nxp_hscmp_irq_config, inst)(const struct device *dev) \ + { \ + IRQ_CONNECT(DT_INST_IRQN(inst), DT_INST_IRQ(inst, priority), \ + nxp_hscmp_irq_handler, DEVICE_DT_INST_GET(inst), 0); \ + irq_enable(DT_INST_IRQN(inst)); \ + } \ + \ + static const struct nxp_hscmp_config _CONCAT(config, inst) = { \ + .base = (HSCMP_Type *)DT_INST_REG_ADDR(inst), \ + .enable_stop_mode = DT_INST_PROP(inst, enable_stop_mode), \ + .invert_output = DT_INST_PROP(inst, invert_output), \ + .enable_pin_out = DT_INST_PROP(inst, enable_pin_out), \ + .use_unfiltered_output = DT_INST_PROP(inst, use_unfiltered_output), \ + .filter_count = DT_INST_PROP_OR(inst, filter_count, 0), \ + .filter_period = DT_INST_PROP_OR(inst, filter_period, 0), \ + .positive_mux_is_dac = HSCMP_DT_MUX_IS_DAC(inst, positive_mux_input), \ + .negative_mux_is_dac = HSCMP_DT_MUX_IS_DAC(inst, negative_mux_input), \ + .positive_mux_input = HSCMP_DT_MUX_IDX(inst, positive_mux_input), \ + .negative_mux_input = HSCMP_DT_MUX_IDX(inst, negative_mux_input), \ + .dac_value = DT_INST_PROP_OR(inst, dac_value, 0), \ + .dac_vref_source = HSCMP_DT_ENUM_IDX(inst, dac_vref_source, 0), \ + .hysteresis_mode = DT_INST_ENUM_IDX_OR(inst, hysteresis_mode, 0), \ + .power_mode = HSCMP_DT_ENUM_IDX(inst, power_mode, 0), \ + .clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(inst)), \ + .clock_subsys = (clock_control_subsys_t)DT_INST_CLOCKS_CELL(inst, name), \ + .reset = RESET_DT_SPEC_INST_GET(inst), \ + .irq_config_func = _CONCAT(nxp_hscmp_irq_config, inst), \ + .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(inst), \ + .ref_supplies = COND_CODE_1(DT_INST_NODE_HAS_PROP(inst, nxp_references), \ + (DEVICE_DT_GET(DT_INST_PHANDLE(inst, nxp_references))), (NULL)), \ + .ref_supply_val = COND_CODE_1(DT_INST_NODE_HAS_PROP(inst, nxp_references), \ + (DT_INST_PHA(inst, nxp_references, vref_mv)), (0)), \ + }; \ + \ + DEVICE_DT_INST_DEFINE(inst, nxp_hscmp_init, HSCMP_PM_DEVICE_GET, \ + &_CONCAT(data, inst), &_CONCAT(config, inst), POST_KERNEL, \ + CONFIG_COMPARATOR_INIT_PRIORITY, &nxp_hscmp_api); + +DT_INST_FOREACH_STATUS_OKAY(NXP_HSCMP_DEVICE_INIT) diff --git a/dts/bindings/comparator/nxp,hscmp.yaml b/dts/bindings/comparator/nxp,hscmp.yaml new file mode 100644 index 000000000000..a1f819f3837f --- /dev/null +++ b/dts/bindings/comparator/nxp,hscmp.yaml @@ -0,0 +1,124 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +description: | + NXP High Speed Comparator (HSCMP) + +compatible: "nxp,hscmp" + +include: + - base.yaml + - pinctrl-device.yaml + - reset-device.yaml + +properties: + reg: + required: true + + interrupts: + required: true + + clocks: + required: true + + resets: + required: true + + power-mode: + type: string + enum: + - "low_speed" + - "high_speed" + - "nano_power" + description: | + Select comparator power/speed mode. + + hysteresis-mode: + type: string + enum: + - "LEVEL0" + - "LEVEL1" + - "LEVEL2" + - "LEVEL3" + description: | + Comparator hysteresis level. + + enable-stop-mode: + type: boolean + description: | + Allow the comparator to remain enabled in STOP mode. + + invert-output: + type: boolean + description: | + Invert comparator output. + + enable-pin-out: + type: boolean + description: | + Drive comparator output on the associated pin. + + use-unfiltered-output: + type: boolean + description: | + Route unfiltered comparator output to COUT. + When false, the filtered output is used and filter parameters + are taken from filter-count and filter-period. + + filter-count: + type: int + enum: [0, 1, 2, 3, 4, 5, 6, 7] + description: | + Number of consecutive samples that must agree before updating + the filtered output. Set to 0 to bypass the filter. + + filter-period: + type: int + description: | + Sampling period for the filter in bus clock cycles. + Valid range: 0 - 255. + + dac-vref-source: + type: string + enum: + - "VREFH0" + - "VREFH1" + description: | + DAC reference high-voltage source selection. + + dac-value: + type: int + description: | + 8-bit DAC code used when an input channel is set to DAC output. + Valid range: 0 - 255. + + positive-mux-input: + type: string + enum: + - "IN0" + - "IN1" + - "IN2" + - "IN3" + - "IN4" + - "IN5" + - "DAC" + description: | + Positive input multiplexer selection. "DAC" routes the internal DAC output. + + negative-mux-input: + type: string + enum: + - "IN0" + - "IN1" + - "IN2" + - "IN3" + - "IN4" + - "IN5" + - "DAC" + description: | + Negative input multiplexer selection. "DAC" routes the internal DAC output. + + nxp,references: + type: phandle-array + description: | + References to required regulators which must be enabled for HSCMP to function From d17a9659ea91ceab56bbb683442fb84ea4ed9bab Mon Sep 17 00:00:00 2001 From: Zhaoxiang Jin Date: Sun, 7 Dec 2025 22:45:36 +0800 Subject: [PATCH 0086/3659] boards: lpcxpresso55s36: enable hscmp for lpc55s36 enable hscmp for lpc55s36 Signed-off-by: Zhaoxiang Jin --- .../lpcxpresso55s36-pinctrl.dtsi | 8 +++++ .../nxp/lpcxpresso55s36/lpcxpresso55s36.dts | 6 ++++ .../nxp/lpcxpresso55s36/lpcxpresso55s36.yaml | 1 + dts/arm/nxp/nxp_lpc55S3x_common.dtsi | 30 +++++++++++++++++++ soc/nxp/lpc/lpc55xxx/soc.c | 21 +++++++++++++ 5 files changed, 66 insertions(+) diff --git a/boards/nxp/lpcxpresso55s36/lpcxpresso55s36-pinctrl.dtsi b/boards/nxp/lpcxpresso55s36/lpcxpresso55s36-pinctrl.dtsi index 306da273f3c1..d3ba959c8abe 100644 --- a/boards/nxp/lpcxpresso55s36/lpcxpresso55s36-pinctrl.dtsi +++ b/boards/nxp/lpcxpresso55s36/lpcxpresso55s36-pinctrl.dtsi @@ -135,4 +135,12 @@ nxp,analog-mode; }; }; + + pinmux_hscmp0: pinmux_hscmp0 { + group0 { + pinmux = ; + slew-rate = "standard"; + nxp,analog-mode; + }; + }; }; diff --git a/boards/nxp/lpcxpresso55s36/lpcxpresso55s36.dts b/boards/nxp/lpcxpresso55s36/lpcxpresso55s36.dts index 46da74e55e31..605286d746f5 100644 --- a/boards/nxp/lpcxpresso55s36/lpcxpresso55s36.dts +++ b/boards/nxp/lpcxpresso55s36/lpcxpresso55s36.dts @@ -214,3 +214,9 @@ zephyr_udc0: &usbfs { pinctrl-0 = <&pinmux_opamp0>; pinctrl-names = "default"; }; + +&hscmp0 { + status = "okay"; + pinctrl-0 = <&pinmux_hscmp0>; + pinctrl-names = "default"; +}; diff --git a/boards/nxp/lpcxpresso55s36/lpcxpresso55s36.yaml b/boards/nxp/lpcxpresso55s36/lpcxpresso55s36.yaml index 68c9e00555b0..1cbf188bbf4c 100644 --- a/boards/nxp/lpcxpresso55s36/lpcxpresso55s36.yaml +++ b/boards/nxp/lpcxpresso55s36/lpcxpresso55s36.yaml @@ -23,4 +23,5 @@ supported: - pwm - usb_device - usbd + - comparator vendor: nxp diff --git a/dts/arm/nxp/nxp_lpc55S3x_common.dtsi b/dts/arm/nxp/nxp_lpc55S3x_common.dtsi index f75ae4398017..8c70c28551d9 100644 --- a/dts/arm/nxp/nxp_lpc55S3x_common.dtsi +++ b/dts/arm/nxp/nxp_lpc55S3x_common.dtsi @@ -312,6 +312,36 @@ clocks = <&syscon MCUX_LPADC1_CLK>; }; + hscmp0: comparator@b3000 { + compatible = "nxp,hscmp"; + reg = <0xb3000 0x1000>; + interrupts = <77 0>; + clocks = <&syscon MCUX_HSCMP0_CLK>; + resets = <&reset NXP_SYSCON_RESET(3, 15)>; + status = "disabled"; + nxp,references = <&vref0 1800>; + }; + + hscmp1: comparator@b7000 { + compatible = "nxp,hscmp"; + reg = <0xb7000 0x1000>; + interrupts = <78 0>; + clocks = <&syscon MCUX_HSCMP1_CLK>; + resets = <&reset NXP_SYSCON_RESET(3, 16)>; + status = "disabled"; + nxp,references = <&vref0 1800>; + }; + + hscmp2: comparator@ba000 { + compatible = "nxp,hscmp"; + reg = <0xba000 0x1000>; + interrupts = <79 0>; + clocks = <&syscon MCUX_HSCMP2_CLK>; + resets = <&reset NXP_SYSCON_RESET(3, 17)>; + status = "disabled"; + nxp,references = <&vref0 1800>; + }; + opamp0: opamp@b4000 { compatible = "nxp,opamp"; reg = <0xb4000 0x1000>; diff --git a/soc/nxp/lpc/lpc55xxx/soc.c b/soc/nxp/lpc/lpc55xxx/soc.c index 100569953286..cbf7474d2a9e 100644 --- a/soc/nxp/lpc/lpc55xxx/soc.c +++ b/soc/nxp/lpc/lpc55xxx/soc.c @@ -444,6 +444,27 @@ DT_FOREACH_STATUS_OKAY(nxp_ctimer_pwm, CTIMER_CLOCK_SETUP) SYSCON->MCLKDIV = SYSCON_MCLKDIV_DIV(0U); SYSCON->MCLKIO = 1U; #endif /* CONFIG_AUDIO_CODEC_WM8904 */ + +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(hscmp0)) + POWER_DisablePD(kPDRUNCFG_PD_VREF); + POWER_DisablePD(kPDRUNCFG_PD_CMPBIAS); + POWER_DisablePD(kPDRUNCFG_PD_HSCMP0); + POWER_DisablePD(kPDRUNCFG_PD_HSCMP0_DAC); +#endif + +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(hscmp1)) + POWER_DisablePD(kPDRUNCFG_PD_VREF); + POWER_DisablePD(kPDRUNCFG_PD_CMPBIAS); + POWER_DisablePD(kPDRUNCFG_PD_HSCMP1); + POWER_DisablePD(kPDRUNCFG_PD_HSCMP1_DAC); +#endif + +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(hscmp2)) + POWER_DisablePD(kPDRUNCFG_PD_VREF); + POWER_DisablePD(kPDRUNCFG_PD_CMPBIAS); + POWER_DisablePD(kPDRUNCFG_PD_HSCMP2); + POWER_DisablePD(kPDRUNCFG_PD_HSCMP2_DAC); +#endif } /** From 6e51add741a51447ffa576dc23a9c036dd1e807e Mon Sep 17 00:00:00 2001 From: Zhaoxiang Jin Date: Sun, 7 Dec 2025 22:46:41 +0800 Subject: [PATCH 0087/3659] tests: comparator: enable gpio_loopback for lpcxpresso55s36 enable gpio_loopback for lpcxpresso55s36 Signed-off-by: Zhaoxiang Jin --- .../boards/lpcxpresso55s36.overlay | 25 +++++++++++++++++++ .../comparator/gpio_loopback/testcase.yaml | 3 +++ 2 files changed, 28 insertions(+) create mode 100644 tests/drivers/comparator/gpio_loopback/boards/lpcxpresso55s36.overlay diff --git a/tests/drivers/comparator/gpio_loopback/boards/lpcxpresso55s36.overlay b/tests/drivers/comparator/gpio_loopback/boards/lpcxpresso55s36.overlay new file mode 100644 index 000000000000..523930ba39d9 --- /dev/null +++ b/tests/drivers/comparator/gpio_loopback/boards/lpcxpresso55s36.overlay @@ -0,0 +1,25 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/ { + aliases { + test-comp = &hscmp0; + }; + + zephyr,user { + /* P0-10 (LPC55S36-EVK J9-7) output connect to P1-5 (LPC55S36-EVK J9-9). */ + test-gpios = <&gpio0 10 GPIO_ACTIVE_HIGH>; + }; +}; + +&hscmp0 { + positive-mux-input = "IN3"; + negative-mux-input = "DAC"; + dac-vref-source = "VREFH1"; + dac-value = <127>; +}; diff --git a/tests/drivers/comparator/gpio_loopback/testcase.yaml b/tests/drivers/comparator/gpio_loopback/testcase.yaml index 0af23dcb7ee1..0ff7b7061cec 100644 --- a/tests/drivers/comparator/gpio_loopback/testcase.yaml +++ b/tests/drivers/comparator/gpio_loopback/testcase.yaml @@ -44,3 +44,6 @@ tests: platform_allow: - nucleo_h745zi_q/stm32h745xx/m7 - nucleo_g474re/stm32g474xx + drivers.comparator.gpio_loopback.nxp_hscmp: + platform_allow: + - lpcxpresso55s36 From ef85dbe085f5a05a7acfb5605227981128bff320 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20K=C3=A4sser?= Date: Sun, 7 Dec 2025 12:06:20 +0100 Subject: [PATCH 0088/3659] drivers: sensor: adxl345: add device PM support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add support for the Zephyr device power management framework to enable runtime power control of the ADXL345 accelerometer. This implementation adds a pm_device_action callback that handles SUSPEND and RESUME actions. When suspended, the sensor enters standby mode for low power operation. On resume, it returns to measurement mode. The implementation follows the standard pattern used by other sensor drivers (lis2dh, bme280, vcnl4040) and integrates with the PM_DEVICE_DT_INST_DEFINE macro for automatic PM setup. Tested on nRF52832 with CONFIG_PM_DEVICE enabled. Signed-off-by: Tobias Kässer --- drivers/sensor/adi/adxl345/adxl345.c | 35 +++++++++++++++++++++++++++- drivers/sensor/adi/adxl345/adxl345.h | 1 + 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/drivers/sensor/adi/adxl345/adxl345.c b/drivers/sensor/adi/adxl345/adxl345.c index 4ead4f5867b2..6c203f755d7d 100644 --- a/drivers/sensor/adi/adxl345/adxl345.c +++ b/drivers/sensor/adi/adxl345/adxl345.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include "adxl345.h" @@ -472,6 +473,9 @@ static int adxl345_init(const struct device *dev) return -EIO; } + /* Initialize op_mode to reflect current state */ + data->op_mode = ADXL345_MEASURE; + #ifdef CONFIG_ADXL345_TRIGGER rc = adxl345_init_interrupt(dev); if (rc < 0) { @@ -500,6 +504,34 @@ static int adxl345_init(const struct device *dev) return 0; } +#ifdef CONFIG_PM_DEVICE +static int adxl345_pm_action(const struct device *dev, + enum pm_device_action action) +{ + struct adxl345_dev_data *data = dev->data; + int rc; + + switch (action) { + case PM_DEVICE_ACTION_RESUME: + /* Resume to measurement mode */ + rc = adxl345_set_op_mode(dev, ADXL345_MEASURE); + if (rc == 0) { + data->op_mode = ADXL345_MEASURE; + } + return rc; + case PM_DEVICE_ACTION_SUSPEND: + /* Enter standby mode for low power */ + rc = adxl345_set_op_mode(dev, ADXL345_STANDBY); + if (rc == 0) { + data->op_mode = ADXL345_STANDBY; + } + return rc; + default: + return -ENOTSUP; + } +} +#endif /* CONFIG_PM_DEVICE */ + #ifdef CONFIG_ADXL345_TRIGGER #define ADXL345_CFG_IRQ(inst) \ @@ -604,7 +636,8 @@ static int adxl345_init(const struct device *dev) COND_CODE_1(DT_INST_ON_BUS(inst, spi), (ADXL345_CONFIG_SPI(inst)), \ (ADXL345_CONFIG_I2C(inst))); \ \ - SENSOR_DEVICE_DT_INST_DEFINE(inst, adxl345_init, NULL, \ + PM_DEVICE_DT_INST_DEFINE(inst, adxl345_pm_action); \ + SENSOR_DEVICE_DT_INST_DEFINE(inst, adxl345_init, PM_DEVICE_DT_INST_GET(inst), \ &adxl345_data_##inst, &adxl345_config_##inst, POST_KERNEL, \ CONFIG_SENSOR_INIT_PRIORITY, &adxl345_api_funcs); diff --git a/drivers/sensor/adi/adxl345/adxl345.h b/drivers/sensor/adi/adxl345/adxl345.h index 4a7ebea3ba1b..845384caedd4 100644 --- a/drivers/sensor/adi/adxl345/adxl345.h +++ b/drivers/sensor/adi/adxl345/adxl345.h @@ -170,6 +170,7 @@ struct adxl345_dev_data { uint8_t is_full_res; uint8_t selected_range; enum adxl345_odr odr; + enum adxl345_op_mode op_mode; #ifdef CONFIG_ADXL345_TRIGGER struct gpio_callback gpio_cb; From 5f3f4e7285b0530ec979b3be71fbbcf1b76731ad Mon Sep 17 00:00:00 2001 From: Marek Matej Date: Sat, 6 Dec 2025 19:25:41 +0000 Subject: [PATCH 0089/3659] drivers: flash: Fix flash host type for CI builds This fixes the APPCPU synthetic builds. Signed-off-by: Marek Matej --- drivers/flash/Kconfig.esp32 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/flash/Kconfig.esp32 b/drivers/flash/Kconfig.esp32 index e1b81069200c..882c531da5f1 100644 --- a/drivers/flash/Kconfig.esp32 +++ b/drivers/flash/Kconfig.esp32 @@ -61,7 +61,7 @@ config ESP_FLASH_ASYNC_IPM config ESP_FLASH_REMOTE bool "Remote IPM flash driver" - default y if (SOC_ESP32_APPCPU || SOC_ESP32S3_APPCPU || SOC_ESP32C6_LPCORE) + default y if (SOC_ESP32_APPCPU || SOC_ESP32S3_APPCPU || SOC_ESP32C6_LPCORE) && (IPM || MBOX) config ESP_FLASH_HOST bool "Host functionality flash driver" From 00b051dd7693114bbdc8216c3dea9749758f7dd9 Mon Sep 17 00:00:00 2001 From: Pieter De Gendt Date: Sat, 6 Dec 2025 16:32:59 +0100 Subject: [PATCH 0090/3659] drivers: ethernet: sensry: Fix phy handle instance Fix ethernet PHY handle in case of multiple instances. Signed-off-by: Pieter De Gendt --- drivers/ethernet/eth_sensry_sy1xx_mac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ethernet/eth_sensry_sy1xx_mac.c b/drivers/ethernet/eth_sensry_sy1xx_mac.c index e77a77576df4..29e47e2ae397 100644 --- a/drivers/ethernet/eth_sensry_sy1xx_mac.c +++ b/drivers/ethernet/eth_sensry_sy1xx_mac.c @@ -571,7 +571,7 @@ const struct ethernet_api sy1xx_mac_driver_api = { .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ .promiscuous_mode = DT_INST_PROP_OR(n, promiscuous_mode, false), \ .use_zephyr_random_mac = DT_INST_PROP(n, zephyr_random_mac_address), \ - .phy_dev = DEVICE_DT_GET(DT_INST_PHANDLE(0, phy_handle))}; \ + .phy_dev = DEVICE_DT_GET(DT_INST_PHANDLE(n, phy_handle))}; \ \ static struct sy1xx_mac_dma_buffers __attribute__((section(".udma_access"))) \ __aligned(4) sy1xx_mac_dma_buffers_##n; \ From f75ba50de6b6735e6bb70fcb804ca49970c5128b Mon Sep 17 00:00:00 2001 From: Pieter De Gendt Date: Sat, 6 Dec 2025 16:40:02 +0100 Subject: [PATCH 0091/3659] drivers: ethernet: sensry: Support MAC address config Update the sensry,sy1xx-mac driver to use a MAC address configuration struct. Signed-off-by: Pieter De Gendt --- drivers/ethernet/eth_sensry_sy1xx_mac.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/drivers/ethernet/eth_sensry_sy1xx_mac.c b/drivers/ethernet/eth_sensry_sy1xx_mac.c index 29e47e2ae397..b151ac1773c4 100644 --- a/drivers/ethernet/eth_sensry_sy1xx_mac.c +++ b/drivers/ethernet/eth_sensry_sy1xx_mac.c @@ -59,8 +59,8 @@ struct sy1xx_mac_dev_config { uint32_t base_addr; /* optional - enable promiscuous mode */ bool promiscuous_mode; - /* optional - random mac */ - bool use_zephyr_random_mac; + + struct net_eth_mac_config mcfg; /* phy config */ const struct device *phy_dev; @@ -203,13 +203,6 @@ static int sy1xx_mac_start(const struct device *dev) sys_write32(0x0001, cfg->ctrl_addr + SY1XX_MAC_CTRL_REG); sys_write32(0x0000, cfg->ctrl_addr + SY1XX_MAC_CTRL_REG); - if (cfg->use_zephyr_random_mac) { - /* prio 1 -- generate random, if set in device tree */ - sys_rand_get(&data->mac_addr, 6); - /* Set MAC address locally administered, unicast (LAA) */ - data->mac_addr[0] |= 0x02; - } - sy1xx_mac_set_mac_addr(dev); sy1xx_mac_set_promiscuous_mode(dev, cfg->promiscuous_mode); @@ -315,6 +308,8 @@ static void sy1xx_mac_iface_init(struct net_if *iface) data->iface = iface; + (void)net_eth_mac_load(&cfg->mcfg, data->mac_addr); + ethernet_init(iface); if (device_is_ready(cfg->phy_dev)) { @@ -570,14 +565,13 @@ const struct ethernet_api sy1xx_mac_driver_api = { .base_addr = DT_INST_REG_ADDR_BY_NAME(n, data), \ .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ .promiscuous_mode = DT_INST_PROP_OR(n, promiscuous_mode, false), \ - .use_zephyr_random_mac = DT_INST_PROP(n, zephyr_random_mac_address), \ + .mcfg = NET_ETH_MAC_DT_INST_CONFIG_INIT(n), \ .phy_dev = DEVICE_DT_GET(DT_INST_PHANDLE(n, phy_handle))}; \ \ static struct sy1xx_mac_dma_buffers __attribute__((section(".udma_access"))) \ __aligned(4) sy1xx_mac_dma_buffers_##n; \ \ static struct sy1xx_mac_dev_data sy1xx_mac_dev_data##n = { \ - .mac_addr = DT_INST_PROP_OR(n, local_mac_address, {0}), \ .dma_buffers = &sy1xx_mac_dma_buffers_##n, \ }; \ \ From 7fc2f421a4fad1cf6f38d56747130d4d01c7ad6e Mon Sep 17 00:00:00 2001 From: Tim Pambor Date: Sat, 6 Dec 2025 10:35:25 +0100 Subject: [PATCH 0092/3659] dts: arm: st: add reset for lptim Add resets property to lptim binding and define resets for all lptim instances in device tree files for STM32 MCUs. Signed-off-by: Tim Pambor --- dts/arm/st/g0/stm32g0.dtsi | 1 + dts/arm/st/g4/stm32g4.dtsi | 1 + dts/arm/st/h5/stm32h5.dtsi | 2 ++ dts/arm/st/h5/stm32h562.dtsi | 4 ++++ dts/arm/st/h7/stm32h7.dtsi | 1 + dts/arm/st/h7rs/stm32h7rs.dtsi | 1 + dts/arm/st/l0/stm32l0.dtsi | 1 + dts/arm/st/l4/stm32l4.dtsi | 2 ++ dts/arm/st/l5/stm32l5.dtsi | 1 + dts/arm/st/u0/stm32u0.dtsi | 2 ++ dts/arm/st/u0/stm32u073.dtsi | 1 + dts/arm/st/u5/stm32u5.dtsi | 4 ++++ dts/arm/st/wb/stm32wb.dtsi | 1 + dts/arm/st/wba/stm32wba.dtsi | 2 ++ dts/arm/st/wl/stm32wl.dtsi | 1 + dts/bindings/timer/st,stm32-lptim.yaml | 2 -- 16 files changed, 25 insertions(+), 2 deletions(-) diff --git a/dts/arm/st/g0/stm32g0.dtsi b/dts/arm/st/g0/stm32g0.dtsi index dc80d3e7fd37..4763ce6b1837 100644 --- a/dts/arm/st/g0/stm32g0.dtsi +++ b/dts/arm/st/g0/stm32g0.dtsi @@ -259,6 +259,7 @@ lptim1: timers@40007c00 { compatible = "st,stm32-lptim"; clocks = <&rcc STM32_CLOCK(APB1, 31)>; + resets = <&rctl STM32_RESET(APB1L, 31)>; #address-cells = <1>; #size-cells = <0>; reg = <0x40007c00 0x400>; diff --git a/dts/arm/st/g4/stm32g4.dtsi b/dts/arm/st/g4/stm32g4.dtsi index db6fdb69828e..e9f1c6b989aa 100644 --- a/dts/arm/st/g4/stm32g4.dtsi +++ b/dts/arm/st/g4/stm32g4.dtsi @@ -416,6 +416,7 @@ lptim1: timers@40007c00 { compatible = "st,stm32-lptim"; clocks = <&rcc STM32_CLOCK(APB1, 31)>; + resets = <&rctl STM32_RESET(APB1L, 31)>; #address-cells = <1>; #size-cells = <0>; reg = <0x40007c00 0x400>; diff --git a/dts/arm/st/h5/stm32h5.dtsi b/dts/arm/st/h5/stm32h5.dtsi index 292af871786e..df4223b03662 100644 --- a/dts/arm/st/h5/stm32h5.dtsi +++ b/dts/arm/st/h5/stm32h5.dtsi @@ -231,6 +231,7 @@ lptim1: timers@44004400 { compatible = "st,stm32-lptim"; clocks = <&rcc STM32_CLOCK(APB3, 11)>; + resets = <&rctl STM32_RESET(APB3, 11)>; #address-cells = <1>; #size-cells = <0>; reg = <0x44004400 0x400>; @@ -242,6 +243,7 @@ lptim2: timers@40009400 { compatible = "st,stm32-lptim"; clocks = <&rcc STM32_CLOCK(APB1_2, 5)>; + resets = <&rctl STM32_RESET(APB1H, 5)>; #address-cells = <1>; #size-cells = <0>; reg = <0x40009400 0x400>; diff --git a/dts/arm/st/h5/stm32h562.dtsi b/dts/arm/st/h5/stm32h562.dtsi index f5a64069102c..6099f1d0bfb3 100644 --- a/dts/arm/st/h5/stm32h562.dtsi +++ b/dts/arm/st/h5/stm32h562.dtsi @@ -81,6 +81,7 @@ lptim3: timers@44004800 { compatible = "st,stm32-lptim"; clocks = <&rcc STM32_CLOCK(APB3, 12)>; + resets = <&rctl STM32_RESET(APB3, 12)>; #address-cells = <1>; #size-cells = <0>; reg = <0x44004800 0x400>; @@ -92,6 +93,7 @@ lptim4: timers@44004c00 { compatible = "st,stm32-lptim"; clocks = <&rcc STM32_CLOCK(APB3, 13)>; + resets = <&rctl STM32_RESET(APB3, 13)>; #address-cells = <1>; #size-cells = <0>; reg = <0x44004c00 0x400>; @@ -103,6 +105,7 @@ lptim5: timers@44005000 { compatible = "st,stm32-lptim"; clocks = <&rcc STM32_CLOCK(APB3, 14)>; + resets = <&rctl STM32_RESET(APB3, 14)>; #address-cells = <1>; #size-cells = <0>; reg = <0x44005000 0x400>; @@ -114,6 +117,7 @@ lptim6: timers@44005400 { compatible = "st,stm32-lptim"; clocks = <&rcc STM32_CLOCK(APB3, 15)>; + resets = <&rctl STM32_RESET(APB3, 15)>; #address-cells = <1>; #size-cells = <0>; reg = <0x44005400 0x400>; diff --git a/dts/arm/st/h7/stm32h7.dtsi b/dts/arm/st/h7/stm32h7.dtsi index af3247ea7a16..584ab1451b3c 100644 --- a/dts/arm/st/h7/stm32h7.dtsi +++ b/dts/arm/st/h7/stm32h7.dtsi @@ -932,6 +932,7 @@ lptim1: timers@40002400 { compatible = "st,stm32-lptim"; clocks = <&rcc STM32_CLOCK(APB1, 9)>; + resets = <&rctl STM32_RESET(APB1L, 9)>; #address-cells = <1>; #size-cells = <0>; reg = <0x40002400 0x400>; diff --git a/dts/arm/st/h7rs/stm32h7rs.dtsi b/dts/arm/st/h7rs/stm32h7rs.dtsi index b01aeb433ded..ece4ef0b3bae 100644 --- a/dts/arm/st/h7rs/stm32h7rs.dtsi +++ b/dts/arm/st/h7rs/stm32h7rs.dtsi @@ -868,6 +868,7 @@ lptim1: timers@40002400 { compatible = "st,stm32-lptim"; clocks = <&rcc STM32_CLOCK(APB1, 9)>; + resets = <&rctl STM32_RESET(APB1L, 9)>; #address-cells = <1>; #size-cells = <0>; reg = <0x40002400 0x400>; diff --git a/dts/arm/st/l0/stm32l0.dtsi b/dts/arm/st/l0/stm32l0.dtsi index fa22dbb826cd..7ecb011008cc 100644 --- a/dts/arm/st/l0/stm32l0.dtsi +++ b/dts/arm/st/l0/stm32l0.dtsi @@ -311,6 +311,7 @@ lptim1: timers@40007c00 { compatible = "st,stm32-lptim"; clocks = <&rcc STM32_CLOCK(APB1, 31)>; + resets = <&rctl STM32_RESET(APB1, 31)>; #address-cells = <1>; #size-cells = <0>; reg = <0x40007c00 0x400>; diff --git a/dts/arm/st/l4/stm32l4.dtsi b/dts/arm/st/l4/stm32l4.dtsi index 151695dee6e8..dc1bd7126424 100644 --- a/dts/arm/st/l4/stm32l4.dtsi +++ b/dts/arm/st/l4/stm32l4.dtsi @@ -490,6 +490,7 @@ lptim1: timers@40007c00 { compatible = "st,stm32-lptim"; clocks = <&rcc STM32_CLOCK(APB1, 31)>; + resets = <&rctl STM32_RESET(APB1L, 31)>; #address-cells = <1>; #size-cells = <0>; reg = <0x40007c00 0x400>; @@ -504,6 +505,7 @@ #size-cells = <0>; reg = <0x40009400 0x400>; clocks = <&rcc STM32_CLOCK(APB1_2, 5)>; + resets = <&rctl STM32_RESET(APB1H, 5)>; interrupts = <66 1>; interrupt-names = "wakeup"; status = "disabled"; diff --git a/dts/arm/st/l5/stm32l5.dtsi b/dts/arm/st/l5/stm32l5.dtsi index 10904ece0368..523650830a3a 100644 --- a/dts/arm/st/l5/stm32l5.dtsi +++ b/dts/arm/st/l5/stm32l5.dtsi @@ -331,6 +331,7 @@ lptim1: timers@40007c00 { compatible = "st,stm32-lptim"; clocks = <&rcc STM32_CLOCK(APB1, 31)>; + resets = <&rctl STM32_RESET(APB1L, 31)>; #address-cells = <1>; #size-cells = <0>; reg = <0x40007c00 0x400>; diff --git a/dts/arm/st/u0/stm32u0.dtsi b/dts/arm/st/u0/stm32u0.dtsi index 0ac94e17b1a3..e082dd5a2f6f 100644 --- a/dts/arm/st/u0/stm32u0.dtsi +++ b/dts/arm/st/u0/stm32u0.dtsi @@ -582,6 +582,7 @@ lptim1: timers@40007c00 { compatible = "st,stm32-lptim"; clocks = <&rcc STM32_CLOCK(APB1, 31)>; + resets = <&rctl STM32_RESET(APB1L, 31)>; #address-cells = <1>; #size-cells = <0>; reg = <0x40007c00 0x400>; @@ -593,6 +594,7 @@ lptim2: timers@40009400 { compatible = "st,stm32-lptim"; clocks = <&rcc STM32_CLOCK(APB1, 30)>; + resets = <&rctl STM32_RESET(APB1L, 30)>; #address-cells = <1>; #size-cells = <0>; reg = <0x40009400 0x400>; diff --git a/dts/arm/st/u0/stm32u073.dtsi b/dts/arm/st/u0/stm32u073.dtsi index 8122543d9555..bf26420d7116 100644 --- a/dts/arm/st/u0/stm32u073.dtsi +++ b/dts/arm/st/u0/stm32u073.dtsi @@ -25,6 +25,7 @@ lptim3: timers@40009000 { compatible = "st,stm32-lptim"; clocks = <&rcc STM32_CLOCK(APB1, 26)>; + resets = <&rctl STM32_RESET(APB1L, 26)>; #address-cells = <1>; #size-cells = <0>; reg = <0x40009000 0x400>; diff --git a/dts/arm/st/u5/stm32u5.dtsi b/dts/arm/st/u5/stm32u5.dtsi index c031b7109caf..7aea280d7bc1 100644 --- a/dts/arm/st/u5/stm32u5.dtsi +++ b/dts/arm/st/u5/stm32u5.dtsi @@ -432,6 +432,7 @@ #size-cells = <0>; reg = <0x46004400 0x400>; clocks = <&rcc STM32_CLOCK(APB3, 11)>; + resets = <&rctl STM32_RESET(APB3, 11)>; interrupts = <67 1>; interrupt-names = "wakeup"; status = "disabled"; @@ -443,6 +444,7 @@ #size-cells = <0>; reg = <0x40009400 0x400>; clocks = <&rcc STM32_CLOCK(APB1_2, 5)>; + resets = <&rctl STM32_RESET(APB1H, 5)>; interrupts = <68 0>; interrupt-names = "global"; status = "disabled"; @@ -454,6 +456,7 @@ #size-cells = <0>; reg = <0x46004800 0x400>; clocks = <&rcc STM32_CLOCK(APB3, 12)>; + resets = <&rctl STM32_RESET(APB3, 12)>; interrupts = <98 0>; interrupt-names = "global"; status = "disabled"; @@ -465,6 +468,7 @@ #size-cells = <0>; reg = <0x46004c00 0x400>; clocks = <&rcc STM32_CLOCK(APB3, 13)>; + resets = <&rctl STM32_RESET(APB3, 13)>; interrupts = <110 0>; interrupt-names = "global"; status = "disabled"; diff --git a/dts/arm/st/wb/stm32wb.dtsi b/dts/arm/st/wb/stm32wb.dtsi index e1aba8b9c135..28dc4ea9e08d 100644 --- a/dts/arm/st/wb/stm32wb.dtsi +++ b/dts/arm/st/wb/stm32wb.dtsi @@ -457,6 +457,7 @@ lptim1: timers@40007c00 { compatible = "st,stm32-lptim"; clocks = <&rcc STM32_CLOCK(APB1, 31)>; + resets = <&rctl STM32_RESET(APB1L, 31)>; #address-cells = <1>; #size-cells = <0>; reg = <0x40007c00 0x400>; diff --git a/dts/arm/st/wba/stm32wba.dtsi b/dts/arm/st/wba/stm32wba.dtsi index cbbdfea66685..020001e4285a 100644 --- a/dts/arm/st/wba/stm32wba.dtsi +++ b/dts/arm/st/wba/stm32wba.dtsi @@ -520,6 +520,7 @@ #size-cells = <0>; reg = <0x46004400 0x400>; clocks = <&rcc STM32_CLOCK(APB7, 11)>; + resets = <&rctl STM32_RESET(APB7, 11)>; interrupts = <49 1>; interrupt-names = "wakeup"; status = "disabled"; @@ -531,6 +532,7 @@ #size-cells = <0>; reg = <0x40009400 0x400>; clocks = <&rcc STM32_CLOCK(APB1_2, 5)>; + resets = <&rctl STM32_RESET(APB1H, 5)>; interrupts = <50 1>; interrupt-names = "wakeup"; status = "disabled"; diff --git a/dts/arm/st/wl/stm32wl.dtsi b/dts/arm/st/wl/stm32wl.dtsi index b94439ee83de..078d46e9d1f4 100644 --- a/dts/arm/st/wl/stm32wl.dtsi +++ b/dts/arm/st/wl/stm32wl.dtsi @@ -205,6 +205,7 @@ lptim1: timers@40007c00 { compatible = "st,stm32-lptim"; clocks = <&rcc STM32_CLOCK(APB1, 31)>; + resets = <&rctl STM32_RESET(APB1L, 31)>; #address-cells = <1>; #size-cells = <0>; reg = <0x40007c00 0x400>; diff --git a/dts/bindings/timer/st,stm32-lptim.yaml b/dts/bindings/timer/st,stm32-lptim.yaml index 31e4ea0e8efd..43b9e311f663 100644 --- a/dts/bindings/timer/st,stm32-lptim.yaml +++ b/dts/bindings/timer/st,stm32-lptim.yaml @@ -15,8 +15,6 @@ compatible: "st,stm32-lptim" include: - name: st,stm32-timers.yaml property-blocklist: - # 'resets' property is not supported yet - - resets - st,prescaler - st,countermode From 816dfb8f1145ea2e56b72ef84b73497cfe5356f5 Mon Sep 17 00:00:00 2001 From: Tim Pambor Date: Sat, 6 Dec 2025 10:36:42 +0100 Subject: [PATCH 0093/3659] drivers: timer: stm32_lptim: add reset support Add support for resetting the LPTIM peripheral to its default state on initialization. This ensures that any previous configurations do not interfere with the new settings. Signed-off-by: Tim Pambor --- drivers/timer/stm32_lptim_timer.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/timer/stm32_lptim_timer.c b/drivers/timer/stm32_lptim_timer.c index 6a8fdd6b29fb..86994fa9a952 100644 --- a/drivers/timer/stm32_lptim_timer.c +++ b/drivers/timer/stm32_lptim_timer.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -38,6 +39,8 @@ static const struct stm32_pclken lptim_clk[] = STM32_DT_INST_CLOCKS(0); static const struct device *const clk_ctrl = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE); +static const struct reset_dt_spec lptim_reset = RESET_DT_SPEC_INST_GET(0); + /* * Assumptions and limitations: * @@ -559,6 +562,9 @@ static int sys_clock_driver_init(void) } #endif + /* Reset timer to default state using RCC */ + (void)reset_line_toggle_dt(&lptim_reset); + #if DT_PROP(DT_NODELABEL(stm32_lp_tick_source), st_timeout) uint32_t timeout = DT_PROP(DT_NODELABEL(stm32_lp_tick_source), st_timeout); From ac576474e6a72cb83bc7cc0a6c8e24a1861ac2ae Mon Sep 17 00:00:00 2001 From: Biwen Li Date: Wed, 19 Nov 2025 15:36:18 +0900 Subject: [PATCH 0094/3659] soc: nxp: imx943: use configdefault Use configdefault Signed-off-by: Biwen Li --- .../imx943/Kconfig.defconfig.mimx94398.m33 | 22 ++++++++-------- .../imx943/Kconfig.defconfig.mimx94398.m7_0 | 26 +++++++++---------- .../imx943/Kconfig.defconfig.mimx94398.m7_1 | 26 +++++++++---------- 3 files changed, 37 insertions(+), 37 deletions(-) diff --git a/soc/nxp/imx/imx9/imx943/Kconfig.defconfig.mimx94398.m33 b/soc/nxp/imx/imx9/imx943/Kconfig.defconfig.mimx94398.m33 index bf3b9b296264..b285db76ac7f 100644 --- a/soc/nxp/imx/imx9/imx943/Kconfig.defconfig.mimx94398.m33 +++ b/soc/nxp/imx/imx9/imx943/Kconfig.defconfig.mimx94398.m33 @@ -5,22 +5,22 @@ if SOC_MIMX94398_M33 DT_CHOSEN_Z_FLASH := zephyr,flash -config FLASH_SIZE +configdefault FLASH_SIZE default $(dt_chosen_reg_size_int,$(DT_CHOSEN_Z_FLASH),0,K) -config FLASH_BASE_ADDRESS +configdefault FLASH_BASE_ADDRESS default $(dt_chosen_reg_addr_hex,$(DT_CHOSEN_Z_FLASH)) -config MCUX_CORE_SUFFIX +configdefault MCUX_CORE_SUFFIX default "_cm33_core1" if SOC_MIMX94398_M33 -config NUM_IRQS +configdefault NUM_IRQS default 405 -config CORTEX_M_SYSTICK +configdefault CORTEX_M_SYSTICK default n if MCUX_GPT_TIMER -config SYS_CLOCK_HW_CYCLES_PER_SEC +configdefault SYS_CLOCK_HW_CYCLES_PER_SEC default $(dt_node_int_prop_int,/cpus/cpu@0,clock-frequency) if CORTEX_M_SYSTICK default 32768 if MCUX_GPT_TIMER @@ -28,21 +28,21 @@ choice CACHE_TYPE default EXTERNAL_CACHE endchoice -config ETH_NXP_IMX_MSGINTR +configdefault ETH_NXP_IMX_MSGINTR default 2 -config CACHE_MANAGEMENT +configdefault CACHE_MANAGEMENT default y if PM -config IDLE_STACK_SIZE +configdefault IDLE_STACK_SIZE default 640 -config MCUX_GPT_TIMER +configdefault MCUX_GPT_TIMER default y -config SYS_CLOCK_TICKS_PER_SEC +configdefault SYS_CLOCK_TICKS_PER_SEC default 1024 endif diff --git a/soc/nxp/imx/imx9/imx943/Kconfig.defconfig.mimx94398.m7_0 b/soc/nxp/imx/imx9/imx943/Kconfig.defconfig.mimx94398.m7_0 index 40fb23130e4a..05f450adcf39 100644 --- a/soc/nxp/imx/imx9/imx943/Kconfig.defconfig.mimx94398.m7_0 +++ b/soc/nxp/imx/imx9/imx943/Kconfig.defconfig.mimx94398.m7_0 @@ -5,46 +5,46 @@ if SOC_MIMX94398_M7_0 DT_CHOSEN_Z_FLASH := zephyr,flash -config FLASH_SIZE +configdefault FLASH_SIZE default $(dt_chosen_reg_size_int,$(DT_CHOSEN_Z_FLASH),0,K) -config FLASH_BASE_ADDRESS +configdefault FLASH_BASE_ADDRESS default $(dt_chosen_reg_addr_hex,$(DT_CHOSEN_Z_FLASH)) -config MCUX_CORE_SUFFIX +configdefault MCUX_CORE_SUFFIX default "_cm7_core0" if SOC_MIMX94398_M7_0 -config NUM_IRQS +configdefault NUM_IRQS default 238 -config CORTEX_M_SYSTICK +configdefault CORTEX_M_SYSTICK default n if MCUX_GPT_TIMER -config SYS_CLOCK_HW_CYCLES_PER_SEC +configdefault SYS_CLOCK_HW_CYCLES_PER_SEC default $(dt_node_int_prop_int,/cpus/cpu@0,clock-frequency) if CORTEX_M_SYSTICK default 32768 if MCUX_GPT_TIMER -config ETH_NXP_IMX_MSGINTR +configdefault ETH_NXP_IMX_MSGINTR default 2 -config CACHE_MANAGEMENT +configdefault CACHE_MANAGEMENT default n if PM -config IDLE_STACK_SIZE +configdefault IDLE_STACK_SIZE default 640 -config PM_S2RAM +configdefault PM_S2RAM default y -config HAS_PM_S2RAM_CUSTOM_MARKING +configdefault HAS_PM_S2RAM_CUSTOM_MARKING default y -config MCUX_GPT_TIMER +configdefault MCUX_GPT_TIMER default y -config SYS_CLOCK_TICKS_PER_SEC +configdefault SYS_CLOCK_TICKS_PER_SEC default 1024 endif diff --git a/soc/nxp/imx/imx9/imx943/Kconfig.defconfig.mimx94398.m7_1 b/soc/nxp/imx/imx9/imx943/Kconfig.defconfig.mimx94398.m7_1 index 2c31e9db67e5..6c7f9717711b 100644 --- a/soc/nxp/imx/imx9/imx943/Kconfig.defconfig.mimx94398.m7_1 +++ b/soc/nxp/imx/imx9/imx943/Kconfig.defconfig.mimx94398.m7_1 @@ -5,46 +5,46 @@ if SOC_MIMX94398_M7_1 DT_CHOSEN_Z_FLASH := zephyr,flash -config FLASH_SIZE +configdefault FLASH_SIZE default $(dt_chosen_reg_size_int,$(DT_CHOSEN_Z_FLASH),0,K) -config FLASH_BASE_ADDRESS +configdefault FLASH_BASE_ADDRESS default $(dt_chosen_reg_addr_hex,$(DT_CHOSEN_Z_FLASH)) -config MCUX_CORE_SUFFIX +configdefault MCUX_CORE_SUFFIX default "_cm7_core1" if SOC_MIMX94398_M7_1 -config NUM_IRQS +configdefault NUM_IRQS default 238 -config CORTEX_M_SYSTICK +configdefault CORTEX_M_SYSTICK default n if MCUX_GPT_TIMER -config SYS_CLOCK_HW_CYCLES_PER_SEC +configdefault SYS_CLOCK_HW_CYCLES_PER_SEC default $(dt_node_int_prop_int,/cpus/cpu@0,clock-frequency) if CORTEX_M_SYSTICK default 32768 if MCUX_GPT_TIMER -config ETH_NXP_IMX_MSGINTR +configdefault ETH_NXP_IMX_MSGINTR default 2 -config CACHE_MANAGEMENT +configdefault CACHE_MANAGEMENT default n if PM -config IDLE_STACK_SIZE +configdefault IDLE_STACK_SIZE default 640 -config PM_S2RAM +configdefault PM_S2RAM default y -config HAS_PM_S2RAM_CUSTOM_MARKING +configdefault HAS_PM_S2RAM_CUSTOM_MARKING default y -config MCUX_GPT_TIMER +configdefault MCUX_GPT_TIMER default y -config SYS_CLOCK_TICKS_PER_SEC +configdefault SYS_CLOCK_TICKS_PER_SEC default 1024 endif From 5c65e3797fe8a380593a87ddad3c6d47e8524543 Mon Sep 17 00:00:00 2001 From: Mathieu Choplain Date: Wed, 19 Nov 2025 17:32:21 +0100 Subject: [PATCH 0095/3659] drivers: usb: udc: skeleton: share thread creation code across instances Instead of having one "make_thread" function per instance, called through a function pointer in the instance configuration, save the thread stack information instead and consume it from shared code in the driver pre-init function. This makes the driver more readable (less code in the instance creation macro) and should reduce its footprint impact (since the thread creation code is no longer duplicated). Signed-off-by: Mathieu Choplain --- drivers/usb/udc/udc_skeleton.c | 45 +++++++++++++++------------------- 1 file changed, 20 insertions(+), 25 deletions(-) diff --git a/drivers/usb/udc/udc_skeleton.c b/drivers/usb/udc/udc_skeleton.c index 384efa9cc2c3..5c40cfd5de4f 100644 --- a/drivers/usb/udc/udc_skeleton.c +++ b/drivers/usb/udc/udc_skeleton.c @@ -43,7 +43,8 @@ struct udc_skeleton_config { size_t num_of_eps; struct udc_ep_config *ep_cfg_in; struct udc_ep_config *ep_cfg_out; - void (*make_thread)(const struct device *dev); + k_thread_stack_t *thread_stk; + size_t thread_stk_sz; int speed_idx; }; @@ -62,9 +63,12 @@ struct udc_skeleton_data { * enable Kconfig option UDC_WORKQUEUE and remove the handler below and * caller from the UDC_SKELETON_DEVICE_DEFINE macro. */ -static ALWAYS_INLINE void skeleton_thread_handler(void *const arg) +static void skeleton_thread_handler(void *arg1, void *arg2, void *arg3) { - const struct device *dev = (const struct device *)arg; + const struct device *dev = (const struct device *)arg1; + + ARG_UNUSED(arg2); + ARG_UNUSED(arg3); LOG_DBG("Driver %p thread started", dev); while (true) { @@ -283,6 +287,7 @@ static int udc_skeleton_shutdown(const struct device *dev) static int udc_skeleton_driver_preinit(const struct device *dev) { const struct udc_skeleton_config *config = dev->config; + struct udc_skeleton_data *priv = udc_get_private(dev); struct udc_data *data = dev->data; uint16_t mps = 1023; int err; @@ -341,7 +346,16 @@ static int udc_skeleton_driver_preinit(const struct device *dev) } } - config->make_thread(dev); + k_thread_create(&priv->thread_data, + config->thread_stk, + config->thread_stk_sz, + skeleton_thread_handler, + (void *)dev, NULL, NULL, + K_PRIO_COOP(CONFIG_UDC_SKELETON_THREAD_PRIORITY), + K_ESSENTIAL, + K_NO_WAIT); + k_thread_name_set(&priv->thread_data, dev->name); + LOG_INF("Device %p (max. speed %d)", dev, config->speed_idx); return 0; @@ -390,26 +404,6 @@ static const struct udc_api udc_skeleton_api = { K_THREAD_STACK_DEFINE(udc_skeleton_stack_##n, \ CONFIG_UDC_SKELETON_STACK_SIZE); \ \ - static void udc_skeleton_thread_##n(void *dev, void *arg1, void *arg2) \ - { \ - skeleton_thread_handler(dev); \ - } \ - \ - static void udc_skeleton_make_thread_##n(const struct device *dev) \ - { \ - struct udc_skeleton_data *priv = udc_get_private(dev); \ - \ - k_thread_create(&priv->thread_data, \ - udc_skeleton_stack_##n, \ - K_THREAD_STACK_SIZEOF(udc_skeleton_stack_##n), \ - udc_skeleton_thread_##n, \ - (void *)dev, NULL, NULL, \ - K_PRIO_COOP(CONFIG_UDC_SKELETON_THREAD_PRIORITY),\ - K_ESSENTIAL, \ - K_NO_WAIT); \ - k_thread_name_set(&priv->thread_data, dev->name); \ - } \ - \ static struct udc_ep_config \ ep_cfg_out[DT_INST_PROP(n, num_bidir_endpoints)]; \ static struct udc_ep_config \ @@ -419,7 +413,8 @@ static const struct udc_api udc_skeleton_api = { .num_of_eps = DT_INST_PROP(n, num_bidir_endpoints), \ .ep_cfg_in = ep_cfg_out, \ .ep_cfg_out = ep_cfg_in, \ - .make_thread = udc_skeleton_make_thread_##n, \ + .thread_stk = udc_skeleton_stack_##n, \ + .thread_stk_sz = K_THREAD_STACK_SIZEOF(udc_skeleton_stack_##n), \ .speed_idx = DT_ENUM_IDX(DT_DRV_INST(n), maximum_speed), \ }; \ \ From 1b2b09d6ad06211bd3fecc0753ee2d8c6a266636 Mon Sep 17 00:00:00 2001 From: Mathieu Choplain Date: Thu, 4 Dec 2025 13:19:21 +0100 Subject: [PATCH 0096/3659] tests: drivers: udc: add integration platform for skeleton test Add `integration_platforms` to the `drivers.usb.udc.skeleton` test case to ensure the UDC Skeleton driver is built and tested by CI. Signed-off-by: Mathieu Choplain --- tests/drivers/udc/testcase.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/drivers/udc/testcase.yaml b/tests/drivers/udc/testcase.yaml index 2ba45d77488d..a7a6122dd8f6 100644 --- a/tests/drivers/udc/testcase.yaml +++ b/tests/drivers/udc/testcase.yaml @@ -26,3 +26,5 @@ tests: - CONFIG_UDC_BUF_POOL_SIZE=32768 platform_allow: - native_sim/native/64 + integration_platforms: + - native_sim/native/64 From d0e9d950fb9bb27091d08816f9e189646be5ad90 Mon Sep 17 00:00:00 2001 From: Yongxu Wang Date: Fri, 14 Nov 2025 15:05:47 +0800 Subject: [PATCH 0097/3659] drivers: firmware: scmi: add common protocol interface functions Add standardized SCMI protocol common interface functions that can be reused across different SCMI protocol implementations: - scmi_protocol_get_version(): Query protocol version - scmi_protocol_attributes_get(): Get protocol-specific attributes - scmi_protocol_message_attributes_get(): Query message capabilities - scmi_protocol_version_negotiate(): Negotiate protocol version support Signed-off-by: Yongxu Wang --- drivers/firmware/scmi/CMakeLists.txt | 2 +- drivers/firmware/scmi/common.c | 162 ++++++++++++++++++ .../zephyr/drivers/firmware/scmi/protocol.h | 56 ++++++ 3 files changed, 219 insertions(+), 1 deletion(-) create mode 100644 drivers/firmware/scmi/common.c diff --git a/drivers/firmware/scmi/CMakeLists.txt b/drivers/firmware/scmi/CMakeLists.txt index 60ea86a5cb69..9108f9b41745 100644 --- a/drivers/firmware/scmi/CMakeLists.txt +++ b/drivers/firmware/scmi/CMakeLists.txt @@ -3,7 +3,7 @@ zephyr_library() # SCMI core files -zephyr_library_sources_ifdef(CONFIG_ARM_SCMI core.c) +zephyr_library_sources_ifdef(CONFIG_ARM_SCMI core.c common.c) zephyr_library_sources_ifdef(CONFIG_ARM_SCMI_MAILBOX_TRANSPORT mailbox.c) zephyr_library_sources_ifdef(CONFIG_ARM_SCMI_SHMEM shmem.c) diff --git a/drivers/firmware/scmi/common.c b/drivers/firmware/scmi/common.c new file mode 100644 index 000000000000..d2e768c69c7a --- /dev/null +++ b/drivers/firmware/scmi/common.c @@ -0,0 +1,162 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief SCMI Common Protocol Commands Implementation + * + * This file contains the implementation of the SCMI commands that are + * common to all protocols (generic or vendor-specific) as listed in + * ARM SCMI Specification such as v4.0 (DEN0056F), Section 3.2.2 "Base protocol Commands". + * + * The following common commands are implemented: + * - PROTOCOL_VERSION (0x0): Query protocol version + * - PROTOCOL_ATTRIBUTES (0x1): Get protocol-specific attributes + * - MESSAGE_ATTRIBUTES (0x2): Query message capabilities + * - NEGOTIATE_PROTOCOL_VERSION (0x10): Negotiate protocol version support + * + * These commands provide standardized interfaces that can be reused across + * different SCMI protocol implementations, ensuring consistency and reducing + * code duplication. + * + * Reference: ARM System Control and Management Interface Platform Design Document + * Version 4.0, Document number: DEN0056F + * Available at: https://developer.arm.com/documentation/den0056/latest + */ + +#include +#include +#include + +struct scmi_protocol_version_reply { + int32_t status; + uint32_t version; +}; + +struct scmi_protocol_attributes_reply { + int32_t status; + uint32_t attributes; +}; + +struct scmi_protocol_message_attributes_reply { + int32_t status; + uint32_t attributes; +}; + +int scmi_protocol_get_version(struct scmi_protocol *proto, uint32_t *version) +{ + struct scmi_protocol_version_reply reply_buffer; + struct scmi_message msg, reply; + int ret; + + if (!proto || !version) { + return -EINVAL; + } + + msg.hdr = SCMI_MESSAGE_HDR_MAKE(SCMI_MSG_PROTOCOL_VERSION, SCMI_COMMAND, + proto->id, 0x0); + msg.len = 0; + msg.content = NULL; + + reply.hdr = msg.hdr; + reply.len = sizeof(reply_buffer); + reply.content = &reply_buffer; + + ret = scmi_send_message(proto, &msg, &reply, k_is_pre_kernel()); + if (ret < 0) { + return ret; + } + + *version = reply_buffer.version; + + return scmi_status_to_errno(reply_buffer.status); +} + +int scmi_protocol_attributes_get(struct scmi_protocol *proto, uint32_t *attributes) +{ + struct scmi_protocol_attributes_reply reply_buffer; + struct scmi_message msg, reply; + int ret; + + if (!proto || !attributes) { + return -EINVAL; + } + + msg.hdr = SCMI_MESSAGE_HDR_MAKE(SCMI_MSG_PROTOCOL_ATTRIBUTES, SCMI_COMMAND, + proto->id, 0x0); + msg.len = 0; + msg.content = NULL; + + reply.hdr = msg.hdr; + reply.len = sizeof(reply_buffer); + reply.content = &reply_buffer; + + ret = scmi_send_message(proto, &msg, &reply, k_is_pre_kernel()); + if (ret < 0) { + return ret; + } + + *attributes = reply_buffer.attributes; + + return scmi_status_to_errno(reply_buffer.status); +} + +int scmi_protocol_message_attributes_get(struct scmi_protocol *proto, + uint32_t message_id, uint32_t *attributes) +{ + struct scmi_protocol_message_attributes_reply reply_buffer; + struct scmi_message msg, reply; + int ret; + + if (!proto || !attributes) { + return -EINVAL; + } + + msg.hdr = SCMI_MESSAGE_HDR_MAKE(SCMI_MSG_MESSAGE_ATTRIBUTES, SCMI_COMMAND, + proto->id, 0x0); + msg.len = sizeof(message_id); + msg.content = &message_id; + + reply.hdr = msg.hdr; + reply.len = sizeof(reply_buffer); + reply.content = &reply_buffer; + + ret = scmi_send_message(proto, &msg, &reply, k_is_pre_kernel()); + if (ret < 0) { + return ret; + } + + *attributes = reply_buffer.attributes; + + return scmi_status_to_errno(reply_buffer.status); +} + +int scmi_protocol_version_negotiate(struct scmi_protocol *proto, uint32_t version) +{ + struct scmi_message msg, reply; + int32_t status; + int ret; + + if (!proto) { + return -EINVAL; + } + + msg.hdr = SCMI_MESSAGE_HDR_MAKE(SCMI_MSG_NEGOTIATE_PROTOCOL_VERSION, SCMI_COMMAND, + proto->id, 0x0); + msg.len = sizeof(version); + msg.content = &version; + + reply.hdr = msg.hdr; + reply.len = sizeof(status); + reply.content = &status; + + ret = scmi_send_message(proto, &msg, &reply, k_is_pre_kernel()); + if (ret < 0) { + return ret; + } + + return scmi_status_to_errno(status); +} diff --git a/include/zephyr/drivers/firmware/scmi/protocol.h b/include/zephyr/drivers/firmware/scmi/protocol.h index 920aaf5c435d..fd530961a410 100644 --- a/include/zephyr/drivers/firmware/scmi/protocol.h +++ b/include/zephyr/drivers/firmware/scmi/protocol.h @@ -66,6 +66,16 @@ enum scmi_status_code { SCMI_IN_USE = -11, }; +/** + * @brief SCMI common command + */ +enum scmi_common_cmd { + SCMI_MSG_PROTOCOL_VERSION = 0x0, + SCMI_MSG_PROTOCOL_ATTRIBUTES = 0x1, + SCMI_MSG_MESSAGE_ATTRIBUTES = 0x2, + SCMI_MSG_NEGOTIATE_PROTOCOL_VERSION = 0x10, +}; + /** * @struct scmi_protocol * @@ -126,4 +136,50 @@ int scmi_send_message(struct scmi_protocol *proto, struct scmi_message *msg, struct scmi_message *reply, bool use_polling); +/** + * @brief Get protocol version + * + * @param proto Protocol instance + * @param version Pointer to store protocol version + * + * @retval 0 if successful + * @retval negative errno if failure + */ +int scmi_protocol_get_version(struct scmi_protocol *proto, uint32_t *version); + +/** + * @brief Get protocol attributes + * + * @param proto Protocol instance + * @param attributes Pointer to store protocol attributes + * + * @retval 0 if successful + * @retval negative errno if failure + */ +int scmi_protocol_attributes_get(struct scmi_protocol *proto, uint32_t *attributes); + +/** + * @brief Get protocol message attributes + * + * @param proto Protocol instance + * @param message_id Message ID to query + * @param attributes Pointer to store message attributes + * + * @retval 0 if successful + * @retval negative errno if failure + */ +int scmi_protocol_message_attributes_get(struct scmi_protocol *proto, + uint32_t message_id, uint32_t *attributes); + +/** + * @brief Negotiate protocol version + * + * @param proto Protocol instance + * @param version Desired protocol version + * + * @retval 0 if successful + * @retval negative errno if failure + */ +int scmi_protocol_version_negotiate(struct scmi_protocol *proto, uint32_t version); + #endif /* _INCLUDE_ZEPHYR_DRIVERS_FIRMWARE_SCMI_PROTOCOL_H_ */ From 9d163c73fb894b1f6624afe64266b0f17a232a34 Mon Sep 17 00:00:00 2001 From: Yongxu Wang Date: Thu, 20 Nov 2025 13:02:01 +0800 Subject: [PATCH 0098/3659] drivers: firmware: scmi: add protocol version support Add version field to struct scmi_protocol and update protocol macros to accept version parameter. Protocol versions added: - Clock Control: v3.0.0 (SCMI v3.2 DEN0056E) - Pin Control: v1.0.0 (SCMI v3.2 DEN0056E) - Power Domain: v3.0.1 (SCMI v3.2 DEN0056E) - NXP CPU: v1.0.0 (vendor extension) Updated macros: - DT_SCMI_PROTOCOL_DATA_DEFINE - DT_SCMI_PROTOCOL_DEFINE - DT_SCMI_PROTOCOL_DEFINE_NODEV - DT_INST_SCMI_PROTOCOL_DEFINE Signed-off-by: Yongxu Wang --- drivers/clock_control/clock_control_arm_scmi.c | 2 +- drivers/firmware/scmi/nxp/cpu.c | 3 ++- drivers/firmware/scmi/pinctrl.c | 3 ++- drivers/firmware/scmi/power.c | 3 ++- include/zephyr/drivers/firmware/scmi/clk.h | 2 ++ include/zephyr/drivers/firmware/scmi/nxp/cpu.h | 2 ++ include/zephyr/drivers/firmware/scmi/pinctrl.h | 2 ++ include/zephyr/drivers/firmware/scmi/power.h | 2 ++ include/zephyr/drivers/firmware/scmi/protocol.h | 2 ++ include/zephyr/drivers/firmware/scmi/util.h | 17 ++++++++++------- 10 files changed, 27 insertions(+), 11 deletions(-) diff --git a/drivers/clock_control/clock_control_arm_scmi.c b/drivers/clock_control/clock_control_arm_scmi.c index f48d91dae620..c6780882c358 100644 --- a/drivers/clock_control/clock_control_arm_scmi.c +++ b/drivers/clock_control/clock_control_arm_scmi.c @@ -121,4 +121,4 @@ static struct scmi_clock_data data; DT_INST_SCMI_PROTOCOL_DEFINE(0, &scmi_clock_init, NULL, &data, NULL, PRE_KERNEL_1, CONFIG_CLOCK_CONTROL_INIT_PRIORITY, - &scmi_clock_api); + &scmi_clock_api, SCMI_CLK_PROTOCOL_SUPPORTED_VERSION); diff --git a/drivers/firmware/scmi/nxp/cpu.c b/drivers/firmware/scmi/nxp/cpu.c index ee6a14ddc739..e2ec6c764383 100644 --- a/drivers/firmware/scmi/nxp/cpu.c +++ b/drivers/firmware/scmi/nxp/cpu.c @@ -8,7 +8,8 @@ #include #include -DT_SCMI_PROTOCOL_DEFINE_NODEV(DT_INST(0, nxp_scmi_cpu), NULL); +DT_SCMI_PROTOCOL_DEFINE_NODEV(DT_INST(0, nxp_scmi_cpu), NULL, + SCMI_NXP_CPU_PROTOCOL_SUPPORTED_VERSION); struct scmi_nxp_cpu_info_get_reply { int32_t status; diff --git a/drivers/firmware/scmi/pinctrl.c b/drivers/firmware/scmi/pinctrl.c index 73ed000daa0e..abfcae844a67 100644 --- a/drivers/firmware/scmi/pinctrl.c +++ b/drivers/firmware/scmi/pinctrl.c @@ -7,7 +7,8 @@ #include #include -DT_SCMI_PROTOCOL_DEFINE_NODEV(DT_INST(0, arm_scmi_pinctrl), NULL); +DT_SCMI_PROTOCOL_DEFINE_NODEV(DT_INST(0, arm_scmi_pinctrl), NULL, + SCMI_PIN_CONTROL_PROTOCOL_SUPPORTED_VERSION); int scmi_pinctrl_settings_configure(struct scmi_pinctrl_settings *settings) { diff --git a/drivers/firmware/scmi/power.c b/drivers/firmware/scmi/power.c index b560ce484571..6396029071be 100644 --- a/drivers/firmware/scmi/power.c +++ b/drivers/firmware/scmi/power.c @@ -8,7 +8,8 @@ #include #include -DT_SCMI_PROTOCOL_DEFINE_NODEV(DT_INST(0, arm_scmi_power), NULL); +DT_SCMI_PROTOCOL_DEFINE_NODEV(DT_INST(0, arm_scmi_power), NULL, + SCMI_POWER_DOMAIN_PROTOCOL_SUPPORTED_VERSION); struct scmi_power_state_get_reply { int32_t status; diff --git a/include/zephyr/drivers/firmware/scmi/clk.h b/include/zephyr/drivers/firmware/scmi/clk.h index d13cfd136794..c3b511c4f517 100644 --- a/include/zephyr/drivers/firmware/scmi/clk.h +++ b/include/zephyr/drivers/firmware/scmi/clk.h @@ -25,6 +25,8 @@ #define SCMI_CLK_RATE_SET_FLAGS_ROUNDS_UP_DOWN BIT(2) #define SCMI_CLK_RATE_SET_FLAGS_ROUNDS_AUTO BIT(3) +#define SCMI_CLK_PROTOCOL_SUPPORTED_VERSION 0x30000 + /** * @struct scmi_clock_config * diff --git a/include/zephyr/drivers/firmware/scmi/nxp/cpu.h b/include/zephyr/drivers/firmware/scmi/nxp/cpu.h index 1cfb91a8ff54..212bf96ba4aa 100644 --- a/include/zephyr/drivers/firmware/scmi/nxp/cpu.h +++ b/include/zephyr/drivers/firmware/scmi/nxp/cpu.h @@ -34,6 +34,8 @@ /** CPU vector flag: Resume address (exit from suspend) */ #define SCMI_NXP_CPU_VEC_FLAGS_RESUME BIT(31) +#define SCMI_NXP_CPU_PROTOCOL_SUPPORTED_VERSION 0x10000 + /** * @struct scmi_nxp_cpu_sleep_mode_config * diff --git a/include/zephyr/drivers/firmware/scmi/pinctrl.h b/include/zephyr/drivers/firmware/scmi/pinctrl.h index 3906b91db681..cb6a39a765e2 100644 --- a/include/zephyr/drivers/firmware/scmi/pinctrl.h +++ b/include/zephyr/drivers/firmware/scmi/pinctrl.h @@ -29,6 +29,8 @@ #define SCMI_PINCTRL_ATTRIBUTES_CONFIG_NUM(attributes)\ (((attributes) & GENMASK(9, 2)) >> 2) +#define SCMI_PIN_CONTROL_PROTOCOL_SUPPORTED_VERSION 0x10000 + /** * @brief Pinctrl protocol command message IDs */ diff --git a/include/zephyr/drivers/firmware/scmi/power.h b/include/zephyr/drivers/firmware/scmi/power.h index dcf73ef13f78..7545da9ef968 100644 --- a/include/zephyr/drivers/firmware/scmi/power.h +++ b/include/zephyr/drivers/firmware/scmi/power.h @@ -16,6 +16,8 @@ #define SCMI_POWER_STATE_SET_FLAGS_ASYNC BIT(0) +#define SCMI_POWER_DOMAIN_PROTOCOL_SUPPORTED_VERSION 0x30001 + /** * @name SCMI power domain state parameters * @{ diff --git a/include/zephyr/drivers/firmware/scmi/protocol.h b/include/zephyr/drivers/firmware/scmi/protocol.h index fd530961a410..a03d8cf493f8 100644 --- a/include/zephyr/drivers/firmware/scmi/protocol.h +++ b/include/zephyr/drivers/firmware/scmi/protocol.h @@ -90,6 +90,8 @@ struct scmi_protocol { const struct device *transport; /** protocol private data */ void *data; + /** protocol supported version */ + uint32_t version; }; /** diff --git a/include/zephyr/drivers/firmware/scmi/util.h b/include/zephyr/drivers/firmware/scmi/util.h index cd05f984ac20..55bceeaaf904 100644 --- a/include/zephyr/drivers/firmware/scmi/util.h +++ b/include/zephyr/drivers/firmware/scmi/util.h @@ -146,12 +146,13 @@ * @param proto protocol ID in decimal format * @param pdata protocol private data */ -#define DT_SCMI_PROTOCOL_DATA_DEFINE(node_id, proto, pdata) \ +#define DT_SCMI_PROTOCOL_DATA_DEFINE(node_id, proto, pdata, version_val) \ STRUCT_SECTION_ITERABLE(scmi_protocol, SCMI_PROTOCOL_NAME(proto)) = \ { \ .id = proto, \ .tx = DT_SCMI_TRANSPORT_TX_CHAN(node_id), \ .data = pdata, \ + .version = version_val \ } #else /* CONFIG_ARM_SCMI_TRANSPORT_HAS_STATIC_CHANNELS */ @@ -209,9 +210,10 @@ * @param prio protocol's priority within its initialization level */ #define DT_SCMI_PROTOCOL_DEFINE(node_id, init_fn, pm, data, config, \ - level, prio, api) \ + level, prio, api, version_val) \ DT_SCMI_TRANSPORT_CHANNELS_DECLARE(node_id) \ - DT_SCMI_PROTOCOL_DATA_DEFINE(node_id, DT_REG_ADDR_RAW(node_id), data); \ + DT_SCMI_PROTOCOL_DATA_DEFINE(node_id, DT_REG_ADDR_RAW(node_id), data, \ + version_val); \ DEVICE_DT_DEFINE(node_id, init_fn, pm, \ &SCMI_PROTOCOL_NAME(DT_REG_ADDR_RAW(node_id)), \ config, level, prio, api) @@ -230,9 +232,9 @@ * @param prio protocol's priority within its initialization level */ #define DT_INST_SCMI_PROTOCOL_DEFINE(inst, init_fn, pm, data, config, \ - level, prio, api) \ + level, prio, api, version) \ DT_SCMI_PROTOCOL_DEFINE(DT_INST(inst, DT_DRV_COMPAT), init_fn, pm, \ - data, config, level, prio, api) + data, config, level, prio, api, version) /** * @brief Define an SCMI protocol with no device @@ -245,9 +247,10 @@ * @param node_id protocol node identifier * @param data protocol private data */ -#define DT_SCMI_PROTOCOL_DEFINE_NODEV(node_id, data) \ +#define DT_SCMI_PROTOCOL_DEFINE_NODEV(node_id, data, version) \ DT_SCMI_TRANSPORT_CHANNELS_DECLARE(node_id) \ - DT_SCMI_PROTOCOL_DATA_DEFINE(node_id, DT_REG_ADDR_RAW(node_id), data) + DT_SCMI_PROTOCOL_DATA_DEFINE(node_id, DT_REG_ADDR_RAW(node_id), data, \ + version) \ /** * @brief Create an SCMI message field From ada584012b5ff410add1c59f0dd40c123140e624 Mon Sep 17 00:00:00 2001 From: Yongxu Wang Date: Thu, 20 Nov 2025 13:03:14 +0800 Subject: [PATCH 0099/3659] drivers: firmware: scmi: add protocol version negotiate Add SCMI protocol version negotiation to handle compatibility between different agent and platform versions. The negotiation automatically downgrades to supported version when needed and maintains backward compatibility with legacy systems. Signed-off-by: Yongxu Wang --- drivers/firmware/scmi/core.c | 45 ++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/drivers/firmware/scmi/core.c b/drivers/firmware/scmi/core.c index 378b654c5ec6..547ee92f43e5 100644 --- a/drivers/firmware/scmi/core.c +++ b/drivers/firmware/scmi/core.c @@ -215,6 +215,45 @@ int scmi_send_message(struct scmi_protocol *proto, struct scmi_message *msg, } } +static int scmi_core_protocol_negotiate(struct scmi_protocol *proto) + +{ + uint32_t agent_version, platform_version; + int ret; + + if (!proto) { + return -EINVAL; + } + + agent_version = proto->version; + + if (!agent_version) { + LOG_ERR("Protocol 0x%X: Agent version not specified", proto->id); + return -EINVAL; + } + + ret = scmi_protocol_get_version(proto, &platform_version); + if (ret < 0) { + LOG_ERR("Protocol 0x%X: Failed to get platform version: %d", + proto->id, ret); + return ret; + } + + if (platform_version > agent_version) { + ret = scmi_protocol_version_negotiate(proto, agent_version); + if (ret < 0) { + LOG_WRN("Protocol 0x%X: Negotiation failed (%d). " + "Platform v0x%08x does not support downgrade to agent v0x%08x", + proto->id, ret, platform_version, agent_version); + } + } + + LOG_INF("Using protocol 0x%X: agent version 0x%08x, platform version 0x%08x", + proto->id, agent_version, platform_version); + + return 0; +} + static int scmi_core_protocol_setup(const struct device *transport) { int ret; @@ -235,6 +274,12 @@ static int scmi_core_protocol_setup(const struct device *transport) if (ret < 0) { return ret; } + + ret = scmi_core_protocol_negotiate(it); + if (ret < 0) { + return ret; + } + } return 0; From cc069c02010b76cdb0d514f1c63d9468b2333f2d Mon Sep 17 00:00:00 2001 From: Yongxu Wang Date: Wed, 5 Nov 2025 15:09:51 +0800 Subject: [PATCH 0100/3659] drivers: firmware: scmi: Introduce basic system power protocol Add SCMI System Power Domain Protocol support with: - System power state set operations - Standard SCMI power states (shutdown, cold/warm reset, suspend) - Graceful and forceful power transitions - Optional NXP vendor-specific power states - Device tree binding for "arm,scmi-system" This enables system-wide power management through standardized SCMI interfaces for reboot and power control operations. Signed-off-by: Yongxu Wang --- drivers/firmware/scmi/CMakeLists.txt | 1 + drivers/firmware/scmi/Kconfig | 7 + drivers/firmware/scmi/system.c | 76 +++++++++ dts/bindings/firmware/arm,scmi-system.yaml | 13 ++ .../zephyr/drivers/firmware/scmi/nxp/system.h | 39 +++++ include/zephyr/drivers/firmware/scmi/system.h | 153 ++++++++++++++++++ 6 files changed, 289 insertions(+) create mode 100644 drivers/firmware/scmi/system.c create mode 100644 dts/bindings/firmware/arm,scmi-system.yaml create mode 100644 include/zephyr/drivers/firmware/scmi/nxp/system.h create mode 100644 include/zephyr/drivers/firmware/scmi/system.h diff --git a/drivers/firmware/scmi/CMakeLists.txt b/drivers/firmware/scmi/CMakeLists.txt index 9108f9b41745..d0e6128a97fe 100644 --- a/drivers/firmware/scmi/CMakeLists.txt +++ b/drivers/firmware/scmi/CMakeLists.txt @@ -11,5 +11,6 @@ zephyr_library_sources_ifdef(CONFIG_ARM_SCMI_SHMEM shmem.c) zephyr_library_sources_ifdef(CONFIG_ARM_SCMI_CLK_HELPERS clk.c) zephyr_library_sources_ifdef(CONFIG_ARM_SCMI_PINCTRL_HELPERS pinctrl.c) zephyr_library_sources_ifdef(CONFIG_ARM_SCMI_POWER_DOMAIN_HELPERS power.c) +zephyr_library_sources_ifdef(CONFIG_ARM_SCMI_SYSTEM system.c) add_subdirectory_ifdef(CONFIG_ARM_SCMI nxp) diff --git a/drivers/firmware/scmi/Kconfig b/drivers/firmware/scmi/Kconfig index 1f59ab872e67..fb35de45d2a7 100644 --- a/drivers/firmware/scmi/Kconfig +++ b/drivers/firmware/scmi/Kconfig @@ -48,6 +48,13 @@ config ARM_SCMI_SHMEM_INIT_PRIORITY help SCMI SHMEM driver device initialization priority. +config ARM_SCMI_SYSTEM + bool "SCMI system power protocol" + default y + depends on DT_HAS_ARM_SCMI_SYSTEM_ENABLED + help + Enable support for SCMI system protocol functions. + config ARM_SCMI_TRANSPORT_HAS_STATIC_CHANNELS bool "Transport layer has static channels" help diff --git a/drivers/firmware/scmi/system.c b/drivers/firmware/scmi/system.c new file mode 100644 index 000000000000..d96efd27e3bb --- /dev/null +++ b/drivers/firmware/scmi/system.c @@ -0,0 +1,76 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +DT_SCMI_PROTOCOL_DEFINE_NODEV(DT_INST(0, arm_scmi_system), NULL, + SCMI_SYSTEM_POWER_PROTOCOL_SUPPORTED_VERSION); + +int scmi_system_protocol_version(uint32_t *version) +{ + struct scmi_protocol *proto = &SCMI_PROTOCOL_NAME(SCMI_PROTOCOL_SYSTEM); + + return scmi_protocol_get_version(proto, version); +} + +int scmi_system_protocol_attributes(uint32_t *attributes) +{ + struct scmi_protocol *proto = &SCMI_PROTOCOL_NAME(SCMI_PROTOCOL_SYSTEM); + + return scmi_protocol_attributes_get(proto, attributes); +} + +int scmi_system_protocol_message_attributes(uint32_t message_id, uint32_t *attributes) +{ + struct scmi_protocol *proto = &SCMI_PROTOCOL_NAME(SCMI_PROTOCOL_SYSTEM); + + return scmi_protocol_message_attributes_get(proto, message_id, attributes); +} + +int scmi_system_protocol_version_negotiate(uint32_t version) +{ + struct scmi_protocol *proto = &SCMI_PROTOCOL_NAME(SCMI_PROTOCOL_SYSTEM); + + return scmi_protocol_version_negotiate(proto, version); +} + +int scmi_system_power_state_set(struct scmi_system_power_state_config *cfg) +{ + struct scmi_protocol *proto = &SCMI_PROTOCOL_NAME(SCMI_PROTOCOL_SYSTEM); + struct scmi_message msg, reply; + int32_t status; + int ret; + bool use_polling; + + /* sanity checks */ + if (!proto || !cfg) { + return -EINVAL; + } + + if (proto->id != SCMI_PROTOCOL_SYSTEM) { + return -EINVAL; + } + + msg.hdr = SCMI_MESSAGE_HDR_MAKE(SCMI_SYSTEM_MSG_POWER_STATE_SET, SCMI_COMMAND, + proto->id, 0x0); + msg.len = sizeof(*cfg); + msg.content = cfg; + + reply.hdr = msg.hdr; + reply.len = sizeof(status); + reply.content = &status; + + use_polling = k_is_pre_kernel(); + + ret = scmi_send_message(proto, &msg, &reply, use_polling); + if (ret < 0) { + return ret; + } + + return scmi_status_to_errno(status); +} diff --git a/dts/bindings/firmware/arm,scmi-system.yaml b/dts/bindings/firmware/arm,scmi-system.yaml new file mode 100644 index 000000000000..77aba5abf176 --- /dev/null +++ b/dts/bindings/firmware/arm,scmi-system.yaml @@ -0,0 +1,13 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +description: System Control and Management Interface (SCMI) system power protocol + +compatible: "arm,scmi-system" + +include: [base.yaml] + +properties: + reg: + required: true + const: [0x12] diff --git a/include/zephyr/drivers/firmware/scmi/nxp/system.h b/include/zephyr/drivers/firmware/scmi/nxp/system.h new file mode 100644 index 000000000000..63f3502cf7e8 --- /dev/null +++ b/include/zephyr/drivers/firmware/scmi/nxp/system.h @@ -0,0 +1,39 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_FIRMWARE_SCMI_NXP_SYSTEM_H_ +#define ZEPHYR_INCLUDE_DRIVERS_FIRMWARE_SCMI_NXP_SYSTEM_H_ + +/** + * @file + * @brief NXP SCMI System Protocol Extensions + */ +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @name NXP Vendor System Power States + * @{ + */ +#define SCMI_NXP_SYSTEM_POWER_STATE_WAKE 0x80000000U +#define SCMI_NXP_SYSTEM_POWER_STATE_FULL_SHUTDOWN 0x80000001U +#define SCMI_NXP_SYSTEM_POWER_STATE_FULL_RESET 0x80000002U +#define SCMI_NXP_SYSTEM_POWER_STATE_FULL_SUSPEND 0x80000003U +#define SCMI_NXP_SYSTEM_POWER_STATE_FULL_WAKE 0x80000004U +#define SCMI_NXP_SYSTEM_POWER_STATE_GRP_SHUTDOWN 0x80000005U +#define SCMI_NXP_SYSTEM_POWER_STATE_GRP_RESET 0x80000006U +#define SCMI_NXP_SYSTEM_POWER_STATE_SUBSYS_RESET 0x80000007U +#define SCMI_NXP_SYSTEM_POWER_STATE_MODE 0xC0000000U +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_INCLUDE_DRIVERS_FIRMWARE_SCMI_NXP_SYSTEM_H_ */ diff --git a/include/zephyr/drivers/firmware/scmi/system.h b/include/zephyr/drivers/firmware/scmi/system.h new file mode 100644 index 000000000000..b947d89b3607 --- /dev/null +++ b/include/zephyr/drivers/firmware/scmi/system.h @@ -0,0 +1,153 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_FIRMWARE_SCMI_SYSTEM_H_ +#define ZEPHYR_INCLUDE_DRIVERS_FIRMWARE_SCMI_SYSTEM_H_ + +/** + * @file + * @brief SCMI System Power Management Protocol + */ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief System protocol command message IDs + */ +enum scmi_system_message { + SCMI_SYSTEM_MSG_PROTOCOL_VERSION = 0x0, + SCMI_SYSTEM_MSG_PROTOCOL_ATTRIBUTES = 0x1, + SCMI_SYSTEM_MSG_MESSAGE_ATTRIBUTES = 0x2, + SCMI_SYSTEM_MSG_POWER_STATE_SET = 0x3, + SCMI_SYSTEM_MSG_POWER_STATE_NOTIFY = 0x5, + SCMI_SYSTEM_MSG_NEGOTIATE_PROTOCOL_VERSION = 0x10, +}; + +#define SCMI_SYSTEM_POWER_PROTOCOL_SUPPORTED_VERSION 0x20001 + +/** + * @name Standard SCMI System Power States + * @{ + */ + +/**< Shutdown off */ +#define SCMI_SYSTEM_POWER_STATE_SHUTDOWN 0x00000000U +/**< Cold reset */ +#define SCMI_SYSTEM_POWER_STATE_COLD_RESET 0x00000001U +/**< Warm reset */ +#define SCMI_SYSTEM_POWER_STATE_WARM_RESET 0x00000002U +/**< Power up */ +#define SCMI_SYSTEM_POWER_STATE_POWER_UP 0x00000003U +/**< Suspend */ +#define SCMI_SYSTEM_POWER_STATE_SUSPEND 0x00000004U + +/** @} */ + +/** + * @name System Power State flags + * @{ + */ + +/** @cond INTERNAL_HIDDEN */ +#define SCMI_SYSTEM_POWER_FLAG_SHIFT (0) +/** @endcond */ + +/**< Forceful request */ +#define SCMI_SYSTEM_POWER_FLAG_FORCEFUL (0 << SCMI_SYSTEM_POWER_FLAG_SHIFT) +/**< Graceful request */ +#define SCMI_SYSTEM_POWER_FLAG_GRACEFUL (1 << SCMI_SYSTEM_POWER_FLAG_SHIFT) + +/** @} */ + + +/*! + * @name SCMI system message attributes + * @{ + */ + +/** @cond INTERNAL_HIDDEN */ +#define SCMI_SYSTEM_MSG_ATTR_SUSPEND_SHIFT (30U) +#define SCMI_SYSTEM_MSG_ATTR_WARM_RESET_SHIFT (31U) +/** @endcond */ + +/*! System suspend support */ +#define SCMI_SYSTEM_MSG_ATTR_SUSPEND (1 << SCMI_SYSTEM_MSG_ATTR_SUSPEND_SHIFT) +/*! System warm reset support */ +#define SCMI_SYSTEM_MSG_ATTR_WARM_RESET (1 << SCMI_SYSTEM_MSG_ATTR_WARM_RESET_SHIFT) + +/** @} */ + +/** + * @struct scmi_system_power_state_config + * @brief System power state configuration + */ +struct scmi_system_power_state_config { + uint32_t flags; + uint32_t system_state; +}; + +/** + * @brief Get protocol version + * + * @param version Protocol version + * + * @retval 0 if successful + * @retval negative errno if failure + */ +int scmi_system_protocol_version(uint32_t *version); + +/** + * @brief Get protocol attributes + * + * @param attributes Protocol attributes + * + * @retval 0 if successful + * @retval negative errno if failure + */ +int scmi_system_protocol_attributes(uint32_t *attributes); + +/** + * @brief Get protocol message attributes + * + * @param message_id Message ID of the message + * @param attributes Message attributes + * + * @retval 0 if successful + * @retval negative errno if failure + */ +int scmi_system_protocol_message_attributes(uint32_t message_id, uint32_t *attributes); + +/** + * @brief Negotiate protocol version + * + * @param version desired protocol version + * + * @retval 0 if successful + * @retval negative errno if failure + */ +int scmi_system_protocol_version_negotiate(uint32_t version); + +/** + * @brief Set system power state + * + * @param cfg pointer to power state configuration + * + * @retval 0 if successful + * @retval negative errno if failure + */ +int scmi_system_power_state_set(struct scmi_system_power_state_config *cfg); + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_INCLUDE_DRIVERS_FIRMWARE_SCMI_SYSTEM_H_ */ From 2d3c40d1b368d0e60df65c73bf05fe3b1f970b85 Mon Sep 17 00:00:00 2001 From: Yongxu Wang Date: Mon, 17 Nov 2025 14:43:59 +0800 Subject: [PATCH 0101/3659] drivers: firmware: scmi: add initial reboot interface Implement sys_arch_reboot() using SCMI system power protocol for warm and cold reset operations on SCMI-enabled platforms. Signed-off-by: Yongxu Wang --- drivers/firmware/scmi/CMakeLists.txt | 1 + drivers/firmware/scmi/Kconfig | 8 ++++ drivers/firmware/scmi/reboot.c | 59 ++++++++++++++++++++++++++++ 3 files changed, 68 insertions(+) create mode 100644 drivers/firmware/scmi/reboot.c diff --git a/drivers/firmware/scmi/CMakeLists.txt b/drivers/firmware/scmi/CMakeLists.txt index d0e6128a97fe..1118c34090a6 100644 --- a/drivers/firmware/scmi/CMakeLists.txt +++ b/drivers/firmware/scmi/CMakeLists.txt @@ -11,6 +11,7 @@ zephyr_library_sources_ifdef(CONFIG_ARM_SCMI_SHMEM shmem.c) zephyr_library_sources_ifdef(CONFIG_ARM_SCMI_CLK_HELPERS clk.c) zephyr_library_sources_ifdef(CONFIG_ARM_SCMI_PINCTRL_HELPERS pinctrl.c) zephyr_library_sources_ifdef(CONFIG_ARM_SCMI_POWER_DOMAIN_HELPERS power.c) +zephyr_library_sources_ifdef(CONFIG_ARM_SCMI_REBOOT reboot.c) zephyr_library_sources_ifdef(CONFIG_ARM_SCMI_SYSTEM system.c) add_subdirectory_ifdef(CONFIG_ARM_SCMI nxp) diff --git a/drivers/firmware/scmi/Kconfig b/drivers/firmware/scmi/Kconfig index fb35de45d2a7..a1fb0ae55ba9 100644 --- a/drivers/firmware/scmi/Kconfig +++ b/drivers/firmware/scmi/Kconfig @@ -35,6 +35,14 @@ config ARM_SCMI_POWER_DOMAIN_HELPERS help Enable support for SCMI power domain protocol helper functions. +config ARM_SCMI_REBOOT + bool "SCMI system reboot support" + depends on ARM_SCMI_SYSTEM && REBOOT + default y + help + Enable system reboot functionality using SCMI system power protocol. + This provides sys_arch_reboot() implementation for platforms with SCMI. + config ARM_SCMI_SHMEM bool "SCMI shared memory (SHMEM) driver" default y diff --git a/drivers/firmware/scmi/reboot.c b/drivers/firmware/scmi/reboot.c new file mode 100644 index 000000000000..d00c3ff201ae --- /dev/null +++ b/drivers/firmware/scmi/reboot.c @@ -0,0 +1,59 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +LOG_MODULE_REGISTER(scmi_reboot, CONFIG_PM_LOG_LEVEL); + +static int scmi_reboot_handler(int type) +{ + struct scmi_system_power_state_config cfg; + int ret; + uint32_t mesg_attr; + + cfg.flags = SCMI_SYSTEM_POWER_FLAG_FORCEFUL; + + switch (type) { + case SYS_REBOOT_WARM: + ret = scmi_system_protocol_message_attributes(SCMI_SYSTEM_MSG_POWER_STATE_SET, + &mesg_attr); + if (ret < 0) { + LOG_ERR("Failed to query SCMI system capabilities: %d", ret); + return ret; + } + + if (!(mesg_attr & SCMI_SYSTEM_MSG_ATTR_WARM_RESET)) { + LOG_WRN("Warm reset not supported by platform"); + return -ENOTSUP; + } + + cfg.system_state = SCMI_SYSTEM_POWER_STATE_WARM_RESET; + break; + + case SYS_REBOOT_COLD: + cfg.system_state = SCMI_SYSTEM_POWER_STATE_COLD_RESET; + break; + + default: + LOG_ERR("Unsupported reboot type: %d", type); + return -EINVAL; + } + + ret = scmi_system_power_state_set(&cfg); + if (ret < 0) { + LOG_ERR("System reboot failed with error: %d", ret); + } + + return ret; +} + +void sys_arch_reboot(int type) +{ + scmi_reboot_handler(type); +} From 90f2a228823659fbdc246b68e31e7428a5a9eea5 Mon Sep 17 00:00:00 2001 From: Yongxu Wang Date: Thu, 20 Nov 2025 16:44:30 +0800 Subject: [PATCH 0102/3659] drivers: firmware: scmi: force polling mode for message attributes query During reboot operations, interrupts are disabled but k_is_pre_kernel() returns false, causing SCMI communication to fail when using interrupt mode. Force polling mode to ensure reliable operation in all contexts. Signed-off-by: Yongxu Wang --- drivers/firmware/scmi/common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/firmware/scmi/common.c b/drivers/firmware/scmi/common.c index d2e768c69c7a..11ff71b90f70 100644 --- a/drivers/firmware/scmi/common.c +++ b/drivers/firmware/scmi/common.c @@ -124,7 +124,7 @@ int scmi_protocol_message_attributes_get(struct scmi_protocol *proto, reply.len = sizeof(reply_buffer); reply.content = &reply_buffer; - ret = scmi_send_message(proto, &msg, &reply, k_is_pre_kernel()); + ret = scmi_send_message(proto, &msg, &reply, true); if (ret < 0) { return ret; } From e3882162cfe787742358378884961e31afa12a54 Mon Sep 17 00:00:00 2001 From: Pieter De Gendt Date: Sat, 6 Dec 2025 16:53:45 +0100 Subject: [PATCH 0103/3659] drivers: ethernet: litex: Support MAC address config Update the litex,liteeth ethernet driver to use a MAC address configuration struct. Signed-off-by: Pieter De Gendt --- drivers/ethernet/eth_litex_liteeth.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/drivers/ethernet/eth_litex_liteeth.c b/drivers/ethernet/eth_litex_liteeth.c index 6542b278fcec..810009930b1c 100644 --- a/drivers/ethernet/eth_litex_liteeth.c +++ b/drivers/ethernet/eth_litex_liteeth.c @@ -42,7 +42,7 @@ struct eth_litex_dev_data { struct eth_litex_config { const struct device *phy_dev; void (*config_func)(const struct device *dev); - bool random_mac_address; + struct net_eth_mac_config mcfg; uint32_t rx_slot_addr; uint32_t rx_length_addr; uint32_t rx_ev_pending_addr; @@ -69,10 +69,7 @@ static int eth_initialize(const struct device *dev) config->config_func(dev); - if (config->random_mac_address) { - /* generate random MAC address */ - gen_random_mac(context->mac_addr, 0x10, 0xe2, 0xd5); - } + (void)net_eth_mac_load(&config->mcfg, context->mac_addr); return 0; } @@ -330,14 +327,12 @@ static const struct ethernet_api eth_api = { irq_enable(DT_INST_IRQN(n)); \ } \ \ - static struct eth_litex_dev_data eth_data##n = { \ - .mac_addr = DT_INST_PROP_OR(n, local_mac_address, {0}), \ - }; \ + static struct eth_litex_dev_data eth_data##n; \ \ static const struct eth_litex_config eth_config##n = { \ .phy_dev = DEVICE_DT_GET_OR_NULL(DT_INST_PHANDLE(n, phy_handle)), \ .config_func = eth_irq_config##n, \ - .random_mac_address = DT_INST_PROP(n, zephyr_random_mac_address), \ + .mcfg = NET_ETH_MAC_DT_INST_CONFIG_INIT(n), \ .rx_slot_addr = DT_INST_REG_ADDR_BY_NAME(n, rx_slot), \ .rx_length_addr = DT_INST_REG_ADDR_BY_NAME(n, rx_length), \ .rx_ev_pending_addr = DT_INST_REG_ADDR_BY_NAME(n, rx_ev_pending), \ From 90e81504aed3299a21e1b3387fee0be9cc26c061 Mon Sep 17 00:00:00 2001 From: Marek Matej Date: Wed, 26 Nov 2025 16:14:52 +0000 Subject: [PATCH 0104/3659] soc: espressif: hide AMP configs Hide AMP configs if not used. Provide safe SRAM values for synthetic appcpu targets. Signed-off-by: Marek Matej --- soc/espressif/common/Kconfig.amp | 6 +++++- soc/espressif/esp32/memory.h | 10 ++++++++-- soc/espressif/esp32s3/memory.h | 10 +++++++++- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/soc/espressif/common/Kconfig.amp b/soc/espressif/common/Kconfig.amp index cce7c8669287..96e2ad9472b3 100644 --- a/soc/espressif/common/Kconfig.amp +++ b/soc/espressif/common/Kconfig.amp @@ -9,6 +9,8 @@ config SOC_ENABLE_APPCPU help This hidden configuration lets PROCPU core to map and start APPCPU whenever IPM is enabled. +if SOC_ENABLE_APPCPU + menu "Espressif AMP Config" config ESP_APPCPU_IRAM_SIZE @@ -35,4 +37,6 @@ config ESP_APPCPU_DROM_SIZE help Defines APPCPU DROM area size in bytes. -endmenu # AMP config +endmenu # AMP menu + +endif # SOC_ENABLE_APPCPU config diff --git a/soc/espressif/esp32/memory.h b/soc/espressif/esp32/memory.h index 08098406dc17..231803574d60 100644 --- a/soc/espressif/esp32/memory.h +++ b/soc/espressif/esp32/memory.h @@ -86,13 +86,19 @@ #endif /* AMP memory */ -#if defined(CONFIG_SOC_ENABLE_APPCPU) || defined(CONFIG_SOC_ESP32_APPCPU) +#if defined(CONFIG_SOC_ESP32_APPCPU) +#if defined(CONFIG_SOC_ENABLE_APPCPU) #define APPCPU_IRAM_SIZE CONFIG_ESP_APPCPU_IRAM_SIZE #define APPCPU_DRAM_SIZE CONFIG_ESP_APPCPU_DRAM_SIZE #else +/* Fallback for non-AMP APPCPU builds */ +#define APPCPU_IRAM_SIZE 0x8000 +#define APPCPU_DRAM_SIZE 0x8000 +#endif /* CONFIG_SOC_ENABLE_APPCPU */ +#else #define APPCPU_IRAM_SIZE 0 #define APPCPU_DRAM_SIZE 0 -#endif +#endif /* CONFIG_SOC_ESP32_APPCPU */ #define APPCPU_SRAM_SIZE (APPCPU_IRAM_SIZE + APPCPU_DRAM_SIZE) diff --git a/soc/espressif/esp32s3/memory.h b/soc/espressif/esp32s3/memory.h index 7ec93526c4c8..ce08a0358ab0 100644 --- a/soc/espressif/esp32s3/memory.h +++ b/soc/espressif/esp32s3/memory.h @@ -86,7 +86,8 @@ #define USER_IRAM_END (USER_DRAM_END + IRAM_DRAM_OFFSET) /* AMP */ -#if (defined(CONFIG_SOC_ENABLE_APPCPU) || defined(CONFIG_SOC_ESP32S3_APPCPU)) +#if defined(CONFIG_SOC_ESP32S3_APPCPU) +#if defined(CONFIG_SOC_ENABLE_APPCPU) #define APPCPU_IRAM_SIZE CONFIG_ESP_APPCPU_IRAM_SIZE #define APPCPU_DRAM_SIZE CONFIG_ESP_APPCPU_DRAM_SIZE #define AMP_COMM_SIZE DT_REG_SIZE(DT_NODELABEL(ipmmem0)) + DT_REG_SIZE(DT_NODELABEL(shm0)) + \ @@ -96,6 +97,13 @@ #define APPCPU_IROM_SIZE CONFIG_ESP_APPCPU_IROM_SIZE #define APPCPU_DROM_SIZE CONFIG_ESP_APPCPU_DROM_SIZE #else +/* Fallback for non-AMP APPCPU builds */ +#define APPCPU_IRAM_SIZE 0x8000 +#define APPCPU_DRAM_SIZE 0x8000 +#define APPCPU_IROM_SIZE 0x10000 +#define APPCPU_DROM_SIZE 0x10000 +#endif /* CONFIG_SOC_ENABLE_APPCPU */ +#else #define APPCPU_IRAM_SIZE 0 #define APPCPU_DRAM_SIZE 0 #define AMP_COMM_SIZE 0 From 432d9d2a6b87a08479dfea7527f051e86b275b92 Mon Sep 17 00:00:00 2001 From: Vijay Sharma Date: Thu, 9 Oct 2025 10:54:34 +0530 Subject: [PATCH 0105/3659] tracing: trace timer calls Add tracing support for timer expiry and stop function callbacks, enabling measurement of callback execution duration and facilitating debugging of cases where callbacks take longer than expected. Signed-off-by: Vijay Sharma --- include/zephyr/tracing/tracing.h | 24 +++++++ kernel/timer.c | 10 +++ subsys/tracing/ctf/ctf_top.c | 20 ++++++ subsys/tracing/ctf/ctf_top.h | 25 ++++++++ subsys/tracing/ctf/tracing_ctf.h | 10 +++ subsys/tracing/ctf/tsdl/metadata | 32 ++++++++++ subsys/tracing/sysview/tracing_sysview.h | 12 ++++ subsys/tracing/sysview/tracing_sysview_ids.h | 5 +- .../tracing/test/tracing_string_format_test.c | 19 ++++++ subsys/tracing/test/tracing_test.h | 12 ++++ subsys/tracing/user/tracing_user.c | 63 +++++++++++++++++++ subsys/tracing/user/tracing_user.h | 36 +++++++++-- 12 files changed, 261 insertions(+), 7 deletions(-) diff --git a/include/zephyr/tracing/tracing.h b/include/zephyr/tracing/tracing.h index fdc816eb2c4a..9ba27a8389b3 100644 --- a/include/zephyr/tracing/tracing.h +++ b/include/zephyr/tracing/tracing.h @@ -1923,6 +1923,30 @@ */ #define sys_port_trace_k_timer_status_sync_exit(timer, result) +/** + * @brief Trace Timer expiry entry + * @param timer Timer object + */ +#define sys_port_trace_k_timer_expiry_enter(timer) + +/** + * @brief Trace Timer expiry exit + * @param timer Timer object + */ +#define sys_port_trace_k_timer_expiry_exit(timer) + +/** + * @brief Trace Timer stop function expiry entry + * @param timer Timer object + */ +#define sys_port_trace_k_timer_stop_fn_expiry_enter(timer) + +/** + * @brief Trace Timer stop function expiry exit + * @param timer Timer object + */ +#define sys_port_trace_k_timer_stop_fn_expiry_exit(timer) + /** @} */ /* end of subsys_tracing_apis_timer */ /** diff --git a/kernel/timer.c b/kernel/timer.c index 0fa14b55315d..7938323e706a 100644 --- a/kernel/timer.c +++ b/kernel/timer.c @@ -84,7 +84,13 @@ void z_timer_expiration_handler(struct _timeout *t) if (timer->expiry_fn != NULL) { /* Unlock for user handler. */ k_spin_unlock(&lock, key); + + SYS_PORT_TRACING_OBJ_FUNC_ENTER(k_timer, expiry, timer); + timer->expiry_fn(timer); + + SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_timer, expiry, timer); + key = k_spin_lock(&lock); } @@ -207,7 +213,11 @@ void z_impl_k_timer_stop(struct k_timer *timer) } if (timer->stop_fn != NULL) { + SYS_PORT_TRACING_OBJ_FUNC_ENTER(k_timer, stop_fn_expiry, timer); + timer->stop_fn(timer); + + SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_timer, stop_fn_expiry, timer); } if (IS_ENABLED(CONFIG_MULTITHREADING)) { diff --git a/subsys/tracing/ctf/ctf_top.c b/subsys/tracing/ctf/ctf_top.c index c9717ddcc173..7d1a17042755 100644 --- a/subsys/tracing/ctf/ctf_top.c +++ b/subsys/tracing/ctf/ctf_top.c @@ -939,6 +939,26 @@ void sys_trace_k_timer_status_sync_exit(struct k_timer *timer, uint32_t result) ctf_top_timer_status_sync_exit((uint32_t)(uintptr_t)timer, result); } +void sys_trace_k_timer_expiry_enter(struct k_timer *timer) +{ + ctf_top_timer_expiry_enter((uint32_t)(uintptr_t)timer); +} + +void sys_trace_k_timer_expiry_exit(struct k_timer *timer) +{ + ctf_top_timer_expiry_exit((uint32_t)(uintptr_t)timer); +} + +void sys_trace_k_timer_stop_fn_expiry_enter(struct k_timer *timer) +{ + ctf_top_timer_stop_fn_expiry_enter((uint32_t)(uintptr_t)timer); +} + +void sys_trace_k_timer_stop_fn_expiry_exit(struct k_timer *timer) +{ + ctf_top_timer_stop_fn_expiry_exit((uint32_t)(uintptr_t)timer); +} + /* Network socket */ void sys_trace_socket_init(int sock, int family, int type, int proto) { diff --git a/subsys/tracing/ctf/ctf_top.h b/subsys/tracing/ctf/ctf_top.h index 60316aa04d00..6b3dd62d003a 100644 --- a/subsys/tracing/ctf/ctf_top.h +++ b/subsys/tracing/ctf/ctf_top.h @@ -336,6 +336,11 @@ typedef enum { CTF_EVENT_EVENT_WAIT_BLOCKING = 0xFE, CTF_EVENT_EVENT_WAIT_EXIT = 0xFF, + CTF_EVENT_TIMER_EXPIRY_ENTER = 0x100, + CTF_EVENT_TIMER_EXPIRY_EXIT = 0x101, + CTF_EVENT_TIMER_STOP_FN_EXPIRY_ENTER = 0x102, + CTF_EVENT_TIMER_STOP_FN_EXPIRY_EXIT = 0x103, + } ctf_event_t; typedef struct { @@ -1116,6 +1121,26 @@ static inline void ctf_top_timer_status_sync_exit(uint32_t timer, uint32_t resul CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_TIMER_STATUS_SYNC_EXIT), timer, result); } +static inline void ctf_top_timer_expiry_enter(uint32_t timer) +{ + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_TIMER_EXPIRY_ENTER), timer); +} + +static inline void ctf_top_timer_expiry_exit(uint32_t timer) +{ + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_TIMER_EXPIRY_EXIT), timer); +} + +static inline void ctf_top_timer_stop_fn_expiry_enter(uint32_t timer) +{ + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_TIMER_STOP_FN_EXPIRY_ENTER), timer); +} + +static inline void ctf_top_timer_stop_fn_expiry_exit(uint32_t timer) +{ + CTF_EVENT(CTF_LITERAL(uint16_t, CTF_EVENT_TIMER_STOP_FN_EXPIRY_EXIT), timer); +} + /* Network socket */ typedef struct { char buf[CTF_NET_MAX_STRING_LEN]; diff --git a/subsys/tracing/ctf/tracing_ctf.h b/subsys/tracing/ctf/tracing_ctf.h index 319e76c27488..4a6162e6c61f 100644 --- a/subsys/tracing/ctf/tracing_ctf.h +++ b/subsys/tracing/ctf/tracing_ctf.h @@ -198,6 +198,12 @@ extern "C" { sys_trace_k_timer_status_sync_blocking(timer, timeout) #define sys_port_trace_k_timer_status_sync_exit(timer, result) \ sys_trace_k_timer_status_sync_exit(timer, result) +#define sys_port_trace_k_timer_expiry_enter(timer) sys_trace_k_timer_expiry_enter(timer) +#define sys_port_trace_k_timer_expiry_exit(timer) sys_trace_k_timer_expiry_exit(timer) +#define sys_port_trace_k_timer_stop_fn_expiry_enter(timer) \ + sys_trace_k_timer_stop_fn_expiry_enter(timer) +#define sys_port_trace_k_timer_stop_fn_expiry_exit(timer) \ + sys_trace_k_timer_stop_fn_expiry_exit(timer) #define sys_port_trace_k_condvar_init(condvar, ret) sys_trace_k_condvar_init(condvar, ret) #define sys_port_trace_k_condvar_signal_enter(condvar) sys_trace_k_condvar_signal_enter(condvar) @@ -602,6 +608,10 @@ void sys_trace_k_timer_stop(struct k_timer *timer); void sys_trace_k_timer_status_sync_blocking(struct k_timer *timer, k_timeout_t timeout); void sys_trace_k_timer_status_sync_enter(struct k_timer *timer); void sys_trace_k_timer_status_sync_exit(struct k_timer *timer, uint32_t result); +void sys_trace_k_timer_expiry_enter(struct k_timer *timer); +void sys_trace_k_timer_expiry_exit(struct k_timer *timer); +void sys_trace_k_timer_stop_fn_expiry_enter(struct k_timer *timer); +void sys_trace_k_timer_stop_fn_expiry_exit(struct k_timer *timer); /* Mailbox */ void sys_trace_k_mbox_init(struct k_mbox *mbox); diff --git a/subsys/tracing/ctf/tsdl/metadata b/subsys/tracing/ctf/tsdl/metadata index 972d8d8b9924..cfac9d41b539 100644 --- a/subsys/tracing/ctf/tsdl/metadata +++ b/subsys/tracing/ctf/tsdl/metadata @@ -2197,3 +2197,35 @@ event { int32_t ret; }; }; + +event { + name = timer_expiry_enter; + id = 0x100; + fields := struct { + uint32_t id; + }; +}; + +event { + name = timer_expiry_exit; + id = 0x101; + fields := struct { + uint32_t id; + }; +}; + +event { + name = timer_stop_fn_expiry_enter; + id = 0x102; + fields := struct { + uint32_t id; + }; +}; + +event { + name = timer_stop_fn_expiry_exit; + id = 0x103; + fields := struct { + uint32_t id; + }; +}; diff --git a/subsys/tracing/sysview/tracing_sysview.h b/subsys/tracing/sysview/tracing_sysview.h index 38d1eec61e14..b982d1c7101c 100644 --- a/subsys/tracing/sysview/tracing_sysview.h +++ b/subsys/tracing/sysview/tracing_sysview.h @@ -733,6 +733,18 @@ void sys_trace_thread_info(struct k_thread *thread); #define sys_port_trace_k_timer_status_sync_exit(timer, result) \ SEGGER_SYSVIEW_RecordEndCallU32(TID_TIMER_STATUS_SYNC, (uint32_t)result) +#define sys_port_trace_k_timer_expiry_enter(timer) \ + SEGGER_SYSVIEW_RecordU32(TID_TIMER_EXPIRY, (uint32_t)(uintptr_t)timer) + +#define sys_port_trace_k_timer_expiry_exit(timer) \ + SEGGER_SYSVIEW_RecordEndCall(TID_TIMER_EXPIRY) + +#define sys_port_trace_k_timer_stop_fn_expiry_enter(timer) \ + SEGGER_SYSVIEW_RecordU32(TID_TIMER_STOP_EXPIRY, (uint32_t)(uintptr_t)timer) + +#define sys_port_trace_k_timer_stop_fn_expiry_exit(timer) \ + SEGGER_SYSVIEW_RecordEndCall(TID_TIMER_STOP_EXPIRY) + #define sys_port_trace_syscall_enter(id, name, ...) \ SEGGER_SYSVIEW_RecordString(TID_SYSCALL, (const char *)#name) diff --git a/subsys/tracing/sysview/tracing_sysview_ids.h b/subsys/tracing/sysview/tracing_sysview_ids.h index 246a9d58b0f4..6d3a2f193eec 100644 --- a/subsys/tracing/sysview/tracing_sysview_ids.h +++ b/subsys/tracing/sysview/tracing_sysview_ids.h @@ -163,7 +163,10 @@ extern "C" { #define TID_EVENT_POST (133u + TID_OFFSET) #define TID_EVENT_WAIT (134u + TID_OFFSET) -/* latest ID is 134 */ +#define TID_TIMER_EXPIRY (135u + TID_OFFSET) +#define TID_TIMER_STOP_EXPIRY (136u + TID_OFFSET) + +/* latest ID is 136 */ #ifdef __cplusplus } diff --git a/subsys/tracing/test/tracing_string_format_test.c b/subsys/tracing/test/tracing_string_format_test.c index 1dec7339fcbb..323277da663f 100644 --- a/subsys/tracing/test/tracing_string_format_test.c +++ b/subsys/tracing/test/tracing_string_format_test.c @@ -348,6 +348,25 @@ void sys_trace_k_timer_status_sync_exit(struct k_timer *timer, uint32_t result) TRACING_STRING("%s: %p\n", __func__, timer); } +void sys_trace_k_timer_expiry_enter(struct k_timer *timer) +{ + TRACING_STRING("%s: %p\n", __func__, timer); +} + +void sys_trace_k_timer_expiry_exit(struct k_timer *timer) +{ + TRACING_STRING("%s: %p\n", __func__, timer); +} + +void sys_trace_k_timer_stop_fn_expiry_enter(struct k_timer *timer) +{ + TRACING_STRING("%s: %p\n", __func__, timer); +} + +void sys_trace_k_timer_stop_fn_expiry_exit(struct k_timer *timer) +{ + TRACING_STRING("%s: %p\n", __func__, timer); +} void sys_trace_k_heap_init(struct k_heap *h, void *mem, size_t bytes) { diff --git a/subsys/tracing/test/tracing_test.h b/subsys/tracing/test/tracing_test.h index a58f9f61c5e8..55d527007d3d 100644 --- a/subsys/tracing/test/tracing_test.h +++ b/subsys/tracing/test/tracing_test.h @@ -429,6 +429,14 @@ sys_trace_k_timer_status_sync_blocking(timer) #define sys_port_trace_k_timer_status_sync_exit(timer, result) \ sys_trace_k_timer_status_sync_exit(timer, result) +#define sys_port_trace_k_timer_expiry_enter(timer) \ + sys_trace_k_timer_expiry_enter(timer) +#define sys_port_trace_k_timer_expiry_exit(timer) \ + sys_trace_k_timer_expiry_exit(timer) +#define sys_port_trace_k_timer_stop_fn_expiry_enter(timer) \ + sys_trace_k_timer_stop_fn_expiry_enter(timer) +#define sys_port_trace_k_timer_stop_fn_expiry_exit(timer) \ + sys_trace_k_timer_stop_fn_expiry_exit(timer) #define sys_port_trace_k_event_init(event) sys_trace_k_event_init(event) #define sys_port_trace_k_event_post_enter(event, events, events_mask) \ @@ -694,6 +702,10 @@ void sys_trace_k_timer_start(struct k_timer *timer, k_timeout_t duration, k_time void sys_trace_k_timer_stop(struct k_timer *timer); void sys_trace_k_timer_status_sync_blocking(struct k_timer *timer); void sys_trace_k_timer_status_sync_exit(struct k_timer *timer, uint32_t result); +void sys_trace_k_timer_expiry_enter(struct k_timer *timer); +void sys_trace_k_timer_expiry_exit(struct k_timer *timer); +void sys_trace_k_timer_stop_fn_expiry_enter(struct k_timer *timer); +void sys_trace_k_timer_stop_fn_expiry_exit(struct k_timer *timer); void sys_trace_k_event_init(struct k_event *event); void sys_trace_k_event_post_enter(struct k_event *event, uint32_t events, uint32_t events_mask); diff --git a/subsys/tracing/user/tracing_user.c b/subsys/tracing/user/tracing_user.c index e807f2c15e20..b10825a3abb8 100644 --- a/subsys/tracing/user/tracing_user.c +++ b/subsys/tracing/user/tracing_user.c @@ -75,6 +75,19 @@ void __weak sys_trace_gpio_fire_callbacks_enter_user(sys_slist_t *list, const st gpio_pin_t pins) {} void __weak sys_trace_gpio_fire_callback_user(const struct device *port, struct gpio_callback *callback) {} +void __weak sys_trace_timer_init_user(struct k_timer *timer) {} +void __weak sys_trace_timer_start_user(struct k_timer *timer, k_timeout_t duration, + k_timeout_t period) +{} +void __weak sys_trace_timer_stop_user(struct k_timer *timer) {} +void __weak sys_trace_timer_status_sync_enter_user(struct k_timer *timer) {} +void __weak sys_trace_timer_status_sync_blocking_user(struct k_timer *timer, k_timeout_t timeout) +{} +void __weak sys_trace_timer_status_sync_exit_user(struct k_timer *timer, uint32_t result) {} +void __weak sys_trace_timer_expiry_enter_user(struct k_timer *timer) {} +void __weak sys_trace_timer_expiry_exit_user(struct k_timer *timer) {} +void __weak sys_trace_timer_stop_fn_expiry_enter_user(struct k_timer *timer) {} +void __weak sys_trace_timer_stop_fn_expiry_exit_user(struct k_timer *timer) {} void __weak sys_trace_rtio_submit_enter_user(const struct rtio *r, uint32_t wait_count) { @@ -463,3 +476,53 @@ void sys_trace_rtio_chain_next_exit(const struct rtio *r, const struct rtio_iode { sys_trace_rtio_chain_next_exit_user(r, iodev_sqe); } + +void sys_trace_timer_init(struct k_timer *timer) +{ + sys_trace_timer_init_user(timer); +} + +void sys_trace_timer_start(struct k_timer *timer, k_timeout_t duration, k_timeout_t period) +{ + sys_trace_timer_start_user(timer, duration, period); +} + +void sys_trace_timer_stop(struct k_timer *timer) +{ + sys_trace_timer_stop_user(timer); +} + +void sys_trace_timer_status_sync_enter(struct k_timer *timer) +{ + sys_trace_timer_status_sync_enter_user(timer); +} + +void sys_trace_timer_status_sync_blocking(struct k_timer *timer, k_timeout_t timeout) +{ + sys_trace_timer_status_sync_blocking_user(timer, timeout); +} + +void sys_trace_timer_status_sync_exit(struct k_timer *timer, uint32_t result) +{ + sys_trace_timer_status_sync_exit_user(timer, result); +} + +void sys_trace_timer_expiry_enter(struct k_timer *timer) +{ + sys_trace_timer_expiry_enter_user(timer); +} + +void sys_trace_timer_expiry_exit(struct k_timer *timer) +{ + sys_trace_timer_expiry_exit_user(timer); +} + +void sys_trace_timer_stop_fn_expiry_enter(struct k_timer *timer) +{ + sys_trace_timer_stop_fn_expiry_enter_user(timer); +} + +void sys_trace_timer_stop_fn_expiry_exit(struct k_timer *timer) +{ + sys_trace_timer_stop_fn_expiry_exit_user(timer); +} diff --git a/subsys/tracing/user/tracing_user.h b/subsys/tracing/user/tracing_user.h index 85477c1badcd..6a6c93bcd15f 100644 --- a/subsys/tracing/user/tracing_user.h +++ b/subsys/tracing/user/tracing_user.h @@ -49,6 +49,16 @@ void sys_trace_idle(void); void sys_trace_idle_exit(void); void sys_trace_sys_init_enter(const struct init_entry *entry, int level); void sys_trace_sys_init_exit(const struct init_entry *entry, int level, int result); +void sys_trace_timer_init(struct k_timer *timer); +void sys_trace_timer_start(struct k_timer *timer, k_timeout_t duration, k_timeout_t period); +void sys_trace_timer_stop(struct k_timer *timer); +void sys_trace_timer_status_sync_enter(struct k_timer *timer); +void sys_trace_timer_status_sync_blocking(struct k_timer *timer, k_timeout_t timeout); +void sys_trace_timer_status_sync_exit(struct k_timer *timer, uint32_t result); +void sys_trace_timer_expiry_enter(struct k_timer *timer); +void sys_trace_timer_expiry_exit(struct k_timer *timer); +void sys_trace_timer_stop_fn_expiry_enter(struct k_timer *timer); +void sys_trace_timer_stop_fn_expiry_exit(struct k_timer *timer); struct rtio; struct rtio_sqe; @@ -388,12 +398,26 @@ void sys_trace_rtio_chain_next_exit(const struct rtio *r, const struct rtio_iode #define sys_port_trace_k_mem_slab_free_enter(slab) #define sys_port_trace_k_mem_slab_free_exit(slab) -#define sys_port_trace_k_timer_init(timer) -#define sys_port_trace_k_timer_start(timer, duration, period) -#define sys_port_trace_k_timer_stop(timer) -#define sys_port_trace_k_timer_status_sync_enter(timer) -#define sys_port_trace_k_timer_status_sync_blocking(timer, timeout) -#define sys_port_trace_k_timer_status_sync_exit(timer, result) +#define sys_port_trace_k_timer_init(timer) \ + sys_trace_timer_init(timer) +#define sys_port_trace_k_timer_start(timer, duration, period) \ + sys_trace_timer_start(timer, duration, period) +#define sys_port_trace_k_timer_stop(timer) \ + sys_trace_timer_stop(timer) +#define sys_port_trace_k_timer_status_sync_enter(timer) \ + sys_trace_timer_status_sync_enter(timer) +#define sys_port_trace_k_timer_status_sync_blocking(timer, timeout) \ + sys_trace_timer_status_sync_blocking(timer, timeout) +#define sys_port_trace_k_timer_status_sync_exit(timer, result) \ + sys_trace_timer_status_sync_exit(timer, result) +#define sys_port_trace_k_timer_expiry_enter(timer) \ + sys_trace_timer_expiry_enter(timer) +#define sys_port_trace_k_timer_expiry_exit(timer) \ + sys_trace_timer_expiry_exit(timer) +#define sys_port_trace_k_timer_stop_fn_expiry_enter(timer) \ + sys_trace_timer_stop_fn_expiry_enter(timer) +#define sys_port_trace_k_timer_stop_fn_expiry_exit(timer) \ + sys_trace_timer_stop_fn_expiry_exit(timer) #define sys_port_trace_k_event_init(event) #define sys_port_trace_k_event_post_enter(event, events, events_mask) From 81e37ad4e853d0e25f6e1814d91aa87363002a62 Mon Sep 17 00:00:00 2001 From: Kai Vehmanen Date: Mon, 1 Dec 2025 14:31:58 +0200 Subject: [PATCH 0106/3659] drivers: dai: add ability to use dai.h from user threads Add user-space support to the dai.h interface. No functional impact to builds when CONFIG_USERSPACE is not set. Signed-off-by: Kai Vehmanen --- drivers/dai/CMakeLists.txt | 3 + drivers/dai/dai_handlers.c | 133 +++++++++++++++++++++++++++++++++++ include/zephyr/drivers/dai.h | 73 +++++++++++++------ 3 files changed, 189 insertions(+), 20 deletions(-) create mode 100644 drivers/dai/dai_handlers.c diff --git a/drivers/dai/CMakeLists.txt b/drivers/dai/CMakeLists.txt index 332a792981d1..523fcb6a4885 100644 --- a/drivers/dai/CMakeLists.txt +++ b/drivers/dai/CMakeLists.txt @@ -9,3 +9,6 @@ add_subdirectory_ifdef(CONFIG_DAI_NXP_ESAI nxp/esai) add_subdirectory_ifdef(CONFIG_DAI_NXP_MICFIL nxp/micfil) add_subdirectory_ifdef(CONFIG_DAI_NXP_SAI nxp/sai) # zephyr-keep-sorted-stop + +zephyr_syscall_header(${ZEPHYR_BASE}/include/zephyr/drivers/dai.h) +zephyr_library_sources_ifdef(CONFIG_USERSPACE dai_handlers.c) diff --git a/drivers/dai/dai_handlers.c b/drivers/dai/dai_handlers.c new file mode 100644 index 000000000000..debba1635fb2 --- /dev/null +++ b/drivers/dai/dai_handlers.c @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2025 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/** + * Maximum size of bespoke objects passed to DAI driver. + * The objects get allocated temporarily on stack for validation, + * so size needs to be limited. + */ +#define DAI_MAX_BESPOKE_CFG_SIZE 256 + +static inline int z_vrfy_dai_probe(const struct device *dev) +{ + K_OOPS(K_SYSCALL_DRIVER_DAI(dev, probe)); + + return z_impl_dai_probe(dev); +} +#include + +static inline int z_vrfy_dai_remove(const struct device *dev) +{ + K_OOPS(K_SYSCALL_DRIVER_DAI(dev, remove)); + + return z_impl_dai_remove(dev); +} +#include + +static inline int z_vrfy_dai_config_set(const struct device *dev, + const struct dai_config *cfg, + const void *bespoke_cfg, + size_t size) +{ + uint8_t bespoke_cfg_kernel[DAI_MAX_BESPOKE_CFG_SIZE]; + + if (size > DAI_MAX_BESPOKE_CFG_SIZE) { + return -EINVAL; + } + + K_OOPS(K_SYSCALL_DRIVER_DAI(dev, config_set)); + K_OOPS(k_usermode_from_copy(bespoke_cfg_kernel, bespoke_cfg, size)); + + return z_impl_dai_config_set(dev, cfg, bespoke_cfg_kernel, size); +} +#include + +static inline int z_vrfy_dai_config_get(const struct device *dev, + struct dai_config *cfg, + enum dai_dir dir) +{ + K_OOPS(K_SYSCALL_DRIVER_DAI(dev, config_get)); + K_OOPS(K_SYSCALL_MEMORY_WRITE(cfg, sizeof(*cfg))); + + return z_impl_dai_config_get(dev, cfg, dir); +} +#include + +static inline int z_vrfy_dai_trigger(const struct device *dev, + enum dai_dir dir, + enum dai_trigger_cmd cmd) +{ + K_OOPS(K_SYSCALL_DRIVER_DAI(dev, trigger)); + + return z_impl_dai_trigger(dev, dir, cmd); +} +#include + +static inline int z_vrfy_dai_ts_config(const struct device *dev, struct dai_ts_cfg *cfg) +{ + struct dai_ts_cfg cfg_kernel; + + K_OOPS(K_SYSCALL_DRIVER_DAI(dev, ts_config)); + K_OOPS(k_usermode_from_copy(&cfg_kernel, cfg, sizeof(cfg_kernel))); + + return z_impl_dai_ts_config(dev, &cfg_kernel); +} +#include + +static inline int z_vrfy_dai_ts_start(const struct device *dev, struct dai_ts_cfg *cfg) +{ + struct dai_ts_cfg cfg_kernel; + + K_OOPS(K_SYSCALL_DRIVER_DAI(dev, ts_start)); + K_OOPS(k_usermode_from_copy(&cfg_kernel, cfg, sizeof(cfg_kernel))); + + return z_impl_dai_ts_start(dev, &cfg_kernel); +} +#include + +static inline int z_vrfy_dai_ts_stop(const struct device *dev, struct dai_ts_cfg *cfg) +{ + struct dai_ts_cfg cfg_kernel; + + K_OOPS(K_SYSCALL_DRIVER_DAI(dev, ts_stop)); + K_OOPS(k_usermode_from_copy(&cfg_kernel, cfg, sizeof(cfg_kernel))); + + return z_impl_dai_ts_stop(dev, &cfg_kernel); +} +#include + +static inline int z_vrfy_dai_ts_get(const struct device *dev, struct dai_ts_cfg *cfg, + struct dai_ts_data *tsd) +{ + struct dai_ts_cfg cfg_kernel; + + K_OOPS(K_SYSCALL_DRIVER_DAI(dev, ts_get)); + K_OOPS(k_usermode_from_copy(&cfg_kernel, cfg, sizeof(cfg_kernel))); + K_OOPS(K_SYSCALL_MEMORY_WRITE(tsd, sizeof(*tsd))); + + return z_impl_dai_ts_get(dev, &cfg_kernel, tsd); +} +#include + +static inline int z_vrfy_dai_config_update(const struct device *dev, + const void *bespoke_cfg, + size_t size) +{ + uint8_t bespoke_cfg_kernel[DAI_MAX_BESPOKE_CFG_SIZE]; + + if (size > DAI_MAX_BESPOKE_CFG_SIZE) { + return -EINVAL; + } + + K_OOPS(K_SYSCALL_DRIVER_DAI(dev, config_update)); + K_OOPS(k_usermode_from_copy(bespoke_cfg_kernel, bespoke_cfg, size)); + + return z_impl_dai_config_update(dev, bespoke_cfg_kernel, size); +} +#include diff --git a/include/zephyr/drivers/dai.h b/include/zephyr/drivers/dai.h index 889effea783d..f3e40dd94690 100644 --- a/include/zephyr/drivers/dai.h +++ b/include/zephyr/drivers/dai.h @@ -351,7 +351,9 @@ __subsystem struct dai_driver_api { * * @retval 0 If successful. */ -static inline int dai_probe(const struct device *dev) +__syscall int dai_probe(const struct device *dev); + +static inline int z_impl_dai_probe(const struct device *dev) { const struct dai_driver_api *api = (const struct dai_driver_api *)dev->api; @@ -368,7 +370,9 @@ static inline int dai_probe(const struct device *dev) * * @retval 0 If successful. */ -static inline int dai_remove(const struct device *dev) +__syscall int dai_remove(const struct device *dev); + +static inline int z_impl_dai_remove(const struct device *dev) { const struct dai_driver_api *api = (const struct dai_driver_api *)dev->api; @@ -396,10 +400,16 @@ static inline int dai_remove(const struct device *dev) * @retval -EINVAL Invalid argument. * @retval -ENOSYS DAI_DIR_BOTH value is not supported. */ -static inline int dai_config_set(const struct device *dev, - const struct dai_config *cfg, - const void *bespoke_cfg, - size_t size) + +__syscall int dai_config_set(const struct device *dev, + const struct dai_config *cfg, + const void *bespoke_cfg, + size_t size); + +static inline int z_impl_dai_config_set(const struct device *dev, + const struct dai_config *cfg, + const void *bespoke_cfg, + size_t size) { const struct dai_driver_api *api = (const struct dai_driver_api *)dev->api; @@ -414,9 +424,13 @@ static inline int dai_config_set(const struct device *dev, * @param dir Stream direction: RX or TX as defined by DAI_DIR_* * @return 0 if success, negative if invalid parameters or DAI un-configured */ -static inline int dai_config_get(const struct device *dev, - struct dai_config *cfg, - enum dai_dir dir) +__syscall int dai_config_get(const struct device *dev, + struct dai_config *cfg, + enum dai_dir dir); + +static inline int z_impl_dai_config_get(const struct device *dev, + struct dai_config *cfg, + enum dai_dir dir) { const struct dai_driver_api *api = (const struct dai_driver_api *)dev->api; @@ -459,9 +473,13 @@ static inline const struct dai_properties *dai_get_properties(const struct devic * @retval -ENOMEM RX/TX memory block not available. * @retval -ENOSYS DAI_DIR_BOTH value is not supported. */ -static inline int dai_trigger(const struct device *dev, - enum dai_dir dir, - enum dai_trigger_cmd cmd) +__syscall int dai_trigger(const struct device *dev, + enum dai_dir dir, + enum dai_trigger_cmd cmd); + +static inline int z_impl_dai_trigger(const struct device *dev, + enum dai_dir dir, + enum dai_trigger_cmd cmd) { const struct dai_driver_api *api = (const struct dai_driver_api *)dev->api; @@ -477,7 +495,9 @@ static inline int dai_trigger(const struct device *dev, * * @retval 0 If successful. */ -static inline int dai_ts_config(const struct device *dev, struct dai_ts_cfg *cfg) +__syscall int dai_ts_config(const struct device *dev, struct dai_ts_cfg *cfg); + +static inline int z_impl_dai_ts_config(const struct device *dev, struct dai_ts_cfg *cfg) { const struct dai_driver_api *api = (const struct dai_driver_api *)dev->api; @@ -497,7 +517,9 @@ static inline int dai_ts_config(const struct device *dev, struct dai_ts_cfg *cfg * * @retval 0 If successful. */ -static inline int dai_ts_start(const struct device *dev, struct dai_ts_cfg *cfg) +__syscall int dai_ts_start(const struct device *dev, struct dai_ts_cfg *cfg); + +static inline int z_impl_dai_ts_start(const struct device *dev, struct dai_ts_cfg *cfg) { const struct dai_driver_api *api = (const struct dai_driver_api *)dev->api; @@ -517,7 +539,9 @@ static inline int dai_ts_start(const struct device *dev, struct dai_ts_cfg *cfg) * * @retval 0 If successful. */ -static inline int dai_ts_stop(const struct device *dev, struct dai_ts_cfg *cfg) +__syscall int dai_ts_stop(const struct device *dev, struct dai_ts_cfg *cfg); + +static inline int z_impl_dai_ts_stop(const struct device *dev, struct dai_ts_cfg *cfg) { const struct dai_driver_api *api = (const struct dai_driver_api *)dev->api; @@ -538,8 +562,11 @@ static inline int dai_ts_stop(const struct device *dev, struct dai_ts_cfg *cfg) * * @retval 0 If successful. */ -static inline int dai_ts_get(const struct device *dev, struct dai_ts_cfg *cfg, - struct dai_ts_data *tsd) +__syscall int dai_ts_get(const struct device *dev, struct dai_ts_cfg *cfg, + struct dai_ts_data *tsd); + +static inline int z_impl_dai_ts_get(const struct device *dev, struct dai_ts_cfg *cfg, + struct dai_ts_data *tsd) { const struct dai_driver_api *api = (const struct dai_driver_api *)dev->api; @@ -569,9 +596,13 @@ static inline int dai_ts_get(const struct device *dev, struct dai_ts_cfg *cfg, * @retval -ENOSYS If the configuration update operation is not implemented. * @retval <0 Negative errno code if failure. */ -static inline int dai_config_update(const struct device *dev, - const void *bespoke_cfg, - size_t size) +__syscall int dai_config_update(const struct device *dev, + const void *bespoke_cfg, + size_t size); + +static inline int z_impl_dai_config_update(const struct device *dev, + const void *bespoke_cfg, + size_t size) { const struct dai_driver_api *api = (const struct dai_driver_api *)dev->api; @@ -590,4 +621,6 @@ static inline int dai_config_update(const struct device *dev, } #endif +#include + #endif /* ZEPHYR_INCLUDE_DRIVERS_DAI_H_ */ From fa2c904266aa069a6242c96cb259a372f6591c68 Mon Sep 17 00:00:00 2001 From: Kai Vehmanen Date: Mon, 1 Dec 2025 16:25:24 +0200 Subject: [PATCH 0107/3659] drivers: dai: add get_properties_copy() method Add a variant of get_properties() method that writes the properties to a caller provided pointer. Unlike the old variant, this copy variant can be exported to user-space in a safe way. Signed-off-by: Kai Vehmanen --- drivers/dai/dai_handlers.c | 12 ++++++++++++ include/zephyr/drivers/dai.h | 29 +++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/drivers/dai/dai_handlers.c b/drivers/dai/dai_handlers.c index debba1635fb2..28283e25a66b 100644 --- a/drivers/dai/dai_handlers.c +++ b/drivers/dai/dai_handlers.c @@ -59,6 +59,18 @@ static inline int z_vrfy_dai_config_get(const struct device *dev, } #include +static inline int z_vrfy_dai_get_properties_copy(const struct device *dev, + enum dai_dir dir, + int stream_id, + struct dai_properties *dst) +{ + K_OOPS(K_SYSCALL_DRIVER_DAI(dev, get_properties_copy)); + K_OOPS(K_SYSCALL_MEMORY_WRITE(dst, sizeof(*dst))); + + return z_impl_dai_get_properties_copy(dev, dir, stream_id, dst); +} +#include + static inline int z_vrfy_dai_trigger(const struct device *dev, enum dai_dir dir, enum dai_trigger_cmd cmd) diff --git a/include/zephyr/drivers/dai.h b/include/zephyr/drivers/dai.h index f3e40dd94690..606a2f325668 100644 --- a/include/zephyr/drivers/dai.h +++ b/include/zephyr/drivers/dai.h @@ -322,6 +322,10 @@ __subsystem struct dai_driver_api { const struct dai_properties *(*get_properties)(const struct device *dev, enum dai_dir dir, int stream_id); + int (*get_properties_copy)(const struct device *dev, + enum dai_dir dir, + int stream_id, + struct dai_properties *dst); int (*trigger)(const struct device *dev, enum dai_dir dir, enum dai_trigger_cmd cmd); @@ -456,6 +460,31 @@ static inline const struct dai_properties *dai_get_properties(const struct devic return api->get_properties(dev, dir, stream_id); } +/** + * @brief Fetch properties of a DAI driver + * + * @param dev Pointer to the device structure for the driver instance + * @param dir Stream direction: RX or TX as defined by DAI_DIR_* + * @param stream_id Stream id: some drivers may have stream specific + * properties, this id specifies the stream. + * @param dst address where to write properties to + * @retval Zero on success + */ +__syscall int dai_get_properties_copy(const struct device *dev, + enum dai_dir dir, + int stream_id, + struct dai_properties *dst); + +static inline int z_impl_dai_get_properties_copy(const struct device *dev, + enum dai_dir dir, + int stream_id, + struct dai_properties *dst) +{ + const struct dai_driver_api *api = (const struct dai_driver_api *)dev->api; + + return api->get_properties_copy(dev, dir, stream_id, dst); +} + /** * @brief Send a trigger command. * From 05069845d4df9af7012ae7b5fc967dda0177364b Mon Sep 17 00:00:00 2001 From: Kai Vehmanen Date: Tue, 2 Dec 2025 14:40:32 +0200 Subject: [PATCH 0108/3659] drivers: dai: make user-space support build-time selectable The DAI interface is not used from user-space in all configurations where Zephyr user-space is enabled, so it is beneficial to have a build option to contorl whether the DAI syscalls are included or not. Signed-off-by: Kai Vehmanen --- drivers/dai/CMakeLists.txt | 6 ++++-- drivers/dai/Kconfig | 6 ++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/dai/CMakeLists.txt b/drivers/dai/CMakeLists.txt index 523fcb6a4885..6aedee9d3c7d 100644 --- a/drivers/dai/CMakeLists.txt +++ b/drivers/dai/CMakeLists.txt @@ -10,5 +10,7 @@ add_subdirectory_ifdef(CONFIG_DAI_NXP_MICFIL nxp/micfil) add_subdirectory_ifdef(CONFIG_DAI_NXP_SAI nxp/sai) # zephyr-keep-sorted-stop -zephyr_syscall_header(${ZEPHYR_BASE}/include/zephyr/drivers/dai.h) -zephyr_library_sources_ifdef(CONFIG_USERSPACE dai_handlers.c) +if(CONFIG_DAI_USERSPACE) + zephyr_syscall_header(${ZEPHYR_BASE}/include/zephyr/drivers/dai.h) + zephyr_library_sources(dai_handlers.c) +endif() diff --git a/drivers/dai/Kconfig b/drivers/dai/Kconfig index ea46c593bac9..456c86a2292f 100644 --- a/drivers/dai/Kconfig +++ b/drivers/dai/Kconfig @@ -19,6 +19,12 @@ config DAI_INIT_PRIORITY help Device driver initialization priority. +config DAI_USERSPACE + bool "DAI user-space support" + depends on USERSPACE + help + Expose the DAI interface to user-space threads via syscalls. + module = DAI module-str = dai source "subsys/logging/Kconfig.template.log_config" From 3b7b2aef96cf41b7402e49af6614e07d38588fdf Mon Sep 17 00:00:00 2001 From: Kai Vehmanen Date: Mon, 1 Dec 2025 16:26:01 +0200 Subject: [PATCH 0109/3659] drivers: dai: intel: ssp: add get_properties_copy support Add support for new get_properties_copy() method. This allows to use ssp driver from user-space threads. Signed-off-by: Kai Vehmanen --- drivers/dai/intel/ssp/ssp.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/drivers/dai/intel/ssp/ssp.c b/drivers/dai/intel/ssp/ssp.c index d86155b65af0..653f1d481687 100644 --- a/drivers/dai/intel/ssp/ssp.c +++ b/drivers/dai/intel/ssp/ssp.c @@ -2548,6 +2548,20 @@ static const struct dai_properties *dai_ssp_get_properties(const struct device * return prop; } +static int dai_ssp_get_properties_copy(const struct device *dev, + enum dai_dir dir, int stream_id, struct dai_properties *prop) +{ + const struct dai_properties *kernel_prop = dai_ssp_get_properties(dev, dir, stream_id); + + if (!prop) { + return -EINVAL; + } + + memcpy(prop, kernel_prop, sizeof(*kernel_prop)); + + return 0; +} + static void ssp_acquire_ip(struct dai_intel_ssp *dp) { struct dai_intel_ssp_plat_data *ssp = dai_get_plat_data(dp); @@ -2730,6 +2744,7 @@ static DEVICE_API(dai, dai_intel_ssp_api_funcs) = { .config_get = dai_ssp_config_get, .trigger = dai_ssp_trigger, .get_properties = dai_ssp_get_properties, + .get_properties_copy = dai_ssp_get_properties_copy, .config_update = dai_ssp_dma_control_set, }; From 653731d2e11fff87a8646c1297b986c150491433 Mon Sep 17 00:00:00 2001 From: Peter Mitsis Date: Thu, 6 Nov 2025 13:54:05 -0800 Subject: [PATCH 0110/3659] kernel: Adjust metairq preemption tracking bounds Adjust the bounds for tracking metairq preemption to include the case where the number of metairq threads matches the number of cooperative threads. This is needed as a thread that is schedule locked through k_sched_lock() is documented to be treated as a cooperative thread. This implies that if such a thread is preempted by a metairq thread that execution control must return to that thread after the metairq thread finishes its work. Signed-off-by: Peter Mitsis --- include/zephyr/kernel_structs.h | 3 +-- kernel/sched.c | 16 ++++------------ 2 files changed, 5 insertions(+), 14 deletions(-) diff --git a/include/zephyr/kernel_structs.h b/include/zephyr/kernel_structs.h index be883530b842..1a20bcc31507 100644 --- a/include/zephyr/kernel_structs.h +++ b/include/zephyr/kernel_structs.h @@ -161,8 +161,7 @@ struct _cpu { struct _ready_q ready_q; #endif -#if (CONFIG_NUM_METAIRQ_PRIORITIES > 0) && \ - (CONFIG_NUM_COOP_PRIORITIES > CONFIG_NUM_METAIRQ_PRIORITIES) +#if (CONFIG_NUM_METAIRQ_PRIORITIES > 0) /* Coop thread preempted by current metairq, or NULL */ struct k_thread *metairq_preempted; #endif diff --git a/kernel/sched.c b/kernel/sched.c index 34528271b1bd..83e8a10ebe57 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -164,8 +164,7 @@ static ALWAYS_INLINE struct k_thread *next_up(void) struct k_thread *thread = runq_best(); -#if (CONFIG_NUM_METAIRQ_PRIORITIES > 0) && \ - (CONFIG_NUM_COOP_PRIORITIES > CONFIG_NUM_METAIRQ_PRIORITIES) +#if (CONFIG_NUM_METAIRQ_PRIORITIES > 0) /* MetaIRQs must always attempt to return back to a * cooperative thread they preempted and not whatever happens * to be highest priority now. The cooperative thread was @@ -180,10 +179,7 @@ static ALWAYS_INLINE struct k_thread *next_up(void) _current_cpu->metairq_preempted = NULL; } } -#endif -/* CONFIG_NUM_METAIRQ_PRIORITIES > 0 && - * CONFIG_NUM_COOP_PRIORITIES > CONFIG_NUM_METAIRQ_PRIORITIES - */ +#endif /* CONFIG_NUM_METAIRQ_PRIORITIES > 0 */ #ifndef CONFIG_SMP /* In uniprocessor mode, we can leave the current thread in @@ -254,8 +250,7 @@ void move_current_to_end_of_prio_q(void) */ static void update_metairq_preempt(struct k_thread *thread) { -#if (CONFIG_NUM_METAIRQ_PRIORITIES > 0) && \ - (CONFIG_NUM_COOP_PRIORITIES > CONFIG_NUM_METAIRQ_PRIORITIES) +#if (CONFIG_NUM_METAIRQ_PRIORITIES > 0) if (thread_is_metairq(thread) && !thread_is_metairq(_current) && !thread_is_preemptible(_current)) { /* Record new preemption */ @@ -266,10 +261,7 @@ static void update_metairq_preempt(struct k_thread *thread) } #else ARG_UNUSED(thread); -#endif -/* CONFIG_NUM_METAIRQ_PRIORITIES > 0 && - * CONFIG_NUM_COOP_PRIORITIES > CONFIG_NUM_METAIRQ_PRIORITIES - */ +#endif /* CONFIG_NUM_METAIRQ_PRIORITIES > 0 */ } static ALWAYS_INLINE void update_cache(int preempt_ok) From 36d195b7171963330d46bc56a048f2c04b044607 Mon Sep 17 00:00:00 2001 From: Peter Mitsis Date: Mon, 10 Nov 2025 14:13:16 -0800 Subject: [PATCH 0111/3659] kernel: MetaIRQ on SMP fix When a cooperative thread (temporary or otherwise) is preempted by a metaIRQ thread on SMP, it is no longer re-inserted into the readyQ. This prevents it from being scheduled by another CPU while the preempting metaIRQ thread runs. Fixes #95081 Signed-off-by: Peter Mitsis --- kernel/sched.c | 69 +++++++++++++++++++++++++++++--------------------- 1 file changed, 40 insertions(+), 29 deletions(-) diff --git a/kernel/sched.c b/kernel/sched.c index 83e8a10ebe57..31f791b721eb 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -153,6 +153,26 @@ static inline void clear_halting(struct k_thread *thread) } } +/* Track cooperative threads preempted by metairqs so we can return to + * them specifically. Called at the moment a new thread has been + * selected to run. + */ +static void update_metairq_preempt(struct k_thread *thread) +{ +#if (CONFIG_NUM_METAIRQ_PRIORITIES > 0) + if (thread_is_metairq(thread) && !thread_is_metairq(_current) && + !thread_is_preemptible(_current)) { + /* Record new preemption */ + _current_cpu->metairq_preempted = _current; + } else if (!thread_is_metairq(thread)) { + /* Returning from existing preemption */ + _current_cpu->metairq_preempted = NULL; + } +#else + ARG_UNUSED(thread); +#endif /* CONFIG_NUM_METAIRQ_PRIORITIES > 0 */ +} + static ALWAYS_INLINE struct k_thread *next_up(void) { #ifdef CONFIG_SMP @@ -196,10 +216,10 @@ static ALWAYS_INLINE struct k_thread *next_up(void) * thread selected above represents "the best thread that is * not current". * - * Subtle note on "queued": in SMP mode, _current does not - * live in the queue, so this isn't exactly the same thing as - * "ready", it means "is _current already added back to the - * queue such that we don't want to re-add it". + * Subtle note on "queued": in SMP mode, neither _current nor + * metairq_premepted live in the queue, so this isn't exactly the + * same thing as "ready", it means "the thread already been + * added back to the queue such that we don't want to re-add it". */ bool queued = z_is_thread_queued(_current); bool active = z_is_thread_ready(_current); @@ -221,10 +241,22 @@ static ALWAYS_INLINE struct k_thread *next_up(void) } } - /* Put _current back into the queue */ - if ((thread != _current) && active && - !z_is_idle_thread_object(_current) && !queued) { - queue_thread(_current); + if (thread != _current) { + update_metairq_preempt(thread); + /* + * Put _current back into the queue unless it is .. + * 1. not active (i.e., blocked, suspended, dead), or + * 2. already queued, or + * 3. the idle thread, or + * 4. preempted by a MetaIRQ thread + */ + if (active && !queued && !z_is_idle_thread_object(_current) +#if (CONFIG_NUM_METAIRQ_PRIORITIES > 0) + && (_current != _current_cpu->metairq_preempted) +#endif + ) { + queue_thread(_current); + } } /* Take the new _current out of the queue */ @@ -244,26 +276,6 @@ void move_current_to_end_of_prio_q(void) update_cache(1); } -/* Track cooperative threads preempted by metairqs so we can return to - * them specifically. Called at the moment a new thread has been - * selected to run. - */ -static void update_metairq_preempt(struct k_thread *thread) -{ -#if (CONFIG_NUM_METAIRQ_PRIORITIES > 0) - if (thread_is_metairq(thread) && !thread_is_metairq(_current) && - !thread_is_preemptible(_current)) { - /* Record new preemption */ - _current_cpu->metairq_preempted = _current; - } else if (!thread_is_metairq(thread)) { - /* Returning from existing preemption */ - _current_cpu->metairq_preempted = NULL; - } -#else - ARG_UNUSED(thread); -#endif /* CONFIG_NUM_METAIRQ_PRIORITIES > 0 */ -} - static ALWAYS_INLINE void update_cache(int preempt_ok) { #ifndef CONFIG_SMP @@ -863,7 +875,6 @@ void *z_get_next_switch_handle(void *interrupted) if (old_thread != new_thread) { uint8_t cpu_id; - update_metairq_preempt(new_thread); z_sched_switch_spin(new_thread); arch_cohere_stacks(old_thread, interrupted, new_thread); From 5dd36854fde7e6497124b791243c2e8fbe747210 Mon Sep 17 00:00:00 2001 From: Peter Mitsis Date: Thu, 6 Nov 2025 14:47:17 -0800 Subject: [PATCH 0112/3659] kernel: Update clearing metairq_preempted record If the thread being aborted or suspended was preempted by a metaIRQ thread then clear the metairq_preempted record. In the case of aborting a thread, this prevents a re-used thread from being mistaken for a preempted thread. Furthermore, it removes the need to test the recorded thread for readiness in next_up(). Signed-off-by: Peter Mitsis --- kernel/sched.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/kernel/sched.c b/kernel/sched.c index 31f791b721eb..1b40c93bf6fd 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -193,11 +193,7 @@ static ALWAYS_INLINE struct k_thread *next_up(void) struct k_thread *mirqp = _current_cpu->metairq_preempted; if (mirqp != NULL && (thread == NULL || !thread_is_metairq(thread))) { - if (z_is_thread_ready(mirqp)) { - thread = mirqp; - } else { - _current_cpu->metairq_preempted = NULL; - } + thread = mirqp; } #endif /* CONFIG_NUM_METAIRQ_PRIORITIES > 0 */ @@ -383,6 +379,22 @@ static void thread_halt_spin(struct k_thread *thread, k_spinlock_key_t key) } } +/** + * If the specified thread is recorded as being preempted by a meta IRQ thread, + * clear that record. + */ +static ALWAYS_INLINE void z_metairq_preempted_clear(struct k_thread *thread) +{ +#if (CONFIG_NUM_METAIRQ_PRIORITIES > 0) + for (unsigned int i = 0; i < CONFIG_MP_MAX_NUM_CPUS; i++) { + if (_kernel.cpus[i].metairq_preempted == thread) { + _kernel.cpus[i].metairq_preempted = NULL; + break; + } + } +#endif +} + /* Shared handler for k_thread_{suspend,abort}(). Called with the * scheduler lock held and the key passed (which it may * release/reacquire!) which will be released before a possible return @@ -397,6 +409,8 @@ static ALWAYS_INLINE void z_thread_halt(struct k_thread *thread, k_spinlock_key_ wq = terminate ? wq : &thread->halt_queue; #endif + z_metairq_preempted_clear(thread); + /* If the target is a thread running on another CPU, flag and * poke (note that we might spin to wait, so a true * synchronous IPI is needed here, not deferred!), it will @@ -454,6 +468,7 @@ void z_impl_k_thread_suspend(k_tid_t thread) k_spinlock_key_t key = k_spin_lock(&_sched_spinlock); z_mark_thread_as_suspended(thread); + z_metairq_preempted_clear(thread); dequeue_thread(thread); update_cache(1); z_swap(&_sched_spinlock, key); From 9d23a1a948e731dadbd25835164c967f6878632c Mon Sep 17 00:00:00 2001 From: Peter Mitsis Date: Thu, 13 Nov 2025 12:09:31 -0800 Subject: [PATCH 0113/3659] doc: Add note to meta-IRQ threads Adds a note to the meta-IRQ thread documentation indicating that that when a cooperative thread resumes after being preempted by a meta-IRQ thread it will resume on the same CPU from which it was preempted. On a UP system such behavior is a given. However, this behavior becomes relevant on an SMP system to ensure that both schedule-locked and cooperative threads are not accidentally shuffled to another CPU while querying the properties associated with their current CPU. Signed-off-by: Peter Mitsis --- doc/kernel/services/threads/index.rst | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/doc/kernel/services/threads/index.rst b/doc/kernel/services/threads/index.rst index 1edc7593cff1..1c78982d6847 100644 --- a/doc/kernel/services/threads/index.rst +++ b/doc/kernel/services/threads/index.rst @@ -287,6 +287,14 @@ priorities, even if those threads are cooperative and/or have taken a scheduler lock. Meta-IRQ threads are still threads, however, and can still be interrupted by any hardware interrupt. +.. note:: + When a cooperative (or schedule-locked) thread that was preempted by a + meta-IRQ thread resumes its execution after the meta-IRQ thread completes, + it will be on the same CPU--assuming it was neither suspended nor aborted. + This helps ensure that these threads are not unexpectedly shuffled to + another CPU while in the midst of querying the properties associated + with their own CPU. + This behavior makes the act of unblocking a meta-IRQ thread (by any means, e.g. creating it, calling k_sem_give(), etc.) into the equivalent of a synchronous system call when done by a lower From 8fa52bf82ff95be2583012059eb2dd5817e9714f Mon Sep 17 00:00:00 2001 From: Peter Mitsis Date: Thu, 13 Nov 2025 14:49:38 -0800 Subject: [PATCH 0114/3659] tests: Add smp_metairq test Adds a new meta-IRQ test just for SMP. This test verifies that a cooperative thread preempted by a meta-IRQ thread resumes on the same CPU after the meta-IRQ thread finishes. Signed-off-by: Peter Mitsis --- tests/kernel/smp_metairq/CMakeLists.txt | 7 + .../qemu_cortex_a53_qemu_cortex_a53_smp.conf | 1 + ...emu_cortex_a53_qemu_cortex_a53_smp.overlay | 21 +++ tests/kernel/smp_metairq/prj.conf | 4 + tests/kernel/smp_metairq/src/main.c | 170 ++++++++++++++++++ tests/kernel/smp_metairq/testcase.yaml | 6 + 6 files changed, 209 insertions(+) create mode 100644 tests/kernel/smp_metairq/CMakeLists.txt create mode 100644 tests/kernel/smp_metairq/boards/qemu_cortex_a53_qemu_cortex_a53_smp.conf create mode 100644 tests/kernel/smp_metairq/boards/qemu_cortex_a53_qemu_cortex_a53_smp.overlay create mode 100644 tests/kernel/smp_metairq/prj.conf create mode 100644 tests/kernel/smp_metairq/src/main.c create mode 100644 tests/kernel/smp_metairq/testcase.yaml diff --git a/tests/kernel/smp_metairq/CMakeLists.txt b/tests/kernel/smp_metairq/CMakeLists.txt new file mode 100644 index 000000000000..d608925f5788 --- /dev/null +++ b/tests/kernel/smp_metairq/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(sleep) + +target_sources(app PRIVATE src/main.c) diff --git a/tests/kernel/smp_metairq/boards/qemu_cortex_a53_qemu_cortex_a53_smp.conf b/tests/kernel/smp_metairq/boards/qemu_cortex_a53_qemu_cortex_a53_smp.conf new file mode 100644 index 000000000000..797559f4fd3f --- /dev/null +++ b/tests/kernel/smp_metairq/boards/qemu_cortex_a53_qemu_cortex_a53_smp.conf @@ -0,0 +1 @@ +CONFIG_MP_MAX_NUM_CPUS=4 diff --git a/tests/kernel/smp_metairq/boards/qemu_cortex_a53_qemu_cortex_a53_smp.overlay b/tests/kernel/smp_metairq/boards/qemu_cortex_a53_qemu_cortex_a53_smp.overlay new file mode 100644 index 000000000000..080287699c6f --- /dev/null +++ b/tests/kernel/smp_metairq/boards/qemu_cortex_a53_qemu_cortex_a53_smp.overlay @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2025 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + cpus { + cpu@2 { + device_type = "cpu"; + compatible = "arm,cortex-a53"; + reg = <2>; + }; + + cpu@3 { + device_type = "cpu"; + compatible = "arm,cortex-a53"; + reg = <3>; + }; + }; +}; diff --git a/tests/kernel/smp_metairq/prj.conf b/tests/kernel/smp_metairq/prj.conf new file mode 100644 index 000000000000..1a4c91fca4bc --- /dev/null +++ b/tests/kernel/smp_metairq/prj.conf @@ -0,0 +1,4 @@ +CONFIG_ZTEST=y +CONFIG_SMP=y +CONFIG_IRQ_OFFLOAD=y +CONFIG_NUM_METAIRQ_PRIORITIES=1 diff --git a/tests/kernel/smp_metairq/src/main.c b/tests/kernel/smp_metairq/src/main.c new file mode 100644 index 000000000000..a4e471e3313f --- /dev/null +++ b/tests/kernel/smp_metairq/src/main.c @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2025 Intel Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +#if (CONFIG_MP_MAX_NUM_CPUS < 2) +#error "This test requires at least 2 CPUs" +#endif + +#define STACK_SIZE (1024 + CONFIG_TEST_EXTRA_STACK_SIZE) +#define ONE_BUSY_SECOND 1000000 + +#define NUM_HELPER_THREADS (CONFIG_MP_MAX_NUM_CPUS - 1) + +/* Define an array of stacks */ +static K_THREAD_STACK_ARRAY_DEFINE(helper_stacks, NUM_HELPER_THREADS, STACK_SIZE); +static K_THREAD_STACK_DEFINE(meta_irq_stack, STACK_SIZE); +static K_SEM_DEFINE(helper_sem, 0, NUM_HELPER_THREADS); + +static struct k_thread helper_threads[NUM_HELPER_THREADS]; +static struct k_thread meta_irq_thread; +static struct k_thread *test_thread; + +static volatile struct _cpu *test_cpu; +static volatile bool metairq_thread_has_started; +static volatile bool loop_forever = true; + +static void meta_irq_thread_entry(void *p1, void *p2, void *p3) +{ + unsigned int state; + struct _cpu *cpu = arch_curr_cpu(); + + zassert_equal(cpu, test_cpu, + "Expected MetaIRQ on CPU%u, not CPU%u\n", + test_cpu->id, cpu->id); + + /* + * The pre-empted cooperative test thread should not be blocked + * or tracked in a readyQ. It should however be tracked in the + * current CPU's 'metairq_preempted' field. + */ + + state = test_thread->base.thread_state; + zassert_equal(state, 0x0, + "Test thread has unexpected thread state (0x%x)\n", + state); + + zassert_equal(cpu->metairq_preempted, test_thread, + "Test thread not found in CPU%u metairq_preempted\n", + cpu->id); + + TC_PRINT("MetaIRQ thread running on CPU%u\n", cpu->id); + + metairq_thread_has_started = true; + + /* Send IPI to all other CPUs to force a reschedule*/ + arch_sched_broadcast_ipi(); + + /* + * Busy wait for one second to allow other CPUs to process the IPI. + * The scheduler should not try to schedule the cooperative test + * thread. If it for some reason does, we can detect it in the test + * thread. + */ + + k_busy_wait(ONE_BUSY_SECOND); + + k_thread_suspend(k_current_get()); + + zassert_true(false, "MetaIRQ thread resumed unexpectedly"); +} + +static void irq_handler(const void *arg) +{ + ARG_UNUSED(arg); + + k_thread_start(&meta_irq_thread); +} + +/* + * The helper thread is preemptible. It locks interrupts and waits for the + * metaIRQ thread to start. This is to guarantee that the metaIRQ thread runs + * on the same CPU as the cooperative test thread. + */ +static void helper_thread_entry(void *p1, void *p2, void *p3) +{ + unsigned int key; + + k_sem_give(&helper_sem); + + /* Lock interrupts until metaIRQ thread runs */ + + key = arch_irq_lock(); + while (metairq_thread_has_started == false) { + arch_spin_relax(); /* Requires interrupts to be masked */ + } + arch_irq_unlock(key); + + while (loop_forever) { + /* Busy wait */ + } +} + +ZTEST(smp_metairq, test_smp_metairq_no_migration) +{ + unsigned int i; + unsigned int id1; + unsigned int id2; + + test_thread = k_current_get(); + + /* Create, but do not start the meta-irq thread */ + + k_thread_create(&meta_irq_thread, meta_irq_stack, + STACK_SIZE, + meta_irq_thread_entry, + NULL, NULL, NULL, + K_HIGHEST_THREAD_PRIO, 0, K_FOREVER); + + /* Create preemptible helper threads on all other CPUs */ + + for (i = 0; i < CONFIG_MP_MAX_NUM_CPUS - 1; i++) { + k_thread_create(&helper_threads[i], helper_stacks[i], + STACK_SIZE, + helper_thread_entry, + NULL, NULL, NULL, + K_PRIO_PREEMPT(2), 0, K_NO_WAIT); + + k_sem_take(&helper_sem, K_FOREVER); + } + + TC_PRINT("Test thread running on CPU%u\n", arch_curr_cpu()->id); + + k_busy_wait(ONE_BUSY_SECOND); + + test_cpu = arch_curr_cpu(); + id1 = test_cpu->id; + + /* Force an interrupt that will schedule the metaIRQ on this CPU */ + irq_offload(irq_handler, NULL); + + TC_PRINT("Test thread resuming on CPU%u\n", arch_curr_cpu()->id); + + test_cpu = arch_curr_cpu(); + id2 = test_cpu->id; + + zassert_equal(id1, id2, + "Thread migrated from CPU%u to CPU%u during IRQ", + id1, id2); + + /* Clean up threads */ + + k_thread_abort(&meta_irq_thread); + loop_forever = false; + + for (i = 0; i < NUM_HELPER_THREADS; i++) { + k_thread_join(&helper_threads[i], K_FOREVER); + } + + k_thread_join(&meta_irq_thread, K_FOREVER); +} + +ZTEST_SUITE(smp_metairq, NULL, NULL, NULL, NULL, NULL); diff --git a/tests/kernel/smp_metairq/testcase.yaml b/tests/kernel/smp_metairq/testcase.yaml new file mode 100644 index 000000000000..3345b2947cb9 --- /dev/null +++ b/tests/kernel/smp_metairq/testcase.yaml @@ -0,0 +1,6 @@ +tests: + kernel.smp_metairq: + tags: + - kernel + - smp + filter: (CONFIG_MP_MAX_NUM_CPUS > 1) From 06eb1473d5132d32328080aeb33ebf33a713a848 Mon Sep 17 00:00:00 2001 From: Dmitrii Sharshakov Date: Thu, 27 Nov 2025 20:43:18 +0100 Subject: [PATCH 0115/3659] settings: tfm_psa: rename from its Prepare for extending this backend to also allow storing settings in the PS (Protected Storage). Mostly file and kconfig renames, as well as updates to comments and log messages. Signed-off-by: Dmitrii Sharshakov --- include/zephyr/psa/its_ids.h | 8 +-- samples/subsys/settings/sample.yaml | 2 +- subsys/settings/Kconfig | 30 +++++---- subsys/settings/src/CMakeLists.txt | 6 +- .../{settings_its.c => settings_tfm_psa.c} | 67 ++++++++++--------- ...ngs_its_priv.h => settings_tfm_psa_priv.h} | 0 .../functional/src/settings_basic_test.c | 11 +-- .../settings/functional/tfm_psa/prj.conf | 2 +- .../settings/functional/tfm_psa/testcase.yaml | 2 +- .../settings/{its => tfm_psa}/CMakeLists.txt | 4 +- .../subsys/settings/{its => tfm_psa}/prj.conf | 2 +- .../{its => tfm_psa}/src/CMakeLists.txt | 4 +- .../{its => tfm_psa}/src/settings_test.h | 6 +- .../src/settings_test_psa.c} | 0 .../settings/{its => tfm_psa}/testcase.yaml | 4 +- 15 files changed, 77 insertions(+), 71 deletions(-) rename subsys/settings/src/{settings_its.c => settings_tfm_psa.c} (71%) rename subsys/settings/src/{settings_its_priv.h => settings_tfm_psa_priv.h} (100%) rename tests/subsys/settings/{its => tfm_psa}/CMakeLists.txt (71%) rename tests/subsys/settings/{its => tfm_psa}/prj.conf (89%) rename tests/subsys/settings/{its => tfm_psa}/src/CMakeLists.txt (73%) rename tests/subsys/settings/{its => tfm_psa}/src/settings_test.h (89%) rename tests/subsys/settings/{its/src/settings_test_its.c => tfm_psa/src/settings_test_psa.c} (100%) rename tests/subsys/settings/{its => tfm_psa}/testcase.yaml (91%) diff --git a/include/zephyr/psa/its_ids.h b/include/zephyr/psa/its_ids.h index aebe2d54ce09..ed5371eea998 100644 --- a/include/zephyr/psa/its_ids.h +++ b/include/zephyr/psa/its_ids.h @@ -3,11 +3,11 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#ifndef ZEPHYR_ITS_IDS_H_ -#define ZEPHYR_ITS_IDS_H_ +#ifndef ZEPHYR_PSA_ITS_IDS_H_ +#define ZEPHYR_PSA_ITS_IDS_H_ -/** UID range to be used by the TF-M ITS Settings backend. */ +/** UID range to be used by the TF-M PSA ITS Settings backend. */ #define ZEPHYR_PSA_SETTINGS_TFM_ITS_UID_RANGE_BEGIN 0x28000000 #define ZEPHYR_PSA_SETTINGS_TFM_ITS_UID_RANGE_SIZE 0x10000 /* 64 Ki */ -#endif /* ZEPHYR_ITS_IDS_H_ */ +#endif /* ZEPHYR_PSA_ITS_IDS_H_ */ diff --git a/samples/subsys/settings/sample.yaml b/samples/subsys/settings/sample.yaml index 0faec9d38165..1080c0c0fdee 100644 --- a/samples/subsys/settings/sample.yaml +++ b/samples/subsys/settings/sample.yaml @@ -63,4 +63,4 @@ tests: integration_platforms: - mps2/an521/cpu0/ns extra_args: - - CONFIG_SETTINGS_TFM_ITS=y + - CONFIG_SETTINGS_TFM_PSA=y diff --git a/subsys/settings/Kconfig b/subsys/settings/Kconfig index 1f314e024a44..50f77bfc2746 100644 --- a/subsys/settings/Kconfig +++ b/subsys/settings/Kconfig @@ -143,17 +143,19 @@ config SETTINGS_CUSTOM help Use a custom settings storage back-end. -config SETTINGS_TFM_ITS - bool "Internal Trusted Storage (ITS) settings backend" +config SETTINGS_TFM_PSA + bool "TF-M PSA" depends on TFM_PARTITION_INTERNAL_TRUSTED_STORAGE select EXPERIMENTAL help - Enables Internal Trusted Storage (ITS) Settings backend. Intended for use with boards + Enables PSA Settings backend. Intended for use with boards using TF-M which cannot make use of persistent storage otherwise. - Note: This settings backend compacts settings data into as few ITS nodes as possible. - On every save, the entire settings array is written to ITS. + This backend uses the PSA Internal Trusted Storage (ITS) service to store settings data. + Note: This settings backend compacts settings data into as few secure storage nodes as possible. + After each save, the entire settings array is written to the secure storage. To avoid excessive + latency on saving, settings are saved after a delay using a kernel work item. Note: With this backend, all settings are kept in RAM at all times. The RAM consumption - is controlled by the SETTINGS_TFM_ITS_NUM_ENTRIES Kconfig option. + is controlled by the SETTINGS_TFM_PSA_NUM_ENTRIES Kconfig option. config SETTINGS_NONE bool "NONE" @@ -265,9 +267,9 @@ config SETTINGS_SHELL size of the shell thread may need to be increased to accommodate this feature. -if SETTINGS_TFM_ITS +if SETTINGS_TFM_PSA -config SETTINGS_TFM_ITS_NUM_ENTRIES +config SETTINGS_TFM_PSA_NUM_ENTRIES int "Maximum number of settings entries" default 10 help @@ -275,18 +277,18 @@ config SETTINGS_TFM_ITS_NUM_ENTRIES Note: This value determines the size of a statically-allocated buffer which holds all the settings entries in RAM at all times. -config SETTINGS_TFM_ITS_LAZY_PERSIST_DELAY_MS +config SETTINGS_TFM_PSA_LAZY_PERSIST_DELAY_MS int "Milliseconds delay before persisting settings" default 500 help - ITS may block for a long period of time when writing to flash, which may be + PSA Secure Storage APIs may block for a long period of time when writing to flash, which may be unacceptable for time-sensitive events. - Data is always persisted to ITS using k_work_delayable, instead of happening in - the same context as settings_its_save. This option sets the delay with which the + Data is always persisted to the secure storage using k_work_delayable, instead of happening in + the same context as settings_save. This option sets the delay with which the work item is scheduled. The delay is useful in cases where a PSA ITS write may - block a time-sensitive event, Bluetooth pairing for example, which requires a + block a time-sensitive event, for example Bluetooth pairing, which requires a sequence of settings writes. -endif # SETTINGS_TFM_ITS +endif # SETTINGS_TFM_PSA endif # SETTINGS diff --git a/subsys/settings/src/CMakeLists.txt b/subsys/settings/src/CMakeLists.txt index 27264cf6af2b..ef5e7d4c585a 100644 --- a/subsys/settings/src/CMakeLists.txt +++ b/subsys/settings/src/CMakeLists.txt @@ -14,6 +14,8 @@ zephyr_sources_ifdef(CONFIG_SETTINGS_NVS settings_nvs.c) zephyr_sources_ifdef(CONFIG_SETTINGS_NONE settings_none.c) zephyr_sources_ifdef(CONFIG_SETTINGS_SHELL settings_shell.c) zephyr_sources_ifdef(CONFIG_SETTINGS_ZMS settings_zms.c) -zephyr_sources_ifdef(CONFIG_SETTINGS_TFM_ITS settings_its.c) -zephyr_library_link_libraries_ifdef(CONFIG_SETTINGS_TFM_ITS tfm_api) +if(CONFIG_SETTINGS_TFM_PSA) + zephyr_sources(settings_tfm_psa.c) + zephyr_library_link_libraries(tfm_api) +endif() zephyr_sources_ifdef(CONFIG_SETTINGS_RETENTION settings_retention.c) diff --git a/subsys/settings/src/settings_its.c b/subsys/settings/src/settings_tfm_psa.c similarity index 71% rename from subsys/settings/src/settings_its.c rename to subsys/settings/src/settings_tfm_psa.c index 67d3d091ae79..08bc6fb07a4e 100644 --- a/subsys/settings/src/settings_its.c +++ b/subsys/settings/src/settings_tfm_psa.c @@ -15,29 +15,30 @@ /* TF-M config file containing ITS_MAX_ASSET_SIZE */ #include -#include "settings_its_priv.h" +#include "settings_tfm_psa_priv.h" LOG_MODULE_DECLARE(settings, CONFIG_SETTINGS_LOG_LEVEL); K_MUTEX_DEFINE(worker_mutex); static struct k_work_delayable worker; -static struct setting_entry entries[CONFIG_SETTINGS_TFM_ITS_NUM_ENTRIES]; +static struct setting_entry entries[CONFIG_SETTINGS_TFM_PSA_NUM_ENTRIES]; static int entries_count; -static int settings_its_load(struct settings_store *cs, const struct settings_load_arg *arg); -static int settings_its_save(struct settings_store *cs, const char *name, const char *value, +static int settings_psa_load(struct settings_store *cs, const struct settings_load_arg *arg); +static int settings_psa_save(struct settings_store *cs, const char *name, const char *value, size_t val_len); -static const struct settings_store_itf settings_its_itf = { - .csi_load = settings_its_load, - .csi_save = settings_its_save, +static const struct settings_store_itf settings_psa_itf = { + .csi_load = settings_psa_load, + .csi_save = settings_psa_save, }; -static struct settings_store default_settings_its = {.cs_itf = &settings_its_itf}; +static struct settings_store default_settings_psa = {.cs_itf = &settings_psa_itf}; /* Ensure Key configured max size does not exceed reserved Key range */ -BUILD_ASSERT(sizeof(entries) / ITS_MAX_ASSET_SIZE <= ZEPHYR_PSA_SETTINGS_TFM_ITS_UID_RANGE_SIZE, +BUILD_ASSERT(sizeof(entries) / ITS_MAX_ASSET_SIZE <= + ZEPHYR_PSA_SETTINGS_TFM_ITS_UID_RANGE_BEGIN, "entries array exceeds reserved ITS UID range"); static int store_entries(void) @@ -49,9 +50,9 @@ static int store_entries(void) const uint8_t *data_ptr = (const uint8_t *)&entries; /* - * Each ITS UID is treated like a sector. Data is written to each ITS node until - * that node is full, before incrementing the UID. This is done to minimize the - * number of allocated ITS nodes and to avoid wasting allocated bytes. + * Each storage UID is treated like a sector. Data is written to each KV pair until + * that data field is full, before incrementing the UID. This is done to minimize the + * number of allocated UIDs and to allocate bytes in the most efficient way. */ while (remaining > 0) { size_t write_size = (remaining > chunk_size) ? chunk_size : remaining; @@ -69,7 +70,7 @@ static int store_entries(void) uid++; } - LOG_DBG("ITS entries stored successfully - bytes_saved: %d num_entries: %d max_uid: %lld", + LOG_DBG("PSA storage entries stored successfully - bytes_saved: %d num_entries: %d max_uid: %lld", sizeof(entries), entries_count, uid); return 0; @@ -85,9 +86,9 @@ static int load_entries(void) uint8_t *data_ptr = (uint8_t *)&entries; /* - * Each ITS UID is treated like a sector. Data is written to each ITS node until - * that node is full, before incrementing the UID. This is done to minimize the - * number of allocated ITS nodes and to avoid wasting allocated bytes. + * Each storage UID is treated like a sector. Data is written to each KV pair until + * that data field is full, before incrementing the UID. This is done to minimize the + * number of allocated UIDs and to allocate bytes in the most efficient way. */ while (remaining > 0) { size_t to_read = (remaining > chunk_size) ? chunk_size : remaining; @@ -102,27 +103,27 @@ static int load_entries(void) uid++; } - for (int i = 0; i < CONFIG_SETTINGS_TFM_ITS_NUM_ENTRIES; i++) { + for (int i = 0; i < CONFIG_SETTINGS_TFM_PSA_NUM_ENTRIES; i++) { if (strnlen(entries[i].name, SETTINGS_MAX_NAME_LEN) != 0) { entries_count++; } } - LOG_DBG("ITS entries restored successfully - bytes_loaded: %d, num_entries: %d", + LOG_DBG("PSA storage entries restored successfully - bytes_loaded: %d, num_entries: %d", sizeof(entries), entries_count); return 0; } /* void *back_end is the index of the entry in metadata entries struct */ -static ssize_t settings_its_read_fn(void *back_end, void *data, size_t len) +static ssize_t settings_psa_read_fn(void *back_end, void *data, size_t len) { int index = *(int *)back_end; - LOG_DBG("ITS Read - index: %d", index); + LOG_DBG("reading index: %d", index); - if (index < 0 || index >= CONFIG_SETTINGS_TFM_ITS_NUM_ENTRIES) { - LOG_ERR("Invalid index %d in ITS metadata", index); + if (index < 0 || index >= CONFIG_SETTINGS_TFM_PSA_NUM_ENTRIES) { + LOG_ERR("Invalid index %d in metadata", index); return 0; } @@ -134,7 +135,7 @@ static ssize_t settings_its_read_fn(void *back_end, void *data, size_t len) return entries[index].val_len; } -static int settings_its_load(struct settings_store *cs, const struct settings_load_arg *arg) +static int settings_psa_load(struct settings_store *cs, const struct settings_load_arg *arg) { int ret; @@ -145,7 +146,7 @@ static int settings_its_load(struct settings_store *cs, const struct settings_lo * to be read during callback function later. */ ret = settings_call_set_handler(entries[i].name, entries[i].val_len, - settings_its_read_fn, (void *)&i, + settings_psa_read_fn, (void *)&i, (void *)arg); if (ret) { return ret; @@ -156,12 +157,12 @@ static int settings_its_load(struct settings_store *cs, const struct settings_lo return 0; } -static int settings_its_save(struct settings_store *cs, const char *name, const char *value, +static int settings_psa_save(struct settings_store *cs, const char *name, const char *value, size_t val_len) { - if (entries_count >= CONFIG_SETTINGS_TFM_ITS_NUM_ENTRIES) { + if (entries_count >= CONFIG_SETTINGS_TFM_PSA_NUM_ENTRIES) { LOG_ERR("%s: Max settings reached: %d", __func__, - CONFIG_SETTINGS_TFM_ITS_NUM_ENTRIES); + CONFIG_SETTINGS_TFM_PSA_NUM_ENTRIES); return -ENOMEM; } @@ -183,7 +184,7 @@ static int settings_its_save(struct settings_store *cs, const char *name, const * Search metadata to see if entry already exists. Array is compacted, so first blank entry * signals end of settings. */ - for (index = 0; index < CONFIG_SETTINGS_TFM_ITS_NUM_ENTRIES; index++) { + for (index = 0; index < CONFIG_SETTINGS_TFM_PSA_NUM_ENTRIES; index++) { if (strncmp(entries[index].name, name, SETTINGS_MAX_NAME_LEN) == 0) { break; } else if (entries[index].val_len == 0) { @@ -201,7 +202,7 @@ static int settings_its_save(struct settings_store *cs, const char *name, const } } - LOG_DBG("ITS Save - index %d: name %s, val_len %d", index, name, val_len); + LOG_DBG("writing index %d: name %s, val_len %d", index, name, val_len); if (delete) { /* Clear metadata */ @@ -226,7 +227,7 @@ static int settings_its_save(struct settings_store *cs, const char *name, const } k_mutex_unlock(&worker_mutex); - k_work_schedule(&worker, K_MSEC(CONFIG_SETTINGS_TFM_ITS_LAZY_PERSIST_DELAY_MS)); + k_work_schedule(&worker, K_MSEC(CONFIG_SETTINGS_TFM_PSA_LAZY_PERSIST_DELAY_MS)); return 0; } @@ -242,7 +243,7 @@ int settings_backend_init(void) { psa_status_t status; - /* Load ITS metadata */ + /* Load settings from storage */ status = load_entries(); /* If resource DNE, we need to allocate it */ @@ -257,8 +258,8 @@ int settings_backend_init(void) return -EIO; } - settings_dst_register(&default_settings_its); - settings_src_register(&default_settings_its); + settings_dst_register(&default_settings_psa); + settings_src_register(&default_settings_psa); k_work_init_delayable(&worker, worker_persist_entries_struct_fn); diff --git a/subsys/settings/src/settings_its_priv.h b/subsys/settings/src/settings_tfm_psa_priv.h similarity index 100% rename from subsys/settings/src/settings_its_priv.h rename to subsys/settings/src/settings_tfm_psa_priv.h diff --git a/tests/subsys/settings/functional/src/settings_basic_test.c b/tests/subsys/settings/functional/src/settings_basic_test.c index 639e4e22cdde..8e44394c0e98 100644 --- a/tests/subsys/settings/functional/src/settings_basic_test.c +++ b/tests/subsys/settings/functional/src/settings_basic_test.c @@ -24,13 +24,14 @@ LOG_MODULE_REGISTER(settings_basic_test); #elif defined(CONFIG_SETTINGS_FILE) #include #include -#elif defined(CONFIG_SETTINGS_TFM_ITS) +#elif defined(CONFIG_SETTINGS_TFM_PSA) + #include #include /* TF-M config file containing ITS_MAX_ASSET_SIZE */ #include -#include +#include #else #error "Settings backend not selected" #endif @@ -45,14 +46,14 @@ LOG_MODULE_REGISTER(settings_basic_test); */ ZTEST(settings_functional, test_clear_settings) { -#if defined(CONFIG_SETTINGS_TFM_ITS) +#if defined(CONFIG_SETTINGS_TFM_PSA) psa_status_t status; /* Remove all potentially accessed ITS entries in the UID range */ - for (int i = 0; i < sizeof(struct setting_entry) * CONFIG_SETTINGS_TFM_ITS_NUM_ENTRIES / + for (int i = 0; i < sizeof(struct setting_entry) * CONFIG_SETTINGS_TFM_PSA_NUM_ENTRIES / ITS_MAX_ASSET_SIZE + 1; i++) { status = psa_its_remove(ZEPHYR_PSA_SETTINGS_TFM_ITS_UID_RANGE_BEGIN + i); - zassert_true(status == PSA_SUCCESS || status == PSA_ERROR_DOES_NOT_EXIST, + zassert_true((status == PSA_SUCCESS) || (status == PSA_ERROR_DOES_NOT_EXIST), "psa_its_remove failed"); } #elif !defined(CONFIG_SETTINGS_FILE) diff --git a/tests/subsys/settings/functional/tfm_psa/prj.conf b/tests/subsys/settings/functional/tfm_psa/prj.conf index 1a4ea593f3f3..e541ffa16cb6 100644 --- a/tests/subsys/settings/functional/tfm_psa/prj.conf +++ b/tests/subsys/settings/functional/tfm_psa/prj.conf @@ -3,4 +3,4 @@ CONFIG_ZTEST=y CONFIG_SETTINGS=y # 10 is not sufficient for the test -CONFIG_SETTINGS_TFM_ITS_NUM_ENTRIES=11 +CONFIG_SETTINGS_TFM_PSA_NUM_ENTRIES=11 diff --git a/tests/subsys/settings/functional/tfm_psa/testcase.yaml b/tests/subsys/settings/functional/tfm_psa/testcase.yaml index 6c7c9758a869..561645212dd6 100644 --- a/tests/subsys/settings/functional/tfm_psa/testcase.yaml +++ b/tests/subsys/settings/functional/tfm_psa/testcase.yaml @@ -13,4 +13,4 @@ tests: - settings - trusted-firmware-m extra_args: - - CONFIG_SETTINGS_TFM_ITS=y + - CONFIG_SETTINGS_TFM_PSA=y diff --git a/tests/subsys/settings/its/CMakeLists.txt b/tests/subsys/settings/tfm_psa/CMakeLists.txt similarity index 71% rename from tests/subsys/settings/its/CMakeLists.txt rename to tests/subsys/settings/tfm_psa/CMakeLists.txt index 877aa7be73de..ca0cc839fcfc 100644 --- a/tests/subsys/settings/its/CMakeLists.txt +++ b/tests/subsys/settings/tfm_psa/CMakeLists.txt @@ -4,6 +4,6 @@ cmake_minimum_required(VERSION 3.20.0) find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) -project(test_settings_its_raw) +project(test_settings_psa) -add_subdirectory(./src its_test_bindir) +add_subdirectory(./src psa_test_bindir) diff --git a/tests/subsys/settings/its/prj.conf b/tests/subsys/settings/tfm_psa/prj.conf similarity index 89% rename from tests/subsys/settings/its/prj.conf rename to tests/subsys/settings/tfm_psa/prj.conf index a677dc7c2feb..81fbad3a5669 100644 --- a/tests/subsys/settings/its/prj.conf +++ b/tests/subsys/settings/tfm_psa/prj.conf @@ -7,5 +7,5 @@ CONFIG_FLASH=y CONFIG_FLASH_MAP=y CONFIG_TFM_PARTITION_INTERNAL_TRUSTED_STORAGE=y CONFIG_SETTINGS=y -CONFIG_SETTINGS_TFM_ITS=y +CONFIG_SETTINGS_TFM_PSA=y CONFIG_SETTINGS_RUNTIME=y diff --git a/tests/subsys/settings/its/src/CMakeLists.txt b/tests/subsys/settings/tfm_psa/src/CMakeLists.txt similarity index 73% rename from tests/subsys/settings/its/src/CMakeLists.txt rename to tests/subsys/settings/tfm_psa/src/CMakeLists.txt index 4d39b6af79f5..802c6a14abd1 100644 --- a/tests/subsys/settings/its/src/CMakeLists.txt +++ b/tests/subsys/settings/tfm_psa/src/CMakeLists.txt @@ -6,9 +6,9 @@ zephyr_include_directories( ${ZEPHYR_BASE}/subsys/settings/include ${ZEPHYR_BASE}/subsys/settings/src - ${ZEPHYR_BASE}/tests/subsys/settings/its/src + ${ZEPHYR_BASE}/tests/subsys/settings/tfm_psa/src ) -target_sources(app PRIVATE settings_test_its.c) +target_sources(app PRIVATE settings_test_psa.c) add_subdirectory(../../src settings_test_bindir) diff --git a/tests/subsys/settings/its/src/settings_test.h b/tests/subsys/settings/tfm_psa/src/settings_test.h similarity index 89% rename from tests/subsys/settings/its/src/settings_test.h rename to tests/subsys/settings/tfm_psa/src/settings_test.h index 73efbba60f35..f7eb9a40f85f 100644 --- a/tests/subsys/settings/its/src/settings_test.h +++ b/tests/subsys/settings/tfm_psa/src/settings_test.h @@ -5,8 +5,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef _SETTINGS_TEST_ITS_H -#define _SETTINGS_TEST_ITS_H +#ifndef _SETTINGS_TEST_PSA_H +#define _SETTINGS_TEST_PSA_H #include #include @@ -41,4 +41,4 @@ void settings_config_teardown(void *fixture); } #endif -#endif /* _SETTINGS_TEST_ITS_H */ +#endif /* _SETTINGS_TEST_PSA_H */ diff --git a/tests/subsys/settings/its/src/settings_test_its.c b/tests/subsys/settings/tfm_psa/src/settings_test_psa.c similarity index 100% rename from tests/subsys/settings/its/src/settings_test_its.c rename to tests/subsys/settings/tfm_psa/src/settings_test_psa.c diff --git a/tests/subsys/settings/its/testcase.yaml b/tests/subsys/settings/tfm_psa/testcase.yaml similarity index 91% rename from tests/subsys/settings/its/testcase.yaml rename to tests/subsys/settings/tfm_psa/testcase.yaml index 338ed99380b7..379e67cbc4c6 100644 --- a/tests/subsys/settings/its/testcase.yaml +++ b/tests/subsys/settings/tfm_psa/testcase.yaml @@ -3,9 +3,8 @@ # SPDX-License-Identifier: Apache-2.0 tests: - settings.tfm_its: + settings.tfm_psa_its: filter: CONFIG_TFM_PARTITION_INTERNAL_TRUSTED_STORAGE - min_ram: 32 integration_platforms: - max32657evkit/max32657/ns - nrf5340dk/nrf5340/cpuapp/ns @@ -14,4 +13,5 @@ tests: - mps2/an521/cpu0/ns - lpcxpresso55s69/lpc55s69/cpu0/ns tags: + - settings - trusted-firmware-m From 0e04d8a8026e39776e85bdaf53626ef5594164b9 Mon Sep 17 00:00:00 2001 From: Dmitrii Sharshakov Date: Sat, 6 Dec 2025 14:29:34 +0100 Subject: [PATCH 0116/3659] settings: tfm_psa: add support for PS backend Protected Storage is another type of secure (encrypted and authenticated) storage available using PSA interfaces. When targeting TF-M builds, allow making use of PS for storing settings Fixes #94681 Signed-off-by: Dmitrii Sharshakov --- include/zephyr/psa/ps_ids.h | 13 ++++++ subsys/settings/Kconfig | 26 ++++++++++-- subsys/settings/src/settings_tfm_psa.c | 55 +++++++++++++++++++------- 3 files changed, 77 insertions(+), 17 deletions(-) create mode 100644 include/zephyr/psa/ps_ids.h diff --git a/include/zephyr/psa/ps_ids.h b/include/zephyr/psa/ps_ids.h new file mode 100644 index 000000000000..9ea296f67c60 --- /dev/null +++ b/include/zephyr/psa/ps_ids.h @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2025 Analog Devices, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef ZEPHYR_PSA_PS_IDS_H_ +#define ZEPHYR_PSA_PS_IDS_H_ + +/** UID range to be used by the TF-M PSA PS Settings backend. */ +#define ZEPHYR_PSA_SETTINGS_TFM_PS_UID_RANGE_BEGIN 0x2C000000 +#define ZEPHYR_PSA_SETTINGS_TFM_PS_UID_RANGE_SIZE 0x10000 /* 64 Ki */ + +#endif /* ZEPHYR_PSA_PS_IDS_H_ */ diff --git a/subsys/settings/Kconfig b/subsys/settings/Kconfig index 50f77bfc2746..95e995d8d24b 100644 --- a/subsys/settings/Kconfig +++ b/subsys/settings/Kconfig @@ -145,12 +145,12 @@ config SETTINGS_CUSTOM config SETTINGS_TFM_PSA bool "TF-M PSA" - depends on TFM_PARTITION_INTERNAL_TRUSTED_STORAGE + depends on BUILD_WITH_TFM select EXPERIMENTAL help Enables PSA Settings backend. Intended for use with boards using TF-M which cannot make use of persistent storage otherwise. - This backend uses the PSA Internal Trusted Storage (ITS) service to store settings data. + This backend uses the PSA ITS or PS service to store settings data. Note: This settings backend compacts settings data into as few secure storage nodes as possible. After each save, the entire settings array is written to the secure storage. To avoid excessive latency on saving, settings are saved after a delay using a kernel work item. @@ -269,6 +269,26 @@ config SETTINGS_SHELL if SETTINGS_TFM_PSA +choice SETTINGS_TFM_PSA_BACKEND + prompt "TF-M PSA Settings backend" + default SETTINGS_TFM_PSA_BACKEND_ITS + help + PSA storage option to be used by the PSA settings backend. + +config SETTINGS_TFM_PSA_BACKEND_PS + bool "PSA Protected Storage (PS)" + depends on TFM_PARTITION_PROTECTED_STORAGE + help + Use PSA Protected Storage as settings storage backend. + +config SETTINGS_TFM_PSA_BACKEND_ITS + bool "PSA Internal Trusted Storage (ITS)" + depends on TFM_PARTITION_INTERNAL_TRUSTED_STORAGE + help + Use PSA Internal Trusted Storage as settings storage backend. + +endchoice # SETTINGS_TFM_PSA_BACKEND + config SETTINGS_TFM_PSA_NUM_ENTRIES int "Maximum number of settings entries" default 10 @@ -285,7 +305,7 @@ config SETTINGS_TFM_PSA_LAZY_PERSIST_DELAY_MS unacceptable for time-sensitive events. Data is always persisted to the secure storage using k_work_delayable, instead of happening in the same context as settings_save. This option sets the delay with which the - work item is scheduled. The delay is useful in cases where a PSA ITS write may + work item is scheduled. The delay is useful in cases where a write may block a time-sensitive event, for example Bluetooth pairing, which requires a sequence of settings writes. diff --git a/subsys/settings/src/settings_tfm_psa.c b/subsys/settings/src/settings_tfm_psa.c index 08bc6fb07a4e..b5aa4512b292 100644 --- a/subsys/settings/src/settings_tfm_psa.c +++ b/subsys/settings/src/settings_tfm_psa.c @@ -6,11 +6,10 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include #include #include #include -#include /* TF-M config file containing ITS_MAX_ASSET_SIZE */ #include @@ -36,17 +35,40 @@ static const struct settings_store_itf settings_psa_itf = { static struct settings_store default_settings_psa = {.cs_itf = &settings_psa_itf}; +#if defined(CONFIG_SETTINGS_TFM_PSA_BACKEND_PS) +#include +#include + +#define SETTINGS_PSA_MAX_ASSET_SIZE PS_MAX_ASSET_SIZE +#define SETTINGS_PSA_UID_RANGE_BEGIN ZEPHYR_PSA_SETTINGS_TFM_PS_UID_RANGE_BEGIN +#define SETTINGS_PSA_UID_RANGE_SIZE ZEPHYR_PSA_SETTINGS_TFM_PS_UID_RANGE_SIZE +#define SETTINGS_PSA_SET psa_ps_set +#define SETTINGS_PSA_GET psa_ps_get + +#elif defined(CONFIG_SETTINGS_TFM_PSA_BACKEND_ITS) +#include +#include + +#define SETTINGS_PSA_MAX_ASSET_SIZE ITS_MAX_ASSET_SIZE +#define SETTINGS_PSA_UID_RANGE_BEGIN ZEPHYR_PSA_SETTINGS_TFM_ITS_UID_RANGE_BEGIN +#define SETTINGS_PSA_UID_RANGE_SIZE ZEPHYR_PSA_SETTINGS_TFM_ITS_UID_RANGE_SIZE +#define SETTINGS_PSA_SET psa_its_set +#define SETTINGS_PSA_GET psa_its_get + +#else +#error "No PSA backend selected" +#endif /* CONFIG_SETTINGS_TFM_PSA_BACKEND */ + /* Ensure Key configured max size does not exceed reserved Key range */ -BUILD_ASSERT(sizeof(entries) / ITS_MAX_ASSET_SIZE <= - ZEPHYR_PSA_SETTINGS_TFM_ITS_UID_RANGE_BEGIN, - "entries array exceeds reserved ITS UID range"); +BUILD_ASSERT(sizeof(entries) / SETTINGS_PSA_MAX_ASSET_SIZE <= + SETTINGS_PSA_UID_RANGE_SIZE, + "entries array exceeds reserved PSA storage UID range"); static int store_entries(void) { psa_status_t status; - psa_storage_uid_t uid = ZEPHYR_PSA_SETTINGS_TFM_ITS_UID_RANGE_BEGIN; + psa_storage_uid_t uid = SETTINGS_PSA_UID_RANGE_BEGIN; size_t remaining = sizeof(entries); - size_t chunk_size = ITS_MAX_ASSET_SIZE; const uint8_t *data_ptr = (const uint8_t *)&entries; /* @@ -55,9 +77,12 @@ static int store_entries(void) * number of allocated UIDs and to allocate bytes in the most efficient way. */ while (remaining > 0) { - size_t write_size = (remaining > chunk_size) ? chunk_size : remaining; + size_t write_size = SETTINGS_PSA_MAX_ASSET_SIZE; + if (remaining < SETTINGS_PSA_MAX_ASSET_SIZE) { + write_size = remaining; + } - status = psa_its_set(uid, write_size, data_ptr, PSA_STORAGE_FLAG_NONE); + status = SETTINGS_PSA_SET(uid, write_size, data_ptr, PSA_STORAGE_FLAG_NONE); if (status) { LOG_ERR("Error storing %d bytes of metadata! Bytes Remaining: %d, status: " "%d", @@ -70,7 +95,7 @@ static int store_entries(void) uid++; } - LOG_DBG("PSA storage entries stored successfully - bytes_saved: %d num_entries: %d max_uid: %lld", + LOG_DBG("PSA entries stored successfully - bytes_saved: %d num_entries: %d max_uid: %lld", sizeof(entries), entries_count, uid); return 0; @@ -80,9 +105,8 @@ static int load_entries(void) { psa_status_t status; size_t bytes_read; - psa_storage_uid_t uid = ZEPHYR_PSA_SETTINGS_TFM_ITS_UID_RANGE_BEGIN; + psa_storage_uid_t uid = SETTINGS_PSA_UID_RANGE_BEGIN; size_t remaining = sizeof(entries); - size_t chunk_size = ITS_MAX_ASSET_SIZE; uint8_t *data_ptr = (uint8_t *)&entries; /* @@ -91,9 +115,12 @@ static int load_entries(void) * number of allocated UIDs and to allocate bytes in the most efficient way. */ while (remaining > 0) { - size_t to_read = (remaining > chunk_size) ? chunk_size : remaining; + size_t read_size = SETTINGS_PSA_MAX_ASSET_SIZE; + if (remaining < SETTINGS_PSA_MAX_ASSET_SIZE) { + read_size = remaining; + } - status = psa_its_get(uid, 0, to_read, data_ptr, &bytes_read); + status = SETTINGS_PSA_GET(uid, 0, read_size, data_ptr, &bytes_read); if (status) { return status; } From 3117d7ad2c8f74bce98b6a0ba7c634b4f3863f78 Mon Sep 17 00:00:00 2001 From: Dmitrii Sharshakov Date: Sat, 6 Dec 2025 14:37:41 +0100 Subject: [PATCH 0117/3659] tests: settings: cover PSA PS backend Just like ITS, it can be tested on mps2/an521/cpu0/ns with TF-M. Signed-off-by: Dmitrii Sharshakov --- .../functional/src/settings_basic_test.c | 24 ++++++++++++-- .../settings/functional/tfm_psa/testcase.yaml | 33 ++++++++++++------- tests/subsys/settings/tfm_psa/testcase.yaml | 29 ++++++++++------ 3 files changed, 61 insertions(+), 25 deletions(-) diff --git a/tests/subsys/settings/functional/src/settings_basic_test.c b/tests/subsys/settings/functional/src/settings_basic_test.c index 8e44394c0e98..da00b1e7237d 100644 --- a/tests/subsys/settings/functional/src/settings_basic_test.c +++ b/tests/subsys/settings/functional/src/settings_basic_test.c @@ -26,8 +26,26 @@ LOG_MODULE_REGISTER(settings_basic_test); #include #elif defined(CONFIG_SETTINGS_TFM_PSA) +#if defined(CONFIG_SETTINGS_TFM_PSA_BACKEND_PS) +#include +#include + +#define SETTINGS_PSA_MAX_ASSET_SIZE PS_MAX_ASSET_SIZE +#define SETTINGS_PSA_REMOVE psa_ps_remove +#define SETTINGS_PSA_ID_RANGE_START ZEPHYR_PSA_SETTINGS_TFM_PS_UID_RANGE_BEGIN + +#elif defined(CONFIG_SETTINGS_TFM_PSA_BACKEND_ITS) #include #include + +#define SETTINGS_PSA_MAX_ASSET_SIZE ITS_MAX_ASSET_SIZE +#define SETTINGS_PSA_REMOVE psa_its_remove +#define SETTINGS_PSA_ID_RANGE_START ZEPHYR_PSA_SETTINGS_TFM_ITS_UID_RANGE_BEGIN + +#else +#error "No PSA backend selected" +#endif /* CONFIG_SETTINGS_TFM_PSA_BACKEND */ + /* TF-M config file containing ITS_MAX_ASSET_SIZE */ #include @@ -49,10 +67,10 @@ ZTEST(settings_functional, test_clear_settings) #if defined(CONFIG_SETTINGS_TFM_PSA) psa_status_t status; - /* Remove all potentially accessed ITS entries in the UID range */ + /* Remove all potentially accessed entries in the UID range */ for (int i = 0; i < sizeof(struct setting_entry) * CONFIG_SETTINGS_TFM_PSA_NUM_ENTRIES / - ITS_MAX_ASSET_SIZE + 1; i++) { - status = psa_its_remove(ZEPHYR_PSA_SETTINGS_TFM_ITS_UID_RANGE_BEGIN + i); + SETTINGS_PSA_MAX_ASSET_SIZE + 1; i++) { + status = SETTINGS_PSA_REMOVE(SETTINGS_PSA_ID_RANGE_START + i); zassert_true((status == PSA_SUCCESS) || (status == PSA_ERROR_DOES_NOT_EXIST), "psa_its_remove failed"); } diff --git a/tests/subsys/settings/functional/tfm_psa/testcase.yaml b/tests/subsys/settings/functional/tfm_psa/testcase.yaml index 561645212dd6..eaed7cc4b8e5 100644 --- a/tests/subsys/settings/functional/tfm_psa/testcase.yaml +++ b/tests/subsys/settings/functional/tfm_psa/testcase.yaml @@ -1,16 +1,25 @@ +common: + integration_platforms: + - max32657evkit/max32657/ns + - nrf5340dk/nrf5340/cpuapp/ns + - nrf54l15dk/nrf54l15/cpuapp/ns + - nrf54lm20dk/nrf54lm20a/cpuapp/ns + - mps2/an521/cpu0/ns + platform_exclude: + - lpcxpresso55s69/lpc55s69/cpu0/ns + tags: + - settings + - trusted-firmware-m + extra_args: + - CONFIG_SETTINGS_TFM_PSA=y + tests: + settings.functional.tfm-ps: + filter: CONFIG_TFM_PARTITION_PROTECTED_STORAGE + extra_args: + - CONFIG_SETTINGS_TFM_PSA_BACKEND_PS=y + settings.functional.tfm-its: filter: CONFIG_TFM_PARTITION_INTERNAL_TRUSTED_STORAGE - integration_platforms: - - max32657evkit/max32657/ns - - nrf5340dk/nrf5340/cpuapp/ns - - nrf54l15dk/nrf54l15/cpuapp/ns - - nrf54lm20dk/nrf54lm20a/cpuapp/ns - - mps2/an521/cpu0/ns - platform_exclude: - - lpcxpresso55s69/lpc55s69/cpu0/ns - tags: - - settings - - trusted-firmware-m extra_args: - - CONFIG_SETTINGS_TFM_PSA=y + - CONFIG_SETTINGS_TFM_PSA_BACKEND_ITS=y diff --git a/tests/subsys/settings/tfm_psa/testcase.yaml b/tests/subsys/settings/tfm_psa/testcase.yaml index 379e67cbc4c6..4c036ca752b4 100644 --- a/tests/subsys/settings/tfm_psa/testcase.yaml +++ b/tests/subsys/settings/tfm_psa/testcase.yaml @@ -2,16 +2,25 @@ # # SPDX-License-Identifier: Apache-2.0 +common: + integration_platforms: + - max32657evkit/max32657/ns + - nrf5340dk/nrf5340/cpuapp/ns + - nrf54l15dk/nrf54l15/cpuapp/ns + - nrf54lm20dk/nrf54lm20a/cpuapp/ns + - mps2/an521/cpu0/ns + - lpcxpresso55s69/lpc55s69/cpu0/ns + tags: + - settings + - trusted-firmware-m + tests: + settings.tfm_psa_ps: + filter: CONFIG_TFM_PARTITION_PROTECTED_STORAGE + extra_args: + - CONFIG_SETTINGS_TFM_PSA_BACKEND_PS=y + settings.tfm_psa_its: filter: CONFIG_TFM_PARTITION_INTERNAL_TRUSTED_STORAGE - integration_platforms: - - max32657evkit/max32657/ns - - nrf5340dk/nrf5340/cpuapp/ns - - nrf54l15dk/nrf54l15/cpuapp/ns - - nrf54lm20dk/nrf54lm20a/cpuapp/ns - - mps2/an521/cpu0/ns - - lpcxpresso55s69/lpc55s69/cpu0/ns - tags: - - settings - - trusted-firmware-m + extra_args: + - CONFIG_SETTINGS_TFM_PSA_BACKEND_PS=y From 7c3762130de3e9feb3dfa7d1439733ab3b940492 Mon Sep 17 00:00:00 2001 From: Dmitrii Sharshakov Date: Sat, 6 Dec 2025 14:37:47 +0100 Subject: [PATCH 0118/3659] samples: settings: cover PSA PS backend By default, run on mps2/an521/cpu0/ns with TF-M. Signed-off-by: Dmitrii Sharshakov --- samples/subsys/settings/sample.yaml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/samples/subsys/settings/sample.yaml b/samples/subsys/settings/sample.yaml index 1080c0c0fdee..be571f428d5b 100644 --- a/samples/subsys/settings/sample.yaml +++ b/samples/subsys/settings/sample.yaml @@ -56,6 +56,16 @@ tests: - CONFIG_SETTINGS_NVS=y - CONFIG_MPU_ALLOW_FLASH_WRITE=y + sample.subsys.settings.tfm-ps: + tags: + - trusted-firmware-m + filter: CONFIG_TFM_PARTITION_PROTECTED_STORAGE + integration_platforms: + - mps2/an521/cpu0/ns + extra_args: + - CONFIG_SETTINGS_TFM_PSA=y + - CONFIG_SETTINGS_TFM_PSA_BACKEND_PS=y + sample.subsys.settings.tfm-its: tags: - trusted-firmware-m @@ -64,3 +74,4 @@ tests: - mps2/an521/cpu0/ns extra_args: - CONFIG_SETTINGS_TFM_PSA=y + - CONFIG_SETTINGS_TFM_PSA_BACKEND_ITS=y From e80b608cd46fc0f7b45de4946b72007c61f0a21d Mon Sep 17 00:00:00 2001 From: Dmitrii Sharshakov Date: Sun, 30 Nov 2025 21:23:05 +0100 Subject: [PATCH 0119/3659] settings: tfm_psa: improve code style Fix SonarQube warnings, move variable declarations to the top of the block according to Zephyr code style Signed-off-by: Dmitrii Sharshakov --- subsys/settings/src/settings_tfm_psa.c | 39 +++++++++++++------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/subsys/settings/src/settings_tfm_psa.c b/subsys/settings/src/settings_tfm_psa.c index b5aa4512b292..8d6495f0bf7a 100644 --- a/subsys/settings/src/settings_tfm_psa.c +++ b/subsys/settings/src/settings_tfm_psa.c @@ -68,6 +68,7 @@ static int store_entries(void) { psa_status_t status; psa_storage_uid_t uid = SETTINGS_PSA_UID_RANGE_BEGIN; + size_t write_size = SETTINGS_PSA_MAX_ASSET_SIZE; size_t remaining = sizeof(entries); const uint8_t *data_ptr = (const uint8_t *)&entries; @@ -77,7 +78,6 @@ static int store_entries(void) * number of allocated UIDs and to allocate bytes in the most efficient way. */ while (remaining > 0) { - size_t write_size = SETTINGS_PSA_MAX_ASSET_SIZE; if (remaining < SETTINGS_PSA_MAX_ASSET_SIZE) { write_size = remaining; } @@ -106,8 +106,10 @@ static int load_entries(void) psa_status_t status; size_t bytes_read; psa_storage_uid_t uid = SETTINGS_PSA_UID_RANGE_BEGIN; + size_t read_size = SETTINGS_PSA_MAX_ASSET_SIZE; size_t remaining = sizeof(entries); uint8_t *data_ptr = (uint8_t *)&entries; + int i; /* * Each storage UID is treated like a sector. Data is written to each KV pair until @@ -115,7 +117,6 @@ static int load_entries(void) * number of allocated UIDs and to allocate bytes in the most efficient way. */ while (remaining > 0) { - size_t read_size = SETTINGS_PSA_MAX_ASSET_SIZE; if (remaining < SETTINGS_PSA_MAX_ASSET_SIZE) { read_size = remaining; } @@ -130,7 +131,7 @@ static int load_entries(void) uid++; } - for (int i = 0; i < CONFIG_SETTINGS_TFM_PSA_NUM_ENTRIES; i++) { + for (i = 0; i < CONFIG_SETTINGS_TFM_PSA_NUM_ENTRIES; i++) { if (strnlen(entries[i].name, SETTINGS_MAX_NAME_LEN) != 0) { entries_count++; } @@ -164,9 +165,10 @@ static ssize_t settings_psa_read_fn(void *back_end, void *data, size_t len) static int settings_psa_load(struct settings_store *cs, const struct settings_load_arg *arg) { + int i; int ret; - for (int i = 0; i < entries_count; i++) { + for (i = 0; i < entries_count; i++) { if (strnlen(entries[i].name, SETTINGS_MAX_NAME_LEN) != 0) { /* * Pass the key to the settings handler with it's index as an argument, @@ -174,7 +176,7 @@ static int settings_psa_load(struct settings_store *cs, const struct settings_lo */ ret = settings_call_set_handler(entries[i].name, entries[i].val_len, settings_psa_read_fn, (void *)&i, - (void *)arg); + arg); if (ret) { return ret; } @@ -187,6 +189,9 @@ static int settings_psa_load(struct settings_store *cs, const struct settings_lo static int settings_psa_save(struct settings_store *cs, const char *name, const char *value, size_t val_len) { + int index; + bool delete; + if (entries_count >= CONFIG_SETTINGS_TFM_PSA_NUM_ENTRIES) { LOG_ERR("%s: Max settings reached: %d", __func__, CONFIG_SETTINGS_TFM_PSA_NUM_ENTRIES); @@ -198,9 +203,6 @@ static int settings_psa_save(struct settings_store *cs, const char *name, const return -EINVAL; } - int index; - bool delete; - /* Find out if we are doing a delete */ delete = ((value == NULL) || (val_len == 0)); @@ -215,7 +217,6 @@ static int settings_psa_save(struct settings_store *cs, const char *name, const if (strncmp(entries[index].name, name, SETTINGS_MAX_NAME_LEN) == 0) { break; } else if (entries[index].val_len == 0) { - /* Setting already deleted */ if (delete) { LOG_DBG("%s: %s Already deleted!", __func__, name); @@ -268,21 +269,21 @@ void worker_persist_entries_struct_fn(struct k_work *work) int settings_backend_init(void) { - psa_status_t status; - /* Load settings from storage */ - status = load_entries(); + psa_status_t status = load_entries(); + + if (status != PSA_SUCCESS) { + if (status != PSA_ERROR_DOES_NOT_EXIST) { + LOG_ERR("Error %s metadata: status %d", "loading", status); + return -EIO; + } - /* If resource DNE, we need to allocate it */ - if (status == PSA_ERROR_DOES_NOT_EXIST) { + /* If resource does not exist, we need to allocate it */ status = store_entries(); - if (status) { - LOG_ERR("Error storing metadata in %s: (status %d)", __func__, status); + if (status != PSA_SUCCESS) { + LOG_ERR("Error %s metadata: status %d", "storing", status); return -EIO; } - } else if (status) { - LOG_ERR("Error loading metadata in %s: (status %d)", __func__, status); - return -EIO; } settings_dst_register(&default_settings_psa); From a6b9f877e93d2f16350b326b1c4a2b95c05bc0ba Mon Sep 17 00:00:00 2001 From: Dmitrii Sharshakov Date: Sat, 6 Dec 2025 14:35:47 +0100 Subject: [PATCH 0120/3659] doc: releases: migration-guide-4.4: add a note on SETTINGS_TFM_PSA Add a note about a renamed Kconfig option Signed-off-by: Dmitrii Sharshakov --- doc/releases/migration-guide-4.4.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/doc/releases/migration-guide-4.4.rst b/doc/releases/migration-guide-4.4.rst index d3f4985e9205..37c27abf0b95 100644 --- a/doc/releases/migration-guide-4.4.rst +++ b/doc/releases/migration-guide-4.4.rst @@ -252,6 +252,11 @@ Tracing With this change, existing CTF traces with 8-bit IDs won't be compatible. +Settings +======== + +* ``CONFIG_SETTINGS_TFM_ITS`` has been renamed to :kconfig:option:`CONFIG_SETTINGS_TFM_PSA`. + Modules ******* From ccdf98acd8fd62712ce4797fcf007527ce73a31e Mon Sep 17 00:00:00 2001 From: Mario Paja Date: Mon, 8 Dec 2025 17:04:42 +0100 Subject: [PATCH 0121/3659] drivers: remove on-stack copying of dma cfg on stm32 drivers This change removes the on-stack copying and instead uses a pointer to the configuration to avoid unnecessary stack usage Signed-off-by: Mario Paja --- drivers/flash/flash_stm32_ospi.c | 18 +++++++++--------- drivers/flash/flash_stm32_qspi.c | 18 +++++++++--------- drivers/i2s/i2s_stm32_sai.c | 18 +++++++++--------- 3 files changed, 27 insertions(+), 27 deletions(-) diff --git a/drivers/flash/flash_stm32_ospi.c b/drivers/flash/flash_stm32_ospi.c index 3f092ee129a9..3f0cd1f9ecfc 100644 --- a/drivers/flash/flash_stm32_ospi.c +++ b/drivers/flash/flash_stm32_ospi.c @@ -2233,7 +2233,7 @@ static int flash_stm32_ospi_init(const struct device *dev) * the minimum information to inform the DMA slot will be in used and * how to route callbacks. */ - struct dma_config dma_cfg = dev_data->dma.cfg; + struct dma_config *dma_cfg = &dev_data->dma.cfg; static DMA_HandleTypeDef hdma; if (!device_is_ready(dev_data->dma.dev)) { @@ -2242,22 +2242,22 @@ static int flash_stm32_ospi_init(const struct device *dev) } /* Proceed to the minimum Zephyr DMA driver init */ - dma_cfg.user_data = &hdma; + dma_cfg->user_data = &hdma; /* HACK: This field is used to inform driver that it is overridden */ - dma_cfg.linked_channel = STM32_DMA_HAL_OVERRIDE; - ret = dma_config(dev_data->dma.dev, dev_data->dma.channel, &dma_cfg); + dma_cfg->linked_channel = STM32_DMA_HAL_OVERRIDE; + ret = dma_config(dev_data->dma.dev, dev_data->dma.channel, dma_cfg); if (ret != 0) { LOG_ERR("Failed to configure DMA channel %d", dev_data->dma.channel); return ret; } /* Proceed to the HAL DMA driver init */ - if (dma_cfg.source_data_size != dma_cfg.dest_data_size) { + if (dma_cfg->source_data_size != dma_cfg->dest_data_size) { LOG_ERR("Source and destination data sizes not aligned"); return -EINVAL; } - int index = find_lsb_set(dma_cfg.source_data_size) - 1; + int index = find_lsb_set(dma_cfg->source_data_size) - 1; #if CONFIG_DMA_STM32U5 /* Fill the structure for dma init */ @@ -2277,14 +2277,14 @@ static int flash_stm32_ospi_init(const struct device *dev) hdma.Init.MemInc = DMA_MINC_ENABLE; #endif /* CONFIG_DMA_STM32U5 */ hdma.Init.Mode = DMA_NORMAL; - hdma.Init.Priority = table_priority[dma_cfg.channel_priority]; + hdma.Init.Priority = table_priority[dma_cfg->channel_priority]; hdma.Init.Direction = DMA_PERIPH_TO_MEMORY; hdma.Instance = STM32_DMA_GET_INSTANCE(dev_data->dma.reg, dev_data->dma.channel); #ifdef CONFIG_DMA_STM32_V1 /* TODO: Not tested in this configuration */ - hdma.Init.Channel = dma_cfg.dma_slot; + hdma.Init.Channel = dma_cfg->dma_slot; #else - hdma.Init.Request = dma_cfg.dma_slot; + hdma.Init.Request = dma_cfg->dma_slot; #endif /* CONFIG_DMA_STM32_V1 */ /* Initialize DMA HAL */ diff --git a/drivers/flash/flash_stm32_qspi.c b/drivers/flash/flash_stm32_qspi.c index a88b7a0aebf0..bde14f611bac 100644 --- a/drivers/flash/flash_stm32_qspi.c +++ b/drivers/flash/flash_stm32_qspi.c @@ -1558,7 +1558,7 @@ static int flash_stm32_qspi_init(const struct device *dev) * the minimum information to inform the DMA slot will be in used and * how to route callbacks. */ - struct dma_config dma_cfg = dev_data->dma.cfg; + struct dma_config *dma_cfg = &dev_data->dma.cfg; static DMA_HandleTypeDef hdma; if (!device_is_ready(dev_data->dma.dev)) { @@ -1567,34 +1567,34 @@ static int flash_stm32_qspi_init(const struct device *dev) } /* Proceed to the minimum Zephyr DMA driver init */ - dma_cfg.user_data = &hdma; + dma_cfg->user_data = &hdma; /* HACK: This field is used to inform driver that it is overridden */ - dma_cfg.linked_channel = STM32_DMA_HAL_OVERRIDE; - ret = dma_config(dev_data->dma.dev, dev_data->dma.channel, &dma_cfg); + dma_cfg->linked_channel = STM32_DMA_HAL_OVERRIDE; + ret = dma_config(dev_data->dma.dev, dev_data->dma.channel, dma_cfg); if (ret != 0) { return ret; } /* Proceed to the HAL DMA driver init */ - if (dma_cfg.source_data_size != dma_cfg.dest_data_size) { + if (dma_cfg->source_data_size != dma_cfg->dest_data_size) { LOG_ERR("Source and destination data sizes not aligned"); return -EINVAL; } - int index = find_lsb_set(dma_cfg.source_data_size) - 1; + int index = find_lsb_set(dma_cfg->source_data_size) - 1; hdma.Init.PeriphDataAlignment = table_p_size[index]; hdma.Init.MemDataAlignment = table_m_size[index]; hdma.Init.PeriphInc = DMA_PINC_DISABLE; hdma.Init.MemInc = DMA_MINC_ENABLE; hdma.Init.Mode = DMA_NORMAL; - hdma.Init.Priority = table_priority[dma_cfg.channel_priority]; + hdma.Init.Priority = table_priority[dma_cfg->channel_priority]; hdma.Instance = STM32_DMA_GET_INSTANCE(dev_data->dma.reg, dev_data->dma.channel); #ifdef CONFIG_DMA_STM32_V1 /* TODO: Not tested in this configuration */ - hdma.Init.Channel = dma_cfg.dma_slot; + hdma.Init.Channel = dma_cfg->dma_slot; #else - hdma.Init.Request = dma_cfg.dma_slot; + hdma.Init.Request = dma_cfg->dma_slot; #endif /* CONFIG_DMA_STM32_V1 */ /* Initialize DMA HAL */ diff --git a/drivers/i2s/i2s_stm32_sai.c b/drivers/i2s/i2s_stm32_sai.c index 323f28b84176..6b556de798b1 100644 --- a/drivers/i2s/i2s_stm32_sai.c +++ b/drivers/i2s/i2s_stm32_sai.c @@ -303,7 +303,7 @@ static int i2s_stm32_sai_dma_init(const struct device *dev) { struct i2s_stm32_sai_data *dev_data = dev->data; struct stream *stream = &dev_data->stream; - struct dma_config dma_cfg = dev_data->stream.dma_cfg; + struct dma_config *dma_cfg = &dev_data->stream.dma_cfg; int ret; SAI_HandleTypeDef *hsai = &dev_data->hsai; @@ -315,12 +315,12 @@ static int i2s_stm32_sai_dma_init(const struct device *dev) } /* Proceed to the minimum Zephyr DMA driver init */ - dma_cfg.user_data = hdma; + dma_cfg->user_data = hdma; /* HACK: This field is used to inform driver that it is overridden */ - dma_cfg.linked_channel = STM32_DMA_HAL_OVERRIDE; + dma_cfg->linked_channel = STM32_DMA_HAL_OVERRIDE; - ret = dma_config(stream->dma_dev, stream->dma_channel, &dma_cfg); + ret = dma_config(stream->dma_dev, stream->dma_channel, dma_cfg); if (ret != 0) { LOG_ERR("Failed to configure DMA channel %d", stream->dma_channel); return ret; @@ -329,16 +329,16 @@ static int i2s_stm32_sai_dma_init(const struct device *dev) hdma->Instance = STM32_DMA_GET_INSTANCE(stream->reg, stream->dma_channel); hdma->Init.Mode = DMA_NORMAL; - if (dma_cfg.channel_priority >= ARRAY_SIZE(dma_priority)) { + if (dma_cfg->channel_priority >= ARRAY_SIZE(dma_priority)) { LOG_ERR("Invalid DMA channel priority"); return -EINVAL; } - hdma->Init.Priority = dma_priority[dma_cfg.channel_priority]; + hdma->Init.Priority = dma_priority[dma_cfg->channel_priority]; #if defined(DMA_CHANNEL_1) - hdma->Init.Channel = dma_cfg.dma_slot * DMA_CHANNEL_1; + hdma->Init.Channel = dma_cfg->dma_slot * DMA_CHANNEL_1; #else - hdma->Init.Request = dma_cfg.dma_slot; + hdma->Init.Request = dma_cfg->dma_slot; #endif if (dma_cfg.source_data_size != dma_cfg.dest_data_size) { @@ -377,7 +377,7 @@ static int i2s_stm32_sai_dma_init(const struct device *dev) hdma->Init.FIFOMode = DMA_FIFOMODE_DISABLE; #endif - if (stream->dma_cfg.channel_direction == (enum dma_channel_direction)MEMORY_TO_PERIPHERAL) { + if (dma_cfg->channel_direction == (enum dma_channel_direction)MEMORY_TO_PERIPHERAL) { hdma->Init.Direction = DMA_MEMORY_TO_PERIPH; #if defined(CONFIG_DMA_STM32U5) From f4cfd85c5641ff3a92e6a7fb1dcec742b3347ba0 Mon Sep 17 00:00:00 2001 From: Mario Paja Date: Mon, 8 Dec 2025 17:05:29 +0100 Subject: [PATCH 0122/3659] drivers: video: stm32_dcmi: relocate dma stream to driver data This change moves the dma stream from _config to _data, allowing direct reference the DMA stream rather than duplicating it on the stack. Additionally, it aligns the declaration to the other STM32 drivers. Signed-off-by: Mario Paja --- drivers/video/video_stm32_dcmi.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/drivers/video/video_stm32_dcmi.c b/drivers/video/video_stm32_dcmi.c index 6a5c720343ec..9d34344c902f 100644 --- a/drivers/video/video_stm32_dcmi.c +++ b/drivers/video/video_stm32_dcmi.c @@ -45,6 +45,7 @@ struct video_stm32_dcmi_data { struct k_fifo fifo_in; struct k_fifo fifo_out; struct video_buffer *vbuf; + struct stream dma; }; struct video_stm32_dcmi_config { @@ -52,7 +53,6 @@ struct video_stm32_dcmi_config { irq_config_func_t irq_config; const struct pinctrl_dev_config *pctrl; const struct device *sensor_dev; - const struct stream dma; }; static void stm32_dcmi_process_dma_error(DCMI_HandleTypeDef *hdcmi) @@ -130,12 +130,12 @@ static void dcmi_dma_callback(const struct device *dev, void *arg, uint32_t chan static int stm32_dma_init(const struct device *dev) { struct video_stm32_dcmi_data *data = dev->data; - const struct video_stm32_dcmi_config *config = dev->config; + struct stream *dma = &data->dma; int ret; /* Check if the DMA device is ready */ - if (!device_is_ready(config->dma.dma_dev)) { - LOG_ERR("%s DMA device not ready", config->dma.dma_dev->name); + if (!device_is_ready(dma->dma_dev)) { + LOG_ERR("%s DMA device not ready", dma->dma_dev->name); return -ENODEV; } @@ -147,16 +147,16 @@ static int stm32_dma_init(const struct device *dev) * the minimum information to inform the DMA slot will be in used and * how to route callbacks. */ - struct dma_config dma_cfg = config->dma.cfg; + struct dma_config *dma_cfg = &dma->cfg; static DMA_HandleTypeDef hdma; /* Proceed to the minimum Zephyr DMA driver init */ - dma_cfg.user_data = &hdma; + dma_cfg->user_data = &hdma; /* HACK: This field is used to inform driver that it is overridden */ - dma_cfg.linked_channel = STM32_DMA_HAL_OVERRIDE; - ret = dma_config(config->dma.dma_dev, config->dma.channel, &dma_cfg); + dma_cfg->linked_channel = STM32_DMA_HAL_OVERRIDE; + ret = dma_config(dma->dma_dev, dma->channel, dma_cfg); if (ret != 0) { - LOG_ERR("Failed to configure DMA channel %d", config->dma.channel); + LOG_ERR("Failed to configure DMA channel %d", dma->channel); return ret; } @@ -170,8 +170,7 @@ static int stm32_dma_init(const struct device *dev) hdma.Init.MemDataAlignment = DMA_MDATAALIGN_WORD; hdma.Init.Mode = DMA_CIRCULAR; hdma.Init.Priority = DMA_PRIORITY_HIGH; - hdma.Instance = STM32_DMA_GET_INSTANCE(config->dma.reg, - config->dma.channel); + hdma.Instance = STM32_DMA_GET_INSTANCE(dma->reg, dma->channel); #if defined(CONFIG_SOC_SERIES_STM32F7X) || defined(CONFIG_SOC_SERIES_STM32H7X) hdma.Init.FIFOMode = DMA_FIFOMODE_DISABLE; #endif @@ -533,6 +532,7 @@ static struct video_stm32_dcmi_data video_stm32_dcmi_data_0 = { .LineSelectStart = DCMI_OELS_ODD, }, }, + DCMI_DMA_CHANNEL(0, PERIPHERAL, MEMORY) }; #define SOURCE_DEV(n) DEVICE_DT_GET(DT_NODE_REMOTE_DEVICE(DT_INST_ENDPOINT_BY_ID(n, 0, 0))) @@ -542,7 +542,6 @@ static const struct video_stm32_dcmi_config video_stm32_dcmi_config_0 = { .irq_config = video_stm32_dcmi_irq_config_func, .pctrl = PINCTRL_DT_INST_DEV_CONFIG_GET(0), .sensor_dev = SOURCE_DEV(0), - DCMI_DMA_CHANNEL(0, PERIPHERAL, MEMORY) }; static int video_stm32_dcmi_init(const struct device *dev) From a57fcc12a82986b3538d7631810f2271de671094 Mon Sep 17 00:00:00 2001 From: Sercan Erat Date: Sat, 29 Nov 2025 14:32:46 +0300 Subject: [PATCH 0123/3659] boards: rakwireless: Adding rak11160 board support The RAK11160 WisDuo module is a low-power, long-range LoRaWAN module based on the STM32WLE5 and Espressif ESP8684H2 MCUs. Signed-off-by: Sercan Erat --- boards/rakwireless/rak11160/Kconfig.rak11160 | 5 + boards/rakwireless/rak11160/board.cmake | 12 ++ boards/rakwireless/rak11160/board.yml | 6 + .../rak11160/doc/img/rak11160.webp | Bin 0 -> 42314 bytes boards/rakwireless/rak11160/doc/index.rst | 79 ++++++++ boards/rakwireless/rak11160/rak11160.dts | 174 ++++++++++++++++++ boards/rakwireless/rak11160/rak11160.yaml | 19 ++ .../rakwireless/rak11160/rak11160_defconfig | 21 +++ 8 files changed, 316 insertions(+) create mode 100644 boards/rakwireless/rak11160/Kconfig.rak11160 create mode 100644 boards/rakwireless/rak11160/board.cmake create mode 100644 boards/rakwireless/rak11160/board.yml create mode 100644 boards/rakwireless/rak11160/doc/img/rak11160.webp create mode 100644 boards/rakwireless/rak11160/doc/index.rst create mode 100644 boards/rakwireless/rak11160/rak11160.dts create mode 100644 boards/rakwireless/rak11160/rak11160.yaml create mode 100644 boards/rakwireless/rak11160/rak11160_defconfig diff --git a/boards/rakwireless/rak11160/Kconfig.rak11160 b/boards/rakwireless/rak11160/Kconfig.rak11160 new file mode 100644 index 000000000000..cf75f12d0a7e --- /dev/null +++ b/boards/rakwireless/rak11160/Kconfig.rak11160 @@ -0,0 +1,5 @@ +# Copyright (c) 2025 RAKwireless Technology Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_RAK11160 + select SOC_STM32WLE5XX diff --git a/boards/rakwireless/rak11160/board.cmake b/boards/rakwireless/rak11160/board.cmake new file mode 100644 index 000000000000..d343c2f98fb9 --- /dev/null +++ b/boards/rakwireless/rak11160/board.cmake @@ -0,0 +1,12 @@ +# Copyright (c) 2025 RAKwireless Technology Co., Ltd. +# Sercan Erat +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(pyocd "--target=stm32wle5ccux") +board_runner_args(pyocd "--flash-opt=-O cmsis_dap.limit_packets=1") +board_runner_args(jlink "--device=STM32WLE5CC" "--speed=4000" "--reset-after-load") +board_runner_args(stm32cubeprogrammer "--port=swd" "--reset-mode=hw") + +include(${ZEPHYR_BASE}/boards/common/stm32cubeprogrammer.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) +include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake) diff --git a/boards/rakwireless/rak11160/board.yml b/boards/rakwireless/rak11160/board.yml new file mode 100644 index 000000000000..dba3f6317cb7 --- /dev/null +++ b/boards/rakwireless/rak11160/board.yml @@ -0,0 +1,6 @@ +board: + name: rak11160 + full_name: RAK11160 + vendor: rakwireless + socs: + - name: stm32wle5xx diff --git a/boards/rakwireless/rak11160/doc/img/rak11160.webp b/boards/rakwireless/rak11160/doc/img/rak11160.webp new file mode 100644 index 0000000000000000000000000000000000000000..da2acb5aa0bc8af57e3b99c2c439fe677e6606b0 GIT binary patch literal 42314 zcmce-Q*b6u(Et0yww-Kj+tw3vV{>EM&c?QFn;YBa#&$M*{=c{C)Tuh}#i=?sr)y>| z`l7FTKGoluZdF++DX~%jKuc0gSyP!u8y)}vp#HbD!2f570+nS(kpKX&yFj~-Lym8d zU~-hvwdR^%(0if7#jfh=&VNSqKWA8%&s2@>juWf_dXksHSYl7OKys+rLrNd@539j8 zyVBIrRZ~-gOG0F;1kVqG^{QW>jqm0!%a6I2{A=N@fHu(oa-`*5T&y3zc;;L?dI{Xf zbPma;xJ%Js#-MK*mxPLCT&5-8S9zFJYB++37tw5VCMFegyZF0GBjwJmKs33cZaRHM%% zpk0Mm@R_rle}+)dMWbEKdC^)Y%4%cdFk4LOxv)&P+RT)aX5y~7J#-KEt1Rm^>md|U zTS`+s{Xsj$Jr}DXiq|DT!{^TlWZ`k8W=y+Pl|1>5#YRBD3Q6{B(G#}B)0)!MsX>Cl z=Pr9qTs{B$dv;N_@u__Y5qSf6xpLx%xY$=PVk0;r;uXwO!rYD6$n>l9c+)j-@E?^) z{j7=^OfC7#1(D>cE%u`Gmz_4bwS%M|v6sU$VO^Aj@;m**OWiIZ>B&2-0#{WquB{Ww z&$-OtGS?blFT2c=d$KrJSuC!PsM1dln|iuYTz5$iXe;pc>W5H56}cQ$_O6MpTGAJr zF_Gc6m&$_sJ*rnZKW*xhtR)3^PEO4YR4*Wteeuf$pGLHsiTD$B((U9&2wc!Qiz*mk z?z}X(;slWzKm(BmThvzWBdh!2;{PLuUj{6&rFpWlkzUCWEYNh^*@gk6)?51f*olO5 zEm#ij$f)>@ho69z52!uO1zt9${;!p+ljlB^_`cVR{7s&b57U%wEg&)t>~8blCCVyGgGYUc>R*_si%vVO+h-pj%LK0WfldBe7LX(X?f-Kjl8 zWeOKyijYOnoQCa^yPBQ#d1BJab&XC1Gh$ZXuwhm|k8`2%%O=+-q3LVwCm#G2BGiTr z*j6to$%0$iJ0=m7{6b=89~ypuh^r71uVhO8B-t0_^dsPA(Z1^eKvqykIN$KUSm zh4nj(;Q&%$(cDD*L(G%%zn^^29Ts3{3QC%7XtfA)1-^kX8A3J$N7+y=OIW<+aC;8l z(Rwc1z#?+HwnyZYg1C|h{S)JDYG=vX-<+Fl7!|SC;BD+-yp=2hQ9q+2!GYJUBTu8B zgo@X_IDgjn<^u@JUS9IUaD`Du#^IG_3qZ_`J)~`~5FH1xxnTvs9p(BlrnXru%fN$v zalrDG%Z168DW2HKJu)CrEencyrETL>UTdy;9B8mE|9$$XRDnKy^Z^9O@ZV*@+rLvR zD5J9Z)EeHYr6OvIG^igKawDSyHSCc52Q^v~Yis@^*j^>@&iH`XCXGz%yc<39Vo)9L zzFj1)2|HyXK>hsFY>ESL=9iM5E2N`R0002%OsRDH`R3rr;<~}7k2V-!LXqC%v(x(J zAOMth%gn*qSJQBvFTJ^+PrY}&bpSAZ7Ii40i}X4k5Zs(W5?>DA{GB6UMbxd8lKN_x(Ky5{RXUF{kTP;xmpe?nbi_%z*RNbJ|(Ql`d`p%3UN{bBdGoGB5yKl_{W{p@0sO zVQO+##>A3h!sJ)hEHE#fSFs9h+RR>4=44PS<$h^v9f(5vJxBeo@*BS{aKBQ=M}teN z*E^K++1D+vN)Y3yx-1z+qHRbEp$BE7|L2sZoZ8G|?fM0W(6(T2v#9OW{kyt-H}KaY z(*~_}m8&v!K)0l21;{O;9WdZxA%F2NmQ&@)puUGn+&_TA;{A|F>6oAFmp3^(k%Koi zQi&?bL0NZ<`o{bW_Wu2<$ve+B4W6mi4{pEoYdhxU5ZhtpB;tqxa-$PrlqWi^@2f$8 z&8sTAt&^;Fw8_ciK{g-#Tj8;Mzr~~)JLLHX{8X4cIt5k7f7N@m{F^1n9uJp#ILK;- zbW|iFyJh{}X&GE+ky+mV>FifyB~5I=AdN{7lo|bxtocJx_GVp&x1Y{0-{!mQ$Ly!xBEFd%TkZMx(*QGh%2 z_XAt<$_^Ms`K<{ouG$=rdEQ#b`AxZcl($rf5fyv0SQBz@rK)3c_&Hhg>IbCoio+Ke zq|!9$FmWgGPmbYy1Y+9;?&7=6)Z`&+b zO8WB6+)D5zPP0k0kI#Pfd=#7BzkyR$D0ML9(634PPVy(5!mm~*;%B#1d(l^qG=Q0c zf8AhkUsM4lAmN+Ic{%vWpS)Jj+>B9+w!)Gw4#u^N&8*mnwysBGT=nL?26Kcss5Pd3 zR;~5F!i5>`=bWaFq-FI3xmKsWJ%*Z-YxaX=U@;`1;Pi)k@bR8LagpBjDbaV(UKg(aMqwTzdB-MXG5dBM*s-XsqrTj77wnjF4Wk1BMD0MPZP)SL(;@G2w{ z_Dyy=I9P!FaVd*M-yh?gMQNEeH};N;Oedb)6K6gnw2wVggiBl%(mO6yf4uA=T&^J9 zV!Oih#o3TMx28zO42tW7gw0mpxuAJF@V`d(VE9DtWT1-kT&9r3A=NYrObC(%^2Lv; zAJsRYny?nm;hhNu$7NWCf)J0$amk>YkX`h#0MZU4o>;e2~z>CZRHcd7K47C9BK( z7d|pA(Hji;&hG^|Y!oE%E3V9F;-l(*-A`c+Wl}@VHjq1nHi`6Dc(x93)W(Vhuey%T zNKwDCGvHCpfu@$-&5ZAiv7XD##x0GO$}e3 zU>?&@5`wBq3m*H=@6~#xj`ijKk;PAy@28)l82ASHY-jft?2WsbNiGvy7&iIYj(?Wl zz`CM~?sG#P~Xs6h(sA5mGCA2>aiNoch_&`1*H7NIu8c8ka+N| zPYeI!^`KbQX1NG9;AVi8>COZ2to!w&noktUac?0bq2@}zW^C+dldu~EVC+k@X^tHX zK$Vhg+Is;F7-t|81_&{YI12%Z3I}@WLTy{pt=2}OF{?ksiqc$&02ZS)-;lhVITAVQ zNMnKOlgHhWy9rW=%a;`dOSdqSjW?1Pk$Lcof&F4cj$cqX0Fn1>Z*WyFM8f-@wgOgy zx;obw1d){zQwyXD>ypdMjN~F!-4)fXCb%-3(R{}3C&3hcPz(JZQ;mcu=wBNcNBH_m z&A!YDZu-E-^g^`;P`w0HxOV4O4dID^MG(mc=z;!y?H%Pmm++x)V1Uf`GpKy?_Dic#`UUiA`0_OX zN(7mKhTlLBuORVPm~ZNdfake?{T;&BAkY^)NE(C!YJQmlfyQA#O3Emo0idryLACeB zFXoSkOW_-wStT%`?ys#+>eu=k;oC2#`=wLR-hTmmKqDa2SG5nAHv=@j)9<~){K@Yv zzy6Q-H{nN;U67^!U4S?U;tS?R`d_}>w_Jeko5r`xi^~~D9HCK;(hs( z`D175gZUk_*>4nYB$WK^@zMTH@&?)yBKfZVYJbh&32^-$2Mv5KfmB`~KGWZ+-}#E8Pm;1(bmdK~rCQU3(S%SD+%0 zIjH)}5)?3Sd(yuK+71W@34^pg`$3@Ze81hfesAHIk2?P;&va}j9tx< zp}f0Dd@S(Z}(A$p@YPmqs%FtEZy)W3TkcpPIm(&i<# z2E{X=L$58|6gC&KVXMUHbz`pa!FL@ZHhQMnTOLylEFBh5(00T<4r?9vQXZBWTT3~g zDp8|1D54bH(M6%zyDSkopgMXQpMHpGZrGG{N$Ld%y;F*K&=bR0aC=E!10zuqx~cK8@-5RFcbAK4HaMVN#jldm|J+?_})~$ zEX+Upe9_2q<6#9b{vE%9?3T@;dT1Zj-cFR6>kyA ztbTvbd7^kFQe_*;p0E%NaX`MzcW+Ezq@iB~`t*b=y9KGi>0FE*8egI0^l)k`6bu;+ z0xZXTHteF@E2NV=6C9JY_Q+2{M+8w0ms@5{0$dC+*^+;;p5FS!>Eex}18==WA8iAeb?4UTt(xZo zPz?6wZZ|q!4<)jte>eZ)b;vQ6TYPE6Msj%gwUweFX~Z7L+wet!)yRR4daQneRl!wN357-YiY_I>}PV6bzm48%v}f|8#NPb7_DxZ5DhB;Ro+$j=vaE^)GWvb2| zJUsX7+;80DI}*Xupt3l%lbuIILMc8z21DXsYnzu`!+_w*vK9Kq64EPyek!PLfg!h& zjlF{_SQPd7H3#Bj40Gx&?l`DMw{YjDmt^Wu^LWg>ID~Px4K8d?Y@IaNUv8Jf zOca-6k!+>D)GsRl+EgBKetdizj;^!RQ;=Q)wF`T7(hi@NqQx_d)i2_Kv z>N$bi%G(LSAo{s)l};c|i$UrqJo_PPXyW2iLy1i?nN(?tqJ* z$_AdEU;hs(cypawvExTV;kwL=Ulko)7lI5|&r^PAu5K{yC!z0%tSKxyd8zC4z>V<8rEH4s)h?5_|2J>wxdh}w6qg6}2O$Lci1%W=Mh>N3dLgzE5X<28HdG#p(_i&t zR=w5|yd(_@;i@)cEwTPWt;3H>r_+zZ(Aw<^yI|Gey~0M^A23^PU-^$M>e@%D*{t<_ z1whrHm=HEFRFCleT&#T6ME5WTAz%R)Y0_bBo4OPJy>04a`>{-WG>9dtr|OwK3IrZ0 z7fUFqWC^UiWbv@sh@@ne=QAC!u9-9&b=|HjZ{N$($tXgu{ZX##kw-;8BQ}gNSA^w^ zw&rpxL-U6yF#H^pOS87f1ka2y(Bm&uJN`9I;Z%B8Ru1+KU1Ti0s)(>gq*HP7_Hs1Y z5kFx)e4T5bo-+8mYRi3#7oU;dexRta2b#M`yf^0$cM8l2gwF`nmoI;uiR8kGVMk_) z>kbx5njQO8K?}z@SI9K`-$pfQ;%s)mWOOwYY=g!dn$jqJ8ou4EuVyo3s-8r!VAA4* zy-&cE)!x|}flSokIczXTeoyJCSr7`MU|2{{S4JGeR}+KqZvx`*B&9F1A4w#z%iuMiByS=oy z=b5{g4z>q1jhqzZ1+8Y9<~P1~+p~f!Yc7s|q{Spps{;90(jzn=q;~85#dTlv}nu(4=GU|}aj3=|n^l7{27-Eoy|mj;WqO_Rd@#fJ#}*f<=-QjC!o^p4NH|@1 zG_9MQUM)5LoWRZ&#Y+(I67tP zVIPJ4BomM~J`o@O*zCNt3@HH|{)j5Sc7>tEg$&b~Cb<5s;ysvByYMp0R7vcTN~sK7 zn-+4re*(!0UNcF_pAg666PwBJ34leF+@3u(Vy%<^y;i_r39006>PDkUQcKdoZ6eJ! zm8ih{lFs@f)k2vsI0rPj&O@~;U&q68$$#~fe@ceqcuYUxw;twG5=^=( z#ZVN#Z7$2RXOoJHkQraI-WZ{2*lJmETMsp#tiWQ$p3!z^q;M?AHE*Yz=uW;3`L#OU#(N{jOtm| zNLXdA))-U=J?2n$*;}E3`NvBpbJ##N4Gdt+)?cvsF0`{9%5Y014d0=>eVsHPC^5`_ zQaIhKYkK+459mMGgD}((E?_*>K4P1ichE*X27iTa3h!q(Y?6u3X+s+ePzMpZIGLba zxZ_XPIpZ~>5{mq#J2H8#u-TpC#d)QA3C3~`Ki>F;@j_h#s5P(iy7$h^A9%A#-tclZ zxrc*aVj-TV5H1WPEFii|e*tw@RNLWBjvAPvk3=NjWFqSvqL2afR1lun?0J*Jn_M+5jg~l7B{I zsl41|L(+oc%d8tKT-eHa=L`fY6vIm4pxpMj@DOc2w);J2-NqYp*lYU4AHUQgj8#Ut z+Y@w?~1G$ z6M0Z+LW9+_!)`bE8$?TX7(Hvr5+J6ZEirDHOgkX3*VN;}z9_A%D1hg{1I(oqj z@2``ne0~Z~4SENl6EeftNfzJ|5n zW6*QC<8M^P#ne^a20a2Dqo1)s z7~^F#*nUBg(Po3vq6}}ogM$sVwdAvgPPg%)&t0LO?3tzZF-}+gDs#A-PoicOt(D^6w?kYCeij!rj326+*)kDy>@Urp;K}@j4>3?+&)jGorcZNt;q> z^3Qb>lL(L~s@u|WZVb8ZM)Y~BJVZDM(vU9^!6*Ww9A+B>&cBf6;}_Y>Cj(+2L;b=* zZZH3TN~iyNsA?{90z|2|*;AGV1G6@R<@A9Bc}afOa2>A-#_kj0@U17%>VTk4Fs z0Z;)y8KZ+2YttaWBR9reFWU59BD>U~v&VI9d(M?w>_;95Xjm?vPsj=`x<0qMRrE7z1+=1$+4(y$m?`MjG0yI)d z&MYrE{lbSdvrW4CFv+fB@v**tZ9fhjb>s;|T#h>vmeScS2vBtBuQO5Vu*(Xw{*-EU z!qds^cIcEg>l(5*r8(Bb1rp==8?O-n6>>>B1!{3{w|br;h$wG$$keH1WfG==C0LP9^g$Ml!qxG$Pp4$g6O6^E&Rl* z05~B6;?JP$hfR%*^`vCE&@3q>47Y==RGt{9yCoRwDf+X3@qF03>2K$z5=^I)l!H+( zu5ALHl?Km_Tu zg-fMr3GCJ`RnDQ;9tMYvtTTlNjCf4yF>!j&b3@r=Wtg`1XgV}n2f|fNLNyv!%*624 z!QOocU<1N$4RB>94MuDBnMZBBc$Zxpooiq!Y&}sV@#TfspvxR=-mR)%5|}|*Ea`e+ zm6X(#8bbyOV}s&n$(jfGK(=z=5nIt#FeXg8O=nT(Z;T7>$9Zp#PcUz!&q)uzF!C=A zx-{oV6a554*Tdh&;iF+W>y%-C$uf{36T77?N)!HbaKhJj%BD#VlVJZ~N ztmQkjsGo}Yi zWT`e^@|>YE2PE?dLMTN>6L>zoIm2YycdLc7`TS|$0ykkw+66}9Rav;6N?*hm4kvT< zY!qj3gk5S~N#j^eAI^rmCqHl8$7~GO0x>aV;?KVjdzu~h|G)yIoU<&-zjMVMIO}-0 zIvZc0+VD&4Hm+9CZeZX!ve&@M%ReAK_+!r#LPt_tlk{N&^m7wdNV#O7q)yOhG#Q_7 zU&hkoG3sqeHp9S{a${13btpbd1|E`$xj(LP$_iRf8NKGD98|3DREJ$v7$>rt8+P!(u2Q0v(}D*!E8E0N!s z6uSC(&{GL0{Hp@qzILC};9hyr4rMXa3QV?g#h)u?_K2hA9^y(FmR`Zv#=_%RV{xV> zFY%6yY-=)Ny;vA>K-<0_Z#8ElUrjMeWbgy(4i+!%sK_;I(IC>T@)Y}^Z_O<1KH-Kh z!GB3t$4J#Z=vvF|0Sj$E0)FFmT^f{(dhSYw9dEe}|3e$gJzTZ$3k*Es8L9+=0o z^PE-_DNP7f0^4E#D)!jyFgRAN*6U^BsCTOb$av{Juc$igEzPSgtq?$<+6s6~5K%;g zD$Xs=qUu}SBW=m;!tPleX86$56^Q%&DS@HRCd!iJ@4o=Y90WWWhy>gwMr;^Mc@?DD zF=CG4%b;#Sx2PBj6tXoZ_n#!U$%%lkPDHX@snXm$1i!3hIf=zMjdps_WptX%610cI zYo%^e%JGpL#7XL|q+>y`q%rKRe>1^oMYV~V(eJYjre?X8c}pz628?BLVTN;>GZqB0 z%>UG-l*S-nU^xo91#iHA6dNC&_rs{fj3Mgh%`e&idc+`D89Sd7?$G{BO@1!j<hS~vpCy&ba!ft=lT9h8YEozd+2Xb{V2zo#2) zKE!nz%L5arI>uTfzSrGMzp1yu#z!xf8xoyOe<*|;B9RrabHnz^ZR!(*MU`o%Gj6!L zURQ|u7yXse8JgF6Kbqv})3fgKaj&K%IiQZJ&<5wBCkbm`{a!*0+&PQDNHLf#rBP+! zMpaU}a-y%NflZcUsgX>gQ*hJg>MaQ5M_C%@XY#o}i1*7U99)sqMrRBVfUjfTFy$4W zD;rBg!)|#9*g(I(|0EN&Wm^zi349v!Bx-{5_W zk_2)fQ+&epkb*hSKP4HaK<6hrgB68K;B`(J(5AIjBwf0)1MY2@fSD?_aZT`U1c?J9 z;c9ENAqz<^s7KDP9CB2 zH(DS2P1Jq_Rb?~RBDkq)yfnR9By5I9B?>PE&`@#!*TCW5wYu?VTni2ET1ICab|?Ha zgHX28930C!`(PZ@;$}LF?yWcHE#!T7yTvL;1#Gt@RJt5nn+Nvcsk=jrdRr4UTKjZ? z6;FvFUOJ~EGAmxXUIJ&ElEj8%So{cejpt{Y6ydAR?4RlGLJi#lzDCWs61Wg=+&asR z+Nso`HreNhNzU^$O_JJXsS&T%Q=zWl^$~0hA|B)7!V56MZ0*XkX2d^VXbi-48CWLb zXakczgB1bRo*l%)eyfXKh{Tpz3Rph}%^FAw1r7qLXKiV3-M?DaV^wk_;E(u`50QDF zWoNJudr@^40=xaL5{9uuUq=PG$V8=3fVsh1oNpKxf`sc{vsB+U&7OF&SmlEhZ{D7P zh?1@nL($oUsA6AJ4k>mn=e|o@@*4q;L-IIY$+@&~3sJ+S;=jn3WC#J(ZNFlDz*c_4 z^E*Ni2n$N>Xn$PMQXw?N8LBNz%#U-n8C|8M^Q86?Y~~_T~t!B{(hI& z)j^FU9mr~b^gdyjP_jhH+fT}Vlq(EY@O#Yu{v~G8LYb$shTn>|!|wyyzIayXlPntL zjAvY58meDcu~VB3He90WRztDJKjB-wDl?ehxc__v!0x2}`3uWN?oYBF#Q8WsSiY&B zFI^A&%ZS|N66~_R)_p7~#F{cGGkr5FN2Bg|07w7PupXG93J^kJVdRoIpWs*jgb5wQ zrACIwch^B5~n>R#<$VCxpy*2E zJf9(up~U47&Fwbq_#A|n5`b0>2}ahTNlv-V<)xu_4(%*Nt>p>8^YF7~Dk>6QqAk~> zZLAI2vIQFt!wpa zOQlEQm3ozSLwJwVr(5bd)Mr4{ZG*qm+!c{22Y9v-0TLH_5;o;Ok2qnEf*O&Zw!d?d zQ{yzm#CDgzd-W_Oml6xzh{tXW?cwUNy}OC5swoO+y??rWr7rq4?~K=GsQV`r6UT?G zEd8m_P7#k$s}po9N7pj=ug^ja@;b6woEWDha8^!o{&jP{{)Q712yDoH-*^&m>Q=J(|=Fc?06!&?eI<|;oB5d{?XA!<>7Og zK4{#kTSY}!*w0w=J8#*!@DRukeG+2W^k6E^o!M3x#)T8P2>l|1V-z!z9yzYnL%ce>~DR;)QkY96Nj;FJfd1j@!kub67#7#a!b z_xY~2QL1v?wlEJ!D!IZj2tzBSD0qGWIQauQPQc4KT0r91 zC(_|}MoE)>q}MWDSqMp|ZOB8sDy-hNAMG|+f??NH6$pfyaK?nLk38FA$v{u6DGBv+j|7t1$Tf{hf)a9WU?@NAG1V^~a9^c%PFde`=} zuqC?k9{OYOkN)76fmJ2uXi(xRP@xyK&`+eWhzA=Z)6j_~50B1Nv`%+w5~bv>PL=sk z+5}@QT9l`c3-2k~Tm`TJButJcp_xC3`%#v(sWC>r>HLvb#S-HTOm7#E)+jkvE*OhM zufDD=TlqIcCAMZCq`l~>4|_r%*uM}i-x;FsLuMcMp;TB?$>2jbMzr2Kp_U`gEly}0mGgektj zBQl0MDHS$XhkyNy3;zy;}xTc;^rb zYs-rIi5%7Ni?zDIXidf137uXcm3gBAL)Y}DSsAP075ao>$xv@~4WZZSPjNerflVm< z1}agpDF-7+{F#17j;^O!^1s95J454qDJnV90?N?kN#*R!4szz3H3oHxS7dZa&9Z#J z&WgsiPdSV^qDT90)*zRl`Cn;)lnTrG`x7FSp`?s4pl3S&mw@02qY?h*9?rGv? zb*dY}QWuiuOH@N^JpldIURILc&ocs;^Lty3*Ev~YRNFn1`9 z1%d@IeyvJ9DO5-$Ej2Z)9_afDHGMfe5hE%x>Ium-De`j`M17u&LM&3(gSWi;jfOuh z_liQU_)6Mt__#<`XSN$TD{l1d|2zxnno(@?cqn8gb_;rz#J&?(z?G*c$C#(=WDrU{co+0{fhp;G2YmEdqoNoQt$&FMA@QG zFyxLMa7SH{^}`LZ0<|#$j0h48XzIh1ZkuwOlUUxVFwe6{xJQi9z(d{XA{DOdbBxn& zjXdX3Uh#S`V#AbO7oPD2-0AD%%K{@Jo6SfkBvLs^AD!fY0o{do4u zO!uSN2(5w@p8PS=doW8;rDAmsitj~GI-~nc3Ay(U+PZV$g2?yc$l1KPQiS&Bj-eE`Rx;JL%I4a z>vBaE?#Sww#@$z2Js;RX`9E!_^wN{;x1w2?J_dV1CpZ_vMpDg&$i+5bgNV)G*;0nr zG6Sp_=_CUxdimPbNPra1r@ZL>(`y~ZzdZr};r-8=@=LL#q;bMtoQChDP}WtJ;K2EI z+&&tc%RM&uUW_#)`K`WVJtFPnrB5M)VEzE*j+Ar6xe}4k*LO-p1j4;*l=jKM-=BPD z)*ixL&2bsO^P0AemmiuwtbR*mg8rJ8uth1`gc*!edP=$+X~e_9nhZ*&|HW1<#wh}0 zItxW)4zVCMp5T!-c={Nl+PW8o4bvui9RCaXk`{QsEp^LyyC@5OYH0yu0nQaYNTi(kWF&K`>8epOG%!xbe>g&qARKb^YaMd z@Yyq$^@kJiqJysUr2RVUh-eNVzbl_%|4rP zhxwc%tQdiwcr1gfp^t3Y!^T5>lawGc$kR;xoU(AsxL=jc;wA(N%!qKuf+D^gWaw=t zt|u__##A5nzd@--B|I8H81c(pd$cApCOaHmer@8}9Yn5(u=D`Z$3UE3Q|215;#UT! z9vmZD%&oxJiT&ZpS^WTt$@1pjfyjXjb%G`4zL46gD~Bg8V)ceo*OK_o5JOU4$ueWn zG8P`?5A5uykBZjGw(&WlVFE=jiQGL2=wyv#D7PH50W7(XngR`OX>3dT}uC=VWsFMe+}L|6Y20=y-Qpi&#(hK_?uiL+t$c2T?!p7W!3j}fkTUonfF zk@(!^(^u9i8A*n2oM+eF(II+P>3+1ODlk%9+gjk_@lhBO5$3#CFaO5`CG@|i%b5F` zX0C}Jb^F0k;{Uzv*trMgaWxY`$Ymp?IYpSyFi0wsF8c0HdM2~Edsv67dH5k%JZ`f9mM zM<*-n*(oTHeRlXJZwR`Jgw55AyZ|CD<;lS7PC$DG?Ml%5Y0}mn0 zI7a6{A=M*D>dl|=kbARgmf&S0-kEn(yD_Wd$hSS3*UfLnL+OX32xpo$p^f-O>5U)( z8wrP}PQmbZ!Go-B04&{UbwsmTNkuqU7?Hz~LNi8l_HNdY0p4C+%tELC80xzwdf1;s zvEBIFX)p4%SYo@*k;{Csd<)iV775O4?@&<^`Ib7=TylX z9h;m??8>evtwQi?1X%g?x{?+?^`g&0X>Z9Tl2+KXkPowMALG~0T%Q%u0_R3l+2<4p z)Kmm^LyI1=15vxVHtZx&0U&6A4NAS5e8{F9TKQ8A>@Ktc+4t9wAbAadbZ1Nyv9MpW zvokZq=c%p(gR#yBms00EB(U7+n`n!m=?Be9knlkF`Cjn(HeBva0UQVR*_t4frs>=T zAChzTUy?~9@@+wYASCd9YtQE+z)Zun>YK$Dxz&5|wT;o6%`vw9y+LO#$*e!ZTZ-;B z9b%jqZ_cfQb*jUD^u_vS*^x^(&HpA@r&nkS=Zz)Gnzf<*xF9Vn>za_k6#aVKrgj>2 z;Lgm@{z+9Cg|>4=`3f&)c+sM^O7t106bvYKw3ES3+y}n#auj=Yn2`2VQ1UxE?_Xmu zqWXYN@@Sky(tiBaH$?i*s)K$yzQn7^z*6Ayl_3aFk@O>j-`|scJp*3o`82{)kx`}n zikR8JmHpo$9oBSFX&1}FU2w^Dk|y1!_>$^=nkj@pAJ5$1Zvok8`wlx1>Gxu=@My9l zLV7Y;-gB#o2?#+>rWYF7W#mQg#}~%W{?a1R|HKjVEC+NkYvCdKr?Z6NfIt4aJ8kHI z-X*f>o2H=7qc5l2>FKBSe?xKt6FTM?3!=GL7-MMdHA!d!1pc3baAumX=;6rqQTn#a zB6v~S_8=dK{^oHQL-3(#7&d|I>bnFA&{W$XaVRHXi=ZZ!j}$TUDL$CD;KA$;qr03Imjg)4093DQ__1UidsJaO)nnY}vl#aQ854)n3sD8W> zmQ)cXiybtEx5W&U*(<7IEJ|8Bf<-;gz}%~Ymc1G(bS*KV;)hkn3e$kXOO~5p2|2t0 zfGM}qGop-=LX+S(8&-5XW1hq*V26$uSk)P!hqx&p>U*I-Q2%Wx`NC$pF`$|=9uss& zyEc`8F!9?8JG;j#Ue~M>L4D6c9x4)U9S6(zli&CVJ+bzST5cR5Nbk1mBK&&(41G)@j;(2{Rg<5t9jUd4&W5;sp& zrGw*^wTl%^+IDnz!pF0zjv2JV%j+mOESxvr&5?h;s%%O%)F&-<$xSib@}z|_;kg*F zis5FM{*WkgfON7cLTyoqLLX#@G^WqHPL7l^08UW>o=XyQhQh#INVzjsh?px(XabpbU{ zu}#)0ClMO^!J*!E0!g6_tAIf?FL{E?My$1|r2t+%OA@QnU&j{TWoQ7=H|J~C**9cD zBCs*4^X51%`KveJ$DV9!87t;1ym>`1L8z)!o#I|nb)v*N2> zCv=A}dJ_a8skGJg*O+_!8@CN!_tSuZ_lk;(ZyeX>h>J<$Hje8j<40}3Jlpd%tig(GWdRp=6aCM54__yKSo@bg% zx8Z0A3STdR`qumvlLA$7$&`{W*dK!vR>_dF`qjjOK(AUVF>x5_g`Aj#LiOaPI2&*c zJu;4mb2ufi8J~A`A~6L=c=6#VYmDdx4N5O%+D%NiWhU+fvyC8Wnaa5=XYL5sZ3!M0 z$}jDqcP|ds$imY#S|p+OwxO>MW)5!-R%Y)Zk94NDP>iRepkv&33bD`Q%v=9E>ThoN zg?k0FckWgEQoJTZ-%z|M%*+7_lR0uirSpwR=gP}(Z9y6C?0!pZ;&-o9;-Pfc(3ttR zWOgnQ^v826v5r*B_PI;;5Z`|l&+#7~; zER52kF3RP`q~z;H0}M=3$bx(L_xgxaLrOmCn*ReGK;pl?s;CV|)IqP9t9qB)WMd{l z5yv{bHltL|HAG%xhPZff`y)P}JN}MQSFzdBvCdtpVN0JSG)ZOOPMU!_z2CiZrlp^t91Mru5Wa$>>j!Hvo$AQFu9O77!SnQWK#okJ!^$N^4yfW z9(4%Si&;0a7+456OerfyhxvPP;Lbwqo{QiyS@LXkdA%~$SmMQ|NR0VaWDKIA_UAp0wNt&k+C! zYZql%$5mGVk6xpRo|TsIEz8>r*JcL71}mrAY23Fcn@}O0{}4Vi963UF%Utj633i$@ z=%_Ffy9~vKq=eTSdtrP|_@T|aEH~D9l#t?kK-gy2C65u0YH8zh8P*Ywc!Qd8Y_9=k zsw>>!&M3K0dCA8hHiog?)d*EYs4)vLL|ly_&Z~n)uJaV_;T~s#VG3N=-v2D-FZSif zWe!!{PHQOPbL=VWAKyn&32Gve7i}O-K5Z)zy*y^w_bYePk;&k0NxjILC%Ka|u8^w# zT6{t}v6(UEcBlYZ+^C;n=eObZed$kl)!M15@HMsci;CIUH627z3^0FN9XZ0-zs&j% z*siQt9FSige_yF(7L~S;9b{P=_J@1Im%XJ8QB-^J((ACvH!zCA+*&>7+8(CMx`aQF zDmP%@d8d4z-)gp6URzKQF!n~BDC(&G30ul15?4x@=P@{m9xeAOg{aZt)}FRA_uldl;} z9s?sjGtbs+jLeuufhed7?81pTIB+F`WUZ$B;2E(Mq%d}!c}F;XR1q5<>`amwi0DRK z9)>bkP`q4P><*L{&Y4* z&y$E7xKKSZTdX@@)Hc}z=_m^}ERlaA<<*aa584Elac@ZfOnhT|&CEMeG%&2tajeCT zlrd7Pnw;CLA5)sAR!&_qeE^*1nVkwkJMzARrx6NSxC|~DVc-m4n}-6>AGGg;It=iR zdJ&b;q*B~(c7XWEMEHBlI#a?p2u)>rz>NEiH~JKAO+Mcwm$45*av4<$@=!qp{5(B} zL9OW&Vu&;2PV>Gp*9ez~M4cE=NY=M2)!T-anIxS2rmszar^RFh_`A+yxV6pRUro`` zBs*_MIl`xbqrGuDy&85?kR#$8F2(-okXq}dKUv60%&|qC)<4O(p z=kmoA!vl-}04TLD8mV3fY@@#)q3{Se;?!URY-^l6KCQ6_qll?;o~nK?9HNM}0S6#g zb99K&3?9)2_2l-NWz?)|eaXu(AlSzY`?>dk%KSID9GG}Sus=C-G-@^(CB2^P>Xmoe z4j1G5J1G2X+O;Q4>Q78i*JxT#fQn6+!eKSmUwYNs*6Xs2fdg!kn;w?evRkeVS`#d2 zgm$(3*YqvVQkP<@k$|X;00ZB5wc-C`!PK>X*(ROMJ9ByGahkEMbZ{)lxB_dK2L7mm zq`#2R9ZwoWIacxzS6fB+|9N|f#hx9U@Ka>BAny{uUjNE6=B7uoM}}*vDBVH%CXzD% z+>d4ox~10BhI{xx^#*=w&5jRcyjbsd*=X?VvDEh1_X(B%My192X4Cw6)3zlga|l~( z%Rj;CA#wNljusL(_=fq_3d2_}|DAH+Q5p<3uiE90H0_7OBf0sBEJT%Nwi!b=S$X(?+G0<_B2#BAQeb7hdZx^mfHYFFrz zbjxn{g^bdz8F4RqvN1ujhQJ;Gf8A71q6VlJ8-_d}1vT00hgMB9W68jy*i~Qc1i=ij z`VZCey_r>E(Y%SWI|*lmX=MD{QZ1Rb`7LmW*G&8RzLtn2*&>JA_$nPiJy$0jiY`@v zVF)%BrNxPS+Sc6j8Tbfkk6L$z7q_&NMGAq5S|&&vVMtC08khyp(brlf z|4IQ;7GO-nBHLNbub5gxGT_fQI^j1FuOnE}BkVj%ITDn*^Thjv_lYAQhHKk=Xi# zX2*I5T3TbLeNYOdlY$kj-MvQ_4I(Q!IP^nxpH3RH6`7>MIB-BNY<+h3s`k3AMlnXc z;{WyUR8Jd`Z*YS2%-6&(ewGk(F~nb;!JD(=9Wq^8&4@Z!q+BKiq3S8)AK>Z5A?WFq zEoN(U<^^E#S6sT`jJ`el!>RpTDKx!m{ijD^m_;VTMTQepK;geiX>K>{{uO5L!hVU_ z56iO>;6JpFOpF9tNqkE+$kap})ay~em|3tFeEBnKfFXNJMffUk6jov& z`^*TtZcHIsW`#}f_1K0_`z zMZuYT=X|gXym*1pZpL@wLIW`HxrFo`;8ymp-DHkC(6b+$PJ5A$8IU<{p61n^hwoks zehc3jv)d+X(v(+W7CeWr@%J*-RLNOUd*@(50R4&;tE#xpZ1DtEVfwMxH78PUCuj%U zF;A<})TaTI8rt2i<<+p!<+@d>u*^ncO0~(uLuBG2_KLWVpH?ifb%FP=bT$X&UQG-aYH#63Qr4fOVb9QSK-3ymo)G& z>Ro(z@a%{m_m}wrz`4jT)a)#Ct6Oy6d~3?OsFLuA*=2fcn+m%a#J5bnJhsR&GsKJ|{*x_a_vk_J zrroq-lHUx+nFgK^C@P4>t=Ul);a*+81&C@!=ph`0Wh?=9RZF_+%;t8jib+ljeN3Qn z>0bTfjbfGj=bHQ+uqXpp8{$=$lbe_?rH{=_GSA~8hPO4=Z(-q>Ls%+c_N=&2_W^+i zV*jJXxcA3aPpnO!@6^Z|5S=^$KoqJ&2C|)=GY;MENbNc5lVt~^Sx&y5gOl6e(`g`7)0nME z#U`rWXvI|5jgk!3_AMcLF_L0ervst~^#!$}0Ws3Oaj&Ue3Xa0%6<<_-_@+N_QoSjV zLHA7GX=@SRXk_iVYIq7{g2D{mYR5IK!5_rR9hnj)Co9!RM&4hhv({zI zd#Vn{95}xwvmnDsj|sE44ch_@Qzr17 zAau{s@(qZi^HaCGXa^ZqQ+J_9G9-rAc`o-c1$1zLNI(7LQZWky4zRf+MJP1QwXv&j z*i$pf?Y!aP_2e#aVB2?kh^f`>)jgSzP5%n29&#FMxn*{0^d26>;HOgd77z9722(o8 z*BLc9C_z+^zRP~?+-&lniYmr-#?8Nj^o>D^pV4JowOscMNWEOj` zDK@QPe^ef{TU8t(OaFS;eAKhmHBN_ffD(WEB2%KVbA5uTd8Pglwi#FI`37rx}?el!3COzJ63Qjb7a6;!YE z4S`4gX<<*@nc*4+Pk=xEHreBy>dM3GZJHbQ?kMz`MQqEvx zWGW#QWI@imsL<*p?N|7WIw*$Jw!7HiC)r(q_>4krvB!DQZ%8rq1uRh2C}-$8PMhcS zWRw6efi)Qboq%ZcM8&>pJPBlwqP6<`+<*&{Ab}%Nkh5e`mNwOfQU5Ovh+wra;;>6y zpVxWQN_F5GQ`iwMRy~5^E~OuCR;f01-17UXXDC)TlaNBvc~cLR`*fYlcwj8|M_k7c26g?2wLm6p7MpZV#x*TbTk(t}RlOtVk`!0147R0J z4_wyV2$=DfMHs-exQW8xvm?aLC|SHuxAQIqVB^wX8xmf-%F?>K(^3uNf-&CT(7ZGd zpQv`cX5NA|qu06IG##Jm?biEaNV2++wd$vCt1GE*6NyVKr(G;uE=-11KpXs8>f|>m z<{>cl3DkTiYlASQft0El4{3X>a5A>z1nv=Wr{TmSMqTJ27~4on>A$a(=Z>@?Q4oO_ zg2R0D-A{pLwm4iXoaHR`C_yx7&G7FA=Gsa6j70{;B66cUKeT}UJVRms{ zT@Ytltw^*#{D1tV3W#`9pIlpjKsyM#C8Y0gJ4WIq^c}<}Tc>{a2ge0;1hm4hJP@+> zv+Aq3ICO2SV1b4WuTqeK`{M-c1sqcN_M_J5kQoU!C<);HSlInwa-6g#Uf_PKht~-3 z()s%BeHTmeVCgW6BoJymExMa#nmBCv{ld?``+_IW=w250i9ANRjnB6~l?04EH4z5p z3wI@!0QEWyHsi$Q2+4gE^7Fb^t;oTj*Y@-;Ku*SJ%nHBxd2kDTl%((a9|&bCzPCwp zJx0rX<0>sSrX-xo7Uwp4M<9aVLx-lOYgV}z^_6;-p2EEqk~18zKKzb1^I?83HAi+2 zWb)m#S#r%tA5weP|qiY7Bhi?u5?xTy`=A)6>uie zuTMHcZOCjyoEX@v-^~1ebnJ#{1)WyDBv5Q=7F({+GD4-odAYbVvzL1KToLc9YCxwFP?6`1 zv#xhNRH@21afqo`_n94-wESkuF!^Kc2u2i&$m8(dnSLo^EE1xyLMg=9Y5G}knpoj^ zA`SzWiV=@LfUWi5aigAV;Jdg)vsIzy7(_oIWLmFu5lrL<5S0t>Z8g0#TBtY|*sAdt zImVp*9S6GY5B9l|RyrD5)V{|ZCNs|;am&}BR$>8J;mv|C%E$3wyOeGj@%UMo7Hcsn zL0DpBX8#U{ux-*h6y)A|Cy&J|G&!_I3;uh4c4zHo&+rSC`iuS{C9`cSUSMKF`q3&~ zKcUtm+|8czc%QS8ao-X0mZtc=j~@CH@u$e&Ej~OlL27{{FEkffd9A`BfzAZRke8_UzW1;weZ$}4#UjXQpK6!o zhH?13Il4{%Pdd0neaZ1eIh@xh{e4N|J)a~5rcT*F#%(X~u}kam^)AoqDK1?tHd$y$ z7XX!IL=IS!3j@bx;HhHg%teFDi(olxhrf>n%z&=4kNA#=1P%@oI2{m8_{wes>fsTQ zG+pF}BSRYy-(TZ)EG!0GfqC7Lr4aS}>K~VXi3|}2e;+bD39Wy-&9BbxHAov{{EETg zn|La3j0i>UnN&6$E9cY-WOW3r;>*&wfE||9kJEtwUA#n%`aFN|&*b@GGfHHVB3C-2 zi~Jp=+?O5lISR!WQjV-b{h52FAvchaWPlo(>NecH4DE5-ieb=_X6) zhNCs(4EX#f7TK?jOVoe=i-K=pe4kcWh-PE_cdl1H=j5@V#WH~Bc%({>rh61sQgtmA2EivI;lz%1HBP>$ z+39k}Qq$AUUu>_5xTtmAfP&5mZw1&Oe{@^tKVu6?dE?kLA=}6tP zmCgh0_P#G~L`8vt=qadFbrL$cv;+OUG!ocQMy%zT>%GiUgZ3*IZDVShK*y_W$xwx*o_C+?g$S9>16UM4 zg7V_ZznxMV+-fM5UUt(=ap1i+ihOg930k5G>}A%UxgZjWp!J|fy>Ot{?x_alt3Eyd zFbxu@Q;nQ^mS)Bk1(I7o^i<|2D|`$Cw-nL;oIBhe(}?+S(i{%N*zR$>ji(W0Y|0-! z%$xjClSYoBFsMUIE0d6(UjU40Wcq03i73B=p`_~eehKHpAa-l$GqcFG5}wFv;Oz}p zC7hZpl)GO{&c^|zY7p&Ti~-lqUT{Eis$Eic!hy|Yf}Oy*Wix3(D-s9|$~lbtmOZc< z(*(klzqPkU2MO-2biJ{k>r}po3ZT_shvP#1oB}_vMMx=(!-l|_-yr`htz;5jl|u{( zK$&iXUv)^xIN*UPd!4>svPT;L8lH`ivxC_G02%$tCM*;9eIh}N8;nKYdCvp_49BL z^)OrqLHfGTiJnDA2e2%}B{0Mti|Kp>&AC8;;0j)<(@!GEmAaRLkE)>a`lZJtFQ};J zaeTjBeC_b&wK|L%0SV83c#JZaah-8TG(7Az-WyV$J)0SMXN{l=+MskFgxL?-NC}bx zSMQtR?FVx{iNjjMiPQRWqFV5GkB9kr(CxZH&mG+Colh+Jp=827KkIPa6@o4)qt881 z^Rw+949c%*eKZR%JAc2_8=?1>}_*|Mpv z=JT3A8CKf9K%_L4*1(N>#kQGlTHUuHd`*Mi-PNorruI7@p&SCK1@%Pi9GmK`X8>Wn zz5a4qSYGaWg!n1(YYGa}adM}h9|;8*Y4cZT!U#X)a0!_k82(XXglkwlx@TD=U_ zfkrE1$FVZE9qqFr4H#ohq4uE6v30LhWi{;afU9m1V$Me9*UDWJv9Kl_yaL`T8RbdHqcjFb{HShAtV!+khB zlonTWt*?Ge2Nym2jJPa=n~@b9e&w9eP1E)iibVw#;K@@i-*CcsX3mpCG9zkmI>FxY z=9>zpvKZ8#d`oiei2e&IP7}nVh#1EXuN^e%ofV8jDIw|d>-#c7Ibi6B31~^Z)$D{m z{tu$=#vD({bd0SCI)MgYzM%xw`fbNINDOY|YI|tB{ceG)@n209| zJf*&!Vam(?9vzE+&w)=xAt7W*t!r@a!T|FWKc*#%?CRmf%C5ygL4-C`u#`!<$B^?# zsX(T=06BgmsNJ;x&2S-NKy4hA5 zg6A{+tLT!bpEE1UWW(sQ!aV*@kBVPfRCL^nrYx@RVSnv$SU|t>e1M_jYA1ppc$tCI zX@ibI`d?gP(Snbei+$IZB&mZAcp)<{hDR=gNvo+mZbxj|C^btjJ*1ostM!wFL zw6x?@wzEU0OqBhEr;I;5L)RNQq~vB}trs=fm6)^4hoxHSPvrMXMMD1aAqju$57wDh zCmJyt6-C0~YFdgsq5yKLXgnYEcgJq&3d4V@VRphIL~?$V9H0OXo@f@w|C~idOTP|$ zms20UmgW}vD%>bXyQE}7h|wp5$_l3Z9UmaOsv;TYTy-1=?ILEc8=}iZi;!}v;~sNU z{=BJ_1v%3&lT5k>SGwtAp*J2L5<5^0b}U*Y}a1eALQ@aC&u> z21>>hGjyt?3Xq$&Fe-u#<)#BNg=A_bt1h2`=21@e`0u*zm0^JmWzHx@+^$$0fKNOO zIAD%YS(?_I@bcXP)Rto8o*S&Tf~7Ui1MEob!@Qit8h+=wC^(u)m=D8p#U2PNb7nFK zgJDd;M$x&blc#||she|KRxehDQ7jN*m`)p>yIwhzChLkOd~IBjES>(Tpd470fs!tkrfRWbuSvAL5Q(y#6&ioR9)*($ieB%{A_<52 zb95d&7jcD>{fe|h9NebZHsdeVD;|E-$VYp&JGRTfATK?m1&yWV`ddEL%YXrT%^G{J z)OcF!4E;63fHHwW=?{>GKz-dNGtR zjmu>55dafrc>81&#p)u*N&9Tf+ZNN$g5xI)mL5^8*Gh}QZ}k)NmATEG4HV>i5M%*q zEO0BzXG_AahNsQm4ZNg85bG~+Mv5nn1SXy*Qe~Ma=JAB}O#AV}X~f`ijO~Nj5lP)_JTKtcduV%33+E;>pG3RBYh+%3x_noG%Q6=0 zxzC1|2wrUvnb!ECVjn!C5w1*3z|rpfM)e7+>OE%S_>_K)-YUodcJf&LLiFr0>$vWOoK^~B+ZQIxxcvF78rh)8FgePtu?L81mk3WCE_}rtJQC2tJ^frvIDkh94u_=#Wd)9vW(c}*+!GR|zhYJzin!ynQl%AWZsTxo zWLM^Ud!DXK$JiMMrv5%h3IK}$5Zo$drpU^+={FAxudn>@1FeKboEZVC!PFpKF66kO zPEG~<)#fNg_&x;q(hks*XF$fAGqn!A{=Xmuv|ATIB=3HsiEARf?d-FP%!PNG+?}Og z(%D8Ur6{5k-Dxh0|78E>EY565^!)9@#I!X*NIA}BOZ*#^=-~k z9rQ*OnJNB2U)7sR{DxpAj(;E5(NnXa?gYpX+2mDv+8=!my?4fN9JX8KE%?r9{+XEM zv46rGU7@c*64Bqk4Ufnoo|d3PJ`4jN&-6Z{{sjG(1XxyP`18w^AT;kVEkCN30` zxz|2qO2UA#iAhZP39 zA@&j1=><{8Wb&LqYSymMyaK|H1}H>*w>P6O&J}4b&o3sY$V%dEB{On@Hl#ZVEcKD7 zyuI+2Ixe&^w|3!FHDoCa&tX^!#BtegBhh+76MYosI#7qm^uraCbh{D#BK&?c#M=^10C-Gnjg|)? zOh@H|jy$mr(GIJu7-Cj2K?#A|0_{8U@zB3lvAM+kcb>bP(ufx7XGcwBZMJ3$9PgZ7W2V)hAmatZD-IgSnEwedFdgHFbNKn`d{8~Y*EC=ThDzeo48lVS53D%LX7gf_Tg!esG zvQ3h$?qpQ<3;=1)lBQX8+%h{lYc2a#4mIvvDXxcKTcI?=LW{GxWucj$yLR+uUewiz zjbG^aErZqp-*@tEM0o!N02=yK06Em=BUFb5O~*@2;jF)_PvWn>(hC|QMoORb^v}x` zq5iU7RZ=swYoTHEZP=OUN$;FFK~QxcoiSvuU7s^Ir_zt%^>1*%1d9)9wFkvPG6<`oT}eAck~C&yTsvu z>dhX{aFGVHvT7Yf-aJodJ}ep>N{>M0A9#(|1D6F^Ww3_A*=Q};nJ=;&%;ihKE7s$f z!pga2%FMaby|ergf!Hiec{8xksC3gEgvIUmm|QK#+_BpzjyjIV;JcLwF2uDQ!0LDg ztz(N(pGv)jLCf_|a0xxHF>j+B-O-)<3k8f`xQwK)?+t_cuEKU>t z{R!^mvn6BGiSl*o2D@~h69z459mhr7He}@$*MBT({y&%iR5$JCF}Y)l4Z6jEH4c5n zjGz0-^a_@AMGd$gYB%)zFpPInkg`3~`m9V%3762aTmiAoi4yfa-pUAiMmO>_rqPn`Wfz?m(IjVoG%MAjA; zZX8R|$`jF2E5(%Bv>J|Da`?GGZ@I4DRt%h5Q{h0q;5u&I`T>ZyV;%qiw8L7;N{RAK z#vw;?H39|+*rHI1eBKUXTrYdBk8BP&;VI(s__HM-Qhd`jbOlzv@dUbWSz^?&4>P!& z{EiC`7m|4D#WmyNTjyrkZ>_f24N}Y+80MuCGBENVFC3Y!@=Gcf_bAqc53{vo35mQT zg@zC?rT`$lIR%R{!zwl^HE^NIq7riO64D#$Pwk`|LbcIk7V4X?+ zxx<>Ix)-i%f^KP+Xb^2UxH7h}t(E<@O{pd$C|ik8u=+BtLrk=A(tOt{&*veX_SwRO z>9-;NdVl}M%j?Xv2Zz*WaKU(g3yy~)L0TMH_9PW4!uv(Vy|9*5!_H&_RObX9&_IE! z*vVtcl9%tTAuThZMVjNsM$=CGHu$Fvq0(j<-E&1paoSN1Jz0|!Y7dD$D*@V%I@h!H z?AIII_}lf!7|Ox6k8&TiJdo{QWM$m$q82oNA91~ek>rsZgfwwneuKZCAx{p68ipGB4mu~>$!)^9a%esei-FDLvJuXnUDZ=4;mH}rC5nRr!3kw^NpH(B2 zdN>sO5Nn`Lz{kHD6fj^O{2&X&OlZw6v4}g{{b?(PeO-i-*D-l%C;NV1bDsTH9%UIU zc=C|nu|OOK8O-C(;C;R2j0hxBqHp=8ywiRV4TNV?O_1&!uNxGu*8?2I?n98sNjP9i* zmXztfnd@G3=)H}W9c*G2zjt;E=xv;jrCRFH7NuP3pwN%ah_QcSB( zT#o&%w_+yZj=F1AY(7f*>XpxkPA2~KKsrwVXTyd0eTX(s0^L`()umAm88cBdh_pJ# zhV#5O-__DzIi^hDoSz2N%!ip7ERW?{s@nP~(uq$rz%tBQ<5RcYY;(nzXCYj)K9M_` z+lXbB#ov?NY05P^#eAX6232-IUJgUIiK0kDmGBLY$iJn&#>-}B@c0N1-yA+A-jE91 z#HX~H<8_4RZA(QB$8K+Q+ZAN}_LO*0)gS84j@lT1;B4NgBK2JdoN0=M;e4ArmZSUP zej+31PlgIe>8*c|9Qdl6t#x<0O{7xyGd#0;6Mz`70@6!(j~WqfPqG+;yzA=*L>VKr z7j3zKx-SWI*Q@ZgD)$r<`IY05AMk5K4$Epf4?87$vXC~48yOt_czART9zk1lMa>R9 zY{&v$+RxQH4(CDC^xelwE;WfhsU^lK$=$}sQm7ph&?XD z7)Ep>*!SQ)3}(OFpp8gSNn+h~x{kO+iCweESalbka6)s4+Y-Q|w!oB8tq1(rJ6JY{ zZmEF8d?ajYWckd3FP`7Qg+sL?+V<8xAskw=XbKfZP``S3cr_&J!op6P^Ccb zZ(bUFVfBk~j|aIB$)&DRX?KGeSs+!>;pto7@TB?3V4v<{93}C{5-jYs`}9CUUzRBj zIeds}>r3elH3a1MZ9DYptp}F0-x!v zbEZ9lE*u;`PR5wlO~^wkdpaiY>{RH?8^mbuLAHk`5P2J z%uSv}%IOCo6q&}ITEM-9U=W|i(nx!w&z%;tVFsY#PYazJYS=5jvcx^KE==G7(&2oh zC-y-sye>(5Y6r-;=3Ea>-@AgsiajrZwaMVKaQ^>0D+FrQOl`HO9*R=d>U3D_+Om>V zFP@YY()98vIPLkxxNDy=PX;YHY<^X$s7m8~eB#79)-H&R3y|cSm1k_QYSU*Zw&3K`f;IMLz|utg}?Hk6vkdc^CgU3r3jork;JwRw_!MrslwphK_Ly{+mTtCCJ^gH zUCWHINWUsCYHWe1C|0<55d&1??rxvlab6QrOZzS#dO5(Bu!8)SknMOFVm%{hGfas~ z0pfaLz`=2Pe@~r6YkCyleM?L4+s%*tS+OiZF$23Dj1gNSyBX&~($KuR)O!3xgNo@wQ}BcW^--HhaH zU9p^f>h^>=?INeZvfZ1}*W|8nq_tXcRphR%=G~^i=t2V{Rig#n=0@ICjAm9mM4#3E z+Gldd)^j7mB3}>m0FvPhITbFvgeU`E8Xm~Gr!gTL)bYe?nBFU^<85b^EYyFpBGO9j zDEQ}bIm0#0M;oTixNE^2RDr%3_eQO^3t;_6O%OsJJ*K{4N^q&gKk#ZtNh!zLV|#(7 zl{MnGpGIkU3Z4id6`oxv!(Z0*Zh%KBrnS#0o!*ZeHbL1>xver}Z1^IJ!BU`~5zr0c zEw2izH-Zi;?ihc8e(mKnK7$&!m(hkVLUf9eC7U+MiMlL=EL1I6n=UQlr)K?_*!}3n zQ^w)>dAJa=058-TyTZc92UyNMj{^Do1}5O)O{5I}nr-}g5_AF z@M*vy$=PicQ9PK4K?&U;6V9J^yCAEOu;Tyh=S>cj@*+acwk|~tKBOt=#NA5euX1O# zHmYDb|1+c}l!6}mt8qispAttX%BO&R!WG{4QpyNS#qmi-pW?{{o&wli^Nj3+)yK4& z5?kuh!y|#NVInucP3o1hJH2itq3|2AiNA|nZ|#P+yvdvkhidFpvijZaL7L=TtEi0!p6A&Y`kJ@9Y))~i zi?qc`YKiFKLXqJfqUGJZt$stbX_j1>6?rdND|Hsuw-PC}!C$Ydf8ihJU#e;Nmz7U?+WskWX=DeHu)CUw< zIA-Tc2<9pXDG;aX-FC%Y3@k}8pIdC^jn5+QY!J|fg^|=(S3W^=XT&h_@-KewFC}nf3+|vHInSsklk!JlOwQEr=J~kG zcO^%6r_~uFy88Kvd85T>rYh(m-W|qZLbA|#iuGtltyAW?H)OrRhYY4o@qe!@P~8h^ zq#$oraP-E3|MXC~XfZDFtsPnoKmd9w!gqvNaUd)I^u8bdMwpF}*3o{oPC3AAx^Uw~ zH>4HiH>AL!dRMZApmcH7Bw+|*q-k>-Xh%PI;)Ll?e3iWk22Qb!bax_5^*6Cd+_eXfl~KMDX0`75>$yf%&bcvJwNb zA$>|?_pI85-eV;zh*JlS8f2L8UYvJN6)=?tp@4I8OFSqnC z+ke=CIl=m(pZmpV72Z$5%S(JY#S0UE&3^>3NKbzG3J}#N85AtmW0q@ihe;s9?2of% zjn=NjSUuqN#b%f3`@qOoF<0-jgYr7uRR||95N_@4oj4i4~M^j z!SUJ?xKGpU0G1JMd%dH8eQ6}l1fIq4a#9!N5F|oTAa2*D^1m1mkzFC#=dS8P6T03x zcdB+1lA+GE2!la0oMj`qleix75O9?EB#b!Q<@fC}DW<3fUcBrfFB{MLErvI4>I<%{ zV@MoNyFRBNfPFT6@B!DtP~CTEUqKVC6fv4ZrpNRsss*9uHI&8b6a1lLmRwG`2Ocd3 zl7bu{V{ zd-rQVh>2rnU>H6aDK)+{Jl*~CrU^R&AuGJ&}pX4venbQ z1)1^>bIFBUgq2(-xP_ZF^Q}6hkyD)gQ-Os~N(VfUY^L2M<%&eWrsBVhfWgm5$yHHC zUh{`M-u^;?Q)tT5xv-<038Au2)#`YLP8Cb?+}fs=3dU1!2b?INxk?OGoQ01S_wi%VCMKm$6h#Ax5u91PJR7{VVBJpeXY?D~fcjnr)dykV`qyB5qC zokn}@;?~i8)VInMa48eNAAF?4y`$O4`2+weCkIlo;JL61TW|1t=<^{gf^~lgHS6*I z^7Vz{ccA;a>%;@I*T&@0;`w>nUt^Cv=cg(4%H<&Qq&Dh`#}gFtFc@;YF;|L7|(Q zDr^<*B9oVrFY7M-jM5M%BIghv0)Bs7|GwVzJ1qAbPc0`%F4d>c!Gs!8_rcwd5%iew zrjQkJc0Bzlfc3BBr)-CrXtOW8OPHal>ZPa3cQFZpD5?8$iSvgqCX-==3Mx5WsoUY0DoisEKzPmMkkzL$W;=cA3M&X`?dS(%U zB@`puv2%3|Ng_nuoD>$IHE zgi0r;X;*m(Rx9+EXuq^fNF;l7ihp^y^q@e@B{R@0#Dg~gy*CpZ5touM1kr=7=O;Dl zsB9@bAF1Otq`)p$wleRk6R>dO`_f%2@$y0cLf>lTo{A|Bj?hRIeYB?b<$HWfZk%~y zNt9J#ZRJNH9O>3424SKzuIvIz+G9K|;4NU~Bf_T?V}76I!>41|SVPM|9xb8gFWJae)$`1$T@7Hz) znI%yZ-*-Z+TT1&23S#aUa&fF+95U~}620t^Rm3V*o}Fb~%~4B$m@C^ldL87uUaO75_WzwEQ$L!)SE~aP2N)3+uR^V8 zji5-%bUxSuZY@~&xsL=DhVrPWtyU`V^9SZK)UsR_Uf2?1!6=}GDA0XBpE5a2nop3O zq#rb?7H6vEDOzDAJbMv-Rr^0VXv^85x!&0hSbDPrVkis@LK3b#HFk1X5T1O5M~5?1 zY!Hf%&V0&oY@Lbj=?vQt-69hBul#Pl3hd~xmJK@IMvnY7lb_`bu3K?eFO6y&-a~r?=w{So1rjT*^hE*HYw$&+wZuXwoiA5G97h`F39U%0_ zG!bCtDyG*+Y6Jy@LqenHmG_fo1YcQP5}R`rh%je==FqBiJyD4$ICD9&K`s-PxW33^ zKo|y}yad=*V5^Qli?oGw_=3b*qZncu!~9;NSZgLw2U+ttonz7VRnBr|(WN`nRP~Lv zRs=ipQN-$nE*8@rf#9JCc~~Z^Dmjki(I*U|ANTD2jU($#L+Se`bT?)mhSCC!qx5;} zA#j@iU=Y0$Hd`4^U0_=hqQJ4r~ACt0ysbHgK{l{A9C4>o0|hs*AF{I^!mc3{&i zt@(=+V8_R98$o`8;=s*JMDlNlJ$)TZnvg}q}4up6UOE4Kij1dbeDPF zHp0F>H+?pxMLS_|DW38itD1LcUfZqT!~NTdZkclpKhn}i5WL_o<;8)IaLlJ$c7k5? zo$HIX%&SZ9 zPb#1>?<5L-r_-R1zAgc<*8Hkbf2^%@cH?YV2k6RrHn@KD7YJ zoT4bQImj(Wv|fWhR!3$JJ`oRmm%@3TRQ-hiO&8keOBcT4q~rH`b}*kmW|2oMiGOgN z+C0?LB8bncS*|TFa~}6ieol#!y98U2O;#k{R7!$g$YtHoIUL4$2iLHkc`V; zD020r1S1!2S!A7-v>uh(ZS9_vRH2N1zu=BY?KNl%?<-gYl6Q`!wi-l&Cw~JsMd;}W z7z;o*dCmAR2HrE`4HCpi0sbQa++Xc`82|s+IIf)!E{*uXp@25(E+Epk} zIn>X;uyKsr(WY&d1HH`L zp7HS791k}iQ&yx)3eS?ctavMm88p0Zf@tmF9xttDQ6+&p#Oj%eSg1wu*2lCj!(MZQgMU*8|HYwT_xuIYw(+h$}lA! zDF45(S7pmEE-}sp8&kylknZyO!T&E(J4OC`oCPg!(!47vY=|BfQf3yPa<+FcR~IxW zA@a`F0pMgNbXZH63pJEQ{^3$*H=z(+7v6$?6>pW2)*6*F_9`jnn65z{bA|$Z-kiS! zZ6!1yN8?8V*t2yj5W)~WCRXUC@|68s2qLbiT;YzzdD64Sx5npTkw$s^w0My1h1xEC zKA-Vbpoa!w1HX*Y0w-ay-cmJ8{C`Cog^!{>lTxSu$jhc7I#e?>V3y+GJVc;GqM^O6 zXH&7e5cfC)VjIyr$w%|R0000000;9sfF2ee`QRc8ZDb1Apb`tE(tePPUYhC?4!wH0 z3dnSAXH;dOIy1r&+^5kmwE>w2?zV z0Sa_@(v6-;)`Cuh*&mr6DcUq?NQOH*h(d7SnmDC*5QF)lF7L!SX{VP;^UQ!7s~^@9 zFjw!lwA|16ZEIyh|JHWzNDTi0xN#tyh;9)&ft{ng>-XRe$Z9+%_NzQtRj-;px-K&nxGa1 zi`>|EDa6Oec7G`q(k8U@CQE@oyFXQnR7S|DoswQWf2HVe(6-B~15JSUTUS|9uzDko z8k_PJ4+G99kIK^G0CRf&61^s5R|?=Mx4M{fx+tfJq>O?p`+5_T*8zd~Zitb4#Ki^p zpQ5`scLQD)f-iB-b6cmbP4itk9c4I+)t8h_`m0ZdX{;X-_G^uDNqm{v1RnE%98Au%HJA_w*?uw0*z|8G}Vg6SKL%vDH0=7Br#I~Pxp5iPz;XyO@c03GL zxJExXD8PSkUBGW$V)OjEK@5iU+36q`UAM-@^! zCj+%jH=57@>37Ee{b=I~G($V&34?(*dik zWQ>|l0A_1OoH>oi;Z zmfY4ynxy;UnTXGXE_gqn-OP^&eDcdpG51?Ge)!?wLe&LCJ8J@hSb5CV|f;Y3MG7hi|bV+=H1K@cvrovK8PWf2^@uO)76dA-m!!;AoS zm>FXba3f(@ICU=CL;Xm8cyQNa4KR!fQ)cI+v7$ViCAhMO@cg?FEcdMjeWUvt`to7u zf*3rXlfpNC?JX6nIEY#x!+C&k4 zc7<5apY&f;l-|`<>f6^GZ`1jd=X-OtMYE2!Qj4B`#gQ9mc6qV$WySEn_+AK?XamGj zjf5#I9BYJ<94xX<#E6KSiWDvvBHY*b2ye|wb%QEotXMR75Ey%%7Ms;<>N%OUIrfQj zl)+3=q)3q1%aeV_TBvyI!S`bAY(eco3u`v+(n+2o!+HJdvv*H zL$vqf_d$SC{U5*=Ot5intkp4mKSVnGxMa+tw9271JBlDxGMT2p0_NXZY5oPIUPNuO z`VC<=!|-sdJ#YLUcuye%j$;(pl{_u2fC^xQrJl5FIg|pW*OTvG6oiZ?Go-Id3~VyU zmlbXoDYJ}8`5ja)#|8DOMX4ApXquz@68d% z)hP6BnWdi6RDI@pEIPcR!M|6Wdf*J{xDg&ZO=cDUz$J02wzFZXj=Dh$9*eAAI31wwLxrbP1XsxbAY$@2h`;VWne zUG^BQ@M95EvB#yCRw~(X_k^ob$gBV*@x_MGhW8%hYeV$%fh+3#BwwPdTw3d2<5WT( zpJVjaK*;on)6>Ws3JyKDo^v$+x+1EH7wDZX+@Rg1>B6RGEInPy^**~M*K_Ew2{5yYH?}t z*F90N6~HE?-#XMnl|wFq)$sGpzD6%|Xr|>7m`U-~@$akqPdo=XaLwRbj5ky?gDboz zgkq!Wj3+3ThS|L3+SEUoqh!(B2Ykrk z^Xt*cT3p8yaYq|wQ)BcAwHEIka|#3#75TpLc2Bb=b3sVjYJzyh{So=(BBR1mKzC24 zP&W*9(kj5iz10Vp`n^=TaY=Ov^dR_|RiN@5oVeGShyYs^lSPC1$Aoi#x!7JxQ{g*4 zhxfz0rGww2j>6C3yIKa8+G3>&Aq?4*%&kBlbz@KUT^b61;sF=g(avLTr=cBDe_zcDL~PcW7h0*-GCyCVD{;--dQL60`^AN;?v-mJo zHV58Mxw*cIH!`5_<7a$IXB0b{xAlr*^MSkZc6c`i3sG@9D~|LCyKuhCJ)fKFANhlc zz`(Vf?&3MxKQC4-lrb9&G)?hU(xQ$e@_2o(*8Q^RoIWcs2ryqxJHS)a@{a`(!m9rZ zY4&|>Xcwz)9L|Dt+rwQBS3nRxV8Sw%^`48@p8}aRW_6^)?=?m-4!&Gcy3nsZ0gC`c zV^IFgw(0}Py%S)kOQ#!EcZ5zm|A z_*SxqM3tDb07*K!@(P(z^lGC(Sxeiq8^X*I&5oihD00>vei#$w)-R{3g1_vkc+bHe z!vetsPipAlY-~{}q_7VmKd-Go!gxnJ7fezFc~q{7^hpJu;7(NeuXEq7a^Vc41F1EP zzEdYwjol0|Fc%QcrLhIluqNNW13vBAlsM3}uXzSW?4Xi*1%9f`h;CH!M^kPpG{UFs zL_NK-@OuJTl~*OOc8&$0^lSDus!nu)ichD*Wob#i`y}MYXm=oK;iKuv{i1q)jJbEs zn`f^D*!PLqoM$34kMoJr5WAbp9^Lv~HT91virW>mOr&Rv ziNp_L3yC;rRd0pnVxFRQ95pqZ8a(Ldb}{U>g?Tem7t7Kn%{R25^G1Tf`3If?LNW}x z#HUp6>+6D{+>8Bih^94Ho($Amxn3F9J}AV!1&_8i1}) z3vL-nLG>6t<#uFW)%k1zvN@peSX(AFaS*D$`TfxlNR^P*3F7y2dG|Qo?vmjb{Gg6 zkdEYXy!5GpE`uoJGy_q;cxgYGpMg0O!R!_GqY(nrVMtP+h!+U+_=u|q4h1;?CK&`v zAOAc|7-5fbVc*V-cO4=u%+`5=$irf%ge{e8Y4GsA#2)Osc03`>L=kGofU7wf zLPSZr9uQ6~sKgY>7-?-|0DGU2=Zum+g2FIAH$SO3Z@4IsU5M~9?qo3S%TbMyZl2OF zZU-DEIIN);eATrN5T2kFYtC)Mr)zczj=5XAzpzF`4lvNBvyIcCWH$l8UU+T6VPZ#mVUAkAm^!QF%AZ zk|Lqs^LmqPP&l^*6Z2wH!R=7|3j;~VOBo$uuC-0 z#cyfKEAA;9qs%IslU7j``Ch_<{tZU_ol6y{%AT9*l7NFdn&*mfo0se}_KsYvJqYff znJ&-!nUQ*`gOmgGwH9Bkj1&AZ!|*_sWzYvxV=wOFJs~q&?K7RG($8Qyj#V-WwzLkP zV7M(26jGyj1L5AkFv;2B;W#Uu5Yr-)FewfAal*@Vehq{Ehwr+jJk`bQ@o%3rx+90_ zJL{8mq)qt3#DN`Z-tdE+1iAc=xAoLb*9hW;VO4<(gO@BDAfs9kSL&OHhLuWZ*dt%8 z)F@Cpni=~Gmj7wHI;tv$jP58W0o*wodH#~WJtc%m1fn(MmZ%3oNQnvQX=OW2_iMC$ zSKhm5iXK{|ISg29BdH4uZYQro7~3ykBT(!)=t<`m5vx%H9C+p$w3rEgN!YQp9HWqs z0hsY}bClS50n7;6SX1!dRC@>bBIE((8YxlO86vIe?$$%0 ztcJr6j`?wiXObIh*mcDs#{7)=KItlF3x!z>HGhC3#+nNt*l%fZO~mp7x6DT;e^1J} zQ+{QUKa*G-o;ef?i=c$~q;q+p@$w>hSI=?lV52X-uNlOM7kF+lD!p8C@Lb162~l3)v-+U=Ewn560!{HXVp)fYD|qy_b^{q z(8GIJH`wigSkojl6`xuOM-XhysKBU>b2C3!MlRM+c6;nMO`BHvic0&lf7-lcl0Z8f9){|_0D7$X(xb^35rBBGuFl#P1Ru^8;zz}iMz2GahQ{?udL3Jr zpDwb&Nvj)5ZxV2}gk(_4@!Kxv7mu2@(3V7#-}Um#a{PMx^X#h-Oxw`afaf5pa->c5 zx60n$`1Gc(tC>b&mhhV})co%K1YoPg?Ghrw@Sm3_)>X>jg={3P`35{b!LybVQ{;2P z*vJTyf+g2b*Dbb4Sd#vRiCww&M}2vMDShR8B=SCczD= z8b(J%0az3iA%@%`2CI`*T>*Q-*HKxZQX=BiwfU1!4!27E!fo;2C2~MTAOJ5$ZY_t!iaiWa0fZjEu-J=;} z&{!cbS%_VDL8wHXF22tt%B`IV@NYUkzoI=v#~3SyH%?b+GX1m}qUC%NaFWRn=mj$4jK)HV8vDcK2`f z88W2NG1d{Kg#|`KslUI;-am;|BOe8wrqGadHq=Zdqb8CL1lErdtC-1z)qEwvksoP* z<+#db-F^b7VInzl=}M(&X@m>sIdz+y^#W}-|5ZmHiWLflkVZk|=#3s=hQl{2^WpEz zeYz!m>~uJHltOv%{4BENb7GAK6_5;uhUf)X)<7yS6JgOh8U*D1IbUe->8%oi+=*zK zVyk?Q=+%x19-nC$6HQK_t}yH9^p1vNP0W+ikerCz0?}_YGo1Oj!Sd(j+IGg!j*ph- zr^?5-1gx%Pn(Mv|?M2$aD0Mxl2-Ue56^+b(*vJ><58BGCet6Au__Y1;C3fC+TeI+d z*(eu501nv!SeGa^d5oqbEp#Z(gP#I<=bIJ!&-lh;$)Yp>VPbTA<&$_E8y^CtJXqJm z&E#nnD=7039fi(N?ws-;h(NZ zXS1^_sl4eh1me4Iy)acKf8JRno7yM)sB}7$HSK;f`krRlV3$qZWV5LYcQtJ?LxyNz zrjXI^vAauM`#9!OhE5+!gpCc5MV+7RqhaxLaiY9!ddM#$QSvNX;&ZJSOZ0K+@hP8i zB}vmna?*s`XR-$g)nP9nt0aXzVUfqiIqkPU&A+-!QldWKJYnA#l;d{%o7xj7u-JDb z1lJMGv<&5bV8i;0RM?s!Tnc0>A|N92#22U<&CSLM;lkg3lj2G?+B}M%A12+%gCk7b ziPge*lZs)!mscg=Vn$jFXNg1~y~uu;PQ$+$yQqP()4etFiR1C1STU0uJ+3@`sUTJ( z0PF)J`dAT6)7a!>B(w*(1oyG99x@gL1eUEh{AuPT)z4s^7T5y3wHU57ZJ8wu;$rat zFzB^ZHN*wx{E}uzUHvkDaZ~lYt6w9ojmxlW)`kG@uT!wy~+If6n%a(j6b#xptUqA|8g-Vqn0H-oOgs^73MH3Dw z%oNO5iphemc*-Dco{6czYt^GJpG+yjD)yf8N$pyb zqnsX7$hcdq$qV^7oY{iO+hY$!KTIB+yz4h>Zb=(EpP`l~9?2HJtk(G7Yn1*ocHd8c ziV?$O-MJ#0k%#-`%lnIv{ z&XvgtsUdcijL~4#x3#pI(S4Rjm&}C)^kz5#K>fXD$>Hx?l16F2(UYP+)2<&l=^KkK>}6VMvyj%*(b8$<>NjhX1HE7$ZE;0 zB6T3$eu6E$_cUF8ewuc*WJ!X{+bFR6H2(zz?1fOPi#pXKebDY}>amU3lOyNmg6n(O z(3J-DwsB{>V|5lgvpe^|_LK10jDO6yf~od?jMT;9DlaH z`#kV>lHal*Q;bC<3y)i~9YQ^tgJB`TT#wM~Imtl8&ztI?gCR-%3GnjIPmaK{m@PbYqUyPX_Lj|sG` z(LW?(Zf=`g6YZec@ogMqTMn=O?4NG7Axl=H%*V`Kj) zpqfwiA&(IbbkT5vRH85UxWfUt(jv zoqM~UQ`V-NHPt^ zt?qH|_b95x`W5Qv<{msi$qeHM7C>nLMcWmATi4%+&Z)aib3s|3>uNnxR*NykesW#- zO^%e#!P?jNV{Fc(IHTr!qClY66=b2<+wKr0f4LjMzx#QQ$1QfUOJebFCV(XEd3=b%7x7&$py= z`{IMkt9X^=CU`sb^tR9GP_>qw1{pb*{3NY*h`kPS(5KrS<3Y*eHpVm^K-C?cCN4x2 z{---W>tV#hmz>q;~sJFS`A zjEQ%WJ~G@0h>9010PAHI2c(M(q*9qu zR7grL?kw2U61(g*`-fe>>3)R}dCNr*$5mQbhH?ruWQ&Cwg6M*TCD%i*ovM2L#s5c1 zimHH4xvHKHjgO|@f-7R9--%Ph8Cn9wK?Ye|R04?T+E1=|SNw5)DPqN+5nz%^XKkr^ z;)x-f-|5F4k~lZ+Pnr;Wu5fre1OqFLm;r7DP2HCcr6>uZwhGltU*=fl?Z#TbFDPRU zQ-XU7G1A4$$qNIAR5&;sRlU+KUkzep6e|3$^P!yX_B{q1#j|Ulf-yI1FfJMDLt@M z)xBo-ku56oyDIt#IJB)kydWBCSg0E=s$eyuN?`~G1-l#N6c>qREO^>AMW7X0N}j{` zte|+(LY?Timh)| zz_K9+n_opGIxfjf$tQA1a2*EUB{pMuy6KbdCe_3A(LF2{EHD58VwN%7*9-Pgu@hk` zqs!)xImVm=d4hMj;R7~^gDg$6(-kg#IFBwie1@WF1Z0ej?u|V2&;eGG@%n=!tG-Ns zjkTw253wV0*Pa!1?IrKJTv9+R(0T30CI2J+0X)s@ic4%WyN?w&lf0Xep6+ueio&W7 zR-MO{iC|w+ z27VBFjGOP>yX6unhJ94`-flY@?8c%MSPv(l3uea%6t+VR3~B#pEfGxdl9AubiJ&~! z6wthP8+gH16{~nd1Zw<3ag!G+^=~CzI}N@jA-QTO5|AadYgUWc`a~K994vh;lt{>O zxhI~}g@N810%_(Fu&jrM8C8ycPLU_C`aC9E}M| z;tGjXWe`rgw0i9%3p1wohEJkL8!1^tL0WEGC@jO^0W`AZ9>l3K`8)`bYvET$BoXX^MNaYm7B~rmc zQ?=XjD|@(mZGS`*4ryvQ;F$Q3HBWMPp`g|c(^Cbb#AS8I3i2a;qy3Bq=k{592ZZ|m|NW?TY$a`_omgWa?@Ag)ps#%#3J=hRt8nO6 iCchPgbPxapa6kY6000000000000000000000002t)xe7Y literal 0 HcmV?d00001 diff --git a/boards/rakwireless/rak11160/doc/index.rst b/boards/rakwireless/rak11160/doc/index.rst new file mode 100644 index 000000000000..c53d259b9bb3 --- /dev/null +++ b/boards/rakwireless/rak11160/doc/index.rst @@ -0,0 +1,79 @@ +.. zephyr:board:: rak11160 + +Overview +******** + +RAK11160 is a WisDuo module based on the STM32WLE5 MCU with integrated LoRa +transceiver. It uses an Espressif ESP8684H2 co-processor to support Bluetooth +and WiFi connectivity. This module is ideal for various IoT applications such as +home automation, sensor networks, building automation, and other IoT network +applications. + +Hardware +******** + +The module has below hardware features: +- STM32WLE5CC MCU with LPWAN single-core Cortex®-M4 at 48 MHz +- 256-Kbyte Flash memory and 64-Kbyte SRAM +- RF transceiver LoRa® modulations +- Hardware encryption AES256-bit and a true random number generator +- SMA connectors for the LORA antenna and BLE/WiFi antenna +- 32-bit single core RISC-V ESP8684 MCU +- 2 MB in ESP8684 MCU flash +- ESP8684 MCU support 802.11b/g/n +- A Bluetooth LE subsystem that supports features of Bluetooth 5 and Bluetooth Mesh + +.. image:: img/rak11160.webp + :align: center + :alt: RAK11160-pinout + +For more information about the RAK3112 stamp module: + +- `WisDuo RAK11160 Website`_ +- `STM32WLE5CC on www.st.com`_ +- `ESP8684 on www.espressif.com`_ + +Supported Features +================== + +.. zephyr:board-supported-hw:: + +Building & Flashing +******************* + +.. zephyr:board-supported-runners:: + +Connect the board to your host computer and build and flash an application. +The sample application :zephyr:code-sample:`hello_world` is used for this example. +Build the Zephyr kernel and application, then flash it to the device: + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: rak11160 + :goals: build flash + +Run a serial terminal to connect with your board. By default, ``usart1`` is +accessible via the USB to TTL converter. + +- Speed: 115200 +- Data: 8 bits +- Parity: None +- Stop bits: 1 + +.. code-block:: console + + Hello World! rak11160/stm32wle5xx + +References +********** + +.. target-notes:: + +.. _WisDuo RAK11160 Website: + https://docs.rakwireless.com/product-categories/wisduo/rak11160-module/overview + +.. _STM32WLE5CC on www.st.com: + https://www.st.com/en/microcontrollers-microprocessors/stm32wle5cc.html + +.. _ESP8684 on www.espressif.com: + https://www.espressif.com/sites/default/files/documentation/esp8684_datasheet_en.pdf diff --git a/boards/rakwireless/rak11160/rak11160.dts b/boards/rakwireless/rak11160/rak11160.dts new file mode 100644 index 000000000000..bdb1c0ff2346 --- /dev/null +++ b/boards/rakwireless/rak11160/rak11160.dts @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2025 RAKwireless Technology Co., Ltd. + * Sercan Erat + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include + +/ { + model = "RAKWireless RAK11160 WisDuo LPWAN Module"; + compatible = "stm32,rak11160_stm32wl"; + + chosen { + zephyr,console = &usart1; + zephyr,shell-uart = &usart1; + zephyr,sram = &sram0; + zephyr,flash = &flash0; + zephyr,code-partition = &slot0_partition; + }; + + leds { + compatible = "gpio-leds"; + + blue_led: led_2 { + gpios = <&gpioa 1 GPIO_ACTIVE_HIGH>; + label = "Blue LED"; + }; + + green_led: led_1 { + gpios = <&gpioa 10 GPIO_ACTIVE_HIGH>; + label = "Green LED"; + }; + }; + + /* Regulator controlling ESP8684 enable */ + esp8684_enable: esp8684-enable { + compatible = "regulator-fixed"; + regulator-name = "esp8684_enable"; + enable-gpios = <&gpioa 0 GPIO_ACTIVE_HIGH>; + regulator-boot-off; + }; + + aliases { + led0 = &green_led; + lora0 = &lora; + watchdog0 = &iwdg; + }; +}; + +&pll { + div-m = <1>; + mul-n = <3>; + div-r = <2>; + div-q = <2>; + clocks = <&clk_hse>; + status = "okay"; +}; + +&rcc { + clocks = <&pll>; + clock-frequency = ; + cpu1-prescaler = <1>; + ahb3-prescaler = <1>; + apb1-prescaler = <1>; + apb2-prescaler = <1>; +}; + +&clk_hse { + status = "okay"; + clock-frequency = ; + hse-tcxo; +}; + +&clk_lse { + status = "okay"; + clock-frequency = <32768>; +}; + +&subghzspi { + status = "okay"; + + lora: radio@0 { + status = "okay"; + antenna-enable-gpios = <&gpiob 8 GPIO_ACTIVE_HIGH>; + tx-enable-gpios = <&gpioc 13 GPIO_ACTIVE_HIGH>; + rx-enable-gpios = <&gpioc 13 GPIO_ACTIVE_LOW>; + dio3-tcxo-voltage = ; + tcxo-power-startup-delay-ms = <5>; + power-amplifier-output = "rfo-hp"; + rfo-hp-max-power = <22>; + }; +}; + +&usart1 { + pinctrl-0 = <&usart1_tx_pb6 &usart1_rx_pb7>; + pinctrl-names = "default"; + current-speed = <115200>; + status = "okay"; + + espc2 { + compatible = "espressif,esp-at"; + status = "okay"; + }; +}; + +&usart2 { + pinctrl-0 = <&usart2_tx_pa2 &usart2_rx_pa3>; + pinctrl-names = "default"; + current-speed = <115200>; + status = "okay"; +}; + +&i2c2 { + pinctrl-0 = <&i2c2_scl_pa12 &i2c2_sda_pa11>; + pinctrl-names = "default"; + status = "okay"; + clock-frequency = ; +}; + +&spi1 { + pinctrl-0 = <&spi1_nss_pa4 &spi1_sck_pa5 + &spi1_miso_pa6 &spi1_mosi_pa7>; + pinctrl-names = "default"; + status = "okay"; +}; + +&rtc { + clocks = <&rcc STM32_CLOCK_BUS_APB1 0x00000400>, + <&rcc STM32_SRC_LSE RTC_SEL(1)>; + status = "okay"; +}; + +&iwdg { + status = "okay"; +}; + +&aes { + status = "okay"; +}; + +&rng { + status = "okay"; +}; + +&flash0 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 DT_SIZE_K(32)>; + read-only; + }; + + slot0_partition: partition@8000 { + label = "image-0"; + reg = <0x00008000 DT_SIZE_K(108)>; + }; + + slot1_partition: partition@23000 { + label = "image-1"; + reg = <0x00023000 DT_SIZE_K(108)>; + }; + + storage_partition: partition@3e000 { + label = "storage"; + reg = <0x0003e000 DT_SIZE_K(8)>; + }; + }; +}; diff --git a/boards/rakwireless/rak11160/rak11160.yaml b/boards/rakwireless/rak11160/rak11160.yaml new file mode 100644 index 000000000000..f7975116da64 --- /dev/null +++ b/boards/rakwireless/rak11160/rak11160.yaml @@ -0,0 +1,19 @@ +identifier: rak11160 +name: RAK11160 +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb +ram: 64 +flash: 256 +supported: + - counter + - gpio + - i2c + - nvs + - spi + - uart + - watchdog + - lora +vendor: rak diff --git a/boards/rakwireless/rak11160/rak11160_defconfig b/boards/rakwireless/rak11160/rak11160_defconfig new file mode 100644 index 000000000000..a5fbfda97edb --- /dev/null +++ b/boards/rakwireless/rak11160/rak11160_defconfig @@ -0,0 +1,21 @@ +# Enable UART driver +CONFIG_SERIAL=y + +# Enable GPIO +CONFIG_GPIO=y + +# Enable Clocks +CONFIG_CLOCK_CONTROL=y + +# Console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable HW stack protection +CONFIG_HW_STACK_PROTECTION=y + +# Regulator +CONFIG_REGULATOR=y From ab6c28fd9815e81d5488c8e165776dfc8af1526a Mon Sep 17 00:00:00 2001 From: Biwen Li Date: Wed, 24 Sep 2025 17:43:18 +0900 Subject: [PATCH 0124/3659] soc: nxp: imx943: set dma tcd queue size to fix build issues Set dma tcd queue size to 4 defaultly to fix build issues, - error: static assertion failed: NUM_DMA_BLOCKS_RX_PREP must be < CONFIG_DMA_TCD_QUEUE_SIZE #define BUILD_ASSERT(EXPR, MSG...) _Static_assert((EXPR),... drivers/i2s/i2s_mcux_sai.c:45: note: in expansion of macro BUILD_ASSERT BUILD_ASSERT(MAX_TX_DMA_BLOCKS > NUM_DMA_BLOCKS_RX_PREP, Signed-off-by: Biwen Li --- soc/nxp/imx/imx9/imx943/Kconfig.defconfig.mimx94398.m33 | 3 +++ soc/nxp/imx/imx9/imx943/Kconfig.defconfig.mimx94398.m7_0 | 3 +++ soc/nxp/imx/imx9/imx943/Kconfig.defconfig.mimx94398.m7_1 | 3 +++ 3 files changed, 9 insertions(+) diff --git a/soc/nxp/imx/imx9/imx943/Kconfig.defconfig.mimx94398.m33 b/soc/nxp/imx/imx9/imx943/Kconfig.defconfig.mimx94398.m33 index b285db76ac7f..1af8f5705a21 100644 --- a/soc/nxp/imx/imx9/imx943/Kconfig.defconfig.mimx94398.m33 +++ b/soc/nxp/imx/imx9/imx943/Kconfig.defconfig.mimx94398.m33 @@ -47,4 +47,7 @@ configdefault SYS_CLOCK_TICKS_PER_SEC endif +configdefault DMA_TCD_QUEUE_SIZE + default 4 + endif # SOC_MIMX94398_M33 diff --git a/soc/nxp/imx/imx9/imx943/Kconfig.defconfig.mimx94398.m7_0 b/soc/nxp/imx/imx9/imx943/Kconfig.defconfig.mimx94398.m7_0 index 05f450adcf39..b476d69dcbaf 100644 --- a/soc/nxp/imx/imx9/imx943/Kconfig.defconfig.mimx94398.m7_0 +++ b/soc/nxp/imx/imx9/imx943/Kconfig.defconfig.mimx94398.m7_0 @@ -49,4 +49,7 @@ configdefault SYS_CLOCK_TICKS_PER_SEC endif +configdefault DMA_TCD_QUEUE_SIZE + default 4 + endif # SOC_MIMX94398_M7_0 diff --git a/soc/nxp/imx/imx9/imx943/Kconfig.defconfig.mimx94398.m7_1 b/soc/nxp/imx/imx9/imx943/Kconfig.defconfig.mimx94398.m7_1 index 6c7f9717711b..84a726d4ecd7 100644 --- a/soc/nxp/imx/imx9/imx943/Kconfig.defconfig.mimx94398.m7_1 +++ b/soc/nxp/imx/imx9/imx943/Kconfig.defconfig.mimx94398.m7_1 @@ -49,4 +49,7 @@ configdefault SYS_CLOCK_TICKS_PER_SEC endif +configdefault DMA_TCD_QUEUE_SIZE + default 4 + endif # SOC_MIMX94398_M7_1 From 82ed28fea6a9a10c5e9140c6c4eeaaa8191f7709 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Pelikan?= Date: Thu, 4 Dec 2025 16:05:55 +0100 Subject: [PATCH 0125/3659] manifest: Update hal_nordic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Manifest to update latest changes. Signed-off-by: Paweł Pelikan --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 48e1d5834fc4..b30ee495cb1f 100644 --- a/west.yml +++ b/west.yml @@ -200,7 +200,7 @@ manifest: groups: - hal - name: hal_nordic - revision: 0dbbf4794156ca09dc2d4bad8c42dcdb54acd662 + revision: 757314f07fbf2fb0f0257d7cfa147ca03f9d8398 path: modules/hal/nordic groups: - hal From e4f518b56a4d3a24e1abfd1657bbdf24b78c94e9 Mon Sep 17 00:00:00 2001 From: Tim Lin Date: Mon, 8 Dec 2025 13:31:56 +0800 Subject: [PATCH 0126/3659] drivers/i2c: it8xxx2: Add port info to error logs Improve I2C error logs by adding port number to all timeout and host error messages, making it easier to identify which controller reports failures. Signed-off-by: Tim Lin --- drivers/i2c/i2c_ite_it8xxx2.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/i2c/i2c_ite_it8xxx2.c b/drivers/i2c/i2c_ite_it8xxx2.c index 58cf13906918..3e8df3dddc05 100644 --- a/drivers/i2c/i2c_ite_it8xxx2.c +++ b/drivers/i2c/i2c_ite_it8xxx2.c @@ -144,20 +144,22 @@ static int i2c_parsing_return_value(const struct device *dev) LOG_ERR("I2C ch%d Address:0x%X Transaction time out.", config->port, data->addr_16bit); } else { - LOG_DBG("I2C ch%d Address:0x%X Host error bits message:", - config->port, data->addr_16bit); /* Host error bits message*/ if (data->err & HOSTA_TMOE) { - LOG_ERR("Time-out error: hardware time-out error."); + LOG_ERR("I2C ch%d Address:0x%X Time-out error: hardware time-out error.", + config->port, data->addr_16bit); } if (data->err & HOSTA_NACK) { - LOG_DBG("NACK error: device does not response ACK."); + LOG_DBG("I2C ch%d Address:0x%X NACK error: device does not response ACK.", + config->port, data->addr_16bit); } if (data->err & HOSTA_FAIL) { - LOG_ERR("Fail: a processing transmission is killed."); + LOG_ERR("I2C ch%d Address:0x%X Fail: a processing transmission is killed.", + config->port, data->addr_16bit); } if (data->err & HOSTA_BSER) { - LOG_ERR("BUS error: SMBus has lost arbitration."); + LOG_ERR("I2C ch%d Address:0x%X BUS error: SMBus has lost arbitration.", + config->port, data->addr_16bit); } } From 33f50ee90eb1e172afd85cf4f55883cde8901023 Mon Sep 17 00:00:00 2001 From: Tim Pambor Date: Mon, 8 Dec 2025 09:40:03 +0100 Subject: [PATCH 0127/3659] drivers: clock_control: stm32: enable fractional divider for PLL2/3 Configure the fractional divider (FRACN) for PLL2 and PLL3 on STM32H5 series when specified in the device tree. Signed-off-by: Tim Pambor --- drivers/clock_control/clock_stm32_ll_h5.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/clock_control/clock_stm32_ll_h5.c b/drivers/clock_control/clock_stm32_ll_h5.c index 466305b4e690..80a165e2ea09 100644 --- a/drivers/clock_control/clock_stm32_ll_h5.c +++ b/drivers/clock_control/clock_stm32_ll_h5.c @@ -612,6 +612,10 @@ static int set_up_plls(void) LL_RCC_PLL2_SetN(STM32_PLL2_N_MULTIPLIER); LL_RCC_PLL2FRACN_Disable(); + if (IS_ENABLED(STM32_PLL2_FRACN_ENABLED)) { + LL_RCC_PLL2_SetFRACN(STM32_PLL2_FRACN_VALUE); + LL_RCC_PLL2FRACN_Enable(); + } if (IS_ENABLED(STM32_PLL2_P_ENABLED)) { LL_RCC_PLL2_SetP(STM32_PLL2_P_DIVISOR); @@ -671,6 +675,10 @@ static int set_up_plls(void) LL_RCC_PLL3_SetN(STM32_PLL3_N_MULTIPLIER); LL_RCC_PLL3FRACN_Disable(); + if (IS_ENABLED(STM32_PLL3_FRACN_ENABLED)) { + LL_RCC_PLL3_SetFRACN(STM32_PLL3_FRACN_VALUE); + LL_RCC_PLL3FRACN_Enable(); + } if (IS_ENABLED(STM32_PLL3_P_ENABLED)) { LL_RCC_PLL3_SetP(STM32_PLL3_P_DIVISOR); From e260a69c612d6d13799a0cdec4d88e0ddc538fae Mon Sep 17 00:00:00 2001 From: Stephen Stauts Date: Mon, 8 Dec 2025 10:07:34 +0100 Subject: [PATCH 0128/3659] samples: boards: nordic: Update command for checking ironside Uses the modern nrfutil command for checking ironside versions through the boot report, rather than hardcoded addressing. Signed-off-by: Stephen Stauts --- samples/boards/nordic/nrf_ironside/update/README.rst | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/samples/boards/nordic/nrf_ironside/update/README.rst b/samples/boards/nordic/nrf_ironside/update/README.rst index 484d97d0adda..b76d30583dd5 100644 --- a/samples/boards/nordic/nrf_ironside/update/README.rst +++ b/samples/boards/nordic/nrf_ironside/update/README.rst @@ -60,15 +60,12 @@ Building and running the application for nrf54h20dk/nrf54h20/cpuapp #. Trigger a reset: -.. code-block:: console + .. code-block:: console - nrfutil device reset --reset-kind RESET_PIN --traits jlink + nrfutil device reset --reset-kind RESET_PIN --traits jlink -#. Check that the new version is installed: +#. Check the boot report to verify that the new versions have been installed: .. code-block:: console - # Read the version fields from the boot report - nrfutil x-read --direct --address 0x2f88fd04 --bytes 16 --traits jlink - # Read the update status in the boot report - nrfutil x-read --direct --address 0x2f88fd24 --bytes 4 --traits jlink + nrfutil device x-ironside-boot-report-read --traits jlink From fd38fde6c25ab4feea8c3f76d2d4034dc588a9fe Mon Sep 17 00:00:00 2001 From: Pavel Vasilyev Date: Mon, 8 Dec 2025 10:33:02 +0100 Subject: [PATCH 0129/3659] doc: bluetooth: mesh: Update supported Bluetooth Mesh Protocol version Update Bluetooth Mesh Protocol supported version to 1.1.1. Signed-off-by: Pavel Vasilyev --- doc/connectivity/bluetooth/api/mesh.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/connectivity/bluetooth/api/mesh.rst b/doc/connectivity/bluetooth/api/mesh.rst index 404e86018c7a..45b3563fc758 100644 --- a/doc/connectivity/bluetooth/api/mesh.rst +++ b/doc/connectivity/bluetooth/api/mesh.rst @@ -5,7 +5,7 @@ Bluetooth Mesh Profile The Bluetooth Mesh profile adds secure wireless multi-hop communication for Bluetooth Low Energy. This module implements the -`Bluetooth Mesh Protocol Specification v1.1 `_. +`Bluetooth Mesh Protocol Specification v1.1.1 `_. Read more about Bluetooth Mesh on the `Bluetooth SIG Website `_. From 79356f1385ff24ae3f9b6e4b94d19bee93aef781 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Wed, 10 Dec 2025 07:04:41 -0500 Subject: [PATCH 0130/3659] ci: assigner: only run on main branch See if this fixes the issue where this workflow runs on released branches. Signed-off-by: Anas Nashif --- .github/workflows/assigner.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/assigner.yml b/.github/workflows/assigner.yml index e83f2422869d..9ae1c2e3b9cc 100644 --- a/.github/workflows/assigner.yml +++ b/.github/workflows/assigner.yml @@ -9,8 +9,6 @@ on: - ready_for_review branches: - main - - collab-* - - v*-branch issues: types: - labeled From 7830a76b7f7e8774b32d16dde8324f171db5cac5 Mon Sep 17 00:00:00 2001 From: Camille BAUD Date: Wed, 10 Dec 2025 11:13:25 +0100 Subject: [PATCH 0131/3659] dts: bflb: Add flash-controller chosen Adds flash controller chosen to make CI happy Signed-off-by: Camille BAUD --- dts/riscv/bflb/bl60x.dtsi | 4 ++++ dts/riscv/bflb/bl61x.dtsi | 4 ++++ dts/riscv/bflb/bl70x.dtsi | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/dts/riscv/bflb/bl60x.dtsi b/dts/riscv/bflb/bl60x.dtsi index d77398c2fc06..521f34bf5fca 100644 --- a/dts/riscv/bflb/bl60x.dtsi +++ b/dts/riscv/bflb/bl60x.dtsi @@ -57,6 +57,10 @@ }; }; + chosen { + zephyr,flash-controller = &flashctrl; + }; + cpus { #address-cells = <1>; #size-cells = <0>; diff --git a/dts/riscv/bflb/bl61x.dtsi b/dts/riscv/bflb/bl61x.dtsi index afbcbf01e32a..beacbfec2b00 100644 --- a/dts/riscv/bflb/bl61x.dtsi +++ b/dts/riscv/bflb/bl61x.dtsi @@ -71,6 +71,10 @@ }; }; + chosen { + zephyr,flash-controller = &flashctrl; + }; + cpus { #address-cells = <1>; #size-cells = <0>; diff --git a/dts/riscv/bflb/bl70x.dtsi b/dts/riscv/bflb/bl70x.dtsi index 427d9af9a092..568ed3ff9c3d 100644 --- a/dts/riscv/bflb/bl70x.dtsi +++ b/dts/riscv/bflb/bl70x.dtsi @@ -56,6 +56,10 @@ }; }; + chosen { + zephyr,flash-controller = &flashctrl; + }; + cpus { #address-cells = <1>; #size-cells = <0>; From f7786bba5fc16bdc9074cb1b965cbcd8ec06bb0e Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Mon, 8 Dec 2025 12:33:41 +0100 Subject: [PATCH 0132/3659] tests: drivers: can: api: relax CAN sample point accuracy requirements Relax the CAN sample point location accuracy requirements in the CAN API test suites by taking CONFIG_CAN_SAMPLE_POINT_MARGIN into account. Fixes: #100615 Signed-off-by: Henrik Brix Andersen --- tests/drivers/can/api/src/canfd.c | 3 ++- tests/drivers/can/api/src/classic.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/drivers/can/api/src/canfd.c b/tests/drivers/can/api/src/canfd.c index 0056a3b0b15a..c2ad3c1f0b35 100644 --- a/tests/drivers/can/api/src/canfd.c +++ b/tests/drivers/can/api/src/canfd.c @@ -528,7 +528,8 @@ ZTEST_USER(canfd, test_set_timing_data_while_started) int err; err = can_calc_timing_data(can_dev, &timing, TEST_BITRATE_3, TEST_SAMPLE_POINT); - zassert_ok(err, "failed to calculate data timing (err %d)", err); + zassert_true(err >= 0, "failed to calculate data timing (err %d)", err); + zassert_true(err <= CONFIG_CAN_SAMPLE_POINT_MARGIN, "sample point error %d too large", err); err = can_set_timing_data(can_dev, &timing); zassert_not_equal(err, 0, "changed data timing while started"); diff --git a/tests/drivers/can/api/src/classic.c b/tests/drivers/can/api/src/classic.c index d6a7d78444eb..674409634054 100644 --- a/tests/drivers/can/api/src/classic.c +++ b/tests/drivers/can/api/src/classic.c @@ -1393,7 +1393,8 @@ ZTEST_USER(can_classic, test_set_timing_while_started) int err; err = can_calc_timing(can_dev, &timing, TEST_BITRATE_1, TEST_SAMPLE_POINT); - zassert_ok(err, "failed to calculate timing (err %d)", err); + zassert_true(err >= 0, "failed to calculate timing (err %d)", err); + zassert_true(err <= CONFIG_CAN_SAMPLE_POINT_MARGIN, "sample point error %d too large", err); err = can_set_timing(can_dev, &timing); zassert_not_equal(err, 0, "changed timing while started"); From 573f4805c9ff2a09abef404ccaf85cf68083132c Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Mon, 8 Dec 2025 12:37:44 +0100 Subject: [PATCH 0133/3659] tests: drivers: can: api: canfd: use 75% for the data phase sample point Use a sample point of 75% for the data phase timing to match the bitrate of 1Mbit/s. Fixes: #100615 Signed-off-by: Henrik Brix Andersen --- tests/drivers/can/api/src/canfd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/drivers/can/api/src/canfd.c b/tests/drivers/can/api/src/canfd.c index c2ad3c1f0b35..68ce34447951 100644 --- a/tests/drivers/can/api/src/canfd.c +++ b/tests/drivers/can/api/src/canfd.c @@ -527,7 +527,7 @@ ZTEST_USER(canfd, test_set_timing_data_while_started) struct can_timing timing = { 0 }; int err; - err = can_calc_timing_data(can_dev, &timing, TEST_BITRATE_3, TEST_SAMPLE_POINT); + err = can_calc_timing_data(can_dev, &timing, TEST_BITRATE_3, TEST_SAMPLE_POINT_2); zassert_true(err >= 0, "failed to calculate data timing (err %d)", err); zassert_true(err <= CONFIG_CAN_SAMPLE_POINT_MARGIN, "sample point error %d too large", err); From d9cc7845ecd7e9acc428ac781202bd53e1540952 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Mon, 8 Dec 2025 12:33:26 +0100 Subject: [PATCH 0134/3659] samples: net: lwm2m_client: Add missing PSA configs neeed for HS Add missing PSA configs required for successful DTLS handshake with PSK. Cert-based config also needed to enable some RSA support, as otherwise mbed TLS throws errors about some undefined RSA error mapping. Signed-off-by: Robert Lubos --- samples/net/lwm2m_client/overlay-dtls-cert.conf | 5 +++++ samples/net/lwm2m_client/overlay-dtls.conf | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/samples/net/lwm2m_client/overlay-dtls-cert.conf b/samples/net/lwm2m_client/overlay-dtls-cert.conf index fe37cc0307eb..9cfbd945871e 100644 --- a/samples/net/lwm2m_client/overlay-dtls-cert.conf +++ b/samples/net/lwm2m_client/overlay-dtls-cert.conf @@ -18,10 +18,12 @@ CONFIG_MBEDTLS_CIPHER_GCM_ENABLED=y # Disable RSA, use only ECC certificates CONFIG_MBEDTLS_KEY_EXCHANGE_RSA_ENABLED=n +CONFIG_PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE=y # To avoid mbed TLS build error # Enable PSK and ECDHE_ECDSA CONFIG_MBEDTLS_KEY_EXCHANGE_PSK_ENABLED=y CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED=y # We only need prime256v1 curve +CONFIG_PSA_CRYPTO=y CONFIG_PSA_WANT_ECC_SECP_R1_256=y CONFIG_PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT=y CONFIG_PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT=y @@ -29,6 +31,9 @@ CONFIG_PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE=y CONFIG_PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE=y CONFIG_PSA_WANT_ALG_ECDH=y CONFIG_PSA_WANT_ALG_ECDSA=y +CONFIG_PSA_WANT_ALG_SHA_256=y +CONFIG_PSA_WANT_ALG_TLS12_PRF=y +CONFIG_PSA_WANT_ALG_TLS12_PSK_TO_MS=y # Optional: we could use just binary DER certificates CONFIG_MBEDTLS_PEM_CERTIFICATE_FORMAT=y diff --git a/samples/net/lwm2m_client/overlay-dtls.conf b/samples/net/lwm2m_client/overlay-dtls.conf index 2f2fb9788c8c..c3b944c0dcb3 100644 --- a/samples/net/lwm2m_client/overlay-dtls.conf +++ b/samples/net/lwm2m_client/overlay-dtls.conf @@ -12,8 +12,12 @@ CONFIG_MBEDTLS_SSL_DTLS_CONNECTION_ID=y CONFIG_MBEDTLS_ENABLE_HEAP=y CONFIG_MBEDTLS_HEAP_SIZE=8192 CONFIG_MBEDTLS_SSL_MAX_CONTENT_LEN=1500 +CONFIG_PSA_CRYPTO=y CONFIG_PSA_WANT_KEY_TYPE_AES=y CONFIG_PSA_WANT_ALG_CCM=y +CONFIG_PSA_WANT_ALG_SHA_256=y +CONFIG_PSA_WANT_ALG_TLS12_PRF=y +CONFIG_PSA_WANT_ALG_TLS12_PSK_TO_MS=y # Disable RSA, we don't parse certs: saves flash/memory CONFIG_MBEDTLS_KEY_EXCHANGE_RSA_ENABLED=n From 221699228a53532f62e8de7a81f6cde9206bedad Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Mon, 8 Dec 2025 12:35:11 +0100 Subject: [PATCH 0135/3659] samples: net: lwm2m_client: Use cert-based DTLS overlay in twister Make sure that certificate-based DTLS config is built by twister and also mention it in the README file. Signed-off-by: Robert Lubos --- samples/net/lwm2m_client/README.rst | 3 +++ samples/net/lwm2m_client/sample.yaml | 12 ++++++++++++ 2 files changed, 15 insertions(+) diff --git a/samples/net/lwm2m_client/README.rst b/samples/net/lwm2m_client/README.rst index bc0658a1d805..fcdb70562225 100644 --- a/samples/net/lwm2m_client/README.rst +++ b/samples/net/lwm2m_client/README.rst @@ -49,6 +49,9 @@ samples/net/lwm2m_client directory: * - :file:`overlay-dtls.conf` - This overlay config can be added for DTLS support via MBEDTLS. + * - :file:`overlay-dtls-cert.conf` + - This overlay config can be added for DTLS with certificates support via MBEDTLS. + * - :file:`overlay-queue.conf` - This overlay config can be added to enable LWM2M Queue Mode support. diff --git a/samples/net/lwm2m_client/sample.yaml b/samples/net/lwm2m_client/sample.yaml index 1627211816d4..ddadac9dd081 100644 --- a/samples/net/lwm2m_client/sample.yaml +++ b/samples/net/lwm2m_client/sample.yaml @@ -52,6 +52,18 @@ tests: tags: - net - lwm2m + sample.net.lwm2m_client.dtls_cert: + harness: net + depends_on: netif + extra_args: EXTRA_CONF_FILE=overlay-dtls-cert.conf + platform_allow: + - qemu_x86 + - native_sim + integration_platforms: + - qemu_x86 + tags: + - net + - lwm2m sample.net.lwm2m_client.queue_mode: harness: net depends_on: netif From 3da552b2c7827c143cf28316525a17b603e9fa33 Mon Sep 17 00:00:00 2001 From: Qingsong Gou Date: Fri, 5 Dec 2025 20:00:09 +0800 Subject: [PATCH 0136/3659] drivers: i2c: sf32lb: add get_config() support Add get_config() support for sf32lb Signed-off-by: Qingsong Gou --- drivers/i2c/i2c_sf32lb.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/drivers/i2c/i2c_sf32lb.c b/drivers/i2c/i2c_sf32lb.c index 5b2632d3c873..402718bf8c63 100644 --- a/drivers/i2c/i2c_sf32lb.c +++ b/drivers/i2c/i2c_sf32lb.c @@ -235,6 +235,33 @@ static int i2c_sf32lb_configure(const struct device *dev, uint32_t dev_config) return 0; } +static int i2c_sf32lb_get_config(const struct device *dev, uint32_t *dev_config) +{ + const struct i2c_sf32lb_config *cfg = dev->config; + uint32_t cr = sys_read32(cfg->base + I2C_CR); + + *dev_config = I2C_MODE_CONTROLLER; + + switch (FIELD_GET(I2C_CR_MODE_Msk, cr)) { + case I2C_MODE_STD: + *dev_config |= I2C_SPEED_SET(I2C_SPEED_STANDARD); + break; + case I2C_MODE_FS: + *dev_config |= I2C_SPEED_SET(I2C_SPEED_FAST); + break; + case I2C_MODE_HS_STD: + *dev_config |= I2C_SPEED_SET(I2C_SPEED_FAST_PLUS); + break; + case I2C_MODE_HS_FS: + *dev_config |= I2C_SPEED_SET(I2C_SPEED_HIGH); + break; + default: + return -ERANGE; + } + + return 0; +} + static int i2c_sf32lb_transfer(const struct device *dev, struct i2c_msg *msgs, uint8_t num_msgs, uint16_t addr) { @@ -293,6 +320,7 @@ static int i2c_sf32lb_recover_bus(const struct device *dev) static DEVICE_API(i2c, i2c_sf32lb_driver_api) = { .configure = i2c_sf32lb_configure, + .get_config = i2c_sf32lb_get_config, .transfer = i2c_sf32lb_transfer, .recover_bus = i2c_sf32lb_recover_bus, }; From ea85a8b841cb52d42dde26fd4d8ca80bd2fe9fce Mon Sep 17 00:00:00 2001 From: Pieter De Gendt Date: Mon, 1 Dec 2025 18:11:10 +0100 Subject: [PATCH 0137/3659] drivers: ethernet: eth_lan865x: Support MAC address config Update the microchip,lan865x ethernet driver to use a MAC address configuration struct. Signed-off-by: Pieter De Gendt --- drivers/ethernet/eth_lan865x.c | 13 +++++++++++-- drivers/ethernet/eth_lan865x_priv.h | 2 ++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/drivers/ethernet/eth_lan865x.c b/drivers/ethernet/eth_lan865x.c index 603e44bf89a0..75c21efb0096 100644 --- a/drivers/ethernet/eth_lan865x.c +++ b/drivers/ethernet/eth_lan865x.c @@ -426,6 +426,14 @@ static int lan865x_init(const struct device *dev) return ret; } + ret = net_eth_mac_load(&cfg->mac_cfg, ctx->mac_address); + if (ret == -ENODATA) { + LOG_DBG("No MAC address configured for %s", dev->name); + } else if (ret < 0) { + LOG_ERR("Failed to load MAC address (%d)", ret); + return ret; + } + return lan865x_gpio_reset(dev); } @@ -475,12 +483,13 @@ static const struct ethernet_api lan865x_api_func = { .reset = GPIO_DT_SPEC_INST_GET(inst, rst_gpios), \ .timeout = CONFIG_ETH_LAN865X_TIMEOUT, \ .phy = DEVICE_DT_GET( \ - DT_CHILD(DT_INST_CHILD(inst, lan865x_mdio), ethernet_phy_##inst))}; \ + DT_CHILD(DT_INST_CHILD(inst, lan865x_mdio), ethernet_phy_##inst)), \ + .mac_cfg = NET_ETH_MAC_DT_INST_CONFIG_INIT(inst), \ + }; \ \ struct oa_tc6 oa_tc6_##inst = { \ .cps = 64, .protected = 0, .spi = &lan865x_config_##inst.spi}; \ static struct lan865x_data lan865x_data_##inst = { \ - .mac_address = DT_INST_PROP_OR(inst, local_mac_address, {0}), \ .tx_rx_sem = Z_SEM_INITIALIZER((lan865x_data_##inst).tx_rx_sem, 1, 1), \ .int_sem = Z_SEM_INITIALIZER((lan865x_data_##inst).int_sem, 0, 1), \ .tc6 = &oa_tc6_##inst}; \ diff --git a/drivers/ethernet/eth_lan865x_priv.h b/drivers/ethernet/eth_lan865x_priv.h index 50110dee133d..1b22b1b9e6f3 100644 --- a/drivers/ethernet/eth_lan865x_priv.h +++ b/drivers/ethernet/eth_lan865x_priv.h @@ -12,6 +12,7 @@ #include #include #include +#include #include #include "oa_tc6.h" @@ -50,6 +51,7 @@ struct lan865x_config { struct gpio_dt_spec interrupt; struct gpio_dt_spec reset; int32_t timeout; + struct net_eth_mac_config mac_cfg; /* MAC */ bool tx_cut_through_mode; /* 1 - tx cut through, 0 - Store and forward */ From 2e7115a45f0e1588f739a380137a82a749241de4 Mon Sep 17 00:00:00 2001 From: Khanh Nguyen Date: Mon, 15 Sep 2025 17:17:23 +0700 Subject: [PATCH 0138/3659] drivers: mipi_dsi: Add support Renesas RA MIPI DSI for RA8P1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update the Renesas RA MIPI DSI driver and bindings to align with RA8P1 SoC support: - Add SoC-specific PHY PLL multiplier ranges - RA8D1: 20–180 - RA8P1: 40–375 - Correct t_init limit from 15 bits to 19 bits as specified in HUM - Update devicetree bindings: - Clarify `pll-div` as input frequency divisor - Add `pll-out-div` property as output frequency divisor Signed-off-by: Khanh Nguyen --- drivers/mipi_dsi/dsi_renesas_ra.c | 18 ++++++++++++++++-- dts/bindings/mipi-dsi/renesas,ra-mipi-dsi.yaml | 8 +++++++- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/drivers/mipi_dsi/dsi_renesas_ra.c b/drivers/mipi_dsi/dsi_renesas_ra.c index 587cf1661456..339ba14c0d29 100644 --- a/drivers/mipi_dsi/dsi_renesas_ra.c +++ b/drivers/mipi_dsi/dsi_renesas_ra.c @@ -224,9 +224,19 @@ static int mipi_dsi_renesas_ra_init(const struct device *dev) return 0; } +#if defined(CONFIG_SOC_SERIES_RA8D1) +#define RENESAS_RA_PHY_PLL_MUL_INT_MIN 20 +#define RENESAS_RA_PHY_PLL_MUL_INT_MAX 180 +#elif defined(CONFIG_SOC_SERIES_RA8P1) +#define RENESAS_RA_PHY_PLL_MUL_INT_MIN 40 +#define RENESAS_RA_PHY_PLL_MUL_INT_MAX 375 +#else +#error "Unsupported SoC series" +#endif + #define RENESAS_RA_MIPI_PHYS_SETTING_DEFINE(n) \ static const mipi_phy_timing_t mipi_phy_##n##_timing = { \ - .t_init = CLAMP(DT_PROP(DT_INST_CHILD(n, phys_timing), t_init), 0, 0x7FFF), \ + .t_init = CLAMP(DT_PROP(DT_INST_CHILD(n, phys_timing), t_init), 0, 0x7FFFF), \ .dphytim2_b = \ { \ .t_clk_prep = \ @@ -266,8 +276,12 @@ static int mipi_dsi_renesas_ra_init(const struct device *dev) .pll_settings = \ { \ .div = DT_INST_PROP(n, pll_div) - 1, \ + .pll_div = DT_INST_ENUM_IDX_OR(n, pll_out_div, 0), \ .mul_frac = DT_INST_ENUM_IDX(n, pll_mul_frac), \ - .mul_int = CLAMP(DT_INST_PROP(n, pll_mul_int), 20, 180) - 1, \ + .mul_int = CLAMP(DT_INST_PROP(n, pll_mul_int), \ + RENESAS_RA_PHY_PLL_MUL_INT_MIN, \ + RENESAS_RA_PHY_PLL_MUL_INT_MAX) - \ + 1, \ }, \ .lp_divisor = CLAMP(DT_INST_PROP(n, lp_divisor), 1, 32) - 1, \ .p_timing = &mipi_phy_##n##_timing, \ diff --git a/dts/bindings/mipi-dsi/renesas,ra-mipi-dsi.yaml b/dts/bindings/mipi-dsi/renesas,ra-mipi-dsi.yaml index dbcbb47c8e21..68d204f63c96 100644 --- a/dts/bindings/mipi-dsi/renesas,ra-mipi-dsi.yaml +++ b/dts/bindings/mipi-dsi/renesas,ra-mipi-dsi.yaml @@ -23,7 +23,7 @@ properties: type: int enum: [1, 2, 3, 4] description: - PHY PLL divisor. + PHY PLL input frequency divisor. pll-mul-int: type: int @@ -36,6 +36,12 @@ properties: description: PHY PLL fractional multiplier. + pll-out-div: + type: int + enum: [1, 2, 4, 8] + description: | + PHY PLL output frequency divisor. + lp-divisor: type: int description: From f4ff6f6ca15599b4803836458383d86dd255ba09 Mon Sep 17 00:00:00 2001 From: Khanh Nguyen Date: Mon, 15 Sep 2025 17:31:46 +0700 Subject: [PATCH 0139/3659] boards: renesas: ek_ra8p1: add MIPI DSI support Add MIPI DSI support for EK-RA8P1: - Add default configs for MEMC, GLCDC framebuffer, and LVGL - Update DTS: * Add zephyr,user node with mipi-dphy-en-gpios * Add mipi-dsi alias and MIPI connector node * Add interrupts for lcdif, and mipi_dsi * Add aliases for lcdif, mipi_dsi, and I2C * Add gpio-hog for mipi_phy_enable Signed-off-by: Khanh Nguyen Signed-off-by: Khoa Nguyen --- boards/renesas/ek_ra8p1/Kconfig.defconfig | 18 +++++++++++++ boards/renesas/ek_ra8p1/ek_ra8p1.dtsi | 6 +++++ .../ek_ra8p1/ek_ra8p1_r7ka8p1kflcac_cm85.dts | 27 +++++++++++++++++++ 3 files changed, 51 insertions(+) diff --git a/boards/renesas/ek_ra8p1/Kconfig.defconfig b/boards/renesas/ek_ra8p1/Kconfig.defconfig index 6b28a1674754..fa71b1b3dc37 100644 --- a/boards/renesas/ek_ra8p1/Kconfig.defconfig +++ b/boards/renesas/ek_ra8p1/Kconfig.defconfig @@ -10,4 +10,22 @@ config SD_CMD_TIMEOUT endif # DISK_DRIVER_SDMMC +if DISPLAY + +config MEMC + default y + +config RENESAS_RA_GLCDC_FRAME_BUFFER_SECTION + default ".sdram" + depends on RENESAS_RA_GLCDC + +if LVGL + +config LV_Z_VDB_CUSTOM_SECTION + default y + +endif # LVGL + +endif # DISPLAY + endif # BOARD_EK_RA8P1 diff --git a/boards/renesas/ek_ra8p1/ek_ra8p1.dtsi b/boards/renesas/ek_ra8p1/ek_ra8p1.dtsi index 7a1a2a05bdcc..9adfec33e7f3 100644 --- a/boards/renesas/ek_ra8p1/ek_ra8p1.dtsi +++ b/boards/renesas/ek_ra8p1/ek_ra8p1.dtsi @@ -143,6 +143,12 @@ &ioport1 { status = "okay"; + + mipi_dphy_gpio: mipi-dphy-enable { + gpio-hog; + gpios = <8 GPIO_ACTIVE_LOW>; + output-low; + }; }; &ioport2 { diff --git a/boards/renesas/ek_ra8p1/ek_ra8p1_r7ka8p1kflcac_cm85.dts b/boards/renesas/ek_ra8p1/ek_ra8p1_r7ka8p1kflcac_cm85.dts index 4923dcc87cce..17e0de1f992d 100644 --- a/boards/renesas/ek_ra8p1/ek_ra8p1_r7ka8p1kflcac_cm85.dts +++ b/boards/renesas/ek_ra8p1/ek_ra8p1_r7ka8p1kflcac_cm85.dts @@ -25,6 +25,19 @@ aliases { led0 = &led1; sw0 = &button0; + mipi-dsi = &mipi_dsi; + }; + + renesas_mipi_connector: mipi-connector { + compatible = "renesas,ra-gpio-mipi-header"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <14 0 &ioport5 11 0>, /* IIC_SDA */ + <15 0 &ioport5 14 0>, /* DISP_BLEN */ + <16 0 &ioport5 12 0>, /* IIC_SCL */ + <17 0 &ioport1 11 0>, /* DISP_INT */ + <18 0 &ioport6 6 0>; /* DISP_RST */ }; }; @@ -171,8 +184,22 @@ }; }; +&mipi_dsi { + interrupts = <24 12>, <25 12>, <26 12>, <27 12>, <28 12>, <29 12>; + interrupt-names = "sq0", "sq1", "vm", "rcv", "ferr", "ppi"; +}; + +&lcdif { + interrupts = <30 1>; + interrupt-names = "line"; +}; + zephyr_lcdif: &lcdif {}; +zephyr_mipi_dsi: &mipi_dsi {}; + +renesas_mipi_i2c: &iic1 {}; + pmod_sd_shield: &sdhc0 {}; arducam_ffc_40pin_i2c: &iic1 {}; From d231118e7a9c049542634fc6b5f725fc7ee80ca1 Mon Sep 17 00:00:00 2001 From: Khanh Nguyen Date: Mon, 15 Sep 2025 17:33:26 +0700 Subject: [PATCH 0140/3659] boards: shields: add rtkmipilcdb00000be support for ek_ra8p1 Add support for the RTK MIPI LCD shield on EK-RA8P1: - Add default display configuration in .conf - Add overlay with MIPI DSI PLL, timing, gpio-hog, panel settings Signed-off-by: Khanh Nguyen Signed-off-by: Khoa Nguyen --- .../boards/ek_ra8p1_r7ka8p1kflcac_cm85.conf | 6 +++ .../ek_ra8p1_r7ka8p1kflcac_cm85.overlay | 38 +++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 boards/shields/rtkmipilcdb00000be/boards/ek_ra8p1_r7ka8p1kflcac_cm85.conf create mode 100644 boards/shields/rtkmipilcdb00000be/boards/ek_ra8p1_r7ka8p1kflcac_cm85.overlay diff --git a/boards/shields/rtkmipilcdb00000be/boards/ek_ra8p1_r7ka8p1kflcac_cm85.conf b/boards/shields/rtkmipilcdb00000be/boards/ek_ra8p1_r7ka8p1kflcac_cm85.conf new file mode 100644 index 000000000000..0ac7b7ace6ab --- /dev/null +++ b/boards/shields/rtkmipilcdb00000be/boards/ek_ra8p1_r7ka8p1kflcac_cm85.conf @@ -0,0 +1,6 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_LV_Z_FLUSH_THREAD=n +CONFIG_LV_Z_BITS_PER_PIXEL=16 +CONFIG_LV_COLOR_DEPTH_16=y diff --git a/boards/shields/rtkmipilcdb00000be/boards/ek_ra8p1_r7ka8p1kflcac_cm85.overlay b/boards/shields/rtkmipilcdb00000be/boards/ek_ra8p1_r7ka8p1kflcac_cm85.overlay new file mode 100644 index 000000000000..754aad780795 --- /dev/null +++ b/boards/shields/rtkmipilcdb00000be/boards/ek_ra8p1_r7ka8p1kflcac_cm85.overlay @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&mipi_dphy_gpio { + /delete-property/ output-low; + output-high; +}; + +&renesas_mipi_i2c { + clock-frequency = ; +}; + +&zephyr_lcdif { + input-pixel-format = ; +}; + +&zephyr_mipi_dsi { + pll-div = <3>; + pll-mul-int = <125>; + pll-mul-frac = "0.00"; + pll-out-div = <1>; + lp-divisor = <5>; + ulps-wakeup-period = <97>; + video-mode-delay = <186>; + timing = <1183 11 26 40>; + + phys-timing { + t-init = <74999>; + t-clk-prep = <9>; + t-hs-prep = <6>; + t-lp-exit = <7>; + dphytim4 = <28 1 20 7>; + dphytim5 = <19 8 12>; + }; +}; From e09d0adf577189d906febab93358ff3ac2be5e18 Mon Sep 17 00:00:00 2001 From: Khoa Nguyen Date: Wed, 26 Nov 2025 04:03:15 +0000 Subject: [PATCH 0141/3659] samples: modules: lvgl: demos: Enable ek_ra8p1 CM85 using MIPI LCD Enable ek_ra8p1_r7ka8p1kflcac_cm85 to run with rtkmipilcdb00000be MIPI LCD shield Signed-off-by: Khoa Nguyen --- .../boards/ek_ra8p1_r7ka8p1kflcac_cm85.overlay | 18 ++++++++++++++---- samples/modules/lvgl/demos/sample.yaml | 4 +++- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/samples/modules/lvgl/demos/boards/ek_ra8p1_r7ka8p1kflcac_cm85.overlay b/samples/modules/lvgl/demos/boards/ek_ra8p1_r7ka8p1kflcac_cm85.overlay index 5207a4a73fd6..d1e833df831e 100644 --- a/samples/modules/lvgl/demos/boards/ek_ra8p1_r7ka8p1kflcac_cm85.overlay +++ b/samples/modules/lvgl/demos/boards/ek_ra8p1_r7ka8p1kflcac_cm85.overlay @@ -4,10 +4,20 @@ * SPDX-License-Identifier: Apache-2.0 */ -&code_mram_cm85 { - reg = <0x2000000 DT_SIZE_K(950)>; +/delete-node/ &code_mram_cm85; +/delete-node/ &code_mram_cm33; + +/ { + chosen { + /delete-property/ zephyr,code-partition; + }; }; -&code_mram_cm33 { - reg = <0x20ed800 DT_SIZE_K(74)>; +&mram_ctrl { + code_mram_cm85: mram@2000000 { + compatible = "renesas,ra-nv-mram"; + reg = <0x2000000 DT_SIZE_M(1)>; + write-block-size = <1>; + erase-block-size = <32>; + }; }; diff --git a/samples/modules/lvgl/demos/sample.yaml b/samples/modules/lvgl/demos/sample.yaml index 869dcc1b1101..5cdf40e77ce2 100644 --- a/samples/modules/lvgl/demos/sample.yaml +++ b/samples/modules/lvgl/demos/sample.yaml @@ -65,7 +65,9 @@ tests: tags: - shield sample.modules.lvgl.demos.rtkmipilcdb00000be: - platform_allow: ek_ra8d1 + platform_allow: + - ek_ra8d1 + - ek_ra8p1/r7ka8p1kflcac/cm85 extra_args: SHIELD=rtkmipilcdb00000be tags: - shield From 518a21f59df389af3d223c3c7ed0d23ce55ff391 Mon Sep 17 00:00:00 2001 From: cyliang tw Date: Wed, 10 Dec 2025 10:59:55 +0800 Subject: [PATCH 0142/3659] MAINTAINERS: modify dts files to match Numaker Modify dts/arm/nuvoton/m* to better align with Numaker platform naming conventions. Also add one more collaborator. Signed-off-by: cyliang tw --- MAINTAINERS.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index 8dbc3da1c4d1..a9b5f8a8637e 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -4125,11 +4125,12 @@ Nuvoton Numicro Numaker Platforms: - cyliangtw collaborators: - ssekar15 + - ccli8 files: - soc/nuvoton/numaker/ - soc/nuvoton/numicro/ - boards/nuvoton/numaker*/ - - dts/arm/nuvoton/ + - dts/arm/nuvoton/m* - dts/bindings/*/*numicro* - dts/bindings/*/*numaker* - drivers/*/*_numicro* From df1677c8aa999907f05639b8ee8610f91bae7991 Mon Sep 17 00:00:00 2001 From: Mathieu Choplain Date: Mon, 8 Dec 2025 14:13:41 +0100 Subject: [PATCH 0143/3659] doc: kconfig: document DT_COMPAT_<...> macro variables The DT_COMPAT_<...> macro variables are generated for every compatible found in bindings: document them as existing and recommend using them in various Kconfig documentation pages. Signed-off-by: Mathieu Choplain --- doc/build/kconfig/tips.rst | 5 +++++ doc/contribute/style/kconfig.rst | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/doc/build/kconfig/tips.rst b/doc/build/kconfig/tips.rst index ab1653424bce..e89010c0c307 100644 --- a/doc/build/kconfig/tips.rst +++ b/doc/build/kconfig/tips.rst @@ -628,6 +628,11 @@ argument, as follows: bool default y if $(dt_chosen_enabled,$(DT_CHOSEN_ZEPHYR_BAR)) +.. note:: + + A variable :samp:`DT_COMPAT_{VND_MY_DEVICE} := {vnd,my-device}` + is automatically created by Zephyr for every ``compatible`` found + in Devicetree bindings; there is no need to define such variables. Checking changes in menuconfig/guiconfig **************************************** diff --git a/doc/contribute/style/kconfig.rst b/doc/contribute/style/kconfig.rst index 727104a09462..5c5cf7f0aaef 100644 --- a/doc/contribute/style/kconfig.rst +++ b/doc/contribute/style/kconfig.rst @@ -66,6 +66,10 @@ Naming Conventions * When the enabling symbol is dependent on a devicetree node, consider depending on the automatically created ``DT_HAS__ENABLED`` symbol. +* When building complex expressions based on devicetree node compatibles, + use the automatically defined :samp:`DT_COMPAT_{VND_DEVICE}` instead + of defining a variable equal to :samp:`{vnd,device}` manually. + The specific formats by subtree: * **Drivers (/drivers)**: Use the format ``{Driver Type}_{Driver Name}`` for From 22a163f938af31b0595bff3b38af1862b70d2b02 Mon Sep 17 00:00:00 2001 From: Mathieu Choplain Date: Mon, 8 Dec 2025 13:06:34 +0100 Subject: [PATCH 0144/3659] kconfig: source autogenerated Kconfig.dts earlier than defconfigs In addition to the DT_HAS__ENABLED options, the autogenerated Kconfig.dts file also provides the DT_COMPAT_ *macros* which avoid manually declaring them when working around the no comma limitation. Unlike options which can be referenced before their declaration, macros MUST be defined before their usage (otherwise, they expand to nothing ("")). Because the defconfig files were sourced before "dts/Kconfig", it was not possible to use the DT_COMPAT macros from shields/boards/SoC defconfig; this is not only confusing but also suboptimal because the macros must be defined manually. Include "dts/Kconfig" earlier to allow usage of the DT_COMPAT macros from shields, boards and SoC defconfig. This should have no adverse effect since there is no reason to override the options provided by the autogenerated Kconfig.dts anyways. Signed-off-by: Mathieu Choplain --- Kconfig.zephyr | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Kconfig.zephyr b/Kconfig.zephyr index fdf3a84087db..8bdaff1c4127 100644 --- a/Kconfig.zephyr +++ b/Kconfig.zephyr @@ -9,6 +9,10 @@ source "Kconfig.constants" osource "$(APPLICATION_SOURCE_DIR)/VERSION" +# This should be sourced early since the autogen Kconfig.dts options +# and macros may get used by shields/boards/SoC defconfig or modules. +source "dts/Kconfig" + # Include Kconfig.defconfig files first so that they can override defaults and # other symbol/choice properties by adding extra symbol/choice definitions. # After merging all definitions for a symbol/choice, Kconfig picks the first @@ -33,10 +37,6 @@ osource "$(TOOLCHAIN_KCONFIG_DIR)/Kconfig.defconfig" # This loads the testsuite defconfig source "subsys/testsuite/Kconfig.defconfig" -# This should be early since the autogen Kconfig.dts symbols may get -# used by modules -source "dts/Kconfig" - menu "Modules" source "modules/Kconfig" From 23d873188bf54d9b0a4ae918cb28188282bc4a4c Mon Sep 17 00:00:00 2001 From: Gang He Date: Fri, 5 Dec 2025 00:39:17 -0800 Subject: [PATCH 0145/3659] bluetooth: host: scan: Format source code Run clang-format on scan.c Signed-off-by: Gang He --- subsys/bluetooth/host/scan.c | 253 +++++++++++++---------------------- 1 file changed, 95 insertions(+), 158 deletions(-) diff --git a/subsys/bluetooth/host/scan.c b/subsys/bluetooth/host/scan.c index 8c5278f362c0..b4d8341771eb 100644 --- a/subsys/bluetooth/host/scan.c +++ b/subsys/bluetooth/host/scan.c @@ -458,8 +458,7 @@ static int scan_update(void) LOG_DBG("Could not stop scanner: %d", err); break; } - memset(&scan_state.used_scan_param, 0x0, - sizeof(scan_state.used_scan_param)); + memset(&scan_state.used_scan_param, 0x0, sizeof(scan_state.used_scan_param)); break; case SCAN_ACTION_UPDATE: err = cmd_le_set_scan_enable(BT_HCI_LE_SCAN_DISABLE, @@ -538,8 +537,8 @@ int bt_le_scan_user_remove(enum bt_le_scan_user flag) return scan_update(); } -static void check_pending_conn(const bt_addr_le_t *id_addr, - const bt_addr_le_t *addr, uint8_t adv_props) +static void check_pending_conn(const bt_addr_le_t *id_addr, const bt_addr_le_t *addr, + uint8_t adv_props) { struct bt_conn *conn; int err; @@ -557,8 +556,7 @@ static void check_pending_conn(const bt_addr_le_t *id_addr, return; } - conn = bt_conn_lookup_state_le(BT_ID_DEFAULT, id_addr, - BT_CONN_SCAN_BEFORE_INITIATING); + conn = bt_conn_lookup_state_le(BT_ID_DEFAULT, id_addr, BT_CONN_SCAN_BEFORE_INITIATING); if (!conn) { return; } @@ -598,12 +596,10 @@ static uint8_t get_adv_props_legacy(uint8_t evt_type) { switch (evt_type) { case BT_GAP_ADV_TYPE_ADV_IND: - return BT_GAP_ADV_PROP_CONNECTABLE | - BT_GAP_ADV_PROP_SCANNABLE; + return BT_GAP_ADV_PROP_CONNECTABLE | BT_GAP_ADV_PROP_SCANNABLE; case BT_GAP_ADV_TYPE_ADV_DIRECT_IND: - return BT_GAP_ADV_PROP_CONNECTABLE | - BT_GAP_ADV_PROP_DIRECTED; + return BT_GAP_ADV_PROP_CONNECTABLE | BT_GAP_ADV_PROP_DIRECTED; case BT_GAP_ADV_TYPE_ADV_SCAN_IND: return BT_GAP_ADV_PROP_SCANNABLE; @@ -616,8 +612,7 @@ static uint8_t get_adv_props_legacy(uint8_t evt_type) * set connectable property bit. */ case BT_GAP_ADV_TYPE_SCAN_RSP: - return BT_GAP_ADV_PROP_SCAN_RESPONSE | - BT_GAP_ADV_PROP_SCANNABLE; + return BT_GAP_ADV_PROP_SCAN_RESPONSE | BT_GAP_ADV_PROP_SCANNABLE; default: return 0; @@ -631,7 +626,7 @@ static void le_adv_recv(bt_addr_le_t *addr, struct bt_le_scan_recv_info *info, struct net_buf_simple_state state; bt_addr_le_t id_addr; bool explicit_scan = atomic_test_bit(scan_state.scan_flags, BT_LE_SCAN_USER_EXPLICIT_SCAN); - bool conn_scan = atomic_test_bit(scan_state.scan_flags, BT_LE_SCAN_USER_CONN); + bool conn_scan = atomic_test_bit(scan_state.scan_flags, BT_LE_SCAN_USER_CONN); LOG_DBG("%s event %u, len %u, rssi %d dBm", bt_addr_le_str(addr), info->adv_type, len, info->rssi); @@ -647,8 +642,7 @@ static void le_adv_recv(bt_addr_le_t *addr, struct bt_le_scan_recv_info *info, } else if (addr->type == BT_HCI_PEER_ADDR_ANONYMOUS) { bt_addr_le_copy(&id_addr, BT_ADDR_LE_ANY); } else { - bt_addr_le_copy(&id_addr, - bt_lookup_id_addr(BT_ID_DEFAULT, addr)); + bt_addr_le_copy(&id_addr, bt_lookup_id_addr(BT_ID_DEFAULT, addr)); } /* For connection-purpose scanning, @@ -723,29 +717,23 @@ void bt_hci_le_scan_timeout(struct net_buf *buf) static uint8_t get_adv_type(uint8_t evt_type) { switch (evt_type) { - case (BT_HCI_LE_ADV_EVT_TYPE_CONN | - BT_HCI_LE_ADV_EVT_TYPE_SCAN | + case (BT_HCI_LE_ADV_EVT_TYPE_CONN | BT_HCI_LE_ADV_EVT_TYPE_SCAN | BT_HCI_LE_ADV_EVT_TYPE_LEGACY): return BT_GAP_ADV_TYPE_ADV_IND; - case (BT_HCI_LE_ADV_EVT_TYPE_CONN | - BT_HCI_LE_ADV_EVT_TYPE_DIRECT | + case (BT_HCI_LE_ADV_EVT_TYPE_CONN | BT_HCI_LE_ADV_EVT_TYPE_DIRECT | BT_HCI_LE_ADV_EVT_TYPE_LEGACY): return BT_GAP_ADV_TYPE_ADV_DIRECT_IND; - case (BT_HCI_LE_ADV_EVT_TYPE_SCAN | - BT_HCI_LE_ADV_EVT_TYPE_LEGACY): + case (BT_HCI_LE_ADV_EVT_TYPE_SCAN | BT_HCI_LE_ADV_EVT_TYPE_LEGACY): return BT_GAP_ADV_TYPE_ADV_SCAN_IND; case BT_HCI_LE_ADV_EVT_TYPE_LEGACY: return BT_GAP_ADV_TYPE_ADV_NONCONN_IND; - case (BT_HCI_LE_ADV_EVT_TYPE_SCAN_RSP | - BT_HCI_LE_ADV_EVT_TYPE_CONN | - BT_HCI_LE_ADV_EVT_TYPE_SCAN | - BT_HCI_LE_ADV_EVT_TYPE_LEGACY): - case (BT_HCI_LE_ADV_EVT_TYPE_SCAN_RSP | - BT_HCI_LE_ADV_EVT_TYPE_SCAN | + case (BT_HCI_LE_ADV_EVT_TYPE_SCAN_RSP | BT_HCI_LE_ADV_EVT_TYPE_CONN | + BT_HCI_LE_ADV_EVT_TYPE_SCAN | BT_HCI_LE_ADV_EVT_TYPE_LEGACY): + case (BT_HCI_LE_ADV_EVT_TYPE_SCAN_RSP | BT_HCI_LE_ADV_EVT_TYPE_SCAN | BT_HCI_LE_ADV_EVT_TYPE_LEGACY): /* Scan response from connectable or non-connectable advertiser. */ @@ -813,7 +801,7 @@ void bt_hci_le_adv_ext_report(struct net_buf *buf) { uint8_t num_reports = net_buf_pull_u8(buf); bool explicit_scan = atomic_test_bit(scan_state.scan_flags, BT_LE_SCAN_USER_EXPLICIT_SCAN); - bool conn_scan = atomic_test_bit(scan_state.scan_flags, BT_LE_SCAN_USER_CONN); + bool conn_scan = atomic_test_bit(scan_state.scan_flags, BT_LE_SCAN_USER_CONN); LOG_DBG("Adv number of reports %u", num_reports); @@ -977,8 +965,7 @@ static struct bt_le_per_adv_sync *per_adv_sync_new(void) struct bt_le_per_adv_sync *per_adv_sync = NULL; for (int i = 0; i < ARRAY_SIZE(per_adv_sync_pool); i++) { - if (!atomic_test_bit(per_adv_sync_pool[i].flags, - BT_PER_ADV_SYNC_CREATED)) { + if (!atomic_test_bit(per_adv_sync_pool[i].flags, BT_PER_ADV_SYNC_CREATED)) { per_adv_sync = &per_adv_sync_pool[i]; break; } @@ -992,8 +979,7 @@ static struct bt_le_per_adv_sync *per_adv_sync_new(void) atomic_set_bit(per_adv_sync->flags, BT_PER_ADV_SYNC_CREATED); #if CONFIG_BT_PER_ADV_SYNC_BUF_SIZE > 0 - net_buf_simple_init_with_data(&per_adv_sync->reassembly, - per_adv_sync->reassembly_data, + net_buf_simple_init_with_data(&per_adv_sync->reassembly, per_adv_sync->reassembly_data, CONFIG_BT_PER_ADV_SYNC_BUF_SIZE); net_buf_simple_reset(&per_adv_sync->reassembly); #endif /* CONFIG_BT_PER_ADV_SYNC_BUF_SIZE > 0 */ @@ -1004,8 +990,7 @@ static struct bt_le_per_adv_sync *per_adv_sync_new(void) static struct bt_le_per_adv_sync *get_pending_per_adv_sync(void) { for (int i = 0; i < ARRAY_SIZE(per_adv_sync_pool); i++) { - if (atomic_test_bit(per_adv_sync_pool[i].flags, - BT_PER_ADV_SYNC_SYNCING)) { + if (atomic_test_bit(per_adv_sync_pool[i].flags, BT_PER_ADV_SYNC_SYNCING)) { return &per_adv_sync_pool[i]; } } @@ -1024,8 +1009,7 @@ struct bt_le_per_adv_sync *bt_hci_per_adv_sync_lookup_handle(uint16_t handle) { for (int i = 0; i < ARRAY_SIZE(per_adv_sync_pool); i++) { if (per_adv_sync_pool[i].handle == handle && - atomic_test_bit(per_adv_sync_pool[i].flags, - BT_PER_ADV_SYNC_SYNCED)) { + atomic_test_bit(per_adv_sync_pool[i].flags, BT_PER_ADV_SYNC_SYNCED)) { return &per_adv_sync_pool[i]; } } @@ -1051,7 +1035,7 @@ void bt_hci_le_per_adv_report_recv(struct bt_le_per_adv_sync *per_adv_sync, #if defined(CONFIG_BT_PER_ADV_SYNC_RSP) && (CONFIG_BT_PER_ADV_SYNC_BUF_SIZE > 0) static void bt_hci_le_per_adv_report_recv_failure(struct bt_le_per_adv_sync *per_adv_sync, - const struct bt_le_per_adv_sync_recv_info *info) + const struct bt_le_per_adv_sync_recv_info *info) { struct bt_le_per_adv_sync_cb *listener; @@ -1089,8 +1073,7 @@ static void bt_hci_le_per_adv_report_common(struct net_buf *buf) return; } - if (atomic_test_bit(per_adv_sync->flags, - BT_PER_ADV_SYNC_RECV_DISABLED)) { + if (atomic_test_bit(per_adv_sync->flags, BT_PER_ADV_SYNC_RECV_DISABLED)) { LOG_ERR("Received PA adv report when receive disabled"); return; } @@ -1126,8 +1109,8 @@ static void bt_hci_le_per_adv_report_common(struct net_buf *buf) */ bt_hci_le_per_adv_report_recv(per_adv_sync, &buf->b, &info); } else { - net_buf_simple_add_mem(&per_adv_sync->reassembly, - buf->data, evt->length); + net_buf_simple_add_mem(&per_adv_sync->reassembly, buf->data, + evt->length); bt_hci_le_per_adv_report_recv(per_adv_sync, &per_adv_sync->reassembly, &info); net_buf_simple_reset(&per_adv_sync->reassembly); @@ -1148,7 +1131,7 @@ static void bt_hci_le_per_adv_report_common(struct net_buf *buf) } else { __ASSERT(false, "Invalid data status 0x%02X", evt->data_status); } -#else /* CONFIG_BT_PER_ADV_SYNC_BUF_SIZE > 0 */ +#else /* CONFIG_BT_PER_ADV_SYNC_BUF_SIZE > 0 */ if (evt->data_status == BT_HCI_LE_ADV_EVT_TYPE_DATA_STATUS_COMPLETE) { bt_hci_le_per_adv_report_recv(per_adv_sync, &buf->b, &info); } else { @@ -1186,12 +1169,10 @@ static int per_adv_sync_terminate(uint16_t handle) cp->handle = sys_cpu_to_le16(handle); - return bt_hci_cmd_send_sync(BT_HCI_OP_LE_PER_ADV_TERMINATE_SYNC, buf, - NULL); + return bt_hci_cmd_send_sync(BT_HCI_OP_LE_PER_ADV_TERMINATE_SYNC, buf, NULL); } -static void per_adv_sync_terminated(struct bt_le_per_adv_sync *per_adv_sync, - uint8_t reason) +static void per_adv_sync_terminated(struct bt_le_per_adv_sync *per_adv_sync, uint8_t reason) { /* Terminate the PA sync and notify app */ const struct bt_le_per_adv_sync_term_info term_info = { @@ -1255,14 +1236,11 @@ static void bt_hci_le_per_adv_sync_established_common(struct net_buf *buf) if (bt_addr_le_is_resolved(&evt->adv_addr)) { bt_addr_le_copy_resolved(&id_addr, &evt->adv_addr); } else { - bt_addr_le_copy(&id_addr, - bt_lookup_id_addr(BT_ID_DEFAULT, - &evt->adv_addr)); + bt_addr_le_copy(&id_addr, bt_lookup_id_addr(BT_ID_DEFAULT, &evt->adv_addr)); } if (!pending_per_adv_sync || - (!atomic_test_bit(pending_per_adv_sync->flags, - BT_PER_ADV_SYNC_SYNCING_USE_LIST) && + (!atomic_test_bit(pending_per_adv_sync->flags, BT_PER_ADV_SYNC_SYNCING_USE_LIST) && ((pending_per_adv_sync->sid != evt->sid) || !bt_addr_le_eq(&pending_per_adv_sync->addr, &id_addr)))) { LOG_ERR("Unexpected per adv sync established event"); @@ -1276,16 +1254,15 @@ static void bt_hci_le_per_adv_sync_established_common(struct net_buf *buf) if (unexpected_evt || evt->status != BT_HCI_ERR_SUCCESS) { if (pending_per_adv_sync) { - const uint8_t reason = unexpected_evt ? BT_HCI_ERR_UNSPECIFIED - : evt->status; + const uint8_t reason = + unexpected_evt ? BT_HCI_ERR_UNSPECIFIED : evt->status; if (atomic_test_bit(pending_per_adv_sync->flags, BT_PER_ADV_SYNC_SYNCING_USE_LIST)) { /* Update the addr and sid for the callback * Already set if not using the sync list */ - bt_addr_le_copy(&pending_per_adv_sync->addr, - &id_addr); + bt_addr_le_copy(&pending_per_adv_sync->addr, &id_addr); pending_per_adv_sync->sid = evt->sid; } @@ -1300,22 +1277,19 @@ static void bt_hci_le_per_adv_sync_established_common(struct net_buf *buf) pending_per_adv_sync->handle = sys_le16_to_cpu(evt->handle); pending_per_adv_sync->interval = sys_le16_to_cpu(evt->interval); - pending_per_adv_sync->clock_accuracy = - sys_le16_to_cpu(evt->clock_accuracy); + pending_per_adv_sync->clock_accuracy = sys_le16_to_cpu(evt->clock_accuracy); pending_per_adv_sync->phy = bt_get_phy(evt->phy); memset(&sync_info, 0, sizeof(sync_info)); sync_info.interval = pending_per_adv_sync->interval; sync_info.phy = pending_per_adv_sync->phy; - if (atomic_test_bit(pending_per_adv_sync->flags, - BT_PER_ADV_SYNC_SYNCING_USE_LIST)) { + if (atomic_test_bit(pending_per_adv_sync->flags, BT_PER_ADV_SYNC_SYNCING_USE_LIST)) { /* Now we know which address and SID we synchronized to. */ pending_per_adv_sync->sid = evt->sid; if (bt_addr_le_is_resolved(&pending_per_adv_sync->addr)) { - bt_addr_le_copy_resolved(&pending_per_adv_sync->addr, - &id_addr); + bt_addr_le_copy_resolved(&pending_per_adv_sync->addr, &id_addr); } else { bt_addr_le_copy(&pending_per_adv_sync->addr, &id_addr); } @@ -1336,8 +1310,7 @@ static void bt_hci_le_per_adv_sync_established_common(struct net_buf *buf) #endif /* CONFIG_BT_PER_ADV_SYNC_RSP */ sync_info.recv_enabled = - !atomic_test_bit(pending_per_adv_sync->flags, - BT_PER_ADV_SYNC_RECV_DISABLED); + !atomic_test_bit(pending_per_adv_sync->flags, BT_PER_ADV_SYNC_RECV_DISABLED); SYS_SLIST_FOR_EACH_CONTAINER(&pa_sync_cbs, listener, node) { if (listener->synced) { @@ -1466,8 +1439,7 @@ static void bt_hci_le_past_received_common(struct net_buf *buf) struct bt_hci_evt_le_past_received_v2 *evt = (struct bt_hci_evt_le_past_received_v2 *)buf->data; #else - struct bt_hci_evt_le_past_received *evt = - (struct bt_hci_evt_le_past_received *)buf->data; + struct bt_hci_evt_le_past_received *evt = (struct bt_hci_evt_le_past_received *)buf->data; #endif /* defined(CONFIG_BT_PER_ADV_SYNC_RSP) */ struct bt_le_per_adv_sync_synced_info sync_info; @@ -1477,14 +1449,12 @@ static void bt_hci_le_past_received_common(struct net_buf *buf) if (evt->status) { /* No sync created, don't notify app */ - LOG_DBG("PAST receive failed with status 0x%02X %s", - evt->status, bt_hci_err_to_str(evt->status)); + LOG_DBG("PAST receive failed with status 0x%02X %s", evt->status, + bt_hci_err_to_str(evt->status)); return; } - sync_info.conn = bt_conn_lookup_handle( - sys_le16_to_cpu(evt->conn_handle), - BT_CONN_TYPE_LE); + sync_info.conn = bt_conn_lookup_handle(sys_le16_to_cpu(evt->conn_handle), BT_CONN_TYPE_LE); if (!sync_info.conn) { LOG_ERR("Could not lookup connection handle from PAST"); @@ -1505,8 +1475,7 @@ static void bt_hci_le_past_received_common(struct net_buf *buf) if (bt_addr_le_is_resolved(&evt->addr)) { bt_addr_le_copy_resolved(&id_addr, &evt->addr); } else { - bt_addr_le_copy(&id_addr, - bt_lookup_id_addr(BT_ID_DEFAULT, &evt->addr)); + bt_addr_le_copy(&id_addr, bt_lookup_id_addr(BT_ID_DEFAULT, &evt->addr)); } per_adv_sync->handle = sys_le16_to_cpu(evt->sync_handle); @@ -1542,10 +1511,10 @@ static void bt_hci_le_past_received_common(struct net_buf *buf) } #if defined(CONFIG_BT_PER_ADV_SYNC_RSP) - sync_info.num_subevents = per_adv_sync->num_subevents; - sync_info.subevent_interval = per_adv_sync->subevent_interval; - sync_info.response_slot_delay = per_adv_sync->response_slot_delay; - sync_info.response_slot_spacing = per_adv_sync->response_slot_spacing; + sync_info.num_subevents = per_adv_sync->num_subevents; + sync_info.subevent_interval = per_adv_sync->subevent_interval; + sync_info.response_slot_delay = per_adv_sync->response_slot_delay; + sync_info.response_slot_spacing = per_adv_sync->response_slot_spacing; #endif /* defined(CONFIG_BT_PER_ADV_SYNC_RSP) */ SYS_SLIST_FOR_EACH_CONTAINER(&pa_sync_cbs, listener, node) { @@ -1683,9 +1652,9 @@ void bt_hci_le_adv_report(struct net_buf *buf) uint8_t num_reports = net_buf_pull_u8(buf); struct bt_hci_evt_le_advertising_info *evt; bool explicit_scan = atomic_test_bit(scan_state.scan_flags, BT_LE_SCAN_USER_EXPLICIT_SCAN); - bool conn_scan = atomic_test_bit(scan_state.scan_flags, BT_LE_SCAN_USER_CONN); + bool conn_scan = atomic_test_bit(scan_state.scan_flags, BT_LE_SCAN_USER_CONN); - LOG_DBG("Adv number of reports %u", num_reports); + LOG_DBG("Adv number of reports %u", num_reports); while (num_reports--) { struct bt_le_scan_recv_info adv_info; @@ -1734,8 +1703,7 @@ void bt_hci_le_adv_report(struct net_buf *buf) static bool valid_le_scan_param(const struct bt_le_scan_param *param) { - if (IS_ENABLED(CONFIG_BT_PRIVACY) && - param->type == BT_LE_SCAN_TYPE_ACTIVE && + if (IS_ENABLED(CONFIG_BT_PRIVACY) && param->type == BT_LE_SCAN_TYPE_ACTIVE && param->timeout != 0) { /* This is marked as not supported as a stopgap until the (scan, * adv, init) roles are reworked into proper state machines. @@ -1752,15 +1720,12 @@ static bool valid_le_scan_param(const struct bt_le_scan_param *param) return false; } - if (param->type != BT_LE_SCAN_TYPE_PASSIVE && - param->type != BT_LE_SCAN_TYPE_ACTIVE) { + if (param->type != BT_LE_SCAN_TYPE_PASSIVE && param->type != BT_LE_SCAN_TYPE_ACTIVE) { return false; } - if (param->options & ~(BT_LE_SCAN_OPT_FILTER_DUPLICATE | - BT_LE_SCAN_OPT_FILTER_ACCEPT_LIST | - BT_LE_SCAN_OPT_CODED | - BT_LE_SCAN_OPT_NO_1M)) { + if (param->options & ~(BT_LE_SCAN_OPT_FILTER_DUPLICATE | BT_LE_SCAN_OPT_FILTER_ACCEPT_LIST | + BT_LE_SCAN_OPT_CODED | BT_LE_SCAN_OPT_NO_1M)) { return false; } @@ -1813,8 +1778,7 @@ int bt_le_scan_start(const struct bt_le_scan_param *param, bt_le_scan_cb_t cb) } /* store the parameters that were used to start the scanner */ - memcpy(&scan_state.explicit_scan_param, param, - sizeof(scan_state.explicit_scan_param)); + memcpy(&scan_state.explicit_scan_param, param, sizeof(scan_state.explicit_scan_param)); scan_dev_found_cb = cb; err = bt_le_scan_user_add(BT_LE_SCAN_USER_EXPLICIT_SCAN); @@ -1859,8 +1823,7 @@ void bt_le_scan_cb_unregister(struct bt_le_scan_cb *cb) #if defined(CONFIG_BT_PER_ADV_SYNC) uint8_t bt_le_per_adv_sync_get_index(struct bt_le_per_adv_sync *per_adv_sync) { - __ASSERT(IS_ARRAY_ELEMENT(per_adv_sync_pool, per_adv_sync), - "Invalid per_adv_sync pointer"); + __ASSERT(IS_ARRAY_ELEMENT(per_adv_sync_pool, per_adv_sync), "Invalid per_adv_sync pointer"); return (uint8_t)ARRAY_INDEX(per_adv_sync_pool, per_adv_sync); } @@ -1889,14 +1852,12 @@ int bt_le_per_adv_sync_get_info(struct bt_le_per_adv_sync *per_adv_sync, return 0; } -struct bt_le_per_adv_sync *bt_le_per_adv_sync_lookup_addr(const bt_addr_le_t *adv_addr, - uint8_t sid) +struct bt_le_per_adv_sync *bt_le_per_adv_sync_lookup_addr(const bt_addr_le_t *adv_addr, uint8_t sid) { for (int i = 0; i < ARRAY_SIZE(per_adv_sync_pool); i++) { struct bt_le_per_adv_sync *sync = &per_adv_sync_pool[i]; - if (!atomic_test_bit(per_adv_sync_pool[i].flags, - BT_PER_ADV_SYNC_CREATED)) { + if (!atomic_test_bit(per_adv_sync_pool[i].flags, BT_PER_ADV_SYNC_CREATED)) { continue; } @@ -1924,10 +1885,9 @@ int bt_le_per_adv_sync_create(const struct bt_le_per_adv_sync_param *param, return -EBUSY; } - if (param->sid > BT_GAP_SID_MAX || - param->skip > BT_GAP_PER_ADV_MAX_SKIP || - param->timeout > BT_GAP_PER_ADV_MAX_TIMEOUT || - param->timeout < BT_GAP_PER_ADV_MIN_TIMEOUT) { + if (param->sid > BT_GAP_SID_MAX || param->skip > BT_GAP_PER_ADV_MAX_SKIP || + param->timeout > BT_GAP_PER_ADV_MAX_TIMEOUT || + param->timeout < BT_GAP_PER_ADV_MIN_TIMEOUT) { return -EINVAL; } @@ -1946,8 +1906,7 @@ int bt_le_per_adv_sync_create(const struct bt_le_per_adv_sync_param *param, (void)memset(cp, 0, sizeof(*cp)); if (param->options & BT_LE_PER_ADV_SYNC_OPT_USE_PER_ADV_LIST) { - atomic_set_bit(per_adv_sync->flags, - BT_PER_ADV_SYNC_SYNCING_USE_LIST); + atomic_set_bit(per_adv_sync->flags, BT_PER_ADV_SYNC_SYNCING_USE_LIST); cp->options |= BT_HCI_LE_PER_ADV_CREATE_SYNC_FP_USE_LIST; } else { @@ -1960,18 +1919,14 @@ int bt_le_per_adv_sync_create(const struct bt_le_per_adv_sync_param *param, cp->sid = param->sid; } - if (param->options & - BT_LE_PER_ADV_SYNC_OPT_REPORTING_INITIALLY_DISABLED) { - cp->options |= - BT_HCI_LE_PER_ADV_CREATE_SYNC_FP_REPORTS_DISABLED; + if (param->options & BT_LE_PER_ADV_SYNC_OPT_REPORTING_INITIALLY_DISABLED) { + cp->options |= BT_HCI_LE_PER_ADV_CREATE_SYNC_FP_REPORTS_DISABLED; - atomic_set_bit(per_adv_sync->flags, - BT_PER_ADV_SYNC_RECV_DISABLED); + atomic_set_bit(per_adv_sync->flags, BT_PER_ADV_SYNC_RECV_DISABLED); } if (param->options & BT_LE_PER_ADV_SYNC_OPT_FILTER_DUPLICATE) { - cp->options |= - BT_HCI_LE_PER_ADV_CREATE_SYNC_FP_FILTER_DUPLICATE; + cp->options |= BT_HCI_LE_PER_ADV_CREATE_SYNC_FP_FILTER_DUPLICATE; } if (param->options & BT_LE_PER_ADV_SYNC_OPT_DONT_SYNC_AOA) { @@ -1979,13 +1934,11 @@ int bt_le_per_adv_sync_create(const struct bt_le_per_adv_sync_param *param, } if (param->options & BT_LE_PER_ADV_SYNC_OPT_DONT_SYNC_AOD_1US) { - cp->cte_type |= - BT_HCI_LE_PER_ADV_CREATE_SYNC_CTE_TYPE_NO_AOD_1US; + cp->cte_type |= BT_HCI_LE_PER_ADV_CREATE_SYNC_CTE_TYPE_NO_AOD_1US; } if (param->options & BT_LE_PER_ADV_SYNC_OPT_DONT_SYNC_AOD_2US) { - cp->cte_type |= - BT_HCI_LE_PER_ADV_CREATE_SYNC_CTE_TYPE_NO_AOD_2US; + cp->cte_type |= BT_HCI_LE_PER_ADV_CREATE_SYNC_CTE_TYPE_NO_AOD_2US; } if (param->options & BT_LE_PER_ADV_SYNC_OPT_SYNC_ONLY_CONST_TONE_EXT) { @@ -2027,8 +1980,7 @@ int bt_le_per_adv_sync_create(const struct bt_le_per_adv_sync_param *param, return 0; } -static int bt_le_per_adv_sync_create_cancel( - struct bt_le_per_adv_sync *per_adv_sync) +static int bt_le_per_adv_sync_create_cancel(struct bt_le_per_adv_sync *per_adv_sync) { struct net_buf *buf; int err; @@ -2048,8 +2000,7 @@ static int bt_le_per_adv_sync_create_cancel( return -ENOBUFS; } - err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_PER_ADV_CREATE_SYNC_CANCEL, buf, - NULL); + err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_PER_ADV_CREATE_SYNC_CANCEL, buf, NULL); if (err) { return err; } @@ -2086,8 +2037,7 @@ int bt_le_per_adv_sync_delete(struct bt_le_per_adv_sync *per_adv_sync) err = bt_le_per_adv_sync_terminate(per_adv_sync); if (!err) { - per_adv_sync_terminated(per_adv_sync, - BT_HCI_ERR_LOCALHOST_TERM_CONN); + per_adv_sync_terminated(per_adv_sync, BT_HCI_ERR_LOCALHOST_TERM_CONN); } } else if (get_pending_per_adv_sync() == per_adv_sync) { err = bt_le_per_adv_sync_create_cancel(per_adv_sync); @@ -2110,8 +2060,7 @@ int bt_le_per_adv_sync_cb_register(struct bt_le_per_adv_sync_cb *cb) return 0; } -static int bt_le_set_per_adv_recv_enable( - struct bt_le_per_adv_sync *per_adv_sync, bool enable) +static int bt_le_set_per_adv_recv_enable(struct bt_le_per_adv_sync *per_adv_sync, bool enable) { struct bt_hci_cp_le_set_per_adv_recv_enable *cp; struct bt_le_per_adv_sync_cb *listener; @@ -2132,10 +2081,8 @@ static int bt_le_set_per_adv_recv_enable( return -EINVAL; } - if ((enable && !atomic_test_bit(per_adv_sync->flags, - BT_PER_ADV_SYNC_RECV_DISABLED)) || - (!enable && atomic_test_bit(per_adv_sync->flags, - BT_PER_ADV_SYNC_RECV_DISABLED))) { + if ((enable && !atomic_test_bit(per_adv_sync->flags, BT_PER_ADV_SYNC_RECV_DISABLED)) || + (!enable && atomic_test_bit(per_adv_sync->flags, BT_PER_ADV_SYNC_RECV_DISABLED))) { return -EALREADY; } @@ -2150,18 +2097,16 @@ static int bt_le_set_per_adv_recv_enable( cp->handle = sys_cpu_to_le16(per_adv_sync->handle); cp->enable = enable ? 1 : 0; - bt_hci_cmd_state_set_init(buf, &state, per_adv_sync->flags, - BT_PER_ADV_SYNC_RECV_DISABLED, !enable); + bt_hci_cmd_state_set_init(buf, &state, per_adv_sync->flags, BT_PER_ADV_SYNC_RECV_DISABLED, + !enable); - err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_PER_ADV_RECV_ENABLE, - buf, NULL); + err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_PER_ADV_RECV_ENABLE, buf, NULL); if (err) { return err; } - info.recv_enabled = !atomic_test_bit(per_adv_sync->flags, - BT_PER_ADV_SYNC_RECV_DISABLED); + info.recv_enabled = !atomic_test_bit(per_adv_sync->flags, BT_PER_ADV_SYNC_RECV_DISABLED); SYS_SLIST_FOR_EACH_CONTAINER(&pa_sync_cbs, listener, node) { if (listener->state_changed) { @@ -2184,13 +2129,11 @@ int bt_le_per_adv_sync_recv_disable(struct bt_le_per_adv_sync *per_adv_sync) #if defined(CONFIG_BT_PER_ADV_SYNC_TRANSFER_SENDER) int bt_le_per_adv_sync_transfer(const struct bt_le_per_adv_sync *per_adv_sync, - const struct bt_conn *conn, - uint16_t service_data) + const struct bt_conn *conn, uint16_t service_data) { struct bt_hci_cp_le_per_adv_sync_transfer *cp; struct net_buf *buf; - if (!BT_FEAT_LE_EXT_PER_ADV(bt_dev.le.features)) { return -ENOTSUP; } else if (!BT_FEAT_LE_PAST_SEND(bt_dev.le.features)) { @@ -2209,18 +2152,14 @@ int bt_le_per_adv_sync_transfer(const struct bt_le_per_adv_sync *per_adv_sync, cp->sync_handle = sys_cpu_to_le16(per_adv_sync->handle); cp->service_data = sys_cpu_to_le16(service_data); - return bt_hci_cmd_send_sync(BT_HCI_OP_LE_PER_ADV_SYNC_TRANSFER, buf, - NULL); + return bt_hci_cmd_send_sync(BT_HCI_OP_LE_PER_ADV_SYNC_TRANSFER, buf, NULL); } #endif /* CONFIG_BT_PER_ADV_SYNC_TRANSFER_SENDER */ #if defined(CONFIG_BT_PER_ADV_SYNC_TRANSFER_RECEIVER) -static bool valid_past_param( - const struct bt_le_per_adv_sync_transfer_param *param) +static bool valid_past_param(const struct bt_le_per_adv_sync_transfer_param *param) { - if (param->skip > 0x01f3 || - param->timeout < 0x000A || - param->timeout > 0x4000) { + if (param->skip > 0x01f3 || param->timeout < 0x000A || param->timeout > 0x4000) { return false; } if ((param->options & BT_LE_PER_ADV_SYNC_TRANSFER_OPT_REPORTING_INITIALLY_DISABLED) && @@ -2231,11 +2170,12 @@ static bool valid_past_param( return true; } -static int past_param_set(const struct bt_conn *conn, uint8_t mode, - uint16_t skip, uint16_t timeout, uint8_t cte_type) +static int past_param_set(const struct bt_conn *conn, uint8_t mode, uint16_t skip, uint16_t timeout, + uint8_t cte_type) { struct bt_hci_cp_le_past_param *cp; struct net_buf *buf; + int err; buf = bt_hci_cmd_alloc(K_FOREVER); if (!buf) { @@ -2250,15 +2190,16 @@ static int past_param_set(const struct bt_conn *conn, uint8_t mode, cp->skip = sys_cpu_to_le16(skip); cp->timeout = sys_cpu_to_le16(timeout); cp->cte_type = cte_type; + err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_PAST_PARAM, buf, NULL); - return bt_hci_cmd_send_sync(BT_HCI_OP_LE_PAST_PARAM, buf, NULL); + return err; } -static int default_past_param_set(uint8_t mode, uint16_t skip, uint16_t timeout, - uint8_t cte_type) +static int default_past_param_set(uint8_t mode, uint16_t skip, uint16_t timeout, uint8_t cte_type) { struct bt_hci_cp_le_default_past_param *cp; struct net_buf *buf; + int err; buf = bt_hci_cmd_alloc(K_FOREVER); if (!buf) { @@ -2272,13 +2213,13 @@ static int default_past_param_set(uint8_t mode, uint16_t skip, uint16_t timeout, cp->skip = sys_cpu_to_le16(skip); cp->timeout = sys_cpu_to_le16(timeout); cp->cte_type = cte_type; + err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_DEFAULT_PAST_PARAM, buf, NULL); - return bt_hci_cmd_send_sync(BT_HCI_OP_LE_DEFAULT_PAST_PARAM, buf, NULL); + return err; } -int bt_le_per_adv_sync_transfer_subscribe( - const struct bt_conn *conn, - const struct bt_le_per_adv_sync_transfer_param *param) +int bt_le_per_adv_sync_transfer_subscribe(const struct bt_conn *conn, + const struct bt_le_per_adv_sync_transfer_param *param) { uint8_t cte_type = 0; uint8_t mode = BT_HCI_LE_PAST_MODE_SYNC; @@ -2397,15 +2338,12 @@ int bt_le_per_adv_list_add(const bt_addr_le_t *addr, uint8_t sid) bt_addr_le_copy(&cp->addr, addr); cp->sid = sid; - err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_ADD_DEV_TO_PER_ADV_LIST, buf, - NULL); + err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_ADD_DEV_TO_PER_ADV_LIST, buf, NULL); if (err) { LOG_ERR("Failed to add device to periodic advertiser list"); - - return err; } - return 0; + return err; } int bt_le_per_adv_list_remove(const bt_addr_le_t *addr, uint8_t sid) @@ -2427,8 +2365,7 @@ int bt_le_per_adv_list_remove(const bt_addr_le_t *addr, uint8_t sid) bt_addr_le_copy(&cp->addr, addr); cp->sid = sid; - err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_REM_DEV_FROM_PER_ADV_LIST, buf, - NULL); + err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_REM_DEV_FROM_PER_ADV_LIST, buf, NULL); if (err) { LOG_ERR("Failed to remove device from periodic advertiser list"); return err; @@ -2463,13 +2400,13 @@ bool bt_le_explicit_scanner_running(void) bool bt_le_explicit_scanner_uses_same_params(const struct bt_conn_le_create_param *create_param) { if (scan_state.explicit_scan_param.window != create_param->window || - scan_state.explicit_scan_param.interval != create_param->interval){ + scan_state.explicit_scan_param.interval != create_param->interval) { return false; } if (scan_state.explicit_scan_param.options & BT_LE_SCAN_OPT_CODED) { if (scan_state.explicit_scan_param.window_coded != create_param->window_coded || - scan_state.explicit_scan_param.interval_coded != create_param->interval_coded){ + scan_state.explicit_scan_param.interval_coded != create_param->interval_coded) { return false; } } From 2594859a0e3f234fba8ca7e62f2b7c25adecf3bc Mon Sep 17 00:00:00 2001 From: Gang He Date: Sun, 7 Dec 2025 23:53:05 -0800 Subject: [PATCH 0146/3659] bluetooth: host: Add parameter check when creating periodic adv sync In option of HCI_LE_Periodic_Advertising_Create_Sync, bit 2 depend on Periodic Advertising ADI Support feature. Signed-off-by: Gang He --- subsys/bluetooth/host/scan.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/subsys/bluetooth/host/scan.c b/subsys/bluetooth/host/scan.c index b4d8341771eb..53d856c9b7e7 100644 --- a/subsys/bluetooth/host/scan.c +++ b/subsys/bluetooth/host/scan.c @@ -1891,6 +1891,11 @@ int bt_le_per_adv_sync_create(const struct bt_le_per_adv_sync_param *param, return -EINVAL; } + if ((param->options & BT_LE_PER_ADV_SYNC_OPT_FILTER_DUPLICATE) != 0 && + BT_FEAT_LE_PER_ADV_ADI_SUPP(bt_dev.le.features) == 0) { + return -ENOTSUP; + } + per_adv_sync = per_adv_sync_new(); if (!per_adv_sync) { return -ENOMEM; From 9c8e72a0d92e2f98f35fa2651cebdf56908f2af0 Mon Sep 17 00:00:00 2001 From: Gang He Date: Fri, 5 Dec 2025 17:46:18 -0800 Subject: [PATCH 0147/3659] samples: bluetooth: bap_broadcast_sink: format source code Run clang-format to format sample source code. Signed-off-by: Gang He --- .../bluetooth/bap_broadcast_sink/src/main.c | 31 ++++++++----------- 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/samples/bluetooth/bap_broadcast_sink/src/main.c b/samples/bluetooth/bap_broadcast_sink/src/main.c index e15e714ec297..1f623ee1ee39 100644 --- a/samples/bluetooth/bap_broadcast_sink/src/main.c +++ b/samples/bluetooth/bap_broadcast_sink/src/main.c @@ -52,9 +52,9 @@ BUILD_ASSERT(IS_ENABLED(CONFIG_SCAN_SELF) || IS_ENABLED(CONFIG_SCAN_OFFLOAD), #endif /* CONFIG_SCAN_SELF */ #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) +#define PA_SYNC_SKIP 5 +#define NAME_LEN sizeof(CONFIG_TARGET_BROADCAST_NAME) + 1 +#define BROADCAST_DATA_ELEMENT_SIZE sizeof(int16_t) static K_SEM_DEFINE(sem_broadcast_sink_stopped, 0U, 1U); static K_SEM_DEFINE(sem_connected, 0U, 1U); @@ -404,8 +404,7 @@ static void pa_timer_handler(struct k_work *work) pa_state = BT_BAP_PA_STATE_FAILED; } - bt_bap_scan_delegator_set_pa_state(req_recv_state->src_id, - pa_state); + bt_bap_scan_delegator_set_pa_state(req_recv_state->src_id, pa_state); } printk("PA timeout\n"); @@ -438,7 +437,7 @@ static uint16_t interval_to_sync_timeout(uint16_t pa_interval) static int pa_sync_past(struct bt_conn *conn, uint16_t pa_interval) { - struct bt_le_per_adv_sync_transfer_param param = { 0 }; + struct bt_le_per_adv_sync_transfer_param param = {0}; int err; param.skip = PA_SYNC_SKIP; @@ -606,10 +605,10 @@ static int bis_sync_req_cb(struct bt_conn *conn, } /* The stream stopped callback will be called as part of this, - * and we do not need to wait for any events from the - * controller. Thus, when this returns, the `big_synced` - * is back to false. - */ + * and we do not need to wait for any events from the + * controller. Thus, when this returns, the `big_synced` + * is back to false. + */ err = bt_bap_broadcast_sink_stop(broadcast_sink); if (err != 0) { printk("Failed to stop Broadcast Sink: %d\n", err); @@ -853,7 +852,6 @@ static struct bt_le_per_adv_sync_cb bap_pa_sync_cb = { .term = bap_pa_sync_terminated_cb, }; - static int init(void) { const struct bt_pacs_register_param pacs_param = { @@ -965,8 +963,7 @@ static int start_adv(void) { const struct bt_data ad[] = { BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)), - BT_DATA_BYTES(BT_DATA_UUID16_ALL, - BT_UUID_16_ENCODE(BT_UUID_BASS_VAL), + BT_DATA_BYTES(BT_DATA_UUID16_ALL, BT_UUID_16_ENCODE(BT_UUID_BASS_VAL), BT_UUID_16_ENCODE(BT_UUID_PACS_VAL)), BT_DATA_BYTES(BT_DATA_SVC_DATA16, BT_UUID_16_ENCODE(BT_UUID_BASS_VAL)), BT_DATA(BT_DATA_NAME_COMPLETE, CONFIG_BT_DEVICE_NAME, @@ -1108,7 +1105,7 @@ static uint32_t select_bis_sync_bitfield(struct base_data *base_sg_data, /* Partial match */ printk("Channel allocation match, partial %d\n", combine_alloc); } else { - /* No action required */ + /* No action required */ } } @@ -1208,8 +1205,7 @@ int main(void) * should start scanning, or wait for PAST */ printk("Waiting for PA sync request\n"); - err = k_sem_take(&sem_pa_request, - BROADCAST_ASSISTANT_TIMEOUT); + err = k_sem_take(&sem_pa_request, BROADCAST_ASSISTANT_TIMEOUT); if (err != 0) { printk("sem_pa_request timed out, resetting\n"); continue; @@ -1230,8 +1226,7 @@ int main(void) err = bt_le_scan_start(BT_LE_SCAN_ACTIVE, NULL); if (err != 0 && err != -EALREADY) { - printk("Unable to start scan for broadcast sources: %d\n", - err); + printk("Unable to start scan for broadcast sources: %d\n", err); return 0; } From 32c1db7c15f9c797a0cf6e1cac095e1156f63f7b Mon Sep 17 00:00:00 2001 From: Gang He Date: Mon, 8 Dec 2025 17:16:44 -0800 Subject: [PATCH 0148/3659] samples: bluetooth: bap_broadcast_sink: add parameter checking BT_LE_PER_ADV_SYNC_OPT_FILTER_DUPLICATE option is only available when BT_FEAT_LE_PER_ADV_ADI_SUPP is enabled in chipset. Signed-off-by: Gang He --- .../bluetooth/bap_broadcast_sink/sample.yaml | 1 + .../bluetooth/bap_broadcast_sink/src/main.c | 26 ++++++++++++++----- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/samples/bluetooth/bap_broadcast_sink/sample.yaml b/samples/bluetooth/bap_broadcast_sink/sample.yaml index 5d06dee0bf89..e6739dc10242 100644 --- a/samples/bluetooth/bap_broadcast_sink/sample.yaml +++ b/samples/bluetooth/bap_broadcast_sink/sample.yaml @@ -9,6 +9,7 @@ tests: - qemu_x86 - nrf5340dk/nrf5340/cpuapp - nrf5340bsim/nrf5340/cpuapp + - sf32lb52_devkit_lcd/sf32lb525uc6 integration_platforms: - qemu_x86 - nrf5340dk/nrf5340/cpuapp diff --git a/samples/bluetooth/bap_broadcast_sink/src/main.c b/samples/bluetooth/bap_broadcast_sink/src/main.c index 1f623ee1ee39..0754f21a054e 100644 --- a/samples/bluetooth/bap_broadcast_sink/src/main.c +++ b/samples/bluetooth/bap_broadcast_sink/src/main.c @@ -460,7 +460,7 @@ static void recv_state_updated_cb(struct bt_conn *conn, printk("Receive state updated, pa sync state: %u, encrypt_state %u\n", recv_state->pa_sync_state, recv_state->encrypt_state); - for (uint8_t i = 0; i < recv_state->num_subgroups; i++) { + for (uint8_t i = 0U; i < recv_state->num_subgroups; i++) { printk("subgroup %d bis_sync: 0x%08x\n", i, recv_state->subgroups[i].bis_sync); } @@ -517,7 +517,7 @@ static int pa_sync_term_req_cb(struct bt_conn *conn, printk("PA sync termination req, pa sync state: %u\n", recv_state->pa_sync_state); - for (uint8_t i = 0; i < recv_state->num_subgroups; i++) { + for (uint8_t i = 0U; i < recv_state->num_subgroups; i++) { printk("subgroup %d bis_sync: 0x%08x\n", i, recv_state->subgroups[i].bis_sync); } @@ -558,7 +558,7 @@ static int bis_sync_req_cb(struct bt_conn *conn, (void)memset(requested_bis_sync, 0, sizeof(requested_bis_sync)); - for (uint8_t subgroup = 0; subgroup < recv_state->num_subgroups; subgroup++) { + for (uint8_t subgroup = 0U; subgroup < recv_state->num_subgroups; subgroup++) { printk("bis_sync_req[%u] = 0x%0x\n", subgroup, bis_sync_req[subgroup]); if (bis_sync_req[subgroup] != 0) { @@ -735,7 +735,7 @@ static bool is_substring(const char *substr, const char *str) return false; } - for (size_t pos = 0; pos < str_len; pos++) { + for (size_t pos = 0U; pos < str_len; pos++) { if (pos + sub_str_len > str_len) { return false; } @@ -1022,9 +1022,21 @@ static int stop_adv(void) static int pa_sync_create(void) { struct bt_le_per_adv_sync_param create_params = {0}; + struct bt_le_local_features feature; + int err; + + err = bt_le_get_local_features(&feature); + if (err < 0) { + printk("Failed to get local le features (err %d)\n", err); + return err; + } bt_addr_le_copy(&create_params.addr, &broadcaster_addr); - create_params.options = BT_LE_PER_ADV_SYNC_OPT_FILTER_DUPLICATE; + if (BT_FEAT_LE_PER_ADV_ADI_SUPP(feature.features)) { + create_params.options = BT_LE_PER_ADV_SYNC_OPT_FILTER_DUPLICATE; + } else { + create_params.options = BT_LE_PER_ADV_SYNC_OPT_NONE; + } create_params.sid = broadcaster_info.sid; create_params.skip = PA_SYNC_SKIP; create_params.timeout = interval_to_sync_timeout(broadcaster_info.interval); @@ -1037,7 +1049,7 @@ static uint32_t keep_n_least_significant_ones(uint32_t bitfield, uint8_t n) { uint32_t result = 0U; - for (uint8_t i = 0; i < n && bitfield != 0; i++) { + for (uint8_t i = 0U; i < n && bitfield != 0; i++) { uint32_t lsb = bitfield & -bitfield; /* extract lsb */ result |= lsb; @@ -1117,7 +1129,7 @@ static uint32_t select_bis_sync_bitfield(struct base_data *base_sg_data, #else /* !CONFIG_TARGET_BROADCAST_CHANNEL */ bool bis_sync_req_no_pref = false; - for (uint8_t i = 0; i < CONFIG_BT_BAP_BASS_MAX_SUBGROUPS; i++) { + for (uint8_t i = 0U; i < CONFIG_BT_BAP_BASS_MAX_SUBGROUPS; i++) { if (bis_sync_req[i] != 0) { if (bis_sync_req[i] == BT_BAP_BIS_SYNC_NO_PREF) { bis_sync_req_no_pref = true; From 949adae4f121ee4139a92718d526233028d362d2 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Thu, 4 Dec 2025 14:54:57 +0000 Subject: [PATCH 0149/3659] dts: vendor: nordic: Fix invalid nrf54lm20a partition layout This device indicates 4KiB sector size and has an impossible partition layout that starts part the way through a sector, this fixes the issue by having proper partition alignment Signed-off-by: Jamie McCrae --- dts/vendor/nordic/nrf54lm20a_partition.dtsi | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/dts/vendor/nordic/nrf54lm20a_partition.dtsi b/dts/vendor/nordic/nrf54lm20a_partition.dtsi index 049f87139d91..1bc6991c434a 100644 --- a/dts/vendor/nordic/nrf54lm20a_partition.dtsi +++ b/dts/vendor/nordic/nrf54lm20a_partition.dtsi @@ -21,17 +21,17 @@ slot0_partition: partition@10000 { label = "image-0"; - reg = <0x10000 DT_SIZE_K(922)>; + reg = <0x10000 DT_SIZE_K(920)>; }; - slot1_partition: partition@f6800 { + slot1_partition: partition@f6000 { label = "image-1"; - reg = <0xf6800 DT_SIZE_K(922)>; + reg = <0xf6000 DT_SIZE_K(920)>; }; - storage_partition: partition@1dd000 { + storage_partition: partition@1dc000 { label = "storage"; - reg = <0x1dd000 DT_SIZE_K(32)>; + reg = <0x1dc000 DT_SIZE_K(36)>; }; }; }; From 7703c31c98b54eff8d14c801f3caa5d7435a1e71 Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Tue, 2 Dec 2025 10:07:59 +0100 Subject: [PATCH 0150/3659] code of conduct: change the title from the template Change the Code of Conduct title from the one used in the template to reflect that this is the Code of Conduct for the Zephyr Project, not the Contributor Covenant project. The attribution for the Contributor Covenant template is present at the very last paragraph. Signed-off-by: Henrik Brix Andersen --- CODE_OF_CONDUCT.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index f81c519c7831..1bd59a4aa177 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -1,4 +1,4 @@ -# Contributor Covenant Code of Conduct +# Zephyr Project Code of Conduct ## Our Pledge From 367c859ee9dc67325ae852e66c05e3be8facbf03 Mon Sep 17 00:00:00 2001 From: Josuah Demangeon Date: Sat, 29 Nov 2025 23:27:19 +0000 Subject: [PATCH 0151/3659] usb: device_next: uvc: fix frame interval sorting The qsort() function takes a callback argument that is having the same semantics as strcmp(). Fix uvc_compare_frmival_desc() sorting to make qsort() list frame intervals in increasing values. Fix a bug where Windows would not enumerate devices when the video device have multiple frame interval supported. Signed-off-by: Josuah Demangeon --- subsys/usb/device_next/class/usbd_uvc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/usb/device_next/class/usbd_uvc.c b/subsys/usb/device_next/class/usbd_uvc.c index 2b80084079e3..91e19c003141 100644 --- a/subsys/usb/device_next/class/usbd_uvc.c +++ b/subsys/usb/device_next/class/usbd_uvc.c @@ -1498,7 +1498,7 @@ static int uvc_compare_frmival_desc(const void *const a, const void *const b) memcpy(&ia, a, sizeof(uint32_t)); memcpy(&ib, b, sizeof(uint32_t)); - return ib - ia; + return ia - ib; } static void uvc_set_vs_bitrate_range(struct uvc_frame_descriptor *const desc, From 007203965e8e3f7cc620fbd1681a0cb1960ccd03 Mon Sep 17 00:00:00 2001 From: Deepika aerlync Date: Mon, 24 Nov 2025 17:54:05 +0530 Subject: [PATCH 0152/3659] manifest: hal_infineon: update rev to latest Update hal_infineon revision to add PSOC4 family support Signed-off-by: Dharun krithik k Signed-off-by: Sayooj K Karun Signed-off-by: Deepika aerlync --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index b30ee495cb1f..82f8430b4729 100644 --- a/west.yml +++ b/west.yml @@ -185,7 +185,7 @@ manifest: groups: - hal - name: hal_infineon - revision: 26ccd68277fdb41db550fce2ffda6ab652d74ae6 + revision: e81d26f77faa419a6b2286418dbe6796c92ed18a path: modules/hal/infineon groups: - hal From 592c22f25d26bb8e288fc5c89c9f2a3b1ca621ad Mon Sep 17 00:00:00 2001 From: Deepika aerlync Date: Mon, 24 Nov 2025 17:54:09 +0530 Subject: [PATCH 0153/3659] modules: hal_infineon: add PSoC4 Kconfig support Add Kconfig configuration support for PSoC4 family in hal_infineon module. Signed-off-by: Manojkumar Konisetty Signed-off-by: Sayooj K Karun Signed-off-by: Deepika aerlync --- modules/hal_infineon/Kconfig | 4 +- modules/hal_infineon/infineon_kconfig.h | 331 ++++++++++++++++++++++++ 2 files changed, 333 insertions(+), 2 deletions(-) diff --git a/modules/hal_infineon/Kconfig b/modules/hal_infineon/Kconfig index b6b85a29d9f6..53ebfe309375 100644 --- a/modules/hal_infineon/Kconfig +++ b/modules/hal_infineon/Kconfig @@ -7,7 +7,7 @@ config ZEPHYR_HAL_INFINEON_MODULE config ZEPHYR_HAL_INFINEON_MODULE_BLOBS bool -if SOC_FAMILY_INFINEON_CAT1 || SOC_FAMILY_INFINEON_EDGE || SOC_FAMILY_PSOC6_LEGACY +if SOC_FAMILY_INFINEON_CAT1 || SOC_FAMILY_INFINEON_EDGE || SOC_FAMILY_PSOC6_LEGACY || SOC_FAMILY_INFINEON_PSOC4 config USE_INFINEON_LEGACY_HAL bool @@ -116,7 +116,7 @@ config USE_INFINEON_SMIF help Enable SMIF HAL driver for Infineon devices -endif # SOC_FAMILY_INFINEON_CAT1 || SOC_FAMILY_INFINEON_EDGE || SOC_FAMILY_PSOC6_LEGACY +endif # SOC_FAMILY_INFINEON_CAT1 || SOC_FAMILY_INFINEON_EDGE || SOC_FAMILY_PSOC6_LEGACY || SOC_FAMILY_INFINEON_PSOC4 config USE_INFINEON_ABSTRACTION_RTOS bool "Abstraction RTOS component (Zephyr support)" diff --git a/modules/hal_infineon/infineon_kconfig.h b/modules/hal_infineon/infineon_kconfig.h index 200861a2fb4c..464059d6f883 100644 --- a/modules/hal_infineon/infineon_kconfig.h +++ b/modules/hal_infineon/infineon_kconfig.h @@ -44,4 +44,335 @@ #endif /* CONFIG_CPU_CORTEXT_M33* */ #endif /* CONFIG_SOC_PSE846GPS2DBZC4A* */ +#if defined(CONFIG_SOC_SERIES_PSOC4100TP) + +/* + * Map Zephyr Kconfig selections for PSOC4 SoCs to the macros expected by the + * ModusToolbox PDL headers. We define both the bare part macro and the variant + * with a trailing underscore to retain compatibility with existing build logic. + */ + +#if defined(CONFIG_SOC_CY8C4146LQI_T403) +#ifndef CY8C4146LQI_T403 +#define CY8C4146LQI_T403 +#endif +#ifndef CY8C4146LQI_T403_ +#define CY8C4146LQI_T403_ +#endif +#endif +#if defined(CONFIG_SOC_CY8C4146AXI_T403) +#ifndef CY8C4146AXI_T403 +#define CY8C4146AXI_T403 +#endif +#ifndef CY8C4146AXI_T403_ +#define CY8C4146AXI_T403_ +#endif +#endif +#if defined(CONFIG_SOC_CY8C4146AZI_T403) +#ifndef CY8C4146AZI_T403 +#define CY8C4146AZI_T403 +#endif +#ifndef CY8C4146AZI_T403_ +#define CY8C4146AZI_T403_ +#endif +#endif +#if defined(CONFIG_SOC_CY8C4146AZI_T405) +#ifndef CY8C4146AZI_T405 +#define CY8C4146AZI_T405 +#endif +#ifndef CY8C4146AZI_T405_ +#define CY8C4146AZI_T405_ +#endif +#endif +#if defined(CONFIG_SOC_CY8C4146LQI_T413) +#ifndef CY8C4146LQI_T413 +#define CY8C4146LQI_T413 +#endif +#ifndef CY8C4146LQI_T413_ +#define CY8C4146LQI_T413_ +#endif +#endif +#if defined(CONFIG_SOC_CY8C4146AXI_T413) +#ifndef CY8C4146AXI_T413 +#define CY8C4146AXI_T413 +#endif +#ifndef CY8C4146AXI_T413_ +#define CY8C4146AXI_T413_ +#endif +#endif +#if defined(CONFIG_SOC_CY8C4146AZI_T413) +#ifndef CY8C4146AZI_T413 +#define CY8C4146AZI_T413 +#endif +#ifndef CY8C4146AZI_T413_ +#define CY8C4146AZI_T413_ +#endif +#endif +#if defined(CONFIG_SOC_CY8C4146AZI_T415) +#ifndef CY8C4146AZI_T415 +#define CY8C4146AZI_T415 +#endif +#ifndef CY8C4146AZI_T415_ +#define CY8C4146AZI_T415_ +#endif +#endif +#if defined(CONFIG_SOC_CY8C4146LQI_T453) +#ifndef CY8C4146LQI_T453 +#define CY8C4146LQI_T453 +#endif +#ifndef CY8C4146LQI_T453_ +#define CY8C4146LQI_T453_ +#endif +#endif +#if defined(CONFIG_SOC_CY8C4146AXI_T453) +#ifndef CY8C4146AXI_T453 +#define CY8C4146AXI_T453 +#endif +#ifndef CY8C4146AXI_T453_ +#define CY8C4146AXI_T453_ +#endif +#endif +#if defined(CONFIG_SOC_CY8C4146AZI_T453) +#ifndef CY8C4146AZI_T453 +#define CY8C4146AZI_T453 +#endif +#ifndef CY8C4146AZI_T453_ +#define CY8C4146AZI_T453_ +#endif +#endif +#if defined(CONFIG_SOC_CY8C4146AZI_T455) +#ifndef CY8C4146AZI_T455 +#define CY8C4146AZI_T455 +#endif +#ifndef CY8C4146AZI_T455_ +#define CY8C4146AZI_T455_ +#endif +#endif +#if defined(CONFIG_SOC_CY8C4147LQI_T403) +#ifndef CY8C4147LQI_T403 +#define CY8C4147LQI_T403 +#endif +#ifndef CY8C4147LQI_T403_ +#define CY8C4147LQI_T403_ +#endif +#endif +#if defined(CONFIG_SOC_CY8C4147AXI_T403) +#ifndef CY8C4147AXI_T403 +#define CY8C4147AXI_T403 +#endif +#ifndef CY8C4147AXI_T403_ +#define CY8C4147AXI_T403_ +#endif +#endif +#if defined(CONFIG_SOC_CY8C4147AZI_T403) +#ifndef CY8C4147AZI_T403 +#define CY8C4147AZI_T403 +#endif +#ifndef CY8C4147AZI_T403_ +#define CY8C4147AZI_T403_ +#endif +#endif +#if defined(CONFIG_SOC_CY8C4147AZI_T405) +#ifndef CY8C4147AZI_T405 +#define CY8C4147AZI_T405 +#endif +#ifndef CY8C4147AZI_T405_ +#define CY8C4147AZI_T405_ +#endif +#endif +#if defined(CONFIG_SOC_CY8C4147LQI_T413) +#ifndef CY8C4147LQI_T413 +#define CY8C4147LQI_T413 +#endif +#ifndef CY8C4147LQI_T413_ +#define CY8C4147LQI_T413_ +#endif +#endif +#if defined(CONFIG_SOC_CY8C4147AXI_T413) +#ifndef CY8C4147AXI_T413 +#define CY8C4147AXI_T413 +#endif +#ifndef CY8C4147AXI_T413_ +#define CY8C4147AXI_T413_ +#endif +#endif +#if defined(CONFIG_SOC_CY8C4147AZI_T413) +#ifndef CY8C4147AZI_T413 +#define CY8C4147AZI_T413 +#endif +#ifndef CY8C4147AZI_T413_ +#define CY8C4147AZI_T413_ +#endif +#endif +#if defined(CONFIG_SOC_CY8C4147AZI_T415) +#ifndef CY8C4147AZI_T415 +#define CY8C4147AZI_T415 +#endif +#ifndef CY8C4147AZI_T415_ +#define CY8C4147AZI_T415_ +#endif +#endif +#if defined(CONFIG_SOC_CY8C4147LQI_T453) +#ifndef CY8C4147LQI_T453 +#define CY8C4147LQI_T453 +#endif +#ifndef CY8C4147LQI_T453_ +#define CY8C4147LQI_T453_ +#endif +#endif +#if defined(CONFIG_SOC_CY8C4147AXI_T453) +#ifndef CY8C4147AXI_T453 +#define CY8C4147AXI_T453 +#endif +#ifndef CY8C4147AXI_T453_ +#define CY8C4147AXI_T453_ +#endif +#endif +#if defined(CONFIG_SOC_CY8C4147AZI_T453) +#ifndef CY8C4147AZI_T453 +#define CY8C4147AZI_T453 +#endif +#ifndef CY8C4147AZI_T453_ +#define CY8C4147AZI_T453_ +#endif +#endif +#if defined(CONFIG_SOC_CY8C4147AZI_T455) +#ifndef CY8C4147AZI_T455 +#define CY8C4147AZI_T455 +#endif +#ifndef CY8C4147AZI_T455_ +#define CY8C4147AZI_T455_ +#endif +#endif +#if defined(CONFIG_SOC_CY8C4147LQI_T463) +#ifndef CY8C4147LQI_T463 +#define CY8C4147LQI_T463 +#endif +#ifndef CY8C4147LQI_T463_ +#define CY8C4147LQI_T463_ +#endif +#endif +#if defined(CONFIG_SOC_CY8C4147AXI_T463) +#ifndef CY8C4147AXI_T463 +#define CY8C4147AXI_T463 +#endif +#ifndef CY8C4147AXI_T463_ +#define CY8C4147AXI_T463_ +#endif +#endif +#if defined(CONFIG_SOC_CY8C4147AZI_T463) +#ifndef CY8C4147AZI_T463 +#define CY8C4147AZI_T463 +#endif +#ifndef CY8C4147AZI_T463_ +#define CY8C4147AZI_T463_ +#endif +#endif +#if defined(CONFIG_SOC_CY8C4147AZI_T465) +#ifndef CY8C4147AZI_T465 +#define CY8C4147AZI_T465 +#endif +#ifndef CY8C4147AZI_T465_ +#define CY8C4147AZI_T465_ +#endif +#endif +#if defined(CONFIG_SOC_CY8C4147LQI_T473) +#ifndef CY8C4147LQI_T473 +#define CY8C4147LQI_T473 +#endif +#ifndef CY8C4147LQI_T473_ +#define CY8C4147LQI_T473_ +#endif +#endif +#if defined(CONFIG_SOC_CY8C4147AXI_T473) +#ifndef CY8C4147AXI_T473 +#define CY8C4147AXI_T473 +#endif +#ifndef CY8C4147AXI_T473_ +#define CY8C4147AXI_T473_ +#endif +#endif +#if defined(CONFIG_SOC_CY8C4147AZI_T473) +#ifndef CY8C4147AZI_T473 +#define CY8C4147AZI_T473 +#endif +#ifndef CY8C4147AZI_T473_ +#define CY8C4147AZI_T473_ +#endif +#endif +#if defined(CONFIG_SOC_CY8C4147AZI_T475) +#ifndef CY8C4147AZI_T475 +#define CY8C4147AZI_T475 +#endif +#ifndef CY8C4147AZI_T475_ +#define CY8C4147AZI_T475_ +#endif +#endif +#if defined(CONFIG_SOC_CY8C4147LQQ_T493) +#ifndef CY8C4147LQQ_T493 +#define CY8C4147LQQ_T493 +#endif +#ifndef CY8C4147LQQ_T493_ +#define CY8C4147LQQ_T493_ +#endif +#endif +#if defined(CONFIG_SOC_CY8C4147AXQ_T493) +#ifndef CY8C4147AXQ_T493 +#define CY8C4147AXQ_T493 +#endif +#ifndef CY8C4147AXQ_T493_ +#define CY8C4147AXQ_T493_ +#endif +#endif +#if defined(CONFIG_SOC_CY8C4147AZQ_T493) +#ifndef CY8C4147AZQ_T493 +#define CY8C4147AZQ_T493 +#endif +#ifndef CY8C4147AZQ_T493_ +#define CY8C4147AZQ_T493_ +#endif +#endif +#if defined(CONFIG_SOC_CY8C4147AZQ_T495) +#ifndef CY8C4147AZQ_T495 +#define CY8C4147AZQ_T495 +#endif +#ifndef CY8C4147AZQ_T495_ +#define CY8C4147AZQ_T495_ +#endif +#endif +#if defined(CONFIG_SOC_CY8C4146AZQ_T413) +#ifndef CY8C4146AZQ_T413 +#define CY8C4146AZQ_T413 +#endif +#ifndef CY8C4146AZQ_T413_ +#define CY8C4146AZQ_T413_ +#endif +#endif +#if defined(CONFIG_SOC_CY8C4146AZQ_T453) +#ifndef CY8C4146AZQ_T453 +#define CY8C4146AZQ_T453 +#endif +#ifndef CY8C4146AZQ_T453_ +#define CY8C4146AZQ_T453_ +#endif +#endif +#if defined(CONFIG_SOC_CY8C4147AZQ_T415) +#ifndef CY8C4147AZQ_T415 +#define CY8C4147AZQ_T415 +#endif +#ifndef CY8C4147AZQ_T415_ +#define CY8C4147AZQ_T415_ +#endif +#endif +#if defined(CONFIG_SOC_CY8C4147AZQ_T455) +#ifndef CY8C4147AZQ_T455 +#define CY8C4147AZQ_T455 +#endif +#ifndef CY8C4147AZQ_T455_ +#define CY8C4147AZQ_T455_ +#endif +#endif + +#endif /* CONFIG_SOC_SERIES_PSOC4100TP */ + #endif /* INFINEON_KCONFIG_H__ */ From 0add918ec9a377284afd1179fc608c385a8ed370 Mon Sep 17 00:00:00 2001 From: Deepika aerlync Date: Mon, 24 Nov 2025 17:54:12 +0530 Subject: [PATCH 0154/3659] modules: hal_infineon: add PSoC4 build support Add CMake build configuration support for PSoC4 PDL and templates. Signed-off-by: Manojkumar Konisetty Signed-off-by: Sayooj K Karun Signed-off-by: Deepika aerlync --- modules/hal_infineon/CMakeLists.txt | 17 ++++- .../hal_infineon/mtb-pdl-cat2/CMakeLists.txt | 70 +++++++++++++++++++ .../mtb-pdl-cat2/include/cy_device_headers.h | 24 +++++++ .../mtb-template-cat2/CMakeLists.txt | 12 ++++ 4 files changed, 122 insertions(+), 1 deletion(-) create mode 100644 modules/hal_infineon/mtb-pdl-cat2/CMakeLists.txt create mode 100644 modules/hal_infineon/mtb-pdl-cat2/include/cy_device_headers.h create mode 100644 modules/hal_infineon/mtb-template-cat2/CMakeLists.txt diff --git a/modules/hal_infineon/CMakeLists.txt b/modules/hal_infineon/CMakeLists.txt index f4d2c6bc0545..397b72c51c13 100644 --- a/modules/hal_infineon/CMakeLists.txt +++ b/modules/hal_infineon/CMakeLists.txt @@ -5,7 +5,8 @@ if(CONFIG_HAS_XMCLIB OR CONFIG_SOC_FAMILY_PSOC6_LEGACY OR CONFIG_SOC_FAMILY_INFINEON_CAT1 - OR CONFIG_SOC_FAMILY_INFINEON_EDGE) + OR CONFIG_SOC_FAMILY_INFINEON_EDGE + OR CONFIG_SOC_FAMILY_INFINEON_PSOC4) zephyr_library_named(modules_hal_infineon) zephyr_library_compile_options($) @@ -98,3 +99,17 @@ endif() if(CONFIG_BT_PSOC6_BLESS) add_subdirectory(bless) endif() + +if(CONFIG_SOC_FAMILY_INFINEON_PSOC4) + ## Add core-lib sources for PSCO4 devices + add_subdirectory(core-lib) + + ## Add mtb-pdl-cat2 sources for PSCO4 devices + add_subdirectory(mtb-pdl-cat2) + + ## Add mtb-template-cat2 sources for PSCO4 devices + add_subdirectory(mtb-template-cat2) + + ## Add abstraction-rtos sources + add_subdirectory(abstraction-rtos) +endif() diff --git a/modules/hal_infineon/mtb-pdl-cat2/CMakeLists.txt b/modules/hal_infineon/mtb-pdl-cat2/CMakeLists.txt new file mode 100644 index 000000000000..4b25873ccbfe --- /dev/null +++ b/modules/hal_infineon/mtb-pdl-cat2/CMakeLists.txt @@ -0,0 +1,70 @@ +# Copyright (c) 2025 Infineon Technologies AG, +# or an affiliate of Infineon Technologies AG. +# +# SPDX-License-Identifier: Apache-2.0 + +# Infineon PSoC4100tp / PSCO4 MCUs + +# PDL directories +set(pdl_dir ${ZEPHYR_HAL_INFINEON_MODULE_DIR}/mtb-pdl-cat2) +set(pdl_drv_dir ${pdl_dir}/drivers) +set(pdl_dev_dir ${pdl_dir}/devices) + +# Generate PDL specific SOC defines +zephyr_library_compile_definitions(CONFIG_SOC_PART_NUMBER) +zephyr_library_compile_definitions($) +zephyr_library_compile_definitions(${CONFIG_SOC_PART_NUMBER}_device) + +# Include directories +# Add HAL wrapper include directory first so cy_device_headers.h wrapper is found +# before the PDL version. The wrapper includes infineon_kconfig.h before +# the actual PDL cy_device_headers.h, ensuring part number macros are available. +zephyr_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) +zephyr_include_directories(${pdl_drv_dir}/include) +zephyr_include_directories(${pdl_dev_dir}/include) +zephyr_include_directories(${pdl_dev_dir}/include/ip) +zephyr_include_directories(${ZEPHYR_HAL_INFINEON_MODULE_DIR}/core-lib/include) + +# Tool Chain +zephyr_library_sources(${pdl_drv_dir}/source/COMPONENT_CM0P/TOOLCHAIN_GCC_ARM/cy_syslib_gcc.S) + +# Peripheral drivers +zephyr_library_sources_ifdef(CONFIG_USE_INFINEON_ADC ${pdl_drv_dir}/source/cy_sar.c) +zephyr_library_sources_ifdef(CONFIG_USE_INFINEON_I2C ${pdl_drv_dir}/source/cy_scb_i2c.c) +zephyr_library_sources_ifdef(CONFIG_USE_INFINEON_SPI ${pdl_drv_dir}/source/cy_scb_spi.c) +zephyr_library_sources_ifdef(CONFIG_USE_INFINEON_TIMER ${pdl_drv_dir}/source/cy_tcpwm_counter.c) +zephyr_library_sources_ifdef(CONFIG_USE_INFINEON_UART ${pdl_drv_dir}/source/cy_scb_uart.c) +zephyr_library_sources_ifdef(CONFIG_USE_INFINEON_FLASH ${pdl_drv_dir}/source/cy_flash.c) +zephyr_library_sources_ifdef(CONFIG_USE_INFINEON_PWM ${pdl_drv_dir}/source/cy_tcpwm_pwm.c) + +# TRNG / Crypto +if(CONFIG_USE_INFINEON_TRNG) + zephyr_library_sources(${pdl_drv_dir}/source/cy_crypto_trng.c) + zephyr_library_sources(${pdl_drv_dir}/source/cy_cryptolite_trng.c) +endif() + +# SCB common sources (I2C/SPI/UART) +if(CONFIG_USE_INFINEON_UART OR CONFIG_USE_INFINEON_I2C OR CONFIG_USE_INFINEON_SPI) + zephyr_library_sources(${pdl_drv_dir}/source/cy_scb_common.c) +endif() + +# DMA +if(CONFIG_USE_INFINEON_DMA OR CONFIG_USE_INFINEON_ADC) + zephyr_library_sources(${pdl_drv_dir}/source/cy_dmac.c) +endif() + +# Watch Dog Timer +if(CONFIG_USE_INFINEON_WDT) + zephyr_library_sources(${pdl_drv_dir}/source/cy_wdt.c) + zephyr_library_sources(${pdl_drv_dir}/source/cy_crwdt.c) +endif() + +# Common part +zephyr_library_sources(${pdl_drv_dir}/source/cy_gpio.c) +zephyr_library_sources(${pdl_drv_dir}/source/cy_sysclk.c) +zephyr_library_sources(${pdl_drv_dir}/source/cy_syspm.c) +zephyr_library_sources(${pdl_drv_dir}/source/cy_syslib.c) +zephyr_library_sources(${pdl_drv_dir}/source/cy_trigmux.c) +zephyr_library_sources(${pdl_drv_dir}/source/cy_sysint.c) +zephyr_library_sources(${pdl_drv_dir}/source/cy_flash.c) +zephyr_library_sources(${pdl_drv_dir}/source/cy_ram.c) diff --git a/modules/hal_infineon/mtb-pdl-cat2/include/cy_device_headers.h b/modules/hal_infineon/mtb-pdl-cat2/include/cy_device_headers.h new file mode 100644 index 000000000000..9709450b1cee --- /dev/null +++ b/modules/hal_infineon/mtb-pdl-cat2/include/cy_device_headers.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef HAL_INFINEON_MTB_PDL_CAT2_CY_DEVICE_HEADERS_H_ +#define HAL_INFINEON_MTB_PDL_CAT2_CY_DEVICE_HEADERS_H_ + +/* This wrapper ensures infineon_kconfig.h is included before + * the PDL cy_device_headers.h, providing the part number macros + * required by the PDL headers. This header is placed in the HAL + * include path before the PDL include path, so it shadows the + * PDL header and ensures the kconfig mapping is always available. + */ +#include + +/* Include the actual PDL header using #include_next to bypass this wrapper + * and get the real cy_device_headers.h from the devices/include directory. + */ +#include_next + +#endif /* HAL_INFINEON_MTB_PDL_CAT2_CY_DEVICE_HEADERS_H_ */ diff --git a/modules/hal_infineon/mtb-template-cat2/CMakeLists.txt b/modules/hal_infineon/mtb-template-cat2/CMakeLists.txt new file mode 100644 index 000000000000..963aa2f60c1c --- /dev/null +++ b/modules/hal_infineon/mtb-template-cat2/CMakeLists.txt @@ -0,0 +1,12 @@ +# Copyright (c) 2025 Infineon Technologies AG, +# or an affiliate of Infineon Technologies AG. +# +# SPDX-License-Identifier: Apache-2.0 + +set(template_dir ${ZEPHYR_HAL_INFINEON_MODULE_DIR}/mtb-template-cat2) +set(psoc4_dir ${template_dir}/files/templates) + +if(CONFIG_SOC_FAMILY_INFINEON_PSOC4) + zephyr_include_directories(${psoc4_dir}/COMPONENT_MTB) + zephyr_library_sources(${psoc4_dir}/COMPONENT_MTB/system_cat2.c) +endif() From 977f3f10ac0140250597a55f89b6c13dbb66c757 Mon Sep 17 00:00:00 2001 From: Deepika aerlync Date: Mon, 24 Nov 2025 17:54:16 +0530 Subject: [PATCH 0155/3659] dts: arm: infineon: add PSoC4100TP base devicetree Add base devicetree support for Infineon PSoC4100TP series including: - Core SoC devicetree (psoc4100tp.dtsi) - CM0+ core configuration (psoc4100tp.cm0p.dtsi) - Pin package variants (44-TQFP, 48-QFN, 48-TQFP, 64-TQFP) - System clocks configuration (system_clocks.dtsi) Signed-off-by: Manojkumar Konisetty Signed-off-by: Sayooj K Karun Signed-off-by: Deepika aerlync --- .../psoc4/psoc4100tp/psoc4100tp.44-tqfp.dtsi | 550 +++++++++++++++ .../psoc4/psoc4100tp/psoc4100tp.48-qfn.dtsi | 641 ++++++++++++++++++ .../psoc4/psoc4100tp/psoc4100tp.48-tqfp.dtsi | 641 ++++++++++++++++++ .../psoc4/psoc4100tp/psoc4100tp.64-tqfp.dtsi | 148 ++++ .../psoc4/psoc4100tp/psoc4100tp.cm0p.dtsi | 40 ++ .../infineon/psoc4/psoc4100tp/psoc4100tp.dtsi | 252 +++++++ .../psoc4/psoc4100tp/system_clocks.dtsi | 271 ++++++++ 7 files changed, 2543 insertions(+) create mode 100644 dts/arm/infineon/psoc4/psoc4100tp/psoc4100tp.44-tqfp.dtsi create mode 100644 dts/arm/infineon/psoc4/psoc4100tp/psoc4100tp.48-qfn.dtsi create mode 100644 dts/arm/infineon/psoc4/psoc4100tp/psoc4100tp.48-tqfp.dtsi create mode 100644 dts/arm/infineon/psoc4/psoc4100tp/psoc4100tp.64-tqfp.dtsi create mode 100644 dts/arm/infineon/psoc4/psoc4100tp/psoc4100tp.cm0p.dtsi create mode 100644 dts/arm/infineon/psoc4/psoc4100tp/psoc4100tp.dtsi create mode 100644 dts/arm/infineon/psoc4/psoc4100tp/system_clocks.dtsi diff --git a/dts/arm/infineon/psoc4/psoc4100tp/psoc4100tp.44-tqfp.dtsi b/dts/arm/infineon/psoc4/psoc4100tp/psoc4100tp.44-tqfp.dtsi new file mode 100644 index 000000000000..9ee2d4a0a037 --- /dev/null +++ b/dts/arm/infineon/psoc4/psoc4100tp/psoc4100tp.44-tqfp.dtsi @@ -0,0 +1,550 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "psoc4100tp.dtsi" + +/ { + soc { + /delete-node/ gpio@40040500; /* gpio_prt5 */ + /delete-node/ gpio@40040600; /* gpio_prt6 */ + + pinctrl: pinctrl@40020000 { + /* scb_i2c_scl */ + /omit-if-no-ref/ p0_0_scb0_i2c_scl: p0_0_scb0_i2c_scl { + pinmux = ; + }; + + /omit-if-no-ref/ p1_4_scb1_i2c_scl: p1_4_scb1_i2c_scl { + pinmux = ; + }; + + /omit-if-no-ref/ p2_0_scb0_i2c_scl: p2_0_scb0_i2c_scl { + pinmux = ; + }; + + /omit-if-no-ref/ p3_3_scb0_i2c_scl: p3_3_scb0_i2c_scl { + pinmux = ; + }; + + /omit-if-no-ref/ p4_0_scb1_i2c_scl: p4_0_scb1_i2c_scl { + pinmux = ; + }; + + /* scb_i2c_sda */ + /omit-if-no-ref/ p0_1_scb0_i2c_sda: p0_1_scb0_i2c_sda { + pinmux = ; + }; + + /omit-if-no-ref/ p1_5_scb1_i2c_sda: p1_5_scb1_i2c_sda { + pinmux = ; + }; + + /omit-if-no-ref/ p2_1_scb0_i2c_sda: p2_1_scb0_i2c_sda { + pinmux = ; + }; + + /omit-if-no-ref/ p3_2_scb0_i2c_sda: p3_2_scb0_i2c_sda { + pinmux = ; + }; + + /omit-if-no-ref/ p4_1_scb1_i2c_sda: p4_1_scb1_i2c_sda { + pinmux = ; + }; + + /* scb_spi_m_clk */ + /omit-if-no-ref/ p0_6_scb0_spi_m_clk: p0_6_scb0_spi_m_clk { + pinmux = ; + }; + + /omit-if-no-ref/ p1_7_scb1_spi_m_clk: p1_7_scb1_spi_m_clk { + pinmux = ; + }; + + /omit-if-no-ref/ p2_6_scb0_spi_m_clk: p2_6_scb0_spi_m_clk { + pinmux = ; + }; + + /omit-if-no-ref/ p4_6_scb1_spi_m_clk: p4_6_scb1_spi_m_clk { + pinmux = ; + }; + + /* scb_spi_m_miso */ + /omit-if-no-ref/ p0_5_scb0_spi_m_miso: p0_5_scb0_spi_m_miso { + pinmux = ; + }; + + /omit-if-no-ref/ p1_6_scb1_spi_m_miso: p1_6_scb1_spi_m_miso { + pinmux = ; + }; + + /omit-if-no-ref/ p2_5_scb0_spi_m_miso: p2_5_scb0_spi_m_miso { + pinmux = ; + }; + + /omit-if-no-ref/ p4_5_scb1_spi_m_miso: p4_5_scb1_spi_m_miso { + pinmux = ; + }; + + /* scb_spi_m_mosi */ + /omit-if-no-ref/ p0_4_scb0_spi_m_mosi: p0_4_scb0_spi_m_mosi { + pinmux = ; + }; + + /omit-if-no-ref/ p1_5_scb1_spi_m_mosi: p1_5_scb1_spi_m_mosi { + pinmux = ; + }; + + /omit-if-no-ref/ p2_4_scb0_spi_m_mosi: p2_4_scb0_spi_m_mosi { + pinmux = ; + }; + + /omit-if-no-ref/ p4_4_scb1_spi_m_mosi: p4_4_scb1_spi_m_mosi { + pinmux = ; + }; + + /* scb_spi_m_select0 */ + /omit-if-no-ref/ p0_0_scb0_spi_m_select0: p0_0_scb0_spi_m_select0 { + pinmux = ; + }; + + /omit-if-no-ref/ p1_3_scb1_spi_m_select0: p1_3_scb1_spi_m_select0 { + pinmux = ; + }; + + /omit-if-no-ref/ p2_0_scb0_spi_m_select0: p2_0_scb0_spi_m_select0 { + pinmux = ; + }; + + /omit-if-no-ref/ p4_0_scb1_spi_m_select0: p4_0_scb1_spi_m_select0 { + pinmux = ; + }; + + /* scb_spi_m_select1 */ + /omit-if-no-ref/ p0_1_scb0_spi_m_select1: p0_1_scb0_spi_m_select1 { + pinmux = ; + }; + + /omit-if-no-ref/ p1_4_scb1_spi_m_select1: p1_4_scb1_spi_m_select1 { + pinmux = ; + }; + + /omit-if-no-ref/ p2_1_scb0_spi_m_select1: p2_1_scb0_spi_m_select1 { + pinmux = ; + }; + + /omit-if-no-ref/ p3_1_scb0_spi_m_select1: p3_1_scb0_spi_m_select1 { + pinmux = ; + }; + + /omit-if-no-ref/ p4_1_scb1_spi_m_select1: p4_1_scb1_spi_m_select1 { + pinmux = ; + }; + + /* scb_spi_m_select2 */ + /omit-if-no-ref/ p0_2_scb0_spi_m_select2: p0_2_scb0_spi_m_select2 { + pinmux = ; + }; + + /omit-if-no-ref/ p2_2_scb0_spi_m_select2: p2_2_scb0_spi_m_select2 { + pinmux = ; + }; + + /omit-if-no-ref/ p3_2_scb0_spi_m_select2: p3_2_scb0_spi_m_select2 { + pinmux = ; + }; + + /omit-if-no-ref/ p4_2_scb1_spi_m_select2: p4_2_scb1_spi_m_select2 { + pinmux = ; + }; + + /* scb_spi_m_select3 */ + /omit-if-no-ref/ p0_3_scb0_spi_m_select3: p0_3_scb0_spi_m_select3 { + pinmux = ; + }; + + /omit-if-no-ref/ p2_3_scb0_spi_m_select3: p2_3_scb0_spi_m_select3 { + pinmux = ; + }; + + /omit-if-no-ref/ p3_3_scb0_spi_m_select3: p3_3_scb0_spi_m_select3 { + pinmux = ; + }; + + /omit-if-no-ref/ p4_3_scb1_spi_m_select3: p4_3_scb1_spi_m_select3 { + pinmux = ; + }; + + /* scb_spi_s_clk */ + /omit-if-no-ref/ p0_6_scb0_spi_s_clk: p0_6_scb0_spi_s_clk { + pinmux = ; + }; + + /omit-if-no-ref/ p1_7_scb1_spi_s_clk: p1_7_scb1_spi_s_clk { + pinmux = ; + }; + + /omit-if-no-ref/ p2_6_scb0_spi_s_clk: p2_6_scb0_spi_s_clk { + pinmux = ; + }; + + /omit-if-no-ref/ p4_6_scb1_spi_s_clk: p4_6_scb1_spi_s_clk { + pinmux = ; + }; + + /* scb_spi_s_miso */ + /omit-if-no-ref/ p0_5_scb0_spi_s_miso: p0_5_scb0_spi_s_miso { + pinmux = ; + }; + + /omit-if-no-ref/ p1_6_scb1_spi_s_miso: p1_6_scb1_spi_s_miso { + pinmux = ; + }; + + /omit-if-no-ref/ p2_5_scb0_spi_s_miso: p2_5_scb0_spi_s_miso { + pinmux = ; + }; + + /omit-if-no-ref/ p4_5_scb1_spi_s_miso: p4_5_scb1_spi_s_miso { + pinmux = ; + }; + + /* scb_spi_s_mosi */ + /omit-if-no-ref/ p0_4_scb0_spi_s_mosi: p0_4_scb0_spi_s_mosi { + pinmux = ; + }; + + /omit-if-no-ref/ p1_5_scb1_spi_s_mosi: p1_5_scb1_spi_s_mosi { + pinmux = ; + }; + + /omit-if-no-ref/ p2_4_scb0_spi_s_mosi: p2_4_scb0_spi_s_mosi { + pinmux = ; + }; + + /omit-if-no-ref/ p4_4_scb1_spi_s_mosi: p4_4_scb1_spi_s_mosi { + pinmux = ; + }; + + /* scb_spi_s_select0 */ + /omit-if-no-ref/ p0_0_scb0_spi_s_select0: p0_0_scb0_spi_s_select0 { + pinmux = ; + }; + + /omit-if-no-ref/ p1_3_scb1_spi_s_select0: p1_3_scb1_spi_s_select0 { + pinmux = ; + }; + + /omit-if-no-ref/ p2_0_scb0_spi_s_select0: p2_0_scb0_spi_s_select0 { + pinmux = ; + }; + + /omit-if-no-ref/ p4_0_scb1_spi_s_select0: p4_0_scb1_spi_s_select0 { + pinmux = ; + }; + + /* scb_spi_s_select1 */ + /omit-if-no-ref/ p0_1_scb0_spi_s_select1: p0_1_scb0_spi_s_select1 { + pinmux = ; + }; + + /omit-if-no-ref/ p1_4_scb1_spi_s_select1: p1_4_scb1_spi_s_select1 { + pinmux = ; + }; + + /omit-if-no-ref/ p2_1_scb0_spi_s_select1: p2_1_scb0_spi_s_select1 { + pinmux = ; + }; + + /omit-if-no-ref/ p3_1_scb0_spi_s_select1: p3_1_scb0_spi_s_select1 { + pinmux = ; + }; + + /omit-if-no-ref/ p4_1_scb1_spi_s_select1: p4_1_scb1_spi_s_select1 { + pinmux = ; + }; + + /* scb_spi_s_select2 */ + /omit-if-no-ref/ p0_2_scb0_spi_s_select2: p0_2_scb0_spi_s_select2 { + pinmux = ; + }; + + /omit-if-no-ref/ p2_2_scb0_spi_s_select2: p2_2_scb0_spi_s_select2 { + pinmux = ; + }; + + /omit-if-no-ref/ p3_2_scb0_spi_s_select2: p3_2_scb0_spi_s_select2 { + pinmux = ; + }; + + /omit-if-no-ref/ p4_2_scb1_spi_s_select2: p4_2_scb1_spi_s_select2 { + pinmux = ; + }; + + /* scb_spi_s_select3 */ + /omit-if-no-ref/ p0_3_scb0_spi_s_select3: p0_3_scb0_spi_s_select3 { + pinmux = ; + }; + + /omit-if-no-ref/ p2_3_scb0_spi_s_select3: p2_3_scb0_spi_s_select3 { + pinmux = ; + }; + + /omit-if-no-ref/ p3_3_scb0_spi_s_select3: p3_3_scb0_spi_s_select3 { + pinmux = ; + }; + + /omit-if-no-ref/ p4_3_scb1_spi_s_select3: p4_3_scb1_spi_s_select3 { + pinmux = ; + }; + + /* scb_uart_cts */ + /omit-if-no-ref/ p0_2_scb0_uart_cts: p0_2_scb0_uart_cts { + pinmux = ; + }; + + /omit-if-no-ref/ p1_6_scb1_uart_cts: p1_6_scb1_uart_cts { + pinmux = ; + }; + + /omit-if-no-ref/ p2_2_scb2_uart_cts: p2_2_scb2_uart_cts { + pinmux = ; + }; + + /omit-if-no-ref/ p2_6_scb3_uart_cts: p2_6_scb3_uart_cts { + pinmux = ; + }; + + /omit-if-no-ref/ p4_2_scb4_uart_cts: p4_2_scb4_uart_cts { + pinmux = ; + }; + + /* scb_uart_rts */ + /omit-if-no-ref/ p0_3_scb0_uart_rts: p0_3_scb0_uart_rts { + pinmux = ; + }; + + /omit-if-no-ref/ p1_7_scb1_uart_rts: p1_7_scb1_uart_rts { + pinmux = ; + }; + + /omit-if-no-ref/ p2_3_scb2_uart_rts: p2_3_scb2_uart_rts { + pinmux = ; + }; + + /omit-if-no-ref/ p2_7_scb3_uart_rts: p2_7_scb3_uart_rts { + pinmux = ; + }; + + /omit-if-no-ref/ p3_1_scb3_uart_rts: p3_1_scb3_uart_rts { + pinmux = ; + }; + + /omit-if-no-ref/ p4_3_scb4_uart_rts: p4_3_scb4_uart_rts { + pinmux = ; + }; + + /* scb_uart_rx */ + /omit-if-no-ref/ p0_0_scb0_uart_rx: p0_0_scb0_uart_rx { + pinmux = ; + }; + + /omit-if-no-ref/ p1_4_scb1_uart_rx: p1_4_scb1_uart_rx { + pinmux = ; + }; + + /omit-if-no-ref/ p2_0_scb2_uart_rx: p2_0_scb2_uart_rx { + pinmux = ; + }; + + /omit-if-no-ref/ p2_4_scb3_uart_rx: p2_4_scb3_uart_rx { + pinmux = ; + }; + + /omit-if-no-ref/ p3_2_scb3_uart_rx: p3_2_scb3_uart_rx { + pinmux = ; + }; + + /omit-if-no-ref/ p4_0_scb4_uart_rx: p4_0_scb4_uart_rx { + pinmux = ; + }; + + /* scb_uart_tx */ + /omit-if-no-ref/ p0_1_scb0_uart_tx: p0_1_scb0_uart_tx { + pinmux = ; + }; + + /omit-if-no-ref/ p1_5_scb1_uart_tx: p1_5_scb1_uart_tx { + pinmux = ; + }; + + /omit-if-no-ref/ p2_1_scb2_uart_tx: p2_1_scb2_uart_tx { + pinmux = ; + }; + + /omit-if-no-ref/ p2_5_scb3_uart_tx: p2_5_scb3_uart_tx { + pinmux = ; + }; + + /omit-if-no-ref/ p3_3_scb3_uart_tx: p3_3_scb3_uart_tx { + pinmux = ; + }; + + /omit-if-no-ref/ p4_1_scb4_uart_tx: p4_1_scb4_uart_tx { + pinmux = ; + }; + + /* PWM tcpwm_line*/ + /omit-if-no-ref/ p0_0_pwm0_0: p0_0_pwm0_0 { + pinmux = ; + }; + + /omit-if-no-ref/ p0_6_pwm0_1: p0_6_pwm0_1 { + pinmux = ; + }; + + /omit-if-no-ref/ p2_0_pwm0_2: p2_0_pwm0_2 { + pinmux = ; + }; + + /omit-if-no-ref/ p2_2_pwm0_3: p2_2_pwm0_3 { + pinmux = ; + }; + + /omit-if-no-ref/ p2_4_pwm0_4: p2_4_pwm0_4 { + pinmux = ; + }; + + /omit-if-no-ref/ p2_6_pwm0_5: p2_6_pwm0_5 { + pinmux = ; + }; + + /omit-if-no-ref/ p3_1_pwm0_0: p3_1_pwm0_0 { + pinmux = ; + }; + + /omit-if-no-ref/ p4_0_pwm0_1: p4_0_pwm0_1 { + pinmux = ; + }; + + /omit-if-no-ref/ p4_2_pwm0_2: p4_2_pwm0_2 { + pinmux = ; + }; + + /omit-if-no-ref/ p4_4_pwm0_3: p4_4_pwm0_3 { + pinmux = ; + }; + + /omit-if-no-ref/ p4_6_pwm0_4: p4_6_pwm0_4 { + pinmux = ; + }; + + /* PWM tcpwm_line_compl*/ + /omit-if-no-ref/ p0_1_pwm0_0: p0_1_pwm0_0_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p0_7_pwm0_1: p0_7_pwm0_1_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p2_1_pwm0_2: p2_1_pwm0_2_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p2_3_pwm0_3: p2_3_pwm0_3_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p2_5_pwm0_4: p2_5_pwm0_4_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p2_7_pwm0_5: p2_7_pwm0_5_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p3_2_pwm0_0: p3_2_pwm0_0_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p4_1_pwm0_1: p4_1_pwm0_1_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p4_3_pwm0_2: p4_3_pwm0_2_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p4_5_pwm0_3: p4_5_pwm0_3_compl { + pinmux = ; + }; + + /* PWM tcpwm_tr_in*/ + /omit-if-no-ref/ p0_1_pwm0_1: p0_1_pwm0_1 { + pinmux = ; + }; + + /omit-if-no-ref/ p1_4_pwm0_2: p1_4_pwm0_2 { + pinmux = ; + }; + + /omit-if-no-ref/ p1_5_pwm0_3: p1_5_pwm0_3 { + pinmux = ; + }; + + /omit-if-no-ref/ p2_0_pwm0_4: p2_0_pwm0_4 { + pinmux = ; + }; + + /omit-if-no-ref/ p2_1_pwm0_5: p2_1_pwm0_5 { + pinmux = ; + }; + + /omit-if-no-ref/ p2_5_pwm0_6: p2_5_pwm0_6 { + pinmux = ; + }; + + /omit-if-no-ref/ p2_6_pwm0_0: p2_6_pwm0_0 { + pinmux = ; + }; + + /omit-if-no-ref/ p3_1_pwm0_1: p3_1_pwm0_1 { + pinmux = ; + }; + + /omit-if-no-ref/ p3_2_pwm0_2: p3_2_pwm0_2 { + pinmux = ; + }; + + /omit-if-no-ref/ p4_0_pwm0_3: p4_0_pwm0_3 { + pinmux = ; + }; + + /omit-if-no-ref/ p4_1_pwm0_4: p4_1_pwm0_4 { + pinmux = ; + }; + + /omit-if-no-ref/ p4_4_pwm0_5: p4_4_pwm0_5 { + pinmux = ; + }; + + /omit-if-no-ref/ p4_5_pwm0_6: p4_5_pwm0_6 { + pinmux = ; + }; + }; + }; +}; + +&gpio_prt3 { + ngpios = <3>; +}; + +&gpio_prt4 { + ngpios = <7>; +}; diff --git a/dts/arm/infineon/psoc4/psoc4100tp/psoc4100tp.48-qfn.dtsi b/dts/arm/infineon/psoc4/psoc4100tp/psoc4100tp.48-qfn.dtsi new file mode 100644 index 000000000000..9ee6a4d72d85 --- /dev/null +++ b/dts/arm/infineon/psoc4/psoc4100tp/psoc4100tp.48-qfn.dtsi @@ -0,0 +1,641 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "psoc4100tp.dtsi" + +/ { + soc { + /delete-node/ gpio@40040600; /* gpio_prt6 */ + + pinctrl: pinctrl@40020000 { + /* scb_i2c_scl */ + /omit-if-no-ref/ p0_0_scb0_i2c_scl: p0_0_scb0_i2c_scl { + pinmux = ; + }; + + /omit-if-no-ref/ p1_4_scb1_i2c_scl: p1_4_scb1_i2c_scl { + pinmux = ; + }; + + /omit-if-no-ref/ p2_0_scb0_i2c_scl: p2_0_scb0_i2c_scl { + pinmux = ; + }; + + /omit-if-no-ref/ p3_3_scb0_i2c_scl: p3_3_scb0_i2c_scl { + pinmux = ; + }; + + /omit-if-no-ref/ p4_0_scb1_i2c_scl: p4_0_scb1_i2c_scl { + pinmux = ; + }; + + /omit-if-no-ref/ p5_1_scb1_i2c_scl: p5_1_scb1_i2c_scl { + pinmux = ; + }; + + /* scb_i2c_sda */ + /omit-if-no-ref/ p0_1_scb0_i2c_sda: p0_1_scb0_i2c_sda { + pinmux = ; + }; + + /omit-if-no-ref/ p1_5_scb1_i2c_sda: p1_5_scb1_i2c_sda { + pinmux = ; + }; + + /omit-if-no-ref/ p2_1_scb0_i2c_sda: p2_1_scb0_i2c_sda { + pinmux = ; + }; + + /omit-if-no-ref/ p3_2_scb0_i2c_sda: p3_2_scb0_i2c_sda { + pinmux = ; + }; + + /omit-if-no-ref/ p4_1_scb1_i2c_sda: p4_1_scb1_i2c_sda { + pinmux = ; + }; + + /omit-if-no-ref/ p5_2_scb1_i2c_sda: p5_2_scb1_i2c_sda { + pinmux = ; + }; + + /* scb_spi_m_clk */ + /omit-if-no-ref/ p0_6_scb0_spi_m_clk: p0_6_scb0_spi_m_clk { + pinmux = ; + }; + + /omit-if-no-ref/ p1_7_scb1_spi_m_clk: p1_7_scb1_spi_m_clk { + pinmux = ; + }; + + /omit-if-no-ref/ p2_6_scb0_spi_m_clk: p2_6_scb0_spi_m_clk { + pinmux = ; + }; + + /omit-if-no-ref/ p4_6_scb1_spi_m_clk: p4_6_scb1_spi_m_clk { + pinmux = ; + }; + + /omit-if-no-ref/ p5_3_scb1_spi_m_clk: p5_3_scb1_spi_m_clk { + pinmux = ; + }; + + /* scb_spi_m_miso */ + /omit-if-no-ref/ p0_5_scb0_spi_m_miso: p0_5_scb0_spi_m_miso { + pinmux = ; + }; + + /omit-if-no-ref/ p1_6_scb1_spi_m_miso: p1_6_scb1_spi_m_miso { + pinmux = ; + }; + + /omit-if-no-ref/ p2_5_scb0_spi_m_miso: p2_5_scb0_spi_m_miso { + pinmux = ; + }; + + /omit-if-no-ref/ p4_5_scb1_spi_m_miso: p4_5_scb1_spi_m_miso { + pinmux = ; + }; + + /omit-if-no-ref/ p5_2_scb1_spi_m_miso: p5_2_scb1_spi_m_miso { + pinmux = ; + }; + + /* scb_spi_m_mosi */ + /omit-if-no-ref/ p0_4_scb0_spi_m_mosi: p0_4_scb0_spi_m_mosi { + pinmux = ; + }; + + /omit-if-no-ref/ p1_5_scb1_spi_m_mosi: p1_5_scb1_spi_m_mosi { + pinmux = ; + }; + + /omit-if-no-ref/ p2_4_scb0_spi_m_mosi: p2_4_scb0_spi_m_mosi { + pinmux = ; + }; + + /omit-if-no-ref/ p4_4_scb1_spi_m_mosi: p4_4_scb1_spi_m_mosi { + pinmux = ; + }; + + /omit-if-no-ref/ p5_1_scb1_spi_m_mosi: p5_1_scb1_spi_m_mosi { + pinmux = ; + }; + + /* scb_spi_m_select0 */ + /omit-if-no-ref/ p0_0_scb0_spi_m_select0: p0_0_scb0_spi_m_select0 { + pinmux = ; + }; + + /omit-if-no-ref/ p1_3_scb1_spi_m_select0: p1_3_scb1_spi_m_select0 { + pinmux = ; + }; + + /omit-if-no-ref/ p2_0_scb0_spi_m_select0: p2_0_scb0_spi_m_select0 { + pinmux = ; + }; + + /omit-if-no-ref/ p4_0_scb1_spi_m_select0: p4_0_scb1_spi_m_select0 { + pinmux = ; + }; + + /omit-if-no-ref/ p5_4_scb1_spi_m_select0: p5_4_scb1_spi_m_select0 { + pinmux = ; + }; + + /* scb_spi_m_select1 */ + /omit-if-no-ref/ p0_1_scb0_spi_m_select1: p0_1_scb0_spi_m_select1 { + pinmux = ; + }; + + /omit-if-no-ref/ p1_4_scb1_spi_m_select1: p1_4_scb1_spi_m_select1 { + pinmux = ; + }; + + /omit-if-no-ref/ p2_1_scb0_spi_m_select1: p2_1_scb0_spi_m_select1 { + pinmux = ; + }; + + /omit-if-no-ref/ p3_1_scb0_spi_m_select1: p3_1_scb0_spi_m_select1 { + pinmux = ; + }; + + /omit-if-no-ref/ p4_1_scb1_spi_m_select1: p4_1_scb1_spi_m_select1 { + pinmux = ; + }; + + /* scb_spi_m_select2 */ + /omit-if-no-ref/ p0_2_scb0_spi_m_select2: p0_2_scb0_spi_m_select2 { + pinmux = ; + }; + + /omit-if-no-ref/ p2_2_scb0_spi_m_select2: p2_2_scb0_spi_m_select2 { + pinmux = ; + }; + + /omit-if-no-ref/ p3_2_scb0_spi_m_select2: p3_2_scb0_spi_m_select2 { + pinmux = ; + }; + + /omit-if-no-ref/ p4_2_scb1_spi_m_select2: p4_2_scb1_spi_m_select2 { + pinmux = ; + }; + + /* scb_spi_m_select3 */ + /omit-if-no-ref/ p0_3_scb0_spi_m_select3: p0_3_scb0_spi_m_select3 { + pinmux = ; + }; + + /omit-if-no-ref/ p2_3_scb0_spi_m_select3: p2_3_scb0_spi_m_select3 { + pinmux = ; + }; + + /omit-if-no-ref/ p3_3_scb0_spi_m_select3: p3_3_scb0_spi_m_select3 { + pinmux = ; + }; + + /omit-if-no-ref/ p4_3_scb1_spi_m_select3: p4_3_scb1_spi_m_select3 { + pinmux = ; + }; + + /* scb_spi_s_clk */ + /omit-if-no-ref/ p0_6_scb0_spi_s_clk: p0_6_scb0_spi_s_clk { + pinmux = ; + }; + + /omit-if-no-ref/ p1_7_scb1_spi_s_clk: p1_7_scb1_spi_s_clk { + pinmux = ; + }; + + /omit-if-no-ref/ p2_6_scb0_spi_s_clk: p2_6_scb0_spi_s_clk { + pinmux = ; + }; + + /omit-if-no-ref/ p4_6_scb1_spi_s_clk: p4_6_scb1_spi_s_clk { + pinmux = ; + }; + + /omit-if-no-ref/ p5_3_scb1_spi_s_clk: p5_3_scb1_spi_s_clk { + pinmux = ; + }; + + /* scb_spi_s_miso */ + /omit-if-no-ref/ p0_5_scb0_spi_s_miso: p0_5_scb0_spi_s_miso { + pinmux = ; + }; + + /omit-if-no-ref/ p1_6_scb1_spi_s_miso: p1_6_scb1_spi_s_miso { + pinmux = ; + }; + + /omit-if-no-ref/ p2_5_scb0_spi_s_miso: p2_5_scb0_spi_s_miso { + pinmux = ; + }; + + /omit-if-no-ref/ p4_5_scb1_spi_s_miso: p4_5_scb1_spi_s_miso { + pinmux = ; + }; + + /omit-if-no-ref/ p5_2_scb1_spi_s_miso: p5_2_scb1_spi_s_miso { + pinmux = ; + }; + + /* scb_spi_s_mosi */ + /omit-if-no-ref/ p0_4_scb0_spi_s_mosi: p0_4_scb0_spi_s_mosi { + pinmux = ; + }; + + /omit-if-no-ref/ p1_5_scb1_spi_s_mosi: p1_5_scb1_spi_s_mosi { + pinmux = ; + }; + + /omit-if-no-ref/ p2_4_scb0_spi_s_mosi: p2_4_scb0_spi_s_mosi { + pinmux = ; + }; + + /omit-if-no-ref/ p4_4_scb1_spi_s_mosi: p4_4_scb1_spi_s_mosi { + pinmux = ; + }; + + /omit-if-no-ref/ p5_1_scb1_spi_s_mosi: p5_1_scb1_spi_s_mosi { + pinmux = ; + }; + + /* scb_spi_s_select0 */ + /omit-if-no-ref/ p0_0_scb0_spi_s_select0: p0_0_scb0_spi_s_select0 { + pinmux = ; + }; + + /omit-if-no-ref/ p1_3_scb1_spi_s_select0: p1_3_scb1_spi_s_select0 { + pinmux = ; + }; + + /omit-if-no-ref/ p2_0_scb0_spi_s_select0: p2_0_scb0_spi_s_select0 { + pinmux = ; + }; + + /omit-if-no-ref/ p4_0_scb1_spi_s_select0: p4_0_scb1_spi_s_select0 { + pinmux = ; + }; + + /omit-if-no-ref/ p5_4_scb1_spi_s_select0: p5_4_scb1_spi_s_select0 { + pinmux = ; + }; + + /* scb_spi_s_select1 */ + /omit-if-no-ref/ p0_1_scb0_spi_s_select1: p0_1_scb0_spi_s_select1 { + pinmux = ; + }; + + /omit-if-no-ref/ p1_4_scb1_spi_s_select1: p1_4_scb1_spi_s_select1 { + pinmux = ; + }; + + /omit-if-no-ref/ p2_1_scb0_spi_s_select1: p2_1_scb0_spi_s_select1 { + pinmux = ; + }; + + /omit-if-no-ref/ p3_1_scb0_spi_s_select1: p3_1_scb0_spi_s_select1 { + pinmux = ; + }; + + /omit-if-no-ref/ p4_1_scb1_spi_s_select1: p4_1_scb1_spi_s_select1 { + pinmux = ; + }; + + /* scb_spi_s_select2 */ + /omit-if-no-ref/ p0_2_scb0_spi_s_select2: p0_2_scb0_spi_s_select2 { + pinmux = ; + }; + + /omit-if-no-ref/ p2_2_scb0_spi_s_select2: p2_2_scb0_spi_s_select2 { + pinmux = ; + }; + + /omit-if-no-ref/ p3_2_scb0_spi_s_select2: p3_2_scb0_spi_s_select2 { + pinmux = ; + }; + + /omit-if-no-ref/ p4_2_scb1_spi_s_select2: p4_2_scb1_spi_s_select2 { + pinmux = ; + }; + + /* scb_spi_s_select3 */ + /omit-if-no-ref/ p0_3_scb0_spi_s_select3: p0_3_scb0_spi_s_select3 { + pinmux = ; + }; + + /omit-if-no-ref/ p2_3_scb0_spi_s_select3: p2_3_scb0_spi_s_select3 { + pinmux = ; + }; + + /omit-if-no-ref/ p3_3_scb0_spi_s_select3: p3_3_scb0_spi_s_select3 { + pinmux = ; + }; + + /omit-if-no-ref/ p4_3_scb1_spi_s_select3: p4_3_scb1_spi_s_select3 { + pinmux = ; + }; + + /* scb_uart_cts */ + /omit-if-no-ref/ p0_2_scb0_uart_cts: p0_2_scb0_uart_cts { + pinmux = ; + }; + + /omit-if-no-ref/ p1_6_scb1_uart_cts: p1_6_scb1_uart_cts { + pinmux = ; + }; + + /omit-if-no-ref/ p2_2_scb2_uart_cts: p2_2_scb2_uart_cts { + pinmux = ; + }; + + /omit-if-no-ref/ p2_6_scb3_uart_cts: p2_6_scb3_uart_cts { + pinmux = ; + }; + + /omit-if-no-ref/ p4_2_scb4_uart_cts: p4_2_scb4_uart_cts { + pinmux = ; + }; + + /omit-if-no-ref/ p5_3_scb0_uart_cts: p5_3_scb0_uart_cts { + pinmux = ; + }; + + /* scb_uart_rts */ + /omit-if-no-ref/ p0_3_scb0_uart_rts: p0_3_scb0_uart_rts { + pinmux = ; + }; + + /omit-if-no-ref/ p1_7_scb1_uart_rts: p1_7_scb1_uart_rts { + pinmux = ; + }; + + /omit-if-no-ref/ p2_3_scb2_uart_rts: p2_3_scb2_uart_rts { + pinmux = ; + }; + + /omit-if-no-ref/ p2_7_scb3_uart_rts: p2_7_scb3_uart_rts { + pinmux = ; + }; + + /omit-if-no-ref/ p3_1_scb3_uart_rts: p3_1_scb3_uart_rts { + pinmux = ; + }; + + /omit-if-no-ref/ p4_3_scb4_uart_rts: p4_3_scb4_uart_rts { + pinmux = ; + }; + + /omit-if-no-ref/ p5_4_scb0_uart_rts: p5_4_scb0_uart_rts { + pinmux = ; + }; + + /* scb_uart_rx */ + /omit-if-no-ref/ p0_0_scb0_uart_rx: p0_0_scb0_uart_rx { + pinmux = ; + }; + + /omit-if-no-ref/ p1_4_scb1_uart_rx: p1_4_scb1_uart_rx { + pinmux = ; + }; + + /omit-if-no-ref/ p2_0_scb2_uart_rx: p2_0_scb2_uart_rx { + pinmux = ; + }; + + /omit-if-no-ref/ p2_4_scb3_uart_rx: p2_4_scb3_uart_rx { + pinmux = ; + }; + + /omit-if-no-ref/ p3_2_scb3_uart_rx: p3_2_scb3_uart_rx { + pinmux = ; + }; + + /omit-if-no-ref/ p4_0_scb4_uart_rx: p4_0_scb4_uart_rx { + pinmux = ; + }; + + /omit-if-no-ref/ p5_1_scb0_uart_rx: p5_1_scb0_uart_rx { + pinmux = ; + }; + + /* scb_uart_tx */ + /omit-if-no-ref/ p0_1_scb0_uart_tx: p0_1_scb0_uart_tx { + pinmux = ; + }; + + /omit-if-no-ref/ p1_5_scb1_uart_tx: p1_5_scb1_uart_tx { + pinmux = ; + }; + + /omit-if-no-ref/ p2_1_scb2_uart_tx: p2_1_scb2_uart_tx { + pinmux = ; + }; + + /omit-if-no-ref/ p2_5_scb3_uart_tx: p2_5_scb3_uart_tx { + pinmux = ; + }; + + /omit-if-no-ref/ p3_3_scb3_uart_tx: p3_3_scb3_uart_tx { + pinmux = ; + }; + + /omit-if-no-ref/ p4_1_scb4_uart_tx: p4_1_scb4_uart_tx { + pinmux = ; + }; + + /omit-if-no-ref/ p5_2_scb0_uart_tx: p5_2_scb0_uart_tx { + pinmux = ; + }; + + /* PWM tcpwm_line*/ + /omit-if-no-ref/ p0_0_pwm0_0: p0_0_pwm0_0 { + pinmux = ; + }; + + /omit-if-no-ref/ p0_6_pwm0_1: p0_6_pwm0_1 { + pinmux = ; + }; + + /omit-if-no-ref/ p2_0_pwm0_2: p2_0_pwm0_2 { + pinmux = ; + }; + + /omit-if-no-ref/ p2_2_pwm0_3: p2_2_pwm0_3 { + pinmux = ; + }; + + /omit-if-no-ref/ p2_4_pwm0_4: p2_4_pwm0_4 { + pinmux = ; + }; + + /omit-if-no-ref/ p2_6_pwm0_5: p2_6_pwm0_5 { + pinmux = ; + }; + + /omit-if-no-ref/ p3_1_pwm0_0: p3_1_pwm0_0 { + pinmux = ; + }; + + /omit-if-no-ref/ p4_0_pwm0_1: p4_0_pwm0_1 { + pinmux = ; + }; + + /omit-if-no-ref/ p4_2_pwm0_2: p4_2_pwm0_2 { + pinmux = ; + }; + + /omit-if-no-ref/ p4_4_pwm0_3: p4_4_pwm0_3 { + pinmux = ; + }; + + /omit-if-no-ref/ p4_6_pwm0_4: p4_6_pwm0_4 { + pinmux = ; + }; + + /omit-if-no-ref/ p5_1_pwm0_5: p5_1_pwm0_5 { + pinmux = ; + }; + + /omit-if-no-ref/ p5_3_pwm0_0: p5_3_pwm0_0 { + pinmux = ; + }; + + /* PWM tcpwm_line_compl*/ + /omit-if-no-ref/ p0_1_pwm0_0: p0_1_pwm0_0_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p0_7_pwm0_1: p0_7_pwm0_1_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p2_1_pwm0_2: p2_1_pwm0_2_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p2_3_pwm0_3: p2_3_pwm0_3_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p2_5_pwm0_4: p2_5_pwm0_4_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p2_7_pwm0_5: p2_7_pwm0_5_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p3_2_pwm0_0: p3_2_pwm0_0_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p4_1_pwm0_1: p4_1_pwm0_1_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p4_3_pwm0_2: p4_3_pwm0_2_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p4_5_pwm0_3: p4_5_pwm0_3_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p5_2_pwm0_5: p5_2_pwm0_5_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p5_4_pwm0_0: p5_4_pwm0_0_compl { + pinmux = ; + }; + + /* PWM tcpwm_tr_in*/ + /omit-if-no-ref/ p0_1_pwm0_1: p0_1_pwm0_1 { + pinmux = ; + }; + + /omit-if-no-ref/ p1_4_pwm0_2: p1_4_pwm0_2 { + pinmux = ; + }; + + /omit-if-no-ref/ p1_5_pwm0_3: p1_5_pwm0_3 { + pinmux = ; + }; + + /omit-if-no-ref/ p2_0_pwm0_4: p2_0_pwm0_4 { + pinmux = ; + }; + + /omit-if-no-ref/ p2_1_pwm0_5: p2_1_pwm0_5 { + pinmux = ; + }; + + /omit-if-no-ref/ p2_5_pwm0_6: p2_5_pwm0_6 { + pinmux = ; + }; + + /omit-if-no-ref/ p2_6_pwm0_0: p2_6_pwm0_0 { + pinmux = ; + }; + + /omit-if-no-ref/ p3_1_pwm0_1: p3_1_pwm0_1 { + pinmux = ; + }; + + /omit-if-no-ref/ p3_2_pwm0_2: p3_2_pwm0_2 { + pinmux = ; + }; + + /omit-if-no-ref/ p4_0_pwm0_3: p4_0_pwm0_3 { + pinmux = ; + }; + + /omit-if-no-ref/ p4_1_pwm0_4: p4_1_pwm0_4 { + pinmux = ; + }; + + /omit-if-no-ref/ p4_4_pwm0_5: p4_4_pwm0_5 { + pinmux = ; + }; + + /omit-if-no-ref/ p4_5_pwm0_6: p4_5_pwm0_6 { + pinmux = ; + }; + + /omit-if-no-ref/ p5_1_pwm0_0: p5_1_pwm0_0 { + pinmux = ; + }; + + /omit-if-no-ref/ p5_2_pwm0_1: p5_2_pwm0_1 { + pinmux = ; + }; + + /omit-if-no-ref/ p5_3_pwm0_2: p5_3_pwm0_2 { + pinmux = ; + }; + + /omit-if-no-ref/ p5_4_pwm0_3: p5_4_pwm0_3 { + pinmux = ; + }; + }; + }; +}; + +&gpio_prt3 { + ngpios = <3>; +}; + +&gpio_prt4 { + ngpios = <7>; +}; + +&gpio_prt5 { + ngpios = <4>; +}; diff --git a/dts/arm/infineon/psoc4/psoc4100tp/psoc4100tp.48-tqfp.dtsi b/dts/arm/infineon/psoc4/psoc4100tp/psoc4100tp.48-tqfp.dtsi new file mode 100644 index 000000000000..9ee6a4d72d85 --- /dev/null +++ b/dts/arm/infineon/psoc4/psoc4100tp/psoc4100tp.48-tqfp.dtsi @@ -0,0 +1,641 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "psoc4100tp.dtsi" + +/ { + soc { + /delete-node/ gpio@40040600; /* gpio_prt6 */ + + pinctrl: pinctrl@40020000 { + /* scb_i2c_scl */ + /omit-if-no-ref/ p0_0_scb0_i2c_scl: p0_0_scb0_i2c_scl { + pinmux = ; + }; + + /omit-if-no-ref/ p1_4_scb1_i2c_scl: p1_4_scb1_i2c_scl { + pinmux = ; + }; + + /omit-if-no-ref/ p2_0_scb0_i2c_scl: p2_0_scb0_i2c_scl { + pinmux = ; + }; + + /omit-if-no-ref/ p3_3_scb0_i2c_scl: p3_3_scb0_i2c_scl { + pinmux = ; + }; + + /omit-if-no-ref/ p4_0_scb1_i2c_scl: p4_0_scb1_i2c_scl { + pinmux = ; + }; + + /omit-if-no-ref/ p5_1_scb1_i2c_scl: p5_1_scb1_i2c_scl { + pinmux = ; + }; + + /* scb_i2c_sda */ + /omit-if-no-ref/ p0_1_scb0_i2c_sda: p0_1_scb0_i2c_sda { + pinmux = ; + }; + + /omit-if-no-ref/ p1_5_scb1_i2c_sda: p1_5_scb1_i2c_sda { + pinmux = ; + }; + + /omit-if-no-ref/ p2_1_scb0_i2c_sda: p2_1_scb0_i2c_sda { + pinmux = ; + }; + + /omit-if-no-ref/ p3_2_scb0_i2c_sda: p3_2_scb0_i2c_sda { + pinmux = ; + }; + + /omit-if-no-ref/ p4_1_scb1_i2c_sda: p4_1_scb1_i2c_sda { + pinmux = ; + }; + + /omit-if-no-ref/ p5_2_scb1_i2c_sda: p5_2_scb1_i2c_sda { + pinmux = ; + }; + + /* scb_spi_m_clk */ + /omit-if-no-ref/ p0_6_scb0_spi_m_clk: p0_6_scb0_spi_m_clk { + pinmux = ; + }; + + /omit-if-no-ref/ p1_7_scb1_spi_m_clk: p1_7_scb1_spi_m_clk { + pinmux = ; + }; + + /omit-if-no-ref/ p2_6_scb0_spi_m_clk: p2_6_scb0_spi_m_clk { + pinmux = ; + }; + + /omit-if-no-ref/ p4_6_scb1_spi_m_clk: p4_6_scb1_spi_m_clk { + pinmux = ; + }; + + /omit-if-no-ref/ p5_3_scb1_spi_m_clk: p5_3_scb1_spi_m_clk { + pinmux = ; + }; + + /* scb_spi_m_miso */ + /omit-if-no-ref/ p0_5_scb0_spi_m_miso: p0_5_scb0_spi_m_miso { + pinmux = ; + }; + + /omit-if-no-ref/ p1_6_scb1_spi_m_miso: p1_6_scb1_spi_m_miso { + pinmux = ; + }; + + /omit-if-no-ref/ p2_5_scb0_spi_m_miso: p2_5_scb0_spi_m_miso { + pinmux = ; + }; + + /omit-if-no-ref/ p4_5_scb1_spi_m_miso: p4_5_scb1_spi_m_miso { + pinmux = ; + }; + + /omit-if-no-ref/ p5_2_scb1_spi_m_miso: p5_2_scb1_spi_m_miso { + pinmux = ; + }; + + /* scb_spi_m_mosi */ + /omit-if-no-ref/ p0_4_scb0_spi_m_mosi: p0_4_scb0_spi_m_mosi { + pinmux = ; + }; + + /omit-if-no-ref/ p1_5_scb1_spi_m_mosi: p1_5_scb1_spi_m_mosi { + pinmux = ; + }; + + /omit-if-no-ref/ p2_4_scb0_spi_m_mosi: p2_4_scb0_spi_m_mosi { + pinmux = ; + }; + + /omit-if-no-ref/ p4_4_scb1_spi_m_mosi: p4_4_scb1_spi_m_mosi { + pinmux = ; + }; + + /omit-if-no-ref/ p5_1_scb1_spi_m_mosi: p5_1_scb1_spi_m_mosi { + pinmux = ; + }; + + /* scb_spi_m_select0 */ + /omit-if-no-ref/ p0_0_scb0_spi_m_select0: p0_0_scb0_spi_m_select0 { + pinmux = ; + }; + + /omit-if-no-ref/ p1_3_scb1_spi_m_select0: p1_3_scb1_spi_m_select0 { + pinmux = ; + }; + + /omit-if-no-ref/ p2_0_scb0_spi_m_select0: p2_0_scb0_spi_m_select0 { + pinmux = ; + }; + + /omit-if-no-ref/ p4_0_scb1_spi_m_select0: p4_0_scb1_spi_m_select0 { + pinmux = ; + }; + + /omit-if-no-ref/ p5_4_scb1_spi_m_select0: p5_4_scb1_spi_m_select0 { + pinmux = ; + }; + + /* scb_spi_m_select1 */ + /omit-if-no-ref/ p0_1_scb0_spi_m_select1: p0_1_scb0_spi_m_select1 { + pinmux = ; + }; + + /omit-if-no-ref/ p1_4_scb1_spi_m_select1: p1_4_scb1_spi_m_select1 { + pinmux = ; + }; + + /omit-if-no-ref/ p2_1_scb0_spi_m_select1: p2_1_scb0_spi_m_select1 { + pinmux = ; + }; + + /omit-if-no-ref/ p3_1_scb0_spi_m_select1: p3_1_scb0_spi_m_select1 { + pinmux = ; + }; + + /omit-if-no-ref/ p4_1_scb1_spi_m_select1: p4_1_scb1_spi_m_select1 { + pinmux = ; + }; + + /* scb_spi_m_select2 */ + /omit-if-no-ref/ p0_2_scb0_spi_m_select2: p0_2_scb0_spi_m_select2 { + pinmux = ; + }; + + /omit-if-no-ref/ p2_2_scb0_spi_m_select2: p2_2_scb0_spi_m_select2 { + pinmux = ; + }; + + /omit-if-no-ref/ p3_2_scb0_spi_m_select2: p3_2_scb0_spi_m_select2 { + pinmux = ; + }; + + /omit-if-no-ref/ p4_2_scb1_spi_m_select2: p4_2_scb1_spi_m_select2 { + pinmux = ; + }; + + /* scb_spi_m_select3 */ + /omit-if-no-ref/ p0_3_scb0_spi_m_select3: p0_3_scb0_spi_m_select3 { + pinmux = ; + }; + + /omit-if-no-ref/ p2_3_scb0_spi_m_select3: p2_3_scb0_spi_m_select3 { + pinmux = ; + }; + + /omit-if-no-ref/ p3_3_scb0_spi_m_select3: p3_3_scb0_spi_m_select3 { + pinmux = ; + }; + + /omit-if-no-ref/ p4_3_scb1_spi_m_select3: p4_3_scb1_spi_m_select3 { + pinmux = ; + }; + + /* scb_spi_s_clk */ + /omit-if-no-ref/ p0_6_scb0_spi_s_clk: p0_6_scb0_spi_s_clk { + pinmux = ; + }; + + /omit-if-no-ref/ p1_7_scb1_spi_s_clk: p1_7_scb1_spi_s_clk { + pinmux = ; + }; + + /omit-if-no-ref/ p2_6_scb0_spi_s_clk: p2_6_scb0_spi_s_clk { + pinmux = ; + }; + + /omit-if-no-ref/ p4_6_scb1_spi_s_clk: p4_6_scb1_spi_s_clk { + pinmux = ; + }; + + /omit-if-no-ref/ p5_3_scb1_spi_s_clk: p5_3_scb1_spi_s_clk { + pinmux = ; + }; + + /* scb_spi_s_miso */ + /omit-if-no-ref/ p0_5_scb0_spi_s_miso: p0_5_scb0_spi_s_miso { + pinmux = ; + }; + + /omit-if-no-ref/ p1_6_scb1_spi_s_miso: p1_6_scb1_spi_s_miso { + pinmux = ; + }; + + /omit-if-no-ref/ p2_5_scb0_spi_s_miso: p2_5_scb0_spi_s_miso { + pinmux = ; + }; + + /omit-if-no-ref/ p4_5_scb1_spi_s_miso: p4_5_scb1_spi_s_miso { + pinmux = ; + }; + + /omit-if-no-ref/ p5_2_scb1_spi_s_miso: p5_2_scb1_spi_s_miso { + pinmux = ; + }; + + /* scb_spi_s_mosi */ + /omit-if-no-ref/ p0_4_scb0_spi_s_mosi: p0_4_scb0_spi_s_mosi { + pinmux = ; + }; + + /omit-if-no-ref/ p1_5_scb1_spi_s_mosi: p1_5_scb1_spi_s_mosi { + pinmux = ; + }; + + /omit-if-no-ref/ p2_4_scb0_spi_s_mosi: p2_4_scb0_spi_s_mosi { + pinmux = ; + }; + + /omit-if-no-ref/ p4_4_scb1_spi_s_mosi: p4_4_scb1_spi_s_mosi { + pinmux = ; + }; + + /omit-if-no-ref/ p5_1_scb1_spi_s_mosi: p5_1_scb1_spi_s_mosi { + pinmux = ; + }; + + /* scb_spi_s_select0 */ + /omit-if-no-ref/ p0_0_scb0_spi_s_select0: p0_0_scb0_spi_s_select0 { + pinmux = ; + }; + + /omit-if-no-ref/ p1_3_scb1_spi_s_select0: p1_3_scb1_spi_s_select0 { + pinmux = ; + }; + + /omit-if-no-ref/ p2_0_scb0_spi_s_select0: p2_0_scb0_spi_s_select0 { + pinmux = ; + }; + + /omit-if-no-ref/ p4_0_scb1_spi_s_select0: p4_0_scb1_spi_s_select0 { + pinmux = ; + }; + + /omit-if-no-ref/ p5_4_scb1_spi_s_select0: p5_4_scb1_spi_s_select0 { + pinmux = ; + }; + + /* scb_spi_s_select1 */ + /omit-if-no-ref/ p0_1_scb0_spi_s_select1: p0_1_scb0_spi_s_select1 { + pinmux = ; + }; + + /omit-if-no-ref/ p1_4_scb1_spi_s_select1: p1_4_scb1_spi_s_select1 { + pinmux = ; + }; + + /omit-if-no-ref/ p2_1_scb0_spi_s_select1: p2_1_scb0_spi_s_select1 { + pinmux = ; + }; + + /omit-if-no-ref/ p3_1_scb0_spi_s_select1: p3_1_scb0_spi_s_select1 { + pinmux = ; + }; + + /omit-if-no-ref/ p4_1_scb1_spi_s_select1: p4_1_scb1_spi_s_select1 { + pinmux = ; + }; + + /* scb_spi_s_select2 */ + /omit-if-no-ref/ p0_2_scb0_spi_s_select2: p0_2_scb0_spi_s_select2 { + pinmux = ; + }; + + /omit-if-no-ref/ p2_2_scb0_spi_s_select2: p2_2_scb0_spi_s_select2 { + pinmux = ; + }; + + /omit-if-no-ref/ p3_2_scb0_spi_s_select2: p3_2_scb0_spi_s_select2 { + pinmux = ; + }; + + /omit-if-no-ref/ p4_2_scb1_spi_s_select2: p4_2_scb1_spi_s_select2 { + pinmux = ; + }; + + /* scb_spi_s_select3 */ + /omit-if-no-ref/ p0_3_scb0_spi_s_select3: p0_3_scb0_spi_s_select3 { + pinmux = ; + }; + + /omit-if-no-ref/ p2_3_scb0_spi_s_select3: p2_3_scb0_spi_s_select3 { + pinmux = ; + }; + + /omit-if-no-ref/ p3_3_scb0_spi_s_select3: p3_3_scb0_spi_s_select3 { + pinmux = ; + }; + + /omit-if-no-ref/ p4_3_scb1_spi_s_select3: p4_3_scb1_spi_s_select3 { + pinmux = ; + }; + + /* scb_uart_cts */ + /omit-if-no-ref/ p0_2_scb0_uart_cts: p0_2_scb0_uart_cts { + pinmux = ; + }; + + /omit-if-no-ref/ p1_6_scb1_uart_cts: p1_6_scb1_uart_cts { + pinmux = ; + }; + + /omit-if-no-ref/ p2_2_scb2_uart_cts: p2_2_scb2_uart_cts { + pinmux = ; + }; + + /omit-if-no-ref/ p2_6_scb3_uart_cts: p2_6_scb3_uart_cts { + pinmux = ; + }; + + /omit-if-no-ref/ p4_2_scb4_uart_cts: p4_2_scb4_uart_cts { + pinmux = ; + }; + + /omit-if-no-ref/ p5_3_scb0_uart_cts: p5_3_scb0_uart_cts { + pinmux = ; + }; + + /* scb_uart_rts */ + /omit-if-no-ref/ p0_3_scb0_uart_rts: p0_3_scb0_uart_rts { + pinmux = ; + }; + + /omit-if-no-ref/ p1_7_scb1_uart_rts: p1_7_scb1_uart_rts { + pinmux = ; + }; + + /omit-if-no-ref/ p2_3_scb2_uart_rts: p2_3_scb2_uart_rts { + pinmux = ; + }; + + /omit-if-no-ref/ p2_7_scb3_uart_rts: p2_7_scb3_uart_rts { + pinmux = ; + }; + + /omit-if-no-ref/ p3_1_scb3_uart_rts: p3_1_scb3_uart_rts { + pinmux = ; + }; + + /omit-if-no-ref/ p4_3_scb4_uart_rts: p4_3_scb4_uart_rts { + pinmux = ; + }; + + /omit-if-no-ref/ p5_4_scb0_uart_rts: p5_4_scb0_uart_rts { + pinmux = ; + }; + + /* scb_uart_rx */ + /omit-if-no-ref/ p0_0_scb0_uart_rx: p0_0_scb0_uart_rx { + pinmux = ; + }; + + /omit-if-no-ref/ p1_4_scb1_uart_rx: p1_4_scb1_uart_rx { + pinmux = ; + }; + + /omit-if-no-ref/ p2_0_scb2_uart_rx: p2_0_scb2_uart_rx { + pinmux = ; + }; + + /omit-if-no-ref/ p2_4_scb3_uart_rx: p2_4_scb3_uart_rx { + pinmux = ; + }; + + /omit-if-no-ref/ p3_2_scb3_uart_rx: p3_2_scb3_uart_rx { + pinmux = ; + }; + + /omit-if-no-ref/ p4_0_scb4_uart_rx: p4_0_scb4_uart_rx { + pinmux = ; + }; + + /omit-if-no-ref/ p5_1_scb0_uart_rx: p5_1_scb0_uart_rx { + pinmux = ; + }; + + /* scb_uart_tx */ + /omit-if-no-ref/ p0_1_scb0_uart_tx: p0_1_scb0_uart_tx { + pinmux = ; + }; + + /omit-if-no-ref/ p1_5_scb1_uart_tx: p1_5_scb1_uart_tx { + pinmux = ; + }; + + /omit-if-no-ref/ p2_1_scb2_uart_tx: p2_1_scb2_uart_tx { + pinmux = ; + }; + + /omit-if-no-ref/ p2_5_scb3_uart_tx: p2_5_scb3_uart_tx { + pinmux = ; + }; + + /omit-if-no-ref/ p3_3_scb3_uart_tx: p3_3_scb3_uart_tx { + pinmux = ; + }; + + /omit-if-no-ref/ p4_1_scb4_uart_tx: p4_1_scb4_uart_tx { + pinmux = ; + }; + + /omit-if-no-ref/ p5_2_scb0_uart_tx: p5_2_scb0_uart_tx { + pinmux = ; + }; + + /* PWM tcpwm_line*/ + /omit-if-no-ref/ p0_0_pwm0_0: p0_0_pwm0_0 { + pinmux = ; + }; + + /omit-if-no-ref/ p0_6_pwm0_1: p0_6_pwm0_1 { + pinmux = ; + }; + + /omit-if-no-ref/ p2_0_pwm0_2: p2_0_pwm0_2 { + pinmux = ; + }; + + /omit-if-no-ref/ p2_2_pwm0_3: p2_2_pwm0_3 { + pinmux = ; + }; + + /omit-if-no-ref/ p2_4_pwm0_4: p2_4_pwm0_4 { + pinmux = ; + }; + + /omit-if-no-ref/ p2_6_pwm0_5: p2_6_pwm0_5 { + pinmux = ; + }; + + /omit-if-no-ref/ p3_1_pwm0_0: p3_1_pwm0_0 { + pinmux = ; + }; + + /omit-if-no-ref/ p4_0_pwm0_1: p4_0_pwm0_1 { + pinmux = ; + }; + + /omit-if-no-ref/ p4_2_pwm0_2: p4_2_pwm0_2 { + pinmux = ; + }; + + /omit-if-no-ref/ p4_4_pwm0_3: p4_4_pwm0_3 { + pinmux = ; + }; + + /omit-if-no-ref/ p4_6_pwm0_4: p4_6_pwm0_4 { + pinmux = ; + }; + + /omit-if-no-ref/ p5_1_pwm0_5: p5_1_pwm0_5 { + pinmux = ; + }; + + /omit-if-no-ref/ p5_3_pwm0_0: p5_3_pwm0_0 { + pinmux = ; + }; + + /* PWM tcpwm_line_compl*/ + /omit-if-no-ref/ p0_1_pwm0_0: p0_1_pwm0_0_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p0_7_pwm0_1: p0_7_pwm0_1_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p2_1_pwm0_2: p2_1_pwm0_2_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p2_3_pwm0_3: p2_3_pwm0_3_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p2_5_pwm0_4: p2_5_pwm0_4_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p2_7_pwm0_5: p2_7_pwm0_5_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p3_2_pwm0_0: p3_2_pwm0_0_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p4_1_pwm0_1: p4_1_pwm0_1_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p4_3_pwm0_2: p4_3_pwm0_2_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p4_5_pwm0_3: p4_5_pwm0_3_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p5_2_pwm0_5: p5_2_pwm0_5_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p5_4_pwm0_0: p5_4_pwm0_0_compl { + pinmux = ; + }; + + /* PWM tcpwm_tr_in*/ + /omit-if-no-ref/ p0_1_pwm0_1: p0_1_pwm0_1 { + pinmux = ; + }; + + /omit-if-no-ref/ p1_4_pwm0_2: p1_4_pwm0_2 { + pinmux = ; + }; + + /omit-if-no-ref/ p1_5_pwm0_3: p1_5_pwm0_3 { + pinmux = ; + }; + + /omit-if-no-ref/ p2_0_pwm0_4: p2_0_pwm0_4 { + pinmux = ; + }; + + /omit-if-no-ref/ p2_1_pwm0_5: p2_1_pwm0_5 { + pinmux = ; + }; + + /omit-if-no-ref/ p2_5_pwm0_6: p2_5_pwm0_6 { + pinmux = ; + }; + + /omit-if-no-ref/ p2_6_pwm0_0: p2_6_pwm0_0 { + pinmux = ; + }; + + /omit-if-no-ref/ p3_1_pwm0_1: p3_1_pwm0_1 { + pinmux = ; + }; + + /omit-if-no-ref/ p3_2_pwm0_2: p3_2_pwm0_2 { + pinmux = ; + }; + + /omit-if-no-ref/ p4_0_pwm0_3: p4_0_pwm0_3 { + pinmux = ; + }; + + /omit-if-no-ref/ p4_1_pwm0_4: p4_1_pwm0_4 { + pinmux = ; + }; + + /omit-if-no-ref/ p4_4_pwm0_5: p4_4_pwm0_5 { + pinmux = ; + }; + + /omit-if-no-ref/ p4_5_pwm0_6: p4_5_pwm0_6 { + pinmux = ; + }; + + /omit-if-no-ref/ p5_1_pwm0_0: p5_1_pwm0_0 { + pinmux = ; + }; + + /omit-if-no-ref/ p5_2_pwm0_1: p5_2_pwm0_1 { + pinmux = ; + }; + + /omit-if-no-ref/ p5_3_pwm0_2: p5_3_pwm0_2 { + pinmux = ; + }; + + /omit-if-no-ref/ p5_4_pwm0_3: p5_4_pwm0_3 { + pinmux = ; + }; + }; + }; +}; + +&gpio_prt3 { + ngpios = <3>; +}; + +&gpio_prt4 { + ngpios = <7>; +}; + +&gpio_prt5 { + ngpios = <4>; +}; diff --git a/dts/arm/infineon/psoc4/psoc4100tp/psoc4100tp.64-tqfp.dtsi b/dts/arm/infineon/psoc4/psoc4100tp/psoc4100tp.64-tqfp.dtsi new file mode 100644 index 000000000000..88a8d3fce22c --- /dev/null +++ b/dts/arm/infineon/psoc4/psoc4100tp/psoc4100tp.64-tqfp.dtsi @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "psoc4100tp.dtsi" +#include +#include + +/ { + soc { + pinctrl: pinctrl@40020000 { + /* scb_uart_cts */ + /omit-if-no-ref/ p0_2_scb0_uart_cts: p0_2_scb0_uart_cts { + pinmux = ; + }; + + /omit-if-no-ref/ p1_6_scb1_uart_cts: p1_6_scb1_uart_cts { + pinmux = ; + }; + + /omit-if-no-ref/ p2_2_scb2_uart_cts: p2_2_scb2_uart_cts { + pinmux = ; + }; + + /omit-if-no-ref/ p2_6_scb3_uart_cts: p2_6_scb3_uart_cts { + pinmux = ; + }; + + /omit-if-no-ref/ p3_0_scb3_uart_cts: p3_0_scb3_uart_cts { + pinmux = ; + }; + + /omit-if-no-ref/ p4_2_scb4_uart_cts: p4_2_scb4_uart_cts { + pinmux = ; + }; + + /omit-if-no-ref/ p5_3_scb0_uart_cts: p5_3_scb0_uart_cts { + pinmux = ; + }; + + /omit-if-no-ref/ p6_2_scb1_uart_cts: p6_2_scb1_uart_cts { + pinmux = ; + }; + + /* scb_uart_rts */ + /omit-if-no-ref/ p0_3_scb0_uart_rts: p0_3_scb0_uart_rts { + pinmux = ; + }; + + /omit-if-no-ref/ p1_7_scb1_uart_rts: p1_7_scb1_uart_rts { + pinmux = ; + }; + + /omit-if-no-ref/ p2_3_scb2_uart_rts: p2_3_scb2_uart_rts { + pinmux = ; + }; + + /omit-if-no-ref/ p2_7_scb3_uart_rts: p2_7_scb3_uart_rts { + pinmux = ; + }; + + /omit-if-no-ref/ p3_1_scb3_uart_rts: p3_1_scb3_uart_rts { + pinmux = ; + }; + + /omit-if-no-ref/ p4_3_scb4_uart_rts: p4_3_scb4_uart_rts { + pinmux = ; + }; + + /omit-if-no-ref/ p5_4_scb0_uart_rts: p5_4_scb0_uart_rts { + pinmux = ; + }; + + /omit-if-no-ref/ p6_3_scb1_uart_rts: p6_3_scb1_uart_rts { + pinmux = ; + }; + + /* scb_uart_rx */ + /omit-if-no-ref/ p0_0_scb0_uart_rx: p0_0_scb0_uart_rx { + pinmux = ; + }; + + /omit-if-no-ref/ p1_4_scb1_uart_rx: p1_4_scb1_uart_rx { + pinmux = ; + }; + + /omit-if-no-ref/ p2_0_scb2_uart_rx: p2_0_scb2_uart_rx { + pinmux = ; + }; + + /omit-if-no-ref/ p2_4_scb3_uart_rx: p2_4_scb3_uart_rx { + pinmux = ; + }; + + /omit-if-no-ref/ p3_2_scb3_uart_rx: p3_2_scb3_uart_rx { + pinmux = ; + }; + + /omit-if-no-ref/ p4_0_scb4_uart_rx: p4_0_scb4_uart_rx { + pinmux = ; + }; + + /omit-if-no-ref/ p5_1_scb0_uart_rx: p5_1_scb0_uart_rx { + pinmux = ; + }; + + /omit-if-no-ref/ p6_0_scb1_uart_rx: p6_0_scb1_uart_rx { + pinmux = ; + }; + + /* scb_uart_tx */ + /omit-if-no-ref/ p0_1_scb0_uart_tx: p0_1_scb0_uart_tx { + pinmux = ; + }; + + /omit-if-no-ref/ p1_5_scb1_uart_tx: p1_5_scb1_uart_tx { + pinmux = ; + }; + + /omit-if-no-ref/ p2_1_scb2_uart_tx: p2_1_scb2_uart_tx { + pinmux = ; + }; + + /omit-if-no-ref/ p2_5_scb3_uart_tx: p2_5_scb3_uart_tx { + pinmux = ; + }; + + /omit-if-no-ref/ p3_3_scb3_uart_tx: p3_3_scb3_uart_tx { + pinmux = ; + }; + + /omit-if-no-ref/ p4_1_scb4_uart_tx: p4_1_scb4_uart_tx { + pinmux = ; + }; + + /omit-if-no-ref/ p5_2_scb0_uart_tx: p5_2_scb0_uart_tx { + pinmux = ; + }; + + /omit-if-no-ref/ p6_1_scb1_uart_tx: p6_1_scb1_uart_tx { + pinmux = ; + }; + }; /* pinctrl */ + }; /* soc */ +}; /* root */ diff --git a/dts/arm/infineon/psoc4/psoc4100tp/psoc4100tp.cm0p.dtsi b/dts/arm/infineon/psoc4/psoc4100tp/psoc4100tp.cm0p.dtsi new file mode 100644 index 000000000000..89e6ac1a87e2 --- /dev/null +++ b/dts/arm/infineon/psoc4/psoc4100tp/psoc4100tp.cm0p.dtsi @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/ { + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-m0+"; + reg = <0>; + clock-frequency = <48000000>; + }; + }; + + soc { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + /* Pinctrl node for Infineon PSOC4 SoC */ + pinctrl0: pinctrl@40310000 { + compatible = "infineon,cat1-pinctrl"; + reg = <0x40310000 0x1000>; + status = "okay"; + }; + }; +}; + +&nvic { + arm,num-irq-priority-bits = <2>; +}; diff --git a/dts/arm/infineon/psoc4/psoc4100tp/psoc4100tp.dtsi b/dts/arm/infineon/psoc4/psoc4100tp/psoc4100tp.dtsi new file mode 100644 index 000000000000..a58175ba20bc --- /dev/null +++ b/dts/arm/infineon/psoc4/psoc4100tp/psoc4100tp.dtsi @@ -0,0 +1,252 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "psoc4100tp.cm0p.dtsi" +#include +#include + +/ { + flash0: flash@0 { + compatible = "soc-nv-flash"; + reg = <0x00000000 0x20000>; /* 128 KB Flash */ + }; + + sram0: memory@20000000 { + compatible = "mmio-sram"; + reg = <0x20000000 0x8000>; + }; + + soc { + pinctrl: pinctrl@40020000 { + compatible = "infineon,cat1-pinctrl"; + reg = <0x40020000 0x24000>; + }; + + hsiom: hsiom@40020000 { + compatible = "infineon,cat1-hsiom"; + reg = <0x40020000 0x4000>; + status = "disabled"; + }; + + gpio_prt0: gpio@40040000 { + compatible = "infineon,cat1-gpio"; + reg = <0x40040000 0x100>; + interrupts = <0 4>; + gpio-controller; + ngpios = <8>; + status = "disabled"; + #gpio-cells = <2>; + }; + + gpio_prt1: gpio@40040100 { + compatible = "infineon,cat1-gpio"; + reg = <0x40040100 0x100>; + interrupts = <1 4>; + gpio-controller; + ngpios = <8>; + status = "disabled"; + #gpio-cells = <2>; + }; + + gpio_prt2: gpio@40040200 { + compatible = "infineon,cat1-gpio"; + reg = <0x40040200 0x100>; + interrupts = <2 4>; + gpio-controller; + ngpios = <8>; + status = "disabled"; + #gpio-cells = <2>; + }; + + gpio_prt3: gpio@40040300 { + compatible = "infineon,cat1-gpio"; + reg = <0x40040300 0x100>; + interrupts = <3 4>; + gpio-controller; + ngpios = <8>; + status = "disabled"; + #gpio-cells = <2>; + }; + + gpio_prt4: gpio@40040400 { + compatible = "infineon,cat1-gpio"; + reg = <0x40040400 0x100>; + gpio-controller; + ngpios = <8>; + status = "disabled"; + #gpio-cells = <2>; + }; + + gpio_prt5: gpio@40040500 { + compatible = "infineon,cat1-gpio"; + reg = <0x40040500 0x100>; + gpio-controller; + ngpios = <8>; + status = "disabled"; + #gpio-cells = <2>; + }; + + gpio_prt6: gpio@40040600 { + compatible = "infineon,cat1-gpio"; + reg = <0x40040600 0x100>; + gpio-controller; + ngpios = <8>; + status = "disabled"; + #gpio-cells = <2>; + }; + + scb0: scb@40240000 { + compatible = "infineon,cat1-scb"; + reg = <0x40240000 0xfcc>; + interrupts = <6 3>; + status = "disabled"; + }; + + scb1: scb@40250000 { + compatible = "infineon,cat1-scb"; + reg = <0x40250000 0xfcc>; + interrupts = <7 3>; + status = "disabled"; + }; + + scb2: scb@40260000 { + compatible = "infineon,cat1-scb"; + reg = <0x40260000 0xfcc>; + interrupts = <8 3>; + status = "disabled"; + }; + + scb3: scb@40270000 { + compatible = "infineon,cat1-scb"; + reg = <0x40270000 0xfcc>; + interrupts = <9 3>; + status = "disabled"; + }; + + scb4: scb@40280000 { + compatible = "infineon,cat1-scb"; + reg = <0x40280000 0xfcc>; + interrupts = <10 3>; + status = "disabled"; + }; + + tcpwm0: tcpwm0@40200100 { + reg = <0x40200100 0x180>; + #address-cells = <1>; + #size-cells = <1>; + + tcpwm0_0: tcpwm0_0@40200100 { + compatible = "infineon,tcpwm"; + reg = <0x40200100 0x40>; + resolution = <16>; + status = "disabled"; + + pwm0_0: pwm0_0 { + compatible = "infineon,tcpwm-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + + counter0_0: counter0_0 { + compatible = "infineon,tcpwm-counter"; + status = "disabled"; + }; + }; + + tcpwm0_1: tcpwm0_1@40200140 { + compatible = "infineon,tcpwm"; + reg = <0x40200140 0x40>; + resolution = <16>; + status = "disabled"; + + pwm0_1: pwm0_1 { + compatible = "infineon,tcpwm-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + + counter0_1: counter0_1 { + compatible = "infineon,tcpwm-counter"; + status = "disabled"; + }; + }; + + tcpwm0_2: tcpwm0_2@40200180 { + compatible = "infineon,tcpwm"; + reg = <0x40200180 0x40>; + resolution = <16>; + status = "disabled"; + + pwm0_2: pwm0_2 { + compatible = "infineon,tcpwm-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + + counter0_2: counter0_2 { + compatible = "infineon,tcpwm-counter"; + status = "disabled"; + }; + }; + + tcpwm0_3: tcpwm0_3@402001c0 { + compatible = "infineon,tcpwm"; + reg = <0x402001c0 0x40>; + resolution = <16>; + status = "disabled"; + + pwm0_3: pwm0_3 { + compatible = "infineon,tcpwm-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + + counter0_3: counter0_3 { + compatible = "infineon,tcpwm-counter"; + status = "disabled"; + }; + }; + + tcpwm0_4: tcpwm0_4@40200200 { + compatible = "infineon,tcpwm"; + reg = <0x40200200 0x40>; + resolution = <16>; + status = "disabled"; + + pwm0_4: pwm0_4 { + compatible = "infineon,tcpwm-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + + counter0_4: counter0_4 { + compatible = "infineon,tcpwm-counter"; + status = "disabled"; + }; + }; + + tcpwm0_5: tcpwm0_5@40200240 { + compatible = "infineon,tcpwm"; + reg = <0x40200240 0x40>; + resolution = <16>; + status = "disabled"; + + pwm0_5: pwm0_5 { + compatible = "infineon,tcpwm-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + + counter0_5: counter0_5 { + compatible = "infineon,tcpwm-counter"; + status = "disabled"; + }; + }; + }; + }; +}; diff --git a/dts/arm/infineon/psoc4/psoc4100tp/system_clocks.dtsi b/dts/arm/infineon/psoc4/psoc4100tp/system_clocks.dtsi new file mode 100644 index 000000000000..0f1f67f29188 --- /dev/null +++ b/dts/arm/infineon/psoc4/psoc4100tp/system_clocks.dtsi @@ -0,0 +1,271 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DIV_16_BIT 1 +#define DIV_16_5_BIT 2 +#define DIV_24_5_BIT 3 + +#include + +/ { + clocks { + /* Internal main oscillator (IMO) */ + clk_imo: clk_imo { + #clock-cells = <0>; + compatible = "infineon,fixed-clock"; + clock-frequency = <24000000>; /* 24 MHz */ + system-clock = ; + status = "okay"; + }; + + /* Internal low-speed oscillator (ILO) */ + clk_ilo: clk_ilo { + #clock-cells = <0>; + compatible = "infineon,fixed-clock"; + clock-frequency = <40000>; /* 40 kHz */ + system-clock = ; + status = "okay"; + }; + + /* External clock (EXTCLK) */ + clk_extclk: clk_extclk { + #clock-cells = <0>; + compatible = "infineon,fixed-clock"; + clock-frequency = <48000000>; /* 48 MHz external input */ + system-clock = ; + status = "disabled"; + }; + + /* Watch crystal oscillator (WCO) */ + clk_wco: clk_wco { + #clock-cells = <0>; + compatible = "infineon,fixed-clock"; + clock-frequency = <32000>; /* 32 kHz */ + system-clock = ; + status = "disabled"; + }; + + hf_clk_sel: hf_clk_sel { + #clock-cells = <0>; + compatible = "infineon,fixed-factor-clock"; + clocks = <&clk_imo>; + system-clock = ; + instance = <0>; + status = "disabled"; + }; + + wdt_clk_sel: wdt_clk_sel { + #clock-cells = <0>; + compatible = "infineon,fixed-factor-clock"; + clocks = <&clk_ilo>; + system-clock = ; + instance = <0>; + status = "disabled"; + }; + + clk_hf0: clk_hf0 { + #clock-cells = <0>; + compatible = "infineon,fixed-factor-clock"; + clock-div = ; + clocks = <&hf_clk_sel>; + system-clock = ; + instance = <0>; + status = "disabled"; + }; + + pump_clk_sel: pump_clk_sel { + #clock-cells = <0>; + compatible = "infineon,fixed-factor-clock"; + clocks = <&clk_imo>; + system-clock = ; + instance = <0>; + status = "disabled"; + }; + }; + + peri0: peri0 { + peri0_group0_16bit_0: peri0_group0_16bit_0 { + #clock-cells = <0>; + compatible = "infineon,peri-div"; + peri-group = [00 00]; + div-type = ; + channel = <0>; + clock-div = <1>; + status = "disabled"; + }; + + peri0_group1_16bit_0: peri0_group1_16bit_0 { + #clock-cells = <0>; + compatible = "infineon,peri-div"; + peri-group = [00 01]; + div-type = ; + channel = <0>; + clock-div = <1>; + status = "disabled"; + }; + + peri0_group2_16bit_0: peri0_group2_16bit_0 { + #clock-cells = <0>; + compatible = "infineon,peri-div"; + peri-group = [00 02]; + div-type = ; + channel = <0>; + clock-div = <1>; + status = "disabled"; + }; + + peri0_group3_16bit_0: peri0_group3_16bit_0 { + #clock-cells = <0>; + compatible = "infineon,peri-div"; + peri-group = [00 03]; + div-type = ; + channel = <0>; + clock-div = <1>; + status = "disabled"; + }; + + peri0_group4_16bit_0: peri0_group4_16bit_0 { + #clock-cells = <0>; + compatible = "infineon,peri-div"; + peri-group = [00 04]; + div-type = ; + channel = <0>; + clock-div = <1>; + status = "disabled"; + }; + + peri0_group5_16bit_0: peri0_group5_16bit_0 { + #clock-cells = <0>; + compatible = "infineon,peri-div"; + peri-group = [00 05]; + div-type = ; + channel = <0>; + clock-div = <1>; + status = "disabled"; + }; + + peri0_group6_16bit_0: peri0_group6_16bit_0 { + #clock-cells = <0>; + compatible = "infineon,peri-div"; + peri-group = [00 06]; + div-type = ; + channel = <0>; + clock-div = <1>; + status = "disabled"; + }; + + peri0_group7_16bit_0: peri0_group7_16bit_0 { + #clock-cells = <0>; + compatible = "infineon,peri-div"; + peri-group = [00 07]; + div-type = ; + channel = <0>; + clock-div = <1>; + status = "disabled"; + }; + + peri0_group8_16bit_0: peri0_group8_16bit_0 { + #clock-cells = <0>; + compatible = "infineon,peri-div"; + peri-group = [00 08]; + div-type = ; + channel = <0>; + clock-div = <1>; + status = "disabled"; + }; + + peri0_group9_16bit_0: peri0_group9_16bit_0 { + #clock-cells = <0>; + compatible = "infineon,peri-div"; + peri-group = [00 09]; + div-type = ; + channel = <0>; + clock-div = <1>; + status = "disabled"; + }; + + peri0_group10_16bit_0: peri0_group10_16bit_0 { + #clock-cells = <0>; + compatible = "infineon,peri-div"; + peri-group = [00 0A]; + div-type = ; + channel = <0>; + clock-div = <1>; + status = "disabled"; + }; + + peri0_group11_16bit_0: peri0_group11_16bit_0 { + #clock-cells = <0>; + compatible = "infineon,peri-div"; + peri-group = [00 0B]; + div-type = ; + channel = <0>; + clock-div = <1>; + status = "disabled"; + }; + + peri0_group4_16_5bit_0: peri0_group4_16_5bit_0 { + #clock-cells = <0>; + compatible = "infineon,peri-div"; + peri-group = [00 04]; + div-type = ; + channel = <0>; + clock-div = <1>; + status = "disabled"; + }; + + peri0_group4_16_5bit_1: peri0_group4_16_5bit_1 { + #clock-cells = <0>; + compatible = "infineon,peri-div"; + peri-group = [00 04]; + div-type = ; + channel = <1>; + clock-div = <1>; + status = "disabled"; + }; + + peri0_group4_16_5bit_2: peri0_group4_16_5bit_2 { + #clock-cells = <0>; + compatible = "infineon,peri-div"; + peri-group = [00 04]; + div-type = ; + channel = <2>; + clock-div = <1>; + status = "disabled"; + }; + + peri0_group4_16_5bit_3: peri0_group4_16_5bit_3 { + #clock-cells = <0>; + compatible = "infineon,peri-div"; + peri-group = [00 04]; + div-type = ; + channel = <3>; + clock-div = <1>; + status = "disabled"; + }; + + peri0_group4_16_5bit_4: peri0_group4_16_5bit_4 { + #clock-cells = <0>; + compatible = "infineon,peri-div"; + peri-group = [00 04]; + div-type = ; + channel = <4>; + clock-div = <1>; + status = "disabled"; + }; + + peri0_group4_24_5bit_0: peri0_group4_24_5bit_0 { + #clock-cells = <0>; + compatible = "infineon,peri-div"; + peri-group = [00 04]; + div-type = ; + channel = <0>; + clock-div = <1>; + status = "disabled"; + }; + }; +}; From 69ed4fc87d2aa490fc566f9731403042500c8cc6 Mon Sep 17 00:00:00 2001 From: Deepika aerlync Date: Mon, 24 Nov 2025 17:54:43 +0530 Subject: [PATCH 0156/3659] dts: arm: infineon: add CY8C4146 MPN variants Add devicetree support for CY8C4146 MPN variants including: - AXI packages (T403, T413, T453) - AZI packages (T403-T455) - AZQ packages (T413, T453) - LQI packages (T403, T413, T453) Signed-off-by: Manojkumar Konisetty Signed-off-by: Sayooj K Karun Signed-off-by: Deepika aerlync --- .../infineon/psoc4/mpns/cy8c4146axi_t403.dtsi | 16 ++++++++++++++++ .../infineon/psoc4/mpns/cy8c4146axi_t413.dtsi | 16 ++++++++++++++++ .../infineon/psoc4/mpns/cy8c4146axi_t453.dtsi | 16 ++++++++++++++++ .../infineon/psoc4/mpns/cy8c4146azi_t403.dtsi | 16 ++++++++++++++++ .../infineon/psoc4/mpns/cy8c4146azi_t405.dtsi | 16 ++++++++++++++++ .../infineon/psoc4/mpns/cy8c4146azi_t413.dtsi | 16 ++++++++++++++++ .../infineon/psoc4/mpns/cy8c4146azi_t415.dtsi | 16 ++++++++++++++++ .../infineon/psoc4/mpns/cy8c4146azi_t453.dtsi | 16 ++++++++++++++++ .../infineon/psoc4/mpns/cy8c4146azi_t455.dtsi | 16 ++++++++++++++++ .../infineon/psoc4/mpns/cy8c4146azq_t413.dtsi | 16 ++++++++++++++++ .../infineon/psoc4/mpns/cy8c4146azq_t453.dtsi | 16 ++++++++++++++++ .../infineon/psoc4/mpns/cy8c4146lqi_t403.dtsi | 16 ++++++++++++++++ .../infineon/psoc4/mpns/cy8c4146lqi_t413.dtsi | 16 ++++++++++++++++ .../infineon/psoc4/mpns/cy8c4146lqi_t453.dtsi | 16 ++++++++++++++++ 14 files changed, 224 insertions(+) create mode 100644 dts/arm/infineon/psoc4/mpns/cy8c4146axi_t403.dtsi create mode 100644 dts/arm/infineon/psoc4/mpns/cy8c4146axi_t413.dtsi create mode 100644 dts/arm/infineon/psoc4/mpns/cy8c4146axi_t453.dtsi create mode 100644 dts/arm/infineon/psoc4/mpns/cy8c4146azi_t403.dtsi create mode 100644 dts/arm/infineon/psoc4/mpns/cy8c4146azi_t405.dtsi create mode 100644 dts/arm/infineon/psoc4/mpns/cy8c4146azi_t413.dtsi create mode 100644 dts/arm/infineon/psoc4/mpns/cy8c4146azi_t415.dtsi create mode 100644 dts/arm/infineon/psoc4/mpns/cy8c4146azi_t453.dtsi create mode 100644 dts/arm/infineon/psoc4/mpns/cy8c4146azi_t455.dtsi create mode 100644 dts/arm/infineon/psoc4/mpns/cy8c4146azq_t413.dtsi create mode 100644 dts/arm/infineon/psoc4/mpns/cy8c4146azq_t453.dtsi create mode 100644 dts/arm/infineon/psoc4/mpns/cy8c4146lqi_t403.dtsi create mode 100644 dts/arm/infineon/psoc4/mpns/cy8c4146lqi_t413.dtsi create mode 100644 dts/arm/infineon/psoc4/mpns/cy8c4146lqi_t453.dtsi diff --git a/dts/arm/infineon/psoc4/mpns/cy8c4146axi_t403.dtsi b/dts/arm/infineon/psoc4/mpns/cy8c4146axi_t403.dtsi new file mode 100644 index 000000000000..c2d95836a08d --- /dev/null +++ b/dts/arm/infineon/psoc4/mpns/cy8c4146axi_t403.dtsi @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "../psoc4100tp/psoc4100tp.44-tqfp.dtsi" + +&flash0 { + reg = <0x00000000 0x10000>; +}; + +&sram0 { + reg = <0x20000000 0x4000>; +}; diff --git a/dts/arm/infineon/psoc4/mpns/cy8c4146axi_t413.dtsi b/dts/arm/infineon/psoc4/mpns/cy8c4146axi_t413.dtsi new file mode 100644 index 000000000000..c2d95836a08d --- /dev/null +++ b/dts/arm/infineon/psoc4/mpns/cy8c4146axi_t413.dtsi @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "../psoc4100tp/psoc4100tp.44-tqfp.dtsi" + +&flash0 { + reg = <0x00000000 0x10000>; +}; + +&sram0 { + reg = <0x20000000 0x4000>; +}; diff --git a/dts/arm/infineon/psoc4/mpns/cy8c4146axi_t453.dtsi b/dts/arm/infineon/psoc4/mpns/cy8c4146axi_t453.dtsi new file mode 100644 index 000000000000..c2d95836a08d --- /dev/null +++ b/dts/arm/infineon/psoc4/mpns/cy8c4146axi_t453.dtsi @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "../psoc4100tp/psoc4100tp.44-tqfp.dtsi" + +&flash0 { + reg = <0x00000000 0x10000>; +}; + +&sram0 { + reg = <0x20000000 0x4000>; +}; diff --git a/dts/arm/infineon/psoc4/mpns/cy8c4146azi_t403.dtsi b/dts/arm/infineon/psoc4/mpns/cy8c4146azi_t403.dtsi new file mode 100644 index 000000000000..9ccd14b3a490 --- /dev/null +++ b/dts/arm/infineon/psoc4/mpns/cy8c4146azi_t403.dtsi @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "../psoc4100tp/psoc4100tp.48-tqfp.dtsi" + +&flash0 { + reg = <0x00000000 0x10000>; +}; + +&sram0 { + reg = <0x20000000 0x4000>; +}; diff --git a/dts/arm/infineon/psoc4/mpns/cy8c4146azi_t405.dtsi b/dts/arm/infineon/psoc4/mpns/cy8c4146azi_t405.dtsi new file mode 100644 index 000000000000..9eebc9f00a26 --- /dev/null +++ b/dts/arm/infineon/psoc4/mpns/cy8c4146azi_t405.dtsi @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "../psoc4100tp/psoc4100tp.64-tqfp.dtsi" + +&flash0 { + reg = <0x00000000 0x10000>; +}; + +&sram0 { + reg = <0x20000000 0x4000>; +}; diff --git a/dts/arm/infineon/psoc4/mpns/cy8c4146azi_t413.dtsi b/dts/arm/infineon/psoc4/mpns/cy8c4146azi_t413.dtsi new file mode 100644 index 000000000000..9ccd14b3a490 --- /dev/null +++ b/dts/arm/infineon/psoc4/mpns/cy8c4146azi_t413.dtsi @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "../psoc4100tp/psoc4100tp.48-tqfp.dtsi" + +&flash0 { + reg = <0x00000000 0x10000>; +}; + +&sram0 { + reg = <0x20000000 0x4000>; +}; diff --git a/dts/arm/infineon/psoc4/mpns/cy8c4146azi_t415.dtsi b/dts/arm/infineon/psoc4/mpns/cy8c4146azi_t415.dtsi new file mode 100644 index 000000000000..9eebc9f00a26 --- /dev/null +++ b/dts/arm/infineon/psoc4/mpns/cy8c4146azi_t415.dtsi @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "../psoc4100tp/psoc4100tp.64-tqfp.dtsi" + +&flash0 { + reg = <0x00000000 0x10000>; +}; + +&sram0 { + reg = <0x20000000 0x4000>; +}; diff --git a/dts/arm/infineon/psoc4/mpns/cy8c4146azi_t453.dtsi b/dts/arm/infineon/psoc4/mpns/cy8c4146azi_t453.dtsi new file mode 100644 index 000000000000..9ccd14b3a490 --- /dev/null +++ b/dts/arm/infineon/psoc4/mpns/cy8c4146azi_t453.dtsi @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "../psoc4100tp/psoc4100tp.48-tqfp.dtsi" + +&flash0 { + reg = <0x00000000 0x10000>; +}; + +&sram0 { + reg = <0x20000000 0x4000>; +}; diff --git a/dts/arm/infineon/psoc4/mpns/cy8c4146azi_t455.dtsi b/dts/arm/infineon/psoc4/mpns/cy8c4146azi_t455.dtsi new file mode 100644 index 000000000000..9eebc9f00a26 --- /dev/null +++ b/dts/arm/infineon/psoc4/mpns/cy8c4146azi_t455.dtsi @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "../psoc4100tp/psoc4100tp.64-tqfp.dtsi" + +&flash0 { + reg = <0x00000000 0x10000>; +}; + +&sram0 { + reg = <0x20000000 0x4000>; +}; diff --git a/dts/arm/infineon/psoc4/mpns/cy8c4146azq_t413.dtsi b/dts/arm/infineon/psoc4/mpns/cy8c4146azq_t413.dtsi new file mode 100644 index 000000000000..9ccd14b3a490 --- /dev/null +++ b/dts/arm/infineon/psoc4/mpns/cy8c4146azq_t413.dtsi @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "../psoc4100tp/psoc4100tp.48-tqfp.dtsi" + +&flash0 { + reg = <0x00000000 0x10000>; +}; + +&sram0 { + reg = <0x20000000 0x4000>; +}; diff --git a/dts/arm/infineon/psoc4/mpns/cy8c4146azq_t453.dtsi b/dts/arm/infineon/psoc4/mpns/cy8c4146azq_t453.dtsi new file mode 100644 index 000000000000..9ccd14b3a490 --- /dev/null +++ b/dts/arm/infineon/psoc4/mpns/cy8c4146azq_t453.dtsi @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "../psoc4100tp/psoc4100tp.48-tqfp.dtsi" + +&flash0 { + reg = <0x00000000 0x10000>; +}; + +&sram0 { + reg = <0x20000000 0x4000>; +}; diff --git a/dts/arm/infineon/psoc4/mpns/cy8c4146lqi_t403.dtsi b/dts/arm/infineon/psoc4/mpns/cy8c4146lqi_t403.dtsi new file mode 100644 index 000000000000..2304acd7b188 --- /dev/null +++ b/dts/arm/infineon/psoc4/mpns/cy8c4146lqi_t403.dtsi @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "../psoc4100tp/psoc4100tp.48-qfn.dtsi" + +&flash0 { + reg = <0x00000000 0x10000>; +}; + +&sram0 { + reg = <0x20000000 0x4000>; +}; diff --git a/dts/arm/infineon/psoc4/mpns/cy8c4146lqi_t413.dtsi b/dts/arm/infineon/psoc4/mpns/cy8c4146lqi_t413.dtsi new file mode 100644 index 000000000000..2304acd7b188 --- /dev/null +++ b/dts/arm/infineon/psoc4/mpns/cy8c4146lqi_t413.dtsi @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "../psoc4100tp/psoc4100tp.48-qfn.dtsi" + +&flash0 { + reg = <0x00000000 0x10000>; +}; + +&sram0 { + reg = <0x20000000 0x4000>; +}; diff --git a/dts/arm/infineon/psoc4/mpns/cy8c4146lqi_t453.dtsi b/dts/arm/infineon/psoc4/mpns/cy8c4146lqi_t453.dtsi new file mode 100644 index 000000000000..2304acd7b188 --- /dev/null +++ b/dts/arm/infineon/psoc4/mpns/cy8c4146lqi_t453.dtsi @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "../psoc4100tp/psoc4100tp.48-qfn.dtsi" + +&flash0 { + reg = <0x00000000 0x10000>; +}; + +&sram0 { + reg = <0x20000000 0x4000>; +}; From 6dfae9c9f72727ec34da3dec27f17e217d8d11b3 Mon Sep 17 00:00:00 2001 From: Manojkumar Konisetty Date: Mon, 1 Dec 2025 15:12:49 +0530 Subject: [PATCH 0157/3659] dts: arm: infineon: add CY8C4147 MPN variants Add devicetree support for CY8C4147 MPN variants including: - AXI packages (T403-T493) - AZI packages (T403-T475) - AZQ packages (T415-T495) - LQI packages (T403-T473) - LQQ package (T493) Signed-off-by: Manojkumar Konisetty Signed-off-by: Sayooj K Karun Signed-off-by: Deepika aerlync --- .../infineon/psoc4/mpns/cy8c4147axi_t403.dtsi | 16 ++++++++++++++++ .../infineon/psoc4/mpns/cy8c4147axi_t413.dtsi | 16 ++++++++++++++++ .../infineon/psoc4/mpns/cy8c4147axi_t453.dtsi | 16 ++++++++++++++++ .../infineon/psoc4/mpns/cy8c4147axi_t463.dtsi | 16 ++++++++++++++++ .../infineon/psoc4/mpns/cy8c4147axi_t473.dtsi | 16 ++++++++++++++++ .../infineon/psoc4/mpns/cy8c4147axq_t493.dtsi | 16 ++++++++++++++++ .../infineon/psoc4/mpns/cy8c4147azi_t403.dtsi | 16 ++++++++++++++++ .../infineon/psoc4/mpns/cy8c4147azi_t405.dtsi | 16 ++++++++++++++++ .../infineon/psoc4/mpns/cy8c4147azi_t413.dtsi | 16 ++++++++++++++++ .../infineon/psoc4/mpns/cy8c4147azi_t415.dtsi | 16 ++++++++++++++++ .../infineon/psoc4/mpns/cy8c4147azi_t453.dtsi | 16 ++++++++++++++++ .../infineon/psoc4/mpns/cy8c4147azi_t455.dtsi | 16 ++++++++++++++++ .../infineon/psoc4/mpns/cy8c4147azi_t463.dtsi | 16 ++++++++++++++++ .../infineon/psoc4/mpns/cy8c4147azi_t465.dtsi | 16 ++++++++++++++++ .../infineon/psoc4/mpns/cy8c4147azi_t473.dtsi | 16 ++++++++++++++++ .../infineon/psoc4/mpns/cy8c4147azi_t475.dtsi | 16 ++++++++++++++++ .../infineon/psoc4/mpns/cy8c4147azq_t415.dtsi | 16 ++++++++++++++++ .../infineon/psoc4/mpns/cy8c4147azq_t455.dtsi | 16 ++++++++++++++++ .../infineon/psoc4/mpns/cy8c4147azq_t493.dtsi | 16 ++++++++++++++++ .../infineon/psoc4/mpns/cy8c4147azq_t495.dtsi | 16 ++++++++++++++++ .../infineon/psoc4/mpns/cy8c4147lqi_t403.dtsi | 16 ++++++++++++++++ .../infineon/psoc4/mpns/cy8c4147lqi_t413.dtsi | 16 ++++++++++++++++ .../infineon/psoc4/mpns/cy8c4147lqi_t453.dtsi | 16 ++++++++++++++++ .../infineon/psoc4/mpns/cy8c4147lqi_t463.dtsi | 16 ++++++++++++++++ .../infineon/psoc4/mpns/cy8c4147lqi_t473.dtsi | 16 ++++++++++++++++ .../infineon/psoc4/mpns/cy8c4147lqq_t493.dtsi | 16 ++++++++++++++++ 26 files changed, 416 insertions(+) create mode 100644 dts/arm/infineon/psoc4/mpns/cy8c4147axi_t403.dtsi create mode 100644 dts/arm/infineon/psoc4/mpns/cy8c4147axi_t413.dtsi create mode 100644 dts/arm/infineon/psoc4/mpns/cy8c4147axi_t453.dtsi create mode 100644 dts/arm/infineon/psoc4/mpns/cy8c4147axi_t463.dtsi create mode 100644 dts/arm/infineon/psoc4/mpns/cy8c4147axi_t473.dtsi create mode 100644 dts/arm/infineon/psoc4/mpns/cy8c4147axq_t493.dtsi create mode 100644 dts/arm/infineon/psoc4/mpns/cy8c4147azi_t403.dtsi create mode 100644 dts/arm/infineon/psoc4/mpns/cy8c4147azi_t405.dtsi create mode 100644 dts/arm/infineon/psoc4/mpns/cy8c4147azi_t413.dtsi create mode 100644 dts/arm/infineon/psoc4/mpns/cy8c4147azi_t415.dtsi create mode 100644 dts/arm/infineon/psoc4/mpns/cy8c4147azi_t453.dtsi create mode 100644 dts/arm/infineon/psoc4/mpns/cy8c4147azi_t455.dtsi create mode 100644 dts/arm/infineon/psoc4/mpns/cy8c4147azi_t463.dtsi create mode 100644 dts/arm/infineon/psoc4/mpns/cy8c4147azi_t465.dtsi create mode 100644 dts/arm/infineon/psoc4/mpns/cy8c4147azi_t473.dtsi create mode 100644 dts/arm/infineon/psoc4/mpns/cy8c4147azi_t475.dtsi create mode 100644 dts/arm/infineon/psoc4/mpns/cy8c4147azq_t415.dtsi create mode 100644 dts/arm/infineon/psoc4/mpns/cy8c4147azq_t455.dtsi create mode 100644 dts/arm/infineon/psoc4/mpns/cy8c4147azq_t493.dtsi create mode 100644 dts/arm/infineon/psoc4/mpns/cy8c4147azq_t495.dtsi create mode 100644 dts/arm/infineon/psoc4/mpns/cy8c4147lqi_t403.dtsi create mode 100644 dts/arm/infineon/psoc4/mpns/cy8c4147lqi_t413.dtsi create mode 100644 dts/arm/infineon/psoc4/mpns/cy8c4147lqi_t453.dtsi create mode 100644 dts/arm/infineon/psoc4/mpns/cy8c4147lqi_t463.dtsi create mode 100644 dts/arm/infineon/psoc4/mpns/cy8c4147lqi_t473.dtsi create mode 100644 dts/arm/infineon/psoc4/mpns/cy8c4147lqq_t493.dtsi diff --git a/dts/arm/infineon/psoc4/mpns/cy8c4147axi_t403.dtsi b/dts/arm/infineon/psoc4/mpns/cy8c4147axi_t403.dtsi new file mode 100644 index 000000000000..ac9307c873f1 --- /dev/null +++ b/dts/arm/infineon/psoc4/mpns/cy8c4147axi_t403.dtsi @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "../psoc4100tp/psoc4100tp.44-tqfp.dtsi" + +&flash0 { + reg = <0x00000000 0x20000>; +}; + +&sram0 { + reg = <0x20000000 0x4000>; +}; diff --git a/dts/arm/infineon/psoc4/mpns/cy8c4147axi_t413.dtsi b/dts/arm/infineon/psoc4/mpns/cy8c4147axi_t413.dtsi new file mode 100644 index 000000000000..ac9307c873f1 --- /dev/null +++ b/dts/arm/infineon/psoc4/mpns/cy8c4147axi_t413.dtsi @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "../psoc4100tp/psoc4100tp.44-tqfp.dtsi" + +&flash0 { + reg = <0x00000000 0x20000>; +}; + +&sram0 { + reg = <0x20000000 0x4000>; +}; diff --git a/dts/arm/infineon/psoc4/mpns/cy8c4147axi_t453.dtsi b/dts/arm/infineon/psoc4/mpns/cy8c4147axi_t453.dtsi new file mode 100644 index 000000000000..ac9307c873f1 --- /dev/null +++ b/dts/arm/infineon/psoc4/mpns/cy8c4147axi_t453.dtsi @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "../psoc4100tp/psoc4100tp.44-tqfp.dtsi" + +&flash0 { + reg = <0x00000000 0x20000>; +}; + +&sram0 { + reg = <0x20000000 0x4000>; +}; diff --git a/dts/arm/infineon/psoc4/mpns/cy8c4147axi_t463.dtsi b/dts/arm/infineon/psoc4/mpns/cy8c4147axi_t463.dtsi new file mode 100644 index 000000000000..d5e85fec3715 --- /dev/null +++ b/dts/arm/infineon/psoc4/mpns/cy8c4147axi_t463.dtsi @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "../psoc4100tp/psoc4100tp.44-tqfp.dtsi" + +&flash0 { + reg = <0x00000000 0x20000>; +}; + +&sram0 { + reg = <0x20000000 0x8000>; +}; diff --git a/dts/arm/infineon/psoc4/mpns/cy8c4147axi_t473.dtsi b/dts/arm/infineon/psoc4/mpns/cy8c4147axi_t473.dtsi new file mode 100644 index 000000000000..d5e85fec3715 --- /dev/null +++ b/dts/arm/infineon/psoc4/mpns/cy8c4147axi_t473.dtsi @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "../psoc4100tp/psoc4100tp.44-tqfp.dtsi" + +&flash0 { + reg = <0x00000000 0x20000>; +}; + +&sram0 { + reg = <0x20000000 0x8000>; +}; diff --git a/dts/arm/infineon/psoc4/mpns/cy8c4147axq_t493.dtsi b/dts/arm/infineon/psoc4/mpns/cy8c4147axq_t493.dtsi new file mode 100644 index 000000000000..d5e85fec3715 --- /dev/null +++ b/dts/arm/infineon/psoc4/mpns/cy8c4147axq_t493.dtsi @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "../psoc4100tp/psoc4100tp.44-tqfp.dtsi" + +&flash0 { + reg = <0x00000000 0x20000>; +}; + +&sram0 { + reg = <0x20000000 0x8000>; +}; diff --git a/dts/arm/infineon/psoc4/mpns/cy8c4147azi_t403.dtsi b/dts/arm/infineon/psoc4/mpns/cy8c4147azi_t403.dtsi new file mode 100644 index 000000000000..63542b8e7197 --- /dev/null +++ b/dts/arm/infineon/psoc4/mpns/cy8c4147azi_t403.dtsi @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "../psoc4100tp/psoc4100tp.48-tqfp.dtsi" + +&flash0 { + reg = <0x00000000 0x20000>; +}; + +&sram0 { + reg = <0x20000000 0x4000>; +}; diff --git a/dts/arm/infineon/psoc4/mpns/cy8c4147azi_t405.dtsi b/dts/arm/infineon/psoc4/mpns/cy8c4147azi_t405.dtsi new file mode 100644 index 000000000000..45495e06e7ff --- /dev/null +++ b/dts/arm/infineon/psoc4/mpns/cy8c4147azi_t405.dtsi @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "../psoc4100tp/psoc4100tp.64-tqfp.dtsi" + +&flash0 { + reg = <0x00000000 0x20000>; +}; + +&sram0 { + reg = <0x20000000 0x4000>; +}; diff --git a/dts/arm/infineon/psoc4/mpns/cy8c4147azi_t413.dtsi b/dts/arm/infineon/psoc4/mpns/cy8c4147azi_t413.dtsi new file mode 100644 index 000000000000..63542b8e7197 --- /dev/null +++ b/dts/arm/infineon/psoc4/mpns/cy8c4147azi_t413.dtsi @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "../psoc4100tp/psoc4100tp.48-tqfp.dtsi" + +&flash0 { + reg = <0x00000000 0x20000>; +}; + +&sram0 { + reg = <0x20000000 0x4000>; +}; diff --git a/dts/arm/infineon/psoc4/mpns/cy8c4147azi_t415.dtsi b/dts/arm/infineon/psoc4/mpns/cy8c4147azi_t415.dtsi new file mode 100644 index 000000000000..45495e06e7ff --- /dev/null +++ b/dts/arm/infineon/psoc4/mpns/cy8c4147azi_t415.dtsi @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "../psoc4100tp/psoc4100tp.64-tqfp.dtsi" + +&flash0 { + reg = <0x00000000 0x20000>; +}; + +&sram0 { + reg = <0x20000000 0x4000>; +}; diff --git a/dts/arm/infineon/psoc4/mpns/cy8c4147azi_t453.dtsi b/dts/arm/infineon/psoc4/mpns/cy8c4147azi_t453.dtsi new file mode 100644 index 000000000000..63542b8e7197 --- /dev/null +++ b/dts/arm/infineon/psoc4/mpns/cy8c4147azi_t453.dtsi @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "../psoc4100tp/psoc4100tp.48-tqfp.dtsi" + +&flash0 { + reg = <0x00000000 0x20000>; +}; + +&sram0 { + reg = <0x20000000 0x4000>; +}; diff --git a/dts/arm/infineon/psoc4/mpns/cy8c4147azi_t455.dtsi b/dts/arm/infineon/psoc4/mpns/cy8c4147azi_t455.dtsi new file mode 100644 index 000000000000..45495e06e7ff --- /dev/null +++ b/dts/arm/infineon/psoc4/mpns/cy8c4147azi_t455.dtsi @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "../psoc4100tp/psoc4100tp.64-tqfp.dtsi" + +&flash0 { + reg = <0x00000000 0x20000>; +}; + +&sram0 { + reg = <0x20000000 0x4000>; +}; diff --git a/dts/arm/infineon/psoc4/mpns/cy8c4147azi_t463.dtsi b/dts/arm/infineon/psoc4/mpns/cy8c4147azi_t463.dtsi new file mode 100644 index 000000000000..337f46eec29d --- /dev/null +++ b/dts/arm/infineon/psoc4/mpns/cy8c4147azi_t463.dtsi @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "../psoc4100tp/psoc4100tp.48-tqfp.dtsi" + +&flash0 { + reg = <0x00000000 0x20000>; +}; + +&sram0 { + reg = <0x20000000 0x8000>; +}; diff --git a/dts/arm/infineon/psoc4/mpns/cy8c4147azi_t465.dtsi b/dts/arm/infineon/psoc4/mpns/cy8c4147azi_t465.dtsi new file mode 100644 index 000000000000..06330460525e --- /dev/null +++ b/dts/arm/infineon/psoc4/mpns/cy8c4147azi_t465.dtsi @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "../psoc4100tp/psoc4100tp.64-tqfp.dtsi" + +&flash0 { + reg = <0x00000000 0x20000>; +}; + +&sram0 { + reg = <0x20000000 0x8000>; +}; diff --git a/dts/arm/infineon/psoc4/mpns/cy8c4147azi_t473.dtsi b/dts/arm/infineon/psoc4/mpns/cy8c4147azi_t473.dtsi new file mode 100644 index 000000000000..337f46eec29d --- /dev/null +++ b/dts/arm/infineon/psoc4/mpns/cy8c4147azi_t473.dtsi @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "../psoc4100tp/psoc4100tp.48-tqfp.dtsi" + +&flash0 { + reg = <0x00000000 0x20000>; +}; + +&sram0 { + reg = <0x20000000 0x8000>; +}; diff --git a/dts/arm/infineon/psoc4/mpns/cy8c4147azi_t475.dtsi b/dts/arm/infineon/psoc4/mpns/cy8c4147azi_t475.dtsi new file mode 100644 index 000000000000..06330460525e --- /dev/null +++ b/dts/arm/infineon/psoc4/mpns/cy8c4147azi_t475.dtsi @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "../psoc4100tp/psoc4100tp.64-tqfp.dtsi" + +&flash0 { + reg = <0x00000000 0x20000>; +}; + +&sram0 { + reg = <0x20000000 0x8000>; +}; diff --git a/dts/arm/infineon/psoc4/mpns/cy8c4147azq_t415.dtsi b/dts/arm/infineon/psoc4/mpns/cy8c4147azq_t415.dtsi new file mode 100644 index 000000000000..45495e06e7ff --- /dev/null +++ b/dts/arm/infineon/psoc4/mpns/cy8c4147azq_t415.dtsi @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "../psoc4100tp/psoc4100tp.64-tqfp.dtsi" + +&flash0 { + reg = <0x00000000 0x20000>; +}; + +&sram0 { + reg = <0x20000000 0x4000>; +}; diff --git a/dts/arm/infineon/psoc4/mpns/cy8c4147azq_t455.dtsi b/dts/arm/infineon/psoc4/mpns/cy8c4147azq_t455.dtsi new file mode 100644 index 000000000000..45495e06e7ff --- /dev/null +++ b/dts/arm/infineon/psoc4/mpns/cy8c4147azq_t455.dtsi @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "../psoc4100tp/psoc4100tp.64-tqfp.dtsi" + +&flash0 { + reg = <0x00000000 0x20000>; +}; + +&sram0 { + reg = <0x20000000 0x4000>; +}; diff --git a/dts/arm/infineon/psoc4/mpns/cy8c4147azq_t493.dtsi b/dts/arm/infineon/psoc4/mpns/cy8c4147azq_t493.dtsi new file mode 100644 index 000000000000..337f46eec29d --- /dev/null +++ b/dts/arm/infineon/psoc4/mpns/cy8c4147azq_t493.dtsi @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "../psoc4100tp/psoc4100tp.48-tqfp.dtsi" + +&flash0 { + reg = <0x00000000 0x20000>; +}; + +&sram0 { + reg = <0x20000000 0x8000>; +}; diff --git a/dts/arm/infineon/psoc4/mpns/cy8c4147azq_t495.dtsi b/dts/arm/infineon/psoc4/mpns/cy8c4147azq_t495.dtsi new file mode 100644 index 000000000000..06330460525e --- /dev/null +++ b/dts/arm/infineon/psoc4/mpns/cy8c4147azq_t495.dtsi @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "../psoc4100tp/psoc4100tp.64-tqfp.dtsi" + +&flash0 { + reg = <0x00000000 0x20000>; +}; + +&sram0 { + reg = <0x20000000 0x8000>; +}; diff --git a/dts/arm/infineon/psoc4/mpns/cy8c4147lqi_t403.dtsi b/dts/arm/infineon/psoc4/mpns/cy8c4147lqi_t403.dtsi new file mode 100644 index 000000000000..81936c9980e7 --- /dev/null +++ b/dts/arm/infineon/psoc4/mpns/cy8c4147lqi_t403.dtsi @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "../psoc4100tp/psoc4100tp.48-qfn.dtsi" + +&flash0 { + reg = <0x00000000 0x20000>; +}; + +&sram0 { + reg = <0x20000000 0x4000>; +}; diff --git a/dts/arm/infineon/psoc4/mpns/cy8c4147lqi_t413.dtsi b/dts/arm/infineon/psoc4/mpns/cy8c4147lqi_t413.dtsi new file mode 100644 index 000000000000..81936c9980e7 --- /dev/null +++ b/dts/arm/infineon/psoc4/mpns/cy8c4147lqi_t413.dtsi @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "../psoc4100tp/psoc4100tp.48-qfn.dtsi" + +&flash0 { + reg = <0x00000000 0x20000>; +}; + +&sram0 { + reg = <0x20000000 0x4000>; +}; diff --git a/dts/arm/infineon/psoc4/mpns/cy8c4147lqi_t453.dtsi b/dts/arm/infineon/psoc4/mpns/cy8c4147lqi_t453.dtsi new file mode 100644 index 000000000000..81936c9980e7 --- /dev/null +++ b/dts/arm/infineon/psoc4/mpns/cy8c4147lqi_t453.dtsi @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "../psoc4100tp/psoc4100tp.48-qfn.dtsi" + +&flash0 { + reg = <0x00000000 0x20000>; +}; + +&sram0 { + reg = <0x20000000 0x4000>; +}; diff --git a/dts/arm/infineon/psoc4/mpns/cy8c4147lqi_t463.dtsi b/dts/arm/infineon/psoc4/mpns/cy8c4147lqi_t463.dtsi new file mode 100644 index 000000000000..d826fe752159 --- /dev/null +++ b/dts/arm/infineon/psoc4/mpns/cy8c4147lqi_t463.dtsi @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "../psoc4100tp/psoc4100tp.48-qfn.dtsi" + +&flash0 { + reg = <0x00000000 0x20000>; +}; + +&sram0 { + reg = <0x20000000 0x8000>; +}; diff --git a/dts/arm/infineon/psoc4/mpns/cy8c4147lqi_t473.dtsi b/dts/arm/infineon/psoc4/mpns/cy8c4147lqi_t473.dtsi new file mode 100644 index 000000000000..d826fe752159 --- /dev/null +++ b/dts/arm/infineon/psoc4/mpns/cy8c4147lqi_t473.dtsi @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "../psoc4100tp/psoc4100tp.48-qfn.dtsi" + +&flash0 { + reg = <0x00000000 0x20000>; +}; + +&sram0 { + reg = <0x20000000 0x8000>; +}; diff --git a/dts/arm/infineon/psoc4/mpns/cy8c4147lqq_t493.dtsi b/dts/arm/infineon/psoc4/mpns/cy8c4147lqq_t493.dtsi new file mode 100644 index 000000000000..d826fe752159 --- /dev/null +++ b/dts/arm/infineon/psoc4/mpns/cy8c4147lqq_t493.dtsi @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "../psoc4100tp/psoc4100tp.48-qfn.dtsi" + +&flash0 { + reg = <0x00000000 0x20000>; +}; + +&sram0 { + reg = <0x20000000 0x8000>; +}; From f54955f6d21168f9cd7610bf9daa64199c3fa00b Mon Sep 17 00:00:00 2001 From: Deepika aerlync Date: Mon, 24 Nov 2025 17:54:53 +0530 Subject: [PATCH 0158/3659] soc: infineon: add PSoC4100TP SOC support Add SoC port for the Infineon PSoC4100TP series, including: - Core initialization - Kconfig files - YAML device definitions - SoC-specific pin control configuration Signed-off-by: Manojkumar Konisetty Signed-off-by: Sayooj K Karun Signed-off-by: Deepika aerlync --- soc/infineon/psoc4/CMakeLists.txt | 7 + soc/infineon/psoc4/Kconfig | 6 + soc/infineon/psoc4/Kconfig.defconfig | 10 + soc/infineon/psoc4/Kconfig.soc | 10 + soc/infineon/psoc4/common/CMakeLists.txt | 6 + soc/infineon/psoc4/common/pinctrl_soc.h | 129 +++++++++++ soc/infineon/psoc4/psoc4100tp/CMakeLists.txt | 10 + soc/infineon/psoc4/psoc4100tp/Kconfig | 169 ++++++++++++++ .../psoc4/psoc4100tp/Kconfig.defconfig | 14 ++ soc/infineon/psoc4/psoc4100tp/Kconfig.soc | 217 ++++++++++++++++++ soc/infineon/psoc4/psoc4100tp/soc.c | 21 ++ soc/infineon/psoc4/psoc4100tp/soc.h | 15 ++ soc/infineon/psoc4/soc.yml | 50 ++++ 13 files changed, 664 insertions(+) create mode 100644 soc/infineon/psoc4/CMakeLists.txt create mode 100644 soc/infineon/psoc4/Kconfig create mode 100644 soc/infineon/psoc4/Kconfig.defconfig create mode 100644 soc/infineon/psoc4/Kconfig.soc create mode 100644 soc/infineon/psoc4/common/CMakeLists.txt create mode 100644 soc/infineon/psoc4/common/pinctrl_soc.h create mode 100644 soc/infineon/psoc4/psoc4100tp/CMakeLists.txt create mode 100644 soc/infineon/psoc4/psoc4100tp/Kconfig create mode 100644 soc/infineon/psoc4/psoc4100tp/Kconfig.defconfig create mode 100644 soc/infineon/psoc4/psoc4100tp/Kconfig.soc create mode 100644 soc/infineon/psoc4/psoc4100tp/soc.c create mode 100644 soc/infineon/psoc4/psoc4100tp/soc.h create mode 100644 soc/infineon/psoc4/soc.yml diff --git a/soc/infineon/psoc4/CMakeLists.txt b/soc/infineon/psoc4/CMakeLists.txt new file mode 100644 index 000000000000..bae3262885cc --- /dev/null +++ b/soc/infineon/psoc4/CMakeLists.txt @@ -0,0 +1,7 @@ +# Copyright (c) 2025 Infineon Technologies AG, +# or an affiliate of Infineon Technologies AG. +# +# SPDX-License-Identifier: Apache-2.0 + +add_subdirectory(${SOC_SERIES}) +zephyr_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/common) diff --git a/soc/infineon/psoc4/Kconfig b/soc/infineon/psoc4/Kconfig new file mode 100644 index 000000000000..5eb456ee5199 --- /dev/null +++ b/soc/infineon/psoc4/Kconfig @@ -0,0 +1,6 @@ +# Copyright (c) 2025 Infineon Technologies AG, +# or an affiliate of Infineon Technologies AG. +# +# SPDX-License-Identifier: Apache-2.0 + +rsource "*/Kconfig" diff --git a/soc/infineon/psoc4/Kconfig.defconfig b/soc/infineon/psoc4/Kconfig.defconfig new file mode 100644 index 000000000000..005ea6f4792d --- /dev/null +++ b/soc/infineon/psoc4/Kconfig.defconfig @@ -0,0 +1,10 @@ +# Copyright (c) 2025 Infineon Technologies AG, +# or an affiliate of Infineon Technologies AG. +# +# SPDX-License-Identifier: Apache-2.0 + +if SOC_FAMILY_INFINEON_PSOC4 + +rsource "*/Kconfig.defconfig" + +endif # SOC_FAMILY_INFINEON_PSOC4 diff --git a/soc/infineon/psoc4/Kconfig.soc b/soc/infineon/psoc4/Kconfig.soc new file mode 100644 index 000000000000..734c360e2231 --- /dev/null +++ b/soc/infineon/psoc4/Kconfig.soc @@ -0,0 +1,10 @@ +# Copyright (c) 2025 Infineon Technologies AG, +# or an affiliate of Infineon Technologies AG. +# +# SPDX-License-Identifier: Apache-2.0 + +# Family definitions +config SOC_FAMILY_INFINEON_PSOC4 + bool + +rsource "*/Kconfig.soc" diff --git a/soc/infineon/psoc4/common/CMakeLists.txt b/soc/infineon/psoc4/common/CMakeLists.txt new file mode 100644 index 000000000000..4a6459f1607a --- /dev/null +++ b/soc/infineon/psoc4/common/CMakeLists.txt @@ -0,0 +1,6 @@ +# Copyright (c) 2025 Infineon Technologies AG, +# or an affiliate of Infineon Technologies AG. +# +# SPDX-License-Identifier: Apache-2.0 + +zephyr_include_directories(.) diff --git a/soc/infineon/psoc4/common/pinctrl_soc.h b/soc/infineon/psoc4/common/pinctrl_soc.h new file mode 100644 index 000000000000..213cf8de62cb --- /dev/null +++ b/soc/infineon/psoc4/common/pinctrl_soc.h @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2016-2017 Piotr Mienkowski + * Copyright (c) 2021 ATL Electronics + * Copyright (c) 2022 Cypress Semiconductor Corporation (an Infineon company) or + * an affiliate of Cypress Semiconductor Corporation + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +/** + * @brief Infineon CAT1 SoC specific helpers for pinctrl driver. + */ + +#ifndef ZEPHYR_SOC_ARM_INFINEON_CAT1_COMMON_PINCTRL_SOC_H_ +#define ZEPHYR_SOC_ARM_INFINEON_CAT1_COMMON_PINCTRL_SOC_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @cond INTERNAL_HIDDEN */ + +/** + * Bit definition in PINMUX field + */ +#define SOC_PINMUX_PORT_POS (0) +#define SOC_PINMUX_PORT_MASK (0xFFul << SOC_PINMUX_PORT_POS) +#define SOC_PINMUX_PIN_POS (8) +#define SOC_PINMUX_PIN_MASK (0xFFul << SOC_PINMUX_PIN_POS) +#define SOC_PINMUX_HSIOM_FUNC_POS (16) +#define SOC_PINMUX_HSIOM_MASK (0xFFul << SOC_PINMUX_HSIOM_FUNC_POS) +#define SOC_PINMUX_SIGNAL_POS (24) +#define SOC_PINMUX_SIGNAL_MASK (0xFFul << SOC_PINMUX_SIGNAL_POS) + +/* + * Pin flags/attributes + */ +#define SOC_GPIO_DEFAULT (0) +#define SOC_GPIO_FLAGS_POS (0) +#define SOC_GPIO_FLAGS_MASK (0x3F << SOC_GPIO_FLAGS_POS) +#define SOC_GPIO_PULLUP_POS (0) +#define SOC_GPIO_PULLUP (1 << SOC_GPIO_PULLUP_POS) +#define SOC_GPIO_PULLDOWN_POS (1) +#define SOC_GPIO_PULLDOWN (1 << SOC_GPIO_PULLDOWN_POS) +#define SOC_GPIO_OPENDRAIN_POS (2) +#define SOC_GPIO_OPENDRAIN (1 << SOC_GPIO_OPENDRAIN_POS) +#define SOC_GPIO_OPENSOURCE_POS (3) +#define SOC_GPIO_OPENSOURCE (1 << SOC_GPIO_OPENSOURCE_POS) + +/* Push-Pull means Strong, see dts/pinctrl/pincfg-node.yaml */ +#define SOC_GPIO_PUSHPULL_POS (4) +#define SOC_GPIO_PUSHPULL (1 << SOC_GPIO_PUSHPULL_POS) + +/* Input-Enable means Input-Buffer, see dts/pinctrl/pincfg-node.yaml */ +#define SOC_GPIO_INPUTENABLE_POS (5) +#define SOC_GPIO_INPUTENABLE (1 << SOC_GPIO_INPUTENABLE_POS) + +#define SOC_GPIO_HIGHZ_POS (6) +#define SOC_GPIO_HIGHZ (1 << SOC_GPIO_HIGHZ_POS) + +/** Type for CAT1 Soc pin. */ +typedef struct { + /** + * Pinmux settings (port, pin and function). + * [0..7] - Port nunder + * [8..15] - Pin number + * [16..23]- HSIOM function + */ + uint32_t pinmux; + + /** Pin configuration (bias, drive and slew rate). */ + uint32_t pincfg; +} pinctrl_soc_pin_t; + +#define CAT1_PINMUX_GET_PORT_NUM(pinmux) (((pinmux) & SOC_PINMUX_PORT_MASK) >> SOC_PINMUX_PORT_POS) +#define CAT1_PINMUX_GET_PIN_NUM(pinmux) (((pinmux) & SOC_PINMUX_PIN_MASK) >> SOC_PINMUX_PIN_POS) +#define CAT1_PINMUX_GET_HSIOM_FUNC(pinmux) \ + (((pinmux) & SOC_PINMUX_HSIOM_MASK) >> SOC_PINMUX_HSIOM_FUNC_POS) + +/** + * @brief Utility macro to initialize pinmux field in #pinctrl_pin_t. + * @param node_id Node identifier. + */ +#define Z_PINCTRL_CAT1_PINMUX_INIT(node_id) DT_PROP(node_id, pinmux) + +/** + * @brief Utility macro to initialize pincfg field in #pinctrl_pin_t. + * @param node_id Node identifier. + */ +#define Z_PINCTRL_CAT1_PINCFG_INIT(node_id) \ + ((DT_PROP(node_id, bias_pull_up) << SOC_GPIO_PULLUP_POS) | \ + (DT_PROP(node_id, bias_pull_down) << SOC_GPIO_PULLDOWN_POS) | \ + (DT_PROP(node_id, drive_open_drain) << SOC_GPIO_OPENDRAIN_POS) | \ + (DT_PROP(node_id, drive_open_source) << SOC_GPIO_OPENSOURCE_POS) | \ + (DT_PROP(node_id, drive_push_pull) << SOC_GPIO_PUSHPULL_POS) | \ + (DT_PROP(node_id, input_enable) << SOC_GPIO_INPUTENABLE_POS) | \ + (DT_PROP(node_id, bias_high_impedance) << SOC_GPIO_HIGHZ_POS)) + +/** + * @brief Utility macro to initialize each pin. + * + * @param node_id Node identifier. + * @param state_prop State property name. + * @param idx State property entry index. + */ +#define Z_PINCTRL_STATE_PIN_INIT(node_id, state_prop, idx) \ + {.pinmux = Z_PINCTRL_CAT1_PINMUX_INIT(DT_PROP_BY_IDX(node_id, state_prop, idx)), \ + .pincfg = Z_PINCTRL_CAT1_PINCFG_INIT(DT_PROP_BY_IDX(node_id, state_prop, idx))}, + +/** + * @brief Utility macro to initialize state pins contained in a given property. + * + * @param node_id Node identifier. + * @param prop Property name describing state pins. + */ +#define Z_PINCTRL_STATE_PINS_INIT(node_id, prop) \ + {DT_FOREACH_PROP_ELEM(node_id, prop, Z_PINCTRL_STATE_PIN_INIT)} + +/** @endcond */ + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_SOC_ARM_INFINEON_CAT1_COMMON_PINCTRL_SOC_H_ */ diff --git a/soc/infineon/psoc4/psoc4100tp/CMakeLists.txt b/soc/infineon/psoc4/psoc4100tp/CMakeLists.txt new file mode 100644 index 000000000000..638c47e666a4 --- /dev/null +++ b/soc/infineon/psoc4/psoc4100tp/CMakeLists.txt @@ -0,0 +1,10 @@ +# Copyright (c) 2025 Infineon Technologies AG, +# or an affiliate of Infineon Technologies AG. +# +# SPDX-License-Identifier: Apache-2.0 + +zephyr_sources(soc.c) +zephyr_include_directories(.) + +#default Zephyr linker script +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/infineon/psoc4/psoc4100tp/Kconfig b/soc/infineon/psoc4/psoc4100tp/Kconfig new file mode 100644 index 000000000000..c28d2496aa06 --- /dev/null +++ b/soc/infineon/psoc4/psoc4100tp/Kconfig @@ -0,0 +1,169 @@ +# Copyright (c) 2025 Infineon Technologies AG, +# or an affiliate of Infineon Technologies AG. +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# SOC Packages for Infineon PSOC4100Tp series MCUs +config SOC_PACKAGE_PSOC4100TP_64_TQFP + bool + help + 64-pin TQFP package + +config SOC_PACKAGE_PSOC4100TP_48_TQFP + bool + help + 48-pin TQFP package + +config SOC_PACKAGE_PSOC4100TP_48_QFN + bool + help + 48-pin QFN package + +config SOC_PACKAGE_PSOC4100TP_44_TQFP + bool + help + 44-pin TQFP package + +# Hardware configuration for PSOC4100TP series +config SOC_SERIES_PSOC4100TP + select ARM + select CPU_CORTEX_M0PLUS + select CPU_CORTEX_M_HAS_VTOR + select BUILD_OUTPUT_HEX + select BUILD_OUTPUT_BIN + select DYNAMIC_INTERRUPTS + select SOC_EARLY_INIT_HOOK + select CPU_CORTEX_M_HAS_SYSTICK + +# Infineon PSOC4100Tp series MPNs +config SOC_CY8C4146LQI_T403 + select SOC_PACKAGE_PSOC4100TP_48_QFN + +config SOC_CY8C4146AXI_T403 + select SOC_PACKAGE_PSOC4100TP_44_TQFP + +config SOC_CY8C4146AZI_T403 + select SOC_PACKAGE_PSOC4100TP_48_TQFP + +config SOC_CY8C4146AZI_T405 + select SOC_PACKAGE_PSOC4100TP_64_TQFP + +config SOC_CY8C4146LQI_T413 + select SOC_PACKAGE_PSOC4100TP_48_QFN + +config SOC_CY8C4146AXI_T413 + select SOC_PACKAGE_PSOC4100TP_44_TQFP + +config SOC_CY8C4146AZI_T413 + select SOC_PACKAGE_PSOC4100TP_48_TQFP + +config SOC_CY8C4146AZI_T415 + select SOC_PACKAGE_PSOC4100TP_64_TQFP + +config SOC_CY8C4146LQI_T453 + select SOC_PACKAGE_PSOC4100TP_48_QFN + +config SOC_CY8C4146AXI_T453 + select SOC_PACKAGE_PSOC4100TP_44_TQFP + +config SOC_CY8C4146AZI_T453 + select SOC_PACKAGE_PSOC4100TP_48_TQFP + +config SOC_CY8C4146AZI_T455 + select SOC_PACKAGE_PSOC4100TP_64_TQFP + +config SOC_CY8C4147LQI_T403 + select SOC_PACKAGE_PSOC4100TP_48_QFN + +config SOC_CY8C4147AXI_T403 + select SOC_PACKAGE_PSOC4100TP_44_TQFP + +config SOC_CY8C4147AZI_T403 + select SOC_PACKAGE_PSOC4100TP_48_TQFP + +config SOC_CY8C4147AZI_T405 + select SOC_PACKAGE_PSOC4100TP_64_TQFP + +config SOC_CY8C4147LQI_T413 + select SOC_PACKAGE_PSOC4100TP_48_QFN + +config SOC_CY8C4147AXI_T413 + select SOC_PACKAGE_PSOC4100TP_44_TQFP + +config SOC_CY8C4147AZI_T413 + select SOC_PACKAGE_PSOC4100TP_48_TQFP + +config SOC_CY8C4147AZI_T415 + select SOC_PACKAGE_PSOC4100TP_64_TQFP + +config SOC_CY8C4147LQI_T453 + select SOC_PACKAGE_PSOC4100TP_48_QFN + +config SOC_CY8C4147AXI_T453 + select SOC_PACKAGE_PSOC4100TP_44_TQFP + +config SOC_CY8C4147AZI_T453 + select SOC_PACKAGE_PSOC4100TP_48_TQFP + +config SOC_CY8C4147AZI_T455 + select SOC_PACKAGE_PSOC4100TP_64_TQFP + +config SOC_CY8C4147LQI_T463 + select SOC_PACKAGE_PSOC4100TP_48_QFN + +config SOC_CY8C4147AXI_T463 + select SOC_PACKAGE_PSOC4100TP_44_TQFP + +config SOC_CY8C4147AZI_T463 + select SOC_PACKAGE_PSOC4100TP_48_TQFP + +config SOC_CY8C4147AZI_T465 + select SOC_PACKAGE_PSOC4100TP_64_TQFP + +config SOC_CY8C4147LQI_T473 + select SOC_PACKAGE_PSOC4100TP_48_QFN + +config SOC_CY8C4147AXI_T473 + select SOC_PACKAGE_PSOC4100TP_44_TQFP + +config SOC_CY8C4147AZI_T473 + select SOC_PACKAGE_PSOC4100TP_48_TQFP + +config SOC_CY8C4147AZI_T475 + select SOC_PACKAGE_PSOC4100TP_64_TQFP + +config SOC_CY8C4147LQQ_T493 + select SOC_PACKAGE_PSOC4100TP_48_QFN + +config SOC_CY8C4147AXQ_T493 + select SOC_PACKAGE_PSOC4100TP_44_TQFP + +config SOC_CY8C4147AZQ_T493 + select SOC_PACKAGE_PSOC4100TP_48_TQFP + +config SOC_CY8C4147AZQ_T495 + select SOC_PACKAGE_PSOC4100TP_64_TQFP + +config SOC_CY8C4146AZQ_T413 + select SOC_PACKAGE_PSOC4100TP_48_TQFP + +config SOC_CY8C4146AZQ_T453 + select SOC_PACKAGE_PSOC4100TP_48_TQFP + +config SOC_CY8C4147AZQ_T415 + select SOC_PACKAGE_PSOC4100TP_64_TQFP + +config SOC_CY8C4147AZQ_T455 + select SOC_PACKAGE_PSOC4100TP_64_TQFP diff --git a/soc/infineon/psoc4/psoc4100tp/Kconfig.defconfig b/soc/infineon/psoc4/psoc4100tp/Kconfig.defconfig new file mode 100644 index 000000000000..13c925706e43 --- /dev/null +++ b/soc/infineon/psoc4/psoc4100tp/Kconfig.defconfig @@ -0,0 +1,14 @@ +# Copyright (c) 2025 Infineon Technologies AG, +# or an affiliate of Infineon Technologies AG. +# +# SPDX-License-Identifier: Apache-2.0 + +if SOC_SERIES_PSOC4100TP + +config NUM_IRQS + default 23 + +config SYS_CLOCK_HW_CYCLES_PER_SEC + default $(dt_node_int_prop_int,/cpus/cpu@0,clock-frequency) + +endif # SOC_SERIES_PSOC4100TP diff --git a/soc/infineon/psoc4/psoc4100tp/Kconfig.soc b/soc/infineon/psoc4/psoc4100tp/Kconfig.soc new file mode 100644 index 000000000000..093303b85a9a --- /dev/null +++ b/soc/infineon/psoc4/psoc4100tp/Kconfig.soc @@ -0,0 +1,217 @@ +# Copyright (c) 2025 Infineon Technologies AG, +# or an affiliate of Infineon Technologies AG. +# +# SPDX-License-Identifier: Apache-2.0 + +# MCU series +config SOC_SERIES_PSOC4100TP + bool + select SOC_FAMILY_INFINEON_PSOC4 + help + PSOC4100tp Series MCU + +config SOC_SERIES + default "psoc4100tp" if SOC_SERIES_PSOC4100TP + +config SOC_CY8C4146LQI_T403 + bool + select SOC_SERIES_PSOC4100TP + +config SOC_CY8C4146AXI_T403 + bool + select SOC_SERIES_PSOC4100TP + +config SOC_CY8C4146AZI_T403 + bool + select SOC_SERIES_PSOC4100TP + +config SOC_CY8C4146AZI_T405 + bool + select SOC_SERIES_PSOC4100TP + +config SOC_CY8C4146LQI_T413 + bool + select SOC_SERIES_PSOC4100TP + +config SOC_CY8C4146AXI_T413 + bool + select SOC_SERIES_PSOC4100TP + +config SOC_CY8C4146AZI_T413 + bool + select SOC_SERIES_PSOC4100TP + +config SOC_CY8C4146AZI_T415 + bool + select SOC_SERIES_PSOC4100TP + +config SOC_CY8C4146LQI_T453 + bool + select SOC_SERIES_PSOC4100TP + +config SOC_CY8C4146AXI_T453 + bool + select SOC_SERIES_PSOC4100TP + +config SOC_CY8C4146AZI_T453 + bool + select SOC_SERIES_PSOC4100TP + +config SOC_CY8C4146AZI_T455 + bool + select SOC_SERIES_PSOC4100TP + +config SOC_CY8C4147LQI_T403 + bool + select SOC_SERIES_PSOC4100TP + +config SOC_CY8C4147AXI_T403 + bool + select SOC_SERIES_PSOC4100TP + +config SOC_CY8C4147AZI_T403 + bool + select SOC_SERIES_PSOC4100TP + +config SOC_CY8C4147AZI_T405 + bool + select SOC_SERIES_PSOC4100TP + +config SOC_CY8C4147LQI_T413 + bool + select SOC_SERIES_PSOC4100TP + +config SOC_CY8C4147AXI_T413 + bool + select SOC_SERIES_PSOC4100TP + +config SOC_CY8C4147AZI_T413 + bool + select SOC_SERIES_PSOC4100TP + +config SOC_CY8C4147AZI_T415 + bool + select SOC_SERIES_PSOC4100TP + +config SOC_CY8C4147LQI_T453 + bool + select SOC_SERIES_PSOC4100TP + +config SOC_CY8C4147AXI_T453 + bool + select SOC_SERIES_PSOC4100TP + +config SOC_CY8C4147AZI_T453 + bool + select SOC_SERIES_PSOC4100TP + +config SOC_CY8C4147AZI_T455 + bool + select SOC_SERIES_PSOC4100TP + +config SOC_CY8C4147LQI_T463 + bool + select SOC_SERIES_PSOC4100TP + +config SOC_CY8C4147AXI_T463 + bool + select SOC_SERIES_PSOC4100TP + +config SOC_CY8C4147AZI_T463 + bool + select SOC_SERIES_PSOC4100TP + +config SOC_CY8C4147AZI_T465 + bool + select SOC_SERIES_PSOC4100TP + +config SOC_CY8C4147LQI_T473 + bool + select SOC_SERIES_PSOC4100TP + +config SOC_CY8C4147AXI_T473 + bool + select SOC_SERIES_PSOC4100TP + +config SOC_CY8C4147AZI_T473 + bool + select SOC_SERIES_PSOC4100TP + +config SOC_CY8C4147AZI_T475 + bool + select SOC_SERIES_PSOC4100TP + +config SOC_CY8C4147LQQ_T493 + bool + select SOC_SERIES_PSOC4100TP + +config SOC_CY8C4147AXQ_T493 + bool + select SOC_SERIES_PSOC4100TP + +config SOC_CY8C4147AZQ_T493 + bool + select SOC_SERIES_PSOC4100TP + +config SOC_CY8C4147AZQ_T495 + bool + select SOC_SERIES_PSOC4100TP + +config SOC_CY8C4146AZQ_T413 + bool + select SOC_SERIES_PSOC4100TP + +config SOC_CY8C4146AZQ_T453 + bool + select SOC_SERIES_PSOC4100TP + +config SOC_CY8C4147AZQ_T415 + bool + select SOC_SERIES_PSOC4100TP + +config SOC_CY8C4147AZQ_T455 + bool + select SOC_SERIES_PSOC4100TP + +# Default SOC selection +config SOC + default "cy8c4146lqi_t403" if SOC_CY8C4146LQI_T403 + default "cy8c4146axi_t403" if SOC_CY8C4146AXI_T403 + default "cy8c4146azi_t403" if SOC_CY8C4146AZI_T403 + default "cy8c4146azi_t405" if SOC_CY8C4146AZI_T405 + default "cy8c4146lqi_t413" if SOC_CY8C4146LQI_T413 + default "cy8c4146axi_t413" if SOC_CY8C4146AXI_T413 + default "cy8c4146azi_t413" if SOC_CY8C4146AZI_T413 + default "cy8c4146azi_t415" if SOC_CY8C4146AZI_T415 + default "cy8c4146lqi_t453" if SOC_CY8C4146LQI_T453 + default "cy8c4146axi_t453" if SOC_CY8C4146AXI_T453 + default "cy8c4146azi_t453" if SOC_CY8C4146AZI_T453 + default "cy8c4146azi_t455" if SOC_CY8C4146AZI_T455 + default "cy8c4147lqi_t403" if SOC_CY8C4147LQI_T403 + default "cy8c4147axi_t403" if SOC_CY8C4147AXI_T403 + default "cy8c4147azi_t403" if SOC_CY8C4147AZI_T403 + default "cy8c4147azi_t405" if SOC_CY8C4147AZI_T405 + default "cy8c4147lqi_t413" if SOC_CY8C4147LQI_T413 + default "cy8c4147axi_t413" if SOC_CY8C4147AXI_T413 + default "cy8c4147azi_t413" if SOC_CY8C4147AZI_T413 + default "cy8c4147azi_t415" if SOC_CY8C4147AZI_T415 + default "cy8c4147lqi_t453" if SOC_CY8C4147LQI_T453 + default "cy8c4147axi_t453" if SOC_CY8C4147AXI_T453 + default "cy8c4147azi_t453" if SOC_CY8C4147AZI_T453 + default "cy8c4147azi_t455" if SOC_CY8C4147AZI_T455 + default "cy8c4147lqi_t463" if SOC_CY8C4147LQI_T463 + default "cy8c4147axi_t463" if SOC_CY8C4147AXI_T463 + default "cy8c4147azi_t463" if SOC_CY8C4147AZI_T463 + default "cy8c4147azi_t465" if SOC_CY8C4147AZI_T465 + default "cy8c4147lqi_t473" if SOC_CY8C4147LQI_T473 + default "cy8c4147axi_t473" if SOC_CY8C4147AXI_T473 + default "cy8c4147azi_t473" if SOC_CY8C4147AZI_T473 + default "cy8c4147azi_t475" if SOC_CY8C4147AZI_T475 + default "cy8c4147lqq_t493" if SOC_CY8C4147LQQ_T493 + default "cy8c4147axq_t493" if SOC_CY8C4147AXQ_T493 + default "cy8c4147azq_t493" if SOC_CY8C4147AZQ_T493 + default "cy8c4147azq_t495" if SOC_CY8C4147AZQ_T495 + default "cy8c4146azq_t413" if SOC_CY8C4146AZQ_T413 + default "cy8c4146azq_t453" if SOC_CY8C4146AZQ_T453 + default "cy8c4147azq_t415" if SOC_CY8C4147AZQ_T415 + default "cy8c4147azq_t455" if SOC_CY8C4147AZQ_T455 diff --git a/soc/infineon/psoc4/psoc4100tp/soc.c b/soc/infineon/psoc4/psoc4100tp/soc.c new file mode 100644 index 000000000000..5ad95ebaa986 --- /dev/null +++ b/soc/infineon/psoc4/psoc4100tp/soc.c @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#include +#include /* PSoC4 system init header from PDL */ +#include "cy_pdl.h" + +/* Minimal early initialization for PSOC4100tp */ +void soc_early_init_hook(void) +{ + /* Initializes the system */ + SystemInit(); +} diff --git a/soc/infineon/psoc4/psoc4100tp/soc.h b/soc/infineon/psoc4/psoc4100tp/soc.h new file mode 100644 index 000000000000..ce0ec4825199 --- /dev/null +++ b/soc/infineon/psoc4/psoc4100tp/soc.h @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_SOC_INFINEON_PSOC4_PSOC4100TP_SOC_H_ +#define ZEPHYR_SOC_INFINEON_PSOC4_PSOC4100TP_SOC_H_ + +#ifndef _ASMLANGUAGE +#include +#endif /* !_ASMLANGUAGE */ + +#endif /* ZEPHYR_SOC_INFINEON_PSOC4_PSOC4100TP_SOC_H_ */ diff --git a/soc/infineon/psoc4/soc.yml b/soc/infineon/psoc4/soc.yml new file mode 100644 index 000000000000..2938ebf605e7 --- /dev/null +++ b/soc/infineon/psoc4/soc.yml @@ -0,0 +1,50 @@ +# Copyright (c) 2025 Infineon Technologies AG, +# or an affiliate of Infineon Technologies AG. +# +# SPDX-License-Identifier: Apache-2.0 + +family: +- name: psoc4 + series: + - name: psoc4100tp + socs: + - name: cy8c4146lqi_t403 + - name: cy8c4146axi_t403 + - name: cy8c4146azi_t403 + - name: cy8c4146azi_t405 + - name: cy8c4146lqi_t413 + - name: cy8c4146axi_t413 + - name: cy8c4146azi_t413 + - name: cy8c4146azi_t415 + - name: cy8c4146lqi_t453 + - name: cy8c4146axi_t453 + - name: cy8c4146azi_t453 + - name: cy8c4146azi_t455 + - name: cy8c4147lqi_t403 + - name: cy8c4147axi_t403 + - name: cy8c4147azi_t403 + - name: cy8c4147azi_t405 + - name: cy8c4147lqi_t413 + - name: cy8c4147axi_t413 + - name: cy8c4147azi_t413 + - name: cy8c4147azi_t415 + - name: cy8c4147lqi_t453 + - name: cy8c4147axi_t453 + - name: cy8c4147azi_t453 + - name: cy8c4147azi_t455 + - name: cy8c4147lqi_t463 + - name: cy8c4147axi_t463 + - name: cy8c4147azi_t463 + - name: cy8c4147azi_t465 + - name: cy8c4147lqi_t473 + - name: cy8c4147axi_t473 + - name: cy8c4147azi_t473 + - name: cy8c4147azi_t475 + - name: cy8c4147lqq_t493 + - name: cy8c4147axq_t493 + - name: cy8c4147azq_t493 + - name: cy8c4147azq_t495 + - name: cy8c4146azq_t413 + - name: cy8c4146azq_t453 + - name: cy8c4147azq_t415 + - name: cy8c4147azq_t455 From ccabf2457fbe157c91d3fcd989b9e57155318d6a Mon Sep 17 00:00:00 2001 From: Deepika aerlync Date: Mon, 24 Nov 2025 17:54:57 +0530 Subject: [PATCH 0159/3659] boards: infineon: add CY8CPROTO-041TP board support Add board porting for the Infineon CY8CPROTO-041TP evaluation kit: - Board devicetree and pinctrl configuration - Kconfig and YAML definitions - Documentation - Support for west build, west flash, and west debug (OpenOCD) Signed-off-by: Manojkumar Konisetty Signed-off-by: Sayooj K Karun Signed-off-by: Deepika aerlync --- .../cy8cproto_041tp/Kconfig.cy8cproto_041tp | 7 ++ boards/infineon/cy8cproto_041tp/board.cmake | 10 ++ boards/infineon/cy8cproto_041tp/board.yml | 11 ++ .../cy8cproto_041tp-pinctrl.dtsi | 15 +++ .../cy8cproto_041tp/cy8cproto_041tp.dts | 47 ++++++++ .../cy8cproto_041tp/cy8cproto_041tp.yaml | 19 ++++ .../cy8cproto_041tp/cy8cproto_041tp_defconfig | 14 +++ .../infineon/cy8cproto_041tp/docs/index.rst | 102 ++++++++++++++++++ .../cy8cproto_041tp/support/openocd.cfg | 19 ++++ 9 files changed, 244 insertions(+) create mode 100644 boards/infineon/cy8cproto_041tp/Kconfig.cy8cproto_041tp create mode 100644 boards/infineon/cy8cproto_041tp/board.cmake create mode 100644 boards/infineon/cy8cproto_041tp/board.yml create mode 100644 boards/infineon/cy8cproto_041tp/cy8cproto_041tp-pinctrl.dtsi create mode 100644 boards/infineon/cy8cproto_041tp/cy8cproto_041tp.dts create mode 100644 boards/infineon/cy8cproto_041tp/cy8cproto_041tp.yaml create mode 100644 boards/infineon/cy8cproto_041tp/cy8cproto_041tp_defconfig create mode 100644 boards/infineon/cy8cproto_041tp/docs/index.rst create mode 100644 boards/infineon/cy8cproto_041tp/support/openocd.cfg diff --git a/boards/infineon/cy8cproto_041tp/Kconfig.cy8cproto_041tp b/boards/infineon/cy8cproto_041tp/Kconfig.cy8cproto_041tp new file mode 100644 index 000000000000..6a67a704be75 --- /dev/null +++ b/boards/infineon/cy8cproto_041tp/Kconfig.cy8cproto_041tp @@ -0,0 +1,7 @@ +# Copyright (c) 2025 Infineon Technologies AG, +# or an affiliate of Infineon Technologies AG. +# +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_CY8CPROTO_041TP + select SOC_CY8C4147AZQ_T495 diff --git a/boards/infineon/cy8cproto_041tp/board.cmake b/boards/infineon/cy8cproto_041tp/board.cmake new file mode 100644 index 000000000000..8254533de3f3 --- /dev/null +++ b/boards/infineon/cy8cproto_041tp/board.cmake @@ -0,0 +1,10 @@ +# Copyright (c) 2025 Infineon Technologies AG, +# or an affiliate of Infineon Technologies AG. +# +# SPDX-License-Identifier: Apache-2.0 + +# OpenOCD cfg +board_runner_args(openocd "--config=${ZEPHYR_BASE}/boards/infineon/cy8cproto_041tp/support/openocd.cfg") + +# Include standard OpenOCD runner helpers +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) diff --git a/boards/infineon/cy8cproto_041tp/board.yml b/boards/infineon/cy8cproto_041tp/board.yml new file mode 100644 index 000000000000..04c79ee47168 --- /dev/null +++ b/boards/infineon/cy8cproto_041tp/board.yml @@ -0,0 +1,11 @@ +# Copyright (c) 2025 Infineon Technologies AG, +# or an affiliate of Infineon Technologies AG. +# +# SPDX-License-Identifier: Apache-2.0 + +board: + name: cy8cproto_041tp + full_name: CY8CPROTO-041TP + vendor: infineon + socs: + - name: cy8c4147azq_t495 diff --git a/boards/infineon/cy8cproto_041tp/cy8cproto_041tp-pinctrl.dtsi b/boards/infineon/cy8cproto_041tp/cy8cproto_041tp-pinctrl.dtsi new file mode 100644 index 000000000000..69a0a2db88ec --- /dev/null +++ b/boards/infineon/cy8cproto_041tp/cy8cproto_041tp-pinctrl.dtsi @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* Configure pin drive mode for uart pins */ +&p5_2_scb0_uart_tx { + drive-push-pull; +}; + +&p5_1_scb0_uart_rx { + input-enable; +}; diff --git a/boards/infineon/cy8cproto_041tp/cy8cproto_041tp.dts b/boards/infineon/cy8cproto_041tp/cy8cproto_041tp.dts new file mode 100644 index 000000000000..4319fc89fe79 --- /dev/null +++ b/boards/infineon/cy8cproto_041tp/cy8cproto_041tp.dts @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include +#include "cy8cproto_041tp-pinctrl.dtsi" + +/ { + model = "CY8CPROTO-041TP Development Board"; + compatible = "infineon,cy8cproto-041tp", "infineon,psoc4100tp"; + + chosen { + zephyr,sram = &sram0; + zephyr,flash = &flash0; + zephyr,console = &uart0; + zephyr,shell-uart = &uart0; + }; +}; + +uart0: &scb0 { + compatible = "infineon,cat1-uart"; + status = "okay"; + current-speed = <115200>; + clocks = <&peri0_group0_16bit_0>; + pinctrl-0 = <&p5_2_scb0_uart_tx &p5_1_scb0_uart_rx>; + pinctrl-names = "default"; +}; + +&peri0_group0_16bit_0 { + status = "okay"; + resource-type = ; + resource-instance = <0>; + clock-div = <26>; +}; + +&hf_clk_sel { + status = "okay"; +}; + +&clk_hf0 { + status = "okay"; +}; diff --git a/boards/infineon/cy8cproto_041tp/cy8cproto_041tp.yaml b/boards/infineon/cy8cproto_041tp/cy8cproto_041tp.yaml new file mode 100644 index 000000000000..7053a2254b9c --- /dev/null +++ b/boards/infineon/cy8cproto_041tp/cy8cproto_041tp.yaml @@ -0,0 +1,19 @@ +# Copyright (c) 2025 Infineon Technologies AG, +# or an affiliate of Infineon Technologies AG. +# +# SPDX-License-Identifier: Apache-2.0 + +identifier: cy8cproto_041tp +name: CY8CPROTO-041TP Development Board +type: mcu +arch: arm +ram: 32 +flash: 128 +toolchain: + - zephyr + - gnuarmemb +supported: + - uart + - clock_control + - pin_ctrl +vendor: infineon diff --git a/boards/infineon/cy8cproto_041tp/cy8cproto_041tp_defconfig b/boards/infineon/cy8cproto_041tp/cy8cproto_041tp_defconfig new file mode 100644 index 000000000000..ab312bcd2d16 --- /dev/null +++ b/boards/infineon/cy8cproto_041tp/cy8cproto_041tp_defconfig @@ -0,0 +1,14 @@ +# Copyright (c) 2025 Infineon Technologies AG, +# or an affiliate of Infineon Technologies AG. +# +# SPDX-License-Identifier: Apache-2.0 + +# Console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# UART driver +CONFIG_SERIAL=y + +# Clock controller +CONFIG_CLOCK_CONTROL=y diff --git a/boards/infineon/cy8cproto_041tp/docs/index.rst b/boards/infineon/cy8cproto_041tp/docs/index.rst new file mode 100644 index 000000000000..8f0edacb4c74 --- /dev/null +++ b/boards/infineon/cy8cproto_041tp/docs/index.rst @@ -0,0 +1,102 @@ +.. zephyr:board:: cy8cproto_041tp + +Overview +******** + +The PSOC™ 4100T Plus evaluation kit enables you to evaluate and develop applications using the PSOC™ 4100T Plus microcontroller, part of Infineon’s PSOC™ 4 family. +The device integrates an Arm Cortex-M0 CPU running up to 48 MHz, combining programmable analog and digital subsystems to support flexible mixed-signal designs. It features up to 128 KB Flash and 16 KB SRAM, and includes a wide range of configurable peripherals such as SAR ADC, comparators, opamps (CTBm), CapSense™ capacitive touch sensing, and TCPWM for timer/counter/PWM functionality. + +32-bit MCU subsystem +- 48-MHz Arm® Cortex®-M0+ CPU with single-cycle multiply +- Up to 128 KB of flash with read accelerator +- Up to 32 KB of SRAM +- Direct memory access (DMA) +- Low-power 1.71 V to 5.5 V operation +- Deep sleep mode with 6 μA always-on touch sensing +- Active touch detection and tracking with 200 μA (average) +- Real Time clock-SW is available +- Power supply: 3.3 V or 5 V operation + +Programming and Debugging +************************* + +.. zephyr:board-supported-runners:: + +Building +======== + +Here is an example for building the :zephyr:code-sample:`hello_world` sample application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: cy8cproto_041tp + :goals: build + +Flashing +======== + +The KIT_XMC72_EVK includes an onboard programmer/debugger (`KitProg3`_) to provide debugging, flash programming, and serial communication over USB. Flash and debug commands use OpenOCD and require a custom Infineon OpenOCD version, that supports KitProg3, to be installed. + +Infineon OpenOCD Installation +============================= + +Both the full `ModusToolbox`_ and the `ModusToolbox Programming Tools`_ packages include Infineon OpenOCD. +Installing either of these packages will also install Infineon OpenOCD. + +If neither package is installed, a minimal installation can be done by downloading the `Infineon OpenOCD`_ release for your system and manually extract the files to a location of your choice. + +.. note:: Linux requires device access rights to be set up for KitProg3. This is handled automatically by the ModusToolbox and ModusToolbox Programming Tools installations. When doing a minimal installation, this can be done manually by executing the script ``openocd/udev_rules/install_rules.sh``. + +West Commands +============= + +The path to the installed Infineon OpenOCD executable must be available to the ``west`` tool commands. There are multiple ways of doing this. The example below uses a permanent CMake argument to set the CMake variable ``OPENOCD``. + + .. tabs:: + .. group-tab:: Windows + + .. code-block:: shell + + # Run west config once to set permanent CMake argument + west config build.cmake-args -- -DOPENOCD=path/to/infineon/openocd/bin/openocd.exe + + # Do a pristine build once after setting CMake argument + west build -b cy8cproto_041tp -p always samples/hello_world + + west flash + west debug + + .. group-tab:: Linux + + .. code-block:: shell + + # Run west config once to set permanent CMake argument + west config build.cmake-args -- -DOPENOCD=path/to/infineon/openocd/bin/openocd + + # Do a pristine build once after setting CMake argument + west build -b cy8cproto_041tp -p always samples/hello_world + + west flash + west debug + +Once the gdb console starts after executing the west debug command, you may now set breakpoints and perform other standard GDB debugging. + +References +********** + +.. target-notes:: + +.. _cy8cproto_041tp Board Website: + https://www.infineon.com/evaluation-board/CY8CPROTO-041TP + +.. _ModusToolbox: + https://www.infineon.com/design-resources/development-tools/sdk/modustoolbox-software + +.. _ModusToolbox Programming Tools: + https://www.infineon.com/design-resources/development-tools/sdk/modustoolbox-software/modustoolbox-programming-tools + +.. _Infineon OpenOCD: + https://github.com/Infineon/openocd/releases/latest + +.. _KitProg3: + https://github.com/Infineon/KitProg3 diff --git a/boards/infineon/cy8cproto_041tp/support/openocd.cfg b/boards/infineon/cy8cproto_041tp/support/openocd.cfg new file mode 100644 index 000000000000..751be3351477 --- /dev/null +++ b/boards/infineon/cy8cproto_041tp/support/openocd.cfg @@ -0,0 +1,19 @@ +# Copyright (c) 2025 Infineon Technologies AG, +# or an affiliate of Infineon Technologies AG. +# +# SPDX-License-Identifier: Apache-2.0 + +# Use KitProg3 interface +source [find interface/kitprog3.cfg] + +set ENABLE_ACQUIRE 0 +set PSOC4_USE_ACQUIRE 0 +transport select swd + +# Target configuration for PSoC4 +source [find target/infineon/psoc4.cfg] + +# Optional: specify a particular KitProg3 debugger if multiple are connected +if { [info exists _ZEPHYR_BOARD_SERIAL] } { + adapter serial $_ZEPHYR_BOARD_SERIAL +} From c40d66d046c5644f88df4211c959d0c33322487b Mon Sep 17 00:00:00 2001 From: Deepika aerlync Date: Mon, 24 Nov 2025 17:55:26 +0530 Subject: [PATCH 0160/3659] drivers: clock_control: add Infineon PSOC4 support Add clock control driver support for Infineon PSoC4: - Fixed clock driver (clock_control_ifx_fixed_clock.c) - Fixed factor clock driver (clock_control_ifx_fixed_factor_clock.c) - Peripheral clock driver (clock_control_ifx_peri_clock.c) - CAT1 clock control header Provides clock initialization and management based on devicetree configuration. Signed-off-by: Dharun krithik k Signed-off-by: Sayooj K Karun Signed-off-by: Manojkumar Konisetty Signed-off-by: Deepika aerlync --- drivers/clock_control/Kconfig.infineon | 9 ++++++--- .../clock_control_infineon_fixed_clock.c | 18 ++++++++++++++++-- ...clock_control_infineon_fixed_factor_clock.c | 17 +++++++++++++++-- .../clock_control_infineon_peri_clock.c | 7 ++++--- .../clock_control/clock_control_ifx_cat1.h | 9 +++++++++ 5 files changed, 50 insertions(+), 10 deletions(-) diff --git a/drivers/clock_control/Kconfig.infineon b/drivers/clock_control/Kconfig.infineon index aa02ce3a9fe1..4bcd3b3bec1a 100644 --- a/drivers/clock_control/Kconfig.infineon +++ b/drivers/clock_control/Kconfig.infineon @@ -38,10 +38,13 @@ if CLOCK_CONTROL_IFX_FIXED_FACTOR_CLOCK config CLOCK_CONTROL_IFX_FIXED_FACTOR_CLOCK_INIT_PRIORITY int "Infineon fixed factor clock driver init priority" - default 29 + default 31 help Infineon fixed factor clock control driver initialization priority. - This should be lower than the priority of fixed factor clock driver - to ensure the clock paths are initialized before. + This should be higher than CLOCK_CONTROL_INIT_PRIORITY to ensure + fixed-rate clocks are initialized before fixed-factor clocks that + depend on them.Since fixed-factor clocks depend on fixed-rate clocks, + they need a HIGHER priority number so they initialize after their + dependencies. endif # CLOCK_CONTROL_IFX_FIXED_FACTOR_CLOCK diff --git a/drivers/clock_control/clock_control_infineon_fixed_clock.c b/drivers/clock_control/clock_control_infineon_fixed_clock.c index 1c9e5ac086c2..90299aef146f 100644 --- a/drivers/clock_control/clock_control_infineon_fixed_clock.c +++ b/drivers/clock_control/clock_control_infineon_fixed_clock.c @@ -128,20 +128,33 @@ static int fixed_rate_clk_init(const struct device *dev) const struct fixed_rate_clock_config *const config = dev->config; switch (config->system_clock) { - +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(clk_imo)) case IFX_IMO: - break; + Cy_SysClk_ImoEnable(); +#if defined(CONFIG_SOC_FAMILY_INFINEON_PSOC4) + int err = Cy_SysClk_ImoSetFrequency(config->rate); + if (err != CY_SYSCLK_SUCCESS) { + printk("Failed to set IMO frequency with (error: %d)\n", err); + return -EIO; + } +#endif + break; +#endif case IFX_FLL: break; +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(clk_iho)) case IFX_IHO: Cy_SysClk_IhoEnable(); break; +#endif +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(clk_pilo)) case IFX_PILO: Cy_SysClk_PiloEnable(); break; +#endif #if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(dpll_lp0)) case IFX_DPLL250_0: @@ -173,6 +186,7 @@ static int fixed_rate_clk_init(const struct device *dev) SystemCoreClockUpdate(); break; #endif + default: break; } diff --git a/drivers/clock_control/clock_control_infineon_fixed_factor_clock.c b/drivers/clock_control/clock_control_infineon_fixed_factor_clock.c index 000702bd32aa..d26a324eeeba 100644 --- a/drivers/clock_control/clock_control_infineon_fixed_factor_clock.c +++ b/drivers/clock_control/clock_control_infineon_fixed_factor_clock.c @@ -32,6 +32,7 @@ struct fixed_factor_clock_config { uint32_t source_path; }; +#if defined(CONFIG_SOC_SERIES_PSE84) || defined(CONFIG_SOC_SERIES_PSC3) static int check_legal_max_min(const struct device *dev) { const struct fixed_factor_clock_config *const config = dev->config; @@ -54,30 +55,42 @@ static int check_legal_max_min(const struct device *dev) return 0; } +#endif static int fixed_factor_clk_init(const struct device *dev) { const struct fixed_factor_clock_config *const config = dev->config; +#if defined(CONFIG_SOC_SERIES_PSE84) || defined(CONFIG_SOC_SERIES_PSC3) uint32_t rslt; +#endif + uint32_t source_instance = 0; switch (config->block) { case IFX_PATHMUX: +#if !defined(CONFIG_SOC_FAMILY_INFINEON_PSOC4) Cy_SysClk_ClkPathSetSource(config->instance, config->source_path); +#endif break; case IFX_HF: - Cy_SysClk_ClkHfSetSource(config->instance, config->source_path); +#if defined(CONFIG_SOC_FAMILY_INFINEON_PSOC4) + Cy_SysClk_ClkHfSetSource(source_instance); + Cy_SysClk_ClkHfSetDivider(config->divider); +#else + Cy_SysClk_ClkHfSetSource(config->instance, source_instance); Cy_SysClk_ClkHfSetDivider(config->instance, config->divider); Cy_SysClk_ClkHfEnable(config->instance); +#endif break; default: return -EINVAL; } +#if defined(CONFIG_SOC_SERIES_PSE84) || defined(CONFIG_SOC_SERIES_PSC3) rslt = check_legal_max_min(dev); - +#endif return 0; } diff --git a/drivers/clock_control/clock_control_infineon_peri_clock.c b/drivers/clock_control/clock_control_infineon_peri_clock.c index bbd1b437483e..08b5ef11c2b5 100644 --- a/drivers/clock_control/clock_control_infineon_peri_clock.c +++ b/drivers/clock_control/clock_control_infineon_peri_clock.c @@ -22,7 +22,7 @@ #include #include -struct ifx_cat1_peri_clock_data { +struct ifx_peri_clock_data { struct ifx_cat1_resource_inst hw_resource; struct ifx_cat1_clock clock; uint16_t divider; @@ -67,12 +67,13 @@ en_clk_dst_t ifx_cat1_scb_get_clock_index(uint32_t block_num) #else clk = (en_clk_dst_t)((uint32_t)_IFX_CAT1_SCB0_PCLK_CLOCK + block_num); #endif + return clk; } static int ifx_cat1_peri_clock_init(const struct device *dev) { - struct ifx_cat1_peri_clock_data *const data = dev->data; + struct ifx_peri_clock_data *const data = dev->data; if (data->hw_resource.type == IFX_RSC_SCB) { en_clk_dst_t clk_idx = ifx_cat1_scb_get_clock_index(data->hw_resource.block_num); @@ -105,7 +106,7 @@ static int ifx_cat1_peri_clock_init(const struct device *dev) #endif #define INFINEON_CAT1_PERI_CLOCK_INIT(n) \ - static struct ifx_cat1_peri_clock_data ifx_cat1_peri_clock##n##_data = { \ + static struct ifx_peri_clock_data ifx_cat1_peri_clock##n##_data = { \ PERI_CLOCK_INIT(n).divider = DT_INST_PROP(n, clock_div), \ .hw_resource = {.type = DT_INST_PROP(n, resource_type), \ .block_num = DT_INST_PROP(n, resource_instance)}, \ diff --git a/include/zephyr/drivers/clock_control/clock_control_ifx_cat1.h b/include/zephyr/drivers/clock_control/clock_control_ifx_cat1.h index 9d305f5b884c..c02050216508 100644 --- a/include/zephyr/drivers/clock_control/clock_control_ifx_cat1.h +++ b/include/zephyr/drivers/clock_control/clock_control_ifx_cat1.h @@ -369,6 +369,15 @@ enum ifx_cat1_clock_block { IFX_CAT1_CLOCK_BLOCK_BAK, /*!< Backup Power Domain Clock */ IFX_CAT1_CLOCK_BLOCK_PERI, /*!< Peripheral Clock Group */ +#elif defined(CONFIG_SOC_FAMILY_INFINEON_PSOC4) + IFX_CAT1_CLOCK_BLOCK_PERIPHERAL_16BIT = + CY_SYSCLK_DIV_16_BIT, /* Equal to IFX_CAT1_CLOCK_BLOCK_PERIPHERAL0_16_BIT */ + + IFX_CAT1_CLOCK_BLOCK_PERIPHERAL_16_5BIT = + CY_SYSCLK_DIV_16_5_BIT, /* Equal to IFX_CAT1_CLOCK_BLOCK_PERIPHERAL0_16_5_BIT */ + + IFX_CAT1_CLOCK_BLOCK_PERIPHERAL_24_5BIT = + CY_SYSCLK_DIV_24_5_BIT, /* Equal to IFX_CAT1_CLOCK_BLOCK_PERIPHERAL0_24_5_BIT */ #endif }; From 067426ac542ed394fb0878b4f3a7fbf59e3994a7 Mon Sep 17 00:00:00 2001 From: Deepika aerlync Date: Mon, 24 Nov 2025 17:55:29 +0530 Subject: [PATCH 0161/3659] drivers: serial: add Infineon PSOC4 UART support Add initial implementation of the Infineon PSOC4 UART driver based on the Peripheral Driver Library (PDL) for PSOC4 (PSoC 4100TP) devices. Features: - UART transmit and receive using PDL SCB UART APIs - Configurable baud rate, parity, stop bits, and data bits from devicetree - Pinctrl integration for TX/RX pins - Support for Zephyr console and shell subsystems - Build-time validation for UART configuration parameters Signed-off-by: Dharun krithik k Signed-off-by: Sayooj K Karun Signed-off-by: Manojkumar Konisetty Signed-off-by: Deepika aerlync --- drivers/serial/uart_infineon_pdl.c | 185 ++++++++++++++++------------- 1 file changed, 102 insertions(+), 83 deletions(-) diff --git a/drivers/serial/uart_infineon_pdl.c b/drivers/serial/uart_infineon_pdl.c index ae246810e62b..bcd51e53efee 100644 --- a/drivers/serial/uart_infineon_pdl.c +++ b/drivers/serial/uart_infineon_pdl.c @@ -17,22 +17,45 @@ #include #include #include +#include +#include #include +#include #include #include #include #include +#include #include #include #include -LOG_MODULE_REGISTER(uart_ifx_cat1, CONFIG_UART_LOG_LEVEL); +LOG_MODULE_REGISTER(uart_ifx, CONFIG_UART_LOG_LEVEL); -#define IFX_CAT1_UART_OVERSAMPLE_MIN 8UL -#define IFX_CAT1_UART_OVERSAMPLE_MAX 16UL -#define IFX_CAT1_UART_MAX_BAUD_PERCENT_DIFFERENCE 10 +#define IFX_UART_OVERSAMPLE_MIN 8UL +#define IFX_UART_OVERSAMPLE_MAX 16UL +#define IFX_UART_MAX_BAUD_PERCENT_DIFFERENCE 10U + +#if defined(CY_IP_MXSCB_INSTANCES) +#define _IFX_CAT1_SCB_ARRAY_SIZE (CY_IP_MXSCB_INSTANCES) +#elif defined(CY_IP_M0S8SCB_INSTANCES) +#define _IFX_CAT1_SCB_ARRAY_SIZE (CY_IP_M0S8SCB_INSTANCES) +#elif defined(CY_IP_MXS22SCB_INSTANCES) +#define _IFX_CAT1_SCB_ARRAY_SIZE (CY_IP_MXS22SCB_INSTANCES) +#endif /* CY_IP_MXSCB_INSTANCES */ + +#if defined(CONFIG_SOC_SERIES_PSOC4100TP) +#define IFX_UART_RX_FIFO_TRIGGER_LEVEL 7 +#define IFX_UART_TX_FIFO_TRIGGER_LEVEL 0 +#else +#define IFX_UART_RX_FIFO_TRIGGER_LEVEL 63UL +#define IFX_UART_TX_FIFO_TRIGGER_LEVEL 63UL +#endif /* CONFIG_SOC_SERIES_PSOC4100TP */ + +#define IFX_UART_RX_INT_MASK_NONE 0UL +#define IFX_UART_TX_INT_MASK_NONE 0UL #ifdef CONFIG_UART_ASYNC_API #include @@ -112,80 +135,83 @@ struct ifx_cat1_uart_config { typedef void (*ifx_cat1_uart_event_callback_t)(void *callback_arg); -/* Helper API */ -static cy_en_scb_uart_parity_t convert_uart_parity_z_to_cy(const enum uart_config_parity parity) -{ - cy_en_scb_uart_parity_t cy_parity; +const uint8_t data_bits_lut[] = { + [UART_CFG_DATA_BITS_5] = 5, [UART_CFG_DATA_BITS_6] = 6, [UART_CFG_DATA_BITS_7] = 7, + [UART_CFG_DATA_BITS_8] = 8, [UART_CFG_DATA_BITS_9] = 9, +}; + +const uint8_t stop_bits_lut[] = { + [UART_CFG_STOP_BITS_1] = CY_SCB_UART_STOP_BITS_1, + [UART_CFG_STOP_BITS_2] = CY_SCB_UART_STOP_BITS_2, +}; +const uint8_t parity_lut[] = { + [UART_CFG_PARITY_NONE] = CY_SCB_UART_PARITY_NONE, + [UART_CFG_PARITY_ODD] = CY_SCB_UART_PARITY_ODD, + [UART_CFG_PARITY_EVEN] = CY_SCB_UART_PARITY_EVEN, +}; + +static inline uint32_t convert_uart_parity_z_to_cy(uint32_t parity) +{ switch (parity) { case UART_CFG_PARITY_NONE: - cy_parity = CY_SCB_UART_PARITY_NONE; - break; + return CY_SCB_UART_PARITY_NONE; case UART_CFG_PARITY_ODD: - cy_parity = CY_SCB_UART_PARITY_ODD; - break; + return CY_SCB_UART_PARITY_ODD; case UART_CFG_PARITY_EVEN: - cy_parity = CY_SCB_UART_PARITY_EVEN; - break; + return CY_SCB_UART_PARITY_EVEN; default: - cy_parity = CY_SCB_UART_PARITY_NONE; + return CY_SCB_UART_PARITY_NONE; } - return cy_parity; } -static uint8_t convert_uart_stop_bits_z_to_cy(const enum uart_config_stop_bits stop_bits) +static inline uint32_t convert_uart_stop_bits_z_to_cy(uint32_t sb) { - uint32_t cy_stop_bits; - - switch (stop_bits) { - case UART_CFG_STOP_BITS_1: - cy_stop_bits = CY_SCB_UART_STOP_BITS_1; - break; - - case UART_CFG_STOP_BITS_2: - cy_stop_bits = CY_SCB_UART_STOP_BITS_2; - break; - default: - cy_stop_bits = CY_SCB_UART_STOP_BITS_1; + if (sb <= UART_CFG_STOP_BITS_2) { + return stop_bits_lut[sb]; } - return cy_stop_bits; + + LOG_WRN("Invalid stop bits (%u), defaulting to 1 stop bit", sb); + return CY_SCB_UART_STOP_BITS_1; } -static uint32_t convert_uart_data_bits_z_to_cy(const enum uart_config_data_bits data_bits) +static inline uint32_t convert_uart_data_bits_z_to_cy(uint32_t db) { - uint32_t cy_data_bits; - - switch (data_bits) { - case UART_CFG_DATA_BITS_5: - cy_data_bits = 5u; - break; - - case UART_CFG_DATA_BITS_6: - cy_data_bits = 6u; - break; + if (db <= UART_CFG_DATA_BITS_9) { + return data_bits_lut[db]; + } - case UART_CFG_DATA_BITS_7: - cy_data_bits = 7u; - break; + LOG_WRN("Invalid data bits (%u), defaulting to 1 bit", db); + return 1U; +} - case UART_CFG_DATA_BITS_8: - cy_data_bits = 8u; - break; +static inline uint32_t ifx_uart_baud_diff(uint32_t actual, uint32_t baud) +{ + return (actual > baud) ? (((actual - baud) * 100U) / baud) + : (((baud - actual) * 100U) / baud); +} - case UART_CFG_DATA_BITS_9: - cy_data_bits = 9u; - break; +static inline uint32_t ifx_uart_divider(uint32_t freq, uint32_t baud, uint32_t oversample) +{ + return (freq + ((baud * oversample) / 2U)) / (baud * oversample); +} - default: - cy_data_bits = 1u; - } - return cy_data_bits; +static inline uint32_t ifx_uart_mem_width(uint32_t data_width) +{ +#if defined(CONFIG_SOC_FAMILY_INFINEON_PSOC4) + return (data_width <= CY_SCB_BYTE_WIDTH) ? CY_SCB_CTRL_MEM_WIDTH_BYTE + : CY_SCB_CTRL_MEM_WIDTH_HALFWORD; +#else + return (data_width <= CY_SCB_BYTE_WIDTH) ? CY_SCB_MEM_WIDTH_BYTE + : CY_SCB_MEM_WIDTH_HALFWORD; +#endif } #if defined(CONFIG_SOC_FAMILY_INFINEON_EDGE) #define IFX_CAT1_INSTANCE_GROUP(instance, group) (((instance) << 4) | (group)) #endif +#if !defined(CONFIG_SOC_FAMILY_INFINEON_PSOC4) static uint8_t ifx_cat1_get_hfclk_for_peri_group(uint8_t peri_group) { #if defined(CONFIG_SOC_SERIES_PSE84) @@ -237,6 +263,7 @@ static uint8_t ifx_cat1_get_hfclk_for_peri_group(uint8_t peri_group) #endif return -EINVAL; } +#endif cy_rslt_t ifx_cat1_uart_set_baud(const struct device *dev, uint32_t baudrate) { @@ -244,7 +271,7 @@ cy_rslt_t ifx_cat1_uart_set_baud(const struct device *dev, uint32_t baudrate) struct ifx_cat1_uart_data *data = dev->data; const struct ifx_cat1_uart_config *const config = dev->config; - uint8_t best_oversample = IFX_CAT1_UART_OVERSAMPLE_MIN; + uint8_t best_oversample = IFX_UART_OVERSAMPLE_MIN; uint8_t best_difference = 0xFF; uint32_t divider; @@ -263,15 +290,14 @@ cy_rslt_t ifx_cat1_uart_set_baud(const struct device *dev, uint32_t baudrate) uint8_t hfclk = ifx_cat1_get_hfclk_for_peri_group(data->clock_peri_group); peri_frequency = Cy_SysClk_ClkHfGetFrequency(hfclk); +#else + peri_frequency = Cy_SysClk_ClkHfGetFrequency(); #endif - - for (uint8_t i = IFX_CAT1_UART_OVERSAMPLE_MIN; i < IFX_CAT1_UART_OVERSAMPLE_MAX + 1; i++) { + for (uint8_t i = IFX_UART_OVERSAMPLE_MIN; i < IFX_UART_OVERSAMPLE_MAX + 1; i++) { uint32_t tmp_divider = ((peri_frequency + ((baudrate * i) / 2))) / (baudrate * i); uint32_t actual_baud = (peri_frequency / (tmp_divider * i)); - uint8_t difference = (actual_baud > baudrate) - ? ((actual_baud * 100) - (baudrate * 100)) / baudrate - : ((baudrate * 100) - (actual_baud * 100)) / baudrate; + uint8_t difference = ifx_uart_baud_diff(actual_baud, baudrate); if (difference < best_difference) { best_difference = difference; @@ -279,16 +305,13 @@ cy_rslt_t ifx_cat1_uart_set_baud(const struct device *dev, uint32_t baudrate) } } - if (best_difference > IFX_CAT1_UART_MAX_BAUD_PERCENT_DIFFERENCE) { + if (best_difference > IFX_UART_MAX_BAUD_PERCENT_DIFFERENCE) { status = -EINVAL; } - best_oversample = best_oversample; - data->scb_config.oversample = best_oversample; - divider = ((peri_frequency + ((baudrate * best_oversample) / 2)) / - (baudrate * best_oversample)); + divider = ifx_uart_divider(peri_frequency, baudrate, best_oversample); en_clk_dst_t clk_idx = ifx_cat1_scb_get_clock_index(data->hw_resource.block_num); @@ -300,15 +323,15 @@ cy_rslt_t ifx_cat1_uart_set_baud(const struct device *dev, uint32_t baudrate) divider - 1, 0); } + if (status < 0) { + return status; + } + /* Configure the UART interface */ #if (CY_IP_MXSCB_VERSION >= 2) || (CY_IP_MXS22SCB_VERSION >= 1) - uint32_t mem_width = (data->scb_config.dataWidth <= CY_SCB_BYTE_WIDTH) - ? CY_SCB_MEM_WIDTH_BYTE - : CY_SCB_MEM_WIDTH_HALFWORD; - SCB_CTRL(config->reg_addr) = _BOOL2FLD(SCB_CTRL_ADDR_ACCEPT, data->scb_config.acceptAddrInFifo) | - _BOOL2FLD(SCB_CTRL_MEM_WIDTH, mem_width) | + _BOOL2FLD(SCB_CTRL_MEM_WIDTH, ifx_uart_mem_width(data->scb_config.dataWidth)) | _VAL2FLD(SCB_CTRL_OVS, best_oversample - 1) | _VAL2FLD(SCB_CTRL_MODE, CY_SCB_CTRL_MODE_UART); #else /* Older versions of the block */ @@ -541,7 +564,7 @@ static int ifx_cat1_uart_irq_tx_complete(const struct device *dev) const struct ifx_cat1_uart_config *const config = dev->config; return Cy_SCB_IsTxComplete(config->reg_addr) || - (0UL == (data->context.txStatus & CY_SCB_UART_TRANSMIT_ACTIVE)); + ((data->context.txStatus & CY_SCB_UART_TRANSMIT_ACTIVE) == 0); } static void ifx_cat1_uart_irq_rx_enable(const struct device *dev) @@ -675,7 +698,11 @@ static const cy_stc_scb_uart_config_t _uart_default_config = { .breakWidth = 11UL, .dropOnFrameError = false, .dropOnParityError = false, +#if !defined(CONFIG_SOC_SERIES_PSOC4100TP) .breaklevel = false, +#else + .breakLevel = false, +#endif .receiverAddress = 0x0UL, .receiverAddressMask = 0x0UL, .acceptAddrInFifo = false, @@ -683,10 +710,10 @@ static const cy_stc_scb_uart_config_t _uart_default_config = { .ctsPolarity = CY_SCB_UART_ACTIVE_LOW, .rtsRxFifoLevel = 0UL, .rtsPolarity = CY_SCB_UART_ACTIVE_LOW, - .rxFifoTriggerLevel = 63UL, - .rxFifoIntEnableMask = 0UL, - .txFifoTriggerLevel = 63UL, - .txFifoIntEnableMask = 0UL, + .rxFifoTriggerLevel = IFX_UART_RX_FIFO_TRIGGER_LEVEL, + .rxFifoIntEnableMask = IFX_UART_RX_INT_MASK_NONE, + .txFifoTriggerLevel = IFX_UART_TX_FIFO_TRIGGER_LEVEL, + .txFifoIntEnableMask = IFX_UART_TX_INT_MASK_NONE, }; #ifdef CONFIG_UART_ASYNC_API @@ -1155,14 +1182,6 @@ static int ifx_cat1_uart_async_rx_buf_rsp(const struct device *dev, uint8_t *buf #endif /*CONFIG_UART_ASYNC_API */ -#if defined(CY_IP_MXSCB_INSTANCES) -#define _IFX_CAT1_SCB_ARRAY_SIZE (CY_IP_MXSCB_INSTANCES) -#elif defined(CY_IP_M0S8SCB_INSTANCES) -#define _IFX_CAT1_SCB_ARRAY_SIZE (CY_IP_M0S8SCB_INSTANCES) -#elif defined(CY_IP_MXS22SCB_INSTANCES) -#define _IFX_CAT1_SCB_ARRAY_SIZE (CY_IP_MXS22SCB_INSTANCES) -#endif /* CY_IP_MXSCB_INSTANCES */ - CySCB_Type *const _IFX_CAT1_SCB_BASE_ADDRESSES[_IFX_CAT1_SCB_ARRAY_SIZE] = { #ifdef SCB0 SCB0, From 41542b56137e347a76ec021da0c4b48a6d2f9632 Mon Sep 17 00:00:00 2001 From: Zhaoxiang Jin Date: Mon, 1 Dec 2025 14:19:20 +0800 Subject: [PATCH 0162/3659] drivers: sim: Enable dma clock through sim driver Enable dma and dmamux clock through sim driver Signed-off-by: Zhaoxiang Jin --- drivers/clock_control/clock_control_mcux_sim.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/clock_control/clock_control_mcux_sim.c b/drivers/clock_control/clock_control_mcux_sim.c index 180f44fce783..095d3e8b23c1 100644 --- a/drivers/clock_control/clock_control_mcux_sim.c +++ b/drivers/clock_control/clock_control_mcux_sim.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017,2025 NXP + * Copyright 2017, 2025 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -37,6 +37,16 @@ static int mcux_sim_on(const struct device *dev, } #endif +#ifdef CONFIG_DMA_NXP_4CH_DMA + if ((uint32_t)sub_system == KINETIS_SIM_DMA_CLK) { + clock_ip_name = kCLOCK_Dma0; + } + + if ((uint32_t)sub_system == KINETIS_SIM_DMAMUX_CLK) { + clock_ip_name = kCLOCK_Dmamux0; + } +#endif + CLOCK_EnableClock(clock_ip_name); return 0; From a58a750336a27a9319ee84713df427495423a74f Mon Sep 17 00:00:00 2001 From: Zhaoxiang Jin Date: Mon, 1 Dec 2025 14:26:37 +0800 Subject: [PATCH 0163/3659] drivers: dma: nxp: Add support for NXP 4 channel DMA driver This commit introduces a new DMA driver for NXP platforms, specifically supporting the MCXC/kinetis series. Please access https://www.nxp.com/webapp/sps/download/preDownload.jsp?render=true to download MCXC44x Sub-Family Reference Manual for more details. DMAMUX can be found in Chapter 20 and DMA in Chapter 21. Signed-off-by: Zhaoxiang Jin --- drivers/dma/CMakeLists.txt | 1 + drivers/dma/Kconfig | 1 + drivers/dma/Kconfig.nxp_4ch_dma | 7 + drivers/dma/dma_nxp_4ch_dma.c | 454 ++++++++++++++++++++++++++++++ dts/bindings/dma/nxp,4ch-dma.yaml | 45 +++ 5 files changed, 508 insertions(+) create mode 100644 drivers/dma/Kconfig.nxp_4ch_dma create mode 100644 drivers/dma/dma_nxp_4ch_dma.c create mode 100644 dts/bindings/dma/nxp,4ch-dma.yaml diff --git a/drivers/dma/CMakeLists.txt b/drivers/dma/CMakeLists.txt index 0bfc8ff766ff..6da1031f7bfa 100644 --- a/drivers/dma/CMakeLists.txt +++ b/drivers/dma/CMakeLists.txt @@ -35,6 +35,7 @@ zephyr_library_sources_ifdef(CONFIG_DMA_MCUX_LPC dma_mcux_lpc.c) zephyr_library_sources_ifdef(CONFIG_DMA_MCUX_SMARTDMA dma_mcux_smartdma.c) zephyr_library_sources_ifdef(CONFIG_DMA_NIOS2_MSGDMA dma_nios2_msgdma.c) zephyr_library_sources_ifdef(CONFIG_DMA_NPCX_GDMA dma_npcx_gdma.c) +zephyr_library_sources_ifdef(CONFIG_DMA_NXP_4CH_DMA dma_nxp_4ch_dma.c) zephyr_library_sources_ifdef(CONFIG_DMA_NXP_EDMA dma_nxp_edma.c) zephyr_library_sources_ifdef(CONFIG_DMA_NXP_SDMA dma_nxp_sdma.c) zephyr_library_sources_ifdef(CONFIG_DMA_NXP_SOF_HOST_DMA dma_nxp_sof_host_dma.c) diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index b57f14c95e2b..a0ff171fb293 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -48,6 +48,7 @@ source "drivers/dma/Kconfig.mcux_pxp" source "drivers/dma/Kconfig.mcux_smartdma" source "drivers/dma/Kconfig.nios2_msgdma" source "drivers/dma/Kconfig.npcx" +source "drivers/dma/Kconfig.nxp_4ch_dma" source "drivers/dma/Kconfig.nxp_edma" source "drivers/dma/Kconfig.nxp_sdma" source "drivers/dma/Kconfig.nxp_sof_host_dma" diff --git a/drivers/dma/Kconfig.nxp_4ch_dma b/drivers/dma/Kconfig.nxp_4ch_dma new file mode 100644 index 000000000000..6a894365faaf --- /dev/null +++ b/drivers/dma/Kconfig.nxp_4ch_dma @@ -0,0 +1,7 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +config DMA_NXP_4CH_DMA + bool "NXP 4 channel DMA driver" + default y + depends on DT_HAS_NXP_4CH_DMA_ENABLED diff --git a/drivers/dma/dma_nxp_4ch_dma.c b/drivers/dma/dma_nxp_4ch_dma.c new file mode 100644 index 000000000000..f2a60b471fb5 --- /dev/null +++ b/drivers/dma/dma_nxp_4ch_dma.c @@ -0,0 +1,454 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(nxp_4ch_dma, CONFIG_DMA_LOG_LEVEL); + +#define DT_DRV_COMPAT nxp_4ch_dma + +struct nxp_dma_chan_data { + const struct device *dev; + dma_callback_t cb; + void *user_data; + uint32_t width; + uint8_t src_inc; + uint8_t dst_inc; + enum dma_channel_direction dir; + bool busy; + uint16_t dmamux_source; +}; + +struct nxp_dma_data { + struct dma_context ctx; + struct nxp_dma_chan_data *chan; +}; + +struct nxp_dma_config { + DMA_Type *dma_base; + DMAMUX_Type *dmamux_base; + uint8_t num_channels; + void (*irq_config_func)(const struct device *dev); + const struct device *dma_clk_dev; + clock_control_subsys_t dma_clk_subsys; + const struct device *dmamux_clk_dev; + clock_control_subsys_t dmamux_clk_subsys; +}; + +static inline uint32_t nxp_dma_bytes_to_size_field(uint32_t bytes) +{ + switch (bytes) { + case 1: + return 1U; /* 8 bits */ + case 2: + return 2U; /* 16 bits */ + case 4: + return 0U; /* 32 bits */ + default: + return 0U; /* default to 32 bits */ + } +} + +static inline void nxp_dma_reset_channel(DMA_Type *dma, uint32_t ch) +{ + /* Clear DSR_BCR[DONE] and reset registers to defaults */ + dma->DMA[ch].DSR_BCR |= DMA_DSR_BCR_DONE_MASK; + dma->DMA[ch].SAR = 0U; + dma->DMA[ch].DAR = 0U; + dma->DMA[ch].DSR_BCR = 0U; + /* Enable auto stop request and cycle steal by default */ + dma->DMA[ch].DCR = DMA_DCR_D_REQ_MASK | DMA_DCR_CS_MASK; +} + +static int nxp_dma_configure(const struct device *dev, uint32_t channel, + struct dma_config *config) +{ + const struct nxp_dma_config *cfg = dev->config; + struct nxp_dma_data *data = dev->data; + struct nxp_dma_chan_data *chan_data = &data->chan[channel]; + DMAMUX_Type *mux = cfg->dmamux_base; + DMA_Type *dma = cfg->dma_base; + uint8_t src_inc, dst_inc; + + if (channel >= cfg->num_channels || config == NULL || + config->head_block == NULL) { + return -EINVAL; + } + + if (!((config->source_data_size == 1U) || (config->source_data_size == 2U) || + (config->source_data_size == 4U))) { + return -EINVAL; + } + + if (config->dest_data_size != config->source_data_size) { + return -EINVAL; + } + + /* Reset channel. */ + nxp_dma_reset_channel(dma, channel); + + /* Source and destination address increment. */ + src_inc = (config->head_block->source_addr_adj == DMA_ADDR_ADJ_NO_CHANGE) ? 0U : 1U; + dst_inc = (config->head_block->dest_addr_adj == DMA_ADDR_ADJ_NO_CHANGE) ? 0U : 1U; + + /* Save channel settings */ + chan_data->dev = dev; + chan_data->busy = false; + chan_data->src_inc = src_inc; + chan_data->dst_inc = dst_inc; + chan_data->cb = config->dma_callback; + chan_data->user_data = config->user_data; + chan_data->width = config->dest_data_size; + chan_data->dir = config->channel_direction; + chan_data->dmamux_source = (uint16_t)config->dma_slot; + + /* Configure DCR register: + * destination size, source size, destination increment, source increment. + */ + dma->DMA[channel].DCR &= ~(DMA_DCR_DSIZE_MASK | DMA_DCR_SSIZE_MASK | + DMA_DCR_DINC_MASK | DMA_DCR_SINC_MASK | + DMA_DCR_EINT_MASK | DMA_DCR_ERQ_MASK); + + dma->DMA[channel].DCR |= (DMA_DCR_DSIZE(nxp_dma_bytes_to_size_field(chan_data->width)) | + DMA_DCR_SSIZE(nxp_dma_bytes_to_size_field(chan_data->width)) | + DMA_DCR_DINC((uint32_t)chan_data->dst_inc) | + DMA_DCR_SINC((uint32_t)chan_data->src_inc)); + + /* Trigger an interrupt after transmission is complete. */ + if (config->complete_callback_en || chan_data->cb) { + dma->DMA[channel].DCR |= DMA_DCR_EINT_MASK; + } + + /* Configure DMAMUX if available. */ + if (mux != NULL) { + if (config->dma_slot != 0U) { + mux->CHCFG[channel] = + (mux->CHCFG[channel] & (uint8_t)~DMAMUX_CHCFG_SOURCE_MASK) | + DMAMUX_CHCFG_SOURCE(config->dma_slot); + mux->CHCFG[channel] |= DMAMUX_CHCFG_ENBL_MASK; + } else { + mux->CHCFG[channel] &= (uint8_t)~DMAMUX_CHCFG_ENBL_MASK; + } + } + + const struct dma_block_config *blk = config->head_block; + + /* Enforce alignment to width */ + if (((blk->source_address % chan_data->width) != 0U) || + ((blk->dest_address % chan_data->width) != 0U)) { + return -EINVAL; + } + + dma->DMA[channel].SAR = blk->source_address; + dma->DMA[channel].DAR = blk->dest_address; + dma->DMA[channel].DSR_BCR = DMA_DSR_BCR_BCR(blk->block_size); + + return 0; +} + +/** + * @note: start() does not reprogram the SAR/DAR/BCR registers, but instead + * directly uses the values stored in the current hardware registers. + * These values originate from the most recent configure()/reload() call, + * or from the register state after the last transmission (including any + * remaining BCR settings preserved by stop() to support repeated starts, + * and any advanced SAR/DAR registers). + */ +static int nxp_dma_start(const struct device *dev, uint32_t channel) +{ + const struct nxp_dma_config *cfg = dev->config; + struct nxp_dma_data *data = dev->data; + struct nxp_dma_chan_data *chan_data = &data->chan[channel]; + DMAMUX_Type *mux = cfg->dmamux_base; + DMA_Type *dma = cfg->dma_base; + + if (channel >= cfg->num_channels) { + return -EINVAL; + } + + if (chan_data->busy) { + return -EBUSY; + } + + if ((dma->DMA[channel].DSR_BCR & DMA_DSR_BCR_BCR_MASK) == 0U) { + return -EINVAL; + } + + chan_data->busy = true; + + /* If DMAMUX is enabled, then enable hardware trigger. + * Otherwise, enable software trigger. + */ + if ((mux != NULL) && (chan_data->dmamux_source != 0U)) { + dma->DMA[channel].DCR |= (DMA_DCR_ERQ_MASK | DMA_DCR_CS_MASK); + dma->DMA[channel].DCR &= ~DMA_DCR_START_MASK; + } else { + dma->DMA[channel].DCR &= ~(DMA_DCR_ERQ_MASK | DMA_DCR_CS_MASK); + dma->DMA[channel].DCR |= DMA_DCR_START_MASK; + } + + return 0; +} + +static int nxp_dma_stop(const struct device *dev, uint32_t channel) +{ + const struct nxp_dma_config *cfg = dev->config; + struct nxp_dma_data *data = dev->data; + struct nxp_dma_chan_data *chan_data = &data->chan[channel]; + DMA_Type *dma = cfg->dma_base; + + if (channel >= cfg->num_channels) { + return -EINVAL; + } + + /* Disable ERQ to stop further HW requests */ + dma->DMA[channel].DCR &= ~DMA_DCR_ERQ_MASK; + + /* Disable DMAMUX channel. */ + if (cfg->dmamux_base) { + cfg->dmamux_base->CHCFG[channel] &= (uint8_t)~DMAMUX_CHCFG_ENBL_MASK; + } + + /* Capture remaining BCR and then restore the remaining BCR to enable + * subsequent continuation via start() without calling configure()/reload(). + * Note that SAR/DAR have advanced to the current position during transmission + * and are intentionally not restored to enable 'resumable download'. + */ + uint32_t remain = (dma->DMA[channel].DSR_BCR & DMA_DSR_BCR_BCR_MASK) >> + DMA_DSR_BCR_BCR_SHIFT; + + /* Clear status/error bits; note this also clears BCR to 0 per RM */ + dma->DMA[channel].DSR_BCR |= DMA_DSR_BCR_DONE_MASK; + + if (remain != 0U) { + dma->DMA[channel].DSR_BCR = DMA_DSR_BCR_BCR(remain); + } + + chan_data->busy = false; + + return 0; +} + +static int nxp_dma_reload(const struct device *dev, uint32_t channel, + uint32_t src, uint32_t dst, size_t size) +{ + const struct nxp_dma_config *cfg = dev->config; + struct nxp_dma_data *data = dev->data; + DMA_Type *dma = cfg->dma_base; + struct nxp_dma_chan_data *chan_data = &data->chan[channel]; + + if (channel >= cfg->num_channels) { + return -EINVAL; + } + + /* Alignment requirements: address aligned to transfer width */ + if ((src % chan_data->width) != 0U || (dst % chan_data->width) != 0U) { + return -EINVAL; + } + + if (chan_data->busy) { + return -EBUSY; + } + + /* Configure SAR/DAR and BCR */ + dma->DMA[channel].SAR = src; + dma->DMA[channel].DAR = dst; + dma->DMA[channel].DSR_BCR = DMA_DSR_BCR_BCR(size); + + return 0; +} + +static int nxp_dma_get_status(const struct device *dev, uint32_t channel, + struct dma_status *status) +{ + const struct nxp_dma_config *cfg = dev->config; + struct nxp_dma_data *data = dev->data; + DMA_Type *dma = cfg->dma_base; + struct nxp_dma_chan_data *chan_data = &data->chan[channel]; + + if ((channel >= cfg->num_channels) || (status == NULL)) { + return -EINVAL; + } + + status->busy = ((dma->DMA[channel].DSR_BCR & DMA_DSR_BCR_BSY_MASK) != 0U) && + chan_data->busy; + status->pending_length = (dma->DMA[channel].DSR_BCR & DMA_DSR_BCR_BCR_MASK) >> + DMA_DSR_BCR_BCR_SHIFT; + status->dir = chan_data->dir; + + return 0; +} + +static void nxp_dma_isr(const struct device *dev, uint32_t channel) +{ + const struct nxp_dma_config *cfg = dev->config; + struct nxp_dma_data *data = dev->data; + struct nxp_dma_chan_data *chan_data = &data->chan[channel]; + DMA_Type *dma = cfg->dma_base; + int ret = DMA_STATUS_COMPLETE; + + if (dma->DMA[channel].DSR_BCR & (DMA_DSR_BCR_BED_MASK | + DMA_DSR_BCR_BES_MASK | DMA_DSR_BCR_CE_MASK)) { + ret = -EIO; + } + + /* Clear DONE flags */ + dma->DMA[channel].DSR_BCR |= DMA_DSR_BCR_DONE_MASK; + + chan_data->busy = false; + + if (chan_data->cb) { + chan_data->cb(dev, chan_data->user_data, channel, ret); + } + + barrier_dsync_fence_full(); +} + +static int nxp_dma_init(const struct device *dev) +{ + const struct nxp_dma_config *cfg = dev->config; + struct nxp_dma_data *data = dev->data; + int ret; + + if (cfg->dma_clk_dev != NULL) { + if (!device_is_ready(cfg->dma_clk_dev)) { + LOG_ERR("DMA clock device not ready"); + return -ENODEV; + } + ret = clock_control_on(cfg->dma_clk_dev, cfg->dma_clk_subsys); + if (ret < 0) { + LOG_ERR("Failed to enable DMA clock (%d)", ret); + return ret; + } + } + + if (cfg->dmamux_clk_dev != NULL) { + if (!device_is_ready(cfg->dmamux_clk_dev)) { + LOG_ERR("DMAMUX clock device not ready"); + return -ENODEV; + } + ret = clock_control_on(cfg->dmamux_clk_dev, cfg->dmamux_clk_subsys); + if (ret < 0) { + LOG_ERR("Failed to enable DMAMUX clock (%d)", ret); + return ret; + } + } + + /* Reset all channels */ + for (uint32_t ch = 0; ch < cfg->num_channels; ch++) { + nxp_dma_reset_channel(cfg->dma_base, ch); + + /* Disable DMAMUX channel if present */ + if (cfg->dmamux_base) { + cfg->dmamux_base->CHCFG[ch] &= (uint8_t)~DMAMUX_CHCFG_ENBL_MASK; + } + + data->chan[ch].busy = false; + data->chan[ch].cb = NULL; + data->chan[ch].user_data = NULL; + } + + cfg->irq_config_func(dev); + + return 0; +} + +static DEVICE_API(dma, nxp_dma_api) = { + .config = nxp_dma_configure, + .start = nxp_dma_start, + .stop = nxp_dma_stop, + .reload = nxp_dma_reload, + .get_status = nxp_dma_get_status, +}; + +/* IRQ dispatcher per-channel */ +#define NXP_DMA_DECLARE_IRQ(inst, ch) \ + static void _CONCAT(_CONCAT(nxp_dma_irq, inst), ch)(const struct device *dev) \ + { \ + nxp_dma_isr(dev, ch); \ + } + +/* Per-instance macros, connect each channel IRQ by index. */ +#define NXP_DMA_IRQ_CFG_FUNC(inst) \ + static void _CONCAT(nxp_dma_irq_config_func, inst)(const struct device *dev) \ + { \ + IF_ENABLED(DT_INST_IRQ_HAS_IDX(inst, 0), ( \ + IRQ_CONNECT(DT_INST_IRQ_BY_IDX(inst, 0, irq), \ + DT_INST_IRQ_BY_IDX(inst, 0, priority), \ + _CONCAT(_CONCAT(nxp_dma_irq, inst), 0), \ + DEVICE_DT_INST_GET(inst), 0); \ + irq_enable(DT_INST_IRQ_BY_IDX(inst, 0, irq)); \ + )) \ + IF_ENABLED(DT_INST_IRQ_HAS_IDX(inst, 1), ( \ + IRQ_CONNECT(DT_INST_IRQ_BY_IDX(inst, 1, irq), \ + DT_INST_IRQ_BY_IDX(inst, 1, priority), \ + _CONCAT(_CONCAT(nxp_dma_irq, inst), 1), \ + DEVICE_DT_INST_GET(inst), 0); \ + irq_enable(DT_INST_IRQ_BY_IDX(inst, 1, irq)); \ + )) \ + IF_ENABLED(DT_INST_IRQ_HAS_IDX(inst, 2), ( \ + IRQ_CONNECT(DT_INST_IRQ_BY_IDX(inst, 2, irq), \ + DT_INST_IRQ_BY_IDX(inst, 2, priority), \ + _CONCAT(_CONCAT(nxp_dma_irq, inst), 2), \ + DEVICE_DT_INST_GET(inst), 0); \ + irq_enable(DT_INST_IRQ_BY_IDX(inst, 2, irq)); \ + )) \ + IF_ENABLED(DT_INST_IRQ_HAS_IDX(inst, 3), ( \ + IRQ_CONNECT(DT_INST_IRQ_BY_IDX(inst, 3, irq), \ + DT_INST_IRQ_BY_IDX(inst, 3, priority), \ + _CONCAT(_CONCAT(nxp_dma_irq, inst), 3), \ + DEVICE_DT_INST_GET(inst), 0); \ + irq_enable(DT_INST_IRQ_BY_IDX(inst, 3, irq)); \ + )); \ + } + +#define NXP_DMA_INIT(inst) \ + NXP_DMA_DECLARE_IRQ(inst, 0) \ + NXP_DMA_DECLARE_IRQ(inst, 1) \ + NXP_DMA_DECLARE_IRQ(inst, 2) \ + NXP_DMA_DECLARE_IRQ(inst, 3) \ + NXP_DMA_IRQ_CFG_FUNC(inst) \ + \ + ATOMIC_DEFINE(_CONCAT(nxp_dma_atomic, inst), DT_INST_PROP(inst, dma_channels)); \ + \ + static struct nxp_dma_chan_data \ + _CONCAT(nxp_dma_chan_data, inst)[DT_INST_PROP(inst, dma_channels)]; \ + \ + static struct nxp_dma_data _CONCAT(nxp_dma_runtime, inst) = { \ + .ctx = { \ + .magic = DMA_MAGIC, \ + .dma_channels = DT_INST_PROP(inst, dma_channels), \ + .atomic = _CONCAT(nxp_dma_atomic, inst), \ + }, \ + .chan = _CONCAT(nxp_dma_chan_data, inst), \ + }; \ + \ + static const struct nxp_dma_config _CONCAT(nxp_dma_config, inst) = { \ + .dma_base = (DMA_Type *)DT_INST_REG_ADDR_BY_IDX(inst, 0), \ + .dmamux_base = (DMAMUX_Type *)DT_INST_REG_ADDR_BY_IDX(inst, 1), \ + .num_channels = DT_INST_PROP(inst, dma_channels), \ + .irq_config_func = _CONCAT(nxp_dma_irq_config_func, inst), \ + .dma_clk_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR_BY_IDX(inst, 0)), \ + .dma_clk_subsys = \ + (clock_control_subsys_t)DT_INST_CLOCKS_CELL_BY_IDX(inst, 0, name), \ + .dmamux_clk_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR_BY_IDX(inst, 1)), \ + .dmamux_clk_subsys = \ + (clock_control_subsys_t)DT_INST_CLOCKS_CELL_BY_IDX(inst, 1, name), \ + }; \ + \ + DEVICE_DT_INST_DEFINE(inst, nxp_dma_init, NULL, &_CONCAT(nxp_dma_runtime, inst), \ + &_CONCAT(nxp_dma_config, inst), PRE_KERNEL_1, \ + CONFIG_DMA_INIT_PRIORITY, &nxp_dma_api); + +DT_INST_FOREACH_STATUS_OKAY(NXP_DMA_INIT) diff --git a/dts/bindings/dma/nxp,4ch-dma.yaml b/dts/bindings/dma/nxp,4ch-dma.yaml new file mode 100644 index 000000000000..fa64417bb7ab --- /dev/null +++ b/dts/bindings/dma/nxp,4ch-dma.yaml @@ -0,0 +1,45 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +description: NXP 4 channel DMA controller (DMA + DMAMUX) + +compatible: "nxp,4ch-dma" + +include: dma-controller.yaml + +properties: + reg: + required: true + description: | + Specifies base address and size of DMA and respective DMAMUX base address + that routes DMA sources. Provide two regions: index 0 is DMA, index 1 is DMAMUX. + + interrupts: + required: true + description: | + Interrupts for each DMA channel. + + dma-channels: + required: true + description: | + Specifies the number of DMA channels supported by the controller. This value is + used to validate the channel number provided in the DMA specifier. + + dma-requests: + required: true + description: | + Indicates the maximum value of the DMA request sources (slots) index supported by + DMAMUX. This value is used to validate the request source index provided in the + DMA specifier. + + "#dma-cells": + type: int + required: true + const: 2 + description: | + Number of items to expect in a specifier, including the channel number and + the DMA request source. + +dma-cells: + - channel + - source From ee2cab94d9f7df677a669798ed2c506c882c5e5a Mon Sep 17 00:00:00 2001 From: Zhaoxiang Jin Date: Mon, 1 Dec 2025 14:31:37 +0800 Subject: [PATCH 0164/3659] boards: Enable DMA on frdm_mcxc444 Enable DMA on frdm_mcxc444 Signed-off-by: Zhaoxiang Jin --- boards/nxp/frdm_mcxc444/frdm_mcxc444.dts | 4 ++++ boards/nxp/frdm_mcxc444/frdm_mcxc444.yaml | 1 + dts/arm/nxp/nxp_mcxc_common.dtsi | 13 +++++++++++++ 3 files changed, 18 insertions(+) diff --git a/boards/nxp/frdm_mcxc444/frdm_mcxc444.dts b/boards/nxp/frdm_mcxc444/frdm_mcxc444.dts index ef8f66c349d8..b6318a5ca6d7 100644 --- a/boards/nxp/frdm_mcxc444/frdm_mcxc444.dts +++ b/boards/nxp/frdm_mcxc444/frdm_mcxc444.dts @@ -195,3 +195,7 @@ zephyr_udc0: &usb { status = "okay"; num-bidir-endpoints = <8>; }; + +&dma { + status = "okay"; +}; diff --git a/boards/nxp/frdm_mcxc444/frdm_mcxc444.yaml b/boards/nxp/frdm_mcxc444/frdm_mcxc444.yaml index 26fa057959cf..81cc7a849578 100644 --- a/boards/nxp/frdm_mcxc444/frdm_mcxc444.yaml +++ b/boards/nxp/frdm_mcxc444/frdm_mcxc444.yaml @@ -24,6 +24,7 @@ supported: - usb_device - usbd - watchdog + - dma testing: ignore_tags: - net diff --git a/dts/arm/nxp/nxp_mcxc_common.dtsi b/dts/arm/nxp/nxp_mcxc_common.dtsi index 26f752ee251a..7469dde82120 100644 --- a/dts/arm/nxp/nxp_mcxc_common.dtsi +++ b/dts/arm/nxp/nxp_mcxc_common.dtsi @@ -362,6 +362,19 @@ NXP_VREF_MODE_LOW_POWER NXP_VREF_MODE_HIGH_POWER>; }; + + dma: dma-controller@40008000 { + compatible = "nxp,4ch-dma"; + #dma-cells = <2>; + dma-channels = <4>; + dma-requests = <64>; + reg = <0x40008000 0x1000>, + <0x40021000 0x1000>; + clocks = <&sim KINETIS_SIM_DMA_CLK 0 0>, + <&sim KINETIS_SIM_DMAMUX_CLK 0 0>; + interrupts = <0 0>, <1 0>, <2 0>, <3 0>; + status = "disabled"; + }; }; }; From 4a92103f92df3f23217d89f5d5cee0c825f3bb34 Mon Sep 17 00:00:00 2001 From: Zhaoxiang Jin Date: Mon, 1 Dec 2025 14:32:07 +0800 Subject: [PATCH 0165/3659] tests: dma: Enable loop_transfer for nxp,4ch-dma Enable loop_transfer for nxp,4ch-dma Signed-off-by: Zhaoxiang Jin --- tests/drivers/dma/loop_transfer/boards/frdm_mcxc444.conf | 4 ++++ .../drivers/dma/loop_transfer/boards/frdm_mcxc444.overlay | 7 +++++++ 2 files changed, 11 insertions(+) create mode 100644 tests/drivers/dma/loop_transfer/boards/frdm_mcxc444.conf create mode 100644 tests/drivers/dma/loop_transfer/boards/frdm_mcxc444.overlay diff --git a/tests/drivers/dma/loop_transfer/boards/frdm_mcxc444.conf b/tests/drivers/dma/loop_transfer/boards/frdm_mcxc444.conf new file mode 100644 index 000000000000..a1e9e76dcaaa --- /dev/null +++ b/tests/drivers/dma/loop_transfer/boards/frdm_mcxc444.conf @@ -0,0 +1,4 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_DMA_LOOP_TRANSFER_SIZE=1024 diff --git a/tests/drivers/dma/loop_transfer/boards/frdm_mcxc444.overlay b/tests/drivers/dma/loop_transfer/boards/frdm_mcxc444.overlay new file mode 100644 index 000000000000..64ad361fb63a --- /dev/null +++ b/tests/drivers/dma/loop_transfer/boards/frdm_mcxc444.overlay @@ -0,0 +1,7 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +tst_dma0: &dma {}; From ca5986b084d07e2834cf80d3944f618f682ac65a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Stasiak?= Date: Tue, 9 Dec 2025 11:56:23 +0100 Subject: [PATCH 0166/3659] drivers: i2c: clean-up macros used in nrfx_twim MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Removed unused macros. Moved common macros to common header. Aligned naming and style to other nrf drivers. Signed-off-by: Michał Stasiak --- drivers/i2c/i2c_nrfx_twim.c | 95 ++++++++----------- drivers/i2c/i2c_nrfx_twim_common.h | 46 +++++---- drivers/i2c/i2c_nrfx_twim_rtio.c | 144 +++++++++++++---------------- 3 files changed, 134 insertions(+), 151 deletions(-) diff --git a/drivers/i2c/i2c_nrfx_twim.c b/drivers/i2c/i2c_nrfx_twim.c index 59fe40404e5b..9c7b2a6cde79 100644 --- a/drivers/i2c/i2c_nrfx_twim.c +++ b/drivers/i2c/i2c_nrfx_twim.c @@ -245,62 +245,43 @@ static DEVICE_API(i2c, i2c_nrfx_twim_driver_api) = { #define DT_DRV_COMPAT nordic_nrf_twim #endif -#define CONCAT_BUF_SIZE(idx) \ - COND_CODE_1(DT_NODE_HAS_PROP(DT_DRV_INST(idx), zephyr_concat_buf_size), \ - (DT_INST_PROP(idx, zephyr_concat_buf_size)), (0)) -#define FLASH_BUF_MAX_SIZE(idx) \ - COND_CODE_1(DT_NODE_HAS_PROP(DT_DRV_INST(idx), zephyr_flash_buf_max_size), \ - (DT_INST_PROP(idx, zephyr_flash_buf_max_size)), (0)) - -#define USES_MSG_BUF(idx) \ - COND_CODE_0(CONCAT_BUF_SIZE(idx), \ - (COND_CODE_0(FLASH_BUF_MAX_SIZE(idx), (0), (1))), \ - (1)) -#define MSG_BUF_SIZE(idx) MAX(CONCAT_BUF_SIZE(idx), FLASH_BUF_MAX_SIZE(idx)) - -#define I2C_NRFX_TWIM_DEVICE(idx) \ - NRF_DT_CHECK_NODE_HAS_PINCTRL_SLEEP(DT_DRV_INST(idx)); \ - NRF_DT_CHECK_NODE_HAS_REQUIRED_MEMORY_REGIONS(DT_DRV_INST(idx)); \ - BUILD_ASSERT(I2C_FREQUENCY(DT_DRV_INST(idx)) != I2C_NRFX_TWIM_INVALID_FREQUENCY, \ - "Wrong I2C " #idx " frequency setting in dts"); \ - static struct i2c_nrfx_twim_data twim_##idx##_data; \ - static struct i2c_nrfx_twim_common_config twim_##idx##z_config; \ - static void pre_init##idx(void) \ - { \ - twim_##idx##z_config.twim = &twim_##idx##_data.twim; \ - twim_##idx##_data.twim.p_twim = (NRF_TWIM_Type *)DT_INST_REG_ADDR(idx); \ - IRQ_CONNECT(DT_INST_IRQN(idx), DT_INST_IRQ(idx, priority), nrfx_twim_irq_handler, \ - &twim_##idx##_data.twim, 0); \ - } \ - IF_ENABLED(USES_MSG_BUF(idx), \ - (static uint8_t twim_##idx##_msg_buf[MSG_BUF_SIZE(idx)] \ - I2C_MEMORY_SECTION(idx);)) \ - PINCTRL_DT_INST_DEFINE(idx); \ - static struct i2c_nrfx_twim_common_config twim_##idx##z_config = { \ - .twim_config = \ - { \ - .skip_gpio_cfg = true, \ - .skip_psel_cfg = true, \ - .frequency = I2C_FREQUENCY(DT_DRV_INST(idx)), \ - }, \ - .event_handler = event_handler, \ - .msg_buf_size = MSG_BUF_SIZE(idx), \ - .pre_init = pre_init##idx, \ - .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(idx), \ - IF_ENABLED(USES_MSG_BUF(idx), \ - (.msg_buf = twim_##idx##_msg_buf,)) .max_transfer_size = \ - BIT_MASK(DT_INST_PROP(idx, easydma_maxcnt_bits)), \ - }; \ - PM_DEVICE_DT_INST_DEFINE(idx, twim_nrfx_pm_action, I2C_PM_ISR_SAFE(idx)); \ - I2C_DEVICE_DT_INST_DEINIT_DEFINE(idx, i2c_nrfx_twim_init, i2c_nrfx_twim_deinit, \ - PM_DEVICE_DT_INST_GET(idx), &twim_##idx##_data, \ - &twim_##idx##z_config, POST_KERNEL, \ - CONFIG_I2C_INIT_PRIORITY, &i2c_nrfx_twim_driver_api) - -#define I2C_MEMORY_SECTION(idx) \ - COND_CODE_1(DT_NODE_HAS_PROP(DT_DRV_INST(idx), memory_regions), \ - (__attribute__((__section__(LINKER_DT_NODE_REGION_NAME( \ - DT_PHANDLE(DT_DRV_INST(idx), memory_regions)))))), \ - ()) +#define I2C_NRFX_TWIM_DEVICE(inst) \ + NRF_DT_CHECK_NODE_HAS_PINCTRL_SLEEP(DT_DRV_INST(inst)); \ + NRF_DT_CHECK_NODE_HAS_REQUIRED_MEMORY_REGIONS(DT_DRV_INST(inst)); \ + BUILD_ASSERT(I2C_FREQUENCY(inst) != I2C_NRFX_TWIM_INVALID_FREQUENCY, \ + "Wrong I2C " #inst " frequency setting in dts"); \ + static struct i2c_nrfx_twim_data twim_##inst##_data; \ + static struct i2c_nrfx_twim_common_config twim_##inst##z_config; \ + static void pre_init##inst(void) \ + { \ + twim_##inst##z_config.twim = &twim_##inst##_data.twim; \ + twim_##inst##_data.twim.p_twim = (NRF_TWIM_Type *)DT_INST_REG_ADDR(inst); \ + IRQ_CONNECT(DT_INST_IRQN(inst), DT_INST_IRQ(inst, priority), \ + nrfx_twim_irq_handler, &twim_##inst##_data.twim, 0); \ + } \ + IF_ENABLED(USES_MSG_BUF(inst), \ + (static uint8_t twim_##inst##_msg_buf[MSG_BUF_SIZE(inst)] \ + DMM_MEMORY_SECTION(DT_DRV_INST(inst));)) \ + PINCTRL_DT_INST_DEFINE(inst); \ + static struct i2c_nrfx_twim_common_config twim_##inst##z_config = { \ + .twim_config = \ + { \ + .skip_gpio_cfg = true, \ + .skip_psel_cfg = true, \ + .frequency = I2C_FREQUENCY(inst), \ + }, \ + .event_handler = event_handler, \ + .msg_buf_size = MSG_BUF_SIZE(inst), \ + .pre_init = pre_init##inst, \ + .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(inst), \ + IF_ENABLED(USES_MSG_BUF(inst), \ + (.msg_buf = twim_##inst##_msg_buf,)) \ + .max_transfer_size = MAX_TRANSFER_SIZE(inst), \ + }; \ + PM_DEVICE_DT_INST_DEFINE(inst, twim_nrfx_pm_action, I2C_PM_ISR_SAFE(inst)); \ + I2C_DEVICE_DT_INST_DEINIT_DEFINE(inst, i2c_nrfx_twim_init, i2c_nrfx_twim_deinit, \ + PM_DEVICE_DT_INST_GET(inst), &twim_##inst##_data, \ + &twim_##inst##z_config, POST_KERNEL, \ + CONFIG_I2C_INIT_PRIORITY, &i2c_nrfx_twim_driver_api) \ DT_INST_FOREACH_STATUS_OKAY(I2C_NRFX_TWIM_DEVICE) diff --git a/drivers/i2c/i2c_nrfx_twim_common.h b/drivers/i2c/i2c_nrfx_twim_common.h index c51932af5fd3..a0894cdcac86 100644 --- a/drivers/i2c/i2c_nrfx_twim_common.h +++ b/drivers/i2c/i2c_nrfx_twim_common.h @@ -26,10 +26,8 @@ extern "C" { (bitrate == I2C_BITRATE_FAST_PLUS ? NRF_TWIM_FREQ_1000K :)) \ I2C_NRFX_TWIM_INVALID_FREQUENCY) -#define I2C(idx) DT_NODELABEL(i2c##idx) -#define I2C_HAS_PROP(idx, prop) DT_NODE_HAS_PROP(I2C(idx), prop) -#define I2C_FREQUENCY(node) \ - I2C_NRFX_TWIM_FREQUENCY(DT_PROP_OR(node, clock_frequency, I2C_BITRATE_STANDARD)) +#define I2C_FREQUENCY(inst) \ + I2C_NRFX_TWIM_FREQUENCY(DT_INST_PROP_OR(inst, clock_frequency, I2C_BITRATE_STANDARD)) /* Macro determines PM actions interrupt safety level. * @@ -38,20 +36,36 @@ extern "C" { * no longer ISR safe. This macro let's us check if we will be requesting/releasing * power domains and determines PM device ISR safety value. */ -#define I2C_PM_ISR_SAFE(idx) \ - COND_CODE_1( \ - UTIL_AND( \ - IS_ENABLED(CONFIG_PM_DEVICE_POWER_DOMAIN), \ - UTIL_AND( \ - DT_NODE_HAS_PROP(DT_DRV_INST(idx), power_domains), \ - DT_NODE_HAS_STATUS_OKAY(DT_PHANDLE(DT_DRV_INST(idx), \ - power_domains)) \ - ) \ - ), \ - (0), \ - (PM_DEVICE_ISR_SAFE) \ +#define I2C_PM_ISR_SAFE(inst) \ + COND_CODE_1( \ + UTIL_AND( \ + IS_ENABLED(CONFIG_PM_DEVICE_POWER_DOMAIN), \ + UTIL_AND( \ + DT_NODE_INST_HAS_PROP(inst, power_domains), \ + DT_NODE_HAS_STATUS_OKAY(DT_INST_PHANDLE(inst, power_domains)) \ + ) \ + ), \ + (0), \ + (PM_DEVICE_ISR_SAFE) \ ) +#define CONCAT_BUF_SIZE(inst) \ + COND_CODE_1(DT_INST_NODE_HAS_PROP(inst, zephyr_concat_buf_size), \ + (DT_INST_PROP(inst, zephyr_concat_buf_size)), (0)) + +#define FLASH_BUF_MAX_SIZE(inst) \ + COND_CODE_1(DT_INST_NODE_HAS_PROP(inst, zephyr_flash_buf_max_size), \ + (DT_INST_PROP(inst, zephyr_flash_buf_max_size)), (0)) + +#define USES_MSG_BUF(inst) \ + COND_CODE_0(CONCAT_BUF_SIZE(inst), \ + (COND_CODE_0(FLASH_BUF_MAX_SIZE(inst), (0), (1))), \ + (1)) + +#define MSG_BUF_SIZE(inst) MAX(CONCAT_BUF_SIZE(inst), FLASH_BUF_MAX_SIZE(inst)) + +#define MAX_TRANSFER_SIZE(inst) BIT_MASK(DT_INST_PROP(inst, easydma_maxcnt_bits)) + struct i2c_nrfx_twim_common_config { nrfx_twim_config_t twim_config; nrfx_twim_event_handler_t event_handler; diff --git a/drivers/i2c/i2c_nrfx_twim_rtio.c b/drivers/i2c/i2c_nrfx_twim_rtio.c index 3f1bd9344fed..a14ebf9afd29 100644 --- a/drivers/i2c/i2c_nrfx_twim_rtio.c +++ b/drivers/i2c/i2c_nrfx_twim_rtio.c @@ -221,85 +221,73 @@ static int i2c_nrfx_twim_rtio_deinit(const struct device *dev) } #endif -#define CONCAT_BUF_SIZE(idx) \ - COND_CODE_1(DT_NODE_HAS_PROP(DT_DRV_INST(idx), zephyr_concat_buf_size), \ - (DT_INST_PROP(idx, zephyr_concat_buf_size)), (0)) -#define FLASH_BUF_MAX_SIZE(idx) \ - COND_CODE_1(DT_NODE_HAS_PROP(DT_DRV_INST(idx), zephyr_flash_buf_max_size), \ - (DT_INST_PROP(idx, zephyr_flash_buf_max_size)), (0)) - -#define USES_MSG_BUF(idx) \ - COND_CODE_0(CONCAT_BUF_SIZE(idx), (COND_CODE_0(FLASH_BUF_MAX_SIZE(idx), (0), (1))), (1)) -#define MSG_BUF_SIZE(idx) MAX(CONCAT_BUF_SIZE(idx), FLASH_BUF_MAX_SIZE(idx)) - -#define MSG_BUF_HAS_MEMORY_REGIONS(idx) DT_NODE_HAS_PROP(DT_DRV_INST(idx), memory_regions) - -#define MSG_BUF_LINKER_REGION_NAME(idx) \ - LINKER_DT_NODE_REGION_NAME(DT_PHANDLE(DT_DRV_INST(idx), memory_regions)) - -#define MSG_BUF_ATTR_SECTION(idx) \ - __attribute__((__section__(MSG_BUF_LINKER_REGION_NAME(idx)))) - -#define MSG_BUF_ATTR(idx) \ - COND_CODE_1( \ - MSG_BUF_HAS_MEMORY_REGIONS(idx), \ - (MSG_BUF_ATTR_SECTION(idx)), \ - () \ +#define MSG_BUF_HAS_MEMORY_REGIONS(inst) DT_INST_NODE_HAS_PROP(inst, memory_regions) + +#define MSG_BUF_LINKER_REGION_NAME(inst) \ + LINKER_DT_NODE_REGION_NAME(DT_INST_PHANDLE(inst, memory_regions)) + +#define MSG_BUF_ATTR_SECTION(inst) \ + __attribute__((__section__(MSG_BUF_LINKER_REGION_NAME(inst)))) + +#define MSG_BUF_ATTR(inst) \ + COND_CODE_1( \ + MSG_BUF_HAS_MEMORY_REGIONS(inst), \ + (MSG_BUF_ATTR_SECTION(inst)), \ + () \ ) -#define MSG_BUF_SYM(idx) \ - _CONCAT_3(twim_, idx, _msg_buf) - -#define MSG_BUF_DEFINE(idx) \ - static uint8_t MSG_BUF_SYM(idx)[MSG_BUF_SIZE(idx)] MSG_BUF_ATTR(idx) - -#define MAX_TRANSFER_SIZE(idx) BIT_MASK(DT_INST_PROP(idx, easydma_maxcnt_bits)) - -#define I2C_NRFX_TWIM_RTIO_DEVICE(idx) \ - NRF_DT_CHECK_NODE_HAS_PINCTRL_SLEEP(DT_DRV_INST(idx)); \ - NRF_DT_CHECK_NODE_HAS_REQUIRED_MEMORY_REGIONS(DT_DRV_INST(idx)); \ - BUILD_ASSERT(I2C_FREQUENCY(DT_DRV_INST(idx)) != I2C_NRFX_TWIM_INVALID_FREQUENCY, \ - "Wrong I2C " #idx " frequency setting in dts"); \ - static struct i2c_nrfx_twim_rtio_data twim_##idx##z_data = { \ - .twim = \ - { \ - .p_twim = (NRF_TWIM_Type *)DT_INST_REG_ADDR(idx), \ - }, \ - }; \ - static void pre_init##idx(void) \ - { \ - twim_##idx##z_data.twim.p_twim = (NRF_TWIM_Type *)DT_INST_REG_ADDR(idx); \ - IRQ_CONNECT(DT_INST_IRQN(idx), DT_INST_IRQ(idx, priority), nrfx_twim_irq_handler, \ - &twim_##idx##z_data.twim, 0); \ - } \ - IF_ENABLED(USES_MSG_BUF(idx), (MSG_BUF_DEFINE(idx);)) \ - I2C_RTIO_DEFINE(_i2c##idx##_twim_rtio, \ - DT_INST_PROP_OR(n, sq_size, CONFIG_I2C_RTIO_SQ_SIZE), \ - DT_INST_PROP_OR(n, cq_size, CONFIG_I2C_RTIO_CQ_SIZE)); \ - PINCTRL_DT_INST_DEFINE(idx); \ - static const struct i2c_nrfx_twim_rtio_config twim_##idx##z_config = { \ - .common = \ - { \ - .twim_config = \ - { \ - .skip_gpio_cfg = true, \ - .skip_psel_cfg = true, \ - .frequency = I2C_FREQUENCY(DT_DRV_INST(idx)), \ - }, \ - .event_handler = event_handler, \ - .msg_buf_size = MSG_BUF_SIZE(idx), \ - .pre_init = pre_init##idx, \ - .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(idx), \ - IF_ENABLED(USES_MSG_BUF(idx), (.msg_buf = MSG_BUF_SYM(idx),)) \ - .max_transfer_size = MAX_TRANSFER_SIZE(idx), \ - .twim = &twim_##idx##z_data.twim, \ - }, \ - .ctx = &_i2c##idx##_twim_rtio, \ - }; \ - PM_DEVICE_DT_INST_DEFINE(idx, twim_nrfx_pm_action, I2C_PM_ISR_SAFE(idx)); \ - I2C_DEVICE_DT_INST_DEINIT_DEFINE(idx, i2c_nrfx_twim_rtio_init, i2c_nrfx_twim_rtio_deinit, \ - PM_DEVICE_DT_INST_GET(idx), &twim_##idx##z_data, \ - &twim_##idx##z_config, POST_KERNEL, \ - CONFIG_I2C_INIT_PRIORITY, &i2c_nrfx_twim_driver_api); +#define MSG_BUF_SYM(inst) \ + _CONCAT_3(twim_, inst, _msg_buf) + +#define MSG_BUF_DEFINE(inst) \ + static uint8_t MSG_BUF_SYM(inst)[MSG_BUF_SIZE(inst)] MSG_BUF_ATTR(inst) + +#define I2C_NRFX_TWIM_RTIO_DEVICE(inst) \ + NRF_DT_CHECK_NODE_HAS_PINCTRL_SLEEP(DT_DRV_INST(inst)); \ + NRF_DT_CHECK_NODE_HAS_REQUIRED_MEMORY_REGIONS(DT_DRV_INST(inst)); \ + BUILD_ASSERT(I2C_FREQUENCY(inst) != I2C_NRFX_TWIM_INVALID_FREQUENCY, \ + "Wrong I2C " #inst " frequency setting in dts"); \ + static struct i2c_nrfx_twim_rtio_data twim_##inst##z_data = { \ + .twim = \ + { \ + .p_twim = (NRF_TWIM_Type *)DT_INST_REG_ADDR(inst), \ + }, \ + }; \ + static void pre_init##inst(void) \ + { \ + twim_##inst##z_data.twim.p_twim = (NRF_TWIM_Type *)DT_INST_REG_ADDR(inst); \ + IRQ_CONNECT(DT_INST_IRQN(inst), DT_INST_IRQ(inst, priority), \ + nrfx_twim_irq_handler, &twim_##inst##z_data.twim, 0); \ + } \ + IF_ENABLED(USES_MSG_BUF(inst), (MSG_BUF_DEFINE(inst);)) \ + I2C_RTIO_DEFINE(_i2c##inst##_twim_rtio, \ + DT_INST_PROP_OR(n, sq_size, CONFIG_I2C_RTIO_SQ_SIZE), \ + DT_INST_PROP_OR(n, cq_size, CONFIG_I2C_RTIO_CQ_SIZE)); \ + PINCTRL_DT_INST_DEFINE(inst); \ + static const struct i2c_nrfx_twim_rtio_config twim_##inst##z_config = { \ + .common = \ + { \ + .twim_config = \ + { \ + .skip_gpio_cfg = true, \ + .skip_psel_cfg = true, \ + .frequency = I2C_FREQUENCY(inst), \ + }, \ + .event_handler = event_handler, \ + .msg_buf_size = MSG_BUF_SIZE(inst), \ + .pre_init = pre_init##inst, \ + .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(inst), \ + IF_ENABLED(USES_MSG_BUF(inst), (.msg_buf = MSG_BUF_SYM(inst),)) \ + .max_transfer_size = MAX_TRANSFER_SIZE(inst), \ + .twim = &twim_##inst##z_data.twim, \ + }, \ + .ctx = &_i2c##inst##_twim_rtio, \ + }; \ + PM_DEVICE_DT_INST_DEFINE(inst, twim_nrfx_pm_action, I2C_PM_ISR_SAFE(inst)); \ + I2C_DEVICE_DT_INST_DEINIT_DEFINE(inst, i2c_nrfx_twim_rtio_init, \ + i2c_nrfx_twim_rtio_deinit, \ + PM_DEVICE_DT_INST_GET(inst), &twim_##inst##z_data, \ + &twim_##inst##z_config, POST_KERNEL, \ + CONFIG_I2C_INIT_PRIORITY, &i2c_nrfx_twim_driver_api); \ DT_INST_FOREACH_STATUS_OKAY(I2C_NRFX_TWIM_RTIO_DEVICE) From 013428c5518d0b06ec08a42f63aa19e3ff6ff853 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Stasiak?= Date: Tue, 9 Dec 2025 13:37:27 +0100 Subject: [PATCH 0167/3659] drivers: i2c: add DMM to i2c_nrfx_twim MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added DMM buffer preparation to I2C TWIM driver. Adds little impact as buffer content is already copied into message buffer which is places in proper memory for optimized transfer. Signed-off-by: Michał Stasiak --- drivers/i2c/i2c_nrfx_twim.c | 32 +++++++++++++++++++++++++++++- drivers/i2c/i2c_nrfx_twim_common.h | 1 + 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/drivers/i2c/i2c_nrfx_twim.c b/drivers/i2c/i2c_nrfx_twim.c index 9c7b2a6cde79..7f9369cce0b8 100644 --- a/drivers/i2c/i2c_nrfx_twim.c +++ b/drivers/i2c/i2c_nrfx_twim.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -33,6 +34,7 @@ struct i2c_nrfx_twim_data { struct k_sem transfer_sync; struct k_sem completion_sync; volatile int res; + uint8_t *buf_ptr; }; int i2c_nrfx_twim_exclusive_access_acquire(const struct device *dev, k_timeout_t timeout) @@ -70,6 +72,7 @@ static int i2c_nrfx_twim_transfer(const struct device *dev, uint16_t msg_buf_size = dev_config->msg_buf_size; uint8_t *buf; uint16_t buf_len; + uint8_t *dma_buf; (void)i2c_nrfx_twim_exclusive_access_acquire(dev, K_FOREVER); @@ -134,7 +137,23 @@ static int i2c_nrfx_twim_transfer(const struct device *dev, buf = msg_buf; buf_len = msg_buf_used; } - ret = i2c_nrfx_twim_msg_transfer(dev, msgs[i].flags, buf, buf_len, addr); + + if (msgs[i].flags & I2C_MSG_READ) { + ret = dmm_buffer_in_prepare(dev_config->mem_reg, buf, buf_len, + (void **)&dma_buf); + } else { + ret = dmm_buffer_out_prepare(dev_config->mem_reg, buf, buf_len, + (void **)&dma_buf); + } + + if (ret < 0) { + LOG_ERR("Failed to prepare buffer: %d", ret); + return ret; + } + + dev_data->buf_ptr = buf; + + ret = i2c_nrfx_twim_msg_transfer(dev, msgs[i].flags, dma_buf, buf_len, addr); if (ret < 0) { break; } @@ -196,6 +215,16 @@ static void event_handler(nrfx_twim_event_t const *p_event, void *p_context) { const struct device *dev = p_context; struct i2c_nrfx_twim_data *dev_data = dev->data; + const struct i2c_nrfx_twim_common_config *config = dev->config; + + if (p_event->xfer_desc.type == NRFX_TWIM_XFER_TX) { + dmm_buffer_out_release(config->mem_reg, + (void **)&p_event->xfer_desc.p_primary_buf); + } else { + dmm_buffer_in_release(config->mem_reg, dev_data->buf_ptr, + p_event->xfer_desc.primary_length, + p_event->xfer_desc.p_primary_buf); + } switch (p_event->type) { case NRFX_TWIM_EVT_DONE: @@ -277,6 +306,7 @@ static DEVICE_API(i2c, i2c_nrfx_twim_driver_api) = { IF_ENABLED(USES_MSG_BUF(inst), \ (.msg_buf = twim_##inst##_msg_buf,)) \ .max_transfer_size = MAX_TRANSFER_SIZE(inst), \ + .mem_reg = DMM_DEV_TO_REG(DT_DRV_INST(inst)), \ }; \ PM_DEVICE_DT_INST_DEFINE(inst, twim_nrfx_pm_action, I2C_PM_ISR_SAFE(inst)); \ I2C_DEVICE_DT_INST_DEINIT_DEFINE(inst, i2c_nrfx_twim_init, i2c_nrfx_twim_deinit, \ diff --git a/drivers/i2c/i2c_nrfx_twim_common.h b/drivers/i2c/i2c_nrfx_twim_common.h index a0894cdcac86..21ba3c601ac0 100644 --- a/drivers/i2c/i2c_nrfx_twim_common.h +++ b/drivers/i2c/i2c_nrfx_twim_common.h @@ -75,6 +75,7 @@ struct i2c_nrfx_twim_common_config { uint8_t *msg_buf; uint16_t max_transfer_size; nrfx_twim_t *twim; + void *mem_reg; }; int i2c_nrfx_twim_common_init(const struct device *dev); From 51a6e8b6f6f28c4a386ab493d45dfda179f4914f Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Wed, 10 Dec 2025 08:11:04 -0500 Subject: [PATCH 0168/3659] ci: assigner: do not check permission/manifest on branches Workaround GH running workflows from main on release branches. The assignment script fails and does wrong assignments based on wrong versions of the maintainer file and manifest. Signed-off-by: Anas Nashif --- .github/workflows/assigner.yml | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/.github/workflows/assigner.yml b/.github/workflows/assigner.yml index 9ae1c2e3b9cc..545bb311a178 100644 --- a/.github/workflows/assigner.yml +++ b/.github/workflows/assigner.yml @@ -38,7 +38,7 @@ jobs: - name: Fetch west.yml/Maintainer.yml from pull request if: > - github.event_name == 'pull_request_target' + github.event_name == 'pull_request_target' && github.base_ref == 'main' run: | git fetch origin pull/${{ github.event.pull_request.number }}/merge git show FETCH_HEAD:west.yml > pr_west.yml @@ -61,7 +61,11 @@ jobs: FLAGS+=" -r ${{ github.event.repository.name }}" FLAGS+=" -M MAINTAINERS.yml" if [ "${{ github.event_name }}" = "pull_request_target" ]; then - FLAGS+=" -P ${{ github.event.pull_request.number }} --updated-manifest pr_west.yml --updated-maintainer-file pr_MAINTAINERS.yml" + if [ "${{ github.base_ref }}" != "main" ]; then + FLAGS+=" -P ${{ github.event.pull_request.number }} --updated-manifest pr_west.yml --updated-maintainer-file pr_MAINTAINERS.yml" + else + FLAGS+=" -P ${{ github.event.pull_request.number }}" + fi elif [ "${{ github.event_name }}" = "issues" ]; then FLAGS+=" -I ${{ github.event.issue.number }}" elif [ "${{ github.event_name }}" = "schedule" ]; then @@ -74,7 +78,7 @@ jobs: - name: Check maintainer file changes if: > - github.event_name == 'pull_request_target' + github.event_name == 'pull_request_target' && github.base_ref == 'main' env: GITHUB_TOKEN: ${{ secrets.ZB_PR_ASSIGNER_GITHUB_TOKEN }} run: | From 172c403be554f09c0deedbf0d0552ed712cf1196 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Wed, 10 Dec 2025 08:47:20 -0500 Subject: [PATCH 0169/3659] Revert "ci: assigner: only run on main branch" This reverts commit 79356f1385ff24ae3f9b6e4b94d19bee93aef781. Was the wrong "fix". Signed-off-by: Anas Nashif --- .github/workflows/assigner.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/assigner.yml b/.github/workflows/assigner.yml index 545bb311a178..e1dc1006f85b 100644 --- a/.github/workflows/assigner.yml +++ b/.github/workflows/assigner.yml @@ -9,6 +9,8 @@ on: - ready_for_review branches: - main + - collab-* + - v*-branch issues: types: - labeled From ce99d1e4282bf3291154c587e3053166fa418d27 Mon Sep 17 00:00:00 2001 From: Marcelo Roberto Jimenez Date: Wed, 10 Dec 2025 10:39:12 -0300 Subject: [PATCH 0170/3659] drivers: ethernet: stm32hal: Fixes source address control The default configuration for all STM32 microcontrollers in HAL is to replace the ehternet MAC address with the address configured in replace address zero. In "modules/hal", Grep for: macDefaultConf.SourceAddrControl = ETH_SOURCEADDRESS_REPLACE_ADDR0; But this is a bad thing for bridging. Since Zephyr ethernet LL code always writes the source address, this patch has no impact on normal operation. And has the benefit of maintaining the source MAC address of bridged packets. Signed-off-by: Marcelo Roberto Jimenez --- drivers/ethernet/eth_stm32_hal_v2.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/ethernet/eth_stm32_hal_v2.c b/drivers/ethernet/eth_stm32_hal_v2.c index 9992d15b930b..f075ba2e42dd 100644 --- a/drivers/ethernet/eth_stm32_hal_v2.c +++ b/drivers/ethernet/eth_stm32_hal_v2.c @@ -679,6 +679,14 @@ void eth_stm32_set_mac_config(const struct device *dev, struct phy_link_state *s #if DT_HAS_COMPAT_STATUS_OKAY(st_stm32n6_ethernet) mac_config.PortSelect = PHY_LINK_IS_SPEED_1000M(state->speed) ? DISABLE : ENABLE; #endif + + /* Always disable hardware source address replacement. + * Zephyr network stack sets the source MAC address and + * therefore hardware replacement should not be enabled, + * since it may affect bridging applications, for example. + */ + mac_config.SourceAddrControl = ETH_SOURCEADDRESS_DISABLE; + hal_ret = HAL_ETH_SetMACConfig(heth, &mac_config); if (hal_ret != HAL_OK) { LOG_ERR("HAL_ETH_SetMACConfig failed: %d", hal_ret); From 24b3ff233bc89352158abedb71aea2ca9ef59e41 Mon Sep 17 00:00:00 2001 From: Peter van der Perk Date: Fri, 28 Nov 2025 11:07:23 +0100 Subject: [PATCH 0171/3659] gpio: mcux_rgpio: Support IRQ output select and access checks for i.MX95 M7 Support for selecting the IRQ output via the `irq-output-select` property in devicetree. Updates interrupt configuration and ISR logic to use the selected IRQ index. For i.MX95 M7, ensures pins and IRQs are configured only when secure access is allowed by checking PCNS and ICNS registers. Signed-off-by: Peter van der Perk --- drivers/gpio/gpio_mcux_rgpio.c | 36 ++++++++++++++++++++-------- dts/bindings/gpio/nxp,imx-rgpio.yaml | 11 +++++++++ 2 files changed, 37 insertions(+), 10 deletions(-) diff --git a/drivers/gpio/gpio_mcux_rgpio.c b/drivers/gpio/gpio_mcux_rgpio.c index 27933dcea956..6fc7df16b1b4 100644 --- a/drivers/gpio/gpio_mcux_rgpio.c +++ b/drivers/gpio/gpio_mcux_rgpio.c @@ -35,6 +35,7 @@ struct mcux_rgpio_config { const struct pinctrl_soc_pinmux *pin_muxes; uint8_t mux_count; + uint8_t irq_sel; }; struct mcux_rgpio_data { @@ -144,6 +145,14 @@ static int mcux_rgpio_configure(const struct device *dev, } #endif +#if !defined(__ARM_FEATURE_CMSE) + base->PCNS &= ~BIT(pin); + if (base->PCNS & BIT(pin)) { + /* We don't have access to this pin */ + return -ENOTSUP; + } +#endif + memcpy(&pin_cfg.pinmux, &config->pin_muxes[cfg_idx], sizeof(pin_cfg)); /* cfg register will be set by pinctrl_configure_pins */ pin_cfg.pin_ctrl_flags = reg; @@ -226,12 +235,20 @@ static int mcux_rgpio_pin_interrupt_configure(const struct device *dev, unsigned int key; uint8_t irqs, irqc; +#if !defined(__ARM_FEATURE_CMSE) + base->ICNS &= ~BIT(config->irq_sel); + if (base->ICNS & BIT(config->irq_sel)) { + /* We don't have access to this IRQ */ + return -ENOTSUP; + } +#endif + /* Make sure pin is supported */ if ((config->common.port_pin_mask & BIT(pin)) == 0) { return -ENOTSUP; } - irqs = 0; /* only irq0 is used for irq */ + irqs = config->irq_sel; if (mode == GPIO_INT_MODE_DISABLED) { irqc = kRGPIO_InterruptOrDMADisabled; @@ -277,9 +294,9 @@ static void mcux_rgpio_port_isr(const struct device *dev) struct mcux_rgpio_data *data = dev->data; uint32_t int_flags; - int_flags = base->ISFR[0]; /* Notice: only irq0 is used for now */ + int_flags = base->ISFR[config->irq_sel]; int_flags &= config->common.port_pin_mask; /* don't handle unusable pin */ - base->ISFR[0] = int_flags; + base->ISFR[config->irq_sel] = int_flags; gpio_fire_callbacks(&data->callbacks, dev, int_flags); } @@ -303,7 +320,8 @@ static DEVICE_API(gpio, mcux_rgpio_driver_api) = { }; #define MCUX_RGPIO_PIN_INIT(n) \ .pin_muxes = mcux_rgpio_pinmux_##n, \ - .mux_count = DT_PROP_LEN(DT_DRV_INST(n), pinmux), + .mux_count = DT_PROP_LEN(DT_DRV_INST(n), pinmux), \ + .irq_sel = DT_INST_PROP(n, irq_output_select) \ #define MCUX_RGPIO_IRQ_INIT(n, i) \ do { \ @@ -317,6 +335,8 @@ static DEVICE_API(gpio, mcux_rgpio_driver_api) = { #define MCUX_RGPIO_INIT(n) \ MCUX_RGPIO_PIN_DECLARE(n) \ + BUILD_ASSERT((DT_INST_PROP(n, irq_output_select) != 1) || DT_INST_IRQ_HAS_IDX(n, 1), \ + "irq-output-select=1 but IRQ 1 is not defined"); \ static int mcux_rgpio_##n##_init(const struct device *dev); \ \ static const struct mcux_rgpio_config mcux_rgpio_##n##_config = { \ @@ -343,12 +363,8 @@ static DEVICE_API(gpio, mcux_rgpio_driver_api) = { { \ DEVICE_MMIO_NAMED_MAP(dev, reg_base, \ K_MEM_CACHE_NONE | K_MEM_DIRECT_MAP); \ - IF_ENABLED(DT_INST_IRQ_HAS_IDX(n, 0), \ - (MCUX_RGPIO_IRQ_INIT(n, 0);)) \ - \ - IF_ENABLED(DT_INST_IRQ_HAS_IDX(n, 1), \ - (MCUX_RGPIO_IRQ_INIT(n, 1);)) \ - \ + IF_ENABLED(DT_INST_IRQ_HAS_IDX(n, DT_INST_PROP(n, irq_output_select)), \ + (MCUX_RGPIO_IRQ_INIT(n, DT_INST_PROP(n, irq_output_select));)) \ return 0; \ } diff --git a/dts/bindings/gpio/nxp,imx-rgpio.yaml b/dts/bindings/gpio/nxp,imx-rgpio.yaml index 9b032c1350cd..ac10b42cc589 100644 --- a/dts/bindings/gpio/nxp,imx-rgpio.yaml +++ b/dts/bindings/gpio/nxp,imx-rgpio.yaml @@ -23,6 +23,17 @@ properties: "#gpio-cells": const: 2 + irq-output-select: + type: int + default: 0 + description: | + Select which IRQ line the GPIO controller outputs to. + 0 = First IRQ line (default) + 1 = Second IRQ line + enum: + - 0 + - 1 + gpio-cells: - pin - flags From a8d0a7789ea47f9f691bb101e6c9ec82f5bf3c4d Mon Sep 17 00:00:00 2001 From: Qingsong Gou Date: Fri, 5 Dec 2025 18:33:46 +0800 Subject: [PATCH 0172/3659] drivers: adc: sf32lb: fix ref_internal Fix adc ref_internal value Signed-off-by: Qingsong Gou --- drivers/adc/adc_sf32lb.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/adc/adc_sf32lb.c b/drivers/adc/adc_sf32lb.c index f0a5895394f2..1f092d96df90 100644 --- a/drivers/adc/adc_sf32lb.c +++ b/drivers/adc/adc_sf32lb.c @@ -31,6 +31,8 @@ LOG_MODULE_REGISTER(adc_sf32lb, CONFIG_ADC_LOG_LEVEL); #define ADC_RDATAX(n) (ADC_RDATA + (((n) >> 1) * 4U)) #define ADC_SLOT_REGX(n) (ADC_SLOT_REG + (n) * 4U) +#define ADC_SF32LB_DEFAULT_VREF_INTERNAL 3300 + struct adc_sf32lb_data { struct adc_context ctx; const struct device *dev; @@ -214,6 +216,7 @@ static int adc_sf32lb_read(const struct device *dev, const struct adc_sequence * static DEVICE_API(adc, adc_sf32lb_driver_api) = { .channel_setup = adc_sf32lb_channel_setup, .read = adc_sf32lb_read, + .ref_internal = ADC_SF32LB_DEFAULT_VREF_INTERNAL, }; static int adc_sf32lb_init(const struct device *dev) From 6c6e8e51bfdfc4947e2a69f62d7e2ee4caaef05f Mon Sep 17 00:00:00 2001 From: Tahsin Mutlugun Date: Wed, 26 Nov 2025 13:34:22 +0300 Subject: [PATCH 0173/3659] drivers: serial: uart_max32: Refactor IRQ flag clearing api_irq_update was clearing TX interrupt flags before the TX interrupt could be served, breaking synchronization in time-sensitive applications. Changes: 1. Remove unnecessary MXC_UART_ClearFlags() calls in api_fifo_read() and api_irq_update to avoid premature flag clearing; ISR handler already clears them after returning from the callback. 2. Replace raw flag checks in irq_is_pending() with more complete api_irq_rx_ready() and api_irq_tx_ready(). Signed-off-by: Tahsin Mutlugun --- drivers/serial/uart_max32.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/drivers/serial/uart_max32.c b/drivers/serial/uart_max32.c index 43c0e9a2ac46..4a43149f6725 100644 --- a/drivers/serial/uart_max32.c +++ b/drivers/serial/uart_max32.c @@ -367,9 +367,6 @@ static int api_fifo_read(const struct device *dev, uint8_t *rx_data, const int s const struct max32_uart_config *cfg = dev->config; num_rx = MXC_UART_ReadRXFIFO(cfg->regs, (unsigned char *)rx_data, size); - if (num_rx == 0) { - MXC_UART_ClearFlags(cfg->regs, ADI_MAX32_UART_INT_RX); - } return num_rx; } @@ -438,9 +435,7 @@ static void api_irq_err_disable(const struct device *dev) static int api_irq_is_pending(const struct device *dev) { - struct max32_uart_data *const data = dev->data; - - return (data->flags & (ADI_MAX32_UART_INT_RX | ADI_MAX32_UART_INT_TX)); + return api_irq_rx_ready(dev) || api_irq_tx_ready(dev); } static int api_irq_update(const struct device *dev) @@ -451,8 +446,6 @@ static int api_irq_update(const struct device *dev) data->flags = MXC_UART_GetFlags(cfg->regs); data->status = MXC_UART_GetStatus(cfg->regs); - MXC_UART_ClearFlags(cfg->regs, data->flags); - return 1; } From 15965b266c118c4f77665f36a9359b2f70469d99 Mon Sep 17 00:00:00 2001 From: Tahsin Mutlugun Date: Wed, 26 Nov 2025 14:08:57 +0300 Subject: [PATCH 0174/3659] drivers: serial: uart_max32: Enable TX AE workaround for MAX32657 Extend UART_MAX32_TX_AE_WORKAROUND to also apply when building for MAX32657. Without this option, logging output may become fragmented or delayed because TX interrupts fail to trigger reliably for small chunks of data. Signed-off-by: Tahsin Mutlugun --- drivers/serial/Kconfig.max32 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/serial/Kconfig.max32 b/drivers/serial/Kconfig.max32 index ff14affbadb1..8380d0aec2dd 100644 --- a/drivers/serial/Kconfig.max32 +++ b/drivers/serial/Kconfig.max32 @@ -19,7 +19,7 @@ config UART_MAX32 config UART_MAX32_TX_AE_WORKAROUND bool - default y if SOC_MAX32690 || SOC_MAX32655 + default y if SOC_MAX32690 || SOC_MAX32655 || SOC_MAX32657 depends on UART_MAX32 && UART_INTERRUPT_DRIVEN help This option enables a small workaround for almost-empty interrupts From ed182a89cd07cc87be9204e5c3abf560a877517b Mon Sep 17 00:00:00 2001 From: Mathieu Choplain Date: Mon, 8 Dec 2025 17:03:23 +0100 Subject: [PATCH 0175/3659] scripts: build: check_init_prio: create dedicated "flag errors" function There is a bit of logic to run every time an error is reported. Factor it out into a dedicated function. Signed-off-by: Mathieu Choplain --- scripts/build/check_init_priorities.py | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/scripts/build/check_init_priorities.py b/scripts/build/check_init_priorities.py index 616a0c65a4f3..10ac3bd0ed3b 100755 --- a/scripts/build/check_init_priorities.py +++ b/scripts/build/check_init_priorities.py @@ -262,6 +262,17 @@ def __init__(self, elf_file_path, edt_pickle, log, elf_file): self.errors = 0 + def _flag_error(self, msg): + """Remember that a validation error occurred and report to user""" + if not self.errors: + self.log.error( + "Device initialization priority validation failed, " + "the sequence of initialization calls does not match " + "the devicetree dependencies." + ) + self.errors += 1 + self.log.error(msg) + def _check_dep(self, dev_ord, dep_ord): """Validate the priority between two devices.""" if dev_ord == dep_ord: @@ -287,14 +298,7 @@ def _check_dep(self, dev_ord, dep_ord): f"{dev_node.path} and {dep_node.path} have the same priority: {dev_prio}" ) elif dev_prio < dep_prio: - if not self.errors: - self.log.error( - "Device initialization priority validation failed, " - "the sequence of initialization calls does not match " - "the devicetree dependencies." - ) - self.errors += 1 - self.log.error( + self._flag_error( f"{dev_node.path} <{dev_init}> is initialized before its dependency " f"{dep_node.path} <{dep_init}> ({dev_prio} < {dep_prio})" ) From cb27d92c0c139727857122add232cfd7c8791ce3 Mon Sep 17 00:00:00 2001 From: Mathieu Choplain Date: Mon, 8 Dec 2025 17:10:25 +0100 Subject: [PATCH 0176/3659] scripts: build: check_init_prio: take deferred-init into account A device with zephyr,deferred-init is initialized by the application, so we cannot check if it is initialized in "the correct order". On the other hand, a non-deferred device must not depend on a deferred-init device: this is guaranteed to be initialized out of order. Also adjust existing test cases and add a new test case to validate this behavior. Signed-off-by: Mathieu Choplain --- scripts/build/check_init_priorities.py | 29 ++++++++++++++++++ scripts/build/check_init_priorities_test.py | 34 +++++++++++++++++++++ 2 files changed, 63 insertions(+) diff --git a/scripts/build/check_init_priorities.py b/scripts/build/check_init_priorities.py index 10ac3bd0ed3b..5046d28f5786 100755 --- a/scripts/build/check_init_priorities.py +++ b/scripts/build/check_init_priorities.py @@ -49,6 +49,11 @@ ] ) +# Deferred initialization property name. +# When present, the device is not initialized during boot. +# (it is evaluated as if initializing "after everything else") +_DEFERRED_INIT_PROP_NAME = "zephyr,deferred-init" + # The offset of the init pointer in "struct device", in number of pointers. DEVICE_INIT_OFFSET = 5 @@ -287,6 +292,30 @@ def _check_dep(self, dev_ord, dep_ord): self.log.info(f"Ignoring priority: {dev_node._binding.compatible}") return + def _deferred(node): + # Even though the property is boolean, it is sometimes present + # in node.props despite having value false: check for both + # presence *and* value. + if (p := node.props.get(_DEFERRED_INIT_PROP_NAME)) is None: + return False + assert isinstance(p.val, bool) + return p.val + + dev_deferred = _deferred(dev_node) + dep_deferred = _deferred(dep_node) + + # Deferred devices can depend on any device... + if dev_deferred: + self.log.info(f"Ignoring deferred device {dev_node.path}") + return + + # ...but non-deferred devices cannot depend on them! + if dep_deferred: # we already know dev_deferred==False + self._flag_error( + f"Non-deferred device {dev_node.path} depends on deferred device {dep_node.path}" + ) + return + dev_prio, dev_init = self._obj.devices.get(dev_ord, (None, None)) dep_prio, dep_init = self._obj.devices.get(dep_ord, (None, None)) diff --git a/scripts/build/check_init_priorities_test.py b/scripts/build/check_init_priorities_test.py index e912ad01b0dc..e78763a5b346 100755 --- a/scripts/build/check_init_priorities_test.py +++ b/scripts/build/check_init_priorities_test.py @@ -294,7 +294,9 @@ def test_check_dep_no_prio(self, mock_vinit): validator._ord2node = {1: mock.Mock(), 2: mock.Mock()} validator._ord2node[1]._binding = None + validator._ord2node[1].props = {} validator._ord2node[2]._binding = None + validator._ord2node[2].props = {} validator._obj.devices = {1: (10, "i1")} validator._check_dep(1, 2) @@ -316,8 +318,10 @@ def test_check(self, mock_vinit): validator._ord2node = {1: mock.Mock(), 2: mock.Mock()} validator._ord2node[1]._binding = None validator._ord2node[1].path = "/1" + validator._ord2node[1].props = {} validator._ord2node[2]._binding = None validator._ord2node[2].path = "/2" + validator._ord2node[2].props = {} validator._obj.devices = {1: (10, "i1"), 2: (20, "i2")} @@ -340,8 +344,10 @@ def test_check_same_prio_assert(self, mock_vinit): validator._ord2node = {1: mock.Mock(), 2: mock.Mock()} validator._ord2node[1]._binding = None validator._ord2node[1].path = "/1" + validator._ord2node[1].props = {} validator._ord2node[2]._binding = None validator._ord2node[2].path = "/2" + validator._ord2node[2].props = {} validator._obj.devices = {1: (10, "i1"), 2: (10, "i2")} @@ -379,6 +385,34 @@ def test_check_ignored(self, mock_vinit): check_init_priorities._IGNORE_COMPATIBLES = save_ignore_compatibles + @mock.patch("check_init_priorities.Validator.__init__", return_value=None) + def test_check_deferred(self, mock_vinit): + validator = check_init_priorities.Validator("", "", None, None) + validator.log = mock.Mock() + validator._obj = mock.Mock() + validator.errors = 0 + + validator._ord2node = {1: mock.Mock(), 2: mock.Mock()} + validator._ord2node[1]._binding = None + validator._ord2node[1].path = "/1" + validator._ord2node[1].props = {} + validator._ord2node[2]._binding = None + validator._ord2node[2].path = "/2" + validator._ord2node[2].props = { + check_init_priorities._DEFERRED_INIT_PROP_NAME: mock.Mock(val=True) + } + + validator._obj.devices = {1: (10, "i1"), 2: (5, "i2")} + + validator._check_dep(2, 1) + validator._check_dep(1, 2) + + validator.log.info.assert_called_once_with("Ignoring deferred device /2") + validator.log.error.assert_has_calls( + [mock.call("Non-deferred device /1 depends on deferred device /2")] + ) + self.assertEqual(validator.errors, 1) + @mock.patch("check_init_priorities.Validator._check_dep") @mock.patch("check_init_priorities.Validator.__init__", return_value=None) def test_check_edt(self, mock_vinit, mock_cd): From 307c08ba6b7093cfe4e5b2803306b11f1cce4936 Mon Sep 17 00:00:00 2001 From: Fabrice DJIATSA Date: Mon, 8 Dec 2025 11:04:16 +0100 Subject: [PATCH 0177/3659] boards: st: stm32n6570_dk: increase size ram size of serial boot variant Increase the RAM size of the SB variant to enable execution of relevant tests that require at least 172 KB. This ensures continuous tracking of these tests on CI. Signed-off-by: Fabrice DJIATSA --- boards/st/stm32n6570_dk/twister.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boards/st/stm32n6570_dk/twister.yaml b/boards/st/stm32n6570_dk/twister.yaml index 04bb6f781e40..496de1a62aa6 100644 --- a/boards/st/stm32n6570_dk/twister.yaml +++ b/boards/st/stm32n6570_dk/twister.yaml @@ -1,7 +1,7 @@ name: STM32N6570 Discovery Kit type: mcu arch: arm -ram: 128 +ram: 192 flash: 512 vendor: st supported: From 9f0ce75b411af1d03663b4302d16de07ef223c52 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Tue, 9 Dec 2025 15:57:53 +0100 Subject: [PATCH 0178/3659] drivers: disk: loopback: Remove unnecessary include This file does not seem to need unistd.h, and that header is a POSIX extension to the C library which is not avaiable in general. So let's not include it. Without this change this file fails to build with minimal libc or other C libraries which do not have this extra header. Signed-off-by: Alberto Escolar Piedras --- drivers/disk/loopback_disk.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/disk/loopback_disk.c b/drivers/disk/loopback_disk.c index c7f587b0c195..5fa89a6457c4 100644 --- a/drivers/disk/loopback_disk.c +++ b/drivers/disk/loopback_disk.c @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include #include #include From 17d143a175084809f25a3e43c923bbb4da74241c Mon Sep 17 00:00:00 2001 From: Pete Johanson Date: Wed, 10 Dec 2025 11:56:31 -0700 Subject: [PATCH 0179/3659] tests: secure_storage: Don't try to erase flash with no controller Add a check for a chosen flash controller to avoid attempting to clear the settings flash with no controller available. Signed-off-by: Pete Johanson --- tests/subsys/secure_storage/psa/its/src/main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/subsys/secure_storage/psa/its/src/main.c b/tests/subsys/secure_storage/psa/its/src/main.c index c00dce03f790..fc075f1d3e17 100644 --- a/tests/subsys/secure_storage/psa/its/src/main.c +++ b/tests/subsys/secure_storage/psa/its/src/main.c @@ -8,7 +8,8 @@ #include /* The flash must be erased after this test suite is run for the write-once entry test to pass. */ -#if !defined(CONFIG_BUILD_WITH_TFM) && defined(CONFIG_FLASH_PAGE_LAYOUT) +#if !defined(CONFIG_BUILD_WITH_TFM) && defined(CONFIG_FLASH_PAGE_LAYOUT) && \ + DT_HAS_CHOSEN(zephyr_flash_controller) static int erase_flash(void) { const struct device *const fdev = DEVICE_DT_GET(DT_CHOSEN(zephyr_flash_controller)); From 312b1ef04f577d71e6169a47fb5a7ab66cf1cdae Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Wed, 10 Dec 2025 17:33:14 +0100 Subject: [PATCH 0180/3659] pmci: mctp: samples: Remove unnecessary include These samples do not seem to need the unistd.h header, but including it limits us to C libraries which have it, which as it is a POSIX extension is not all. So let's not include it so we do not limit ourselves unnecessarily. Signed-off-by: Alberto Escolar Piedras --- samples/subsys/pmci/mctp/endpoint/src/main.c | 1 - samples/subsys/pmci/mctp/host/src/main.c | 1 - samples/subsys/pmci/mctp/i2c_gpio_bus_endpoint/src/main.c | 1 - samples/subsys/pmci/mctp/i2c_gpio_bus_owner/src/main.c | 1 - samples/subsys/pmci/mctp/usb_endpoint/src/main.c | 1 - 5 files changed, 5 deletions(-) diff --git a/samples/subsys/pmci/mctp/endpoint/src/main.c b/samples/subsys/pmci/mctp/endpoint/src/main.c index 6eaa0a67193f..5b8f47b43fe0 100644 --- a/samples/subsys/pmci/mctp/endpoint/src/main.c +++ b/samples/subsys/pmci/mctp/endpoint/src/main.c @@ -7,7 +7,6 @@ #include #include #include -#include #include #include #include diff --git a/samples/subsys/pmci/mctp/host/src/main.c b/samples/subsys/pmci/mctp/host/src/main.c index 7b9e5112c177..7345e584aab7 100644 --- a/samples/subsys/pmci/mctp/host/src/main.c +++ b/samples/subsys/pmci/mctp/host/src/main.c @@ -7,7 +7,6 @@ #include #include #include -#include #include #include #include diff --git a/samples/subsys/pmci/mctp/i2c_gpio_bus_endpoint/src/main.c b/samples/subsys/pmci/mctp/i2c_gpio_bus_endpoint/src/main.c index 6e7263095750..8fa84cb93fe5 100644 --- a/samples/subsys/pmci/mctp/i2c_gpio_bus_endpoint/src/main.c +++ b/samples/subsys/pmci/mctp/i2c_gpio_bus_endpoint/src/main.c @@ -7,7 +7,6 @@ #include #include #include -#include #include #include #include diff --git a/samples/subsys/pmci/mctp/i2c_gpio_bus_owner/src/main.c b/samples/subsys/pmci/mctp/i2c_gpio_bus_owner/src/main.c index 737819fc3bb1..1280773563af 100644 --- a/samples/subsys/pmci/mctp/i2c_gpio_bus_owner/src/main.c +++ b/samples/subsys/pmci/mctp/i2c_gpio_bus_owner/src/main.c @@ -7,7 +7,6 @@ #include #include #include -#include #include #include #include diff --git a/samples/subsys/pmci/mctp/usb_endpoint/src/main.c b/samples/subsys/pmci/mctp/usb_endpoint/src/main.c index 178fbce47ffd..6ab511c91aa2 100644 --- a/samples/subsys/pmci/mctp/usb_endpoint/src/main.c +++ b/samples/subsys/pmci/mctp/usb_endpoint/src/main.c @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include From b78d150e47d65ba0f78a8d3d803b90415c047d1f Mon Sep 17 00:00:00 2001 From: Lucien Zhao Date: Tue, 9 Dec 2025 11:43:06 +0800 Subject: [PATCH 0181/3659] dts: arm: nxp: rt700_cpu0: add uuid support SYSCON0 IP can be accessed by CPU0, HiFi4, EZH-V, eDMA0, eDMA1. So cm33_cpu1 can't be supported this feature. Signed-off-by: Lucien Zhao --- dts/arm/nxp/nxp_rt7xx_cm33_cpu0.dtsi | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/dts/arm/nxp/nxp_rt7xx_cm33_cpu0.dtsi b/dts/arm/nxp/nxp_rt7xx_cm33_cpu0.dtsi index 8d76256743d1..c42a7dc4c518 100644 --- a/dts/arm/nxp/nxp_rt7xx_cm33_cpu0.dtsi +++ b/dts/arm/nxp/nxp_rt7xx_cm33_cpu0.dtsi @@ -1122,6 +1122,11 @@ compatible = "nxp,pmc-tmpsns"; status = "disabled"; }; + + uuid: uuid@2bc0 { + compatible = "nxp,lpc-uid"; + reg = <0x2bc0 0x10>; + }; }; &xspi0 { From 89ae7bb8e84bb52092470275c9733e18bc33c4ee Mon Sep 17 00:00:00 2001 From: Firas Sammoura Date: Tue, 9 Dec 2025 01:32:39 +0000 Subject: [PATCH 0182/3659] arch: riscv: pmp: Remove header guards and add kconfig deps Remove the CONFIG_RISCV_PMP #ifdef guards from the function declarations in pmp.h. This allows the header to be included unconditionally, while the function definitions remain conditional on the Kconfig option. Add @kconfig_dep to the Doxygen comments for all functions to clearly indicate the dependency on CONFIG_RISCV_PMP. Signed-off-by: Firas Sammoura --- include/zephyr/arch/riscv/pmp.h | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/include/zephyr/arch/riscv/pmp.h b/include/zephyr/arch/riscv/pmp.h index e53b0732df75..df8debf8c109 100644 --- a/include/zephyr/arch/riscv/pmp.h +++ b/include/zephyr/arch/riscv/pmp.h @@ -7,9 +7,7 @@ #ifndef ZEPHYR_INCLUDE_RISCV_PMP_H_ #define ZEPHYR_INCLUDE_RISCV_PMP_H_ - #include - -#ifdef CONFIG_RISCV_PMP +#include /** * @brief Change the memory protection (R/W/X) permissions for a defined region. @@ -26,6 +24,7 @@ * committed to the PMP configuration registers. * * @kconfig_dep{CONFIG_MEM_ATTR} + * @kconfig_dep{CONFIG_RISCV_PMP} * * @param region_idx Index of the memory attribute region (from * mem_attr_get_regions) whose permissions should be changed. @@ -40,6 +39,8 @@ int z_riscv_pmp_change_permissions(size_t region_idx, uint8_t perm); /** * @brief Resets all unlocked PMP entries to OFF mode (Null Region). * + * @kconfig_dep{CONFIG_RISCV_PMP} + * * This function is used to securely clear the PMP configuration. It first * ensures the execution context is M-mode by setting MSTATUS_MPRV=0 and * MSTATUS_MPP=M-mode. It then reads all pmpcfgX CSRs, iterates through @@ -48,6 +49,4 @@ int z_riscv_pmp_change_permissions(size_t region_idx, uint8_t perm); */ void z_riscv_pmp_clear_all(void); -#endif - #endif /* ZEPHYR_INCLUDE_RISCV_PMP_H_ */ From 76410eef68a3442b7cbab520cf2991126b6a2467 Mon Sep 17 00:00:00 2001 From: Alain Volmat Date: Tue, 2 Dec 2025 10:29:19 +0100 Subject: [PATCH 0183/3659] soc: stm32n6x: addition of RIF configuration at soc init Perform all the IPs RIF configuration at init time in case of this isn't yet performed by an earlier entity during the boot sequence. This configuration depends on TRUSTED_EXECUTION_SECURE which is currently always enabled on STM32N6x but will be configurable in future. Signed-off-by: Alain Volmat --- soc/st/stm32/stm32n6x/Kconfig | 11 ++++++++- soc/st/stm32/stm32n6x/soc.c | 45 +++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/soc/st/stm32/stm32n6x/Kconfig b/soc/st/stm32/stm32n6x/Kconfig index 53e763bd3826..e3aba615e544 100644 --- a/soc/st/stm32/stm32n6x/Kconfig +++ b/soc/st/stm32/stm32n6x/Kconfig @@ -23,6 +23,7 @@ config SOC_SERIES_STM32N6X # MPU_GAP_FILLING is default when !USERSPACE, select it in the other case as well. select MPU_GAP_FILLING if USERSPACE select CPU_HAS_CUSTOM_FIXED_SOC_MPU_REGIONS if USERSPACE && !XIP + select USE_STM32_HAL_RIF if STM32N6_RIF_OPEN if SOC_SERIES_STM32N6X @@ -31,9 +32,17 @@ config STM32N6_BOOT_SERIAL config STM32N6_NPU bool "Neural-ART accelerator (NPU)" - select USE_STM32_HAL_RIF select RESET default y depends on DT_HAS_ST_STM32_NPU_ENABLED +config STM32N6_RIF_OPEN + bool "Configure the RIF with all OPEN access" + default y + depends on TRUSTED_EXECUTION_SECURE + help + When this option is enabled, the RIMC of all masters and the RISC of all slaves are + configured during SoC initialization. Zephyr running with Secure privileges has full + access to all SoC resources. + endif # SOC_SERIES_STM32N6X diff --git a/soc/st/stm32/stm32n6x/soc.c b/soc/st/stm32/stm32n6x/soc.c index d3bae6eeff81..49f5417f1d24 100644 --- a/soc/st/stm32/stm32n6x/soc.c +++ b/soc/st/stm32/stm32n6x/soc.c @@ -34,6 +34,46 @@ void soc_reset_hook(void) } #endif +#define RIF_MASTER_CID1_SEC_PRIV(device) \ + do { \ + RIMC_MasterConfig_t rimc = { \ + .MasterCID = RIF_CID_1, \ + .SecPriv = RIF_ATTRIBUTE_SEC | RIF_ATTRIBUTE_PRIV, \ + }; \ + HAL_RIF_RIMC_ConfigMasterAttributes(RIF_MASTER_INDEX_##device, &rimc); \ + } while (0) + +#define RIF_SLAVE_SEC_PRIV(device) \ + HAL_RIF_RISC_SetSlaveSecureAttributes(RIF_RISC_PERIPH_INDEX_##device, \ + RIF_ATTRIBUTE_SEC | RIF_ATTRIBUTE_PRIV) + +static void soc_rif_config(void) +{ + /* Enable the clock for the RIFSC (RIF Security Controller) */ + __HAL_RCC_RIFSC_CLK_ENABLE(); + + /* DCMIPP */ + RIF_MASTER_CID1_SEC_PRIV(DCMIPP); + RIF_SLAVE_SEC_PRIV(DCMIPP); + /* DMA2D */ + RIF_MASTER_CID1_SEC_PRIV(DMA2D); + RIF_SLAVE_SEC_PRIV(DMA2D); + /* ETH */ + RIF_MASTER_CID1_SEC_PRIV(ETH1); + RIF_SLAVE_SEC_PRIV(ETH1); + /* JPEG */ + RIF_SLAVE_SEC_PRIV(JPEG); + /* LTDC Layer 1 */ + RIF_MASTER_CID1_SEC_PRIV(LTDC1); + RIF_SLAVE_SEC_PRIV(LTDCL1); + /* NPU */ + RIF_MASTER_CID1_SEC_PRIV(NPU); + RIF_SLAVE_SEC_PRIV(NPU); + /* VENC */ + RIF_MASTER_CID1_SEC_PRIV(VENC); + RIF_SLAVE_SEC_PRIV(VENC); +} + /** * @brief Perform basic hardware initialization at boot. * @@ -66,4 +106,9 @@ void soc_early_init_hook(void) /* Set Vdd IO2 and IO3 to 1.8V */ LL_PWR_SetVddIO2VoltageRange(LL_PWR_VDDIO_VOLTAGE_RANGE_1V8); LL_PWR_SetVddIO3VoltageRange(LL_PWR_VDDIO_VOLTAGE_RANGE_1V8); + + /* RIF configuration */ + if (IS_ENABLED(CONFIG_STM32N6_RIF_OPEN)) { + soc_rif_config(); + } } From d671e3f675b9549aee2e09774c213c0452b2be0f Mon Sep 17 00:00:00 2001 From: Alain Volmat Date: Tue, 2 Dec 2025 10:31:44 +0100 Subject: [PATCH 0184/3659] drivers: stm32: remove all HAL_RIF_ calls from stm32 drivers RIF configuration is now done at soc init time in a centralized way so it is no more necessary for drivers to perform this configuration. Signed-off-by: Alain Volmat --- drivers/display/Kconfig.stm32_ltdc | 1 - drivers/display/display_stm32_ltdc.c | 12 ---------- drivers/ethernet/Kconfig.stm32_hal | 1 - drivers/ethernet/eth_stm32_hal_common.c | 31 ------------------------- drivers/video/Kconfig.stm32_dcmipp | 1 - drivers/video/Kconfig.stm32_jpeg | 1 - drivers/video/Kconfig.stm32_venc | 1 - drivers/video/video_stm32_dcmipp.c | 12 ---------- drivers/video/video_stm32_jpeg.c | 5 ---- drivers/video/video_stm32_venc.c | 21 ----------------- soc/st/stm32/stm32n6x/npu/npu_stm32n6.c | 13 ----------- 11 files changed, 99 deletions(-) diff --git a/drivers/display/Kconfig.stm32_ltdc b/drivers/display/Kconfig.stm32_ltdc index 62e46b0a3cc9..56c9baef7b82 100644 --- a/drivers/display/Kconfig.stm32_ltdc +++ b/drivers/display/Kconfig.stm32_ltdc @@ -8,7 +8,6 @@ menuconfig STM32_LTDC default y depends on DT_HAS_ST_STM32_LTDC_ENABLED select USE_STM32_HAL_LTDC - select USE_STM32_HAL_RIF if SOC_SERIES_STM32N6X select CACHE_MANAGEMENT if CPU_HAS_DCACHE select PINCTRL select RESET diff --git a/drivers/display/display_stm32_ltdc.c b/drivers/display/display_stm32_ltdc.c index da4c26ab8b96..92b2a4271d4b 100644 --- a/drivers/display/display_stm32_ltdc.c +++ b/drivers/display/display_stm32_ltdc.c @@ -357,9 +357,6 @@ static int stm32_ltdc_init(const struct device *dev) int err; const struct display_stm32_ltdc_config *config = dev->config; struct display_stm32_ltdc_data *data = dev->data; -#if defined(CONFIG_SOC_SERIES_STM32N6X) - RIMC_MasterConfig_t rimc = {0}; -#endif /* Configure and set display on/off GPIO */ if (config->disp_on_gpio.port) { @@ -459,15 +456,6 @@ static int stm32_ltdc_init(const struct device *dev) return err; } -#if defined(CONFIG_SOC_SERIES_STM32N6X) - /* Configure RIF for LTDC layer 1 */ - rimc.MasterCID = RIF_CID_1; - rimc.SecPriv = RIF_ATTRIBUTE_SEC | RIF_ATTRIBUTE_PRIV; - HAL_RIF_RIMC_ConfigMasterAttributes(RIF_MASTER_INDEX_LTDC1, &rimc); - HAL_RIF_RISC_SetSlaveSecureAttributes(RIF_RISC_PERIPH_INDEX_LTDCL1, - RIF_ATTRIBUTE_SEC | RIF_ATTRIBUTE_PRIV); -#endif - /* Disable layer 2, since it not used */ __HAL_LTDC_LAYER_DISABLE(&data->hltdc, LTDC_LAYER_2); diff --git a/drivers/ethernet/Kconfig.stm32_hal b/drivers/ethernet/Kconfig.stm32_hal index 464d480771cd..00100dc5f0b6 100644 --- a/drivers/ethernet/Kconfig.stm32_hal +++ b/drivers/ethernet/Kconfig.stm32_hal @@ -9,7 +9,6 @@ menuconfig ETH_STM32_HAL default y depends on DT_HAS_ST_STM32_ETHERNET_ENABLED select USE_STM32_HAL_ETH - select USE_STM32_HAL_RIF if SOC_SERIES_STM32N6X select NOCACHE_MEMORY if (SOC_SERIES_STM32H7X && CPU_CORTEX_M7) || SOC_SERIES_STM32N6X select HWINFO select ETH_DSA_SUPPORT_DEPRECATED diff --git a/drivers/ethernet/eth_stm32_hal_common.c b/drivers/ethernet/eth_stm32_hal_common.c index 0373e8b81007..e30e7fbaf506 100644 --- a/drivers/ethernet/eth_stm32_hal_common.c +++ b/drivers/ethernet/eth_stm32_hal_common.c @@ -140,32 +140,6 @@ static void generate_mac(uint8_t *mac_addr) #endif } -#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32n6_ethernet) -/** - * Configures the RISAF (RIF Security Attribute Framework) for Ethernet on STM32N6. - * This function sets up the master and slave security attributes for the Ethernet peripheral. - */ - -static void RISAF_Config(void) -{ - /* Define and initialize the master configuration structure */ - RIMC_MasterConfig_t RIMC_master = {0}; - - /* Enable the clock for the RIFSC (RIF Security Controller) */ - __HAL_RCC_RIFSC_CLK_ENABLE(); - - RIMC_master.MasterCID = RIF_CID_1; - RIMC_master.SecPriv = RIF_ATTRIBUTE_SEC | RIF_ATTRIBUTE_PRIV; - - /* Configure the master attributes for the Ethernet peripheral (ETH1) */ - HAL_RIF_RIMC_ConfigMasterAttributes(RIF_MASTER_INDEX_ETH1, &RIMC_master); - - /* Set the secure and privileged attributes for the Ethernet peripheral (ETH1) as a slave */ - HAL_RIF_RISC_SetSlaveSecureAttributes(RIF_RISC_PERIPH_INDEX_ETH1, - RIF_ATTRIBUTE_SEC | RIF_ATTRIBUTE_PRIV); -} -#endif - static int eth_initialize(const struct device *dev) { struct eth_stm32_hal_dev_data *dev_data = dev->data; @@ -178,11 +152,6 @@ static int eth_initialize(const struct device *dev) return -ENODEV; } -#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32n6_ethernet) - /* RISAF Configuration */ - RISAF_Config(); -#endif - /* enable clock */ ret = clock_control_on(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE), (clock_control_subsys_t)&cfg->pclken); diff --git a/drivers/video/Kconfig.stm32_dcmipp b/drivers/video/Kconfig.stm32_dcmipp index 728db10a284a..b7f34e48d9be 100644 --- a/drivers/video/Kconfig.stm32_dcmipp +++ b/drivers/video/Kconfig.stm32_dcmipp @@ -8,7 +8,6 @@ config VIDEO_STM32_DCMIPP default y depends on DT_HAS_ST_STM32_DCMIPP_ENABLED select USE_STM32_HAL_DCMIPP - select USE_STM32_HAL_RIF if SOC_SERIES_STM32N6X select RESET select PINCTRL help diff --git a/drivers/video/Kconfig.stm32_jpeg b/drivers/video/Kconfig.stm32_jpeg index 498f20163993..0a0900ae40e4 100644 --- a/drivers/video/Kconfig.stm32_jpeg +++ b/drivers/video/Kconfig.stm32_jpeg @@ -12,6 +12,5 @@ config VIDEO_STM32_JPEG select USE_STM32_HAL_JPEG select USE_STM32_HAL_DMA select USE_STM32_HAL_DMA_EX - select USE_STM32_HAL_RIF if SOC_SERIES_STM32N6X help Enable driver for STM32 JPEG HW Codec peripheral diff --git a/drivers/video/Kconfig.stm32_venc b/drivers/video/Kconfig.stm32_venc index 9c018c97ac28..e55c7c41db7c 100644 --- a/drivers/video/Kconfig.stm32_venc +++ b/drivers/video/Kconfig.stm32_venc @@ -10,7 +10,6 @@ config VIDEO_STM32_VENC depends on VIDEO_ENCODER_H264 select HAS_STM32LIB select USE_STM32_LL_VENC - select USE_STM32_HAL_RIF if SOC_SERIES_STM32N6X select RESET help Enable driver for STM32 video encoder peripheral. diff --git a/drivers/video/video_stm32_dcmipp.c b/drivers/video/video_stm32_dcmipp.c index 71915e4144f5..650532acb136 100644 --- a/drivers/video/video_stm32_dcmipp.c +++ b/drivers/video/video_stm32_dcmipp.c @@ -1694,10 +1694,6 @@ static int stm32_dcmipp_init(const struct device *dev) int err; -#if defined(CONFIG_SOC_SERIES_STM32N6X) - RIMC_MasterConfig_t rimc = {0}; -#endif - dcmipp->enabled_pipe = 0; #if defined(STM32_DCMIPP_HAS_PIXEL_PIPES) @@ -1736,14 +1732,6 @@ static int stm32_dcmipp_init(const struct device *dev) /* Run IRQ init */ cfg->irq_config(dev); -#if defined(CONFIG_SOC_SERIES_STM32N6X) - rimc.MasterCID = RIF_CID_1; - rimc.SecPriv = RIF_ATTRIBUTE_SEC | RIF_ATTRIBUTE_PRIV; - HAL_RIF_RIMC_ConfigMasterAttributes(RIF_MASTER_INDEX_DCMIPP, &rimc); - HAL_RIF_RISC_SetSlaveSecureAttributes(RIF_RISC_PERIPH_INDEX_DCMIPP, - RIF_ATTRIBUTE_SEC | RIF_ATTRIBUTE_PRIV); -#endif - /* Initialize DCMI peripheral */ err = HAL_DCMIPP_Init(&dcmipp->hdcmipp); if (err != HAL_OK) { diff --git a/drivers/video/video_stm32_jpeg.c b/drivers/video/video_stm32_jpeg.c index d19281fcf300..b7b092830667 100644 --- a/drivers/video/video_stm32_jpeg.c +++ b/drivers/video/video_stm32_jpeg.c @@ -521,11 +521,6 @@ static int stm32_jpeg_init(const struct device *dev) /* Run IRQ init */ cfg->irq_config(dev); -#if defined(CONFIG_SOC_SERIES_STM32N6X) - HAL_RIF_RISC_SetSlaveSecureAttributes(RIF_RISC_PERIPH_INDEX_JPEG, - RIF_ATTRIBUTE_PRIV | RIF_ATTRIBUTE_SEC); -#endif - /* Initialise default input / output formats */ k_mutex_init(&data->lock); k_fifo_init(&data->m2m.in.fifo_in); diff --git a/drivers/video/video_stm32_venc.c b/drivers/video/video_stm32_venc.c index 1317db308e6e..34ca31263a4b 100644 --- a/drivers/video/video_stm32_venc.c +++ b/drivers/video/video_stm32_venc.c @@ -841,25 +841,6 @@ static const struct stm32_venc_config stm32_venc_config_0 = { .irq_config = stm32_venc_irq_config_func, }; -static void risaf_config(void) -{ - /* Define and initialize the master configuration structure */ - RIMC_MasterConfig_t rimc_master = {0}; - - /* Enable the clock for the RIFSC (RIF Security Controller) */ - __HAL_RCC_RIFSC_CLK_ENABLE(); - - rimc_master.MasterCID = RIF_CID_1; - rimc_master.SecPriv = RIF_ATTRIBUTE_SEC | RIF_ATTRIBUTE_PRIV; - - /* Configure the master attributes for the video encoder peripheral (VENC) */ - HAL_RIF_RIMC_ConfigMasterAttributes(RIF_MASTER_INDEX_VENC, &rimc_master); - - /* Set the secure and privileged attributes for the VENC as a slave */ - HAL_RIF_RISC_SetSlaveSecureAttributes(RIF_RISC_PERIPH_INDEX_VENC, - RIF_ATTRIBUTE_SEC | RIF_ATTRIBUTE_PRIV); -} - static int stm32_venc_init(const struct device *dev) { const struct stm32_venc_config *config = dev->config; @@ -890,8 +871,6 @@ static int stm32_venc_init(const struct device *dev) /* Run IRQ init */ config->irq_config(dev); - risaf_config(); - LOG_DBG("CPU frequency : %d", HAL_RCC_GetCpuClockFreq() / 1000000); LOG_DBG("sysclk frequency : %d", HAL_RCC_GetSysClockFreq() / 1000000); LOG_DBG("pclk5 frequency : %d", HAL_RCC_GetPCLK5Freq() / 1000000); diff --git a/soc/st/stm32/stm32n6x/npu/npu_stm32n6.c b/soc/st/stm32/stm32n6x/npu/npu_stm32n6.c index 191929503c50..4c437281aedc 100644 --- a/soc/st/stm32/stm32n6x/npu/npu_stm32n6.c +++ b/soc/st/stm32/stm32n6x/npu/npu_stm32n6.c @@ -25,17 +25,6 @@ struct npu_stm32_cfg { const struct reset_dt_spec reset_cacheaxi; }; -static void npu_risaf_config(void) -{ - RIMC_MasterConfig_t RIMC_master = {0}; - - RIMC_master.MasterCID = RIF_CID_1; - RIMC_master.SecPriv = RIF_ATTRIBUTE_SEC | RIF_ATTRIBUTE_PRIV; - HAL_RIF_RIMC_ConfigMasterAttributes(RIF_MASTER_INDEX_NPU, &RIMC_master); - HAL_RIF_RISC_SetSlaveSecureAttributes(RIF_RISC_PERIPH_INDEX_NPU, - RIF_ATTRIBUTE_SEC | RIF_ATTRIBUTE_PRIV); -} - static int npu_stm32_init(const struct device *dev) { const struct device *const clk = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE); @@ -61,8 +50,6 @@ static int npu_stm32_init(const struct device *dev) (void)reset_line_toggle_dt(&cfg->reset_npu); (void)reset_line_toggle_dt(&cfg->reset_cacheaxi); - npu_risaf_config(); - return 0; } From bd500cb1f9713c85350feab50dd1c21189d20244 Mon Sep 17 00:00:00 2001 From: Zhaoxiang Jin Date: Sun, 30 Nov 2025 11:55:03 +0800 Subject: [PATCH 0185/3659] boards: nxp: remove unused definitions 1. Remove 'XIP_BOOT_HEADER_ENABLE', it is not used in the mcxn947 build tree. 2. Remove 'BOARD_FLASH_SIZE', it is not used in the rw612 build tree. Signed-off-by: Zhaoxiang Jin --- boards/nxp/frdm_mcxn947/CMakeLists.txt | 1 - boards/nxp/frdm_rw612/CMakeLists.txt | 1 - boards/nxp/mcx_nx4x_evk/CMakeLists.txt | 1 - boards/nxp/rd_rw612_bga/CMakeLists.txt | 1 - 4 files changed, 4 deletions(-) diff --git a/boards/nxp/frdm_mcxn947/CMakeLists.txt b/boards/nxp/frdm_mcxn947/CMakeLists.txt index d12527c90b1e..def454d5950d 100644 --- a/boards/nxp/frdm_mcxn947/CMakeLists.txt +++ b/boards/nxp/frdm_mcxn947/CMakeLists.txt @@ -9,7 +9,6 @@ zephyr_library_sources(board.c) if(CONFIG_FLEXSPI_CONFIG_BLOCK_OFFSET) # Include flash configuration block - zephyr_compile_definitions(XIP_BOOT_HEADER_ENABLE=1) zephyr_library_sources(xip/mcxn_flexspi_nor_config.c) zephyr_library_include_directories(xip) endif() diff --git a/boards/nxp/frdm_rw612/CMakeLists.txt b/boards/nxp/frdm_rw612/CMakeLists.txt index 441e31cdcdd1..cd5c71177429 100644 --- a/boards/nxp/frdm_rw612/CMakeLists.txt +++ b/boards/nxp/frdm_rw612/CMakeLists.txt @@ -10,7 +10,6 @@ dt_nodelabel(xtal32 NODELABEL "xtal32") dt_node_has_status(xtal32_status PATH ${xtal32} STATUS okay) if(CONFIG_NXP_RW6XX_BOOT_HEADER) - zephyr_compile_definitions(BOARD_FLASH_SIZE=CONFIG_FLASH_SIZE*1024) # This FCB is specific to the flash on this board, it won't work # for boards with different flash chips. If you flash this FCB # onto a board with a different flash chip you may break it. diff --git a/boards/nxp/mcx_nx4x_evk/CMakeLists.txt b/boards/nxp/mcx_nx4x_evk/CMakeLists.txt index d12527c90b1e..def454d5950d 100644 --- a/boards/nxp/mcx_nx4x_evk/CMakeLists.txt +++ b/boards/nxp/mcx_nx4x_evk/CMakeLists.txt @@ -9,7 +9,6 @@ zephyr_library_sources(board.c) if(CONFIG_FLEXSPI_CONFIG_BLOCK_OFFSET) # Include flash configuration block - zephyr_compile_definitions(XIP_BOOT_HEADER_ENABLE=1) zephyr_library_sources(xip/mcxn_flexspi_nor_config.c) zephyr_library_include_directories(xip) endif() diff --git a/boards/nxp/rd_rw612_bga/CMakeLists.txt b/boards/nxp/rd_rw612_bga/CMakeLists.txt index 246474cdd68e..f58318a19891 100644 --- a/boards/nxp/rd_rw612_bga/CMakeLists.txt +++ b/boards/nxp/rd_rw612_bga/CMakeLists.txt @@ -16,7 +16,6 @@ if(CONFIG_NXP_RW6XX_BOOT_HEADER) "update your flash configuration block data") endif() zephyr_compile_definitions(BOOT_HEADER_ENABLE=1) - zephyr_compile_definitions(BOARD_FLASH_SIZE=CONFIG_FLASH_SIZE*1024) zephyr_library_sources(MX25U51245GZ4I00_FCB.c) endif() From 75a2b1e35cb9b74a869624d193a036e55e3708f6 Mon Sep 17 00:00:00 2001 From: Andrej Butok Date: Fri, 5 Dec 2025 15:07:06 +0100 Subject: [PATCH 0186/3659] drivers: gpio: nxp: mcux_igpio: fix mcux_igpio_port_get_raw() - Reads the Pad Status Register (PSR) to get the current GPIO input value, instead of the Data Register (DR). Following IMXRT1170RM.pdf "13.5.2 GPIO Write Mode". - Enables input buffer via Software Input On (SION) to get correct pin value in PSR for both input/output pins. - Issue has been discovered during Safety DIO self-tests. Signed-off-by: Andrej Butok --- drivers/gpio/gpio_mcux_igpio.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/gpio/gpio_mcux_igpio.c b/drivers/gpio/gpio_mcux_igpio.c index df140eb55c36..f55df0746ae8 100644 --- a/drivers/gpio/gpio_mcux_igpio.c +++ b/drivers/gpio/gpio_mcux_igpio.c @@ -200,6 +200,9 @@ static int mcux_igpio_configure(const struct device *dev, } #endif /* CONFIG_SOC_SERIES_IMXRT10XX */ + /* Enable input buffer via Software Input On (SION). */ + reg |= 0x1 << MCUX_IMX_INPUT_ENABLE_SHIFT; + memcpy(&pin_cfg.pinmux, &config->pin_muxes[cfg_idx], sizeof(pin_cfg.pinmux)); /* cfg register will be set by pinctrl_configure_pins */ pin_cfg.pin_ctrl_flags = reg; @@ -226,7 +229,8 @@ static int mcux_igpio_port_get_raw(const struct device *dev, uint32_t *value) { GPIO_Type *base = get_base(dev); - *value = base->DR; + /* Read the Pad Status Register to get current input value */ + *value = base->PSR; return 0; } From a84e0b5413233c74d3294d979030da403f9c5e49 Mon Sep 17 00:00:00 2001 From: Missael Maciel Date: Thu, 27 Nov 2025 16:24:03 -0600 Subject: [PATCH 0187/3659] drivers: uart: save interrupts in PM Action The PM action saves the interrupts enabled using a global variable called usart_intenset. The problem is when you have multiple uart instances that have different configurations, when entering/exiting from a power level, only one configuration is saved and will be applied to all uart instances when exiting from a power level. We need to keep this setting individual for each instance. To do this, usart_intenset was added as a new element to mcux_flexcomm_data structure. In this way, each uart instance will keep/restore each own setting. Signed-off-by: Missael Maciel --- drivers/serial/uart_mcux_flexcomm.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/serial/uart_mcux_flexcomm.c b/drivers/serial/uart_mcux_flexcomm.c index f0cae8ee912e..12ca54418aaa 100644 --- a/drivers/serial/uart_mcux_flexcomm.c +++ b/drivers/serial/uart_mcux_flexcomm.c @@ -89,6 +89,7 @@ struct mcux_flexcomm_data { #ifdef CONFIG_UART_INTERRUPT_DRIVEN uart_irq_callback_user_data_t irq_callback; void *irq_cb_data; + uint32_t usart_intenset; #endif #ifdef CONFIG_UART_ASYNC_API uart_callback_t async_callback; @@ -1205,10 +1206,12 @@ static void mcux_flexcomm_pm_restore_wake(const struct device *dev, } #endif /* FC_UART_IS_WAKEUP */ -static uint32_t usart_intenset; static int mcux_flexcomm_pm_action(const struct device *dev, enum pm_device_action action) { +#ifdef CONFIG_UART_INTERRUPT_DRIVEN const struct mcux_flexcomm_config *config = dev->config; + struct mcux_flexcomm_data *data = dev->data; +#endif int ret; switch (action) { @@ -1217,14 +1220,18 @@ static int mcux_flexcomm_pm_action(const struct device *dev, enum pm_device_acti case PM_DEVICE_ACTION_SUSPEND: break; case PM_DEVICE_ACTION_TURN_OFF: - usart_intenset = USART_GetEnabledInterrupts(config->base); +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + data->usart_intenset = USART_GetEnabledInterrupts(config->base); +#endif break; case PM_DEVICE_ACTION_TURN_ON: ret = mcux_flexcomm_init_common(dev); if (ret) { return ret; } - USART_EnableInterrupts(config->base, usart_intenset); +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + USART_EnableInterrupts(config->base, data->usart_intenset); +#endif break; default: return -ENOTSUP; From 726e7b64c24f2fa559f591ed7cbcfcf8372194d0 Mon Sep 17 00:00:00 2001 From: Missael Maciel Date: Tue, 2 Dec 2025 14:27:03 -0600 Subject: [PATCH 0188/3659] drivers: uart: save interrupts in PM Action Removed usart_intenset attribute from conditional compilation in mcux_flexcomm_data structure since this parameter needs to be saved/restored independently if the interrupts are enabled or not based on the PR feedback Signed-off-by: Missael Maciel --- drivers/serial/uart_mcux_flexcomm.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/serial/uart_mcux_flexcomm.c b/drivers/serial/uart_mcux_flexcomm.c index 12ca54418aaa..d76ea3377837 100644 --- a/drivers/serial/uart_mcux_flexcomm.c +++ b/drivers/serial/uart_mcux_flexcomm.c @@ -89,7 +89,6 @@ struct mcux_flexcomm_data { #ifdef CONFIG_UART_INTERRUPT_DRIVEN uart_irq_callback_user_data_t irq_callback; void *irq_cb_data; - uint32_t usart_intenset; #endif #ifdef CONFIG_UART_ASYNC_API uart_callback_t async_callback; @@ -109,6 +108,7 @@ struct mcux_flexcomm_data { bool pm_policy_state_lock; struct k_work pm_lock_work; #endif + uint32_t usart_intenset; }; #ifdef CONFIG_PM_POLICY_DEVICE_CONSTRAINTS @@ -1208,10 +1208,8 @@ static void mcux_flexcomm_pm_restore_wake(const struct device *dev, static int mcux_flexcomm_pm_action(const struct device *dev, enum pm_device_action action) { -#ifdef CONFIG_UART_INTERRUPT_DRIVEN const struct mcux_flexcomm_config *config = dev->config; struct mcux_flexcomm_data *data = dev->data; -#endif int ret; switch (action) { @@ -1220,18 +1218,14 @@ static int mcux_flexcomm_pm_action(const struct device *dev, enum pm_device_acti case PM_DEVICE_ACTION_SUSPEND: break; case PM_DEVICE_ACTION_TURN_OFF: -#ifdef CONFIG_UART_INTERRUPT_DRIVEN data->usart_intenset = USART_GetEnabledInterrupts(config->base); -#endif break; case PM_DEVICE_ACTION_TURN_ON: ret = mcux_flexcomm_init_common(dev); if (ret) { return ret; } -#ifdef CONFIG_UART_INTERRUPT_DRIVEN USART_EnableInterrupts(config->base, data->usart_intenset); -#endif break; default: return -ENOTSUP; From 5c31987ce2cb3cae4ea60d26fabac4120a284819 Mon Sep 17 00:00:00 2001 From: cyliang tw Date: Thu, 27 Nov 2025 09:33:19 +0800 Subject: [PATCH 0189/3659] dts: arm: nuvoton: add PWM nodes for numaker m333x Update m333x.dtsi to add PWM nodes for PWM driver support. Signed-off-by: cyliang tw --- dts/arm/nuvoton/m333x.dtsi | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/dts/arm/nuvoton/m333x.dtsi b/dts/arm/nuvoton/m333x.dtsi index d171127313d8..2e402421f458 100644 --- a/dts/arm/nuvoton/m333x.dtsi +++ b/dts/arm/nuvoton/m333x.dtsi @@ -339,6 +339,30 @@ status = "disabled"; #io-channel-cells = <1>; }; + + epwm0: epwm@40058000 { + compatible = "nuvoton,numaker-pwm"; + reg = <0x40058000 0x37c>; + interrupts = <25 0>, <26 0>, <27 0>; + interrupt-names = "pair0", "pair1", "pair2"; + resets = <&rst NUMAKER_EPWM0_RST>; + prescaler = <19>; + clocks = <&pcc NUMAKER_EPWM0_MODULE NUMAKER_CLK_CLKSEL2_EPWM0SEL_PCLK0 0>; + #pwm-cells = <3>; + status = "disabled"; + }; + + epwm1: epwm@40059000 { + compatible = "nuvoton,numaker-pwm"; + reg = <0x40059000 0x37c>; + interrupts = <29 0>, <30 0>, <31 0>; + interrupt-names = "pair0", "pair1", "pair2"; + resets = <&rst NUMAKER_EPWM1_RST>; + prescaler = <19>; + clocks = <&pcc NUMAKER_EPWM1_MODULE NUMAKER_CLK_CLKSEL2_EPWM1SEL_PCLK1 0>; + #pwm-cells = <3>; + status = "disabled"; + }; }; }; From 43d1c516af77f43f7eadbcb0a4a95ed09fdf7c8a Mon Sep 17 00:00:00 2001 From: cyliang tw Date: Thu, 27 Nov 2025 09:39:40 +0800 Subject: [PATCH 0190/3659] tests: drivers: pwm: pwm_gpio_loopback: support numaker_m3334ki Add support for Nuvoton numaker board numaker_m3334ki. Signed-off-by: cyliang tw --- .../boards/numaker_m3334ki.overlay | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 tests/drivers/pwm/pwm_gpio_loopback/boards/numaker_m3334ki.overlay diff --git a/tests/drivers/pwm/pwm_gpio_loopback/boards/numaker_m3334ki.overlay b/tests/drivers/pwm/pwm_gpio_loopback/boards/numaker_m3334ki.overlay new file mode 100644 index 000000000000..8e14c89f2f04 --- /dev/null +++ b/tests/drivers/pwm/pwm_gpio_loopback/boards/numaker_m3334ki.overlay @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2025 Nuvoton Technology Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Test requires jumper between: + * - EVB's D3(PC10) -- D5(PC12) + */ + +#include + +/ { + zephyr,user { + pwms = <&epwm1 2 PWM_MSEC(2) PWM_POLARITY_NORMAL>; + gpios = <&gpioc 12 GPIO_ACTIVE_HIGH>; + }; +}; + +&pinctrl { + epwm1_default: epwm1_default { + group0 { + /* EVB's D3 --> PC10 */ + pinmux = ; + }; + }; +}; + +&epwm1 { + status = "okay"; + prescaler = <19>; + pinctrl-0 = <&epwm1_default>; + pinctrl-names = "default"; +}; From 301c0130b2086aedb35eaee565a3fd47de61352e Mon Sep 17 00:00:00 2001 From: Stuart Longland Date: Thu, 9 Oct 2025 12:34:44 +1000 Subject: [PATCH 0191/3659] shell_uart: Stop polling if buffer is full Before calling `uart_poll_in`, check we have space to store the character in the ring buffer beforehand. If we do, *then* poll for the character. That way we don't miss out on serial traffic when our ring buffer is full unless we fill our hardware ring buffer too. Signed-off-by: Stuart Longland --- subsys/shell/backends/shell_uart.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/subsys/shell/backends/shell_uart.c b/subsys/shell/backends/shell_uart.c index a65c2fb16aef..7bcc48580476 100644 --- a/subsys/shell/backends/shell_uart.c +++ b/subsys/shell/backends/shell_uart.c @@ -266,7 +266,8 @@ static void polling_rx_timeout_handler(struct k_timer *timer) uint8_t c; struct shell_uart_polling *sh_uart = k_timer_user_data_get(timer); - while (uart_poll_in(sh_uart->common.dev, &c) == 0) { + while ((ring_buf_space_get(&sh_uart->rx_ringbuf) > 0) && + (uart_poll_in(sh_uart->common.dev, &c) == 0)) { if (ring_buf_put(&sh_uart->rx_ringbuf, &c, 1) == 0U) { /* ring buffer full. */ LOG_WRN("RX ring buffer full."); From b87498212d6ea75f3d4033180b822e102036ce95 Mon Sep 17 00:00:00 2001 From: Stuart Longland Date: Fri, 10 Oct 2025 20:57:13 +1000 Subject: [PATCH 0192/3659] shell_uart: Drop superfluous `if` statement We're now checking if there is space prior to executing the loop body, therefore guaranteeing this condition is never going to fire in a single-threaded context. Signed-off-by: Stuart Longland --- subsys/shell/backends/shell_uart.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/subsys/shell/backends/shell_uart.c b/subsys/shell/backends/shell_uart.c index 7bcc48580476..ddaf1c818cb9 100644 --- a/subsys/shell/backends/shell_uart.c +++ b/subsys/shell/backends/shell_uart.c @@ -268,10 +268,7 @@ static void polling_rx_timeout_handler(struct k_timer *timer) while ((ring_buf_space_get(&sh_uart->rx_ringbuf) > 0) && (uart_poll_in(sh_uart->common.dev, &c) == 0)) { - if (ring_buf_put(&sh_uart->rx_ringbuf, &c, 1) == 0U) { - /* ring buffer full. */ - LOG_WRN("RX ring buffer full."); - } + ring_buf_put(&sh_uart->rx_ringbuf, &c, 1); sh_uart->common.handler(SHELL_TRANSPORT_EVT_RX_RDY, sh_uart->common.context); } } From ed75a0a293174e9f43aff7eafeda103e4d6f5b97 Mon Sep 17 00:00:00 2001 From: Pisit Sawangvonganan Date: Tue, 28 Oct 2025 23:07:48 +0700 Subject: [PATCH 0193/3659] shell: modules: devmem: use `shell_print` where applicable To improve code clarity, use `shell_print` in place of `shell_fprintf` with `SHELL_NORMAL` where appropriate. Signed-off-by: Pisit Sawangvonganan --- subsys/shell/modules/devmem_service.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/subsys/shell/modules/devmem_service.c b/subsys/shell/modules/devmem_service.c index 786642a3367a..434724e0c47c 100644 --- a/subsys/shell/modules/devmem_service.c +++ b/subsys/shell/modules/devmem_service.c @@ -95,7 +95,7 @@ static int memory_dump(const struct shell *sh, mem_addr_t phys_addr, size_t size break; #endif /* CONFIG_64BIT */ default: - shell_fprintf(sh, SHELL_NORMAL, "Incorrect data width\n"); + shell_print(sh, "Incorrect data width"); return -EINVAL; } } @@ -285,13 +285,13 @@ static int memory_read(const struct shell *sh, mem_addr_t addr, uint8_t width) break; #endif /* CONFIG_64BIT */ default: - shell_fprintf(sh, SHELL_NORMAL, "Incorrect data width\n"); + shell_print(sh, "Incorrect data width"); err = -EINVAL; break; } if (err == 0) { - shell_fprintf(sh, SHELL_NORMAL, "Read value 0x%llx\n", value); + shell_print(sh, "Read value 0x%llx", value); } return err; @@ -317,7 +317,7 @@ static int memory_write(const struct shell *sh, mem_addr_t addr, uint8_t width, break; #endif /* CONFIG_64BIT */ default: - shell_fprintf(sh, SHELL_NORMAL, "Incorrect data width\n"); + shell_print(sh, "Incorrect data width"); err = -EINVAL; break; } @@ -348,7 +348,7 @@ static int cmd_devmem(const struct shell *sh, size_t argc, char **argv) width = strtoul(argv[2], NULL, 10); } - shell_fprintf(sh, SHELL_NORMAL, "Using data width %d\n", width); + shell_print(sh, "Using data width %d", width); if (argc <= 3) { return memory_read(sh, addr, width); @@ -360,7 +360,7 @@ static int cmd_devmem(const struct shell *sh, size_t argc, char **argv) value = (uint64_t)strtoull(argv[3], NULL, 16); - shell_fprintf(sh, SHELL_NORMAL, "Writing value 0x%llx\n", value); + shell_print(sh, "Writing value 0x%llx", value); return memory_write(sh, addr, width, value); } From c5365797ac8c4196db2b6ea0048d98f017b3b367 Mon Sep 17 00:00:00 2001 From: Pisit Sawangvonganan Date: Tue, 28 Oct 2025 23:17:03 +0700 Subject: [PATCH 0194/3659] shell: modules: devmem: utilize `sys_put_le(16|32|64)` in `memory_dump` Replaces direct byte shifting and assignment with `sys_put_le16`, `sys_put_le32`, and `sys_put_le64` to simplify the `memory_dump` function. Signed-off-by: Pisit Sawangvonganan --- subsys/shell/modules/devmem_service.c | 28 +++------------------------ 1 file changed, 3 insertions(+), 25 deletions(-) diff --git a/subsys/shell/modules/devmem_service.c b/subsys/shell/modules/devmem_service.c index 434724e0c47c..dd3f1ea41f89 100644 --- a/subsys/shell/modules/devmem_service.c +++ b/subsys/shell/modules/devmem_service.c @@ -60,38 +60,16 @@ static int memory_dump(const struct shell *sh, mem_addr_t phys_addr, size_t size break; case 16: value = sys_le16_to_cpu(sys_read16(addr + data_offset)); - hex_data[data_offset] = (uint8_t)value; - value >>= 8; - hex_data[data_offset + 1] = (uint8_t)value; + sys_put_le16(value, &hex_data[data_offset]); break; case 32: value = sys_le32_to_cpu(sys_read32(addr + data_offset)); - hex_data[data_offset] = (uint8_t)value; - value >>= 8; - hex_data[data_offset + 1] = (uint8_t)value; - value >>= 8; - hex_data[data_offset + 2] = (uint8_t)value; - value >>= 8; - hex_data[data_offset + 3] = (uint8_t)value; + sys_put_le32(value, &hex_data[data_offset]); break; #ifdef CONFIG_64BIT case 64: value = sys_le64_to_cpu(sys_read64(addr + data_offset)); - hex_data[data_offset] = (uint8_t)value; - value >>= 8; - hex_data[data_offset + 1] = (uint8_t)value; - value >>= 8; - hex_data[data_offset + 2] = (uint8_t)value; - value >>= 8; - hex_data[data_offset + 3] = (uint8_t)value; - value >>= 8; - hex_data[data_offset + 4] = (uint8_t)value; - value >>= 8; - hex_data[data_offset + 5] = (uint8_t)value; - value >>= 8; - hex_data[data_offset + 6] = (uint8_t)value; - value >>= 8; - hex_data[data_offset + 7] = (uint8_t)value; + sys_put_le64(value, &hex_data[data_offset]); break; #endif /* CONFIG_64BIT */ default: From 0b52928625b06b6b8de9b56524fbc1ae5f8cbd6a Mon Sep 17 00:00:00 2001 From: Alexandre Rey Date: Wed, 19 Nov 2025 15:15:30 +0100 Subject: [PATCH 0195/3659] driver: spi: mcux_dspi: remove obsolete rx_bufs check The guard against rx_bufs == NULL was originally added to prevent a DMA misconfiguration observed when no RX buffer was provided. The issue can no longer be reproduced, and the check was incomplete since it did not cover rx_bufs->buffers == NULL or rx_bufs->count == 0, which lead to the same effective condition. Removing the check simplifies the driver and avoids blocking valid TX-only transfers. Signed-off-by: Alexandre Rey --- drivers/spi/spi_mcux_dspi.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/spi/spi_mcux_dspi.c b/drivers/spi/spi_mcux_dspi.c index 7cbb6f12b6bf..e5211eaff840 100644 --- a/drivers/spi/spi_mcux_dspi.c +++ b/drivers/spi/spi_mcux_dspi.c @@ -687,13 +687,6 @@ static int transceive(const struct device *dev, SPI_Type *base = config->base; #endif - if (rx_bufs == NULL) { - /* FIXME: for some reason this messes up the DMA configuration - * probably because CITER is 0 and transfer is starting for some reason - */ - return -ENOTSUP; - } - spi_context_lock(&data->ctx, asynchronous, cb, userdata, spi_cfg); ret = spi_mcux_configure(dev, spi_cfg); From 0a5ad3aaa86bdeb33fed91e62b164fe29f59eb9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fin=20Maa=C3=9F?= Date: Wed, 10 Dec 2025 14:07:54 +0100 Subject: [PATCH 0196/3659] drivers: ethernet: remove imply MDIO MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit remove `imply MDIO` from the ethernet drivers, that don't directly use mdio and only use the ethernet phy api, now that the phys select MDIO. in 648c8252b575879c2e926d0b051febf2cb1672d1 the `select MDIO` ones were remove, unfortunatly I forgot the implyed ones. Signed-off-by: Fin Maaß --- drivers/ethernet/Kconfig.litex | 1 - drivers/ethernet/Kconfig.nxp_s32_gmac | 1 - 2 files changed, 2 deletions(-) diff --git a/drivers/ethernet/Kconfig.litex b/drivers/ethernet/Kconfig.litex index 196e4229587f..dde522347f4a 100644 --- a/drivers/ethernet/Kconfig.litex +++ b/drivers/ethernet/Kconfig.litex @@ -5,4 +5,3 @@ config ETH_LITEX_LITEETH bool "LiteX LiteEth Ethernet core driver" default y depends on DT_HAS_LITEX_LITEETH_ENABLED - imply MDIO diff --git a/drivers/ethernet/Kconfig.nxp_s32_gmac b/drivers/ethernet/Kconfig.nxp_s32_gmac index 40dad1b500b2..a1d0f3f7c3d6 100644 --- a/drivers/ethernet/Kconfig.nxp_s32_gmac +++ b/drivers/ethernet/Kconfig.nxp_s32_gmac @@ -7,7 +7,6 @@ menuconfig ETH_NXP_S32_GMAC depends on DT_HAS_NXP_S32_GMAC_ENABLED select NOCACHE_MEMORY if ARCH_HAS_NOCACHE_MEMORY_SUPPORT select PINCTRL - imply MDIO help Enable GMAC/EMAC Ethernet driver for NXP S32 SoCs. From e197198f0ac4ed42f73e34431c79f7bad947d10f Mon Sep 17 00:00:00 2001 From: Cristian Bulacu Date: Tue, 9 Dec 2025 12:34:13 +0200 Subject: [PATCH 0197/3659] openthread: platform: udp: Correct scope_id assignment for ll addresses This commit aims to fix correct scope_id assignment when link local addresses are in use Signed-off-by: Cristian Bulacu --- modules/openthread/platform/udp.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/modules/openthread/platform/udp.c b/modules/openthread/platform/udp.c index ff57161b06fd..0532dea534fd 100644 --- a/modules/openthread/platform/udp.c +++ b/modules/openthread/platform/udp.c @@ -273,10 +273,13 @@ otError otPlatUdpSend(otUdpSocket *aUdpSocket, peer.sin6_port = net_htons(aMessageInfo->mPeerPort); memcpy(&peer.sin6_addr, &aMessageInfo->mPeerAddr, sizeof(otIp6Address)); - if (((aMessageInfo->mPeerAddr.mFields.m8[0] == 0xfe) && - ((aMessageInfo->mPeerAddr.mFields.m8[1] & 0xc0) == 0x80)) && - !aMessageInfo->mIsHostInterface) { - peer.sin6_scope_id = ail_iface_index; + if ((aMessageInfo->mPeerAddr.mFields.m8[0] == 0xfe) && + ((aMessageInfo->mPeerAddr.mFields.m8[1] & 0xc0) == 0x80)) { + if (aMessageInfo->mIsHostInterface) { + peer.sin6_scope_id = ail_iface_index; + } else { + peer.sin6_scope_id = ot_iface_index; + } } msg_hdr.msg_name = &peer; @@ -305,7 +308,8 @@ otError otPlatUdpSend(otUdpSocket *aUdpSocket, cmsg_hdr->cmsg_type = ZSOCK_IPV6_PKTINFO; cmsg_hdr->cmsg_len = NET_CMSG_LEN(sizeof(pktinfo)); - pktinfo.ipi6_ifindex = aMessageInfo->mIsHostInterface ? 0 : ail_iface_index; + pktinfo.ipi6_ifindex = aMessageInfo->mIsHostInterface ? + ail_iface_index : ot_iface_index; memcpy(&pktinfo.ipi6_addr, &aMessageInfo->mSockAddr, sizeof(otIp6Address)); memcpy(NET_CMSG_DATA(cmsg_hdr), &pktinfo, sizeof(pktinfo)); From 510ccd718f8566cdc5a6ccfe5bb914d0d7fa1239 Mon Sep 17 00:00:00 2001 From: Cristian Bulacu Date: Tue, 9 Dec 2025 12:27:19 +0200 Subject: [PATCH 0198/3659] net: ip: net_context: Use sin6_scope_id for link-local IPv6 addresses This commit aims to make use of sin6_scope_id field of net_sockaddr_in6 structure to correctly choose the network interface when destination address in link-local. Signed-off-by: Cristian Bulacu --- subsys/net/ip/net_context.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/subsys/net/ip/net_context.c b/subsys/net/ip/net_context.c index 079d261e2d71..80f468dae5ab 100644 --- a/subsys/net/ip/net_context.c +++ b/subsys/net/ip/net_context.c @@ -944,6 +944,12 @@ int net_context_bind(struct net_context *context, const struct net_sockaddr *add } else { struct net_if_addr *ifaddr; + if (net_ipv6_is_ll_addr(&addr6->sin6_addr)) { + if (iface == NULL) { + iface = net_if_get_by_index(addr6->sin6_scope_id); + } + } + ifaddr = net_if_ipv6_addr_lookup( &addr6->sin6_addr, iface == NULL ? &iface : NULL); @@ -2471,6 +2477,17 @@ static int context_sendto(struct net_context *context, (iface = net_if_get_by_index( context->options.ipv6_mcast_ifindex))); } + + if (net_ipv6_is_ll_addr(&addr6->sin6_addr) && + !net_context_is_bound_to_iface(context) && + COND_CODE_1(CONFIG_NET_IPV6, + (addr6->sin6_scope_id > 0), (false))) { + IF_ENABLED(CONFIG_NET_IPV6, ( + iface = net_if_get_by_index(addr6->sin6_scope_id))); + if (iface != NULL) { + net_context_set_iface(context, iface); + } + } } /* If application has not yet set the destination address From cafe2858102371894813f084273383783895e760 Mon Sep 17 00:00:00 2001 From: Yassine El Aissaoui Date: Tue, 9 Dec 2025 10:49:33 +0100 Subject: [PATCH 0199/3659] modules: hal_nxp: Fix spc module selection on MCXW SoC family Fix wrong condition for spc selection on MCXW family. Signed-off-by: Yassine El Aissaoui --- modules/hal_nxp/mcux/mcux-sdk-ng/drivers/drivers.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/hal_nxp/mcux/mcux-sdk-ng/drivers/drivers.cmake b/modules/hal_nxp/mcux/mcux-sdk-ng/drivers/drivers.cmake index 0b47f42e9c1f..9a4edb9d3603 100644 --- a/modules/hal_nxp/mcux/mcux-sdk-ng/drivers/drivers.cmake +++ b/modules/hal_nxp/mcux/mcux-sdk-ng/drivers/drivers.cmake @@ -191,7 +191,7 @@ if(CONFIG_SOC_FAMILY_MCXN OR CONFIG_SOC_FAMILY_MCXA) set(CONFIG_MCUX_COMPONENT_driver.mcx_spc ON) endif() -if(CONFIG_DT_HAS_NXP_SPC_ENABLED AND SOC_FAMILY_MCXW) +if(CONFIG_DT_HAS_NXP_SPC_ENABLED AND CONFIG_SOC_FAMILY_MCXW) set(CONFIG_MCUX_COMPONENT_driver.spc ON) endif() From 82845973a6c9179b7bf7156f650c7366d862f05a Mon Sep 17 00:00:00 2001 From: Pieter De Gendt Date: Tue, 9 Dec 2025 10:31:54 +0100 Subject: [PATCH 0200/3659] scripts: footprint: size_report: Close ELF file Use the ELFFile context manager to open/close an input file. Signed-off-by: Pieter De Gendt --- scripts/footprint/size_report | 102 +++++++++++++++++----------------- 1 file changed, 52 insertions(+), 50 deletions(-) diff --git a/scripts/footprint/size_report b/scripts/footprint/size_report index 544efd492702..fa3de7ded39a 100755 --- a/scripts/footprint/size_report +++ b/scripts/footprint/size_report @@ -866,56 +866,58 @@ def main(): assert os.path.exists(args.kernel), "{0} does not exist.".format(args.kernel) targets = args.target - elf = ELFFile(open(args.kernel, "rb")) - assert elf.has_dwarf_info(), "ELF file has no DWARF information" - - set_global_machine_arch(elf.get_machine_arch()) - addr_ranges = get_section_ranges(elf) - dwarfinfo = elf.get_dwarf_info() - - symbols = get_symbols(elf, addr_ranges) - for sym in symbols['unassigned'].values(): - for sym_entry in sym: - print(f"WARN: Symbol '{sym_entry['name']}' section '{sym_entry['section']}' " - "is not in RAM or ROM.") - - for t in targets: - if args.json: - jsonout = args.json.replace('{target}', t) - else: - jsonout = os.path.join(args.output, f'{t}.json') - - symbol_dict = symbols[t] - symsize = addr_ranges[f'{t}_total_size'] - ranges = addr_ranges[t] - - if symbol_dict is not None: - processed = {"mapped_symbols": set(), - "mapped_addr": set(), - "unmapped_symbols": set(symbol_dict.keys())} - - do_simple_name_matching(dwarfinfo, symbol_dict, processed) - mark_address_aliases(symbol_dict, processed) - do_address_range_matching(dwarfinfo, symbol_dict, processed) - mark_address_aliases(symbol_dict, processed) - common_path_prefix = find_common_path_prefix(symbol_dict) - set_root_path_for_unmapped_symbols(symbol_dict, ranges, processed) - - if args.verbose: - for sym in processed['unmapped_symbols']: - print("INFO: Unmapped symbol: {0}".format(sym)) - - root = generate_any_tree(symbol_dict, symsize, common_path_prefix) - if not args.quiet: - header = f"{t.upper()} Report" if len(targets) > 1 else None - print_any_tree(root, symsize, args.depth, header) - - exporter = DictExporter(attriter=lambda attrs: [(k.lstrip('_'), v) for k, v in attrs]) - data = dict() - data["symbols"] = exporter.export(root) - data["total_size"] = symsize - with open(jsonout, "w") as fp: - json.dump(data, fp, indent=4) + with ELFFile(open(args.kernel, "rb")) as elf: + assert elf.has_dwarf_info(), "ELF file has no DWARF information" + + set_global_machine_arch(elf.get_machine_arch()) + addr_ranges = get_section_ranges(elf) + dwarfinfo = elf.get_dwarf_info() + + symbols = get_symbols(elf, addr_ranges) + for sym in symbols['unassigned'].values(): + for sym_entry in sym: + print(f"WARN: Symbol '{sym_entry['name']}' section '{sym_entry['section']}' " + "is not in RAM or ROM.") + + for t in targets: + if args.json: + jsonout = args.json.replace('{target}', t) + else: + jsonout = os.path.join(args.output, f'{t}.json') + + symbol_dict = symbols[t] + symsize = addr_ranges[f'{t}_total_size'] + ranges = addr_ranges[t] + + if symbol_dict is not None: + processed = {"mapped_symbols": set(), + "mapped_addr": set(), + "unmapped_symbols": set(symbol_dict.keys())} + + do_simple_name_matching(dwarfinfo, symbol_dict, processed) + mark_address_aliases(symbol_dict, processed) + do_address_range_matching(dwarfinfo, symbol_dict, processed) + mark_address_aliases(symbol_dict, processed) + common_path_prefix = find_common_path_prefix(symbol_dict) + set_root_path_for_unmapped_symbols(symbol_dict, ranges, processed) + + if args.verbose: + for sym in processed['unmapped_symbols']: + print("INFO: Unmapped symbol: {0}".format(sym)) + + root = generate_any_tree(symbol_dict, symsize, common_path_prefix) + if not args.quiet: + header = f"{t.upper()} Report" if len(targets) > 1 else None + print_any_tree(root, symsize, args.depth, header) + + exporter = DictExporter( + attriter=lambda attrs: [(k.lstrip('_'), v) for k, v in attrs] + ) + data = dict() + data["symbols"] = exporter.export(root) + data["total_size"] = symsize + with open(jsonout, "w") as fp: + json.dump(data, fp, indent=4) if __name__ == "__main__": From 2565352d11f926b521ee6ffccc04761e990b518a Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Tue, 9 Dec 2025 10:19:59 +0100 Subject: [PATCH 0201/3659] net: http: server: websocket: Fix truncated string warning on copying WS_MAGIC is a constant string and when calculating lengths for copying we always exclude the NULL terminator. In result, using strncpy() for copying can generate a warning about truncated string, as WS_MAGIC will always be truncated from the NULL terminator. Therefore replace strncpy() with memcpy() as it seems more appropriate for this case. Signed-off-by: Robert Lubos --- subsys/net/lib/http/http_server_ws.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/net/lib/http/http_server_ws.c b/subsys/net/lib/http/http_server_ws.c index 0eee1e020034..6d6c2f702a9f 100644 --- a/subsys/net/lib/http/http_server_ws.c +++ b/subsys/net/lib/http/http_server_ws.c @@ -50,7 +50,7 @@ int handle_http1_to_websocket_upgrade(struct http_client_ctx *client) key_len = strlen(key_accept); olen = MIN(sizeof(key_accept) - 1 - key_len, sizeof(WS_MAGIC) - 1); - strncpy(key_accept + key_len, WS_MAGIC, olen); + memcpy(key_accept + key_len, WS_MAGIC, olen); mbedtls_sha1(key_accept, olen + key_len, accept); From cdb23524c373404a8cd6c825001aff549d21a493 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Stasiak?= Date: Tue, 9 Dec 2025 08:55:57 +0100 Subject: [PATCH 0202/3659] drivers: nrf: remove GPIO HAL inclusion MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since pin retention handling was moved to nrfx, GPIO HAL no longer has to be included in analog drivers. Signed-off-by: Michał Stasiak --- drivers/adc/adc_nrfx_saadc.c | 1 - drivers/comparator/comparator_nrf_comp.c | 1 - drivers/comparator/comparator_nrf_lpcomp.c | 1 - 3 files changed, 3 deletions(-) diff --git a/drivers/adc/adc_nrfx_saadc.c b/drivers/adc/adc_nrfx_saadc.c index f54fd0a1aee8..af29161fc3cb 100644 --- a/drivers/adc/adc_nrfx_saadc.c +++ b/drivers/adc/adc_nrfx_saadc.c @@ -14,7 +14,6 @@ #include #include #include -#include LOG_MODULE_REGISTER(adc_nrfx_saadc, CONFIG_ADC_LOG_LEVEL); diff --git a/drivers/comparator/comparator_nrf_comp.c b/drivers/comparator/comparator_nrf_comp.c index bab02e7b9204..2764d1f0b8cb 100644 --- a/drivers/comparator/comparator_nrf_comp.c +++ b/drivers/comparator/comparator_nrf_comp.c @@ -5,7 +5,6 @@ */ #include -#include #include #include diff --git a/drivers/comparator/comparator_nrf_lpcomp.c b/drivers/comparator/comparator_nrf_lpcomp.c index ec1d10c3dae9..20e19191729c 100644 --- a/drivers/comparator/comparator_nrf_lpcomp.c +++ b/drivers/comparator/comparator_nrf_lpcomp.c @@ -5,7 +5,6 @@ */ #include -#include #include #include From ab0bf3a47f1ee4cb8f8a0384cf0973260cf68d30 Mon Sep 17 00:00:00 2001 From: Firas Sammoura Date: Tue, 9 Dec 2025 01:18:00 +0000 Subject: [PATCH 0203/3659] tests: riscv: pmp: Make permission change tests dynamic The existing PMP permission tests relied on hardcoded region indices (e.g., index 0 or 2). This makes the tests fragile and dependent on the exact memory attribute region setup. This change refactors the tests to dynamically determine region counts and indices based on the output of `mem_attr_get_regions()`: - `test_pmp_change_perm_invalid_permission`: Uses the last valid region index to test invalid permission flags. - `test_pmp_change_perm_invalid_region_index`: Uses the total number of regions as the out-of-bounds index. - `test_successful_permission_change`: Locates the index of the target test region (`dt_regions[0]`) by matching its base address and size. The test now also inverts the X bit of the current permissions to ensure a change is applied and verified. These changes make the tests more robust and less dependent on a specific static configuration. Signed-off-by: Firas Sammoura --- .../riscv/pmp/mem-attr-entries/src/main.c | 46 ++++++++++++++----- 1 file changed, 35 insertions(+), 11 deletions(-) diff --git a/tests/arch/riscv/pmp/mem-attr-entries/src/main.c b/tests/arch/riscv/pmp/mem-attr-entries/src/main.c index d6d2e5f51d66..8f1ba6c09b30 100644 --- a/tests/arch/riscv/pmp/mem-attr-entries/src/main.c +++ b/tests/arch/riscv/pmp/mem-attr-entries/src/main.c @@ -127,33 +127,53 @@ ZTEST(riscv_pmp_memattr_entries, test_dt_pmp_perm_conversion) ZTEST(riscv_pmp_memattr_entries, test_pmp_change_perm_invalid_permission) { + const struct mem_attr_region_t *region; + size_t num_regions = mem_attr_get_regions(®ion); + size_t idx = num_regions - 1; + /* Invalid permission: 0x08 (bit 3) is outside of R|W|X (0x7) mask */ - zassert_equal(z_riscv_pmp_change_permissions(0, 0x08), -EINVAL, + zassert_equal(z_riscv_pmp_change_permissions(idx, 0x08), -EINVAL, "Should return -EINVAL for invalid permission bits."); } ZTEST(riscv_pmp_memattr_entries, test_pmp_change_perm_invalid_region_index) { - /* region_idx = 2, which is out of bounds */ - size_t idx = 2; + const struct mem_attr_region_t *region; + size_t num_regions = mem_attr_get_regions(®ion); + size_t invalid_idx = num_regions; - zassert_equal(z_riscv_pmp_change_permissions(idx, PMP_R), -EINVAL, + zassert_equal(z_riscv_pmp_change_permissions(invalid_idx, PMP_R), -EINVAL, "Should return -EINVAL for region index out of bounds."); } ZTEST(riscv_pmp_memattr_entries, test_successful_permission_change) { - const uint8_t new_perm = 0x03; /* Read (0x1) | Write (0x2) */ - const size_t idx = 0; + const struct mem_attr_region_t *region; + size_t num_regions = mem_attr_get_regions(®ion); + size_t idx; + + /* Find the matching index of memory attribute region for dt_regions[0] */ + for (idx = 0; idx < num_regions; ++idx) { + if ((region[idx].dt_addr == dt_regions[0].base) && + (region[idx].dt_size == dt_regions[0].size)) { + break; + } + } - zassert_not_equal(new_perm, dt_regions[idx].perm, - "Ensure new permission is different from existing permission"); + zassert_not_equal(idx, num_regions, + "No matching memory attribute region found for dt_regions[0]."); - int ret = z_riscv_pmp_change_permissions(idx, new_perm); + /* Store original permission to revert later if needed, and calculate new permission */ + uint8_t original_perm = dt_regions[0].perm; + uint8_t new_perm = PMP_X ^ original_perm; /* Toggle X bit */ - dt_regions[idx].perm = new_perm; + /* Update the expectations */ + dt_regions[0].perm = new_perm; - zassert_equal(ret, 0, "Function should return 0 on success."); + /* Apply the permission change to the hardware */ + int ret = z_riscv_pmp_change_permissions(idx, new_perm); + + zassert_equal(ret, 0, "z_riscv_pmp_change_permissions should return 0 on success."); const size_t num_pmpcfg_regs = CONFIG_PMP_SLOTS / sizeof(unsigned long); const size_t num_pmpaddr_regs = CONFIG_PMP_SLOTS; @@ -192,6 +212,10 @@ ZTEST(riscv_pmp_memattr_entries, test_successful_permission_change) "found.", i + 1, dt_regions[i].base, dt_regions[i].size, dt_regions[i].perm); } + + /* Restore original permissions to leave system in original state */ + z_riscv_pmp_change_permissions(idx, original_perm); + dt_regions[0].perm = original_perm; } ZTEST_SUITE(riscv_pmp_memattr_entries, NULL, NULL, NULL, NULL, NULL); From ff252ebbf4e17d09b024f64613314a4660c4525d Mon Sep 17 00:00:00 2001 From: Filip Kokosinski Date: Tue, 9 Dec 2025 10:19:00 +0100 Subject: [PATCH 0204/3659] MAINTAINERS: relegate some Microchip RISC-V maintainers to colalborators This commit relegates some of the Microchip RISC-V area maitainers to the collabolator tier. Signed-off-by: Filip Kokosinski --- MAINTAINERS.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index a9b5f8a8637e..2677c85e0c6b 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -3386,6 +3386,7 @@ Microchip RISC-V Platforms: status: maintained maintainers: - fkokosinski + collaborators: - kgugala - tgorochowik files: From ba0402998688517f930bb8fe3292a9592c5cab95 Mon Sep 17 00:00:00 2001 From: Maochen Wang Date: Mon, 8 Dec 2025 16:40:21 +0800 Subject: [PATCH 0205/3659] mbedtls: enable config for keying material export Introduce MBEDTLS_SSL_KEYING_MATERIAL_EXPORT configuration option to control support for TLS keying material export. Signed-off-by: Maochen Wang --- modules/mbedtls/Kconfig.mbedtls | 3 +++ modules/mbedtls/configs/config-mbedtls.h | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/modules/mbedtls/Kconfig.mbedtls b/modules/mbedtls/Kconfig.mbedtls index 34052f44a1f7..c8065fa758a1 100644 --- a/modules/mbedtls/Kconfig.mbedtls +++ b/modules/mbedtls/Kconfig.mbedtls @@ -149,6 +149,9 @@ config MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED endif # MBEDTLS_SSL_PROTO_TLS1_3 +config MBEDTLS_SSL_KEYING_MATERIAL_EXPORT + bool "TLS keying material export support" + config MBEDTLS_HKDF_C bool "HMAC-based Extract-and-Expand Key Derivation Function" diff --git a/modules/mbedtls/configs/config-mbedtls.h b/modules/mbedtls/configs/config-mbedtls.h index 0b52143e3aa1..3c33586c4c1f 100644 --- a/modules/mbedtls/configs/config-mbedtls.h +++ b/modules/mbedtls/configs/config-mbedtls.h @@ -168,6 +168,10 @@ #define MBEDTLS_SSL_EARLY_DATA #endif +#if defined(CONFIG_MBEDTLS_SSL_KEYING_MATERIAL_EXPORT) +#define MBEDTLS_SSL_KEYING_MATERIAL_EXPORT +#endif + #if defined(CONFIG_MBEDTLS_HKDF_C) #define MBEDTLS_HKDF_C #endif From 2faece54944f6b9d5bfd6fea9e22c331a3984e17 Mon Sep 17 00:00:00 2001 From: Maochen Wang Date: Mon, 8 Dec 2025 16:43:56 +0800 Subject: [PATCH 0206/3659] hostap: update mbedtls config for enterprise use Enable MBEDTLS_SSL_KEYING_MATERIAL_EXPORT by default to support TLS keying material export for enterprise scenarios. Replace deprecated TLS 1.3 configs with MBEDTLS_SSL_PROTO_TLS1_3 and MBEDTLS_SSL_SESSION_TICKETS. Signed-off-by: Maochen Wang --- modules/hostap/Kconfig | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/hostap/Kconfig b/modules/hostap/Kconfig index ccc3b1899810..c5b0df1f81b2 100644 --- a/modules/hostap/Kconfig +++ b/modules/hostap/Kconfig @@ -238,6 +238,7 @@ config WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE select MBEDTLS_SERVER_NAME_INDICATION if MBEDTLS_BUILTIN select MBEDTLS_X509_CRL_PARSE_C select MBEDTLS_SSL_PROTO_TLS1_2 + select MBEDTLS_SSL_KEYING_MATERIAL_EXPORT select NOT_SECURE select WIFI_CERTIFICATE_LIB depends on !WIFI_NM_WPA_SUPPLICANT_CRYPTO_NONE @@ -309,8 +310,8 @@ config EAP_ALL config EAP_TLSV1_3 bool "EAP TLSv1.3 support" - select MBEDTLS_TLS_VERSION_1_3 - select MBEDTLS_TLS_SESSION_TICKETS + select MBEDTLS_SSL_PROTO_TLS1_3 + select MBEDTLS_SSL_SESSION_TICKETS select MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED select MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED select MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED From e01e67e1b00a9839dfe250ef4feb60077f394379 Mon Sep 17 00:00:00 2001 From: Maochen Wang Date: Mon, 8 Dec 2025 16:47:23 +0800 Subject: [PATCH 0207/3659] samples: net: wifi: enable supplicant key debug for NXP config Introduce WIFI_NM_WPA_SUPPLICANT_DEBUG_SHOW_KEYS to allow key dump when using the NXP board debug configuration. Signed-off-by: Maochen Wang --- samples/net/wifi/shell/nxp/overlay_hostap_debug.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/samples/net/wifi/shell/nxp/overlay_hostap_debug.conf b/samples/net/wifi/shell/nxp/overlay_hostap_debug.conf index 6e57a8f1a390..0d656b6c35bb 100644 --- a/samples/net/wifi/shell/nxp/overlay_hostap_debug.conf +++ b/samples/net/wifi/shell/nxp/overlay_hostap_debug.conf @@ -7,3 +7,4 @@ CONFIG_WIFI_NM_WPA_SUPPLICANT_THREAD_STACK_SIZE=16384 # debug level CONFIG_WIFI_NM_WPA_SUPPLICANT_DEBUG_LEVEL=2 CONFIG_WIFI_NM_WPA_SUPPLICANT_LOG_LEVEL_DBG=y +CONFIG_WIFI_NM_WPA_SUPPLICANT_DEBUG_SHOW_KEYS=y From 09aac143bf6963384f786ef1e482770e0ea05451 Mon Sep 17 00:00:00 2001 From: Maochen Wang Date: Mon, 8 Dec 2025 16:49:24 +0800 Subject: [PATCH 0208/3659] manifest: update hostap to fix EAP-TLS failure with TLS 1.3 on Cisco AP Current implementation uses tls_connection_export_keys_cb to retrieve exporter_master_secret, client_random, and server_random, which only works for TLS 1.2. TLS 1.3 introduces a different key derivation mechanism. In mbedtls 3.6.4, MBEDTLS_SSL_KEYING_MATERIAL_EXPORT supports exporting keying material for both TLS 1.2 and TLS 1.3. Update logic to use this macro and remove redundant MBEDTLS_SSL_PROTO_TLS1_3 check in TLS 1.2 handling. Signed-off-by: Maochen Wang --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 82f8430b4729..d1b90d200111 100644 --- a/west.yml +++ b/west.yml @@ -286,7 +286,7 @@ manifest: - hal - name: hostap path: modules/lib/hostap - revision: 98daa83ecc54e560610711e142184f5f77607bad + revision: 5af8b179632c602b8a05c34c74a50dda3d546eaa - name: liblc3 revision: 48bbd3eacd36e99a57317a0a4867002e0b09e183 path: modules/lib/liblc3 From bcec3bd04ba38e65008f81d867f3b046a9da637f Mon Sep 17 00:00:00 2001 From: Cristian Bulacu Date: Fri, 5 Dec 2025 13:52:04 +0200 Subject: [PATCH 0209/3659] openthread: platform: infra_if: Remove NAT64 packet checksums OpenThread NAT64 translator creates a packet that has header checksum computed and appended. In case of using ethernet as backbone interface, some NICs may want to have checksum set to 0 for a correct computation. This commit aims to address this issue by checking if hardware has offload capabilities and setting NAT64 packet checksums to 0, if needed. Signed-off-by: Cristian Bulacu --- modules/openthread/platform/infra_if.c | 51 ++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/modules/openthread/platform/infra_if.c b/modules/openthread/platform/infra_if.c index b6a6728d74b6..c15b1e4e4c6b 100644 --- a/modules/openthread/platform/infra_if.c +++ b/modules/openthread/platform/infra_if.c @@ -44,6 +44,7 @@ static void handle_ra_from_ot(const uint8_t *buffer, uint16_t buffer_length); static struct zsock_pollfd sockfd_raw[MAX_SERVICES]; static void raw_receive_handler(struct net_socket_service_event *evt); +static void remove_checksums_for_eth_offloading(uint8_t *buf, uint16_t len); static int raw_infra_if_sock = -1; NET_SOCKET_SERVICE_SYNC_DEFINE_STATIC(handle_infra_if_raw_recv, raw_receive_handler, MAX_SERVICES); @@ -360,10 +361,60 @@ otError infra_if_send_raw_message(uint8_t *buf, uint16_t len) { otError error = OT_ERROR_NONE; + remove_checksums_for_eth_offloading(buf, len); + VerifyOrExit(zsock_send(raw_infra_if_sock, buf, len, 0) > 0, error = OT_ERROR_FAILED); exit: return error; } + +static void remove_checksums_for_eth_offloading(uint8_t *buf, uint16_t len) +{ + struct net_ipv4_hdr *ipv4_hdr = (struct net_ipv4_hdr *)buf; + uint8_t *pkt_cursor = NULL; + struct ethernet_config config; + + if ((net_eth_get_hw_capabilities(ail_iface_ptr) & ETHERNET_HW_TX_CHKSUM_OFFLOAD) == 0) { + return; /* No checksum offload capabilities*/ + } + + if (net_eth_get_hw_config(ail_iface_ptr, ETHERNET_CONFIG_TYPE_TX_CHECKSUM_SUPPORT, + &config) != 0) { + return; /* No TX checksum capabilities*/ + } + + pkt_cursor = buf + (ipv4_hdr->vhl & 0x0F) * 4; + + if ((config.chksum_support & NET_IF_CHECKSUM_IPV4_HEADER) != 0) { + ipv4_hdr->chksum = 0; + } + + switch (ipv4_hdr->proto) { + case IPPROTO_ICMP: + if ((config.chksum_support & NET_IF_CHECKSUM_IPV4_ICMP) != 0) { + struct net_icmp_hdr *icmp_hdr = (struct net_icmp_hdr *)pkt_cursor; + + icmp_hdr->chksum = 0; + } + break; + case IPPROTO_UDP: + if ((config.chksum_support & NET_IF_CHECKSUM_IPV4_UDP) != 0) { + struct net_udp_hdr *udp_hdr = (struct net_udp_hdr *)pkt_cursor; + + udp_hdr->chksum = 0; + } + break; + case IPPROTO_TCP: + if ((config.chksum_support & NET_IF_CHECKSUM_IPV4_TCP) != 0) { + struct net_tcp_hdr *tcp_hdr = (struct net_tcp_hdr *)pkt_cursor; + + tcp_hdr->chksum = 0; + } + break; + default: + break; + } +} #endif /* CONFIG_OPENTHREAD_NAT64_TRANSLATOR */ From fba7c3ed88f1a36474a043e25568d70201ed7871 Mon Sep 17 00:00:00 2001 From: Holt Sun Date: Fri, 5 Dec 2025 22:54:05 +0800 Subject: [PATCH 0210/3659] drivers: counter: fix mcux lptmr unit test issue. The counter alarm irq shall set the match value to the max top value after stopping the timer, otherwise the next start of the lptmr counter may shortly match the the previous match value thus cause test_valid_function_without_alarm run failed. Signed-off-by: Holt Sun --- drivers/counter/counter_mcux_lptmr.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/counter/counter_mcux_lptmr.c b/drivers/counter/counter_mcux_lptmr.c index 51eb46cb8f21..0a0a4a2650aa 100644 --- a/drivers/counter/counter_mcux_lptmr.c +++ b/drivers/counter/counter_mcux_lptmr.c @@ -247,6 +247,7 @@ static void mcux_lptmr_isr(const struct device *dev) uint32_t current_count = LPTMR_GetCurrentTimerCount(config->base); LPTMR_StopTimer(config->base); + LPTMR_SetTimerPeriod(config->base, config->info.max_top_value); callback(dev, 0, current_count, user_data); From 6008841b603c7c2cbd5334a46b9ca189461e3165 Mon Sep 17 00:00:00 2001 From: Holt Sun Date: Sat, 6 Dec 2025 13:22:23 +0800 Subject: [PATCH 0211/3659] tests: counter: add mcux LPTMR alarm mode coverage Extend the counter_basic_api tests with a dedicated configuration that enables the MCUX LPTMR driver in alarm mode. The new testcase: - Selects CONFIG_COUNTER_MCUX_LPTMR_ALARM - Runs the existing counter_basic_api suite against nxp_lptmr devices when built for a board that instantiates the LPTMR This verifies that the alarm-only LPTMR configuration passes the common counter API tests without relying on the TOP callback feature. Signed-off-by: Holt Sun --- tests/drivers/counter/counter_basic_api/testcase.yaml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/drivers/counter/counter_basic_api/testcase.yaml b/tests/drivers/counter/counter_basic_api/testcase.yaml index f13e18ec35b7..aed62735a5ee 100644 --- a/tests/drivers/counter/counter_basic_api/testcase.yaml +++ b/tests/drivers/counter/counter_basic_api/testcase.yaml @@ -51,3 +51,12 @@ tests: - CONFIG_TEST_DRIVER_COUNTER_MCUX_LPC_RTC_HIGHRES=n extra_args: DTC_OVERLAY_FILE="enable_standby.overlay" + drivers.counter.basic_api.mcux_lptmr_alarm: + tags: + - drivers + - counter + filter: dt_compat_enabled("nxp,lptmr") + depends_on: counter + timeout: 600 + extra_configs: + - CONFIG_COUNTER_MCUX_LPTMR_ALARM=y From 2a9114af3da992a893cea6d0c1bc47c4428aa021 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Grochala?= Date: Wed, 3 Dec 2025 14:57:14 +0100 Subject: [PATCH 0212/3659] soc: nordic: nrf54l: Remove selecting a DTS-type option MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove selecting `CONFIG_HAS_HW_NRF_RADIO_IEEE802154` that should be generated from DTS based on the SoC selection. Signed-off-by: Michał Grochala --- soc/nordic/nrf54l/Kconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/soc/nordic/nrf54l/Kconfig b/soc/nordic/nrf54l/Kconfig index 753bdbfa8472..6d10e4c80f1c 100644 --- a/soc/nordic/nrf54l/Kconfig +++ b/soc/nordic/nrf54l/Kconfig @@ -16,7 +16,6 @@ config SOC_NRF54L_CPUAPP_COMMON select CPU_CORTEX_M33 select CPU_CORTEX_M_HAS_DWT select CPU_HAS_ICACHE - select HAS_HW_NRF_RADIO_IEEE802154 select HAS_POWEROFF select HAS_NORDIC_RAM_CTRL From c1091acd097f222d7a9ac753096ffd3754cb969f Mon Sep 17 00:00:00 2001 From: Simon Piriou Date: Sat, 5 Jul 2025 16:57:00 +0200 Subject: [PATCH 0213/3659] net: l2: ieee802154: add support for IEEE802154_CFI_DATA_REQUEST 802.15.4 specifies that a device may send a DATA_REQUEST command to the coordinator after waiting for "macResponseWaitTime", starting after the acknowledgment to the association request command. This change adds support to generate DATA_REQUEST frames and sends one for the association usecase only. The two other usecases, for MLME-POLL or for beacon-enabled PAN, are not yet supported. Signed-off-by: Simon Piriou --- subsys/net/l2/ieee802154/ieee802154_frame.c | 31 ++++++++++++++++++++- subsys/net/l2/ieee802154/ieee802154_mgmt.c | 26 ++++++++++++++++- 2 files changed, 55 insertions(+), 2 deletions(-) diff --git a/subsys/net/l2/ieee802154/ieee802154_frame.c b/subsys/net/l2/ieee802154/ieee802154_frame.c index a4a379308115..b56149853813 100644 --- a/subsys/net/l2/ieee802154/ieee802154_frame.c +++ b/subsys/net/l2/ieee802154/ieee802154_frame.c @@ -792,8 +792,37 @@ static inline bool cfi_to_fs_settings(enum ieee802154_cfi cfi, struct ieee802154 break; case IEEE802154_CFI_DATA_REQUEST: + if (params->dst.len == 0) { + /* If the Destination Addressing Mode subfield is set to zero (i.e., + * destination addressing information not present), the PAN ID + * Compression subfield of the Frame Control field shall be set to zero + * and the source PAN identifier shall contain the value of macPANId. + * + * This is the case only if the data request command is being + * sent in response to the receipt of a beacon frame indicating that + * data are pending for that device. + */ + fs->fc.dst_addr_mode = IEEE802154_ADDR_MODE_NONE; + } else { + /* Both short and extended dest addresses are supported. + * It's up to the caller to configure it correctly. + */ + if (params->dst.len == IEEE802154_SHORT_ADDR_LENGTH) { + fs->fc.dst_addr_mode = IEEE802154_ADDR_MODE_SHORT; + } else { + fs->fc.dst_addr_mode = IEEE802154_ADDR_MODE_EXTENDED; + } + fs->fc.pan_id_comp = 1U; + } + + if (params->short_addr == IEEE802154_NO_SHORT_ADDRESS_ASSIGNED) { + fs->fc.src_addr_mode = IEEE802154_ADDR_MODE_EXTENDED; + } else { + fs->fc.dst_addr_mode = IEEE802154_ADDR_MODE_SHORT; + } + + /* the Acknowledgment Request subfield is always set */ fs->fc.ar = 1U; - /* TODO: src/dst addr mode: see section 7.5.5 */ break; case IEEE802154_CFI_ORPHAN_NOTIFICATION: diff --git a/subsys/net/l2/ieee802154/ieee802154_mgmt.c b/subsys/net/l2/ieee802154/ieee802154_mgmt.c index 8ecc8653f6b1..f03d674156d5 100644 --- a/subsys/net/l2/ieee802154/ieee802154_mgmt.c +++ b/subsys/net/l2/ieee802154/ieee802154_mgmt.c @@ -574,7 +574,30 @@ static int ieee802154_associate(uint64_t mgmt_request, struct net_if *iface, * TODO: The Association Response command shall be sent to the device * requesting association using indirect transmission. */ - k_sem_take(&ctx->scan_ctx_lock, K_USEC(ieee802154_get_response_wait_time_us(iface))); + ret = k_sem_take(&ctx->scan_ctx_lock, K_USEC(ieee802154_get_response_wait_time_us(iface))); + + if (ret == -EAGAIN) { + /* Timeout, send DATA_REQUEST */ + net_pkt_unref(pkt); + pkt = ieee802154_create_mac_cmd_frame(iface, IEEE802154_CFI_DATA_REQUEST, ¶ms); + if (pkt == NULL) { + ret = -ENOBUFS; + k_sem_give(&ctx->scan_ctx_lock); + NET_ERR("Could not associate: cannot allocate DATA request frame"); + goto out; + } + ieee802154_mac_cmd_finalize(pkt, IEEE802154_CFI_DATA_REQUEST); + + if (ieee802154_radio_send(iface, pkt, pkt->buffer)) { + ret = -EIO; + k_sem_give(&ctx->scan_ctx_lock); + NET_ERR("Could not associate: cannot send DATA request"); + goto out; + } + + k_sem_take(&ctx->scan_ctx_lock, + K_USEC(ieee802154_get_response_wait_time_us(iface))); + } /* Release the scan lock in case an association response was not received * within macResponseWaitTime and we got a timeout instead. @@ -607,6 +630,7 @@ static int ieee802154_associate(uint64_t mgmt_request, struct net_if *iface, } ctx->channel = req->channel; + ret = 0; } else { ret = -EACCES; } From c4a4d8aa873bb5d49366eb0019e51f824a95e15e Mon Sep 17 00:00:00 2001 From: Sven Ginka Date: Thu, 21 Aug 2025 12:28:20 +0200 Subject: [PATCH 0214/3659] drivers: ethernet: dsa_nxp_imx_netc: fix zephyr random mac zephyr,random-mac-address defaults to 0 or 1, which is always available in generated code. so we can use the value itself. Signed-off-by: Sven Ginka --- doc/connectivity/networking/dsa.rst | 2 +- drivers/ethernet/dsa/dsa_nxp_imx_netc.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/connectivity/networking/dsa.rst b/doc/connectivity/networking/dsa.rst index b4d3c79f443e..3f78b03d50eb 100644 --- a/doc/connectivity/networking/dsa.rst +++ b/doc/connectivity/networking/dsa.rst @@ -83,7 +83,7 @@ of i.MX NETC. .phy_mode = NETC_PHY_MODE(port), \ }; \ struct dsa_port_config dsa_##n##_##port##_config = { \ - .use_random_mac_addr = DT_NODE_HAS_PROP(port, zephyr_random_mac_address), \ + .use_random_mac_addr = DT_PROP(port, zephyr_random_mac_address), \ .mac_addr = DT_PROP_OR(port, local_mac_address, {0}), \ .port_idx = DT_REG_ADDR(port), \ .phy_dev = DEVICE_DT_GET_OR_NULL(DT_PHANDLE(port, phy_handle)), \ diff --git a/drivers/ethernet/dsa/dsa_nxp_imx_netc.c b/drivers/ethernet/dsa/dsa_nxp_imx_netc.c index e7915f62ba08..8d0c0bc5597d 100644 --- a/drivers/ethernet/dsa/dsa_nxp_imx_netc.c +++ b/drivers/ethernet/dsa/dsa_nxp_imx_netc.c @@ -552,7 +552,7 @@ static struct dsa_api dsa_netc_api = { .phy_mode = NETC_PHY_MODE(port), \ }; \ struct dsa_port_config dsa_##n##_##port##_config = { \ - .use_random_mac_addr = DT_NODE_HAS_PROP(port, zephyr_random_mac_address), \ + .use_random_mac_addr = DT_PROP(port, zephyr_random_mac_address), \ .mac_addr = DT_PROP_OR(port, local_mac_address, {0}), \ .port_idx = DT_REG_ADDR(port), \ .phy_dev = DEVICE_DT_GET_OR_NULL(DT_PHANDLE(port, phy_handle)), \ @@ -583,6 +583,6 @@ static struct dsa_api dsa_netc_api = { POST_KERNEL, \ CONFIG_ETH_INIT_PRIORITY, \ NULL); \ - DSA_SWITCH_INST_INIT(n, &dsa_netc_api, &dsa_netc_data_##n, DSA_NETC_PORT_INST_INIT); \ + DSA_SWITCH_INST_INIT(n, &dsa_netc_api, &dsa_netc_data_##n, DSA_NETC_PORT_INST_INIT); DT_INST_FOREACH_STATUS_OKAY(DSA_NETC_DEVICE); From 83956260f77e6138ca56614e004ee891d27e80ff Mon Sep 17 00:00:00 2001 From: Jilay Pandya Date: Tue, 8 Jul 2025 21:24:03 +0200 Subject: [PATCH 0215/3659] drivers: stepper: split stepper api - split stepper api into stepper and stepper_drv api - stepper api now comprises only of motion control apis - stepper_drv api comprises of apis for configuring stepper drivers - add documentation about stepper and stepper_drv api - move stepper.rst in a dedicated stepper folder - add information about stepper_drv api and relevant functions in stepper documentation. - drop motion control functions from all the stepper_drv drivers - create a common a library for controlling stepper motors by toggling gpios via h-bridge or step-dir stepper_drivers - tmc5xxx devices are a combination of motion controller and stepper driver devices. tmc5xxx devices need to be modelled as mfds in order to address the split in stepper driver subsystem Signed-off-by: Jilay Pandya --- MAINTAINERS.yml | 2 +- doc/hardware/peripherals/index.rst | 2 +- .../{stepper.rst => stepper/index.rst} | 57 +- .../stepper/individual_controller_driver.rst | 49 ++ .../stepper/integrated_controller_driver.rst | 90 +++ drivers/stepper/CMakeLists.txt | 3 +- drivers/stepper/Kconfig | 1 + drivers/stepper/Kconfig.fake | 6 +- .../adi_tmc/Kconfig.tmc_rampgen_template | 1 - drivers/stepper/adi_tmc/tmc22xx/tmc22xx.c | 59 +- .../stepper/adi_tmc/tmc50xx/CMakeLists.txt | 5 +- .../stepper/adi_tmc/tmc50xx/Kconfig.tmc50xx | 12 +- drivers/stepper/adi_tmc/tmc50xx/tmc50xx.c | 734 ++++-------------- drivers/stepper/adi_tmc/tmc50xx/tmc50xx.h | 90 +++ .../stepper/adi_tmc/tmc50xx/tmc50xx_stepper.c | 448 +++++++++++ .../adi_tmc/tmc50xx/tmc50xx_stepper_drv.c | 185 +++++ .../stepper/adi_tmc/tmc51xx/CMakeLists.txt | 2 + .../stepper/adi_tmc/tmc51xx/Kconfig.tmc51xx | 13 +- drivers/stepper/adi_tmc/tmc51xx/tmc51xx.c | 717 +++-------------- drivers/stepper/adi_tmc/tmc51xx/tmc51xx.h | 89 +++ .../stepper/adi_tmc/tmc51xx/tmc51xx_stepper.c | 460 +++++++++++ .../adi_tmc/tmc51xx/tmc51xx_stepper_drv.c | 184 +++++ drivers/stepper/allegro/a4979.c | 62 +- drivers/stepper/fake_stepper_controller.c | 98 ++- drivers/stepper/gpio_stepper/CMakeLists.txt | 4 +- drivers/stepper/gpio_stepper/Kconfig | 7 +- .../gpio_stepper/Kconfig.gpio_step_dir | 9 + drivers/stepper/gpio_stepper/Kconfig.h_bridge | 3 +- .../gpio_stepper/common/CMakeLists.txt | 8 + drivers/stepper/gpio_stepper/common/Kconfig | 22 + .../gpio_stepper/common/gpio_stepper_common.c | 88 +++ .../common/include/gpio_stepper_common.h | 290 +++++++ .../include/stepper_timing_source.h | 10 +- .../stepper_counter_timing.c | 28 +- .../stepper_work_timing.c | 19 +- drivers/stepper/gpio_stepper/gpio_step_dir.c | 304 ++++++++ .../stepper/gpio_stepper/h_bridge_stepper.c | 332 ++------ .../gpio_stepper/step_dir/CMakeLists.txt | 8 - drivers/stepper/gpio_stepper/step_dir/Kconfig | 24 - .../include/step_dir_stepper_common.h | 239 ------ .../step_dir/step_dir_stepper_common.c | 404 ---------- drivers/stepper/step_dir/CMakeLists.txt | 4 + drivers/stepper/step_dir/Kconfig | 9 + .../include/step_dir_stepper_common.h | 60 ++ drivers/stepper/stepper_shell.c | 160 ++-- drivers/stepper/ti/Kconfig.drv84xx | 1 - drivers/stepper/ti/drv84xx.c | 69 +- dts/bindings/stepper/adi/adi,tmc2209.yaml | 9 +- .../stepper/adi/adi,tmc50xx-stepper-drv.yaml | 15 + .../stepper/adi/adi,tmc50xx-stepper.yaml | 32 + dts/bindings/stepper/adi/adi,tmc50xx.yaml | 98 +-- .../stepper/adi/adi,tmc51xx-base.yaml | 36 +- dts/bindings/stepper/adi/adi,tmc51xx-spi.yaml | 54 +- .../stepper/adi/adi,tmc51xx-stepper-drv.yaml | 10 + .../stepper/adi/adi,tmc51xx-stepper.yaml | 29 + .../stepper/adi/adi,tmc51xx-uart.yaml | 50 +- .../stepper/allegro/allegro,a4979.yaml | 5 +- dts/bindings/stepper/stepper-controller.yaml | 46 -- dts/bindings/stepper/stepper-driver.yaml | 26 + dts/bindings/stepper/ti/ti,drv84xx.yaml | 11 +- .../stepper/zephyr,fake-stepper-drv.yaml | 9 + dts/bindings/stepper/zephyr,fake-stepper.yaml | 7 +- .../stepper/zephyr,gpio-step-dir-stepper.yaml | 55 ++ .../stepper/zephyr,h-bridge-stepper.yaml | 34 +- include/zephyr/drivers/stepper.h | 449 ++++++----- include/zephyr/drivers/stepper/stepper_fake.h | 19 +- .../zephyr/drivers/stepper/stepper_trinamic.h | 12 +- .../generic/boards/nucleo_g071rb.overlay | 32 +- samples/drivers/stepper/generic/src/main.c | 9 +- .../tmc50xx/boards/nucleo_g071rb.overlay | 34 +- samples/drivers/stepper/tmc50xx/src/main.c | 28 +- tests/drivers/build_all/stepper/app.overlay | 36 + tests/drivers/build_all/stepper/gpio.dtsi | 22 +- tests/drivers/build_all/stepper/spi.dtsi | 195 ++--- tests/drivers/build_all/stepper/testcase.yaml | 2 +- tests/drivers/build_all/stepper/uart.dtsi | 53 +- tests/drivers/stepper/shell/app.overlay | 7 +- tests/drivers/stepper/shell/src/main.c | 94 ++- .../boards/native_sim_adi_tmc2209.overlay | 27 - .../native_sim_adi_tmc2209_work_q.overlay | 26 - .../boards/native_sim_allegro_a4979.overlay | 27 - .../native_sim_allegro_a4979_work_q.overlay | 26 - .../boards/native_sim_gpio_step_dir.overlay | 19 + .../native_sim_gpio_step_dir_workq.overlay | 18 + .../native_sim_h_bridge_stepper.overlay | 24 + .../native_sim_h_bridge_stepper_workq.overlay | 22 + .../boards/native_sim_ti_drv84xx.overlay | 27 - .../native_sim_ti_drv84xx_work_q.overlay | 26 - ...native_sim_zephyr_h_bridge_stepper.overlay | 25 - ...emu_x86_64_zephyr_h_bridge_stepper.overlay | 54 -- tests/drivers/stepper/stepper_api/src/main.c | 19 - .../drivers/stepper/stepper_api/testcase.yaml | 49 +- .../{step_dir => stepper_drv}/CMakeLists.txt | 0 .../stepper/{step_dir => stepper_drv}/Kconfig | 4 +- .../boards/native_sim.overlay | 0 .../boards/native_sim_adi_tmc2209.overlay | 6 +- .../boards/native_sim_allegro_a4979.overlay | 5 +- .../boards/native_sim_ti_drv84xx.overlay | 6 +- .../{step_dir => stepper_drv}/prj.conf | 0 .../{step_dir => stepper_drv}/src/main.c | 39 +- .../{step_dir => stepper_drv}/testcase.yaml | 8 +- 101 files changed, 4144 insertions(+), 3302 deletions(-) rename doc/hardware/peripherals/{stepper.rst => stepper/index.rst} (76%) create mode 100644 doc/hardware/peripherals/stepper/individual_controller_driver.rst create mode 100644 doc/hardware/peripherals/stepper/integrated_controller_driver.rst create mode 100644 drivers/stepper/adi_tmc/tmc50xx/tmc50xx.h create mode 100644 drivers/stepper/adi_tmc/tmc50xx/tmc50xx_stepper.c create mode 100644 drivers/stepper/adi_tmc/tmc50xx/tmc50xx_stepper_drv.c create mode 100644 drivers/stepper/adi_tmc/tmc51xx/tmc51xx.h create mode 100644 drivers/stepper/adi_tmc/tmc51xx/tmc51xx_stepper.c create mode 100644 drivers/stepper/adi_tmc/tmc51xx/tmc51xx_stepper_drv.c create mode 100644 drivers/stepper/gpio_stepper/Kconfig.gpio_step_dir create mode 100644 drivers/stepper/gpio_stepper/common/CMakeLists.txt create mode 100644 drivers/stepper/gpio_stepper/common/Kconfig create mode 100644 drivers/stepper/gpio_stepper/common/gpio_stepper_common.c create mode 100644 drivers/stepper/gpio_stepper/common/include/gpio_stepper_common.h rename drivers/stepper/gpio_stepper/{step_dir => common}/include/stepper_timing_source.h (87%) rename drivers/stepper/gpio_stepper/{step_dir => common}/stepper_counter_timing.c (75%) rename drivers/stepper/gpio_stepper/{step_dir => common}/stepper_work_timing.c (76%) create mode 100644 drivers/stepper/gpio_stepper/gpio_step_dir.c delete mode 100644 drivers/stepper/gpio_stepper/step_dir/CMakeLists.txt delete mode 100644 drivers/stepper/gpio_stepper/step_dir/Kconfig delete mode 100644 drivers/stepper/gpio_stepper/step_dir/include/step_dir_stepper_common.h delete mode 100644 drivers/stepper/gpio_stepper/step_dir/step_dir_stepper_common.c create mode 100644 drivers/stepper/step_dir/CMakeLists.txt create mode 100644 drivers/stepper/step_dir/Kconfig create mode 100644 drivers/stepper/step_dir/include/step_dir_stepper_common.h create mode 100644 dts/bindings/stepper/adi/adi,tmc50xx-stepper-drv.yaml create mode 100644 dts/bindings/stepper/adi/adi,tmc50xx-stepper.yaml create mode 100644 dts/bindings/stepper/adi/adi,tmc51xx-stepper-drv.yaml create mode 100644 dts/bindings/stepper/adi/adi,tmc51xx-stepper.yaml delete mode 100644 dts/bindings/stepper/stepper-controller.yaml create mode 100644 dts/bindings/stepper/stepper-driver.yaml create mode 100644 dts/bindings/stepper/zephyr,fake-stepper-drv.yaml create mode 100644 dts/bindings/stepper/zephyr,gpio-step-dir-stepper.yaml delete mode 100644 tests/drivers/stepper/stepper_api/boards/native_sim_adi_tmc2209.overlay delete mode 100644 tests/drivers/stepper/stepper_api/boards/native_sim_adi_tmc2209_work_q.overlay delete mode 100644 tests/drivers/stepper/stepper_api/boards/native_sim_allegro_a4979.overlay delete mode 100644 tests/drivers/stepper/stepper_api/boards/native_sim_allegro_a4979_work_q.overlay create mode 100644 tests/drivers/stepper/stepper_api/boards/native_sim_gpio_step_dir.overlay create mode 100644 tests/drivers/stepper/stepper_api/boards/native_sim_gpio_step_dir_workq.overlay create mode 100644 tests/drivers/stepper/stepper_api/boards/native_sim_h_bridge_stepper.overlay create mode 100644 tests/drivers/stepper/stepper_api/boards/native_sim_h_bridge_stepper_workq.overlay delete mode 100644 tests/drivers/stepper/stepper_api/boards/native_sim_ti_drv84xx.overlay delete mode 100644 tests/drivers/stepper/stepper_api/boards/native_sim_ti_drv84xx_work_q.overlay delete mode 100644 tests/drivers/stepper/stepper_api/boards/native_sim_zephyr_h_bridge_stepper.overlay delete mode 100644 tests/drivers/stepper/stepper_api/boards/qemu_x86_64_zephyr_h_bridge_stepper.overlay rename tests/drivers/stepper/{step_dir => stepper_drv}/CMakeLists.txt (100%) rename tests/drivers/stepper/{step_dir => stepper_drv}/Kconfig (84%) rename tests/drivers/stepper/{step_dir => stepper_drv}/boards/native_sim.overlay (100%) rename tests/drivers/stepper/{step_dir => stepper_drv}/boards/native_sim_adi_tmc2209.overlay (73%) rename tests/drivers/stepper/{step_dir => stepper_drv}/boards/native_sim_allegro_a4979.overlay (77%) rename tests/drivers/stepper/{step_dir => stepper_drv}/boards/native_sim_ti_drv84xx.overlay (77%) rename tests/drivers/stepper/{step_dir => stepper_drv}/prj.conf (100%) rename tests/drivers/stepper/{step_dir => stepper_drv}/src/main.c (61%) rename tests/drivers/stepper/{step_dir => stepper_drv}/testcase.yaml (87%) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index 2677c85e0c6b..9cf63201a3a6 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -2450,7 +2450,7 @@ Documentation Infrastructure: - include/zephyr/drivers/stepper/ - include/zephyr/drivers/stepper.h - dts/bindings/stepper/ - - doc/hardware/peripherals/stepper.rst + - doc/hardware/peripherals/stepper/ - samples/drivers/stepper/ - tests/drivers/build_all/stepper/ - tests/drivers/stepper/ diff --git a/doc/hardware/peripherals/index.rst b/doc/hardware/peripherals/index.rst index 2ef752c27dfe..7286d88f5b30 100644 --- a/doc/hardware/peripherals/index.rst +++ b/doc/hardware/peripherals/index.rst @@ -58,7 +58,7 @@ Peripherals sensor/index.rst sent.rst spi.rst - stepper.rst + stepper/index.rst smbus.rst uart.rst usbc_vbus.rst diff --git a/doc/hardware/peripherals/stepper.rst b/doc/hardware/peripherals/stepper/index.rst similarity index 76% rename from doc/hardware/peripherals/stepper.rst rename to doc/hardware/peripherals/stepper/index.rst index 5e399b2d594d..fc11f4bbe2bd 100644 --- a/doc/hardware/peripherals/stepper.rst +++ b/doc/hardware/peripherals/stepper/index.rst @@ -3,22 +3,27 @@ Steppers ######## -The stepper driver API provides a set of functions for controlling and configuring stepper drivers. +The stepper driver subsystem consists of two device driver APIs: -Configure Stepper Driver -======================== +Stepper-DRV API +*************** + +The stepper driver API provides a common interface for stepper drivers. + +- Configure **micro-stepping resolution** using :c:func:`stepper_drv_set_micro_step_res` + and :c:func:`stepper_drv_get_micro_step_res`. +- **Enable** the stepper driver using :c:func:`stepper_drv_enable`. +- **Disable** the stepper driver using :c:func:`stepper_drv_disable`. +- Register an **event callback** using :c:func:`stepper_drv_set_event_cb`. + +Stepper API +*********** + +The stepper API provides a common interface for stepper controllers. -- Configure **micro-stepping resolution** using :c:func:`stepper_set_micro_step_res` - and :c:func:`stepper_get_micro_step_res`. - Configure **reference position** in microsteps using :c:func:`stepper_set_reference_position` and :c:func:`stepper_get_actual_position`. - Set **step interval** in nanoseconds between steps using :c:func:`stepper_set_microstep_interval` -- **Enable** the stepper driver using :c:func:`stepper_enable`. -- **Disable** the stepper driver using :c:func:`stepper_disable`. - -Control Stepper -=============== - - **Move by** +/- micro-steps also known as **relative movement** using :c:func:`stepper_move_by`. - **Move to** a specific position also known as **absolute movement** using :c:func:`stepper_move_to`. - Run continuously with a **constant step interval** in a specific direction until @@ -27,8 +32,10 @@ Control Stepper - Check if the stepper is **moving** using :c:func:`stepper_is_moving`. - Register an **event callback** using :c:func:`stepper_set_event_callback`. +.. _stepper-device-tree: + Device Tree -=========== +*********** In the context of stepper controllers device tree provides the initial hardware configuration for stepper drivers on a per device level. Each device must specify @@ -36,21 +43,19 @@ a device tree binding in Zephyr, and ideally, a set of hardware configuration op for things such as current settings, ramp parameters and furthermore. These can then be used in a boards devicetree to configure a stepper driver to its initial state. -See examples in: +Driver Composition Scenarios +============================ -- :dtcompatible:`zephyr,h-bridge-stepper` -- :dtcompatible:`adi,tmc50xx` +Below are two typical scenarios: -Discord -======= +.. toctree:: + :maxdepth: 1 -Zephyr has a `stepper discord`_ channel for stepper related discussions, which -is open to all. - -.. _stepper-api-reference: + integrated_controller_driver.rst + individual_controller_driver.rst Stepper API Test Suite -====================== +********************** The stepper API test suite provides a set of tests that can be used to verify the functionality of stepper drivers. @@ -91,8 +96,16 @@ have been skipped. API Reference ************* +.. _stepper-drv-api-reference: + A common set of functions which should be implemented by all stepper drivers. +.. doxygengroup:: stepper_drv_interface + +.. _stepper-api-reference: + +A common set of functions which should be implemented by all stepper controllers. + .. doxygengroup:: stepper_interface Stepper controller specific APIs diff --git a/doc/hardware/peripherals/stepper/individual_controller_driver.rst b/doc/hardware/peripherals/stepper/individual_controller_driver.rst new file mode 100644 index 000000000000..9602b765bd21 --- /dev/null +++ b/doc/hardware/peripherals/stepper/individual_controller_driver.rst @@ -0,0 +1,49 @@ +.. _stepper-individual-controller-driver: + +Individual Stepper Motion Controller and Driver +############################################### + +A motion control driver implements :c:group:`stepper_interface` API, for instance, +:dtcompatible:`zephyr,gpio-step-dir-stepper` and a hardware driver implements :c:group:`stepper_drv_interface` +API, for instance, :dtcompatible:`adi,tmc2209`. + +Following is an example of a device tree configuration for a stepper driver with a dedicated stepper motion +controller: + +.. code-block:: dts + + / { + aliases { + stepper_drv = &tmc2209 + stepper = &step_dir_motion_control; + }; + + /* DEVICE_API: stepper_drv api */ + tmc2209: tmc2209 { + compatible = "adi,tmc2209"; + enable-gpios = <&gpioa 6 GPIO_ACTIVE_HIGH>; + m0-gpios = <&gpiob 0 GPIO_ACTIVE_HIGH>; + m1-gpios = <&gpioa 7 GPIO_ACTIVE_HIGH>; + }; + + /* DEVICE_API: stepper api */ + step_dir_motion_control: step_dir_motion_control { + compatible = "zephyr,gpio-step-dir-stepper"; + step-gpios = <&gpioa 9 GPIO_ACTIVE_HIGH>; + dir-gpios = <&gpioc 7 GPIO_ACTIVE_HIGH>; + invert-direction; + stepper-drv = <&tmc2209>; + }; + }; + +Following the aforementioned configurations, the stepper driver subsystem can be used in the application code +as follows: + +.. code-block:: c + + static const struct device *stepper = DEVICE_DT_GET(DT_ALIAS(stepper)); + static const struct device *stepper_drv = DEVICE_DT_GET(DT_ALIAS(stepper_drv)); + ... + stepper_move_to(stepper, 200); + stepper_stop(stepper); + stepper_drv_disable(stepper_drv); diff --git a/doc/hardware/peripherals/stepper/integrated_controller_driver.rst b/doc/hardware/peripherals/stepper/integrated_controller_driver.rst new file mode 100644 index 000000000000..a3b46ff6a1dc --- /dev/null +++ b/doc/hardware/peripherals/stepper/integrated_controller_driver.rst @@ -0,0 +1,90 @@ +.. _stepper-integrated-controller-driver: + +Integrated Stepper Motion Control and Driver +############################################ + +Devices which comprise of both motion controller and a stepper driver in a single IC. These devices +have to be modelled as multi-functional-device in device tree, implementing both :c:group:`stepper_interface` +and :c:group:`stepper_drv_interface` APIs. An example of such a device is :dtcompatible:`adi,tmc50xx`. +:c:group:`stepper_interface` API is implemented by :dtcompatible:`adi,tmc50xx-stepper` and +:c:group:`stepper_drv_interface` API is implemented by :dtcompatible:`adi,tmc50xx-stepper-drv`. + +.. code-block:: dts + + / { + aliases { + x_axis_stepper_motor = &tmc50xx_0_motion_controller; + y_axis_stepper_motor = &tmc50xx_1_motion_controller; + x_axis_stepper_driver = &tmc50xx_0_stepper_driver; + y_axis_stepper_driver = &tmc50xx_1_stepper_driver; + }; + }; + + &spi0 { + /* SPI bus options here, not shown */ + + /* Dual controller/driver for up to two 2-phase bipolar stepper motors */ + tmc50xx: tmc50xx@0 { + compatible = "adi,tmc50xx"; + reg = <0>; + spi-max-frequency = ; /* Maximum SPI bus frequency */ + + poscmp-enable; test-mode; lock-gconf; /* ADI TMC Global configuration flags */ + clock-frequency = ; /* Internal/External Clock frequency */ + + /* DEVICE_API: stepper_drv api */ + tmc50xx_0_stepper_driver: tmc50xx_0_stepper_driver { + idx = <0>; + compatible = "adi,tmc50xx-stepper-drv"; + micro-step-res = <256>; + /* ADI TMC stallguard settings specific to TMC50XX */ + stallguard2-threshold=<30>; + }; + + /* DEVICE_API: stepper api */ + tmc50xx_0_motion_controller: tmc50xx_0_motion_controller { + idx = <0>; + compatible = "adi,tmc50xx-stepper"; + ... + vmax = <900000>; + amax = <50000>; + ... + activate-stallguard2; + ... + }; + + /* DEVICE_API: stepper_drv api */ + tmc50xx_1_stepper_driver: tmc50xx_1_stepper_driver { + idx = <1>; + compatible = "adi,tmc50xx-stepper-drv"; + micro-step-res = <256>; + /* ADI TMC stallguard settings specific to TMC50XX */ + stallguard2-threshold=<30>; + }; + + /* DEVICE_API: stepper api */ + tmc50xx_1_motion_controller: tmc50xx_1_motion_controller { + idx = <1>; + compatible = "adi,tmc50xx-stepper"; + ... + vstart = <1000>; + ... + stallguard-threshold-velocity=<200000>; + }; + }; + }; + +Following the aforementioned configurations, the stepper driver subsystem can be used in the application code +as follows: + +.. code-block:: c + + static const struct device *x_stepper = DEVICE_DT_GET(DT_ALIAS(x_axis_stepper_motor)); + static const struct device *x_stepper_drv = DEVICE_DT_GET(DT_ALIAS(x_axis_stepper_driver)); + static const struct device *y_stepper = DEVICE_DT_GET(DT_ALIAS(y_axis_stepper_motor)); + static const struct device *y_stepper_drv = DEVICE_DT_GET(DT_ALIAS(y_axis_stepper_driver)); + ... + stepper_move_to(x_stepper, 200); + stepper_stop(x_stepper); + stepper_drv_disable(x_stepper_drv); + stepper_drv_disable(y_stepper_drv); diff --git a/drivers/stepper/CMakeLists.txt b/drivers/stepper/CMakeLists.txt index 35879aa6a0b5..399201217cf3 100644 --- a/drivers/stepper/CMakeLists.txt +++ b/drivers/stepper/CMakeLists.txt @@ -7,13 +7,12 @@ zephyr_syscall_header(${ZEPHYR_BASE}/include/zephyr/drivers/stepper.h) add_subdirectory(adi_tmc) add_subdirectory(allegro) add_subdirectory(gpio_stepper) +add_subdirectory(step_dir) add_subdirectory(ti) # zephyr-keep-sorted-stop zephyr_library() zephyr_library_property(ALLOW_EMPTY TRUE) -# zephyr-keep-sorted-start zephyr_library_sources_ifdef(CONFIG_FAKE_STEPPER fake_stepper_controller.c) zephyr_library_sources_ifdef(CONFIG_STEPPER_SHELL stepper_shell.c) -# zephyr-keep-sorted-stop diff --git a/drivers/stepper/Kconfig b/drivers/stepper/Kconfig index 81c6114500b6..fd15cf287a09 100644 --- a/drivers/stepper/Kconfig +++ b/drivers/stepper/Kconfig @@ -31,6 +31,7 @@ rsource "Kconfig.fake" rsource "adi_tmc/Kconfig" rsource "allegro/Kconfig" rsource "gpio_stepper/Kconfig" +rsource "step_dir/Kconfig" rsource "ti/Kconfig" # zephyr-keep-sorted-stop diff --git a/drivers/stepper/Kconfig.fake b/drivers/stepper/Kconfig.fake index 942a556f1be2..1f08a01af0df 100644 --- a/drivers/stepper/Kconfig.fake +++ b/drivers/stepper/Kconfig.fake @@ -4,8 +4,8 @@ # SPDX-License-Identifier: Apache-2.0 config FAKE_STEPPER - bool "Fake stepper driver" + bool "Fake stepper and stepper_drv driver" default y - depends on DT_HAS_ZEPHYR_FAKE_STEPPER_ENABLED + depends on DT_HAS_ZEPHYR_FAKE_STEPPER_DRV_ENABLED || DT_HAS_ZEPHYR_FAKE_STEPPER_ENABLED help - Enable support for the FFF-based fake stepper driver. + Enable support for the FFF-based fake stepper controller & driver. diff --git a/drivers/stepper/adi_tmc/Kconfig.tmc_rampgen_template b/drivers/stepper/adi_tmc/Kconfig.tmc_rampgen_template index a357f8917d87..a3a79bd49067 100644 --- a/drivers/stepper/adi_tmc/Kconfig.tmc_rampgen_template +++ b/drivers/stepper/adi_tmc/Kconfig.tmc_rampgen_template @@ -3,7 +3,6 @@ config STEPPER_ADI_$(module)_RAMPSTAT_POLL_INTERVAL_IN_MSEC int "$(module-str) poll ramp status interval in ms" - depends on !$(dt_compat_any_has_prop,$(DT_COMPAT_ADI_$(module)),diag0-gpios) default 100 help When DIAG0 pin is not available, the driver automatically falls back to diff --git a/drivers/stepper/adi_tmc/tmc22xx/tmc22xx.c b/drivers/stepper/adi_tmc/tmc22xx/tmc22xx.c index 7d99a52203e4..97cc4203e61e 100644 --- a/drivers/stepper/adi_tmc/tmc22xx/tmc22xx.c +++ b/drivers/stepper/adi_tmc/tmc22xx/tmc22xx.c @@ -3,6 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include #include #include @@ -17,17 +18,16 @@ struct tmc22xx_config { const struct gpio_dt_spec enable_pin; struct gpio_dt_spec m0_pin; struct gpio_dt_spec m1_pin; - enum stepper_micro_step_resolution *msx_resolutions; + enum stepper_drv_micro_step_resolution *msx_resolutions; }; struct tmc22xx_data { - struct step_dir_stepper_common_data common; - enum stepper_micro_step_resolution resolution; + enum stepper_drv_micro_step_resolution resolution; }; -STEP_DIR_STEPPER_STRUCT_CHECK(struct tmc22xx_config, struct tmc22xx_data); +STEP_DIR_STEPPER_STRUCT_CHECK(struct tmc22xx_config); -static int tmc22xx_stepper_enable(const struct device *dev) +static int tmc22xx_enable(const struct device *dev) { const struct tmc22xx_config *config = dev->config; @@ -35,7 +35,7 @@ static int tmc22xx_stepper_enable(const struct device *dev) return gpio_pin_set_dt(&config->enable_pin, 1); } -static int tmc22xx_stepper_disable(const struct device *dev) +static int tmc22xx_disable(const struct device *dev) { const struct tmc22xx_config *config = dev->config; @@ -43,8 +43,8 @@ static int tmc22xx_stepper_disable(const struct device *dev) return gpio_pin_set_dt(&config->enable_pin, 0); } -static int tmc22xx_stepper_set_micro_step_res(const struct device *dev, - enum stepper_micro_step_resolution micro_step_res) +static int tmc22xx_set_micro_step_res(const struct device *dev, + enum stepper_drv_micro_step_resolution micro_step_res) { struct tmc22xx_data *data = dev->data; const struct tmc22xx_config *config = dev->config; @@ -79,11 +79,12 @@ static int tmc22xx_stepper_set_micro_step_res(const struct device *dev, } LOG_ERR("Unsupported microstep resolution: %d", micro_step_res); + return -ENOTSUP; } -static int tmc22xx_stepper_get_micro_step_res(const struct device *dev, - enum stepper_micro_step_resolution *micro_step_res) +static int tmc22xx_get_micro_step_res(const struct device *dev, + enum stepper_drv_micro_step_resolution *micro_step_res) { struct tmc22xx_data *data = dev->data; @@ -145,36 +146,21 @@ static int tmc22xx_stepper_init(const struct device *dev) return ret; } - ret = tmc22xx_stepper_set_micro_step_res(dev, data->resolution); + ret = tmc22xx_set_micro_step_res(dev, data->resolution); if (ret < 0) { LOG_ERR("Failed to set microstep resolution: %d", ret); return ret; } } - ret = step_dir_stepper_common_init(dev); - if (ret < 0) { - LOG_ERR("Failed to init step dir common stepper: %d", ret); - return ret; - } - return 0; } -static DEVICE_API(stepper, tmc22xx_stepper_api) = { - .enable = tmc22xx_stepper_enable, - .disable = tmc22xx_stepper_disable, - .move_by = step_dir_stepper_common_move_by, - .is_moving = step_dir_stepper_common_is_moving, - .set_reference_position = step_dir_stepper_common_set_reference_position, - .get_actual_position = step_dir_stepper_common_get_actual_position, - .move_to = step_dir_stepper_common_move_to, - .set_microstep_interval = step_dir_stepper_common_set_microstep_interval, - .run = step_dir_stepper_common_run, - .stop = step_dir_stepper_common_stop, - .set_event_callback = step_dir_stepper_common_set_event_callback, - .set_micro_step_res = tmc22xx_stepper_set_micro_step_res, - .get_micro_step_res = tmc22xx_stepper_get_micro_step_res, +static DEVICE_API(stepper_drv, tmc22xx_stepper_api) = { + .enable = tmc22xx_enable, + .disable = tmc22xx_disable, + .set_micro_step_res = tmc22xx_set_micro_step_res, + .get_micro_step_res = tmc22xx_get_micro_step_res, }; #define TMC22XX_STEPPER_DEFINE(inst, msx_table) \ @@ -186,7 +172,6 @@ static DEVICE_API(stepper, tmc22xx_stepper_api) = { .m1_pin = GPIO_DT_SPEC_INST_GET_OR(inst, m1_gpios, {0}), \ }; \ static struct tmc22xx_data tmc22xx_data_##inst = { \ - .common = STEP_DIR_STEPPER_DT_INST_COMMON_DATA_INIT(inst), \ .resolution = DT_INST_PROP(inst, micro_step_res), \ }; \ DEVICE_DT_INST_DEFINE(inst, tmc22xx_stepper_init, NULL, &tmc22xx_data_##inst, \ @@ -194,11 +179,11 @@ static DEVICE_API(stepper, tmc22xx_stepper_api) = { &tmc22xx_stepper_api); #define DT_DRV_COMPAT adi_tmc2209 -static enum stepper_micro_step_resolution tmc2209_msx_resolutions[MSX_PIN_STATE_COUNT] = { - STEPPER_MICRO_STEP_8, - STEPPER_MICRO_STEP_32, - STEPPER_MICRO_STEP_64, - STEPPER_MICRO_STEP_16, +static enum stepper_drv_micro_step_resolution tmc2209_msx_resolutions[MSX_PIN_STATE_COUNT] = { + STEPPER_DRV_MICRO_STEP_8, + STEPPER_DRV_MICRO_STEP_32, + STEPPER_DRV_MICRO_STEP_64, + STEPPER_DRV_MICRO_STEP_16, }; DT_INST_FOREACH_STATUS_OKAY_VARGS(TMC22XX_STEPPER_DEFINE, tmc2209_msx_resolutions) #undef DT_DRV_COMPAT diff --git a/drivers/stepper/adi_tmc/tmc50xx/CMakeLists.txt b/drivers/stepper/adi_tmc/tmc50xx/CMakeLists.txt index dd40d1f653ef..2e2d026182cf 100644 --- a/drivers/stepper/adi_tmc/tmc50xx/CMakeLists.txt +++ b/drivers/stepper/adi_tmc/tmc50xx/CMakeLists.txt @@ -1,4 +1,7 @@ +# SPDX-FileCopyrightText: Copyright (c) 2025 Dipak Shetty # SPDX-FileCopyrightText: Copyright (c) 2025 Jilay Sandeep Pandya # SPDX-License-Identifier: Apache-2.0 -zephyr_library_sources(tmc50xx.c) +zephyr_library_sources_ifdef(CONFIG_STEPPER_ADI_TMC50XX tmc50xx.c) +zephyr_library_sources_ifdef(CONFIG_STEPPER_ADI_TMC50XX_STEPPER tmc50xx_stepper.c) +zephyr_library_sources_ifdef(CONFIG_STEPPER_ADI_TMC50XX_STEPPER_DRV tmc50xx_stepper_drv.c) diff --git a/drivers/stepper/adi_tmc/tmc50xx/Kconfig.tmc50xx b/drivers/stepper/adi_tmc/tmc50xx/Kconfig.tmc50xx index 46589a2a9e3d..19ef19da0a7b 100644 --- a/drivers/stepper/adi_tmc/tmc50xx/Kconfig.tmc50xx +++ b/drivers/stepper/adi_tmc/tmc50xx/Kconfig.tmc50xx @@ -3,11 +3,21 @@ # SPDX-License-Identifier: Apache-2.0 config STEPPER_ADI_TMC50XX - bool "Activate trinamic tmc50xx stepper driver" + bool "Activate trinamic tmc50xx" depends on DT_HAS_ADI_TMC50XX_ENABLED select STEPPER_ADI_TMC_SPI default y +config STEPPER_ADI_TMC50XX_STEPPER + bool "Activate trinamic tmc50xx motion controller" + depends on DT_HAS_ADI_TMC50XX_STEPPER_ENABLED && STEPPER_ADI_TMC50XX + default y + +config STEPPER_ADI_TMC50XX_STEPPER_DRV + bool "Activate trinamic tmc50xx stepper driver" + depends on DT_HAS_ADI_TMC50XX_STEPPER_DRV_ENABLED && STEPPER_ADI_TMC50XX + default y + if STEPPER_ADI_TMC50XX module = TMC50XX diff --git a/drivers/stepper/adi_tmc/tmc50xx/tmc50xx.c b/drivers/stepper/adi_tmc/tmc50xx/tmc50xx.c index 2a2cdefe1960..8c45040d7daa 100644 --- a/drivers/stepper/adi_tmc/tmc50xx/tmc50xx.c +++ b/drivers/stepper/adi_tmc/tmc50xx/tmc50xx.c @@ -12,6 +12,7 @@ #include #include +#include "tmc50xx.h" #include #include @@ -19,41 +20,41 @@ LOG_MODULE_REGISTER(tmc50xx, CONFIG_STEPPER_LOG_LEVEL); struct tmc50xx_data { struct k_sem sem; + /* Work item to run the callback in a thread context. */ + struct k_work_delayable rampstat_callback_dwork; + const struct device *dev; + uint8_t work_index; }; struct tmc50xx_config { const uint32_t gconf; struct spi_dt_spec spi; const uint32_t clock_frequency; + const struct device **stepper_drivers; + uint8_t num_stepper_drivers; + const struct device **motion_controllers; + uint8_t num_motion_controllers; }; -struct tmc50xx_stepper_data { - struct k_work_delayable stallguard_dwork; - /* Work item to run the callback in a thread context. */ - struct k_work_delayable rampstat_callback_dwork; - /* device pointer required to access config in k_work */ - const struct device *stepper; - stepper_event_callback_t callback; - void *event_cb_user_data; -}; +int tmc50xx_read_actual_position(const struct device *dev, const uint8_t index, int32_t *position) +{ + int err; -struct tmc50xx_stepper_config { - const uint8_t index; - const uint16_t default_micro_step_res; - const int8_t sg_threshold; - const bool is_sg_enabled; - const uint32_t sg_velocity_check_interval_ms; - const uint32_t sg_threshold_velocity; - /* parent controller required for bus communication */ - const struct device *controller; -#ifdef CONFIG_STEPPER_ADI_TMC50XX_RAMP_GEN - const struct tmc_ramp_generator_data default_ramp_config; -#endif -}; + err = tmc50xx_read(dev, TMC50XX_XACTUAL(index), position); + if (err != 0) { + return -EIO; + } + return 0; +} + +int tmc50xx_get_clock_frequency(const struct device *dev) +{ + const struct tmc50xx_config *config = dev->config; -static int read_actual_position(const struct tmc50xx_stepper_config *config, int32_t *position); + return config->clock_frequency; +} -static int tmc50xx_write(const struct device *dev, const uint8_t reg_addr, const uint32_t reg_val) +int tmc50xx_write(const struct device *dev, const uint8_t reg_addr, const uint32_t reg_val) { const struct tmc50xx_config *config = dev->config; struct tmc50xx_data *data = dev->data; @@ -70,10 +71,11 @@ static int tmc50xx_write(const struct device *dev, const uint8_t reg_addr, const LOG_ERR("Failed to write register 0x%x with value 0x%x", reg_addr, reg_val); return err; } + return 0; } -static int tmc50xx_read(const struct device *dev, const uint8_t reg_addr, uint32_t *reg_val) +int tmc50xx_read(const struct device *dev, const uint8_t reg_addr, uint32_t *reg_val) { const struct tmc50xx_config *config = dev->config; struct tmc50xx_data *data = dev->data; @@ -90,171 +92,72 @@ static int tmc50xx_read(const struct device *dev, const uint8_t reg_addr, uint32 LOG_ERR("Failed to read register 0x%x", reg_addr); return err; } - return 0; -} - -static int tmc50xx_stepper_set_event_callback(const struct device *dev, - stepper_event_callback_t callback, void *user_data) -{ - struct tmc50xx_stepper_data *data = dev->data; - data->callback = callback; - data->event_cb_user_data = user_data; return 0; } -static int read_vactual(const struct tmc50xx_stepper_config *config, int32_t *actual_velocity) -{ - __ASSERT(actual_velocity != NULL, "actual_velocity pointer must not be NULL"); - int err; - - err = tmc50xx_read(config->controller, TMC50XX_VACTUAL(config->index), actual_velocity); - if (err) { - LOG_ERR("Failed to read VACTUAL register"); - return err; - } - - *actual_velocity = sign_extend(*actual_velocity, TMC_RAMP_VACTUAL_SHIFT); - if (actual_velocity) { - LOG_DBG("actual velocity: %d", *actual_velocity); - } - return 0; -} - -static int stallguard_enable(const struct device *dev, const bool enable) -{ - const struct tmc50xx_stepper_config *config = dev->config; - uint32_t reg_value; - int err; - - err = tmc50xx_read(config->controller, TMC50XX_SWMODE(config->index), ®_value); - if (err) { - LOG_ERR("Failed to read SWMODE register"); - return -EIO; - } - - if (enable) { - reg_value |= TMC5XXX_SW_MODE_SG_STOP_ENABLE; - - int32_t actual_velocity; - - err = read_vactual(config, &actual_velocity); - if (err) { - return -EIO; - } - if (abs(actual_velocity) < config->sg_threshold_velocity) { - return -EAGAIN; - } - } else { - reg_value &= ~TMC5XXX_SW_MODE_SG_STOP_ENABLE; - } - err = tmc50xx_write(config->controller, TMC50XX_SWMODE(config->index), reg_value); - if (err) { - LOG_ERR("Failed to write SWMODE register"); - return -EIO; - } - - LOG_DBG("Stallguard %s", enable ? "enabled" : "disabled"); - return 0; -} - -static void stallguard_work_handler(struct k_work *work) -{ - struct k_work_delayable *dwork = k_work_delayable_from_work(work); - struct tmc50xx_stepper_data *stepper_data = - CONTAINER_OF(dwork, struct tmc50xx_stepper_data, stallguard_dwork); - int err; - const struct tmc50xx_stepper_config *stepper_config = stepper_data->stepper->config; - - err = stallguard_enable(stepper_data->stepper, true); - if (err == -EAGAIN) { - k_work_reschedule(dwork, K_MSEC(stepper_config->sg_velocity_check_interval_ms)); - } - if (err == -EIO) { - LOG_ERR("Failed to enable stallguard because of I/O error"); - return; - } -} - -static void execute_callback(const struct device *dev, const enum stepper_event event) -{ - struct tmc50xx_stepper_data *data = dev->data; - - if (!data->callback) { - LOG_WRN_ONCE("No callback registered"); - return; - } - data->callback(dev, event, data->event_cb_user_data); -} - #ifdef CONFIG_STEPPER_ADI_TMC50XX_RAMPSTAT_POLL_STALLGUARD_LOG -static void log_stallguard(struct tmc50xx_stepper_data *stepper_data, const uint32_t drv_status) +static void log_stallguard(const struct device *dev, const uint32_t drv_status) { - const struct tmc50xx_stepper_config *stepper_config = stepper_data->stepper->config; int32_t position; int err; - err = read_actual_position(stepper_config, &position); + err = read_actual_position(dev, &position); if (err != 0) { - LOG_ERR("%s: Failed to read XACTUAL register", stepper_data->stepper->name); + LOG_ERR("%s: Failed to read XACTUAL register", dev->name); return; } - const uint8_t sg_result = FIELD_GET(TMC5XXX_DRV_STATUS_SG_RESULT_MASK, drv_status); - const bool sg_status = FIELD_GET(TMC5XXX_DRV_STATUS_SG_STATUS_MASK, drv_status); + __maybe_unused const uint8_t sg_result = + FIELD_GET(TMC5XXX_DRV_STATUS_SG_RESULT_MASK, drv_status); + __maybe_unused const bool sg_status = + FIELD_GET(TMC5XXX_DRV_STATUS_SG_STATUS_MASK, drv_status); - LOG_DBG("%s position: %d | sg result: %3d status: %d", - stepper_data->stepper->name, position, sg_result, sg_status); + LOG_DBG("%s position: %d | sg result: %3d status: %d", dev->name, position, sg_result, + sg_status); } #endif -static void rampstat_work_reschedule(struct k_work_delayable *rampstat_callback_dwork) +void tmc50xx_rampstat_work_reschedule(const struct device *dev) { - k_work_reschedule(rampstat_callback_dwork, - K_MSEC(CONFIG_STEPPER_ADI_TMC50XX_RAMPSTAT_POLL_INTERVAL_IN_MSEC)); + struct tmc50xx_data *data = dev->data; + + k_work_reschedule(&data->rampstat_callback_dwork, + K_MSEC(CONFIG_STEPPER_ADI_TMC50XX_RAMPSTAT_POLL_INTERVAL_IN_MSEC)); } -static void rampstat_work_handler(struct k_work *work) +static void rampstat_work(const struct device *dev) { - struct k_work_delayable *dwork = k_work_delayable_from_work(work); - - struct tmc50xx_stepper_data *stepper_data = - CONTAINER_OF(dwork, struct tmc50xx_stepper_data, rampstat_callback_dwork); - const struct tmc50xx_stepper_config *stepper_config = stepper_data->stepper->config; - - __ASSERT_NO_MSG(stepper_config->controller != NULL); - + struct tmc50xx_data *data = dev->data; + __maybe_unused const struct tmc50xx_config *config = dev->config; uint32_t drv_status; int err; - err = tmc50xx_read(stepper_config->controller, TMC50XX_DRVSTATUS(stepper_config->index), - &drv_status); + err = tmc50xx_read(dev, TMC50XX_DRVSTATUS(data->work_index), &drv_status); if (err != 0) { - LOG_ERR("%s: Failed to read DRVSTATUS register", stepper_data->stepper->name); + LOG_ERR("%s: Failed to read DRVSTATUS register", data->dev->name); return; } #ifdef CONFIG_STEPPER_ADI_TMC50XX_RAMPSTAT_POLL_STALLGUARD_LOG - log_stallguard(stepper_data, drv_status); + log_stallguard(dev, drv_status); #endif if (FIELD_GET(TMC5XXX_DRV_STATUS_SG_STATUS_MASK, drv_status) == 1U) { - LOG_INF("%s: Stall detected", stepper_data->stepper->name); - err = tmc50xx_write(stepper_config->controller, - TMC50XX_RAMPMODE(stepper_config->index), + LOG_INF("%s: Stall detected", data->dev->name); + err = tmc50xx_write(dev, TMC50XX_RAMPMODE(data->work_index), TMC5XXX_RAMPMODE_HOLD_MODE); if (err != 0) { - LOG_ERR("%s: Failed to stop motor", stepper_data->stepper->name); + LOG_ERR("%s: Failed to stop motor", data->dev->name); return; } } uint32_t rampstat_value; - err = tmc50xx_read(stepper_config->controller, TMC50XX_RAMPSTAT(stepper_config->index), - &rampstat_value); + err = tmc50xx_read(dev, TMC50XX_RAMPSTAT(data->work_index), &rampstat_value); if (err != 0) { - LOG_ERR("%s: Failed to read RAMPSTAT register", stepper_data->stepper->name); + LOG_ERR("%s: Failed to read RAMPSTAT register", data->dev->name); return; } @@ -262,377 +165,68 @@ static void rampstat_work_handler(struct k_work *work) if (ramp_stat_values > 0) { switch (ramp_stat_values) { - +#ifdef CONFIG_STEPPER_ADI_TMC50XX_STEPPER case TMC5XXX_STOP_LEFT_EVENT: - LOG_DBG("RAMPSTAT %s:Left end-stop detected", stepper_data->stepper->name); - execute_callback(stepper_data->stepper, - STEPPER_EVENT_LEFT_END_STOP_DETECTED); + LOG_DBG("RAMPSTAT %s:Left end-stop detected", data->dev->name); + tmc50xx_stepper_trigger_cb( + config->motion_controllers[data->work_index], + STEPPER_EVENT_LEFT_END_STOP_DETECTED); break; case TMC5XXX_STOP_RIGHT_EVENT: - LOG_DBG("RAMPSTAT %s:Right end-stop detected", stepper_data->stepper->name); - execute_callback(stepper_data->stepper, - STEPPER_EVENT_RIGHT_END_STOP_DETECTED); + LOG_DBG("RAMPSTAT %s:Right end-stop detected", data->dev->name); + tmc50xx_stepper_trigger_cb( + config->motion_controllers[data->work_index], + STEPPER_EVENT_RIGHT_END_STOP_DETECTED); break; case TMC5XXX_POS_REACHED_EVENT: case TMC5XXX_POS_REACHED: case TMC5XXX_POS_REACHED_AND_EVENT: - LOG_DBG("RAMPSTAT %s:Position reached", stepper_data->stepper->name); - execute_callback(stepper_data->stepper, STEPPER_EVENT_STEPS_COMPLETED); + LOG_DBG("RAMPSTAT %s:Position reached", data->dev->name); + tmc50xx_stepper_trigger_cb( + config->motion_controllers[data->work_index], + STEPPER_EVENT_STEPS_COMPLETED); break; - +#endif +#ifdef CONFIG_STEPPER_ADI_TMC50XX_STEPPER_DRV case TMC5XXX_STOP_SG_EVENT: - LOG_DBG("RAMPSTAT %s:Stall detected", stepper_data->stepper->name); - stallguard_enable(stepper_data->stepper, false); - execute_callback(stepper_data->stepper, STEPPER_EVENT_STALL_DETECTED); + LOG_DBG("RAMPSTAT %s:Stall detected", data->dev->name); + tmc50xx_stepper_stallguard_enable(data->dev, false); + tmc50xx_stepper_drv_trigger_cb(config->stepper_drivers[data->work_index], + STEPPER_DRV_EVENT_STALL_DETECTED); break; +#endif default: - LOG_ERR("Illegal ramp stat bit field"); + LOG_ERR("Illegal ramp stat bit field 0x%x", ramp_stat_values); break; } } else { - rampstat_work_reschedule(&stepper_data->rampstat_callback_dwork); - } -} - -static int tmc50xx_stepper_enable(const struct device *dev) -{ - LOG_DBG("Enabling Stepper motor controller %s", dev->name); - const struct tmc50xx_stepper_config *config = dev->config; - uint32_t reg_value; - int err; - - err = tmc50xx_read(config->controller, TMC50XX_CHOPCONF(config->index), ®_value); - if (err != 0) { - return -EIO; - } - - reg_value |= TMC5XXX_CHOPCONF_DRV_ENABLE_MASK; - - return tmc50xx_write(config->controller, TMC50XX_CHOPCONF(config->index), reg_value); -} - -static int tmc50xx_stepper_disable(const struct device *dev) -{ - LOG_DBG("Disabling Stepper motor controller %s", dev->name); - const struct tmc50xx_stepper_config *config = dev->config; - uint32_t reg_value; - int err; - - err = tmc50xx_read(config->controller, TMC50XX_CHOPCONF(config->index), ®_value); - if (err != 0) { - return -EIO; - } - - reg_value &= ~TMC5XXX_CHOPCONF_DRV_ENABLE_MASK; - - return tmc50xx_write(config->controller, TMC50XX_CHOPCONF(config->index), reg_value); -} - -static int tmc50xx_stepper_is_moving(const struct device *dev, bool *is_moving) -{ - const struct tmc50xx_stepper_config *config = dev->config; - uint32_t reg_value; - int err; - - err = tmc50xx_read(config->controller, TMC50XX_DRVSTATUS(config->index), ®_value); - - if (err != 0) { - LOG_ERR("%s: Failed to read DRVSTATUS register", dev->name); - return -EIO; - } - - *is_moving = (FIELD_GET(TMC5XXX_DRV_STATUS_STST_BIT, reg_value) != 1U); - LOG_DBG("Stepper motor controller %s is moving: %d", dev->name, *is_moving); - return 0; -} - -int tmc50xx_stepper_set_max_velocity(const struct device *dev, uint32_t velocity) -{ - const struct tmc50xx_stepper_config *config = dev->config; - const struct tmc50xx_config *tmc50xx_config = config->controller->config; - const uint32_t clock_frequency = tmc50xx_config->clock_frequency; - uint32_t velocity_fclk; - int err; - - velocity_fclk = tmc5xxx_calculate_velocity_from_hz_to_fclk(velocity, clock_frequency); - - err = tmc50xx_write(config->controller, TMC50XX_VMAX(config->index), velocity_fclk); - if (err != 0) { - LOG_ERR("%s: Failed to set max velocity", dev->name); - return -EIO; - } - return 0; -} - -static int tmc50xx_stepper_set_micro_step_res(const struct device *dev, - enum stepper_micro_step_resolution res) -{ - const struct tmc50xx_stepper_config *config = dev->config; - uint32_t reg_value; - int err; - - err = tmc50xx_read(config->controller, TMC50XX_CHOPCONF(config->index), ®_value); - if (err != 0) { - return -EIO; - } - - reg_value &= ~TMC5XXX_CHOPCONF_MRES_MASK; - reg_value |= ((MICRO_STEP_RES_INDEX(STEPPER_MICRO_STEP_256) - LOG2(res)) - << TMC5XXX_CHOPCONF_MRES_SHIFT); - - err = tmc50xx_write(config->controller, TMC50XX_CHOPCONF(config->index), reg_value); - if (err != 0) { - return -EIO; - } - - LOG_DBG("Stepper motor controller %s set micro step resolution to 0x%x", dev->name, - reg_value); - return 0; -} - -static int tmc50xx_stepper_get_micro_step_res(const struct device *dev, - enum stepper_micro_step_resolution *res) -{ - const struct tmc50xx_stepper_config *config = dev->config; - uint32_t reg_value; - int err; - - err = tmc50xx_read(config->controller, TMC50XX_CHOPCONF(config->index), ®_value); - if (err != 0) { - return -EIO; - } - reg_value &= TMC5XXX_CHOPCONF_MRES_MASK; - reg_value >>= TMC5XXX_CHOPCONF_MRES_SHIFT; - *res = (1 << (MICRO_STEP_RES_INDEX(STEPPER_MICRO_STEP_256) - reg_value)); - LOG_DBG("Stepper motor controller %s get micro step resolution: %d", dev->name, *res); - return 0; -} - -static int tmc50xx_stepper_set_reference_position(const struct device *dev, const int32_t position) -{ - const struct tmc50xx_stepper_config *config = dev->config; - int err; - - err = tmc50xx_write(config->controller, TMC50XX_RAMPMODE(config->index), - TMC5XXX_RAMPMODE_HOLD_MODE); - if (err != 0) { - return -EIO; - } - - err = tmc50xx_write(config->controller, TMC50XX_XACTUAL(config->index), position); - if (err != 0) { - return -EIO; - } - LOG_DBG("Stepper motor controller %s set actual position to %d", dev->name, position); - return 0; -} - -static int read_actual_position(const struct tmc50xx_stepper_config *config, int32_t *position) -{ - int err; - - err = tmc50xx_read(config->controller, TMC50XX_XACTUAL(config->index), position); - if (err != 0) { - return -EIO; + tmc50xx_rampstat_work_reschedule(dev); } - return 0; } -static int tmc50xx_stepper_get_actual_position(const struct device *dev, int32_t *position) -{ - const struct tmc50xx_stepper_config *config = dev->config; - int err; - - err = read_actual_position(config, position); - if (err != 0) { - return -EIO; - } - LOG_DBG("%s actual position: %d", dev->name, *position); - return 0; -} - -static int tmc50xx_stepper_move_to(const struct device *dev, const int32_t micro_steps) -{ - LOG_DBG("%s set target position to %d", dev->name, micro_steps); - const struct tmc50xx_stepper_config *config = dev->config; - struct tmc50xx_stepper_data *data = dev->data; - int err; - - if (config->is_sg_enabled) { - stallguard_enable(dev, false); - } - - err = tmc50xx_write(config->controller, TMC50XX_RAMPMODE(config->index), - TMC5XXX_RAMPMODE_POSITIONING_MODE); - if (err != 0) { - return -EIO; - } - err = tmc50xx_write(config->controller, TMC50XX_XTARGET(config->index), micro_steps); - if (err != 0) { - return -EIO; - } - - if (config->is_sg_enabled) { - k_work_reschedule(&data->stallguard_dwork, - K_MSEC(config->sg_velocity_check_interval_ms)); - } - if (data->callback) { - rampstat_work_reschedule(&data->rampstat_callback_dwork); - } - return 0; -} - -static int tmc50xx_stepper_move_by(const struct device *dev, const int32_t micro_steps) -{ - int err; - int32_t position; - - err = stepper_get_actual_position(dev, &position); - if (err != 0) { - return -EIO; - } - int32_t target_position = position + micro_steps; - - LOG_DBG("%s moved to %d by steps: %d", dev->name, target_position, micro_steps); - - return tmc50xx_stepper_move_to(dev, target_position); -} - -static int tmc50xx_stepper_run(const struct device *dev, const enum stepper_direction direction) -{ - LOG_DBG("Stepper motor controller %s run", dev->name); - const struct tmc50xx_stepper_config *config = dev->config; - struct tmc50xx_stepper_data *data = dev->data; - int err; - - if (config->is_sg_enabled) { - err = stallguard_enable(dev, false); - if (err != 0) { - return -EIO; - } - } - - switch (direction) { - case STEPPER_DIRECTION_POSITIVE: - err = tmc50xx_write(config->controller, TMC50XX_RAMPMODE(config->index), - TMC5XXX_RAMPMODE_POSITIVE_VELOCITY_MODE); - if (err != 0) { - return -EIO; - } - break; - - case STEPPER_DIRECTION_NEGATIVE: - err = tmc50xx_write(config->controller, TMC50XX_RAMPMODE(config->index), - TMC5XXX_RAMPMODE_NEGATIVE_VELOCITY_MODE); - if (err != 0) { - return -EIO; - } - break; - } - - if (config->is_sg_enabled) { - k_work_reschedule(&data->stallguard_dwork, - K_MSEC(config->sg_velocity_check_interval_ms)); - } - if (data->callback) { - rampstat_work_reschedule(&data->rampstat_callback_dwork); - } - return 0; -} - -static int tmc50xx_stepper_stop(const struct device *dev) -{ - const struct tmc50xx_stepper_config *config = dev->config; - int err; - - err = tmc50xx_write(config->controller, TMC50XX_RAMPMODE(config->index), - TMC5XXX_RAMPMODE_POSITIVE_VELOCITY_MODE); - if (err != 0) { - return -EIO; - } - - err = tmc50xx_write(config->controller, TMC50XX_VMAX(config->index), 0); - if (err != 0) { - return -EIO; - } - - return 0; -} - -#ifdef CONFIG_STEPPER_ADI_TMC50XX_RAMP_GEN - -int tmc50xx_stepper_set_ramp(const struct device *dev, - const struct tmc_ramp_generator_data *ramp_data) +static void rampstat_work_handler(struct k_work *work) { - LOG_DBG("Stepper motor controller %s set ramp", dev->name); - const struct tmc50xx_stepper_config *config = dev->config; - int err; + struct k_work_delayable *dwork = k_work_delayable_from_work(work); + struct tmc50xx_data *data = + CONTAINER_OF(dwork, struct tmc50xx_data, rampstat_callback_dwork); + const struct device *dev = data->dev; + const struct tmc50xx_config *config = dev->config; - err = tmc50xx_write(config->controller, TMC50XX_VSTART(config->index), ramp_data->vstart); - if (err != 0) { - return -EIO; - } - err = tmc50xx_write(config->controller, TMC50XX_A1(config->index), ramp_data->a1); - if (err != 0) { - return -EIO; - } - err = tmc50xx_write(config->controller, TMC50XX_AMAX(config->index), ramp_data->amax); - if (err != 0) { - return -EIO; - } - err = tmc50xx_write(config->controller, TMC50XX_D1(config->index), ramp_data->d1); - if (err != 0) { - return -EIO; - } - err = tmc50xx_write(config->controller, TMC50XX_DMAX(config->index), ramp_data->dmax); - if (err != 0) { - return -EIO; - } - err = tmc50xx_write(config->controller, TMC50XX_V1(config->index), ramp_data->v1); - if (err != 0) { - return -EIO; - } - err = tmc50xx_write(config->controller, TMC50XX_VMAX(config->index), ramp_data->vmax); - if (err != 0) { - return -EIO; - } - err = tmc50xx_write(config->controller, TMC50XX_VSTOP(config->index), ramp_data->vstop); - if (err != 0) { - return -EIO; - } - err = tmc50xx_write(config->controller, TMC50XX_TZEROWAIT(config->index), - ramp_data->tzerowait); - if (err != 0) { - return -EIO; - } - err = tmc50xx_write(config->controller, TMC50XX_VHIGH(config->index), ramp_data->vhigh); - if (err != 0) { - return -EIO; - } - err = tmc50xx_write(config->controller, TMC50XX_VCOOLTHRS(config->index), - ramp_data->vcoolthrs); - if (err != 0) { - return -EIO; - } - err = tmc50xx_write(config->controller, TMC50XX_IHOLD_IRUN(config->index), - ramp_data->iholdrun); - if (err != 0) { - return -EIO; + for (uint8_t i = 0; i < config->num_stepper_drivers; i++) { + data->work_index = tmc50xx_stepper_index(config->motion_controllers[i]); + rampstat_work(dev); } - return 0; } -#endif - static int tmc50xx_init(const struct device *dev) { - LOG_DBG("TMC50XX stepper motor controller %s initialized", dev->name); struct tmc50xx_data *data = dev->data; const struct tmc50xx_config *config = dev->config; int err; + LOG_DBG("Initializing TMC50XX stepper motor controller %s", dev->name); k_sem_init(&data->sem, 1, 1); if (!spi_is_ready_dt(&config->spi)) { @@ -655,125 +249,63 @@ static int tmc50xx_init(const struct device *dev) return -EIO; } - LOG_DBG("Device %s initialized", dev->name); - return 0; -} - -static int tmc50xx_stepper_init(const struct device *dev) -{ - const struct tmc50xx_stepper_config *stepper_config = dev->config; - struct tmc50xx_stepper_data *data = dev->data; - int err; - - LOG_DBG("Controller: %s, Stepper: %s", stepper_config->controller->name, dev->name); - - if (stepper_config->is_sg_enabled) { - k_work_init_delayable(&data->stallguard_dwork, stallguard_work_handler); - - err = tmc50xx_write(stepper_config->controller, - TMC50XX_SWMODE(stepper_config->index), BIT(10)); - if (err != 0) { - return -EIO; - } - - LOG_DBG("Setting stall guard to %d with delay %d ms", stepper_config->sg_threshold, - stepper_config->sg_velocity_check_interval_ms); - if (!IN_RANGE(stepper_config->sg_threshold, TMC5XXX_SG_MIN_VALUE, - TMC5XXX_SG_MAX_VALUE)) { - LOG_ERR("Stallguard threshold out of range"); - return -EINVAL; - } - - int32_t stall_guard_threshold = (int32_t)stepper_config->sg_threshold; - - err = tmc50xx_write( - stepper_config->controller, TMC50XX_COOLCONF(stepper_config->index), - stall_guard_threshold << TMC5XXX_COOLCONF_SG2_THRESHOLD_VALUE_SHIFT); - if (err != 0) { - return -EIO; + LOG_DBG("Num of motion controllers: %d %s", config->num_motion_controllers, + config->motion_controllers[0]->name); + for (uint8_t i = 0; i < config->num_stepper_drivers; i++) { + if (config->stepper_drivers[i] != NULL) { + LOG_DBG("Stepper driver %s", config->stepper_drivers[i]->name); } - k_work_reschedule(&data->stallguard_dwork, K_NO_WAIT); } -#ifdef CONFIG_STEPPER_ADI_TMC50XX_RAMP_GEN - err = tmc50xx_stepper_set_ramp(dev, &stepper_config->default_ramp_config); - if (err != 0) { - return -EIO; + for (uint8_t i = 0; i < config->num_motion_controllers; i++) { + if (config->motion_controllers[i] != NULL) { + LOG_DBG("Motion controller %s", config->motion_controllers[i]->name); + } } -#endif - k_work_init_delayable(&data->rampstat_callback_dwork, rampstat_work_handler); - rampstat_work_reschedule(&data->rampstat_callback_dwork); - err = tmc50xx_stepper_set_micro_step_res(dev, stepper_config->default_micro_step_res); - if (err != 0) { - return -EIO; - } + + LOG_DBG("Device %s initialized", dev->name); return 0; } -static DEVICE_API(stepper, tmc50xx_stepper_api) = { - .enable = tmc50xx_stepper_enable, - .disable = tmc50xx_stepper_disable, - .is_moving = tmc50xx_stepper_is_moving, - .move_by = tmc50xx_stepper_move_by, - .set_micro_step_res = tmc50xx_stepper_set_micro_step_res, - .get_micro_step_res = tmc50xx_stepper_get_micro_step_res, - .set_reference_position = tmc50xx_stepper_set_reference_position, - .get_actual_position = tmc50xx_stepper_get_actual_position, - .move_to = tmc50xx_stepper_move_to, - .run = tmc50xx_stepper_run, - .stop = tmc50xx_stepper_stop, - .set_event_callback = tmc50xx_stepper_set_event_callback, -}; - -#define TMC50XX_SHAFT_CONFIG(child) \ - (DT_PROP(child, invert_direction) << TMC50XX_GCONF_SHAFT_SHIFT(DT_REG_ADDR(child))) | - -#define TMC50XX_STEPPER_CONFIG_DEFINE(child) \ - COND_CODE_1(DT_PROP_EXISTS(child, stallguard_threshold_velocity), \ - BUILD_ASSERT(DT_PROP(child, stallguard_threshold_velocity), \ - "stallguard threshold velocity must be a positive value"), ()); \ - IF_ENABLED(CONFIG_STEPPER_ADI_TMC50XX_RAMP_GEN, (CHECK_RAMP_DT_DATA(child))); \ - static const struct tmc50xx_stepper_config tmc50xx_stepper_config_##child = { \ - .controller = DEVICE_DT_GET(DT_PARENT(child)), \ - .default_micro_step_res = DT_PROP(child, micro_step_res), \ - .index = DT_REG_ADDR(child), \ - .sg_threshold = DT_PROP(child, stallguard2_threshold), \ - .sg_threshold_velocity = DT_PROP(child, stallguard_threshold_velocity), \ - .sg_velocity_check_interval_ms = DT_PROP(child, \ - stallguard_velocity_check_interval_ms), \ - .is_sg_enabled = DT_PROP(child, activate_stallguard2), \ - IF_ENABLED(CONFIG_STEPPER_ADI_TMC50XX_RAMP_GEN, \ - (.default_ramp_config = TMC_RAMP_DT_SPEC_GET_TMC50XX(child))) }; - -#define TMC50XX_STEPPER_DATA_DEFINE(child) \ - static struct tmc50xx_stepper_data tmc50xx_stepper_data_##child = { \ - .stepper = DEVICE_DT_GET(child),}; - -#define TMC50XX_STEPPER_DEFINE(child) \ - DEVICE_DT_DEFINE(child, tmc50xx_stepper_init, NULL, &tmc50xx_stepper_data_##child, \ - &tmc50xx_stepper_config_##child, POST_KERNEL, \ - CONFIG_STEPPER_INIT_PRIORITY, &tmc50xx_stepper_api); - -#define TMC50XX_DEFINE(inst) \ - BUILD_ASSERT(DT_INST_CHILD_NUM(inst) <= 2, "tmc50xx can drive two steppers at max"); \ - BUILD_ASSERT((DT_INST_PROP(inst, clock_frequency) > 0), \ - "clock frequency must be non-zero positive value"); \ - static struct tmc50xx_data tmc50xx_data_##inst; \ - static const struct tmc50xx_config tmc50xx_config_##inst = { \ - .gconf = ( \ - (DT_INST_PROP(inst, poscmp_enable) << TMC50XX_GCONF_POSCMP_ENABLE_SHIFT) | \ - (DT_INST_PROP(inst, test_mode) << TMC50XX_GCONF_TEST_MODE_SHIFT) | \ - DT_INST_FOREACH_CHILD(inst, TMC50XX_SHAFT_CONFIG) \ - (DT_INST_PROP(inst, lock_gconf) << TMC50XX_LOCK_GCONF_SHIFT)), \ - .spi = SPI_DT_SPEC_INST_GET(inst, (SPI_OP_MODE_MASTER | SPI_TRANSFER_MSB | \ - SPI_MODE_CPOL | SPI_MODE_CPHA | SPI_WORD_SET(8))), \ - .clock_frequency = DT_INST_PROP(inst, clock_frequency),}; \ - DT_INST_FOREACH_CHILD(inst, TMC50XX_STEPPER_CONFIG_DEFINE); \ - DT_INST_FOREACH_CHILD(inst, TMC50XX_STEPPER_DATA_DEFINE); \ - DT_INST_FOREACH_CHILD(inst, TMC50XX_STEPPER_DEFINE); \ - DEVICE_DT_INST_DEFINE(inst, tmc50xx_init, NULL, &tmc50xx_data_##inst, \ - &tmc50xx_config_##inst, POST_KERNEL, CONFIG_STEPPER_INIT_PRIORITY,\ +#define TMC50XX_CHILD_DEVICES_ARRAY(inst, compat) \ + {DT_INST_FOREACH_CHILD_STATUS_OKAY_VARGS(inst, TMC50XX_CHILD_DEVICE_GET, compat)} + +#define TMC50XX_CHILD_DEVICE_GET(node_id, compat) \ + COND_CODE_1(DT_NODE_HAS_COMPAT(node_id, compat), (DEVICE_DT_GET(node_id),), ()) + +#define TMC50XX_DEFINE(inst) \ + static const struct device *tmc50xx_stepper_drivers_##inst[] = \ + TMC50XX_CHILD_DEVICES_ARRAY(inst, adi_tmc50xx_stepper_drv); \ + static const struct device *tmc50xx_motion_controllers_##inst[] = \ + TMC50XX_CHILD_DEVICES_ARRAY(inst, adi_tmc50xx_stepper); \ + BUILD_ASSERT(ARRAY_SIZE(tmc50xx_motion_controllers_##inst) <= 2, \ + "tmc50xx can drive two steppers at max"); \ + BUILD_ASSERT(ARRAY_SIZE(tmc50xx_stepper_drivers_##inst) <= 2, \ + "tmc50xx can drive two steppers at max"); \ + BUILD_ASSERT((DT_INST_PROP(inst, clock_frequency) > 0), \ + "clock frequency must be non-zero positive value"); \ + static struct tmc50xx_data tmc50xx_data_##inst = { \ + .dev = DEVICE_DT_GET(DT_DRV_INST(inst))}; \ + static const struct tmc50xx_config tmc50xx_config_##inst = { \ + .gconf = ((DT_INST_PROP(inst, poscmp_enable) \ + << TMC50XX_GCONF_POSCMP_ENABLE_SHIFT) | \ + (DT_INST_PROP(inst, test_mode) << TMC50XX_GCONF_TEST_MODE_SHIFT) | \ + DT_INST_PROP(inst, shaft1) << TMC50XX_GCONF_SHAFT_SHIFT(0) | \ + DT_INST_PROP(inst, shaft2) << TMC50XX_GCONF_SHAFT_SHIFT(1) | \ + (DT_INST_PROP(inst, lock_gconf) << TMC50XX_LOCK_GCONF_SHIFT)), \ + .spi = SPI_DT_SPEC_INST_GET(inst, \ + (SPI_OP_MODE_MASTER | SPI_TRANSFER_MSB | \ + SPI_MODE_CPOL | SPI_MODE_CPHA | SPI_WORD_SET(8))), \ + .clock_frequency = \ + DT_INST_PROP(inst, clock_frequency), /* Child device references */ \ + .stepper_drivers = tmc50xx_stepper_drivers_##inst, \ + .num_stepper_drivers = ARRAY_SIZE(tmc50xx_stepper_drivers_##inst), \ + .motion_controllers = tmc50xx_motion_controllers_##inst, \ + .num_motion_controllers = ARRAY_SIZE(tmc50xx_motion_controllers_##inst), \ + }; \ + DEVICE_DT_INST_DEFINE(inst, tmc50xx_init, NULL, &tmc50xx_data_##inst, \ + &tmc50xx_config_##inst, POST_KERNEL, CONFIG_STEPPER_INIT_PRIORITY, \ NULL); DT_INST_FOREACH_STATUS_OKAY(TMC50XX_DEFINE) diff --git a/drivers/stepper/adi_tmc/tmc50xx/tmc50xx.h b/drivers/stepper/adi_tmc/tmc50xx/tmc50xx.h new file mode 100644 index 000000000000..d07a27414b16 --- /dev/null +++ b/drivers/stepper/adi_tmc/tmc50xx/tmc50xx.h @@ -0,0 +1,90 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2025 Jilay Sandeep Pandya + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_STEPPER_ADI_TMC_TMC50XX_H_ +#define ZEPHYR_DRIVERS_STEPPER_ADI_TMC_TMC50XX_H_ + +#include +#include +#include + +/* + * @brief Write a value to a TMC50XX register. + * @param dev Pointer to the TMC50XX device. + * @param reg_addr Register address to write to. + * @param reg_val Value to write to the register. + * @retval -EIO on failure, 0 on success + */ +int tmc50xx_write(const struct device *dev, const uint8_t reg_addr, const uint32_t reg_val); + +/* + * @brief Read a value from a TMC50XX register. + * @param dev Pointer to the TMC50XX device. + * @param reg_addr Register address to read from. + * @param reg_val Pointer to store the read value. + * @retval -EIO on failure, 0 on success + */ +int tmc50xx_read(const struct device *dev, const uint8_t reg_addr, uint32_t *reg_val); + +/** + * @brief Trigger the registered callback for stepper events. + * + * @param dev Pointer to the TMC50XX stepper device. + * @param event The stepper event that occurred. + */ +void tmc50xx_stepper_trigger_cb(const struct device *dev, const enum stepper_event event); + +/** + * @brief Trigger the registered callback for stepper driver events. + * + * @param dev Pointer to the TMC50XX stepper driver device. + * @param event The stepper driver event that occurred. + */ +void tmc50xx_stepper_drv_trigger_cb(const struct device *dev, const enum stepper_drv_event event); + +/** + * @brief Enable or disable stallguard feature. + * + * @param dev Pointer to the TMC50XX stepper device. + * @param enable true to enable, false to disable + * @retval -EIO on failure, -EAGAIN if velocity is too low, 0 on success + */ +int tmc50xx_stepper_stallguard_enable(const struct device *dev, const bool enable); + +/** + * @brief Read the actual position from the TMC50XX device. + * + * @param dev Pointer to the TMC50XX device. + * @param index Index of the stepper motor (0 or 1). + * @param position Pointer to store the actual position in micro-steps. + * @retval -EIO on failure, 0 on success + */ +int tmc50xx_read_actual_position(const struct device *dev, const uint8_t index, int32_t *position); + +/** + * @brief Get the clock frequency in Hz of the TMC50XX device. + * + * @param dev Pointer to the TMC50XX device. + * @return Clock frequency in Hz + */ +int tmc50xx_get_clock_frequency(const struct device *dev); + +/** + * @brief Get the stepper index for the given device. + * + * @param dev Pointer to the TMC50XX stepper device. + * @return Index of the stepper (0 or 1) + */ +int tmc50xx_stepper_index(const struct device *dev); + +/** + * @brief Reschedule the ramp status work for the TMC50XX device. + * + * @param dev Pointer to the TMC50XX stepper device. + */ +void tmc50xx_rampstat_work_reschedule(const struct device *dev); + +#endif /* ZEPHYR_DRIVERS_STEPPER_ADI_TMC_TMC50XX_H_ */ diff --git a/drivers/stepper/adi_tmc/tmc50xx/tmc50xx_stepper.c b/drivers/stepper/adi_tmc/tmc50xx/tmc50xx_stepper.c new file mode 100644 index 000000000000..8de2a0a39721 --- /dev/null +++ b/drivers/stepper/adi_tmc/tmc50xx/tmc50xx_stepper.c @@ -0,0 +1,448 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2025 Dipak Shetty + * SPDX-FileCopyrightText: Copyright (c) 2025 Jilay Sandeep Pandya + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT adi_tmc50xx_stepper + +#include + +#include "tmc50xx.h" +#include + +#include +#include + +#include +LOG_MODULE_DECLARE(tmc50xx, CONFIG_STEPPER_LOG_LEVEL); + +struct tmc50xx_stepper_data { + struct k_work_delayable stallguard_dwork; + const struct device *dev; + stepper_event_callback_t callback; + void *event_cb_user_data; +}; + +struct tmc50xx_stepper_config { + const uint8_t index; + const bool is_sg_enabled; + const uint32_t sg_velocity_check_interval_ms; + const uint32_t sg_threshold_velocity; +#ifdef CONFIG_STEPPER_ADI_TMC50XX_RAMP_GEN + const struct tmc_ramp_generator_data default_ramp_config; +#endif + /* parent controller required for bus communication */ + const struct device *controller; +}; + +int tmc50xx_stepper_index(const struct device *dev) +{ + const struct tmc50xx_stepper_config *config = dev->config; + + return config->index; +} + +int tmc50xx_stepper_set_max_velocity(const struct device *dev, uint32_t velocity) +{ + const struct tmc50xx_stepper_config *config = dev->config; + const uint32_t clock_frequency = tmc50xx_get_clock_frequency(dev); + uint32_t velocity_fclk; + int err; + + velocity_fclk = tmc5xxx_calculate_velocity_from_hz_to_fclk(velocity, clock_frequency); + + err = tmc50xx_write(config->controller, TMC50XX_VMAX(config->index), velocity_fclk); + if (err != 0) { + LOG_ERR("%s: Failed to set max velocity", dev->name); + return -EIO; + } + return 0; +} + +static int read_vactual(const struct device *dev, int32_t *actual_velocity) +{ + __ASSERT(actual_velocity != NULL, "actual_velocity pointer must not be NULL"); + const struct tmc50xx_stepper_config *config = dev->config; + int err; + + err = tmc50xx_read(config->controller, TMC50XX_VACTUAL(config->index), actual_velocity); + if (err) { + LOG_ERR("Failed to read VACTUAL register"); + return err; + } + + *actual_velocity = sign_extend(*actual_velocity, TMC_RAMP_VACTUAL_SHIFT); + if (actual_velocity) { + LOG_DBG("actual velocity: %d", *actual_velocity); + } + return 0; +} + +static void stallguard_work_handler(struct k_work *work) +{ + struct k_work_delayable *dwork = k_work_delayable_from_work(work); + struct tmc50xx_stepper_data *data = + CONTAINER_OF(dwork, struct tmc50xx_stepper_data, stallguard_dwork); + const struct tmc50xx_stepper_config *config = data->dev->config; + int err; + + err = tmc50xx_stepper_stallguard_enable(data->dev, true); + if (err == -EAGAIN) { + k_work_reschedule(dwork, K_MSEC(config->sg_velocity_check_interval_ms)); + } + if (err == -EIO) { + LOG_ERR("Failed to enable stallguard because of I/O error"); + return; + } +} + +int tmc50xx_stepper_stallguard_enable(const struct device *dev, const bool enable) +{ + const struct tmc50xx_stepper_config *config = dev->config; + uint32_t reg_value; + int err; + + err = tmc50xx_read(config->controller, TMC50XX_SWMODE(config->index), ®_value); + if (err) { + LOG_ERR("Failed to read SWMODE register"); + return -EIO; + } + + if (enable) { + reg_value |= TMC5XXX_SW_MODE_SG_STOP_ENABLE; + + int32_t actual_velocity; + + err = read_vactual(dev, &actual_velocity); + if (err) { + return -EIO; + } + if (abs(actual_velocity) < config->sg_threshold_velocity) { + return -EAGAIN; + } + } else { + reg_value &= ~TMC5XXX_SW_MODE_SG_STOP_ENABLE; + } + err = tmc50xx_write(config->controller, TMC50XX_SWMODE(config->index), reg_value); + if (err) { + LOG_ERR("Failed to write SWMODE register"); + return -EIO; + } + + LOG_DBG("Stallguard %s", enable ? "enabled" : "disabled"); + return 0; +} + +void tmc50xx_stepper_trigger_cb(const struct device *dev, const enum stepper_event event) +{ + if (dev == NULL) { + return; + } + struct tmc50xx_stepper_data *data = dev->data; + + if (!data->callback) { + LOG_WRN_ONCE("No motion controller callback registered"); + return; + } + data->callback(dev, event, data->event_cb_user_data); +} + +static int tmc50xx_stepper_set_event_callback(const struct device *dev, + stepper_event_callback_t callback, + void *user_data) +{ + struct tmc50xx_stepper_data *data = dev->data; + + data->callback = callback; + data->event_cb_user_data = user_data; + + return 0; +} + +static int tmc50xx_stepper_is_moving(const struct device *dev, bool *is_moving) +{ + const struct tmc50xx_stepper_config *config = dev->config; + uint32_t reg_value; + int err; + + err = tmc50xx_read(config->controller, TMC50XX_DRVSTATUS(config->index), ®_value); + + if (err != 0) { + LOG_ERR("%s: Failed to read DRVSTATUS register", dev->name); + return -EIO; + } + + *is_moving = (FIELD_GET(TMC5XXX_DRV_STATUS_STST_BIT, reg_value) != 1U); + LOG_DBG("Stepper motor controller %s is moving: %d", dev->name, *is_moving); + return 0; +} + +static int tmc50xx_stepper_set_reference_position(const struct device *dev, const int32_t position) +{ + const struct tmc50xx_stepper_config *config = dev->config; + int err; + + err = tmc50xx_write(config->controller, TMC50XX_RAMPMODE(config->index), + TMC5XXX_RAMPMODE_HOLD_MODE); + if (err != 0) { + return -EIO; + } + + err = tmc50xx_write(config->controller, TMC50XX_XACTUAL(config->index), position); + if (err != 0) { + return -EIO; + } + LOG_DBG("Stepper motor controller %s set actual position to %d", dev->name, position); + return 0; +} + +static int tmc50xx_stepper_get_actual_position(const struct device *dev, int32_t *position) +{ + const struct tmc50xx_stepper_config *config = dev->config; + int err; + + err = tmc50xx_read_actual_position(config->controller, config->index, position); + if (err != 0) { + return -EIO; + } + LOG_DBG("%s actual position: %d", dev->name, *position); + return 0; +} + +static int tmc50xx_stepper_move_to(const struct device *dev, const int32_t micro_steps) +{ + const struct tmc50xx_stepper_config *config = dev->config; + struct tmc50xx_stepper_data *data = dev->data; + int err; + + LOG_DBG("%s set target position to %d", dev->name, micro_steps); + + if (config->is_sg_enabled) { + tmc50xx_stepper_stallguard_enable(dev, false); + } + + err = tmc50xx_write(config->controller, TMC50XX_RAMPMODE(config->index), + TMC5XXX_RAMPMODE_POSITIONING_MODE); + if (err != 0) { + return -EIO; + } + err = tmc50xx_write(config->controller, TMC50XX_XTARGET(config->index), micro_steps); + if (err != 0) { + return -EIO; + } + + if (config->is_sg_enabled) { + k_work_reschedule(&data->stallguard_dwork, + K_MSEC(config->sg_velocity_check_interval_ms)); + } + + if (data->callback) { + tmc50xx_rampstat_work_reschedule(config->controller); + } + return 0; +} + +static int tmc50xx_stepper_move_by(const struct device *dev, const int32_t micro_steps) +{ + int32_t position; + int err; + + err = tmc50xx_stepper_get_actual_position(dev, &position); + if (err != 0) { + return -EIO; + } + int32_t target_position = position + micro_steps; + + LOG_DBG("%s moved to %d by steps: %d", dev->name, target_position, micro_steps); + + return tmc50xx_stepper_move_to(dev, target_position); +} + +static int tmc50xx_stepper_run(const struct device *dev, const enum stepper_direction direction) +{ + const struct tmc50xx_stepper_config *config = dev->config; + struct tmc50xx_stepper_data *data = dev->data; + int err; + + LOG_DBG("Stepper motor controller %s run", dev->name); + + if (config->is_sg_enabled) { + err = tmc50xx_stepper_stallguard_enable(dev, false); + if (err != 0) { + return -EIO; + } + } + + switch (direction) { + case STEPPER_DIRECTION_POSITIVE: + err = tmc50xx_write(config->controller, TMC50XX_RAMPMODE(config->index), + TMC5XXX_RAMPMODE_POSITIVE_VELOCITY_MODE); + if (err != 0) { + return -EIO; + } + break; + + case STEPPER_DIRECTION_NEGATIVE: + err = tmc50xx_write(config->controller, TMC50XX_RAMPMODE(config->index), + TMC5XXX_RAMPMODE_NEGATIVE_VELOCITY_MODE); + if (err != 0) { + return -EIO; + } + break; + } + + if (config->is_sg_enabled) { + k_work_reschedule(&data->stallguard_dwork, + K_MSEC(config->sg_velocity_check_interval_ms)); + } + if (data->callback) { + tmc50xx_rampstat_work_reschedule(config->controller); + } + return 0; +} + +static int tmc50xx_stepper_stop(const struct device *dev) +{ + const struct tmc50xx_stepper_config *config = dev->config; + int err; + + err = tmc50xx_write(config->controller, TMC50XX_RAMPMODE(config->index), + TMC5XXX_RAMPMODE_POSITIVE_VELOCITY_MODE); + if (err != 0) { + return -EIO; + } + + err = tmc50xx_write(config->controller, TMC50XX_VMAX(config->index), 0); + if (err != 0) { + return -EIO; + } + + return 0; +} + +#ifdef CONFIG_STEPPER_ADI_TMC50XX_RAMP_GEN + +int tmc50xx_stepper_set_ramp(const struct device *dev, + const struct tmc_ramp_generator_data *ramp_data) +{ + const struct tmc50xx_stepper_config *config = dev->config; + const struct device *controller = config->controller; + int err; + + LOG_DBG("Stepper motor controller %s set ramp", dev->name); + + err = tmc50xx_write(controller, TMC50XX_VSTART(config->index), ramp_data->vstart); + if (err != 0) { + return -EIO; + } + err = tmc50xx_write(controller, TMC50XX_A1(config->index), ramp_data->a1); + if (err != 0) { + return -EIO; + } + err = tmc50xx_write(controller, TMC50XX_AMAX(config->index), ramp_data->amax); + if (err != 0) { + return -EIO; + } + err = tmc50xx_write(controller, TMC50XX_D1(config->index), ramp_data->d1); + if (err != 0) { + return -EIO; + } + err = tmc50xx_write(controller, TMC50XX_DMAX(config->index), ramp_data->dmax); + if (err != 0) { + return -EIO; + } + err = tmc50xx_write(controller, TMC50XX_V1(config->index), ramp_data->v1); + if (err != 0) { + return -EIO; + } + err = tmc50xx_write(controller, TMC50XX_VMAX(config->index), ramp_data->vmax); + if (err != 0) { + return -EIO; + } + err = tmc50xx_write(controller, TMC50XX_VSTOP(config->index), ramp_data->vstop); + if (err != 0) { + return -EIO; + } + err = tmc50xx_write(controller, TMC50XX_TZEROWAIT(config->index), ramp_data->tzerowait); + if (err != 0) { + return -EIO; + } + err = tmc50xx_write(controller, TMC50XX_VHIGH(config->index), ramp_data->vhigh); + if (err != 0) { + return -EIO; + } + err = tmc50xx_write(controller, TMC50XX_VCOOLTHRS(config->index), ramp_data->vcoolthrs); + if (err != 0) { + return -EIO; + } + err = tmc50xx_write(controller, TMC50XX_IHOLD_IRUN(config->index), ramp_data->iholdrun); + if (err != 0) { + return -EIO; + } + + return 0; +} + +#endif + +static int tmc50xx_stepper_init(const struct device *dev) +{ + const struct tmc50xx_stepper_config *config = dev->config; + struct tmc50xx_stepper_data *data = dev->data; + int err; + + LOG_DBG("Controller: %s, Motion Controller: %s", config->controller->name, dev->name); + data->dev = dev; + + if (config->is_sg_enabled) { + k_work_init_delayable(&data->stallguard_dwork, stallguard_work_handler); + + err = tmc50xx_write(config->controller, TMC50XX_SWMODE(config->index), BIT(10)); + if (err != 0) { + return -EIO; + } + + LOG_DBG("stallguard delay %d ms", config->sg_velocity_check_interval_ms); + k_work_reschedule(&data->stallguard_dwork, K_NO_WAIT); + } + +#ifdef CONFIG_STEPPER_ADI_TMC50XX_RAMP_GEN + err = tmc50xx_stepper_set_ramp(dev, &config->default_ramp_config); + if (err != 0) { + return -EIO; + } +#endif + return 0; +} + +static DEVICE_API(stepper, tmc50xx_stepper_api) = { + .is_moving = tmc50xx_stepper_is_moving, + .move_by = tmc50xx_stepper_move_by, + .set_reference_position = tmc50xx_stepper_set_reference_position, + .get_actual_position = tmc50xx_stepper_get_actual_position, + .move_to = tmc50xx_stepper_move_to, + .run = tmc50xx_stepper_run, + .stop = tmc50xx_stepper_stop, + .set_event_callback = tmc50xx_stepper_set_event_callback, +}; + +#define TMC50XX_STEPPER_DEFINE(inst) \ + IF_ENABLED(CONFIG_STEPPER_ADI_TMC50XX_RAMP_GEN, (CHECK_RAMP_DT_DATA(DT_DRV_INST(inst)))); \ + static const struct tmc50xx_stepper_config tmc50xx_stepper_cfg_##inst = { \ + .controller = DEVICE_DT_GET(DT_PARENT(DT_DRV_INST(inst))), \ + .index = DT_INST_PROP(inst, idx), \ + .sg_threshold_velocity = DT_INST_PROP(inst, stallguard_threshold_velocity), \ + .sg_velocity_check_interval_ms = \ + DT_INST_PROP(inst, stallguard_velocity_check_interval_ms), \ + .is_sg_enabled = DT_INST_PROP(inst, activate_stallguard2), \ + IF_ENABLED(CONFIG_STEPPER_ADI_TMC50XX_RAMP_GEN, \ + (.default_ramp_config = TMC_RAMP_DT_SPEC_GET_TMC50XX(DT_DRV_INST(inst)))) }; \ + static struct tmc50xx_stepper_data tmc50xx_stepper_data_##inst; \ + DEVICE_DT_INST_DEFINE(inst, tmc50xx_stepper_init, NULL, \ + &tmc50xx_stepper_data_##inst, \ + &tmc50xx_stepper_cfg_##inst, POST_KERNEL, \ + CONFIG_STEPPER_INIT_PRIORITY, &tmc50xx_stepper_api); + +DT_INST_FOREACH_STATUS_OKAY(TMC50XX_STEPPER_DEFINE) diff --git a/drivers/stepper/adi_tmc/tmc50xx/tmc50xx_stepper_drv.c b/drivers/stepper/adi_tmc/tmc50xx/tmc50xx_stepper_drv.c new file mode 100644 index 000000000000..d7c31f09d64b --- /dev/null +++ b/drivers/stepper/adi_tmc/tmc50xx/tmc50xx_stepper_drv.c @@ -0,0 +1,185 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2025 Dipak Shetty + * SPDX-FileCopyrightText: Copyright (c) 2025 Jilay Sandeep Pandya + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT adi_tmc50xx_stepper_drv + +#include "tmc50xx.h" +#include + +#include + +#include +LOG_MODULE_DECLARE(tmc50xx, CONFIG_STEPPER_LOG_LEVEL); + +struct tmc50xx_stepper_drv_data { + stepper_drv_event_cb_t drv_event_cb; + void *drv_event_cb_user_data; +}; + +struct tmc50xx_stepper_drv_config { + const uint8_t index; + const uint16_t default_micro_step_res; + const int8_t sg_threshold; + /* parent controller required for bus communication */ + const struct device *controller; +}; + +void tmc50xx_stepper_drv_trigger_cb(const struct device *dev, const enum stepper_drv_event event) +{ + if (dev == NULL) { + return; + } + + struct tmc50xx_stepper_drv_data *data = dev->data; + + if (!data->drv_event_cb) { + LOG_WRN_ONCE("No stepper driver callback registered"); + return; + } + + data->drv_event_cb(dev, event, data->drv_event_cb_user_data); +} + +static int tmc50xx_stepper_drv_set_event_callback(const struct device *stepper, + stepper_drv_event_cb_t callback, void *user_data) +{ + struct tmc50xx_stepper_drv_data *data = stepper->data; + + data->drv_event_cb = callback; + data->drv_event_cb_user_data = user_data; + + return 0; +} + +static int tmc50xx_stepper_drv_enable(const struct device *dev) +{ + LOG_DBG("Enabling Stepper motor controller %s", dev->name); + const struct tmc50xx_stepper_drv_config *config = dev->config; + uint32_t reg_value; + int err; + + err = tmc50xx_read(config->controller, TMC50XX_CHOPCONF(config->index), ®_value); + if (err != 0) { + return -EIO; + } + + reg_value |= TMC5XXX_CHOPCONF_DRV_ENABLE_MASK; + + return tmc50xx_write(config->controller, TMC50XX_CHOPCONF(config->index), reg_value); +} + +static int tmc50xx_stepper_drv_disable(const struct device *dev) +{ + LOG_DBG("Disabling Stepper motor controller %s", dev->name); + const struct tmc50xx_stepper_drv_config *config = dev->config; + uint32_t reg_value; + int err; + + err = tmc50xx_read(config->controller, TMC50XX_CHOPCONF(config->index), ®_value); + if (err != 0) { + return -EIO; + } + + reg_value &= ~TMC5XXX_CHOPCONF_DRV_ENABLE_MASK; + + return tmc50xx_write(config->controller, TMC50XX_CHOPCONF(config->index), reg_value); +} + +static int tmc50xx_stepper_drv_set_micro_step_res(const struct device *dev, + enum stepper_drv_micro_step_resolution res) +{ + const struct tmc50xx_stepper_drv_config *config = dev->config; + uint32_t reg_value; + int err; + + err = tmc50xx_read(config->controller, TMC50XX_CHOPCONF(config->index), ®_value); + if (err != 0) { + return -EIO; + } + + reg_value &= ~TMC5XXX_CHOPCONF_MRES_MASK; + reg_value |= ((MICRO_STEP_RES_INDEX(STEPPER_DRV_MICRO_STEP_256) - LOG2(res)) + << TMC5XXX_CHOPCONF_MRES_SHIFT); + + err = tmc50xx_write(config->controller, TMC50XX_CHOPCONF(config->index), reg_value); + if (err != 0) { + return -EIO; + } + + LOG_DBG("Stepper motor controller %s set micro step resolution to 0x%x", dev->name, + reg_value); + return 0; +} + +static int tmc50xx_stepper_drv_get_micro_step_res(const struct device *dev, + enum stepper_drv_micro_step_resolution *res) +{ + const struct tmc50xx_stepper_drv_config *config = dev->config; + uint32_t reg_value; + int err; + + err = tmc50xx_read(config->controller, TMC50XX_CHOPCONF(config->index), ®_value); + if (err != 0) { + return -EIO; + } + reg_value &= TMC5XXX_CHOPCONF_MRES_MASK; + reg_value >>= TMC5XXX_CHOPCONF_MRES_SHIFT; + *res = (1 << (MICRO_STEP_RES_INDEX(STEPPER_DRV_MICRO_STEP_256) - reg_value)); + LOG_DBG("Stepper motor controller %s get micro step resolution: %d", dev->name, *res); + return 0; +} + +static int tmc50xx_stepper_drv_init(const struct device *dev) +{ + const struct tmc50xx_stepper_drv_config *config = dev->config; + int err; + + LOG_DBG("Controller: %s, Stepper: %s", config->controller->name, dev->name); + if (!IN_RANGE(config->sg_threshold, TMC5XXX_SG_MIN_VALUE, TMC5XXX_SG_MAX_VALUE)) { + LOG_ERR("Stallguard threshold out of range"); + return -EINVAL; + } + + int32_t stall_guard_threshold = (int32_t)config->sg_threshold; + + err = tmc50xx_write(config->controller, TMC50XX_COOLCONF(config->index), + stall_guard_threshold << TMC5XXX_COOLCONF_SG2_THRESHOLD_VALUE_SHIFT); + if (err != 0) { + return -EIO; + } + err = tmc50xx_stepper_drv_set_micro_step_res(dev, config->default_micro_step_res); + if (err != 0) { + return -EIO; + } + LOG_DBG("Setting stallguard %d", config->sg_threshold); + return 0; +} + +static DEVICE_API(stepper_drv, tmc50xx_stepper_drv_api) = { + .enable = tmc50xx_stepper_drv_enable, + .disable = tmc50xx_stepper_drv_disable, + .set_micro_step_res = tmc50xx_stepper_drv_set_micro_step_res, + .get_micro_step_res = tmc50xx_stepper_drv_get_micro_step_res, + .set_event_cb = tmc50xx_stepper_drv_set_event_callback, +}; + +#define TMC50XX_STEPPER_DRV_DEFINE(inst) \ + COND_CODE_1(DT_PROP_EXISTS(inst, stallguard_threshold_velocity), \ + BUILD_ASSERT(DT_PROP(inst, stallguard_threshold_velocity), \ + "stallguard threshold velocity must be a positive value"), ()); \ + static const struct tmc50xx_stepper_drv_config tmc50xx_stepper_drv_config_##inst = { \ + .controller = DEVICE_DT_GET(DT_PARENT(DT_DRV_INST(inst))), \ + .default_micro_step_res = DT_INST_PROP(inst, micro_step_res), \ + .index = DT_INST_PROP(inst, idx), \ + .sg_threshold = DT_INST_PROP(inst, stallguard2_threshold), \ + }; \ + static struct tmc50xx_stepper_drv_data tmc50xx_stepper_drv_data_##inst; \ + DEVICE_DT_INST_DEFINE(inst, tmc50xx_stepper_drv_init, NULL, \ + &tmc50xx_stepper_drv_data_##inst, \ + &tmc50xx_stepper_drv_config_##inst, POST_KERNEL, \ + CONFIG_STEPPER_INIT_PRIORITY, &tmc50xx_stepper_drv_api); + +DT_INST_FOREACH_STATUS_OKAY(TMC50XX_STEPPER_DRV_DEFINE) diff --git a/drivers/stepper/adi_tmc/tmc51xx/CMakeLists.txt b/drivers/stepper/adi_tmc/tmc51xx/CMakeLists.txt index 5886e78a241a..39e85e8fc193 100644 --- a/drivers/stepper/adi_tmc/tmc51xx/CMakeLists.txt +++ b/drivers/stepper/adi_tmc/tmc51xx/CMakeLists.txt @@ -2,3 +2,5 @@ # SPDX-License-Identifier: Apache-2.0 zephyr_library_sources_ifdef(CONFIG_STEPPER_ADI_TMC51XX tmc51xx.c) +zephyr_library_sources_ifdef(CONFIG_STEPPER_ADI_TMC51XX_STEPPER tmc51xx_stepper.c) +zephyr_library_sources_ifdef(CONFIG_STEPPER_ADI_TMC51XX_STEPPER_DRV tmc51xx_stepper_drv.c) diff --git a/drivers/stepper/adi_tmc/tmc51xx/Kconfig.tmc51xx b/drivers/stepper/adi_tmc/tmc51xx/Kconfig.tmc51xx index db315fb9c208..a9567da99dd8 100644 --- a/drivers/stepper/adi_tmc/tmc51xx/Kconfig.tmc51xx +++ b/drivers/stepper/adi_tmc/tmc51xx/Kconfig.tmc51xx @@ -1,13 +1,24 @@ # SPDX-FileCopyrightText: Copyright (c) 2025 Prevas A/S +# SPDX-FileCopyrightText: Copyright (c) 2025 Jilay Sandeep Pandya # SPDX-License-Identifier: Apache-2.0 config STEPPER_ADI_TMC51XX - bool "Activate trinamic tmc51xx stepper driver" + bool "Activate trinamic tmc51xx" depends on DT_HAS_ADI_TMC51XX_ENABLED select STEPPER_ADI_TMC_UART if $(dt_compat_on_bus,$(DT_COMPAT_ADI_TMC51XX),uart) select STEPPER_ADI_TMC_SPI if $(dt_compat_on_bus,$(DT_COMPAT_ADI_TMC51XX),spi) default y +config STEPPER_ADI_TMC51XX_STEPPER + bool "Activate trinamic tmc51xx motion controller" + depends on DT_HAS_ADI_TMC51XX_STEPPER_ENABLED && STEPPER_ADI_TMC51XX + default y + +config STEPPER_ADI_TMC51XX_STEPPER_DRV + bool "Activate trinamic tmc51xx stepper driver" + depends on DT_HAS_ADI_TMC51XX_STEPPER_DRV_ENABLED && STEPPER_ADI_TMC51XX + default y + if STEPPER_ADI_TMC51XX module = TMC51XX diff --git a/drivers/stepper/adi_tmc/tmc51xx/tmc51xx.c b/drivers/stepper/adi_tmc/tmc51xx/tmc51xx.c index dc4272aa62b2..8b5703bf06bb 100644 --- a/drivers/stepper/adi_tmc/tmc51xx/tmc51xx.c +++ b/drivers/stepper/adi_tmc/tmc51xx/tmc51xx.c @@ -16,6 +16,8 @@ #include #include +#include "tmc51xx.h" + #include LOG_MODULE_REGISTER(tmc51xx, CONFIG_STEPPER_LOG_LEVEL); @@ -30,14 +32,6 @@ struct tmc51xx_config { uint8_t comm_type; const uint32_t gconf; const uint32_t clock_frequency; - const uint16_t default_micro_step_res; - const int8_t sg_threshold; - const bool is_sg_enabled; - const uint32_t sg_velocity_check_interval_ms; - const uint32_t sg_threshold_velocity; -#ifdef CONFIG_STEPPER_ADI_TMC51XX_RAMP_GEN - const struct tmc_ramp_generator_data default_ramp_config; -#endif #if TMC51XX_BUS_UART const struct gpio_dt_spec sw_sel_gpio; uint8_t uart_addr; @@ -45,16 +39,15 @@ struct tmc51xx_config { #if TMC51XX_BUS_SPI struct gpio_dt_spec diag0_gpio; #endif + const struct device *motion_controller; + const struct device *stepper_driver; }; struct tmc51xx_data { struct k_sem sem; - struct k_work_delayable stallguard_dwork; struct k_work_delayable rampstat_callback_dwork; struct gpio_callback diag0_cb; - const struct device *stepper; - stepper_event_callback_t callback; - void *event_cb_user_data; + const struct device *dev; }; #if TMC51XX_BUS_SPI @@ -155,187 +148,102 @@ static inline int tmc51xx_bus_check(const struct device *dev) return config->bus_io->check(&config->bus, config->comm_type); } -static int read_actual_position(const struct device *dev, int32_t *position); -static void rampstat_work_handler(struct k_work *work); -static void tmc51xx_diag0_gpio_callback_handler(const struct device *port, struct gpio_callback *cb, - gpio_port_pins_t pins); -static int rampstat_read_clear(const struct device *dev, uint32_t *rampstat_value); - -static int tmc51xx_write(const struct device *dev, const uint8_t reg_addr, const uint32_t reg_val) +int tmc51xx_get_clock_frequency(const struct device *dev) { const struct tmc51xx_config *config = dev->config; - struct tmc51xx_data *data = dev->data; - int err; - - k_sem_take(&data->sem, K_FOREVER); - err = config->bus_io->write(dev, reg_addr, reg_val); - - k_sem_give(&data->sem); - - if (err < 0) { - LOG_ERR("Failed to write register 0x%x with value 0x%x", reg_addr, reg_val); - return err; - } - return 0; + return config->clock_frequency; } -static int tmc51xx_read(const struct device *dev, const uint8_t reg_addr, uint32_t *reg_val) +int tmc51xx_read_actual_position(const struct device *dev, int32_t *position) { const struct tmc51xx_config *config = dev->config; - struct tmc51xx_data *data = dev->data; + const struct device *motion_controller = config->motion_controller; int err; + uint32_t raw_value; - k_sem_take(&data->sem, K_FOREVER); + /* Check if device is using UART and is currently moving */ + if (config->comm_type == TMC_COMM_UART) { + bool is_moving; - err = config->bus_io->read(dev, reg_addr, reg_val); + err = stepper_is_moving(motion_controller, &is_moving); + if (err != 0) { + return -EIO; + } - k_sem_give(&data->sem); + if (is_moving) { + LOG_WRN("%s: Reading position while moving over UART is not supported", + dev->name); + return -ENOTSUP; + } + } - if (err < 0) { - LOG_ERR("Failed to read register 0x%x", reg_addr); - return err; + err = tmc51xx_read(dev, TMC51XX_XACTUAL, &raw_value); + if (err != 0) { + return -EIO; } + + *position = sign_extend(raw_value, TMC_RAMP_XACTUAL_SHIFT); return 0; } -static int tmc51xx_stepper_set_event_callback(const struct device *dev, - stepper_event_callback_t callback, void *user_data) +bool tmc51xx_is_interrupt_driven(const struct device *dev) { - struct tmc51xx_data *data = dev->data; __maybe_unused const struct tmc51xx_config *config = dev->config; - __maybe_unused int err; - - data->callback = callback; - data->event_cb_user_data = user_data; - - /* Configure DIAG0 GPIO interrupt pin */ IF_ENABLED(TMC51XX_BUS_SPI, ({ - if ((config->comm_type == TMC_COMM_SPI) && config->diag0_gpio.port) { - LOG_INF("Configuring DIAG0 GPIO interrupt pin"); - if (!gpio_is_ready_dt(&config->diag0_gpio)) { - LOG_ERR("DIAG0 interrupt GPIO not ready"); - return -ENODEV; - } - - err = gpio_pin_configure_dt(&config->diag0_gpio, GPIO_INPUT); - if (err < 0) { - LOG_ERR("Could not configure DIAG0 GPIO (%d)", err); - return err; - } - k_work_init_delayable(&data->rampstat_callback_dwork, rampstat_work_handler); - - err = gpio_pin_interrupt_configure_dt(&config->diag0_gpio, GPIO_INT_EDGE_RISING); - if (err) { - LOG_ERR("failed to configure DIAG0 interrupt (err %d)", err); - return -EIO; - } - - /* Initialize and add GPIO callback */ - gpio_init_callback(&data->diag0_cb, tmc51xx_diag0_gpio_callback_handler, - BIT(config->diag0_gpio.pin)); - - err = gpio_add_callback(config->diag0_gpio.port, &data->diag0_cb); - if (err < 0) { - LOG_ERR("Could not add DIAG0 pin GPIO callback (%d)", err); - return -EIO; - } - - /* Clear any pending interrupts */ - uint32_t rampstat_value; - - err = rampstat_read_clear(dev, &rampstat_value); - if (err != 0) { - return -EIO; - } - }})) - - return 0; +if (config->comm_type == TMC_COMM_SPI && config->diag0_gpio.port) { + /* Using interrupt-driven approach - no polling needed */ + return true; +} +})) + return false; } -static int read_vactual(const struct device *dev, int32_t *actual_velocity) +void tmc51xx_reschedule_rampstat_callback(const struct device *dev) { - int err; - uint32_t raw_value; - - err = tmc51xx_read(dev, TMC51XX_VACTUAL, &raw_value); - if (err) { - LOG_ERR("Failed to read VACTUAL register"); - return err; - } + struct tmc51xx_data *data = dev->data; - *actual_velocity = sign_extend(raw_value, TMC_RAMP_VACTUAL_SHIFT); - if (*actual_velocity) { - LOG_DBG("actual velocity: %d", *actual_velocity); - } - return 0; + k_work_reschedule(&data->rampstat_callback_dwork, + K_MSEC(CONFIG_STEPPER_ADI_TMC51XX_RAMPSTAT_POLL_INTERVAL_IN_MSEC)); } -static int stallguard_enable(const struct device *dev, const bool enable) +int tmc51xx_write(const struct device *dev, const uint8_t reg_addr, const uint32_t reg_val) { const struct tmc51xx_config *config = dev->config; - uint32_t reg_value; + struct tmc51xx_data *data = dev->data; int err; - err = tmc51xx_read(dev, TMC51XX_SWMODE, ®_value); - if (err) { - LOG_ERR("Failed to read SWMODE register"); - return -EIO; - } + k_sem_take(&data->sem, K_FOREVER); - if (enable) { - reg_value |= TMC5XXX_SW_MODE_SG_STOP_ENABLE; + err = config->bus_io->write(dev, reg_addr, reg_val); - int32_t actual_velocity; + k_sem_give(&data->sem); - err = read_vactual(dev, &actual_velocity); - if (err) { - return -EIO; - } - if (abs(actual_velocity) < config->sg_threshold_velocity) { - return -EAGAIN; - } - } else { - reg_value &= ~TMC5XXX_SW_MODE_SG_STOP_ENABLE; - } - err = tmc51xx_write(dev, TMC51XX_SWMODE, reg_value); - if (err) { - LOG_ERR("Failed to write SWMODE register"); - return -EIO; + if (err < 0) { + LOG_ERR("Failed to write register 0x%x with value 0x%x", reg_addr, reg_val); + return err; } - - LOG_DBG("Stallguard %s", enable ? "enabled" : "disabled"); return 0; } -static void stallguard_work_handler(struct k_work *work) +int tmc51xx_read(const struct device *dev, const uint8_t reg_addr, uint32_t *reg_val) { - struct k_work_delayable *dwork = k_work_delayable_from_work(work); - struct tmc51xx_data const *stepper_data = - CONTAINER_OF(dwork, struct tmc51xx_data, stallguard_dwork); - const struct device *dev = stepper_data->stepper; const struct tmc51xx_config *config = dev->config; + struct tmc51xx_data *data = dev->data; int err; - err = stallguard_enable(dev, true); - if (err == -EAGAIN) { - k_work_reschedule(dwork, K_MSEC(config->sg_velocity_check_interval_ms)); - } - if (err == -EIO) { - LOG_ERR("Failed to enable stallguard because of I/O error"); - } -} + k_sem_take(&data->sem, K_FOREVER); -static void stepper_trigger_callback(const struct device *dev, const enum stepper_event event) -{ - struct tmc51xx_data *data = dev->data; + err = config->bus_io->read(dev, reg_addr, reg_val); - if (!data->callback) { - LOG_WRN_ONCE("No callback registered"); - return; + k_sem_give(&data->sem); + + if (err < 0) { + LOG_ERR("Failed to read register 0x%x", reg_addr); + return err; } - data->callback(dev, event, data->event_cb_user_data); + return 0; } #ifdef CONFIG_STEPPER_ADI_TMC51XX_RAMPSTAT_POLL_STALLGUARD_LOG @@ -377,8 +285,10 @@ static void rampstat_work_handler(struct k_work *work) struct tmc51xx_data *stepper_data = CONTAINER_OF(dwork, struct tmc51xx_data, rampstat_callback_dwork); - const struct device *dev = stepper_data->stepper; + const struct device *dev = stepper_data->dev; __maybe_unused const struct tmc51xx_config *config = dev->config; + const struct device *motion_controller = config->motion_controller; + const struct device *stepper_driver = config->stepper_driver; __ASSERT_NO_MSG(dev); @@ -414,28 +324,35 @@ static void rampstat_work_handler(struct k_work *work) if (ramp_stat_values > 0) { switch (ramp_stat_values) { +#ifdef CONFIG_STEPPER_ADI_TMC51XX_STEPPER case TMC5XXX_STOP_LEFT_EVENT: LOG_DBG("RAMPSTAT %s:Left end-stop detected", dev->name); - stepper_trigger_callback(dev, STEPPER_EVENT_LEFT_END_STOP_DETECTED); + tmc51xx_stepper_trigger_cb(motion_controller, + STEPPER_EVENT_LEFT_END_STOP_DETECTED); break; case TMC5XXX_STOP_RIGHT_EVENT: LOG_DBG("RAMPSTAT %s:Right end-stop detected", dev->name); - stepper_trigger_callback(dev, STEPPER_EVENT_RIGHT_END_STOP_DETECTED); + tmc51xx_stepper_trigger_cb(motion_controller, + STEPPER_EVENT_RIGHT_END_STOP_DETECTED); break; case TMC5XXX_POS_REACHED_EVENT: case TMC5XXX_POS_REACHED: case TMC5XXX_POS_REACHED_AND_EVENT: LOG_DBG("RAMPSTAT %s:Position reached", dev->name); - stepper_trigger_callback(dev, STEPPER_EVENT_STEPS_COMPLETED); + tmc51xx_stepper_trigger_cb(motion_controller, + STEPPER_EVENT_STEPS_COMPLETED); break; - +#endif /* CONFIG_STEPPER_ADI_TMC51XX_STEPPER */ +#ifdef CONFIG_STEPPER_ADI_TMC51XX_STEPPER_DRV case TMC5XXX_STOP_SG_EVENT: LOG_DBG("RAMPSTAT %s:Stall detected", dev->name); - stallguard_enable(dev, false); - stepper_trigger_callback(dev, STEPPER_EVENT_STALL_DETECTED); + tmc51xx_stepper_stallguard_enable(dev, false); + tmc51xx_stepper_drv_trigger_cb(stepper_driver, + STEPPER_DRV_EVENT_STALL_DETECTED); break; +#endif /* CONFIG_STEPPER_ADI_TMC51XX_STEPPER_DRV */ default: LOG_ERR("Illegal ramp stat bit field 0x%x", ramp_stat_values); break; @@ -470,362 +387,14 @@ static void __maybe_unused tmc51xx_diag0_gpio_callback_handler(const struct devi k_work_reschedule(&stepper_data->rampstat_callback_dwork, K_NO_WAIT); } -static int tmc51xx_stepper_enable(const struct device *dev) -{ - LOG_DBG("Enabling Stepper motor controller %s", dev->name); - uint32_t reg_value; - int err; - - err = tmc51xx_read(dev, TMC51XX_CHOPCONF, ®_value); - if (err != 0) { - return -EIO; - } - - reg_value |= TMC5XXX_CHOPCONF_DRV_ENABLE_MASK; - - return tmc51xx_write(dev, TMC51XX_CHOPCONF, reg_value); -} - -static int tmc51xx_stepper_disable(const struct device *dev) -{ - LOG_DBG("Disabling Stepper motor controller %s", dev->name); - uint32_t reg_value; - int err; - - err = tmc51xx_read(dev, TMC51XX_CHOPCONF, ®_value); - if (err != 0) { - return -EIO; - } - - reg_value &= ~TMC5XXX_CHOPCONF_DRV_ENABLE_MASK; - - return tmc51xx_write(dev, TMC51XX_CHOPCONF, reg_value); -} - -static int tmc51xx_stepper_is_moving(const struct device *dev, bool *is_moving) -{ - uint32_t reg_value; - int err; - - err = tmc51xx_read(dev, TMC51XX_DRVSTATUS, ®_value); - - if (err != 0) { - LOG_ERR("%s: Failed to read DRVSTATUS register", dev->name); - return -EIO; - } - - *is_moving = (FIELD_GET(TMC5XXX_DRV_STATUS_STST_BIT, reg_value) != 1U); - LOG_DBG("Stepper motor controller %s is moving: %d", dev->name, *is_moving); - return 0; -} - -int tmc51xx_stepper_set_max_velocity(const struct device *dev, uint32_t velocity) -{ - const struct tmc51xx_config *config = dev->config; - const uint32_t clock_frequency = config->clock_frequency; - uint32_t velocity_fclk; - int err; - - velocity_fclk = tmc5xxx_calculate_velocity_from_hz_to_fclk(velocity, clock_frequency); - - err = tmc51xx_write(dev, TMC51XX_VMAX, velocity_fclk); - if (err != 0) { - LOG_ERR("%s: Failed to set max velocity", dev->name); - return -EIO; - } - return 0; -} - -static int tmc51xx_stepper_set_micro_step_res(const struct device *dev, - enum stepper_micro_step_resolution res) -{ - uint32_t reg_value; - int err; - - err = tmc51xx_read(dev, TMC51XX_CHOPCONF, ®_value); - if (err != 0) { - return -EIO; - } - - reg_value &= ~TMC5XXX_CHOPCONF_MRES_MASK; - reg_value |= ((MICRO_STEP_RES_INDEX(STEPPER_MICRO_STEP_256) - LOG2(res)) - << TMC5XXX_CHOPCONF_MRES_SHIFT); - - err = tmc51xx_write(dev, TMC51XX_CHOPCONF, reg_value); - if (err != 0) { - return -EIO; - } - - LOG_DBG("Stepper motor controller %s set micro step resolution to 0x%x", dev->name, - reg_value); - return 0; -} - -static int tmc51xx_stepper_get_micro_step_res(const struct device *dev, - enum stepper_micro_step_resolution *res) -{ - uint32_t reg_value; - int err; - - err = tmc51xx_read(dev, TMC51XX_CHOPCONF, ®_value); - if (err != 0) { - return -EIO; - } - reg_value &= TMC5XXX_CHOPCONF_MRES_MASK; - reg_value >>= TMC5XXX_CHOPCONF_MRES_SHIFT; - *res = (1 << (MICRO_STEP_RES_INDEX(STEPPER_MICRO_STEP_256) - reg_value)); - LOG_DBG("Stepper motor controller %s get micro step resolution: %d", dev->name, *res); - return 0; -} - -static int tmc51xx_stepper_set_reference_position(const struct device *dev, const int32_t position) -{ - int err; - - err = tmc51xx_write(dev, TMC51XX_RAMPMODE, TMC5XXX_RAMPMODE_HOLD_MODE); - if (err != 0) { - return -EIO; - } - - err = tmc51xx_write(dev, TMC51XX_XACTUAL, position); - if (err != 0) { - return -EIO; - } - LOG_DBG("Stepper motor controller %s set actual position to %d", dev->name, position); - return 0; -} - -static int read_actual_position(const struct device *dev, int32_t *position) -{ - const struct tmc51xx_config *config = dev->config; - - int err; - uint32_t raw_value; - - /* Check if device is using UART and is currently moving */ - if (config->comm_type == TMC_COMM_UART) { - bool is_moving; - - err = tmc51xx_stepper_is_moving(dev, &is_moving); - if (err != 0) { - return -EIO; - } - - if (is_moving) { - LOG_WRN("%s: Reading position while moving over UART is not supported", - dev->name); - return -ENOTSUP; - } - } - - err = tmc51xx_read(dev, TMC51XX_XACTUAL, &raw_value); - if (err != 0) { - return -EIO; - } - - *position = sign_extend(raw_value, TMC_RAMP_XACTUAL_SHIFT); - return 0; -} - -static int tmc51xx_stepper_get_actual_position(const struct device *dev, int32_t *position) -{ - int err; - - err = read_actual_position(dev, position); - if (err != 0) { - return -EIO; - } - LOG_DBG("%s actual position: %d", dev->name, *position); - return 0; -} - -static int tmc51xx_stepper_move_to(const struct device *dev, const int32_t micro_steps) -{ - LOG_DBG("%s set target position to %d", dev->name, micro_steps); - const struct tmc51xx_config *config = dev->config; - struct tmc51xx_data *data = dev->data; - int err; - - if (config->is_sg_enabled) { - stallguard_enable(dev, false); - } - - err = tmc51xx_write(dev, TMC51XX_RAMPMODE, TMC5XXX_RAMPMODE_POSITIONING_MODE); - if (err != 0) { - return -EIO; - } - err = tmc51xx_write(dev, TMC51XX_XTARGET, micro_steps); - if (err != 0) { - return -EIO; - } - - if (config->is_sg_enabled) { - k_work_reschedule(&data->stallguard_dwork, - K_MSEC(config->sg_velocity_check_interval_ms)); - } - if (data->callback) { - /* For SPI with DIAG0 pin, we use interrupt-driven approach */ - IF_ENABLED(TMC51XX_BUS_SPI, ({ - if (config->comm_type == TMC_COMM_SPI && config->diag0_gpio.port) { - /* Using interrupt-driven approach - no polling needed */ - return 0; - } - })) - - /* For UART or SPI without DIAG0, reschedule RAMPSTAT polling */ -#ifdef CONFIG_STEPPER_ADI_TMC51XX_RAMPSTAT_POLL_INTERVAL_IN_MSEC - k_work_reschedule( - &data->rampstat_callback_dwork, - K_MSEC(CONFIG_STEPPER_ADI_TMC51XX_RAMPSTAT_POLL_INTERVAL_IN_MSEC)); -#endif /* CONFIG_STEPPER_ADI_TMC51XX_RAMPSTAT_POLL_INTERVAL_IN_MSEC */ - } - return 0; -} - -static int tmc51xx_stepper_move_by(const struct device *dev, const int32_t micro_steps) -{ - int err; - int32_t position; - - err = tmc51xx_stepper_get_actual_position(dev, &position); - if (err != 0) { - return -EIO; - } - int32_t target_position = position + micro_steps; - - LOG_DBG("%s moved to %d by steps: %d", dev->name, target_position, micro_steps); - - return tmc51xx_stepper_move_to(dev, target_position); -} - -static int tmc51xx_stepper_run(const struct device *dev, const enum stepper_direction direction) +static int tmc51xx_init(const struct device *dev) { - LOG_DBG("Stepper motor controller %s run", dev->name); const struct tmc51xx_config *config = dev->config; struct tmc51xx_data *data = dev->data; int err; - if (config->is_sg_enabled) { - err = stallguard_enable(dev, false); - if (err != 0) { - return -EIO; - } - } - - switch (direction) { - case STEPPER_DIRECTION_POSITIVE: - err = tmc51xx_write(dev, TMC51XX_RAMPMODE, TMC5XXX_RAMPMODE_POSITIVE_VELOCITY_MODE); - if (err != 0) { - return -EIO; - } - break; - - case STEPPER_DIRECTION_NEGATIVE: - err = tmc51xx_write(dev, TMC51XX_RAMPMODE, TMC5XXX_RAMPMODE_NEGATIVE_VELOCITY_MODE); - if (err != 0) { - return -EIO; - } - break; - } - - if (config->is_sg_enabled) { - k_work_reschedule(&data->stallguard_dwork, - K_MSEC(config->sg_velocity_check_interval_ms)); - } - if (data->callback) { - /* For SPI with DIAG0 pin, we use interrupt-driven approach */ - IF_ENABLED(TMC51XX_BUS_SPI, ({ - if (config->comm_type == TMC_COMM_SPI && config->diag0_gpio.port) { - /* Using interrupt-driven approach - no polling needed */ - return 0; - } - })) - - /* For UART or SPI without DIAG0, reschedule RAMPSTAT polling */ -#ifdef CONFIG_STEPPER_ADI_TMC51XX_RAMPSTAT_POLL_INTERVAL_IN_MSEC - k_work_reschedule( - &data->rampstat_callback_dwork, - K_MSEC(CONFIG_STEPPER_ADI_TMC51XX_RAMPSTAT_POLL_INTERVAL_IN_MSEC)); -#endif /* CONFIG_STEPPER_ADI_TMC51XX_RAMPSTAT_POLL_INTERVAL_IN_MSEC */ - } - return 0; -} - -#ifdef CONFIG_STEPPER_ADI_TMC51XX_RAMP_GEN - -int tmc51xx_stepper_set_ramp(const struct device *dev, - const struct tmc_ramp_generator_data *ramp_data) -{ - LOG_DBG("Stepper motor controller %s set ramp", dev->name); - int err; - - err = tmc51xx_write(dev, TMC51XX_VSTART, ramp_data->vstart); - if (err != 0) { - return -EIO; - } - err = tmc51xx_write(dev, TMC51XX_A1, ramp_data->a1); - if (err != 0) { - return -EIO; - } - err = tmc51xx_write(dev, TMC51XX_AMAX, ramp_data->amax); - if (err != 0) { - return -EIO; - } - err = tmc51xx_write(dev, TMC51XX_D1, ramp_data->d1); - if (err != 0) { - return -EIO; - } - err = tmc51xx_write(dev, TMC51XX_DMAX, ramp_data->dmax); - if (err != 0) { - return -EIO; - } - err = tmc51xx_write(dev, TMC51XX_V1, ramp_data->v1); - if (err != 0) { - return -EIO; - } - err = tmc51xx_write(dev, TMC51XX_VMAX, ramp_data->vmax); - if (err != 0) { - return -EIO; - } - err = tmc51xx_write(dev, TMC51XX_VSTOP, ramp_data->vstop); - if (err != 0) { - return -EIO; - } - err = tmc51xx_write(dev, TMC51XX_TZEROWAIT, ramp_data->tzerowait); - if (err != 0) { - return -EIO; - } - err = tmc51xx_write(dev, TMC51XX_THIGH, ramp_data->thigh); - if (err != 0) { - return -EIO; - } - err = tmc51xx_write(dev, TMC51XX_TCOOLTHRS, ramp_data->tcoolthrs); - if (err != 0) { - return -EIO; - } - err = tmc51xx_write(dev, TMC51XX_TPWMTHRS, ramp_data->tpwmthrs); - if (err != 0) { - return -EIO; - } - err = tmc51xx_write(dev, TMC51XX_TPOWER_DOWN, ramp_data->tpowerdown); - if (err != 0) { - return -EIO; - } - err = tmc51xx_write(dev, TMC51XX_IHOLD_IRUN, ramp_data->iholdrun); - if (err != 0) { - return -EIO; - } - return 0; -} - -#endif - -static int tmc51xx_init(const struct device *dev) -{ - LOG_DBG("TMC51XX stepper motor controller %s initialized", dev->name); - struct tmc51xx_data *data = dev->data; - const struct tmc51xx_config *config = dev->config; - int err; + LOG_DBG("Initializing TMC51XX stepper motor controller %s, stepper motor driver %s", + config->motion_controller->name, config->stepper_driver->name); k_sem_init(&data->sem, 1, 1); @@ -851,107 +420,84 @@ static int tmc51xx_init(const struct device *dev) } #endif - LOG_DBG("GCONF: %d", config->gconf); - err = tmc51xx_write(dev, TMC5XXX_GCONF, config->gconf); - if (err != 0) { - return -EIO; - } - - /* Read and write GSTAT register to clear any SPI Datagram errors. */ - uint32_t gstat_value; - - err = tmc51xx_read(dev, TMC5XXX_GSTAT, &gstat_value); - if (err != 0) { - return -EIO; - } - - err = tmc51xx_write(dev, TMC5XXX_GSTAT, gstat_value); - if (err != 0) { - return -EIO; - } + /* Configure DIAG0 GPIO interrupt pin */ + IF_ENABLED(TMC51XX_BUS_SPI, ({ + if ((config->comm_type == TMC_COMM_SPI) && config->diag0_gpio.port) { + LOG_INF("Configuring DIAG0 GPIO interrupt pin"); + if (!gpio_is_ready_dt(&config->diag0_gpio)) { + LOG_ERR("DIAG0 interrupt GPIO not ready"); + return -ENODEV; + } - if (config->is_sg_enabled) { - k_work_init_delayable(&data->stallguard_dwork, stallguard_work_handler); + err = gpio_pin_configure_dt(&config->diag0_gpio, GPIO_INPUT); + if (err < 0) { + LOG_ERR("Could not configure DIAG0 GPIO (%d)", err); + return err; + } + k_work_init_delayable(&data->rampstat_callback_dwork, rampstat_work_handler); - err = tmc51xx_write(dev, TMC51XX_SWMODE, BIT(10)); - if (err != 0) { + err = gpio_pin_interrupt_configure_dt(&config->diag0_gpio, GPIO_INT_EDGE_RISING); + if (err) { + LOG_ERR("failed to configure DIAG0 interrupt (err %d)", err); return -EIO; } - LOG_DBG("Setting stall guard to %d with delay %d ms", config->sg_threshold, - config->sg_velocity_check_interval_ms); - if (!IN_RANGE(config->sg_threshold, TMC5XXX_SG_MIN_VALUE, TMC5XXX_SG_MAX_VALUE)) { - LOG_ERR("Stallguard threshold out of range"); - return -EINVAL; + /* Initialize and add GPIO callback */ + gpio_init_callback(&data->diag0_cb, tmc51xx_diag0_gpio_callback_handler, + BIT(config->diag0_gpio.pin)); + + err = gpio_add_callback(config->diag0_gpio.port, &data->diag0_cb); + if (err < 0) { + LOG_ERR("Could not add DIAG0 pin GPIO callback (%d)", err); + return -EIO; } - int32_t stall_guard_threshold = (int32_t)config->sg_threshold; + /* Clear any pending interrupts */ + uint32_t rampstat_value; - err = tmc51xx_write(dev, TMC51XX_COOLCONF, - stall_guard_threshold - << TMC5XXX_COOLCONF_SG2_THRESHOLD_VALUE_SHIFT); + err = rampstat_read_clear(dev, &rampstat_value); if (err != 0) { return -EIO; } - k_work_reschedule(&data->stallguard_dwork, K_NO_WAIT); - } + }})) -#ifdef CONFIG_STEPPER_ADI_TMC51XX_RAMP_GEN - err = tmc51xx_stepper_set_ramp(dev, &config->default_ramp_config); + LOG_DBG("GCONF: %d", config->gconf); + err = tmc51xx_write(dev, TMC5XXX_GCONF, config->gconf); if (err != 0) { return -EIO; } -#endif - k_work_init_delayable(&data->rampstat_callback_dwork, rampstat_work_handler); - uint32_t rampstat_value; - (void)rampstat_read_clear(dev, &rampstat_value); + /* Read and write GSTAT register to clear any SPI Datagram errors. */ + uint32_t gstat_value; - err = tmc51xx_stepper_set_micro_step_res(dev, config->default_micro_step_res); + err = tmc51xx_read(dev, TMC5XXX_GSTAT, &gstat_value); if (err != 0) { return -EIO; } - return 0; -} - -static int tmc51xx_stepper_stop(const struct device *dev) -{ - int err; - err = tmc51xx_write(dev, TMC51XX_RAMPMODE, TMC5XXX_RAMPMODE_POSITIVE_VELOCITY_MODE); + err = tmc51xx_write(dev, TMC5XXX_GSTAT, gstat_value); if (err != 0) { return -EIO; } - err = tmc51xx_write(dev, TMC51XX_VMAX, 0); - if (err != 0) { - return -EIO; - } + k_work_init_delayable(&data->rampstat_callback_dwork, rampstat_work_handler); + uint32_t rampstat_value; + (void)rampstat_read_clear(dev, &rampstat_value); return 0; } -static DEVICE_API(stepper, tmc51xx_api) = { - .enable = tmc51xx_stepper_enable, - .disable = tmc51xx_stepper_disable, - .is_moving = tmc51xx_stepper_is_moving, - .move_by = tmc51xx_stepper_move_by, - .set_micro_step_res = tmc51xx_stepper_set_micro_step_res, - .get_micro_step_res = tmc51xx_stepper_get_micro_step_res, - .set_reference_position = tmc51xx_stepper_set_reference_position, - .get_actual_position = tmc51xx_stepper_get_actual_position, - .move_to = tmc51xx_stepper_move_to, - .run = tmc51xx_stepper_run, - .stop = tmc51xx_stepper_stop, - .set_event_callback = tmc51xx_stepper_set_event_callback, -}; +#define DT_CHILD_BY_COMPATIBLE(parent_node_id, compat) \ + DT_FOREACH_CHILD_STATUS_OKAY_VARGS(parent_node_id, _DT_CHILD_BY_COMPAT_HELPER, compat) + +#define _DT_CHILD_BY_COMPAT_HELPER(node_id, compat) \ + COND_CODE_1(DT_NODE_HAS_COMPAT(node_id, compat), (node_id), ()) /* Initializes a struct tmc51xx_config for an instance on a SPI bus. */ #define TMC51XX_CONFIG_SPI(inst) \ .comm_type = TMC_COMM_SPI, \ - .bus.spi = SPI_DT_SPEC_INST_GET(inst, \ - (SPI_OP_MODE_MASTER | SPI_TRANSFER_MSB | SPI_MODE_CPOL | \ - SPI_MODE_CPHA | SPI_WORD_SET(8))), \ + .bus.spi = SPI_DT_SPEC_INST_GET(inst, (SPI_OP_MODE_MASTER | SPI_TRANSFER_MSB | \ + SPI_MODE_CPOL | SPI_MODE_CPHA | SPI_WORD_SET(8))), \ .bus_io = &tmc51xx_spi_bus_io, \ .diag0_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, diag0_gpios, {0}) @@ -966,32 +512,27 @@ static DEVICE_API(stepper, tmc51xx_api) = { BUILD_ASSERT((DT_INST_PROP(inst, clock_frequency) > 0), \ "clock frequency must be non-zero positive value"); \ static struct tmc51xx_data tmc51xx_data_##inst = { \ - .stepper = DEVICE_DT_GET(DT_DRV_INST(inst))}; \ + .dev = DEVICE_DT_GET(DT_DRV_INST(inst))}; \ COND_CODE_1(DT_PROP_EXISTS(inst, stallguard_threshold_velocity), \ BUILD_ASSERT(DT_PROP(inst, stallguard_threshold_velocity), \ "stallguard threshold velocity must be a positive value"), ()); \ - IF_ENABLED(CONFIG_STEPPER_ADI_TMC51XX_RAMP_GEN, (CHECK_RAMP_DT_DATA(inst))); \ static const struct tmc51xx_config tmc51xx_config_##inst = {COND_CODE_1 \ (DT_INST_ON_BUS(inst, spi), \ (TMC51XX_CONFIG_SPI(inst)), \ - (TMC51XX_CONFIG_UART(inst))), \ + (TMC51XX_CONFIG_UART(inst))), \ .gconf = ((DT_INST_PROP(inst, en_pwm_mode) << TMC51XX_GCONF_EN_PWM_MODE_SHIFT) | \ (DT_INST_PROP(inst, test_mode) << TMC51XX_GCONF_TEST_MODE_SHIFT) | \ - (DT_INST_PROP(inst, invert_direction) << TMC51XX_GCONF_SHAFT_SHIFT) | \ + (DT_INST_PROP(inst, shaft) << TMC51XX_GCONF_SHAFT_SHIFT) | \ (DT_INST_NODE_HAS_PROP(inst, diag0_gpios) \ ? BIT(TMC51XX_GCONF_DIAG0_INT_PUSHPULL_SHIFT) \ : 0)), \ .clock_frequency = DT_INST_PROP(inst, clock_frequency), \ - .default_micro_step_res = DT_INST_PROP(inst, micro_step_res), \ - .sg_threshold = DT_INST_PROP(inst, stallguard2_threshold), \ - .sg_threshold_velocity = DT_INST_PROP(inst, stallguard_threshold_velocity), \ - .sg_velocity_check_interval_ms = \ - DT_INST_PROP(inst, stallguard_velocity_check_interval_ms), \ - .is_sg_enabled = DT_INST_PROP(inst, activate_stallguard2), \ - IF_ENABLED(CONFIG_STEPPER_ADI_TMC51XX_RAMP_GEN, \ - (.default_ramp_config = TMC_RAMP_DT_SPEC_GET_TMC51XX(inst)))}; \ + .motion_controller = DEVICE_DT_GET_OR_NULL(DT_CHILD_BY_COMPATIBLE( \ + DT_DRV_INST(inst), adi_tmc51xx_stepper)), \ + .stepper_driver = DEVICE_DT_GET_OR_NULL( \ + DT_CHILD_BY_COMPATIBLE(DT_DRV_INST(inst), adi_tmc51xx_stepper_drv))}; \ DEVICE_DT_INST_DEFINE(inst, tmc51xx_init, NULL, &tmc51xx_data_##inst, \ &tmc51xx_config_##inst, POST_KERNEL, CONFIG_STEPPER_INIT_PRIORITY, \ - &tmc51xx_api); + NULL); DT_INST_FOREACH_STATUS_OKAY(TMC51XX_DEFINE) diff --git a/drivers/stepper/adi_tmc/tmc51xx/tmc51xx.h b/drivers/stepper/adi_tmc/tmc51xx/tmc51xx.h new file mode 100644 index 000000000000..2bcaa8e1fd89 --- /dev/null +++ b/drivers/stepper/adi_tmc/tmc51xx/tmc51xx.h @@ -0,0 +1,89 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2025 Dipak Shetty + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_STEPPER_ADI_TMC51XX_H +#define ZEPHYR_DRIVERS_STEPPER_ADI_TMC51XX_H + +#include + +/** + * @brief Trigger the registered callback for stepper driver events. + * + * @param dev Pointer to the stepper driver device. + * @param event The stepper driver event that occurred. + */ +void tmc51xx_stepper_drv_trigger_cb(const struct device *dev, const enum stepper_drv_event event); + +/** + * @brief Trigger the registered callback for stepper events. + * + * @param dev Pointer to the stepper device. + * @param event The stepper event that occurred. + */ +void tmc51xx_stepper_trigger_cb(const struct device *dev, const enum stepper_event event); + +/** + * @brief Enable or disable stallguard feature. + * + * @param dev Pointer to the stepper device. + * @param enable true to enable, false to disable + * @retval -EIO on failure, -EAGAIN if velocity is too low, 0 on success + */ +int tmc51xx_stepper_stallguard_enable(const struct device *dev, const bool enable); + +/** + * @brief Read the actual position from the TMC51xx device. + * + * @param dev Pointer to the TMC51xx device. + * @param position Pointer to store the actual position in microsteps. + * @retval -EIO on failure, -ENOTSUP if reading while moving over UART is attempted, 0 on success + */ +int tmc51xx_read_actual_position(const struct device *dev, int32_t *position); + +/** + * @brief Reschedule the ramp status callback work item. + * + * @param dev Pointer to the TMC51xx device. + */ +void tmc51xx_reschedule_rampstat_callback(const struct device *dev); + +/** + * @brief Write a 32-bit value to a TMC51xx register. + * + * @param dev Pointer to the TMC51xx device. + * @param reg_addr Register address to write to. + * @param reg_val Value to write to the register. + * @retval -EIO on failure, 0 on success + */ +int tmc51xx_write(const struct device *dev, const uint8_t reg_addr, const uint32_t reg_val); + +/** + * @brief Read a 32-bit value from a TMC51xx register. + * + * @param dev Pointer to the TMC51xx device. + * @param reg_addr Register address to read from. + * @param reg_val Pointer to store the read value. + * @retval -EIO on failure, 0 on success + */ +int tmc51xx_read(const struct device *dev, const uint8_t reg_addr, uint32_t *reg_val); + +/** + * @brief Check if the TMC51xx driver is interrupt driven. + * + * @param dev Pointer to the TMC51xx device. + * @return true if interrupt driven, false otherwise. + */ +bool tmc51xx_is_interrupt_driven(const struct device *dev); + +/** + * @brief Get the clock frequency in Hz of the TMC51XX device. + * + * @param dev Pointer to the TMC51XX device. + * @return Clock frequency in Hz + */ +int tmc51xx_get_clock_frequency(const struct device *dev); + +#endif /* ZEPHYR_DRIVERS_STEPPER_ADI_TMC51XX_H */ diff --git a/drivers/stepper/adi_tmc/tmc51xx/tmc51xx_stepper.c b/drivers/stepper/adi_tmc/tmc51xx/tmc51xx_stepper.c new file mode 100644 index 000000000000..e6772bbbaf13 --- /dev/null +++ b/drivers/stepper/adi_tmc/tmc51xx/tmc51xx_stepper.c @@ -0,0 +1,460 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2025 Dipak Shetty + * SPDX-FileCopyrightText: Copyright (c) 2025 Jilay Sandeep Pandya + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include +#include "tmc51xx.h" +#include + +#include +LOG_MODULE_DECLARE(tmc51xx, CONFIG_STEPPER_LOG_LEVEL); + +#define DT_DRV_COMPAT adi_tmc51xx_stepper + +struct tmc51xx_stepper_config { + const bool is_sg_enabled; + const uint32_t sg_velocity_check_interval_ms; + const uint32_t sg_threshold_velocity; +#ifdef CONFIG_STEPPER_ADI_TMC51XX_RAMP_GEN + const struct tmc_ramp_generator_data default_ramp_config; +#endif + /* parent controller required for bus communication */ + const struct device *controller; +}; + +struct tmc51xx_stepper_data { + struct k_work_delayable stallguard_dwork; + /* Work item to run the callback in a thread context. */ + const struct device *dev; + stepper_event_callback_t callback; + void *event_cb_user_data; +}; + +void tmc51xx_stepper_trigger_cb(const struct device *dev, const enum stepper_event event) +{ + struct tmc51xx_stepper_data *data = dev->data; + + if (!data->callback) { + LOG_WRN_ONCE("No motion controller callback registered"); + return; + } + data->callback(dev, event, data->event_cb_user_data); +} + +static int read_vactual(const struct device *dev, int32_t *actual_velocity) +{ + __ASSERT(actual_velocity != NULL, "actual_velocity pointer must not be NULL"); + const struct tmc51xx_stepper_config *config = dev->config; + const struct device *controller = config->controller; + int err; + uint32_t raw_value; + + err = tmc51xx_read(controller, TMC51XX_VACTUAL, &raw_value); + if (err) { + LOG_ERR("Failed to read VACTUAL register"); + return err; + } + + *actual_velocity = sign_extend(raw_value, TMC_RAMP_VACTUAL_SHIFT); + if (*actual_velocity) { + LOG_DBG("actual velocity: %d", *actual_velocity); + } + return 0; +} + +int tmc51xx_stepper_set_max_velocity(const struct device *dev, uint32_t velocity) +{ + const struct tmc51xx_stepper_config *config = dev->config; + const uint32_t clock_frequency = tmc51xx_get_clock_frequency(dev); + uint32_t velocity_fclk; + int err; + + velocity_fclk = tmc5xxx_calculate_velocity_from_hz_to_fclk(velocity, clock_frequency); + + err = tmc51xx_write(config->controller, TMC51XX_VMAX, velocity_fclk); + if (err != 0) { + LOG_ERR("%s: Failed to set max velocity", dev->name); + return -EIO; + } + return 0; +} + +int tmc51xx_stepper_stallguard_enable(const struct device *dev, const bool enable) +{ + const struct tmc51xx_stepper_config *config = dev->config; + const struct device *controller = config->controller; + uint32_t reg_value; + int err; + + err = tmc51xx_read(controller, TMC51XX_SWMODE, ®_value); + if (err) { + LOG_ERR("Failed to read SWMODE register"); + return -EIO; + } + + if (enable) { + reg_value |= TMC5XXX_SW_MODE_SG_STOP_ENABLE; + + int32_t actual_velocity; + + err = read_vactual(dev, &actual_velocity); + if (err) { + return -EIO; + } + if (abs(actual_velocity) < config->sg_threshold_velocity) { + return -EAGAIN; + } + } else { + reg_value &= ~TMC5XXX_SW_MODE_SG_STOP_ENABLE; + } + err = tmc51xx_write(controller, TMC51XX_SWMODE, reg_value); + if (err) { + LOG_ERR("Failed to write SWMODE register"); + return -EIO; + } + + LOG_DBG("Stallguard %s", enable ? "enabled" : "disabled"); + return 0; +} + +static void stallguard_work_handler(struct k_work *work) +{ + struct k_work_delayable *dwork = k_work_delayable_from_work(work); + struct tmc51xx_stepper_data const *data = + CONTAINER_OF(dwork, struct tmc51xx_stepper_data, stallguard_dwork); + const struct device *dev = data->dev; + const struct tmc51xx_stepper_config *config = dev->config; + int err; + + err = tmc51xx_stepper_stallguard_enable(dev, true); + if (err == -EAGAIN) { + k_work_reschedule(dwork, K_MSEC(config->sg_velocity_check_interval_ms)); + } + if (err == -EIO) { + LOG_ERR("Failed to enable stallguard because of I/O error"); + } +} + +static int tmc51xx_stepper_set_event_callback(const struct device *dev, + stepper_event_callback_t callback, void *user_data) +{ + struct tmc51xx_stepper_data *data = dev->data; + + data->callback = callback; + data->event_cb_user_data = user_data; + + return 0; +} + +static int tmc51xx_stepper_is_moving(const struct device *dev, bool *is_moving) +{ + const struct tmc51xx_stepper_config *config = dev->config; + const struct device *controller = config->controller; + uint32_t reg_value; + int err; + + err = tmc51xx_read(controller, TMC51XX_DRVSTATUS, ®_value); + + if (err != 0) { + LOG_ERR("%s: Failed to read DRVSTATUS register", dev->name); + return -EIO; + } + + *is_moving = (FIELD_GET(TMC5XXX_DRV_STATUS_STST_BIT, reg_value) != 1U); + LOG_DBG("Stepper motor controller %s is moving: %d", dev->name, *is_moving); + return 0; +} + +static int tmc51xx_stepper_set_reference_position(const struct device *dev, const int32_t position) +{ + const struct tmc51xx_stepper_config *config = dev->config; + const struct device *controller = config->controller; + int err; + + err = tmc51xx_write(controller, TMC51XX_RAMPMODE, TMC5XXX_RAMPMODE_HOLD_MODE); + if (err != 0) { + return -EIO; + } + + err = tmc51xx_write(controller, TMC51XX_XACTUAL, position); + if (err != 0) { + return -EIO; + } + LOG_DBG("Stepper motor controller %s set actual position to %d", dev->name, position); + return 0; +} + +static int tmc51xx_stepper_get_actual_position(const struct device *dev, int32_t *position) +{ + const struct tmc51xx_stepper_config *config = dev->config; + int err; + + err = tmc51xx_read_actual_position(config->controller, position); + if (err != 0) { + return -EIO; + } + LOG_DBG("%s actual position: %d", dev->name, *position); + return 0; +} + +static int tmc51xx_stepper_move_to(const struct device *dev, const int32_t micro_steps) +{ + LOG_DBG("%s set target position to %d", dev->name, micro_steps); + const struct tmc51xx_stepper_config *config = dev->config; + struct tmc51xx_stepper_data *data = dev->data; + const struct device *comm_device = config->controller; + int err; + + if (config->is_sg_enabled) { + tmc51xx_stepper_stallguard_enable(dev, false); + } + + err = tmc51xx_write(comm_device, TMC51XX_RAMPMODE, TMC5XXX_RAMPMODE_POSITIONING_MODE); + if (err != 0) { + return -EIO; + } + err = tmc51xx_write(comm_device, TMC51XX_XTARGET, micro_steps); + if (err != 0) { + return -EIO; + } + + if (config->is_sg_enabled) { + k_work_reschedule(&data->stallguard_dwork, + K_MSEC(config->sg_velocity_check_interval_ms)); + } + if (data->callback) { + /* For SPI with DIAG0 pin, we use interrupt-driven approach */ + + if (tmc51xx_is_interrupt_driven(config->controller)) { + return 0; + } + /* For UART or SPI without DIAG0, reschedule RAMPSTAT polling */ +#ifdef CONFIG_STEPPER_ADI_TMC51XX_RAMPSTAT_POLL_INTERVAL_IN_MSEC + tmc51xx_reschedule_rampstat_callback(config->controller); +#endif /* CONFIG_STEPPER_ADI_TMC51XX_RAMPSTAT_POLL_INTERVAL_IN_MSEC */ + } + return 0; +} + +static int tmc51xx_stepper_move_by(const struct device *dev, const int32_t micro_steps) +{ + int err; + int32_t position; + + err = tmc51xx_stepper_get_actual_position(dev, &position); + if (err != 0) { + return -EIO; + } + int32_t target_position = position + micro_steps; + + LOG_DBG("%s moved to %d by steps: %d", dev->name, target_position, micro_steps); + + return tmc51xx_stepper_move_to(dev, target_position); +} + +static int tmc51xx_stepper_run(const struct device *dev, const enum stepper_direction direction) +{ + LOG_DBG("Stepper motor controller %s run", dev->name); + const struct tmc51xx_stepper_config *config = dev->config; + struct tmc51xx_stepper_data *data = dev->data; + const struct device *controller = config->controller; + int err; + + if (config->is_sg_enabled) { + err = tmc51xx_stepper_stallguard_enable(dev, false); + if (err != 0) { + return -EIO; + } + } + + switch (direction) { + case STEPPER_DIRECTION_POSITIVE: + err = tmc51xx_write(controller, TMC51XX_RAMPMODE, + TMC5XXX_RAMPMODE_POSITIVE_VELOCITY_MODE); + if (err != 0) { + return -EIO; + } + break; + + case STEPPER_DIRECTION_NEGATIVE: + err = tmc51xx_write(controller, TMC51XX_RAMPMODE, + TMC5XXX_RAMPMODE_NEGATIVE_VELOCITY_MODE); + if (err != 0) { + return -EIO; + } + break; + } + + if (config->is_sg_enabled) { + k_work_reschedule(&data->stallguard_dwork, + K_MSEC(config->sg_velocity_check_interval_ms)); + } + if (data->callback) { + /* For SPI with DIAG0 pin, we use interrupt-driven approach */ + if (tmc51xx_is_interrupt_driven(controller)) { + return 0; + } + + /* For UART or SPI without DIAG0, reschedule RAMPSTAT polling */ +#ifdef CONFIG_STEPPER_ADI_TMC51XX_RAMPSTAT_POLL_INTERVAL_IN_MSEC + tmc51xx_reschedule_rampstat_callback(config->controller); +#endif /* CONFIG_STEPPER_ADI_TMC51XX_RAMPSTAT_POLL_INTERVAL_IN_MSEC */ + } + return 0; +} + +#ifdef CONFIG_STEPPER_ADI_TMC51XX_RAMP_GEN + +int tmc51xx_stepper_set_ramp(const struct device *dev, + const struct tmc_ramp_generator_data *ramp_data) +{ + const struct tmc51xx_stepper_config *config = dev->config; + const struct device *controller = config->controller; + int err; + + LOG_DBG("Stepper motor controller %s set ramp", dev->name); + + err = tmc51xx_write(controller, TMC51XX_VSTART, ramp_data->vstart); + if (err != 0) { + return -EIO; + } + err = tmc51xx_write(controller, TMC51XX_A1, ramp_data->a1); + if (err != 0) { + return -EIO; + } + err = tmc51xx_write(controller, TMC51XX_AMAX, ramp_data->amax); + if (err != 0) { + return -EIO; + } + err = tmc51xx_write(controller, TMC51XX_D1, ramp_data->d1); + if (err != 0) { + return -EIO; + } + err = tmc51xx_write(controller, TMC51XX_DMAX, ramp_data->dmax); + if (err != 0) { + return -EIO; + } + err = tmc51xx_write(controller, TMC51XX_V1, ramp_data->v1); + if (err != 0) { + return -EIO; + } + err = tmc51xx_write(controller, TMC51XX_VMAX, ramp_data->vmax); + if (err != 0) { + return -EIO; + } + err = tmc51xx_write(controller, TMC51XX_VSTOP, ramp_data->vstop); + if (err != 0) { + return -EIO; + } + err = tmc51xx_write(controller, TMC51XX_TZEROWAIT, ramp_data->tzerowait); + if (err != 0) { + return -EIO; + } + err = tmc51xx_write(controller, TMC51XX_THIGH, ramp_data->thigh); + if (err != 0) { + return -EIO; + } + err = tmc51xx_write(controller, TMC51XX_TCOOLTHRS, ramp_data->tcoolthrs); + if (err != 0) { + return -EIO; + } + err = tmc51xx_write(controller, TMC51XX_TPWMTHRS, ramp_data->tpwmthrs); + if (err != 0) { + return -EIO; + } + err = tmc51xx_write(controller, TMC51XX_TPOWER_DOWN, ramp_data->tpowerdown); + if (err != 0) { + return -EIO; + } + err = tmc51xx_write(controller, TMC51XX_IHOLD_IRUN, ramp_data->iholdrun); + if (err != 0) { + return -EIO; + } + return 0; +} + +#endif + +static int tmc51xx_stepper_init(const struct device *dev) +{ + const struct tmc51xx_stepper_config *config = dev->config; + struct tmc51xx_stepper_data *data = dev->data; + const struct device *controller = config->controller; + int err; + + data->dev = dev; + + if (config->is_sg_enabled) { + k_work_init_delayable(&data->stallguard_dwork, stallguard_work_handler); + + err = tmc51xx_write(controller, TMC51XX_SWMODE, BIT(10)); + if (err != 0) { + return -EIO; + } + + LOG_DBG("stallguard delay %d ms", config->sg_velocity_check_interval_ms); + + k_work_reschedule(&data->stallguard_dwork, K_NO_WAIT); + } + +#ifdef CONFIG_STEPPER_ADI_TMC51XX_RAMP_GEN + err = tmc51xx_stepper_set_ramp(dev, &config->default_ramp_config); + if (err != 0) { + return -EIO; + } +#endif + return 0; +} + +static int tmc51xx_stepper_stop(const struct device *dev) +{ + const struct tmc51xx_stepper_config *config = dev->config; + const struct device *controller = config->controller; + int err; + + err = tmc51xx_write(controller, TMC51XX_RAMPMODE, TMC5XXX_RAMPMODE_POSITIVE_VELOCITY_MODE); + if (err != 0) { + return -EIO; + } + + err = tmc51xx_write(controller, TMC51XX_VMAX, 0); + if (err != 0) { + return -EIO; + } + + return 0; +} + +static DEVICE_API(stepper, tmc51xx_stepper_api) = { + .is_moving = tmc51xx_stepper_is_moving, + .move_by = tmc51xx_stepper_move_by, + .set_reference_position = tmc51xx_stepper_set_reference_position, + .get_actual_position = tmc51xx_stepper_get_actual_position, + .move_to = tmc51xx_stepper_move_to, + .run = tmc51xx_stepper_run, + .stop = tmc51xx_stepper_stop, + .set_event_callback = tmc51xx_stepper_set_event_callback, +}; + +#define TMC51XX_STEPPER_DEFINE(inst) \ + IF_ENABLED(CONFIG_STEPPER_ADI_TMC51XX_RAMP_GEN, (CHECK_RAMP_DT_DATA(inst))); \ + static const struct tmc51xx_stepper_config tmc51xx_stepper_cfg_##inst = { \ + .controller = DEVICE_DT_GET(DT_PARENT(DT_DRV_INST(inst))), \ + .sg_threshold_velocity = DT_INST_PROP(inst, stallguard_threshold_velocity), \ + .sg_velocity_check_interval_ms = \ + DT_INST_PROP(inst, stallguard_velocity_check_interval_ms), \ + .is_sg_enabled = DT_INST_PROP(inst, activate_stallguard2), \ + IF_ENABLED(CONFIG_STEPPER_ADI_TMC51XX_RAMP_GEN, \ + (.default_ramp_config = TMC_RAMP_DT_SPEC_GET_TMC51XX(inst))) }; \ + static struct tmc51xx_stepper_data tmc51xx_stepper_data_##inst; \ + DEVICE_DT_INST_DEFINE(inst, tmc51xx_stepper_init, NULL, \ + &tmc51xx_stepper_data_##inst, \ + &tmc51xx_stepper_cfg_##inst, POST_KERNEL, \ + CONFIG_STEPPER_INIT_PRIORITY, &tmc51xx_stepper_api); + +DT_INST_FOREACH_STATUS_OKAY(TMC51XX_STEPPER_DEFINE) diff --git a/drivers/stepper/adi_tmc/tmc51xx/tmc51xx_stepper_drv.c b/drivers/stepper/adi_tmc/tmc51xx/tmc51xx_stepper_drv.c new file mode 100644 index 000000000000..b64f77b2c43f --- /dev/null +++ b/drivers/stepper/adi_tmc/tmc51xx/tmc51xx_stepper_drv.c @@ -0,0 +1,184 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2025 Dipak Shetty + * SPDX-FileCopyrightText: Copyright (c) 2025 Jilay Sandeep Pandya + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "tmc51xx.h" +#include + +#include +LOG_MODULE_DECLARE(tmc51xx, CONFIG_STEPPER_LOG_LEVEL); + +#define DT_DRV_COMPAT adi_tmc51xx_stepper_drv + +struct tmc51xx_stepper_drv_config { + const uint16_t default_micro_step_res; + const int8_t sg_threshold; + /* parent controller required for bus communication */ + const struct device *controller; +}; + +struct tmc51xx_stepper_drv_data { + stepper_drv_event_cb_t drv_event_cb; + void *drv_event_cb_user_data; +}; + +void tmc51xx_stepper_drv_trigger_cb(const struct device *dev, const enum stepper_drv_event event) +{ + struct tmc51xx_stepper_drv_data *data = dev->data; + + if (!data->drv_event_cb) { + LOG_WRN_ONCE("No stepper driver callback registered"); + return; + } + data->drv_event_cb(dev, event, data->drv_event_cb_user_data); +} + +static int tmc51xx_stepper_drv_set_event_callback(const struct device *stepper, + stepper_drv_event_cb_t callback, void *user_data) +{ + struct tmc51xx_stepper_drv_data *data = stepper->data; + + data->drv_event_cb = callback; + data->drv_event_cb_user_data = user_data; + + return 0; +} + +static int tmc51xx_stepper_drv_enable(const struct device *dev) +{ + const struct tmc51xx_stepper_drv_config *config = dev->config; + const struct device *controller = config->controller; + uint32_t reg_value; + int err; + + LOG_DBG("Enabling Stepper motor controller %s", dev->name); + + err = tmc51xx_read(controller, TMC51XX_CHOPCONF, ®_value); + if (err != 0) { + return -EIO; + } + + reg_value |= TMC5XXX_CHOPCONF_DRV_ENABLE_MASK; + + return tmc51xx_write(controller, TMC51XX_CHOPCONF, reg_value); +} + +static int tmc51xx_stepper_drv_disable(const struct device *dev) +{ + LOG_DBG("Disabling Stepper motor controller %s", dev->name); + const struct tmc51xx_stepper_drv_config *config = dev->config; + const struct device *controller = config->controller; + uint32_t reg_value; + int err; + + err = tmc51xx_read(controller, TMC51XX_CHOPCONF, ®_value); + if (err != 0) { + return -EIO; + } + + reg_value &= ~TMC5XXX_CHOPCONF_DRV_ENABLE_MASK; + + return tmc51xx_write(controller, TMC51XX_CHOPCONF, reg_value); +} + +static int tmc51xx_stepper_drv_set_micro_step_res(const struct device *dev, + enum stepper_drv_micro_step_resolution res) +{ + const struct tmc51xx_stepper_drv_config *config = dev->config; + const struct device *controller = config->controller; + uint32_t reg_value; + int err; + + err = tmc51xx_read(controller, TMC51XX_CHOPCONF, ®_value); + if (err != 0) { + return -EIO; + } + + reg_value &= ~TMC5XXX_CHOPCONF_MRES_MASK; + reg_value |= ((MICRO_STEP_RES_INDEX(STEPPER_DRV_MICRO_STEP_256) - LOG2(res)) + << TMC5XXX_CHOPCONF_MRES_SHIFT); + + err = tmc51xx_write(controller, TMC51XX_CHOPCONF, reg_value); + if (err != 0) { + return -EIO; + } + + LOG_DBG("Stepper motor controller %s set micro step resolution to 0x%x", dev->name, + reg_value); + return 0; +} + +static int tmc51xx_stepper_drv_get_micro_step_res(const struct device *dev, + enum stepper_drv_micro_step_resolution *res) +{ + const struct tmc51xx_stepper_drv_config *config = dev->config; + const struct device *controller = config->controller; + uint32_t reg_value; + int err; + + err = tmc51xx_read(controller, TMC51XX_CHOPCONF, ®_value); + if (err != 0) { + return -EIO; + } + reg_value &= TMC5XXX_CHOPCONF_MRES_MASK; + reg_value >>= TMC5XXX_CHOPCONF_MRES_SHIFT; + *res = (1 << (MICRO_STEP_RES_INDEX(STEPPER_DRV_MICRO_STEP_256) - reg_value)); + LOG_DBG("Stepper motor controller %s get micro step resolution: %d", dev->name, *res); + return 0; +} + +static int tmc51xx_stepper_drv_init(const struct device *dev) +{ + const struct tmc51xx_stepper_drv_config *config = dev->config; + const struct device *controller = config->controller; + int err; + + if (!IN_RANGE(config->sg_threshold, TMC5XXX_SG_MIN_VALUE, TMC5XXX_SG_MAX_VALUE)) { + LOG_ERR("Stallguard threshold out of range"); + return -EINVAL; + } + + int32_t stall_guard_threshold = (int32_t)config->sg_threshold; + + err = tmc51xx_write(controller, TMC51XX_COOLCONF, + stall_guard_threshold << TMC5XXX_COOLCONF_SG2_THRESHOLD_VALUE_SHIFT); + if (err != 0) { + return -EIO; + } + + err = tmc51xx_stepper_drv_set_micro_step_res(dev, config->default_micro_step_res); + if (err != 0) { + return -EIO; + } + LOG_DBG("Setting stallguard %d", config->sg_threshold); + return 0; +} + +static DEVICE_API(stepper_drv, tmc51xx_stepper_drv_api) = { + .enable = tmc51xx_stepper_drv_enable, + .disable = tmc51xx_stepper_drv_disable, + .set_micro_step_res = tmc51xx_stepper_drv_set_micro_step_res, + .get_micro_step_res = tmc51xx_stepper_drv_get_micro_step_res, + .set_event_cb = tmc51xx_stepper_drv_set_event_callback, +}; + +#define TMC51XX_STEPPER_DRV_DEFINE(inst) \ + COND_CODE_1(DT_PROP_EXISTS(inst, stallguard_threshold_velocity), \ + BUILD_ASSERT(DT_PROP(inst, stallguard_threshold_velocity), \ + "stallguard threshold velocity must be a positive value"), ()); \ + static const struct tmc51xx_stepper_drv_config tmc51xx_stepper_drv_config_##inst = { \ + .controller = DEVICE_DT_GET(DT_PARENT(DT_DRV_INST(inst))), \ + .default_micro_step_res = DT_INST_PROP(inst, micro_step_res), \ + .sg_threshold = DT_INST_PROP(inst, stallguard2_threshold), \ + }; \ + static struct tmc51xx_stepper_drv_data tmc51xx_stepper_drv_data_##inst; \ + DEVICE_DT_INST_DEFINE(inst, tmc51xx_stepper_drv_init, NULL, \ + &tmc51xx_stepper_drv_data_##inst, \ + &tmc51xx_stepper_drv_config_##inst, POST_KERNEL, \ + CONFIG_STEPPER_INIT_PRIORITY, &tmc51xx_stepper_drv_api); + +DT_INST_FOREACH_STATUS_OKAY(TMC51XX_STEPPER_DRV_DEFINE) diff --git a/drivers/stepper/allegro/a4979.c b/drivers/stepper/allegro/a4979.c index dea0de4f818a..302c5d560f05 100644 --- a/drivers/stepper/allegro/a4979.c +++ b/drivers/stepper/allegro/a4979.c @@ -22,11 +22,10 @@ struct a4979_config { }; struct a4979_data { - const struct step_dir_stepper_common_data common; - enum stepper_micro_step_resolution micro_step_res; + enum stepper_drv_micro_step_resolution micro_step_res; }; -STEP_DIR_STEPPER_STRUCT_CHECK(struct a4979_config, struct a4979_data); +STEP_DIR_STEPPER_STRUCT_CHECK(struct a4979_config); static int a4979_set_microstep_pin(const struct device *dev, const struct gpio_dt_spec *pin, int value) @@ -49,11 +48,11 @@ static int a4979_set_microstep_pin(const struct device *dev, const struct gpio_d return 0; } -static int a4979_stepper_enable(const struct device *dev) +static int a4979_enable(const struct device *dev) { - int ret; const struct a4979_config *config = dev->config; bool has_enable_pin = config->en_pin.port != NULL; + int ret; /* Check availability of enable pin, as it might be hardwired. */ if (!has_enable_pin) { @@ -70,11 +69,11 @@ static int a4979_stepper_enable(const struct device *dev) return 0; } -static int a4979_stepper_disable(const struct device *dev) +static int a4979_disable(const struct device *dev) { - int ret; const struct a4979_config *config = dev->config; bool has_enable_pin = config->en_pin.port != NULL; + int ret; /* Check availability of enable pin, as it might be hardwired. */ if (!has_enable_pin) { @@ -91,8 +90,8 @@ static int a4979_stepper_disable(const struct device *dev) return 0; } -static int a4979_stepper_set_micro_step_res(const struct device *dev, - const enum stepper_micro_step_resolution micro_step_res) +static int a4979_set_micro_step_res(const struct device *dev, + const enum stepper_drv_micro_step_resolution micro_step_res) { const struct a4979_config *config = dev->config; struct a4979_data *data = dev->data; @@ -102,19 +101,19 @@ static int a4979_stepper_set_micro_step_res(const struct device *dev, uint8_t m1_value = 0; switch (micro_step_res) { - case STEPPER_MICRO_STEP_1: + case STEPPER_DRV_MICRO_STEP_1: m0_value = 0; m1_value = 0; break; - case STEPPER_MICRO_STEP_2: + case STEPPER_DRV_MICRO_STEP_2: m0_value = 1; m1_value = 0; break; - case STEPPER_MICRO_STEP_4: + case STEPPER_DRV_MICRO_STEP_4: m0_value = 0; m1_value = 1; break; - case STEPPER_MICRO_STEP_16: + case STEPPER_DRV_MICRO_STEP_16: m0_value = 1; m1_value = 1; break; @@ -136,10 +135,10 @@ static int a4979_stepper_set_micro_step_res(const struct device *dev, return 0; } -static int a4979_stepper_get_micro_step_res(const struct device *dev, - enum stepper_micro_step_resolution *micro_step_res) +static int a4979_get_micro_step_res(const struct device *dev, + enum stepper_drv_micro_step_resolution *micro_step_res) { - struct a4979_data *data = dev->data; + const struct a4979_data *data = dev->data; *micro_step_res = data->micro_step_res; return 0; @@ -148,7 +147,7 @@ static int a4979_stepper_get_micro_step_res(const struct device *dev, static int a4979_init(const struct device *dev) { const struct a4979_config *config = dev->config; - struct a4979_data *data = dev->data; + const struct a4979_data *data = dev->data; int ret; bool has_enable_pin = config->en_pin.port != NULL; @@ -206,36 +205,20 @@ static int a4979_init(const struct device *dev) return ret; } - ret = a4979_stepper_set_micro_step_res(dev, data->micro_step_res); + ret = a4979_set_micro_step_res(dev, data->micro_step_res); if (ret != 0) { LOG_ERR("Failed to set micro step resolution: %d", ret); return ret; } - ret = step_dir_stepper_common_init(dev); - if (ret != 0) { - LOG_ERR("Failed to initialize common stepper data: %d", ret); - return ret; - } - gpio_pin_set_dt(&config->common.step_pin, 0); - return 0; } -static DEVICE_API(stepper, a4979_stepper_api) = { - .enable = a4979_stepper_enable, - .disable = a4979_stepper_disable, - .move_by = step_dir_stepper_common_move_by, - .move_to = step_dir_stepper_common_move_to, - .is_moving = step_dir_stepper_common_is_moving, - .set_reference_position = step_dir_stepper_common_set_reference_position, - .get_actual_position = step_dir_stepper_common_get_actual_position, - .set_microstep_interval = step_dir_stepper_common_set_microstep_interval, - .run = step_dir_stepper_common_run, - .stop = step_dir_stepper_common_stop, - .set_micro_step_res = a4979_stepper_set_micro_step_res, - .get_micro_step_res = a4979_stepper_get_micro_step_res, - .set_event_callback = step_dir_stepper_common_set_event_callback, +static DEVICE_API(stepper_drv, a4979_stepper_api) = { + .enable = a4979_enable, + .disable = a4979_disable, + .set_micro_step_res = a4979_set_micro_step_res, + .get_micro_step_res = a4979_get_micro_step_res, }; #define A4979_DEVICE(inst) \ @@ -249,7 +232,6 @@ static DEVICE_API(stepper, a4979_stepper_api) = { }; \ \ static struct a4979_data a4979_data_##inst = { \ - .common = STEP_DIR_STEPPER_DT_INST_COMMON_DATA_INIT(inst), \ .micro_step_res = DT_INST_PROP(inst, micro_step_res), \ }; \ \ diff --git a/drivers/stepper/fake_stepper_controller.c b/drivers/stepper/fake_stepper_controller.c index 3abce9726c50..2fb3fafe9ea0 100644 --- a/drivers/stepper/fake_stepper_controller.c +++ b/drivers/stepper/fake_stepper_controller.c @@ -12,16 +12,26 @@ #include #endif /* CONFIG_ZTEST */ -#define DT_DRV_COMPAT zephyr_fake_stepper +struct fake_stepper_drv_data { + enum stepper_drv_micro_step_resolution micro_step_res; +}; struct fake_stepper_data { - enum stepper_micro_step_resolution micro_step_res; int32_t actual_position; }; -DEFINE_FAKE_VALUE_FUNC(int, fake_stepper_enable, const struct device *); +DEFINE_FAKE_VALUE_FUNC(int, fake_stepper_drv_enable, const struct device *); + +DEFINE_FAKE_VALUE_FUNC(int, fake_stepper_drv_disable, const struct device *); -DEFINE_FAKE_VALUE_FUNC(int, fake_stepper_disable, const struct device *); +DEFINE_FAKE_VALUE_FUNC(int, fake_stepper_drv_set_micro_step_res, const struct device *, + enum stepper_drv_micro_step_resolution); + +DEFINE_FAKE_VALUE_FUNC(int, fake_stepper_drv_get_micro_step_res, const struct device *, + enum stepper_drv_micro_step_resolution *); + +DEFINE_FAKE_VALUE_FUNC(int, fake_stepper_drv_set_event_cb, const struct device *, + stepper_drv_event_cb_t, void *); DEFINE_FAKE_VALUE_FUNC(int, fake_stepper_is_moving, const struct device *, bool *); @@ -29,12 +39,6 @@ DEFINE_FAKE_VALUE_FUNC(int, fake_stepper_move_by, const struct device *, int32_t DEFINE_FAKE_VALUE_FUNC(int, fake_stepper_set_microstep_interval, const struct device *, uint64_t); -DEFINE_FAKE_VALUE_FUNC(int, fake_stepper_set_micro_step_res, const struct device *, - enum stepper_micro_step_resolution); - -DEFINE_FAKE_VALUE_FUNC(int, fake_stepper_get_micro_step_res, const struct device *, - enum stepper_micro_step_resolution *); - DEFINE_FAKE_VALUE_FUNC(int, fake_stepper_set_reference_position, const struct device *, int32_t); DEFINE_FAKE_VALUE_FUNC(int, fake_stepper_get_actual_position, const struct device *, int32_t *); @@ -48,20 +52,21 @@ DEFINE_FAKE_VALUE_FUNC(int, fake_stepper_stop, const struct device *); DEFINE_FAKE_VALUE_FUNC(int, fake_stepper_set_event_callback, const struct device *, stepper_event_callback_t, void *); -static int fake_stepper_set_micro_step_res_delegate(const struct device *dev, - const enum stepper_micro_step_resolution res) +static int +fake_stepper_drv_set_micro_step_res_delegate(const struct device *dev, + const enum stepper_drv_micro_step_resolution res) { - struct fake_stepper_data *data = dev->data; + struct fake_stepper_drv_data *data = dev->data; data->micro_step_res = res; return 0; } -static int fake_stepper_get_micro_step_res_delegate(const struct device *dev, - enum stepper_micro_step_resolution *res) +static int fake_stepper_drv_get_micro_step_res_delegate(const struct device *dev, + enum stepper_drv_micro_step_resolution *res) { - struct fake_stepper_data *data = dev->data; + struct fake_stepper_drv_data *data = dev->data; *res = data->micro_step_res; @@ -92,13 +97,14 @@ static void fake_stepper_reset_rule_before(const struct ztest_unit_test *test, v ARG_UNUSED(test); ARG_UNUSED(fixture); - RESET_FAKE(fake_stepper_enable); - RESET_FAKE(fake_stepper_disable); + RESET_FAKE(fake_stepper_drv_enable); + RESET_FAKE(fake_stepper_drv_disable); + RESET_FAKE(fake_stepper_drv_set_micro_step_res); + RESET_FAKE(fake_stepper_drv_get_micro_step_res); + RESET_FAKE(fake_stepper_drv_set_event_cb); RESET_FAKE(fake_stepper_move_by); RESET_FAKE(fake_stepper_is_moving); RESET_FAKE(fake_stepper_set_microstep_interval); - RESET_FAKE(fake_stepper_set_micro_step_res); - RESET_FAKE(fake_stepper_get_micro_step_res); RESET_FAKE(fake_stepper_set_reference_position); RESET_FAKE(fake_stepper_get_actual_position); RESET_FAKE(fake_stepper_move_to); @@ -106,8 +112,10 @@ static void fake_stepper_reset_rule_before(const struct ztest_unit_test *test, v RESET_FAKE(fake_stepper_stop); /* Install custom fakes for the setter and getter functions */ - fake_stepper_set_micro_step_res_fake.custom_fake = fake_stepper_set_micro_step_res_delegate; - fake_stepper_get_micro_step_res_fake.custom_fake = fake_stepper_get_micro_step_res_delegate; + fake_stepper_drv_set_micro_step_res_fake.custom_fake = + fake_stepper_drv_set_micro_step_res_delegate; + fake_stepper_drv_get_micro_step_res_fake.custom_fake = + fake_stepper_drv_get_micro_step_res_delegate; fake_stepper_set_reference_position_fake.custom_fake = fake_stepper_set_reference_position_delegate; fake_stepper_get_actual_position_fake.custom_fake = @@ -117,10 +125,18 @@ static void fake_stepper_reset_rule_before(const struct ztest_unit_test *test, v ZTEST_RULE(fake_stepper_reset_rule, fake_stepper_reset_rule_before, NULL); #endif /* CONFIG_ZTEST */ +static int fake_stepper_driver_init(const struct device *dev) +{ + fake_stepper_drv_set_micro_step_res_fake.custom_fake = + fake_stepper_drv_set_micro_step_res_delegate; + fake_stepper_drv_get_micro_step_res_fake.custom_fake = + fake_stepper_drv_get_micro_step_res_delegate; + + return 0; +} + static int fake_stepper_init(const struct device *dev) { - fake_stepper_set_micro_step_res_fake.custom_fake = fake_stepper_set_micro_step_res_delegate; - fake_stepper_get_micro_step_res_fake.custom_fake = fake_stepper_get_micro_step_res_delegate; fake_stepper_set_reference_position_fake.custom_fake = fake_stepper_set_reference_position_delegate; fake_stepper_get_actual_position_fake.custom_fake = @@ -129,14 +145,18 @@ static int fake_stepper_init(const struct device *dev) return 0; } -static DEVICE_API(stepper, fake_stepper_driver_api) = { - .enable = fake_stepper_enable, - .disable = fake_stepper_disable, +static DEVICE_API(stepper_drv, fake_stepper_drv_api) = { + .enable = fake_stepper_drv_enable, + .disable = fake_stepper_drv_disable, + .set_micro_step_res = fake_stepper_drv_set_micro_step_res, + .get_micro_step_res = fake_stepper_drv_get_micro_step_res, + .set_event_cb = fake_stepper_drv_set_event_cb, +}; + +static DEVICE_API(stepper, fake_stepper_api) = { .move_by = fake_stepper_move_by, .is_moving = fake_stepper_is_moving, .set_microstep_interval = fake_stepper_set_microstep_interval, - .set_micro_step_res = fake_stepper_set_micro_step_res, - .get_micro_step_res = fake_stepper_get_micro_step_res, .set_reference_position = fake_stepper_set_reference_position, .get_actual_position = fake_stepper_get_actual_position, .move_to = fake_stepper_move_to, @@ -145,12 +165,26 @@ static DEVICE_API(stepper, fake_stepper_driver_api) = { .set_event_callback = fake_stepper_set_event_callback, }; +#define FAKE_STEPPER_DRV_INIT(inst) \ + \ + static struct fake_stepper_drv_data fake_stepper_drv_data_##inst; \ + \ + DEVICE_DT_INST_DEFINE(inst, fake_stepper_driver_init, NULL, \ + &fake_stepper_drv_data_##inst, NULL, POST_KERNEL, \ + CONFIG_STEPPER_INIT_PRIORITY, &fake_stepper_drv_api); + #define FAKE_STEPPER_INIT(inst) \ \ static struct fake_stepper_data fake_stepper_data_##inst; \ \ - DEVICE_DT_INST_DEFINE(inst, fake_stepper_init, NULL, &fake_stepper_data_##inst, NULL, \ - POST_KERNEL, CONFIG_STEPPER_INIT_PRIORITY, \ - &fake_stepper_driver_api); + DEVICE_DT_INST_DEFINE(inst, fake_stepper_init, NULL, \ + &fake_stepper_data_##inst, NULL, POST_KERNEL, \ + CONFIG_STEPPER_INIT_PRIORITY, &fake_stepper_api); +#define DT_DRV_COMPAT zephyr_fake_stepper_drv +DT_INST_FOREACH_STATUS_OKAY(FAKE_STEPPER_DRV_INIT) +#undef DT_DRV_COMPAT + +#define DT_DRV_COMPAT zephyr_fake_stepper DT_INST_FOREACH_STATUS_OKAY(FAKE_STEPPER_INIT) +#undef DT_DRV_COMPAT diff --git a/drivers/stepper/gpio_stepper/CMakeLists.txt b/drivers/stepper/gpio_stepper/CMakeLists.txt index 9f5a94107fe9..4a3ef2446485 100644 --- a/drivers/stepper/gpio_stepper/CMakeLists.txt +++ b/drivers/stepper/gpio_stepper/CMakeLists.txt @@ -2,7 +2,9 @@ # SPDX-License-Identifier: Apache-2.0 zephyr_library() +zephyr_library_property(ALLOW_EMPTY TRUE) zephyr_library_sources_ifdef(CONFIG_H_BRIDGE_STEPPER h_bridge_stepper.c) +zephyr_library_sources_ifdef(CONFIG_GPIO_STEP_DIR_STEPPER gpio_step_dir.c) -add_subdirectory_ifdef(CONFIG_STEP_DIR_STEPPER step_dir) +add_subdirectory_ifdef(CONFIG_GPIO_STEPPER common) diff --git a/drivers/stepper/gpio_stepper/Kconfig b/drivers/stepper/gpio_stepper/Kconfig index 39596e010f6f..a609fc03828c 100644 --- a/drivers/stepper/gpio_stepper/Kconfig +++ b/drivers/stepper/gpio_stepper/Kconfig @@ -1,5 +1,8 @@ # Copyright (c) 2025 Jilay Sandeep Pandya # SPDX-License-Identifier: Apache-2.0 -source "drivers/stepper/gpio_stepper/Kconfig.h_bridge" -source "drivers/stepper/gpio_stepper/step_dir/Kconfig" +comment "GPIO Stepper Controllers" + +rsource "common/Kconfig" +rsource "Kconfig.gpio_step_dir" +rsource "Kconfig.h_bridge" diff --git a/drivers/stepper/gpio_stepper/Kconfig.gpio_step_dir b/drivers/stepper/gpio_stepper/Kconfig.gpio_step_dir new file mode 100644 index 000000000000..f15637e05703 --- /dev/null +++ b/drivers/stepper/gpio_stepper/Kconfig.gpio_step_dir @@ -0,0 +1,9 @@ +# SPDX-FileCopyrightText: Copyright (c) 2025 Jilay Sandeep Pandya +# SPDX-License-Identifier: Apache-2.0 + +config GPIO_STEP_DIR_STEPPER + bool "Activate driver for gpio step dir stepper control" + select GPIO_STEPPER + depends on DT_HAS_ZEPHYR_GPIO_STEP_DIR_STEPPER_ENABLED + select STEP_DIR_STEPPER + default y diff --git a/drivers/stepper/gpio_stepper/Kconfig.h_bridge b/drivers/stepper/gpio_stepper/Kconfig.h_bridge index f227d7be4aa9..51e17de09b91 100644 --- a/drivers/stepper/gpio_stepper/Kconfig.h_bridge +++ b/drivers/stepper/gpio_stepper/Kconfig.h_bridge @@ -3,6 +3,7 @@ # SPDX-License-Identifier: Apache-2.0 config H_BRIDGE_STEPPER - bool "Activate driver for gpio h-bridge stepper" + bool "Activate driver for gpio h-bridge stepper control" + select GPIO_STEPPER depends on DT_HAS_ZEPHYR_H_BRIDGE_STEPPER_ENABLED default y diff --git a/drivers/stepper/gpio_stepper/common/CMakeLists.txt b/drivers/stepper/gpio_stepper/common/CMakeLists.txt new file mode 100644 index 000000000000..4adbd4748d58 --- /dev/null +++ b/drivers/stepper/gpio_stepper/common/CMakeLists.txt @@ -0,0 +1,8 @@ +# SPDX-FileCopyrightText: Copyright (c) 2025 Jilay Sandeep Pandya +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library_include_directories(include) + +zephyr_library_sources(gpio_stepper_common.c) +zephyr_library_sources(stepper_work_timing.c) +zephyr_library_sources_ifdef(CONFIG_GPIO_STEPPER_COUNTER_TIMING stepper_counter_timing.c) diff --git a/drivers/stepper/gpio_stepper/common/Kconfig b/drivers/stepper/gpio_stepper/common/Kconfig new file mode 100644 index 000000000000..09c3dd1c902f --- /dev/null +++ b/drivers/stepper/gpio_stepper/common/Kconfig @@ -0,0 +1,22 @@ +# Copyright (c) 2025 Jilay Sandeep Pandya +# SPDX-License-Identifier: Apache-2.0 + +config GPIO_STEPPER + bool + help + Enable library used for gpio based stepper controllers. + +if GPIO_STEPPER + +config GPIO_STEPPER_COUNTER_TIMING + bool "Counter use for step timing" + select COUNTER + default y + help + Enable usage of a counter device for accurate stepping. + +module = GPIO_STEPPER +module-str = gpio_stepper +source "drivers/stepper/Kconfig.stepper_event_template" + +endif # GPIO_STEPPER diff --git a/drivers/stepper/gpio_stepper/common/gpio_stepper_common.c b/drivers/stepper/gpio_stepper/common/gpio_stepper_common.c new file mode 100644 index 000000000000..c24395f1fd32 --- /dev/null +++ b/drivers/stepper/gpio_stepper/common/gpio_stepper_common.c @@ -0,0 +1,88 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2024 Fabian Blatz + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "gpio_stepper_common.h" + +#include +LOG_MODULE_REGISTER(gpio_stepper_common, CONFIG_STEPPER_LOG_LEVEL); + +void gpio_stepper_trigger_callback(const struct device *dev, enum stepper_event event) +{ + struct gpio_stepper_common_data *data = dev->data; + + if (!data->callback) { + LOG_WRN_ONCE("No callback set"); + return; + } + + if (!k_is_in_isr()) { + data->callback(dev, event, data->event_cb_user_data); + return; + } + +#ifdef CONFIG_STEPPER_GPIO_STEPPER_GENERATE_ISR_SAFE_EVENTS + /* Dispatch to msgq instead of raising directly */ + int ret = k_msgq_put(&data->event_msgq, &event, K_NO_WAIT); + + if (ret != 0) { + LOG_WRN("Failed to put event in msgq: %d", ret); + } + + ret = k_work_submit(&data->event_callback_work); + if (ret < 0) { + LOG_ERR("Failed to submit work item: %d", ret); + } +#else + LOG_WRN_ONCE("Event callback called from ISR context without ISR safe events enabled"); +#endif /* CONFIG_STEPPER_GPIO_STEPPER_GENERATE_ISR_SAFE_EVENTS */ +} + +#ifdef CONFIG_STEPPER_GPIO_STEPPER_GENERATE_ISR_SAFE_EVENTS +static void gpio_stepper_work_event_handler(struct k_work *work) +{ + struct gpio_stepper_common_data *data = + CONTAINER_OF(work, struct gpio_stepper_common_data, event_callback_work); + enum stepper_event event; + int ret; + + ret = k_msgq_get(&data->event_msgq, &event, K_NO_WAIT); + if (ret != 0) { + return; + } + + /* Run the callback */ + if (data->callback != NULL) { + data->callback(data->dev, event, data->event_cb_user_data); + } + + /* If there are more pending events, resubmit this work item to handle them */ + if (k_msgq_num_used_get(&data->event_msgq) > 0) { + k_work_submit(work); + } +} +#endif /* CONFIG_STEPPER_GPIO_STEPPER_GENERATE_ISR_SAFE_EVENTS */ + +int gpio_stepper_common_init(const struct device *dev) +{ + const struct gpio_stepper_common_config *config = dev->config; + int ret; + + if (config->timing_source->init) { + ret = config->timing_source->init(dev); + if (ret < 0) { + LOG_ERR("Failed to initialize timing source: %d", ret); + return ret; + } + } + +#ifdef CONFIG_STEPPER_GPIO_STEPPER_GENERATE_ISR_SAFE_EVENTS + struct gpio_stepper_common_data *data = dev->data; + + k_msgq_init(&data->event_msgq, data->event_msgq_buffer, sizeof(enum stepper_event), + CONFIG_STEPPER_GPIO_STEPPER_EVENT_QUEUE_LEN); + k_work_init(&data->event_callback_work, gpio_stepper_work_event_handler); +#endif /* CONFIG_STEPPER_GPIO_STEPPER_GENERATE_ISR_SAFE_EVENTS */ + return 0; +} diff --git a/drivers/stepper/gpio_stepper/common/include/gpio_stepper_common.h b/drivers/stepper/gpio_stepper/common/include/gpio_stepper_common.h new file mode 100644 index 000000000000..1eb3b891d968 --- /dev/null +++ b/drivers/stepper/gpio_stepper/common/include/gpio_stepper_common.h @@ -0,0 +1,290 @@ +/* + * Copyright 2024 Fabian Blatz + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVER_STEPPER_GPIO_STEPPER_COMMON_H_ +#define ZEPHYR_DRIVER_STEPPER_GPIO_STEPPER_COMMON_H_ + +/** + * @brief Stepper Driver APIs + * @defgroup gpio_stepper Stepper Driver APIs + * @ingroup io_interfaces + * @{ + */ + +#include +#include +#include +#include + +#include "stepper_timing_source.h" + +/** + * @brief Common GPIO stepper config. + * + * This structure **must** be placed first in the driver's config structure. + */ +struct gpio_stepper_common_config { + const struct stepper_timing_source_api *timing_source; + const struct device *counter; + bool invert_direction; + void (*timing_source_cb)(const struct device *dev); +}; + +/** + * @brief Initialize common GPIO stepper config from devicetree instance. + * If the counter property is set, the timing source will be set to the counter timing + * source. + * + * @param node_id The devicetree node identifier. + */ +#define GPIO_STEPPER_DT_COMMON_CONFIG_INIT(node_id) \ + { \ + .counter = DEVICE_DT_GET_OR_NULL(DT_PHANDLE(node_id, counter)), \ + .invert_direction = DT_PROP(node_id, invert_direction), \ + .timing_source = COND_CODE_1(DT_NODE_HAS_PROP(node_id, counter), \ + (&step_counter_timing_source_api), \ + (&step_work_timing_source_api)), \ + } + +/** + * @brief Initialize common GPIO stepper config from devicetree instance. + * @param inst Instance. + */ +#define GPIO_STEPPER_DT_INST_COMMON_CONFIG_INIT(inst) \ + GPIO_STEPPER_DT_COMMON_CONFIG_INIT(DT_DRV_INST(inst)) + +/** + * @brief Common GPIO stepper data. + * + * This structure **must** be placed first in the driver's data structure. + */ +struct gpio_stepper_common_data { + const struct device *dev; + struct k_spinlock lock; + enum stepper_direction direction; + enum stepper_run_mode run_mode; + uint64_t microstep_interval_ns; + atomic_t actual_position; + atomic_t step_count; + stepper_event_callback_t callback; + void *event_cb_user_data; + + struct k_work_delayable stepper_dwork; +#ifdef CONFIG_GPIO_STEPPER_COUNTER_TIMING + struct counter_top_cfg counter_top_cfg; + bool counter_running; +#endif /* CONFIG_GPIO_STEPPER_COUNTER_TIMING */ + +#ifdef CONFIG_STEPPER_GPIO_STEPPER_GENERATE_ISR_SAFE_EVENTS + struct k_work event_callback_work; + struct k_msgq event_msgq; + uint8_t event_msgq_buffer[CONFIG_STEPPER_GPIO_STEPPER_EVENT_QUEUE_LEN * + sizeof(enum stepper_event)]; +#endif /* CONFIG_STEPPER_GPIO_STEPPER_GENERATE_ISR_SAFE_EVENTS */ +}; + +/** + * @brief Initialize common GPIO stepper data from devicetree instance. + * + * @param node_id The devicetree node identifier. + */ +#define GPIO_STEPPER_DT_COMMON_DATA_INIT(node_id) \ + { \ + .dev = DEVICE_DT_GET(node_id), \ + } + +/** + * @brief Initialize common GPIO stepper data from devicetree instance. + * @param inst Instance. + */ +#define GPIO_STEPPER_DT_INST_COMMON_DATA_INIT(inst) \ + GPIO_STEPPER_DT_COMMON_DATA_INIT(DT_DRV_INST(inst)) + +/** + * @brief Validate the offset of the common data structures. + * + * @param config Name of the config structure. + * @param data Name of the data structure. + */ +#define GPIO_STEPPER_STRUCT_CHECK(config, data) \ + BUILD_ASSERT(offsetof(config, common) == 0, \ + "struct gpio_stepper_common_config must be placed first"); \ + BUILD_ASSERT(offsetof(data, common) == 0, \ + "struct gpio_stepper_common_data must be placed first"); + +/** + * @brief Common function to initialize a GPIO stepper device at init time. + * + * This function must be called at the end of the device init function. + * + * @param dev GPIO stepper device instance. + * + * @retval 0 If initialized successfully. + * @retval -errno Negative errno in case of failure. + */ +int gpio_stepper_common_init(const struct device *dev); + +/** + * @brief Trigger callback function for stepper events. + * @param dev Pointer to the device structure. + * @param event The stepper_event to trigger the callback for. + */ +void gpio_stepper_trigger_callback(const struct device *dev, enum stepper_event event); + +/** + * @brief Set the reference position of the stepper. + * + * @param dev Pointer to the device structure. + * @param value The reference position value to set. + * @return 0 on success, or a negative error code on failure. + */ +static inline int gpio_stepper_common_set_reference_position(const struct device *dev, + const int32_t value) +{ + struct gpio_stepper_common_data *data = dev->data; + + atomic_set(&data->actual_position, value); + + return 0; +} + +/** + * @brief Get the actual (reference) position of the stepper. + * + * @param dev Pointer to the device structure. + * @param value Pointer to a variable where the position value will be stored. + * @return 0 on success, or a negative error code on failure. + */ +static inline int gpio_stepper_common_get_actual_position(const struct device *dev, int32_t *value) +{ + struct gpio_stepper_common_data *data = dev->data; + + *value = atomic_get(&data->actual_position); + + return 0; +} + +/** + * @brief Set the absolute target position of the stepper motor. + * + * @param dev Pointer to the device structure. + * @param value The target position to set. + * @return 0 on success, or a negative error code on failure. + */ +static inline int gpio_stepper_common_move_to(const struct device *dev, const int32_t value) +{ + struct gpio_stepper_common_data *data = dev->data; + int32_t steps_to_move; + + /* Calculate the relative movement required */ + steps_to_move = value - atomic_get(&data->actual_position); + + return stepper_move_by(dev, steps_to_move); +} + +/** + * @brief Check if the stepper motor is still moving. + * + * @param dev Pointer to the device structure. + * @param is_moving Pointer to a boolean where the movement status will be stored. + * @return 0 on success, or a negative error code on failure. + */ +static inline int gpio_stepper_common_is_moving(const struct device *dev, bool *is_moving) +{ + const struct gpio_stepper_common_config *config = dev->config; + + *is_moving = config->timing_source->is_running(dev); + + return 0; +} + +/** + * @brief Set a callback function for stepper events. + * + * This function sets a user-defined callback that will be invoked when a stepper motor event + * occurs. + * + * @param dev Pointer to the device structure. + * @param callback The callback function to set. + * @param user_data Pointer to user-defined data that will be passed to the callback. + * @return 0 on success, or a negative error code on failure. + */ +static inline int gpio_stepper_common_set_event_callback(const struct device *dev, + stepper_event_callback_t callback, + void *user_data) +{ + struct gpio_stepper_common_data *data = dev->data; + + data->callback = callback; + data->event_cb_user_data = user_data; + + return 0; +} + +/** + * @brief Update the direction of the stepper motor based on the step count. + * @param dev Pointer to the device structure. + */ +static inline void gpio_stepper_common_update_direction_from_step_count(const struct device *dev) +{ + struct gpio_stepper_common_data *data = dev->data; + + if (atomic_get(&data->step_count) > 0) { + data->direction = STEPPER_DIRECTION_POSITIVE; + } else if (atomic_get(&data->step_count) < 0) { + data->direction = STEPPER_DIRECTION_NEGATIVE; + } else { + /* Step count is zero, direction remains unchanged */ + } +} + +/** + * @brief Update the remaining steps to move for the stepper motor. + * @param dev Pointer to the device structure. + */ +static inline void gpio_stepper_common_update_remaining_steps(const struct device *dev) +{ + struct gpio_stepper_common_data *data = dev->data; + + if (atomic_get(&data->step_count) > 0) { + atomic_dec(&data->step_count); + } else if (atomic_get(&data->step_count) < 0) { + atomic_inc(&data->step_count); + } +} + +/** + * @brief Task for controlling the stepper motor in position mode. + * @param dev Pointer to the device structure. + */ +static inline void gpio_stepper_common_position_mode_task(const struct device *dev) +{ + struct gpio_stepper_common_data *data = dev->data; + const struct gpio_stepper_common_config *config = dev->config; + + if (config->timing_source->needs_reschedule(dev) && atomic_get(&data->step_count) != 0) { + (void)config->timing_source->start(dev); + } else if (atomic_get(&data->step_count) == 0) { + config->timing_source->stop(data->dev); + gpio_stepper_trigger_callback(data->dev, STEPPER_EVENT_STEPS_COMPLETED); + } +} + +/** + * @brief Task for controlling the stepper motor in velocity mode. + * @param dev Pointer to the device structure. + */ +static inline void gpio_stepper_common_velocity_mode_task(const struct device *dev) +{ + const struct gpio_stepper_common_config *config = dev->config; + + if (config->timing_source->needs_reschedule(dev)) { + (void)config->timing_source->start(dev); + } +} +/** @} */ + +#endif /* ZEPHYR_DRIVER_STEPPER_GPIO_STEPPER_COMMON_H_ */ diff --git a/drivers/stepper/gpio_stepper/step_dir/include/stepper_timing_source.h b/drivers/stepper/gpio_stepper/common/include/stepper_timing_source.h similarity index 87% rename from drivers/stepper/gpio_stepper/step_dir/include/stepper_timing_source.h rename to drivers/stepper/gpio_stepper/common/include/stepper_timing_source.h index ececa56df446..ba222fb7ebf7 100644 --- a/drivers/stepper/gpio_stepper/step_dir/include/stepper_timing_source.h +++ b/drivers/stepper/gpio_stepper/common/include/stepper_timing_source.h @@ -3,8 +3,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef ZEPHYR_DRIVER_STEPPER_GPIO_STEPPER_STEP_DIR_STEPPER_TIMING_SOURCE_H_ -#define ZEPHYR_DRIVER_STEPPER_GPIO_STEPPER_STEP_DIR_STEPPER_TIMING_SOURCE_H_ +#ifndef ZEPHYR_DRIVER_STEPPER_GPIO_STEPPER_STEPPER_TIMING_SOURCE_H_ +#define ZEPHYR_DRIVER_STEPPER_GPIO_STEPPER_STEPPER_TIMING_SOURCE_H_ #include @@ -72,8 +72,8 @@ struct stepper_timing_source_api { }; extern const struct stepper_timing_source_api step_work_timing_source_api; -#ifdef CONFIG_STEP_DIR_STEPPER_COUNTER_TIMING +#ifdef CONFIG_GPIO_STEPPER_COUNTER_TIMING extern const struct stepper_timing_source_api step_counter_timing_source_api; -#endif /* CONFIG_STEP_DIR_STEPPER_COUNTER_TIMING */ +#endif /* CONFIG_GPIO_STEPPER_COUNTER_TIMING */ -#endif /* ZEPHYR_DRIVER_STEPPER_GPIO_STEPPER_STEP_DIR_STEPPER_TIMING_SOURCE_H_ */ +#endif /* ZEPHYR_DRIVER_STEPPER_GPIO_STEPPER_STEPPER_TIMING_SOURCE_H_ */ diff --git a/drivers/stepper/gpio_stepper/step_dir/stepper_counter_timing.c b/drivers/stepper/gpio_stepper/common/stepper_counter_timing.c similarity index 75% rename from drivers/stepper/gpio_stepper/step_dir/stepper_counter_timing.c rename to drivers/stepper/gpio_stepper/common/stepper_counter_timing.c index 96374628c28f..f47e7cf2f08f 100644 --- a/drivers/stepper/gpio_stepper/step_dir/stepper_counter_timing.c +++ b/drivers/stepper/gpio_stepper/common/stepper_counter_timing.c @@ -4,24 +4,26 @@ */ #include -#include +#include "gpio_stepper_common.h" +#include "stepper_timing_source.h" #include -LOG_MODULE_DECLARE(step_dir_stepper); +LOG_MODULE_DECLARE(gpio_stepper_common); static void step_counter_top_interrupt(const struct device *dev, void *user_data) { ARG_UNUSED(dev); - struct step_dir_stepper_common_data *data = user_data; + struct gpio_stepper_common_data *data = user_data; + const struct gpio_stepper_common_config *config = data->dev->config; - stepper_handle_timing_signal(data->dev); + config->timing_source_cb(data->dev); } int step_counter_timing_source_update(const struct device *dev, const uint64_t microstep_interval_ns) { - const struct step_dir_stepper_common_config *config = dev->config; - struct step_dir_stepper_common_data *data = dev->data; + const struct gpio_stepper_common_config *config = dev->config; + struct gpio_stepper_common_data *data = dev->data; int ret; if (microstep_interval_ns == 0) { @@ -48,8 +50,8 @@ int step_counter_timing_source_update(const struct device *dev, int step_counter_timing_source_start(const struct device *dev) { - const struct step_dir_stepper_common_config *config = dev->config; - struct step_dir_stepper_common_data *data = dev->data; + const struct gpio_stepper_common_config *config = dev->config; + struct gpio_stepper_common_data *data = dev->data; int ret; ret = counter_start(config->counter); @@ -65,8 +67,8 @@ int step_counter_timing_source_start(const struct device *dev) int step_counter_timing_source_stop(const struct device *dev) { - const struct step_dir_stepper_common_config *config = dev->config; - struct step_dir_stepper_common_data *data = dev->data; + const struct gpio_stepper_common_config *config = dev->config; + struct gpio_stepper_common_data *data = dev->data; int ret; ret = counter_stop(config->counter); @@ -88,15 +90,15 @@ bool step_counter_timing_source_needs_reschedule(const struct device *dev) bool step_counter_timing_source_is_running(const struct device *dev) { - struct step_dir_stepper_common_data *data = dev->data; + struct gpio_stepper_common_data *data = dev->data; return data->counter_running; } int step_counter_timing_source_init(const struct device *dev) { - const struct step_dir_stepper_common_config *config = dev->config; - struct step_dir_stepper_common_data *data = dev->data; + const struct gpio_stepper_common_config *config = dev->config; + struct gpio_stepper_common_data *data = dev->data; if (!device_is_ready(config->counter)) { LOG_ERR("Counter device is not ready"); diff --git a/drivers/stepper/gpio_stepper/step_dir/stepper_work_timing.c b/drivers/stepper/gpio_stepper/common/stepper_work_timing.c similarity index 76% rename from drivers/stepper/gpio_stepper/step_dir/stepper_work_timing.c rename to drivers/stepper/gpio_stepper/common/stepper_work_timing.c index 923b148082f9..d7681005a85c 100644 --- a/drivers/stepper/gpio_stepper/step_dir/stepper_work_timing.c +++ b/drivers/stepper/gpio_stepper/common/stepper_work_timing.c @@ -4,11 +4,11 @@ */ #include -#include +#include "gpio_stepper_common.h" static k_timeout_t stepper_movement_delay(const struct device *dev) { - const struct step_dir_stepper_common_data *data = dev->data; + const struct gpio_stepper_common_data *data = dev->data; if (data->microstep_interval_ns == 0) { return K_FOREVER; @@ -20,15 +20,16 @@ static k_timeout_t stepper_movement_delay(const struct device *dev) static void stepper_work_step_handler(struct k_work *work) { struct k_work_delayable *dwork = k_work_delayable_from_work(work); - struct step_dir_stepper_common_data *data = - CONTAINER_OF(dwork, struct step_dir_stepper_common_data, stepper_dwork); + struct gpio_stepper_common_data *data = + CONTAINER_OF(dwork, struct gpio_stepper_common_data, stepper_dwork); + const struct gpio_stepper_common_config *config = data->dev->config; - stepper_handle_timing_signal(data->dev); + config->timing_source_cb(data->dev); } int step_work_timing_source_init(const struct device *dev) { - struct step_dir_stepper_common_data *data = dev->data; + struct gpio_stepper_common_data *data = dev->data; k_work_init_delayable(&data->stepper_dwork, stepper_work_step_handler); @@ -44,14 +45,14 @@ int step_work_timing_source_update(const struct device *dev, const uint64_t micr int step_work_timing_source_start(const struct device *dev) { - struct step_dir_stepper_common_data *data = dev->data; + struct gpio_stepper_common_data *data = dev->data; return k_work_reschedule(&data->stepper_dwork, stepper_movement_delay(dev)); } int step_work_timing_source_stop(const struct device *dev) { - struct step_dir_stepper_common_data *data = dev->data; + struct gpio_stepper_common_data *data = dev->data; return k_work_cancel_delayable(&data->stepper_dwork); } @@ -64,7 +65,7 @@ bool step_work_timing_source_needs_reschedule(const struct device *dev) bool step_work_timing_source_is_running(const struct device *dev) { - struct step_dir_stepper_common_data *data = dev->data; + struct gpio_stepper_common_data *data = dev->data; return k_work_delayable_is_pending(&data->stepper_dwork); } diff --git a/drivers/stepper/gpio_stepper/gpio_step_dir.c b/drivers/stepper/gpio_stepper/gpio_step_dir.c new file mode 100644 index 000000000000..12c7d11671a2 --- /dev/null +++ b/drivers/stepper/gpio_stepper/gpio_step_dir.c @@ -0,0 +1,304 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2025 Jilay Sandeep Pandya + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT zephyr_gpio_step_dir_stepper + +#include +#include +#include + +#include + +#include +LOG_MODULE_REGISTER(gpio_step_dir_stepper, CONFIG_STEPPER_LOG_LEVEL); + +struct zephyr_gpio_step_dir_stepper_config { + struct gpio_stepper_common_config common; + const struct gpio_dt_spec step_pin; + const struct gpio_dt_spec dir_pin; + const struct device *stepper_drv; +}; + +struct zephyr_gpio_step_dir_stepper_data { + struct gpio_stepper_common_data common; + uint32_t step_width_ns; + bool dual_edge; + atomic_t step_high; +}; + +GPIO_STEPPER_STRUCT_CHECK(struct zephyr_gpio_step_dir_stepper_config, + struct zephyr_gpio_step_dir_stepper_data); + +static int update_dir_pin(const struct device *dev) +{ + const struct zephyr_gpio_step_dir_stepper_config *config = dev->config; + struct zephyr_gpio_step_dir_stepper_data *data = dev->data; + int ret; + + switch (data->common.direction) { + case STEPPER_DIRECTION_POSITIVE: + ret = gpio_pin_set_dt(&config->dir_pin, 1 ^ config->common.invert_direction); + break; + case STEPPER_DIRECTION_NEGATIVE: + ret = gpio_pin_set_dt(&config->dir_pin, 0 ^ config->common.invert_direction); + break; + default: + LOG_ERR("Unsupported direction: %d", data->common.direction); + return -ENOTSUP; + } + if (ret < 0) { + LOG_ERR("Failed to set direction: %d", ret); + return ret; + } + + return ret; +} + +static void stepper_handle_timing_signal(const struct device *dev) +{ + const struct zephyr_gpio_step_dir_stepper_config *config = dev->config; + struct zephyr_gpio_step_dir_stepper_data *data = dev->data; + int ret; + + atomic_val_t step_pin_status = atomic_xor(&data->step_high, 1) ^ 1; + + ret = gpio_pin_set_dt(&config->step_pin, atomic_get(&step_pin_status)); + if (ret < 0) { + LOG_ERR("Failed to set step pin: %d", ret); + return; + } + + if (!atomic_get(&step_pin_status) || data->dual_edge) { + if (data->common.direction == STEPPER_DIRECTION_POSITIVE) { + atomic_inc(&data->common.actual_position); + } else { + atomic_dec(&data->common.actual_position); + } + } + + switch (data->common.run_mode) { + case STEPPER_RUN_MODE_POSITION: + if (!data->step_high || data->dual_edge) { + gpio_stepper_common_update_remaining_steps(dev); + } + gpio_stepper_common_position_mode_task(dev); + break; + case STEPPER_RUN_MODE_VELOCITY: + gpio_stepper_common_velocity_mode_task(dev); + break; + default: + LOG_WRN("Unsupported run mode: %d", data->common.run_mode); + break; + } +} + +static int start_stepping(const struct device *dev) +{ + const struct zephyr_gpio_step_dir_stepper_config *config = dev->config; + struct zephyr_gpio_step_dir_stepper_data *data = dev->data; + int ret; + + ret = config->common.timing_source->update( + dev, data->dual_edge ? data->common.microstep_interval_ns + : data->common.microstep_interval_ns / 2); + if (ret < 0) { + LOG_ERR("Failed to update timing source: %d", ret); + return ret; + } + + ret = config->common.timing_source->start(dev); + if (ret < 0) { + LOG_ERR("Failed to start timing source: %d", ret); + return ret; + } + + stepper_handle_timing_signal(dev); + return 0; +} + +static int gpio_step_dir_move_by(const struct device *dev, const int32_t micro_steps) +{ + struct zephyr_gpio_step_dir_stepper_data *data = dev->data; + const struct zephyr_gpio_step_dir_stepper_config *config = dev->config; + int ret; + + if (data->common.microstep_interval_ns == 0) { + LOG_ERR("Step interval not set or invalid step interval set"); + return -EINVAL; + } + + if (micro_steps == 0) { + gpio_stepper_trigger_callback(data->common.dev, STEPPER_EVENT_STEPS_COMPLETED); + config->common.timing_source->stop(dev); + return 0; + } + + K_SPINLOCK(&data->common.lock) { + data->common.run_mode = STEPPER_RUN_MODE_POSITION; + atomic_set(&data->common.step_count, micro_steps); + gpio_stepper_common_update_direction_from_step_count(dev); + ret = update_dir_pin(dev); + if (ret < 0) { + K_SPINLOCK_BREAK; + } + + ret = start_stepping(dev); + } + + return ret; +} + +static int gpio_step_dir_set_microstep_interval(const struct device *dev, + const uint64_t microstep_interval_ns) +{ + const struct zephyr_gpio_step_dir_stepper_config *config = dev->config; + struct zephyr_gpio_step_dir_stepper_data *data = dev->data; + + if (microstep_interval_ns == 0) { + LOG_ERR("Step interval cannot be zero"); + return -EINVAL; + } + + if (data->dual_edge && (microstep_interval_ns < data->step_width_ns)) { + LOG_ERR("Step interval too small for configured step width"); + return -EINVAL; + } + + if (microstep_interval_ns < 2 * data->step_width_ns) { + LOG_ERR("Step interval too small for configured step width"); + return -EINVAL; + } + + K_SPINLOCK(&data->common.lock) { + data->common.microstep_interval_ns = microstep_interval_ns; + config->common.timing_source->update( + dev, data->dual_edge ? data->common.microstep_interval_ns + : data->common.microstep_interval_ns / 2); + } + + return 0; +} + +int gpio_step_dir_stepper_run(const struct device *dev, const enum stepper_direction direction) +{ + struct gpio_stepper_common_data *data = dev->data; + int ret; + + if (data->microstep_interval_ns == 0) { + LOG_ERR("Step interval not set or invalid step interval set"); + return -EINVAL; + } + + K_SPINLOCK(&data->lock) { + data->run_mode = STEPPER_RUN_MODE_VELOCITY; + data->direction = direction; + ret = update_dir_pin(dev); + if (ret < 0) { + K_SPINLOCK_BREAK; + } + + ret = start_stepping(dev); + } + + return ret; +} + +int gpio_step_dir_stepper_stop(const struct device *dev) +{ + const struct zephyr_gpio_step_dir_stepper_config *config = dev->config; + struct zephyr_gpio_step_dir_stepper_data *data = dev->data; + int ret; + + ret = config->common.timing_source->stop(dev); + if (ret != 0) { + LOG_ERR("Failed to stop timing source: %d", ret); + return ret; + } + + if (!data->dual_edge && atomic_cas(&data->step_high, 1, 0)) { + gpio_pin_set_dt(&config->step_pin, 0); + /* If we are in the high state, we need to account for that step */ + if (data->common.direction == STEPPER_DIRECTION_POSITIVE) { + atomic_inc(&data->common.actual_position); + } else { + atomic_dec(&data->common.actual_position); + } + } + + gpio_stepper_trigger_callback(dev, STEPPER_EVENT_STOPPED); + + return 0; +} + +static int gpio_step_dir_stepper_init(const struct device *dev) +{ + const struct zephyr_gpio_step_dir_stepper_config *config = dev->config; + struct zephyr_gpio_step_dir_stepper_data *data = dev->data; + int ret; + + if (!gpio_is_ready_dt(&config->step_pin) || !gpio_is_ready_dt(&config->dir_pin)) { + LOG_ERR("GPIO pins are not ready"); + return -ENODEV; + } + + ret = gpio_pin_configure_dt(&config->step_pin, GPIO_OUTPUT); + if (ret < 0) { + LOG_ERR("Failed to configure step pin: %d", ret); + return ret; + } + + ret = gpio_pin_configure_dt(&config->dir_pin, GPIO_OUTPUT); + if (ret < 0) { + LOG_ERR("Failed to configure dir pin: %d", ret); + return ret; + } + + if (config->stepper_drv) { + if (device_is_ready(config->stepper_drv)) { + const struct step_dir_stepper_common_config *drv_config = + config->stepper_drv->config; + data->step_width_ns = drv_config->step_width_ns; + data->dual_edge = drv_config->dual_edge; + } else { + LOG_ERR("Stepper driver device not ready"); + return -ENODEV; + } + } else { + LOG_DBG("Steper driver not specified"); + } + + return gpio_stepper_common_init(dev); +} + +static DEVICE_API(stepper, gpio_step_dir_stepper_api) = { + .move_by = gpio_step_dir_move_by, + .move_to = gpio_stepper_common_move_to, + .is_moving = gpio_stepper_common_is_moving, + .set_reference_position = gpio_stepper_common_set_reference_position, + .get_actual_position = gpio_stepper_common_get_actual_position, + .set_event_callback = gpio_stepper_common_set_event_callback, + .set_microstep_interval = gpio_step_dir_set_microstep_interval, + .run = gpio_step_dir_stepper_run, + .stop = gpio_step_dir_stepper_stop, +}; + +#define ZEPHYR_GPIO_STEP_DIR_CONTROLLER_DEFINE(inst) \ + static const struct zephyr_gpio_step_dir_stepper_config gpio_step_dir_config_##inst = { \ + .common = GPIO_STEPPER_DT_INST_COMMON_CONFIG_INIT(inst), \ + .common.timing_source_cb = stepper_handle_timing_signal, \ + .step_pin = GPIO_DT_SPEC_INST_GET(inst, step_gpios), \ + .dir_pin = GPIO_DT_SPEC_INST_GET(inst, dir_gpios), \ + .stepper_drv = DEVICE_DT_GET_OR_NULL(DT_PHANDLE(DT_DRV_INST(inst), stepper_drv)), \ + }; \ + static struct zephyr_gpio_step_dir_stepper_data gpio_step_dir_data_##inst = { \ + .common = GPIO_STEPPER_DT_INST_COMMON_DATA_INIT(inst), \ + .step_high = ATOMIC_INIT(0), \ + }; \ + DEVICE_DT_INST_DEFINE(inst, gpio_step_dir_stepper_init, NULL, \ + &gpio_step_dir_data_##inst, &gpio_step_dir_config_##inst, \ + POST_KERNEL, CONFIG_STEPPER_INIT_PRIORITY, \ + &gpio_step_dir_stepper_api); + +DT_INST_FOREACH_STATUS_OKAY(ZEPHYR_GPIO_STEP_DIR_CONTROLLER_DEFINE) diff --git a/drivers/stepper/gpio_stepper/h_bridge_stepper.c b/drivers/stepper/gpio_stepper/h_bridge_stepper.c index b6580a3c5876..3a85bb89af5f 100644 --- a/drivers/stepper/gpio_stepper/h_bridge_stepper.c +++ b/drivers/stepper/gpio_stepper/h_bridge_stepper.c @@ -11,38 +11,32 @@ #include #include +#include + #include LOG_MODULE_REGISTER(h_bridge_stepper, CONFIG_STEPPER_LOG_LEVEL); -#define MAX_MICRO_STEP_RES STEPPER_MICRO_STEP_2 -#define NUM_CONTROL_PINS 4 +#define LUT_MAX_STEP_GAP 2 +#define NUM_CONTROL_PINS 4 static const uint8_t - half_step_lookup_table[NUM_CONTROL_PINS * MAX_MICRO_STEP_RES][NUM_CONTROL_PINS] = { - {1u, 1u, 0u, 0u}, {0u, 1u, 0u, 0u}, {0u, 1u, 1u, 0u}, {0u, 0u, 1u, 0u}, - {0u, 0u, 1u, 1u}, {0u, 0u, 0u, 1u}, {1u, 0u, 0u, 1u}, {1u, 0u, 0u, 0u}}; + half_step_lookup_table[NUM_CONTROL_PINS * LUT_MAX_STEP_GAP][NUM_CONTROL_PINS] = { + {1u, 1u, 0u, 0u}, {0u, 1u, 0u, 0u}, {0u, 1u, 1u, 0u}, {0u, 0u, 1u, 0u}, + {0u, 0u, 1u, 1u}, {0u, 0u, 0u, 1u}, {1u, 0u, 0u, 1u}, {1u, 0u, 0u, 0u}}; struct h_bridge_stepper_config { - const struct gpio_dt_spec en_pin; + struct gpio_stepper_common_config common; const struct gpio_dt_spec *control_pins; - bool invert_direction; + uint8_t step_gap; }; struct h_bridge_stepper_data { - const struct device *dev; - struct k_spinlock lock; - enum stepper_direction direction; - enum stepper_run_mode run_mode; - uint8_t step_gap; + struct gpio_stepper_common_data common; uint8_t coil_charge; - struct k_work_delayable stepper_dwork; - int32_t actual_position; - uint64_t delay_in_ns; - int32_t step_count; - stepper_event_callback_t callback; - void *event_cb_user_data; }; +GPIO_STEPPER_STRUCT_CHECK(struct h_bridge_stepper_config, struct h_bridge_stepper_data); + static int stepper_motor_set_coil_charge(const struct device *dev) { struct h_bridge_stepper_data *data = dev->data; @@ -63,70 +57,47 @@ static int stepper_motor_set_coil_charge(const struct device *dev) static void increment_coil_charge(const struct device *dev) { + const struct h_bridge_stepper_config *config = dev->config; struct h_bridge_stepper_data *data = dev->data; - if (data->coil_charge == NUM_CONTROL_PINS * MAX_MICRO_STEP_RES - data->step_gap) { + if (data->coil_charge == NUM_CONTROL_PINS * LUT_MAX_STEP_GAP - config->step_gap) { data->coil_charge = 0; } else { - data->coil_charge = data->coil_charge + data->step_gap; + data->coil_charge = data->coil_charge + config->step_gap; } } static void decrement_coil_charge(const struct device *dev) { + const struct h_bridge_stepper_config *config = dev->config; struct h_bridge_stepper_data *data = dev->data; if (data->coil_charge == 0) { - data->coil_charge = NUM_CONTROL_PINS * MAX_MICRO_STEP_RES - data->step_gap; + data->coil_charge = NUM_CONTROL_PINS * LUT_MAX_STEP_GAP - config->step_gap; } else { - data->coil_charge = data->coil_charge - data->step_gap; + data->coil_charge = data->coil_charge - config->step_gap; } } static void update_coil_charge(const struct device *dev) { - const struct h_bridge_stepper_config *config = dev->config; - struct h_bridge_stepper_data *data = dev->data; + const struct gpio_stepper_common_config *config = dev->config; + struct gpio_stepper_common_data *data = dev->data; if (data->direction == STEPPER_DIRECTION_POSITIVE) { config->invert_direction ? decrement_coil_charge(dev) : increment_coil_charge(dev); - data->actual_position++; + atomic_inc(&data->actual_position); } else if (data->direction == STEPPER_DIRECTION_NEGATIVE) { config->invert_direction ? increment_coil_charge(dev) : decrement_coil_charge(dev); - data->actual_position--; - } -} - -static void update_remaining_steps(const struct device *dev) -{ - struct h_bridge_stepper_data *data = dev->data; - - if (data->step_count > 0) { - data->step_count--; - } else if (data->step_count < 0) { - data->step_count++; + atomic_dec(&data->actual_position); } } -static void update_direction_from_step_count(const struct device *dev) +static void stepper_work_step_handler(const struct device *dev) { - struct h_bridge_stepper_data *data = dev->data; - - if (data->step_count > 0) { - data->direction = STEPPER_DIRECTION_POSITIVE; - } else if (data->step_count < 0) { - data->direction = STEPPER_DIRECTION_NEGATIVE; - } else { - LOG_ERR("Step count is zero"); - } -} - -static void position_mode_task(const struct device *dev) -{ - struct h_bridge_stepper_data *data = dev->data; + struct gpio_stepper_common_data *data = dev->data; int ret; - update_remaining_steps(dev); ret = stepper_motor_set_coil_charge(dev); if (ret < 0) { LOG_ERR("Failed to set coil charge: %d", ret); @@ -134,45 +105,14 @@ static void position_mode_task(const struct device *dev) } update_coil_charge(dev); - if (data->step_count) { - (void)k_work_reschedule(&data->stepper_dwork, K_NSEC(data->delay_in_ns)); - } else { - if (data->callback) { - data->callback(data->dev, STEPPER_EVENT_STEPS_COMPLETED, - data->event_cb_user_data); - } - (void)k_work_cancel_delayable(&data->stepper_dwork); - } -} - -static void velocity_mode_task(const struct device *dev) -{ - struct h_bridge_stepper_data *data = dev->data; - int ret; - - ret = stepper_motor_set_coil_charge(dev); - if (ret < 0) { - LOG_ERR("Failed to set coil charge: %d", ret); - return; - } - - update_coil_charge(dev); - (void)k_work_reschedule(&data->stepper_dwork, K_NSEC(data->delay_in_ns)); -} - -static void stepper_work_step_handler(struct k_work *work) -{ - struct k_work_delayable *dwork = k_work_delayable_from_work(work); - struct h_bridge_stepper_data *data = - CONTAINER_OF(dwork, struct h_bridge_stepper_data, stepper_dwork); - K_SPINLOCK(&data->lock) { switch (data->run_mode) { case STEPPER_RUN_MODE_POSITION: - position_mode_task(data->dev); + gpio_stepper_common_update_remaining_steps(dev); + gpio_stepper_common_position_mode_task(data->dev); break; case STEPPER_RUN_MODE_VELOCITY: - velocity_mode_task(data->dev); + gpio_stepper_common_velocity_mode_task(data->dev); break; default: LOG_WRN("Unsupported run mode %d", data->run_mode); @@ -183,74 +123,45 @@ static void stepper_work_step_handler(struct k_work *work) static int h_bridge_stepper_move_by(const struct device *dev, int32_t micro_steps) { - struct h_bridge_stepper_data *data = dev->data; + const struct gpio_stepper_common_config *config = dev->config; + struct gpio_stepper_common_data *data = dev->data; + int ret; - if (data->delay_in_ns == 0) { + if (data->microstep_interval_ns == 0) { LOG_ERR("Step interval not set or invalid step interval set"); return -EINVAL; } if (micro_steps == 0) { - (void)k_work_cancel_delayable(&data->stepper_dwork); - if (data->callback) { - data->callback(data->dev, STEPPER_EVENT_STEPS_COMPLETED, - data->event_cb_user_data); - } + gpio_stepper_trigger_callback(dev, STEPPER_EVENT_STEPS_COMPLETED); + config->timing_source->stop(dev); return 0; } - K_SPINLOCK(&data->lock) { - data->run_mode = STEPPER_RUN_MODE_POSITION; - data->step_count = micro_steps; - update_direction_from_step_count(dev); - (void)k_work_reschedule(&data->stepper_dwork, K_NO_WAIT); - } - return 0; -} - -static int h_bridge_stepper_set_reference_position(const struct device *dev, int32_t position) -{ - struct h_bridge_stepper_data *data = dev->data; - - K_SPINLOCK(&data->lock) { - data->actual_position = position; - } - return 0; -} - -static int h_bridge_stepper_get_actual_position(const struct device *dev, int32_t *position) -{ - struct h_bridge_stepper_data *data = dev->data; K_SPINLOCK(&data->lock) { - *position = data->actual_position; - } - return 0; -} - -static int h_bridge_stepper_move_to(const struct device *dev, int32_t micro_steps) -{ - struct h_bridge_stepper_data *data = dev->data; - int32_t steps_to_move; + data->run_mode = STEPPER_RUN_MODE_POSITION; + atomic_set(&data->step_count, micro_steps); + gpio_stepper_common_update_direction_from_step_count(dev); + ret = config->timing_source->update(dev, data->microstep_interval_ns); + if (ret < 0) { + LOG_ERR("Failed to update timing source: %d", ret); + K_SPINLOCK_BREAK; + } - K_SPINLOCK(&data->lock) { - steps_to_move = micro_steps - data->actual_position; + ret = config->timing_source->start(dev); + if (ret < 0) { + LOG_ERR("Failed to start timing source: %d", ret); + } } - return h_bridge_stepper_move_by(dev, steps_to_move); -} -static int h_bridge_stepper_is_moving(const struct device *dev, bool *is_moving) -{ - struct h_bridge_stepper_data *data = dev->data; - - *is_moving = k_work_delayable_is_pending(&data->stepper_dwork); - LOG_DBG("Motor is %s moving", *is_moving ? "" : "not"); return 0; } static int h_bridge_stepper_set_microstep_interval(const struct device *dev, uint64_t microstep_interval_ns) { - struct h_bridge_stepper_data *data = dev->data; + const struct gpio_stepper_common_config *config = dev->config; + struct gpio_stepper_common_data *data = dev->data; if (microstep_interval_ns == 0) { LOG_ERR("Step interval is invalid."); @@ -258,17 +169,21 @@ static int h_bridge_stepper_set_microstep_interval(const struct device *dev, } K_SPINLOCK(&data->lock) { - data->delay_in_ns = microstep_interval_ns; + data->microstep_interval_ns = microstep_interval_ns; + config->timing_source->update(dev, microstep_interval_ns); } LOG_DBG("Setting Motor step interval to %llu", microstep_interval_ns); + return 0; } static int h_bridge_stepper_run(const struct device *dev, const enum stepper_direction direction) { - struct h_bridge_stepper_data *data = dev->data; + const struct gpio_stepper_common_config *config = dev->config; + struct gpio_stepper_common_data *data = dev->data; + int ret; - if (data->delay_in_ns == 0) { + if (data->microstep_interval_ns == 0) { LOG_ERR("Step interval not set or invalid step interval set"); return -EINVAL; } @@ -276,144 +191,68 @@ static int h_bridge_stepper_run(const struct device *dev, const enum stepper_dir K_SPINLOCK(&data->lock) { data->run_mode = STEPPER_RUN_MODE_VELOCITY; data->direction = direction; - (void)k_work_reschedule(&data->stepper_dwork, K_NO_WAIT); - } - return 0; -} - -static int h_bridge_stepper_set_micro_step_res(const struct device *dev, - enum stepper_micro_step_resolution micro_step_res) -{ - struct h_bridge_stepper_data *data = dev->data; - int err = 0; - - K_SPINLOCK(&data->lock) { - switch (micro_step_res) { - case STEPPER_MICRO_STEP_1: - case STEPPER_MICRO_STEP_2: - data->step_gap = MAX_MICRO_STEP_RES >> (micro_step_res - 1); - break; - default: - LOG_ERR("Unsupported micro step resolution %d", micro_step_res); - err = -ENOTSUP; + ret = config->timing_source->update(dev, data->microstep_interval_ns); + if (ret < 0) { + LOG_ERR("Failed to update timing source: %d", ret); + K_SPINLOCK_BREAK; } - } - return err; -} -static int h_bridge_stepper_get_micro_step_res(const struct device *dev, - enum stepper_micro_step_resolution *micro_step_res) -{ - struct h_bridge_stepper_data *data = dev->data; - *micro_step_res = MAX_MICRO_STEP_RES >> (data->step_gap - 1); - return 0; -} - -static int h_bridge_stepper_set_event_callback(const struct device *dev, - stepper_event_callback_t callback, void *user_data) -{ - struct h_bridge_stepper_data *data = dev->data; - - K_SPINLOCK(&data->lock) { - data->callback = callback; - data->event_cb_user_data = user_data; - } - return 0; -} - -static int h_bridge_stepper_enable(const struct device *dev) -{ - const struct h_bridge_stepper_config *config = dev->config; - struct h_bridge_stepper_data *data = dev->data; - int err; - - K_SPINLOCK(&data->lock) { - if (config->en_pin.port != NULL) { - err = gpio_pin_set_dt(&config->en_pin, 1); - } else { - LOG_DBG("No en_pin detected"); - err = -ENOTSUP; + ret = config->timing_source->start(dev); + if (ret < 0) { + LOG_ERR("Failed to start timing source: %d", ret); } } - return err; -} - -static int h_bridge_stepper_disable(const struct device *dev) -{ - const struct h_bridge_stepper_config *config = dev->config; - struct h_bridge_stepper_data *data = dev->data; - int err; - K_SPINLOCK(&data->lock) { - if (config->en_pin.port != NULL) { - err = gpio_pin_set_dt(&config->en_pin, 0); - } else { - LOG_DBG("No en_pin detected, power stages will not be turned off if " - "stepper is in motion"); - err = -ENOTSUP; - } - } - return err; + return 0; } static int h_bridge_stepper_stop(const struct device *dev) { - struct h_bridge_stepper_data *data = dev->data; + const struct gpio_stepper_common_config *config = dev->config; + struct gpio_stepper_common_data *data = dev->data; int err; K_SPINLOCK(&data->lock) { - err = k_work_cancel_delayable(&data->stepper_dwork); - - if (data->callback && !err) { - data->callback(data->dev, STEPPER_EVENT_STOPPED, data->event_cb_user_data); - } + err = config->timing_source->stop(dev); + gpio_stepper_trigger_callback(dev, STEPPER_EVENT_STOPPED); } + return err; } static int h_bridge_stepper_init(const struct device *dev) { - struct h_bridge_stepper_data *data = dev->data; + struct gpio_stepper_common_data *data = dev->data; const struct h_bridge_stepper_config *config = dev->config; int err; data->dev = dev; LOG_DBG("Initializing %s h_bridge_stepper with %d pin", dev->name, NUM_CONTROL_PINS); for (uint8_t n_pin = 0; n_pin < NUM_CONTROL_PINS; n_pin++) { - (void)gpio_pin_configure_dt(&config->control_pins[n_pin], GPIO_OUTPUT_INACTIVE); - } - - if (config->en_pin.port != NULL) { - if (!gpio_is_ready_dt(&config->en_pin)) { - LOG_ERR("Enable Pin is not ready"); + if (!gpio_is_ready_dt(&config->control_pins[n_pin])) { + LOG_ERR("Control pin %d is not ready", n_pin); return -ENODEV; } - - err = gpio_pin_configure_dt(&config->en_pin, GPIO_OUTPUT_INACTIVE); - if (err != 0) { - LOG_ERR("%s: Failed to configure en_pin (error: %d)", dev->name, err); - return err; + err = gpio_pin_configure_dt(&config->control_pins[n_pin], GPIO_OUTPUT_INACTIVE); + if (err < 0) { + LOG_ERR("Failed to configure control pin %d: %d", n_pin, err); + return -ENODEV; } } - k_work_init_delayable(&data->stepper_dwork, stepper_work_step_handler); - return 0; + return gpio_stepper_common_init(dev); } static DEVICE_API(stepper, h_bridge_stepper_api) = { - .enable = h_bridge_stepper_enable, - .disable = h_bridge_stepper_disable, - .set_micro_step_res = h_bridge_stepper_set_micro_step_res, - .get_micro_step_res = h_bridge_stepper_get_micro_step_res, - .set_reference_position = h_bridge_stepper_set_reference_position, - .get_actual_position = h_bridge_stepper_get_actual_position, - .set_event_callback = h_bridge_stepper_set_event_callback, + .set_reference_position = gpio_stepper_common_set_reference_position, + .get_actual_position = gpio_stepper_common_get_actual_position, + .set_event_callback = gpio_stepper_common_set_event_callback, .set_microstep_interval = h_bridge_stepper_set_microstep_interval, .move_by = h_bridge_stepper_move_by, - .move_to = h_bridge_stepper_move_to, + .move_to = gpio_stepper_common_move_to, .run = h_bridge_stepper_run, .stop = h_bridge_stepper_stop, - .is_moving = h_bridge_stepper_is_moving, + .is_moving = gpio_stepper_common_is_moving, }; #define H_BRIDGE_STEPPER_DEFINE(inst) \ @@ -423,14 +262,11 @@ static DEVICE_API(stepper, h_bridge_stepper_api) = { BUILD_ASSERT(ARRAY_SIZE(h_bridge_stepper_motor_control_pins_##inst) == 4, \ "h_bridge stepper driver currently supports only 4 wire configuration"); \ static const struct h_bridge_stepper_config h_bridge_stepper_config_##inst = { \ - .en_pin = GPIO_DT_SPEC_INST_GET_OR(inst, en_gpios, {0}), \ - .invert_direction = DT_INST_PROP(inst, invert_direction), \ + .common = GPIO_STEPPER_DT_INST_COMMON_CONFIG_INIT(inst), \ + .common.timing_source_cb = stepper_work_step_handler, \ + .step_gap = DT_INST_PROP(inst, lut_step_gap), \ .control_pins = h_bridge_stepper_motor_control_pins_##inst}; \ - static struct h_bridge_stepper_data h_bridge_stepper_data_##inst = { \ - .step_gap = MAX_MICRO_STEP_RES >> (DT_INST_PROP(inst, micro_step_res) - 1), \ - }; \ - BUILD_ASSERT(DT_INST_PROP(inst, micro_step_res) <= STEPPER_MICRO_STEP_2, \ - "h_bridge stepper driver supports up to 2 micro steps"); \ + static struct h_bridge_stepper_data h_bridge_stepper_data_##inst; \ DEVICE_DT_INST_DEFINE(inst, h_bridge_stepper_init, NULL, &h_bridge_stepper_data_##inst, \ &h_bridge_stepper_config_##inst, POST_KERNEL, \ CONFIG_STEPPER_INIT_PRIORITY, &h_bridge_stepper_api); diff --git a/drivers/stepper/gpio_stepper/step_dir/CMakeLists.txt b/drivers/stepper/gpio_stepper/step_dir/CMakeLists.txt deleted file mode 100644 index f3976f5d1971..000000000000 --- a/drivers/stepper/gpio_stepper/step_dir/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -# SPDX-FileCopyrightText: Copyright (c) 2024 Fabian Blatz -# SPDX-License-Identifier: Apache-2.0 - -zephyr_include_directories(include) - -zephyr_library_sources(step_dir_stepper_common.c) -zephyr_library_sources(stepper_work_timing.c) -zephyr_library_sources_ifdef(CONFIG_STEP_DIR_STEPPER_COUNTER_TIMING stepper_counter_timing.c) diff --git a/drivers/stepper/gpio_stepper/step_dir/Kconfig b/drivers/stepper/gpio_stepper/step_dir/Kconfig deleted file mode 100644 index cac12bb61401..000000000000 --- a/drivers/stepper/gpio_stepper/step_dir/Kconfig +++ /dev/null @@ -1,24 +0,0 @@ -# Copyright (c) 2024 Fabian Blatz -# SPDX-License-Identifier: Apache-2.0 - -comment "Stepper Step-Dir Common" - -config STEP_DIR_STEPPER - bool - help - Enable library used for step direction stepper drivers. - -if STEP_DIR_STEPPER - -config STEP_DIR_STEPPER_COUNTER_TIMING - bool "Counter use for stepping" - select COUNTER - default y - help - Enable usage of a counter device for accurate stepping. - -module = STEP_DIR -module-str = step_dir -source "drivers/stepper/Kconfig.stepper_event_template" - -endif # STEP_DIR_STEPPER diff --git a/drivers/stepper/gpio_stepper/step_dir/include/step_dir_stepper_common.h b/drivers/stepper/gpio_stepper/step_dir/include/step_dir_stepper_common.h deleted file mode 100644 index fda34256842d..000000000000 --- a/drivers/stepper/gpio_stepper/step_dir/include/step_dir_stepper_common.h +++ /dev/null @@ -1,239 +0,0 @@ -/* - * Copyright 2024 Fabian Blatz - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef ZEPHYR_DRIVER_STEPPER_GPIO_STEPPER_STEP_DIR_STEPPER_COMMON_H_ -#define ZEPHYR_DRIVER_STEPPER_GPIO_STEPPER_STEP_DIR_STEPPER_COMMON_H_ - -/** - * @brief Stepper Driver APIs - * @defgroup step_dir_stepper Stepper Driver APIs - * @ingroup io_interfaces - * @{ - */ - -#include -#include -#include -#include - -#include "stepper_timing_source.h" - -/** - * @brief Common step direction stepper config. - * - * This structure **must** be placed first in the driver's config structure. - */ -struct step_dir_stepper_common_config { - const struct gpio_dt_spec step_pin; - const struct gpio_dt_spec dir_pin; - uint32_t step_width_ns; - bool dual_edge; - const struct stepper_timing_source_api *timing_source; - const struct device *counter; - bool invert_direction; -}; - -/** - * @brief Initialize common step direction stepper config from devicetree instance. - * If the counter property is set, the timing source will be set to the counter timing - * source. - * - * @param node_id The devicetree node identifier. - */ -#define STEP_DIR_STEPPER_DT_COMMON_CONFIG_INIT(node_id) \ - { \ - .step_pin = GPIO_DT_SPEC_GET(node_id, step_gpios), \ - .dir_pin = GPIO_DT_SPEC_GET(node_id, dir_gpios), \ - .dual_edge = DT_PROP_OR(node_id, dual_edge_step, false), \ - .step_width_ns = DT_PROP(node_id, step_width_ns), \ - .counter = DEVICE_DT_GET_OR_NULL(DT_PHANDLE(node_id, counter)), \ - .invert_direction = DT_PROP(node_id, invert_direction), \ - .timing_source = COND_CODE_1(DT_NODE_HAS_PROP(node_id, counter), \ - (&step_counter_timing_source_api), \ - (&step_work_timing_source_api)), \ - } - -/** - * @brief Initialize common step direction stepper config from devicetree instance. - * @param inst Instance. - */ -#define STEP_DIR_STEPPER_DT_INST_COMMON_CONFIG_INIT(inst) \ - STEP_DIR_STEPPER_DT_COMMON_CONFIG_INIT(DT_DRV_INST(inst)) - -/** - * @brief Common step direction stepper data. - * - * This structure **must** be placed first in the driver's data structure. - */ -struct step_dir_stepper_common_data { - const struct device *dev; - struct k_spinlock lock; - enum stepper_direction direction; - enum stepper_run_mode run_mode; - uint64_t microstep_interval_ns; - atomic_t actual_position; - atomic_t step_count; - stepper_event_callback_t callback; - void *event_cb_user_data; - - struct k_work_delayable stepper_dwork; - atomic_t step_high; -#ifdef CONFIG_STEP_DIR_STEPPER_COUNTER_TIMING - struct counter_top_cfg counter_top_cfg; - bool counter_running; -#endif /* CONFIG_STEP_DIR_STEPPER_COUNTER_TIMING */ - -#ifdef CONFIG_STEPPER_STEP_DIR_GENERATE_ISR_SAFE_EVENTS - struct k_work event_callback_work; - struct k_msgq event_msgq; - uint8_t event_msgq_buffer[CONFIG_STEPPER_STEP_DIR_EVENT_QUEUE_LEN * - sizeof(enum stepper_event)]; -#endif /* CONFIG_STEPPER_STEP_DIR_GENERATE_ISR_SAFE_EVENTS */ -}; - -/** - * @brief Initialize common step direction stepper data from devicetree instance. - * - * @param node_id The devicetree node identifier. - */ -#define STEP_DIR_STEPPER_DT_COMMON_DATA_INIT(node_id) \ - { \ - .dev = DEVICE_DT_GET(node_id), \ - } - -/** - * @brief Initialize common step direction stepper data from devicetree instance. - * @param inst Instance. - */ -#define STEP_DIR_STEPPER_DT_INST_COMMON_DATA_INIT(inst) \ - STEP_DIR_STEPPER_DT_COMMON_DATA_INIT(DT_DRV_INST(inst)) - -/** - * @brief Validate the offset of the common data structures. - * - * @param config Name of the config structure. - * @param data Name of the data structure. - */ -#define STEP_DIR_STEPPER_STRUCT_CHECK(config, data) \ - BUILD_ASSERT(offsetof(config, common) == 0, \ - "struct step_dir_stepper_common_config must be placed first"); \ - BUILD_ASSERT(offsetof(data, common) == 0, \ - "struct step_dir_stepper_common_data must be placed first"); - -/** - * @brief Common function to initialize a step direction stepper device at init time. - * - * This function must be called at the end of the device init function. - * - * @param dev Step direction stepper device instance. - * - * @retval 0 If initialized successfully. - * @retval -errno Negative errno in case of failure. - */ -int step_dir_stepper_common_init(const struct device *dev); - -/** - * @brief Move the stepper motor by a given number of micro_steps. - * - * @param dev Pointer to the device structure. - * @param micro_steps Number of micro_steps to move. Can be positive or negative. - * @return 0 on success, or a negative error code on failure. - */ -int step_dir_stepper_common_move_by(const struct device *dev, const int32_t micro_steps); - -/** - * @brief Set the step interval of the stepper motor. - * - * @param dev Pointer to the device structure. - * @param microstep_interval_ns The step interval in nanoseconds. - * @return 0 on success, or a negative error code on failure. - */ -int step_dir_stepper_common_set_microstep_interval(const struct device *dev, - const uint64_t microstep_interval_ns); - -/** - * @brief Set the reference position of the stepper motor. - * - * @param dev Pointer to the device structure. - * @param value The reference position value to set. - * @return 0 on success, or a negative error code on failure. - */ -int step_dir_stepper_common_set_reference_position(const struct device *dev, const int32_t value); - -/** - * @brief Get the actual (reference) position of the stepper motor. - * - * @param dev Pointer to the device structure. - * @param value Pointer to a variable where the position value will be stored. - * @return 0 on success, or a negative error code on failure. - */ -int step_dir_stepper_common_get_actual_position(const struct device *dev, int32_t *value); - -/** - * @brief Set the absolute target position of the stepper motor. - * - * @param dev Pointer to the device structure. - * @param value The target position to set. - * @return 0 on success, or a negative error code on failure. - */ -int step_dir_stepper_common_move_to(const struct device *dev, const int32_t value); - -/** - * @brief Check if the stepper motor is still moving. - * - * @param dev Pointer to the device structure. - * @param is_moving Pointer to a boolean where the movement status will be stored. - * @return 0 on success, or a negative error code on failure. - */ -int step_dir_stepper_common_is_moving(const struct device *dev, bool *is_moving); - -/** - * @brief Run the stepper with a given direction and step interval. - * - * @param dev Pointer to the device structure. - * @param direction The direction of movement (positive or negative). - * @return 0 on success, or a negative error code on failure. - */ -int step_dir_stepper_common_run(const struct device *dev, const enum stepper_direction direction); - -/** - * @brief Stop the stepper motor. - * - * @param dev Pointer to the device structure. - * @return 0 on success, or a negative error code on failure. - */ -int step_dir_stepper_common_stop(const struct device *dev); - -/** - * @brief Set a callback function for stepper motor events. - * - * This function sets a user-defined callback that will be invoked when a stepper motor event - * occurs. - * - * @param dev Pointer to the device structure. - * @param callback The callback function to set. - * @param user_data Pointer to user-defined data that will be passed to the callback. - * @return 0 on success, or a negative error code on failure. - */ -int step_dir_stepper_common_set_event_callback(const struct device *dev, - stepper_event_callback_t callback, void *user_data); - -/** - * @brief Handle a timing signal and update the stepper position. - * @param dev Pointer to the device structure. - */ -void stepper_handle_timing_signal(const struct device *dev); - -/** - * @brief Trigger callback function for stepper motor events. - * @param dev Pointer to the device structure. - * @param event The stepper_event to rigger the callback for. - */ -void stepper_trigger_callback(const struct device *dev, enum stepper_event event); - -/** @} */ - -#endif /* ZEPHYR_DRIVER_STEPPER_GPIO_STEPPER_STEP_DIR_STEPPER_COMMON_H_ */ diff --git a/drivers/stepper/gpio_stepper/step_dir/step_dir_stepper_common.c b/drivers/stepper/gpio_stepper/step_dir/step_dir_stepper_common.c deleted file mode 100644 index 5a6337bad2ca..000000000000 --- a/drivers/stepper/gpio_stepper/step_dir/step_dir_stepper_common.c +++ /dev/null @@ -1,404 +0,0 @@ -/* - * SPDX-FileCopyrightText: Copyright (c) 2024 Fabian Blatz - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -#include -LOG_MODULE_REGISTER(step_dir_stepper, CONFIG_STEPPER_LOG_LEVEL); - -static inline int update_dir_pin(const struct device *dev) -{ - const struct step_dir_stepper_common_config *config = dev->config; - struct step_dir_stepper_common_data *data = dev->data; - int ret; - - switch (data->direction) { - case STEPPER_DIRECTION_POSITIVE: - ret = gpio_pin_set_dt(&config->dir_pin, 1 ^ config->invert_direction); - break; - case STEPPER_DIRECTION_NEGATIVE: - ret = gpio_pin_set_dt(&config->dir_pin, 0 ^ config->invert_direction); - break; - default: - LOG_ERR("Unsupported direction: %d", data->direction); - return -ENOTSUP; - } - if (ret < 0) { - LOG_ERR("Failed to set direction: %d", ret); - return ret; - } - - return ret; -} - -void stepper_trigger_callback(const struct device *dev, enum stepper_event event) -{ - struct step_dir_stepper_common_data *data = dev->data; - - if (!data->callback) { - LOG_WRN_ONCE("No callback set"); - return; - } - - if (!k_is_in_isr()) { - data->callback(dev, event, data->event_cb_user_data); - return; - } - -#ifdef CONFIG_STEPPER_STEP_DIR_GENERATE_ISR_SAFE_EVENTS - /* Dispatch to msgq instead of raising directly */ - int ret = k_msgq_put(&data->event_msgq, &event, K_NO_WAIT); - - if (ret != 0) { - LOG_WRN("Failed to put event in msgq: %d", ret); - } - - ret = k_work_submit(&data->event_callback_work); - if (ret < 0) { - LOG_ERR("Failed to submit work item: %d", ret); - } -#else - LOG_WRN_ONCE("Event callback called from ISR context without ISR safe events enabled"); -#endif /* CONFIG_STEPPER_STEP_DIR_GENERATE_ISR_SAFE_EVENTS */ -} - -#ifdef CONFIG_STEPPER_STEP_DIR_GENERATE_ISR_SAFE_EVENTS -static void stepper_work_event_handler(struct k_work *work) -{ - struct step_dir_stepper_common_data *data = - CONTAINER_OF(work, struct step_dir_stepper_common_data, event_callback_work); - enum stepper_event event; - int ret; - - ret = k_msgq_get(&data->event_msgq, &event, K_NO_WAIT); - if (ret != 0) { - return; - } - - /* Run the callback */ - if (data->callback != NULL) { - data->callback(data->dev, event, data->event_cb_user_data); - } - - /* If there are more pending events, resubmit this work item to handle them */ - if (k_msgq_num_used_get(&data->event_msgq) > 0) { - k_work_submit(work); - } -} -#endif /* CONFIG_STEPPER_STEP_DIR_GENERATE_ISR_SAFE_EVENTS */ - -static int start_stepping(const struct device *dev) -{ - const struct step_dir_stepper_common_config *config = dev->config; - struct step_dir_stepper_common_data *data = dev->data; - int ret; - - ret = config->timing_source->update(dev, config->dual_edge - ? data->microstep_interval_ns - : data->microstep_interval_ns / 2); - if (ret < 0) { - LOG_ERR("Failed to update timing source: %d", ret); - return ret; - } - - ret = config->timing_source->start(dev); - if (ret < 0) { - LOG_ERR("Failed to start timing source: %d", ret); - return ret; - } - - stepper_handle_timing_signal(dev); - return 0; -} - -static void update_remaining_steps(const struct device *dev) -{ - const struct step_dir_stepper_common_config *config = dev->config; - struct step_dir_stepper_common_data *data = dev->data; - - if (data->step_high && !config->dual_edge) { - return; - } - if (atomic_get(&data->step_count) > 0) { - atomic_dec(&data->step_count); - } else if (atomic_get(&data->step_count) < 0) { - atomic_inc(&data->step_count); - } -} - -static void update_direction_from_step_count(const struct device *dev) -{ - struct step_dir_stepper_common_data *data = dev->data; - - if (atomic_get(&data->step_count) > 0) { - data->direction = STEPPER_DIRECTION_POSITIVE; - } else if (atomic_get(&data->step_count) < 0) { - data->direction = STEPPER_DIRECTION_NEGATIVE; - } else { - LOG_ERR("Step count is zero"); - } -} - -static void position_mode_task(const struct device *dev) -{ - struct step_dir_stepper_common_data *data = dev->data; - const struct step_dir_stepper_common_config *config = dev->config; - - update_remaining_steps(dev); - - if (config->timing_source->needs_reschedule(dev) && atomic_get(&data->step_count) != 0) { - (void)config->timing_source->start(dev); - } else if (atomic_get(&data->step_count) == 0) { - config->timing_source->stop(data->dev); - stepper_trigger_callback(data->dev, STEPPER_EVENT_STEPS_COMPLETED); - } -} - -static void velocity_mode_task(const struct device *dev) -{ - const struct step_dir_stepper_common_config *config = dev->config; - - if (config->timing_source->needs_reschedule(dev)) { - (void)config->timing_source->start(dev); - } -} - -void stepper_handle_timing_signal(const struct device *dev) -{ - const struct step_dir_stepper_common_config *config = dev->config; - struct step_dir_stepper_common_data *data = dev->data; - int ret; - - atomic_val_t step_pin_status = atomic_xor(&data->step_high, 1) ^ 1; - - ret = gpio_pin_set_dt(&config->step_pin, atomic_get(&step_pin_status)); - if (ret < 0) { - LOG_ERR("Failed to set step pin: %d", ret); - return; - } - - if (!atomic_get(&step_pin_status) || config->dual_edge) { - if (data->direction == STEPPER_DIRECTION_POSITIVE) { - atomic_inc(&data->actual_position); - } else { - atomic_dec(&data->actual_position); - } - } - - switch (data->run_mode) { - case STEPPER_RUN_MODE_POSITION: - position_mode_task(dev); - break; - case STEPPER_RUN_MODE_VELOCITY: - velocity_mode_task(dev); - break; - default: - LOG_WRN("Unsupported run mode: %d", data->run_mode); - break; - } -} - -int step_dir_stepper_common_init(const struct device *dev) -{ - const struct step_dir_stepper_common_config *config = dev->config; - int ret; - - if (!gpio_is_ready_dt(&config->step_pin) || !gpio_is_ready_dt(&config->dir_pin)) { - LOG_ERR("GPIO pins are not ready"); - return -ENODEV; - } - - ret = gpio_pin_configure_dt(&config->step_pin, GPIO_OUTPUT); - if (ret < 0) { - LOG_ERR("Failed to configure step pin: %d", ret); - return ret; - } - - ret = gpio_pin_configure_dt(&config->dir_pin, GPIO_OUTPUT); - if (ret < 0) { - LOG_ERR("Failed to configure dir pin: %d", ret); - return ret; - } - - if (config->timing_source->init) { - ret = config->timing_source->init(dev); - if (ret < 0) { - LOG_ERR("Failed to initialize timing source: %d", ret); - return ret; - } - } - -#ifdef CONFIG_STEPPER_STEP_DIR_GENERATE_ISR_SAFE_EVENTS - struct step_dir_stepper_common_data *data = dev->data; - - k_msgq_init(&data->event_msgq, data->event_msgq_buffer, sizeof(enum stepper_event), - CONFIG_STEPPER_STEP_DIR_EVENT_QUEUE_LEN); - k_work_init(&data->event_callback_work, stepper_work_event_handler); -#endif /* CONFIG_STEPPER_STEP_DIR_GENERATE_ISR_SAFE_EVENTS */ - return 0; -} - -int step_dir_stepper_common_move_by(const struct device *dev, const int32_t micro_steps) -{ - struct step_dir_stepper_common_data *data = dev->data; - const struct step_dir_stepper_common_config *config = dev->config; - int ret; - - if (data->microstep_interval_ns == 0) { - LOG_ERR("Step interval not set or invalid step interval set"); - return -EINVAL; - } - - if (micro_steps == 0) { - stepper_trigger_callback(data->dev, STEPPER_EVENT_STEPS_COMPLETED); - config->timing_source->stop(dev); - return 0; - } - - K_SPINLOCK(&data->lock) { - data->run_mode = STEPPER_RUN_MODE_POSITION; - atomic_set(&data->step_count, micro_steps); - update_direction_from_step_count(dev); - ret = update_dir_pin(dev); - if (ret < 0) { - K_SPINLOCK_BREAK; - } - - ret = start_stepping(dev); - } - - return ret; -} - -int step_dir_stepper_common_set_microstep_interval(const struct device *dev, - const uint64_t microstep_interval_ns) -{ - struct step_dir_stepper_common_data *data = dev->data; - const struct step_dir_stepper_common_config *config = dev->config; - - if (microstep_interval_ns == 0) { - LOG_ERR("Step interval cannot be zero"); - return -EINVAL; - } - - if (config->dual_edge && (microstep_interval_ns < config->step_width_ns)) { - LOG_ERR("Step interval too small for configured step width"); - return -EINVAL; - } - - if (microstep_interval_ns < 2 * config->step_width_ns) { - LOG_ERR("Step interval too small for configured step width"); - return -EINVAL; - } - - K_SPINLOCK(&data->lock) { - data->microstep_interval_ns = microstep_interval_ns; - config->timing_source->update(dev, config->dual_edge - ? data->microstep_interval_ns - : data->microstep_interval_ns / 2); - } - - return 0; -} - -int step_dir_stepper_common_set_reference_position(const struct device *dev, const int32_t value) -{ - struct step_dir_stepper_common_data *data = dev->data; - - K_SPINLOCK(&data->lock) { - data->actual_position = value; - } - - return 0; -} - -int step_dir_stepper_common_get_actual_position(const struct device *dev, int32_t *value) -{ - struct step_dir_stepper_common_data *data = dev->data; - - *value = atomic_get(&data->actual_position); - - return 0; -} - -int step_dir_stepper_common_move_to(const struct device *dev, const int32_t value) -{ - struct step_dir_stepper_common_data *data = dev->data; - int32_t steps_to_move; - - /* Calculate the relative movement required */ - steps_to_move = value - atomic_get(&data->actual_position); - - return step_dir_stepper_common_move_by(dev, steps_to_move); -} - -int step_dir_stepper_common_is_moving(const struct device *dev, bool *is_moving) -{ - const struct step_dir_stepper_common_config *config = dev->config; - - *is_moving = config->timing_source->is_running(dev); - return 0; -} - -int step_dir_stepper_common_run(const struct device *dev, const enum stepper_direction direction) -{ - struct step_dir_stepper_common_data *data = dev->data; - int ret; - - if (data->microstep_interval_ns == 0) { - LOG_ERR("Step interval not set or invalid step interval set"); - return -EINVAL; - } - - K_SPINLOCK(&data->lock) { - data->run_mode = STEPPER_RUN_MODE_VELOCITY; - data->direction = direction; - ret = update_dir_pin(dev); - if (ret < 0) { - K_SPINLOCK_BREAK; - } - - ret = start_stepping(dev); - } - - return ret; -} - -int step_dir_stepper_common_stop(const struct device *dev) -{ - const struct step_dir_stepper_common_config *config = dev->config; - struct step_dir_stepper_common_data *data = dev->data; - int ret; - - ret = config->timing_source->stop(dev); - if (ret != 0) { - LOG_ERR("Failed to stop timing source: %d", ret); - return ret; - } - - if (!config->dual_edge && atomic_cas(&data->step_high, 1, 0)) { - gpio_pin_set_dt(&config->step_pin, 0); - /* If we are in the high state, we need to account for that step */ - if (data->direction == STEPPER_DIRECTION_POSITIVE) { - atomic_inc(&data->actual_position); - } else { - atomic_dec(&data->actual_position); - } - } - - stepper_trigger_callback(dev, STEPPER_EVENT_STOPPED); - - return 0; -} - -int step_dir_stepper_common_set_event_callback(const struct device *dev, - stepper_event_callback_t callback, void *user_data) -{ - struct step_dir_stepper_common_data *data = dev->data; - - data->callback = callback; - data->event_cb_user_data = user_data; - return 0; -} diff --git a/drivers/stepper/step_dir/CMakeLists.txt b/drivers/stepper/step_dir/CMakeLists.txt new file mode 100644 index 000000000000..df91611a9f6e --- /dev/null +++ b/drivers/stepper/step_dir/CMakeLists.txt @@ -0,0 +1,4 @@ +# SPDX-FileCopyrightText: Copyright (c) 2024 Fabian Blatz +# SPDX-License-Identifier: Apache-2.0 + +zephyr_include_directories_ifdef(CONFIG_STEP_DIR_STEPPER include) diff --git a/drivers/stepper/step_dir/Kconfig b/drivers/stepper/step_dir/Kconfig new file mode 100644 index 000000000000..63891e434804 --- /dev/null +++ b/drivers/stepper/step_dir/Kconfig @@ -0,0 +1,9 @@ +# Copyright (c) 2024 Fabian Blatz +# SPDX-License-Identifier: Apache-2.0 + +comment "Stepper Step-Dir Common" + +config STEP_DIR_STEPPER + bool + help + Enable library used for step direction stepper drivers. diff --git a/drivers/stepper/step_dir/include/step_dir_stepper_common.h b/drivers/stepper/step_dir/include/step_dir_stepper_common.h new file mode 100644 index 000000000000..e167cb667fb6 --- /dev/null +++ b/drivers/stepper/step_dir/include/step_dir_stepper_common.h @@ -0,0 +1,60 @@ +/* + * Copyright 2024 Fabian Blatz + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVER_STEPPER_STEP_DIR_STEPPER_COMMON_H_ +#define ZEPHYR_DRIVER_STEPPER_STEP_DIR_STEPPER_COMMON_H_ + +/** + * @brief Stepper Driver APIs + * @defgroup step_dir_stepper Stepper Driver APIs + * @ingroup io_interfaces + * @{ + */ + +#include +/** + * @brief Common step direction stepper config. + * + * This structure **must** be placed first in the driver's config structure. + */ +struct step_dir_stepper_common_config { + uint32_t step_width_ns; + bool dual_edge; +}; + +/** + * @brief Initialize common step direction stepper config from devicetree instance. + * If the counter property is set, the timing source will be set to the counter timing + * source. + * + * @param node_id The devicetree node identifier. + */ +#define STEP_DIR_STEPPER_DT_COMMON_CONFIG_INIT(node_id) \ + { \ + .dual_edge = DT_PROP_OR(node_id, dual_edge_step, false), \ + .step_width_ns = DT_PROP(node_id, step_width_ns), \ + } + +/** + * @brief Initialize common step direction stepper config from devicetree instance. + * @param inst Instance. + */ +#define STEP_DIR_STEPPER_DT_INST_COMMON_CONFIG_INIT(inst) \ + STEP_DIR_STEPPER_DT_COMMON_CONFIG_INIT(DT_DRV_INST(inst)) + + +/** + * @brief Validate the offset of the common data structures. + * + * @param config Name of the config structure. + */ +#define STEP_DIR_STEPPER_STRUCT_CHECK(config) \ + BUILD_ASSERT(offsetof(config, common) == 0, \ + "struct step_dir_stepper_common_config must be placed first"); + +/** @} */ + +#endif /* ZEPHYR_DRIVER_STEPPER_STEP_DIR_STEPPER_COMMON_H_ */ diff --git a/drivers/stepper/stepper_shell.c b/drivers/stepper/stepper_shell.c index 1e96fb20c5f1..8eede1677d0c 100644 --- a/drivers/stepper/stepper_shell.c +++ b/drivers/stepper/stepper_shell.c @@ -20,7 +20,7 @@ enum { struct stepper_microstep_map { const char *name; - enum stepper_micro_step_resolution microstep; + enum stepper_drv_micro_step_resolution microstep; }; struct stepper_direction_map { @@ -28,6 +28,8 @@ struct stepper_direction_map { enum stepper_direction direction; }; +#define STEPPER_DRV_MICROSTEP_PARAM_IDX 2 + #define STEPPER_DIRECTION_MAP_ENTRY(_name, _dir) \ { \ .name = _name, \ @@ -40,10 +42,33 @@ struct stepper_direction_map { .microstep = _microstep, \ } +static void print_stepper_drv_event_cb(const struct device *dev, const enum stepper_drv_event event, + void *user_data) +{ + const struct shell *sh = user_data; + + if (!sh) { + return; + } + + switch (event) { + case STEPPER_DRV_EVENT_STALL_DETECTED: + shell_info(sh, "%s: Stall detected.", dev->name); + break; + case STEPPER_DRV_EVENT_FAULT_DETECTED: + shell_info(sh, "%s: Fault detected.", dev->name); + break; + default: + shell_info(sh, "%s: Unknown event.", dev->name); + break; + } +} + static void print_callback(const struct device *dev, const enum stepper_event event, void *user_data) { const struct shell *sh = user_data; + if (!sh) { return; } @@ -52,9 +77,6 @@ static void print_callback(const struct device *dev, const enum stepper_event ev case STEPPER_EVENT_STEPS_COMPLETED: shell_info(sh, "%s: Steps completed.", dev->name); break; - case STEPPER_EVENT_STALL_DETECTED: - shell_info(sh, "%s: Stall detected.", dev->name); - break; case STEPPER_EVENT_LEFT_END_STOP_DETECTED: shell_info(sh, "%s: Left limit switch pressed.", dev->name); break; @@ -64,16 +86,18 @@ static void print_callback(const struct device *dev, const enum stepper_event ev case STEPPER_EVENT_STOPPED: shell_info(sh, "%s: Stepper stopped.", dev->name); break; - case STEPPER_EVENT_FAULT_DETECTED: - shell_info(sh, "%s: Fault detected.", dev->name); - break; default: shell_info(sh, "%s: Unknown signal received.", dev->name); break; } } -static bool device_is_stepper(const struct device *dev) +static bool device_is_stepper_drv(const struct device *dev) +{ + return DEVICE_API_IS(stepper_drv, dev); +} + +static bool device_is_stepper_controller(const struct device *dev) { return DEVICE_API_IS(stepper, dev); } @@ -84,15 +108,15 @@ static const struct stepper_direction_map stepper_direction_map[] = { }; static const struct stepper_microstep_map stepper_microstep_map[] = { - STEPPER_MICROSTEP_MAP("1", STEPPER_MICRO_STEP_1), - STEPPER_MICROSTEP_MAP("2", STEPPER_MICRO_STEP_2), - STEPPER_MICROSTEP_MAP("4", STEPPER_MICRO_STEP_4), - STEPPER_MICROSTEP_MAP("8", STEPPER_MICRO_STEP_8), - STEPPER_MICROSTEP_MAP("16", STEPPER_MICRO_STEP_16), - STEPPER_MICROSTEP_MAP("32", STEPPER_MICRO_STEP_32), - STEPPER_MICROSTEP_MAP("64", STEPPER_MICRO_STEP_64), - STEPPER_MICROSTEP_MAP("128", STEPPER_MICRO_STEP_128), - STEPPER_MICROSTEP_MAP("256", STEPPER_MICRO_STEP_256), + STEPPER_MICROSTEP_MAP("1", STEPPER_DRV_MICRO_STEP_1), + STEPPER_MICROSTEP_MAP("2", STEPPER_DRV_MICRO_STEP_2), + STEPPER_MICROSTEP_MAP("4", STEPPER_DRV_MICRO_STEP_4), + STEPPER_MICROSTEP_MAP("8", STEPPER_DRV_MICRO_STEP_8), + STEPPER_MICROSTEP_MAP("16", STEPPER_DRV_MICRO_STEP_16), + STEPPER_MICROSTEP_MAP("32", STEPPER_DRV_MICRO_STEP_32), + STEPPER_MICROSTEP_MAP("64", STEPPER_DRV_MICRO_STEP_64), + STEPPER_MICROSTEP_MAP("128", STEPPER_DRV_MICRO_STEP_128), + STEPPER_MICROSTEP_MAP("256", STEPPER_DRV_MICRO_STEP_256), }; static void cmd_stepper_direction(size_t idx, struct shell_static_entry *entry) @@ -125,7 +149,7 @@ SHELL_DYNAMIC_CMD_CREATE(dsub_stepper_microstep, cmd_stepper_microstep); static void cmd_pos_stepper_motor_name(size_t idx, struct shell_static_entry *entry) { - const struct device *dev = shell_device_filter(idx, device_is_stepper); + const struct device *dev = shell_device_filter(idx, device_is_stepper_drv); entry->syntax = (dev != NULL) ? dev->name : NULL; entry->handler = NULL; @@ -135,9 +159,21 @@ static void cmd_pos_stepper_motor_name(size_t idx, struct shell_static_entry *en SHELL_DYNAMIC_CMD_CREATE(dsub_pos_stepper_motor_name, cmd_pos_stepper_motor_name); -static void cmd_pos_stepper_motor_name_dir(size_t idx, struct shell_static_entry *entry) +static void cmd_pos_stepper_controller_name(size_t idx, struct shell_static_entry *entry) +{ + const struct device *dev = shell_device_filter(idx, device_is_stepper_controller); + + entry->syntax = (dev != NULL) ? dev->name : NULL; + entry->handler = NULL; + entry->help = "List Devices"; + entry->subcmd = NULL; +} + +SHELL_DYNAMIC_CMD_CREATE(dsub_pos_stepper_controller_name, cmd_pos_stepper_controller_name); + +static void cmd_pos_stepper_controller_name_dir(size_t idx, struct shell_static_entry *entry) { - const struct device *dev = shell_device_filter(idx, device_is_stepper); + const struct device *dev = shell_device_filter(idx, device_is_stepper_controller); if (dev != NULL) { entry->syntax = dev->name; @@ -149,11 +185,11 @@ static void cmd_pos_stepper_motor_name_dir(size_t idx, struct shell_static_entry entry->subcmd = &dsub_stepper_direction; } -SHELL_DYNAMIC_CMD_CREATE(dsub_pos_stepper_motor_name_dir, cmd_pos_stepper_motor_name_dir); +SHELL_DYNAMIC_CMD_CREATE(dsub_pos_stepper_controller_name_dir, cmd_pos_stepper_controller_name_dir); static void cmd_pos_stepper_motor_name_microstep(size_t idx, struct shell_static_entry *entry) { - const struct device *dev = shell_device_filter(idx, device_is_stepper); + const struct device *dev = shell_device_filter(idx, device_is_stepper_drv); if (dev != NULL) { entry->syntax = dev->name; @@ -188,11 +224,15 @@ static int cmd_stepper_enable(const struct shell *sh, size_t argc, char **argv) return err; } - err = stepper_enable(dev); + err = stepper_drv_enable(dev); if (err) { shell_error(sh, "Error: %d", err); } + err = stepper_drv_set_event_cb(dev, print_stepper_drv_event_cb, (void *)sh); + if (err) { + shell_error(sh, "Failed to set stepper driver event callback: %d", err); + } return err; } @@ -206,7 +246,7 @@ static int cmd_stepper_disable(const struct shell *sh, size_t argc, char **argv) return err; } - err = stepper_disable(dev); + err = stepper_drv_disable(dev); if (err) { shell_error(sh, "Error: %d", err); } @@ -271,6 +311,7 @@ static int cmd_stepper_set_microstep_interval(const struct shell *sh, size_t arg { const struct device *dev; int err = 0; + uint64_t step_interval = shell_strtoull(argv[ARG_IDX_PARAM], 10, &err); if (err < 0) { @@ -293,18 +334,20 @@ static int cmd_stepper_set_microstep_interval(const struct shell *sh, size_t arg static int cmd_stepper_set_micro_step_res(const struct shell *sh, size_t argc, char **argv) { const struct device *dev; - enum stepper_micro_step_resolution resolution; + enum stepper_drv_micro_step_resolution resolution; int err = -EINVAL; for (int i = 0; i < ARRAY_SIZE(stepper_microstep_map); i++) { - if (strcmp(argv[ARG_IDX_PARAM], stepper_microstep_map[i].name) == 0) { + if (strcmp(argv[STEPPER_DRV_MICROSTEP_PARAM_IDX], stepper_microstep_map[i].name) == + 0) { resolution = stepper_microstep_map[i].microstep; err = 0; break; } } if (err != 0) { - shell_error(sh, "Invalid microstep value %s", argv[ARG_IDX_PARAM]); + shell_error(sh, "Invalid microstep value %s", + argv[STEPPER_DRV_MICROSTEP_PARAM_IDX]); return err; } @@ -313,7 +356,7 @@ static int cmd_stepper_set_micro_step_res(const struct shell *sh, size_t argc, c return err; } - err = stepper_set_micro_step_res(dev, resolution); + err = stepper_drv_set_micro_step_res(dev, resolution); if (err) { shell_error(sh, "Error: %d", err); } @@ -325,14 +368,14 @@ static int cmd_stepper_get_micro_step_res(const struct shell *sh, size_t argc, c { const struct device *dev; int err; - enum stepper_micro_step_resolution micro_step_res; + enum stepper_drv_micro_step_resolution micro_step_res; err = parse_device_arg(sh, argv, &dev); if (err < 0) { return err; } - err = stepper_get_micro_step_res(dev, µ_step_res); + err = stepper_drv_get_micro_step_res(dev, µ_step_res); if (err < 0) { shell_warn(sh, "Failed to get micro-step resolution: %d", err); } else { @@ -346,6 +389,7 @@ static int cmd_stepper_set_reference_position(const struct shell *sh, size_t arg { const struct device *dev; int err = 0; + int32_t position = shell_strtol(argv[ARG_IDX_PARAM], 10, &err); if (err < 0) { @@ -369,6 +413,7 @@ static int cmd_stepper_get_actual_position(const struct shell *sh, size_t argc, { const struct device *dev; int err; + int32_t actual_position; err = parse_device_arg(sh, argv, &dev); @@ -390,6 +435,7 @@ static int cmd_stepper_move_to(const struct shell *sh, size_t argc, char **argv) { const struct device *dev; int err = 0; + const int32_t position = shell_strtol(argv[ARG_IDX_PARAM], 10, &err); if (err < 0) { @@ -417,9 +463,11 @@ static int cmd_stepper_move_to(const struct shell *sh, size_t argc, char **argv) static int cmd_stepper_run(const struct shell *sh, size_t argc, char **argv) { const struct device *dev; - int err = -EINVAL; + int err; + enum stepper_direction direction = STEPPER_DIRECTION_POSITIVE; + err = -EINVAL; for (int i = 0; i < ARRAY_SIZE(stepper_direction_map); i++) { if (strcmp(argv[ARG_IDX_PARAM], stepper_direction_map[i].name) == 0) { direction = stepper_direction_map[i].direction; @@ -451,13 +499,12 @@ static int cmd_stepper_run(const struct shell *sh, size_t argc, char **argv) return 0; } -static int cmd_stepper_info(const struct shell *sh, size_t argc, char **argv) +static int cmd_stepper_control_info(const struct shell *sh, size_t argc, char **argv) { const struct device *dev; int err; bool is_moving; int32_t actual_position; - enum stepper_micro_step_resolution micro_step_res; err = parse_device_arg(sh, argv, &dev); if (err < 0) { @@ -474,18 +521,35 @@ static int cmd_stepper_info(const struct shell *sh, size_t argc, char **argv) shell_print(sh, "Actual Position: %d", actual_position); } - err = stepper_get_micro_step_res(dev, µ_step_res); + err = stepper_is_moving(dev, &is_moving); if (err < 0) { - shell_warn(sh, "Failed to get micro-step resolution: %d", err); + shell_warn(sh, "Failed to check if the motor is moving: %d", err); } else { - shell_print(sh, "Micro-step Resolution: %d", micro_step_res); + shell_print(sh, "Is Moving: %s", is_moving ? "Yes" : "No"); } - err = stepper_is_moving(dev, &is_moving); + return 0; +} + +static int cmd_stepper_info(const struct shell *sh, size_t argc, char **argv) +{ + const struct device *dev; + int err; + enum stepper_drv_micro_step_resolution micro_step_res; + + err = parse_device_arg(sh, argv, &dev); if (err < 0) { - shell_warn(sh, "Failed to check if the motor is moving: %d", err); + return err; + } + + shell_print(sh, "Stepper Info:"); + shell_print(sh, "Device: %s", dev->name); + + err = stepper_drv_get_micro_step_res(dev, µ_step_res); + if (err < 0) { + shell_warn(sh, "Failed to get micro-step resolution: %d", err); } else { - shell_print(sh, "Is Moving: %s", is_moving ? "Yes" : "No"); + shell_print(sh, "Micro-step Resolution: %d", micro_step_res); } return 0; @@ -499,19 +563,21 @@ SHELL_STATIC_SUBCMD_SET_CREATE( " ", cmd_stepper_set_micro_step_res, 3, 0), SHELL_CMD_ARG(get_micro_step_res, &dsub_pos_stepper_motor_name, "", cmd_stepper_get_micro_step_res, 2, 0), - SHELL_CMD_ARG(set_reference_position, &dsub_pos_stepper_motor_name, " ", - cmd_stepper_set_reference_position, 3, 0), - SHELL_CMD_ARG(get_actual_position, &dsub_pos_stepper_motor_name, "", + SHELL_CMD_ARG(set_reference_position, &dsub_pos_stepper_controller_name, + " ", cmd_stepper_set_reference_position, 3, 0), + SHELL_CMD_ARG(get_actual_position, &dsub_pos_stepper_controller_name, "", cmd_stepper_get_actual_position, 2, 0), - SHELL_CMD_ARG(set_microstep_interval, &dsub_pos_stepper_motor_name, + SHELL_CMD_ARG(set_microstep_interval, &dsub_pos_stepper_controller_name, " ", cmd_stepper_set_microstep_interval, 3, 0), - SHELL_CMD_ARG(move_by, &dsub_pos_stepper_motor_name, " ", + SHELL_CMD_ARG(move_by, &dsub_pos_stepper_controller_name, " ", cmd_stepper_move_by, 3, 0), - SHELL_CMD_ARG(move_to, &dsub_pos_stepper_motor_name, " ", + SHELL_CMD_ARG(move_to, &dsub_pos_stepper_controller_name, " ", cmd_stepper_move_to, 3, 0), - SHELL_CMD_ARG(run, &dsub_pos_stepper_motor_name_dir, " ", + SHELL_CMD_ARG(run, &dsub_pos_stepper_controller_name_dir, " ", cmd_stepper_run, 3, 0), - SHELL_CMD_ARG(stop, &dsub_pos_stepper_motor_name, "", cmd_stepper_stop, 2, 0), + SHELL_CMD_ARG(stop, &dsub_pos_stepper_controller_name, "", cmd_stepper_stop, 2, 0), + SHELL_CMD_ARG(control_info, &dsub_pos_stepper_controller_name, "", + cmd_stepper_control_info, 2, 0), SHELL_CMD_ARG(info, &dsub_pos_stepper_motor_name, "", cmd_stepper_info, 2, 0), SHELL_SUBCMD_SET_END); diff --git a/drivers/stepper/ti/Kconfig.drv84xx b/drivers/stepper/ti/Kconfig.drv84xx index 58ccc50bb7c5..12fde469a99b 100644 --- a/drivers/stepper/ti/Kconfig.drv84xx +++ b/drivers/stepper/ti/Kconfig.drv84xx @@ -6,6 +6,5 @@ config DRV84XX default y depends on DT_HAS_TI_DRV84XX_ENABLED select STEP_DIR_STEPPER - select STEPPER_STEP_DIR_GENERATE_ISR_SAFE_EVENTS help Enable driver for TI DRV84XX stepper motor driver. diff --git a/drivers/stepper/ti/drv84xx.c b/drivers/stepper/ti/drv84xx.c index b87c17ba950c..9f2ad6300c2f 100644 --- a/drivers/stepper/ti/drv84xx.c +++ b/drivers/stepper/ti/drv84xx.c @@ -5,7 +5,6 @@ #define DT_DRV_COMPAT ti_drv84xx -#include #include #include #include @@ -23,7 +22,7 @@ LOG_MODULE_REGISTER(drv84xx, CONFIG_STEPPER_LOG_LEVEL); /** * @brief DRV84XX stepper driver configuration data. * - * This structure contains all of the devicetree specifications for the pins + * This structure contains all the devicetree specifications for the pins * needed by a given DRV84XX stepper driver. */ struct drv84xx_config { @@ -47,14 +46,15 @@ struct drv84xx_pin_states { * @brief DRV84XX stepper driver data. */ struct drv84xx_data { - const struct step_dir_stepper_common_data common; const struct device *dev; struct drv84xx_pin_states pin_states; - enum stepper_micro_step_resolution ustep_res; + enum stepper_drv_micro_step_resolution ustep_res; struct gpio_callback fault_cb_data; + stepper_drv_event_cb_t fault_cb; + void *fault_cb_user_data; }; -STEP_DIR_STEPPER_STRUCT_CHECK(struct drv84xx_config, struct drv84xx_data); +STEP_DIR_STEPPER_STRUCT_CHECK(struct drv84xx_config); static int drv84xx_set_microstep_pin(const struct device *dev, const struct gpio_dt_spec *pin, int value) @@ -255,8 +255,19 @@ static int drv84xx_disable(const struct device *dev) return ret; } +static int drv84xx_set_fault_cb(const struct device *dev, stepper_drv_event_cb_t fault_cb, + void *user_data) +{ + struct drv84xx_data *data = dev->data; + + data->fault_cb = fault_cb; + data->fault_cb_user_data = user_data; + + return 0; +} + static int drv84xx_set_micro_step_res(const struct device *dev, - enum stepper_micro_step_resolution micro_step_res) + enum stepper_drv_micro_step_resolution micro_step_res) { const struct drv84xx_config *config = dev->config; struct drv84xx_data *data = dev->data; @@ -279,39 +290,39 @@ static int drv84xx_set_micro_step_res(const struct device *dev, * 3: 330kΩ */ switch (micro_step_res) { - case STEPPER_MICRO_STEP_1: + case STEPPER_DRV_MICRO_STEP_1: m0_value = 0; m1_value = 0; break; - case STEPPER_MICRO_STEP_2: + case STEPPER_DRV_MICRO_STEP_2: m0_value = 2; m1_value = 0; break; - case STEPPER_MICRO_STEP_4: + case STEPPER_DRV_MICRO_STEP_4: m0_value = 0; m1_value = 1; break; - case STEPPER_MICRO_STEP_8: + case STEPPER_DRV_MICRO_STEP_8: m0_value = 1; m1_value = 1; break; - case STEPPER_MICRO_STEP_16: + case STEPPER_DRV_MICRO_STEP_16: m0_value = 2; m1_value = 1; break; - case STEPPER_MICRO_STEP_32: + case STEPPER_DRV_MICRO_STEP_32: m0_value = 0; m1_value = 2; break; - case STEPPER_MICRO_STEP_64: + case STEPPER_DRV_MICRO_STEP_64: m0_value = 2; m1_value = 3; break; - case STEPPER_MICRO_STEP_128: + case STEPPER_DRV_MICRO_STEP_128: m0_value = 2; m1_value = 2; break; - case STEPPER_MICRO_STEP_256: + case STEPPER_DRV_MICRO_STEP_256: m0_value = 1; m1_value = 2; break; @@ -337,7 +348,7 @@ static int drv84xx_set_micro_step_res(const struct device *dev, } static int drv84xx_get_micro_step_res(const struct device *dev, - enum stepper_micro_step_resolution *micro_step_res) + enum stepper_drv_micro_step_resolution *micro_step_res) { struct drv84xx_data *data = dev->data; *micro_step_res = data->ustep_res; @@ -348,7 +359,12 @@ void fault_event(const struct device *dev, struct gpio_callback *cb, uint32_t pi { struct drv84xx_data *data = CONTAINER_OF(cb, struct drv84xx_data, fault_cb_data); - stepper_trigger_callback(data->dev, STEPPER_EVENT_FAULT_DETECTED); + if (data->fault_cb != NULL) { + data->fault_cb(data->dev, STEPPER_DRV_EVENT_FAULT_DETECTED, + data->fault_cb_user_data); + } else { + LOG_WRN_ONCE("%s: Fault pin triggered but no callback is set", dev->name); + } } static int drv84xx_init(const struct device *dev) @@ -404,12 +420,6 @@ static int drv84xx_init(const struct device *dev) } } - ret = step_dir_stepper_common_init(dev); - if (ret != 0) { - LOG_ERR("Failed to initialize common step direction stepper (error: %d)", ret); - return ret; - } - /* Configure fault pin if it is available */ if (config->fault_pin.port != NULL) { ret = gpio_pin_configure_dt(&config->fault_pin, GPIO_INPUT); @@ -432,20 +442,12 @@ static int drv84xx_init(const struct device *dev) return 0; } -static DEVICE_API(stepper, drv84xx_stepper_api) = { +static DEVICE_API(stepper_drv, drv84xx_stepper_api) = { .enable = drv84xx_enable, .disable = drv84xx_disable, - .move_by = step_dir_stepper_common_move_by, - .move_to = step_dir_stepper_common_move_to, - .is_moving = step_dir_stepper_common_is_moving, - .set_reference_position = step_dir_stepper_common_set_reference_position, - .get_actual_position = step_dir_stepper_common_get_actual_position, - .set_microstep_interval = step_dir_stepper_common_set_microstep_interval, - .run = step_dir_stepper_common_run, - .stop = step_dir_stepper_common_stop, + .set_event_cb = drv84xx_set_fault_cb, .set_micro_step_res = drv84xx_set_micro_step_res, .get_micro_step_res = drv84xx_get_micro_step_res, - .set_event_callback = step_dir_stepper_common_set_event_callback, }; #define DRV84XX_DEVICE(inst) \ @@ -460,7 +462,6 @@ static DEVICE_API(stepper, drv84xx_stepper_api) = { }; \ \ static struct drv84xx_data drv84xx_data_##inst = { \ - .common = STEP_DIR_STEPPER_DT_INST_COMMON_DATA_INIT(inst), \ .ustep_res = DT_INST_PROP(inst, micro_step_res), \ .dev = DEVICE_DT_INST_GET(inst), \ }; \ diff --git a/dts/bindings/stepper/adi/adi,tmc2209.yaml b/dts/bindings/stepper/adi/adi,tmc2209.yaml index 95eedad546c2..8c093d5c65f3 100644 --- a/dts/bindings/stepper/adi/adi,tmc2209.yaml +++ b/dts/bindings/stepper/adi/adi,tmc2209.yaml @@ -8,17 +8,14 @@ description: | tmc2209: tmc2209 { compatible = "adi,tmc2209"; enable-gpios = <&gpio0 0 GPIO_ACTIVE_HIGH>; - msx-gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>, - <&gpio0 2 GPIO_ACTIVE_HIGH>; - step-gpios = <&gpio0 3 GPIO_ACTIVE_HIGH>; - dir-gpios = <&gpio0 4 GPIO_ACTIVE_HIGH>; - dual-edge-step; + m0-gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>; + m1-gpios = <&gpio0 2 GPIO_ACTIVE_HIGH>; } compatible: "adi,tmc2209" include: - - name: stepper-controller.yaml + - name: stepper-driver.yaml - name: step-dir-timing.yaml properties: diff --git a/dts/bindings/stepper/adi/adi,tmc50xx-stepper-drv.yaml b/dts/bindings/stepper/adi/adi,tmc50xx-stepper-drv.yaml new file mode 100644 index 000000000000..339df08499a7 --- /dev/null +++ b/dts/bindings/stepper/adi/adi,tmc50xx-stepper-drv.yaml @@ -0,0 +1,15 @@ +# SPDX-FileCopyrightText: Copyright (c) 2025 Jilay Sandeep Pandya +# SPDX-License-Identifier: Apache-2.0 + +compatible: "adi,tmc50xx-stepper-drv" + +include: + - name: stepper-driver.yaml + - name: adi,trinamic-stallguard.yaml + property-allowlist: + - stallguard2-threshold + +properties: + idx: + type: int + required: true diff --git a/dts/bindings/stepper/adi/adi,tmc50xx-stepper.yaml b/dts/bindings/stepper/adi/adi,tmc50xx-stepper.yaml new file mode 100644 index 000000000000..000245557dcb --- /dev/null +++ b/dts/bindings/stepper/adi/adi,tmc50xx-stepper.yaml @@ -0,0 +1,32 @@ +# SPDX-FileCopyrightText: Copyright (c) 2025 Jilay Sandeep Pandya +# SPDX-License-Identifier: Apache-2.0 + +compatible: "adi,tmc50xx-stepper" + +include: + - name: adi,trinamic-stallguard.yaml + property-allowlist: + - activate-stallguard2 + - stallguard-threshold-velocity + - stallguard-velocity-check-interval-ms + - name: adi,trinamic-ramp-generator.yaml + property-allowlist: + - vstart + - a1 + - v1 + - amax + - vmax + - dmax + - d1 + - vstop + - tzerowait + - vhigh + - vcoolthrs + - ihold + - irun + - iholddelay + +properties: + idx: + type: int + required: true diff --git a/dts/bindings/stepper/adi/adi,tmc50xx.yaml b/dts/bindings/stepper/adi/adi,tmc50xx.yaml index eba9cd3f664c..ea988be5bfc7 100644 --- a/dts/bindings/stepper/adi/adi,tmc50xx.yaml +++ b/dts/bindings/stepper/adi/adi,tmc50xx.yaml @@ -15,40 +15,37 @@ description: | reg = <0>; spi-max-frequency = ; /* Maximum SPI bus frequency */ - #address-cells = <1>; - #size-cells = <0>; - poscmp-enable; test-mode; lock-gconf; /* ADI TMC Global configuration flags */ clock-frequency = ; /* Internal/External Clock frequency */ - motor: motor@0 { - status = "okay"; - reg = <0>; - - /* common stepper controller settings */ - invert-direction; - micro-step-res = <256>; - - /* ADI TMC stallguard settings specific to TMC50XX */ - activate-stallguard2; - stallguard-velocity-check-interval-ms=<100>; - stallguard2-threshold=<9>; - stallguard-threshold-velocity=<500000>; + tmc50xx_0_stepper_driver: tmc50xx_0_stepper_driver { + idx = <0>; + compatible = "adi,tmc50xx-stepper-drv"; + micro-step-res = <256>; + /* ADI TMC stallguard settings specific to TMC50XX */ + stallguard2-threshold=<30>; + }; - /* ADI TMC ramp generator as well as current settings */ - vstart = <10>; - a1 = <20>; - v1 = <30>; - d1 = <40>; - vmax = <50>; - amax = <60>; - dmax = <70>; - tzerowait = <80>; - vhigh = <90>; - vcoolthrs = <100>; - ihold = <1>; - irun = <2>; - iholddelay = <3>; + tmc50xx_0_motion_controller: tmc50xx_0_motion_controller { + idx = <0>; + compatible = "adi,tmc50xx-stepper"; + vstart = <1000>; + vstop = <10>; + a1 = <10000>; + v1 = <50000>; + d1 = <14000>; + vmax = <900000>; + amax = <50000>; + dmax = <7000>; + tzerowait = <100>; + vhigh = <900000>; + vcoolthrs = <900000>; + ihold = <1>; + irun = <10>; + iholddelay = <1>; + activate-stallguard2; + stallguard-velocity-check-interval-ms=<1000>; + stallguard-threshold-velocity=<200000>; }; }; }; @@ -65,14 +62,6 @@ include: - lock-gconf properties: - "#address-cells": - default: 1 - const: 1 - - "#size-cells": - default: 0 - const: 0 - clock-frequency: type: int required: true @@ -83,31 +72,18 @@ properties: Hint: µstep velocity v[Hz] µsteps / s v[Hz] = v[50xx] * ( fCLK[Hz]/2 / 2^23 ) where v[50xx] is the value written to the TMC50XX. + shaft1: + type: boolean + description: | + Inverse motor 1 direction + + shaft2: + type: boolean + description: | + Inverse motor 2 direction + child-binding: include: - - name: stepper-controller.yaml - name: base.yaml property-allowlist: - reg - - name: adi,trinamic-ramp-generator.yaml - property-allowlist: - - vstart - - a1 - - v1 - - amax - - vmax - - dmax - - d1 - - vstop - - tzerowait - - vhigh - - vcoolthrs - - ihold - - irun - - iholddelay - - name: adi,trinamic-stallguard.yaml - property-allowlist: - - activate-stallguard2 - - stallguard2-threshold - - stallguard-threshold-velocity - - stallguard-velocity-check-interval-ms diff --git a/dts/bindings/stepper/adi/adi,tmc51xx-base.yaml b/dts/bindings/stepper/adi/adi,tmc51xx-base.yaml index dbdd40065c4a..b311c5d12054 100644 --- a/dts/bindings/stepper/adi/adi,tmc51xx-base.yaml +++ b/dts/bindings/stepper/adi/adi,tmc51xx-base.yaml @@ -9,40 +9,12 @@ include: property-allowlist: - en-pwm-mode - test-mode - - name: stepper-controller.yaml - - name: adi,trinamic-ramp-generator.yaml - property-allowlist: - - vstart - - a1 - - v1 - - amax - - vmax - - dmax - - d1 - - vstop - - tzerowait - - thigh - - tcoolthrs - - tpwmthrs - - tpowerdown - - ihold - - irun - - iholddelay - - name: adi,trinamic-stallguard.yaml - property-allowlist: - - activate-stallguard2 - - stallguard2-threshold - - stallguard-threshold-velocity - - stallguard-velocity-check-interval-ms properties: - "#address-cells": - default: 1 - const: 1 - - "#size-cells": - default: 0 - const: 0 + shaft: + type: boolean + description: | + Inverse motor direction clock-frequency: type: int diff --git a/dts/bindings/stepper/adi/adi,tmc51xx-spi.yaml b/dts/bindings/stepper/adi/adi,tmc51xx-spi.yaml index f9213a95c11c..0ac310a1e262 100644 --- a/dts/bindings/stepper/adi/adi,tmc51xx-spi.yaml +++ b/dts/bindings/stepper/adi/adi,tmc51xx-spi.yaml @@ -13,28 +13,42 @@ description: | spi-max-frequency = ; diag0-gpios = <&gpio0 0 (GPIO_ACTIVE_HIGH | GPIO_PULL_UP)>; /* Diag0 pin */ - #address-cells = <1>; - #size-cells = <0>; - /* Common settings from base binding */ clock-frequency = ; /* Internal/External Clock frequency */ - en-pwm-mode; - invert-direction; - micro-step-res = <256>; - - /* ADI TMC ramp generator as well as current settings */ - vstart = <0>; - vstop = <10>; - a1 = <1000>; - v1 = <50000>; - d1 = <1400>; - vmax = <200000>; - amax = <50000>; - dmax = <700>; - tzerowait = <100>; - ihold = <10>; - irun = <31>; - iholddelay = <6>; + en-pwm-mode, shaft; /* ADI TMC Global configuration flags */ + + tmc51xx_1_stepper_driver: tmc51xx_1_stepper_driver { + compatible = "adi,tmc51xx-stepper-drv"; + micro-step-res = <256>; + /* ADI TMC stallguard settings specific to TMC51XX */ + stallguard2-threshold=<9>; + }; + + tmc51xx_1_motion_controller: tmc51xx_1_motion_controller { + compatible = "adi,tmc51xx-stepper"; + + /* ADI TMC stallguard settings specific to TMC5160 */ + activate-stallguard2; + stallguard-velocity-check-interval-ms = <100>; + stallguard-threshold-velocity = <50000>; + + /* ADI TMC ramp generator as well as current settings */ + vstart = <10>; + a1 = <20>; + v1 = <30>; + d1 = <40>; + vmax = <50>; + amax = <60>; + dmax = <70>; + tzerowait = <80>; + thigh = <90>; + tcoolthrs = <100>; + tpwmthrs = <110>; + tpowerdown = <120>; + ihold = <1>; + irun = <2>; + iholddelay = <3>; + }; }; }; diff --git a/dts/bindings/stepper/adi/adi,tmc51xx-stepper-drv.yaml b/dts/bindings/stepper/adi/adi,tmc51xx-stepper-drv.yaml new file mode 100644 index 000000000000..d2893111ca87 --- /dev/null +++ b/dts/bindings/stepper/adi/adi,tmc51xx-stepper-drv.yaml @@ -0,0 +1,10 @@ +# SPDX-FileCopyrightText: Copyright (c) 2025 Jilay Sandeep Pandya +# SPDX-License-Identifier: Apache-2.0 + +compatible: "adi,tmc51xx-stepper-drv" + +include: + - name: stepper-driver.yaml + - name: adi,trinamic-stallguard.yaml + property-allowlist: + - stallguard2-threshold diff --git a/dts/bindings/stepper/adi/adi,tmc51xx-stepper.yaml b/dts/bindings/stepper/adi/adi,tmc51xx-stepper.yaml new file mode 100644 index 000000000000..4f86c3ea8b58 --- /dev/null +++ b/dts/bindings/stepper/adi/adi,tmc51xx-stepper.yaml @@ -0,0 +1,29 @@ +# SPDX-FileCopyrightText: Copyright (c) 2025 Jilay Sandeep Pandya +# SPDX-License-Identifier: Apache-2.0 + +compatible: "adi,tmc51xx-stepper" + +include: + - name: adi,trinamic-stallguard.yaml + property-allowlist: + - activate-stallguard2 + - stallguard-threshold-velocity + - stallguard-velocity-check-interval-ms + - name: adi,trinamic-ramp-generator.yaml + property-allowlist: + - vstart + - a1 + - v1 + - amax + - vmax + - dmax + - d1 + - vstop + - tzerowait + - thigh + - tcoolthrs + - tpwmthrs + - tpowerdown + - ihold + - irun + - iholddelay diff --git a/dts/bindings/stepper/adi/adi,tmc51xx-uart.yaml b/dts/bindings/stepper/adi/adi,tmc51xx-uart.yaml index a6691ff36b06..e87d8a475244 100644 --- a/dts/bindings/stepper/adi/adi,tmc51xx-uart.yaml +++ b/dts/bindings/stepper/adi/adi,tmc51xx-uart.yaml @@ -23,21 +23,41 @@ description: | clock-frequency = ; en-pwm-mode; invert-direction; - micro-step-res = <256>; - - /* ADI TMC ramp generator as well as current settings */ - vstart = <0>; - vstop = <10>; - a1 = <1000>; - v1 = <50000>; - d1 = <1400>; - vmax = <200000>; - amax = <50000>; - dmax = <700>; - tzerowait = <100>; - ihold = <10>; - irun = <31>; - iholddelay = <6>; + + tmc51xx_stepper_driver: stepper_driver { + compatible = "adi,tmc51xx-stepper-drv"; + micro-step-res = <256>; + + /* ADI TMC stallguard settings specific to TMC51XX */ + stallguard2-threshold=<9>; + }; + + /* common stepper controller settings */ + tmc51xx_motion_controller: motion_controller { + compatible = "adi,tmc51xx-stepper"; + + /* ADI TMC stallguard settings specific to TMC5160 */ + activate-stallguard2; + stallguard-velocity-check-interval-ms = <100>; + stallguard-threshold-velocity = <50000>; + + /* ADI TMC ramp generator as well as current settings */ + vstart = <10>; + a1 = <20>; + v1 = <30>; + d1 = <40>; + vmax = <50>; + amax = <60>; + dmax = <70>; + tzerowait = <80>; + thigh = <90>; + tcoolthrs = <100>; + tpwmthrs = <110>; + tpowerdown = <120>; + ihold = <1>; + irun = <2>; + iholddelay = <3>; + }; }; }; diff --git a/dts/bindings/stepper/allegro/allegro,a4979.yaml b/dts/bindings/stepper/allegro/allegro,a4979.yaml index d53832a83138..ce573c96fce1 100644 --- a/dts/bindings/stepper/allegro/allegro,a4979.yaml +++ b/dts/bindings/stepper/allegro/allegro,a4979.yaml @@ -13,18 +13,15 @@ description: | compatible = "allegro,a4979"; micro-step-res = <2>; reset-gpios = <&gpiod 10 GPIO_ACTIVE_HIGH>; - dir-gpios = <&gpiod 14 GPIO_ACTIVE_HIGH>; - step-gpios = <&gpiod 15 GPIO_ACTIVE_HIGH>; en-gpios = <&gpiod 11 GPIO_ACTIVE_HIGH>; m0-gpios = <&gpiod 13 0>; m1-gpios = <&gpiod 12 0>; - counter = <&counter5>; }; compatible: "allegro,a4979" include: - - name: stepper-controller.yaml + - name: stepper-driver.yaml - name: step-dir-timing.yaml properties: diff --git a/dts/bindings/stepper/stepper-controller.yaml b/dts/bindings/stepper/stepper-controller.yaml deleted file mode 100644 index a73037bb6b97..000000000000 --- a/dts/bindings/stepper/stepper-controller.yaml +++ /dev/null @@ -1,46 +0,0 @@ -# SPDX-FileCopyrightText: Copyright (c) 2024 Carl Zeiss Meditec AG -# SPDX-License-Identifier: Apache-2.0 - -description: Stepper Controller - -properties: - invert-direction: - type: boolean - description: | - Invert motor direction. - - micro-step-res: - type: int - default: 1 - enum: - - 1 - - 2 - - 4 - - 8 - - 16 - - 32 - - 64 - - 128 - - 256 - description: | - micro-step resolution to be set while initializing the device driver. - - en-gpios: - type: phandle-array - description: | - GPIO pins used to control the enable signal of the motor driver. - - step-gpios: - type: phandle-array - description: | - The GPIO pins used to send step signals to the stepper motor. - - dir-gpios: - type: phandle-array - description: | - The GPIO pins used to send direction signals to the stepper motor. - Pin will be driven high for forward direction and low for reverse direction. - - counter: - type: phandle - description: Counter used for generating step-accurate pulse signals. diff --git a/dts/bindings/stepper/stepper-driver.yaml b/dts/bindings/stepper/stepper-driver.yaml new file mode 100644 index 000000000000..a4ae99dc76e8 --- /dev/null +++ b/dts/bindings/stepper/stepper-driver.yaml @@ -0,0 +1,26 @@ +# SPDX-FileCopyrightText: Copyright (c) 2024 Carl Zeiss Meditec AG +# SPDX-License-Identifier: Apache-2.0 + +description: collection of properties for stepper drivers. + +properties: + micro-step-res: + type: int + default: 1 + enum: + - 1 + - 2 + - 4 + - 8 + - 16 + - 32 + - 64 + - 128 + - 256 + description: | + micro-step resolution to be set while initializing the device driver. + + en-gpios: + type: phandle-array + description: | + GPIO pins used to control the enable signal of the motor driver. diff --git a/dts/bindings/stepper/ti/ti,drv84xx.yaml b/dts/bindings/stepper/ti/ti,drv84xx.yaml index d0efc11a3ebf..e179240820a3 100644 --- a/dts/bindings/stepper/ti/ti,drv84xx.yaml +++ b/dts/bindings/stepper/ti/ti,drv84xx.yaml @@ -4,33 +4,24 @@ description: | TI DRV84XX stepper motor driver. Compatible with drv8424, drv8425, drv8426, drv8434 and drv8436. - SAFETY: - The counter needs to support both set_top_value functionalities: Setting a new top value and - attaching an ISR to the turnaround. - SAFETY: - The step gpio pin needs to be connected directly to the SOC GPIO controller, connecting the - pin to a controller connected via a bus such as i2c or others will lead to undefined behaviour. Example: drv8424: drv8424 { status = "okay"; compatible = "ti,drv84xx"; - dir-gpios = <&arduino_header 18 0>; - step-gpios = <&arduino_header 19 0>; fault-gpios = <&arduino_header 16 0>; sleep-gpios = <&arduino_header 15 GPIO_ACTIVE_LOW>; en-gpios = <&arduino_header 14 0>; m0-gpios = <&mikroe_stepper_gpios 0 0>; m1-gpios = <&mikroe_stepper_gpios 1 0>; - counter = <&counter2>; }; compatible: "ti,drv84xx" include: - - name: stepper-controller.yaml + - name: stepper-driver.yaml - name: step-dir-timing.yaml properties: diff --git a/dts/bindings/stepper/zephyr,fake-stepper-drv.yaml b/dts/bindings/stepper/zephyr,fake-stepper-drv.yaml new file mode 100644 index 000000000000..85b0d355dfa3 --- /dev/null +++ b/dts/bindings/stepper/zephyr,fake-stepper-drv.yaml @@ -0,0 +1,9 @@ +# Copyright (c) 2024 Fabian Blatz +# SPDX-License-Identifier: Apache-2.0 + +description: | + A fake stepper driver for use as either a stub or a mock in testing. + +compatible: "zephyr,fake-stepper-drv" + +include: stepper-driver.yaml diff --git a/dts/bindings/stepper/zephyr,fake-stepper.yaml b/dts/bindings/stepper/zephyr,fake-stepper.yaml index d286dfbfeb4c..21b0e9188efc 100644 --- a/dts/bindings/stepper/zephyr,fake-stepper.yaml +++ b/dts/bindings/stepper/zephyr,fake-stepper.yaml @@ -1,10 +1,7 @@ -# Copyright (c) 2024 Fabian Blatz +# Copyright (c) 2025 Jilay Sandeep Pandya # SPDX-License-Identifier: Apache-2.0 description: | - This binding provides a fake stepper controller for use as either a stub or a mock in - Zephyr testing. + A fake stepper controller for use as either a stub or a mock in testing. compatible: "zephyr,fake-stepper" - -include: stepper-controller.yaml diff --git a/dts/bindings/stepper/zephyr,gpio-step-dir-stepper.yaml b/dts/bindings/stepper/zephyr,gpio-step-dir-stepper.yaml new file mode 100644 index 000000000000..091c9508462d --- /dev/null +++ b/dts/bindings/stepper/zephyr,gpio-step-dir-stepper.yaml @@ -0,0 +1,55 @@ +# SPDX-FileCopyrightText: Copyright (c) 2025 Jilay Sandeep Pandya +# SPDX-License-Identifier: Apache-2.0 + +description: | + CPU based Stepper Motion Controller for controlling stepper motors using GPIO pins. + It is used to generate step and direction signals for a stepper motor driver. + Example: + step_dir_motion_control: step_dir_motion_control { + compatible = "zephyr,gpio-step-dir-stepper"; + step-gpios = <&gpio0 10 GPIO_ACTIVE_HIGH>; + dir-gpios = <&gpio0 11 GPIO_ACTIVE_HIGH>; + invert-direction; + counter = <&counter1>; + stepper-drv = <&tmc2209>; /* Optional stepper-drv driver reference */ + }; + + +compatible: "zephyr,gpio-step-dir-stepper" + +properties: + invert-direction: + type: boolean + description: | + Invert motor direction. + + step-gpios: + type: phandle-array + description: | + The GPIO pins used to send step signals to the stepper motor. + + dir-gpios: + type: phandle-array + description: | + The GPIO pins used to send direction signals to the stepper motor. + Pin will be driven high for forward direction and low for reverse direction. + + counter: + type: phandle + description: | + Counter used for generating step-accurate pulse signals. + This should be a reference to a counter node in the device tree. + When this property is present, the stepper motion controller will use + the counter as a timing source instead of the default work queue timing. + This enables more precise step timing control. + + Note: The counter needs to support both set_top_value functionalities: + - Setting a new top value + - Attaching an ISR to the turnaround + + stepper-drv: + type: phandle + description: | + Reference to the stepper driver device. + This property, if provided, will result in configuring the driver with the + step-width-ns and dual-edge-step properties from the stepper driver node. diff --git a/dts/bindings/stepper/zephyr,h-bridge-stepper.yaml b/dts/bindings/stepper/zephyr,h-bridge-stepper.yaml index b243a8d92938..b6cd00d31a19 100644 --- a/dts/bindings/stepper/zephyr,h-bridge-stepper.yaml +++ b/dts/bindings/stepper/zephyr,h-bridge-stepper.yaml @@ -7,9 +7,8 @@ description: | Example: /* Lead A is connected Lead C and Lead B is connected to Lead D*/ - stepper: stepper { + h_bridge_stepper: h_bridge_stepper { compatible = "zephyr,h-bridge-stepper"; - en-gpios = <&gpioa 6 GPIO_ACTIVE_HIGH>; gpios = <&gpioa 9 GPIO_ACTIVE_HIGH>, /* Lead A1/A */ <&gpioc 7 GPIO_ACTIVE_HIGH>, /* Lead B1/B */ <&gpiob 0 GPIO_ACTIVE_HIGH>, /* Lead A2/C */ @@ -18,11 +17,38 @@ description: | compatible: "zephyr,h-bridge-stepper" -include: stepper-controller.yaml - properties: + invert-direction: + type: boolean + description: | + Invert motor direction. + gpios: type: phandle-array required: true description: | The gpio pin array on which the stepper inputs are to be connected + + lut-step-gap: + type: int + default: 1 + enum: + - 1 + - 2 + description: | + Step mode selection. + 1 - Half step mode + 2 - Full step mode + + counter: + type: phandle + description: | + Counter used for generating step-accurate pulse signals. + This should be a reference to a counter node in the device tree. + When this property is present, the stepper motion controller will use + the counter as a timing source instead of the default work queue timing. + This enables more precise step timing control. + + Note: The counter needs to support both set_top_value functionalities: + - Setting a new top value + - Attaching an ISR to the turnaround diff --git a/include/zephyr/drivers/stepper.h b/include/zephyr/drivers/stepper.h index 13bf336d5c28..7a1ce8267117 100644 --- a/include/zephyr/drivers/stepper.h +++ b/include/zephyr/drivers/stepper.h @@ -30,43 +30,6 @@ extern "C" { #endif -/** - * @brief Stepper Motor micro-step resolution options - */ -enum stepper_micro_step_resolution { - /** Full step resolution */ - STEPPER_MICRO_STEP_1 = 1, - /** 2 micro-steps per full step */ - STEPPER_MICRO_STEP_2 = 2, - /** 4 micro-steps per full step */ - STEPPER_MICRO_STEP_4 = 4, - /** 8 micro-steps per full step */ - STEPPER_MICRO_STEP_8 = 8, - /** 16 micro-steps per full step */ - STEPPER_MICRO_STEP_16 = 16, - /** 32 micro-steps per full step */ - STEPPER_MICRO_STEP_32 = 32, - /** 64 micro-steps per full step */ - STEPPER_MICRO_STEP_64 = 64, - /** 128 micro-steps per full step */ - STEPPER_MICRO_STEP_128 = 128, - /** 256 micro-steps per full step */ - STEPPER_MICRO_STEP_256 = 256, -}; - -/** - * @brief Macro to calculate the index of the microstep resolution - * @param res Microstep resolution - */ -#define MICRO_STEP_RES_INDEX(res) LOG2(res) - -#define VALID_MICRO_STEP_RES(res) \ - ((res) == STEPPER_MICRO_STEP_1 || (res) == STEPPER_MICRO_STEP_2 || \ - (res) == STEPPER_MICRO_STEP_4 || (res) == STEPPER_MICRO_STEP_8 || \ - (res) == STEPPER_MICRO_STEP_16 || (res) == STEPPER_MICRO_STEP_32 || \ - (res) == STEPPER_MICRO_STEP_64 || (res) == STEPPER_MICRO_STEP_128 || \ - (res) == STEPPER_MICRO_STEP_256) - /** * @brief Stepper Motor direction options */ @@ -83,7 +46,7 @@ enum stepper_direction { enum stepper_run_mode { /** Hold Mode */ STEPPER_RUN_MODE_HOLD = 0, - /** Position Mode*/ + /** Position Mode */ STEPPER_RUN_MODE_POSITION = 1, /** Velocity Mode */ STEPPER_RUN_MODE_VELOCITY = 2, @@ -95,16 +58,12 @@ enum stepper_run_mode { enum stepper_event { /** Steps set using move_by or move_to have been executed */ STEPPER_EVENT_STEPS_COMPLETED = 0, - /** Stall detected */ - STEPPER_EVENT_STALL_DETECTED = 1, /** Left end switch status changes to pressed */ - STEPPER_EVENT_LEFT_END_STOP_DETECTED = 2, + STEPPER_EVENT_LEFT_END_STOP_DETECTED = 1, /** Right end switch status changes to pressed */ - STEPPER_EVENT_RIGHT_END_STOP_DETECTED = 3, + STEPPER_EVENT_RIGHT_END_STOP_DETECTED = 2, /** Stepper has stopped */ - STEPPER_EVENT_STOPPED = 4, - /** Fault with the stepper controller detected */ - STEPPER_EVENT_FAULT_DETECTED = 5, + STEPPER_EVENT_STOPPED = 3, }; /** @@ -114,35 +73,6 @@ enum stepper_event { * */ -/** - * @brief Enable the stepper driver. - * - * @see stepper_enable() for details. - */ -typedef int (*stepper_enable_t)(const struct device *dev); - -/** - * @brief Disable the stepper driver. - * - * @see stepper_disable() for details. - */ -typedef int (*stepper_disable_t)(const struct device *dev); - -/** - * @brief Set the micro-step resolution - * - * @see stepper_set_micro_step_res() for details. - */ -typedef int (*stepper_set_micro_step_res_t)(const struct device *dev, - const enum stepper_micro_step_resolution resolution); - -/** - * @brief Get the micro-step resolution - * - * @see stepper_get_micro_step_res() for details. - */ -typedef int (*stepper_get_micro_step_res_t)(const struct device *dev, - enum stepper_micro_step_resolution *resolution); /** * @brief Set the reference position of the stepper * @@ -170,6 +100,7 @@ typedef void (*stepper_event_callback_t)(const struct device *dev, const enum st */ typedef int (*stepper_set_event_callback_t)(const struct device *dev, stepper_event_callback_t callback, void *user_data); + /** * @brief Set the time interval between steps in nanoseconds. * @@ -216,10 +147,6 @@ typedef int (*stepper_is_moving_t)(const struct device *dev, bool *is_moving); * @brief Stepper Driver API */ __subsystem struct stepper_driver_api { - stepper_enable_t enable; - stepper_disable_t disable; - stepper_set_micro_step_res_t set_micro_step_res; - stepper_get_micro_step_res_t get_micro_step_res; stepper_set_reference_position_t set_reference_position; stepper_get_actual_position_t get_actual_position; stepper_set_event_callback_t set_event_callback; @@ -235,105 +162,10 @@ __subsystem struct stepper_driver_api { * @endcond */ -/** - * @brief Enable stepper driver - * - * @details Enabling the driver shall switch on the power stage and energize the coils. - * - * @param dev pointer to the stepper driver instance - * - * @retval -EIO Error during Enabling - * @retval 0 Success - */ -__syscall int stepper_enable(const struct device *dev); - -static inline int z_impl_stepper_enable(const struct device *dev) -{ - const struct stepper_driver_api *api = (const struct stepper_driver_api *)dev->api; - - return api->enable(dev); -} - -/** - * @brief Disable stepper driver - * - * @details Disabling the driver shall switch off the power stage and de-energize the coils. - * Disabling the stepper does not implicitly stop the stepper. If the motor shall not move after - * re-enabling the stepper than consider calling stepper_stop() before. - * - * @param dev pointer to the stepper driver instance - * - * @retval -ENOTSUP Disabling of driver is not supported. - * @retval -EIO Error during Disabling - * @retval 0 Success - */ -__syscall int stepper_disable(const struct device *dev); - -static inline int z_impl_stepper_disable(const struct device *dev) -{ - const struct stepper_driver_api *api = (const struct stepper_driver_api *)dev->api; - - return api->disable(dev); -} - -/** - * @brief Set the micro-step resolution in stepper driver - * - * @param dev pointer to the stepper driver instance - * @param resolution micro-step resolution - * - * @retval -EIO General input / output error - * @retval -ENOSYS If not implemented by device driver - * @retval -EINVAL If the requested resolution is invalid - * @retval -ENOTSUP If the requested resolution is not supported - * @retval 0 Success - */ -__syscall int stepper_set_micro_step_res(const struct device *dev, - enum stepper_micro_step_resolution resolution); - -static inline int z_impl_stepper_set_micro_step_res(const struct device *dev, - enum stepper_micro_step_resolution resolution) -{ - const struct stepper_driver_api *api = (const struct stepper_driver_api *)dev->api; - - if (api->set_micro_step_res == NULL) { - return -ENOSYS; - } - - if (!VALID_MICRO_STEP_RES(resolution)) { - return -EINVAL; - } - return api->set_micro_step_res(dev, resolution); -} - -/** - * @brief Get the micro-step resolution in stepper driver - * - * @param dev pointer to the stepper driver instance - * @param resolution micro-step resolution - * - * @retval -EIO General input / output error - * @retval -ENOSYS If not implemented by device driver - * @retval 0 Success - */ -__syscall int stepper_get_micro_step_res(const struct device *dev, - enum stepper_micro_step_resolution *resolution); - -static inline int z_impl_stepper_get_micro_step_res(const struct device *dev, - enum stepper_micro_step_resolution *resolution) -{ - const struct stepper_driver_api *api = (const struct stepper_driver_api *)dev->api; - - if (api->get_micro_step_res == NULL) { - return -ENOSYS; - } - return api->get_micro_step_res(dev, resolution); -} - /** * @brief Set the reference position of the stepper * - * @param dev Pointer to the stepper driver instance. + * @param dev pointer to the device structure for the driver instance. * @param value The reference position to set in micro-steps. * * @retval -EIO General input / output error @@ -345,6 +177,7 @@ __syscall int stepper_set_reference_position(const struct device *dev, int32_t v static inline int z_impl_stepper_set_reference_position(const struct device *dev, const int32_t value) { + __ASSERT_NO_MSG(dev != NULL); const struct stepper_driver_api *api = (const struct stepper_driver_api *)dev->api; if (api->set_reference_position == NULL) { @@ -358,7 +191,7 @@ static inline int z_impl_stepper_set_reference_position(const struct device *dev * @note This function does not guarantee that the returned position is the exact current * position. For precise positioning, encoders should be used in addition to the stepper driver. * - * @param dev pointer to the stepper driver instance + * @param dev pointer to the device structure for the driver instance. * @param value The actual position to get in micro-steps * * @retval -EIO General input / output error @@ -369,6 +202,8 @@ __syscall int stepper_get_actual_position(const struct device *dev, int32_t *val static inline int z_impl_stepper_get_actual_position(const struct device *dev, int32_t *value) { + __ASSERT_NO_MSG(dev != NULL); + __ASSERT_NO_MSG(value != NULL); const struct stepper_driver_api *api = (const struct stepper_driver_api *)dev->api; if (api->get_actual_position == NULL) { @@ -380,7 +215,7 @@ static inline int z_impl_stepper_get_actual_position(const struct device *dev, i /** * @brief Set the callback function to be called when a stepper event occurs * - * @param dev pointer to the stepper driver instance + * @param dev pointer to the device structure for the driver instance. * @param callback Callback function to be called when a stepper event occurs * passing NULL will disable the callback * @param user_data User data to be passed to the callback function @@ -395,6 +230,7 @@ static inline int z_impl_stepper_set_event_callback(const struct device *dev, stepper_event_callback_t callback, void *user_data) { + __ASSERT_NO_MSG(dev != NULL); const struct stepper_driver_api *api = (const struct stepper_driver_api *)dev->api; if (api->set_event_callback == NULL) { @@ -409,7 +245,7 @@ static inline int z_impl_stepper_set_event_callback(const struct device *dev, * @note Setting step interval does not set the stepper into motion, a combination of * set_microstep_interval and move is required to set the stepper into motion. * - * @param dev pointer to the stepper driver instance + * @param dev pointer to the device structure for the driver instance. * @param microstep_interval_ns time interval between steps in nanoseconds * * @retval -EIO General input / output error @@ -423,6 +259,7 @@ __syscall int stepper_set_microstep_interval(const struct device *dev, static inline int z_impl_stepper_set_microstep_interval(const struct device *dev, const uint64_t microstep_interval_ns) { + __ASSERT_NO_MSG(dev != NULL); const struct stepper_driver_api *api = (const struct stepper_driver_api *)dev->api; if (api->set_microstep_interval == NULL) { @@ -437,7 +274,7 @@ static inline int z_impl_stepper_set_microstep_interval(const struct device *dev * @note The stepper will move by the given number of micro-steps from the current position. * This function is non-blocking. * - * @param dev pointer to the stepper driver instance + * @param dev pointer to the device structure for the driver instance. * @param micro_steps target micro-steps to be moved from the current position * * @retval -EIO General input / output error @@ -448,6 +285,7 @@ __syscall int stepper_move_by(const struct device *dev, int32_t micro_steps); static inline int z_impl_stepper_move_by(const struct device *dev, const int32_t micro_steps) { + __ASSERT_NO_MSG(dev != NULL); const struct stepper_driver_api *api = (const struct stepper_driver_api *)dev->api; return api->move_by(dev, micro_steps); @@ -459,7 +297,7 @@ static inline int z_impl_stepper_move_by(const struct device *dev, const int32_t * @note The stepper will move to the given micro-steps position from the reference position. * This function is non-blocking. * - * @param dev pointer to the stepper driver instance + * @param dev pointer to the device structure for the driver instance. * @param micro_steps target position to set in micro-steps * * @retval -EIO General input / output error @@ -470,11 +308,9 @@ __syscall int stepper_move_to(const struct device *dev, int32_t micro_steps); static inline int z_impl_stepper_move_to(const struct device *dev, const int32_t micro_steps) { + __ASSERT_NO_MSG(dev != NULL); const struct stepper_driver_api *api = (const struct stepper_driver_api *)dev->api; - if (api->move_to == NULL) { - return -ENOSYS; - } return api->move_to(dev, micro_steps); } @@ -485,7 +321,7 @@ static inline int z_impl_stepper_move_to(const struct device *dev, const int32_t * stalled or stopped using some other command, for instance, stepper_stop(). This * function is non-blocking. * - * @param dev pointer to the stepper driver instance + * @param dev pointer to the device structure for the driver instance. * @param direction The direction to set * * @retval -EIO General input / output error @@ -498,6 +334,7 @@ __syscall int stepper_run(const struct device *dev, enum stepper_direction direc static inline int z_impl_stepper_run(const struct device *dev, const enum stepper_direction direction) { + __ASSERT_NO_MSG(dev != NULL); const struct stepper_driver_api *api = (const struct stepper_driver_api *)dev->api; if (api->run == NULL) { @@ -510,7 +347,7 @@ static inline int z_impl_stepper_run(const struct device *dev, * @brief Stop the stepper * @note Cancel all active movements. * - * @param dev pointer to the stepper driver instance + * @param dev pointer to the device structure for the driver instance. * * @retval -EIO General input / output error * @retval -ENOSYS If not implemented by device driver @@ -520,6 +357,7 @@ __syscall int stepper_stop(const struct device *dev); static inline int z_impl_stepper_stop(const struct device *dev) { + __ASSERT_NO_MSG(dev != NULL); const struct stepper_driver_api *api = (const struct stepper_driver_api *)dev->api; if (api->stop == NULL) { @@ -531,7 +369,7 @@ static inline int z_impl_stepper_stop(const struct device *dev) /** * @brief Check if the stepper is currently moving * - * @param dev pointer to the stepper driver instance + * @param dev pointer to the device structure for the driver instance. * @param is_moving Pointer to a boolean to store the moving status of the stepper * * @retval -EIO General input / output error @@ -542,6 +380,8 @@ __syscall int stepper_is_moving(const struct device *dev, bool *is_moving); static inline int z_impl_stepper_is_moving(const struct device *dev, bool *is_moving) { + __ASSERT_NO_MSG(dev != NULL); + __ASSERT_NO_MSG(is_moving != NULL); const struct stepper_driver_api *api = (const struct stepper_driver_api *)dev->api; if (api->is_moving == NULL) { @@ -550,6 +390,245 @@ static inline int z_impl_stepper_is_moving(const struct device *dev, bool *is_mo return api->is_moving(dev, is_moving); } +/** + * @} + */ + +/** + * @brief Interface for stepper-drv drivers + * @defgroup stepper_drv_interface Stepper-Drv + * @since 4.0 + * @version 0.8.0 + * @ingroup io_interfaces + * @{ + */ + +/** + * @brief Stepper Motor micro-step resolution options + */ +enum stepper_drv_micro_step_resolution { + /** Full step resolution */ + STEPPER_DRV_MICRO_STEP_1 = 1, + /** 2 micro-steps per full step */ + STEPPER_DRV_MICRO_STEP_2 = 2, + /** 4 micro-steps per full step */ + STEPPER_DRV_MICRO_STEP_4 = 4, + /** 8 micro-steps per full step */ + STEPPER_DRV_MICRO_STEP_8 = 8, + /** 16 micro-steps per full step */ + STEPPER_DRV_MICRO_STEP_16 = 16, + /** 32 micro-steps per full step */ + STEPPER_DRV_MICRO_STEP_32 = 32, + /** 64 micro-steps per full step */ + STEPPER_DRV_MICRO_STEP_64 = 64, + /** 128 micro-steps per full step */ + STEPPER_DRV_MICRO_STEP_128 = 128, + /** 256 micro-steps per full step */ + STEPPER_DRV_MICRO_STEP_256 = 256, +}; + +/** + * @brief Macro to calculate the index of the microstep resolution + * @param res Microstep resolution + */ +#define MICRO_STEP_RES_INDEX(res) LOG2(res) + +#define VALID_MICRO_STEP_RES(res) \ + ((res) == STEPPER_DRV_MICRO_STEP_1 || (res) == STEPPER_DRV_MICRO_STEP_2 || \ + (res) == STEPPER_DRV_MICRO_STEP_4 || (res) == STEPPER_DRV_MICRO_STEP_8 || \ + (res) == STEPPER_DRV_MICRO_STEP_16 || (res) == STEPPER_DRV_MICRO_STEP_32 || \ + (res) == STEPPER_DRV_MICRO_STEP_64 || (res) == STEPPER_DRV_MICRO_STEP_128 || \ + (res) == STEPPER_DRV_MICRO_STEP_256) + +enum stepper_drv_event { + /** Stepper driver stall detected */ + STEPPER_DRV_EVENT_STALL_DETECTED = 0, + /** Stepper driver fault detected */ + STEPPER_DRV_EVENT_FAULT_DETECTED = 1, +}; + +/** + * @cond INTERNAL_HIDDEN + * + * Stepper Drv driver API definition and system call entry points. + * + */ + +/** + * @brief Enable the stepper driver + * + * @see stepper_drv_enable() for details. + */ +typedef int (*stepper_drv_enable_t)(const struct device *dev); + +/** + * @brief Disable the stepper driver + * + * @see stepper_drv_disable() for details. + */ +typedef int (*stepper_drv_disable_t)(const struct device *dev); + +/** + * @brief Set the stepper micro-step resolution + * + * @see stepper_drv_set_micro_step_res() for details. + */ +typedef int (*stepper_drv_set_micro_step_res_t)( + const struct device *dev, const enum stepper_drv_micro_step_resolution resolution); + +/** + * @brief Get the stepper micro-step resolution + * + * @see stepper_drv_get_micro_step_res() for details. + */ +typedef int (*stepper_drv_get_micro_step_res_t)(const struct device *dev, + enum stepper_drv_micro_step_resolution *resolution); + +/** + * @brief Callback function for stepper driver events + */ +typedef void (*stepper_drv_event_cb_t)(const struct device *dev, const enum stepper_drv_event event, + void *user_data); + +/** + * @brief Set the callback function to be called when a stepper_drv_event occurs + * + * @see stepper_drv_set_event_callback() for details. + */ +typedef int (*stepper_drv_set_event_callback_t)(const struct device *dev, + stepper_drv_event_cb_t callback, void *user_data); + +/** + * @brief Stepper DRV Driver API + */ +__subsystem struct stepper_drv_driver_api { + stepper_drv_enable_t enable; + stepper_drv_disable_t disable; + stepper_drv_set_micro_step_res_t set_micro_step_res; + stepper_drv_get_micro_step_res_t get_micro_step_res; + stepper_drv_set_event_callback_t set_event_cb; +}; + +/** + * @endcond + */ + +/** + * @brief Enable stepper driver + * + * @details Enabling the driver shall switch on the power stage and energize the coils. + * + * @param dev pointer to the device structure for the driver instance. + * + * @retval -EIO Error during Enabling + * @retval 0 Success + */ +__syscall int stepper_drv_enable(const struct device *dev); + +static inline int z_impl_stepper_drv_enable(const struct device *dev) +{ + __ASSERT_NO_MSG(dev != NULL); + const struct stepper_drv_driver_api *api = (const struct stepper_drv_driver_api *)dev->api; + + return api->enable(dev); +} + +/** + * @brief Disable stepper driver + * + * @details Disabling the driver shall switch off the power stage and de-energize the coils. + * + * @param dev pointer to the device structure for the driver instance. + * + * @retval -ENOTSUP Disabling of driver is not supported. + * @retval -EIO Error during Disabling + * @retval 0 Success + */ +__syscall int stepper_drv_disable(const struct device *dev); + +static inline int z_impl_stepper_drv_disable(const struct device *dev) +{ + __ASSERT_NO_MSG(dev != NULL); + const struct stepper_drv_driver_api *api = (const struct stepper_drv_driver_api *)dev->api; + + return api->disable(dev); +} + +/** + * @brief Set the micro-step resolution in stepper driver + * + * @param dev pointer to the device structure for the driver instance. + * @param res micro-step resolution + * + * @retval -EIO General input / output error + * @retval -EINVAL If the requested resolution is invalid + * @retval -ENOTSUP If the requested resolution is not supported + * @retval 0 Success + */ +__syscall int stepper_drv_set_micro_step_res(const struct device *dev, + enum stepper_drv_micro_step_resolution res); + +static inline int z_impl_stepper_drv_set_micro_step_res(const struct device *dev, + enum stepper_drv_micro_step_resolution res) +{ + __ASSERT_NO_MSG(dev != NULL); + const struct stepper_drv_driver_api *api = (const struct stepper_drv_driver_api *)dev->api; + + if (!VALID_MICRO_STEP_RES(res)) { + return -EINVAL; + } + return api->set_micro_step_res(dev, res); +} + +/** + * @brief Get the micro-step resolution in stepper driver + * + * @param dev pointer to the device structure for the driver instance. + * @param res micro-step resolution + * + * @retval -EIO General input / output error + * @retval 0 Success + */ +__syscall int stepper_drv_get_micro_step_res(const struct device *dev, + enum stepper_drv_micro_step_resolution *res); + +static inline int z_impl_stepper_drv_get_micro_step_res(const struct device *dev, + enum stepper_drv_micro_step_resolution *res) +{ + __ASSERT_NO_MSG(dev != NULL); + __ASSERT_NO_MSG(res != NULL); + const struct stepper_drv_driver_api *api = (const struct stepper_drv_driver_api *)dev->api; + + return api->get_micro_step_res(dev, res); +} + +/** + * @brief Set the callback function to be called when a stepper_drv_event occurs + * + * @param dev pointer to the device structure for the driver instance. + * @param callback Callback function to be called when a stepper_drv_event occurs + * passing NULL will disable the callback + * @param user_data User data to be passed to the callback function + * + * @retval -ENOSYS If not implemented by device driver + * @retval 0 Success + */ +__syscall int stepper_drv_set_event_cb(const struct device *dev, stepper_drv_event_cb_t callback, + void *user_data); + +static inline int z_impl_stepper_drv_set_event_cb(const struct device *dev, + stepper_drv_event_cb_t cb, void *user_data) +{ + __ASSERT_NO_MSG(dev != NULL); + const struct stepper_drv_driver_api *api = (const struct stepper_drv_driver_api *)dev->api; + + if (api->set_event_cb == NULL) { + return -ENOSYS; + } + + return api->set_event_cb(dev, cb, user_data); +} + /** * @} */ diff --git a/include/zephyr/drivers/stepper/stepper_fake.h b/include/zephyr/drivers/stepper/stepper_fake.h index 0dad709dc61a..304066b75e73 100644 --- a/include/zephyr/drivers/stepper/stepper_fake.h +++ b/include/zephyr/drivers/stepper/stepper_fake.h @@ -14,19 +14,22 @@ extern "C" { #endif -DECLARE_FAKE_VALUE_FUNC(int, fake_stepper_enable, const struct device *); +DECLARE_FAKE_VALUE_FUNC(int, fake_stepper_drv_enable, const struct device *); -DECLARE_FAKE_VALUE_FUNC(int, fake_stepper_disable, const struct device *); +DECLARE_FAKE_VALUE_FUNC(int, fake_stepper_drv_disable, const struct device *); -DECLARE_FAKE_VALUE_FUNC(int, fake_stepper_move_by, const struct device *, int32_t); +DECLARE_FAKE_VALUE_FUNC(int, fake_stepper_drv_set_micro_step_res, const struct device *, + enum stepper_drv_micro_step_resolution); -DECLARE_FAKE_VALUE_FUNC(int, fake_stepper_set_microstep_interval, const struct device *, uint64_t); +DECLARE_FAKE_VALUE_FUNC(int, fake_stepper_drv_get_micro_step_res, const struct device *, + enum stepper_drv_micro_step_resolution *); -DECLARE_FAKE_VALUE_FUNC(int, fake_stepper_set_micro_step_res, const struct device *, - enum stepper_micro_step_resolution); +DECLARE_FAKE_VALUE_FUNC(int, fake_stepper_drv_set_event_cb, const struct device *, + stepper_drv_event_cb_t, void *); -DECLARE_FAKE_VALUE_FUNC(int, fake_stepper_get_micro_step_res, const struct device *, - enum stepper_micro_step_resolution *); +DECLARE_FAKE_VALUE_FUNC(int, fake_stepper_move_by, const struct device *, int32_t); + +DECLARE_FAKE_VALUE_FUNC(int, fake_stepper_set_microstep_interval, const struct device *, uint64_t); DECLARE_FAKE_VALUE_FUNC(int, fake_stepper_set_reference_position, const struct device *, int32_t); diff --git a/include/zephyr/drivers/stepper/stepper_trinamic.h b/include/zephyr/drivers/stepper/stepper_trinamic.h index 7a27ef8de9c8..963924b4aeac 100644 --- a/include/zephyr/drivers/stepper/stepper_trinamic.h +++ b/include/zephyr/drivers/stepper/stepper_trinamic.h @@ -217,7 +217,7 @@ int tmc50xx_stepper_set_ramp(const struct device *dev, /** * @brief Set the maximum velocity of the stepper motor * - * @param dev Pointer to the stepper motor controller instance + * @param dev Pointer to the stepper driver instance * @param velocity Maximum velocity in microsteps per second. * * @retval -EIO General input / output error @@ -225,6 +225,16 @@ int tmc50xx_stepper_set_ramp(const struct device *dev, */ int tmc50xx_stepper_set_max_velocity(const struct device *dev, uint32_t velocity); +/** + * @brief Set the maximum velocity of the stepper motor + * + * @param dev Pointer to the stepper driver instance + * @param velocity Maximum velocity in microsteps per second. + * + * @retval -EIO General input / output error + * @retval 0 Success + */ +int tmc51xx_stepper_set_max_velocity(const struct device *dev, uint32_t velocity); /** * @} */ diff --git a/samples/drivers/stepper/generic/boards/nucleo_g071rb.overlay b/samples/drivers/stepper/generic/boards/nucleo_g071rb.overlay index 9533bbb982e2..0617d501bb0b 100644 --- a/samples/drivers/stepper/generic/boards/nucleo_g071rb.overlay +++ b/samples/drivers/stepper/generic/boards/nucleo_g071rb.overlay @@ -1,18 +1,28 @@ +/* + * Copyright (c) 2025 Jilay Sandeep Pandya + * + * SPDX-License-Identifier: Apache-2.0 + */ + / { aliases { - stepper = &h_bridge_stepper; + stepper-drv = &tmc2209; + stepper = &step_dir_motion_control; }; -}; -/ { - h_bridge_stepper: h_bridge_stepper { - compatible = "zephyr,h-bridge-stepper"; - status = "okay"; - micro-step-res = <2>; + tmc2209: tmc2209 { + compatible = "adi,tmc2209"; en-gpios = <&gpioa 6 GPIO_ACTIVE_HIGH>; /* D12 */ - gpios = <&gpioa 9 GPIO_ACTIVE_HIGH>, /* D8 */ - <&gpioc 7 GPIO_ACTIVE_HIGH>, /* D9 */ - <&gpiob 0 GPIO_ACTIVE_HIGH>, /* D10 */ - <&gpioa 7 GPIO_ACTIVE_HIGH>; /* D11 */ + m0-gpios = <&gpiob 0 GPIO_ACTIVE_HIGH>; /* D10 */ + m1-gpios = <&gpioa 7 GPIO_ACTIVE_HIGH>; /* D11 */ + micro-step-res = <32>; + }; + + step_dir_motion_control: step_dir_motion_control { + compatible = "zephyr,gpio-step-dir-stepper"; + step-gpios = <&gpioa 9 GPIO_ACTIVE_HIGH>; /* D8 */ + dir-gpios = <&gpioc 7 GPIO_ACTIVE_HIGH>; /* D9 */ + invert-direction; + stepper-drv = <&tmc2209>; }; }; diff --git a/samples/drivers/stepper/generic/src/main.c b/samples/drivers/stepper/generic/src/main.c index c044b88376c8..fea05d0190e9 100644 --- a/samples/drivers/stepper/generic/src/main.c +++ b/samples/drivers/stepper/generic/src/main.c @@ -13,6 +13,7 @@ LOG_MODULE_REGISTER(stepper_generic, CONFIG_STEPPER_LOG_LEVEL); static const struct device *stepper = DEVICE_DT_GET(DT_ALIAS(stepper)); +static const struct device *stepper_drv = DEVICE_DT_GET(DT_ALIAS(stepper_drv)); enum stepper_mode { STEPPER_MODE_ENABLE, @@ -26,8 +27,8 @@ enum stepper_mode { static atomic_t stepper_mode = ATOMIC_INIT(STEPPER_MODE_DISABLE); -static int32_t ping_pong_target_position = - CONFIG_STEPS_PER_REV * CONFIG_PING_PONG_N_REV * DT_PROP(DT_ALIAS(stepper), micro_step_res); +static int32_t ping_pong_target_position = CONFIG_STEPS_PER_REV * CONFIG_PING_PONG_N_REV * + DT_PROP_OR(DT_ALIAS(stepper_drv), micro_step_res, 1); static K_SEM_DEFINE(stepper_generic_sem, 0, 1); @@ -79,7 +80,7 @@ int main(void) k_sem_take(&stepper_generic_sem, K_FOREVER); switch (atomic_get(&stepper_mode)) { case STEPPER_MODE_ENABLE: - stepper_enable(stepper); + stepper_drv_enable(stepper_drv); LOG_INF("mode: enable"); break; case STEPPER_MODE_PING_PONG_RELATIVE: @@ -105,7 +106,7 @@ int main(void) LOG_INF("mode: stop"); break; case STEPPER_MODE_DISABLE: - stepper_disable(stepper); + stepper_drv_disable(stepper_drv); LOG_INF("mode: disable"); break; default: diff --git a/samples/drivers/stepper/tmc50xx/boards/nucleo_g071rb.overlay b/samples/drivers/stepper/tmc50xx/boards/nucleo_g071rb.overlay index c1effb72d1bf..c0ee77b45890 100644 --- a/samples/drivers/stepper/tmc50xx/boards/nucleo_g071rb.overlay +++ b/samples/drivers/stepper/tmc50xx/boards/nucleo_g071rb.overlay @@ -1,6 +1,13 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2025 Dipak Shetty + * SPDX-FileCopyrightText: Copyright (c) 2024 Jilay Sandeep Pandya + * SPDX-License-Identifier: Apache-2.0 + */ + / { aliases { - stepper = &tmc_stepper; + stepper-drv = &tmc_stepper_driver; + stepper = &tmc_motion_controller; }; }; @@ -15,25 +22,21 @@ reg = <0>; spi-max-frequency = ; /* Maximum SPI bus frequency */ - #address-cells = <1>; - #size-cells = <0>; - clock-frequency = ; /* Internal/External Clock frequency */ - tmc_stepper: tmc_stepper@0 { - status = "okay"; - reg = <0>; - - /* common stepper controller settings */ + /* common stepper controller settings */ + tmc_stepper_driver: stepper_driver { micro-step-res = <256>; - + idx = <0>; + compatible = "adi,tmc50xx-stepper-drv"; /* ADI TMC stallguard settings specific to TMC50XX */ - activate-stallguard2; - stallguard-velocity-check-interval-ms = <1000>; stallguard2-threshold = <30>; - stallguard-threshold-velocity = <200000>; + }; - /* ADI TMC ramp generator as well as current settings */ + /* ADI TMC ramp generator as well as current settings */ + tmc_motion_controller: motion_controller { + compatible = "adi,tmc50xx-stepper"; + idx = <0>; vstart = <1000>; vstop = <10>; a1 = <10000>; @@ -48,6 +51,9 @@ ihold = <1>; irun = <10>; iholddelay = <1>; + activate-stallguard2; + stallguard-velocity-check-interval-ms = <1000>; + stallguard-threshold-velocity = <200000>; }; }; }; diff --git a/samples/drivers/stepper/tmc50xx/src/main.c b/samples/drivers/stepper/tmc50xx/src/main.c index 996e96af9b73..aa8a01b32b2f 100644 --- a/samples/drivers/stepper/tmc50xx/src/main.c +++ b/samples/drivers/stepper/tmc50xx/src/main.c @@ -12,15 +12,17 @@ #include LOG_MODULE_REGISTER(stepper_tmc50xx, CONFIG_STEPPER_LOG_LEVEL); -const struct device *stepper = DEVICE_DT_GET(DT_ALIAS(stepper)); +static const struct device *stepper = DEVICE_DT_GET(DT_ALIAS(stepper)); +static const struct device *stepper_drv = DEVICE_DT_GET(DT_ALIAS(stepper_drv)); int32_t ping_pong_target_position = CONFIG_STEPS_PER_REV * CONFIG_PING_PONG_N_REV * - DT_PROP(DT_ALIAS(stepper), micro_step_res); + DT_PROP(DT_ALIAS(stepper_drv), micro_step_res); K_SEM_DEFINE(steps_completed_sem, 0, 1); void stepper_callback(const struct device *dev, const enum stepper_event event, void *user_data) { + ARG_UNUSED(user_data); switch (event) { case STEPPER_EVENT_STEPS_COMPLETED: k_sem_give(&steps_completed_sem); @@ -40,18 +42,36 @@ int main(void) LOG_DBG("stepper is %p, name is %s", stepper, stepper->name); stepper_set_event_callback(stepper, stepper_callback, NULL); - stepper_enable(stepper); + stepper_drv_enable(stepper); + + enum stepper_drv_micro_step_resolution micro_step_res; + + stepper_drv_get_micro_step_res(stepper_drv, µ_step_res); + LOG_DBG("Microstep resolution is %d", micro_step_res); + stepper_set_reference_position(stepper, 0); stepper_move_by(stepper, ping_pong_target_position); /* Change Max Velocity during runtime */ - int32_t tmc_velocity = DT_PROP(DT_ALIAS(stepper), vmax) * CONFIG_MAX_VELOCITY_MULTIPLIER; + int32_t tmc_velocity; + + tmc_velocity = DT_PROP(DT_ALIAS(stepper), vmax) * CONFIG_MAX_VELOCITY_MULTIPLIER; (void)tmc50xx_stepper_set_max_velocity(stepper, tmc_velocity); for (;;) { if (k_sem_take(&steps_completed_sem, K_FOREVER) == 0) { ping_pong_target_position *= -1; stepper_move_by(stepper, ping_pong_target_position); + + int32_t actual_position; + int ret; + + ret = stepper_get_actual_position(stepper, &actual_position); + if (ret == 0) { + LOG_INF("Actual position: %d", actual_position); + } else { + LOG_ERR("Failed to get actual position"); + } } } return 0; diff --git a/tests/drivers/build_all/stepper/app.overlay b/tests/drivers/build_all/stepper/app.overlay index 177d15926bcd..f0ad20581cd6 100644 --- a/tests/drivers/build_all/stepper/app.overlay +++ b/tests/drivers/build_all/stepper/app.overlay @@ -39,5 +39,41 @@ #include "uart.dtsi" }; + + zephyr_gpio_step_dir_workq: zephyr_gpio_step_dir_workq { + compatible = "zephyr,gpio-step-dir-stepper"; + step-gpios = <&test_gpio 0 0>; + dir-gpios = <&test_gpio 0 0>; + stepper-drv = <&adi_tmc2209>; + }; + + zephyr_gpio_step_dir_counter: zephyr_gpio_step_dir_counter { + compatible = "zephyr,gpio-step-dir-stepper"; + step-gpios = <&test_gpio 0 0>; + dir-gpios = <&test_gpio 0 0>; + counter = <&counter0>; + stepper-drv = <&ti_drv84xx>; + }; + + zephyr_h_bridge_stepper_workq: zephyr_h_bridge_stepper_workq { + compatible = "zephyr,h-bridge-stepper"; + status = "okay"; + lut-step-gap = <1>; + gpios = <&test_gpio 0 0>, + <&test_gpio 0 0>, + <&test_gpio 0 0>, + <&test_gpio 0 0>; + }; + + zephyr_h_bridge_stepper_counter: zephyr_h_bridge_stepper_counter { + compatible = "zephyr,h-bridge-stepper"; + status = "okay"; + lut-step-gap = <1>; + counter = <&counter0>; + gpios = <&test_gpio 0 0>, + <&test_gpio 0 0>, + <&test_gpio 0 0>, + <&test_gpio 0 0>; + }; }; }; diff --git a/tests/drivers/build_all/stepper/gpio.dtsi b/tests/drivers/build_all/stepper/gpio.dtsi index 5e609502ea44..a247baef9a40 100644 --- a/tests/drivers/build_all/stepper/gpio.dtsi +++ b/tests/drivers/build_all/stepper/gpio.dtsi @@ -15,9 +15,7 @@ adi_tmc2209: adi_tmc2209 { m0-gpios = <&test_gpio 0 0>; m1-gpios = <&test_gpio 0 0>; en-gpios = <&test_gpio 0 0>; - step-gpios = <&test_gpio 0 0>; - dir-gpios = <&test_gpio 0 0>; - counter = <&counter0>; + dual-edge-step; }; allegro_a4979: allegro_a4979 { @@ -25,34 +23,16 @@ allegro_a4979: allegro_a4979 { compatible = "allegro,a4979"; micro-step-res = <1>; reset-gpios = <&test_gpio 0 0>; - dir-gpios = <&test_gpio 0 0>; - step-gpios = <&test_gpio 0 0>; en-gpios = <&test_gpio 0 0>; m0-gpios = <&test_gpio 0 0>; m1-gpios = <&test_gpio 0 0>; - counter = <&counter0>; }; ti_drv84xx: ti_drv84xx { status = "okay"; compatible = "ti,drv84xx"; - - dir-gpios = <&test_gpio 0 0>; - step-gpios = <&test_gpio 0 0>; sleep-gpios = <&test_gpio 0 0>; en-gpios = <&test_gpio 0 0>; m0-gpios = <&test_gpio 0 0>; m1-gpios = <&test_gpio 0 0>; - counter = <&counter0>; -}; - -zephyr_h_bridge_stepper: zephyr_h_bridge_stepper { - compatible = "zephyr,h-bridge-stepper"; - status = "okay"; - micro-step-res = <1>; - en-gpios = <&test_gpio 0 0>; - gpios = <&test_gpio 0 0>, - <&test_gpio 0 0>, - <&test_gpio 0 0>, - <&test_gpio 0 0>; }; diff --git a/tests/drivers/build_all/stepper/spi.dtsi b/tests/drivers/build_all/stepper/spi.dtsi index 400be1f84669..58146d87d4ce 100644 --- a/tests/drivers/build_all/stepper/spi.dtsi +++ b/tests/drivers/build_all/stepper/spi.dtsi @@ -2,11 +2,15 @@ * SPDX-FileCopyrightText: Copyright (c) 2024 Carl Zeiss Meditec AG * SPDX-License-Identifier: Apache-2.0 */ -/**************************************** + +/* + **************************************** * PLEASE KEEP REG ADDRESSES SEQUENTIAL * - ************************************** + **************************************** */ +#include + adi_tmc50xx: adi_tmc50xx@0 { compatible = "adi,tmc50xx"; status = "okay"; @@ -14,56 +18,56 @@ adi_tmc50xx: adi_tmc50xx@0 { spi-max-frequency = <8000000>; label = "tmc5041_0"; - #address-cells = <1>; - #size-cells = <0>; - poscmp-enable; test-mode; - lock-gconf; /* ADI TMC Global configuration flags */ + lock-gconf; clock-frequency = <16000000>; /* Internal/External Clock frequency */ - tmc50xx_0: tmc50xx_0@0 { - status = "okay"; - reg = <0>; - - /* common stepper controller settings */ - invert-direction; + tmc50xx_0_stepper_driver: tmc50xx_0_stepper_driver { + idx = <0>; + compatible = "adi,tmc50xx-stepper-drv"; micro-step-res = <256>; - /* ADI TMC stallguard settings specific to TMC50XX */ - activate-stallguard2; - stallguard-velocity-check-interval-ms = <100>; - stallguard2-threshold = <9>; - stallguard-threshold-velocity = <500000>; + stallguard2-threshold = <30>; + }; - /* ADI TMC ramp generator as well as current settings */ - vstart = <10>; - a1 = <20>; - v1 = <30>; - d1 = <40>; - vmax = <50>; - amax = <60>; - dmax = <70>; - tzerowait = <80>; - vhigh = <90>; - vcoolthrs = <100>; + /* ADI TMC ramp generator as well as current settings */ + tmc50xx_0_motion_controller: tmc50xx_0_motion_controller { + idx = <0>; + compatible = "adi,tmc50xx-stepper"; + vstart = <1000>; + vstop = <10>; + a1 = <10000>; + v1 = <50000>; + d1 = <14000>; + vmax = <900000>; + amax = <50000>; + dmax = <7000>; + tzerowait = <100>; + vhigh = <900000>; + vcoolthrs = <900000>; ihold = <1>; - irun = <2>; - iholddelay = <3>; + irun = <10>; + iholddelay = <1>; + activate-stallguard2; + stallguard-velocity-check-interval-ms = <1000>; + stallguard-threshold-velocity = <200000>; }; - tmc50xx_1: tmc50xx_1@1 { - status = "okay"; - reg = <1>; - - /* common stepper controller settings */ - invert-direction; + tmc50xx_1_stepper_driver: tmc50xx_1_stepper_driver { + idx = <1>; + compatible = "adi,tmc50xx-stepper-drv"; micro-step-res = <256>; + /* ADI TMC stallguard settings specific to TMC50XX */ + stallguard2-threshold = <9>; + }; + tmc50xx_1_motion_controller: tmc50xx_1_motion_controller { + idx = <1>; /* ADI TMC stallguard settings specific to TMC50XX */ + compatible = "adi,tmc50xx-stepper"; activate-stallguard2; stallguard-velocity-check-interval-ms = <100>; - stallguard2-threshold = <9>; stallguard-threshold-velocity = <500000>; /* ADI TMC ramp generator as well as current settings */ @@ -90,39 +94,44 @@ adi_tmc51xx_1: adi_tmc51xx@1 { spi-max-frequency = <8000000>; label = "tmc5160_1"; - #address-cells = <1>; - #size-cells = <0>; - en-pwm-mode; - test-mode; /* ADI TMC Global configuration flags */ + test-mode; + shaft; clock-frequency = <16000000>; /* Internal/External Clock frequency */ + tmc51xx_1_stepper_driver: tmc51xx_1_stepper_driver { + compatible = "adi,tmc51xx-stepper-drv"; + micro-step-res = <256>; + /* ADI TMC stallguard settings specific to TMC51XX */ + stallguard2-threshold = <9>; + }; + /* common stepper controller settings */ - invert-direction; - micro-step-res = <256>; + tmc51xx_1_motion_controller: tmc51xx_1_motion_controller { + compatible = "adi,tmc51xx-stepper"; - /* ADI TMC stallguard settings specific to TMC5160 */ - activate-stallguard2; - stallguard-velocity-check-interval-ms = <100>; - stallguard2-threshold = <9>; - stallguard-threshold-velocity = <50000>; + /* ADI TMC stallguard settings specific to TMC5160 */ + activate-stallguard2; + stallguard-velocity-check-interval-ms = <100>; + stallguard-threshold-velocity = <50000>; - /* ADI TMC ramp generator as well as current settings */ - vstart = <10>; - a1 = <20>; - v1 = <30>; - d1 = <40>; - vmax = <50>; - amax = <60>; - dmax = <70>; - tzerowait = <80>; - thigh = <90>; - tcoolthrs = <100>; - tpwmthrs = <110>; - tpowerdown = <120>; - ihold = <1>; - irun = <2>; - iholddelay = <3>; + /* ADI TMC ramp generator as well as current settings */ + vstart = <10>; + a1 = <20>; + v1 = <30>; + d1 = <40>; + vmax = <50>; + amax = <60>; + dmax = <70>; + tzerowait = <80>; + thigh = <90>; + tcoolthrs = <100>; + tpwmthrs = <110>; + tpowerdown = <120>; + ihold = <1>; + irun = <2>; + iholddelay = <3>; + }; }; adi_tmc51xx_2: adi_tmc51xx@2 { @@ -132,38 +141,44 @@ adi_tmc51xx_2: adi_tmc51xx@2 { spi-max-frequency = <8000000>; label = "tmc5160_2"; - #address-cells = <1>; - #size-cells = <0>; diag0-gpios = <&test_gpio 0x01 (GPIO_ACTIVE_HIGH | GPIO_PULL_UP)>; /* DIAG pin @0x01 */ en-pwm-mode; - test-mode; /* ADI TMC Global configuration flags */ + test-mode; + shaft; clock-frequency = <16000000>; /* Internal/External Clock frequency */ + tmc51xx_2_stepper_driver: tmc51xx_2_stepper_driver { + compatible = "adi,tmc51xx-stepper-drv"; + micro-step-res = <256>; + /* ADI TMC stallguard settings specific to TMC51XX */ + stallguard2-threshold = <9>; + }; + /* common stepper controller settings */ - invert-direction; - micro-step-res = <256>; + tmc51xx_2_motion_controller: tmc51xx_2_motion_controller { + compatible = "adi,tmc51xx-stepper"; - /* ADI TMC stallguard settings specific to TMC5160 */ - activate-stallguard2; - stallguard-velocity-check-interval-ms = <100>; - stallguard2-threshold = <9>; - stallguard-threshold-velocity = <50000>; + /* ADI TMC stallguard settings specific to TMC5160 */ + activate-stallguard2; + stallguard-velocity-check-interval-ms = <100>; + stallguard-threshold-velocity = <50000>; - /* ADI TMC ramp generator as well as current settings */ - vstart = <10>; - a1 = <20>; - v1 = <30>; - d1 = <40>; - vmax = <50>; - amax = <60>; - dmax = <70>; - tzerowait = <80>; - thigh = <90>; - tcoolthrs = <100>; - tpwmthrs = <110>; - tpowerdown = <120>; - ihold = <1>; - irun = <2>; - iholddelay = <3>; + /* ADI TMC ramp generator as well as current settings */ + vstart = <10>; + a1 = <20>; + v1 = <30>; + d1 = <40>; + vmax = <50>; + amax = <60>; + dmax = <70>; + tzerowait = <80>; + thigh = <90>; + tcoolthrs = <100>; + tpwmthrs = <110>; + tpowerdown = <120>; + ihold = <1>; + irun = <2>; + iholddelay = <3>; + }; }; diff --git a/tests/drivers/build_all/stepper/testcase.yaml b/tests/drivers/build_all/stepper/testcase.yaml index c6be5f3bac8a..12a9ba8507b8 100644 --- a/tests/drivers/build_all/stepper/testcase.yaml +++ b/tests/drivers/build_all/stepper/testcase.yaml @@ -8,4 +8,4 @@ tests: - stepper build_only: true platform_allow: - - native_sim + - native_sim/native/64 diff --git a/tests/drivers/build_all/stepper/uart.dtsi b/tests/drivers/build_all/stepper/uart.dtsi index 35480e08f61f..c228cc2a1aed 100644 --- a/tests/drivers/build_all/stepper/uart.dtsi +++ b/tests/drivers/build_all/stepper/uart.dtsi @@ -17,30 +17,37 @@ adi_tmc51xx_uart: adi_tmc51xx { test-mode; /* ADI TMC Global configuration flags */ clock-frequency = <16000000>; /* Internal/External Clock frequency */ + tmc51xx_stepper_driver: stepper_driver { + compatible = "adi,tmc51xx-stepper-drv"; + micro-step-res = <256>; + /* ADI TMC stallguard settings specific to TMC51XX */ + stallguard2-threshold = <9>; + }; + /* common stepper controller settings */ - invert-direction; - micro-step-res = <256>; + tmc51xx_motion_controller: motion_controller { + compatible = "adi,tmc51xx-stepper"; - /* ADI TMC stallguard settings specific to TMC5160 */ - activate-stallguard2; - stallguard-velocity-check-interval-ms = <100>; - stallguard2-threshold = <9>; - stallguard-threshold-velocity = <50000>; + /* ADI TMC stallguard settings specific to TMC5160 */ + activate-stallguard2; + stallguard-velocity-check-interval-ms = <100>; + stallguard-threshold-velocity = <50000>; - /* ADI TMC ramp generator as well as current settings */ - vstart = <10>; - a1 = <20>; - v1 = <30>; - d1 = <40>; - vmax = <50>; - amax = <60>; - dmax = <70>; - tzerowait = <80>; - thigh = <90>; - tcoolthrs = <100>; - tpwmthrs = <110>; - tpowerdown = <120>; - ihold = <1>; - irun = <2>; - iholddelay = <3>; + /* ADI TMC ramp generator as well as current settings */ + vstart = <10>; + a1 = <20>; + v1 = <30>; + d1 = <40>; + vmax = <50>; + amax = <60>; + dmax = <70>; + tzerowait = <80>; + thigh = <90>; + tcoolthrs = <100>; + tpwmthrs = <110>; + tpowerdown = <120>; + ihold = <1>; + irun = <2>; + iholddelay = <3>; + }; }; diff --git a/tests/drivers/stepper/shell/app.overlay b/tests/drivers/stepper/shell/app.overlay index f6c262f129ea..2d8506b37d86 100644 --- a/tests/drivers/stepper/shell/app.overlay +++ b/tests/drivers/stepper/shell/app.overlay @@ -5,7 +5,12 @@ */ / { - fake_stepper: fake_stepper { + fake_stepper_driver: fake_stepper_driver { + compatible = "zephyr,fake-stepper-drv"; + status = "okay"; + }; + + fake_stepper_controller: fake_stepper_controller { compatible = "zephyr,fake-stepper"; status = "okay"; }; diff --git a/tests/drivers/stepper/shell/src/main.c b/tests/drivers/stepper/shell/src/main.c index c4c9c5796272..7aa966d27600 100644 --- a/tests/drivers/stepper/shell/src/main.c +++ b/tests/drivers/stepper/shell/src/main.c @@ -14,18 +14,22 @@ #include #include -#define FAKE_STEPPER_NAME DEVICE_DT_NAME(DT_NODELABEL(fake_stepper)) +#define FAKE_STEPPER_CONTROLLER DEVICE_DT_NAME(DT_NODELABEL(fake_stepper_controller)) +#define FAKE_STEPPER_DRIVER DEVICE_DT_NAME(DT_NODELABEL(fake_stepper_driver)) /* Global variables */ -static const struct device *const fake_stepper_dev = DEVICE_DT_GET(DT_NODELABEL(fake_stepper)); +static const struct device *const fake_stepper_driver_dev = + DEVICE_DT_GET(DT_NODELABEL(fake_stepper_driver)); +static const struct device *const fake_stepper_controller_dev = + DEVICE_DT_GET(DT_NODELABEL(fake_stepper_controller)); DEFINE_FFF_GLOBALS; -#define ASSERT_STEPPER_FUNC_CALLED(stepper_fake_func, retval) \ +#define ASSERT_STEPPER_FUNC_CALLED(stepper_fake_func, stepper_fake_dev, retval) \ zassert_ok(retval, "failed to execute shell command (err %d)", retval); \ zassert_equal(stepper_fake_func.call_count, 1, \ STRINGIFY(stepper_fake_func) " function not called"); \ - zassert_equal(stepper_fake_func.arg0_val, fake_stepper_dev, "wrong device pointer") + zassert_equal(stepper_fake_func.arg0_val, stepper_fake_dev, "wrong device pointer") static void *stepper_shell_setup(void) { @@ -40,75 +44,81 @@ static void *stepper_shell_setup(void) ZTEST_SUITE(stepper_shell, NULL, stepper_shell_setup, NULL, NULL, NULL); -ZTEST(stepper_shell, test_stepper_enable) +ZTEST(stepper_shell, test_stepper_drv_enable) { const struct shell *sh = shell_backend_dummy_get_ptr(); - int err = shell_execute_cmd(sh, "stepper enable " FAKE_STEPPER_NAME); + int err = shell_execute_cmd(sh, "stepper enable " FAKE_STEPPER_DRIVER); - ASSERT_STEPPER_FUNC_CALLED(fake_stepper_enable_fake, err); + ASSERT_STEPPER_FUNC_CALLED(fake_stepper_drv_enable_fake, fake_stepper_driver_dev, err); zassert_equal(err, 0, "stepper enable could not be executed"); } -ZTEST(stepper_shell, test_stepper_disable) +ZTEST(stepper_shell, test_stepper_drv_disable) { const struct shell *sh = shell_backend_dummy_get_ptr(); - int err = shell_execute_cmd(sh, "stepper disable " FAKE_STEPPER_NAME); + int err = shell_execute_cmd(sh, "stepper disable " FAKE_STEPPER_DRIVER); - ASSERT_STEPPER_FUNC_CALLED(fake_stepper_disable_fake, err); + ASSERT_STEPPER_FUNC_CALLED(fake_stepper_drv_disable_fake, fake_stepper_driver_dev, err); zassert_equal(err, 0, "stepper disable could not be executed"); } ZTEST(stepper_shell, test_stepper_move_by) { const struct shell *sh = shell_backend_dummy_get_ptr(); - int err = shell_execute_cmd(sh, "stepper move_by " FAKE_STEPPER_NAME " 1000"); + int err = shell_execute_cmd(sh, "stepper move_by " FAKE_STEPPER_CONTROLLER " 1000"); - ASSERT_STEPPER_FUNC_CALLED(fake_stepper_move_by_fake, err); + ASSERT_STEPPER_FUNC_CALLED(fake_stepper_move_by_fake, fake_stepper_controller_dev, err); zassert_equal(fake_stepper_move_by_fake.arg1_val, 1000, "wrong microsteps value"); } ZTEST(stepper_shell, test_stepper_set_microstep_interval) { const struct shell *sh = shell_backend_dummy_get_ptr(); - int err = shell_execute_cmd(sh, "stepper set_microstep_interval " FAKE_STEPPER_NAME " 200"); + int err = shell_execute_cmd(sh, "stepper set_microstep_interval " FAKE_STEPPER_CONTROLLER + " 200"); - ASSERT_STEPPER_FUNC_CALLED(fake_stepper_set_microstep_interval_fake, err); + ASSERT_STEPPER_FUNC_CALLED(fake_stepper_set_microstep_interval_fake, + fake_stepper_controller_dev, err); zassert_equal(fake_stepper_set_microstep_interval_fake.arg1_val, 200, "wrong step_interval value"); } -ZTEST(stepper_shell, test_stepper_set_micro_step_res) +ZTEST(stepper_shell, test_stepper_drv_set_micro_step_res) { const struct shell *sh = shell_backend_dummy_get_ptr(); - int err = shell_execute_cmd(sh, "stepper set_micro_step_res " FAKE_STEPPER_NAME " 64"); + int err = shell_execute_cmd(sh, "stepper set_micro_step_res " FAKE_STEPPER_DRIVER " 64"); - ASSERT_STEPPER_FUNC_CALLED(fake_stepper_set_micro_step_res_fake, err); - zassert_equal(fake_stepper_set_micro_step_res_fake.arg1_val, 64, + ASSERT_STEPPER_FUNC_CALLED(fake_stepper_drv_set_micro_step_res_fake, + fake_stepper_driver_dev, err); + zassert_equal(fake_stepper_drv_set_micro_step_res_fake.arg1_val, 64, "wrong micro steps resolution value"); } -ZTEST(stepper_shell, test_stepper_set_micro_step_res_invalid_value) +ZTEST(stepper_shell, test_stepper_drv_set_micro_step_res_invalid_value) { const struct shell *sh = shell_backend_dummy_get_ptr(); - int err = shell_execute_cmd(sh, "stepper set_micro_step_res " FAKE_STEPPER_NAME " 111"); + int err = shell_execute_cmd(sh, "stepper set_micro_step_res " FAKE_STEPPER_DRIVER " 111"); zassert_not_equal(err, 0, " executed set_micro_step_res with invalid micro steps value"); } -ZTEST(stepper_shell, test_stepper_get_micro_step_res) +ZTEST(stepper_shell, test_stepper_drv_get_micro_step_res) { const struct shell *sh = shell_backend_dummy_get_ptr(); - int err = shell_execute_cmd(sh, "stepper get_micro_step_res " FAKE_STEPPER_NAME); + int err = shell_execute_cmd(sh, "stepper get_micro_step_res " FAKE_STEPPER_DRIVER); - ASSERT_STEPPER_FUNC_CALLED(fake_stepper_get_micro_step_res_fake, err); + ASSERT_STEPPER_FUNC_CALLED(fake_stepper_drv_get_micro_step_res_fake, + fake_stepper_driver_dev, err); } ZTEST(stepper_shell, test_stepper_set_reference_position) { const struct shell *sh = shell_backend_dummy_get_ptr(); - int err = shell_execute_cmd(sh, "stepper set_reference_position " FAKE_STEPPER_NAME " 100"); + int err = shell_execute_cmd(sh, "stepper set_reference_position " FAKE_STEPPER_CONTROLLER + " 100"); - ASSERT_STEPPER_FUNC_CALLED(fake_stepper_set_reference_position_fake, err); + ASSERT_STEPPER_FUNC_CALLED(fake_stepper_set_reference_position_fake, + fake_stepper_controller_dev, err); zassert_equal(fake_stepper_set_reference_position_fake.arg1_val, 100, "wrong actual position value"); } @@ -116,26 +126,27 @@ ZTEST(stepper_shell, test_stepper_set_reference_position) ZTEST(stepper_shell, test_stepper_get_actual_position) { const struct shell *sh = shell_backend_dummy_get_ptr(); - int err = shell_execute_cmd(sh, "stepper get_actual_position " FAKE_STEPPER_NAME); + int err = shell_execute_cmd(sh, "stepper get_actual_position " FAKE_STEPPER_CONTROLLER); - ASSERT_STEPPER_FUNC_CALLED(fake_stepper_get_actual_position_fake, err); + ASSERT_STEPPER_FUNC_CALLED(fake_stepper_get_actual_position_fake, + fake_stepper_controller_dev, err); } ZTEST(stepper_shell, test_stepper_move_to) { const struct shell *sh = shell_backend_dummy_get_ptr(); - int err = shell_execute_cmd(sh, "stepper move_to " FAKE_STEPPER_NAME " 200"); + int err = shell_execute_cmd(sh, "stepper move_to " FAKE_STEPPER_CONTROLLER " 200"); - ASSERT_STEPPER_FUNC_CALLED(fake_stepper_move_to_fake, err); + ASSERT_STEPPER_FUNC_CALLED(fake_stepper_move_to_fake, fake_stepper_controller_dev, err); zassert_equal(fake_stepper_move_to_fake.arg1_val, 200, "wrong target position value"); } ZTEST(stepper_shell, test_stepper_run) { const struct shell *sh = shell_backend_dummy_get_ptr(); - int err = shell_execute_cmd(sh, "stepper run " FAKE_STEPPER_NAME " positive"); + int err = shell_execute_cmd(sh, "stepper run " FAKE_STEPPER_CONTROLLER " positive"); - ASSERT_STEPPER_FUNC_CALLED(fake_stepper_run_fake, err); + ASSERT_STEPPER_FUNC_CALLED(fake_stepper_run_fake, fake_stepper_controller_dev, err); zassert_equal(fake_stepper_run_fake.arg1_val, STEPPER_DIRECTION_POSITIVE, "wrong direction value"); } @@ -143,7 +154,7 @@ ZTEST(stepper_shell, test_stepper_run) ZTEST(stepper_shell, test_stepper_run_invalid_direction) { const struct shell *sh = shell_backend_dummy_get_ptr(); - int err = shell_execute_cmd(sh, "stepper run " FAKE_STEPPER_NAME " foo"); + int err = shell_execute_cmd(sh, "stepper run " FAKE_STEPPER_CONTROLLER " foo"); zassert_not_equal(err, 0, " executed run with invalid direction value"); } @@ -151,22 +162,31 @@ ZTEST(stepper_shell, test_stepper_run_invalid_direction) ZTEST(stepper_shell, test_stepper_stop) { const struct shell *sh = shell_backend_dummy_get_ptr(); - int err = shell_execute_cmd(sh, "stepper stop " FAKE_STEPPER_NAME); + int err = shell_execute_cmd(sh, "stepper stop " FAKE_STEPPER_CONTROLLER); - ASSERT_STEPPER_FUNC_CALLED(fake_stepper_stop_fake, err); + ASSERT_STEPPER_FUNC_CALLED(fake_stepper_stop_fake, fake_stepper_controller_dev, err); zassert_equal(err, 0, "stepper stop could not be executed"); } -ZTEST(stepper_shell, test_stepper_info) +ZTEST(stepper_shell, test_stepper_controller_info) { const struct shell *sh = shell_backend_dummy_get_ptr(); - int err = shell_execute_cmd(sh, "stepper info " FAKE_STEPPER_NAME); + int err = shell_execute_cmd(sh, "stepper control_info " FAKE_STEPPER_CONTROLLER); zassert_ok(err, "failed to execute shell command (err %d)", err); zassert_equal(fake_stepper_is_moving_fake.call_count, 1, "is_moving function not called"); zassert_equal(fake_stepper_get_actual_position_fake.call_count, 1, "get_actual_position function not called"); - zassert_equal(fake_stepper_get_micro_step_res_fake.call_count, 1, +} + +ZTEST(stepper_shell, test_stepper_info) +{ + const struct shell *sh = shell_backend_dummy_get_ptr(); + int err = shell_execute_cmd(sh, "stepper info " FAKE_STEPPER_DRIVER); + + zassert_ok(err, "failed to execute shell command (err %d)", err); + + zassert_equal(fake_stepper_drv_get_micro_step_res_fake.call_count, 1, "get_micro_step_res function not called"); } diff --git a/tests/drivers/stepper/stepper_api/boards/native_sim_adi_tmc2209.overlay b/tests/drivers/stepper/stepper_api/boards/native_sim_adi_tmc2209.overlay deleted file mode 100644 index 00672366f701..000000000000 --- a/tests/drivers/stepper/stepper_api/boards/native_sim_adi_tmc2209.overlay +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2025 Jilay Sandeep Pandya - * SPDX-License-Identifier: Apache-2.0 - */ - -#include "native_sim.overlay" - -/ { - aliases { - stepper = &adi_tmc2209; - }; -}; - -/ { - adi_tmc2209: adi_tmc2209 { - status = "okay"; - compatible = "adi,tmc2209"; - micro-step-res = <32>; - dir-gpios = <&gpio1 0 0>; - step-gpios = <&gpio1 1 0>; - en-gpios = <&gpio2 1 0>; - m0-gpios = <&gpio3 0 0>; - m1-gpios = <&gpio4 1 0>; - counter = <&counter0>; - dual-edge-step; - }; -}; diff --git a/tests/drivers/stepper/stepper_api/boards/native_sim_adi_tmc2209_work_q.overlay b/tests/drivers/stepper/stepper_api/boards/native_sim_adi_tmc2209_work_q.overlay deleted file mode 100644 index e1486caeba03..000000000000 --- a/tests/drivers/stepper/stepper_api/boards/native_sim_adi_tmc2209_work_q.overlay +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2025 Josselin Bunt - * SPDX-License-Identifier: Apache-2.0 - */ - -#include "native_sim.overlay" - -/ { - aliases { - stepper = &adi_tmc2209; - }; -}; - -/ { - adi_tmc2209: adi_tmc2209 { - status = "okay"; - compatible = "adi,tmc2209"; - micro-step-res = <32>; - dir-gpios = <&gpio1 0 0>; - step-gpios = <&gpio1 1 0>; - en-gpios = <&gpio2 1 0>; - m0-gpios = <&gpio3 0 0>; - m1-gpios = <&gpio4 1 0>; - dual-edge-step; - }; -}; diff --git a/tests/drivers/stepper/stepper_api/boards/native_sim_allegro_a4979.overlay b/tests/drivers/stepper/stepper_api/boards/native_sim_allegro_a4979.overlay deleted file mode 100644 index 897d95933c8f..000000000000 --- a/tests/drivers/stepper/stepper_api/boards/native_sim_allegro_a4979.overlay +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2025 Jilay Sandeep Pandya - * SPDX-License-Identifier: Apache-2.0 - */ - -#include "native_sim.overlay" - -/ { - aliases { - stepper = &allegro_a4979; - }; -}; - -/ { - allegro_a4979: allegro_a4979 { - status = "okay"; - compatible = "allegro,a4979"; - micro-step-res = <1>; - reset-gpios = <&gpio4 0 0>; - dir-gpios = <&gpio1 0 0>; - step-gpios = <&gpio1 1 0>; - en-gpios = <&gpio2 1 0>; - m0-gpios = <&gpio3 0 0>; - m1-gpios = <&gpio3 1 0>; - counter = <&counter0>; - }; -}; diff --git a/tests/drivers/stepper/stepper_api/boards/native_sim_allegro_a4979_work_q.overlay b/tests/drivers/stepper/stepper_api/boards/native_sim_allegro_a4979_work_q.overlay deleted file mode 100644 index 85404efc18ac..000000000000 --- a/tests/drivers/stepper/stepper_api/boards/native_sim_allegro_a4979_work_q.overlay +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2025 Josselin Bunt - * SPDX-License-Identifier: Apache-2.0 - */ - -#include "native_sim.overlay" - -/ { - aliases { - stepper = &allegro_a4979; - }; -}; - -/ { - allegro_a4979: allegro_a4979 { - status = "okay"; - compatible = "allegro,a4979"; - micro-step-res = <1>; - reset-gpios = <&gpio4 0 0>; - dir-gpios = <&gpio1 0 0>; - step-gpios = <&gpio1 1 0>; - en-gpios = <&gpio2 1 0>; - m0-gpios = <&gpio3 0 0>; - m1-gpios = <&gpio3 1 0>; - }; -}; diff --git a/tests/drivers/stepper/stepper_api/boards/native_sim_gpio_step_dir.overlay b/tests/drivers/stepper/stepper_api/boards/native_sim_gpio_step_dir.overlay new file mode 100644 index 000000000000..41d9624d8770 --- /dev/null +++ b/tests/drivers/stepper/stepper_api/boards/native_sim_gpio_step_dir.overlay @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2025 Jilay Sandeep Pandya + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "native_sim.overlay" + +/ { + aliases { + stepper = &gpio_step_dir_controller; + }; + + gpio_step_dir_controller: gpio_step_dir_controller { + compatible = "zephyr,gpio-step-dir-stepper"; + step-gpios = <&gpio1 1 GPIO_ACTIVE_HIGH>; + dir-gpios = <&gpio2 0 GPIO_ACTIVE_HIGH>; + counter = <&counter0>; + }; +}; diff --git a/tests/drivers/stepper/stepper_api/boards/native_sim_gpio_step_dir_workq.overlay b/tests/drivers/stepper/stepper_api/boards/native_sim_gpio_step_dir_workq.overlay new file mode 100644 index 000000000000..9a3b38992860 --- /dev/null +++ b/tests/drivers/stepper/stepper_api/boards/native_sim_gpio_step_dir_workq.overlay @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2025 Jilay Sandeep Pandya + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "native_sim.overlay" + +/ { + aliases { + stepper = &gpio_step_dir_controller; + }; + + gpio_step_dir_controller: gpio_step_dir_controller { + compatible = "zephyr,gpio-step-dir-stepper"; + step-gpios = <&gpio1 1 GPIO_ACTIVE_HIGH>; + dir-gpios = <&gpio2 0 GPIO_ACTIVE_HIGH>; + }; +}; diff --git a/tests/drivers/stepper/stepper_api/boards/native_sim_h_bridge_stepper.overlay b/tests/drivers/stepper/stepper_api/boards/native_sim_h_bridge_stepper.overlay new file mode 100644 index 000000000000..c40f3dda7f67 --- /dev/null +++ b/tests/drivers/stepper/stepper_api/boards/native_sim_h_bridge_stepper.overlay @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2025 Jilay Sandeep Pandya + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "native_sim.overlay" + +/ { + aliases { + stepper = &h_bridge_stepper; + }; + + h_bridge_stepper: h_bridge_stepper { + compatible = "zephyr,h-bridge-stepper"; + status = "okay"; + lut-step-gap = <1>; + gpios = <&gpio1 0 GPIO_ACTIVE_HIGH>, + <&gpio2 0 GPIO_ACTIVE_HIGH>, + <&gpio3 0 GPIO_ACTIVE_HIGH>, + <&gpio4 0 GPIO_ACTIVE_HIGH>; + counter = <&counter0>; + }; +}; diff --git a/tests/drivers/stepper/stepper_api/boards/native_sim_h_bridge_stepper_workq.overlay b/tests/drivers/stepper/stepper_api/boards/native_sim_h_bridge_stepper_workq.overlay new file mode 100644 index 000000000000..9c589039dba6 --- /dev/null +++ b/tests/drivers/stepper/stepper_api/boards/native_sim_h_bridge_stepper_workq.overlay @@ -0,0 +1,22 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2024 Jilay Sandeep Pandya + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "native_sim.overlay" + +/ { + aliases { + stepper = &h_bridge_stepper; + }; + + h_bridge_stepper: h_bridge_stepper { + compatible = "zephyr,h-bridge-stepper"; + status = "okay"; + lut-step-gap = <1>; + gpios = <&gpio1 0 GPIO_ACTIVE_HIGH>, + <&gpio2 0 GPIO_ACTIVE_HIGH>, + <&gpio3 0 GPIO_ACTIVE_HIGH>, + <&gpio4 0 GPIO_ACTIVE_HIGH>; + }; +}; diff --git a/tests/drivers/stepper/stepper_api/boards/native_sim_ti_drv84xx.overlay b/tests/drivers/stepper/stepper_api/boards/native_sim_ti_drv84xx.overlay deleted file mode 100644 index 22b09bc1edf5..000000000000 --- a/tests/drivers/stepper/stepper_api/boards/native_sim_ti_drv84xx.overlay +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2025 Jilay Sandeep Pandya - * SPDX-License-Identifier: Apache-2.0 - */ - -#include "native_sim.overlay" - -/ { - aliases { - stepper = &ti_drv84xx; - }; -}; - -/ { - ti_drv84xx: ti_drv84xx { - status = "okay"; - compatible = "ti,drv84xx"; - micro-step-res = <8>; - dir-gpios = <&gpio1 0 0>; - step-gpios = <&gpio1 1 0>; - sleep-gpios = <&gpio2 0 GPIO_ACTIVE_LOW>; - en-gpios = <&gpio2 1 0>; - m0-gpios = <&gpio3 0 0>; - m1-gpios = <&gpio3 1 0>; - counter = <&counter0>; - }; -}; diff --git a/tests/drivers/stepper/stepper_api/boards/native_sim_ti_drv84xx_work_q.overlay b/tests/drivers/stepper/stepper_api/boards/native_sim_ti_drv84xx_work_q.overlay deleted file mode 100644 index b9545a12739a..000000000000 --- a/tests/drivers/stepper/stepper_api/boards/native_sim_ti_drv84xx_work_q.overlay +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2025 Josselin Bunt - * SPDX-License-Identifier: Apache-2.0 - */ - -#include "native_sim.overlay" - -/ { - aliases { - stepper = &ti_drv84xx; - }; -}; - -/ { - ti_drv84xx: ti_drv84xx { - status = "okay"; - compatible = "ti,drv84xx"; - micro-step-res = <8>; - dir-gpios = <&gpio1 0 0>; - step-gpios = <&gpio1 1 0>; - sleep-gpios = <&gpio2 0 GPIO_ACTIVE_LOW>; - en-gpios = <&gpio2 1 0>; - m0-gpios = <&gpio3 0 0>; - m1-gpios = <&gpio3 1 0>; - }; -}; diff --git a/tests/drivers/stepper/stepper_api/boards/native_sim_zephyr_h_bridge_stepper.overlay b/tests/drivers/stepper/stepper_api/boards/native_sim_zephyr_h_bridge_stepper.overlay deleted file mode 100644 index 11bfb3d56024..000000000000 --- a/tests/drivers/stepper/stepper_api/boards/native_sim_zephyr_h_bridge_stepper.overlay +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2025 Jilay Sandeep Pandya - * SPDX-License-Identifier: Apache-2.0 - */ - -#include "native_sim.overlay" - -/ { - aliases { - stepper = &zephyr_h_bridge_stepper; - }; -}; - -/ { - zephyr_h_bridge_stepper: zephyr_h_bridge_stepper { - compatible = "zephyr,h-bridge-stepper"; - status = "okay"; - micro-step-res = <1>; - en-gpios = <&gpio1 0 0>; - gpios = <&gpio1 0 0>, - <&gpio2 0 0>, - <&gpio3 0 0>, - <&gpio4 0 0>; - }; -}; diff --git a/tests/drivers/stepper/stepper_api/boards/qemu_x86_64_zephyr_h_bridge_stepper.overlay b/tests/drivers/stepper/stepper_api/boards/qemu_x86_64_zephyr_h_bridge_stepper.overlay deleted file mode 100644 index e11ea8dddc30..000000000000 --- a/tests/drivers/stepper/stepper_api/boards/qemu_x86_64_zephyr_h_bridge_stepper.overlay +++ /dev/null @@ -1,54 +0,0 @@ -/* - * SPDX-FileCopyrightText: Copyright (c) 2024 Jilay Sandeep Pandya - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -/ { - aliases { - stepper = &zephyr_h_bridge_stepper; - }; -}; - -/ { - gpio1: gpio1 { - compatible = "zephyr,gpio-emul"; - #gpio-cells = <0x2>; - status = "okay"; - gpio-controller; - }; - - gpio2: gpio2 { - compatible = "zephyr,gpio-emul"; - #gpio-cells = <0x2>; - status = "okay"; - gpio-controller; - }; - - gpio3: gpio3 { - compatible = "zephyr,gpio-emul"; - #gpio-cells = <0x2>; - status = "okay"; - gpio-controller; - }; - - gpio4: gpio4 { - compatible = "zephyr,gpio-emul"; - #gpio-cells = <0x2>; - status = "okay"; - gpio-controller; - }; -}; - -/ { - zephyr_h_bridge_stepper: zephyr_h_bridge_stepper { - compatible = "zephyr,h-bridge-stepper"; - status = "okay"; - micro-step-res = <2>; - gpios = <&gpio1 0 0>, - <&gpio2 0 0>, - <&gpio3 0 0>, - <&gpio4 0 0>; - }; -}; diff --git a/tests/drivers/stepper/stepper_api/src/main.c b/tests/drivers/stepper/stepper_api/src/main.c index 826f0876ef53..55edbb18feec 100644 --- a/tests/drivers/stepper/stepper_api/src/main.c +++ b/tests/drivers/stepper/stepper_api/src/main.c @@ -46,9 +46,6 @@ static void stepper_print_event_callback(const struct device *dev, enum stepper_ case STEPPER_EVENT_RIGHT_END_STOP_DETECTED: k_poll_signal_raise(&stepper_signal, STEPPER_EVENT_RIGHT_END_STOP_DETECTED); break; - case STEPPER_EVENT_STALL_DETECTED: - k_poll_signal_raise(&stepper_signal, STEPPER_EVENT_STALL_DETECTED); - break; case STEPPER_EVENT_STOPPED: k_poll_signal_raise(&stepper_signal, STEPPER_EVENT_STOPPED); break; @@ -75,7 +72,6 @@ static void *stepper_setup(void) zassert_equal( stepper_set_event_callback(fixture.dev, fixture.callback, (void *)fixture.dev), 0, "Failed to set event callback"); - (void)stepper_enable(fixture.dev); return &fixture; } @@ -91,21 +87,6 @@ static void stepper_before(void *f) ZTEST_SUITE(stepper, NULL, stepper_setup, stepper_before, NULL, NULL); -ZTEST_F(stepper, test_set_micro_step_res_invalid) -{ - int ret = stepper_set_micro_step_res(fixture->dev, 127); - - zassert_equal(ret, -EINVAL, "Invalid micro step resolution should return -EINVAL"); -} - -ZTEST_F(stepper, test_get_micro_step_res) -{ - enum stepper_micro_step_resolution res; - (void)stepper_get_micro_step_res(fixture->dev, &res); - zassert_equal(res, DT_PROP(DT_ALIAS(stepper), micro_step_res), - "Micro step resolution not set correctly"); -} - ZTEST_F(stepper, test_set_micro_step_interval_invalid_zero) { int err = stepper_set_microstep_interval(fixture->dev, 0); diff --git a/tests/drivers/stepper/stepper_api/testcase.yaml b/tests/drivers/stepper/stepper_api/testcase.yaml index ceae1261d50e..fe6e7ade434b 100644 --- a/tests/drivers/stepper/stepper_api/testcase.yaml +++ b/tests/drivers/stepper/stepper_api/testcase.yaml @@ -7,66 +7,37 @@ common: - stepper - api tests: - drivers.stepper.stepper_api.adi_tmc2209: + drivers.stepper.stepper_api.gpio_step_dir: extra_args: - - platform:native_sim/native/64:DTC_OVERLAY_FILE="boards/native_sim_adi_tmc2209.overlay" + - platform:native_sim/native/64:DTC_OVERLAY_FILE="boards/native_sim_gpio_step_dir.overlay" extra_configs: - CONFIG_GPIO=y - CONFIG_COUNTER=y - - CONFIG_STEPPER_STEP_DIR_GENERATE_ISR_SAFE_EVENTS=y + - CONFIG_STEPPER_GPIO_STEPPER_GENERATE_ISR_SAFE_EVENTS=y platform_allow: - native_sim/native/64 - drivers.stepper.stepper_api.adi_tmc2209_work_q: + drivers.stepper.stepper_api.gpio_step_dir_work_q: extra_args: - - platform:native_sim/native/64:DTC_OVERLAY_FILE="boards/native_sim_adi_tmc2209_work_q.overlay" + - platform:native_sim/native/64:DTC_OVERLAY_FILE="boards/native_sim_gpio_step_dir_workq.overlay" extra_configs: - CONFIG_GPIO=y - - CONFIG_STEPPER_STEP_DIR_GENERATE_ISR_SAFE_EVENTS=y - CONFIG_STEPPER_TEST_TIMING_TIMEOUT_TOLERANCE_PCT=130 platform_allow: - native_sim/native/64 - drivers.stepper.stepper_api.allegro_a4979: + drivers.stepper.stepper_api.h_bridge_stepper: extra_args: - - platform:native_sim/native/64:DTC_OVERLAY_FILE="boards/native_sim_allegro_a4979.overlay" + - platform:native_sim/native/64:DTC_OVERLAY_FILE="boards/native_sim_h_bridge_stepper.overlay" extra_configs: - CONFIG_GPIO=y - CONFIG_COUNTER=y - - CONFIG_STEPPER_STEP_DIR_GENERATE_ISR_SAFE_EVENTS=y + - CONFIG_STEPPER_GPIO_STEPPER_GENERATE_ISR_SAFE_EVENTS=y platform_allow: - native_sim/native/64 - drivers.stepper.stepper_api.allegro_a4979_work_q: + drivers.stepper.stepper_api.h_bridge_stepper_work_q: extra_args: - - platform:native_sim/native/64:DTC_OVERLAY_FILE="boards/native_sim_allegro_a4979_work_q.overlay" + - platform:native_sim/native/64:DTC_OVERLAY_FILE="boards/native_sim_h_bridge_stepper_workq.overlay" extra_configs: - CONFIG_GPIO=y - - CONFIG_STEPPER_STEP_DIR_GENERATE_ISR_SAFE_EVENTS=y - CONFIG_STEPPER_TEST_TIMING_TIMEOUT_TOLERANCE_PCT=130 platform_allow: - native_sim/native/64 - drivers.stepper.stepper_api.ti_drv84xx: - extra_args: - - platform:native_sim/native/64:DTC_OVERLAY_FILE="boards/native_sim_ti_drv84xx.overlay" - extra_configs: - - CONFIG_GPIO=y - - CONFIG_COUNTER=y - - CONFIG_STEPPER_STEP_DIR_GENERATE_ISR_SAFE_EVENTS=y - platform_allow: - - native_sim/native/64 - drivers.stepper.stepper_api.ti_drv84xx_work_q: - extra_args: - - platform:native_sim/native/64:DTC_OVERLAY_FILE="boards/native_sim_ti_drv84xx_work_q.overlay" - extra_configs: - - CONFIG_GPIO=y - - CONFIG_STEPPER_STEP_DIR_GENERATE_ISR_SAFE_EVENTS=y - - CONFIG_STEPPER_TEST_TIMING_TIMEOUT_TOLERANCE_PCT=130 - platform_allow: - - native_sim/native/64 - drivers.stepper.stepper_api.zephyr_gpio_stepper: - extra_args: - - platform:native_sim/native/64:DTC_OVERLAY_FILE="boards/native_sim_zephyr_h_bridge_stepper.overlay" - - platform:qemu_x86_64/atom:DTC_OVERLAY_FILE="boards/qemu_x86_64_zephyr_h_bridge_stepper.overlay" - extra_configs: - - CONFIG_GPIO=y - platform_allow: - - native_sim/native/64 - - qemu_x86_64/atom diff --git a/tests/drivers/stepper/step_dir/CMakeLists.txt b/tests/drivers/stepper/stepper_drv/CMakeLists.txt similarity index 100% rename from tests/drivers/stepper/step_dir/CMakeLists.txt rename to tests/drivers/stepper/stepper_drv/CMakeLists.txt diff --git a/tests/drivers/stepper/step_dir/Kconfig b/tests/drivers/stepper/stepper_drv/Kconfig similarity index 84% rename from tests/drivers/stepper/step_dir/Kconfig rename to tests/drivers/stepper/stepper_drv/Kconfig index c194e58c9b10..08ac1cbb9b50 100644 --- a/tests/drivers/stepper/step_dir/Kconfig +++ b/tests/drivers/stepper/stepper_drv/Kconfig @@ -7,10 +7,10 @@ config ENTROPY_GENERATOR default y config MICRO_STEP_RESOLUTION - int "Microstep resolution for step-dir driver tests" + int "Microstep resolution for stepper_drv driver tests" help Set the microstep resolution (number of microsteps per full step) - for the step-dir driver tests. + for the stepper_drv driver tests. config MICRO_STEP_RESOLUTION_M0 int "Set Value for pin M0 for the given microstep resolution" diff --git a/tests/drivers/stepper/step_dir/boards/native_sim.overlay b/tests/drivers/stepper/stepper_drv/boards/native_sim.overlay similarity index 100% rename from tests/drivers/stepper/step_dir/boards/native_sim.overlay rename to tests/drivers/stepper/stepper_drv/boards/native_sim.overlay diff --git a/tests/drivers/stepper/step_dir/boards/native_sim_adi_tmc2209.overlay b/tests/drivers/stepper/stepper_drv/boards/native_sim_adi_tmc2209.overlay similarity index 73% rename from tests/drivers/stepper/step_dir/boards/native_sim_adi_tmc2209.overlay rename to tests/drivers/stepper/stepper_drv/boards/native_sim_adi_tmc2209.overlay index 1f4e5a33e945..d17430e2a850 100644 --- a/tests/drivers/stepper/step_dir/boards/native_sim_adi_tmc2209.overlay +++ b/tests/drivers/stepper/stepper_drv/boards/native_sim_adi_tmc2209.overlay @@ -8,19 +8,15 @@ / { aliases { - step-dir-driver = &adi_tmc2209; + stepper-drv = &adi_tmc2209; }; adi_tmc2209: adi_tmc2209 { status = "okay"; compatible = "adi,tmc2209"; micro-step-res = <32>; - dir-gpios = <&gpio1 0 0>; - step-gpios = <&gpio1 1 0>; en-gpios = <&gpio2 1 0>; m0-gpios = <&gpio3 0 0>; m1-gpios = <&gpio4 1 0>; - counter = <&counter0>; - dual-edge-step; }; }; diff --git a/tests/drivers/stepper/step_dir/boards/native_sim_allegro_a4979.overlay b/tests/drivers/stepper/stepper_drv/boards/native_sim_allegro_a4979.overlay similarity index 77% rename from tests/drivers/stepper/step_dir/boards/native_sim_allegro_a4979.overlay rename to tests/drivers/stepper/stepper_drv/boards/native_sim_allegro_a4979.overlay index 66c863345169..da7a6187bb63 100644 --- a/tests/drivers/stepper/step_dir/boards/native_sim_allegro_a4979.overlay +++ b/tests/drivers/stepper/stepper_drv/boards/native_sim_allegro_a4979.overlay @@ -8,7 +8,7 @@ / { aliases { - step-dir-driver = &allegro_a4979; + stepper-drv = &allegro_a4979; }; allegro_a4979: allegro_a4979 { @@ -16,11 +16,8 @@ compatible = "allegro,a4979"; micro-step-res = <1>; reset-gpios = <&gpio4 0 0>; - dir-gpios = <&gpio1 0 0>; - step-gpios = <&gpio1 1 0>; en-gpios = <&gpio2 1 0>; m0-gpios = <&gpio3 0 0>; m1-gpios = <&gpio3 1 0>; - counter = <&counter0>; }; }; diff --git a/tests/drivers/stepper/step_dir/boards/native_sim_ti_drv84xx.overlay b/tests/drivers/stepper/stepper_drv/boards/native_sim_ti_drv84xx.overlay similarity index 77% rename from tests/drivers/stepper/step_dir/boards/native_sim_ti_drv84xx.overlay rename to tests/drivers/stepper/stepper_drv/boards/native_sim_ti_drv84xx.overlay index 8bc1aa96793f..9c58153dc245 100644 --- a/tests/drivers/stepper/step_dir/boards/native_sim_ti_drv84xx.overlay +++ b/tests/drivers/stepper/stepper_drv/boards/native_sim_ti_drv84xx.overlay @@ -8,19 +8,15 @@ / { aliases { - step-dir-driver = &ti_drv84xx; + stepper-drv = &ti_drv84xx; }; ti_drv84xx: ti_drv84xx { status = "okay"; compatible = "ti,drv84xx"; - - dir-gpios = <&gpio1 0 0>; - step-gpios = <&gpio1 1 0>; sleep-gpios = <&gpio2 0 GPIO_ACTIVE_LOW>; en-gpios = <&gpio2 1 0>; m0-gpios = <&gpio3 0 0>; m1-gpios = <&gpio4 1 0>; - counter = <&counter0>; }; }; diff --git a/tests/drivers/stepper/step_dir/prj.conf b/tests/drivers/stepper/stepper_drv/prj.conf similarity index 100% rename from tests/drivers/stepper/step_dir/prj.conf rename to tests/drivers/stepper/stepper_drv/prj.conf diff --git a/tests/drivers/stepper/step_dir/src/main.c b/tests/drivers/stepper/stepper_drv/src/main.c similarity index 61% rename from tests/drivers/stepper/step_dir/src/main.c rename to tests/drivers/stepper/stepper_drv/src/main.c index f9200bf12dbf..9ea7fd4781be 100644 --- a/tests/drivers/stepper/step_dir/src/main.c +++ b/tests/drivers/stepper/stepper_drv/src/main.c @@ -13,31 +13,31 @@ #include #include -struct step_dir_fixture { +struct stepper_drv_fixture { const struct device *dev; }; -struct gpio_dt_spec en_pin = GPIO_DT_SPEC_GET_OR(DT_ALIAS(step_dir_driver), en_gpios, {0}); -struct gpio_dt_spec slp_pin = GPIO_DT_SPEC_GET_OR(DT_ALIAS(step_dir_driver), sleep_gpios, {0}); -struct gpio_dt_spec m0_pin = GPIO_DT_SPEC_GET_OR(DT_ALIAS(step_dir_driver), m0_gpios, {0}); -struct gpio_dt_spec m1_pin = GPIO_DT_SPEC_GET_OR(DT_ALIAS(step_dir_driver), m1_gpios, {0}); +struct gpio_dt_spec en_pin = GPIO_DT_SPEC_GET_OR(DT_ALIAS(stepper_drv), en_gpios, {0}); +struct gpio_dt_spec slp_pin = GPIO_DT_SPEC_GET_OR(DT_ALIAS(stepper_drv), sleep_gpios, {0}); +struct gpio_dt_spec m0_pin = GPIO_DT_SPEC_GET_OR(DT_ALIAS(stepper_drv), m0_gpios, {0}); +struct gpio_dt_spec m1_pin = GPIO_DT_SPEC_GET_OR(DT_ALIAS(stepper_drv), m1_gpios, {0}); -static void *step_dir_setup(void) +static void *stepper_drv_setup(void) { - static struct step_dir_fixture fixture = { - .dev = DEVICE_DT_GET(DT_ALIAS(step_dir_driver)), + static struct stepper_drv_fixture fixture = { + .dev = DEVICE_DT_GET(DT_ALIAS(stepper_drv)), }; zassert_not_null(fixture.dev); return &fixture; } -ZTEST_F(step_dir, test_enable_gpio_pins) +ZTEST_F(stepper_drv, test_enable_gpio_pins) { int value = 0; int err; - err = stepper_enable(fixture->dev); + err = stepper_drv_enable(fixture->dev); if (err == -ENOTSUP) { ztest_test_skip(); } @@ -52,7 +52,7 @@ ZTEST_F(step_dir, test_enable_gpio_pins) } /* As enable is supported, disable must also be supported */ - zassert_ok(stepper_disable(fixture->dev)); + zassert_ok(stepper_drv_disable(fixture->dev)); if (en_pin.port != NULL) { value = gpio_emul_output_get(en_pin.port, en_pin.pin); @@ -64,12 +64,12 @@ ZTEST_F(step_dir, test_enable_gpio_pins) } } -ZTEST_F(step_dir, test_micro_step_res_set) +ZTEST_F(stepper_drv, test_micro_step_res_set) { - enum stepper_micro_step_resolution res; + enum stepper_drv_micro_step_resolution res; int value = 0; - zassert_ok(stepper_set_micro_step_res(fixture->dev, CONFIG_MICRO_STEP_RESOLUTION)); + zassert_ok(stepper_drv_set_micro_step_res(fixture->dev, CONFIG_MICRO_STEP_RESOLUTION)); if (m0_pin.port == NULL || m1_pin.port == NULL) { ztest_test_skip(); @@ -83,10 +83,17 @@ ZTEST_F(step_dir, test_micro_step_res_set) zassert_equal(value, CONFIG_MICRO_STEP_RESOLUTION_M1, "M1 pin should be 1", CONFIG_MICRO_STEP_RESOLUTION_M1); - zassert_ok(stepper_get_micro_step_res(fixture->dev, &res)); + zassert_ok(stepper_drv_get_micro_step_res(fixture->dev, &res)); zassert_equal(res, CONFIG_MICRO_STEP_RESOLUTION, "Micro step resolution not set correctly, should be %d but is %d", CONFIG_MICRO_STEP_RESOLUTION, res); } -ZTEST_SUITE(step_dir, NULL, step_dir_setup, NULL, NULL, NULL); +ZTEST_F(stepper_drv, test_set_micro_step_res_invalid) +{ + int ret = stepper_drv_set_micro_step_res(fixture->dev, 127); + + zassert_equal(ret, -EINVAL, "Invalid micro step resolution should return -EINVAL"); +} + +ZTEST_SUITE(stepper_drv, NULL, stepper_drv_setup, NULL, NULL, NULL); diff --git a/tests/drivers/stepper/step_dir/testcase.yaml b/tests/drivers/stepper/stepper_drv/testcase.yaml similarity index 87% rename from tests/drivers/stepper/step_dir/testcase.yaml rename to tests/drivers/stepper/stepper_drv/testcase.yaml index b339d382437c..4d878e1f1077 100644 --- a/tests/drivers/stepper/step_dir/testcase.yaml +++ b/tests/drivers/stepper/stepper_drv/testcase.yaml @@ -5,10 +5,10 @@ common: tags: - drivers - stepper - - step_dir + - stepper_drv tests: - drivers.stepper.step_dir.adi_tmc2209: + drivers.stepper.stepper_drv.adi_tmc2209: extra_args: - platform:native_sim/native/64:DTC_OVERLAY_FILE="boards/native_sim_adi_tmc2209.overlay" extra_configs: @@ -17,7 +17,7 @@ tests: - CONFIG_MICRO_STEP_RESOLUTION_M1=1 platform_allow: - native_sim/native/64 - drivers.stepper.step_dir.allegro_a4979: + drivers.stepper.stepper_drv.allegro_a4979: extra_args: - platform:native_sim/native/64:DTC_OVERLAY_FILE="boards/native_sim_allegro_a4979.overlay" extra_configs: @@ -26,7 +26,7 @@ tests: - CONFIG_MICRO_STEP_RESOLUTION_M1=1 platform_allow: - native_sim/native/64 - drivers.stepper.step_dir.drv84xx: + drivers.stepper.stepper_drv.drv84xx: extra_args: - platform:native_sim/native/64:DTC_OVERLAY_FILE="boards/native_sim_ti_drv84xx.overlay" extra_configs: From aa2a0fbc8ae3fa130a9d1897dd2961c68fa132da Mon Sep 17 00:00:00 2001 From: Jilay Pandya Date: Tue, 9 Dec 2025 19:39:32 +0100 Subject: [PATCH 0216/3659] doc: migration_guide: address stepper split add entry for splitting stepper api in migration-guide-4.4 Signed-off-by: Jilay Pandya --- doc/releases/migration-guide-4.4.rst | 38 ++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/doc/releases/migration-guide-4.4.rst b/doc/releases/migration-guide-4.4.rst index 37c27abf0b95..670fee39a15d 100644 --- a/doc/releases/migration-guide-4.4.rst +++ b/doc/releases/migration-guide-4.4.rst @@ -157,6 +157,44 @@ Stepper * For :dtcompatible:`adi,tmc2209`, the property ``msx-gpios`` is now replaced by ``m0-gpios`` and ``m1-gpios`` for consistency with other step/dir stepper drivers. +* Since :github:`91979`, All stepper-drv driver APIs have been refactored out of the stepper API. + The following APIs have been moved from :c:group:`stepper_interface` to :c:group:`stepper_drv_interface`: + + * :c:func:`stepper_enable` is replaced by :c:func:`stepper_drv_enable`. + * :c:func:`stepper_disable` is replaced by :c:func:`stepper_drv_disable`. + * :c:func:`stepper_set_micro_step_res` is replaced by :c:func:`stepper_drv_set_micro_step_res`. + * :c:func:`stepper_get_micro_step_res` is replaced by :c:func:`stepper_drv_get_micro_step_res`. + +* :c:enum:`stepper_micro_step_resolution` is replaced by :c:enum:`stepper_drv_micro_step_resolution`. +* ``STEPPER_DRV_EVENT_STALL_DETECTED`` and ``STEPPER_DRV_EVENT_FAULT_DETECTED`` events have been + refactored to :c:enum:`stepper_drv_event`. + +* :dtcompatible:`zephyr,gpio-step-dir-stepper` implements :c:group:`stepper_interface` for + controlling stepper motors via GPIO step and direction signals. Refer to + :ref:`stepper-individual-controller-driver` for more details. + + * ``step-gpios``, ``dir-gpios``, ``invert-direction`` and ``counter`` properties are removed + from :dtcompatible:`adi,tmc2209`, :dtcompatible:`ti,drv84xx` and :dtcompatible:`allegro,a4979`, + these are now are implemented by :dtcompatible:`zephyr,gpio-step-dir-stepper`. + * :c:func:`stepper_move_by`, :c:func:`stepper_move_to`, :c:func:`stepper_run`, + :c:func:`stepper_stop`, :c:func:`stepper_is_moving`, :c:func:`stepper_set_microstep_interval` + and :c:func:`stepper_set_event_callback` APIs are removed from :dtcompatible:`adi,tmc2209`, + :dtcompatible:`ti,drv84xx` and :dtcompatible:`allegro,a4979`. + * :dtcompatible:`adi,tmc2209`, :dtcompatible:`ti,drv84xx` and :dtcompatible:`allegro,a4979` + implement :c:group:`stepper_drv_interface`. + +* :c:func:`stepper_enable`, :c:func:`stepper_disable`, :c:func:`stepper_set_micro_step_res` and + :c:func:`stepper_get_micro_step_res` APIs are removed from :dtcompatible:`zephyr,h-bridge-stepper`. +* ``en-gpios`` property is removed from :dtcompatible:`zephyr,h-bridge-stepper`. +* ``micro-step-res`` property is replaced by ``lut-step-gap`` property in + :dtcompatible:`zephyr,h-bridge-stepper`. + +* :dtcompatible:`adi,tmc50xx` and :dtcompatible:`adi,tmc51xx` devices are now modeled as MFDs. +* :dtcompatible:`adi,tmc50xx-stepper` and :dtcompatible:`adi,tmc51xx-stepper` drivers implement + :c:group:`stepper_interface`. +* :dtcompatible:`adi,tmc50xx-stepper-drv` and :dtcompatible:`adi,tmc51xx-stepper-drv` drivers implement + :c:group:`stepper_drv_interface`. + USB === From 15716542c20dea8d32a4e8e3072a90c6635ee589 Mon Sep 17 00:00:00 2001 From: Carles Cufi Date: Wed, 3 Dec 2025 20:00:10 +0100 Subject: [PATCH 0217/3659] dts: nordic: Fix ngpios for nRF54L15 (and variants) The correct number is 7, since the QFN52 (QGAA) variant has P0.00 to P0.06 present. See: https://docs.nordicsemi.com/bundle/ps_nrf54L15/page/chapters/pin.html#ariaid-title6 Signed-off-by: Carles Cufi --- dts/vendor/nordic/nrf54l_05_10_15.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dts/vendor/nordic/nrf54l_05_10_15.dtsi b/dts/vendor/nordic/nrf54l_05_10_15.dtsi index 957445902185..2e74909fd04e 100644 --- a/dts/vendor/nordic/nrf54l_05_10_15.dtsi +++ b/dts/vendor/nordic/nrf54l_05_10_15.dtsi @@ -695,7 +695,7 @@ gpio-controller; reg = <0x10a000 0x300>; #gpio-cells = <2>; - ngpios = <5>; + ngpios = <7>; status = "disabled"; port = <0>; gpiote-instance = <&gpiote30>; From cc8bb0427af4c39b5811aed6c9d9569a990897b4 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Tue, 9 Dec 2025 17:08:51 +0100 Subject: [PATCH 0218/3659] net: latmon: Fix net API use In d45cd6716bbab3a805e3a5fd461934f0dcdc13e5 the mayority of the Zephyr networking code was changed to use the Zephyr native net_/zsock_ prefixed types, but some symbols were forgotten. Let's change them. Without these fixes/changes the code still builds in most cases as we are by now setting CONFIG_NET_NAMESPACE_COMPAT_MODE. But when this is not set, things will fail to build. Signed-off-by: Alberto Escolar Piedras --- subsys/net/lib/latmon/latmon.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/subsys/net/lib/latmon/latmon.c b/subsys/net/lib/latmon/latmon.c index 64fcb707fb86..26dfc96aeb40 100644 --- a/subsys/net/lib/latmon/latmon.c +++ b/subsys/net/lib/latmon/latmon.c @@ -342,7 +342,7 @@ static int broadcast_ip_address(struct net_in_addr *ip_addr) return -1; } - broadcast.sin_addr.s_addr = net_htonl(INADDR_BROADCAST); + broadcast.sin_addr.s_addr = net_htonl(NET_INADDR_BROADCAST); broadcast.sin_port = net_htons(LATMON_NET_PORT); broadcast.sin_family = NET_AF_INET; @@ -381,7 +381,7 @@ int net_latmon_get_socket(struct net_sockaddr *connection_addr) return -1; } - zsock_setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); + zsock_setsockopt(s, ZSOCK_SOL_SOCKET, ZSOCK_SO_REUSEADDR, &on, sizeof(on)); if (zsock_bind(s, (struct net_sockaddr *)&addr, sizeof(addr)) < 0) { LOG_ERR("failed to bind latmon socket : %d", errno); zsock_close(s); From addca1250b67a6c5bfc591ef6d63f5a0110a458a Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Tue, 9 Dec 2025 17:11:28 +0100 Subject: [PATCH 0219/3659] samples: net: latmon: Use native networking API directly This subsystem does not use the POSIX_API, and the sample only used one call to the POSIX API to close a socket instead of using the native networking API. Let's just use the native networking API, so we avoid pulling-in more dependencies. Signed-off-by: Alberto Escolar Piedras --- samples/net/latmon/prj.conf | 2 -- samples/net/latmon/src/main.c | 3 +-- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/samples/net/latmon/prj.conf b/samples/net/latmon/prj.conf index 6d1ef64b8baa..bf8e37f469b2 100644 --- a/samples/net/latmon/prj.conf +++ b/samples/net/latmon/prj.conf @@ -1,8 +1,6 @@ # SPDX-License-Identifier: Apache-2.0 # Copyright (c) 2025 Jorge Ramirez-Ortiz -CONFIG_POSIX_API=y - # General config CONFIG_LOG=y CONFIG_GPIO=y diff --git a/samples/net/latmon/src/main.c b/samples/net/latmon/src/main.c index e3c97d42d046..6e8dd80e9c0b 100644 --- a/samples/net/latmon/src/main.c +++ b/samples/net/latmon/src/main.c @@ -13,7 +13,6 @@ LOG_MODULE_REGISTER(sample_latmon, LOG_LEVEL_DBG); #include #include #include -#include /* * Blink Control @@ -267,7 +266,7 @@ int main(void) } out: k_thread_abort(blink_tid); - close(socket); + zsock_close(socket); return ret; } From a90994006a259227529d4d7868ab552524b322d5 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 11 Dec 2025 13:19:08 +0100 Subject: [PATCH 0220/3659] tests: net: all: Also build latmon Also build the latency monitor support code. As a sideeffect, we run out of bits in the kernel objects per thread permissions tracking field. So let's increase it to 6 bytes. Signed-off-by: Alberto Escolar Piedras --- tests/net/all/prj.conf | 4 +++- tests/net/all/testcase.yaml | 1 - 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/net/all/prj.conf b/tests/net/all/prj.conf index 1b61afc46205..a2e9f66640bb 100644 --- a/tests/net/all/prj.conf +++ b/tests/net/all/prj.conf @@ -8,7 +8,7 @@ CONFIG_ENTROPY_GENERATOR=y CONFIG_TEST_RANDOM_GENERATOR=y CONFIG_ZTEST=y CONFIG_LOG_DEFAULT_LEVEL=4 -CONFIG_MAX_THREAD_BYTES=4 +CONFIG_MAX_THREAD_BYTES=6 CONFIG_POSIX_API=y # TLS configuration @@ -688,3 +688,5 @@ CONFIG_SHELL_BACKEND_TELNET=y CONFIG_TFTP_LIB=y CONFIG_NET_PKT_FILTER=y + +CONFIG_NET_LATMON=y diff --git a/tests/net/all/testcase.yaml b/tests/net/all/testcase.yaml index 9f23ce7be66b..2e33dfddb898 100644 --- a/tests/net/all/testcase.yaml +++ b/tests/net/all/testcase.yaml @@ -128,4 +128,3 @@ tests: - CONFIG_NET_ROUTE_MCAST=y - CONFIG_OPENTHREAD_SHELL=y - CONFIG_DNS_RESOLVER_PACKET_FORWARDING=y - - CONFIG_MAX_THREAD_BYTES=5 From dd7526af499a35a3c19b2f4698cb5279c74a4f06 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 11 Dec 2025 15:12:05 +0100 Subject: [PATCH 0221/3659] modules: openthread: Fix network namespace API usage bcec3bd04ba38e65008f81d867f3b046a9da637f introduced some of the non-native API names back into this module. Let's fix it. Signed-off-by: Alberto Escolar Piedras --- modules/openthread/platform/infra_if.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/openthread/platform/infra_if.c b/modules/openthread/platform/infra_if.c index c15b1e4e4c6b..f978389f4cc4 100644 --- a/modules/openthread/platform/infra_if.c +++ b/modules/openthread/platform/infra_if.c @@ -392,21 +392,21 @@ static void remove_checksums_for_eth_offloading(uint8_t *buf, uint16_t len) } switch (ipv4_hdr->proto) { - case IPPROTO_ICMP: + case NET_IPPROTO_ICMP: if ((config.chksum_support & NET_IF_CHECKSUM_IPV4_ICMP) != 0) { struct net_icmp_hdr *icmp_hdr = (struct net_icmp_hdr *)pkt_cursor; icmp_hdr->chksum = 0; } break; - case IPPROTO_UDP: + case NET_IPPROTO_UDP: if ((config.chksum_support & NET_IF_CHECKSUM_IPV4_UDP) != 0) { struct net_udp_hdr *udp_hdr = (struct net_udp_hdr *)pkt_cursor; udp_hdr->chksum = 0; } break; - case IPPROTO_TCP: + case NET_IPPROTO_TCP: if ((config.chksum_support & NET_IF_CHECKSUM_IPV4_TCP) != 0) { struct net_tcp_hdr *tcp_hdr = (struct net_tcp_hdr *)pkt_cursor; From 7e139d6bfe15fcda8af8a32c4014d2111a69247b Mon Sep 17 00:00:00 2001 From: Gilles Devillers Date: Wed, 10 Dec 2025 11:26:49 +0100 Subject: [PATCH 0222/3659] net: mqtt: fix log typo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix typo in a log message and remove a redundant “error” mention. Signed-off-by: Gilles Devillers --- subsys/net/lib/mqtt/mqtt_transport_socket_tls.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/net/lib/mqtt/mqtt_transport_socket_tls.c b/subsys/net/lib/mqtt/mqtt_transport_socket_tls.c index 4f300e390f39..c86dec88e16d 100644 --- a/subsys/net/lib/mqtt/mqtt_transport_socket_tls.c +++ b/subsys/net/lib/mqtt/mqtt_transport_socket_tls.c @@ -42,7 +42,7 @@ int mqtt_client_tls_connect(struct mqtt_client *client) ZSOCK_SO_BINDTODEVICE, &ifname, sizeof(struct net_ifreq)); if (ret < 0) { - NET_ERR("Failed to bind ot interface %s error (%d)", + NET_ERR("Failed to bind to interface %s (%d)", ifname.ifr_name, -errno); goto error; } From aecaeae13e354d0f379bd722843f952fbe3041e3 Mon Sep 17 00:00:00 2001 From: Mathieu Choplain Date: Tue, 9 Dec 2025 16:47:58 +0100 Subject: [PATCH 0223/3659] soc: st: stm32: wb0: don't quote section names in Z_GENERIC_SECTION Don't quote the section names provided to Z_GENERIC_SECTION: the macro already performs stringification on our behalf. Signed-off-by: Mathieu Choplain --- soc/st/stm32/stm32wb0x/soc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/soc/st/stm32/stm32wb0x/soc.c b/soc/st/stm32/stm32wb0x/soc.c index 758652781a72..2754a70d2f7b 100644 --- a/soc/st/stm32/stm32wb0x/soc.c +++ b/soc/st/stm32/stm32wb0x/soc.c @@ -38,7 +38,7 @@ uint32_t SystemCoreClock = 16000000U; * of SRAM0; used by the UART bootloader and the Low Power Manager. * Data type definition comes from @ref system_stm32wb0xx.h */ -Z_GENERIC_SECTION("stm32wb0_RAM_VR") +Z_GENERIC_SECTION(stm32wb0_RAM_VR) __used RAM_VR_TypeDef RAM_VR; #if defined(CONFIG_BT) @@ -47,7 +47,7 @@ __used RAM_VR_TypeDef RAM_VR; * * N.B.: radio driver defines CFG_BLE_NUM_RADIO_TASKS. */ -Z_GENERIC_SECTION("stm32wb0_BLUE_RAM") +Z_GENERIC_SECTION(stm32wb0_BLUE_RAM) static uint8_t __used __blue_RAM[sizeof(GLOBALSTATMACH_TypeDef) + CFG_BLE_NUM_RADIO_TASKS * sizeof(STATMACH_TypeDef)]; #endif /* CONFIG_BT */ From ddd25e81e77774bb7bb84f8bd7f8f712e9f9a4b2 Mon Sep 17 00:00:00 2001 From: Atilla Filiz Date: Sat, 23 Aug 2025 21:12:45 +0200 Subject: [PATCH 0224/3659] drivers: sensor: add ams as6221 temperature sensor driver support The as6221 is functionally equivalent to ti tmp108 and ams as6212, so it is added as a new variant of tmp108. Signed-off-by: Atilla Filiz --- drivers/sensor/ti/tmp108/Kconfig | 8 ++++-- drivers/sensor/ti/tmp108/tmp108.c | 6 ++++ drivers/sensor/ti/tmp108/tmp108.h | 2 ++ dts/bindings/sensor/ams,as6221.yaml | 18 ++++++++++++ samples/sensor/tmp108/README.rst | 3 +- samples/sensor/tmp108/sample.yaml | 4 ++- samples/sensor/tmp108/src/main.c | 37 +++++++++++++++++-------- tests/drivers/build_all/sensor/i2c.dtsi | 5 ++++ 8 files changed, 66 insertions(+), 17 deletions(-) create mode 100644 dts/bindings/sensor/ams,as6221.yaml diff --git a/drivers/sensor/ti/tmp108/Kconfig b/drivers/sensor/ti/tmp108/Kconfig index e160b6edd4bd..99cc2c6e2fc1 100644 --- a/drivers/sensor/ti/tmp108/Kconfig +++ b/drivers/sensor/ti/tmp108/Kconfig @@ -2,17 +2,19 @@ # Copyright (c) 2021 Jimmy Johnson # Copyright (c) 2022 T-Mobile USA, Inc. +# Copyright (c) 2025 Byteflies NV # SPDX-License-Identifier: Apache-2.0 menuconfig TMP108 bool "TMP108 Temperature Sensor" default y - depends on DT_HAS_TI_TMP108_ENABLED || DT_HAS_AMS_AS6212_ENABLED + depends on DT_HAS_TI_TMP108_ENABLED || DT_HAS_AMS_AS6212_ENABLED \ + || DT_HAS_AMS_AS6221_ENABLED select I2C help - Enable driver for the TMP108 temperature sensor and/or it's variant - the AMS AS621. + Enable driver for the TMP108 temperature sensor and/or it's variants, + the AMS AS621x, AS6221. if TMP108 diff --git a/drivers/sensor/ti/tmp108/tmp108.c b/drivers/sensor/ti/tmp108/tmp108.c index 69e8fadbf550..855856458298 100644 --- a/drivers/sensor/ti/tmp108/tmp108.c +++ b/drivers/sensor/ti/tmp108/tmp108.c @@ -1,6 +1,7 @@ /* * Copyright (c) 2021 Jimmy Johnson * Copyright (c) 2022 T-Mobile USA, Inc. + * Copyright (c) 2025 Byteflies NV * * SPDX-License-Identifier: Apache-2.0 */ @@ -438,3 +439,8 @@ DT_INST_FOREACH_STATUS_OKAY(TMP108_INIT) #undef DT_DRV_COMPAT #define DT_DRV_COMPAT ams_as6212 DT_INST_FOREACH_STATUS_OKAY(AS6212_INIT) + +#define AS6221_INIT(n) TMP108_DEFINE(n, AMS_AS6221) +#undef DT_DRV_COMPAT +#define DT_DRV_COMPAT ams_as6221 +DT_INST_FOREACH_STATUS_OKAY(AS6221_INIT) diff --git a/drivers/sensor/ti/tmp108/tmp108.h b/drivers/sensor/ti/tmp108/tmp108.h index 9ca65fc5d061..630a8dcf1050 100644 --- a/drivers/sensor/ti/tmp108/tmp108.h +++ b/drivers/sensor/ti/tmp108/tmp108.h @@ -32,6 +32,8 @@ .TEMP_DIV = 2, \ IF_ENABLED(CONFIG_TMP108_ALERT_INTERRUPTS, (.CONF_POL = 0x0400))} +#define AMS_AS6221_CONF AMS_AS6212_CONF + #define TI_TMP108_CONF \ {.CONF_M0 = 0x0100, \ .CONF_M1 = 0x0200, \ diff --git a/dts/bindings/sensor/ams,as6221.yaml b/dts/bindings/sensor/ams,as6221.yaml new file mode 100644 index 000000000000..f11c56bc76e9 --- /dev/null +++ b/dts/bindings/sensor/ams,as6221.yaml @@ -0,0 +1,18 @@ +# Copyright (c) 2025 Byteflies NV +# Copyright (c) 2022 T-Mobile USA, Inc. +# SPDX-License-Identifier: Apache-2.0 + +description: | + AMS AS6221 Digital Temperature Sensor. See more info at + https://ams.com/en/as6221 + +compatible: "ams,as6221" + +include: [sensor-device.yaml, i2c-device.yaml] + +properties: + alert-gpios: + type: phandle-array + description: | + Identifies the ALERT signal, which is active-low open drain when + produced by the sensor. diff --git a/samples/sensor/tmp108/README.rst b/samples/sensor/tmp108/README.rst index b516c844d32d..ca8fd4ffdff4 100644 --- a/samples/sensor/tmp108/README.rst +++ b/samples/sensor/tmp108/README.rst @@ -14,7 +14,8 @@ also using low power one shot mode. Requirements ************ -A board with the :dtcompatible:`ti,tmp108` built in to its :ref:`devicetree `, +A board with either the :dtcompatible:`ti,tmp108` or :dtcompatible:`ams,as6212` or +:dtcompatible:`ams,as6221` built in to its :ref:`devicetree `, or a devicetree overlay with such a node added. Sample Output diff --git a/samples/sensor/tmp108/sample.yaml b/samples/sensor/tmp108/sample.yaml index b40fb0d337f1..b9046f3ea1ab 100644 --- a/samples/sensor/tmp108/sample.yaml +++ b/samples/sensor/tmp108/sample.yaml @@ -7,7 +7,9 @@ tests: depends_on: - i2c - gpio - filter: dt_compat_enabled("ti,tmp108") + filter: dt_compat_enabled("ti,tmp108") or + dt_compat_enabled("ams,as6212") or + dt_compat_enabled("ams,as6221") harness_config: type: multi_line regex: diff --git a/samples/sensor/tmp108/src/main.c b/samples/sensor/tmp108/src/main.c index fbf8e247c603..fd12b9df3165 100644 --- a/samples/sensor/tmp108/src/main.c +++ b/samples/sensor/tmp108/src/main.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2021 Jimmy Johnson + * Copyright (c) 2025 Byteflies NV * * SPDX-License-Identifier: Apache-2.0 */ @@ -10,6 +11,29 @@ #include #include +const struct device *get_tmp_sensor_dev(void) +{ + + const struct device *temp_sensor = DEVICE_DT_GET_ANY(ti_tmp108); + + if (!temp_sensor) { + printf("warning: tmp108 device not found checking for compatible ams device\n"); + + temp_sensor = DEVICE_DT_GET_ANY(ams_as6212); + } + + if (!temp_sensor) { + temp_sensor = DEVICE_DT_GET_ANY(ams_as6221); + + if (!temp_sensor) { + printf("error: tmp108 compatible devices not found\n"); + return 0; + } + } + + return temp_sensor; +} + void temperature_one_shot(const struct device *dev, const struct sensor_trigger *trigger) { @@ -135,18 +159,7 @@ int main(void) printf("TI TMP108 Example, %s\n", CONFIG_ARCH); - temp_sensor = DEVICE_DT_GET_ANY(ti_tmp108); - - if (!temp_sensor) { - printf("warning: tmp108 device not found checking for compatible ams device\n"); - - temp_sensor = DEVICE_DT_GET_ANY(ams_as6212); - - if (!temp_sensor) { - printf("error: tmp108 compatible devices not found\n"); - return 0; - } - } + temp_sensor = get_tmp_sensor_dev(); if (!device_is_ready(temp_sensor)) { printf("error: tmp108 device not ready\n"); diff --git a/tests/drivers/build_all/sensor/i2c.dtsi b/tests/drivers/build_all/sensor/i2c.dtsi index 0d35e5eb5543..f6fa32022457 100644 --- a/tests/drivers/build_all/sensor/i2c.dtsi +++ b/tests/drivers/build_all/sensor/i2c.dtsi @@ -1472,3 +1472,8 @@ test_rv3032: rv3032c7@c2 { status = "okay"; }; }; + +test_i2c_as6221: as6221@c3 { + compatible = "ams,as6221"; + reg = <0xc3>; +}; From ffb046b7971a928bb3a7f32445c35c6c90b476c9 Mon Sep 17 00:00:00 2001 From: Martin Stumpf Date: Fri, 21 Nov 2025 13:41:14 +0100 Subject: [PATCH 0225/3659] MCUmgr: OS: fix set datetime millisecond handling According to the docs the millis were in the format `.SSSSSS`. In reality though, it only accepted exactly `.SSS`, not `.SS` or `.SSSS` and specifically also not `.SSSSSS`, contrary to the docs. Further, it did not fail with an error message but simply produced the wrong value. With this change it accepts everything from `.` to `.SSSSSS` and produces the correct result. This is compatible with the previous behavior, with the documentation and with everything in between. Signed-off-by: Martin Stumpf --- subsys/mgmt/mcumgr/grp/os_mgmt/src/os_mgmt.c | 29 +++++++++++--------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/subsys/mgmt/mcumgr/grp/os_mgmt/src/os_mgmt.c b/subsys/mgmt/mcumgr/grp/os_mgmt/src/os_mgmt.c index c8798edd0b36..a175cdf78fe1 100644 --- a/subsys/mgmt/mcumgr/grp/os_mgmt/src/os_mgmt.c +++ b/subsys/mgmt/mcumgr/grp/os_mgmt/src/os_mgmt.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -122,8 +123,6 @@ struct datetime_parser { #define RTC_DATETIME_MINUTE_MAX 59 #define RTC_DATETIME_SECOND_MIN 0 #define RTC_DATETIME_SECOND_MAX 59 -#define RTC_DATETIME_MILLISECOND_MIN 0 -#define RTC_DATETIME_MILLISECOND_MAX 999 /* Size used for datetime creation buffer */ #ifdef CONFIG_MCUMGR_GRP_OS_DATETIME_MS @@ -134,7 +133,7 @@ struct datetime_parser { /* Minimum/maximum size of a datetime string that a client can provide */ #define RTC_DATETIME_MIN_STRING_SIZE 19 -#define RTC_DATETIME_MAX_STRING_SIZE 26 +#define RTC_DATETIME_MAX_STRING_SIZE 31 #endif /* Specifies what the "all" ('a') of info parameter shows */ @@ -1060,7 +1059,7 @@ static int os_mgmt_datetime_write(struct smp_streamer *ctxt) bool ok = true; char *pos; char *new_pos; - char date_string[RTC_DATETIME_MAX_STRING_SIZE]; + char date_string[RTC_DATETIME_MAX_STRING_SIZE + 1]; struct rtc_time new_time = { .tm_wday = -1, .tm_yday = -1, @@ -1115,7 +1114,7 @@ static int os_mgmt_datetime_write(struct smp_streamer *ctxt) if (zcbor_map_decode_bulk(zsd, datetime_decode, ARRAY_SIZE(datetime_decode), &decoded)) { return MGMT_ERR_EINVAL; } else if (datetime.len < RTC_DATETIME_MIN_STRING_SIZE || - datetime.len >= RTC_DATETIME_MAX_STRING_SIZE) { + datetime.len > RTC_DATETIME_MAX_STRING_SIZE) { return MGMT_ERR_EINVAL; } @@ -1151,16 +1150,20 @@ static int os_mgmt_datetime_write(struct smp_streamer *ctxt) } #ifdef CONFIG_MCUMGR_GRP_OS_DATETIME_MS - if (*(pos - 1) == '.' && *pos != '\0') { - /* Provided value has a ms value, extract it */ - new_time.tm_nsec = strtol(pos, &new_pos, RTC_DATETIME_NUMERIC_BASE); - - if (new_time.tm_nsec < RTC_DATETIME_MILLISECOND_MIN || - new_time.tm_nsec > RTC_DATETIME_MILLISECOND_MAX) { - return MGMT_ERR_EINVAL; + if (*(pos - 1) == '.') { + uint32_t msec = 0; + uint32_t mul = 100; /* first digit: 10^-1 second = 100 ms */ + + /* Parse up to 3 fractional digits */ + while (isdigit((unsigned char)*pos) && mul >= 1) { + msec += (uint32_t)(*pos - '0') * mul; + mul /= 10; + pos++; } - new_time.tm_nsec *= RTC_DATETIME_MS_TO_NS; + /* "." without digits yields 0 µs */ + + new_time.tm_nsec = msec * RTC_DATETIME_MS_TO_NS; } #endif From 09c80e18e6c9d616da96a45bac172d1c6aeaa6cd Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Fri, 21 Nov 2025 14:54:15 +0100 Subject: [PATCH 0226/3659] tests: Bluetooth: Update ICS to TCRL pkg101 Updated to TCRL pkg101. Security Mode 2 supporte removed (GAP,SM,GATT). Bumped supported LE Audio profiles versions and enabled implemented features (notably TMPA UMS) Signed-off-by: Szymon Janc --- .../ICS_Zephyr_Bluetooth_Host.bqw | 3559 +++++++++-------- .../ICS_Zephyr_Bluetooth_Host.pts | 484 ++- 2 files changed, 2232 insertions(+), 1811 deletions(-) diff --git a/tests/bluetooth/qualification/ICS_Zephyr_Bluetooth_Host.bqw b/tests/bluetooth/qualification/ICS_Zephyr_Bluetooth_Host.bqw index 1f0b30081209..4a85480206c8 100644 --- a/tests/bluetooth/qualification/ICS_Zephyr_Bluetooth_Host.bqw +++ b/tests/bluetooth/qualification/ICS_Zephyr_Bluetooth_Host.bqw @@ -1,28 +1,12 @@ - + - + - GAP 11c/1 - GAP 27b/7 - GAP 20/8 - GAP 17b/2 - GAP 30a/5 - GAP 17/5 - GAP 30a/10 - GAP 36/6 - GAP 8a/18 - GAP 27b/1 - GAP 30a/4 - GAP 37a/4 - GAP 30a/13 - GAP 11/5 - GAP 26/6 - GAP 30a/2 GAP 27c/1 GAP 35/11 GAP 25/13b @@ -35,67 +19,12 @@ GAP 8/5 GAP 35/13 GAP 30a/1 - GAP 35/12 - GAP 11/2 - GAP 12/2 - GAP 37b/1 - GAP 27a/6 - GAP 14a/1 - GAP 14a/13 - GAP 8a/19 - GAP 20A/1 - GAP 20A/14 - GAP 21/10 - GAP 21/2 - GAP 22/1 - GAP 22/3 - GAP 24/4 - GAP 27/2 - GAP 31/10 - GAP 32/1 - GAP 32/2 - GAP 37/1 - GAP 5/4 - GAP 8a/1 - GAP 8a/4 - GAP 25/12 - GAP 30a/19 - GAP 30a/18 - GAP 30a/14 - GAP 37a/6 - GAP 14a/11 - GAP 25/13a - GAP 14a/9 - GAP 30a/9 - GAP 33/8a - GAP 14a/14a - GAP 11/3 - GAP 13/2 - GAP 15/1 - GAP 17/1 - GAP 17a/2 - GAP 18/1 - GAP 18/2 - GAP 20/4 - GAP 20/6 - GAP 20A/5 - GAP 20A/8 - GAP 21/5 - GAP 23/2 - GAP 25/1 - GAP 27/7 - GAP 28/2 - GAP 33/4 - GAP 34/1 - GAP 35/10 - GAP 36/1 - GAP 37/3 - GAP 6/2 - GAP 7/1 - GAP 8a/12 - GAP 8a/14 - GAP 17b/1 - GAP 23/6 + GAP 17b/2 + GAP 30a/5 + GAP 17/5 + GAP 30a/10 + GAP 36/6 + GAP 8a/18 GAP 11b/3 GAP 37c/2 GAP 37/7 @@ -104,6 +33,7 @@ GAP 37b/2 GAP 30a/12 GAP 17a/5 + GAP 0b/2 GAP 14a/4 GAP 14a/14 GAP 26/5 @@ -132,135 +62,6 @@ GAP 10/4 GAP 16/2 GAP 16/4 - GAP 37c/3 - GAP 37/6 - GAP 35/15 - GAP 14a/17 - GAP 11/4 - GAP 37b/9 - GAP 37c/1 - GAP 17b/4 - GAP 11b/4 - GAP 37b/3 - GAP 30a/15 - GAP 11b/2 - GAP 14a/15 - GAP 20A/19 - GAP 30a/16 - GAP 14a/10 - GAP 27b/3 - GAP 27b/6 - GAP 25/11 - GAP 11/1 - GAP 20/2 - GAP 20A/4 - GAP 21/6 - GAP 21/8 - GAP 23/4 - GAP 25/3 - GAP 25/8 - GAP 31/11 - GAP 31/2 - GAP 31/5 - GAP 33/6 - GAP 35/7 - GAP 37/2 - GAP 37a/3 - GAP 7/2 - GAP 8/2 - GAP 0/2 - GAP 11a/1 - GAP 12/1 - GAP 13/1 - GAP 17/2 - GAP 20/7 - GAP 20A/11 - GAP 20A/13 - GAP 20A/16 - GAP 20A/2 - GAP 20A/9 - GAP 21/7 - GAP 23/1 - GAP 23/5 - GAP 27/1 - GAP 27/9 - GAP 28/1 - GAP 30/2 - GAP 31/1 - GAP 31/6 - GAP 31/9 - GAP 8a/10 - GAP 8a/13 - GAP 8a/17 - GAP 8a/3 - GAP 8a/8 - GAP 33/7 - GAP 14/2 - GAP 17/4 - GAP 20/1 - GAP 20A/15 - GAP 20A/3 - GAP 21/9 - GAP 22/2 - GAP 24/2 - GAP 25/4 - GAP 25/9 - GAP 27/6 - GAP 27a/2 - GAP 29/4 - GAP 30/1 - GAP 31/4 - GAP 33/1 - GAP 33/5 - GAP 34/3 - GAP 35/3 - GAP 35/8 - GAP 36/2 - GAP 36/5 - GAP 5/3 - GAP 8a/2 - GAP 8a/9 - GAP 10/2 - GAP 33/8 - GAP 35/14 - GAP 17a/4 - GAP 14a/7 - GAP 23/7a - GAP 30a/17 - GAP 27a/5 - GAP 27b/5 - GAP 30a/8 - GAP 14a/5 - GAP 27a/4 - GAP 20A/18 - GAP 30a/6 - GAP 27c/2 - GAP 14a/6 - GAP 25/14 - GAP 14a/3 - GAP 27c/3 - GAP 11a/2 - GAP 16/1 - GAP 17a/1 - GAP 19/1 - GAP 20/3 - GAP 20/5 - GAP 20A/7 - GAP 23/3 - GAP 26/3 - GAP 27/5 - GAP 27a/1 - GAP 27a/3 - GAP 31/3 - GAP 37a/2 - GAP 6/1 - GAP 8a/11 - GAP 8a/15 - GAP 8a/16 - GAP 9/1 - GAP 10/3 - GAP 23/7 - GAP 7/3 GAP 8a/14a GAP 14a/16 GAP 27b/2 @@ -268,6 +69,7 @@ GAP 35/13b GAP 17b/3 GAP 25/13 + GAP 37b/10 GAP 14a/2 GAP 35/13a GAP 30a/11 @@ -299,61 +101,237 @@ GAP 10/5 GAP 11b/1 GAP 16/3 - - - - - L2CAP 1/3 - L2CAP 2/49 - L2CAP 2/40 - L2CAP 2/42 - L2CAP 2/47 - L2CAP 2/45a - L2CAP 1/6 - L2CAP 4/1 - L2CAP 2/43 - L2CAP 3/12 - L2CAP 1/4 - L2CAP 2/48 - L2CAP 3/16 - L2CAP 0/2 - L2CAP 4/3 - L2CAP 1/5 - L2CAP 2/48b - L2CAP 4/2 - L2CAP 2/41 - L2CAP 2/46 - L2CAP 3/1 - - - - - GATT 8/8 - GATT 10/5 - GATT 9/6 - GATT 9/5 - GATT 3/1 - GATT 3/7 - GATT 4/14 - GATT 4/25 - GATT 4/8 - GATT 7/7 - GATT 9/15 - GATT 2/5 - GATT 9/11 - GATT 1/2 - GATT 3/12 - GATT 3/14 - GATT 3/19 - GATT 3/2 - GATT 3/20 - GATT 3/26 - GATT 3/3 - GATT 3/8 - GATT 4/27 - GATT 4/5 - GATT 4/6 - GATT 7/5 + GAP 35/12 + GAP 11/2 + GAP 12/2 + GAP 14/2 + GAP 17/4 + GAP 20/1 + GAP 20A/15 + GAP 20A/3 + GAP 21/9 + GAP 22/2 + GAP 24/2 + GAP 25/4 + GAP 25/9 + GAP 27/6 + GAP 27a/2 + GAP 29/4 + GAP 30/1 + GAP 31/4 + GAP 33/1 + GAP 33/5 + GAP 34/3 + GAP 35/3 + GAP 35/8 + GAP 36/2 + GAP 36/5 + GAP 5/3 + GAP 8a/2 + GAP 8a/9 + GAP 10/2 + GAP 33/8 + GAP 11c/1 + GAP 27b/7 + GAP 27b/12 + GAP 20/8 + GAP 37b/1 + GAP 27a/6 + GAP 14a/1 + GAP 14a/13 + GAP 8a/19 + GAP 20A/1 + GAP 20A/14 + GAP 21/10 + GAP 21/2 + GAP 22/1 + GAP 22/3 + GAP 24/4 + GAP 27/2 + GAP 31/10 + GAP 32/1 + GAP 32/2 + GAP 37/1 + GAP 5/4 + GAP 8a/1 + GAP 8a/4 + GAP 37c/3 + GAP 37/6 + GAP 35/15 + GAP 14a/17 + GAP 11/4 + GAP 37b/9 + GAP 37c/1 + GAP 37b/11 + GAP 17b/4 + GAP 11b/4 + GAP 37b/3 + GAP 30a/15 + GAP 11b/2 + GAP 14a/15 + GAP 20A/19 + GAP 30a/16 + GAP 27b/11 + GAP 14a/10 + GAP 27b/3 + GAP 27b/6 + GAP 25/11 + GAP 11/1 + GAP 20/2 + GAP 20A/4 + GAP 21/6 + GAP 21/8 + GAP 23/4 + GAP 25/3 + GAP 25/8 + GAP 31/11 + GAP 31/2 + GAP 31/5 + GAP 33/6 + GAP 35/7 + GAP 37/2 + GAP 37a/3 + GAP 7/2 + GAP 8/2 + GAP 25/12 + GAP 30a/19 + GAP 30a/18 + GAP 30a/14 + GAP 37a/6 + GAP 14a/11 + GAP 25/13a + GAP 14a/9 + GAP 30a/9 + GAP 33/8a + GAP 14a/14a + GAP 11/3 + GAP 13/2 + GAP 15/1 + GAP 17/1 + GAP 17a/2 + GAP 18/1 + GAP 18/2 + GAP 20/4 + GAP 20/6 + GAP 20A/5 + GAP 20A/8 + GAP 21/5 + GAP 23/2 + GAP 25/1 + GAP 27/7 + GAP 28/2 + GAP 33/4 + GAP 34/1 + GAP 35/10 + GAP 36/1 + GAP 37/3 + GAP 6/2 + GAP 7/1 + GAP 8a/12 + GAP 8a/14 + GAP 17b/1 + GAP 23/6 + GAP 35/14 + GAP 17a/4 + GAP 14a/7 + GAP 23/7a + GAP 30a/17 + GAP 27a/5 + GAP 27b/5 + GAP 30a/8 + GAP 14a/5 + GAP 27a/4 + GAP 20A/18 + GAP 30a/6 + GAP 27c/2 + GAP 14a/6 + GAP 25/14 + GAP 14a/3 + GAP 27c/3 + GAP 11a/2 + GAP 16/1 + GAP 17a/1 + GAP 19/1 + GAP 20/3 + GAP 20/5 + GAP 20A/7 + GAP 23/3 + GAP 26/3 + GAP 27/5 + GAP 27a/1 + GAP 27a/3 + GAP 31/3 + GAP 37a/2 + GAP 6/1 + GAP 8a/11 + GAP 8a/15 + GAP 8a/16 + GAP 9/1 + GAP 10/3 + GAP 23/7 + GAP 7/3 + GAP 27b/1 + GAP 30a/4 + GAP 37a/4 + GAP 30a/13 + GAP 11/5 + GAP 26/6 + GAP 30a/2 + GAP 11a/1 + GAP 12/1 + GAP 13/1 + GAP 17/2 + GAP 20/7 + GAP 20A/11 + GAP 20A/13 + GAP 20A/16 + GAP 20A/2 + GAP 20A/9 + GAP 21/7 + GAP 23/1 + GAP 23/5 + GAP 27/1 + GAP 27/9 + GAP 28/1 + GAP 30/2 + GAP 31/1 + GAP 31/6 + GAP 31/9 + GAP 8a/10 + GAP 8a/13 + GAP 8a/17 + GAP 8a/3 + GAP 8a/8 + GAP 33/7 + + + + + L2CAP 2/45a + L2CAP 1/6 + L2CAP 2/40 + L2CAP 2/42 + L2CAP 2/47 + L2CAP 3/16 + L2CAP 2/49 + L2CAP 2/48b + L2CAP 4/2 + L2CAP 2/41 + L2CAP 2/46 + L2CAP 3/1 + L2CAP 0a/2 + L2CAP 1/3 + L2CAP 4/3 + L2CAP 1/5 + L2CAP 4/1 + L2CAP 2/43 + L2CAP 3/12 + L2CAP 1/4 + L2CAP 2/48 + + + + GATT 10/7 GATT 10/12 GATT 9/8 @@ -367,7 +345,34 @@ GATT 4/21 GATT 4/22 GATT 7/4 - GATT 7/6 + GATT 3a/1 + GATT 9/12 + GATT 1a/1 + GATT 1a/3 + GATT 4/11 + GATT 4/12 + GATT 4/9 + GATT 7/2 + GATT 10/1 + GATT 9/4 + GATT 10/3 + GATT 4a/2 + GATT 10/4 + GATT 3/25 + GATT 3/6 + GATT 4/17 + GATT 4/19 + GATT 4/4 + GATT 8/8 + GATT 10/5 + GATT 9/6 + GATT 9/5 + GATT 3/1 + GATT 3/7 + GATT 4/14 + GATT 4/25 + GATT 4/8 + GATT 7/7 GATT 10/11 GATT 2/3a GATT 9/2 @@ -381,30 +386,23 @@ GATT 3/4 GATT 3/9 GATT 4/1 - GATT 4/13 GATT 4/18 GATT 4/3 - GATT 4a/1 - GATT 1/1 - GATT 3/29 - GATT 3/21 - GATT 3/22 - GATT 3/23 - GATT 3/5 - GATT 4/10 - GATT 4/15 - GATT 4/7 - GATT 10/6 - GATT 10/1 - GATT 9/4 - GATT 10/3 - GATT 4a/2 - GATT 10/4 - GATT 3/25 - GATT 3/6 - GATT 4/17 - GATT 4/19 - GATT 4/4 + GATT 9/15 + GATT 2/5 + GATT 9/11 + GATT 1/2 + GATT 3/12 + GATT 3/14 + GATT 3/19 + GATT 3/2 + GATT 3/20 + GATT 3/26 + GATT 3/3 + GATT 3/8 + GATT 4/27 + GATT 4/5 + GATT 4/6 GATT 9/3 GATT 8/2 GATT 10/2 @@ -418,69 +416,54 @@ GATT 4/20 GATT 4/23 GATT 4/26 - GATT 3a/1 - GATT 9/12 - GATT 1a/1 - GATT 1a/3 - GATT 4/11 - GATT 4/12 - GATT 4/9 - GATT 7/2 + GATT 4a/1 + GATT 1/1 + GATT 3/29 + GATT 3/21 + GATT 3/22 + GATT 3/23 + GATT 3/5 + GATT 4/10 + GATT 4/15 + GATT 4/7 - SM 7b/2 - SM 3/1 - SM 5/2 + SM 4a/1 + SM 2a/1 + SM 5/3 + SM 1/1 + SM 4b/1 + SM 4a/2 + SM 7a/1 SM 7a/2 - SM 2/2 + SM 4a/3 SM 5/1 SM 5/4 - SM 1/1 - SM 2/1 - SM 4/1 - SM 5/3 - SM 7b/1 - SM 4/3 - SM 7b/3 - SM 7a/3 + SM 2a/2 + SM 7b/2 + SM 4b/2 + SM 5/2 + SM 4b/3 SM 1/2 - SM 7a/1 - SM 2/3 - SM 2/5 - SM 4/2 - - - - - ATT 7/3 - ATT 4/32 - ATT 2/2 - ATT 3/11 - ATT 3/14 - ATT 3/17 - ATT 3/7 - ATT 4/19 - ATT 4/3 - ATT 4/6 - ATT 4/9 - ATT 7/1 - ATT 3/30 - ATT 3/32 - ATT 4/12 - ATT 4/22 - ATT 4/24 - ATT 4/27 - ATT 4/7 - ATT 4/8 + SM 7b/1 + + + + + ATT 6/1 + ATT 3/12 + ATT 3/15 + ATT 3/18 + ATT 4/10 + ATT 4/20 ATT 3/10 ATT 3/16 ATT 2/3a ATT 3/31 ATT 4/33 ATT 3/19 - ATT 3/21 ATT 3/22 ATT 3/25 ATT 3/28 @@ -491,12 +474,6 @@ ATT 4/16 ATT 4/2 ATT 4/26 - ATT 6/1 - ATT 3/12 - ATT 3/15 - ATT 3/18 - ATT 4/10 - ATT 4/20 ATT 7/2 ATT 3/23 ATT 3/8 @@ -516,9 +493,28 @@ ATT 4/11 ATT 4/15 ATT 4/18 - ATT 4/21 ATT 4/25 ATT 4/28 + ATT 7/1 + ATT 3/30 + ATT 3/32 + ATT 4/12 + ATT 4/22 + ATT 4/24 + ATT 4/27 + ATT 4/7 + ATT 4/8 + ATT 7/3 + ATT 4/32 + ATT 2/2 + ATT 3/11 + ATT 3/14 + ATT 3/17 + ATT 3/7 + ATT 4/19 + ATT 4/3 + ATT 4/6 + ATT 4/9 ATT 1/1 ATT 4/31 ATT 3/26 @@ -528,99 +524,124 @@ - DIS 2/11 DIS 3/3 DIS 2/7 - DIS 2/3 + DIS 2/11 DIS 2/4 DIS 2/6 + DIS 1/2 + DIS 2/2 DIS 5/1 DIS 0/2 DIS 2/1 + DIS 2/3 DIS 2/5 - DIS 1/2 - DIS 2/2 + IAS 3/1 IAS 0/1 IAS 2/1 IAS 2/4 - IAS 3/1 - IAS 2/2 - IAS 2/3 IAS 3/2 IAS 1/2 + IAS 2/2 + IAS 2/3 - HRS 3/4 - HRS 2/2 HRS 1/2 - HRS 3/6 - HRS 2/1 HRS 0/1 HRS 3/2 HRS 3/5 + HRS 2/2 + HRS 3/4 + HRS 3/6 + HRS 2/1 - BAS 4/1 BAS 3/3 BAS 2/1 + BAS 3/5 + BAS 4/1 BAS 4/2 BAS 1/2 - BAS 3/5 BAS 0/2 BAS 2/3 - OTS 8/1b - OTS 8/8 - OTS 5/9 - OTS 6/3 - OTS 7/1 - OTS 8/3 - OTS 3/2 - OTS 4/12 - OTS 4/4 - OTS 4/5 - OTS 5/2 - OTS 4/1 - OTS 5/5 OTS 8/2 OTS 2/1 OTS 4/6 OTS 6/2 OTS 6/4 OTS 6/5 - OTS 0/1 + OTS 4/1 + OTS 5/5 OTS 4/16 OTS 4/2 OTS 4/20 OTS 4/3 OTS 5/1 + OTS 8/6 + OTS 4/13 + OTS 4/15 + OTS 6/1 + OTS 8/3 + OTS 3/2 + OTS 4/12 + OTS 4/4 + OTS 4/5 + OTS 5/2 + OTS 8/1b + OTS 8/8 + OTS 5/9 + OTS 6/3 + OTS 7/1 OTS 8/7 OTS 8/4 OTS 3/3 OTS 4/7 OTS 5/3 OTS 5/6 - OTS 8/6 - OTS 4/13 - OTS 4/15 - OTS 6/1 + OTS 0/1 + OTP 9/10 + OTP 2/1 + OTP 6/11 + OTP 7/15 + OTP 7/17 + OTP 10/1 + OTP 9/14 + OTP 9/16 + OTP 4/1 + OTP 6/14 + OTP 6/2 + OTP 7/2 + OTP 8/17 OTP 9/11 OTP 9/15 + OTP 9/18 + OTP 3/2 + OTP 6/1 + OTP 6/13 + OTP 7/16 + OTP 8/18 + OTP 9/12 + OTP 6/10 + OTP 6/12 + OTP 7/1 + OTP 7/20 + OTP 7/7 OTP 9/3 OTP 0/1 OTP 6/3 @@ -634,87 +655,24 @@ OTP 6/7 OTP 6/9 OTP 8/19 - OTP 10/1 - OTP 9/14 - OTP 9/16 - OTP 4/1 - OTP 6/14 - OTP 6/2 - OTP 7/2 - OTP 8/17 - OTP 9/10 - OTP 2/1 - OTP 6/11 - OTP 7/15 - OTP 7/17 - OTP 9/5 - OTP 9/8 - OTP 7/18 - OTP 8/1 - OTP 9/18 - OTP 3/2 - OTP 6/1 - OTP 6/13 - OTP 7/16 - OTP 8/18 OTP 9/4 OTP 9/9 OTP 2/2 OTP 5/1 OTP 7/12 OTP 7/6 - OTP 9/12 - OTP 6/10 - OTP 6/12 - OTP 7/1 - OTP 7/20 - OTP 7/7 + OTP 9/5 + OTP 9/8 + OTP 7/18 + OTP 8/1 - MESH 11/11 - MESH 4/14 - MESH 12/8 - MESH 18/13 - MESH 2/1 - MESH 10/4 - MESH 15/4 - MESH 15/5 - MESH 16/5 - MESH 4/7 - MESH 7/3 - MESH 19/1 + MESH 11/24 MESH 11/22 MESH 11/1 MESH 11/4 - MESH 11/15 - MESH 2/2 - MESH 12/3 - MESH 12/6 - MESH 4/3 - MESH 4/8 - MESH 5/4 - MESH 18/11 - MESH 21/2 - MESH 11/24 - MESH 11/16 - MESH 11/7 - MESH 4/17 - MESH 11/19 - MESH 11/5 - MESH 10/2 - MESH 11/3 - MESH 13/2 - MESH 14/5 - MESH 4/10 - MESH 4/5 - MESH 5/1 - MESH 5/2 - MESH 6/2 - MESH 18/5 - MESH 18/8 - MESH 20/1 MESH 12/1 MESH 15/1 MESH 20/3 @@ -748,17 +706,55 @@ MESH 18/7 MESH 20/4 MESH 21/3 - MESH 10/1 - MESH 13/1 - MESH 14/4 - MESH 16/4 - MESH 3/1 - MESH 7/1 - MESH 18/1 - MESH 18/9 - MESH 20/2 - MESH 21/1 - MESH 21/4 + MESH 11/16 + MESH 11/7 + MESH 11/19 + MESH 11/5 + MESH 10/2 + MESH 11/3 + MESH 13/2 + MESH 14/5 + MESH 4/10 + MESH 4/5 + MESH 5/1 + MESH 5/2 + MESH 6/2 + MESH 18/5 + MESH 18/8 + MESH 20/1 + MESH 11/11 + MESH 4/14 + MESH 12/8 + MESH 18/13 + MESH 2/1 + MESH 10/4 + MESH 15/4 + MESH 15/5 + MESH 16/5 + MESH 4/7 + MESH 7/3 + MESH 19/1 + MESH 11/23 + MESH 12/12 + MESH 18/12 + MESH 1a/2 + MESH 11/14 + MESH 4/13 + MESH 11/6 + MESH 14/1 + MESH 4/11 + MESH 7/4 + MESH 18/2 + MESH 18/6 + MESH 11/15 + MESH 2/2 + MESH 12/3 + MESH 12/6 + MESH 4/3 + MESH 4/8 + MESH 5/4 + MESH 18/11 + MESH 21/2 MESH 11/12 MESH 4/15 MESH 11/18 @@ -777,49 +773,49 @@ MESH 18/10 MESH 18/3 MESH 20/5 - MESH 11/23 - MESH 12/12 - MESH 18/12 - MESH 1a/2 - MESH 11/14 - MESH 4/13 - MESH 11/6 - MESH 14/1 - MESH 4/11 - MESH 7/4 - MESH 18/2 - MESH 18/6 + MESH 4/17 + MESH 10/1 + MESH 13/1 + MESH 14/4 + MESH 16/4 + MESH 3/1 + MESH 7/1 + MESH 18/1 + MESH 18/9 + MESH 20/2 + MESH 21/1 + MESH 21/4 - LC3 4/2 - LC3 2/2 + LC3 3/6 + LC3 5/5 LC3 6/2 LC3 3/1 LC3 3/4 LC3 0/1 LC3 3/2 - LC3 3/6 - LC3 5/5 - LC3 6/1 - LC3 5/1 LC3 2/3 LC3 4/1 - LC3 5/4 - LC3 1/1 - LC3 5/6 - LC3 5/2 + LC3 4/2 + LC3 2/2 LC3 2/1 LC3 3/3 LC3 5/3 LC3 3/5 + LC3 5/4 + LC3 1/1 + LC3 5/6 + LC3 5/2 + LC3 6/1 + LC3 5/1 - AICS 4/1 - AICS 4/2 + AICS 4/3 + AICS 2/4 AICS 3/5 AICS 3/2 AICS 2/8 @@ -828,82 +824,67 @@ AICS 2/1 AICS 4/6 AICS 1/2 - AICS 4/3 - AICS 2/4 AICS 2/2 AICS 2/6 AICS 2/7 AICS 3/3 AICS 3/1 AICS 0/1 + AICS 2/10 + AICS 4/1 + AICS 4/2 + AICS 3/3b AICS 3/4 AICS 2/3 + AICS 2/9 AICS 2/5 - VOCS 0/1 VOCS 3/3 + VOCS 3/2 + VOCS 0/1 VOCS 1/2 VOCS 2/3 VOCS 2/1 VOCS 2/6 VOCS 2/8 + VOCS 2/2 + VOCS 3/4 + VOCS 2/5 VOCS 3/6 VOCS 0a/1 VOCS 2/4 VOCS 2/7 VOCS 3/1 - VOCS 3/2 - VOCS 2/2 - VOCS 3/4 - VOCS 2/5 - VCS 4/2 - VCS 3/6 - VCS 2/1 - VCS 2/4 VCS 3/7 VCS 3/4 VCS 4/1 + VCS 4/4 + VCS 0a/1 + VCS 4/2 VCS 3/3 VCS 1/2 VCS 2/3 - VCS 2/2 - VCS 4/3 - VCS 4/4 - VCS 0a/1 + VCS 3/6 + VCS 2/1 + VCS 2/4 VCS 3/2 VCS 3/1 VCS 0/1 VCS 3/5 VCS 4/6 + VCS 2/2 + VCS 4/3 - VCP 15/2 - VCP 16/7 - VCP 14/5 - VCP 12/8 - VCP 16/10 - VCP 11/2 - VCP 18/3 - VCP 13/2 - VCP 16/3 - VCP 10/1 - VCP 6/3 - VCP 17/9 - VCP 12/12 - VCP 12/1 - VCP 12/6 - VCP 13/3 - VCP 16/6 - VCP 15/1 VCP 17/11 VCP 16/9 VCP 13/1 @@ -916,29 +897,6 @@ VCP 18/12 VCP 17/2 VCP 6/13 - VCP 14/3 - VCP 15/4 - VCP 12/7 - VCP 6/2 - VCP 12/5 - VCP 15/5 - VCP 16/4 - VCP 12/2 - VCP 14/9 - VCP 18/14 - VCP 5/1 - VCP 16/12 - VCP 11/1 - VCP 11/3 - VCP 5/2 - VCP 5/3 - VCP 16/14 - VCP 16/1 - VCP 18/4 - VCP 14/7 - VCP 6/8 - VCP 17/13 - VCP 17/6 VCP 14/2 VCP 8/1 VCP 10/3 @@ -951,6 +909,32 @@ VCP 2/2 VCP 16/8 VCP 10/2 + VCP 15/2 + VCP 16/7 + VCP 14/5 + VCP 12/8 + VCP 16/10 + VCP 11/2 + VCP 18/3 + VCP 14/3 + VCP 15/4 + VCP 12/7 + VCP 6/2 + VCP 12/5 + VCP 15/5 + VCP 16/4 + VCP 12/2 + VCP 14/9 + VCP 13/2 + VCP 16/3 + VCP 10/1 + VCP 6/3 + VCP 17/9 + VCP 12/12 + VCP 12/1 + VCP 12/6 + VCP 13/3 + VCP 16/6 VCP 18/15 VCP 15/3 VCP 12/3 @@ -974,22 +958,49 @@ VCP 17/8 VCP 17/1 VCP 3/1 + VCP 15/1 + VCP 18/14 + VCP 5/1 + VCP 16/12 + VCP 11/1 + VCP 11/3 + VCP 5/2 + VCP 5/3 + VCP 16/14 + VCP 16/1 + VCP 18/4 + VCP 14/7 + VCP 6/8 + VCP 17/13 + VCP 17/6 - MICS 2/1 - MICS 3/3 - MICS 3/2 - MICS 3/1 MICS 3/6 MICS 1/2 + MICS 3/1 + MICS 2/1 + MICS 3/3 MICS 0/1 MICS 3/4 + MICS 3/2 + MICP 14/9 + MICP 14/5 + MICP 16/7 + MICP 6/1 + MICP 15/10 + MICP 16/3 + MICP 6/5 + MICP 12/1 + MICP 13/2 + MICP 16/6 + MICP 15/3 + MICP 14/14 MICP 14/2 MICP 14/13 MICP 15/2 @@ -1000,6 +1011,20 @@ MICP 16/4 MICP 13/5 MICP 5/2 + MICP 15/8 + MICP 16/5 + MICP 14/11 + MICP 15/1 + MICP 14/7 + MICP 3/1 + MICP 16/14 + MICP 14/12 + MICP 15/5 + MICP 6/6 + MICP 15/13 + MICP 6/13 + MICP 13/3 + MICP 6/4 MICP 6/14 MICP 1/1 MICP 14/10 @@ -1011,32 +1036,6 @@ MICP 16/1 MICP 13/1 MICP 10/2 - MICP 6/5 - MICP 12/1 - MICP 13/2 - MICP 16/6 - MICP 15/3 - MICP 14/14 - MICP 14/9 - MICP 14/5 - MICP 16/7 - MICP 6/1 - MICP 15/10 - MICP 16/3 - MICP 8/1 - MICP 16/13 - MICP 13/6 - MICP 14/6 - MICP 13/4 - MICP 2/2 - MICP 15/8 - MICP 16/5 - MICP 14/11 - MICP 15/1 - MICP 14/7 - MICP 3/1 - MICP 16/14 - MICP 14/12 MICP 15/6 MICP 15/11 MICP 10/1 @@ -1045,16 +1044,40 @@ MICP 12/2 MICP 14/1 MICP 14/4 - MICP 15/5 - MICP 6/6 - MICP 15/13 - MICP 6/13 - MICP 13/3 - MICP 6/4 + MICP 8/1 + MICP 16/13 + MICP 13/6 + MICP 14/6 + MICP 13/4 + MICP 2/2 + MCS 23/19 + MCS 23/4 + MCS 23/3 + MCS 23/7 + MCS 24/1 + MCS 22/19 + MCS 22/5 + MCS 24/2 + MCS 23/10 + MCS 25/4 + MCS 22/20 + MCS 22/13 + MCS 25/2 + MCS 22/25 + MCS 22/3 + MCS 20/1 + MCS 22/23 + MCS 22/17 + MCS 23/13 + MCS 21/2 + MCS 22/12 + MCS 23/9 + MCS 22/21 + MCS 20a/1 MCS 25/6 MCS 22/15 MCS 23/15 @@ -1067,39 +1090,12 @@ MCS 25/1 MCS 0b/2 MCS 23/18 - MCS 23/7 - MCS 24/1 - MCS 22/19 - MCS 22/5 - MCS 24/2 - MCS 23/10 - MCS 25/4 - MCS 22/20 - MCS 22/13 - MCS 25/2 - MCS 22/25 + MCS 24/3 MCS 22/7 MCS 22/24 MCS 23/20 MCS 25/3 MCS 23/14 - MCS 23/19 - MCS 23/4 - MCS 23/3 - MCS 23/11 - MCS 23/17 - MCS 22/6 - MCS 22/10 - MCS 23/1 - MCS 22/18 - MCS 23/2 - MCS 22/4 - MCS 22/3 - MCS 20/1 - MCS 22/23 - MCS 22/17 - MCS 23/13 - MCS 21/2 MCS 23/21 MCS 22/26 MCS 22/11 @@ -1110,46 +1106,18 @@ MCS 22/9 MCS 22/8 MCS 22/14 - MCS 22/12 - MCS 23/9 - MCS 22/21 - MCS 20a/1 - MCS 24/3 + MCS 23/11 + MCS 23/17 + MCS 22/6 + MCS 22/10 + MCS 23/1 + MCS 22/18 + MCS 23/2 + MCS 22/4 - MCP 17/13 - MCP 17/19 - MCP 17/1 - MCP 6/6 - MCP 17/11 - MCP 18a/8 - MCP 17/9 - MCP 17/14 - MCP 16/20 - MCP 1/1 - MCP 16/4 - MCP 6/5 - MCP 18/4 - MCP 18/3 - MCP 6/13 - MCP 18/2 - MCP 16/22 - MCP 6/2 - MCP 18/7 - MCP 17/12 - MCP 16/14 - MCP 18a/10 - MCP 16/13 - MCP 17/8 - MCP 16/10 - MCP 17/20 - MCP 17/15 - MCP 16/2 - MCP 10/1 - MCP 18a/2 - MCP 16/15 MCP 18/5 MCP 5/4 MCP 16/12 @@ -1164,20 +1132,15 @@ MCP 5/3 MCP 17/16 MCP 16/18 - MCP 9/2 - MCP 21/2 - MCP 18a/14 - MCP 20/1 - MCP 6/1 - MCP 17/6 - MCP 16/17 - MCP 16/11 - MCP 17/5 - MCP 18a/11 - MCP 9/3 - MCP 16/5 - MCP 13/3 - MCP 18/8 + MCP 18/2 + MCP 16/22 + MCP 6/2 + MCP 18/7 + MCP 17/12 + MCP 16/14 + MCP 18a/10 + MCP 16/13 + MCP 17/8 MCP 16/19 MCP 21/3 MCP 8/1 @@ -1188,6 +1151,39 @@ MCP 6/4 MCP 1/2 MCP 18a/4 + MCP 16/4 + MCP 6/5 + MCP 18/4 + MCP 18/3 + MCP 6/13 + MCP 21/1 + MCP 18a/6 + MCP 2/2 + MCP 17/7 + MCP 18a/9 + MCP 3/1 + MCP 17/4 + MCP 17/3 + MCP 16/9 + MCP 6/14 + MCP 13/2 + MCP 17/13 + MCP 17/19 + MCP 17/1 + MCP 6/6 + MCP 17/11 + MCP 18a/8 + MCP 17/9 + MCP 17/14 + MCP 16/20 + MCP 1/1 + MCP 16/10 + MCP 17/20 + MCP 17/15 + MCP 16/2 + MCP 10/1 + MCP 18a/2 + MCP 16/15 MCP 6/3 MCP 18a/12 MCP 18a/13 @@ -1201,44 +1197,24 @@ MCP 16/16 MCP 5/2 MCP 18a/7 - MCP 21/1 - MCP 18a/6 - MCP 2/2 - MCP 17/7 - MCP 18a/9 - MCP 3/1 - MCP 17/4 - MCP 17/3 - MCP 16/9 - MCP 6/14 - MCP 13/2 + MCP 9/2 + MCP 21/2 + MCP 18a/14 + MCP 20/1 + MCP 6/1 + MCP 17/6 + MCP 16/17 + MCP 16/11 + MCP 17/5 + MCP 18a/11 + MCP 9/3 + MCP 16/5 + MCP 13/3 + MCP 18/8 - TBS 22/3 - TBS 2/13 - TBS 4/5 - TBS 24/3 - TBS 22/12 - TBS 22/14 - TBS 2/25 - TBS 2/10 - TBS 22/22 - TBS 2/8 - TBS 2/7 - TBS 23/6 - TBS 2/19 - TBS 22/18 - TBS 22/25 - TBS 22/21 - TBS 2/24 - TBS 22/23 - TBS 24/4 - TBS 22/9 - TBS 4/3 - TBS 23/2 - TBS 0b/1 TBS 23/5 TBS 2/12 TBS 24/2 @@ -1253,19 +1229,9 @@ TBS 1/2 TBS 24/7 TBS 22/11 - TBS 22/7 - TBS 22/24 - TBS 2/2 - TBS 23/3 - TBS 3/4 - TBS 2/18 - TBS 0b/2 - TBS 22/1 - TBS 4/7 - TBS 2/6 - TBS 21/2 - TBS 22/6 - TBS 2/1 + TBS 4/3 + TBS 23/2 + TBS 0b/1 TBS 2/15 TBS 23/1 TBS 20/1 @@ -1278,12 +1244,6 @@ TBS 3/5 TBS 22/20 TBS 24/5 - TBS 22/2 - TBS 4/2 - TBS 2/14 - TBS 0/1 - TBS 22/5 - TBS 3/3 TBS 3/1 TBS 22/17 TBS 22/15 @@ -1296,46 +1256,49 @@ TBS 2/17 TBS 4/4 TBS 2/20 - - - - - CCP 14/7 - CCP 14/20 - CCP 12/5 - CCP 12/9 - CCP 11/4 - CCP 13/16 - CCP 17/12 - CCP 12/18 - CCP 6/7 - CCP 11/14 - CCP 17/2 - CCP 14/11 - CCP 12/12 - CCP 10/1 - CCP 14/19 - CCP 15/4 - CCP 2/2 - CCP 11/16 - CCP 14/10 - CCP 13/15 - CCP 14/2 - CCP 5/2 - CCP 15/6 - CCP 11/8 - CCP 14/9 - CCP 11/15 - CCP 13/12 - CCP 17/5 - CCP 11/1 - CCP 17/10 - CCP 1/1 - CCP 6/1 - CCP 13/7 - CCP 6/5 - CCP 17/4 - CCP 12/1 + TBS 2/7 + TBS 23/6 + TBS 2/19 + TBS 22/18 + TBS 22/25 + TBS 22/21 + TBS 2/24 + TBS 22/23 + TBS 24/4 + TBS 22/9 + TBS 22/3 + TBS 2/13 + TBS 4/5 + TBS 24/3 + TBS 22/12 + TBS 22/14 + TBS 2/25 + TBS 2/10 + TBS 22/22 + TBS 2/8 + TBS 22/2 + TBS 4/2 + TBS 2/14 + TBS 0/1 + TBS 22/5 + TBS 3/3 + TBS 22/7 + TBS 22/24 + TBS 2/2 + TBS 23/3 + TBS 3/4 + TBS 2/18 + TBS 0b/2 + TBS 22/1 + TBS 4/7 + TBS 2/6 + TBS 21/2 + TBS 22/6 + TBS 2/1 + + + + CCP 12/7 CCP 17/3 CCP 17/13 @@ -1365,7 +1328,46 @@ CCP 15/7 CCP 11/10 CCP 13/9 - CCP 14/5 + CCP 14/8 + CCP 6/2 + CCP 14/3 + CCP 12/3 + CCP 12/19 + CCP 14/14 + CCP 13/11 + CCP 12/20 + CCP 11/6 + CCP 13/14 + CCP 17/7 + CCP 11/9 + CCP 12/21 + CCP 12/14 + CCP 15/2 + CCP 1/2 + CCP 13/13 + CCP 15/14 + CCP 13/3 + CCP 11/12 + CCP 11/3 + CCP 13/1 + CCP 14/7 + CCP 14/20 + CCP 12/5 + CCP 12/9 + CCP 11/4 + CCP 13/16 + CCP 17/12 + CCP 12/18 + CCP 6/7 + CCP 11/14 + CCP 17/2 + CCP 14/11 + CCP 12/12 + CCP 10/1 + CCP 14/19 + CCP 15/4 + CCP 2/2 + CCP 11/16 CCP 17/14 CCP 17/6 CCP 6/4 @@ -1381,32 +1383,29 @@ CCP 14/21 CCP 13/8 CCP 15/8 - CCP 14/1 - CCP 11/13 - CCP 13/14 - CCP 17/7 - CCP 11/9 - CCP 12/21 - CCP 12/14 - CCP 15/2 - CCP 1/2 - CCP 13/13 - CCP 15/14 - CCP 13/3 - CCP 11/12 - CCP 11/3 - CCP 13/1 - CCP 14/8 - CCP 6/2 - CCP 14/3 - CCP 12/3 - CCP 12/19 - CCP 14/14 - CCP 13/11 - CCP 12/20 - CCP 11/6 + CCP 14/10 + CCP 13/15 + CCP 14/2 + CCP 5/2 + CCP 15/6 + CCP 11/8 + CCP 14/9 + CCP 11/15 + CCP 13/12 + CCP 17/5 + CCP 11/1 + CCP 17/10 + CCP 1/1 + CCP 6/1 + CCP 13/7 + CCP 6/5 + CCP 17/4 CCP 17/15 CCP 12/13 + CCP 14/5 + CCP 14/1 + CCP 11/13 + CCP 12/1 CCP 12/17 CCP 11/2 CCP 17/9 @@ -1421,42 +1420,38 @@ - CSIS 2a/1 - CSIS 2/1 - CSIS 3/6 - CSIS 1/2 - CSIS 3/3 CSIS 2/2 CSIS 2/6 CSIS 0a/2 CSIS 3/1 - CSIS 5/1 - CSIS 3/4 + CSIS 2/7 + CSIS 1/2 + CSIS 3/3 + CSIS 2a/1 + CSIS 2/1 + CSIS 3/6 CSIS 2/4 + CSIS 2/3 CSIS 2/5 + CSIS 5/1 + CSIS 3/4 CSIS 0/1 CSIS 2a/2 CSIS 3/2 - CSIS 2/3 - CSIP 12/5 - CSIP 14/16 - CSIP 12/1 - CSIP 11/3 - CSIP 6/4 - CSIP 11/1 - CSIP 11/4 CSIP 12/2 CSIP 6/15 CSIP 6/9 CSIP 6/1 CSIP 5/5 - CSIP 6/16 - CSIP 14/6 - CSIP 12/4 + CSIP 13/10 + CSIP 5/1 + CSIP 4/2 + CSIP 9/2 + CSIP 14/4 CSIP 14/2 CSIP 13/6 CSIP 5/2 @@ -1466,21 +1461,34 @@ CSIP 14/5 CSIP 13/9 CSIP 13/4 - CSIP 13/10 - CSIP 5/1 - CSIP 4/2 - CSIP 9/2 - CSIP 14/4 - CSIP 13/1 - CSIP 6/6 - CSIP 13/11 - CSIP 2/2 + CSIP 12/5 + CSIP 14/16 + CSIP 12/1 + CSIP 11/3 + CSIP 6/4 + CSIP 11/1 + CSIP 5/6 + CSIP 11/4 + CSIP 5/7 + CSIP 6/16 CSIP 6/8 + CSIP 14/6 + CSIP 12/4 + CSIP 1/1 + CSIP 6/7 + CSIP 1/2 + CSIP 11/2 + CSIP 14/3 + CSIP 5/8 CSIP 6/3 CSIP 13/5 CSIP 14/8 CSIP 13/2 CSIP 13/7 + CSIP 13/1 + CSIP 6/6 + CSIP 13/11 + CSIP 2/2 CSIP 14/9 CSIP 5/4 CSIP 6/2 @@ -1490,26 +1498,10 @@ CSIP 12/3 CSIP 13/3 CSIP 3/1 - CSIP 1/1 - CSIP 6/7 - CSIP 1/2 - CSIP 11/2 - CSIP 14/3 - PACS 4/4 - PACS 3/2 - PACS 6/3 - PACS 4/6 - PACS 4/2 - PACS 3/3 - PACS 6/1 - PACS 5/1 - PACS 4/8 - PACS 6/7 - PACS 3/6 PACS 4/5 PACS 4/11 PACS 3/4 @@ -1517,32 +1509,41 @@ PACS 4/3 PACS 3/1 PACS 4/14 - PACS 4/15 - PACS 4/1 - PACS 4/13 - PACS 4/7 + PACS 4/8 + PACS 6/7 + PACS 3/6 PACS 4/12 PACS 0/1 PACS 6/2 PACS 3/5 PACS 4/16 PACS 6/5 - PACS 2/2 PACS 4/9 PACS 4/10 PACS 6/4 + PACS 6/3 + PACS 4/6 + PACS 4/2 + PACS 3/3 + PACS 6/1 + PACS 5/1 + PACS 4/4 + PACS 3/2 + PACS 2/2 + PACS 4/15 + PACS 4/1 + PACS 4/13 + PACS 4/7 - ASCS 9/3 - ASCS 7/1 - ASCS 0/1 - ASCS 6/2 - ASCS 8/1 - ASCS 6/1 - ASCS 6/9 - ASCS 4/1 + ASCS 9/2 + ASCS 9/9 + ASCS 4/3 + ASCS 3/1 + ASCS 5/1 + ASCS 9/4 ASCS 7/3 ASCS 9/5 ASCS 7/5 @@ -1550,12 +1551,6 @@ ASCS 2/2 ASCS 9/6 ASCS 6/4 - ASCS 9/2 - ASCS 9/9 - ASCS 4/3 - ASCS 3/1 - ASCS 5/1 - ASCS 9/4 ASCS 6/3 ASCS 7/2 ASCS 6/8 @@ -1564,6 +1559,14 @@ ASCS 5/3 ASCS 6/6 ASCS 5/2 + ASCS 6/2 + ASCS 8/1 + ASCS 6/1 + ASCS 6/9 + ASCS 4/1 + ASCS 9/3 + ASCS 7/1 + ASCS 0/1 ASCS 6/7 ASCS 7/4 ASCS 9/7 @@ -1573,23 +1576,23 @@ - BASS 3/4 - BASS 2/2 - BASS 4/4 - BASS 5/1 - BASS 4/5 BASS 5/8 BASS 3/3 BASS 4/3 - BASS 5/5 - BASS 5/4 + BASS 3/2a + BASS 5/3 + BASS 1/1 BASS 4/6 BASS 4/2 BASS 0/1 BASS 3/1 - BASS 3/2a - BASS 5/3 - BASS 1/1 + BASS 3/4 + BASS 2/2 + BASS 4/4 + BASS 5/5 + BASS 5/4 + BASS 5/1 + BASS 4/5 BASS 5/2 BASS 5/6 BASS 3/5 @@ -1599,122 +1602,64 @@ - BAP 44/13 - BAP 10/1 - BAP 89/13 - BAP 68/11 - BAP 9a/6 - BAP 21/9 - BAP 88/3 - BAP 1/4 - BAP 51/4 - BAP 7/7 - BAP 21/12 - BAP 40/2 - BAP 73/9 - BAP 21/8 - BAP 29/1 - BAP 21/11 - BAP 36/6 - BAP 60/1 - BAP 39/7 - BAP 76/3 - BAP 21/4 - BAP 92/7 - BAP 16/6 - BAP 36/11 - BAP 45/9 - BAP 55/1 - BAP 16/16 - BAP 44/10 - BAP 55/15 - BAP 65/3 - BAP 76/4 - BAP 39/13 - BAP 16/7 - BAP 37/4 - BAP 22/3 - BAP 59/1 - BAP 92/3 - BAP 59/10 - BAP 80/10 - BAP 34/5 - BAP 60/2 - BAP 37/11 - BAP 59/8 - BAP 12/14 - BAP 23/4 - BAP 38/14 - BAP 68/17 - BAP 40/12 - BAP 74/11 - BAP 14/7 - BAP 73/4 - BAP 45/10 - BAP 17/15 - BAP 38/16 - BAP 36/4 - BAP 90/23 - BAP 76/1 - BAP 66/2 - BAP 89/2 - BAP 38/9 - BAP 38/4 - BAP 69/11 - BAP 39/4 - BAP 32/5 - BAP 14/8 - BAP 56/14 - BAP 54/11 - BAP 11/1 - BAP 69/9 - BAP 41/8 - BAP 56/10 - BAP 63/3 - BAP 74/4 - BAP 46/9 - BAP 22/2 - BAP 25/3 - BAP 80/1 - BAP 38/13 - BAP 12/9 - BAP 16/4 - BAP 13/7 - BAP 62/1 - BAP 68/8 - BAP 40/4 - BAP 9/6 - BAP 37/17 - BAP 56/2 - BAP 17/5 - BAP 80/5 - BAP 70/6 - BAP 17/13 - BAP 67/3 - BAP 20/11 - BAP 32/6 - BAP 90/20 - BAP 23/1 - BAP 84/3 - BAP 73/5 - BAP 28/4 - BAP 20/2 - BAP 55/2 - BAP 76/2 - BAP 20/3 - BAP 7/1 - BAP 13/1 - BAP 9a/3 - BAP 33a/2 - BAP 32/2 - BAP 13/13 - BAP 37/13 - BAP 35/2 - BAP 13/14 - BAP 13/12 - BAP 59/4 - BAP 94/2 - BAP 54/5 + BAP 70/11 + BAP 14/11 + BAP 54/4 + BAP 44/9 + BAP 20/4 + BAP 39/12 + BAP 92/6 + BAP 90/4 + BAP 16/8 + BAP 15/15 + BAP 54/17 + BAP 82/1 + BAP 13/8 + BAP 40/9 + BAP 45/6 + BAP 96/2 + BAP 90/2 + BAP 73/2 + BAP 93/5 + BAP 1/3 + BAP 93/6 + BAP 21/2 + BAP 13/16 + BAP 36/5 + BAP 61/1 + BAP 7/9 + BAP 40/6 + BAP 32/10 + BAP 59/12 + BAP 40/15 + BAP 13/5 + BAP 95/3 + BAP 95/2 + BAP 34/4 + BAP 73/12 + BAP 33/4 + BAP 23/21 + BAP 70/5 + BAP 45/8 + BAP 54/14 + BAP 12/12 + BAP 37/15 + BAP 40/14 + BAP 22/7 + BAP 41/14 + BAP 39/5 + BAP 12/4 + BAP 45/13 + BAP 17/10 + BAP 12/10 + BAP 89/10 + BAP 87/3 + BAP 9/2 + BAP 33a/1 + BAP 16/13 + BAP 89/7 + BAP 69/2 + BAP 13/11 BAP 36/7 BAP 53/1 BAP 54/12 @@ -1805,94 +1750,37 @@ BAP 52/5 BAP 68/7 BAP 44/4 - BAP 56/11 - BAP 74/9 - BAP 70/8 - BAP 68/5 - BAP 33/3 - BAP 37/2 - BAP 54/3 - BAP 93/2 - BAP 1/6 - BAP 7/3 - BAP 88/4 - BAP 55/16 - BAP 21/1 - BAP 20/5 - BAP 14/16 - BAP 41/9 - BAP 37/6 - BAP 80/14 - BAP 80/2 - BAP 59/3 - BAP 44/14 - BAP 31/6 - BAP 68/14 - BAP 33a/6 - BAP 34/1 - BAP 70/11 - BAP 14/11 - BAP 54/4 - BAP 44/9 - BAP 20/4 - BAP 39/12 - BAP 92/6 - BAP 90/4 - BAP 16/8 - BAP 15/15 - BAP 54/17 - BAP 82/1 - BAP 13/8 - BAP 40/9 - BAP 45/6 - BAP 96/2 - BAP 90/2 - BAP 73/2 - BAP 93/5 - BAP 1/3 - BAP 93/6 - BAP 21/2 - BAP 13/16 - BAP 36/5 - BAP 61/1 - BAP 7/9 - BAP 40/6 - BAP 32/10 - BAP 59/12 - BAP 40/15 - BAP 13/5 - BAP 95/3 - BAP 95/2 - BAP 34/4 - BAP 73/12 - BAP 33/4 - BAP 70/5 - BAP 45/8 - BAP 54/14 - BAP 12/12 - BAP 37/15 - BAP 40/14 - BAP 22/7 - BAP 41/14 - BAP 39/5 - BAP 12/4 - BAP 45/13 - BAP 17/10 - BAP 12/10 - BAP 89/10 - BAP 87/3 - BAP 9/2 - BAP 33a/1 - BAP 16/13 - BAP 89/7 - BAP 69/2 - BAP 13/11 - BAP 23/5 + BAP 56/11 + BAP 74/9 + BAP 70/8 + BAP 68/5 + BAP 33/3 + BAP 37/2 + BAP 54/3 + BAP 93/2 + BAP 1/6 + BAP 7/3 + BAP 88/4 + BAP 55/16 + BAP 21/1 + BAP 20/5 + BAP 14/16 + BAP 41/9 + BAP 37/6 + BAP 80/14 + BAP 80/2 + BAP 59/3 + BAP 44/14 + BAP 31/6 + BAP 68/14 + BAP 33a/6 + BAP 34/1 BAP 33a/7 BAP 68/6 BAP 32/1 BAP 43/1 BAP 65/5 + BAP 74/12 BAP 20/9 BAP 39/9 BAP 15/13 @@ -1912,12 +1800,14 @@ BAP 22/9 BAP 88/5 BAP 16/5 + BAP 74/25 BAP 38/7 BAP 39/14 BAP 40/1 BAP 86/4 BAP 74/3 BAP 69/4 + BAP 45/16 BAP 69/14 BAP 26/1 BAP 61/5 @@ -1926,6 +1816,7 @@ BAP 22/12 BAP 41/11 BAP 72/1 + BAP 89/15 BAP 12/3 BAP 34/2 BAP 65/4 @@ -1940,11 +1831,6 @@ BAP 36/14 BAP 83/1 BAP 8/1 - BAP 33/2 - BAP 69/7 - BAP 57/1 - BAP 68/3 - BAP 70/3 BAP 38/5 BAP 38/11 BAP 22/8 @@ -2000,62 +1886,178 @@ BAP 23/19 BAP 14/6 BAP 12/15 - BAP 13/17 - BAP 61/4 - BAP 41/10 - BAP 56/3 - BAP 15/6 - BAP 17/16 - BAP 3/1 - BAP 15/7 - BAP 56/15 - BAP 9a/5 - BAP 14/14 - BAP 37/8 - BAP 41/5 - BAP 68/9 - BAP 90/15 - BAP 16/2 - BAP 89/4 - BAP 71/1 - BAP 95/5 - BAP 80/16 - BAP 68/2 - BAP 21/10 - BAP 90/3 - BAP 89/8 - BAP 45/12 - BAP 52/2 - BAP 70/15 - BAP 19/1 - BAP 59/5 - BAP 70/2 - BAP 44/15 - BAP 72/2 - BAP 14/12 - BAP 73/11 - BAP 54/6 - BAP 10/3 - BAP 45/14 - BAP 80/22 - BAP 54/8 - BAP 31/7 - BAP 88/1 - BAP 36/9 - BAP 17/7 - BAP 22/6 - BAP 68/4 - BAP 67/1 - BAP 38/12 - BAP 4/1 - BAP 70/4 - BAP 58/1 - BAP 73/1 - BAP 82/3 - BAP 55/7 - BAP 51/6 - BAP 17/4 - BAP 18/1 + BAP 66/2 + BAP 89/2 + BAP 38/9 + BAP 38/4 + BAP 69/11 + BAP 39/4 + BAP 32/5 + BAP 14/8 + BAP 56/14 + BAP 54/11 + BAP 11/1 + BAP 69/9 + BAP 41/8 + BAP 56/10 + BAP 63/3 + BAP 74/4 + BAP 46/9 + BAP 22/2 + BAP 25/3 + BAP 80/1 + BAP 38/13 + BAP 12/9 + BAP 16/4 + BAP 13/7 + BAP 62/1 + BAP 68/8 + BAP 40/4 + BAP 9/6 + BAP 37/17 + BAP 56/2 + BAP 17/5 + BAP 80/5 + BAP 70/6 + BAP 17/13 + BAP 67/3 + BAP 20/11 + BAP 32/6 + BAP 90/20 + BAP 23/1 + BAP 84/3 + BAP 73/5 + BAP 28/4 + BAP 20/2 + BAP 55/2 + BAP 76/2 + BAP 20/3 + BAP 7/1 + BAP 13/1 + BAP 9a/3 + BAP 33a/2 + BAP 32/2 + BAP 13/13 + BAP 37/13 + BAP 35/2 + BAP 13/14 + BAP 13/12 + BAP 59/4 + BAP 94/2 + BAP 44/13 + BAP 10/1 + BAP 89/13 + BAP 68/11 + BAP 9a/6 + BAP 21/9 + BAP 88/3 + BAP 1/4 + BAP 51/4 + BAP 7/7 + BAP 21/12 + BAP 40/2 + BAP 73/9 + BAP 21/8 + BAP 29/1 + BAP 21/11 + BAP 36/6 + BAP 60/1 + BAP 39/7 + BAP 76/3 + BAP 21/4 + BAP 92/7 + BAP 16/6 + BAP 36/11 + BAP 45/9 + BAP 55/1 + BAP 16/16 + BAP 44/10 + BAP 55/15 + BAP 65/3 + BAP 76/4 + BAP 39/13 + BAP 16/7 + BAP 37/4 + BAP 22/3 + BAP 59/1 + BAP 92/3 + BAP 59/10 + BAP 80/10 + BAP 34/5 + BAP 60/2 + BAP 37/11 + BAP 59/8 + BAP 12/14 + BAP 23/4 + BAP 38/14 + BAP 68/17 + BAP 40/12 + BAP 74/11 + BAP 14/7 + BAP 73/4 + BAP 45/10 + BAP 80/24 + BAP 17/15 + BAP 38/16 + BAP 36/4 + BAP 7/8 + BAP 93/4 + BAP 14/13 + BAP 23/10 + BAP 10/5 + BAP 69/16 + BAP 2/1 + BAP 14/10 + BAP 39/10 + BAP 37/1 + BAP 17/12 + BAP 55/5 + BAP 46/6 + BAP 30/3 + BAP 36/12 + BAP 36/17 + BAP 16/14 + BAP 51/1 + BAP 56/1 + BAP 44/8 + BAP 22/4 + BAP 32/7 + BAP 31/5 + BAP 58/3 + BAP 41/4 + BAP 9/1 + BAP 9/3 + BAP 33/6 + BAP 15/2 + BAP 52/1 + BAP 56/6 + BAP 12/5 + BAP 12/11 + BAP 56/16 + BAP 14/2 + BAP 13/2 + BAP 15/14 + BAP 54/13 + BAP 37/9 + BAP 36/2 + BAP 92/5 + BAP 32/9 + BAP 54/7 + BAP 40/8 + BAP 86/1 + BAP 41/6 + BAP 9a/4 + BAP 53/2 + BAP 80/13 + BAP 56/8 + BAP 93/3 + BAP 80/6 + BAP 41/1 + BAP 20/7 + BAP 33a/3 + BAP 14/4 + BAP 27/5 + BAP 34/3 BAP 74/1 BAP 20/8 BAP 16/1 @@ -2116,6 +2118,53 @@ BAP 70/10 BAP 79/2 BAP 56/7 + BAP 23/5 + BAP 65/1 + BAP 40/3 + BAP 69/3 + BAP 61/2 + BAP 17/3 + BAP 13/9 + BAP 15/1 + BAP 38/10 + BAP 10/4 + BAP 9a/8 + BAP 70/13 + BAP 67/2 + BAP 59/2 + BAP 55/9 + BAP 33/2 + BAP 69/7 + BAP 57/1 + BAP 68/3 + BAP 70/3 + BAP 61/6 + BAP 17/11 + BAP 35/1 + BAP 56/4 + BAP 49/1 + BAP 70/14 + BAP 44/6 + BAP 9/7 + BAP 29/2 + BAP 54/5 + BAP 13/17 + BAP 61/4 + BAP 41/10 + BAP 56/3 + BAP 15/6 + BAP 17/16 + BAP 3/1 + BAP 15/7 + BAP 56/15 + BAP 9a/5 + BAP 14/14 + BAP 37/8 + BAP 41/5 + BAP 68/9 + BAP 90/15 + BAP 16/2 + BAP 89/4 BAP 59/7 BAP 36/15 BAP 22/10 @@ -2128,6 +2177,7 @@ BAP 74/7 BAP 40/11 BAP 45/1 + BAP 46/17 BAP 68/12 BAP 69/6 BAP 54/10 @@ -2143,86 +2193,47 @@ BAP 38/15 BAP 13/4 BAP 41/2 - BAP 61/6 - BAP 17/11 - BAP 35/1 - BAP 56/4 - BAP 49/1 - BAP 70/14 - BAP 44/6 - BAP 9/7 - BAP 29/2 - BAP 65/1 - BAP 40/3 - BAP 69/3 - BAP 61/2 - BAP 17/3 - BAP 13/9 - BAP 15/1 - BAP 38/10 - BAP 10/4 - BAP 9a/8 - BAP 70/13 - BAP 67/2 - BAP 59/2 - BAP 55/9 - BAP 7/8 - BAP 93/4 - BAP 14/13 - BAP 23/10 - BAP 10/5 - BAP 69/16 - BAP 14/10 - BAP 39/10 - BAP 37/1 - BAP 17/12 - BAP 55/5 - BAP 46/6 - BAP 30/3 - BAP 36/12 - BAP 36/17 - BAP 16/14 - BAP 51/1 - BAP 56/1 - BAP 44/8 - BAP 22/4 - BAP 32/7 - BAP 31/5 - BAP 58/3 - BAP 41/4 - BAP 9/1 - BAP 9/3 - BAP 33/6 - BAP 15/2 - BAP 52/1 - BAP 56/6 - BAP 12/5 - BAP 12/11 - BAP 56/16 - BAP 14/2 - BAP 13/2 - BAP 15/14 - BAP 54/13 - BAP 37/9 - BAP 36/2 - BAP 92/5 - BAP 32/9 - BAP 54/7 - BAP 40/8 - BAP 86/1 - BAP 41/6 - BAP 9a/4 - BAP 53/2 - BAP 80/13 - BAP 56/8 - BAP 93/3 - BAP 80/6 - BAP 41/1 - BAP 20/7 - BAP 33a/3 - BAP 14/4 - BAP 27/5 - BAP 34/3 + BAP 90/23 + BAP 76/1 + BAP 71/1 + BAP 95/5 + BAP 80/16 + BAP 68/2 + BAP 21/10 + BAP 90/3 + BAP 89/8 + BAP 45/12 + BAP 52/2 + BAP 70/15 + BAP 19/1 + BAP 59/5 + BAP 70/2 + BAP 44/15 + BAP 72/2 + BAP 14/12 + BAP 73/11 + BAP 54/6 + BAP 10/3 + BAP 45/14 + BAP 80/22 + BAP 54/8 + BAP 31/7 + BAP 88/1 + BAP 36/9 + BAP 17/7 + BAP 22/6 + BAP 68/4 + BAP 67/1 + BAP 38/12 + BAP 4/1 + BAP 70/4 + BAP 58/1 + BAP 73/1 + BAP 82/3 + BAP 55/7 + BAP 51/6 + BAP 17/4 + BAP 18/1 BAP 51/5 BAP 7/5 BAP 46/5 @@ -2265,37 +2276,14 @@ - CAS 5/2 CAS 2/2 CAS 0/1 CAS 3/1 + CAS 5/2 - CAP 16/5 - CAP 1/3 - CAP 26/4 - CAP 10/1 - CAP 22/7 - CAP 9/1 - CAP 11/10 - CAP 16/1 - CAP 22/3 - CAP 23a/3 - CAP 30/4 - CAP 19/4 - CAP 26/5 - CAP 20/3 - CAP 11/5 - CAP 26/7 - CAP 22/4 - CAP 5/1 - CAP 16/4 - CAP 6/8 - CAP 20/6 - CAP 7/5 - CAP 17/1 CAP 11/11 CAP 1/1 CAP 12/1 @@ -2307,6 +2295,7 @@ CAP 3/1 CAP 20/1 CAP 28/2 + CAP 28/4 CAP 28/7 CAP 11/3 CAP 22/5 @@ -2325,47 +2314,14 @@ CAP 14/1 CAP 8/2 CAP 33a/2 + CAP 20/8 CAP 33a/1 CAP 7/2 CAP 8/1 CAP 33a/3 CAP 8/4 - CAP 28/11 - CAP 7/1 - CAP 19/1 - CAP 33/2 - CAP 21/3 - CAP 24/1 - CAP 18/1 - CAP 25/1 - CAP 1/2 - CAP 22/11 - CAP 33/1 - CAP 11/8 - CAP 26/1 - CAP 6b/1 - CAP 10/2 - CAP 21/2 - CAP 23/1 - CAP 31/2 - CAP 30/2 - CAP 11/6 - CAP 7/7 - CAP 11/9 - CAP 6/2 - CAP 2/2 - CAP 16/2 - CAP 19/2 - CAP 23a/2 - CAP 22/2 - CAP 22/12 - CAP 23a/4 - CAP 7/3 - CAP 29/1 - CAP 17/5 - CAP 16/6 - CAP 28/10 - CAP 11/4 + CAP 6a/3 + CAP 21/4 CAP 22/1 CAP 28/1 CAP 26/6 @@ -2375,13 +2331,78 @@ CAP 30/3 CAP 27/1 CAP 6/6 + CAP 27/2 CAP 15/1 CAP 6/5 CAP 6a/1 CAP 20/4 CAP 22/6 CAP 11/1 + CAP 2/2 + CAP 16/2 + CAP 19/2 + CAP 23a/2 + CAP 22/2 + CAP 8/6 + CAP 22/12 + CAP 23a/4 + CAP 7/3 + CAP 29/1 + CAP 17/5 + CAP 16/6 + CAP 28/10 + CAP 11/4 + CAP 16/5 + CAP 1/3 + CAP 26/4 + CAP 10/1 + CAP 27/3 + CAP 22/7 + CAP 9/1 + CAP 11/10 + CAP 16/1 + CAP 22/3 + CAP 23a/3 + CAP 30/4 + CAP 19/4 + CAP 28/11 + CAP 7/1 + CAP 19/1 + CAP 33/2 + CAP 24/1 + CAP 18/1 + CAP 20/7 + CAP 25/1 + CAP 8/5 + CAP 1/2 + CAP 22/11 + CAP 33/1 + CAP 11/8 + CAP 26/1 + CAP 6b/1 + CAP 6a/4 + CAP 10/2 + CAP 21/2 + CAP 23/1 + CAP 31/2 + CAP 30/2 + CAP 11/6 + CAP 7/7 + CAP 11/9 + CAP 6/2 + CAP 26/5 + CAP 20/3 + CAP 11/5 + CAP 26/7 + CAP 22/4 + CAP 5/1 + CAP 16/4 + CAP 6/8 + CAP 20/6 + CAP 7/5 + CAP 17/1 CAP 18/2 + CAP 28/3 CAP 6/1 CAP 6/7 CAP 7/6 @@ -2393,6 +2414,7 @@ CAP 31/3 CAP 31/1 CAP 22/9 + CAP 17/3 CAP 33a/4 CAP 11/2 CAP 28/6 @@ -2400,6 +2422,7 @@ CAP 22/10 CAP 30/1 CAP 21/1 + CAP 17/4 CAP 27/4 CAP 11/12 CAP 16/3 @@ -2407,73 +2430,57 @@ - HAS 4/10 - HAS 3/12 - HAS 3/5 - HAS 4/5 - HAS 5/7 - HAS 3/1 - HAS 4/7 - HAS 2/2 - HAS 3/4 - HAS 3/9 - HAS 3/13 - HAS 3/8 - HAS 3/3 - HAS 5/2 - HAS 5/3 - HAS 4/6 HAS 4/2 HAS 5/5 HAS 3/6 HAS 0/1 - HAS 3/14 + HAS 5/2 + HAS 5/3 + HAS 4/6 HAS 4/4 HAS 1/1 HAS 4/9 HAS 3/1a - HAS 5/4 - HAS 5/1 - HAS 4/1 - HAS 5/6 - HAS 3/10 + HAS 4/7 + HAS 2/2 + HAS 3/4 + HAS 3/9 + HAS 3/13 + HAS 3/8 + HAS 3/3 HAS 4/8 HAS 4/3 HAS 3/7 HAS 3/11 HAS 3/2 + HAS 4/10 + HAS 3/12 + HAS 3/5 + HAS 4/5 + HAS 5/7 + HAS 3/1 + HAS 5/4 + HAS 5/1 + HAS 4/1 + HAS 5/6 + HAS 3/10 + HAS 3/14 - HAP 12/3 - HAP 24/3 - HAP 19/1 - HAP 24/4 - HAP 14/1 - HAP 13/6 - HAP 50/3 - HAP 18/1 - HAP 1/1 - HAP 19/2 - HAP 24/2 - HAP 13/1 - HAP 43/4 - HAP 24/6 - HAP 13/5 - HAP 93/4 HAP 12/7 HAP 13/7 HAP 12/6 HAP 11/1 HAP 93/2 HAP 46/1 - HAP 12/5 - HAP 14/3 - HAP 13/2 - HAP 16/2 - HAP 13/3 - HAP 12/4 + HAP 24/2 + HAP 13/1 + HAP 43/4 + HAP 24/6 + HAP 13/5 + HAP 93/4 HAP 10/1 HAP 92/1 HAP 51/1 @@ -2483,6 +2490,22 @@ HAP 17/1 HAP 43/1 HAP 41/1 + HAP 13/6 + HAP 50/3 + HAP 18/1 + HAP 1/1 + HAP 19/2 + HAP 26/1 + HAP 93/1 + HAP 16/1 + HAP 24/1 + HAP 93/3 + HAP 2/2 + HAP 12/3 + HAP 24/3 + HAP 19/1 + HAP 24/4 + HAP 14/1 HAP 50/1 HAP 24/5 HAP 13/4 @@ -2496,101 +2519,16 @@ HAP 12/1 HAP 93/5 HAP 1/4 - HAP 26/1 - HAP 93/1 - HAP 16/1 - HAP 24/1 - HAP 93/3 - HAP 2/2 + HAP 12/5 + HAP 14/3 + HAP 13/2 + HAP 16/2 + HAP 13/3 + HAP 12/4 - TMAP 95/5 - TMAP 114/4 - TMAP 57/3 - TMAP 79/2 - TMAP 116/4 - TMAP 78/1 - TMAP 55/3 - TMAP 113/1 - TMAP 98/3 - TMAP 17/6 - TMAP 115/5 - TMAP 55/5 - TMAP 52/2 - TMAP 1/7 - TMAP 56/12 - TMAP 153/6 - TMAP 56/1 - TMAP 56/5 - TMAP 118/2 - TMAP 16/5 - TMAP 150/1 - TMAP 116/13 - TMAP 116/6 - TMAP 153/5 - TMAP 19/3 - TMAP 57/1 - TMAP 19/2 - TMAP 151/6 - TMAP 91/1 - TMAP 116/2 - TMAP 55/8 - TMAP 97/2 - TMAP 96/6 - TMAP 51/1 - TMAP 1/5 - TMAP 115/2 - TMAP 115/6 - TMAP 114/2 - TMAP 121/1 - TMAP 112/2 - TMAP 55/1 - TMAP 94/2 - TMAP 116/12 - TMAP 95/3 - TMAP 95/8 - TMAP 2/2 - TMAP 112/1 - TMAP 54/2 - TMAP 100/2 - TMAP 75/1 - TMAP 56/3 - TMAP 94/4 - TMAP 12/1 - TMAP 116/16 - TMAP 95/2 - TMAP 12/3 - TMAP 73/1 - TMAP 152/1 - TMAP 74/5 - TMAP 18/1 - TMAP 96/4 - TMAP 56/11 - TMAP 94/3 - TMAP 75/6 - TMAP 74/4 - TMAP 2/2a - TMAP 151/2 - TMAP 116/7 - TMAP 76/6 - TMAP 110/1 - TMAP 14/1 - TMAP 16/1 - TMAP 56/7 - TMAP 54/3 - TMAP 117/1 - TMAP 78/2 - TMAP 56/10 - TMAP 96/14 - TMAP 3/1 - TMAP 100/1 - TMAP 76/1 - TMAP 55/2 - TMAP 16/4 - TMAP 95/6 - TMAP 74/6 TMAP 57/2 TMAP 19/1 TMAP 96/16 @@ -2606,45 +2544,54 @@ TMAP 151/1 TMAP 115/4 TMAP 74/7 + TMAP 130/4 TMAP 131/1 TMAP 154/1 TMAP 118/1 + TMAP 36/3 TMAP 14/7 - TMAP 56/16 - TMAP 72/2 - TMAP 116/3 - TMAP 96/15 - TMAP 114/5 - TMAP 76/5 - TMAP 99/2 - TMAP 96/7 - TMAP 15/6 - TMAP 14/5 - TMAP 153/4 - TMAP 98/2 - TMAP 95/4 - TMAP 118/3 - TMAP 17/5 - TMAP 96/1 - TMAP 11/1 - TMAP 75/2 - TMAP 14/2 - TMAP 15/3 - TMAP 117/2 - TMAP 15/1 - TMAP 56/13 - TMAP 119/2 - TMAP 90/1 - TMAP 56/8 - TMAP 50/1 - TMAP 14/4 + TMAP 35/8 + TMAP 94/2 + TMAP 39/2 + TMAP 33/1 + TMAP 116/12 + TMAP 95/3 + TMAP 36/11 + TMAP 130/1 + TMAP 95/8 + TMAP 32/1 + TMAP 2/2 + TMAP 112/1 + TMAP 54/2 + TMAP 100/2 + TMAP 75/1 + TMAP 56/3 + TMAP 94/4 + TMAP 12/1 + TMAP 1/3 + TMAP 116/16 + TMAP 95/2 + TMAP 12/3 + TMAP 73/1 + TMAP 54/4 + TMAP 152/1 + TMAP 74/5 + TMAP 18/1 + TMAP 96/4 + TMAP 56/16 + TMAP 72/2 + TMAP 116/3 TMAP 116/10 TMAP 15/2 + TMAP 36/7 TMAP 96/8 TMAP 95/1 TMAP 96/11 TMAP 12/2 + TMAP 35/5 TMAP 55/7 + TMAP 34/6 + TMAP 38/2 TMAP 95/7 TMAP 76/3 TMAP 1/2 @@ -2656,170 +2603,380 @@ TMAP 55/4 TMAP 14/3 TMAP 76/4 + TMAP 36/15 TMAP 119/1 TMAP 1/6 + TMAP 34/7 TMAP 16/6 + TMAP 38/3 TMAP 52/1 TMAP 72/1 TMAP 15/5 TMAP 121/2 TMAP 77/2 + TMAP 79/1 + TMAP 116/5 + TMAP 96/12 + TMAP 94/1 + TMAP 35/3 + TMAP 116/1 + TMAP 1/4 + TMAP 97/1 + TMAP 15/4 + TMAP 115/1 + TMAP 56/6 + TMAP 78/3 + TMAP 36/5 + TMAP 56/4 + TMAP 116/15 + TMAP 74/3 + TMAP 14/6 + TMAP 153/3 + TMAP 54/1 + TMAP 76/2 + TMAP 156/1 TMAP 115/8 TMAP 96/9 TMAP 115/7 TMAP 74/8 TMAP 96/5 + TMAP 38/1 TMAP 17/3 + TMAP 52/2 + TMAP 1/7 + TMAP 41/1 + TMAP 56/12 + TMAP 153/6 + TMAP 56/1 + TMAP 56/5 + TMAP 118/2 + TMAP 16/5 + TMAP 150/1 + TMAP 116/13 + TMAP 116/6 + TMAP 153/5 + TMAP 19/3 + TMAP 57/1 + TMAP 19/2 + TMAP 151/6 + TMAP 91/1 + TMAP 116/2 + TMAP 55/8 + TMAP 36/13 + TMAP 97/2 + TMAP 96/6 + TMAP 51/1 + TMAP 1/5 + TMAP 115/2 + TMAP 115/6 + TMAP 31/1 + TMAP 34/4 + TMAP 36/8 + TMAP 114/2 + TMAP 36/4 + TMAP 34/5 + TMAP 121/1 + TMAP 112/2 + TMAP 55/1 + TMAP 95/5 + TMAP 114/4 + TMAP 57/3 + TMAP 79/2 + TMAP 116/4 + TMAP 78/1 + TMAP 55/3 + TMAP 113/1 + TMAP 98/3 + TMAP 56/11 + TMAP 94/3 + TMAP 75/6 + TMAP 36/12 + TMAP 74/4 + TMAP 2/2a + TMAP 151/2 + TMAP 17/6 + TMAP 115/5 + TMAP 39/1 + TMAP 55/5 + TMAP 37/1 + TMAP 116/7 + TMAP 76/6 + TMAP 110/1 + TMAP 36/2 + TMAP 14/1 + TMAP 16/1 + TMAP 56/7 + TMAP 54/3 + TMAP 117/1 + TMAP 78/2 + TMAP 30/1 + TMAP 56/10 + TMAP 96/14 + TMAP 3/1 + TMAP 100/1 + TMAP 76/1 + TMAP 55/2 + TMAP 16/4 + TMAP 35/4 + TMAP 95/6 + TMAP 74/6 + TMAP 20/1 TMAP 18/2 TMAP 56/14 + TMAP 36/6 TMAP 1/1 TMAP 115/3 TMAP 54/5 TMAP 1/8 TMAP 116/11 TMAP 70/1 + TMAP 36/10 + TMAP 130/3 + TMAP 34/2 TMAP 93/1 + TMAP 34/3 TMAP 96/13 TMAP 114/1 TMAP 75/4 TMAP 17/1 TMAP 77/1 + TMAP 32/2 TMAP 53/1 TMAP 120/1 TMAP 13/1 + TMAP 130/2 TMAP 55/6 TMAP 75/5 TMAP 96/10 + TMAP 35/6 TMAP 116/8 TMAP 98/1 TMAP 153/2 TMAP 92/1 TMAP 111/1 - TMAP 79/1 - TMAP 116/5 - TMAP 96/12 - TMAP 94/1 - TMAP 116/1 - TMAP 1/4 - TMAP 97/1 - TMAP 15/4 - TMAP 115/1 - TMAP 56/6 - TMAP 78/3 - TMAP 56/4 - TMAP 116/15 - TMAP 74/3 - TMAP 14/6 - TMAP 54/1 - TMAP 76/2 - TMAP 156/1 TMAP 96/3 TMAP 114/3 TMAP 16/2 TMAP 116/14 TMAP 56/15 + TMAP 40/2 TMAP 92/2 TMAP 99/1 TMAP 17/4 + TMAP 36/14 TMAP 56/2 TMAP 74/1 TMAP 151/5 TMAP 151/4 TMAP 94/5 + TMAP 32/3 + TMAP 96/15 + TMAP 114/5 + TMAP 76/5 + TMAP 34/1 + TMAP 99/2 + TMAP 96/7 + TMAP 15/6 + TMAP 14/5 + TMAP 153/4 + TMAP 98/2 + TMAP 95/4 + TMAP 118/3 + TMAP 35/7 + TMAP 17/5 + TMAP 36/16 + TMAP 35/2 + TMAP 36/9 + TMAP 96/1 + TMAP 11/1 + TMAP 75/2 + TMAP 36/1 + TMAP 14/2 + TMAP 15/3 + TMAP 117/2 + TMAP 15/1 + TMAP 56/13 + TMAP 40/1 + TMAP 35/1 + TMAP 119/2 + TMAP 90/1 + TMAP 56/8 + TMAP 50/1 + TMAP 14/4 - PBP 8/9 - PBP 12/2 - PBP 14/11 - PBP 6/6 - PBP 8/5 - PBP 11/1 - PBP 8/2 - PBP 14/1 - PBP 8/11 - PBP 8/1 - PBP 14/2 - PBP 6/5 - PBP 14/3 - PBP 6/3 - PBP 14/8 - PBP 1/2 - PBP 8/4 - PBP 13/3 - PBP 5/1 - PBP 15/1 - PBP 8/12 - PBP 4/1 + PBP 14a/1 PBP 14/10 PBP 12/1 PBP 1/1 - PBP 10/1 PBP 14/12 PBP 14/5 PBP 17/2 - PBP 6/8 - PBP 6/4 - PBP 7/2 - PBP 6/7 - PBP 7/1 - PBP 17/1 - PBP 14/7 + PBP 8/4 + PBP 13/3 + PBP 5/1 + PBP 15/1 + PBP 8/12 + PBP 4/2 PBP 8/10 PBP 11/2 + PBP 17a/1 PBP 13/2 PBP 2/2 PBP 8/8 + PBP 6/9 PBP 6/1 PBP 8/3 + PBP 7/4 + PBP 8/7 + PBP 1/3 + PBP 8/6 + PBP 14/6 + PBP 7/3 + PBP 8/5 + PBP 11/1 + PBP 8/2 + PBP 14/1 + PBP 8/11 + PBP 18/1 + PBP 8/1 + PBP 14/2 + PBP 6/5 + PBP 14/3 + PBP 6/3 + PBP 14/8 + PBP 1/2 + PBP 8/9 + PBP 16/2 + PBP 12/2 + PBP 10/2 + PBP 14/11 + PBP 6/6 PBP 13/4 PBP 14/4 PBP 5/2 PBP 14/9 PBP 13/1 - PBP 16/1 PBP 6/2 PBP 9/1 PBP 3/1 - PBP 7/4 - PBP 8/7 - PBP 1/3 - PBP 8/6 - PBP 14/6 - PBP 7/3 + PBP 6/8 + PBP 12/3 + PBP 6/4 + PBP 7/2 + PBP 6/7 + PBP 7/1 + PBP 17/1 + PBP 14/7 - MBT 3/1 MBT 20/2 - MBT 20/1 - MBT 3/2 MBT 0/1 MBT 10/1 MBT 10/2 + MBT 3/1 + MBT 20/1 + MBT 3/2 - DFU 3/2 + DFU 22/3 + DFU 30/1 DFU 10/1 DFU 3/1 DFU 21/1 - DFU 22/3 - DFU 30/1 + DFU 22/1 + DFU 3/2 DFU 3/3 DFU 11/1 DFU 0/1 DFU 20/1 DFU 11/2 DFU 21/2 - DFU 22/1 + GMAP 20/92 + GMAP 20/19 + GMAP 20/95 + GMAP 40/71 + GMAP 40/55 + GMAP 20/67 + GMAP 32/5 + GMAP 20/13 + GMAP 42/1 + GMAP 62/1 + GMAP 32/7 + GMAP 74/1 + GMAP 20/25 + GMAP 77/2 + GMAP 20/109 + GMAP 20/97 + GMAP 35/9 + GMAP 40/20 + GMAP 40/35 + GMAP 40/49 + GMAP 40/69 + GMAP 39/1 + GMAP 32/3 + GMAP 20/85 + GMAP 107/2 + GMAP 57/3 + GMAP 40/3 + GMAP 20/43 + GMAP 92/1 + GMAP 20/56 + GMAP 56/2 + GMAP 41/1 + GMAP 38/2 + GMAP 79/14 + GMAP 20/110 + GMAP 101/1 + GMAP 40/1 + GMAP 14/7 + GMAP 79/2 + GMAP 38/5 + GMAP 58/2 + GMAP 40/46 + GMAP 10/1 + GMAP 20/55 + GMAP 105/6 + GMAP 20/47 + GMAP 40/18 + GMAP 37/5 + GMAP 20/7 + GMAP 14/2 + GMAP 40/26 + GMAP 14/10 + GMAP 20/52 + GMAP 40/13 + GMAP 79/3 + GMAP 37/2 + GMAP 16/3 + GMAP 54/2 + GMAP 14/5 + GMAP 79/12 + GMAP 15/2 + GMAP 60/1 + GMAP 14/8 + GMAP 20/9 + GMAP 35/6 + GMAP 56/1 + GMAP 20/91 + GMAP 20/96 + GMAP 58/1 + GMAP 20/66 + GMAP 105/4 + GMAP 54/3 + GMAP 57/4 + GMAP 59/10 + GMAP 20/21 GMAP 20/63 GMAP 20/80 GMAP 16/2 @@ -2827,6 +2984,7 @@ GMAP 11/1 GMAP 40/42 GMAP 20/1 + GMAP 78/2 GMAP 35/12 GMAP 14/12 GMAP 37/1 @@ -2858,86 +3016,6 @@ GMAP 20/99 GMAP 108/1 GMAP 36/4 - GMAP 2/2 - GMAP 40/5 - GMAP 20/102 - GMAP 59/4 - GMAP 20/94 - GMAP 102/1 - GMAP 77/1 - GMAP 20/59 - GMAP 40/43 - GMAP 20/12 - GMAP 104/2 - GMAP 36/5 - GMAP 14/11 - GMAP 40/70 - GMAP 104/1 - GMAP 20/93 - GMAP 59/3 - GMAP 20/44 - GMAP 34/2 - GMAP 38/4 - GMAP 40/9 - GMAP 40/10 - GMAP 20/34 - GMAP 20/2 - GMAP 20/106 - GMAP 35/3 - GMAP 20/112 - GMAP 20/113 - GMAP 79/5 - GMAP 52/1 - GMAP 102/3 - GMAP 20/6 - GMAP 22/1 - GMAP 16/4 - GMAP 20/100 - GMAP 50/1 - GMAP 40/41 - GMAP 20/3 - GMAP 20/23 - GMAP 17/3 - GMAP 20/18 - GMAP 79/7 - GMAP 35/11 - GMAP 20/65 - GMAP 75/2 - GMAP 38/1 - GMAP 94/1 - GMAP 92/4 - GMAP 40/60 - GMAP 105/2 - GMAP 103/2 - GMAP 17/2 - GMAP 20/107 - GMAP 20/77 - GMAP 74/2 - GMAP 20/37 - GMAP 18/1 - GMAP 79/10 - GMAP 20/92 - GMAP 20/19 - GMAP 20/95 - GMAP 40/71 - GMAP 40/55 - GMAP 20/67 - GMAP 32/5 - GMAP 20/13 - GMAP 42/1 - GMAP 62/1 - GMAP 32/7 - GMAP 74/1 - GMAP 20/25 - GMAP 77/2 - GMAP 20/109 - GMAP 20/97 - GMAP 35/9 - GMAP 40/20 - GMAP 40/35 - GMAP 40/49 - GMAP 40/69 - GMAP 39/1 GMAP 20/32 GMAP 34/5 GMAP 90/1 @@ -2950,71 +3028,6 @@ GMAP 40/22 GMAP 1/3 GMAP 77/3 - GMAP 14/4 - GMAP 20/82 - GMAP 20/24 - GMAP 32/2 - GMAP 34/3 - GMAP 20/90 - GMAP 20/71 - GMAP 20/41 - GMAP 92/5 - GMAP 40/23 - GMAP 76/2 - GMAP 20/11 - GMAP 102/4 - GMAP 18/2 - GMAP 40/44 - GMAP 40/12 - GMAP 1/2 - GMAP 20/54 - GMAP 40/17 - GMAP 20/42 - GMAP 40/15 - GMAP 79/16 - GMAP 40/38 - GMAP 20/40 - GMAP 36/2 - GMAP 75/1 - GMAP 59/8 - GMAP 40/7 - GMAP 20/73 - GMAP 40/32 - GMAP 18/6 - GMAP 56/4 - GMAP 93/4 - GMAP 103/4 - GMAP 40/19 - GMAP 40/39 - GMAP 20/84 - GMAP 93/2 - GMAP 40/6 - GMAP 20/15 - GMAP 20/105 - GMAP 40/61 - GMAP 54/1 - GMAP 82/1 - GMAP 20/60 - GMAP 40/66 - GMAP 40/31 - GMAP 20/87 - GMAP 16/1 - GMAP 20/76 - GMAP 71/1 - GMAP 110/1 - GMAP 15/1 - GMAP 76/3 - GMAP 40/30 - GMAP 20/68 - GMAP 20/86 - GMAP 21/1 - GMAP 20/8 - GMAP 74/3 - GMAP 40/11 - GMAP 36/3 - GMAP 104/3 - GMAP 20/83 - GMAP 17/5 GMAP 70/1 GMAP 20/62 GMAP 20/28 @@ -3047,69 +3060,41 @@ GMAP 40/29 GMAP 40/56 GMAP 79/1 - GMAP 59/6 - GMAP 20/88 - GMAP 20/22 - GMAP 76/4 - GMAP 59/11 - GMAP 20/16 - GMAP 20/78 - GMAP 35/2 - GMAP 34/4 - GMAP 111/1 - GMAP 20/64 - GMAP 20/57 - GMAP 20/111 - GMAP 31/1 - GMAP 59/5 - GMAP 38/6 - GMAP 105/7 - GMAP 20/31 - GMAP 20/103 - GMAP 14/1 - GMAP 59/9 - GMAP 14/6 - GMAP 12/3 - GMAP 35/1 - GMAP 79/8 - GMAP 20/79 - GMAP 79/2 - GMAP 38/5 - GMAP 58/2 - GMAP 40/46 - GMAP 10/1 - GMAP 20/55 - GMAP 105/6 - GMAP 20/47 - GMAP 40/18 - GMAP 37/5 - GMAP 20/7 - GMAP 14/2 - GMAP 40/26 - GMAP 14/10 - GMAP 20/52 - GMAP 40/13 - GMAP 79/3 - GMAP 37/2 - GMAP 16/3 - GMAP 54/2 - GMAP 14/5 - GMAP 79/12 - GMAP 15/2 - GMAP 60/1 - GMAP 14/8 - GMAP 20/9 - GMAP 35/6 - GMAP 56/1 - GMAP 20/91 - GMAP 20/96 - GMAP 58/1 - GMAP 20/66 - GMAP 105/4 - GMAP 54/3 - GMAP 57/4 - GMAP 59/10 - GMAP 20/21 + GMAP 102/1 + GMAP 77/1 + GMAP 20/59 + GMAP 40/43 + GMAP 20/12 + GMAP 104/2 + GMAP 36/5 + GMAP 14/11 + GMAP 40/70 + GMAP 104/1 + GMAP 20/105 + GMAP 40/61 + GMAP 54/1 + GMAP 82/1 + GMAP 20/60 + GMAP 40/66 + GMAP 40/31 + GMAP 20/87 + GMAP 16/1 + GMAP 20/76 + GMAP 71/1 + GMAP 110/1 + GMAP 15/1 + GMAP 76/3 + GMAP 40/30 + GMAP 20/68 + GMAP 20/86 + GMAP 21/1 + GMAP 20/8 + GMAP 74/3 + GMAP 40/11 + GMAP 36/3 + GMAP 104/3 + GMAP 20/83 + GMAP 17/5 GMAP 107/1 GMAP 20/53 GMAP 20/104 @@ -3118,6 +3103,83 @@ GMAP 20/69 GMAP 40/48 GMAP 40/28 + GMAP 20/44 + GMAP 34/2 + GMAP 38/4 + GMAP 40/9 + GMAP 40/10 + GMAP 20/34 + GMAP 20/2 + GMAP 20/106 + GMAP 35/3 + GMAP 20/112 + GMAP 20/113 + GMAP 79/5 + GMAP 52/1 + GMAP 102/3 + GMAP 20/6 + GMAP 22/1 + GMAP 16/4 + GMAP 20/100 + GMAP 50/1 + GMAP 40/41 + GMAP 20/3 + GMAP 20/23 + GMAP 17/3 + GMAP 20/18 + GMAP 79/7 + GMAP 35/11 + GMAP 20/65 + GMAP 75/2 + GMAP 38/1 + GMAP 94/1 + GMAP 92/4 + GMAP 40/60 + GMAP 105/2 + GMAP 103/2 + GMAP 17/2 + GMAP 20/107 + GMAP 20/77 + GMAP 74/2 + GMAP 20/37 + GMAP 18/1 + GMAP 79/10 + GMAP 40/65 + GMAP 59/1 + GMAP 40/50 + GMAP 40/67 + GMAP 20/50 + GMAP 40/34 + GMAP 40/63 + GMAP 38/3 + GMAP 33/1 + GMAP 20/39 + GMAP 40/52 + GMAP 20/98 + GMAP 16/6 + GMAP 19/1 + GMAP 105/5 + GMAP 18/3 + GMAP 20/61 + GMAP 12/2 + GMAP 40/25 + GMAP 93/5 + GMAP 77/4 + GMAP 35/10 + GMAP 40/72 + GMAP 20/10 + GMAP 13/1 + GMAP 78/1 + GMAP 20/26 + GMAP 93/1 + GMAP 35/7 + GMAP 2/2 + GMAP 40/5 + GMAP 20/102 + GMAP 59/4 + GMAP 20/94 + GMAP 20/93 + GMAP 59/3 GMAP 20/33 GMAP 20/29 GMAP 79/6 @@ -3176,74 +3238,97 @@ GMAP 92/3 GMAP 91/1 GMAP 20/72 - GMAP 32/3 - GMAP 20/85 - GMAP 107/2 - GMAP 57/3 - GMAP 40/3 - GMAP 20/43 - GMAP 92/1 - GMAP 20/56 - GMAP 56/2 - GMAP 41/1 - GMAP 38/2 - GMAP 79/14 - GMAP 20/110 - GMAP 101/1 - GMAP 40/1 - GMAP 14/7 - GMAP 40/65 - GMAP 59/1 - GMAP 40/50 - GMAP 40/67 - GMAP 20/50 - GMAP 40/34 - GMAP 40/63 - GMAP 38/3 - GMAP 33/1 - GMAP 20/39 - GMAP 40/52 - GMAP 20/98 - GMAP 16/6 - GMAP 19/1 - GMAP 105/5 - GMAP 18/3 - GMAP 20/61 - GMAP 12/2 - GMAP 40/25 - GMAP 93/5 - GMAP 77/4 - GMAP 35/10 - GMAP 40/72 - GMAP 20/10 - GMAP 13/1 - GMAP 20/26 - GMAP 93/1 - GMAP 35/7 + GMAP 14/4 + GMAP 20/82 + GMAP 20/24 + GMAP 32/2 + GMAP 34/3 + GMAP 20/90 + GMAP 20/71 + GMAP 20/41 + GMAP 92/5 + GMAP 40/23 + GMAP 76/2 + GMAP 20/11 + GMAP 102/4 + GMAP 18/2 + GMAP 40/44 + GMAP 40/12 + GMAP 1/2 + GMAP 20/54 + GMAP 40/17 + GMAP 20/42 + GMAP 40/15 + GMAP 79/16 + GMAP 40/38 + GMAP 20/40 + GMAP 36/2 + GMAP 75/1 + GMAP 59/8 + GMAP 40/7 + GMAP 20/73 + GMAP 40/32 + GMAP 18/6 + GMAP 56/4 + GMAP 93/4 + GMAP 103/4 + GMAP 40/19 + GMAP 40/39 + GMAP 20/84 + GMAP 93/2 + GMAP 40/6 + GMAP 20/15 + GMAP 59/6 + GMAP 20/88 + GMAP 20/22 + GMAP 76/4 + GMAP 59/11 + GMAP 20/16 + GMAP 20/78 + GMAP 35/2 + GMAP 34/4 + GMAP 111/1 + GMAP 20/64 + GMAP 20/57 + GMAP 20/111 + GMAP 31/1 + GMAP 59/5 + GMAP 38/6 + GMAP 105/7 + GMAP 20/31 + GMAP 20/103 + GMAP 14/1 + GMAP 59/9 + GMAP 14/6 + GMAP 12/3 + GMAP 35/1 + GMAP 79/8 + GMAP 20/79 - CORE 11/6 - CORE 20a/1 - CORE 2b/60 - CORE 20/4 - CORE 2a/50 - CORE 11/2 CORE 2a/54 CORE 2a/51 CORE 41/2 CORE 11/5 CORE 2a/52 - CORE 2/60 - CORE 40/2 - CORE 11/3 CORE 2b/61 CORE 12/3 + CORE 40/2 + CORE 11/3 + CORE 11/6 + CORE 20a/1 + CORE 2b/60 + CORE 20/4 + CORE 2a/50 + CORE 2b/62 + CORE 2/60 + CORE 2/1 + CORE 11/2 CORE 11/1 CORE 2a/60 CORE 12/1 - CORE 2/1 CORE 2a/53 CORE 31/2 @@ -3255,28 +3340,28 @@ - IOPT 2/16b - IOPT 2/33b - IOPT 2/6b - IOPT 2a/2 - IOPT 2/29b - IOPT 2/44b - IOPT 2/35b + IOPT 2/63b + IOPT 2/19b + IOPT 2/28b IOPT 2/7b IOPT 2/59b IOPT 2/5b IOPT 2/53b - IOPT 2/63b - IOPT 2/19b - IOPT 2/28b - IOPT 2/30b - IOPT 2/55b IOPT 2/2b - IOPT 2/58b + IOPT 2/6b + IOPT 2a/2 + IOPT 2/29b + IOPT 2/44b + IOPT 2/35b IOPT 2/45b IOPT 2/42b IOPT 2/12b + IOPT 2/16b + IOPT 2/33b + IOPT 2/58b + IOPT 2/30b + IOPT 2/55b - + \ No newline at end of file diff --git a/tests/bluetooth/qualification/ICS_Zephyr_Bluetooth_Host.pts b/tests/bluetooth/qualification/ICS_Zephyr_Bluetooth_Host.pts index 38a5a2dfa67c..192555599d24 100644 --- a/tests/bluetooth/qualification/ICS_Zephyr_Bluetooth_Host.pts +++ b/tests/bluetooth/qualification/ICS_Zephyr_Bluetooth_Host.pts @@ -1,6 +1,6 @@  - 376799 + 347313 Zephyr Host @@ -105,6 +105,10 @@ 8a
18 + + 27b
+ 12 +
35
15 @@ -241,6 +245,14 @@ 25
13
+ + 37b
+ 11 +
+ + 37b
+ 10 +
14a
2 @@ -261,6 +273,10 @@ 20A
18
+ + 0b
+ 2 +
37b
3 @@ -353,6 +369,10 @@ 14a
9
+ + 27b
+ 11 +
30a
9 @@ -437,10 +457,6 @@ 27c
3
- - 0
- 2 -
10
1 @@ -937,10 +953,6 @@ 35
10
- - 35
- 2 -
35
3 @@ -1200,6 +1212,10 @@ 4
1
+ + 0a
+ 2 +
2
40 @@ -1240,10 +1256,6 @@ 3
16
- - 0
- 2 -
1
3 @@ -1283,10 +1295,6 @@ 2
3a
- - 10
- 6 -
10
1 @@ -1551,10 +1559,6 @@ 4
12
- - 4
- 13 -
4
14 @@ -1647,14 +1651,6 @@ 7
4
- - 7
- 5 -
- - 7
- 6 -
7
7 @@ -1662,10 +1658,18 @@
SM + + 4a
+ 2 +
7a
1
+ + 2a
+ 2 +
7a
2 @@ -1679,53 +1683,37 @@ 2
- 7b
- 3 -
- - 7a
+ 4b
3
- 1
+ 4a
1
- 1
- 2 -
- - 2
+ 2a
1
- 2
- 2 -
- - 2
+ 4a
3
- 2
- 5 + 4b
+ 1
- 3
- 1 + 4b
+ 2
- 4
+ 1
1
- 4
+ 1
2
- - 4
- 3 -
5
1 @@ -1853,10 +1841,6 @@ 3
20
- - 3
- 21 -
3
22 @@ -1965,10 +1949,6 @@ 4
20
- - 4
- 21 -
4
22 @@ -3108,6 +3088,10 @@ 4
2
+ + 2
+ 10 +
3
4 @@ -3136,6 +3120,10 @@ 2
3
+ + 2
+ 9 +
2
4 @@ -3152,6 +3140,10 @@ 1
2
+ + 3
+ 3b +
2
5 @@ -5366,6 +5358,10 @@
CSIS + + 2
+ 7 +
2
2 @@ -5613,6 +5609,10 @@ 9
2
+ + 5
+ 6 +
11
4 @@ -5649,6 +5649,14 @@ 2
2
+ + 5
+ 8 +
+ + 5
+ 7 +
PACS @@ -6245,6 +6253,10 @@ 69
16 + + 2
+ 1 +
69
9 @@ -6345,6 +6357,10 @@ 21
12
+ + 74
+ 12 +
20
9 @@ -6953,6 +6969,10 @@ 33
1
+ + 23
+ 21 +
70
5 @@ -7033,6 +7053,10 @@ 56
2
+ + 74
+ 25 +
74
15 @@ -7285,6 +7309,10 @@ 16
9
+ + 45
+ 16 +
21
1 @@ -7525,6 +7553,10 @@ 23
1
+ + 80
+ 24 +
14
4 @@ -7545,6 +7577,10 @@ 28
4
+ + 89
+ 15 +
17
15 @@ -8269,6 +8305,10 @@ 45
1
+ + 46
+ 17 +
17
11 @@ -8735,6 +8775,10 @@ 12
1
+ + 28
+ 3 +
2
2 @@ -8851,6 +8895,10 @@ 22
2
+ + 27
+ 3 +
28
9 @@ -8875,10 +8923,6 @@ 26
7
- - 21
- 3 -
22
4 @@ -8915,6 +8959,14 @@ 8
2
+ + 20
+ 7 +
+ + 8
+ 6 +
5
1 @@ -8927,6 +8979,10 @@ 31
1
+ + 8
+ 5 +
1
2 @@ -8991,6 +9047,14 @@ 28
2
+ + 20
+ 8 +
+ + 17
+ 3 +
16
1 @@ -8999,6 +9063,10 @@ 7
3
+ + 6a
+ 4 +
33a
1 @@ -9007,6 +9075,10 @@ 10
2
+ + 28
+ 4 +
27
1 @@ -9067,6 +9139,10 @@ 31
2
+ + 27
+ 2 +
33a
3 @@ -9127,6 +9203,10 @@ 8
4
+ + 6a
+ 3 +
22
6 @@ -9151,6 +9231,14 @@ 16
6
+ + 17
+ 4 +
+ + 21
+ 4 +
23a
3 @@ -9576,6 +9664,10 @@
TMAP + + 32
+ 3 +
95
5 @@ -9584,6 +9676,14 @@ 114
4
+ + 35
+ 8 +
+ + 20
+ 1 +
52
2 @@ -9596,6 +9696,10 @@ 57
3
+ + 41
+ 1 +
94
2 @@ -9612,10 +9716,22 @@ 56
14
+ + 38
+ 2 +
79
1
+ + 39
+ 2 +
+ + 36
+ 6 +
79
2 @@ -9628,6 +9744,10 @@ 153
6
+ + 33
+ 1 +
57
2 @@ -9696,6 +9816,10 @@ 70
1
+ + 36
+ 10 +
96
16 @@ -9712,10 +9836,22 @@ 76
5
+ + 36
+ 11 +
+ + 130
+ 3 +
1
2
+ + 34
+ 2 +
93
1 @@ -9724,6 +9860,10 @@ 55
3
+ + 130
+ 1 +
95
8 @@ -9732,6 +9872,10 @@ 113
1
+ + 34
+ 1 +
96
12 @@ -9748,6 +9892,10 @@ 96
7
+ + 32
+ 1 +
94
1 @@ -9768,6 +9916,10 @@ 116
9
+ + 35
+ 3 +
2
2 @@ -9812,6 +9964,10 @@ 115
5
+ + 39
+ 1 +
55
5 @@ -9852,6 +10008,14 @@ 19
2
+ + 34
+ 3 +
+ + 37
+ 1 +
97
1 @@ -9928,10 +10092,18 @@ 14
3
+ + 36
+ 5 +
56
4
+ + 36
+ 2 +
76
4 @@ -9960,6 +10132,10 @@ 75
1
+ + 36
+ 15 +
94
6 @@ -9980,6 +10156,10 @@ 14
1
+ + 35
+ 7 +
16
1 @@ -10028,6 +10208,10 @@ 17
1
+ + 1
+ 3 +
1
6 @@ -10036,6 +10220,10 @@ 116
16
+ + 36
+ 13 +
95
2 @@ -10052,6 +10240,10 @@ 54
3
+ + 153
+ 3 +
97
2 @@ -10060,10 +10252,22 @@ 54
1
+ + 36
+ 16 +
+ + 32
+ 2 +
12
3
+ + 35
+ 2 +
115
4 @@ -10080,6 +10284,14 @@ 117
1
+ + 34
+ 7 +
+ + 130
+ 4 +
76
2 @@ -10108,6 +10320,10 @@ 120
1
+ + 54
+ 4 +
51
1 @@ -10120,6 +10336,10 @@ 16
6
+ + 36
+ 9 +
1
5 @@ -10160,6 +10380,10 @@ 115
6
+ + 38
+ 3 +
154
1 @@ -10168,6 +10392,14 @@ 114
3
+ + 30
+ 1 +
+ + 130
+ 2 +
118
1 @@ -10176,6 +10408,14 @@ 96
4
+ + 36
+ 3 +
+ + 31
+ 1 +
56
10 @@ -10184,10 +10424,18 @@ 55
6
+ + 36
+ 1 +
52
1
+ + 34
+ 4 +
75
5 @@ -10196,6 +10444,10 @@ 14
7
+ + 36
+ 8 +
14
2 @@ -10216,6 +10468,10 @@ 114
2
+ + 36
+ 4 +
94
3 @@ -10244,6 +10500,10 @@ 116
3
+ + 35
+ 6 +
15
1 @@ -10256,6 +10516,10 @@ 116
14
+ + 34
+ 5 +
116
8 @@ -10284,6 +10548,10 @@ 121
2
+ + 40
+ 2 +
77
2 @@ -10292,10 +10560,18 @@ 3
1
+ + 40
+ 1 +
15
2
+ + 36
+ 7 +
96
8 @@ -10320,6 +10596,10 @@ 115
7
+ + 36
+ 12 +
92
2 @@ -10344,10 +10624,18 @@ 12
2
+ + 35
+ 1 +
76
1
+ + 35
+ 5 +
99
1 @@ -10388,6 +10676,10 @@ 56
8
+ + 36
+ 14 +
16
4 @@ -10408,6 +10700,10 @@ 96
5
+ + 38
+ 1 +
17
3 @@ -10420,10 +10716,18 @@ 151
5
+ + 35
+ 4 +
92
1
+ + 34
+ 6 +
151
4 @@ -10467,6 +10771,10 @@ 6
8
+ + 12
+ 3 +
8
5 @@ -10499,10 +10807,18 @@ 11
2
+ + 17a
+ 1 +
13
2
+ + 14a
+ 1 +
8
7 @@ -10535,6 +10851,10 @@ 1
3
+ + 16
+ 2 +
12
1 @@ -10575,6 +10895,10 @@ 5
2
+ + 18
+ 1 +
14
6 @@ -10603,6 +10927,10 @@ 13
1
+ + 10
+ 2 +
1
1 @@ -10612,8 +10940,8 @@ 3
- 10
- 1 + 6
+ 9
6
@@ -10639,10 +10967,6 @@ 7
3
- - 16
- 1 -
1
2 @@ -10673,7 +10997,7 @@
4
- 1 + 2
17
@@ -10980,6 +11304,10 @@ 14
3
+ + 78
+ 2 +
92
1 @@ -12136,6 +12464,10 @@ 13
1
+ + 78
+ 1 +
59
5 @@ -12451,6 +12783,10 @@ 20
4
+ + 2b
+ 62 +
2a
60 From fc370b8481a54cb33a6a2bf9a2e9586ae71b94af Mon Sep 17 00:00:00 2001 From: Qingsong Gou Date: Fri, 5 Dec 2025 19:28:50 +0800 Subject: [PATCH 0227/3659] drivers: rtc: sf32lb: fix alarm_is_pending error Fix alarm_is_pending error Signed-off-by: Qingsong Gou --- drivers/rtc/rtc_sf32lb.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/rtc/rtc_sf32lb.c b/drivers/rtc/rtc_sf32lb.c index ad0ab0939507..e4b5deb3ab14 100644 --- a/drivers/rtc/rtc_sf32lb.c +++ b/drivers/rtc/rtc_sf32lb.c @@ -11,6 +11,7 @@ #include #include #include +#include #include @@ -59,6 +60,7 @@ struct rtc_sf32lb_alarm_cb { struct rtc_sf32lb_data { #ifdef CONFIG_RTC_ALARM struct rtc_sf32lb_alarm_cb alarm_cb; + ATOMIC_DEFINE(is_pending, 1); #endif }; @@ -79,7 +81,10 @@ static void rtc_irq_handler(const struct device *dev) if (isr & RTC_ISR_ALRMF) { sys_clear_bit(config->base + RTC_ISR, RTC_ISR_ALRMF_Pos); + #ifdef CONFIG_RTC_ALARM + atomic_set_bit(&data->is_pending, 0); + if (data->alarm_cb.cb) { data->alarm_cb.cb(dev, 0, data->alarm_cb.user_data); } @@ -308,18 +313,13 @@ static int rtc_sf32lb_alarm_get_time(const struct device *dev, uint16_t id, uint static int rtc_sf32lb_alarm_is_pending(const struct device *dev, uint16_t id) { - const struct rtc_sf32lb_config *config = dev->config; + struct rtc_sf32lb_data *data = dev->data; if (id != 0) { return -EINVAL; } - if (sys_test_bit(config->base + RTC_ISR, RTC_ISR_ALRMF_Pos)) { - sys_clear_bit(config->base + RTC_ISR, RTC_ISR_ALRMF_Pos); - return 1; - } - - return 0; + return (int)atomic_test_and_clear_bit(&data->is_pending, 0); } static int rtc_sf32lb_alarm_set_callback(const struct device *dev, uint16_t id, From d3d2bd2f02f8ef6bfea916c4818fee4b4cfb5002 Mon Sep 17 00:00:00 2001 From: Sylvio Alves Date: Fri, 5 Dec 2025 14:26:20 -0300 Subject: [PATCH 0228/3659] driver: clock: espressif: get frequency default to calibrated value When clock get_rate() is called, return by default the calibrated frequency instead of nominal one. This improves accuracy specially when internal RC SLOW clock is used. To guarantee that nominal values can be still be retrieved, add a new type of clock subsys for such scenario. west.yml is also updated to add fix into calibration sources. Signed-off-by: Sylvio Alves --- drivers/clock_control/clock_control_esp32.c | 10 ++++++++-- .../zephyr/drivers/clock_control/esp32_clock_control.h | 2 ++ west.yml | 2 +- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/clock_control/clock_control_esp32.c b/drivers/clock_control/clock_control_esp32.c index a7f00a4962a1..11df4ad0ee46 100644 --- a/drivers/clock_control/clock_control_esp32.c +++ b/drivers/clock_control/clock_control_esp32.c @@ -567,10 +567,16 @@ static int clock_control_esp32_get_rate(const struct device *dev, clock_control_ 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); + *rate = esp_clk_tree_lp_fast_get_freq_hz(ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED); break; case ESP32_CLOCK_CONTROL_SUBSYS_RTC_SLOW: - *rate = clk_hal_lp_slow_get_freq_hz(); + *rate = esp_clk_tree_lp_slow_get_freq_hz(ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED); + break; + case ESP32_CLOCK_CONTROL_SUBSYS_RTC_FAST_NOMINAL: + *rate = esp_clk_tree_lp_fast_get_freq_hz(ESP_CLK_TREE_SRC_FREQ_PRECISION_APPROX); + break; + case ESP32_CLOCK_CONTROL_SUBSYS_RTC_SLOW_NOMINAL: + *rate = esp_clk_tree_lp_slow_get_freq_hz(ESP_CLK_TREE_SRC_FREQ_PRECISION_APPROX); break; default: *rate = clk_hal_cpu_get_freq_hz(); diff --git a/include/zephyr/drivers/clock_control/esp32_clock_control.h b/include/zephyr/drivers/clock_control/esp32_clock_control.h index a56e9142e9d5..30351ed9ffc3 100644 --- a/include/zephyr/drivers/clock_control/esp32_clock_control.h +++ b/include/zephyr/drivers/clock_control/esp32_clock_control.h @@ -26,6 +26,8 @@ #define ESP32_CLOCK_CONTROL_SUBSYS_CPU 50 #define ESP32_CLOCK_CONTROL_SUBSYS_RTC_FAST 51 #define ESP32_CLOCK_CONTROL_SUBSYS_RTC_SLOW 52 +#define ESP32_CLOCK_CONTROL_SUBSYS_RTC_FAST_NOMINAL 53 +#define ESP32_CLOCK_CONTROL_SUBSYS_RTC_SLOW_NOMINAL 54 struct esp32_cpu_clock_config { int clk_src; diff --git a/west.yml b/west.yml index d1b90d200111..da6f75547c8a 100644 --- a/west.yml +++ b/west.yml @@ -169,7 +169,7 @@ manifest: groups: - hal - name: hal_espressif - revision: 51544259fc62153df6142279bc55ee8ef40172ac + revision: 19807014b69b2dc24edb7a1b49c915fd58083527 path: modules/hal/espressif west-commands: west/west-commands.yml groups: From 889910d7d8c62b2b77e283948bd585304536aa82 Mon Sep 17 00:00:00 2001 From: Sylvio Alves Date: Fri, 5 Dec 2025 15:56:49 -0300 Subject: [PATCH 0229/3659] tests: counter_basic_api: esp32h2: remove custom tolerance ESP32-H2 counter test works with default tolerance. Signed-off-by: Sylvio Alves --- tests/drivers/counter/counter_basic_api/socs/esp32h2.conf | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 tests/drivers/counter/counter_basic_api/socs/esp32h2.conf diff --git a/tests/drivers/counter/counter_basic_api/socs/esp32h2.conf b/tests/drivers/counter/counter_basic_api/socs/esp32h2.conf deleted file mode 100644 index e87bbb981181..000000000000 --- a/tests/drivers/counter/counter_basic_api/socs/esp32h2.conf +++ /dev/null @@ -1,2 +0,0 @@ -# LP Timer is driven by RC_SLOW, which has limited precision -CONFIG_TEST_DRIVER_COUNTER_TOLERANCE=20 From 16f6f392b466e21bd2ed28acd677c310966f97a4 Mon Sep 17 00:00:00 2001 From: Sylvio Alves Date: Fri, 5 Dec 2025 15:58:18 -0300 Subject: [PATCH 0230/3659] tests: espressif: rtc_clk: update to keep nominal tests usage Update the test case to use the nominal clock_subsys and print calibration deviation. Signed-off-by: Sylvio Alves --- .../espressif/rtc_clk/src/rtc_clk_test.c | 60 ++++++++++++++----- 1 file changed, 46 insertions(+), 14 deletions(-) diff --git a/tests/boards/espressif/rtc_clk/src/rtc_clk_test.c b/tests/boards/espressif/rtc_clk/src/rtc_clk_test.c index 6933849e3942..36a2114a92cf 100644 --- a/tests/boards/espressif/rtc_clk/src/rtc_clk_test.c +++ b/tests/boards/espressif/rtc_clk/src/rtc_clk_test.c @@ -141,27 +141,43 @@ ZTEST(rtc_clk, test_rtc_fast_src) { struct esp32_clock_config clk_cfg = {0}; int ret = 0; - uint32_t cpu_rate = 0; + uint32_t nominal_rate = 0; + uint32_t calibrated_rate = 0; clk_cfg.cpu.xtal_freq = (DT_PROP(DT_INST(0, DT_CPU_COMPAT), xtal_freq) / MHZ(1)); for (uint8_t i = 0; i < ARRAY_SIZE(rtc_rtc_fast_clk_src); i++) { clk_cfg.rtc.rtc_fast_clock_src = rtc_rtc_fast_clk_src[i]; - TC_PRINT("Testing RTC FAST CLK freq: %d MHz\n", rtc_rtc_fast_clk_src_freq_mhz[i]); + TC_PRINT("Testing RTC FAST CLK source: %d\n", rtc_rtc_fast_clk_src_freq_mhz[i]); ret = clock_control_configure( clk_dev, (clock_control_subsys_t)ESP32_CLOCK_CONTROL_SUBSYS_RTC_FAST, &clk_cfg); - zassert_false(ret, "Failed to set CPU clock source"); + zassert_false(ret, "Failed to set RTC fast clock source"); + /* Verify nominal frequency matches expected value for selected source */ + ret = clock_control_get_rate( + clk_dev, + (clock_control_subsys_t)ESP32_CLOCK_CONTROL_SUBSYS_RTC_FAST_NOMINAL, + &nominal_rate); + zassert_false(ret, "Failed to get RTC_FAST nominal clock rate"); + zassert_equal(nominal_rate, rtc_rtc_fast_clk_src_freq_mhz[i], + "Nominal rate mismatch (%d != %d)", nominal_rate, + rtc_rtc_fast_clk_src_freq_mhz[i]); + + /* Also retrieve calibrated value for informational purposes */ ret = clock_control_get_rate( clk_dev, (clock_control_subsys_t)ESP32_CLOCK_CONTROL_SUBSYS_RTC_FAST, - &cpu_rate); - zassert_false(ret, "Failed to get RTC_FAST clock rate"); - zassert_equal(cpu_rate, rtc_rtc_fast_clk_src_freq_mhz[i], - "CPU clock rate is not equal to configured frequency (%d != %d)", - cpu_rate, rtc_rtc_fast_clk_src_freq_mhz[i]); + &calibrated_rate); + zassert_false(ret, "Failed to get RTC_FAST calibrated clock rate"); + + int32_t diff = (int32_t)calibrated_rate - (int32_t)nominal_rate; + int32_t deviation_tenths = (diff * 1000) / (int32_t)nominal_rate; + + TC_PRINT("Nominal: %d Hz, Calibrated: %d Hz (deviation: %d.%d%%)\n", nominal_rate, + calibrated_rate, deviation_tenths / 10, + (deviation_tenths < 0 ? -deviation_tenths : deviation_tenths) % 10); } } @@ -199,7 +215,8 @@ ZTEST(rtc_clk, test_rtc_slow_src) { struct esp32_clock_config clk_cfg = {0}; int ret = 0; - uint32_t cpu_rate = 0; + uint32_t nominal_rate = 0; + uint32_t calibrated_rate = 0; clk_cfg.cpu.xtal_freq = (DT_PROP(DT_INST(0, DT_CPU_COMPAT), xtal_freq) / MHZ(1)); @@ -213,13 +230,28 @@ ZTEST(rtc_clk, test_rtc_slow_src) &clk_cfg); zassert_false(ret, "Failed to set CPU clock source"); + /* Verify nominal frequency matches expected value for selected source */ + ret = clock_control_get_rate( + clk_dev, + (clock_control_subsys_t)ESP32_CLOCK_CONTROL_SUBSYS_RTC_SLOW_NOMINAL, + &nominal_rate); + zassert_false(ret, "Failed to get RTC_SLOW nominal clock rate"); + zassert_equal(nominal_rate, rtc_rtc_slow_clk_src_freq[i], + "Nominal rate mismatch (%d != %d)", nominal_rate, + rtc_rtc_slow_clk_src_freq[i]); + + /* Also retrieve calibrated value for informational purposes */ ret = clock_control_get_rate( clk_dev, (clock_control_subsys_t)ESP32_CLOCK_CONTROL_SUBSYS_RTC_SLOW, - &cpu_rate); - zassert_false(ret, "Failed to get RTC_SLOW clock rate"); - zassert_equal(cpu_rate, rtc_rtc_slow_clk_src_freq[i], - "CPU clock rate is not equal to configured frequency (%d != %d)", - cpu_rate, rtc_rtc_slow_clk_src_freq[i]); + &calibrated_rate); + zassert_false(ret, "Failed to get RTC_SLOW calibrated clock rate"); + + int32_t diff = (int32_t)calibrated_rate - (int32_t)nominal_rate; + int32_t deviation_tenths = (diff * 1000) / (int32_t)nominal_rate; + + TC_PRINT("Nominal: %d Hz, Calibrated: %d Hz (deviation: %d.%d%%)\n", nominal_rate, + calibrated_rate, deviation_tenths / 10, + (deviation_tenths < 0 ? -deviation_tenths : deviation_tenths) % 10); } } From 7127ff4be330341273d93452b3130b9e7dd49178 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 8 Dec 2025 08:14:31 +0000 Subject: [PATCH 0231/3659] kconfig: Remove dependencies from CONFIG_IS_BOOTLOADER symbol This symbol has no relation to the dependencies it had, thus remove them Signed-off-by: Jamie McCrae --- Kconfig.zephyr | 2 -- 1 file changed, 2 deletions(-) diff --git a/Kconfig.zephyr b/Kconfig.zephyr index 8bdaff1c4127..d534c1c7543d 100644 --- a/Kconfig.zephyr +++ b/Kconfig.zephyr @@ -1071,8 +1071,6 @@ menu "Boot Options" config IS_BOOTLOADER bool "Act as a bootloader" - depends on XIP - depends on ARM help This option indicates that Zephyr will act as a bootloader to execute a separate Zephyr image payload. From 7d7aa2c1d7f8b6f4f00b4b6fdc3e8580c09983aa Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 8 Dec 2025 07:36:35 +0000 Subject: [PATCH 0232/3659] west.yml: MCUboot synchronization from upstream Update Zephyr fork of MCUboot to revision: 234c66e66ee39c0f836a57ba805245534be332f2 Brings following Zephyr relevant fixes: - 55ae5342 doc: imgtool: Update available options - cd96b62f boot: zephyr: Fix comment in banner.c - 1357a70f Updates for v2.3.0-rc2 release - afcca2c7 boot: zephyr: Fix Espressif build issues - d95ca5c7 boot: zephyr: Remove BOOT_MAX_IMG settings - 623f0230 boot: zephyr: stm32n657xx: Move overlay to socs - 31469b43 boot: zephyr: kconfig: Flip swap move defaults for esp32/stm32 - a2ee0a75 scripts: imgtool: Fix verification with public ed25519 key file - 49bbbabf boot: zephyr: Add watchdog setup/timeout configurability options - c25d2506 boot: zephyr: Move watchdog code to separate file - 9efb9d3f boot: zephyr: kconfig: Move modes to choice Kconfig - 92854b7b boot: zephyr: kconfig: Only show signature file when needed - 716f338a boot: zephyr: Remove weird custom key directory handling - c52f8af7 boot: zephyr: select `IS_BOOTLOADER` Signed-off-by: Jamie McCrae --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index da6f75547c8a..936b5b717add 100644 --- a/west.yml +++ b/west.yml @@ -321,7 +321,7 @@ manifest: groups: - crypto - name: mcuboot - revision: c11e845e2483917d7478ba1a7a3591a9f4e8d4a2 + revision: 234c66e66ee39c0f836a57ba805245534be332f2 path: bootloader/mcuboot groups: - bootloader From 5dada87def8939289d50f616230eec8a826d5f8f Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Tue, 9 Dec 2025 11:41:46 +0200 Subject: [PATCH 0233/3659] doc: net: Enhance network packet filtering documentation Add more information to network packet filter documentation to make it more useful to end users. Signed-off-by: Jukka Rissanen --- .../networking/api/net_pkt_filter.rst | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/doc/connectivity/networking/api/net_pkt_filter.rst b/doc/connectivity/networking/api/net_pkt_filter.rst index 338aaa684378..afd7babc85d5 100644 --- a/doc/connectivity/networking/api/net_pkt_filter.rst +++ b/doc/connectivity/networking/api/net_pkt_filter.rst @@ -38,8 +38,22 @@ A rule is represented by a :c:struct:`npf_rule` object. It can be inserted to, appended to or removed from a rule list contained in a :c:struct:`npf_rule_list` object using :c:func:`npf_insert_rule()`, :c:func:`npf_append_rule()`, and :c:func:`npf_remove_rule()`. -Currently, two such rule lists exist: ``npf_send_rules`` for outgoing packets, -and ``npf_recv_rules`` for incoming packets. + +There are different sets of rules for different layers in the network stack. +Some of the rules are applied for L2 layer like Ethernet, and some for L3 layer +where IPv4 or IPv6 protocol is handled. The ``local_in`` rules are for matching +incoming protocol types like UDP or TCP packets that are run on top of IPv4 or IPv6. +The rule support for different layers can be controlled by relevant Kconfig options +mentioned below. + +* ``npf_send_rules`` is a rule list applied to outgoing packets in L2 layer +* ``npf_recv_rules`` is a rule list applied to incoming packets in L2 layer +* ``npf_ipv4_recv_rules`` is a rule list applied for incoming IPv4 packets. Can be + enabled or disabled by :kconfig:option:`CONFIG_NET_PKT_FILTER_IPV4_HOOK` option. +* ``npf_ipv6_recv_rules`` is a rule list applied for incoming IPv6 packets. Can be + enabled or disabled by :kconfig:option:`CONFIG_NET_PKT_FILTER_IPV6_HOOK` option. +* ``npf_local_in_recv_rules`` is a rule list applied for incoming UDP or TCP packets. + Can be enabled or disabled by :kconfig:option:`CONFIG_NET_PKT_FILTER_LOCAL_IN_HOOK` option. If a filter rule list is empty then ``NET_OK`` is assumed. If a non-empty rule list runs to the end then ``NET_DROP`` is assumed. However it is @@ -56,6 +70,10 @@ to statically define condition instances for various conditions, and :c:macro:`NPF_RULE()` and :c:macro:`NPF_PRIORITY()` to create a rule instance with an immediate outcome or a priority change. +See also :zephyr:code-sample:`net-pkt-filter` sample for an example of how to create and +manage packet filters. The network shell has a ``net filter`` command that can be used +to see the installed rules at runtime. + Examples ******** From 139b7c20c2761319df3a99e336d7746c0332f4b4 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Tue, 9 Dec 2025 13:16:28 +0100 Subject: [PATCH 0234/3659] drivers: xen: Fix uninitialized variable warning gcc complains about the posibility of ret and gfn being used unitialiazed (with the input npages == 0). Let's fix it by initializing ret to 0. The warnings being: ``` zephyr/CMakeFiles/zephyr.dir/drivers/xen/gnttab.c.obj In file included from include/zephyr/logging/log.h:11, from drivers/xen/gnttab.c:31: include/zephyr/logging/log_core.h: In function 'gnttab_get_pages': include/zephyr/logging/log_core.h:221:9: warning: 'gfn' may be used uninitialized [-Wmaybe-uninitialized] 221 | z_log_minimal_printk("%c: " fmt "\n", \ | ^~~~~~~~~~~~~~~~~~~~ drivers/xen/gnttab.c:202:19: note: 'gfn' was declared here 202 | xen_pfn_t gfn; | ^~~ include/zephyr/logging/log_core.h:221:9: warning: 'ret' may be used uninitialized [-Wmaybe-uninitialized] 221 | z_log_minimal_printk("%c: " fmt "\n", \ | ^~~~~~~~~~~~~~~~~~~~ drivers/xen/gnttab.c:199:13: note: 'ret' was declared here 199 | int ret; | ^~~ ``` Signed-off-by: Alberto Escolar Piedras --- drivers/xen/gnttab.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/xen/gnttab.c b/drivers/xen/gnttab.c index da0722bbf448..6733f9df9a2e 100644 --- a/drivers/xen/gnttab.c +++ b/drivers/xen/gnttab.c @@ -196,7 +196,7 @@ static void gop_eagain_retry(int cmd, struct gnttab_map_grant_ref *gref) void *gnttab_get_pages(unsigned int npages) { - int ret; + int ret = 0; void *page_addr; unsigned int removed; xen_pfn_t gfn; From 2ed5e0d6083488c28a758bc51f10542bfa434a3f Mon Sep 17 00:00:00 2001 From: Hank Wang Date: Mon, 15 Sep 2025 04:13:08 +0800 Subject: [PATCH 0235/3659] dts: arm: xilinx: fix zynqmp RPU IPI mailbox base addresses The RPU0 mailbox node in `zynqmp_rpu.dtsi` used incorrect IPI message buffer base addresses. According to UG1085 (Table 13-3)[1], RPU0 should use the channel 1 message buffer region at `0xFF99_0080` for local request/response and `0xFF99_0400` for remote request/ response. The previous values pointed to the APU channel 0 buffer (`0xFF99_0200`), which does not match the hardware mapping. The same is true for rpu1. The IPI buffer base looks something like this: IPI1 - 0xFF990000 IPI2 - 0xFF990200 IPI0 - 0xFF990400 Fix the DTS by updating the RPU0, RPU1 mailbox nodes to use the correct base addresses from the documentation. [1] https://docs.amd.com/v/u/en-US/ug1085-zynq-ultrascale-trm Signed-off-by: Hank Wang Signed-off-by: Harini T --- dts/arm/xilinx/zynqmp_rpu.dtsi | 40 +++++++++++++++++----------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/dts/arm/xilinx/zynqmp_rpu.dtsi b/dts/arm/xilinx/zynqmp_rpu.dtsi index 8c77e3df274d..ad759c013940 100644 --- a/dts/arm/xilinx/zynqmp_rpu.dtsi +++ b/dts/arm/xilinx/zynqmp_rpu.dtsi @@ -31,24 +31,24 @@ IRQ_DEFAULT_PRIORITY>; local-ipi-id = <1>; - rpu0_apu_mailbox: mailbox@ff990200 { + rpu0_apu_mailbox: mailbox@ff990080 { remote-ipi-id = <0>; - reg = <0xff990200 0x20>, - <0xff990220 0x20>, - <0xff990040 0x20>, - <0xff990060 0x20>; + reg = <0xff990080 0x20>, + <0xff9900a0 0x20>, + <0xff990400 0x20>, + <0xff990420 0x20>; reg-names = "local_request_region", "local_response_region", "remote_request_region", "remote_response_region"; }; - rpu0_rpu1_mailbox: mailbox@ff990260 { + rpu0_rpu1_mailbox: mailbox@ff990040 { remote-ipi-id = <2>; - reg = <0xff990260 0x20>, - <0xff990280 0x20>, - <0xff990420 0x20>, - <0xff990440 0x20>; + reg = <0xff990040 0x20>, + <0xff990060 0x20>, + <0xff990200 0x20>, + <0xff990220 0x20>; reg-names = "local_request_region", "local_response_region", @@ -70,24 +70,24 @@ interrupts = ; - rpu1_apu_mailbox: mailbox@ff990400 { + rpu1_apu_mailbox: mailbox@ff990280 { remote-ipi-id = <0>; - reg = <0xff990400 0x20>, - <0xff990420 0x20>, - <0xff990080 0x20>, - <0xff9900a0 0x20>; + reg = <0xff990280 0x20>, + <0xff9902a0 0x20>, + <0xff990440 0x20>, + <0xff990460 0x20>; reg-names = "local_request_region", "local_response_region", "remote_request_region", "remote_response_region"; }; - rpu1_rpu0_mailbox: mailbox@ff990420 { + rpu1_rpu0_mailbox: mailbox@ff990200 { remote-ipi-id = <1>; - reg = <0xff990420 0x20>, - <0xff990440 0x20>, - <0xff990260 0x20>, - <0xff990280 0x20>; + reg = <0xff990200 0x20>, + <0xff990220 0x20>, + <0xff990040 0x20>, + <0xff990060 0x20>; reg-names = "local_request_region", "local_response_region", "remote_request_region", From c4d72ac549dd3351c1832e1fdf48b2bfb3ebff94 Mon Sep 17 00:00:00 2001 From: Mathieu Choplain Date: Tue, 25 Nov 2025 13:21:16 +0100 Subject: [PATCH 0236/3659] dts: arm: st: stm32f723: disable USBPHYC by default Like other devices, the USBPHYC should be disabled by default. Add missing property `status` with value `disabled` on the node in DTSI. Signed-off-by: Mathieu Choplain --- dts/arm/st/f7/stm32f723.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/dts/arm/st/f7/stm32f723.dtsi b/dts/arm/st/f7/stm32f723.dtsi index f8b5448a7880..11506220f9f3 100644 --- a/dts/arm/st/f7/stm32f723.dtsi +++ b/dts/arm/st/f7/stm32f723.dtsi @@ -14,6 +14,7 @@ compatible = "st,stm32-usbphyc"; reg = <0x40017c00 0x400>; #phy-cells = <0>; + status = "disabled"; }; usbotg_hs: usb@40040000 { From 13ce8eac996f7f798a662b0dfe4cdf47343caded Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Tue, 9 Dec 2025 14:52:22 +0100 Subject: [PATCH 0237/3659] drivers: sensor: adi: adxl345: use selected range for conversion When running the samples/sensor/accel_trig sample with a adxl345 sensor the logged output values were doubled compared to the expected values. The sensor_channel_get() path calls adxl345_accel_convert which did not handle the configured g-range, resulting in invalid sample values except for the +/-16g range. To fix this issue the configured range is taken into account and different conversion factors are applied. adxl345_accel_convert is also made static. It is not used by another file. Signed-off-by: Stefan Schmidt --- drivers/sensor/adi/adxl345/adxl345.c | 34 ++++++++++++++++++++-------- drivers/sensor/adi/adxl345/adxl345.h | 1 - 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/drivers/sensor/adi/adxl345/adxl345.c b/drivers/sensor/adi/adxl345/adxl345.c index 6c203f755d7d..626f09dd8b65 100644 --- a/drivers/sensor/adi/adxl345/adxl345.c +++ b/drivers/sensor/adi/adxl345/adxl345.c @@ -313,14 +313,22 @@ int adxl345_read_sample(const struct device *dev, return 0; } -void adxl345_accel_convert(struct sensor_value *val, int16_t sample) +static void adxl345_accel_convert(struct sensor_value *val, int16_t sample, + uint8_t selected_range) { + const int32_t sensitivity[] = { + [ADXL345_RANGE_2G] = INT32_C(SENSOR_G / 256), + [ADXL345_RANGE_4G] = INT32_C(SENSOR_G / 128), + [ADXL345_RANGE_8G] = INT32_C(SENSOR_G / 64), + [ADXL345_RANGE_16G] = INT32_C(SENSOR_G / 32), + }; + if (sample & BIT(9)) { sample |= ADXL345_COMPLEMENT; } - val->val1 = ((sample * SENSOR_G) / 32) / 1000000; - val->val2 = ((sample * SENSOR_G) / 32) % 1000000; + val->val1 = (sample * sensitivity[selected_range]) / 1000000; + val->val2 = (sample * sensitivity[selected_range]) % 1000000; } static int adxl345_sample_fetch(const struct device *dev, @@ -350,18 +358,26 @@ static int adxl345_channel_get(const struct device *dev, switch (chan) { case SENSOR_CHAN_ACCEL_X: - adxl345_accel_convert(val, data->samples.x); + adxl345_accel_convert(val, data->samples.x, + data->selected_range); break; case SENSOR_CHAN_ACCEL_Y: - adxl345_accel_convert(val, data->samples.y); + adxl345_accel_convert(val, data->samples.y, + data->selected_range); break; case SENSOR_CHAN_ACCEL_Z: - adxl345_accel_convert(val, data->samples.z); + adxl345_accel_convert(val, data->samples.z, + data->selected_range); break; case SENSOR_CHAN_ACCEL_XYZ: - adxl345_accel_convert(val++, data->samples.x); - adxl345_accel_convert(val++, data->samples.y); - adxl345_accel_convert(val, data->samples.z); + adxl345_accel_convert(val, data->samples.x, + data->selected_range); + val++; + adxl345_accel_convert(val, data->samples.y, + data->selected_range); + val++; + adxl345_accel_convert(val, data->samples.z, + data->selected_range); break; default: return -ENOTSUP; diff --git a/drivers/sensor/adi/adxl345/adxl345.h b/drivers/sensor/adi/adxl345/adxl345.h index 845384caedd4..136217f28b2d 100644 --- a/drivers/sensor/adi/adxl345/adxl345.h +++ b/drivers/sensor/adi/adxl345/adxl345.h @@ -292,7 +292,6 @@ int adxl345_read_sample(const struct device *dev, struct adxl345_sample *sample) #ifdef CONFIG_SENSOR_ASYNC_API void adxl345_submit(const struct device *dev, struct rtio_iodev_sqe *iodev_sqe); int adxl345_get_decoder(const struct device *dev, const struct sensor_decoder_api **decoder); -void adxl345_accel_convert(struct sensor_value *val, int16_t sample); #endif /* CONFIG_SENSOR_ASYNC_API */ #ifdef CONFIG_ADXL345_STREAM From f0ecb0a17f917e9eafd9f78acfcf8556ae00d433 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Tue, 9 Dec 2025 14:00:00 +0100 Subject: [PATCH 0238/3659] drivers: ethernet: intel_igc: Use net namespaced APIs In e6daacf3c9e3fbe879fe5b3cd451550d64d60784 the mayority of the Zephyr ethernet drivers were changed to use the Zephyr native net_ prefixed types, but this one was forgotten. Without this fix/change the code still builds as we are by now setting CONFIG_NET_NAMESPACE_COMPAT_MODE. But when this is not set, things fail to build. Signed-off-by: Alberto Escolar Piedras --- drivers/ethernet/intel/eth_intel_igc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ethernet/intel/eth_intel_igc.c b/drivers/ethernet/intel/eth_intel_igc.c index 928c943636c2..12f2d055a4ed 100644 --- a/drivers/ethernet/intel/eth_intel_igc.c +++ b/drivers/ethernet/intel/eth_intel_igc.c @@ -650,7 +650,7 @@ static int eth_intel_igc_tx_data(const struct device *dev, struct net_pkt *pkt) /** * @brief Identify the address family of received packets as per header type. */ -static sa_family_t eth_intel_igc_get_sa_family(uint8_t *rx_buf) +static net_sa_family_t eth_intel_igc_get_sa_family(uint8_t *rx_buf) { struct net_eth_hdr *eth_hdr = (struct net_eth_hdr *)rx_buf; From e19d78e6070c4c3a2d315219d38ea66a100ec161 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Tue, 9 Dec 2025 14:09:04 +0100 Subject: [PATCH 0239/3659] drivers: modem: Fix remaining net API use In b5588ed684365eedfb55822804af3d0c3cd944ab the mayority of the Zephyr modem drivers were changed to use the Zephyr native net_ prefixed types, but this one was forgotten. Without this fix/change the code still builds as we are by now setting CONFIG_NET_NAMESPACE_COMPAT_MODE. But when this is not set, things fail to build. Note that the net_offload struct was updated accordingly in d45cd6716bbab3a805e3a5fd461934f0dcdc13e5 Signed-off-by: Alberto Escolar Piedras --- drivers/modem/hl7800.c | 26 +++++++++++++------------- drivers/modem/hl78xx/hl78xx_sockets.c | 12 ++++++------ drivers/modem/modem_socket.h | 2 +- drivers/modem/ublox-sara-r4.c | 2 +- drivers/modem/wncm14a2a.c | 4 ++-- 5 files changed, 23 insertions(+), 23 deletions(-) diff --git a/drivers/modem/hl7800.c b/drivers/modem/hl7800.c index 282e2d12fc09..c3515d590fa3 100644 --- a/drivers/modem/hl7800.c +++ b/drivers/modem/hl7800.c @@ -377,7 +377,7 @@ static const char OK_STRING[] = "OK"; struct hl7800_socket { struct net_context *context; - sa_family_t family; + net_sa_family_t family; enum net_sock_type type; enum net_ip_protocol ip_proto; struct net_sockaddr src; @@ -418,9 +418,9 @@ struct hl7800_config { struct hl7800_iface_ctx { struct net_if *iface; uint8_t mac_addr[6]; - struct in_addr ipv4Addr, subnet, gateway, dns_v4; + struct net_in_addr ipv4Addr, subnet, gateway, dns_v4; #ifdef CONFIG_NET_IPV6 - struct in6_addr ipv6Addr, dns_v6; + struct net_in6_addr ipv6Addr, dns_v6; char dns_v6_string[HL7800_IPV6_ADDR_LEN]; #endif bool restarting; @@ -1454,7 +1454,7 @@ static int send_data(struct hl7800_socket *sock, struct net_pkt *pkt) send_len = net_buf_frags_len(frag); /* start sending data */ k_sem_reset(&sock->sock_send_sem); - if (sock->type == SOCK_STREAM) { + if (sock->type == NET_SOCK_STREAM) { snprintk(buf, sizeof(buf), "AT+KTCPSND=%d,%zu", sock->socket_id, send_len); } else { @@ -1504,7 +1504,7 @@ static int send_data(struct hl7800_socket *sock, struct net_pkt *pkt) ret = -ETIMEDOUT; } done: - if (sock->type == SOCK_STREAM) { + if (sock->type == NET_SOCK_STREAM) { if (sock->error == 0) { sock->state = SOCK_CONNECTED; } @@ -2008,7 +2008,7 @@ char *mdm_hl7800_get_imsi(void) * a01.a02.a03.a04.a05.a06.a07.a08.a09.a10.a11.a12.a13.a14.a15.a16 to * an IPv6 address. */ -static int hl7800_net_addr6_pton(const char *src, struct in6_addr *dst) +static int hl7800_net_addr6_pton(const char *src, struct net_in6_addr *dst) { int num_sections = 8; int i, len; @@ -2062,8 +2062,8 @@ static bool on_cmd_atcmdinfo_ipaddr(struct net_buf **buf, uint16_t len) size_t out_len; char value[MDM_IP_INFO_RESP_SIZE]; char *search_start, *addr_start, *sm_start; - struct in_addr new_ipv4_addr; - struct in6_addr new_ipv6_addr; + struct net_in_addr new_ipv4_addr; + struct net_in6_addr new_ipv6_addr; bool is_ipv4; int addr_len; char temp_addr_str[HL7800_IPV6_ADDR_LEN]; @@ -5958,7 +5958,7 @@ static int reconfigure_IP_connection(void) return ret; } -static int offload_get(sa_family_t family, enum net_sock_type type, +static int offload_get(net_sa_family_t family, enum net_sock_type type, enum net_ip_protocol ip_proto, struct net_context **context) { @@ -6010,7 +6010,7 @@ static int offload_get(sa_family_t family, enum net_sock_type type, } static int offload_bind(struct net_context *context, - const struct net_sockaddr *addr, socklen_t addr_len) + const struct net_sockaddr *addr, net_socklen_t addr_len) { struct hl7800_socket *sock = NULL; @@ -6049,7 +6049,7 @@ static int offload_listen(struct net_context *context, int backlog) } static int offload_connect(struct net_context *context, - const struct net_sockaddr *addr, socklen_t addr_len, + const struct net_sockaddr *addr, net_socklen_t addr_len, net_context_connect_cb_t cb, int32_t timeout, void *user_data) { @@ -6136,7 +6136,7 @@ static int offload_accept(struct net_context *context, net_tcp_accept_cb_t cb, } static int offload_sendto(struct net_pkt *pkt, const struct net_sockaddr *dst_addr, - socklen_t addr_len, net_context_send_cb_t cb, + net_socklen_t addr_len, net_context_send_cb_t cb, int32_t timeout, void *user_data) { struct net_context *context = net_pkt_context(pkt); @@ -6192,7 +6192,7 @@ static int offload_send(struct net_pkt *pkt, net_context_send_cb_t cb, int32_t timeout, void *user_data) { struct net_context *context = net_pkt_context(pkt); - socklen_t addr_len; + net_socklen_t addr_len; addr_len = 0; diff --git a/drivers/modem/hl78xx/hl78xx_sockets.c b/drivers/modem/hl78xx/hl78xx_sockets.c index f26d2b2026fb..748a10ccbaee 100644 --- a/drivers/modem/hl78xx/hl78xx_sockets.c +++ b/drivers/modem/hl78xx/hl78xx_sockets.c @@ -828,12 +828,12 @@ static int validate_socket(const struct modem_socket *sock, struct hl78xx_socket return -1; } - bool not_connected = (!sock->is_connected && sock->type != SOCK_DGRAM); + bool not_connected = (!sock->is_connected && sock->type != NET_SOCK_DGRAM); bool tcp_disconnected = - (sock->type == SOCK_STREAM && + (sock->type == NET_SOCK_STREAM && !socket_data->tcp_conn_status[HL78XX_TCP_STATUS_ID(sock->id)].is_connected); bool udp_not_created = - (sock->type == SOCK_DGRAM && + (sock->type == NET_SOCK_DGRAM && !socket_data->udp_conn_status[HL78XX_UDP_STATUS_ID(sock->id)].is_created); if (not_connected || tcp_disconnected || udp_not_created) { @@ -1959,7 +1959,7 @@ static int validate_and_prepare(struct modem_socket *sock, const struct net_sock errno = EINVAL; return -1; } - if (sock->type != SOCK_DGRAM && !sock->is_connected) { + if (sock->type != NET_SOCK_DGRAM && !sock->is_connected) { errno = ENOTCONN; return -1; } @@ -1967,7 +1967,7 @@ static int validate_and_prepare(struct modem_socket *sock, const struct net_sock *dst_addr = &sock->dst; } if (*buf_len > MDM_MAX_DATA_LENGTH) { - if (sock->type == SOCK_DGRAM) { + if (sock->type == NET_SOCK_DGRAM) { errno = EMSGSIZE; return -1; } @@ -2137,7 +2137,7 @@ static ssize_t offload_sendto(void *obj, const void *buf, size_t len, int flags, * destination address is provided or the socket has a stored dst. The * helper validate_and_prepare will supply sock->dst for UDP when needed. */ - if (sock->type != SOCK_DGRAM && !sock->is_connected) { + if (sock->type != NET_SOCK_DGRAM && !sock->is_connected) { errno = ENOTCONN; return -1; } diff --git a/drivers/modem/modem_socket.h b/drivers/modem/modem_socket.h index b679076e874b..dd1957d862d7 100644 --- a/drivers/modem/modem_socket.h +++ b/drivers/modem/modem_socket.h @@ -24,7 +24,7 @@ extern "C" { #endif __net_socket struct modem_socket { - sa_family_t family; + net_sa_family_t family; enum net_sock_type type; int ip_proto; struct net_sockaddr src; diff --git a/drivers/modem/ublox-sara-r4.c b/drivers/modem/ublox-sara-r4.c index 95fe769e8190..4275c7a8170f 100644 --- a/drivers/modem/ublox-sara-r4.c +++ b/drivers/modem/ublox-sara-r4.c @@ -2038,7 +2038,7 @@ static const struct socket_dns_offload offload_dns_ops = { }; #endif -static int net_offload_dummy_get(sa_family_t family, +static int net_offload_dummy_get(net_sa_family_t family, enum net_sock_type type, enum net_ip_protocol ip_proto, struct net_context **context) diff --git a/drivers/modem/wncm14a2a.c b/drivers/modem/wncm14a2a.c index bd27e67e5b98..b9249a2dcce0 100644 --- a/drivers/modem/wncm14a2a.c +++ b/drivers/modem/wncm14a2a.c @@ -105,7 +105,7 @@ static struct k_work_q wncm14a2a_workq; struct wncm14a2a_socket { struct net_context *context; - sa_family_t family; + net_sa_family_t family; enum net_sock_type type; enum net_ip_protocol ip_proto; struct net_sockaddr src; @@ -1430,7 +1430,7 @@ static int wncm14a2a_init(const struct device *dev) /*** OFFLOAD FUNCTIONS ***/ -static int offload_get(sa_family_t family, +static int offload_get(net_sa_family_t family, enum net_sock_type type, enum net_ip_protocol ip_proto, struct net_context **context) From f81011ee6a8656bf6c1835f6ea3f7e7c50b0e84d Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Tue, 9 Dec 2025 14:16:46 +0100 Subject: [PATCH 0240/3659] net: ip: Rename namespaced type in comment In d45cd6716bbab3a805e3a5fd461934f0dcdc13e5 the mayority of the Zephyr codebased was changed to use the Zephyr native net_ prefixed types. This comment was fogotten. Let's fix it. Signed-off-by: Alberto Escolar Piedras --- include/zephyr/net/net_ip.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/zephyr/net/net_ip.h b/include/zephyr/net/net_ip.h index 3bb0feb888c5..e2dfd32d000c 100644 --- a/include/zephyr/net/net_ip.h +++ b/include/zephyr/net/net_ip.h @@ -381,7 +381,7 @@ struct net_cmsghdr { #if defined(CONFIG_NET_NATIVE_OFFLOADED_SOCKETS) #define UNIX_PATH_MAX 108 #undef NET_SOCKADDR_MAX_SIZE -/* Define NET_SOCKADDR_MAX_SIZE to be struct of sa_family_t + char[UNIX_PATH_MAX] */ +/* Define NET_SOCKADDR_MAX_SIZE to be struct of net_sa_family_t + char[UNIX_PATH_MAX] */ #define NET_SOCKADDR_MAX_SIZE (UNIX_PATH_MAX+sizeof(net_sa_family_t)) #if !defined(CONFIG_NET_SOCKETS_PACKET) #undef NET_SOCKADDR_PTR_MAX_SIZE From 244fe54a6d17bb9ff3369ddd80740096080bd82e Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Tue, 9 Dec 2025 14:14:00 +0100 Subject: [PATCH 0241/3659] drivers: wifi: Fix remaining use of sa_family_t In 55c49cdb8f7e93b018f908fc8356212cc0e42da8 the mayority of the Zephyr wifi drivers was changed to use the Zephyr native net_ prefixed types, but some were forgotten. Without this fix/change the code still builds as we are by now setting CONFIG_NET_NAMESPACE_COMPAT_MODE. But when this is not set, things will fail to build. Note that the net_offload struct was updated accordingly in d45cd6716bbab3a805e3a5fd461934f0dcdc13e5 Signed-off-by: Alberto Escolar Piedras --- drivers/wifi/esp_at/esp_offload.c | 2 +- drivers/wifi/eswifi/eswifi_offload.c | 2 +- drivers/wifi/simplelink/simplelink.c | 2 +- drivers/wifi/siwx91x/siwx91x_wifi_socket.c | 2 +- drivers/wifi/winc1500/wifi_winc1500.c | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/wifi/esp_at/esp_offload.c b/drivers/wifi/esp_at/esp_offload.c index 8cfa4a75c06b..744ca2840a4a 100644 --- a/drivers/wifi/esp_at/esp_offload.c +++ b/drivers/wifi/esp_at/esp_offload.c @@ -748,7 +748,7 @@ static int esp_put(struct net_context *context) return 0; } -static int esp_get(sa_family_t family, +static int esp_get(net_sa_family_t family, enum net_sock_type type, enum net_ip_protocol ip_proto, struct net_context **context) diff --git a/drivers/wifi/eswifi/eswifi_offload.c b/drivers/wifi/eswifi/eswifi_offload.c index 0e68efe3af01..57e5369cee67 100644 --- a/drivers/wifi/eswifi/eswifi_offload.c +++ b/drivers/wifi/eswifi/eswifi_offload.c @@ -404,7 +404,7 @@ static int eswifi_off_put(struct net_context *context) return ret; } -static int eswifi_off_get(sa_family_t family, +static int eswifi_off_get(net_sa_family_t family, enum net_sock_type type, enum net_ip_protocol ip_proto, struct net_context **context) diff --git a/drivers/wifi/simplelink/simplelink.c b/drivers/wifi/simplelink/simplelink.c index c4af70ce003b..4d4472c4ebec 100644 --- a/drivers/wifi/simplelink/simplelink.c +++ b/drivers/wifi/simplelink/simplelink.c @@ -192,7 +192,7 @@ static int simplelink_mgmt_disconnect(const struct device *dev) return ret ? -EIO : ret; } -static int simplelink_dummy_get(sa_family_t family, +static int simplelink_dummy_get(net_sa_family_t family, enum net_sock_type type, enum net_ip_protocol ip_proto, struct net_context **context) diff --git a/drivers/wifi/siwx91x/siwx91x_wifi_socket.c b/drivers/wifi/siwx91x/siwx91x_wifi_socket.c index b84a436051fb..d9661c5888da 100644 --- a/drivers/wifi/siwx91x/siwx91x_wifi_socket.c +++ b/drivers/wifi/siwx91x/siwx91x_wifi_socket.c @@ -166,7 +166,7 @@ static void siwx91x_sock_on_recv(sl_si91x_fdset_t *read_fd, sl_si91x_fdset_t *wr siwx91x_sock_on_recv); } -static int siwx91x_sock_get(sa_family_t family, enum net_sock_type type, +static int siwx91x_sock_get(net_sa_family_t family, enum net_sock_type type, enum net_ip_protocol ip_proto, struct net_context **context) { struct siwx91x_dev *sidev = net_if_get_first_wifi()->if_dev->dev->data; diff --git a/drivers/wifi/winc1500/wifi_winc1500.c b/drivers/wifi/winc1500/wifi_winc1500.c index a5cb597c371f..806391d1e586 100644 --- a/drivers/wifi/winc1500/wifi_winc1500.c +++ b/drivers/wifi/winc1500/wifi_winc1500.c @@ -289,7 +289,7 @@ static char *socket_message_to_string(uint8_t message) /** * This function is called when the socket is to be opened. */ -static int winc1500_get(sa_family_t family, +static int winc1500_get(net_sa_family_t family, enum net_sock_type type, enum net_ip_protocol ip_proto, struct net_context **context) From 3be4c4c5a81949b771c7d59b1852ef3e61836df9 Mon Sep 17 00:00:00 2001 From: Mathieu Choplain Date: Thu, 4 Dec 2025 16:08:05 +0100 Subject: [PATCH 0242/3659] soc: st: stm32f0: SRAM vector table CMake Linker Generator compatibility Add required CMake directives to enable working CONFIG_SRAM_VECTOR_TABLE=y on STM32F0 series when CONFIG_CMAKE_LINKER_GENERATOR=y. Builds OK with both ZEPHYR_TOOLCHAIN_VARIANT undefined (uses GNU toolchain from Zephyr SDK) and set to "iar" (uses IAR toochain from EWARM v9.70.1). Signed-off-by: Mathieu Choplain --- soc/st/stm32/stm32f0x/CMakeLists.txt | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/soc/st/stm32/stm32f0x/CMakeLists.txt b/soc/st/stm32/stm32f0x/CMakeLists.txt index 0ce31c70062b..26d4e6bfbef8 100644 --- a/soc/st/stm32/stm32f0x/CMakeLists.txt +++ b/soc/st/stm32/stm32f0x/CMakeLists.txt @@ -1,11 +1,27 @@ # SPDX-License-Identifier: Apache-2.0 -# The vector table must be placed at the start of SRAM -zephyr_linker_sources_ifdef(CONFIG_SRAM_VECTOR_TABLE - RAM_SECTIONS - SORT_KEY 0 - sram_vector_table.ld -) +if(CONFIG_SRAM_VECTOR_TABLE) + # The vector table must be placed at the start of SRAM. + # Reserve the first sizeof() bytes for this purpose. + if(CONFIG_CMAKE_LINKER_GENERATOR) + # We use MIN_SIZE to perform the equivalent of GNU ld `. += ;` + # but we have to compute the size of the vector table manually as + # it must be a bytes count (can't be `_vector_end - _vector_start`). + # Fortunately, the vector table size can be easily computed: + # 16 words for the architectural exceptions plus one word per IRQ + # (each word is 32 bits = 4 bytes). + math(EXPR vect_tbl_size "(16 + ${CONFIG_NUM_IRQS}) * 4") + zephyr_linker_section(NAME .st_stm32f0x_vt TYPE NOLOAD GROUP RAM_REGION ADDRESS 0x20000000 NOINPUT NOINIT) + zephyr_linker_section_configure(SECTION .st_stm32f0x_vt MIN_SIZE ${vect_tbl_size} SYMBOLS _ram_vector_start _ram_vector_end) + else() + zephyr_linker_sources( + RAM_SECTIONS + SORT_KEY 0 + sram_vector_table.ld + ) + endif() +endif() + zephyr_include_directories(${ZEPHYR_BASE}/drivers) zephyr_sources(soc.c) From fd24cefd01825453e7ff3f5cd0d706c73e160b85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Thu, 11 Dec 2025 15:13:16 +0100 Subject: [PATCH 0243/3659] doc: spelling/typo fixes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit minor spelling/typo fixes, mainly around using proper US English Signed-off-by: Benjamin Cabé --- doc/connectivity/networking/api/lwm2m.rst | 2 +- doc/develop/flash_debug/probes.rst | 2 +- doc/hardware/pinctrl/index.rst | 2 +- doc/hardware/porting/board_porting.rst | 2 +- doc/hardware/porting/soc_porting.rst | 2 +- doc/kernel/data_structures/slist.rst | 2 +- doc/kernel/services/threads/index.rst | 4 ++-- doc/security/security-overview.rst | 2 +- doc/services/zbus/index.rst | 4 ++-- 9 files changed, 11 insertions(+), 11 deletions(-) diff --git a/doc/connectivity/networking/api/lwm2m.rst b/doc/connectivity/networking/api/lwm2m.rst index 73d9dd8f244b..d365f1f1fbdf 100644 --- a/doc/connectivity/networking/api/lwm2m.rst +++ b/doc/connectivity/networking/api/lwm2m.rst @@ -230,7 +230,7 @@ The full list of registered objects and resource IDs can be found in the Zephyr's LwM2M library lives in the :zephyr_file:`subsys/net/lib/lwm2m`, with a client sample in :zephyr_file:`samples/net/lwm2m_client`. For more information about the provided sample see: :zephyr:code-sample:`lwm2m-client`. The sample can be -configured to use normal unsecure network sockets or sockets secured via DTLS. +configured to use normal insecure network sockets or sockets secured via DTLS. The Zephyr LwM2M library implements the following items: diff --git a/doc/develop/flash_debug/probes.rst b/doc/develop/flash_debug/probes.rst index 38a320099d12..9ac963cc0c99 100644 --- a/doc/develop/flash_debug/probes.rst +++ b/doc/develop/flash_debug/probes.rst @@ -481,7 +481,7 @@ OpenOCD Deprecates HLA ST-Link Interface ======================================== OpenOCD has deprecated the legacy HLA interface used by ST-Link firmware in favor to the -generic DAP interface in Januray 2024 (see `OpenOCD deprecates ST-Link HLA Interface`_) +generic DAP interface in January 2024 (see `OpenOCD deprecates ST-Link HLA Interface`_) in favor of the generic DAP interface. DAP interface is supported by ST-Link firmware since 2015 (from version v2j24). diff --git a/doc/hardware/pinctrl/index.rst b/doc/hardware/pinctrl/index.rst index 98edfeacf586..8549a440b9f9 100644 --- a/doc/hardware/pinctrl/index.rst +++ b/doc/hardware/pinctrl/index.rst @@ -282,7 +282,7 @@ particular state are enclosed in a single Devicetree node. Another popular model is based on having a node for each pin configuration and state. While this model may lead to shorter board pin control files, it also requires to have one node for each pin mapping and state, since in general, -nodes can not be re-used for multiple states. This method is discouraged if +nodes can not be reused for multiple states. This method is discouraged if autogeneration is not an option. .. note:: diff --git a/doc/hardware/porting/board_porting.rst b/doc/hardware/porting/board_porting.rst index 2a7e3844bcbf..07209e934c6a 100644 --- a/doc/hardware/porting/board_porting.rst +++ b/doc/hardware/porting/board_porting.rst @@ -515,7 +515,7 @@ files for a board named ``plank``: Kconfig trees. This file selects the SoC in the Kconfig tree and potential other SoC related - Kconfig settings. This file must not select anything outside the re-usable + Kconfig settings. This file must not select anything outside the reusable Kconfig board and SoC trees. A :file:`Kconfig.plank` may look like this: diff --git a/doc/hardware/porting/soc_porting.rst b/doc/hardware/porting/soc_porting.rst index ca8b9f355b7e..77a4b189e2fd 100644 --- a/doc/hardware/porting/soc_porting.rst +++ b/doc/hardware/porting/soc_porting.rst @@ -225,7 +225,7 @@ files for a SoC: This file selects the SoC family and series in the Kconfig tree and potential other SoC related Kconfig settings. In some cases a SOC_PART_NUMBER. - This file must not select anything outside the re-usable Kconfig SoC tree. + This file must not select anything outside the reusable Kconfig SoC tree. A :file:`Kconfig.soc` may look like this: diff --git a/doc/kernel/data_structures/slist.rst b/doc/kernel/data_structures/slist.rst index cfffe802895e..5a7f960f74ce 100644 --- a/doc/kernel/data_structures/slist.rst +++ b/doc/kernel/data_structures/slist.rst @@ -89,7 +89,7 @@ internal "Z_GENLIST" template API which allows for extracting those fields from arbitrary structures and emits an arbitrarily named set of functions. This allows for implementing more complicated single-linked list variants using the same basic primitives. The -genlist implementor is responsible for a custom implementation of the +genlist implementer is responsible for a custom implementation of the primitive operations only: an "init" step for each struct, and a "get" and "set" primitives for each of head, tail and next pointers on their relevant structs. These inline functions are passed as parameters to diff --git a/doc/kernel/services/threads/index.rst b/doc/kernel/services/threads/index.rst index 1c78982d6847..ac3ee308696a 100644 --- a/doc/kernel/services/threads/index.rst +++ b/doc/kernel/services/threads/index.rst @@ -93,7 +93,7 @@ thread self-exits, or the target thread aborts (either due to a Once a thread has terminated, the kernel guarantees that no use will be made of the thread struct. The memory of such a struct can then be -re-used for any purpose, including spawning a new thread. Note that +reused for any purpose, including spawning a new thread. Note that the thread must be fully terminated, which presents race conditions where a thread's own logic signals completion which is seen by another thread before the kernel processing is complete. Under normal @@ -563,7 +563,7 @@ The following code illustrates the ways a thread can terminate. } If :kconfig:option:`CONFIG_USERSPACE` is enabled, aborting a thread will additionally -mark the thread and stack objects as uninitialized so that they may be re-used. +mark the thread and stack objects as uninitialized so that they may be reused. Runtime Statistics ****************** diff --git a/doc/security/security-overview.rst b/doc/security/security-overview.rst index 53c956cbe53b..1cb6942a6b15 100644 --- a/doc/security/security-overview.rst +++ b/doc/security/security-overview.rst @@ -66,7 +66,7 @@ with security implications. The effects on security of not implementing a MUST or SHOULD, or doing something the specification says MUST NOT or SHOULD NOT be done may be very subtle. Document authors should take the time to elaborate the security implications of not following -recommendations or requirements as most implementors will not have had +recommendations or requirements as most implementers will not have had the benefit of the experience and discussion that produced the specification." diff --git a/doc/services/zbus/index.rst b/doc/services/zbus/index.rst index 72a1eea3c9e1..2601f34a57ad 100644 --- a/doc/services/zbus/index.rst +++ b/doc/services/zbus/index.rst @@ -913,7 +913,7 @@ illustrates the runtime registration usage. .. warning:: - The :c:struct:`zbus_observer_node` can only be re-used in :c:func:`zbus_chan_add_obs_with_node` after removing + The :c:struct:`zbus_observer_node` can only be reused in :c:func:`zbus_chan_add_obs_with_node` after removing the channel observer it was first associated with through :c:func:`zbus_chan_rm_obs`. @@ -974,7 +974,7 @@ Related configuration options: * :kconfig:option:`CONFIG_ZBUS_OBSERVER_NAME` enables the name of observers to be available inside the channels metadata; * :kconfig:option:`CONFIG_ZBUS_PREFER_DYNAMIC_ALLOCATION` instructs zbus to - use dynamic allocation for its internals. That can be disabled by the user and tunned later; + use dynamic allocation for its internals. That can be disabled by the user and tuned later; * :kconfig:option:`CONFIG_ZBUS_MSG_SUBSCRIBER` enables the message subscriber observer type; * :kconfig:option:`CONFIG_ZBUS_MSG_SUBSCRIBER_BUF_ALLOC_DYNAMIC` uses the heap to allocate message buffers; From 66121b7bb861a9e2a9f561f6f4ce38fe7ef340a0 Mon Sep 17 00:00:00 2001 From: Mario Paja Date: Thu, 11 Dec 2025 09:28:37 +0100 Subject: [PATCH 0244/3659] drivers: i2s: stm32 sai fix dma_cfg This change fixes dma_cfg conflict between #99967 and #100223 Signed-off-by: Mario Paja --- drivers/i2s/i2s_stm32_sai.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/i2s/i2s_stm32_sai.c b/drivers/i2s/i2s_stm32_sai.c index 6b556de798b1..63502be25a3f 100644 --- a/drivers/i2s/i2s_stm32_sai.c +++ b/drivers/i2s/i2s_stm32_sai.c @@ -341,12 +341,12 @@ static int i2s_stm32_sai_dma_init(const struct device *dev) hdma->Init.Request = dma_cfg->dma_slot; #endif - if (dma_cfg.source_data_size != dma_cfg.dest_data_size) { + if (dma_cfg->source_data_size != dma_cfg->dest_data_size) { LOG_ERR("Source and destination data sizes are not aligned"); return -EINVAL; } - int idx = find_lsb_set(dma_cfg.source_data_size) - 1; + int idx = find_lsb_set(dma_cfg->source_data_size) - 1; #if defined(CONFIG_DMA_STM32U5) if (idx >= ARRAY_SIZE(dma_src_size)) { From d533ef74ea2bacc26c8c090c2f4c0e585058f1c0 Mon Sep 17 00:00:00 2001 From: McAtee Maxwell Date: Wed, 10 Dec 2025 10:18:24 -0800 Subject: [PATCH 0245/3659] drivers: allow for two different infineon clock init flows - differentiate fixed_factor init priority based on soc family Signed-off-by: McAtee Maxwell --- drivers/clock_control/Kconfig.infineon | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/clock_control/Kconfig.infineon b/drivers/clock_control/Kconfig.infineon index 4bcd3b3bec1a..b4a7a952d559 100644 --- a/drivers/clock_control/Kconfig.infineon +++ b/drivers/clock_control/Kconfig.infineon @@ -35,16 +35,12 @@ config CLOCK_CONTROL_IFX_PERI_CLOCK if CLOCK_CONTROL_IFX_FIXED_FACTOR_CLOCK - config CLOCK_CONTROL_IFX_FIXED_FACTOR_CLOCK_INIT_PRIORITY int "Infineon fixed factor clock driver init priority" - default 31 + default 29 if !SOC_FAMILY_INFINEON_PSOC4 + default 31 if SOC_FAMILY_INFINEON_PSOC4 help Infineon fixed factor clock control driver initialization priority. - This should be higher than CLOCK_CONTROL_INIT_PRIORITY to ensure - fixed-rate clocks are initialized before fixed-factor clocks that - depend on them.Since fixed-factor clocks depend on fixed-rate clocks, - they need a HIGHER priority number so they initialize after their - dependencies. - + This should be lower than the priority of fixed factor clock driver + to ensure the clock paths are initialized before. endif # CLOCK_CONTROL_IFX_FIXED_FACTOR_CLOCK From f24b902f5e563ba913def7a59d14888bde62478f Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Wed, 10 Dec 2025 01:55:08 +0530 Subject: [PATCH 0246/3659] net: l2: ethernet: Add new stats API Add a new API that takes stat type, the networking stack only needs NATIVE stats per-packet, it doesn't need to update vendor stats per-packet. This saves unncessary exchanges in case driver needs to query the firmware for the vendor stats. Signed-off-by: Chaitanya Tata --- doc/releases/release-notes-4.4.rst | 7 + include/zephyr/net/ethernet.h | 18 +++ subsys/net/l2/ethernet/eth_stats.h | 178 ++++++------------------ subsys/net/l2/ethernet/ethernet_stats.c | 10 +- 4 files changed, 78 insertions(+), 135 deletions(-) diff --git a/doc/releases/release-notes-4.4.rst b/doc/releases/release-notes-4.4.rst index 8ede8b4a2a2c..9479cb2287be 100644 --- a/doc/releases/release-notes-4.4.rst +++ b/doc/releases/release-notes-4.4.rst @@ -130,6 +130,13 @@ New APIs and options * :c:struct:`net_eth_mac_config` * :c:macro:`NET_ETH_MAC_DT_CONFIG_INIT` and :c:macro:`NET_ETH_MAC_DT_INST_CONFIG_INIT` + * Added :c:enum:`ethernet_stats_type` and optional ``get_stats_type`` callback in + :c:struct:`ethernet_api` to allow filtering of ethernet statistics by type + (common, vendor, or all). Drivers that support vendor-specific statistics can + implement ``get_stats_type`` to skip expensive FW queries when only common stats + are requested. The existing ``get_stats`` API remains unchanged for backward + compatibility. + * Flash * :dtcompatible:`jedec,mspi-nor` now allows MSPI configuration of read, write and diff --git a/include/zephyr/net/ethernet.h b/include/zephyr/net/ethernet.h index f9dac8b1c536..22110d6fc6d2 100644 --- a/include/zephyr/net/ethernet.h +++ b/include/zephyr/net/ethernet.h @@ -529,6 +529,16 @@ struct ethernet_config { /** @endcond */ +/** Ethernet statistics type (bitmap) */ +enum ethernet_stats_type { + /** Common statistics only (excludes vendor statistics) */ + ETHERNET_STATS_TYPE_COMMON = BIT(0), + /** Vendor statistics only */ + ETHERNET_STATS_TYPE_VENDOR = BIT(1), + /** All statistics */ + ETHERNET_STATS_TYPE_ALL = 0xFFFFFFFFU, +}; + /** Ethernet L2 API operations. */ struct ethernet_api { /** @@ -543,6 +553,14 @@ struct ethernet_api { */ #if defined(CONFIG_NET_STATISTICS_ETHERNET) struct net_stats_eth *(*get_stats)(const struct device *dev); + + /** Optional function to collect ethernet specific statistics with + * type filter. If NULL, get_stats() will be called instead, which + * is equivalent to calling this with ETHERNET_STATS_TYPE_ALL. + * @param type Bitmask of ethernet_stats_type values. + */ + struct net_stats_eth *(*get_stats_type)(const struct device *dev, + uint32_t type); #endif /** Start the device */ diff --git a/subsys/net/l2/ethernet/eth_stats.h b/subsys/net/l2/ethernet/eth_stats.h index b9860938f573..a30b5b8647c4 100644 --- a/subsys/net/l2/ethernet/eth_stats.h +++ b/subsys/net/l2/ethernet/eth_stats.h @@ -14,211 +14,123 @@ #include #include -static inline void eth_stats_update_bytes_rx(struct net_if *iface, - uint32_t bytes) +static inline struct net_stats_eth *eth_stats_get_common(struct net_if *iface) { const struct ethernet_api *api = (const struct ethernet_api *) net_if_get_device(iface)->api; - struct net_stats_eth *stats; - - if (!api->get_stats) { - return; - } - stats = api->get_stats(net_if_get_device(iface)); - if (!stats) { - return; + if (api->get_stats_type != NULL) { + return api->get_stats_type(net_if_get_device(iface), + ETHERNET_STATS_TYPE_COMMON); + } else if (api->get_stats != NULL) { + return api->get_stats(net_if_get_device(iface)); } - stats->bytes.received += bytes; + return NULL; } -static inline void eth_stats_update_bytes_tx(struct net_if *iface, - uint32_t bytes) +static inline void eth_stats_update_bytes_rx(struct net_if *iface, uint32_t bytes) { - const struct ethernet_api *api = (const struct ethernet_api *) - net_if_get_device(iface)->api; - struct net_stats_eth *stats; + struct net_stats_eth *stats = eth_stats_get_common(iface); - if (!api->get_stats) { - return; + if (stats != NULL) { + stats->bytes.received += bytes; } +} - stats = api->get_stats(net_if_get_device(iface)); - if (!stats) { - return; - } +static inline void eth_stats_update_bytes_tx(struct net_if *iface, uint32_t bytes) +{ + struct net_stats_eth *stats = eth_stats_get_common(iface); - stats->bytes.sent += bytes; + if (stats != NULL) { + stats->bytes.sent += bytes; + } } static inline void eth_stats_update_pkts_rx(struct net_if *iface) { - const struct ethernet_api *api = (const struct ethernet_api *) - net_if_get_device(iface)->api; - struct net_stats_eth *stats; + struct net_stats_eth *stats = eth_stats_get_common(iface); - if (!api->get_stats) { - return; - } - - stats = api->get_stats(net_if_get_device(iface)); - if (!stats) { - return; + if (stats != NULL) { + stats->pkts.rx++; } - - stats->pkts.rx++; } static inline void eth_stats_update_pkts_tx(struct net_if *iface) { - const struct ethernet_api *api = (const struct ethernet_api *) - net_if_get_device(iface)->api; - struct net_stats_eth *stats; - - if (!api->get_stats) { - return; - } + struct net_stats_eth *stats = eth_stats_get_common(iface); - stats = api->get_stats(net_if_get_device(iface)); - if (!stats) { - return; + if (stats != NULL) { + stats->pkts.tx++; } - - stats->pkts.tx++; } static inline void eth_stats_update_broadcast_rx(struct net_if *iface) { - const struct ethernet_api *api = (const struct ethernet_api *) - net_if_get_device(iface)->api; - struct net_stats_eth *stats; - - if (!api->get_stats) { - return; - } + struct net_stats_eth *stats = eth_stats_get_common(iface); - stats = api->get_stats(net_if_get_device(iface)); - if (!stats) { - return; + if (stats != NULL) { + stats->broadcast.rx++; } - - stats->broadcast.rx++; } static inline void eth_stats_update_broadcast_tx(struct net_if *iface) { - const struct ethernet_api *api = (const struct ethernet_api *) - net_if_get_device(iface)->api; - struct net_stats_eth *stats; + struct net_stats_eth *stats = eth_stats_get_common(iface); - if (!api->get_stats) { - return; + if (stats != NULL) { + stats->broadcast.tx++; } - - stats = api->get_stats(net_if_get_device(iface)); - if (!stats) { - return; - } - - stats->broadcast.tx++; } static inline void eth_stats_update_multicast_rx(struct net_if *iface) { - const struct ethernet_api *api = (const struct ethernet_api *) - net_if_get_device(iface)->api; - struct net_stats_eth *stats; - - if (!api->get_stats) { - return; - } + struct net_stats_eth *stats = eth_stats_get_common(iface); - stats = api->get_stats(net_if_get_device(iface)); - if (!stats) { - return; + if (stats != NULL) { + stats->multicast.rx++; } - - stats->multicast.rx++; } static inline void eth_stats_update_multicast_tx(struct net_if *iface) { - const struct ethernet_api *api = (const struct ethernet_api *) - net_if_get_device(iface)->api; - struct net_stats_eth *stats; + struct net_stats_eth *stats = eth_stats_get_common(iface); - if (!api->get_stats) { - return; - } - - stats = api->get_stats(net_if_get_device(iface)); - if (!stats) { - return; + if (stats != NULL) { + stats->multicast.tx++; } - - stats->multicast.tx++; } - static inline void eth_stats_update_errors_rx(struct net_if *iface) { struct net_stats_eth *stats; - const struct ethernet_api *api; if (!iface) { return; } - api = ((const struct ethernet_api *) - net_if_get_device(iface)->api); - - if (!api->get_stats) { - return; - } - - stats = api->get_stats(net_if_get_device(iface)); - if (!stats) { - return; + stats = eth_stats_get_common(iface); + if (stats != NULL) { + stats->errors.rx++; } - - stats->errors.rx++; } static inline void eth_stats_update_errors_tx(struct net_if *iface) { - struct net_stats_eth *stats; - const struct ethernet_api *api = ((const struct ethernet_api *) - net_if_get_device(iface)->api); - - if (!api->get_stats) { - return; - } + struct net_stats_eth *stats = eth_stats_get_common(iface); - stats = api->get_stats(net_if_get_device(iface)); - if (!stats) { - return; + if (stats != NULL) { + stats->errors.tx++; } - - stats->errors.tx++; } static inline void eth_stats_update_unknown_protocol(struct net_if *iface) { - struct net_stats_eth *stats; - const struct ethernet_api *api = ((const struct ethernet_api *) - net_if_get_device(iface)->api); + struct net_stats_eth *stats = eth_stats_get_common(iface); - if (!api->get_stats) { - return; + if (stats != NULL) { + stats->unknown_protocol++; } - - stats = api->get_stats(net_if_get_device(iface)); - if (!stats) { - return; - } - - stats->unknown_protocol++; } #else /* CONFIG_NET_STATISTICS_ETHERNET */ diff --git a/subsys/net/l2/ethernet/ethernet_stats.c b/subsys/net/l2/ethernet/ethernet_stats.c index 57d354623f66..3dd211e4cf7d 100644 --- a/subsys/net/l2/ethernet/ethernet_stats.c +++ b/subsys/net/l2/ethernet/ethernet_stats.c @@ -31,12 +31,18 @@ static int eth_stats_get(uint64_t mgmt_request, struct net_if *iface, } eth = net_if_get_device(iface)->api; - if (eth == NULL || eth->get_stats == NULL) { + if (eth == NULL || + (eth->get_stats == NULL && eth->get_stats_type == NULL)) { return -ENOENT; } len_chk = sizeof(struct net_stats_eth); - src = eth->get_stats(net_if_get_device(iface)); + if (eth->get_stats_type != NULL) { + src = eth->get_stats_type(net_if_get_device(iface), + ETHERNET_STATS_TYPE_ALL); + } else { + src = eth->get_stats(net_if_get_device(iface)); + } break; } From 55c492c7c59ea04963179c2d330d64987fb78f78 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Wed, 10 Dec 2025 01:56:31 +0530 Subject: [PATCH 0247/3659] drivers: nrf_wifi: Switch to new stats API nRF70 queries FW to fet the stats, use the new stats API and filter FW query depending on the type. Signed-off-by: Chaitanya Tata --- drivers/wifi/nrf_wifi/inc/net_if.h | 5 +- drivers/wifi/nrf_wifi/src/fmac_main.c | 2 +- drivers/wifi/nrf_wifi/src/net_if.c | 66 +++++++++++++-------------- 3 files changed, 36 insertions(+), 37 deletions(-) diff --git a/drivers/wifi/nrf_wifi/inc/net_if.h b/drivers/wifi/nrf_wifi/inc/net_if.h index 315740ac5d9d..b6c48e00598d 100644 --- a/drivers/wifi/nrf_wifi/inc/net_if.h +++ b/drivers/wifi/nrf_wifi/inc/net_if.h @@ -56,7 +56,10 @@ enum nrf_wifi_status nrf_wifi_if_carr_state_chg(void *os_vif_ctx, int nrf_wifi_stats_get(const struct device *dev, struct net_stats_wifi *stats); -struct net_stats_eth *nrf_wifi_eth_stats_get(const struct device *dev); +#ifdef CONFIG_NET_STATISTICS_ETHERNET +struct net_stats_eth *nrf_wifi_eth_stats_get_type(const struct device *dev, + uint32_t type); +#endif /* CONFIG_NET_STATISTICS_ETHERNET */ void nrf_wifi_set_iface_event_handler(void *os_vif_ctx, struct nrf_wifi_umac_event_set_interface *event, diff --git a/drivers/wifi/nrf_wifi/src/fmac_main.c b/drivers/wifi/nrf_wifi/src/fmac_main.c index 897cb76809cb..a113563cce16 100644 --- a/drivers/wifi/nrf_wifi/src/fmac_main.c +++ b/drivers/wifi/nrf_wifi/src/fmac_main.c @@ -978,7 +978,7 @@ static const struct net_wifi_mgmt_offload wifi_offload_ops = { .wifi_iface.get_capabilities = nrf_wifi_if_caps_get, .wifi_iface.send = nrf_wifi_if_send, #ifdef CONFIG_NET_STATISTICS_ETHERNET - .wifi_iface.get_stats = nrf_wifi_eth_stats_get, + .wifi_iface.get_stats_type = nrf_wifi_eth_stats_get_type, #endif /* CONFIG_NET_STATISTICS_ETHERNET */ #ifdef CONFIG_NET_L2_WIFI_MGMT .wifi_mgmt_api = &nrf_wifi_mgmt_ops, diff --git a/drivers/wifi/nrf_wifi/src/net_if.c b/drivers/wifi/nrf_wifi/src/net_if.c index 8f7750031476..ea1b146e0538 100644 --- a/drivers/wifi/nrf_wifi/src/net_if.c +++ b/drivers/wifi/nrf_wifi/src/net_if.c @@ -1210,7 +1210,8 @@ int nrf_wifi_if_set_config_zep(const struct device *dev, } #ifdef CONFIG_NET_STATISTICS_ETHERNET -struct net_stats_eth *nrf_wifi_eth_stats_get(const struct device *dev) +struct net_stats_eth *nrf_wifi_eth_stats_get_type(const struct device *dev, + uint32_t type) { struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL; #ifdef CONFIG_NET_STATISTICS_ETHERNET_VENDOR @@ -1222,24 +1223,34 @@ struct net_stats_eth *nrf_wifi_eth_stats_get(const struct device *dev) const uint8_t *fw_stats_bytes; size_t i; int vendor_idx = 0; -#endif /* CONFIG_NET_STATISTICS_ETHERNET_VENDOR */ + const char **key_ptr; + uint32_t *val_ptr; + uint32_t val; +#endif if (!dev) { LOG_ERR("%s Device not found", __func__); - goto out; + goto err; } vif_ctx_zep = dev->data; if (!vif_ctx_zep) { LOG_ERR("%s: vif_ctx_zep is NULL", __func__); - goto out; + goto err; + } + + if (!(type & ETHERNET_STATS_TYPE_VENDOR)) { +#ifdef CONFIG_NET_STATISTICS_ETHERNET_VENDOR + vif_ctx_zep->eth_stats.vendor = NULL; +#endif + goto done; } #ifdef CONFIG_NET_STATISTICS_ETHERNET_VENDOR rpu_ctx_zep = vif_ctx_zep->rpu_ctx_zep; if (!rpu_ctx_zep || !rpu_ctx_zep->rpu_ctx) { LOG_ERR("%s: rpu_ctx_zep or rpu_ctx is NULL", __func__); - goto out; + goto err; } memset(&stats, 0, sizeof(stats)); @@ -1248,7 +1259,7 @@ struct net_stats_eth *nrf_wifi_eth_stats_get(const struct device *dev) &stats); if (status != NRF_WIFI_STATUS_SUCCESS) { LOG_ERR("%s: Failed to get RPU stats", __func__); - goto ret; + goto done; } /* Treat stats.fw as a blob and divide into uint32_t chunks */ @@ -1257,49 +1268,34 @@ struct net_stats_eth *nrf_wifi_eth_stats_get(const struct device *dev) fw_stats_bytes = (const uint8_t *)&stats.fw; vendor_idx = 0; - for (i = 0; i < num_uint32 && vendor_idx < MAX_VENDOR_STATS - 1; i++) { - uint32_t val; - const char **key_ptr; - uint32_t *val_ptr; - - /* Extract uint32_t value from blob */ - memcpy(&val, fw_stats_bytes + i * sizeof(uint32_t), sizeof(uint32_t)); + memcpy(&val, fw_stats_bytes + i * sizeof(uint32_t), + sizeof(uint32_t)); - /* Create key name */ - snprintk(vif_ctx_zep->vendor_key_strings[vendor_idx], 16, "fw_%zu", i); + snprintk(vif_ctx_zep->vendor_key_strings[vendor_idx], 16, + "fw_%zu", i); - /* Assign key */ - key_ptr = (const char **) - &vif_ctx_zep->eth_stats_vendor_data[vendor_idx].key; + key_ptr = (const char **) &vif_ctx_zep->eth_stats_vendor_data[vendor_idx].key; *key_ptr = vif_ctx_zep->vendor_key_strings[vendor_idx]; - /* Assign value */ - val_ptr = (uint32_t *) - &vif_ctx_zep->eth_stats_vendor_data[vendor_idx].value; + val_ptr = (uint32_t *) &vif_ctx_zep->eth_stats_vendor_data[vendor_idx].value; *val_ptr = val; vendor_idx++; } - /* Null terminator entry */ - { - const char **key_ptr = (const char **) - &vif_ctx_zep->eth_stats_vendor_data[vendor_idx].key; - uint32_t *val_ptr = (uint32_t *) - &vif_ctx_zep->eth_stats_vendor_data[vendor_idx].value; - - *key_ptr = NULL; - *val_ptr = 0; - } + key_ptr = (const char **) &vif_ctx_zep->eth_stats_vendor_data[vendor_idx].key; + val_ptr = (uint32_t *) &vif_ctx_zep->eth_stats_vendor_data[vendor_idx].value; + *key_ptr = NULL; + *val_ptr = 0; - /* Point to the static vendor data */ vif_ctx_zep->eth_stats.vendor = vif_ctx_zep->eth_stats_vendor_data; +#endif -ret: -#endif /* CONFIG_NET_STATISTICS_ETHERNET_VENDOR */ +done: return &vif_ctx_zep->eth_stats; -out: + +err: return NULL; } #endif /* CONFIG_NET_STATISTICS_ETHERNET */ From f312cc341bec4087485bbd153511f34d81c95191 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Wed, 10 Dec 2025 02:04:06 +0530 Subject: [PATCH 0248/3659] tests: drivers: nrf_wifi: Add twister combo for vendor stats This ensures vendor stats always builds. Signed-off-by: Chaitanya Tata --- tests/drivers/wifi/nrf_wifi/testcase.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/drivers/wifi/nrf_wifi/testcase.yaml b/tests/drivers/wifi/nrf_wifi/testcase.yaml index 085d02f407d2..6dc68db29a97 100644 --- a/tests/drivers/wifi/nrf_wifi/testcase.yaml +++ b/tests/drivers/wifi/nrf_wifi/testcase.yaml @@ -44,3 +44,7 @@ tests: extra_configs: - CONFIG_NET_PKT_BUF_TX_DATA_ALLOC_ALIGN_LEN=4 - CONFIG_NET_BUF_VARIABLE_DATA_SIZE=y + drivers.wifi.build.ethernet_stats: + extra_configs: + - CONFIG_NET_STATISTICS_ETHERNET=y + - CONFIG_NET_STATISTICS_ETHERNET_VENDOR=y From d404fa687986c3fa48fbbec0972c4e0e26251c1f Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Wed, 10 Dec 2025 22:46:10 +0530 Subject: [PATCH 0249/3659] net: lib: shell: Rejig statistics Use the newly added API to get specific type of stats (if supported) but also keep the backwards compatibility. Signed-off-by: Chaitanya Tata --- subsys/net/lib/shell/stats.c | 259 ++++++++++++++++++++--------------- 1 file changed, 152 insertions(+), 107 deletions(-) diff --git a/subsys/net/lib/shell/stats.c b/subsys/net/lib/shell/stats.c index bac8eb31f235..76a985f285fd 100644 --- a/subsys/net/lib/shell/stats.c +++ b/subsys/net/lib/shell/stats.c @@ -9,6 +9,7 @@ LOG_MODULE_DECLARE(net_shell); #include +#include #include "net_shell_private.h" @@ -21,6 +22,12 @@ enum net_shell_stats_format { NET_SHELL_STATS_FORMAT_BOTH }; +/** Shell stats options passed via user_data */ +struct net_shell_stats_options { + enum net_shell_stats_format format; + uint32_t type; /* Bitmask of ethernet_stats_type */ +}; + #if defined(CONFIG_NET_STATISTICS) @@ -55,74 +62,86 @@ static const char *priority2str(enum net_priority priority) static void print_eth_stats(struct net_if *iface, struct net_stats_eth *data, const struct shell *sh, struct net_shell_user_data *user_data) { - PR("Statistics for Ethernet interface %p [%d]\n", iface, - net_if_get_by_iface(iface)); - - PR("Bytes received : %llu\n", data->bytes.received); - PR("Bytes sent : %llu\n", data->bytes.sent); - PR("Packets received : %u\n", data->pkts.rx); - PR("Packets sent : %u\n", data->pkts.tx); - PR("Bcast received : %u\n", data->broadcast.rx); - PR("Bcast sent : %u\n", data->broadcast.tx); - PR("Mcast received : %u\n", data->multicast.rx); - PR("Mcast sent : %u\n", data->multicast.tx); - - PR("Send errors : %u\n", data->errors.tx); - PR("Receive errors : %u\n", data->errors.rx); - PR("Collisions : %u\n", data->collisions); - PR("Send Drops : %u\n", data->tx_dropped); - PR("Send timeouts : %u\n", data->tx_timeout_count); - PR("Send restarts : %u\n", data->tx_restart_queue); - PR("Unknown protocol : %u\n", data->unknown_protocol); - - PR("Checksum offload : RX good %u errors %u\n", - data->csum.rx_csum_offload_good, - data->csum.rx_csum_offload_errors); - PR("Flow control : RX xon %u xoff %u TX xon %u xoff %u\n", - data->flow_control.rx_flow_control_xon, - data->flow_control.rx_flow_control_xoff, - data->flow_control.tx_flow_control_xon, - data->flow_control.tx_flow_control_xoff); - PR("ECC errors : uncorrected %u corrected %u\n", - data->error_details.uncorr_ecc_errors, - data->error_details.corr_ecc_errors); - PR("HW timestamp : RX cleared %u TX timeout %u skipped %u\n", - data->hw_timestamp.rx_hwtstamp_cleared, - data->hw_timestamp.tx_hwtstamp_timeouts, - data->hw_timestamp.tx_hwtstamp_skipped); - - PR("RX errors : %5s %5s %5s %5s %5s %5s %5s %5s %5s %5s %5s\n", - "Len", "Over", "CRC", "Frame", "NoBuf", "Miss", "Long", "Short", - "Align", "DMA", "Alloc"); - PR(" %5u %5u %5u %5u %5u %5u %5u %5u %5u %5u %5u\n", - data->error_details.rx_length_errors, - data->error_details.rx_over_errors, - data->error_details.rx_crc_errors, - data->error_details.rx_frame_errors, - data->error_details.rx_no_buffer_count, - data->error_details.rx_missed_errors, - data->error_details.rx_long_length_errors, - data->error_details.rx_short_length_errors, - data->error_details.rx_align_errors, - data->error_details.rx_dma_failed, - data->error_details.rx_buf_alloc_failed); - PR("TX errors : %5s %8s %5s %10s %7s %5s\n", - "Abort", "Carrier", "Fifo", "Heartbeat", "Window", "DMA"); - PR(" %5u %8u %5u %10u %7u %5u\n", - data->error_details.tx_aborted_errors, - data->error_details.tx_carrier_errors, - data->error_details.tx_fifo_errors, - data->error_details.tx_heartbeat_errors, - data->error_details.tx_window_errors, - data->error_details.tx_dma_failed); + struct net_shell_stats_options *opts = NULL; + uint32_t type = ETHERNET_STATS_TYPE_ALL; + + if (user_data != NULL && user_data->user_data != NULL) { + opts = (struct net_shell_stats_options *)user_data->user_data; + type = opts->type; + } + + /* Print common stats if requested */ + if (type & ETHERNET_STATS_TYPE_COMMON) { + PR("Statistics for Ethernet interface %p [%d]\n", iface, + net_if_get_by_iface(iface)); + + PR("Bytes received : %llu\n", data->bytes.received); + PR("Bytes sent : %llu\n", data->bytes.sent); + PR("Packets received : %u\n", data->pkts.rx); + PR("Packets sent : %u\n", data->pkts.tx); + PR("Bcast received : %u\n", data->broadcast.rx); + PR("Bcast sent : %u\n", data->broadcast.tx); + PR("Mcast received : %u\n", data->multicast.rx); + PR("Mcast sent : %u\n", data->multicast.tx); + + PR("Send errors : %u\n", data->errors.tx); + PR("Receive errors : %u\n", data->errors.rx); + PR("Collisions : %u\n", data->collisions); + PR("Send Drops : %u\n", data->tx_dropped); + PR("Send timeouts : %u\n", data->tx_timeout_count); + PR("Send restarts : %u\n", data->tx_restart_queue); + PR("Unknown protocol : %u\n", data->unknown_protocol); + + PR("Checksum offload : RX good %u errors %u\n", + data->csum.rx_csum_offload_good, + data->csum.rx_csum_offload_errors); + PR("Flow control : RX xon %u xoff %u TX xon %u xoff %u\n", + data->flow_control.rx_flow_control_xon, + data->flow_control.rx_flow_control_xoff, + data->flow_control.tx_flow_control_xon, + data->flow_control.tx_flow_control_xoff); + PR("ECC errors : uncorrected %u corrected %u\n", + data->error_details.uncorr_ecc_errors, + data->error_details.corr_ecc_errors); + PR("HW timestamp : RX cleared %u TX timeout %u skipped %u\n", + data->hw_timestamp.rx_hwtstamp_cleared, + data->hw_timestamp.tx_hwtstamp_timeouts, + data->hw_timestamp.tx_hwtstamp_skipped); + + PR("RX errors : %5s %5s %5s %5s %5s %5s %5s %5s %5s %5s %5s\n", + "Len", "Over", "CRC", "Frame", "NoBuf", "Miss", "Long", "Short", + "Align", "DMA", "Alloc"); + PR(" %5u %5u %5u %5u %5u %5u %5u %5u %5u %5u %5u\n", + data->error_details.rx_length_errors, + data->error_details.rx_over_errors, + data->error_details.rx_crc_errors, + data->error_details.rx_frame_errors, + data->error_details.rx_no_buffer_count, + data->error_details.rx_missed_errors, + data->error_details.rx_long_length_errors, + data->error_details.rx_short_length_errors, + data->error_details.rx_align_errors, + data->error_details.rx_dma_failed, + data->error_details.rx_buf_alloc_failed); + PR("TX errors : %5s %8s %5s %10s %7s %5s\n", + "Abort", "Carrier", "Fifo", "Heartbeat", "Window", "DMA"); + PR(" %5u %8u %5u %10u %7u %5u\n", + data->error_details.tx_aborted_errors, + data->error_details.tx_carrier_errors, + data->error_details.tx_fifo_errors, + data->error_details.tx_heartbeat_errors, + data->error_details.tx_window_errors, + data->error_details.tx_dma_failed); + } #if defined(CONFIG_NET_STATISTICS_ETHERNET_VENDOR) - if (data->vendor) { - size_t i = 0; + /* Print vendor stats if requested - format options only apply here */ + if ((type & ETHERNET_STATS_TYPE_VENDOR) && data->vendor) { enum net_shell_stats_format format = NET_SHELL_STATS_FORMAT_DEFAULT; + size_t i = 0; - if (user_data != NULL) { - format = *(enum net_shell_stats_format *)user_data->user_data; + if (opts != NULL) { + format = opts->format; } PR("Vendor specific statistics for Ethernet interface %p [%d]:\n", @@ -619,13 +638,30 @@ static void net_shell_print_statistics(struct net_if *iface, void *user_data) #if defined(CONFIG_NET_STATISTICS_ETHERNET) && \ defined(CONFIG_NET_STATISTICS_USER_API) if (iface && net_if_l2(iface) == &NET_L2_GET_NAME(ETHERNET)) { - struct net_stats_eth eth_data; - int ret; + const struct ethernet_api *eth_api; + struct net_stats_eth *eth_data = NULL; + uint32_t type = ETHERNET_STATS_TYPE_ALL; - ret = net_mgmt(NET_REQUEST_STATS_GET_ETHERNET, iface, - ð_data, sizeof(eth_data)); - if (!ret) { - print_eth_stats(iface, ð_data, sh, data); + if (data != NULL && data->user_data != NULL) { + struct net_shell_stats_options *opts = data->user_data; + + type = opts->type; + } + + eth_api = net_if_get_device(iface)->api; + if (eth_api != NULL) { + /* Use get_stats_type if available for type filtering */ + if (eth_api->get_stats_type != NULL) { + eth_data = eth_api->get_stats_type( + net_if_get_device(iface), type); + } else if (eth_api->get_stats != NULL) { + eth_data = eth_api->get_stats( + net_if_get_device(iface)); + } + } + + if (eth_data != NULL) { + print_eth_stats(iface, eth_data, sh, data); } } #endif /* CONFIG_NET_STATISTICS_ETHERNET && CONFIG_NET_STATISTICS_USER_API */ @@ -653,31 +689,45 @@ static void net_shell_print_statistics_all(struct net_shell_user_data *data) net_if_foreach(net_shell_print_statistics, data); } } + +static void parse_stats_options(size_t argc, char *argv[], int start_idx, + struct net_shell_stats_options *opts) +{ + opts->format = NET_SHELL_STATS_FORMAT_DEFAULT; + opts->type = ETHERNET_STATS_TYPE_ALL; + + for (int i = start_idx; i < argc && argv[i] != NULL; i++) { + /* Format options */ + if (strcmp(argv[i], "key-value") == 0) { + opts->format = NET_SHELL_STATS_FORMAT_KEY_VALUE; + } else if (strcmp(argv[i], "hex-blob") == 0) { + opts->format = NET_SHELL_STATS_FORMAT_HEX_BLOB; + } else if (strcmp(argv[i], "both") == 0) { + opts->format = NET_SHELL_STATS_FORMAT_BOTH; + /* Type filter options */ + } else if (strcmp(argv[i], "common") == 0) { + opts->type = ETHERNET_STATS_TYPE_COMMON; + } else if (strcmp(argv[i], "vendor") == 0) { + opts->type = ETHERNET_STATS_TYPE_VENDOR; + } else if (strcmp(argv[i], "all") == 0) { + opts->type = ETHERNET_STATS_TYPE_ALL; + } + } +} #endif /* CONFIG_NET_STATISTICS */ int cmd_net_stats_all(const struct shell *sh, size_t argc, char *argv[]) { #if defined(CONFIG_NET_STATISTICS) struct net_shell_user_data user_data; -#endif - -#if defined(CONFIG_NET_STATISTICS) - enum net_shell_stats_format format = NET_SHELL_STATS_FORMAT_DEFAULT; + struct net_shell_stats_options opts; user_data.sh = sh; - /* Parse format argument if provided */ - if (argc > 1) { - if (strcmp(argv[1], "key-value") == 0) { - format = NET_SHELL_STATS_FORMAT_KEY_VALUE; - } else if (strcmp(argv[1], "hex-blob") == 0) { - format = NET_SHELL_STATS_FORMAT_HEX_BLOB; - } else if (strcmp(argv[1], "both") == 0) { - format = NET_SHELL_STATS_FORMAT_BOTH; - } - } + /* Parse options starting from argv[1] */ + parse_stats_options(argc, argv, 1, &opts); - user_data.user_data = &format; + user_data.user_data = &opts; /* Print global network statistics */ net_shell_print_statistics_all(&user_data); @@ -697,6 +747,7 @@ int cmd_net_stats_iface(const struct shell *sh, size_t argc, char *argv[]) #if defined(CONFIG_NET_STATISTICS) #if defined(CONFIG_NET_STATISTICS_PER_INTERFACE) struct net_shell_user_data data; + struct net_shell_stats_options opts; struct net_if *iface; char *endptr; int idx; @@ -722,22 +773,12 @@ int cmd_net_stats_iface(const struct shell *sh, size_t argc, char *argv[]) return -ENOEXEC; } - enum net_shell_stats_format format = NET_SHELL_STATS_FORMAT_DEFAULT; - data.sh = sh; - /* Parse format argument if provided */ - if (argc > 2) { - if (strcmp(argv[2], "key-value") == 0) { - format = NET_SHELL_STATS_FORMAT_KEY_VALUE; - } else if (strcmp(argv[2], "hex-blob") == 0) { - format = NET_SHELL_STATS_FORMAT_HEX_BLOB; - } else if (strcmp(argv[2], "both") == 0) { - format = NET_SHELL_STATS_FORMAT_BOTH; - } - } + /* Parse options starting from argv[2] */ + parse_stats_options(argc, argv, 2, &opts); - data.user_data = &format; + data.user_data = &opts; net_shell_print_statistics(iface, &data); #else @@ -766,8 +807,8 @@ static int cmd_net_stats(const struct shell *sh, size_t argc, char *argv[]) if (strcmp(argv[1], "reset") == 0) { net_stats_reset(NULL); } else { - /* Shift arguments for iface command */ - cmd_net_stats_iface(sh, argc - 1, &argv[1]); + /* Pass arguments directly - cmd_net_stats_iface expects index in argv[1] */ + cmd_net_stats_iface(sh, argc, argv); } #else ARG_UNUSED(argc); @@ -789,19 +830,23 @@ static int cmd_net_stats(const struct shell *sh, size_t argc, char *argv[]) SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_stats, SHELL_CMD(all, NULL, "Show network statistics for all network interfaces.\n" - "Usage: net stats all [key-value|hex-blob|both]", + "Usage: net stats all [common|vendor|all] [key-value|hex-blob|both]", cmd_net_stats_all), SHELL_CMD(iface, IFACE_DYN_CMD, - "'net stats [key-value|hex-blob|both]' shows network statistics for " + "'net stats [options]' shows network statistics for " "one specific network interface.\n" - "Format options:\n" - " key-value: Show vendor stats as key-value pairs (default)\n" - " hex-blob: Show vendor stats as hex blob for parsing\n" - " both: Show both key-value and hex blob formats", + "Type filter:\n" + " common: Only common stats (skips FW query)\n" + " vendor: Only vendor-specific stats\n" + " all: All stats (default)\n" + "Vendor stats format (only applies when vendor stats shown):\n" + " key-value: Key-value pairs (default)\n" + " hex-blob: Hex blob for parsing\n" + " both: Both formats", cmd_net_stats_iface), SHELL_SUBCMD_SET_END ); SHELL_SUBCMD_ADD((net), stats, &net_cmd_stats, "Show network statistics.", - cmd_net_stats, 1, 3); + cmd_net_stats, 1, 4); From 46a60bb7d92a3bcac6ce18ad26dc9a3e3b1f71de Mon Sep 17 00:00:00 2001 From: Keith Short Date: Tue, 9 Dec 2025 11:45:35 -0700 Subject: [PATCH 0250/3659] drivers: i2c: Fix default setting for I2C dump allowlist The option CONFIG_I2C_DUMP_MESSAGES_ALLOWLIST should automatically be turned on if the depedencies are satisfied. Signed-off-by: Keith Short --- drivers/i2c/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig index c920bd9727e0..57c7838f3147 100644 --- a/drivers/i2c/Kconfig +++ b/drivers/i2c/Kconfig @@ -47,6 +47,7 @@ config I2C_DUMP_MESSAGES_ALLOWLIST bool "Use allowlist for logging of I2C transactions" depends on I2C_DUMP_MESSAGES depends on DT_HAS_ZEPHYR_I2C_DUMP_ALLOWLIST_ENABLED + default y help Use allowlist to specify which devices transactions should be logged. The allowlist is defined in the devicetree using the compatible string of From 1ef630572b7b0634f475da4eb03891bd8c514486 Mon Sep 17 00:00:00 2001 From: Dmitrii Sharshakov Date: Tue, 9 Dec 2025 19:13:12 +0100 Subject: [PATCH 0251/3659] MAINTAINERS: add TF-M PSA Settings backend collaborators Add myself alongside @seankyer and @tomi-font as the engineers involved in development of this backend. Signed-off-by: Dmitrii Sharshakov --- MAINTAINERS.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index 9cf63201a3a6..f30cd265aa7e 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -4750,6 +4750,16 @@ Settings: - samples/subsys/settings/ - doc/services/storage/settings/ - tests/subsys/settings_commit_prio/ + file-groups: + - name: TF-M PSA backend + collaborators: + - dsseng + - seankyer + - tomi-font + files: + - subsys/settings/src/settings_tfm_psa* + - tests/subsys/settings/functional/tfm_psa/ + - tests/subsys/settings/tfm_psa/ labels: - "area: Settings" tests: From 88b39fd6f912db5c532aa53ae528d095b15f832d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Pouiller?= Date: Tue, 9 Dec 2025 17:12:43 +0100 Subject: [PATCH 0252/3659] drivers: spi: siwx91x: Simplify gspi_siwx91x_config() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The bit_rate variable does not bring any benefit. Signed-off-by: Jérôme Pouiller --- drivers/spi/spi_silabs_siwx91x_gspi.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/spi/spi_silabs_siwx91x_gspi.c b/drivers/spi/spi_silabs_siwx91x_gspi.c index 1ff4723c44b4..092c67929d60 100644 --- a/drivers/spi/spi_silabs_siwx91x_gspi.c +++ b/drivers/spi/spi_silabs_siwx91x_gspi.c @@ -105,7 +105,6 @@ static int gspi_siwx91x_config(const struct device *dev, const struct spi_config { __maybe_unused struct gspi_siwx91x_data *data = dev->data; const struct gspi_siwx91x_config *cfg = dev->config; - uint32_t bit_rate = spi_cfg->frequency; uint32_t clk_div_factor; uint32_t actual_freq; uint32_t clock_rate; @@ -137,7 +136,7 @@ static int gspi_siwx91x_config(const struct device *dev, const struct spi_config } /* Configure clock divider based on the requested bit rate */ - if (bit_rate > GSPI_MAX_BAUDRATE_FOR_DYNAMIC_CLOCK) { + if (spi_cfg->frequency > GSPI_MAX_BAUDRATE_FOR_DYNAMIC_CLOCK) { clk_div_factor = 1; } else { ret = clock_control_get_rate(cfg->clock_dev, cfg->clock_subsys, &clock_rate); @@ -159,7 +158,7 @@ static int gspi_siwx91x_config(const struct device *dev, const struct spi_config } /* Configure data sampling edge for high-speed transfers */ - if (bit_rate > GSPI_MAX_BAUDRATE_FOR_POS_EDGE_SAMPLE) { + if (spi_cfg->frequency > GSPI_MAX_BAUDRATE_FOR_POS_EDGE_SAMPLE) { cfg->reg->GSPI_BUS_MODE_b.GSPI_DATA_SAMPLE_EDGE = 1; } From 115241c645e3cf6ee9ecd7f8c42208d55efddd1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Pouiller?= Date: Tue, 9 Dec 2025 17:17:17 +0100 Subject: [PATCH 0253/3659] drivers: spi: siwx91x: Simplify error management MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In functions requiring to lock/release resources, it is less error prone to have only one exit point and user goto to manage errors. The behavior of the new code is exactly identical to the initial one. Signed-off-by: Jérôme Pouiller --- drivers/spi/spi_silabs_siwx91x_gspi.c | 30 +++++++++++++-------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/drivers/spi/spi_silabs_siwx91x_gspi.c b/drivers/spi/spi_silabs_siwx91x_gspi.c index 092c67929d60..7b1d51bdd6d3 100644 --- a/drivers/spi/spi_silabs_siwx91x_gspi.c +++ b/drivers/spi/spi_silabs_siwx91x_gspi.c @@ -626,7 +626,7 @@ static int gspi_siwx91x_transceive(const struct device *dev, const struct spi_co spi_callback_t cb, void *userdata) { struct gspi_siwx91x_data *data = dev->data; - int ret = 0; + int ret; ret = pm_device_runtime_get(dev); if (ret < 0) { @@ -635,40 +635,38 @@ static int gspi_siwx91x_transceive(const struct device *dev, const struct spi_co if (!spi_siwx91x_is_dma_enabled_instance(dev) && asynchronous) { ret = -ENOTSUP; - pm_device_runtime_put(dev); - return ret; + goto pm; } spi_context_lock(&data->ctx, asynchronous, cb, userdata, config); - /* Configure the device if it is not already configured */ if (!spi_context_configured(&data->ctx, config)) { ret = gspi_siwx91x_config(dev, config, cb, userdata); if (ret) { - spi_context_release(&data->ctx, ret); - pm_device_runtime_put(dev); - return ret; + goto context; } } spi_context_buffers_setup(&data->ctx, tx_bufs, rx_bufs, SPI_WORD_SIZE_GET(config->operation) / 8); - /* Check if DMA is enabled */ if (spi_siwx91x_is_dma_enabled_instance(dev)) { - /* Perform DMA transceive */ ret = gspi_siwx91x_transceive_dma(dev, config); - if (ret < 0) { - pm_device_runtime_put(dev); - } - spi_context_release(&data->ctx, ret); } else { - /* Perform synchronous polling transceive */ ret = gspi_siwx91x_transceive_polling_sync(dev, &data->ctx); - spi_context_unlock_unconditionally(&data->ctx); - pm_device_runtime_put(dev); } + if (spi_siwx91x_is_dma_enabled_instance(dev) && !ret) { + /* pm_device_runtime_put(dev) is called from the dma callback */ + spi_context_release(&data->ctx, ret); + return ret; + } + +context: + spi_context_release(&data->ctx, ret); +pm: + pm_device_runtime_put(dev); return ret; + } static int gspi_siwx91x_transceive_sync(const struct device *dev, const struct spi_config *config, From 1c356d0ed1d0cadc12a577334d87606ac2989b52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Pouiller?= Date: Tue, 9 Dec 2025 17:20:50 +0100 Subject: [PATCH 0254/3659] drivers: spi: siwx91x: Fix use of GSPI_DATA_SAMPLE_EDGE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Until now, GSPI_DATA_SAMPLE_EDGE was enabled as soon as the user requested > 40Mhz (even if the actual frequency was in fact 40Mhz). However, at 40MHz and at 80MHz, use of GSPI_DATA_SAMPLE_EDGE generated read errors on the last bit of the transaction: Buffer contents are different: [...],0xaa,0xaa,0xaa,0xaa, vs: [...],0xaa,0xaa,0xaa,0xab, I have not found any case where GSPI_DATA_SAMPLE_EDGE is useful, so this patch just remove this parameter. Signed-off-by: Jérôme Pouiller --- drivers/spi/spi_silabs_siwx91x_gspi.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/spi/spi_silabs_siwx91x_gspi.c b/drivers/spi/spi_silabs_siwx91x_gspi.c index 7b1d51bdd6d3..fa92fd147cc3 100644 --- a/drivers/spi/spi_silabs_siwx91x_gspi.c +++ b/drivers/spi/spi_silabs_siwx91x_gspi.c @@ -25,7 +25,6 @@ LOG_MODULE_REGISTER(spi_siwx91x_gspi, CONFIG_SPI_LOG_LEVEL); #include "spi_context.h" #define GSPI_MAX_BAUDRATE_FOR_DYNAMIC_CLOCK 110000000 -#define GSPI_MAX_BAUDRATE_FOR_POS_EDGE_SAMPLE 40000000 #define GSPI_DMA_MAX_DESCRIPTOR_TRANSFER_SIZE 4096 #define SPI_HIGH_BURST_FREQ_THRESHOLD_HZ 10000000 @@ -157,11 +156,6 @@ static int gspi_siwx91x_config(const struct device *dev, const struct spi_config cfg->reg->GSPI_CLK_CONFIG_b.GSPI_CLK_SYNC = 1; } - /* Configure data sampling edge for high-speed transfers */ - if (spi_cfg->frequency > GSPI_MAX_BAUDRATE_FOR_POS_EDGE_SAMPLE) { - cfg->reg->GSPI_BUS_MODE_b.GSPI_DATA_SAMPLE_EDGE = 1; - } - /* Set the clock divider factor */ cfg->reg->GSPI_CLK_DIV = clk_div_factor; From 918426ff3010d0195a0a512be95dbd1826adbc3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Pouiller?= Date: Tue, 9 Dec 2025 17:24:41 +0100 Subject: [PATCH 0255/3659] drivers: spi: siwx91x: clk_div_factor can't be 0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In gspi_siwx91x_config(), clk_div_factor can't be < 1. Therefore, we can remove the dead code. This code has been tested with tests/drivers/spi/spi_loopback, with a PLL clock configured to 160MHz and a bus clock to 80MHz with success. I have not found the case where change in GSPI_CLK_CONFIG are required. Signed-off-by: Jérôme Pouiller --- drivers/spi/spi_silabs_siwx91x_gspi.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/spi/spi_silabs_siwx91x_gspi.c b/drivers/spi/spi_silabs_siwx91x_gspi.c index fa92fd147cc3..48f10027947f 100644 --- a/drivers/spi/spi_silabs_siwx91x_gspi.c +++ b/drivers/spi/spi_silabs_siwx91x_gspi.c @@ -151,11 +151,6 @@ static int gspi_siwx91x_config(const struct device *dev, const struct spi_config } } - if (clk_div_factor < 1) { - cfg->reg->GSPI_CLK_CONFIG_b.GSPI_CLK_EN = 1; - cfg->reg->GSPI_CLK_CONFIG_b.GSPI_CLK_SYNC = 1; - } - /* Set the clock divider factor */ cfg->reg->GSPI_CLK_DIV = clk_div_factor; From 0623e6f3903633ac09fa5a2184c57023e081d9b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Pouiller?= Date: Tue, 9 Dec 2025 17:43:12 +0100 Subject: [PATCH 0256/3659] drivers: spi: siwx91x: Simplify gspi_siwx91x_pick_lower_freq() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since actual_hz is no more needed, we can simplify gspi_siwx91x_pick_lower_freq(). Signed-off-by: Jérôme Pouiller --- drivers/spi/spi_silabs_siwx91x_gspi.c | 31 ++++++--------------------- 1 file changed, 7 insertions(+), 24 deletions(-) diff --git a/drivers/spi/spi_silabs_siwx91x_gspi.c b/drivers/spi/spi_silabs_siwx91x_gspi.c index 48f10027947f..29aef6abd2f9 100644 --- a/drivers/spi/spi_silabs_siwx91x_gspi.c +++ b/drivers/spi/spi_silabs_siwx91x_gspi.c @@ -76,27 +76,17 @@ static bool spi_siwx91x_is_dma_enabled_instance(const struct device *dev) #endif } -void gspi_siwx91x_pick_lower_freq(uint32_t clock_hz, uint32_t requested_hz, uint32_t *actual_hz_out, - uint32_t *div_out) +static uint32_t gspi_siwx91x_get_divider(uint32_t clock_hz, uint32_t requested_hz) { - /* Calculate divider that ensures freq <= requested */ uint32_t divider = DIV_ROUND_UP(clock_hz, 2 * requested_hz); - uint32_t actual_hz; + uint32_t actual_freq = clock_hz / (2U * divider); - if (divider == 0U) { - divider = 1U; + if (requested_hz != actual_freq) { + LOG_INF("Requested %u Hz, programmed %u Hz (divider=%u)", + requested_hz, actual_freq, divider); } - /* Compute the actual achievable frequency */ - actual_hz = clock_hz / (2U * divider); - - if (actual_hz_out) { - *actual_hz_out = actual_hz; - } - - if (div_out) { - *div_out = divider; - } + return divider; } static int gspi_siwx91x_config(const struct device *dev, const struct spi_config *spi_cfg, @@ -105,7 +95,6 @@ static int gspi_siwx91x_config(const struct device *dev, const struct spi_config __maybe_unused struct gspi_siwx91x_data *data = dev->data; const struct gspi_siwx91x_config *cfg = dev->config; uint32_t clk_div_factor; - uint32_t actual_freq; uint32_t clock_rate; int ret; __maybe_unused int channel_filter; @@ -142,13 +131,7 @@ static int gspi_siwx91x_config(const struct device *dev, const struct spi_config if (ret) { return ret; } - - gspi_siwx91x_pick_lower_freq(clock_rate, spi_cfg->frequency, &actual_freq, - &clk_div_factor); - if (spi_cfg->frequency != actual_freq) { - LOG_INF("Requested %u Hz, programmed %u Hz (divider=%u)", - spi_cfg->frequency, actual_freq, clk_div_factor); - } + clk_div_factor = gspi_siwx91x_get_divider(clock_rate, spi_cfg->frequency); } /* Set the clock divider factor */ From 3fbaa29bbac6ea79aee442079007cbb7df7844df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Pouiller?= Date: Tue, 9 Dec 2025 18:13:03 +0100 Subject: [PATCH 0257/3659] drivers: spi: siwx91x: Drop GSPI_MAX_BAUDRATE_FOR_DYNAMIC_CLOCK MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently, clk_div_factor is force to 1 if user request more than 110MHz. However, in this case, gspi_siwx91x_get_divider() will never return 2 or more, unless the input clock is >= 220MHz. The si91x is not designed for such high clock frequency. So, this case has never been tested. Signed-off-by: Jérôme Pouiller --- drivers/spi/spi_silabs_siwx91x_gspi.c | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/drivers/spi/spi_silabs_siwx91x_gspi.c b/drivers/spi/spi_silabs_siwx91x_gspi.c index 29aef6abd2f9..9f18b7ce4552 100644 --- a/drivers/spi/spi_silabs_siwx91x_gspi.c +++ b/drivers/spi/spi_silabs_siwx91x_gspi.c @@ -24,7 +24,6 @@ LOG_MODULE_REGISTER(spi_siwx91x_gspi, CONFIG_SPI_LOG_LEVEL); #include "spi_context.h" -#define GSPI_MAX_BAUDRATE_FOR_DYNAMIC_CLOCK 110000000 #define GSPI_DMA_MAX_DESCRIPTOR_TRANSFER_SIZE 4096 #define SPI_HIGH_BURST_FREQ_THRESHOLD_HZ 10000000 @@ -94,7 +93,6 @@ static int gspi_siwx91x_config(const struct device *dev, const struct spi_config { __maybe_unused struct gspi_siwx91x_data *data = dev->data; const struct gspi_siwx91x_config *cfg = dev->config; - uint32_t clk_div_factor; uint32_t clock_rate; int ret; __maybe_unused int channel_filter; @@ -124,18 +122,11 @@ static int gspi_siwx91x_config(const struct device *dev, const struct spi_config } /* Configure clock divider based on the requested bit rate */ - if (spi_cfg->frequency > GSPI_MAX_BAUDRATE_FOR_DYNAMIC_CLOCK) { - clk_div_factor = 1; - } else { - ret = clock_control_get_rate(cfg->clock_dev, cfg->clock_subsys, &clock_rate); - if (ret) { - return ret; - } - clk_div_factor = gspi_siwx91x_get_divider(clock_rate, spi_cfg->frequency); + ret = clock_control_get_rate(cfg->clock_dev, cfg->clock_subsys, &clock_rate); + if (ret) { + return ret; } - - /* Set the clock divider factor */ - cfg->reg->GSPI_CLK_DIV = clk_div_factor; + cfg->reg->GSPI_CLK_DIV = gspi_siwx91x_get_divider(clock_rate, spi_cfg->frequency); /* Configure SPI clock mode */ if ((spi_cfg->operation & (SPI_MODE_CPOL | SPI_MODE_CPHA)) == 0) { From 41403cae9ec2435f6c0dcdd4757c37b645c702c4 Mon Sep 17 00:00:00 2001 From: Firas Sammoura Date: Tue, 9 Dec 2025 16:29:47 +0000 Subject: [PATCH 0258/3659] tests: riscv: pmp: Add test case for null pointer access Adds `test_null_pointer_access` to verify that attempting to write to a null pointer (address 0x0) correctly triggers a fatal error, confirming the Physical Memory Protection (PMP) guard functionality. Signed-off-by: Firas Sammoura --- .../riscv/pmp/null-pointer/CMakeLists.txt | 8 +++ tests/arch/riscv/pmp/null-pointer/prj.conf | 2 + tests/arch/riscv/pmp/null-pointer/src/main.c | 49 +++++++++++++++++++ .../arch/riscv/pmp/null-pointer/testcase.yaml | 8 +++ 4 files changed, 67 insertions(+) create mode 100644 tests/arch/riscv/pmp/null-pointer/CMakeLists.txt create mode 100644 tests/arch/riscv/pmp/null-pointer/prj.conf create mode 100644 tests/arch/riscv/pmp/null-pointer/src/main.c create mode 100644 tests/arch/riscv/pmp/null-pointer/testcase.yaml diff --git a/tests/arch/riscv/pmp/null-pointer/CMakeLists.txt b/tests/arch/riscv/pmp/null-pointer/CMakeLists.txt new file mode 100644 index 000000000000..4b7bea5d2be4 --- /dev/null +++ b/tests/arch/riscv/pmp/null-pointer/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(riscv_pmp) + +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources}) diff --git a/tests/arch/riscv/pmp/null-pointer/prj.conf b/tests/arch/riscv/pmp/null-pointer/prj.conf new file mode 100644 index 000000000000..58ef9e667900 --- /dev/null +++ b/tests/arch/riscv/pmp/null-pointer/prj.conf @@ -0,0 +1,2 @@ +CONFIG_ZTEST=y +CONFIG_NULL_POINTER_EXCEPTION_DETECTION_PMP=y diff --git a/tests/arch/riscv/pmp/null-pointer/src/main.c b/tests/arch/riscv/pmp/null-pointer/src/main.c new file mode 100644 index 000000000000..ee32533eb4ec --- /dev/null +++ b/tests/arch/riscv/pmp/null-pointer/src/main.c @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2025 Google LLC + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +static volatile bool valid_fault; + +void k_sys_fatal_error_handler(unsigned int reason, const struct arch_esf *pEsf) +{ + TC_PRINT("Caught system error -- reason %d %d\n", reason, valid_fault); + if (!valid_fault) { + TC_PRINT("fatal error was unexpected, aborting\n"); + TC_END_REPORT(TC_FAIL); + k_fatal_halt(reason); + } + + TC_PRINT("fatal error expected as part of test case\n"); + valid_fault = false; /* reset back to normal */ + TC_END_REPORT(TC_PASS); +} + +static void check_null_ptr_guard(void) +{ + volatile int *null_ptr = NULL; + + valid_fault = true; + *null_ptr = 42; + + if (valid_fault) { + /* + * valid_fault gets cleared if an expected exception took place + */ + TC_PRINT("test function was supposed to fault but didn't\n"); + ztest_test_fail(); + } +} + +ZTEST(riscv_pmp_null_pointer, test_null_pointer_access) +{ + check_null_ptr_guard(); + + zassert_unreachable("Write to stack guard did not fault"); + TC_END_REPORT(TC_FAIL); +} + +ZTEST_SUITE(riscv_pmp_null_pointer, NULL, NULL, NULL, NULL, NULL); diff --git a/tests/arch/riscv/pmp/null-pointer/testcase.yaml b/tests/arch/riscv/pmp/null-pointer/testcase.yaml new file mode 100644 index 000000000000..5ebcfa8e38a5 --- /dev/null +++ b/tests/arch/riscv/pmp/null-pointer/testcase.yaml @@ -0,0 +1,8 @@ +common: + filter: CONFIG_RISCV_PMP + +tests: + arch.riscv.pmp.null_pointer.locked: {} + arch.riscv.pmp.null_pointer.unlocked: + extra_configs: + - CONFIG_PMP_NO_LOCK_GLOBAL=y From 26128ab73d7127c9dde2e04fecf35d84ca67ec88 Mon Sep 17 00:00:00 2001 From: Tomasz Chyrowicz Date: Mon, 8 Dec 2025 17:05:46 +0100 Subject: [PATCH 0259/3659] mcumgr: Prevent FW loader from self-destruction The FW loader reports and manages exactly two slots: - slot 0: this is the slot for the application code to update - slot 1: this is the slot, in which the FW loader is placed The slot 1 is reported, so tools can fetch metadata about the FW loader installed on the device. Unfortunately, currently SMP-based FW loader allows to issue slot erase command for the slot 1, effectively erasing the FW loader code that is being executed. This change correctly identifies the slot 1 as an active one, marking it as used and blocking erase operation on that slot. Signed-off-by: Tomasz Chyrowicz --- subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c index 0ebb722c2a90..0a594e238478 100644 --- a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c +++ b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c @@ -361,15 +361,13 @@ img_mgmt_state_any_pending(void) int img_mgmt_slot_in_use(int slot) { -#if defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_FIRMWARE_UPDATER) - return 0; -#else int image = img_mgmt_slot_to_image(slot); int active_slot = img_mgmt_active_slot(image); #if !defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP) && \ !defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_RAM_LOAD) && \ - !defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_RAM_LOAD_WITH_REVERT) + !defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_RAM_LOAD_WITH_REVERT) && \ + !defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_FIRMWARE_UPDATER) enum img_mgmt_next_boot_type type = NEXT_BOOT_TYPE_NORMAL; int nbs = img_mgmt_get_next_boot_slot(image, &type); @@ -391,7 +389,6 @@ img_mgmt_slot_in_use(int slot) #endif return (active_slot == slot); -#endif /* !defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_FIRMWARE_UPDATER) */ } /** From 7b39f9ac71c975f79cf69482c298522bece16683 Mon Sep 17 00:00:00 2001 From: Fabin V Martin Date: Fri, 10 Oct 2025 14:46:56 +0530 Subject: [PATCH 0260/3659] dts: arm: microchip: pic32cm_jh: add sercom nodes Add sercom nodes for pic32cm_jh Signed-off-by: Fabin V Martin --- .../pic32c/pic32cm_jh/common/pic32cm_jh.dtsi | 44 +++++++++++++++++ .../pic32cm_jh/common/pic32cm_jh_100.dtsi | 48 +++++++++++++++++++ .../pic32cm_jh/common/pic32cm_jh_48.dtsi | 26 ++++++++++ .../pic32cm_jh/common/pic32cm_jh_64.dtsi | 26 ++++++++++ .../serial/microchip,sercom-g1-uart.yaml | 2 +- 5 files changed, 145 insertions(+), 1 deletion(-) diff --git a/dts/arm/microchip/pic32c/pic32cm_jh/common/pic32cm_jh.dtsi b/dts/arm/microchip/pic32c/pic32cm_jh/common/pic32cm_jh.dtsi index 255c2f6dae84..9191d4d19400 100644 --- a/dts/arm/microchip/pic32c/pic32cm_jh/common/pic32cm_jh.dtsi +++ b/dts/arm/microchip/pic32c/pic32cm_jh/common/pic32cm_jh.dtsi @@ -105,6 +105,50 @@ #microchip,pin-cells = <2>; }; }; + + sercom0: sercom@42000400 { + compatible = "microchip,sercom-g1"; + reg = <0x42000400 0x31>; + interrupts = <9 0>; + interrupt-names = "source-0-7"; + clocks = <&mclkperiph CLOCK_MCHP_MCLKPERIPH_ID_APBC_SERCOM0>, + <&gclkperiph CLOCK_MCHP_GCLKPERIPH_ID_SERCOM0_CORE>; + clock-names = "mclk", "gclk"; + status = "disabled"; + }; + + sercom1: sercom@42000800 { + compatible = "microchip,sercom-g1"; + reg = <0x42000800 0x31>; + interrupts = <10 0>; + interrupt-names = "source-0-7"; + clocks = <&mclkperiph CLOCK_MCHP_MCLKPERIPH_ID_APBC_SERCOM1>, + <&gclkperiph CLOCK_MCHP_GCLKPERIPH_ID_SERCOM1_CORE>; + clock-names = "mclk", "gclk"; + status = "disabled"; + }; + + sercom2: sercom@42000c00 { + compatible = "microchip,sercom-g1"; + reg = <0x42000c00 0x31>; + interrupts = <11 0>; + interrupt-names = "source-0-7"; + clocks = <&mclkperiph CLOCK_MCHP_MCLKPERIPH_ID_APBC_SERCOM2>, + <&gclkperiph CLOCK_MCHP_GCLKPERIPH_ID_SERCOM2_CORE>; + clock-names = "mclk", "gclk"; + status = "disabled"; + }; + + sercom3: sercom@42001000 { + compatible = "microchip,sercom-g1"; + reg = <0x42001000 0x31>; + interrupts = <12 0>; + interrupt-names = "source-0-7"; + clocks = <&mclkperiph CLOCK_MCHP_MCLKPERIPH_ID_APBC_SERCOM3>, + <&gclkperiph CLOCK_MCHP_GCLKPERIPH_ID_SERCOM3_CORE>; + clock-names = "mclk", "gclk"; + status = "disabled"; + }; }; }; diff --git a/dts/arm/microchip/pic32c/pic32cm_jh/common/pic32cm_jh_100.dtsi b/dts/arm/microchip/pic32c/pic32cm_jh/common/pic32cm_jh_100.dtsi index 52e9858eca8b..98cbe081a234 100644 --- a/dts/arm/microchip/pic32c/pic32cm_jh/common/pic32cm_jh_100.dtsi +++ b/dts/arm/microchip/pic32c/pic32cm_jh/common/pic32cm_jh_100.dtsi @@ -8,6 +8,54 @@ #include +/ { + soc { + sercom4: sercom@42001400 { + compatible = "microchip,sercom-g1"; + reg = <0x42001400 0x31>; + interrupts = <13 0>; + interrupt-names = "source-0-7"; + clocks = <&mclkperiph CLOCK_MCHP_MCLKPERIPH_ID_APBC_SERCOM4>, + <&gclkperiph CLOCK_MCHP_GCLKPERIPH_ID_SERCOM4_CORE>; + clock-names = "mclk", "gclk"; + status = "disabled"; + }; + + sercom5: sercom@42001800 { + compatible = "microchip,sercom-g1"; + reg = <0x42001800 0x31>; + interrupts = <14 0>; + interrupt-names = "source-0-7"; + clocks = <&mclkperiph CLOCK_MCHP_MCLKPERIPH_ID_APBC_SERCOM5>, + <&gclkperiph CLOCK_MCHP_GCLKPERIPH_ID_SERCOM5_CORE>; + clock-names = "mclk", "gclk"; + status = "disabled"; + }; + + sercom6: sercom@43000000 { + compatible = "microchip,sercom-g1"; + reg = <0x43000000 0x31>; + interrupts = <9 0>; + interrupt-names = "source-0-7"; + clocks = <&mclkperiph CLOCK_MCHP_MCLKPERIPH_ID_APBD_SERCOM6>, + <&gclkperiph CLOCK_MCHP_GCLKPERIPH_ID_SERCOM6_CORE>; + clock-names = "mclk", "gclk"; + status = "disabled"; + }; + + sercom7: sercom@43000400 { + compatible = "microchip,sercom-g1"; + reg = <0x43000400 0x31>; + interrupts = <10 0>; + interrupt-names = "source-0-7"; + clocks = <&mclkperiph CLOCK_MCHP_MCLKPERIPH_ID_APBD_SERCOM7>, + <&gclkperiph CLOCK_MCHP_GCLKPERIPH_ID_SERCOM7_CORE>; + clock-names = "mclk", "gclk"; + status = "disabled"; + }; + }; +}; + &pinctrl { portb: gpio@41000080 { compatible = "microchip,port-g1-gpio"; diff --git a/dts/arm/microchip/pic32c/pic32cm_jh/common/pic32cm_jh_48.dtsi b/dts/arm/microchip/pic32c/pic32cm_jh/common/pic32cm_jh_48.dtsi index 365d175fd11a..a2f0ce7f0134 100644 --- a/dts/arm/microchip/pic32c/pic32cm_jh/common/pic32cm_jh_48.dtsi +++ b/dts/arm/microchip/pic32c/pic32cm_jh/common/pic32cm_jh_48.dtsi @@ -8,6 +8,32 @@ #include +/ { + soc { + sercom4: sercom@42001400 { + compatible = "microchip,sercom-g1"; + reg = <0x42001400 0x31>; + interrupts = <13 0>; + interrupt-names = "source-0-7"; + clocks = <&mclkperiph CLOCK_MCHP_MCLKPERIPH_ID_APBC_SERCOM4>, + <&gclkperiph CLOCK_MCHP_GCLKPERIPH_ID_SERCOM4_CORE>; + clock-names = "mclk", "gclk"; + status = "disabled"; + }; + + sercom5: sercom@42001800 { + compatible = "microchip,sercom-g1"; + reg = <0x42001800 0x31>; + interrupts = <14 0>; + interrupt-names = "source-0-7"; + clocks = <&mclkperiph CLOCK_MCHP_MCLKPERIPH_ID_APBC_SERCOM5>, + <&gclkperiph CLOCK_MCHP_GCLKPERIPH_ID_SERCOM5_CORE>; + clock-names = "mclk", "gclk"; + status = "disabled"; + }; + }; +}; + &pinctrl { portb: gpio@41000080 { compatible = "microchip,port-g1-gpio"; diff --git a/dts/arm/microchip/pic32c/pic32cm_jh/common/pic32cm_jh_64.dtsi b/dts/arm/microchip/pic32c/pic32cm_jh/common/pic32cm_jh_64.dtsi index 3d61e9d9abe7..1f6bf9aad164 100644 --- a/dts/arm/microchip/pic32c/pic32cm_jh/common/pic32cm_jh_64.dtsi +++ b/dts/arm/microchip/pic32c/pic32cm_jh/common/pic32cm_jh_64.dtsi @@ -8,6 +8,32 @@ #include +/ { + soc { + sercom4: sercom@42001400 { + compatible = "microchip,sercom-g1"; + reg = <0x42001400 0x31>; + interrupts = <13 0>; + interrupt-names = "source-0-7"; + clocks = <&mclkperiph CLOCK_MCHP_MCLKPERIPH_ID_APBC_SERCOM4>, + <&gclkperiph CLOCK_MCHP_GCLKPERIPH_ID_SERCOM4_CORE>; + clock-names = "mclk", "gclk"; + status = "disabled"; + }; + + sercom5: sercom@42001800 { + compatible = "microchip,sercom-g1"; + reg = <0x42001800 0x31>; + interrupts = <14 0>; + interrupt-names = "source-0-7"; + clocks = <&mclkperiph CLOCK_MCHP_MCLKPERIPH_ID_APBC_SERCOM5>, + <&gclkperiph CLOCK_MCHP_GCLKPERIPH_ID_SERCOM5_CORE>; + clock-names = "mclk", "gclk"; + status = "disabled"; + }; + }; +}; + &pinctrl { portb: gpio@41000080 { compatible = "microchip,port-g1-gpio"; diff --git a/dts/bindings/serial/microchip,sercom-g1-uart.yaml b/dts/bindings/serial/microchip,sercom-g1-uart.yaml index 932e12eff4a8..4177b9584861 100644 --- a/dts/bindings/serial/microchip,sercom-g1-uart.yaml +++ b/dts/bindings/serial/microchip,sercom-g1-uart.yaml @@ -7,7 +7,7 @@ description: | Microchip SERCOM UART driver. Group g1 SERCOM UART driver supports following hardware peripherals: - - module name="SERCOM" id="U2201" version="5.0.0" + - module name="SERCOM" id="U2201" version="3.1.1","5.0.0" compatible: "microchip,sercom-g1-uart" From f9fb943967cfe983a4f12c03d570d6ad706bad52 Mon Sep 17 00:00:00 2001 From: Fabin V Martin Date: Fri, 10 Oct 2025 15:12:29 +0530 Subject: [PATCH 0261/3659] boards: microchip: Update pic32cm_jh01_cpro device tree Add uart support for pic32cm_jh01_cpro. Signed-off-by: Fabin V Martin --- .../pic32cm_jh01_cpro-pinctrl.dtsi | 16 ++++++++++++++++ .../pic32cm_jh01_cpro/pic32cm_jh01_cpro.dts | 18 ++++++++++++++++++ .../pic32cm_jh01_cpro/pic32cm_jh01_cpro.yaml | 1 + .../pic32cm_jh01_cpro_defconfig | 3 +++ 4 files changed, 38 insertions(+) create mode 100644 boards/microchip/pic32c/pic32cm_jh01_cpro/pic32cm_jh01_cpro-pinctrl.dtsi diff --git a/boards/microchip/pic32c/pic32cm_jh01_cpro/pic32cm_jh01_cpro-pinctrl.dtsi b/boards/microchip/pic32c/pic32cm_jh01_cpro/pic32cm_jh01_cpro-pinctrl.dtsi new file mode 100644 index 000000000000..e8f700b06f94 --- /dev/null +++ b/boards/microchip/pic32c/pic32cm_jh01_cpro/pic32cm_jh01_cpro-pinctrl.dtsi @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&pinctrl { + sercom4_uart_default: sercom4_uart_default { + group1 { + pinmux = , + ; + }; + }; +}; diff --git a/boards/microchip/pic32c/pic32cm_jh01_cpro/pic32cm_jh01_cpro.dts b/boards/microchip/pic32c/pic32cm_jh01_cpro/pic32cm_jh01_cpro.dts index 7de914800f98..f51c4e839559 100644 --- a/boards/microchip/pic32c/pic32cm_jh01_cpro/pic32cm_jh01_cpro.dts +++ b/boards/microchip/pic32c/pic32cm_jh01_cpro/pic32cm_jh01_cpro.dts @@ -6,6 +6,7 @@ /dts-v1/; #include +#include "pic32cm_jh01_cpro-pinctrl.dtsi" #include / { @@ -15,6 +16,8 @@ chosen { zephyr,sram = &sram0; zephyr,flash = &flash0; + zephyr,console = &sercom4; + zephyr,shell-uart = &sercom4; }; aliases { @@ -124,3 +127,18 @@ }; }; }; + +&sercom4 { + compatible = "microchip,sercom-g1-uart"; + #address-cells = <1>; + #size-cells = <0>; + current-speed = <115200>; + data-bits = <8>; + parity = "none"; + stop-bits = "1"; + rxpo = <3>; + txpo = <1>; + pinctrl-0 = <&sercom4_uart_default>; + pinctrl-names = "default"; + status = "okay"; +}; diff --git a/boards/microchip/pic32c/pic32cm_jh01_cpro/pic32cm_jh01_cpro.yaml b/boards/microchip/pic32c/pic32cm_jh01_cpro/pic32cm_jh01_cpro.yaml index d1b7db53376e..3a26590f8ce7 100644 --- a/boards/microchip/pic32c/pic32cm_jh01_cpro/pic32cm_jh01_cpro.yaml +++ b/boards/microchip/pic32c/pic32cm_jh01_cpro/pic32cm_jh01_cpro.yaml @@ -13,4 +13,5 @@ supported: - clock_control - gpio - pinctrl + - uart vendor: microchip diff --git a/boards/microchip/pic32c/pic32cm_jh01_cpro/pic32cm_jh01_cpro_defconfig b/boards/microchip/pic32c/pic32cm_jh01_cpro/pic32cm_jh01_cpro_defconfig index 912a8e104237..fd05b25cd749 100644 --- a/boards/microchip/pic32c/pic32cm_jh01_cpro/pic32cm_jh01_cpro_defconfig +++ b/boards/microchip/pic32c/pic32cm_jh01_cpro/pic32cm_jh01_cpro_defconfig @@ -3,3 +3,6 @@ CONFIG_BUILD_OUTPUT_HEX=y CONFIG_ARM_MPU=y +CONFIG_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_UART_CONSOLE=y From d9f1761571d3748cd840e9d301957953e1735a4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Mon, 8 Dec 2025 11:46:34 +0100 Subject: [PATCH 0262/3659] boards: nordic: Add bias-pull-up to UART TX pin sleep state MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When UART TX pin is in sleep state it should have pull up. So far it was floating and that could lead to garbage output on terminal. Signed-off-by: Krzysztof Chruściński --- .../nrf21540dk_nrf52840-pinctrl.dtsi | 9 +++++-- .../nrf51dk/nrf51dk_nrf51822-pinctrl.dtsi | 9 +++++-- .../nrf52833dk_nrf52820-pinctrl.dtsi | 9 +++++-- .../nrf52833dk_nrf52833-pinctrl.dtsi | 9 +++++-- .../nrf52840dk_nrf52811-pinctrl.dtsi | 9 +++++-- .../nrf52840dk_nrf52840-pinctrl.dtsi | 9 +++++-- .../nrf52840dongle_nrf52840-pinctrl.dtsi | 9 +++++-- .../nrf52dk/nrf52dk_nrf52805-pinctrl.dtsi | 9 +++++-- .../nrf52dk/nrf52dk_nrf52810-pinctrl.dtsi | 9 +++++-- .../nrf52dk/nrf52dk_nrf52832-pinctrl.dtsi | 9 +++++-- ...udio_dk_nrf5340_cpuapp_common-pinctrl.dtsi | 9 +++++-- ...f5340_audio_dk_nrf5340_cpunet-pinctrl.dtsi | 9 +++++-- .../nrf5340_cpuapp_common-pinctrl.dtsi | 9 +++++-- .../nrf5340dk_nrf5340_cpunet-pinctrl.dtsi | 9 +++++-- .../nrf54h20dk_nrf54h20-pinctrl.dtsi | 27 ++++++++++++++----- .../nrf54l15dk_nrf54l_05_10_15-pinctrl.dtsi | 9 +++++-- .../nrf54lm20dk_nrf54lm20a-pinctrl.dtsi | 9 +++++-- .../nrf5340_cpuapp_common_pinctrl.dtsi | 14 ++++++++-- .../nrf7002dk_nrf5340_cpunet_pinctrl.dtsi | 14 ++++++++-- .../nrf9131ek_nrf9131_common-pinctrl.dtsi | 9 +++++-- .../nrf9151dk_nrf9151_common-pinctrl.dtsi | 9 +++++-- .../nrf9160dk/nrf9160dk_nrf52840-pinctrl.dtsi | 9 +++++-- .../nrf9160dk_nrf9160_common-pinctrl.dtsi | 9 +++++-- .../nrf9161dk_nrf9161_common-pinctrl.dtsi | 9 +++++-- .../nrf9280pdk_nrf9280-pinctrl.dtsi | 18 ++++++++++--- .../thingy52/thingy52_nrf52832-pinctrl.dtsi | 9 +++++-- .../thingy53_nrf5340_common-pinctrl.dtsi | 9 +++++-- .../thingy53_nrf5340_cpunet-pinctrl.dtsi | 9 +++++-- 28 files changed, 227 insertions(+), 62 deletions(-) diff --git a/boards/nordic/nrf21540dk/nrf21540dk_nrf52840-pinctrl.dtsi b/boards/nordic/nrf21540dk/nrf21540dk_nrf52840-pinctrl.dtsi index d1da980ec5cf..a59b81a35b06 100644 --- a/boards/nordic/nrf21540dk/nrf21540dk_nrf52840-pinctrl.dtsi +++ b/boards/nordic/nrf21540dk/nrf21540dk_nrf52840-pinctrl.dtsi @@ -19,12 +19,17 @@ uart0_sleep: uart0_sleep { group1 { - psels = , - , + psels = , , ; low-power-enable; }; + + group2 { + psels = ; + low-power-enable; + bias-pull-up; + }; }; uart1_default: uart1_default { diff --git a/boards/nordic/nrf51dk/nrf51dk_nrf51822-pinctrl.dtsi b/boards/nordic/nrf51dk/nrf51dk_nrf51822-pinctrl.dtsi index c806e25f8ce4..e7399e0ccee2 100644 --- a/boards/nordic/nrf51dk/nrf51dk_nrf51822-pinctrl.dtsi +++ b/boards/nordic/nrf51dk/nrf51dk_nrf51822-pinctrl.dtsi @@ -15,12 +15,17 @@ uart0_sleep: uart0_sleep { group1 { - psels = , - , + psels = , , ; low-power-enable; }; + + group2 { + psels = ; + low-power-enable; + bias-pull-up; + }; }; i2c0_default: i2c0_default { diff --git a/boards/nordic/nrf52833dk/nrf52833dk_nrf52820-pinctrl.dtsi b/boards/nordic/nrf52833dk/nrf52833dk_nrf52820-pinctrl.dtsi index 0a2dd6da3ef2..2973c48ac6f7 100644 --- a/boards/nordic/nrf52833dk/nrf52833dk_nrf52820-pinctrl.dtsi +++ b/boards/nordic/nrf52833dk/nrf52833dk_nrf52820-pinctrl.dtsi @@ -19,12 +19,17 @@ uart0_sleep: uart0_sleep { group1 { - psels = , - , + psels = , , ; low-power-enable; }; + + group2 { + psels = ; + low-power-enable; + bias-pull-up; + }; }; i2c0_default: i2c0_default { diff --git a/boards/nordic/nrf52833dk/nrf52833dk_nrf52833-pinctrl.dtsi b/boards/nordic/nrf52833dk/nrf52833dk_nrf52833-pinctrl.dtsi index bddbc2f5a365..e5de1ae3986e 100644 --- a/boards/nordic/nrf52833dk/nrf52833dk_nrf52833-pinctrl.dtsi +++ b/boards/nordic/nrf52833dk/nrf52833dk_nrf52833-pinctrl.dtsi @@ -19,12 +19,17 @@ uart0_sleep: uart0_sleep { group1 { - psels = , - , + psels = , , ; low-power-enable; }; + + group2 { + psels = ; + low-power-enable; + bias-pull-up; + }; }; uart1_default: uart1_default { diff --git a/boards/nordic/nrf52840dk/nrf52840dk_nrf52811-pinctrl.dtsi b/boards/nordic/nrf52840dk/nrf52840dk_nrf52811-pinctrl.dtsi index c3706043f4f4..ad768eb029c2 100644 --- a/boards/nordic/nrf52840dk/nrf52840dk_nrf52811-pinctrl.dtsi +++ b/boards/nordic/nrf52840dk/nrf52840dk_nrf52811-pinctrl.dtsi @@ -19,12 +19,17 @@ uart0_sleep: uart0_sleep { group1 { - psels = , - , + psels = , , ; low-power-enable; }; + + group2 { + psels = ; + low-power-enable; + bias-pull-up; + }; }; i2c0_default: i2c0_default { diff --git a/boards/nordic/nrf52840dk/nrf52840dk_nrf52840-pinctrl.dtsi b/boards/nordic/nrf52840dk/nrf52840dk_nrf52840-pinctrl.dtsi index 152a6e95b5f8..39dacdcb77b5 100644 --- a/boards/nordic/nrf52840dk/nrf52840dk_nrf52840-pinctrl.dtsi +++ b/boards/nordic/nrf52840dk/nrf52840dk_nrf52840-pinctrl.dtsi @@ -19,12 +19,17 @@ uart0_sleep: uart0_sleep { group1 { - psels = , - , + psels = , , ; low-power-enable; }; + + group2 { + psels = ; + low-power-enable; + bias-pull-up; + }; }; uart1_default: uart1_default { diff --git a/boards/nordic/nrf52840dongle/nrf52840dongle_nrf52840-pinctrl.dtsi b/boards/nordic/nrf52840dongle/nrf52840dongle_nrf52840-pinctrl.dtsi index cf2b8523b8e0..5b5460ab4cfa 100644 --- a/boards/nordic/nrf52840dongle/nrf52840dongle_nrf52840-pinctrl.dtsi +++ b/boards/nordic/nrf52840dongle/nrf52840dongle_nrf52840-pinctrl.dtsi @@ -19,12 +19,17 @@ uart0_sleep: uart0_sleep { group1 { - psels = , - , + psels = , , ; low-power-enable; }; + + group2 { + psels = ; + low-power-enable; + bias-pull-up; + }; }; i2c0_default: i2c0_default { diff --git a/boards/nordic/nrf52dk/nrf52dk_nrf52805-pinctrl.dtsi b/boards/nordic/nrf52dk/nrf52dk_nrf52805-pinctrl.dtsi index 00d60d2cbecc..ba8f5c146817 100644 --- a/boards/nordic/nrf52dk/nrf52dk_nrf52805-pinctrl.dtsi +++ b/boards/nordic/nrf52dk/nrf52dk_nrf52805-pinctrl.dtsi @@ -47,11 +47,16 @@ uart0_sleep: uart0_sleep { group1 { - psels = , - , + psels = , , ; low-power-enable; }; + + group2 { + psels = ; + low-power-enable; + bias-pull-up; + }; }; }; diff --git a/boards/nordic/nrf52dk/nrf52dk_nrf52810-pinctrl.dtsi b/boards/nordic/nrf52dk/nrf52dk_nrf52810-pinctrl.dtsi index bec21acc20f5..7b53da139756 100644 --- a/boards/nordic/nrf52dk/nrf52dk_nrf52810-pinctrl.dtsi +++ b/boards/nordic/nrf52dk/nrf52dk_nrf52810-pinctrl.dtsi @@ -15,12 +15,17 @@ uart0_sleep: uart0_sleep { group1 { - psels = , - , + psels = , , ; low-power-enable; }; + + group2 { + psels = ; + low-power-enable; + bias-pull-up; + }; }; i2c0_default: i2c0_default { diff --git a/boards/nordic/nrf52dk/nrf52dk_nrf52832-pinctrl.dtsi b/boards/nordic/nrf52dk/nrf52dk_nrf52832-pinctrl.dtsi index 15a9920877d6..2eaa58687393 100644 --- a/boards/nordic/nrf52dk/nrf52dk_nrf52832-pinctrl.dtsi +++ b/boards/nordic/nrf52dk/nrf52dk_nrf52832-pinctrl.dtsi @@ -15,12 +15,17 @@ uart0_sleep: uart0_sleep { group1 { - psels = , - , + psels = , , ; low-power-enable; }; + + group2 { + psels = ; + low-power-enable; + bias-pull-up; + }; }; i2c0_default: i2c0_default { diff --git a/boards/nordic/nrf5340_audio_dk/nrf5340_audio_dk_nrf5340_cpuapp_common-pinctrl.dtsi b/boards/nordic/nrf5340_audio_dk/nrf5340_audio_dk_nrf5340_cpuapp_common-pinctrl.dtsi index 6f835be43c6b..7201a806fe44 100644 --- a/boards/nordic/nrf5340_audio_dk/nrf5340_audio_dk_nrf5340_cpuapp_common-pinctrl.dtsi +++ b/boards/nordic/nrf5340_audio_dk/nrf5340_audio_dk_nrf5340_cpuapp_common-pinctrl.dtsi @@ -45,12 +45,17 @@ uart0_sleep: uart0_sleep { group1 { - psels = , - , + psels = , , ; low-power-enable; }; + + group2 { + psels = ; + low-power-enable; + bias-pull-up; + }; }; uart1_default: uart1_default { diff --git a/boards/nordic/nrf5340_audio_dk/nrf5340_audio_dk_nrf5340_cpunet-pinctrl.dtsi b/boards/nordic/nrf5340_audio_dk/nrf5340_audio_dk_nrf5340_cpunet-pinctrl.dtsi index 869788437579..2af3c58d2064 100644 --- a/boards/nordic/nrf5340_audio_dk/nrf5340_audio_dk_nrf5340_cpunet-pinctrl.dtsi +++ b/boards/nordic/nrf5340_audio_dk/nrf5340_audio_dk_nrf5340_cpunet-pinctrl.dtsi @@ -19,12 +19,17 @@ uart0_sleep: uart0_sleep { group1 { - psels = , - , + psels = , , ; low-power-enable; }; + + group2 { + psels = ; + low-power-enable; + bias-pull-up; + }; }; spi0_default: spi0_default { diff --git a/boards/nordic/nrf5340dk/nrf5340_cpuapp_common-pinctrl.dtsi b/boards/nordic/nrf5340dk/nrf5340_cpuapp_common-pinctrl.dtsi index ed1f278f5d1b..a5d70c602310 100644 --- a/boards/nordic/nrf5340dk/nrf5340_cpuapp_common-pinctrl.dtsi +++ b/boards/nordic/nrf5340dk/nrf5340_cpuapp_common-pinctrl.dtsi @@ -34,12 +34,17 @@ uart0_sleep: uart0_sleep { group1 { - psels = , - , + psels = , , ; low-power-enable; }; + + group2 { + psels = ; + low-power-enable; + bias-pull-up; + }; }; pwm0_default: pwm0_default { diff --git a/boards/nordic/nrf5340dk/nrf5340dk_nrf5340_cpunet-pinctrl.dtsi b/boards/nordic/nrf5340dk/nrf5340dk_nrf5340_cpunet-pinctrl.dtsi index 30f638a7eae7..a8f5c5f357d3 100644 --- a/boards/nordic/nrf5340dk/nrf5340dk_nrf5340_cpunet-pinctrl.dtsi +++ b/boards/nordic/nrf5340dk/nrf5340dk_nrf5340_cpunet-pinctrl.dtsi @@ -19,12 +19,17 @@ uart0_sleep: uart0_sleep { group1 { - psels = , - , + psels = , , ; low-power-enable; }; + + group2 { + psels = ; + low-power-enable; + bias-pull-up; + }; }; i2c0_default: i2c0_default { diff --git a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20-pinctrl.dtsi b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20-pinctrl.dtsi index 0e2ab313df9b..3bf93c920e57 100644 --- a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20-pinctrl.dtsi +++ b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20-pinctrl.dtsi @@ -19,8 +19,13 @@ /omit-if-no-ref/ uart120_sleep: uart120_sleep { group1 { low-power-enable; - psels = , - ; + psels = ; + }; + + group2 { + low-power-enable; + bias-pull-up; + psels = ; }; }; @@ -40,11 +45,16 @@ /omit-if-no-ref/ uart135_sleep: uart135_sleep { group1 { low-power-enable; - psels = , - , + psels = , , ; }; + + group2 { + psels = ; + low-power-enable; + bias-pull-up; + }; }; /omit-if-no-ref/ uart136_default: uart136_default { @@ -63,11 +73,16 @@ /omit-if-no-ref/ uart136_sleep: uart136_sleep { group1 { low-power-enable; - psels = , - , + psels = , , ; }; + + group2 { + psels = ; + low-power-enable; + bias-pull-up; + }; }; /omit-if-no-ref/ exmif_default: exmif_default { diff --git a/boards/nordic/nrf54l15dk/nrf54l15dk_nrf54l_05_10_15-pinctrl.dtsi b/boards/nordic/nrf54l15dk/nrf54l15dk_nrf54l_05_10_15-pinctrl.dtsi index 6f36b4e71129..54c2f0241ad0 100644 --- a/boards/nordic/nrf54l15dk/nrf54l15dk_nrf54l_05_10_15-pinctrl.dtsi +++ b/boards/nordic/nrf54l15dk/nrf54l15dk_nrf54l_05_10_15-pinctrl.dtsi @@ -19,12 +19,17 @@ /omit-if-no-ref/ uart20_sleep: uart20_sleep { group1 { - psels = , - , + psels = , , ; low-power-enable; }; + + group2 { + psels = ; + low-power-enable; + bias-pull-up; + }; }; /omit-if-no-ref/ uart30_default: uart30_default { diff --git a/boards/nordic/nrf54lm20dk/nrf54lm20dk_nrf54lm20a-pinctrl.dtsi b/boards/nordic/nrf54lm20dk/nrf54lm20dk_nrf54lm20a-pinctrl.dtsi index b68222f8cb1f..d6a6dbadd146 100644 --- a/boards/nordic/nrf54lm20dk/nrf54lm20dk_nrf54lm20a-pinctrl.dtsi +++ b/boards/nordic/nrf54lm20dk/nrf54lm20dk_nrf54lm20a-pinctrl.dtsi @@ -19,12 +19,17 @@ /omit-if-no-ref/ uart20_sleep: uart20_sleep { group1 { - psels = , - , + psels = , , ; low-power-enable; }; + + group2 { + psels = ; + low-power-enable; + bias-pull-up; + }; }; /omit-if-no-ref/ pwm20_default: pwm20_default { diff --git a/boards/nordic/nrf7002dk/nrf5340_cpuapp_common_pinctrl.dtsi b/boards/nordic/nrf7002dk/nrf5340_cpuapp_common_pinctrl.dtsi index 9a17443b3dc0..ebd915ce817e 100644 --- a/boards/nordic/nrf7002dk/nrf5340_cpuapp_common_pinctrl.dtsi +++ b/boards/nordic/nrf7002dk/nrf5340_cpuapp_common_pinctrl.dtsi @@ -1,3 +1,8 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor + * SPDX-License-Identifier: Apache-2.0 + */ + &pinctrl { i2c1_default: i2c1_default { group1 { @@ -29,12 +34,17 @@ uart0_sleep: uart0_sleep { group1 { - psels = , - , + psels = , , ; low-power-enable; }; + + group2 { + psels = ; + low-power-enable; + bias-pull-up; + }; }; pwm0_default: pwm0_default { diff --git a/boards/nordic/nrf7002dk/nrf7002dk_nrf5340_cpunet_pinctrl.dtsi b/boards/nordic/nrf7002dk/nrf7002dk_nrf5340_cpunet_pinctrl.dtsi index 0abcb4724d53..2413b7c7db48 100644 --- a/boards/nordic/nrf7002dk/nrf7002dk_nrf5340_cpunet_pinctrl.dtsi +++ b/boards/nordic/nrf7002dk/nrf7002dk_nrf5340_cpunet_pinctrl.dtsi @@ -1,3 +1,8 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor + * SPDX-License-Identifier: Apache-2.0 + */ + &pinctrl { uart0_default: uart0_default { group1 { @@ -14,12 +19,17 @@ uart0_sleep: uart0_sleep { group1 { - psels = , - , + psels = , , ; low-power-enable; }; + + group2 { + psels = ; + low-power-enable; + bias-pull-up; + }; }; i2c0_default: i2c0_default { diff --git a/boards/nordic/nrf9131ek/nrf9131ek_nrf9131_common-pinctrl.dtsi b/boards/nordic/nrf9131ek/nrf9131ek_nrf9131_common-pinctrl.dtsi index edb6d869bf62..3bf954e021c9 100644 --- a/boards/nordic/nrf9131ek/nrf9131ek_nrf9131_common-pinctrl.dtsi +++ b/boards/nordic/nrf9131ek/nrf9131ek_nrf9131_common-pinctrl.dtsi @@ -19,12 +19,17 @@ uart0_sleep: uart0_sleep { group1 { - psels = , - , + psels = , , ; low-power-enable; }; + + group2 { + psels = ; + low-power-enable; + bias-pull-up; + }; }; uart1_default: uart1_default { diff --git a/boards/nordic/nrf9151dk/nrf9151dk_nrf9151_common-pinctrl.dtsi b/boards/nordic/nrf9151dk/nrf9151dk_nrf9151_common-pinctrl.dtsi index 2685cc354ec5..ce045be9157f 100644 --- a/boards/nordic/nrf9151dk/nrf9151dk_nrf9151_common-pinctrl.dtsi +++ b/boards/nordic/nrf9151dk/nrf9151dk_nrf9151_common-pinctrl.dtsi @@ -19,12 +19,17 @@ uart0_sleep: uart0_sleep { group1 { - psels = , - , + psels = , , ; low-power-enable; }; + + group2 { + psels = ; + low-power-enable; + bias-pull-up; + }; }; uart1_default: uart1_default { diff --git a/boards/nordic/nrf9160dk/nrf9160dk_nrf52840-pinctrl.dtsi b/boards/nordic/nrf9160dk/nrf9160dk_nrf52840-pinctrl.dtsi index 22eae1b3b6c2..69a3c104bd50 100644 --- a/boards/nordic/nrf9160dk/nrf9160dk_nrf52840-pinctrl.dtsi +++ b/boards/nordic/nrf9160dk/nrf9160dk_nrf52840-pinctrl.dtsi @@ -19,11 +19,16 @@ uart0_sleep: uart0_sleep { group1 { - psels = , - , + psels = , , ; low-power-enable; }; + + group2 { + psels = ; + low-power-enable; + bias-pull-up; + }; }; }; diff --git a/boards/nordic/nrf9160dk/nrf9160dk_nrf9160_common-pinctrl.dtsi b/boards/nordic/nrf9160dk/nrf9160dk_nrf9160_common-pinctrl.dtsi index 8ca261027d11..493ccab64d54 100644 --- a/boards/nordic/nrf9160dk/nrf9160dk_nrf9160_common-pinctrl.dtsi +++ b/boards/nordic/nrf9160dk/nrf9160dk_nrf9160_common-pinctrl.dtsi @@ -19,12 +19,17 @@ uart0_sleep: uart0_sleep { group1 { - psels = , - , + psels = , , ; low-power-enable; }; + + group2 { + psels = ; + low-power-enable; + bias-pull-up; + }; }; uart1_default: uart1_default { diff --git a/boards/nordic/nrf9161dk/nrf9161dk_nrf9161_common-pinctrl.dtsi b/boards/nordic/nrf9161dk/nrf9161dk_nrf9161_common-pinctrl.dtsi index 2685cc354ec5..ce045be9157f 100644 --- a/boards/nordic/nrf9161dk/nrf9161dk_nrf9161_common-pinctrl.dtsi +++ b/boards/nordic/nrf9161dk/nrf9161dk_nrf9161_common-pinctrl.dtsi @@ -19,12 +19,17 @@ uart0_sleep: uart0_sleep { group1 { - psels = , - , + psels = , , ; low-power-enable; }; + + group2 { + psels = ; + low-power-enable; + bias-pull-up; + }; }; uart1_default: uart1_default { diff --git a/boards/nordic/nrf9280pdk/nrf9280pdk_nrf9280-pinctrl.dtsi b/boards/nordic/nrf9280pdk/nrf9280pdk_nrf9280-pinctrl.dtsi index 709fda74f89f..b00d9e0082d6 100644 --- a/boards/nordic/nrf9280pdk/nrf9280pdk_nrf9280-pinctrl.dtsi +++ b/boards/nordic/nrf9280pdk/nrf9280pdk_nrf9280-pinctrl.dtsi @@ -21,11 +21,16 @@ /omit-if-no-ref/ uart135_sleep: uart135_sleep { group1 { low-power-enable; - psels = , - , + psels = , , ; }; + + group2 { + psels = ; + low-power-enable; + bias-pull-up; + }; }; /omit-if-no-ref/ uart136_default: uart136_default { @@ -44,11 +49,16 @@ /omit-if-no-ref/ uart136_sleep: uart136_sleep { group1 { low-power-enable; - psels = , - , + psels = , , ; }; + + group2 { + psels = ; + low-power-enable; + bias-pull-up; + }; }; /omit-if-no-ref/ exmif_default: exmif_default { diff --git a/boards/nordic/thingy52/thingy52_nrf52832-pinctrl.dtsi b/boards/nordic/thingy52/thingy52_nrf52832-pinctrl.dtsi index df96e0c27c7c..5b4953cfffeb 100644 --- a/boards/nordic/thingy52/thingy52_nrf52832-pinctrl.dtsi +++ b/boards/nordic/thingy52/thingy52_nrf52832-pinctrl.dtsi @@ -13,9 +13,14 @@ uart0_sleep: uart0_sleep { group1 { - psels = , - ; + psels = ; + low-power-enable; + }; + + group2 { + psels = ; low-power-enable; + bias-pull-up; }; }; diff --git a/boards/nordic/thingy53/thingy53_nrf5340_common-pinctrl.dtsi b/boards/nordic/thingy53/thingy53_nrf5340_common-pinctrl.dtsi index fbd084a152c6..76dd258cfe85 100644 --- a/boards/nordic/thingy53/thingy53_nrf5340_common-pinctrl.dtsi +++ b/boards/nordic/thingy53/thingy53_nrf5340_common-pinctrl.dtsi @@ -77,12 +77,17 @@ uart0_sleep: uart0_sleep { group1 { - psels = , - , + psels = , , ; low-power-enable; }; + + group2 { + psels = ; + low-power-enable; + bias-pull-up; + }; }; qspi_default: qspi_default { diff --git a/boards/nordic/thingy53/thingy53_nrf5340_cpunet-pinctrl.dtsi b/boards/nordic/thingy53/thingy53_nrf5340_cpunet-pinctrl.dtsi index 76d1fd8bad50..566521568f8f 100644 --- a/boards/nordic/thingy53/thingy53_nrf5340_cpunet-pinctrl.dtsi +++ b/boards/nordic/thingy53/thingy53_nrf5340_cpunet-pinctrl.dtsi @@ -15,12 +15,17 @@ uart0_sleep: uart0_sleep { group1 { - psels = , - , + psels = , , ; low-power-enable; }; + + group2 { + psels = ; + low-power-enable; + bias-pull-up; + }; }; spi0_default: spi0_default { From 01fc83d63d08e57fee058e1cc7b7379af56b70e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Thu, 4 Dec 2025 10:30:05 +0100 Subject: [PATCH 0263/3659] boards: nordic: nrf54h20dk: Add cpuapp TCM memory section MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add memory section which is placed in cpuapp TCM (Tightly Coupled Memory) RAM0 which is fast, non-cacheable. Signed-off-by: Krzysztof Chruściński --- .../nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts | 34 +++++++++---------- 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts index 5e13af28c2ba..01d75ffa3556 100644 --- a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts +++ b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts @@ -334,26 +334,24 @@ zephyr_udc0: &usbhs { status = "okay"; }; -/* Trim this RAM block for power management related features. */ &cpuapp_ram0 { - reg = <0x22000000 (DT_SIZE_K(32) - 256)>; - ranges = <0x0 0x22000000 (0x8000 - 0x100)>; -}; + cpuapp_tcm_region: cpuapp_ram0@0 { + compatible = "zephyr,memory-region"; + reg = <0x00000000 (DT_SIZE_K(32) - 256)>; + zephyr,memory-region = "APP_RAM0"; + }; -/ { - soc { - /* cache control functions - must be executed from local SRAM */ - pm_ramfunc: cpuapp_s2ram@22007f00 { - compatible = "zephyr,memory-region", "mmio-sram"; - reg = <0x22007f00 192>; - zephyr,memory-region = "PMLocalRamfunc"; - }; + /* cache control functions - must be executed from local SRAM */ + pm_ramfunc: cpuapp_s2ram@7f00 { + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x00007f00 192>; + zephyr,memory-region = "PMLocalRamfunc"; + }; - /* run-time common S2RAM cpu context RAM */ - pm_s2ram: cpuapp_s2ram@22007fe0 { - compatible = "zephyr,memory-region", "mmio-sram"; - reg = <0x22007fe0 32>; - zephyr,memory-region = "pm_s2ram_context"; - }; + /* run-time common S2RAM cpu context RAM */ + pm_s2ram: cpuapp_s2ram@7fe0 { + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x00007fe0 32>; + zephyr,memory-region = "pm_s2ram_context"; }; }; From 1adf52166da45d64d8884da025cecb9175e80758 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Mon, 1 Dec 2025 16:14:05 +0100 Subject: [PATCH 0264/3659] samples: boards: nordic: clock_control: add README.rst Add documentation of the nordic clock control sample in the form of a README.rst Signed-off-by: Bjarki Arge Andreasen --- .../boards/nordic/clock_control/README.rst | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 samples/boards/nordic/clock_control/README.rst diff --git a/samples/boards/nordic/clock_control/README.rst b/samples/boards/nordic/clock_control/README.rst new file mode 100644 index 000000000000..0bbc1f08e842 --- /dev/null +++ b/samples/boards/nordic/clock_control/README.rst @@ -0,0 +1,60 @@ +.. zephyr:code-sample:: nrf_clock_control + :name: nRF clock control + + Request minimum clock requirements at runtime. + +Demonstrates how to request minimum clock requirements of nordic clocks, including getting the +startup time to ensure clock requirements are met in time. + +Requirements +************ + +Requires an nRF54H20 based board. + +Building, Flashing and Running +****************************** + +The sample is built to test a specific clock requirement for a specific clock. The clock is +specified in a devicetree overlay, and the clock requirement is defined using these sample +specific Kconfigs: + +* :kconfig:option:`CONFIG_SAMPLE_CLOCK_FREQUENCY_HZ` +* :kconfig:option:`CONFIG_SAMPLE_CLOCK_ACCURACY_PPM` +* :kconfig:option:`CONFIG_SAMPLE_CLOCK_PRECISION` + +With the following controlling how long the request is held: + +* :kconfig:option:`CONFIG_SAMPLE_PRE_REQUEST_TIMEOUT` +* :kconfig:option:`CONFIG_SAMPLE_KEEP_REQUEST_TIMEOUT` + +Example configs and overlays are added for every clock, which can be found in :file:`sample.yaml`, +and applied using the ``-T`` west argument. The following example builds the sample to test the +FLL16M: + +.. zephyr-app-commands:: + :zephyr-app: samples/boards/nordic/clock_control + :board: nrf54h20dk/nrf54h20/cpuapp + :goals: build + :west-args: -T sample.boards.nrf.clock_control.fll16m + :compact: + +Example output: + +.. code-block:: none + + clock name: fll16m + minimum frequency request: 0Hz + minimum accuracy request: 30PPM + minimum precision request: 0 + + resolved frequency request: 16000000Hz + resolved accuracy request: 30PPM + resolved precision request: 0 + + startup time for requested spec: 850us + + requesting minimum clock specs + request applied to clock in 1ms + + releasing requested clock specs + clock spec request released From d1858bed248a9ed41e8142c6597013dbf1374386 Mon Sep 17 00:00:00 2001 From: Cristian Bulacu Date: Fri, 5 Dec 2025 13:13:21 +0200 Subject: [PATCH 0265/3659] openthread: platform: infra_if: Add packet filtering rule for NAT64 This commit aims to implement IPv4 packet filtering for NAT64 translator. If packets are consumed, those are not processed anymore by network stack. NAT64 packets are created by OpenThread stack and sent on backbone interface using a raw socket. This commit attempts to fix an issue where a TCP connection is initiated by an OpenThread node, but discarded by network stack since there is no active known connection. Signed-off-by: Cristian Bulacu --- modules/openthread/platform/infra_if.c | 54 ++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/modules/openthread/platform/infra_if.c b/modules/openthread/platform/infra_if.c index f978389f4cc4..58189e8ba9a9 100644 --- a/modules/openthread/platform/infra_if.c +++ b/modules/openthread/platform/infra_if.c @@ -26,6 +26,7 @@ #if defined(CONFIG_OPENTHREAD_NAT64_TRANSLATOR) #include +#include #include #endif /* CONFIG_OPENTHREAD_NAT64_TRANSLATOR */ @@ -45,9 +46,19 @@ static void handle_ra_from_ot(const uint8_t *buffer, uint16_t buffer_length); static struct zsock_pollfd sockfd_raw[MAX_SERVICES]; static void raw_receive_handler(struct net_socket_service_event *evt); static void remove_checksums_for_eth_offloading(uint8_t *buf, uint16_t len); +static bool infra_if_nat64_try_consume_packet(struct npf_test *test, struct net_pkt *pkt); static int raw_infra_if_sock = -1; NET_SOCKET_SERVICE_SYNC_DEFINE_STATIC(handle_infra_if_raw_recv, raw_receive_handler, MAX_SERVICES); + +struct ot_nat64_pkt_filter_test { + struct npf_test test; +}; +/* Packet filtering rules for NAT64 translator section */ +static struct ot_nat64_pkt_filter_test ot_nat64_drop_rule_check = { + .test.fn = infra_if_nat64_try_consume_packet}; +/* Drop all traffic destined to and consumed by NAT64 translator */ +static NPF_RULE(ot_nat64_drop_pkt_process, NET_DROP, ot_nat64_drop_rule_check); #endif /* CONFIG_OPENTHREAD_NAT64_TRANSLATOR */ otError otPlatInfraIfSendIcmp6Nd(uint32_t aInfraIfIndex, const otIp6Address *aDestAddress, @@ -318,6 +329,9 @@ otError infra_if_nat64_init(void) ARRAY_SIZE(sockfd_raw), NULL) == 0, error = OT_ERROR_FAILED); + npf_insert_ipv4_recv_rule(&ot_nat64_drop_pkt_process); + npf_append_ipv4_recv_rule(&npf_default_ok); + exit: return error; } @@ -417,4 +431,44 @@ static void remove_checksums_for_eth_offloading(uint8_t *buf, uint16_t len) break; } } + +static bool infra_if_nat64_try_consume_packet(struct npf_test *test, struct net_pkt *pkt) +{ + ARG_UNUSED(test); + + struct net_buf *buf = NULL; + otMessage *message = NULL; + otMessageSettings settings; + + openthread_mutex_lock(); + + if (ot_instance == NULL || + otNat64GetTranslatorState(ot_instance) != OT_NAT64_STATE_ACTIVE) { + ExitNow(); + } + + settings.mPriority = OT_MESSAGE_PRIORITY_NORMAL; + settings.mLinkSecurityEnabled = true; + + message = otIp4NewMessage(ot_instance, &settings); + VerifyOrExit(message != NULL); + + for (buf = pkt->buffer; buf; buf = buf->frags) { + if (otMessageAppend(message, buf->data, buf->len) != OT_ERROR_NONE) { + otMessageFree(message); + ExitNow(); + } + } + + if (otNat64Send(ot_instance, message) == OT_ERROR_NONE) { + net_pkt_unref(pkt); + openthread_mutex_unlock(); + return true; + } + +exit: + openthread_mutex_unlock(); + return false; +} + #endif /* CONFIG_OPENTHREAD_NAT64_TRANSLATOR */ From 6dab107c91c4215734b787ad4e9f50b6a8a931e8 Mon Sep 17 00:00:00 2001 From: Cristian Bulacu Date: Mon, 8 Dec 2025 12:05:46 +0200 Subject: [PATCH 0266/3659] openthread: Kconfig: Enable packet filtering Enable packet filtering functionality for OpenThread Border Router when NAT64 Translator is enabled Signed-off-by: Cristian Bulacu --- modules/openthread/Kconfig | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/openthread/Kconfig b/modules/openthread/Kconfig index d3c6498e2dff..1e257b0a8ff5 100644 --- a/modules/openthread/Kconfig +++ b/modules/openthread/Kconfig @@ -367,7 +367,9 @@ menu "OpenThread Border Router" config OPENTHREAD_ZEPHYR_BORDER_ROUTER bool "Adds support for Border Router functionality [EXPERIMENTAL]" select EXPERIMENTAL - imply NET_ROUTING + select NET_ROUTING + select NET_PKT_FILTER if OPENTHREAD_NAT64_TRANSLATOR + select NET_PKT_FILTER_IPV4_HOOK if OPENTHREAD_NAT64_TRANSLATOR help Enable support for Border Router using Openthread's implementation. From 006a9513238643c31661dcff94e3d9fe4c013e8a Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Tue, 9 Dec 2025 19:22:20 +0000 Subject: [PATCH 0267/3659] tests: assert_custom_header: only build on some platforms This test does not build correctly on some modules, namely TFM, just run it on a few platform, that should be enough to validate that the feature is working correctly. Signed-off-by: Fabio Baltieri --- tests/subsys/debug/assert_custom_header/testcase.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/subsys/debug/assert_custom_header/testcase.yaml b/tests/subsys/debug/assert_custom_header/testcase.yaml index 70bb040d7105..c923f21f3c79 100644 --- a/tests/subsys/debug/assert_custom_header/testcase.yaml +++ b/tests/subsys/debug/assert_custom_header/testcase.yaml @@ -1,6 +1,11 @@ common: integration_platforms: - native_sim + platform_allow: + - native_sim + - native_sim/native/64 + - qemu_x86 + - qemu_cortex_m3 tests: debug.assert_custom_header: From e88400036e105b23b944fb69e7ca75775d2302db Mon Sep 17 00:00:00 2001 From: S Mohamed Fiaz Date: Wed, 10 Dec 2025 11:45:40 +0530 Subject: [PATCH 0268/3659] modules: hal_silabs: wiseconnect: CMakeLists fix This fix addresses a PM failure caused by an inconsistency between the device tree and the build system. The device tree was updated with `reg = <0x00000400 DT_SIZE_K(319)>;`, but the corresponding value for `SL_SI91X_SI917_RAM_MEM_CONFIG` in CMakeLists.txt was not updated, leading to the problem. The build system now automatically sets `SL_SI91X_SI917_RAM_MEM_CONFIG` based on the sram0 RAM size from the device tree using `dt_prop()` and `list(GET)`, ensuring the configuration matches the device tree and preventing future mismatches. Signed-off-by: S Mohamed Fiaz --- modules/hal_silabs/wiseconnect/CMakeLists.txt | 23 +++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/modules/hal_silabs/wiseconnect/CMakeLists.txt b/modules/hal_silabs/wiseconnect/CMakeLists.txt index 573f722cb197..0c740f5e4395 100644 --- a/modules/hal_silabs/wiseconnect/CMakeLists.txt +++ b/modules/hal_silabs/wiseconnect/CMakeLists.txt @@ -5,6 +5,25 @@ set(SISDK_DIR ${ZEPHYR_HAL_SILABS_MODULE_DIR}/simplicity_sdk) set(WISECONNECT_DIR ${ZEPHYR_HAL_SILABS_MODULE_DIR}/wiseconnect) set(COMMON_DIR ${ZEPHYR_HAL_SILABS_MODULE_DIR}/simplicity_sdk/platform/common) +function(wiseconnect_get_ram_config node_var out_var) + # Get reg property from device tree node + dt_nodelabel(node_path NODELABEL "${node_var}") + dt_prop(reg_property PATH "${node_path}" PROPERTY "reg") + list(GET reg_property 1 size_bytes) + math(EXPR size_kb "${size_bytes} / 1024") + + # Set output variable based on size + if(size_kb EQUAL 195) + set(${out_var} 1 PARENT_SCOPE) + elseif(size_kb EQUAL 255) + set(${out_var} 2 PARENT_SCOPE) + elseif(size_kb EQUAL 319) + set(${out_var} 3 PARENT_SCOPE) + else() + message(FATAL_ERROR "Unsupported RAM size config: ${size_kb}KB") + endif() +endfunction() + # Keep these values sync with # components/device/silabs/si91x/mcu/core/chip/component/siwg917*.slcc zephyr_compile_definitions( @@ -156,9 +175,10 @@ if(CONFIG_BT_SILABS_SIWX91X) endif() # CONFIG_BT_SILABS_SIWX91X if(CONFIG_SILABS_SIWX91X_NWP) + wiseconnect_get_ram_config("sram0" RAM_MEM_CONFIG) zephyr_compile_definitions( SLI_SI91X_ENABLE_OS - SL_SI91X_SI917_RAM_MEM_CONFIG=2 + SL_SI91X_SI917_RAM_MEM_CONFIG=${RAM_MEM_CONFIG} SL_WIFI_COMPONENT_INCLUDED # Depite de the name, required for everything ) zephyr_include_directories( @@ -247,7 +267,6 @@ if(CONFIG_SOC_SIWX91X_PM_BACKEND_PMGR) SL_CODE_COMPONENT_POWER_MANAGER=power_manager SL_SI91X_TICKLESS_MODE SL_SLEEP_TIMER - SL_SI91X_SI917_RAM_MEM_CONFIG=2 SL_CODE_COMPONENT_CORE=core SLI_WIRELESS_COMPONENT_PRESENT ) From de66e0560287952cdadb4fcd50ed8fbe95edcaa3 Mon Sep 17 00:00:00 2001 From: Qingsong Gou Date: Tue, 9 Dec 2025 15:25:46 +0800 Subject: [PATCH 0269/3659] drivers: watchdog: sf32lb: fix return errors Fix watchdog driver return error Signed-off-by: Qingsong Gou --- drivers/watchdog/wdt_sf32lb.c | 42 ++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/drivers/watchdog/wdt_sf32lb.c b/drivers/watchdog/wdt_sf32lb.c index 4b2d219130ee..7368a7ad25af 100644 --- a/drivers/watchdog/wdt_sf32lb.c +++ b/drivers/watchdog/wdt_sf32lb.c @@ -32,6 +32,20 @@ struct wdt_sf32lb_config { uintptr_t base; }; +struct wdt_sf32lb_data { + bool timeout_valid; +}; + +static inline bool wdt_sf32lb_is_enabled(const struct device *dev) +{ + const struct wdt_sf32lb_config *config = dev->config; + uint32_t cr; + + cr = sys_read32(config->base + WDT_CCR); + + return (cr == WDT_CMD_START); +} + static int wdt_sf32lb_setup(const struct device *dev, uint8_t options) { const struct wdt_sf32lb_config *config = dev->config; @@ -41,6 +55,11 @@ static int wdt_sf32lb_setup(const struct device *dev, uint8_t options) return -ENOTSUP; } + if (wdt_sf32lb_is_enabled(dev)) { + LOG_ERR("Setup not allowed with watchdog enabled"); + return -EBUSY; + } + sys_write32(WDT_CMD_START, config->base + WDT_CCR); return 0; @@ -49,7 +68,13 @@ static int wdt_sf32lb_setup(const struct device *dev, uint8_t options) static int wdt_sf32lb_disable(const struct device *dev) { const struct wdt_sf32lb_config *config = dev->config; + struct wdt_sf32lb_data *data = dev->data; + if (!wdt_sf32lb_is_enabled(dev)) { + LOG_ERR("Watchdog already disabled"); + return -EFAULT; + } + data->timeout_valid = false; sys_write32(WDT_CMD_STOP, config->base + WDT_CCR); return 0; @@ -59,6 +84,12 @@ static int wdt_sf32lb_install_timeout(const struct device *dev, const struct wdt_timeout_cfg *wdt_cfg) { const struct wdt_sf32lb_config *config = dev->config; + struct wdt_sf32lb_data *data = dev->data; + + if (wdt_sf32lb_is_enabled(dev)) { + LOG_ERR("Timeout install not allowed with watchdog enabled"); + return -EBUSY; + } if (wdt_cfg->flags != WDT_FLAG_RESET_SOC) { LOG_ERR("Only SoC reset supported"); @@ -79,6 +110,8 @@ static int wdt_sf32lb_install_timeout(const struct device *dev, return -EINVAL; } + data->timeout_valid = true; + sys_write32(wdt_cfg->window.max * WDT_CLK_KHZ, config->base + WDT_CVR0); return 0; @@ -87,6 +120,12 @@ static int wdt_sf32lb_install_timeout(const struct device *dev, static int wdt_sf32lb_feed(const struct device *dev, int channel_id) { const struct wdt_sf32lb_config *config = dev->config; + struct wdt_sf32lb_data *data = dev->data; + + if (!data->timeout_valid) { + LOG_ERR("No valid timeout installed"); + return -EINVAL; + } sys_write32(WDT_CMD_START, config->base + WDT_CCR); @@ -117,7 +156,8 @@ static int wdt_sf32lb_init(const struct device *dev) static const struct wdt_sf32lb_config wdt_sf32lb_config_##index = { \ .base = DT_INST_REG_ADDR(index), \ }; \ - DEVICE_DT_INST_DEFINE(index, wdt_sf32lb_init, NULL, NULL, \ + static struct wdt_sf32lb_data wdt_sf32lb_data_##index; \ + DEVICE_DT_INST_DEFINE(index, wdt_sf32lb_init, NULL, &wdt_sf32lb_data_##index, \ &wdt_sf32lb_config_##index, POST_KERNEL, \ CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &wdt_sf32lb_api); From 3a384173b411e5ce462ee6d6ce69e85346013b93 Mon Sep 17 00:00:00 2001 From: Khoa Nguyen Date: Tue, 9 Dec 2025 18:09:45 +0700 Subject: [PATCH 0270/3659] tests: drivers: i2c: Update to use i2c_write instead of burst_write Update test app `i2c_target_api` to use i2c_write instead of using same burst_write functional Signed-off-by: Khoa Nguyen --- tests/drivers/i2c/i2c_target_api/src/main.c | 30 ++++++++------------- 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/tests/drivers/i2c/i2c_target_api/src/main.c b/tests/drivers/i2c/i2c_target_api/src/main.c index 143248d187e4..07004c730099 100644 --- a/tests/drivers/i2c/i2c_target_api/src/main.c +++ b/tests/drivers/i2c/i2c_target_api/src/main.c @@ -135,42 +135,34 @@ static int run_program_read(const struct device *i2c, uint8_t addr, uint8_t addr_width, unsigned int offset) { int ret, i; - uint8_t start_addr[2]; - struct i2c_msg msg[2]; + uint8_t buf[TEST_DATA_SIZE + 2]; + uint8_t addr_size; TC_PRINT("Testing program. Master: %s, address: 0x%x, off=%d\n", i2c->name, addr, offset); - for (i = 0 ; i < TEST_DATA_SIZE-offset ; ++i) { - i2c_buffer[i] = i & 0xFF; - } - switch (addr_width) { case 8: - start_addr[0] = (uint8_t) (offset & 0xFF); + buf[0] = (uint8_t) (offset & 0xFF); + addr_size = 1; break; case 16: - sys_put_be16((uint16_t)(offset & 0xFFFF), start_addr); + sys_put_be16((uint16_t)(offset & 0xFFFF), buf); + addr_size = 2; break; default: return -EINVAL; } - msg[0].buf = start_addr; - msg[0].len = (addr_width >> 3); - msg[0].flags = I2C_MSG_WRITE; - msg[1].buf = &i2c_buffer[0]; - msg[1].len = TEST_DATA_SIZE; - msg[1].flags = I2C_MSG_WRITE | I2C_MSG_STOP; + for (i = 0; i < TEST_DATA_SIZE - offset; ++i) { + buf[i + addr_size] = i & 0xFF; + } - ret = i2c_transfer(i2c, &msg[0], 2, addr); + ret = i2c_write(i2c, &buf[0], TEST_DATA_SIZE - offset + addr_size, addr); zassert_equal(ret, 0, "Failed to write EEPROM"); - (void)memset(i2c_buffer, 0xFF, TEST_DATA_SIZE); - /* Read back EEPROM from I2C Master requests, then compare */ - ret = i2c_write_read(i2c, addr, - start_addr, (addr_width >> 3), i2c_buffer, TEST_DATA_SIZE-offset); + ret = i2c_write_read(i2c, addr, buf, addr_size, i2c_buffer, TEST_DATA_SIZE - offset); zassert_equal(ret, 0, "Failed to read EEPROM"); for (i = 0 ; i < TEST_DATA_SIZE-offset ; ++i) { From 90bbc471229f83ac452d8fdcc9f696a9f5f22631 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Wed, 10 Dec 2025 08:13:33 +0100 Subject: [PATCH 0271/3659] samples: boards: nordic: coresight_stm: Benchmark only the cached code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add additional call before starting time measurement to ensure that all calls that are benchmarked are already cached. This change allows to get more stable results as all exectutions are from cache. Signed-off-by: Krzysztof Chruściński --- samples/boards/nordic/coresight_stm/src/main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/samples/boards/nordic/coresight_stm/src/main.c b/samples/boards/nordic/coresight_stm/src/main.c index b788d4fc15d9..a92b4dbe6da6 100644 --- a/samples/boards/nordic/coresight_stm/src/main.c +++ b/samples/boards/nordic/coresight_stm/src/main.c @@ -16,6 +16,7 @@ LOG_MODULE_REGISTER(app); #define TEST_LOG(rpt, item) \ ({ \ uint32_t key = irq_lock(); \ + __DEBRACKET item; \ uint32_t t = k_cycle_get_32(); \ for (uint32_t i = 0; i < rpt; i++) { \ __DEBRACKET item; \ From 81666a327574ef3644e08b436beb4f6eece151a0 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Tue, 9 Dec 2025 14:35:16 +0200 Subject: [PATCH 0272/3659] intel_adsp: common: gdbstub: Correct z_gdb_backend_init() return type The z_gdb_backend_init() is defined to return with success/error code with return type of int. Fixes: a9c47a47a4f3 ("intel_adsp: cavs: add gdb support") Signed-off-by: Peter Ujfalusi --- soc/intel/intel_adsp/common/gdbstub_backend_sram.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/soc/intel/intel_adsp/common/gdbstub_backend_sram.c b/soc/intel/intel_adsp/common/gdbstub_backend_sram.c index 6d7420de587e..7477d38e5c99 100644 --- a/soc/intel/intel_adsp/common/gdbstub_backend_sram.c +++ b/soc/intel/intel_adsp/common/gdbstub_backend_sram.c @@ -63,7 +63,7 @@ static inline int ring_have_data(const volatile struct gdb_sram_ring *ring) static volatile struct gdb_sram_ring *rx; static volatile struct gdb_sram_ring *tx; -void z_gdb_backend_init(void) +int z_gdb_backend_init(void) { __ASSERT_NO_MSG(sizeof(ADSP_DW->descs) <= SOF_GDB_WINDOW_OFFSET); @@ -71,6 +71,8 @@ void z_gdb_backend_init(void) tx = sys_cache_uncached_ptr_get(TX_UNCACHED); rx->head = rx->tail = 0; tx->head = tx->tail = 0; + + return 0; } void z_gdb_putchar(unsigned char c) From c7dd9d79bdf37eb30933ec2251b5c8ebb1ef7796 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Fri, 8 Aug 2025 15:42:56 +0300 Subject: [PATCH 0273/3659] intel_adsp: kconfig: Increase the default size of MEMORY_WIN_2_SIZE The current default of 8192 will provide only 2 pages in debug window: page0: descriptors page1: slot0 However, the coredump is hardwired to use slot1, which by default is not valid. Increase the default window size to 12288 to allow three pages. This change affects CAVS25 only as it is using default window sizes and the window 3 is not used in this configuration at all (it was used with IPC3 only), so we do have enough space for the three page - we could even increase the default to cover 4 pages (8192+8192), but let's be conservative on this. Signed-off-by: Peter Ujfalusi --- soc/intel/intel_adsp/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/soc/intel/intel_adsp/Kconfig b/soc/intel/intel_adsp/Kconfig index 96fb840010f7..3b3517f9798f 100644 --- a/soc/intel/intel_adsp/Kconfig +++ b/soc/intel/intel_adsp/Kconfig @@ -63,11 +63,11 @@ config MEMORY_WIN_1_SIZE config MEMORY_WIN_2_SIZE int "Size of memory window 2" - default 8192 + default 12288 help Size of memory window 2. - This window is used for debug. + This window is used for debug, default size is 12288 bytes config MEMORY_WIN_3_SIZE int "Size of memory window 3" From 8cb287a411e8f825b8d933802f9c657e06a47b5e Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 18 Jun 2025 09:42:06 +0300 Subject: [PATCH 0274/3659] intel_adsp: debug_window: Describe the partial slot in page0 Resize the reserved part of the debug window to cover the first 1K and define the partial_page0 which will cover the partial slot in page 0. Add comment to describe the debug window layout. Signed-off-by: Peter Ujfalusi --- .../common/include/adsp_debug_window.h | 27 ++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/soc/intel/intel_adsp/common/include/adsp_debug_window.h b/soc/intel/intel_adsp/common/include/adsp_debug_window.h index 2a8a33590d33..f98eaded3a3e 100644 --- a/soc/intel/intel_adsp/common/include/adsp_debug_window.h +++ b/soc/intel/intel_adsp/common/include/adsp_debug_window.h @@ -35,11 +35,34 @@ * u32 res_id; * u32 type; * u32 vma; + * + * The descriptor layout is: + * + * -------------------- + * | Desc0 - slot0 | + * -------------------- + * | Desc1 - slot1 | + * -------------------- + * | Desc2 - slot2 | + * -------------------- + * | ... | + * -------------------- + * | Desc13 - slot13 | + * -------------------- + * | Desc14 - slot14 | + * -------------------- + * + * Additional descriptor to describe the function of the partial slot at page0: + * + * -------------------------- + * | Desc15 - page0 + 1024 | + * -------------------------- */ #define ADSP_DW_PAGE_SIZE 0x1000 #define ADSP_DW_SLOT_SIZE ADSP_DW_PAGE_SIZE #define ADSP_DW_SLOT_COUNT 15 +#define ADSP_DW_PAGE0_SLOT_OFFSET 1024 #define ADSP_DW_DESC_COUNT (ADSP_DW_SLOT_COUNT + 1) /* debug window slots usage, mutually exclusive options can reuse slots */ @@ -73,7 +96,9 @@ struct adsp_dw_desc { struct adsp_debug_window { struct adsp_dw_desc descs[ADSP_DW_DESC_COUNT]; - uint8_t reserved[ADSP_DW_SLOT_SIZE - ADSP_DW_DESC_COUNT * sizeof(struct adsp_dw_desc)]; + uint8_t reserved[ADSP_DW_PAGE0_SLOT_OFFSET - + ADSP_DW_DESC_COUNT * sizeof(struct adsp_dw_desc)]; + uint8_t partial_page0[ADSP_DW_SLOT_SIZE - ADSP_DW_PAGE0_SLOT_OFFSET]; uint8_t slots[ADSP_DW_SLOT_COUNT][ADSP_DW_SLOT_SIZE]; } __packed; From 2ce9d5f5e3ced08e77547fa90c44df2e928842e0 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Tue, 24 Jun 2025 09:33:58 +0300 Subject: [PATCH 0275/3659] soc: intel_adsp: tools: cavstool.py: Look up the shell slot by type Instead of using hardwired index for the shell debug slot, look it up by it's type. Signed-off-by: Peter Ujfalusi --- soc/intel/intel_adsp/tools/cavstool.py | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/soc/intel/intel_adsp/tools/cavstool.py b/soc/intel/intel_adsp/tools/cavstool.py index fcb518c30b3b..9042e9c2891e 100755 --- a/soc/intel/intel_adsp/tools/cavstool.py +++ b/soc/intel/intel_adsp/tools/cavstool.py @@ -37,6 +37,7 @@ DEBUG_SLOT_SIZE = 4096 DEBUG_SLOT_SHELL = 0 +DEBUG_SLOT_SHELL_TYPE = 0x73686c6c SHELL_RX_SIZE = 256 SHELL_MAX_VALID_SLOT_SIZE = 16777216 @@ -769,19 +770,28 @@ def debug_slot_offset_by_type(the_type, timeout_s=0.2): return None def shell_base_offset(): - return debug_offset() + DEBUG_SLOT_SIZE * (1 + DEBUG_SLOT_SHELL) + return debug_slot_offset_by_type(DEBUG_SLOT_SHELL_TYPE) def read_from_shell_memwindow_winstream(last_seq): - offset = shell_base_offset() + SHELL_RX_SIZE - (last_seq, output) = winstream_read(offset, last_seq) - if output: - os.write(shell_client_port, output.encode("utf-8")) + offset = shell_base_offset() + if offset is not None: + offset += SHELL_RX_SIZE + (last_seq, output) = winstream_read(offset, last_seq) + if output: + os.write(shell_client_port, output.encode("utf-8")) + else: + log.info("Shell debug window is not available") + return last_seq def write_to_shell_memwindow_winstream(): msg = os.read(shell_client_port, 1) if len(msg) > 0: - winstream_write(shell_base_offset(), msg) + offset = shell_base_offset() + if offset is not None: + winstream_write(offset, msg) + else: + log.info("Shell debug window is not available") def create_shell_pty(): global shell_client_port From ebb5625bee8a6f03162f9fdfe161cb7dd30838d6 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Mon, 6 Oct 2025 16:21:27 +0300 Subject: [PATCH 0276/3659] intel_adsp: Add debug slot manager Currently all drivers which uses a slot from the debug window have fragile hardwired slot 'mapping', they are locked to use specific slots even if there are free slots available for them to take. The new API hides the management of the slots and descriptors and users can ask, release or even seize slots that they want to use. Add a new debug slot manager API and a new default no config option to allow selection between the hardwired or dynamic debug slot management. Signed-off-by: Peter Ujfalusi --- soc/intel/intel_adsp/Kconfig | 9 + soc/intel/intel_adsp/common/CMakeLists.txt | 4 + soc/intel/intel_adsp/common/debug_window.c | 187 ++++++++++++++++++ .../intel_adsp/common/gdbstub_backend_sram.c | 44 ++++- .../common/include/adsp_debug_window.h | 60 +++++- .../coredump_backend_intel_adsp_mem_window.c | 29 ++- .../backends/log_backend_adsp_mtrace.c | 22 +++ .../shell/backends/shell_adsp_memory_window.c | 22 ++- .../tracing_backend_adsp_memory_window.c | 16 ++ 9 files changed, 379 insertions(+), 14 deletions(-) create mode 100644 soc/intel/intel_adsp/common/debug_window.c diff --git a/soc/intel/intel_adsp/Kconfig b/soc/intel/intel_adsp/Kconfig index 3b3517f9798f..edb9ceb1d288 100644 --- a/soc/intel/intel_adsp/Kconfig +++ b/soc/intel/intel_adsp/Kconfig @@ -77,6 +77,15 @@ config MEMORY_WIN_3_SIZE This window is used for trace. +config INTEL_ADSP_DEBUG_SLOT_MANAGER + bool "Debug slot manager" + help + If selected the debug slot allocation can be only done via + the manager API, direct debug window access and tampering is + forbidden. + The API use allows dynamic slot allocation instead of static + and error prone slot usage. + config ADSP_CLOCK bool help diff --git a/soc/intel/intel_adsp/common/CMakeLists.txt b/soc/intel/intel_adsp/common/CMakeLists.txt index 9e49bd26eabe..d091bd5afd36 100644 --- a/soc/intel/intel_adsp/common/CMakeLists.txt +++ b/soc/intel/intel_adsp/common/CMakeLists.txt @@ -25,6 +25,10 @@ zephyr_library_sources( zephyr_library_sources_ifdef(CONFIG_ADSP_CLOCK clk.c) +zephyr_library_sources_ifdef(CONFIG_INTEL_ADSP_DEBUG_SLOT_MANAGER + debug_window.c + ) + if(CONFIG_SMP OR CONFIG_MP_MAX_NUM_CPUS GREATER 1) zephyr_library_sources(multiprocessing.c) endif() diff --git a/soc/intel/intel_adsp/common/debug_window.c b/soc/intel/intel_adsp/common/debug_window.c new file mode 100644 index 000000000000..b88ae62dcc22 --- /dev/null +++ b/soc/intel/intel_adsp/common/debug_window.c @@ -0,0 +1,187 @@ +/* Copyright (c) 2025 Intel Corporation. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#include +LOG_MODULE_REGISTER(debug_window, CONFIG_SOC_LOG_LEVEL); + +struct adsp_debug_window { + struct adsp_dw_desc descs[ADSP_DW_DESC_COUNT]; + uint8_t reserved[ADSP_DW_PAGE0_SLOT_OFFSET - + ADSP_DW_DESC_COUNT * sizeof(struct adsp_dw_desc)]; + uint8_t partial_page0[ADSP_DW_SLOT_SIZE - ADSP_DW_PAGE0_SLOT_OFFSET]; + uint8_t slots[ADSP_DW_SLOT_COUNT][ADSP_DW_SLOT_SIZE]; +} __packed; + +#define WIN2_MBASE DT_REG_ADDR(DT_PHANDLE(DT_NODELABEL(mem_window2), memory)) +#define WIN2_SLOTS ((HP_SRAM_WIN2_SIZE / ADSP_DW_PAGE_SIZE) - 1) +#define ADSP_DW_FULL_SLOTS MIN(WIN2_SLOTS, ADSP_DW_SLOT_COUNT) + +#define ADSP_DW ((struct adsp_debug_window *) \ + (sys_cache_uncached_ptr_get((__sparse_force void __sparse_cache *) \ + (WIN2_MBASE + WIN2_OFFSET)))) + +static int adsp_dw_find_unused_slot(bool prefer_partial) +{ + int i; + + if (prefer_partial) { + if (ADSP_DW->descs[ADSP_DW_SLOT_COUNT].type == ADSP_DW_SLOT_UNUSED) { + return ADSP_DW_SLOT_COUNT; + } + } + + for (i = 0; i < ADSP_DW_FULL_SLOTS; i++) { + if (ADSP_DW->descs[i].type == ADSP_DW_SLOT_UNUSED) { + return i; + } + } + + if (!prefer_partial) { + if (ADSP_DW->descs[ADSP_DW_SLOT_COUNT].type == ADSP_DW_SLOT_UNUSED) { + return ADSP_DW_SLOT_COUNT; + } + } + + return -ENOENT; +} + +static int adsp_dw_find_slot_by_type(uint32_t type) +{ + int i; + + for (i = 0; i < ADSP_DW_FULL_SLOTS; i++) { + if (ADSP_DW->descs[i].type == type) { + return i; + } + } + + if (ADSP_DW->descs[ADSP_DW_SLOT_COUNT].type == type) { + return ADSP_DW_SLOT_COUNT; + } + + return -ENOENT; +} + +void *adsp_dw_request_slot(struct adsp_dw_desc *dw_desc, size_t *slot_size) +{ + int slot_idx; + + if (!dw_desc->type) { + return NULL; + } + + /* Check if a slot has been allocated for this type */ + slot_idx = adsp_dw_find_slot_by_type(dw_desc->type); + if (slot_idx >= 0) { + if (slot_size) { + *slot_size = ADSP_DW_SLOT_SIZE; + } + + if (slot_idx == ADSP_DW_SLOT_COUNT) { + if (slot_size) { + *slot_size -= ADSP_DW_PAGE0_SLOT_OFFSET; + } + return ADSP_DW->partial_page0; + } + + return ADSP_DW->slots[slot_idx]; + } + + /* Look for an empty slot */ + slot_idx = adsp_dw_find_unused_slot(!!slot_size); + if (slot_idx < 0) { + LOG_INF("No available slot for %#x", dw_desc->type); + return NULL; + } + + ADSP_DW->descs[slot_idx].resource_id = dw_desc->resource_id; + ADSP_DW->descs[slot_idx].type = dw_desc->type; + ADSP_DW->descs[slot_idx].vma = dw_desc->vma; + + if (slot_size) { + *slot_size = ADSP_DW_SLOT_SIZE; + } + + if (slot_idx == ADSP_DW_SLOT_COUNT) { + if (slot_size) { + *slot_size -= ADSP_DW_PAGE0_SLOT_OFFSET; + } + + LOG_DBG("Allocating partial page0 to be used for %#x", dw_desc->type); + + return ADSP_DW->partial_page0; + } + + LOG_DBG("Allocating debug slot %d to be used for %#x", slot_idx, dw_desc->type); + + return ADSP_DW->slots[slot_idx]; +} + +void *adsp_dw_seize_slot(uint32_t slot_index, struct adsp_dw_desc *dw_desc, + size_t *slot_size) +{ + if ((slot_index >= ADSP_DW_FULL_SLOTS && slot_index != ADSP_DW_SLOT_COUNT) || + !dw_desc->type) { + return NULL; + } + + if (slot_index < ADSP_DW_FULL_SLOTS) { + if (ADSP_DW->descs[slot_index].type != ADSP_DW_SLOT_UNUSED) { + LOG_INF("Overtaking debug slot %d, used by %#x for %#x", slot_index, + ADSP_DW->descs[slot_index].type, dw_desc->type); + } + + if (slot_size) { + *slot_size = ADSP_DW_SLOT_SIZE; + } + + ADSP_DW->descs[slot_index].resource_id = dw_desc->resource_id; + ADSP_DW->descs[slot_index].type = dw_desc->type; + ADSP_DW->descs[slot_index].vma = dw_desc->vma; + + return ADSP_DW->slots[slot_index]; + } + + /* The caller is not prepared to handle partial debug slot */ + if (!slot_size) { + return NULL; + } + + if (ADSP_DW->descs[slot_index].type != ADSP_DW_SLOT_UNUSED) { + LOG_INF("Overtaking partial page0, used by %#x for %#x", + ADSP_DW->descs[slot_index].type, dw_desc->type); + } + + *slot_size = ADSP_DW_SLOT_SIZE - ADSP_DW_PAGE0_SLOT_OFFSET; + + ADSP_DW->descs[slot_index].resource_id = dw_desc->resource_id; + ADSP_DW->descs[slot_index].type = dw_desc->type; + ADSP_DW->descs[slot_index].vma = dw_desc->vma; + + return ADSP_DW->partial_page0; +} + +void adsp_dw_release_slot(uint32_t type) +{ + int slot_idx; + + slot_idx = adsp_dw_find_slot_by_type(type); + if (slot_idx < 0) { + return; + } + + if (slot_idx == ADSP_DW_SLOT_COUNT) { + LOG_DBG("Releasing partial page0 used by %#x", type); + } else { + LOG_DBG("Releasing debug slot %d used by %#x", slot_idx, type); + } + + ADSP_DW->descs[slot_idx].resource_id = 0; + ADSP_DW->descs[slot_idx].type = ADSP_DW_SLOT_UNUSED; + ADSP_DW->descs[slot_idx].vma = 0; +} diff --git a/soc/intel/intel_adsp/common/gdbstub_backend_sram.c b/soc/intel/intel_adsp/common/gdbstub_backend_sram.c index 7477d38e5c99..4a33e9397d60 100644 --- a/soc/intel/intel_adsp/common/gdbstub_backend_sram.c +++ b/soc/intel/intel_adsp/common/gdbstub_backend_sram.c @@ -57,18 +57,51 @@ static inline int ring_have_data(const volatile struct gdb_sram_ring *ring) return ring->head != ring->tail; } -#define RX_UNCACHED (uint8_t *) (HP_SRAM_WIN2_BASE + SOF_GDB_WINDOW_OFFSET) -#define TX_UNCACHED (uint8_t *) (RX_UNCACHED + sizeof(struct gdb_sram_ring)) - static volatile struct gdb_sram_ring *rx; static volatile struct gdb_sram_ring *tx; +#ifndef CONFIG_INTEL_ADSP_DEBUG_SLOT_MANAGER +static int gdb_get_debug_slot(void) +{ + struct adsp_dw_desc slot_desc = { .type = ADSP_DW_SLOT_GDB_STUB, }; + size_t slot_size; + char *slot_addr; + + if (rx && tx) { + /* Slot already allocated */ + return 0; + } + + /* Force use the partial page0 slot */ + slot_addr = (char *)adsp_dw_request_slot(&slot_desc, &slot_size); + if (!slot_addr) { + return -ENOMEM; + } + + rx = sys_cache_uncached_ptr_get(slot_addr); + tx = sys_cache_uncached_ptr_get(slot_addr + sizeof(struct gdb_sram_ring)); + + return 0; +} +#define RX_UNCACHED (uint8_t *) (HP_SRAM_WIN2_BASE + SOF_GDB_WINDOW_OFFSET) +#define TX_UNCACHED (uint8_t *) (RX_UNCACHED + sizeof(struct gdb_sram_ring)) +#endif + int z_gdb_backend_init(void) { +#ifdef CONFIG_INTEL_ADSP_DEBUG_SLOT_MANAGER + int ret = gdb_get_debug_slot(); + + if (ret) { + return ret; + } +#else __ASSERT_NO_MSG(sizeof(ADSP_DW->descs) <= SOF_GDB_WINDOW_OFFSET); rx = sys_cache_uncached_ptr_get(RX_UNCACHED); tx = sys_cache_uncached_ptr_get(TX_UNCACHED); +#endif + rx->head = rx->tail = 0; tx->head = tx->tail = 0; @@ -98,7 +131,12 @@ unsigned char z_gdb_getchar(void) static int gdbstub_backend_sram_init(void) { +#ifdef CONFIG_INTEL_ADSP_DEBUG_SLOT_MANAGER + return gdb_get_debug_slot(); +#else ADSP_DW->descs[ADSP_DW_SLOT_NUM_GDB].type = ADSP_DW_SLOT_GDB_STUB; +#endif + return 0; } diff --git a/soc/intel/intel_adsp/common/include/adsp_debug_window.h b/soc/intel/intel_adsp/common/include/adsp_debug_window.h index f98eaded3a3e..64e1ee3e08b3 100644 --- a/soc/intel/intel_adsp/common/include/adsp_debug_window.h +++ b/soc/intel/intel_adsp/common/include/adsp_debug_window.h @@ -65,14 +65,6 @@ #define ADSP_DW_PAGE0_SLOT_OFFSET 1024 #define ADSP_DW_DESC_COUNT (ADSP_DW_SLOT_COUNT + 1) -/* debug window slots usage, mutually exclusive options can reuse slots */ -#define ADSP_DW_SLOT_NUM_SHELL 0 -#define ADSP_DW_SLOT_NUM_MTRACE 0 -#define ADSP_DW_SLOT_NUM_TRACE 1 -#define ADSP_DW_SLOT_NUM_TELEMETRY 1 -/* this uses remaining space in the first page after descriptors */ -#define ADSP_DW_SLOT_NUM_GDB (ADSP_DW_DESC_COUNT - 1) - /* debug log slot types */ #define ADSP_DW_SLOT_UNUSED 0x00000000 #define ADSP_DW_SLOT_CRITICAL_LOG 0x54524300 @@ -94,6 +86,56 @@ struct adsp_dw_desc { uint32_t vma; } __packed; +#ifdef CONFIG_INTEL_ADSP_DEBUG_SLOT_MANAGER +/** + * @brief Request a free debug slot for a function described by desc + * + * if a slot for the same function has been already allocated, the existing slot will be returned + * + * @param dw_desc Description of the slot to be requested for + * @param slot_size Optional pointer to receive back the size of the assigned slot, if not + * provided then the partial slot from window 0 cannot be requested as caller + * must be aware and be able to handle the different size of the slot + * + * @return Pointer to the start of the slot or NULL in case of an error. When NULL is + * returned, the @slot_size value is undefined. + */ +void *adsp_dw_request_slot(struct adsp_dw_desc *dw_desc, size_t *slot_size); + +/** + * @brief Forcibly overtake a slot + * + * @param slot_index Index of the slot to take. + * Requesting ADSP_DW_FULL_SLOTS will return the partial slot + * @param dw_desc Description of the slot to be requested for + * @param slot_size Optional pointer to receive back the size of the assigned slot, if not + * provided then the partial slot from window 0 cannot be requested as caller + * must be aware and be able to handle the different size of the slot + * + * @return Pointer to the start of the slot or NULL in case of an error. When NULL is + * returned, the @slot_size value is undefined. + */ +void *adsp_dw_seize_slot(uint32_t slot_index, struct adsp_dw_desc *dw_desc, + size_t *slot_size); + +/**( + * @brief Release a slot allocated for type + * + * @param type Slot type to be released + * + * @note Only a single slot can be allocated at the same time for a type + */ +void adsp_dw_release_slot(uint32_t type); +#else /* CONFIG_INTEL_ADSP_DEBUG_SLOT_MANAGER */ + +/* debug window slots usage, mutually exclusive options can reuse slots */ +#define ADSP_DW_SLOT_NUM_SHELL 0 +#define ADSP_DW_SLOT_NUM_MTRACE 0 +#define ADSP_DW_SLOT_NUM_TRACE 1 +#define ADSP_DW_SLOT_NUM_TELEMETRY 1 +/* this uses remaining space in the first page after descriptors */ +#define ADSP_DW_SLOT_NUM_GDB (ADSP_DW_DESC_COUNT - 1) + struct adsp_debug_window { struct adsp_dw_desc descs[ADSP_DW_DESC_COUNT]; uint8_t reserved[ADSP_DW_PAGE0_SLOT_OFFSET - @@ -108,4 +150,6 @@ struct adsp_debug_window { (sys_cache_uncached_ptr_get((__sparse_force void __sparse_cache *) \ (WIN2_MBASE + WIN2_OFFSET)))) +#endif /* CONFIG_INTEL_ADSP_DEBUG_SLOT_MANAGER */ + #endif diff --git a/subsys/debug/coredump/coredump_backend_intel_adsp_mem_window.c b/subsys/debug/coredump/coredump_backend_intel_adsp_mem_window.c index 201a2e8a2a43..17bf3461037b 100644 --- a/subsys/debug/coredump/coredump_backend_intel_adsp_mem_window.c +++ b/subsys/debug/coredump/coredump_backend_intel_adsp_mem_window.c @@ -20,12 +20,27 @@ LOG_MODULE_REGISTER(coredump, CONFIG_DEBUG_COREDUMP_LOG_LEVEL); static int error; static uint32_t mem_wptr; +#ifdef CONFIG_INTEL_ADSP_DEBUG_SLOT_MANAGER +static void *coredump_slot_addr; +#endif + static void coredump_mem_window_backend_start(void) { /* Reset error & mem write ptr */ error = 0; mem_wptr = 0; +#ifdef CONFIG_INTEL_ADSP_DEBUG_SLOT_MANAGER + struct adsp_dw_desc slot_desc = { .type = ADSP_DW_SLOT_TELEMETRY, }; + + /* Forcibly take debug slot 1 */ + coredump_slot_addr = adsp_dw_seize_slot(1, &slot_desc, NULL); + if (!coredump_slot_addr) { + /* Try to get the first slot if slot 1 is not available as fallback */ + coredump_slot_addr = adsp_dw_seize_slot(0, &slot_desc, NULL); + } +#else ADSP_DW->descs[1].type = ADSP_DW_SLOT_TELEMETRY; +#endif while (LOG_PROCESS()) { ; @@ -46,10 +61,20 @@ static void coredump_mem_window_backend_end(void) static void coredump_mem_window_backend_buffer_output(uint8_t *buf, size_t buflen) { - uint32_t *mem_window_separator = (uint32_t *)(ADSP_DW->slots[1]); - uint8_t *mem_window_sink = (uint8_t *)(ADSP_DW->slots[1]) + 4 + mem_wptr; uint8_t *coredump_data = buf; size_t data_left; +#ifdef CONFIG_INTEL_ADSP_DEBUG_SLOT_MANAGER + uint32_t *mem_window_separator = (uint32_t *)coredump_slot_addr; + uint8_t *mem_window_sink = (uint8_t *)coredump_slot_addr + 4 + mem_wptr; + + if (!coredump_slot_addr) { + return; + } +#else + uint32_t *mem_window_separator = (uint32_t *)(ADSP_DW->slots[1]); + uint8_t *mem_window_sink = (uint8_t *)(ADSP_DW->slots[1]) + 4 + mem_wptr; +#endif + /* Default place for telemetry dump is in memory window. Each data is easily find using * separator. For telemetry that separator is 0x0DEC0DEB. */ diff --git a/subsys/logging/backends/log_backend_adsp_mtrace.c b/subsys/logging/backends/log_backend_adsp_mtrace.c index 10271c9c8ed9..bbceefa4a29d 100644 --- a/subsys/logging/backends/log_backend_adsp_mtrace.c +++ b/subsys/logging/backends/log_backend_adsp_mtrace.c @@ -64,19 +64,41 @@ struct adsp_debug_slot { uint8_t data[ADSP_DW_SLOT_SIZE - sizeof(uint32_t) * 2]; } __packed; +#ifdef CONFIG_INTEL_ADSP_DEBUG_SLOT_MANAGER +static struct adsp_debug_slot *slot; +#endif + static void mtrace_init(void) { +#ifdef CONFIG_INTEL_ADSP_DEBUG_SLOT_MANAGER + struct adsp_dw_desc slot_desc = { .type = MTRACE_LOGGING_SLOT_TYPE(MTRACE_CORE), }; + + if (slot) { + return; + } + + slot = adsp_dw_request_slot(&slot_desc, NULL); +#else if (ADSP_DW->descs[ADSP_DW_SLOT_NUM_MTRACE].type == MTRACE_LOGGING_SLOT_TYPE(MTRACE_CORE)) { return; } ADSP_DW->descs[ADSP_DW_SLOT_NUM_MTRACE].type = MTRACE_LOGGING_SLOT_TYPE(MTRACE_CORE); +#endif } static size_t mtrace_out(int8_t *str, size_t len, size_t *space_left) { +#ifdef CONFIG_INTEL_ADSP_DEBUG_SLOT_MANAGER + /* Debug slot is not allocated */ + if (!slot) { + return 0; + } +#else struct adsp_debug_slot *slot = (struct adsp_debug_slot *) ADSP_DW->slots[ADSP_DW_SLOT_NUM_MTRACE]; +#endif + uint8_t *data = slot->data; uint32_t r = slot->host_ptr; uint32_t w = slot->dsp_ptr; diff --git a/subsys/shell/backends/shell_adsp_memory_window.c b/subsys/shell/backends/shell_adsp_memory_window.c index 519e68ea52f0..50730d9b41f7 100644 --- a/subsys/shell/backends/shell_adsp_memory_window.c +++ b/subsys/shell/backends/shell_adsp_memory_window.c @@ -22,6 +22,10 @@ LOG_MODULE_REGISTER(shell_adsp_memory_window); BUILD_ASSERT(RX_WINDOW_SIZE < ADSP_DW_SLOT_SIZE); +#ifdef CONFIG_INTEL_ADSP_DEBUG_SLOT_MANAGER +static struct adsp_debug_slot_shell *dw_slot; +#endif + struct adsp_debug_slot_shell { uint8_t rx_window[RX_WINDOW_SIZE]; uint8_t tx_window[ADSP_DW_SLOT_SIZE - RX_WINDOW_SIZE]; @@ -44,6 +48,15 @@ static int init(const struct shell_transport *transport, { struct shell_adsp_memory_window *sh_adsp_mw = (struct shell_adsp_memory_window *)transport->ctx; + +#ifdef CONFIG_INTEL_ADSP_DEBUG_SLOT_MANAGER + struct adsp_dw_desc slot_desc = { .type = ADSP_DW_SLOT_SHELL, }; + + dw_slot = (struct adsp_debug_slot_shell *)adsp_dw_request_slot(&slot_desc, NULL); + if (!dw_slot) { + return -ENOTSUP; + } +#else struct adsp_debug_slot_shell *dw_slot; if (ADSP_DW->descs[ADSP_DW_SLOT_NUM_SHELL].type && @@ -55,10 +68,12 @@ static int init(const struct shell_transport *transport, ADSP_DW->descs[ADSP_DW_SLOT_NUM_SHELL].type = ADSP_DW->descs[ADSP_DW_SLOT_NUM_SHELL].type; + dw_slot = (struct adsp_debug_slot_shell *)ADSP_DW->slots[ADSP_DW_SLOT_NUM_SHELL]; +#endif + sh_adsp_mw->shell_handler = evt_handler; sh_adsp_mw->shell_context = context; - dw_slot = (struct adsp_debug_slot_shell *)ADSP_DW->slots[ADSP_DW_SLOT_NUM_SHELL]; sh_adsp_mw->ws_rx = sys_winstream_init(&dw_slot->rx_window[0], sizeof(dw_slot->rx_window)); sh_adsp_mw->ws_tx = sys_winstream_init(&dw_slot->tx_window[0], sizeof(dw_slot->tx_window)); @@ -80,6 +95,11 @@ static int uninit(const struct shell_transport *transport) k_timer_stop(&sh_adsp_mw->timer); +#ifdef CONFIG_INTEL_ADSP_DEBUG_SLOT_MANAGER + adsp_dw_release_slot(ADSP_DW_SLOT_SHELL); + dw_slot = NULL; +#endif + return 0; } diff --git a/subsys/tracing/tracing_backend_adsp_memory_window.c b/subsys/tracing/tracing_backend_adsp_memory_window.c index 43f8229ad964..5d6e1a6e16b7 100644 --- a/subsys/tracing/tracing_backend_adsp_memory_window.c +++ b/subsys/tracing/tracing_backend_adsp_memory_window.c @@ -29,6 +29,12 @@ static void tracing_backend_adsp_memory_window_output( const struct tracing_backend *backend, uint8_t *data, uint32_t length) { +#ifdef CONFIG_INTEL_ADSP_DEBUG_SLOT_MANAGER + if (!mem_window) { + return; + } +#endif + /* copy data to ring buffer, * to make FW part fast, there's no sync with the data reader * the reader MUST read data before they got overwritten @@ -48,6 +54,15 @@ static void tracing_backend_adsp_memory_window_output( static void tracing_backend_adsp_memory_window_init(void) { +#ifdef CONFIG_INTEL_ADSP_DEBUG_SLOT_MANAGER + struct adsp_dw_desc slot_desc = { .type = ADSP_DW_SLOT_TRACE, }; + + mem_window = (struct tracing_backend_adsp_memory_window *)adsp_dw_request_slot(&slot_desc, + NULL); + if (mem_window) { + mem_window->head_offset = 0; + } +#else volatile struct adsp_debug_window *window = ADSP_DW; window->descs[ADSP_DW_SLOT_NUM_TRACE].type = ADSP_DW_SLOT_TRACE; @@ -56,6 +71,7 @@ static void tracing_backend_adsp_memory_window_init(void) ADSP_DW->slots[ADSP_DW_SLOT_NUM_TRACE]; mem_window->head_offset = 0; +#endif } const struct tracing_backend_api tracing_backend_adsp_memory_window_api = { From d32e7de5091e1a6b8497b8e9f3739d274e60a776 Mon Sep 17 00:00:00 2001 From: Jeppe Odgaard Date: Thu, 11 Dec 2025 15:52:40 +0100 Subject: [PATCH 0277/3659] debug: coredump: add cpp header guards Add header guards to support usage from C++. Signed-off-by: Jeppe Odgaard --- include/zephyr/debug/coredump.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/include/zephyr/debug/coredump.h b/include/zephyr/debug/coredump.h index bf045763c458..908024cf00f9 100644 --- a/include/zephyr/debug/coredump.h +++ b/include/zephyr/debug/coredump.h @@ -11,6 +11,10 @@ #include #include +#ifdef __cplusplus +extern "C" { +#endif + /* * Define COREDUMP_*_STR as public to allow coredump_backend_other to re-use * these strings if necessary @@ -354,4 +358,8 @@ static inline int coredump_cmd(enum coredump_cmd_id query_id, void *arg) * @} */ +#ifdef __cplusplus +} +#endif + #endif /* ZEPHYR_INCLUDE_DEBUG_COREDUMP_H_ */ From d26ffeba9d25cbbe60c3b0d8de7e9e749ccf6f02 Mon Sep 17 00:00:00 2001 From: Ruibin Chang Date: Mon, 17 Nov 2025 11:30:18 +0800 Subject: [PATCH 0278/3659] drivers/pwm/it8xxx2: add pwm init output level property When EC reboot, pwm pins go back to default GPI mode. After we set pin mode to pwm mode at init(), it would output low, so LED will be light (LED is low-activated). And until set_cycles() is called to set output high, then LED will be turn off the light (PWM-LED flicker). So add the property to set PWM channel init output level. Signed-off-by: Ruibin Chang --- drivers/pwm/pwm_ite_it8xxx2.c | 16 ++++++++++++++++ dts/bindings/pwm/ite,it8xxx2-pwm.yaml | 6 ++++++ 2 files changed, 22 insertions(+) diff --git a/drivers/pwm/pwm_ite_it8xxx2.c b/drivers/pwm/pwm_ite_it8xxx2.c index 6e265c8be5df..14be0b97f9cb 100644 --- a/drivers/pwm/pwm_ite_it8xxx2.c +++ b/drivers/pwm/pwm_ite_it8xxx2.c @@ -35,6 +35,8 @@ struct pwm_it8xxx2_cfg { uintptr_t reg_pwmpol; /* PWM channel */ int channel; + /* Init PWM channel output high */ + bool pwm_init_high; /* PWM prescaler control register base */ struct pwm_it8xxx2_regs *base; /* Select PWM prescaler that output to PWM channel */ @@ -232,7 +234,9 @@ static int pwm_it8xxx2_init(const struct device *dev) { const struct pwm_it8xxx2_cfg *config = dev->config; struct pwm_it8xxx2_regs *const inst = config->base; + volatile uint8_t *reg_dcr = (uint8_t *)config->reg_dcr; volatile uint8_t *reg_pcssg = (uint8_t *)config->reg_pcssg; + volatile uint8_t *reg_pwmpol = (uint8_t *)config->reg_pwmpol; int ch = config->channel; int prs_sel = config->prs_sel; int pcssg_shift; @@ -262,6 +266,17 @@ static int pwm_it8xxx2_init(const struct device *dev) */ inst->CTR1M = 0; + /* Set PWM init output level */ + *reg_dcr = 0; + if (config->pwm_init_high) { + *reg_pwmpol |= BIT(ch); + } else { + *reg_pwmpol &= ~BIT(ch); + } + + /* PWM channel clock source not gating */ + pwm_enable(dev, 1); + /* Enable PWMs clock counter */ inst->ZTIER |= IT8XXX2_PWM_PCCE; @@ -290,6 +305,7 @@ static DEVICE_API(pwm, pwm_it8xxx2_api) = { .reg_pcsgr = DT_INST_REG_ADDR_BY_IDX(inst, 2), \ .reg_pwmpol = DT_INST_REG_ADDR_BY_IDX(inst, 3), \ .channel = DT_PROP(DT_INST(inst, ite_it8xxx2_pwm), channel), \ + .pwm_init_high = DT_INST_PROP(inst, pwm_init_high), \ .base = (struct pwm_it8xxx2_regs *) DT_REG_ADDR(DT_NODELABEL(prs)), \ .prs_sel = DT_PROP(DT_INST(inst, ite_it8xxx2_pwm), prescaler_cx), \ .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(inst), \ diff --git a/dts/bindings/pwm/ite,it8xxx2-pwm.yaml b/dts/bindings/pwm/ite,it8xxx2-pwm.yaml index 81eafc5b95c3..10f387fad1ef 100644 --- a/dts/bindings/pwm/ite,it8xxx2-pwm.yaml +++ b/dts/bindings/pwm/ite,it8xxx2-pwm.yaml @@ -28,6 +28,12 @@ properties: 3 = PWM_CHANNEL_3, 4 = PWM_CHANNEL_4, 5 = PWM_CHANNEL_5, 6 = PWM_CHANNEL_6, 7 = PWM_CHANNEL_7 + pwm-init-high: + type: boolean + description: | + After setting PWM pin to alternate mode, initialize PWM pin to output high, + otherwise output low. + pwmctrl: type: phandle required: true From 7389cbbd3ea76648c3f9d0dac9e65fcfbbaa0ef0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Tue, 9 Dec 2025 10:44:58 +0100 Subject: [PATCH 0279/3659] sys: util: hide internal gcd/lcm helpers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These should not show up as API in doxygen Signed-off-by: Benjamin Cabé --- include/zephyr/sys/util.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/include/zephyr/sys/util.h b/include/zephyr/sys/util.h index 7750b9e38215..63e66bfd428c 100644 --- a/include/zephyr/sys/util.h +++ b/include/zephyr/sys/util.h @@ -1050,6 +1050,9 @@ static inline size_t sys_count_bits(const void *value, size_t len) */ #define gcd(a, b) ((((__typeof__(a))-1) < 0) ? gcd_s(a, b) : gcd_u(a, b)) +/** + * @cond INTERNAL_HIDDEN + */ static ALWAYS_INLINE uint32_t gcd_u(uint32_t a, uint32_t b) { uint32_t c; @@ -1076,6 +1079,9 @@ static ALWAYS_INLINE uint32_t gcd_s(int32_t a, int32_t b) { return gcd_u(a < 0 ? -(uint32_t)a : (uint32_t)a, b < 0 ? -(uint32_t)b : (uint32_t)b); } +/** + * @endcond + */ /** * @brief Compute the Least Common Multiple (LCM) of two integers. @@ -1088,6 +1094,9 @@ static ALWAYS_INLINE uint32_t gcd_s(int32_t a, int32_t b) */ #define lcm(a, b) ((((__typeof__(a))-1) < 0) ? lcm_s(a, b) : lcm_u(a, b)) +/** + * @cond INTERNAL_HIDDEN + */ static ALWAYS_INLINE uint64_t lcm_u(uint32_t a, uint32_t b) { if (a == 0 || b == 0) { @@ -1101,6 +1110,9 @@ static ALWAYS_INLINE uint64_t lcm_s(int32_t a, int32_t b) { return lcm_u(a < 0 ? -(uint32_t)a : (uint32_t)a, b < 0 ? -(uint32_t)b : (uint32_t)b); } +/** + * @endcond + */ #ifdef __cplusplus } From bef6cdb1276f290e63e57658b85feef47b62601d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Tue, 9 Dec 2025 10:46:01 +0100 Subject: [PATCH 0280/3659] sys: util: add sys_ prefix to SIGN, gcd, and lcm utils MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As per our naming conventions for public symbols, these utility functions and macros should be prefixed with "sys_". Signed-off-by: Benjamin Cabé --- include/zephyr/sys/util.h | 20 ++++++------- lib/utils/getopt/getopt_long.c | 3 +- tests/unit/util/main.c | 52 +++++++++++++++++----------------- 3 files changed, 38 insertions(+), 37 deletions(-) diff --git a/include/zephyr/sys/util.h b/include/zephyr/sys/util.h index 63e66bfd428c..31ff2228ca81 100644 --- a/include/zephyr/sys/util.h +++ b/include/zephyr/sys/util.h @@ -1036,7 +1036,7 @@ static inline size_t sys_count_bits(const void *value, size_t len) * @retval -1 if x is negative * @retval 0 if x is zero */ -#define SIGN(x) (((x) > 0) - ((x) < 0)) +#define SYS_SIGN(x) (((x) > 0) - ((x) < 0)) /** * @brief Compute the Greatest Common Divisor (GCD) of two integers @@ -1048,12 +1048,12 @@ static inline size_t sys_count_bits(const void *value, size_t len) * @return The greatest common divisor of a and b, always returns an unsigned value. * If one of the parameters is 0, returns the absolute value of the other parameter. */ -#define gcd(a, b) ((((__typeof__(a))-1) < 0) ? gcd_s(a, b) : gcd_u(a, b)) +#define sys_gcd(a, b) ((((__typeof__(a))-1) < 0) ? sys_gcd_s(a, b) : sys_gcd_u(a, b)) /** * @cond INTERNAL_HIDDEN */ -static ALWAYS_INLINE uint32_t gcd_u(uint32_t a, uint32_t b) +static ALWAYS_INLINE uint32_t sys_gcd_u(uint32_t a, uint32_t b) { uint32_t c; @@ -1075,9 +1075,9 @@ static ALWAYS_INLINE uint32_t gcd_u(uint32_t a, uint32_t b) return b; } -static ALWAYS_INLINE uint32_t gcd_s(int32_t a, int32_t b) +static ALWAYS_INLINE uint32_t sys_gcd_s(int32_t a, int32_t b) { - return gcd_u(a < 0 ? -(uint32_t)a : (uint32_t)a, b < 0 ? -(uint32_t)b : (uint32_t)b); + return sys_gcd_u(a < 0 ? -(uint32_t)a : (uint32_t)a, b < 0 ? -(uint32_t)b : (uint32_t)b); } /** * @endcond @@ -1092,23 +1092,23 @@ static ALWAYS_INLINE uint32_t gcd_s(int32_t a, int32_t b) * @retval The least common multiple of a and b. * @retval 0 if either input is 0. */ -#define lcm(a, b) ((((__typeof__(a))-1) < 0) ? lcm_s(a, b) : lcm_u(a, b)) +#define sys_lcm(a, b) ((((__typeof__(a))-1) < 0) ? sys_lcm_s(a, b) : sys_lcm_u(a, b)) /** * @cond INTERNAL_HIDDEN */ -static ALWAYS_INLINE uint64_t lcm_u(uint32_t a, uint32_t b) +static ALWAYS_INLINE uint64_t sys_lcm_u(uint32_t a, uint32_t b) { if (a == 0 || b == 0) { return 0; } - return (uint64_t)(a / gcd_u(a, b)) * (uint64_t)b; + return (uint64_t)(a / sys_gcd_u(a, b)) * (uint64_t)b; } -static ALWAYS_INLINE uint64_t lcm_s(int32_t a, int32_t b) +static ALWAYS_INLINE uint64_t sys_lcm_s(int32_t a, int32_t b) { - return lcm_u(a < 0 ? -(uint32_t)a : (uint32_t)a, b < 0 ? -(uint32_t)b : (uint32_t)b); + return sys_lcm_u(a < 0 ? -(uint32_t)a : (uint32_t)a, b < 0 ? -(uint32_t)b : (uint32_t)b); } /** * @endcond diff --git a/lib/utils/getopt/getopt_long.c b/lib/utils/getopt/getopt_long.c index ac739e50a736..d03f48ba7d26 100644 --- a/lib/utils/getopt/getopt_long.c +++ b/lib/utils/getopt/getopt_long.c @@ -52,6 +52,7 @@ #include #include +#include #include "getopt_common.h" #include @@ -120,7 +121,7 @@ static void permute_args(int panonopt_start, int panonopt_end, int opt_end, char */ nnonopts = panonopt_end - panonopt_start; nopts = opt_end - panonopt_end; - ncycle = gcd(nnonopts, nopts); + ncycle = sys_gcd(nnonopts, nopts); cyclelen = (opt_end - panonopt_start) / ncycle; for (int i = 0; i < ncycle; i++) { diff --git a/tests/unit/util/main.c b/tests/unit/util/main.c index eeb97a43c519..33822b811447 100644 --- a/tests/unit/util/main.c +++ b/tests/unit/util/main.c @@ -1240,67 +1240,67 @@ ZTEST(util, test_bitmask_find_gap) test_single_bitmask_find_gap(0x0000000F, 2, 6, false, 4, __LINE__); } -ZTEST(util, test_gcd) +ZTEST(util, test_sys_gcd) { /* Zero cases */ - zassert_equal(gcd(0, 0), 0, "should be 0"); - zassert_equal(gcd(0, INT_MAX), INT_MAX, "should be 0"); - zassert_equal(gcd(INT_MAX, 0), INT_MAX, "should be 0"); + zassert_equal(sys_gcd(0, 0), 0, "should be 0"); + zassert_equal(sys_gcd(0, INT_MAX), INT_MAX, "should be 0"); + zassert_equal(sys_gcd(INT_MAX, 0), INT_MAX, "should be 0"); /* Normal cases */ - zassert_equal(gcd(12, 8), 4, "should be 4"); + zassert_equal(sys_gcd(12, 8), 4, "should be 4"); /* Negative number cases */ - zassert_equal(gcd(-12, 8), 4, "should be 4"); - zassert_equal(gcd(-12, -8), 4, "should be 4"); + zassert_equal(sys_gcd(-12, 8), 4, "should be 4"); + zassert_equal(sys_gcd(-12, -8), 4, "should be 4"); /* Prime numbers */ - zassert_equal(gcd(17, 13), 1, "should be 1"); - zassert_equal(gcd(25, 49), 1, "should be 1"); + zassert_equal(sys_gcd(17, 13), 1, "should be 1"); + zassert_equal(sys_gcd(25, 49), 1, "should be 1"); /* Boundary values */ - zassert_equal(gcd(INT_MAX, INT_MAX), INT_MAX, "should be INT_MAX"); - zassert_equal(gcd(INT_MIN, INT_MIN), (uint32_t)(-(int64_t)INT_MIN), + zassert_equal(sys_gcd(INT_MAX, INT_MAX), INT_MAX, "should be INT_MAX"); + zassert_equal(sys_gcd(INT_MIN, INT_MIN), (uint32_t)(-(int64_t)INT_MIN), "should be INT_MAX + 1"); - zassert_equal(gcd(INT_MIN, INT_MAX), 1, "should be 1"); - zassert_equal(gcd(UINT32_MAX, UINT32_MAX), UINT32_MAX, "should be UINT32_MAX"); + zassert_equal(sys_gcd(INT_MIN, INT_MAX), 1, "should be 1"); + zassert_equal(sys_gcd(UINT32_MAX, UINT32_MAX), UINT32_MAX, "should be UINT32_MAX"); /* Macro expansion */ int a = 12, b = 8; - zassert_equal(gcd(a++, b++), 4, "should be 4"); + zassert_equal(sys_gcd(a++, b++), 4, "should be 4"); zassert_equal(a, 13, "should be 13"); zassert_equal(b, 9, "should be 9"); } -ZTEST(util, test_lcm) +ZTEST(util, test_sys_lcm) { /* Zero cases - lcm with 0 should be 0 */ - zassert_equal(lcm(0, 0), 0, "should be 0"); - zassert_equal(lcm(0, INT_MAX), 0, "should be 0"); + zassert_equal(sys_lcm(0, 0), 0, "should be 0"); + zassert_equal(sys_lcm(0, INT_MAX), 0, "should be 0"); /* Normal cases */ - zassert_equal(lcm(12, 8), 24, "should be 24"); - zassert_equal(lcm(8, 12), 24, "should be 24"); + zassert_equal(sys_lcm(12, 8), 24, "should be 24"); + zassert_equal(sys_lcm(8, 12), 24, "should be 24"); /* Negative number cases - lcm should always be positive */ - zassert_equal(lcm(-12, 8), 24, "should be 24"); + zassert_equal(sys_lcm(-12, 8), 24, "should be 24"); /* Prime numbers (gcd = 1, so lcm = a * b) */ - zassert_equal(lcm(17, 13), 221, "should be 221"); + zassert_equal(sys_lcm(17, 13), 221, "should be 221"); /* Boundary values */ - zassert_equal(lcm(INT_MAX, INT_MAX - 1), (uint64_t)INT_MAX * (INT_MAX - 1), + zassert_equal(sys_lcm(INT_MAX, INT_MAX - 1), (uint64_t)INT_MAX * (INT_MAX - 1), "should be INT_MAX * (INT_MAX - 1)"); - zassert_equal(lcm(INT_MIN, INT_MIN), (uint64_t)INT_MAX + 1, "should be INT_MAX + 1"); - zassert_equal(lcm(INT_MIN, INT_MAX), (uint64_t)INT_MAX * (uint64_t)(-(int64_t)INT_MIN), + zassert_equal(sys_lcm(INT_MIN, INT_MIN), (uint64_t)INT_MAX + 1, "should be INT_MAX + 1"); + zassert_equal(sys_lcm(INT_MIN, INT_MAX), (uint64_t)INT_MAX * (uint64_t)(-(int64_t)INT_MIN), "should be INT_MAX * (INT_MAX + 1)"); - zassert_equal(lcm(UINT32_MAX, UINT32_MAX), UINT32_MAX, "should be UINT32_MAX"); + zassert_equal(sys_lcm(UINT32_MAX, UINT32_MAX), UINT32_MAX, "should be UINT32_MAX"); /* Macro expansion */ int a = 12, b = 8; - zassert_equal(lcm(a++, b++), 24, "should be 4"); + zassert_equal(sys_lcm(a++, b++), 24, "should be 4"); zassert_equal(a, 13, "should be 13"); zassert_equal(b, 9, "should be 9"); } From 7c2ab76a706e24cbb0ab534ae36c8308fed2ab13 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Mon, 10 Nov 2025 09:14:56 +0100 Subject: [PATCH 0281/3659] drivers: timer: nrf_grtc: Decouple clock source from CLOCK_CONTROL The GRTC timer, typically used as sys clock on newer nordic chips, is currently tightly coupled to the CLOCK_CONTROL_NRF drivers though not being dependent on it. The GRTC and its device driver is independent from CLOCK_CONTROL, its clock requirements are managed by hardware, based on its clock source selection. This commit moves the clock source selection to the GRTC driver, and removes the hard coupling to the CLOCK_CONTROL drivers. To preserve backwards compatibility, if CLOCK_CONTROL_NRF_K32SRC_RC is selected, GRTC will default to LFLPRC. Signed-off-by: Bjarki Arge Andreasen --- drivers/timer/Kconfig.nrf_grtc | 25 +++++++++++++++++++++++++ drivers/timer/nrf_grtc_timer.c | 5 +++-- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/drivers/timer/Kconfig.nrf_grtc b/drivers/timer/Kconfig.nrf_grtc index affbe72998f7..ab230245ebfd 100644 --- a/drivers/timer/Kconfig.nrf_grtc +++ b/drivers/timer/Kconfig.nrf_grtc @@ -57,4 +57,29 @@ config NRF_GRTC_TIMER_AUTO_KEEP_ALIVE This feature prevents the SYSCOUNTER from sleeping when any core is in active state. +if NRF_GRTC_START_SYSCOUNTER + +choice NRF_GRTC_TIMER_SOURCE + prompt "nRF GRTC clock source" + # Default to LFLPRC if CLOCK_CONTROL_NRF_K32SRC_RC for backwards compatibility + default NRF_GRTC_TIMER_SOURCE_LFLPRC if CLOCK_CONTROL_NRF_K32SRC_RC + # Default to LFXO if present as this allows GRTC to run in SYSTEM OFF + default NRF_GRTC_TIMER_SOURCE_LFXO + # Default to SYSTEM_LFCLK if LFXO is not present + default NRF_GRTC_TIMER_SOURCE_SYSTEM_LFCLK + +config NRF_GRTC_TIMER_SOURCE_LFXO + bool "Use Low Frequency XO as clock source" + depends on $(dt_nodelabel_enabled,lfxo) + +config NRF_GRTC_TIMER_SOURCE_SYSTEM_LFCLK + bool "Use System Low Frequency clock as clock source" + +config NRF_GRTC_TIMER_SOURCE_LFLPRC + bool "Use Low Frequency Low Power RC as clock source" + +endchoice # NRF_GRTC_TIMER_SOURCE + +endif # NRF_GRTC_START_SYSCOUNTER + endif # NRF_GRTC_TIMER diff --git a/drivers/timer/nrf_grtc_timer.c b/drivers/timer/nrf_grtc_timer.c index 173d7a031ceb..faecda31b472 100644 --- a/drivers/timer/nrf_grtc_timer.c +++ b/drivers/timer/nrf_grtc_timer.c @@ -462,13 +462,14 @@ static int sys_clock_driver_init(void) #endif #if defined(CONFIG_NRF_GRTC_TIMER_CLOCK_MANAGEMENT) && NRF_GRTC_HAS_CLKSEL -#if defined(CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC) +#if defined(CONFIG_NRF_GRTC_TIMER_SOURCE_LFLPRC) /* Switch to LFPRC as the low-frequency clock source. */ nrfx_grtc_clock_source_set(NRF_GRTC_CLKSEL_LFLPRC); -#elif DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(lfxo)) +#elif defined(CONFIG_NRF_GRTC_TIMER_SOURCE_LFXO) /* Switch to LFXO as the low-frequency clock source. */ nrfx_grtc_clock_source_set(NRF_GRTC_CLKSEL_LFXO); #else + /* Use LFCLK as the low-frequency clock source. */ nrfx_grtc_clock_source_set(NRF_GRTC_CLKSEL_LFCLK); #endif #endif From c4e857c9fd77f278623aee0bf594d4b5d0f30772 Mon Sep 17 00:00:00 2001 From: Anuj Pathak Date: Thu, 12 Jun 2025 13:12:41 +0530 Subject: [PATCH 0282/3659] dts: i2s: add i2s node for max32655fthr - add basic dma only i2s dts binding for max32-i2s - add i2s node with default config to max32655.dtsi - add i2s pin definition for max32655fthr board as per spec Signed-off-by: Anuj Pathak --- .../max32655fthr/max32655fthr_max32655_m4.dts | 6 ++++ dts/arm/adi/max32/max32655.dtsi | 18 +++++++++++ dts/bindings/i2s/adi,max32-i2s.yaml | 30 +++++++++++++++++++ include/zephyr/dt-bindings/dma/max32655_dma.h | 3 +- 4 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 dts/bindings/i2s/adi,max32-i2s.yaml diff --git a/boards/adi/max32655fthr/max32655fthr_max32655_m4.dts b/boards/adi/max32655fthr/max32655fthr_max32655_m4.dts index cfdb83d97944..d5263a8858da 100644 --- a/boards/adi/max32655fthr/max32655fthr_max32655_m4.dts +++ b/boards/adi/max32655fthr/max32655fthr_max32655_m4.dts @@ -155,6 +155,12 @@ status = "okay"; }; +&i2s0 { + status = "okay"; + pinctrl-0 = <&i2s_sck_p1_2 &i2s_ws_p1_3 &i2s_sdi_p1_4 &i2s_sdo_p1_5>; + pinctrl-names = "default"; +}; + &wdt0 { status = "okay"; }; diff --git a/dts/arm/adi/max32/max32655.dtsi b/dts/arm/adi/max32/max32655.dtsi index 1a2a6e51939f..741444964315 100644 --- a/dts/arm/adi/max32/max32655.dtsi +++ b/dts/arm/adi/max32/max32655.dtsi @@ -164,5 +164,23 @@ status = "disabled"; }; }; + + i2s0: i2s0@40060000 { + compatible = "adi,max32-i2s"; + reg = <0x40060000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + /* + * DMA Configuration is provided as an example. + * user is free to change dma channel index, + * but tx and rx slot should be kept same as below + * + * ref to MAX32655 User Guide + * Table 9-2: DMA Source and Destination by Peripheral + */ + dmas = <&dma0 0 MAX32_DMA_SLOT_I2S_TX>, <&dma0 1 MAX32_DMA_SLOT_I2S_RX>; + dma-names = "tx", "rx"; + status = "disabled"; + }; }; }; diff --git a/dts/bindings/i2s/adi,max32-i2s.yaml b/dts/bindings/i2s/adi,max32-i2s.yaml new file mode 100644 index 000000000000..cca93fc29c7b --- /dev/null +++ b/dts/bindings/i2s/adi,max32-i2s.yaml @@ -0,0 +1,30 @@ +# Copyright (c) 2025 Croxel Inc. +# SPDX-License-Identifier: Apache-2.0 + +description: Analog Devices MAX32 series I2S controller + +compatible: "adi,max32-i2s" + +include: [i2s-controller.yaml, pinctrl-device.yaml] + +properties: + reg: + required: true + + dmas: + required: true + description: | + DMA channels for both RX and TX. + + dma-names: + required: true + description: | + Names of DMA channels for both RX and TX. + + i2s-clk-frequency: + type: int + default: 12288000 + description: | + Frequency of the I2S clock in Hz. + This clock is used to derive the bit clock and frame clock. + Default to 12.288 MHz, which is suitable for common audio sample rates. diff --git a/include/zephyr/dt-bindings/dma/max32655_dma.h b/include/zephyr/dt-bindings/dma/max32655_dma.h index bedb4b5ad9d6..1d73ad3ed3f6 100644 --- a/include/zephyr/dt-bindings/dma/max32655_dma.h +++ b/include/zephyr/dt-bindings/dma/max32655_dma.h @@ -18,6 +18,7 @@ #define MAX32_DMA_SLOT_UART2_RX 0x0EU #define MAX32_DMA_SLOT_SPI0_RX 0x0FU #define MAX32_DMA_SLOT_UART3_RX 0x1CU +#define MAX32_DMA_SLOT_I2S_RX 0x1EU #define MAX32_DMA_SLOT_SPI1_TX 0x21U #define MAX32_DMA_SLOT_UART0_TX 0x24U #define MAX32_DMA_SLOT_UART1_TX 0x25U @@ -28,6 +29,6 @@ #define MAX32_DMA_SLOT_UART2_TX 0x2EU #define MAX32_DMA_SLOT_SPI0_TX 0x2FU #define MAX32_DMA_SLOT_UART3_TX 0x3CU -#define MAX32_DMA_SLOT_I2S 0x3EU +#define MAX32_DMA_SLOT_I2S_TX 0x3EU #endif /* ZEPHYR_INCLUDE_DT_BINDINGS_DMA_MAX32655_DMA_H_ */ From 4409ba86550c84951b2d18ae102321b6551f37f2 Mon Sep 17 00:00:00 2001 From: Anuj Pathak Date: Thu, 12 Jun 2025 15:33:08 +0530 Subject: [PATCH 0283/3659] drivers: i2s: add i2s driver for max32 mcu add necessary build files and i2s driver with tx/rx support Signed-off-by: Anuj Pathak --- drivers/i2s/CMakeLists.txt | 1 + drivers/i2s/Kconfig.max32 | 21 + drivers/i2s/i2s_max32.c | 774 +++++++++++++++++++++++++++++++++++++ 3 files changed, 796 insertions(+) create mode 100644 drivers/i2s/Kconfig.max32 create mode 100644 drivers/i2s/i2s_max32.c diff --git a/drivers/i2s/CMakeLists.txt b/drivers/i2s/CMakeLists.txt index f309572eb461..6c28075d06dd 100644 --- a/drivers/i2s/CMakeLists.txt +++ b/drivers/i2s/CMakeLists.txt @@ -10,6 +10,7 @@ zephyr_library_sources(i2s_common.c) zephyr_library_sources_ifdef(CONFIG_I2S_AMBIQ i2s_ambiq.c) zephyr_library_sources_ifdef(CONFIG_I2S_ESP32 i2s_esp32.c) zephyr_library_sources_ifdef(CONFIG_I2S_LITEX i2s_litex.c) +zephyr_library_sources_ifdef(CONFIG_I2S_MAX32 i2s_max32.c) zephyr_library_sources_ifdef(CONFIG_I2S_MCUX_FLEXCOMM i2s_mcux_flexcomm.c) zephyr_library_sources_ifdef(CONFIG_I2S_MCUX_SAI i2s_mcux_sai.c) zephyr_library_sources_ifdef(CONFIG_I2S_NRFX i2s_nrfx.c) diff --git a/drivers/i2s/Kconfig.max32 b/drivers/i2s/Kconfig.max32 new file mode 100644 index 000000000000..112c315ded61 --- /dev/null +++ b/drivers/i2s/Kconfig.max32 @@ -0,0 +1,21 @@ +# Copyright (c) 2025 Croxel Inc. +# SPDX-License-Identifier: Apache-2.0 + +config I2S_MAX32 + bool "Analog Devices MAX32 series I2S driver" + default y + depends on DT_HAS_ADI_MAX32_I2S_ENABLED + select DMA + help + Enable support for Analog Devices MAX32 series I2S driver. + +if I2S_MAX32 + +config I2S_MAX32_QUEUE_SIZE + int "Queue size" + default 8 + help + Size of the Tx/Rx pending block queue. This is the maximum number of + blocks that can be queued for transmission or reception. + +endif # I2S_MAX32 diff --git a/drivers/i2s/i2s_max32.c b/drivers/i2s/i2s_max32.c new file mode 100644 index 000000000000..7425b8eca7b6 --- /dev/null +++ b/drivers/i2s/i2s_max32.c @@ -0,0 +1,774 @@ +/* + * Copyright (c) 2025 Croxel Inc. + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT adi_max32_i2s + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(max32_i2s, CONFIG_I2S_LOG_LEVEL); + +struct i2s_mem_block { + void *block; + size_t size; +}; + +struct i2s_max32_stream_data { + volatile enum i2s_state state; + volatile bool drain; + struct i2s_mem_block cur_block; + struct k_msgq *queue; + struct i2s_config i2s_cfg; +}; + +struct i2s_max32_stream { + struct i2s_max32_stream_data *data; + struct { + mxc_i2s_regs_t *reg; + const struct device *dev; + } i2s; + struct { + const struct device *dev; + uint32_t channel; + uint32_t slot; + } dma; +}; + +struct i2s_max32_cfg { + const struct i2s_max32_stream tx; + const struct i2s_max32_stream rx; + const struct pinctrl_dev_config *pcfg; + const uint32_t i2s_clk_freq; +}; + +/* + * following are the 5 helper apis to handle register configuration while + * making other part of code readable + */ +static inline int mxc_i2s_init(mxc_i2s_req_t *req) +{ + /* + * MXC_I2S_Init internally required at least one data pointer set + * but we don't have any data to send or receive at this point. + * So we set a dummy buffer to satisfy the requirement. + * This buffer will not be used in the transaction. + */ + uint32_t buf0[1] = {0}; + + req->rxData = buf0; + req->length = ARRAY_SIZE(buf0); + + return MXC_I2S_Init(req); +} + +static inline void mxc_i2s_enable_dma_tx(mxc_i2s_regs_t *i2s) +{ + i2s->dmach0 |= MXC_F_I2S_DMACH0_DMA_TX_EN; + i2s->ctrl0ch0 |= MXC_F_I2S_CTRL0CH0_TX_EN; +} + +static inline void mxc_i2s_enable_dma_rx(mxc_i2s_regs_t *i2s) +{ + i2s->dmach0 |= MXC_F_I2S_DMACH0_DMA_RX_EN; + i2s->ctrl0ch0 |= MXC_F_I2S_CTRL0CH0_RX_EN; +} + +static inline void mxc_i2s_set_dma_tx_threshold(mxc_i2s_regs_t *i2s, uint8_t threshold) +{ + i2s->dmach0 &= ~MXC_F_I2S_DMACH0_DMA_TX_THD_VAL; + i2s->dmach0 |= (threshold << MXC_F_I2S_DMACH0_DMA_TX_THD_VAL_POS); +} + +static inline void mxc_i2s_set_dma_rx_threshold(mxc_i2s_regs_t *i2s, uint8_t threshold) +{ + i2s->dmach0 &= ~MXC_F_I2S_DMACH0_DMA_RX_THD_VAL; + i2s->dmach0 |= (threshold << MXC_F_I2S_DMACH0_DMA_RX_THD_VAL_POS); +} + +static void i2s_max32_tx_dma_callback(const struct device *dma_dev, void *arg, uint32_t channel, + int status); + +static void i2s_max32_rx_dma_callback(const struct device *dma_dev, void *arg, uint32_t channel, + int status); + +static inline void free_mem_block(const struct i2s_max32_stream *stream) +{ + struct i2s_max32_stream_data *stream_data = stream->data; + + k_mem_slab_free(stream_data->i2s_cfg.mem_slab, stream_data->cur_block.block); + stream_data->cur_block.block = NULL; +} + +static inline void trigger_stream_stop(const struct i2s_max32_stream *stream, bool drain) +{ + struct i2s_max32_stream_data *stream_data = stream->data; + + LOG_DBG("Stopping stream %p, drain: %d", (void *)stream, drain); + /* signal stopping to handle in the dma callback */ + stream_data->state = I2S_STATE_STOPPING; + /* use to control drain/drop behaviour */ + stream_data->drain = drain; +} + +static inline void clean_stream(const struct i2s_max32_stream *stream) +{ + struct i2s_max32_stream_data *stream_data = stream->data; + struct i2s_mem_block mem_block; + + /* Clear transient block */ + if (stream->data->cur_block.block != NULL) { + k_mem_slab_free(stream_data->i2s_cfg.mem_slab, stream_data->cur_block.block); + stream->data->cur_block.block = NULL; + } + + /* Clear the pending blocks from the queue */ + while (k_msgq_get(stream_data->queue, &mem_block, K_NO_WAIT) == 0) { + k_mem_slab_free(stream_data->i2s_cfg.mem_slab, mem_block.block); + } + + /* mark as ready */ + stream_data->state = I2S_STATE_READY; +} + +static int terminate_stream(const struct i2s_max32_stream *stream) +{ + int ret; + struct i2s_max32_stream_data *stream_data = stream->data; + + if (stream_data->state != I2S_STATE_RUNNING) { + LOG_ERR("Stream not running, state: %d", (int)stream_data->state); + return -EIO; + } + stream_data->state = I2S_STATE_STOPPING; + /* stop dma immediately */ + ret = dma_stop(stream->dma.dev, stream->dma.channel); + if (ret < 0) { + LOG_ERR("Failed to stop DMA channel[%d]: %d", (int)stream->dma.channel, ret); + return ret; + } + /* Clear the queue */ + clean_stream(stream); + return 0; +} + +static inline int start_stream(const struct i2s_max32_stream *stream, enum i2s_dir dir) +{ + int ret; + struct i2s_max32_stream_data *stream_data = stream->data; + struct dma_block_config dma_block; + /* + * For TX destination size and RX source size is always word, + * and thus burst length is always 4, refer to 14.6.4 of MAX32655 user manual + */ + struct dma_config dma_cfg = { + .dma_slot = stream->dma.slot, + .source_data_size = stream_data->i2s_cfg.word_size / 8, + .source_burst_length = 4, + .dest_data_size = stream_data->i2s_cfg.word_size / 8, + .dest_burst_length = 4, + .block_count = 1, + .user_data = (void *)stream, + .head_block = &dma_block, + }; + + if ((dir != I2S_DIR_RX) && (dir != I2S_DIR_TX)) { + LOG_ERR("Invalid I2S direction: %d", (int)dir); + return -EINVAL; + } + + if (stream_data->cur_block.block != NULL) { + LOG_ERR("Stream already running"); + return -EIO; + } + + if (dir == I2S_DIR_RX) { + ret = k_mem_slab_alloc(stream_data->i2s_cfg.mem_slab, &stream_data->cur_block.block, + K_NO_WAIT); + if (ret < 0) { + LOG_ERR("Failed to allocate RX mem block: %d", ret); + return -ENOMEM; + } + + /* set block size manually */ + stream_data->cur_block.size = stream_data->i2s_cfg.mem_slab->info.block_size; + /* Configure DMA Block */ + dma_block.block_size = stream_data->i2s_cfg.mem_slab->info.block_size, + dma_block.source_address = (uint32_t)NULL; + dma_block.source_addr_adj = DMA_ADDR_ADJ_NO_CHANGE; + dma_block.dest_address = (uint32_t)stream_data->cur_block.block; + dma_block.dest_addr_adj = DMA_ADDR_ADJ_INCREMENT; + /* Configure DMA */ + dma_cfg.channel_direction = PERIPHERAL_TO_MEMORY; + dma_cfg.dma_callback = i2s_max32_rx_dma_callback; + dma_cfg.channel_priority = 1; + } else { + ret = k_msgq_get(stream_data->queue, &stream_data->cur_block, K_NO_WAIT); + if (ret < 0) { + LOG_ERR("Failed to get item from TX queue: %d", ret); + return ret; + } + /* Configure DMA Block */ + dma_block.block_size = stream_data->cur_block.size, + dma_block.source_address = (uint32_t)stream_data->cur_block.block; + dma_block.source_addr_adj = DMA_ADDR_ADJ_INCREMENT; + dma_block.dest_address = (uint32_t)NULL; + dma_block.dest_addr_adj = DMA_ADDR_ADJ_NO_CHANGE; + /* Configure DMA */ + dma_cfg.channel_direction = MEMORY_TO_PERIPHERAL; + dma_cfg.dma_callback = i2s_max32_tx_dma_callback; + dma_cfg.channel_priority = 0; + } + + /* Configure DMA channel */ + ret = dma_config(stream->dma.dev, stream->dma.channel, &dma_cfg); + if (ret < 0) { + LOG_ERR("DMA config failed with error: %d", ret); + free_mem_block(stream); + return ret; + } + + /* TX/RX FIFO size is 8 word, thus using 4 words to trigger DMA transfer */ + if (dir == I2S_DIR_RX) { + mxc_i2s_set_dma_rx_threshold(stream->i2s.reg, 4); + mxc_i2s_enable_dma_rx(stream->i2s.reg); + } else { + mxc_i2s_set_dma_tx_threshold(stream->i2s.reg, 4); + mxc_i2s_enable_dma_tx(stream->i2s.reg); + } + + /* Start DMA transfer */ + ret = dma_start(stream->dma.dev, stream->dma.channel); + if (ret < 0) { + LOG_ERR("DMA start failed with error: %d", ret); + free_mem_block(stream); + return ret; + } + + stream_data->state = I2S_STATE_RUNNING; + return 0; +} + +static inline int restart_stream(const struct i2s_max32_stream *stream, enum i2s_dir dir) +{ + int ret; + struct i2s_max32_stream_data *stream_data = stream->data; + + if ((stream_data->state != I2S_STATE_RUNNING) && + (stream_data->state != I2S_STATE_STOPPING)) { + LOG_ERR("Stream not running"); + return -EIO; + } + + if ((dir != I2S_DIR_TX) && (dir != I2S_DIR_RX)) { + LOG_ERR("Invalid I2S direction: %d", (int)dir); + return -ENOTSUP; + } + + if (stream_data->cur_block.block != NULL) { + LOG_ERR("Stream already running"); + return -EIO; + } + + if (dir == I2S_DIR_RX) { + ret = k_mem_slab_alloc(stream_data->i2s_cfg.mem_slab, &stream_data->cur_block.block, + K_NO_WAIT); + if (ret < 0) { + LOG_ERR("Failed to allocate RX mem block: %d", ret); + return -ENOMEM; + } + } else { + ret = k_msgq_get(stream_data->queue, &stream_data->cur_block, K_NO_WAIT); + if (ret < 0) { + LOG_ERR("Failed to get item from TX queue: %d", ret); + return ret; + } + } + + /* + * source address in case of RX and destination address in case of TX is ignored, + * thus it is safe to use same address irrespective of the direction + */ + ret = dma_reload(stream->dma.dev, stream->dma.channel, + (uint32_t)stream_data->cur_block.block, + (uint32_t)stream_data->cur_block.block, stream_data->i2s_cfg.block_size); + if (ret < 0) { + LOG_ERR("Error reloading DMA channel[%d]: %d", (int)stream->dma.channel, ret); + free_mem_block(stream); + return ret; + } + + ret = dma_start(stream->dma.dev, stream->dma.channel); + if (ret < 0) { + LOG_ERR("Error starting DMA channel[%d]: %d", (int)stream->dma.channel, ret); + free_mem_block(stream); + return ret; + } + + return 0; +} + +static void i2s_max32_tx_dma_callback(const struct device *dma_dev, void *arg, uint32_t channel, + int status) +{ + int err; + const struct i2s_max32_stream *stream = (const struct i2s_max32_stream *)arg; + struct i2s_max32_stream_data *stream_data = stream->data; + + if (stream_data->cur_block.block == NULL) { + LOG_ERR("TX DMA callback called with NULL block"); + stream_data->state = I2S_STATE_ERROR; + return; + } + + /* free the block we are working with irrespective of success/fail */ + free_mem_block(stream); + + /* check the status of the DMA transfer */ + if (status < 0) { + LOG_ERR("TX DMA status bad: %d", status); + stream_data->state = I2S_STATE_ERROR; + return; + } + + /* + * if a stop was requested without draining, + * or the queue has drained completely, + * then we can stop the stream + */ + if ((stream_data->state == I2S_STATE_STOPPING) && + ((stream_data->drain == false) || (k_msgq_num_used_get(stream_data->queue) == 0))) { + stream_data->state = I2S_STATE_READY; + return; + } + + err = restart_stream(stream, I2S_DIR_TX); + if (err < 0) { + LOG_ERR("Failed to restart TX transfer: %d", err); + stream_data->state = I2S_STATE_ERROR; + } +} + +static void i2s_max32_rx_dma_callback(const struct device *dma_dev, void *arg, uint32_t channel, + int status) +{ + int err; + const struct i2s_max32_stream *stream = (const struct i2s_max32_stream *)arg; + struct i2s_max32_stream_data *stream_data = stream->data; + + if (stream_data->cur_block.block == NULL) { + LOG_ERR("RX DMA callback called with NULL block"); + stream_data->state = I2S_STATE_ERROR; + return; + } + + if (status < 0) { + LOG_ERR("RX DMA status bad: %d", status); + stream_data->state = I2S_STATE_ERROR; + return; + } + + /* we have completely received the block, push to queue to let user handle and free it*/ + err = k_msgq_put(stream_data->queue, &stream_data->cur_block, K_NO_WAIT); + if (err < 0) { + LOG_ERR("Failed to put item to RX queue: %d", err); + free_mem_block(stream); + stream_data->state = I2S_STATE_ERROR; + return; + } + + /* remove reference and let user free it when done */ + stream_data->cur_block.block = NULL; + + if (stream_data->state == I2S_STATE_STOPPING) { + stream_data->state = I2S_STATE_READY; + return; + } + + err = restart_stream(stream, I2S_DIR_RX); + if (err < 0) { + LOG_ERR("Failed to restart RX transfer: %d", err); + stream_data->state = I2S_STATE_ERROR; + } +} + +static int i2s_max32_trigger_single(const struct device *dev, enum i2s_dir dir, + enum i2s_trigger_cmd cmd, const struct i2s_max32_stream *stream) +{ + struct i2s_max32_stream_data *stream_data = stream->data; + + switch (cmd) { + case I2S_TRIGGER_START: + if (stream_data->state != I2S_STATE_READY) { + LOG_ERR("START - Invalid state: %d", (int)stream_data->state); + return -EIO; + } + return start_stream(stream, dir); + + case I2S_TRIGGER_STOP: + if (stream_data->state != I2S_STATE_RUNNING) { + LOG_ERR("STOP - Invalid state: %d", (int)stream_data->state); + return -EIO; + } + trigger_stream_stop(stream, false); + return 0; + case I2S_TRIGGER_DRAIN: + if (stream_data->state != I2S_STATE_RUNNING) { + LOG_ERR("DRAIN - Invalid state: %d", (int)stream_data->state); + return -EIO; + } + trigger_stream_stop(stream, true); + return 0; + case I2S_TRIGGER_DROP: + if (stream_data->state == I2S_STATE_NOT_READY) { + LOG_ERR("DROP - Invalid state: %d", (int)stream_data->state); + return -EIO; + } + return terminate_stream(stream); + case I2S_TRIGGER_PREPARE: + if (stream_data->state != I2S_STATE_ERROR) { + LOG_ERR("PREPARE - Invalid state: %d", (int)stream_data->state); + return -EIO; + } + clean_stream(stream); + return 0; + default: + return -ENOTSUP; + } +} + +static int i2s_max32_trigger(const struct device *dev, enum i2s_dir dir, enum i2s_trigger_cmd cmd) +{ + int ret; + const struct i2s_max32_cfg *cfg = dev->config; + + LOG_DBG("trigger with dir=%d, cmd=%d", (int)dir, (int)cmd); + + switch (dir) { + case I2S_DIR_TX: + return i2s_max32_trigger_single(dev, dir, cmd, &cfg->tx); + case I2S_DIR_RX: + return i2s_max32_trigger_single(dev, dir, cmd, &cfg->rx); + case I2S_DIR_BOTH: + /* + * If user requests both TX and RX trigger, we trigger them one by one here. + * Failing to trigger any stream will result in an error. + * This could mean one has been trigger successfully and the other has failed. + * This is not an error condition, as the user can choose to trigger only one + * stream at a time. + */ + + ret = i2s_max32_trigger_single(dev, I2S_DIR_TX, cmd, &cfg->tx); + if (ret < 0) { + return ret; + } + + ret = i2s_max32_trigger_single(dev, I2S_DIR_RX, cmd, &cfg->rx); + if (ret < 0) { + return ret; + } + + return 0; + default: + LOG_ERR("Invalid I2S direction: %d", (int)dir); + return -EINVAL; + } +} + +static int i2s_cfg_to_max32_cfg(const struct i2s_config *i2s_cfg, mxc_i2s_req_t *max_cfg, + uint32_t i2s_clk_freq) +{ + /* Input validation */ + __ASSERT(i2s_cfg != NULL, "i2s_cfg cannot be NULL"); + __ASSERT(max_cfg != NULL, "max_cfg cannot be NULL"); + + /* Clear configuration struct */ + memset(max_cfg, 0, sizeof(mxc_i2s_req_t)); + + /* Validate word size */ + switch (i2s_cfg->word_size) { + case 8: + max_cfg->wordSize = MXC_I2S_WSIZE_BYTE; + max_cfg->sampleSize = MXC_I2S_SAMPLESIZE_EIGHT; + break; + case 16: + max_cfg->wordSize = MXC_I2S_WSIZE_HALFWORD; + max_cfg->sampleSize = MXC_I2S_SAMPLESIZE_SIXTEEN; + break; + case 32: + max_cfg->wordSize = MXC_I2S_WSIZE_WORD; + max_cfg->sampleSize = MXC_I2S_SAMPLESIZE_THIRTYTWO; + break; + default: + LOG_ERR("Unsupported word size: %u", i2s_cfg->word_size); + return -EINVAL; + } + + /* Validate channels */ + if (i2s_cfg->channels == 2) { + max_cfg->stereoMode = MXC_I2S_STEREO; + } else if (i2s_cfg->channels == 1) { + max_cfg->stereoMode = MXC_I2S_MONO_RIGHT_CH; + } else { + LOG_ERR("Unsupported number of channels: %u", i2s_cfg->channels); + return -EINVAL; + } + + /* Validate format */ + switch (i2s_cfg->format & I2S_FMT_DATA_FORMAT_MASK) { + case I2S_FMT_DATA_FORMAT_I2S: + case I2S_FMT_DATA_FORMAT_LEFT_JUSTIFIED: + max_cfg->justify = MXC_I2S_LSB_JUSTIFY; + break; + case I2S_FMT_DATA_FORMAT_RIGHT_JUSTIFIED: + max_cfg->justify = MXC_I2S_MSB_JUSTIFY; + break; + default: + LOG_ERR("Unsupported data format: 0x%02x", i2s_cfg->format); + return -EINVAL; + } + + /* Check unsupported format options */ + if (i2s_cfg->format & + (I2S_FMT_DATA_ORDER_LSB | I2S_FMT_BIT_CLK_INV | I2S_FMT_FRAME_CLK_INV)) { + LOG_ERR("Unsupported format options: 0x%02x", i2s_cfg->format); + return -EINVAL; + } + + /* Set master/slave mode */ + if (i2s_cfg->options & I2S_OPT_FRAME_CLK_SLAVE) { + max_cfg->channelMode = MXC_I2S_EXTERNAL_SCK_EXTERNAL_WS; + } else { + max_cfg->channelMode = MXC_I2S_INTERNAL_SCK_WS_0; + } + + /* Check unsupported options */ + if (i2s_cfg->options & (I2S_OPT_LOOPBACK | I2S_OPT_PINGPONG)) { + LOG_ERR("Unsupported options: 0x%02x", i2s_cfg->options); + return -EINVAL; + } + + /* Set standard values */ + max_cfg->bitOrder = MXC_I2S_LSB_FIRST; + max_cfg->wsPolarity = MXC_I2S_POL_NORMAL; + max_cfg->bitsWord = i2s_cfg->word_size; + max_cfg->adjust = MXC_I2S_ADJUST_LEFT; + + /* Calculate clock divider for sample rate */ + max_cfg->clkdiv = Wrap_MXC_I2S_CalculateClockDiv(i2s_cfg->frame_clk_freq, max_cfg->wordSize, + i2s_clk_freq); + if (max_cfg->clkdiv < 0) { + LOG_ERR("Invalid frame clock frequency: %u", i2s_cfg->frame_clk_freq); + return -EINVAL; + } + + return 0; +} + +static int i2s_max32_configure_single(const struct device *dev, enum i2s_dir dir, + const struct i2s_config *i2s_cfg, + const struct i2s_max32_stream *stream) +{ + int ret; + struct i2s_max32_stream_data *stream_data = stream->data; + const struct i2s_max32_cfg *config = dev->config; + mxc_i2s_req_t mxc_cfg; + + if ((stream_data->state != I2S_STATE_NOT_READY) && + (stream_data->state != I2S_STATE_READY)) { + LOG_ERR("Invalid state: %d", (int)stream_data->state); + return -EINVAL; + } + + if (i2s_cfg->frame_clk_freq == 0) { + terminate_stream(stream); + return 0; + } + + ret = i2s_cfg_to_max32_cfg(i2s_cfg, &mxc_cfg, config->i2s_clk_freq); + if (ret < 0) { + LOG_ERR("Failed to convert I2S config to MAX32 config"); + return ret; + } + + ret = mxc_i2s_init(&mxc_cfg); + if (ret < 0) { + LOG_ERR("Failed to initialize I2S: %d", ret); + return -EINVAL; + } + + stream_data->i2s_cfg = *i2s_cfg; + stream_data->state = I2S_STATE_READY; + return 0; +} + +static int i2s_max32_configure(const struct device *dev, enum i2s_dir dir, + const struct i2s_config *i2s_cfg) +{ + int ret; + const struct i2s_max32_cfg *cfg = dev->config; + + LOG_DBG("configure with dir=%d, word_size=%u, channels=%u, frame_clk_freq=%u", (int)dir, + i2s_cfg->word_size, i2s_cfg->channels, i2s_cfg->frame_clk_freq); + + switch (dir) { + case I2S_DIR_TX: + return i2s_max32_configure_single(dev, dir, i2s_cfg, &cfg->tx); + case I2S_DIR_RX: + return i2s_max32_configure_single(dev, dir, i2s_cfg, &cfg->rx); + case I2S_DIR_BOTH: + /* + * If user requests both TX and RX configuration, we can configure both streams + * with the same configuration. This is useful for full-duplex operation. + * Failing to configure any stream will result in an error. + * This could mean one has been configured successfully and the other has failed. + * This is not an error condition, as the user can choose to configure only one + * stream at a time. + */ + ret = i2s_max32_configure_single(dev, I2S_DIR_TX, i2s_cfg, &cfg->tx); + if (ret < 0) { + return ret; + } + + ret = i2s_max32_configure_single(dev, I2S_DIR_RX, i2s_cfg, &cfg->rx); + if (ret < 0) { + return ret; + } + return 0; + default: + LOG_ERR("Invalid I2S direction: %d", (int)dir); + return -EINVAL; + } +} + +static int i2s_max32_read(const struct device *dev, void **mem_block, size_t *size) +{ + int err; + const struct i2s_max32_cfg *cfg = dev->config; + const struct i2s_max32_stream *stream = &cfg->rx; + struct i2s_max32_stream_data *stream_data = stream->data; + struct i2s_mem_block block; + + if (stream_data->state == I2S_STATE_NOT_READY) { + LOG_ERR("RX invalid state: %d", (int)stream_data->state); + return -EIO; + } else if (stream_data->state == I2S_STATE_ERROR && + k_msgq_num_used_get(stream_data->queue) == 0) { + LOG_ERR("RX queue empty"); + return -EIO; + } + + err = k_msgq_get(stream_data->queue, &block, K_MSEC(stream_data->i2s_cfg.timeout)); + if (err < 0) { + LOG_ERR("RX queue empty"); + return err; + } + + *mem_block = block.block; + *size = block.size; + + return 0; +} + +static int i2s_max32_write(const struct device *dev, void *mem_block, size_t size) +{ + int err; + const struct i2s_max32_cfg *cfg = dev->config; + const struct i2s_max32_stream *stream = &cfg->tx; + struct i2s_max32_stream_data *stream_data = stream->data; + struct i2s_mem_block block = {.block = mem_block, .size = size}; + + if (stream_data->state != I2S_STATE_READY && stream_data->state != I2S_STATE_RUNNING) { + LOG_ERR("TX Invalid state: %d", (int)stream_data->state); + return -EIO; + } + + if (size > stream_data->i2s_cfg.block_size) { + LOG_ERR("Max write size is: %u", (unsigned int)stream_data->i2s_cfg.block_size); + return -EINVAL; + } + + err = k_msgq_put(stream_data->queue, &block, K_MSEC(stream_data->i2s_cfg.timeout)); + if (err < 0) { + LOG_ERR("TX queue full"); + return err; + } + + return 0; +} + +static DEVICE_API(i2s, i2s_max32_driver_api) = { + .read = i2s_max32_read, + .write = i2s_max32_write, + .configure = i2s_max32_configure, + .trigger = i2s_max32_trigger, +}; + +static int i2s_max32_init(const struct device *dev) +{ + const struct i2s_max32_cfg *config = dev->config; + int err; + + err = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT); + if (err < 0) { + return err; + } + + return 0; +} + +#define MAX32_DT_INST_DMA_CTLR(n, name) DEVICE_DT_GET(DT_INST_DMAS_CTLR_BY_NAME(n, name)) + +#define MAX32_DT_INST_DMA_CELL(n, name, cell) DT_INST_DMAS_CELL_BY_NAME(n, name, cell) + +#define I2S_MAX32_STREAM_DATA_CREATE_AND_INIT(n, dir) \ + K_MSGQ_DEFINE(i2s_max32_##dir##_q_##n, sizeof(struct i2s_mem_block), \ + CONFIG_I2S_MAX32_QUEUE_SIZE, 1); \ + static struct i2s_max32_stream_data i2s_max32_##dir##_data_##n = { \ + .state = I2S_STATE_NOT_READY, \ + .drain = false, \ + .queue = &i2s_max32_##dir##_q_##n, \ + }; + +#define I2S_MAX32_STREAM_INIT(n, dir) \ + { \ + .data = &i2s_max32_##dir##_data_##n, \ + .i2s = \ + { \ + .reg = (mxc_i2s_regs_t *)DT_INST_REG_ADDR(n), \ + .dev = DEVICE_DT_INST_GET(n), \ + }, \ + .dma = \ + { \ + .dev = MAX32_DT_INST_DMA_CTLR(n, dir), \ + .channel = MAX32_DT_INST_DMA_CELL(n, dir, channel), \ + .slot = MAX32_DT_INST_DMA_CELL(n, dir, slot), \ + }, \ + } + +#define I2S_MAX32_INIT(n) \ + PINCTRL_DT_DEFINE(DT_DRV_INST(n)); \ + \ + I2S_MAX32_STREAM_DATA_CREATE_AND_INIT(n, tx); \ + I2S_MAX32_STREAM_DATA_CREATE_AND_INIT(n, rx); \ + \ + static const struct i2s_max32_cfg i2s_max32_cfg_##n = { \ + .tx = I2S_MAX32_STREAM_INIT(n, tx), \ + .rx = I2S_MAX32_STREAM_INIT(n, rx), \ + .pcfg = PINCTRL_DT_DEV_CONFIG_GET(DT_DRV_INST(n)), \ + .i2s_clk_freq = DT_INST_PROP(n, i2s_clk_frequency), \ + }; \ + DEVICE_DT_INST_DEFINE(n, i2s_max32_init, NULL, NULL, &i2s_max32_cfg_##n, POST_KERNEL, \ + CONFIG_I2S_INIT_PRIORITY, &i2s_max32_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(I2S_MAX32_INIT) From 68b23bab289b7ec854564f296485c4d584403acf Mon Sep 17 00:00:00 2001 From: Anuj Pathak Date: Thu, 12 Jun 2025 15:34:56 +0530 Subject: [PATCH 0284/3659] boards: max32655fthr: enable i2c1 MAX32655 uses I2C1 to control on board PMIC and Audio Codec this commit enable it as per board spec Signed-off-by: Anuj Pathak --- boards/adi/max32655fthr/max32655fthr_max32655_m4.dts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/boards/adi/max32655fthr/max32655fthr_max32655_m4.dts b/boards/adi/max32655fthr/max32655fthr_max32655_m4.dts index d5263a8858da..cdcfd1849387 100644 --- a/boards/adi/max32655fthr/max32655fthr_max32655_m4.dts +++ b/boards/adi/max32655fthr/max32655fthr_max32655_m4.dts @@ -145,6 +145,12 @@ status = "okay"; }; +&i2c1 { + status = "okay"; + pinctrl-0 = <&i2c1_scl_p0_16 &i2c1_sda_p0_17>; + pinctrl-names = "default"; +}; + &i2c2 { status = "okay"; pinctrl-0 = <&i2c2_scl_p0_30 &i2c2_sda_p0_31>; From c0b013d2d48665dab3ca8eac7cb5b32874f59066 Mon Sep 17 00:00:00 2001 From: Anuj Pathak Date: Thu, 12 Jun 2025 17:04:01 +0530 Subject: [PATCH 0285/3659] samples: drivers: i2s: echo: Add MAX9867 codec support Add MAX9867 codec initialization support to the sample to later use for MAX32655FTHR support Signed-off-by: Anuj Pathak --- samples/drivers/i2s/echo/Kconfig | 4 +- .../i2s/echo/dts/bindings/adi,max9867.yaml | 13 ++ samples/drivers/i2s/echo/src/codec.c | 188 ++++++++++++++++++ samples/drivers/i2s/echo/src/codec.h | 6 + samples/drivers/i2s/echo/src/main.c | 6 + 5 files changed, 216 insertions(+), 1 deletion(-) create mode 100644 samples/drivers/i2s/echo/dts/bindings/adi,max9867.yaml diff --git a/samples/drivers/i2s/echo/Kconfig b/samples/drivers/i2s/echo/Kconfig index 623e2ae6318a..803f31750d26 100644 --- a/samples/drivers/i2s/echo/Kconfig +++ b/samples/drivers/i2s/echo/Kconfig @@ -1,10 +1,12 @@ # Copyright (c) 2021 Nordic Semiconductor ASA +# Copyright (c) 2025 Croxel Inc. # SPDX-License-Identifier: Apache-2.0 source "Kconfig.zephyr" config I2C - default $(dt_compat_on_bus,$(DT_COMPAT_WOLFSON_WM8731),i2c) + default $(dt_compat_on_bus,$(DT_COMPAT_WOLFSON_WM8731),i2c) \ + || $(dt_compat_on_bus,$(DT_COMPAT_ADI_MAX9867),i2c) config TOGGLE_ECHO_EFFECT_SW0 bool "Toggle echo effect when pressing sw0" diff --git a/samples/drivers/i2s/echo/dts/bindings/adi,max9867.yaml b/samples/drivers/i2s/echo/dts/bindings/adi,max9867.yaml new file mode 100644 index 000000000000..7e656aa21d55 --- /dev/null +++ b/samples/drivers/i2s/echo/dts/bindings/adi,max9867.yaml @@ -0,0 +1,13 @@ +# Copyright (c) 2021 Nordic Semiconductor ASA +# Copyright (c) 2025 Croxel Inc. +# SPDX-License-Identifier: Apache-2.0 + +# This binding has been added solely for the purpose of the overlay files used +# in the drivers/i2s/output sample. That's why it is located in this sample source +# directory. It can be moved and made available more widely if the need arises. + +description: MAX9867 Audio CODEC + +compatible: "adi,max9867" + +include: i2c-device.yaml diff --git a/samples/drivers/i2s/echo/src/codec.c b/samples/drivers/i2s/echo/src/codec.c index bcbf8ac7c04a..c1b2c6386b35 100644 --- a/samples/drivers/i2s/echo/src/codec.c +++ b/samples/drivers/i2s/echo/src/codec.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2021 Nordic Semiconductor ASA + * Copyright (c) 2025 Croxel Inc * * SPDX-License-Identifier: Apache-2.0 */ @@ -123,3 +124,190 @@ bool init_wm8731_i2c(void) } #endif /* DT_ON_BUS(WM8731_NODE, i2c) */ + +#if DT_ON_BUS(MAX9867_NODE, i2c) + +#define MAX9867_I2C_NODE DT_BUS(MAX9867_NODE) +#define MAX9867_I2C_ADDR DT_REG_ADDR(MAX9867_NODE) +/* Register addresses */ +#define MAX9867_00_STATUS 0x00 +#define MAX9867_01_JACKSENSE 0x01 +#define MAX9867_02_AUX_HIGH 0x02 +#define MAX9867_03_AUX_LOW 0x03 +#define MAX9867_04_INT_EN 0x04 +#define MAX9867_05_SYS_CLK 0x05 +#define MAX9867_06_CLK_HIGH 0x06 +#define MAX9867_07_CLK_LOW 0x07 +#define MAX9867_08_DAI_FORMAT 0x08 +#define MAX9867_09_DAI_CLOCK 0x09 +#define MAX9867_0A_DIG_FILTER 0x0A +#define MAX9867_0B_SIDETONE 0x0B +#define MAX9867_0C_LVL_DAC 0x0C +#define MAX9867_0D_LVL_ADC 0x0D +#define MAX9867_0E_LVL_LINE_IN_LEFT 0x0E +#define MAX9867_0F_LVL_LINE_IN_RIGHT 0x0F +#define MAX9867_10_VOL_LEFT 0x10 +#define MAX9867_11_VOL_RIGHT 0x11 +#define MAX9867_12_MIC_GAIN_LEFT 0x12 +#define MAX9867_13_MIC_GAIN_RIGHT 0x13 +#define MAX9867_14_ADC_INPUT 0x14 +#define MAX9867_15_MIC 0x15 +#define MAX9867_16_MODE 0x16 +#define MAX9867_17_PWR_SYS 0x17 +#define MAX9867_FF_REV_ID 0xFF + +/* MAX9867_04_INT_EN */ +#define MAX9867_ICLD (1 << 7) +#define MAX9867_SDODLY (1 << 2) + +/* MAX9867_05_SYS_CLK */ +#define MAX9867_PSCLK_POS 4 + +/* MAX9867_06_CLK_HIGH */ +#define MAX9867_PLL (1 << 7) +#define MAX9867_NI_UPPER_8KHZ 0x10 +#define MAX9867_NI_UPPER_16KHZ 0x20 +#define MAX9867_NI_UPPER_24KHZ 0x30 +#define MAX9867_NI_UPPER_32KHZ 0x40 +#define MAX9867_NI_UPPER_44p1KHZ 0x58 +#define MAX9867_NI_UPPER_48KHZ 0x60 + +/* MAX9867_07_CLK_LOW */ +#define MAX9867_NI_LOWER_OTHER 0x00 +#define MAX9867_NI_LOWER_44p1KHZ 0x33 + +/* MAX9867_08_DAI_FORMAT */ +#define MAX9867_MAS (1 << 7) +#define MAX9867_WCI (1 << 6) +#define MAX9867_BCI (1 << 5) +#define MAX9867_DLY (1 << 4) +#define MAX9867_HIZOFF (1 << 3) +#define MAX9867_TDM (1 << 2) + +/* MAX9867_09_DAI_CLOCK */ +#define MAX9867_BSEL_PCLK_DIV8 0x06 + +/* MAX9867_0D_LVL_ADC */ +#define MAX9867_AVL_POS 4 +#define MAX9867_AVR_POS 0 + +/* + * MAX9867_0E_LVL_LINE_IN_LEFT + * MAX9867_0F_LVL_LINE_IN_RIGHT + */ +#define MAX9867_LI_MUTE (1 << 6) +#define MAX9867_LI_GAIN_POS 0 + +/* + * MAX9867_10_VOL_LEFT + * MAX9867_11_VOL_RIGHT + */ +#define MAX9867_VOL_POS 0 + +/* MAX9867_14_ADC_INPUT */ +#define MAX9867_MXINL_POS 6 +#define MAX9867_MXINR_POS 4 +#define MAX9867_MXIN_DIS 0 +#define MAX9867_MXIN_ANALOG_MIC 1 +#define MAX9867_MXIN_LINE 2 + +/* MAX9867_15_MIC */ +#define MAX9867_MICCLK_POS 6 +#define MAX9867_DIGMICL_POS 5 +#define MAX9867_DIGMICR_POS 4 + +/* MAX9867_16_MODE */ +#define MAX9867_HPMODE_POS 0 +#define MAX9867_STEREO_SE_CLICKLESS 4 +#define MAX9867_MONO_SE_CLICKLESS 5 + +/* MAX9867_17_PWR_SYS */ +#define MAX9867_SHDN (1 << 7) +#define MAX9867_LNLEN (1 << 6) +#define MAX9867_LNREN (1 << 5) +#define MAX9867_DALEN (1 << 3) +#define MAX9867_DAREN (1 << 2) +#define MAX9867_ADLEN (1 << 1) +#define MAX9867_ADREN (1 << 0) + +bool init_max9867_i2c(void) +{ + const struct device *const i2c_dev = DEVICE_DT_GET(MAX9867_I2C_NODE); + + /* Initialization data for MAX9867 registers. */ + static const uint8_t init[][2] = { + /* Shutdown MAX9867 during configuration */ + {MAX9867_17_PWR_SYS, 0x00}, + /* + * Clear all regs to POR state. The MAX9867 does not not have an external + * reset signal. So manually writing 0, from (0x04 - 0x17) + */ + {MAX9867_04_INT_EN, 0x00}, + {MAX9867_05_SYS_CLK, 0x00}, + {MAX9867_06_CLK_HIGH, 0x00}, + {MAX9867_07_CLK_LOW, 0x00}, + {MAX9867_08_DAI_FORMAT, 0x00}, + {MAX9867_09_DAI_CLOCK, 0x00}, + {MAX9867_0A_DIG_FILTER, 0x00}, + {MAX9867_0B_SIDETONE, 0x00}, + {MAX9867_0C_LVL_DAC, 0x00}, + {MAX9867_0D_LVL_ADC, 0x00}, + {MAX9867_0E_LVL_LINE_IN_LEFT, 0x00}, + {MAX9867_0F_LVL_LINE_IN_RIGHT, 0x00}, + {MAX9867_10_VOL_LEFT, 0x00}, + {MAX9867_11_VOL_RIGHT, 0x00}, + {MAX9867_12_MIC_GAIN_LEFT, 0x00}, + {MAX9867_13_MIC_GAIN_RIGHT, 0x00}, + {MAX9867_14_ADC_INPUT, 0x00}, + {MAX9867_15_MIC, 0x00}, + {MAX9867_16_MODE, 0x00}, + {MAX9867_17_PWR_SYS, 0x00}, + /* + * Select MCLK prescaler. PSCLK divides MCLK to generate a PCLK between 10MHz and + * 20MHz. Set prescaler, FREQ field is 0 for Normal or PLL mode, < 20MHz. + */ + {MAX9867_05_SYS_CLK, 0x01 << MAX9867_PSCLK_POS}, + /* Configure codec to generate 48kHz sampling frequency in master mode */ + {MAX9867_06_CLK_HIGH, MAX9867_NI_UPPER_44p1KHZ}, + {MAX9867_07_CLK_LOW, MAX9867_NI_LOWER_44p1KHZ}, + {MAX9867_09_DAI_CLOCK, MAX9867_BSEL_PCLK_DIV8}, + /* I2S format */ + {MAX9867_08_DAI_FORMAT, MAX9867_MAS | MAX9867_DLY | MAX9867_HIZOFF}, + /* */ + {MAX9867_0A_DIG_FILTER, 0xA2}, + /* Select Digital microphone input */ + {MAX9867_15_MIC, ((0x1 << MAX9867_DIGMICR_POS))}, + /* ADC level */ + {MAX9867_0D_LVL_ADC, (3 << MAX9867_AVL_POS) | (3 << MAX9867_AVR_POS)}, + /*Set line-in level, disconnect line input from playback amplifiers */ + {MAX9867_0E_LVL_LINE_IN_LEFT, (0x0C << MAX9867_LI_GAIN_POS) | MAX9867_LI_MUTE}, + {MAX9867_0F_LVL_LINE_IN_RIGHT, (0x0C << MAX9867_LI_GAIN_POS) | MAX9867_LI_MUTE}, + /* Headphone mode */ + {MAX9867_16_MODE, MAX9867_STEREO_SE_CLICKLESS << MAX9867_HPMODE_POS}, + /* Set playback volume */ + {MAX9867_10_VOL_LEFT, 0x04 << MAX9867_VOL_POS}, + {MAX9867_11_VOL_RIGHT, 0x04 << MAX9867_VOL_POS}, + /* Enable */ + {MAX9867_17_PWR_SYS, MAX9867_SHDN | MAX9867_DALEN | MAX9867_DAREN | MAX9867_ADLEN}, + }; + + if (!device_is_ready(i2c_dev)) { + printk("%s is not ready\n", i2c_dev->name); + return false; + } + + for (int i = 0; i < ARRAY_SIZE(init); ++i) { + const uint8_t *entry = init[i]; + int ret; + + ret = i2c_reg_write_byte(i2c_dev, MAX9867_I2C_ADDR, entry[0], entry[1]); + if (ret < 0) { + printk("Initialization step %d failed with %d\n", i, ret); + return false; + } + } + + return true; +} + +#endif /* DT_ON_BUS(MAX9867_NODE, i2c) */ diff --git a/samples/drivers/i2s/echo/src/codec.h b/samples/drivers/i2s/echo/src/codec.h index 38d629c5d2f7..3daf6ae16115 100644 --- a/samples/drivers/i2s/echo/src/codec.h +++ b/samples/drivers/i2s/echo/src/codec.h @@ -1,11 +1,17 @@ /* * Copyright (c) 2021 Nordic Semiconductor ASA + * Copyright (c) 2025 Croxel Inc * * SPDX-License-Identifier: Apache-2.0 */ #define WM8731_NODE DT_NODELABEL(wm8731) +#define MAX9867_NODE DT_NODELABEL(max9867) #if DT_ON_BUS(WM8731_NODE, i2c) bool init_wm8731_i2c(void); #endif + +#if DT_ON_BUS(MAX9867_NODE, i2c) +bool init_max9867_i2c(void); +#endif diff --git a/samples/drivers/i2s/echo/src/main.c b/samples/drivers/i2s/echo/src/main.c index c03b2ad4c817..52f7eb662f25 100644 --- a/samples/drivers/i2s/echo/src/main.c +++ b/samples/drivers/i2s/echo/src/main.c @@ -275,6 +275,12 @@ int main(void) k_msleep(1000); #endif +#if DT_ON_BUS(MAX9867_NODE, i2c) + if (!init_max9867_i2c()) { + return 0; + } +#endif + if (!init_buttons()) { return 0; } From cb2109e7d9241922f5e534f98e4f083caf4471e2 Mon Sep 17 00:00:00 2001 From: Anuj Pathak Date: Mon, 13 Oct 2025 17:21:45 +0530 Subject: [PATCH 0286/3659] samples: drivers: i2s: echo: add MAX32655 support - reduced block length from 100ms to 33.33ms to compile for low ram - add compile time conditional option to slave mode - add overlay file for max32655fthr Signed-off-by: Anuj Pathak --- .../boards/max32655fthr_max32655_m4.overlay | 16 ++++++++++++++++ samples/drivers/i2s/echo/src/main.c | 19 +++++++++++++++++-- 2 files changed, 33 insertions(+), 2 deletions(-) create mode 100644 samples/drivers/i2s/echo/boards/max32655fthr_max32655_m4.overlay diff --git a/samples/drivers/i2s/echo/boards/max32655fthr_max32655_m4.overlay b/samples/drivers/i2s/echo/boards/max32655fthr_max32655_m4.overlay new file mode 100644 index 000000000000..34fab6d44de1 --- /dev/null +++ b/samples/drivers/i2s/echo/boards/max32655fthr_max32655_m4.overlay @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025 Croxel Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +i2s_rxtx: &i2s0 { + status = "okay"; +}; + +&i2c1 { + max9867: max9867@18 { + compatible = "adi,max9867"; + reg = <0x18>; + }; +}; diff --git a/samples/drivers/i2s/echo/src/main.c b/samples/drivers/i2s/echo/src/main.c index 52f7eb662f25..cf861240b56c 100644 --- a/samples/drivers/i2s/echo/src/main.c +++ b/samples/drivers/i2s/echo/src/main.c @@ -21,12 +21,19 @@ #define I2S_TX_NODE DT_NODELABEL(i2s_tx) #endif +/* Reduce echo delay when running on low ram devices */ +#if CONFIG_SRAM_SIZE <= 48 +#define ECHO_DELAY 30 +#else +#define ECHO_DELAY 10 +#endif + #define SAMPLE_FREQUENCY 44100 #define SAMPLE_BIT_WIDTH 16 #define BYTES_PER_SAMPLE sizeof(int16_t) #define NUMBER_OF_CHANNELS 2 -/* Such block length provides an echo with the delay of 100 ms. */ -#define SAMPLES_PER_BLOCK ((SAMPLE_FREQUENCY / 10) * NUMBER_OF_CHANNELS) +/* Such block length provides an echo with the delay of 100ms or 33.33ms */ +#define SAMPLES_PER_BLOCK ((SAMPLE_FREQUENCY / ECHO_DELAY) * NUMBER_OF_CHANNELS) #define INITIAL_BLOCKS 2 #define TIMEOUT 1000 @@ -298,7 +305,15 @@ int main(void) config.word_size = SAMPLE_BIT_WIDTH; config.channels = NUMBER_OF_CHANNELS; config.format = I2S_FMT_DATA_FORMAT_I2S; + /* + * On MAX32655FTHR, MAX9867 MCLK is connected to external 12.2880 crystal + * thus using slave mode + */ +#if CONFIG_BOARD_MAX32655FTHR_MAX32655_M4 + config.options = I2S_OPT_BIT_CLK_SLAVE | I2S_OPT_FRAME_CLK_SLAVE; +#else config.options = I2S_OPT_BIT_CLK_MASTER | I2S_OPT_FRAME_CLK_MASTER; +#endif config.frame_clk_freq = SAMPLE_FREQUENCY; config.mem_slab = &mem_slab; config.block_size = BLOCK_SIZE; From d904d11a224404877b56dac2bc5651c37fb7c82b Mon Sep 17 00:00:00 2001 From: Gaetan Perrot Date: Fri, 12 Dec 2025 13:16:57 +0900 Subject: [PATCH 0287/3659] tests: Fix typo in "Unsupported configuration" error message Several test sources used the misspelled string "Unsupported configuraiton". Fix the typo across all affected files to improve clarity and consistency. Updated files: - tests/boards/nrf/rram_throttling/src/main.c - tests/drivers/flash/common/src/main.c - tests/drivers/flash/negative_tests/src/main.c No functional change. Signed-off-by: Gaetan Perrot --- tests/boards/nrf/rram_throttling/src/main.c | 2 +- tests/drivers/flash/common/src/main.c | 2 +- tests/drivers/flash/negative_tests/src/main.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/boards/nrf/rram_throttling/src/main.c b/tests/boards/nrf/rram_throttling/src/main.c index 341ffadc5f2e..9984f26787d0 100644 --- a/tests/boards/nrf/rram_throttling/src/main.c +++ b/tests/boards/nrf/rram_throttling/src/main.c @@ -20,7 +20,7 @@ #define TEST_AREA_SIZE FIXED_PARTITION_SIZE(TEST_AREA) #define TEST_AREA_DEVICE FIXED_PARTITION_DEVICE(TEST_AREA) #else -#error "Unsupported configuraiton" +#error "Unsupported configuration" #endif #define BUF_SIZE 512 diff --git a/tests/drivers/flash/common/src/main.c b/tests/drivers/flash/common/src/main.c index 0bc7a7adda36..9c176f47d2a8 100644 --- a/tests/drivers/flash/common/src/main.c +++ b/tests/drivers/flash/common/src/main.c @@ -61,7 +61,7 @@ #endif #else -#error "Unsupported configuraiton" +#error "Unsupported configuration" #endif #define EXPECTED_SIZE 512 diff --git a/tests/drivers/flash/negative_tests/src/main.c b/tests/drivers/flash/negative_tests/src/main.c index 723056f817ce..890f4c0b3a1e 100644 --- a/tests/drivers/flash/negative_tests/src/main.c +++ b/tests/drivers/flash/negative_tests/src/main.c @@ -37,7 +37,7 @@ #endif #else -#error "Unsupported configuraiton" +#error "Unsupported configuration" #endif #define EXPECTED_SIZE 512 From 7a662cac8bb0ec27f0502e7e81e62a1fc15f4232 Mon Sep 17 00:00:00 2001 From: Matthias Alleman Date: Mon, 8 Dec 2025 15:22:03 +0100 Subject: [PATCH 0288/3659] drivers: input: input_chsc5x: add delay after reset The sensor requires at least 94ms of delay before starting communication after a reset. This is not mentioned in the datasheet but is arbitrarily defined. Signed-off-by: Matthias Alleman --- drivers/input/input_chsc5x.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/input/input_chsc5x.c b/drivers/input/input_chsc5x.c index 344adfaff0dd..647c3e3dbb0e 100644 --- a/drivers/input/input_chsc5x.c +++ b/drivers/input/input_chsc5x.c @@ -252,6 +252,9 @@ static int chsc5x_init(const struct device *dev) return ret; } + /* It takes about 94ms until chip is ready after reset. */ + k_msleep(100); + return chsc5x_chip_init(dev); }; From 158ec0384bba410beb614aa24539482dc9506cdb Mon Sep 17 00:00:00 2001 From: Matthias Alleman Date: Wed, 10 Dec 2025 15:57:35 +0100 Subject: [PATCH 0289/3659] drivers: input: input_chsc5x: configurable ic type verification Add Kconfig option to skip or execute the verification of the ic type. This adds a delay of 100ms to the initialization. Signed-off-by: Matthias Alleman --- drivers/input/Kconfig.chsc5x | 8 ++++++++ drivers/input/input_chsc5x.c | 13 +++++++++++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/drivers/input/Kconfig.chsc5x b/drivers/input/Kconfig.chsc5x index edd791dddbff..6a5607c44e23 100644 --- a/drivers/input/Kconfig.chsc5x +++ b/drivers/input/Kconfig.chsc5x @@ -10,3 +10,11 @@ config INPUT_CHSC5X select INPUT_TOUCH help Enable CHSC5X driver for Chipsemi capacitive touch panel controller. + +config INPUT_CHSC5X_VERIFY_IC_TYPE + bool "IC type verification" + default y + depends on INPUT_CHSC5X + help + This option enables the verification of the IC type which implies an + additional delay of 100ms during initialization. diff --git a/drivers/input/input_chsc5x.c b/drivers/input/input_chsc5x.c index 647c3e3dbb0e..7b5085fdec3e 100644 --- a/drivers/input/input_chsc5x.c +++ b/drivers/input/input_chsc5x.c @@ -100,7 +100,8 @@ static void chsc5x_isr_handler(const struct device *dev, struct gpio_callback *c k_work_submit(&data->work); } -static int chsc5x_chip_init(const struct device *dev) +#if defined(CONFIG_INPUT_CHSC5X_VERIFY_IC_TYPE) +static int chsc5x_verify_ic(const struct device *dev) { const struct chsc5x_config *cfg = dev->config; int ret; @@ -141,6 +142,7 @@ static int chsc5x_chip_init(const struct device *dev) return 0; } +#endif /* CONFIG_INPUT_CHSC5X_VERIFY_IC_TYPE */ static int chsc5x_reset(const struct device *dev) { @@ -252,10 +254,17 @@ static int chsc5x_init(const struct device *dev) return ret; } +#if defined(CONFIG_INPUT_CHSC5X_VERIFY_IC_TYPE) /* It takes about 94ms until chip is ready after reset. */ k_msleep(100); - return chsc5x_chip_init(dev); + ret = chsc5x_verify_ic(dev); + if (ret < 0) { + LOG_ERR("Failed to verify ic: %d", ret); + return ret; + } +#endif /* CONFIG_INPUT_CHSC5X_VERIFY_IC_TYPE */ + return ret; }; #define CHSC5X_DEFINE(index) \ From a2a215e8cc354cd06aa7cc21dfb414ad389c9fce Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Wed, 10 Dec 2025 14:35:10 +0100 Subject: [PATCH 0290/3659] subsys/crc/crc_shell: Fix includes To use the shell one does not need anymore to pull unistd.h, if one uses sys_getopt, we need to include sys/sys_getopt.h Signed-off-by: Alberto Escolar Piedras --- subsys/crc/crc_shell.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/subsys/crc/crc_shell.c b/subsys/crc/crc_shell.c index b8c313403de0..620a83e5c2d8 100644 --- a/subsys/crc/crc_shell.c +++ b/subsys/crc/crc_shell.c @@ -8,13 +8,8 @@ #include #include #include -#ifdef CONFIG_NATIVE_LIBC -#include -#else -#include -#endif - #include +#include #include #include From ba9b5f5ce0624b9958a523db3ea856014deeb3a2 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Wed, 10 Dec 2025 14:37:39 +0100 Subject: [PATCH 0291/3659] tests: subsys: crc: Improve test 1) Also build the CRC shell: Even if we do not runtime test that part, let's at least build it. Otherwise we do not have any test building it, and it just rots. 2) Do not limit the test to devices with HW CRC acceleration. The CRC module has a SW version, and it makes sense to test it also. (we were only build testing the HW support side in CI so far). 3) Limit what we test in integration to one platform for the SW version and one HW platform. Signed-off-by: Alberto Escolar Piedras --- tests/subsys/crc/prj.conf | 2 ++ tests/subsys/crc/testcase.yaml | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/subsys/crc/prj.conf b/tests/subsys/crc/prj.conf index d187aba6a129..881347bf05df 100644 --- a/tests/subsys/crc/prj.conf +++ b/tests/subsys/crc/prj.conf @@ -1,3 +1,5 @@ CONFIG_ZTEST=y CONFIG_CRC=y CONFIG_LOG=y +CONFIG_SHELL=y +CONFIG_CRC_SHELL=y diff --git a/tests/subsys/crc/testcase.yaml b/tests/subsys/crc/testcase.yaml index 6e8f87cc10fb..5d66a3c189d3 100644 --- a/tests/subsys/crc/testcase.yaml +++ b/tests/subsys/crc/testcase.yaml @@ -1,7 +1,9 @@ tests: subsys.crc: - depends_on: crc tags: - subsys - crc harness: ztest + integration_platforms: + - native_sim + - ek_ra8m1 From b62921f4cecba8972c048147bbd8cf7f40ec0836 Mon Sep 17 00:00:00 2001 From: Nikodem Kastelik Date: Wed, 10 Dec 2025 12:01:57 +0100 Subject: [PATCH 0292/3659] tests: boards: nrf: i2c: add twi variant Currently only TWIM peripheral is verified against TWIS. Add new test variant to verify nRF52 TWI peripheral as well. Signed-off-by: Nikodem Kastelik --- .../boards/nrf52840dk_nrf52840.overlay | 63 +---------------- .../boards/nrf52840dk_nrf52840_common.overlay | 70 +++++++++++++++++++ .../boards/nrf52840dk_nrf52840_twi.overlay | 10 +++ tests/boards/nrf/i2c/i2c_slave/testcase.yaml | 6 ++ 4 files changed, 87 insertions(+), 62 deletions(-) create mode 100644 tests/boards/nrf/i2c/i2c_slave/boards/nrf52840dk_nrf52840_common.overlay create mode 100644 tests/boards/nrf/i2c/i2c_slave/boards/nrf52840dk_nrf52840_twi.overlay diff --git a/tests/boards/nrf/i2c/i2c_slave/boards/nrf52840dk_nrf52840.overlay b/tests/boards/nrf/i2c/i2c_slave/boards/nrf52840dk_nrf52840.overlay index 8f9f7135f7b2..005708caa6f5 100644 --- a/tests/boards/nrf/i2c/i2c_slave/boards/nrf52840dk_nrf52840.overlay +++ b/tests/boards/nrf/i2c/i2c_slave/boards/nrf52840dk_nrf52840.overlay @@ -3,69 +3,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -/* - * Two loopbacks are required: - * P1.01 - P1.02 - * P1.03 - P1.04 - */ - -/ { - aliases { - i2c-slave = &i2c1; - }; -}; - -&pinctrl { - i2c0_default_alt: i2c0_default_alt { - group1 { - psels = , - ; - }; - }; - - i2c0_sleep_alt: i2c0_sleep_alt { - group1 { - psels = , - ; - low-power-enable; - }; - }; - - i2c1_default_alt: i2c1_default_alt { - group1 { - psels = , - ; - bias-pull-up; - }; - }; - - i2c1_sleep_alt: i2c1_sleep_alt { - group1 { - psels = , - ; - low-power-enable; - }; - }; -}; +#include "nrf52840dk_nrf52840_common.overlay" dut_twim: &i2c0 { compatible = "nordic,nrf-twim"; - status = "okay"; - pinctrl-0 = <&i2c0_default_alt>; - pinctrl-1 = <&i2c0_sleep_alt>; - pinctrl-names = "default", "sleep"; - clock-frequency = ; - - sensor: sensor@54 { - reg = <0x54>; - }; -}; - -dut_twis: &i2c1 { - compatible = "nordic,nrf-twis"; - status = "okay"; - pinctrl-0 = <&i2c1_default_alt>; - pinctrl-1 = <&i2c1_sleep_alt>; - pinctrl-names = "default", "sleep"; - clock-frequency = ; }; diff --git a/tests/boards/nrf/i2c/i2c_slave/boards/nrf52840dk_nrf52840_common.overlay b/tests/boards/nrf/i2c/i2c_slave/boards/nrf52840dk_nrf52840_common.overlay new file mode 100644 index 000000000000..4b52aa7ab9b3 --- /dev/null +++ b/tests/boards/nrf/i2c/i2c_slave/boards/nrf52840dk_nrf52840_common.overlay @@ -0,0 +1,70 @@ +/* + * Copyright 2025 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * Two loopbacks are required: + * P1.01 - P1.02 + * P1.03 - P1.04 + */ + +/ { + aliases { + i2c-slave = &i2c1; + }; +}; + +&pinctrl { + i2c0_default_alt: i2c0_default_alt { + group1 { + psels = , + ; + }; + }; + + i2c0_sleep_alt: i2c0_sleep_alt { + group1 { + psels = , + ; + low-power-enable; + }; + }; + + i2c1_default_alt: i2c1_default_alt { + group1 { + psels = , + ; + bias-pull-up; + }; + }; + + i2c1_sleep_alt: i2c1_sleep_alt { + group1 { + psels = , + ; + low-power-enable; + }; + }; +}; + +&i2c0 { + status = "okay"; + pinctrl-0 = <&i2c0_default_alt>; + pinctrl-1 = <&i2c0_sleep_alt>; + pinctrl-names = "default", "sleep"; + clock-frequency = ; + + sensor: sensor@54 { + reg = <0x54>; + }; +}; + +dut_twis: &i2c1 { + compatible = "nordic,nrf-twis"; + status = "okay"; + pinctrl-0 = <&i2c1_default_alt>; + pinctrl-1 = <&i2c1_sleep_alt>; + pinctrl-names = "default", "sleep"; + clock-frequency = ; +}; diff --git a/tests/boards/nrf/i2c/i2c_slave/boards/nrf52840dk_nrf52840_twi.overlay b/tests/boards/nrf/i2c/i2c_slave/boards/nrf52840dk_nrf52840_twi.overlay new file mode 100644 index 000000000000..36a246257db2 --- /dev/null +++ b/tests/boards/nrf/i2c/i2c_slave/boards/nrf52840dk_nrf52840_twi.overlay @@ -0,0 +1,10 @@ +/* + * Copyright 2025 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "nrf52840dk_nrf52840_common.overlay" + +&i2c0 { + compatible = "nordic,nrf-twi"; +}; diff --git a/tests/boards/nrf/i2c/i2c_slave/testcase.yaml b/tests/boards/nrf/i2c/i2c_slave/testcase.yaml index 8e324bcaf563..b50aade0191e 100644 --- a/tests/boards/nrf/i2c/i2c_slave/testcase.yaml +++ b/tests/boards/nrf/i2c/i2c_slave/testcase.yaml @@ -24,6 +24,12 @@ tests: - nrf54h20dk/nrf54h20/cpuppr - nrf54l15dk/nrf54l15/cpuapp - nrf54lm20dk/nrf54lm20a/cpuapp + boards.nrf.i2c.i2c_slave.twi: + platform_allow: + - nrf52840dk/nrf52840 + integration_platforms: + - nrf52840dk/nrf52840 + extra_args: DTC_OVERLAY_FILE="boards/nrf52840dk_nrf52840_twi.overlay" boards.nrf.i2c.i2c_slave.fast: platform_allow: - nrf52840dk/nrf52840 From 1a6ff4f8e44a4105397992e46d9cb1ade073596e Mon Sep 17 00:00:00 2001 From: Damian Krolik Date: Wed, 10 Dec 2025 11:44:28 +0100 Subject: [PATCH 0293/3659] drivers: ieee802154: remove unused IEEE802154_CSL_DEBUG The Kconfig option is not used anywhere for a while. Signed-off-by: Damian Krolik --- drivers/ieee802154/Kconfig | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/ieee802154/Kconfig b/drivers/ieee802154/Kconfig index fc28d332c2f5..1ead7ac32149 100644 --- a/drivers/ieee802154/Kconfig +++ b/drivers/ieee802154/Kconfig @@ -91,12 +91,6 @@ config IEEE802154_CSL_ENDPOINT Make this device a CSL (coordinated sampled listening) endpoint with delayed reception handling and CSL IE injection. -config IEEE802154_CSL_DEBUG - bool "Support for CSL debugging" - depends on IEEE802154_CSL_ENDPOINT - help - Enable support for CSL debugging by avoiding sleep state in favor of receive state. - config IEEE802154_SELECTIVE_TXCHANNEL bool "Support for selective TX channel setting" help From 287f40edbe095eccdd5ab95729c50317b228076d Mon Sep 17 00:00:00 2001 From: Camille BAUD Date: Mon, 8 Dec 2025 23:46:18 +0100 Subject: [PATCH 0294/3659] drivers: lora: Add regulator-ldo for sx126x Adds ability to set usage of LDO instead of DCDC Signed-off-by: Camille BAUD --- drivers/lora/lora_basics_modem/lbm_sx126x.c | 12 ++++++++++-- dts/bindings/lora/semtech,sx126x-base.yaml | 5 +++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/drivers/lora/lora_basics_modem/lbm_sx126x.c b/drivers/lora/lora_basics_modem/lbm_sx126x.c index af8f97e08baa..462d88e2b03f 100644 --- a/drivers/lora/lora_basics_modem/lbm_sx126x.c +++ b/drivers/lora/lora_basics_modem/lbm_sx126x.c @@ -97,6 +97,7 @@ struct lbm_sx126x_config { uint8_t dio3_tcxo_voltage; bool dio2_rf_switch; bool rx_boosted; + bool regulator_ldo; enum sx126x_variant variant; }; @@ -277,8 +278,14 @@ sx126x_hal_status_t sx126x_hal_wakeup(const void *context) void ral_sx126x_bsp_get_reg_mode(const void *context, sx126x_reg_mod_t *reg_mode) { - /* Not currently described in devicetree */ - *reg_mode = SX126X_REG_MODE_DCDC; + const struct device *dev = context; + const struct lbm_sx126x_config *config = dev->config; + + if (config->regulator_ldo) { + *reg_mode = SX126X_REG_MODE_LDO; + } else { + *reg_mode = SX126X_REG_MODE_DCDC; + } } void ral_sx126x_bsp_get_rf_switch_cfg(const void *context, bool *dio2_is_set_as_rf_switch) @@ -506,6 +513,7 @@ static int sx126x_init(const struct device *dev) .dio3_tcxo_voltage = DT_PROP_OR(node_id, dio3_tcxo_voltage, UINT8_MAX), \ .dio2_rf_switch = DT_PROP(node_id, dio2_tx_enable), \ .rx_boosted = DT_PROP(node_id, rx_boosted), \ + .regulator_ldo = DT_PROP(node_id, regulator_ldo), \ .variant = sx_variant, \ }; \ static struct lbm_sx126x_data data_##node_id; \ diff --git a/dts/bindings/lora/semtech,sx126x-base.yaml b/dts/bindings/lora/semtech,sx126x-base.yaml index d4d1c36b6622..72143f2564f8 100644 --- a/dts/bindings/lora/semtech,sx126x-base.yaml +++ b/dts/bindings/lora/semtech,sx126x-base.yaml @@ -65,3 +65,8 @@ properties: description: | Enable RX boosted mode, which increases the power consumption of RX mode by ~2mA in exchange for ~3dB sensitivity improvement. + + regulator-ldo: + type: boolean + description: | + Use the internal LDO instead of the internal DCDC. Increases power consumption. From 7a1e2d7509c90a85e7a7ac1fcadee79ee6ef8416 Mon Sep 17 00:00:00 2001 From: Camille BAUD Date: Mon, 8 Dec 2025 23:48:36 +0100 Subject: [PATCH 0295/3659] drivers: lora: Add explicit support for variants Add explicit support for sx1268, sx1278, llcc68 Signed-off-by: Camille BAUD --- drivers/lora/Kconfig | 7 ++++++- drivers/lora/Kconfig.sx12xx | 11 ++++++----- drivers/lora/lora_basics_modem/lbm_sx126x.c | 2 ++ drivers/lora/lora_basics_modem/lbm_sx127x.c | 1 + dts/bindings/lora/semtech,llcc68.yaml | 21 +++++++++++++++++++++ dts/bindings/lora/semtech,sx1268.yaml | 18 ++++++++++++++++++ dts/bindings/lora/semtech,sx1278.yaml | 10 ++++++++++ modules/lora-basics-modem/sx127x.cmake | 2 +- 8 files changed, 65 insertions(+), 7 deletions(-) create mode 100644 dts/bindings/lora/semtech,llcc68.yaml create mode 100644 dts/bindings/lora/semtech,sx1268.yaml create mode 100644 dts/bindings/lora/semtech,sx1278.yaml diff --git a/drivers/lora/Kconfig b/drivers/lora/Kconfig index 41512c5f75c1..380d2d39728f 100644 --- a/drivers/lora/Kconfig +++ b/drivers/lora/Kconfig @@ -16,6 +16,8 @@ if LORA choice LORA_MODULE_BACKEND prompt "Low-level LoRa modem integration to use" + default LORA_MODULE_BACKEND_LORA_BASICS_MODEM if DT_HAS_SEMTECH_SX1268_ENABLED \ + || DT_HAS_SEMTECH_LLCC68_ENABLED || DT_HAS_SEMTECH_SX1278_ENABLED config LORA_MODULE_BACKEND_LORAMAC_NODE bool "loramac-node backend" @@ -24,7 +26,10 @@ config LORA_MODULE_BACKEND_LORAMAC_NODE config LORA_MODULE_BACKEND_LORA_BASICS_MODEM bool "LoRa Basic modem backend" depends on ZEPHYR_LORA_BASICS_MODEM_MODULE - depends on DT_HAS_SEMTECH_SX1262_ENABLED || DT_HAS_SEMTECH_SX1261_ENABLED || DT_HAS_SEMTECH_SX1272_ENABLED || DT_HAS_SEMTECH_SX1276_ENABLED + depends on DT_HAS_SEMTECH_SX1262_ENABLED || DT_HAS_SEMTECH_SX1261_ENABLED \ + || DT_HAS_SEMTECH_SX1272_ENABLED || DT_HAS_SEMTECH_SX1276_ENABLED \ + || DT_HAS_SEMTECH_SX1268_ENABLED || DT_HAS_SEMTECH_LLCC68_ENABLED \ + || DT_HAS_SEMTECH_SX1278_ENABLED select USE_LORA_BASICS_MODEM_DRIVERS help LoRa API support using the LoRa Basics Modem module. diff --git a/drivers/lora/Kconfig.sx12xx b/drivers/lora/Kconfig.sx12xx index 209432717df5..8c2de22e11f6 100644 --- a/drivers/lora/Kconfig.sx12xx +++ b/drivers/lora/Kconfig.sx12xx @@ -7,23 +7,24 @@ config LORA_SX127X bool "Semtech SX127x driver" default y - depends on DT_HAS_SEMTECH_SX1272_ENABLED || DT_HAS_SEMTECH_SX1276_ENABLED + depends on DT_HAS_SEMTECH_SX1272_ENABLED || DT_HAS_SEMTECH_SX1276_ENABLED || DT_HAS_SEMTECH_SX1278_ENABLED select HAS_SEMTECH_SX1272 if DT_HAS_SEMTECH_SX1272_ENABLED - select HAS_SEMTECH_SX1276 if DT_HAS_SEMTECH_SX1276_ENABLED + select HAS_SEMTECH_SX1276 if DT_HAS_SEMTECH_SX1276_ENABLED || DT_HAS_SEMTECH_SX1278_ENABLED select SPI select GPIO help - Enable LoRa driver for Semtech SX1272 and SX1276. + Enable LoRa driver for Semtech SX1272 and SX1276/SX1278 config LORA_SX126X bool "Semtech SX126x driver" default y - depends on DT_HAS_SEMTECH_SX1261_ENABLED || DT_HAS_SEMTECH_SX1262_ENABLED + depends on DT_HAS_SEMTECH_SX1261_ENABLED || DT_HAS_SEMTECH_SX1262_ENABLED \ + || DT_HAS_SEMTECH_SX1268_ENABLED || DT_HAS_SEMTECH_LLCC68_ENABLED select HAS_SEMTECH_SX126X select SPI select GPIO help - Enable LoRa driver for Semtech SX1261 and SX1262. + Enable LoRa driver for Semtech SX1261, SX1262/SX1268, and LLCC68 config LORA_STM32WL_SUBGHZ_RADIO bool "STM32WL SUBGHZ radio driver" diff --git a/drivers/lora/lora_basics_modem/lbm_sx126x.c b/drivers/lora/lora_basics_modem/lbm_sx126x.c index 462d88e2b03f..fa93a5e3218d 100644 --- a/drivers/lora/lora_basics_modem/lbm_sx126x.c +++ b/drivers/lora/lora_basics_modem/lbm_sx126x.c @@ -525,3 +525,5 @@ static int sx126x_init(const struct device *dev) DT_FOREACH_STATUS_OKAY(semtech_sx1261, SX1261_DEFINE); DT_FOREACH_STATUS_OKAY(semtech_sx1262, SX1262_DEFINE); +DT_FOREACH_STATUS_OKAY(semtech_sx1268, SX1262_DEFINE); +DT_FOREACH_STATUS_OKAY(semtech_llcc68, SX1262_DEFINE); diff --git a/drivers/lora/lora_basics_modem/lbm_sx127x.c b/drivers/lora/lora_basics_modem/lbm_sx127x.c index 1a12bd2421bf..200fadee597e 100644 --- a/drivers/lora/lora_basics_modem/lbm_sx127x.c +++ b/drivers/lora/lora_basics_modem/lbm_sx127x.c @@ -457,3 +457,4 @@ static int sx127x_driver_init(const struct device *dev) DT_FOREACH_STATUS_OKAY(semtech_sx1272, SX127X_DEFINE); DT_FOREACH_STATUS_OKAY(semtech_sx1276, SX127X_DEFINE); +DT_FOREACH_STATUS_OKAY(semtech_sx1278, SX127X_DEFINE); diff --git a/dts/bindings/lora/semtech,llcc68.yaml b/dts/bindings/lora/semtech,llcc68.yaml new file mode 100644 index 000000000000..8f8bc1619585 --- /dev/null +++ b/dts/bindings/lora/semtech,llcc68.yaml @@ -0,0 +1,21 @@ +# Copyright (c) 2025 MASSDRIVER EI (massdriver.space) +# SPDX-License-Identifier: Apache-2.0 + +description: | + Semtech LLCC68 LoRa Modem + A cost-cut version of sx126x with limited Spreading Factors and Bandwidth selections: + SF=5-6-7-8-9 for BW=125kHz, + SF=5-6-7-8-9-10 for BW =250 kHz, + SF=5-6-7-8-9-10-11 for BW=500 kHz. + +compatible: "semtech,llcc68" + +include: semtech,sx126x-base.yaml + +properties: + reset-gpios: + required: true + busy-gpios: + required: true + dio1-gpios: + required: true diff --git a/dts/bindings/lora/semtech,sx1268.yaml b/dts/bindings/lora/semtech,sx1268.yaml new file mode 100644 index 000000000000..8b04875e35d7 --- /dev/null +++ b/dts/bindings/lora/semtech,sx1268.yaml @@ -0,0 +1,18 @@ +# Copyright (c) 2025 MASSDRIVER EI (massdriver.space) +# SPDX-License-Identifier: Apache-2.0 + +description: | + Semtech SX1268 LoRa Modem + A variant of sx1262 targeting Chinese regulations compliance. + +compatible: "semtech,sx1268" + +include: semtech,sx126x-base.yaml + +properties: + reset-gpios: + required: true + busy-gpios: + required: true + dio1-gpios: + required: true diff --git a/dts/bindings/lora/semtech,sx1278.yaml b/dts/bindings/lora/semtech,sx1278.yaml new file mode 100644 index 000000000000..aebb7f0d1ef1 --- /dev/null +++ b/dts/bindings/lora/semtech,sx1278.yaml @@ -0,0 +1,10 @@ +# Copyright (c) 2025 MASSDRIVER EI (massdriver.space) +# SPDX-License-Identifier: Apache-2.0 + +description: | + Semtech SX1278 LoRa Modem + A variant of sx1276 targeting sub-525MHz bands. + +compatible: "semtech,sx1278" + +include: semtech,sx127x-base.yaml diff --git a/modules/lora-basics-modem/sx127x.cmake b/modules/lora-basics-modem/sx127x.cmake index 512114520d20..b26c4f824c58 100644 --- a/modules/lora-basics-modem/sx127x.cmake +++ b/modules/lora-basics-modem/sx127x.cmake @@ -8,7 +8,7 @@ zephyr_library_compile_definitions(SX127X_TRANSCEIVER) if(CONFIG_DT_HAS_SEMTECH_SX1272_ENABLED) zephyr_library_compile_definitions(SX1272) endif() -if(CONFIG_DT_HAS_SEMTECH_SX1276_ENABLED) +if(CONFIG_DT_HAS_SEMTECH_SX1276_ENABLED OR CONFIG_DT_HAS_SEMTECH_SX1278_ENABLED) zephyr_library_compile_definitions(SX1276) endif() From 7abba8812fc1bf293cbd5e2be52b146e66bb2b07 Mon Sep 17 00:00:00 2001 From: Cristian Bulacu Date: Wed, 3 Dec 2025 10:52:59 +0200 Subject: [PATCH 0296/3659] samples: net: openthread: border_router: Add ethernet config Added project configuration for OpenThread Zephyr Border Router with ethernet configured as backbone interface Signed-off-by: Cristian Bulacu --- .../overlay-ot-rcp-host-eth-nxp.conf | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 samples/net/openthread/border_router/overlay-ot-rcp-host-eth-nxp.conf diff --git a/samples/net/openthread/border_router/overlay-ot-rcp-host-eth-nxp.conf b/samples/net/openthread/border_router/overlay-ot-rcp-host-eth-nxp.conf new file mode 100644 index 000000000000..6909f891e362 --- /dev/null +++ b/samples/net/openthread/border_router/overlay-ot-rcp-host-eth-nxp.conf @@ -0,0 +1,55 @@ +# +# Copyright 2025, NXP +# +# Generic Ethernet options +CONFIG_ETH_DRIVER=y +CONFIG_NET_L2_ETHERNET=y +CONFIG_NET_DHCPV4=y +CONFIG_ZVFS_EVENTFD_MAX=2 +CONFIG_NET_CONFIG_SETTINGS=y +CONFIG_NET_CONFIG_AUTO_INIT=y +CONFIG_NET_CONFIG_NEED_IPV4=y +CONFIG_NET_CONFIG_NEED_IPV6=n +CONFIG_IEEE802154_NET_IF_NO_AUTO_START=y + +# lib & os +CONFIG_EVENTS=y + +# CPP library +CONFIG_CPP=y + +# Use NVS as settings backend +CONFIG_NVS=y + +# IMU & FW loader +CONFIG_NXP_RF_IMU=y +CONFIG_NXP_FW_LOADER=y + +# Shell +CONFIG_SHELL_ARGC_MAX=26 +CONFIG_SHELL_CMD_BUFF_SIZE=512 +CONFIG_SHELL_STACK_SIZE=5120 + +# Network shell +CONFIG_NET_SHELL=y +CONFIG_SHELL=y + +# Enable Openthread RCP host interface +CONFIG_HDLC_RCP_IF=y +CONFIG_OPENTHREAD_MANUAL_START=y +CONFIG_OPENTHREAD_RCP_RESTORATION_MAX_COUNT=10 + +#Border Router mDNS host name and service base name +CONFIG_OPENTHREAD_ZEPHYR_BORDER_ROUTER_VENDOR_NAME="NXP" +CONFIG_OPENTHREAD_ZEPHYR_BORDER_ROUTER_BASE_SERVICE_NAME="NXP-BorderRouter" + +#As per Thread v1.2.0 Conformance, a Thread Border Router MUST be able to hold a Multicast Listener +#Table in memory with at least 75 entries. +#75 entries for conformance, 10 extra for other purposes, if any. +CONFIG_NET_MAX_MCAST_ROUTES=85 +CONFIG_NET_IF_MCAST_IPV6_ADDR_COUNT=85 + +# Network diagnostics +CONFIG_OPENTHREAD_NET_DIAG_VENDOR_NAME="NXP" +CONFIG_OPENTHREAD_NET_DIAG_VENDOR_MODEL="RW612" +CONFIG_OPENTHREAD_NET_DIAG_VENDOR_SW_VERSION="v1.0.0" From 267c3196f6138bc58ec8e03d0708fb83af03eda8 Mon Sep 17 00:00:00 2001 From: Cristian Bulacu Date: Wed, 3 Dec 2025 10:54:26 +0200 Subject: [PATCH 0297/3659] net: l2: openthread: Bring OT iface up on backbone events When Ethernet is enabled, `net_config_init_app` function will use the first found interface that has auto start enabled. In this particular case, backbone interface will not be able to perform dhcp request because OpenThread interface gets to be the first interface found and chose. Openthread will fail this procedure, as it has no direct connectivity to backbone. This is why, ethernet app has `CONFIG_IEEE802154_NET_IF_NO_AUTO_START` set. In this case, make sure to call net_if_up for OpenThread interface from border router code when backbone events are triggered. Signed-off-by: Cristian Bulacu --- subsys/net/l2/openthread/openthread_border_router.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/subsys/net/l2/openthread/openthread_border_router.c b/subsys/net/l2/openthread/openthread_border_router.c index ad87fb19863d..ca949c123d12 100644 --- a/subsys/net/l2/openthread/openthread_border_router.c +++ b/subsys/net/l2/openthread/openthread_border_router.c @@ -244,6 +244,11 @@ static void ail_connection_handler(struct net_mgmt_event_callback *cb, uint64_t break; } #endif /* CONFIG_NET_IPV4*/ + + if (!net_if_is_wifi(iface)) { + net_if_up(ot_context->iface); + } + (void)openthread_start_border_router_services(ot_context->iface, iface); break; case NET_EVENT_IF_DOWN: @@ -285,6 +290,10 @@ static void ail_ipv4_address_event_handler(struct net_mgmt_event_callback *cb, u if (mgmt_event == NET_EVENT_IPV4_ADDR_ADD) { struct openthread_context *ot_context = openthread_get_default_context(); + if (!net_if_is_wifi(iface)) { + net_if_up(ot_context->iface); + } + openthread_start_border_router_services(ot_context->iface, iface); } From 7a9b4d3a5cf2257b6d6aef6f518d8969ff831d58 Mon Sep 17 00:00:00 2001 From: Tim Pambor Date: Tue, 9 Dec 2025 11:34:13 +0100 Subject: [PATCH 0298/3659] boards: st: stm32h573i_dk: Add TF-M non-secure app support Add support for building Trusted Firmware-M (TF-M) non-secure applications for the STM32H573I-DK board. Signed-off-by: Tim Pambor --- boards/st/stm32h573i_dk/board.cmake | 12 +++ boards/st/stm32h573i_dk/board.yml | 1 + boards/st/stm32h573i_dk/doc/index.rst | 44 +++++++++ .../stm32h573i_dk_stm32h573xx_ns.dts | 96 +++++++++++++++++++ .../stm32h573i_dk_stm32h573xx_ns.yaml | 9 ++ .../stm32h573i_dk_stm32h573xx_ns_defconfig | 24 +++++ modules/trusted-firmware-m/Kconfig.tfm | 1 + .../tfm_integration/config_build/sample.yaml | 1 + .../tfm_integration/psa_crypto/sample.yaml | 1 + .../psa_protected_storage/sample.yaml | 1 + samples/tfm_integration/tfm_ipc/sample.yaml | 1 + .../tfm_regression_test/sample.yaml | 1 + .../tfm_secure_partition/sample.yaml | 1 + west.yml | 2 +- 14 files changed, 194 insertions(+), 1 deletion(-) create mode 100644 boards/st/stm32h573i_dk/stm32h573i_dk_stm32h573xx_ns.dts create mode 100644 boards/st/stm32h573i_dk/stm32h573i_dk_stm32h573xx_ns.yaml create mode 100644 boards/st/stm32h573i_dk/stm32h573i_dk_stm32h573xx_ns_defconfig diff --git a/boards/st/stm32h573i_dk/board.cmake b/boards/st/stm32h573i_dk/board.cmake index a98d8bd66650..e25cbad6fd6a 100644 --- a/boards/st/stm32h573i_dk/board.cmake +++ b/boards/st/stm32h573i_dk/board.cmake @@ -1,4 +1,16 @@ # SPDX-License-Identifier: Apache-2.0 +if(CONFIG_BUILD_WITH_TFM) + set(FLASH_BASE_ADDRESS_S 0x0C000000) + + # Flash merged TF-M + Zephyr binary + set_property(TARGET runners_yaml_props_target PROPERTY hex_file tfm_merged.hex) + + if(CONFIG_HAS_FLASH_LOAD_OFFSET) + MATH(EXPR TFM_HEX_BASE_ADDRESS_NS "${FLASH_BASE_ADDRESS_S}+${CONFIG_FLASH_LOAD_OFFSET}") + else() + set(TFM_HEX_BASE_ADDRESS_NS ${TFM_FLASH_BASE_ADDRESS_S}) + endif() +endif() # keep first board_runner_args(stm32cubeprogrammer "--port=swd" "--reset-mode=hw") diff --git a/boards/st/stm32h573i_dk/board.yml b/boards/st/stm32h573i_dk/board.yml index 8b9adab2eedb..173fc4740402 100644 --- a/boards/st/stm32h573i_dk/board.yml +++ b/boards/st/stm32h573i_dk/board.yml @@ -6,3 +6,4 @@ board: - name: stm32h573xx variants: - name: ext_flash_app + - name: ns diff --git a/boards/st/stm32h573i_dk/doc/index.rst b/boards/st/stm32h573i_dk/doc/index.rst index f1733b945885..a0d789a82862 100644 --- a/boards/st/stm32h573i_dk/doc/index.rst +++ b/boards/st/stm32h573i_dk/doc/index.rst @@ -149,6 +149,50 @@ Supported Features .. zephyr:board-supported-hw:: +Zephyr board options +==================== + +The STM32H573 is an SoC with Cortex-M33 architecture. Zephyr provides support +for building for both Secure and Non-Secure firmware. + +The BOARD options are summarized below: + ++-----------------------------------------+------------------------------------------------------------------+ +| BOARD | Description | ++=========================================+==================================================================+ +| stm32h573i_dk | For building firmware with TrustZone disabled for internal flash | ++-----------------------------------------+------------------------------------------------------------------+ +| stm32h573i_dk/stm32h573xx/ext_flash_app | For building firmware with TrustZone disabled for external flash | ++-----------------------------------------+------------------------------------------------------------------+ +| stm32h573i_dk/stm32h573xx/ns | For building Non-Secure firmware for internal flash | ++-----------------------------------------+------------------------------------------------------------------+ + +Here are the instructions to build Zephyr with a non-secure configuration, +using :zephyr:code-sample:`tfm_ipc` sample: + +.. zephyr-app-commands:: + :zephyr-app: samples/tfm_integration/tfm_ipc + :board: stm32h573i_dk/stm32h573xx/ns + :goals: build + +Once done, before flashing, you need to first run a generated script that +will set platform Option Bytes config and erase platform (among others, +Option Byte TZEN will be set). + + .. code-block:: bash + + $ ./build/tfm/api_ns/regression.sh + $ west flash + +Please note that, after having run a TF-M sample on the board, you will need to +use STM32CubeProgrammer_ to return the board to a state with TrustZone disabled +and be able to run usual binaries without TrustZone and TF-M. For example, +when using a device in Open Product State, one can disable TZEN with: + + .. code-block:: bash + + $ STM32_Programmer_CLI -c port=swd -ob TZEN=0xC3 + Connections and IOs =================== diff --git a/boards/st/stm32h573i_dk/stm32h573i_dk_stm32h573xx_ns.dts b/boards/st/stm32h573i_dk/stm32h573i_dk_stm32h573xx_ns.dts new file mode 100644 index 000000000000..46357c2e2d58 --- /dev/null +++ b/boards/st/stm32h573i_dk/stm32h573i_dk_stm32h573xx_ns.dts @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2023 STMicroelectronics + * Copyright (c) 2025 CodeWrights GmbH + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include "stm32h573i_dk-common.dtsi" + +/ { + model = "STMicroelectronics STM32H573I DISCOVERY KIT board"; + compatible = "st,stm32h573i-dk"; + + chosen { + zephyr,flash = &flash0; + zephyr,flash-controller = &flash; + zephyr,code-partition = &slot0_ns_partition; + }; +}; + +/* Last 64kB of SRAM1 are owned by TF-M */ +&sram1 { + reg = <0x20000000 DT_SIZE_K(256 - 64)>; +}; + +/* SRAM2 is owned by TF-M */ +&sram2 { + status = "disabled"; +}; + +&flash0 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + /* Keep in sync with partitions from flash_layout.h in TF-M + * MCUboot (scratch area) 0000_0000 - 0000_C000 ( 48k) + * MCUboot (anti-rollback counter) 0000_C000 - 0001_0000 ( 16k) + * MCUboot (BL2) 0001_0000 - 0002_8000 ( 96k) + * MCUboot (OTP / non-volatile counters) 0002_8000 - 0002_C000 ( 16k) + * MCUboot (non-volatile counters) 0002_C000 - 0003_0000 ( 16k) + * Secure storage 0003_0000 - 0003_4000 ( 16k) + * Internal trusted storage 0003_4000 - 0003_8000 ( 16k) + * Slot 0 Secure Partition 0003_8000 - 0008_8000 (320k) + * Slot 0 Non-Secure Partition 0008_8000 - 0011_8000 (576k) + * Slot 1 Secure Partition 0011_8000 - 0016_8000 (320k) + * Slot 1 Non-Secure Partition 0016_8000 - 001F_8000 (576k) + * Storage Partition 001F_8000 - 0020_0000 ( 32k) + */ + + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 DT_SIZE_K(192)>; + }; + + slot0_partition: partition@38000 { + label = "image-0"; + reg = <0x00038000 DT_SIZE_K(320)>; + }; + + slot0_ns_partition: partition@88000 { + label = "image-0-nonsecure"; + reg = <0x00088000 DT_SIZE_K(576)>; + }; + + slot1_partition: partition@118000 { + label = "image-1"; + reg = <0x00118000 DT_SIZE_K(320)>; + }; + + slot1_ns_partition: partition@168000 { + label = "image-1-nonsecure"; + reg = <0x00168000 DT_SIZE_K(576)>; + }; + + storage_partition: partition@1f8000 { + label = "storage"; + reg = <0x001f8000 DT_SIZE_K(32)>; + }; + }; +}; + +&ext_flash { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "nor"; + reg = <0x00000000 DT_SIZE_M(64)>; + }; + }; +}; diff --git a/boards/st/stm32h573i_dk/stm32h573i_dk_stm32h573xx_ns.yaml b/boards/st/stm32h573i_dk/stm32h573i_dk_stm32h573xx_ns.yaml new file mode 100644 index 000000000000..ce41200eb222 --- /dev/null +++ b/boards/st/stm32h573i_dk/stm32h573i_dk_stm32h573xx_ns.yaml @@ -0,0 +1,9 @@ +identifier: stm32h573i_dk/stm32h573xx/ns +name: ST STM32H573I Discovery Kit non-secure +type: mcu +arch: arm +toolchain: + - zephyr +ram: 192 +flash: 575 # size in kB of 1 app slot minus MCUboot header size (1KB) +vendor: st diff --git a/boards/st/stm32h573i_dk/stm32h573i_dk_stm32h573xx_ns_defconfig b/boards/st/stm32h573i_dk/stm32h573i_dk_stm32h573xx_ns_defconfig new file mode 100644 index 000000000000..ecccf647305f --- /dev/null +++ b/boards/st/stm32h573i_dk/stm32h573i_dk_stm32h573xx_ns_defconfig @@ -0,0 +1,24 @@ +# Copyright (c) 2023 STMicroelectronics +# Copyright (c) 2025 CodeWrights GmbH +# SPDX-License-Identifier: Apache-2.0 + +# 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 TZ non-secure configuration +CONFIG_TRUSTED_EXECUTION_NONSECURE=y +CONFIG_RUNTIME_NMI=y +CONFIG_TFM_MCUBOOT_SIGNATURE_TYPE="RSA-3072" diff --git a/modules/trusted-firmware-m/Kconfig.tfm b/modules/trusted-firmware-m/Kconfig.tfm index 6a8140b23d5a..692cd9efa5e9 100644 --- a/modules/trusted-firmware-m/Kconfig.tfm +++ b/modules/trusted-firmware-m/Kconfig.tfm @@ -24,6 +24,7 @@ config TFM_BOARD default "nxp/lpcxpresso55s69" if BOARD_LPCXPRESSO55S69_LPC55S69_CPU0_NS default "stm/b_u585i_iot02a" if BOARD_B_U585I_IOT02A default "stm/nucleo_l552ze_q" if BOARD_NUCLEO_L552ZE_Q + default "stm/stm32h573i_dk" if BOARD_STM32H573I_DK default "stm/stm32l562e_dk" if BOARD_STM32L562E_DK default "stm/stm32wba65i_dk" if BOARD_NUCLEO_WBA65RI || BOARD_STM32WBA65I_DK1 default "$(ZEPHYR_BASE)/modules/trusted-firmware-m/nordic/nrf9160" if SOC_NRF9160 diff --git a/samples/tfm_integration/config_build/sample.yaml b/samples/tfm_integration/config_build/sample.yaml index 55c4e2348081..b8d0a6876238 100644 --- a/samples/tfm_integration/config_build/sample.yaml +++ b/samples/tfm_integration/config_build/sample.yaml @@ -28,6 +28,7 @@ tests: - mcuboot platform_allow: # Platform fails no_bl2 + - stm32h573i_dk/stm32h573xx/ns - stm32l562e_dk/stm32l562xx/ns extra_configs: - CONFIG_TFM_MCUBOOT_IMAGE_NUMBER=1 diff --git a/samples/tfm_integration/psa_crypto/sample.yaml b/samples/tfm_integration/psa_crypto/sample.yaml index ea9844730fc1..545b2337e578 100644 --- a/samples/tfm_integration/psa_crypto/sample.yaml +++ b/samples/tfm_integration/psa_crypto/sample.yaml @@ -21,6 +21,7 @@ tests: - stm32l562e_dk/stm32l562xx/ns - bl5340_dvk/nrf5340/cpuapp/ns - max32657evkit/max32657/ns + - stm32h573i_dk/stm32h573xx/ns integration_platforms: - mps2/an521/cpu0/ns harness: console diff --git a/samples/tfm_integration/psa_protected_storage/sample.yaml b/samples/tfm_integration/psa_protected_storage/sample.yaml index 753f10d92335..eaee6b5512e0 100644 --- a/samples/tfm_integration/psa_protected_storage/sample.yaml +++ b/samples/tfm_integration/psa_protected_storage/sample.yaml @@ -11,6 +11,7 @@ common: - bl5340_dvk/nrf5340/cpuapp/ns - lpcxpresso55s69/lpc55s69/cpu0/ns - max32657evkit/max32657/ns + - stm32h573i_dk/stm32h573xx/ns integration_platforms: - mps2/an521/cpu0/ns harness: console diff --git a/samples/tfm_integration/tfm_ipc/sample.yaml b/samples/tfm_integration/tfm_ipc/sample.yaml index 154d91b23f31..e9dccceb5050 100644 --- a/samples/tfm_integration/tfm_ipc/sample.yaml +++ b/samples/tfm_integration/tfm_ipc/sample.yaml @@ -17,6 +17,7 @@ tests: - v2m_musca_s1/musca_s1/ns - bl5340_dvk/nrf5340/cpuapp/ns - b_u585i_iot02a/stm32u585xx/ns + - stm32h573i_dk/stm32h573xx/ns integration_platforms: - mps2/an521/cpu0/ns harness: console diff --git a/samples/tfm_integration/tfm_regression_test/sample.yaml b/samples/tfm_integration/tfm_regression_test/sample.yaml index 793481562352..df68fee84a74 100644 --- a/samples/tfm_integration/tfm_regression_test/sample.yaml +++ b/samples/tfm_integration/tfm_regression_test/sample.yaml @@ -9,6 +9,7 @@ common: - nrf9160dk/nrf9160/ns - nrf9161dk/nrf9161/ns - v2m_musca_s1/musca_s1/ns + - stm32h573i_dk/stm32h573xx/ns integration_platforms: - nrf5340dk/nrf5340/cpuapp/ns harness: console diff --git a/samples/tfm_integration/tfm_secure_partition/sample.yaml b/samples/tfm_integration/tfm_secure_partition/sample.yaml index f9d23b7a35bd..c5a88b09ccf4 100644 --- a/samples/tfm_integration/tfm_secure_partition/sample.yaml +++ b/samples/tfm_integration/tfm_secure_partition/sample.yaml @@ -8,6 +8,7 @@ common: - nrf9160dk/nrf9160/ns - lpcxpresso55s69/lpc55s69/cpu0/ns - max32657evkit/max32657/ns + - stm32h573i_dk/stm32h573xx/ns integration_platforms: - mps2/an521/cpu0/ns harness: console diff --git a/west.yml b/west.yml index 936b5b717add..5d4fefc5d38a 100644 --- a/west.yml +++ b/west.yml @@ -380,7 +380,7 @@ manifest: groups: - tee - name: trusted-firmware-m - revision: e295109067f71e1c8db76d02396baa050687b1df + revision: db82030ab21def6d170a7a7ef8def5081ed6f328 path: modules/tee/tf-m/trusted-firmware-m groups: - tee From a4e2a3837071c119c929f8396a66bd477d132764 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Thu, 20 Nov 2025 16:51:57 +0000 Subject: [PATCH 0299/3659] scripts: zephyr_module: Skip writing output on no change Skips updating files if the output already matches the file contents, this prevents a random occurance whereby sysbuild reconfigures itself after a reconfiguration for no known discernable reason Signed-off-by: Jamie McCrae --- scripts/zephyr_module.py | 61 +++++++++++++++++++--------------------- 1 file changed, 29 insertions(+), 32 deletions(-) diff --git a/scripts/zephyr_module.py b/scripts/zephyr_module.py index 544775dc4b3a..1bef12ff2484 100755 --- a/scripts/zephyr_module.py +++ b/scripts/zephyr_module.py @@ -830,6 +830,14 @@ def parse_modules(zephyr_base, manifest=None, west_projs=None, modules=None, return sorted_modules +def write_if_different(file, data): + if Path(file).is_file(): + with open(file, encoding="utf-8") as fp: + if fp.read() == data: + return + + with open(file, 'w', encoding="utf-8") as fp: + fp.write(data) def main(): parser = argparse.ArgumentParser(description=''' @@ -878,8 +886,17 @@ def main(): cmake = "" sysbuild_kconfig = "" sysbuild_cmake = "" - settings = "" twister = "" + settings = '''\ +# WARNING. THIS FILE IS AUTO-GENERATED. DO NOT MODIFY! +# +# This file contains build system settings derived from your modules. +# +# Modules may be set via ZEPHYR_MODULES, ZEPHYR_EXTRA_MODULES, +# and/or the west manifest file. +# +# See the Modules guide for more information. +''' west_projs = west_projects() modules = parse_modules(args.zephyr_base, None, west_projs, @@ -907,54 +924,34 @@ def main(): kconfig_module_dirs_cmake_out = PurePath(args.sysbuild_kconfig_out).parent / \ 'kconfig_module_dirs.cmake' - with open(kconfig_module_dirs_out, 'w', encoding="utf-8") as fp: - fp.write(kconfig_module_dirs) - - with open(kconfig_module_dirs_cmake_out, 'w', encoding="utf-8") as fp: - fp.write(kconfig_module_dirs_cmake) + write_if_different(kconfig_module_dirs_out, kconfig_module_dirs) + write_if_different(kconfig_module_dirs_cmake_out, kconfig_module_dirs_cmake) if args.kconfig_out: - with open(args.kconfig_out, 'w', encoding="utf-8") as fp: - fp.write(kconfig) + write_if_different(args.kconfig_out, kconfig) if args.cmake_out: - with open(args.cmake_out, 'w', encoding="utf-8") as fp: - fp.write(cmake) + write_if_different(args.cmake_out, cmake) if args.sysbuild_kconfig_out: - with open(args.sysbuild_kconfig_out, 'w', encoding="utf-8") as fp: - fp.write(sysbuild_kconfig) + write_if_different(args.sysbuild_kconfig_out, sysbuild_kconfig) if args.sysbuild_cmake_out: - with open(args.sysbuild_cmake_out, 'w', encoding="utf-8") as fp: - fp.write(sysbuild_cmake) + write_if_different(args.sysbuild_cmake_out, sysbuild_cmake) if args.settings_out: - with open(args.settings_out, 'w', encoding="utf-8") as fp: - fp.write('''\ -# WARNING. THIS FILE IS AUTO-GENERATED. DO NOT MODIFY! -# -# This file contains build system settings derived from your modules. -# -# Modules may be set via ZEPHYR_MODULES, ZEPHYR_EXTRA_MODULES, -# and/or the west manifest file. -# -# See the Modules guide for more information. -''') - fp.write(settings) + write_if_different(args.settings_out, settings) if args.twister_out: - with open(args.twister_out, 'w', encoding="utf-8") as fp: - fp.write(twister) + write_if_different(args.twister_out, twister) if args.meta_out: meta = process_meta(args.zephyr_base, west_projs, modules, args.extra_modules, args.meta_state_propagate) - with open(args.meta_out, 'w', encoding="utf-8") as fp: - # Ignore references and insert data instead - yaml.Dumper.ignore_aliases = lambda self, data: True - fp.write(yaml.dump(meta)) + # Ignore references and insert data instead + yaml.Dumper.ignore_aliases = lambda self, data: True + write_if_different(args.meta_out, yaml.dump(meta)) if __name__ == "__main__": From 1dc0e167e302c10e5eabd83dd3eb78697ed462eb Mon Sep 17 00:00:00 2001 From: Jisheng Zhang Date: Sat, 1 Nov 2025 00:08:14 +0800 Subject: [PATCH 0300/3659] dts: arm: renesas: Add DTCM and ITCM nodes for RA8D1 Add DTCM and ITCM for RA8D1. Signed-off-by: Jisheng Zhang --- dts/arm/renesas/ra/ra8/r7fa8d1xh.dtsi | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/dts/arm/renesas/ra/ra8/r7fa8d1xh.dtsi b/dts/arm/renesas/ra/ra8/r7fa8d1xh.dtsi index e6dae81f7480..5cf4e71d92cc 100644 --- a/dts/arm/renesas/ra/ra8/r7fa8d1xh.dtsi +++ b/dts/arm/renesas/ra/ra8/r7fa8d1xh.dtsi @@ -10,6 +10,18 @@ / { soc { + itcm: memory@0 { + compatible = "zephyr,memory-region", "arm,itcm"; + reg = <0x0 DT_SIZE_K(64)>; + zephyr,memory-region = "ITCM"; + }; + + dtcm: memory@20000000 { + compatible = "zephyr,memory-region", "arm,dtcm"; + reg = <0x20000000 DT_SIZE_K(64)>; + zephyr,memory-region = "DTCM"; + }; + lcdif: display-controller@40342000 { compatible = "renesas,ra-glcdc"; reg = <0x40342000 0x1454>; From d2ec1c35a0fe4943c7f231a9503c654a8e862145 Mon Sep 17 00:00:00 2001 From: Jisheng Zhang Date: Sat, 1 Nov 2025 00:09:32 +0800 Subject: [PATCH 0301/3659] boards: renesas: Add CPKCOR-RA8D1B board support Add CPKCOR-RA8D1B board support. Tested uart, button, led, sdram, tfcard and usbhs. Signed-off-by: Jisheng Zhang --- boards/renesas/cpkcor_ra8d1b/CMakeLists.txt | 7 + .../cpkcor_ra8d1b/Kconfig.cpkcor_ra8d1b | 5 + boards/renesas/cpkcor_ra8d1b/board.cmake | 8 + boards/renesas/cpkcor_ra8d1b/board.yml | 6 + .../cpkcor_ra8d1b/cpkcor_ra8d1b-pinctrl.dtsi | 109 ++++++++ .../renesas/cpkcor_ra8d1b/cpkcor_ra8d1b.dts | 251 ++++++++++++++++++ .../renesas/cpkcor_ra8d1b/cpkcor_ra8d1b.yaml | 16 ++ .../cpkcor_ra8d1b/cpkcor_ra8d1b_defconfig | 11 + boards/renesas/cpkcor_ra8d1b/doc/index.rst | 76 ++++++ boards/renesas/cpkcor_ra8d1b/sdram.ld | 16 ++ 10 files changed, 505 insertions(+) create mode 100644 boards/renesas/cpkcor_ra8d1b/CMakeLists.txt create mode 100644 boards/renesas/cpkcor_ra8d1b/Kconfig.cpkcor_ra8d1b create mode 100644 boards/renesas/cpkcor_ra8d1b/board.cmake create mode 100644 boards/renesas/cpkcor_ra8d1b/board.yml create mode 100644 boards/renesas/cpkcor_ra8d1b/cpkcor_ra8d1b-pinctrl.dtsi create mode 100644 boards/renesas/cpkcor_ra8d1b/cpkcor_ra8d1b.dts create mode 100644 boards/renesas/cpkcor_ra8d1b/cpkcor_ra8d1b.yaml create mode 100644 boards/renesas/cpkcor_ra8d1b/cpkcor_ra8d1b_defconfig create mode 100644 boards/renesas/cpkcor_ra8d1b/doc/index.rst create mode 100644 boards/renesas/cpkcor_ra8d1b/sdram.ld diff --git a/boards/renesas/cpkcor_ra8d1b/CMakeLists.txt b/boards/renesas/cpkcor_ra8d1b/CMakeLists.txt new file mode 100644 index 000000000000..6e7e11bab968 --- /dev/null +++ b/boards/renesas/cpkcor_ra8d1b/CMakeLists.txt @@ -0,0 +1,7 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +zephyr_include_directories(.) + +zephyr_linker_sources_ifdef(CONFIG_MEMC + SECTIONS sdram.ld) diff --git a/boards/renesas/cpkcor_ra8d1b/Kconfig.cpkcor_ra8d1b b/boards/renesas/cpkcor_ra8d1b/Kconfig.cpkcor_ra8d1b new file mode 100644 index 000000000000..beb8a0b0c1cf --- /dev/null +++ b/boards/renesas/cpkcor_ra8d1b/Kconfig.cpkcor_ra8d1b @@ -0,0 +1,5 @@ +# Copyright (c) 2025 Jisheng Zhang +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_CPKCOR_RA8D1B + select SOC_R7FA8D1BHECBD diff --git a/boards/renesas/cpkcor_ra8d1b/board.cmake b/boards/renesas/cpkcor_ra8d1b/board.cmake new file mode 100644 index 000000000000..06ba0e171694 --- /dev/null +++ b/boards/renesas/cpkcor_ra8d1b/board.cmake @@ -0,0 +1,8 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(jlink "--device=R7FA8D1BH") +board_runner_args(pyocd "--target=R7FA8D1BH") + +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) +include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake) diff --git a/boards/renesas/cpkcor_ra8d1b/board.yml b/boards/renesas/cpkcor_ra8d1b/board.yml new file mode 100644 index 000000000000..ac660c9a7803 --- /dev/null +++ b/boards/renesas/cpkcor_ra8d1b/board.yml @@ -0,0 +1,6 @@ +board: + name: cpkcor_ra8d1b + full_name: CPKCOR RA8D1B board + vendor: renesas + socs: + - name: r7fa8d1bhecbd diff --git a/boards/renesas/cpkcor_ra8d1b/cpkcor_ra8d1b-pinctrl.dtsi b/boards/renesas/cpkcor_ra8d1b/cpkcor_ra8d1b-pinctrl.dtsi new file mode 100644 index 000000000000..343e04b15695 --- /dev/null +++ b/boards/renesas/cpkcor_ra8d1b/cpkcor_ra8d1b-pinctrl.dtsi @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * Copyright (c) 2025 Jisheng Zhang + * SPDX-License-Identifier: Apache-2.0 + */ + +&pinctrl { + sci3_default: sci3_default { + group1 { + /* tx */ + psels = ; + drive-strength = "medium"; + }; + + group2 { + /* rx */ + psels = ; + }; + }; + + usbhs_default: usbhs_default { + group1 { + psels = ; /* USBHS-VBUS */ + drive-strength = "high"; + }; + }; + + adc0_default: adc0_default { + group1 { + /* input */ + psels = ; + renesas,analog-enable; + }; + }; + + dac0_default: dac0_default { + group1 { + /* output */ + psels = ; + renesas,analog-enable; + }; + }; + + sdram_default: sdram_default { + group1 { + psels = , /* SDRAM_A1 */ + , /* SDRAM_A2 */ + , /* SDRAM_A3 */ + , /* SDRAM_A4 */ + , /* SDRAM_A5 */ + , /* SDRAM_A6 */ + , /* SDRAM_A7 */ + , /* SDRAM_A8 */ + , /* SDRAM_A9 */ + , /* SDRAM_A10 */ + , /* SDRAM_A11 */ + , /* SDRAM_A12 */ + , /* SDRAM_A13 */ + , /* SDRAM_A14 */ + , /* SDRAM_A15 */ + , /* SDRAM_CAS */ + , /* SDRAM_CKE */ + , /* SDRAM_DQ0 */ + , /* SDRAM_DQ1 */ + , /* SDRAM_DQ2 */ + , /* SDRAM_DQ3 */ + , /* SDRAM_DQ4 */ + , /* SDRAM_DQ5 */ + , /* SDRAM_DQ6 */ + , /* SDRAM_DQ7 */ + , /* SDRAM_DQ8 */ + , /* SDRAM_DQ9 */ + , /* SDRAM_DQ10 */ + , /* SDRAM_DQ11 */ + , /* SDRAM_DQ12 */ + , /* SDRAM_DQ13 */ + , /* SDRAM_DQ14 */ + , /* SDRAM_DQ15 */ + , /* SDRAM_DQM0 */ + , /* SDRAM_DQM1 */ + , /* SDRAM_RAS */ + , /* SDRAM_SDCS */ + ; /* SDRAM_WE */ + drive-strength = "high"; + }; + + group2 { + psels = ; /* SDRAM_SDCLK */ + drive-strength = "highspeed-high"; + }; + }; + + sdhc1_default: sdhc1_default { + group1 { + psels = , /* SDCD */ + , /* SDCMD */ + , /* SDDATA0 */ + , /* SDDATA1 */ + , /* SDDATA2 */ + ; /* SDDATA3 */ + drive-strength = "high"; + }; + + group2 { + psels = ; /* SDCLK */ + drive-strength = "highspeed-high"; + }; + }; +}; diff --git a/boards/renesas/cpkcor_ra8d1b/cpkcor_ra8d1b.dts b/boards/renesas/cpkcor_ra8d1b/cpkcor_ra8d1b.dts new file mode 100644 index 000000000000..dd1d5cdfb073 --- /dev/null +++ b/boards/renesas/cpkcor_ra8d1b/cpkcor_ra8d1b.dts @@ -0,0 +1,251 @@ +/* + * Copyright (c) 2025 Jisheng Zhang + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include +#include +#include +#include +#include +#include "cpkcor_ra8d1b-pinctrl.dtsi" + +/ { + model = "Renesas CPKCOR-RA8D1B"; + compatible = "renesas,ra8d1", "renesas,ra8"; + + chosen { + zephyr,sram = &sram0; + zephyr,flash = &flash0; + zephyr,itcm = &itcm; + zephyr,dtcm = &dtcm; + zephyr,console = &uart3; + zephyr,shell-uart = &uart3; + zephyr,entropy = &trng; + zephyr,flash-controller = &flash; + zephyr,crc = &crc; + }; + + leds { + compatible = "gpio-leds"; + + led0: led0 { + gpios = <&ioporta 1 GPIO_ACTIVE_HIGH>; + label = "LED1"; + }; + }; + + buttons { + compatible = "gpio-keys"; + + button0: s1 { + gpios = <&ioport0 8 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "User Button"; + zephyr,code = ; + }; + }; + + sdram1: sdram@68000000 { + compatible = "zephyr,memory-region", "mmio-sram"; + device_type = "memory"; + reg = <0x68000000 DT_SIZE_M(32)>; /* 256 Mbits */ + zephyr,memory-region = "SDRAM"; + status = "okay"; + }; + + aliases { + led0 = &led0; + sw0 = &button0; + watchdog0 = &wdt; + sdhc0 = &sdhc1; + }; +}; + +&xtal { + clock-frequency = ; + mosel = <0>; + #clock-cells = <0>; + status = "okay"; +}; + +&subclk { + status = "okay"; +}; + +&pll { + status = "okay"; + div = <4>; + mul = <160 0>; + + pllp { + status = "okay"; + }; + + pllq { + div = <4>; + freq = ; + status = "okay"; + }; + + pllr { + status = "okay"; + }; +}; + +&pll2 { + status = "okay"; + clocks = <&xtal>; + div = <3>; + mul = <100 0>; + + pll2p { + status = "okay"; + freq = ; + div = <4>; + }; +}; + +&sciclk { + clocks = <&pllp>; + div = <4>; + status = "okay"; +}; + +&uclk { + clocks = <&pllq>; + div = <5>; + status = "okay"; +}; + +&ioport0 { + status = "okay"; +}; + +&ioporta { + status = "okay"; +}; + +&sci3 { + pinctrl-0 = <&sci3_default>; + pinctrl-names = "default"; + status = "okay"; + + uart3: uart { + current-speed = <115200>; + status = "okay"; + }; +}; + +&trng { + status = "okay"; +}; + +&flash1 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + storage_partition: partition@0 { + label = "storage"; + reg = <0X0 DT_SIZE_K(12)>; + }; + }; +}; + +&usbhs { + pinctrl-0 = <&usbhs_default>; + pinctrl-names = "default"; + maximum-speed = "high-speed"; + status = "okay"; + + zephyr_udc0: udc { + status = "okay"; + }; +}; + +&usbhs_phy { + phys-clock-src = "xtal"; +}; + +&adc0 { + status = "okay"; + pinctrl-0 = <&adc0_default>; + pinctrl-names = "default"; +}; + +&dac0 { + pinctrl-0 = <&dac0_default>; + pinctrl-names = "default"; + status = "okay"; +}; + +&port_irq12 { + interrupts = <88 12>; + status = "okay"; +}; + +&sdram { + pinctrl-0 = <&sdram_default>; + pinctrl-names = "default"; + status = "okay"; + auto-refresh-interval = ; + auto-refresh-count = ; + precharge-cycle-count = ; + multiplex-addr-shift = "8-bit"; + edian-mode = "little-endian"; + continuous-access; + bus-width = "16-bit"; + + bank@0 { + reg = <0>; + renesas,ra-sdram-timing = ; + }; +}; + +&wdt { + status = "okay"; +}; + +&ulpt0 { + status = "okay"; + + timer { + status = "okay"; + }; +}; + +&ulpt1 { + status = "okay"; + + timer { + status = "okay"; + }; +}; + +&crc { + status = "okay"; +}; + +&sdhc1 { + pinctrl-names = "default"; + interrupt-names = "accs", "card", "dma-req"; + interrupts = <60 12>, <61 12>, <62 12>; + pinctrl-0 = <&sdhc1_default>; + status = "okay"; + + sdmmc { + compatible = "zephyr,sdmmc-disk"; + disk-name = "SD"; + status = "okay"; + }; +}; diff --git a/boards/renesas/cpkcor_ra8d1b/cpkcor_ra8d1b.yaml b/boards/renesas/cpkcor_ra8d1b/cpkcor_ra8d1b.yaml new file mode 100644 index 000000000000..4315fcda698b --- /dev/null +++ b/boards/renesas/cpkcor_ra8d1b/cpkcor_ra8d1b.yaml @@ -0,0 +1,16 @@ +identifier: cpkcor_ra8d1b +name: Renesas CPKCOR-RA8D1B +type: mcu +arch: arm +ram: 1024 +flash: 2016 +toolchain: + - zephyr + - gnuarmemb +supported: + - gpio + - uart + - watchdog + - usbd + - memc +vendor: renesas diff --git a/boards/renesas/cpkcor_ra8d1b/cpkcor_ra8d1b_defconfig b/boards/renesas/cpkcor_ra8d1b/cpkcor_ra8d1b_defconfig new file mode 100644 index 000000000000..1b679557be4e --- /dev/null +++ b/boards/renesas/cpkcor_ra8d1b/cpkcor_ra8d1b_defconfig @@ -0,0 +1,11 @@ +# Copyright (c) 2025 Jisheng Zhang +# SPDX-License-Identifier: Apache-2.0 + +# Enable GPIO +CONFIG_GPIO=y + +# Enable Console +CONFIG_SERIAL=y +CONFIG_UART_CONSOLE=y +CONFIG_UART_INTERRUPT_DRIVEN=y +CONFIG_CONSOLE=y diff --git a/boards/renesas/cpkcor_ra8d1b/doc/index.rst b/boards/renesas/cpkcor_ra8d1b/doc/index.rst new file mode 100644 index 000000000000..3c15ca8076ea --- /dev/null +++ b/boards/renesas/cpkcor_ra8d1b/doc/index.rst @@ -0,0 +1,76 @@ +.. zephyr:board:: cpkcor_ra8d1b + +Overview +******** + +The CPKCOR-RA8D1B, based on the Renesas Cortex-M85 architecture RA8D1 chip, offers engineers a convenient evelopment platform for study, evaluation and development. + +Key Features + +- Arm Cortex-M85 +- 480MHz frequency, on-chip 2MB Flash, 1MB SRAM +- 32MB-SDRAM +- 16MB-QSPI Flash +- TF card slot +- USB2.0 high speed host/device controller via. Type-C interface + +More information about the board can be found at the `CPKCOR-RA8D1B website`_. + +Hardware +******** +Detailed Hardware features for the RA8D1 MCU group can be found at `RA8D1 Group User's Manual Hardware`_ + +Supported Features +================== + +.. zephyr:board-supported-hw:: + +Programming and Debugging +************************* + +.. zephyr:board-supported-runners:: + +Applications for the ``cpkcor_ra8d1b`` board can be +built, flashed, and debugged in the usual way. See +:ref:`build_an_application` and :ref:`application_run` for more details on +building and running. + +**Note:** Only support from SDK v0.16.6 in which GCC for Cortex Arm-M85 was available. +To build for CPKCOR-RA8D1B user need to get and install GNU Arm Embedded toolchain from https://github.com/zephyrproject-rtos/sdk-ng/releases/tag/v0.16.6 + +Flashing +======== + +Program can be flashed to CPKCOR-RA8D1B via the on-board SEGGER J-Link debugger. + +To flash the program to board + +1. Connect to J-LINK OB via USB port to host PC + +2. Execute west command + + .. code-block:: console + + west flash + +Debugging +========= + +You can debug an application in the usual way. Here is an example for the +:zephyr:code-sample:`hello_world` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: cpkcor_ra8d1b + :maybe-skip-config: + :goals: debug + +References +********** +.. target-notes:: + +.. _CPKCOR-RA8D1B Website: + https://github.com/renesas/cpk_examples/blob/main/cpkcor_ra8d1b + +.. _RA8D1 Group User's Manual Hardware: + https://www.renesas.com/us/en/document/mah/ra8d1-group-users-manual-hardware diff --git a/boards/renesas/cpkcor_ra8d1b/sdram.ld b/boards/renesas/cpkcor_ra8d1b/sdram.ld new file mode 100644 index 000000000000..fc0e4d4fd759 --- /dev/null +++ b/boards/renesas/cpkcor_ra8d1b/sdram.ld @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(sdram1), okay) + +SECTION_DATA_PROLOGUE(.sdram,(NOLOAD),) +{ + __SDRAM_Start = .; + KEEP(*(.sdram*)) + __SDRAM_End = .; +} GROUP_LINK_IN(SDRAM) + +#endif From b2d7055de9837358dee8dd7a59848b009e6040d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomas=20Gudelevi=C4=8Dius?= Date: Fri, 31 Oct 2025 12:24:13 +0200 Subject: [PATCH 0302/3659] drivers: modem: cellular: reinit modem after script failures MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If the modem reboots or stops responding to AT commands while in RUN_DIAL, AWAIT_REGISTERED, or CARRIER_ON, the modem_cellular state machine could previously dead-end. Applications had to recover by manually issuing device PM suspend/resume. This change adds an internal recovery path: after repeated chat/script failures in the states above, the driver resets the state to INIT, and posts an immediate RESUME event. This allows the initialization sequence to run again and restores connectivity, including after unexpected modem reboots. No API changes; behavior only differs in failure scenarios. Signed-off-by: Tomas Gudelevičius --- drivers/modem/modem_cellular.c | 62 +++++++++++++++++++++++++++++++--- 1 file changed, 57 insertions(+), 5 deletions(-) diff --git a/drivers/modem/modem_cellular.c b/drivers/modem/modem_cellular.c index 652758f45388..a166ecdfe058 100644 --- a/drivers/modem/modem_cellular.c +++ b/drivers/modem/modem_cellular.c @@ -42,6 +42,8 @@ LOG_MODULE_REGISTER(modem_cellular, CONFIG_MODEM_LOG_LEVEL); #define MODEM_CELLULAR_MAX_APN_CMDS (2) #define MODEM_CELLULAR_APN_BUF_SIZE (64) +#define MODEM_CELLULAR_MAX_SCRIPT_FAILURES (3) + /* Magic constants */ #define CSQ_RSSI_UNKNOWN (99) #define CESQ_RSRP_UNKNOWN (255) @@ -135,6 +137,7 @@ struct modem_cellular_data { uint8_t *chat_delimiter; uint8_t *chat_filter; uint8_t *chat_argv[32]; + uint8_t script_failure_counter; /* Status */ enum cellular_registration_status registration_status_gsm; @@ -1299,6 +1302,25 @@ static void modem_cellular_run_apn_script_event_handler(struct modem_cellular_da } } +static void modem_cellular_script_failed(struct modem_cellular_data *data) +{ + data->script_failure_counter++; +} + +static void modem_cellular_script_success(struct modem_cellular_data *data) +{ + data->script_failure_counter = 0; +} + +static bool modem_cellular_is_script_retry_exceeded(struct modem_cellular_data *data) +{ + if (data->script_failure_counter >= MODEM_CELLULAR_MAX_SCRIPT_FAILURES) { + data->script_failure_counter = 0; + return true; + } + return false; +} + static int modem_cellular_on_run_dial_script_state_enter(struct modem_cellular_data *data) { modem_cellular_start_timer(data, K_NO_WAIT); @@ -1317,9 +1339,16 @@ static void modem_cellular_run_dial_script_event_handler(struct modem_cellular_d modem_chat_run_script_async(&data->chat, config->dial_chat_script); break; case MODEM_CELLULAR_EVENT_SCRIPT_FAILED: - modem_cellular_start_timer(data, MODEM_CELLULAR_PERIODIC_SCRIPT_TIMEOUT); + modem_cellular_script_failed(data); + if (modem_cellular_is_script_retry_exceeded(data)) { + modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_IDLE); + modem_cellular_delegate_event(data, MODEM_CELLULAR_EVENT_RESUME); + } else { + modem_cellular_start_timer(data, MODEM_CELLULAR_PERIODIC_SCRIPT_TIMEOUT); + } break; case MODEM_CELLULAR_EVENT_SCRIPT_SUCCESS: + modem_cellular_script_success(data); modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_AWAIT_REGISTERED); break; @@ -1359,10 +1388,20 @@ static void modem_cellular_await_registered_event_handler(struct modem_cellular_ switch (evt) { case MODEM_CELLULAR_EVENT_SCRIPT_SUCCESS: - case MODEM_CELLULAR_EVENT_SCRIPT_FAILED: + modem_cellular_script_success(data); modem_cellular_start_timer(data, MODEM_CELLULAR_PERIODIC_SCRIPT_TIMEOUT); break; + case MODEM_CELLULAR_EVENT_SCRIPT_FAILED: + modem_cellular_script_failed(data); + if (modem_cellular_is_script_retry_exceeded(data)) { + modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_IDLE); + modem_cellular_delegate_event(data, MODEM_CELLULAR_EVENT_RESUME); + } else { + modem_cellular_start_timer(data, MODEM_CELLULAR_PERIODIC_SCRIPT_TIMEOUT); + } + break; + case MODEM_CELLULAR_EVENT_TIMEOUT: modem_chat_run_script_async(&data->chat, config->periodic_chat_script); break; @@ -1405,10 +1444,23 @@ static void modem_cellular_carrier_on_event_handler(struct modem_cellular_data * switch (evt) { case MODEM_CELLULAR_EVENT_SCRIPT_SUCCESS: - case MODEM_CELLULAR_EVENT_SCRIPT_FAILED: - result.success = evt == MODEM_CELLULAR_EVENT_SCRIPT_SUCCESS; - + modem_cellular_script_success(data); modem_cellular_start_timer(data, MODEM_CELLULAR_PERIODIC_SCRIPT_TIMEOUT); + result.success = true; + modem_cellular_emit_event(data, CELLULAR_EVENT_MODEM_COMMS_CHECK_RESULT, &result); + break; + + case MODEM_CELLULAR_EVENT_SCRIPT_FAILED: + modem_cellular_script_failed(data); + if (modem_cellular_is_script_retry_exceeded(data)) { + net_if_carrier_off(modem_ppp_get_iface(data->ppp)); + modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_IDLE); + modem_cellular_delegate_event(data, MODEM_CELLULAR_EVENT_RESUME); + LOG_WRN("Maximum script failures reached, restarting modem"); + } else { + modem_cellular_start_timer(data, MODEM_CELLULAR_PERIODIC_SCRIPT_TIMEOUT); + } + result.success = false; modem_cellular_emit_event(data, CELLULAR_EVENT_MODEM_COMMS_CHECK_RESULT, &result); break; From 24c510ec54e5cd0012edd6a7625abc150177af16 Mon Sep 17 00:00:00 2001 From: Jason He Date: Fri, 18 Jul 2025 17:15:29 +0900 Subject: [PATCH 0303/3659] drivers: clock: mcux_ccm: add USB clock control support Add USB_CLK and USB_PHY_CLK support for NXP EHCI controller on MIMX9352. Signed-off-by: Jason He Signed-off-by: Jiafei Pan Signed-off-by: Jony Zhang --- drivers/clock_control/clock_control_mcux_ccm_rev2.c | 6 ++++++ include/zephyr/dt-bindings/clock/imx_ccm_rev2.h | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/drivers/clock_control/clock_control_mcux_ccm_rev2.c b/drivers/clock_control/clock_control_mcux_ccm_rev2.c index fc5ed7876691..c8a5fe7196cf 100644 --- a/drivers/clock_control/clock_control_mcux_ccm_rev2.c +++ b/drivers/clock_control/clock_control_mcux_ccm_rev2.c @@ -454,6 +454,12 @@ static int CCM_SET_FUNC_ATTR mcux_ccm_set_subsys_rate(const struct device *dev, return 0; #endif +#if defined(CONFIG_UDC_NXP_EHCI) && defined(CONFIG_SOC_MIMX9352_A55) + case IMX_CCM_USB_CLK: + case IMX_CCM_USB_PHY_CLK: + return common_clock_set_freq(clock_name, (uint32_t)clock_rate); +#endif + default: /* Silence unused variable warning */ ARG_UNUSED(clock_rate); diff --git a/include/zephyr/dt-bindings/clock/imx_ccm_rev2.h b/include/zephyr/dt-bindings/clock/imx_ccm_rev2.h index 6fdd477aa78a..8ca2b172d1fd 100644 --- a/include/zephyr/dt-bindings/clock/imx_ccm_rev2.h +++ b/include/zephyr/dt-bindings/clock/imx_ccm_rev2.h @@ -159,6 +159,10 @@ /* KPP */ #define IMX_CCM_KPP_CLK 0x2400UL +/* USB */ +#define IMX_CCM_USB_CLK 0x2500UL +#define IMX_CCM_USB_PHY_CLK 0x2600UL + /* QTMR */ #define IMX_CCM_QTMR_CLK 0x6000UL #define IMX_CCM_QTMR1_CLK 0x6000UL From 02c808f3908cbcb1f3cdd1d340a17ff6fd3d7737 Mon Sep 17 00:00:00 2001 From: Jiafei Pan Date: Fri, 12 Sep 2025 16:59:48 +0800 Subject: [PATCH 0304/3659] modules: hal_nxp: fix camke for sdk-ng middleware As middleware.cmake could be included by mcux-sdk's CMakeLists.txt, so use CMAKE_CURRENT_LIST_DIR to make sure the directory is correct. Signed-off-by: Jiafei Pan Signed-off-by: Jony Zhang --- .../hal_nxp/mcux/mcux-sdk-ng/middleware/middleware.cmake | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/hal_nxp/mcux/mcux-sdk-ng/middleware/middleware.cmake b/modules/hal_nxp/mcux/mcux-sdk-ng/middleware/middleware.cmake index 12a1e2ce2920..2bf1bfa84f86 100644 --- a/modules/hal_nxp/mcux/mcux-sdk-ng/middleware/middleware.cmake +++ b/modules/hal_nxp/mcux/mcux-sdk-ng/middleware/middleware.cmake @@ -13,7 +13,7 @@ if(CONFIG_USB_DEVICE_DRIVER) set_variable_ifdef(CONFIG_USB_DC_NXP_LPCIP3511 CONFIG_MCUX_COMPONENT_middleware.usb.device.ip3511fs) # For soc.c build pass - zephyr_include_directories(.) + zephyr_include_directories(${CMAKE_CURRENT_LIST_DIR}) zephyr_include_directories(${MCUX_SDK_NG_DIR}/middleware/usb/device) zephyr_include_directories(${MCUX_SDK_NG_DIR}/middleware/usb/phy) zephyr_include_directories(${MCUX_SDK_NG_DIR}/middleware/usb/include) @@ -30,7 +30,7 @@ if(CONFIG_UDC_DRIVER) set_variable_ifdef(CONFIG_UDC_NXP_IP3511 CONFIG_MCUX_COMPONENT_middleware.usb.device.ip3511fs) # For soc.c build pass - zephyr_include_directories(.) + zephyr_include_directories(${CMAKE_CURRENT_LIST_DIR}) zephyr_include_directories(${MCUX_SDK_NG_DIR}/middleware/usb/device) zephyr_include_directories(${MCUX_SDK_NG_DIR}/middleware/usb/phy) zephyr_include_directories(${MCUX_SDK_NG_DIR}/middleware/usb/include) @@ -47,7 +47,7 @@ if(CONFIG_UHC_DRIVER) set_variable_ifdef(CONFIG_UHC_NXP_OHCI CONFIG_MCUX_COMPONENT_middleware.usb.host.ohci) set_variable_ifdef(CONFIG_UHC_NXP_IP3516HS CONFIG_MCUX_COMPONENT_middleware.usb.host.ip3516hs) # For soc.c build pass - zephyr_include_directories(.) + zephyr_include_directories(${CMAKE_CURRENT_LIST_DIR}) zephyr_include_directories(${MCUX_SDK_NG_DIR}/middleware/usb/phy) zephyr_include_directories(${MCUX_SDK_NG_DIR}/middleware/usb/include) endif() From c2b7ae10e6df42cc4dd0c01b9ffd10370bbdbd20 Mon Sep 17 00:00:00 2001 From: Jason He Date: Fri, 18 Jul 2025 17:15:58 +0900 Subject: [PATCH 0305/3659] drivers: usb: mcux_ehci: add clock control for i.MX 93 family Support device tree specified clock rates for USB controller and PHY. Signed-off-by: Jason He Signed-off-by: Jiafei Pan Signed-off-by: Jony Zhang --- drivers/usb/udc/udc_mcux_ehci.c | 52 +++++++++++++++++++++++++++++++-- dts/bindings/usb/nxp,ehci.yaml | 7 ++++- 2 files changed, 56 insertions(+), 3 deletions(-) diff --git a/drivers/usb/udc/udc_mcux_ehci.c b/drivers/usb/udc/udc_mcux_ehci.c index 2212debd2509..58661c2ec8f6 100644 --- a/drivers/usb/udc/udc_mcux_ehci.c +++ b/drivers/usb/udc/udc_mcux_ehci.c @@ -1,19 +1,21 @@ /* - * Copyright 2024 NXP + * Copyright 2024-2025 NXP * * SPDX-License-Identifier: Apache-2.0 */ #define DT_DRV_COMPAT nxp_ehci -#include #include #include +#include +#include #include #include #include #include #include +#include #include "udc_common.h" #include "usb.h" @@ -44,6 +46,12 @@ struct udc_mcux_config { uintptr_t base; const struct pinctrl_dev_config *pincfg; usb_phy_config_struct_t *phy_config; + const struct device *clock_dev; + clock_control_subsys_t clock_subsys; + clock_control_subsys_rate_t clock_rate; + const struct device *phy_clock_dev; + clock_control_subsys_t phy_clock_subsys; + clock_control_subsys_rate_t phy_clock_rate; }; struct udc_mcux_data { @@ -777,6 +785,22 @@ static int udc_mcux_driver_preinit(const struct device *dev) return -ENOMEM; } + if (config->clock_dev && config->clock_rate) { + clock_control_set_rate( + config->clock_dev, + config->clock_subsys, + config->clock_rate + ); + } + + if (config->phy_clock_dev && config->phy_clock_rate) { + clock_control_set_rate( + config->phy_clock_dev, + config->phy_clock_subsys, + config->phy_clock_rate + ); + } + k_mutex_init(&data->mutex); k_fifo_init(&priv->fifo); k_work_init(&priv->work, udc_mcux_work_handler); @@ -859,6 +883,28 @@ static const usb_device_controller_interface_struct_t udc_mcux_if = { USB_DeviceEhciRecv, USB_DeviceEhciCancel, USB_DeviceEhciControl }; +#define UDC_MCUX_USB_CLK_DEFINE(n) \ + .clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR_BY_IDX(n, 0)), \ + .clock_subsys = (clock_control_subsys_t) \ + DT_INST_CLOCKS_CELL_BY_IDX(n, 0, name), \ + .clock_rate = (void *)(uintptr_t)DT_INST_PROP_BY_IDX(n, clock_rates, 0), + +#define UDC_MCUX_USB_CLK_DEFINE_OR(n) \ + IF_ENABLED(DT_INST_CLOCKS_HAS_IDX(n, 0), \ + (IF_ENABLED(DT_INST_PROP_HAS_IDX(n, clock_rates, 0), \ + (UDC_MCUX_USB_CLK_DEFINE(n))))) + +#define UDC_MCUX_USB_PHY_CLK_DEFINE(n) \ + .phy_clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR_BY_IDX(n, 1)), \ + .phy_clock_subsys = (clock_control_subsys_t) \ + DT_INST_CLOCKS_CELL_BY_IDX(n, 1, name), \ + .phy_clock_rate = (void *)(uintptr_t)DT_INST_PROP_BY_IDX(n, clock_rates, 1), + +#define UDC_MCUX_USB_PHY_CLK_DEFINE_OR(n) \ + IF_ENABLED(DT_INST_CLOCKS_HAS_IDX(n, 1), \ + (IF_ENABLED(DT_INST_PROP_HAS_IDX(n, clock_rates, 1), \ + (UDC_MCUX_USB_PHY_CLK_DEFINE(n))))) + #define UDC_MCUX_PHY_DEFINE(n) \ static usb_phy_config_struct_t phy_config_##n = { \ .D_CAL = DT_PROP_OR(DT_INST_PHANDLE(n, phy_handle), tx_d_cal, 0), \ @@ -913,6 +959,8 @@ static usb_phy_config_struct_t phy_config_##n = { \ .mcux_if = &udc_mcux_if, \ .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ .phy_config = UDC_MCUX_PHY_CFG_PTR_OR_NULL(n), \ + UDC_MCUX_USB_CLK_DEFINE_OR(n) \ + UDC_MCUX_USB_PHY_CLK_DEFINE_OR(n) \ }; \ \ static struct udc_mcux_data priv_data_##n = { \ diff --git a/dts/bindings/usb/nxp,ehci.yaml b/dts/bindings/usb/nxp,ehci.yaml index de4c8f25cba0..366548ab8c00 100644 --- a/dts/bindings/usb/nxp,ehci.yaml +++ b/dts/bindings/usb/nxp,ehci.yaml @@ -1,4 +1,4 @@ -# Copyright 2023 NXP +# Copyright 2023,2025 NXP # SPDX-License-Identifier: Apache-2.0 description: NXP EHCI USB device mode @@ -10,3 +10,8 @@ include: "nxp,mcux-usbd.yaml" properties: phy-handle: type: phandle + + clock-rates: + type: array + description: | + Optional rate given to each clock provider in the "clocks" property. From ddb3acfb746470a5e4d729f188576ff495caa3d6 Mon Sep 17 00:00:00 2001 From: Jony Zhang Date: Fri, 21 Nov 2025 20:46:55 +0800 Subject: [PATCH 0306/3659] drivers: usb: mcux_ehci: add MMIO configuration for i.MX 93 family The original driver is only feasible for M-Core, but for Cortex-A Core, it need to do MMU mapping to map physical address to virtual address, to the main update is to add MMIO mapping in this driver, and all the register access should use virtual address. Replace direct base address access with DEVICE_MMIO_NAMED_* macros to provide better memory mapping abstraction and improve platform portability. This change: - Adds DEVICE_MMIO_NAMED_ROM/RAM to config and data structures - Maps the register base address during driver pre-initialization - Updates all base address references to use DEVICE_MMIO_NAMED_GET - Maintains backward compatibility with existing functionality The DEVICE_MMIO API provides a standardized way to handle memory-mapped registers across different platforms and memory protection schemes. Signed-off-by: Jason He Signed-off-by: Jiafei Pan Signed-off-by: Jony Zhang --- drivers/usb/udc/udc_mcux_ehci.c | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/drivers/usb/udc/udc_mcux_ehci.c b/drivers/usb/udc/udc_mcux_ehci.c index 58661c2ec8f6..d586435c0fea 100644 --- a/drivers/usb/udc/udc_mcux_ehci.c +++ b/drivers/usb/udc/udc_mcux_ehci.c @@ -36,6 +36,10 @@ LOG_MODULE_REGISTER(udc_mcux, CONFIG_UDC_DRIVER_LOG_LEVEL); #define PRV_DATA_HANDLE(_handle) CONTAINER_OF(_handle, struct udc_mcux_data, mcux_device) +/* Required by DEVICE_MMIO_NAMED_* macros */ +#define DEV_CFG(_dev) ((const struct udc_mcux_config *)(_dev)->config) +#define DEV_DATA(_dev) ((struct udc_mcux_data *)(udc_get_private(_dev))) + struct udc_mcux_config { const usb_device_controller_interface_struct_t *mcux_if; void (*irq_enable_func)(const struct device *dev); @@ -43,7 +47,7 @@ struct udc_mcux_config { size_t num_of_eps; struct udc_ep_config *ep_cfg_in; struct udc_ep_config *ep_cfg_out; - uintptr_t base; + DEVICE_MMIO_NAMED_ROM(reg_base); const struct pinctrl_dev_config *pincfg; usb_phy_config_struct_t *phy_config; const struct device *clock_dev; @@ -55,6 +59,7 @@ struct udc_mcux_config { }; struct udc_mcux_data { + DEVICE_MMIO_NAMED_RAM(reg_base); const struct device *dev; usb_device_struct_t mcux_device; struct k_work work; @@ -698,11 +703,14 @@ static int udc_mcux_init(const struct device *dev) const usb_device_controller_interface_struct_t *mcux_if = config->mcux_if; struct udc_mcux_data *priv = udc_get_private(dev); usb_status_t status; + uintptr_t base; if (priv->controller_id == 0xFFu) { return -ENOMEM; } + base = (uintptr_t)DEVICE_MMIO_NAMED_GET(dev, reg_base); + #ifdef CONFIG_DT_HAS_NXP_USBPHY_ENABLED if (config->phy_config != NULL) { USB_EhciPhyInit(priv->controller_id, 0u, config->phy_config); @@ -717,7 +725,7 @@ static int udc_mcux_init(const struct device *dev) } if (!IS_ENABLED(CONFIG_UDC_DRIVER_HIGH_SPEED_SUPPORT_ENABLED)) { - USBHS_Type *usbBase = (USBHS_Type *)config->base; + USBHS_Type *usbBase = (USBHS_Type *)base; usbBase->PORTSC1 |= USBHS_PORTSC1_PFSC_MASK; } @@ -725,7 +733,7 @@ static int udc_mcux_init(const struct device *dev) /* enable USB interrupt */ config->irq_enable_func(dev); - LOG_DBG("Initialized USB controller %x", (uint32_t)config->base); + LOG_DBG("Initialized USB controller %x", (uint32_t)base); return 0; } @@ -749,9 +757,14 @@ static int udc_mcux_shutdown(const struct device *dev) return 0; } -static inline void udc_mcux_get_hal_driver_id(struct udc_mcux_data *priv, - const struct udc_mcux_config *config) +static inline void udc_mcux_get_hal_driver_id(const struct device *dev) { + struct udc_data *data = dev->data; + struct udc_mcux_data *priv = data->priv; + uintptr_t base; + + base = (uintptr_t)DEVICE_MMIO_NAMED_GET(dev, reg_base); + /* * MCUX USB controller drivers use an ID to tell the HAL drivers * which controller is being used. This part of the code converts @@ -766,7 +779,7 @@ static inline void udc_mcux_get_hal_driver_id(struct udc_mcux_data *priv, /* get the right controller id */ priv->controller_id = 0xFFu; /* invalid value */ for (uint8_t i = 0; i < ARRAY_SIZE(usb_base_addrs); i++) { - if (usb_base_addrs[i] == config->base) { + if (usb_base_addrs[i] == base) { priv->controller_id = kUSB_ControllerEhci0 + i; break; } @@ -780,7 +793,9 @@ static int udc_mcux_driver_preinit(const struct device *dev) struct udc_mcux_data *priv = data->priv; int err; - udc_mcux_get_hal_driver_id(priv, config); + DEVICE_MMIO_NAMED_MAP(dev, reg_base, K_MEM_CACHE_NONE | K_MEM_DIRECT_MAP); + + udc_mcux_get_hal_driver_id(dev); if (priv->controller_id == 0xFFu) { return -ENOMEM; } @@ -950,7 +965,7 @@ static usb_phy_config_struct_t phy_config_##n = { \ PINCTRL_DT_INST_DEFINE(n); \ \ static struct udc_mcux_config priv_config_##n = { \ - .base = DT_INST_REG_ADDR(n), \ + DEVICE_MMIO_NAMED_ROM_INIT(reg_base, DT_DRV_INST(n)), \ .irq_enable_func = udc_irq_enable_func##n, \ .irq_disable_func = udc_irq_disable_func##n, \ .num_of_eps = DT_INST_PROP(n, num_bidir_endpoints), \ From 89d3de81e67b4aa8b6704f39c4dd7de92a40d99a Mon Sep 17 00:00:00 2001 From: Jason He Date: Fri, 18 Jul 2025 18:26:19 +0900 Subject: [PATCH 0307/3659] boards: frdm_imx93: enable USB support Add EHCI controller configuration with dual USB instances (USB1/USB2), device tree bindings, 8 bidirectional endpoints, and UDC workqueue stack optimization for frdm_imx93 A55 platform. Signed-off-by: Jason He Signed-off-by: Jiafei Pan Signed-off-by: Jony Zhang --- boards/nxp/frdm_imx93/Kconfig.defconfig | 3 +++ .../frdm_imx93/frdm_imx93_mimx9352_a55.dts | 4 +++ .../frdm_imx93/frdm_imx93_mimx9352_a55.yaml | 1 + dts/arm64/nxp/nxp_mimx93_a55.dtsi | 26 +++++++++++++++++++ 4 files changed, 34 insertions(+) diff --git a/boards/nxp/frdm_imx93/Kconfig.defconfig b/boards/nxp/frdm_imx93/Kconfig.defconfig index fc59366b9114..04a10d3bedc7 100644 --- a/boards/nxp/frdm_imx93/Kconfig.defconfig +++ b/boards/nxp/frdm_imx93/Kconfig.defconfig @@ -42,6 +42,9 @@ configdefault NET_MGMT_EVENT_STACK_SIZE configdefault NET_SOCKETS_SERVICE_STACK_SIZE default 8192 +configdefault UDC_WORKQUEUE_STACK_SIZE + default 4096 + endif # BOARD_FRDM_IMX93_MIMX9352_A55 if IMX_USDHC diff --git a/boards/nxp/frdm_imx93/frdm_imx93_mimx9352_a55.dts b/boards/nxp/frdm_imx93/frdm_imx93_mimx9352_a55.dts index fd6ee72e88ae..59cb63e558b9 100644 --- a/boards/nxp/frdm_imx93/frdm_imx93_mimx9352_a55.dts +++ b/boards/nxp/frdm_imx93/frdm_imx93_mimx9352_a55.dts @@ -227,3 +227,7 @@ }; display_i2c: &lpi2c1 {}; + +zephyr_udc0: &usb1 { + status = "okay"; +}; diff --git a/boards/nxp/frdm_imx93/frdm_imx93_mimx9352_a55.yaml b/boards/nxp/frdm_imx93/frdm_imx93_mimx9352_a55.yaml index c9f4df5f8189..a4a76f58a5ce 100644 --- a/boards/nxp/frdm_imx93/frdm_imx93_mimx9352_a55.yaml +++ b/boards/nxp/frdm_imx93/frdm_imx93_mimx9352_a55.yaml @@ -21,6 +21,7 @@ supported: - can - net - watchdog + - usbd testing: ignore_tags: - bluetooth diff --git a/dts/arm64/nxp/nxp_mimx93_a55.dtsi b/dts/arm64/nxp/nxp_mimx93_a55.dtsi index 31305b51f203..79f1f1c2692e 100644 --- a/dts/arm64/nxp/nxp_mimx93_a55.dtsi +++ b/dts/arm64/nxp/nxp_mimx93_a55.dtsi @@ -617,6 +617,32 @@ prescaler = <1>; status = "disabled"; }; + + usb1: usbd@4c100000 { + compatible = "nxp,ehci"; + reg = <0x4c100000 DT_SIZE_K(4)>; + interrupts = ; + interrupt-names = "usb_0"; + interrupt-parent = <&gic>; + clocks = <&ccm IMX_CCM_USB_CLK 2 3>, + <&ccm IMX_CCM_USB_PHY_CLK 2 8>; + clock-rates = <134000000 50000000>; + num-bidir-endpoints = <8>; + status = "disabled"; + }; + + usb2: usbd@4c200000 { + compatible = "nxp,ehci"; + reg = <0x4c200000 DT_SIZE_K(4)>; + interrupts = ; + interrupt-names = "usb_1"; + interrupt-parent = <&gic>; + clocks = <&ccm IMX_CCM_USB_CLK 2 3>, + <&ccm IMX_CCM_USB_PHY_CLK 2 8>; + clock-rates = <134000000 50000000>; + num-bidir-endpoints = <8>; + status = "disabled"; + }; }; &gpio1 { From 5741f3ee6be6283886e48577be5473de5f3c144d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Ma=C5=A1karinec?= Date: Thu, 10 Jul 2025 09:53:42 +0200 Subject: [PATCH 0308/3659] drivers: tmag5273: Add mag gain property MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds mag-gain-correction DT property, which sets the magnetic gain correction value. Previously a property to select the channel for gain correction existed, but there was no way to configure the correction value itself. Signed-off-by: Marek Maškarinec --- drivers/sensor/ti/tmag5273/tmag5273.c | 9 +++++++++ dts/bindings/sensor/ti,tmag5273.yaml | 12 ++++++++++++ 2 files changed, 21 insertions(+) diff --git a/drivers/sensor/ti/tmag5273/tmag5273.c b/drivers/sensor/ti/tmag5273/tmag5273.c index d3711da69442..1330901d4eae 100644 --- a/drivers/sensor/ti/tmag5273/tmag5273.c +++ b/drivers/sensor/ti/tmag5273/tmag5273.c @@ -58,6 +58,7 @@ struct tmag5273_config { uint8_t temperature_coefficient; uint8_t angle_magnitude_axis; uint8_t ch_mag_gain_correction; + uint8_t mag_gain_correction; uint8_t operation_mode; uint8_t averaging; @@ -1075,6 +1076,13 @@ static inline int tmag5273_init_sensor_settings(const struct tmag5273_config *dr return -EIO; } + retval = i2c_reg_write_byte_dt(&drv_cfg->i2c, TMAG5273_REG_MAG_GAIN_CONFIG, + drv_cfg->mag_gain_correction); + if (retval < 0) { + LOG_ERR("error setting MAG_GAIN_CONFIG %d", retval); + return -EIO; + } + return 0; } @@ -1258,6 +1266,7 @@ static DEVICE_API(sensor, tmag5273_driver_api) = { DT_PROP(DT_INST(inst, compat), temperature_coefficient), \ .angle_magnitude_axis = DT_PROP(DT_INST(inst, compat), angle_magnitude_axis), \ .ch_mag_gain_correction = DT_PROP(DT_INST(inst, compat), ch_mag_gain_correction), \ + .mag_gain_correction = DT_PROP(DT_INST(inst, compat), mag_gain_correction), \ .operation_mode = DT_PROP(DT_INST(inst, compat), operation_mode), \ .averaging = DT_PROP(DT_INST(inst, compat), average_mode), \ .trigger_conv_via_int = \ diff --git a/dts/bindings/sensor/ti,tmag5273.yaml b/dts/bindings/sensor/ti,tmag5273.yaml index 76f5eefe8d0b..f6b6a1767a56 100644 --- a/dts/bindings/sensor/ti,tmag5273.yaml +++ b/dts/bindings/sensor/ti,tmag5273.yaml @@ -134,6 +134,18 @@ properties: Only active if angle-magnitude-calculation is active. + mag-gain-correction: + type: int + default: 0 + description: | + Gain value for axis determined by ch-mag-gain-correction. + + The value is between 0 and 255, interpreted as a fractional + value between 0 and 1 (mag-gain-correction/256). Gain value of 0 + is interpreted as 1. + + The default corresponds to the reset value of the register field. + average-mode: type: int default: 1 From 9ece57491b349ecea155dbafc9826cd533039e05 Mon Sep 17 00:00:00 2001 From: Julien Vermillard Date: Wed, 10 Dec 2025 18:30:08 +0100 Subject: [PATCH 0309/3659] boards: holyiot: support holyiot 21014 Add support fot the holyiot 21014 board. BLE 5.0 module based on NRF52810. Signed-off-by: Julien Vermillard --- .../holyiot_21014/Kconfig.holyiot_21014 | 7 ++ boards/holyiot/holyiot_21014/board.cmake | 2 + boards/holyiot/holyiot_21014/board.yml | 6 + .../holyiot_21014/doc/img/holyiot_21014.webp | Bin 0 -> 17824 bytes boards/holyiot/holyiot_21014/doc/index.rst | 66 ++++++++++ .../holyiot_21014/holyiot_21014-pinctrl.dtsi | 23 ++++ .../holyiot/holyiot_21014/holyiot_21014.dts | 117 ++++++++++++++++++ .../holyiot/holyiot_21014/holyiot_21014.yaml | 13 ++ .../holyiot_21014/holyiot_21014_defconfig | 13 ++ .../holyiot/holyiot_21014/pre_dt_board.cmake | 7 ++ 10 files changed, 254 insertions(+) create mode 100644 boards/holyiot/holyiot_21014/Kconfig.holyiot_21014 create mode 100644 boards/holyiot/holyiot_21014/board.cmake create mode 100644 boards/holyiot/holyiot_21014/board.yml create mode 100644 boards/holyiot/holyiot_21014/doc/img/holyiot_21014.webp create mode 100644 boards/holyiot/holyiot_21014/doc/index.rst create mode 100644 boards/holyiot/holyiot_21014/holyiot_21014-pinctrl.dtsi create mode 100644 boards/holyiot/holyiot_21014/holyiot_21014.dts create mode 100644 boards/holyiot/holyiot_21014/holyiot_21014.yaml create mode 100644 boards/holyiot/holyiot_21014/holyiot_21014_defconfig create mode 100644 boards/holyiot/holyiot_21014/pre_dt_board.cmake diff --git a/boards/holyiot/holyiot_21014/Kconfig.holyiot_21014 b/boards/holyiot/holyiot_21014/Kconfig.holyiot_21014 new file mode 100644 index 000000000000..b786816171b6 --- /dev/null +++ b/boards/holyiot/holyiot_21014/Kconfig.holyiot_21014 @@ -0,0 +1,7 @@ +# Holyiot 21014 board configuration + +# SPDX-FileCopyrightText: Copyright (c) 2025 Clunky Machines +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_HOLYIOT_21014 + select SOC_NRF52810_QFAA diff --git a/boards/holyiot/holyiot_21014/board.cmake b/boards/holyiot/holyiot_21014/board.cmake new file mode 100644 index 000000000000..ef7fbcbfe6e2 --- /dev/null +++ b/boards/holyiot/holyiot_21014/board.cmake @@ -0,0 +1,2 @@ +board_runner_args(jlink "--device=nRF52810_xxAA" "--speed=4000") +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/holyiot/holyiot_21014/board.yml b/boards/holyiot/holyiot_21014/board.yml new file mode 100644 index 000000000000..bac106d76683 --- /dev/null +++ b/boards/holyiot/holyiot_21014/board.yml @@ -0,0 +1,6 @@ +board: + name: holyiot_21014 + full_name: 21014 Module + vendor: holyiot + socs: + - name: nrf52810 diff --git a/boards/holyiot/holyiot_21014/doc/img/holyiot_21014.webp b/boards/holyiot/holyiot_21014/doc/img/holyiot_21014.webp new file mode 100644 index 0000000000000000000000000000000000000000..a985584a7eea1b8dfaed271fdd6c08ba8fe1306f GIT binary patch literal 17824 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 DAhMAj literal 0 HcmV?d00001 diff --git a/boards/holyiot/holyiot_21014/doc/index.rst b/boards/holyiot/holyiot_21014/doc/index.rst new file mode 100644 index 000000000000..5611ef5a54a5 --- /dev/null +++ b/boards/holyiot/holyiot_21014/doc/index.rst @@ -0,0 +1,66 @@ +.. zephyr:board:: holyiot_21014 + +Overview +******** + +The Holyiot_ 21014 module is built around the Nordic Semiconductor +`nRF52810`_ Arm Cortex-M4 SoC with 192 KiB of flash and 24 KiB of RAM. The +module have one user button and an RGB LED. + +.. figure:: img/holyiot_21014.webp + :align: center + :alt: Holyiot 21014 module + + Holyiot 21014 module + +Supported Features +================== + +.. zephyr:board-supported-hw:: + +Connections and IOs +=================== + +* Button: ``P0.31`` +* RGB LED: ``P0.29`` (red), ``P0.30`` (green), ``P0.28`` (blue) +* SPI0: ``P0.5`` (SCK), ``P0.2`` (MOSI), ``P0.3`` (MISO) + +Programming and Debugging +************************* + +.. zephyr:board-supported-runners:: + +The board must be programmed using an external SWD probe (for example, a Segger +J-Link) connected to the SWDIO, SWCLK, VDD, and GND pads. + +Flashing +======== + +Follow the instructions in the :ref:`nordic_segger` page to install and +configure the required software. Then build and flash applications as usual +(see :ref:`build_an_application` and :ref:`application_run` for more details). + +Here is an example for the :zephyr:code-sample:`blinky` application: + +.. zephyr-app-commands:: + :zephyr-app: samples/basic/blinky + :board: holyiot_21014 + :goals: build flash + +Testing the LED and button +========================== + +You can test the board peripherals with the following samples: + +.. code-block:: console + + samples/basic/blinky + samples/basic/button + +References +********** + +.. target-notes:: + +.. _Holyiot: http://www.holyiot.com +.. _nRF52810: https://www.nordicsemi.com/Products/Low-power-short-range-wireless/nRF52810 diff --git a/boards/holyiot/holyiot_21014/holyiot_21014-pinctrl.dtsi b/boards/holyiot/holyiot_21014/holyiot_21014-pinctrl.dtsi new file mode 100644 index 000000000000..50f5c3762cf4 --- /dev/null +++ b/boards/holyiot/holyiot_21014/holyiot_21014-pinctrl.dtsi @@ -0,0 +1,23 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2025 Clunky Machines + * SPDX-License-Identifier: Apache-2.0 + */ + +&pinctrl { + spi0_default: spi0_default { + group1 { + psels = , + , + ; + }; + }; + + spi0_sleep: spi0_sleep { + group1 { + psels = , + , + ; + low-power-enable; + }; + }; +}; diff --git a/boards/holyiot/holyiot_21014/holyiot_21014.dts b/boards/holyiot/holyiot_21014/holyiot_21014.dts new file mode 100644 index 000000000000..8d423e6617a8 --- /dev/null +++ b/boards/holyiot/holyiot_21014/holyiot_21014.dts @@ -0,0 +1,117 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2025 Clunky Machines + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include "holyiot_21014-pinctrl.dtsi" +#include + +/ { + model = "Holyiot 21014"; + compatible = "holyiot,21014"; + + chosen { + zephyr,sram = &sram0; + zephyr,flash = &flash0; + zephyr,code-partition = &slot0_partition; + }; + + buttons { + compatible = "gpio-keys"; + + button0: button_0 { + gpios = <&gpio0 31 GPIO_ACTIVE_HIGH>; + label = "Push button switch 0"; + zephyr,code = ; + }; + }; + + leds { + compatible = "gpio-leds"; + + led0_red: led_0 { + gpios = <&gpio0 29 GPIO_ACTIVE_LOW>; + label = "Red LED 0"; + }; + + led0_green: led_1 { + gpios = <&gpio0 30 GPIO_ACTIVE_LOW>; + label = "Green LED 0"; + }; + + led0_blue: led_2 { + gpios = <&gpio0 28 GPIO_ACTIVE_LOW>; + label = "Blue LED 0"; + }; + }; + + aliases { + led0 = &led0_red; + led1 = &led0_green; + led2 = &led0_blue; + led0-red = &led0_red; + led0-green = &led0_green; + led0-blue = &led0_blue; + sw0 = &button0; + watchdog0 = &wdt0; + }; +}; + +® { + regulator-initial-mode = ; +}; + +&adc { + status = "okay"; +}; + +&gpiote { + status = "okay"; +}; + +&gpio0 { + status = "okay"; +}; + +&uicr { + gpio-as-nreset; +}; + +&spi0 { + compatible = "nordic,nrf-spi"; + status = "okay"; + pinctrl-0 = <&spi0_default>; + pinctrl-1 = <&spi0_sleep>; + pinctrl-names = "default", "sleep"; +}; + +&flash0 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 0x0000c000>; + }; + + slot0_partition: partition@c000 { + label = "image-0"; + reg = <0x0000c000 0x0000f000>; + }; + + slot1_partition: partition@1b000 { + label = "image-1"; + reg = <0x0001b000 0x0000f000>; + }; + + storage_partition: partition@2a000 { + label = "storage"; + reg = <0x0002a000 0x00006000>; + }; + }; +}; diff --git a/boards/holyiot/holyiot_21014/holyiot_21014.yaml b/boards/holyiot/holyiot_21014/holyiot_21014.yaml new file mode 100644 index 000000000000..dd72f8cbef28 --- /dev/null +++ b/boards/holyiot/holyiot_21014/holyiot_21014.yaml @@ -0,0 +1,13 @@ +identifier: holyiot_21014 +name: Holyiot 21014 +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb +supported: + - counter + - gpio +ram: 24 +flash: 192 +vendor: holyiot diff --git a/boards/holyiot/holyiot_21014/holyiot_21014_defconfig b/boards/holyiot/holyiot_21014/holyiot_21014_defconfig new file mode 100644 index 000000000000..cee867613f06 --- /dev/null +++ b/boards/holyiot/holyiot_21014/holyiot_21014_defconfig @@ -0,0 +1,13 @@ +# SPDX-License-Identifier: Apache-2.0 + +# 32kHz clock source +CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC=y + +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable RTT +CONFIG_USE_SEGGER_RTT=y + +# Enable GPIO +CONFIG_GPIO=y diff --git a/boards/holyiot/holyiot_21014/pre_dt_board.cmake b/boards/holyiot/holyiot_21014/pre_dt_board.cmake new file mode 100644 index 000000000000..3369c21d3af5 --- /dev/null +++ b/boards/holyiot/holyiot_21014/pre_dt_board.cmake @@ -0,0 +1,7 @@ +# Copyright (c) 2022 Nordic Semiconductor +# SPDX-License-Identifier: Apache-2.0 + +# Suppress "unique_unit_address_if_enabled" to handle the following overlaps: +# - power@40000000 & clock@40000000 & bprot@40000000 +# - acl@4001e000 & flash-controller@4001e000 +list(APPEND EXTRA_DTC_FLAGS "-Wno-unique_unit_address_if_enabled") From 0d4517a8ef14e0c6859ae75f860eb4d72a1160a9 Mon Sep 17 00:00:00 2001 From: Camille BAUD Date: Wed, 10 Dec 2025 18:08:18 +0100 Subject: [PATCH 0310/3659] tests: build_all: display: clear up logic platform_exclude not necessary Signed-off-by: Camille BAUD --- tests/drivers/build_all/display/testcase.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/drivers/build_all/display/testcase.yaml b/tests/drivers/build_all/display/testcase.yaml index 07061a17eebc..efc7de08a461 100644 --- a/tests/drivers/build_all/display/testcase.yaml +++ b/tests/drivers/build_all/display/testcase.yaml @@ -10,8 +10,6 @@ tests: integration_platforms: - native_sim - native_sim/native/64 - platform_exclude: - - ai_m62_12f_kit drivers.display.build.rk055hdmipi4ma0: platform_allow: From d8f67d777bdc034feba3ffe83a06d552c0590ea9 Mon Sep 17 00:00:00 2001 From: Camille BAUD Date: Wed, 10 Dec 2025 18:08:57 +0100 Subject: [PATCH 0311/3659] tests: build_all: display: rename bflb dbi m62 overlay Forgot to update the file name in PR changing naming Signed-off-by: Camille BAUD --- .../display/boards/{ai_m62_12f.overlay => ai_m62_12f_kit.overlay} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename tests/drivers/build_all/display/boards/{ai_m62_12f.overlay => ai_m62_12f_kit.overlay} (100%) diff --git a/tests/drivers/build_all/display/boards/ai_m62_12f.overlay b/tests/drivers/build_all/display/boards/ai_m62_12f_kit.overlay similarity index 100% rename from tests/drivers/build_all/display/boards/ai_m62_12f.overlay rename to tests/drivers/build_all/display/boards/ai_m62_12f_kit.overlay From 3b15324eac55d962cbd7dd3ac48dea6ced807ea0 Mon Sep 17 00:00:00 2001 From: Aksel Skauge Mellbye Date: Wed, 10 Dec 2025 13:31:43 +0100 Subject: [PATCH 0312/3659] samples: drivers: uart: async_api: Add overlays for silabs boards Add overlays enabling DMA for Silabs boards to enable use of the async API on the default shell uart. Signed-off-by: Aksel Skauge Mellbye --- .../uart/async_api/boards/bg29_rb4420a.overlay | 15 +++++++++++++++ .../uart/async_api/boards/slwrb4182a.overlay | 15 +++++++++++++++ .../uart/async_api/boards/slwrb4311a.overlay | 15 +++++++++++++++ .../uart/async_api/boards/xg24_rb4186c.overlay | 15 +++++++++++++++ .../uart/async_api/boards/xg24_rb4187c.overlay | 15 +++++++++++++++ .../uart/async_api/boards/xg27_rb4194a.overlay | 15 +++++++++++++++ .../uart/async_api/boards/xg29_rb4412a.overlay | 15 +++++++++++++++ 7 files changed, 105 insertions(+) create mode 100644 samples/drivers/uart/async_api/boards/bg29_rb4420a.overlay create mode 100644 samples/drivers/uart/async_api/boards/slwrb4182a.overlay create mode 100644 samples/drivers/uart/async_api/boards/slwrb4311a.overlay create mode 100644 samples/drivers/uart/async_api/boards/xg24_rb4186c.overlay create mode 100644 samples/drivers/uart/async_api/boards/xg24_rb4187c.overlay create mode 100644 samples/drivers/uart/async_api/boards/xg27_rb4194a.overlay create mode 100644 samples/drivers/uart/async_api/boards/xg29_rb4412a.overlay diff --git a/samples/drivers/uart/async_api/boards/bg29_rb4420a.overlay b/samples/drivers/uart/async_api/boards/bg29_rb4420a.overlay new file mode 100644 index 000000000000..e2c563243a16 --- /dev/null +++ b/samples/drivers/uart/async_api/boards/bg29_rb4420a.overlay @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2025 Silicon Laboratories Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&dma0 { + status = "okay"; +}; + +&usart1 { + dmas = <&dma0 DMA_REQSEL_USART1TXBL>, + <&dma0 DMA_REQSEL_USART1RXDATAV>; + dma-names = "tx", "rx"; +}; diff --git a/samples/drivers/uart/async_api/boards/slwrb4182a.overlay b/samples/drivers/uart/async_api/boards/slwrb4182a.overlay new file mode 100644 index 000000000000..e2c563243a16 --- /dev/null +++ b/samples/drivers/uart/async_api/boards/slwrb4182a.overlay @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2025 Silicon Laboratories Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&dma0 { + status = "okay"; +}; + +&usart1 { + dmas = <&dma0 DMA_REQSEL_USART1TXBL>, + <&dma0 DMA_REQSEL_USART1RXDATAV>; + dma-names = "tx", "rx"; +}; diff --git a/samples/drivers/uart/async_api/boards/slwrb4311a.overlay b/samples/drivers/uart/async_api/boards/slwrb4311a.overlay new file mode 100644 index 000000000000..e2c563243a16 --- /dev/null +++ b/samples/drivers/uart/async_api/boards/slwrb4311a.overlay @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2025 Silicon Laboratories Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&dma0 { + status = "okay"; +}; + +&usart1 { + dmas = <&dma0 DMA_REQSEL_USART1TXBL>, + <&dma0 DMA_REQSEL_USART1RXDATAV>; + dma-names = "tx", "rx"; +}; diff --git a/samples/drivers/uart/async_api/boards/xg24_rb4186c.overlay b/samples/drivers/uart/async_api/boards/xg24_rb4186c.overlay new file mode 100644 index 000000000000..6473330b83cd --- /dev/null +++ b/samples/drivers/uart/async_api/boards/xg24_rb4186c.overlay @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2025 Silicon Laboratories Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&dma0 { + status = "okay"; +}; + +&usart0 { + dmas = <&dma0 DMA_REQSEL_USART0TXBL>, + <&dma0 DMA_REQSEL_USART0RXDATAV>; + dma-names = "tx", "rx"; +}; diff --git a/samples/drivers/uart/async_api/boards/xg24_rb4187c.overlay b/samples/drivers/uart/async_api/boards/xg24_rb4187c.overlay new file mode 100644 index 000000000000..6473330b83cd --- /dev/null +++ b/samples/drivers/uart/async_api/boards/xg24_rb4187c.overlay @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2025 Silicon Laboratories Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&dma0 { + status = "okay"; +}; + +&usart0 { + dmas = <&dma0 DMA_REQSEL_USART0TXBL>, + <&dma0 DMA_REQSEL_USART0RXDATAV>; + dma-names = "tx", "rx"; +}; diff --git a/samples/drivers/uart/async_api/boards/xg27_rb4194a.overlay b/samples/drivers/uart/async_api/boards/xg27_rb4194a.overlay new file mode 100644 index 000000000000..e2c563243a16 --- /dev/null +++ b/samples/drivers/uart/async_api/boards/xg27_rb4194a.overlay @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2025 Silicon Laboratories Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&dma0 { + status = "okay"; +}; + +&usart1 { + dmas = <&dma0 DMA_REQSEL_USART1TXBL>, + <&dma0 DMA_REQSEL_USART1RXDATAV>; + dma-names = "tx", "rx"; +}; diff --git a/samples/drivers/uart/async_api/boards/xg29_rb4412a.overlay b/samples/drivers/uart/async_api/boards/xg29_rb4412a.overlay new file mode 100644 index 000000000000..e2c563243a16 --- /dev/null +++ b/samples/drivers/uart/async_api/boards/xg29_rb4412a.overlay @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2025 Silicon Laboratories Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&dma0 { + status = "okay"; +}; + +&usart1 { + dmas = <&dma0 DMA_REQSEL_USART1TXBL>, + <&dma0 DMA_REQSEL_USART1RXDATAV>; + dma-names = "tx", "rx"; +}; From 94212fb6657023c1ccfa2281844410925ce94482 Mon Sep 17 00:00:00 2001 From: Aksel Skauge Mellbye Date: Wed, 10 Dec 2025 11:43:17 +0100 Subject: [PATCH 0313/3659] samples: driver: counter: Fix silabs timer name The Counter alarm sample contains a hard-coded list of devicetree nodes to use. Since the definition of the counter node was changed on Series 2 devices in #97912, this sample hasn't compiled. Update the sample to select the correct devicetree node, and add representative boards to platform_allow to allow the sample to be tested on Series 2 boards. Signed-off-by: Aksel Skauge Mellbye --- boards/silabs/radio_boards/xg29_rb4412a/xg29_rb4412a.yaml | 1 + samples/drivers/counter/alarm/sample.yaml | 4 ++++ samples/drivers/counter/alarm/src/main.c | 5 ++++- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/boards/silabs/radio_boards/xg29_rb4412a/xg29_rb4412a.yaml b/boards/silabs/radio_boards/xg29_rb4412a/xg29_rb4412a.yaml index dbb61719e50a..454c7c807ff5 100644 --- a/boards/silabs/radio_boards/xg29_rb4412a/xg29_rb4412a.yaml +++ b/boards/silabs/radio_boards/xg29_rb4412a/xg29_rb4412a.yaml @@ -11,6 +11,7 @@ supported: - adc - bluetooth - comparator + - counter - dma - entropy - gpio diff --git a/samples/drivers/counter/alarm/sample.yaml b/samples/drivers/counter/alarm/sample.yaml index 1b4c34b9146f..064284aa4887 100644 --- a/samples/drivers/counter/alarm/sample.yaml +++ b/samples/drivers/counter/alarm/sample.yaml @@ -49,6 +49,10 @@ tests: - s32z2xxdc2@D/s32z270/rtu0 - s32z2xxdc2@D/s32z270/rtu1 - lp_em_cc2340r5 + - slwrb4180b + - xg24_rb4187c + - xg27_rb4194a + - xg29_rb4412a integration_platforms: - nucleo_f746zg sample.drivers.counter.alarm.stm32_rtc: diff --git a/samples/drivers/counter/alarm/src/main.c b/samples/drivers/counter/alarm/src/main.c index 11b2e760115e..c0ba6a65ae51 100644 --- a/samples/drivers/counter/alarm/src/main.c +++ b/samples/drivers/counter/alarm/src/main.c @@ -48,7 +48,10 @@ struct counter_alarm_cfg alarm_cfg; #elif defined(CONFIG_COUNTER_GECKO_RTCC) #define TIMER DT_NODELABEL(rtcc0) #elif defined(CONFIG_COUNTER_GECKO_STIMER) -#define TIMER DT_NODELABEL(stimer0) +#ifdef TIMER +#undef TIMER +#endif +#define TIMER DT_CHOSEN(silabs_sleeptimer) #elif defined(CONFIG_COUNTER_INFINEON_CAT1) || defined(CONFIG_COUNTER_INFINEON_TCPWM) #define TIMER DT_NODELABEL(counter0_0) #elif defined(CONFIG_COUNTER_AMBIQ) From 44627801a366998485229f47183e4832b69b6e5a Mon Sep 17 00:00:00 2001 From: Aksel Skauge Mellbye Date: Wed, 10 Dec 2025 09:26:16 +0100 Subject: [PATCH 0314/3659] boards: silabs: Enable PWM on boards with PWM configuration xg24_dk2601b and bg22_ek4108a has PWM configuration in Devicetree, but didn't enable PWM for testing. xg24_dk2601b has RGB LEDs, add aliases to enable the rgb_led sample. Signed-off-by: Aksel Skauge Mellbye --- boards/silabs/dev_kits/xg24_dk2601b/xg24_dk2601b.dts | 3 +++ boards/silabs/dev_kits/xg24_dk2601b/xg24_dk2601b.yaml | 1 + boards/silabs/explorer_kits/xg22/bg22_ek4108a.yaml | 1 + 3 files changed, 5 insertions(+) diff --git a/boards/silabs/dev_kits/xg24_dk2601b/xg24_dk2601b.dts b/boards/silabs/dev_kits/xg24_dk2601b/xg24_dk2601b.dts index 3d30acb7e2be..42fec3949ed9 100644 --- a/boards/silabs/dev_kits/xg24_dk2601b/xg24_dk2601b.dts +++ b/boards/silabs/dev_kits/xg24_dk2601b/xg24_dk2601b.dts @@ -32,6 +32,9 @@ pwm-led0 = &red_pwm_led; pwm-led1 = &green_pwm_led; pwm-led2 = &blue_pwm_led; + red-pwm-led = &red_pwm_led; + green-pwm-led = &green_pwm_led; + blue-pwm-led = &blue_pwm_led; sw0 = &button0; sw1 = &button1; watchdog0 = &wdog0; diff --git a/boards/silabs/dev_kits/xg24_dk2601b/xg24_dk2601b.yaml b/boards/silabs/dev_kits/xg24_dk2601b/xg24_dk2601b.yaml index 70aa8f626389..4ccec71e88e5 100644 --- a/boards/silabs/dev_kits/xg24_dk2601b/xg24_dk2601b.yaml +++ b/boards/silabs/dev_kits/xg24_dk2601b/xg24_dk2601b.yaml @@ -18,6 +18,7 @@ supported: - comparator - adc - dac + - pwm testing: ignore_tags: - pm diff --git a/boards/silabs/explorer_kits/xg22/bg22_ek4108a.yaml b/boards/silabs/explorer_kits/xg22/bg22_ek4108a.yaml index 69df78c02778..f5a80d8d4423 100644 --- a/boards/silabs/explorer_kits/xg22/bg22_ek4108a.yaml +++ b/boards/silabs/explorer_kits/xg22/bg22_ek4108a.yaml @@ -18,6 +18,7 @@ supported: - i2c - dma - spi + - pwm testing: ignore_tags: - pm From 5be58ab5439feddc71c799cbcd737bd99bd536fa Mon Sep 17 00:00:00 2001 From: Aksel Skauge Mellbye Date: Wed, 10 Dec 2025 10:30:12 +0100 Subject: [PATCH 0315/3659] boards: silabs: Add pwm-leds configuration Add PWM configuration on boards that have LEDs, but were missing a definition of pwm-leds. Signed-off-by: Aksel Skauge Mellbye --- .../dev_kits/sltb010a/sltb010a-pinctrl.dtsi | 8 ++++++ boards/silabs/dev_kits/sltb010a/sltb010a.dts | 1 + .../silabs/dev_kits/sltb010a/sltb010a_0.yaml | 1 + .../dev_kits/sltb010a/sltb010a_2.overlay | 4 +++ .../silabs/dev_kits/sltb010a/sltb010a_2.yaml | 1 + .../dev_kits/sltb010a/thunderboard.dtsi | 20 ++++++++++++++ .../xg24_ek2703a/xg24_ek2703a-pinctrl.dtsi | 8 ++++++ .../dev_kits/xg24_ek2703a/xg24_ek2703a.dts | 27 +++++++++++++++++++ .../dev_kits/xg24_ek2703a/xg24_ek2703a.yaml | 1 + .../dev_kits/xg27_dk2602a/thunderboard.dtsi | 20 ++++++++++++++ .../xg27_dk2602a/xg27_dk2602a-pinctrl.dtsi | 8 ++++++ .../dev_kits/xg27_dk2602a/xg27_dk2602a.dts | 1 + .../dev_kits/xg27_dk2602a/xg27_dk2602a.yaml | 1 + 13 files changed, 101 insertions(+) diff --git a/boards/silabs/dev_kits/sltb010a/sltb010a-pinctrl.dtsi b/boards/silabs/dev_kits/sltb010a/sltb010a-pinctrl.dtsi index 9e930284b12e..f3ead2b73760 100644 --- a/boards/silabs/dev_kits/sltb010a/sltb010a-pinctrl.dtsi +++ b/boards/silabs/dev_kits/sltb010a/sltb010a-pinctrl.dtsi @@ -23,6 +23,14 @@ }; }; + timer0_default: timer0_default { + group0 { + pins = ; + drive-push-pull; + output-high; + }; + }; + usart0_default: usart0_default { group0 { pins = , ; diff --git a/boards/silabs/dev_kits/sltb010a/sltb010a.dts b/boards/silabs/dev_kits/sltb010a/sltb010a.dts index 602ef95af048..8e94c86a297a 100644 --- a/boards/silabs/dev_kits/sltb010a/sltb010a.dts +++ b/boards/silabs/dev_kits/sltb010a/sltb010a.dts @@ -14,6 +14,7 @@ /* These aliases are provided for compatibility with samples */ aliases { led0 = &led0; + pwm-led0 = &pwm_led0; spi0 = &usart0; sw0 = &button0; watchdog0 = &wdog0; diff --git a/boards/silabs/dev_kits/sltb010a/sltb010a_0.yaml b/boards/silabs/dev_kits/sltb010a/sltb010a_0.yaml index fd679198dc93..a68baea8cc69 100644 --- a/boards/silabs/dev_kits/sltb010a/sltb010a_0.yaml +++ b/boards/silabs/dev_kits/sltb010a/sltb010a_0.yaml @@ -14,6 +14,7 @@ supported: - uart - i2c - dma + - pwm - spi - clock_control vendor: silabs diff --git a/boards/silabs/dev_kits/sltb010a/sltb010a_2.overlay b/boards/silabs/dev_kits/sltb010a/sltb010a_2.overlay index ead0fc78f41b..2f52846d81b7 100644 --- a/boards/silabs/dev_kits/sltb010a/sltb010a_2.overlay +++ b/boards/silabs/dev_kits/sltb010a/sltb010a_2.overlay @@ -27,6 +27,10 @@ enable-gpios = <&gpioc 7 GPIO_ACTIVE_HIGH>; }; +&timer0_default { + pins = ; +}; + &exp_header { gpio-map = <3 0 &gpioa 8 0>, <4 0 &gpioc 0 0>, diff --git a/boards/silabs/dev_kits/sltb010a/sltb010a_2.yaml b/boards/silabs/dev_kits/sltb010a/sltb010a_2.yaml index fbd9f8c97244..21416add61de 100644 --- a/boards/silabs/dev_kits/sltb010a/sltb010a_2.yaml +++ b/boards/silabs/dev_kits/sltb010a/sltb010a_2.yaml @@ -14,5 +14,6 @@ supported: - uart - i2c - dma + - pwm - spi vendor: silabs diff --git a/boards/silabs/dev_kits/sltb010a/thunderboard.dtsi b/boards/silabs/dev_kits/sltb010a/thunderboard.dtsi index 664efbe17812..480f9dd81ef2 100644 --- a/boards/silabs/dev_kits/sltb010a/thunderboard.dtsi +++ b/boards/silabs/dev_kits/sltb010a/thunderboard.dtsi @@ -5,6 +5,7 @@ */ #include +#include / { chosen { @@ -25,6 +26,15 @@ }; }; + pwmleds { + compatible = "pwm-leds"; + + pwm_led0: pwm_led_0 { + pwms = <&timer0_pwm 0 PWM_MSEC(20) PWM_POLARITY_NORMAL>; + label = "PWM LED 0"; + }; + }; + buttons { compatible = "gpio-keys"; @@ -74,6 +84,16 @@ swo-ref-frequency = ; }; +&timer0 { + status = "okay"; + + timer0_pwm: pwm { + pinctrl-0 = <&timer0_default>; + pinctrl-names = "default"; + status = "okay"; + }; +}; + &usart0 { pinctrl-0 = <&usart0_default>; pinctrl-names = "default"; diff --git a/boards/silabs/dev_kits/xg24_ek2703a/xg24_ek2703a-pinctrl.dtsi b/boards/silabs/dev_kits/xg24_ek2703a/xg24_ek2703a-pinctrl.dtsi index cf81ff6990a6..f384e307ecbf 100644 --- a/boards/silabs/dev_kits/xg24_ek2703a/xg24_ek2703a-pinctrl.dtsi +++ b/boards/silabs/dev_kits/xg24_ek2703a/xg24_ek2703a-pinctrl.dtsi @@ -31,6 +31,14 @@ }; }; + timer0_default: timer0_default { + group0 { + pins = , ; + drive-push-pull; + output-high; + }; + }; + usart0_default: usart0_default { group0 { pins = ; diff --git a/boards/silabs/dev_kits/xg24_ek2703a/xg24_ek2703a.dts b/boards/silabs/dev_kits/xg24_ek2703a/xg24_ek2703a.dts index 824f9aaaa416..04c14194222d 100644 --- a/boards/silabs/dev_kits/xg24_ek2703a/xg24_ek2703a.dts +++ b/boards/silabs/dev_kits/xg24_ek2703a/xg24_ek2703a.dts @@ -7,6 +7,7 @@ /dts-v1/; #include #include +#include #include #include "xg24_ek2703a-pinctrl.dtsi" @@ -27,6 +28,8 @@ aliases { led0 = &led0; led1 = &led1; + pwm-led0 = &pwm_led0; + pwm-led1 = &pwm_led1; sw0 = &button0; sw1 = &button1; watchdog0 = &wdog0; @@ -44,6 +47,20 @@ }; }; + pwmleds { + compatible = "pwm-leds"; + + pwm_led0: pwm_led_0 { + pwms = <&timer0_pwm 0 PWM_MSEC(20) PWM_POLARITY_INVERTED>; + label = "PWM LED 0"; + }; + + pwm_led1: pwm_led_1 { + pwms = <&timer0_pwm 1 PWM_MSEC(20) PWM_POLARITY_INVERTED>; + label = "PWM LED 1"; + }; + }; + buttons { compatible = "gpio-keys"; @@ -124,6 +141,16 @@ status = "okay"; }; +&timer0 { + status = "okay"; + + timer0_pwm: pwm { + pinctrl-0 = <&timer0_default>; + pinctrl-names = "default"; + status = "okay"; + }; +}; + &gpio { status = "okay"; }; diff --git a/boards/silabs/dev_kits/xg24_ek2703a/xg24_ek2703a.yaml b/boards/silabs/dev_kits/xg24_ek2703a/xg24_ek2703a.yaml index e5c360b43a60..4e05445fe3ab 100644 --- a/boards/silabs/dev_kits/xg24_ek2703a/xg24_ek2703a.yaml +++ b/boards/silabs/dev_kits/xg24_ek2703a/xg24_ek2703a.yaml @@ -16,6 +16,7 @@ supported: - clock_control - comparator - dac + - pwm testing: ignore_tags: - pm diff --git a/boards/silabs/dev_kits/xg27_dk2602a/thunderboard.dtsi b/boards/silabs/dev_kits/xg27_dk2602a/thunderboard.dtsi index 90dad770149c..69b6caab224d 100644 --- a/boards/silabs/dev_kits/xg27_dk2602a/thunderboard.dtsi +++ b/boards/silabs/dev_kits/xg27_dk2602a/thunderboard.dtsi @@ -5,6 +5,7 @@ */ #include +#include / { chosen { @@ -25,6 +26,15 @@ }; }; + pwmleds { + compatible = "pwm-leds"; + + pwm_led0: pwm_led_0 { + pwms = <&timer0_pwm 0 PWM_MSEC(20) PWM_POLARITY_NORMAL>; + label = "PWM LED 0"; + }; + }; + buttons { compatible = "gpio-keys"; @@ -88,6 +98,16 @@ swo-ref-frequency = ; }; +&timer0 { + status = "okay"; + + timer0_pwm: pwm { + pinctrl-0 = <&timer0_default>; + pinctrl-names = "default"; + status = "okay"; + }; +}; + &usart0 { status = "okay"; pinctrl-0 = <&usart0_default>; diff --git a/boards/silabs/dev_kits/xg27_dk2602a/xg27_dk2602a-pinctrl.dtsi b/boards/silabs/dev_kits/xg27_dk2602a/xg27_dk2602a-pinctrl.dtsi index 3d91497a8403..18a687c1695b 100644 --- a/boards/silabs/dev_kits/xg27_dk2602a/xg27_dk2602a-pinctrl.dtsi +++ b/boards/silabs/dev_kits/xg27_dk2602a/xg27_dk2602a-pinctrl.dtsi @@ -31,6 +31,14 @@ }; }; + timer0_default: timer0_default { + group0 { + pins = ; + drive-push-pull; + output-low; + }; + }; + usart0_default: usart0_default { group0 { pins = , ; diff --git a/boards/silabs/dev_kits/xg27_dk2602a/xg27_dk2602a.dts b/boards/silabs/dev_kits/xg27_dk2602a/xg27_dk2602a.dts index 6381cb8b4170..e8d6268f288c 100644 --- a/boards/silabs/dev_kits/xg27_dk2602a/xg27_dk2602a.dts +++ b/boards/silabs/dev_kits/xg27_dk2602a/xg27_dk2602a.dts @@ -18,6 +18,7 @@ /* These aliases are provided for compatibility with samples */ aliases { led0 = &led0; + pwm-led0 = &pwm_led0; spi0 = &usart0; sw0 = &button0; watchdog0 = &wdog0; diff --git a/boards/silabs/dev_kits/xg27_dk2602a/xg27_dk2602a.yaml b/boards/silabs/dev_kits/xg27_dk2602a/xg27_dk2602a.yaml index 73d0ba0dc8d6..85fc88413e01 100644 --- a/boards/silabs/dev_kits/xg27_dk2602a/xg27_dk2602a.yaml +++ b/boards/silabs/dev_kits/xg27_dk2602a/xg27_dk2602a.yaml @@ -16,5 +16,6 @@ supported: - clock_control - comparator - adc + - pwm - watchdog vendor: silabs From 01e19e96c9642d899f08a5ac8dbeee9682d71427 Mon Sep 17 00:00:00 2001 From: Aksel Skauge Mellbye Date: Wed, 10 Dec 2025 11:36:34 +0100 Subject: [PATCH 0316/3659] boards: silabs: List ADC as supported for testing Add ADC to supported list for testing on boards that have a zephyr,user io-channels property. Signed-off-by: Aksel Skauge Mellbye --- boards/silabs/explorer_kits/xg22/bg22_ek4108a.yaml | 1 + boards/silabs/explorer_kits/xg22/xg22_ek2710a.yaml | 1 + 2 files changed, 2 insertions(+) diff --git a/boards/silabs/explorer_kits/xg22/bg22_ek4108a.yaml b/boards/silabs/explorer_kits/xg22/bg22_ek4108a.yaml index f5a80d8d4423..a57fa9bfc8d4 100644 --- a/boards/silabs/explorer_kits/xg22/bg22_ek4108a.yaml +++ b/boards/silabs/explorer_kits/xg22/bg22_ek4108a.yaml @@ -8,6 +8,7 @@ toolchain: - zephyr - gnuarmemb supported: + - adc - bluetooth - counter - gpio diff --git a/boards/silabs/explorer_kits/xg22/xg22_ek2710a.yaml b/boards/silabs/explorer_kits/xg22/xg22_ek2710a.yaml index ed8b28059a08..103883506f56 100644 --- a/boards/silabs/explorer_kits/xg22/xg22_ek2710a.yaml +++ b/boards/silabs/explorer_kits/xg22/xg22_ek2710a.yaml @@ -8,6 +8,7 @@ toolchain: - zephyr - gnuarmemb supported: + - adc - bluetooth - counter - gpio From 9a17f66b7726dcf024b72ca7e1aea7aa14ea022b Mon Sep 17 00:00:00 2001 From: Aksel Skauge Mellbye Date: Wed, 10 Dec 2025 12:18:40 +0100 Subject: [PATCH 0317/3659] boards: silabs: xg24_ek2703a: Enable analog peripherals Configure ADC and DAC to use the Analog pin on the Mikrobus connector as input/output to enable ADC and DAC samples. Signed-off-by: Aksel Skauge Mellbye --- .../xg24_ek2703a/xg24_ek2703a-pinctrl.dtsi | 12 +++++++ .../dev_kits/xg24_ek2703a/xg24_ek2703a.dts | 31 +++++++++++++++++++ .../dev_kits/xg24_ek2703a/xg24_ek2703a.yaml | 1 + 3 files changed, 44 insertions(+) diff --git a/boards/silabs/dev_kits/xg24_ek2703a/xg24_ek2703a-pinctrl.dtsi b/boards/silabs/dev_kits/xg24_ek2703a/xg24_ek2703a-pinctrl.dtsi index f384e307ecbf..b4bfbac2256d 100644 --- a/boards/silabs/dev_kits/xg24_ek2703a/xg24_ek2703a-pinctrl.dtsi +++ b/boards/silabs/dev_kits/xg24_ek2703a/xg24_ek2703a-pinctrl.dtsi @@ -15,6 +15,12 @@ }; }; + iadc0_default: iadc0_default { + group0 { + silabs,analog-bus = ; + }; + }; + i2c0_default: i2c0_default { group0 { pins = , ; @@ -52,4 +58,10 @@ silabs,input-filter; }; }; + + vdac0_default: vdac0_default { + group0 { + silabs,analog-bus = ; + }; + }; }; diff --git a/boards/silabs/dev_kits/xg24_ek2703a/xg24_ek2703a.dts b/boards/silabs/dev_kits/xg24_ek2703a/xg24_ek2703a.dts index 04c14194222d..786dd03f9716 100644 --- a/boards/silabs/dev_kits/xg24_ek2703a/xg24_ek2703a.dts +++ b/boards/silabs/dev_kits/xg24_ek2703a/xg24_ek2703a.dts @@ -6,6 +6,8 @@ /dts-v1/; #include +#include +#include #include #include #include @@ -74,6 +76,13 @@ zephyr,code = ; }; }; + + mikrobus_adc: mikrobus_dac: zephyr,user { + io-channels = <&adc0 0>; + dac = <&vdac0>; + dac-channel-id = <0>; + dac-resolution = <12>; + }; }; &cpu0 { @@ -220,11 +229,33 @@ }; &adc0 { + pinctrl-0 = <&iadc0_default>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; status = "okay"; + + channel@0 { + reg = <0>; + zephyr,acquisition-time = ; + zephyr,gain = "ADC_GAIN_1"; + zephyr,input-positive = ; + zephyr,reference = "ADC_REF_VDD_1"; + zephyr,resolution = <12>; + zephyr,vref-mv = <3300>; + }; }; &vdac0 { + pinctrl-0 = <&vdac0_default>; + pinctrl-names = "default"; + voltage-reference = "AVDD"; status = "okay"; + + channel@0 { + reg = <0>; + aux-output = ; + }; }; &vdac1 { diff --git a/boards/silabs/dev_kits/xg24_ek2703a/xg24_ek2703a.yaml b/boards/silabs/dev_kits/xg24_ek2703a/xg24_ek2703a.yaml index 4e05445fe3ab..3c4c784a05eb 100644 --- a/boards/silabs/dev_kits/xg24_ek2703a/xg24_ek2703a.yaml +++ b/boards/silabs/dev_kits/xg24_ek2703a/xg24_ek2703a.yaml @@ -8,6 +8,7 @@ toolchain: - zephyr - gnuarmemb supported: + - adc - bluetooth - counter - gpio From 3ac0e760e66654aeef659e1a739a7b00535bcf59 Mon Sep 17 00:00:00 2001 From: Aksel Skauge Mellbye Date: Wed, 10 Dec 2025 14:07:46 +0100 Subject: [PATCH 0318/3659] boards: silabs: sltb010a: Enable watchdog for testing Declare watchdog as supported for testing. Signed-off-by: Aksel Skauge Mellbye --- boards/silabs/dev_kits/sltb010a/sltb010a_0.yaml | 1 + boards/silabs/dev_kits/sltb010a/sltb010a_2.yaml | 1 + 2 files changed, 2 insertions(+) diff --git a/boards/silabs/dev_kits/sltb010a/sltb010a_0.yaml b/boards/silabs/dev_kits/sltb010a/sltb010a_0.yaml index a68baea8cc69..f85f435a4bbd 100644 --- a/boards/silabs/dev_kits/sltb010a/sltb010a_0.yaml +++ b/boards/silabs/dev_kits/sltb010a/sltb010a_0.yaml @@ -17,4 +17,5 @@ supported: - pwm - spi - clock_control + - watchdog vendor: silabs diff --git a/boards/silabs/dev_kits/sltb010a/sltb010a_2.yaml b/boards/silabs/dev_kits/sltb010a/sltb010a_2.yaml index 21416add61de..139654299437 100644 --- a/boards/silabs/dev_kits/sltb010a/sltb010a_2.yaml +++ b/boards/silabs/dev_kits/sltb010a/sltb010a_2.yaml @@ -16,4 +16,5 @@ supported: - dma - pwm - spi + - watchdog vendor: silabs From 2f3e902cd0abe754db5136aaf6e8934ca5569de7 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Wed, 10 Dec 2025 17:18:59 +0200 Subject: [PATCH 0319/3659] net: Start RX before the TX Honor the comment in the code and make sure RX is started before TX so that we can receive responses to any data we are sending. Signed-off-by: Jukka Rissanen --- subsys/net/ip/net_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/subsys/net/ip/net_core.c b/subsys/net/ip/net_core.c index b9026fb9df17..058477ee37b2 100644 --- a/subsys/net/ip/net_core.c +++ b/subsys/net/ip/net_core.c @@ -647,13 +647,13 @@ int net_recv_data(struct net_if *iface, struct net_pkt *pkt) static void init_rx_queues(void) { + net_tc_rx_init(); + /* Starting TX side. The ordering is important here and the TX * can only be started when RX side is ready to receive packets. */ net_if_init(); - net_tc_rx_init(); - /* This will take the interface up and start everything. */ net_if_post_init(); From 7c62cd32cbdabc0d7990b45ec115b31a4c5559f1 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Tue, 9 Dec 2025 18:10:22 +0200 Subject: [PATCH 0320/3659] net: pkt_filter: Reformat macro lines Shorten long lines with \ chars in NPF_PRIORITY macro so that the output looks good if user is using narrower window to view the code. Reformat \ in NPF_RULE macro so that the code looks better. Signed-off-by: Jukka Rissanen --- include/zephyr/net/net_pkt_filter.h | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/include/zephyr/net/net_pkt_filter.h b/include/zephyr/net/net_pkt_filter.h index 73e65f67b756..fe46db0dea06 100644 --- a/include/zephyr/net/net_pkt_filter.h +++ b/include/zephyr/net/net_pkt_filter.h @@ -236,19 +236,19 @@ bool npf_remove_all_rules(struct npf_rule_list *rules); * NET_OK or NET_DROP. * @param ... List of conditions for this rule. */ -#define NPF_RULE(_name, _result, ...) \ - struct npf_rule _name = { \ - .result = (_result), \ - .nb_tests = NUM_VA_ARGS_LESS_1(__VA_ARGS__) + 1, \ +#define NPF_RULE(_name, _result, ...) \ + struct npf_rule _name = { \ + .result = (_result), \ + .nb_tests = NUM_VA_ARGS_LESS_1(__VA_ARGS__) + 1, \ .tests = { FOR_EACH(Z_NPF_TEST_ADDR, (,), __VA_ARGS__) }, \ } -#define NPF_PRIORITY(_name, _priority, ...) \ - struct npf_rule _name = { \ - .result = NET_CONTINUE, \ - .priority = (_priority), \ - .nb_tests = NUM_VA_ARGS_LESS_1(__VA_ARGS__) + 1, \ - .tests = {FOR_EACH(Z_NPF_TEST_ADDR, (,), __VA_ARGS__)}, \ +#define NPF_PRIORITY(_name, _priority, ...) \ + struct npf_rule _name = { \ + .result = NET_CONTINUE, \ + .priority = (_priority), \ + .nb_tests = NUM_VA_ARGS_LESS_1(__VA_ARGS__) + 1, \ + .tests = {FOR_EACH(Z_NPF_TEST_ADDR, (,), __VA_ARGS__)}, \ } #define Z_NPF_TEST_ADDR(arg) &arg.test From 9dd57b34052f3a8067a891c288009e92a3254079 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Tue, 9 Dec 2025 17:53:22 +0200 Subject: [PATCH 0321/3659] samples: net: pkt_filter: Fix the readme file The readme file did not mention the network packet priority based rules 1-5 introduced recently. Signed-off-by: Jukka Rissanen --- samples/net/pkt_filter/README.rst | 38 +++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/samples/net/pkt_filter/README.rst b/samples/net/pkt_filter/README.rst index 2759085475b5..0b3673915aec 100644 --- a/samples/net/pkt_filter/README.rst +++ b/samples/net/pkt_filter/README.rst @@ -54,13 +54,13 @@ In network shell, you can monitor the network packet filters: .. code-block:: console uart:~$ net filter - Rule Type Verdict Tests - [ 1] recv OK 3 eth vlan type[0x0800],size max[200],iface[2] - [ 2] recv OK 3 eth vlan type[0x0800],size min[100],iface[3] - [ 3] recv OK 1 iface[1] - [ 4] recv OK 2 eth vlan type[0x0806],iface[2] - [ 5] recv OK 2 eth vlan type[0x0806],iface[3] - [ 6] recv DROP 0 + Rule Type Verdict Pkt-Prio Queue Thread-Prio Tests + [ 1] recv OK N/A N/A N/A 3 iface[2],eth vlan type[0x0800],size max[200] + [ 2] recv OK N/A N/A N/A 3 iface[3],eth vlan type[0x0800],size min[100] + [ 3] recv OK N/A N/A N/A 1 iface[1] + [ 4] recv OK N/A N/A N/A 2 iface[2],eth vlan type[0x0806] + [ 5] recv OK N/A N/A N/A 2 iface[3],eth vlan type[0x0806] + [ 6] recv DROP N/A N/A N/A 0 The above sample application network packet filter rules can be interpreted like this: @@ -80,6 +80,30 @@ like this: * Rule 6: Drop all other packets. This also means that IPv6 packets are dropped. +If you enable network packet priority option :kconfig:option:`CONFIG_NET_SAMPLE_USE_PACKET_PRIORITIES` +then the sample will install extra rules for setting up the priorities. + + uart:~$ net filter + Rule Type Verdict Pkt-Prio Queue Thread-Prio Tests + [ 1] recv CONTINUE 1 0 1 1 iface[1] + [ 2] recv CONTINUE 7 2 SKIP 2 iface[1],eth type[0x88f7] + [ 3] recv CONTINUE 2 0 1 2 iface[1],eth type[0x8100] + [ 4] recv CONTINUE 1 0 1 2 iface[2],eth vlan type[0x0806] + [ 5] recv CONTINUE 1 0 1 2 iface[3],eth vlan type[0x0806] + [ 6] recv OK N/A N/A N/A 3 iface[2],eth vlan type[0x0800],size max[200] + [ 7] recv OK N/A N/A N/A 3 iface[3],eth vlan type[0x0800],size min[100] + [ 8] recv OK N/A N/A N/A 1 iface[1] + [ 9] recv OK N/A N/A N/A 2 iface[2],eth vlan type[0x0806] + [10] recv OK N/A N/A N/A 2 iface[3],eth vlan type[0x0806] + [11] recv DROP N/A N/A N/A 0 + +The above sample application network packet filter rules can be interpreted +like this: + +* Rules 1 - 5: Add rules to set network packet priority to certain type packets. + +* Rule 6 - 11: These are the same as in previous rule list. + The network statistics can be used to see that the packets are dropped. Use ``net stats`` command to monitor statistics. From 47941a6f587797656c57f6c44b9068d530095aad Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Tue, 9 Dec 2025 16:53:13 +0200 Subject: [PATCH 0322/3659] samples: net: pkt_filter: Add IPv4/6 address blocklist Add information how to block IPv4 or IPv6 addresses. Signed-off-by: Jukka Rissanen --- samples/net/pkt_filter/README.rst | 10 ++++++++- samples/net/pkt_filter/src/main.c | 35 ++++++++++++++++++++++++++++++- 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/samples/net/pkt_filter/README.rst b/samples/net/pkt_filter/README.rst index 0b3673915aec..de234c9c229d 100644 --- a/samples/net/pkt_filter/README.rst +++ b/samples/net/pkt_filter/README.rst @@ -61,6 +61,8 @@ In network shell, you can monitor the network packet filters: [ 4] recv OK N/A N/A N/A 2 iface[2],eth vlan type[0x0806] [ 5] recv OK N/A N/A N/A 2 iface[3],eth vlan type[0x0806] [ 6] recv DROP N/A N/A N/A 0 + [ 7] IPv4 recv OK N/A N/A N/A 1 ip src block[192.0.2.2,198.51.100.2] + [ 8] IPv6 recv OK N/A N/A N/A 1 ip src block[2001:db8::2,2001:db8::100:2] The above sample application network packet filter rules can be interpreted like this: @@ -80,6 +82,10 @@ like this: * Rule 6: Drop all other packets. This also means that IPv6 packets are dropped. +* Rule 7: Drop IPv4 packets where the source address is either ``192.0.2.2`` or ``198.51.100.2``. + +* Rule 8: Drop IPv6 packets where the source address is either ``2001:db8::2`` or ``2001:db8::100:2``. + If you enable network packet priority option :kconfig:option:`CONFIG_NET_SAMPLE_USE_PACKET_PRIORITIES` then the sample will install extra rules for setting up the priorities. @@ -96,13 +102,15 @@ then the sample will install extra rules for setting up the priorities. [ 9] recv OK N/A N/A N/A 2 iface[2],eth vlan type[0x0806] [10] recv OK N/A N/A N/A 2 iface[3],eth vlan type[0x0806] [11] recv DROP N/A N/A N/A 0 + [12] IPv4 recv OK N/A N/A N/A 1 ip src block[192.0.2.2,198.51.100.2] + [13] IPv6 recv OK N/A N/A N/A 1 ip src block[2001:db8::2,2001:db8::100:2] The above sample application network packet filter rules can be interpreted like this: * Rules 1 - 5: Add rules to set network packet priority to certain type packets. -* Rule 6 - 11: These are the same as in previous rule list. +* Rule 6 - 13: These are the same as in previous rule list. The network statistics can be used to see that the packets are dropped. Use ``net stats`` command to monitor statistics. diff --git a/samples/net/pkt_filter/src/main.c b/samples/net/pkt_filter/src/main.c index 81600995b5a2..b11867733862 100644 --- a/samples/net/pkt_filter/src/main.c +++ b/samples/net/pkt_filter/src/main.c @@ -59,6 +59,33 @@ static NPF_RULE(arp_pkt_vlan2, NET_OK, match_iface_vlan2, match_arp_vlan); static NPF_PRIORITY(arp_priority_vlan1, NET_PRIORITY_BK, match_iface_vlan1, match_arp_vlan); static NPF_PRIORITY(arp_priority_vlan2, NET_PRIORITY_BK, match_iface_vlan2, match_arp_vlan); +/* Block IPv4 or IPv6 packets from only these addresses */ +#define PEER1_IPV4_ADDR_INIT {{{ 192, 0, 2, 2 }}} +#define PEER2_IPV4_ADDR_INIT {{{ 198, 51, 100, 2 }}} +#define PEER1_IPV6_ADDR_INIT \ + {{{ 0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x02 }}} +#define PEER2_IPV6_ADDR_INIT \ + {{{ 0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0x1, 0, 0, 0x02 }}} + +static struct net_in_addr peer_ipv4_addr[] = { + [0] = PEER1_IPV4_ADDR_INIT, + [1] = PEER2_IPV4_ADDR_INIT, +}; + +static struct net_in6_addr peer_ipv6_addr[] = { + [0] = PEER1_IPV6_ADDR_INIT, + [1] = PEER2_IPV6_ADDR_INIT, +}; + +static NPF_IP_SRC_ADDR_BLOCKLIST(ipv4_src_block, + peer_ipv4_addr, ARRAY_SIZE(peer_ipv4_addr), + NET_AF_INET); +static NPF_IP_SRC_ADDR_BLOCKLIST(ipv6_src_block, + peer_ipv6_addr, ARRAY_SIZE(peer_ipv6_addr), + NET_AF_INET6); +static NPF_RULE(ipv4_addr_block, NET_OK, ipv4_src_block); +static NPF_RULE(ipv6_addr_block, NET_OK, ipv6_src_block); + static void iface_cb(struct net_if *iface, void *user_data) { int count = 0; @@ -116,7 +143,7 @@ static void init_app(void) /* The sample will setup the Ethernet interface and two VLAN * optional interfaces (if VLAN is enabled). * We allow all traffic to the Ethernet interface, but have - * filters for the VLAN interfaces. + * filters for the VLAN interfaces and check IPv4 and IPv6 source addresses. * * First append the priority rules, so that they get evaluated before * deciding on the final verdict for the packet. @@ -142,6 +169,12 @@ static void init_app(void) /* The remaining packets that do not match are dropped */ npf_append_recv_rule(&npf_default_drop); + + /* We block packets from specific IPv4 addresses */ + npf_append_ipv4_recv_rule(&ipv4_addr_block); + + /* We block packets from specific IPv6 addresses */ + npf_append_ipv6_recv_rule(&ipv6_addr_block); } int main(void) From 869cfb8fd67b5d30c4b1acca9e1de480e83b88e5 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Wed, 10 Dec 2025 17:30:04 +0200 Subject: [PATCH 0323/3659] samples: net: pkt_filter: Disabling packet priorities by default The packet priority support is disabled by default so that the application can work "normally" as a sample for trying network packet filtering. Signed-off-by: Jukka Rissanen --- samples/net/pkt_filter/Kconfig | 8 +++++++ samples/net/pkt_filter/overlay-priority.conf | 4 ++++ samples/net/pkt_filter/prj.conf | 3 +-- samples/net/pkt_filter/sample.yaml | 23 +++++++++++--------- samples/net/pkt_filter/src/main.c | 16 +++++++++----- 5 files changed, 37 insertions(+), 17 deletions(-) create mode 100644 samples/net/pkt_filter/overlay-priority.conf diff --git a/samples/net/pkt_filter/Kconfig b/samples/net/pkt_filter/Kconfig index 5a084b0fff52..2e15d3353e24 100644 --- a/samples/net/pkt_filter/Kconfig +++ b/samples/net/pkt_filter/Kconfig @@ -3,5 +3,13 @@ # Copyright (c) 2025 Nordic Semiconductor ASA # SPDX-License-Identifier: Apache-2.0 +mainmenu "Networking pkt_filter sample application" + +config NET_SAMPLE_USE_PACKET_PRIORITIES + bool "Use network packet priorities" + help + Create multiple traffic class queues in order to test + network packet priorities. + source "samples/net/common/Kconfig" source "Kconfig.zephyr" diff --git a/samples/net/pkt_filter/overlay-priority.conf b/samples/net/pkt_filter/overlay-priority.conf new file mode 100644 index 000000000000..85a095b295f0 --- /dev/null +++ b/samples/net/pkt_filter/overlay-priority.conf @@ -0,0 +1,4 @@ +# Enable network packet priority support in the sample +CONFIG_NET_SAMPLE_USE_PACKET_PRIORITIES=y +CONFIG_NET_TC_RX_COUNT=2 +CONFIG_NET_TC_RX_SKIP_FOR_HIGH_PRIO=y diff --git a/samples/net/pkt_filter/prj.conf b/samples/net/pkt_filter/prj.conf index 151fa6d73009..4bfabf002928 100644 --- a/samples/net/pkt_filter/prj.conf +++ b/samples/net/pkt_filter/prj.conf @@ -62,5 +62,4 @@ CONFIG_NET_IF_MAX_IPV6_COUNT=3 # Network traffic class queues CONFIG_NET_TC_THREAD_PREEMPTIVE=y -CONFIG_NET_TC_RX_COUNT=2 -CONFIG_NET_TC_RX_SKIP_FOR_HIGH_PRIO=y +CONFIG_NET_TC_RX_COUNT=1 diff --git a/samples/net/pkt_filter/sample.yaml b/samples/net/pkt_filter/sample.yaml index 7122b4b8926c..6933491f6513 100644 --- a/samples/net/pkt_filter/sample.yaml +++ b/samples/net/pkt_filter/sample.yaml @@ -1,14 +1,17 @@ sample: description: Network packet filtering functionality name: Network packet filter sample app +common: + harness: net + min_ram: 64 + tags: + - net + - statistics + - net_pkt_filter + depends_on: netif + integration_platforms: + - native_sim tests: - sample.net.pkt_filter: - harness: net - min_ram: 64 - tags: - - net - - statistics - - net_pkt_filter - depends_on: netif - integration_platforms: - - native_sim + sample.net.pkt_filter: {} + sample.net.pkt_filter_priorities: + extra_args: EXTRA_CONF_FILE="overlay-priority.conf" diff --git a/samples/net/pkt_filter/src/main.c b/samples/net/pkt_filter/src/main.c index b11867733862..60b6eefa2930 100644 --- a/samples/net/pkt_filter/src/main.c +++ b/samples/net/pkt_filter/src/main.c @@ -148,11 +148,17 @@ static void init_app(void) * First append the priority rules, so that they get evaluated before * deciding on the final verdict for the packet. */ - npf_append_recv_rule(ð_priority_default); - npf_append_recv_rule(ð_priority_ptp); - npf_append_recv_rule(ð_priority_vlan); - npf_append_recv_rule(&arp_priority_vlan1); - npf_append_recv_rule(&arp_priority_vlan2); + if (IS_ENABLED(CONFIG_NET_SAMPLE_USE_PACKET_PRIORITIES)) { + LOG_INF("Using packet priorities"); + + npf_append_recv_rule(ð_priority_default); + npf_append_recv_rule(ð_priority_ptp); + npf_append_recv_rule(ð_priority_vlan); + npf_append_recv_rule(&arp_priority_vlan1); + npf_append_recv_rule(&arp_priority_vlan2); + } else { + LOG_INF("Packet priorities are disabled"); + } /* We allow small IPv4 packets to the VLAN interface 1 */ npf_append_recv_rule(&small_ipv4_pkt); From d726022f83a344a17717559b1a52a42f6b0ea0e1 Mon Sep 17 00:00:00 2001 From: Kyle Bonnici Date: Thu, 11 Dec 2025 15:03:32 +0100 Subject: [PATCH 0324/3659] CI: Update dts-linter to 0.3.7-hotfix2 dts-linter 0.3.7-hotfix2 Security Updates: - Update `glob` to address CVE-2025-64756 - Update `js-yaml` to address CVE-2025-64718 Formatting updates: - Ensure that properties have 2 new lines when node is above it. - Enures that 1 new line is required between a node and #if/#ifdef... - Enures that 2 new line are required between #endif and node. - Wraps property values that exceed 100 characters in length. Signed-off-by: Kyle Bonnici --- scripts/ci/package-lock.json | 16 ++++++++-------- scripts/ci/package.json | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/scripts/ci/package-lock.json b/scripts/ci/package-lock.json index 437ea4b6f3dd..21fe2fdb4147 100644 --- a/scripts/ci/package-lock.json +++ b/scripts/ci/package-lock.json @@ -5,13 +5,13 @@ "packages": { "": { "dependencies": { - "dts-linter": "^0.3.6" + "dts-linter": "^0.3.7-hotfix2" } }, "node_modules/devicetree-language-server": { - "version": "0.6.7", - "resolved": "https://registry.npmjs.org/devicetree-language-server/-/devicetree-language-server-0.6.7.tgz", - "integrity": "sha512-ov/f8B8WcKAgOR4TVmr3cgH5KWsrmFnHZJL4Zha6x7b7gpux9eXWWAg/XsgE0Aifexu8ht0txy1us7/IiUs/dg==", + "version": "0.7.2-hotfix1", + "resolved": "https://registry.npmjs.org/devicetree-language-server/-/devicetree-language-server-0.7.2-hotfix1.tgz", + "integrity": "sha512-46UFopMrfO5sNEPZSqCmWfkwVRn370roIUt3W99KwLpF/4rEt2FOxFtp/uZ+T+h09HLx013L3h7jTKnMtTLU4g==", "license": "Apache-2.0", "bin": { "devicetree-language-server": "dist/server.js" @@ -21,12 +21,12 @@ } }, "node_modules/dts-linter": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/dts-linter/-/dts-linter-0.3.6.tgz", - "integrity": "sha512-MG7r0hWOcmhue4k0oSd0+/mNC9nNnpdRKfW4EhQevOd1apHUhmTW4SsI6Um5zfVP1fNpy95IpBS0/dja9UYCXw==", + "version": "0.3.7-hotfix2", + "resolved": "https://registry.npmjs.org/dts-linter/-/dts-linter-0.3.7-hotfix2.tgz", + "integrity": "sha512-pFR/Zpwsh8djV9Gd9sO8mSvTwOpW3Y4DRKD+Y4Scka+KXVYQQB8Z1uGxNFMjMQVdg9plwYUSLLt9//QkN48ulw==", "license": "Apache-2.0", "dependencies": { - "devicetree-language-server": "^0.6.7" + "devicetree-language-server": "0.7.2-hotfix1" }, "bin": { "dts-linter": "dist/dts-linter.js" diff --git a/scripts/ci/package.json b/scripts/ci/package.json index c77680f1bbe6..c3b12dcbd4e0 100644 --- a/scripts/ci/package.json +++ b/scripts/ci/package.json @@ -1,6 +1,6 @@ { "private": true, "dependencies": { - "dts-linter": "^0.3.6" + "dts-linter": "^0.3.7-hotfix2" } } From bbff45f1c4cf7d3baa068294a30fc490d692bdb4 Mon Sep 17 00:00:00 2001 From: Kyle Bonnici Date: Thu, 11 Dec 2025 15:06:39 +0100 Subject: [PATCH 0325/3659] DTS: format files using dts-linter 0.3.7-hotfix2 - Ensure that properties have 2 new lines when node is above it. - Enures that 1 new line is required between a node and #if/#ifdef... - Enures that 2 new line are required between #endif and node. - Wraps property values that exceed 100 characters in length. Signed-off-by: Kyle Bonnici --- boards/hardkernel/odroid_go/odroid_go_procpu.dts | 1 + boards/nxp/frdm_k64f/frdm_k64f.dts | 1 + boards/nxp/imx943_evk/imx943_evk_mimx94398_m33.dts | 1 + boards/nxp/imx943_evk/imx943_evk_mimx94398_m7_0.dts | 1 + boards/nxp/imx943_evk/imx943_evk_mimx94398_m7_1.dts | 1 + boards/nxp/mimxrt595_evk/mimxrt595_evk_mimxrt595s_cm33.dts | 1 + boards/nxp/mimxrt685_evk/mimxrt685_evk_mimxrt685s_cm33.dts | 1 + .../mimxrt700_evk/mimxrt700_evk_mimxrt798s_cm33_cpu0.dts | 1 + boards/renesas/rcar_h3ulcb/rcar_h3ulcb_r8a77951_a57.dts | 1 + boards/seeed/xiao_esp32s3/xiao_esp32s3_procpu_sense.dts | 1 + boards/shields/rk043fn02h_ct/rk043fn02h_ct.overlay | 1 + boards/shields/rk043fn66hs_ctg/rk043fn66hs_ctg.overlay | 1 + boards/shields/rk055hdmipi4m/rk055hdmipi4m.overlay | 1 + boards/shields/rk055hdmipi4ma0/rk055hdmipi4ma0.overlay | 1 + .../shields/rtk7eka6m3b00001bu/rtk7eka6m3b00001bu.overlay | 1 + .../shields/rtkmipilcdb00000be/rtkmipilcdb00000be.overlay | 1 + .../seeed_xiao_expansion_board.overlay | 1 + .../seeed_xiao_round_display.overlay | 1 + .../sparkfun_carrier_asset_tracker.overlay | 1 + boards/witte/linum/linum.dts | 1 + dts/arm/adi/max32/max32666.dtsi | 1 + dts/arm/nxp/nxp_k6x.dtsi | 3 ++- dts/arm/silabs/efm32wg990f256.dtsi | 3 ++- dts/arm/silabs/xg1/efm32pg1b200f256gm48.dtsi | 3 ++- dts/arm/silabs/xg1/efr32fg1p133f256gm48.dtsi | 3 ++- dts/arm/silabs/xg12/efm32jg12b500f1024gl125.dtsi | 3 ++- dts/arm/silabs/xg12/efm32pg12b500f1024gl125.dtsi | 3 ++- dts/vendor/nordic/nrf54l_05_10_15.dtsi | 3 --- dts/vendor/nordic/nrf54lm20a.dtsi | 3 --- samples/drivers/adc/adc_dt/boards/da1469x_dk_pro.overlay | 2 ++ samples/drivers/adc/adc_dt/boards/siwx917_rb4338a.overlay | 1 + samples/drivers/adc/adc_dt/boards/xmc45_relax_kit.overlay | 1 + samples/subsys/display/lvgl/boards/wio_terminal.overlay | 3 ++- samples/subsys/fs/fs_sample/boards/hifive_unmatched.overlay | 1 + samples/subsys/fs/fs_sample/boards/nrf52840_blip.overlay | 1 + samples/subsys/fs/fs_sample/boards/nucleo_f429zi.overlay | 1 + .../fs/littlefs/boards/rcar_h3ulcb_r8a77951_a57.overlay | 1 + samples/subsys/fs/littlefs/boards/rcar_salvator_xs.overlay | 1 + .../rtu_client/boards/arduino_opta_stm32h747xx_m7.overlay | 1 + .../rtu_server/boards/arduino_opta_stm32h747xx_m7.overlay | 1 + samples/subsys/sensing/simple/boards/native_sim.overlay | 6 ++++-- samples/subsys/usb_c/source/boards/stm32g081b_eval.overlay | 3 ++- tests/drivers/adc/adc_api/boards/siwx917_dk2605a.overlay | 1 + tests/drivers/adc/adc_api/boards/siwx917_rb4338a.overlay | 1 + tests/drivers/build_all/input/app.overlay | 1 + .../boards/rcar_h3ulcb_r8a77951_a57.overlay | 1 + .../disk/disk_performance/boards/rcar_salvator_xs.overlay | 1 + tests/drivers/pwm/pwm_api/boards/siwx917_rb4338a.overlay | 1 + tests/drivers/pwm/pwm_api/boards/siwx917_rb4342a.overlay | 1 + .../spi_controller_peripheral/boards/frdm_mcxa156.overlay | 1 + .../drivers/spi/spi_loopback/boards/mimxrt1010_evk.overlay | 1 + .../drivers/spi/spi_loopback/boards/mimxrt1015_evk.overlay | 1 + .../drivers/spi/spi_loopback/boards/mimxrt1020_evk.overlay | 1 + .../drivers/spi/spi_loopback/boards/mimxrt1024_evk.overlay | 1 + .../drivers/spi/spi_loopback/boards/mimxrt1040_evk.overlay | 1 + .../boards/mimxrt1060_evk_mimxrt1062_qspi.overlay | 1 + .../boards/mimxrt1060_evk_mimxrt1062_qspi_C.overlay | 1 + .../drivers/spi/spi_loopback/boards/mimxrt1064_evk.overlay | 1 + .../boards/mimxrt1170_evk_mimxrt1176_cm4_B.overlay | 1 + .../boards/mimxrt1170_evk_mimxrt1176_cm7_A.overlay | 1 + .../boards/mimxrt1170_evk_mimxrt1176_cm7_B.overlay | 1 + .../boards/mimxrt1180_evk_mimxrt1189_cm33.overlay | 1 + .../boards/mimxrt1180_evk_mimxrt1189_cm7.overlay | 1 + .../spi/spi_loopback/boards/nrf54h20dk_nrf54h20_common.dtsi | 1 + .../drivers/spi/spi_loopback/boards/numaker_m2l31ki.overlay | 1 + .../drivers/spi/spi_loopback/boards/numaker_m3334ki.overlay | 1 + tests/drivers/spi/spi_loopback/boards/numaker_m55m1.overlay | 1 + .../spi/spi_loopback/boards/numaker_pfm_m467.overlay | 1 + tests/lib/devicetree/api/app.overlay | 3 ++- .../subsys/fs/ext2/boards/hifive_unmatched_fu740_s7.overlay | 1 + .../fs/ext2/boards/hifive_unmatched_fu740_u74.overlay | 1 + .../modbus/boards/arduino_opta_stm32h747xx_m7.overlay | 1 + tests/subsys/sd/mmc/boards/rcar_h3ulcb_r8a77951_a57.overlay | 1 + tests/subsys/sensing/boards/native_sim.overlay | 6 ++++-- 74 files changed, 88 insertions(+), 19 deletions(-) diff --git a/boards/hardkernel/odroid_go/odroid_go_procpu.dts b/boards/hardkernel/odroid_go/odroid_go_procpu.dts index b51120268dd9..a02996771b46 100644 --- a/boards/hardkernel/odroid_go/odroid_go_procpu.dts +++ b/boards/hardkernel/odroid_go/odroid_go_procpu.dts @@ -155,6 +155,7 @@ disk-name = "SD"; status = "okay"; }; + spi-max-frequency = <20000000>; }; }; diff --git a/boards/nxp/frdm_k64f/frdm_k64f.dts b/boards/nxp/frdm_k64f/frdm_k64f.dts index f337a24a0f6d..133044393963 100644 --- a/boards/nxp/frdm_k64f/frdm_k64f.dts +++ b/boards/nxp/frdm_k64f/frdm_k64f.dts @@ -173,6 +173,7 @@ arduino_spi: &spi0 { disk-name = "SD"; status = "okay"; }; + spi-max-frequency = ; }; }; diff --git a/boards/nxp/imx943_evk/imx943_evk_mimx94398_m33.dts b/boards/nxp/imx943_evk/imx943_evk_mimx94398_m33.dts index 44a3a65520d6..271e8b4c7ac6 100644 --- a/boards/nxp/imx943_evk/imx943_evk_mimx94398_m33.dts +++ b/boards/nxp/imx943_evk/imx943_evk_mimx94398_m33.dts @@ -96,6 +96,7 @@ pin-id = <5>; prescaler = <1>; }; + status = "okay"; }; }; diff --git a/boards/nxp/imx943_evk/imx943_evk_mimx94398_m7_0.dts b/boards/nxp/imx943_evk/imx943_evk_mimx94398_m7_0.dts index 1499a02213a5..18810c2f372e 100644 --- a/boards/nxp/imx943_evk/imx943_evk_mimx94398_m7_0.dts +++ b/boards/nxp/imx943_evk/imx943_evk_mimx94398_m7_0.dts @@ -36,6 +36,7 @@ pin-id = <5>; prescaler = <1>; }; + status = "okay"; }; }; diff --git a/boards/nxp/imx943_evk/imx943_evk_mimx94398_m7_1.dts b/boards/nxp/imx943_evk/imx943_evk_mimx94398_m7_1.dts index 06075021693b..f8df98f9332c 100644 --- a/boards/nxp/imx943_evk/imx943_evk_mimx94398_m7_1.dts +++ b/boards/nxp/imx943_evk/imx943_evk_mimx94398_m7_1.dts @@ -36,6 +36,7 @@ pin-id = <5>; prescaler = <1>; }; + status = "okay"; }; }; diff --git a/boards/nxp/mimxrt595_evk/mimxrt595_evk_mimxrt595s_cm33.dts b/boards/nxp/mimxrt595_evk/mimxrt595_evk_mimxrt595s_cm33.dts index f92a4f529b75..08c6d7583ad5 100644 --- a/boards/nxp/mimxrt595_evk/mimxrt595_evk_mimxrt595s_cm33.dts +++ b/boards/nxp/mimxrt595_evk/mimxrt595_evk_mimxrt595s_cm33.dts @@ -379,6 +379,7 @@ zephyr_udc0: &usbhs { disk-name = "SD2"; status = "okay"; }; + pinctrl-0 = <&pinmux_usdhc>; pinctrl-names = "default"; mmc-hs200-1_8v; diff --git a/boards/nxp/mimxrt685_evk/mimxrt685_evk_mimxrt685s_cm33.dts b/boards/nxp/mimxrt685_evk/mimxrt685_evk_mimxrt685s_cm33.dts index c6399ba494a0..83912c378327 100644 --- a/boards/nxp/mimxrt685_evk/mimxrt685_evk_mimxrt685s_cm33.dts +++ b/boards/nxp/mimxrt685_evk/mimxrt685_evk_mimxrt685s_cm33.dts @@ -361,6 +361,7 @@ i2s1: &flexcomm3 { disk-name = "SD"; status = "okay"; }; + pinctrl-0 = <&pinmux_usdhc>; pinctrl-names = "default"; }; diff --git a/boards/nxp/mimxrt700_evk/mimxrt700_evk_mimxrt798s_cm33_cpu0.dts b/boards/nxp/mimxrt700_evk/mimxrt700_evk_mimxrt798s_cm33_cpu0.dts index cb6d72561cdb..8feb364fd49e 100644 --- a/boards/nxp/mimxrt700_evk/mimxrt700_evk_mimxrt798s_cm33_cpu0.dts +++ b/boards/nxp/mimxrt700_evk/mimxrt700_evk_mimxrt798s_cm33_cpu0.dts @@ -457,6 +457,7 @@ zephyr_udc0: &usb0 { disk-name = "SD2"; status = "okay"; }; + pinctrl-0 = <&pinmux_usdhc>; pinctrl-names = "default"; mmc-hs200-1_8v; diff --git a/boards/renesas/rcar_h3ulcb/rcar_h3ulcb_r8a77951_a57.dts b/boards/renesas/rcar_h3ulcb/rcar_h3ulcb_r8a77951_a57.dts index fdb378490a9b..6dbb1d585c0b 100644 --- a/boards/renesas/rcar_h3ulcb/rcar_h3ulcb_r8a77951_a57.dts +++ b/boards/renesas/rcar_h3ulcb/rcar_h3ulcb_r8a77951_a57.dts @@ -99,6 +99,7 @@ disk-name = "SD2"; status = "disabled"; }; + bus-width = <8>; mmc-hs200-1_8v; mmc-hs400-1_8v; diff --git a/boards/seeed/xiao_esp32s3/xiao_esp32s3_procpu_sense.dts b/boards/seeed/xiao_esp32s3/xiao_esp32s3_procpu_sense.dts index 3e18fa58ac20..b8efaa2c8fed 100644 --- a/boards/seeed/xiao_esp32s3/xiao_esp32s3_procpu_sense.dts +++ b/boards/seeed/xiao_esp32s3/xiao_esp32s3_procpu_sense.dts @@ -71,6 +71,7 @@ disk-name = "SD"; status = "okay"; }; + spi-max-frequency = <20000000>; }; }; diff --git a/boards/shields/rk043fn02h_ct/rk043fn02h_ct.overlay b/boards/shields/rk043fn02h_ct/rk043fn02h_ct.overlay index af7ce65798e7..3e527eb6c3c9 100644 --- a/boards/shields/rk043fn02h_ct/rk043fn02h_ct.overlay +++ b/boards/shields/rk043fn02h_ct/rk043fn02h_ct.overlay @@ -42,6 +42,7 @@ 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/rk043fn66hs_ctg.overlay b/boards/shields/rk043fn66hs_ctg/rk043fn66hs_ctg.overlay index a04adf7f22f7..de2b6ab508f1 100644 --- a/boards/shields/rk043fn66hs_ctg/rk043fn66hs_ctg.overlay +++ b/boards/shields/rk043fn66hs_ctg/rk043fn66hs_ctg.overlay @@ -43,6 +43,7 @@ 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/rk055hdmipi4m/rk055hdmipi4m.overlay b/boards/shields/rk055hdmipi4m/rk055hdmipi4m.overlay index 9db9dc4fe514..d637e93fa49c 100644 --- a/boards/shields/rk055hdmipi4m/rk055hdmipi4m.overlay +++ b/boards/shields/rk055hdmipi4m/rk055hdmipi4m.overlay @@ -55,6 +55,7 @@ */ clock-frequency = <62346240>; }; + pixel-format = ; data-bus-width = "24-bit"; backlight-gpios = <&nxp_mipi_connector 0 GPIO_ACTIVE_HIGH>; diff --git a/boards/shields/rk055hdmipi4ma0/rk055hdmipi4ma0.overlay b/boards/shields/rk055hdmipi4ma0/rk055hdmipi4ma0.overlay index 0a8cb8cada69..d1f2deeaa61f 100644 --- a/boards/shields/rk055hdmipi4ma0/rk055hdmipi4ma0.overlay +++ b/boards/shields/rk055hdmipi4ma0/rk055hdmipi4ma0.overlay @@ -55,6 +55,7 @@ */ clock-frequency = <62346240>; }; + pixel-format = ; data-bus-width = "24-bit"; backlight-gpios = <&nxp_mipi_connector 0 GPIO_ACTIVE_HIGH>; diff --git a/boards/shields/rtk7eka6m3b00001bu/rtk7eka6m3b00001bu.overlay b/boards/shields/rtk7eka6m3b00001bu/rtk7eka6m3b00001bu.overlay index a6459d18db9d..14e65f9520a1 100644 --- a/boards/shields/rtk7eka6m3b00001bu/rtk7eka6m3b00001bu.overlay +++ b/boards/shields/rtk7eka6m3b00001bu/rtk7eka6m3b00001bu.overlay @@ -47,5 +47,6 @@ hfront-porch = <4>; vfront-porch = <35>; }; + backlight-gpios = <&lcd_expansion_rtk7eka6m3b00001bu 39 GPIO_ACTIVE_HIGH>; }; diff --git a/boards/shields/rtkmipilcdb00000be/rtkmipilcdb00000be.overlay b/boards/shields/rtkmipilcdb00000be/rtkmipilcdb00000be.overlay index a74179414114..415e8c8de69d 100644 --- a/boards/shields/rtkmipilcdb00000be/rtkmipilcdb00000be.overlay +++ b/boards/shields/rtkmipilcdb00000be/rtkmipilcdb00000be.overlay @@ -58,5 +58,6 @@ hfront-porch = <72>; vfront-porch = <17>; }; + backlight-gpios = <&renesas_mipi_connector 15 GPIO_ACTIVE_HIGH>; }; diff --git a/boards/shields/seeed_xiao_expansion_board/seeed_xiao_expansion_board.overlay b/boards/shields/seeed_xiao_expansion_board/seeed_xiao_expansion_board.overlay index ac33ce99074a..a90a4b62c465 100644 --- a/boards/shields/seeed_xiao_expansion_board/seeed_xiao_expansion_board.overlay +++ b/boards/shields/seeed_xiao_expansion_board/seeed_xiao_expansion_board.overlay @@ -65,6 +65,7 @@ disk-name = "SD"; status = "okay"; }; + spi-max-frequency = <24000000>; }; }; diff --git a/boards/shields/seeed_xiao_round_display/seeed_xiao_round_display.overlay b/boards/shields/seeed_xiao_round_display/seeed_xiao_round_display.overlay index 0f241d045706..5532500a63f3 100644 --- a/boards/shields/seeed_xiao_round_display/seeed_xiao_round_display.overlay +++ b/boards/shields/seeed_xiao_round_display/seeed_xiao_round_display.overlay @@ -88,6 +88,7 @@ disk-name = "SD"; status = "okay"; }; + spi-max-frequency = ; }; }; diff --git a/boards/shields/sparkfun_carrier_asset_tracker/sparkfun_carrier_asset_tracker.overlay b/boards/shields/sparkfun_carrier_asset_tracker/sparkfun_carrier_asset_tracker.overlay index c090c609a7d0..bb587a3219db 100644 --- a/boards/shields/sparkfun_carrier_asset_tracker/sparkfun_carrier_asset_tracker.overlay +++ b/boards/shields/sparkfun_carrier_asset_tracker/sparkfun_carrier_asset_tracker.overlay @@ -39,6 +39,7 @@ disk-name = "SD"; status = "okay"; }; + spi-max-frequency = ; }; }; diff --git a/boards/witte/linum/linum.dts b/boards/witte/linum/linum.dts index 5bca36dd8e86..3254cdc078cb 100644 --- a/boards/witte/linum/linum.dts +++ b/boards/witte/linum/linum.dts @@ -404,6 +404,7 @@ zephyr_udc0: &usbotg_fs { hfront-porch = <160>; vfront-porch = <12>; }; + def-back-color-red = <0xFF>; def-back-color-green = <0xFF>; def-back-color-blue = <0xFF>; diff --git a/dts/arm/adi/max32/max32666.dtsi b/dts/arm/adi/max32/max32666.dtsi index f21d13aa955d..5b98b639fee3 100644 --- a/dts/arm/adi/max32/max32666.dtsi +++ b/dts/arm/adi/max32/max32666.dtsi @@ -187,6 +187,7 @@ status = "disabled"; disk-name = "SD"; }; + power-delay-ms = <1500>; clocks = <&gcr ADI_MAX32_CLOCK_BUS1 10>; }; diff --git a/dts/arm/nxp/nxp_k6x.dtsi b/dts/arm/nxp/nxp_k6x.dtsi index 05fc5209a3ad..0e7b71eb7155 100644 --- a/dts/arm/nxp/nxp_k6x.dtsi +++ b/dts/arm/nxp/nxp_k6x.dtsi @@ -515,7 +515,8 @@ compatible = "nxp,flexcan"; reg = <0x40024000 0x1000>; interrupts = <75 0>, <76 0>, <77 0>, <78 0>, <79 0>, <80 0>; - interrupt-names = "mb-0-15", "bus-off", "error", "tx-warning", "rx-warning", "wake-up"; + interrupt-names = "mb-0-15", "bus-off", "error", "tx-warning", "rx-warning", + "wake-up"; clocks = <&sim KINETIS_SIM_BUS_CLK 0x103C 4>; clk-source = <1>; status = "disabled"; diff --git a/dts/arm/silabs/efm32wg990f256.dtsi b/dts/arm/silabs/efm32wg990f256.dtsi index 02cf261cf45e..1152bfd78ef9 100644 --- a/dts/arm/silabs/efm32wg990f256.dtsi +++ b/dts/arm/silabs/efm32wg990f256.dtsi @@ -9,7 +9,8 @@ / { soc { - compatible = "silabs,efm32wg990f256", "silabs,efm32wg", "silabs,efm32", "simple-bus"; + compatible = "silabs,efm32wg990f256", "silabs,efm32wg", "silabs,efm32", + "simple-bus"; }; }; diff --git a/dts/arm/silabs/xg1/efm32pg1b200f256gm48.dtsi b/dts/arm/silabs/xg1/efm32pg1b200f256gm48.dtsi index f09597310eb8..0524f6bfea27 100644 --- a/dts/arm/silabs/xg1/efm32pg1b200f256gm48.dtsi +++ b/dts/arm/silabs/xg1/efm32pg1b200f256gm48.dtsi @@ -9,7 +9,8 @@ / { soc { - compatible = "silabs,efm32pg1b200f256gm48", "silabs,efm32pg1b", "silabs,efm32", "simple-bus"; + compatible = "silabs,efm32pg1b200f256gm48", "silabs,efm32pg1b", "silabs,efm32", + "simple-bus"; }; }; diff --git a/dts/arm/silabs/xg1/efr32fg1p133f256gm48.dtsi b/dts/arm/silabs/xg1/efr32fg1p133f256gm48.dtsi index 89e740804e4e..900c303386ce 100644 --- a/dts/arm/silabs/xg1/efr32fg1p133f256gm48.dtsi +++ b/dts/arm/silabs/xg1/efr32fg1p133f256gm48.dtsi @@ -9,7 +9,8 @@ / { soc { - compatible = "silabs,efr32fg1p133f256gm48", "silabs,efr32fg1p", "silabs,efr32", "simple-bus"; + compatible = "silabs,efr32fg1p133f256gm48", "silabs,efr32fg1p", "silabs,efr32", + "simple-bus"; }; }; diff --git a/dts/arm/silabs/xg12/efm32jg12b500f1024gl125.dtsi b/dts/arm/silabs/xg12/efm32jg12b500f1024gl125.dtsi index 71ea057bcca0..151d1fc48106 100644 --- a/dts/arm/silabs/xg12/efm32jg12b500f1024gl125.dtsi +++ b/dts/arm/silabs/xg12/efm32jg12b500f1024gl125.dtsi @@ -9,7 +9,8 @@ / { soc { - compatible = "silabs,efm32jg12b500f1024gl125", "silabs,efm32jg12b", "silabs,efm32", "simple-bus"; + compatible = "silabs,efm32jg12b500f1024gl125", "silabs,efm32jg12b", "silabs,efm32", + "simple-bus"; }; }; diff --git a/dts/arm/silabs/xg12/efm32pg12b500f1024gl125.dtsi b/dts/arm/silabs/xg12/efm32pg12b500f1024gl125.dtsi index a2384df16a5e..968a46595e41 100644 --- a/dts/arm/silabs/xg12/efm32pg12b500f1024gl125.dtsi +++ b/dts/arm/silabs/xg12/efm32pg12b500f1024gl125.dtsi @@ -9,7 +9,8 @@ / { soc { - compatible = "silabs,efm32pg12b500f1024gl125", "silabs,efm32pg12b", "silabs,efm32", "simple-bus"; + compatible = "silabs,efm32pg12b500f1024gl125", "silabs,efm32pg12b", "silabs,efm32", + "simple-bus"; }; }; diff --git a/dts/vendor/nordic/nrf54l_05_10_15.dtsi b/dts/vendor/nordic/nrf54l_05_10_15.dtsi index 2e74909fd04e..bbd9e135e3d7 100644 --- a/dts/vendor/nordic/nrf54l_05_10_15.dtsi +++ b/dts/vendor/nordic/nrf54l_05_10_15.dtsi @@ -82,7 +82,6 @@ #ifdef USE_NON_SECURE_ADDRESS_MAP /* intentionally empty because UICR is hardware fixed to Secure */ #else - uicr: uicr@ffd000 { compatible = "nordic,nrf-uicr"; reg = <0xffd000 0x1000>; @@ -108,7 +107,6 @@ #size-cells = <1>; ranges = <0x0 0x40000000 0x10000000>; #else - global_peripherals: peripheral@50000000 { reg = <0x50000000 0x10000000>; #address-cells = <1>; @@ -674,7 +672,6 @@ #ifdef USE_NON_SECURE_ADDRESS_MAP /* intentionally empty because WDT30 is hardware fixed to Secure */ #else - wdt30: watchdog@108000 { compatible = "nordic,nrf-wdt"; reg = <0x108000 0x620>; diff --git a/dts/vendor/nordic/nrf54lm20a.dtsi b/dts/vendor/nordic/nrf54lm20a.dtsi index 1fde09b2eb28..1b467f1171ed 100644 --- a/dts/vendor/nordic/nrf54lm20a.dtsi +++ b/dts/vendor/nordic/nrf54lm20a.dtsi @@ -99,7 +99,6 @@ #ifdef USE_NON_SECURE_ADDRESS_MAP /* intentionally empty because UICR is hardware fixed to Secure */ #else - uicr: uicr@ffd000 { compatible = "nordic,nrf-uicr"; reg = <0xffd000 0x1000>; @@ -129,7 +128,6 @@ #size-cells = <1>; ranges = <0x0 0x40000000 0x10000000>; #else - global_peripherals: peripheral@50000000 { reg = <0x50000000 0x10000000>; ranges = <0x0 0x50000000 0x10000000>; @@ -765,7 +763,6 @@ #ifdef USE_NON_SECURE_ADDRESS_MAP /* intentionally empty because WDT30 is hardware fixed to Secure */ #else - wdt30: watchdog@108000 { compatible = "nordic,nrf-wdt"; reg = <0x108000 0x620>; diff --git a/samples/drivers/adc/adc_dt/boards/da1469x_dk_pro.overlay b/samples/drivers/adc/adc_dt/boards/da1469x_dk_pro.overlay index a781c0a4f6a1..5b4a060418de 100644 --- a/samples/drivers/adc/adc_dt/boards/da1469x_dk_pro.overlay +++ b/samples/drivers/adc/adc_dt/boards/da1469x_dk_pro.overlay @@ -75,6 +75,7 @@ zephyr,oversampling = <0>; zephyr,input-positive = ; }; + pinctrl-0 = <&adc_default>; pinctrl-names = "default"; }; @@ -114,6 +115,7 @@ zephyr,oversampling = <7>; zephyr,input-positive = ; }; + pinctrl-0 = <&sdadc_default>; pinctrl-names = "default"; }; diff --git a/samples/drivers/adc/adc_dt/boards/siwx917_rb4338a.overlay b/samples/drivers/adc/adc_dt/boards/siwx917_rb4338a.overlay index 50212190bada..c26eda458d22 100644 --- a/samples/drivers/adc/adc_dt/boards/siwx917_rb4338a.overlay +++ b/samples/drivers/adc/adc_dt/boards/siwx917_rb4338a.overlay @@ -31,5 +31,6 @@ zephyr,resolution = <12>; zephyr,input-positive = <10>; }; + status = "okay"; }; diff --git a/samples/drivers/adc/adc_dt/boards/xmc45_relax_kit.overlay b/samples/drivers/adc/adc_dt/boards/xmc45_relax_kit.overlay index a9fbe127f131..cc0bf422e74a 100644 --- a/samples/drivers/adc/adc_dt/boards/xmc45_relax_kit.overlay +++ b/samples/drivers/adc/adc_dt/boards/xmc45_relax_kit.overlay @@ -21,5 +21,6 @@ zephyr,reference = "ADC_REF_INTERNAL"; zephyr,resolution = <12>; }; + status = "okay"; }; diff --git a/samples/subsys/display/lvgl/boards/wio_terminal.overlay b/samples/subsys/display/lvgl/boards/wio_terminal.overlay index 2f9e228cd821..85e48a9d9fad 100644 --- a/samples/subsys/display/lvgl/boards/wio_terminal.overlay +++ b/samples/subsys/display/lvgl/boards/wio_terminal.overlay @@ -17,7 +17,8 @@ lvgl_keypad_input { compatible = "zephyr,lvgl-keypad-input"; input = <&joystick>; - input-codes = ; + input-codes = ; lvgl-codes = ; }; }; diff --git a/samples/subsys/fs/fs_sample/boards/hifive_unmatched.overlay b/samples/subsys/fs/fs_sample/boards/hifive_unmatched.overlay index ad6b6ccdf55d..6c265cc51bd2 100644 --- a/samples/subsys/fs/fs_sample/boards/hifive_unmatched.overlay +++ b/samples/subsys/fs/fs_sample/boards/hifive_unmatched.overlay @@ -17,6 +17,7 @@ disk-name = "SD"; status = "okay"; }; + spi-max-frequency = <20000000>; }; }; diff --git a/samples/subsys/fs/fs_sample/boards/nrf52840_blip.overlay b/samples/subsys/fs/fs_sample/boards/nrf52840_blip.overlay index 043a434f394c..1c668afadcaa 100644 --- a/samples/subsys/fs/fs_sample/boards/nrf52840_blip.overlay +++ b/samples/subsys/fs/fs_sample/boards/nrf52840_blip.overlay @@ -18,6 +18,7 @@ disk-name = "SD"; status = "okay"; }; + spi-max-frequency = <24000000>; }; }; diff --git a/samples/subsys/fs/fs_sample/boards/nucleo_f429zi.overlay b/samples/subsys/fs/fs_sample/boards/nucleo_f429zi.overlay index c24abf2e4962..6394b760d7ca 100644 --- a/samples/subsys/fs/fs_sample/boards/nucleo_f429zi.overlay +++ b/samples/subsys/fs/fs_sample/boards/nucleo_f429zi.overlay @@ -15,6 +15,7 @@ disk-name = "SD"; status = "okay"; }; + spi-max-frequency = <25000000>; spi-clock-mode-cpol; spi-clock-mode-cpha; diff --git a/samples/subsys/fs/littlefs/boards/rcar_h3ulcb_r8a77951_a57.overlay b/samples/subsys/fs/littlefs/boards/rcar_h3ulcb_r8a77951_a57.overlay index 9442e02b45f5..8ab023a5c50f 100644 --- a/samples/subsys/fs/littlefs/boards/rcar_h3ulcb_r8a77951_a57.overlay +++ b/samples/subsys/fs/littlefs/boards/rcar_h3ulcb_r8a77951_a57.overlay @@ -4,5 +4,6 @@ disk { status = "okay"; }; + status = "okay"; }; diff --git a/samples/subsys/fs/littlefs/boards/rcar_salvator_xs.overlay b/samples/subsys/fs/littlefs/boards/rcar_salvator_xs.overlay index 9442e02b45f5..8ab023a5c50f 100644 --- a/samples/subsys/fs/littlefs/boards/rcar_salvator_xs.overlay +++ b/samples/subsys/fs/littlefs/boards/rcar_salvator_xs.overlay @@ -4,5 +4,6 @@ disk { status = "okay"; }; + status = "okay"; }; diff --git a/samples/subsys/modbus/rtu_client/boards/arduino_opta_stm32h747xx_m7.overlay b/samples/subsys/modbus/rtu_client/boards/arduino_opta_stm32h747xx_m7.overlay index 1838da4c32c3..13025f0b1726 100644 --- a/samples/subsys/modbus/rtu_client/boards/arduino_opta_stm32h747xx_m7.overlay +++ b/samples/subsys/modbus/rtu_client/boards/arduino_opta_stm32h747xx_m7.overlay @@ -8,5 +8,6 @@ modbus0 { status = "okay"; }; + status = "okay"; }; diff --git a/samples/subsys/modbus/rtu_server/boards/arduino_opta_stm32h747xx_m7.overlay b/samples/subsys/modbus/rtu_server/boards/arduino_opta_stm32h747xx_m7.overlay index 1838da4c32c3..13025f0b1726 100644 --- a/samples/subsys/modbus/rtu_server/boards/arduino_opta_stm32h747xx_m7.overlay +++ b/samples/subsys/modbus/rtu_server/boards/arduino_opta_stm32h747xx_m7.overlay @@ -8,5 +8,6 @@ modbus0 { status = "okay"; }; + status = "okay"; }; diff --git a/samples/subsys/sensing/simple/boards/native_sim.overlay b/samples/subsys/sensing/simple/boards/native_sim.overlay index 73a81b81f640..18d2f7ef36a6 100644 --- a/samples/subsys/sensing/simple/boards/native_sim.overlay +++ b/samples/subsys/sensing/simple/boards/native_sim.overlay @@ -29,7 +29,8 @@ base_accel_gyro: base-accel-gyro { compatible = "zephyr,sensing-phy-3d-sensor"; status = "okay"; - sensor-types = ; + sensor-types = ; friendly-name = "Base Accel Gyro Sensor"; minimal-interval = <625>; underlying-device = <&bmi160_i2c>; @@ -38,7 +39,8 @@ lid_accel_gyro: lid-accel-gyro { compatible = "zephyr,sensing-phy-3d-sensor"; status = "okay"; - sensor-types = ; + sensor-types = ; friendly-name = "Lid Accel Gyro Sensor"; minimal-interval = <625>; underlying-device = <&bmi160_spi>; diff --git a/samples/subsys/usb_c/source/boards/stm32g081b_eval.overlay b/samples/subsys/usb_c/source/boards/stm32g081b_eval.overlay index 94b4ab3d3601..5f8f61439921 100644 --- a/samples/subsys/usb_c/source/boards/stm32g081b_eval.overlay +++ b/samples/subsys/usb_c/source/boards/stm32g081b_eval.overlay @@ -73,7 +73,8 @@ vbus = <&vbus1>; power-role = "source"; typec-power-opmode = "3.0A"; - source-pdos = ; + source-pdos = ; }; /* usbc.rst usbc-port end */ }; diff --git a/tests/drivers/adc/adc_api/boards/siwx917_dk2605a.overlay b/tests/drivers/adc/adc_api/boards/siwx917_dk2605a.overlay index 46fb27d52f4e..a27f1410c174 100644 --- a/tests/drivers/adc/adc_api/boards/siwx917_dk2605a.overlay +++ b/tests/drivers/adc/adc_api/boards/siwx917_dk2605a.overlay @@ -41,5 +41,6 @@ zephyr,resolution = <12>; zephyr,input-positive = <7>; }; + status = "okay"; }; diff --git a/tests/drivers/adc/adc_api/boards/siwx917_rb4338a.overlay b/tests/drivers/adc/adc_api/boards/siwx917_rb4338a.overlay index adf970571e68..10ca93827b58 100644 --- a/tests/drivers/adc/adc_api/boards/siwx917_rb4338a.overlay +++ b/tests/drivers/adc/adc_api/boards/siwx917_rb4338a.overlay @@ -40,5 +40,6 @@ zephyr,resolution = <12>; zephyr,input-positive = <7>; }; + status = "okay"; }; diff --git a/tests/drivers/build_all/input/app.overlay b/tests/drivers/build_all/input/app.overlay index 6bce18c7448b..db3183d90b4b 100644 --- a/tests/drivers/build_all/input/app.overlay +++ b/tests/drivers/build_all/input/app.overlay @@ -69,6 +69,7 @@ gpios = <&test_gpio 0 0>; zephyr,code = <0>; }; + polling-mode; }; diff --git a/tests/drivers/disk/disk_performance/boards/rcar_h3ulcb_r8a77951_a57.overlay b/tests/drivers/disk/disk_performance/boards/rcar_h3ulcb_r8a77951_a57.overlay index 9442e02b45f5..8ab023a5c50f 100644 --- a/tests/drivers/disk/disk_performance/boards/rcar_h3ulcb_r8a77951_a57.overlay +++ b/tests/drivers/disk/disk_performance/boards/rcar_h3ulcb_r8a77951_a57.overlay @@ -4,5 +4,6 @@ disk { status = "okay"; }; + status = "okay"; }; diff --git a/tests/drivers/disk/disk_performance/boards/rcar_salvator_xs.overlay b/tests/drivers/disk/disk_performance/boards/rcar_salvator_xs.overlay index 9442e02b45f5..8ab023a5c50f 100644 --- a/tests/drivers/disk/disk_performance/boards/rcar_salvator_xs.overlay +++ b/tests/drivers/disk/disk_performance/boards/rcar_salvator_xs.overlay @@ -4,5 +4,6 @@ disk { status = "okay"; }; + status = "okay"; }; diff --git a/tests/drivers/pwm/pwm_api/boards/siwx917_rb4338a.overlay b/tests/drivers/pwm/pwm_api/boards/siwx917_rb4338a.overlay index 4d0e8cb76e03..7f86e41fb72b 100644 --- a/tests/drivers/pwm/pwm_api/boards/siwx917_rb4338a.overlay +++ b/tests/drivers/pwm/pwm_api/boards/siwx917_rb4338a.overlay @@ -27,6 +27,7 @@ pwm_channel1: pwm_channel1 { pwms = <&pwm 0 1000000>; }; + silabs,pwm-polarity = ; status = "okay"; }; diff --git a/tests/drivers/pwm/pwm_api/boards/siwx917_rb4342a.overlay b/tests/drivers/pwm/pwm_api/boards/siwx917_rb4342a.overlay index 4d0e8cb76e03..7f86e41fb72b 100644 --- a/tests/drivers/pwm/pwm_api/boards/siwx917_rb4342a.overlay +++ b/tests/drivers/pwm/pwm_api/boards/siwx917_rb4342a.overlay @@ -27,6 +27,7 @@ pwm_channel1: pwm_channel1 { pwms = <&pwm 0 1000000>; }; + silabs,pwm-polarity = ; status = "okay"; }; diff --git a/tests/drivers/spi/spi_controller_peripheral/boards/frdm_mcxa156.overlay b/tests/drivers/spi/spi_controller_peripheral/boards/frdm_mcxa156.overlay index c533c11b4fd0..0652ffa48dec 100644 --- a/tests/drivers/spi/spi_controller_peripheral/boards/frdm_mcxa156.overlay +++ b/tests/drivers/spi/spi_controller_peripheral/boards/frdm_mcxa156.overlay @@ -18,6 +18,7 @@ reg = <0>; spi-max-frequency = <10000000>; }; + transfer-delay = <100>; sck-pcs-delay = <10>; pcs-sck-delay = <10>; diff --git a/tests/drivers/spi/spi_loopback/boards/mimxrt1010_evk.overlay b/tests/drivers/spi/spi_loopback/boards/mimxrt1010_evk.overlay index 7595f78e886a..e4bf0ce3ccf9 100644 --- a/tests/drivers/spi/spi_loopback/boards/mimxrt1010_evk.overlay +++ b/tests/drivers/spi/spi_loopback/boards/mimxrt1010_evk.overlay @@ -16,6 +16,7 @@ reg = <0>; spi-max-frequency = <16000000>; }; + transfer-delay = <100>; pcs-sck-delay = <100>; sck-pcs-delay = <100>; diff --git a/tests/drivers/spi/spi_loopback/boards/mimxrt1015_evk.overlay b/tests/drivers/spi/spi_loopback/boards/mimxrt1015_evk.overlay index 7595f78e886a..e4bf0ce3ccf9 100644 --- a/tests/drivers/spi/spi_loopback/boards/mimxrt1015_evk.overlay +++ b/tests/drivers/spi/spi_loopback/boards/mimxrt1015_evk.overlay @@ -16,6 +16,7 @@ reg = <0>; spi-max-frequency = <16000000>; }; + transfer-delay = <100>; pcs-sck-delay = <100>; sck-pcs-delay = <100>; diff --git a/tests/drivers/spi/spi_loopback/boards/mimxrt1020_evk.overlay b/tests/drivers/spi/spi_loopback/boards/mimxrt1020_evk.overlay index 7595f78e886a..e4bf0ce3ccf9 100644 --- a/tests/drivers/spi/spi_loopback/boards/mimxrt1020_evk.overlay +++ b/tests/drivers/spi/spi_loopback/boards/mimxrt1020_evk.overlay @@ -16,6 +16,7 @@ reg = <0>; spi-max-frequency = <16000000>; }; + transfer-delay = <100>; pcs-sck-delay = <100>; sck-pcs-delay = <100>; diff --git a/tests/drivers/spi/spi_loopback/boards/mimxrt1024_evk.overlay b/tests/drivers/spi/spi_loopback/boards/mimxrt1024_evk.overlay index 7595f78e886a..e4bf0ce3ccf9 100644 --- a/tests/drivers/spi/spi_loopback/boards/mimxrt1024_evk.overlay +++ b/tests/drivers/spi/spi_loopback/boards/mimxrt1024_evk.overlay @@ -16,6 +16,7 @@ reg = <0>; spi-max-frequency = <16000000>; }; + transfer-delay = <100>; pcs-sck-delay = <100>; sck-pcs-delay = <100>; diff --git a/tests/drivers/spi/spi_loopback/boards/mimxrt1040_evk.overlay b/tests/drivers/spi/spi_loopback/boards/mimxrt1040_evk.overlay index 56afa5dfcda5..f51762813ac4 100644 --- a/tests/drivers/spi/spi_loopback/boards/mimxrt1040_evk.overlay +++ b/tests/drivers/spi/spi_loopback/boards/mimxrt1040_evk.overlay @@ -16,6 +16,7 @@ reg = <0>; spi-max-frequency = <16000000>; }; + transfer-delay = <100>; pcs-sck-delay = <100>; sck-pcs-delay = <100>; diff --git a/tests/drivers/spi/spi_loopback/boards/mimxrt1060_evk_mimxrt1062_qspi.overlay b/tests/drivers/spi/spi_loopback/boards/mimxrt1060_evk_mimxrt1062_qspi.overlay index 7595f78e886a..e4bf0ce3ccf9 100644 --- a/tests/drivers/spi/spi_loopback/boards/mimxrt1060_evk_mimxrt1062_qspi.overlay +++ b/tests/drivers/spi/spi_loopback/boards/mimxrt1060_evk_mimxrt1062_qspi.overlay @@ -16,6 +16,7 @@ reg = <0>; spi-max-frequency = <16000000>; }; + transfer-delay = <100>; pcs-sck-delay = <100>; sck-pcs-delay = <100>; diff --git a/tests/drivers/spi/spi_loopback/boards/mimxrt1060_evk_mimxrt1062_qspi_C.overlay b/tests/drivers/spi/spi_loopback/boards/mimxrt1060_evk_mimxrt1062_qspi_C.overlay index a9085f30d735..e259e585a71d 100644 --- a/tests/drivers/spi/spi_loopback/boards/mimxrt1060_evk_mimxrt1062_qspi_C.overlay +++ b/tests/drivers/spi/spi_loopback/boards/mimxrt1060_evk_mimxrt1062_qspi_C.overlay @@ -17,6 +17,7 @@ reg = <0>; spi-max-frequency = <16000000>; }; + transfer-delay = <100>; pcs-sck-delay = <100>; sck-pcs-delay = <100>; diff --git a/tests/drivers/spi/spi_loopback/boards/mimxrt1064_evk.overlay b/tests/drivers/spi/spi_loopback/boards/mimxrt1064_evk.overlay index 7595f78e886a..e4bf0ce3ccf9 100644 --- a/tests/drivers/spi/spi_loopback/boards/mimxrt1064_evk.overlay +++ b/tests/drivers/spi/spi_loopback/boards/mimxrt1064_evk.overlay @@ -16,6 +16,7 @@ reg = <0>; spi-max-frequency = <16000000>; }; + transfer-delay = <100>; pcs-sck-delay = <100>; sck-pcs-delay = <100>; diff --git a/tests/drivers/spi/spi_loopback/boards/mimxrt1170_evk_mimxrt1176_cm4_B.overlay b/tests/drivers/spi/spi_loopback/boards/mimxrt1170_evk_mimxrt1176_cm4_B.overlay index 56afa5dfcda5..f51762813ac4 100644 --- a/tests/drivers/spi/spi_loopback/boards/mimxrt1170_evk_mimxrt1176_cm4_B.overlay +++ b/tests/drivers/spi/spi_loopback/boards/mimxrt1170_evk_mimxrt1176_cm4_B.overlay @@ -16,6 +16,7 @@ reg = <0>; spi-max-frequency = <16000000>; }; + transfer-delay = <100>; pcs-sck-delay = <100>; sck-pcs-delay = <100>; diff --git a/tests/drivers/spi/spi_loopback/boards/mimxrt1170_evk_mimxrt1176_cm7_A.overlay b/tests/drivers/spi/spi_loopback/boards/mimxrt1170_evk_mimxrt1176_cm7_A.overlay index 7dd3cb966353..8dea5a6db95a 100644 --- a/tests/drivers/spi/spi_loopback/boards/mimxrt1170_evk_mimxrt1176_cm7_A.overlay +++ b/tests/drivers/spi/spi_loopback/boards/mimxrt1170_evk_mimxrt1176_cm7_A.overlay @@ -20,6 +20,7 @@ reg = <0>; spi-max-frequency = <16000000>; }; + transfer-delay = <100>; pcs-sck-delay = <100>; sck-pcs-delay = <100>; diff --git a/tests/drivers/spi/spi_loopback/boards/mimxrt1170_evk_mimxrt1176_cm7_B.overlay b/tests/drivers/spi/spi_loopback/boards/mimxrt1170_evk_mimxrt1176_cm7_B.overlay index 56afa5dfcda5..f51762813ac4 100644 --- a/tests/drivers/spi/spi_loopback/boards/mimxrt1170_evk_mimxrt1176_cm7_B.overlay +++ b/tests/drivers/spi/spi_loopback/boards/mimxrt1170_evk_mimxrt1176_cm7_B.overlay @@ -16,6 +16,7 @@ reg = <0>; spi-max-frequency = <16000000>; }; + transfer-delay = <100>; pcs-sck-delay = <100>; sck-pcs-delay = <100>; diff --git a/tests/drivers/spi/spi_loopback/boards/mimxrt1180_evk_mimxrt1189_cm33.overlay b/tests/drivers/spi/spi_loopback/boards/mimxrt1180_evk_mimxrt1189_cm33.overlay index 0fe45f47f40c..4c711fd7be8d 100644 --- a/tests/drivers/spi/spi_loopback/boards/mimxrt1180_evk_mimxrt1189_cm33.overlay +++ b/tests/drivers/spi/spi_loopback/boards/mimxrt1180_evk_mimxrt1189_cm33.overlay @@ -18,6 +18,7 @@ reg = <0>; spi-max-frequency = <16000000>; }; + transfer-delay = <100>; pcs-sck-delay = <100>; sck-pcs-delay = <100>; diff --git a/tests/drivers/spi/spi_loopback/boards/mimxrt1180_evk_mimxrt1189_cm7.overlay b/tests/drivers/spi/spi_loopback/boards/mimxrt1180_evk_mimxrt1189_cm7.overlay index 70ba5ecc8a70..0f61df274f42 100644 --- a/tests/drivers/spi/spi_loopback/boards/mimxrt1180_evk_mimxrt1189_cm7.overlay +++ b/tests/drivers/spi/spi_loopback/boards/mimxrt1180_evk_mimxrt1189_cm7.overlay @@ -30,6 +30,7 @@ reg = <0>; spi-max-frequency = <16000000>; }; + transfer-delay = <100>; pcs-sck-delay = <100>; sck-pcs-delay = <100>; diff --git a/tests/drivers/spi/spi_loopback/boards/nrf54h20dk_nrf54h20_common.dtsi b/tests/drivers/spi/spi_loopback/boards/nrf54h20dk_nrf54h20_common.dtsi index ce32c7627d4f..dd8880c8e056 100644 --- a/tests/drivers/spi/spi_loopback/boards/nrf54h20dk_nrf54h20_common.dtsi +++ b/tests/drivers/spi/spi_loopback/boards/nrf54h20dk_nrf54h20_common.dtsi @@ -51,6 +51,7 @@ reg = <0>; spi-max-frequency = ; }; + cs-gpios = <&gpio7 0 0>; }; diff --git a/tests/drivers/spi/spi_loopback/boards/numaker_m2l31ki.overlay b/tests/drivers/spi/spi_loopback/boards/numaker_m2l31ki.overlay index 0ea2045895cb..5e61762a671e 100644 --- a/tests/drivers/spi/spi_loopback/boards/numaker_m2l31ki.overlay +++ b/tests/drivers/spi/spi_loopback/boards/numaker_m2l31ki.overlay @@ -28,6 +28,7 @@ reg = <0>; spi-max-frequency = <16000000>; }; + status = "okay"; pinctrl-0 = <&spi0_default>; pinctrl-names = "default"; diff --git a/tests/drivers/spi/spi_loopback/boards/numaker_m3334ki.overlay b/tests/drivers/spi/spi_loopback/boards/numaker_m3334ki.overlay index b0992ad156c7..246ec0320fc5 100644 --- a/tests/drivers/spi/spi_loopback/boards/numaker_m3334ki.overlay +++ b/tests/drivers/spi/spi_loopback/boards/numaker_m3334ki.overlay @@ -28,6 +28,7 @@ reg = <0>; spi-max-frequency = ; }; + status = "okay"; pinctrl-0 = <&spi2_default>; pinctrl-names = "default"; diff --git a/tests/drivers/spi/spi_loopback/boards/numaker_m55m1.overlay b/tests/drivers/spi/spi_loopback/boards/numaker_m55m1.overlay index e8b65b2c457c..d613ffe7b320 100644 --- a/tests/drivers/spi/spi_loopback/boards/numaker_m55m1.overlay +++ b/tests/drivers/spi/spi_loopback/boards/numaker_m55m1.overlay @@ -24,6 +24,7 @@ reg = <0>; spi-max-frequency = ; }; + status = "okay"; pinctrl-0 = <&spi2_default>; pinctrl-names = "default"; diff --git a/tests/drivers/spi/spi_loopback/boards/numaker_pfm_m467.overlay b/tests/drivers/spi/spi_loopback/boards/numaker_pfm_m467.overlay index ceaf2664299b..6b03eb185b43 100644 --- a/tests/drivers/spi/spi_loopback/boards/numaker_pfm_m467.overlay +++ b/tests/drivers/spi/spi_loopback/boards/numaker_pfm_m467.overlay @@ -28,6 +28,7 @@ reg = <0>; spi-max-frequency = <16000000>; }; + status = "okay"; pinctrl-0 = <&spi2_default>; pinctrl-names = "default"; diff --git a/tests/lib/devicetree/api/app.overlay b/tests/lib/devicetree/api/app.overlay index 4df236d10863..05889318e38e 100644 --- a/tests/lib/devicetree/api/app.overlay +++ b/tests/lib/devicetree/api/app.overlay @@ -72,7 +72,8 @@ phs = <&test_i2c &test_spi>; phs-or = <&test_enum_default_0 &test_enum_default_1>; gpios = <&test_gpio_1 10 20>, <&test_gpio_2 30 40>; - pha-gpios = <&test_gpio_1 50 60>, <0>, <&test_gpio_3 70>, <&test_gpio_2 80 90>; + pha-gpios = <&test_gpio_1 50 60>, <0>, <&test_gpio_3 70>, + <&test_gpio_2 80 90>; foos = <&test_gpio_1 100>, <&test_gpio_2 110>; foo-names = "A", "b-c"; pwms = <&test_pwm1 8 200 3>, <&test_pwm2 5 100 1>; diff --git a/tests/subsys/fs/ext2/boards/hifive_unmatched_fu740_s7.overlay b/tests/subsys/fs/ext2/boards/hifive_unmatched_fu740_s7.overlay index ad6b6ccdf55d..6c265cc51bd2 100644 --- a/tests/subsys/fs/ext2/boards/hifive_unmatched_fu740_s7.overlay +++ b/tests/subsys/fs/ext2/boards/hifive_unmatched_fu740_s7.overlay @@ -17,6 +17,7 @@ disk-name = "SD"; status = "okay"; }; + spi-max-frequency = <20000000>; }; }; diff --git a/tests/subsys/fs/ext2/boards/hifive_unmatched_fu740_u74.overlay b/tests/subsys/fs/ext2/boards/hifive_unmatched_fu740_u74.overlay index ad6b6ccdf55d..6c265cc51bd2 100644 --- a/tests/subsys/fs/ext2/boards/hifive_unmatched_fu740_u74.overlay +++ b/tests/subsys/fs/ext2/boards/hifive_unmatched_fu740_u74.overlay @@ -17,6 +17,7 @@ disk-name = "SD"; status = "okay"; }; + spi-max-frequency = <20000000>; }; }; diff --git a/tests/subsys/modbus/boards/arduino_opta_stm32h747xx_m7.overlay b/tests/subsys/modbus/boards/arduino_opta_stm32h747xx_m7.overlay index 1838da4c32c3..13025f0b1726 100644 --- a/tests/subsys/modbus/boards/arduino_opta_stm32h747xx_m7.overlay +++ b/tests/subsys/modbus/boards/arduino_opta_stm32h747xx_m7.overlay @@ -8,5 +8,6 @@ modbus0 { status = "okay"; }; + status = "okay"; }; diff --git a/tests/subsys/sd/mmc/boards/rcar_h3ulcb_r8a77951_a57.overlay b/tests/subsys/sd/mmc/boards/rcar_h3ulcb_r8a77951_a57.overlay index 9442e02b45f5..8ab023a5c50f 100644 --- a/tests/subsys/sd/mmc/boards/rcar_h3ulcb_r8a77951_a57.overlay +++ b/tests/subsys/sd/mmc/boards/rcar_h3ulcb_r8a77951_a57.overlay @@ -4,5 +4,6 @@ disk { status = "okay"; }; + status = "okay"; }; diff --git a/tests/subsys/sensing/boards/native_sim.overlay b/tests/subsys/sensing/boards/native_sim.overlay index 38096e477714..d02c97d7c838 100644 --- a/tests/subsys/sensing/boards/native_sim.overlay +++ b/tests/subsys/sensing/boards/native_sim.overlay @@ -29,7 +29,8 @@ base_accel_gyro: base-accel-gyro { compatible = "zephyr,sensing-phy-3d-sensor"; status = "okay"; - sensor-types = ; + sensor-types = ; friendly-name = "Base Accel Gyro Sensor"; minimal-interval = <625>; underlying-device = <&bmi160_i2c>; @@ -38,7 +39,8 @@ lid_accel_gyro: lid-accel-gyro { compatible = "zephyr,sensing-phy-3d-sensor"; status = "okay"; - sensor-types = ; + sensor-types = ; friendly-name = "Lid Accel Gyro Sensor"; minimal-interval = <625>; underlying-device = <&bmi160_spi>; From 5ce1df22fa4c52c85306795c286e980a701777bb Mon Sep 17 00:00:00 2001 From: Jason Yu Date: Fri, 14 Nov 2025 15:56:21 +0800 Subject: [PATCH 0326/3659] drivers: counter: nxp_mrt: Support power device constraint Call pm_policy_device_power_lock_put/pm_policy_device_power_lock_get to coordinate with system level power modes. Signed-off-by: Jason Yu --- drivers/counter/counter_nxp_mrt.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/counter/counter_nxp_mrt.c b/drivers/counter/counter_nxp_mrt.c index b08a6765fc42..9e1446260f4f 100644 --- a/drivers/counter/counter_nxp_mrt.c +++ b/drivers/counter/counter_nxp_mrt.c @@ -23,6 +23,7 @@ #include #include #include +#include #include @@ -73,6 +74,8 @@ static int nxp_mrt_stop(const struct device *dev) /* LOAD bit and 0 ivalue allows us to forcibly stop the timer */ base->CHANNEL[channel_id].INTVAL = MRT_CHANNEL_INTVAL_LOAD(1); + pm_policy_device_power_lock_put(dev); + return 0; } @@ -90,6 +93,8 @@ static int nxp_mrt_start(const struct device *dev) data->top = config->info.max_top_value; } + pm_policy_device_power_lock_get(dev); + /* Start with previously configured top value (if already running this has no effect) */ base->CHANNEL[channel_id].INTVAL = data->top; From 1bbbedc9569fbea6573012b139ce16c5950cf412 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Wed, 10 Dec 2025 19:13:42 +0100 Subject: [PATCH 0327/3659] arch: introduce arch_zli_lock and arch_zli_unlock Introduce APIs for locking zero latency interrupts. Zero latency interrupts are defined as non-maskable interrupts "above" the kernel. They can not be locked by the kernel. However, there are cases where we do need to mask/lock ZLIs from the kernel, namely when accessing and changing the state of core shared hardware like RAM and the CPU which must be done atomically. A common case is when powering down or rebooting the SoC. We can't allow any IRQ, ZLI or not, to interrupt these operations. In any case, such an interrupt would be immediately followed by the CPU being off, and whatever process running from ZLIs would be terminated anyway. Since we have specific usecases which require these APIs, and there are already drivers and socs which do lock ZLIs by directly calling arch APIs to acheive this, let's officially add the APIs with appropriate documentation detailing expected usecases and warning of the dire consequences of misusing it, keeping it in arch/cpu.h to limit exposure of the API (compared to having it in zephyr/irq.h). Signed-off-by: Bjarki Arge Andreasen --- include/zephyr/arch/arch_interface.h | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/include/zephyr/arch/arch_interface.h b/include/zephyr/arch/arch_interface.h index 881af15ff33f..f53298e08fde 100644 --- a/include/zephyr/arch/arch_interface.h +++ b/include/zephyr/arch/arch_interface.h @@ -280,6 +280,28 @@ static inline void arch_irq_unlock(unsigned int key); */ static inline bool arch_irq_unlocked(unsigned int key); +#ifdef CONFIG_ZERO_LATENCY_IRQS + +/** + * @brief Lock all interrupts including zero latency interrupts on the current CPU. + * + * @details Intended to be used when breaking the promise of zero latency interrupts is + * unavoidable and necessary, like accessing shared core peripherals or powering down the + * SoC. + * + * @warning This lock breaks the promise of zero latency interrupts. + */ +static inline unsigned int arch_zli_lock(void); + +/** + * @brief Unlock all interrupts including zero latency interrupts on the current CPU + * + * @see arch_zli_lock() + */ +static inline void arch_zli_unlock(unsigned int key); + +#endif + /** * Disable the specified interrupt line * From 239d20af9023d983b684f798b01f29e398c892d2 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Wed, 10 Dec 2025 19:44:08 +0100 Subject: [PATCH 0328/3659] arch: arm: implement arch_zli_lock and arch_zli_unlock Implement arch_zli_lock and arch_zli_unlock for the currently only supported target cortex-M. Signed-off-by: Bjarki Arge Andreasen --- include/zephyr/arch/arm/asm_inline_gcc.h | 25 ++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/include/zephyr/arch/arm/asm_inline_gcc.h b/include/zephyr/arch/arm/asm_inline_gcc.h index c0222b8b5486..1aedaf9c6622 100644 --- a/include/zephyr/arch/arm/asm_inline_gcc.h +++ b/include/zephyr/arch/arm/asm_inline_gcc.h @@ -105,6 +105,31 @@ static ALWAYS_INLINE bool arch_irq_unlocked(unsigned int key) return key == 0U; } +#ifdef CONFIG_ZERO_LATENCY_IRQS + +static ALWAYS_INLINE unsigned int arch_zli_lock(void) +{ + unsigned int key; + + key = __get_PRIMASK(); + + /* + * The cpsid instruction is self synchronizing within the instruction stream, no need for + * an explicit __ISB(). + */ + __disable_irq(); + + return key; +} + +static ALWAYS_INLINE void arch_zli_unlock(unsigned int key) +{ + __set_PRIMASK(key); + __ISB(); +} + +#endif /* CONFIG_ZERO_LATENCY_IRQS */ + #ifdef __cplusplus } #endif From 7c72e3cc42cff7db622e2473a7176e66b2847f36 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Wed, 10 Dec 2025 19:50:09 +0100 Subject: [PATCH 0329/3659] lib: os: reboot: Disable ZLIs before reboot We currently only disable "normal" IRQs with irq_lock(). This is not sufficient if ZLIs are enabled, as even though they are supposed to be "above" the kernel, they must not interrupt the reboot procedure. Signed-off-by: Bjarki Arge Andreasen --- lib/os/reboot.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/os/reboot.c b/lib/os/reboot.c index 0a483895dafe..c3b7318b0239 100644 --- a/lib/os/reboot.c +++ b/lib/os/reboot.c @@ -23,6 +23,10 @@ FUNC_NORETURN void sys_reboot(int type) (void)irq_lock(); +#if defined(CONFIG_ZERO_LATENCY_IRQS) + (void)arch_zli_lock(); +#endif /* CONFIG_ZERO_LATENCY_IRQS */ + /* Disable caches to ensure all data is flushed */ #if defined(CONFIG_ARCH_CACHE) #if defined(CONFIG_DCACHE) From 66dbe436bd4e2998494f58e0adbecaddefdc0169 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Wed, 10 Dec 2025 19:56:52 +0100 Subject: [PATCH 0330/3659] lib: os: poweroff: Disable ZLIs before poweroff We currently only disable "normal" IRQs with irq_lock(). This is not sufficient if ZLIs are enabled, as even though they are supposed to be "above" the kernel, they must not interrupt the poweroff procedure. Signed-off-by: Bjarki Arge Andreasen --- lib/os/poweroff.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/os/poweroff.c b/lib/os/poweroff.c index f4e90e477caa..2340f306d97c 100644 --- a/lib/os/poweroff.c +++ b/lib/os/poweroff.c @@ -10,5 +10,9 @@ void sys_poweroff(void) { (void)irq_lock(); +#if defined(CONFIG_ZERO_LATENCY_IRQS) + (void)arch_zli_lock(); +#endif /* CONFIG_ZERO_LATENCY_IRQS */ + z_sys_poweroff(); } From cb93f97bd63207211d92f7c5a0ffd8d5e270dd42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Fri, 12 Dec 2025 16:37:18 +0100 Subject: [PATCH 0331/3659] boards: m5stack: add full_name for NanoC6 board MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add full_name field to the m5stack_nanoc6 board definition Signed-off-by: Benjamin Cabé --- boards/m5stack/m5stack_nanoc6/board.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/boards/m5stack/m5stack_nanoc6/board.yml b/boards/m5stack/m5stack_nanoc6/board.yml index 129d67eb2e16..53975a09f6ab 100644 --- a/boards/m5stack/m5stack_nanoc6/board.yml +++ b/boards/m5stack/m5stack_nanoc6/board.yml @@ -1,5 +1,6 @@ board: name: m5stack_nanoc6 + full_name: NanoC6 vendor: m5stack socs: - name: esp32c6 From b7b32944fcae6d4f226b12d9e677a67ca4a33d0e Mon Sep 17 00:00:00 2001 From: Sylvio Alves Date: Wed, 10 Dec 2025 15:15:07 -0300 Subject: [PATCH 0332/3659] drivers: espressif: move ISRs into IRAM area Most of Espressif drivers ISRs are already running in IRAM area, except those in this PR. Move ISRs accordingly so we avoid any interrupt miss when cache is disabled. Signed-off-by: Sylvio Alves --- drivers/counter/counter_esp32_rtc.c | 4 ++-- drivers/counter/counter_esp32_tmr.c | 4 ++-- drivers/input/input_esp32_touch_sensor.c | 4 ++-- drivers/serial/serial_esp32_usb.c | 9 ++++----- drivers/serial/uart_esp32.c | 10 ++++------ drivers/timer/esp32_sys_timer.c | 12 ++++++------ drivers/watchdog/wdt_esp32.c | 5 +++-- drivers/watchdog/xt_wdt_esp32.c | 6 +++--- 8 files changed, 26 insertions(+), 28 deletions(-) diff --git a/drivers/counter/counter_esp32_rtc.c b/drivers/counter/counter_esp32_rtc.c index 9b57624b1893..0fd1f1b13ac3 100644 --- a/drivers/counter/counter_esp32_rtc.c +++ b/drivers/counter/counter_esp32_rtc.c @@ -59,7 +59,7 @@ static int counter_esp32_init(const struct device *dev) &data->clk_src_freq); flags = ESP_PRIO_TO_FLAGS(cfg->irq_priority) | ESP_INT_FLAGS_CHECK(cfg->irq_flags) | - ESP_INTR_FLAG_SHARED; + ESP_INTR_FLAG_SHARED | ESP_INTR_FLAG_IRAM; ret = esp_intr_alloc(cfg->irq_source, flags, (intr_handler_t)counter_esp32_isr, (void *)dev, NULL); @@ -288,7 +288,7 @@ static DEVICE_API(counter, rtc_timer_esp32_api) = { .get_freq = counter_esp32_get_freq, }; -static void counter_esp32_isr(void *arg) +static void IRAM_ATTR counter_esp32_isr(void *arg) { const struct device *dev = (const struct device *)arg; struct counter_esp32_data *data = dev->data; diff --git a/drivers/counter/counter_esp32_tmr.c b/drivers/counter/counter_esp32_tmr.c index 995b5101c2b1..a17e1795b4b1 100644 --- a/drivers/counter/counter_esp32_tmr.c +++ b/drivers/counter/counter_esp32_tmr.c @@ -92,7 +92,7 @@ static int counter_esp32_init(const struct device *dev) int ret = esp_intr_alloc(cfg->irq_source, ESP_PRIO_TO_FLAGS(cfg->irq_priority) | - ESP_INT_FLAGS_CHECK(cfg->irq_flags), + ESP_INT_FLAGS_CHECK(cfg->irq_flags) | ESP_INTR_FLAG_IRAM, (intr_handler_t)counter_esp32_isr, (void *)dev, NULL); if (ret != 0) { @@ -330,7 +330,7 @@ static DEVICE_API(counter, counter_api) = { .set_guard_period = counter_esp32_set_guard_period, }; -static void counter_esp32_isr(void *arg) +static void IRAM_ATTR counter_esp32_isr(void *arg) { const struct device *dev = (const struct device *)arg; struct counter_esp32_data *data = dev->data; diff --git a/drivers/input/input_esp32_touch_sensor.c b/drivers/input/input_esp32_touch_sensor.c index 4ec5597ff88c..b328d1fee737 100644 --- a/drivers/input/input_esp32_touch_sensor.c +++ b/drivers/input/input_esp32_touch_sensor.c @@ -136,7 +136,7 @@ static void esp32_touch_sensor_interrupt_cb(void *arg) } } -static void esp32_touch_rtc_isr(void *arg) +static void IRAM_ATTR esp32_touch_rtc_isr(void *arg) { uint32_t status = REG_READ(RTC_CNTL_INT_ST_REG); @@ -274,7 +274,7 @@ static int esp32_touch_sensor_init(const struct device *dev) flags = ESP_PRIO_TO_FLAGS(DT_IRQ_BY_IDX(DT_NODELABEL(touch), 0, priority)) | ESP_INT_FLAGS_CHECK(DT_IRQ_BY_IDX(DT_NODELABEL(touch), 0, flags)) | - ESP_INTR_FLAG_SHARED; + ESP_INTR_FLAG_SHARED | ESP_INTR_FLAG_IRAM; err = esp_intr_alloc(DT_IRQ_BY_IDX(DT_NODELABEL(touch), 0, irq), flags, esp32_touch_rtc_isr, (void *)dev, NULL); if (err) { diff --git a/drivers/serial/serial_esp32_usb.c b/drivers/serial/serial_esp32_usb.c index de278ee27ab1..1a0480ecefaf 100644 --- a/drivers/serial/serial_esp32_usb.c +++ b/drivers/serial/serial_esp32_usb.c @@ -102,10 +102,9 @@ static int serial_esp32_usb_init(const struct device *dev) #ifdef CONFIG_UART_INTERRUPT_DRIVEN ret = esp_intr_alloc(config->irq_source, - ESP_PRIO_TO_FLAGS(config->irq_priority) | - ESP_INT_FLAGS_CHECK(config->irq_flags), - (intr_handler_t)serial_esp32_usb_isr, - (void *)dev, NULL); + ESP_PRIO_TO_FLAGS(config->irq_priority) | + ESP_INT_FLAGS_CHECK(config->irq_flags) | ESP_INTR_FLAG_IRAM, + (intr_handler_t)serial_esp32_usb_isr, (void *)dev, NULL); #endif return ret; } @@ -222,7 +221,7 @@ static void serial_esp32_usb_irq_callback_set(const struct device *dev, data->irq_cb = cb; } -static void serial_esp32_usb_isr(void *arg) +static void IRAM_ATTR serial_esp32_usb_isr(void *arg) { const struct device *dev = (const struct device *)arg; struct serial_esp32_usb_data *data = dev->data; diff --git a/drivers/serial/uart_esp32.c b/drivers/serial/uart_esp32.c index 32505a4750cf..e82f775e5617 100644 --- a/drivers/serial/uart_esp32.c +++ b/drivers/serial/uart_esp32.c @@ -517,7 +517,7 @@ static void uart_esp32_irq_rx_enable(const struct device *dev) uart_hal_ena_intr_mask(&data->hal, UART_INTR_RXFIFO_TOUT); } -static void uart_esp32_isr(void *arg) +static void IRAM_ATTR uart_esp32_isr(void *arg) { const struct device *dev = (const struct device *)arg; struct uart_esp32_data *data = dev->data; @@ -955,11 +955,9 @@ static int uart_esp32_init(const struct device *dev) #if CONFIG_UART_INTERRUPT_DRIVEN || CONFIG_UART_ASYNC_API ret = esp_intr_alloc(config->irq_source, - ESP_PRIO_TO_FLAGS(config->irq_priority) | - ESP_INT_FLAGS_CHECK(config->irq_flags), - (intr_handler_t)uart_esp32_isr, - (void *)dev, - NULL); + ESP_PRIO_TO_FLAGS(config->irq_priority) | + ESP_INT_FLAGS_CHECK(config->irq_flags) | ESP_INTR_FLAG_IRAM, + (intr_handler_t)uart_esp32_isr, (void *)dev, NULL); if (ret < 0) { LOG_ERR("Error allocating UART interrupt (%d)", ret); return ret; diff --git a/drivers/timer/esp32_sys_timer.c b/drivers/timer/esp32_sys_timer.c index 46bc17877e7f..439dfdb9216c 100644 --- a/drivers/timer/esp32_sys_timer.c +++ b/drivers/timer/esp32_sys_timer.c @@ -57,7 +57,7 @@ static uint64_t get_systimer_alarm(void) return systimer_hal_get_counter_value(&systimer_hal, SYSTIMER_COUNTER_OS_TICK); } -static void sys_timer_isr(void *arg) +static void IRAM_ATTR sys_timer_isr(void *arg) { ARG_UNUSED(arg); systimer_ll_clear_alarm_int(systimer_hal.dev, SYSTIMER_ALARM_OS_TICK_CORE0); @@ -146,12 +146,12 @@ static int sys_clock_driver_init(void) { int ret; - ret = esp_intr_alloc(DT_IRQ_BY_IDX(DT_NODELABEL(systimer0), 0, irq), + ret = esp_intr_alloc( + DT_IRQ_BY_IDX(DT_NODELABEL(systimer0), 0, irq), ESP_PRIO_TO_FLAGS(DT_IRQ_BY_IDX(DT_NODELABEL(systimer0), 0, priority)) | - ESP_INT_FLAGS_CHECK(DT_IRQ_BY_IDX(DT_NODELABEL(systimer0), 0, flags)), - sys_timer_isr, - NULL, - NULL); + ESP_INT_FLAGS_CHECK(DT_IRQ_BY_IDX(DT_NODELABEL(systimer0), 0, flags)) | + ESP_INTR_FLAG_IRAM, + sys_timer_isr, NULL, NULL); if (ret != 0) { return ret; diff --git a/drivers/watchdog/wdt_esp32.c b/drivers/watchdog/wdt_esp32.c index c045d8922bab..cbdf1e015fce 100644 --- a/drivers/watchdog/wdt_esp32.c +++ b/drivers/watchdog/wdt_esp32.c @@ -159,7 +159,8 @@ static int wdt_esp32_init(const struct device *dev) wdt_hal_init(&data->hal, config->wdt_inst, MWDT_TICK_PRESCALER, true); - flags = ESP_PRIO_TO_FLAGS(config->irq_priority) | ESP_INT_FLAGS_CHECK(config->irq_flags); + flags = ESP_PRIO_TO_FLAGS(config->irq_priority) | ESP_INT_FLAGS_CHECK(config->irq_flags) | + ESP_INTR_FLAG_IRAM; ret = esp_intr_alloc(config->irq_source, flags, (intr_handler_t)wdt_esp32_isr, (void *)dev, NULL); @@ -201,7 +202,7 @@ static DEVICE_API(wdt, wdt_api) = { PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, \ &wdt_api) -static void wdt_esp32_isr(void *arg) +static void IRAM_ATTR wdt_esp32_isr(void *arg) { const struct device *dev = (const struct device *)arg; struct wdt_esp32_data *data = dev->data; diff --git a/drivers/watchdog/xt_wdt_esp32.c b/drivers/watchdog/xt_wdt_esp32.c index 25aefaa68c86..10a945db38dd 100644 --- a/drivers/watchdog/xt_wdt_esp32.c +++ b/drivers/watchdog/xt_wdt_esp32.c @@ -7,7 +7,7 @@ #include #include -#include +#include #include #include @@ -85,7 +85,7 @@ static int esp32_xt_wdt_install_timeout(const struct device *dev, return 0; } -static void esp32_xt_wdt_isr(void *arg) +static void IRAM_ATTR esp32_xt_wdt_isr(void *arg) { const struct device *dev = (const struct device *)arg; const struct esp32_xt_wdt_config *cfg = dev->config; @@ -123,7 +123,7 @@ static int esp32_xt_wdt_init(const struct device *dev) xt_wdt_hal_enable_backup_clk(&data->hal, ESP32_RTC_SLOW_CLK_SRC_RC_SLOW_FREQ/1000); flags = ESP_PRIO_TO_FLAGS(cfg->irq_priority) | ESP_INT_FLAGS_CHECK(cfg->irq_flags) | - ESP_INTR_FLAG_SHARED; + ESP_INTR_FLAG_SHARED | ESP_INTR_FLAG_IRAM; err = esp_intr_alloc(cfg->irq_source, flags, (intr_handler_t)esp32_xt_wdt_isr, (void *)dev, NULL); if (err) { From 15408144885933689c4acfa98219fc353d2f4acf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5vard=20Reierstad?= Date: Thu, 11 Dec 2025 10:47:34 +0100 Subject: [PATCH 0333/3659] Bluetooth: Host: Add random number clarification MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Updates the `bt_le_oob_set_legacy_tk` API docs to encourage the temp key to be generated randomly for each pairing process. Updates the `bt_le_oob_get_local` and `bt_le_ext_adv_oob_get_local` to encourage the user to generate new OOB information for each paring process. Signed-off-by: Håvard Reierstad --- include/zephyr/bluetooth/bluetooth.h | 6 ++++++ include/zephyr/bluetooth/conn.h | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/include/zephyr/bluetooth/bluetooth.h b/include/zephyr/bluetooth/bluetooth.h index 8e738d21970d..593ebf1551e6 100644 --- a/include/zephyr/bluetooth/bluetooth.h +++ b/include/zephyr/bluetooth/bluetooth.h @@ -2788,6 +2788,9 @@ struct bt_le_oob { * - The local identity address conflicts with the local identity address used by other * roles. * + * @note This function randomly generates cryptographic material used in the pairing process, and + * should be called again for each new pairing process. + * * @param[in] id Local identity handle (typically @ref BT_ID_DEFAULT). Corresponds to the identity * address this function will be called for. * @param[out] oob LE OOB information @@ -2815,6 +2818,9 @@ int bt_le_oob_get_local(uint8_t id, struct bt_le_oob *oob); * cases: * - Creating a connection in progress, wait for the connected callback. * + * @note This function randomly generates cryptographic material used in the pairing process, and + * should be called again for each new pairing process. + * * @param[in] adv The advertising set object * @param[out] oob LE OOB information * diff --git a/include/zephyr/bluetooth/conn.h b/include/zephyr/bluetooth/conn.h index 14bf2d657f28..50d68d58ef23 100644 --- a/include/zephyr/bluetooth/conn.h +++ b/include/zephyr/bluetooth/conn.h @@ -2617,7 +2617,8 @@ void bt_le_oob_set_legacy_flag(bool enable); * callback provided that the legacy method is user pairing. * * @param conn @ref BT_CONN_TYPE_LE connection object. - * @param tk Pointer to 16 byte long TK array + * @param tk Pointer to 16 byte long TK array. The TK value should be generated randomly for each + * new pairing process. * * @retval 0 Success * @return -EINVAL @p conn is not a valid @ref BT_CONN_TYPE_LE connection. From b44fe22e984e49383b8baf164dd1d10fdb17d179 Mon Sep 17 00:00:00 2001 From: Holt Sun Date: Thu, 11 Dec 2025 15:50:54 +0800 Subject: [PATCH 0334/3659] samples: drivers: crc: select protocol by capability Choose CRC protocol in the sample at build time using CONFIG_CRC_DRIVER_HAS_* guards (CRC8, CRC16-CCITT, CRC32-IEEE, CRC32-C). Allow optional verification via EXPECTED_* macros; otherwise log result. Update README to describe selection and add build instructions for frdm_mcxe247 in addition to ek_ra8m1. Signed-off-by: Holt Sun --- samples/drivers/crc/Kconfig | 28 ++++++++++ samples/drivers/crc/README.rst | 30 +++++++++-- samples/drivers/crc/src/main.c | 96 ++++++++++++++++++++++------------ 3 files changed, 118 insertions(+), 36 deletions(-) create mode 100644 samples/drivers/crc/Kconfig diff --git a/samples/drivers/crc/Kconfig b/samples/drivers/crc/Kconfig new file mode 100644 index 000000000000..96d3ab45d62c --- /dev/null +++ b/samples/drivers/crc/Kconfig @@ -0,0 +1,28 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +menu "CRC sample application" + +choice SAMPLE_CRC_VARIANT + prompt "CRC variant to run" + default SAMPLE_CRC_VARIANT_CRC8 + help + Choose which CRC algorithm the sample computes. + +config SAMPLE_CRC_VARIANT_CRC8 + bool "CRC8" + +config SAMPLE_CRC_VARIANT_CRC16_CCITT + bool "CRC16-CCITT" + +config SAMPLE_CRC_VARIANT_CRC32_IEEE + bool "CRC32-IEEE" + +config SAMPLE_CRC_VARIANT_CRC32_C + bool "CRC32-C" + +endchoice + +endmenu + +source "Kconfig.zephyr" diff --git a/samples/drivers/crc/README.rst b/samples/drivers/crc/README.rst index 109e779c5155..8e6804c1204e 100644 --- a/samples/drivers/crc/README.rst +++ b/samples/drivers/crc/README.rst @@ -8,6 +8,22 @@ Overview ******** This sample demonstrates how to use the :ref:`CRC driver API `. +It computes a single CRC variant selected via sample Kconfig and logs +the computed result. Optionally, it verifies against an expected value. + +Configuration +************* + +Select the CRC variant to run using the sample's Kconfig: + +- ``SAMPLE_CRC_VARIANT_CRC8`` +- ``SAMPLE_CRC_VARIANT_CRC16_CCITT`` +- ``SAMPLE_CRC_VARIANT_CRC32_IEEE`` +- ``SAMPLE_CRC_VARIANT_CRC32_C`` + +The sample performs a build-time capability check and will emit a +compile error if the selected variant is not supported by the target +driver/platform. Building and Running ******************** @@ -29,16 +45,22 @@ To build for another board, change "ek_ra8m1" above to that board's name. Sample Output ============= +The console logs the selected variant and the computed value. If an +expected value is provided, the sample verifies and logs the outcome. + .. code-block:: console - crc_example: CRC verification succeed. + crc_example: CRC8 result: 0x000000b2 + crc_example: CRC8 verification succeeded (expected 0x000000b2) -.. note:: If the CRC is not supported, the output will be an error message. +.. note:: If the selected CRC variant is not supported by the target, + the build will fail with an error message describing the mismatch. Expected Behavior ***************** When the sample runs, it should: -1. Compute the CRC8 values of predefined data. -2. Verify the CRC result. +1. Compute the selected CRC variant for predefined data. +2. Log the computed CRC value. +3. If an expected value is configured, verify it and log success/failure. diff --git a/samples/drivers/crc/src/main.c b/samples/drivers/crc/src/main.c index 2ed7260e1342..b28ef5d8a151 100644 --- a/samples/drivers/crc/src/main.c +++ b/samples/drivers/crc/src/main.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2025 Renesas Electronics Corporation + * Copyright 2025 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -13,6 +14,51 @@ LOG_MODULE_REGISTER(crc_example, CONFIG_LOG_DEFAULT_LEVEL); /* The devicetree node identifier for the "crc" */ #define CRC_NODE DT_CHOSEN(zephyr_crc) +/* Pre-select CRC variant and constants via Kconfig */ +#if defined(CONFIG_SAMPLE_CRC_VARIANT_CRC8) +#if !IS_ENABLED(CONFIG_CRC_DRIVER_HAS_CRC8) +#error "Selected CRC8 but driver/platform does not support it" +#endif +#define CRC_SAMPLE_TYPE CRC8 +#define CRC_SAMPLE_POLY CRC8_POLY +#define CRC_SAMPLE_SEED CRC8_INIT_VAL +#define CRC_SAMPLE_REVERSED (CRC_FLAG_REVERSE_OUTPUT | CRC_FLAG_REVERSE_INPUT) +#define CRC_SAMPLE_NAME "CRC8" +#define CRC_SAMPLE_EXPECTED 0xB2 +#elif defined(CONFIG_SAMPLE_CRC_VARIANT_CRC16_CCITT) +#if !IS_ENABLED(CONFIG_CRC_DRIVER_HAS_CRC16_CCITT) && !IS_ENABLED(CONFIG_CRC_DRIVER_HAS_CRC16) +#error "Selected CRC16-CCITT but platform does not support it" +#endif +#define CRC_SAMPLE_TYPE CRC16_CCITT +#define CRC_SAMPLE_POLY CRC16_CCITT_POLY +#define CRC_SAMPLE_SEED CRC16_CCITT_INIT_VAL +#define CRC_SAMPLE_REVERSED (CRC_FLAG_REVERSE_OUTPUT | CRC_FLAG_REVERSE_INPUT) +#define CRC_SAMPLE_NAME "CRC16-CCITT" +#define CRC_SAMPLE_EXPECTED 0x445c +#elif defined(CONFIG_SAMPLE_CRC_VARIANT_CRC32_IEEE) +#if !IS_ENABLED(CONFIG_CRC_DRIVER_HAS_CRC32_IEEE) +#error "Selected CRC32-IEEE but platform does not support it" +#endif +#define CRC_SAMPLE_TYPE CRC32_IEEE +#define CRC_SAMPLE_POLY CRC32_IEEE_POLY +#define CRC_SAMPLE_SEED CRC32_IEEE_INIT_VAL +#define CRC_SAMPLE_REVERSED (CRC_FLAG_REVERSE_OUTPUT | CRC_FLAG_REVERSE_INPUT) +#define CRC_SAMPLE_NAME "CRC32-IEEE" +#define CRC_SAMPLE_EXPECTED 0xCEA4A6C2 +#elif defined(CONFIG_SAMPLE_CRC_VARIANT_CRC32_C) +#if !IS_ENABLED(CONFIG_CRC_DRIVER_HAS_CRC32_C) +#error "Selected CRC32-C but platform does not support it" +#endif +#define CRC_SAMPLE_TYPE CRC32_C +#define CRC_SAMPLE_POLY CRC32_C_POLY +#define CRC_SAMPLE_SEED CRC32_C_INIT_VAL +#define CRC_SAMPLE_REVERSED (CRC_FLAG_REVERSE_OUTPUT | CRC_FLAG_REVERSE_INPUT) +#define CRC_SAMPLE_NAME "CRC32-C" +#define CRC_SAMPLE_EXPECTED 0xBB19ECB2 +#else +#error "No CRC sample variant selected" +#endif + /* * A build error on this line means your board is unsupported. * See the sample documentation for information on how to fix this. @@ -21,7 +67,6 @@ LOG_MODULE_REGISTER(crc_example, CONFIG_LOG_DEFAULT_LEVEL); int main(void) { static const struct device *const dev = DEVICE_DT_GET(CRC_NODE); - /* Define the data to compute CRC */ uint8_t data[8] = {0x0A, 0x2B, 0x4C, 0x6D, 0x8E, 0x49, 0x00, 0xC4}; int ret; @@ -31,55 +76,42 @@ int main(void) } struct crc_ctx ctx = { - .type = CRC8, - .polynomial = CRC8_POLY, - .seed = CRC8_INIT_VAL, - .reversed = CRC_FLAG_REVERSE_OUTPUT | CRC_FLAG_REVERSE_INPUT, + .type = CRC_SAMPLE_TYPE, + .polynomial = CRC_SAMPLE_POLY, + .seed = CRC_SAMPLE_SEED, + .reversed = CRC_SAMPLE_REVERSED, }; - /* Start CRC computation */ ret = crc_begin(dev, &ctx); - if (ret != 0) { - LOG_ERR("Failed to begin CRC: %d", ret); + LOG_ERR("Failed to begin %s: %d", CRC_SAMPLE_NAME, ret); return ret; } - /* Update CRC computation */ - ret = crc_update(dev, &ctx, data, 8); - + ret = crc_update(dev, &ctx, data, sizeof(data)); if (ret != 0) { - LOG_ERR("Failed to update CRC: %d", ret); + LOG_ERR("Failed to update %s: %d", CRC_SAMPLE_NAME, ret); return ret; } - /* Finish CRC computation */ ret = crc_finish(dev, &ctx); - if (ret != 0) { - LOG_ERR("Failed to finish CRC: %d", ret); + LOG_ERR("Failed to finish %s: %d", CRC_SAMPLE_NAME, ret); return ret; } - /* Verify CRC computation - * (example expected value: 0xB2 with LSB, 0x4D with MSB bit order) - */ - if (ctx.reversed != (CRC_FLAG_REVERSE_OUTPUT | CRC_FLAG_REVERSE_INPUT)) { - ret = crc_verify(&ctx, 0x4D); - if (ret != 0) { - LOG_ERR("CRC verification failed: %d", ret); - return ret; - } - } else { /* Reversed is no reversed output */ - ret = crc_verify(&ctx, 0xB2); + LOG_INF("%s result: 0x%08x", CRC_SAMPLE_NAME, (unsigned int)ctx.result); - if (ret != 0) { - LOG_ERR("CRC verification failed: %d", ret); - return ret; - } +#if defined(CRC_SAMPLE_EXPECTED) && (CRC_SAMPLE_EXPECTED != 0) + ret = crc_verify(&ctx, CRC_SAMPLE_EXPECTED); + if (ret != 0) { + LOG_ERR("%s verification failed (expected 0x%08x): %d", CRC_SAMPLE_NAME, + CRC_SAMPLE_EXPECTED, ret); + return ret; } - - LOG_INF("CRC verification succeeded"); + LOG_INF("%s verification succeeded (expected 0x%08x)", CRC_SAMPLE_NAME, + CRC_SAMPLE_EXPECTED); +#endif return 0; } From dd73fce1cef769660b1d37b3c835c8c4e9e53c15 Mon Sep 17 00:00:00 2001 From: Holt Sun Date: Thu, 11 Dec 2025 16:21:16 +0800 Subject: [PATCH 0335/3659] tests: drivers: crc: add conditional test compilation Make CRC tests conditional based on driver capabilities to support drivers that implement only a subset of CRC protocols. Signed-off-by: Holt Sun --- tests/drivers/crc/src/main.c | 87 +++++++++++++++++++++++++++++------- 1 file changed, 72 insertions(+), 15 deletions(-) diff --git a/tests/drivers/crc/src/main.c b/tests/drivers/crc/src/main.c index 9a3d4af857c1..cd1556774fdd 100644 --- a/tests/drivers/crc/src/main.c +++ b/tests/drivers/crc/src/main.c @@ -19,7 +19,7 @@ K_THREAD_STACK_DEFINE(wait_thread_stack_area, WAIT_THREAD_STACK_SIZE); struct k_thread wait_thread_data; /* Define result of CRC computation */ -#define RESULT_CRC_16_THREADSAFE 0xD543 +#define RESULT_CRC_16_THREADSAFE_WAIT_THREAD_ENTRY 0xD543 /** * 1) Take the semaphore @@ -45,7 +45,7 @@ static void wait_thread_entry(void *a, void *b, void *c) crc_update(dev, &ctx, data, sizeof(data)); crc_finish(dev, &ctx); - zassert_equal(crc_verify(&ctx, RESULT_CRC_16_THREADSAFE), 0); + zassert_equal(crc_verify(&ctx, RESULT_CRC_16_THREADSAFE_WAIT_THREAD_ENTRY), 0); } /* Define result of CRC computation */ @@ -56,6 +56,10 @@ static void wait_thread_entry(void *a, void *b, void *c) */ ZTEST(crc, test_crc_8) { +#ifndef CONFIG_CRC_DRIVER_HAS_CRC8 + ztest_test_skip(); +#endif + static const struct device *dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_crc)); uint8_t data[8] = {0x0A, 0x2B, 0x4C, 0x6D, 0x8E, 0x49, 0x00, 0xC4}; @@ -84,6 +88,10 @@ ZTEST(crc, test_crc_8) */ ZTEST(crc, test_crc_16) { +#ifndef CONFIG_CRC_DRIVER_HAS_CRC16 + ztest_test_skip(); +#endif + static const struct device *dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_crc)); uint8_t data[8] = {0x0A, 0x2B, 0x4C, 0x6D, 0x8E, 0x49, 0x00, 0xC4}; @@ -110,6 +118,10 @@ ZTEST(crc, test_crc_16) */ ZTEST(crc, test_crc_16_ccitt) { +#ifndef CONFIG_CRC_DRIVER_HAS_CRC16_CCITT + ztest_test_skip(); +#endif + static const struct device *dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_crc)); uint8_t data[8] = {0x0A, 0x2B, 0x4C, 0x6D, 0x8E, 0x49, 0x00, 0xC4}; @@ -136,6 +148,10 @@ ZTEST(crc, test_crc_16_ccitt) */ ZTEST(crc, test_crc_32_c) { +#ifndef CONFIG_CRC_DRIVER_HAS_CRC32_C + ztest_test_skip(); +#endif + static const struct device *dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_crc)); uint8_t data[8] = {0x0A, 0x2B, 0x4C, 0x6D, 0x8E, 0x49, 0x00, 0xC4}; @@ -162,6 +178,10 @@ ZTEST(crc, test_crc_32_c) */ ZTEST(crc, test_crc_32_ieee) { +#ifndef CONFIG_CRC_DRIVER_HAS_CRC32_IEEE + ztest_test_skip(); +#endif + static const struct device *dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_crc)); uint8_t data[8] = {0x0A, 0x2B, 0x4C, 0x6D, 0x8E, 0x49, 0x00, 0xC4}; @@ -186,6 +206,10 @@ ZTEST(crc, test_crc_32_ieee) */ ZTEST(crc, test_crc_8_remain_3) { +#ifndef CONFIG_CRC_DRIVER_HAS_CRC8 + ztest_test_skip(); +#endif + static const struct device *dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_crc)); uint8_t data[11] = {0x0A, 0x2B, 0x4C, 0x6D, 0x8E, 0x49, 0x00, 0xC4, 0x3D, 0x4D, 0x51}; @@ -211,6 +235,10 @@ ZTEST(crc, test_crc_8_remain_3) */ ZTEST(crc, test_crc_16_remain_1) { +#ifndef CONFIG_CRC_DRIVER_HAS_CRC16 + ztest_test_skip(); +#endif + static const struct device *dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_crc)); uint8_t data[9] = {0x0A, 0x2B, 0x4C, 0x6D, 0x8E, 0x49, 0x00, 0xC4, 0x3D}; @@ -237,6 +265,10 @@ ZTEST(crc, test_crc_16_remain_1) */ ZTEST(crc, test_crc_16_ccitt_remain_2) { +#ifndef CONFIG_CRC_DRIVER_HAS_CRC16_CCITT + ztest_test_skip(); +#endif + static const struct device *dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_crc)); uint8_t data[10] = {0x0A, 0x2B, 0x4C, 0x6D, 0x8E, 0x49, 0x00, 0xC4, 0xFF, 0xA0}; @@ -255,8 +287,26 @@ ZTEST(crc, test_crc_16_ccitt_remain_2) zassert_equal(crc_verify(&ctx, RESULT_CRC_CCITT_REMAIN_2), 0); } -/* Define result of CRC computation */ -#define RESULT_DISCONTINUOUS_BUFFER 0x75 +/* Select CRC test variant macros */ +#ifdef CONFIG_CRC_DRIVER_HAS_CRC8 +#define CRC_TEST_VARIANT CRC8 +#define CRC_TEST_POLY CRC8_POLY +#define CRC_TEST_INIT_VAL CRC8_INIT_VAL +#define CRC_TEST_REVERSE_CONFIG (CRC_FLAG_REVERSE_INPUT | CRC_FLAG_REVERSE_OUTPUT) +#define CRC_TEST_DISCONTINUOUS_BUF_EXPECTED 0x75 +#elif defined(CONFIG_CRC_DRIVER_HAS_CRC16) +#define CRC_TEST_VARIANT CRC16 +#define CRC_TEST_POLY CRC16_POLY +#define CRC_TEST_INIT_VAL CRC16_INIT_VAL +#define CRC_TEST_REVERSE_CONFIG (CRC_FLAG_REVERSE_INPUT | CRC_FLAG_REVERSE_OUTPUT) +#define CRC_TEST_DISCONTINUOUS_BUF_EXPECTED 0xBDE3 +#else +#define CRC_TEST_VARIANT CRC32_C +#define CRC_TEST_POLY CRC32C_POLY +#define CRC_TEST_INIT_VAL CRC32_C_INIT_VAL +#define CRC_TEST_REVERSE_CONFIG (CRC_FLAG_REVERSE_INPUT | CRC_FLAG_REVERSE_OUTPUT) +#define CRC_TEST_DISCONTINUOUS_BUF_EXPECTED 0x20477127 +#endif /** * @brief Test CRC calculation with discontinuous buffers. @@ -269,21 +319,27 @@ ZTEST(crc, test_discontinuous_buf) uint8_t data2[5] = {0x49, 0x00, 0xC4, 0x3B, 0x78}; struct crc_ctx ctx = { - .type = CRC8, - .polynomial = CRC8_POLY, - .seed = CRC8_INIT_VAL, - .reversed = CRC_FLAG_REVERSE_INPUT | CRC_FLAG_REVERSE_OUTPUT, + .type = CRC_TEST_VARIANT, + .polynomial = CRC_TEST_POLY, + .seed = CRC_TEST_INIT_VAL, + .reversed = CRC_TEST_REVERSE_CONFIG, }; zassert_equal(crc_begin(dev, &ctx), 0); zassert_equal(crc_update(dev, &ctx, data1, sizeof(data1)), 0); zassert_equal(crc_update(dev, &ctx, data2, sizeof(data2)), 0); zassert_equal(crc_finish(dev, &ctx), 0); - zassert_equal(crc_verify(&ctx, RESULT_DISCONTINUOUS_BUFFER), 0); + zassert_equal(crc_verify(&ctx, CRC_TEST_DISCONTINUOUS_BUF_EXPECTED), 0); } /* Define result of CRC computation */ -#define RESULT_CRC_8_REMAIN_3_THREADSAFE 0xBB +#ifdef CONFIG_CRC_DRIVER_HAS_CRC8 +#define CRC_TEST_THREADSAFE_EXPECTED 0xBB +#elif defined(CONFIG_CRC_DRIVER_HAS_CRC16) +#define CRC_TEST_THREADSAFE_EXPECTED 0x24CA +#else +#define CRC_TEST_THREADSAFE_EXPECTED 0x9BCEE9AB +#endif /** * @brief Test CRC function semaphore wait for thread safety @@ -293,15 +349,16 @@ ZTEST(crc, test_discontinuous_buf) */ ZTEST(crc, test_crc_threadsafe) { + static const struct device *dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_crc)); uint8_t data[11] = {0x0A, 0x2B, 0x4C, 0x6D, 0x8E, 0x49, 0x00, 0xC4, 0x3D, 0x4D, 0x51}; struct crc_ctx ctx = { - .type = CRC8, - .polynomial = CRC8_POLY, - .seed = CRC8_INIT_VAL, - .reversed = CRC_FLAG_REVERSE_OUTPUT | CRC_FLAG_REVERSE_INPUT, + .type = CRC_TEST_VARIANT, + .polynomial = CRC_TEST_POLY, + .seed = CRC_TEST_INIT_VAL, + .reversed = CRC_TEST_REVERSE_CONFIG, }; /** @@ -323,7 +380,7 @@ ZTEST(crc, test_crc_threadsafe) crc_begin(dev, &ctx); crc_update(dev, &ctx, data, sizeof(data)); crc_finish(dev, &ctx); - zassert_equal(crc_verify(&ctx, RESULT_CRC_8_REMAIN_3_THREADSAFE), 0); + zassert_equal(crc_verify(&ctx, CRC_TEST_THREADSAFE_EXPECTED), 0); } ZTEST_SUITE(crc, NULL, NULL, NULL, NULL, NULL); From a838ad5ece3ac5b881934f5c1f8dbf3216b6220e Mon Sep 17 00:00:00 2001 From: Holt Sun Date: Thu, 11 Dec 2025 15:46:18 +0800 Subject: [PATCH 0336/3659] modules: hal_nxp: mcux: enable CRC driver component Enable mcux crc driver for zephyr crc driver. Signed-off-by: Holt Sun --- modules/hal_nxp/mcux/mcux-sdk-ng/drivers/drivers.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/hal_nxp/mcux/mcux-sdk-ng/drivers/drivers.cmake b/modules/hal_nxp/mcux/mcux-sdk-ng/drivers/drivers.cmake index 9a4edb9d3603..07a8e45d973a 100644 --- a/modules/hal_nxp/mcux/mcux-sdk-ng/drivers/drivers.cmake +++ b/modules/hal_nxp/mcux/mcux-sdk-ng/drivers/drivers.cmake @@ -153,6 +153,7 @@ set_variable_ifdef(CONFIG_ETH_NXP_IMX_NETC CONFIG_MCUX_COMPONENT_driver set_variable_ifdef(CONFIG_NXP_TMPSNS CONFIG_MCUX_COMPONENT_driver.tempsensor) set_variable_ifdef(CONFIG_OPAMP_MCUX_OPAMP CONFIG_MCUX_COMPONENT_driver.opamp) set_variable_ifdef(CONFIG_OPAMP_MCUX_OPAMP_FAST CONFIG_MCUX_COMPONENT_driver.opamp_fast) +set_variable_ifdef(CONFIG_CRC_DRIVER_NXP CONFIG_MCUX_COMPONENT_driver.crc) if(NOT CONFIG_SOC_MIMX9596) set_variable_ifdef(CONFIG_ETH_NXP_IMX_NETC CONFIG_MCUX_COMPONENT_driver.netc_switch) From 6e6cc2270dd2f29e5580d34f63498aff836bf415 Mon Sep 17 00:00:00 2001 From: Holt Sun Date: Wed, 10 Dec 2025 22:03:26 +0800 Subject: [PATCH 0337/3659] dts: bindings: crc: add NXP CRC binding Add devicetree binding for the NXP CRC controller (compatible "nxp,crc") with required reg property. Signed-off-by: Holt Sun --- dts/bindings/crc/nxp,crc.yaml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 dts/bindings/crc/nxp,crc.yaml diff --git a/dts/bindings/crc/nxp,crc.yaml b/dts/bindings/crc/nxp,crc.yaml new file mode 100644 index 000000000000..fb554d021804 --- /dev/null +++ b/dts/bindings/crc/nxp,crc.yaml @@ -0,0 +1,14 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +title: NXP CRC (Cyclic Redundancy Check) device + +description: NXP CRC (Cyclic Redundancy Check) driver + +compatible: "nxp,crc" + +include: [base.yaml] + +properties: + reg: + required: true From 45e9fe3eb2f02688f0a8fb5490cd507c0a013616 Mon Sep 17 00:00:00 2001 From: Holt Sun Date: Thu, 11 Dec 2025 15:33:25 +0800 Subject: [PATCH 0338/3659] drivers: crc: nxp: add CRC driver Support CRC16 and CRC32 variants; return -ENOTSUP for unsupported types. Use kCrcBits16/kCrcBits32 and complementChecksum for IEEE CRC-32. Stream data via CRC_WriteData() and fetch results via CRC_Get16bitResult()/CRC_Get32bitResult(). Provide simple thread-safety with a semaphore. Work around the name clash between Zephyr's typedef crc_result_t and the MCUX enum name by temporarily redefining crc_result_t around fsl_crc.h include in this TU. Signed-off-by: Holt Sun --- drivers/crc/CMakeLists.txt | 2 + drivers/crc/Kconfig | 2 + drivers/crc/Kconfig.nxp | 16 +++ drivers/crc/crc_nxp.c | 213 +++++++++++++++++++++++++++++++++++++ 4 files changed, 233 insertions(+) create mode 100644 drivers/crc/Kconfig.nxp create mode 100644 drivers/crc/crc_nxp.c diff --git a/drivers/crc/CMakeLists.txt b/drivers/crc/CMakeLists.txt index edb1e0c95d32..a93302c643ee 100644 --- a/drivers/crc/CMakeLists.txt +++ b/drivers/crc/CMakeLists.txt @@ -1,4 +1,5 @@ # Copyright (c) 2025 Renesas Electronics Corporation +# Copyright 2025 NXP # SPDX-License-Identifier: Apache-2.0 zephyr_syscall_header(${ZEPHYR_BASE}/include/zephyr/drivers/crc.h) @@ -6,6 +7,7 @@ zephyr_syscall_header(${ZEPHYR_BASE}/include/zephyr/drivers/crc.h) zephyr_library() # zephyr-keep-sorted-start +zephyr_library_sources_ifdef(CONFIG_CRC_DRIVER_NXP crc_nxp.c) zephyr_library_sources_ifdef(CONFIG_CRC_DRIVER_RENESAS_RA crc_renesas_ra.c) zephyr_library_sources_ifdef(CONFIG_CRC_DRIVER_SF32LB crc_sf32lb.c) # zephyr-keep-sorted-stop diff --git a/drivers/crc/Kconfig b/drivers/crc/Kconfig index ecf637f47152..125f107d38fb 100644 --- a/drivers/crc/Kconfig +++ b/drivers/crc/Kconfig @@ -1,4 +1,5 @@ # Copyright (c) 2024 Brill Power Ltd. +# Copyright 2025 NXP # SPDX-License-Identifier: Apache-2.0 menuconfig CRC_DRIVER @@ -20,6 +21,7 @@ config CRC_DRIVER_INIT_PRIORITY CRC driver device initialization priority. # zephyr-keep-sorted-start +source "drivers/crc/Kconfig.nxp" source "drivers/crc/Kconfig.renesas_ra" source "drivers/crc/Kconfig.sf32lb" # zephyr-keep-sorted-stop diff --git a/drivers/crc/Kconfig.nxp b/drivers/crc/Kconfig.nxp new file mode 100644 index 000000000000..2467b8e4b9d8 --- /dev/null +++ b/drivers/crc/Kconfig.nxp @@ -0,0 +1,16 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +config CRC_DRIVER_NXP + bool + depends on DT_HAS_NXP_CRC_ENABLED + default y + select CRC_DRIVER_HAS_CRC16 + select CRC_DRIVER_HAS_CRC16_CCITT + select CRC_DRIVER_HAS_CRC16_ANSI + select CRC_DRIVER_HAS_CRC16_ITU_T + select CRC_DRIVER_HAS_CRC16_REFLECT + select CRC_DRIVER_HAS_CRC32_C + select CRC_DRIVER_HAS_CRC32_IEEE + help + Enable the driver implementation for NXP microcontrollers diff --git a/drivers/crc/crc_nxp.c b/drivers/crc/crc_nxp.c new file mode 100644 index 000000000000..25110f05bb4b --- /dev/null +++ b/drivers/crc/crc_nxp.c @@ -0,0 +1,213 @@ +/* + * Copyright 2025 NXP + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT nxp_crc + +#include +#include +#include +LOG_MODULE_REGISTER(nxp_crc, CONFIG_CRC_LOG_LEVEL); + +/* Namespace collision process: there are crc_result_t defined in both mcux and Zephyr */ +#define crc_result_t mcux_crc_result_t +#include "fsl_crc.h" +#undef crc_result_t + +struct crc_nxp_config { + CRC_Type *base; +}; + +struct crc_nxp_data { + struct k_sem lock; +}; + +static inline void crc_nxp_lock(const struct device *dev) +{ + struct crc_nxp_data *data = dev->data; + + k_sem_take(&data->lock, K_FOREVER); +} + +static inline void crc_nxp_unlock(const struct device *dev) +{ + struct crc_nxp_data *data = dev->data; + + k_sem_give(&data->lock); +} + +static int crc_nxp_prepare_config(const struct device *dev, const struct crc_ctx *ctx, + crc_config_t *cfg, bool *use32) +{ + const struct crc_nxp_config *config = dev->config; + + ARG_UNUSED(config); + + if ((ctx == NULL) || (cfg == NULL)) { + return -EINVAL; + } + + cfg->polynomial = ctx->polynomial; + cfg->seed = ctx->seed; + cfg->reflectIn = (ctx->reversed & CRC_FLAG_REVERSE_INPUT) != 0U; + cfg->reflectOut = (ctx->reversed & CRC_FLAG_REVERSE_OUTPUT) != 0U; + cfg->complementChecksum = false; + cfg->crcResult = kCrcFinalChecksum; + + switch (ctx->type) { + case CRC16: + if (ctx->polynomial != CRC16_POLY) { + return -EINVAL; + } + cfg->seed &= 0xFFFFU; + cfg->crcBits = kCrcBits16; + *use32 = false; + break; + case CRC16_CCITT: + if (ctx->polynomial != CRC16_CCITT_POLY) { + return -EINVAL; + } + cfg->seed &= 0xFFFFU; + cfg->crcBits = kCrcBits16; + *use32 = false; + break; + case CRC16_ANSI: + if (ctx->polynomial != CRC16_REFLECT_POLY) { + return -EINVAL; + } + cfg->seed &= 0xFFFFU; + cfg->crcBits = kCrcBits16; + *use32 = false; + break; + case CRC16_ITU_T: + if (ctx->polynomial != CRC16_CCITT_POLY) { + return -EINVAL; + } + cfg->seed &= 0xFFFFU; + cfg->crcBits = kCrcBits16; + *use32 = false; + break; + case CRC32_C: + if (ctx->polynomial != CRC32C_POLY) { + return -EINVAL; + } + cfg->crcBits = kCrcBits32; + *use32 = true; + break; + case CRC32_IEEE: + if (ctx->polynomial != CRC32_IEEE_POLY) { + return -EINVAL; + } + cfg->crcBits = kCrcBits32; + cfg->complementChecksum = true; /* IEEE requires final XOR */ + *use32 = true; + break; + default: + return -ENOTSUP; + } + + return 0; +} + +static int crc_nxp_begin(const struct device *dev, struct crc_ctx *ctx) +{ + const struct crc_nxp_config *config = dev->config; + crc_config_t cfg; + bool use32 = false; + int ret; + + if ((ctx == NULL) || (ctx->state != CRC_STATE_IDLE)) { + return -EINVAL; + } + + crc_nxp_lock(dev); + + ret = crc_nxp_prepare_config(dev, ctx, &cfg, &use32); + if (ret != 0) { + crc_nxp_unlock(dev); + return ret; + } + + /* Initialize hardware with protocol settings and seed */ + CRC_Init(config->base, &cfg); + + ctx->state = CRC_STATE_IN_PROGRESS; + + return 0; +} + +static int crc_nxp_update(const struct device *dev, struct crc_ctx *ctx, const void *buffer, + size_t bufsize) +{ + const struct crc_nxp_config *config = dev->config; + + if (ctx->state != CRC_STATE_IN_PROGRESS) { + return -EINVAL; + } + + /* Allow zero-length updates */ + if ((bufsize > 0U) && (buffer == NULL)) { + ctx->state = CRC_STATE_IDLE; + crc_nxp_unlock(dev); + return -EINVAL; + } + + if (bufsize > 0U) { + CRC_WriteData(config->base, (const uint8_t *)buffer, bufsize); + } + + /* Keep an updated result for streaming verification */ + if ((ctx->type == CRC32_C) || (ctx->type == CRC32_IEEE)) { + ctx->result = CRC_Get32bitResult(config->base); + } else { + ctx->result = (uint32_t)CRC_Get16bitResult(config->base); + } + + return 0; +} + +static int crc_nxp_finish(const struct device *dev, struct crc_ctx *ctx) +{ + const struct crc_nxp_config *config = dev->config; + + if (ctx->state != CRC_STATE_IN_PROGRESS) { + return -EINVAL; + } + + /* Read final result */ + if (((ctx->type == CRC32_C) || (ctx->type == CRC32_IEEE))) { + ctx->result = CRC_Get32bitResult(config->base); + } else { + ctx->result = (uint32_t)CRC_Get16bitResult(config->base); + } + + ctx->state = CRC_STATE_IDLE; + crc_nxp_unlock(dev); + return 0; +} + +static DEVICE_API(crc, crc_nxp_driver_api) = { + .begin = crc_nxp_begin, + .update = crc_nxp_update, + .finish = crc_nxp_finish, +}; + +static int crc_nxp_init(const struct device *dev) +{ + struct crc_nxp_data *data = dev->data; + + k_sem_init(&data->lock, 1, 1); + return 0; +} + +#define CRC_NXP_INIT(inst) \ + static struct crc_nxp_data crc_nxp_data_##inst; \ + static const struct crc_nxp_config crc_nxp_config_##inst = { \ + .base = (CRC_Type *)DT_INST_REG_ADDR(inst), \ + }; \ + DEVICE_DT_INST_DEFINE(inst, crc_nxp_init, NULL, &crc_nxp_data_##inst, \ + &crc_nxp_config_##inst, POST_KERNEL, \ + CONFIG_CRC_DRIVER_INIT_PRIORITY, &crc_nxp_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(CRC_NXP_INIT) From 7214e39540a8ff44006cb77c7268e23b60779c6c Mon Sep 17 00:00:00 2001 From: Holt Sun Date: Thu, 11 Dec 2025 15:26:40 +0800 Subject: [PATCH 0339/3659] boards: nxp: frdm_mcxe247: enable CRC Enable the CRC peripheral for MCXE24x and turn it on in the FRDM-MCXE247 board DTS. Add a CRC sample board config to run on FRDM-MCXE247 with default. Signed-off-by: Holt Sun --- boards/nxp/frdm_mcxe247/frdm_mcxe247.dts | 5 +++++ dts/arm/nxp/nxp_mcxe24x_common.dtsi | 6 ++++++ samples/drivers/crc/boards/frdm_mcxe247.conf | 4 ++++ 3 files changed, 15 insertions(+) create mode 100644 samples/drivers/crc/boards/frdm_mcxe247.conf diff --git a/boards/nxp/frdm_mcxe247/frdm_mcxe247.dts b/boards/nxp/frdm_mcxe247/frdm_mcxe247.dts index 7f508a22b864..28f9baad5e26 100644 --- a/boards/nxp/frdm_mcxe247/frdm_mcxe247.dts +++ b/boards/nxp/frdm_mcxe247/frdm_mcxe247.dts @@ -31,6 +31,7 @@ zephyr,shell-uart = &lpuart2; zephyr,canbus = &flexcan0; zephyr,edac = &erm0; + zephyr,crc = &crc; }; leds { @@ -213,3 +214,7 @@ &counter_rtc { status = "okay"; }; + +&crc { + status = "okay"; +}; diff --git a/dts/arm/nxp/nxp_mcxe24x_common.dtsi b/dts/arm/nxp/nxp_mcxe24x_common.dtsi index c56335b96be7..5bba4e5f0ad5 100644 --- a/dts/arm/nxp/nxp_mcxe24x_common.dtsi +++ b/dts/arm/nxp/nxp_mcxe24x_common.dtsi @@ -692,6 +692,12 @@ clk-divider = <256>; status = "disabled"; }; + + crc: crc@40032000 { + compatible = "nxp,crc"; + reg = <0x40032000 0x1000>; + status = "disabled"; + }; }; }; diff --git a/samples/drivers/crc/boards/frdm_mcxe247.conf b/samples/drivers/crc/boards/frdm_mcxe247.conf new file mode 100644 index 000000000000..ccc1ce48999e --- /dev/null +++ b/samples/drivers/crc/boards/frdm_mcxe247.conf @@ -0,0 +1,4 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SAMPLE_CRC_VARIANT_CRC16_CCITT=y From 2d8cb5dad9debaf069a44fd75418de2a799bba94 Mon Sep 17 00:00:00 2001 From: Michael Zimmermann Date: Thu, 11 Dec 2025 11:45:29 +0100 Subject: [PATCH 0340/3659] tests: net: mqtt_sn: client: fix running just search_gw Since the code can't handle timestamp 0, we have to sleep during setup. Signed-off-by: Michael Zimmermann --- tests/net/lib/mqtt_sn_client/src/mqtt_sn_client.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/net/lib/mqtt_sn_client/src/mqtt_sn_client.c b/tests/net/lib/mqtt_sn_client/src/mqtt_sn_client.c index a43e0be42e07..c42811d16d9f 100644 --- a/tests/net/lib/mqtt_sn_client/src/mqtt_sn_client.c +++ b/tests/net/lib/mqtt_sn_client/src/mqtt_sn_client.c @@ -176,6 +176,15 @@ static void setup(void *f) k_sem_init(&mqtt_sn_tx_sem, 0, 1); k_sem_init(&mqtt_sn_rx_sem, 0, 1); k_sem_init(&mqtt_sn_cb_sem, 0, 1); + + /* The MQTT-SN client uses timestamp 0 as a special value which + * indicates, that no gwinfo or searchgw message needs to be sent. + * This means that the code effectively ignores such incoming messages + * during timestamp 0. Since this is both unrealistic and unproblematic + * on a real device, we simply sleep here to workaround that without + * complicating the MQTT-SN implementation. + */ + k_sleep(K_MSEC(1)); } static void cleanup(void *f) From 53012f9cc255b6847c31d2fb54088c104a602aeb Mon Sep 17 00:00:00 2001 From: Michael Zimmermann Date: Thu, 11 Dec 2025 11:43:35 +0100 Subject: [PATCH 0341/3659] tests: net: mqtt_sn: client: Test gwinfo response from a gateway itself. When the response comes from a gateway, the address length is 0. I renamed the test which tests a gwinfo from another client to make this more clear. Signed-off-by: Michael Zimmermann --- .../lib/mqtt_sn_client/src/mqtt_sn_client.c | 36 +++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/tests/net/lib/mqtt_sn_client/src/mqtt_sn_client.c b/tests/net/lib/mqtt_sn_client/src/mqtt_sn_client.c index c42811d16d9f..09831c7692f5 100644 --- a/tests/net/lib/mqtt_sn_client/src/mqtt_sn_client.c +++ b/tests/net/lib/mqtt_sn_client/src/mqtt_sn_client.c @@ -324,8 +324,40 @@ static ZTEST(mqtt_sn_client, test_mqtt_sn_search_gw) zassert_equal(evt_cb_data.last_evt.type, MQTT_SN_EVT_GWINFO, "Wrong event"); } -/* Test send SEARCHGW and peer response */ -static ZTEST(mqtt_sn_client, test_mqtt_sn_search_peer) +/* Test send SEARCHGW and expect GWINFO response from a gateway */ +static ZTEST(mqtt_sn_client, test_mqtt_sn_search_peer_direct) +{ + int err; + static uint8_t gwinfo[3]; + + gwinfo[0] = 3; + gwinfo[1] = 0x02; + gwinfo[2] = gw_id; + + err = mqtt_sn_client_init(mqtt_client, &client_id, &transport, evt_cb, tx, sizeof(tx), rx, + sizeof(rx)); + zassert_equal(err, 0, "unexpected error %d", err); + + err = k_sem_take(&mqtt_sn_tx_sem, K_NO_WAIT); + err = mqtt_sn_search(mqtt_client, 1); + zassert_equal(err, 0, "unexpected error %d", err); + + err = k_sem_take(&mqtt_sn_tx_sem, K_SECONDS(10)); + zassert_equal(err, 0, "Timed out waiting for callback."); + + assert_msg_send(1, 3, NULL); + zassert_equal(mqtt_client->state, 0, "Wrong state"); + zassert_equal(evt_cb_data.called, 0, "Unexpected event"); + + err = input(mqtt_client, gwinfo, sizeof(gwinfo), &gw_addr); + zassert_equal(err, 0, "unexpected error %d", err); + zassert_false(sys_slist_is_empty(&mqtt_client->gateway), "GW not saved."); + zassert_equal(evt_cb_data.called, 1, "NO event"); + zassert_equal(evt_cb_data.last_evt.type, MQTT_SN_EVT_GWINFO, "Wrong event"); +} + +/* Test send SEARCHGW and expect GWINFO response from another client */ +static ZTEST(mqtt_sn_client, test_mqtt_sn_search_peer_indirect) { int err; static uint8_t gwinfo[3 + 3]; From 4759e3912237974f0bdd3d640e4895f97ed88c98 Mon Sep 17 00:00:00 2001 From: Michael Zimmermann Date: Mon, 27 Oct 2025 15:22:04 +0100 Subject: [PATCH 0342/3659] net: mqtt_sn: Disable support for GWINFO messages The MQTT-SN v1.2 [0] specification specified the GwAddr as follows: The GwAdd field has a variable length and contains the address of a GW. Its depends on the network over which MQTT-SN operates and is indicated in the first octet of this field. For example, in a ZigBee network the network address is 2-octet long. It specifies neither the possible values for the first octet, nor the format of the network-specific address that follows. Thus, the specification is incomplete and this functionality unusable. I also wasn't able to find any implementation which implements a gwinfo message where the address length is not zero. This includes https://github.com/eclipse-paho/paho.mqtt-sn.embedded-c . The current implementation in Zephyr simply copies a `struct sockaddr` into GwAddr. This is a bad idea for many reasons, the most important one being that the format is not even specified by POSIX [1]. They only say, which defines must exist, not what their values are. And in fact, these even differ between Zephyr and Linux. Thus, I think it's best to remove the implementation to prevent people from using this, which may even lead to memory safety issues, depending on the length of CONFIG_MQTT_SN_LIB_MAX_ADDR_SIZE. If we were to receive an updated specification, all we'd have to do is to convert between `struct sockaddr` and mqtt-sn addresses both ways. [0] https://groups.oasis-open.org/higherlogic/ws/public/download/66091/MQTT-SN_spec_v1.2.pdf [1] https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/sys_socket.h.html Signed-off-by: Michael Zimmermann --- subsys/net/lib/mqtt_sn/mqtt_sn.c | 41 ++++--------- .../lib/mqtt_sn_client/src/mqtt_sn_client.c | 60 ------------------- 2 files changed, 11 insertions(+), 90 deletions(-) diff --git a/subsys/net/lib/mqtt_sn/mqtt_sn.c b/subsys/net/lib/mqtt_sn/mqtt_sn.c index 3ba20d553fed..a9468e7809eb 100644 --- a/subsys/net/lib/mqtt_sn/mqtt_sn.c +++ b/subsys/net/lib/mqtt_sn/mqtt_sn.c @@ -595,32 +595,6 @@ static void mqtt_sn_do_searchgw(struct mqtt_sn_client *client) encode_and_send(client, &p, CONFIG_MQTT_SN_LIB_BROADCAST_RADIUS); } -/** - * @brief Internal function to send a GWINFO message. - * - * @param client - */ -static void mqtt_sn_do_gwinfo(struct mqtt_sn_client *client) -{ - struct mqtt_sn_param response = {.type = MQTT_SN_MSG_TYPE_GWINFO}; - struct mqtt_sn_gateway *gw; - struct mqtt_sn_data addr; - - gw = SYS_SLIST_PEEK_HEAD_CONTAINER(&client->gateway, gw, next); - - if (gw == NULL || gw->addr_len == 0) { - LOG_WRN("No Gateway Address"); - return; - } - - response.params.gwinfo.gw_id = gw->gw_id; - addr.data = gw->addr; - addr.size = gw->addr_len; - response.params.gwinfo.gw_add = addr; - - encode_and_send(client, &response, client->radius_gwinfo); -} - /** * @brief Internal function to send a PINGREQ message. * @@ -1074,8 +1048,11 @@ static int process_search(struct mqtt_sn_client *client, int64_t *next_cycle) } if (client->ts_gwinfo != 0 && client->ts_gwinfo <= now) { - LOG_DBG("Sending GWINFO"); - mqtt_sn_do_gwinfo(client); + /* The MQTT-SN specification doesn't properly specify the format + * of the address in this message. + * See https://github.com/zephyrproject-rtos/zephyr/pull/100874 + */ + LOG_WRN("GwAddr is not specified properly. Ignoring SEARCHGW message"); client->ts_gwinfo = 0; } @@ -1559,8 +1536,12 @@ static void handle_gwinfo(struct mqtt_sn_client *client, struct mqtt_sn_param_gw /* Extract GW info and store */ if (p->gw_add.size > 0) { - rx_addr.data = p->gw_add.data; - rx_addr.size = p->gw_add.size; + /* The MQTT-SN specification doesn't properly specify the format + * of the address in this message. + * See https://github.com/zephyrproject-rtos/zephyr/pull/100874 + */ + LOG_WRN("GwAddr is not specified properly. Ignoring GWINFO message"); + return; } else { } gw = mqtt_sn_gw_create(p->gw_id, -1, rx_addr); diff --git a/tests/net/lib/mqtt_sn_client/src/mqtt_sn_client.c b/tests/net/lib/mqtt_sn_client/src/mqtt_sn_client.c index 09831c7692f5..2010919159dc 100644 --- a/tests/net/lib/mqtt_sn_client/src/mqtt_sn_client.c +++ b/tests/net/lib/mqtt_sn_client/src/mqtt_sn_client.c @@ -15,7 +15,6 @@ LOG_MODULE_REGISTER(test); static const struct mqtt_sn_data client_id = MQTT_SN_DATA_STRING_LITERAL("zephyr"); -static const struct mqtt_sn_data client2_id = MQTT_SN_DATA_STRING_LITERAL("zephyr2"); static const uint8_t gw_id = 12; static const struct mqtt_sn_data gw_addr = MQTT_SN_DATA_STRING_LITERAL("gw1"); @@ -356,65 +355,6 @@ static ZTEST(mqtt_sn_client, test_mqtt_sn_search_peer_direct) zassert_equal(evt_cb_data.last_evt.type, MQTT_SN_EVT_GWINFO, "Wrong event"); } -/* Test send SEARCHGW and expect GWINFO response from another client */ -static ZTEST(mqtt_sn_client, test_mqtt_sn_search_peer_indirect) -{ - int err; - static uint8_t gwinfo[3 + 3]; - - gwinfo[0] = 3 + gw_addr.size; - gwinfo[1] = 0x02; - gwinfo[2] = gw_id; - memcpy(&gwinfo[3], gw_addr.data, 3); - - err = mqtt_sn_client_init(mqtt_client, &client_id, &transport, evt_cb, tx, sizeof(tx), rx, - sizeof(rx)); - zassert_equal(err, 0, "unexpected error %d", err); - - err = k_sem_take(&mqtt_sn_tx_sem, K_NO_WAIT); - err = mqtt_sn_search(mqtt_client, 1); - zassert_equal(err, 0, "unexpected error %d", err); - - err = k_sem_take(&mqtt_sn_tx_sem, K_SECONDS(10)); - zassert_equal(err, 0, "Timed out waiting for callback."); - - assert_msg_send(1, 3, NULL); - zassert_equal(mqtt_client->state, 0, "Wrong state"); - zassert_equal(evt_cb_data.called, 0, "Unexpected event"); - - err = input(mqtt_client, gwinfo, sizeof(gwinfo), &gw_addr); - zassert_equal(err, 0, "unexpected error %d", err); - zassert_false(sys_slist_is_empty(&mqtt_client->gateway), "GW not saved."); - zassert_equal(evt_cb_data.called, 1, "NO event"); - zassert_equal(evt_cb_data.last_evt.type, MQTT_SN_EVT_GWINFO, "Wrong event"); -} - -static ZTEST(mqtt_sn_client, test_mqtt_sn_respond_searchgw) -{ - int err; - static uint8_t searchgw[] = {3, 0x01, 1}; - - err = mqtt_sn_client_init(mqtt_client, &client_id, &transport, evt_cb, tx, sizeof(tx), rx, - sizeof(rx)); - zassert_equal(err, 0, "unexpected error %d", err); - - err = mqtt_sn_add_gw(mqtt_client, gw_id, gw_addr); - zassert_equal(err, 0, "unexpected error %d", err); - zassert_false(sys_slist_is_empty(&mqtt_client->gateway), "GW not saved."); - zassert_equal(evt_cb_data.called, 0, "Unexpected event"); - - err = k_sem_take(&mqtt_sn_tx_sem, K_NO_WAIT); - err = input(mqtt_client, searchgw, sizeof(searchgw), &client2_id); - zassert_equal(err, 0, "unexpected error %d", err); - - err = k_sem_take(&mqtt_sn_tx_sem, K_SECONDS(10)); - zassert_equal(err, 0, "Timed out waiting for callback."); - - zassert_equal(evt_cb_data.called, 1, "NO event"); - zassert_equal(evt_cb_data.last_evt.type, MQTT_SN_EVT_SEARCHGW, "Wrong event"); - assert_msg_send(1, 3 + gw_addr.size, NULL); -} - static ZTEST(mqtt_sn_client, test_mqtt_sn_connect_no_will) { mqtt_sn_connect_no_will(mqtt_client); From a0b8684e46bf2cf6bad6d7d77c237a84d6b674c4 Mon Sep 17 00:00:00 2001 From: Martin Lampacher Date: Thu, 11 Dec 2025 09:03:13 +0000 Subject: [PATCH 0343/3659] boards: doc: remove tfm note for stm32u0 boards The STM32U0 series MCUs don't support TF-M and therefore the note regarding the `build/tfm` directory needs to be removed. Signed-off-by: Martin Lampacher --- boards/st/nucleo_u031r8/doc/index.rst | 4 ---- boards/st/nucleo_u083rc/doc/index.rst | 4 ---- 2 files changed, 8 deletions(-) diff --git a/boards/st/nucleo_u031r8/doc/index.rst b/boards/st/nucleo_u031r8/doc/index.rst index f369de0920af..8645101911ba 100644 --- a/boards/st/nucleo_u031r8/doc/index.rst +++ b/boards/st/nucleo_u031r8/doc/index.rst @@ -231,10 +231,6 @@ Here is an example for the :zephyr:code-sample:`blinky` application. :board: nucleo_u031r8 :goals: debug -Note: Check the ``build/tfm`` directory to ensure that the commands required by these scripts -(``readlink``, etc.) are available on your system. Please also check ``STM32_Programmer_CLI`` -(which is used for initialization) is available in the PATH. - .. _NUCLEO_U031R8 website: https://www.st.com/en/evaluation-tools/nucleo-u031r8.html diff --git a/boards/st/nucleo_u083rc/doc/index.rst b/boards/st/nucleo_u083rc/doc/index.rst index 5e4e21b4727d..8fb0af2a60bd 100644 --- a/boards/st/nucleo_u083rc/doc/index.rst +++ b/boards/st/nucleo_u083rc/doc/index.rst @@ -244,10 +244,6 @@ Here is an example for the :zephyr:code-sample:`blinky` application. :board: nucleo_u083rc :goals: debug -Note: Check the ``build/tfm`` directory to ensure that the commands required by these scripts -(``readlink``, etc.) are available on your system. Please also check ``STM32_Programmer_CLI`` -(which is used for initialization) is available in the PATH. - .. _NUCLEO_U083RC website: https://www.st.com/en/evaluation-tools/nucleo-u083rc.html From dbe12ad8dea6f086e4d1727ca1548f349ea98827 Mon Sep 17 00:00:00 2001 From: Muzaffar Ahmed Date: Thu, 11 Dec 2025 13:52:33 +0530 Subject: [PATCH 0344/3659] drivers: wifi: siwx91x: Fix region persistence across reboots Use the last configured region in the boot config for the next boot, as opposed to a default region. Signed-off-by: Muzaffar Ahmed --- soc/silabs/silabs_siwx91x/siwg917/siwx91x_nwp.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/soc/silabs/silabs_siwx91x/siwg917/siwx91x_nwp.c b/soc/silabs/silabs_siwx91x/siwg917/siwx91x_nwp.c index 5fbf3fd41555..2a511034cb57 100644 --- a/soc/silabs/silabs_siwx91x/siwg917/siwx91x_nwp.c +++ b/soc/silabs/silabs_siwx91x/siwg917/siwx91x_nwp.c @@ -343,7 +343,7 @@ static int siwx91x_get_nwp_config(const struct device *dev, { const struct siwx91x_nwp_config *config = dev->config; sl_wifi_device_configuration_t default_config = { - .region_code = siwx91x_map_country_code_to_region(DEFAULT_COUNTRY_CODE), + .region_code = siwx91x_map_country_code_to_region(siwx91x_get_country_code(dev)), .band = SL_SI91X_WIFI_BAND_2_4GHZ, .boot_option = LOAD_NWP_FW, .boot_config = { @@ -374,7 +374,6 @@ static int siwx91x_get_nwp_config(const struct device *dev, if (IS_ENABLED(CONFIG_WIFI_SILABS_SIWX91X_FEAT_HIDE_PSK_CREDENTIALS)) { boot_config->feature_bit_map |= SL_SI91X_FEAT_HIDE_PSK_CREDENTIALS; } - siwx91x_store_country_code(dev, DEFAULT_COUNTRY_CODE); siwx91x_apply_sram_config(boot_config); siwx91x_apply_boot_config(dev, boot_config); From 1e510faed434488d0dedb08a7b20dac391e9ccb9 Mon Sep 17 00:00:00 2001 From: Farsin Nasar V A Date: Fri, 5 Dec 2025 10:33:56 +0530 Subject: [PATCH 0345/3659] dts: arm: microchip: add RTC node for G1 IP Add the device tree node for microchip RTC G1 IP. Signed-off-by: Farsin Nasar V A --- .../pic32c/pic32cx_sg/common/pic32cx_sg.dtsi | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/dts/arm/microchip/pic32c/pic32cx_sg/common/pic32cx_sg.dtsi b/dts/arm/microchip/pic32c/pic32cx_sg/common/pic32cx_sg.dtsi index 1400758df7ce..7f219231ba54 100644 --- a/dts/arm/microchip/pic32c/pic32cx_sg/common/pic32cx_sg.dtsi +++ b/dts/arm/microchip/pic32c/pic32cx_sg/common/pic32cx_sg.dtsi @@ -87,6 +87,19 @@ }; }; + rtc: rtc@40002400 { + compatible = "microchip,rtc-g1"; + reg = <0x40002400 0x400>; + interrupts = <11 0>; + clocks = <&mclkperiph CLOCK_MCHP_MCLKPERIPH_ID_APBA_RTC>, + <&rtcclock CLOCK_MCHP_RTC_ID>; + clock-names = "mclk", "rtcclk"; + prescaler = <1>; + alarms-count = <2>; + cal-constant = <1048576>; + status = "disabled"; + }; + sercom0: sercom@40003000 { compatible = "microchip,sercom-g1"; reg = <0x40003000 0x29>; From 58a9c9335cdf141fd153575693c83fbab97ffa00 Mon Sep 17 00:00:00 2001 From: Farsin Nasar V A Date: Fri, 5 Dec 2025 10:40:03 +0530 Subject: [PATCH 0346/3659] boards: microchip: pic32cx_sg41_cult: Add RTC to supported list Add RTC node in pic32cx_sg41_cult.dts Update pic32cx_sg41_cult.yaml to reflect RTC G1 support on the board. Signed-off-by: Farsin Nasar V A --- .../pic32c/pic32cx_sg41_cult/pic32cx_sg41_cult.dts | 6 ++++++ .../pic32c/pic32cx_sg41_cult/pic32cx_sg41_cult.yaml | 1 + 2 files changed, 7 insertions(+) diff --git a/boards/microchip/pic32c/pic32cx_sg41_cult/pic32cx_sg41_cult.dts b/boards/microchip/pic32c/pic32cx_sg41_cult/pic32cx_sg41_cult.dts index 69bdb88777b5..594e9baafac8 100644 --- a/boards/microchip/pic32c/pic32cx_sg41_cult/pic32cx_sg41_cult.dts +++ b/boards/microchip/pic32c/pic32cx_sg41_cult/pic32cx_sg41_cult.dts @@ -26,6 +26,7 @@ led0 = &led1; sw0 = &button0; pwm-led0 = &pwm_led0; + rtc = &rtc; }; leds { @@ -68,6 +69,11 @@ }; }; +&rtc { + prescaler = <1024>; + status = "okay"; +}; + &flash0 { partitions { compatible = "fixed-partitions"; diff --git a/boards/microchip/pic32c/pic32cx_sg41_cult/pic32cx_sg41_cult.yaml b/boards/microchip/pic32c/pic32cx_sg41_cult/pic32cx_sg41_cult.yaml index ca20eef5173e..6edbff52f2e2 100644 --- a/boards/microchip/pic32c/pic32cx_sg41_cult/pic32cx_sg41_cult.yaml +++ b/boards/microchip/pic32c/pic32cx_sg41_cult/pic32cx_sg41_cult.yaml @@ -16,5 +16,6 @@ supported: - gpio - pinctrl - pwm + - rtc - uart vendor: microchip From 12192e9d346312d364fc275295304f2b703f7305 Mon Sep 17 00:00:00 2001 From: Farsin Nasar V A Date: Fri, 5 Dec 2025 10:43:23 +0530 Subject: [PATCH 0347/3659] boards: microchip: pic32cx_sg61_cult: Add RTC to supported list Add RTC node in pic32cx_sg61_cult.dts Update pic32cx_sg61_cult.yaml to reflect RTC G1 support on the board. Signed-off-by: Farsin Nasar V A --- .../pic32c/pic32cx_sg61_cult/pic32cx_sg61_cult.dts | 6 ++++++ .../pic32c/pic32cx_sg61_cult/pic32cx_sg61_cult.yaml | 1 + 2 files changed, 7 insertions(+) diff --git a/boards/microchip/pic32c/pic32cx_sg61_cult/pic32cx_sg61_cult.dts b/boards/microchip/pic32c/pic32cx_sg61_cult/pic32cx_sg61_cult.dts index 2bc1769a35e4..84589aa2b7eb 100644 --- a/boards/microchip/pic32c/pic32cx_sg61_cult/pic32cx_sg61_cult.dts +++ b/boards/microchip/pic32c/pic32cx_sg61_cult/pic32cx_sg61_cult.dts @@ -26,6 +26,7 @@ led0 = &led1; sw0 = &button0; pwm-led0 = &pwm_led0; + rtc = &rtc; }; leds { @@ -62,6 +63,11 @@ }; }; +&rtc { + prescaler = <1024>; + status = "okay"; +}; + &flash0 { partitions { compatible = "fixed-partitions"; diff --git a/boards/microchip/pic32c/pic32cx_sg61_cult/pic32cx_sg61_cult.yaml b/boards/microchip/pic32c/pic32cx_sg61_cult/pic32cx_sg61_cult.yaml index dbdf53dd402f..b8f6338a3174 100644 --- a/boards/microchip/pic32c/pic32cx_sg61_cult/pic32cx_sg61_cult.yaml +++ b/boards/microchip/pic32c/pic32cx_sg61_cult/pic32cx_sg61_cult.yaml @@ -16,5 +16,6 @@ supported: - gpio - pinctrl - pwm + - rtc - uart vendor: microchip From b682749a62c239a6489af3cb60b759ff646bca69 Mon Sep 17 00:00:00 2001 From: Farsin Nasar V A Date: Fri, 5 Dec 2025 10:46:42 +0530 Subject: [PATCH 0348/3659] tests: drivers: rtc: Add support for the pic32cx_sg41 and sg61 board Added pic32cx_sg41_cult.conf file and pic32cx_sg61_cult.conf file Signed-off-by: Farsin Nasar V A --- tests/drivers/rtc/rtc_api/boards/pic32cx_sg41_cult.conf | 6 ++++++ tests/drivers/rtc/rtc_api/boards/pic32cx_sg61_cult.conf | 6 ++++++ 2 files changed, 12 insertions(+) create mode 100644 tests/drivers/rtc/rtc_api/boards/pic32cx_sg41_cult.conf create mode 100644 tests/drivers/rtc/rtc_api/boards/pic32cx_sg61_cult.conf diff --git a/tests/drivers/rtc/rtc_api/boards/pic32cx_sg41_cult.conf b/tests/drivers/rtc/rtc_api/boards/pic32cx_sg41_cult.conf new file mode 100644 index 000000000000..79b805435a4c --- /dev/null +++ b/tests/drivers/rtc/rtc_api/boards/pic32cx_sg41_cult.conf @@ -0,0 +1,6 @@ +# Copyright (c) 2025 Microchip Technology Inc. +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_RTC_ALARM=y +CONFIG_TEST_RTC_ALARM_TIME_MASK=63 +CONFIG_RTC_CALIBRATION=y diff --git a/tests/drivers/rtc/rtc_api/boards/pic32cx_sg61_cult.conf b/tests/drivers/rtc/rtc_api/boards/pic32cx_sg61_cult.conf new file mode 100644 index 000000000000..79b805435a4c --- /dev/null +++ b/tests/drivers/rtc/rtc_api/boards/pic32cx_sg61_cult.conf @@ -0,0 +1,6 @@ +# Copyright (c) 2025 Microchip Technology Inc. +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_RTC_ALARM=y +CONFIG_TEST_RTC_ALARM_TIME_MASK=63 +CONFIG_RTC_CALIBRATION=y From c65ffc7737d7c03e111a6830c124792f1ee9e366 Mon Sep 17 00:00:00 2001 From: Zhaoxiang Jin Date: Wed, 10 Dec 2025 22:45:09 +0800 Subject: [PATCH 0349/3659] soc: nxp: rw: Power on GAU if acomp is enabled Power on GAU if acomp is enabled. Signed-off-by: Zhaoxiang Jin --- soc/nxp/rw/soc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/soc/nxp/rw/soc.c b/soc/nxp/rw/soc.c index e743fac02bc4..428622433208 100644 --- a/soc/nxp/rw/soc.c +++ b/soc/nxp/rw/soc.c @@ -147,12 +147,14 @@ __weak __ramfunc void clock_init(void) CLOCK_AttachClk(kNONE_to_WDT0_CLK); #endif -#if defined(CONFIG_ADC_MCUX_GAU) || defined(CONFIG_DAC_MCUX_GAU) +#if defined(CONFIG_ADC_MCUX_GAU) || defined(CONFIG_DAC_MCUX_GAU) || \ + defined(CONFIG_COMPARATOR_NXP_ACOMP) /* Attack clock for GAU and reset */ CLOCK_AttachClk(kMAIN_CLK_to_GAU_CLK); CLOCK_SetClkDiv(kCLOCK_DivGauClk, 1U); CLOCK_EnableClock(kCLOCK_Gau); RESET_PeripheralReset(kGAU_RST_SHIFT_RSTn); + GAU_BG->CTRL &= ~BG_CTRL_PD_MASK; #endif /* GAU */ /* Any flexcomm can be USART */ From bd65e115fa9e440084518a952ef1365fd2dd6f23 Mon Sep 17 00:00:00 2001 From: Zhaoxiang Jin Date: Wed, 10 Dec 2025 22:46:44 +0800 Subject: [PATCH 0350/3659] drivers: comparator: add NXP ACOMP driver support Add NXP ACOMP comparator driver support. Signed-off-by: Zhaoxiang Jin --- drivers/comparator/CMakeLists.txt | 1 + drivers/comparator/Kconfig | 1 + drivers/comparator/Kconfig.nxp_acomp | 7 + drivers/comparator/comparator_nxp_acomp.c | 284 ++++++++++++++++++++++ dts/bindings/comparator/nxp,acomp.yaml | 102 ++++++++ 5 files changed, 395 insertions(+) create mode 100644 drivers/comparator/Kconfig.nxp_acomp create mode 100644 drivers/comparator/comparator_nxp_acomp.c create mode 100644 dts/bindings/comparator/nxp,acomp.yaml diff --git a/drivers/comparator/CMakeLists.txt b/drivers/comparator/CMakeLists.txt index 6802cc894c83..2b2fd1df69b4 100644 --- a/drivers/comparator/CMakeLists.txt +++ b/drivers/comparator/CMakeLists.txt @@ -14,6 +14,7 @@ zephyr_library_sources_ifdef(CONFIG_COMPARATOR_MCHP_AC_G1 comparator_mchp_ac_g1. zephyr_library_sources_ifdef(CONFIG_COMPARATOR_MCUX_ACMP comparator_mcux_acmp.c) zephyr_library_sources_ifdef(CONFIG_COMPARATOR_NRF_COMP comparator_nrf_comp.c) zephyr_library_sources_ifdef(CONFIG_COMPARATOR_NRF_LPCOMP comparator_nrf_lpcomp.c) +zephyr_library_sources_ifdef(CONFIG_COMPARATOR_NXP_ACOMP comparator_nxp_acomp.c) zephyr_library_sources_ifdef(CONFIG_COMPARATOR_NXP_CMP comparator_nxp_cmp.c) zephyr_library_sources_ifdef(CONFIG_COMPARATOR_NXP_HSCMP comparator_nxp_hscmp.c) zephyr_library_sources_ifdef(CONFIG_COMPARATOR_RENESAS_RA comparator_renesas_ra.c) diff --git a/drivers/comparator/Kconfig b/drivers/comparator/Kconfig index 2069bcde171e..778ea63d13d4 100644 --- a/drivers/comparator/Kconfig +++ b/drivers/comparator/Kconfig @@ -25,6 +25,7 @@ rsource "Kconfig.mchp" rsource "Kconfig.mcux_acmp" rsource "Kconfig.nrf_comp" rsource "Kconfig.nrf_lpcomp" +rsource "Kconfig.nxp_acomp" rsource "Kconfig.nxp_cmp" rsource "Kconfig.nxp_hscmp" rsource "Kconfig.renesas_ra" diff --git a/drivers/comparator/Kconfig.nxp_acomp b/drivers/comparator/Kconfig.nxp_acomp new file mode 100644 index 000000000000..028343853018 --- /dev/null +++ b/drivers/comparator/Kconfig.nxp_acomp @@ -0,0 +1,7 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +config COMPARATOR_NXP_ACOMP + bool "NXP analog comparator driver" + default y + depends on DT_HAS_NXP_ACOMP_ENABLED diff --git a/drivers/comparator/comparator_nxp_acomp.c b/drivers/comparator/comparator_nxp_acomp.c new file mode 100644 index 000000000000..fbec51a44378 --- /dev/null +++ b/drivers/comparator/comparator_nxp_acomp.c @@ -0,0 +1,284 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(nxp_acomp, CONFIG_COMPARATOR_LOG_LEVEL); + +#define DT_DRV_COMPAT nxp_acomp + +#define ACOMP_NEG_INPUT_VIO_0P25 12U + +struct nxp_acomp_config { + ACOMP_Type *base; + bool async_output; + bool invert_output; + bool enable_pin_out; + bool inactive_value_high; + uint8_t positive_input; + uint8_t negative_input; + uint8_t positive_hysteresis; + uint8_t negative_hysteresis; + uint8_t warmup_time_us; + uint8_t response_mode; + void (*irq_config_func)(const struct device *dev); +}; + +struct nxp_acomp_data { + comparator_callback_t callback; + void *user_data; + uint32_t interrupt_mask; +}; + +static int nxp_acomp_get_output(const struct device *dev) +{ + const struct nxp_acomp_config *config = dev->config; + uint32_t status = config->base->STATUS0; + + return ((bool)(status & ACOMP_STATUS0_OUT_MASK)) ? 1U : 0U; +} + +static int nxp_acomp_set_trigger(const struct device *dev, enum comparator_trigger trigger) +{ + const struct nxp_acomp_config *config = dev->config; + struct nxp_acomp_data *data = dev->data; + uint32_t ctrl = config->base->CTRL0; + + ctrl &= ~(ACOMP_CTRL0_INT_ACT_HI_MASK | ACOMP_CTRL0_EDGE_LEVL_SEL_MASK); + + switch (trigger) { + case COMPARATOR_TRIGGER_NONE: + data->interrupt_mask = 0U; + break; + case COMPARATOR_TRIGGER_RISING_EDGE: + ctrl |= (ACOMP_CTRL0_EDGE_LEVL_SEL(1U) | ACOMP_CTRL0_INT_ACT_HI(1U)); + data->interrupt_mask = ACOMP_IMR0_OUTA_INT_MASK_MASK | ACOMP_IMR0_OUT_INT_MASK_MASK; + break; + case COMPARATOR_TRIGGER_FALLING_EDGE: + ctrl |= (ACOMP_CTRL0_EDGE_LEVL_SEL(1U) | ACOMP_CTRL0_INT_ACT_HI(0U)); + data->interrupt_mask = ACOMP_IMR0_OUTA_INT_MASK_MASK | ACOMP_IMR0_OUT_INT_MASK_MASK; + break; + case COMPARATOR_TRIGGER_BOTH_EDGES: + LOG_ERR("Trigger type not support."); + return -ENOTSUP; + default: + LOG_ERR("Trigger type invalid."); + return -EINVAL; + } + + config->base->CTRL0 = ctrl; + + /* Clear latched status flags before enabling interrupts. */ + config->base->ICR0 = ACOMP_ICR0_OUT_INT_CLR_MASK | ACOMP_ICR0_OUTA_INT_CLR_MASK; + + if ((data->interrupt_mask != 0U) && (data->callback != NULL)) { + config->base->IMR0 &= ~data->interrupt_mask; + } else { + config->base->IMR0 |= data->interrupt_mask; + } + + return 0; +} + +static int nxp_acomp_trigger_is_pending(const struct device *dev) +{ + const struct nxp_acomp_config *config = dev->config; + struct nxp_acomp_data *data = dev->data; + + /* Read raw status first. We'll clear the hardware flag when we + * consume the pending event to avoid leaving sticky RAW bits set + * and producing repeated reports. + */ + bool interrupts_enabled = (data->interrupt_mask & (ACOMP_IMR0_OUTA_INT_MASK_MASK | + ACOMP_IMR0_OUT_INT_MASK_MASK)) != 0U; + bool interrupt_flags = ((config->base->IRSR0 & (ACOMP_IRSR0_OUTA_INT_RAW_MASK | + ACOMP_IRSR0_OUT_INT_RAW_MASK))) != 0U; + int pending = (interrupts_enabled && interrupt_flags) ? 1 : 0; + + /* Always clear raw flags so we don't re-report the same edge. */ + config->base->ICR0 = ACOMP_ICR0_OUTA_INT_CLR_MASK | ACOMP_ICR0_OUT_INT_CLR_MASK; + + return pending; +} + +static int nxp_acomp_set_trigger_callback(const struct device *dev, + comparator_callback_t callback, void *user_data) +{ + const struct nxp_acomp_config *config = dev->config; + struct nxp_acomp_data *data = dev->data; + + config->base->CTRL0 &= ~ACOMP_CTRL0_EN_MASK; + + data->callback = callback; + data->user_data = user_data; + + /* Clear any pending flags when (re)arming the callback. */ + config->base->ICR0 = ACOMP_ICR0_OUTA_INT_CLR_MASK | ACOMP_ICR0_OUT_INT_CLR_MASK; + + if ((data->callback != NULL) && (data->interrupt_mask != 0U)) { + config->base->IMR0 &= ~data->interrupt_mask; + } else { + config->base->IMR0 |= data->interrupt_mask; + } + + config->base->CTRL0 |= ACOMP_CTRL0_EN_MASK; + + return 0; +} + +static void nxp_acomp_irq_handler(const struct device *dev) +{ + const struct nxp_acomp_config *config = dev->config; + struct nxp_acomp_data *data = dev->data; + uint32_t status = config->base->IRSR0; + uint32_t raw_mask = ACOMP_IRSR0_OUTA_INT_RAW_MASK | ACOMP_IRSR0_OUT_INT_RAW_MASK; + + /* Clear interrupt status flags */ + config->base->ICR0 = ACOMP_ICR0_OUTA_INT_CLR_MASK | ACOMP_ICR0_OUT_INT_CLR_MASK; + + if ((status & raw_mask) == 0U) { + return; + } + + if (data->callback == NULL) { + LOG_WRN("No callback can be executed."); + return; + } + + /* RAW bits stay asserted; mask both sources after one hit to avoid ISR storms. */ + config->base->IMR0 |= ACOMP_IMR0_OUTA_INT_MASK_MASK | ACOMP_IMR0_OUT_INT_MASK_MASK; + + data->callback(dev, data->user_data); +} + +#if CONFIG_PM_DEVICE +static int nxp_acomp_pm_callback(const struct device *dev, + enum pm_device_action action) +{ + const struct nxp_acomp_config *config = dev->config; + + switch (action) { + case PM_DEVICE_ACTION_RESUME: + config->base->CTRL0 |= ACOMP_CTRL0_EN_MASK; + break; + case PM_DEVICE_ACTION_SUSPEND: + config->base->CTRL0 &= ~ACOMP_CTRL0_EN_MASK; + break; + default: + return -ENOTSUP; + } + + return 0; +} +#endif + +static int nxp_acomp_init(const struct device *dev) +{ + const struct nxp_acomp_config *config = dev->config; + uint32_t ctrl = config->base->CTRL0; + uint32_t route = config->base->ROUTE0; + + /* Do software first. */ + config->base->RST0 |= ACOMP_RST0_SOFT_RST_MASK; + config->base->RST0 &= ~ACOMP_RST0_SOFT_RST_MASK; + + ctrl &= ~(ACOMP_CTRL0_WARMTIME_MASK | ACOMP_CTRL0_BIAS_PROG_MASK | + ACOMP_CTRL0_INACT_VAL_MASK | ACOMP_CTRL0_GPIOINV_MASK | + ACOMP_CTRL0_HYST_SELP_MASK | ACOMP_CTRL0_HYST_SELN_MASK | + ACOMP_CTRL0_POS_SEL_MASK | ACOMP_CTRL0_NEG_SEL_MASK | + ACOMP_CTRL0_LEVEL_SEL_MASK | ACOMP_CTRL0_MUXEN_MASK); + + ctrl |= ACOMP_CTRL0_WARMTIME(config->warmup_time_us) | + ACOMP_CTRL0_BIAS_PROG(config->response_mode) | + ACOMP_CTRL0_INACT_VAL(config->inactive_value_high) | + ACOMP_CTRL0_GPIOINV(config->invert_output) | + ACOMP_CTRL0_HYST_SELP(config->positive_hysteresis) | + ACOMP_CTRL0_HYST_SELN(config->negative_hysteresis) | + ACOMP_CTRL0_POS_SEL(config->positive_input) | + ACOMP_CTRL0_NEG_SEL(config->negative_input) | + ACOMP_CTRL0_MUXEN(1U); + + /* VIO-based negative inputs use LEVEL_SEL[1:0] to pick 0.25/0.5/0.75/1.0. */ + if (config->negative_input >= ACOMP_NEG_INPUT_VIO_0P25) { + uint32_t level = (config->negative_input - ACOMP_NEG_INPUT_VIO_0P25) & 0x3U; + + ctrl |= ACOMP_CTRL0_LEVEL_SEL(level); + } + config->base->CTRL0 = ctrl; + + route &= ~(ACOMP_ROUTE0_OUTSEL_MASK | ACOMP_ROUTE0_PE_MASK); + route |= ACOMP_ROUTE0_OUTSEL(config->async_output) | + ACOMP_ROUTE0_PE(config->enable_pin_out); + config->base->ROUTE0 = route; + + /* Disable interrupt, clear status. */ + config->base->IMR0 |= ACOMP_IMR0_OUT_INT_MASK_MASK | ACOMP_IMR0_OUTA_INT_MASK_MASK; + config->base->ICR0 = ACOMP_ICR0_OUT_INT_CLR_MASK | ACOMP_ICR0_OUTA_INT_CLR_MASK; + + config->base->CTRL0 |= ACOMP_CTRL0_EN_MASK; + + config->irq_config_func(dev); + +#if CONFIG_PM_DEVICE + return pm_device_driver_init(dev, nxp_acomp_pm_callback); +#else + return 0; +#endif +} + +static DEVICE_API(comparator, nxp_acomp_api) = { + .get_output = nxp_acomp_get_output, + .set_trigger = nxp_acomp_set_trigger, + .set_trigger_callback = nxp_acomp_set_trigger_callback, + .trigger_is_pending = nxp_acomp_trigger_is_pending, +}; + +#if CONFIG_PM_DEVICE +#define ACOMP_PM_DEVICE_DEFINE PM_DEVICE_DT_INST_DEFINE(inst, nxp_acomp_pm_callback); +#define ACOMP_PM_DEVICE_GET PM_DEVICE_DT_INST_GET(inst) +#else +#define ACOMP_PM_DEVICE_DEFINE +#define ACOMP_PM_DEVICE_GET NULL +#endif + +#define NXP_ACOMP_INIT(inst) \ + ACOMP_PM_DEVICE_DEFINE \ + \ + static void nxp_acomp_irq_config_##inst(const struct device *dev) \ + { \ + IRQ_CONNECT(DT_INST_IRQN(inst), DT_INST_IRQ(inst, priority), \ + nxp_acomp_irq_handler, DEVICE_DT_INST_GET(inst), 0); \ + irq_enable(DT_INST_IRQN(inst)); \ + } \ + \ + static struct nxp_acomp_data nxp_acomp_data_##inst; \ + \ + static const struct nxp_acomp_config nxp_acomp_config_##inst = { \ + .base = (ACOMP_Type *)DT_INST_REG_ADDR(inst), \ + .positive_input = DT_ENUM_IDX(DT_DRV_INST(inst), positive_input), \ + .negative_input = DT_ENUM_IDX(DT_DRV_INST(inst), negative_input), \ + .positive_hysteresis = DT_INST_PROP_OR(inst, positive_hysteresis_mv / 10, 0), \ + .negative_hysteresis = DT_INST_PROP_OR(inst, negative_hysteresis_mv / 10, 0), \ + .warmup_time_us = DT_INST_PROP_OR(inst, warmup_time_us, 0), \ + .response_mode = DT_ENUM_IDX_OR(DT_DRV_INST(inst), response_mode, 0), \ + .inactive_value_high = DT_INST_PROP_OR(inst, inactive_value_high, 0), \ + .invert_output = DT_INST_PROP_OR(inst, invert_output, 0), \ + .enable_pin_out = DT_INST_PROP_OR(inst, enable_pin_out, 0), \ + .async_output = DT_INST_PROP_OR(inst, async_output, 0), \ + .irq_config_func = nxp_acomp_irq_config_##inst, \ + }; \ + \ + DEVICE_DT_INST_DEFINE(inst, nxp_acomp_init, NULL, \ + &nxp_acomp_data_##inst, &nxp_acomp_config_##inst, POST_KERNEL, \ + CONFIG_COMPARATOR_INIT_PRIORITY, &nxp_acomp_api); + +DT_INST_FOREACH_STATUS_OKAY(NXP_ACOMP_INIT) diff --git a/dts/bindings/comparator/nxp,acomp.yaml b/dts/bindings/comparator/nxp,acomp.yaml new file mode 100644 index 000000000000..db2cf627fb1e --- /dev/null +++ b/dts/bindings/comparator/nxp,acomp.yaml @@ -0,0 +1,102 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +description: | + NXP Analog Comparator (ACOMP) + +compatible: "nxp,acomp" + +include: + - base.yaml + - pinctrl-device.yaml + +properties: + reg: + required: true + + interrupts: + required: true + + positive-input: + type: string + enum: + - ch0 + - ch1 + - ch2 + - ch3 + - ch4 + - ch5 + - ch6 + - ch7 + - daca + - dacb + required: true + description: | + Positive input selection. + + negative-input: + type: string + enum: + - ch0 + - ch1 + - ch2 + - ch3 + - ch4 + - ch5 + - ch6 + - ch7 + - daca + - dacb + - vref1p2 + - vssa + - vio-0p25 + - vio-0p50 + - vio-0p75 + - vio-1p00 + required: true + description: | + Negative input selection. + + positive-hysteresis-mv: + type: int + enum: [0, 10, 20, 30, 40, 50, 60, 70] + description: | + Positive input hysteresis in millivolts. + + negative-hysteresis-mv: + type: int + enum: [0, 10, 20, 30, 40, 50, 60, 70] + description: | + Negative input hysteresis in millivolts. + + warmup-time-us: + type: int + enum: [1, 2, 4, 8] + description: | + Warm-up time before the comparator becomes active. + + response-mode: + type: string + enum: ["fast", "medium", "slow"] + description: | + Bias/response speed selection. + + inactive-value-high: + type: boolean + description: | + Set comparator output high when disabled. + + enable-pin-out: + type: boolean + description: | + Enable routing comparator output to its GPIO pin. + + invert-output: + type: boolean + description: | + Invert the comparator output routed to GPIO. + + async-output: + type: boolean + description: | + Use asynchronous comparator output for pin routing and interrupts. From 864272d892ff9720eb7950fdd6fed42ceaf73f7c Mon Sep 17 00:00:00 2001 From: Zhaoxiang Jin Date: Wed, 10 Dec 2025 22:47:39 +0800 Subject: [PATCH 0351/3659] boards: nxp/frdm_rw612: Enable NXP ACOMP for frdm_rw612 Enable NXP ACOMP for frdm_rw612 Signed-off-by: Zhaoxiang Jin --- boards/nxp/frdm_rw612/frdm_rw612.yaml | 1 + dts/arm/nxp/nxp_rw6xx_common.dtsi | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/boards/nxp/frdm_rw612/frdm_rw612.yaml b/boards/nxp/frdm_rw612/frdm_rw612.yaml index 7efe02807c44..29401a9c3fca 100644 --- a/boards/nxp/frdm_rw612/frdm_rw612.yaml +++ b/boards/nxp/frdm_rw612/frdm_rw612.yaml @@ -33,4 +33,5 @@ supported: - dac - netif:eth - netif:openthread + - comparator vendor: nxp diff --git a/dts/arm/nxp/nxp_rw6xx_common.dtsi b/dts/arm/nxp/nxp_rw6xx_common.dtsi index 86c01a28ef4c..3ed349059721 100644 --- a/dts/arm/nxp/nxp_rw6xx_common.dtsi +++ b/dts/arm/nxp/nxp_rw6xx_common.dtsi @@ -604,6 +604,13 @@ #io-channel-cells = <0>; power-domains = <&peripheral_domain>; }; + + acomp: acomp@38400 { + compatible = "nxp,acomp"; + reg = <0x38400 0x4c>; + interrupts = <110 0>; + status = "disabled"; + }; }; os_timer: timers@13b000 { From 315e4efa2daaf329a2b13b02546ccf6f0f1e6ee9 Mon Sep 17 00:00:00 2001 From: Zhaoxiang Jin Date: Wed, 10 Dec 2025 22:48:43 +0800 Subject: [PATCH 0352/3659] test: comparator/gpio_loopback: handle unsupported BOTH trigger mode If the comparator driver does not support BOTH edge trigger mode, skip the test instead of failing it. Signed-off-by: Zhaoxiang Jin --- tests/drivers/comparator/gpio_loopback/src/test.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tests/drivers/comparator/gpio_loopback/src/test.c b/tests/drivers/comparator/gpio_loopback/src/test.c index 930422b1a65e..6a0cc6756330 100644 --- a/tests/drivers/comparator/gpio_loopback/src/test.c +++ b/tests/drivers/comparator/gpio_loopback/src/test.c @@ -91,7 +91,14 @@ ZTEST(comparator_gpio_loopback, test_trigger_falling_edge_pending) ZTEST(comparator_gpio_loopback, test_trigger_both_edges_pending) { - zassert_ok(comparator_set_trigger(test_dev, COMPARATOR_TRIGGER_BOTH_EDGES)); + int rc = comparator_set_trigger(test_dev, COMPARATOR_TRIGGER_BOTH_EDGES); + + if (rc == -ENOTSUP) { + /* If driver explicitly doesn't support BOTH — skip the test. */ + ztest_test_skip(); + } + + zassert_ok(rc); k_msleep(1); zassert_equal(comparator_trigger_is_pending(test_dev), 0); zassert_ok(gpio_pin_set_dt(&test_pin, 1)); From 93ec5c8c1d01fdf450aaa3227a86f0a1ad6d8170 Mon Sep 17 00:00:00 2001 From: Zhaoxiang Jin Date: Wed, 10 Dec 2025 22:49:56 +0800 Subject: [PATCH 0353/3659] test: comparator: Enable gpio_loopback for NXP ACOMP driver Enable gpio_loopback test for NXP ACOMP driver. Signed-off-by: Zhaoxiang Jin --- .../gpio_loopback/boards/frdm_rw612.overlay | 24 +++++++++++++++++++ .../comparator/gpio_loopback/testcase.yaml | 3 +++ 2 files changed, 27 insertions(+) create mode 100644 tests/drivers/comparator/gpio_loopback/boards/frdm_rw612.overlay diff --git a/tests/drivers/comparator/gpio_loopback/boards/frdm_rw612.overlay b/tests/drivers/comparator/gpio_loopback/boards/frdm_rw612.overlay new file mode 100644 index 000000000000..b56c925ab05e --- /dev/null +++ b/tests/drivers/comparator/gpio_loopback/boards/frdm_rw612.overlay @@ -0,0 +1,24 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/ { + aliases { + test-comp = &acomp; + }; + + zephyr,user { + /* J4-4(GPIO_43) connect to J4-2(GPIO_42). */ + test-gpios = <&hsgpio1 11 GPIO_ACTIVE_HIGH>; + }; +}; + +&acomp { + status = "okay"; + positive-input = "ch0"; + negative-input = "vio-0p50"; +}; diff --git a/tests/drivers/comparator/gpio_loopback/testcase.yaml b/tests/drivers/comparator/gpio_loopback/testcase.yaml index 0ff7b7061cec..deeca32ffe1f 100644 --- a/tests/drivers/comparator/gpio_loopback/testcase.yaml +++ b/tests/drivers/comparator/gpio_loopback/testcase.yaml @@ -47,3 +47,6 @@ tests: drivers.comparator.gpio_loopback.nxp_hscmp: platform_allow: - lpcxpresso55s36 + drivers.comparator.gpio_loopback.nxp_acomp: + platform_allow: + - frdm_rw612 From 683ea0eaf0eb3ef62a04ec0e69ec7c6447581b60 Mon Sep 17 00:00:00 2001 From: Fabrice DJIATSA Date: Tue, 9 Dec 2025 16:31:19 +0100 Subject: [PATCH 0354/3659] tests: drivers: spi: spi_loopback: add support for nucleo_g071rb add nucleo_g071rb overlay and conf files to configure board to execute spi_loopback to set up the board for executing the spi_loopback test on CI. With this addition, we will now be able to detect SPI and RTIO regressions on this board. Signed-off-by: Fabrice DJIATSA --- .../spi_loopback/boards/nucleo_g071rb.conf | 2 ++ .../spi_loopback/boards/nucleo_g071rb.overlay | 31 +++++++++++++++++++ tests/drivers/spi/spi_loopback/testcase.yaml | 3 ++ 3 files changed, 36 insertions(+) create mode 100644 tests/drivers/spi/spi_loopback/boards/nucleo_g071rb.conf create mode 100644 tests/drivers/spi/spi_loopback/boards/nucleo_g071rb.overlay diff --git a/tests/drivers/spi/spi_loopback/boards/nucleo_g071rb.conf b/tests/drivers/spi/spi_loopback/boards/nucleo_g071rb.conf new file mode 100644 index 000000000000..093e1f09d89d --- /dev/null +++ b/tests/drivers/spi/spi_loopback/boards/nucleo_g071rb.conf @@ -0,0 +1,2 @@ +CONFIG_SPI_LARGE_BUFFER_SIZE=4500 +CONFIG_SPI_IDEAL_TRANSFER_DURATION_SCALING=20 diff --git a/tests/drivers/spi/spi_loopback/boards/nucleo_g071rb.overlay b/tests/drivers/spi/spi_loopback/boards/nucleo_g071rb.overlay new file mode 100644 index 000000000000..93a1d5ef5cd1 --- /dev/null +++ b/tests/drivers/spi/spi_loopback/boards/nucleo_g071rb.overlay @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2025 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&spi1 { + dmas = <&dmamux1 2 17 (STM32_DMA_PERIPH_TX | STM32_DMA_PRIORITY_HIGH)>, + <&dmamux1 1 16 (STM32_DMA_PERIPH_RX | STM32_DMA_PRIORITY_HIGH)>; + dma-names = "tx", "rx"; + + slow@0 { + compatible = "test-spi-loopback-slow"; + reg = <0>; + spi-max-frequency = <500000>; + }; + + fast@0 { + compatible = "test-spi-loopback-fast"; + reg = <0>; + spi-max-frequency = <16000000>; + }; +}; + +&dma1 { + status = "okay"; +}; + +&dmamux1 { + status = "okay"; +}; diff --git a/tests/drivers/spi/spi_loopback/testcase.yaml b/tests/drivers/spi/spi_loopback/testcase.yaml index e46ace151095..55e47bbc7340 100644 --- a/tests/drivers/spi/spi_loopback/testcase.yaml +++ b/tests/drivers/spi/spi_loopback/testcase.yaml @@ -58,6 +58,7 @@ tests: platform_allow: - b_u585i_iot02a - nucleo_c071rb + - nucleo_g071rb - nucleo_g474re - nucleo_f207zg - nucleo_f429zi @@ -99,6 +100,7 @@ tests: - nucleo_f429zi - nucleo_f746zg - nucleo_f767zi + - nucleo_g071rb - nucleo_g474re - nucleo_h743zi - nucleo_h753zi @@ -124,6 +126,7 @@ tests: - nucleo_f429zi - nucleo_f746zg - nucleo_f767zi + - nucleo_g071rb - nucleo_g474re - nucleo_h743zi - nucleo_h753zi From 318e43503f5cd141e64b97ae6556c12ea30ec818 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Tue, 9 Dec 2025 14:50:25 +0000 Subject: [PATCH 0355/3659] drivers: ksz8081: fix reset pin polarity The reset pin, like most reset pins, is active low. Fix the driver to treat it as active low and simplify the pin control logic while at it. Fix all current boards using the wrong pin definition and add a note for out of tree users. Signed-off-by: Fabio Baltieri --- boards/nxp/frdm_rw612/frdm_rw612_common.dtsi | 2 +- boards/nxp/mimxrt1020_evk/mimxrt1020_evk.dts | 2 +- boards/nxp/mimxrt1024_evk/mimxrt1024_evk.dts | 2 +- boards/nxp/mimxrt1050_evk/mimxrt1050_evk.dtsi | 2 +- boards/nxp/mimxrt1060_evk/mimxrt1060_evk.dtsi | 2 +- boards/nxp/mimxrt1064_evk/mimxrt1064_evk.dts | 2 +- boards/nxp/mimxrt1160_evk/mimxrt1160_evk.dtsi | 2 +- boards/nxp/mimxrt1170_evk/mimxrt1170_evk.dtsi | 2 +- .../rd_rw612_bga_rw612_ethernet.dts | 2 +- doc/releases/migration-guide-4.4.rst | 4 +++ drivers/ethernet/phy/phy_microchip_ksz8081.c | 28 ++----------------- 11 files changed, 16 insertions(+), 34 deletions(-) diff --git a/boards/nxp/frdm_rw612/frdm_rw612_common.dtsi b/boards/nxp/frdm_rw612/frdm_rw612_common.dtsi index 1d4e20a9ff70..c346301132b4 100644 --- a/boards/nxp/frdm_rw612/frdm_rw612_common.dtsi +++ b/boards/nxp/frdm_rw612/frdm_rw612_common.dtsi @@ -232,7 +232,7 @@ mikrobus_serial: &flexcomm0 {}; compatible = "microchip,ksz8081"; reg = <2>; status = "okay"; - reset-gpios = <&hsgpio1 23 GPIO_ACTIVE_HIGH>; + reset-gpios = <&hsgpio1 23 GPIO_ACTIVE_LOW>; int-gpios = <&hsgpio0 21 GPIO_ACTIVE_HIGH>; microchip,interface-type = "rmii"; }; diff --git a/boards/nxp/mimxrt1020_evk/mimxrt1020_evk.dts b/boards/nxp/mimxrt1020_evk/mimxrt1020_evk.dts index 23f61740ce64..73c3facd2a7d 100644 --- a/boards/nxp/mimxrt1020_evk/mimxrt1020_evk.dts +++ b/boards/nxp/mimxrt1020_evk/mimxrt1020_evk.dts @@ -160,7 +160,7 @@ arduino_serial: &lpuart2 { compatible = "microchip,ksz8081"; reg = <0>; status = "okay"; - reset-gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>; + reset-gpios = <&gpio1 4 GPIO_ACTIVE_LOW>; int-gpios = <&gpio1 22 GPIO_ACTIVE_HIGH>; microchip,interface-type = "rmii"; }; diff --git a/boards/nxp/mimxrt1024_evk/mimxrt1024_evk.dts b/boards/nxp/mimxrt1024_evk/mimxrt1024_evk.dts index 29a39b7f66f8..07a86e4e8588 100644 --- a/boards/nxp/mimxrt1024_evk/mimxrt1024_evk.dts +++ b/boards/nxp/mimxrt1024_evk/mimxrt1024_evk.dts @@ -152,7 +152,7 @@ arduino_serial: &lpuart2 { compatible = "microchip,ksz8081"; reg = <0>; status = "okay"; - reset-gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>; + reset-gpios = <&gpio1 4 GPIO_ACTIVE_LOW>; int-gpios = <&gpio1 22 GPIO_ACTIVE_HIGH>; microchip,interface-type = "rmii"; }; diff --git a/boards/nxp/mimxrt1050_evk/mimxrt1050_evk.dtsi b/boards/nxp/mimxrt1050_evk/mimxrt1050_evk.dtsi index 499d43d1fb41..b3ed061bc25b 100644 --- a/boards/nxp/mimxrt1050_evk/mimxrt1050_evk.dtsi +++ b/boards/nxp/mimxrt1050_evk/mimxrt1050_evk.dtsi @@ -200,7 +200,7 @@ zephyr_lcdif: &lcdif { compatible = "microchip,ksz8081"; reg = <0>; status = "okay"; - reset-gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>; + reset-gpios = <&gpio1 9 GPIO_ACTIVE_LOW>; int-gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>; microchip,interface-type = "rmii"; }; diff --git a/boards/nxp/mimxrt1060_evk/mimxrt1060_evk.dtsi b/boards/nxp/mimxrt1060_evk/mimxrt1060_evk.dtsi index 087cff325fbc..20bdef2f33de 100644 --- a/boards/nxp/mimxrt1060_evk/mimxrt1060_evk.dtsi +++ b/boards/nxp/mimxrt1060_evk/mimxrt1060_evk.dtsi @@ -178,7 +178,7 @@ arduino_i2c: &lpi2c1 { compatible = "microchip,ksz8081"; reg = <0>; status = "okay"; - reset-gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>; + reset-gpios = <&gpio1 9 GPIO_ACTIVE_LOW>; int-gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>; microchip,interface-type = "rmii"; }; diff --git a/boards/nxp/mimxrt1064_evk/mimxrt1064_evk.dts b/boards/nxp/mimxrt1064_evk/mimxrt1064_evk.dts index 8a353bca0a6e..28f64e1f8339 100644 --- a/boards/nxp/mimxrt1064_evk/mimxrt1064_evk.dts +++ b/boards/nxp/mimxrt1064_evk/mimxrt1064_evk.dts @@ -244,7 +244,7 @@ arduino_serial: &lpuart3 { compatible = "microchip,ksz8081"; reg = <0>; status = "okay"; - reset-gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>; + reset-gpios = <&gpio1 9 GPIO_ACTIVE_LOW>; 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 9f5ded1dbe7e..ac1b5c6af4c6 100644 --- a/boards/nxp/mimxrt1160_evk/mimxrt1160_evk.dtsi +++ b/boards/nxp/mimxrt1160_evk/mimxrt1160_evk.dtsi @@ -160,7 +160,7 @@ compatible = "microchip,ksz8081"; reg = <0>; status = "okay"; - reset-gpios = <&gpio12 12 GPIO_ACTIVE_HIGH>; + reset-gpios = <&gpio12 12 GPIO_ACTIVE_LOW>; int-gpios = <&gpio9 11 GPIO_ACTIVE_HIGH>; microchip,interface-type = "rmii"; }; diff --git a/boards/nxp/mimxrt1170_evk/mimxrt1170_evk.dtsi b/boards/nxp/mimxrt1170_evk/mimxrt1170_evk.dtsi index ab2f9dfb2219..f1571826ebec 100644 --- a/boards/nxp/mimxrt1170_evk/mimxrt1170_evk.dtsi +++ b/boards/nxp/mimxrt1170_evk/mimxrt1170_evk.dtsi @@ -154,7 +154,7 @@ arduino_serial: &lpuart2 { compatible = "microchip,ksz8081"; reg = <0>; status = "okay"; - reset-gpios = <&gpio12 12 GPIO_ACTIVE_HIGH>; + reset-gpios = <&gpio12 12 GPIO_ACTIVE_LOW>; int-gpios = <&gpio9 11 GPIO_ACTIVE_HIGH>; microchip,interface-type = "rmii"; }; 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 index 6792e819adcb..32d80aa5e93d 100644 --- a/boards/nxp/rd_rw612_bga/rd_rw612_bga_rw612_ethernet.dts +++ b/boards/nxp/rd_rw612_bga/rd_rw612_bga_rw612_ethernet.dts @@ -33,7 +33,7 @@ compatible = "microchip,ksz8081"; reg = <2>; status = "okay"; - reset-gpios = <&hsgpio1 23 GPIO_ACTIVE_HIGH>; + reset-gpios = <&hsgpio1 23 GPIO_ACTIVE_LOW>; int-gpios = <&hsgpio0 21 GPIO_ACTIVE_HIGH>; microchip,interface-type = "rmii"; }; diff --git a/doc/releases/migration-guide-4.4.rst b/doc/releases/migration-guide-4.4.rst index 670fee39a15d..0853c0ace75c 100644 --- a/doc/releases/migration-guide-4.4.rst +++ b/doc/releases/migration-guide-4.4.rst @@ -85,6 +85,10 @@ Ethernet is needed. There you need to specify the fixed link parameters using the ``default-speeds`` property (:github:`100454`). +* The ``reset-gpios`` property of :dtcompatible:`microchip,ksz8081` has been + reworked to be used as active low, you may have to set the pin as + ``GPIO_ACTIVE_LOW`` in devicetree (:github:`100751`). + MDIO ==== diff --git a/drivers/ethernet/phy/phy_microchip_ksz8081.c b/drivers/ethernet/phy/phy_microchip_ksz8081.c index 52774e45d06c..3d5bd4b9ca84 100644 --- a/drivers/ethernet/phy/phy_microchip_ksz8081.c +++ b/drivers/ethernet/phy/phy_microchip_ksz8081.c @@ -407,12 +407,11 @@ static int phy_mc_ksz8081_reset_gpio(const struct mc_ksz8081_config *config) { int ret; - if (!config->reset_gpio.port) { + if (!gpio_is_ready_dt(&config->reset_gpio)) { return -ENODEV; } - /* Start reset */ - ret = gpio_pin_set_dt(&config->reset_gpio, 0); + ret = gpio_pin_configure_dt(&config->reset_gpio, GPIO_OUTPUT_ACTIVE); if (ret) { return ret; } @@ -420,8 +419,7 @@ static int phy_mc_ksz8081_reset_gpio(const struct mc_ksz8081_config *config) /* Wait for at least 500 us as specified by datasheet */ k_busy_wait(1000); - /* Reset over */ - ret = gpio_pin_set_dt(&config->reset_gpio, 1); + ret = gpio_pin_set_dt(&config->reset_gpio, 0); /* After deasserting reset, must wait at least 100 us to use programming interface */ k_busy_wait(200); @@ -653,21 +651,6 @@ static int ksz8081_init_int_gpios(const struct device *dev) #define ksz8081_init_int_gpios(dev) 0 #endif -#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(reset_gpios) -static int ksz8081_init_reset_gpios(const struct device *dev) -{ - const struct mc_ksz8081_config *config = dev->config; - - if (config->reset_gpio.port == NULL) { - return 0; - } - - return gpio_pin_configure_dt(&config->reset_gpio, GPIO_OUTPUT_ACTIVE); -} -#else -#define ksz8081_init_reset_gpios(dev) 0 -#endif - static int phy_mc_ksz8081_init(const struct device *dev) { const struct mc_ksz8081_config *config = dev->config; @@ -681,11 +664,6 @@ static int phy_mc_ksz8081_init(const struct device *dev) return ret; } - ret = ksz8081_init_reset_gpios(dev); - if (ret) { - return ret; - } - /* Reset PHY */ ret = phy_mc_ksz8081_reset(dev); if (ret) { From ea9c1af07da044647eb136623e37db202fb7fc9b Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Tue, 9 Dec 2025 05:33:13 +0100 Subject: [PATCH 0356/3659] samples: drivers: crypto: fix heap memory size for Mbed TLS shim Increase heap memory size when Mbed TLS shim driver is used otherwise all crypto tests will fail on some platforms. Signed-off-by: Valerio Setti --- samples/drivers/crypto/prj_mtls_shim.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/drivers/crypto/prj_mtls_shim.conf b/samples/drivers/crypto/prj_mtls_shim.conf index d595285affa1..5954fe5f9f3c 100644 --- a/samples/drivers/crypto/prj_mtls_shim.conf +++ b/samples/drivers/crypto/prj_mtls_shim.conf @@ -1,5 +1,5 @@ CONFIG_MBEDTLS=y CONFIG_MBEDTLS_BUILTIN=y -CONFIG_MBEDTLS_HEAP_SIZE=512 +CONFIG_MBEDTLS_HEAP_SIZE=1024 CONFIG_CRYPTO_MBEDTLS_SHIM=y From 75b48db7184029964c770ec2bb81d3540046c382 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Tue, 9 Dec 2025 05:34:19 +0100 Subject: [PATCH 0357/3659] samples: drivers: crypto: fix regex matching for Mbed TLS shim Update regex matching for the Mbed TLS shim driver scenario in order to match all the supported cases and ensure that they all passed. Signed-off-by: Valerio Setti --- samples/drivers/crypto/sample.yaml | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/samples/drivers/crypto/sample.yaml b/samples/drivers/crypto/sample.yaml index 54fadd37651e..e653eda24bfc 100644 --- a/samples/drivers/crypto/sample.yaml +++ b/samples/drivers/crypto/sample.yaml @@ -15,11 +15,14 @@ tests: harness_config: type: multi_line regex: - - ".*: Cipher Sample" - - ".*: CBC Mode" - - ".*: CTR Mode" - - ".*: CCM Mode" - - ".*: GCM Mode" + - ".*: ECB mode ENCRYPT - Match" + - ".*: ECB mode DECRYPT - Match" + - ".*: CBC mode ENCRYPT - Match" + - ".*: CBC mode DECRYPT - Match" + - ".*: CCM mode ENCRYPT - Match" + - ".*: CCM mode DECRYPT - Match" + - ".*: GCM mode ENCRYPT - Match" + - ".*: GCM mode DECRYPT - Match" sample.drivers.crypto.stm32: tags: crypto filter: dt_compat_enabled("st,stm32-aes") or dt_compat_enabled("st,stm32-cryp") From d76477f9eb3c3bc5a7207c297e04bd5683bfd076 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Wed, 10 Dec 2025 09:20:23 +0100 Subject: [PATCH 0358/3659] drivers: crypto: mbedtls_shim: fix crash in AES-ECB for RISCV 64 bits Using "pkt->out_len" as the output length of "psa_cipher_[en|de]crypt" caused a crash in RISCV 64 bits platforms due to misaligned address access. The solution is to add a temporary value on the stack to store this lenght and only after the [en|de]cryption copy it to "pkt->out_len". Signed-off-by: Valerio Setti --- drivers/crypto/crypto_mbedtls_shim.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/crypto/crypto_mbedtls_shim.c b/drivers/crypto/crypto_mbedtls_shim.c index 054ccd998937..569658a24a51 100644 --- a/drivers/crypto/crypto_mbedtls_shim.c +++ b/drivers/crypto/crypto_mbedtls_shim.c @@ -84,6 +84,7 @@ static int mbedtls_ecb(struct cipher_ctx *ctx, struct cipher_pkt *pkt) { struct mbedtls_shim_session *session = ctx->drv_sessn_state; psa_status_t status; + size_t out_len; /* For security reasons, ECB mode should not be used to encrypt/decrypt * more than one block. Use CBC mode instead. @@ -97,14 +98,16 @@ static int mbedtls_ecb(struct cipher_ctx *ctx, struct cipher_pkt *pkt) status = psa_cipher_encrypt(session->key_id, session->psa_alg, pkt->in_buf, pkt->in_len, pkt->out_buf, pkt->out_buf_max, - (size_t *) &pkt->out_len); + &out_len); } else { status = psa_cipher_decrypt(session->key_id, session->psa_alg, pkt->in_buf, pkt->in_len, pkt->out_buf, pkt->out_buf_max, - (size_t *) &pkt->out_len); + &out_len); } + pkt->out_len = out_len; + if (status != PSA_SUCCESS) { LOG_ERR("psa_cipher_[en|de]crypt() failed (%d)", status); return -EINVAL; From 2e54a3915bcbd5ffb153f5751777692aaa9573fa Mon Sep 17 00:00:00 2001 From: Zhaoxiang Jin Date: Fri, 5 Dec 2025 19:10:18 +0800 Subject: [PATCH 0359/3659] tests: counter_basic_api: harden alarm capability probing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add a self-contained alarm_capable() probe that starts the device, sets and cancels a 1-tick alarm, and stops the counter again. This treats -ENOTSUP as “not capable” and avoids leaving pending alarms. - Switch single/multiple alarm capability checks to reuse alarm_capable(), preventing unsupported drivers from running alarm cases and reducing false failures. - Ensure capability probing no longer leaves the driver running or with active alarms, preventing teardown/set_top_value failures in later tests. Signed-off-by: Zhaoxiang Jin --- .../counter_basic_api/src/test_counter.c | 63 +++++++++++++++++-- 1 file changed, 59 insertions(+), 4 deletions(-) diff --git a/tests/drivers/counter/counter_basic_api/src/test_counter.c b/tests/drivers/counter/counter_basic_api/src/test_counter.c index 7f159bf734b4..caa197ef965c 100644 --- a/tests/drivers/counter/counter_basic_api/src/test_counter.c +++ b/tests/drivers/counter/counter_basic_api/src/test_counter.c @@ -432,6 +432,62 @@ static void alarm_handler(const struct device *dev, uint8_t chan_id, k_sem_give(&alarm_cnt_sem); } +static void alarm_capable_handler(const struct device *dev, uint8_t chan_id, + uint32_t counter, + void *user_data) +{ + ARG_UNUSED(dev); + ARG_UNUSED(chan_id); + ARG_UNUSED(counter); + ARG_UNUSED(user_data); + + /* Intentionally empty - capability probe only */ +} + +/* Any non-zero error (including -ENOTSUP) is treated as "not supported", + * and only returns true when there are no errors throughout the entire process. + */ +static bool alarm_capable(const struct device *dev) +{ + struct counter_alarm_cfg cfg = { + .flags = 0U, + .ticks = counter_us_to_ticks(dev, 1000U), + .callback = alarm_capable_handler, + .user_data = NULL, + }; + + /* Avoid zero-tick requests on very low-frequency counters */ + if (cfg.ticks == 0U) { + cfg.ticks = 1U; + } + + int err; + + if (counter_get_num_of_channels(dev) < 1U) { + return false; + } + + err = counter_start(dev); + if (err != 0) { + return false; + } + + err = counter_set_channel_alarm(dev, 0, &cfg); + if (err != 0) { + goto out_stop; + } + + err = counter_cancel_channel_alarm(dev, 0); + if (err != 0) { + goto out_stop; + } + +out_stop: + (void)counter_stop(dev); + + return err == 0; +} + static void test_single_shot_alarm_instance(const struct device *dev, bool set_top) { int err; @@ -524,13 +580,12 @@ void test_single_shot_alarm_top_instance(const struct device *dev) static bool single_channel_alarm_capable(const struct device *dev) { - return (counter_get_num_of_channels(dev) > 0); + return alarm_capable(dev); } static bool single_channel_alarm_and_custom_top_capable(const struct device *dev) { - return single_channel_alarm_capable(dev) && - set_top_value_capable(dev); + return alarm_capable(dev) && set_top_value_capable(dev); } ZTEST(counter_basic, test_single_shot_alarm_notop) @@ -652,7 +707,7 @@ static void test_multiple_alarms_instance(const struct device *dev) static bool multiple_channel_alarm_capable(const struct device *dev) { - return (counter_get_num_of_channels(dev) > 1); + return alarm_capable(dev) && (counter_get_num_of_channels(dev) > 1); } ZTEST(counter_basic, test_multiple_alarms) From 2bff5bdef0ae0c05011b899e6583a3379e84b7cb Mon Sep 17 00:00:00 2001 From: Jason Yu Date: Sun, 7 Dec 2025 21:16:26 +0800 Subject: [PATCH 0360/3659] dts: nxp: resets: include the reset header Include the header so that resets can be added in each driver node, for such platforms: mcxaxxx6, mcxa344. Signed-off-by: Jason Yu --- dts/arm/nxp/nxp_mcxa156.dtsi | 1 + dts/arm/nxp/nxp_mcxa344.dtsi | 1 + dts/arm/nxp/nxp_mcxaxx6_common.dtsi | 1 + 3 files changed, 3 insertions(+) diff --git a/dts/arm/nxp/nxp_mcxa156.dtsi b/dts/arm/nxp/nxp_mcxa156.dtsi index 7f0bb64aa656..00c9234d7b98 100644 --- a/dts/arm/nxp/nxp_mcxa156.dtsi +++ b/dts/arm/nxp/nxp_mcxa156.dtsi @@ -8,6 +8,7 @@ #include #include #include +#include #include #include diff --git a/dts/arm/nxp/nxp_mcxa344.dtsi b/dts/arm/nxp/nxp_mcxa344.dtsi index 2f4e5e81922e..c7b67d6c9846 100644 --- a/dts/arm/nxp/nxp_mcxa344.dtsi +++ b/dts/arm/nxp/nxp_mcxa344.dtsi @@ -7,6 +7,7 @@ #include #include #include +#include #include #include diff --git a/dts/arm/nxp/nxp_mcxaxx6_common.dtsi b/dts/arm/nxp/nxp_mcxaxx6_common.dtsi index bbb8433e8e85..b19a4d78a5da 100644 --- a/dts/arm/nxp/nxp_mcxaxx6_common.dtsi +++ b/dts/arm/nxp/nxp_mcxaxx6_common.dtsi @@ -8,6 +8,7 @@ #include #include #include +#include #include #include From 4e760db89348de33380363e94b5e778f6dfa3399 Mon Sep 17 00:00:00 2001 From: Jason Yu Date: Mon, 17 Nov 2025 16:23:23 +0800 Subject: [PATCH 0361/3659] dts: bindings: os-timer: Add resets in device tree binding Add resets in OSTIMER device tree binding Signed-off-by: Jason Yu --- dts/bindings/timer/nxp,os-timer.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dts/bindings/timer/nxp,os-timer.yaml b/dts/bindings/timer/nxp,os-timer.yaml index eb945b807fc4..519e20f73b53 100644 --- a/dts/bindings/timer/nxp,os-timer.yaml +++ b/dts/bindings/timer/nxp,os-timer.yaml @@ -20,3 +20,7 @@ properties: Instance of a counter peripheral. The OS Timer maybe powered off in certain deep power down modes. The OS Timer driver will use this counter to wakeup and also to keep track of system time. + + resets: + type: phandle-array + description: reset line From c9a1e0fd91277432f51013519c9e33bdb506419c Mon Sep 17 00:00:00 2001 From: Jason Yu Date: Thu, 6 Nov 2025 17:16:21 +0800 Subject: [PATCH 0362/3659] drivers: timer: ostimer: Change to use reset API Use reset API to reset OSTIMER for better portability. Signed-off-by: Jason Yu --- drivers/timer/Kconfig.mcux_os | 1 + drivers/timer/mcux_os_timer.c | 8 +++++++- dts/arm/nxp/nxp_mcxa153.dtsi | 1 + dts/arm/nxp/nxp_mcxa156.dtsi | 1 + dts/arm/nxp/nxp_mcxa344.dtsi | 1 + dts/arm/nxp/nxp_mcxaxx6_common.dtsi | 1 + dts/arm/nxp/nxp_mcxn23x_common.dtsi | 1 + dts/arm/nxp/nxp_mcxnx4x_common.dtsi | 1 + dts/arm/nxp/nxp_mcxw23x_common.dtsi | 1 + dts/arm/nxp/nxp_rt5xx_common.dtsi | 1 + dts/arm/nxp/nxp_rt6xx_common.dtsi | 1 + dts/arm/nxp/nxp_rw6xx_common.dtsi | 1 + 12 files changed, 18 insertions(+), 1 deletion(-) diff --git a/drivers/timer/Kconfig.mcux_os b/drivers/timer/Kconfig.mcux_os index 26a3ac9885f4..cb4d16ae110b 100644 --- a/drivers/timer/Kconfig.mcux_os +++ b/drivers/timer/Kconfig.mcux_os @@ -9,6 +9,7 @@ config MCUX_OS_TIMER depends on DT_HAS_NXP_OS_TIMER_ENABLED select TICKLESS_CAPABLE select TIMER_HAS_64BIT_CYCLE_COUNTER + select RESET help This module implements a kernel device driver for the NXP OS event timer and provides the standard "system clock driver" interfaces. diff --git a/drivers/timer/mcux_os_timer.c b/drivers/timer/mcux_os_timer.c index a2b761e32bab..6d4f9aa7d050 100644 --- a/drivers/timer/mcux_os_timer.c +++ b/drivers/timer/mcux_os_timer.c @@ -16,6 +16,7 @@ #include #include #include +#include #include "fsl_ostimer.h" #if !defined(CONFIG_SOC_FAMILY_MCXN) && !defined(CONFIG_SOC_FAMILY_MCXA) #include "fsl_power.h" @@ -179,9 +180,14 @@ static uint32_t mcux_lpc_ostick_compensate_system_timer(void) } slept_time_us = counter_ticks_to_us(counter_dev, slept_time_ticks); cyc_sys_compensated += CYC_PER_US * slept_time_us; + if (IS_ENABLED(CONFIG_MCUX_OS_TIMER_PM_POWERED_OFF)) { /* Reset the OS Timer to a known state */ - RESET_PeripheralReset(kOSEVENT_TIMER_RST_SHIFT_RSTn); + const struct reset_dt_spec reset = RESET_DT_SPEC_INST_GET_OR(0, {0}); + + if (reset.dev != NULL) { + reset_line_toggle_dt(&reset); + } /* Reactivate os_timer for cases where it loses its state */ OSTIMER_Init(base); } diff --git a/dts/arm/nxp/nxp_mcxa153.dtsi b/dts/arm/nxp/nxp_mcxa153.dtsi index a89df273bb29..ea4d87569d7b 100644 --- a/dts/arm/nxp/nxp_mcxa153.dtsi +++ b/dts/arm/nxp/nxp_mcxa153.dtsi @@ -339,6 +339,7 @@ compatible = "nxp,os-timer"; reg = <0x400ad000 0x1000>; interrupts = <57 0>; + resets = <&reset NXP_SYSCON_RESET(0, 25)>; status = "disabled"; }; diff --git a/dts/arm/nxp/nxp_mcxa156.dtsi b/dts/arm/nxp/nxp_mcxa156.dtsi index 00c9234d7b98..c4863ef63238 100644 --- a/dts/arm/nxp/nxp_mcxa156.dtsi +++ b/dts/arm/nxp/nxp_mcxa156.dtsi @@ -516,6 +516,7 @@ compatible = "nxp,os-timer"; reg = <0x400ad000 0x1000>; interrupts = <57 0>; + resets = <&reset NXP_SYSCON_RESET(1, 0)>; status = "disabled"; }; diff --git a/dts/arm/nxp/nxp_mcxa344.dtsi b/dts/arm/nxp/nxp_mcxa344.dtsi index c7b67d6c9846..d859daf81966 100644 --- a/dts/arm/nxp/nxp_mcxa344.dtsi +++ b/dts/arm/nxp/nxp_mcxa344.dtsi @@ -458,6 +458,7 @@ compatible = "nxp,os-timer"; reg = <0x400ad000 0x1000>; interrupts = <57 0>; + resets = <&reset NXP_SYSCON_RESET(1, 1)>; status = "disabled"; }; diff --git a/dts/arm/nxp/nxp_mcxaxx6_common.dtsi b/dts/arm/nxp/nxp_mcxaxx6_common.dtsi index b19a4d78a5da..cdf103553b91 100644 --- a/dts/arm/nxp/nxp_mcxaxx6_common.dtsi +++ b/dts/arm/nxp/nxp_mcxaxx6_common.dtsi @@ -476,6 +476,7 @@ compatible = "nxp,os-timer"; reg = <0x400ad000 0x1000>; interrupts = <57 0>; + resets = <&reset NXP_SYSCON_RESET(1, 0)>; status = "disabled"; }; diff --git a/dts/arm/nxp/nxp_mcxn23x_common.dtsi b/dts/arm/nxp/nxp_mcxn23x_common.dtsi index 179ca560e198..5045c844645b 100644 --- a/dts/arm/nxp/nxp_mcxn23x_common.dtsi +++ b/dts/arm/nxp/nxp_mcxn23x_common.dtsi @@ -661,6 +661,7 @@ compatible = "nxp,os-timer"; reg = <0x49000 0x1000>; interrupts = <57 0>; + resets = <&reset NXP_SYSCON_RESET(1, 1)>; status = "disabled"; }; diff --git a/dts/arm/nxp/nxp_mcxnx4x_common.dtsi b/dts/arm/nxp/nxp_mcxnx4x_common.dtsi index 7e3ff1dc8e93..8f97403da617 100644 --- a/dts/arm/nxp/nxp_mcxnx4x_common.dtsi +++ b/dts/arm/nxp/nxp_mcxnx4x_common.dtsi @@ -726,6 +726,7 @@ compatible = "nxp,os-timer"; reg = <0x49000 0x1000>; interrupts = <57 0>; + resets = <&reset NXP_SYSCON_RESET(1, 1)>; status = "disabled"; }; diff --git a/dts/arm/nxp/nxp_mcxw23x_common.dtsi b/dts/arm/nxp/nxp_mcxw23x_common.dtsi index 69069e29a4fa..1a32a00672a6 100644 --- a/dts/arm/nxp/nxp_mcxw23x_common.dtsi +++ b/dts/arm/nxp/nxp_mcxw23x_common.dtsi @@ -239,6 +239,7 @@ compatible = "nxp,os-timer"; reg = <0x2d000 0x1000>; interrupts = <38 1>; + resets = <&reset NXP_SYSCON_RESET(1, 1)>; status = "disabled"; }; diff --git a/dts/arm/nxp/nxp_rt5xx_common.dtsi b/dts/arm/nxp/nxp_rt5xx_common.dtsi index c7caa322cea2..f9f88c52814c 100644 --- a/dts/arm/nxp/nxp_rt5xx_common.dtsi +++ b/dts/arm/nxp/nxp_rt5xx_common.dtsi @@ -494,6 +494,7 @@ compatible = "nxp,os-timer"; reg = <0x113000 0x1000>; interrupts = <41 0>; + resets = <&rstctl1 NXP_SYSCON_RESET(0, 27)>; status = "disabled"; }; diff --git a/dts/arm/nxp/nxp_rt6xx_common.dtsi b/dts/arm/nxp/nxp_rt6xx_common.dtsi index 937cbf663c9e..6f406160debe 100644 --- a/dts/arm/nxp/nxp_rt6xx_common.dtsi +++ b/dts/arm/nxp/nxp_rt6xx_common.dtsi @@ -438,6 +438,7 @@ compatible = "nxp,os-timer"; reg = <0x113000 0x1000>; interrupts = <41 0>; + resets = <&rstctl1 NXP_SYSCON_RESET(0, 27)>; status = "disabled"; }; diff --git a/dts/arm/nxp/nxp_rw6xx_common.dtsi b/dts/arm/nxp/nxp_rw6xx_common.dtsi index 3ed349059721..50f766ef3e15 100644 --- a/dts/arm/nxp/nxp_rw6xx_common.dtsi +++ b/dts/arm/nxp/nxp_rw6xx_common.dtsi @@ -617,6 +617,7 @@ compatible = "nxp,os-timer"; reg = <0x13b000 0x1000>; interrupts = <41 0>; + resets = <&rstctl1 NXP_SYSCON_RESET(0, 27)>; status = "disabled"; }; From 184e0311633066250547ef556597c0b490c7e52b Mon Sep 17 00:00:00 2001 From: Jason Yu Date: Mon, 3 Nov 2025 14:44:18 +0800 Subject: [PATCH 0363/3659] drivers: timer: ostimer: Fix run fail when no deep_sleep_counter Only access deep_sleep_counter when it is available. Signed-off-by: Jason Yu --- drivers/timer/mcux_os_timer.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/timer/mcux_os_timer.c b/drivers/timer/mcux_os_timer.c index 6d4f9aa7d050..2c18d8286e63 100644 --- a/drivers/timer/mcux_os_timer.c +++ b/drivers/timer/mcux_os_timer.c @@ -343,7 +343,9 @@ static int sys_clock_driver_init(void) /* On some SoC's, OS Timer cannot wakeup from low power mode in standby modes */ #if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(standby)) && CONFIG_PM counter_dev = DEVICE_DT_GET_OR_NULL(DT_INST_PHANDLE(0, deep_sleep_counter)); - counter_max_val = counter_get_max_top_value(counter_dev); + if (NULL != counter_dev) { + counter_max_val = counter_get_max_top_value(counter_dev); + } #endif #if (DT_INST_PROP(0, wakeup_source)) From 4f152eeb372aa52316d1f4834ede0d4a8f91d7e7 Mon Sep 17 00:00:00 2001 From: William Tang Date: Fri, 21 Nov 2025 18:27:48 +0800 Subject: [PATCH 0364/3659] drivers: can: mcux: flexcan: fix prop_seg for enhanced bit timing Move the no propagation segment configuration and prop_seg must be 0 logic from the general timing configuration to only apply within the CAN FD specific sections. This ensures that for classic CAN mode or platfrom without enhanced bit timing, prop_seg is always decremented by 1. The previous implementation incorrectly applied the enhanced bit timing logic to classic CAN mode, which could cause timing misconfiguration on devices with enhanced bit timing register support when operating in classic CAN mode. Fixes #99746 Signed-off-by: William Tang --- drivers/can/can_mcux_flexcan.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/drivers/can/can_mcux_flexcan.c b/drivers/can/can_mcux_flexcan.c index 57ab127bbd9c..f688b2ef1a77 100644 --- a/drivers/can/can_mcux_flexcan.c +++ b/drivers/can/can_mcux_flexcan.c @@ -311,8 +311,13 @@ static int mcux_flexcan_start(const struct device *dev) timing.phaseSeg2 = data->timing.phase_seg2 - 1U; #if (defined(FSL_FEATURE_FLEXCAN_HAS_ENHANCED_BIT_TIMING_REG) && \ FSL_FEATURE_FLEXCAN_HAS_ENHANCED_BIT_TIMING_REG) - /* No propagation segment configuration, so prop_seg must be 0 */ - timing.propSeg = data->timing.prop_seg; + if (UTIL_AND(IS_ENABLED(CONFIG_CAN_MCUX_FLEXCAN_FD), config->flexcan_fd)) { + /* No propagation segment configuration, so prop_seg must be 0 */ + timing.propSeg = data->timing.prop_seg; + } else { + /* Use standard configuration for classic CAN mode */ + timing.propSeg = data->timing.prop_seg - 1U; + } #else timing.propSeg = data->timing.prop_seg - 1U; #endif @@ -1262,13 +1267,7 @@ static int mcux_flexcan_init(const struct device *dev) flexcan_config.enableListenOnlyMode = true; flexcan_config.timingConfig.rJumpwidth = data->timing.sjw - 1U; -#if (defined(FSL_FEATURE_FLEXCAN_HAS_ENHANCED_BIT_TIMING_REG) && \ - FSL_FEATURE_FLEXCAN_HAS_ENHANCED_BIT_TIMING_REG) - /* No propagation segment configuration, so prop_seg must be 0 */ - flexcan_config.timingConfig.propSeg = data->timing.prop_seg; -#else flexcan_config.timingConfig.propSeg = data->timing.prop_seg - 1U; -#endif flexcan_config.timingConfig.phaseSeg1 = data->timing.phase_seg1 - 1U; flexcan_config.timingConfig.phaseSeg2 = data->timing.phase_seg2 - 1U; @@ -1276,6 +1275,11 @@ static int mcux_flexcan_init(const struct device *dev) #ifdef CONFIG_CAN_MCUX_FLEXCAN_FD if (config->flexcan_fd) { +#if (defined(FSL_FEATURE_FLEXCAN_HAS_ENHANCED_BIT_TIMING_REG) && \ + FSL_FEATURE_FLEXCAN_HAS_ENHANCED_BIT_TIMING_REG) + /* No propagation segment configuration, so prop_seg must be 0 */ + flexcan_config.timingConfig.propSeg = data->timing.prop_seg; +#endif flexcan_config.timingConfig.frJumpwidth = data->timing_data.sjw - 1U; flexcan_config.timingConfig.fpropSeg = data->timing_data.prop_seg; flexcan_config.timingConfig.fphaseSeg1 = data->timing_data.phase_seg1 - 1U; From 287ca5b9ebe78a2ae1fdd05f9331dfe799df355e Mon Sep 17 00:00:00 2001 From: Josia Strack Date: Fri, 10 Oct 2025 15:29:12 +0200 Subject: [PATCH 0365/3659] drivers: gpio: pcf857x: ensure input pins default high for open-drain Ensure that pins configured as inputs are driven high in the port output register, consistent with open-drain operation. This prevents inputs from being driven low unintentionally and aligns behavior with hardware expectations. Signed-off-by: Josia Strack --- drivers/gpio/gpio_pcf857x.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/gpio/gpio_pcf857x.c b/drivers/gpio/gpio_pcf857x.c index b14e54cbd9a7..1103cfef0c1d 100644 --- a/drivers/gpio/gpio_pcf857x.c +++ b/drivers/gpio/gpio_pcf857x.c @@ -135,11 +135,6 @@ static int pcf857x_port_get_raw(const struct device *dev, gpio_port_value_t *val return -EWOULDBLOCK; } - if ((~drv_data->pins_cfg.configured_as_outputs & (uint16_t)*value) != (uint16_t)*value) { - LOG_ERR("Pin(s) is/are configured as output which should be input."); - return -EOPNOTSUPP; - } - k_sem_take(&drv_data->lock, K_FOREVER); /** @@ -185,6 +180,7 @@ static int pcf857x_port_set_raw(const struct device *dev, uint16_t mask, uint16_ tx_buf = (drv_data->pins_cfg.outputs_state & ~mask); tx_buf |= (value & mask); tx_buf ^= toggle; + tx_buf |= ~drv_data->pins_cfg.configured_as_outputs; sys_put_le16(tx_buf, tx_buf_p); rc = i2c_write_dt(&drv_cfg->i2c, tx_buf_p, drv_data->num_bytes); @@ -223,7 +219,7 @@ static int pcf857x_pin_configure(const struct device *dev, gpio_pin_t pin, gpio_ } if (flags & GPIO_INPUT) { temp_outputs &= ~BIT(pin); - temp_pins &= ~(1 << pin); + temp_pins |= (1 << pin); } else if (flags & GPIO_OUTPUT) { drv_data->pins_cfg.configured_as_outputs |= BIT(pin); temp_outputs = drv_data->pins_cfg.configured_as_outputs; From 11d3fc4143607a8667500d82d7becfa70cf89ae6 Mon Sep 17 00:00:00 2001 From: TOKITA Hiroshi Date: Sat, 20 Sep 2025 07:27:49 +0900 Subject: [PATCH 0366/3659] drivers: display: display_sdl: Reimplementing tile rendering The current implementation has a bug in the calculation of tile offsets, causing them to be calculated incorrectly. This is particularly evident when there are fractional rows or columns. Also, there was an assertion that assumed vtiled. The logic has become too complicated, so we'll reimplement to simplify this. Signed-off-by: TOKITA Hiroshi --- drivers/display/display_sdl.c | 103 ++++++++++++---------------------- 1 file changed, 36 insertions(+), 67 deletions(-) diff --git a/drivers/display/display_sdl.c b/drivers/display/display_sdl.c index 0b5af2e77462..08a769ef8e48 100644 --- a/drivers/display/display_sdl.c +++ b/drivers/display/display_sdl.c @@ -320,64 +320,31 @@ static void sdl_display_write_bgr565(uint8_t *disp_buf, } } -static void sdl_display_write_mono(uint8_t *disp_buf, - const struct display_buffer_descriptor *desc, const void *buf, - const bool one_is_black) +static void sdl_display_write_mono(uint8_t *disp_buf, const struct display_buffer_descriptor *desc, + const void *buf, const bool one_is_black) { + const uint32_t pixel_on = one_is_black ? 0U : 0x00FFFFFF; uint32_t w_idx; uint32_t h_idx; - uint32_t tile_idx; - uint32_t pixel; + bool pixel; const uint8_t *byte_ptr; - uint32_t one_color; - uint8_t *disp_buf_start; - - __ASSERT((desc->pitch * desc->height) <= (desc->buf_size * 8U), - "Input buffer too small"); - __ASSERT((desc->height % 8) == 0U, - "Input buffer height not aligned per 8 pixels"); - if (one_is_black) { - one_color = 0U; - } else { - one_color = 0x00FFFFFF; - } + __ASSERT((desc->pitch * desc->height) <= (desc->buf_size * 8U), "Input buffer too small"); - if (IS_ENABLED(CONFIG_SDL_DISPLAY_MONO_VTILED)) { - for (tile_idx = 0U; tile_idx < desc->height / 8U; ++tile_idx) { - for (w_idx = 0U; w_idx < desc->width; ++w_idx) { - byte_ptr = - (const uint8_t *)buf + ((tile_idx * desc->pitch) + w_idx); - disp_buf_start = disp_buf; - for (h_idx = 0U; h_idx < 8; ++h_idx) { - if ((*byte_ptr & mono_pixel_order(h_idx)) != 0U) { - pixel = one_color; - } else { - pixel = ~one_color; - } - *((uint32_t *)disp_buf) = pixel | 0xFF000000; - disp_buf += (desc->width * 4U); - } - disp_buf = disp_buf_start; - disp_buf += 4; - } - disp_buf += 7 * (desc->width * 4U); - } - } else { - for (h_idx = 0; h_idx < desc->height; h_idx++) { - for (tile_idx = 0; tile_idx < desc->width / 8; tile_idx++) { - byte_ptr = (const uint8_t *)buf + - ((h_idx * desc->width / 8) + tile_idx); - for (w_idx = 0; w_idx < 8; w_idx++) { - if ((*byte_ptr & mono_pixel_order(w_idx)) != 0U) { - pixel = one_color; - } else { - pixel = ~one_color; - } - *((uint32_t *)disp_buf + w_idx) = pixel | 0xFF000000; - } - disp_buf += 8 * sizeof(uint32_t); + for (h_idx = 0U; h_idx < desc->height; ++h_idx) { + for (w_idx = 0U; w_idx < desc->width; ++w_idx) { + byte_ptr = buf; + + if (IS_ENABLED(CONFIG_SDL_DISPLAY_MONO_VTILED)) { + byte_ptr += ((h_idx / 8U) * DIV_ROUND_UP(desc->pitch, 1U)) + w_idx; + pixel = !!(*byte_ptr & mono_pixel_order(h_idx % 8U)); + } else { + byte_ptr += (h_idx * DIV_ROUND_UP(desc->pitch, 8U)) + (w_idx / 8U); + pixel = !!(*byte_ptr & mono_pixel_order(w_idx % 8U)); } + + *((uint32_t *)disp_buf) = (pixel ? pixel_on : ~pixel_on) | 0xFF000000; + disp_buf += 4; } } } @@ -555,31 +522,33 @@ static void sdl_display_read_mono(const uint8_t *read_buf, const struct display_buffer_descriptor *desc, void *buf, const bool one_is_black) { + const uint32_t pixel_on = one_is_black ? 0xFF000000 : 0xFFFFFFFF; uint32_t w_idx; uint32_t h_idx; - uint32_t tile_idx; - uint8_t tile; + uint8_t bits; const uint32_t *pix_ptr; uint8_t *buf8; __ASSERT((desc->pitch * desc->height) <= (desc->buf_size * 8U), "Read buffer is too small"); - __ASSERT((desc->height % 8U) == 0U, "Read buffer height not aligned per 8 pixels"); - - for (tile_idx = 0U; tile_idx < (desc->height / 8U); ++tile_idx) { - buf8 = (void *)(((uint8_t *)buf) + desc->pitch * tile_idx); + for (h_idx = 0U; h_idx < desc->height; ++h_idx) { for (w_idx = 0U; w_idx < desc->width; ++w_idx) { - tile = 0; - - for (h_idx = 0U; h_idx < 8; ++h_idx) { - pix_ptr = (const uint32_t *)read_buf + - ((tile_idx * 8 + h_idx) * desc->pitch + w_idx); - if ((*pix_ptr)) { - tile |= mono_pixel_order(h_idx); - } + pix_ptr = (const uint32_t *)read_buf + h_idx * desc->pitch + w_idx; + buf8 = buf; + + if (IS_ENABLED(CONFIG_SDL_DISPLAY_MONO_VTILED)) { + buf8 += (h_idx / 8U) * DIV_ROUND_UP(desc->pitch, 1U) + (w_idx); + bits = mono_pixel_order(h_idx % 8U); + } else { + buf8 += (h_idx)*DIV_ROUND_UP(desc->pitch, 8U) + (w_idx / 8U); + bits = mono_pixel_order(w_idx % 8U); + } + + if (*pix_ptr == pixel_on) { + *buf8 |= bits; + } else { + *buf8 &= ~bits; } - *buf8 = one_is_black ? ~tile : tile; - buf8 += 1; } } } From c7cac1373f097c867f852f84509ae1128585f609 Mon Sep 17 00:00:00 2001 From: TOKITA Hiroshi Date: Sat, 20 Sep 2025 01:44:39 +0900 Subject: [PATCH 0367/3659] tests: drivers: display: read_write: Fix tile eendering test The buffer size calculation was not rounded up to what it needed. We fixed it. Signed-off-by: TOKITA Hiroshi --- .../display/display_read_write/src/main.c | 52 +++++++++---------- 1 file changed, 25 insertions(+), 27 deletions(-) diff --git a/tests/drivers/display/display_read_write/src/main.c b/tests/drivers/display/display_read_write/src/main.c index 16e1ba1688ac..6ae88b1fb97b 100644 --- a/tests/drivers/display/display_read_write/src/main.c +++ b/tests/drivers/display/display_read_write/src/main.c @@ -8,6 +8,7 @@ #include #include #include +#include LOG_MODULE_DECLARE(display_api, CONFIG_DISPLAY_LOG_LEVEL); @@ -25,6 +26,15 @@ static uint8_t bpp; static bool is_vtiled; static bool is_htiled; +static inline size_t buffer_size(size_t width, size_t height) +{ + if (is_vtiled || is_htiled) { + return DIV_ROUND_UP(width * height, 8U); + } + + return width * height * bpp; +} + static inline uint8_t bytes_per_pixel(enum display_pixel_format pixel_format) { switch (pixel_format) { @@ -52,23 +62,19 @@ static void verify_bytes_of_area(uint8_t *data, int cmp_x, int cmp_y, size_t wid .height = height, .pitch = width, .width = width, - .buf_size = height * width * bpp, + .buf_size = buffer_size(width, height), }; int err = display_read(dev, cmp_x, cmp_y, &desc, disp_buffer); zassert_ok(err, "display_read failed"); - if (is_vtiled || is_htiled) { - zassert_mem_equal(data, disp_buffer, width * height / 8); - } else { - zassert_mem_equal(data, disp_buffer, width * height * bpp); - } + zassert_mem_equal(data, disp_buffer, buffer_size(width, height)); } static void verify_background_color(int x, int y, size_t width, size_t height, uint32_t color) { - size_t buf_size = height * width * bpp / ((is_vtiled || is_htiled) ? 8 : 1); + size_t buf_size = buffer_size(width, height); struct display_buffer_descriptor desc = { .height = height, .pitch = width, @@ -191,7 +197,7 @@ ZTEST(display_read_write, test_write_to_buffer_tail) .height = display_height, .pitch = display_width, .width = display_width, - .buf_size = display_height * display_width * bpp / height, + .buf_size = buffer_size(display_width, display_height), }; int err; @@ -203,15 +209,11 @@ ZTEST(display_read_write, test_write_to_buffer_tail) zassert_ok(err, "display_read failed"); /* check write data and read data are same */ - if (is_vtiled || is_htiled) { - zassert_mem_equal(data, - disp_buffer + (display_width * display_height / 8 - buf_size), - buf_size); - } else { - zassert_mem_equal(data, - disp_buffer + (display_width * display_height * bpp - buf_size), - buf_size); - } + size_t total_bytes = buffer_size(display_width, display_height); + size_t area_bytes = buffer_size(width, height); + uint8_t *compare = disp_buffer + (total_bytes - area_bytes); + + zassert_mem_equal(data, compare, area_bytes); /* check remaining region still black */ verify_background_color(0, 0, display_width, display_height - height, 0); @@ -237,7 +239,7 @@ ZTEST(display_read_write, test_read_does_not_clear_existing_buffer) .height = display_height, .pitch = display_width, .width = display_width, - .buf_size = display_height * display_width * bpp / height, + .buf_size = buffer_size(display_width, display_height), }; int err; @@ -259,15 +261,11 @@ ZTEST(display_read_write, test_read_does_not_clear_existing_buffer) zassert_ok(err, "display_read failed"); /* checking correctly write to the tail of buffer */ - if (is_vtiled || is_htiled) { - zassert_mem_equal(data, - disp_buffer + (display_width * display_height / 8 - buf_size), - buf_size); - } else { - zassert_mem_equal(data, - disp_buffer + (display_width * display_height * bpp - buf_size), - buf_size); - } + size_t total_bytes = buffer_size(display_width, display_height); + size_t area_bytes = buffer_size(width, height); + uint8_t *compare = disp_buffer + (total_bytes - area_bytes); + + zassert_mem_equal(data, compare, area_bytes); /* checking if the content written before reading is kept */ verify_bytes_of_area(data, 0, 0, width, height); From 8cad3fd3826f790ba5b613676c3e48a44555425a Mon Sep 17 00:00:00 2001 From: CHEN Xing Date: Mon, 4 Aug 2025 18:14:32 +0800 Subject: [PATCH 0368/3659] dts: arm: microchip: sam: add pit64b device to sama7g5 Add pit64b1 ~ pit64b5 counter devices to sama7g5 Signed-off-by: CHEN Xing --- .../microchip/sam/sama7/sama7g5/sama7g5.dtsi | 50 +++++++++++++++++++ .../counter/microchip,sam-pit64b-counter.yaml | 44 ++++++++++++++++ 2 files changed, 94 insertions(+) create mode 100644 dts/bindings/counter/microchip,sam-pit64b-counter.yaml diff --git a/dts/arm/microchip/sam/sama7/sama7g5/sama7g5.dtsi b/dts/arm/microchip/sam/sama7/sama7g5/sama7g5.dtsi index b4411f8c58a6..f4636a70095f 100644 --- a/dts/arm/microchip/sam/sama7/sama7g5/sama7g5.dtsi +++ b/dts/arm/microchip/sam/sama7/sama7g5/sama7g5.dtsi @@ -264,6 +264,26 @@ interrupts = ; }; + pit64b1: timer@e1804000 { + compatible = "microchip,sam-pit64b-counter"; + reg = <0xe1804000 0x4000>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 71>, <&pmc PMC_TYPE_GCK 71>; + clock-names = "pclk", "gclk"; + interrupt-parent = <&gic>; + interrupts = ; + status = "disabled"; + }; + + pit64b2: timer@e1808000 { + compatible = "microchip,sam-pit64b-counter"; + reg = <0xe1808000 0x4000>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 72>, <&pmc PMC_TYPE_GCK 72>; + clock-names = "pclk", "gclk"; + interrupt-parent = <&gic>; + interrupts = ; + status = "disabled"; + }; + sha: sha@e1814000 { compatible = "microchip,sha-g1-crypto"; reg = <0xe1814000 0x100>; @@ -391,6 +411,26 @@ }; }; + pit64b3: timer@e2004000 { + compatible = "microchip,sam-pit64b-counter"; + reg = <0xe2004000 0x4000>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 73>, <&pmc PMC_TYPE_GCK 73>; + clock-names = "pclk", "gclk"; + interrupt-parent = <&gic>; + interrupts = ; + status = "disabled"; + }; + + pit64b4: timer@e2008000 { + compatible = "microchip,sam-pit64b-counter"; + reg = <0xe2008000 0x4000>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 74>, <&pmc PMC_TYPE_GCK 74>; + clock-names = "pclk", "gclk"; + interrupt-parent = <&gic>; + interrupts = ; + status = "disabled"; + }; + trng: rng@e2010000 { compatible = "atmel,sam-trng"; reg = <0xe2010000 0x100>; @@ -592,6 +632,16 @@ status = "disabled"; }; + pit64b5: timer@e2810000 { + compatible = "microchip,sam-pit64b-counter"; + reg = <0xe2810000 0x4000>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 75>, <&pmc PMC_TYPE_GCK 75>; + clock-names = "pclk", "gclk"; + interrupt-parent = <&gic>; + interrupts = ; + status = "disabled"; + }; + flx8: flexcom@e2818000 { compatible = "microchip,sam-flexcom"; reg = <0xe2818000 0x200>; diff --git a/dts/bindings/counter/microchip,sam-pit64b-counter.yaml b/dts/bindings/counter/microchip,sam-pit64b-counter.yaml new file mode 100644 index 000000000000..ffd97e01fac0 --- /dev/null +++ b/dts/bindings/counter/microchip,sam-pit64b-counter.yaml @@ -0,0 +1,44 @@ +# Copyright (C) 2025 Microchip Technology Inc. and its subsidiaries +# +# SPDX-License-Identifier: Apache-2.0 +# + +description: Microchip SAM PIT64B Counter + +compatible: "microchip,sam-pit64b-counter" + +include: + - name: base.yaml + - name: pinctrl-device.yaml + +properties: + reg: + required: true + + interrupts: + required: true + + clocks: + required: true + + clock-selection: + type: string + default: "SGCLK_PERIPHERAL_CLOCK" + description: | + Refer to PIT64B_MR.SGCLK in datasheet. + Peripheral clock (MCK1) is used by default. + enum: + - "SGCLK_PERIPHERAL_CLOCK" + - "SGCLK_GENERIC_CLOCK" + + prescaler-period: + type: int + default: 0 + description: | + Refer to PIT64B_MR.PRESCALER[3:0] in datasheet. + enum: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] + + top-alarm: + type: boolean + description: | + Reuse the top value channel as an alarm channel. From 14b2a1dfa206230f0561274120775340dab5e593 Mon Sep 17 00:00:00 2001 From: CHEN Xing Date: Mon, 4 Aug 2025 18:17:39 +0800 Subject: [PATCH 0369/3659] drivers: counter: add support for sama7g54 PIT64B Add driver for sama7g54 PIT64B Use PIT64B as a zephyr counter device Signed-off-by: CHEN Xing --- drivers/counter/CMakeLists.txt | 1 + drivers/counter/Kconfig | 1 + drivers/counter/Kconfig.mchp_sam_pit64b | 11 + drivers/counter/counter_mchp_sam_pit64b.c | 439 ++++++++++++++++++++++ 4 files changed, 452 insertions(+) create mode 100644 drivers/counter/Kconfig.mchp_sam_pit64b create mode 100644 drivers/counter/counter_mchp_sam_pit64b.c diff --git a/drivers/counter/CMakeLists.txt b/drivers/counter/CMakeLists.txt index a63fdf585f07..99786dade581 100644 --- a/drivers/counter/CMakeLists.txt +++ b/drivers/counter/CMakeLists.txt @@ -28,6 +28,7 @@ zephyr_library_sources_ifdef(CONFIG_COUNTER_INFINEON_TCPWM counter_infineon_tcpw zephyr_library_sources_ifdef(CONFIG_COUNTER_ITE_IT51XXX counter_ite_it51xxx.c) zephyr_library_sources_ifdef(CONFIG_COUNTER_ITE_IT8XXX2 counter_ite_it8xxx2.c) zephyr_library_sources_ifdef(CONFIG_COUNTER_MAXIM_DS3231 maxim_ds3231.c) +zephyr_library_sources_ifdef(CONFIG_COUNTER_MCHP_SAM_PIT64B counter_mchp_sam_pit64b.c) zephyr_library_sources_ifdef(CONFIG_COUNTER_MCUX_CTIMER counter_mcux_ctimer.c) zephyr_library_sources_ifdef(CONFIG_COUNTER_MCUX_FTM counter_mcux_ftm.c) zephyr_library_sources_ifdef(CONFIG_COUNTER_MCUX_GPT counter_mcux_gpt.c) diff --git a/drivers/counter/Kconfig b/drivers/counter/Kconfig index 6fab1ac6ecd5..03dcc5b9d3ae 100644 --- a/drivers/counter/Kconfig +++ b/drivers/counter/Kconfig @@ -48,6 +48,7 @@ source "drivers/counter/Kconfig.max32_rtc" source "drivers/counter/Kconfig.max32_timer" source "drivers/counter/Kconfig.max32_wut" source "drivers/counter/Kconfig.maxim_ds3231" +source "drivers/counter/Kconfig.mchp_sam_pit64b" source "drivers/counter/Kconfig.mcp7940n" source "drivers/counter/Kconfig.mcux_ctimer" source "drivers/counter/Kconfig.mcux_ftm" diff --git a/drivers/counter/Kconfig.mchp_sam_pit64b b/drivers/counter/Kconfig.mchp_sam_pit64b new file mode 100644 index 000000000000..2796bc1a8bdd --- /dev/null +++ b/drivers/counter/Kconfig.mchp_sam_pit64b @@ -0,0 +1,11 @@ +# Copyright (C) 2025 Microchip Technology Inc. and its subsidiaries +# +# SPDX-License-Identifier: Apache-2.0 +# + +config COUNTER_MCHP_SAM_PIT64B + bool "Microchip SAM PIT64B Counter" + default y + depends on DT_HAS_MICROCHIP_SAM_PIT64B_COUNTER_ENABLED + help + Enable the Microchip PIT64B counter driver. diff --git a/drivers/counter/counter_mchp_sam_pit64b.c b/drivers/counter/counter_mchp_sam_pit64b.c new file mode 100644 index 000000000000..a1f821c48cb1 --- /dev/null +++ b/drivers/counter/counter_mchp_sam_pit64b.c @@ -0,0 +1,439 @@ +/* + * Copyright (C) 2025 Microchip Technology Inc. and its subsidiaries + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT microchip_sam_pit64b_counter + +#include +#include +#include +#include + +#include +LOG_MODULE_REGISTER(counter_mchp_sam, CONFIG_COUNTER_LOG_LEVEL); + +#define PERIOD_MAX UINT64_MAX + +struct sam_pit_config { + struct counter_config_info info; + pit64b_registers_t *regs; + const struct atmel_sam_pmc_config clock_cfg; + const struct atmel_sam_pmc_config gclk_cfg; + uint8_t clock_selection; + uint8_t prescaler_period; + uint8_t top_alarm; + void (*irq_config_func)(const struct device *dev); +}; + +struct sam_pit_alarm_data { + counter_alarm_callback_t callback; + void *user_data; +}; + +struct sam_pit_data { + counter_top_callback_t top_cb; + void *top_user_data; + struct k_spinlock lock; + + struct sam_pit_alarm_data alarm; +}; + +static inline void pit_configure(pit64b_registers_t *regs, uint32_t mode) +{ + regs->PIT64B_MR = mode; +} + +static inline void pit_start(pit64b_registers_t *regs) +{ + regs->PIT64B_CR = PIT64B_CR_START_1; +} + +static inline void pit_stop(pit64b_registers_t *regs) +{ + regs->PIT64B_CR = PIT64B_CR_SWRST_1; +} + +static inline uint32_t pit_irq_status(pit64b_registers_t *regs) +{ + return regs->PIT64B_ISR; +} + +static inline void pit_irq_enable(pit64b_registers_t *regs, uint32_t mask) +{ + regs->PIT64B_IER = mask & PIT64B_IER_Msk; +} + +static inline void pit_irq_disable(pit64b_registers_t *regs, uint32_t mask) +{ + regs->PIT64B_IDR = mask & PIT64B_IDR_Msk; +} + +static inline void pit_irq_disable_all(pit64b_registers_t *regs) +{ + regs->PIT64B_IDR = PIT64B_IDR_Msk; +} + +static inline uint32_t pit_irq_mask(pit64b_registers_t *regs) +{ + return regs->PIT64B_IMR; +} + +static inline uint64_t pit_counter_value(pit64b_registers_t *regs) +{ + uint64_t ret; + + ret = regs->PIT64B_TLSBR; + ret |= (uint64_t)regs->PIT64B_TMSBR << 32; + + return ret; +} + +static inline uint64_t pit_period_get_value(pit64b_registers_t *regs) +{ + return (uint64_t)regs->PIT64B_MSBPR << 32 | regs->PIT64B_LSBPR; +} + +static inline void pit_period_set_value(pit64b_registers_t *regs, uint64_t value) +{ + regs->PIT64B_MSBPR = (uint32_t)(value >> 32); + regs->PIT64B_LSBPR = (uint32_t)value; +} + +static int sam_pit_start(const struct device *dev) +{ + const struct sam_pit_config *config = dev->config; + + pit_start(config->regs); + + return 0; +} + +static int sam_pit_stop(const struct device *dev) +{ + const struct sam_pit_config *config = dev->config; + + pit_stop(config->regs); + + return 0; +} + +static int sam_pit_get_value(const struct device *dev, uint32_t *ticks) +{ + const struct sam_pit_config *config = dev->config; + struct sam_pit_data *data = dev->data; + k_spinlock_key_t key; + + key = k_spin_lock(&data->lock); + + *ticks = (uint32_t)pit_counter_value(config->regs); + + k_spin_unlock(&data->lock, key); + + return 0; +} + +static int sam_pit_get_value_64(const struct device *dev, uint64_t *ticks) +{ + const struct sam_pit_config *config = dev->config; + struct sam_pit_data *data = dev->data; + k_spinlock_key_t key; + + key = k_spin_lock(&data->lock); + + *ticks = pit_counter_value(config->regs); + + k_spin_unlock(&data->lock, key); + + return 0; +} + +static int sam_pit_set_alarm(const struct device *dev, uint8_t chan_id, + const struct counter_alarm_cfg *alarm_cfg) +{ + const struct sam_pit_config *config = dev->config; + const struct counter_config_info *info = &config->info; + struct sam_pit_data *data = dev->data; + k_spinlock_key_t key; + uint64_t top_value; + + if (chan_id >= info->channels) { + return -ENOTSUP; + } + + __ASSERT_NO_MSG(alarm_cfg->callback); + + /* PIT64B only support absolute value */ + if (!(alarm_cfg->flags & COUNTER_ALARM_CFG_ABSOLUTE)) { + return -EINVAL; + } + + key = k_spin_lock(&data->lock); + + if (data->alarm.callback) { + k_spin_unlock(&data->lock, key); + return -EBUSY; + } + + /* Top-alarm is enabled, Check if the top value is running */ + top_value = pit_period_get_value(config->regs); + if ((top_value) && (top_value != PERIOD_MAX)) { + /* Top value is running, cannot be reused for alarm */ + k_spin_unlock(&data->lock, key); + return -EBUSY; + } + + data->alarm.callback = alarm_cfg->callback; + data->alarm.user_data = alarm_cfg->user_data; + + pit_period_set_value(config->regs, alarm_cfg->ticks); + pit_irq_status(config->regs); + pit_irq_enable(config->regs, PIT64B_IER_OVRE_Msk | PIT64B_IER_PERIOD_Msk); + + k_spin_unlock(&data->lock, key); + + return 0; +} + +static int sam_pit_cancel_alarm(const struct device *dev, uint8_t chan_id) +{ + const struct sam_pit_config *config = dev->config; + const struct counter_config_info *info = &config->info; + struct sam_pit_data *data = dev->data; + k_spinlock_key_t key; + + if (chan_id >= info->channels) { + return -EINVAL; + } + + key = k_spin_lock(&data->lock); + + pit_irq_disable(config->regs, PIT64B_IDR_OVRE_Msk | PIT64B_IDR_PERIOD_Msk); + pit_period_set_value(config->regs, PERIOD_MAX); + + data->alarm.callback = NULL; + data->alarm.user_data = NULL; + + k_spin_unlock(&data->lock, key); + + return 0; +} + +static int sam_pit_set_top_value(const struct device *dev, + const struct counter_top_cfg *top_cfg) +{ + const struct sam_pit_config *config = dev->config; + struct sam_pit_data *data = dev->data; + k_spinlock_key_t key; + int ret = 0; + + if (!top_cfg->ticks) { + return -EINVAL; + } + + key = k_spin_lock(&data->lock); + + if ((config->top_alarm) && (data->alarm.callback)) { + /* Alarm is running, cannot be reused for top value */ + k_spin_unlock(&data->lock, key); + return -EBUSY; + } + + pit_irq_disable(config->regs, PIT64B_IDR_OVRE_Msk | PIT64B_IDR_PERIOD_Msk); + + if (top_cfg->callback) { + data->top_cb = top_cfg->callback; + data->top_user_data = top_cfg->user_data; + } + + /* PIT64B will reset the counter automatically */ + if ((top_cfg->flags & COUNTER_TOP_CFG_DONT_RESET) != 0) { + ret = -ENOTSUP; + } + + pit_period_set_value(config->regs, top_cfg->ticks); + pit_irq_status(config->regs); + pit_irq_enable(config->regs, PIT64B_IER_OVRE_Msk | PIT64B_IER_PERIOD_Msk); + + k_spin_unlock(&data->lock, key); + + return ret; +} + +static uint32_t sam_pit_get_top_value(const struct device *dev) +{ + const struct sam_pit_config *config = dev->config; + struct sam_pit_data *data = dev->data; + k_spinlock_key_t key; + uint64_t ret; + + key = k_spin_lock(&data->lock); + + if ((config->top_alarm) && (data->alarm.callback)) { + /* Alarm is running, top value is stopped */ + k_spin_unlock(&data->lock, key); + return 0; + } + + ret = pit_period_get_value(config->regs); + if (ret == PERIOD_MAX) { + ret = 0; + } + + k_spin_unlock(&data->lock, key); + + return (uint32_t)ret; +} + +static uint32_t sam_pit_get_pending_int(const struct device *dev) +{ + const struct sam_pit_config *config = dev->config; + + return pit_irq_status(config->regs) & pit_irq_mask(config->regs); +} + +static uint32_t sam_pit_get_freq(const struct device *dev) +{ + const struct sam_pit_config *config = dev->config; + uint32_t rate = 0; + + if (config->clock_selection == 0) { + clock_control_get_rate(SAM_DT_PMC_CONTROLLER, + (clock_control_subsys_t)&config->clock_cfg, + &rate); + } else if (config->clock_selection == 1) { + clock_control_get_rate(SAM_DT_PMC_CONTROLLER, + (clock_control_subsys_t)&config->gclk_cfg, + &rate); + } else { + return 0; + } + + if (rate) { + rate /= (config->prescaler_period + 1); + } + + return rate; +} + +static void sam_pit_isr(const struct device *dev) +{ + const struct sam_pit_config *config = dev->config; + struct sam_pit_data *data = dev->data; + k_spinlock_key_t key; + uint32_t status; + + status = pit_irq_status(config->regs); + + key = k_spin_lock(&data->lock); + + if (status & PIT64B_ISR_OVRE_Msk) { + LOG_ERR("%s: More than 1 rollover occurred since the last read\n\r", + dev->name); + } + + if (status & PIT64B_ISR_PERIOD_Msk) { + if (data->alarm.callback) { + counter_alarm_callback_t cb = data->alarm.callback; + void *user_data = data->alarm.user_data; + uint32_t ticks = (uint32_t)pit_counter_value(config->regs); + + pit_irq_disable(config->regs, PIT64B_IDR_OVRE_Msk | PIT64B_IDR_PERIOD_Msk); + pit_period_set_value(config->regs, PERIOD_MAX); + data->alarm.callback = NULL; + data->alarm.user_data = NULL; + + cb(dev, 0, ticks, user_data); + } else { + if (data->top_cb) { + data->top_cb(dev, data->top_user_data); + } + } + } + + k_spin_unlock(&data->lock, key); +} + +static int sam_pit_init(const struct device *dev) +{ + const struct sam_pit_config *config = dev->config; + + /* Enable channel's clock */ + (void)clock_control_on(SAM_DT_PMC_CONTROLLER, (clock_control_subsys_t)&config->clock_cfg); + + /* Configure PIT64B */ + pit_stop(config->regs); + pit_irq_disable_all(config->regs); + pit_irq_status(config->regs); + pit_period_set_value(config->regs, PERIOD_MAX); + pit_configure(config->regs, PIT64B_MR_PRESCALER(config->prescaler_period) | + PIT64B_MR_SMOD_1 | + PIT64B_MR_SGCLK(config->clock_selection) | + PIT64B_MR_CONT_1); + + config->irq_config_func(dev); + + LOG_INF("Device %s initialized, reg:0x%08x cs:%d pc:%d channels:%u top_alarm:%u", + dev->name, + (unsigned int)config->regs, + (unsigned int)config->clock_selection, + (unsigned int)config->prescaler_period, + (unsigned int)config->info.channels, + (unsigned int)config->top_alarm); + + return 0; +} + +static DEVICE_API(counter, sam_pit_driver_api) = { + .start = sam_pit_start, + .stop = sam_pit_stop, + .get_value = sam_pit_get_value, + .get_value_64 = sam_pit_get_value_64, + .set_alarm = sam_pit_set_alarm, + .cancel_alarm = sam_pit_cancel_alarm, + .set_top_value = sam_pit_set_top_value, + .get_top_value = sam_pit_get_top_value, + .get_pending_int = sam_pit_get_pending_int, + .get_freq = sam_pit_get_freq, +}; + +#define SAM_PIT_ALARM_CHANNELS(n) \ + COND_CODE_1(DT_INST_PROP(n, top_alarm), \ + (1), \ + (0)) + +#define COUNTER_SAM_PIT64B_INIT(n) \ +static void counter_##n##_sam_config_func(const struct device *dev); \ + \ +static const struct sam_pit_config counter_##n##_sam_config = { \ + .info = { \ + .max_top_value = UINT32_MAX, \ + .flags = COUNTER_CONFIG_INFO_COUNT_UP, \ + .channels = SAM_PIT_ALARM_CHANNELS(n), \ + }, \ + .regs = (pit64b_registers_t *)DT_INST_REG_ADDR(n), \ + .clock_cfg = SAM_DT_INST_CLOCK_PMC_CFG(n), \ + .gclk_cfg = SAM_DT_CLOCK_PMC_CFG(1, DT_DRV_INST(n)), \ + .clock_selection = DT_ENUM_IDX(DT_DRV_INST(n), clock_selection), \ + .prescaler_period = DT_INST_PROP(n, prescaler_period), \ + .top_alarm = DT_INST_PROP(n, top_alarm), \ + .irq_config_func = &counter_##n##_sam_config_func, \ +}; \ + \ +static struct sam_pit_data counter_##n##_sam_data; \ + \ +DEVICE_DT_INST_DEFINE(n, sam_pit_init, NULL, \ + &counter_##n##_sam_data, \ + &counter_##n##_sam_config, \ + POST_KERNEL, CONFIG_COUNTER_INIT_PRIORITY, \ + &sam_pit_driver_api); \ + \ +static void counter_##n##_sam_config_func(const struct device *dev) \ +{ \ + IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority), \ + sam_pit_isr, DEVICE_DT_INST_GET(n), 0); \ + irq_enable(DT_INST_IRQN(n)); \ +} + +DT_INST_FOREACH_STATUS_OKAY(COUNTER_SAM_PIT64B_INIT) From 773cf7a141bf14a09302c35fe536d503ce926865 Mon Sep 17 00:00:00 2001 From: CHEN Xing Date: Mon, 4 Aug 2025 18:25:26 +0800 Subject: [PATCH 0370/3659] soc: microchip: sam: update mmu for sama7g5 pit64b Update mmu region for mchp sam pit64b Add gclk configuration for mchp sam pit64b Signed-off-by: CHEN Xing --- soc/microchip/sam/sama7/sama7g5/soc.c | 37 ++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/soc/microchip/sam/sama7/sama7g5/soc.c b/soc/microchip/sam/sama7/sama7g5/soc.c index e5261337e7e6..4f15f3864c79 100644 --- a/soc/microchip/sam/sama7/sama7g5/soc.c +++ b/soc/microchip/sam/sama7/sama7g5/soc.c @@ -25,6 +25,11 @@ (MMU_REGION_FLAT_ENTRY("xdmac"#n, XDMAC##n##_BASE_ADDRESS, 0x4000, \ MT_STRONGLY_ORDERED | MPERM_R | MPERM_W),)) +#define CONFIGURE_GCLK(idx, div, src) \ + PMC_REGS->PMC_PCR = PMC_PCR_CMD(1) | PMC_PCR_GCLKEN(1) | PMC_PCR_EN(1) | \ + PMC_PCR_GCLKDIV((div) - 1) | (src) | \ + PMC_PCR_PID(idx); + static const struct arm_mmu_region mmu_regions[] = { MMU_REGION_FLAT_ENTRY("vectors", CONFIG_KERNEL_VM_BASE, 0x1000, MT_STRONGLY_ORDERED | MPERM_R | MPERM_X), @@ -58,6 +63,21 @@ static const struct arm_mmu_region mmu_regions[] = { MMU_REGION_FLAT_ENTRY("pit64b0", PIT64B0_BASE_ADDRESS, 0x4000, MT_STRONGLY_ORDERED | MPERM_R | MPERM_W), + MMU_REGION_FLAT_ENTRY("pit64b1", PIT64B1_BASE_ADDRESS, 0x4000, + MT_STRONGLY_ORDERED | MPERM_R | MPERM_W), + + MMU_REGION_FLAT_ENTRY("pit64b2", PIT64B2_BASE_ADDRESS, 0x4000, + MT_STRONGLY_ORDERED | MPERM_R | MPERM_W), + + MMU_REGION_FLAT_ENTRY("pit64b3", PIT64B3_BASE_ADDRESS, 0x4000, + MT_STRONGLY_ORDERED | MPERM_R | MPERM_W), + + MMU_REGION_FLAT_ENTRY("pit64b4", PIT64B4_BASE_ADDRESS, 0x4000, + MT_STRONGLY_ORDERED | MPERM_R | MPERM_W), + + MMU_REGION_FLAT_ENTRY("pit64b5", PIT64B5_BASE_ADDRESS, 0x4000, + MT_STRONGLY_ORDERED | MPERM_R | MPERM_W), + MMU_REGION_FLAT_ENTRY("pmc", PMC_BASE_ADDRESS, 0x200, MT_STRONGLY_ORDERED | MPERM_R | MPERM_W), @@ -108,9 +128,14 @@ void relocate_vector_table(void) void soc_early_init_hook(void) { /* Enable Generic clock for PIT64B0 for system tick */ - PMC_REGS->PMC_PCR = PMC_PCR_CMD(1) | PMC_PCR_GCLKEN(1) | PMC_PCR_EN(1) | - PMC_PCR_GCLKDIV(40 - 1) | PMC_PCR_GCLKCSS_SYSPLL | - PMC_PCR_PID(ID_PIT64B0); + CONFIGURE_GCLK(ID_PIT64B0, 40, PMC_PCR_GCLKCSS_SYSPLL); + + /* Enable Generic clock for PIT64B 1~5, frequency is 66.667MHz */ + CONFIGURE_GCLK(ID_PIT64B1, 6, PMC_PCR_GCLKCSS_SYSPLL); + CONFIGURE_GCLK(ID_PIT64B2, 6, PMC_PCR_GCLKCSS_SYSPLL); + CONFIGURE_GCLK(ID_PIT64B3, 6, PMC_PCR_GCLKCSS_SYSPLL); + CONFIGURE_GCLK(ID_PIT64B4, 6, PMC_PCR_GCLKCSS_SYSPLL); + CONFIGURE_GCLK(ID_PIT64B5, 6, PMC_PCR_GCLKCSS_SYSPLL); /* Enable generic clock for MCANx, frequency SYSPLL / (4 + 1) = 80MHz */ FOR_EACH_IDX(MCAN_CLK_INIT_DEFN, (), 0, 1, 2, 3, 4, 5) @@ -125,6 +150,12 @@ void soc_early_init_hook(void) PMC_PCR_GCLKDIV(2 - 1) | PMC_PCR_GCLKCSS_SYSPLL | PMC_PCR_PID(ID_SDMMC1); + /* Enable Generic clock for TC0 channels, frequency is 66.667MHz */ + CONFIGURE_GCLK(ID_TC0_CHANNEL0, 6, PMC_PCR_GCLKCSS_SYSPLL); + + /* Enable Generic clock for TC1 channels, frequency is 66.667MHz */ + CONFIGURE_GCLK(ID_TC1_CHANNEL0, 6, PMC_PCR_GCLKCSS_SYSPLL); + /* config ETHPLL to 625 MHz, 24 * (0x19 + 1 + 0x2aaab / 2^22) = 625 */ if (DT_HAS_COMPAT_STATUS_OKAY(atmel_sam_gmac)) { PMC_REGS->PMC_PLL_UPDT = PMC_PLL_UPDT_ID(PLL_ID_ETHPLL); From b7268f9c3ba3e432aa1c8c8016e3ec789c0e2af1 Mon Sep 17 00:00:00 2001 From: CHEN Xing Date: Tue, 5 Aug 2025 14:26:09 +0800 Subject: [PATCH 0371/3659] boards: microchip: sam: add and enable pit64b1 Add and enable pit64b1 counter device. Signed-off-by: CHEN Xing --- boards/microchip/sam/sama7g54_ek/sama7g54_ek.dts | 6 ++++++ boards/microchip/sam/sama7g54_ek/sama7g54_ek.yaml | 1 + 2 files changed, 7 insertions(+) diff --git a/boards/microchip/sam/sama7g54_ek/sama7g54_ek.dts b/boards/microchip/sam/sama7g54_ek/sama7g54_ek.dts index 9642f55d3049..f1463a01ce1e 100644 --- a/boards/microchip/sam/sama7g54_ek/sama7g54_ek.dts +++ b/boards/microchip/sam/sama7g54_ek/sama7g54_ek.dts @@ -367,6 +367,12 @@ clock-frequency = ; }; +&pit64b1 { + top-alarm; + prescaler-period = <15>; + status = "okay"; +}; + &pwm { pinctrl-0 = <&pinctrl_mikrobus_pwm_default>; pinctrl-names = "default"; diff --git a/boards/microchip/sam/sama7g54_ek/sama7g54_ek.yaml b/boards/microchip/sam/sama7g54_ek/sama7g54_ek.yaml index 94ae1ce1716c..43d2699344ab 100644 --- a/boards/microchip/sam/sama7g54_ek/sama7g54_ek.yaml +++ b/boards/microchip/sam/sama7g54_ek/sama7g54_ek.yaml @@ -10,6 +10,7 @@ toolchain: ram: 128 supported: - can + - counter - crypto - dma - entropy From fd0f0f3c60a13ebd6fbd68d79ab52efab3a3bb08 Mon Sep 17 00:00:00 2001 From: CHEN Xing Date: Tue, 5 Aug 2025 17:46:07 +0800 Subject: [PATCH 0372/3659] samples: drivers: counter: alarm: add definition for alarm flag Counter devices can use this definition to specify alarm flags. Signed-off-by: CHEN Xing --- samples/drivers/counter/alarm/src/main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/samples/drivers/counter/alarm/src/main.c b/samples/drivers/counter/alarm/src/main.c index c0ba6a65ae51..d6c56473c3b6 100644 --- a/samples/drivers/counter/alarm/src/main.c +++ b/samples/drivers/counter/alarm/src/main.c @@ -12,6 +12,7 @@ #define DELAY 2000000 #define ALARM_CHANNEL_ID 0 +#define ALARM_FLAGS 0 struct counter_alarm_cfg alarm_cfg; @@ -140,7 +141,7 @@ int main(void) counter_start(counter_dev); - alarm_cfg.flags = 0; + alarm_cfg.flags = ALARM_FLAGS; alarm_cfg.ticks = counter_us_to_ticks(counter_dev, DELAY); alarm_cfg.callback = test_counter_interrupt_fn; alarm_cfg.user_data = &alarm_cfg; From 297ab7ac154ed64f40567159e590219079f5b631 Mon Sep 17 00:00:00 2001 From: CHEN Xing Date: Tue, 5 Aug 2025 17:51:43 +0800 Subject: [PATCH 0373/3659] samples: drivers: counter: alarm: add support for pit64b1 Add support for pit64b1 counter device. Signed-off-by: CHEN Xing --- samples/drivers/counter/alarm/sample.yaml | 1 + samples/drivers/counter/alarm/src/main.c | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/samples/drivers/counter/alarm/sample.yaml b/samples/drivers/counter/alarm/sample.yaml index 064284aa4887..266c11240f51 100644 --- a/samples/drivers/counter/alarm/sample.yaml +++ b/samples/drivers/counter/alarm/sample.yaml @@ -29,6 +29,7 @@ tests: - nrf54l15dk/nrf54l15/cpuflpr - nrf54lm20dk/nrf54lm20a/cpuapp - nrf9160dk/nrf9160 + - sama7g54_ek - samd20_xpro - bl5340_dvk/nrf5340/cpuapp - gd32e103v_eval diff --git a/samples/drivers/counter/alarm/src/main.c b/samples/drivers/counter/alarm/src/main.c index d6c56473c3b6..838781f7c894 100644 --- a/samples/drivers/counter/alarm/src/main.c +++ b/samples/drivers/counter/alarm/src/main.c @@ -78,6 +78,10 @@ struct counter_alarm_cfg alarm_cfg; #define TIMER DT_NODELABEL(rtc0) #elif defined(CONFIG_COUNTER_RENESAS_RZ_CMTW) #define TIMER DT_INST(0, renesas_rz_cmtw_counter) +#elif defined(CONFIG_COUNTER_MCHP_SAM_PIT64B) +#define TIMER DT_NODELABEL(pit64b1) +#undef ALARM_FLAGS +#define ALARM_FLAGS COUNTER_ALARM_CFG_ABSOLUTE #elif defined(CONFIG_COUNTER_MCUX_RTC_JDP) #define TIMER DT_NODELABEL(rtc) #elif defined(CONFIG_COUNTER_MCUX_RTC) From d90ca00c6a5f9a776e9b5066c9bfc7c4e4f22499 Mon Sep 17 00:00:00 2001 From: Lucien Zhao Date: Wed, 10 Dec 2025 16:39:11 +0800 Subject: [PATCH 0374/3659] boards: nxp: frdm_mcxe247: add adc feature - enable adc0 channel 0/1 - enable samples cases: adc_dt/adc_squence test case: adc_api Signed-off-by: Lucien Zhao --- boards/nxp/frdm_mcxe247/board.c | 2 +- boards/nxp/frdm_mcxe247/doc/index.rst | 4 +++ .../frdm_mcxe247/frdm_mcxe247-pinctrl.dtsi | 9 ++++++ boards/nxp/frdm_mcxe247/frdm_mcxe247.dts | 12 +++++++ boards/nxp/frdm_mcxe247/frdm_mcxe247.yaml | 1 + .../adc/adc_dt/boards/frdm_mcxe247.overlay | 31 ++++++++++++++++++ samples/drivers/adc/adc_dt/sample.yaml | 1 + .../adc_sequence/boards/frdm_mcxe247.overlay | 30 +++++++++++++++++ samples/drivers/adc/adc_sequence/sample.yaml | 1 + .../adc/adc_api/boards/frdm_mcxe247.overlay | 32 +++++++++++++++++++ 10 files changed, 122 insertions(+), 1 deletion(-) create mode 100644 samples/drivers/adc/adc_dt/boards/frdm_mcxe247.overlay create mode 100644 samples/drivers/adc/adc_sequence/boards/frdm_mcxe247.overlay create mode 100644 tests/drivers/adc/adc_api/boards/frdm_mcxe247.overlay diff --git a/boards/nxp/frdm_mcxe247/board.c b/boards/nxp/frdm_mcxe247/board.c index c2c2ceb3fecf..a0cb98d6f7d6 100644 --- a/boards/nxp/frdm_mcxe247/board.c +++ b/boards/nxp/frdm_mcxe247/board.c @@ -214,7 +214,7 @@ __weak void clock_init(void) DT_CLOCKS_CELL(DT_NODELABEL(lpspi2), ip_source)); #endif #if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(adc0)) - CLOCK_SetIpSrc(kCLOCK_Adc0 + CLOCK_SetIpSrc(kCLOCK_Adc0, DT_CLOCKS_CELL(DT_NODELABEL(adc0), ip_source)); #endif #if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(adc1)) diff --git a/boards/nxp/frdm_mcxe247/doc/index.rst b/boards/nxp/frdm_mcxe247/doc/index.rst index 11cd6e608c93..b3aa7120e1db 100644 --- a/boards/nxp/frdm_mcxe247/doc/index.rst +++ b/boards/nxp/frdm_mcxe247/doc/index.rst @@ -70,6 +70,10 @@ PORTB/GPIOB, PORTC/GPIOC, PORTD/GPIOD, and PORTE/GPIOE). +-------+-------------+---------------------------+ | PTA3 | I2C0_SCL | I2C sensor | +-------+-------------+---------------------------+ +| PTA0 | ADC0 | ADC0 Channel 0 | ++-------+-------------+---------------------------+ +| PTA1 | ADC0 | ADC0 Channel 1 | ++-------+-------------+---------------------------+ System Clock ============ diff --git a/boards/nxp/frdm_mcxe247/frdm_mcxe247-pinctrl.dtsi b/boards/nxp/frdm_mcxe247/frdm_mcxe247-pinctrl.dtsi index 2f7ad4be2507..0db0f8f69f68 100644 --- a/boards/nxp/frdm_mcxe247/frdm_mcxe247-pinctrl.dtsi +++ b/boards/nxp/frdm_mcxe247/frdm_mcxe247-pinctrl.dtsi @@ -25,4 +25,13 @@ slew-rate = "slow"; }; }; + + pinmux_adc0: pinmux_adc0 { + group0 { + pinmux = , + ; + drive-strength = "low"; + slew-rate = "slow"; + }; + }; }; diff --git a/boards/nxp/frdm_mcxe247/frdm_mcxe247.dts b/boards/nxp/frdm_mcxe247/frdm_mcxe247.dts index 28f9baad5e26..4eb07adb28cc 100644 --- a/boards/nxp/frdm_mcxe247/frdm_mcxe247.dts +++ b/boards/nxp/frdm_mcxe247/frdm_mcxe247.dts @@ -99,6 +99,14 @@ }; }; +&adc0 { + status = "okay"; + sample-time = <12>; + vref-mv = <3300>; + pinctrl-0 = <&pinmux_adc0>; + pinctrl-names = "default"; +}; + &cpu0 { clock-frequency = <80000000>; }; @@ -137,6 +145,10 @@ clock-div = <4>; }; +&fircdiv1_clk { + clock-div = <1>; +}; + &fircdiv2_clk { clock-div = <1>; }; diff --git a/boards/nxp/frdm_mcxe247/frdm_mcxe247.yaml b/boards/nxp/frdm_mcxe247/frdm_mcxe247.yaml index 1946cb7b2801..1e35cf562a79 100644 --- a/boards/nxp/frdm_mcxe247/frdm_mcxe247.yaml +++ b/boards/nxp/frdm_mcxe247/frdm_mcxe247.yaml @@ -16,5 +16,6 @@ toolchain: supported: - uart - gpio + - adc - arduino_gpio vendor: nxp diff --git a/samples/drivers/adc/adc_dt/boards/frdm_mcxe247.overlay b/samples/drivers/adc/adc_dt/boards/frdm_mcxe247.overlay new file mode 100644 index 000000000000..950612716e9a --- /dev/null +++ b/samples/drivers/adc/adc_dt/boards/frdm_mcxe247.overlay @@ -0,0 +1,31 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright 2025 NXP + */ + +/ { + zephyr,user { + /* adjust channel number according to pinmux in board.dts */ + io-channels = <&adc0 0>; + }; +}; + +&adc0 { + #address-cells = <1>; + #size-cells = <0>; + + /* + * To use this sample: + * - Connect ADC0 SE0 signal to voltage between 0~3.3V (J4 pin 10) + */ + + channel@0 { + reg = <0>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,vref-mv = <3300>; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; +}; diff --git a/samples/drivers/adc/adc_dt/sample.yaml b/samples/drivers/adc/adc_dt/sample.yaml index c691bc0e40e5..cb19a18488d5 100644 --- a/samples/drivers/adc/adc_dt/sample.yaml +++ b/samples/drivers/adc/adc_dt/sample.yaml @@ -48,6 +48,7 @@ tests: - frdm_mcxa346 - frdm_mcxa266 - frdm_mcxa366 + - frdm_mcxe247 - s32k148_evb - raytac_an54lq_db_15/nrf54l15/cpuapp - mck_ra4t1 diff --git a/samples/drivers/adc/adc_sequence/boards/frdm_mcxe247.overlay b/samples/drivers/adc/adc_sequence/boards/frdm_mcxe247.overlay new file mode 100644 index 000000000000..66a6b3689cee --- /dev/null +++ b/samples/drivers/adc/adc_sequence/boards/frdm_mcxe247.overlay @@ -0,0 +1,30 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright 2025 NXP + */ + +/ { + aliases { + adc0 = &adc0; + }; +}; + +&adc0 { + #address-cells = <1>; + #size-cells = <0>; + + /* + * To use this sample: + * - Connect ADC0 SE0 signal to voltage between 0~3.3V (J4 pin 10) + */ + + channel@0 { + reg = <0>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,vref-mv = <3300>; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; +}; diff --git a/samples/drivers/adc/adc_sequence/sample.yaml b/samples/drivers/adc/adc_sequence/sample.yaml index ff0fc64a91dc..95ea7e88009b 100644 --- a/samples/drivers/adc/adc_sequence/sample.yaml +++ b/samples/drivers/adc/adc_sequence/sample.yaml @@ -27,6 +27,7 @@ tests: - ucans32k1sic - s32k148_evb - frdm_mcxc242 + - frdm_mcxe247 - slwrb4180a - xg27_rb4194a - xg29_rb4412a diff --git a/tests/drivers/adc/adc_api/boards/frdm_mcxe247.overlay b/tests/drivers/adc/adc_api/boards/frdm_mcxe247.overlay new file mode 100644 index 000000000000..28f84adfc444 --- /dev/null +++ b/tests/drivers/adc/adc_api/boards/frdm_mcxe247.overlay @@ -0,0 +1,32 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + zephyr,user { + io-channels = <&adc0 0>, <&adc0 1>; + }; +}; + +&adc0 { + #address-cells = <1>; + #size-cells = <0>; + + channel@0 { + reg = <0>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; + + channel@1 { + reg = <1>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; +}; From fefb2837300e8919885493b2161989dbe1fed724 Mon Sep 17 00:00:00 2001 From: Lucien Zhao Date: Thu, 11 Dec 2025 15:02:20 +0800 Subject: [PATCH 0375/3659] boards: nxp: frdm_mcxe247: support cmp feature - Enable CMP0_IN0 as input channel - Enable gpio_loopback case Signed-off-by: Lucien Zhao --- boards/nxp/frdm_mcxe247/doc/index.rst | 2 ++ .../frdm_mcxe247/frdm_mcxe247-pinctrl.dtsi | 8 ++++++ boards/nxp/frdm_mcxe247/frdm_mcxe247.dts | 6 +++++ boards/nxp/frdm_mcxe247/frdm_mcxe247.yaml | 1 + .../gpio_loopback/boards/frdm_mcxe247.overlay | 25 +++++++++++++++++++ .../comparator/gpio_loopback/testcase.yaml | 1 + 6 files changed, 43 insertions(+) create mode 100644 tests/drivers/comparator/gpio_loopback/boards/frdm_mcxe247.overlay diff --git a/boards/nxp/frdm_mcxe247/doc/index.rst b/boards/nxp/frdm_mcxe247/doc/index.rst index b3aa7120e1db..0103adc7dfca 100644 --- a/boards/nxp/frdm_mcxe247/doc/index.rst +++ b/boards/nxp/frdm_mcxe247/doc/index.rst @@ -74,6 +74,8 @@ PORTB/GPIOB, PORTC/GPIOC, PORTD/GPIOD, and PORTE/GPIOE). +-------+-------------+---------------------------+ | PTA1 | ADC0 | ADC0 Channel 1 | +-------+-------------+---------------------------+ +| PTA0 | CMP0 | CMP0 IN 0 | ++-------+-------------+---------------------------+ System Clock ============ diff --git a/boards/nxp/frdm_mcxe247/frdm_mcxe247-pinctrl.dtsi b/boards/nxp/frdm_mcxe247/frdm_mcxe247-pinctrl.dtsi index 0db0f8f69f68..d7d5f1868221 100644 --- a/boards/nxp/frdm_mcxe247/frdm_mcxe247-pinctrl.dtsi +++ b/boards/nxp/frdm_mcxe247/frdm_mcxe247-pinctrl.dtsi @@ -34,4 +34,12 @@ slew-rate = "slow"; }; }; + + pinmux_cmp0: pinmux_cmp0 { + group0 { + pinmux = ; + drive-strength = "high"; + slew-rate = "fast"; + }; + }; }; diff --git a/boards/nxp/frdm_mcxe247/frdm_mcxe247.dts b/boards/nxp/frdm_mcxe247/frdm_mcxe247.dts index 4eb07adb28cc..ece371f6dc0e 100644 --- a/boards/nxp/frdm_mcxe247/frdm_mcxe247.dts +++ b/boards/nxp/frdm_mcxe247/frdm_mcxe247.dts @@ -107,6 +107,12 @@ pinctrl-names = "default"; }; +&cmp0 { + status = "okay"; + pinctrl-0 = <&pinmux_cmp0>; + pinctrl-names = "default"; +}; + &cpu0 { clock-frequency = <80000000>; }; diff --git a/boards/nxp/frdm_mcxe247/frdm_mcxe247.yaml b/boards/nxp/frdm_mcxe247/frdm_mcxe247.yaml index 1e35cf562a79..fdcfaebc97fb 100644 --- a/boards/nxp/frdm_mcxe247/frdm_mcxe247.yaml +++ b/boards/nxp/frdm_mcxe247/frdm_mcxe247.yaml @@ -18,4 +18,5 @@ supported: - gpio - adc - arduino_gpio + - comparator vendor: nxp diff --git a/tests/drivers/comparator/gpio_loopback/boards/frdm_mcxe247.overlay b/tests/drivers/comparator/gpio_loopback/boards/frdm_mcxe247.overlay new file mode 100644 index 000000000000..baff797343dd --- /dev/null +++ b/tests/drivers/comparator/gpio_loopback/boards/frdm_mcxe247.overlay @@ -0,0 +1,25 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/ { + aliases { + test-comp = &cmp0; + }; + + zephyr,user { + /* PTA1 output connect to PTA0. */ + test-gpios = <&gpioa 1 GPIO_ACTIVE_HIGH>; + }; +}; + +&cmp0 { + positive-mux-input = "IN0"; /* PTA0, FRDM-MCXE247 J4-10 */ + negative-mux-input = "IN7"; /* DAC output => 1.65V */ + dac-vref-source = "VIN2"; + dac-value = <31>; +}; diff --git a/tests/drivers/comparator/gpio_loopback/testcase.yaml b/tests/drivers/comparator/gpio_loopback/testcase.yaml index deeca32ffe1f..2d1b07d42cf8 100644 --- a/tests/drivers/comparator/gpio_loopback/testcase.yaml +++ b/tests/drivers/comparator/gpio_loopback/testcase.yaml @@ -20,6 +20,7 @@ tests: drivers.comparator.gpio_loopback.mcux_acmp: platform_allow: - frdm_ke15z + - frdm_mcxe247 drivers.comparator.gpio_loopback.nrf_comp: extra_args: - FILE_SUFFIX="nrf_comp" From 44eaeb011944db7b919c581d6381230f8e6402e5 Mon Sep 17 00:00:00 2001 From: Muhammad Waleed Badar Date: Fri, 21 Nov 2025 03:25:07 +0500 Subject: [PATCH 0376/3659] samples: ocpp: add DNS lookup before SNTP request Added dns_query() function to perform DNS lookup before attempting SNTP synchronization. This ensures the SNTP server hostname is properly resolved to an IP address before making the time request. Signed-off-by: Muhammad Waleed Badar --- samples/net/ocpp/Kconfig | 5 ++++ samples/net/ocpp/prj.conf | 4 +++ samples/net/ocpp/src/main.c | 54 ++++++++++++++++++++++++++++++------- 3 files changed, 53 insertions(+), 10 deletions(-) diff --git a/samples/net/ocpp/Kconfig b/samples/net/ocpp/Kconfig index 706c528161dc..4ab610774b3a 100644 --- a/samples/net/ocpp/Kconfig +++ b/samples/net/ocpp/Kconfig @@ -26,4 +26,9 @@ config NET_SAMPLE_SNTP_SERVER help SNTP server ip to get the time from network +config NET_SAMPLE_SNTP_SERVER_PORT + int "SNTP server port" + help + SNTP server port to get the time from network + source "Kconfig.zephyr" diff --git a/samples/net/ocpp/prj.conf b/samples/net/ocpp/prj.conf index 3897041e6c96..5d6bb9cbeee6 100644 --- a/samples/net/ocpp/prj.conf +++ b/samples/net/ocpp/prj.conf @@ -21,6 +21,7 @@ CONFIG_OCPP=y # Please set the server addresses when compiling the sample CONFIG_NET_SAMPLE_SNTP_SERVER="" +CONFIG_NET_SAMPLE_SNTP_SERVER_PORT=123 CONFIG_NET_SAMPLE_OCPP_SERVER="" CONFIG_NET_SAMPLE_OCPP_PORT=8180 @@ -42,6 +43,9 @@ CONFIG_NET_BUF_RX_COUNT=60 CONFIG_NET_MGMT=y CONFIG_NET_MGMT_EVENT=y +CONFIG_DNS_RESOLVER=y +CONFIG_NET_SOCKETS_DNS_TIMEOUT=5000 + CONFIG_SNTP=y CONFIG_ZBUS=y diff --git a/samples/net/ocpp/src/main.c b/samples/net/ocpp/src/main.c index 6745e5581f73..df4b42c23731 100644 --- a/samples/net/ocpp/src/main.c +++ b/samples/net/ocpp/src/main.c @@ -35,34 +35,68 @@ static struct k_thread tinfo[NO_OF_CONN]; static k_tid_t tid[NO_OF_CONN]; static char idtag[NO_OF_CONN][25]; +static int dns_query(const char *host, uint16_t port, int family, int socktype, + struct sockaddr *addr, socklen_t *addrlen) +{ + struct addrinfo hints = { + .ai_family = family, + .ai_socktype = socktype, + }; + + struct addrinfo *res = NULL; + char addr_str[INET6_ADDRSTRLEN] = {0}; + int ret; + + /* Perform DNS query */ + ret = getaddrinfo(host, NULL, &hints, &res); + if (ret < 0) { + LOG_ERR("getaddrinfo failed (%d, errno %d)", ret, errno); + return ret; + } + + /* Store the first result */ + *addr = *res->ai_addr; + *addrlen = res->ai_addrlen; + /* Free the allocated memory */ + freeaddrinfo(res); + /* Store the port */ + net_sin(addr)->sin_port = htons(port); + /* Print the found address */ + inet_ntop(addr->sa_family, &net_sin(addr)->sin_addr, addr_str, sizeof(addr_str)); + LOG_INF("%s -> %s", host, addr_str); + + return 0; +} + static int ocpp_get_time_from_sntp(void) { struct sntp_ctx ctx; struct sntp_time stime; - struct sockaddr_in addr; + struct sockaddr addr; + socklen_t addrlen; struct timespec tv; int ret; - /* ipv4 */ - memset(&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_port = htons(123); - inet_pton(AF_INET, CONFIG_NET_SAMPLE_SNTP_SERVER, &addr.sin_addr); + ret = dns_query(CONFIG_NET_SAMPLE_SNTP_SERVER, CONFIG_NET_SAMPLE_SNTP_SERVER_PORT, + AF_INET, SOCK_DGRAM, &addr, &addrlen); + if (ret != 0) { + LOG_ERR("Failed to lookup SNTP server (%d)", ret); + return ret; + } - ret = sntp_init(&ctx, (struct sockaddr *) &addr, - sizeof(struct sockaddr_in)); + ret = sntp_init(&ctx, &addr, addrlen); if (ret < 0) { LOG_ERR("Failed to init SNTP IPv4 ctx: %d", ret); return ret; } - ret = sntp_query(&ctx, 60, &stime); + ret = sntp_query(&ctx, 4 * MSEC_PER_SEC, &stime); if (ret < 0) { LOG_ERR("SNTP IPv4 request failed: %d", ret); return ret; } - LOG_INF("sntp succ since Epoch: %llu\n", stime.seconds); + LOG_INF("SNTP success, epoch seconds: %llu\n", stime.seconds); tv.tv_sec = stime.seconds; clock_settime(CLOCK_REALTIME, &tv); sntp_close(&ctx); From 8ee850953341781c0adb535c310854f675598af1 Mon Sep 17 00:00:00 2001 From: zjian zhang Date: Fri, 20 Sep 2024 16:52:14 +0800 Subject: [PATCH 0377/3659] west.yml: Add Realtek HAL as a new HAL module Realtek HAL (Hardware Abstraction Layer) provides a low level peripheral configuration function. Signed-off-by: zjian zhang --- west.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/west.yml b/west.yml index 5d4fefc5d38a..87c7e076d9ef 100644 --- a/west.yml +++ b/west.yml @@ -224,6 +224,11 @@ manifest: path: modules/hal/quicklogic groups: - hal + - name: hal_realtek + path: modules/hal/realtek + revision: c769be0fb9e385edba12e9626ee516c0a44b9907 + groups: + - hal - name: hal_renesas path: modules/hal/renesas revision: d01039075990309dcbbec9b86510ed9f70a01dff From 56d6012c96b6f01419d89901af83373ae3b9b2f8 Mon Sep 17 00:00:00 2001 From: zjian zhang Date: Mon, 30 Sep 2024 23:29:56 +0800 Subject: [PATCH 0378/3659] dts: arm: introduce amebadplus SOC Devicetree add initial version of devicetree for amebadplus SOC. amebadplus devicetree file is main platform dtsi file, which should be included from board dts (e.g rtl872xda_evb.dts) Signed-off-by: zjian zhang --- dts/arm/realtek/amebadplus/amebadplus.dtsi | 99 ++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 dts/arm/realtek/amebadplus/amebadplus.dtsi diff --git a/dts/arm/realtek/amebadplus/amebadplus.dtsi b/dts/arm/realtek/amebadplus/amebadplus.dtsi new file mode 100644 index 000000000000..95375a9d0e4f --- /dev/null +++ b/dts/arm/realtek/amebadplus/amebadplus.dtsi @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor Corp. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#include + +/ { + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-m55"; + reg = <0>; + d-cache-line-size = <32>; + #address-cells = <1>; + #size-cells = <1>; + }; + }; + + clocks { + clk_sys: clk_sys { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = ; + }; + }; + + soc { + sram0: memory@20010020 { + compatible = "mmio-sram"; + reg = <0x20010020 0x00030000>; + }; + + ram_image2_entry: memory@20004da0 { + compatible = "zephyr,memory-region"; + reg = <0x20004da0 0x20>; + zephyr,memory-region = "KM4_IMG2_ENTRY"; + }; + + pinctrl: pinctrl@41008800 { + compatible = "realtek,ameba-pinctrl"; + reg = <0x41008800 0x200>; + status = "disabled"; + }; + + loguart: serial@4100f000 { + compatible = "realtek,ameba-loguart"; + reg = <0x4100f000 0x100>; + interrupts = <27 0>; + current-speed = <1500000>; + status = "disabled"; + }; + + gpioa: gpio@41010000 { + compatible = "realtek,ameba-gpio"; + reg = <0x41010000 0x400>; + gpio-controller; + #gpio-cells = <2>; + interrupts = <28 0>; + status = "disabled"; + }; + + gpiob: gpio@41010400 { + compatible = "realtek,ameba-gpio"; + reg = <0x41010400 0x400>; + gpio-controller; + #gpio-cells = <2>; + interrupts = <29 0>; + status = "disabled"; + }; + + spic: flash-controller@40128000 { + compatible = "realtek,ameba-flash-controller"; + reg = <0x40128000 0x400>; + + #address-cells = <1>; + #size-cells = <1>; + status = "disabled"; + + flash0: flash@e000020 { + compatible = "soc-nv-flash"; + erase-block-size = ; + write-block-size = <4>; + }; + }; + }; +}; + +&nvic { + arm,num-irq-priority-bits = <3>; +}; From e6d690a983c3066dc5674da875c854b6861164b6 Mon Sep 17 00:00:00 2001 From: zjian zhang Date: Thu, 19 Sep 2024 21:27:27 +0800 Subject: [PATCH 0379/3659] soc: add realtek amebadplus SOC integration Add initial version of Amebadplus Soc integration Signed-off-by: zjian zhang --- soc/realtek/ameba/CMakeLists.txt | 4 ++ soc/realtek/ameba/Kconfig | 12 ++++++ soc/realtek/ameba/Kconfig.defconfig | 8 ++++ soc/realtek/ameba/Kconfig.soc | 10 +++++ soc/realtek/ameba/amebadplus/CMakeLists.txt | 34 ++++++++++++++++ soc/realtek/ameba/amebadplus/Kconfig | 15 +++++++ .../ameba/amebadplus/Kconfig.defconfig | 15 +++++++ soc/realtek/ameba/amebadplus/Kconfig.soc | 16 ++++++++ soc/realtek/ameba/amebadplus/boot_section.ld | 20 ++++++++++ soc/realtek/ameba/amebadplus/soc.c | 39 +++++++++++++++++++ soc/realtek/ameba/amebadplus/soc.h | 17 ++++++++ soc/realtek/ameba/soc.yml | 6 +++ 12 files changed, 196 insertions(+) create mode 100644 soc/realtek/ameba/CMakeLists.txt create mode 100644 soc/realtek/ameba/Kconfig create mode 100644 soc/realtek/ameba/Kconfig.defconfig create mode 100644 soc/realtek/ameba/Kconfig.soc create mode 100644 soc/realtek/ameba/amebadplus/CMakeLists.txt create mode 100644 soc/realtek/ameba/amebadplus/Kconfig create mode 100644 soc/realtek/ameba/amebadplus/Kconfig.defconfig create mode 100644 soc/realtek/ameba/amebadplus/Kconfig.soc create mode 100644 soc/realtek/ameba/amebadplus/boot_section.ld create mode 100644 soc/realtek/ameba/amebadplus/soc.c create mode 100644 soc/realtek/ameba/amebadplus/soc.h create mode 100644 soc/realtek/ameba/soc.yml diff --git a/soc/realtek/ameba/CMakeLists.txt b/soc/realtek/ameba/CMakeLists.txt new file mode 100644 index 000000000000..89876e8d3f64 --- /dev/null +++ b/soc/realtek/ameba/CMakeLists.txt @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Realtek Semiconductor Corp. +# SPDX-License-Identifier: Apache-2.0 + +add_subdirectory(${CONFIG_SOC_SERIES}) diff --git a/soc/realtek/ameba/Kconfig b/soc/realtek/ameba/Kconfig new file mode 100644 index 000000000000..b51759e89007 --- /dev/null +++ b/soc/realtek/ameba/Kconfig @@ -0,0 +1,12 @@ +# Copyright (c) 2024 Realtek Semiconductor Corp. +# SPDX-License-Identifier: Apache-2.0 + +config SOC_FAMILY_REALTEK_AMEBA + select BUILD_OUTPUT_HEX + select SOC_EARLY_INIT_HOOK + +if SOC_FAMILY_REALTEK_AMEBA + +rsource "*/Kconfig" + +endif # SOC_FAMILY_REALTEK_AMEBA diff --git a/soc/realtek/ameba/Kconfig.defconfig b/soc/realtek/ameba/Kconfig.defconfig new file mode 100644 index 000000000000..d4e73efa3d45 --- /dev/null +++ b/soc/realtek/ameba/Kconfig.defconfig @@ -0,0 +1,8 @@ +# Copyright (c) 2024 Realtek Semiconductor Corp. +# SPDX-License-Identifier: Apache-2.0 + +if SOC_FAMILY_REALTEK_AMEBA + +rsource "*/Kconfig.defconfig" + +endif # SOC_FAMILY_REALTEK_AMEBA diff --git a/soc/realtek/ameba/Kconfig.soc b/soc/realtek/ameba/Kconfig.soc new file mode 100644 index 000000000000..2c1a5f11b316 --- /dev/null +++ b/soc/realtek/ameba/Kconfig.soc @@ -0,0 +1,10 @@ +# Copyright (c) 2024 Realtek Semiconductor Corp. +# SPDX-License-Identifier: Apache-2.0 + +config SOC_FAMILY_REALTEK_AMEBA + bool + +config SOC_FAMILY + default "realtek_ameba" if SOC_FAMILY_REALTEK_AMEBA + +rsource "*/Kconfig.soc" diff --git a/soc/realtek/ameba/amebadplus/CMakeLists.txt b/soc/realtek/ameba/amebadplus/CMakeLists.txt new file mode 100644 index 000000000000..6b3fb8c38fbe --- /dev/null +++ b/soc/realtek/ameba/amebadplus/CMakeLists.txt @@ -0,0 +1,34 @@ +# Copyright (c) 2024 Realtek Semiconductor Corp. +# SPDX-License-Identifier: Apache-2.0 + +zephyr_include_directories(${ZEPHYR_BASE}/drivers) +zephyr_include_directories(.) + +zephyr_sources(soc.c) + +zephyr_linker_sources(SECTIONS boot_section.ld) +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") + +# west sign +file(GLOB BIN_FILES "${ZEPHYR_HAL_REALTEK_MODULE_DIR}/zephyr/blobs/${CONFIG_SOC_SERIES}/bin/*.bin") + +if(BIN_FILES) + set(python_script_args + --soc ${CONFIG_SOC_SERIES} + --bin-file ${ZEPHYR_BINARY_DIR}/${KERNEL_BIN_NAME} + --out-dir ${CMAKE_BINARY_DIR} + --module-dir ${ZEPHYR_HAL_REALTEK_MODULE_DIR} + ) + + add_custom_target(zephyr.raw.map ALL + DEPENDS ${ZEPHYR_BINARY_DIR}/${KERNEL_NAME}.raw.map + ) + + add_custom_command( + OUTPUT ${ZEPHYR_BINARY_DIR}/${KERNEL_NAME}.raw.map + COMMAND ${CMAKE_NM} ${ZEPHYR_BINARY_DIR}/${KERNEL_ELF_NAME} | sort > ${ZEPHYR_BINARY_DIR}/${KERNEL_NAME}.raw.map + COMMAND ${CMAKE_OBJDUMP} -d ${ZEPHYR_BINARY_DIR}/${KERNEL_ELF_NAME} > ${ZEPHYR_BINARY_DIR}/${KERNEL_NAME}.asm + COMMAND ${PYTHON_EXECUTABLE} ${ZEPHYR_HAL_REALTEK_MODULE_DIR}/ameba/scripts/merge_bin.py ${python_script_args} + DEPENDS ${ZEPHYR_BINARY_DIR}/${KERNEL_ELF_NAME} ${ZEPHYR_HAL_REALTEK_MODULE_DIR}/ameba/${CONFIG_SOC_SERIES}/manifest.json5 + ) +endif() diff --git a/soc/realtek/ameba/amebadplus/Kconfig b/soc/realtek/ameba/amebadplus/Kconfig new file mode 100644 index 000000000000..1cac9c3cfad4 --- /dev/null +++ b/soc/realtek/ameba/amebadplus/Kconfig @@ -0,0 +1,15 @@ +# Copyright (c) 2024 Realtek Semiconductor Corp. +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_AMEBADPLUS + select ARM + select CPU_CORTEX_M55 + select CPU_HAS_DCACHE + select CPU_HAS_ICACHE + select CPU_HAS_ARM_SAU + select CPU_HAS_FPU + select CPU_HAS_VFP + select ARMV8_M_DSP + select CPU_HAS_ARM_MPU + select ARM_MPU + select ARM_TRUSTZONE_M diff --git a/soc/realtek/ameba/amebadplus/Kconfig.defconfig b/soc/realtek/ameba/amebadplus/Kconfig.defconfig new file mode 100644 index 000000000000..06a123e6a71b --- /dev/null +++ b/soc/realtek/ameba/amebadplus/Kconfig.defconfig @@ -0,0 +1,15 @@ +# Copyright (c) 2024 Realtek Semiconductor Corp. +# SPDX-License-Identifier: Apache-2.0 + +if SOC_SERIES_AMEBADPLUS + +config NUM_IRQS + default 96 + +config SYS_CLOCK_HW_CYCLES_PER_SEC + default $(dt_node_int_prop_int,/clocks/clk_sys,clock-frequency) + +config CACHE_MANAGEMENT + default y + +endif # SOC_SERIES_AMEBADPLUS diff --git a/soc/realtek/ameba/amebadplus/Kconfig.soc b/soc/realtek/ameba/amebadplus/Kconfig.soc new file mode 100644 index 000000000000..35a05340858d --- /dev/null +++ b/soc/realtek/ameba/amebadplus/Kconfig.soc @@ -0,0 +1,16 @@ +# Copyright (c) 2024 Realtek Semiconductor Corp. +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_AMEBADPLUS + bool + select SOC_FAMILY_REALTEK_AMEBA + +config SOC_SERIES + default "amebadplus" if SOC_SERIES_AMEBADPLUS + +config SOC_RTL8721DX + bool + select SOC_SERIES_AMEBADPLUS + +config SOC + default "rtl8721dx" if SOC_RTL8721DX diff --git a/soc/realtek/ameba/amebadplus/boot_section.ld b/soc/realtek/ameba/amebadplus/boot_section.ld new file mode 100644 index 000000000000..94dfffc01072 --- /dev/null +++ b/soc/realtek/ameba/amebadplus/boot_section.ld @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor Corp. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +SECTION_PROLOGUE(.ram_image2.entry,,SUBALIGN(32)) +{ + __image2_entry_func__ = .; + KEEP(*(SORT(.image2.entry.data*))) + . = ALIGN(32); +} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) + +SECTION_PROLOGUE(.psram_image2.text.data,,) +{ + . = ALIGN (32); + __ipc_table_start__ = .; + KEEP(*(*.ipc.table.data*)) + __ipc_table_end__ = .; +} GROUP_LINK_IN(ROMABLE_REGION) diff --git a/soc/realtek/ameba/amebadplus/soc.c b/soc/realtek/ameba/amebadplus/soc.c new file mode 100644 index 000000000000..20092ac51783 --- /dev/null +++ b/soc/realtek/ameba/amebadplus/soc.c @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor Corp. + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include + +#include +#include +#include +#include + +void z_arm_reset(void); + +IMAGE2_ENTRY_SECTION +RAM_START_FUNCTION Img2EntryFun0 = {z_arm_reset, NULL, /* BOOT_RAM_WakeFromPG, */ + (uint32_t)NewVectorTable}; + +void soc_early_init_hook(void) +{ + /* + * Cache is enabled by default at reset, disable it before + * sys_cache*-functions can enable them. + */ + Cache_Enable(DISABLE); + sys_cache_instr_enable(); + sys_cache_data_enable(); + + XTAL_INIT(); + + if (SYSCFG_CHIPType_Get() == CHIP_TYPE_ASIC_POSTSIM) { + OSC4M_Init(); + OSC4M_Calibration(30000); + if (!(BOOT_Reason() & AON_BIT_RSTF_DSLP)) { + OSC131K_Calibration(30000); /* PPM=30000=3% */ + } + } +} diff --git a/soc/realtek/ameba/amebadplus/soc.h b/soc/realtek/ameba/amebadplus/soc.h new file mode 100644 index 000000000000..be800319c1e5 --- /dev/null +++ b/soc/realtek/ameba/amebadplus/soc.h @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor Corp. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_SOC_REALTEK_AMEBA_AMEBADPLUS_H_ +#define ZEPHYR_SOC_REALTEK_AMEBA_AMEBADPLUS_H_ + +#ifndef _ASMLANGUAGE + +#include +#include "cmsis_cpu.h" + +#endif /* _ASMLANGUAGE */ + +#endif /* ZEPHYR_SOC_REALTEK_AMEBA_AMEBADPLUS_H_ */ diff --git a/soc/realtek/ameba/soc.yml b/soc/realtek/ameba/soc.yml new file mode 100644 index 000000000000..602bbb18bea7 --- /dev/null +++ b/soc/realtek/ameba/soc.yml @@ -0,0 +1,6 @@ +family: + - name: realtek_ameba + series: + - name: amebadplus + socs: + - name: rtl8721dx From d21b2aa15d47c873e1994a253c241f878385eef2 Mon Sep 17 00:00:00 2001 From: zjian zhang Date: Fri, 20 Sep 2024 14:19:40 +0800 Subject: [PATCH 0380/3659] drivers: pinctrl: add amebadplus pin controller driver add amebadplus pin controller driver Signed-off-by: zjian zhang --- drivers/pinctrl/CMakeLists.txt | 1 + drivers/pinctrl/Kconfig | 1 + drivers/pinctrl/Kconfig.ameba | 9 ++ drivers/pinctrl/pinctrl_ameba.c | 85 +++++++++++++++ .../pinctrl/realtek,ameba-pinctrl.yaml | 88 +++++++++++++++ .../dt-bindings/pinctrl/amebadplus-pinctrl.h | 101 ++++++++++++++++++ soc/realtek/ameba/amebadplus/pinctrl_soc.h | 54 ++++++++++ 7 files changed, 339 insertions(+) create mode 100644 drivers/pinctrl/Kconfig.ameba create mode 100644 drivers/pinctrl/pinctrl_ameba.c create mode 100644 dts/bindings/pinctrl/realtek,ameba-pinctrl.yaml create mode 100644 include/zephyr/dt-bindings/pinctrl/amebadplus-pinctrl.h create mode 100644 soc/realtek/ameba/amebadplus/pinctrl_soc.h diff --git a/drivers/pinctrl/CMakeLists.txt b/drivers/pinctrl/CMakeLists.txt index f38d33dbb2c9..0efdc3dc5a3b 100644 --- a/drivers/pinctrl/CMakeLists.txt +++ b/drivers/pinctrl/CMakeLists.txt @@ -8,6 +8,7 @@ zephyr_library_sources(common.c) # zephyr-keep-sorted-start zephyr_library_sources_ifdef(CONFIG_PINCTRL_AMBIQ pinctrl_ambiq.c) +zephyr_library_sources_ifdef(CONFIG_PINCTRL_AMEBA pinctrl_ameba.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_ARM_MPS2 pinctrl_arm_mps2.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_ARM_MPS3 pinctrl_arm_mps3.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_ARM_MPS4 pinctrl_arm_mps4.c) diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index c71cf703995c..751c26ed8c75 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -40,6 +40,7 @@ config PINCTRL_KEEP_SLEEP_STATE # zephyr-keep-sorted-start source "drivers/pinctrl/Kconfig.ambiq" +source "drivers/pinctrl/Kconfig.ameba" source "drivers/pinctrl/Kconfig.arm_mps2" source "drivers/pinctrl/Kconfig.arm_mps3" source "drivers/pinctrl/Kconfig.arm_mps4" diff --git a/drivers/pinctrl/Kconfig.ameba b/drivers/pinctrl/Kconfig.ameba new file mode 100644 index 000000000000..3a168ee8467d --- /dev/null +++ b/drivers/pinctrl/Kconfig.ameba @@ -0,0 +1,9 @@ +# Copyright (c) 2024 Realtek Semiconductor Corp. +# SPDX-License-Identifier: Apache-2.0 + +config PINCTRL_AMEBA + bool "Pin controller driver for Realtek Ameba series SoC" + default y + depends on DT_HAS_REALTEK_AMEBA_PINCTRL_ENABLED + help + Enable pin controller driver for Realtek Ameba series SoC diff --git a/drivers/pinctrl/pinctrl_ameba.c b/drivers/pinctrl/pinctrl_ameba.c new file mode 100644 index 000000000000..dc9370829a8d --- /dev/null +++ b/drivers/pinctrl/pinctrl_ameba.c @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor Corp. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* Include before to avoid redefining unlikely() macro */ +#include +#include + +#include + +#define AMEBA_GET_PORT_NUM(pin_mux) ((pin_mux >> 13) & 0x03) +#define AMEBA_GET_PIN_NUM(pin_mux) ((pin_mux >> 8) & 0x1f) +#define AMEBA_GET_PIMNUX_ID(pin_mux) (pin_mux & 0xFF) + +#define AMEBA_GPIO_PINNAME(port, pin) (((port) << 5) | ((pin) & 0x1F)) + +static int ameba_configure_pin(const pinctrl_soc_pin_t *pin) +{ + uint32_t port_idx, pin_idx; + uint8_t gpio_pin; + uint32_t function_id; + + port_idx = AMEBA_GET_PORT_NUM(pin->pinmux); + pin_idx = AMEBA_GET_PIN_NUM(pin->pinmux); + function_id = AMEBA_GET_PIMNUX_ID(pin->pinmux); + gpio_pin = AMEBA_GPIO_PINNAME(port_idx, pin_idx); + + Pinmux_Config(gpio_pin, function_id); + + if (pin->pull_up) { + PAD_PullCtrl(gpio_pin, GPIO_PuPd_UP); + PAD_SleepPullCtrl(gpio_pin, GPIO_PuPd_UP); + } else if (pin->pull_down) { + PAD_PullCtrl(gpio_pin, GPIO_PuPd_DOWN); + PAD_SleepPullCtrl(gpio_pin, GPIO_PuPd_DOWN); + } else { + PAD_PullCtrl(gpio_pin, GPIO_PuPd_NOPULL); + PAD_SleepPullCtrl(gpio_pin, GPIO_PuPd_NOPULL); + } + + /* default slew rate fast */ + if (pin->slew_rate_slow) { + PAD_SlewRateCtrl(gpio_pin, PAD_SlewRate_Slow); + } + + /* Set the PAD driving strength to PAD_DRV_ABILITITY_LOW, default PAD_DRV_ABILITITY_HIGH */ + if (pin->drive_strength_low) { + PAD_DrvStrength(gpio_pin, PAD_DRV_ABILITITY_LOW); + } + + /* default enable digital path input. */ + if (pin->digital_input_disable) { + PAD_InputCtrl(gpio_pin, DISABLE); + } + + /* default enable schmitt */ + if (pin->schmitt_disable) { + PAD_SchmitCtrl(gpio_pin, DISABLE); + } + + if (pin->swd_off) { + Pinmux_Swdoff(); + } + + return 0; +} + +int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, uintptr_t reg) +{ + int ret; + + ARG_UNUSED(reg); + + for (int i = 0; i < pin_cnt; i++) { + ret = ameba_configure_pin(&pins[i]); + + if (ret < 0) { + return ret; + } + } + + return 0; +} diff --git a/dts/bindings/pinctrl/realtek,ameba-pinctrl.yaml b/dts/bindings/pinctrl/realtek,ameba-pinctrl.yaml new file mode 100644 index 000000000000..bf9d285b8868 --- /dev/null +++ b/dts/bindings/pinctrl/realtek,ameba-pinctrl.yaml @@ -0,0 +1,88 @@ +# Copyright (c) 2024 Realtek Semiconductor Corp. +# SPDX-License-Identifier: Apache-2.0 + +description: | + Realtek Ameba pinctrl is a singleton node responsible for controlling pin function selection + and pin properties. For example, you can use this node to route UART0 TX to pin PB_17 + and enable the pull-up resistor on the pin. + + All device pin configurations should be placed in child nodes of the 'pinctrl' node, + as shown in this example: + /* put this example in places like a board-pinctrl.dtsi file in your board directory, + * or a devicetree overlay in your application. + */ + &pinctrl { + /* configuration for uart0 device, default state */ + uart0_default: uart0_default { + /* 'group1' name is arbitrary, if pin's settings are not same, + * add other group like group2 {} + */ + group1 { + pinmux = , + ; + bias-pull-up; + }; + }; + }; + + The 'uart0_default' child node encodes the pin configurations for a particular state of a device; + in this case, the default (that is, active) state. You would specify the low-power configuration + for the same device in a separate child node. + + As shown, pin configurations are organized in groups within each child node. Each group can + specify a list of pin function selections in the 'pinmux' property. The AMEBA_PINMUX macro is + used to specify a pin function selection and pin configuration. You could choose pinmux specified + function to specified pin. And you could configure driver direction, driver state and pull state + for the specified pad. + + To link this pin configuration with a device, use a pinctrl-N property for some number N, + like this example you could place in your board's DTS file: + &uart0 { + pinctrl-0 = <&uart0_default>; + pinctrl-names = "default"; + }; + +compatible: "realtek,ameba-pinctrl" + +include: base.yaml + +properties: + reg: + required: true +child-binding: + description: | + Realtek Ameba pin controller pin group for a pinctrl state. + child-binding: + description: | + Realtek Ameba pin controller pin configuration node. + include: + - name: pincfg-node.yaml + property-allowlist: + - bias-disable + - bias-pull-down + - bias-pull-up + - input-schmitt-disable + properties: + pinmux: + required: true + type: array + description: | + Pin mux selections for this group. An array of pins sharing the same group properties. + Each element of the array is an integer constructed from the pin number and + the alternative function of the pin. + slew-rate-slow: + type: boolean + description: | + Pin output slew rate.If not set, default value is fast. + drive-strength-low: + type: boolean + description: | + Drive strength of the output pin.If not set, default ability is high. + digital-input-disable: + type: boolean + description: | + Disable the digital input function. + swd-off: + type: boolean + description: | + Disable the SWD function. diff --git a/include/zephyr/dt-bindings/pinctrl/amebadplus-pinctrl.h b/include/zephyr/dt-bindings/pinctrl/amebadplus-pinctrl.h new file mode 100644 index 000000000000..0d7f535e71cb --- /dev/null +++ b/include/zephyr/dt-bindings/pinctrl/amebadplus-pinctrl.h @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor Corp. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_AMEBADPLUS_PINCTRL_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_AMEBADPLUS_PINCTRL_H_ + +/* PINMUX Function definitions */ +#define AMEBA_GPIO 0 +#define AMEBA_LOG_UART 1 +#define AMEBA_UART 1 +#define AMEBA_SPIC0_FLASH 2 +#define AMEBA_SPIC1_FLASH 3 +#define AMEBA_SPIC1_PSRAM 4 +#define AMEBA_OSPI 5 +#define AMEBA_QSPI 5 +#define AMEBA_ADC 6 +#define AMEBA_CAP_TOUCH 6 +#define AMEBA_SIC 7 +#define AMEBA_SPI 8 +#define AMEBA_SWD 9 +#define AMEBA_SDIO 10 +#define AMEBA_ANT_DIV 11 +#define AMEBA_EXT_BT 12 +#define AMEBA_BT_IO 13 +#define AMEBA_BT 14 +#define AMEBA_EXT_ZIGBEE 15 +#define AMEBA_TIMER 16 +#define AMEBA_USB 17 +#define AMEBA_DEBUG 18 +#define AMEBA_UART0_TXD 19 +#define AMEBA_UART0_RXD 20 +#define AMEBA_UART0_CTS 21 +#define AMEBA_UART0_RTS 22 +#define AMEBA_UART1_TXD 23 +#define AMEBA_UART1_RXD 24 +#define AMEBA_UART2_TXD 25 +#define AMEBA_UART2_RXD 26 +#define AMEBA_UART2_CTS 27 +#define AMEBA_UART2_RTS 28 +#define AMEBA_SPI1_CLK 29 +#define AMEBA_SPI1_MISO 30 +#define AMEBA_SPI1_MOSI 31 +#define AMEBA_SPI1_CS 32 +#define AMEBA_LEDC 33 +#define AMEBA_I2S0_MCLK 34 +#define AMEBA_I2S0_BCLK 35 +#define AMEBA_I2S0_WS 36 +#define AMEBA_I2S0_DIO0 37 +#define AMEBA_I2S0_DIO1 38 +#define AMEBA_I2S0_DIO2 39 +#define AMEBA_I2S0_DIO3 40 +#define AMEBA_I2S1_MCLK 41 +#define AMEBA_I2S1_BCLK 42 +#define AMEBA_I2S1_WS 43 +#define AMEBA_I2S1_DIO0 44 +#define AMEBA_I2S1_DIO1 45 +#define AMEBA_I2S1_DIO2 46 +#define AMEBA_I2S1_DIO3 47 +#define AMEBA_I2C0_SCL 48 +#define AMEBA_I2C0_SDA 49 +#define AMEBA_I2C1_SCL 50 +#define AMEBA_I2C1_SDA 51 +#define AMEBA_PWM0 52 +#define AMEBA_PWM1 53 +#define AMEBA_PWM2 54 +#define AMEBA_PWM3 55 +#define AMEBA_PWM4 56 +#define AMEBA_PWM5 57 +#define AMEBA_PWM6 58 +#define AMEBA_PWM7 59 +#define AMEBA_BT_UART_TXD 60 +#define AMEBA_BT_UART_RTS 61 +#define AMEBA_DMIC_CLK 62 +#define AMEBA_DMIC_DATA 63 +#define AMEBA_IR_TX 64 +#define AMEBA_IR_RX 65 +#define AMEBA_KEY_ROW0 66 +#define AMEBA_KEY_ROW1 67 +#define AMEBA_KEY_ROW2 68 +#define AMEBA_KEY_ROW3 69 +#define AMEBA_KEY_ROW4 70 +#define AMEBA_KEY_ROW5 71 +#define AMEBA_KEY_ROW6 72 +#define AMEBA_KEY_ROW7 73 +#define AMEBA_KEY_COL0 74 +#define AMEBA_KEY_COL1 75 +#define AMEBA_KEY_COL2 76 +#define AMEBA_KEY_COL3 77 +#define AMEBA_KEY_COL4 78 +#define AMEBA_KEY_COL5 79 +#define AMEBA_KEY_COL6 80 +#define AMEBA_KEY_COL7 81 + +/* Define pins number: bit[14:13] port, bit[12:8] pin, bit[7:0] function ID */ +#define AMEBA_PORT_PIN(port, line) ((((port) - 'A') << 5) + (line)) +#define AMEBA_PINMUX(port, line, funcid) (((AMEBA_PORT_PIN(port, line)) << 8) | (funcid)) + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_AMEBADPLUS_PINCTRL_H_ */ diff --git a/soc/realtek/ameba/amebadplus/pinctrl_soc.h b/soc/realtek/ameba/amebadplus/pinctrl_soc.h new file mode 100644 index 000000000000..9465578c56f2 --- /dev/null +++ b/soc/realtek/ameba/amebadplus/pinctrl_soc.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor Corp. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_SOC_REALTEK_AMEBA_AMEBADPLUS_PINCTRL_SOC_H_ +#define ZEPHYR_SOC_REALTEK_AMEBA_AMEBADPLUS_PINCTRL_SOC_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct pinctrl_soc_pin { + uint32_t pinmux: 15; + /* bit[14:13] port + * bit[12:8] pin + * bit[7:0] function ID + */ + uint32_t pull_down: 1; + uint32_t pull_up: 1; + uint32_t schmitt_disable: 1; + uint32_t slew_rate_slow: 1; + uint32_t drive_strength_low: 1; + uint32_t digital_input_disable: 1; + uint32_t swd_off: 1; +}; + +typedef struct pinctrl_soc_pin pinctrl_soc_pin_t; + +#define Z_PINCTRL_STATE_PIN_INIT(node_id, prop, idx) \ + { \ + .pinmux = DT_PROP_BY_IDX(node_id, prop, idx), \ + .pull_down = DT_PROP(node_id, bias_pull_down), \ + .pull_up = DT_PROP(node_id, bias_pull_up), \ + .schmitt_disable = DT_PROP(node_id, input_schmitt_disable), \ + .slew_rate_slow = DT_PROP(node_id, slew_rate_slow), \ + .drive_strength_low = DT_PROP(node_id, drive_strength_low), \ + .digital_input_disable = DT_PROP(node_id, digital_input_disable), \ + .swd_off = DT_PROP(node_id, swd_off), \ + }, + +#define Z_PINCTRL_STATE_PINS_INIT(node_id, prop) \ + {DT_FOREACH_CHILD_VARGS(DT_PHANDLE(node_id, prop), DT_FOREACH_PROP_ELEM, pinmux, \ + Z_PINCTRL_STATE_PIN_INIT)} + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_SOC_REALTEK_AMEBA_AMEBADPLUS_PINCTRL_SOC_H_ */ From 53bba6df0161d27af392ec880adf4bb1da9efe58 Mon Sep 17 00:00:00 2001 From: zjian zhang Date: Fri, 20 Sep 2024 16:03:32 +0800 Subject: [PATCH 0381/3659] drivers: serial: add amebadplus loguart driver loguart driver for amebadplus Signed-off-by: zjian zhang --- drivers/serial/CMakeLists.txt | 1 + drivers/serial/Kconfig | 1 + drivers/serial/Kconfig.ameba_loguart | 10 + drivers/serial/uart_ameba_loguart.c | 320 ++++++++++++++++++ .../serial/realtek,ameba-loguart.yaml | 16 + 5 files changed, 348 insertions(+) create mode 100644 drivers/serial/Kconfig.ameba_loguart create mode 100644 drivers/serial/uart_ameba_loguart.c create mode 100644 dts/bindings/serial/realtek,ameba-loguart.yaml diff --git a/drivers/serial/CMakeLists.txt b/drivers/serial/CMakeLists.txt index db7182c72bdb..0f558417d211 100644 --- a/drivers/serial/CMakeLists.txt +++ b/drivers/serial/CMakeLists.txt @@ -21,6 +21,7 @@ zephyr_library_sources_ifdef(CONFIG_UART_AESC uart_aesc.c) zephyr_library_sources_ifdef(CONFIG_UART_ALTERA uart_altera.c) zephyr_library_sources_ifdef(CONFIG_UART_ALTERA_JTAG uart_altera_jtag.c) zephyr_library_sources_ifdef(CONFIG_UART_AMBIQ uart_ambiq.c) +zephyr_library_sources_ifdef(CONFIG_UART_AMEBA_LOGUART uart_ameba_loguart.c) zephyr_library_sources_ifdef(CONFIG_UART_APBUART uart_apbuart.c) zephyr_library_sources_ifdef(CONFIG_UART_BCM2711_MU uart_bcm2711.c) zephyr_library_sources_ifdef(CONFIG_UART_BFLB uart_bflb.c) diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 2d207d768f0e..bdb34c100ecf 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -161,6 +161,7 @@ rsource "Kconfig.aesc" rsource "Kconfig.altera" rsource "Kconfig.altera_jtag" rsource "Kconfig.ambiq" +rsource "Kconfig.ameba_loguart" rsource "Kconfig.apbuart" rsource "Kconfig.b91" rsource "Kconfig.bcm2711" diff --git a/drivers/serial/Kconfig.ameba_loguart b/drivers/serial/Kconfig.ameba_loguart new file mode 100644 index 000000000000..93fb92c38738 --- /dev/null +++ b/drivers/serial/Kconfig.ameba_loguart @@ -0,0 +1,10 @@ +# Copyright (c) 2024 Realtek Semiconductor Corp. +# SPDX-License-Identifier: Apache-2.0 + +config UART_AMEBA_LOGUART + bool "Ameba LOGUART driver" + default y + depends on DT_HAS_REALTEK_AMEBA_LOGUART_ENABLED + select SERIAL_HAS_DRIVER + help + This option enables the LOGUART driver for Realtek Ameba SoCs. diff --git a/drivers/serial/uart_ameba_loguart.c b/drivers/serial/uart_ameba_loguart.c new file mode 100644 index 000000000000..5196ba71fe83 --- /dev/null +++ b/drivers/serial/uart_ameba_loguart.c @@ -0,0 +1,320 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor Corp. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @brief Driver for Realtek Ameba LOGUART + */ + +/* Include before to avoid redefining unlikely() macro */ +#include +#include + +#include +#include +#include +#include + +#include +LOG_MODULE_REGISTER(loguart_ameba, CONFIG_UART_LOG_LEVEL); + +/* + * Extract information from devicetree. + * + * This driver only supports one instance of this IP block, so the + * instance number is always 0. + */ +#define DT_DRV_COMPAT realtek_ameba_loguart + +/* Device config structure */ +struct loguart_ameba_config { +#if defined(CONFIG_UART_INTERRUPT_DRIVEN) + uart_irq_config_func_t irq_config_func; +#endif +}; + +/* Device data structure */ +struct loguart_ameba_data { + struct uart_config config; +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + uart_irq_callback_user_data_t user_cb; + void *user_data; + bool tx_int_en; + bool rx_int_en; +#endif +}; + +/** + * @brief Poll the device for input. + * + * @param dev UART device struct + * @param c Pointer to character + * + * @return 0 if a character arrived, -1 if the input buffer if empty. + */ +static int loguart_ameba_poll_in(const struct device *dev, unsigned char *c) +{ + ARG_UNUSED(dev); + + if (!LOGUART_Readable()) { + return -1; + } + + *c = LOGUART_GetChar(false); + return 0; +} + +/** + * @brief Output a character in polled mode. + * + * @param dev UART device struct + * @param c Character to send + */ +static void loguart_ameba_poll_out(const struct device *dev, unsigned char c) +{ + ARG_UNUSED(dev); + LOGUART_PutChar(c); +} + +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + +static int loguart_ameba_fifo_fill(const struct device *dev, const uint8_t *tx_data, int len) +{ + ARG_UNUSED(dev); + + uint8_t num_tx = 0U; + unsigned int key; + + if (!LOGUART_Writable()) { + return num_tx; + } + + /* Lock interrupts to prevent nested interrupts or thread switch */ + + key = irq_lock(); + + while ((len - num_tx > 0) && LOGUART_Writable()) { + LOGUART_PutChar((uint8_t)tx_data[num_tx++]); + } + + irq_unlock(key); + + return num_tx; +} + +static int loguart_ameba_fifo_read(const struct device *dev, uint8_t *rx_data, const int size) +{ + ARG_UNUSED(dev); + + uint8_t num_rx = 0U; + + while ((size - num_rx > 0) && LOGUART_Readable()) { + rx_data[num_rx++] = LOGUART_GetChar(false); + } + + /* Clear timeout int flag */ + if (LOGUART_GetStatus(LOGUART_DEV) & LOGUART_BIT_TIMEOUT_INT) { + LOGUART_INTClear(LOGUART_DEV, LOGUART_BIT_TOICF); + } + + return num_rx; +} + +static void loguart_ameba_irq_tx_enable(const struct device *dev) +{ + u32 sts; + struct loguart_ameba_data *data = dev->data; + + /* Disable IRQ Interrupts and Save Previous Status. */ + sts = irq_disable_save(); + + data->tx_int_en = true; + /* KM4: TX_PATH1 */ + LOGUART_INTConfig(LOGUART_DEV, LOGUART_TX_EMPTY_PATH_1_INTR, ENABLE); + + /* Enable IRQ Interrupts according to Previous Status. */ + irq_enable_restore(sts); +} + +static void loguart_ameba_irq_tx_disable(const struct device *dev) +{ + u32 sts; + struct loguart_ameba_data *data = dev->data; + + /* Disable IRQ Interrupts and Save Previous Status. */ + sts = irq_disable_save(); + + LOGUART_INTConfig(LOGUART_DEV, LOGUART_TX_EMPTY_PATH_1_INTR, DISABLE); + data->tx_int_en = false; + + /* Enable IRQ Interrupts according to Previous Status. */ + irq_enable_restore(sts); +} + +static int loguart_ameba_irq_tx_ready(const struct device *dev) +{ + struct loguart_ameba_data *data = dev->data; + + /* KM4: TX_PATH1 */ + return (LOGUART_GetStatus(LOGUART_DEV) & LOGUART_BIT_TP1F_EMPTY) && data->tx_int_en; +} + +static int loguart_ameba_irq_tx_complete(const struct device *dev) +{ + return loguart_ameba_irq_tx_ready(dev); +} + +static void loguart_ameba_irq_rx_enable(const struct device *dev) +{ + struct loguart_ameba_data *data = dev->data; + + data->rx_int_en = true; + LOGUART_INTConfig(LOGUART_DEV, LOGUART_BIT_ERBI | LOGUART_BIT_ETOI, ENABLE); +} + +static void loguart_ameba_irq_rx_disable(const struct device *dev) +{ + struct loguart_ameba_data *data = dev->data; + + data->rx_int_en = false; + LOGUART_INTConfig(LOGUART_DEV, LOGUART_BIT_ERBI | LOGUART_BIT_ETOI, DISABLE); +} + +static int loguart_ameba_irq_rx_ready(const struct device *dev) +{ + struct loguart_ameba_data *data = dev->data; + + return (LOGUART_GetStatus(LOGUART_DEV) & + (LOGUART_BIT_DRDY | LOGUART_BIT_RXFIFO_INT | LOGUART_BIT_TIMEOUT_INT)) && + data->rx_int_en; +} + +static void loguart_ameba_irq_err_enable(const struct device *dev) +{ + ARG_UNUSED(dev); + + LOGUART_INTConfig(LOGUART_DEV, LOGUART_BIT_ELSI, ENABLE); +} + +static void loguart_ameba_irq_err_disable(const struct device *dev) +{ + ARG_UNUSED(dev); + + LOGUART_INTConfig(LOGUART_DEV, LOGUART_BIT_ELSI, DISABLE); +} + +static int loguart_ameba_irq_is_pending(const struct device *dev) +{ + return loguart_ameba_irq_tx_ready(dev) || loguart_ameba_irq_rx_ready(dev); +} + +static int loguart_ameba_irq_update(const struct device *dev) +{ + return 1; +} + +static void loguart_ameba_irq_callback_set(const struct device *dev, + uart_irq_callback_user_data_t cb, void *cb_data) +{ + struct loguart_ameba_data *data = dev->data; + + data->user_cb = cb; + data->user_data = cb_data; +} + +#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ + +/** + * @brief Initialize UART channel + * + * This routine is called to reset the chip in a quiescent state. + * It is assumed that this function is called only once per UART. + * + * @param dev UART device struct + * + * @return 0 on success + */ +static int loguart_ameba_init(const struct device *dev) +{ + LOGUART_RxCmd(LOGUART_DEV, DISABLE); + LOGUART_INTCoreConfig(LOGUART_DEV, LOGUART_BIT_INTR_MASK_KM0, DISABLE); + LOGUART_INTCoreConfig(LOGUART_DEV, LOGUART_BIT_INTR_MASK_KM4, ENABLE); + +#if defined(CONFIG_UART_INTERRUPT_DRIVEN) + const struct loguart_ameba_config *config = dev->config; + + config->irq_config_func(dev); +#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ + + LOGUART_RxCmd(LOGUART_DEV, ENABLE); + + return 0; +} + +#if defined(CONFIG_UART_INTERRUPT_DRIVEN) +#define AMEBA_LOGUART_IRQ_HANDLER_DECL \ + static void loguart_ameba_irq_config_func(const struct device *dev); +#define AMEBA_LOGUART_IRQ_HANDLER \ + static void loguart_ameba_irq_config_func(const struct device *dev) \ + { \ + IRQ_CONNECT(DT_INST_IRQN(0), DT_INST_IRQ(0, priority), loguart_ameba_isr, \ + DEVICE_DT_INST_GET(0), 0); \ + irq_enable(DT_INST_IRQN(0)); \ + } +#define AMEBA_LOGUART_IRQ_HANDLER_FUNC .irq_config_func = loguart_ameba_irq_config_func, +#else +#define AMEBA_LOGUART_IRQ_HANDLER_DECL /* Not used */ +#define AMEBA_LOGUART_IRQ_HANDLER /* Not used */ +#define AMEBA_LOGUART_IRQ_HANDLER_FUNC /* Not used */ +#endif + +#if defined(CONFIG_UART_INTERRUPT_DRIVEN) + +static void loguart_ameba_isr(const struct device *dev) +{ + struct loguart_ameba_data *data = dev->data; + + if (data->user_cb) { + data->user_cb(dev, data->user_data); + } +} +#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ + +static const struct uart_driver_api loguart_ameba_driver_api = { + .poll_in = loguart_ameba_poll_in, + .poll_out = loguart_ameba_poll_out, +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + .fifo_fill = loguart_ameba_fifo_fill, + .fifo_read = loguart_ameba_fifo_read, + .irq_tx_enable = loguart_ameba_irq_tx_enable, + .irq_tx_disable = loguart_ameba_irq_tx_disable, + .irq_tx_ready = loguart_ameba_irq_tx_ready, + .irq_rx_enable = loguart_ameba_irq_rx_enable, + .irq_rx_disable = loguart_ameba_irq_rx_disable, + .irq_tx_complete = loguart_ameba_irq_tx_complete, + .irq_rx_ready = loguart_ameba_irq_rx_ready, + .irq_err_enable = loguart_ameba_irq_err_enable, + .irq_err_disable = loguart_ameba_irq_err_disable, + .irq_is_pending = loguart_ameba_irq_is_pending, + .irq_update = loguart_ameba_irq_update, + .irq_callback_set = loguart_ameba_irq_callback_set, +#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ +}; + +AMEBA_LOGUART_IRQ_HANDLER_DECL +AMEBA_LOGUART_IRQ_HANDLER + +static const struct loguart_ameba_config loguart_config = {AMEBA_LOGUART_IRQ_HANDLER_FUNC}; + +static struct loguart_ameba_data loguart_data = {.config = { + .stop_bits = UART_CFG_STOP_BITS_1, + .data_bits = UART_CFG_DATA_BITS_8, + .baudrate = DT_INST_PROP(0, current_speed), + .parity = UART_CFG_PARITY_NONE, + .flow_ctrl = UART_CFG_FLOW_CTRL_NONE, + }}; + +DEVICE_DT_INST_DEFINE(0, loguart_ameba_init, NULL, &loguart_data, &loguart_config, PRE_KERNEL_1, + CONFIG_SERIAL_INIT_PRIORITY, &loguart_ameba_driver_api); diff --git a/dts/bindings/serial/realtek,ameba-loguart.yaml b/dts/bindings/serial/realtek,ameba-loguart.yaml new file mode 100644 index 000000000000..68926503fc74 --- /dev/null +++ b/dts/bindings/serial/realtek,ameba-loguart.yaml @@ -0,0 +1,16 @@ +# Copyright (c) 2024 Realtek Semiconductor Corp. +# SPDX-License-Identifier: Apache-2.0 + +description: Ameba LOGUART +compatible: "realtek,ameba-loguart" + +include: [uart-controller.yaml, base.yaml, pinctrl-device.yaml] + +bus: uart + +properties: + reg: + required: true + + interrupts: + required: true From e788c98af6fd031147eb29cfc2f7e3f869624453 Mon Sep 17 00:00:00 2001 From: zjian zhang Date: Fri, 20 Sep 2024 17:51:08 +0800 Subject: [PATCH 0382/3659] drivers: gpio: add amebadplus gpio driver GPIO driver for amebadplus Signed-off-by: zjian zhang --- drivers/gpio/CMakeLists.txt | 1 + drivers/gpio/Kconfig | 1 + drivers/gpio/Kconfig.ameba | 18 ++ drivers/gpio/gpio_ameba.c | 291 ++++++++++++++++++++++ dts/bindings/gpio/realtek,ameba-gpio.yaml | 22 ++ 5 files changed, 333 insertions(+) create mode 100644 drivers/gpio/Kconfig.ameba create mode 100644 drivers/gpio/gpio_ameba.c create mode 100644 dts/bindings/gpio/realtek,ameba-gpio.yaml diff --git a/drivers/gpio/CMakeLists.txt b/drivers/gpio/CMakeLists.txt index 10e2fb23beec..3811b378f4ec 100644 --- a/drivers/gpio/CMakeLists.txt +++ b/drivers/gpio/CMakeLists.txt @@ -11,6 +11,7 @@ zephyr_library_sources_ifdef(CONFIG_GPIO_ADS1X4S0X gpio_ads1x4s0x.c) zephyr_library_sources_ifdef(CONFIG_GPIO_AESC gpio_aesc.c) zephyr_library_sources_ifdef(CONFIG_GPIO_ALTERA_PIO gpio_altera_pio.c) zephyr_library_sources_ifdef(CONFIG_GPIO_AMBIQ gpio_ambiq.c) +zephyr_library_sources_ifdef(CONFIG_GPIO_AMEBA gpio_ameba.c) zephyr_library_sources_ifdef(CONFIG_GPIO_ANDES_ATCGPIO100 gpio_andes_atcgpio100.c) zephyr_library_sources_ifdef(CONFIG_GPIO_AW9523B gpio_aw9523b.c) zephyr_library_sources_ifdef(CONFIG_GPIO_AXP192 gpio_axp192.c) diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 497b4e8acbf5..c03445ab6b93 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -100,6 +100,7 @@ source "drivers/gpio/Kconfig.ads1x4s0x" source "drivers/gpio/Kconfig.aesc" source "drivers/gpio/Kconfig.altera" source "drivers/gpio/Kconfig.ambiq" +source "drivers/gpio/Kconfig.ameba" source "drivers/gpio/Kconfig.andes_atcgpio100" source "drivers/gpio/Kconfig.aw9523b" source "drivers/gpio/Kconfig.axp192" diff --git a/drivers/gpio/Kconfig.ameba b/drivers/gpio/Kconfig.ameba new file mode 100644 index 000000000000..58a27a8f039b --- /dev/null +++ b/drivers/gpio/Kconfig.ameba @@ -0,0 +1,18 @@ +# Copyright (c) 2024 Realtek Semiconductor Corp. +# SPDX-License-Identifier: Apache-2.0 + +config GPIO_AMEBA + bool "GPIO controller driver for Realtek Ameba series SoC" + default y + depends on DT_HAS_REALTEK_AMEBA_GPIO_ENABLED + help + Enable GPIO controller driver for Realtek Ameba series SoC + +config GPIO_DEBOUNCE_EN + bool "Ameba GPIO Interrupt Debounce Enable" + depends on GPIO_AMEBA + default y + help + When Enable GPIO Interrupt Debounce, the external signal can be debounced to + remove any spurious glitches that are less than one period(about 32us) of + the external debouncing clock. diff --git a/drivers/gpio/gpio_ameba.c b/drivers/gpio/gpio_ameba.c new file mode 100644 index 000000000000..3b49ee4b6404 --- /dev/null +++ b/drivers/gpio/gpio_ameba.c @@ -0,0 +1,291 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor Corp. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT realtek_ameba_gpio + +/* Include before to avoid redefining unlikely() macro */ +#include +#include + +#include +#include +#include + +#include +LOG_MODULE_REGISTER(gpio_ameba, CONFIG_GPIO_LOG_LEVEL); + +#define GPIO_PINNAME(PORT, PIN) (((PORT) << 5) | ((PIN) & 0x1F)) + +struct gpio_ameba_config { + /* gpio_driver_config needs to be first */ + struct gpio_driver_config common; + /* port base address */ + uint32_t base; + /* IO port */ + int port; +}; + +struct gpio_ameba_data { + /* gpio_driver_data needs to be first */ + struct gpio_driver_data common; + /* port ISR callback routine address */ + sys_slist_t callbacks; +}; + +static int gpio_ameba_port_get_raw(const struct device *dev, uint32_t *value) +{ + const struct gpio_ameba_config *cfg = dev->config; + + *value = GPIO_PortRead(cfg->port, cfg->common.port_pin_mask); + + return 0; +} + +static int gpio_ameba_port_set_masked_raw(const struct device *dev, uint32_t mask, uint32_t value) +{ + const struct gpio_ameba_config *cfg = dev->config; + + GPIO_PortDirection(cfg->port, mask, GPIO_Mode_OUT); + GPIO_PortWrite(cfg->port, mask, value); + + return 0; +} + +static int gpio_ameba_port_set_bits_raw(const struct device *dev, uint32_t mask) +{ + const struct gpio_ameba_config *cfg = dev->config; + + GPIO_PortWrite(cfg->port, mask, cfg->common.port_pin_mask); + + return 0; +} + +static int gpio_ameba_port_clear_bits_raw(const struct device *dev, uint32_t mask) +{ + const struct gpio_ameba_config *cfg = dev->config; + + GPIO_PortWrite(cfg->port, mask, 0); + + return 0; +} + +static int gpio_ameba_port_toggle_bits(const struct device *dev, uint32_t mask) +{ + const struct gpio_ameba_config *cfg = dev->config; + u32 gpio_pin; + u32 value; + uint8_t i; + + for (i = 0; i < 32; i++) { + if (mask & 0x1) { + gpio_pin = GPIO_PINNAME(cfg->port, i); + value = GPIO_ReadDataBit(gpio_pin); + GPIO_WriteBit(gpio_pin, (~value) & 0x1); + } + mask >>= 1; + if (mask == 0) { + break; + } + } + + return 0; +} + +static int gpio_ameba_configure(const struct device *dev, gpio_pin_t pin, gpio_flags_t flags) +{ + const struct gpio_ameba_config *cfg = dev->config; + + GPIO_InitTypeDef gpio_initstruct; + u32 gpio_pin; + + if (((flags & GPIO_INPUT) != 0) && ((flags & GPIO_OUTPUT) != 0)) { + return -ENOTSUP; + } + + if ((flags & (GPIO_INPUT | GPIO_OUTPUT)) == 0) { + return -ENOTSUP; + } + + gpio_pin = GPIO_PINNAME(cfg->port, pin); + gpio_initstruct.GPIO_Pin = gpio_pin; + + if (flags & GPIO_INPUT) { + gpio_initstruct.GPIO_Mode = GPIO_Mode_IN; + } else { + gpio_initstruct.GPIO_Mode = GPIO_Mode_OUT; + } + + if (flags & GPIO_PULL_UP) { + gpio_initstruct.GPIO_PuPd = GPIO_PuPd_UP; + } else if (flags & GPIO_PULL_DOWN) { + gpio_initstruct.GPIO_PuPd = GPIO_PuPd_DOWN; + } else { + gpio_initstruct.GPIO_PuPd = GPIO_PuPd_NOPULL; + } + + GPIO_Init(&gpio_initstruct); + + if (flags & GPIO_OUTPUT) { + if ((flags & GPIO_OUTPUT_INIT_HIGH) != 0) { + gpio_ameba_port_set_bits_raw(dev, BIT(pin)); + } else if ((flags & GPIO_OUTPUT_INIT_LOW) != 0) { + gpio_ameba_port_clear_bits_raw(dev, BIT(pin)); + } else { + /* Do nothing */ + } + } + + return 0; +} + +static int gpio_ameba_pin_interrupt_configure(const struct device *dev, gpio_pin_t pin, + enum gpio_int_mode mode, enum gpio_int_trig trig) +{ + const struct gpio_ameba_config *cfg = dev->config; + u32 gpio_pin; + + gpio_pin = GPIO_PINNAME(cfg->port, pin); + GPIO_InitTypeDef gpio_initstruct; + + gpio_initstruct.GPIO_Pin = gpio_pin; + + GPIO_INTConfig(gpio_pin, DISABLE); + + LOG_DBG("Config GPIO int:%d-%d, mode:%x, flag:0x%x", cfg->port, pin, mode, trig); + gpio_initstruct.GPIO_Pin = gpio_pin; + gpio_initstruct.GPIO_PuPd = GPIO_PuPd_NOPULL; + gpio_initstruct.GPIO_Mode = GPIO_Mode_INT; + gpio_initstruct.GPIO_ITDebounce = GPIO_INT_DEBOUNCE_DISABLE; + + if (mode != GPIO_INT_MODE_DISABLED) { + if (mode & GPIO_INT_MODE_EDGE) { + switch (trig) { + case GPIO_INT_TRIG_LOW: + gpio_initstruct.GPIO_ITTrigger = GPIO_INT_Trigger_EDGE; + gpio_initstruct.GPIO_ITPolarity = GPIO_INT_POLARITY_ACTIVE_LOW; + break; + case GPIO_INT_TRIG_HIGH: + gpio_initstruct.GPIO_ITTrigger = GPIO_INT_Trigger_EDGE; + gpio_initstruct.GPIO_ITPolarity = GPIO_INT_POLARITY_ACTIVE_HIGH; + break; + case GPIO_INT_TRIG_BOTH: + gpio_initstruct.GPIO_ITTrigger = GPIO_INT_Trigger_BOTHEDGE; + break; + default: + LOG_ERR("GPIO Edge interrupt type invalid"); + return -ENOTSUP; + } + } else { + gpio_initstruct.GPIO_ITTrigger = GPIO_INT_Trigger_LEVEL; + switch (trig) { + case GPIO_INT_TRIG_LOW: + gpio_initstruct.GPIO_ITPolarity = GPIO_INT_POLARITY_ACTIVE_LOW; + gpio_initstruct.GPIO_PuPd = GPIO_PuPd_UP; + break; + case GPIO_INT_TRIG_HIGH: + gpio_initstruct.GPIO_ITPolarity = GPIO_INT_POLARITY_ACTIVE_HIGH; + gpio_initstruct.GPIO_PuPd = GPIO_PuPd_DOWN; + break; + default: + LOG_ERR("GPIO level interrupt doesn't support both high and low"); + return -ENOTSUP; + } + } + +#if defined(CONFIG_GPIO_DEBOUNCE_EN) + gpio_initstruct.GPIO_ITDebounce = GPIO_INT_DEBOUNCE_ENABLE; + GPIO_Init(&gpio_initstruct); + k_busy_wait(64); + GPIO_INTConfig(gpio_pin, ENABLE); +#else + GPIO_Init(&gpio_initstruct); + GPIO_INTConfig(gpio_pin, ENABLE); +#endif + } else { + GPIO_Direction(gpio_pin, GPIO_Mode_IN); + PAD_PullCtrl(gpio_pin, gpio_initstruct.GPIO_PuPd); + + GPIO_INTMode(gpio_pin, DISABLE, 0, 0, 0); + } + + return 0; +} + +static int gpio_ameba_manage_callback(const struct device *dev, struct gpio_callback *callback, + bool set) +{ + struct gpio_ameba_data *data = dev->data; + + return gpio_manage_callback(&data->callbacks, callback, set); +} + +static uint32_t gpio_ameba_get_pending_int(const struct device *dev) +{ + uint32_t irq_status; + const struct gpio_ameba_config *cfg = dev->config; + uint32_t port = cfg->port; + + irq_status = GPIO_INTStatusGet(port); + + return irq_status; +} + +static void gpio_ameba_isr(const struct device *dev) +{ + uint32_t int_status; + struct gpio_ameba_data *data = dev->data; + const struct gpio_ameba_config *cfg = dev->config; + uint32_t port = cfg->port; + + /* Get the int status */ + int_status = GPIO_INTStatusGet(port); + + /* Clear pending edge interrupt */ + GPIO_INTStatusClearEdge(port); + + /* Call the registered callbacks */ + gpio_fire_callbacks(&data->callbacks, dev, int_status); +} + +static const struct gpio_driver_api gpio_ameba_driver_api = { + .pin_configure = gpio_ameba_configure, + .port_get_raw = gpio_ameba_port_get_raw, + .port_set_masked_raw = gpio_ameba_port_set_masked_raw, + .port_set_bits_raw = gpio_ameba_port_set_bits_raw, + .port_clear_bits_raw = gpio_ameba_port_clear_bits_raw, + .port_toggle_bits = gpio_ameba_port_toggle_bits, + .pin_interrupt_configure = gpio_ameba_pin_interrupt_configure, + .manage_callback = gpio_ameba_manage_callback, + .get_pending_int = gpio_ameba_get_pending_int, +}; + +#define GPIO_AMEBA_INIT(n) \ + static int gpio_ameba_port##n##_init(const struct device *dev) \ + { \ + const struct gpio_ameba_config *cfg = dev->config; \ + \ + IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority), gpio_ameba_isr, \ + DEVICE_DT_INST_GET(n), 0); \ + irq_enable(DT_INST_IRQN(n)); \ + \ + return 0; \ + } \ + static struct gpio_ameba_data gpio_ameba_port##n##_data; \ + \ + static const struct gpio_ameba_config gpio_ameba_port##n##_config = { \ + .common = \ + { \ + .port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(n), \ + }, \ + .base = DT_INST_REG_ADDR(n), \ + .port = n, \ + }; \ + \ + DEVICE_DT_INST_DEFINE(n, gpio_ameba_port##n##_init, NULL, &gpio_ameba_port##n##_data, \ + &gpio_ameba_port##n##_config, POST_KERNEL, \ + CONFIG_GPIO_INIT_PRIORITY, &gpio_ameba_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(GPIO_AMEBA_INIT) diff --git a/dts/bindings/gpio/realtek,ameba-gpio.yaml b/dts/bindings/gpio/realtek,ameba-gpio.yaml new file mode 100644 index 000000000000..4eab82fd2316 --- /dev/null +++ b/dts/bindings/gpio/realtek,ameba-gpio.yaml @@ -0,0 +1,22 @@ +# Copyright (c) 2024 Realtek Semiconductor Corp. +# SPDX-License-Identifier: Apache-2.0 + +description: Realtek Ameba GPIO controller + +compatible: "realtek,ameba-gpio" + +include: [gpio-controller.yaml, base.yaml] + +properties: + reg: + required: true + + interrupts: + required: true + + "#gpio-cells": + const: 2 + +gpio-cells: + - pin + - flags From 1d36710436d2e31e8db8eba6bdd45543aafd583f Mon Sep 17 00:00:00 2001 From: zjian zhang Date: Wed, 28 Aug 2024 14:21:51 +0800 Subject: [PATCH 0383/3659] boards: add rtl872xda_evb board add initial version of rtl872xda_evb board Signed-off-by: zjian zhang --- .../rtl872xda_evb/Kconfig.rtl872xda_evb | 5 + boards/realtek/rtl872xda_evb/board.cmake | 6 ++ boards/realtek/rtl872xda_evb/board.yml | 5 + boards/realtek/rtl872xda_evb/doc/index.rst | 96 ++++++++++++++++++ .../rtl872xda_evb/doc/rtl872xda_evb.webp | Bin 0 -> 29540 bytes .../rtl872xda_evb/rtl872xda_evb-pinctrl.dtsi | 20 ++++ .../realtek/rtl872xda_evb/rtl872xda_evb.dts | 30 ++++++ .../realtek/rtl872xda_evb/rtl872xda_evb.yaml | 16 +++ .../rtl872xda_evb/rtl872xda_evb_defconfig | 8 ++ 9 files changed, 186 insertions(+) create mode 100644 boards/realtek/rtl872xda_evb/Kconfig.rtl872xda_evb create mode 100644 boards/realtek/rtl872xda_evb/board.cmake create mode 100644 boards/realtek/rtl872xda_evb/board.yml create mode 100644 boards/realtek/rtl872xda_evb/doc/index.rst create mode 100644 boards/realtek/rtl872xda_evb/doc/rtl872xda_evb.webp create mode 100644 boards/realtek/rtl872xda_evb/rtl872xda_evb-pinctrl.dtsi create mode 100644 boards/realtek/rtl872xda_evb/rtl872xda_evb.dts create mode 100644 boards/realtek/rtl872xda_evb/rtl872xda_evb.yaml create mode 100644 boards/realtek/rtl872xda_evb/rtl872xda_evb_defconfig diff --git a/boards/realtek/rtl872xda_evb/Kconfig.rtl872xda_evb b/boards/realtek/rtl872xda_evb/Kconfig.rtl872xda_evb new file mode 100644 index 000000000000..f9f0c70e7162 --- /dev/null +++ b/boards/realtek/rtl872xda_evb/Kconfig.rtl872xda_evb @@ -0,0 +1,5 @@ +# Copyright (c) 2024 Realtek Semiconductor Corp. +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_RTL872XDA_EVB + select SOC_RTL8721DX diff --git a/boards/realtek/rtl872xda_evb/board.cmake b/boards/realtek/rtl872xda_evb/board.cmake new file mode 100644 index 000000000000..e63da5e6ab42 --- /dev/null +++ b/boards/realtek/rtl872xda_evb/board.cmake @@ -0,0 +1,6 @@ +# Copyright (c) 2024 Realtek Semiconductor Corp. +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(jlink "--device=Cortex-M55" "--speed=4000") + +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/realtek/rtl872xda_evb/board.yml b/boards/realtek/rtl872xda_evb/board.yml new file mode 100644 index 000000000000..e92ad06fcade --- /dev/null +++ b/boards/realtek/rtl872xda_evb/board.yml @@ -0,0 +1,5 @@ +board: + name: rtl872xda_evb + vendor: realtek + socs: + - name: rtl8721dx diff --git a/boards/realtek/rtl872xda_evb/doc/index.rst b/boards/realtek/rtl872xda_evb/doc/index.rst new file mode 100644 index 000000000000..92e7f5f4b241 --- /dev/null +++ b/boards/realtek/rtl872xda_evb/doc/index.rst @@ -0,0 +1,96 @@ +.. zephyr:board:: rtl872xda_evb + +Overview +******** + +The Realtek RTL8721Dx Series is a Combo SoC that supports dual-band Wi-Fi 4 (2.4GHz + 5GHz) and +BLE 5.0 specifications. With excellent ultra-low power consumption, enhanced encryption strategy +(PSA Level 2), and abundant peripheral resources, it is widely used in smart home appliance, +line controller, smart door lock, battery camera, smart remote controller, Wi-Fi Speaker, Wi-Fi +Full MAC NIC, BLE gateway, and smart POS, etc. For more information, check `RTL872XDA-EVB`_. + +The features include the following: + +- Dual cores: Real-M300 and Real-M200 +- 512KB on-chip SRAM +- 802.11 a/b/g/n 1 x 1, 2.4GHz + 5GHz +- Supports BLE 5.0 +- Peripheral Interface: + + - Multi-communication interfaces: SPI x 2, UART x 4, I2C x 2 + - Hardware Key-Scan interface supports up to 8*8 (64) keys + - Hardware IR transceiver can easily adapt to various IR protocols + - Supports Real-Time Clock timer together with 10 basic timers + - Supports 8 channels of PWM timer and 1 capture timer + - Supports 7 channels of general 12-bit ADC and 1 channel of VBAT + - Supports 4 channels of touch pad + - Supports 8 independent channels of GDMA + - Supports USB 2.0 full-speed device mode + - Supports SDIO device with 1-bit and 4-bit mode + - Embeds a serial LEDC to control the external LED lamps + - Integrated Pixel Processing Engine (PPE) to process pixel data faster + - Integrated OSPI display interface supports screens with OSPI/QSPI/SPI interfaces + - Integrated audio codec supports 2 channels DMIC interface + - I2S x 2: up to 384kHz sampling rate + +- Cryptographic hardware acceleration (TRNG, ECC, SHA-2, AES) + +For more information, Get application note and datasheet at `RTL8721Dx Series`_ depending on chip you use. + +Supported Features +================== + +.. zephyr:board-supported-hw:: + +Prerequisites +************* + +Realtek HAL requires binary blobs in order work. Run the command below to retrieve those files. + +.. code-block:: console + + west blobs fetch hal_realtek + +.. note:: + + It is recommended running the command above after ``west update``. + +Building +******** + +Here is an example for building the :zephyr:code-sample:`hello_world` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: rtl872xda_evb + :goals: buil + +Flashing +******** + +When the build finishes, downloading images into flash by `AmebaImageTool`_: + +See the ApplicationNote chapter Image Tool from documentation links for more details. + +#. Environment Requirements: EX. WinXP, Win 7 or later, Microsoft .NET Framework 4.0. +#. Connect chip and PC with USB wire. +#. Choose the Device profiles according to the chip you use. +#. Select the corresponding serial port and transmission baud rate. The default baud rate is 1500000. +#. Select the images to be programmed and set the start address and end address according to the flash layout, refer to [ameba_flashcfg.c/Flash_layout]. +#. Click the Download button and start. The progress bar will show the download progress of each image and the log window will show the operation status. + +.. note:: + + For an empty chip, the bootloader and app image shall be downloaded. + +Debugging +********* + +Using SWD through PA30(SWD_CLK) and PA31(SWD_DAT). + +References +********** + +.. _`RTL872XDA-EVB`: https://www.realmcu.com/en/Home/Product/add965ea-d661-4a63-9514-d18b6912f8ab# +.. _`RTL8721Dx Series`: https://www.realmcu.com +.. _`AmebaImageTool`: https://github.com/Ameba-AIoT/ameba-rtos/blob/master/tools/ameba/ImageTool/AmebaImageTool.exe diff --git a/boards/realtek/rtl872xda_evb/doc/rtl872xda_evb.webp b/boards/realtek/rtl872xda_evb/doc/rtl872xda_evb.webp new file mode 100644 index 0000000000000000000000000000000000000000..dff4bf60705bed5f2a5d6d421607db4f1900954e GIT binary patch literal 29540 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 TFu<=giMTcUhNob?XaE2JxxIW$ literal 0 HcmV?d00001 diff --git a/boards/realtek/rtl872xda_evb/rtl872xda_evb-pinctrl.dtsi b/boards/realtek/rtl872xda_evb/rtl872xda_evb-pinctrl.dtsi new file mode 100644 index 000000000000..b91aa74f31ad --- /dev/null +++ b/boards/realtek/rtl872xda_evb/rtl872xda_evb-pinctrl.dtsi @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor Corp. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&pinctrl { + compatible = "realtek,ameba-pinctrl"; + + /* PA30 is SWD_CLK, PA31 is SWD_DAT(both pull-up internally) */ + loguart_default: loguart_default { + group1 { + pinmux = , /* RXD */ + ; /* TXD */ + bias-pull-up; + }; + }; +}; diff --git a/boards/realtek/rtl872xda_evb/rtl872xda_evb.dts b/boards/realtek/rtl872xda_evb/rtl872xda_evb.dts new file mode 100644 index 000000000000..c45b01368d0b --- /dev/null +++ b/boards/realtek/rtl872xda_evb/rtl872xda_evb.dts @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor Corp. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include "rtl872xda_evb-pinctrl.dtsi" + +/ { + model = "RealTek AmebaDplus RTL872XDA EVB"; + compatible = "realtek,rtl872xda_evb"; + + chosen { + zephyr,console = &loguart; + zephyr,shell-uart = &loguart; + zephyr,sram = &sram0; + zephyr,flash = &flash0; + }; +}; + +&flash0 { + reg = <0x0e000020 DT_SIZE_M(4)>; +}; + +&loguart { + status = "okay"; +}; diff --git a/boards/realtek/rtl872xda_evb/rtl872xda_evb.yaml b/boards/realtek/rtl872xda_evb/rtl872xda_evb.yaml new file mode 100644 index 000000000000..64e415c56c30 --- /dev/null +++ b/boards/realtek/rtl872xda_evb/rtl872xda_evb.yaml @@ -0,0 +1,16 @@ +# Copyright (c) 2024 Realtek Semiconductor Corp. +# SPDX-License-Identifier: Apache-2.0 + +identifier: rtl872xda_evb +name: Realtek rtl872xda evaluation board +vendor: realtek +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb +ram: 512 +flash: 4096 +supported: + - pinctrl + - serial diff --git a/boards/realtek/rtl872xda_evb/rtl872xda_evb_defconfig b/boards/realtek/rtl872xda_evb/rtl872xda_evb_defconfig new file mode 100644 index 000000000000..3e16c302accf --- /dev/null +++ b/boards/realtek/rtl872xda_evb/rtl872xda_evb_defconfig @@ -0,0 +1,8 @@ +# Copyright (c) 2024 Realtek Semiconductor Corp. +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# Enable LogUart +CONFIG_SERIAL=y From e369c524c34134caa51eb1a9515f6e104765d097 Mon Sep 17 00:00:00 2001 From: zjian zhang Date: Sun, 19 Oct 2025 22:44:41 +0800 Subject: [PATCH 0384/3659] MAINTAINERS: Add hal_realtek as a new HAL module This commit adds maintainers for hal_realtek repository Signed-off-by: zjian zhang --- MAINTAINERS.yml | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index f30cd265aa7e..f4f75861b639 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -4407,6 +4407,20 @@ Raspberry Pi Pico Platforms: labels: - "platform: Raspberry Pi Pico" +Realtek Ameba Platforms: + status: maintained + maintainers: + - zjian-zhang + - Derek-RTK + files: + - drivers/*/*ameba* + - boards/realtek/ + - soc/realtek/ameba/ + - dts/arm/realtek/ameba*/ + - dts/bindings/*/*ameba* + labels: + - "platform: Ameba" + Realtek EC Platforms: status: maintained maintainers: @@ -5766,6 +5780,15 @@ West: labels: - "platform: Quicklogic" +"West project: hal_realtek": + status: maintained + maintainers: + - zjian-zhang + - Derek-RTK + files: [] + labels: + - "platform: Ameba" + "West project: hal_renesas": status: maintained maintainers: From fab5f5745572f08e440f7a38882dae7459ef2f6d Mon Sep 17 00:00:00 2001 From: Jordan Yates Date: Wed, 20 Aug 2025 10:31:16 +1000 Subject: [PATCH 0385/3659] lora: optional disable CRC Add the option to disable the builtin 16 bit CRC on the LoRa payload. Signed-off-by: Jordan Yates --- drivers/lora/lora_basics_modem/lbm_common.c | 2 +- drivers/lora/loramac_node/sx12xx_common.c | 6 ++++-- include/zephyr/drivers/lora.h | 3 +++ 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/lora/lora_basics_modem/lbm_common.c b/drivers/lora/lora_basics_modem/lbm_common.c index 42bea84267ab..7eaed585524e 100644 --- a/drivers/lora/lora_basics_modem/lbm_common.c +++ b/drivers/lora/lora_basics_modem/lbm_common.c @@ -79,7 +79,7 @@ int lbm_lora_config(const struct device *dev, struct lora_modem_config *lora_con .preamble_len_in_symb = lora_config->preamble_len, .header_type = RAL_LORA_PKT_EXPLICIT, .pld_len_in_bytes = UINT8_MAX, - .crc_is_on = true, + .crc_is_on = !lora_config->packet_crc_disable, .invert_iq_is_on = lora_config->iq_inverted, }, .rf_freq_in_hz = lora_config->frequency, diff --git a/drivers/lora/loramac_node/sx12xx_common.c b/drivers/lora/loramac_node/sx12xx_common.c index 25d72ff80611..aba0064b91ef 100644 --- a/drivers/lora/loramac_node/sx12xx_common.c +++ b/drivers/lora/loramac_node/sx12xx_common.c @@ -337,6 +337,8 @@ int sx12xx_lora_recv_async(const struct device *dev, lora_recv_cb cb, void *user int sx12xx_lora_config(const struct device *dev, struct lora_modem_config *config) { + bool crc = !config->packet_crc_disable; + /* Ensure available, decremented after configuration */ if (!modem_acquire(&dev_data)) { return -EBUSY; @@ -351,13 +353,13 @@ int sx12xx_lora_config(const struct device *dev, Radio.SetTxConfig(MODEM_LORA, config->tx_power, 0, config->bandwidth, config->datarate, config->coding_rate, config->preamble_len, - false, true, 0, 0, config->iq_inverted, 4000); + false, crc, 0, 0, config->iq_inverted, 4000); } else { /* TODO: Get symbol timeout value from config parameters */ Radio.SetRxConfig(MODEM_LORA, config->bandwidth, config->datarate, config->coding_rate, 0, config->preamble_len, 10, false, 0, - false, 0, 0, config->iq_inverted, true); + crc, false, 0, config->iq_inverted, true); } Radio.SetPublicNetwork(config->public_network); diff --git a/include/zephyr/drivers/lora.h b/include/zephyr/drivers/lora.h index cb51e50e061a..7267209fa688 100644 --- a/include/zephyr/drivers/lora.h +++ b/include/zephyr/drivers/lora.h @@ -122,6 +122,9 @@ struct lora_modem_config { * interacting with a public network. */ bool public_network; + + /** Set to true to disable the 16-bit payload CRC */ + bool packet_crc_disable; }; /** From 08f74a26389a65ac7cb3f7d03f65ba22890b5966 Mon Sep 17 00:00:00 2001 From: Jordan Yates Date: Tue, 1 Jul 2025 17:25:14 +1000 Subject: [PATCH 0386/3659] lora: add `lora_airtime` Add a simple function that exposes the airtime of a packet of a given length. Use the new internal implementations of the airtime function when calculating TX durations inside the send functions to reduce code duplication on a complex function. Signed-off-by: Jordan Yates --- doc/releases/release-notes-4.4.rst | 4 ++++ drivers/lora/lora_basics_modem/lbm_common.c | 22 +++++++++++++---- drivers/lora/loramac_node/sx126x.c | 1 + drivers/lora/loramac_node/sx127x.c | 1 + drivers/lora/loramac_node/sx12xx_common.c | 19 +++++++++------ drivers/lora/loramac_node/sx12xx_common.h | 2 ++ include/zephyr/drivers/lora.h | 26 +++++++++++++++++++++ 7 files changed, 63 insertions(+), 12 deletions(-) diff --git a/doc/releases/release-notes-4.4.rst b/doc/releases/release-notes-4.4.rst index 9479cb2287be..7aa852d2ac6e 100644 --- a/doc/releases/release-notes-4.4.rst +++ b/doc/releases/release-notes-4.4.rst @@ -232,6 +232,10 @@ DeviceTree Libraries / Subsystems ********************** +* LoRa/LoRaWAN + + * :c:func:`lora_airtime` + Other notable changes ********************* diff --git a/drivers/lora/lora_basics_modem/lbm_common.c b/drivers/lora/lora_basics_modem/lbm_common.c index 7eaed585524e..9edb6b8c74c2 100644 --- a/drivers/lora/lora_basics_modem/lbm_common.c +++ b/drivers/lora/lora_basics_modem/lbm_common.c @@ -122,6 +122,20 @@ int lbm_lora_config(const struct device *dev, struct lora_modem_config *lora_con return ret; } +uint32_t lbm_lora_airtime(const struct device *dev, uint32_t data_len) +{ + const struct lbm_lora_config_common *config = dev->config; + struct lbm_lora_data_common *data = dev->data; + + /* Updating the internal variable is fine since it is only used by ral_set_lora_pkt_params + * in lbm_lora_send_async, and the value is set there immediately before use. + */ + data->pkt_params.pld_len_in_bytes = data_len; + + return ral_get_lora_time_on_air_in_ms(&config->ralf.ral, &data->pkt_params, + &data->mod_params); +} + int lbm_lora_send_async(const struct device *dev, uint8_t *msg, uint32_t msg_len, struct k_poll_signal *async) { @@ -182,8 +196,6 @@ int lbm_lora_send_async(const struct device *dev, uint8_t *msg, uint32_t msg_len int lbm_lora_send(const struct device *dev, uint8_t *msg, uint32_t msg_len) { - const struct lbm_lora_config_common *config = dev->config; - struct lbm_lora_data_common *data = dev->data; struct k_poll_signal done = K_POLL_SIGNAL_INITIALIZER(done); struct k_poll_event evt = K_POLL_EVENT_INITIALIZER(K_POLL_TYPE_SIGNAL, K_POLL_MODE_NOTIFY_ONLY, &done); @@ -197,9 +209,8 @@ int lbm_lora_send(const struct device *dev, uint8_t *msg, uint32_t msg_len) } /* Calculate expected airtime of the packet */ - air_time = ral_get_lora_time_on_air_in_ms(&config->ralf.ral, &data->pkt_params, - &data->mod_params); - LOG_DBG("Expected airtime: %d ms", air_time); + air_time = lbm_lora_airtime(dev, msg_len); + LOG_DBG("Expected air time of %u bytes = %u ms", msg_len, air_time); /* Wait for the packet to finish transmitting. * Setting up the transaction takes some minimal time, take it into @@ -547,6 +558,7 @@ int lbm_lora_common_init(const struct device *dev) DEVICE_API(lora, lbm_lora_api) = { .config = lbm_lora_config, + .airtime = lbm_lora_airtime, .send = lbm_lora_send, .send_async = lbm_lora_send_async, .recv = lbm_lora_recv, diff --git a/drivers/lora/loramac_node/sx126x.c b/drivers/lora/loramac_node/sx126x.c index 6221943f5200..a1de81b0a687 100644 --- a/drivers/lora/loramac_node/sx126x.c +++ b/drivers/lora/loramac_node/sx126x.c @@ -465,6 +465,7 @@ static int sx126x_lora_init(const struct device *dev) static DEVICE_API(lora, sx126x_lora_api) = { .config = sx12xx_lora_config, + .airtime = sx12xx_airtime, .send = sx12xx_lora_send, .send_async = sx12xx_lora_send_async, .recv = sx12xx_lora_recv, diff --git a/drivers/lora/loramac_node/sx127x.c b/drivers/lora/loramac_node/sx127x.c index d478b4081c71..a7c65ac57a9f 100644 --- a/drivers/lora/loramac_node/sx127x.c +++ b/drivers/lora/loramac_node/sx127x.c @@ -627,6 +627,7 @@ static int sx127x_lora_init(const struct device *dev) static DEVICE_API(lora, sx127x_lora_api) = { .config = sx12xx_lora_config, + .airtime = sx12xx_airtime, .send = sx12xx_lora_send, .send_async = sx12xx_lora_send_async, .recv = sx12xx_lora_recv, diff --git a/drivers/lora/loramac_node/sx12xx_common.c b/drivers/lora/loramac_node/sx12xx_common.c index aba0064b91ef..8c86dc913c2e 100644 --- a/drivers/lora/loramac_node/sx12xx_common.c +++ b/drivers/lora/loramac_node/sx12xx_common.c @@ -192,6 +192,16 @@ static void sx12xx_ev_rx_error(void) } } +uint32_t sx12xx_airtime(const struct device *dev, uint32_t data_len) +{ + return Radio.TimeOnAir(MODEM_LORA, + dev_data.tx_cfg.bandwidth, + dev_data.tx_cfg.datarate, + dev_data.tx_cfg.coding_rate, + dev_data.tx_cfg.preamble_len, + 0, data_len, !dev_data.tx_cfg.packet_crc_disable); +} + int sx12xx_lora_send(const struct device *dev, uint8_t *data, uint32_t data_len) { @@ -214,13 +224,8 @@ int sx12xx_lora_send(const struct device *dev, uint8_t *data, } /* Calculate expected airtime of the packet */ - air_time = Radio.TimeOnAir(MODEM_LORA, - dev_data.tx_cfg.bandwidth, - dev_data.tx_cfg.datarate, - dev_data.tx_cfg.coding_rate, - dev_data.tx_cfg.preamble_len, - 0, data_len, true); - LOG_DBG("Expected air time of %d bytes = %dms", data_len, air_time); + air_time = sx12xx_airtime(dev, data_len); + LOG_DBG("Expected air time of %u bytes = %u ms", data_len, air_time); /* Wait for the packet to finish transmitting. * Use twice the tx duration to ensure that we are actually detecting diff --git a/drivers/lora/loramac_node/sx12xx_common.h b/drivers/lora/loramac_node/sx12xx_common.h index 2a26485f2c07..60706436977c 100644 --- a/drivers/lora/loramac_node/sx12xx_common.h +++ b/drivers/lora/loramac_node/sx12xx_common.h @@ -31,6 +31,8 @@ int sx12xx_lora_recv(const struct device *dev, uint8_t *data, uint8_t size, int sx12xx_lora_recv_async(const struct device *dev, lora_recv_cb cb, void *user_data); +uint32_t sx12xx_airtime(const struct device *dev, uint32_t data_len); + int sx12xx_lora_config(const struct device *dev, struct lora_modem_config *config); diff --git a/include/zephyr/drivers/lora.h b/include/zephyr/drivers/lora.h index 7267209fa688..f224b4f05429 100644 --- a/include/zephyr/drivers/lora.h +++ b/include/zephyr/drivers/lora.h @@ -151,6 +151,14 @@ typedef void (*lora_recv_cb)(const struct device *dev, uint8_t *data, uint16_t s typedef int (*lora_api_config)(const struct device *dev, struct lora_modem_config *config); +/** + * @typedef lora_api_airtime() + * @brief Callback API for querying packet airtime + * + * @see lora_airtime() for argument descriptions. + */ +typedef uint32_t (*lora_api_airtime)(const struct device *dev, uint32_t data_len); + /** * @typedef lora_api_send() * @brief Callback API for sending data over LoRa @@ -201,6 +209,7 @@ typedef int (*lora_api_test_cw)(const struct device *dev, uint32_t frequency, __subsystem struct lora_driver_api { lora_api_config config; + lora_api_airtime airtime; lora_api_send send; lora_api_send_async send_async; lora_api_recv recv; @@ -227,6 +236,23 @@ static inline int lora_config(const struct device *dev, return api->config(dev, config); } +/** + * @brief Query the airtime of a packet with a given length + * + * @note Uses the current radio configuration from @ref lora_config + * + * @param dev LoRa device + * @param data_len Length of the data + * @return Airtime of packet in milliseconds + */ +static inline uint32_t lora_airtime(const struct device *dev, uint32_t data_len) +{ + const struct lora_driver_api *api = + (const struct lora_driver_api *)dev->api; + + return api->airtime(dev, data_len); +} + /** * @brief Send data over LoRa * From 3514ff9fe2fa811c70fb57eba949c15c45d472df Mon Sep 17 00:00:00 2001 From: Jordan Yates Date: Mon, 15 Dec 2025 10:26:42 +1000 Subject: [PATCH 0387/3659] samples: lora: zero initialise config structure Zero initialise the configuration struct to ensure non-set fields are zero. Signed-off-by: Jordan Yates --- samples/drivers/lora/receive/src/main.c | 2 +- samples/drivers/lora/send/src/main.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/samples/drivers/lora/receive/src/main.c b/samples/drivers/lora/receive/src/main.c index db42583860b0..c32d614d14a2 100644 --- a/samples/drivers/lora/receive/src/main.c +++ b/samples/drivers/lora/receive/src/main.c @@ -42,7 +42,7 @@ void lora_receive_cb(const struct device *dev, uint8_t *data, uint16_t size, int main(void) { const struct device *const lora_dev = DEVICE_DT_GET(DEFAULT_RADIO_NODE); - struct lora_modem_config config; + struct lora_modem_config config = {0}; int ret, len; uint8_t data[MAX_DATA_LEN] = {0}; int16_t rssi; diff --git a/samples/drivers/lora/send/src/main.c b/samples/drivers/lora/send/src/main.c index fa8288c5a5f5..a3400639c4af 100644 --- a/samples/drivers/lora/send/src/main.c +++ b/samples/drivers/lora/send/src/main.c @@ -25,7 +25,7 @@ char data[MAX_DATA_LEN] = {'h', 'e', 'l', 'l', 'o', 'w', 'o', 'r', 'l', 'd', ' ' int main(void) { const struct device *const lora_dev = DEVICE_DT_GET(DEFAULT_RADIO_NODE); - struct lora_modem_config config; + struct lora_modem_config config = {0}; int ret; if (!device_is_ready(lora_dev)) { From 6b8ad0b48b30619205b78c38d61a19bb2f2663bf Mon Sep 17 00:00:00 2001 From: Jordan Yates Date: Wed, 3 Sep 2025 10:35:30 +1000 Subject: [PATCH 0388/3659] samples: lora: send: display packet airtime Display the expected airtime of the transmitted packet at the start of the sample. Signed-off-by: Jordan Yates --- samples/drivers/lora/send/src/main.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/samples/drivers/lora/send/src/main.c b/samples/drivers/lora/send/src/main.c index a3400639c4af..731c92db0b08 100644 --- a/samples/drivers/lora/send/src/main.c +++ b/samples/drivers/lora/send/src/main.c @@ -49,6 +49,8 @@ int main(void) return 0; } + LOG_INF("Expected packet airtime: %u ms", lora_airtime(lora_dev, MAX_DATA_LEN)); + while (1) { ret = lora_send(lora_dev, data, MAX_DATA_LEN); if (ret < 0) { From 5df9d8d176680dacd08f3ec65ce25c60dfe43145 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johan=20Alfv=C3=A9n?= Date: Mon, 24 Nov 2025 09:52:16 +0100 Subject: [PATCH 0389/3659] MAINTAINERS: add hal_ethos_u collaborator MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add johan-alfven-arm as collaborator for hal_ethos_u driver Signed-off-by: Johan Alfvén --- MAINTAINERS.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index f4f75861b639..1c5d3528fe1c 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -5652,6 +5652,7 @@ West: collaborators: - ithinuel - ccli8 + - johan-alfven-arm files: - drivers/misc/ethos_u/ - modules/hal_ethos_u/ From 79d841a6004e4edb22cccc72e503cac37022cf49 Mon Sep 17 00:00:00 2001 From: Muhammed Asif Date: Mon, 3 Nov 2025 16:59:01 +0530 Subject: [PATCH 0390/3659] dts: arm: microchip: add dts nodes of tc peripheral Adds binding yaml for tc peripheral Adds the dts nodes for tc peripheral for same5xd5x series and its default configurations. Signed-off-by: Muhammed Asif --- .../sam/sam_d5x_e5x/common/samd5xe5x.dtsi | 55 ++++++++++++ .../sam/sam_d5x_e5x/common/samd5xe5x_j.dtsi | 24 ++++++ .../sam/sam_d5x_e5x/common/samd5xe5x_n.dtsi | 48 +++++++++++ .../sam/sam_d5x_e5x/common/samd5xe5x_p.dtsi | 48 +++++++++++ dts/bindings/counter/microchip,tc-g1.yaml | 85 +++++++++++++++++++ 5 files changed, 260 insertions(+) create mode 100644 dts/bindings/counter/microchip,tc-g1.yaml diff --git a/dts/arm/microchip/sam/sam_d5x_e5x/common/samd5xe5x.dtsi b/dts/arm/microchip/sam/sam_d5x_e5x/common/samd5xe5x.dtsi index 8c652b3827a9..dd3cc0c8e72b 100644 --- a/dts/arm/microchip/sam/sam_d5x_e5x/common/samd5xe5x.dtsi +++ b/dts/arm/microchip/sam/sam_d5x_e5x/common/samd5xe5x.dtsi @@ -131,6 +131,33 @@ clock-names = "mclk", "gclk"; }; + tc0: tc@40003800 { + compatible = "microchip,tc-g1"; + reg = <0x40003800 0x400>; + interrupts = <107 0>; + clocks = <&mclkperiph CLOCK_MCHP_MCLKPERIPH_ID_APBA_TC0>, + <&gclkperiph CLOCK_MCHP_GCLKPERIPH_ID_TC0>, + <&mclkperiph CLOCK_MCHP_MCLKPERIPH_ID_APBA_TC1>; + clock-names = "mclk", "gclk", "client_mclk"; + max-bit-width = <16>; + prescaler = <1>; + channels = <2>; + status = "disabled"; + }; + + tc1: tc@40003c00 { + compatible = "microchip,tc-g1"; + reg = <0x40003c00 0x400>; + interrupts = <108 0>; + clocks = <&mclkperiph CLOCK_MCHP_MCLKPERIPH_ID_APBA_TC1>, + <&gclkperiph CLOCK_MCHP_GCLKPERIPH_ID_TC1>; + clock-names = "mclk", "gclk"; + max-bit-width = <16>; + prescaler = <1>; + channels = <2>; + status = "disabled"; + }; + nvmctrl: nvmctrl@41004000 { compatible = "microchip,nvmctrl-g1-flash"; status = "okay"; @@ -232,6 +259,34 @@ clock-names = "mclk", "gclk"; max-bit-width = <24>; channels = <4>; + status = "disabled"; + }; + + tc2: tc@4101a000 { + compatible = "microchip,tc-g1"; + reg = <0x4101a000 0x400>; + interrupts = <109 0>; + clocks = <&mclkperiph CLOCK_MCHP_MCLKPERIPH_ID_APBB_TC2>, + <&gclkperiph CLOCK_MCHP_GCLKPERIPH_ID_TC2>, + <&mclkperiph CLOCK_MCHP_MCLKPERIPH_ID_APBB_TC3>; + clock-names = "mclk", "gclk", "client_mclk"; + max-bit-width = <16>; + prescaler = <1>; + channels = <2>; + status = "disabled"; + }; + + tc3: tc@4101c000 { + compatible = "microchip,tc-g1"; + reg = <0x4101c000 0x400>; + interrupts = <110 0>; + clocks = <&mclkperiph CLOCK_MCHP_MCLKPERIPH_ID_APBB_TC3>, + <&gclkperiph CLOCK_MCHP_GCLKPERIPH_ID_TC3>; + clock-names = "mclk", "gclk"; + max-bit-width = <16>; + prescaler = <1>; + channels = <2>; + status = "disabled"; }; tcc2: tcc@42000c00 { diff --git a/dts/arm/microchip/sam/sam_d5x_e5x/common/samd5xe5x_j.dtsi b/dts/arm/microchip/sam/sam_d5x_e5x/common/samd5xe5x_j.dtsi index bb544fe11b2d..30b19f837751 100644 --- a/dts/arm/microchip/sam/sam_d5x_e5x/common/samd5xe5x_j.dtsi +++ b/dts/arm/microchip/sam/sam_d5x_e5x/common/samd5xe5x_j.dtsi @@ -19,6 +19,30 @@ channels = <2>; }; + tc4: tc@42001400 { + compatible = "microchip,tc-g1"; + reg = <0x42001400 0x400>; + interrupts = <111 0>; + clocks = <&mclkperiphperiph CLOCK_MCHP_MCLKPERIPH_ID_APBC_TC4>, + <&gclkperiph CLOCK_MCHP_GCLKPERIPH_ID_TC4>; + clock-names = "mclk", "gclk"; + max-bit-width = <16>; + channels = <2>; + status = "disabled"; + }; + + tc5: tc@42001800 { + compatible = "microchip,tc-g1"; + reg = <0x42001800 0x400>; + interrupts = <112 0>; + clocks = <&mclkperiphperiph CLOCK_MCHP_MCLKPERIPH_ID_APBC_TC5>, + <&gclkperiph CLOCK_MCHP_GCLKPERIPH_ID_TC5>; + clock-names = "mclk", "gclk"; + max-bit-width = <16>; + channels = <2>; + status = "disabled"; + }; + tcc4: tcc@43001000 { compatible = "microchip,tcc-g1"; reg = <0x43001000 0x2000>; diff --git a/dts/arm/microchip/sam/sam_d5x_e5x/common/samd5xe5x_n.dtsi b/dts/arm/microchip/sam/sam_d5x_e5x/common/samd5xe5x_n.dtsi index da9349c368d7..a2c252691599 100644 --- a/dts/arm/microchip/sam/sam_d5x_e5x/common/samd5xe5x_n.dtsi +++ b/dts/arm/microchip/sam/sam_d5x_e5x/common/samd5xe5x_n.dtsi @@ -19,6 +19,30 @@ channels = <2>; }; + tc4: tc@42001400 { + compatible = "microchip,tc-g1"; + reg = <0x42001400 0x400>; + interrupts = <111 0>; + clocks = <&mclkperiph CLOCK_MCHP_MCLKPERIPH_ID_APBC_TC4>, + <&gclkperiph CLOCK_MCHP_GCLKPERIPH_ID_TC4>; + clock-names = "mclk", "gclk"; + max-bit-width = <16>; + channels = <2>; + status = "disabled"; + }; + + tc5: tc@42001800 { + compatible = "microchip,tc-g1"; + reg = <0x42001800 0x400>; + interrupts = <112 0>; + clocks = <&mclkperiph CLOCK_MCHP_MCLKPERIPH_ID_APBC_TC5>, + <&gclkperiph CLOCK_MCHP_GCLKPERIPH_ID_TC5>; + clock-names = "mclk", "gclk"; + max-bit-width = <16>; + channels = <2>; + status = "disabled"; + }; + sercom6: sercom@43000800 { compatible = "microchip,sercom-g1"; status = "disabled"; @@ -50,6 +74,30 @@ max-bit-width = <16>; channels = <2>; }; + + tc6: tc@43001400 { + compatible = "microchip,tc-g1"; + reg = <0x43001400 0x400>; + interrupts = <113 0>; + clocks = <&mclkperiph CLOCK_MCHP_MCLKPERIPH_ID_APBD_TC6>, + <&gclkperiph CLOCK_MCHP_GCLKPERIPH_ID_TC6>; + clock-names = "mclk", "gclk"; + max-bit-width = <16>; + channels = <2>; + status = "disabled"; + }; + + tc7: tc@43001800 { + compatible = "microchip,tc-g1"; + reg = <0x43001800 0x400>; + interrupts = <114 0>; + clocks = <&mclkperiph CLOCK_MCHP_MCLKPERIPH_ID_APBD_TC7>, + <&gclkperiph CLOCK_MCHP_GCLKPERIPH_ID_TC7>; + clock-names = "mclk", "gclk"; + max-bit-width = <16>; + channels = <2>; + status = "disabled"; + }; }; }; diff --git a/dts/arm/microchip/sam/sam_d5x_e5x/common/samd5xe5x_p.dtsi b/dts/arm/microchip/sam/sam_d5x_e5x/common/samd5xe5x_p.dtsi index b6bc835e9326..ac71565163d8 100644 --- a/dts/arm/microchip/sam/sam_d5x_e5x/common/samd5xe5x_p.dtsi +++ b/dts/arm/microchip/sam/sam_d5x_e5x/common/samd5xe5x_p.dtsi @@ -19,6 +19,30 @@ channels = <2>; }; + tc4: tc@42001400 { + compatible = "microchip,tc-g1"; + reg = <0x42001400 0x400>; + interrupts = <111 0>; + clocks = <&mclkperiph CLOCK_MCHP_MCLKPERIPH_ID_APBC_TC4>, + <&gclkperiph CLOCK_MCHP_GCLKPERIPH_ID_TC4>; + clock-names = "mclk", "gclk"; + max-bit-width = <16>; + channels = <2>; + status = "disabled"; + }; + + tc5: tc@42001800 { + compatible = "microchip,tc-g1"; + reg = <0x42001800 0x400>; + interrupts = <112 0>; + clocks = <&mclkperiph CLOCK_MCHP_MCLKPERIPH_ID_APBC_TC5>, + <&gclkperiph CLOCK_MCHP_GCLKPERIPH_ID_TC5>; + clock-names = "mclk", "gclk"; + max-bit-width = <16>; + channels = <2>; + status = "disabled"; + }; + sercom6: sercom@43000800 { compatible = "microchip,sercom-g1"; status = "disabled"; @@ -50,6 +74,30 @@ max-bit-width = <16>; channels = <2>; }; + + tc6: tc@43001400 { + compatible = "microchip,tc-g1"; + reg = <0x43001400 0x400>; + interrupts = <113 0>; + clocks = <&mclkperiph CLOCK_MCHP_MCLKPERIPH_ID_APBD_TC6>, + <&gclkperiph CLOCK_MCHP_GCLKPERIPH_ID_TC6>; + clock-names = "mclk", "gclk"; + max-bit-width = <16>; + channels = <2>; + status = "disabled"; + }; + + tc7: tc@43001800 { + compatible = "microchip,tc-g1"; + reg = <0x43001800 0x400>; + interrupts = <114 0>; + clocks = <&mclkperiph CLOCK_MCHP_MCLKPERIPH_ID_APBD_TC7>, + <&gclkperiph CLOCK_MCHP_GCLKPERIPH_ID_TC7>; + clock-names = "mclk", "gclk"; + max-bit-width = <16>; + channels = <2>; + status = "disabled"; + }; }; }; diff --git a/dts/bindings/counter/microchip,tc-g1.yaml b/dts/bindings/counter/microchip,tc-g1.yaml new file mode 100644 index 000000000000..c433fb484439 --- /dev/null +++ b/dts/bindings/counter/microchip,tc-g1.yaml @@ -0,0 +1,85 @@ +# Copyright (c) 2025 Microchip Technology Inc. +# SPDX-License-Identifier: Apache-2.0 +title: Microchip TC g1 peripheral. + +description: | + Microchip TC g1 peripheral. + + It is used for creating the PWM output on different channels + as well as used as a timer/counter. + This yaml supports the following peripherals + - tc-u2249 (3.0.0) + +compatible: "microchip,tc-g1" + +include: + - name: base.yaml + - name: pinctrl-device.yaml + +properties: + reg: + description: | + Specifies the base address and size of the register set for the timer counter peripheral. + required: true + + interrupts: + description: | + Defines the interrupt lines used by the timer counter peripheral. + + This property specifies the interrupt number and priority. + required: true + + clocks: + description: | + Specifies the clock sources and their configurations for the timer counter peripheral. + + This property ensures the peripheral is provided with the necessary clock signals. + The following are the clock names applicable to this property. + - mclk + - gclk + - client_mclk : This is the clock subsystem of the client with + which the instance can be paired. This is an optional clock name. + It is only applicable to those peripherals which can be paired with another + instance for achieving a higher max bit width. In this particular case, + 32-bit max-bit-width is attained by pairing two such instances. The ability for + an instance to pair with another instance attain higher max-bit-width will be + specified in their respective datasheets.It is not available for all the instances. + required: true + + prescaler: + type: int + enum: + - 1 + - 2 + - 4 + - 8 + - 16 + - 64 + - 256 + - 1024 + description: | + Timer prescaler values. + + The prescaler divides the input clock frequency to + achieve the desired timer frequency. + + channels: + type: int + required: true + description: | + This property indicates the maximum available channels in a peripheral instance + + max-bit-width: + type: int + required: true + enum: + - 8 + - 16 + - 32 + description: | + Maximum bit width supported by the PWM counter. + + This property specifies the resolution of the counter. The value provided + in the device tree should reflect the maximum supported by the hardware + instance. It should only be overridden after consulting the relevant family + datasheet to ensure compatibility. From b926d8553514c892f2618ab5c5883bfd5e6547e1 Mon Sep 17 00:00:00 2001 From: Muhammed Asif Date: Mon, 3 Nov 2025 17:32:46 +0530 Subject: [PATCH 0391/3659] dts: bindings: microchip: add tc binding for pwm peripheral Adds binding YAML for pwm using tc peripheral Signed-off-by: Muhammed Asif --- dts/bindings/pwm/microchip,tc-g1-pwm.yaml | 43 +++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 dts/bindings/pwm/microchip,tc-g1-pwm.yaml diff --git a/dts/bindings/pwm/microchip,tc-g1-pwm.yaml b/dts/bindings/pwm/microchip,tc-g1-pwm.yaml new file mode 100644 index 000000000000..1481aa4c8843 --- /dev/null +++ b/dts/bindings/pwm/microchip,tc-g1-pwm.yaml @@ -0,0 +1,43 @@ +# Copyright (c) 2025 Microchip Technology Inc. +# SPDX-License-Identifier: Apache-2.0 +title: Microchip PWM TC g1 driver. + +description: | + Microchip PWM TC g1 driver. + + This driver is responsible for configuring + and managing the TC peripheral in Microchip microcontrollers for PWM configuration. + The supported devices : + - tc-u2249 (3.0.0) + + Example usage in a Device Tree Source (DTS) file: + + pwm_led0: pwm_led_0 { + status = "okay"; + pwms = <&tc0 1 PWM_MSEC(20) 0>; + }; + + Explanation: + - 'pwm_led0' is a node representing a device (e.g., an LED) controlled by PWM. + - The 'pwms' property uses the phandle to the PWM controller (here, 'tc0'), + specifies channel 2, sets the PWM period to 20 milliseconds, + and uses a polarity of 0 (normal). + - The order of the 'pwms' arguments matches the 'pwm-cells' definition: + <&controller channel period polarity> + - This allows the device to be driven with a specific PWM configuration using + the Microchip PWM TC driver. + +compatible: "microchip,tc-g1-pwm" + +include: + - pwm-controller.yaml + - microchip,tc-g1.yaml + +properties: + "#pwm-cells": + const: 3 + +pwm-cells: + - channel + - period + - polarity From 20d7d23d530f45cdf4f5b95a271ba4e9f4738ca4 Mon Sep 17 00:00:00 2001 From: Muhammed Asif Date: Mon, 3 Nov 2025 17:35:50 +0530 Subject: [PATCH 0392/3659] drivers: pwm: microchip: add support for pwm tc g1 Add pwm driver using tc g1 peripheral. Adds the support for generating pwm output. Supports 8-bit, 16-bit and 32-bit mode of tc peripheral Signed-off-by: Muhammed Asif --- drivers/pwm/CMakeLists.txt | 1 + drivers/pwm/Kconfig.mchp | 7 + drivers/pwm/pwm_mchp_tc_g1.c | 812 +++++++++++++++++++++++++++++++++++ 3 files changed, 820 insertions(+) create mode 100644 drivers/pwm/pwm_mchp_tc_g1.c diff --git a/drivers/pwm/CMakeLists.txt b/drivers/pwm/CMakeLists.txt index 2cd435b65b6f..b8d59336afd5 100644 --- a/drivers/pwm/CMakeLists.txt +++ b/drivers/pwm/CMakeLists.txt @@ -31,6 +31,7 @@ zephyr_library_sources_ifdef(CONFIG_PWM_LITEX pwm_litex.c) zephyr_library_sources_ifdef(CONFIG_PWM_MAX31790 pwm_max31790.c) zephyr_library_sources_ifdef(CONFIG_PWM_MAX32 pwm_max32.c) zephyr_library_sources_ifdef(CONFIG_PWM_MCHP_G1_TCC pwm_mchp_tcc_g1.c) +zephyr_library_sources_ifdef(CONFIG_PWM_MCHP_TC_G1 pwm_mchp_tc_g1.c) zephyr_library_sources_ifdef(CONFIG_PWM_MCUX pwm_mcux.c) zephyr_library_sources_ifdef(CONFIG_PWM_MCUX_CTIMER pwm_mcux_ctimer.c) zephyr_library_sources_ifdef(CONFIG_PWM_MCUX_FTM pwm_mcux_ftm.c) diff --git a/drivers/pwm/Kconfig.mchp b/drivers/pwm/Kconfig.mchp index d468b0ee49b5..7a28e093135e 100644 --- a/drivers/pwm/Kconfig.mchp +++ b/drivers/pwm/Kconfig.mchp @@ -11,4 +11,11 @@ config PWM_MCHP_G1_TCC help Enable the Microchip Pulse Width Modulation(PWM) driver. +config PWM_MCHP_TC_G1 + bool "Microchip TC G1 PWM driver" + default y + depends on DT_HAS_MICROCHIP_TC_G1_PWM_ENABLED + select PINCTRL + help + Enable the Microchip Pulse Width Modulation(PWM) driver. endmenu diff --git a/drivers/pwm/pwm_mchp_tc_g1.c b/drivers/pwm/pwm_mchp_tc_g1.c new file mode 100644 index 000000000000..8df5d0194bd6 --- /dev/null +++ b/drivers/pwm/pwm_mchp_tc_g1.c @@ -0,0 +1,812 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include + +#define DT_DRV_COMPAT microchip_tc_g1_pwm + +LOG_MODULE_REGISTER(pwm_mchp_tc_g1, CONFIG_PWM_LOG_LEVEL); + +#define PWM_MODE8(pwm_reg) ((tc_count8_registers_t *)&(((tc_registers_t *)(pwm_reg))->COUNT8)) +#define PWM_MODE16(pwm_reg) ((tc_count16_registers_t *)&(((tc_registers_t *)(pwm_reg))->COUNT16)) +#define PWM_MODE32(pwm_reg) ((tc_count32_registers_t *)&(((tc_registers_t *)(pwm_reg))->COUNT32)) + +#define MCHP_PWM_SUCCESS 0 + +#define MCHP_PWM_LOCK_TIMEOUT K_MSEC(10) + +#define TIMEOUT_VALUE_US 5000000 +#define DELAY_US 2 + +enum pwm_counter_modes { + BIT_MODE_8 = 8, + BIT_MODE_16 = 16, + BIT_MODE_24 = 24, + BIT_MODE_32 = 32, +}; + +enum pwm_prescale_modes { + PWM_PRESCALE_1 = 1, + PWM_PRESCALE_2 = 2, + PWM_PRESCALE_4 = 4, + PWM_PRESCALE_8 = 8, + PWM_PRESCALE_16 = 16, + PWM_PRESCALE_32 = 32, + PWM_PRESCALE_64 = 64, + PWM_PRESCALE_128 = 128, + PWM_PRESCALE_256 = 256, + PWM_PRESCALE_512 = 512, + PWM_PRESCALE_1024 = 1024 +}; + +struct pwm_mchp_data { + struct k_mutex lock; +}; + +struct mchp_pwm_clock { + const struct device *clock_dev; + clock_control_subsys_t host_mclk; + clock_control_subsys_t client_mclk; + clock_control_subsys_t host_gclk; +}; + +struct pwm_mchp_config { + void *regs; /*Pointer to PWM peripheral registers */ + uint32_t max_bit_width; /* Used for finding the mode of tc peripheral */ + struct mchp_pwm_clock pwm_clock; + const struct pinctrl_dev_config *pinctrl_config; + uint16_t prescaler; + uint8_t channels; /* Number of PWM channels */ + uint32_t freq; /* Frequency of the PWM signal */ +}; + +/* + *This function maps a given prescaler constant to its corresponding numerical + *value. If the prescaler does not match any predefined constants, it returns 0. + */ +static uint32_t tc_get_prescale_val(uint32_t prescaler) +{ + uint32_t prescaler_val; + + switch (prescaler) { + case PWM_PRESCALE_1: + prescaler_val = TC_CTRLA_PRESCALER_DIV1; + break; + case PWM_PRESCALE_2: + prescaler_val = TC_CTRLA_PRESCALER_DIV2; + break; + case PWM_PRESCALE_4: + prescaler_val = TC_CTRLA_PRESCALER_DIV4; + break; + case PWM_PRESCALE_8: + prescaler_val = TC_CTRLA_PRESCALER_DIV8; + break; + case PWM_PRESCALE_16: + prescaler_val = TC_CTRLA_PRESCALER_DIV16; + break; + case PWM_PRESCALE_64: + prescaler_val = TC_CTRLA_PRESCALER_DIV64; + break; + case PWM_PRESCALE_256: + prescaler_val = TC_CTRLA_PRESCALER_DIV256; + break; + case PWM_PRESCALE_1024: + prescaler_val = TC_CTRLA_PRESCALER_DIV1024; + break; + default: + prescaler_val = TC_CTRLA_PRESCALER_DIV1; + LOG_ERR("Unsupported prescaler specified in dts. Initialising with default " + "prescaler of DIV1"); + break; + } + + return prescaler_val; +} + +/* + * This function will check whether the tc peripheral is in slave mode or not. + * This is for ensuring that the tc peripheral will not be configured if it is chained to a host tc + * peripheral to achieve 32 bit mode. + */ +static bool check_slave_status(const void *pwm_reg) +{ + bool ret; + + ret = ((PWM_MODE8(pwm_reg)->TC_STATUS & TC_STATUS_SLAVE_Msk) != 0) ? true : false; + LOG_DBG("%s", (ret ? "tc is a slave" : "tc is not a slave")); + + return ret; +} + +static void tc_sync_wait(const void *pwm_reg, const uint32_t max_bit_width) +{ + switch (max_bit_width) { + case BIT_MODE_8: + if ((WAIT_FOR((0 == (PWM_MODE8(pwm_reg)->TC_SYNCBUSY)), TIMEOUT_VALUE_US, + k_busy_wait(DELAY_US))) == false) { + LOG_ERR("TC_SYNCBUSY8 reset timed out"); + } + break; + + case BIT_MODE_16: + if ((WAIT_FOR((0 == (PWM_MODE16(pwm_reg)->TC_SYNCBUSY)), TIMEOUT_VALUE_US, + k_busy_wait(DELAY_US))) == false) { + LOG_ERR("TC_SYNCBUSY16 reset timed out"); + } + break; + + case BIT_MODE_32: + if ((WAIT_FOR((0 == (PWM_MODE32(pwm_reg)->TC_SYNCBUSY)), TIMEOUT_VALUE_US, + k_busy_wait(DELAY_US))) == false) { + LOG_ERR("TC_SYNCBUSY32 reset timed out"); + } + break; + + default: + LOG_ERR("%s : Unsupported PWM mode %d", __func__, max_bit_width); + break; + } +} + +/* + *This function resets the TC registers for the given PWM. + *It sets the TC_CTRLA register to initiate a software reset based on the + *max_bit_width. After setting the reset, it waits for synchronization to + *complete. + */ +static int tc_reset_regs(const void *pwm_reg, const uint32_t max_bit_width) +{ + bool slave_mode = check_slave_status(pwm_reg); + + if (slave_mode == true) { + LOG_ERR("tc is in slave mode"); + return -EBUSY; + } + + switch (max_bit_width) { + case BIT_MODE_8: + PWM_MODE8(pwm_reg)->TC_CTRLA = TC_CTRLA_SWRST(1); + break; + + case BIT_MODE_16: + PWM_MODE16(pwm_reg)->TC_CTRLA = TC_CTRLA_SWRST(1); + break; + + case BIT_MODE_32: + PWM_MODE32(pwm_reg)->TC_CTRLA = TC_CTRLA_SWRST(1); + break; + + default: + LOG_ERR("%s : Unsupported PWM mode %d", __func__, max_bit_width); + return -ENOTSUP; + } + LOG_DBG("%s invoked %d", __func__, max_bit_width); + tc_sync_wait(pwm_reg, max_bit_width); + + return MCHP_PWM_SUCCESS; +} + +/* + * This function enables or disables the TC based on the enable parameter. + * It sets or clears the TC_CTRLA_ENABLE bit in the TC_CTRLA register based on + * the max_bit_width. After setting or clearing the enable bit, it waits for + * synchronization to complete. + */ +static int32_t tc_enable(const void *pwm_reg, const uint32_t max_bit_width, bool enable) +{ + bool slave_mode = check_slave_status(pwm_reg); + + if (slave_mode == true) { + LOG_ERR("tc is in slave mode"); + return -EBUSY; + } + + switch (max_bit_width) { + case BIT_MODE_8: + if (enable != 0) { + PWM_MODE8(pwm_reg)->TC_CTRLA |= TC_CTRLA_ENABLE(1); + } else { + PWM_MODE8(pwm_reg)->TC_CTRLA &= ~TC_CTRLA_ENABLE(1); + } + LOG_DBG("%s %d invoked 0x%x", __func__, enable, PWM_MODE8(pwm_reg)->TC_CTRLA); + break; + + case BIT_MODE_16: + if (enable != 0) { + PWM_MODE16(pwm_reg)->TC_CTRLA |= TC_CTRLA_ENABLE(1); + } else { + PWM_MODE16(pwm_reg)->TC_CTRLA &= ~TC_CTRLA_ENABLE(1); + } + break; + + case BIT_MODE_32: + if (enable != 0) { + PWM_MODE32(pwm_reg)->TC_CTRLA |= TC_CTRLA_ENABLE(1); + } else { + PWM_MODE32(pwm_reg)->TC_CTRLA &= ~TC_CTRLA_ENABLE(1); + } + break; + + default: + LOG_ERR("%s : Unsupported PWM mode %d", __func__, max_bit_width); + return -ENOTSUP; + } + tc_sync_wait(pwm_reg, max_bit_width); + + return MCHP_PWM_SUCCESS; +} + +/* + * This function sets the mode of the TC based on the max_bit_width. + * It clears the current mode bits in the TC_CTRLA register and sets the + * appropriate mode bits. After setting the mode, it waits for synchronization to + * complete. Returns 0 on success, or -1 if the max_bit_width is unsupported. + */ +static int32_t tc_set_mode(const void *pwm_reg, const uint32_t max_bit_width) +{ + uint32_t reg_val; + bool slave_mode = check_slave_status(pwm_reg); + + if (slave_mode == true) { + LOG_ERR("tc is in slave mode"); + return -EBUSY; + } + + switch (max_bit_width) { + case BIT_MODE_8: + reg_val = PWM_MODE8(pwm_reg)->TC_CTRLA; + reg_val &= (~TC_CTRLA_MODE_Msk); + reg_val |= TC_CTRLA_MODE(TC_CTRLA_MODE_COUNT8_Val); + PWM_MODE8(pwm_reg)->TC_CTRLA = (uint8_t)reg_val; + LOG_DBG("CTRLA = 0x%x\n", PWM_MODE8(pwm_reg)->TC_CTRLA); + break; + + case BIT_MODE_16: + reg_val = PWM_MODE16(pwm_reg)->TC_CTRLA; + reg_val &= (~TC_CTRLA_MODE_Msk); + reg_val |= TC_CTRLA_MODE(TC_CTRLA_MODE_COUNT16_Val); + PWM_MODE16(pwm_reg)->TC_CTRLA = (uint16_t)reg_val; + break; + + case BIT_MODE_32: + reg_val = PWM_MODE32(pwm_reg)->TC_CTRLA; + reg_val &= (~TC_CTRLA_MODE_Msk); + reg_val |= TC_CTRLA_MODE(TC_CTRLA_MODE_COUNT32_Val); + PWM_MODE32(pwm_reg)->TC_CTRLA = reg_val; + break; + + default: + LOG_ERR("%s : Unsupported PWM mode %d", __func__, max_bit_width); + return -ENOTSUP; + } + tc_sync_wait(pwm_reg, max_bit_width); + LOG_DBG("Mode set = %x\n", TC_CTRLA_MODE(TC_CTRLA_MODE_COUNT8_Val)); + + return MCHP_PWM_SUCCESS; +} + +/* + * This function sets the pulse width for the specified channel based on the + * max_bit_width. It writes the pulse value to the appropriate TC_CCBUF register. + * Logs the pulse value for debugging purposes. + * + * In 16-bit/32-bit mode, the pulse value is written to CCBUF[1]. This is because they are in MPWM + * mode. In MPWM mode, the wave output will can be observed in WO[1] and a negative spike can be + * observed in each overflow of the counter(at the beginning of each period). By default double + * buffering is enabled to prevent wraparound issues. + */ +static int32_t tc_set_pulse_buf(const void *pwm_reg, uint32_t max_bit_width, uint32_t channel, + uint32_t pulse) +{ + bool slave_mode = check_slave_status(pwm_reg); + + if (slave_mode == true) { + LOG_ERR("tc is in slave mode"); + return -EBUSY; + } + + switch (max_bit_width) { + case BIT_MODE_8: + PWM_MODE8(pwm_reg)->TC_CCBUF[channel] = TC_COUNT8_CCBUF_CCBUF(pulse); + LOG_DBG("m_tc_set_pulse invoked 8: 0x%x", TC_COUNT8_CCBUF_CCBUF(pulse)); + break; + + case BIT_MODE_16: + PWM_MODE16(pwm_reg)->TC_CCBUF[1] = TC_COUNT16_CCBUF_CCBUF(pulse); + LOG_DBG("m_tc_set_pulse invoked 16: 0x%x", TC_COUNT16_CCBUF_CCBUF(pulse)); + break; + + case BIT_MODE_32: + PWM_MODE32(pwm_reg)->TC_CCBUF[1] = TC_COUNT32_CCBUF_CCBUF(pulse); + LOG_DBG("m_tc_set_pulse invoked 32 : 0x%x", TC_COUNT32_CCBUF_CCBUF(pulse)); + break; + + default: + LOG_ERR("%s : Unsupported PWM mode %d", __func__, max_bit_width); + return -ENOTSUP; + } + + return MCHP_PWM_SUCCESS; +} + +/* + * This function sets the period value for the TC based on the max_bit_width. + * It writes the period value to the appropriate register (TC_PER or TC_CC[0]). + * Logs the period value and max_bit_width for debugging purposes. + * After setting the period, it waits for synchronization to complete. + */ +static int32_t tc_set_period(const void *pwm_reg, const uint32_t max_bit_width, + const uint32_t period) +{ + bool slave_mode = check_slave_status(pwm_reg); + + if (slave_mode == true) { + LOG_ERR("tc is in slave mode"); + return -EBUSY; + } + + switch (max_bit_width) { + case BIT_MODE_8: + PWM_MODE8(pwm_reg)->TC_PER = TC_COUNT8_PER_PER(period); + break; + + case BIT_MODE_16: + PWM_MODE16(pwm_reg)->TC_CC[0u] = TC_COUNT16_CC_CC(period); + break; + + case BIT_MODE_32: + PWM_MODE32(pwm_reg)->TC_CC[0] = TC_COUNT32_CC_CC(period); + break; + + default: + LOG_ERR("%s : Unsupported PWM mode %d", __func__, max_bit_width); + return -ENOTSUP; + } + tc_sync_wait(pwm_reg, max_bit_width); + + return MCHP_PWM_SUCCESS; +} + +/* + * This function sets the period value for the TC based on the max_bit_width. + * It writes the period value to the appropriate register (TC_PERBUF or TC_CCBUF[0]). + * Logs the period value and max_bit_width for debugging purposes. + * After setting the period, it waits for synchronization to complete. + */ +static int32_t tc_set_period_buf(const void *pwm_reg, const uint32_t max_bit_width, + const uint32_t period) +{ + bool slave_mode = check_slave_status(pwm_reg); + + if (slave_mode == true) { + LOG_ERR("tc is in slave mode"); + return -EBUSY; + } + + switch (max_bit_width) { + case BIT_MODE_8: + PWM_MODE8(pwm_reg)->TC_PERBUF = TC_COUNT8_CCBUF_CCBUF(period); + break; + + case BIT_MODE_16: + PWM_MODE16(pwm_reg)->TC_CCBUF[0u] = TC_COUNT16_CCBUF_CCBUF(period); + break; + + case BIT_MODE_32: + PWM_MODE32(pwm_reg)->TC_CCBUF[0u] = TC_COUNT32_CCBUF_CCBUF(period); + break; + + default: + LOG_ERR("%s : Unsupported PWM mode %d", __func__, max_bit_width); + return -ENOTSUP; + } + LOG_DBG("period %d bit: set to %x", max_bit_width, period); + tc_sync_wait(pwm_reg, max_bit_width); + + return MCHP_PWM_SUCCESS; +} + +/* + * This function sets the invert mode for the specified channel based on the + * max_bit_width. It first disables the TC, waits for synchronization, and then + * sets the invert mask in the TC_DRVCTRL register. After setting the invert + * mask, it re-enables the TC and waits for synchronization again. + */ +static int32_t tc_set_invert(const void *pwm_reg, const uint32_t max_bit_width, uint32_t channel) +{ + uint8_t reg_val; + bool slave_mode = check_slave_status(pwm_reg); + + if (slave_mode == true) { + LOG_ERR("tc is in slave mode"); + return -EBUSY; + } + uint32_t invert_mask = BIT(channel + TC_DRVCTRL_INVEN0_Pos); + + tc_enable(pwm_reg, max_bit_width, false); + tc_sync_wait(pwm_reg, max_bit_width); + + switch (max_bit_width) { + case BIT_MODE_8: + reg_val = PWM_MODE8(pwm_reg)->TC_DRVCTRL; + reg_val &= (~TC_DRVCTRL_INVEN_Msk); + reg_val |= invert_mask; + PWM_MODE8(pwm_reg)->TC_DRVCTRL = reg_val; + LOG_DBG("tc set invert 0x%x invoked", invert_mask); + break; + + case BIT_MODE_16: + reg_val = PWM_MODE16(pwm_reg)->TC_DRVCTRL; + reg_val &= (~TC_DRVCTRL_INVEN_Msk); + reg_val |= invert_mask; + PWM_MODE16(pwm_reg)->TC_DRVCTRL = reg_val; + break; + + case BIT_MODE_32: + reg_val = PWM_MODE32(pwm_reg)->TC_DRVCTRL; + reg_val &= (~TC_DRVCTRL_INVEN_Msk); + reg_val |= invert_mask; + PWM_MODE32(pwm_reg)->TC_DRVCTRL = reg_val; + break; + + default: + tc_enable(pwm_reg, max_bit_width, true); + tc_sync_wait(pwm_reg, max_bit_width); + LOG_ERR("%s : Unsupported PWM mode %d", __func__, max_bit_width); + return -ENOTSUP; + } + tc_enable(pwm_reg, max_bit_width, true); + tc_sync_wait(pwm_reg, max_bit_width); + + return MCHP_PWM_SUCCESS; +} + +/* + * This function retrieves the invert status for the specified channel based on + * the max_bit_width. It reads the invert status from the TC_DRVCTRL register and + * checks if the invert mask is set. Returns true if the invert status is not + * set, otherwise returns false. + */ +static bool tc_get_invert_status(const void *pwm_reg, const uint32_t max_bit_width, + uint32_t channel) +{ + uint32_t invert_status = 0; + uint32_t invert_mask = 1 << (channel + TC_DRVCTRL_INVEN0_Pos); + + LOG_DBG("mchp_pwm_get_invert_status 0x%x invoked", invert_mask); + switch (max_bit_width) { + case BIT_MODE_8: + invert_status = PWM_MODE8(pwm_reg)->TC_DRVCTRL & invert_mask; + break; + + case BIT_MODE_16: + invert_status = PWM_MODE16(pwm_reg)->TC_DRVCTRL & invert_mask; + break; + + case BIT_MODE_32: + invert_status = PWM_MODE32(pwm_reg)->TC_DRVCTRL & invert_mask; + break; + + default: + LOG_ERR("%s : Unsupported PWM mode %d", __func__, max_bit_width); + break; + } + + return (invert_status == 0) ? true : false; +} + +/* + * This function sets the prescaler value for the TC based on the max_bit_width. + * It writes the prescaler value to the TC_CTRLA register and also sets the configuration + * for reloading/resetting the counter on next prescaler clock Position. + * After setting the prescaler, it waits for synchronization to complete. + */ +static int32_t tc_set_prescaler(const void *pwm_reg, const uint32_t max_bit_width, + uint32_t prescaler) +{ + uint32_t reg_val = 0; + bool slave_mode = check_slave_status(pwm_reg); + + if (slave_mode == true) { + LOG_ERR("tc is in slave mode"); + return -EBUSY; + } + prescaler = tc_get_prescale_val(prescaler); + switch (max_bit_width) { + case BIT_MODE_8: + reg_val = PWM_MODE8(pwm_reg)->TC_CTRLA; + reg_val &= ~(TC_CTRLA_PRESCSYNC_Msk | TC_CTRLA_PRESCALER_Msk); + reg_val |= (prescaler | TC_CTRLA_PRESCSYNC_PRESC); + PWM_MODE8(pwm_reg)->TC_CTRLA = reg_val; + break; + + case BIT_MODE_16: + reg_val = PWM_MODE16(pwm_reg)->TC_CTRLA; + reg_val &= ~(TC_CTRLA_PRESCSYNC_Msk | TC_CTRLA_PRESCALER_Msk); + reg_val |= (prescaler | TC_CTRLA_PRESCSYNC_PRESC); + PWM_MODE16(pwm_reg)->TC_CTRLA = reg_val; + break; + + case BIT_MODE_32: + reg_val = PWM_MODE32(pwm_reg)->TC_CTRLA; + reg_val &= ~(TC_CTRLA_PRESCSYNC_Msk | TC_CTRLA_PRESCALER_Msk); + reg_val |= (prescaler | TC_CTRLA_PRESCSYNC_PRESC); + PWM_MODE32(pwm_reg)->TC_CTRLA = reg_val; + break; + + default: + LOG_ERR("%s : Unsupported PWM mode %d", __func__, max_bit_width); + return -ENOTSUP; + } + tc_sync_wait(pwm_reg, max_bit_width); + + return MCHP_PWM_SUCCESS; +} + +/* + * This function sets the wave generation type for the TC based on the + * max_bit_width. It writes the appropriate wave generation value to the TC_WAVE + * register. After setting the wave type, it waits for synchronization to + * complete. + * + * In 16-bit/32-bit mode, the PWM wave type is set as MPWM mode as default. This is because the MAX + * value of the counter can be controlled in that mode only for setting proper period. + */ +static int32_t tc_set_wave_type(const void *pwm_reg, const uint32_t max_bit_width, + uint32_t wave_type) +{ + bool slave_mode = check_slave_status(pwm_reg); + + if (slave_mode == true) { + LOG_ERR("tc is in slave mode"); + return -EBUSY; + } + + switch (max_bit_width) { + case BIT_MODE_8: + PWM_MODE8(pwm_reg)->TC_WAVE = TC_WAVE_WAVEGEN(wave_type); + break; + + case BIT_MODE_16: + PWM_MODE16(pwm_reg)->TC_WAVE = TC_WAVE_WAVEGEN(TC_WAVE_WAVEGEN_MPWM); + break; + + case BIT_MODE_32: + PWM_MODE32(pwm_reg)->TC_WAVE = TC_WAVE_WAVEGEN(TC_WAVE_WAVEGEN_MPWM); + break; + + default: + LOG_ERR("%s : Unsupported PWM mode %d", __func__, max_bit_width); + return -ENOTSUP; + } + tc_sync_wait(pwm_reg, max_bit_width); + LOG_DBG("%s invoked", __func__); + + return MCHP_PWM_SUCCESS; +} + +/* + * Initializes the TC for PWM by performing the following steps: + * 1. Resets the TC registers. + * 2. Sets the TC mode. + * 3. Sets the prescaler value. + * 4. Sets the wave generation type to NPWM. + * 5. Sets the period to 0. + * 6. Enables the TC. + */ +static int tc_init(const struct pwm_mchp_config *const mchp_pwm_cfg) +{ + const void *pwm_reg = mchp_pwm_cfg->regs; + const uint32_t max_bit_width = mchp_pwm_cfg->max_bit_width; + int ret; + + ret = tc_reset_regs(pwm_reg, max_bit_width); + if (ret != MCHP_PWM_SUCCESS) { + return ret; + } + + ret = tc_set_mode(pwm_reg, max_bit_width); + if (ret != MCHP_PWM_SUCCESS) { + return ret; + } + + ret = tc_set_prescaler(pwm_reg, max_bit_width, mchp_pwm_cfg->prescaler); + if (ret != MCHP_PWM_SUCCESS) { + return ret; + } + + ret = tc_set_wave_type(pwm_reg, max_bit_width, TC_WAVE_WAVEGEN_NPWM); + if (ret != MCHP_PWM_SUCCESS) { + return ret; + } + + ret = tc_set_period(pwm_reg, max_bit_width, 0); + if (ret != MCHP_PWM_SUCCESS) { + return ret; + } + + ret = tc_enable(pwm_reg, max_bit_width, true); + if (ret != MCHP_PWM_SUCCESS) { + return ret; + } + + return MCHP_PWM_SUCCESS; +} + +static int pwm_mchp_set_cycles(const struct device *pwm_dev, uint32_t channel, uint32_t period, + uint32_t pulse, pwm_flags_t flags) +{ + + const struct pwm_mchp_config *const mchp_pwm_cfg = pwm_dev->config; + + struct pwm_mchp_data *mchp_pwm_data = pwm_dev->data; + const void *pwm_reg = mchp_pwm_cfg->regs; + const uint32_t max_bit_width = mchp_pwm_cfg->max_bit_width; + uint64_t top = BIT64(max_bit_width) - 1; + int ret_val; + + k_mutex_lock(&mchp_pwm_data->lock, MCHP_PWM_LOCK_TIMEOUT); + bool invert_flag_set = ((flags & PWM_POLARITY_INVERTED) != 0); + bool not_inverted = tc_get_invert_status(pwm_reg, max_bit_width, channel); + + if ((invert_flag_set == true) && (not_inverted == true)) { + ret_val = tc_set_invert(pwm_reg, max_bit_width, channel); + if (ret_val < 0) { + LOG_ERR("PWM peripheral busy"); + return -EBUSY; + } + } + + if (channel >= mchp_pwm_cfg->channels) { + LOG_ERR("channel %d is invalid", channel); + return -EINVAL; + } + + if ((period > top) || (pulse > top)) { + LOG_ERR("period or pulse is out of range"); + return -EINVAL; + } + + ret_val = tc_set_pulse_buf(pwm_reg, max_bit_width, channel, pulse); + if (ret_val < 0) { + LOG_ERR("PWM peripheral busy"); + return -EBUSY; + } + ret_val = tc_set_period_buf(pwm_reg, max_bit_width, period); + if (ret_val < 0) { + LOG_ERR("PWM peripheral busy"); + return -EBUSY; + } + k_mutex_unlock(&mchp_pwm_data->lock); + + return ret_val; +} + +static int pwm_mchp_get_cycles_per_sec(const struct device *pwm_dev, uint32_t channel, + uint64_t *cycles) +{ + const struct pwm_mchp_config *const mchp_pwm_cfg = pwm_dev->config; + struct pwm_mchp_data *mchp_pwm_data = pwm_dev->data; + uint32_t periph_clk_freq = 0; + int ret_val; + + if (channel >= (mchp_pwm_cfg->channels)) { + LOG_ERR("channel %d is invalid", channel); + return -EINVAL; + } + k_mutex_lock(&mchp_pwm_data->lock, MCHP_PWM_LOCK_TIMEOUT); + + ret_val = clock_control_get_rate(mchp_pwm_cfg->pwm_clock.clock_dev, + mchp_pwm_cfg->pwm_clock.host_gclk, &periph_clk_freq); + if (ret_val < 0) { + LOG_ERR("clock get rate failed"); + return ret_val; + } + + *cycles = periph_clk_freq / mchp_pwm_cfg->prescaler; + + k_mutex_unlock(&mchp_pwm_data->lock); + + return MCHP_PWM_SUCCESS; +} + +static int pwm_mchp_init(const struct device *pwm_dev) +{ + int ret_val; + const struct pwm_mchp_config *const mchp_pwm_cfg = pwm_dev->config; + struct pwm_mchp_data *mchp_pwm_data = pwm_dev->data; + + k_mutex_init(&mchp_pwm_data->lock); + + ret_val = clock_control_on(mchp_pwm_cfg->pwm_clock.clock_dev, + mchp_pwm_cfg->pwm_clock.host_gclk); + if ((ret_val < 0) && (ret_val != -EALREADY)) { + LOG_ERR("Failed to enable the host_gclk for PWM: %d", ret_val); + return ret_val; + } + ret_val = clock_control_on(mchp_pwm_cfg->pwm_clock.clock_dev, + mchp_pwm_cfg->pwm_clock.host_mclk); + if ((ret_val < 0) && (ret_val != -EALREADY)) { + LOG_ERR("Failed to enable the host_mclk for PWM: %d", ret_val); + return ret_val; + } + /* If the mode is 32 bit the turn on the clock of the client peripheral as well. + * If the client clock is not provided in the device tree that means it is not + * supported for that particular instance. The MCLK of the client peripheral is to + * be turned on in case 32 bit mode is to be enabled + */ + if (mchp_pwm_cfg->max_bit_width == BIT_MODE_32) { + if (mchp_pwm_cfg->pwm_clock.client_mclk != NULL) { + + ret_val = clock_control_on(mchp_pwm_cfg->pwm_clock.clock_dev, + (mchp_pwm_cfg->pwm_clock.client_mclk)); + if ((ret_val < 0) && (ret_val != -EALREADY)) { + LOG_ERR("Failed to enable the client_mclk: %d", ret_val); + return ret_val; + } + } else { + LOG_ERR("Peripheral does not support 32 bit mode"); + return -ENOTSUP; + } + } + + ret_val = pinctrl_apply_state(mchp_pwm_cfg->pinctrl_config, PINCTRL_STATE_DEFAULT); + if (ret_val < 0) { + LOG_ERR("pincontrol apply state failed: %d", ret_val); + return ret_val; + } + ret_val = tc_init(mchp_pwm_cfg); + ret_val = (ret_val == -EALREADY) ? 0 : ret_val; + + return ret_val; +} + +static DEVICE_API(pwm, pwm_mchp_api) = { + .set_cycles = pwm_mchp_set_cycles, + .get_cycles_per_sec = pwm_mchp_get_cycles_per_sec, +}; + +#define PWM_MCHP_DATA_DEFN(n) static struct pwm_mchp_data pwm_mchp_data_##n + +/* clang-format off */ +#define GET_THE_CLIENT_MCLOCK_IF_AVAILABLE(n) \ + COND_CODE_1(DT_INST_CLOCKS_HAS_NAME(n, client_mclk), \ + ((void *)(DT_INST_CLOCKS_CELL_BY_NAME(n, client_mclk, subsystem))), \ + NULL) + +#define PWM_MCHP_CLOCK_ASSIGN(n) \ + .pwm_clock.clock_dev = DEVICE_DT_GET(DT_NODELABEL(clock)), \ + .pwm_clock.host_mclk = (void *)(DT_INST_CLOCKS_CELL_BY_NAME(n, mclk, subsystem)),\ + .pwm_clock.host_gclk = (void *)DT_INST_CLOCKS_CELL_BY_NAME(n, gclk, subsystem), \ + .pwm_clock.client_mclk = GET_THE_CLIENT_MCLOCK_IF_AVAILABLE(n) + +#define PWM_MCHP_CONFIG_DEFN(n) \ + static const struct pwm_mchp_config pwm_mchp_config_##n = { \ + .prescaler = DT_INST_PROP(n, prescaler), \ + .pinctrl_config = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ + .channels = DT_INST_PROP(n, channels), \ + .regs = (void *)DT_INST_REG_ADDR(n), \ + .max_bit_width = DT_INST_PROP(n, max_bit_width), \ + PWM_MCHP_CLOCK_ASSIGN(n)} + + +#define PWM_MCHP_DEVICE_DT_DEFN(n) \ + DEVICE_DT_INST_DEFINE(n, pwm_mchp_init, NULL, &pwm_mchp_data_##n, &pwm_mchp_config_##n, \ + POST_KERNEL, CONFIG_PWM_INIT_PRIORITY, &pwm_mchp_api) + +#define PWM_MCHP_DEVICE_INIT(n) \ + PINCTRL_DT_INST_DEFINE(n); \ + PWM_MCHP_DATA_DEFN(n); \ + PWM_MCHP_CONFIG_DEFN(n); \ + PWM_MCHP_DEVICE_DT_DEFN(n); + +/* clang-format on */ +DT_INST_FOREACH_STATUS_OKAY(PWM_MCHP_DEVICE_INIT) From b17128e517ae40dda526061dffebdda9d9a43a8c Mon Sep 17 00:00:00 2001 From: Muhammed Asif Date: Wed, 26 Nov 2025 10:56:08 +0530 Subject: [PATCH 0393/3659] boards: microchip: sam_e54_xpro: Add tc node with pwm support - Adds the tc node and its pinmuxing to the board files Signed-off-by: Muhammed Asif --- .../microchip/sam/sam_e54_xpro/sam_e54_xpro-pinctrl.dtsi | 7 +++++++ boards/microchip/sam/sam_e54_xpro/sam_e54_xpro.dts | 9 +++++++++ 2 files changed, 16 insertions(+) diff --git a/boards/microchip/sam/sam_e54_xpro/sam_e54_xpro-pinctrl.dtsi b/boards/microchip/sam/sam_e54_xpro/sam_e54_xpro-pinctrl.dtsi index 8697ae40f4e8..5f9d40ad4a6a 100644 --- a/boards/microchip/sam/sam_e54_xpro/sam_e54_xpro-pinctrl.dtsi +++ b/boards/microchip/sam/sam_e54_xpro/sam_e54_xpro-pinctrl.dtsi @@ -26,4 +26,11 @@ pinmux = ; }; }; + + tc0_pwm_default: tc0_pwm_default { + group1 { + pinmux = , + ; + }; + }; }; diff --git a/boards/microchip/sam/sam_e54_xpro/sam_e54_xpro.dts b/boards/microchip/sam/sam_e54_xpro/sam_e54_xpro.dts index 6ba9d58374f8..b8a8e1ef308e 100644 --- a/boards/microchip/sam/sam_e54_xpro/sam_e54_xpro.dts +++ b/boards/microchip/sam/sam_e54_xpro/sam_e54_xpro.dts @@ -210,6 +210,15 @@ channels = <6>; }; +&tc0 { + compatible = "microchip,tc-g1-pwm"; + #pwm-cells = <3>; + pinctrl-0 = <&tc0_pwm_default>; + pinctrl-names = "default"; + max-bit-width = <32>; + prescaler = <1>; +}; + &portb { status = "okay"; }; From dd53e383e0039e6470279f64ddbccc10ea3725a2 Mon Sep 17 00:00:00 2001 From: Farsin Nasar V A Date: Tue, 18 Nov 2025 15:51:40 +0530 Subject: [PATCH 0394/3659] tests: drivers: pwm: Add SAM E54 test support for TC Added overlay files for sam_e54_xpro TC nodes Added sam_e54_xpro platform allow in testcase.yaml. Added an extra scenario to testcase.yaml Signed-off-by: Farsin Nasar V A --- tests/drivers/pwm/pwm_api/Kconfig | 8 ++-- .../boards/microchip/sam_e54_xpro_tc0.overlay | 13 ++++++ .../boards/microchip/sam_e54_xpro_tc1.overlay | 27 +++++++++++++ .../boards/microchip/sam_e54_xpro_tc2.overlay | 27 +++++++++++++ .../boards/microchip/sam_e54_xpro_tc3.overlay | 27 +++++++++++++ .../boards/microchip/sam_e54_xpro_tc4.overlay | 27 +++++++++++++ .../boards/microchip/sam_e54_xpro_tc5.overlay | 27 +++++++++++++ .../boards/microchip/sam_e54_xpro_tc6.overlay | 27 +++++++++++++ .../boards/microchip/sam_e54_xpro_tc7.overlay | 27 +++++++++++++ tests/drivers/pwm/pwm_api/testcase.yaml | 40 +++++++++++++++++++ .../boards/microchip/sam_e54_xpro_tc0.overlay | 28 +++++++++++++ .../boards/microchip/sam_e54_xpro_tc1.overlay | 33 +++++++++++++++ .../boards/microchip/sam_e54_xpro_tc4.overlay | 37 +++++++++++++++++ .../boards/microchip/sam_e54_xpro_tc5.overlay | 33 +++++++++++++++ .../boards/microchip/sam_e54_xpro_tc6.overlay | 33 +++++++++++++++ .../boards/microchip/sam_e54_xpro_tc7.overlay | 33 +++++++++++++++ .../boards/sam_e54_xpro.conf | 4 ++ .../pwm/pwm_gpio_loopback/testcase.yaml | 29 ++++++++++++++ 18 files changed, 476 insertions(+), 4 deletions(-) create mode 100644 tests/drivers/pwm/pwm_api/boards/microchip/sam_e54_xpro_tc0.overlay create mode 100644 tests/drivers/pwm/pwm_api/boards/microchip/sam_e54_xpro_tc1.overlay create mode 100644 tests/drivers/pwm/pwm_api/boards/microchip/sam_e54_xpro_tc2.overlay create mode 100644 tests/drivers/pwm/pwm_api/boards/microchip/sam_e54_xpro_tc3.overlay create mode 100644 tests/drivers/pwm/pwm_api/boards/microchip/sam_e54_xpro_tc4.overlay create mode 100644 tests/drivers/pwm/pwm_api/boards/microchip/sam_e54_xpro_tc5.overlay create mode 100644 tests/drivers/pwm/pwm_api/boards/microchip/sam_e54_xpro_tc6.overlay create mode 100644 tests/drivers/pwm/pwm_api/boards/microchip/sam_e54_xpro_tc7.overlay create mode 100644 tests/drivers/pwm/pwm_gpio_loopback/boards/microchip/sam_e54_xpro_tc0.overlay create mode 100644 tests/drivers/pwm/pwm_gpio_loopback/boards/microchip/sam_e54_xpro_tc1.overlay create mode 100644 tests/drivers/pwm/pwm_gpio_loopback/boards/microchip/sam_e54_xpro_tc4.overlay create mode 100644 tests/drivers/pwm/pwm_gpio_loopback/boards/microchip/sam_e54_xpro_tc5.overlay create mode 100644 tests/drivers/pwm/pwm_gpio_loopback/boards/microchip/sam_e54_xpro_tc6.overlay create mode 100644 tests/drivers/pwm/pwm_gpio_loopback/boards/microchip/sam_e54_xpro_tc7.overlay create mode 100644 tests/drivers/pwm/pwm_gpio_loopback/boards/sam_e54_xpro.conf diff --git a/tests/drivers/pwm/pwm_api/Kconfig b/tests/drivers/pwm/pwm_api/Kconfig index aeb9c99edc6b..ea95c12fad61 100644 --- a/tests/drivers/pwm/pwm_api/Kconfig +++ b/tests/drivers/pwm/pwm_api/Kconfig @@ -7,14 +7,14 @@ source "Kconfig.zephyr" config DEFAULT_PWM_PORT int "Default PWM port/channel" - default 1 if PWM_STM32 || PWM_MCHP_G1_TCC + default 1 if PWM_STM32 || PWM_MCHP_G1_TCC || PWM_MCHP_G1_TC default 0 help PWM port matching the channel associated with PWM pin. config INVALID_PWM_PORT int "Invalid PWM port/channel" - default 9 if PWM_NRFX || PWM_MCHP_G1_TCC + default 9 if PWM_NRFX || PWM_MCHP_G1_TCC || PWM_MCHP_G1_TC default -1 help Invalid PWM port/channel for negative testing. @@ -38,7 +38,7 @@ config DEFAULT_PULSE_CYCLE config DEFAULT_PERIOD_NSEC int "Default PWM period in nanoseconds" default 4000000 if SOC_FAMILY_MCXW - default 546000 if PWM_MCHP_G1_TCC + default 546000 if PWM_MCHP_G1_TCC || PWM_MCHP_G1_TC default 2000000 help Default PWM period in nanoseconds. @@ -48,7 +48,7 @@ config DEFAULT_PULSE_NSEC default 500000 if SOC_MK64F12 || SOC_MKW41Z4 || SOC_ESP32S2 || SOC_ESP32S3 || SOC_ESP32C3 default 500000 if PWM_INTEL_BLINKY default 2000000 if SOC_FAMILY_MCXW - default 273000 if PWM_MCHP_G1_TCC + default 273000 if PWM_MCHP_G1_TCC || PWM_MCHP_G1_TC default 1000000 help Default PWM pulse in nanoseconds. diff --git a/tests/drivers/pwm/pwm_api/boards/microchip/sam_e54_xpro_tc0.overlay b/tests/drivers/pwm/pwm_api/boards/microchip/sam_e54_xpro_tc0.overlay new file mode 100644 index 000000000000..c5cd34b2019b --- /dev/null +++ b/tests/drivers/pwm/pwm_api/boards/microchip/sam_e54_xpro_tc0.overlay @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&tcc0 { + status = "disabled"; +}; + +&tc0 { + status = "okay"; +}; diff --git a/tests/drivers/pwm/pwm_api/boards/microchip/sam_e54_xpro_tc1.overlay b/tests/drivers/pwm/pwm_api/boards/microchip/sam_e54_xpro_tc1.overlay new file mode 100644 index 000000000000..73e9b5f488c8 --- /dev/null +++ b/tests/drivers/pwm/pwm_api/boards/microchip/sam_e54_xpro_tc1.overlay @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&tcc0 { + status = "disabled"; +}; + +&tc1 { + status = "okay"; + compatible = "microchip,tc-g1-pwm"; + prescaler = <1>; + #pwm-cells = <3>; + pinctrl-0 = <&tc1_pwm_default>; + pinctrl-names = "default"; +}; + +&pinctrl { + tc1_pwm_default: tc1_pwm_default { + group1 { + pinmux = , + ; + }; + }; +}; diff --git a/tests/drivers/pwm/pwm_api/boards/microchip/sam_e54_xpro_tc2.overlay b/tests/drivers/pwm/pwm_api/boards/microchip/sam_e54_xpro_tc2.overlay new file mode 100644 index 000000000000..44ebf45c6b24 --- /dev/null +++ b/tests/drivers/pwm/pwm_api/boards/microchip/sam_e54_xpro_tc2.overlay @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&tcc0 { + status = "disabled"; +}; + +&tc2 { + status = "okay"; + compatible = "microchip,tc-g1-pwm"; + prescaler = <1>; + #pwm-cells = <3>; + pinctrl-0 = <&tc2_pwm_default>; + pinctrl-names = "default"; +}; + +&pinctrl { + tc2_pwm_default: tc2_pwm_default { + group1 { + pinmux = , + ; + }; + }; +}; diff --git a/tests/drivers/pwm/pwm_api/boards/microchip/sam_e54_xpro_tc3.overlay b/tests/drivers/pwm/pwm_api/boards/microchip/sam_e54_xpro_tc3.overlay new file mode 100644 index 000000000000..543be0c44d43 --- /dev/null +++ b/tests/drivers/pwm/pwm_api/boards/microchip/sam_e54_xpro_tc3.overlay @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&tcc0 { + status = "disabled"; +}; + +&tc3 { + status = "okay"; + compatible = "microchip,tc-g1-pwm"; + prescaler = <1>; + #pwm-cells = <3>; + pinctrl-0 = <&tc3_pwm_default>; + pinctrl-names = "default"; +}; + +&pinctrl { + tc3_pwm_default: tc3_pwm_default { + group1 { + pinmux = , + ; + }; + }; +}; diff --git a/tests/drivers/pwm/pwm_api/boards/microchip/sam_e54_xpro_tc4.overlay b/tests/drivers/pwm/pwm_api/boards/microchip/sam_e54_xpro_tc4.overlay new file mode 100644 index 000000000000..a867fe1873a2 --- /dev/null +++ b/tests/drivers/pwm/pwm_api/boards/microchip/sam_e54_xpro_tc4.overlay @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&tcc0 { + status = "disabled"; +}; + +&tc4 { + status = "okay"; + compatible = "microchip,tc-g1-pwm"; + prescaler = <1>; + #pwm-cells = <3>; + pinctrl-0 = <&tc4_pwm_default>; + pinctrl-names = "default"; +}; + +&pinctrl { + tc4_pwm_default: tc4_pwm_default { + group1 { + pinmux = , + ; + }; + }; +}; diff --git a/tests/drivers/pwm/pwm_api/boards/microchip/sam_e54_xpro_tc5.overlay b/tests/drivers/pwm/pwm_api/boards/microchip/sam_e54_xpro_tc5.overlay new file mode 100644 index 000000000000..592fb5ab00cd --- /dev/null +++ b/tests/drivers/pwm/pwm_api/boards/microchip/sam_e54_xpro_tc5.overlay @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&tcc0 { + status = "disabled"; +}; + +&tc5 { + status = "okay"; + compatible = "microchip,tc-g1-pwm"; + prescaler = <1>; + #pwm-cells = <3>; + pinctrl-0 = <&tc5_pwm_default>; + pinctrl-names = "default"; +}; + +&pinctrl { + tc5_pwm_default: tc5_pwm_default { + group1 { + pinmux = , + ; + }; + }; +}; diff --git a/tests/drivers/pwm/pwm_api/boards/microchip/sam_e54_xpro_tc6.overlay b/tests/drivers/pwm/pwm_api/boards/microchip/sam_e54_xpro_tc6.overlay new file mode 100644 index 000000000000..f65946420c64 --- /dev/null +++ b/tests/drivers/pwm/pwm_api/boards/microchip/sam_e54_xpro_tc6.overlay @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&tcc0 { + status = "disabled"; +}; + +&tc6 { + status = "okay"; + compatible = "microchip,tc-g1-pwm"; + prescaler = <1>; + #pwm-cells = <3>; + pinctrl-0 = <&tc6_pwm_default>; + pinctrl-names = "default"; +}; + +&pinctrl { + tc6_pwm_default: tc6_pwm_default { + group1 { + pinmux = , + ; + }; + }; +}; diff --git a/tests/drivers/pwm/pwm_api/boards/microchip/sam_e54_xpro_tc7.overlay b/tests/drivers/pwm/pwm_api/boards/microchip/sam_e54_xpro_tc7.overlay new file mode 100644 index 000000000000..704a3cdcaf5f --- /dev/null +++ b/tests/drivers/pwm/pwm_api/boards/microchip/sam_e54_xpro_tc7.overlay @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&tcc0 { + status = "disabled"; +}; + +&tc7 { + status = "okay"; + compatible = "microchip,tc-g1-pwm"; + prescaler = <1>; + #pwm-cells = <3>; + pinctrl-0 = <&tc7_pwm_default>; + pinctrl-names = "default"; +}; + +&pinctrl { + tc7_pwm_default: tc7_pwm_default { + group1 { + pinmux = , + ; + }; + }; +}; diff --git a/tests/drivers/pwm/pwm_api/testcase.yaml b/tests/drivers/pwm/pwm_api/testcase.yaml index 6bd719c52a23..deeb338f94b6 100644 --- a/tests/drivers/pwm/pwm_api/testcase.yaml +++ b/tests/drivers/pwm/pwm_api/testcase.yaml @@ -106,3 +106,43 @@ tests: - sam_e54_xpro - pic32cx_sg61_cult filter: dt_alias_exists("pwm-test") + drivers.pwm.mchp_tc0: + extra_args: DTC_OVERLAY_FILE="boards/microchip/sam_e54_xpro_tc0.overlay" + platform_allow: + - sam_e54_xpro + filter: dt_alias_exists("pwm-test") + drivers.pwm.mchp_tc1: + extra_args: DTC_OVERLAY_FILE="boards/microchip/sam_e54_xpro_tc1.overlay" + platform_allow: + - sam_e54_xpro + filter: dt_alias_exists("pwm-test") + drivers.pwm.mchp_tc2: + extra_args: DTC_OVERLAY_FILE="boards/microchip/sam_e54_xpro_tc2.overlay" + platform_allow: + - sam_e54_xpro + filter: dt_alias_exists("pwm-test") + drivers.pwm.mchp_tc3: + extra_args: DTC_OVERLAY_FILE="boards/microchip/sam_e54_xpro_tc3.overlay" + platform_allow: + - sam_e54_xpro + filter: dt_alias_exists("pwm-test") + drivers.pwm.mchp_tc4: + extra_args: DTC_OVERLAY_FILE="boards/microchip/sam_e54_xpro_tc4.overlay" + platform_allow: + - sam_e54_xpro + filter: dt_alias_exists("pwm-test") + drivers.pwm.mchp_tc5: + extra_args: DTC_OVERLAY_FILE="boards/microchip/sam_e54_xpro_tc5.overlay" + platform_allow: + - sam_e54_xpro + filter: dt_alias_exists("pwm-test") + drivers.pwm.mchp_tc6: + extra_args: DTC_OVERLAY_FILE="boards/microchip/sam_e54_xpro_tc6.overlay" + platform_allow: + - sam_e54_xpro + filter: dt_alias_exists("pwm-test") + drivers.pwm.mchp_tc7: + extra_args: DTC_OVERLAY_FILE="boards/microchip/sam_e54_xpro_tc7.overlay" + platform_allow: + - sam_e54_xpro + filter: dt_alias_exists("pwm-test") diff --git a/tests/drivers/pwm/pwm_gpio_loopback/boards/microchip/sam_e54_xpro_tc0.overlay b/tests/drivers/pwm/pwm_gpio_loopback/boards/microchip/sam_e54_xpro_tc0.overlay new file mode 100644 index 000000000000..87345364c49e --- /dev/null +++ b/tests/drivers/pwm/pwm_gpio_loopback/boards/microchip/sam_e54_xpro_tc0.overlay @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* connect the PA05 to PB04 */ + +#include + +/ { + zephyr,user { + pwms = <&tc0 1 PWM_MSEC(20) 0>; + gpios = <&portb 4 GPIO_ACTIVE_HIGH>; + }; +}; + +&tc0 { + status = "okay"; +}; + +&pinctrl { + tc0_pwm_default: tc0_pwm_default { + group1 { + pinmux = ; + }; + }; +}; diff --git a/tests/drivers/pwm/pwm_gpio_loopback/boards/microchip/sam_e54_xpro_tc1.overlay b/tests/drivers/pwm/pwm_gpio_loopback/boards/microchip/sam_e54_xpro_tc1.overlay new file mode 100644 index 000000000000..ae17c24d248b --- /dev/null +++ b/tests/drivers/pwm/pwm_gpio_loopback/boards/microchip/sam_e54_xpro_tc1.overlay @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* connect the PA07 to PC05 */ + +#include + +/ { + zephyr,user { + pwms = <&tc1 1 PWM_MSEC(1) 0>; + gpios = <&portc 5 GPIO_ACTIVE_HIGH>; + }; +}; + +&tc1 { + status = "okay"; + compatible = "microchip,tc-g1-pwm"; + #pwm-cells = <3>; + pinctrl-0 = <&tc1_pwm_default>; + pinctrl-names = "default"; + prescaler = <4>; +}; + +&pinctrl { + tc1_pwm_default: tc1_pwm_default { + group1 { + pinmux = ; + }; + }; +}; diff --git a/tests/drivers/pwm/pwm_gpio_loopback/boards/microchip/sam_e54_xpro_tc4.overlay b/tests/drivers/pwm/pwm_gpio_loopback/boards/microchip/sam_e54_xpro_tc4.overlay new file mode 100644 index 000000000000..df7899bd21cb --- /dev/null +++ b/tests/drivers/pwm/pwm_gpio_loopback/boards/microchip/sam_e54_xpro_tc4.overlay @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* connect the PA23 to PA03 */ + +#include + +/ { + zephyr,user { + pwms = <&tc4 1 PWM_MSEC(1) 0>; + gpios = <&porta 3 GPIO_ACTIVE_HIGH>; + }; +}; + +&tc4 { + status = "okay"; + compatible = "microchip,tc-g1-pwm"; + #pwm-cells = <3>; + pinctrl-0 = <&tc4_pwm_default>; + pinctrl-names = "default"; + prescaler = <4>; +}; + +&porta { + status = "okay"; +}; + +&pinctrl { + tc4_pwm_default: tc4_pwm_default { + group1 { + pinmux = ; + }; + }; +}; diff --git a/tests/drivers/pwm/pwm_gpio_loopback/boards/microchip/sam_e54_xpro_tc5.overlay b/tests/drivers/pwm/pwm_gpio_loopback/boards/microchip/sam_e54_xpro_tc5.overlay new file mode 100644 index 000000000000..4a2e0ae16918 --- /dev/null +++ b/tests/drivers/pwm/pwm_gpio_loopback/boards/microchip/sam_e54_xpro_tc5.overlay @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* connect the PB15 to PC03 */ + +#include + +/ { + zephyr,user { + pwms = <&tc5 1 PWM_MSEC(1) 0>; + gpios = <&portc 3 GPIO_ACTIVE_HIGH>; + }; +}; + +&tc5 { + status = "okay"; + compatible = "microchip,tc-g1-pwm"; + #pwm-cells = <3>; + pinctrl-0 = <&tc5_pwm_default>; + pinctrl-names = "default"; + prescaler = <4>; +}; + +&pinctrl { + tc5_pwm_default: tc5_pwm_default { + group1 { + pinmux = ; + }; + }; +}; diff --git a/tests/drivers/pwm/pwm_gpio_loopback/boards/microchip/sam_e54_xpro_tc6.overlay b/tests/drivers/pwm/pwm_gpio_loopback/boards/microchip/sam_e54_xpro_tc6.overlay new file mode 100644 index 000000000000..e968e410a01a --- /dev/null +++ b/tests/drivers/pwm/pwm_gpio_loopback/boards/microchip/sam_e54_xpro_tc6.overlay @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* connect the PB17 to PC01 */ + +#include + +/ { + zephyr,user { + pwms = <&tc6 1 PWM_MSEC(1) 0>; + gpios = <&portc 1 GPIO_ACTIVE_HIGH>; + }; +}; + +&tc6 { + status = "okay"; + compatible = "microchip,tc-g1-pwm"; + #pwm-cells = <3>; + pinctrl-0 = <&tc6_pwm_default>; + pinctrl-names = "default"; + prescaler = <4>; +}; + +&pinctrl { + tc6_pwm_default: tc6_pwm_default { + group1 { + pinmux = ; + }; + }; +}; diff --git a/tests/drivers/pwm/pwm_gpio_loopback/boards/microchip/sam_e54_xpro_tc7.overlay b/tests/drivers/pwm/pwm_gpio_loopback/boards/microchip/sam_e54_xpro_tc7.overlay new file mode 100644 index 000000000000..2e59f25e2e7a --- /dev/null +++ b/tests/drivers/pwm/pwm_gpio_loopback/boards/microchip/sam_e54_xpro_tc7.overlay @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* connect the PB01 to PC02 */ + +#include + +/ { + zephyr,user { + pwms = <&tc7 1 PWM_MSEC(1) 1>; + gpios = <&portc 2 GPIO_ACTIVE_HIGH>; + }; +}; + +&tc7 { + status = "okay"; + compatible = "microchip,tc-g1-pwm"; + #pwm-cells = <3>; + pinctrl-0 = <&tc7_pwm_default>; + pinctrl-names = "default"; + prescaler = <4>; +}; + +&pinctrl { + tc7_pwm_default: tc7_pwm_default { + group1 { + pinmux = ; + }; + }; +}; diff --git a/tests/drivers/pwm/pwm_gpio_loopback/boards/sam_e54_xpro.conf b/tests/drivers/pwm/pwm_gpio_loopback/boards/sam_e54_xpro.conf new file mode 100644 index 000000000000..d01fd7e3d63c --- /dev/null +++ b/tests/drivers/pwm/pwm_gpio_loopback/boards/sam_e54_xpro.conf @@ -0,0 +1,4 @@ +# Copyright (c) 2025 Microchip Technology Inc. +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_GPIO=y diff --git a/tests/drivers/pwm/pwm_gpio_loopback/testcase.yaml b/tests/drivers/pwm/pwm_gpio_loopback/testcase.yaml index b43eb74b2bd8..4c8ef496b974 100644 --- a/tests/drivers/pwm/pwm_gpio_loopback/testcase.yaml +++ b/tests/drivers/pwm/pwm_gpio_loopback/testcase.yaml @@ -34,3 +34,32 @@ tests: - cyw920829m2evk_02/cyw20829b1340 - cyw920829m2evk_02/cyw20829b1010 - cyw920829m2evk_02/cyw20829b0lkml + drivers.pwm.gpio_loopback_tc0.mchp: + extra_args: DTC_OVERLAY_FILE="boards/microchip/sam_e54_xpro_tc0.overlay" + platform_allow: + - sam_e54_xpro + + drivers.pwm.gpio_loopback_tc1.mchp: + extra_args: DTC_OVERLAY_FILE="boards/microchip/sam_e54_xpro_tc1.overlay" + platform_allow: + - sam_e54_xpro + + drivers.pwm.gpio_loopback_tc4.mchp: + extra_args: DTC_OVERLAY_FILE="boards/microchip/sam_e54_xpro_tc4.overlay" + platform_allow: + - sam_e54_xpro + + drivers.pwm.gpio_loopback_tc5.mchp: + extra_args: DTC_OVERLAY_FILE="boards/microchip/sam_e54_xpro_tc5.overlay" + platform_allow: + - sam_e54_xpro + + drivers.pwm.gpio_loopback_tc6.mchp: + extra_args: DTC_OVERLAY_FILE="boards/microchip/sam_e54_xpro_tc6.overlay" + platform_allow: + - sam_e54_xpro + + drivers.pwm.gpio_loopback_tc7.mchp: + extra_args: DTC_OVERLAY_FILE="boards/microchip/sam_e54_xpro_tc7.overlay" + platform_allow: + - sam_e54_xpro From 5018d2456ec496aa66f205b9a2fe4c802ca7c313 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Tue, 2 Dec 2025 12:39:54 +0530 Subject: [PATCH 0395/3659] modules: hostap: Workaround for BTM failure Fixes WFA QT BTM test case. Signed-off-by: Chaitanya Tata --- modules/hostap/Kconfig | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/modules/hostap/Kconfig b/modules/hostap/Kconfig index c5b0df1f81b2..a1ab1a8ce867 100644 --- a/modules/hostap/Kconfig +++ b/modules/hostap/Kconfig @@ -719,4 +719,13 @@ config WIFI_NM_HOSTAPD_REGULATORY_ENV All supported environments of current region can be used with default value of 0x20 or 32. +config WIFI_NM_WPA_SUPPLICANT_BTM_PRE_SCAN_CHECK + bool "Pre-scan check for BTM" + default y if !SOC_FAMILY_NORDIC_NRF + help + This option is used to enable the pre-scan check for BTM. + When no candidate is found, a new scan is performed. + Disable this if the chip takes too long to perform a scan causing + disassociations in WFA QT tests. + endif # WIFI_NM_WPA_SUPPLICANT From b152f71aaa7340559107b3eda6e105e54fddf40a Mon Sep 17 00:00:00 2001 From: Fabrice DJIATSA Date: Tue, 2 Dec 2025 17:01:34 +0100 Subject: [PATCH 0396/3659] modules: kconfig: mcuboot: make SWAP_USING_OFFSET the default for STM32 Update MCUboot configuration so that STM32 no longer defaults to SWAP_USING_MOVE. Instead, SWAP_USING_OFFSET becomes the default mode for STM32 boards. Signed-off-by: Fabrice DJIATSA --- modules/Kconfig.mcuboot | 2 +- share/sysbuild/images/bootloader/Kconfig | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/Kconfig.mcuboot b/modules/Kconfig.mcuboot index a71520c40105..c83b2ef9d155 100644 --- a/modules/Kconfig.mcuboot +++ b/modules/Kconfig.mcuboot @@ -189,7 +189,7 @@ menu "On board MCUboot operation mode" choice MCUBOOT_BOOTLOADER_MODE prompt "Application assumed MCUboot mode of operation" # Should be removed if board dts is updated - default MCUBOOT_BOOTLOADER_MODE_SWAP_USING_MOVE if SOC_FAMILY_STM32 || SOC_FAMILY_ESPRESSIF_ESP32 + default MCUBOOT_BOOTLOADER_MODE_SWAP_USING_MOVE if SOC_FAMILY_ESPRESSIF_ESP32 default MCUBOOT_BOOTLOADER_MODE_SWAP_USING_OFFSET help Informs application build on assumed MCUboot mode of operation. diff --git a/share/sysbuild/images/bootloader/Kconfig b/share/sysbuild/images/bootloader/Kconfig index 32cd25901abf..a3c9bbef83a3 100644 --- a/share/sysbuild/images/bootloader/Kconfig +++ b/share/sysbuild/images/bootloader/Kconfig @@ -33,7 +33,7 @@ if BOOTLOADER_MCUBOOT choice MCUBOOT_MODE prompt "Mode of operation" # Should be removed if board dts is updated - default MCUBOOT_MODE_SWAP_USING_MOVE if SOC_FAMILY_STM32 || SOC_FAMILY_ESPRESSIF_ESP32 + default MCUBOOT_MODE_SWAP_USING_MOVE if SOC_FAMILY_ESPRESSIF_ESP32 default MCUBOOT_MODE_SWAP_USING_OFFSET help The operating mode of MCUboot (which will also be propagated to the application). From b348fd4d7a6ba92aa45ae8d96ad018c0e0cf11db Mon Sep 17 00:00:00 2001 From: Fabrice DJIATSA Date: Tue, 2 Dec 2025 17:21:11 +0100 Subject: [PATCH 0397/3659] boards: st: add support for boards compatible with swap using offset - Swap using offset requires that slot1 has one extra sector size compared to slot0 - Additionally, add a storage partition with at least 3 sectors for NVS if needed. Signed-off-by: Fabrice DJIATSA --- boards/st/nucleo_c071rb/nucleo_c071rb.dts | 29 +++++++++++++ boards/st/nucleo_f091rc/nucleo_f091rc.dts | 43 +++++++++++++------ boards/st/nucleo_f103rb/nucleo_f103rb.dts | 21 +++++++-- boards/st/nucleo_g071rb/nucleo_g071rb.dts | 21 +++++++-- boards/st/nucleo_g474re/nucleo_g474re.dts | 15 +++---- boards/st/nucleo_h753zi/nucleo_h753zi.dts | 8 ++-- boards/st/nucleo_l152re/nucleo_l152re.dts | 21 +++++++-- boards/st/nucleo_u385rg_q/nucleo_u385rg_q.dts | 17 +++----- boards/st/nucleo_wb55rg/nucleo_wb55rg.dts | 15 +++---- boards/st/nucleo_wba55cg/nucleo_wba55cg.dts | 6 +-- boards/st/nucleo_wba65ri/nucleo_wba65ri.dts | 20 ++++++++- boards/st/nucleo_wl55jc/nucleo_wl55jc.dts | 18 +++----- boards/st/stm32f3_disco/stm32f3_disco.dts | 16 +++++++ boards/st/stm32h573i_dk/Kconfig.sysbuild | 2 +- boards/st/stm32h573i_dk/stm32h573i_dk.dts | 6 +-- boards/st/stm32u083c_dk/stm32u083c_dk.dts | 29 +++++++++++++ boards/st/stm32wba65i_dk1/stm32wba65i_dk1.dts | 20 ++++++++- dts/arm/st/l1/stm32l1.dtsi | 1 + 18 files changed, 230 insertions(+), 78 deletions(-) diff --git a/boards/st/nucleo_c071rb/nucleo_c071rb.dts b/boards/st/nucleo_c071rb/nucleo_c071rb.dts index 3f85064c6121..8f6c879f8cd2 100644 --- a/boards/st/nucleo_c071rb/nucleo_c071rb.dts +++ b/boards/st/nucleo_c071rb/nucleo_c071rb.dts @@ -19,6 +19,7 @@ zephyr,shell-uart = &usart2; zephyr,sram = &sram0; zephyr,flash = &flash0; + zephyr,code-partition = &slot0_partition; }; leds: leds { @@ -194,3 +195,31 @@ zephyr_udc0: &usb { pinctrl-names = "default"; status = "okay"; }; + +&flash0 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 DT_SIZE_K(36)>; + }; + + slot0_partition: partition@9000 { + label = "image-0"; + reg = <0x00009000 DT_SIZE_K(42)>; + }; + + slot1_partition: partition@13800 { + label = "image-1"; + reg = <0x00013800 DT_SIZE_K(44)>; + }; + + storage_partition: partition@1e800 { + label = "storage"; + reg = <0x0001e800 DT_SIZE_K(6)>; + }; + }; +}; diff --git a/boards/st/nucleo_f091rc/nucleo_f091rc.dts b/boards/st/nucleo_f091rc/nucleo_f091rc.dts index 4127816f0e49..988a9417bf64 100644 --- a/boards/st/nucleo_f091rc/nucleo_f091rc.dts +++ b/boards/st/nucleo_f091rc/nucleo_f091rc.dts @@ -21,6 +21,7 @@ zephyr,sram = &sram0; zephyr,flash = &flash0; zephyr,canbus = &can1; + zephyr,code-partition = &slot0_partition; }; leds: leds { @@ -143,20 +144,6 @@ status = "okay"; }; -&flash0 { - partitions { - compatible = "fixed-partitions"; - #address-cells = <1>; - #size-cells = <1>; - - /* Set 6Kb of storage at the end of the 256Kb of flash */ - storage_partition: partition@3e800 { - label = "storage"; - reg = <0x0003e800 DT_SIZE_K(6)>; - }; - }; -}; - &adc1 { pinctrl-0 = <&adc_in0_pa0>; pinctrl-names = "default"; @@ -197,3 +184,31 @@ &vbat { status = "okay"; }; + +&flash0 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 DT_SIZE_K(48)>; + }; + + slot0_partition: partition@c000 { + label = "image-0"; + reg = <0x0000c000 DT_SIZE_K(100)>; + }; + + slot1_partition: partition@25000 { + label = "image-1"; + reg = <0x00025000 DT_SIZE_K(102)>; + }; + + storage_partition: partition@3e800 { + label = "storage"; + reg = <0x0003e800 DT_SIZE_K(6)>; + }; + }; +}; diff --git a/boards/st/nucleo_f103rb/nucleo_f103rb.dts b/boards/st/nucleo_f103rb/nucleo_f103rb.dts index fe4a9cd3b7a3..03ceb13fc3c8 100644 --- a/boards/st/nucleo_f103rb/nucleo_f103rb.dts +++ b/boards/st/nucleo_f103rb/nucleo_f103rb.dts @@ -20,6 +20,7 @@ zephyr,shell-uart = &usart2; zephyr,sram = &sram0; zephyr,flash = &flash0; + zephyr,code-partition = &slot0_partition; }; leds: leds { @@ -166,10 +167,24 @@ #address-cells = <1>; #size-cells = <1>; - /* Set 2KB of storage at the end of 128KB flash */ - storage_partition: partition@1f800 { + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 DT_SIZE_K(34)>; + }; + + slot0_partition: partition@8800 { + label = "image-0"; + reg = <0x00008800 DT_SIZE_K(45)>; + }; + + slot1_partition: partition@13c00 { + label = "image-1"; + reg = <0x00013c00 DT_SIZE_K(46)>; + }; + + storage_partition: partition@1f400 { label = "storage"; - reg = <0x0001f800 DT_SIZE_K(2)>; + reg = <0x0001f400 DT_SIZE_K(3)>; }; }; }; diff --git a/boards/st/nucleo_g071rb/nucleo_g071rb.dts b/boards/st/nucleo_g071rb/nucleo_g071rb.dts index f7d063908318..9448d4a412fb 100644 --- a/boards/st/nucleo_g071rb/nucleo_g071rb.dts +++ b/boards/st/nucleo_g071rb/nucleo_g071rb.dts @@ -21,6 +21,7 @@ zephyr,shell-uart = &usart2; zephyr,sram = &sram0; zephyr,flash = &flash0; + zephyr,code-partition = &slot0_partition; }; leds: leds { @@ -172,10 +173,24 @@ #address-cells = <1>; #size-cells = <1>; - /* Set 4KB of storage at the end of 128KB flash */ - storage_partition: partition@1f000 { + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 DT_SIZE_K(36)>; + }; + + slot0_partition: partition@9000 { + label = "image-0"; + reg = <0x00009000 DT_SIZE_K(42)>; + }; + + slot1_partition: partition@13800 { + label = "image-1"; + reg = <0x00013800 DT_SIZE_K(44)>; + }; + + storage_partition: partition@1e800 { label = "storage"; - reg = <0x0001f000 DT_SIZE_K(4)>; + reg = <0x0001e800 DT_SIZE_K(6)>; }; }; }; diff --git a/boards/st/nucleo_g474re/nucleo_g474re.dts b/boards/st/nucleo_g474re/nucleo_g474re.dts index a8ca56c2ea8d..7f8733f76b7f 100644 --- a/boards/st/nucleo_g474re/nucleo_g474re.dts +++ b/boards/st/nucleo_g474re/nucleo_g474re.dts @@ -178,23 +178,22 @@ stm32_lp_tick_source: &lptim1 { boot_partition: partition@0 { label = "mcuboot"; - reg = <0x00000000 DT_SIZE_K(34)>; + reg = <0x00000000 DT_SIZE_K(48)>; }; - slot0_partition: partition@8800 { + slot0_partition: partition@c000 { label = "image-0"; - reg = <0x00008800 DT_SIZE_K(240)>; + reg = <0x0000c000 DT_SIZE_K(228)>; }; - slot1_partition: partition@44800 { + slot1_partition: partition@45000 { label = "image-1"; - reg = <0x00044800 DT_SIZE_K(234)>; + reg = <0x00045000 DT_SIZE_K(230)>; }; - /* Set 4Kb of storage at the end of the 512Kb of flash */ - storage_partition: partition@7f000 { + storage_partition: partition@7e800 { label = "storage"; - reg = <0x0007f000 DT_SIZE_K(4)>; + reg = <0x0007e800 DT_SIZE_K(6)>; }; }; }; diff --git a/boards/st/nucleo_h753zi/nucleo_h753zi.dts b/boards/st/nucleo_h753zi/nucleo_h753zi.dts index abd3cf330503..f69890628496 100644 --- a/boards/st/nucleo_h753zi/nucleo_h753zi.dts +++ b/boards/st/nucleo_h753zi/nucleo_h753zi.dts @@ -258,16 +258,16 @@ zephyr_udc0: &usbotg_fs { reg = <0x00020000 DT_SIZE_K(256)>; }; - /* backup slot: 256KB */ + /* backup slot: 384KB */ slot1_partition: partition@60000 { label = "image-1"; - reg = <0x00060000 DT_SIZE_K(256)>; + reg = <0x00060000 DT_SIZE_K(384)>; }; /* storage: 256KB for settings */ - storage_partition: partition@a0000 { + storage_partition: partition@c0000 { label = "storage"; - reg = <0x000a0000 DT_SIZE_K(256)>; + reg = <0x000c0000 DT_SIZE_K(256)>; }; }; }; diff --git a/boards/st/nucleo_l152re/nucleo_l152re.dts b/boards/st/nucleo_l152re/nucleo_l152re.dts index d0edae20e60c..c87adf015bea 100644 --- a/boards/st/nucleo_l152re/nucleo_l152re.dts +++ b/boards/st/nucleo_l152re/nucleo_l152re.dts @@ -20,6 +20,7 @@ zephyr,shell-uart = &usart2; zephyr,sram = &sram0; zephyr,flash = &flash0; + zephyr,code-partition = &slot0_partition; }; leds: leds { @@ -147,10 +148,24 @@ #address-cells = <1>; #size-cells = <1>; - /* Set 8KB of storage at the end of 512KB flash */ - storage_partition: partition@7e000 { + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 DT_SIZE_K(48)>; + }; + + slot0_partition: partition@c000 { + label = "image-0"; + reg = <0x0000c000 DT_SIZE_K(224)>; + }; + + slot1_partition: partition@44000 { + label = "image-1"; + reg = <0x00044000 DT_SIZE_K(228)>; + }; + + storage_partition: partition@7d000 { label = "storage"; - reg = <0x0007e000 DT_SIZE_K(8)>; + reg = <0x0007d000 DT_SIZE_K(12)>; }; }; }; diff --git a/boards/st/nucleo_u385rg_q/nucleo_u385rg_q.dts b/boards/st/nucleo_u385rg_q/nucleo_u385rg_q.dts index 3df4e6b4c6c6..1902855d8383 100644 --- a/boards/st/nucleo_u385rg_q/nucleo_u385rg_q.dts +++ b/boards/st/nucleo_u385rg_q/nucleo_u385rg_q.dts @@ -66,29 +66,24 @@ #address-cells = <1>; #size-cells = <1>; - /* - * The following partitioning is dedicated to the use of nucleo_u385rg_q - * with TZEN=0 (i.e., without TF-M). - * Place partitions within first 512 KiB to make use of the whole Bank1. - */ boot_partition: partition@0 { label = "mcuboot"; reg = <0x00000000 DT_SIZE_K(64)>; }; - slot0_partition: partition@10000 { + slot0_partition: partition@c000 { label = "image-0"; - reg = <0x00010000 DT_SIZE_K(192)>; + reg = <0x0000c000 DT_SIZE_K(472)>; }; - slot1_partition: partition@40000 { + slot1_partition: partition@44000 { label = "image-1"; - reg = <0x00040000 DT_SIZE_K(192)>; + reg = <0x00044000 DT_SIZE_K(476)>; }; - storage_partition: partition@70000 { + storage_partition: partition@fd000 { label = "storage"; - reg = <0x00070000 DT_SIZE_K(64)>; + reg = <0x0007d000 DT_SIZE_K(12)>; }; }; }; diff --git a/boards/st/nucleo_wb55rg/nucleo_wb55rg.dts b/boards/st/nucleo_wb55rg/nucleo_wb55rg.dts index 8c4c56d294ee..0207fcb32da2 100644 --- a/boards/st/nucleo_wb55rg/nucleo_wb55rg.dts +++ b/boards/st/nucleo_wb55rg/nucleo_wb55rg.dts @@ -237,22 +237,17 @@ zephyr_udc0: &usb { slot0_partition: partition@c000 { label = "image-0"; - reg = <0x0000c000 DT_SIZE_K(400)>; + reg = <0x0000c000 DT_SIZE_K(408)>; }; - slot1_partition: partition@70000 { + slot1_partition: partition@72000 { label = "image-1"; - reg = <0x00070000 DT_SIZE_K(400)>; + reg = <0x00072000 DT_SIZE_K(412)>; }; - scratch_partition: partition@d4000 { - label = "image-scratch"; - reg = <0x000d4000 DT_SIZE_K(16)>; - }; - - storage_partition: partition@d8000 { + storage_partition: partition@d9000 { label = "storage"; - reg = <0x000d8000 DT_SIZE_K(8)>; + reg = <0x000d9000 DT_SIZE_K(8)>; }; }; }; diff --git a/boards/st/nucleo_wba55cg/nucleo_wba55cg.dts b/boards/st/nucleo_wba55cg/nucleo_wba55cg.dts index 2409c4c95838..1f436f71482b 100644 --- a/boards/st/nucleo_wba55cg/nucleo_wba55cg.dts +++ b/boards/st/nucleo_wba55cg/nucleo_wba55cg.dts @@ -214,12 +214,12 @@ stm32_lp_tick_source: &lptim1 { slot0_partition: partition@10000 { label = "image-0"; - reg = <0x00010000 DT_SIZE_K(456)>; + reg = <0x00010000 DT_SIZE_K(448)>; }; - slot1_partition: partition@82000 { + slot1_partition: partition@80000 { label = "image-1"; - reg = <0x00082000 DT_SIZE_K(448)>; + reg = <0x00080000 DT_SIZE_K(456)>; }; storage_partition: partition@f2000 { diff --git a/boards/st/nucleo_wba65ri/nucleo_wba65ri.dts b/boards/st/nucleo_wba65ri/nucleo_wba65ri.dts index 3c031aa9f2ac..6568ff34c12f 100644 --- a/boards/st/nucleo_wba65ri/nucleo_wba65ri.dts +++ b/boards/st/nucleo_wba65ri/nucleo_wba65ri.dts @@ -23,6 +23,7 @@ zephyr,shell-uart = &usart1; zephyr,sram = &sram0; zephyr,flash = &flash0; + zephyr,code-partition = &slot0_partition; }; leds: leds { @@ -172,9 +173,24 @@ stm32_lp_tick_source: &lptim1 { #address-cells = <1>; #size-cells = <1>; - storage_partition: partition@1c0000 { + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 DT_SIZE_K(64)>; + }; + + slot0_partition: partition@10000 { + label = "image-0"; + reg = <0x00010000 DT_SIZE_K(960)>; + }; + + slot1_partition: partition@100000 { + label = "image-1"; + reg = <0x00100000 DT_SIZE_K(968)>; + }; + + storage_partition: partition@1f2000 { label = "storage"; - reg = <0x001c0000 DT_SIZE_K(256)>; + reg = <0x001f2000 DT_SIZE_K(56)>; }; }; }; diff --git a/boards/st/nucleo_wl55jc/nucleo_wl55jc.dts b/boards/st/nucleo_wl55jc/nucleo_wl55jc.dts index c99ff311f1ae..09b168122358 100644 --- a/boards/st/nucleo_wl55jc/nucleo_wl55jc.dts +++ b/boards/st/nucleo_wl55jc/nucleo_wl55jc.dts @@ -203,27 +203,23 @@ stm32_lp_tick_source: &lptim1 { boot_partition: partition@0 { label = "mcuboot"; - reg = <0x00000000 DT_SIZE_K(32)>; + reg = <0x00000000 DT_SIZE_K(48)>; read-only; }; - slot0_partition: partition@8000 { + slot0_partition: partition@c000 { label = "image-0"; - reg = <0x00008000 DT_SIZE_K(104)>; + reg = <0x0000c000 DT_SIZE_K(98)>; }; - slot1_partition: partition@22000 { + slot1_partition: partition@24800 { label = "image-1"; - reg = <0x00022000 DT_SIZE_K(104)>; + reg = <0x00024800 DT_SIZE_K(100)>; }; - /* - * Set 16kB of storage (8x2kB pages) at the end of the 256kB of - * flash. - */ - storage_partition: partition@3c000 { + storage_partition: partition@3d800 { label = "storage"; - reg = <0x0003c000 DT_SIZE_K(16)>; + reg = <0x0003d800 DT_SIZE_K(10)>; }; }; }; diff --git a/boards/st/stm32f3_disco/stm32f3_disco.dts b/boards/st/stm32f3_disco/stm32f3_disco.dts index 2d6ad6f6d5f0..854a221ecd2f 100644 --- a/boards/st/stm32f3_disco/stm32f3_disco.dts +++ b/boards/st/stm32f3_disco/stm32f3_disco.dts @@ -18,6 +18,7 @@ zephyr,shell-uart = &usart1; zephyr,sram = &sram0; zephyr,flash = &flash0; + zephyr,code-partition = &slot0_partition; zephyr,canbus = &can1; }; @@ -202,6 +203,21 @@ zephyr_udc0: &usb { #address-cells = <1>; #size-cells = <1>; + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 DT_SIZE_K(48)>; + }; + + slot0_partition: partition@c000 { + label = "image-0"; + reg = <0x0000c000 DT_SIZE_K(100)>; + }; + + slot1_partition: partition@25000 { + label = "image-1"; + reg = <0x00025000 DT_SIZE_K(102)>; + }; + /* Set 6Kb of storage at the end of the 256Kb of flash */ storage_partition: partition@3e800 { label = "storage"; diff --git a/boards/st/stm32h573i_dk/Kconfig.sysbuild b/boards/st/stm32h573i_dk/Kconfig.sysbuild index 4f2afc0b2c4d..b4bd392f3bf3 100644 --- a/boards/st/stm32h573i_dk/Kconfig.sysbuild +++ b/boards/st/stm32h573i_dk/Kconfig.sysbuild @@ -6,7 +6,7 @@ choice BOOTLOADER endchoice choice BOOT_SIGNATURE_TYPE - default BOOT_SIGNATURE_TYPE_NONE + default BOOT_SIGNATURE_TYPE_RSA endchoice if BOARD_STM32H573I_DK_STM32H573XX_EXT_FLASH_APP diff --git a/boards/st/stm32h573i_dk/stm32h573i_dk.dts b/boards/st/stm32h573i_dk/stm32h573i_dk.dts index 4884d83f7ff6..91b27fdf7cb3 100644 --- a/boards/st/stm32h573i_dk/stm32h573i_dk.dts +++ b/boards/st/stm32h573i_dk/stm32h573i_dk.dts @@ -32,12 +32,12 @@ slot0_partition: partition@10000 { label = "image-0"; - reg = <0x00010000 DT_SIZE_K(448)>; + reg = <0x00010000 DT_SIZE_K(440)>; }; - slot1_partition: partition@80000 { + slot1_partition: partition@7e000 { label = "image-1"; - reg = <0x00080000 DT_SIZE_K(440)>; + reg = <0x0007e000 DT_SIZE_K(448)>; }; /* Set 72KB of storage at the end of Bank1 */ diff --git a/boards/st/stm32u083c_dk/stm32u083c_dk.dts b/boards/st/stm32u083c_dk/stm32u083c_dk.dts index 8a5a38a24736..3c9fee2d856d 100644 --- a/boards/st/stm32u083c_dk/stm32u083c_dk.dts +++ b/boards/st/stm32u083c_dk/stm32u083c_dk.dts @@ -23,6 +23,7 @@ zephyr,shell-uart = &usart2; zephyr,sram = &sram0; zephyr,flash = &flash0; + zephyr,code-partition = &slot0_partition; }; leds: leds { @@ -192,3 +193,31 @@ zephyr_udc0: &usb { clocks = <&rcc STM32_SRC_HSI48 CLK48_SEL(3)>; status = "okay"; }; + +&flash0 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 DT_SIZE_K(48)>; + }; + + slot0_partition: partition@c000 { + label = "image-0"; + reg = <0x0000c000 DT_SIZE_K(100)>; + }; + + slot1_partition: partition@25000 { + label = "image-1"; + reg = <0x00025000 DT_SIZE_K(102)>; + }; + + storage_partition: partition@3e800 { + label = "storage"; + reg = <0x0003e800 DT_SIZE_K(6)>; + }; + }; +}; diff --git a/boards/st/stm32wba65i_dk1/stm32wba65i_dk1.dts b/boards/st/stm32wba65i_dk1/stm32wba65i_dk1.dts index 4bf903506b9e..b28795d2f4ea 100644 --- a/boards/st/stm32wba65i_dk1/stm32wba65i_dk1.dts +++ b/boards/st/stm32wba65i_dk1/stm32wba65i_dk1.dts @@ -23,6 +23,7 @@ zephyr,shell-uart = &usart1; zephyr,sram = &sram0; zephyr,flash = &flash0; + zephyr,code-partition = &slot0_partition; }; leds: leds { @@ -183,9 +184,24 @@ stm32_lp_tick_source: &lptim1 { #address-cells = <1>; #size-cells = <1>; - storage_partition: partition@1c0000 { + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 DT_SIZE_K(64)>; + }; + + slot0_partition: partition@10000 { + label = "image-0"; + reg = <0x00010000 DT_SIZE_K(960)>; + }; + + slot1_partition: partition@100000 { + label = "image-1"; + reg = <0x00100000 DT_SIZE_K(968)>; + }; + + storage_partition: partition@1f2000 { label = "storage"; - reg = <0x001c0000 DT_SIZE_K(256)>; + reg = <0x001f2000 DT_SIZE_K(56)>; }; }; }; diff --git a/dts/arm/st/l1/stm32l1.dtsi b/dts/arm/st/l1/stm32l1.dtsi index 82b3e7fcba9d..46ea95cfda56 100644 --- a/dts/arm/st/l1/stm32l1.dtsi +++ b/dts/arm/st/l1/stm32l1.dtsi @@ -116,6 +116,7 @@ compatible = "st,stm32f4-nv-flash", "st,stm32-nv-flash", "soc-nv-flash"; + erase-block-size = <256>; write-block-size = <4>; /* maximum erase time(ms) for a 128B half-page */ From d55fc5b8571e0cfa5fc7c6eabda14574c30e1be0 Mon Sep 17 00:00:00 2001 From: Fabrice DJIATSA Date: Tue, 2 Dec 2025 17:34:18 +0100 Subject: [PATCH 0398/3659] boards: st: add support for boards compatible with swap using scratch SomeSTM32 series, like F2, F4, and F7, do not have homogeneous flash sector sizes; they include very large sectors such as 128 KB and even 256 KB. The scratch partition needs to be large enough to hold the largest sector size ( 256k for F7 and 128k for F2). Signed-off-by: Fabrice DJIATSA --- boards/st/nucleo_f207zg/nucleo_f207zg.dts | 12 ++++++-- boards/st/nucleo_f746zg/nucleo_f746zg.dts | 35 +++++++++++++++++++++++ 2 files changed, 44 insertions(+), 3 deletions(-) diff --git a/boards/st/nucleo_f207zg/nucleo_f207zg.dts b/boards/st/nucleo_f207zg/nucleo_f207zg.dts index ed4f550fdfad..da0b1cba39bd 100644 --- a/boards/st/nucleo_f207zg/nucleo_f207zg.dts +++ b/boards/st/nucleo_f207zg/nucleo_f207zg.dts @@ -20,6 +20,7 @@ zephyr,canbus = &can1; zephyr,sram = &sram0; zephyr,flash = &flash0; + zephyr,code-partition = &slot0_partition; }; leds: leds { @@ -247,12 +248,17 @@ zephyr_udc0: &usbotg_fs { slot0_partition: partition@20000 { label = "image-0"; - reg = <0x20000 DT_SIZE_K(448)>; + reg = <0x20000 DT_SIZE_K(384)>; }; - slot1_partition: partition@90000 { + slot1_partition: partition@60000 { label = "image-1"; - reg = <0x90000 DT_SIZE_K(448)>; + reg = <0x60000 DT_SIZE_K(384)>; + }; + + scratch_partition: partiimagtion@c0000 { + label = "image-scratch"; + reg = <0xc0000 DT_SIZE_K(128)>; }; }; }; diff --git a/boards/st/nucleo_f746zg/nucleo_f746zg.dts b/boards/st/nucleo_f746zg/nucleo_f746zg.dts index c76261768a1e..6ea7f0fb044f 100644 --- a/boards/st/nucleo_f746zg/nucleo_f746zg.dts +++ b/boards/st/nucleo_f746zg/nucleo_f746zg.dts @@ -28,6 +28,7 @@ zephyr,flash = &flash0; zephyr,dtcm = &dtcm; zephyr,canbus = &can1; + zephyr,code-partition = &slot0_partition; }; leds: leds { @@ -235,3 +236,37 @@ zephyr_udc0: &usbotg_fs { &vbat { status = "okay"; }; + +&flash0 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + /* set 4* 32KB */ + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 DT_SIZE_K(128)>; + }; + + storage_partition: partition@20000 { + label = "storage"; + reg = <0x00020000 DT_SIZE_K(256)>; + }; + + slot0_partition: partition@60000 { + label = "image-0"; + reg = <0x00060000 DT_SIZE_K(128)>; + }; + + slot1_partition: partition@80000 { + label = "image-1"; + reg = <0x00080000 DT_SIZE_K(128)>; + }; + + scratch_partition: partition@a0000 { + label = "image-scratch"; + reg = <0x000a0000 DT_SIZE_K(256)>; + }; + }; +}; From 602baf682966e26ecfac6907f441eb4d59a0f854 Mon Sep 17 00:00:00 2001 From: Fabrice DJIATSA Date: Tue, 2 Dec 2025 17:35:39 +0100 Subject: [PATCH 0399/3659] samples: sysbuild: with_mcuboot: update sample.yaml file Add STM32 supported boards for the test. Signed-off-by: Fabrice DJIATSA --- samples/sysbuild/with_mcuboot/sample.yaml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/samples/sysbuild/with_mcuboot/sample.yaml b/samples/sysbuild/with_mcuboot/sample.yaml index 5359ea467935..cc11a68cef71 100644 --- a/samples/sysbuild/with_mcuboot/sample.yaml +++ b/samples/sysbuild/with_mcuboot/sample.yaml @@ -14,12 +14,28 @@ tests: - esp32s3_devkitm/esp32s3/procpu - esp32c3_devkitm - esp32c6_devkitc/esp32c6/hpcore + - nucleo_c071rb + - nucleo_f091rc + - nucleo_f207zg + - nucleo_f429zi + - nucleo_f746zg + - nucleo_g071rb + - nucleo_g474re + - nucleo_h753zi - nucleo_h7s3l8 + - nucleo_l152re - nucleo_u385rg_q + - nucleo_wb55rg + - nucleo_wba65ri + - nucleo_wba55cg + - nucleo_wl55jc + - stm32f3_disco - stm32h7s78_dk/stm32h7s7xx/ext_flash_app - stm32h573i_dk - stm32h573i_dk/stm32h573xx/ext_flash_app - stm32h750b_dk/stm32h750xx/ext_flash_app + - stm32u083c_dk + - stm32wba65i_dk1 - sam_e54_xpro - pic32cx_sg41_cult integration_platforms: From 81c93141ddea61f67bee57aabdad0a6d885c8e34 Mon Sep 17 00:00:00 2001 From: Fabrice DJIATSA Date: Tue, 2 Dec 2025 17:39:03 +0100 Subject: [PATCH 0400/3659] tests: boot: test_mcuboot: update testcase.yaml file Add STM32 supported boards for the test. Signed-off-by: Fabrice DJIATSA --- tests/boot/test_mcuboot/testcase.yaml | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/tests/boot/test_mcuboot/testcase.yaml b/tests/boot/test_mcuboot/testcase.yaml index 0a7206ffa546..250cbeecb138 100644 --- a/tests/boot/test_mcuboot/testcase.yaml +++ b/tests/boot/test_mcuboot/testcase.yaml @@ -59,14 +59,25 @@ tests: - stm32h573i_dk/stm32h573xx/ext_flash_app - sam_e54_xpro - pic32cx_sg41_cult + - nucleo_c071rb + - nucleo_f091rc + - nucleo_g071rb + - nucleo_g474re + - nucleo_h753zi + - nucleo_u385rg_q + - nucleo_wb55rg + - nucleo_wba55cg + - nucleo_wba65ri + - nucleo_wl55jc + - stm32f3_disco + - stm32u083c_dk + - stm32wba65i_dk1 integration_platforms: - frdm_k64f - nrf52840dk/nrf52840 bootloader.mcuboot.assert: platform_allow: - - b_u585i_iot02a - stm32h750b_dk/stm32h750xx/ext_flash_app - - stm32h573i_dk - stm32h573i_dk/stm32h573xx/ext_flash_app extra_configs: - CONFIG_ASSERT=y @@ -75,9 +86,7 @@ tests: - frdm_k64f - nrf5340dk/nrf5340/cpuapp - nrf52840dk/nrf52840 - - nucleo_wba55cg - stm32h750b_dk/stm32h750xx/ext_flash_app - - stm32h573i_dk - stm32h573i_dk/stm32h573xx/ext_flash_app integration_platforms: - frdm_k64f From bdc79574c59643773e29e520d9b5725b66b09ce1 Mon Sep 17 00:00:00 2001 From: Fabrice DJIATSA Date: Tue, 2 Dec 2025 17:42:22 +0100 Subject: [PATCH 0401/3659] tests: boot: with_mcumgr: update testcase.yaml file Add STM32 supported boards for the test. Signed-off-by: Fabrice DJIATSA --- tests/boot/with_mcumgr/testcase.yaml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/tests/boot/with_mcumgr/testcase.yaml b/tests/boot/with_mcumgr/testcase.yaml index afaca20f90bd..b293ae2a5897 100644 --- a/tests/boot/with_mcumgr/testcase.yaml +++ b/tests/boot/with_mcumgr/testcase.yaml @@ -4,7 +4,18 @@ common: - nrf5340dk/nrf5340/cpuapp - nrf54l15dk/nrf54l15/cpuapp - nrf9160dk/nrf9160 + - nucleo_f091rc + - nucleo_g474re + - nucleo_h753zi + - nucleo_u385rg_q + - nucleo_wb55rg - nucleo_wba55cg + - nucleo_wba65ri + - nucleo_wl55jc + - stm32f3_disco + - stm32h573i_dk + - stm32u083c_dk + - stm32wba65i_dk1 timeout: 600 slow: true tags: @@ -27,7 +38,15 @@ tests: - nrf52840dk/nrf52840 platform_exclude: - nrf9160dk/nrf9160 + - nucleo_f091rc + - nucleo_g474re + - nucleo_h753zi + - nucleo_u385rg_q + - nucleo_wb55rg - nucleo_wba55cg + - nucleo_wl55jc + - stm32f3_disco + - stm32u083c_dk integration_platforms: - nrf52840dk/nrf52840 extra_args: EXTRA_CONF_FILE="overlay-bt.conf" From 2f48c25e9803cc97b9cb0206130670575ba23750 Mon Sep 17 00:00:00 2001 From: Fabrice DJIATSA Date: Thu, 4 Dec 2025 17:57:34 +0100 Subject: [PATCH 0402/3659] tests: drivers: flash: stm32: handle conflict for storage partition Since the addition of a new storage partition definition in the nucleo_f746zg dts, there is no need to have this configuration in the overlay file. Signed-off-by: Fabrice DJIATSA --- .../flash/stm32/boards/nucleo_f746zg.overlay | 19 ------------------- 1 file changed, 19 deletions(-) delete mode 100644 tests/drivers/flash/stm32/boards/nucleo_f746zg.overlay diff --git a/tests/drivers/flash/stm32/boards/nucleo_f746zg.overlay b/tests/drivers/flash/stm32/boards/nucleo_f746zg.overlay deleted file mode 100644 index ad661beb63b6..000000000000 --- a/tests/drivers/flash/stm32/boards/nucleo_f746zg.overlay +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (c) 2024 SILA Embedded Solutions GmbH - * - * SPDX-License-Identifier: Apache-2.0 - */ - -&flash0 { - partitions { - compatible = "fixed-partitions"; - #address-cells = <1>; - #size-cells = <1>; - - /* Reserve 4KiB of flash for storage_partition. */ - storage_partition: partition@f0000 { - label = "storage"; - reg = <0x000f0000 DT_SIZE_K(4)>; - }; - }; -}; From f09282ecdeeb051ae5877d12e362c074fa882151 Mon Sep 17 00:00:00 2001 From: Fabrice DJIATSA Date: Thu, 4 Dec 2025 18:02:45 +0100 Subject: [PATCH 0403/3659] release: migration-guide: 4.4: add entry about mcuboot mode STM32 platforms now use the default MCUboot operating mode swap using offset instead of swap using move. Signed-off-by: Fabrice DJIATSA --- doc/releases/migration-guide-4.4.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/doc/releases/migration-guide-4.4.rst b/doc/releases/migration-guide-4.4.rst index 0853c0ace75c..cffc4cdbb2e2 100644 --- a/doc/releases/migration-guide-4.4.rst +++ b/doc/releases/migration-guide-4.4.rst @@ -149,6 +149,13 @@ STM32 deprecated, but retained for backwards compatibility; **they will be removed in Zephyr 4.5**. The generic ``__dtcm_{data,bss,noinit}_section`` macros should be used instead. (:github:`100590`) +* STM32 platforms now use the default MCUboot operating mode ``swap using offset`` + (:kconfig:option:`SB_CONFIG_MCUBOOT_MODE_SWAP_USING_OFFSET`). To support this bootloader mode, + some changes to the board devicetrees are required. Several boards already support this mode + (see :github:`100385`). + The previous ``swap using move`` mode can still be selected in sysbuild by enabling + :kconfig:option:`SB_CONFIG_MCUBOOT_MODE_SWAP_USING_MOVE`. + Shell ===== From 91079cf8252fb2612fd5299377bd0ed7e7027169 Mon Sep 17 00:00:00 2001 From: Xavier Razavet Date: Tue, 2 Dec 2025 18:26:29 +0100 Subject: [PATCH 0404/3659] drivers: ieee802154: SSED attachment management Few functions have been corrected to the SSED attachment for the MCXW72 as leader : - mcxw_tx(): tx_frame.tx_delay corrected. Adjusts the scheduled transmission start time to account for the SHR duration (160us) as requested by the OpenThread radio API. - mcxw_rx_thread(): Stores the frame counter and key ID from a security-enabled enhanced ACK into the received packet's metadata for cryptographic verification. - mcxw_tx_started() added: Notifies the registered event handler that a frame transmission has started, passing the frame buffer as context. - pd_mac_sap_handler(): timestamp corrected - mcxw_configure(): IEEE802154_CONFIG_EVENT_HANDLER case updated Signed-off-by: Xavier Razavet --- drivers/ieee802154/ieee802154_mcxw.c | 54 +++++++++++++++------ drivers/ieee802154/ieee802154_mcxw.h | 70 +++++++++++++++++----------- 2 files changed, 81 insertions(+), 43 deletions(-) diff --git a/drivers/ieee802154/ieee802154_mcxw.c b/drivers/ieee802154/ieee802154_mcxw.c index 7f09313feb4b..b724c3a5cb6a 100644 --- a/drivers/ieee802154/ieee802154_mcxw.c +++ b/drivers/ieee802154/ieee802154_mcxw.c @@ -451,7 +451,7 @@ static int handle_ack(struct mcxw_context *mcxw_radio) net_pkt_set_ieee802154_lqi(pkt, mcxw_radio->rx_ack_frame.lqi); net_pkt_set_ieee802154_rssi_dbm(pkt, mcxw_radio->rx_ack_frame.rssi); - net_pkt_set_timestamp_ns(pkt, mcxw_radio->rx_ack_frame.timestamp); + net_pkt_set_timestamp_ns(pkt, mcxw_radio->rx_ack_frame.timestamp * NSEC_PER_USEC); net_pkt_cursor_init(pkt); @@ -467,6 +467,15 @@ static int handle_ack(struct mcxw_context *mcxw_radio) return err; } +static void mcxw_tx_started(const struct device *dev, struct net_pkt *pkt, struct net_buf *frag) +{ + ARG_UNUSED(pkt); + + if (mcxw_ctx.event_handler) { + mcxw_ctx.event_handler(dev, IEEE802154_EVENT_TX_STARTED, (void *)frag); + } +} + static int mcxw_tx(const struct device *dev, enum ieee802154_tx_mode mode, struct net_pkt *pkt, struct net_buf *frag) { @@ -540,7 +549,8 @@ static int mcxw_tx(const struct device *dev, enum ieee802154_tx_mode mode, struc #if defined(CONFIG_NET_PKT_TXTIME) case IEEE802154_TX_MODE_TXTIME: case IEEE802154_TX_MODE_TXTIME_CCA: - mcxw_radio->tx_frame.tx_delay = net_pkt_timestamp_ns(pkt); + mcxw_radio->tx_frame.tx_delay = net_pkt_timestamp_ns(pkt) / NSEC_PER_USEC; + mcxw_radio->tx_frame.tx_delay -= IEEE802154_SHR_DURATION_US; msg->msgData.dataReq.startTime = rf_adjust_tstamp_from_app(mcxw_radio->tx_frame.tx_delay); msg->msgData.dataReq.startTime /= IEEE802154_SYMBOL_TIME_US; @@ -596,20 +606,20 @@ static int mcxw_tx(const struct device *dev, enum ieee802154_tx_mode mode, struc k_sem_reset(&mcxw_radio->tx_wait); + mcxw_radio_state tmp_state = mcxw_radio->state; + + mcxw_radio->state = RADIO_STATE_TRANSMIT; + phy_status = MAC_PD_SapHandler(msg, ot_phy_ctx); if (phy_status == gPhySuccess_c) { - mcxw_radio->tx_status = 0; - mcxw_radio->state = RADIO_STATE_TRANSMIT; + mcxw_tx_started(dev, pkt, frag); } else { + mcxw_radio->state = tmp_state; return -EIO; } k_sem_take(&mcxw_radio->tx_wait, K_FOREVER); - /* PWR_AllowDeviceToSleep(); */ - - mcxw_radio_receive(); - switch (mcxw_radio->tx_status) { case 0: if (mcxw_radio->rx_ack_frame.length) { @@ -653,11 +663,16 @@ void mcxw_rx_thread(void *arg1, void *arg2, void *arg3) net_pkt_set_ieee802154_ack_fpb(pkt, rx_frame.ack_fpb); #if defined(CONFIG_NET_PKT_TIMESTAMP) - net_pkt_set_timestamp_ns(pkt, rx_frame.timestamp); + net_pkt_set_timestamp_ns(pkt, rx_frame.timestamp * NSEC_PER_USEC); #endif #if defined(CONFIG_NET_L2_OPENTHREAD) net_pkt_set_ieee802154_ack_seb(pkt, rx_frame.ack_seb); + + if (rx_frame.ack_seb) { + net_pkt_set_ieee802154_ack_fc(pkt, rx_frame.ack_fc); + net_pkt_set_ieee802154_ack_keyid(pkt, rx_frame.ack_keyid); + } #endif if (net_recv_data(mcxw_radio->iface, pkt) < 0) { LOG_ERR("Packet dropped by NET stack"); @@ -840,7 +855,6 @@ static void mcxw_receive_at(uint8_t channel, uint32_t start, uint32_t duration) start = rf_adjust_tstamp_from_app(start); msg.msgType = gPlmeSetTRxStateReq_c; - msg.msgData.setTRxStateReq.slottedMode = gPhyUnslottedMode_c; msg.msgData.setTRxStateReq.state = gPhySetRxOn_c; msg.msgData.setTRxStateReq.rxDuration = duration / IEEE802154_SYMBOL_TIME_US; msg.msgData.setTRxStateReq.startTime = start / IEEE802154_SYMBOL_TIME_US; @@ -1005,8 +1019,8 @@ static int mcxw_set_channel(const struct device *dev, uint16_t channel) static net_time_t mcxw_get_time(const struct device *dev) { - static uint64_t sw_timestamp; - static uint64_t hw_timestamp; + static uint64_t sw_timestamp; /* µs, last timestamp, monotonous */ + static uint64_t hw_timestamp; /* µs, last converted raw reading */ ARG_UNUSED(dev); @@ -1021,7 +1035,7 @@ static net_time_t mcxw_get_time(const struct device *dev) if (counter_get_value(mcxw_ctx.counter, &ticks)) { irq_unlock(key); - return -1; + return (net_time_t)-1; } hw_timestamp_new = counter_ticks_to_us(mcxw_ctx.counter, ticks); @@ -1110,7 +1124,8 @@ phyStatus_t pd_mac_sap_handler(void *msg, instanceId_t instance) mcxw_ctx.rx_ack_frame.length = data_msg->msgData.dataCnf.ackLength; mcxw_ctx.rx_ack_frame.lqi = data_msg->msgData.dataCnf.ppduLinkQuality; mcxw_ctx.rx_ack_frame.rssi = data_msg->msgData.dataCnf.ppduRssi; - mcxw_ctx.rx_ack_frame.timestamp = data_msg->msgData.dataCnf.timeStamp; + mcxw_ctx.rx_ack_frame.timestamp = + rf_adjust_tstamp_from_phy(data_msg->msgData.dataCnf.timeStamp); memcpy(mcxw_ctx.rx_ack_frame.psdu, data_msg->msgData.dataCnf.ackData, mcxw_ctx.rx_ack_frame.length); @@ -1130,7 +1145,14 @@ phyStatus_t pd_mac_sap_handler(void *msg, instanceId_t instance) rx_frame.ack_fpb = data_msg->msgData.dataInd.rxAckFp; rx_frame.length = data_msg->msgData.dataInd.psduLength; rx_frame.psdu = data_msg->msgData.dataInd.pPsdu; + +#if defined(CONFIG_NET_L2_OPENTHREAD) rx_frame.ack_seb = data_msg->msgData.dataInd.ackedWithSecEnhAck; + if (rx_frame.ack_seb) { + rx_frame.ack_fc = data_msg->msgData.dataInd.ackFrameCounter; + rx_frame.ack_keyid = data_msg->msgData.dataInd.ackKeyId; + } +#endif rx_frame.phy_buffer = (void *)msg; @@ -1293,7 +1315,8 @@ static int mcxw_configure(const struct device *dev, enum ieee802154_config_type #if defined(CONFIG_IEEE802154_CSL_ENDPOINT) case IEEE802154_CONFIG_EXPECTED_RX_TIME: - mcxw_ctx.csl_sample_time = config->expected_rx_time; + /* CSL endpoint (SSED) */ + mcxw_ctx.csl_sample_time = config->expected_rx_time / NSEC_PER_USEC; break; case IEEE802154_CONFIG_RX_SLOT: @@ -1315,6 +1338,7 @@ static int mcxw_configure(const struct device *dev, enum ieee802154_config_type break; case IEEE802154_CONFIG_EVENT_HANDLER: + mcxw_ctx.event_handler = config->event_handler; break; default: diff --git a/drivers/ieee802154/ieee802154_mcxw.h b/drivers/ieee802154/ieee802154_mcxw.h index eb3fb284dc6e..17f3157fcec0 100644 --- a/drivers/ieee802154/ieee802154_mcxw.h +++ b/drivers/ieee802154/ieee802154_mcxw.h @@ -15,38 +15,43 @@ #define TX_ENCRYPT_DELAY_SYM 200 -#define DEFAULT_CHANNEL (11) -#define DEFAULT_CCA_MODE (gPhyCCAMode1_c) -#define IEEE802154_ACK_REQUEST (1 << 5) -#define IEEE802154_MIN_LENGTH (5) -#define IEEE802154_FRM_CTL_LO_OFFSET (0) -#define IEEE802154_DSN_OFFSET (2) -#define IEEE802154_FRM_TYPE_MASK (0x7) -#define IEEE802154_FRM_TYPE_ACK (0x2) -#define IEEE802154_SYMBOL_TIME_US (16) -#define IEEE802154_TURNAROUND_LEN_SYM (12) -#define IEEE802154_CCA_LEN_SYM (8) -#define IEEE802154_PHY_SHR_LEN_SYM (10) -#define IEEE802154_IMM_ACK_WAIT_SYM (54) -#define IEEE802154_ENH_ACK_WAIT_SYM (90) - -#define NMAX_RXRING_BUFFERS (8) -#define RX_ON_IDLE_START (1) -#define RX_ON_IDLE_STOP (0) - -#define PHY_TMR_MAX_VALUE (0x00FFFFFF) +#define DEFAULT_CHANNEL (11) +#define DEFAULT_CCA_MODE (gPhyCCAMode1_c) +#define IEEE802154_ACK_REQUEST (1 << 5) +#define IEEE802154_MIN_LENGTH (5) +#define IEEE802154_FRM_CTL_LO_OFFSET (0) +#define IEEE802154_DSN_OFFSET (2) +#define IEEE802154_FRM_TYPE_MASK (0x7) +#define IEEE802154_FRM_TYPE_ACK (0x2) +#define IEEE802154_SYMBOL_TIME_US (16) +#define IEEE802154_TURNAROUND_LEN_SYM (12) +#define IEEE802154_CCA_LEN_SYM (8) +#define IEEE802154_PHY_SHR_LEN_SYM (10) +#define IEEE802154_IMM_ACK_WAIT_SYM (54) +#define IEEE802154_ENH_ACK_WAIT_SYM (90) + +#define NMAX_RXRING_BUFFERS (8) +#define RX_ON_IDLE_START (1) +#define RX_ON_IDLE_STOP (0) + +#define PHY_TMR_MAX_VALUE (0x00FFFFFF) /* The Uncertainty of the scheduling CSL of transmission by the parent, in ±10 us units. */ #define CSL_UNCERT 32 -#define RADIO_SYMBOLS_PER_OCTET (2) +/* Duration in microseconds of the IEEE 802.15.4 Synchronization Header + * (preamble + SFD) transmitted before the MAC payload. + */ + #define IEEE802154_SHR_DURATION_US 160 + +#define RADIO_SYMBOLS_PER_OCTET (2) typedef enum mcxw_radio_state { RADIO_STATE_DISABLED = 0, - RADIO_STATE_SLEEP = 1, - RADIO_STATE_RECEIVE = 2, + RADIO_STATE_SLEEP = 1, + RADIO_STATE_RECEIVE = 2, RADIO_STATE_TRANSMIT = 3, - RADIO_STATE_INVALID = 255, + RADIO_STATE_INVALID = 255, } mcxw_radio_state; typedef struct mcxw_rx_frame { @@ -54,18 +59,22 @@ typedef struct mcxw_rx_frame { uint8_t length; int8_t rssi; uint8_t lqi; - uint32_t timestamp; + uint64_t timestamp; bool ack_fpb; - bool ack_seb; uint64_t time; void *phy_buffer; uint8_t channel; +#if defined(CONFIG_NET_L2_OPENTHREAD) + uint32_t ack_fc; /* ACK frame counter */ + uint8_t ack_keyid; /* ACK key ID */ + bool ack_seb; /* Security Enabled Bit in ACK */ +#endif } mcxw_rx_frame; typedef struct mcxw_tx_frame { uint8_t *psdu; uint8_t length; - uint32_t tx_delay; + net_time_t tx_delay; uint32_t tx_delay_base; bool sec_processed; bool hdr_updated; @@ -117,9 +126,14 @@ struct mcxw_context { /* CSL period */ uint32_t csl_period; /* CSL sample time in microseconds */ - uint32_t csl_sample_time; + net_time_t csl_sample_time; /* PHY context */ uint8_t ot_phy_ctx; + + /* Callback handler to notify of any important radio events. + * Can be NULL if event notification is not needed. + */ + ieee802154_event_cb_t event_handler; }; #endif /* ZEPHYR_DRIVERS_IEEE802154_IEEE802154_MCXW_H_ */ From 536c937162eca79d51cfacc11a193c2f9ec50381 Mon Sep 17 00:00:00 2001 From: Xavier Razavet Date: Wed, 3 Dec 2025 15:38:25 +0100 Subject: [PATCH 0405/3659] samples: openthread: shell: .conf files updated frdm_mcxw71.conf: LOGs removed for RAM size optimization. prj-ot-host.conf: LOGs removed because already in prj.conf. Signed-off-by: Xavier Razavet --- samples/net/openthread/shell/boards/frdm_mcxw71.conf | 4 ++++ samples/net/openthread/shell/prj-ot-host.conf | 4 ---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/samples/net/openthread/shell/boards/frdm_mcxw71.conf b/samples/net/openthread/shell/boards/frdm_mcxw71.conf index 292c9be5cd64..5bcc05259f69 100644 --- a/samples/net/openthread/shell/boards/frdm_mcxw71.conf +++ b/samples/net/openthread/shell/boards/frdm_mcxw71.conf @@ -7,3 +7,7 @@ CONFIG_MAIN_STACK_SIZE=2048 #shell CONFIG_SHELL_STACK_SIZE=2048 + +# Logging +CONFIG_LOG=n +CONFIG_NET_LOG=n diff --git a/samples/net/openthread/shell/prj-ot-host.conf b/samples/net/openthread/shell/prj-ot-host.conf index 6c34b407e352..1565846414bd 100644 --- a/samples/net/openthread/shell/prj-ot-host.conf +++ b/samples/net/openthread/shell/prj-ot-host.conf @@ -4,10 +4,6 @@ CONFIG_NETWORKING=y CONFIG_NET_L2_OPENTHREAD=y -# Logging -CONFIG_LOG=y -CONFIG_NET_LOG=y - # Networking and OpenThread shells CONFIG_SHELL=y CONFIG_NET_SHELL=y From f6b3101db8122a15331153f349c5b7d806bcfee6 Mon Sep 17 00:00:00 2001 From: Xavier Razavet Date: Wed, 3 Dec 2025 15:43:08 +0100 Subject: [PATCH 0406/3659] dts: arm: nxp: MCXW72 corrected on the lptmr clock frequency The lptmr clock frequency was wrong and equal to 32000. The clock frequency is 32.768KHz (32768). Signed-off-by: Xavier Razavet --- dts/arm/nxp/nxp_mcxw7x_common.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dts/arm/nxp/nxp_mcxw7x_common.dtsi b/dts/arm/nxp/nxp_mcxw7x_common.dtsi index ce32007af7e1..d29a88276074 100644 --- a/dts/arm/nxp/nxp_mcxw7x_common.dtsi +++ b/dts/arm/nxp/nxp_mcxw7x_common.dtsi @@ -334,7 +334,7 @@ compatible = "nxp,lptmr"; reg = <0x2d000 0x10>; interrupts = <34 0>; - clock-frequency = ; + clock-frequency = <32768>; clk-source = <2>; prescale-glitch-filter = <0>; resolution = <32>; @@ -345,7 +345,7 @@ compatible = "nxp,lptmr"; reg = <0x2e000 0x10>; interrupts = <35 0>; - clock-frequency = ; + clock-frequency = <32768>; clk-source = <2>; prescale-glitch-filter = <0>; resolution = <32>; From aef5728e57574472ddbe59546a00782d03e8ee4f Mon Sep 17 00:00:00 2001 From: Xavier Razavet Date: Wed, 3 Dec 2025 15:46:12 +0100 Subject: [PATCH 0407/3659] drivers: ieee802154: mcxw ieee802154 driver updated To support the SSED attachment, the IEEE802154_MCXW_CSL_ACCURACY default value shall be 50. Signed-off-by: Xavier Razavet --- drivers/ieee802154/Kconfig.mcxw | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/ieee802154/Kconfig.mcxw b/drivers/ieee802154/Kconfig.mcxw index 4e41e8e409a3..b43a0d57caa1 100644 --- a/drivers/ieee802154/Kconfig.mcxw +++ b/drivers/ieee802154/Kconfig.mcxw @@ -8,6 +8,8 @@ menuconfig IEEE802154_MCXW default y depends on DT_HAS_NXP_MCXW_IEEE802154_ENABLED select COUNTER + select NET_PKT_TXTIME + select NET_PKT_TIMESTAMP if IEEE802154_MCXW @@ -19,10 +21,8 @@ config IEEE802154_MCXW_RX_STACK_SIZE int "Driver's internal RX thread stack size" default 800 - config IEEE802154_MCXW_CSL_ACCURACY int "Csl accuracy for delayed operations" - default 100 - + default 50 endif From 2264f9901cde0fd71d4b8257ae9d480eedda5613 Mon Sep 17 00:00:00 2001 From: Xavier Razavet Date: Wed, 3 Dec 2025 15:52:26 +0100 Subject: [PATCH 0408/3659] soc: nxp: MCXW7x configuration updated for CSL The default MCXW7x platform's clock uncertainty in microseconds for Coordinated Sampled Listening (CSL) timing synchronization in OpenThread shall be set to 20. Signed-off-by: Xavier Razavet --- soc/nxp/mcx/mcxw/Kconfig.defconfig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/soc/nxp/mcx/mcxw/Kconfig.defconfig b/soc/nxp/mcx/mcxw/Kconfig.defconfig index 43bbb470acf1..eeb625f2a1a1 100644 --- a/soc/nxp/mcx/mcxw/Kconfig.defconfig +++ b/soc/nxp/mcx/mcxw/Kconfig.defconfig @@ -8,4 +8,7 @@ if SOC_FAMILY_MCXW config CORTEX_M_SYSTICK default n if MCUX_LPTMR_TIMER +config OPENTHREAD_PLATFORM_CSL_UNCERT + default 20 if OPENTHREAD + endif # SOC_FAMILY_MCXW From 049d3685246d10a0a66ba4b644e2f61568c42997 Mon Sep 17 00:00:00 2001 From: "Trond F. Christiansen" Date: Mon, 8 Dec 2025 10:13:20 +0100 Subject: [PATCH 0409/3659] sensor: bmm350: Fix I2C register write to use single transaction The bmm350_prep_reg_write_rtio_async() function was incorrectly using two separate SQEs for register writes, creating two distinct I2C transactions: Before: [START][ADDR+W][REG][RESTART] + [START][ADDR+W][DATA][STOP] Change to use a single SQE for the entire write: After: [START][ADDR+W][REG][DATA][STOP] Signed-off-by: Trond F. Christiansen --- drivers/sensor/bosch/bmm350/bmm350_bus.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/drivers/sensor/bosch/bmm350/bmm350_bus.c b/drivers/sensor/bosch/bmm350/bmm350_bus.c index e82455e66dd3..d567f207654a 100644 --- a/drivers/sensor/bosch/bmm350/bmm350_bus.c +++ b/drivers/sensor/bosch/bmm350/bmm350_bus.c @@ -52,27 +52,29 @@ static int bmm350_prep_reg_write_rtio_async(const struct bmm350_bus *bus, { struct rtio *ctx = bus->rtio.ctx; struct rtio_iodev *iodev = bus->rtio.iodev; - struct rtio_sqe *write_reg_sqe = rtio_sqe_acquire(ctx); - struct rtio_sqe *write_buf_sqe = rtio_sqe_acquire(ctx); + struct rtio_sqe *write_sqe = rtio_sqe_acquire(ctx); + uint8_t write_buf[2]; - if (!write_reg_sqe || !write_buf_sqe) { + if (!write_sqe) { rtio_sqe_drop_all(ctx); return -ENOMEM; } - rtio_sqe_prep_tiny_write(write_reg_sqe, iodev, RTIO_PRIO_NORM, ®, 1, NULL); - write_reg_sqe->flags |= RTIO_SQE_TRANSACTION; - rtio_sqe_prep_tiny_write(write_buf_sqe, iodev, RTIO_PRIO_NORM, &val, 1, NULL); + write_buf[0] = reg; + write_buf[1] = val; + + /* Single I2C transaction: [W(addr), reg, data] */ + rtio_sqe_prep_tiny_write(write_sqe, iodev, RTIO_PRIO_NORM, write_buf, 2, NULL); if (bus->rtio.type == BMM350_BUS_TYPE_I2C) { - write_buf_sqe->iodev_flags |= RTIO_IODEV_I2C_STOP; + write_sqe->iodev_flags |= RTIO_IODEV_I2C_STOP; } - /** Send back last SQE so it can be concatenated later. */ + /** Send back SQE so it can be concatenated later. */ if (out) { - *out = write_buf_sqe; + *out = write_sqe; } - return 2; + return 1; } static int bmm350_reg_read_rtio(const struct bmm350_bus *bus, uint8_t start, uint8_t *buf, int size) From 92365ed4b74339e5f9b7233ac64e5e5b2ddcc9ba Mon Sep 17 00:00:00 2001 From: Tim Pambor Date: Wed, 10 Dec 2025 11:42:50 +0100 Subject: [PATCH 0410/3659] drivers: clock_control: stm32{h5,u5}: fix PLL rate with fractional PLL When calculating the PLL output rate, take into account the fractional part of the PLL multiplier N. This ensures that the calculated output frequency is correct. Signed-off-by: Tim Pambor --- drivers/clock_control/clock_stm32_ll_h5.c | 24 +++++++++++++++---- drivers/clock_control/clock_stm32_ll_u5.c | 24 +++++++++++++++---- .../clock_control/stm32_clock_control.h | 8 +++---- 3 files changed, 44 insertions(+), 12 deletions(-) diff --git a/drivers/clock_control/clock_stm32_ll_h5.c b/drivers/clock_control/clock_stm32_ll_h5.c index 80a165e2ea09..341915539d2e 100644 --- a/drivers/clock_control/clock_stm32_ll_h5.c +++ b/drivers/clock_control/clock_stm32_ll_h5.c @@ -40,6 +40,8 @@ #define PLL2_ID 2 #define PLL3_ID 3 +#define PLL_FRACN_DIVISOR 8192 + static uint32_t get_bus_clock(uint32_t clock, uint32_t prescaler) { return clock / prescaler; @@ -87,13 +89,17 @@ static uint32_t get_startup_frequency(void) __unused static uint32_t get_pllout_frequency(uint32_t pllsrc_freq, - int pllm_div, - int plln_mul, - int pllout_div) + unsigned int pllm_div, + unsigned int plln_mul, + unsigned int plln_frac, + unsigned int pllout_div) { __ASSERT_NO_MSG(pllm_div && pllout_div); - return (pllsrc_freq / pllm_div) * plln_mul / pllout_div; + uint32_t f_vco = (pllsrc_freq / pllm_div) * + ((uint64_t)plln_mul * PLL_FRACN_DIVISOR + plln_frac) / PLL_FRACN_DIVISOR; + + return f_vco / pllout_div; } static uint32_t get_sysclk_frequency(void) @@ -102,6 +108,7 @@ static uint32_t get_sysclk_frequency(void) return get_pllout_frequency(get_pllsrc_frequency(PLL1_ID), STM32_PLL_M_DIVISOR, STM32_PLL_N_MULTIPLIER, + STM32_PLL_FRACN_VALUE, STM32_PLL_R_DIVISOR); #elif defined(STM32_SYSCLK_SRC_CSI) return STM32_CSI_FREQ; @@ -290,18 +297,21 @@ static int stm32_clock_control_get_subsys_rate(const struct device *dev, *rate = get_pllout_frequency(get_pllsrc_frequency(PLL1_ID), STM32_PLL_M_DIVISOR, STM32_PLL_N_MULTIPLIER, + STM32_PLL_FRACN_VALUE, STM32_PLL_P_DIVISOR); break; case STM32_SRC_PLL1_Q: *rate = get_pllout_frequency(get_pllsrc_frequency(PLL1_ID), STM32_PLL_M_DIVISOR, STM32_PLL_N_MULTIPLIER, + STM32_PLL_FRACN_VALUE, STM32_PLL_Q_DIVISOR); break; case STM32_SRC_PLL1_R: *rate = get_pllout_frequency(get_pllsrc_frequency(PLL1_ID), STM32_PLL_M_DIVISOR, STM32_PLL_N_MULTIPLIER, + STM32_PLL_FRACN_VALUE, STM32_PLL_R_DIVISOR); break; #endif /* STM32_PLL_ENABLED */ @@ -310,18 +320,21 @@ static int stm32_clock_control_get_subsys_rate(const struct device *dev, *rate = get_pllout_frequency(get_pllsrc_frequency(PLL2_ID), STM32_PLL2_M_DIVISOR, STM32_PLL2_N_MULTIPLIER, + STM32_PLL2_FRACN_VALUE, STM32_PLL2_P_DIVISOR); break; case STM32_SRC_PLL2_Q: *rate = get_pllout_frequency(get_pllsrc_frequency(PLL2_ID), STM32_PLL2_M_DIVISOR, STM32_PLL2_N_MULTIPLIER, + STM32_PLL2_FRACN_VALUE, STM32_PLL2_Q_DIVISOR); break; case STM32_SRC_PLL2_R: *rate = get_pllout_frequency(get_pllsrc_frequency(PLL2_ID), STM32_PLL2_M_DIVISOR, STM32_PLL2_N_MULTIPLIER, + STM32_PLL2_FRACN_VALUE, STM32_PLL2_R_DIVISOR); break; #endif /* STM32_PLL2_ENABLED */ @@ -330,18 +343,21 @@ static int stm32_clock_control_get_subsys_rate(const struct device *dev, *rate = get_pllout_frequency(get_pllsrc_frequency(PLL3_ID), STM32_PLL3_M_DIVISOR, STM32_PLL3_N_MULTIPLIER, + STM32_PLL3_FRACN_VALUE, STM32_PLL3_P_DIVISOR); break; case STM32_SRC_PLL3_Q: *rate = get_pllout_frequency(get_pllsrc_frequency(PLL3_ID), STM32_PLL3_M_DIVISOR, STM32_PLL3_N_MULTIPLIER, + STM32_PLL3_FRACN_VALUE, STM32_PLL3_Q_DIVISOR); break; case STM32_SRC_PLL3_R: *rate = get_pllout_frequency(get_pllsrc_frequency(PLL3_ID), STM32_PLL3_M_DIVISOR, STM32_PLL3_N_MULTIPLIER, + STM32_PLL3_FRACN_VALUE, STM32_PLL3_R_DIVISOR); break; #endif /* STM32_PLL3_ENABLED */ diff --git a/drivers/clock_control/clock_stm32_ll_u5.c b/drivers/clock_control/clock_stm32_ll_u5.c index 8b592f0f67cc..6a6434de316f 100644 --- a/drivers/clock_control/clock_stm32_ll_u5.c +++ b/drivers/clock_control/clock_stm32_ll_u5.c @@ -37,6 +37,8 @@ #define PLL2_ID 2 #define PLL3_ID 3 +#define PLL_FRACN_DIVISOR 8192 + /* Shorthand for Power Controller node */ #define PWR_NODE DT_NODELABEL(pwr) @@ -103,13 +105,17 @@ static uint32_t get_startup_frequency(void) __unused static uint32_t get_pllout_frequency(uint32_t pllsrc_freq, - int pllm_div, - int plln_mul, - int pllout_div) + unsigned int pllm_div, + unsigned int plln_mul, + unsigned int plln_frac, + unsigned int pllout_div) { __ASSERT_NO_MSG(pllm_div && pllout_div); - return (pllsrc_freq / pllm_div) * plln_mul / pllout_div; + uint32_t f_vco = (pllsrc_freq / pllm_div) * + ((uint64_t)plln_mul * PLL_FRACN_DIVISOR + plln_frac) / PLL_FRACN_DIVISOR; + + return f_vco / pllout_div; } static uint32_t get_sysclk_frequency(void) @@ -118,6 +124,7 @@ static uint32_t get_sysclk_frequency(void) return get_pllout_frequency(get_pllsrc_frequency(PLL1_ID), STM32_PLL_M_DIVISOR, STM32_PLL_N_MULTIPLIER, + STM32_PLL_FRACN_VALUE, STM32_PLL_R_DIVISOR); #elif defined(STM32_SYSCLK_SRC_MSIS) return get_msis_frequency(); @@ -318,18 +325,21 @@ static int stm32_clock_control_get_subsys_rate(const struct device *dev, *rate = get_pllout_frequency(get_pllsrc_frequency(PLL1_ID), STM32_PLL_M_DIVISOR, STM32_PLL_N_MULTIPLIER, + STM32_PLL_FRACN_VALUE, STM32_PLL_P_DIVISOR); break; case STM32_SRC_PLL1_Q: *rate = get_pllout_frequency(get_pllsrc_frequency(PLL1_ID), STM32_PLL_M_DIVISOR, STM32_PLL_N_MULTIPLIER, + STM32_PLL_FRACN_VALUE, STM32_PLL_Q_DIVISOR); break; case STM32_SRC_PLL1_R: *rate = get_pllout_frequency(get_pllsrc_frequency(PLL1_ID), STM32_PLL_M_DIVISOR, STM32_PLL_N_MULTIPLIER, + STM32_PLL_FRACN_VALUE, STM32_PLL_R_DIVISOR); break; #endif /* STM32_PLL_ENABLED */ @@ -338,18 +348,21 @@ static int stm32_clock_control_get_subsys_rate(const struct device *dev, *rate = get_pllout_frequency(get_pllsrc_frequency(PLL2_ID), STM32_PLL2_M_DIVISOR, STM32_PLL2_N_MULTIPLIER, + STM32_PLL2_FRACN_VALUE, STM32_PLL2_P_DIVISOR); break; case STM32_SRC_PLL2_Q: *rate = get_pllout_frequency(get_pllsrc_frequency(PLL2_ID), STM32_PLL2_M_DIVISOR, STM32_PLL2_N_MULTIPLIER, + STM32_PLL2_FRACN_VALUE, STM32_PLL2_Q_DIVISOR); break; case STM32_SRC_PLL2_R: *rate = get_pllout_frequency(get_pllsrc_frequency(PLL2_ID), STM32_PLL2_M_DIVISOR, STM32_PLL2_N_MULTIPLIER, + STM32_PLL2_FRACN_VALUE, STM32_PLL2_R_DIVISOR); break; #endif /* STM32_PLL2_ENABLED */ @@ -358,18 +371,21 @@ static int stm32_clock_control_get_subsys_rate(const struct device *dev, *rate = get_pllout_frequency(get_pllsrc_frequency(PLL3_ID), STM32_PLL3_M_DIVISOR, STM32_PLL3_N_MULTIPLIER, + STM32_PLL3_FRACN_VALUE, STM32_PLL3_P_DIVISOR); break; case STM32_SRC_PLL3_Q: *rate = get_pllout_frequency(get_pllsrc_frequency(PLL3_ID), STM32_PLL3_M_DIVISOR, STM32_PLL3_N_MULTIPLIER, + STM32_PLL3_FRACN_VALUE, STM32_PLL3_Q_DIVISOR); break; case STM32_SRC_PLL3_R: *rate = get_pllout_frequency(get_pllsrc_frequency(PLL3_ID), STM32_PLL3_M_DIVISOR, STM32_PLL3_N_MULTIPLIER, + STM32_PLL3_FRACN_VALUE, STM32_PLL3_R_DIVISOR); break; #endif /* STM32_PLL3_ENABLED */ diff --git a/include/zephyr/drivers/clock_control/stm32_clock_control.h b/include/zephyr/drivers/clock_control/stm32_clock_control.h index 1f900b5e538a..f5e438d7e5a6 100644 --- a/include/zephyr/drivers/clock_control/stm32_clock_control.h +++ b/include/zephyr/drivers/clock_control/stm32_clock_control.h @@ -204,7 +204,7 @@ #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) +#define STM32_PLL_FRACN_VALUE DT_PROP_OR(DT_NODELABEL(pll), fracn, 0) #endif #if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(plli2s), st_stm32f4_plli2s_clock, okay) @@ -293,7 +293,7 @@ #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) +#define STM32_PLL2_FRACN_VALUE DT_PROP_OR(DT_NODELABEL(pll2), fracn, 0) #endif #if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll3), st_stm32h7_pll_clock, okay) || \ @@ -312,7 +312,7 @@ #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) +#define STM32_PLL3_FRACN_VALUE DT_PROP_OR(DT_NODELABEL(pll3), fracn, 0) #endif #if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll4), st_stm32mp13_pll_clock, okay) @@ -326,7 +326,7 @@ #define STM32_PLL4_R_ENABLED DT_NODE_HAS_PROP(DT_NODELABEL(pll4), div_r) #define STM32_PLL4_R_DIVISOR DT_PROP_OR(DT_NODELABEL(pll4), div_r, 1) #define STM32_PLL4_FRACN_ENABLED DT_NODE_HAS_PROP(DT_NODELABEL(pll4), fracn) -#define STM32_PLL4_FRACN_VALUE DT_PROP_OR(DT_NODELABEL(pll4), fracn, 1) +#define STM32_PLL4_FRACN_VALUE DT_PROP_OR(DT_NODELABEL(pll4), fracn, 0) #endif #if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll), st_stm32f1_pll_clock, okay) From 9399183944287a05608443dc2586baf742c04202 Mon Sep 17 00:00:00 2001 From: Tim Pambor Date: Wed, 10 Dec 2025 19:56:59 +0100 Subject: [PATCH 0411/3659] drivers: rtc: rv3028: add calibration support Add support for RTC calibration API by implementing set_calibration and get_calibration functions. RV3028 RTC supports calibration to adjust for errors from +243.2 ppm to -244.1 ppm in steps of 0.9537 ppm. Signed-off-by: Tim Pambor --- drivers/rtc/rtc_rv3028.c | 104 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) diff --git a/drivers/rtc/rtc_rv3028.c b/drivers/rtc/rtc_rv3028.c index 2fa6719ba798..95b9d43a18cf 100644 --- a/drivers/rtc/rtc_rv3028.c +++ b/drivers/rtc/rtc_rv3028.c @@ -83,9 +83,12 @@ LOG_MODULE_REGISTER(rv3028, CONFIG_RTC_LOG_LEVEL); #define RV3028_CLKOUT_FD_LOW 0x7 +#define RV3028_OFFSET_SIGN_BIT_INDEX 8 + #define RV3028_BACKUP_TCE BIT(5) #define RV3028_BACKUP_TCR GENMASK(1, 0) #define RV3028_BACKUP_BSM GENMASK(3, 2) +#define RV3028_BACKUP_OFFSET_BIT_INDEX 7 #define RV3028_BSM_LEVEL 0x3 #define RV3028_BSM_DIRECT 0x1 @@ -123,6 +126,23 @@ LOG_MODULE_REGISTER(rv3028, CONFIG_RTC_LOG_LEVEL); /* The RV3028 enumerates months 1 to 12 */ #define RV3028_MONTH_OFFSET 1 +/* Convert part per billion calibration value to a number of clock pulses added or removed each + * 2^20 clock cycles so it is suitable for the EEOffset register field + * + * nb_pulses = ppb * 2^20 / 10^9 = ppb * 2^11 / 5^9 = ppb * 2048 / 1953125 + */ +#define PPB_TO_NB_PULSES(ppb) DIV_ROUND_CLOSEST((ppb) * 2048, 1953125) + +/* Convert EEOffset register value (number of clock pulses added or removed each 2^20 clock cycles) + * to part ber billion calibration value + * + * ppb = nb_pulses * 10^9 / 2^20 = nb_pulses * 5^9 / 2^11 = nb_pulses * 1953125 / 2048 + */ +#define NB_PULSES_TO_PPB(pulses) DIV_ROUND_CLOSEST((pulses) * 1953125, 2048) + +#define MAX_PPB NB_PULSES_TO_PPB(255) +#define MIN_PPB NB_PULSES_TO_PPB(-256) + #define RV3028_EEBUSY_READ_POLL_MS 1 #define RV3028_EEBUSY_WRITE_POLL_MS 10 #define RV3028_EEBUSY_TIMEOUT_MS 100 @@ -761,6 +781,86 @@ static int rv3028_update_set_callback(const struct device *dev, rtc_update_callb #endif /* RV3028_INT_GPIOS_IN_USE && defined(CONFIG_RTC_UPDATE) */ +#ifdef CONFIG_RTC_CALIBRATION +static int rv3028_set_calibration(const struct device *dev, int32_t freq_ppb) +{ + int err; + int32_t nb_pulses; + uint16_t offset; + uint8_t val_backup; + + if ((freq_ppb > MAX_PPB) || (freq_ppb < MIN_PPB)) { + /* out of supported range */ + return -EINVAL; + } + + nb_pulses = PPB_TO_NB_PULSES(freq_ppb); + offset = nb_pulses & 0x1FF; + + LOG_DBG("Set calibration: frequency ppb: %d, offset value: %d", NB_PULSES_TO_PPB(nb_pulses), + offset); + + /* 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) { + rv3028_exit_eerd(dev); + return err; + } + + err = rv3028_read_reg8(dev, RV3028_REG_BACKUP, &val_backup); + if (err) { + rv3028_exit_eerd(dev); + return err; + } + + /* LSB of offset is stored in BACKUP register */ + val_backup &= ~BIT(RV3028_BACKUP_OFFSET_BIT_INDEX); + val_backup |= (offset & 0x01) << RV3028_BACKUP_OFFSET_BIT_INDEX; + + err = rv3028_write_reg8(dev, RV3028_REG_BACKUP, val_backup); + if (err) { + rv3028_exit_eerd(dev); + return err; + } + + err = rv3028_write_reg8(dev, RV3028_REG_OFFSET, offset >> 1); + if (err) { + rv3028_exit_eerd(dev); + return err; + } + + return rv3028_update(dev); +} + +static int rv3028_get_calibration(const struct device *dev, int32_t *freq_ppb) +{ + uint8_t regs[2]; + int err; + uint16_t offset; + int32_t nb_pulses; + + /* Read OFFSET and BACKUP register */ + err = rv3028_read_regs(dev, RV3028_REG_OFFSET, regs, sizeof(regs)); + if (err) { + return err; + } + + /* LSB of offset is stored in BACKUP register */ + offset = (regs[0] << 1) | ((regs[1] & BIT(RV3028_BACKUP_OFFSET_BIT_INDEX)) >> + RV3028_BACKUP_OFFSET_BIT_INDEX); + nb_pulses = sign_extend(offset, RV3028_OFFSET_SIGN_BIT_INDEX); + *freq_ppb = NB_PULSES_TO_PPB(nb_pulses); + + LOG_DBG("Get calibration: frequency ppb: %d, offset value: %d", *freq_ppb, offset); + + return 0; +} +#endif /* CONFIG_RTC_CALIBRATION */ + static int rv3028_init(const struct device *dev) { const struct rv3028_config *config = dev->config; @@ -908,6 +1008,10 @@ static DEVICE_API(rtc, rv3028_driver_api) = { #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) */ +#ifdef CONFIG_RTC_CALIBRATION + .set_calibration = rv3028_set_calibration, + .get_calibration = rv3028_get_calibration +#endif /* CONFIG_RTC_CALIBRATION */ }; #define RV3028_BSM_FROM_DT_INST(inst) \ From f8ffcbde17672530cb07c5d9f21c5ae6f1f46cf3 Mon Sep 17 00:00:00 2001 From: Julien Racki Date: Thu, 11 Dec 2025 09:29:22 +0100 Subject: [PATCH 0412/3659] drivers: i2c: stm32: Fix hang on read log position Ensure that data is transmitted before logging as it could cause lockups in some setups. Also update i2c_stm32_v2_rtio.c to match this behavior to always send data in order to avoid the I2C to lockup. Signed-off-by: Julien Racki --- drivers/i2c/i2c_stm32_v2.c | 10 +++++++--- drivers/i2c/i2c_stm32_v2_rtio.c | 13 +++++++++---- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/drivers/i2c/i2c_stm32_v2.c b/drivers/i2c/i2c_stm32_v2.c index 26827e6cf587..81ed208c754e 100644 --- a/drivers/i2c/i2c_stm32_v2.c +++ b/drivers/i2c/i2c_stm32_v2.c @@ -270,13 +270,17 @@ static void i2c_stm32_slave_event(const struct device *dev) if (LL_I2C_IsActiveFlag_TXIS(i2c)) { uint8_t val = 0x00; + int ret = slave_cb->read_processed(slave_cfg, &val); - if (slave_cb->read_processed(slave_cfg, &val) < 0) { + /* We should transmit the data before logging because logging could + * lead the i2c slave to stretch the clock if the data are not + * transmitted fast enough. + */ + LL_I2C_TransmitData8(i2c, val); + if (ret < 0) { LOG_ERR("Error continuing reading"); } - LL_I2C_TransmitData8(i2c, val); - return; } diff --git a/drivers/i2c/i2c_stm32_v2_rtio.c b/drivers/i2c/i2c_stm32_v2_rtio.c index 9e267c55c1f8..7f0ca0b8a679 100644 --- a/drivers/i2c/i2c_stm32_v2_rtio.c +++ b/drivers/i2c/i2c_stm32_v2_rtio.c @@ -115,13 +115,18 @@ static void i2c_stm32_target_event(const struct device *dev) target_cb = target_cfg->callbacks; if (LL_I2C_IsActiveFlag_TXIS(i2c)) { - uint8_t val; + uint8_t val = 0x00; + int ret = target_cb->read_processed(target_cfg, &val); - if (target_cb->read_processed(target_cfg, &val) < 0) { + /* We should transmit the data before logging because logging could + * lead the i2c target to stretch the clock if the data are not + * transmitted fast enough. + */ + LL_I2C_TransmitData8(i2c, val); + if (ret < 0) { LOG_ERR("Error continuing reading"); - } else { - LL_I2C_TransmitData8(i2c, val); } + return; } From cec2702012bb83ddfb1133c68f5889af15033826 Mon Sep 17 00:00:00 2001 From: Guillaume Gautier Date: Thu, 11 Dec 2025 14:35:03 +0100 Subject: [PATCH 0413/3659] drivers: adc: stm32: fix init issue when 2 adc are enabled If several ADCs are used and share a common clock property (for example ADC1/2 prescaler value on STM32U5), none of them should be enabled when the clock is set. To that end, make sure to disable ADC at the end of the initialization, it will be enabled later when necessary anyway. Signed-off-by: Guillaume Gautier --- drivers/adc/adc_stm32.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/adc/adc_stm32.c b/drivers/adc/adc_stm32.c index eeddf7b6f065..226acd3164fe 100644 --- a/drivers/adc/adc_stm32.c +++ b/drivers/adc/adc_stm32.c @@ -1700,6 +1700,13 @@ static int adc_stm32_init(const struct device *dev) LL_ADC_REG_SetTriggerSource(adc, LL_ADC_REG_TRIG_SOFTWARE); #endif /* HAS_CALIBRATION */ + /* If several ADCs are used and share a common clock property (for example ADC1/2 prescaler + * value on STM32U5), none of them should be enabled when the clock is set. + * To that end, make sure to disable ADC at the end of the initialization, it will be + * enabled later when necessary anyway. + */ + adc_stm32_disable(adc); + adc_context_unlock_unconditionally(&data->ctx); return 0; From 5f1cf576a79aba70666ef651db00f6033a88c738 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Thu, 11 Dec 2025 17:04:05 +0100 Subject: [PATCH 0414/3659] tests: arch: arm: vector_table: disable PM for nrf54h20 cpurad The nrf54h20 cpurad has CONFIG_PM enabled by default. This causes some of the IRQs reserved for the test to be triggered as they are used for PM as well. Disable PM for the test to make sure nothing triggers the IRQs outside of the test itself. Signed-off-by: Bjarki Arge Andreasen --- .../arm_irq_vector_table/boards/nrf54h20dk_nrf54h20_cpurad.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/arch/arm/arm_irq_vector_table/boards/nrf54h20dk_nrf54h20_cpurad.conf b/tests/arch/arm/arm_irq_vector_table/boards/nrf54h20dk_nrf54h20_cpurad.conf index e12e413d9e5a..8a512affa722 100644 --- a/tests/arch/arm/arm_irq_vector_table/boards/nrf54h20dk_nrf54h20_cpurad.conf +++ b/tests/arch/arm/arm_irq_vector_table/boards/nrf54h20dk_nrf54h20_cpurad.conf @@ -2,3 +2,4 @@ # SPDX-License-Identifier: Apache-2.0 CONFIG_POWER_DOMAIN=n +CONFIG_PM=n From 98e98be846e1e840eca489378a557c4fe674cecd Mon Sep 17 00:00:00 2001 From: Mathieu Choplain Date: Thu, 11 Dec 2025 17:06:43 +0100 Subject: [PATCH 0415/3659] drivers: display: stm32_ltdc: remove unnecessary `depends on` in Kconfig `choice STM32_LTDC_PIXEL_FORMAT` is already enclosed in an `if STM32_LTDC` block - there is no need to add a `depends on` on this option. Signed-off-by: Mathieu Choplain --- drivers/display/Kconfig.stm32_ltdc | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/display/Kconfig.stm32_ltdc b/drivers/display/Kconfig.stm32_ltdc index 56c9baef7b82..700687421173 100644 --- a/drivers/display/Kconfig.stm32_ltdc +++ b/drivers/display/Kconfig.stm32_ltdc @@ -19,7 +19,6 @@ if STM32_LTDC choice STM32_LTDC_PIXEL_FORMAT prompt "Color pixel format" default STM32_LTDC_RGB565 - depends on STM32_LTDC help Specify the color pixel format for the STM32 LCD-TFT display controller. From 754f972b4dd2dce8ca78406c5b0e6f0bd89abf5d Mon Sep 17 00:00:00 2001 From: Mateusz Junkier Date: Fri, 12 Dec 2025 13:58:27 +0100 Subject: [PATCH 0416/3659] tests: kconfig: fix path for different repo names Test expected path "zephyr/boards/Kconfig" but failed when the repository had a different name. Changed to "boards/Kconfig" to work with any repository name, as code below. Signed-off-by: Mateusz Junkier --- tests/kconfig/tracing/validate_tracing.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/kconfig/tracing/validate_tracing.py b/tests/kconfig/tracing/validate_tracing.py index 0de12a12323f..1b453d5dbc13 100644 --- a/tests/kconfig/tracing/validate_tracing.py +++ b/tests/kconfig/tracing/validate_tracing.py @@ -26,7 +26,7 @@ "string", "native_sim", "default", - [ "zephyr/boards/Kconfig", None ] # only test the file name + [ "boards/Kconfig", None ] # only test the file name ], [ "CONFIG_MAIN_FLAG", From d5982f0f89f8200ceaeeeabb6fb45b3759008eba Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Mon, 15 Dec 2025 10:29:38 +0200 Subject: [PATCH 0417/3659] net: dns: Make sure IPv6 address can be stored to a buf The CONFIG_DNS_RESOLVER_MAX_NAME_LEN should be large enough so that IPv6 address can be stored into it. So increase the max name length to 46 if IPv6 is enabled. Signed-off-by: Jukka Rissanen --- subsys/net/lib/dns/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/subsys/net/lib/dns/Kconfig b/subsys/net/lib/dns/Kconfig index 6b686767bc06..2e192cfc42c8 100644 --- a/subsys/net/lib/dns/Kconfig +++ b/subsys/net/lib/dns/Kconfig @@ -81,6 +81,7 @@ config DNS_RESOLVER_MAX_NAME_LEN int "Max length of the resolved DNS name" range 1 $(UINT8_MAX) default 128 if DNS_SD + default 46 if NET_IPV6 default 20 help Max length of a buffer that is used to store information returned from From 4f0f02df90e074ee4cad86e3e8937671e83cca2e Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Mon, 17 Mar 2025 14:34:25 +0100 Subject: [PATCH 0418/3659] tests: Bluetooth: Tester: BAP unicast BSIM test Adds BSIM testing of the BAP unicast features of the BT Tester. Signed-off-by: Emil Gydesen --- tests/bluetooth/tester/testcase.yaml | 8 + tests/bsim/bluetooth/tester/CMakeLists.txt | 2 + .../bluetooth/tester/src/audio/bap_central.c | 113 +++++++ .../tester/src/audio/bap_peripheral.c | 60 ++++ tests/bsim/bluetooth/tester/src/bsim_btp.h | 295 +++++++++++++++++- tests/bsim/bluetooth/tester/src/test_main.c | 4 + .../bluetooth/tester/tests_scripts/bap.sh | 41 +++ 7 files changed, 516 insertions(+), 7 deletions(-) create mode 100644 tests/bsim/bluetooth/tester/src/audio/bap_central.c create mode 100644 tests/bsim/bluetooth/tester/src/audio/bap_peripheral.c create mode 100755 tests/bsim/bluetooth/tester/tests_scripts/bap.sh diff --git a/tests/bluetooth/tester/testcase.yaml b/tests/bluetooth/tester/testcase.yaml index 9d3f7f758ccf..9205c250b55d 100644 --- a/tests/bluetooth/tester/testcase.yaml +++ b/tests/bluetooth/tester/testcase.yaml @@ -65,6 +65,14 @@ tests: build_only: true platform_allow: - nrf52_bsim/native + extra_args: + - EXTRA_CONF_FILE="overlay-le-audio.conf;overlay-bt_ll_sw_split.conf" + harness: bsim + harness_config: + bsim_exe_name: tests_bluetooth_tester_le_audio_prj_conf + bluetooth.general.tester_hci_ipc_le_audio_bsim: + build_only: true + platform_allow: - nrf5340bsim/nrf5340/cpuapp extra_args: - EXTRA_CONF_FILE="overlay-le-audio.conf" diff --git a/tests/bsim/bluetooth/tester/CMakeLists.txt b/tests/bsim/bluetooth/tester/CMakeLists.txt index d86c1e0c2059..b0ce594c0e61 100644 --- a/tests/bsim/bluetooth/tester/CMakeLists.txt +++ b/tests/bsim/bluetooth/tester/CMakeLists.txt @@ -24,6 +24,8 @@ zephyr_include_directories( target_sources(app PRIVATE src/bsim_btp.c src/test_main.c + src/audio/bap_central.c + src/audio/bap_peripheral.c src/audio/ccp_central.c src/audio/ccp_peripheral.c src/audio/csip_central.c diff --git a/tests/bsim/bluetooth/tester/src/audio/bap_central.c b/tests/bsim/bluetooth/tester/src/audio/bap_central.c new file mode 100644 index 000000000000..97565ca84ce3 --- /dev/null +++ b/tests/bsim/bluetooth/tester/src/audio/bap_central.c @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "babblekit/testcase.h" +#include "bstests.h" + +#include "btp/btp.h" +#include "bsim_btp.h" + +LOG_MODULE_REGISTER(bsim_bap_central, CONFIG_BSIM_BTTESTER_LOG_LEVEL); + +static void test_bap_central(void) +{ + uint8_t cc_data_16_2_1[] = BT_AUDIO_CODEC_CFG_LC3_DATA(BT_AUDIO_CODEC_CFG_FREQ_16KHZ, + BT_AUDIO_CODEC_CFG_DURATION_10, + BT_AUDIO_LOCATION_FRONT_LEFT, 40, 1); + + char addr_str[BT_ADDR_LE_STR_LEN]; + const uint8_t cig_id = 0U; + const uint8_t cis_id = 0U; + const uint32_t sdu_interval = 10000U; + const uint8_t framing = BT_ISO_FRAMING_UNFRAMED; + const uint16_t max_sdu = 40U; + const uint8_t rtn = 2U; + const uint16_t max_latency = 10U; + const uint32_t presentation_delay = 40000U; + bt_addr_le_t remote_addr; + uint8_t ase_id; + + bsim_btp_uart_init(); + + bsim_btp_wait_for_evt(BTP_SERVICE_ID_CORE, BTP_CORE_EV_IUT_READY, NULL); + + bsim_btp_core_register(BTP_SERVICE_ID_GAP); + bsim_btp_core_register(BTP_SERVICE_ID_BAP); + bsim_btp_core_register(BTP_SERVICE_ID_ASCS); + bsim_btp_core_register(BTP_SERVICE_ID_PACS); + + bsim_btp_gap_start_discovery(BTP_GAP_DISCOVERY_FLAG_LE); + bsim_btp_wait_for_gap_device_found(&remote_addr); + bt_addr_le_to_str(&remote_addr, addr_str, sizeof(addr_str)); + LOG_INF("Found remote device %s", addr_str); + + bsim_btp_gap_stop_discovery(); + bsim_btp_gap_connect(&remote_addr, BTP_GAP_ADDR_TYPE_IDENTITY); + bsim_btp_wait_for_gap_device_connected(NULL); + LOG_INF("Device %s connected", addr_str); + + bsim_btp_gap_pair(&remote_addr); + bsim_btp_wait_for_gap_sec_level_changed(NULL, NULL); + + bsim_btp_bap_discover(&remote_addr); + bsim_btp_wait_for_bap_ase_found(&ase_id); + bsim_btp_wait_for_bap_discovered(); + + bsim_btp_ascs_configure_codec(&remote_addr, ase_id, BT_HCI_CODING_FORMAT_LC3, 0U, 0U, + ARRAY_SIZE(cc_data_16_2_1), cc_data_16_2_1); + bsim_btp_wait_for_ascs_operation_complete(); + + /* The CIS must be preconfigured before sending the request to the BAP unicast server */ + bsim_btp_ascs_add_ase_to_cis(&remote_addr, ase_id, cig_id, cis_id); + btp_ascs_preconfigure_qos(cig_id, cis_id, sdu_interval, framing, max_sdu, rtn, max_latency, + presentation_delay); + + bsim_btp_ascs_configure_qos(&remote_addr, ase_id, cig_id, cis_id, sdu_interval, framing, + max_sdu, rtn, max_latency, presentation_delay); + bsim_btp_wait_for_ascs_operation_complete(); + + bsim_btp_ascs_enable(&remote_addr, ase_id); + bsim_btp_wait_for_ascs_operation_complete(); + + bsim_btp_ascs_receiver_start_ready(&remote_addr, ase_id); + bsim_btp_wait_for_ascs_operation_complete(); + + bsim_btp_ascs_release(&remote_addr, ase_id); + bsim_btp_wait_for_ascs_operation_complete(); + + bsim_btp_gap_disconnect(&remote_addr); + bsim_btp_wait_for_gap_device_disconnected(NULL); + LOG_INF("Device %s disconnected", addr_str); + + TEST_PASS("PASSED\n"); +} + +static const struct bst_test_instance test_sample[] = { + { + .test_id = "bap_central", + .test_descr = "Smoketest for the BAP central BT Tester behavior", + .test_main_f = test_bap_central, + }, + BSTEST_END_MARKER, +}; + +struct bst_test_list *test_bap_central_install(struct bst_test_list *tests) +{ + return bst_add_tests(tests, test_sample); +} diff --git a/tests/bsim/bluetooth/tester/src/audio/bap_peripheral.c b/tests/bsim/bluetooth/tester/src/audio/bap_peripheral.c new file mode 100644 index 000000000000..60e5e6fd2723 --- /dev/null +++ b/tests/bsim/bluetooth/tester/src/audio/bap_peripheral.c @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include + +#include +#include +#include +#include +#include + +#include "babblekit/testcase.h" +#include "bstests.h" + +#include "btp/btp.h" +#include "bsim_btp.h" + +LOG_MODULE_REGISTER(bsim_bap_peripheral, CONFIG_BSIM_BTTESTER_LOG_LEVEL); + +static void test_bap_peripheral(void) +{ + char addr_str[BT_ADDR_LE_STR_LEN]; + bt_addr_le_t remote_addr; + + bsim_btp_uart_init(); + + bsim_btp_wait_for_evt(BTP_SERVICE_ID_CORE, BTP_CORE_EV_IUT_READY, NULL); + + bsim_btp_core_register(BTP_SERVICE_ID_GAP); + bsim_btp_core_register(BTP_SERVICE_ID_BAP); + bsim_btp_core_register(BTP_SERVICE_ID_ASCS); + bsim_btp_core_register(BTP_SERVICE_ID_PACS); + + bsim_btp_gap_set_discoverable(BTP_GAP_GENERAL_DISCOVERABLE); + bsim_btp_gap_start_advertising(0U, 0U, NULL, BT_HCI_OWN_ADDR_PUBLIC); + bsim_btp_wait_for_gap_device_connected(&remote_addr); + bt_addr_le_to_str(&remote_addr, addr_str, sizeof(addr_str)); + LOG_INF("Device %s connected", addr_str); + bsim_btp_wait_for_gap_device_disconnected(NULL); + LOG_INF("Device %s disconnected", addr_str); + + TEST_PASS("PASSED\n"); +} + +static const struct bst_test_instance test_sample[] = { + { + .test_id = "bap_peripheral", + .test_descr = "Smoketest for the BAP peripheral BT Tester behavior", + .test_main_f = test_bap_peripheral, + }, + BSTEST_END_MARKER, +}; + +struct bst_test_list *test_bap_peripheral_install(struct bst_test_list *tests) +{ + return bst_add_tests(tests, test_sample); +} diff --git a/tests/bsim/bluetooth/tester/src/bsim_btp.h b/tests/bsim/bluetooth/tester/src/bsim_btp.h index 2480076bc069..40a0cd829bbe 100644 --- a/tests/bsim/bluetooth/tester/src/bsim_btp.h +++ b/tests/bsim/bluetooth/tester/src/bsim_btp.h @@ -24,6 +24,287 @@ void bsim_btp_uart_init(void); void bsim_btp_send_to_tester(const uint8_t *data, size_t len); void bsim_btp_wait_for_evt(uint8_t service, uint8_t opcode, struct net_buf **out_buf); +static inline void bsim_btp_ascs_configure_codec(const bt_addr_le_t *address, uint8_t ase_id, + uint8_t coding_format, uint16_t vid, uint16_t cid, + uint8_t cc_ltvs_len, uint8_t cc_ltvs[]) +{ + struct btp_ascs_configure_codec_cmd *cmd; + struct btp_hdr *cmd_hdr; + + NET_BUF_SIMPLE_DEFINE(cmd_buffer, BTP_MTU); + + cmd_hdr = net_buf_simple_add(&cmd_buffer, sizeof(*cmd_hdr)); + cmd_hdr->service = BTP_SERVICE_ID_ASCS; + cmd_hdr->opcode = BTP_ASCS_CONFIGURE_CODEC; + cmd_hdr->index = BTP_INDEX; + cmd = net_buf_simple_add(&cmd_buffer, sizeof(*cmd)); + bt_addr_le_copy(&cmd->address, address); + cmd->ase_id = ase_id; + cmd->coding_format = coding_format; + cmd->vid = sys_cpu_to_le16(vid); + cmd->cid = sys_cpu_to_le16(cid); + cmd->cc_ltvs_len = cc_ltvs_len; + if (cc_ltvs_len != 0) { + (void)net_buf_simple_add_mem(&cmd_buffer, cc_ltvs, cc_ltvs_len); + } + + cmd_hdr->len = sys_cpu_to_le16(cmd_buffer.len - sizeof(*cmd_hdr)); + + bsim_btp_send_to_tester(cmd_buffer.data, cmd_buffer.len); +} + +static inline void bsim_btp_ascs_configure_qos(const bt_addr_le_t *address, uint8_t ase_id, + uint8_t cig_id, uint8_t cis_id, + uint32_t sdu_interval, uint8_t framing, + uint16_t max_sdu, uint8_t rtn, uint16_t max_latency, + uint32_t presentation_delay) +{ + struct btp_ascs_configure_qos_cmd *cmd; + struct btp_hdr *cmd_hdr; + + NET_BUF_SIMPLE_DEFINE(cmd_buffer, BTP_MTU); + + cmd_hdr = net_buf_simple_add(&cmd_buffer, sizeof(*cmd_hdr)); + cmd_hdr->service = BTP_SERVICE_ID_ASCS; + cmd_hdr->opcode = BTP_ASCS_CONFIGURE_QOS; + cmd_hdr->index = BTP_INDEX; + cmd = net_buf_simple_add(&cmd_buffer, sizeof(*cmd)); + bt_addr_le_copy(&cmd->address, address); + cmd->ase_id = ase_id; + cmd->cig_id = cig_id; + cmd->cis_id = cis_id; + sys_put_le24(sdu_interval, cmd->sdu_interval); + cmd->framing = framing; + cmd->max_sdu = sys_cpu_to_le16(max_sdu); + cmd->retransmission_num = rtn; + cmd->max_transport_latency = sys_cpu_to_le16(max_latency); + sys_put_le24(presentation_delay, cmd->presentation_delay); + + cmd_hdr->len = sys_cpu_to_le16(cmd_buffer.len - sizeof(*cmd_hdr)); + + bsim_btp_send_to_tester(cmd_buffer.data, cmd_buffer.len); +} + +static inline void bsim_btp_ascs_enable(const bt_addr_le_t *address, uint8_t ase_id) +{ + struct btp_ascs_enable_cmd *cmd; + struct btp_hdr *cmd_hdr; + + NET_BUF_SIMPLE_DEFINE(cmd_buffer, BTP_MTU); + + cmd_hdr = net_buf_simple_add(&cmd_buffer, sizeof(*cmd_hdr)); + cmd_hdr->service = BTP_SERVICE_ID_ASCS; + cmd_hdr->opcode = BTP_ASCS_ENABLE; + cmd_hdr->index = BTP_INDEX; + cmd = net_buf_simple_add(&cmd_buffer, sizeof(*cmd)); + bt_addr_le_copy(&cmd->address, address); + cmd->ase_id = ase_id; + + cmd_hdr->len = sys_cpu_to_le16(cmd_buffer.len - sizeof(*cmd_hdr)); + + bsim_btp_send_to_tester(cmd_buffer.data, cmd_buffer.len); +} + +static inline void bsim_btp_ascs_receiver_start_ready(const bt_addr_le_t *address, uint8_t ase_id) +{ + struct btp_ascs_receiver_start_ready_cmd *cmd; + struct btp_hdr *cmd_hdr; + + NET_BUF_SIMPLE_DEFINE(cmd_buffer, BTP_MTU); + + cmd_hdr = net_buf_simple_add(&cmd_buffer, sizeof(*cmd_hdr)); + cmd_hdr->service = BTP_SERVICE_ID_ASCS; + cmd_hdr->opcode = BTP_ASCS_RECEIVER_START_READY; + cmd_hdr->index = BTP_INDEX; + cmd = net_buf_simple_add(&cmd_buffer, sizeof(*cmd)); + bt_addr_le_copy(&cmd->address, address); + cmd->ase_id = ase_id; + + cmd_hdr->len = sys_cpu_to_le16(cmd_buffer.len - sizeof(*cmd_hdr)); + + bsim_btp_send_to_tester(cmd_buffer.data, cmd_buffer.len); +} + +static inline void bsim_btp_ascs_receiver_stop_ready(const bt_addr_le_t *address, uint8_t ase_id) +{ + struct btp_ascs_receiver_stop_ready_cmd *cmd; + struct btp_hdr *cmd_hdr; + + NET_BUF_SIMPLE_DEFINE(cmd_buffer, BTP_MTU); + + cmd_hdr = net_buf_simple_add(&cmd_buffer, sizeof(*cmd_hdr)); + cmd_hdr->service = BTP_SERVICE_ID_ASCS; + cmd_hdr->opcode = BTP_ASCS_RECEIVER_STOP_READY; + cmd_hdr->index = BTP_INDEX; + cmd = net_buf_simple_add(&cmd_buffer, sizeof(*cmd)); + bt_addr_le_copy(&cmd->address, address); + cmd->ase_id = ase_id; + + cmd_hdr->len = sys_cpu_to_le16(cmd_buffer.len - sizeof(*cmd_hdr)); + + bsim_btp_send_to_tester(cmd_buffer.data, cmd_buffer.len); +} + +static inline void bsim_btp_ascs_disable(const bt_addr_le_t *address, uint8_t ase_id) +{ + struct btp_ascs_disable_cmd *cmd; + struct btp_hdr *cmd_hdr; + + NET_BUF_SIMPLE_DEFINE(cmd_buffer, BTP_MTU); + + cmd_hdr = net_buf_simple_add(&cmd_buffer, sizeof(*cmd_hdr)); + cmd_hdr->service = BTP_SERVICE_ID_ASCS; + cmd_hdr->opcode = BTP_ASCS_DISABLE; + cmd_hdr->index = BTP_INDEX; + cmd = net_buf_simple_add(&cmd_buffer, sizeof(*cmd)); + bt_addr_le_copy(&cmd->address, address); + cmd->ase_id = ase_id; + + cmd_hdr->len = sys_cpu_to_le16(cmd_buffer.len - sizeof(*cmd_hdr)); + + bsim_btp_send_to_tester(cmd_buffer.data, cmd_buffer.len); +} + +static inline void bsim_btp_ascs_release(const bt_addr_le_t *address, uint8_t ase_id) +{ + struct btp_ascs_release_cmd *cmd; + struct btp_hdr *cmd_hdr; + + NET_BUF_SIMPLE_DEFINE(cmd_buffer, BTP_MTU); + + cmd_hdr = net_buf_simple_add(&cmd_buffer, sizeof(*cmd_hdr)); + cmd_hdr->service = BTP_SERVICE_ID_ASCS; + cmd_hdr->opcode = BTP_ASCS_RELEASE; + cmd_hdr->index = BTP_INDEX; + cmd = net_buf_simple_add(&cmd_buffer, sizeof(*cmd)); + bt_addr_le_copy(&cmd->address, address); + cmd->ase_id = ase_id; + + cmd_hdr->len = sys_cpu_to_le16(cmd_buffer.len - sizeof(*cmd_hdr)); + + bsim_btp_send_to_tester(cmd_buffer.data, cmd_buffer.len); +} + +static inline void bsim_btp_wait_for_ascs_operation_complete(void) +{ + struct btp_ascs_operation_completed_ev *ev; + struct net_buf *buf; + + bsim_btp_wait_for_evt(BTP_SERVICE_ID_ASCS, BTP_ASCS_EV_OPERATION_COMPLETED, &buf); + ev = net_buf_pull_mem(buf, sizeof(*ev)); + + net_buf_unref(buf); +} + +static inline void bsim_btp_ascs_add_ase_to_cis(const bt_addr_le_t *address, uint8_t ase_id, + uint8_t cig_id, uint8_t cis_id) +{ + struct btp_ascs_add_ase_to_cis *cmd; + struct btp_hdr *cmd_hdr; + + NET_BUF_SIMPLE_DEFINE(cmd_buffer, BTP_MTU); + + cmd_hdr = net_buf_simple_add(&cmd_buffer, sizeof(*cmd_hdr)); + cmd_hdr->service = BTP_SERVICE_ID_ASCS; + cmd_hdr->opcode = BTP_ASCS_ADD_ASE_TO_CIS; + cmd_hdr->index = BTP_INDEX; + cmd = net_buf_simple_add(&cmd_buffer, sizeof(*cmd)); + bt_addr_le_copy(&cmd->address, address); + cmd->ase_id = ase_id; + cmd->cig_id = cig_id; + cmd->cis_id = cis_id; + + cmd_hdr->len = sys_cpu_to_le16(cmd_buffer.len - sizeof(*cmd_hdr)); + + bsim_btp_send_to_tester(cmd_buffer.data, cmd_buffer.len); +} + +static inline void btp_ascs_preconfigure_qos(uint8_t cig_id, uint8_t cis_id, uint32_t sdu_interval, + uint8_t framing, uint16_t max_sdu, uint8_t rtn, + uint16_t max_latency, uint32_t presentation_delay) +{ + struct btp_ascs_preconfigure_qos_cmd *cmd; + struct btp_hdr *cmd_hdr; + + NET_BUF_SIMPLE_DEFINE(cmd_buffer, BTP_MTU); + + cmd_hdr = net_buf_simple_add(&cmd_buffer, sizeof(*cmd_hdr)); + cmd_hdr->service = BTP_SERVICE_ID_ASCS; + cmd_hdr->opcode = BTP_ASCS_PRECONFIGURE_QOS; + cmd_hdr->index = BTP_INDEX; + cmd = net_buf_simple_add(&cmd_buffer, sizeof(*cmd)); + cmd->cig_id = cig_id; + cmd->cis_id = cis_id; + sys_put_le24(sdu_interval, cmd->sdu_interval); + cmd->framing = framing; + cmd->max_sdu = sys_cpu_to_le16(max_sdu); + cmd->retransmission_num = rtn; + cmd->max_transport_latency = sys_cpu_to_le16(max_latency); + sys_put_le24(presentation_delay, cmd->presentation_delay); + + cmd_hdr->len = sys_cpu_to_le16(cmd_buffer.len - sizeof(*cmd_hdr)); + + bsim_btp_send_to_tester(cmd_buffer.data, cmd_buffer.len); +} + +static inline void bsim_btp_wait_for_ascs_ase_state_changed(void) +{ + struct btp_ascs_ase_state_changed_ev *ev; + struct net_buf *buf; + + bsim_btp_wait_for_evt(BTP_SERVICE_ID_ASCS, BTP_ASCS_EV_ASE_STATE_CHANGED, &buf); + ev = net_buf_pull_mem(buf, sizeof(*ev)); + + net_buf_unref(buf); +} + +static inline void bsim_btp_bap_discover(const bt_addr_le_t *address) +{ + struct btp_bap_discover_cmd *cmd; + struct btp_hdr *cmd_hdr; + + NET_BUF_SIMPLE_DEFINE(cmd_buffer, BTP_MTU); + + cmd_hdr = net_buf_simple_add(&cmd_buffer, sizeof(*cmd_hdr)); + cmd_hdr->service = BTP_SERVICE_ID_BAP; + cmd_hdr->opcode = BTP_BAP_DISCOVER; + cmd_hdr->index = BTP_INDEX; + cmd = net_buf_simple_add(&cmd_buffer, sizeof(*cmd)); + bt_addr_le_copy(&cmd->address, address); + + cmd_hdr->len = sys_cpu_to_le16(cmd_buffer.len - sizeof(*cmd_hdr)); + + bsim_btp_send_to_tester(cmd_buffer.data, cmd_buffer.len); +} + +static inline void bsim_btp_wait_for_bap_discovered(void) +{ + struct btp_bap_discovery_completed_ev *ev; + struct net_buf *buf; + + bsim_btp_wait_for_evt(BTP_SERVICE_ID_BAP, BTP_BAP_EV_DISCOVERY_COMPLETED, &buf); + ev = net_buf_pull_mem(buf, sizeof(*ev)); + + TEST_ASSERT(ev->status == BT_ATT_ERR_SUCCESS); + + net_buf_unref(buf); +} + +static inline void bsim_btp_wait_for_bap_ase_found(uint8_t *ase_id) +{ + struct btp_bap_ase_found_ev *ev; + struct net_buf *buf; + + bsim_btp_wait_for_evt(BTP_SERVICE_ID_BAP, BTP_BAP_EV_ASE_FOUND, &buf); + ev = net_buf_pull_mem(buf, sizeof(*ev)); + + if (ase_id != NULL) { + *ase_id = ev->ase_id; + } + + net_buf_unref(buf); +} + static inline void bsim_btp_ccp_discover(const bt_addr_le_t *address) { struct btp_ccp_discover_tbs_cmd *cmd; @@ -38,7 +319,7 @@ static inline void bsim_btp_ccp_discover(const bt_addr_le_t *address) cmd = net_buf_simple_add(&cmd_buffer, sizeof(*cmd)); bt_addr_le_copy(&cmd->address, address); - cmd_hdr->len = cmd_buffer.len - sizeof(*cmd_hdr); + cmd_hdr->len = sys_cpu_to_le16(cmd_buffer.len - sizeof(*cmd_hdr)); bsim_btp_send_to_tester(cmd_buffer.data, cmd_buffer.len); } @@ -61,7 +342,7 @@ static inline void bsim_btp_ccp_originate_call(const bt_addr_le_t *address, uint cmd->uri_len = strlen(uri) + 1 /* NULL terminator */; net_buf_simple_add_mem(&cmd_buffer, uri, cmd->uri_len); - cmd_hdr->len = cmd_buffer.len - sizeof(*cmd_hdr); + cmd_hdr->len = sys_cpu_to_le16(cmd_buffer.len - sizeof(*cmd_hdr)); bsim_btp_send_to_tester(cmd_buffer.data, cmd_buffer.len); } @@ -125,7 +406,7 @@ static inline void bsim_btp_csip_discover(const bt_addr_le_t *address) cmd = net_buf_simple_add(&cmd_buffer, sizeof(*cmd)); bt_addr_le_copy(&cmd->address, address); - cmd_hdr->len = cmd_buffer.len - sizeof(*cmd_hdr); + cmd_hdr->len = sys_cpu_to_le16(cmd_buffer.len - sizeof(*cmd_hdr)); bsim_btp_send_to_tester(cmd_buffer.data, cmd_buffer.len); } @@ -144,7 +425,7 @@ static inline void bsim_btp_csip_set_coordinator_lock(void) cmd = net_buf_simple_add(&cmd_buffer, sizeof(*cmd)); cmd->addr_cnt = 0U; /* Zephyr BT Tester only supports this value being 0 */ - cmd_hdr->len = cmd_buffer.len - sizeof(*cmd_hdr); + cmd_hdr->len = sys_cpu_to_le16(cmd_buffer.len - sizeof(*cmd_hdr)); bsim_btp_send_to_tester(cmd_buffer.data, cmd_buffer.len); } @@ -414,7 +695,7 @@ static inline void bsim_btp_hauc_init(void) /* command is empty */ - cmd_hdr->len = cmd_buffer.len - sizeof(*cmd_hdr); + cmd_hdr->len = sys_cpu_to_le16(cmd_buffer.len - sizeof(*cmd_hdr)); bsim_btp_send_to_tester(cmd_buffer.data, cmd_buffer.len); } @@ -433,7 +714,7 @@ static inline void bsim_btp_hauc_discover(const bt_addr_le_t *address) cmd = net_buf_simple_add(&cmd_buffer, sizeof(*cmd)); bt_addr_le_copy(&cmd->address, address); - cmd_hdr->len = cmd_buffer.len - sizeof(*cmd_hdr); + cmd_hdr->len = sys_cpu_to_le16(cmd_buffer.len - sizeof(*cmd_hdr)); bsim_btp_send_to_tester(cmd_buffer.data, cmd_buffer.len); } @@ -545,7 +826,7 @@ static inline void bsim_btp_tmap_discover(const bt_addr_le_t *address) cmd = net_buf_simple_add(&cmd_buffer, sizeof(*cmd)); bt_addr_le_copy(&cmd->address, address); - cmd_hdr->len = cmd_buffer.len - sizeof(*cmd_hdr); + cmd_hdr->len = sys_cpu_to_le16(cmd_buffer.len - sizeof(*cmd_hdr)); bsim_btp_send_to_tester(cmd_buffer.data, cmd_buffer.len); } diff --git a/tests/bsim/bluetooth/tester/src/test_main.c b/tests/bsim/bluetooth/tester/src/test_main.c index 9448750ea001..29b9711904e0 100644 --- a/tests/bsim/bluetooth/tester/src/test_main.c +++ b/tests/bsim/bluetooth/tester/src/test_main.c @@ -7,6 +7,8 @@ #include "bstests.h" +extern struct bst_test_list *test_bap_central_install(struct bst_test_list *tests); +extern struct bst_test_list *test_bap_peripheral_install(struct bst_test_list *tests); extern struct bst_test_list *test_ccp_central_install(struct bst_test_list *tests); extern struct bst_test_list *test_ccp_peripheral_install(struct bst_test_list *tests); extern struct bst_test_list *test_csip_central_install(struct bst_test_list *tests); @@ -27,6 +29,8 @@ extern struct bst_test_list *test_iso_broadcaster_install(struct bst_test_list * extern struct bst_test_list *test_iso_sync_receiver_install(struct bst_test_list *tests); bst_test_install_t test_installers[] = { + test_bap_central_install, + test_bap_peripheral_install, test_ccp_central_install, test_ccp_peripheral_install, test_csip_central_install, diff --git a/tests/bsim/bluetooth/tester/tests_scripts/bap.sh b/tests/bsim/bluetooth/tester/tests_scripts/bap.sh new file mode 100755 index 000000000000..71c1b2925965 --- /dev/null +++ b/tests/bsim/bluetooth/tester/tests_scripts/bap.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash +# Copyright 2025 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +# Smoketest for BAP BTP commands with the BT tester + +simulation_id="tester_bap" +verbosity_level=2 +EXECUTE_TIMEOUT=100 + +source ${ZEPHYR_BASE}/tests/bsim/sh_common.source + +cd ${BSIM_OUT_PATH}/bin + +UART_DIR=/tmp/bs_${USER}/${simulation_id}/ +UART_PER=${UART_DIR}/peripheral +UART_CEN=${UART_DIR}/central + +# Central BT Tester +Execute ./bs_${BOARD_TS}_tests_bluetooth_tester_le_audio_prj_conf \ + -v=${verbosity_level} -s=${simulation_id} -rs=10 -d=0 -RealEncryption=1 \ + -uart0_fifob_rxfile=${UART_CEN}.tx -uart0_fifob_txfile=${UART_CEN}.rx + +# Central Upper Tester +Execute ./bs_nrf52_bsim_native_tests_bsim_bluetooth_tester_prj_conf \ + -v=${verbosity_level} -s=${simulation_id} -rs=21 -d=10 -RealEncryption=1 -testid=bap_central \ + -nosim -uart0_fifob_rxfile=${UART_CEN}.rx -uart0_fifob_txfile=${UART_CEN}.tx + +# Peripheral BT Tester +Execute ./bs_${BOARD_TS}_tests_bluetooth_tester_le_audio_prj_conf \ + -v=${verbosity_level} -s=${simulation_id} -rs=32 -d=1 -RealEncryption=1 \ + -uart0_fifob_rxfile=${UART_PER}.tx -uart0_fifob_txfile=${UART_PER}.rx + +# Peripheral Upper Tester +Execute ./bs_nrf52_bsim_native_tests_bsim_bluetooth_tester_prj_conf \ + -v=${verbosity_level} -s=${simulation_id} -rs=43 -d=11 -RealEncryption=1 -testid=bap_peripheral \ + -nosim -uart0_fifob_rxfile=${UART_PER}.rx -uart0_fifob_txfile=${UART_PER}.tx + +Execute ./bs_2G4_phy_v1 -v=${verbosity_level} -s=${simulation_id} -D=2 -sim_length=20e6 $@ + +wait_for_background_jobs # Wait for all programs in background and return != 0 if any fails From df861995320a80c82477f5bb544ad8dc2b70c130 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Tue, 18 Mar 2025 22:21:59 +0100 Subject: [PATCH 0419/3659] tests: Bluetooth: Tester: BAP broadcast BSIM test Adds BSIM testing of the BAP broadcast features of the BT Tester. Signed-off-by: Emil Gydesen --- .../boards/nrf5340bsim_nrf5340_cpuapp.conf | 5 + tests/bsim/bluetooth/tester/CMakeLists.txt | 2 + .../tester/src/audio/bap_broadcast_sink.c | 78 +++++ .../tester/src/audio/bap_broadcast_source.c | 75 +++++ tests/bsim/bluetooth/tester/src/bsim_btp.c | 6 +- tests/bsim/bluetooth/tester/src/bsim_btp.h | 280 ++++++++++++++++++ tests/bsim/bluetooth/tester/src/test_main.c | 4 + .../tester/tests_scripts/bap_broadcast.sh | 43 +++ .../tests_scripts/{bap.sh => bap_unicast.sh} | 2 +- 9 files changed, 493 insertions(+), 2 deletions(-) create mode 100644 tests/bsim/bluetooth/tester/src/audio/bap_broadcast_sink.c create mode 100644 tests/bsim/bluetooth/tester/src/audio/bap_broadcast_source.c create mode 100755 tests/bsim/bluetooth/tester/tests_scripts/bap_broadcast.sh rename tests/bsim/bluetooth/tester/tests_scripts/{bap.sh => bap_unicast.sh} (97%) diff --git a/tests/bluetooth/tester/boards/nrf5340bsim_nrf5340_cpuapp.conf b/tests/bluetooth/tester/boards/nrf5340bsim_nrf5340_cpuapp.conf index 4acb10d28549..af822463fa46 100644 --- a/tests/bluetooth/tester/boards/nrf5340bsim_nrf5340_cpuapp.conf +++ b/tests/bluetooth/tester/boards/nrf5340bsim_nrf5340_cpuapp.conf @@ -16,3 +16,8 @@ CONFIG_UART_PIPE=n CONFIG_UART_INTERRUPT_DRIVEN=y CONFIG_SERIAL=y + +# Increase the number of RX buffers to a high amount to avoid issues with running out of buffers +# Presumably this is due to the speed of BSIM and the "slowness" of the BSIM UART, since all +# events (include ISO data received event) is sent in a blocking manner +CONFIG_BT_ISO_RX_BUF_COUNT=30 diff --git a/tests/bsim/bluetooth/tester/CMakeLists.txt b/tests/bsim/bluetooth/tester/CMakeLists.txt index b0ce594c0e61..d73e1352e15a 100644 --- a/tests/bsim/bluetooth/tester/CMakeLists.txt +++ b/tests/bsim/bluetooth/tester/CMakeLists.txt @@ -24,6 +24,8 @@ zephyr_include_directories( target_sources(app PRIVATE src/bsim_btp.c src/test_main.c + src/audio/bap_broadcast_sink.c + src/audio/bap_broadcast_source.c src/audio/bap_central.c src/audio/bap_peripheral.c src/audio/ccp_central.c diff --git a/tests/bsim/bluetooth/tester/src/audio/bap_broadcast_sink.c b/tests/bsim/bluetooth/tester/src/audio/bap_broadcast_sink.c new file mode 100644 index 000000000000..9eac73993729 --- /dev/null +++ b/tests/bsim/bluetooth/tester/src/audio/bap_broadcast_sink.c @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "babblekit/testcase.h" +#include "bstests.h" + +#include "btp/btp.h" +#include "bsim_btp.h" + +LOG_MODULE_REGISTER(bsim_bap_broadcast_sink, CONFIG_BSIM_BTTESTER_LOG_LEVEL); + +static void test_bap_broadcast_sink(void) +{ + const uint16_t pa_sync_timeout = BT_GAP_PER_ADV_MAX_TIMEOUT; + char addr_str[BT_ADDR_LE_STR_LEN]; + const uint16_t pa_sync_skip = 0U; + const uint8_t src_id = 0U; /* BASS receive state source ID */ + bt_addr_le_t remote_addr; + uint32_t broadcast_id; + uint8_t adv_sid; + uint8_t bis_id; + + bsim_btp_uart_init(); + + bsim_btp_wait_for_evt(BTP_SERVICE_ID_CORE, BTP_CORE_EV_IUT_READY, NULL); + + bsim_btp_core_register(BTP_SERVICE_ID_GAP); + bsim_btp_core_register(BTP_SERVICE_ID_BAP); + bsim_btp_core_register(BTP_SERVICE_ID_PACS); + + bsim_btp_bap_broadcast_sink_setup(); + bsim_btp_bap_broadcast_scan_start(); + + bsim_btp_bap_broadcast_scan_start(); + bsim_btp_wait_for_bap_baa_found(&remote_addr, &broadcast_id, &adv_sid); + bt_addr_le_to_str(&remote_addr, addr_str, sizeof(addr_str)); + LOG_INF("Found remote device %s", addr_str); + bsim_btp_bap_broadcast_scan_stop(); + + bsim_btp_bap_broadcast_sink_sync(&remote_addr, broadcast_id, adv_sid, pa_sync_skip, + pa_sync_timeout, false, src_id); + bsim_btp_wait_for_bap_bap_bis_found(&bis_id); + bsim_btp_bap_broadcast_sink_bis_sync(&remote_addr, broadcast_id, + BT_ISO_BIS_INDEX_BIT(bis_id)); + bsim_btp_wait_for_btp_bap_bis_synced(); + bsim_btp_wait_for_bap_bis_stream_received(); + bsim_btp_bap_broadcast_sink_stop(&remote_addr, broadcast_id); + bsim_btp_bap_broadcast_sink_release(); + + TEST_PASS("PASSED\n"); +} + +static const struct bst_test_instance test_sample[] = { + { + .test_id = "bap_broadcast_sink", + .test_descr = "Smoketest for the BAP Broadcast Sink BT Tester behavior", + .test_main_f = test_bap_broadcast_sink, + }, + BSTEST_END_MARKER, +}; + +struct bst_test_list *test_bap_broadcast_sink_install(struct bst_test_list *tests) +{ + return bst_add_tests(tests, test_sample); +} diff --git a/tests/bsim/bluetooth/tester/src/audio/bap_broadcast_source.c b/tests/bsim/bluetooth/tester/src/audio/bap_broadcast_source.c new file mode 100644 index 000000000000..bf7d088dc403 --- /dev/null +++ b/tests/bsim/bluetooth/tester/src/audio/bap_broadcast_source.c @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "babblekit/testcase.h" +#include "bstests.h" + +#include "btp/btp.h" +#include "bsim_btp.h" + +LOG_MODULE_REGISTER(bsim_bap_broadcast_source, CONFIG_BSIM_BTTESTER_LOG_LEVEL); + +static void test_bap_broadcast_source(void) +{ + const uint8_t cc_data_16_2_1[] = BT_AUDIO_CODEC_CFG_LC3_DATA( + BT_AUDIO_CODEC_CFG_FREQ_16KHZ, BT_AUDIO_CODEC_CFG_DURATION_10, + BT_AUDIO_LOCATION_FRONT_LEFT, 40, 1); + const uint8_t coding_format = BT_HCI_CODING_FORMAT_LC3; + const uint8_t framing = BT_ISO_FRAMING_UNFRAMED; + const uint32_t presentation_delay = 40000U; + const uint32_t broadcast_id = 0x123456; + const uint8_t streams_per_subgroup = 1U; + const uint32_t sdu_interval = 10000U; + const uint16_t max_latency = 10U; + const uint16_t max_sdu = 40U; + const uint8_t subgroups = 1U; + const uint16_t cid = 0U; /* shall be 0 for LC3 */ + const uint16_t vid = 0U; /* shall be 0 for LC3 */ + const uint8_t rtn = 2U; + + bsim_btp_uart_init(); + + bsim_btp_wait_for_evt(BTP_SERVICE_ID_CORE, BTP_CORE_EV_IUT_READY, NULL); + + bsim_btp_core_register(BTP_SERVICE_ID_GAP); + bsim_btp_core_register(BTP_SERVICE_ID_BAP); + + bsim_btp_bap_broadcast_source_setup_v2(broadcast_id, streams_per_subgroup, subgroups, + sdu_interval, framing, max_sdu, rtn, max_latency, + presentation_delay, coding_format, vid, cid, + ARRAY_SIZE(cc_data_16_2_1), cc_data_16_2_1); + bsim_btp_bap_broadcast_adv_start(broadcast_id); + bsim_btp_bap_broadcast_source_start(broadcast_id); + + TEST_PASS("PASSED\n"); +} + +static const struct bst_test_instance test_sample[] = { + { + .test_id = "bap_broadcast_source", + .test_descr = "Smoketest for the BAP broadcast source BT Tester behavior", + .test_main_f = test_bap_broadcast_source, + }, + BSTEST_END_MARKER, +}; + +struct bst_test_list *test_bap_broadcast_source_install(struct bst_test_list *tests) +{ + return bst_add_tests(tests, test_sample); +} diff --git a/tests/bsim/bluetooth/tester/src/bsim_btp.c b/tests/bsim/bluetooth/tester/src/bsim_btp.c index 9ea4100c9971..2ee17f092338 100644 --- a/tests/bsim/bluetooth/tester/src/bsim_btp.c +++ b/tests/bsim/bluetooth/tester/src/bsim_btp.c @@ -1103,6 +1103,8 @@ static bool is_valid_bap_packet_len(const struct btp_hdr *hdr, struct net_buf_si return buf_simple->len == 0U; case BTP_BAP_SEND_PAST: return buf_simple->len == 0U; + case BTP_BAP_BROADCAST_SOURCE_SETUP_V2: + return buf_simple->len == sizeof(struct btp_bap_broadcast_source_setup_v2_rp); /* events */ case BTP_BAP_EV_DISCOVERY_COMPLETED: @@ -1131,6 +1133,8 @@ static bool is_valid_bap_packet_len(const struct btp_hdr *hdr, struct net_buf_si } else { return false; } + case BTP_BAP_EV_BIS_SYNCED: + return buf_simple->len == sizeof(struct btp_bap_bis_synced_ev); case BTP_BAP_EV_BIS_STREAM_RECEIVED: if (hdr->len >= sizeof(struct btp_bap_stream_received_ev)) { const struct btp_bap_bis_stream_received_ev *ev = net_buf_simple_pull_mem( @@ -1156,7 +1160,7 @@ static bool is_valid_bap_packet_len(const struct btp_hdr *hdr, struct net_buf_si uint8_t metadata_len; uint32_t bis_sync; - if (buf_simple->len <= (sizeof(bis_sync) + sizeof(metadata_len))) { + if (buf_simple->len < (sizeof(bis_sync) + sizeof(metadata_len))) { return false; } diff --git a/tests/bsim/bluetooth/tester/src/bsim_btp.h b/tests/bsim/bluetooth/tester/src/bsim_btp.h index 40a0cd829bbe..6e4e39afce99 100644 --- a/tests/bsim/bluetooth/tester/src/bsim_btp.h +++ b/tests/bsim/bluetooth/tester/src/bsim_btp.h @@ -289,6 +289,225 @@ static inline void bsim_btp_wait_for_bap_discovered(void) net_buf_unref(buf); } +static inline void bsim_btp_bap_broadcast_adv_start(uint32_t broadcast_id) +{ + struct btp_bap_broadcast_adv_start_cmd *cmd; + struct btp_hdr *cmd_hdr; + + NET_BUF_SIMPLE_DEFINE(cmd_buffer, BTP_MTU); + + cmd_hdr = net_buf_simple_add(&cmd_buffer, sizeof(*cmd_hdr)); + cmd_hdr->service = BTP_SERVICE_ID_BAP; + cmd_hdr->opcode = BTP_BAP_BROADCAST_ADV_START; + cmd_hdr->index = BTP_INDEX; + cmd = net_buf_simple_add(&cmd_buffer, sizeof(*cmd)); + sys_put_le24(broadcast_id, cmd->broadcast_id); + + cmd_hdr->len = cmd_buffer.len - sizeof(*cmd_hdr); + + bsim_btp_send_to_tester(cmd_buffer.data, cmd_buffer.len); +} + +static inline void bsim_btp_bap_broadcast_source_start(uint32_t broadcast_id) +{ + struct btp_bap_broadcast_source_start_cmd *cmd; + struct btp_hdr *cmd_hdr; + + NET_BUF_SIMPLE_DEFINE(cmd_buffer, BTP_MTU); + + cmd_hdr = net_buf_simple_add(&cmd_buffer, sizeof(*cmd_hdr)); + cmd_hdr->service = BTP_SERVICE_ID_BAP; + cmd_hdr->opcode = BTP_BAP_BROADCAST_SOURCE_START; + cmd_hdr->index = BTP_INDEX; + cmd = net_buf_simple_add(&cmd_buffer, sizeof(*cmd)); + sys_put_le24(broadcast_id, cmd->broadcast_id); + + cmd_hdr->len = cmd_buffer.len - sizeof(*cmd_hdr); + + bsim_btp_send_to_tester(cmd_buffer.data, cmd_buffer.len); +} + +static inline void bsim_btp_bap_broadcast_sink_setup(void) +{ + struct btp_hdr *cmd_hdr; + + NET_BUF_SIMPLE_DEFINE(cmd_buffer, BTP_MTU); + + cmd_hdr = net_buf_simple_add(&cmd_buffer, sizeof(*cmd_hdr)); + cmd_hdr->service = BTP_SERVICE_ID_BAP; + cmd_hdr->opcode = BTP_BAP_BROADCAST_SINK_SETUP; + cmd_hdr->index = BTP_INDEX; + + /* The command for this is empty */ + + cmd_hdr->len = cmd_buffer.len - sizeof(*cmd_hdr); + + bsim_btp_send_to_tester(cmd_buffer.data, cmd_buffer.len); +} + +static inline void bsim_btp_bap_broadcast_sink_release(void) +{ + struct btp_hdr *cmd_hdr; + + NET_BUF_SIMPLE_DEFINE(cmd_buffer, BTP_MTU); + + cmd_hdr = net_buf_simple_add(&cmd_buffer, sizeof(*cmd_hdr)); + cmd_hdr->service = BTP_SERVICE_ID_BAP; + cmd_hdr->opcode = BTP_BAP_BROADCAST_SINK_RELEASE; + cmd_hdr->index = BTP_INDEX; + + /* The command for this is empty */ + + cmd_hdr->len = cmd_buffer.len - sizeof(*cmd_hdr); + + bsim_btp_send_to_tester(cmd_buffer.data, cmd_buffer.len); +} + +static inline void bsim_btp_bap_broadcast_scan_start(void) +{ + struct btp_hdr *cmd_hdr; + + NET_BUF_SIMPLE_DEFINE(cmd_buffer, BTP_MTU); + + cmd_hdr = net_buf_simple_add(&cmd_buffer, sizeof(*cmd_hdr)); + cmd_hdr->service = BTP_SERVICE_ID_BAP; + cmd_hdr->opcode = BTP_BAP_BROADCAST_SCAN_START; + cmd_hdr->index = BTP_INDEX; + + /* The command for this is empty */ + + cmd_hdr->len = cmd_buffer.len - sizeof(*cmd_hdr); + + bsim_btp_send_to_tester(cmd_buffer.data, cmd_buffer.len); +} + +static inline void bsim_btp_bap_broadcast_scan_stop(void) +{ + struct btp_hdr *cmd_hdr; + + NET_BUF_SIMPLE_DEFINE(cmd_buffer, BTP_MTU); + + cmd_hdr = net_buf_simple_add(&cmd_buffer, sizeof(*cmd_hdr)); + cmd_hdr->service = BTP_SERVICE_ID_BAP; + cmd_hdr->opcode = BTP_BAP_BROADCAST_SCAN_STOP; + cmd_hdr->index = BTP_INDEX; + + /* The command for this is empty */ + + cmd_hdr->len = cmd_buffer.len - sizeof(*cmd_hdr); + + bsim_btp_send_to_tester(cmd_buffer.data, cmd_buffer.len); +} + +static inline void bsim_btp_bap_broadcast_sink_sync(const bt_addr_le_t *address, + uint32_t broadcast_id, uint8_t advertiser_sid, + uint16_t skip, uint16_t sync_timeout, + bool past_avail, uint8_t src_id) +{ + struct btp_bap_broadcast_sink_sync_cmd *cmd; + struct btp_hdr *cmd_hdr; + + NET_BUF_SIMPLE_DEFINE(cmd_buffer, BTP_MTU); + + cmd_hdr = net_buf_simple_add(&cmd_buffer, sizeof(*cmd_hdr)); + cmd_hdr->service = BTP_SERVICE_ID_BAP; + cmd_hdr->opcode = BTP_BAP_BROADCAST_SINK_SYNC; + cmd_hdr->index = BTP_INDEX; + cmd = net_buf_simple_add(&cmd_buffer, sizeof(*cmd)); + bt_addr_le_copy(&cmd->address, address); + sys_put_le24(broadcast_id, cmd->broadcast_id); + cmd->advertiser_sid = advertiser_sid; + cmd->skip = sys_cpu_to_le16(skip); + cmd->sync_timeout = sys_cpu_to_le16(sync_timeout); + cmd->past_avail = past_avail ? 1U : 0U; + cmd->src_id = src_id; + + cmd_hdr->len = cmd_buffer.len - sizeof(*cmd_hdr); + + bsim_btp_send_to_tester(cmd_buffer.data, cmd_buffer.len); +} + +static inline void bsim_btp_bap_broadcast_sink_stop(const bt_addr_le_t *address, + uint32_t broadcast_id) +{ + struct btp_bap_broadcast_sink_stop_cmd *cmd; + struct btp_hdr *cmd_hdr; + + NET_BUF_SIMPLE_DEFINE(cmd_buffer, BTP_MTU); + + cmd_hdr = net_buf_simple_add(&cmd_buffer, sizeof(*cmd_hdr)); + cmd_hdr->service = BTP_SERVICE_ID_BAP; + cmd_hdr->opcode = BTP_BAP_BROADCAST_SINK_STOP; + cmd_hdr->index = BTP_INDEX; + cmd = net_buf_simple_add(&cmd_buffer, sizeof(*cmd)); + bt_addr_le_copy(&cmd->address, address); + sys_put_le24(broadcast_id, cmd->broadcast_id); + + cmd_hdr->len = cmd_buffer.len - sizeof(*cmd_hdr); + + bsim_btp_send_to_tester(cmd_buffer.data, cmd_buffer.len); +} + +static inline void bsim_btp_bap_broadcast_sink_bis_sync(const bt_addr_le_t *address, + uint32_t broadcast_id, + uint32_t requested_bis_sync) +{ + struct btp_bap_broadcast_sink_bis_sync_cmd *cmd; + struct btp_hdr *cmd_hdr; + + NET_BUF_SIMPLE_DEFINE(cmd_buffer, BTP_MTU); + + cmd_hdr = net_buf_simple_add(&cmd_buffer, sizeof(*cmd_hdr)); + cmd_hdr->service = BTP_SERVICE_ID_BAP; + cmd_hdr->opcode = BTP_BAP_BROADCAST_SINK_BIS_SYNC; + cmd_hdr->index = BTP_INDEX; + cmd = net_buf_simple_add(&cmd_buffer, sizeof(*cmd)); + bt_addr_le_copy(&cmd->address, address); + sys_put_le24(broadcast_id, cmd->broadcast_id); + cmd->requested_bis_sync = sys_cpu_to_le32(requested_bis_sync); + + cmd_hdr->len = cmd_buffer.len - sizeof(*cmd_hdr); + + bsim_btp_send_to_tester(cmd_buffer.data, cmd_buffer.len); +} + +static inline void bsim_btp_bap_broadcast_source_setup_v2( + uint32_t broadcast_id, uint8_t streams_per_subgroup, uint8_t subgroups, + uint32_t sdu_interval, uint8_t framing, uint16_t max_sdu, uint8_t rtn, uint16_t max_latency, + uint32_t presentation_delay, uint8_t coding_format, uint16_t vid, uint16_t cid, + uint8_t cc_ltvs_len, const uint8_t cc_ltvs[]) +{ + struct btp_bap_broadcast_source_setup_v2_cmd *cmd; + struct btp_hdr *cmd_hdr; + + NET_BUF_SIMPLE_DEFINE(cmd_buffer, BTP_MTU); + + cmd_hdr = net_buf_simple_add(&cmd_buffer, sizeof(*cmd_hdr)); + cmd_hdr->service = BTP_SERVICE_ID_BAP; + cmd_hdr->opcode = BTP_BAP_BROADCAST_SOURCE_SETUP_V2; + cmd_hdr->index = BTP_INDEX; + cmd = net_buf_simple_add(&cmd_buffer, sizeof(*cmd)); + sys_put_le24(broadcast_id, cmd->broadcast_id); + cmd->streams_per_subgroup = streams_per_subgroup; + cmd->subgroups = subgroups; + sys_put_le24(sdu_interval, cmd->sdu_interval); + cmd->framing = framing; + cmd->max_sdu = sys_cpu_to_le16(max_sdu); + cmd->retransmission_num = rtn; + cmd->max_transport_latency = sys_cpu_to_le16(max_latency); + sys_put_le24(presentation_delay, cmd->presentation_delay); + cmd->coding_format = coding_format; + cmd->vid = sys_cpu_to_le16(vid); + cmd->cid = sys_cpu_to_le16(cid); + cmd->cc_ltvs_len = cc_ltvs_len; + if (cc_ltvs_len > 0U) { + (void)net_buf_simple_add_mem(&cmd_buffer, cc_ltvs, cc_ltvs_len); + } + + cmd_hdr->len = cmd_buffer.len - sizeof(*cmd_hdr); + + bsim_btp_send_to_tester(cmd_buffer.data, cmd_buffer.len); +} static inline void bsim_btp_wait_for_bap_ase_found(uint8_t *ase_id) { @@ -305,6 +524,67 @@ static inline void bsim_btp_wait_for_bap_ase_found(uint8_t *ase_id) net_buf_unref(buf); } +static inline void bsim_btp_wait_for_bap_baa_found(bt_addr_le_t *address, uint32_t *broadcast_id, + uint8_t *advertiser_sid) +{ + struct btp_bap_baa_found_ev *ev; + struct net_buf *buf; + + bsim_btp_wait_for_evt(BTP_SERVICE_ID_BAP, BTP_BAP_EV_BAA_FOUND, &buf); + ev = net_buf_pull_mem(buf, sizeof(*ev)); + + if (address != NULL) { + bt_addr_le_copy(address, &ev->address); + } + + if (broadcast_id != NULL) { + *broadcast_id = sys_get_le24(ev->broadcast_id); + } + + if (advertiser_sid != NULL) { + *advertiser_sid = ev->advertiser_sid; + } + + net_buf_unref(buf); +} + +static inline void bsim_btp_wait_for_bap_bap_bis_found(uint8_t *bis_id) +{ + struct btp_bap_bis_found_ev *ev; + struct net_buf *buf; + + bsim_btp_wait_for_evt(BTP_SERVICE_ID_BAP, BTP_BAP_EV_BIS_FOUND, &buf); + ev = net_buf_pull_mem(buf, sizeof(*ev)); + + if (bis_id != NULL) { + *bis_id = ev->bis_id; + } + + net_buf_unref(buf); +} + +static inline void bsim_btp_wait_for_btp_bap_bis_synced(void) +{ + struct btp_bap_bis_synced_ev *ev; + struct net_buf *buf; + + bsim_btp_wait_for_evt(BTP_SERVICE_ID_BAP, BTP_BAP_EV_BIS_SYNCED, &buf); + ev = net_buf_pull_mem(buf, sizeof(*ev)); + + net_buf_unref(buf); +} + +static inline void bsim_btp_wait_for_bap_bis_stream_received(void) +{ + struct btp_bap_bis_stream_received_ev *ev; + struct net_buf *buf; + + bsim_btp_wait_for_evt(BTP_SERVICE_ID_BAP, BTP_BAP_EV_BIS_STREAM_RECEIVED, &buf); + ev = net_buf_pull_mem(buf, sizeof(*ev)); + + net_buf_unref(buf); +} + static inline void bsim_btp_ccp_discover(const bt_addr_le_t *address) { struct btp_ccp_discover_tbs_cmd *cmd; diff --git a/tests/bsim/bluetooth/tester/src/test_main.c b/tests/bsim/bluetooth/tester/src/test_main.c index 29b9711904e0..efb93fb9ba80 100644 --- a/tests/bsim/bluetooth/tester/src/test_main.c +++ b/tests/bsim/bluetooth/tester/src/test_main.c @@ -7,6 +7,8 @@ #include "bstests.h" +extern struct bst_test_list *test_bap_broadcast_sink_install(struct bst_test_list *tests); +extern struct bst_test_list *test_bap_broadcast_source_install(struct bst_test_list *tests); extern struct bst_test_list *test_bap_central_install(struct bst_test_list *tests); extern struct bst_test_list *test_bap_peripheral_install(struct bst_test_list *tests); extern struct bst_test_list *test_ccp_central_install(struct bst_test_list *tests); @@ -29,6 +31,8 @@ extern struct bst_test_list *test_iso_broadcaster_install(struct bst_test_list * extern struct bst_test_list *test_iso_sync_receiver_install(struct bst_test_list *tests); bst_test_install_t test_installers[] = { + test_bap_broadcast_sink_install, + test_bap_broadcast_source_install, test_bap_central_install, test_bap_peripheral_install, test_ccp_central_install, diff --git a/tests/bsim/bluetooth/tester/tests_scripts/bap_broadcast.sh b/tests/bsim/bluetooth/tester/tests_scripts/bap_broadcast.sh new file mode 100755 index 000000000000..9beb1f7ec033 --- /dev/null +++ b/tests/bsim/bluetooth/tester/tests_scripts/bap_broadcast.sh @@ -0,0 +1,43 @@ +#!/usr/bin/env bash +# Copyright 2025 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +# Smoketest for BAP BTP commands with the BT tester + +simulation_id="tester_bap_broadcast" +verbosity_level=2 +EXECUTE_TIMEOUT=100 + +source ${ZEPHYR_BASE}/tests/bsim/sh_common.source + +cd ${BSIM_OUT_PATH}/bin + +UART_DIR=/tmp/bs_${USER}/${simulation_id}/ +UART_SNK=${UART_DIR}/sink +UART_BCST=${UART_DIR}/broadcaster + +# Broadcaster BT Tester +Execute ./bs_${BOARD_TS}_tests_bluetooth_tester_le_audio_prj_conf \ + -v=${verbosity_level} -s=${simulation_id} -rs=10 -d=0 -RealEncryption=1 \ + -uart0_fifob_rxfile=${UART_BCST}.tx -uart0_fifob_txfile=${UART_BCST}.rx + +# Broadcaster Upper Tester +Execute ./bs_nrf52_bsim_native_tests_bsim_bluetooth_tester_prj_conf \ + -v=${verbosity_level} -s=${simulation_id} -rs=21 -d=10 -RealEncryption=1 \ + -testid=bap_broadcast_source \ + -nosim -uart0_fifob_rxfile=${UART_BCST}.rx -uart0_fifob_txfile=${UART_BCST}.tx + +# Sink BT Tester +Execute ./bs_${BOARD_TS}_tests_bluetooth_tester_le_audio_prj_conf \ + -v=${verbosity_level} -s=${simulation_id} -rs=32 -d=1 -RealEncryption=1 \ + -uart0_fifob_rxfile=${UART_SNK}.tx -uart0_fifob_txfile=${UART_SNK}.rx + +# Sink Upper Tester +Execute ./bs_nrf52_bsim_native_tests_bsim_bluetooth_tester_prj_conf \ + -v=${verbosity_level} -s=${simulation_id} -rs=43 -d=11 -RealEncryption=1 \ + -testid=bap_broadcast_sink \ + -nosim -uart0_fifob_rxfile=${UART_SNK}.rx -uart0_fifob_txfile=${UART_SNK}.tx + +Execute ./bs_2G4_phy_v1 -v=${verbosity_level} -s=${simulation_id} -D=2 -sim_length=20e6 $@ + +wait_for_background_jobs # Wait for all programs in background and return != 0 if any fails diff --git a/tests/bsim/bluetooth/tester/tests_scripts/bap.sh b/tests/bsim/bluetooth/tester/tests_scripts/bap_unicast.sh similarity index 97% rename from tests/bsim/bluetooth/tester/tests_scripts/bap.sh rename to tests/bsim/bluetooth/tester/tests_scripts/bap_unicast.sh index 71c1b2925965..77979ad6d8df 100755 --- a/tests/bsim/bluetooth/tester/tests_scripts/bap.sh +++ b/tests/bsim/bluetooth/tester/tests_scripts/bap_unicast.sh @@ -4,7 +4,7 @@ # Smoketest for BAP BTP commands with the BT tester -simulation_id="tester_bap" +simulation_id="tester_bap_unicast" verbosity_level=2 EXECUTE_TIMEOUT=100 From 2223233e98d97b75d8d8cd7657e8b0aadbbd50b5 Mon Sep 17 00:00:00 2001 From: Yongxu Wang Date: Wed, 5 Nov 2025 16:04:01 +0800 Subject: [PATCH 0420/3659] dts: arm: nxp: add scmi system node for i.MX943 Added scmi system node for NXP i.MX943 Mcore Signed-off-by: Yongxu Wang --- dts/arm/nxp/nxp_imx94x.dtsi | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/dts/arm/nxp/nxp_imx94x.dtsi b/dts/arm/nxp/nxp_imx94x.dtsi index f647d70a2e8a..6be6508cc402 100644 --- a/dts/arm/nxp/nxp_imx94x.dtsi +++ b/dts/arm/nxp/nxp_imx94x.dtsi @@ -32,6 +32,11 @@ #power-domain-cells = <1>; }; + scmi_system: protocol@12 { + compatible = "arm,scmi-system"; + reg = <0x12>; + }; + scmi_clk: protocol@14 { compatible = "arm,scmi-clock"; reg = <0x14>; From 0910ebf469a9fc21a85deb963ae32f1a22f7e3ff Mon Sep 17 00:00:00 2001 From: Yongxu Wang Date: Thu, 6 Nov 2025 14:00:40 +0800 Subject: [PATCH 0421/3659] dts: arm: nxp: add scmi system node for i.MX95 M7 Added scmi system node for NXP i.MX95 M7 Signed-off-by: Yongxu Wang --- dts/arm/nxp/nxp_imx95_m7.dtsi | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/dts/arm/nxp/nxp_imx95_m7.dtsi b/dts/arm/nxp/nxp_imx95_m7.dtsi index 2f2469100963..21503182b6c1 100644 --- a/dts/arm/nxp/nxp_imx95_m7.dtsi +++ b/dts/arm/nxp/nxp_imx95_m7.dtsi @@ -81,6 +81,11 @@ #power-domain-cells = <1>; }; + scmi_system: protocol@12 { + compatible = "arm,scmi-system"; + reg = <0x12>; + }; + scmi_clk: protocol@14 { compatible = "arm,scmi-clock"; reg = <0x14>; From b3a6b4d40504ea139660ba517287faf77956e72d Mon Sep 17 00:00:00 2001 From: Aiden Hu Date: Tue, 18 Nov 2025 19:40:16 +0800 Subject: [PATCH 0422/3659] drivers: uhc: use correct endpoint type and interval In the USB transfer allocation, set endpoint type and interval from the appropriate endpoint descriptor. Signed-off-by: Aiden Hu --- drivers/usb/uhc/uhc_common.c | 8 ++++++++ drivers/usb/uhc/uhc_mcux_common.c | 10 ++-------- include/zephyr/drivers/usb/uhc.h | 2 ++ 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/drivers/usb/uhc/uhc_common.c b/drivers/usb/uhc/uhc_common.c index 097d4a01457e..e06048c4e926 100644 --- a/drivers/usb/uhc/uhc_common.c +++ b/drivers/usb/uhc/uhc_common.c @@ -101,6 +101,8 @@ struct uhc_transfer *uhc_xfer_alloc(const struct device *dev, const struct uhc_api *api = dev->api; struct uhc_transfer *xfer = NULL; uint16_t mps; + uint16_t interval; + uint8_t type; api->lock(dev); @@ -109,6 +111,8 @@ struct uhc_transfer *uhc_xfer_alloc(const struct device *dev, } if (ep_idx == 0) { + interval = 0; + type = USB_EP_TYPE_CONTROL; mps = udev->dev_desc.bMaxPacketSize0; } else { struct usb_ep_descriptor *ep_desc; @@ -125,6 +129,8 @@ struct uhc_transfer *uhc_xfer_alloc(const struct device *dev, } mps = ep_desc->wMaxPacketSize; + interval = ep_desc->bInterval; + type = ep_desc->bmAttributes & USB_EP_TRANSFER_TYPE_MASK; } LOG_DBG("Allocate xfer, ep 0x%02x mps %u cb %p", ep, mps, cb); @@ -137,6 +143,8 @@ struct uhc_transfer *uhc_xfer_alloc(const struct device *dev, memset(xfer, 0, sizeof(struct uhc_transfer)); xfer->ep = ep; xfer->mps = mps; + xfer->interval = interval; + xfer->type = type; xfer->udev = udev; xfer->cb = cb; xfer->priv = cb_priv; diff --git a/drivers/usb/uhc/uhc_mcux_common.c b/drivers/usb/uhc/uhc_mcux_common.c index 7ed7aa169e8f..7399adab668d 100644 --- a/drivers/usb/uhc/uhc_mcux_common.c +++ b/drivers/usb/uhc/uhc_mcux_common.c @@ -243,8 +243,7 @@ static usb_host_pipe_handle uhc_mcux_check_hal_ep(const struct device *dev, } } - /* TODO: need to check endpoint type too */ - if (mcux_ep != NULL && + if (mcux_ep != NULL && mcux_ep->pipeType == xfer->type && (mcux_ep->maxPacketSize != xfer->mps || mcux_ep->interval != xfer->interval)) { /* re-initialize the ep */ @@ -289,12 +288,7 @@ usb_host_pipe_t *uhc_mcux_init_hal_ep(const struct device *dev, struct uhc_trans */ pipe_init.numberPerUframe = 0; /* TODO: need right way to implement it. */ pipe_init.interval = xfer->interval; - /* TODO: need right way to implement it. */ - if (pipe_init.endpointAddress == 0) { - pipe_init.pipeType = USB_ENDPOINT_CONTROL; - } else { - pipe_init.pipeType = USB_ENDPOINT_BULK; - } + pipe_init.pipeType = xfer->type; status = priv->mcux_if->controllerOpenPipe(priv->mcux_host.controllerHandle, (usb_host_pipe_handle *)&mcux_ep, &pipe_init); diff --git a/include/zephyr/drivers/usb/uhc.h b/include/zephyr/drivers/usb/uhc.h index 1e0acd71aad1..5bacfdc19556 100644 --- a/include/zephyr/drivers/usb/uhc.h +++ b/include/zephyr/drivers/usb/uhc.h @@ -120,6 +120,8 @@ struct uhc_transfer { struct net_buf *buf; /** Endpoint to which request is associated */ uint8_t ep; + /** Endpoint type */ + uint8_t type; /** Maximum packet size */ uint16_t mps; /** Interval, used for periodic transfers only */ From 53e3cf281f9fa81ce7ae4e867a87425449a4a842 Mon Sep 17 00:00:00 2001 From: Aiden Hu Date: Tue, 18 Nov 2025 20:56:49 +0800 Subject: [PATCH 0423/3659] drivers: uhc: add mcux_eps_interval to save ep interval mcux_eps_interval is added as the new member of uhc_mcux_data. It is used to save endpoint's original interval value and can be compared with xfer->interval. Signed-off-by: Aiden Hu --- drivers/usb/uhc/uhc_mcux_common.c | 4 +++- drivers/usb/uhc/uhc_mcux_common.h | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/usb/uhc/uhc_mcux_common.c b/drivers/usb/uhc/uhc_mcux_common.c index 7399adab668d..41312bc2b101 100644 --- a/drivers/usb/uhc/uhc_mcux_common.c +++ b/drivers/usb/uhc/uhc_mcux_common.c @@ -245,7 +245,7 @@ static usb_host_pipe_handle uhc_mcux_check_hal_ep(const struct device *dev, if (mcux_ep != NULL && mcux_ep->pipeType == xfer->type && (mcux_ep->maxPacketSize != xfer->mps || - mcux_ep->interval != xfer->interval)) { + priv->mcux_eps_interval[i] != xfer->interval)) { /* re-initialize the ep */ status = priv->mcux_if->controllerClosePipe(priv->mcux_host.controllerHandle, mcux_ep); @@ -255,6 +255,7 @@ static usb_host_pipe_handle uhc_mcux_check_hal_ep(const struct device *dev, uhc_mcux_lock(dev); priv->mcux_eps[i] = NULL; + priv->mcux_eps_interval[i] = 0; uhc_mcux_unlock(dev); mcux_ep = NULL; } @@ -308,6 +309,7 @@ usb_host_pipe_t *uhc_mcux_init_hal_ep(const struct device *dev, struct uhc_trans for (i = 0; i < USB_HOST_CONFIG_MAX_PIPES; i++) { if (priv->mcux_eps[i] == NULL) { priv->mcux_eps[i] = mcux_ep; + priv->mcux_eps_interval[i] = xfer->interval; break; } } diff --git a/drivers/usb/uhc/uhc_mcux_common.h b/drivers/usb/uhc/uhc_mcux_common.h index d80ccdadcfcf..3e9014af85a6 100644 --- a/drivers/usb/uhc/uhc_mcux_common.h +++ b/drivers/usb/uhc/uhc_mcux_common.h @@ -12,6 +12,7 @@ struct uhc_mcux_data { const usb_host_controller_interface_t *mcux_if; /* TODO: Maybe make it to link with udev->ep_in and udev->ep_out */ usb_host_pipe_t *mcux_eps[USB_HOST_CONFIG_MAX_PIPES]; + uint16_t mcux_eps_interval[USB_HOST_CONFIG_MAX_PIPES]; usb_host_instance_t mcux_host; struct k_thread drv_stack_data; uint8_t controller_id; /* MCUX hal controller id, 0xFF is invalid value */ From f3e7cde40b14245e8b2c3eb0113f9214601489b8 Mon Sep 17 00:00:00 2001 From: Aiden Hu Date: Wed, 19 Nov 2025 08:34:03 +0800 Subject: [PATCH 0424/3659] drivers: uhc: set right value for pipe by xfer's mps maxPacketSize and numberPerUframe of pipe should be set considering additional transactions. Signed-off-by: Aiden Hu --- drivers/usb/uhc/uhc_mcux_common.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/uhc/uhc_mcux_common.c b/drivers/usb/uhc/uhc_mcux_common.c index 41312bc2b101..d8e96d42d580 100644 --- a/drivers/usb/uhc/uhc_mcux_common.c +++ b/drivers/usb/uhc/uhc_mcux_common.c @@ -280,14 +280,14 @@ usb_host_pipe_t *uhc_mcux_init_hal_ep(const struct device *dev, struct uhc_trans /* USB_HostHelperGetPeripheralInformation uses this value as first parameter */ pipe_init.devInstance = xfer->udev; pipe_init.nakCount = USB_HOST_CONFIG_MAX_NAK; - pipe_init.maxPacketSize = xfer->mps; + pipe_init.maxPacketSize = USB_MPS_EP_SIZE(xfer->mps); pipe_init.endpointAddress = USB_EP_GET_IDX(xfer->ep); pipe_init.direction = USB_EP_GET_IDX(xfer->ep) == 0 ? USB_OUT : USB_EP_GET_DIR(xfer->ep) ? USB_IN : USB_OUT; /* Current Zephyr Host stack is experimental, the endpoint's interval, * 'number per uframe' and the endpoint type cannot be got yet. */ - pipe_init.numberPerUframe = 0; /* TODO: need right way to implement it. */ + pipe_init.numberPerUframe = USB_MPS_ADDITIONAL_TRANSACTIONS(xfer->mps); pipe_init.interval = xfer->interval; pipe_init.pipeType = xfer->type; From 159b4a6d9756644a5b265b3e21ad85b81e989b93 Mon Sep 17 00:00:00 2001 From: Make Shi Date: Tue, 25 Nov 2025 13:56:14 +0800 Subject: [PATCH 0425/3659] Bluetooth: AVRCP: Fix typo in callback name and opid/state Correct typo and fix opid/state assignment. Signed-off-by: Make Shi --- include/zephyr/bluetooth/classic/avrcp.h | 4 ++-- subsys/bluetooth/host/classic/avrcp.c | 2 +- subsys/bluetooth/host/classic/shell/avrcp.c | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/include/zephyr/bluetooth/classic/avrcp.h b/include/zephyr/bluetooth/classic/avrcp.h index d36fa47394c7..ccef651c7614 100644 --- a/include/zephyr/bluetooth/classic/avrcp.h +++ b/include/zephyr/bluetooth/classic/avrcp.h @@ -297,9 +297,9 @@ struct bt_avrcp_subunit_info_rsp { }; #define BT_AVRCP_PASSTHROUGH_GET_STATE(payload) \ - ((bt_avrcp_opid_t)(FIELD_GET(BIT(7), ((payload)->opid_state)))) + ((bt_avrcp_button_state_t)(FIELD_GET(BIT(7), ((payload)->opid_state)))) #define BT_AVRCP_PASSTHROUGH_GET_OPID(payload) \ - ((bt_avrcp_button_state_t)(FIELD_GET(GENMASK(6, 0), ((payload)->opid_state)))) + ((bt_avrcp_opid_t)(FIELD_GET(GENMASK(6, 0), ((payload)->opid_state)))) #define BT_AVRCP_PASSTHROUGH_SET_STATE_OPID(payload, state, opid) \ (payload)->opid_state = FIELD_PREP(BIT(7), state) | FIELD_PREP(GENMASK(6, 0), opid) diff --git a/subsys/bluetooth/host/classic/avrcp.c b/subsys/bluetooth/host/classic/avrcp.c index b7c85a1bd7a9..0a7d994071e3 100644 --- a/subsys/bluetooth/host/classic/avrcp.c +++ b/subsys/bluetooth/host/classic/avrcp.c @@ -1972,7 +1972,7 @@ static void avrcp_pass_through_rsp_handler(struct bt_avrcp *avrcp, uint8_t tid, avrcp_hdr = net_buf_pull_mem(buf, sizeof(*avrcp_hdr)); - if ((avrcp_ct_cb != NULL) && (avrcp_ct_cb->subunit_info_rsp != NULL)) { + if ((avrcp_ct_cb != NULL) && (avrcp_ct_cb->passthrough_rsp != NULL)) { if (buf->len < sizeof(*rsp)) { LOG_ERR("Invalid passthrough length: %d", buf->len); return; diff --git a/subsys/bluetooth/host/classic/shell/avrcp.c b/subsys/bluetooth/host/classic/shell/avrcp.c index 333a98ca4904..60a971948e8f 100644 --- a/subsys/bluetooth/host/classic/shell/avrcp.c +++ b/subsys/bluetooth/host/classic/shell/avrcp.c @@ -1327,8 +1327,8 @@ static void avrcp_passthrough_req(struct bt_avrcp_tg *tg, uint8_t tid, struct ne tg_tid = tid; cmd = net_buf_pull_mem(buf, sizeof(*cmd)); - opid = BT_AVRCP_PASSTHROUGH_GET_STATE(cmd); - state = BT_AVRCP_PASSTHROUGH_GET_OPID(cmd); + state = BT_AVRCP_PASSTHROUGH_GET_STATE(cmd); + opid = BT_AVRCP_PASSTHROUGH_GET_OPID(cmd); if (cmd->data_len > 0U) { if (buf->len < sizeof(struct bt_avrcp_passthrough_opvu_data)) { From 5bdff095f529ade7fbd0b5dcc84842d6a2eb0560 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Tue, 25 Nov 2025 21:26:11 -0800 Subject: [PATCH 0426/3659] doc: security: Disclose CVE-2025-9557 Disclose information about published CVE. Signed-off-by: Flavio Ceolin --- doc/security/vulnerabilities.rst | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/doc/security/vulnerabilities.rst b/doc/security/vulnerabilities.rst index 65bfbac8eaa0..2d4dfdd1c4cc 100644 --- a/doc/security/vulnerabilities.rst +++ b/doc/security/vulnerabilities.rst @@ -2040,7 +2040,25 @@ This has been fixed in main for v4.3.0 :cve:`2025-9557` ---------------- -Under embargo until 2025-11-24 +Bluetooth: Mesh: Out-of-Bound Write in gen_prov_cont + +An out-of-bound write can lead to an arbitrary code execution. Even on +devices with some form of memory protection, this can still lead to a +crash and a resultant denial of service. + +- `Zephyr project bug tracker GHSA-r3j3-c5v7-2ppf + `_ + +This has been fixed in main for v4.3.0 + +- `PR 95061 fix for main + `_ + +- `PR 97518 fix for 4.2 + `_ + +- `PR 97517 fix for 4.1 + `_ :cve:`2025-9558` ---------------- From d06d49eb7ca57ddb5d3d307be2764fc43e73e760 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Tue, 25 Nov 2025 21:30:24 -0800 Subject: [PATCH 0427/3659] doc: security: Disclose CVE-2025-9558 Disclose information about published CVE. Signed-off-by: Flavio Ceolin --- doc/security/vulnerabilities.rst | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/doc/security/vulnerabilities.rst b/doc/security/vulnerabilities.rst index 2d4dfdd1c4cc..f636f2d4f8e8 100644 --- a/doc/security/vulnerabilities.rst +++ b/doc/security/vulnerabilities.rst @@ -2063,7 +2063,27 @@ This has been fixed in main for v4.3.0 :cve:`2025-9558` ---------------- -Under embargo until 2025-11-24 +Bluetooth: Mesh: Out-of-Bound Write in gen_prov_start + +There is a potential OOB Write vulnerability in the gen_prov_start +function in pb_adv.c. The full length of the received data is copied +into the link.rx.buf receiver buffer without any validation on the +data size. + +- `Zephyr project bug tracker GHSA-8wvr-688x-68vr + `_ + +This has been fixed in main for v4.3.0 + +- `PR 95064 fix for main + `_ + +- `PR 97520 fix for 4.2 + `_ + +- `PR 97519 fix for 4.1 + `_ + :cve:`2025-12035` ----------------- From 2a8343f0f763082253e7b4f49837ef458ef767de Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Mon, 15 Dec 2025 11:46:57 -0800 Subject: [PATCH 0428/3659] doc: security: Disclose CVE-2025-12035 Disclose information about published CVE. Signed-off-by: Flavio Ceolin --- doc/security/vulnerabilities.rst | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/doc/security/vulnerabilities.rst b/doc/security/vulnerabilities.rst index f636f2d4f8e8..28242d7f7cb7 100644 --- a/doc/security/vulnerabilities.rst +++ b/doc/security/vulnerabilities.rst @@ -2088,7 +2088,20 @@ This has been fixed in main for v4.3.0 :cve:`2025-12035` ----------------- -Under embargo until 2025-12-13 +Bluetooth: Integer Overflow in Bluetooth Classic (BR/EDR) L2CAP + +An integer overflow condition exists in Bluetooth Host stack, within the bt_br_acl_recv routine a +critical path for processing inbound BR/EDR L2CAP traffic. + + +- `Zephyr project bug tracker GHSA-p793-3456-h7w3 + `_ + +This has been fixed in main for v4.3.0 + +- `PR 97370 fix for main + `_ + :cve:`2025-12890` ----------------- From dd5f8c483b38987e7d3800dff93924674126e9c4 Mon Sep 17 00:00:00 2001 From: Lin Yu-Cheng Date: Mon, 1 Dec 2025 14:14:47 +0800 Subject: [PATCH 0429/3659] drivers: spi: spi_rts5912_spi: Add clock-frequency setting from dtsi The clock-frequency value in dtsi can be used to change the bus frequency for rts5912 driver and it support in the range between 15000 to 50000000. Signed-off-by: Lin Yu-Cheng --- drivers/spi/spi_rts5912_spi.c | 40 +++++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/drivers/spi/spi_rts5912_spi.c b/drivers/spi/spi_rts5912_spi.c index e777fae0ce5c..1b6f5aae396c 100644 --- a/drivers/spi/spi_rts5912_spi.c +++ b/drivers/spi/spi_rts5912_spi.c @@ -14,12 +14,16 @@ #include #include "reg/reg_spi.h" -#define RTS5912_SPI_TIMEOUT_ROUND 100 -#define RTS5912_SPI_TX_FIFO_LIMIT 128 -#define RTS5912_SPI_ADDR_NUM 0x07 -#define RTS5912_SPI_FREQUENCY_SETTING 22 /* 3.84MHz */ -#define RTS5912_SPI_ADDR_ONLY_MODE 0 -#define RTS5912_SPI_ADDR_AND_DATA_MODE 2 +#define RTS5912_SPI_TIMEOUT_ROUND 100 +#define RTS5912_SPI_TX_FIFO_LIMIT 128 +#define RTS5912_SPI_ADDR_NUM 0x07 +#define RTS5912_SPI_FREQUENCY_DEFAULT 22 /* 3.84MHz */ +#define RTS5912_SPI_FREQUENCY_REGISTER_MAXIMUM 0xFFFFFFFF +#define RTS5912_SPI_FREQUENCY_BUS_MAXIMUM (50000000ul) +#define RTS5912_SPI_FREQUENCY_BUS_MINIMUM (15000ul) +#define RTS5912_PLL_DIV2_FREQUENCY (50000000ul) +#define RTS5912_SPI_ADDR_ONLY_MODE 0 +#define RTS5912_SPI_ADDR_AND_DATA_MODE 2 LOG_MODULE_REGISTER(spi_rts5912_spi, CONFIG_SPI_LOG_LEVEL); #include "spi_context.h" @@ -27,6 +31,7 @@ LOG_MODULE_REGISTER(spi_rts5912_spi, CONFIG_SPI_LOG_LEVEL); struct spi_rts5912_config { volatile struct spi_reg *const spi_reg_base; const struct pinctrl_dev_config *pcfg; + const uint32_t frequency; }; struct spi_rts5912_data { @@ -90,11 +95,16 @@ static int spi_rts5912_configure(const struct device *dev, const struct spi_conf spi->CTRL &= ~RTS5912_SPI_CTRL_MODE_MASK; spi->CTRL |= RTS5912_SPI_CTRL_TRANSEL_MASK; - spi->CMDL = 0x00; /* cmd mode setting */ + spi->CMDL = 0x00; /* cmd mode setting */ spi->CMDN = RTS5912_SPI_ADDR_NUM; /* 7+1bit = 1Byte CMD */ spi->ADDR = 0x0; spi->ADDRN = RTS5912_SPI_ADDR_NUM; - spi->CKDV = RTS5912_SPI_FREQUENCY_SETTING; + if ((spi_config->frequency < RTS5912_SPI_FREQUENCY_BUS_MAXIMUM) && + (spi_config->frequency > RTS5912_SPI_FREQUENCY_BUS_MINIMUM)) { + spi->CKDV = (RTS5912_PLL_DIV2_FREQUENCY / spi_config->frequency) - 1; + } else { + spi->CKDV = RTS5912_SPI_FREQUENCY_DEFAULT; + } spi->CTRL |= RTS5912_SPI_CTRL_RST_MASK; return 0; @@ -127,10 +137,10 @@ static inline void rts5912_spi_tx(const struct device *dev) if (ctx->tx_len == 1) { spi->TRSF = ((spi->TRSF & ~RTS5912_SPI_TRSF_MODE_MASK) | - (RTS5912_SPI_ADDR_ONLY_MODE & RTS5912_SPI_TRSF_MODE_MASK)); + (RTS5912_SPI_ADDR_ONLY_MODE & RTS5912_SPI_TRSF_MODE_MASK)); } else { spi->TRSF = ((spi->TRSF & ~RTS5912_SPI_TRSF_MODE_MASK) | - (RTS5912_SPI_ADDR_AND_DATA_MODE & RTS5912_SPI_TRSF_MODE_MASK)); + (RTS5912_SPI_ADDR_AND_DATA_MODE & RTS5912_SPI_TRSF_MODE_MASK)); } spi->CTRL |= RTS5912_SPI_CTRL_RST_MASK; @@ -174,8 +184,8 @@ static int rts5912_spi_xfer(const struct device *dev) } static int rts5912_spi_transceive(const struct device *dev, const struct spi_config *config, - const struct spi_buf_set *tx_bufs, - const struct spi_buf_set *rx_bufs) + const struct spi_buf_set *tx_bufs, + const struct spi_buf_set *rx_bufs) { struct spi_rts5912_data *data = dev->data; struct spi_context *ctx = &data->ctx; @@ -248,8 +258,10 @@ static DEVICE_API(spi, spi_rts5912_driver_api) = { #define SPI_rts5912_INIT(n) \ PINCTRL_DT_INST_DEFINE(n); \ static const struct spi_rts5912_config spi_rts5912_cfg_##n = { \ - .spi_reg_base = (volatile struct spi_reg *const)DT_INST_REG_ADDR(n), \ + .spi_reg_base = (volatile struct spi_reg *const)DT_INST_REG_ADDR(n), \ .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ + .frequency = \ + DT_PROP_OR(n, clock_frequency, RTS5912_SPI_FREQUENCY_REGISTER_MAXIMUM), \ }; \ \ static struct spi_rts5912_data spi_rts5912_data_##n = { \ @@ -257,7 +269,7 @@ static DEVICE_API(spi, spi_rts5912_driver_api) = { SPI_CONTEXT_INIT_SYNC(spi_rts5912_data_##n, ctx), \ SPI_CONTEXT_CS_GPIOS_INITIALIZE(DT_DRV_INST(n), ctx)}; \ \ - DEVICE_DT_INST_DEFINE(n, &spi_rts5912_spi_init, NULL, &spi_rts5912_data_##n, \ + DEVICE_DT_INST_DEFINE(n, &spi_rts5912_spi_init, NULL, &spi_rts5912_data_##n, \ &spi_rts5912_cfg_##n, POST_KERNEL, \ CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &spi_rts5912_driver_api); From 0830f9fd38ca95343c0fa0e98a29a80ee32038ee Mon Sep 17 00:00:00 2001 From: Biwen Li Date: Fri, 17 Oct 2025 18:26:30 +0900 Subject: [PATCH 0430/3659] boards: nxp: imx943_evk: m33: use common dtsi Use common dtsi imx943_evk_mimx94398_cm.dtsi Signed-off-by: Biwen Li --- .../imx943_evk/imx943_evk_mimx94398_cm.dtsi | 2 - .../imx943_evk/imx943_evk_mimx94398_m33.dts | 61 +------------------ 2 files changed, 1 insertion(+), 62 deletions(-) diff --git a/boards/nxp/imx943_evk/imx943_evk_mimx94398_cm.dtsi b/boards/nxp/imx943_evk/imx943_evk_mimx94398_cm.dtsi index aa0bc4c9e29b..e91d88c5c553 100644 --- a/boards/nxp/imx943_evk/imx943_evk_mimx94398_cm.dtsi +++ b/boards/nxp/imx943_evk/imx943_evk_mimx94398_cm.dtsi @@ -4,8 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -/dts-v1/; - &emdio { pinctrl-0 = <&emdio_default>; pinctrl-names = "default"; diff --git a/boards/nxp/imx943_evk/imx943_evk_mimx94398_m33.dts b/boards/nxp/imx943_evk/imx943_evk_mimx94398_m33.dts index 271e8b4c7ac6..6bf01e3fa543 100644 --- a/boards/nxp/imx943_evk/imx943_evk_mimx94398_m33.dts +++ b/boards/nxp/imx943_evk/imx943_evk_mimx94398_m33.dts @@ -8,6 +8,7 @@ #include #include "imx943_evk-pinctrl.dtsi" +#include "imx943_evk_mimx94398_cm.dtsi" / { model = "NXP i.MX943 EVK board"; @@ -22,66 +23,6 @@ }; }; -&emdio { - pinctrl-0 = <&emdio_default>; - pinctrl-names = "default"; - status = "disabled"; - - phy0: phy@2 { - compatible = "ethernet-phy"; - reg = <0x2>; - status = "disabled"; - }; - - phy1: phy@3 { - compatible = "ethernet-phy"; - reg = <0x3>; - status = "disabled"; - }; - - phy2: phy@5 { - compatible = "realtek,rtl8211f"; - reg = <0x5>; - status = "disabled"; - }; - - phy3: phy@6 { - compatible = "realtek,rtl8211f"; - reg = <0x6>; - status = "disabled"; - }; - - phy4: phy@7 { - compatible = "realtek,rtl8211f"; - reg = <0x7>; - status = "disabled"; - }; -}; - -&enetc_psi0 { - pinctrl-0 = <ð2_default>; - pinctrl-names = "default"; - phy-handle = <&phy2>; - phy-connection-type = "rgmii"; - status = "disabled"; -}; - -&enetc_psi1 { - pinctrl-0 = <ð3_default>; - pinctrl-names = "default"; - phy-handle = <&phy3>; - phy-connection-type = "rgmii"; - status = "disabled"; -}; - -&enetc_psi2 { - pinctrl-0 = <ð4_default>; - pinctrl-names = "default"; - phy-handle = <&phy4>; - phy-connection-type = "rgmii"; - status = "disabled"; -}; - &flexio1 { status = "okay"; From 9712a581292c7d59334e7961e45361b2d0534957 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=A9tan=20Froissard?= Date: Thu, 11 Dec 2025 10:02:39 +0100 Subject: [PATCH 0431/3659] drivers: entropy: stm32: Keep RNG clock running during PKA operation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If PKA is running, it needs the RNG clock to properly works. Don't turn it off when RNG computation is over. Signed-off-by: Gaétan Froissard --- drivers/entropy/entropy_stm32.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/entropy/entropy_stm32.c b/drivers/entropy/entropy_stm32.c index 6dd1a8d6f17a..81b416a6f6bb 100644 --- a/drivers/entropy/entropy_stm32.c +++ b/drivers/entropy/entropy_stm32.c @@ -140,12 +140,20 @@ static int entropy_stm32_suspend(void) LL_RNG_SetAesReset(rng, 1); #endif /* CONFIG_SOC_STM32WB09XX */ -#ifdef CONFIG_SOC_SERIES_STM32WBAX - uint32_t wait_cycles, rng_rate; +/* PKA module isn't currently supported in Zephyr, but it could be used outside Zephyr */ +#if defined(PKA) + if (__HAL_RCC_PKA_IS_CLK_ENABLED() && LL_PKA_IsEnabled(PKA)) { +#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 */ - if (LL_PKA_IsEnabled(PKA)) { + /* PKA needs RNG clock, so exit here if in use */ return 0; } +#endif /* PKA */ + +#ifdef CONFIG_SOC_SERIES_STM32WBAX + uint32_t wait_cycles, rng_rate; if (clock_control_get_rate(dev_data->clock, (clock_control_subsys_t) &dev_cfg->pclken[0], From 37fc90cd1d95f48605d8cda4c3e454d5ec3b3353 Mon Sep 17 00:00:00 2001 From: Mark Rages Date: Wed, 3 Dec 2025 15:53:10 -0600 Subject: [PATCH 0432/3659] drivers: sensor: adxl367: fix temperature scaling The fractional part of the value was getting set incorrectly in adxl_temp_convert(). Signed-off-by: Mark Rages --- drivers/sensor/adi/adxl367/adxl367.c | 7 ++++--- drivers/sensor/adi/adxl367/adxl367.h | 7 +++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/sensor/adi/adxl367/adxl367.c b/drivers/sensor/adi/adxl367/adxl367.c index 5196773c3f47..bd5eb5e32000 100644 --- a/drivers/sensor/adi/adxl367/adxl367.c +++ b/drivers/sensor/adi/adxl367/adxl367.c @@ -918,10 +918,11 @@ void adxl367_temp_convert(struct sensor_value *val, int16_t value) static void adxl367_temp_convert(struct sensor_value *val, int16_t value) #endif /*CONFIG_SENSOR_ASYNC_API*/ { - int64_t temp_data = (value - ADXL367_TEMP_25C); + int32_t temp_from_25 = value - ADXL367_TEMP_25C; + int32_t temp_data = temp_from_25 * ADXL367_TEMP_SCALE; - val->val1 = temp_data / 54 /*temp sensitivity LSB/C*/ + 25/*bias test conditions*/; - val->val2 = temp_data % 54 * 10000; + val->val1 = temp_data / 1000000 + 25; + val->val2 = temp_data % 1000000; } static int adxl367_channel_get(const struct device *dev, diff --git a/drivers/sensor/adi/adxl367/adxl367.h b/drivers/sensor/adi/adxl367/adxl367.h index bc6ddd0f32a7..67049b77ded5 100644 --- a/drivers/sensor/adi/adxl367/adxl367.h +++ b/drivers/sensor/adi/adxl367/adxl367.h @@ -155,10 +155,9 @@ #define ADXL367_NO_ACTIVITY_DETECTION_2 0x2 #define ADXL367_REFERENCED_ACTIVITY_ENABLE 0x3 -#define ADXL367_TEMP_OFFSET 1185 -#define ADXL367_TEMP_25C 165 -#define ADXL367_TEMP_SCALE 18518518LL -#define ADXL367_TEMP_SCALE_DIV 1000000000 +#define ADXL367_TEMP_SENSITIVITY 54 /* LSB per C */ +#define ADXL367_TEMP_25C (165) /* Counts at 25 C */ +#define ADXL367_TEMP_SCALE (uint32_t)(1000000 / ADXL367_TEMP_SENSITIVITY) #define ADXL367_THRESH_H_MSK GENMASK(6, 0) #define ADXL367_THRESH_L_MSK GENMASK(7, 2) From 3d8a5700323588edeedbbf1d726263e836422308 Mon Sep 17 00:00:00 2001 From: Zhaoxiang Jin Date: Thu, 11 Dec 2025 10:54:48 +0800 Subject: [PATCH 0433/3659] boards: frdm_mcxc444: Enable DAC for frdm_mcxc444 Enable DAC for frdm_mcxc444 Signed-off-by: Zhaoxiang Jin --- boards/nxp/frdm_mcxc444/frdm_mcxc444.dts | 4 ++++ boards/nxp/frdm_mcxc444/frdm_mcxc444.yaml | 1 + dts/arm/nxp/nxp_mcxc_common.dtsi | 9 +++++++++ 3 files changed, 14 insertions(+) diff --git a/boards/nxp/frdm_mcxc444/frdm_mcxc444.dts b/boards/nxp/frdm_mcxc444/frdm_mcxc444.dts index b6318a5ca6d7..9e9fa9fbf9b0 100644 --- a/boards/nxp/frdm_mcxc444/frdm_mcxc444.dts +++ b/boards/nxp/frdm_mcxc444/frdm_mcxc444.dts @@ -199,3 +199,7 @@ zephyr_udc0: &usb { &dma { status = "okay"; }; + +&dac { + status = "okay"; +}; diff --git a/boards/nxp/frdm_mcxc444/frdm_mcxc444.yaml b/boards/nxp/frdm_mcxc444/frdm_mcxc444.yaml index 81cc7a849578..6ad047ff3715 100644 --- a/boards/nxp/frdm_mcxc444/frdm_mcxc444.yaml +++ b/boards/nxp/frdm_mcxc444/frdm_mcxc444.yaml @@ -25,6 +25,7 @@ supported: - usbd - watchdog - dma + - dac testing: ignore_tags: - net diff --git a/dts/arm/nxp/nxp_mcxc_common.dtsi b/dts/arm/nxp/nxp_mcxc_common.dtsi index 7469dde82120..4803ed9f9047 100644 --- a/dts/arm/nxp/nxp_mcxc_common.dtsi +++ b/dts/arm/nxp/nxp_mcxc_common.dtsi @@ -375,6 +375,15 @@ interrupts = <0 0>, <1 0>, <2 0>, <3 0>; status = "disabled"; }; + + dac: dac@4003f000 { + compatible = "nxp,kinetis-dac"; + reg = <0x4003f000 0x1000>; + interrupts = <25 0>; + status = "disabled"; + #io-channel-cells = <1>; + voltage-reference = <2>; + }; }; }; From cfa415e6059efca6e554ad127c974cb3d8911812 Mon Sep 17 00:00:00 2001 From: Zhaoxiang Jin Date: Thu, 11 Dec 2025 10:56:20 +0800 Subject: [PATCH 0434/3659] tests: dac: Enable dac_api test for frdm_mcxc444 1. Enable dac_api test for frdm_mcxc444. 2. Enable sample/dac for frdm_mcxc444 Signed-off-by: Zhaoxiang Jin --- samples/drivers/dac/boards/frdm_mcxc444.overlay | 14 ++++++++++++++ tests/drivers/dac/dac_api/src/test_dac.c | 3 ++- 2 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 samples/drivers/dac/boards/frdm_mcxc444.overlay diff --git a/samples/drivers/dac/boards/frdm_mcxc444.overlay b/samples/drivers/dac/boards/frdm_mcxc444.overlay new file mode 100644 index 000000000000..8f53bea8c090 --- /dev/null +++ b/samples/drivers/dac/boards/frdm_mcxc444.overlay @@ -0,0 +1,14 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* Users can measure the DAC output on J6-2. */ +/ { + zephyr,user { + dac = <&dac>; + dac-channel-id = <0>; + dac-resolution = <12>; + }; +}; diff --git a/tests/drivers/dac/dac_api/src/test_dac.c b/tests/drivers/dac/dac_api/src/test_dac.c index ab5701e5076b..f5312851988a 100644 --- a/tests/drivers/dac/dac_api/src/test_dac.c +++ b/tests/drivers/dac/dac_api/src/test_dac.c @@ -84,7 +84,8 @@ defined(CONFIG_BOARD_GD32F470I_EVAL) || \ defined(CONFIG_BOARD_YD_ESP32) || \ defined(CONFIG_BOARD_MIMXRT1170_EVK) || \ - defined(CONFIG_BOARD_MIMXRT1180_EVK) + defined(CONFIG_BOARD_MIMXRT1180_EVK) || \ + defined(CONFIG_BOARD_FRDM_MCXC444) #define DAC_DEVICE_NODE DT_NODELABEL(dac) #define DAC_RESOLUTION 12 From e866da994fbfc8e84b90518145b41a268ead91d8 Mon Sep 17 00:00:00 2001 From: Martin Hoff Date: Thu, 11 Dec 2025 17:30:10 +0100 Subject: [PATCH 0435/3659] soc: silabs: siwx91x: remove power profile property Power profile property doesn't need to be defined in device three. It is a configuration value that is defined if we want pm with Bluetooth and/or Wifi . Signed-off-by: Martin Hoff --- dts/arm/silabs/siwg917.dtsi | 1 - dts/bindings/net/wireless/silabs,siwx91x-nwp.yaml | 11 ----------- soc/silabs/silabs_siwx91x/siwg917/siwx91x_nwp.c | 6 ++---- 3 files changed, 2 insertions(+), 16 deletions(-) diff --git a/dts/arm/silabs/siwg917.dtsi b/dts/arm/silabs/siwg917.dtsi index c94abd5b486f..b8c365cb5db2 100644 --- a/dts/arm/silabs/siwg917.dtsi +++ b/dts/arm/silabs/siwg917.dtsi @@ -76,7 +76,6 @@ nwp: nwp { compatible = "silabs,siwx91x-nwp"; - power-profile = "deep-sleep-with-ram-retention"; stack-size = <10240>; interrupt-parent = <&nvic>; interrupts = <30 0>, <74 0>; diff --git a/dts/bindings/net/wireless/silabs,siwx91x-nwp.yaml b/dts/bindings/net/wireless/silabs,siwx91x-nwp.yaml index 44ce5ff751e9..e3fec03f7c76 100644 --- a/dts/bindings/net/wireless/silabs,siwx91x-nwp.yaml +++ b/dts/bindings/net/wireless/silabs,siwx91x-nwp.yaml @@ -21,17 +21,6 @@ properties: description: Stack size for the NWP in bytes required: true - power-profile: - type: string - description: Power/performance profile - enum: - - high-performance - - associated-power-save - - associated-power-save-low-latency - - deep-sleep-without-ram-retention - - deep-sleep-with-ram-retention - required: true - support-1p8v: type: boolean description: | diff --git a/soc/silabs/silabs_siwx91x/siwg917/siwx91x_nwp.c b/soc/silabs/silabs_siwx91x/siwg917/siwx91x_nwp.c index 2a511034cb57..59f43b8b4e17 100644 --- a/soc/silabs/silabs_siwx91x/siwg917/siwx91x_nwp.c +++ b/soc/silabs/silabs_siwx91x/siwg917/siwx91x_nwp.c @@ -43,7 +43,6 @@ struct siwx91x_nwp_data { struct siwx91x_nwp_config { void (*config_irq)(const struct device *dev); uint32_t stack_size; - uint8_t power_profile; uint8_t antenna_selection; bool support_1p8v; bool enable_xtal_correction; @@ -441,9 +440,9 @@ static int siwx91x_nwp_init(const struct device *dev) { const struct siwx91x_nwp_config *config = dev->config; __maybe_unused sl_wifi_performance_profile_t performance_profile = { - .profile = config->power_profile}; + .profile = DEEP_SLEEP_WITH_RAM_RETENTION}; __maybe_unused sl_bt_performance_profile_t bt_performance_profile = { - .profile = config->power_profile}; + .profile = DEEP_SLEEP_WITH_RAM_RETENTION}; sl_wifi_device_configuration_t network_config; int ret; @@ -519,7 +518,6 @@ BUILD_ASSERT(CONFIG_SIWX91X_NWP_INIT_PRIORITY < CONFIG_KERNEL_INIT_PRIORITY_DEFA \ static const struct siwx91x_nwp_config siwx91x_nwp_config_##inst = { \ .config_irq = silabs_siwx91x_nwp_irq_configure_##inst, \ - .power_profile = DT_ENUM_IDX(DT_DRV_INST(inst), power_profile), \ .stack_size = DT_INST_PROP(inst, stack_size), \ .support_1p8v = DT_INST_PROP(inst, support_1p8v), \ .enable_xtal_correction = DT_INST_PROP(inst, enable_xtal_correction), \ From be4723c213541ea01241a9ed27014f57e42e64a3 Mon Sep 17 00:00:00 2001 From: Martin Hoff Date: Thu, 11 Dec 2025 18:22:03 +0100 Subject: [PATCH 0436/3659] soc: silabs: siwx91x: fix pm when bt is enabled This patch is a workaround to a know issue when Bluetooth and pm is activated. We actually need to set the tx power to the Bluetooth controller (network coprocessor) before sending power saving request to the coprocessor. Signed-off-by: Martin Hoff --- drivers/bluetooth/hci/hci_silabs_siwx91x.c | 10 +++ .../silabs_siwx91x/siwg917/siwx91x_nwp.c | 81 +++++++++++++------ .../silabs_siwx91x/siwg917/siwx91x_nwp.h | 11 +++ 3 files changed, 77 insertions(+), 25 deletions(-) diff --git a/drivers/bluetooth/hci/hci_silabs_siwx91x.c b/drivers/bluetooth/hci/hci_silabs_siwx91x.c index 44ca13350145..d02b4bb0d1f2 100644 --- a/drivers/bluetooth/hci/hci_silabs_siwx91x.c +++ b/drivers/bluetooth/hci/hci_silabs_siwx91x.c @@ -13,6 +13,8 @@ LOG_MODULE_REGISTER(bt_hci_driver_siwg917); #include "rsi_ble.h" #include "rsi_ble_common_config.h" +#include "siwx91x_nwp.h" + #define BLE_RF_POWER_INDEX 0x0006 #define BT_OP_VS_RF_POWER_MODE BT_OP(BT_OGF_VS, BLE_RF_POWER_INDEX) #define BT_LE_MODE 2 @@ -76,12 +78,20 @@ static int siwx91x_bt_open(const struct device *dev, bt_hci_recv_t recv) static int siwx91x_bt_setup(const struct device *dev, const struct bt_hci_setup_params *params) { + const struct hci_config *hci_config = dev->config; int err = rsi_bt_driver_send_tx_pwr_vs_cmd(dev, BT_LE_MODE, RSI_BLE_PWR_INX); if (err < 0) { LOG_ERR("Failed to send RF power config command: %d", err); return err; } + + err = siwx91x_nwp_apply_power_profile(hci_config->nwp_dev); + if (err < 0) { + LOG_ERR("Failed to set power profile: %d", err); + return err; + } + return 0; } diff --git a/soc/silabs/silabs_siwx91x/siwg917/siwx91x_nwp.c b/soc/silabs/silabs_siwx91x/siwg917/siwx91x_nwp.c index 59f43b8b4e17..e469b06672e4 100644 --- a/soc/silabs/silabs_siwx91x/siwg917/siwx91x_nwp.c +++ b/soc/silabs/silabs_siwx91x/siwg917/siwx91x_nwp.c @@ -37,6 +37,7 @@ BUILD_ASSERT(DT_REG_SIZE(DT_CHOSEN(zephyr_sram)) == KB(195) || DT_REG_SIZE(DT_CHOSEN(zephyr_sram)) == KB(319)); struct siwx91x_nwp_data { + uint8_t power_profile; char current_country_code[WIFI_COUNTRY_CODE_LEN]; }; @@ -203,7 +204,7 @@ static void siwx91x_configure_sta_mode(sl_si91x_boot_configuration_t *boot_confi } else if (wifi_enabled) { boot_config->coex_mode = SL_SI91X_WLAN_ONLY_MODE; } else if (bt_enabled) { - boot_config->coex_mode = SL_SI91X_BLE_MODE; + boot_config->coex_mode = SL_SI91X_WLAN_BLE_MODE; } else { /* * Even if neither WiFi or BLE is used we have to specify a Coex mode @@ -436,16 +437,52 @@ int siwx91x_nwp_mode_switch(const struct device *dev, uint8_t oper_mode, bool hi return 0; } +int siwx91x_nwp_apply_power_profile(const struct device *dev) +{ + struct siwx91x_nwp_data *data = dev->data; + sl_wifi_performance_profile_t performance_profile = { + .profile = data->power_profile + }; + sl_bt_performance_profile_t bt_performance_profile = { + .profile = data->power_profile + }; + int ret; + + if (!IS_ENABLED(CONFIG_SOC_SIWX91X_PM_BACKEND_PMGR)) { + /* no_op if PM is not enabled*/ + return 0; + } + + if (IS_ENABLED(CONFIG_BT_SILABS_SIWX91X)) { + ret = sl_si91x_bt_set_performance_profile(&bt_performance_profile); + if (ret) { + LOG_ERR("Failed to initiate power save in BLE mode"); + return -EINVAL; + } + } + + ret = sl_wifi_set_performance_profile(&performance_profile); + if (ret) { + return -EINVAL; + } + + /* Remove the previously added PS4 power state requirement */ + sl_si91x_power_manager_remove_ps_requirement(SL_SI91X_POWER_MANAGER_PS4); + + return 0; +} + static int siwx91x_nwp_init(const struct device *dev) { const struct siwx91x_nwp_config *config = dev->config; - __maybe_unused sl_wifi_performance_profile_t performance_profile = { - .profile = DEEP_SLEEP_WITH_RAM_RETENTION}; - __maybe_unused sl_bt_performance_profile_t bt_performance_profile = { - .profile = DEEP_SLEEP_WITH_RAM_RETENTION}; + struct siwx91x_nwp_data *data = dev->data; sl_wifi_device_configuration_t network_config; int ret; + if (IS_ENABLED(CONFIG_BT_SILABS_SIWX91X) || IS_ENABLED(CONFIG_WIFI_SILABS_SIWX91X)) { + data->power_profile = ASSOCIATED_POWER_SAVE; + } + siwx91x_get_nwp_config(dev, &network_config, WIFI_STA_MODE, false, 0); /* TODO: If sl_net_*_profile() functions will be needed for WiFi then call * sl_net_set_profile() here. Currently these are unused. @@ -470,28 +507,20 @@ static int siwx91x_nwp_init(const struct device *dev) return -EINVAL; } - if (IS_ENABLED(CONFIG_SOC_SIWX91X_PM_BACKEND_PMGR)) { - if (IS_ENABLED(CONFIG_BT_SILABS_SIWX91X)) { - ret = sl_si91x_bt_set_performance_profile(&bt_performance_profile); - if (ret) { - LOG_ERR("Failed to initiate power save in BLE mode"); - return -EINVAL; - } - } - /* - * Note: the WiFi related sources are always imported (because of - * CONFIG_SILABS_SIWX91X_NWP) whatever the value of CONFIG_WIFI. However, - * because of boot_config->coex_mode, sl_wifi_set_performance_profile() is a no-op - * if CONFIG_WIFI=n and CONFIG_BT=y. We could probably remove the dependency to the - * WiFi sources in this case. However, outside of the code size, this dependency - * does not hurt. - */ - ret = sl_wifi_set_performance_profile(&performance_profile); + /* WORKAROUND: + * Only set the power profile if Bluetooth is not enabled. + * + * If bt is enabled, we need to wait for the bt setup to complete + * before setting the power profile. + * + * Because of that, if CONFIG_BT_SILABS_SIWX91X is enabled and + * bt_enable() is not called, you will never go in sleep. + */ + if (!IS_ENABLED(CONFIG_BT_SILABS_SIWX91X)) { + ret = siwx91x_nwp_apply_power_profile(dev); if (ret) { return -EINVAL; } - /* Remove the previously added PS4 power state requirement */ - sl_si91x_power_manager_remove_ps_requirement(SL_SI91X_POWER_MANAGER_PS4); } config->config_irq(dev); @@ -514,7 +543,9 @@ BUILD_ASSERT(CONFIG_SIWX91X_NWP_INIT_PRIORITY < CONFIG_KERNEL_INIT_PRIORITY_DEFA irq_enable(DT_INST_IRQ_BY_NAME(inst, nwp_irq, irq)); \ }; \ \ - static struct siwx91x_nwp_data siwx91x_nwp_data_##inst = {}; \ + static struct siwx91x_nwp_data siwx91x_nwp_data_##inst = { \ + .power_profile = DEEP_SLEEP_WITH_RAM_RETENTION, \ + }; \ \ static const struct siwx91x_nwp_config siwx91x_nwp_config_##inst = { \ .config_irq = silabs_siwx91x_nwp_irq_configure_##inst, \ diff --git a/soc/silabs/silabs_siwx91x/siwg917/siwx91x_nwp.h b/soc/silabs/silabs_siwx91x/siwg917/siwx91x_nwp.h index f18bd8531185..885a56a406b7 100644 --- a/soc/silabs/silabs_siwx91x/siwg917/siwx91x_nwp.h +++ b/soc/silabs/silabs_siwx91x/siwg917/siwx91x_nwp.h @@ -28,6 +28,17 @@ int siwx91x_nwp_mode_switch(const struct device *dev, uint8_t oper_mode, bool hidden_ssid, uint8_t max_num_sta); +/* + * @brief Apply the power profile for the NWP. + * + * This function applies the power profile for the NWP. + * + * @param[in] dev NWP device. + * + * @return 0 on success, negative error code on failure. + */ +int siwx91x_nwp_apply_power_profile(const struct device *dev); + /** * @brief Map an ISO/IEC 3166-1 alpha-2 country code to a Wi-Fi region code. * From 91681f222163d40ef3565aa2b676f60bcb1b566a Mon Sep 17 00:00:00 2001 From: Krisztian Szilvasi Date: Fri, 12 Dec 2025 08:30:17 +0100 Subject: [PATCH 0437/3659] boards: stm32: b_u585i_iot2a: update flash controller's node - Refactor the flash controller's node - Introduce flash device's node under the flash controller's - Introduce `ranges` property with mem-mapped address Signed-off-by: Krisztian Szilvasi --- .../st/b_u585i_iot02a/b_u585i_iot02a-common.dtsi | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) 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 0fcb5f44802f..63dc5e711ec0 100644 --- a/boards/st/b_u585i_iot02a/b_u585i_iot02a-common.dtsi +++ b/boards/st/b_u585i_iot02a/b_u585i_iot02a-common.dtsi @@ -167,7 +167,7 @@ stm32_lp_tick_source: &lptim1 { status = "okay"; - mx25lm51245: ospi-nor-flash@0 { + ext_flash_ctrl: ospi-flash-controller@0 { compatible = "st,stm32-ospi-nor"; reg = <0>; size = ; /* 512 Megabits */ @@ -176,6 +176,18 @@ stm32_lp_tick_source: &lptim1 { data-rate = ; four-byte-opcodes; status = "okay"; + + #address-cells = <1>; + #size-cells = <1>; + + ranges = <0x0 0x70000000 DT_SIZE_M(64)>; /* Ext Flash mem-mapped to 0x70000000 */ + + ext_flash: mx25lm51245: ext-flash@0 { + compatible = "soc-nv-flash"; + reg = <0x0 DT_SIZE_M(64)>; + write-block-size = <1>; + erase-block-size = ; + }; }; }; From e6fd157a93db7297583d7b93f9a74c0e0977bc95 Mon Sep 17 00:00:00 2001 From: Bill Waters Date: Mon, 15 Dec 2025 14:38:32 -0800 Subject: [PATCH 0438/3659] boards: infineon: cy8cproto_041tp: board.cmake The openocd --config paramter is not needed. And it causes an error when used on a ci runner. The path created by scripts/west_commands/runners/openocd.py is wrong. Signed-off-by: Bill Waters --- boards/infineon/cy8cproto_041tp/board.cmake | 3 --- 1 file changed, 3 deletions(-) diff --git a/boards/infineon/cy8cproto_041tp/board.cmake b/boards/infineon/cy8cproto_041tp/board.cmake index 8254533de3f3..85b1fb6ebeae 100644 --- a/boards/infineon/cy8cproto_041tp/board.cmake +++ b/boards/infineon/cy8cproto_041tp/board.cmake @@ -3,8 +3,5 @@ # # SPDX-License-Identifier: Apache-2.0 -# OpenOCD cfg -board_runner_args(openocd "--config=${ZEPHYR_BASE}/boards/infineon/cy8cproto_041tp/support/openocd.cfg") - # Include standard OpenOCD runner helpers include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) From c8c6379b8606adf491adfe46d78734007f3e9975 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fin=20Maa=C3=9F?= Date: Fri, 1 Aug 2025 10:39:26 +0200 Subject: [PATCH 0439/3659] ethernet: stm32: remove phy init and config from HAL_ETH_Init MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit the phy is already configured by the phy driver in zephyr and we don't want to overwrite it in the HAL_ETH_Init function in the stm32 HAL. Signed-off-by: Fin Maaß --- drivers/ethernet/eth_stm32_hal_common.c | 3 --- drivers/ethernet/eth_stm32_hal_priv.h | 3 --- drivers/ethernet/eth_stm32_hal_v1.c | 22 +++------------------- west.yml | 2 +- 4 files changed, 4 insertions(+), 26 deletions(-) diff --git a/drivers/ethernet/eth_stm32_hal_common.c b/drivers/ethernet/eth_stm32_hal_common.c index e30e7fbaf506..728586a47805 100644 --- a/drivers/ethernet/eth_stm32_hal_common.c +++ b/drivers/ethernet/eth_stm32_hal_common.c @@ -429,9 +429,6 @@ static struct eth_stm32_hal_dev_data eth0_data = { .Instance = (ETH_TypeDef *)DT_REG_ADDR(DT_INST_PARENT(0)), .Init = { #if defined(CONFIG_ETH_STM32_HAL_API_V1) - .AutoNegotiation = ETH_STM32_AUTO_NEGOTIATION_ENABLE ? - ETH_AUTONEGOTIATION_ENABLE : ETH_AUTONEGOTIATION_DISABLE, - .PhyAddress = DT_REG_ADDR(DT_INST_PHANDLE(0, phy_handle)), .RxMode = ETH_RXINTERRUPT_MODE, .ChecksumMode = IS_ENABLED(CONFIG_ETH_STM32_HW_CHECKSUM) ? ETH_CHECKSUM_BY_HARDWARE : ETH_CHECKSUM_BY_SOFTWARE, diff --git a/drivers/ethernet/eth_stm32_hal_priv.h b/drivers/ethernet/eth_stm32_hal_priv.h index 5d590be1714b..879fb35362e9 100644 --- a/drivers/ethernet/eth_stm32_hal_priv.h +++ b/drivers/ethernet/eth_stm32_hal_priv.h @@ -55,9 +55,6 @@ extern const struct device *eth_stm32_phy_dev; #define ETH_MII_MODE ETH_MEDIA_INTERFACE_MII #define ETH_RMII_MODE ETH_MEDIA_INTERFACE_RMII -#define ETH_STM32_AUTO_NEGOTIATION_ENABLE \ - UTIL_NOT(DT_NODE_HAS_PROP(DT_INST_PHANDLE(0, phy_handle), fixed_link)) - #else /* CONFIG_ETH_STM32_HAL_API_V2 */ #define ETH_MII_MODE HAL_ETH_MII_MODE diff --git a/drivers/ethernet/eth_stm32_hal_v1.c b/drivers/ethernet/eth_stm32_hal_v1.c index e9e56fefd7b2..be2ad3d32d02 100644 --- a/drivers/ethernet/eth_stm32_hal_v1.c +++ b/drivers/ethernet/eth_stm32_hal_v1.c @@ -188,28 +188,12 @@ int eth_stm32_hal_init(const struct device *dev) { struct eth_stm32_hal_dev_data *dev_data = dev->data; ETH_HandleTypeDef *heth = &dev_data->heth; - HAL_StatusTypeDef hal_ret = HAL_OK; - - if (!ETH_STM32_AUTO_NEGOTIATION_ENABLE) { - struct phy_link_state state; - - phy_get_link_state(eth_stm32_phy_dev, &state); - - heth->Init.DuplexMode = PHY_LINK_IS_FULL_DUPLEX(state.speed) ? ETH_MODE_FULLDUPLEX - : ETH_MODE_HALFDUPLEX; - heth->Init.Speed = - PHY_LINK_IS_SPEED_100M(state.speed) ? ETH_SPEED_100M : ETH_SPEED_10M; - } + HAL_StatusTypeDef hal_ret; hal_ret = HAL_ETH_Init(heth); - if (hal_ret == HAL_TIMEOUT) { - /* HAL Init time out. This could be linked to */ - /* a recoverable error. Log the issue and continue */ - /* driver initialisation */ - LOG_WRN("HAL_ETH_Init timed out (cable not connected?)"); - } else if (hal_ret != HAL_OK) { + if (hal_ret != HAL_OK) { LOG_ERR("HAL_ETH_Init failed: %d", hal_ret); - return -EINVAL; + return -EIO; } /* Initialize semaphores */ diff --git a/west.yml b/west.yml index 87c7e076d9ef..70e177a9086e 100644 --- a/west.yml +++ b/west.yml @@ -255,7 +255,7 @@ manifest: groups: - hal - name: hal_stm32 - revision: 2c18f2b49d66d23cabfbd20dd7dbbaef8ee9520b + revision: 9d05ebdff47b5071fa092de243a1244e7c27f518 path: modules/hal/stm32 groups: - hal From 511e10ca7deb1b78fd0326f32827caea58c5c0a5 Mon Sep 17 00:00:00 2001 From: Chun-Chieh Li Date: Fri, 15 Aug 2025 09:59:02 +0800 Subject: [PATCH 0440/3659] drivers: usb: udc: numaker: usbd: enable usb wake-up early Same as VBUS detect, this enables USB wake-up early so that device can also be woken up by VBUS. Signed-off-by: Chun-Chieh Li --- drivers/usb/udc/udc_numaker.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/usb/udc/udc_numaker.c b/drivers/usb/udc/udc_numaker.c index e14640219cf4..fb62c70982ad 100644 --- a/drivers/usb/udc/udc_numaker.c +++ b/drivers/usb/udc/udc_numaker.c @@ -1683,8 +1683,13 @@ static int udc_numaker_init(const struct device *dev) /* Enable VBUS detect early */ if (data->caps.can_detect_vbus) { base->INTEN = USBD_INT_FLDET; + } else { + base->INTEN = 0; } + /* Enable USB wake-up early */ + base->INTEN |= USBD_INT_WAKEUP; + return 0; } From 3191254b6c8af09c8e85dc398d032f99e08ba287 Mon Sep 17 00:00:00 2001 From: Chun-Chieh Li Date: Mon, 4 Aug 2025 18:07:23 +0800 Subject: [PATCH 0441/3659] drivers: usb: udc: numaker: usbd: refine MXPLD read For USBD, this refines MXPLD read to avoid unwanted or reserved bits. Signed-off-by: Chun-Chieh Li --- drivers/usb/udc/udc_numaker.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/usb/udc/udc_numaker.c b/drivers/usb/udc/udc_numaker.c index fb62c70982ad..c3a7bea854a4 100644 --- a/drivers/usb/udc/udc_numaker.c +++ b/drivers/usb/udc/udc_numaker.c @@ -572,7 +572,8 @@ static void numaker_usbd_ep_th(const struct device *dev, uint32_t ep_hw_idx) if (ep == USB_EP_GET_ADDR(0, USB_EP_DIR_OUT)) { struct numaker_usbd_ep *ep_ctrlout = priv->ep_pool + 0; - ep_ctrlout->mxpld_ctrlout = ep_base->MXPLD; + ep_ctrlout->mxpld_ctrlout = (ep_base->MXPLD & USBD_MXPLD_MXPLD_Msk) >> + USBD_MXPLD_MXPLD_Pos; } /* Message for bottom-half processing */ @@ -628,7 +629,7 @@ static void numaker_usbd_ep_copy_to_user(struct numaker_usbd_ep *ep_cur, uint8_t if (ep_cur->addr == USB_CONTROL_EP_OUT) { data_rmn = ep_cur->mxpld_ctrlout; } else { - data_rmn = ep_base->MXPLD; + data_rmn = (ep_base->MXPLD & USBD_MXPLD_MXPLD_Msk) >> USBD_MXPLD_MXPLD_Pos; } *size_p = MIN(*size_p, data_rmn); From 1ae35d3acf6ba7669c9e81f0a54404eaf760f636 Mon Sep 17 00:00:00 2001 From: Chun-Chieh Li Date: Mon, 1 Sep 2025 10:51:40 +0800 Subject: [PATCH 0442/3659] drivers: usb: udc: numaker: usbd: refine on ATTR undefined bits Refine code on ATTR undefined bits: - Add USBD_ATTR_PWRDN_Msk if it is not defined - Following BSP USBD driver, add note on BIT(6) for hidden Signed-off-by: Chun-Chieh Li --- drivers/usb/udc/udc_numaker.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/usb/udc/udc_numaker.c b/drivers/usb/udc/udc_numaker.c index c3a7bea854a4..c22f06794a37 100644 --- a/drivers/usb/udc/udc_numaker.c +++ b/drivers/usb/udc/udc_numaker.c @@ -42,6 +42,10 @@ LOG_MODULE_REGISTER(udc_numaker, CONFIG_UDC_DRIVER_LOG_LEVEL); #define NUMAKER_USBD_DMABUF_SIZE_CTRLOUT 64 #define NUMAKER_USBD_DMABUF_SIZE_CTRLIN 64 +#if !defined(USBD_ATTR_PWRDN_Msk) +#define USBD_ATTR_PWRDN_Msk BIT(9) +#endif + enum numaker_usbd_msg_type { /* Setup packet received */ NUMAKER_USBD_MSG_TYPE_SETUP, @@ -345,8 +349,8 @@ static int numaker_usbd_hw_setup(const struct device *dev) reset_line_toggle_dt(&config->reset); /* Initialize USBD engine */ - /* NOTE: BSP USBD driver: ATTR = 0x7D0 */ - base->ATTR = USBD_ATTR_BYTEM_Msk | BIT(9) | USBD_ATTR_USBEN_Msk | BIT(6) | + /* NOTE: Per USBD spec, BIT(6) is hidden. */ + base->ATTR = USBD_ATTR_BYTEM_Msk | USBD_ATTR_PWRDN_Msk | USBD_ATTR_USBEN_Msk | BIT(6) | USBD_ATTR_PHYEN_Msk; /* Set SE0 for S/W disconnect */ From a9338eb8271224409d57fc73a0205e626790fc6c Mon Sep 17 00:00:00 2001 From: Chun-Chieh Li Date: Mon, 4 Aug 2025 18:07:23 +0800 Subject: [PATCH 0443/3659] drivers: usb: udc: numaker: report instead of assert in control transfer On Control Out failure, this changes to report error message instead of assert failure because USB bus error is allowed to happen. Signed-off-by: Chun-Chieh Li --- drivers/usb/udc/udc_numaker.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/usb/udc/udc_numaker.c b/drivers/usb/udc/udc_numaker.c index c22f06794a37..517a5170be4b 100644 --- a/drivers/usb/udc/udc_numaker.c +++ b/drivers/usb/udc/udc_numaker.c @@ -1158,8 +1158,7 @@ static int numaker_usbd_msg_handle_out(const struct device *dev, struct numaker_ } if (ep == USB_CONTROL_EP_OUT) { - __ASSERT_NO_MSG(net_buf_tailroom(buf) >= priv->ctrlout_tailroom); - data_len = priv->ctrlout_tailroom; + data_len = MIN(net_buf_tailroom(buf), priv->ctrlout_tailroom); } else { data_len = net_buf_tailroom(buf); } @@ -1172,7 +1171,9 @@ static int numaker_usbd_msg_handle_out(const struct device *dev, struct numaker_ } if (data_rmn) { - LOG_ERR("Buffer queued for ep=0x%02x cannot accommodate packet", ep); + LOG_ERR("Buffer (%p) queued for ep=0x%02x cannot accommodate packet", buf, ep); + LOG_ERR("net_buf_tailroom(buf)=%d, data_len=%d, data_rmn=%d", net_buf_tailroom(buf), + data_len, data_rmn); return -ENOBUFS; } From 80df5b5eced9e96b089e1af0dd28c30996636648 Mon Sep 17 00:00:00 2001 From: Chun-Chieh Li Date: Wed, 6 Aug 2025 11:10:25 +0800 Subject: [PATCH 0444/3659] drivers: usb: udc: numaker: recover from incomplete control transfer Previous control transfer can be incomplete and then causes not only net_buf leak but also logic error. This recycles dangling net_buf for new clean control transfer. Signed-off-by: Chun-Chieh Li --- drivers/usb/udc/udc_numaker.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/drivers/usb/udc/udc_numaker.c b/drivers/usb/udc/udc_numaker.c index 517a5170be4b..ffc492133d5a 100644 --- a/drivers/usb/udc/udc_numaker.c +++ b/drivers/usb/udc/udc_numaker.c @@ -1069,11 +1069,29 @@ static int numaker_usbd_msg_handle_setup(const struct device *dev, struct numake int err; uint8_t ep; struct numaker_usbd_ep *ep_cur; + struct udc_ep_config *ep_cfg; struct net_buf *buf; uint8_t *data_ptr; __ASSERT_NO_MSG(msg->type == NUMAKER_USBD_MSG_TYPE_SETUP); + /* Recover from incomplete Control transfer + * + * Previous Control transfer can be incomplete, and causes not + * only net_buf leak but also logic error. This recycles dangling + * net_buf for new clean Control transfer. + */ + ep_cfg = udc_get_ep_cfg(dev, USB_CONTROL_EP_OUT); + buf = udc_buf_get_all(ep_cfg); + if (buf != NULL) { + net_buf_unref(buf); + } + ep_cfg = udc_get_ep_cfg(dev, USB_CONTROL_EP_IN); + buf = udc_buf_get_all(ep_cfg); + if (buf != NULL) { + net_buf_unref(buf); + } + ep = USB_CONTROL_EP_OUT; /* Bind EP H/W context to EP address */ From e64e113700fde46a7e5dcd8f940a9a6948dac403 Mon Sep 17 00:00:00 2001 From: Chun-Chieh Li Date: Fri, 22 Aug 2025 14:26:22 +0800 Subject: [PATCH 0445/3659] drivers: usb: udc: numaker: support NuMaker M46X HSUSBD Add support for Nuvoton NuMaker M46X high-speed USB 2.0 device controller. The code is re-organized to implement both usbd and hsusbd in single source file. Multiple instances of either usbd or hsusbd are supported, but usbd and hsusbd cannot support simultaneously. This limitation is for easy implementation with just single source file, assuming that real application just needs one usb device type. Signed-off-by: Chun-Chieh Li --- drivers/usb/udc/Kconfig.numaker | 8 +- drivers/usb/udc/udc_numaker.c | 1120 ++++++++++++++++-- dts/arm/nuvoton/m46x.dtsi | 13 + dts/bindings/usb/nuvoton,numaker-hsusbd.yaml | 27 + 4 files changed, 1071 insertions(+), 97 deletions(-) create mode 100644 dts/bindings/usb/nuvoton,numaker-hsusbd.yaml diff --git a/drivers/usb/udc/Kconfig.numaker b/drivers/usb/udc/Kconfig.numaker index bb2c27503046..64de929cf4fc 100644 --- a/drivers/usb/udc/Kconfig.numaker +++ b/drivers/usb/udc/Kconfig.numaker @@ -2,12 +2,14 @@ # SPDX-License-Identifier: Apache-2.0 config UDC_NUMAKER - bool "Nuvoton NuMaker USB 1.1 device controller" + bool "Nuvoton NuMaker USB device controller" default y - depends on DT_HAS_NUVOTON_NUMAKER_USBD_ENABLED + depends on DT_HAS_NUVOTON_NUMAKER_USBD_ENABLED \ + || DT_HAS_NUVOTON_NUMAKER_HSUSBD_ENABLED select PINCTRL + select UDC_DRIVER_HAS_HIGH_SPEED_SUPPORT if DT_HAS_NUVOTON_NUMAKER_HSUSBD_ENABLED help - Enable Nuvoton NuMaker USB 1.1 device controller driver + Enable Nuvoton NuMaker USB device controller driver if UDC_NUMAKER diff --git a/drivers/usb/udc/udc_numaker.c b/drivers/usb/udc/udc_numaker.c index ffc492133d5a..0ae73f6a082d 100644 --- a/drivers/usb/udc/udc_numaker.c +++ b/drivers/usb/udc/udc_numaker.c @@ -4,8 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#define DT_DRV_COMPAT nuvoton_numaker_usbd - #include #include #include @@ -31,6 +29,24 @@ LOG_MODULE_REGISTER(udc_numaker, CONFIG_UDC_DRIVER_LOG_LEVEL); * to generate necessary 48MHz. */ +/* Not support USBD/HSUSBD simultaneously + * + * The code is re-organized to implement both usbd and hsusbd in single + * source file. Multiple instances of either usbd or hsusbd are supported, + * but usbd and hsusbd cannot support simultaneously. This limitation is + * for easy implementation with just single source file, assuming that real + * application just needs one usb device type. + */ +BUILD_ASSERT(!(DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) && + DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd)), + "NOT SUPPORT USBD/HSUSBD simultaneously"); + +#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) +#define DT_DRV_COMPAT nuvoton_numaker_usbd +#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) +#define DT_DRV_COMPAT nuvoton_numaker_hsusbd +#endif + /* For bus reset, keep 'SE0' (USB spec: SE0 >= 2.5 ms) */ #define NUMAKER_USBD_BUS_RESET_DRV_SE0_US 3000 @@ -42,11 +58,42 @@ LOG_MODULE_REGISTER(udc_numaker, CONFIG_UDC_DRIVER_LOG_LEVEL); #define NUMAKER_USBD_DMABUF_SIZE_CTRLOUT 64 #define NUMAKER_USBD_DMABUF_SIZE_CTRLIN 64 +#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) + +#define NUMAKER_USBD_SPEED_IDX_DEFAULT 1 + +/* USBD controller does not support DMA, and PHY does not require a delay after reset. */ + #if !defined(USBD_ATTR_PWRDN_Msk) #define USBD_ATTR_PWRDN_Msk BIT(9) #endif +#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) + +#define NUMAKER_USBD_SPEED_IDX_DEFAULT 2 + +/* Redefine to reuse code for HSUSBD */ +#define USBD_T HSUSBD_T +#define USBD_EP_T HSUSBD_EP_T + +/* Per HSUSBD H/W spec, after setting HSUSBEN to enable HSUSB/PHY, user + * should keep HSUSB/PHY at reset mode at lease 10us before changing to + * active mode. + */ +#define NUMAKER_HSUSBD_PHY_RESET_US 10 + +/* Wait for USB/PHY stable timeout 100 ms */ +#define NUMAKER_HSUSBD_PHY_STABLE_TIMEOUT_US 100000 + +#endif + enum numaker_usbd_msg_type { + /* Device plug-in */ + NUMAKER_USBD_MSG_TYPE_ATTACH, + /* Bus reset */ + NUMAKER_USBD_MSG_TYPE_RESET, + /* Bus resume */ + NUMAKER_USBD_MSG_TYPE_RESUME, /* Setup packet received */ NUMAKER_USBD_MSG_TYPE_SETUP, /* OUT transaction for specific EP completed */ @@ -86,19 +133,24 @@ struct numaker_usbd_ep { const struct device *dev; /* Pointer to the containing device */ - uint8_t ep_hw_idx; /* BSP USBD driver EP index EP0, EP1, EP2, etc */ - uint32_t ep_hw_cfg; /* BSP USBD driver EP configuration */ + int32_t ep_hw_idx; /* BSP USBD/HSUSBD driver EP index, e.g. EP0/EPA, EP1/EPB, etc. */ + uint32_t ep_hw_cfg; /* BSP USBD/HSUSBD driver EP configuration */ +#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) + uint32_t ep_hw_rspctl; +#endif /* EP DMA buffer */ bool dmabuf_valid; uint32_t dmabuf_base; uint32_t dmabuf_size; +#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) /* NOTE: On USBD, Setup and CTRL OUT are not completely separated. CTRL OUT MXPLD * can be overridden to 8 by next Setup. To overcome it, we make one copy of CTRL * OUT MXPLD immediately on its interrupt. */ uint32_t mxpld_ctrlout; +#endif /* EP address */ bool addr_valid; @@ -126,6 +178,7 @@ struct udc_numaker_config { const struct pinctrl_dev_config *pincfg; uint32_t dmabuf_size; bool disallow_iso_inout_same; + int speed_idx; void (*make_thread)(const struct device *dev); }; @@ -169,8 +222,9 @@ struct udc_numaker_data { static inline void numaker_usbd_sw_connect(const struct device *dev) { const struct udc_numaker_config *config = dev->config; - USBD_T *const base = config->base; + USBD_T *base = config->base; +#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) /* Clear all interrupts first for clean */ base->INTSTS = base->INTSTS; @@ -182,15 +236,37 @@ static inline void numaker_usbd_sw_connect(const struct device *dev) /* Clear SE0 for connect */ base->ATTR |= USBD_ATTR_DPPUEN_Msk; base->SE0 &= ~USBD_DRVSE0; +#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) + /* Clear all interrupts first for clean */ + base->BUSINTSTS = base->BUSINTSTS; + base->CEPINTSTS = base->CEPINTSTS; + + /* Enable relevant interrupts */ + base->GINTEN = HSUSBD_GINTEN_CEPIEN_Msk | HSUSBD_GINTEN_USBIEN_Msk; + base->BUSINTEN = HSUSBD_BUSINTEN_VBUSDETIEN_Msk | HSUSBD_BUSINTEN_SUSPENDIEN_Msk | + HSUSBD_BUSINTEN_RESUMEIEN_Msk | HSUSBD_BUSINTEN_RSTIEN_Msk | + COND_CODE_1(CONFIG_UDC_ENABLE_SOF, (HSUSBD_BUSINTEN_SOFIEN_Msk), + (0)); /* CPU load concern */ + base->CEPINTEN = HSUSBD_CEPINTEN_STSDONEIEN_Msk | HSUSBD_CEPINTEN_ERRIEN_Msk | + HSUSBD_CEPINTEN_STALLIEN_Msk | HSUSBD_CEPINTEN_SETUPPKIEN_Msk | + HSUSBD_CEPINTEN_SETUPTKIEN_Msk; + + /* Clear SE0 for connect */ + base->PHYCTL |= HSUSBD_PHYCTL_DPPUEN_Msk; +#endif } static inline void numaker_usbd_sw_disconnect(const struct device *dev) { const struct udc_numaker_config *config = dev->config; - USBD_T *const base = config->base; + USBD_T *base = config->base; /* Set SE0 for disconnect */ +#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) base->SE0 |= USBD_DRVSE0; +#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) + base->PHYCTL &= ~HSUSBD_PHYCTL_DPPUEN_Msk; +#endif } static inline void numaker_usbd_sw_reconnect(const struct device *dev) @@ -205,7 +281,7 @@ static inline void numaker_usbd_reset_addr(const struct device *dev) { const struct udc_numaker_config *config = dev->config; struct udc_numaker_data *priv = udc_get_private(dev); - USBD_T *const base = config->base; + USBD_T *base = config->base; base->FADDR = 0; priv->addr = 0; @@ -215,20 +291,24 @@ static inline void numaker_usbd_set_addr(const struct device *dev) { const struct udc_numaker_config *config = dev->config; struct udc_numaker_data *priv = udc_get_private(dev); - USBD_T *const base = config->base; + USBD_T *base = config->base; if (base->FADDR != priv->addr) { base->FADDR = priv->addr; } } -/* USBD EP base by e.g. EP0, EP1, ... */ +/* USBD/HSUSBD EP base by EP index e.g. EP0/EPA, EP1/EPB, etc. */ static inline USBD_EP_T *numaker_usbd_ep_base(const struct device *dev, uint32_t ep_hw_idx) { const struct udc_numaker_config *config = dev->config; - USBD_T *const base = config->base; + USBD_T *base = config->base; - return base->EP + ep_hw_idx; +#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) + return base->EP + (ep_hw_idx - EP0); +#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) + return (ep_hw_idx == CEP) ? NULL : base->EP + (ep_hw_idx - EPA); +#endif } static inline void numaker_usbd_ep_sync_udc_halt(struct numaker_usbd_ep *ep_cur, bool stalled) @@ -244,25 +324,55 @@ static inline void numaker_usbd_ep_sync_udc_halt(struct numaker_usbd_ep *ep_cur, static inline void numaker_usbd_ep_set_stall(struct numaker_usbd_ep *ep_cur) { const struct device *dev = ep_cur->dev; + const struct udc_numaker_config *config = dev->config; + __maybe_unused USBD_T *base = config->base; USBD_EP_T *ep_base = numaker_usbd_ep_base(dev, ep_cur->ep_hw_idx); /* Set EP to stalled */ +#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) ep_base->CFGP |= USBD_CFGP_SSTALL_Msk; numaker_usbd_ep_sync_udc_halt(ep_cur, true); +#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) + if (ep_cur->ep_hw_idx == CEP) { + base->CEPCTL = HSUSBD_CEPCTL_STALL; + } else { + uint32_t eprspctl = ep_base->EPRSPCTL; + + eprspctl &= ~(HSUSBD_EPRSPCTL_HALT_Msk | HSUSBD_EPRSPCTL_TOGGLE_Msk); + eprspctl |= HSUSBD_EP_RSPCTL_HALT; + ep_base->EPRSPCTL = eprspctl; + } +#endif } /* Reset EP to unstalled and data toggle bit to 0 */ static inline void numaker_usbd_ep_clear_stall_n_data_toggle(struct numaker_usbd_ep *ep_cur) { const struct device *dev = ep_cur->dev; + const struct udc_numaker_config *config = dev->config; + __maybe_unused USBD_T *base = config->base; USBD_EP_T *ep_base = numaker_usbd_ep_base(dev, ep_cur->ep_hw_idx); +#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) /* Reset EP to unstalled */ ep_base->CFGP &= ~USBD_CFGP_SSTALL_Msk; numaker_usbd_ep_sync_udc_halt(ep_cur, false); /* Reset EP data toggle bit to 0 */ ep_base->CFG &= ~USBD_CFG_DSQSYNC_Msk; +#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) + if (ep_cur->ep_hw_idx == CEP) { + /* Reset EP to unstalled and H/W will care toggle bit reset */ + base->CEPCTL = 0; + } else { + /* Reset EP to unstalled and its data toggle bit to 0 */ + uint32_t eprspctl = ep_base->EPRSPCTL; + + eprspctl &= ~(HSUSBD_EPRSPCTL_HALT_Msk | HSUSBD_EPRSPCTL_TOGGLE_Msk); + eprspctl |= HSUSBD_EP_RSPCTL_TOGGLE; + ep_base->EPRSPCTL = eprspctl; + } +#endif } static int numaker_usbd_send_msg(const struct device *dev, const struct numaker_usbd_msg *msg) @@ -291,10 +401,29 @@ static int numaker_usbd_send_msg(const struct device *dev, const struct numaker_ return err; } +static int numaker_usbd_enable_usb_phy(const struct device *dev) +{ + const struct udc_numaker_config *config = dev->config; + USBD_T *base = config->base; + +#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) + base->ATTR |= USBD_ATTR_USBEN_Msk | USBD_ATTR_PHYEN_Msk; +#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) + base->PHYCTL |= HSUSBD_PHYCTL_PHYEN_Msk; + WAIT_FOR(base->PHYCTL & HSUSBD_PHYCTL_PHYCLKSTB_Msk, + NUMAKER_HSUSBD_PHY_STABLE_TIMEOUT_US, ;); + if (!(base->PHYCTL & HSUSBD_PHYCTL_PHYCLKSTB_Msk)) { + return -EIO; + } +#endif + + return 0; +} + static int numaker_usbd_hw_setup(const struct device *dev) { const struct udc_numaker_config *config = dev->config; - USBD_T *const base = config->base; + USBD_T *base = config->base; int err; struct numaker_scc_subsys scc_subsys; @@ -306,7 +435,8 @@ static int numaker_usbd_hw_setup(const struct device *dev) SYS_UnlockReg(); - /* Configure USB role as USB Device and enable USB PHY */ + /* Configure USB role as USB Device and enable USB/PHY */ +#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) #if defined(CONFIG_SOC_SERIES_M46X) SYS->USBPHY = (SYS->USBPHY & ~SYS_USBPHY_USBROLE_Msk) | (SYS_USBPHY_USBROLE_STD_USBD | SYS_USBPHY_USBEN_Msk | SYS_USBPHY_SBO_Msk); @@ -317,6 +447,13 @@ static int numaker_usbd_hw_setup(const struct device *dev) SYS->USBPHY = (SYS->USBPHY & ~SYS_USBPHY_USBROLE_Msk) | ((0 << SYS_USBPHY_USBROLE_Pos) | SYS_USBPHY_OTGPHYEN_Msk); #endif +#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) + /* Configure HSUSB role as USB Device and enable HSUSB/PHY */ + SYS->USBPHY = (SYS->USBPHY & ~(SYS_USBPHY_HSUSBROLE_Msk | SYS_USBPHY_HSUSBACT_Msk)) | + (SYS_USBPHY_HSUSBROLE_STD_USBD | SYS_USBPHY_HSUSBEN_Msk | SYS_USBPHY_SBO_Msk); + k_sleep(K_USEC(NUMAKER_HSUSBD_PHY_RESET_US)); + SYS->USBPHY |= SYS_USBPHY_HSUSBACT_Msk; +#endif /* Invoke Clock controller to enable module clock */ memset(&scc_subsys, 0x00, sizeof(scc_subsys)); @@ -337,10 +474,16 @@ static int numaker_usbd_hw_setup(const struct device *dev) goto cleanup; } - /* Configure pinmux (NuMaker's SYS MFP) */ - err = pinctrl_apply_state(config->pincfg, PINCTRL_STATE_DEFAULT); - if (err < 0) { - goto cleanup; + /* Configure pinmux (NuMaker's SYS MFP) + * + * NOTE: Take care of the case, e.g. M460 high-speed USB 2.0 device + * controller, whose pinouts are dedicated and needn't pinmux. + */ + if (config->pincfg) { + err = pinctrl_apply_state(config->pincfg, PINCTRL_STATE_DEFAULT); + if (err < 0) { + goto cleanup; + } } /* Invoke Reset controller to reset module to default state */ @@ -348,15 +491,41 @@ static int numaker_usbd_hw_setup(const struct device *dev) */ reset_line_toggle_dt(&config->reset); +#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) /* Initialize USBD engine */ /* NOTE: Per USBD spec, BIT(6) is hidden. */ - base->ATTR = USBD_ATTR_BYTEM_Msk | USBD_ATTR_PWRDN_Msk | USBD_ATTR_USBEN_Msk | BIT(6) | - USBD_ATTR_PHYEN_Msk; + base->ATTR = USBD_ATTR_BYTEM_Msk | USBD_ATTR_PWRDN_Msk | BIT(6); +#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) + base->PHYCTL = 0; +#endif + err = numaker_usbd_enable_usb_phy(dev); + if (err < 0) { + LOG_ERR("Enable USB/PHY failed"); + goto cleanup; + } /* Set SE0 for S/W disconnect */ numaker_usbd_sw_disconnect(dev); +#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) /* NOTE: Ignore DT maximum-speed with USBD fixed to full-speed */ +#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) + /* Initiate high-speed negotiation (chirp during reset) */ +#if defined(CONFIG_UDC_DRIVER_HIGH_SPEED_SUPPORT_ENABLED) + switch (config->speed_idx) { + case 0: + case 1: + base->OPER &= ~HSUSBD_OPER_HISPDEN_Msk; + break; + case 2: + case 3: + default: + base->OPER |= HSUSBD_OPER_HISPDEN_Msk; + } +#else + base->OPER &= ~HSUSBD_OPER_HISPDEN_Msk; +#endif +#endif /* Initialize IRQ */ config->irq_config_func(dev); @@ -371,7 +540,7 @@ static int numaker_usbd_hw_setup(const struct device *dev) static void numaker_usbd_hw_shutdown(const struct device *dev) { const struct udc_numaker_config *config = dev->config; - USBD_T *const base = config->base; + USBD_T *base = config->base; struct numaker_scc_subsys scc_subsys; SYS_UnlockReg(); @@ -382,8 +551,12 @@ static void numaker_usbd_hw_shutdown(const struct device *dev) /* Set SE0 for S/W disconnect */ numaker_usbd_sw_disconnect(dev); - /* Disable USB PHY */ + /* Disable USB/PHY */ +#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) base->ATTR &= ~USBD_PHY_EN; +#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) + base->PHYCTL &= ~HSUSBD_PHYCTL_PHYEN_Msk; +#endif /* Invoke Clock controller to disable module clock */ memset(&scc_subsys, 0x00, sizeof(scc_subsys)); @@ -404,13 +577,19 @@ static void numaker_usbd_hw_shutdown(const struct device *dev) static void numaker_usbd_vbus_plug_th(const struct device *dev) { const struct udc_numaker_config *config = dev->config; - USBD_T *base = config->base; + __maybe_unused USBD_T *base = config->base; + struct numaker_usbd_msg msg = {0}; +#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) /* Enable back USB/PHY */ base->ATTR |= USBD_ATTR_USBEN_Msk | USBD_ATTR_PHYEN_Msk; +#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) + /* For HSUSBD, enable back USB/PHY will be done in bottom-half for needed wait. */ +#endif - /* UDC stack would handle bottom-half processing */ - udc_submit_event(dev, UDC_EVT_VBUS_READY, 0); + /* Message for bottom-half processing */ + msg.type = NUMAKER_USBD_MSG_TYPE_ATTACH; + numaker_usbd_send_msg(dev, &msg); LOG_DBG("USB plug-in"); } @@ -421,8 +600,13 @@ static void numaker_usbd_vbus_unplug_th(const struct device *dev) const struct udc_numaker_config *config = dev->config; USBD_T *base = config->base; +#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) /* Disable USB */ base->ATTR &= ~USBD_USB_EN; +#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) + /* Disable USB/PHY */ + base->PHYCTL &= ~HSUSBD_PHYCTL_PHYEN_Msk; +#endif /* UDC stack would handle bottom-half processing */ udc_submit_event(dev, UDC_EVT_VBUS_REMOVED, 0); @@ -430,11 +614,13 @@ static void numaker_usbd_vbus_unplug_th(const struct device *dev) LOG_DBG("USB unplug"); } +#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) /* Interrupt top half processing for bus wakeup */ static void numaker_usbd_bus_wakeup_th(const struct device *dev) { LOG_DBG("USB wake-up"); } +#endif /* Interrupt top half processing for bus reset */ static void numaker_usbd_bus_reset_th(const struct device *dev) @@ -442,13 +628,23 @@ static void numaker_usbd_bus_reset_th(const struct device *dev) const struct udc_numaker_config *config = dev->config; USBD_T *base = config->base; struct udc_numaker_data *priv = udc_get_private(dev); + struct numaker_usbd_ep *ep_cur = priv->ep_pool; + struct numaker_usbd_ep *ep_end = priv->ep_pool + priv->ep_pool_size; USBD_EP_T *ep_base; + struct numaker_usbd_msg msg = {0}; +#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) /* Enable back USB/PHY */ base->ATTR |= USBD_ATTR_USBEN_Msk | USBD_ATTR_PHYEN_Msk; +#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) + /* For HSUSBD, enable back USB/PHY will be done in bottom-half for needed wait. */ +#endif - for (uint32_t i = 0ul; i < priv->ep_pool_size; i++) { - ep_base = numaker_usbd_ep_base(dev, EP0 + i); + for (; ep_cur != ep_end; ep_cur++) { + ep_base = numaker_usbd_ep_base(dev, ep_cur->ep_hw_idx); + +#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) + /* For USBD, no separate EP interrupt control */ /* Cancel EP on-going transaction */ ep_base->CFGP |= USBD_CFGP_CLRRDY_Msk; @@ -460,18 +656,46 @@ static void numaker_usbd_bus_reset_th(const struct device *dev) ep_base->CFG &= ~USBD_CFG_DSQSYNC_Msk; /* Except EP0/EP1 kept resident for CTRL OUT/IN, disable all other EPs */ - if (i >= 2) { + if (ep_cur->ep_hw_idx >= (EP0 + 2)) { ep_base->CFG = 0; } +#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) + if (ep_cur->ep_hw_idx == CEP) { + /* Disable CEP interrupt (exclude Setup) */ + base->CEPINTEN &= ~(HSUSBD_CEPINTEN_TXPKIEN_Msk | + HSUSBD_CEPINTEN_RXPKIEN_Msk); + + /* Flush CEP FIFO */ + base->CEPCTL = HSUSBD_CEPCTL_FLUSH | HSUSBD_CEPCTL_NAKCLR_Msk; + + /* CEP is resident and doesn't get disabled */ + } else { + uint32_t eprspctl = ep_base->EPRSPCTL; + + /* Disable EP interrupt */ + ep_base->EPINTEN &= ~(HSUSBD_EPINTEN_TXPKIEN_Msk | + HSUSBD_EPINTEN_RXPKIEN_Msk); + + /* Flush EP FIFO */ + eprspctl |= HSUSBD_EP_RSPCTL_FLUSH; + + /* Reset EP to unstalled and its toggle bit to 0 */ + eprspctl &= ~(HSUSBD_EPRSPCTL_HALT_Msk | HSUSBD_EPRSPCTL_TOGGLE_Msk); + eprspctl |= HSUSBD_EP_RSPCTL_TOGGLE; + + ep_base->EPRSPCTL = eprspctl; + + /* Disable all non-CTRL EPs */ + ep_base->EPCFG &= ~HSUSBD_EPCFG_EPEN_Msk; + } +#endif } numaker_usbd_reset_addr(dev); - /* UDC stack would handle bottom-half processing, - * including reset device address (udc_set_address), - * un-configure device (udc_ep_disable), etc. - */ - udc_submit_event(dev, UDC_EVT_RESET, 0); + /* Message for bottom-half processing */ + msg.type = NUMAKER_USBD_MSG_TYPE_RESET; + numaker_usbd_send_msg(dev, &msg); LOG_DBG("USB reset"); } @@ -480,10 +704,18 @@ static void numaker_usbd_bus_reset_th(const struct device *dev) static void numaker_usbd_bus_suspend_th(const struct device *dev) { const struct udc_numaker_config *config = dev->config; - USBD_T *base = config->base; + __maybe_unused USBD_T *base = config->base; +#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) /* Enable USB but disable PHY */ base->ATTR &= ~USBD_PHY_EN; +#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) + /* NOT disable USB/PHY + * + * For HSUSBD, unlike USBD, bus events (Reset/Suspend/Resume) + * will get unrecognized after USB/PHY is disabled. + */ +#endif /* UDC stack would handle bottom-half processing */ udc_submit_event(dev, UDC_EVT_SUSPEND, 0); @@ -495,13 +727,19 @@ static void numaker_usbd_bus_suspend_th(const struct device *dev) static void numaker_usbd_bus_resume_th(const struct device *dev) { const struct udc_numaker_config *config = dev->config; - USBD_T *base = config->base; + __maybe_unused USBD_T *base = config->base; + struct numaker_usbd_msg msg = {0}; +#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) /* Enable back USB/PHY */ base->ATTR |= USBD_ATTR_USBEN_Msk | USBD_ATTR_PHYEN_Msk; +#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) + /* For HSUSBD, enable back USB/PHY will be done in bottom-half for needed wait. */ +#endif - /* UDC stack would handle bottom-half processing */ - udc_submit_event(dev, UDC_EVT_RESUME, 0); + /* Message for bottom-half processing */ + msg.type = NUMAKER_USBD_MSG_TYPE_RESUME; + numaker_usbd_send_msg(dev, &msg); LOG_DBG("USB resume"); } @@ -515,6 +753,7 @@ static void numaker_usbd_sof_th(const struct device *dev) static void numaker_usbd_setup_copy_to_user(const struct device *dev, uint8_t *usrbuf); +#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) /* Interrupt top half processing for Setup packet */ static void numaker_usbd_setup_th(const struct device *dev) { @@ -590,43 +829,247 @@ static void numaker_usbd_ep_th(const struct device *dev, uint32_t ep_hw_idx) } numaker_usbd_send_msg(dev, &msg); } +#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) +/* Interrupt top half processing for CTRL transfer */ +static void numaker_hsusbd_cep_th(const struct device *dev, uint32_t cepintsts) +{ + const struct udc_numaker_config *config = dev->config; + USBD_T *base = config->base; + struct numaker_usbd_msg msg = {0}; + + /* Setup token */ + if (cepintsts & HSUSBD_CEPINTSTS_SETUPTKIF_Msk) { + /* Flush CEP FIFO */ + base->CEPCTL = HSUSBD_CEPCTL_FLUSH | HSUSBD_CEPCTL_NAKCLR_Msk; + } + + /* Setup packet */ + if (cepintsts & HSUSBD_CEPINTSTS_SETUPPKIF_Msk) { + /* By USB spec, following transactions, regardless of Data/Status stage, + * will always be DATA1. HSUBSD will handle the toggle by itself and needn't + * extra control. + */ + + /* Message for bottom-half processing */ + /* NOTE: In Zephyr USB device stack, Setup packet is passed via + * CTRL OUT EP + */ + msg.type = NUMAKER_USBD_MSG_TYPE_SETUP; + numaker_usbd_setup_copy_to_user(dev, msg.setup.packet); + numaker_usbd_send_msg(dev, &msg); + } + + /* Data packet received */ + if (cepintsts & HSUSBD_CEPINTSTS_RXPKIF_Msk) { + /* Block until next CEP trigger */ + base->CEPINTEN &= ~HSUSBD_CEPINTEN_RXPKIEN_Msk; + /* Message for bottom-half processing */ + msg.type = NUMAKER_USBD_MSG_TYPE_OUT; + msg.out.ep = USB_CONTROL_EP_OUT; + numaker_usbd_send_msg(dev, &msg); + } + + /* Data packet transmitted */ + if (cepintsts & HSUSBD_CEPINTSTS_TXPKIF_Msk) { + /* Block until next CEP trigger */ + base->CEPINTEN &= ~HSUSBD_CEPINTEN_TXPKIEN_Msk; + + /* Message for bottom-half processing */ + msg.type = NUMAKER_USBD_MSG_TYPE_IN; + msg.in.ep = USB_CONTROL_EP_IN; + numaker_usbd_send_msg(dev, &msg); + } + + /* Status stage completed */ + if (cepintsts & HSUSBD_CEPINTSTS_STSDONEIF_Msk) { + /* NOTE: See comment in udc_numaker_set_address()'s implementation + * for safe place to change USB device address + */ + if (udc_ctrl_stage_is_status_in(dev) || udc_ctrl_stage_is_no_data(dev)) { + numaker_usbd_set_addr(dev); + } + + /* Message for bottom-half processing */ + if (udc_ctrl_stage_is_status_out(dev)) { + msg.type = NUMAKER_USBD_MSG_TYPE_OUT; + msg.out.ep = USB_CONTROL_EP_OUT; + } else { + msg.type = NUMAKER_USBD_MSG_TYPE_IN; + msg.in.ep = USB_CONTROL_EP_IN; + } + numaker_usbd_send_msg(dev, &msg); + } +} + +/* Interrupt top half processing for BULK/INT/ISO transfer */ +static void numaker_hsusbd_ep_th(const struct device *dev, uint32_t ep_hw_idx, uint32_t epintsts) +{ + USBD_EP_T *ep_base = numaker_usbd_ep_base(dev, ep_hw_idx); + uint8_t ep_dir; + uint8_t ep_idx; + uint8_t ep; + struct numaker_usbd_msg msg = {0}; + + /* EP direction, number, and address */ + ep_dir = ((ep_base->EPCFG & HSUSBD_EPCFG_EPDIR_Msk) == HSUSBD_EP_CFG_DIR_IN) + ? USB_EP_DIR_IN + : USB_EP_DIR_OUT; + ep_idx = (ep_base->EPCFG & HSUSBD_EPCFG_EPNUM_Msk) >> HSUSBD_EPCFG_EPNUM_Pos; + ep = USB_EP_GET_ADDR(ep_idx, ep_dir); + + /* Block until next EP trigger */ + if (epintsts & HSUSBD_EPINTSTS_RXPKIF_Msk) { + ep_base->EPINTEN &= ~HSUSBD_EPINTEN_RXPKIEN_Msk; + } else { + ep_base->EPINTEN &= ~HSUSBD_EPINTEN_TXPKIEN_Msk; + } + + /* Message for bottom-half processing */ + if (USB_EP_DIR_IS_OUT(ep)) { + msg.type = NUMAKER_USBD_MSG_TYPE_OUT; + msg.out.ep = ep; + } else { + msg.type = NUMAKER_USBD_MSG_TYPE_IN; + msg.in.ep = ep; + } + numaker_usbd_send_msg(dev, &msg); +} +#endif + +#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) /* USBD SRAM base for DMA */ static inline uint32_t numaker_usbd_buf_base(const struct device *dev) { const struct udc_numaker_config *config = dev->config; - USBD_T *const base = config->base; + USBD_T *base = config->base; return ((uint32_t)base + 0x800ul); } +#endif /* Copy Setup packet to user buffer */ static void numaker_usbd_setup_copy_to_user(const struct device *dev, uint8_t *usrbuf) { const struct udc_numaker_config *config = dev->config; - USBD_T *const base = config->base; - uint32_t dmabuf_addr; + USBD_T *base = config->base; + __maybe_unused uint32_t dmabuf_addr; +#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) dmabuf_addr = numaker_usbd_buf_base(dev) + (base->STBUFSEG & USBD_STBUFSEG_STBUFSEG_Msk); - bytecpy(usrbuf, (uint8_t *)dmabuf_addr, 8ul); +#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) + *usrbuf = (uint8_t)(base->SETUP1_0 & 0xfful); + *(usrbuf + 1) = (uint8_t)((base->SETUP1_0 >> 8) & 0xfful); + *(usrbuf + 2) = (uint8_t)(base->SETUP3_2 & 0xfful); + *(usrbuf + 3) = (uint8_t)((base->SETUP3_2 >> 8) & 0xfful); + *(usrbuf + 4) = (uint8_t)(base->SETUP5_4 & 0xfful); + *(usrbuf + 5) = (uint8_t)((base->SETUP5_4 >> 8) & 0xfful); + *(usrbuf + 6) = (uint8_t)(base->SETUP7_6 & 0xfful); + *(usrbuf + 7) = (uint8_t)((base->SETUP7_6 >> 8) & 0xfful); +#endif +} + +#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) +/* Copy data to user buffer + * + * size holds size to copy/copied on input/output + */ +static int numaker_hsusbd_ep_copy_to_user(struct numaker_usbd_ep *ep_cur, uint8_t *usrbuf, + uint32_t *size) +{ + const struct device *dev = ep_cur->dev; + const struct udc_numaker_config *config = dev->config; + USBD_T *base = config->base; + USBD_EP_T *ep_base = numaker_usbd_ep_base(dev, ep_cur->ep_hw_idx); + + __ASSERT_NO_MSG(size); + + if (ep_cur->ep_hw_idx == CEP) { + uint8_t *usrbuf_pos = usrbuf; + uint32_t rmn = *size; + + while (rmn && !(base->CEPINTSTS & HSUSBD_CEPINTSTS_BUFEMPTYIF_Msk)) { + *usrbuf_pos++ = base->CEPDAT_BYTE; + rmn--; + } + + *size -= rmn; + } else { + uint8_t *usrbuf_pos = usrbuf; + uint32_t rmn = *size; + + while (rmn && !(ep_base->EPINTSTS & HSUSBD_EPINTSTS_BUFEMPTYIF_Msk)) { + *usrbuf_pos++ = ep_base->EPDAT_BYTE; + rmn--; + } + + *size -= rmn; + } + + return 0; +} + +/* Copy data from user buffer + * + * size holds size to copy/copied on input/output + */ +static int numaker_hsusbd_ep_copy_from_user(struct numaker_usbd_ep *ep_cur, const uint8_t *usrbuf, + uint32_t *size) +{ + const struct device *dev = ep_cur->dev; + const struct udc_numaker_config *config = dev->config; + USBD_T *base = config->base; + USBD_EP_T *ep_base = numaker_usbd_ep_base(dev, ep_cur->ep_hw_idx); + + __ASSERT_NO_MSG(size); + + if (ep_cur->ep_hw_idx == CEP) { + const uint8_t *usrbuf_pos = usrbuf; + uint32_t rmn = *size; + + while (rmn && !(base->CEPINTSTS & HSUSBD_CEPINTSTS_BUFFULLIF_Msk)) { + base->CEPDAT_BYTE = *usrbuf_pos++; + rmn--; + } + + *size -= rmn; + } else { + const uint8_t *usrbuf_pos = usrbuf; + uint32_t rmn = *size; + + while (rmn && !(ep_base->EPINTSTS & HSUSBD_EPINTSTS_BUFFULLIF_Msk)) { + ep_base->EPDAT_BYTE = *usrbuf_pos++; + rmn--; + } + + *size -= rmn; + } + + return 0; } +#endif + /* Copy data to user buffer * - * size_p holds size to copy/copied on input/output + * size holds size to copy/copied on input/output */ -static void numaker_usbd_ep_copy_to_user(struct numaker_usbd_ep *ep_cur, uint8_t *usrbuf, - uint32_t *size_p, uint32_t *rmn_p) +static int numaker_usbd_ep_copy_to_user(struct numaker_usbd_ep *ep_cur, uint8_t *usrbuf, + uint32_t *size, uint32_t *rmn_p) { const struct device *dev = ep_cur->dev; + const struct udc_numaker_config *config = dev->config; + __maybe_unused USBD_T *base = config->base; USBD_EP_T *ep_base = numaker_usbd_ep_base(dev, ep_cur->ep_hw_idx); - uint32_t dmabuf_addr; + __maybe_unused uint32_t dmabuf_addr; uint32_t data_rmn; + __maybe_unused int err; - __ASSERT_NO_MSG(size_p); + __ASSERT_NO_MSG(size); __ASSERT_NO_MSG(ep_cur->dmabuf_valid); +#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) dmabuf_addr = numaker_usbd_buf_base(dev) + ep_base->BUFSEG; /* NOTE: See comment on mxpld_ctrlout for why make one copy of CTRL OUT's MXPLD */ @@ -635,61 +1078,124 @@ static void numaker_usbd_ep_copy_to_user(struct numaker_usbd_ep *ep_cur, uint8_t } else { data_rmn = (ep_base->MXPLD & USBD_MXPLD_MXPLD_Msk) >> USBD_MXPLD_MXPLD_Pos; } +#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) + if (ep_cur->ep_hw_idx == CEP) { + data_rmn = (base->CEPDATCNT & HSUSBD_CEPDATCNT_DATCNT_Msk) >> + HSUSBD_CEPDATCNT_DATCNT_Pos; + } else { + data_rmn = (ep_base->EPDATCNT & HSUSBD_EPDATCNT_DATCNT_Msk) >> + HSUSBD_EPDATCNT_DATCNT_Pos; + } +#endif - *size_p = MIN(*size_p, data_rmn); + *size = MIN(*size, data_rmn); - bytecpy(usrbuf, (uint8_t *)dmabuf_addr, *size_p); - data_rmn -= *size_p; +#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) + bytecpy(usrbuf, (uint8_t *)dmabuf_addr, *size); +#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) + err = numaker_hsusbd_ep_copy_to_user(ep_cur, usrbuf, size); + if (err < 0) { + return err; + } +#endif + + data_rmn -= *size; if (rmn_p) { *rmn_p = data_rmn; } + + return 0; } /* Copy data from user buffer * - * size_p holds size to copy/copied on input/output + * size holds size to copy/copied on input/output */ -static void numaker_usbd_ep_copy_from_user(struct numaker_usbd_ep *ep_cur, const uint8_t *usrbuf, - uint32_t *size_p) +static int numaker_usbd_ep_copy_from_user(struct numaker_usbd_ep *ep_cur, const uint8_t *usrbuf, + uint32_t *size) { const struct device *dev = ep_cur->dev; - USBD_EP_T *ep_base = numaker_usbd_ep_base(dev, ep_cur->ep_hw_idx); - uint32_t dmabuf_addr; + __maybe_unused USBD_EP_T *ep_base = numaker_usbd_ep_base(dev, ep_cur->ep_hw_idx); + __maybe_unused uint32_t dmabuf_addr; + __maybe_unused int err; - __ASSERT_NO_MSG(size_p); + __ASSERT_NO_MSG(size); __ASSERT_NO_MSG(ep_cur->dmabuf_valid); __ASSERT_NO_MSG(ep_cur->mps_valid); __ASSERT_NO_MSG(ep_cur->mps <= ep_cur->dmabuf_size); - dmabuf_addr = numaker_usbd_buf_base(dev) + ep_base->BUFSEG; + *size = MIN(*size, ep_cur->mps); - *size_p = MIN(*size_p, ep_cur->mps); +#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) + dmabuf_addr = numaker_usbd_buf_base(dev) + ep_base->BUFSEG; + bytecpy((uint8_t *)dmabuf_addr, (uint8_t *)usrbuf, *size); +#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) + err = numaker_hsusbd_ep_copy_from_user(ep_cur, usrbuf, size); + if (err < 0) { + return err; + } +#endif - bytecpy((uint8_t *)dmabuf_addr, (uint8_t *)usrbuf, *size_p); + return 0; } static void numaker_usbd_ep_config_dmabuf(struct numaker_usbd_ep *ep_cur, uint32_t dmabuf_base, uint32_t dmabuf_size) { const struct device *dev = ep_cur->dev; + const struct udc_numaker_config *config = dev->config; + __maybe_unused USBD_T *base = config->base; USBD_EP_T *ep_base = numaker_usbd_ep_base(dev, ep_cur->ep_hw_idx); +#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) ep_base->BUFSEG = dmabuf_base; +#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) + if (ep_cur->ep_hw_idx == CEP) { + base->CEPBUFST = dmabuf_base; + base->CEPBUFEND = dmabuf_base + dmabuf_size - 1ul; + } else { + ep_base->EPBUFST = dmabuf_base; + ep_base->EPBUFEND = dmabuf_base + dmabuf_size - 1ul; + } +#endif ep_cur->dmabuf_valid = true; ep_cur->dmabuf_base = dmabuf_base; ep_cur->dmabuf_size = dmabuf_size; } -static void numaker_usbd_ep_abort(struct numaker_usbd_ep *ep_cur) +static void numaker_usbd_ep_abort(struct numaker_usbd_ep *ep_cur, bool excl_ctrl) { struct udc_ep_config *ep_cfg; const struct device *dev = ep_cur->dev; + const struct udc_numaker_config *config = dev->config; + __maybe_unused USBD_T *base = config->base; USBD_EP_T *ep_base = numaker_usbd_ep_base(dev, ep_cur->ep_hw_idx); +#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) /* Abort EP on-going transaction */ - ep_base->CFGP |= USBD_CFGP_CLRRDY_Msk; + if ((ep_cur->ep_hw_idx != EP0 && ep_cur->ep_hw_idx != EP1) || !excl_ctrl) { + ep_base->CFGP |= USBD_CFGP_CLRRDY_Msk; + } +#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) + /* For HSUSBD, there is no control for aborting EP on-going + * transaction, but there is related control of flush EP FIFO. + */ + if (ep_cur->ep_hw_idx == CEP) { + if (!excl_ctrl) { + /* Flush CEP FIFO */ + base->CEPCTL = HSUSBD_CEPCTL_FLUSH | HSUSBD_CEPCTL_NAKCLR_Msk; + } + } else { + /* Flush EP FIFO */ + uint32_t eprspctl = ep_base->EPRSPCTL; + + eprspctl &= ~HSUSBD_EPRSPCTL_TOGGLE_Msk; + eprspctl |= HSUSBD_EP_RSPCTL_FLUSH; + ep_base->EPRSPCTL = eprspctl; + } +#endif if (ep_cur->addr_valid) { ep_cfg = udc_get_ep_cfg(dev, ep_cur->addr); @@ -703,15 +1209,17 @@ static void numaker_usbd_ep_config_major(struct numaker_usbd_ep *ep_cur, { const struct device *dev = ep_cur->dev; USBD_EP_T *ep_base = numaker_usbd_ep_base(dev, ep_cur->ep_hw_idx); + uint8_t ep_type = ep_cfg->attributes & USB_EP_TRANSFER_TYPE_MASK; ep_cur->mps_valid = true; ep_cur->mps = ep_cfg->mps; /* Configure EP transfer type, DATA0/1 toggle, direction, number, etc. */ +#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) ep_cur->ep_hw_cfg = 0; /* Clear STALL Response in Setup stage */ - if ((ep_cfg->attributes & USB_EP_TRANSFER_TYPE_MASK) == USB_EP_TYPE_CONTROL) { + if (ep_type == USB_EP_TYPE_CONTROL) { ep_cur->ep_hw_cfg |= USBD_CFG_CSTALL; } @@ -722,7 +1230,7 @@ static void numaker_usbd_ep_config_major(struct numaker_usbd_ep *ep_cur, ep_cur->ep_hw_cfg |= USBD_CFG_EPMODE_DISABLE; /* Isochronous or not */ - if ((ep_cfg->attributes & USB_EP_TRANSFER_TYPE_MASK) == USB_EP_TYPE_ISO) { + if (ep_type == USB_EP_TYPE_ISO) { ep_cur->ep_hw_cfg |= USBD_CFG_TYPE_ISO; } @@ -731,17 +1239,69 @@ static void numaker_usbd_ep_config_major(struct numaker_usbd_ep *ep_cur, USBD_CFG_EPNUM_Msk; ep_base->CFG = ep_cur->ep_hw_cfg; +#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) + if (ep_cur->ep_hw_idx == CEP) { + /* EP type: CONTROL */ + __ASSERT_NO_MSG(ep_type == USB_EP_TYPE_CONTROL); + } else { + ep_cur->ep_hw_cfg = 0; + ep_cur->ep_hw_rspctl = 0; + + /* Default to DATA0 */ + ep_cur->ep_hw_rspctl |= HSUSBD_EPRSPCTL_TOGGLE_Msk; + + /* EP type: BULK/INT/ISO */ + switch (ep_type) { + case USB_EP_TYPE_BULK: + ep_cur->ep_hw_rspctl |= HSUSBD_EP_RSPCTL_MODE_AUTO; + ep_cur->ep_hw_cfg |= HSUSBD_EP_CFG_TYPE_BULK; + break; + case USB_EP_TYPE_INTERRUPT: + ep_cur->ep_hw_rspctl |= HSUSBD_EP_RSPCTL_MODE_MANUAL; + ep_cur->ep_hw_cfg |= HSUSBD_EP_CFG_TYPE_INT; + break; + case USB_EP_TYPE_ISO: + ep_cur->ep_hw_rspctl |= HSUSBD_EP_RSPCTL_MODE_FLY; + ep_cur->ep_hw_cfg |= HSUSBD_EP_CFG_TYPE_ISO; + break; + default: + __ASSERT_NO_MSG(0); + } + + /* EP number */ + ep_cur->ep_hw_cfg |= (USB_EP_GET_IDX(ep_cfg->addr) << HSUSBD_EPCFG_EPNUM_Pos) & + HSUSBD_EPCFG_EPNUM_Msk; + + /* EP direction */ + if (USB_EP_DIR_IS_IN(ep_cfg->addr)) { + ep_cur->ep_hw_cfg |= HSUSBD_EP_CFG_DIR_IN; + } else { + ep_cur->ep_hw_cfg |= HSUSBD_EP_CFG_DIR_OUT; + } + + /* EP MPS */ + ep_base->EPMPS = ep_cfg->mps; + + /* Default to disabled (HSUSBD_EP_CFG_VALID unset) */ + + ep_base->EPRSPCTL = ep_cur->ep_hw_rspctl; + ep_base->EPCFG = ep_cur->ep_hw_cfg; + } +#endif } static void numaker_usbd_ep_enable(struct numaker_usbd_ep *ep_cur) { const struct device *dev = ep_cur->dev; + const struct udc_numaker_config *config = dev->config; + __maybe_unused USBD_T *base = config->base; USBD_EP_T *ep_base = numaker_usbd_ep_base(dev, ep_cur->ep_hw_idx); /* For safe, EP (re-)enable from clean state */ - numaker_usbd_ep_abort(ep_cur); + numaker_usbd_ep_abort(ep_cur, false); numaker_usbd_ep_clear_stall_n_data_toggle(ep_cur); +#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) /* Enable EP to IN/OUT */ ep_cur->ep_hw_cfg &= ~USBD_CFG_STATE_Msk; if (USB_EP_DIR_IS_IN(ep_cur->addr)) { @@ -749,37 +1309,154 @@ static void numaker_usbd_ep_enable(struct numaker_usbd_ep *ep_cur) } else { ep_cur->ep_hw_cfg |= USBD_CFG_EPMODE_OUT; } - ep_base->CFG = ep_cur->ep_hw_cfg; /* For USBD, no separate EP interrupt control */ + +#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) + if (ep_cur->ep_hw_idx == CEP) { + /* CEP global interrupt should have enabled for resident. */ + + /* To enable CEP local interrupt in CEP trigger */ + } else { + /* Enable EP */ + ep_cur->ep_hw_cfg &= ~HSUSBD_EPCFG_EPEN_Msk; + ep_cur->ep_hw_cfg |= HSUSBD_EP_CFG_VALID; + ep_base->EPCFG = ep_cur->ep_hw_cfg; + + /* Enable EP global interrupt */ + base->GINTEN |= BIT(ep_cur->ep_hw_idx - EPA + HSUSBD_GINTEN_EPAIEN_Pos); + + /* To enable EP local interrupt in EP trigger */ + } +#endif } static void numaker_usbd_ep_disable(struct numaker_usbd_ep *ep_cur) { const struct device *dev = ep_cur->dev; + const struct udc_numaker_config *config = dev->config; + __maybe_unused USBD_T *base = config->base; USBD_EP_T *ep_base = numaker_usbd_ep_base(dev, ep_cur->ep_hw_idx); +#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) /* For USBD, no separate EP interrupt control */ /* Disable EP */ ep_cur->ep_hw_cfg = (ep_cur->ep_hw_cfg & ~USBD_CFG_STATE_Msk) | USBD_CFG_EPMODE_DISABLE; ep_base->CFG = ep_cur->ep_hw_cfg; +#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) + if (ep_cur->ep_hw_idx == CEP) { + /* Disable CEP local interrupt */ + if (USB_EP_DIR_IS_IN(ep_cur->addr)) { + base->CEPINTEN &= ~HSUSBD_CEPINTEN_TXPKIEN_Msk; + } else { + base->CEPINTEN &= ~HSUSBD_CEPINTEN_RXPKIEN_Msk; + } + + /* CEP global interrupt shouldn't get disabled for resident. */ + } else { + /* Disable EP local interrupt */ + if (USB_EP_DIR_IS_IN(ep_cur->addr)) { + ep_base->EPINTEN &= ~HSUSBD_EPINTEN_TXPKIEN_Msk; + } else { + ep_base->EPINTEN &= ~HSUSBD_EPINTEN_RXPKIEN_Msk; + } + + /* Disable EP global interrupt */ + base->GINTEN &= ~BIT(ep_cur->ep_hw_idx - EPA + HSUSBD_GINTEN_EPAIEN_Pos); + + /* Disable EP */ + ep_cur->ep_hw_cfg &= ~HSUSBD_EPCFG_EPEN_Msk; + ep_base->EPCFG = ep_cur->ep_hw_cfg; + } +#endif } /* Start EP data transaction */ -static void udc_numaker_ep_trigger(struct numaker_usbd_ep *ep_cur, uint32_t len) +static void numaker_usbd_ep_trigger(struct numaker_usbd_ep *ep_cur, uint32_t len) { struct udc_ep_config *ep_cfg; const struct device *dev = ep_cur->dev; + const struct udc_numaker_config *config = dev->config; + __maybe_unused USBD_T *base = config->base; USBD_EP_T *ep_base = numaker_usbd_ep_base(dev, ep_cur->ep_hw_idx); - if (ep_cur->addr_valid) { - ep_cfg = udc_get_ep_cfg(dev, ep_cur->addr); - udc_ep_set_busy(ep_cfg, true); - } + __ASSERT_NO_MSG(ep_cur->addr_valid); + + ep_cfg = udc_get_ep_cfg(dev, ep_cur->addr); + udc_ep_set_busy(ep_cfg, true); +#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) ep_base->MXPLD = len; +#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) + if (ep_cur->ep_hw_idx == CEP) { + if (USB_EP_DIR_IS_IN(ep_cur->addr)) { + if (udc_ctrl_stage_is_status_in(dev) || udc_ctrl_stage_is_no_data(dev)) { + /* Unleash Status stage */ + base->CEPCTL = HSUSBD_CEPCTL_NAKCLR; + } + + if (len == 0) { + base->CEPCTL = HSUSBD_CEPCTL_ZEROLEN | HSUSBD_CEPCTL_NAKCLR_Msk; + } else { + __ASSERT_NO_MSG(len <= ep_cur->mps); + base->CEPTXCNT = len; + } + + /* Enable CEP interrupt */ + base->CEPINTEN |= HSUSBD_CEPINTEN_TXPKIEN_Msk; + } else { + if (udc_ctrl_stage_is_status_out(dev)) { + /* Unleash Status stage */ + base->CEPCTL = HSUSBD_CEPCTL_NAKCLR; + } + + /* Enable CEP interrupt */ + base->CEPINTEN |= HSUSBD_CEPINTEN_RXPKIEN_Msk; + } + } else { + if (USB_EP_DIR_IS_IN(ep_cur->addr)) { + uint32_t eprspctl = ep_base->EPRSPCTL; + uint32_t eprspctl_mode = eprspctl & HSUSBD_EPRSPCTL_MODE_Msk; + + /* Not to change data toggle bit */ + eprspctl &= ~HSUSBD_EPRSPCTL_TOGGLE_Msk; + + if (eprspctl_mode == HSUSBD_EP_RSPCTL_MODE_AUTO) { + if (len == 0) { + eprspctl |= HSUSBD_EP_RSPCTL_ZEROLEN; + ep_base->EPRSPCTL = eprspctl; + } else if (len < ep_cur->mps) { + eprspctl |= HSUSBD_EP_RSPCTL_SHORTTXEN; + ep_base->EPRSPCTL = eprspctl; + } else { + __ASSERT_NO_MSG(len == ep_cur->mps); + /* Tx automatic for mps size */ + } + } else if (eprspctl_mode == HSUSBD_EP_RSPCTL_MODE_MANUAL) { + if (len == 0) { + eprspctl |= HSUSBD_EP_RSPCTL_ZEROLEN; + ep_base->EPRSPCTL = eprspctl; + } else { + __ASSERT_NO_MSG(len <= ep_cur->mps); + ep_base->EPTXCNT = len; + } + } else if (eprspctl_mode == HSUSBD_EP_RSPCTL_MODE_FLY) { + __ASSERT_NO_MSG(len <= ep_cur->mps); + /* Tx automatic for any size */ + } else { + __ASSERT_NO_MSG(0); + } + + /* Enable EP interrupt */ + ep_base->EPINTEN |= HSUSBD_EPINTEN_TXPKIEN_Msk; + } else { + /* Enable EP interrupt */ + ep_base->EPINTEN |= HSUSBD_EPINTEN_RXPKIEN_Msk; + } + } +#endif } static struct numaker_usbd_ep *numaker_usbd_ep_mgmt_alloc_ep(const struct device *dev) @@ -806,14 +1483,14 @@ static struct numaker_usbd_ep *numaker_usbd_ep_mgmt_alloc_ep(const struct device * Return -ENOMEM on OOM error, or 0 on success with DMA buffer base/size (rounded up) allocated */ static int numaker_usbd_ep_mgmt_alloc_dmabuf(const struct device *dev, uint32_t size, - uint32_t *dmabuf_base_p, uint32_t *dmabuf_size_p) + uint32_t *dmabuf_base_p, uint32_t *dmabuf_size) { const struct udc_numaker_config *config = dev->config; struct udc_numaker_data *priv = udc_get_private(dev); struct numaker_usbd_ep_mgmt *ep_mgmt = &priv->ep_mgmt; __ASSERT_NO_MSG(dmabuf_base_p); - __ASSERT_NO_MSG(dmabuf_size_p); + __ASSERT_NO_MSG(dmabuf_size); /* Required to be 8-byte aligned */ size = ROUND_UP(size, 8); @@ -825,7 +1502,7 @@ static int numaker_usbd_ep_mgmt_alloc_dmabuf(const struct device *dev, uint32_t } *dmabuf_base_p = ep_mgmt->dmabuf_pos - size; - *dmabuf_size_p = size; + *dmabuf_size = size; return 0; } @@ -834,7 +1511,7 @@ static void numaker_usbd_ep_mgmt_init(const struct device *dev) { const struct udc_numaker_config *config = dev->config; struct udc_numaker_data *priv = udc_get_private(dev); - USBD_T *const base = config->base; + __maybe_unused USBD_T *base = config->base; struct numaker_usbd_ep_mgmt *ep_mgmt = &priv->ep_mgmt; struct numaker_usbd_ep *ep_cur; @@ -854,21 +1531,49 @@ static void numaker_usbd_ep_mgmt_init(const struct device *dev) /* Pointer to the containing device */ ep_cur->dev = dev; - /* BSP USBD driver EP handle */ +#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) + /* BSP USBD driver EP handle + * + * ep_pool[0]: EP0 (CTRL OUT) + * ep_pool[1]: EP1 (CTRL IN) + * ep_pool[2~]: EP2, EP3, etc. + */ ep_cur->ep_hw_idx = EP0 + (ep_cur - priv->ep_pool); +#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) + /* BSP HSUSBD driver EP handle + * + * ep_pool[0]: CEP (CTRL OUT) + * ep_pool[1]: CEP (CTRL IN) + * ep_pool[2~]: EPA, EPB, etc. + */ + ep_cur->ep_hw_idx = EPA + (ep_cur - priv->ep_pool); + if (ep_cur->ep_hw_idx == 0 || ep_cur->ep_hw_idx == 1) { + ep_cur->ep_hw_idx = CEP; + } else { + ep_cur->ep_hw_idx -= 2; + } +#endif } - /* Reserve 1st/2nd EP H/W contexts (BSP USBD driver EP0/EP1) for CTRL OUT/IN */ + /* Reserve 1st/2nd EP H/W contexts for CTRL OUT/IN + * + * For USBD, EP0/EP1 + * For HSUSBD, EPA/EPB + */ ep_mgmt->ep_idx = 2; /* Reserve DMA buffer for Setup/CTRL OUT/CTRL IN, starting from 0 */ ep_mgmt->dmabuf_pos = 0; /* Configure DMA buffer for Setup packet */ +#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) base->STBUFSEG = ep_mgmt->dmabuf_pos; ep_mgmt->dmabuf_pos += NUMAKER_USBD_DMABUF_SIZE_SETUP; +#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) + /* For HSUSBD, SETUP1_0, SETUP3_2, SETUP5_4, SETUP7_6 */ +#endif - /* Reserve 1st EP H/W context (BSP USBD driver EP0) for CTRL OUT */ + /* Reserve 1st EP H/W context for CTRL OUT */ ep_cur = priv->ep_pool + 0; ep_cur->valid = true; ep_cur->addr_valid = true; @@ -879,7 +1584,7 @@ static void numaker_usbd_ep_mgmt_init(const struct device *dev) ep_cur->mps_valid = true; ep_cur->mps = NUMAKER_USBD_DMABUF_SIZE_CTRLOUT; - /* Reserve 2nd EP H/W context (BSP USBD driver EP1) for CTRL IN */ + /* Reserve 2nd EP H/W context for CTRL IN */ ep_cur = priv->ep_pool + 1; ep_cur->valid = true; ep_cur->addr_valid = true; @@ -979,13 +1684,14 @@ static int numaker_usbd_xfer_out(const struct device *dev, uint8_t ep, bool stri return -ENODEV; } - udc_numaker_ep_trigger(ep_cur, ep_cur->mps); + numaker_usbd_ep_trigger(ep_cur, ep_cur->mps); return 0; } static int numaker_usbd_xfer_in(const struct device *dev, uint8_t ep, bool strict) { + int err; struct net_buf *buf; struct numaker_usbd_ep *ep_cur; struct udc_ep_config *ep_cfg; @@ -1025,7 +1731,11 @@ static int numaker_usbd_xfer_in(const struct device *dev, uint8_t ep, bool stric data_len = buf->len; if (data_len) { - numaker_usbd_ep_copy_from_user(ep_cur, buf->data, &data_len); + err = numaker_usbd_ep_copy_from_user(ep_cur, buf->data, &data_len); + if (err < 0) { + LOG_ERR("Transfer to USB buffer failed: %d", err); + return err; + } net_buf_pull(buf, data_len); } else if (udc_ep_buf_has_zlp(buf)) { /* zlp, send exactly once */ @@ -1034,7 +1744,7 @@ static int numaker_usbd_xfer_in(const struct device *dev, uint8_t ep, bool stric /* initially empty net_buf, send exactly once */ } - udc_numaker_ep_trigger(ep_cur, data_len); + numaker_usbd_ep_trigger(ep_cur, data_len); return 0; } @@ -1063,6 +1773,76 @@ static int numaker_usbd_ctrl_feed_dout(const struct device *dev, const size_t le return numaker_usbd_xfer_out(dev, ep_cfg->addr, true); } +/* Message handler for device plug-in */ +static int numaker_usbd_msg_handle_attach(const struct device *dev, struct numaker_usbd_msg *msg) +{ + int err; + + __ASSERT_NO_MSG(msg->type == NUMAKER_USBD_MSG_TYPE_ATTACH); + +#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) + /* For USBD, enable back USB/PHY has done in ISR for unneeded wait. */ +#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) + err = numaker_usbd_enable_usb_phy(dev); + if (err < 0) { + LOG_ERR("Enable USB/PHY failed"); + return -err; + } +#endif + + err = udc_submit_event(dev, UDC_EVT_VBUS_READY, 0); + + return err; +} + +/* Message handler for bus reset */ +static int numaker_usbd_msg_handle_reset(const struct device *dev, struct numaker_usbd_msg *msg) +{ + int err; + + __ASSERT_NO_MSG(msg->type == NUMAKER_USBD_MSG_TYPE_RESET); + +#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) + /* For USBD, enable back USB/PHY has done in ISR for unneeded wait. */ +#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) + err = numaker_usbd_enable_usb_phy(dev); + if (err < 0) { + LOG_ERR("Enable USB/PHY failed"); + return -err; + } +#endif + + /* UDC stack would handle bottom-half processing, + * including reset device address (udc_set_address), + * un-configure device (udc_ep_disable), etc. + */ + err = udc_submit_event(dev, UDC_EVT_RESET, 0); + + return err; +} + +/* Message handler for bus resume */ +static int numaker_usbd_msg_handle_resume(const struct device *dev, struct numaker_usbd_msg *msg) +{ + int err; + + __ASSERT_NO_MSG(msg->type == NUMAKER_USBD_MSG_TYPE_RESUME); + +#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) + /* For USBD, enable back USB/PHY has done in ISR for unneeded wait. */ +#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) + err = numaker_usbd_enable_usb_phy(dev); + if (err < 0) { + LOG_ERR("Enable USB/PHY failed"); + return -err; + } +#endif + + err = udc_submit_event(dev, UDC_EVT_RESUME, 0); + + return err; +} + /* Message handler for Setup transaction completed */ static int numaker_usbd_msg_handle_setup(const struct device *dev, struct numaker_usbd_msg *msg) { @@ -1106,8 +1886,16 @@ static int numaker_usbd_msg_handle_setup(const struct device *dev, struct numake __ASSERT_NO_MSG((ep_cur + 1)->addr == USB_CONTROL_EP_IN); /* Abort previous CTRL OUT/IN */ - numaker_usbd_ep_abort(ep_cur); - numaker_usbd_ep_abort(ep_cur + 1); +#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) + numaker_usbd_ep_abort(ep_cur, false); + numaker_usbd_ep_abort(ep_cur + 1, false); +#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) + /* For HSUSBD, there is timing concern between FIFO flush and + * immediately following data transaction. Do in ISR for in time. + */ + numaker_usbd_ep_abort(ep_cur, true); + numaker_usbd_ep_abort(ep_cur + 1, true); +#endif /* CTRL OUT/IN reset to unstalled by H/W on receive of Setup packet */ numaker_usbd_ep_sync_udc_halt(ep_cur, false); @@ -1181,7 +1969,11 @@ static int numaker_usbd_msg_handle_out(const struct device *dev, struct numaker_ data_len = net_buf_tailroom(buf); } data_ptr = net_buf_tail(buf); - numaker_usbd_ep_copy_to_user(ep_cur, data_ptr, &data_len, &data_rmn); + err = numaker_usbd_ep_copy_to_user(ep_cur, data_ptr, &data_len, &data_rmn); + if (err < 0) { + LOG_ERR("Transfer from USB buffer failed: %d", err); + return err; + } net_buf_add(buf, data_len); if (ep == USB_CONTROL_EP_OUT) { __ASSERT_NO_MSG(priv->ctrlout_tailroom >= data_len); @@ -1361,6 +2153,18 @@ static void numaker_usbd_msg_handler(const struct device *dev) udc_lock_internal(dev, K_FOREVER); switch (msg.type) { + case NUMAKER_USBD_MSG_TYPE_ATTACH: + err = numaker_usbd_msg_handle_attach(dev, &msg); + break; + + case NUMAKER_USBD_MSG_TYPE_RESUME: + err = numaker_usbd_msg_handle_resume(dev, &msg); + break; + + case NUMAKER_USBD_MSG_TYPE_RESET: + err = numaker_usbd_msg_handle_reset(dev, &msg); + break; + case NUMAKER_USBD_MSG_TYPE_SETUP: err = numaker_usbd_msg_handle_setup(dev, &msg); break; @@ -1396,7 +2200,10 @@ static void numaker_usbd_msg_handler(const struct device *dev) static void numaker_usbd_isr(const struct device *dev) { const struct udc_numaker_config *config = dev->config; - USBD_T *const base = config->base; + __maybe_unused struct udc_numaker_data *priv = udc_get_private(dev); + USBD_T *base = config->base; + +#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) uint32_t usbd_intsts = base->INTSTS; uint32_t usbd_bus_state = base->ATTR; @@ -1471,14 +2278,97 @@ static void numaker_usbd_isr(const struct device *dev) numaker_usbd_ep_th(dev, ep_hw_idx); /* Have handled this EP and go next */ - epintsts &= ~BIT(ep_hw_idx); + epintsts &= ~BIT(ep_hw_idx - EP0); } } +#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) + uint32_t gintsts = base->GINTSTS; + uint32_t gintsts_ep = gintsts & + (BIT_MASK(priv->ep_pool_size - 2) << HSUSBD_GINTSTS_EPAIF_Pos); + uint32_t busintsts = base->BUSINTSTS; + uint32_t cepintsts = base->CEPINTSTS; + + /* Focus on enabled */ + busintsts &= base->BUSINTEN; + cepintsts &= base->CEPINTEN; + + /* Clear event flag */ + base->BUSINTSTS = busintsts; + + /* USB plug-in/unplug */ + if (busintsts & HSUSBD_BUSINTSTS_VBUSDETIF_Msk) { + if (base->PHYCTL & HSUSBD_PHYCTL_VBUSDET_Msk) { + /* USB plug-in */ + numaker_usbd_vbus_plug_th(dev); + } else { + /* USB unplug */ + numaker_usbd_vbus_unplug_th(dev); + } + } + + /* USB reset */ + if (busintsts & HSUSBD_BUSINTSTS_RSTIF_Msk) { + numaker_usbd_bus_reset_th(dev); + } + + /* Bus suspend */ + if (busintsts & HSUSBD_BUSINTSTS_SUSPENDIF_Msk) { + numaker_usbd_bus_suspend_th(dev); + } + + /* Bus resume */ + if (busintsts & HSUSBD_BUSINTSTS_RESUMEIF_Msk) { + numaker_usbd_bus_resume_th(dev); + } + + /* USB SOF */ + if (busintsts & HSUSBD_BUSINTSTS_SOFIF_Msk) { + numaker_usbd_sof_th(dev); + } + + /* USB CEP */ + if (cepintsts) { + /* Clear event flag */ + base->CEPINTSTS = cepintsts; + + numaker_hsusbd_cep_th(dev, cepintsts); + } + + /* USB EP */ + if (gintsts_ep) { + /* Iterate over EP from BIT0 position */ + uint32_t gintsts_ep_iter = gintsts_ep >> HSUSBD_GINTSTS_EPAIF_Pos; + + while (gintsts_ep_iter) { + uint32_t ep_hw_idx = EPA + u32_count_trailing_zeros(gintsts_ep_iter); + HSUSBD_EP_T *ep_base = numaker_usbd_ep_base(dev, ep_hw_idx); + uint32_t epintsts = ep_base->EPINTSTS; + + /* Focus on enabled */ + epintsts &= ep_base->EPINTEN; + + /* Clear event flag */ + ep_base->EPINTSTS = epintsts; + + numaker_hsusbd_ep_th(dev, ep_hw_idx, epintsts); + + /* Have handled this EP and go next */ + gintsts_ep_iter &= ~BIT(ep_hw_idx - EPA); + } + } +#endif } static enum udc_bus_speed udc_numaker_device_speed(const struct device *dev) { + const struct udc_numaker_config *config = dev->config; + __maybe_unused USBD_T *base = config->base; + +#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) return UDC_BUS_SPEED_FS; +#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) + return (base->OPER & HSUSBD_OPER_CURSPD_Msk) ? UDC_BUS_SPEED_HS : UDC_BUS_SPEED_FS; +#endif } static int udc_numaker_ep_enqueue(const struct device *dev, struct udc_ep_config *const ep_cfg, @@ -1511,7 +2401,7 @@ static int udc_numaker_ep_dequeue(const struct device *dev, struct udc_ep_config return -ENODEV; } - numaker_usbd_ep_abort(ep_cur); + numaker_usbd_ep_abort(ep_cur, false); buf = udc_buf_get_all(ep_cfg); if (buf) { @@ -1626,15 +2516,24 @@ static int udc_numaker_ep_disable(const struct device *dev, struct udc_ep_config static int udc_numaker_host_wakeup(const struct device *dev) { const struct udc_numaker_config *config = dev->config; - USBD_T *const base = config->base; + USBD_T *base = config->base; + int err; /* Enable back USB/PHY first */ - base->ATTR |= USBD_ATTR_USBEN_Msk | USBD_ATTR_PHYEN_Msk; + err = numaker_usbd_enable_usb_phy(dev); + if (err < 0) { + LOG_ERR("Enable USB/PHY failed"); + return -EIO; + } /* Then generate 'K' */ +#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) base->ATTR |= USBD_ATTR_RWAKEUP_Msk; k_sleep(K_USEC(NUMAKER_USBD_BUS_RESUME_DRV_K_US)); base->ATTR ^= USBD_ATTR_RWAKEUP_Msk; +#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) + base->OPER |= HSUSBD_OPER_RESUMEEN_Msk; +#endif return 0; } @@ -1681,7 +2580,7 @@ static int udc_numaker_init(const struct device *dev) USBD_T *base = config->base; int err; - /* Initialize USBD H/W */ + /* Initialize UDC H/W */ err = numaker_usbd_hw_setup(dev); if (err < 0) { LOG_ERR("Set up H/W: %d", err); @@ -1706,13 +2605,25 @@ static int udc_numaker_init(const struct device *dev) /* Enable VBUS detect early */ if (data->caps.can_detect_vbus) { +#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) base->INTEN = USBD_INT_FLDET; +#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) + base->BUSINTEN = HSUSBD_BUSINTEN_VBUSDETIEN_Msk; +#endif } else { +#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) base->INTEN = 0; +#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) + base->BUSINTEN = 0; +#endif } /* Enable USB wake-up early */ +#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) base->INTEN |= USBD_INT_WAKEUP; +#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) + base->PHYCTL |= HSUSBD_PHYCTL_VBUSWKEN_Msk; +#endif return 0; } @@ -1731,7 +2642,7 @@ static int udc_numaker_shutdown(const struct device *dev) return -EIO; } - /* Uninitialize USBD H/W */ + /* Uninitialize UDC H/W */ numaker_usbd_hw_shutdown(dev); /* Purge message queue */ @@ -1754,8 +2665,19 @@ static int udc_numaker_driver_preinit(const struct device *dev) { const struct udc_numaker_config *config = dev->config; struct udc_data *data = dev->data; + __maybe_unused struct udc_numaker_data *priv = udc_get_private(dev); + uint16_t mps = 1023; int err; +#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) + /* For USBD, support just full-speed */ +#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) + /* For HSUSBD, support both full-speed and high-speed */ + if (config->speed_idx >= 2) { + data->caps.hs = true; + mps = 1024; + } +#endif data->caps.rwup = true; data->caps.addr_before_status = true; data->caps.can_detect_vbus = true; @@ -1780,7 +2702,7 @@ static int udc_numaker_driver_preinit(const struct device *dev) config->ep_cfg_out[i].caps.bulk = 1; config->ep_cfg_out[i].caps.interrupt = 1; config->ep_cfg_out[i].caps.iso = 1; - config->ep_cfg_out[i].caps.mps = 1023; + config->ep_cfg_out[i].caps.mps = mps; } config->ep_cfg_out[i].addr = USB_EP_DIR_OUT | i; @@ -1805,7 +2727,7 @@ static int udc_numaker_driver_preinit(const struct device *dev) config->ep_cfg_in[i].caps.bulk = 1; config->ep_cfg_in[i].caps.interrupt = 1; config->ep_cfg_in[i].caps.iso = 1; - config->ep_cfg_in[i].caps.mps = 1023; + config->ep_cfg_in[i].caps.mps = mps; } config->ep_cfg_in[i].addr = USB_EP_DIR_IN | i; @@ -1839,8 +2761,15 @@ static const struct udc_api udc_numaker_api = { .unlock = udc_numaker_unlock, }; +#define NUMAKER_USBD_PINCTRL_DEV_CONFIG_GET(inst) \ + COND_CODE_1(DT_NODE_HAS_PROP(DT_DRV_INST(inst), pinctrl_0), \ + (PINCTRL_DT_INST_DEV_CONFIG_GET(inst)), (NULL)) + +#define NUMAKER_USBD_PINCTRL_DEFINE(inst) \ + IF_ENABLED(DT_NODE_HAS_PROP(DT_DRV_INST(inst), pinctrl_0), (PINCTRL_DT_INST_DEFINE(inst))) + #define UDC_NUMAKER_DEVICE_DEFINE(inst) \ - PINCTRL_DT_INST_DEFINE(inst); \ + NUMAKER_USBD_PINCTRL_DEFINE(inst); \ \ static void udc_numaker_irq_config_func_##inst(const struct device *dev) \ { \ @@ -1895,9 +2824,12 @@ static const struct udc_api udc_numaker_api = { .clkctrl_dev = DEVICE_DT_GET(DT_PARENT(DT_INST_CLOCKS_CTLR(inst))), \ .irq_config_func = udc_numaker_irq_config_func_##inst, \ .irq_unconfig_func = udc_numaker_irq_unconfig_func_##inst, \ - .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(inst), \ + .pincfg = NUMAKER_USBD_PINCTRL_DEV_CONFIG_GET(inst), \ .dmabuf_size = DT_INST_PROP(inst, dma_buffer_size), \ - .disallow_iso_inout_same = DT_INST_PROP(inst, disallow_iso_in_out_same_number), \ + .disallow_iso_inout_same = DT_INST_PROP_OR(inst, disallow_iso_in_out_same_number, \ + 0), \ + .speed_idx = DT_ENUM_IDX_OR(DT_DRV_INST(inst), maximum_speed, \ + NUMAKER_USBD_SPEED_IDX_DEFAULT), \ }; \ \ static struct numaker_usbd_ep \ diff --git a/dts/arm/nuvoton/m46x.dtsi b/dts/arm/nuvoton/m46x.dtsi index 98b0ad551a2c..eef431800874 100644 --- a/dts/arm/nuvoton/m46x.dtsi +++ b/dts/arm/nuvoton/m46x.dtsi @@ -615,6 +615,19 @@ disallow-iso-in-out-same-number; }; + hsusbd: hsusbd@40019000 { + compatible = "nuvoton,numaker-hsusbd"; + reg = <0x40019000 0x1000>; + interrupts = <65 0>; + resets = <&rst NUMAKER_HSUSBD_RST>; + clocks = <&pcc NUMAKER_HSUSBD_MODULE NUMAKER_MODULE_NoMsk + NUMAKER_MODULE_NoMsk>; + dma-buffer-size = <4096>; + status = "disabled"; + /* 2 more for Control OUT/IN */ + num-bidir-endpoints = <14>; + }; + wwdt: watchdog@40040100 { compatible = "nuvoton,numaker-wwdt"; reg = <0x40040100 0x10>; diff --git a/dts/bindings/usb/nuvoton,numaker-hsusbd.yaml b/dts/bindings/usb/nuvoton,numaker-hsusbd.yaml new file mode 100644 index 000000000000..c49dc2b64afc --- /dev/null +++ b/dts/bindings/usb/nuvoton,numaker-hsusbd.yaml @@ -0,0 +1,27 @@ +# Copyright (c) 2022 Nuvoton Technology Corporation +# SPDX-License-Identifier: Apache-2.0 + +description: Nuvoton NuMaker high-speed USB 2.0 device controller + +compatible: "nuvoton,numaker-hsusbd" + +include: [usb-ep.yaml, reset-device.yaml, pinctrl-device.yaml] + +properties: + reg: + required: true + + interrupts: + required: true + + resets: + required: true + + clocks: + required: true + + dma-buffer-size: + type: int + required: true + description: | + Size of DMA buffer in bytes From c502ef5b513af75a2b5f658a317c72ec153b5d6c Mon Sep 17 00:00:00 2001 From: Chun-Chieh Li Date: Mon, 22 Sep 2025 13:32:33 +0800 Subject: [PATCH 0446/3659] drivers: usb: udc: numaker: support HSUSBD DMA Add DMA support for Nuvoton NuMaker M46X high-speed USB 2.0 device controller. Signed-off-by: Chun-Chieh Li --- drivers/usb/udc/Kconfig.numaker | 14 +++++ drivers/usb/udc/udc_numaker.c | 93 +++++++++++++++++++++++++++++++-- 2 files changed, 104 insertions(+), 3 deletions(-) diff --git a/drivers/usb/udc/Kconfig.numaker b/drivers/usb/udc/Kconfig.numaker index 64de929cf4fc..f1488456a930 100644 --- a/drivers/usb/udc/Kconfig.numaker +++ b/drivers/usb/udc/Kconfig.numaker @@ -31,4 +31,18 @@ config UDC_NUMAKER_THREAD_PRIORITY help Priority of the driver internal thread. +config UDC_NUMAKER_DMA + bool "UDC NuMaker DMA support" + default y + depends on DT_HAS_NUVOTON_NUMAKER_HSUSBD_ENABLED + help + This enables DMA transfer between user buffer and USB buffer. + +config UDC_NUMAKER_DMA_TIMEOUT_MS + int "UDC NuMaker DMA timeout" + default 2000 + depends on UDC_NUMAKER_DMA + help + This configures timeout of DMA transfer in milliseconds. + endif # UDC_NUMAKER diff --git a/drivers/usb/udc/udc_numaker.c b/drivers/usb/udc/udc_numaker.c index 0ae73f6a082d..747461d5b2d6 100644 --- a/drivers/usb/udc/udc_numaker.c +++ b/drivers/usb/udc/udc_numaker.c @@ -217,6 +217,10 @@ struct udc_numaker_data { * as allocate request. Manually track it instead. */ uint32_t ctrlout_tailroom; + +#if defined(CONFIG_UDC_NUMAKER_DMA) + struct k_sem sem_dma_done; +#endif }; static inline void numaker_usbd_sw_connect(const struct device *dev) @@ -243,7 +247,10 @@ static inline void numaker_usbd_sw_connect(const struct device *dev) /* Enable relevant interrupts */ base->GINTEN = HSUSBD_GINTEN_CEPIEN_Msk | HSUSBD_GINTEN_USBIEN_Msk; - base->BUSINTEN = HSUSBD_BUSINTEN_VBUSDETIEN_Msk | HSUSBD_BUSINTEN_SUSPENDIEN_Msk | + base->BUSINTEN = HSUSBD_BUSINTEN_VBUSDETIEN_Msk | + IF_ENABLED(CONFIG_UDC_NUMAKER_DMA, + (HSUSBD_BUSINTEN_DMADONEIEN_Msk |)) /* DMA */ + HSUSBD_BUSINTEN_SUSPENDIEN_Msk | HSUSBD_BUSINTEN_RESUMEIEN_Msk | HSUSBD_BUSINTEN_RSTIEN_Msk | COND_CODE_1(CONFIG_UDC_ENABLE_SOF, (HSUSBD_BUSINTEN_SOFIEN_Msk), (0)); /* CPU load concern */ @@ -410,8 +417,8 @@ static int numaker_usbd_enable_usb_phy(const struct device *dev) base->ATTR |= USBD_ATTR_USBEN_Msk | USBD_ATTR_PHYEN_Msk; #elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) base->PHYCTL |= HSUSBD_PHYCTL_PHYEN_Msk; - WAIT_FOR(base->PHYCTL & HSUSBD_PHYCTL_PHYCLKSTB_Msk, - NUMAKER_HSUSBD_PHY_STABLE_TIMEOUT_US, ;); + WAIT_FOR(base->PHYCTL & HSUSBD_PHYCTL_PHYCLKSTB_Msk, NUMAKER_HSUSBD_PHY_STABLE_TIMEOUT_US, + ;); if (!(base->PHYCTL & HSUSBD_PHYCTL_PHYCLKSTB_Msk)) { return -EIO; } @@ -971,6 +978,59 @@ static void numaker_usbd_setup_copy_to_user(const struct device *dev, uint8_t *u } #if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) +#if defined(CONFIG_UDC_NUMAKER_DMA) +/* Transfer data between user buffer and USB buffer by DMA + * + * size holds size to copy/copied on input/output + */ +static int numaker_hsusbd_ep_xfer_user_dma(struct numaker_usbd_ep *ep_cur, uint8_t *usrbuf, + uint32_t *size) +{ + const struct device *dev = ep_cur->dev; + const struct udc_numaker_config *config = dev->config; + struct udc_numaker_data *priv = udc_get_private(dev); + USBD_T *base = config->base; + int err; + + /* Reset DMA semaphore */ + k_sem_reset(&priv->sem_dma_done); + + /* Reset DMA */ + base->DMACNT = 0; + base->DMACTL = HSUSBD_DMACTL_DMARST_Msk; + base->DMACTL = 0; + base->BUSINTSTS = HSUSBD_BUSINTSTS_DMADONEIF_Msk; + + /* DMA memory address */ + base->DMAADDR = (uint32_t)usrbuf; + + /* DMA transfer size */ + base->DMACNT = *size; + + /* DMA EP address */ + base->DMACTL = USB_EP_DIR_IS_IN(ep_cur->addr) + ? (HSUSBD_DMACTL_SVINEP_Msk | HSUSBD_DMACTL_DMARD_Msk) + : 0; + base->DMACTL |= USB_EP_GET_IDX(ep_cur->addr) << HSUSBD_DMACTL_EPNUM_Pos; + + /* Start DMA */ + base->DMACTL |= HSUSBD_DMACTL_DMAEN_Msk; + + /* Wait for DMA done */ + err = k_sem_take(&priv->sem_dma_done, K_MSEC(CONFIG_UDC_NUMAKER_DMA_TIMEOUT_MS)); + if (err != 0) { + err = -EIO; + + /* Abort DMA for safe */ + base->DMACNT = 0; + base->DMACTL = HSUSBD_DMACTL_DMARST_Msk; + base->DMACTL = 0; + } + + return err; +} +#endif + /* Copy data to user buffer * * size holds size to copy/copied on input/output @@ -996,6 +1056,13 @@ static int numaker_hsusbd_ep_copy_to_user(struct numaker_usbd_ep *ep_cur, uint8_ *size -= rmn; } else { +#if defined(CONFIG_UDC_NUMAKER_DMA) + int err = numaker_hsusbd_ep_xfer_user_dma(ep_cur, usrbuf, size); + + if (err < 0) { + return err; + } +#else uint8_t *usrbuf_pos = usrbuf; uint32_t rmn = *size; @@ -1005,6 +1072,7 @@ static int numaker_hsusbd_ep_copy_to_user(struct numaker_usbd_ep *ep_cur, uint8_ } *size -= rmn; +#endif } return 0; @@ -1035,6 +1103,13 @@ static int numaker_hsusbd_ep_copy_from_user(struct numaker_usbd_ep *ep_cur, cons *size -= rmn; } else { +#if defined(CONFIG_UDC_NUMAKER_DMA) + int err = numaker_hsusbd_ep_xfer_user_dma(ep_cur, (uint8_t *)usrbuf, size); + + if (err < 0) { + return err; + } +#else const uint8_t *usrbuf_pos = usrbuf; uint32_t rmn = *size; @@ -1044,6 +1119,7 @@ static int numaker_hsusbd_ep_copy_from_user(struct numaker_usbd_ep *ep_cur, cons } *size -= rmn; +#endif } return 0; @@ -2326,6 +2402,13 @@ static void numaker_usbd_isr(const struct device *dev) numaker_usbd_sof_th(dev); } + /* DMA done */ +#if defined(CONFIG_UDC_NUMAKER_DMA) + if (busintsts & HSUSBD_BUSINTSTS_DMADONEIF_Msk) { + k_sem_give(&priv->sem_dma_done); + } +#endif + /* USB CEP */ if (cepintsts) { /* Clear event flag */ @@ -2740,6 +2823,10 @@ static int udc_numaker_driver_preinit(const struct device *dev) config->make_thread(dev); +#if defined(CONFIG_UDC_NUMAKER_DMA) + k_sem_init(&priv->sem_dma_done, 0, 1); +#endif + return 0; } From d288a29979035b0e06f1c2c3e43e39174d87bccb Mon Sep 17 00:00:00 2001 From: Chun-Chieh Li Date: Wed, 20 Aug 2025 17:37:52 +0800 Subject: [PATCH 0447/3659] drivers: usb: udc: numaker: support NuMaker M55M1X HSUSBD Add support for Nuvoton NuMaker M55M1X high-speed USB 2.0 device controller. Compared to M46X HSUSBD, M55M1X HSUSBD introduces some differences: - DMA must handle cache coherency because net_buf can be cache-able - USB suspend interrupt becomes continuous. Aavoid being locked by this interrupt and forward this message just once - New register bit HSUSBD_OPER_HISHSEN_Msk, which controls to enable USB handshake Signed-off-by: Chun-Chieh Li --- drivers/usb/udc/udc_numaker.c | 62 ++++++++++++++++++++++++++++++++--- dts/arm/nuvoton/m55m1x.dtsi | 12 +++++++ 2 files changed, 70 insertions(+), 4 deletions(-) diff --git a/drivers/usb/udc/udc_numaker.c b/drivers/usb/udc/udc_numaker.c index 747461d5b2d6..619491f44632 100644 --- a/drivers/usb/udc/udc_numaker.c +++ b/drivers/usb/udc/udc_numaker.c @@ -11,6 +11,7 @@ #include #include #include +#include #include LOG_MODULE_REGISTER(udc_numaker, CONFIG_UDC_DRIVER_LOG_LEVEL); @@ -64,9 +65,15 @@ BUILD_ASSERT(!(DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) && /* USBD controller does not support DMA, and PHY does not require a delay after reset. */ +#if defined(CONFIG_SOC_SERIES_M46X) #if !defined(USBD_ATTR_PWRDN_Msk) #define USBD_ATTR_PWRDN_Msk BIT(9) #endif +#elif defined(CONFIG_SOC_SERIES_M55M1X) +#if !defined(SYS_USBPHY_USBROLE_STD_USBD) +#define SYS_USBPHY_USBROLE_STD_USBD (0x0 << SYS_USBPHY_USBROLE_Pos) +#endif +#endif #elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) @@ -85,6 +92,15 @@ BUILD_ASSERT(!(DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) && /* Wait for USB/PHY stable timeout 100 ms */ #define NUMAKER_HSUSBD_PHY_STABLE_TIMEOUT_US 100000 +#if defined(CONFIG_SOC_SERIES_M46X) +#define CEPBUFSTART CEPBUFST +#define EPBUFSTART EPBUFST +#elif defined(CONFIG_SOC_SERIES_M55M1X) +#if !defined(SYS_USBPHY_HSUSBROLE_STD_USBD) +#define SYS_USBPHY_HSUSBROLE_STD_USBD (0x0 << SYS_USBPHY_HSUSBROLE_Pos) +#endif +#endif + #endif enum numaker_usbd_msg_type { @@ -258,6 +274,16 @@ static inline void numaker_usbd_sw_connect(const struct device *dev) HSUSBD_CEPINTEN_STALLIEN_Msk | HSUSBD_CEPINTEN_SETUPPKIEN_Msk | HSUSBD_CEPINTEN_SETUPTKIEN_Msk; + /* Enable USB handshake + * + * Being unset, USB handshake won't start, including bus events + * reset/suspend/resume. Per test, this bit also takes effect + * for full-speed; + */ +#if defined(HSUSBD_OPER_HISHSEN_Msk) + base->OPER |= HSUSBD_OPER_HISHSEN_Msk; +#endif + /* Clear SE0 for connect */ base->PHYCTL |= HSUSBD_PHYCTL_DPPUEN_Msk; #endif @@ -452,14 +478,23 @@ static int numaker_usbd_hw_setup(const struct device *dev) (SYS_USBPHY_USBROLE_STD_USBD | SYS_USBPHY_USBEN_Msk | SYS_USBPHY_SBO_Msk); #elif defined(CONFIG_SOC_SERIES_M55M1X) SYS->USBPHY = (SYS->USBPHY & ~SYS_USBPHY_USBROLE_Msk) | - ((0 << SYS_USBPHY_USBROLE_Pos) | SYS_USBPHY_OTGPHYEN_Msk); + (SYS_USBPHY_USBROLE_STD_USBD | SYS_USBPHY_OTGPHYEN_Msk); #endif #elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) +#if defined(CONFIG_SOC_SERIES_M46X) /* Configure HSUSB role as USB Device and enable HSUSB/PHY */ SYS->USBPHY = (SYS->USBPHY & ~(SYS_USBPHY_HSUSBROLE_Msk | SYS_USBPHY_HSUSBACT_Msk)) | (SYS_USBPHY_HSUSBROLE_STD_USBD | SYS_USBPHY_HSUSBEN_Msk | SYS_USBPHY_SBO_Msk); k_sleep(K_USEC(NUMAKER_HSUSBD_PHY_RESET_US)); SYS->USBPHY |= SYS_USBPHY_HSUSBACT_Msk; +#elif defined(CONFIG_SOC_SERIES_M55M1X) + /* Configure HSUSB role as USB Device and enable HSUSB/PHY */ + SYS->USBPHY = (SYS->USBPHY & ~(SYS_USBPHY_HSUSBROLE_Msk | SYS_USBPHY_HSUSBACT_Msk)) | + (SYS_USBPHY_HSUSBROLE_STD_USBD | SYS_USBPHY_HSOTGPHYEN_Msk); + k_sleep(K_USEC(NUMAKER_HSUSBD_PHY_RESET_US)); + SYS->USBPHY |= SYS_USBPHY_HSUSBACT_Msk; +#endif + #endif /* Invoke Clock controller to enable module clock */ @@ -536,7 +571,6 @@ static int numaker_usbd_hw_setup(const struct device *dev) /* Initialize IRQ */ config->irq_config_func(dev); - cleanup: SYS_LockReg(); @@ -1013,6 +1047,13 @@ static int numaker_hsusbd_ep_xfer_user_dma(struct numaker_usbd_ep *ep_cur, uint8 : 0; base->DMACTL |= USB_EP_GET_IDX(ep_cur->addr) << HSUSBD_DMACTL_EPNUM_Pos; + /* Cache coherency */ + if (USB_EP_DIR_IS_IN(ep_cur->addr)) { + sys_cache_data_flush_range(usrbuf, *size); + } else { + sys_cache_data_invd_range(usrbuf, *size); + } + /* Start DMA */ base->DMACTL |= HSUSBD_DMACTL_DMAEN_Msk; @@ -1228,10 +1269,10 @@ static void numaker_usbd_ep_config_dmabuf(struct numaker_usbd_ep *ep_cur, uint32 ep_base->BUFSEG = dmabuf_base; #elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) if (ep_cur->ep_hw_idx == CEP) { - base->CEPBUFST = dmabuf_base; + base->CEPBUFSTART = dmabuf_base; base->CEPBUFEND = dmabuf_base + dmabuf_size - 1ul; } else { - ep_base->EPBUFST = dmabuf_base; + ep_base->EPBUFSTART = dmabuf_base; ep_base->EPBUFEND = dmabuf_base + dmabuf_size - 1ul; } #endif @@ -2382,6 +2423,19 @@ static void numaker_usbd_isr(const struct device *dev) } } + /* Managed USB suspend interrupt + * + * For HSUSBD, on some chips e.g. M55M1, the semantics of USB suspend flag + * is state rather than event. To prevent CPU from overwhelming by this + * interrupt continuously, make it alarm one-shot instead of continuous. + */ + if (busintsts & (HSUSBD_BUSINTSTS_RSTIF_Msk | HSUSBD_BUSINTSTS_RESUMEIF_Msk)) { + busintsts &= ~HSUSBD_BUSINTSTS_SUSPENDIF_Msk; + base->BUSINTEN |= HSUSBD_BUSINTEN_SUSPENDIEN_Msk; + } else if (busintsts & HSUSBD_BUSINTSTS_SUSPENDIF_Msk) { + base->BUSINTEN &= ~HSUSBD_BUSINTEN_SUSPENDIEN_Msk; + } + /* USB reset */ if (busintsts & HSUSBD_BUSINTSTS_RSTIF_Msk) { numaker_usbd_bus_reset_th(dev); diff --git a/dts/arm/nuvoton/m55m1x.dtsi b/dts/arm/nuvoton/m55m1x.dtsi index 1f413667fd0a..10995de2340b 100644 --- a/dts/arm/nuvoton/m55m1x.dtsi +++ b/dts/arm/nuvoton/m55m1x.dtsi @@ -475,6 +475,18 @@ disallow-iso-in-out-same-number; }; + hsusbd: hsusbd@40205000 { + compatible = "nuvoton,numaker-hsusbd"; + reg = <0x40205000 0x1000>; + interrupts = <61 0>; + resets = <&rst NUMAKER_SYS_HSUSBD0RST>; + clocks = <&pcc NUMAKER_HSUSBD0_MODULE 0 0>; + dma-buffer-size = <8192>; + status = "disabled"; + /* 2 more for Control OUT/IN */ + num-bidir-endpoints = <20>; + }; + wwdt: watchdog@40240000 { compatible = "nuvoton,numaker-wwdt"; reg = <0x40240000 0x10>; From 3b635196ee8b29bfb1d17c7fa17bf1792bc7e0c9 Mon Sep 17 00:00:00 2001 From: Chun-Chieh Li Date: Tue, 23 Sep 2025 17:01:31 +0800 Subject: [PATCH 0448/3659] drivers: usb: udc: numaker: support USBD/HSUSBD simultaneously Re-organize to add support for USBD/HSUSBD which can be enabled at the same time Signed-off-by: Chun-Chieh Li --- drivers/usb/udc/udc_numaker.c | 1104 +++++++++++++++++++-------------- 1 file changed, 629 insertions(+), 475 deletions(-) diff --git a/drivers/usb/udc/udc_numaker.c b/drivers/usb/udc/udc_numaker.c index 619491f44632..ee089f93e147 100644 --- a/drivers/usb/udc/udc_numaker.c +++ b/drivers/usb/udc/udc_numaker.c @@ -30,24 +30,6 @@ LOG_MODULE_REGISTER(udc_numaker, CONFIG_UDC_DRIVER_LOG_LEVEL); * to generate necessary 48MHz. */ -/* Not support USBD/HSUSBD simultaneously - * - * The code is re-organized to implement both usbd and hsusbd in single - * source file. Multiple instances of either usbd or hsusbd are supported, - * but usbd and hsusbd cannot support simultaneously. This limitation is - * for easy implementation with just single source file, assuming that real - * application just needs one usb device type. - */ -BUILD_ASSERT(!(DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) && - DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd)), - "NOT SUPPORT USBD/HSUSBD simultaneously"); - -#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) -#define DT_DRV_COMPAT nuvoton_numaker_usbd -#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) -#define DT_DRV_COMPAT nuvoton_numaker_hsusbd -#endif - /* For bus reset, keep 'SE0' (USB spec: SE0 >= 2.5 ms) */ #define NUMAKER_USBD_BUS_RESET_DRV_SE0_US 3000 @@ -59,10 +41,6 @@ BUILD_ASSERT(!(DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) && #define NUMAKER_USBD_DMABUF_SIZE_CTRLOUT 64 #define NUMAKER_USBD_DMABUF_SIZE_CTRLIN 64 -#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) - -#define NUMAKER_USBD_SPEED_IDX_DEFAULT 1 - /* USBD controller does not support DMA, and PHY does not require a delay after reset. */ #if defined(CONFIG_SOC_SERIES_M46X) @@ -75,19 +53,11 @@ BUILD_ASSERT(!(DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) && #endif #endif -#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) - -#define NUMAKER_USBD_SPEED_IDX_DEFAULT 2 - -/* Redefine to reuse code for HSUSBD */ -#define USBD_T HSUSBD_T -#define USBD_EP_T HSUSBD_EP_T - /* Per HSUSBD H/W spec, after setting HSUSBEN to enable HSUSB/PHY, user * should keep HSUSB/PHY at reset mode at lease 10us before changing to * active mode. */ -#define NUMAKER_HSUSBD_PHY_RESET_US 10 +#define NUMAKER_HSUSBD_PHY_RESET_US 10 /* Wait for USB/PHY stable timeout 100 ms */ #define NUMAKER_HSUSBD_PHY_STABLE_TIMEOUT_US 100000 @@ -101,8 +71,6 @@ BUILD_ASSERT(!(DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) && #endif #endif -#endif - enum numaker_usbd_msg_type { /* Device plug-in */ NUMAKER_USBD_MSG_TYPE_ATTACH, @@ -149,24 +117,20 @@ struct numaker_usbd_ep { const struct device *dev; /* Pointer to the containing device */ - int32_t ep_hw_idx; /* BSP USBD/HSUSBD driver EP index, e.g. EP0/EPA, EP1/EPB, etc. */ - uint32_t ep_hw_cfg; /* BSP USBD/HSUSBD driver EP configuration */ -#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) - uint32_t ep_hw_rspctl; -#endif + int32_t ep_hw_idx; /* BSP USBD/HSUSBD driver EP index, e.g. EP0/EPA, EP1/EPB, etc. */ + uint32_t ep_hw_cfg; /* BSP USBD/HSUSBD driver EP configuration */ + uint32_t ep_hw_rspctl; /* BSP HSUSBD driver RSPCTL */ /* EP DMA buffer */ bool dmabuf_valid; uint32_t dmabuf_base; uint32_t dmabuf_size; -#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) /* NOTE: On USBD, Setup and CTRL OUT are not completely separated. CTRL OUT MXPLD * can be overridden to 8 by next Setup. To overcome it, we make one copy of CTRL * OUT MXPLD immediately on its interrupt. */ uint32_t mxpld_ctrlout; -#endif /* EP address */ bool addr_valid; @@ -183,7 +147,7 @@ struct udc_numaker_config { struct udc_ep_config *ep_cfg_in; uint32_t ep_cfg_out_size; uint32_t ep_cfg_in_size; - USBD_T *base; + void *base; const struct reset_dt_spec reset; uint32_t clk_modidx; uint32_t clk_src; @@ -196,6 +160,7 @@ struct udc_numaker_config { bool disallow_iso_inout_same; int speed_idx; void (*make_thread)(const struct device *dev); + bool is_hsusbd; }; /* EP H/W context manager */ @@ -242,64 +207,71 @@ struct udc_numaker_data { static inline void numaker_usbd_sw_connect(const struct device *dev) { const struct udc_numaker_config *config = dev->config; - USBD_T *base = config->base; -#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) - /* Clear all interrupts first for clean */ - base->INTSTS = base->INTSTS; - - /* Enable relevant interrupts */ - base->INTEN = USBD_INT_BUS | USBD_INT_USB | USBD_INT_FLDET | - IF_ENABLED(CONFIG_UDC_ENABLE_SOF, (USBD_INT_SOF |)) /* CPU load concern */ - USBD_INT_WAKEUP; - - /* Clear SE0 for connect */ - base->ATTR |= USBD_ATTR_DPPUEN_Msk; - base->SE0 &= ~USBD_DRVSE0; -#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) - /* Clear all interrupts first for clean */ - base->BUSINTSTS = base->BUSINTSTS; - base->CEPINTSTS = base->CEPINTSTS; - - /* Enable relevant interrupts */ - base->GINTEN = HSUSBD_GINTEN_CEPIEN_Msk | HSUSBD_GINTEN_USBIEN_Msk; - base->BUSINTEN = HSUSBD_BUSINTEN_VBUSDETIEN_Msk | - IF_ENABLED(CONFIG_UDC_NUMAKER_DMA, - (HSUSBD_BUSINTEN_DMADONEIEN_Msk |)) /* DMA */ - HSUSBD_BUSINTEN_SUSPENDIEN_Msk | - HSUSBD_BUSINTEN_RESUMEIEN_Msk | HSUSBD_BUSINTEN_RSTIEN_Msk | - COND_CODE_1(CONFIG_UDC_ENABLE_SOF, (HSUSBD_BUSINTEN_SOFIEN_Msk), - (0)); /* CPU load concern */ - base->CEPINTEN = HSUSBD_CEPINTEN_STSDONEIEN_Msk | HSUSBD_CEPINTEN_ERRIEN_Msk | - HSUSBD_CEPINTEN_STALLIEN_Msk | HSUSBD_CEPINTEN_SETUPPKIEN_Msk | - HSUSBD_CEPINTEN_SETUPTKIEN_Msk; - - /* Enable USB handshake - * - * Being unset, USB handshake won't start, including bus events - * reset/suspend/resume. Per test, this bit also takes effect - * for full-speed; - */ + if (config->is_hsusbd) { + HSUSBD_T *base = config->base; + + /* Clear all interrupts first for clean */ + base->BUSINTSTS = base->BUSINTSTS; + base->CEPINTSTS = base->CEPINTSTS; + + /* Enable relevant interrupts */ + base->GINTEN = HSUSBD_GINTEN_CEPIEN_Msk | HSUSBD_GINTEN_USBIEN_Msk; + base->BUSINTEN = HSUSBD_BUSINTEN_VBUSDETIEN_Msk | + IF_ENABLED(CONFIG_UDC_NUMAKER_DMA, + (HSUSBD_BUSINTEN_DMADONEIEN_Msk |)) /* DMA */ + HSUSBD_BUSINTEN_SUSPENDIEN_Msk | + HSUSBD_BUSINTEN_RESUMEIEN_Msk | HSUSBD_BUSINTEN_RSTIEN_Msk | + COND_CODE_1(CONFIG_UDC_ENABLE_SOF, (HSUSBD_BUSINTEN_SOFIEN_Msk), + (0)); /* CPU load concern */ + base->CEPINTEN = HSUSBD_CEPINTEN_STSDONEIEN_Msk | HSUSBD_CEPINTEN_ERRIEN_Msk | + HSUSBD_CEPINTEN_STALLIEN_Msk | HSUSBD_CEPINTEN_SETUPPKIEN_Msk | + HSUSBD_CEPINTEN_SETUPTKIEN_Msk; + + /* Enable USB handshake + * + * Being unset, USB handshake won't start, including bus events + * reset/suspend/resume. Per test, this bit also takes effect + * for full-speed; + */ #if defined(HSUSBD_OPER_HISHSEN_Msk) - base->OPER |= HSUSBD_OPER_HISHSEN_Msk; + base->OPER |= HSUSBD_OPER_HISHSEN_Msk; #endif - /* Clear SE0 for connect */ - base->PHYCTL |= HSUSBD_PHYCTL_DPPUEN_Msk; -#endif + /* Clear SE0 for connect */ + base->PHYCTL |= HSUSBD_PHYCTL_DPPUEN_Msk; + } else { + USBD_T *base = config->base; + + /* Clear all interrupts first for clean */ + base->INTSTS = base->INTSTS; + + /* Enable relevant interrupts */ + base->INTEN = USBD_INT_BUS | USBD_INT_USB | USBD_INT_FLDET | + IF_ENABLED(CONFIG_UDC_ENABLE_SOF, + (USBD_INT_SOF |)) /* CPU load concern */ + USBD_INT_WAKEUP; + + /* Clear SE0 for connect */ + base->ATTR |= USBD_ATTR_DPPUEN_Msk; + base->SE0 &= ~USBD_DRVSE0; + } } static inline void numaker_usbd_sw_disconnect(const struct device *dev) { const struct udc_numaker_config *config = dev->config; - USBD_T *base = config->base; /* Set SE0 for disconnect */ -#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) - base->SE0 |= USBD_DRVSE0; -#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) - base->PHYCTL &= ~HSUSBD_PHYCTL_DPPUEN_Msk; -#endif + if (config->is_hsusbd) { + HSUSBD_T *base = config->base; + + base->PHYCTL &= ~HSUSBD_PHYCTL_DPPUEN_Msk; + } else { + USBD_T *base = config->base; + + base->SE0 |= USBD_DRVSE0; + } } static inline void numaker_usbd_sw_reconnect(const struct device *dev) @@ -314,9 +286,17 @@ static inline void numaker_usbd_reset_addr(const struct device *dev) { const struct udc_numaker_config *config = dev->config; struct udc_numaker_data *priv = udc_get_private(dev); - USBD_T *base = config->base; - base->FADDR = 0; + if (config->is_hsusbd) { + HSUSBD_T *base = config->base; + + base->FADDR = 0; + } else { + USBD_T *base = config->base; + + base->FADDR = 0; + } + priv->addr = 0; } @@ -324,24 +304,39 @@ static inline void numaker_usbd_set_addr(const struct device *dev) { const struct udc_numaker_config *config = dev->config; struct udc_numaker_data *priv = udc_get_private(dev); - USBD_T *base = config->base; - if (base->FADDR != priv->addr) { - base->FADDR = priv->addr; + if (config->is_hsusbd) { + HSUSBD_T *base = config->base; + + if (base->FADDR != priv->addr) { + base->FADDR = priv->addr; + } + } else { + USBD_T *base = config->base; + + if (base->FADDR != priv->addr) { + base->FADDR = priv->addr; + } } } /* USBD/HSUSBD EP base by EP index e.g. EP0/EPA, EP1/EPB, etc. */ -static inline USBD_EP_T *numaker_usbd_ep_base(const struct device *dev, uint32_t ep_hw_idx) +static inline void *numaker_usbd_ep_base(const struct device *dev, uint32_t ep_hw_idx) { const struct udc_numaker_config *config = dev->config; - USBD_T *base = config->base; + void *ep_base; -#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) - return base->EP + (ep_hw_idx - EP0); -#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) - return (ep_hw_idx == CEP) ? NULL : base->EP + (ep_hw_idx - EPA); -#endif + if (config->is_hsusbd) { + HSUSBD_T *base = config->base; + + ep_base = (ep_hw_idx == CEP) ? NULL : base->EP + (ep_hw_idx - EPA); + } else { + USBD_T *base = config->base; + + ep_base = base->EP + (ep_hw_idx - EP0); + } + + return ep_base; } static inline void numaker_usbd_ep_sync_udc_halt(struct numaker_usbd_ep *ep_cur, bool stalled) @@ -358,24 +353,27 @@ static inline void numaker_usbd_ep_set_stall(struct numaker_usbd_ep *ep_cur) { const struct device *dev = ep_cur->dev; const struct udc_numaker_config *config = dev->config; - __maybe_unused USBD_T *base = config->base; - USBD_EP_T *ep_base = numaker_usbd_ep_base(dev, ep_cur->ep_hw_idx); /* Set EP to stalled */ -#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) - ep_base->CFGP |= USBD_CFGP_SSTALL_Msk; - numaker_usbd_ep_sync_udc_halt(ep_cur, true); -#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) - if (ep_cur->ep_hw_idx == CEP) { - base->CEPCTL = HSUSBD_CEPCTL_STALL; + if (config->is_hsusbd) { + HSUSBD_T *base = config->base; + HSUSBD_EP_T *ep_base = numaker_usbd_ep_base(dev, ep_cur->ep_hw_idx); + + if (ep_cur->ep_hw_idx == CEP) { + base->CEPCTL = HSUSBD_CEPCTL_STALL; + } else { + uint32_t eprspctl = ep_base->EPRSPCTL; + + eprspctl &= ~(HSUSBD_EPRSPCTL_HALT_Msk | HSUSBD_EPRSPCTL_TOGGLE_Msk); + eprspctl |= HSUSBD_EP_RSPCTL_HALT; + ep_base->EPRSPCTL = eprspctl; + } } else { - uint32_t eprspctl = ep_base->EPRSPCTL; + USBD_EP_T *ep_base = numaker_usbd_ep_base(dev, ep_cur->ep_hw_idx); - eprspctl &= ~(HSUSBD_EPRSPCTL_HALT_Msk | HSUSBD_EPRSPCTL_TOGGLE_Msk); - eprspctl |= HSUSBD_EP_RSPCTL_HALT; - ep_base->EPRSPCTL = eprspctl; + ep_base->CFGP |= USBD_CFGP_SSTALL_Msk; + numaker_usbd_ep_sync_udc_halt(ep_cur, true); } -#endif } /* Reset EP to unstalled and data toggle bit to 0 */ @@ -383,29 +381,32 @@ static inline void numaker_usbd_ep_clear_stall_n_data_toggle(struct numaker_usbd { const struct device *dev = ep_cur->dev; const struct udc_numaker_config *config = dev->config; - __maybe_unused USBD_T *base = config->base; - USBD_EP_T *ep_base = numaker_usbd_ep_base(dev, ep_cur->ep_hw_idx); -#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) - /* Reset EP to unstalled */ - ep_base->CFGP &= ~USBD_CFGP_SSTALL_Msk; - numaker_usbd_ep_sync_udc_halt(ep_cur, false); + if (config->is_hsusbd) { + HSUSBD_T *base = config->base; + HSUSBD_EP_T *ep_base = numaker_usbd_ep_base(dev, ep_cur->ep_hw_idx); - /* Reset EP data toggle bit to 0 */ - ep_base->CFG &= ~USBD_CFG_DSQSYNC_Msk; -#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) - if (ep_cur->ep_hw_idx == CEP) { - /* Reset EP to unstalled and H/W will care toggle bit reset */ - base->CEPCTL = 0; + if (ep_cur->ep_hw_idx == CEP) { + /* Reset EP to unstalled and H/W will care toggle bit reset */ + base->CEPCTL = 0; + } else { + /* Reset EP to unstalled and its data toggle bit to 0 */ + uint32_t eprspctl = ep_base->EPRSPCTL; + + eprspctl &= ~(HSUSBD_EPRSPCTL_HALT_Msk | HSUSBD_EPRSPCTL_TOGGLE_Msk); + eprspctl |= HSUSBD_EP_RSPCTL_TOGGLE; + ep_base->EPRSPCTL = eprspctl; + } } else { - /* Reset EP to unstalled and its data toggle bit to 0 */ - uint32_t eprspctl = ep_base->EPRSPCTL; + USBD_EP_T *ep_base = numaker_usbd_ep_base(dev, ep_cur->ep_hw_idx); - eprspctl &= ~(HSUSBD_EPRSPCTL_HALT_Msk | HSUSBD_EPRSPCTL_TOGGLE_Msk); - eprspctl |= HSUSBD_EP_RSPCTL_TOGGLE; - ep_base->EPRSPCTL = eprspctl; + /* Reset EP to unstalled */ + ep_base->CFGP &= ~USBD_CFGP_SSTALL_Msk; + numaker_usbd_ep_sync_udc_halt(ep_cur, false); + + /* Reset EP data toggle bit to 0 */ + ep_base->CFG &= ~USBD_CFG_DSQSYNC_Msk; } -#endif } static int numaker_usbd_send_msg(const struct device *dev, const struct numaker_usbd_msg *msg) @@ -437,18 +438,22 @@ static int numaker_usbd_send_msg(const struct device *dev, const struct numaker_ static int numaker_usbd_enable_usb_phy(const struct device *dev) { const struct udc_numaker_config *config = dev->config; - USBD_T *base = config->base; -#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) - base->ATTR |= USBD_ATTR_USBEN_Msk | USBD_ATTR_PHYEN_Msk; -#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) - base->PHYCTL |= HSUSBD_PHYCTL_PHYEN_Msk; - WAIT_FOR(base->PHYCTL & HSUSBD_PHYCTL_PHYCLKSTB_Msk, NUMAKER_HSUSBD_PHY_STABLE_TIMEOUT_US, - ;); - if (!(base->PHYCTL & HSUSBD_PHYCTL_PHYCLKSTB_Msk)) { - return -EIO; + if (config->is_hsusbd) { + HSUSBD_T *base = config->base; + + base->PHYCTL |= HSUSBD_PHYCTL_PHYEN_Msk; + WAIT_FOR(base->PHYCTL & HSUSBD_PHYCTL_PHYCLKSTB_Msk, + NUMAKER_HSUSBD_PHY_STABLE_TIMEOUT_US, + ;); + if (!(base->PHYCTL & HSUSBD_PHYCTL_PHYCLKSTB_Msk)) { + return -EIO; + } + } else { + USBD_T *base = config->base; + + base->ATTR |= USBD_ATTR_USBEN_Msk | USBD_ATTR_PHYEN_Msk; } -#endif return 0; } @@ -456,7 +461,6 @@ static int numaker_usbd_enable_usb_phy(const struct device *dev) static int numaker_usbd_hw_setup(const struct device *dev) { const struct udc_numaker_config *config = dev->config; - USBD_T *base = config->base; int err; struct numaker_scc_subsys scc_subsys; @@ -469,33 +473,37 @@ static int numaker_usbd_hw_setup(const struct device *dev) SYS_UnlockReg(); /* Configure USB role as USB Device and enable USB/PHY */ -#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) + if (config->is_hsusbd) { #if defined(CONFIG_SOC_SERIES_M46X) - SYS->USBPHY = (SYS->USBPHY & ~SYS_USBPHY_USBROLE_Msk) | - (SYS_USBPHY_USBROLE_STD_USBD | SYS_USBPHY_USBEN_Msk | SYS_USBPHY_SBO_Msk); -#elif defined(CONFIG_SOC_SERIES_M2L31X) - SYS->USBPHY = (SYS->USBPHY & ~SYS_USBPHY_USBROLE_Msk) | - (SYS_USBPHY_USBROLE_STD_USBD | SYS_USBPHY_USBEN_Msk | SYS_USBPHY_SBO_Msk); + /* Configure HSUSB role as USB Device and enable HSUSB/PHY */ + SYS->USBPHY = (SYS->USBPHY & + ~(SYS_USBPHY_HSUSBROLE_Msk | SYS_USBPHY_HSUSBACT_Msk)) | + (SYS_USBPHY_HSUSBROLE_STD_USBD | SYS_USBPHY_HSUSBEN_Msk | + SYS_USBPHY_SBO_Msk); + k_sleep(K_USEC(NUMAKER_HSUSBD_PHY_RESET_US)); + SYS->USBPHY |= SYS_USBPHY_HSUSBACT_Msk; #elif defined(CONFIG_SOC_SERIES_M55M1X) - SYS->USBPHY = (SYS->USBPHY & ~SYS_USBPHY_USBROLE_Msk) | - (SYS_USBPHY_USBROLE_STD_USBD | SYS_USBPHY_OTGPHYEN_Msk); + /* Configure HSUSB role as USB Device and enable HSUSB/PHY */ + SYS->USBPHY = (SYS->USBPHY & + ~(SYS_USBPHY_HSUSBROLE_Msk | SYS_USBPHY_HSUSBACT_Msk)) | + (SYS_USBPHY_HSUSBROLE_STD_USBD | SYS_USBPHY_HSOTGPHYEN_Msk); + k_sleep(K_USEC(NUMAKER_HSUSBD_PHY_RESET_US)); + SYS->USBPHY |= SYS_USBPHY_HSUSBACT_Msk; #endif -#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) + } else { #if defined(CONFIG_SOC_SERIES_M46X) - /* Configure HSUSB role as USB Device and enable HSUSB/PHY */ - SYS->USBPHY = (SYS->USBPHY & ~(SYS_USBPHY_HSUSBROLE_Msk | SYS_USBPHY_HSUSBACT_Msk)) | - (SYS_USBPHY_HSUSBROLE_STD_USBD | SYS_USBPHY_HSUSBEN_Msk | SYS_USBPHY_SBO_Msk); - k_sleep(K_USEC(NUMAKER_HSUSBD_PHY_RESET_US)); - SYS->USBPHY |= SYS_USBPHY_HSUSBACT_Msk; + SYS->USBPHY = (SYS->USBPHY & ~SYS_USBPHY_USBROLE_Msk) | + (SYS_USBPHY_USBROLE_STD_USBD | SYS_USBPHY_USBEN_Msk | + SYS_USBPHY_SBO_Msk); +#elif defined(CONFIG_SOC_SERIES_M2L31X) + SYS->USBPHY = (SYS->USBPHY & ~SYS_USBPHY_USBROLE_Msk) | + (SYS_USBPHY_USBROLE_STD_USBD | SYS_USBPHY_USBEN_Msk | + SYS_USBPHY_SBO_Msk); #elif defined(CONFIG_SOC_SERIES_M55M1X) - /* Configure HSUSB role as USB Device and enable HSUSB/PHY */ - SYS->USBPHY = (SYS->USBPHY & ~(SYS_USBPHY_HSUSBROLE_Msk | SYS_USBPHY_HSUSBACT_Msk)) | - (SYS_USBPHY_HSUSBROLE_STD_USBD | SYS_USBPHY_HSOTGPHYEN_Msk); - k_sleep(K_USEC(NUMAKER_HSUSBD_PHY_RESET_US)); - SYS->USBPHY |= SYS_USBPHY_HSUSBACT_Msk; -#endif - + SYS->USBPHY = (SYS->USBPHY & ~SYS_USBPHY_USBROLE_Msk) | + (SYS_USBPHY_USBROLE_STD_USBD | SYS_USBPHY_OTGPHYEN_Msk); #endif + } /* Invoke Clock controller to enable module clock */ memset(&scc_subsys, 0x00, sizeof(scc_subsys)); @@ -533,13 +541,17 @@ static int numaker_usbd_hw_setup(const struct device *dev) */ reset_line_toggle_dt(&config->reset); -#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) - /* Initialize USBD engine */ - /* NOTE: Per USBD spec, BIT(6) is hidden. */ - base->ATTR = USBD_ATTR_BYTEM_Msk | USBD_ATTR_PWRDN_Msk | BIT(6); -#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) - base->PHYCTL = 0; -#endif + if (config->is_hsusbd) { + HSUSBD_T *base = config->base; + + base->PHYCTL = 0; + } else { + USBD_T *base = config->base; + + /* Initialize USBD engine */ + /* NOTE: Per USBD spec, BIT(6) is hidden. */ + base->ATTR = USBD_ATTR_BYTEM_Msk | USBD_ATTR_PWRDN_Msk | BIT(6); + } err = numaker_usbd_enable_usb_phy(dev); if (err < 0) { LOG_ERR("Enable USB/PHY failed"); @@ -549,25 +561,27 @@ static int numaker_usbd_hw_setup(const struct device *dev) /* Set SE0 for S/W disconnect */ numaker_usbd_sw_disconnect(dev); -#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) - /* NOTE: Ignore DT maximum-speed with USBD fixed to full-speed */ -#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) - /* Initiate high-speed negotiation (chirp during reset) */ + if (config->is_hsusbd) { + HSUSBD_T *base = config->base; + + /* Initiate high-speed negotiation (chirp during reset) */ #if defined(CONFIG_UDC_DRIVER_HIGH_SPEED_SUPPORT_ENABLED) - switch (config->speed_idx) { - case 0: - case 1: - base->OPER &= ~HSUSBD_OPER_HISPDEN_Msk; - break; - case 2: - case 3: - default: - base->OPER |= HSUSBD_OPER_HISPDEN_Msk; - } + switch (config->speed_idx) { + case 0: + case 1: + base->OPER &= ~HSUSBD_OPER_HISPDEN_Msk; + break; + case 2: + case 3: + default: + base->OPER |= HSUSBD_OPER_HISPDEN_Msk; + } #else - base->OPER &= ~HSUSBD_OPER_HISPDEN_Msk; -#endif + base->OPER &= ~HSUSBD_OPER_HISPDEN_Msk; #endif + } else { + /* NOTE: Ignore DT maximum-speed with USBD fixed to full-speed */ + } /* Initialize IRQ */ config->irq_config_func(dev); @@ -581,7 +595,6 @@ static int numaker_usbd_hw_setup(const struct device *dev) static void numaker_usbd_hw_shutdown(const struct device *dev) { const struct udc_numaker_config *config = dev->config; - USBD_T *base = config->base; struct numaker_scc_subsys scc_subsys; SYS_UnlockReg(); @@ -593,11 +606,15 @@ static void numaker_usbd_hw_shutdown(const struct device *dev) numaker_usbd_sw_disconnect(dev); /* Disable USB/PHY */ -#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) - base->ATTR &= ~USBD_PHY_EN; -#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) - base->PHYCTL &= ~HSUSBD_PHYCTL_PHYEN_Msk; -#endif + if (config->is_hsusbd) { + HSUSBD_T *base = config->base; + + base->PHYCTL &= ~HSUSBD_PHYCTL_PHYEN_Msk; + } else { + USBD_T *base = config->base; + + base->ATTR &= ~USBD_PHY_EN; + } /* Invoke Clock controller to disable module clock */ memset(&scc_subsys, 0x00, sizeof(scc_subsys)); @@ -618,15 +635,16 @@ static void numaker_usbd_hw_shutdown(const struct device *dev) static void numaker_usbd_vbus_plug_th(const struct device *dev) { const struct udc_numaker_config *config = dev->config; - __maybe_unused USBD_T *base = config->base; struct numaker_usbd_msg msg = {0}; -#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) - /* Enable back USB/PHY */ - base->ATTR |= USBD_ATTR_USBEN_Msk | USBD_ATTR_PHYEN_Msk; -#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) - /* For HSUSBD, enable back USB/PHY will be done in bottom-half for needed wait. */ -#endif + if (config->is_hsusbd) { + /* For HSUSBD, enable back USB/PHY will be done in bottom-half for needed wait. */ + } else { + USBD_T *base = config->base; + + /* Enable back USB/PHY */ + base->ATTR |= USBD_ATTR_USBEN_Msk | USBD_ATTR_PHYEN_Msk; + } /* Message for bottom-half processing */ msg.type = NUMAKER_USBD_MSG_TYPE_ATTACH; @@ -639,15 +657,18 @@ static void numaker_usbd_vbus_plug_th(const struct device *dev) static void numaker_usbd_vbus_unplug_th(const struct device *dev) { const struct udc_numaker_config *config = dev->config; - USBD_T *base = config->base; -#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) - /* Disable USB */ - base->ATTR &= ~USBD_USB_EN; -#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) - /* Disable USB/PHY */ - base->PHYCTL &= ~HSUSBD_PHYCTL_PHYEN_Msk; -#endif + if (config->is_hsusbd) { + HSUSBD_T *base = config->base; + + /* Disable USB/PHY */ + base->PHYCTL &= ~HSUSBD_PHYCTL_PHYEN_Msk; + } else { + USBD_T *base = config->base; + + /* Disable USB */ + base->ATTR &= ~USBD_USB_EN; + } /* UDC stack would handle bottom-half processing */ udc_submit_event(dev, UDC_EVT_VBUS_REMOVED, 0); @@ -655,13 +676,11 @@ static void numaker_usbd_vbus_unplug_th(const struct device *dev) LOG_DBG("USB unplug"); } -#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) /* Interrupt top half processing for bus wakeup */ static void numaker_usbd_bus_wakeup_th(const struct device *dev) { LOG_DBG("USB wake-up"); } -#endif /* Interrupt top half processing for bus reset */ static void numaker_usbd_bus_reset_th(const struct device *dev) @@ -674,17 +693,12 @@ static void numaker_usbd_bus_reset_th(const struct device *dev) USBD_EP_T *ep_base; struct numaker_usbd_msg msg = {0}; -#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) /* Enable back USB/PHY */ base->ATTR |= USBD_ATTR_USBEN_Msk | USBD_ATTR_PHYEN_Msk; -#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) - /* For HSUSBD, enable back USB/PHY will be done in bottom-half for needed wait. */ -#endif for (; ep_cur != ep_end; ep_cur++) { ep_base = numaker_usbd_ep_base(dev, ep_cur->ep_hw_idx); -#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) /* For USBD, no separate EP interrupt control */ /* Cancel EP on-going transaction */ @@ -700,7 +714,33 @@ static void numaker_usbd_bus_reset_th(const struct device *dev) if (ep_cur->ep_hw_idx >= (EP0 + 2)) { ep_base->CFG = 0; } -#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) + } + + numaker_usbd_reset_addr(dev); + + /* Message for bottom-half processing */ + msg.type = NUMAKER_USBD_MSG_TYPE_RESET; + numaker_usbd_send_msg(dev, &msg); + + LOG_DBG("USB reset"); +} + +/* Interrupt top half processing for bus reset */ +static void numaker_hsusbd_bus_reset_th(const struct device *dev) +{ + const struct udc_numaker_config *config = dev->config; + HSUSBD_T *base = config->base; + struct udc_numaker_data *priv = udc_get_private(dev); + struct numaker_usbd_ep *ep_cur = priv->ep_pool; + struct numaker_usbd_ep *ep_end = priv->ep_pool + priv->ep_pool_size; + HSUSBD_EP_T *ep_base; + struct numaker_usbd_msg msg = {0}; + + /* For HSUSBD, enable back USB/PHY will be done in bottom-half for needed wait. */ + + for (; ep_cur != ep_end; ep_cur++) { + ep_base = numaker_usbd_ep_base(dev, ep_cur->ep_hw_idx); + if (ep_cur->ep_hw_idx == CEP) { /* Disable CEP interrupt (exclude Setup) */ base->CEPINTEN &= ~(HSUSBD_CEPINTEN_TXPKIEN_Msk | @@ -729,7 +769,6 @@ static void numaker_usbd_bus_reset_th(const struct device *dev) /* Disable all non-CTRL EPs */ ep_base->EPCFG &= ~HSUSBD_EPCFG_EPEN_Msk; } -#endif } numaker_usbd_reset_addr(dev); @@ -745,18 +784,19 @@ static void numaker_usbd_bus_reset_th(const struct device *dev) static void numaker_usbd_bus_suspend_th(const struct device *dev) { const struct udc_numaker_config *config = dev->config; - __maybe_unused USBD_T *base = config->base; -#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) - /* Enable USB but disable PHY */ - base->ATTR &= ~USBD_PHY_EN; -#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) - /* NOT disable USB/PHY - * - * For HSUSBD, unlike USBD, bus events (Reset/Suspend/Resume) - * will get unrecognized after USB/PHY is disabled. - */ -#endif + if (config->is_hsusbd) { + /* NOT disable USB/PHY + * + * For HSUSBD, unlike USBD, bus events (Reset/Suspend/Resume) + * will get unrecognized after USB/PHY is disabled. + */ + } else { + USBD_T *base = config->base; + + /* Enable USB but disable PHY */ + base->ATTR &= ~USBD_PHY_EN; + } /* UDC stack would handle bottom-half processing */ udc_submit_event(dev, UDC_EVT_SUSPEND, 0); @@ -768,15 +808,16 @@ static void numaker_usbd_bus_suspend_th(const struct device *dev) static void numaker_usbd_bus_resume_th(const struct device *dev) { const struct udc_numaker_config *config = dev->config; - __maybe_unused USBD_T *base = config->base; struct numaker_usbd_msg msg = {0}; -#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) - /* Enable back USB/PHY */ - base->ATTR |= USBD_ATTR_USBEN_Msk | USBD_ATTR_PHYEN_Msk; -#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) - /* For HSUSBD, enable back USB/PHY will be done in bottom-half for needed wait. */ -#endif + if (config->is_hsusbd) { + /* For HSUSBD, enable back USB/PHY will be done in bottom-half for needed wait. */ + } else { + USBD_T *base = config->base; + + /* Enable back USB/PHY */ + base->ATTR |= USBD_ATTR_USBEN_Msk | USBD_ATTR_PHYEN_Msk; + } /* Message for bottom-half processing */ msg.type = NUMAKER_USBD_MSG_TYPE_RESUME; @@ -794,7 +835,6 @@ static void numaker_usbd_sof_th(const struct device *dev) static void numaker_usbd_setup_copy_to_user(const struct device *dev, uint8_t *usrbuf); -#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) /* Interrupt top half processing for Setup packet */ static void numaker_usbd_setup_th(const struct device *dev) { @@ -870,12 +910,12 @@ static void numaker_usbd_ep_th(const struct device *dev, uint32_t ep_hw_idx) } numaker_usbd_send_msg(dev, &msg); } -#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) + /* Interrupt top half processing for CTRL transfer */ static void numaker_hsusbd_cep_th(const struct device *dev, uint32_t cepintsts) { const struct udc_numaker_config *config = dev->config; - USBD_T *base = config->base; + HSUSBD_T *base = config->base; struct numaker_usbd_msg msg = {0}; /* Setup token */ @@ -946,7 +986,7 @@ static void numaker_hsusbd_cep_th(const struct device *dev, uint32_t cepintsts) /* Interrupt top half processing for BULK/INT/ISO transfer */ static void numaker_hsusbd_ep_th(const struct device *dev, uint32_t ep_hw_idx, uint32_t epintsts) { - USBD_EP_T *ep_base = numaker_usbd_ep_base(dev, ep_hw_idx); + HSUSBD_EP_T *ep_base = numaker_usbd_ep_base(dev, ep_hw_idx); uint8_t ep_dir; uint8_t ep_idx; uint8_t ep; @@ -976,9 +1016,7 @@ static void numaker_hsusbd_ep_th(const struct device *dev, uint32_t ep_hw_idx, u } numaker_usbd_send_msg(dev, &msg); } -#endif -#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) /* USBD SRAM base for DMA */ static inline uint32_t numaker_usbd_buf_base(const struct device *dev) { @@ -987,31 +1025,33 @@ static inline uint32_t numaker_usbd_buf_base(const struct device *dev) return ((uint32_t)base + 0x800ul); } -#endif /* Copy Setup packet to user buffer */ static void numaker_usbd_setup_copy_to_user(const struct device *dev, uint8_t *usrbuf) { const struct udc_numaker_config *config = dev->config; - USBD_T *base = config->base; - __maybe_unused uint32_t dmabuf_addr; - -#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) - dmabuf_addr = numaker_usbd_buf_base(dev) + (base->STBUFSEG & USBD_STBUFSEG_STBUFSEG_Msk); - bytecpy(usrbuf, (uint8_t *)dmabuf_addr, 8ul); -#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) - *usrbuf = (uint8_t)(base->SETUP1_0 & 0xfful); - *(usrbuf + 1) = (uint8_t)((base->SETUP1_0 >> 8) & 0xfful); - *(usrbuf + 2) = (uint8_t)(base->SETUP3_2 & 0xfful); - *(usrbuf + 3) = (uint8_t)((base->SETUP3_2 >> 8) & 0xfful); - *(usrbuf + 4) = (uint8_t)(base->SETUP5_4 & 0xfful); - *(usrbuf + 5) = (uint8_t)((base->SETUP5_4 >> 8) & 0xfful); - *(usrbuf + 6) = (uint8_t)(base->SETUP7_6 & 0xfful); - *(usrbuf + 7) = (uint8_t)((base->SETUP7_6 >> 8) & 0xfful); -#endif + + if (config->is_hsusbd) { + HSUSBD_T *base = config->base; + + *usrbuf = (uint8_t)(base->SETUP1_0 & 0xfful); + *(usrbuf + 1) = (uint8_t)((base->SETUP1_0 >> 8) & 0xfful); + *(usrbuf + 2) = (uint8_t)(base->SETUP3_2 & 0xfful); + *(usrbuf + 3) = (uint8_t)((base->SETUP3_2 >> 8) & 0xfful); + *(usrbuf + 4) = (uint8_t)(base->SETUP5_4 & 0xfful); + *(usrbuf + 5) = (uint8_t)((base->SETUP5_4 >> 8) & 0xfful); + *(usrbuf + 6) = (uint8_t)(base->SETUP7_6 & 0xfful); + *(usrbuf + 7) = (uint8_t)((base->SETUP7_6 >> 8) & 0xfful); + } else { + USBD_T *base = config->base; + uint32_t dmabuf_addr; + + dmabuf_addr = numaker_usbd_buf_base(dev) + + (base->STBUFSEG & USBD_STBUFSEG_STBUFSEG_Msk); + bytecpy(usrbuf, (uint8_t *)dmabuf_addr, 8ul); + } } -#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) #if defined(CONFIG_UDC_NUMAKER_DMA) /* Transfer data between user buffer and USB buffer by DMA * @@ -1023,7 +1063,7 @@ static int numaker_hsusbd_ep_xfer_user_dma(struct numaker_usbd_ep *ep_cur, uint8 const struct device *dev = ep_cur->dev; const struct udc_numaker_config *config = dev->config; struct udc_numaker_data *priv = udc_get_private(dev); - USBD_T *base = config->base; + HSUSBD_T *base = config->base; int err; /* Reset DMA semaphore */ @@ -1081,8 +1121,8 @@ static int numaker_hsusbd_ep_copy_to_user(struct numaker_usbd_ep *ep_cur, uint8_ { const struct device *dev = ep_cur->dev; const struct udc_numaker_config *config = dev->config; - USBD_T *base = config->base; - USBD_EP_T *ep_base = numaker_usbd_ep_base(dev, ep_cur->ep_hw_idx); + HSUSBD_T *base = config->base; + __maybe_unused HSUSBD_EP_T *ep_base = numaker_usbd_ep_base(dev, ep_cur->ep_hw_idx); __ASSERT_NO_MSG(size); @@ -1128,8 +1168,8 @@ static int numaker_hsusbd_ep_copy_from_user(struct numaker_usbd_ep *ep_cur, cons { const struct device *dev = ep_cur->dev; const struct udc_numaker_config *config = dev->config; - USBD_T *base = config->base; - USBD_EP_T *ep_base = numaker_usbd_ep_base(dev, ep_cur->ep_hw_idx); + HSUSBD_T *base = config->base; + __maybe_unused HSUSBD_EP_T *ep_base = numaker_usbd_ep_base(dev, ep_cur->ep_hw_idx); __ASSERT_NO_MSG(size); @@ -1166,8 +1206,6 @@ static int numaker_hsusbd_ep_copy_from_user(struct numaker_usbd_ep *ep_cur, cons return 0; } -#endif - /* Copy data to user buffer * * size holds size to copy/copied on input/output @@ -1177,44 +1215,49 @@ static int numaker_usbd_ep_copy_to_user(struct numaker_usbd_ep *ep_cur, uint8_t { const struct device *dev = ep_cur->dev; const struct udc_numaker_config *config = dev->config; - __maybe_unused USBD_T *base = config->base; - USBD_EP_T *ep_base = numaker_usbd_ep_base(dev, ep_cur->ep_hw_idx); - __maybe_unused uint32_t dmabuf_addr; uint32_t data_rmn; - __maybe_unused int err; __ASSERT_NO_MSG(size); __ASSERT_NO_MSG(ep_cur->dmabuf_valid); -#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) - dmabuf_addr = numaker_usbd_buf_base(dev) + ep_base->BUFSEG; + if (config->is_hsusbd) { + HSUSBD_T *base = config->base; + HSUSBD_EP_T *ep_base = numaker_usbd_ep_base(dev, ep_cur->ep_hw_idx); - /* NOTE: See comment on mxpld_ctrlout for why make one copy of CTRL OUT's MXPLD */ - if (ep_cur->addr == USB_CONTROL_EP_OUT) { - data_rmn = ep_cur->mxpld_ctrlout; - } else { - data_rmn = (ep_base->MXPLD & USBD_MXPLD_MXPLD_Msk) >> USBD_MXPLD_MXPLD_Pos; - } -#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) - if (ep_cur->ep_hw_idx == CEP) { - data_rmn = (base->CEPDATCNT & HSUSBD_CEPDATCNT_DATCNT_Msk) >> - HSUSBD_CEPDATCNT_DATCNT_Pos; + if (ep_cur->ep_hw_idx == CEP) { + data_rmn = (base->CEPDATCNT & HSUSBD_CEPDATCNT_DATCNT_Msk) >> + HSUSBD_CEPDATCNT_DATCNT_Pos; + } else { + data_rmn = (ep_base->EPDATCNT & HSUSBD_EPDATCNT_DATCNT_Msk) >> + HSUSBD_EPDATCNT_DATCNT_Pos; + } } else { - data_rmn = (ep_base->EPDATCNT & HSUSBD_EPDATCNT_DATCNT_Msk) >> - HSUSBD_EPDATCNT_DATCNT_Pos; + USBD_EP_T *ep_base = numaker_usbd_ep_base(dev, ep_cur->ep_hw_idx); + + /* NOTE: See comment on mxpld_ctrlout for why make one copy of CTRL OUT's MXPLD */ + if (ep_cur->addr == USB_CONTROL_EP_OUT) { + data_rmn = ep_cur->mxpld_ctrlout; + } else { + data_rmn = (ep_base->MXPLD & USBD_MXPLD_MXPLD_Msk) >> USBD_MXPLD_MXPLD_Pos; + } } -#endif *size = MIN(*size, data_rmn); -#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) - bytecpy(usrbuf, (uint8_t *)dmabuf_addr, *size); -#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) - err = numaker_hsusbd_ep_copy_to_user(ep_cur, usrbuf, size); - if (err < 0) { - return err; + if (config->is_hsusbd) { + int err; + + err = numaker_hsusbd_ep_copy_to_user(ep_cur, usrbuf, size); + if (err < 0) { + return err; + } + } else { + USBD_EP_T *ep_base = numaker_usbd_ep_base(dev, ep_cur->ep_hw_idx); + uint32_t dmabuf_addr; + + dmabuf_addr = numaker_usbd_buf_base(dev) + ep_base->BUFSEG; + bytecpy(usrbuf, (uint8_t *)dmabuf_addr, *size); } -#endif data_rmn -= *size; @@ -1233,9 +1276,7 @@ static int numaker_usbd_ep_copy_from_user(struct numaker_usbd_ep *ep_cur, const uint32_t *size) { const struct device *dev = ep_cur->dev; - __maybe_unused USBD_EP_T *ep_base = numaker_usbd_ep_base(dev, ep_cur->ep_hw_idx); - __maybe_unused uint32_t dmabuf_addr; - __maybe_unused int err; + const struct udc_numaker_config *config = dev->config; __ASSERT_NO_MSG(size); __ASSERT_NO_MSG(ep_cur->dmabuf_valid); @@ -1244,15 +1285,20 @@ static int numaker_usbd_ep_copy_from_user(struct numaker_usbd_ep *ep_cur, const *size = MIN(*size, ep_cur->mps); -#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) - dmabuf_addr = numaker_usbd_buf_base(dev) + ep_base->BUFSEG; - bytecpy((uint8_t *)dmabuf_addr, (uint8_t *)usrbuf, *size); -#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) - err = numaker_hsusbd_ep_copy_from_user(ep_cur, usrbuf, size); - if (err < 0) { - return err; + if (config->is_hsusbd) { + int err; + + err = numaker_hsusbd_ep_copy_from_user(ep_cur, usrbuf, size); + if (err < 0) { + return err; + } + } else { + USBD_EP_T *ep_base = numaker_usbd_ep_base(dev, ep_cur->ep_hw_idx); + uint32_t dmabuf_addr; + + dmabuf_addr = numaker_usbd_buf_base(dev) + ep_base->BUFSEG; + bytecpy((uint8_t *)dmabuf_addr, (uint8_t *)usrbuf, *size); } -#endif return 0; } @@ -1262,20 +1308,23 @@ static void numaker_usbd_ep_config_dmabuf(struct numaker_usbd_ep *ep_cur, uint32 { const struct device *dev = ep_cur->dev; const struct udc_numaker_config *config = dev->config; - __maybe_unused USBD_T *base = config->base; - USBD_EP_T *ep_base = numaker_usbd_ep_base(dev, ep_cur->ep_hw_idx); -#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) - ep_base->BUFSEG = dmabuf_base; -#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) - if (ep_cur->ep_hw_idx == CEP) { - base->CEPBUFSTART = dmabuf_base; - base->CEPBUFEND = dmabuf_base + dmabuf_size - 1ul; + if (config->is_hsusbd) { + HSUSBD_T *base = config->base; + HSUSBD_EP_T *ep_base = numaker_usbd_ep_base(dev, ep_cur->ep_hw_idx); + + if (ep_cur->ep_hw_idx == CEP) { + base->CEPBUFSTART = dmabuf_base; + base->CEPBUFEND = dmabuf_base + dmabuf_size - 1ul; + } else { + ep_base->EPBUFSTART = dmabuf_base; + ep_base->EPBUFEND = dmabuf_base + dmabuf_size - 1ul; + } } else { - ep_base->EPBUFSTART = dmabuf_base; - ep_base->EPBUFEND = dmabuf_base + dmabuf_size - 1ul; + USBD_EP_T *ep_base = numaker_usbd_ep_base(dev, ep_cur->ep_hw_idx); + + ep_base->BUFSEG = dmabuf_base; } -#endif ep_cur->dmabuf_valid = true; ep_cur->dmabuf_base = dmabuf_base; @@ -1287,32 +1336,35 @@ static void numaker_usbd_ep_abort(struct numaker_usbd_ep *ep_cur, bool excl_ctrl struct udc_ep_config *ep_cfg; const struct device *dev = ep_cur->dev; const struct udc_numaker_config *config = dev->config; - __maybe_unused USBD_T *base = config->base; - USBD_EP_T *ep_base = numaker_usbd_ep_base(dev, ep_cur->ep_hw_idx); -#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) - /* Abort EP on-going transaction */ - if ((ep_cur->ep_hw_idx != EP0 && ep_cur->ep_hw_idx != EP1) || !excl_ctrl) { - ep_base->CFGP |= USBD_CFGP_CLRRDY_Msk; - } -#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) - /* For HSUSBD, there is no control for aborting EP on-going - * transaction, but there is related control of flush EP FIFO. - */ - if (ep_cur->ep_hw_idx == CEP) { - if (!excl_ctrl) { - /* Flush CEP FIFO */ - base->CEPCTL = HSUSBD_CEPCTL_FLUSH | HSUSBD_CEPCTL_NAKCLR_Msk; + if (config->is_hsusbd) { + HSUSBD_T *base = config->base; + HSUSBD_EP_T *ep_base = numaker_usbd_ep_base(dev, ep_cur->ep_hw_idx); + + /* For HSUSBD, there is no control for aborting EP on-going + * transaction, but there is related control of flush EP FIFO. + */ + if (ep_cur->ep_hw_idx == CEP) { + if (!excl_ctrl) { + /* Flush CEP FIFO */ + base->CEPCTL = HSUSBD_CEPCTL_FLUSH | HSUSBD_CEPCTL_NAKCLR_Msk; + } + } else { + /* Flush EP FIFO */ + uint32_t eprspctl = ep_base->EPRSPCTL; + + eprspctl &= ~HSUSBD_EPRSPCTL_TOGGLE_Msk; + eprspctl |= HSUSBD_EP_RSPCTL_FLUSH; + ep_base->EPRSPCTL = eprspctl; } } else { - /* Flush EP FIFO */ - uint32_t eprspctl = ep_base->EPRSPCTL; + USBD_EP_T *ep_base = numaker_usbd_ep_base(dev, ep_cur->ep_hw_idx); - eprspctl &= ~HSUSBD_EPRSPCTL_TOGGLE_Msk; - eprspctl |= HSUSBD_EP_RSPCTL_FLUSH; - ep_base->EPRSPCTL = eprspctl; + /* Abort EP on-going transaction */ + if ((ep_cur->ep_hw_idx != EP0 && ep_cur->ep_hw_idx != EP1) || !excl_ctrl) { + ep_base->CFGP |= USBD_CFGP_CLRRDY_Msk; + } } -#endif if (ep_cur->addr_valid) { ep_cfg = udc_get_ep_cfg(dev, ep_cur->addr); @@ -1332,7 +1384,6 @@ static void numaker_usbd_ep_config_major(struct numaker_usbd_ep *ep_cur, ep_cur->mps = ep_cfg->mps; /* Configure EP transfer type, DATA0/1 toggle, direction, number, etc. */ -#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) ep_cur->ep_hw_cfg = 0; /* Clear STALL Response in Setup stage */ @@ -1356,7 +1407,20 @@ static void numaker_usbd_ep_config_major(struct numaker_usbd_ep *ep_cur, USBD_CFG_EPNUM_Msk; ep_base->CFG = ep_cur->ep_hw_cfg; -#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) +} + +/* Configure EP major common parts */ +static void numaker_hsusbd_ep_config_major(struct numaker_usbd_ep *ep_cur, + struct udc_ep_config *const ep_cfg) +{ + const struct device *dev = ep_cur->dev; + HSUSBD_EP_T *ep_base = numaker_usbd_ep_base(dev, ep_cur->ep_hw_idx); + uint8_t ep_type = ep_cfg->attributes & USB_EP_TRANSFER_TYPE_MASK; + + ep_cur->mps_valid = true; + ep_cur->mps = ep_cfg->mps; + + /* Configure EP transfer type, DATA0/1 toggle, direction, number, etc. */ if (ep_cur->ep_hw_idx == CEP) { /* EP type: CONTROL */ __ASSERT_NO_MSG(ep_type == USB_EP_TYPE_CONTROL); @@ -1404,21 +1468,17 @@ static void numaker_usbd_ep_config_major(struct numaker_usbd_ep *ep_cur, ep_base->EPRSPCTL = ep_cur->ep_hw_rspctl; ep_base->EPCFG = ep_cur->ep_hw_cfg; } -#endif } static void numaker_usbd_ep_enable(struct numaker_usbd_ep *ep_cur) { const struct device *dev = ep_cur->dev; - const struct udc_numaker_config *config = dev->config; - __maybe_unused USBD_T *base = config->base; USBD_EP_T *ep_base = numaker_usbd_ep_base(dev, ep_cur->ep_hw_idx); /* For safe, EP (re-)enable from clean state */ numaker_usbd_ep_abort(ep_cur, false); numaker_usbd_ep_clear_stall_n_data_toggle(ep_cur); -#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) /* Enable EP to IN/OUT */ ep_cur->ep_hw_cfg &= ~USBD_CFG_STATE_Msk; if (USB_EP_DIR_IS_IN(ep_cur->addr)) { @@ -1429,8 +1489,19 @@ static void numaker_usbd_ep_enable(struct numaker_usbd_ep *ep_cur) ep_base->CFG = ep_cur->ep_hw_cfg; /* For USBD, no separate EP interrupt control */ +} + +static void numaker_hsusbd_ep_enable(struct numaker_usbd_ep *ep_cur) +{ + const struct device *dev = ep_cur->dev; + const struct udc_numaker_config *config = dev->config; + HSUSBD_T *base = config->base; + HSUSBD_EP_T *ep_base = numaker_usbd_ep_base(dev, ep_cur->ep_hw_idx); + + /* For safe, EP (re-)enable from clean state */ + numaker_usbd_ep_abort(ep_cur, false); + numaker_usbd_ep_clear_stall_n_data_toggle(ep_cur); -#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) if (ep_cur->ep_hw_idx == CEP) { /* CEP global interrupt should have enabled for resident. */ @@ -1446,23 +1517,27 @@ static void numaker_usbd_ep_enable(struct numaker_usbd_ep *ep_cur) /* To enable EP local interrupt in EP trigger */ } -#endif } static void numaker_usbd_ep_disable(struct numaker_usbd_ep *ep_cur) { const struct device *dev = ep_cur->dev; - const struct udc_numaker_config *config = dev->config; - __maybe_unused USBD_T *base = config->base; USBD_EP_T *ep_base = numaker_usbd_ep_base(dev, ep_cur->ep_hw_idx); -#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) /* For USBD, no separate EP interrupt control */ /* Disable EP */ ep_cur->ep_hw_cfg = (ep_cur->ep_hw_cfg & ~USBD_CFG_STATE_Msk) | USBD_CFG_EPMODE_DISABLE; ep_base->CFG = ep_cur->ep_hw_cfg; -#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) +} + +static void numaker_hsusbd_ep_disable(struct numaker_usbd_ep *ep_cur) +{ + const struct device *dev = ep_cur->dev; + const struct udc_numaker_config *config = dev->config; + HSUSBD_T *base = config->base; + HSUSBD_EP_T *ep_base = numaker_usbd_ep_base(dev, ep_cur->ep_hw_idx); + if (ep_cur->ep_hw_idx == CEP) { /* Disable CEP local interrupt */ if (USB_EP_DIR_IS_IN(ep_cur->addr)) { @@ -1487,26 +1562,16 @@ static void numaker_usbd_ep_disable(struct numaker_usbd_ep *ep_cur) ep_cur->ep_hw_cfg &= ~HSUSBD_EPCFG_EPEN_Msk; ep_base->EPCFG = ep_cur->ep_hw_cfg; } -#endif } /* Start EP data transaction */ -static void numaker_usbd_ep_trigger(struct numaker_usbd_ep *ep_cur, uint32_t len) +static void numaker_hsusbd_ep_trigger(struct numaker_usbd_ep *ep_cur, uint32_t len) { - struct udc_ep_config *ep_cfg; const struct device *dev = ep_cur->dev; const struct udc_numaker_config *config = dev->config; - __maybe_unused USBD_T *base = config->base; - USBD_EP_T *ep_base = numaker_usbd_ep_base(dev, ep_cur->ep_hw_idx); - - __ASSERT_NO_MSG(ep_cur->addr_valid); - - ep_cfg = udc_get_ep_cfg(dev, ep_cur->addr); - udc_ep_set_busy(ep_cfg, true); + HSUSBD_T *base = config->base; + HSUSBD_EP_T *ep_base = numaker_usbd_ep_base(dev, ep_cur->ep_hw_idx); -#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) - ep_base->MXPLD = len; -#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) if (ep_cur->ep_hw_idx == CEP) { if (USB_EP_DIR_IS_IN(ep_cur->addr)) { if (udc_ctrl_stage_is_status_in(dev) || udc_ctrl_stage_is_no_data(dev)) { @@ -1573,7 +1638,27 @@ static void numaker_usbd_ep_trigger(struct numaker_usbd_ep *ep_cur, uint32_t len ep_base->EPINTEN |= HSUSBD_EPINTEN_RXPKIEN_Msk; } } -#endif +} + +/* Start EP data transaction */ +static void numaker_usbd_ep_trigger(struct numaker_usbd_ep *ep_cur, uint32_t len) +{ + struct udc_ep_config *ep_cfg; + const struct device *dev = ep_cur->dev; + const struct udc_numaker_config *config = dev->config; + + __ASSERT_NO_MSG(ep_cur->addr_valid); + + ep_cfg = udc_get_ep_cfg(dev, ep_cur->addr); + udc_ep_set_busy(ep_cfg, true); + + if (config->is_hsusbd) { + numaker_hsusbd_ep_trigger(ep_cur, len); + } else { + USBD_EP_T *ep_base = numaker_usbd_ep_base(dev, ep_cur->ep_hw_idx); + + ep_base->MXPLD = len; + } } static struct numaker_usbd_ep *numaker_usbd_ep_mgmt_alloc_ep(const struct device *dev) @@ -1628,7 +1713,6 @@ static void numaker_usbd_ep_mgmt_init(const struct device *dev) { const struct udc_numaker_config *config = dev->config; struct udc_numaker_data *priv = udc_get_private(dev); - __maybe_unused USBD_T *base = config->base; struct numaker_usbd_ep_mgmt *ep_mgmt = &priv->ep_mgmt; struct numaker_usbd_ep *ep_cur; @@ -1648,28 +1732,28 @@ static void numaker_usbd_ep_mgmt_init(const struct device *dev) /* Pointer to the containing device */ ep_cur->dev = dev; -#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) - /* BSP USBD driver EP handle - * - * ep_pool[0]: EP0 (CTRL OUT) - * ep_pool[1]: EP1 (CTRL IN) - * ep_pool[2~]: EP2, EP3, etc. - */ - ep_cur->ep_hw_idx = EP0 + (ep_cur - priv->ep_pool); -#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) - /* BSP HSUSBD driver EP handle - * - * ep_pool[0]: CEP (CTRL OUT) - * ep_pool[1]: CEP (CTRL IN) - * ep_pool[2~]: EPA, EPB, etc. - */ - ep_cur->ep_hw_idx = EPA + (ep_cur - priv->ep_pool); - if (ep_cur->ep_hw_idx == 0 || ep_cur->ep_hw_idx == 1) { - ep_cur->ep_hw_idx = CEP; + if (config->is_hsusbd) { + /* BSP HSUSBD driver EP handle + * + * ep_pool[0]: CEP (CTRL OUT) + * ep_pool[1]: CEP (CTRL IN) + * ep_pool[2~]: EPA, EPB, etc. + */ + ep_cur->ep_hw_idx = EPA + (ep_cur - priv->ep_pool); + if (ep_cur->ep_hw_idx == 0 || ep_cur->ep_hw_idx == 1) { + ep_cur->ep_hw_idx = CEP; + } else { + ep_cur->ep_hw_idx -= 2; + } } else { - ep_cur->ep_hw_idx -= 2; + /* BSP USBD driver EP handle + * + * ep_pool[0]: EP0 (CTRL OUT) + * ep_pool[1]: EP1 (CTRL IN) + * ep_pool[2~]: EP2, EP3, etc. + */ + ep_cur->ep_hw_idx = EP0 + (ep_cur - priv->ep_pool); } -#endif } /* Reserve 1st/2nd EP H/W contexts for CTRL OUT/IN @@ -1683,12 +1767,14 @@ static void numaker_usbd_ep_mgmt_init(const struct device *dev) ep_mgmt->dmabuf_pos = 0; /* Configure DMA buffer for Setup packet */ -#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) - base->STBUFSEG = ep_mgmt->dmabuf_pos; - ep_mgmt->dmabuf_pos += NUMAKER_USBD_DMABUF_SIZE_SETUP; -#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) - /* For HSUSBD, SETUP1_0, SETUP3_2, SETUP5_4, SETUP7_6 */ -#endif + if (config->is_hsusbd) { + /* For HSUSBD, SETUP1_0, SETUP3_2, SETUP5_4, SETUP7_6 */ + } else { + USBD_T *base = config->base; + + base->STBUFSEG = ep_mgmt->dmabuf_pos; + ep_mgmt->dmabuf_pos += NUMAKER_USBD_DMABUF_SIZE_SETUP; + } /* Reserve 1st EP H/W context for CTRL OUT */ ep_cur = priv->ep_pool + 0; @@ -1893,19 +1979,20 @@ static int numaker_usbd_ctrl_feed_dout(const struct device *dev, const size_t le /* Message handler for device plug-in */ static int numaker_usbd_msg_handle_attach(const struct device *dev, struct numaker_usbd_msg *msg) { + const struct udc_numaker_config *config = dev->config; int err; __ASSERT_NO_MSG(msg->type == NUMAKER_USBD_MSG_TYPE_ATTACH); -#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) - /* For USBD, enable back USB/PHY has done in ISR for unneeded wait. */ -#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) - err = numaker_usbd_enable_usb_phy(dev); - if (err < 0) { - LOG_ERR("Enable USB/PHY failed"); - return -err; + if (config->is_hsusbd) { + err = numaker_usbd_enable_usb_phy(dev); + if (err < 0) { + LOG_ERR("Enable USB/PHY failed"); + return -err; + } + } else { + /* For USBD, enable back USB/PHY has done in ISR for unneeded wait. */ } -#endif err = udc_submit_event(dev, UDC_EVT_VBUS_READY, 0); @@ -1915,19 +2002,20 @@ static int numaker_usbd_msg_handle_attach(const struct device *dev, struct numak /* Message handler for bus reset */ static int numaker_usbd_msg_handle_reset(const struct device *dev, struct numaker_usbd_msg *msg) { + const struct udc_numaker_config *config = dev->config; int err; __ASSERT_NO_MSG(msg->type == NUMAKER_USBD_MSG_TYPE_RESET); -#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) - /* For USBD, enable back USB/PHY has done in ISR for unneeded wait. */ -#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) - err = numaker_usbd_enable_usb_phy(dev); - if (err < 0) { - LOG_ERR("Enable USB/PHY failed"); - return -err; + if (config->is_hsusbd) { + err = numaker_usbd_enable_usb_phy(dev); + if (err < 0) { + LOG_ERR("Enable USB/PHY failed"); + return -err; + } + } else { + /* For USBD, enable back USB/PHY has done in ISR for unneeded wait. */ } -#endif /* UDC stack would handle bottom-half processing, * including reset device address (udc_set_address), @@ -1941,19 +2029,20 @@ static int numaker_usbd_msg_handle_reset(const struct device *dev, struct numake /* Message handler for bus resume */ static int numaker_usbd_msg_handle_resume(const struct device *dev, struct numaker_usbd_msg *msg) { + const struct udc_numaker_config *config = dev->config; int err; __ASSERT_NO_MSG(msg->type == NUMAKER_USBD_MSG_TYPE_RESUME); -#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) - /* For USBD, enable back USB/PHY has done in ISR for unneeded wait. */ -#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) - err = numaker_usbd_enable_usb_phy(dev); - if (err < 0) { - LOG_ERR("Enable USB/PHY failed"); - return -err; + if (config->is_hsusbd) { + err = numaker_usbd_enable_usb_phy(dev); + if (err < 0) { + LOG_ERR("Enable USB/PHY failed"); + return -err; + } + } else { + /* For USBD, enable back USB/PHY has done in ISR for unneeded wait. */ } -#endif err = udc_submit_event(dev, UDC_EVT_RESUME, 0); @@ -1963,6 +2052,7 @@ static int numaker_usbd_msg_handle_resume(const struct device *dev, struct numak /* Message handler for Setup transaction completed */ static int numaker_usbd_msg_handle_setup(const struct device *dev, struct numaker_usbd_msg *msg) { + const struct udc_numaker_config *config = dev->config; int err; uint8_t ep; struct numaker_usbd_ep *ep_cur; @@ -2003,16 +2093,16 @@ static int numaker_usbd_msg_handle_setup(const struct device *dev, struct numake __ASSERT_NO_MSG((ep_cur + 1)->addr == USB_CONTROL_EP_IN); /* Abort previous CTRL OUT/IN */ -#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) - numaker_usbd_ep_abort(ep_cur, false); - numaker_usbd_ep_abort(ep_cur + 1, false); -#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) - /* For HSUSBD, there is timing concern between FIFO flush and - * immediately following data transaction. Do in ISR for in time. - */ - numaker_usbd_ep_abort(ep_cur, true); - numaker_usbd_ep_abort(ep_cur + 1, true); -#endif + if (config->is_hsusbd) { + /* For HSUSBD, there is timing concern between FIFO flush and + * immediately following data transaction. Do in ISR for in time. + */ + numaker_usbd_ep_abort(ep_cur, true); + numaker_usbd_ep_abort(ep_cur + 1, true); + } else { + numaker_usbd_ep_abort(ep_cur, false); + numaker_usbd_ep_abort(ep_cur + 1, false); + } /* CTRL OUT/IN reset to unstalled by H/W on receive of Setup packet */ numaker_usbd_ep_sync_udc_halt(ep_cur, false); @@ -2314,13 +2404,10 @@ static void numaker_usbd_msg_handler(const struct device *dev) } } -static void numaker_usbd_isr(const struct device *dev) +__maybe_unused static void numaker_usbd_isr(const struct device *dev) { const struct udc_numaker_config *config = dev->config; - __maybe_unused struct udc_numaker_data *priv = udc_get_private(dev); USBD_T *base = config->base; - -#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) uint32_t usbd_intsts = base->INTSTS; uint32_t usbd_bus_state = base->ATTR; @@ -2398,7 +2485,13 @@ static void numaker_usbd_isr(const struct device *dev) epintsts &= ~BIT(ep_hw_idx - EP0); } } -#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) +} + +__maybe_unused static void numaker_hsusbd_isr(const struct device *dev) +{ + const struct udc_numaker_config *config = dev->config; + struct udc_numaker_data *priv = udc_get_private(dev); + HSUSBD_T *base = config->base; uint32_t gintsts = base->GINTSTS; uint32_t gintsts_ep = gintsts & (BIT_MASK(priv->ep_pool_size - 2) << HSUSBD_GINTSTS_EPAIF_Pos); @@ -2438,7 +2531,7 @@ static void numaker_usbd_isr(const struct device *dev) /* USB reset */ if (busintsts & HSUSBD_BUSINTSTS_RSTIF_Msk) { - numaker_usbd_bus_reset_th(dev); + numaker_hsusbd_bus_reset_th(dev); } /* Bus suspend */ @@ -2493,19 +2586,19 @@ static void numaker_usbd_isr(const struct device *dev) gintsts_ep_iter &= ~BIT(ep_hw_idx - EPA); } } -#endif } static enum udc_bus_speed udc_numaker_device_speed(const struct device *dev) { const struct udc_numaker_config *config = dev->config; - __maybe_unused USBD_T *base = config->base; -#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) - return UDC_BUS_SPEED_FS; -#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) - return (base->OPER & HSUSBD_OPER_CURSPD_Msk) ? UDC_BUS_SPEED_HS : UDC_BUS_SPEED_FS; -#endif + if (config->is_hsusbd) { + HSUSBD_T *base = config->base; + + return (base->OPER & HSUSBD_OPER_CURSPD_Msk) ? UDC_BUS_SPEED_HS : UDC_BUS_SPEED_FS; + } else { + return UDC_BUS_SPEED_FS; + } } static int udc_numaker_ep_enqueue(const struct device *dev, struct udc_ep_config *const ep_cfg, @@ -2594,6 +2687,7 @@ static int udc_numaker_ep_clear_halt(const struct device *dev, struct udc_ep_con static int udc_numaker_ep_enable(const struct device *dev, struct udc_ep_config *const ep_cfg) { + const struct udc_numaker_config *config = dev->config; int err; uint32_t dmabuf_base; uint32_t dmabuf_size; @@ -2623,16 +2717,25 @@ static int udc_numaker_ep_enable(const struct device *dev, struct udc_ep_config } /* Configure EP majorly */ - numaker_usbd_ep_config_major(ep_cur, ep_cfg); + if (config->is_hsusbd) { + numaker_hsusbd_ep_config_major(ep_cur, ep_cfg); + } else { + numaker_usbd_ep_config_major(ep_cur, ep_cfg); + } /* Enable EP */ - numaker_usbd_ep_enable(ep_cur); + if (config->is_hsusbd) { + numaker_hsusbd_ep_enable(ep_cur); + } else { + numaker_usbd_ep_enable(ep_cur); + } return 0; } static int udc_numaker_ep_disable(const struct device *dev, struct udc_ep_config *const ep_cfg) { + const struct udc_numaker_config *config = dev->config; struct numaker_usbd_ep *ep_cur; LOG_DBG("Disable ep 0x%02x", ep_cfg->addr); @@ -2645,15 +2748,36 @@ static int udc_numaker_ep_disable(const struct device *dev, struct udc_ep_config } /* Disable EP */ - numaker_usbd_ep_disable(ep_cur); + if (config->is_hsusbd) { + numaker_hsusbd_ep_disable(ep_cur); + } else { + numaker_usbd_ep_disable(ep_cur); + } return 0; } -static int udc_numaker_host_wakeup(const struct device *dev) +static void udc_numaker_usbd_gen_K(const struct device *dev) { const struct udc_numaker_config *config = dev->config; USBD_T *base = config->base; + + base->ATTR |= USBD_ATTR_RWAKEUP_Msk; + k_sleep(K_USEC(NUMAKER_USBD_BUS_RESUME_DRV_K_US)); + base->ATTR ^= USBD_ATTR_RWAKEUP_Msk; +} + +static void udc_numaker_hsusbd_gen_K(const struct device *dev) +{ + const struct udc_numaker_config *config = dev->config; + HSUSBD_T *base = config->base; + + base->OPER |= HSUSBD_OPER_RESUMEEN_Msk; +} + +static int udc_numaker_host_wakeup(const struct device *dev) +{ + const struct udc_numaker_config *config = dev->config; int err; /* Enable back USB/PHY first */ @@ -2664,13 +2788,11 @@ static int udc_numaker_host_wakeup(const struct device *dev) } /* Then generate 'K' */ -#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) - base->ATTR |= USBD_ATTR_RWAKEUP_Msk; - k_sleep(K_USEC(NUMAKER_USBD_BUS_RESUME_DRV_K_US)); - base->ATTR ^= USBD_ATTR_RWAKEUP_Msk; -#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) - base->OPER |= HSUSBD_OPER_RESUMEEN_Msk; -#endif + if (config->is_hsusbd) { + udc_numaker_hsusbd_gen_K(dev); + } else { + udc_numaker_usbd_gen_K(dev); + } return 0; } @@ -2710,11 +2832,43 @@ static int udc_numaker_disable(const struct device *dev) return 0; } -static int udc_numaker_init(const struct device *dev) +static void udc_numaker_usbd_init_int_early(const struct device *dev) { const struct udc_numaker_config *config = dev->config; struct udc_data *data = dev->data; USBD_T *base = config->base; + + /* Enable VBUS detect early */ + if (data->caps.can_detect_vbus) { + base->INTEN = USBD_INT_FLDET; + } else { + base->INTEN = 0; + } + + /* Enable USB wake-up early */ + base->INTEN |= USBD_INT_WAKEUP; +} + +static void udc_numaker_hsusbd_init_int_early(const struct device *dev) +{ + const struct udc_numaker_config *config = dev->config; + struct udc_data *data = dev->data; + HSUSBD_T *base = config->base; + + /* Enable VBUS detect early */ + if (data->caps.can_detect_vbus) { + base->BUSINTEN = HSUSBD_BUSINTEN_VBUSDETIEN_Msk; + } else { + base->BUSINTEN = 0; + } + + /* Enable USB wake-up early */ + base->PHYCTL |= HSUSBD_PHYCTL_VBUSWKEN_Msk; +} + +static int udc_numaker_init(const struct device *dev) +{ + const struct udc_numaker_config *config = dev->config; int err; /* Initialize UDC H/W */ @@ -2740,28 +2894,13 @@ static int udc_numaker_init(const struct device *dev) return -EIO; } - /* Enable VBUS detect early */ - if (data->caps.can_detect_vbus) { -#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) - base->INTEN = USBD_INT_FLDET; -#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) - base->BUSINTEN = HSUSBD_BUSINTEN_VBUSDETIEN_Msk; -#endif + /* Initialize interrupt early */ + if (config->is_hsusbd) { + udc_numaker_hsusbd_init_int_early(dev); } else { -#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) - base->INTEN = 0; -#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) - base->BUSINTEN = 0; -#endif + udc_numaker_usbd_init_int_early(dev); } - /* Enable USB wake-up early */ -#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) - base->INTEN |= USBD_INT_WAKEUP; -#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) - base->PHYCTL |= HSUSBD_PHYCTL_VBUSWKEN_Msk; -#endif - return 0; } @@ -2806,15 +2945,15 @@ static int udc_numaker_driver_preinit(const struct device *dev) uint16_t mps = 1023; int err; -#if DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_usbd) - /* For USBD, support just full-speed */ -#elif DT_HAS_COMPAT_STATUS_OKAY(nuvoton_numaker_hsusbd) - /* For HSUSBD, support both full-speed and high-speed */ - if (config->speed_idx >= 2) { - data->caps.hs = true; - mps = 1024; + if (config->is_hsusbd) { + /* For HSUSBD, support both full-speed and high-speed */ + if (config->speed_idx >= 2) { + data->caps.hs = true; + mps = 1024; + } + } else { + /* For USBD, support just full-speed */ } -#endif data->caps.rwup = true; data->caps.addr_before_status = true; data->caps.can_detect_vbus = true; @@ -2909,12 +3048,17 @@ static const struct udc_api udc_numaker_api = { #define NUMAKER_USBD_PINCTRL_DEFINE(inst) \ IF_ENABLED(DT_NODE_HAS_PROP(DT_DRV_INST(inst), pinctrl_0), (PINCTRL_DT_INST_DEFINE(inst))) +#define UDC_NUMAKER_ISR \ + COND_CODE_1(UDC_NUMAKER_DEVICE_HSUSBD, (numaker_hsusbd_isr), (numaker_usbd_isr)) + +#define UDC_NUMAKER_SPEED_IDX_DEFAULT COND_CODE_1(UDC_NUMAKER_DEVICE_HSUSBD, (2), (1)) + #define UDC_NUMAKER_DEVICE_DEFINE(inst) \ NUMAKER_USBD_PINCTRL_DEFINE(inst); \ \ static void udc_numaker_irq_config_func_##inst(const struct device *dev) \ { \ - IRQ_CONNECT(DT_INST_IRQN(inst), DT_INST_IRQ(inst, priority), numaker_usbd_isr, \ + IRQ_CONNECT(DT_INST_IRQN(inst), DT_INST_IRQ(inst, priority), UDC_NUMAKER_ISR, \ DEVICE_DT_INST_GET(inst), 0); \ \ irq_enable(DT_INST_IRQN(inst)); \ @@ -2970,7 +3114,8 @@ static const struct udc_api udc_numaker_api = { .disallow_iso_inout_same = DT_INST_PROP_OR(inst, disallow_iso_in_out_same_number, \ 0), \ .speed_idx = DT_ENUM_IDX_OR(DT_DRV_INST(inst), maximum_speed, \ - NUMAKER_USBD_SPEED_IDX_DEFAULT), \ + UDC_NUMAKER_SPEED_IDX_DEFAULT), \ + .is_hsusbd = IS_ENABLED(UDC_NUMAKER_DEVICE_HSUSBD), \ }; \ \ static struct numaker_usbd_ep \ @@ -2994,4 +3139,13 @@ static const struct udc_api udc_numaker_api = { &udc_numaker_config_##inst, POST_KERNEL, \ CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &udc_numaker_api); +/* Define USBD devices */ +#define DT_DRV_COMPAT nuvoton_numaker_usbd +DT_INST_FOREACH_STATUS_OKAY(UDC_NUMAKER_DEVICE_DEFINE) + +/* Define HSUSBD devices */ + +#undef DT_DRV_COMPAT +#define DT_DRV_COMPAT nuvoton_numaker_hsusbd +#define UDC_NUMAKER_DEVICE_HSUSBD 1 DT_INST_FOREACH_STATUS_OKAY(UDC_NUMAKER_DEVICE_DEFINE) From 7193d72c9ac2d25eb0f6614aa068864da8c162a6 Mon Sep 17 00:00:00 2001 From: YongWoo Kang Date: Tue, 16 Dec 2025 20:02:15 +0900 Subject: [PATCH 0449/3659] boards: arm: doc: update wiki url Update official wiki url. Signed-off-by: YongWoo Kang --- boards/seeed/xiao_nrf54l15/doc/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boards/seeed/xiao_nrf54l15/doc/index.rst b/boards/seeed/xiao_nrf54l15/doc/index.rst index 960b210d772a..8d680e0b487a 100644 --- a/boards/seeed/xiao_nrf54l15/doc/index.rst +++ b/boards/seeed/xiao_nrf54l15/doc/index.rst @@ -94,7 +94,7 @@ Reset the board and you should see the following message in the terminal: https://www.seeedstudio.com/XIAO-nRF54L15-Sense-p-6494 .. _XIAO nRF54L15 Wiki: - https://wiki.seeedstudio.com/getting_started_with_xiao_nrf54l15/ + https://wiki.seeedstudio.com/xiao_nrf54l15_sense_getting_started .. _nRF54L15 Website: https://www.nordicsemi.com/Products/nRF54L15 From f14ccdf462a24f8a32a7b0b7cadbf3d403a6e980 Mon Sep 17 00:00:00 2001 From: Jeremy Bettis Date: Wed, 22 Oct 2025 11:01:20 -0600 Subject: [PATCH 0450/3659] drivers: Add const to rts5912_sha256_process() input rts5913_sha256_update was changed in #94218, but this function passes it's input into rts5912_sha256_process also. Signed-off-by: Jeremy Bettis --- drivers/crypto/crypto_rts5912_sha.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/crypto/crypto_rts5912_sha.c b/drivers/crypto/crypto_rts5912_sha.c index 7e9620aa33cb..b125a8760945 100644 --- a/drivers/crypto/crypto_rts5912_sha.c +++ b/drivers/crypto/crypto_rts5912_sha.c @@ -67,7 +67,7 @@ static void rts5912_sha256_start(const struct device *dev) sha2dma_regs->msk_block = 0x0; } -static int rts5912_sha256_process(const struct device *dev, uint8_t *input, size_t blk_size) +static int rts5912_sha256_process(const struct device *dev, const uint8_t *input, size_t blk_size) { const struct rts5912_sha_config *cfg = dev->config; volatile struct sha2_type *sha2_regs = (volatile struct sha2_type *)cfg->cfg_sha2_regs; From 713ec75a54f62f71e9df9a86a7d445c04289cc19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fin=20Maa=C3=9F?= Date: Tue, 4 Nov 2025 13:36:39 +0100 Subject: [PATCH 0451/3659] litex: i2c: improve litei2c driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit improve litei2c driver Signed-off-by: Fin Maaß --- drivers/i2c/i2c_litex_litei2c.c | 370 ++++++++++++++++++-------------- 1 file changed, 214 insertions(+), 156 deletions(-) diff --git a/drivers/i2c/i2c_litex_litei2c.c b/drivers/i2c/i2c_litex_litei2c.c index f32aee5ca12a..267a112cfc0d 100644 --- a/drivers/i2c/i2c_litex_litei2c.c +++ b/drivers/i2c/i2c_litex_litei2c.c @@ -8,6 +8,7 @@ #include #include +#include #include LOG_MODULE_REGISTER(i2c_litex_litei2c, CONFIG_I2C_LOG_LEVEL); @@ -43,10 +44,20 @@ struct i2c_litex_litei2c_config { #endif /* I2C_LITEX_ANY_HAS_IRQ */ }; +struct i2c_context { + struct i2c_msg *msg; + uint32_t buf_idx; + uint8_t num_msgs; + uint8_t num_msgs_idx; +}; + struct i2c_litex_litei2c_data { struct k_mutex mutex; + struct i2c_context context; + uint8_t len_rx; #if I2C_LITEX_ANY_HAS_IRQ struct k_sem sem_rx_ready; + int ret; #endif /* I2C_LITEX_ANY_HAS_IRQ */ }; @@ -121,56 +132,202 @@ static int i2c_litex_write_settings(const struct device *dev, uint8_t len_tx, ui return 0; } -static void i2c_litex_wait_for_rx_ready(const struct device *dev) +static inline uint8_t get_write_bytes_from_i2c_msg(struct i2c_context *context, uint8_t *data, + uint8_t data_len, bool *with_stop) { - const struct i2c_litex_litei2c_config *config = dev->config; + uint8_t idx = 0; + uint8_t to_copy; + uint32_t msg_len; -#if I2C_LITEX_ANY_HAS_IRQ - struct i2c_litex_litei2c_data *data = dev->data; + while ((data_len > 0) && (context->num_msgs_idx < context->num_msgs) && + !(context->msg[context->num_msgs_idx].flags & I2C_MSG_READ)) { - if (I2C_LITEX_HAS_IRQ) { - /* Wait for the RX ready event */ - k_sem_take(&data->sem_rx_ready, K_FOREVER); - return; + msg_len = context->msg[context->num_msgs_idx].len - context->buf_idx; + to_copy = min(data_len, msg_len); + + memcpy(&data[idx], &context->msg[context->num_msgs_idx].buf[context->buf_idx], + to_copy); + + idx += to_copy; + data_len -= to_copy; + if (to_copy >= msg_len) { + context->num_msgs_idx++; + context->buf_idx = 0; + + if (context->msg[context->num_msgs_idx - 1].flags & I2C_MSG_STOP) { + *with_stop = true; + return idx; + } + } else { + context->buf_idx += to_copy; + } } -#endif /* I2C_LITEX_ANY_HAS_IRQ */ - while (!(litex_read8(config->master_status_addr) & - BIT(MASTER_STATUS_RX_READY_OFFSET))) { - /* Wait until RX is ready */ + if ((data_len == 0) && (context->num_msgs_idx < context->num_msgs) && + !(context->msg[context->num_msgs_idx].flags & I2C_MSG_READ)) { + /* Signal that there is more data to write */ + return idx + 1; } + + return idx; } -static int i2c_litex_transfer(const struct device *dev, struct i2c_msg *msgs, uint8_t num_msgs, - uint16_t addr) +static inline bool next_msg_is_available(struct i2c_context *context) +{ + return (context->num_msgs_idx < context->num_msgs); +} + +static inline uint8_t get_read_bytes_len_from_i2c_msg(struct i2c_context *context, + uint8_t max_data_len) +{ + uint32_t counter = 0; + uint32_t buf_idx = context->buf_idx; + uint8_t num_msgs_idx = context->num_msgs_idx; + + while ((counter < max_data_len) && (num_msgs_idx < context->num_msgs) && + (context->msg[num_msgs_idx].flags & I2C_MSG_READ)) { + counter += context->msg[num_msgs_idx].len - buf_idx; + + if (context->msg[num_msgs_idx].flags & I2C_MSG_STOP) { + break; + } + num_msgs_idx++; + buf_idx = 0; + } + + return min(counter, max_data_len); +} + +static inline uint8_t set_read_bytes_from_i2c_msg(struct i2c_context *context, uint8_t *data, + uint8_t data_len) +{ + uint8_t idx = 0; + uint8_t to_copy; + uint32_t msg_len; + + while ((data_len > 0) && (context->num_msgs_idx < context->num_msgs) && + (context->msg[context->num_msgs_idx].flags & I2C_MSG_READ)) { + + msg_len = context->msg[context->num_msgs_idx].len - context->buf_idx; + to_copy = min(data_len, msg_len); + + memcpy(&context->msg[context->num_msgs_idx].buf[context->buf_idx], &data[idx], + to_copy); + + idx += to_copy; + data_len -= to_copy; + if (to_copy >= msg_len) { + context->num_msgs_idx++; + context->buf_idx = 0; + } else { + context->buf_idx += to_copy; + } + } + + return idx; +} + +static void i2c_litex_i2c_do_tx(const struct device *dev) { const struct i2c_litex_litei2c_config *config = dev->config; struct i2c_litex_litei2c_data *data = dev->data; - uint32_t len_tx_buf = 0; - uint32_t len_rx_buf = 0; - uint8_t len_tx = 0; + uint32_t txd = 0U; uint8_t len_rx = 0; + uint8_t len_tx; + uint8_t tx_buf[4] = {0}; + bool with_stop = false; + + len_tx = get_write_bytes_from_i2c_msg(&data->context, tx_buf, sizeof(tx_buf), &with_stop); + + switch (len_tx) { + case 5: + case 4: + txd = sys_get_be32(tx_buf); + break; + case 3: + txd = sys_get_be24(tx_buf); + break; + case 2: + txd = sys_get_be16(tx_buf); + break; + default: + txd = tx_buf[0]; + break; + } + + if (!with_stop) { + len_rx = get_read_bytes_len_from_i2c_msg(&data->context, 5); + } + + data->len_rx = min(len_rx, 4); + + LOG_DBG("len_tx: %d, len_rx: %d", len_tx, len_rx); + i2c_litex_write_settings(dev, len_tx, len_rx, false); + + LOG_DBG("txd: 0x%x", txd); + litex_write32(txd, config->master_rxtx_addr); +} + +static int i2c_litex_i2c_do_rx(const struct device *dev) +{ + const struct i2c_litex_litei2c_config *config = dev->config; + struct i2c_litex_litei2c_data *data = dev->data; + uint32_t rxd; + uint8_t rx_buf[4] = {0}; + + if (litex_read16(config->master_status_addr) & BIT(MASTER_STATUS_NACK_OFFSET)) { + /* NACK received, clear RX FIFO */ + (void)litex_read32(config->master_rxtx_addr); - uint8_t *tx_buf_ptr; - uint8_t *rx_buf_ptr; + return -EIO; + } - uint32_t tx_buf; - uint32_t rx_buf; + rxd = litex_read32(config->master_rxtx_addr); - uint32_t tx_j = 0; - uint32_t rx_j = 0; + LOG_DBG("rxd: 0x%x", rxd); + switch (data->len_rx) { + case 4: + sys_put_be32(rxd, rx_buf); + break; + case 3: + sys_put_be24(rxd, rx_buf); + break; + case 2: + sys_put_be16(rxd, rx_buf); + break; + case 1: + rx_buf[0] = rxd; + break; + default: + return 0; + } + + set_read_bytes_from_i2c_msg(&data->context, rx_buf, data->len_rx); + + return 0; +} + +static int i2c_litex_transfer(const struct device *dev, struct i2c_msg *msgs, uint8_t num_msgs, + uint16_t addr) +{ + const struct i2c_litex_litei2c_config *config = dev->config; + struct i2c_litex_litei2c_data *data = dev->data; int ret = 0; k_mutex_lock(&data->mutex, K_FOREVER); + data->context.msg = msgs; + data->context.num_msgs = num_msgs; + data->context.num_msgs_idx = 0; + data->context.buf_idx = 0; + litex_write8(1, config->master_active_addr); /* Flush RX buffer */ while ((litex_read8(config->master_status_addr) & BIT(MASTER_STATUS_RX_READY_OFFSET))) { - rx_buf = litex_read32(config->master_rxtx_addr); - LOG_DBG("flushed rxd: 0x%x", rx_buf); + (void)litex_read32(config->master_rxtx_addr); } while (!(litex_read8(config->master_status_addr) & @@ -178,151 +335,40 @@ static int i2c_litex_transfer(const struct device *dev, struct i2c_msg *msgs, ui (void)litex_read32(config->master_rxtx_addr); } + LOG_DBG("addr: 0x%x", addr); + litex_write8((uint8_t)addr, config->master_addr_addr); + #if I2C_LITEX_ANY_HAS_IRQ if (I2C_LITEX_HAS_IRQ) { - litex_write8(BIT(0), config->master_ev_enable_addr); litex_write8(BIT(0), config->master_ev_pending_addr); + litex_write8(BIT(0), config->master_ev_enable_addr); k_sem_reset(&data->sem_rx_ready); - } -#endif /* I2C_LITEX_ANY_HAS_IRQ */ - LOG_DBG("addr: 0x%x", addr); - litex_write8((uint8_t)addr, config->master_addr_addr); + i2c_litex_i2c_do_tx(dev); - for (uint8_t i = 0; i < num_msgs; i++) { - if (msgs[i].flags & I2C_MSG_READ) { - len_tx_buf = 0; - len_rx_buf = msgs[i].len; - rx_buf_ptr = msgs[i].buf; - tx_buf_ptr = NULL; - } else { - len_tx_buf = msgs[i].len; - tx_buf_ptr = msgs[i].buf; - if (!(msgs[i].flags & I2C_MSG_STOP) && (i + 1 < num_msgs) && - (msgs[i + 1].flags & I2C_MSG_READ) && - (msgs[i + 1].flags & I2C_MSG_RESTART)) { - i++; - len_rx_buf = msgs[i].len; - rx_buf_ptr = msgs[i].buf; - } else { - len_rx_buf = 0; - rx_buf_ptr = NULL; - } - } - - LOG_HEXDUMP_DBG(tx_buf_ptr, len_tx_buf, "tx_buf"); - - tx_j = 0; - rx_j = 0; - do { - - if (len_tx_buf > (tx_j + 4)) { - len_tx = 5; - len_rx = 0; - } else { - len_tx = len_tx_buf - tx_j; - - if (len_rx_buf > (rx_j + 4)) { - len_rx = 5; - } else { - len_rx = len_rx_buf - rx_j; - } - } - - tx_buf = 0; - - switch (len_tx) { - case 5: - case 4: - tx_buf |= tx_buf_ptr[0 + tx_j] << 24; - tx_buf |= tx_buf_ptr[1 + tx_j] << 16; - tx_buf |= tx_buf_ptr[2 + tx_j] << 8; - tx_buf |= tx_buf_ptr[3 + tx_j]; - tx_j += 4; - break; - case 3: - tx_buf |= tx_buf_ptr[0 + tx_j] << 16; - tx_buf |= tx_buf_ptr[1 + tx_j] << 8; - tx_buf |= tx_buf_ptr[2 + tx_j]; - tx_j += 3; - break; - case 2: - tx_buf |= tx_buf_ptr[0 + tx_j] << 8; - tx_buf |= tx_buf_ptr[1 + tx_j]; - tx_j += 2; - break; - case 1: - tx_buf |= tx_buf_ptr[0 + tx_j]; - tx_j += 1; - break; - default: - break; - } - - LOG_DBG("len_tx: %d, len_rx: %d", len_tx, len_rx); - i2c_litex_write_settings(dev, len_tx, len_rx, false); - - LOG_DBG("tx_buf: 0x%x", tx_buf); - litex_write32(tx_buf, config->master_rxtx_addr); - - i2c_litex_wait_for_rx_ready(dev); + k_sem_take(&data->sem_rx_ready, K_FOREVER); - if (litex_read16(config->master_status_addr) & - BIT(MASTER_STATUS_NACK_OFFSET)) { - LOG_DBG("NACK received (addr: 0x%x)", addr); - ret = -EIO; - } + ret = data->ret; - rx_buf = litex_read32(config->master_rxtx_addr); - LOG_DBG("rx_buf: 0x%x", rx_buf); - - switch (len_rx) { - case 5: - case 4: - rx_buf_ptr[0 + rx_j] = rx_buf >> 24; - rx_buf_ptr[1 + rx_j] = rx_buf >> 16; - rx_buf_ptr[2 + rx_j] = rx_buf >> 8; - rx_buf_ptr[3 + rx_j] = rx_buf; - rx_j += 4; - break; - case 3: - rx_buf_ptr[0 + rx_j] = rx_buf >> 16; - rx_buf_ptr[1 + rx_j] = rx_buf >> 8; - rx_buf_ptr[2 + rx_j] = rx_buf; - rx_j += 3; - break; - case 2: - rx_buf_ptr[0 + rx_j] = rx_buf >> 8; - rx_buf_ptr[1 + rx_j] = rx_buf; - rx_j += 2; - break; - case 1: - rx_buf_ptr[0 + rx_j] = rx_buf; - rx_j += 1; - break; - default: - break; - } + k_mutex_unlock(&data->mutex); - if (ret < 0) { - goto transfer_end; - } + return ret; + } +#endif /* I2C_LITEX_ANY_HAS_IRQ */ - } while ((tx_j < len_tx_buf) || (rx_j < len_rx_buf)); + do { + i2c_litex_i2c_do_tx(dev); - LOG_HEXDUMP_DBG(rx_buf_ptr, len_rx_buf, "rx_buf"); - } + while (!(litex_read8(config->master_status_addr) & + BIT(MASTER_STATUS_RX_READY_OFFSET))) { + /* Wait until RX is ready */ + } -transfer_end: + ret = i2c_litex_i2c_do_rx(dev); + } while ((ret == 0) && next_msg_is_available(&data->context)); litex_write8(0, config->master_active_addr); -#if I2C_LITEX_ANY_HAS_IRQ - if (I2C_LITEX_HAS_IRQ) { - litex_write8(0, config->master_ev_enable_addr); - } -#endif /* I2C_LITEX_ANY_HAS_IRQ */ - k_mutex_unlock(&data->mutex); return ret; @@ -363,12 +409,24 @@ static void i2c_litex_irq_handler(const struct device *dev) { const struct i2c_litex_litei2c_config *config = dev->config; struct i2c_litex_litei2c_data *data = dev->data; + int ret; if (litex_read8(config->master_ev_pending_addr) & BIT(0)) { - k_sem_give(&data->sem_rx_ready); + ret = i2c_litex_i2c_do_rx(dev); /* ack reader irq */ litex_write8(BIT(0), config->master_ev_pending_addr); + + if ((ret == 0) && next_msg_is_available(&data->context)) { + i2c_litex_i2c_do_tx(dev); + } else { + litex_write8(0, config->master_ev_enable_addr); + litex_write8(0, config->master_active_addr); + + data->ret = ret; + + k_sem_give(&data->sem_rx_ready); + } } } #endif /* I2C_LITEX_ANY_HAS_IRQ */ From 11ff520ec72a44d541123c01c2f1ad63f3e35d0d Mon Sep 17 00:00:00 2001 From: Daniel Kampert Date: Mon, 1 Dec 2025 14:59:22 +0100 Subject: [PATCH 0452/3659] drivers: input: cst816s: Add power management Add power management support Closes: #100300 Signed-off-by: Daniel Kampert --- drivers/input/input_cst816s.c | 172 +++++++++++++++++++---- dts/bindings/input/hynitron,cst816s.yaml | 51 +++++++ 2 files changed, 197 insertions(+), 26 deletions(-) diff --git a/drivers/input/input_cst816s.c b/drivers/input/input_cst816s.c index 84381bac4c2d..f718ef258c8a 100644 --- a/drivers/input/input_cst816s.c +++ b/drivers/input/input_cst816s.c @@ -1,5 +1,8 @@ /* * Copyright (c) 2021 Qingsong Gou + * Copyright (c) 2022 Jakob Krantz + * Copyright (c) 2023 Daniel Kampert + * Copyright (c) 2025 ZSWatch Project * * SPDX-License-Identifier: Apache-2.0 */ @@ -11,6 +14,7 @@ #include #include #include +#include #include LOG_MODULE_REGISTER(cst816s, CONFIG_INPUT_LOG_LEVEL); @@ -31,6 +35,7 @@ LOG_MODULE_REGISTER(cst816s, CONFIG_INPUT_LOG_LEVEL); #define CST816S_REG_BPC1H 0xB2 #define CST816S_REG_BPC1L 0xB3 #define CST816S_REG_POWER_MODE 0xA5 +#define CST816S_REG_SLEEP_MODE 0xE5 #define CST816S_REG_CHIP_ID 0xA7 #define CST816S_REG_PROJ_ID 0xA8 #define CST816S_REG_FW_VERSION 0xA9 @@ -88,6 +93,18 @@ struct cst816s_config { #ifdef CONFIG_INPUT_CST816S_INTERRUPT const struct gpio_dt_spec int_gpio; #endif + +#ifdef CONFIG_PM_DEVICE + /** cst816s power management profile. */ + struct __packed { + uint8_t auto_wake_time_min; /**< Auto-recalibration period during low-power mode */ + uint8_t scan_th; /**< Low-power scan wake-up threshold */ + uint8_t scan_win; /**< Measurement range for low-power scan */ + uint8_t scan_freq; /**< Frequency for low-power scan */ + uint8_t scan_i_dac; /**< Current for low-power scan */ + uint8_t auto_sleep_time_s; /**< Time of inactivity before entering low-power mode */ + } lp_profile; +#endif }; /** cst816s data. */ @@ -106,11 +123,15 @@ struct cst816s_data { #endif }; +/* NOTE: This results in reliable low-power operation with good + * wake sensitivity. Consumes about 80uA in suspend mode. Can probably be tuned more to reduce power + * further while keeping good wake sensitivity. + */ + static int cst816s_process(const struct device *dev) { const struct cst816s_config *cfg = dev->config; - - int r; + int ret; uint8_t event; uint16_t row, col; bool pressed; @@ -120,23 +141,23 @@ static int cst816s_process(const struct device *dev) #ifdef CONFIG_INPUT_CST816S_EV_DEVICE uint8_t gesture; - r = i2c_burst_read_dt(&cfg->i2c, CST816S_REG_GESTURE_ID, &gesture, sizeof(gesture)); - if (r < 0) { + ret = i2c_burst_read_dt(&cfg->i2c, CST816S_REG_GESTURE_ID, &gesture, sizeof(gesture)); + if (ret < 0) { LOG_ERR("Could not read gesture-ID data"); - return r; + return ret; } #endif - r = i2c_burst_read_dt(&cfg->i2c, CST816S_REG_XPOS_H, (uint8_t *)&x, sizeof(x)); - if (r < 0) { + ret = i2c_burst_read_dt(&cfg->i2c, CST816S_REG_XPOS_H, (uint8_t *)&x, sizeof(x)); + if (ret < 0) { LOG_ERR("Could not read x data"); - return r; + return ret; } - r = i2c_burst_read_dt(&cfg->i2c, CST816S_REG_YPOS_H, (uint8_t *)&y, sizeof(y)); - if (r < 0) { + ret = i2c_burst_read_dt(&cfg->i2c, CST816S_REG_YPOS_H, (uint8_t *)&y, sizeof(y)); + if (ret < 0) { LOG_ERR("Could not read y data"); - return r; + return ret; } col = sys_be16_to_cpu(x) & 0x0fff; row = sys_be16_to_cpu(y) & 0x0fff; @@ -166,7 +187,7 @@ static int cst816s_process(const struct device *dev) } #endif - return r; + return ret; } static void cst816s_work_handler(struct k_work *work) @@ -212,8 +233,8 @@ static void cst816s_chip_reset(const struct device *dev) static int cst816s_chip_init(const struct device *dev) { const struct cst816s_config *cfg = dev->config; - int ret = 0; - uint8_t chip_id = 0; + int ret; + uint8_t chip_id; cst816s_chip_reset(dev); @@ -233,6 +254,13 @@ static int cst816s_chip_init(const struct device *dev) return -ENODEV; } + ret = i2c_reg_update_byte_dt(&cfg->i2c, CST816S_REG_MOTION_MASK, CST816S_MOTION_EN_DCLICK, + CST816S_MOTION_EN_DCLICK); + if (ret < 0) { + LOG_ERR("Could not enable double-click motion mask"); + return ret; + } + ret = i2c_reg_update_byte_dt(&cfg->i2c, CST816S_REG_IRQ_CTL, CST816S_IRQ_EN_TOUCH | CST816S_IRQ_EN_CHANGE, CST816S_IRQ_EN_TOUCH | CST816S_IRQ_EN_CHANGE); @@ -240,7 +268,7 @@ static int cst816s_chip_init(const struct device *dev) LOG_ERR("Could not enable irq"); return ret; } - return ret; + return 0; } static int cst816s_init(const struct device *dev) @@ -292,16 +320,108 @@ static int cst816s_init(const struct device *dev) return ret; } -#define CST816S_DEFINE(index) \ - static const struct cst816s_config cst816s_config_##index = { \ - .i2c = I2C_DT_SPEC_INST_GET(index), \ - COND_CODE_1(CONFIG_INPUT_CST816S_INTERRUPT, \ - (.int_gpio = GPIO_DT_SPEC_INST_GET(index, irq_gpios),), ()) \ - .rst_gpio = GPIO_DT_SPEC_INST_GET_OR(index, rst_gpios, {}), \ - }; \ - static struct cst816s_data cst816s_data_##index; \ - DEVICE_DT_INST_DEFINE(index, cst816s_init, NULL, &cst816s_data_##index, \ - &cst816s_config_##index, POST_KERNEL, CONFIG_INPUT_INIT_PRIORITY, \ - NULL); +#ifdef CONFIG_PM_DEVICE +static int cst816s_apply_profile(const struct cst816s_config *cfg) +{ + int ret; + + ret = i2c_burst_write_dt(&cfg->i2c, CST816S_REG_LP_AUTO_WAKEUP_TIME, + (const uint8_t *)&cfg->lp_profile, sizeof(cfg->lp_profile)); + if (ret) { + LOG_WRN("Write power profile failed"); + return ret; + } + + return 0; +} + +static int cst816s_pm_action(const struct device *dev, enum pm_device_action action) +{ + int ret; + const struct cst816s_config *cfg = dev->config; + + /* For some reason the CST816S does not respond to I2C commands after we use the standby + * profile. Workaround for now is to just always reset it before we change power modes. + */ + cst816s_chip_reset(dev); + ret = cst816s_chip_init(dev); + if (ret < 0) { + LOG_ERR("Chip init failed during PM action"); + return ret; + } + + switch (action) { + case PM_DEVICE_ACTION_SUSPEND: + /* For PM TURN_ON means device is in suspend mode, hence apply suspend profile. */ + case PM_DEVICE_ACTION_TURN_ON: + ret = cst816s_apply_profile(cfg); + if (ret < 0) { + LOG_WRN("Could not apply suspend profile"); + return ret; + } + + ret = i2c_reg_write_byte_dt(&cfg->i2c, CST816S_REG_DIS_AUTO_SLEEP, 0x00); + if (ret < 0) { + LOG_WRN("Could not enable auto sleep"); + return ret; + } + break; + case PM_DEVICE_ACTION_TURN_OFF: + /* Put into Deep Sleep mode. */ + ret = i2c_reg_write_byte_dt(&cfg->i2c, CST816S_REG_SLEEP_MODE, + CST816S_POWER_MODE_SLEEP); + if (ret < 0) { + LOG_WRN("Could not enter deep sleep mode"); + return ret; + } + break; + case PM_DEVICE_ACTION_RESUME: + /* Nothing to do, device is already reset above. */ + break; + default: + return -ENOTSUP; + } + + return 0; +} +#endif + +/* clang-format off */ +#define CST816S_DEFINE(index) \ + IF_ENABLED(CONFIG_PM_DEVICE, ( \ + BUILD_ASSERT(DT_INST_PROP(index, scan_th) >= 1 && \ + DT_INST_PROP(index, scan_th) <= 255, \ + "scan_th must be >= 1 and <= 255"); \ + BUILD_ASSERT(DT_INST_PROP(index, scan_freq) >= 1 && \ + DT_INST_PROP(index, scan_freq) <= 255, \ + "scan_freq must be >= 1 and <= 255"); \ + BUILD_ASSERT(DT_INST_PROP(index, scan_win) <= 255, \ + "scan_win must be <= 255"); \ + BUILD_ASSERT(DT_INST_PROP(index, scan_i_dac) >= 1 && \ + DT_INST_PROP(index, scan_i_dac) <= 255, \ + "scan_i_dac must be >= 1 and <= 255"); \ + )) \ + static struct cst816s_data cst816s_data_##index; \ + static const struct cst816s_config cst816s_config_##index = { \ + .i2c = I2C_DT_SPEC_INST_GET(index), \ + .rst_gpio = GPIO_DT_SPEC_INST_GET_OR(index, rst_gpios, {}), \ + IF_ENABLED(CONFIG_INPUT_CST816S_INTERRUPT, \ + (.int_gpio = GPIO_DT_SPEC_INST_GET(index, irq_gpios),)) \ + IF_ENABLED(CONFIG_PM_DEVICE, \ + (.lp_profile = { \ + .auto_wake_time_min = DT_INST_PROP(index, auto_wake_time), \ + .scan_th = DT_INST_PROP(index, scan_th), \ + .scan_win = DT_INST_PROP(index, scan_win), \ + .scan_freq = DT_INST_PROP(index, scan_freq), \ + .scan_i_dac = DT_INST_PROP(index, scan_i_dac), \ + .auto_sleep_time_s = DT_INST_PROP(index, auto_sleep_time), \ + },)) }; \ + \ + PM_DEVICE_DT_INST_DEFINE(index, cst816s_pm_action); \ + \ + DEVICE_DT_INST_DEFINE(index, cst816s_init, PM_DEVICE_DT_INST_GET(index), \ + &cst816s_data_##index, &cst816s_config_##index, POST_KERNEL, \ + CONFIG_INPUT_INIT_PRIORITY, NULL); DT_INST_FOREACH_STATUS_OKAY(CST816S_DEFINE) +/* clang-format on */ diff --git a/dts/bindings/input/hynitron,cst816s.yaml b/dts/bindings/input/hynitron,cst816s.yaml index 02dc01f0390d..e79a1b8c1a59 100644 --- a/dts/bindings/input/hynitron,cst816s.yaml +++ b/dts/bindings/input/hynitron,cst816s.yaml @@ -21,3 +21,54 @@ properties: The reset signal defaults to active low to the sensor. The property value should ensure the flags properly describe the signal that is presented to the driver. + + auto-wake-time: + type: int + default: 5 + enum: + - 1 + - 2 + - 3 + - 4 + - 5 + description: + Auto-recalibration period during low-power mode in minutes. Range 1–5. + The default value is specified in the data sheet. + + scan-th: + type: int + default: 48 + description: + Low-power scan wake-up threshold. Smaller = more sensitive. Range 1–255. + The default value is specified in the data sheet. + + scan-win: + type: int + default: 3 + description: + Measurement range for low-power scan. Larger = more sensitive but higher consumption. + The datasheet is mentiones values from 0 to 3 as valid options with 3 as default. + But you can go higher as it is an 8-bit register and higher values than 3 seem to + work fine. They improve the sensitivity further at the cost of power consumption. + + scan-freq: + type: int + default: 7 + description: + Frequency for low-power scan. Smaller = more sensitive. Range 1–255. + The default value is specified in the data sheet. + + scan-i-dac: + type: int + default: 200 + description: + Current for low-power scan. Smaller = more sensitive. Range 1–255. + The default value is not specified in the data sheet. Instead, 200 is + chosen as a reasonable default based on typical usage. + + auto-sleep-time: + type: int + default: 2 + description: + Time (in seconds) of inactivity after which the controller automatically + enters standby / low-power mode. The default value is specified in the data sheet. From 6a432cfb5eaaf5a8f2e7eec945b3d6a40a401d1d Mon Sep 17 00:00:00 2001 From: Daniel Kampert Date: Thu, 4 Dec 2025 14:01:21 +0000 Subject: [PATCH 0453/3659] drivers: input: cst816s: Add motion interrupt Add support for gesture / motion based interrupts when INPUT_CST816S_EV_DEVICE is enabled. Signed-off-by: Daniel Kampert --- drivers/input/input_cst816s.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/input/input_cst816s.c b/drivers/input/input_cst816s.c index f718ef258c8a..f551d05b6825 100644 --- a/drivers/input/input_cst816s.c +++ b/drivers/input/input_cst816s.c @@ -232,6 +232,7 @@ static void cst816s_chip_reset(const struct device *dev) static int cst816s_chip_init(const struct device *dev) { + uint8_t irq_mask; const struct cst816s_config *cfg = dev->config; int ret; uint8_t chip_id; @@ -261,9 +262,13 @@ static int cst816s_chip_init(const struct device *dev) return ret; } - ret = i2c_reg_update_byte_dt(&cfg->i2c, CST816S_REG_IRQ_CTL, - CST816S_IRQ_EN_TOUCH | CST816S_IRQ_EN_CHANGE, - CST816S_IRQ_EN_TOUCH | CST816S_IRQ_EN_CHANGE); +#ifdef CONFIG_INPUT_CST816S_EV_DEVICE + irq_mask = CST816S_IRQ_EN_TOUCH | CST816S_IRQ_EN_CHANGE | CST816S_IRQ_EN_MOTION; +#else + irq_mask = CST816S_IRQ_EN_TOUCH | CST816S_IRQ_EN_CHANGE; +#endif + + ret = i2c_reg_update_byte_dt(&cfg->i2c, CST816S_REG_IRQ_CTL, irq_mask, irq_mask); if (ret < 0) { LOG_ERR("Could not enable irq"); return ret; From 495bf16234699dc1f29ad601db31924db90aa3ed Mon Sep 17 00:00:00 2001 From: Daniel Kampert Date: Thu, 4 Dec 2025 22:43:29 +0100 Subject: [PATCH 0454/3659] drivers: input: cst816s: Refactor errors and warnings Add error code to error and warning log messages to make debugging easier. Signed-off-by: Daniel Kampert --- drivers/input/input_cst816s.c | 96 +++++++++++++++++------------------ 1 file changed, 48 insertions(+), 48 deletions(-) diff --git a/drivers/input/input_cst816s.c b/drivers/input/input_cst816s.c index f551d05b6825..c0451f53d31f 100644 --- a/drivers/input/input_cst816s.c +++ b/drivers/input/input_cst816s.c @@ -143,20 +143,20 @@ static int cst816s_process(const struct device *dev) ret = i2c_burst_read_dt(&cfg->i2c, CST816S_REG_GESTURE_ID, &gesture, sizeof(gesture)); if (ret < 0) { - LOG_ERR("Could not read gesture-ID data"); + LOG_ERR("Could not read gesture-ID data (%d)", ret); return ret; } #endif ret = i2c_burst_read_dt(&cfg->i2c, CST816S_REG_XPOS_H, (uint8_t *)&x, sizeof(x)); if (ret < 0) { - LOG_ERR("Could not read x data"); + LOG_ERR("Could not read x data (%d)", ret); return ret; } ret = i2c_burst_read_dt(&cfg->i2c, CST816S_REG_YPOS_H, (uint8_t *)&y, sizeof(y)); if (ret < 0) { - LOG_ERR("Could not read y data"); + LOG_ERR("Could not read y data (%d)", ret); return ret; } col = sys_be16_to_cpu(x) & 0x0fff; @@ -221,7 +221,7 @@ static void cst816s_chip_reset(const struct device *dev) if (gpio_is_ready_dt(&config->rst_gpio)) { ret = gpio_pin_configure_dt(&config->rst_gpio, GPIO_OUTPUT_ACTIVE); if (ret < 0) { - LOG_ERR("Could not configure reset GPIO pin"); + LOG_ERR("Could not configure reset GPIO pin (%d)", ret); return; } k_msleep(CST816S_RESET_DELAY); @@ -245,20 +245,20 @@ static int cst816s_chip_init(const struct device *dev) } ret = i2c_reg_read_byte_dt(&cfg->i2c, CST816S_REG_CHIP_ID, &chip_id); if (ret < 0) { - LOG_ERR("failed reading chip id"); + LOG_ERR("Failed reading chip id (%d)", ret); return ret; } if ((chip_id != CST816S_CHIP_ID1) && (chip_id != CST816S_CHIP_ID2) && (chip_id != CST816S_CHIP_ID3)) { - LOG_ERR("CST816S wrong chip id: returned 0x%x", chip_id); + LOG_ERR("Wrong chip id: returned 0x%x", chip_id); return -ENODEV; } ret = i2c_reg_update_byte_dt(&cfg->i2c, CST816S_REG_MOTION_MASK, CST816S_MOTION_EN_DCLICK, CST816S_MOTION_EN_DCLICK); if (ret < 0) { - LOG_ERR("Could not enable double-click motion mask"); + LOG_ERR("Could not enable double-click motion mask (%d)", ret); return ret; } @@ -270,7 +270,7 @@ static int cst816s_chip_init(const struct device *dev) ret = i2c_reg_update_byte_dt(&cfg->i2c, CST816S_REG_IRQ_CTL, irq_mask, irq_mask); if (ret < 0) { - LOG_ERR("Could not enable irq"); + LOG_ERR("Could not enable irq (%d)", ret); return ret; } return 0; @@ -299,13 +299,13 @@ static int cst816s_init(const struct device *dev) ret = gpio_pin_configure_dt(&config->int_gpio, GPIO_INPUT); if (ret < 0) { - LOG_ERR("Could not configure interrupt GPIO pin"); + LOG_ERR("Could not configure interrupt GPIO pin (%d)", ret); return ret; } ret = gpio_pin_interrupt_configure_dt(&config->int_gpio, GPIO_INT_EDGE_TO_ACTIVE); if (ret < 0) { - LOG_ERR("Could not configure interrupt GPIO interrupt."); + LOG_ERR("Could not configure interrupt GPIO interrupt (%d)", ret); return ret; } @@ -313,7 +313,7 @@ static int cst816s_init(const struct device *dev) ret = gpio_add_callback(config->int_gpio.port, &data->int_gpio_cb); if (ret < 0) { - LOG_ERR("Could not set gpio callback"); + LOG_ERR("Could not set gpio callback (%d)", ret); return ret; } #else @@ -333,7 +333,7 @@ static int cst816s_apply_profile(const struct cst816s_config *cfg) ret = i2c_burst_write_dt(&cfg->i2c, CST816S_REG_LP_AUTO_WAKEUP_TIME, (const uint8_t *)&cfg->lp_profile, sizeof(cfg->lp_profile)); if (ret) { - LOG_WRN("Write power profile failed"); + LOG_WRN("Write power profile failed (%d)", ret); return ret; } @@ -351,7 +351,7 @@ static int cst816s_pm_action(const struct device *dev, enum pm_device_action act cst816s_chip_reset(dev); ret = cst816s_chip_init(dev); if (ret < 0) { - LOG_ERR("Chip init failed during PM action"); + LOG_ERR("Chip init failed during PM action (%d)", ret); return ret; } @@ -361,13 +361,13 @@ static int cst816s_pm_action(const struct device *dev, enum pm_device_action act case PM_DEVICE_ACTION_TURN_ON: ret = cst816s_apply_profile(cfg); if (ret < 0) { - LOG_WRN("Could not apply suspend profile"); + LOG_WRN("Could not apply suspend profile (%d)", ret); return ret; } ret = i2c_reg_write_byte_dt(&cfg->i2c, CST816S_REG_DIS_AUTO_SLEEP, 0x00); if (ret < 0) { - LOG_WRN("Could not enable auto sleep"); + LOG_WRN("Could not enable auto sleep (%d)", ret); return ret; } break; @@ -376,7 +376,7 @@ static int cst816s_pm_action(const struct device *dev, enum pm_device_action act ret = i2c_reg_write_byte_dt(&cfg->i2c, CST816S_REG_SLEEP_MODE, CST816S_POWER_MODE_SLEEP); if (ret < 0) { - LOG_WRN("Could not enter deep sleep mode"); + LOG_WRN("Could not enter deep sleep mode (%d)", ret); return ret; } break; @@ -392,40 +392,40 @@ static int cst816s_pm_action(const struct device *dev, enum pm_device_action act #endif /* clang-format off */ -#define CST816S_DEFINE(index) \ - IF_ENABLED(CONFIG_PM_DEVICE, ( \ - BUILD_ASSERT(DT_INST_PROP(index, scan_th) >= 1 && \ - DT_INST_PROP(index, scan_th) <= 255, \ - "scan_th must be >= 1 and <= 255"); \ - BUILD_ASSERT(DT_INST_PROP(index, scan_freq) >= 1 && \ - DT_INST_PROP(index, scan_freq) <= 255, \ - "scan_freq must be >= 1 and <= 255"); \ - BUILD_ASSERT(DT_INST_PROP(index, scan_win) <= 255, \ - "scan_win must be <= 255"); \ - BUILD_ASSERT(DT_INST_PROP(index, scan_i_dac) >= 1 && \ - DT_INST_PROP(index, scan_i_dac) <= 255, \ - "scan_i_dac must be >= 1 and <= 255"); \ - )) \ - static struct cst816s_data cst816s_data_##index; \ - static const struct cst816s_config cst816s_config_##index = { \ - .i2c = I2C_DT_SPEC_INST_GET(index), \ - .rst_gpio = GPIO_DT_SPEC_INST_GET_OR(index, rst_gpios, {}), \ - IF_ENABLED(CONFIG_INPUT_CST816S_INTERRUPT, \ - (.int_gpio = GPIO_DT_SPEC_INST_GET(index, irq_gpios),)) \ - IF_ENABLED(CONFIG_PM_DEVICE, \ - (.lp_profile = { \ +#define CST816S_DEFINE(index) \ + IF_ENABLED(CONFIG_PM_DEVICE, ( \ + BUILD_ASSERT(DT_INST_PROP(index, scan_th) >= 1 && \ + DT_INST_PROP(index, scan_th) <= 255, \ + "scan_th must be >= 1 and <= 255"); \ + BUILD_ASSERT(DT_INST_PROP(index, scan_freq) >= 1 && \ + DT_INST_PROP(index, scan_freq) <= 255, \ + "scan_freq must be >= 1 and <= 255"); \ + BUILD_ASSERT(DT_INST_PROP(index, scan_win) <= 255, \ + "scan_win must be <= 255"); \ + BUILD_ASSERT(DT_INST_PROP(index, scan_i_dac) >= 1 && \ + DT_INST_PROP(index, scan_i_dac) <= 255, \ + "scan_i_dac must be >= 1 and <= 255"); \ + )) \ + static struct cst816s_data cst816s_data_##index; \ + static const struct cst816s_config cst816s_config_##index = { \ + .i2c = I2C_DT_SPEC_INST_GET(index), \ + .rst_gpio = GPIO_DT_SPEC_INST_GET_OR(index, rst_gpios, {}), \ + IF_ENABLED(CONFIG_INPUT_CST816S_INTERRUPT, \ + (.int_gpio = GPIO_DT_SPEC_INST_GET(index, irq_gpios),)) \ + IF_ENABLED(CONFIG_PM_DEVICE, \ + (.lp_profile = { \ .auto_wake_time_min = DT_INST_PROP(index, auto_wake_time), \ - .scan_th = DT_INST_PROP(index, scan_th), \ - .scan_win = DT_INST_PROP(index, scan_win), \ - .scan_freq = DT_INST_PROP(index, scan_freq), \ - .scan_i_dac = DT_INST_PROP(index, scan_i_dac), \ + .scan_th = DT_INST_PROP(index, scan_th), \ + .scan_win = DT_INST_PROP(index, scan_win), \ + .scan_freq = DT_INST_PROP(index, scan_freq), \ + .scan_i_dac = DT_INST_PROP(index, scan_i_dac), \ .auto_sleep_time_s = DT_INST_PROP(index, auto_sleep_time), \ - },)) }; \ - \ - PM_DEVICE_DT_INST_DEFINE(index, cst816s_pm_action); \ - \ - DEVICE_DT_INST_DEFINE(index, cst816s_init, PM_DEVICE_DT_INST_GET(index), \ - &cst816s_data_##index, &cst816s_config_##index, POST_KERNEL, \ + },)) }; \ + \ + PM_DEVICE_DT_INST_DEFINE(index, cst816s_pm_action); \ + \ + DEVICE_DT_INST_DEFINE(index, cst816s_init, PM_DEVICE_DT_INST_GET(index), \ + &cst816s_data_##index, &cst816s_config_##index, POST_KERNEL, \ CONFIG_INPUT_INIT_PRIORITY, NULL); DT_INST_FOREACH_STATUS_OKAY(CST816S_DEFINE) From 1877410b2cebb7667ff746bea8c401cd5ddd09ef Mon Sep 17 00:00:00 2001 From: Erwan Gouriou Date: Mon, 10 Nov 2025 16:09:41 +0100 Subject: [PATCH 0455/3659] boards: st: stm32n6570_dk: Instantiate ext flash controller Instantiate a `soc-nv-flash` compatible node to allow using XSPI flash driver as a real flash controller on NOR device. Signed-off-by: Erwan Gouriou --- .../stm32n6570_dk/stm32n6570_dk_common.dtsi | 62 +++++++++++-------- 1 file changed, 35 insertions(+), 27 deletions(-) diff --git a/boards/st/stm32n6570_dk/stm32n6570_dk_common.dtsi b/boards/st/stm32n6570_dk/stm32n6570_dk_common.dtsi index ded1c0219998..ce141b53a939 100644 --- a/boards/st/stm32n6570_dk/stm32n6570_dk_common.dtsi +++ b/boards/st/stm32n6570_dk/stm32n6570_dk_common.dtsi @@ -23,7 +23,7 @@ zephyr,touch = >911; spi-flash0 = &mx66uw1g45g; zephyr,flash-controller = &mx66uw1g45g; - zephyr,flash = &mx66uw1g45g; + zephyr,flash = &ext_flash; zephyr,code-partition = &slot0_partition; }; @@ -400,32 +400,40 @@ zephyr_udc0: &usbotg_hs1 { four-byte-opcodes; status = "okay"; - partitions { - compatible = "fixed-partitions"; - #address-cells = <1>; - #size-cells = <1>; - - /* - * Following flash partition is dedicated to the use of bootloader - */ - boot_partition: partition@0 { - label = "mcuboot"; - reg = <0x00000000 DT_SIZE_K(64)>; - }; - - slot0_partition: partition@10000 { - label = "image-0"; - reg = <0x10000 DT_SIZE_K(1536)>; - }; - - slot1_partition: partition@210000 { - label = "image-1"; - reg = <0x210000 DT_SIZE_K(1536)>; - }; - - storage_partition: partition@410000 { - label = "storage"; - reg = <0x410000 DT_SIZE_K(64)>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x70000000 DT_SIZE_M(128)>; + + ext_flash: ext-flash@0 { + compatible = "soc-nv-flash"; + reg = <0x0 DT_SIZE_M(128)>; + write-block-size = <1>; + erase-block-size = ; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 DT_SIZE_K(64)>; + }; + + slot0_partition: partition@10000 { + label = "image-0"; + reg = <0x10000 DT_SIZE_K(1536)>; + }; + + slot1_partition: partition@210000 { + label = "image-1"; + reg = <0x210000 DT_SIZE_K(1536)>; + }; + + storage_partition: partition@410000 { + label = "storage"; + reg = <0x410000 DT_SIZE_K(64)>; + }; }; }; }; From 7de3e6acdd3550673f42bab1032f5b5c3ccd5e04 Mon Sep 17 00:00:00 2001 From: Erwan Gouriou Date: Wed, 12 Nov 2025 10:54:57 +0100 Subject: [PATCH 0456/3659] drivers: flash: flash_stm32_xspi: Allow flash driver init in ram load Current driver protections prevent to initialize driver when run as from an external application running from ext flash. Aim is to avoid performing full driver initialization of the NOR flash controller the application is read from. But this problem is actually only valid when application is running in XIP mode (read in memory mapped mode at run time). In ram load mode, since there is no direct activity from the application on the NOR device, nothing prevents the ext flash driver to be used fully. Hence, we should allow the controller initialization to happen, with some adjustments. Mostly, what we need is to: - skip the hal init - abort memory mapping afterwards to let the jedec reading happen. Remove conditions around `stm32_xspi_is_memorymap()` and `stm32_xspi_abort()` which can finally be useful in various cases. Signed-off-by: Erwan Gouriou --- drivers/flash/flash_stm32_xspi.c | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/drivers/flash/flash_stm32_xspi.c b/drivers/flash/flash_stm32_xspi.c index 5d5bd31bda5a..8784645bf5e6 100644 --- a/drivers/flash/flash_stm32_xspi.c +++ b/drivers/flash/flash_stm32_xspi.c @@ -997,6 +997,7 @@ static int stm32_xspi_set_memorymap(const struct device *dev) LOG_DBG("MemoryMap mode enabled"); return 0; } +#endif /* CONFIG_STM32_MEMMAP */ static int stm32_xspi_abort(const struct device *dev) { @@ -1009,10 +1010,7 @@ static int stm32_xspi_abort(const struct device *dev) return 0; } -#endif /* CONFIG_STM32_MEMMAP */ - -#if defined(CONFIG_STM32_MEMMAP) || defined(CONFIG_STM32_APP_IN_EXT_FLASH) /* Function to return true if the octoflash is in MemoryMapped else false */ static bool stm32_xspi_is_memorymap(const struct device *dev) { @@ -1020,7 +1018,6 @@ static bool stm32_xspi_is_memorymap(const struct device *dev) return stm32_reg_read_bits(&dev_data->hxspi.Instance->CR, XSPI_CR_FMODE) == XSPI_CR_FMODE; } -#endif /* * Function to erase the flash : chip or sector with possible OCTO/SPI and STR/DTR @@ -1218,7 +1215,7 @@ static int flash_stm32_xspi_read(const struct device *dev, off_t addr, return 0; } -#if defined(CONFIG_STM32_MEMMAP) || defined(CONFIG_STM32_APP_IN_EXT_FLASH) +#if defined(CONFIG_STM32_MEMMAP) || (defined(CONFIG_STM32_APP_IN_EXT_FLASH) && defined(CONFIG_XIP)) ARG_UNUSED(dev_cfg); ARG_UNUSED(dev_data); /* @@ -1314,7 +1311,7 @@ static int flash_stm32_xspi_read(const struct device *dev, off_t addr, xspi_unlock_thread(dev); return ret; -#endif /* CONFIG_STM32_MEMMAP || CONFIG_STM32_APP_IN_EXT_FLASH */ +#endif /* CONFIG_STM32_MEMMAP || (CONFIG_STM32_APP_IN_EXT_FLASH && CONFIG_XIP) */ } /* Function to write the flash (page program) : with possible OCTO/SPI and STR/DTR */ @@ -2093,7 +2090,7 @@ static int flash_stm32_xspi_init(const struct device *dev) return -ENODEV; } -#ifdef CONFIG_STM32_APP_IN_EXT_FLASH +#if defined(CONFIG_STM32_APP_IN_EXT_FLASH) && defined(CONFIG_XIP) /* If MemoryMapped then configure skip init * Check clock status first as reading CR register without bus clock doesn't work on N6 * If clock is off, then MemoryMapped is off too and we do init @@ -2108,7 +2105,7 @@ static int flash_stm32_xspi_init(const struct device *dev) return 0; } } -#endif /* CONFIG_STM32_APP_IN_EXT_FLASH */ +#endif /* CONFIG_STM32_APP_IN_EXT_FLASH && CONFIG_XIP */ /* The SPI/DTR is not a valid config of data_mode/data_rate according to the DTS */ if ((dev_cfg->data_mode != XSPI_OCTO_MODE) @@ -2195,6 +2192,13 @@ static int flash_stm32_xspi_init(const struct device *dev) dev_data->hxspi.Init.DelayHoldQuarterCycle = HAL_XSPI_DHQC_ENABLE; } + if (stm32_xspi_is_memorymap(dev)) { + /* Memory-mapping could have been set by previous application. + * Force HAL instance in correct state. + */ + dev_data->hxspi.State = HAL_XSPI_STATE_BUSY_MEM_MAPPED; + } + if (HAL_XSPI_Init(&dev_data->hxspi) != HAL_OK) { LOG_ERR("XSPI Init failed"); return -EIO; @@ -2268,6 +2272,18 @@ static int flash_stm32_xspi_init(const struct device *dev) /* Run IRQ init */ dev_cfg->irq_config(dev); + if (stm32_xspi_is_memorymap(dev)) { + /* Memory-mapping could have been set by previous application. + * Abort to allow following Jedec transactions, it will be + * re-enabled afterwards if needed by the application. + */ + ret = stm32_xspi_abort(dev); + if (ret != 0) { + LOG_ERR("Failed to abort memory-mapped access before Jedec ops"); + return ret; + } + } + /* Reset NOR flash memory : still with the SPI/STR config for the NOR */ if (stm32_xspi_mem_reset(dev) != 0) { LOG_ERR("XSPI reset failed"); From c520b3da1ae4c5ffc2433c3ab5c9357e4aeb921d Mon Sep 17 00:00:00 2001 From: Biwen Li Date: Fri, 17 Oct 2025 18:34:13 +0900 Subject: [PATCH 0457/3659] soc: nxp: imx943: m33: add and reuse api to initialize clocks Add and reuse apis to initialize clocks for netc and audio Signed-off-by: Biwen Li --- soc/nxp/imx/imx9/imx943/m33/soc.c | 108 +++++++++++++++++++++++++----- soc/nxp/imx/imx9/imx943/m33/soc.h | 9 +++ 2 files changed, 99 insertions(+), 18 deletions(-) diff --git a/soc/nxp/imx/imx9/imx943/m33/soc.c b/soc/nxp/imx/imx9/imx943/m33/soc.c index 64d9bfb5a261..7036c1fe8d43 100644 --- a/soc/nxp/imx/imx9/imx943/m33/soc.c +++ b/soc/nxp/imx/imx9/imx943/m33/soc.c @@ -15,6 +15,8 @@ #include #include +#define SOC_CLK_NO_PARENT_CLK 0xffffffff + void soc_early_init_hook(void) { #ifdef CONFIG_CACHE_MANAGEMENT @@ -23,28 +25,41 @@ void soc_early_init_hook(void) #endif } -#if defined(CONFIG_ETH_NXP_IMX_NETC) && (DT_CHILD_NUM_STATUS_OKAY(DT_NODELABEL(netc)) != 0) -/* The function is to reuse code for 250MHz NETC system clock and MACs clocks initialization */ -static int soc_netc_clock_init(int clk_id) +#if ((defined(CONFIG_ETH_NXP_IMX_NETC) && (DT_CHILD_NUM_STATUS_OKAY(DT_NODELABEL(netc)) != 0)) \ + || (DT_NUM_INST_STATUS_OKAY(nxp_mcux_i2s) > 0)) +static int soc_clock_set_rate_and_parent(struct soc_clk *sclk) { const struct device *clk_dev = DEVICE_DT_GET(DT_NODELABEL(scmi_clk)); struct scmi_protocol *proto = clk_dev->data; struct scmi_clock_rate_config clk_cfg = {0}; - uint64_t clk_250m = 250000000; int ret = 0; - ret = scmi_clock_parent_set(proto, clk_id, IMX943_CLK_SYSPLL1_PFD0); - if (ret) { - return ret; + if (sclk->parent_id != SOC_CLK_NO_PARENT_CLK) { + ret = scmi_clock_parent_set(proto, sclk->clk_id, sclk->parent_id); + if (ret) { + return ret; + } } - clk_cfg.flags = SCMI_CLK_RATE_SET_FLAGS_ROUNDS_AUTO; - clk_cfg.clk_id = clk_id; - clk_cfg.rate[0] = clk_250m & 0xffffffff; - clk_cfg.rate[1] = (clk_250m >> 32) & 0xffffffff; + clk_cfg.flags = sclk->flags; + clk_cfg.clk_id = sclk->clk_id; + clk_cfg.rate[0] = sclk->rate & 0xffffffff; + clk_cfg.rate[1] = (sclk->rate >> 32) & 0xffffffff; return scmi_clock_rate_set(proto, &clk_cfg); } + +static int soc_clock_enable(struct soc_clk *sclk) +{ + const struct device *clk_dev = DEVICE_DT_GET(DT_NODELABEL(scmi_clk)); + struct scmi_protocol *proto = clk_dev->data; + struct scmi_clock_config clk_cfg = {0}; + + clk_cfg.clk_id = sclk->clk_id; + clk_cfg.attributes = SCMI_CLK_CONFIG_ENABLE_DISABLE(sclk->on); + + return scmi_clock_config_set(proto, &clk_cfg); +} #endif static int soc_init(void) @@ -53,6 +68,10 @@ static int soc_init(void) struct scmi_nxp_cpu_sleep_mode_config cpu_cfg = {0}; #endif /* CONFIG_NXP_SCMI_CPU_DOMAIN_HELPERS */ int ret = 0; +#if ((defined(CONFIG_ETH_NXP_IMX_NETC) && (DT_CHILD_NUM_STATUS_OKAY(DT_NODELABEL(netc)) != 0)) \ + || (DT_NUM_INST_STATUS_OKAY(nxp_mcux_i2s) > 0)) + struct soc_clk sclk = {0}; +#endif #if defined(CONFIG_ETH_NXP_IMX_NETC) && (DT_CHILD_NUM_STATUS_OKAY(DT_NODELABEL(netc)) != 0) struct scmi_power_state_config pwr_cfg = {0}; @@ -74,37 +93,90 @@ static int soc_init(void) } } - ret = soc_netc_clock_init(IMX943_CLK_ENETREF); + sclk.parent_id = IMX943_CLK_SYSPLL1_PFD0; + sclk.flags = SCMI_CLK_RATE_SET_FLAGS_ROUNDS_AUTO; + sclk.rate = 250000000; + sclk.clk_id = IMX943_CLK_ENETREF; + ret = soc_clock_set_rate_and_parent(&sclk); + if (ret) { + return ret; + } + + sclk.clk_id = IMX943_CLK_MAC0; + ret = soc_clock_set_rate_and_parent(&sclk); + if (ret) { + return ret; + } + + sclk.clk_id = IMX943_CLK_MAC1; + ret = soc_clock_set_rate_and_parent(&sclk); + if (ret) { + return ret; + } + + sclk.clk_id = IMX943_CLK_MAC2; + ret = soc_clock_set_rate_and_parent(&sclk); + if (ret) { + return ret; + } + + sclk.clk_id = IMX943_CLK_MAC3; + ret = soc_clock_set_rate_and_parent(&sclk); + if (ret) { + return ret; + } + + sclk.clk_id = IMX943_CLK_MAC4; + ret = soc_clock_set_rate_and_parent(&sclk); if (ret) { return ret; } - ret = soc_netc_clock_init(IMX943_CLK_MAC0); + sclk.clk_id = IMX943_CLK_MAC5; + ret = soc_clock_set_rate_and_parent(&sclk); + if (ret) { + return ret; + } +#endif + +#if DT_NUM_INST_STATUS_OKAY(nxp_mcux_i2s) > 0 + sclk.flags = SCMI_CLK_RATE_SET_FLAGS_ROUNDS_AUTO; + sclk.parent_id = SOC_CLK_NO_PARENT_CLK; + sclk.rate = 3932160000; + sclk.clk_id = IMX943_CLK_AUDIOPLL1_VCO; + ret = soc_clock_set_rate_and_parent(&sclk); if (ret) { return ret; } - ret = soc_netc_clock_init(IMX943_CLK_MAC1); + sclk.on = true; + ret = soc_clock_enable(&sclk); if (ret) { return ret; } - ret = soc_netc_clock_init(IMX943_CLK_MAC2); + sclk.clk_id = IMX943_CLK_AUDIOPLL1; + ret = soc_clock_set_rate_and_parent(&sclk); if (ret) { return ret; } - ret = soc_netc_clock_init(IMX943_CLK_MAC3); + sclk.on = true; + ret = soc_clock_enable(&sclk); if (ret) { return ret; } - ret = soc_netc_clock_init(IMX943_CLK_MAC4); + sclk.parent_id = IMX943_CLK_AUDIOPLL1; + sclk.rate = 12288000; + sclk.clk_id = IMX943_CLK_SAI1; + ret = soc_clock_set_rate_and_parent(&sclk); if (ret) { return ret; } - ret = soc_netc_clock_init(IMX943_CLK_MAC5); + sclk.on = true; + ret = soc_clock_enable(&sclk); if (ret) { return ret; } diff --git a/soc/nxp/imx/imx9/imx943/m33/soc.h b/soc/nxp/imx/imx9/imx943/m33/soc.h index f7c1499faa22..4289a95a449d 100644 --- a/soc/nxp/imx/imx9/imx943/m33/soc.h +++ b/soc/nxp/imx/imx9/imx943/m33/soc.h @@ -7,10 +7,19 @@ #ifndef _SOC_NXP_IMX_IMX943_M33_SOC_H_ #define _SOC_NXP_IMX_IMX943_M33_SOC_H_ +#include #include #include #define NXP_XCACHE_INSTR M33S_CACHE_CTRLPC #define NXP_XCACHE_DATA M33S_CACHE_CTRLPS +struct soc_clk { + int clk_id; + uint32_t parent_id; + uint32_t flags; + bool on; + uint64_t rate; +}; + #endif /* _SOC_NXP_IMX_IMX943_M33_SOC_H_ */ From f809b159e6b27e2cb9be854f8ff90fc52484ba46 Mon Sep 17 00:00:00 2001 From: Chen Xingyu Date: Fri, 5 Dec 2025 11:19:33 +0800 Subject: [PATCH 0458/3659] boards: waveshare: Add ESP32-S3-GEEK Add support for the Waveshare ESP32-S3-GEEK USB dongle. It features an ESP32-S3R2 with 2 MB PSRAM, a 16 MB on-board Flash, a 1.14" LCD, and a microSD slot. Signed-off-by: Chen Xingyu --- boards/waveshare/esp32s3_geek/Kconfig | 8 + .../waveshare/esp32s3_geek/Kconfig.defconfig | 24 +++ .../esp32s3_geek/Kconfig.esp32s3_geek | 8 + .../waveshare/esp32s3_geek/Kconfig.sysbuild | 10 ++ boards/waveshare/esp32s3_geek/board.cmake | 10 ++ boards/waveshare/esp32s3_geek/board.yml | 6 + .../esp32s3_geek/doc/img/esp32s3_geek.webp | Bin 0 -> 39092 bytes boards/waveshare/esp32s3_geek/doc/index.rst | 65 ++++++++ .../esp32s3_geek/esp32s3_geek-pinctrl.dtsi | 58 +++++++ .../esp32s3_geek_esp32s3_appcpu.dts | 30 ++++ .../esp32s3_geek_esp32s3_appcpu.yaml | 28 ++++ .../esp32s3_geek_esp32s3_appcpu_defconfig | 4 + .../esp32s3_geek_esp32s3_procpu.dts | 150 ++++++++++++++++++ .../esp32s3_geek_esp32s3_procpu.yaml | 13 ++ .../esp32s3_geek_esp32s3_procpu_defconfig | 9 ++ .../esp32s3_geek/support/openocd.cfg | 10 ++ 16 files changed, 433 insertions(+) create mode 100644 boards/waveshare/esp32s3_geek/Kconfig create mode 100644 boards/waveshare/esp32s3_geek/Kconfig.defconfig create mode 100644 boards/waveshare/esp32s3_geek/Kconfig.esp32s3_geek create mode 100644 boards/waveshare/esp32s3_geek/Kconfig.sysbuild create mode 100644 boards/waveshare/esp32s3_geek/board.cmake create mode 100644 boards/waveshare/esp32s3_geek/board.yml create mode 100644 boards/waveshare/esp32s3_geek/doc/img/esp32s3_geek.webp create mode 100644 boards/waveshare/esp32s3_geek/doc/index.rst create mode 100644 boards/waveshare/esp32s3_geek/esp32s3_geek-pinctrl.dtsi create mode 100644 boards/waveshare/esp32s3_geek/esp32s3_geek_esp32s3_appcpu.dts create mode 100644 boards/waveshare/esp32s3_geek/esp32s3_geek_esp32s3_appcpu.yaml create mode 100644 boards/waveshare/esp32s3_geek/esp32s3_geek_esp32s3_appcpu_defconfig create mode 100644 boards/waveshare/esp32s3_geek/esp32s3_geek_esp32s3_procpu.dts create mode 100644 boards/waveshare/esp32s3_geek/esp32s3_geek_esp32s3_procpu.yaml create mode 100644 boards/waveshare/esp32s3_geek/esp32s3_geek_esp32s3_procpu_defconfig create mode 100644 boards/waveshare/esp32s3_geek/support/openocd.cfg diff --git a/boards/waveshare/esp32s3_geek/Kconfig b/boards/waveshare/esp32s3_geek/Kconfig new file mode 100644 index 000000000000..02d812e54c3f --- /dev/null +++ b/boards/waveshare/esp32s3_geek/Kconfig @@ -0,0 +1,8 @@ +# Copyright (c) 2024 Joel Guittet +# Copyright (c) 2025 Chen Xingyu +# SPDX-License-Identifier: Apache-2.0 + +config HEAP_MEM_POOL_ADD_SIZE_BOARD + int + default 4096 if BOARD_ESP32S3_GEEK_ESP32S3_PROCPU + default 256 if BOARD_ESP32S3_GEEK_ESP32S3_APPCPU diff --git a/boards/waveshare/esp32s3_geek/Kconfig.defconfig b/boards/waveshare/esp32s3_geek/Kconfig.defconfig new file mode 100644 index 000000000000..cf5d73b2fe14 --- /dev/null +++ b/boards/waveshare/esp32s3_geek/Kconfig.defconfig @@ -0,0 +1,24 @@ +# Copyright (c) 2025 Chen Xingyu +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_ESP32S3_GEEK + +if DISPLAY + +if LVGL + +config LV_Z_BITS_PER_PIXEL + default 16 + +choice LV_COLOR_DEPTH + default LV_COLOR_DEPTH_16 +endchoice + +config LV_COLOR_16_SWAP + default y + +endif # LVGL + +endif # DISPLAY + +endif # BOARD_ESP32S3_GEEK diff --git a/boards/waveshare/esp32s3_geek/Kconfig.esp32s3_geek b/boards/waveshare/esp32s3_geek/Kconfig.esp32s3_geek new file mode 100644 index 000000000000..e833cc12f4be --- /dev/null +++ b/boards/waveshare/esp32s3_geek/Kconfig.esp32s3_geek @@ -0,0 +1,8 @@ +# Copyright (c) 2024 Joel Guittet +# Copyright (c) 2025 Chen Xingyu +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_ESP32S3_GEEK + select SOC_ESP32S3_R2 + select SOC_ESP32S3_PROCPU if BOARD_ESP32S3_GEEK_ESP32S3_PROCPU + select SOC_ESP32S3_APPCPU if BOARD_ESP32S3_GEEK_ESP32S3_APPCPU diff --git a/boards/waveshare/esp32s3_geek/Kconfig.sysbuild b/boards/waveshare/esp32s3_geek/Kconfig.sysbuild new file mode 100644 index 000000000000..8d3acb9e11d7 --- /dev/null +++ b/boards/waveshare/esp32s3_geek/Kconfig.sysbuild @@ -0,0 +1,10 @@ +# Copyright (c) 2024 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/waveshare/esp32s3_geek/board.cmake b/boards/waveshare/esp32s3_geek/board.cmake new file mode 100644 index 000000000000..f8867d9d0b65 --- /dev/null +++ b/boards/waveshare/esp32s3_geek/board.cmake @@ -0,0 +1,10 @@ +# Copyright (c) 2024 Joel Guittet +# 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/waveshare/esp32s3_geek/board.yml b/boards/waveshare/esp32s3_geek/board.yml new file mode 100644 index 000000000000..8202ff84680c --- /dev/null +++ b/boards/waveshare/esp32s3_geek/board.yml @@ -0,0 +1,6 @@ +board: + name: esp32s3_geek + full_name: ESP32-S3-GEEK + vendor: waveshare + socs: + - name: esp32s3 diff --git a/boards/waveshare/esp32s3_geek/doc/img/esp32s3_geek.webp b/boards/waveshare/esp32s3_geek/doc/img/esp32s3_geek.webp new file mode 100644 index 0000000000000000000000000000000000000000..093fea184711986d47bba92a7a226f9d2219d656 GIT binary patch literal 39092 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,^@Q9#`n<0zh>sTN0 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
3RxI|-f=dto7k!XaxqeRQ9o`{D3OFX;)cpttY5 zbe2C(Wz)CrtPN0*F#?JAE_8A8Xy1B%ev(0%g;hK-`D->yPsO~9QC7_oDf@@#P>hnVeBf5^!VicI6}_@f)p|z8lnt8qw2r1 z1sL5`XvDc!*}$(ib5_8sWb-BZ1g#o>pa1{>7>#34^=G5H+yEPI4UV23I@rsrqTo&I zTzS}E`426D5Ou{O@Q;2aiJ*|3l)Ht>5kMT_ri1#7#0zAkq>Eza8^NSg)?gne(KH$ z6mD2yGfRLN_3<5XWfg>dwo*VToarb0+^3f#I2H1SXmUtU2XL=l+|%S2b@3&f{z&bmshaXAnSb#gWVkCfn{r zzZCHC(67~#h$$bD2qz7+b~8A#a$*`!7k{)Sf{k=WLjbvwGY*Cuq$F|g$R1z|Oyfcb zB)Hll4Zx{7&pAABB8IdTyKHX9b_^SdjGI}E!rr^v^3_C_~&uf$WlII6ixbyVaL?1{Rd8|u1}%mg7fy$l=o zOtd1%-qCpbCTmii!@_>@9UgT=>&~OKh8apX(`x|)z?P4iGm7!WEf0Sa2Xop}K9l?& zjMx*yL3GHi$6j_5Ogv_mUjk5e5Cu8v#TD`r5tZ5tr=+u8fo99WLCdWY5)cqS1;-xZ z&chWSdoJ}U1;G4bsaO}}$UH#TO*}j>0|rnFN1#kPWPZ3P#=_?xZh0fINsp**O%br? zv&%Q$D5it@L1RS zU#gRrj?I?a1Fz1M?@{Pr2P5DcGF=1Xc!0)3(!ZDVMK{uqB%0%5GzyOoeH!-s7oQL> zn&}ae-YljImQ}%Mtz{T=<5OmQl$jSrXb}A=UrLK0ON5slJr(u#jn*T&d}>f(JO37C z?FYw&wFV%G945ucy`!F6t0Kx=BM~=wD=j}3q|(4nU{@78=*6AA(dk}H{pBPkc0a3Y zUc^OKN}O2(2W;UjW(p-_-~zrV#r`i9PLZ>n$=_*pmTLgPh1BtzkePtL^r%{q zuPSB*L)BI^_kTymD66*Q)eYOQHsK@_Zwz3*3VXlDdD*T5jz+oeapB;sjV-^K6JIub zp{ek#p@22$V9QOET@EzV)L7N={E@qy=t(XtN*DcFCP9)F(WGfN4wlI>Q?dLTY}@@x zx70Okp+KVk+H~pU^mbKs$+3tr-0)f*CxE?)~7ECqo@D8Zs$& zS*&h5Kj@~+Q)|(b{O8BB=Yr(v$ydKh_aJ)xDe?cf*Lu^&K>?hD zJD+4mYdC^PI*?7o$ZZ(5x1pEbQOnW=6)s>D2A*H1g3CtqNsk4GNjs(`6tK?su2X_Q z7tceC=y{W2%1T;Vn+~g=-z~p1MH?4*bA02G1E2nhuT;eY+3eA8Zf3bj zcy;Kh&D%!Q_IQ2KI#h9ApR#~&aS4aZi$*hu)H$mR^^>Vqn&_&EOTGBl;puD6WOGB=AMmjaH-L~gwhIpERL{Y{+nb9w)2FEs1fuH5nNVUgA%QJ^@hlP zo-6dk=))_W4Uy|yATtdFivJuBe}0_DVi~%v2$Lw`U2)ZSr%bcLT6lc-N-!aa7e#Oi zG%_FiOao|`14TRUb+_%uLVJ%SPtD@UF=Hih{Gd|YrO+|QMe!1STM6;>Qm)c!4m1imBynQRWttzV(r&FHw-P zVqQZ_l`)^;H;P-%CZ8M{C=|4Py~n$PxweX5*=kmzV>*6`)Sr;s+TRN0rkIgR10Mo5f3oJJVY+z`d8kzB0+G$}h}O@x z2nZHyLVyfQe}r|}6}v*Md@2o{a5qTYpih5M&xM(H58>JAtoIyD(W!W&+4p@HlQfpX zrvdnhA&?0Tz>fRM&P`sAQhOTaQ_Z6R;=rFIHx#y`*3EMvDHZFJlM*E8_q7<;+Of>= z%oIKlPfBbuRK2R?R#CpG($44cZDB@A)Qx9y@fWmFA2%Y9^0hi zvG%tGyee`+WGjQsmR~_m*nU0n59T|2l{9o%$tWYvCr-jJ0&Vbq;`fddsbYCSA;0QZ6hCBZ7JaDx=yU%iuPH zL+54f6XY3`Rxbkyh?d(j-<=+-iyA{ip%xX$>FhU%ZR4tHuLO$paeVS6de%mh@Ff@C z94X=SXlvJ+#Y$W!;xc>ulqznCA_rWigy60N{N`|2ZZrvS3?5raTlE@gt9tonpN)EU zzFQiPKaT7!@(J`sFoBa@;&l`Kc8qlUaVEUbbb$^FB@Z0jXym0K)Ji9`&0x83H;A@* zn1@t~y`r=ZDDVK-RQ*>+*_QuX)l%YC@JxNr%?q`qKCh?IgrKOoB>8a z0iMjKb>3{mb`sB*C{|sl?{qbJlR{j<=o=~cP(P9zTMUM}>4<CbvEydgvF>e5@nF&`2*mfml`4cykFd3y13M-J%K<7^!8g zm*`(+vu1fiM2app#f2JWFG49KJXH>E%OuSkrR2)n#&Zq#mcm(fVF}~dKG6vJNB+J2 zcD*U9!;+O;pvW7m-_rhgtF(x8t2i{t-6(dm`^Uo`IsgD(L1iytzl4bUNMt?d7;!Xt zLauAq<{_)FQ`sxI6NRq_B#w4>aKdT2p;D52k~*OPU@fCWw-8PzQjqwk)?^p2vT?Fx z13SV+H*w3~FdGsbzMixNZ`=s)MbUtZ(^v9&sd0nlUOr5Br%^z=y)C+LaB5~49=u`i zg$Bi#`lc+FPOrs<@i@efq;&d&E<_x2c|f}4mA&5zo#8os2Ofnj^~<6PJ2#2K)K^u# z^te3(Qlv@+?VMh-BrUXQPMDZdX#=^-tw1LSdkzco8hyx}tcNxOt%0JARzY)67RF=E zb>n*pJ&=3M;RIVpKVCBOr9yS%_T0V^Rn>Iq6PUd85gW!{LkcQdW-KwyM^8mmmK-{Mgu#J-S_`=6(g^q23wK+;O6wu+%#bZbSDy9~s-mSPu|GCXfLt4i}$19>s zvpu_vegplP+x3NB^SGVfsF@76^NmNkes%_kK^?R=ZTZbBKo3D~v|jxI?pmOmeT0{w zQKb=TvnKmkye=~+R-T$`R~a%uCMHRUvM?-mW9+S!tQG;3>sTGb1;WgfLF&ynxz&Xs z+dS{)1@&iFV-)|@^F)wzEwGpmnxl-HD~$TwNU*`o8nHKiqU)~xS?W#mXH-;X6T&j7 zp8R%oMvChqVtIK2JmTtZz5mua>tS{^nUt@SXqRn*lD2uR;{`c`;W z)2aj5k|-^-A5?@GP7*It1s1nG+W=V)UYvhZIK3i=4oW_+-(yEn}KUqw2cqp|4C47Ki?c>N+u!42b zxQQ?G;6coyd!thvf+8xj7H1XKk6nq;*^>6#UR$Mj{J|hsX`H&5vcrt%xR3hgoZWCH|_d)tc&HmL@mFUzAg8I$I(Szzpw{r&<7yk zki`0lh%aZwaL+J{rE=E|-%3k{@fOde?GBm;VuE;gt3Z4Dg7QOT?WW|pxVOh@zjxVk z27L9Irz~_m3_6D>8jO6A6uLo={&wGC{ki@*#Nu<2Yg$mh{ZWN+W)o7XEz5Pc6^qWQU)WGjtTl7x>}7(QN4c`kBzpWstP z{-VVbN2io>nm_$gh?0mLwL}6@LGg z;k)Q2l;^xbO7*7bAOz30+i?>rNoA^+N%m5)q7tM(2CU<0%K%5RUl85>uKyW2t!~Z&9|7xCM%B*h%7FoLteteiNH_Tbm&_A2Po$eN6eLwn7 zxo4!%U4GUj#fLC8XmF-yN)uf?V%YL)y+U?GRk4Cl3nNECRKH%>#>g>NENf0Q5oWVA zh0oLhJENlL&v6w{y4sh_o=F6@u=Itxer8VFmUwyhe*S15Y5TN`&CAQhJJ*C(xD6AT zcH94aoub-J@Z$TD8iWt8={Yq1<&vW#2Atvj|#b_}#edhqNK55-AAH zn^L)A+Sak+xh&6+N<*E*-JT)|H%wa?06fN)!Wj*i6b!4EAM;*yB-jkRy>jut z1HYmPG|;~%>8`@#dCLY3*Xd`&-XW{=7udFs=v`H(hT?ExgVZ9UL&?E_6J>VJBNI3L z%@mb2HbrHw*lz|3^%>K^w5l<5VRS}d^WrC<2G9TiSU$wWu)^YV56cWLL8)< zk_`xjo*?Ro0@0Nf5kepLuJ}Aqs*QZvi-iP~zw5lr3Yfj5EdozoxFRkuYafe#R zKBQzgT91#!Pp^2DTGE+fGrsTv1aheHRn!_L7EaJDnTe)mIi7sT$TvtPU51 zc=>Nn3<*40=-p}Hw`HArnF>Q@4`U}(pzLOIEX8@dxlYh_$=8pf^lmXX7PC6!+klH6 zv}j5gi0^3*)~w-+(xn$i02?w?B+*h>C6<$k&{04-(WE=YcFjwlfXpLU_ys5CxAzf+ zs*4TKZ*RhMvbaPDh!78WtS)^7cBRXSk5^;^xh+6rwqZ$|M<%)Zahm@I5+LGd*38O2nPPy1oT9*=clANvWIg z0rL9=c?Q3js|M)gts}^uD{lWwmog4rYw}_$s4c`q^y!pSiK-${8XK5~`@+0Io)uTz z&Om2CWibZT*~@(*{7wk7d@NgKbpkI=TX#bc0Fh~>Aq%dUzbGB3G=I3h`k_ORoXZQh zY)ai&0d~;A5KxVHU5$qR9o90FN9cI!b_1TqN7yH|Rti!pW%hJYr@yIEvU}-Xz+A4p zg`8l{M(deT)5a47ZJ*Ze4Req-)@C#2@^Cc<*?ZiYK{K;CH?v zpL+wEyQ&D9M8<=Btt9%;@qrkV?vlOj&&X1b-!K8L4IU1Wfv=3>|A)cW2W$0}7}{{O zd6rRehV!i7OTZb#%{xhdwjgwF8AL~2a(UmT)*lV4sfM%hjPmK9tVRfnsRm0NRca`Nqoye6uuruZOW00b ztUJ;M)Zah!7z10|<|b!~uRekzV4u*vI-@FI`1nJZS}%|AFB@!ak;zZZg=kd3*=YGEWGRjSh(8uaK zk|!cG!ViTWpp(dbk0UnUD}SqP&R2Lc$p-oNL=Po+%*AKBtt>udlXk!@ryZ8w5oJ0G zJTz+_&@Po6bZM0slEOw4tyJlHnm>}|*rUz3UgSltXqf24hF%9O1>n?cB~us1ISxdG zsCHG#%hg`f+(7u-EC)U$2HSXlQyk$@#)7Pr5fw(^fYH zBxwpnn@*ijw0fYayvmC%PP21U1CmJp-VFqmWQ_SYw)KfV2X4Sa{!cb{+Kt@+GN{+{fe;+bMB3{3E_U2oZ+N}+fcNce z=Hg7HK$1q>qRT3}+Ll}09lKK1A=mqQ0}-i5g%#-R2C!fch!rg#H(6NRV?qB873|_m z0BLDqqs2mYlBwc>SOk6L;JZ=9(}}R*53uwQDk(9_gXGoTLL(3_8i%)3P9zzgBpmPC zh34~7CJAHRW}FO|2o23a5h6jFgyF{xG2GOii2szUZ_1&>>d_0biPewSu#M06#p-_C z5>xxeQTGi%lcEgEF8S}DXD1ip#G%*9HCg9_V&xSMiocyr(PeL06^RERl1`53oVWd& zhZ>xJAvlOjml^sc+2tV`XI#lrVSX*GVL_jDeHVgNIK66UMYlVBJXteQFXbeH(ds=u zbJVx6ap`5@WnHB`OZ*TUMI*Vxcx;1IVdMKkE3swip~Hg9t%OldeYNu;#~ew2$L;(- zkp1ICeV$4VM{l-Vfn(0?`@t?@HSm3{Y>Vde>m79Qj!JagcRUv1xpuFuY28tJ0h~m5 zssHBse+peBJvF^ZHT?~!%hLalITIC`3t|=iVYUVipIvtPfs?tWfRCZS;JcLF?FaCD z#xm)0#Ws^Xapvx_`ZU}omNQLB%As-TOlZvYncZcgcuAh;x<6E>WQBc9j7SC*HTu{z zGUhvypDpnt(ibF%Jgm?Ee{&dtQVyH=4!H=OjYB^5r1cIq7+U8g4yDyE5HWpoZ5weV zv5H#2BmZ0zLo8%h^M{>`H%CKpXvj2fOLkW&(8rcjCXrssaU~b%KNDRg3dPblAH(5f zbY8g-olo6)?@rm_!Ai=QuH!&h0hx&vgqSwDXZ7u}(HrXVwA1 z(72{w!(Rrp3-r}QNNd5(V21NwDb~V1vJF1%o4ntSto;vk+h?7vP%QV$X*hwR`Cycz zOJurzL<`P&7;@Cn4l;q{AspRjZ!4XLDyCJn9-0UpfhXsK@^kiM5JJVcMcD0ltDz(H zbksTyks&piTNL8^=iH!n1wq7$0dNjbIn(BR_(#%{H${FG$Moj-yLMZ6E31Y1F&z*F zyyqMV2;GPqGR1U?ajxyaQ}cSqr<)LUYXFDQ9r=%nC zmJPMp(BBO_1{iM!9vi!LS%x=vn|g5~F1Bxn$73MLS|hTETC&t0A4xvFJ%m-csVVmu zfYwsaW=oMxu;{YmL5Sa)bH!$4ffp{vy{9} zpM)u#o5EXNv8v`m7voD;pym@E8=1?(9>2$GJQor@SWkJ`XaZ@B>a;^q{o=pNjj-+v2^e;5C+>#S4C(hsbxqE-_Fy@7TEMmY z)@2kwL0_@MbC@&wx5Tr<3&)vVd;eXysjHK-=&>_lnGY*8fc_~puG{;6-Kn|E3oq3X z^?w3k!Z3m*@q>&EnXX@=4Sdt0yVbw}FENI*%C5{&6aJGV@D2i(Q2Pll{3*Qv#tk5k zy&Z(WhYBD@14mqY3k0Xt{#!qP9p6EVx8 z0Y9+n=#=whJ&lcV-j~Nr)Q&j{P!c?gDENI92vy_F1*#a=0?Qv27}+Rb#sbary@>cANr84w0g^aO#_7w*B;v6)BRK6efCuH=i8mvdfoFyj*mzZUn_cDh zha$#8Kp$2gK*73YodFWguK@k!<#dbi+7O9!l)GyY#h#hr<`nVzB&8&)%yg?}Pc)dEOySj|iRXl^RfLRmJJxVx&XWXjom=Mb=r3JiDq1gjP^R3Ssx3quClYNdMw6 zP#N#=>e41JN!ecWu4NI{P(OTkTzTgJF6=)X@Kw*SahoV;+=ayVP478hOLm@l*sd0s z`2+H#kI5QNe&|1(6(T{NR*hFW_fEjU=gYvoOg_HSuTtB{sPJH=? zB=k&tCQ4hH3QLER6R0b^{BRx4Biur9s}7Fhh%5!7JfwAy16*n?P-ksvq~K>nupdJk zGw~v!WG%64j5hll((fEUfoSAcV_VAym`+$s%kmg$3DiR!NPO`V6` zw<02}e@mcWlo*2J53aDTE>bJDbYF<{oVlNE?r&PB?7`IBvKvy0eOx>MOZrnjZa=OS z38SG*DNN$D**o?e+e^u8QP=ZA3;q3JKy{)67 zbVm%zNihL!89)6*P%_`0ZTQl)MQ`Mc9YnxI*T1z$4UeA#=0~%k_`C+wJ+G((bGZB` zH32Y-zB|gAss@arFGaC1LvE8bj*hc z=N;KHOCu;c4ETuG9ZA>}V04tIGL^*?(q-~dy%W;)N&~=1gv+0+*_Ew^sXSf|73Qc+{&Ob+0>9@quBKq$`K9B8nIXHV%r5F5>c(e1 zLVQ}({jD~)P-N9F7r*9+ajurmh2x)(8*l+Px=NUxI)q+X<}eUfD%Fp5qx5N1IRbZV z2oJ)iiH3XqWkC#wyH)GJ42f52{=~L-OlM+FSdJPhQCXc5h}N%!yguKWEn`b$xX7~P z_&9*bzci>EuDs% zMz0TvaeXgZ*}h9Nra~6D_JgdXaXqwQoJ!C|wb+x^7 zG1=TqLjd*srp8Jkm}^dIoLB`;cj^D+0Vx4OWf#r}^(Kf2@UZjN3kj65!Kt`i2{t*Y zV>*c99#szUlBDreE?$LU{G*Hl%FpQr$Y|_L46pnEjw}DNnYTYz2~ZZ2%?|8{l{1iI zechTqbgB5)xrqs=t>8hLP*aPbpA#3tF@h@bQq*qIDzgNivnUVyXh2CR8Q5U1-Xj-I zXk>HDyxkAiXXqqnw>(Ny1JwXJ>0o?jQSAJGaLhfAl@Bc=A8$DHDCwK}JcrxhBIRq< zr&NY@6Tj?HO>kK6L9X~6rFsA+z544Q7BsO%g=efWE|TcQAbeUu@PO%X@G;zUhu^_^ zy0YqTc-9U^#(*{yTjRb|V0bA5cRYb+?|M6n6%LW{$*+c!;7y#i# zIn?ou0%2d|9EbvM`Pk^{>Q>YR>9?INswV1A=(+jg<6HhWO%lP+1+`M|FtT@;A zdZopyOlK;b0`SV2cCv@)bT=C{e#=-f(@k+fHu#I4&-Gk~+T2R^YxYO}CgTtK(xwY; z2_*{Tr}r5RId-CY6`I_C?$}_elRxa-v_(teeN5&7-B>RFTzi&dExH#S2&){BrS z?${P|!sXew7~xcJMd_~t(p6B%~F!mn+Y zOL7=aWiW?FqC2xrxIs{=Pk^t}h;NC?Q{FS7!Z?&o)2=loR8Z$(*dq(6ktK3OG39jO zS*CITSxs@n*Z|+sICEEbIZRr4mWx_x^8YV(gMnhp?|IMQiN=aK_(00=ZS!)rJp^^J zIgVMtxxQfVzdxS3<014Z2>1K>HJWoQ0QBqtIPOz#cGyzr=~MVanH~VnPN9z(!HAv) zx(CG=rV;=|CBDkU%G%AD{A4)BCnb@_Cg1s}$|UMLWe=aIkpJR)Nnr*LQYDh8ysJGf z67UARn+{=muHgfJV;d(G0DtdEKq1;+W%uS$TKqMDM797>bnL!O9UB}GGb6mOT1b2a z)~fcY$YuOqV=ie43^sU7Fb@sDjY?B;`I+n{UQ%;#I)9K)1rautssQp=-*JrL7%!da z_z+*raKm?_IuLhoFiW>-YPVaO8j0g`JV)1Z$fzYg) z2D7Dy`ICf)(n`Mi5gu}@4G_c>z0Kc01=P|H8$hzeGm|(jFDs1|FL2lYN{Gu{Iib)3 zeDYLeF(0|C@BPKG0vG>Q_X$dq46pKmVMTK~FyGc?vzG)=_RE@y1QgS78Y5SZlp^o0ZI9mRHVC+?q)%{4?p6}_1w(d z%=64!&~r``+W9OO+S|y9J}&#z;JR?^+j2wH+UZVb{i;8an~;XK_P)~Sa;9PcjMRXX zz;E%v pny)t?QO`XE8=x+x<$1qL7P~yoA%jiUcu}>Ho^Sfk}3mF&mPp@fmmhSj_ zc{hv@+9?WAg7;hOg>u{}H29jaFUCcWrxVZZx5bF@jF`dQ6p&`J1&M#@thLU--yL z=J}7~BXN>(1dAeF$&dN;H<(>#jH_YsjLo<$4N(*EdAKn*)|ND*{!}o-C>O^5GZN!e zhACV5BR9b40SuIN2+rb_DFu)s!#V?v0h|P^cLAJXN?39HXV33M;4wHK_jFf75eX>% zACUQ2f-qfhF8uul6nH-XJeXGY;gu{%1f?#&V~|*b9v>Xjt^?Z1Op6R`mMVdPZ%>wm}DM(32$QIEk8$Kl3G(JPP zvxVUbj62t@s>Ib(u%a{0V+re5HEh1kY8=dx#%@z@i9%p)TjsV>|6=?x2;HVYqeT(o zAZU##Xe50rZ57HXCm?G2CoS3zdc<%M3I=m4rh5@rAGIIAzv@a;mr2H5slZ5s0^^ky zui~L`ULPOaAJ&tar9jIUotm!%d_7YQgUd+#rd&)J_kvV#e0w*kq<(Vz7w#^>ubmFk zGT**s*EteuL6K&_>w!#)`5%e=dZ%il>A;Hjy7M8=xi#2f(7yN^nya3$$ZH8gW4{eY zMluyJ7QdxRw;ZHcbVuVuu_}sJ`cDvajG#z5h z$U|x&Ts-bcJhRqk^DoozC4$6z0fBtX2~PK#Ka8(H{J;L$IqOgtREsoOLS%VPC%RMN=aM7*HTBR?Uy3e&7_8s8{Ir_SAq555vR$+3qN z?=gu*qR#_}(!O9tc&X)h+CUSZUTrhzT=*(5-`hW&dR6YRYgU@OvV94tm@b^3HU3nZ z?q}h#VgntgvZ(2v;b%?C6GHh@fOwO?jK67 z)wbcmwXI>_O4y4)YD$jnK6l7Z$Tbr~@v*fzcbQSL9YYoF45}7Yr6p!qL|3CkeR@)5 z*}AXZY|gZB00SdER$Yx6CB@k@%3H))R3YqwRZKw%UCkmW)t50Y zPb6zIg4nc?+jzsGff7``gH{E=0Ch$FgdjXh(5fq00Xo&A?DG}%p{|w2Q+s)>Vp8LR z#Y#`TJc^`?PuDg|5@6OyGmX~)D2sCR!yhp?D&;#lm?cNWePY!mZy*D->9z69E6Hcz z%yk83Q=llEAeCowGf%PiNw}~zKFpYEG8XVFV}|v62-D`QrL8HZO(2e5-Hi9&P*twD zy7@<=&(hFOq~M4UkrOO8d><)cl1i#0zPM=F@ck`3yh-XzB>=mhB1C=RF|K058r`8MROfxCnZRUZ=E1s+;;iTd;ZTLj#MtC&o);^M?edRt zA7)0j_Pk9F=2J)3b6-?G(xCG`ST)o8jD2fCCpRgod!g*@<(x;;8^pcJips+o+h=VW zoo6Jbthn3VN9G@vUKmiuWj(k4w|JrUpAl+`$c{`gsRX-i((N81bBy%94|qchxMih8 zB$y{V0g-~E!6v~=b$oUoAA37p23+v$1)WvWe1?+ib{F}bF329=!YWznA{b2c(6l$u zdP2uvWvzD@c37N-fg!lk<}K8W{O%mvXdvyL3`px!Za?y?wBo)^+3r>vJ-tleKzy^rZWsUKo@(z6Y^n;0 zPF!^~uazp`dX`DXKwu7VZgpq$DBFFdH}O$OmGpvT7K)Q>o3Bx&NJlQ7fQ7i3e48mlJmU8QwtJcYcrKIPx7E20d*ifp#v@H=A+SdSx(`(iA0( zTPR4`;*+-&OLO&eNfGNn7jgb$;DPHq1Pq&s3rC!~`KRzP7Dt78V=ANVm4BpM&LiEr zMf0qqv-Le%QM$8CdQ%(zdu-Q8Vh0ZUpa77f>NS)=yH?@FZr!UvrCoPKa){83+-4$c z=jv^DTHr#}UPQgL<)OV_Alq<-`X`g#`9T}x&nV%4L!P`gjwg#rRnkV8T-By$ze?Ly z68St%Gp%%^DSmkS4Uc(<-52pqa2)q+&C#-n890C8g>kOd>dgTea3?w7&B%6mqYj^n zt`pYvV#KKYs*N{E4h7QsT9*KuV!ymf>-&INaVyoswCo4VOLvuj2l!x1>z=|y*8Z?u9q#Dl6VAx^o7%q{I?#KllvvdwOM)KM+ZNg|m-S~@v*tTxm zw*9^r&5-U)noab6Y!C&ravfyJp*jgE-+|wyRH!R>E+SEBLs81oO?Y_ya10bUv`^|ob0ZDP;J9nKL;Au)E?6>y zkjdz_+%CV;Z;&&POaU{P4;dIp8NYSYP!3Z8yGW)SX1hf5#6t?b2Fp04X%>dqXCKj) z?#}pn?T04^ucIDmK_GKi!he15uy}4=&9eB}HBf!u+~=x}{u2^$s&>X-5t%t)Hxd4P z{L{H+M}`?uE7Jwt!Q61$H%NY{dwC{yb4`ffh2ZtsMX?FM!~V)TfBP)+2pUz1W~csZ zZ}=A|^Q^YyQ5`kP*j(#4_xfDERZG1=5kgP!M^dP6!ka{3C4=vsd4I%3^Vt`>Km zJ=Z2?$}{rr?!m@uOxB*2a4VyAhsa8wa|v`NB<#*F+KmYM-yJfn!xFtxEkBi%7%2r% zL6{lftHWNAQ8${Ko6b6EEt&hD?`|RRJ3c%jK{rLhkE#cAaz&kt8p%rv=b8gk@Eju4 zWd~gmUOF2LqrC5iHh5_}MpD7Ul-{Qm_p?|?2Uz&IekiyjrL(koI$BEXLdkm)1@9-*k6!w;GME+uy5ZG1=>ZwY>1& zxxcs;fqijStjR`AskWy73aC_q!>I(9UNwbJ5DQ#|=jVC&Bsq-$3iIxbLL@xLthJlf zYVc##z?f;V?4r_UsI}TeqWr^zk0ZY&Z8CBtD1RcqErX|Qcd#PM?7)@6fFwQF*w3vI z&sj{je2W!yTGc_^n8hsFPXM`43mvZD#I2CUW&l82bbe{qfe4Ow(DqcU3c38ol+OC2 zBpNY~2S#wjsYiePIF;%=7qZM;&?XhKq0TFJBW$|%f#;CBB&2PQkO+9jVIB92ftlQF zOf8Ep=bxo)eWJ+C*~pY=QV6HyXyV#yRZcn@v%akuF_FL7zSn~(Ni~gP-UMFVC$iiw zIQ1+$WEjf-?Z6{BnHN80?bwjV3xP7*0y=wG#w1$kC^b2uVrVFB7jSHSF)zL%@NGy! zoqr2c#fKTFtn%+Zm8ItX{Ty36?VsLl6J3a!>I++sOi4|H;#VvsSBwq3zR~GqVBn6( zntTK>Fowc36*pA>AGb9C zP=lfvG3Eo9@R#&?T0f5o^-Jx$xbWzlvB`p<=k2PPYU6a%?ZG?+KTp&jljuKp(*xdN zQj-5i1{%4$FEv1XoLbOQwN$>6`tGDKHHNKK&#O~}Z(^xO*U5PZ8RS3KxKrRr9tYw# zK5wjvG_@v%Q*w%)1-8*psJ!bs-YliyuN;oU8t}LfDW6ie;Jff70dcsAl=ik$4XY?^~sh8RkmJ16~dBItNF~|!frx;Fx z5PBNZCf2k3q|7;~0cw9*N(5dcl-1_SrwF5BgIA@~>t<|GRJ$~;C%;y;Vka$DEis@M zm0!b=R>0KaUV)!7o@BGTYm@=kr`kGZ7zwS8O{jMv_1pmO{%c3HJ2Ulo5x=86rCRI3 zP_&rkxJ|(W2f?(Ikx(v_vbyR09;m?Y)-c~22(s8iBi>Vw(2)J~`p1OlGMYdO)UcPV>@M@kTMhzXM;m+;XH}0JuE}e-9!7$`2%&vRpH$u+qmjH| zaKnvu?;(5>vty=bEdB&l8_>Z>bd$0QeZcK+Hk)mpF3bqAH + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +&pinctrl { + spim2_default: spim2_default { + group1 { + pinmux = , + ; + }; + + group2 { + pinmux = ; + output-low; + }; + }; + + i2c0_default: i2c0_default { + group1 { + pinmux = , + ; + bias-pull-up; + drive-open-drain; + output-high; + }; + }; + + sdhc0_default: sdhc0_default { + group1 { + pinmux = , + , + , + , + , + ; + bias-pull-up; + output-high; + }; + }; + + uart0_default: uart0_default { + group1 { + pinmux = ; + output-high; + }; + + group2 { + pinmux = ; + bias-pull-up; + }; + }; +}; diff --git a/boards/waveshare/esp32s3_geek/esp32s3_geek_esp32s3_appcpu.dts b/boards/waveshare/esp32s3_geek/esp32s3_geek_esp32s3_appcpu.dts new file mode 100644 index 000000000000..b51cd808ec18 --- /dev/null +++ b/boards/waveshare/esp32s3_geek/esp32s3_geek_esp32s3_appcpu.dts @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2024 Joel Guittet + * Copyright (c) 2025 Chen Xingyu + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include + +/ { + model = "ESP32-S3-GEEK APPCPU"; + compatible = "waveshare,esp32-s3-geek"; + + chosen { + zephyr,sram = &sram1; + zephyr,ipc_shm = &shm0; + zephyr,ipc = &ipm0; + zephyr,flash = &flash0; + zephyr,code-partition = &slot0_appcpu_partition; + }; +}; + +&flash0 { + reg = <0x0 DT_SIZE_M(16)>; +}; + +&trng0 { + status = "okay"; +}; diff --git a/boards/waveshare/esp32s3_geek/esp32s3_geek_esp32s3_appcpu.yaml b/boards/waveshare/esp32s3_geek/esp32s3_geek_esp32s3_appcpu.yaml new file mode 100644 index 000000000000..af4bc894707d --- /dev/null +++ b/boards/waveshare/esp32s3_geek/esp32s3_geek_esp32s3_appcpu.yaml @@ -0,0 +1,28 @@ +identifier: esp32s3_geek/esp32s3/appcpu +name: ESP32-S3-GEEK 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 + - psa.secure_storage +vendor: waveshare diff --git a/boards/waveshare/esp32s3_geek/esp32s3_geek_esp32s3_appcpu_defconfig b/boards/waveshare/esp32s3_geek/esp32s3_geek_esp32s3_appcpu_defconfig new file mode 100644 index 000000000000..6a13f9c9e392 --- /dev/null +++ b/boards/waveshare/esp32s3_geek/esp32s3_geek_esp32s3_appcpu_defconfig @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Joel Guittet +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_CLOCK_CONTROL=y diff --git a/boards/waveshare/esp32s3_geek/esp32s3_geek_esp32s3_procpu.dts b/boards/waveshare/esp32s3_geek/esp32s3_geek_esp32s3_procpu.dts new file mode 100644 index 000000000000..454ce31dd8d7 --- /dev/null +++ b/boards/waveshare/esp32s3_geek/esp32s3_geek_esp32s3_procpu.dts @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2024 Joel Guittet + * Copyright (c) 2025 Chen Xingyu + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include +#include +#include "esp32s3_geek-pinctrl.dtsi" + +/ { + model = "ESP32-S3-GEEK PROCPU"; + compatible = "waveshare,esp32-s3-geek"; + + aliases { + sw0 = &button0; + watchdog0 = &wdt0; + sdhc0 = &sdhc0; + }; + + chosen { + zephyr,sram = &sram1; + zephyr,console = &usb_serial; + zephyr,shell-uart = &usb_serial; + zephyr,flash = &flash0; + zephyr,code-partition = &slot0_partition; + zephyr,display = &st7789p3; + zephyr,bt-hci = &esp32_bt_hci; + }; + + buttons { + compatible = "gpio-keys"; + + button0: button_0 { + gpios = <&gpio0 0 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "BOOT Button"; + zephyr,code = ; + }; + }; + + mipi_dbi { + compatible = "zephyr,mipi-dbi-spi"; + spi-dev = <&spi2>; + dc-gpios = <&gpio0 8 GPIO_ACTIVE_HIGH>; + reset-gpios = <&gpio0 9 GPIO_ACTIVE_LOW>; + write-only; + #address-cells = <1>; + #size-cells = <0>; + + st7789p3: st7789p3@0 { + compatible = "sitronix,st7789v"; + mipi-max-frequency = ; + mipi-mode = "MIPI_DBI_MODE_SPI_4WIRE"; + reg = <0>; + width = <240>; + height = <136>; + x-offset = <40>; + y-offset = <52>; + vcom = <0x19>; + gctrl = <0x35>; + vrhs = <0x12>; + vdvs = <0x20>; + mdac = <0x70>; + lcm = <0x2c>; + colmod = <0x05>; + gamma = <0x01>; + 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 { + reg = <0x0 DT_SIZE_M(16)>; +}; + +&gpio0 { + status = "okay"; +}; + +&gpio1 { + status = "okay"; +}; + +&uart0 { + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&uart0_default>; + pinctrl-names = "default"; +}; + +&i2c0 { + status = "okay"; + clock-frequency = ; + pinctrl-0 = <&i2c0_default>; + pinctrl-names = "default"; +}; + +&spi2 { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + pinctrl-0 = <&spim2_default>; + pinctrl-names = "default"; +}; + +&usb_serial { + status = "okay"; +}; + +zephyr_udc0: &usb_otg {}; + +&sdhc { + sdhc0: sdhc@0 { + status = "okay"; + pinctrl-0 = <&sdhc0_default>; + pinctrl-names = "default"; + max-bus-freq = ; + bus-width = <4>; + + mmc { + compatible = "zephyr,sdmmc-disk"; + disk-name = "SD"; + status = "okay"; + }; + }; +}; + +&trng0 { + status = "okay"; +}; + +&wdt0 { + status = "okay"; +}; + +&wifi { + status = "okay"; +}; + +&esp32_bt_hci { + status = "okay"; +}; diff --git a/boards/waveshare/esp32s3_geek/esp32s3_geek_esp32s3_procpu.yaml b/boards/waveshare/esp32s3_geek/esp32s3_geek_esp32s3_procpu.yaml new file mode 100644 index 000000000000..60841ad6a089 --- /dev/null +++ b/boards/waveshare/esp32s3_geek/esp32s3_geek_esp32s3_procpu.yaml @@ -0,0 +1,13 @@ +identifier: esp32s3_geek/esp32s3/procpu +name: ESP32-S3-GEEK PROCPU +type: mcu +arch: xtensa +toolchain: + - zephyr +supported: + - display + - gpio + - i2c + - sdhc + - uart +vendor: waveshare diff --git a/boards/waveshare/esp32s3_geek/esp32s3_geek_esp32s3_procpu_defconfig b/boards/waveshare/esp32s3_geek/esp32s3_geek_esp32s3_procpu_defconfig new file mode 100644 index 000000000000..d01cb68ee6f6 --- /dev/null +++ b/boards/waveshare/esp32s3_geek/esp32s3_geek_esp32s3_procpu_defconfig @@ -0,0 +1,9 @@ +# Copyright (c) 2024 Joel Guittet +# Copyright (c) 2025 Chen Xingyu +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_GPIO=y +CONFIG_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_UART_CONSOLE=y +CONFIG_CLOCK_CONTROL=y diff --git a/boards/waveshare/esp32s3_geek/support/openocd.cfg b/boards/waveshare/esp32s3_geek/support/openocd.cfg new file mode 100644 index 000000000000..625341a5aa87 --- /dev/null +++ b/boards/waveshare/esp32s3_geek/support/openocd.cfg @@ -0,0 +1,10 @@ +# Copyright (c) 2024 Joel Guittet +# SPDX-License-Identifier: Apache-2.0 + +set ESP_RTOS none +set ESP32_ONLYCPU 1 + +# Source the JTAG interface configuration file +source [find interface/esp_usb_jtag.cfg] +# Source the ESP32-S3 configuration file +source [find target/esp32s3.cfg] From 402edcf81c440b04fc10a9cf4dde1a86eee6184b Mon Sep 17 00:00:00 2001 From: Mark Wang Date: Mon, 8 Dec 2025 15:54:22 +0800 Subject: [PATCH 0459/3659] bluetooth: avdtp: Fix coverity by adding assertion for MTU size validation Add assertion to ensure MTU is at least the size of the start header before calculating the remaining length for fragmentation. This prevents potential underflow when subtracting the header size from MTU. Fix coverity #551657 Signed-off-by: Mark Wang --- subsys/bluetooth/host/classic/avdtp.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/subsys/bluetooth/host/classic/avdtp.c b/subsys/bluetooth/host/classic/avdtp.c index f1913cf2774a..9dc96f11585f 100644 --- a/subsys/bluetooth/host/classic/avdtp.c +++ b/subsys/bluetooth/host/classic/avdtp.c @@ -455,6 +455,7 @@ static void avdtp_tx_frags(struct bt_avdtp *session, struct net_buf *buf, start_hdr->num_of_signal_pkts = user_data->frag_count; start_hdr->signal_id = user_data->hdr.signal_id; + __ASSERT_NO_MSG(mtu >= sizeof(*start_hdr)); len = mtu - sizeof(*start_hdr); if (len >= buf->len) { LOG_ERR("The start packet can send all data"); @@ -473,6 +474,7 @@ static void avdtp_tx_frags(struct bt_avdtp *session, struct net_buf *buf, cont_hdr->hdr = (user_data->hdr.hdr & ~AVDTP_PKT_MASK) | AVDTP_PKT_PREP(pkt_type); + __ASSERT_NO_MSG(mtu >= sizeof(*cont_hdr)); len = mtu - sizeof(*cont_hdr); if (pkt_type == BT_AVDTP_PACKET_TYPE_CONTINUE && len >= buf->len) { LOG_ERR("The continue packet can send all data"); From ac395b2d853e18aed7d33c41b89be3501812f6da Mon Sep 17 00:00:00 2001 From: Mark Wang Date: Mon, 8 Dec 2025 16:09:53 +0800 Subject: [PATCH 0460/3659] bluetooth: avdtp: Check buf tailroom and len before using it check buf->len before pulling data from buf, check buf tailroom before adding data to buf. Signed-off-by: Mark Wang --- subsys/bluetooth/host/classic/avdtp.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/subsys/bluetooth/host/classic/avdtp.c b/subsys/bluetooth/host/classic/avdtp.c index 9dc96f11585f..155bfbdde557 100644 --- a/subsys/bluetooth/host/classic/avdtp.c +++ b/subsys/bluetooth/host/classic/avdtp.c @@ -445,9 +445,11 @@ static void avdtp_tx_frags(struct bt_avdtp *session, struct net_buf *buf, struct bt_avdtp_start_sig_hdr *start_hdr; struct bt_avdtp_single_sig_hdr *sig_hdr; + __ASSERT_NO_MSG(buf->len >= sizeof(*sig_hdr)); sig_hdr = net_buf_pull_mem(buf, sizeof(*sig_hdr)); user_data->hdr = *sig_hdr; + __ASSERT_NO_MSG(net_buf_tailroom(frag) >= sizeof(*start_hdr)); start_hdr = net_buf_add(frag, sizeof(*start_hdr)); /* use same transaction label and message type */ start_hdr->hdr = (user_data->hdr.hdr & ~AVDTP_PKT_MASK) | @@ -469,6 +471,7 @@ static void avdtp_tx_frags(struct bt_avdtp *session, struct net_buf *buf, uint8_t pkt_type = (user_data->frag_count == user_data->current_frag) ? BT_AVDTP_PACKET_TYPE_END : BT_AVDTP_PACKET_TYPE_CONTINUE; + __ASSERT_NO_MSG(net_buf_tailroom(frag) >= sizeof(*cont_hdr)); cont_hdr = net_buf_add(frag, sizeof(*cont_hdr)); /* use same transaction label and message type */ cont_hdr->hdr = (user_data->hdr.hdr & ~AVDTP_PKT_MASK) | From 2c934f1dd898bb542375ee6f5e549caf5049f2f8 Mon Sep 17 00:00:00 2001 From: Jonathan Nilsen Date: Thu, 27 Nov 2025 14:04:00 +0100 Subject: [PATCH 0461/3659] manifest: update hal_nordic revision Update hal_nordic revision to add IronSide support package. Signed-off-by: Jonathan Nilsen --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 70e177a9086e..e8920224fb0e 100644 --- a/west.yml +++ b/west.yml @@ -200,7 +200,7 @@ manifest: groups: - hal - name: hal_nordic - revision: 757314f07fbf2fb0f0257d7cfa147ca03f9d8398 + revision: 09f24fd6cc7df57a5b5d08102ceb4a38381e2c82 path: modules/hal/nordic groups: - hal From ef587e12f6881af637a37b7f7860297fb168f11b Mon Sep 17 00:00:00 2001 From: Jonathan Nilsen Date: Mon, 11 Aug 2025 10:14:42 +0200 Subject: [PATCH 0462/3659] modules: hal_nordic: move IronSide SE supporting code to hal_nordic Move most of the code that is used to interface with IronSide SE on the nRF54H20/nRF9280 from the soc/nordic directory to the hal_nordic repository. The interface code is now provided by the new IronSide support package. Build system code and glue code that makes use of Zephyr APIs is now located in the modules/hal_nordic directory. Update the directory path for IronSide SE interface code in MAINTAINERS.yml to match the move from soc/nordic/ironside to modules/hal_nordic/ironside. Also included are some refactoring changes and cleanup to match the new supporting code. C code and Kconfigs have been renamed to *ironside_se* / *IRONSIDE_SE* to match the supporting code changes. Users of these APIs in zephyr have been updated to match. Individual configurations for different "IronSide services" have been removed as the API serialization for all of these is now provided in a single C file / header file (ironside/se/api.h). The ironside_boot_report_get() API has been removed. The boot report structure can be accessed through the IRONSIDE_SE_BOOT_REPORT macro. Most configs relating to UICR / PERIPHCONF have been moved under the "IronSide SE" menu to make it clear that these are part of the IronSide SE interface. The macros that in uicr.h that were used to add entries to the PERIPHCONF section have been removed. The supporting code now provides PERIPHCONF_XYZ() macros that can be used to initialize structures that go into this section, and the zephyr part now only contains a macro UICR_PERIPHCONF_ENTRY() that is used to place an arbitrary structure into the section. The gen_periphconf_entries.py script used to generate PERIPHCONF entries based on devicetree has been updated to use the new macro system. IronSide SE integration code/configs is now guarded by HAS_IRONSIDE_SE. Note that the UICR build system integration that relies on Sysbuild remains under the soc/nordic directory for now, but will be moved to the modules/hal_nordic directory once it is clear how the integration will look there. Signed-off-by: Jonathan Nilsen --- MAINTAINERS.yml | 2 +- drivers/clock_control/Kconfig.nrf | 2 +- .../clock_control_nrf_iron_hsfll_local.c | 38 +- drivers/debug/Kconfig.nrf | 2 +- drivers/debug/debug_coresight_nrf.c | 6 +- drivers/debug/debug_nrf_etr.c | 2 +- modules/hal_nordic/CMakeLists.txt | 1 + modules/hal_nordic/Kconfig | 1 + .../hal_nordic/ironside/se}/CMakeLists.txt | 22 +- modules/hal_nordic/ironside/se/Kconfig | 66 ++ .../hal_nordic/ironside/se}/call.c | 27 +- .../hal_nordic/ironside/se}/dvfs.c | 83 +- .../se/include/ironside_zephyr/se/dvfs.h | 37 + .../ironside_zephyr/se/uicr_periphconf.h | 34 + .../se/scripts}/gen_periphconf_entries.py | 3 +- .../se/scripts}/periphconf/__init__.py | 0 .../se/scripts}/periphconf/builder.py | 41 +- .../hal_nordic/ironside/se}/uicr.ld | 4 +- .../nordic/nrf_ironside/update/prj.conf | 3 - .../nordic/nrf_ironside/update/src/main.c | 18 +- soc/nordic/CMakeLists.txt | 1 - soc/nordic/common/CMakeLists.txt | 2 - soc/nordic/common/uicr/Kconfig | 18 - soc/nordic/common/uicr/Kconfig.sysbuild | 6 +- soc/nordic/common/uicr/gen_uicr.py | 859 ------------------ .../common/uicr/gen_uicr/CMakeLists.txt | 6 +- soc/nordic/common/uicr/uicr.h | 308 ------- soc/nordic/ironside/CMakeLists.txt | 13 - soc/nordic/ironside/Kconfig | 89 -- soc/nordic/ironside/boot_report.c | 23 - soc/nordic/ironside/bootmode.c | 51 -- soc/nordic/ironside/counter.c | 81 -- soc/nordic/ironside/cpuconf.c | 59 -- .../include/nrf_ironside/boot_report.h | 229 ----- .../ironside/include/nrf_ironside/bootmode.h | 73 -- .../ironside/include/nrf_ironside/call.h | 82 -- .../ironside/include/nrf_ironside/counter.h | 143 --- .../ironside/include/nrf_ironside/cpuconf.h | 74 -- .../ironside/include/nrf_ironside/dvfs.h | 103 --- .../ironside/include/nrf_ironside/tdd.h | 39 - .../ironside/include/nrf_ironside/update.h | 90 -- soc/nordic/ironside/tdd.c | 28 - soc/nordic/ironside/update.c | 33 - soc/nordic/nrf54h/Kconfig | 3 +- .../nrf54h/Kconfig.defconfig.nrf54h20_cpuapp | 3 + .../nrf54h/Kconfig.defconfig.nrf54h20_cpurad | 3 + soc/nordic/nrf54h/soc.c | 6 +- soc/nordic/nrf92/Kconfig | 1 + .../nrf92/Kconfig.defconfig.nrf9280_cpuapp | 3 + .../nrf92/Kconfig.defconfig.nrf9280_cpurad | 3 + 50 files changed, 288 insertions(+), 2536 deletions(-) rename {soc/nordic/common/uicr => modules/hal_nordic/ironside/se}/CMakeLists.txt (60%) create mode 100644 modules/hal_nordic/ironside/se/Kconfig rename {soc/nordic/ironside => modules/hal_nordic/ironside/se}/call.c (81%) rename {soc/nordic/ironside => modules/hal_nordic/ironside/se}/dvfs.c (60%) create mode 100644 modules/hal_nordic/ironside/se/include/ironside_zephyr/se/dvfs.h create mode 100644 modules/hal_nordic/ironside/se/include/ironside_zephyr/se/uicr_periphconf.h rename {soc/nordic/common/uicr => modules/hal_nordic/ironside/se/scripts}/gen_periphconf_entries.py (99%) rename {soc/nordic/common/uicr => modules/hal_nordic/ironside/se/scripts}/periphconf/__init__.py (100%) rename {soc/nordic/common/uicr => modules/hal_nordic/ironside/se/scripts}/periphconf/builder.py (97%) rename {soc/nordic/common/uicr => modules/hal_nordic/ironside/se}/uicr.ld (61%) delete mode 100644 soc/nordic/common/uicr/gen_uicr.py delete mode 100644 soc/nordic/common/uicr/uicr.h delete mode 100644 soc/nordic/ironside/CMakeLists.txt delete mode 100644 soc/nordic/ironside/Kconfig delete mode 100644 soc/nordic/ironside/boot_report.c delete mode 100644 soc/nordic/ironside/bootmode.c delete mode 100644 soc/nordic/ironside/counter.c delete mode 100644 soc/nordic/ironside/cpuconf.c delete mode 100644 soc/nordic/ironside/include/nrf_ironside/boot_report.h delete mode 100644 soc/nordic/ironside/include/nrf_ironside/bootmode.h delete mode 100644 soc/nordic/ironside/include/nrf_ironside/call.h delete mode 100644 soc/nordic/ironside/include/nrf_ironside/counter.h delete mode 100644 soc/nordic/ironside/include/nrf_ironside/cpuconf.h delete mode 100644 soc/nordic/ironside/include/nrf_ironside/dvfs.h delete mode 100644 soc/nordic/ironside/include/nrf_ironside/tdd.h delete mode 100644 soc/nordic/ironside/include/nrf_ironside/update.h delete mode 100644 soc/nordic/ironside/tdd.c delete mode 100644 soc/nordic/ironside/update.c diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index 1c5d3528fe1c..e7b3dfb791d1 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -6417,7 +6417,7 @@ nRF IronSide SE Platforms: - karstenkoenig - SebastianBoe files: - - soc/nordic/ironside/ + - modules/hal_nordic/ironside/ - soc/nordic/common/uicr/ labels: - "platform: nRF IronSide SE" diff --git a/drivers/clock_control/Kconfig.nrf b/drivers/clock_control/Kconfig.nrf index a051ebd62b02..f8d51383a35c 100644 --- a/drivers/clock_control/Kconfig.nrf +++ b/drivers/clock_control/Kconfig.nrf @@ -290,7 +290,7 @@ endif # CLOCK_CONTROL_NRF_HSFLL_LOCAL config CLOCK_CONTROL_NRF_IRON_HSFLL_LOCAL bool "NRF IronSide HSFLL LOCAL driver support" depends on DT_HAS_NORDIC_NRF_IRON_HSFLL_LOCAL_ENABLED - select NRF_IRONSIDE_DVFS_SERVICE + select IRONSIDE_SE_DVFS select CLOCK_CONTROL_NRF2_COMMON default y diff --git a/drivers/clock_control/clock_control_nrf_iron_hsfll_local.c b/drivers/clock_control/clock_control_nrf_iron_hsfll_local.c index ba4e2a3f6bed..f80521cb03a4 100644 --- a/drivers/clock_control/clock_control_nrf_iron_hsfll_local.c +++ b/drivers/clock_control/clock_control_nrf_iron_hsfll_local.c @@ -14,31 +14,31 @@ LOG_MODULE_DECLARE(clock_control_nrf2, CONFIG_CLOCK_CONTROL_LOG_LEVEL); BUILD_ASSERT(DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) == 1, "multiple instances not supported"); -#ifdef CONFIG_NRF_IRONSIDE_DVFS_SERVICE -#include +#ifdef CONFIG_IRONSIDE_SE_DVFS +#include #define HSFLL_FREQ_LOW MHZ(64) #define HSFLL_FREQ_MEDLOW MHZ(128) #define HSFLL_FREQ_HIGH MHZ(320) -#define IRONSIDE_DVFS_TIMEOUT K_MSEC(CONFIG_CLOCK_CONTROL_NRF_IRON_HSFLL_LOCAL_DVFS_TIMEOUT_MS) +#define IRONSIDE_SE_DVFS_TIMEOUT K_MSEC(CONFIG_CLOCK_CONTROL_NRF_IRON_HSFLL_LOCAL_DVFS_TIMEOUT_MS) /* Clock options sorted from lowest to highest frequency */ static const struct clock_options { uint32_t frequency; - enum ironside_dvfs_oppoint setting; + enum ironside_se_dvfs_oppoint setting; } clock_options[] = { { .frequency = HSFLL_FREQ_LOW, - .setting = IRONSIDE_DVFS_OPP_LOW, + .setting = IRONSIDE_SE_DVFS_OPP_LOW, }, { .frequency = HSFLL_FREQ_MEDLOW, - .setting = IRONSIDE_DVFS_OPP_MEDLOW, + .setting = IRONSIDE_SE_DVFS_OPP_MEDLOW, }, { .frequency = HSFLL_FREQ_HIGH, - .setting = IRONSIDE_DVFS_OPP_HIGH, + .setting = IRONSIDE_SE_DVFS_OPP_HIGH, }, }; @@ -57,17 +57,17 @@ static void hsfll_update_timeout_handler(struct k_timer *timer) static void hsfll_work_handler(struct k_work *work) { struct hsfll_dev_data *dev_data = CONTAINER_OF(work, struct hsfll_dev_data, clk_cfg.work); - enum ironside_dvfs_oppoint required_setting; + enum ironside_se_dvfs_oppoint required_setting; uint8_t to_activate_idx; int rc; to_activate_idx = clock_config_update_begin(work); required_setting = clock_options[to_activate_idx].setting; - k_timer_start(&dev_data->timer, IRONSIDE_DVFS_TIMEOUT, K_NO_WAIT); + k_timer_start(&dev_data->timer, IRONSIDE_SE_DVFS_TIMEOUT, K_NO_WAIT); /* Request the DVFS service to change the OPP point. */ - rc = ironside_dvfs_change_oppoint(required_setting); + rc = ironside_se_dvfs_change_oppoint(required_setting); k_timer_stop(&dev_data->timer); clock_config_update_end(&dev_data->clk_cfg, rc); } @@ -123,12 +123,12 @@ static struct onoff_manager *hsfll_find_mgr_by_spec(const struct device *dev, idx = hsfll_resolve_spec_to_idx(spec); return idx < 0 ? NULL : hsfll_get_mgr_by_idx(dev, idx); } -#endif /* CONFIG_NRF_IRONSIDE_DVFS_SERVICE */ +#endif /* CONFIG_IRONSIDE_SE_DVFS */ static int api_request_hsfll(const struct device *dev, const struct nrf_clock_spec *spec, struct onoff_client *cli) { -#ifdef CONFIG_NRF_IRONSIDE_DVFS_SERVICE +#ifdef CONFIG_IRONSIDE_SE_DVFS struct onoff_manager *mgr = hsfll_find_mgr_by_spec(dev, spec); if (mgr) { @@ -143,7 +143,7 @@ static int api_request_hsfll(const struct device *dev, const struct nrf_clock_sp static int api_release_hsfll(const struct device *dev, const struct nrf_clock_spec *spec) { -#ifdef CONFIG_NRF_IRONSIDE_DVFS_SERVICE +#ifdef CONFIG_IRONSIDE_SE_DVFS struct onoff_manager *mgr = hsfll_find_mgr_by_spec(dev, spec); if (mgr) { @@ -159,7 +159,7 @@ static int api_release_hsfll(const struct device *dev, const struct nrf_clock_sp static int api_cancel_or_release_hsfll(const struct device *dev, const struct nrf_clock_spec *spec, struct onoff_client *cli) { -#ifdef CONFIG_NRF_IRONSIDE_DVFS_SERVICE +#ifdef CONFIG_IRONSIDE_SE_DVFS struct onoff_manager *mgr = hsfll_find_mgr_by_spec(dev, spec); if (mgr) { @@ -175,7 +175,7 @@ static int api_cancel_or_release_hsfll(const struct device *dev, const struct nr static int api_resolve_hsfll(const struct device *dev, const struct nrf_clock_spec *req_spec, struct nrf_clock_spec *res_spec) { -#ifdef CONFIG_NRF_IRONSIDE_DVFS_SERVICE +#ifdef CONFIG_IRONSIDE_SE_DVFS int idx; idx = hsfll_resolve_spec_to_idx(req_spec); @@ -192,7 +192,7 @@ static int api_resolve_hsfll(const struct device *dev, const struct nrf_clock_sp static int hsfll_init(const struct device *dev) { -#ifdef CONFIG_NRF_IRONSIDE_DVFS_SERVICE +#ifdef CONFIG_IRONSIDE_SE_DVFS struct hsfll_dev_data *dev_data = dev->data; int rc; @@ -220,14 +220,14 @@ static DEVICE_API(nrf_clock_control, hsfll_drv_api) = { .resolve = api_resolve_hsfll, }; -#ifdef CONFIG_NRF_IRONSIDE_DVFS_SERVICE +#ifdef CONFIG_IRONSIDE_SE_DVFS static struct hsfll_dev_data hsfll_data; #endif #ifdef CONFIG_CLOCK_CONTROL_NRF_IRON_HSFLL_LOCAL_REQ_LOW_FREQ static int dvfs_low_init(void) { - static const k_timeout_t timeout = IRONSIDE_DVFS_TIMEOUT; + static const k_timeout_t timeout = IRONSIDE_SE_DVFS_TIMEOUT; static const struct device *hsfll_dev = DEVICE_DT_GET(DT_CLOCKS_CTLR(DT_NODELABEL(cpu))); static const struct nrf_clock_spec clk_spec = {.frequency = HSFLL_FREQ_LOW}; @@ -238,7 +238,7 @@ SYS_INIT(dvfs_low_init, APPLICATION, 0); #endif DEVICE_DT_INST_DEFINE(0, hsfll_init, NULL, - COND_CODE_1(CONFIG_NRF_IRONSIDE_DVFS_SERVICE, + COND_CODE_1(CONFIG_IRONSIDE_SE_DVFS, (&hsfll_data), (NULL)), NULL, PRE_KERNEL_1, CONFIG_CLOCK_CONTROL_INIT_PRIORITY, &hsfll_drv_api); diff --git a/drivers/debug/Kconfig.nrf b/drivers/debug/Kconfig.nrf index 030e9885a06d..7ea5f6bed5f8 100644 --- a/drivers/debug/Kconfig.nrf +++ b/drivers/debug/Kconfig.nrf @@ -117,7 +117,7 @@ menuconfig DEBUG_CORESIGHT_NRF default y depends on DT_HAS_NORDIC_CORESIGHT_NRF_ENABLED select PINCTRL - select NRF_IRONSIDE_TDD_SERVICE + select IRONSIDE_SE_CALL help Support CoreSight peripherals in Test and Debug Domain for ARM CoreSight System Trace Macrocell (STM) trace support. diff --git a/drivers/debug/debug_coresight_nrf.c b/drivers/debug/debug_coresight_nrf.c index 7bc9bab68ee0..7aeb14ce6eb5 100644 --- a/drivers/debug/debug_coresight_nrf.c +++ b/drivers/debug/debug_coresight_nrf.c @@ -9,8 +9,8 @@ #include #include #include -#include -#include +#include +#include #undef ETR_MODE_MODE_CIRCULARBUF @@ -262,7 +262,7 @@ static int coresight_nrf_init(const struct device *dev) return 0; } -#define DEBUG_CORESIGHT_NRF_INIT_PRIORITY UTIL_INC(CONFIG_NRF_IRONSIDE_CALL_INIT_PRIORITY) +#define DEBUG_CORESIGHT_NRF_INIT_PRIORITY UTIL_INC(CONFIG_IRONSIDE_SE_CALL_INIT_PRIORITY) #define CORESIGHT_NRF_INST(inst) \ COND_CODE_1(DT_INST_PINCTRL_HAS_IDX(inst, 0), \ diff --git a/drivers/debug/debug_nrf_etr.c b/drivers/debug/debug_nrf_etr.c index d536cd4a9f40..200d6edbc1a7 100644 --- a/drivers/debug/debug_nrf_etr.c +++ b/drivers/debug/debug_nrf_etr.c @@ -792,7 +792,7 @@ int etr_process_init(void) return 0; } -#define NRF_ETR_INIT_PRIORITY UTIL_INC(UTIL_INC(CONFIG_NRF_IRONSIDE_CALL_INIT_PRIORITY)) +#define NRF_ETR_INIT_PRIORITY UTIL_INC(UTIL_INC(CONFIG_IRONSIDE_SE_CALL_INIT_PRIORITY)) SYS_INIT(etr_process_init, POST_KERNEL, NRF_ETR_INIT_PRIORITY); diff --git a/modules/hal_nordic/CMakeLists.txt b/modules/hal_nordic/CMakeLists.txt index 53fae66cf675..a49aec6406fa 100644 --- a/modules/hal_nordic/CMakeLists.txt +++ b/modules/hal_nordic/CMakeLists.txt @@ -5,6 +5,7 @@ if(CONFIG_NRF_802154_RADIO_DRIVER OR CONFIG_NRF_802154_SERIALIZATION) add_subdirectory(nrf_802154) endif(CONFIG_NRF_802154_RADIO_DRIVER OR CONFIG_NRF_802154_SERIALIZATION) +add_subdirectory_ifdef(CONFIG_HAS_IRONSIDE_SE ironside/se) add_subdirectory_ifdef(CONFIG_HAS_NRFX nrfx) add_subdirectory_ifdef(CONFIG_HAS_NRFS nrfs) diff --git a/modules/hal_nordic/Kconfig b/modules/hal_nordic/Kconfig index 7be30750627d..935c4fb4ff38 100644 --- a/modules/hal_nordic/Kconfig +++ b/modules/hal_nordic/Kconfig @@ -258,6 +258,7 @@ endif # NRF_802154_RADIO_DRIVER || NRF_802154_SERIALIZATION endmenu # HAS_NORDIC_DRIVERS +rsource "ironside/se/Kconfig" rsource "nrfs/Kconfig" rsource "nrfx/Kconfig" rsource "Kconfig.nrf_regtool" diff --git a/soc/nordic/common/uicr/CMakeLists.txt b/modules/hal_nordic/ironside/se/CMakeLists.txt similarity index 60% rename from soc/nordic/common/uicr/CMakeLists.txt rename to modules/hal_nordic/ironside/se/CMakeLists.txt index d350d8d3f586..50379a084cb9 100644 --- a/soc/nordic/common/uicr/CMakeLists.txt +++ b/modules/hal_nordic/ironside/se/CMakeLists.txt @@ -1,6 +1,26 @@ # Copyright (c) 2025 Nordic Semiconductor ASA # SPDX-License-Identifier: Apache-2.0 +# The IronSide source directory can be overridden by setting +# IRONSIDE_SUPPORT_DIR before invoking the build system. +zephyr_get(IRONSIDE_SUPPORT_DIR SYSBUILD GLOBAL) +if(NOT DEFINED IRONSIDE_SUPPORT_DIR) + set(IRONSIDE_SUPPORT_DIR + ${ZEPHYR_CURRENT_MODULE_DIR}/ironside CACHE PATH "IronSide Support Directory" + ) +endif() + +zephyr_include_directories(include) +zephyr_include_directories(${IRONSIDE_SUPPORT_DIR}/se/include) + +zephyr_library() +zephyr_library_property(ALLOW_EMPTY TRUE) +zephyr_library_sources_ifdef(CONFIG_IRONSIDE_SE_CALL + ${IRONSIDE_SUPPORT_DIR}/se/src/ironside_se_api.c + call.c +) +zephyr_library_sources_ifdef(CONFIG_IRONSIDE_SE_DVFS dvfs.c) + if(CONFIG_NRF_PERIPHCONF_SECTION) zephyr_linker_sources(SECTIONS uicr.ld) endif() @@ -10,7 +30,7 @@ if(CONFIG_NRF_PERIPHCONF_GENERATE_ENTRIES) execute_process( COMMAND ${CMAKE_COMMAND} -E env ZEPHYR_BASE=${ZEPHYR_BASE} - ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_LIST_DIR}/gen_periphconf_entries.py + ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_LIST_DIR}/scripts/gen_periphconf_entries.py --soc ${CONFIG_SOC} --in-edt-pickle ${EDT_PICKLE} --out-periphconf-source ${periphconf_entries_c_file} diff --git a/modules/hal_nordic/ironside/se/Kconfig b/modules/hal_nordic/ironside/se/Kconfig new file mode 100644 index 000000000000..eae311bef6d0 --- /dev/null +++ b/modules/hal_nordic/ironside/se/Kconfig @@ -0,0 +1,66 @@ +# Copyright (c) 2025 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config HAS_IRONSIDE_SE + bool + +menu "IronSide SE" + depends on HAS_IRONSIDE_SE + +config IRONSIDE_SE_CALL + bool "IronSide calls" + default y + depends on DT_HAS_NORDIC_IRONSIDE_CALL_ENABLED + depends on MULTITHREADING + select EVENTS + select MBOX + help + Support for IronSide call APIs. + +if IRONSIDE_SE_CALL + +config IRONSIDE_SE_CALL_INIT_PRIORITY + int "IronSide calls' driver initialization priority" + default 41 + help + Initialization priority of the IronSide call protocol driver. + It must be below MBOX_INIT_PRIORITY, but higher than the priority of any feature + that depends on IRONSIDE_SE_CALL. + +endif # IRONSIDE_SE_CALL + +config IRONSIDE_SE_DVFS + bool "DVFS support" + depends on SOC_NRF54H20_CPUAPP + depends on IRONSIDE_SE_CALL + help + Support for changing the DVFS operating point. + +if IRONSIDE_SE_DVFS + +config IRONSIDE_SE_DVFS_ABB_STATUSANA_CHECK_MAX_ATTEMPTS + int "ABB analog status check maximum attempts" + range 0 255 + default 50 + help + Maximum attempts with 10us intervals before busy status will be reported. + +endif # IRONSIDE_SE_DVFS + +menuconfig NRF_PERIPHCONF_SECTION + bool "Global peripheral initialization section" + depends on LINKER_DEVNULL_SUPPORT + imply LINKER_DEVNULL_MEMORY + help + Include static global domain peripheral initialization values from the + build in a dedicated section in the devnull region. + +config NRF_PERIPHCONF_GENERATE_ENTRIES + bool "Generate PERIPHCONF entries source file" + default y + depends on NRF_PERIPHCONF_SECTION + help + Generate a C file containing PERIPHCONF entries based on the + device configuration in the devicetree. + +endmenu # IronSide SE diff --git a/soc/nordic/ironside/call.c b/modules/hal_nordic/ironside/se/call.c similarity index 81% rename from soc/nordic/ironside/call.c rename to modules/hal_nordic/ironside/se/call.c index de4f59943f6a..8ca71e2ee690 100644 --- a/soc/nordic/ironside/call.c +++ b/modules/hal_nordic/ironside/se/call.c @@ -3,7 +3,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include +#include #include #include #include @@ -15,15 +16,15 @@ #define DT_DRV_COMPAT nordic_ironside_call #define SHM_NODE DT_INST_PHANDLE(0, memory_region) -#define NUM_BUFS (DT_REG_SIZE(SHM_NODE) / sizeof(struct ironside_call_buf)) +#define NUM_BUFS (DT_REG_SIZE(SHM_NODE) / sizeof(struct ironside_se_call_buf)) #define ALL_BUF_BITS BIT_MASK(NUM_BUFS) /* Note: this area is already zero-initialized at reset time. */ -static struct ironside_call_buf *const bufs = (void *)DT_REG_ADDR(SHM_NODE); +static struct ironside_se_call_buf *const bufs = (void *)DT_REG_ADDR(SHM_NODE); #if defined(CONFIG_DCACHE_LINE_SIZE) BUILD_ASSERT((DT_REG_ADDR(SHM_NODE) % CONFIG_DCACHE_LINE_SIZE) == 0); -BUILD_ASSERT((sizeof(struct ironside_call_buf) % CONFIG_DCACHE_LINE_SIZE) == 0); +BUILD_ASSERT((sizeof(struct ironside_se_call_buf) % CONFIG_DCACHE_LINE_SIZE) == 0); #endif static const struct mbox_dt_spec mbox_rx = MBOX_DT_SPEC_INST_GET(0, rx); @@ -40,7 +41,7 @@ static void ironside_call_rsp(const struct device *dev, mbox_channel_id_t channe ARG_UNUSED(user_data); ARG_UNUSED(data); - struct ironside_call_buf *buf; + struct ironside_se_call_buf *buf; uint32_t rsp_buf_bits = 0; /* Check which buffers are not being dispatched currently. Those must @@ -62,8 +63,8 @@ static void ironside_call_rsp(const struct device *dev, mbox_channel_id_t channe sys_cache_data_invd_range(buf, sizeof(*buf)); barrier_dmem_fence_full(); - if (buf->status != IRONSIDE_CALL_STATUS_IDLE && - buf->status != IRONSIDE_CALL_STATUS_REQ) { + if (buf->status != IRONSIDE_SE_CALL_STATUS_IDLE && + buf->status != IRONSIDE_SE_CALL_STATUS_REQ) { rsp_buf_bits |= BIT(i); } } @@ -89,9 +90,9 @@ static int ironside_call_init(const struct device *dev) } DEVICE_DT_INST_DEFINE(0, ironside_call_init, NULL, NULL, NULL, POST_KERNEL, - CONFIG_NRF_IRONSIDE_CALL_INIT_PRIORITY, NULL); + CONFIG_IRONSIDE_SE_CALL_INIT_PRIORITY, NULL); -struct ironside_call_buf *ironside_call_alloc(void) +struct ironside_se_call_buf *ironside_se_call_alloc(void) { uint32_t avail_buf_bits; uint32_t alloc_buf_bit; @@ -108,12 +109,12 @@ struct ironside_call_buf *ironside_call_alloc(void) return &bufs[u32_count_trailing_zeros(alloc_buf_bit)]; } -void ironside_call_dispatch(struct ironside_call_buf *buf) +void ironside_se_call_dispatch(struct ironside_se_call_buf *buf) { const uint32_t buf_bit = BIT(buf - bufs); int err; - buf->status = IRONSIDE_CALL_STATUS_REQ; + buf->status = IRONSIDE_SE_CALL_STATUS_REQ; barrier_dmem_fence_full(); sys_cache_data_flush_range(buf, sizeof(*buf)); @@ -126,11 +127,11 @@ void ironside_call_dispatch(struct ironside_call_buf *buf) k_event_wait(&rsp_evts, buf_bit, false, K_FOREVER); } -void ironside_call_release(struct ironside_call_buf *buf) +void ironside_se_call_release(struct ironside_se_call_buf *buf) { const uint32_t buf_bit = BIT(buf - bufs); - buf->status = IRONSIDE_CALL_STATUS_IDLE; + buf->status = IRONSIDE_SE_CALL_STATUS_IDLE; barrier_dmem_fence_full(); sys_cache_data_flush_range(buf, sizeof(*buf)); diff --git a/soc/nordic/ironside/dvfs.c b/modules/hal_nordic/ironside/se/dvfs.c similarity index 60% rename from soc/nordic/ironside/dvfs.c rename to modules/hal_nordic/ironside/se/dvfs.c index 6c7a86cd0ad4..8bba1a28f9a3 100644 --- a/soc/nordic/ironside/dvfs.c +++ b/modules/hal_nordic/ironside/se/dvfs.c @@ -2,13 +2,12 @@ * Copyright (c) 2025 Nordic Semiconductor ASA * SPDX-License-Identifier: Apache-2.0 */ +#include +#include #include #include -#include -#include - -static enum ironside_dvfs_oppoint current_dvfs_oppoint = IRONSIDE_DVFS_OPP_HIGH; +static enum ironside_se_dvfs_oppoint current_dvfs_oppoint = IRONSIDE_SE_DVFS_OPP_HIGH; #if defined(CONFIG_SOC_SERIES_NRF54HX) #define ABB_STATUSANA_LOCKED_L_Pos (0UL) @@ -18,7 +17,7 @@ static enum ironside_dvfs_oppoint current_dvfs_oppoint = IRONSIDE_DVFS_OPP_HIGH; #error "Unsupported SoC series for IronSide DVFS" #endif -#define ABB_STATUSANA_CHECK_MAX_ATTEMPTS (CONFIG_NRF_IRONSIDE_ABB_STATUSANA_CHECK_MAX_ATTEMPTS) +#define ABB_STATUSANA_CHECK_MAX_ATTEMPTS (CONFIG_IRONSIDE_SE_DVFS_ABB_STATUSANA_CHECK_MAX_ATTEMPTS) #define ABB_STATUSANA_CHECK_INTERVAL_US (10U) struct dvfs_hsfll_data_t { @@ -48,7 +47,7 @@ static const struct dvfs_hsfll_data_t dvfs_hsfll_data[] = { }, }; -BUILD_ASSERT(ARRAY_SIZE(dvfs_hsfll_data) == (IRONSIDE_DVFS_OPPOINT_COUNT), +BUILD_ASSERT(ARRAY_SIZE(dvfs_hsfll_data) == (IRONSIDE_SE_DVFS_OPPOINT_COUNT), "dvfs_hsfll_data size must match number of DVFS oppoints"); /** @@ -57,7 +56,7 @@ BUILD_ASSERT(ARRAY_SIZE(dvfs_hsfll_data) == (IRONSIDE_DVFS_OPPOINT_COUNT), * @param target_freq_setting The target oppoint to check. * @return true if the current oppoint is higher than the target, false otherwise. */ -static bool ironside_dvfs_is_downscaling(enum ironside_dvfs_oppoint target_freq_setting) +static bool is_downscaling(enum ironside_se_dvfs_oppoint target_freq_setting) { return current_dvfs_oppoint < target_freq_setting; } @@ -67,7 +66,7 @@ static bool ironside_dvfs_is_downscaling(enum ironside_dvfs_oppoint target_freq_ * * @param enum oppoint target operation point */ -static void ironside_dvfs_configure_hsfll(enum ironside_dvfs_oppoint oppoint) +static void configure_hsfll(enum ironside_se_dvfs_oppoint oppoint) { nrf_hsfll_trim_t hsfll_trim = {}; uint8_t freq_trim_idx = dvfs_hsfll_data[oppoint].new_f_trim_entry; @@ -93,15 +92,15 @@ static void ironside_dvfs_configure_hsfll(enum ironside_dvfs_oppoint oppoint) } /* Function handling steps for DVFS oppoint change. */ -static void ironside_dvfs_prepare_to_scale(enum ironside_dvfs_oppoint dvfs_oppoint) +static void prepare_to_scale(enum ironside_se_dvfs_oppoint dvfs_oppoint) { - if (ironside_dvfs_is_downscaling(dvfs_oppoint)) { - ironside_dvfs_configure_hsfll(dvfs_oppoint); + if (is_downscaling(dvfs_oppoint)) { + configure_hsfll(dvfs_oppoint); } } /* Update MDK variable which is used by nrfx_coredep_delay_us (k_busy_wait). */ -static void ironside_dvfs_update_core_clock(enum ironside_dvfs_oppoint dvfs_oppoint) +static void update_core_clock(enum ironside_se_dvfs_oppoint dvfs_oppoint) { extern uint32_t SystemCoreClock; @@ -109,14 +108,14 @@ static void ironside_dvfs_update_core_clock(enum ironside_dvfs_oppoint dvfs_oppo } /* Perform scaling finnish procedure. */ -static void ironside_dvfs_change_oppoint_complete(enum ironside_dvfs_oppoint dvfs_oppoint) +static void change_oppoint_complete(enum ironside_se_dvfs_oppoint dvfs_oppoint) { - if (!ironside_dvfs_is_downscaling(dvfs_oppoint)) { - ironside_dvfs_configure_hsfll(dvfs_oppoint); + if (!is_downscaling(dvfs_oppoint)) { + configure_hsfll(dvfs_oppoint); } current_dvfs_oppoint = dvfs_oppoint; - ironside_dvfs_update_core_clock(dvfs_oppoint); + update_core_clock(dvfs_oppoint); } /** @@ -126,7 +125,7 @@ static void ironside_dvfs_change_oppoint_complete(enum ironside_dvfs_oppoint dvf * * @return true if ABB is locked, false otherwise. */ -static inline bool ironside_dvfs_is_abb_locked(NRF_ABB_Type *abb) +static inline bool is_abb_locked(NRF_ABB_Type *abb) { /* Check if ABB analog part is locked. */ /* Temporary workaround until STATUSANA register is visible. */ @@ -142,46 +141,12 @@ static inline bool ironside_dvfs_is_abb_locked(NRF_ABB_Type *abb) return ((*statusana & ABB_STATUSANA_LOCKED_L_Msk) != 0); } -/** - * @brief Request DVFS oppoint change from IronSide secure domain. - * This function will send a request over IPC to the IronSide secure domain - * This function is synchronous and will return when the request is completed. - * - * @param oppoint @ref enum ironside_dvfs_oppoint - * @return int - */ -static int ironside_dvfs_req_oppoint(enum ironside_dvfs_oppoint oppoint) -{ - int err; - - struct ironside_call_buf *const buf = ironside_call_alloc(); - - buf->id = IRONSIDE_CALL_ID_DVFS_SERVICE_V0; - buf->args[IRONSIDE_DVFS_SERVICE_OPPOINT_IDX] = oppoint; - - ironside_call_dispatch(buf); - - if (buf->status == IRONSIDE_CALL_STATUS_RSP_SUCCESS) { - err = buf->args[IRONSIDE_DVFS_SERVICE_RETCODE_IDX]; - } else { - err = buf->status; - } - - ironside_call_release(buf); - - return err; -} - -int ironside_dvfs_change_oppoint(enum ironside_dvfs_oppoint dvfs_oppoint) +int ironside_se_dvfs_change_oppoint(enum ironside_se_dvfs_oppoint dvfs_oppoint) { int status = 0; - if (!ironside_dvfs_is_oppoint_valid(dvfs_oppoint)) { - return -IRONSIDE_DVFS_ERROR_WRONG_OPPOINT; - } - - if (!ironside_dvfs_is_abb_locked(NRF_ABB)) { - return -IRONSIDE_DVFS_ERROR_BUSY; + if (!is_abb_locked(NRF_ABB)) { + return -IRONSIDE_SE_DVFS_ERROR_BUSY; } if (dvfs_oppoint == current_dvfs_oppoint) { @@ -189,17 +154,17 @@ int ironside_dvfs_change_oppoint(enum ironside_dvfs_oppoint dvfs_oppoint) } if (k_is_in_isr()) { - return -IRONSIDE_DVFS_ERROR_ISR_NOT_ALLOWED; + return -IRONSIDE_SE_DVFS_ERROR_ISR_NOT_ALLOWED; } - ironside_dvfs_prepare_to_scale(dvfs_oppoint); - - status = ironside_dvfs_req_oppoint(dvfs_oppoint); + prepare_to_scale(dvfs_oppoint); + status = ironside_se_dvfs_req_oppoint(dvfs_oppoint); if (status != 0) { return status; } - ironside_dvfs_change_oppoint_complete(dvfs_oppoint); + + change_oppoint_complete(dvfs_oppoint); return status; } diff --git a/modules/hal_nordic/ironside/se/include/ironside_zephyr/se/dvfs.h b/modules/hal_nordic/ironside/se/include/ironside_zephyr/se/dvfs.h new file mode 100644 index 000000000000..d4048704537c --- /dev/null +++ b/modules/hal_nordic/ironside/se/include/ironside_zephyr/se/dvfs.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_MODULES_HAL_NORDIC_IRONSIDE_SE_INCLUDE_IRONSIDE_ZEPHYR_SE_DVFS_H_ +#define ZEPHYR_MODULES_HAL_NORDIC_IRONSIDE_SE_INCLUDE_IRONSIDE_ZEPHYR_SE_DVFS_H_ + +#include + +/** The DVFS oppoint change operation is not allowed in the ISR context. */ +#define IRONSIDE_SE_DVFS_ERROR_ISR_NOT_ALLOWED (7) + +/** + * @brief Change the current DVFS oppoint. + * + * This function will request a change of the current DVFS oppoint to the + * specified value. It will block until the change is applied. + * + * @param dvfs_oppoint The new DVFS oppoint to set. + * + * @retval 0 on success. + * @retval -IRONSIDE_SE_DVFS_ERROR_WRONG_OPPOINT if the requested DVFS oppoint is not allowed. + * @retval -IRONSIDE_SE_DVFS_ERROR_BUSY if waiting for mutex lock timed out, or hardware is busy. + * @retval -IRONSIDE_SE_DVFS_ERROR_OPPOINT_DATA if there is configuration error in the DVFS service. + * @retval -IRONSIDE_SE_DVFS_ERROR_PERMISSION if the caller does not have permission to change the + * DVFS oppoint. + * @retval -IRONSIDE_SE_DVFS_ERROR_NO_CHANGE_NEEDED if the requested DVFS oppoint is already set. + * @retval -IRONSIDE_SE_DVFS_ERROR_TIMEOUT if the operation timed out, possibly due to a hardware + * issue. + * @retval -IRONSIDE_SE_DVFS_ERROR_ISR_NOT_ALLOWED if the DVFS oppoint change operation is not + * allowed in the ISR context. + * @retval Positive error status if reported by IronSide call (see error codes in @ref call.h). + */ +int ironside_se_dvfs_change_oppoint(enum ironside_se_dvfs_oppoint dvfs_oppoint); + +#endif /* ZEPHYR_MODULES_HAL_NORDIC_IRONSIDE_SE_INCLUDE_IRONSIDE_ZEPHYR_SE_DVFS_H_ */ diff --git a/modules/hal_nordic/ironside/se/include/ironside_zephyr/se/uicr_periphconf.h b/modules/hal_nordic/ironside/se/include/ironside_zephyr/se/uicr_periphconf.h new file mode 100644 index 000000000000..919ccb23a79b --- /dev/null +++ b/modules/hal_nordic/ironside/se/include/ironside_zephyr/se/uicr_periphconf.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_MODULES_HAL_NORDIC_IRONSIDE_SE_INCLUDE_IRONSIDE_ZEPHYR_SE_UICR_PERIPHCONF_H_ +#define ZEPHYR_MODULES_HAL_NORDIC_IRONSIDE_SE_INCLUDE_IRONSIDE_ZEPHYR_SE_UICR_PERIPHCONF_H_ + +#include + +#include +#include +#include + +/** Add an entry to the PERIPHCONF table section. + * + * This is a Zephyr integration with the IronSide UICR PERIPHCONF construction + * macros that uses an iterable section to store the entries. + * + * The macro expects a struct periphconf_entry initializer as input. + * The macros defined in ironside/se/periphconf.h can be used to construct the initializer. + * For example: + * + * UICR_PERIPHCONF_ENTRY(PERIPHCONF_SPU_FEATURE_GRTC_CC(...)); + * + */ +#define UICR_PERIPHCONF_ENTRY(_entry) \ + static STRUCT_SECTION_ITERABLE(periphconf_entry, \ + _UICR_PERIPHCONF_ENTRY_NAME(__COUNTER__)) = _entry + +#define _UICR_PERIPHCONF_ENTRY_NAME(_id) __UICR_PERIPHCONF_ENTRY_NAME(_id) +#define __UICR_PERIPHCONF_ENTRY_NAME(_id) _uicr_periphconf_entry_##_id + +#endif /* ZEPHYR_MODULES_HAL_NORDIC_IRONSIDE_SE_INCLUDE_IRONSIDE_ZEPHYR_SE_UICR_PERIPHCONF_H_ */ diff --git a/soc/nordic/common/uicr/gen_periphconf_entries.py b/modules/hal_nordic/ironside/se/scripts/gen_periphconf_entries.py similarity index 99% rename from soc/nordic/common/uicr/gen_periphconf_entries.py rename to modules/hal_nordic/ironside/se/scripts/gen_periphconf_entries.py index 13df5e468ded..b30d36f4c7f6 100644 --- a/soc/nordic/common/uicr/gen_periphconf_entries.py +++ b/modules/hal_nordic/ironside/se/scripts/gen_periphconf_entries.py @@ -19,8 +19,9 @@ sys.exit("Set the environment variable 'ZEPHYR_BASE' to point to the zephyr root directory") # Add packages that are located in zephyr itself to the python path so we can import them below +# The devicetree package is needed on the path for unpickling devicetree object, even if we aren't +# importing anything from it directly. sys.path.insert(0, str(ZEPHYR_BASE / "scripts/dts/python-devicetree/src")) -sys.path.insert(0, str(ZEPHYR_BASE / "soc/nordic/common/uicr")) from periphconf.builder import ( Ctrlsel, diff --git a/soc/nordic/common/uicr/periphconf/__init__.py b/modules/hal_nordic/ironside/se/scripts/periphconf/__init__.py similarity index 100% rename from soc/nordic/common/uicr/periphconf/__init__.py rename to modules/hal_nordic/ironside/se/scripts/periphconf/__init__.py diff --git a/soc/nordic/common/uicr/periphconf/builder.py b/modules/hal_nordic/ironside/se/scripts/periphconf/builder.py similarity index 97% rename from soc/nordic/common/uicr/periphconf/builder.py rename to modules/hal_nordic/ironside/se/scripts/periphconf/builder.py index 34ccc6f7b497..f749a8ea277d 100644 --- a/soc/nordic/common/uicr/periphconf/builder.py +++ b/modules/hal_nordic/ironside/se/scripts/periphconf/builder.py @@ -130,7 +130,7 @@ def build_generated_source(self, header_line: str | None = None) -> str: source_lines.extend( [ "#include ", - "#include ", + "#include ", "", ] ) @@ -270,7 +270,7 @@ def _add_global_peripheral_spu_permissions( self._macros.append( MacroCall( - "UICR_SPU_PERIPH_PERM_SET", + "PERIPHCONF_SPU_PERIPH_PERM", [ Address(spu_address), periph_slave_index, @@ -318,7 +318,7 @@ def _add_global_peripheral_irq_mapping(self, node: Node) -> None: self._macros.append( MacroCall( - "UICR_IRQMAP_IRQ_SINK_SET", + "PERIPHCONF_IRQMAP_IRQ_SINK", [ macro_irqn, irq_processor.c_enum, @@ -339,7 +339,7 @@ def _add_nrf_gpiote_spu_permissions(self, node: Node) -> None: for num, secure in dt_split_channels_get(node): self._macros.append( MacroCall( - "UICR_SPU_FEATURE_GPIOTE_CH_SET", + "PERIPHCONF_SPU_FEATURE_GPIOTE_CH", [ Address(spu_address), 0, @@ -370,7 +370,7 @@ def _add_nrf_dppic_spu_permissions(self, node: Node) -> None: for num, secure in channels: self._macros.append( MacroCall( - "UICR_SPU_FEATURE_DPPIC_CH_SET", + "PERIPHCONF_SPU_FEATURE_DPPIC_CH", [ Address(spu_address), num, @@ -384,7 +384,7 @@ def _add_nrf_dppic_spu_permissions(self, node: Node) -> None: for num, secure in channel_groups: self._macros.append( MacroCall( - "UICR_SPU_FEATURE_DPPIC_CHG_SET", + "PERIPHCONF_SPU_FEATURE_DPPIC_CHG", [ Address(spu_address), num, @@ -435,7 +435,7 @@ def _link_dppi_channels( self._macros.append( MacroCall( - "UICR_PPIB_SUBSCRIBE_SEND_ENABLE", + "PERIPHCONF_PPIB_SUBSCRIBE_SEND", [ Address(sub_ppib_addr), sub_ppib_ch, @@ -447,7 +447,7 @@ def _link_dppi_channels( ) self._macros.append( MacroCall( - "UICR_PPIB_PUBLISH_RECEIVE_ENABLE", + "PERIPHCONF_PPIB_PUBLISH_RECEIVE", [ Address(pub_ppib_addr), pub_ppib_ch, @@ -470,7 +470,7 @@ def _add_nrf_ipct_global_spu_permissions(self, node: Node) -> None: for num, secure in dt_split_channels_get(node): self._macros.append( MacroCall( - "UICR_SPU_FEATURE_IPCT_CH_SET", + "PERIPHCONF_SPU_FEATURE_IPCT_CH", [ Address(spu_address), num, @@ -536,8 +536,18 @@ def _link_ipct_channel( self._macros.append( MacroCall( - "UICR_IPCMAP_CHANNEL_CFG", - [self._ipcmap_idx, *link_args], + "PERIPHCONF_IPCMAP_CHANNEL_SOURCE", + [self._ipcmap_idx, source_domain.c_enum, source_ch], + comment=( + f"{source_domain.name} IPCT ch. {source_ch} => " + f"{sink_domain.name} IPCT ch. {sink_ch}" + ), + ) + ) + self._macros.append( + MacroCall( + "PERIPHCONF_IPCMAP_CHANNEL_SINK", + [self._ipcmap_idx, sink_domain.c_enum, sink_ch], comment=( f"{source_domain.name} IPCT ch. {source_ch} => " f"{sink_domain.name} IPCT ch. {sink_ch}" @@ -557,7 +567,7 @@ def _add_nrf_grtc_spu_permissions(self, node: Node) -> None: for num, secure in dt_split_channels_get(node): self._macros.append( MacroCall( - "UICR_SPU_FEATURE_GRTC_CC_SET", + "PERIPHCONF_SPU_FEATURE_GRTC_CC", [ Address(spu_address), num, @@ -679,7 +689,7 @@ def _configure_gpio_pin( self._macros.append( MacroCall( - "UICR_SPU_FEATURE_GPIO_PIN_SET", + "PERIPHCONF_SPU_FEATURE_GPIO_PIN", [ Address(spu_address), gpio_port, @@ -695,7 +705,7 @@ def _configure_gpio_pin( ctrlsel_int = int(ctrlsel) self._macros.append( MacroCall( - "UICR_GPIO_PIN_CNF_CTRLSEL_SET", + "PERIPHCONF_GPIO_PIN_CNF_CTRLSEL", [ Address(gpio_addr), num, @@ -737,7 +747,8 @@ def c_render(self, nodelabel_lookup: dict[int, str]) -> str: str_args.append(str(arg)) comment = f"/* {self.comment} */\n" if self.comment else "" - return f"{comment}{self.name}({', '.join(str_args)});" + entry_macro = f"UICR_PERIPHCONF_ENTRY({self.name}({', '.join(str_args)}))" + return f"{comment}{entry_macro};" def c_hex_addr(address: int) -> str: diff --git a/soc/nordic/common/uicr/uicr.ld b/modules/hal_nordic/ironside/se/uicr.ld similarity index 61% rename from soc/nordic/common/uicr/uicr.ld rename to modules/hal_nordic/ironside/se/uicr.ld index 210495b1c66c..adc2e2cc3f64 100644 --- a/soc/nordic/common/uicr/uicr.ld +++ b/modules/hal_nordic/ironside/se/uicr.ld @@ -5,7 +5,7 @@ #include -SECTION_PROLOGUE(uicr_periphconf_entry,(COPY),SUBALIGN(Z_LINK_ITERABLE_SUBALIGN)) +SECTION_PROLOGUE(periphconf_entry,(COPY),SUBALIGN(Z_LINK_ITERABLE_SUBALIGN)) { - Z_LINK_ITERABLE(uicr_periphconf_entry); + Z_LINK_ITERABLE(periphconf_entry); } GROUP_ROM_LINK_IN(DEVNULL_REGION, DEVNULL_REGION) diff --git a/samples/boards/nordic/nrf_ironside/update/prj.conf b/samples/boards/nordic/nrf_ironside/update/prj.conf index 1d6a2ac823df..1e935e973c76 100644 --- a/samples/boards/nordic/nrf_ironside/update/prj.conf +++ b/samples/boards/nordic/nrf_ironside/update/prj.conf @@ -1,4 +1 @@ CONFIG_LOG=y - -CONFIG_NRF_IRONSIDE_UPDATE_SERVICE=y -CONFIG_NRF_IRONSIDE_BOOT_REPORT=y diff --git a/samples/boards/nordic/nrf_ironside/update/src/main.c b/samples/boards/nordic/nrf_ironside/update/src/main.c index ee8823217de2..3dbd2de1a85d 100644 --- a/samples/boards/nordic/nrf_ironside/update/src/main.c +++ b/samples/boards/nordic/nrf_ironside/update/src/main.c @@ -4,23 +4,21 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include -#include +#include +#include #include LOG_MODULE_REGISTER(app, LOG_LEVEL_INF); -BUILD_ASSERT(CONFIG_UPDATE_BLOB_ADDRESS >= IRONSIDE_UPDATE_MIN_ADDRESS); -BUILD_ASSERT(CONFIG_UPDATE_BLOB_ADDRESS <= IRONSIDE_UPDATE_MAX_ADDRESS); +BUILD_ASSERT(CONFIG_UPDATE_BLOB_ADDRESS >= IRONSIDE_SE_UPDATE_MIN_ADDRESS); +BUILD_ASSERT(CONFIG_UPDATE_BLOB_ADDRESS <= IRONSIDE_SE_UPDATE_MAX_ADDRESS); int main(void) { int err; - const struct ironside_update_blob *update = (void *)CONFIG_UPDATE_BLOB_ADDRESS; - const struct ironside_boot_report *report; + const struct ironside_se_update_blob *update = (void *)CONFIG_UPDATE_BLOB_ADDRESS; + const struct ironside_se_boot_report *report = IRONSIDE_SE_BOOT_REPORT; - err = ironside_boot_report_get(&report); - LOG_INF("ironside_boot_report_get err: %d", err); /* Extract version components from packed 32-bit integer (8-bit MAJOR.MINOR.PATCH.SEQNUM) */ uint8_t se_major = (report->ironside_se_version_int >> 24) & 0xFF; uint8_t se_minor = (report->ironside_se_version_int >> 16) & 0xFF; @@ -37,9 +35,9 @@ int main(void) LOG_INF("recovery version: %d.%d.%d-%s+%d", recovery_major, recovery_minor, recovery_patch, report->ironside_se_recovery_extraversion, recovery_seqnum); LOG_INF("update status: 0x%x", report->ironside_update_status); - LOG_HEXDUMP_INF((void *)report->random_data, sizeof(report->random_data), "random data"); + LOG_HEXDUMP_INF((void *)report->random.data, sizeof(report->random.data), "random data"); - err = ironside_update(update); + err = ironside_se_update(update); LOG_INF("IronSide update retval: 0x%x", err); if (err == 0) { diff --git a/soc/nordic/CMakeLists.txt b/soc/nordic/CMakeLists.txt index f32466d38ee5..11f6bb66d66f 100644 --- a/soc/nordic/CMakeLists.txt +++ b/soc/nordic/CMakeLists.txt @@ -50,4 +50,3 @@ if(CONFIG_SOC_NORDIC_BSP_NAME STREQUAL "stable") endif() add_subdirectory(common) -add_subdirectory_ifdef(CONFIG_NRF_IRONSIDE ironside) diff --git a/soc/nordic/common/CMakeLists.txt b/soc/nordic/common/CMakeLists.txt index 114d970008d6..0a2825dd741f 100644 --- a/soc/nordic/common/CMakeLists.txt +++ b/soc/nordic/common/CMakeLists.txt @@ -3,8 +3,6 @@ add_subdirectory_ifdef(CONFIG_RISCV_CORE_NORDIC_VPR vpr) -add_subdirectory(uicr) - # Let SystemInit() be called in place of soc_reset_hook() by default. zephyr_linker_symbol(SYMBOL soc_reset_hook EXPR "@SystemInit@") diff --git a/soc/nordic/common/uicr/Kconfig b/soc/nordic/common/uicr/Kconfig index c3a69c3dbe0f..c38a8e9bc67a 100644 --- a/soc/nordic/common/uicr/Kconfig +++ b/soc/nordic/common/uicr/Kconfig @@ -1,24 +1,6 @@ # Copyright (c) 2025 Nordic Semiconductor ASA # SPDX-License-Identifier: Apache-2.0 -config NRF_PERIPHCONF_SECTION - bool "Populate global peripheral initialization section" - default y if SOC_NRF54H20_CPUAPP || SOC_NRF54H20_CPURAD || SOC_NRF9280_CPUAPP - depends on LINKER_DEVNULL_SUPPORT - imply LINKER_DEVNULL_MEMORY - help - Include static global domain peripheral initialization values from the - build in a dedicated section in the devnull region. - -config NRF_PERIPHCONF_GENERATE_ENTRIES - bool "Generate PERIPHCONF entries source file" - default y if SOC_NRF54H20_CPUAPP || SOC_NRF54H20_CPURAD || SOC_NRF9280_CPUAPP - depends on NRF_PERIPHCONF_SECTION - depends on NRF_PLATFORM_HALTIUM - help - Generate a C file containing PERIPHCONF entries based on the - device configuration in the devicetree. - config IS_IRONSIDE_SE_SECONDARY_IMAGE bool "Ironside SE secondary image indicator (informative only, do not change)" help diff --git a/soc/nordic/common/uicr/Kconfig.sysbuild b/soc/nordic/common/uicr/Kconfig.sysbuild index 6a9341f90994..977f910b1617 100644 --- a/soc/nordic/common/uicr/Kconfig.sysbuild +++ b/soc/nordic/common/uicr/Kconfig.sysbuild @@ -2,8 +2,10 @@ # SPDX-License-Identifier: Apache-2.0 config NRF_HALTIUM_GENERATE_UICR - bool "Generate UICR file" + bool "Generate UICR artifacts" depends on SOC_SERIES_NRF54HX || SOC_SERIES_NRF92X default y help - Generate UICR HEX file. + When enabled, a UICR generator image is included in the build. + This generates binary configuration artifacts based on the Kconfig and device tree + of the UICR generator image. See the UICR generator options for further details. diff --git a/soc/nordic/common/uicr/gen_uicr.py b/soc/nordic/common/uicr/gen_uicr.py deleted file mode 100644 index 8dbbc7fe5ce9..000000000000 --- a/soc/nordic/common/uicr/gen_uicr.py +++ /dev/null @@ -1,859 +0,0 @@ -""" -Copyright (c) 2025 Nordic Semiconductor ASA -SPDX-License-Identifier: Apache-2.0 -""" - -from __future__ import annotations - -import argparse -import ctypes as c -import sys -from itertools import groupby, pairwise -from typing import NamedTuple - -from elftools.elf.elffile import ELFFile -from intelhex import IntelHex - -# The UICR format version produced by this script -UICR_FORMAT_VERSION_MAJOR = 2 -UICR_FORMAT_VERSION_MINOR = 0 - -# Name of the ELF section containing PERIPHCONF entries. -# Must match the name used in the linker script. -PERIPHCONF_SECTION = "uicr_periphconf_entry" - -# Common values for representing enabled/disabled in the UICR format. -ENABLED_VALUE = 0xFFFF_FFFF -DISABLED_VALUE = 0xBD23_28A8 -PROTECTED_VALUE = ENABLED_VALUE # UICR_PROTECTED = UICR_ENABLED per uicr_defs.h -UNPROTECTED_VALUE = DISABLED_VALUE # Unprotected uses the default erased value - -KB_4 = 4096 - - -class ScriptError(RuntimeError): ... - - -class PartitionInfo(NamedTuple): - """Information about a partition for secure storage validation.""" - - address: int - size: int - name: str - - -class PeriphconfEntry(c.LittleEndianStructure): - _pack_ = 1 - _fields_ = [ - ("regptr", c.c_uint32), - ("value", c.c_uint32), - ] - - -PERIPHCONF_ENTRY_SIZE = c.sizeof(PeriphconfEntry) - - -class Version(c.LittleEndianStructure): - _pack_ = 1 - _fields_ = [ - ("MINOR", c.c_uint16), - ("MAJOR", c.c_uint16), - ] - - -class Approtect(c.LittleEndianStructure): - _pack_ = 1 - _fields_ = [ - ("APPLICATION", c.c_uint32), - ("RADIOCORE", c.c_uint32), - ("RESERVED", c.c_uint32), - ("CORESIGHT", c.c_uint32), - ] - - -class Protectedmem(c.LittleEndianStructure): - _pack_ = 1 - _fields_ = [ - ("ENABLE", c.c_uint32), - ("SIZE4KB", c.c_uint32), - ] - - -class Wdtstart(c.LittleEndianStructure): - _pack_ = 1 - _fields_ = [ - ("ENABLE", c.c_uint32), - ("INSTANCE", c.c_uint32), - ("CRV", c.c_uint32), - ] - - -class SecurestorageCrypto(c.LittleEndianStructure): - _pack_ = 1 - _fields_ = [ - ("APPLICATIONSIZE1KB", c.c_uint32), - ("RADIOCORESIZE1KB", c.c_uint32), - ] - - -class SecurestorageIts(c.LittleEndianStructure): - _pack_ = 1 - _fields_ = [ - ("APPLICATIONSIZE1KB", c.c_uint32), - ("RADIOCORESIZE1KB", c.c_uint32), - ] - - -class Securestorage(c.LittleEndianStructure): - _pack_ = 1 - _fields_ = [ - ("ENABLE", c.c_uint32), - ("ADDRESS", c.c_uint32), - ("CRYPTO", SecurestorageCrypto), - ("ITS", SecurestorageIts), - ] - - -class Periphconf(c.LittleEndianStructure): - _pack_ = 1 - _fields_ = [ - ("ENABLE", c.c_uint32), - ("ADDRESS", c.c_uint32), - ("MAXCOUNT", c.c_uint32), - ] - - -class Mpcconf(c.LittleEndianStructure): - _pack_ = 1 - _fields_ = [ - ("ENABLE", c.c_uint32), - ("ADDRESS", c.c_uint32), - ("MAXCOUNT", c.c_uint32), - ] - - -class SecondaryTrigger(c.LittleEndianStructure): - _pack_ = 1 - _fields_ = [ - ("ENABLE", c.c_uint32), - ("RESETREAS", c.c_uint32), - ("RESERVED", c.c_uint32), - ] - - -class SecondaryProtectedmem(c.LittleEndianStructure): - _pack_ = 1 - _fields_ = [ - ("ENABLE", c.c_uint32), - ("SIZE4KB", c.c_uint32), - ] - - -class SecondaryWdtstart(c.LittleEndianStructure): - _pack_ = 1 - _fields_ = [ - ("ENABLE", c.c_uint32), - ("INSTANCE", c.c_uint32), - ("CRV", c.c_uint32), - ] - - -class SecondaryPeriphconf(c.LittleEndianStructure): - _pack_ = 1 - _fields_ = [ - ("ENABLE", c.c_uint32), - ("ADDRESS", c.c_uint32), - ("MAXCOUNT", c.c_uint32), - ] - - -class SecondaryMpcconf(c.LittleEndianStructure): - _pack_ = 1 - _fields_ = [ - ("ENABLE", c.c_uint32), - ("ADDRESS", c.c_uint32), - ("MAXCOUNT", c.c_uint32), - ] - - -class Secondary(c.LittleEndianStructure): - _pack_ = 1 - _fields_ = [ - ("ENABLE", c.c_uint32), - ("PROCESSOR", c.c_uint32), - ("TRIGGER", SecondaryTrigger), - ("ADDRESS", c.c_uint32), - ("PROTECTEDMEM", SecondaryProtectedmem), - ("WDTSTART", SecondaryWdtstart), - ("PERIPHCONF", SecondaryPeriphconf), - ("MPCCONF", SecondaryMpcconf), - ] - - -class Uicr(c.LittleEndianStructure): - _pack_ = 1 - _fields_ = [ - ("VERSION", Version), - ("RESERVED", c.c_uint32), - ("LOCK", c.c_uint32), - ("RESERVED1", c.c_uint32), - ("APPROTECT", Approtect), - ("ERASEPROTECT", c.c_uint32), - ("PROTECTEDMEM", Protectedmem), - ("WDTSTART", Wdtstart), - ("RESERVED2", c.c_uint32), - ("SECURESTORAGE", Securestorage), - ("RESERVED3", c.c_uint32 * 5), - ("PERIPHCONF", Periphconf), - ("MPCCONF", Mpcconf), - ("SECONDARY", Secondary), - ("PADDING", c.c_uint32 * 15), - ] - - -def validate_secure_storage_partitions(args: argparse.Namespace) -> None: - """ - Validate that secure storage partitions are laid out correctly. - - Args: - args: Parsed command line arguments containing partition information - - Raises: - ScriptError: If validation fails - """ - # Expected order: cpuapp_crypto_partition, cpurad_crypto_partition, - # cpuapp_its_partition, cpurad_its_partition - partitions = [ - PartitionInfo( - args.cpuapp_crypto_address, args.cpuapp_crypto_size, "cpuapp_crypto_partition" - ), - PartitionInfo( - args.cpurad_crypto_address, args.cpurad_crypto_size, "cpurad_crypto_partition" - ), - PartitionInfo(args.cpuapp_its_address, args.cpuapp_its_size, "cpuapp_its_partition"), - PartitionInfo(args.cpurad_its_address, args.cpurad_its_size, "cpurad_its_partition"), - ] - - # Filter out zero-sized partitions (missing partitions) - present_partitions = [p for p in partitions if p.size > 0] - - # Require at least one subpartition to be present - if not present_partitions: - raise ScriptError( - "At least one secure storage subpartition must be defined. " - "Define one or more of: cpuapp_crypto_partition, cpurad_crypto_partition, " - "cpuapp_its_partition, cpurad_its_partition" - ) - - # Check 4KB alignment for secure storage start address - if args.securestorage_address % 4096 != 0: - raise ScriptError( - f"Secure storage address {args.securestorage_address:#x} must be aligned to 4KB " - f"(4096 bytes)" - ) - - # Check 4KB alignment for secure storage size - if args.securestorage_size % 4096 != 0: - raise ScriptError( - f"Secure storage size {args.securestorage_size} bytes must be aligned to 4KB " - f"(4096 bytes)" - ) - - # Check that the first present partition starts at the secure storage address - first_partition = present_partitions[0] - if first_partition.address != args.securestorage_address: - raise ScriptError( - f"First partition {first_partition.name} starts at {first_partition.address:#x}, " - f"but must start at secure storage address {args.securestorage_address:#x}" - ) - - # Check that all present partitions have sizes that are multiples of 1KB - for partition in present_partitions: - if partition.size % 1024 != 0: - raise ScriptError( - f"Partition {partition.name} has size {partition.size} bytes, but must be " - f"a multiple of 1024 bytes (1KB)" - ) - - # Check that partitions are in correct order and don't overlap - for curr_partition, next_partition in pairwise(present_partitions): - # Check order - partitions should be in ascending address order - if curr_partition.address >= next_partition.address: - raise ScriptError( - f"Partition {curr_partition.name} (starts at {curr_partition.address:#x}) " - f"must come before {next_partition.name} (starts at {next_partition.address:#x})" - ) - - # Check for overlap - curr_end = curr_partition.address + curr_partition.size - if curr_end > next_partition.address: - raise ScriptError( - f"Partition {curr_partition.name} (ends at {curr_end:#x}) overlaps with " - f"{next_partition.name} (starts at {next_partition.address:#x})" - ) - - # Check for gaps (should be no gaps between consecutive partitions) - if curr_end < next_partition.address: - gap = next_partition.address - curr_end - raise ScriptError( - f"Gap of {gap} bytes between {curr_partition.name} (ends at {curr_end:#x}) and " - f"{next_partition.name} (starts at {next_partition.address:#x})" - ) - - # Check that combined subpartition sizes equal secure_storage_partition size - total_subpartition_size = sum(p.size for p in present_partitions) - if total_subpartition_size != args.securestorage_size: - raise ScriptError( - f"Combined size of subpartitions ({total_subpartition_size} bytes) does not match " - f"secure_storage_partition size ({args.securestorage_size} bytes). " - f"The definition is not coherent." - ) - - -def main() -> None: - parser = argparse.ArgumentParser( - allow_abbrev=False, - description=( - "Generate artifacts for the UICR and associated configuration blobs from application " - "build outputs. User Information Configuration Registers (UICR), in the context of " - "certain Nordic SoCs, are used to configure system resources, like memory and " - "peripherals, and to protect the device in various ways." - ), - ) - parser.add_argument( - "--in-periphconf-elf", - dest="in_periphconf_elfs", - default=[], - action="append", - type=argparse.FileType("rb"), - help=( - "Path to an ELF file to extract PERIPHCONF data from. Can be provided multiple times. " - "The PERIPHCONF data from each ELF file is combined in a single list which is sorted " - "by ascending address and cleared of duplicate entries." - ), - ) - parser.add_argument( - "--out-merged-hex", - required=True, - type=argparse.FileType("w", encoding="utf-8"), - help="Path to write the merged UICR+PERIPHCONF HEX file to", - ) - parser.add_argument( - "--out-uicr-hex", - required=True, - type=argparse.FileType("w", encoding="utf-8"), - help="Path to write the UICR-only HEX file to", - ) - parser.add_argument( - "--out-periphconf-hex", - type=argparse.FileType("w", encoding="utf-8"), - help="Path to write the PERIPHCONF-only HEX file to", - ) - parser.add_argument( - "--periphconf-address", - default=None, - type=lambda s: int(s, 0), - help="Absolute flash address of the PERIPHCONF partition (decimal or 0x-prefixed hex)", - ) - parser.add_argument( - "--periphconf-size", - default=None, - type=lambda s: int(s, 0), - help="Size in bytes of the PERIPHCONF partition (decimal or 0x-prefixed hex)", - ) - parser.add_argument( - "--uicr-address", - required=True, - type=lambda s: int(s, 0), - help="Absolute flash address of the UICR region (decimal or 0x-prefixed hex)", - ) - parser.add_argument( - "--securestorage", - action="store_true", - help="Enable secure storage support in UICR", - ) - parser.add_argument( - "--securestorage-address", - default=None, - type=lambda s: int(s, 0), - help="Absolute flash address of the secure storage partition (decimal or 0x-prefixed hex)", - ) - parser.add_argument( - "--securestorage-size", - default=None, - type=lambda s: int(s, 0), - help="Size in bytes of the secure storage partition (decimal or 0x-prefixed hex)", - ) - parser.add_argument( - "--cpuapp-crypto-address", - default=0, - type=lambda s: int(s, 0), - help="Absolute flash address of cpuapp_crypto_partition (decimal or 0x-prefixed hex)", - ) - parser.add_argument( - "--cpuapp-crypto-size", - default=0, - type=lambda s: int(s, 0), - help="Size in bytes of cpuapp_crypto_partition (decimal or 0x-prefixed hex)", - ) - parser.add_argument( - "--cpurad-crypto-address", - default=0, - type=lambda s: int(s, 0), - help="Absolute flash address of cpurad_crypto_partition (decimal or 0x-prefixed hex)", - ) - parser.add_argument( - "--cpurad-crypto-size", - default=0, - type=lambda s: int(s, 0), - help="Size in bytes of cpurad_crypto_partition (decimal or 0x-prefixed hex)", - ) - parser.add_argument( - "--cpuapp-its-address", - default=0, - type=lambda s: int(s, 0), - help="Absolute flash address of cpuapp_its_partition (decimal or 0x-prefixed hex)", - ) - parser.add_argument( - "--cpuapp-its-size", - default=0, - type=lambda s: int(s, 0), - help="Size in bytes of cpuapp_its_partition (decimal or 0x-prefixed hex)", - ) - parser.add_argument( - "--cpurad-its-address", - default=0, - type=lambda s: int(s, 0), - help="Absolute flash address of cpurad_its_partition (decimal or 0x-prefixed hex)", - ) - parser.add_argument( - "--cpurad-its-size", - default=0, - type=lambda s: int(s, 0), - help="Size in bytes of cpurad_its_partition (decimal or 0x-prefixed hex)", - ) - parser.add_argument( - "--permit-permanently-transitioning-device-to-deployed", - action="store_true", - help=( - "Safety flag required to enable both UICR.LOCK and UICR.ERASEPROTECT together. " - "Must be explicitly provided to acknowledge permanent device state changes." - ), - ) - parser.add_argument( - "--lock", - action="store_true", - help="Enable UICR.LOCK to prevent modifications without ERASEALL", - ) - parser.add_argument( - "--eraseprotect", - action="store_true", - help="Enable UICR.ERASEPROTECT to block ERASEALL operations", - ) - parser.add_argument( - "--approtect-application-protected", - action="store_true", - help="Protect application domain access port (disable debug access)", - ) - parser.add_argument( - "--approtect-radiocore-protected", - action="store_true", - help="Protect radio core access port (disable debug access)", - ) - parser.add_argument( - "--approtect-coresight-protected", - action="store_true", - help="Protect CoreSight access port (disable debug access)", - ) - parser.add_argument( - "--protectedmem", - action="store_true", - help="Enable protected memory region in UICR", - ) - parser.add_argument( - "--protectedmem-size-bytes", - type=int, - help="Protected memory size in bytes (must be divisible by 4096)", - ) - parser.add_argument( - "--wdtstart", - action="store_true", - help="Enable watchdog timer start in UICR", - ) - parser.add_argument( - "--wdtstart-instance-code", - type=lambda s: int(s, 0), - help="Watchdog timer instance code (0xBD2328A8 for WDT0, 0x1730C77F for WDT1)", - ) - parser.add_argument( - "--wdtstart-crv", - type=int, - help="Initial Counter Reload Value (CRV) for watchdog timer (minimum: 0xF)", - ) - parser.add_argument( - "--secondary-wdtstart", - action="store_true", - help="Enable watchdog timer start in UICR.SECONDARY", - ) - parser.add_argument( - "--secondary-wdtstart-instance-code", - type=lambda s: int(s, 0), - help="Secondary watchdog timer instance code (0xBD2328A8 for WDT0, 0x1730C77F for WDT1)", - ) - parser.add_argument( - "--secondary-wdtstart-crv", - type=int, - help="Secondary initial Counter Reload Value (CRV) for watchdog timer (minimum: 0xF)", - ) - parser.add_argument( - "--secondary", - action="store_true", - help="Enable secondary firmware support in UICR", - ) - parser.add_argument( - "--secondary-address", - default=None, - type=lambda s: int(s, 0), - help="Absolute flash address of the secondary firmware (decimal or 0x-prefixed hex)", - ) - parser.add_argument( - "--secondary-processor", - default=0xBD2328A8, - type=lambda s: int(s, 0), - help="Processor to boot for the secondary firmware ", - ) - parser.add_argument( - "--secondary-trigger", - action="store_true", - help="Enable UICR.SECONDARY.TRIGGER for automatic secondary firmware boot on reset events", - ) - parser.add_argument( - "--secondary-trigger-resetreas", - default=0, - type=lambda s: int(s, 0), - help=( - "Bitmask of reset reasons that trigger secondary firmware boot " - "(decimal or 0x-prefixed hex)" - ), - ) - parser.add_argument( - "--secondary-protectedmem-size", - default=None, - type=lambda s: int(s, 0), - help="Size in bytes of the secondary protected memory region (decimal or 0x-prefixed hex)", - ) - parser.add_argument( - "--secondary-periphconf-address", - default=None, - type=lambda s: int(s, 0), - help=( - "Absolute flash address of the secondary PERIPHCONF partition " - "(decimal or 0x-prefixed hex)" - ), - ) - parser.add_argument( - "--secondary-periphconf-size", - default=None, - type=lambda s: int(s, 0), - help="Size in bytes of the secondary PERIPHCONF partition (decimal or 0x-prefixed hex)", - ) - parser.add_argument( - "--in-secondary-periphconf-elf", - dest="in_secondary_periphconf_elfs", - default=[], - action="append", - type=argparse.FileType("rb"), - help=( - "Path to an ELF file to extract secondary PERIPHCONF data from. " - "Can be provided multiple times. The secondary PERIPHCONF data from each ELF file " - "is combined in a single list which is sorted by ascending address and cleared " - "of duplicate entries." - ), - ) - parser.add_argument( - "--out-secondary-periphconf-hex", - type=argparse.FileType("w", encoding="utf-8"), - help="Path to write the secondary PERIPHCONF-only HEX file to", - ) - args = parser.parse_args() - - try: - # Validate argument dependencies - if args.out_periphconf_hex: - if args.periphconf_address is None: - raise ScriptError( - "--periphconf-address is required when --out-periphconf-hex is used" - ) - if args.periphconf_size is None: - raise ScriptError("--periphconf-size is required when --out-periphconf-hex is used") - - # Validate secondary argument dependencies - if args.secondary and args.secondary_address is None: - raise ScriptError("--secondary-address is required when --secondary is used") - - if args.out_secondary_periphconf_hex: - if args.secondary_periphconf_address is None: - raise ScriptError( - "--secondary-periphconf-address is required when " - "--out-secondary-periphconf-hex is used" - ) - if args.secondary_periphconf_size is None: - raise ScriptError( - "--secondary-periphconf-size is required when " - "--out-secondary-periphconf-hex is used" - ) - - # Validate secure storage argument dependencies - if args.securestorage: - if args.securestorage_address is None: - raise ScriptError( - "--securestorage-address is required when --securestorage is used" - ) - if args.securestorage_size is None: - raise ScriptError("--securestorage-size is required when --securestorage is used") - - # Validate partition layout - validate_secure_storage_partitions(args) - - init_values = DISABLED_VALUE.to_bytes(4, "little") * (c.sizeof(Uicr) // 4) - uicr = Uicr.from_buffer_copy(init_values) - - uicr.VERSION.MAJOR = UICR_FORMAT_VERSION_MAJOR - uicr.VERSION.MINOR = UICR_FORMAT_VERSION_MINOR - - # Handle secure storage configuration - if args.securestorage: - uicr.SECURESTORAGE.ENABLE = ENABLED_VALUE - uicr.SECURESTORAGE.ADDRESS = args.securestorage_address - - # Set partition sizes in 1KB units - uicr.SECURESTORAGE.CRYPTO.APPLICATIONSIZE1KB = args.cpuapp_crypto_size // 1024 - uicr.SECURESTORAGE.CRYPTO.RADIOCORESIZE1KB = args.cpurad_crypto_size // 1024 - uicr.SECURESTORAGE.ITS.APPLICATIONSIZE1KB = args.cpuapp_its_size // 1024 - uicr.SECURESTORAGE.ITS.RADIOCORESIZE1KB = args.cpurad_its_size // 1024 - - # Handle LOCK and ERASEPROTECT configuration - # Check if both are enabled together - this requires explicit acknowledgment - if ( - args.lock - and args.eraseprotect - and not args.permit_permanently_transitioning_device_to_deployed - ): - raise ScriptError( - "Enabling both --lock and --eraseprotect requires " - "--permit-permanently-transitioning-device-to-deployed to be specified. " - "This combination permanently locks the device configuration and prevents " - "ERASEALL." - ) - - if args.lock: - uicr.LOCK = ENABLED_VALUE - if args.eraseprotect: - uicr.ERASEPROTECT = ENABLED_VALUE - # Handle APPROTECT configuration - if args.approtect_application_protected: - uicr.APPROTECT.APPLICATION = PROTECTED_VALUE - - if args.approtect_radiocore_protected: - uicr.APPROTECT.RADIOCORE = PROTECTED_VALUE - - if args.approtect_coresight_protected: - uicr.APPROTECT.CORESIGHT = PROTECTED_VALUE - # Handle protected memory configuration - if args.protectedmem: - if args.protectedmem_size_bytes % KB_4 != 0: - raise ScriptError( - f"Protected memory size ({args.protectedmem_size_bytes} bytes) " - f"must be divisible by {KB_4}" - ) - uicr.PROTECTEDMEM.ENABLE = ENABLED_VALUE - uicr.PROTECTEDMEM.SIZE4KB = args.protectedmem_size_bytes // KB_4 - - # Handle WDTSTART configuration - if args.wdtstart: - uicr.WDTSTART.ENABLE = ENABLED_VALUE - uicr.WDTSTART.CRV = args.wdtstart_crv - uicr.WDTSTART.INSTANCE = args.wdtstart_instance_code - - # Process periphconf data first and configure UICR completely before creating hex objects - periphconf_hex = IntelHex() - secondary_periphconf_hex = IntelHex() - - if args.out_periphconf_hex: - periphconf_combined = extract_and_combine_periphconfs(args.in_periphconf_elfs) - - padding_len = args.periphconf_size - len(periphconf_combined) - periphconf_final = periphconf_combined + bytes([0xFF for _ in range(padding_len)]) - - # Add periphconf data to periphconf hex object - periphconf_hex.frombytes(periphconf_final, offset=args.periphconf_address) - - # Configure UICR with periphconf settings - uicr.PERIPHCONF.ENABLE = ENABLED_VALUE - uicr.PERIPHCONF.ADDRESS = args.periphconf_address - - # MAXCOUNT is given in number of 8-byte peripheral - # configuration entries and periphconf_size is given in - # bytes. When setting MAXCOUNT based on the - # periphconf_size we must first assert that - # periphconf_size has not been misconfigured. - if args.periphconf_size % 8 != 0: - raise ScriptError( - f"args.periphconf_size was {args.periphconf_size}, but must be divisible by 8" - ) - - uicr.PERIPHCONF.MAXCOUNT = args.periphconf_size // 8 - - # Handle secondary firmware configuration - if args.secondary: - uicr.SECONDARY.ENABLE = ENABLED_VALUE - uicr.SECONDARY.ADDRESS = args.secondary_address - uicr.SECONDARY.PROCESSOR = args.secondary_processor - - # Handle secondary TRIGGER configuration - if args.secondary_trigger: - uicr.SECONDARY.TRIGGER.ENABLE = ENABLED_VALUE - uicr.SECONDARY.TRIGGER.RESETREAS = args.secondary_trigger_resetreas - - # Handle secondary PROTECTEDMEM configuration - if args.secondary_protectedmem_size: - uicr.SECONDARY.PROTECTEDMEM.ENABLE = ENABLED_VALUE - if args.secondary_protectedmem_size % 4096 != 0: - raise ScriptError( - f"args.secondary_protectedmem_size was {args.secondary_protectedmem_size}, " - f"but must be divisible by 4096" - ) - uicr.SECONDARY.PROTECTEDMEM.SIZE4KB = args.secondary_protectedmem_size // 4096 - # Handle secondary periphconf if provided - if args.out_secondary_periphconf_hex: - secondary_periphconf_combined = extract_and_combine_periphconfs( - args.in_secondary_periphconf_elfs - ) - - padding_len = args.secondary_periphconf_size - len(secondary_periphconf_combined) - secondary_periphconf_final = secondary_periphconf_combined + bytes( - [0xFF for _ in range(padding_len)] - ) - - # Add secondary periphconf data to secondary periphconf hex object - secondary_periphconf_hex.frombytes( - secondary_periphconf_final, offset=args.secondary_periphconf_address - ) - - # Configure UICR with secondary periphconf settings - uicr.SECONDARY.PERIPHCONF.ENABLE = ENABLED_VALUE - uicr.SECONDARY.PERIPHCONF.ADDRESS = args.secondary_periphconf_address - - # MAXCOUNT is given in number of 8-byte peripheral - # configuration entries and secondary_periphconf_size is given in - # bytes. When setting MAXCOUNT based on the - # secondary_periphconf_size we must first assert that - # secondary_periphconf_size has not been misconfigured. - if args.secondary_periphconf_size % 8 != 0: - raise ScriptError( - f"args.secondary_periphconf_size was {args.secondary_periphconf_size}, " - f"but must be divisible by 8" - ) - - uicr.SECONDARY.PERIPHCONF.MAXCOUNT = args.secondary_periphconf_size // 8 - - # Handle secondary WDTSTART configuration - if args.secondary_wdtstart: - uicr.SECONDARY.WDTSTART.ENABLE = ENABLED_VALUE - uicr.SECONDARY.WDTSTART.CRV = args.secondary_wdtstart_crv - uicr.SECONDARY.WDTSTART.INSTANCE = args.secondary_wdtstart_instance_code - - # Create UICR hex object with final UICR data - uicr_hex = IntelHex() - uicr_hex.frombytes(bytes(uicr), offset=args.uicr_address) - - # Create merged hex by combining UICR and periphconf hex objects - merged_hex = IntelHex() - merged_hex.fromdict(uicr_hex.todict()) - - if args.out_periphconf_hex: - periphconf_hex.write_hex_file(args.out_periphconf_hex) - merged_hex.fromdict(periphconf_hex.todict()) - - if args.out_secondary_periphconf_hex: - secondary_periphconf_hex.write_hex_file(args.out_secondary_periphconf_hex) - merged_hex.fromdict(secondary_periphconf_hex.todict()) - - merged_hex.write_hex_file(args.out_merged_hex) - uicr_hex.write_hex_file(args.out_uicr_hex) - - except ScriptError as e: - print(f"Error: {e!s}") - sys.exit(1) - - -def extract_and_combine_periphconfs(elf_files: list[argparse.FileType]) -> bytes: - combined_periphconf = [] - ipcmap_index = 0 - - for in_file in elf_files: - elf = ELFFile(in_file) - conf_section = elf.get_section_by_name(PERIPHCONF_SECTION) - if conf_section is None: - continue - - conf_section_data = conf_section.data() - num_entries = len(conf_section_data) // PERIPHCONF_ENTRY_SIZE - periphconf = (PeriphconfEntry * num_entries).from_buffer_copy(conf_section_data) - ipcmap_index = adjust_ipcmap_entries(periphconf, offset_index=ipcmap_index) - combined_periphconf.extend(periphconf) - - combined_periphconf.sort(key=lambda e: e.regptr) - deduplicated_periphconf = [] - - for regptr, regptr_entries in groupby(combined_periphconf, key=lambda e: e.regptr): - entries = list(regptr_entries) - if len(entries) > 1: - unique_values = {e.value for e in entries} - if len(unique_values) > 1: - raise ScriptError( - f"PERIPHCONF has conflicting values for register 0x{regptr:09_x}: " - + ", ".join([f"0x{val:09_x}" for val in unique_values]) - ) - deduplicated_periphconf.append(entries[0]) - - final_periphconf = (PeriphconfEntry * len(deduplicated_periphconf))() - for i, entry in enumerate(deduplicated_periphconf): - final_periphconf[i] = entry - - return bytes(final_periphconf) - - -# This workaround is currently needed to avoid conflicts in IPCMAP whenever more than -# one image uses IPCMAP, because at the moment each image has no way of knowing which -# IPCMAP channel indices it should use for the configuration it generates locally. -# -# What the workaround does is adjust all IPCMAP entries found in the periphconf by the -# given index offset. -# -# The workaround assumes that IPCMAP entries are allocated sequentially starting from 0 -# in each image, it will probably not work for arbitrary IPCMAP entries. -def adjust_ipcmap_entries(periphconf: c.Array[PeriphconfEntry], offset_index: int) -> int: - max_ipcmap_index = offset_index - - for entry in sorted(periphconf, key=lambda e: e.regptr): - if IPCMAP_CHANNEL_START_ADDR <= entry.regptr < IPCMAP_CHANNEL_END_ADDR: - entry.regptr += offset_index * IPCMAP_CHANNEL_SIZE - entry_ipcmap_index = (entry.regptr - IPCMAP_CHANNEL_START_ADDR) // IPCMAP_CHANNEL_SIZE - max_ipcmap_index = max(max_ipcmap_index, entry_ipcmap_index) - - return max_ipcmap_index + 1 - - -# Size of each IPCMAP.CHANNEL[i] -IPCMAP_CHANNEL_SIZE = 8 -# Number of entries in IPCMAP.CHANNEL -IPCMAP_CHANNEL_COUNT = 16 -# Address of IPCMAP.CHANNEL[0] -IPCMAP_CHANNEL_START_ADDR = 0x5F92_3000 + 256 * 4 -# Address of IPCMAP.CHANNEL[channel count] + 1 -IPCMAP_CHANNEL_END_ADDR = IPCMAP_CHANNEL_START_ADDR + IPCMAP_CHANNEL_SIZE * IPCMAP_CHANNEL_COUNT - - -if __name__ == "__main__": - main() diff --git a/soc/nordic/common/uicr/gen_uicr/CMakeLists.txt b/soc/nordic/common/uicr/gen_uicr/CMakeLists.txt index 290cf16a0a6f..9c5111717c6c 100644 --- a/soc/nordic/common/uicr/gen_uicr/CMakeLists.txt +++ b/soc/nordic/common/uicr/gen_uicr/CMakeLists.txt @@ -264,11 +264,13 @@ endif() # Generate hex files (merged, uicr-only, periphconf-only, and secondary-periphconf-only) add_custom_command( OUTPUT ${merged_hex_file} ${uicr_hex_file} ${periphconf_hex_file} ${secondary_periphconf_hex_file} - COMMAND ${CMAKE_COMMAND} -E env PYTHONPATH=${ZEPHYR_BASE}/scripts/dts/python-devicetree/src - ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/soc/nordic/common/uicr/gen_uicr.py + COMMAND ${PYTHON_EXECUTABLE} ${ZEPHYR_HAL_NORDIC_MODULE_DIR}/ironside/se/tool/ironside/__main__.py + gen-uicr --uicr-address ${UICR_ADDRESS} --out-merged-hex ${merged_hex_file} --out-uicr-hex ${uicr_hex_file} + --periphconf-section-name "periphconf_entry" + --periphconf-ipcmap-reallocate ${lock_args} ${eraseprotect_args} ${approtect_args} diff --git a/soc/nordic/common/uicr/uicr.h b/soc/nordic/common/uicr/uicr.h deleted file mode 100644 index 7ceb12429e22..000000000000 --- a/soc/nordic/common/uicr/uicr.h +++ /dev/null @@ -1,308 +0,0 @@ -/* - * Copyright (c) 2025 Nordic Semiconductor ASA - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef SOC_NORDIC_COMMON_UICR_UICR_H_ -#define SOC_NORDIC_COMMON_UICR_UICR_H_ - -#include -#include -#include -#include -#include - -/** Entry in the PERIPHCONF table. */ -struct uicr_periphconf_entry { - /** Register pointer. */ - uint32_t regptr; - /** Register value. */ - uint32_t value; -} __packed; - -/** @brief Add an entry to the PERIPHCONF table section. - * - * This should typically not be used directly. - * Prefer to use one of the higher level macros. - */ -#define UICR_PERIPHCONF_ADD(_regptr, _value) \ - static STRUCT_SECTION_ITERABLE(uicr_periphconf_entry, \ - _UICR_PERIPHCONF_ENTRY_NAME(__COUNTER__)) = { \ - .regptr = (_regptr), \ - .value = (_value), \ - } - -#define _UICR_PERIPHCONF_ENTRY_NAME(_id) __UICR_PERIPHCONF_ENTRY_NAME(_id) -#define __UICR_PERIPHCONF_ENTRY_NAME(_id) _uicr_periphconf_entry_##_id - -/** @brief Add a PERIPHCONF entry for a SPU PERIPH[n].PERM register value. - * - * @param _spu Global domain SPU instance address. - * @param _index Peripheral slave index on the bus (PERIPH[n] register index). - * @param _secattr If true, set SECATTR to secure, otherwise set it to non-secure. - * @param _dmasec If true, set DMASEC to secure, otherwise set it to non-secure. - * @param _ownerid OWNERID field value. - */ -#define UICR_SPU_PERIPH_PERM_SET(_spu, _index, _secattr, _dmasec, _ownerid) \ - UICR_PERIPHCONF_ADD((uint32_t)&((NRF_SPU_Type *)(_spu))->PERIPH[(_index)].PERM, \ - (uint32_t)((((_ownerid) << SPU_PERIPH_PERM_OWNERID_Pos) & \ - SPU_PERIPH_PERM_OWNERID_Msk) | \ - (((_secattr) ? SPU_PERIPH_PERM_SECATTR_Secure \ - : SPU_PERIPH_PERM_SECATTR_NonSecure) \ - << SPU_PERIPH_PERM_SECATTR_Pos) | \ - (((_dmasec) ? SPU_PERIPH_PERM_DMASEC_Secure \ - : SPU_PERIPH_PERM_DMASEC_NonSecure) \ - << SPU_PERIPH_PERM_DMASEC_Pos) | \ - (SPU_PERIPH_PERM_LOCK_Locked << SPU_PERIPH_PERM_LOCK_Pos))) - -/** @brief Add a PERIPHCONF entry for a SPU FEATURE.IPCT.CH[n] register value. - * - * @param _spu Global domain SPU instance address. - * @param _index Feature index. - * @param _secattr If true, set SECATTR to secure, otherwise set it to non-secure. - * @param _ownerid OWNERID field value. - */ -#define UICR_SPU_FEATURE_IPCT_CH_SET(_spu, _index, _secattr, _ownerid) \ - UICR_PERIPHCONF_ADD((uint32_t)&((NRF_SPU_Type *)(_spu))->FEATURE.IPCT.CH[_index], \ - _UICR_SPU_FEATURE_VAL(_secattr, _ownerid)) - -/** @brief Add a PERIPHCONF entry for a SPU FEATURE.IPCT.INTERRUPT[n] register value. - * - * @param _spu Global domain SPU instance address. - * @param _index Feature index. - * @param _secattr If true, set SECATTR to secure, otherwise set it to non-secure. - * @param _ownerid OWNERID field value. - */ -#define UICR_SPU_FEATURE_IPCT_INTERRUPT_SET(_spu, _index, _secattr, _ownerid) \ - UICR_PERIPHCONF_ADD((uint32_t)&((NRF_SPU_Type *)(_spu))->FEATURE.IPCT.INTERRUPT[_index], \ - _UICR_SPU_FEATURE_VAL(_secattr, _ownerid)) - -/** @brief Add a PERIPHCONF entry for a SPU FEATURE.DPPIC.CH[n] register value. - * - * @param _spu Global domain SPU instance address. - * @param _index Feature index. - * @param _secattr If true, set SECATTR to secure, otherwise set it to non-secure. - * @param _ownerid OWNERID field value. - */ -#define UICR_SPU_FEATURE_DPPIC_CH_SET(_spu, _index, _secattr, _ownerid) \ - UICR_PERIPHCONF_ADD((uint32_t)&((NRF_SPU_Type *)(_spu))->FEATURE.DPPIC.CH[_index], \ - _UICR_SPU_FEATURE_VAL(_secattr, _ownerid)) - -/** @brief Add a PERIPHCONF entry for a SPU FEATURE.DPPIC.CHG[n] register value. - * - * @param _spu Global domain SPU instance address. - * @param _index Register index. - * @param _secattr If true, set SECATTR to secure, otherwise set it to non-secure. - * @param _ownerid OWNERID field value. - */ -#define UICR_SPU_FEATURE_DPPIC_CHG_SET(_spu, _index, _secattr, _ownerid) \ - UICR_PERIPHCONF_ADD((uint32_t)&((NRF_SPU_Type *)(_spu))->FEATURE.DPPIC.CHG[_index], \ - _UICR_SPU_FEATURE_VAL(_secattr, _ownerid)) - -/** @brief Add a PERIPHCONF entry for a SPU FEATURE.GPIOTE[n].CH[m] register value. - * - * @param _spu Global domain SPU instance address. - * @param _index Feature index (GPIOTE[n] register index). - * @param _subindex Feature subindex (CH[m] register index). - * @param _secattr If true, set the SECATTR to secure, otherwise set it to non-secure. - * @param _ownerid OWNERID field value. - */ -#define UICR_SPU_FEATURE_GPIOTE_CH_SET(_spu, _index, _subindex, _secattr, _ownerid) \ - UICR_PERIPHCONF_ADD( \ - (uint32_t)&((NRF_SPU_Type *)(_spu))->FEATURE.GPIOTE[_index].CH[_subindex], \ - _UICR_SPU_FEATURE_VAL(_secattr, _ownerid)) - -/** @brief Add a PERIPHCONF entry for a SPU FEATURE.GPIOTE.INTERRUPT[n] register value. - * - * @param _spu Global domain SPU instance address. - * @param _index Feature index. - * @param _subindex Feature subindex. - * @param _secattr If true, set SECATTR to secure, otherwise set it to non-secure. - * @param _ownerid OWNERID field value. - */ -#define UICR_SPU_FEATURE_GPIOTE_INTERRUPT_SET(_spu, _index, _subindex, _secattr, _ownerid) \ - UICR_PERIPHCONF_ADD( \ - (uint32_t)&((NRF_SPU_Type *)(_spu))->FEATURE.GPIOTE[_index].INTERRUPT[_subindex], \ - _UICR_SPU_FEATURE_VAL(_secattr, _ownerid)) - -/** @brief Add a PERIPHCONF entry for a SPU FEATURE.GPIO[n].PIN[m] register value. - * - * @param _spu Global domain SPU instance address. - * @param _index Feature index. - * @param _subindex Feature subindex. - * @param _secattr If true, set SECATTR to secure, otherwise set it to non-secure. - * @param _ownerid OWNERID field value. - */ -#define UICR_SPU_FEATURE_GPIO_PIN_SET(_spu, _index, _subindex, _secattr, _ownerid) \ - UICR_PERIPHCONF_ADD( \ - (uint32_t)&((NRF_SPU_Type *)(_spu))->FEATURE.GPIO[_index].PIN[_subindex], \ - _UICR_SPU_FEATURE_VAL(_secattr, _ownerid)) - -/** @brief Add a PERIPHCONF entry for a SPU FEATURE.GRTC.CC[n] register value. - * - * @param _spu Global domain SPU instance address. - * @param _index Feature index. - * @param _secattr If true, set SECATTR to secure, otherwise set it to non-secure. - * @param _ownerid OWNERID field value. - */ -#define UICR_SPU_FEATURE_GRTC_CC_SET(_spu, _index, _secattr, _ownerid) \ - UICR_PERIPHCONF_ADD((uint32_t)&((NRF_SPU_Type *)(_spu))->FEATURE.GRTC.CC[_index], \ - _UICR_SPU_FEATURE_VAL(_secattr, _ownerid)) - -/* Common macro for encoding a SPU FEATURE.* register value. - * Note that the MDK SPU_FEATURE_IPCT_CH_ macros are used for all since all the FEATURE registers - * have the same layout with different naming. - */ -#define _UICR_SPU_FEATURE_VAL(_secattr, _ownerid) \ - (uint32_t)((((_ownerid) << SPU_FEATURE_IPCT_CH_OWNERID_Pos) & \ - SPU_FEATURE_IPCT_CH_OWNERID_Msk) | \ - (((_secattr) ? SPU_FEATURE_IPCT_CH_SECATTR_Secure \ - : SPU_FEATURE_IPCT_CH_SECATTR_NonSecure) \ - << SPU_FEATURE_IPCT_CH_SECATTR_Pos) | \ - (SPU_FEATURE_IPCT_CH_LOCK_Locked << SPU_FEATURE_IPCT_CH_LOCK_Pos)) - -/** @brief Add PERIPHCONF entries for configuring IPCMAP CHANNEL.SOURCE[n] and CHANNEL.SINK[n]. - * - * @param _index CHANNEL.SOURCE[n]/CHANNEL.SINK[n] register index. - * @param _source_domain DOMAIN field value in CHANNEL[n].SOURCE. - * @param _source_ch SOURCE field value in CHANNEL[n].SOURCE. - * @param _sink_domain DOMAIN field value in CHANNEL[n].SINK. - * @param _sink_ch SINK field value in CHANNEL[n].SINK. - */ -#define UICR_IPCMAP_CHANNEL_CFG(_index, _source_domain, _source_ch, _sink_domain, _sink_ch) \ - UICR_IPCMAP_CHANNEL_SOURCE_SET(_index, _source_domain, _source_ch, 1); \ - UICR_IPCMAP_CHANNEL_SINK_SET(_index, _sink_domain, _sink_ch) - -#define UICR_IPCMAP_CHANNEL_SOURCE_SET(_index, _domain, _ch, _enable) \ - UICR_PERIPHCONF_ADD((uint32_t)&NRF_IPCMAP->CHANNEL[(_index)].SOURCE, \ - (uint32_t)((((_domain) << IPCMAP_CHANNEL_SOURCE_DOMAIN_Pos) & \ - IPCMAP_CHANNEL_SOURCE_DOMAIN_Msk) | \ - (((_ch) << IPCMAP_CHANNEL_SOURCE_SOURCE_Pos) & \ - IPCMAP_CHANNEL_SOURCE_SOURCE_Msk) | \ - (((_enable) ? IPCMAP_CHANNEL_SOURCE_ENABLE_Enabled \ - : IPCMAP_CHANNEL_SOURCE_ENABLE_Disabled) \ - << IPCMAP_CHANNEL_SOURCE_ENABLE_Pos))) - -#define UICR_IPCMAP_CHANNEL_SINK_SET(_index, _domain, _ch) \ - UICR_PERIPHCONF_ADD((uint32_t)&NRF_IPCMAP->CHANNEL[(_index)].SINK, \ - (uint32_t)((((_domain) << IPCMAP_CHANNEL_SINK_DOMAIN_Pos) & \ - IPCMAP_CHANNEL_SINK_DOMAIN_Msk) | \ - (((_ch) << IPCMAP_CHANNEL_SINK_SINK_Pos) & \ - IPCMAP_CHANNEL_SINK_SINK_Msk))) - -/** @brief Add a PERIPHCONF entry for an IRQMAP IRQ[n].SINK register value. - * - * @param _irqnum IRQ number (IRQ[n] register index). - * @param _processor Processor to route the interrupt to (PROCESSORID field value). - */ -#define UICR_IRQMAP_IRQ_SINK_SET(_irqnum, _processor) \ - UICR_PERIPHCONF_ADD((uint32_t)&NRF_IRQMAP->IRQ[(_irqnum)].SINK, \ - (uint32_t)(((_processor) << IRQMAP_IRQ_SINK_PROCESSORID_Pos) & \ - IRQMAP_IRQ_SINK_PROCESSORID_Msk)) - -/** @brief Add a PERIPHCONF entry for configuring a GPIO PIN_CNF[n] CTRLSEL field value. - * - * @param _gpio GPIO instance address. - * @param _pin Pin number (PIN_CNF[n] register index). - * @param _ctrlsel CTRLSEL field value. - */ -#define UICR_GPIO_PIN_CNF_CTRLSEL_SET(_gpio, _pin, _ctrlsel) \ - UICR_PERIPHCONF_ADD( \ - (uint32_t)&((NRF_GPIO_Type *)(_gpio))->PIN_CNF[(_pin)], \ - ((GPIO_PIN_CNF_ResetValue) | \ - (uint32_t)(((_ctrlsel) << GPIO_PIN_CNF_CTRLSEL_Pos) & GPIO_PIN_CNF_CTRLSEL_Msk))) - -/** @brief Add a PERIPHCONF entry for a PPIB SUBSCRIBE_SEND[n] register. - * - * @param _ppib Global domain PPIB instance address. - * @param _ppib_ch PPIB channel number. - */ -#define UICR_PPIB_SUBSCRIBE_SEND_ENABLE(_ppib, _ppib_ch) \ - UICR_PERIPHCONF_ADD((uint32_t)&((NRF_PPIB_Type *)(_ppib))->SUBSCRIBE_SEND[(_ppib_ch)], \ - (uint32_t)PPIB_SUBSCRIBE_SEND_EN_Msk) - -/** @brief Add a PERIPHCONF entry for a PPIB PUBLISH_RECEIVE[n] register. - * - * @param _ppib Global domain PPIB instance address. - * @param _ppib_ch PPIB channel number. - */ -#define UICR_PPIB_PUBLISH_RECEIVE_ENABLE(_ppib, _ppib_ch) \ - UICR_PERIPHCONF_ADD((uint32_t)&((NRF_PPIB_Type *)(_ppib))->PUBLISH_RECEIVE[(_ppib_ch)], \ - (uint32_t)PPIB_PUBLISH_RECEIVE_EN_Msk) - -/* The definitions below are not currently available in the MDK but are needed for the macros - * above. When they are, this can be deleted. - */ -#ifndef IPCMAP_CHANNEL_SOURCE_SOURCE_Msk - -typedef struct { - __IOM uint32_t SOURCE; - __IOM uint32_t SINK; -} NRF_IPCMAP_CHANNEL_Type; - -#define IPCMAP_CHANNEL_SOURCE_SOURCE_Pos (0UL) -#define IPCMAP_CHANNEL_SOURCE_SOURCE_Msk (0xFUL << IPCMAP_CHANNEL_SOURCE_SOURCE_Pos) -#define IPCMAP_CHANNEL_SOURCE_DOMAIN_Pos (8UL) -#define IPCMAP_CHANNEL_SOURCE_DOMAIN_Msk (0xFUL << IPCMAP_CHANNEL_SOURCE_DOMAIN_Pos) -#define IPCMAP_CHANNEL_SOURCE_ENABLE_Pos (31UL) -#define IPCMAP_CHANNEL_SOURCE_ENABLE_Disabled (0x0UL) -#define IPCMAP_CHANNEL_SOURCE_ENABLE_Enabled (0x1UL) -#define IPCMAP_CHANNEL_SINK_SINK_Pos (0UL) -#define IPCMAP_CHANNEL_SINK_SINK_Msk (0xFUL << IPCMAP_CHANNEL_SINK_SINK_Pos) -#define IPCMAP_CHANNEL_SINK_DOMAIN_Pos (8UL) -#define IPCMAP_CHANNEL_SINK_DOMAIN_Msk (0xFUL << IPCMAP_CHANNEL_SINK_DOMAIN_Pos) - -typedef struct { - __IM uint32_t RESERVED[256]; - __IOM NRF_IPCMAP_CHANNEL_Type CHANNEL[16]; -} NRF_IPCMAP_Type; - -#endif /* IPCMAP_CHANNEL_SOURCE_SOURCE_Msk */ - -#ifndef NRF_IPCMAP -#define NRF_IPCMAP ((NRF_IPCMAP_Type *)0x5F923000UL) -#endif - -#ifndef IRQMAP_IRQ_SINK_PROCESSORID_Msk - -typedef struct { - __IOM uint32_t SINK; -} NRF_IRQMAP_IRQ_Type; - -#define IRQMAP_IRQ_SINK_PROCESSORID_Pos (8UL) -#define IRQMAP_IRQ_SINK_PROCESSORID_Msk (0xFUL << IRQMAP_IRQ_SINK_PROCESSORID_Pos) - -typedef struct { - __IM uint32_t RESERVED[256]; - __IOM NRF_IRQMAP_IRQ_Type IRQ[480]; -} NRF_IRQMAP_Type; - -#endif /* IRQMAP_IRQ_SINK_PROCESSORID_Msk */ - -#ifndef NRF_IRQMAP -#define NRF_IRQMAP ((NRF_IRQMAP_Type *)0x5F924000UL) -#endif /* NRF_IRQMAP */ - -#ifndef GPIO_PIN_CNF_CTRLSEL_Pos - -#define GPIO_PIN_CNF_CTRLSEL_Pos (28UL) -#define GPIO_PIN_CNF_CTRLSEL_Msk (0x7UL << GPIO_PIN_CNF_CTRLSEL_Pos) -#define GPIO_PIN_CNF_CTRLSEL_Min (0x0UL) -#define GPIO_PIN_CNF_CTRLSEL_Max (0x7UL) -#define GPIO_PIN_CNF_CTRLSEL_GPIO (0x0UL) -#define GPIO_PIN_CNF_CTRLSEL_VPR (0x1UL) -#define GPIO_PIN_CNF_CTRLSEL_GRC (0x1UL) -#define GPIO_PIN_CNF_CTRLSEL_SecureDomain (0x2UL) -#define GPIO_PIN_CNF_CTRLSEL_PWM (0x2UL) -#define GPIO_PIN_CNF_CTRLSEL_I3C (0x2UL) -#define GPIO_PIN_CNF_CTRLSEL_Serial (0x3UL) -#define GPIO_PIN_CNF_CTRLSEL_HSSPI (0x3UL) -#define GPIO_PIN_CNF_CTRLSEL_RadioCore (0x4UL) -#define GPIO_PIN_CNF_CTRLSEL_EXMIF (0x4UL) -#define GPIO_PIN_CNF_CTRLSEL_CELL (0x4UL) -#define GPIO_PIN_CNF_CTRLSEL_DTB (0x6UL) -#define GPIO_PIN_CNF_CTRLSEL_TND (0x7UL) - -#endif /* GPIO_PIN_CNF_CTRLSEL_Pos */ - -#endif /* SOC_NORDIC_COMMON_UICR_UICR_H_ */ diff --git a/soc/nordic/ironside/CMakeLists.txt b/soc/nordic/ironside/CMakeLists.txt deleted file mode 100644 index f1ae2114f2ec..000000000000 --- a/soc/nordic/ironside/CMakeLists.txt +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright (c) 2025 Nordic Semiconductor ASA -# SPDX-License-Identifier: Apache-2.0 - -zephyr_include_directories(include) -zephyr_library() -zephyr_library_sources_ifdef(CONFIG_NRF_IRONSIDE_CALL call.c) -zephyr_library_sources_ifdef(CONFIG_NRF_IRONSIDE_BOOT_REPORT boot_report.c) -zephyr_library_sources_ifdef(CONFIG_NRF_IRONSIDE_CPUCONF_SERVICE cpuconf.c) -zephyr_library_sources_ifdef(CONFIG_NRF_IRONSIDE_BOOTMODE_SERVICE bootmode.c) -zephyr_library_sources_ifdef(CONFIG_NRF_IRONSIDE_TDD_SERVICE tdd.c) -zephyr_library_sources_ifdef(CONFIG_NRF_IRONSIDE_UPDATE_SERVICE update.c) -zephyr_library_sources_ifdef(CONFIG_NRF_IRONSIDE_DVFS_SERVICE dvfs.c) -zephyr_library_sources_ifdef(CONFIG_NRF_IRONSIDE_COUNTER_SERVICE counter.c) diff --git a/soc/nordic/ironside/Kconfig b/soc/nordic/ironside/Kconfig deleted file mode 100644 index 7498af71d909..000000000000 --- a/soc/nordic/ironside/Kconfig +++ /dev/null @@ -1,89 +0,0 @@ -# Copyright (c) 2025 Nordic Semiconductor ASA -# SPDX-License-Identifier: Apache-2.0 - -config NRF_IRONSIDE - bool - depends on SOC_NRF54H20 || SOC_NRF9280 - help - This is selected by drivers interacting with Nordic IronSide firmware. - -config NRF_IRONSIDE_CALL - bool - depends on DT_HAS_NORDIC_IRONSIDE_CALL_ENABLED - select NRF_IRONSIDE - select EVENTS - select MBOX - help - This is selected by features that require support for IronSide calls. - -if NRF_IRONSIDE_CALL - -config NRF_IRONSIDE_CALL_INIT_PRIORITY - int "IronSide calls' initialization priority" - default 41 - help - Initialization priority of IronSide calls. It must be below MBOX_INIT_PRIORITY, - but higher than the priority of any feature that selects NRF_IRONSIDE_CALL. - -endif # NRF_IRONSIDE_CALL - -menu "Nordic IronSide services" - depends on SOC_NRF54H20 || SOC_NRF9280 - -config NRF_IRONSIDE_CPUCONF_SERVICE - bool "IronSide CPUCONF service" - depends on SOC_NRF54H20_CPUAPP || SOC_NRF9280_CPUAPP - select NRF_IRONSIDE_CALL - help - Service used to boot local domain cores. - -config NRF_IRONSIDE_TDD_SERVICE - bool "IronSide TDD service" - select NRF_IRONSIDE_CALL - help - Service used to control the trace and debug domain. - -config NRF_IRONSIDE_UPDATE_SERVICE - bool "IronSide update service" - select NRF_IRONSIDE_CALL - help - Service used to update the IronSide SE firmware. - -config NRF_IRONSIDE_BOOT_REPORT - bool "IronSide boot report" - depends on $(dt_nodelabel_exists,ironside_se_boot_report) - select NRF_IRONSIDE - help - Support for parsing the Boot Report populated by Nordic IronSide firmware. - -config NRF_IRONSIDE_BOOTMODE_SERVICE - bool "IronSide boot mode service" - select NRF_IRONSIDE_CALL - help - Service used to reboot into secondary firmware boot mode. - -config NRF_IRONSIDE_DVFS_SERVICE - bool "IronSide DVFS service" - depends on SOC_NRF54H20_CPUAPP - select NRF_IRONSIDE_CALL - help - Service used to handle DVFS operating point requests. - -config NRF_IRONSIDE_COUNTER_SERVICE - bool "IronSide counter service" - select NRF_IRONSIDE_CALL - help - Service used to manage secure monotonic counters. - -if NRF_IRONSIDE_DVFS_SERVICE - -config NRF_IRONSIDE_ABB_STATUSANA_CHECK_MAX_ATTEMPTS - int "IRONSside DVFS ABB analog status check maximum attempts" - range 0 255 - default 50 - help - Maximum attempts with 10us intervals before busy status will be reported. - -endif # NRF_IRONSIDE_DVFS_SERVICE - -endmenu diff --git a/soc/nordic/ironside/boot_report.c b/soc/nordic/ironside/boot_report.c deleted file mode 100644 index ead0afca947f..000000000000 --- a/soc/nordic/ironside/boot_report.c +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (c) 2025 Nordic Semiconductor ASA - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include - -#define IRONSIDE_SE_BOOT_REPORT_ADDR DT_REG_ADDR(DT_NODELABEL(ironside_se_boot_report)) - -int ironside_boot_report_get(const struct ironside_boot_report **report) -{ - const struct ironside_boot_report *tmp_report = (void *)IRONSIDE_SE_BOOT_REPORT_ADDR; - - if (tmp_report->magic != IRONSIDE_BOOT_REPORT_MAGIC) { - return -EINVAL; - } - - *report = tmp_report; - - return 0; -} diff --git a/soc/nordic/ironside/bootmode.c b/soc/nordic/ironside/bootmode.c deleted file mode 100644 index 92ca5e312653..000000000000 --- a/soc/nordic/ironside/bootmode.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2025 Nordic Semiconductor ASA - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -#include -#include -#include - -#define BOOT_MODE_SECONDARY (0x1) - -BUILD_ASSERT(IRONSIDE_BOOTMODE_SERVICE_NUM_ARGS <= NRF_IRONSIDE_CALL_NUM_ARGS); - -int ironside_bootmode_secondary_reboot(const uint8_t *msg, size_t msg_size) -{ - int err; - struct ironside_call_buf *buf; - uint8_t *buf_msg; - - if (msg_size > IRONSIDE_BOOTMODE_SERVICE_MSG_MAX_SIZE) { - return -IRONSIDE_BOOTMODE_ERROR_MESSAGE_TOO_LARGE; - } - - buf = ironside_call_alloc(); - - buf->id = IRONSIDE_CALL_ID_BOOTMODE_SERVICE_V1; - - buf->args[IRONSIDE_BOOTMODE_SERVICE_MODE_IDX] = BOOT_MODE_SECONDARY; - - buf_msg = (uint8_t *)&buf->args[IRONSIDE_BOOTMODE_SERVICE_MSG_0_IDX]; - - memset(buf_msg, 0, IRONSIDE_BOOTMODE_SERVICE_MSG_MAX_SIZE); - - if (msg_size > 0) { - memcpy(buf_msg, msg, msg_size); - } - - ironside_call_dispatch(buf); - - if (buf->status == IRONSIDE_CALL_STATUS_RSP_SUCCESS) { - err = buf->args[IRONSIDE_BOOTMODE_SERVICE_RETCODE_IDX]; - } else { - err = buf->status; - } - - ironside_call_release(buf); - - return err; -} diff --git a/soc/nordic/ironside/counter.c b/soc/nordic/ironside/counter.c deleted file mode 100644 index b4506621851d..000000000000 --- a/soc/nordic/ironside/counter.c +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2025 Nordic Semiconductor ASA - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include - -int ironside_counter_set(enum ironside_counter counter_id, uint32_t value) -{ - int err; - struct ironside_call_buf *const buf = ironside_call_alloc(); - - buf->id = IRONSIDE_CALL_ID_COUNTER_SET_V1; - buf->args[IRONSIDE_COUNTER_SET_SERVICE_COUNTER_ID_IDX] = (uint32_t)counter_id; - buf->args[IRONSIDE_COUNTER_SET_SERVICE_VALUE_IDX] = value; - - ironside_call_dispatch(buf); - - if (buf->status == IRONSIDE_CALL_STATUS_RSP_SUCCESS) { - err = buf->args[IRONSIDE_COUNTER_SET_SERVICE_RETCODE_IDX]; - } else { - err = buf->status; - } - - ironside_call_release(buf); - - return err; -} - -int ironside_counter_get(enum ironside_counter counter_id, uint32_t *value) -{ - int err; - struct ironside_call_buf *buf; - - if (value == NULL) { - return -IRONSIDE_COUNTER_ERROR_INVALID_PARAM; - } - - buf = ironside_call_alloc(); - - buf->id = IRONSIDE_CALL_ID_COUNTER_GET_V1; - buf->args[IRONSIDE_COUNTER_GET_SERVICE_COUNTER_ID_IDX] = (uint32_t)counter_id; - - ironside_call_dispatch(buf); - - if (buf->status == IRONSIDE_CALL_STATUS_RSP_SUCCESS) { - err = buf->args[IRONSIDE_COUNTER_GET_SERVICE_RETCODE_IDX]; - if (err == 0) { - *value = buf->args[IRONSIDE_COUNTER_GET_SERVICE_VALUE_IDX]; - } - } else { - err = buf->status; - } - - ironside_call_release(buf); - - return err; -} - -int ironside_counter_lock(enum ironside_counter counter_id) -{ - int err; - struct ironside_call_buf *const buf = ironside_call_alloc(); - - buf->id = IRONSIDE_CALL_ID_COUNTER_LOCK_V1; - buf->args[IRONSIDE_COUNTER_LOCK_SERVICE_COUNTER_ID_IDX] = (uint32_t)counter_id; - - ironside_call_dispatch(buf); - - if (buf->status == IRONSIDE_CALL_STATUS_RSP_SUCCESS) { - err = buf->args[IRONSIDE_COUNTER_LOCK_SERVICE_RETCODE_IDX]; - } else { - err = buf->status; - } - - ironside_call_release(buf); - - return err; -} diff --git a/soc/nordic/ironside/cpuconf.c b/soc/nordic/ironside/cpuconf.c deleted file mode 100644 index 264772a09e25..000000000000 --- a/soc/nordic/ironside/cpuconf.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2025 Nordic Semiconductor ASA - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include - -#include -#include - -#include -#include - -#define CPU_PARAMS_CPU_OFFSET (0) -#define CPU_PARAMS_CPU_MASK (0xF) -#define CPU_PARAMS_WAIT_BIT BIT(4) - -int ironside_cpuconf(NRF_PROCESSORID_Type cpu, const void *vector_table, bool cpu_wait, - const uint8_t *msg, size_t msg_size) -{ - int err; - struct ironside_call_buf *buf; - uint8_t *buf_msg; - - if (msg_size > IRONSIDE_CPUCONF_SERVICE_MSG_MAX_SIZE) { - return -IRONSIDE_CPUCONF_ERROR_MESSAGE_TOO_LARGE; - } - - buf = ironside_call_alloc(); - - buf->id = IRONSIDE_CALL_ID_CPUCONF_V0; - - buf->args[IRONSIDE_CPUCONF_SERVICE_CPU_PARAMS_IDX] = - (((uint32_t)cpu << CPU_PARAMS_CPU_OFFSET) & CPU_PARAMS_CPU_MASK) | - (cpu_wait ? CPU_PARAMS_WAIT_BIT : 0); - - buf->args[IRONSIDE_CPUCONF_SERVICE_VECTOR_TABLE_IDX] = (uint32_t)vector_table; - - buf_msg = (uint8_t *)&buf->args[IRONSIDE_CPUCONF_SERVICE_MSG_0]; - if (msg_size > 0) { - memcpy(buf_msg, msg, msg_size); - } - if (msg_size < IRONSIDE_CPUCONF_SERVICE_MSG_MAX_SIZE) { - memset(&buf_msg[msg_size], 0, IRONSIDE_CPUCONF_SERVICE_MSG_MAX_SIZE - msg_size); - } - - ironside_call_dispatch(buf); - - if (buf->status == IRONSIDE_CALL_STATUS_RSP_SUCCESS) { - err = buf->args[IRONSIDE_CPUCONF_SERVICE_RETCODE_IDX]; - } else { - err = buf->status; - } - - ironside_call_release(buf); - - return err; -} diff --git a/soc/nordic/ironside/include/nrf_ironside/boot_report.h b/soc/nordic/ironside/include/nrf_ironside/boot_report.h deleted file mode 100644 index 8c602c00134c..000000000000 --- a/soc/nordic/ironside/include/nrf_ironside/boot_report.h +++ /dev/null @@ -1,229 +0,0 @@ -/* - * Copyright (c) 2025 Nordic Semiconductor ASA - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef ZEPHYR_SOC_NORDIC_IRONSIDE_INCLUDE_NRF_IRONSIDE_BOOT_REPORT_H_ -#define ZEPHYR_SOC_NORDIC_IRONSIDE_INCLUDE_NRF_IRONSIDE_BOOT_REPORT_H_ - -#include -#include - -/** Constant used to check if an Nordic IronSide SE boot report has been written. */ -#define IRONSIDE_BOOT_REPORT_MAGIC (0x4d69546fUL) - -/** UICR had no errors. */ -#define IRONSIDE_UICR_SUCCESS 0 -/** There was an unexpected error processing the UICR. */ -#define IRONSIDE_UICR_ERROR_UNEXPECTED 1 -/** The UICR integrity check failed. */ -#define IRONSIDE_UICR_ERROR_INTEGRITY 2 -/** The UICR content check failed. */ -#define IRONSIDE_UICR_ERROR_CONTENT 3 -/** Failed to configure system based on UICR. */ -#define IRONSIDE_UICR_ERROR_CONFIG 4 -/** Unsupported UICR format version. */ -#define IRONSIDE_UICR_ERROR_FORMAT 5 - -/** Error found in UICR.PROTECTEDMEM. */ -#define IRONSIDE_UICR_REGID_PROTECTEDMEM 36 -/** Error found in UICR.SECURESTORAGE. */ -#define IRONSIDE_UICR_REGID_SECURESTORAGE 64 -/** Error found in UICR.PERIPHCONF. */ -#define IRONSIDE_UICR_REGID_PERIPHCONF 104 -/** Error found in UICR.MPCCONF. */ -#define IRONSIDE_UICR_REGID_MPCCONF 116 -/** Error found in UICR.SECONDARY.ADDRESS/SIZE4KB */ -#define IRONSIDE_UICR_REGID_SECONDARY 128 -/** Error found in UICR.SECONDARY.PROTECTEDMEM. */ -#define IRONSIDE_UICR_REGID_SECONDARY_PROTECTEDMEM 152 -/** Error found in UICR.SECONDARY.PERIPHCONF. */ -#define IRONSIDE_UICR_REGID_SECONDARY_PERIPHCONF 172 -/** Error found in UICR.SECONDARY.MPCCONF. */ -#define IRONSIDE_UICR_REGID_SECONDARY_MPCCONF 184 - -/** Failed to mount a CRYPTO secure storage partition in MRAM. */ -#define IRONSIDE_UICR_SECURESTORAGE_ERROR_MOUNT_CRYPTO_FAILED 1 -/** Failed to mount an ITS secure storage partition in MRAM. */ -#define IRONSIDE_UICR_SECURESTORAGE_ERROR_MOUNT_ITS_FAILED 2 -/** The start address and total size of all ITS partitions are not aligned to 4 KB. */ -#define IRONSIDE_UICR_SECURESTORAGE_ERROR_MISALIGNED 3 - -/** There was an unexpected error processing UICR.PERIPHCONF. */ -#define IRONSIDE_UICR_PERIPHCONF_ERROR_UNEXPECTED 1 -/** The address contained in a UICR.PERIPHCONF array entry is not permitted. */ -#define IRONSIDE_UICR_PERIPHCONF_ERROR_NOT_PERMITTED 2 -/** The readback of the value for a UICR.PERIPHCONF array entry did not match. */ -#define IRONSIDE_UICR_PERIPHCONF_ERROR_READBACK_MISMATCH 3 - -/** Booted in secondary mode. */ -#define IRONSIDE_BOOT_MODE_FLAGS_SECONDARY_MASK 0x1 - -/** Booted normally by IronSide SE.*/ -#define IRONSIDE_BOOT_REASON_DEFAULT 0 -/** Booted because of a cpuconf service call by a different core. */ -#define IRONSIDE_BOOT_REASON_CPUCONF_CALL 1 -/** Booted in secondary mode because of a bootmode service call. */ -#define IRONSIDE_BOOT_REASON_BOOTMODE_SECONDARY_CALL 2 -/** Booted in secondary mode because of a boot error in the primary mode. */ -#define IRONSIDE_BOOT_REASON_BOOTERROR 3 -/** Booted in secondary mode because of local domain reset reason trigger. */ -#define IRONSIDE_BOOT_REASON_TRIGGER_RESETREAS 4 -/** Booted in secondary mode via the CTRL-AP. */ -#define IRONSIDE_BOOT_REASON_CTRLAP_SECONDARYMODE 5 - -/** The boot had no errors. */ -#define IRONSIDE_BOOT_ERROR_SUCCESS 0x0 -/** The reset vector for the application firmware was not programmed. */ -#define IRONSIDE_BOOT_ERROR_NO_APPLICATION_FIRMWARE 0x1 -/** The IronSide SE was unable to parse the SysCtrl ROM report. */ -#define IRONSIDE_BOOT_ERROR_ROM_REPORT_INVALID 0x2 -/** The SysCtrl ROM booted the system in current limited mode due to an issue in the BICR. */ -#define IRONSIDE_BOOT_ERROR_ROM_REPORT_CURRENT_LIMITED 0x3 -/** The IronSide SE detected an issue with the HFXO configuration in the BICR. */ -#define IRONSIDE_BOOT_ERROR_BICR_HFXO_INVALID 0x4 -/** The IronSide SE detected an issue with the LFXO configuration in the BICR. */ -#define IRONSIDE_BOOT_ERROR_BICR_LFXO_INVALID 0x5 -/** The IronSide SE failed to boot the SysCtrl Firmware. */ -#define IRONSIDE_BOOT_ERROR_SYSCTRL_START_FAILED 0x6 -/** The UICR integrity check failed. */ -#define IRONSIDE_BOOT_ERROR_UICR_INTEGRITY_FAILED 0x7 -/** The UICR content is not valid */ -#define IRONSIDE_BOOT_ERROR_UICR_CONTENT_INVALID 0x8 -/** Integrity check of PROTECTEDMEM failed. */ -#define IRONSIDE_BOOT_ERROR_UICR_PROTECTEDMEM_INTEGRITY_FAILED 0x9 -/** Failed to configure system based on UICR. */ -#define IRONSIDE_BOOT_ERROR_UICR_CONFIG_FAILED 0xA -/** The IronSide SE failed to mount its own storage. */ -#define IRONSIDE_BOOT_ERROR_SECDOM_STORAGE_MOUNT_FAILED 0xB -/** Failed to initialize DVFS service */ -#define IRONSIDE_BOOT_ERROR_DVFS_INIT_FAILED 0xC -/** Failed to boot secondary application firmware; configuration missing from UICR. */ -#define IRONSIDE_BOOT_ERROR_NO_SECONDARY_APPLICATION_FIRMWARE 0xD -/** Integrity check of secondary PROTECTEDMEM failed. */ -#define IRONSIDE_BOOT_ERROR_UICR_SECONDARY_PROTECTEDMEM_INTEGRITY_FAILED 0xE -/** Unsupported UICR format version. */ -#define IRONSIDE_BOOT_ERROR_UICR_FORMAT_UNSUPPORTED 0xF -/** Value reserved for conditions that should never happen. */ -#define IRONSIDE_BOOT_ERROR_UNEXPECTED 0xff - -/** Index for RESETREAS.DOMAIN[NRF_DOMAIN_APPLICATION]. */ -#define IRONSIDE_SECONDARY_RESETREAS_APPLICATION 0 -/** Index for RESETREAS.DOMAIN[NRF_DOMAIN_RADIOCORE]. */ -#define IRONSIDE_SECONDARY_RESETREAS_RADIOCORE 1 - -/** Length of the local domain context buffer in bytes. */ -#define IRONSIDE_BOOT_REPORT_LOCAL_DOMAIN_CONTEXT_SIZE (16UL) -/** Length of the random data buffer in bytes. */ -#define IRONSIDE_BOOT_REPORT_RANDOM_DATA_SIZE (32UL) -/** Length of the uuid buffer in bytes. */ -#define IRONSIDE_BOOT_REPORT_UUID_SIZE (16UL) - -/** @brief Initialization/boot status description contained in the boot report. */ -struct ironside_boot_report_init_status { - /** Reserved for Future Use. */ - uint8_t rfu1[3]; - /** Boot error for the current boot (same as reported in BOOTSTATUS)*/ - uint8_t boot_error; - /** Overall UICR status. */ - uint8_t uicr_status; - /** Reserved for Future Use. */ - uint8_t rfu2; - /** ID of the register that caused the error. - * Only relevant for IRONSIDE_UICR_ERROR_CONTENT and IRONSIDE_UICR_ERROR_CONFIG. - */ - uint16_t uicr_regid; - /** Additional description for IRONSIDE_UICR_ERROR_CONFIG. */ - union { - /** UICR.SECURESTORAGE error description. */ - struct { - /** Reason that UICR.SECURESTORAGE configuration failed. */ - uint16_t status; - /** Owner ID of the failing secure storage partition. - * Only relevant for IRONSIDE_UICR_SECURESTORAGE_ERROR_MOUNT_CRYPTO_FAILED - * and IRONSIDE_UICR_SECURESTORAGE_ERROR_MOUNT_ITS_FAILED. - */ - uint16_t owner_id; - } securestorage; - /** UICR.PERIPHCONF error description. */ - struct { - /** Reason that UICR.PERIPHCONF configuration failed. */ - uint16_t status; - /** Index of the failing entry in the UICR.PERIPHCONF array. */ - uint16_t index; - } periphconf; - } uicr_detail; -}; - -/** @brief Initialization/boot context description contained in the boot report. */ -struct ironside_boot_report_init_context { - /** Reserved for Future Use */ - uint8_t rfu[3]; - /** Reason the processor was started. */ - uint8_t boot_reason; - - union { - /** Data passed from booting local domain to local domain being booted. - * - * Valid if the boot reason is one of the following: - * - IRONSIDE_BOOT_REASON_CPUCONF_CALL - * - IRONSIDE_BOOT_REASON_BOOTMODE_SECONDARY_CALL - */ - uint8_t local_domain_context[IRONSIDE_BOOT_REPORT_LOCAL_DOMAIN_CONTEXT_SIZE]; - - /** Initialiation error that triggered the boot. - * - * Valid if the boot reason is IRONSIDE_BOOT_REASON_BOOTERROR. - */ - struct ironside_boot_report_init_status trigger_init_status; - - /** RESETREAS.DOMAIN that triggered the boot. - * - * Valid if the boot reason is IRONSIDE_BOOT_REASON_TRIGGER_RESETREAS. - */ - uint32_t trigger_resetreas[4]; - }; -}; - -/** @brief IronSide boot report. */ -struct ironside_boot_report { - /** Magic value used to identify valid boot report */ - uint32_t magic; - /** Firmware version of IronSide SE. 8bit MAJOR.MINOR.PATCH.SEQNUM */ - uint32_t ironside_se_version_int; - /** Human readable extraversion of IronSide SE */ - char ironside_se_extraversion[12]; - /** Firmware version of IronSide SE recovery firmware. 8bit MAJOR.MINOR.PATCH.SEQNUM */ - uint32_t ironside_se_recovery_version_int; - /** Human readable extraversion of IronSide SE recovery firmware */ - char ironside_se_recovery_extraversion[12]; - /** Copy of SICR.UROT.UPDATE.STATUS.*/ - uint32_t ironside_update_status; - /** Initialization/boot status. */ - struct ironside_boot_report_init_status init_status; - /** Reserved for Future Use */ - uint16_t rfu1; - /** Flags describing the current boot mode. */ - uint16_t boot_mode_flags; - /** Data describing the context under which the CPU was booted. */ - struct ironside_boot_report_init_context init_context; - /** CSPRNG data */ - uint8_t random_data[IRONSIDE_BOOT_REPORT_RANDOM_DATA_SIZE]; - /** Device Info data : 128-bit Universally Unique IDentifier (UUID) */ - uint8_t device_info_uuid[IRONSIDE_BOOT_REPORT_UUID_SIZE]; - /** Reserved for Future Use */ - uint32_t rfu2[60]; -}; - -/** - * @brief Get a pointer to the IronSide boot report. - * - * @param[out] report Will be set to point to the IronSide boot report. - * - * @retval 0 if successful. - * @retval -EFAULT if the magic field in the report is incorrect. - * @retval -EINVAL if @p report is NULL. - */ -int ironside_boot_report_get(const struct ironside_boot_report **report); - -#endif /* ZEPHYR_SOC_NORDIC_IRONSIDE_INCLUDE_NRF_IRONSIDE_BOOT_REPORT_H_ */ diff --git a/soc/nordic/ironside/include/nrf_ironside/bootmode.h b/soc/nordic/ironside/include/nrf_ironside/bootmode.h deleted file mode 100644 index 4da46f33dd6d..000000000000 --- a/soc/nordic/ironside/include/nrf_ironside/bootmode.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2025 Nordic Semiconductor ASA - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef ZEPHYR_SOC_NORDIC_IRONSIDE_INCLUDE_NRF_IRONSIDE_BOOTMODE_H_ -#define ZEPHYR_SOC_NORDIC_IRONSIDE_INCLUDE_NRF_IRONSIDE_BOOTMODE_H_ - -#include -#include -#include - -/** - * @name Boot mode service error codes. - * @{ - */ - -/** Invalid/unsupported boot mode transition. */ -#define IRONSIDE_BOOTMODE_ERROR_UNSUPPORTED_MODE (1) -/** Failed to reboot into the boot mode due to other activity preventing a reset. */ -#define IRONSIDE_BOOTMODE_ERROR_BUSY (2) -/** The boot message is too large to fit in the buffer. */ -#define IRONSIDE_BOOTMODE_ERROR_MESSAGE_TOO_LARGE (3) - -/** - * @} - */ - -/* IronSide call identifiers with implicit versions. */ -#define IRONSIDE_CALL_ID_BOOTMODE_SERVICE_V1 5 - -enum { - IRONSIDE_BOOTMODE_SERVICE_MODE_IDX, - IRONSIDE_BOOTMODE_SERVICE_MSG_0_IDX, - IRONSIDE_BOOTMODE_SERVICE_MSG_1_IDX, - IRONSIDE_BOOTMODE_SERVICE_MSG_2_IDX, - IRONSIDE_BOOTMODE_SERVICE_MSG_3_IDX, - /* The last enum value is reserved for the number of arguments */ - IRONSIDE_BOOTMODE_SERVICE_NUM_ARGS, -}; - -/* Maximum size of the message parameter. */ -#define IRONSIDE_BOOTMODE_SERVICE_MSG_MAX_SIZE (4 * sizeof(uint32_t)) - -/* Index of the return code within the service buffer. */ -#define IRONSIDE_BOOTMODE_SERVICE_RETCODE_IDX (0) - -/** - * @brief Request a reboot into the secondary firmware boot mode. - * - * This invokes the IronSide SE boot mode service to restart the system into the secondary boot - * mode. In this mode, the secondary configuration defined in UICR is applied instead of the - * primary one. The system immediately reboots without a reply if the request succeeds. - * - * The given message data is passed to the boot report of the CPU booted in the secondary boot mode. - * - * @note This function does not return if the request is successful. - * @note The device will boot into the secondary firmware instead of primary firmware. - * @note The request does not fail if the secondary firmware is not defined. - * - * @param msg A message that can be placed in the cpu's boot report. - * @param msg_size Size of the message in bytes. - * - * @retval 0 on success. - * @retval -IRONSIDE_BOOTMODE_ERROR_UNSUPPORTED_MODE if the secondary boot mode is unsupported. - * @retval -IRONSIDE_BOOTMODE_ERROR_BUSY if the reboot was blocked. - * @retval -IRONSIDE_BOOTMODE_ERROR_MESSAGE_TOO_LARGE if msg_size is greater than - * IRONSIDE_BOOTMODE_SERVICE_MSG_MAX_SIZE. - * @retval Positive error status if reported by IronSide call (see error codes in @ref call.h). - */ -int ironside_bootmode_secondary_reboot(const uint8_t *msg, size_t msg_size); - -#endif /* ZEPHYR_SOC_NORDIC_IRONSIDE_INCLUDE_NRF_IRONSIDE_BOOTMODE_H_ */ diff --git a/soc/nordic/ironside/include/nrf_ironside/call.h b/soc/nordic/ironside/include/nrf_ironside/call.h deleted file mode 100644 index 9a2431c7d580..000000000000 --- a/soc/nordic/ironside/include/nrf_ironside/call.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (c) 2025 Nordic Semiconductor ASA - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef ZEPHYR_SOC_NORDIC_IRONSIDE_INCLUDE_NRF_IRONSIDE_CALL_H_ -#define ZEPHYR_SOC_NORDIC_IRONSIDE_INCLUDE_NRF_IRONSIDE_CALL_H_ - -#include - -/** @brief Maximum number of arguments to an IronSide call. - * - * This is chosen so that the containing message buffer size is minimal but - * cache line aligned. - */ -#define NRF_IRONSIDE_CALL_NUM_ARGS 7 - -/** @brief Message buffer. */ -struct ironside_call_buf { - /** Status code. This is set by the API. */ - uint16_t status; - /** Operation identifier. This is set by the user. */ - uint16_t id; - /** Operation arguments. These are set by the user. */ - uint32_t args[NRF_IRONSIDE_CALL_NUM_ARGS]; -}; - -/** - * @name Message buffer status codes. - * @{ - */ - -/** Buffer is idle and available for allocation. */ -#define IRONSIDE_CALL_STATUS_IDLE 0 -/** Request was processed successfully by the server. */ -#define IRONSIDE_CALL_STATUS_RSP_SUCCESS 1 -/** Request status code is unknown. */ -#define IRONSIDE_CALL_STATUS_RSP_ERR_UNKNOWN_STATUS 2 -/** Request status code is no longer supported. */ -#define IRONSIDE_CALL_STATUS_RSP_ERR_EXPIRED_STATUS 3 -/** Operation identifier is unknown. */ -#define IRONSIDE_CALL_STATUS_RSP_ERR_UNKNOWN_ID 4 -/** Operation identifier is no longer supported. */ -#define IRONSIDE_CALL_STATUS_RSP_ERR_EXPIRED_ID 5 -/** Buffer contains a request from the client. */ -#define IRONSIDE_CALL_STATUS_REQ 6 - -/** - * @} - */ - -/** - * @brief Allocate memory for an IronSide call. - * - * This function will block when no buffers are available, until one is - * released by another thread on the client side. - * - * @return Pointer to the allocated buffer. - */ -struct ironside_call_buf *ironside_call_alloc(void); - -/** - * @brief Dispatch an IronSide call. - * - * This function will block until a response is received from the server. - * - * @param buf Buffer returned by ironside_call_alloc(). It should be populated - * with request data before calling this function. Upon returning, - * this data will have been replaced by response data. - */ -void ironside_call_dispatch(struct ironside_call_buf *buf); - -/** - * @brief Release an IronSide call buffer. - * - * This function must be called after processing the response. - * - * @param buf Buffer used to perform the call. - */ -void ironside_call_release(struct ironside_call_buf *buf); - -#endif /* ZEPHYR_SOC_NORDIC_IRONSIDE_INCLUDE_NRF_IRONSIDE_CALL_H_ */ diff --git a/soc/nordic/ironside/include/nrf_ironside/counter.h b/soc/nordic/ironside/include/nrf_ironside/counter.h deleted file mode 100644 index 37866c43a684..000000000000 --- a/soc/nordic/ironside/include/nrf_ironside/counter.h +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (c) 2025 Nordic Semiconductor ASA - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef ZEPHYR_SOC_NORDIC_IRONSIDE_INCLUDE_NRF_IRONSIDE_COUNTER_H_ -#define ZEPHYR_SOC_NORDIC_IRONSIDE_INCLUDE_NRF_IRONSIDE_COUNTER_H_ - -#include -#include -#include - -/** - * @name Counter service error codes. - * @{ - */ - -/** Counter value is lower than current value (monotonic violation). */ -#define IRONSIDE_COUNTER_ERROR_TOO_LOW (1) -/** Invalid counter ID. */ -#define IRONSIDE_COUNTER_ERROR_INVALID_ID (2) -/** Counter is locked and cannot be modified. */ -#define IRONSIDE_COUNTER_ERROR_LOCKED (3) -/** Invalid parameter. */ -#define IRONSIDE_COUNTER_ERROR_INVALID_PARAM (4) -/** Storage operation failed. */ -#define IRONSIDE_COUNTER_ERROR_STORAGE_FAILURE (5) - -/** - * @} - */ - -/** Maximum value for a counter */ -#define IRONSIDE_COUNTER_MAX_VALUE UINT32_MAX - -/** Number of counters */ -#define IRONSIDE_COUNTER_NUM 4 - -/** - * @brief Counter identifiers. - */ -enum ironside_counter { - IRONSIDE_COUNTER_0 = 0, - IRONSIDE_COUNTER_1, - IRONSIDE_COUNTER_2, - IRONSIDE_COUNTER_3 -}; - -/* IronSide call identifiers with implicit versions. */ -#define IRONSIDE_CALL_ID_COUNTER_SET_V1 6 -#define IRONSIDE_CALL_ID_COUNTER_GET_V1 7 -#define IRONSIDE_CALL_ID_COUNTER_LOCK_V1 8 - -enum { - IRONSIDE_COUNTER_SET_SERVICE_COUNTER_ID_IDX, - IRONSIDE_COUNTER_SET_SERVICE_VALUE_IDX, - /* The last enum value is reserved for the number of arguments */ - IRONSIDE_COUNTER_SET_NUM_ARGS -}; - -enum { - IRONSIDE_COUNTER_GET_SERVICE_COUNTER_ID_IDX, - /* The last enum value is reserved for the number of arguments */ - IRONSIDE_COUNTER_GET_NUM_ARGS -}; - -enum { - IRONSIDE_COUNTER_LOCK_SERVICE_COUNTER_ID_IDX, - /* The last enum value is reserved for the number of arguments */ - IRONSIDE_COUNTER_LOCK_NUM_ARGS -}; - -/* Index of the return code within the service buffer. */ -#define IRONSIDE_COUNTER_SET_SERVICE_RETCODE_IDX (0) -#define IRONSIDE_COUNTER_GET_SERVICE_RETCODE_IDX (0) -#define IRONSIDE_COUNTER_LOCK_SERVICE_RETCODE_IDX (0) - -/* Index of the value within the GET response buffer. */ -#define IRONSIDE_COUNTER_GET_SERVICE_VALUE_IDX (1) - -BUILD_ASSERT(IRONSIDE_COUNTER_SET_NUM_ARGS <= NRF_IRONSIDE_CALL_NUM_ARGS); -BUILD_ASSERT(IRONSIDE_COUNTER_GET_NUM_ARGS <= NRF_IRONSIDE_CALL_NUM_ARGS); -BUILD_ASSERT(IRONSIDE_COUNTER_LOCK_NUM_ARGS <= NRF_IRONSIDE_CALL_NUM_ARGS); - -/** - * @brief Set a counter value. - * - * This sets the specified counter to the given value. The counter is monotonic, - * so the new value must be greater than or equal to the current value. - * If the counter is locked, the operation will fail. - * - * @note Counters are automatically initialized to 0 during the first boot in LCS ROT. - * The monotonic constraint applies to all subsequent writes. - * - * @param counter_id Counter identifier. - * @param value New counter value. - * - * @retval 0 on success. - * @retval -IRONSIDE_COUNTER_ERROR_INVALID_ID if counter_id is invalid. - * @retval -IRONSIDE_COUNTER_ERROR_TOO_LOW if value is lower than current value. - * @retval -IRONSIDE_COUNTER_ERROR_LOCKED if counter is locked. - * @retval -IRONSIDE_COUNTER_ERROR_STORAGE_FAILURE if storage operation failed. - * @retval Positive error status if reported by IronSide call (see error codes in @ref call.h). - */ -int ironside_counter_set(enum ironside_counter counter_id, uint32_t value); - -/** - * @brief Get a counter value. - * - * This retrieves the current value of the specified counter. - * - * @note Counters are automatically initialized to 0 during the first boot in LCS ROT, - * so this function will always succeed for valid counter IDs. - * - * @param counter_id Counter identifier. - * @param value Pointer to store the counter value. - * - * @retval 0 on success. - * @retval -IRONSIDE_COUNTER_ERROR_INVALID_ID if counter_id is invalid. - * @retval -IRONSIDE_COUNTER_ERROR_INVALID_PARAM if value is NULL. - * @retval -IRONSIDE_COUNTER_ERROR_STORAGE_FAILURE if storage operation failed. - * @retval Positive error status if reported by IronSide call (see error codes in @ref call.h). - */ -int ironside_counter_get(enum ironside_counter counter_id, uint32_t *value); - -/** - * @brief Lock a counter for the current boot. - * - * This locks the specified counter, preventing any further modifications until the next reboot. - * The lock state is not persistent and will be cleared on reboot. - * - * @note The intended use case is for a bootloader to lock a counter before transferring control - * to the next boot stage, preventing that image from modifying the counter value. - * - * @param counter_id Counter identifier. - * - * @retval 0 on success. - * @retval -IRONSIDE_COUNTER_ERROR_INVALID_ID if counter_id is invalid. - * @retval Positive error status if reported by IronSide call (see error codes in @ref call.h). - */ -int ironside_counter_lock(enum ironside_counter counter_id); - -#endif /* ZEPHYR_SOC_NORDIC_IRONSIDE_INCLUDE_NRF_IRONSIDE_COUNTER_H_ */ diff --git a/soc/nordic/ironside/include/nrf_ironside/cpuconf.h b/soc/nordic/ironside/include/nrf_ironside/cpuconf.h deleted file mode 100644 index a0fabd8abbd2..000000000000 --- a/soc/nordic/ironside/include/nrf_ironside/cpuconf.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2025 Nordic Semiconductor ASA - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef ZEPHYR_SOC_NORDIC_IRONSIDE_INCLUDE_NRF_IRONSIDE_CPUCONF_H_ -#define ZEPHYR_SOC_NORDIC_IRONSIDE_INCLUDE_NRF_IRONSIDE_CPUCONF_H_ - -#include -#include -#include -#include -#include - -/** - * @name CPUCONF service error codes. - * @{ - */ - -/** An invalid or unsupported processor ID was specified. */ -#define IRONSIDE_CPUCONF_ERROR_WRONG_CPU (1) -/** The boot message is too large to fit in the buffer. */ -#define IRONSIDE_CPUCONF_ERROR_MESSAGE_TOO_LARGE (2) - -/** - * @} - */ - -#define IRONSIDE_CALL_ID_CPUCONF_V0 2 - -enum { - IRONSIDE_CPUCONF_SERVICE_CPU_PARAMS_IDX, - IRONSIDE_CPUCONF_SERVICE_VECTOR_TABLE_IDX, - IRONSIDE_CPUCONF_SERVICE_MSG_0, - IRONSIDE_CPUCONF_SERVICE_MSG_1, - IRONSIDE_CPUCONF_SERVICE_MSG_2, - IRONSIDE_CPUCONF_SERVICE_MSG_3, - /* The last enum value is reserved for the number of arguments */ - IRONSIDE_CPUCONF_NUM_ARGS -}; - -/* Maximum size of the CPUCONF message parameter. */ -#define IRONSIDE_CPUCONF_SERVICE_MSG_MAX_SIZE (4 * sizeof(uint32_t)) - -/* IDX 0 is re-used by the error return code and the 'cpu' parameter. */ -#define IRONSIDE_CPUCONF_SERVICE_RETCODE_IDX 0 - -BUILD_ASSERT(IRONSIDE_CPUCONF_NUM_ARGS <= NRF_IRONSIDE_CALL_NUM_ARGS); - -/** - * @brief Boot a local domain CPU - * - * @param cpu The CPU to be booted - * @param vector_table Pointer to the vector table used to boot the CPU. - * @param cpu_wait When this is true, the CPU will WAIT even if the CPU has clock. - * @param msg A message that can be placed in cpu's boot report. - * @param msg_size Size of the message in bytes. - * - * @note cpu_wait is only intended to be enabled for debug purposes - * and it is only supported that a debugger resumes the CPU. - * - * @note the call always sends IRONSIDE_CPUCONF_SERVICE_MSG_MAX_SIZE message bytes. - * If the given msg_size is less than that, the remaining bytes are set to zero. - * - * @retval 0 on success or if the CPU has already booted. - * @retval -IRONSIDE_CPUCONF_ERROR_WRONG_CPU if cpu is unrecognized. - * @retval -IRONSIDE_CPUCONF_ERROR_MESSAGE_TOO_LARGE if msg_size is greater than - * IRONSIDE_CPUCONF_SERVICE_MSG_MAX_SIZE. - * @retval Positive error status if reported by IronSide call (see error codes in @ref call.h). - */ -int ironside_cpuconf(NRF_PROCESSORID_Type cpu, const void *vector_table, bool cpu_wait, - const uint8_t *msg, size_t msg_size); - -#endif /* ZEPHYR_SOC_NORDIC_IRONSIDE_INCLUDE_NRF_IRONSIDE_CPUCONF_H_ */ diff --git a/soc/nordic/ironside/include/nrf_ironside/dvfs.h b/soc/nordic/ironside/include/nrf_ironside/dvfs.h deleted file mode 100644 index c47cc43a8598..000000000000 --- a/soc/nordic/ironside/include/nrf_ironside/dvfs.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (c) 2025 Nordic Semiconductor ASA - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef ZEPHYR_SOC_NORDIC_IRONSIDE_INCLUDE_NRF_IRONSIDE_DVFS_H_ -#define ZEPHYR_SOC_NORDIC_IRONSIDE_INCLUDE_NRF_IRONSIDE_DVFS_H_ - -#include -#include -#include -#include - -enum ironside_dvfs_oppoint { - IRONSIDE_DVFS_OPP_HIGH = 0, - IRONSIDE_DVFS_OPP_MEDLOW = 1, - IRONSIDE_DVFS_OPP_LOW = 2 -}; - -/** - * @brief Number of DVFS oppoints supported by IronSide. - * - * This is the number of different DVFS oppoints that can be set on IronSide. - * The oppoints are defined in the `ironside_dvfs_oppoint` enum. - */ -#define IRONSIDE_DVFS_OPPOINT_COUNT (3) - -/** - * @name IronSide DVFS service error codes. - * @{ - */ - -/** The requested DVFS oppoint is not allowed. */ -#define IRONSIDE_DVFS_ERROR_WRONG_OPPOINT (1) -/** Waiting for mutex lock timed out, or hardware is busy. */ -#define IRONSIDE_DVFS_ERROR_BUSY (2) -/** There is configuration error in the DVFS service. */ -#define IRONSIDE_DVFS_ERROR_OPPOINT_DATA (3) -/** The caller does not have permission to change the DVFS oppoint. */ -#define IRONSIDE_DVFS_ERROR_PERMISSION (4) -/** The requested DVFS oppoint is already set, no change needed. */ -#define IRONSIDE_DVFS_ERROR_NO_CHANGE_NEEDED (5) -/** The operation timed out, possibly due to a hardware issue. */ -#define IRONSIDE_DVFS_ERROR_TIMEOUT (6) -/** The DVFS oppoint change operation is not allowed in the ISR context. */ -#define IRONSIDE_DVFS_ERROR_ISR_NOT_ALLOWED (7) - -/** - * @} - */ - -/* IronSide call identifiers with implicit versions. - * - * With the initial "version 0", the service ABI is allowed to break until the - * first production release of IronSide SE. - */ -#define IRONSIDE_CALL_ID_DVFS_SERVICE_V0 3 - -/* Index of the DVFS oppoint within the service buffer. */ -#define IRONSIDE_DVFS_SERVICE_OPPOINT_IDX (0) -/* Index of the return code within the service buffer. */ -#define IRONSIDE_DVFS_SERVICE_RETCODE_IDX (0) - -/** - * @brief Change the current DVFS oppoint. - * - * This function will request a change of the current DVFS oppoint to the - * specified value. It will block until the change is applied. - * - * @param dvfs_oppoint The new DVFS oppoint to set. - * - * @retval 0 on success. - * @retval -IRONSIDE_DVFS_ERROR_WRONG_OPPOINT if the requested DVFS oppoint is not allowed. - * @retval -IRONSIDE_DVFS_ERROR_BUSY if waiting for mutex lock timed out, or hardware is busy. - * @retval -IRONSIDE_DVFS_ERROR_OPPOINT_DATA if there is configuration error in the DVFS service. - * @retval -IRONSIDE_DVFS_ERROR_PERMISSION if the caller does not have permission to change the DVFS - * oppoint. - * @retval -IRONSIDE_DVFS_ERROR_NO_CHANGE_NEEDED if the requested DVFS oppoint is already set. - * @retval -IRONSIDE_DVFS_ERROR_TIMEOUT if the operation timed out, possibly due to a hardware - * issue. - * @retval -IRONSIDE_DVFS_ERROR_ISR_NOT_ALLOWED if the DVFS oppoint change operation is not allowed - * in the ISR context. - * @retval Positive error status if reported by IronSide call (see error codes in @ref call.h). - */ -int ironside_dvfs_change_oppoint(enum ironside_dvfs_oppoint dvfs_oppoint); - -/** - * @brief Check if the given oppoint is valid. - * - * @param dvfs_oppoint The oppoint to check. - * @return true if the oppoint is valid, false otherwise. - */ -static inline bool ironside_dvfs_is_oppoint_valid(enum ironside_dvfs_oppoint dvfs_oppoint) -{ - if (dvfs_oppoint != IRONSIDE_DVFS_OPP_HIGH && dvfs_oppoint != IRONSIDE_DVFS_OPP_MEDLOW && - dvfs_oppoint != IRONSIDE_DVFS_OPP_LOW) { - return false; - } - - return true; -} - -#endif /* ZEPHYR_SOC_NORDIC_IRONSIDE_INCLUDE_NRF_IRONSIDE_DVFS_H_ */ diff --git a/soc/nordic/ironside/include/nrf_ironside/tdd.h b/soc/nordic/ironside/include/nrf_ironside/tdd.h deleted file mode 100644 index adfb1c53a648..000000000000 --- a/soc/nordic/ironside/include/nrf_ironside/tdd.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2025 Nordic Semiconductor ASA - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef ZEPHYR_SOC_NORDIC_IRONSIDE_INCLUDE_NRF_IRONSIDE_TDD_H_ -#define ZEPHYR_SOC_NORDIC_IRONSIDE_INCLUDE_NRF_IRONSIDE_TDD_H_ - -#include - -#include - -#define IRONSIDE_SE_TDD_SERVICE_ERROR_INVALID_CONFIG (1) - -#define IRONSIDE_SE_CALL_ID_TDD_V0 4 - -#define IRONSIDE_SE_TDD_SERVICE_REQ_CONFIG_IDX 0 -#define IRONSIDE_SE_TDD_SERVICE_RSP_RETCODE_IDX 0 - -enum ironside_se_tdd_config { - RESERVED0 = 0, /* Reserved */ - /** Turn off the TDD */ - IRONSIDE_SE_TDD_CONFIG_OFF = 1, - /** Turn on the TDD with default configuration */ - IRONSIDE_SE_TDD_CONFIG_ON_DEFAULT = 2, -}; - -/** - * @brief Control the Trace and Debug Domain (TDD). - * - * @param config The configuration to be applied. - * - * @retval 0 on success. - * @retval -IRONSIDE_SE_TDD_SERVICE_ERROR_INVALID_CONFIG if the configuration is invalid. - * @retval Positive error status if reported by IronSide call (see error codes in @ref call.h). - */ -int ironside_se_tdd_configure(const enum ironside_se_tdd_config config); - -#endif /* ZEPHYR_SOC_NORDIC_IRONSIDE_INCLUDE_NRF_IRONSIDE_TDD_H_ */ diff --git a/soc/nordic/ironside/include/nrf_ironside/update.h b/soc/nordic/ironside/include/nrf_ironside/update.h deleted file mode 100644 index 6e520e4e680b..000000000000 --- a/soc/nordic/ironside/include/nrf_ironside/update.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2025 Nordic Semiconductor ASA - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef ZEPHYR_SOC_NORDIC_IRONSIDE_INCLUDE_NRF_IRONSIDE_UPDATE_H_ -#define ZEPHYR_SOC_NORDIC_IRONSIDE_INCLUDE_NRF_IRONSIDE_UPDATE_H_ - -#include -#include - -/** - * @name Update service error codes. - * @{ - */ - -/** Caller does not have access to the provided update candidate buffer. */ -#define IRONSIDE_UPDATE_ERROR_NOT_PERMITTED (1) -/** Failed to write the update metadata to SICR. */ -#define IRONSIDE_UPDATE_ERROR_SICR_WRITE_FAILED (2) -/** Update candidate is placed outside of valid range */ -#define IRONSIDE_UPDATE_ERROR_INVALID_ADDRESS (3) - -/** - * @} - */ - -/** Size of the update blob */ -#ifdef CONFIG_SOC_SERIES_NRF54HX -#define IRONSIDE_UPDATE_BLOB_SIZE (160 * 1024) -#elif CONFIG_SOC_SERIES_NRF92X -#define IRONSIDE_UPDATE_BLOB_SIZE (160 * 1024) -#else -#error "Missing update blob size" -#endif - -/** Min address used for storing the update candidate */ -#define IRONSIDE_UPDATE_MIN_ADDRESS (0x0e100000) -/** Max address used for storing the update candidate */ -#define IRONSIDE_UPDATE_MAX_ADDRESS (0x0e200000 - IRONSIDE_UPDATE_BLOB_SIZE) - -/** Length of the update manifest in bytes */ -#define IRONSIDE_UPDATE_MANIFEST_LENGTH (256) -/** Length of the update public key in bytes. */ -#define IRONSIDE_UPDATE_PUBKEY_LENGTH (32) -/** Length of the update signature in bytes. */ -#define IRONSIDE_UPDATE_SIGNATURE_LENGTH (64) - -/* IronSide call identifiers with implicit versions. - * - * With the initial "version 0", the service ABI is allowed to break until the - * first production release of IronSide SE. - */ -#define IRONSIDE_CALL_ID_UPDATE_SERVICE_V0 1 - -/* Index of the update blob pointer within the service buffer. */ -#define IRONSIDE_UPDATE_SERVICE_UPDATE_PTR_IDX (0) -/* Index of the return code within the service buffer. */ -#define IRONSIDE_UPDATE_SERVICE_RETCODE_IDX (0) - -/** - * @brief IronSide update blob. - */ -struct ironside_update_blob { - uint8_t manifest[IRONSIDE_UPDATE_MANIFEST_LENGTH]; - uint8_t pubkey[IRONSIDE_UPDATE_PUBKEY_LENGTH]; - uint8_t signature[IRONSIDE_UPDATE_SIGNATURE_LENGTH]; - uint32_t firmware[]; -}; - -/** - * @brief Request a firmware upgrade of the IronSide SE. - * - * This invokes the IronSide SE update service. The device must be restarted for the update - * to be installed. Check the update status in the application boot report to see if the update - * was successfully installed. - * - * @param update Pointer to update blob - * - * @retval 0 on a successful request (although the update itself may still fail). - * @retval -IRONSIDE_UPDATE_ERROR_INVALID_ADDRESS if the address of the update is outside of the - * accepted range. - * @retval -IRONSIDE_UPDATE_ERROR_NOT_PERMITTED if missing access to the update candidate. - * @retval -IRONSIDE_UPDATE_ERROR_SICR_WRITE_FAILED if writing update parameters to SICR failed. - * @retval Positive error status if reported by IronSide call (see error codes in @ref call.h). - * - */ -int ironside_update(const struct ironside_update_blob *update); - -#endif /* ZEPHYR_SOC_NORDIC_IRONSIDE_INCLUDE_NRF_IRONSIDE_UPDATE_H_ */ diff --git a/soc/nordic/ironside/tdd.c b/soc/nordic/ironside/tdd.c deleted file mode 100644 index eee5691cf362..000000000000 --- a/soc/nordic/ironside/tdd.c +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2025 Nordic Semiconductor ASA - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include - -int ironside_se_tdd_configure(const enum ironside_se_tdd_config config) -{ - int err; - struct ironside_call_buf *const buf = ironside_call_alloc(); - - buf->id = IRONSIDE_SE_CALL_ID_TDD_V0; - buf->args[IRONSIDE_SE_TDD_SERVICE_REQ_CONFIG_IDX] = (uint32_t)config; - - ironside_call_dispatch(buf); - - if (buf->status == IRONSIDE_CALL_STATUS_RSP_SUCCESS) { - err = buf->args[IRONSIDE_SE_TDD_SERVICE_RSP_RETCODE_IDX]; - } else { - err = buf->status; - } - - ironside_call_release(buf); - - return err; -} diff --git a/soc/nordic/ironside/update.c b/soc/nordic/ironside/update.c deleted file mode 100644 index fabf6fb01049..000000000000 --- a/soc/nordic/ironside/update.c +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2025 Nordic Semiconductor ASA - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include - -int ironside_update(const struct ironside_update_blob *update) -{ - int err; - struct ironside_call_buf *const buf = ironside_call_alloc(); - - if ((uintptr_t)update < IRONSIDE_UPDATE_MIN_ADDRESS || - (uintptr_t)update > IRONSIDE_UPDATE_MAX_ADDRESS) { - return -IRONSIDE_UPDATE_ERROR_INVALID_ADDRESS; - } - - buf->id = IRONSIDE_CALL_ID_UPDATE_SERVICE_V0; - buf->args[IRONSIDE_UPDATE_SERVICE_UPDATE_PTR_IDX] = (uintptr_t)update; - - ironside_call_dispatch(buf); - - if (buf->status == IRONSIDE_CALL_STATUS_RSP_SUCCESS) { - err = buf->args[IRONSIDE_UPDATE_SERVICE_RETCODE_IDX]; - } else { - err = buf->status; - } - - ironside_call_release(buf); - - return err; -} diff --git a/soc/nordic/nrf54h/Kconfig b/soc/nordic/nrf54h/Kconfig index ac25cff79150..f8a1c31f6534 100644 --- a/soc/nordic/nrf54h/Kconfig +++ b/soc/nordic/nrf54h/Kconfig @@ -4,6 +4,7 @@ # SPDX-License-Identifier: Apache-2.0 config SOC_SERIES_NRF54HX + select HAS_IRONSIDE_SE select HAS_NRFS select HAS_NRFX select HAS_NORDIC_DRIVERS @@ -71,7 +72,7 @@ config SOC_NRF54H20_CPURAD_ENABLE bool "Boot the nRF54H20 Radio core" default y if NRF_802154_SER_HOST || BT_HCI_HOST depends on SOC_NRF54H20_CPUAPP - select NRF_IRONSIDE_CPUCONF_SERVICE + select IRONSIDE_SE_CALL select SOC_LATE_INIT_HOOK help This will at application boot time enable clock to the diff --git a/soc/nordic/nrf54h/Kconfig.defconfig.nrf54h20_cpuapp b/soc/nordic/nrf54h/Kconfig.defconfig.nrf54h20_cpuapp index 86149e5bd0e0..1260067a2fc5 100644 --- a/soc/nordic/nrf54h/Kconfig.defconfig.nrf54h20_cpuapp +++ b/soc/nordic/nrf54h/Kconfig.defconfig.nrf54h20_cpuapp @@ -17,4 +17,7 @@ config POWER_DOMAIN config CODE_DATA_RELOCATION default y if (PM || POWEROFF) && !MCUBOOT +config NRF_PERIPHCONF_SECTION + default y + endif # SOC_NRF54H20_CPUAPP diff --git a/soc/nordic/nrf54h/Kconfig.defconfig.nrf54h20_cpurad b/soc/nordic/nrf54h/Kconfig.defconfig.nrf54h20_cpurad index 31687c2a5443..8e0fca298817 100644 --- a/soc/nordic/nrf54h/Kconfig.defconfig.nrf54h20_cpurad +++ b/soc/nordic/nrf54h/Kconfig.defconfig.nrf54h20_cpurad @@ -17,4 +17,7 @@ config POWER_DOMAIN config CODE_DATA_RELOCATION default y if PM || POWEROFF +config NRF_PERIPHCONF_SECTION + default y + endif # SOC_NRF54H20_CPURAD diff --git a/soc/nordic/nrf54h/soc.c b/soc/nordic/nrf54h/soc.c index c52456f03be6..42a99ab6b246 100644 --- a/soc/nordic/nrf54h/soc.c +++ b/soc/nordic/nrf54h/soc.c @@ -24,7 +24,7 @@ #include #if defined(CONFIG_SOC_NRF54H20_CPURAD_ENABLE) -#include +#include #endif LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); @@ -225,8 +225,8 @@ void soc_late_init_hook(void) bool cpu_wait = IS_ENABLED(CONFIG_SOC_NRF54H20_CPURAD_ENABLE_DEBUG_WAIT); - err_cpuconf = ironside_cpuconf(NRF_PROCESSOR_RADIOCORE, radiocore_address, cpu_wait, msg, - msg_size); + err_cpuconf = ironside_se_cpuconf(NRF_PROCESSOR_RADIOCORE, radiocore_address, cpu_wait, msg, + msg_size); __ASSERT(err_cpuconf == 0, "err_cpuconf was %d", err_cpuconf); #endif /* CONFIG_SOC_NRF54H20_CPURAD_ENABLE */ } diff --git a/soc/nordic/nrf92/Kconfig b/soc/nordic/nrf92/Kconfig index 739aada2b26e..1c5b1af8deb3 100644 --- a/soc/nordic/nrf92/Kconfig +++ b/soc/nordic/nrf92/Kconfig @@ -4,6 +4,7 @@ # SPDX-License-Identifier: Apache-2.0 config SOC_SERIES_NRF92X + select HAS_IRONSIDE_SE select HAS_NRFS select HAS_NRFX select HAS_NORDIC_DRIVERS diff --git a/soc/nordic/nrf92/Kconfig.defconfig.nrf9280_cpuapp b/soc/nordic/nrf92/Kconfig.defconfig.nrf9280_cpuapp index 22ba6612ecfb..4e4bacfb5289 100644 --- a/soc/nordic/nrf92/Kconfig.defconfig.nrf9280_cpuapp +++ b/soc/nordic/nrf92/Kconfig.defconfig.nrf9280_cpuapp @@ -8,4 +8,7 @@ if SOC_NRF9280_CPUAPP config NUM_IRQS default 471 +config NRF_PERIPHCONF_SECTION + default y + endif # SOC_NRF9280_CPUAPP diff --git a/soc/nordic/nrf92/Kconfig.defconfig.nrf9280_cpurad b/soc/nordic/nrf92/Kconfig.defconfig.nrf9280_cpurad index 534658997fbe..e708e1208cac 100644 --- a/soc/nordic/nrf92/Kconfig.defconfig.nrf9280_cpurad +++ b/soc/nordic/nrf92/Kconfig.defconfig.nrf9280_cpurad @@ -8,4 +8,7 @@ if SOC_NRF9280_CPURAD config NUM_IRQS default 471 +config NRF_PERIPHCONF_SECTION + default y + endif # SOC_NRF9280_CPURAD From 80801d81bba00e0a06ea287d8b3e04b0993880b2 Mon Sep 17 00:00:00 2001 From: Roberto Flores Date: Thu, 11 Dec 2025 13:56:08 -0600 Subject: [PATCH 0463/3659] dts: atmel: sam0: fix dac generic clock source Changes generic clock source for DAC in SAMD5X MCU's. Generic clock source 0 speed is above the maximum speed permitted by the DAC. The generic clock was changed to the same one the ADC uses (0x2). Compared output of working microchip auto-generated code to the zephyr implementation to find discrepencaies in register values. Signed-off-by: Roberto Flores --- dts/arm/atmel/samd5x.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dts/arm/atmel/samd5x.dtsi b/dts/arm/atmel/samd5x.dtsi index 17683c487647..48092d2f9981 100644 --- a/dts/arm/atmel/samd5x.dtsi +++ b/dts/arm/atmel/samd5x.dtsi @@ -394,7 +394,7 @@ clocks = <&gclk 42>, <&mclk 0x20 9>; clock-names = "GCLK", "MCLK"; - atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clocks = <&gclk 2>; atmel,assigned-clock-names = "GCLK"; status = "disabled"; From e41faae09a9b2faf20d0e19a2b121ef15ddf18dd Mon Sep 17 00:00:00 2001 From: Nicolas Moreno Date: Thu, 11 Dec 2025 21:56:57 -0400 Subject: [PATCH 0464/3659] samples: sensor: accel_polling: remove duplicated header On main.c from sample sensor/accel_polling the header is duplicated, as well in sample sensor/stream_fifo. This is solved on this PR Signed-off-by: Nicolas Moreno --- samples/sensor/accel_polling/src/main.c | 1 - samples/sensor/stream_fifo/src/main.c | 1 - 2 files changed, 2 deletions(-) diff --git a/samples/sensor/accel_polling/src/main.c b/samples/sensor/accel_polling/src/main.c index cdcc9bc55613..ee97d2934a47 100644 --- a/samples/sensor/accel_polling/src/main.c +++ b/samples/sensor/accel_polling/src/main.c @@ -12,7 +12,6 @@ #include #include #include -#include #define ACCEL_ALIAS(i) DT_ALIAS(_CONCAT(accel, i)) #define ACCELEROMETER_DEVICE(i, _) \ diff --git a/samples/sensor/stream_fifo/src/main.c b/samples/sensor/stream_fifo/src/main.c index 45dd3cab8f4f..d97fd5f7af19 100644 --- a/samples/sensor/stream_fifo/src/main.c +++ b/samples/sensor/stream_fifo/src/main.c @@ -12,7 +12,6 @@ #include #include #include -#include #define STREAMDEV_ALIAS(i) DT_ALIAS(_CONCAT(stream, i)) #define STREAMDEV_DEVICE(i, _) \ From 64eba11ee764aed78a86bf76f07ebca7e3512175 Mon Sep 17 00:00:00 2001 From: Hake Huang Date: Fri, 12 Dec 2025 12:36:17 +0800 Subject: [PATCH 0465/3659] scripts: west: runners: add option for debug batch mode when in batch mode, we do not need manually 'go'. with this, we can use `west debug` in twister run test enable for jlink and linkserver which is tested example: west debug --runner jlink -- --batch Signed-off-by: Hake Huang --- scripts/west_commands/runners/core.py | 9 +++++++++ scripts/west_commands/runners/jlink.py | 15 +++++++++++---- scripts/west_commands/runners/linkserver.py | 12 +++++++++--- 3 files changed, 29 insertions(+), 7 deletions(-) diff --git a/scripts/west_commands/runners/core.py b/scripts/west_commands/runners/core.py index d998a1e19bbf..c4595bdb2505 100644 --- a/scripts/west_commands/runners/core.py +++ b/scripts/west_commands/runners/core.py @@ -324,6 +324,11 @@ class RunnerCaps: # to allow other commands to use the rtt address dry_run: bool = False skip_load: bool = False + batch_debug: bool = False # In batch mode, GDB exits with status 0 after loading; + # for automated debugging, add --batch with 'monitor go', + # 'disconnect', and 'quit' commands (named batch_debug in west), + # unlike interactive debug mode (default), + # which stops and waits for user input def __post_init__(self): if self.mult_dev_ids and not self.dev_id: @@ -651,6 +656,10 @@ def add_parser(cls, parser): if caps.skip_load else argparse.SUPPRESS), default=True) + parser.add_argument('--batch', action=argparse.BooleanOptionalAction, + help="enable west debug batch mode" + if caps.batch_debug else argparse.SUPPRESS) + # Runner-specific options. cls.do_add_parser(parser) diff --git a/scripts/west_commands/runners/jlink.py b/scripts/west_commands/runners/jlink.py index bb9426ceab86..ef6feb399587 100644 --- a/scripts/west_commands/runners/jlink.py +++ b/scripts/west_commands/runners/jlink.py @@ -55,7 +55,7 @@ def __init__(self, cfg, device, dev_id=None, gdb_host='', gdb_port=DEFAULT_JLINK_GDB_PORT, rtt_port=DEFAULT_JLINK_RTT_PORT, - tui=False, tool_opt=None, dev_id_type=None): + tui=False, tool_opt=None, dev_id_type=None, batch=False): super().__init__(cfg) self.file = cfg.file self.file_type = cfg.file_type @@ -81,6 +81,7 @@ def __init__(self, cfg, device, dev_id=None, self.loader = loader self.rtt_port = rtt_port self.dev_id_type = dev_id_type + self.is_batch = batch self.tool_opt = [] if tool_opt is not None: @@ -120,7 +121,7 @@ def name(cls): def capabilities(cls): return RunnerCaps(commands={'flash', 'debug', 'debugserver', 'attach', 'rtt'}, dev_id=True, flash_addr=True, erase=True, reset=True, - tool_opt=True, file=True, rtt=True) + tool_opt=True, file=True, rtt=True, batch_debug=True) @classmethod def dev_id_help(cls) -> str: @@ -221,7 +222,8 @@ def do_create(cls, cfg, args): gdb_port=args.gdb_port, rtt_port=args.rtt_port, tui=args.tui, tool_opt=args.tool_opt, - dev_id_type=args.dev_id_type) + dev_id_type=args.dev_id_type, + batch=args.batch) def print_gdbserver_message(self): if not self.thread_info_enabled: @@ -398,16 +400,21 @@ def do_run(self, command, **kwargs): raise ValueError('Cannot debug; elf is missing') else: elf_name = self.elf_name + client_cmd = (self.gdb_cmd + self.tui_arg + [elf_name] + + ['-batch' if self.is_batch else ''] + ['-ex', f'target remote {self.gdb_host}:{self.gdb_port}']) if command == 'debug': client_cmd += ['-ex', 'monitor halt', '-ex', 'monitor reset', '-ex', 'load'] - if self.reset: + if self.is_batch: + client_cmd += ['-ex', 'monitor go', '-ex', 'disconnect', '-ex', 'quit'] + elif self.reset: client_cmd += ['-ex', 'monitor reset'] + if not self.gdb_host: self.require(self.gdbserver) self.print_gdbserver_message() diff --git a/scripts/west_commands/runners/linkserver.py b/scripts/west_commands/runners/linkserver.py index ae3c35e9b57b..8e1a3ba45f53 100644 --- a/scripts/west_commands/runners/linkserver.py +++ b/scripts/west_commands/runners/linkserver.py @@ -29,7 +29,7 @@ def __init__(self, cfg, device, core, gdb_port=DEFAULT_LINKSERVER_GDB_PORT, semihost_port=DEFAULT_LINKSERVER_SEMIHOST_PORT, override=None, - tui=False, tool_opt=None): + tui=False, tool_opt=None, batch=False): super().__init__(cfg) self.file = cfg.file self.file_type = cfg.file_type @@ -49,6 +49,7 @@ def __init__(self, cfg, device, core, self.tui_arg = ['-tui'] if tui else [] self.override = override if override else [] self.override_cli = self._build_override_cli() + self.is_batch = batch self.tool_opt = [] if tool_opt is not None: @@ -63,7 +64,7 @@ def name(cls): def capabilities(cls): return RunnerCaps(commands={'flash', 'debug', 'debugserver', 'attach'}, dev_id=True, flash_addr=True, erase=True, - tool_opt=True, file=True) + tool_opt=True, file=True, batch_debug=True) @classmethod def do_add_parser(cls, parser): @@ -104,7 +105,8 @@ def do_create(cls, cfg, args): semihost_port=args.semihost_port, gdb_port=args.gdb_port, override=args.override, - tui=args.tui, tool_opt=args.tool_opt) + tui=args.tui, tool_opt=args.tool_opt, + batch=args.batch) @property def linkserver_version_str(self): @@ -147,6 +149,7 @@ def do_run(self, command, **kwargs): gdb_cmd = ([self.gdb_cmd] + self.tui_arg + [self.elf_name] + + ['-batch' if self.is_batch else ''] + ['-ex', f'target remote {self.gdb_host}:{self.gdb_port}']) if command == 'debug': @@ -154,6 +157,9 @@ def do_run(self, command, **kwargs): # the ram as inaccessible and does not flash. gdb_cmd += ['-ex', 'set mem inaccessible-by-default off'] gdb_cmd += ['-ex', 'monitor reset', '-ex', 'load'] + if self.is_batch: + gdb_cmd += ['-ex', 'monitor ondisconnect cont', '-ex', + 'monitor kill_server', '-ex', 'quit'] if command == 'attach': linkserver_cmd += ['--attach'] From c141b5563592f12a927210d9f13cdfe8f254c4d0 Mon Sep 17 00:00:00 2001 From: Martin Gysel Date: Fri, 12 Dec 2025 10:04:58 +0100 Subject: [PATCH 0466/3659] drivers: stm32 spi: do not unlock context unconditionally in pm action - call spi_stm32_pm_policy_state_lock_xxx functions wenn context is locked - do not call spi_stm32_pm_policy_state_lock_put() in internal helper spi_stm32_complete() (which gets called from various places) but at the end of a transfer where it belong Signed-off-by: Martin Gysel --- drivers/spi/spi_stm32.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/spi/spi_stm32.c b/drivers/spi/spi_stm32.c index c4943b9415d0..7ce05dd1bb25 100644 --- a/drivers/spi/spi_stm32.c +++ b/drivers/spi/spi_stm32.c @@ -859,8 +859,6 @@ static void spi_stm32_complete(const struct device *dev, int status) #ifdef CONFIG_SPI_STM32_INTERRUPT spi_context_complete(&data->ctx, dev, status); #endif - - spi_stm32_pm_policy_state_lock_put(dev); } #ifdef CONFIG_SPI_STM32_INTERRUPT @@ -1337,6 +1335,7 @@ static int transceive(const struct device *dev, end: #endif /* CONFIG_SPI_RTIO */ + spi_stm32_pm_policy_state_lock_put(dev); spi_context_release(&data->ctx, ret); @@ -1636,10 +1635,10 @@ static int transceive_dma(const struct device *dev, #endif /* CONFIG_SPI_SLAVE */ end: - spi_context_release(&data->ctx, ret); - spi_stm32_pm_policy_state_lock_put(dev); + spi_context_release(&data->ctx, ret); + return ret; } #endif /* CONFIG_SPI_STM32_DMA */ @@ -1739,7 +1738,6 @@ static int spi_stm32_pm_action(const struct device *dev, if (err < 0) { return err; } - spi_context_unlock_unconditionally(&data->ctx); break; case PM_DEVICE_ACTION_SUSPEND: /* Stop device clock. */ @@ -1806,6 +1804,8 @@ static int spi_stm32_init(const struct device *dev) spi_rtio_init(data->rtio_ctx, dev); #endif /* CONFIG_SPI_RTIO */ + spi_context_unlock_unconditionally(&data->ctx); + return pm_device_driver_init(dev, spi_stm32_pm_action); } From 157b0ddc15fafa16cd02462d76de5d0a97591191 Mon Sep 17 00:00:00 2001 From: Martin Gysel Date: Mon, 15 Dec 2025 21:02:51 +0100 Subject: [PATCH 0467/3659] drivers: stm32 spi: mark variable as maybe unused depending on build configuration, spi_context_cs_configure_all() is a no-opt, so mark the data variable as maybe unused. Signed-off-by: Martin Gysel --- drivers/spi/spi_stm32.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/spi/spi_stm32.c b/drivers/spi/spi_stm32.c index 7ce05dd1bb25..fef4e88f0549 100644 --- a/drivers/spi/spi_stm32.c +++ b/drivers/spi/spi_stm32.c @@ -1715,7 +1715,7 @@ static int spi_stm32_pinctrl_apply(const struct device *dev, uint8_t id) static int spi_stm32_pm_action(const struct device *dev, enum pm_device_action action) { - struct spi_stm32_data *data = dev->data; + __maybe_unused struct spi_stm32_data *data = dev->data; const struct spi_stm32_config *config = dev->config; const struct device *const clk = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE); int err; From c42c8a4da482334b62a293c8fa72bc8e0bdc5a6f Mon Sep 17 00:00:00 2001 From: Martin Gysel Date: Fri, 12 Dec 2025 10:55:55 +0100 Subject: [PATCH 0468/3659] drivers: flash: stm32 ospi: do not invalidate bet at end of loop This modification prevents the bet pointer from being nulled at the end of the loop, which would otherwise render the search for a suitable erase type ineffective. It also optimize the loop as it omits unnecessary operations. Without this change, the erase size defaults to one sector. If the chip defines fewer than JESD216_NUM_ERASE_TYPES (=4) erase types, this behavior still works, as the resulting command will correspond to a sector erase operation. However, if the chip defines all erase types, the resulting command will be the one specified in the erase type. But since bet is nulled, the erase size will incorrectly default to the sector size. Signed-off-by: Martin Gysel --- drivers/flash/flash_stm32_ospi.c | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/drivers/flash/flash_stm32_ospi.c b/drivers/flash/flash_stm32_ospi.c index 3f0cd1f9ecfc..02e0e52319a0 100644 --- a/drivers/flash/flash_stm32_ospi.c +++ b/drivers/flash/flash_stm32_ospi.c @@ -1284,24 +1284,23 @@ static int flash_stm32_ospi_erase(const struct device *dev, off_t addr, && ((bet == NULL) || (etp->exp > bet->exp))) { bet = etp; - cmd_erase.Instruction = bet->cmd; - } else if (bet == NULL) { - /* Use the default sector erase cmd */ - if (dev_cfg->data_mode == OSPI_OPI_MODE) { - cmd_erase.Instruction = SPI_NOR_OCMD_SE; - } else { - cmd_erase.Instruction = - (stm32_ospi_hal_address_size(dev) == - HAL_OSPI_ADDRESS_32_BITS) - ? SPI_NOR_CMD_SE_4B - : SPI_NOR_CMD_SE; - } } - /* Avoid using wrong erase type, - * if zero entries are found in erase_types - */ - bet = NULL; } + + if (bet != NULL) { + cmd_erase.Instruction = bet->cmd; + } else { + /* Use the default sector erase cmd */ + if (dev_cfg->data_mode == OSPI_OPI_MODE) { + cmd_erase.Instruction = SPI_NOR_OCMD_SE; + } else { + cmd_erase.Instruction = (stm32_ospi_hal_address_size(dev) == + HAL_OSPI_ADDRESS_32_BITS) + ? SPI_NOR_CMD_SE_4B + : SPI_NOR_CMD_SE; + } + } + LOG_DBG("Sector/Block Erase addr 0x%x, asize 0x%x amode 0x%x instr 0x%x", cmd_erase.Address, cmd_erase.AddressSize, cmd_erase.AddressMode, cmd_erase.Instruction); From f865e9d8329d9cc68bd4059f14faa558b31f25b5 Mon Sep 17 00:00:00 2001 From: Cristian Bulacu Date: Fri, 12 Dec 2025 12:47:38 +0200 Subject: [PATCH 0469/3659] openthread: Kconfig: Add OTBR config for mDNS processing This commit adds a new configuration flag which is used to compute a threshold that determines if an incoming mDNS packet will be processed. Signed-off-by: Cristian Bulacu --- modules/openthread/Kconfig | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/modules/openthread/Kconfig b/modules/openthread/Kconfig index 1e257b0a8ff5..034abf7ca6eb 100644 --- a/modules/openthread/Kconfig +++ b/modules/openthread/Kconfig @@ -257,6 +257,7 @@ config OPENTHREAD_CUSTOM_PARAMETERS config OPENTHREAD_NUM_MESSAGE_BUFFERS int "The number of message buffers in the buffer pool" + default 512 if OPENTHREAD_ZEPHYR_BORDER_ROUTER default 128 help "The number of message buffers in the buffer pool." @@ -439,6 +440,15 @@ config OPENTHREAD_ZEPHYR_BORDER_ROUTER_MSG_POOL_NUM This value represents the maximum number of messages from backbone interface that could be stored without being processed. +config OPENTHREAD_ZEPHYR_BORDER_ROUTER_MDNS_BUFFER_THRESHOLD + int "Threshold value to determine if an mDNS packet will be processed" + default 40 + help + This value is used to calculate if OpenThread mDNS module should + accept an incoming message or not. It is used to determine if + number of available OT message buffers will drop under a certain + threshold if the mDNS packet is accepted and processed. + endif # OPENTHREAD_ZEPHYR_BORDER_ROUTER endmenu # "OpenThread Border Router" From c898f775d240e81104666eec50eb7e061b544ec4 Mon Sep 17 00:00:00 2001 From: Cristian Bulacu Date: Fri, 12 Dec 2025 12:50:29 +0200 Subject: [PATCH 0470/3659] openthread: platform: mdns_socket: Avoid assert in high-traffic networks This commit implements a rule that will silently discard incoming mDNS messages if number of OT free message buffers after message conversion will be under a user-predefined threshold. mDNS is making use of OT message buffers, if an mDNS TX message can't be allocated, it will trigger an assert. Signed-off-by: Cristian Bulacu --- modules/openthread/platform/mdns_socket.c | 24 +++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/modules/openthread/platform/mdns_socket.c b/modules/openthread/platform/mdns_socket.c index fa8934bc590a..f6ace92c4200 100644 --- a/modules/openthread/platform/mdns_socket.c +++ b/modules/openthread/platform/mdns_socket.c @@ -6,6 +6,7 @@ #include "openthread/platform/mdns_socket.h" #include +#include #include "openthread/instance.h" #include "openthread_border_router.h" #include "platform-zephyr.h" @@ -24,6 +25,7 @@ #define MULTICAST_PORT 5353 #define MAX_SERVICES CONFIG_OPENTHREAD_ZEPHYR_BORDER_ROUTER_MAX_MDNS_SERVICES +#define PKT_THRESHOLD_VAL CONFIG_OPENTHREAD_ZEPHYR_BORDER_ROUTER_MDNS_BUFFER_THRESHOLD static struct zsock_pollfd sockfd_udp[MAX_SERVICES]; static int mdns_sock_v6 = -1; @@ -385,6 +387,28 @@ static void process_mdns_message(struct otbr_msg_ctx *msg_ctx_ptr) { otMessageSettings ot_message_settings = {true, OT_MESSAGE_PRIORITY_NORMAL}; otMessage *ot_message = NULL; + otBufferInfo buffer_info; + uint16_t req_buff_num; + + /** In large networks with high traffic, we have observed that mDNS module + * might jump to assert when trying to allocate OT message buffers for a new + * query/response that has to be sent. + * Here, we calculate the approximate number of OT message buffers that will be required + * to hold the incoming mDNS packet. If the number of free OT message buffers will drop + * below the imposed limit after the conversion has been perfomed, the incoming packet + * will be silently dropped. + * A possible scenario would be when multipackets (TC bit set) are received from multiple + * hosts, as mDNS module stores the incoming messages for a period of time. + * This mechanism tries to make sure that there are enough free buffers for mDNS module + * to perform it's execution. + */ + + req_buff_num = (msg_ctx_ptr->length / + (CONFIG_OPENTHREAD_MESSAGE_BUFFER_SIZE - sizeof(otMessageBuffer))) + 1; + otMessageGetBufferInfo(ot_instance_ptr, &buffer_info); + + VerifyOrExit((buffer_info.mFreeBuffers - req_buff_num) >= + ((PKT_THRESHOLD_VAL * CONFIG_OPENTHREAD_NUM_MESSAGE_BUFFERS) / 100)); ot_message = otIp6NewMessage(ot_instance_ptr, &ot_message_settings); VerifyOrExit(ot_message); From 853d33e8e32aab95de7ee9426712d014654386b9 Mon Sep 17 00:00:00 2001 From: Jaro Van Landschoot Date: Fri, 12 Dec 2025 14:26:41 +0100 Subject: [PATCH 0471/3659] soc: atmel: sam: common: add warm reboot to soc_power.c If a warm reboot is issued (e.g., via mcumgr reset), the sam controller just hangs because of loop in reboot.c. This can be devastating if no watchdog is present to reboot the controller. Signed-off-by: Jaro Van Landschoot --- soc/atmel/sam/common/soc_power.c | 1 + 1 file changed, 1 insertion(+) diff --git a/soc/atmel/sam/common/soc_power.c b/soc/atmel/sam/common/soc_power.c index 0b477f9fbe9c..271407b4d1ed 100644 --- a/soc/atmel/sam/common/soc_power.c +++ b/soc/atmel/sam/common/soc_power.c @@ -19,6 +19,7 @@ void sys_arch_reboot(int type) Rstc *regs = (Rstc *)DT_REG_ADDR(SAM_DT_RSTC_DRIVER); switch (type) { + case SYS_REBOOT_WARM: case SYS_REBOOT_COLD: regs->RSTC_CR = RSTC_CR_KEY_PASSWD | RSTC_CR_PROCRST From e02a1b742ae88c1c617722efde2d8a103fceae3d Mon Sep 17 00:00:00 2001 From: Bartlomiej Buczek Date: Fri, 12 Dec 2025 16:21:43 +0100 Subject: [PATCH 0472/3659] Revert "drivers: adc: nrfx: Temporary fix for SAADC power consumption" New hal_nordic was merged some time ago, fix no longer needed. This reverts commit fe0b6b3b55f70c7306bcc21cf5242c00f483dc21. Signed-off-by: Bartlomiej Buczek --- drivers/adc/adc_nrfx_saadc.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/adc/adc_nrfx_saadc.c b/drivers/adc/adc_nrfx_saadc.c index af29161fc3cb..4e3979bc3f02 100644 --- a/drivers/adc/adc_nrfx_saadc.c +++ b/drivers/adc/adc_nrfx_saadc.c @@ -662,7 +662,6 @@ static void event_handler(const nrfx_saadc_evt_t *event) correct_single_ended(&m_data.ctx.sequence, m_data.user_buffer, event->data.done.size); } - nrfy_saadc_disable(NRF_SAADC); adc_context_on_sampling_done(&m_data.ctx, DEVICE_DT_INST_GET(0)); } else if (event->type == NRFX_SAADC_EVT_CALIBRATEDONE) { err = nrfx_saadc_mode_trigger(); From ba10774f912ca89d8ba4fa905c81bed57362ab07 Mon Sep 17 00:00:00 2001 From: Biwen Li Date: Wed, 17 Dec 2025 11:43:52 +0900 Subject: [PATCH 0473/3659] soc: nxp: imx943: m33: fix build issue Fix build issue from the below commit: c520b3da1ae4c5ffc2433c3ab5c9357e4aeb921d soc: nxp: imx943: m33: add and reuse api to initialize clocks error: soc_clock_enable defined but not used. Signed-off-by: Biwen Li --- soc/nxp/imx/imx9/imx943/m33/soc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/soc/nxp/imx/imx9/imx943/m33/soc.c b/soc/nxp/imx/imx9/imx943/m33/soc.c index 7036c1fe8d43..81d251811212 100644 --- a/soc/nxp/imx/imx9/imx943/m33/soc.c +++ b/soc/nxp/imx/imx9/imx943/m33/soc.c @@ -48,7 +48,9 @@ static int soc_clock_set_rate_and_parent(struct soc_clk *sclk) return scmi_clock_rate_set(proto, &clk_cfg); } +#endif +#if DT_NUM_INST_STATUS_OKAY(nxp_mcux_i2s) > 0 static int soc_clock_enable(struct soc_clk *sclk) { const struct device *clk_dev = DEVICE_DT_GET(DT_NODELABEL(scmi_clk)); From 6ad823ab8ddc8942bc69c65ce8ee44f4f92ae1cb Mon Sep 17 00:00:00 2001 From: McAtee Maxwell Date: Wed, 15 Oct 2025 15:40:13 -0700 Subject: [PATCH 0474/3659] drivers: pwm: add support for Infineon kit_pse84_eval - Update the driver to support the kit_pse84_eval board - Update to new peripheral clock allocation scheme Signed-off-by: McAtee Maxwell --- .../clock_control_infineon_peri_clock.c | 74 ++++++++++++++----- drivers/pwm/pwm_infineon_tcpwm.c | 72 ++++++++++++------ dts/bindings/clock/infineon,peri-div.yaml | 9 +++ dts/bindings/pwm/infineon,tcpwm-pwm.yaml | 2 +- dts/bindings/timer/infineon,tcpwm.yaml | 20 ----- .../clock_control/clock_control_ifx_cat1.h | 15 ++++ 6 files changed, 128 insertions(+), 64 deletions(-) diff --git a/drivers/clock_control/clock_control_infineon_peri_clock.c b/drivers/clock_control/clock_control_infineon_peri_clock.c index 08b5ef11c2b5..1c5e6e8f2b53 100644 --- a/drivers/clock_control/clock_control_infineon_peri_clock.c +++ b/drivers/clock_control/clock_control_infineon_peri_clock.c @@ -31,19 +31,23 @@ struct ifx_peri_clock_data { #if defined(CY_IP_MXPERI) || defined(CY_IP_M0S8PERI) -#define _IFX_CAT1_PCLK_GROUP(clkdst) 0 -#define _IFX_CAT1_TCPWM0_PCLK_CLOCK0 PCLK_TCPWM0_CLOCKS0 -#define _IFX_CAT1_TCPWM1_PCLK_CLOCK0 PCLK_TCPWM1_CLOCKS0 -#define _IFX_CAT1_SCB0_PCLK_CLOCK PCLK_SCB0_CLOCK +#define IFX_PCLK_GROUP(clkdst) 0 +#if (CY_IP_MXTCPWM_INSTANCES > 1) || (CY_IP_M0S8TCPWM_INSTANCES > 1) +#define IFX_TCPWM0_PCLK_CLOCK0 PCLK_TCPWM0_CLOCKS0 +#define IFX_TCPWM1_PCLK_CLOCK0 PCLK_TCPWM1_CLOCKS0 +#else +#define IFX_TCPWM0_PCLK_CLOCK0 PCLK_TCPWM_CLOCKS0 +#endif +#define IFX_SCB0_PCLK_CLOCK PCLK_SCB0_CLOCK #elif defined(CY_IP_MXSPERI) -#define _IFX_CAT1_PCLK_GROUP(clkdst) ((uint8_t)((uint32_t)(clkdst) >> 8)) -#define _IFX_CAT1_TCPWM0_PCLK_CLOCK0 PCLK_TCPWM0_CLOCK_COUNTER_EN0 -#define _IFX_CAT1_TCPWM1_PCLK_CLOCK0 PCLK_TCPWM1_CLOCK_COUNTER_EN0 -#define _IFX_CAT1_SCB0_PCLK_CLOCK PCLK_SCB0_CLOCK_SCB_EN -#define _IFX_CAT1_SCB1_PCLK_CLOCK PCLK_SCB1_CLOCK_SCB_EN -#define _IFX_CAT1_SCB5_PCLK_CLOCK PCLK_SCB5_CLOCK_SCB_EN +#define IFX_PCLK_GROUP(clkdst) ((uint8_t)((uint32_t)(clkdst) >> 8)) +#define IFX_TCPWM0_PCLK_CLOCK0 PCLK_TCPWM0_CLOCK_COUNTER_EN0 +#define IFX_TCPWM1_PCLK_CLOCK0 PCLK_TCPWM0_CLOCK_COUNTER_EN256 +#define IFX_SCB0_PCLK_CLOCK PCLK_SCB0_CLOCK_SCB_EN +#define IFX_SCB1_PCLK_CLOCK PCLK_SCB1_CLOCK_SCB_EN +#define IFX_SCB5_PCLK_CLOCK PCLK_SCB5_CLOCK_SCB_EN #endif en_clk_dst_t ifx_cat1_scb_get_clock_index(uint32_t block_num) @@ -52,21 +56,45 @@ en_clk_dst_t ifx_cat1_scb_get_clock_index(uint32_t block_num) /* PSOC6A256K does not have SCB 3 */ #if defined(CY_DEVICE_PSOC6A256K) if (block_num < 3) { - clk = (en_clk_dst_t)((uint32_t)_IFX_CAT1_SCB0_PCLK_CLOCK + block_num); + clk = (en_clk_dst_t)((uint32_t)IFX_SCB0_PCLK_CLOCK + block_num); } else { - clk = (en_clk_dst_t)((uint32_t)_IFX_CAT1_SCB0_PCLK_CLOCK + block_num - 1); + clk = (en_clk_dst_t)((uint32_t)IFX_SCB0_PCLK_CLOCK + block_num - 1); } #elif defined(CONFIG_SOC_FAMILY_INFINEON_EDGE) if (block_num == 0) { - clk = (en_clk_dst_t)((uint32_t)_IFX_CAT1_SCB0_PCLK_CLOCK); + clk = (en_clk_dst_t)((uint32_t)IFX_SCB0_PCLK_CLOCK); } else if (block_num == 1) { - clk = (en_clk_dst_t)((uint32_t)_IFX_CAT1_SCB1_PCLK_CLOCK); + clk = (en_clk_dst_t)((uint32_t)IFX_SCB1_PCLK_CLOCK); } else { - clk = (en_clk_dst_t)((uint32_t)_IFX_CAT1_SCB0_PCLK_CLOCK + block_num - 1); + clk = (en_clk_dst_t)((uint32_t)IFX_SCB0_PCLK_CLOCK + block_num - 1); } #else - clk = (en_clk_dst_t)((uint32_t)_IFX_CAT1_SCB0_PCLK_CLOCK + block_num); + clk = (en_clk_dst_t)((uint32_t)IFX_SCB0_PCLK_CLOCK + block_num); +#endif + + return clk; +} + +en_clk_dst_t ifx_cat1_tcpwm_get_clock_index(uint32_t block_num, uint32_t channel) +{ + en_clk_dst_t clk = -EINVAL; + + if (block_num == 0) { + /* block_num 0 is 32-bit tcpwm instances */ + clk = (en_clk_dst_t)((uint32_t)IFX_TCPWM0_PCLK_CLOCK0 + channel); +#if (CY_IP_MXTCPWM_INSTANCES > 1) || (CY_IP_M0S8TCPWM_INSTANCES > 1) || (CY_IP_MXSPERI) + } else if (block_num == 1) { + /* block_num 1 is 16-bit tcwpm instances */ + clk = (en_clk_dst_t)((uint32_t)IFX_TCPWM1_PCLK_CLOCK0 + channel); #endif + } else { + /* Current support does not account for block_num other than 0 or 1 */ + __ASSERT(block_num == 0 || block_num == 1, + "Invalid block_num used for tcpwm clock index."); +#if (CY_IP_MXTCPWM_INSTANCES == 1) || (CY_IP_M0S8TCPWM_INSTANCES == 1) || (CY_IP_MXSPERI) + __ASSERT(block_num == 0, "Invalid block_num used for tcpwm clock index."); +#endif + } return clk; } @@ -78,6 +106,13 @@ static int ifx_cat1_peri_clock_init(const struct device *dev) if (data->hw_resource.type == IFX_RSC_SCB) { en_clk_dst_t clk_idx = ifx_cat1_scb_get_clock_index(data->hw_resource.block_num); + ifx_cat1_utils_peri_pclk_set_divider(clk_idx, &data->clock, data->divider - 1); + ifx_cat1_utils_peri_pclk_assign_divider(clk_idx, &data->clock); + ifx_cat1_utils_peri_pclk_enable_divider(clk_idx, &data->clock); + } else if (data->hw_resource.type == IFX_RSC_TCPWM) { + en_clk_dst_t clk_idx = ifx_cat1_tcpwm_get_clock_index( + data->hw_resource.block_num, data->hw_resource.channel_num); + ifx_cat1_utils_peri_pclk_set_divider(clk_idx, &data->clock, data->divider - 1); ifx_cat1_utils_peri_pclk_assign_divider(clk_idx, &data->clock); ifx_cat1_utils_peri_pclk_enable_divider(clk_idx, &data->clock); @@ -107,10 +142,11 @@ static int ifx_cat1_peri_clock_init(const struct device *dev) #define INFINEON_CAT1_PERI_CLOCK_INIT(n) \ static struct ifx_peri_clock_data ifx_cat1_peri_clock##n##_data = { \ - PERI_CLOCK_INIT(n).divider = DT_INST_PROP(n, clock_div), \ + .divider = DT_INST_PROP(n, clock_div), \ .hw_resource = {.type = DT_INST_PROP(n, resource_type), \ - .block_num = DT_INST_PROP(n, resource_instance)}, \ - }; \ + .block_num = DT_INST_PROP(n, resource_instance), \ + .channel_num = DT_INST_PROP_OR(n, resource_channel, 0)}, \ + PERI_CLOCK_INIT(n)}; \ \ DEVICE_DT_INST_DEFINE(n, &ifx_cat1_peri_clock_init, NULL, &ifx_cat1_peri_clock##n##_data, \ NULL, PRE_KERNEL_1, CONFIG_CLOCK_CONTROL_INIT_PRIORITY, NULL); diff --git a/drivers/pwm/pwm_infineon_tcpwm.c b/drivers/pwm/pwm_infineon_tcpwm.c index f62173e7274d..a5e177a4f6f3 100644 --- a/drivers/pwm/pwm_infineon_tcpwm.c +++ b/drivers/pwm/pwm_infineon_tcpwm.c @@ -13,8 +13,11 @@ #include #include + +#include #include #include +#include #include #include @@ -27,10 +30,12 @@ struct ifx_tcpwm_pwm_config { TCPWM_GRP_CNT_Type *reg_base; const struct pinctrl_dev_config *pcfg; bool resolution_32_bits; - cy_en_divider_types_t divider_type; - uint32_t divider_sel; - uint32_t divider_val; uint32_t tcpwm_index; + uint32_t index; +}; + +struct ifx_tcpwm_pwm_data { + struct ifx_cat1_clock clock; }; static int ifx_tcpwm_pwm_init(const struct device *dev) @@ -38,7 +43,6 @@ static int ifx_tcpwm_pwm_init(const struct device *dev) const struct ifx_tcpwm_pwm_config *config = dev->config; cy_en_tcpwm_status_t status; int ret; - uint32_t clk_connection; const cy_stc_tcpwm_pwm_config_t pwm_config = { .pwmMode = CY_TCPWM_PWM_MODE_PWM, @@ -51,20 +55,6 @@ static int ifx_tcpwm_pwm_init(const struct device *dev) .enablePeriodSwap = true, }; - /* Configure PWM clock */ - Cy_SysClk_PeriphDisableDivider(config->divider_type, config->divider_sel); - Cy_SysClk_PeriphSetDivider(config->divider_type, config->divider_sel, config->divider_val); - Cy_SysClk_PeriphEnableDivider(config->divider_type, config->divider_sel); - - /* Calculate clock connection based on TCPWM index */ - if (config->resolution_32_bits) { - clk_connection = PCLK_TCPWM0_CLOCK_COUNTER_EN0 + config->tcpwm_index; - } else { - clk_connection = PCLK_TCPWM0_CLOCK_COUNTER_EN256 + config->tcpwm_index; - } - - Cy_SysClk_PeriphAssignDivider(clk_connection, config->divider_type, config->divider_sel); - ret = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT); if (ret < 0) { return ret; @@ -157,9 +147,18 @@ static int ifx_tcpwm_pwm_get_cycles_per_sec(const struct device *dev, uint32_t c { ARG_UNUSED(channel); + struct ifx_tcpwm_pwm_data *const data = dev->data; const struct ifx_tcpwm_pwm_config *config = dev->config; + en_clk_dst_t clk_connection; + + /* Determine tcpwm block number based on its resolution */ + uint32_t tcpwm_block = config->resolution_32_bits ? 0 : 1; + + /* Calculate clock connection based on TCPWM index */ + clk_connection = ifx_cat1_tcpwm_get_clock_index(tcpwm_block, config->index); - *cycles = Cy_SysClk_PeriphGetFrequency(config->divider_type, config->divider_sel); + *cycles = ifx_cat1_utils_peri_pclk_get_frequency(clk_connection, + &data->clock); return 0; } @@ -169,9 +168,33 @@ static DEVICE_API(pwm, ifx_tcpwm_pwm_api) = { .get_cycles_per_sec = ifx_tcpwm_pwm_get_cycles_per_sec, }; +#if defined(CONFIG_SOC_FAMILY_INFINEON_EDGE) +#define PWM_PERI_CLOCK_INIT(n) \ + .clock = \ + { \ + .block = IFX_CAT1_PERIPHERAL_GROUP_ADJUST( \ + DT_PROP_BY_IDX(DT_INST_PHANDLE(n, clocks), peri_group, 0), \ + DT_PROP_BY_IDX(DT_INST_PHANDLE(n, clocks), peri_group, 1), \ + DT_INST_PROP_BY_PHANDLE(n, clocks, div_type)), \ + .channel = DT_INST_PROP_BY_PHANDLE(n, clocks, channel), \ + } +#else +#define PWM_PERI_CLOCK_INIT(n) \ + .clock = \ + { \ + .block = IFX_CAT1_PERIPHERAL_GROUP_ADJUST( \ + DT_PROP_BY_IDX(DT_INST_PHANDLE(n, clocks), peri_group, 1), \ + DT_INST_PROP_BY_PHANDLE(n, clocks, div_type)), \ + .channel = DT_INST_PROP_BY_PHANDLE(n, clocks, channel), \ + } +#endif + #define INFINEON_TCPWM_PWM_INIT(n) \ PINCTRL_DT_INST_DEFINE(n); \ \ + static struct ifx_tcpwm_pwm_data ifx_tcpwm_pwm##n##_data = \ + {PWM_PERI_CLOCK_INIT(n)}; \ + \ static const struct ifx_tcpwm_pwm_config pwm_tcpwm_config_##n = { \ .reg_base = (TCPWM_GRP_CNT_Type *)DT_REG_ADDR(DT_INST_PARENT(n)), \ .tcpwm_index = (DT_REG_ADDR(DT_INST_PARENT(n)) - \ @@ -180,12 +203,13 @@ static DEVICE_API(pwm, ifx_tcpwm_pwm_api) = { .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ .resolution_32_bits = \ (DT_PROP(DT_INST_PARENT(n), resolution) == 32) ? true : false, \ - .divider_type = DT_PROP(DT_INST_PARENT(n), divider_type), \ - .divider_sel = DT_PROP(DT_INST_PARENT(n), divider_sel), \ - .divider_val = DT_PROP(DT_INST_PARENT(n), divider_val), \ + .index = (DT_REG_ADDR(DT_INST_PARENT(n)) - \ + DT_REG_ADDR(DT_PARENT(DT_INST_PARENT(n)))) / \ + DT_REG_SIZE(DT_INST_PARENT(n)), \ }; \ \ - DEVICE_DT_INST_DEFINE(n, ifx_tcpwm_pwm_init, NULL, NULL, &pwm_tcpwm_config_##n, \ - POST_KERNEL, CONFIG_PWM_INIT_PRIORITY, &ifx_tcpwm_pwm_api); + DEVICE_DT_INST_DEFINE(n, ifx_tcpwm_pwm_init, NULL, &ifx_tcpwm_pwm##n##_data, \ + &pwm_tcpwm_config_##n, POST_KERNEL, CONFIG_PWM_INIT_PRIORITY, \ + &ifx_tcpwm_pwm_api); DT_INST_FOREACH_STATUS_OKAY(INFINEON_TCPWM_PWM_INIT) diff --git a/dts/bindings/clock/infineon,peri-div.yaml b/dts/bindings/clock/infineon,peri-div.yaml index 4b55806c0eef..fceb58606f54 100644 --- a/dts/bindings/clock/infineon,peri-div.yaml +++ b/dts/bindings/clock/infineon,peri-div.yaml @@ -63,3 +63,12 @@ properties: &scb0 : resource-instance = <0> &scb3 : resource-instance = <3> &scb5 : resource-instance = <5> + &tcpwm0_3: resource-instance = <0> + + resource-channel: + type: int + description: | + Resource instance's channel that the peripheral clock is assigned to: + &tcpwm0_0 : resource-channel = <0> + &tcpwm0_4 : resource-channel = <4> + &tcpwm1_2 : resource-channel = <2> diff --git a/dts/bindings/pwm/infineon,tcpwm-pwm.yaml b/dts/bindings/pwm/infineon,tcpwm-pwm.yaml index 0d76bd907a56..5951beb20c00 100644 --- a/dts/bindings/pwm/infineon,tcpwm-pwm.yaml +++ b/dts/bindings/pwm/infineon,tcpwm-pwm.yaml @@ -7,7 +7,7 @@ description: Infineon TCPWM PWM compatible: "infineon,tcpwm-pwm" -include: [pwm-controller.yaml, pinctrl-device.yaml, "infineon,system-interrupts.yaml"] +include: [base.yaml, pwm-controller.yaml, pinctrl-device.yaml, "infineon,system-interrupts.yaml"] properties: "#pwm-cells": diff --git a/dts/bindings/timer/infineon,tcpwm.yaml b/dts/bindings/timer/infineon,tcpwm.yaml index c951011f8d6f..a5155ebcd89a 100644 --- a/dts/bindings/timer/infineon,tcpwm.yaml +++ b/dts/bindings/timer/infineon,tcpwm.yaml @@ -19,26 +19,6 @@ properties: type: array description: Interrupt mapping for TCPWM instance - divider-type: - type: int - description: | - Specifies which type of divider to use. - Defined by cy_en_divider_types_t in cy_sysclk.h. - required: true - - divider-sel: - type: int - description: | - Specifies which divider of the selected type to configure. - required: true - - divider-val: - type: int - description: | - Causes integer division of (divider value + 1), or division by 1 to 256 - (8-bit divider) or 1 to 65536 (16-bit divider). - required: true - resolution: type: int required: true diff --git a/include/zephyr/drivers/clock_control/clock_control_ifx_cat1.h b/include/zephyr/drivers/clock_control/clock_control_ifx_cat1.h index c02050216508..36145acb1f6a 100644 --- a/include/zephyr/drivers/clock_control/clock_control_ifx_cat1.h +++ b/include/zephyr/drivers/clock_control/clock_control_ifx_cat1.h @@ -401,6 +401,21 @@ struct ifx_cat1_resource_inst { int ifx_cat1_clock_control_get_frequency(uint32_t dt_ord, uint32_t *frequency); en_clk_dst_t ifx_cat1_scb_get_clock_index(uint32_t block_num); +en_clk_dst_t ifx_cat1_tcpwm_get_clock_index(uint32_t block_num, uint32_t channel); + +static inline uint32_t ifx_cat1_utils_peri_pclk_get_frequency(en_clk_dst_t clk_dest, + const struct ifx_cat1_clock *_clock) +{ +#if defined(COMPONENT_CAT1B) || defined(COMPONENT_CAT1C) || defined(CONFIG_SOC_FAMILY_INFINEON_EDGE) + return Cy_SysClk_PeriPclkGetFrequency( + clk_dest, IFX_CAT1_PERIPHERAL_GROUP_GET_DIVIDER_TYPE(_clock->block), + _clock->channel); +#else + CY_UNUSED_PARAMETER(clk_dest); + return Cy_SysClk_PeriphGetFrequency( + IFX_CAT1_PERIPHERAL_GROUP_GET_DIVIDER_TYPE(_clock->block), _clock->channel); +#endif +} static inline cy_rslt_t ifx_cat1_utils_peri_pclk_enable_divider(en_clk_dst_t clk_dest, const struct ifx_cat1_clock *_clock) From 9f42dd04138b824d0dd1c49b7509afd6f4835285 Mon Sep 17 00:00:00 2001 From: McAtee Maxwell Date: Wed, 15 Oct 2025 15:42:58 -0700 Subject: [PATCH 0475/3659] samples: pwm: add Infineon kit_pse84_eval - Add overlay files for the blinky_pwm and fade_led samples Signed-off-by: McAtee Maxwell --- .../boards/kit_pse84_eval_common.overlay | 51 +++++++++++++++++++ ...it_pse84_eval_pse846gps2dbzc4a_m33.overlay | 8 +++ ...it_pse84_eval_pse846gps2dbzc4a_m55.overlay | 8 +++ .../boards/kit_pse84_eval_common.overlay | 51 +++++++++++++++++++ ...it_pse84_eval_pse846gps2dbzc4a_m33.overlay | 8 +++ ...it_pse84_eval_pse846gps2dbzc4a_m55.overlay | 8 +++ 6 files changed, 134 insertions(+) create mode 100644 samples/basic/blinky_pwm/boards/kit_pse84_eval_common.overlay create mode 100644 samples/basic/blinky_pwm/boards/kit_pse84_eval_pse846gps2dbzc4a_m33.overlay create mode 100644 samples/basic/blinky_pwm/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.overlay create mode 100644 samples/basic/fade_led/boards/kit_pse84_eval_common.overlay create mode 100644 samples/basic/fade_led/boards/kit_pse84_eval_pse846gps2dbzc4a_m33.overlay create mode 100644 samples/basic/fade_led/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.overlay diff --git a/samples/basic/blinky_pwm/boards/kit_pse84_eval_common.overlay b/samples/basic/blinky_pwm/boards/kit_pse84_eval_common.overlay new file mode 100644 index 000000000000..396f1cd9bc37 --- /dev/null +++ b/samples/basic/blinky_pwm/boards/kit_pse84_eval_common.overlay @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + aliases { + pwm-led0 = &pwm_led0; + }; + + pwmleds { + compatible = "pwm-leds"; + + pwm_led0: pwm_led_0 { + pwms = <&pwm0_7 0 PWM_MSEC(20) PWM_POLARITY_INVERTED>; + label = "PWM LED"; + }; + + status = "okay"; + }; +}; + +&tcpwm0_7 { + status = "okay"; + + pwm0_7: pwm0_7 { + status = "okay"; + clocks = <&peri0_group1_16bit_1>; + pinctrl-0 = <&p16_7_pwm0_7>; + pinctrl-names = "default"; + }; +}; + +&peri0_group1_16bit_1 { + status = "okay"; + resource-type = ; + resource-instance = <0>; + resource-channel = <7>; + clock-div = <9600>; +}; + +&pinctrl { + p16_7_pwm0_7: p16_7_pwm0_7 { + drive-push-pull; + }; +}; diff --git a/samples/basic/blinky_pwm/boards/kit_pse84_eval_pse846gps2dbzc4a_m33.overlay b/samples/basic/blinky_pwm/boards/kit_pse84_eval_pse846gps2dbzc4a_m33.overlay new file mode 100644 index 000000000000..533ab3852f0e --- /dev/null +++ b/samples/basic/blinky_pwm/boards/kit_pse84_eval_pse846gps2dbzc4a_m33.overlay @@ -0,0 +1,8 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "kit_pse84_eval_common.overlay" diff --git a/samples/basic/blinky_pwm/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.overlay b/samples/basic/blinky_pwm/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.overlay new file mode 100644 index 000000000000..533ab3852f0e --- /dev/null +++ b/samples/basic/blinky_pwm/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.overlay @@ -0,0 +1,8 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "kit_pse84_eval_common.overlay" diff --git a/samples/basic/fade_led/boards/kit_pse84_eval_common.overlay b/samples/basic/fade_led/boards/kit_pse84_eval_common.overlay new file mode 100644 index 000000000000..396f1cd9bc37 --- /dev/null +++ b/samples/basic/fade_led/boards/kit_pse84_eval_common.overlay @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + aliases { + pwm-led0 = &pwm_led0; + }; + + pwmleds { + compatible = "pwm-leds"; + + pwm_led0: pwm_led_0 { + pwms = <&pwm0_7 0 PWM_MSEC(20) PWM_POLARITY_INVERTED>; + label = "PWM LED"; + }; + + status = "okay"; + }; +}; + +&tcpwm0_7 { + status = "okay"; + + pwm0_7: pwm0_7 { + status = "okay"; + clocks = <&peri0_group1_16bit_1>; + pinctrl-0 = <&p16_7_pwm0_7>; + pinctrl-names = "default"; + }; +}; + +&peri0_group1_16bit_1 { + status = "okay"; + resource-type = ; + resource-instance = <0>; + resource-channel = <7>; + clock-div = <9600>; +}; + +&pinctrl { + p16_7_pwm0_7: p16_7_pwm0_7 { + drive-push-pull; + }; +}; diff --git a/samples/basic/fade_led/boards/kit_pse84_eval_pse846gps2dbzc4a_m33.overlay b/samples/basic/fade_led/boards/kit_pse84_eval_pse846gps2dbzc4a_m33.overlay new file mode 100644 index 000000000000..533ab3852f0e --- /dev/null +++ b/samples/basic/fade_led/boards/kit_pse84_eval_pse846gps2dbzc4a_m33.overlay @@ -0,0 +1,8 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "kit_pse84_eval_common.overlay" diff --git a/samples/basic/fade_led/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.overlay b/samples/basic/fade_led/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.overlay new file mode 100644 index 000000000000..533ab3852f0e --- /dev/null +++ b/samples/basic/fade_led/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.overlay @@ -0,0 +1,8 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "kit_pse84_eval_common.overlay" From 3f916f3b96ea0982a5a20c87b616819e11aec734 Mon Sep 17 00:00:00 2001 From: McAtee Maxwell Date: Wed, 15 Oct 2025 15:44:20 -0700 Subject: [PATCH 0476/3659] tests: pwm: add Infineon kit_pse84_eval - Add overlay files for the pwm_api and pwm_gpio_loopback tests - Update platform_allow for pwm_gpio_loopback Signed-off-by: McAtee Maxwell --- .../boards/kit_pse84_eval_common.overlay | 40 +++++++++++ ...it_pse84_eval_pse846gps2dbzc4a_m33.overlay | 8 +++ ...it_pse84_eval_pse846gps2dbzc4a_m55.overlay | 8 +++ .../boards/kit_pse84_eval_common.overlay | 71 +++++++++++++++++++ ...it_pse84_eval_pse846gps2dbzc4a_m33.overlay | 8 +++ ...it_pse84_eval_pse846gps2dbzc4a_m55.overlay | 8 +++ .../pwm/pwm_gpio_loopback/testcase.yaml | 2 + 7 files changed, 145 insertions(+) create mode 100644 tests/drivers/pwm/pwm_api/boards/kit_pse84_eval_common.overlay create mode 100644 tests/drivers/pwm/pwm_api/boards/kit_pse84_eval_pse846gps2dbzc4a_m33.overlay create mode 100644 tests/drivers/pwm/pwm_api/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.overlay create mode 100644 tests/drivers/pwm/pwm_gpio_loopback/boards/kit_pse84_eval_common.overlay create mode 100644 tests/drivers/pwm/pwm_gpio_loopback/boards/kit_pse84_eval_pse846gps2dbzc4a_m33.overlay create mode 100644 tests/drivers/pwm/pwm_gpio_loopback/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.overlay diff --git a/tests/drivers/pwm/pwm_api/boards/kit_pse84_eval_common.overlay b/tests/drivers/pwm/pwm_api/boards/kit_pse84_eval_common.overlay new file mode 100644 index 000000000000..a0777d90f79a --- /dev/null +++ b/tests/drivers/pwm/pwm_api/boards/kit_pse84_eval_common.overlay @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + aliases { + pwm-test = &pwm0_7; + }; +}; + +&tcpwm0_7 { + status = "okay"; + + pwm0_7: pwm0_7 { + status = "okay"; + clocks = <&peri0_group1_16bit_1>; + pinctrl-0 = <&p16_7_pwm0_7>; + pinctrl-names = "default"; + }; +}; + +&peri0_group1_16bit_1 { + status = "okay"; + resource-type = ; + resource-instance = <0>; + resource-channel = <7>; + clock-div = <9600>; +}; + +&pinctrl { + p16_7_pwm0_7: p16_7_pwm0_7 { + drive-push-pull; + }; +}; diff --git a/tests/drivers/pwm/pwm_api/boards/kit_pse84_eval_pse846gps2dbzc4a_m33.overlay b/tests/drivers/pwm/pwm_api/boards/kit_pse84_eval_pse846gps2dbzc4a_m33.overlay new file mode 100644 index 000000000000..533ab3852f0e --- /dev/null +++ b/tests/drivers/pwm/pwm_api/boards/kit_pse84_eval_pse846gps2dbzc4a_m33.overlay @@ -0,0 +1,8 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "kit_pse84_eval_common.overlay" diff --git a/tests/drivers/pwm/pwm_api/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.overlay b/tests/drivers/pwm/pwm_api/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.overlay new file mode 100644 index 000000000000..533ab3852f0e --- /dev/null +++ b/tests/drivers/pwm/pwm_api/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.overlay @@ -0,0 +1,8 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "kit_pse84_eval_common.overlay" diff --git a/tests/drivers/pwm/pwm_gpio_loopback/boards/kit_pse84_eval_common.overlay b/tests/drivers/pwm/pwm_gpio_loopback/boards/kit_pse84_eval_common.overlay new file mode 100644 index 000000000000..ad6c563a9ae7 --- /dev/null +++ b/tests/drivers/pwm/pwm_gpio_loopback/boards/kit_pse84_eval_common.overlay @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + zephyr,user { + pwms = <&pwm0_1 0 PWM_MSEC(20) (PWM_POLARITY_NORMAL | PWM_IFX_TCPWM_OUTPUT_HIGHZ)>, + <&pwm1_19 1 PWM_MSEC(20) (PWM_POLARITY_NORMAL | PWM_IFX_TCPWM_OUTPUT_HIGHZ)>; + gpios = <&gpio_prt16 2 GPIO_ACTIVE_HIGH>, + <&gpio_prt15 3 GPIO_ACTIVE_HIGH>; + }; +}; + +&tcpwm0_1 { + status = "okay"; + + pwm0_1: pwm0_1 { + status = "okay"; + clocks = <&peri0_group1_16bit_1>; + pinctrl-0 = <&p16_1_pwm0_1>; + pinctrl-names = "default"; + }; +}; + +&peri0_group1_16bit_1 { + status = "okay"; + resource-type = ; + resource-instance = <0>; + resource-channel = <1>; + clock-div = <9600>; +}; + +&tcpwm1_19 { + status = "okay"; + + pwm1_19: pwm1_19 { + status = "okay"; + clocks = <&peri0_group1_16bit_2>; + pinctrl-0 = <&p15_2_pwm1_19>; + pinctrl-names = "default"; + }; +}; + +&peri0_group1_16bit_2 { + status = "okay"; + resource-type = ; + resource-instance = <1>; + resource-channel = <19>; + clock-div = <9600>; +}; + +&pinctrl { + p15_2_pwm1_19: p15_2_pwm1_19 { + drive-push-pull; + }; + + p16_1_pwm0_1: p16_1_pwm0_1 { + drive-push-pull; + }; +}; + +/* gpio_prt16 is already enabled in boards\infineon\kit_pse84_eval\kit_pse84_eval_common.dtsi */ +&gpio_prt15 { + status = "okay"; +}; diff --git a/tests/drivers/pwm/pwm_gpio_loopback/boards/kit_pse84_eval_pse846gps2dbzc4a_m33.overlay b/tests/drivers/pwm/pwm_gpio_loopback/boards/kit_pse84_eval_pse846gps2dbzc4a_m33.overlay new file mode 100644 index 000000000000..533ab3852f0e --- /dev/null +++ b/tests/drivers/pwm/pwm_gpio_loopback/boards/kit_pse84_eval_pse846gps2dbzc4a_m33.overlay @@ -0,0 +1,8 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "kit_pse84_eval_common.overlay" diff --git a/tests/drivers/pwm/pwm_gpio_loopback/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.overlay b/tests/drivers/pwm/pwm_gpio_loopback/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.overlay new file mode 100644 index 000000000000..533ab3852f0e --- /dev/null +++ b/tests/drivers/pwm/pwm_gpio_loopback/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.overlay @@ -0,0 +1,8 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "kit_pse84_eval_common.overlay" diff --git a/tests/drivers/pwm/pwm_gpio_loopback/testcase.yaml b/tests/drivers/pwm/pwm_gpio_loopback/testcase.yaml index 4c8ef496b974..6869d6cf9b84 100644 --- a/tests/drivers/pwm/pwm_gpio_loopback/testcase.yaml +++ b/tests/drivers/pwm/pwm_gpio_loopback/testcase.yaml @@ -34,6 +34,8 @@ tests: - cyw920829m2evk_02/cyw20829b1340 - cyw920829m2evk_02/cyw20829b1010 - cyw920829m2evk_02/cyw20829b0lkml + - kit_pse84_eval/pse846gps2dbzc4a/m33 + - kit_pse84_eval/pse846gps2dbzc4a/m55 drivers.pwm.gpio_loopback_tc0.mchp: extra_args: DTC_OVERLAY_FILE="boards/microchip/sam_e54_xpro_tc0.overlay" platform_allow: From a40956ffdf4373f359a58d5a4626d90ef3d5d599 Mon Sep 17 00:00:00 2001 From: McAtee Maxwell Date: Wed, 15 Oct 2025 15:45:55 -0700 Subject: [PATCH 0477/3659] dts: Add peri-div clock definitions for cyw20829 soc series - Add dts blocks for the peri-div clock instances on cyw20829 Signed-off-by: McAtee Maxwell --- .../cat1b/cyw20829/system_clocks.dtsi | 168 +++++++++++++++++- 1 file changed, 167 insertions(+), 1 deletion(-) diff --git a/dts/arm/infineon/cat1b/cyw20829/system_clocks.dtsi b/dts/arm/infineon/cat1b/cyw20829/system_clocks.dtsi index e7c8e156610b..380041f46352 100644 --- a/dts/arm/infineon/cat1b/cyw20829/system_clocks.dtsi +++ b/dts/arm/infineon/cat1b/cyw20829/system_clocks.dtsi @@ -5,7 +5,12 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "clock_source_def.h" +#define DIV_8_BIT 00 +#define DIV_16_BIT 01 +#define DIV_16_5_BIT 02 +#define DIV_24_5_BIT 03 + +#include / { srss_power: srss_power { @@ -142,4 +147,165 @@ status = "okay"; }; }; + + peri0: peri0 { + /* Peripheral 0, Clock Group 0 */ + /* 24.5-bit */ + peri0_group0_24_5bit_0: peri0_group0_24_5bit_0 { + #clock-cells = <0>; + compatible = "infineon,peri-div"; + peri-group = [00 00]; /* inst#, group# */ + div-type = ; + channel = <0>; + clock-div = <1>; + status = "disabled"; + }; + + /* Peripheral 0, Clock Group 1 */ + /* 8-bit */ + peri0_group1_8bit_0: peri0_group1_8bit_0 { + #clock-cells = <0>; + compatible = "infineon,peri-div"; + peri-group = [00 01]; /* inst#, group# */ + div-type = ; + channel = <0>; + clock-div = <1>; + status = "disabled"; + }; + + peri0_group1_8bit_1: peri0_group1_8bit_1 { + #clock-cells = <0>; + compatible = "infineon,peri-div"; + peri-group = [00 01]; /* inst#, group# */ + div-type = ; + channel = <1>; + clock-div = <1>; + status = "disabled"; + }; + + peri0_group1_8bit_2: peri0_group1_8bit_2 { + #clock-cells = <0>; + compatible = "infineon,peri-div"; + peri-group = [00 01]; /* inst#, group# */ + div-type = ; + channel = <2>; + clock-div = <1>; + status = "disabled"; + }; + + peri0_group1_8bit_3: peri0_group1_8bit_3 { + #clock-cells = <0>; + compatible = "infineon,peri-div"; + peri-group = [00 01]; /* inst#, group# */ + div-type = ; + channel = <3>; + clock-div = <1>; + status = "disabled"; + }; + + peri0_group1_8bit_4: peri0_group1_8bit_4 { + #clock-cells = <0>; + compatible = "infineon,peri-div"; + peri-group = [00 01]; /* inst#, group# */ + div-type = ; + channel = <4>; + clock-div = <1>; + status = "disabled"; + }; + + /* 16-bit */ + peri0_group1_16bit_0: peri0_group1_16bit_0 { + #clock-cells = <0>; + compatible = "infineon,peri-div"; + peri-group = [00 01]; /* inst#, group# */ + div-type = ; + channel = <0>; + clock-div = <1>; + status = "disabled"; + }; + + peri0_group1_16bit_1: peri0_group1_16bit_1 { + #clock-cells = <0>; + compatible = "infineon,peri-div"; + peri-group = [00 01]; /* inst#, group# */ + div-type = ; + channel = <1>; + clock-div = <1>; + status = "disabled"; + }; + + peri0_group1_16bit_2: peri0_group1_16bit_2 { + #clock-cells = <0>; + compatible = "infineon,peri-div"; + peri-group = [00 01]; /* inst#, group# */ + div-type = ; + channel = <2>; + clock-div = <1>; + status = "disabled"; + }; + + peri0_group1_16bit_3: peri0_group1_16bit_3 { + #clock-cells = <0>; + compatible = "infineon,peri-div"; + peri-group = [00 01]; /* inst#, group# */ + div-type = ; + channel = <3>; + clock-div = <1>; + status = "disabled"; + }; + + /* 16.5-bit */ + peri0_group1_16_5bit_0: peri0_group1_16_5bit_0 { + #clock-cells = <0>; + compatible = "infineon,peri-div"; + peri-group = [00 01]; /* inst#, group# */ + div-type = ; + channel = <0>; + clock-div = <1>; + status = "disabled"; + }; + + peri0_group1_16_5bit_1: peri0_group1_16_5bit_1 { + #clock-cells = <0>; + compatible = "infineon,peri-div"; + peri-group = [00 01]; /* inst#, group# */ + div-type = ; + channel = <1>; + clock-div = <1>; + status = "disabled"; + }; + + /* 24.5-bit */ + peri0_group1_24_5bit_0: peri0_group1_24_5bit_0 { + #clock-cells = <0>; + compatible = "infineon,peri-div"; + peri-group = [00 01]; /* inst#, group# */ + div-type = ; + channel = <0>; + clock-div = <1>; + status = "disabled"; + }; + + /* Peripheral 0, Clock Group 3 */ + /* 16.5-bit */ + peri0_group3_16_5bit_0: peri0_group3_16_5bit_0 { + #clock-cells = <0>; + compatible = "infineon,peri-div"; + peri-group = [00 03]; /* inst#, group# */ + div-type = ; + channel = <0>; + clock-div = <1>; + status = "disabled"; + }; + + peri0_group3_16_5bit_1: peri0_group3_16_5bit_1 { + #clock-cells = <0>; + compatible = "infineon,peri-div"; + peri-group = [00 03]; /* inst#, group# */ + div-type = ; + channel = <1>; + clock-div = <1>; + status = "disabled"; + }; + }; }; From 11472639f7699cdf12cd4cbfe703fcf81a3778a8 Mon Sep 17 00:00:00 2001 From: McAtee Maxwell Date: Wed, 15 Oct 2025 15:47:21 -0700 Subject: [PATCH 0478/3659] samples: pwm: update Infineon cyw920829m2evk_02 overlays - Update overlay files for the blinky_pwm and fade_led samples Signed-off-by: McAtee Maxwell --- .../boards/cyw920829m2evk_02_common.overlay | 12 +++++++--- .../boards/cyw920829m2evk_02_common.overlay | 24 ++++++++++++++----- 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/samples/basic/blinky_pwm/boards/cyw920829m2evk_02_common.overlay b/samples/basic/blinky_pwm/boards/cyw920829m2evk_02_common.overlay index 16dc55066bb6..99e56549420d 100644 --- a/samples/basic/blinky_pwm/boards/cyw920829m2evk_02_common.overlay +++ b/samples/basic/blinky_pwm/boards/cyw920829m2evk_02_common.overlay @@ -25,17 +25,23 @@ &tcpwm0_0 { status = "okay"; - divider-type = ; - divider-sel = <1>; - divider-val = <9599>; pwm0_0: pwm0_0 { status = "okay"; + clocks = <&peri0_group1_16bit_0>; pinctrl-0 = <&p1_1_pwm0_0>; pinctrl-names = "default"; }; }; +&peri0_group1_16bit_0 { + status = "okay"; + resource-type = ; + resource-instance = <0>; + resource-channel = <0>; + clock-div = <9600>; +}; + &pinctrl { p1_1_pwm0_0: p1_1_pwm0_0 { drive-push-pull; diff --git a/samples/basic/fade_led/boards/cyw920829m2evk_02_common.overlay b/samples/basic/fade_led/boards/cyw920829m2evk_02_common.overlay index 4754025df75d..dca245a622b7 100644 --- a/samples/basic/fade_led/boards/cyw920829m2evk_02_common.overlay +++ b/samples/basic/fade_led/boards/cyw920829m2evk_02_common.overlay @@ -31,30 +31,42 @@ &tcpwm0_0 { status = "okay"; - divider-type = ; - divider-sel = <1>; - divider-val = <9599>; pwm0_0: pwm0_0 { status = "okay"; + clocks = <&peri0_group1_16bit_0>; pinctrl-0 = <&p1_1_pwm0_0>; pinctrl-names = "default"; }; }; +&peri0_group1_16bit_0 { + status = "okay"; + resource-type = ; + resource-instance = <0>; + resource-channel = <0>; + clock-div = <9600>; +}; + &tcpwm1_5 { status = "okay"; - divider-type = ; - divider-sel = <1>; - divider-val = <9599>; pwm1_5: pwm1_5 { status = "okay"; + clocks = <&peri0_group1_16bit_1>; pinctrl-0 = <&p5_2_pwm1_5>; pinctrl-names = "default"; }; }; +&peri0_group1_16bit_1 { + status = "okay"; + resource-type = ; + resource-instance = <1>; + resource-channel = <5>; + clock-div = <9600>; +}; + &pinctrl { p1_1_pwm0_0: p1_1_pwm0_0 { drive-push-pull; From 4d64e59f2c8e588e3143c1ee2571973b8c6347c3 Mon Sep 17 00:00:00 2001 From: McAtee Maxwell Date: Wed, 15 Oct 2025 15:48:54 -0700 Subject: [PATCH 0479/3659] tests: pwm: update Infineon cyw920829m2evk_02 overlays - Update overlay files for the pwm_api and pwm_gpio_loopback tests Signed-off-by: McAtee Maxwell --- .../boards/cyw920829m2evk_02_common.overlay | 12 +++++++--- .../boards/cyw920829m2evk_02_common.overlay | 24 ++++++++++++++----- 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/tests/drivers/pwm/pwm_api/boards/cyw920829m2evk_02_common.overlay b/tests/drivers/pwm/pwm_api/boards/cyw920829m2evk_02_common.overlay index 33386db01001..827ca136a8b0 100644 --- a/tests/drivers/pwm/pwm_api/boards/cyw920829m2evk_02_common.overlay +++ b/tests/drivers/pwm/pwm_api/boards/cyw920829m2evk_02_common.overlay @@ -16,17 +16,23 @@ &tcpwm0_0 { status = "okay"; - divider-type = ; - divider-sel = <1>; - divider-val = <9599>; pwm0_0: pwm0_0 { status = "okay"; + clocks = <&peri0_group1_16bit_0>; pinctrl-0 = <&p3_4_pwm0_0>; pinctrl-names = "default"; }; }; +&peri0_group1_16bit_0 { + status = "okay"; + resource-type = ; + resource-instance = <0>; + resource-channel = <0>; + clock-div = <9600>; +}; + &pinctrl { p3_4_pwm0_0: p3_4_pwm0_0 { drive-push-pull; diff --git a/tests/drivers/pwm/pwm_gpio_loopback/boards/cyw920829m2evk_02_common.overlay b/tests/drivers/pwm/pwm_gpio_loopback/boards/cyw920829m2evk_02_common.overlay index 20ee0187daec..d260c0f17b78 100644 --- a/tests/drivers/pwm/pwm_gpio_loopback/boards/cyw920829m2evk_02_common.overlay +++ b/tests/drivers/pwm/pwm_gpio_loopback/boards/cyw920829m2evk_02_common.overlay @@ -19,30 +19,42 @@ &tcpwm0_1 { status = "okay"; - divider-type = ; - divider-sel = <1>; - divider-val = <9599>; pwm0_1: pwm0_1 { status = "okay"; + clocks = <&peri0_group1_16bit_0>; pinctrl-0 = <&p3_6_pwm0_1>; pinctrl-names = "default"; }; }; +&peri0_group1_16bit_0 { + status = "okay"; + resource-type = ; + resource-instance = <0>; + resource-channel = <1>; + clock-div = <9600>; +}; + &tcpwm1_0 { status = "okay"; - divider-type = ; - divider-sel = <1>; - divider-val = <9599>; pwm1_0: pwm1_0 { status = "okay"; + clocks = <&peri0_group1_16bit_1>; pinctrl-0 = <&p0_1_pwm1_0>; pinctrl-names = "default"; }; }; +&peri0_group1_16bit_1 { + status = "okay"; + resource-type = ; + resource-instance = <1>; + resource-channel = <0>; + clock-div = <9600>; +}; + &pinctrl { p3_6_pwm0_1: p3_6_pwm0_1 { drive-push-pull; From 9d181c561eafc0a30673a36bbbdb17ba4e731cde Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Wed, 5 Nov 2025 10:51:30 -0800 Subject: [PATCH 0480/3659] serial: uart_bitbang: fix incorrect callback device When doing the callback, it should pass it the UART device pointer. So fix that. Fixes #98229 Signed-off-by: Daniel Leung --- drivers/serial/uart_bitbang.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/serial/uart_bitbang.c b/drivers/serial/uart_bitbang.c index 9908e5362bab..02e87a5c1fa5 100644 --- a/drivers/serial/uart_bitbang.c +++ b/drivers/serial/uart_bitbang.c @@ -187,7 +187,7 @@ static void uart_bitbang_rx_counter_top_interrupt(const struct device *dev, void #ifdef CONFIG_UART_INTERRUPT_DRIVEN if ((data->user_cb) && (data->irq & UART_BITBANG_IRQ_PE)) { - data->user_cb(dev, data->user_data); + data->user_cb(uart_dev, data->user_data); } #endif /* CONFIG_UART_INTERRUPT_DRIVEN */ @@ -200,7 +200,7 @@ static void uart_bitbang_rx_counter_top_interrupt(const struct device *dev, void #ifdef CONFIG_UART_INTERRUPT_DRIVEN if ((data->user_cb) && (data->irq & UART_BITBANG_IRQ_RXNE)) { - data->user_cb(dev, data->user_data); + data->user_cb(uart_dev, data->user_data); } #endif /* CONFIG_UART_INTERRUPT_DRIVEN */ } @@ -287,7 +287,7 @@ static void uart_bitbang_tx_counter_top_interrupt(const struct device *dev, void } #ifdef CONFIG_UART_INTERRUPT_DRIVEN if ((data->user_cb) && (data->irq & UART_BITBANG_IRQ_TC)) { - data->user_cb(dev, data->user_data); + data->user_cb(uart_dev, data->user_data); } #endif /* CONFIG_UART_INTERRUPT_DRIVEN */ } From 8292cc4eb8bdb6579be1caf126602d3d99ed9800 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 14 Nov 2025 10:45:32 +0100 Subject: [PATCH 0481/3659] drivers: clock_control nrf_lfclk: patch clock option order The clock options used within the driver are supposed to be ordered from lowest to highest power consumption, so the lowest/default option is the most power efficient. The order was reversed to make the init code of the lfclk a bit simpler, and this was accounted for in the clock option lookup function. However, the common nrf clock control request/release feature would request the lowest index, not the lowest clock option, so the lfclk would default to its highest power consumption mode. The clock option init and lookup has been refactored to be sorted from lowest to highest power consumption, and comments have been adjusted accordingly. Signed-off-by: Bjarki Arge Andreasen --- .../clock_control/clock_control_nrf_lfclk.c | 104 +++++++++--------- 1 file changed, 55 insertions(+), 49 deletions(-) diff --git a/drivers/clock_control/clock_control_nrf_lfclk.c b/drivers/clock_control/clock_control_nrf_lfclk.c index 9551fb4e6361..dbf7f66e2e25 100644 --- a/drivers/clock_control/clock_control_nrf_lfclk.c +++ b/drivers/clock_control/clock_control_nrf_lfclk.c @@ -25,38 +25,25 @@ BUILD_ASSERT(DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) == 1, #define LFCLK_LFRC_STARTUP_TIME_US DT_INST_PROP(0, lfrc_startup_time_us) #define LFCLK_MAX_OPTS 4 -#define LFCLK_DEF_OPTS 2 #define NRFS_CLOCK_TIMEOUT K_MSEC(CONFIG_CLOCK_CONTROL_NRF_LFCLK_CLOCK_TIMEOUT_MS) #define BICR (NRF_BICR_Type *)DT_REG_ADDR(DT_NODELABEL(bicr)) -/* Clock options sorted from highest to lowest power consumption. - * - Clock synthesized from a high frequency clock +/* + * Clock options sorted from lowest to highest power consumption. If clock option + * is not available it is not included. + * - External sine or square wave + * - XTAL low precision + * - XTAL high precision * - Internal RC oscillator - * - External clock. These are inserted into the list at driver initialization. - * Set to one of the following: - * - XTAL. Low or High precision - * - External sine or square wave + * - Clock synthesized from a high frequency clock */ static struct clock_options { uint16_t accuracy : 15; uint16_t precision : 1; nrfs_clock_src_t src; -} clock_options[LFCLK_MAX_OPTS] = { - { - /* NRFS will request FLL16M use HFXO in bypass mode if SYNTH src is used */ - .accuracy = LFCLK_HFXO_ACCURACY, - .precision = 1, - .src = NRFS_CLOCK_SRC_LFCLK_SYNTH, - }, - { - .accuracy = LFCLK_LFRC_ACCURACY, - .precision = 0, - .src = NRFS_CLOCK_SRC_LFCLK_LFRC, - }, - /* Remaining options are populated on lfclk_init */ -}; +} clock_options[LFCLK_MAX_OPTS]; struct lfclk_dev_data { STRUCT_CLOCK_CONFIG(lfclk, ARRAY_SIZE(clock_options)) clk_cfg; @@ -161,7 +148,7 @@ static int lfclk_resolve_spec_to_idx(const struct device *dev, ? dev_data->max_accuracy : req_spec->accuracy; - for (int i = dev_data->clock_options_cnt - 1; i >= 0; --i) { + for (int i = 0; i < dev_data->clock_options_cnt; i++) { /* Iterate to a more power hungry and accurate clock source * If the requested accuracy is higher (lower ppm) than what * the clock source can provide. @@ -331,15 +318,17 @@ static int api_get_rate_lfclk(const struct device *dev, static int lfclk_init(const struct device *dev) { struct lfclk_dev_data *dev_data = dev->data; - nrf_bicr_lfosc_mode_t lfosc_mode; nrfs_err_t res; + int ret; + nrf_bicr_lfosc_mode_t lfosc_mode; + struct clock_options *clock_option; res = nrfs_clock_init(clock_evt_handler); if (res != NRFS_SUCCESS) { return -EIO; } - dev_data->clock_options_cnt = LFCLK_DEF_OPTS; + dev_data->clock_options_cnt = 0; lfosc_mode = nrf_bicr_lfosc_mode_get(BICR); @@ -347,8 +336,6 @@ static int lfclk_init(const struct device *dev) lfosc_mode == NRF_BICR_LFOSC_MODE_DISABLED) { dev_data->max_accuracy = LFCLK_HFXO_ACCURACY; } else { - int ret; - ret = lfosc_get_accuracy(&dev_data->max_accuracy); if (ret < 0) { LOG_ERR("LFOSC enabled with invalid accuracy"); @@ -357,34 +344,41 @@ static int lfclk_init(const struct device *dev) switch (lfosc_mode) { case NRF_BICR_LFOSC_MODE_CRYSTAL: - clock_options[LFCLK_MAX_OPTS - 1].accuracy = dev_data->max_accuracy; - clock_options[LFCLK_MAX_OPTS - 1].precision = 0; - clock_options[LFCLK_MAX_OPTS - 1].src = NRFS_CLOCK_SRC_LFCLK_XO_PIERCE; - - clock_options[LFCLK_MAX_OPTS - 2].accuracy = dev_data->max_accuracy; - clock_options[LFCLK_MAX_OPTS - 2].precision = 1; - clock_options[LFCLK_MAX_OPTS - 2].src = NRFS_CLOCK_SRC_LFCLK_XO_PIERCE_HP; - - dev_data->clock_options_cnt += 2; + clock_option = &clock_options[dev_data->clock_options_cnt]; + clock_option->accuracy = dev_data->max_accuracy; + clock_option->precision = 0; + clock_option->src = NRFS_CLOCK_SRC_LFCLK_XO_PIERCE; + dev_data->clock_options_cnt++; + + clock_option = &clock_options[dev_data->clock_options_cnt]; + clock_option->accuracy = dev_data->max_accuracy; + clock_option->precision = 1; + clock_option->src = NRFS_CLOCK_SRC_LFCLK_XO_PIERCE_HP; + dev_data->clock_options_cnt++; break; - case NRF_BICR_LFOSC_MODE_EXTSINE: - clock_options[LFCLK_MAX_OPTS - 1].accuracy = dev_data->max_accuracy; - clock_options[LFCLK_MAX_OPTS - 1].precision = 0; - clock_options[LFCLK_MAX_OPTS - 1].src = NRFS_CLOCK_SRC_LFCLK_XO_EXT_SINE; - clock_options[LFCLK_MAX_OPTS - 2].accuracy = dev_data->max_accuracy; - clock_options[LFCLK_MAX_OPTS - 2].precision = 1; - clock_options[LFCLK_MAX_OPTS - 2].src = NRFS_CLOCK_SRC_LFCLK_XO_EXT_SINE_HP; - - dev_data->clock_options_cnt += 2; + case NRF_BICR_LFOSC_MODE_EXTSINE: + clock_option = &clock_options[dev_data->clock_options_cnt]; + clock_option->accuracy = dev_data->max_accuracy; + clock_option->precision = 0; + clock_option->src = NRFS_CLOCK_SRC_LFCLK_XO_EXT_SINE; + dev_data->clock_options_cnt++; + + clock_option = &clock_options[dev_data->clock_options_cnt]; + clock_option->accuracy = dev_data->max_accuracy; + clock_option->precision = 1; + clock_option->src = NRFS_CLOCK_SRC_LFCLK_XO_EXT_SINE_HP; + dev_data->clock_options_cnt++; break; - case NRF_BICR_LFOSC_MODE_EXTSQUARE: - clock_options[LFCLK_MAX_OPTS - 2].accuracy = dev_data->max_accuracy; - clock_options[LFCLK_MAX_OPTS - 2].precision = 0; - clock_options[LFCLK_MAX_OPTS - 2].src = NRFS_CLOCK_SRC_LFCLK_XO_EXT_SQUARE; - dev_data->clock_options_cnt += 1; + case NRF_BICR_LFOSC_MODE_EXTSQUARE: + clock_option = &clock_options[dev_data->clock_options_cnt]; + clock_option->accuracy = dev_data->max_accuracy; + clock_option->precision = 0; + clock_option->src = NRFS_CLOCK_SRC_LFCLK_XO_EXT_SQUARE; + dev_data->clock_options_cnt++; break; + default: LOG_ERR("Unexpected LFOSC mode"); return -EINVAL; @@ -398,6 +392,18 @@ static int lfclk_init(const struct device *dev) } } + clock_option = &clock_options[dev_data->clock_options_cnt]; + clock_option->accuracy = LFCLK_LFRC_ACCURACY; + clock_option->precision = 0; + clock_option->src = NRFS_CLOCK_SRC_LFCLK_LFRC; + dev_data->clock_options_cnt++; + + clock_option = &clock_options[dev_data->clock_options_cnt]; + clock_option->accuracy = LFCLK_HFXO_ACCURACY; + clock_option->precision = 1; + clock_option->src = NRFS_CLOCK_SRC_LFCLK_SYNTH; + dev_data->clock_options_cnt++; + dev_data->hfxo_startup_time_us = nrf_bicr_hfxo_startup_time_us_get(BICR); if (dev_data->hfxo_startup_time_us == NRF_BICR_HFXO_STARTUP_TIME_UNCONFIGURED) { LOG_ERR("BICR HFXO startup time invalid"); From 6fdc675eaed0f811b7af078c2def948ae68593dd Mon Sep 17 00:00:00 2001 From: Lyle Zhu Date: Fri, 28 Nov 2025 18:18:06 +0800 Subject: [PATCH 0482/3659] tests: Bluetooth: Classic: Fix sm_init_035 failure issue For the case sm_init_035, the similar issue also be found. The message `Enter 16 digits wide PIN code for` may be printed after the shell prompt. The assert issue also be found in this case. For the case sm_init_035, check the message `Enter 16 digits wide PIN code for` in the captured log. If it is not found, wait the message until timeout. Signed-off-by: Lyle Zhu --- tests/bluetooth/classic/smp_general/pytest/test_smp.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/bluetooth/classic/smp_general/pytest/test_smp.py b/tests/bluetooth/classic/smp_general/pytest/test_smp.py index b046b1743fce..3714e2be74d5 100644 --- a/tests/bluetooth/classic/smp_general/pytest/test_smp.py +++ b/tests/bluetooth/classic/smp_general/pytest/test_smp.py @@ -1814,6 +1814,12 @@ async def get_string(self, max_length: int) -> str | None: ) lines = shell.exec_command(f"l2cap_br connect {format(l2cap_server_psm, 'x')} sec 3") found = check_shell_response(lines, f"Enter 16 digits wide PIN code for {bumble_address}") + if not found: + found, _ = await wait_for_shell_response( + dut, + [f"Enter 16 digits wide PIN code for {bumble_address}"], + ) + assert found is True await send_cmd_to_iut(shell, dut, f"br auth-pincode {pin_code}", None) From a9269f201218c77f6880429a337aee2629b766f7 Mon Sep 17 00:00:00 2001 From: Lyle Zhu Date: Wed, 26 Nov 2025 16:58:10 +0800 Subject: [PATCH 0483/3659] Bluetooth: Classic: OBEX: Fix unchecked return value issue Check the return value of the function `atomic_cas()`. If the new value cannot be set for the OBEX server, return the error code `BT_OBEX_RSP_CODE_INTER_ERROR`. If the new value cannot be set for the OBEX client, return the error code `-EINVAL`. Fix #100012 Fix #100018 Fix #100019 Fix #100021 Fix #100022 Fix #100023 Signed-off-by: Lyle Zhu --- subsys/bluetooth/host/classic/obex.c | 39 +++++++++++++++++++--------- 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/subsys/bluetooth/host/classic/obex.c b/subsys/bluetooth/host/classic/obex.c index 406783698185..86783b70afcb 100644 --- a/subsys/bluetooth/host/classic/obex.c +++ b/subsys/bluetooth/host/classic/obex.c @@ -351,8 +351,11 @@ static int obex_server_put_common(struct bt_obex_server *server, bool final, uin goto failed; } - if (opcode != req_code) { - atomic_cas(&server->_opcode, opcode, req_code); + if ((opcode != req_code) && !atomic_cas(&server->_opcode, opcode, req_code)) { + LOG_WRN("OP code mismatch %u != %u", (uint8_t)atomic_get(&server->_opcode), + opcode); + rsp_code = BT_OBEX_RSP_CODE_INTER_ERROR; + goto failed; } } @@ -432,8 +435,11 @@ static int obex_server_get_common(struct bt_obex_server *server, bool final, uin goto failed; } - if (opcode != req_code) { - atomic_cas(&server->_opcode, opcode, req_code); + if ((opcode != req_code) && !atomic_cas(&server->_opcode, opcode, req_code)) { + LOG_WRN("OP code mismatch %u != %u", (uint8_t)atomic_get(&server->_opcode), + opcode); + rsp_code = BT_OBEX_RSP_CODE_INTER_ERROR; + goto failed; } } @@ -569,8 +575,11 @@ static int obex_server_action_common(struct bt_obex_server *server, bool final, goto failed; } - if (opcode != req_code) { - atomic_cas(&server->_opcode, opcode, req_code); + if ((opcode != req_code) && !atomic_cas(&server->_opcode, opcode, req_code)) { + LOG_WRN("OP code mismatch %u != %u", (uint8_t)atomic_get(&server->_opcode), + opcode); + rsp_code = BT_OBEX_RSP_CODE_INTER_ERROR; + goto failed; } } @@ -1823,8 +1832,10 @@ int bt_obex_put(struct bt_obex_client *client, bool final, struct net_buf *buf) return -EBUSY; } - if (opcode != req_code) { - atomic_cas(&client->_opcode, opcode, req_code); + if ((opcode != req_code) && !atomic_cas(&client->_opcode, opcode, req_code)) { + LOG_WRN("OP code mismatch %u != %u", (uint8_t)atomic_get(&client->_opcode), + opcode); + return -EINVAL; } } @@ -1958,8 +1969,10 @@ int bt_obex_get(struct bt_obex_client *client, bool final, struct net_buf *buf) return -EBUSY; } - if (opcode != req_code) { - atomic_cas(&client->_opcode, opcode, req_code); + if ((opcode != req_code) && !atomic_cas(&client->_opcode, opcode, req_code)) { + LOG_WRN("OP code mismatch %u != %u", (uint8_t)atomic_get(&client->_opcode), + opcode); + return -EINVAL; } } @@ -2344,8 +2357,10 @@ int bt_obex_action(struct bt_obex_client *client, bool final, struct net_buf *bu return -EBUSY; } - if (opcode != req_code) { - atomic_cas(&client->_opcode, opcode, req_code); + if ((opcode != req_code) && !atomic_cas(&client->_opcode, opcode, req_code)) { + LOG_WRN("OP code mismatch %u != %u", (uint8_t)atomic_get(&client->_opcode), + opcode); + return -EINVAL; } } From 217f8e660b4ed040172bb3feecb1765a8853b06a Mon Sep 17 00:00:00 2001 From: Luis Ubieda Date: Wed, 26 Nov 2025 17:45:49 -0500 Subject: [PATCH 0484/3659] sensor: afbr_s50: Do not cut data-stream due to payload status The payload status is evaluated when decoding, which may indicate sharp distance transitions (from very long to close) and requiring a few more cycles to stabilize. We don't want to stop the data-stream because of these, otherwise the data-stream continuity is compromised. Signed-off-by: Luis Ubieda --- drivers/sensor/broadcom/afbr_s50/afbr_s50.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/sensor/broadcom/afbr_s50/afbr_s50.c b/drivers/sensor/broadcom/afbr_s50/afbr_s50.c index eb91c7e90144..797b0a01c26e 100644 --- a/drivers/sensor/broadcom/afbr_s50/afbr_s50.c +++ b/drivers/sensor/broadcom/afbr_s50/afbr_s50.c @@ -119,7 +119,7 @@ static void data_ready_work_handler(struct rtio_iodev_sqe *iodev_sqe) 0; status = Argus_EvaluateData(data->platform.argus.handle, &edata->payload); - if (status != STATUS_OK || edata->payload.Status != STATUS_OK) { + if (status != STATUS_OK) { LOG_ERR("Data not valid: %d, %d", status, edata->payload.Status); handle_error_on_result(data, -EIO); } From 68ff83079edd03984621367621abea1226e3c5cf Mon Sep 17 00:00:00 2001 From: Lyle Zhu Date: Wed, 19 Nov 2025 20:37:18 +0800 Subject: [PATCH 0485/3659] tests: Bluetooth: Classic: Fix sm_key_persist_004 failure issue For the case sm_key_persist_004, the disconnected event may be printed before the log `Pairings successfully cleared` since there is no order between log `Pairings successfully cleared` and the disconnected event. It causes the script discards the disconnected event in this case and rise the assert issue. For the case sm_key_persist_004, check the disconnected event in the captured log. If it is not found, wait the disconnected event until timeout. Signed-off-by: Lyle Zhu --- .../classic/smp_key_persist/pytest/test_smp.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/tests/bluetooth/classic/smp_key_persist/pytest/test_smp.py b/tests/bluetooth/classic/smp_key_persist/pytest/test_smp.py index 0ba06620be40..f9615c129ea8 100644 --- a/tests/bluetooth/classic/smp_key_persist/pytest/test_smp.py +++ b/tests/bluetooth/classic/smp_key_persist/pytest/test_smp.py @@ -407,9 +407,18 @@ async def sm_key_persist_004(hci_port, shell, dut, address) -> None: device, shell, dut, bumble_address, iut_address ) - await send_cmd_to_iut(shell, dut, "br clear all", "Pairings successfully cleared") + lines = await send_cmd_to_iut( + shell, dut, "br clear all", "Pairings successfully cleared" + ) - await sm_test_initial_disconnect(dut, connection) + disconnected = False + for line in lines: + if "Disconnected:" in line: + disconnected = True + break + + if not disconnected: + await sm_test_initial_disconnect(dut, connection) await sm_test_reboot(shell, dut) From e660314ffedf0715bd95bc6ce4f5e54a5725483b Mon Sep 17 00:00:00 2001 From: Lyle Zhu Date: Wed, 19 Nov 2025 20:26:38 +0800 Subject: [PATCH 0486/3659] tests: Bluetooth: Classic: SDP_S: Reduce time consumption The case `sdp_discover_with_range` will consume much time to exhaustively enumerate all supported attribute id ranges. It will consume much time. Optimize the set of the supported attribute ID ranges to reduce the time consumption. Such as, the discovered attribute ID list is [1, 2, 3, 4, 7, 9, 256]. In the original implementation, the range count is 35511. While in the optimized range count is 105. Signed-off-by: Lyle Zhu --- .../classic/sdp_s/pytest/test_sdp.py | 112 ++++++++++++------ 1 file changed, 73 insertions(+), 39 deletions(-) diff --git a/tests/bluetooth/classic/sdp_s/pytest/test_sdp.py b/tests/bluetooth/classic/sdp_s/pytest/test_sdp.py index 9d2122706d22..866ee34323fe 100644 --- a/tests/bluetooth/classic/sdp_s/pytest/test_sdp.py +++ b/tests/bluetooth/classic/sdp_s/pytest/test_sdp.py @@ -325,7 +325,7 @@ async def sdp_discover_with_range(hci_port, shell, address) -> None: hci_transport.sink, ) - valid_attribute_ids = [] + valid_attr_ids = [] with open("bumble_hci_sdp_s_discover_with_range.log", "wb") as snoop_file: device.host.snooper = BtSnooper(snoop_file) @@ -346,13 +346,16 @@ async def sdp_discover_with_range(hci_port, shell, address) -> None: sdp_client = SDP_Client(connection) await sdp_client.connect() + shell.exec_command("sdp_server register_sdp_all") + shell.exec_command("sdp_server register_sdp_large") + shell.exec_command("sdp_server register_sdp_large_valid") + shell.exec_command("sdp_server register_sdp_uuid128") + logger.info("<<< 1 List all attributes and get all supported attribute ids") search_result = await sdp_client.search_attributes( [BT_L2CAP_PROTOCOL_ID], [SDP_ALL_ATTRIBUTES_RANGE] ) - max_attribute_id = 0 - assert len(search_result) != 0 logger.info('SEARCH RESULTS:') for attribute_list in search_result: @@ -361,42 +364,73 @@ async def sdp_discover_with_range(hci_port, shell, address) -> None: logger.info( ' ' + '\n '.join([attribute.to_string()]) ) - if attribute.id not in valid_attribute_ids: - valid_attribute_ids.append(attribute.id) - if max_attribute_id < attribute.id: - max_attribute_id = attribute.id - - logger.info(f"attribute id list {valid_attribute_ids}") - if (max_attribute_id + 10) <= 0xFFFF: - max_attribute_id += 10 - - for attribute_id_start in range(0, max_attribute_id): - for attribute_id_end in range(attribute_id_start, max_attribute_id): - # List all services in the root browse group - logger.info(f"<<< Service search discovery UUID {BT_L2CAP_PROTOCOL_ID} with " - f"range ({attribute_id_start}, {attribute_id_end})") - search_result = await sdp_client.search_attributes( - [BT_L2CAP_PROTOCOL_ID], [(attribute_id_start, attribute_id_end)] - ) - in_range = False - for id in valid_attribute_ids: - if attribute_id_start <= id <= attribute_id_end: - logger.info(f"({attribute_id_start} {attribute_id_end}) in range") - in_range = True - break - - logger.info('SEARCH RESULTS:') - for attribute_list in search_result: - logger.info('SERVICE:') - logger.info( - ' ' + - '\n'.join([attribute.to_string() for attribute in attribute_list]) - ) - - if in_range: - assert len(search_result) != 0 - else: - assert len(search_result) == 0 + if attribute.id not in valid_attr_ids: + valid_attr_ids.append(attribute.id) + + logger.info(f"attribute id list {valid_attr_ids}") + + valid_attr_ids.sort() + logger.info(f"Sorted attribute id list {valid_attr_ids}") + + range_list = [] + + for _, attr_id_start in enumerate(valid_attr_ids): + for _, attr_id_end in enumerate(valid_attr_ids): + if attr_id_start >= attr_id_end: + continue + + discover_attr_ids = [] + + if attr_id_start > 0: + discover_attr_ids.append(attr_id_start - 1) + discover_attr_ids.append(attr_id_start) + discover_attr_ids.append(attr_id_start + 1) + if attr_id_end > 0: + discover_attr_ids.append(attr_id_end - 1) + discover_attr_ids.append(attr_id_end) + if attr_id_end < 0xFFFF: + discover_attr_ids.append(attr_id_end + 1) + + discover_attr_ids = list(dict.fromkeys(discover_attr_ids)) + discover_attr_ids.sort() + + for _, discover_start in enumerate(discover_attr_ids): + for _, discover_end in enumerate(discover_attr_ids): + if discover_start > discover_end: + continue + + if (discover_start, discover_end) in range_list: + continue + + range_list.append((discover_start, discover_end)) + + # List all services in the root browse group + logger.info(f"<<< Service search discovery UUID {BT_L2CAP_PROTOCOL_ID} " + f"with range ({discover_start}, {discover_end})") + + search_result = await sdp_client.search_attributes( + [BT_L2CAP_PROTOCOL_ID], [(discover_start, discover_end)] + ) + + in_range = False + for id in valid_attr_ids: + if discover_start <= id <= discover_end: + logger.info(f"({discover_start} {discover_end}) in range") + in_range = True + break + + logger.info('SEARCH RESULTS:') + for attr_list in search_result: + logger.info('SERVICE:') + logger.info( + ' ' + '\n'.join([attr.to_string() for attr in attr_list]) + ) + + if in_range: + assert len(search_result) != 0 + else: + assert len(search_result) == 0 + class TestSdpServer: def test_discovery_device(self, sdp_server_dut): From 761fcc8d01c0ae2180c071ab4cce89b198ee23f3 Mon Sep 17 00:00:00 2001 From: Lyle Zhu Date: Wed, 19 Nov 2025 20:10:53 +0800 Subject: [PATCH 0487/3659] tests: Bluetooth: Classic: GAP_S: Fix case tc_gap_s_2 failure issue In the case, when the connection is established on the local side, the test script will require peer device to send ACL disconnection request. But due to the timing issue, the connected event may be not notified on the peer device side when the peer device received the ACL disconnection requirement. The exception will happen. It causes the case to fail. Wait for the connected event of the peer device before sending the ACL disconnection request. Signed-off-by: Lyle Zhu --- tests/bluetooth/classic/gap_s/pytest/test_gap_s.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/bluetooth/classic/gap_s/pytest/test_gap_s.py b/tests/bluetooth/classic/gap_s/pytest/test_gap_s.py index 4e4ec59a542d..f456ab755eab 100644 --- a/tests/bluetooth/classic/gap_s/pytest/test_gap_s.py +++ b/tests/bluetooth/classic/gap_s/pytest/test_gap_s.py @@ -248,6 +248,9 @@ async def tc_gap_s_2(hci_port, shell, dut, address) -> None: await device.connect(dut_address, transport=BT_BR_EDR_TRANSPORT) logger.info('Step 5: DUT accepts connection request') + found, _ = await _wait_for_shell_response(dut, "Connected", max_wait_sec=5) + assert found, "DUT should accept connection request" + # passive logger.info('Step 6: DUT initiates disconnection') From 28bc19beabeb745c069ad6d41578e2e000221219 Mon Sep 17 00:00:00 2001 From: Fabin V Martin Date: Fri, 28 Nov 2025 14:26:15 +0530 Subject: [PATCH 0488/3659] dts: bindings: i2c: add dma properties in i2c yaml add properties for dma support in binding yaml for i2c Signed-off-by: Fabin V Martin --- dts/bindings/i2c/microchip,sercom-g1-i2c.yaml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/dts/bindings/i2c/microchip,sercom-g1-i2c.yaml b/dts/bindings/i2c/microchip,sercom-g1-i2c.yaml index c5a1155d1ce0..cf0ffd4d2206 100644 --- a/dts/bindings/i2c/microchip,sercom-g1-i2c.yaml +++ b/dts/bindings/i2c/microchip,sercom-g1-i2c.yaml @@ -36,3 +36,20 @@ properties: default: 1 description: | Enable (1) or disable (0) runstandby mode for SERCOM I2C. + + dmas: + description: | + Optional TX & RX dma specifiers. Each specifier will have a phandle + reference to the dmac controller, the channel number, and peripheral + trigger source. + + For example dmas for TX, RX on SERCOM3 + dmas = <&dmac 0 0xb>, <&dmac 0 0xa>; + + dma-names: + description: | + Required if the dmas property exists. This should be "tx" and "rx" + to match the dmas property. + + For example + dma-names = "tx", "rx"; From b16b2b2bcb0553a05d5ec5d90a1247f7484fcc24 Mon Sep 17 00:00:00 2001 From: Fabin V Martin Date: Mon, 24 Nov 2025 16:05:37 +0530 Subject: [PATCH 0489/3659] drivers: i2c: microchip: add dma support dma support added for i2c transfer Signed-off-by: Fabin V Martin --- drivers/i2c/Kconfig.mchp | 13 +- drivers/i2c/i2c_mchp_sercom_g1.c | 407 ++++++++++++++++++++++++++++++- 2 files changed, 410 insertions(+), 10 deletions(-) diff --git a/drivers/i2c/Kconfig.mchp b/drivers/i2c/Kconfig.mchp index 98a65ae62fc1..11da41d437f1 100644 --- a/drivers/i2c/Kconfig.mchp +++ b/drivers/i2c/Kconfig.mchp @@ -19,11 +19,22 @@ if I2C_MCHP_SERCOM config I2C_MCHP_INTERRUPT_DRIVEN bool "Interrupt support for Microchip I2C devices" - default y + depends on !I2C_MCHP_DMA_DRIVEN help This enables INTERRUPT driven transactions for the I2C peripheral. interrupt driven mode can be used in blocking & non blocking mode. +config I2C_MCHP_DMA_DRIVEN + bool "DMA support for Microchip I2C devices" + default y + depends on I2C_CALLBACK + depends on DMA + help + This enables DMA driven transactions for the I2C peripheral. + DMA driven mode requires fewer interrupts to handle the + transaction and ensures that high speed modes are not delayed + by data reloading. + config I2C_MCHP_TARGET bool "Target device support for Microchip I2C devices" default y diff --git a/drivers/i2c/i2c_mchp_sercom_g1.c b/drivers/i2c/i2c_mchp_sercom_g1.c index e37e71666a10..34d2c759d138 100644 --- a/drivers/i2c/i2c_mchp_sercom_g1.c +++ b/drivers/i2c/i2c_mchp_sercom_g1.c @@ -10,6 +10,8 @@ #include #include #include +#include +#include #include #include @@ -51,12 +53,25 @@ struct i2c_mchp_clock { clock_control_subsys_t gclk_sys; }; +#ifdef CONFIG_I2C_MCHP_DMA_DRIVEN +struct i2c_mchp_dma { + const struct device *dma_dev; + uint8_t tx_dma_request; + uint8_t tx_dma_channel; + uint8_t rx_dma_request; + uint8_t rx_dma_channel; +}; +#endif /*CONFIG_I2C_MCHP_DMA_DRIVEN*/ + struct i2c_mchp_dev_config { sercom_registers_t *regs; struct i2c_mchp_clock i2c_clock; const struct pinctrl_dev_config *pcfg; uint32_t bitrate; void (*irq_config_func)(const struct device *dev); +#ifdef CONFIG_I2C_MCHP_DMA_DRIVEN + struct i2c_mchp_dma i2c_dma; +#endif /*CONFIG_I2C_MCHP_DMA_DRIVEN*/ uint8_t run_in_standby; }; @@ -86,9 +101,17 @@ struct i2c_mchp_dev_data { struct i2c_target_callbacks target_callbacks; uint8_t rx_tx_data; #endif /*CONFIG_I2C_TARGET*/ +#ifdef CONFIG_I2C_MCHP_DMA_DRIVEN + const struct i2c_mchp_dev_config *cfg; +#endif /*CONFIG_I2C_MCHP_DMA_DRIVEN*/ bool firstReadAfterAddrMatch; }; +#ifdef CONFIG_I2C_MCHP_DMA_DRIVEN +static int i2c_dma_write_config(const struct device *dev); +static int i2c_dma_read_config(const struct device *dev); +#endif /*CONFIG_I2C_MCHP_DMA_DRIVEN*/ + static void i2c_swrst(const struct device *dev) { sercom_registers_t *i2c_regs = ((const struct i2c_mchp_dev_config *)(dev)->config)->regs; @@ -505,11 +528,15 @@ static bool i2c_is_terminate_on_error(const struct device *dev) return false; } + LOG_ERR("I2C error on %s: status=0x%x", dev->name, data->current_msg.status); + i2c_controller_status_clear(dev, data->current_msg.status); i2c_controller_int_disable(dev, SERCOM_I2CM_INTENSET_Msk); i2c_controller_transfer_stop(dev); #ifdef CONFIG_I2C_CALLBACK - data->i2c_async_callback(dev, (int)data->current_msg.status, data->user_data); + if (data->i2c_async_callback != NULL) { + data->i2c_async_callback(dev, (int)data->current_msg.status, data->user_data); + } #else k_sem_give(&data->i2c_sync_sem); #endif /*CONFIG_I2C_CALLBACK*/ @@ -517,11 +544,42 @@ static bool i2c_is_terminate_on_error(const struct device *dev) return true; } +#ifdef CONFIG_I2C_MCHP_DMA_DRIVEN +static int i2c_configure_dma(const struct device *dev, bool is_read) +{ + int retval = I2C_MCHP_SUCCESS; + + if (is_read == true) { + retval = i2c_dma_read_config(dev); + } else { + retval = i2c_dma_write_config(dev); + } + + return retval; +} + +static int i2c_start_dma(const struct device *dev, bool is_read) +{ + const struct i2c_mchp_dev_config *cfg = dev->config; + int retval = I2C_MCHP_SUCCESS; + uint32_t channel; + + if (is_read == true) { + channel = cfg->i2c_dma.rx_dma_channel; + } else { + channel = cfg->i2c_dma.tx_dma_channel; + } + + retval = dma_start(cfg->i2c_dma.dma_dev, channel); + + return retval; +} +#endif /*CONFIG_I2C_MCHP_DMA_DRIVEN*/ + static void i2c_restart(const struct device *dev) { struct i2c_mchp_dev_data *data = dev->data; - /* left-shift address by 1 for R/W bit. */ uint32_t addr_reg = data->target_addr << 1U; bool is_read = @@ -530,8 +588,25 @@ static void i2c_restart(const struct device *dev) addr_reg |= 1U; } +#ifdef CONFIG_I2C_MCHP_DMA_DRIVEN + int retval = i2c_configure_dma(dev, is_read); + + if (retval == I2C_MCHP_SUCCESS) { + i2c_controller_addr_write(dev, addr_reg); + retval = i2c_start_dma(dev, is_read); + } + + if (retval != I2C_MCHP_SUCCESS) { + LOG_ERR("I2C restart DMA failed on %s: error=%d", dev->name, retval); + + if (data->i2c_async_callback != NULL) { + data->i2c_async_callback(dev, retval, data->user_data); + } + } +#else i2c_controller_addr_write(dev, addr_reg); i2c_controller_int_enable(dev, SERCOM_I2CM_INTENSET_Msk); +#endif /*CONFIG_I2C_MCHP_DMA_DRIVEN*/ } #ifdef CONFIG_I2C_TARGET @@ -777,10 +852,14 @@ static void i2c_handle_controller_error(const struct device *dev) { struct i2c_mchp_dev_data *data = dev->data; + LOG_ERR("I2C controller error on %s: status=0x%08X", dev->name, data->current_msg.status); + i2c_controller_transfer_stop(dev); i2c_controller_int_disable(dev, SERCOM_I2CM_INTENSET_Msk); #ifdef CONFIG_I2C_CALLBACK - data->i2c_async_callback(dev, (int)data->current_msg.status, data->user_data); + if (data->i2c_async_callback != NULL) { + data->i2c_async_callback(dev, (int)data->current_msg.status, data->user_data); + } #else k_sem_give(&data->i2c_sync_sem); #endif /*CONFIG_I2C_CALLBACK*/ @@ -803,8 +882,10 @@ static void i2c_handle_controller_write_mode(const struct device *dev, bool cont i2c_restart(dev); } else { #ifdef CONFIG_I2C_CALLBACK - data->i2c_async_callback(dev, (int)data->current_msg.status, - data->user_data); + if (data->i2c_async_callback != NULL) { + data->i2c_async_callback(dev, (int)data->current_msg.status, + data->user_data); + } #else k_sem_give(&data->i2c_sync_sem); #endif /*CONFIG_I2C_CALLBACK*/ @@ -832,9 +913,11 @@ static void i2c_handle_controller_read_mode(const struct device *dev, bool conti i2c_controller_transfer_stop(dev); } +#ifndef CONFIG_I2C_MCHP_DMA_DRIVEN *data->current_msg.buffer = i2c_byte_read(dev); data->current_msg.buffer++; data->current_msg.size--; +#endif /*!CONFIG_I2C_MCHP_DMA_DRIVEN*/ if ((continue_next == false) && (data->current_msg.size == 0U)) { i2c_controller_int_disable(dev, SERCOM_I2CM_INTFLAG_SB_Msk); @@ -848,8 +931,10 @@ static void i2c_handle_controller_read_mode(const struct device *dev, bool conti i2c_restart(dev); } else { #ifdef CONFIG_I2C_CALLBACK - data->i2c_async_callback(dev, (int)data->current_msg.status, - data->user_data); + if (data->i2c_async_callback != NULL) { + data->i2c_async_callback(dev, (int)data->current_msg.status, + data->user_data); + } #else k_sem_give(&data->i2c_sync_sem); #endif /*CONFIG_I2C_CALLBACK*/ @@ -1074,6 +1159,240 @@ static int i2c_mchp_target_unregister(const struct device *dev, } #endif /*CONFIG_I2C_MCHP_TARGET*/ +#ifdef CONFIG_I2C_MCHP_DMA_DRIVEN +static void i2c_dma_write_done(const struct device *dma_dev, void *arg, uint32_t id, int error_code) +{ + struct i2c_mchp_dev_data *data = (struct i2c_mchp_dev_data *)arg; + const struct device *dev = data->dev; + const struct i2c_mchp_dev_config *cfg = dev->config; + bool continue_next = false; + + ARG_UNUSED(dma_dev); + ARG_UNUSED(id); + + unsigned int key = irq_lock(); + + if (i2c_is_terminate_on_error(dev) == true) { + irq_unlock(key); + LOG_ERR("I2C termination due to previous error on %s: status=%d", dev->name, + data->current_msg.status); + + if (data->i2c_async_callback != NULL) { + data->i2c_async_callback(dev, (int)data->current_msg.status, + data->user_data); + } + + return; + } + + if (error_code < 0) { + irq_unlock(key); + LOG_ERR("DMA write error on %s: %d", dev->name, error_code); + + if (data->i2c_async_callback != NULL) { + data->i2c_async_callback(dev, error_code, data->user_data); + } + + return; + } + + if (data->num_msgs > 1U) { + uint8_t cur_flags = data->msgs_array[data->msg_index].flags; + uint8_t next_flags = data->msgs_array[data->msg_index + 1U].flags; + + bool same_rw = ((cur_flags & I2C_MSG_RW_MASK) == (next_flags & I2C_MSG_RW_MASK)); + bool no_restart = ((next_flags & I2C_MSG_RESTART) == 0U); + + continue_next = same_rw && no_restart; + } + + if (continue_next == true) { + data->msg_index++; + data->num_msgs--; + + data->current_msg.buffer = data->msgs_array[data->msg_index].buf; + data->current_msg.size = data->msgs_array[data->msg_index].len; + data->current_msg.status = 0U; + + irq_unlock(key); + + if (i2c_dma_write_config(dev) == 0) { + int retval = dma_start(cfg->i2c_dma.dma_dev, cfg->i2c_dma.tx_dma_channel); + + if (retval != 0) { + LOG_ERR("DMA write start failed on %s: %d", dev->name, retval); + + if (data->i2c_async_callback != NULL) { + data->i2c_async_callback(dev, retval, data->user_data); + } + } + } else { + LOG_ERR("DMA write config failed on %s", dev->name); + if (data->i2c_async_callback != NULL) { + data->i2c_async_callback(dev, -EIO, data->user_data); + } + } + + return; + } + + data->current_msg.size = 0U; + irq_unlock(key); + + i2c_controller_int_enable(dev, SERCOM_I2CM_INTENSET_MB_Msk); +} + +static void i2c_dma_read_done(const struct device *dma_dev, void *arg, uint32_t id, int error_code) +{ + struct i2c_mchp_dev_data *data = (struct i2c_mchp_dev_data *)arg; + const struct device *dev = data->dev; + const struct i2c_mchp_dev_config *cfg = dev->config; + bool continue_next = false; + + ARG_UNUSED(dma_dev); + ARG_UNUSED(id); + + unsigned int key = irq_lock(); + + if (i2c_is_terminate_on_error(dev) == true) { + irq_unlock(key); + LOG_ERR("I2C termination due to previous error on %s: status=%d", dev->name, + data->current_msg.status); + + if (data->i2c_async_callback != NULL) { + data->i2c_async_callback(dev, (int)data->current_msg.status, + data->user_data); + } + + return; + } + + if (error_code < 0) { + irq_unlock(key); + LOG_ERR("DMA read error on %s: %d", dev->name, error_code); + + if (data->i2c_async_callback != NULL) { + data->i2c_async_callback(dev, error_code, data->user_data); + } + + return; + } + + if (data->num_msgs > 1U) { + uint8_t cur_flags = data->msgs_array[data->msg_index].flags; + uint8_t next_flags = data->msgs_array[data->msg_index + 1U].flags; + + bool same_rw = ((cur_flags & I2C_MSG_RW_MASK) == (next_flags & I2C_MSG_RW_MASK)); + bool no_restart = ((next_flags & I2C_MSG_RESTART) == 0U); + + continue_next = same_rw && no_restart; + } + + if (continue_next == true) { + data->msg_index++; + data->num_msgs--; + + data->current_msg.buffer = data->msgs_array[data->msg_index].buf; + data->current_msg.size = data->msgs_array[data->msg_index].len; + data->current_msg.status = 0U; + + irq_unlock(key); + + if (i2c_dma_read_config(dev) == I2C_MCHP_SUCCESS) { + + int retval = dma_start(cfg->i2c_dma.dma_dev, cfg->i2c_dma.rx_dma_channel); + + if (retval != I2C_MCHP_SUCCESS) { + LOG_ERR("DMA read start failed on %s: %d", dev->name, retval); + + if (data->i2c_async_callback != NULL) { + data->i2c_async_callback(dev, retval, data->user_data); + } + } + + } else { + LOG_ERR("DMA read config failed on %s", dev->name); + if (data->i2c_async_callback != NULL) { + data->i2c_async_callback(dev, -EIO, data->user_data); + } + } + + return; + } + + data->current_msg.size = 0U; + irq_unlock(key); + + i2c_controller_int_enable(dev, SERCOM_I2CM_INTENSET_SB_Msk); +} + +static int i2c_dma_write_config(const struct device *dev) +{ + struct i2c_mchp_dev_data *data = dev->data; + const struct i2c_mchp_dev_config *const cfg = dev->config; + struct dma_config dma_cfg = {0}; + struct dma_block_config dma_blk = {0}; + int retval = I2C_MCHP_SUCCESS; + + dma_cfg.channel_direction = MEMORY_TO_PERIPHERAL; + dma_cfg.source_data_size = 1; + dma_cfg.dest_data_size = 1; + dma_cfg.user_data = data; + dma_cfg.dma_callback = i2c_dma_write_done; + dma_cfg.block_count = 1; + dma_cfg.head_block = &dma_blk; + dma_cfg.dma_slot = cfg->i2c_dma.tx_dma_request; + + dma_blk.block_size = data->current_msg.size; + dma_blk.source_address = (uint32_t)data->current_msg.buffer; + dma_blk.dest_address = (uint32_t)(&(cfg->regs->I2CM.SERCOM_DATA)); + dma_blk.dest_addr_adj = DMA_ADDR_ADJ_NO_CHANGE; + + retval = dma_config(cfg->i2c_dma.dma_dev, cfg->i2c_dma.tx_dma_channel, &dma_cfg); + if (retval != I2C_MCHP_SUCCESS) { + LOG_ERR("Write DMA configure on %s failed: %d", dev->name, retval); + if (data->i2c_async_callback != NULL) { + data->i2c_async_callback(dev, retval, data->user_data); + } + } + + return retval; +} + +static int i2c_dma_read_config(const struct device *dev) +{ + struct i2c_mchp_dev_data *data = dev->data; + const struct i2c_mchp_dev_config *const cfg = dev->config; + struct dma_config dma_cfg = {0}; + struct dma_block_config dma_blk = {0}; + int retval = I2C_MCHP_SUCCESS; + + dma_cfg.channel_direction = PERIPHERAL_TO_MEMORY; + dma_cfg.source_data_size = 1; + dma_cfg.dest_data_size = 1; + dma_cfg.user_data = data; + dma_cfg.dma_callback = i2c_dma_read_done; + dma_cfg.block_count = 1; + dma_cfg.head_block = &dma_blk; + dma_cfg.dma_slot = cfg->i2c_dma.rx_dma_request; + + dma_blk.block_size = data->current_msg.size; + dma_blk.dest_address = (uint32_t)data->current_msg.buffer; + dma_blk.source_address = (uint32_t)(&(cfg->regs->I2CM.SERCOM_DATA)); + dma_blk.source_addr_adj = DMA_ADDR_ADJ_NO_CHANGE; + + retval = dma_config(cfg->i2c_dma.dma_dev, cfg->i2c_dma.rx_dma_channel, &dma_cfg); + if (retval != I2C_MCHP_SUCCESS) { + LOG_ERR("Read DMA configure on %s failed: %d", dev->name, retval); + if (data->i2c_async_callback != NULL) { + data->i2c_async_callback(dev, retval, data->user_data); + } + } + + return retval; +} +#endif /*CONFIG_I2C_MCHP_DMA_DRIVEN*/ + #ifdef CONFIG_I2C_CALLBACK static int i2c_mchp_transfer_cb(const struct device *dev, struct i2c_msg *msgs, uint8_t num_msgs, uint16_t addr, i2c_callback_t i2c_async_callback, void *user_data) @@ -1119,15 +1438,34 @@ static int i2c_mchp_transfer_cb(const struct device *dev, struct i2c_msg *msgs, if (is_read == true) { addr_reg |= I2C_MESSAGE_DIR_READ; } + +#ifdef CONFIG_I2C_MCHP_DMA_DRIVEN + int retval = i2c_configure_dma(dev, is_read); + + if (retval == I2C_MCHP_SUCCESS) { + i2c_controller_addr_write(dev, addr_reg); + retval = i2c_start_dma(dev, is_read); + } + + if (retval != I2C_MCHP_SUCCESS) { + LOG_ERR("I2C DMA start failed on %s: error=%d", dev->name, retval); + + if (data->i2c_async_callback != NULL) { + data->i2c_async_callback(dev, retval, user_data); + } + } +#else i2c_controller_addr_write(dev, addr_reg); i2c_controller_int_enable(dev, SERCOM_I2CM_INTENSET_Msk); +#endif /*CONFIG_I2C_MCHP_DMA_DRIVEN*/ + k_mutex_unlock(&data->i2c_bus_mutex); return I2C_MCHP_SUCCESS; } #endif /*CONFIG_I2C_CALLBACK*/ -#if !defined(CONFIG_I2C_MCHP_INTERRUPT_DRIVEN) +#ifndef CONFIG_I2C_MCHP_INTERRUPT_DRIVEN static bool i2c_is_nack(const struct device *dev) { bool retval; @@ -1468,6 +1806,40 @@ static int i2c_mchp_init(const struct device *dev) return retval; } +#ifdef CONFIG_I2C_MCHP_DMA_DRIVEN + data->dev = dev; + data->cfg = cfg; + + if ((cfg->i2c_dma.tx_dma_channel == 0xFFU) || (cfg->i2c_dma.rx_dma_channel == 0xFFU)) { + LOG_ERR("Invalid DMA configuration: TX or RX DMA channel is disabled (0xFF)"); + return -EINVAL; + } + + if (device_is_ready(cfg->i2c_dma.dma_dev) == false) { + LOG_ERR("DMA device not ready"); + return -ENODEV; + } + + int dma_ch = cfg->i2c_dma.tx_dma_channel; + int dma_ch_request = dma_request_channel(cfg->i2c_dma.dma_dev, &dma_ch); + + /* No valid channel available. */ + if (dma_ch_request != cfg->i2c_dma.tx_dma_channel) { + LOG_ERR("TX DMA channel %d unavailable", cfg->i2c_dma.tx_dma_channel); + return -EBUSY; + } + + dma_ch = cfg->i2c_dma.rx_dma_channel; + dma_ch_request = dma_request_channel(cfg->i2c_dma.dma_dev, &dma_ch); + + /* No valid channel available. */ + if (dma_ch_request != cfg->i2c_dma.rx_dma_channel) { + LOG_ERR("RX DMA channel %d unavailable", cfg->i2c_dma.rx_dma_channel); + return -EBUSY; + } + +#endif /*CONFIG_I2C_MCHP_DMA_DRIVEN*/ + i2c_controller_enable(dev, false); cfg->irq_config_func(dev); i2c_controller_runstandby_enable(dev); @@ -1515,6 +1887,22 @@ static DEVICE_API(i2c, i2c_mchp_api) = { .i2c_clock.mclk_sys = (void *)(DT_INST_CLOCKS_CELL_BY_NAME(n, mclk, subsystem)), \ .i2c_clock.gclk_sys = (void *)(DT_INST_CLOCKS_CELL_BY_NAME(n, gclk, subsystem)), +#if CONFIG_I2C_MCHP_DMA_DRIVEN +#define I2C_MCHP_DMA_CHECK(n) \ + BUILD_ASSERT(DT_INST_NODE_HAS_PROP(n, dmas), \ + "DMA is enabled for I2C instance " #n \ + " but 'dmas' property is missing in the devicetree.") +#define I2C_MCHP_DMA_CHANNELS(n) \ + .i2c_dma.dma_dev = DEVICE_DT_GET(MCHP_DT_INST_DMA_CTLR(n, tx)), \ + .i2c_dma.tx_dma_request = MCHP_DT_INST_DMA_TRIGSRC(n, tx), \ + .i2c_dma.tx_dma_channel = MCHP_DT_INST_DMA_CHANNEL(n, tx), \ + .i2c_dma.rx_dma_request = MCHP_DT_INST_DMA_TRIGSRC(n, rx), \ + .i2c_dma.rx_dma_channel = MCHP_DT_INST_DMA_CHANNEL(n, rx), +#else +#define I2C_MCHP_DMA_CHECK(n) +#define I2C_MCHP_DMA_CHANNELS(n) +#endif /*CONFIG_I2C_MCHP_DMA_DRIVEN*/ + #define I2C_MCHP_IRQ_CONNECT(n, m) \ do { \ IRQ_CONNECT(DT_INST_IRQ_BY_IDX(n, m, irq), DT_INST_IRQ_BY_IDX(n, m, priority), \ @@ -1528,9 +1916,10 @@ static DEVICE_API(i2c, i2c_mchp_api) = { .bitrate = DT_INST_PROP(n, clock_frequency), \ .irq_config_func = &i2c_mchp_irq_config_##n, \ .run_in_standby = DT_INST_PROP(n, run_in_standby_en), \ - I2C_MCHP_REG_DEFN(n) I2C_MCHP_CLOCK_DEFN(n)} + I2C_MCHP_REG_DEFN(n) I2C_MCHP_CLOCK_DEFN(n) I2C_MCHP_DMA_CHANNELS(n)} #define I2C_MCHP_DEVICE_INIT(n) \ + I2C_MCHP_DMA_CHECK(n); \ PINCTRL_DT_INST_DEFINE(n); \ static void i2c_mchp_irq_config_##n(const struct device *dev); \ I2C_MCHP_CONFIG_DEFN(n); \ From f177edfe7c2c455ddcfc66ea851ceb7ceda05932 Mon Sep 17 00:00:00 2001 From: Fabin V Martin Date: Mon, 24 Nov 2025 16:09:24 +0530 Subject: [PATCH 0490/3659] boards: microchip: sam_e54_xpro: update i2c nodes for dma support add dma properties in i2c node. Signed-off-by: Fabin V Martin --- boards/microchip/sam/sam_e54_xpro/sam_e54_xpro.dts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/boards/microchip/sam/sam_e54_xpro/sam_e54_xpro.dts b/boards/microchip/sam/sam_e54_xpro/sam_e54_xpro.dts index b8a8e1ef308e..97c096d28dc5 100644 --- a/boards/microchip/sam/sam_e54_xpro/sam_e54_xpro.dts +++ b/boards/microchip/sam/sam_e54_xpro/sam_e54_xpro.dts @@ -196,6 +196,8 @@ clock-frequency = ; pinctrl-0 = <&sercom7_i2c_default>; pinctrl-names = "default"; + dmas = <&dmac 10 0x12>, <&dmac 11 0x13>; + dma-names = "rx", "tx"; status = "okay"; }; From 082a9b349ab788a8e3bf45834befee73d19a0db4 Mon Sep 17 00:00:00 2001 From: Fabin V Martin Date: Fri, 12 Dec 2025 17:40:25 +0530 Subject: [PATCH 0491/3659] tests: drivers: i2c: add i2c dma transfer eeprom test add test project for i2c transfer with callback using dma Signed-off-by: Fabin V Martin --- tests/drivers/i2c/i2c_async/CMakeLists.txt | 9 +++ .../i2c/i2c_async/boards/sam_e54_xpro.overlay | 13 +++ tests/drivers/i2c/i2c_async/prj.conf | 5 ++ tests/drivers/i2c/i2c_async/src/main.c | 79 +++++++++++++++++++ tests/drivers/i2c/i2c_async/testcase.yaml | 9 +++ 5 files changed, 115 insertions(+) create mode 100644 tests/drivers/i2c/i2c_async/CMakeLists.txt create mode 100644 tests/drivers/i2c/i2c_async/boards/sam_e54_xpro.overlay create mode 100644 tests/drivers/i2c/i2c_async/prj.conf create mode 100644 tests/drivers/i2c/i2c_async/src/main.c create mode 100644 tests/drivers/i2c/i2c_async/testcase.yaml diff --git a/tests/drivers/i2c/i2c_async/CMakeLists.txt b/tests/drivers/i2c/i2c_async/CMakeLists.txt new file mode 100644 index 000000000000..0f9740183923 --- /dev/null +++ b/tests/drivers/i2c/i2c_async/CMakeLists.txt @@ -0,0 +1,9 @@ +# Copyright (c) 2025 Microchip Technology Inc. +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(i2c_async) + +target_sources(app PRIVATE src/main.c) diff --git a/tests/drivers/i2c/i2c_async/boards/sam_e54_xpro.overlay b/tests/drivers/i2c/i2c_async/boards/sam_e54_xpro.overlay new file mode 100644 index 000000000000..470b9fbb774a --- /dev/null +++ b/tests/drivers/i2c/i2c_async/boards/sam_e54_xpro.overlay @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&sercom7 { + eeprom0: eeprom@56 { + compatible = "zephyr,i2c-target-eeprom"; + reg = <0x56>; + size = <256>; + }; +}; diff --git a/tests/drivers/i2c/i2c_async/prj.conf b/tests/drivers/i2c/i2c_async/prj.conf new file mode 100644 index 000000000000..dcdca137ba66 --- /dev/null +++ b/tests/drivers/i2c/i2c_async/prj.conf @@ -0,0 +1,5 @@ +CONFIG_I2C=y +CONFIG_ZTEST=y +CONFIG_DMA=y +CONFIG_I2C_CALLBACK=y +CONFIG_I2C_MCHP_DMA_DRIVEN=y diff --git a/tests/drivers/i2c/i2c_async/src/main.c b/tests/drivers/i2c/i2c_async/src/main.c new file mode 100644 index 000000000000..83a2da3dae9b --- /dev/null +++ b/tests/drivers/i2c/i2c_async/src/main.c @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#define EEPROM_NODE DT_NODELABEL(eeprom0) +#define EEPROM_I2C_ADDR DT_REG_ADDR(EEPROM_NODE) +#define I2C_NODE DT_PARENT(EEPROM_NODE) +#define TEST_DATA_LEN 8 + +static const struct device *i2c_dev = DEVICE_DT_GET(I2C_NODE); +static uint8_t write_data[TEST_DATA_LEN] = {0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80}; +static uint8_t read_data[TEST_DATA_LEN]; + +/* Callback function for I2C operations */ +static void i2c_async_callback(const struct device *dev, int status, void *user_data) +{ + if (status == 0) { + printk("I2C operation completed successfully\n"); + } else { + printk("I2C operation failed with error: %d\n", status); + } + + /* Signal completion if needed */ + struct k_sem *sem = (struct k_sem *)user_data; + + k_sem_give(sem); +} + +/* write data to EEPROM */ +uint8_t eeprom_addr = 1; + +struct i2c_msg tx_msg[2] = {{.buf = &eeprom_addr, .len = 1, .flags = I2C_MSG_WRITE}, + {.buf = write_data, .len = sizeof(write_data), .flags = I2C_MSG_WRITE}}; + +/* Read data back from the EEPROM */ +struct i2c_msg rx_msg[2] = {{.buf = &eeprom_addr, .len = 1, .flags = I2C_MSG_WRITE}, + {.buf = read_data, .len = sizeof(read_data), .flags = I2C_MSG_READ}}; + +ZTEST(i2c_async, test_eeprom_async) +{ + /* Semaphore for signaling completion */ + static struct k_sem async_sem; + + k_sem_init(&async_sem, 0, 1); + k_timeout_t timeout = K_MSEC(500); + + int ret = i2c_transfer_cb(i2c_dev, tx_msg, 2, EEPROM_I2C_ADDR, i2c_async_callback, + &async_sem); + zassert_equal(ret, 0, "EEPROM write failed: %d", ret); + + /* Wait for transfer to complete */ + k_sem_take(&async_sem, timeout); + + ret = i2c_transfer_cb(i2c_dev, rx_msg, 2, EEPROM_I2C_ADDR, i2c_async_callback, &async_sem); + zassert_equal(ret, 0, "EEPROM read failed: %d", ret); + + /* Wait for transfer to complete */ + k_sem_take(&async_sem, timeout); + + for (int i = 0; i < TEST_DATA_LEN; i++) { + zassert_equal(read_data[i], write_data[i], + "Data mismatch at index %d: expected 0x%02X, got 0x%02X", i, + write_data[i], read_data[i]); + } +} + +/* Test Setup */ +void *i2c_test_setup(void) +{ + zassert_true(device_is_ready(i2c_dev), "I2C device is not ready"); + return NULL; +} + +ZTEST_SUITE(i2c_async, NULL, i2c_test_setup, NULL, NULL, NULL); diff --git a/tests/drivers/i2c/i2c_async/testcase.yaml b/tests/drivers/i2c/i2c_async/testcase.yaml new file mode 100644 index 000000000000..1a7c6e41adb7 --- /dev/null +++ b/tests/drivers/i2c/i2c_async/testcase.yaml @@ -0,0 +1,9 @@ +common: + tags: + - drivers + - i2c + depends_on: i2c +tests: + drivers.i2c.i2c_async: + platform_allow: + - sam_e54_xpro From a67eee4bb62ce06d391c7b34d085ae90b248d98c Mon Sep 17 00:00:00 2001 From: Camille BAUD Date: Thu, 4 Dec 2025 01:38:32 +0100 Subject: [PATCH 0492/3659] boards: sipeed: Introduce Maix M0S Dock Introduces BL616-based M0S Dock Signed-off-by: Camille BAUD --- .../maix_m0s_dock/Kconfig.maix_m0s_dock | 6 ++ boards/sipeed/maix_m0s_dock/board.cmake | 23 +++++ boards/sipeed/maix_m0s_dock/board.yml | 6 ++ .../maix_m0s_dock/doc/img/maix_m0s_dock.webp | Bin 0 -> 27046 bytes boards/sipeed/maix_m0s_dock/doc/index.rst | 90 ++++++++++++++++++ .../maix_m0s_dock/maix_m0s-pinctrl.dtsi | 26 +++++ boards/sipeed/maix_m0s_dock/maix_m0s.dtsi | 67 +++++++++++++ .../maix_m0s_dock/maix_m0s_dock-pinctrl.dtsi | 26 +++++ boards/sipeed/maix_m0s_dock/maix_m0s_dock.dts | 57 +++++++++++ .../sipeed/maix_m0s_dock/maix_m0s_dock.yaml | 24 +++++ .../maix_m0s_dock/maix_m0s_dock_defconfig | 8 ++ boards/sipeed/maix_m0s_dock/support/bl61x.cfg | 80 ++++++++++++++++ .../sipeed/maix_m0s_dock/support/openocd.cfg | 5 + 13 files changed, 418 insertions(+) create mode 100644 boards/sipeed/maix_m0s_dock/Kconfig.maix_m0s_dock create mode 100644 boards/sipeed/maix_m0s_dock/board.cmake create mode 100644 boards/sipeed/maix_m0s_dock/board.yml create mode 100644 boards/sipeed/maix_m0s_dock/doc/img/maix_m0s_dock.webp create mode 100644 boards/sipeed/maix_m0s_dock/doc/index.rst create mode 100644 boards/sipeed/maix_m0s_dock/maix_m0s-pinctrl.dtsi create mode 100644 boards/sipeed/maix_m0s_dock/maix_m0s.dtsi create mode 100644 boards/sipeed/maix_m0s_dock/maix_m0s_dock-pinctrl.dtsi create mode 100644 boards/sipeed/maix_m0s_dock/maix_m0s_dock.dts create mode 100644 boards/sipeed/maix_m0s_dock/maix_m0s_dock.yaml create mode 100644 boards/sipeed/maix_m0s_dock/maix_m0s_dock_defconfig create mode 100644 boards/sipeed/maix_m0s_dock/support/bl61x.cfg create mode 100644 boards/sipeed/maix_m0s_dock/support/openocd.cfg diff --git a/boards/sipeed/maix_m0s_dock/Kconfig.maix_m0s_dock b/boards/sipeed/maix_m0s_dock/Kconfig.maix_m0s_dock new file mode 100644 index 000000000000..91d9e6a010d4 --- /dev/null +++ b/boards/sipeed/maix_m0s_dock/Kconfig.maix_m0s_dock @@ -0,0 +1,6 @@ +# Copyright (c) 2025 MASSDRIVER EI (massdriver.space) +# +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_MAIX_M0S_DOCK + select SOC_BL616C50Q2I diff --git a/boards/sipeed/maix_m0s_dock/board.cmake b/boards/sipeed/maix_m0s_dock/board.cmake new file mode 100644 index 000000000000..dd5219e96b90 --- /dev/null +++ b/boards/sipeed/maix_m0s_dock/board.cmake @@ -0,0 +1,23 @@ +# Copyright (c) 2024-2025 MASSDRIVER EI (massdriver.space) +# +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(openocd --cmd-pre-init "source [find bl61x.cfg]") + +board_runner_args(openocd --use-elf --no-load --no-init) +board_runner_args(openocd --gdb-init "set mem inaccessible-by-default off") +board_runner_args(openocd --gdb-init "set architecture riscv:rv32") +board_runner_args(openocd --gdb-init "set remotetimeout 250") +board_runner_args(openocd --gdb-init "set print asm-demangle on") +board_runner_args(openocd --gdb-init "set backtrace limit 32") +board_runner_args(openocd --gdb-init "mem 0x22FC0000 0x23010000 rw") +board_runner_args(openocd --gdb-init "mem 0x62FC0000 0x63010000 rw") +board_runner_args(openocd --gdb-init "mem 0x90000000 0x90020000 ro") +board_runner_args(openocd --gdb-init "mem 0xA8000000 0xA8800000 rw") +board_runner_args(openocd --gdb-init "mem 0xA0000000 0xA0400000 ro") +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) + +board_runner_args(bflb_mcu_tool --chipname bl616) +include(${ZEPHYR_BASE}/boards/common/bflb_mcu_tool.board.cmake) + +board_set_flasher(bflb_mcu_tool) diff --git a/boards/sipeed/maix_m0s_dock/board.yml b/boards/sipeed/maix_m0s_dock/board.yml new file mode 100644 index 000000000000..5f7b4da9c733 --- /dev/null +++ b/boards/sipeed/maix_m0s_dock/board.yml @@ -0,0 +1,6 @@ +board: + name: maix_m0s_dock + full_name: Sipeed M0S Dock + vendor: sipeed + socs: + - name: bl616c50q2i diff --git a/boards/sipeed/maix_m0s_dock/doc/img/maix_m0s_dock.webp b/boards/sipeed/maix_m0s_dock/doc/img/maix_m0s_dock.webp new file mode 100644 index 0000000000000000000000000000000000000000..d8f734defb38435d1ef4039e81a4de05e3ecde0b GIT binary patch literal 27046 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 + +&pinctrl { + uart0_default: uart0_default { + group1 { + pinmux = , + ; + bias-pull-up; + input-schmitt-enable; + }; + }; + + uart0_sleep: uart0_sleep { + group1 { + pinmux = , + ; + bias-high-impedance; + }; + }; +}; diff --git a/boards/sipeed/maix_m0s_dock/maix_m0s.dtsi b/boards/sipeed/maix_m0s_dock/maix_m0s.dtsi new file mode 100644 index 000000000000..c3b693ca02fe --- /dev/null +++ b/boards/sipeed/maix_m0s_dock/maix_m0s.dtsi @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2025 MASSDRIVER EI (massdriver.space) + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include "maix_m0s-pinctrl.dtsi" + +/ { + model = "Sipeed M0S"; + compatible = "bflb,bl616"; + + chosen { + zephyr,flash = &flash0; + zephyr,code-partition = &slot0_partition; + zephyr,itcm = &sram1; + zephyr,sram = &sram0; + zephyr,console = &uart0; + zephyr,shell-uart = &uart0; + }; +}; + +&cpu0 { + clock-frequency = ; +}; + +&flashctrl { + flash0: flash@A0000000 { + compatible = "soc-nv-flash", "gd,25lq32d"; + reg = <0xA0000000 (0x400000 - 0x2000)>; + write-block-size = <256>; + erase-block-size = ; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + slot0_partition: partition@0 { + label = "image-0"; + reg = <0x00000000 0x00100000>; + read-only; + }; + + storage_partition: partition@100000 { + label = "storage"; + reg = <0x00100000 (0x300000 - 0x2000)>; + }; + }; + }; +}; + +&uart0 { + status = "okay"; + current-speed = <115200>; + + pinctrl-0 = <&uart0_default>; + pinctrl-1 = <&uart0_sleep>; + pinctrl-names = "default", "sleep"; +}; + +&gpio0 { + status = "okay"; +}; diff --git a/boards/sipeed/maix_m0s_dock/maix_m0s_dock-pinctrl.dtsi b/boards/sipeed/maix_m0s_dock/maix_m0s_dock-pinctrl.dtsi new file mode 100644 index 000000000000..9d85a37cd936 --- /dev/null +++ b/boards/sipeed/maix_m0s_dock/maix_m0s_dock-pinctrl.dtsi @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2025 MASSDRIVER EI (massdriver.space) + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&pinctrl { + i2c0_default: i2c0_default { + group1 { + pinmux = , + ; + bias-pull-up; + input-schmitt-enable; + }; + }; + + spi0_default: spi0_default { + group1 { + pinmux = , + , + ; + bias-pull-up; + input-schmitt-enable; + }; + }; +}; diff --git a/boards/sipeed/maix_m0s_dock/maix_m0s_dock.dts b/boards/sipeed/maix_m0s_dock/maix_m0s_dock.dts new file mode 100644 index 000000000000..6635031ad44a --- /dev/null +++ b/boards/sipeed/maix_m0s_dock/maix_m0s_dock.dts @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2025 MASSDRIVER EI (massdriver.space) + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include "maix_m0s.dtsi" +#include "maix_m0s_dock-pinctrl.dtsi" + +/ { + model = "Sipeed M0S Dock"; + + aliases { + led0 = &red_led_0; + sw0 = &button_0; + }; + + leds { + compatible = "gpio-leds"; + + red_led_0: led_0 { + gpios = <&gpio0 27 GPIO_ACTIVE_LOW>; + label = "Red - LED0"; + }; + + red_led_1: led_1 { + gpios = <&gpio0 28 GPIO_ACTIVE_LOW>; + label = "Red - LED1"; + }; + }; + + buttons { + compatible = "gpio-keys"; + + button_0: sw0 { + gpios = <&gpio0 2 GPIO_ACTIVE_HIGH>; + zephyr,code = ; + }; + }; +}; + +&i2c0 { + status = "okay"; + clock-frequency = ; + + pinctrl-0 = <&i2c0_default>; + pinctrl-names = "default"; +}; + +&spi0 { + status = "okay"; + + pinctrl-0 = <&spi0_default>; + pinctrl-names = "default"; +}; diff --git a/boards/sipeed/maix_m0s_dock/maix_m0s_dock.yaml b/boards/sipeed/maix_m0s_dock/maix_m0s_dock.yaml new file mode 100644 index 000000000000..8470b9fd71e1 --- /dev/null +++ b/boards/sipeed/maix_m0s_dock/maix_m0s_dock.yaml @@ -0,0 +1,24 @@ +# Copyright (c) 2025 MASSDRIVER EI (massdriver.space) +# +# SPDX-License-Identifier: Apache-2.0 + +identifier: maix_m0s_dock +name: Sipeed M0S Dock +type: mcu +arch: riscv +ram: 480 +toolchain: + - zephyr +testing: + ignore_tags: + - net + - bluetooth +supported: + - gpio + - pinctrl + - uart + - dma + - i2c + - spi + - flash +vendor: sipeed diff --git a/boards/sipeed/maix_m0s_dock/maix_m0s_dock_defconfig b/boards/sipeed/maix_m0s_dock/maix_m0s_dock_defconfig new file mode 100644 index 000000000000..7836442f7c45 --- /dev/null +++ b/boards/sipeed/maix_m0s_dock/maix_m0s_dock_defconfig @@ -0,0 +1,8 @@ +# Copyright (c) 2024-2025 MASSDRIVER EI (massdriver.space) +# +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_CONSOLE=y +CONFIG_SERIAL=y + +CONFIG_UART_CONSOLE=y diff --git a/boards/sipeed/maix_m0s_dock/support/bl61x.cfg b/boards/sipeed/maix_m0s_dock/support/bl61x.cfg new file mode 100644 index 000000000000..9c8523db4f1d --- /dev/null +++ b/boards/sipeed/maix_m0s_dock/support/bl61x.cfg @@ -0,0 +1,80 @@ +# Copyright (c) 2025 MASSDRIVER EI (massdriver.space) +# +# SPDX-License-Identifier: Apache-2.0 + +if { [info exists CHIPNAME] } { + set _CHIPNAME $CHIPNAME +} else { + set _CHIPNAME riscv +} + +if { [info exists WORKAREASIZE] } { + set _WORKAREASIZE $WORKAREASIZE +} else { + set _WORKAREASIZE 0x10000 +} + +if { [info exists WORKAREAADDR] } { + set _WORKAREAADDR $WORKAREAADDR +} else { + set _WORKAREAADDR 0x40000000 +} + +if { [info exists CPUTAPID] } { + set _CPUTAPID $CPUTAPID +} else { + set _CPUTAPID 0x10000b6f +} + +transport select jtag +jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id $_CPUTAPID + +set _TARGETNAME $_CHIPNAME.cpu +target create $_TARGETNAME.0 riscv -chain-position $_TARGETNAME + +$_TARGETNAME.0 configure -work-area-phys $_WORKAREAADDR -work-area-size $_WORKAREASIZE -work-area-backup 0 + +echo "Ready for Remote Connections" + +$_TARGETNAME.0 configure -event reset-assert-pre { + echo "reset-assert-pre" + adapter speed 400 +} + +$_TARGETNAME.0 configure -event reset-deassert-post { + echo "reset-deassert-post" + + adapter speed 400 + + reg mstatus 0x7880 + reg mie 0 +} + +$_TARGETNAME.0 configure -event reset-init { + echo "reset-init" + + adapter speed 400 + reg mstatus 0x1880 + reg mie 0 + reg pc 0xA0000000 +} + +$_TARGETNAME.0 configure -event gdb-attach { + echo "Debugger attaching: halting execution" + halt + gdb_breakpoint_override hard +} + +$_TARGETNAME.0 configure -event gdb-detach { + echo "Debugger detaching: resuming execution" + resume +} + +gdb_memory_map enable +gdb_flash_program enable + +# 'progbuf', 'sysbus' or 'abstract' +riscv set_mem_access sysbus +riscv set_command_timeout_sec 1 + +init diff --git a/boards/sipeed/maix_m0s_dock/support/openocd.cfg b/boards/sipeed/maix_m0s_dock/support/openocd.cfg new file mode 100644 index 000000000000..ea9daa4d8b52 --- /dev/null +++ b/boards/sipeed/maix_m0s_dock/support/openocd.cfg @@ -0,0 +1,5 @@ +# For WCH linkE in DAP mode + +interface cmsis-dap + +adapter speed 400 From e24574bb16707fdf5994aaf6211d98705cfda1bc Mon Sep 17 00:00:00 2001 From: Camille BAUD Date: Fri, 5 Dec 2025 04:57:09 +0100 Subject: [PATCH 0493/3659] MAINTAINERS: bflb: Add M0S Dock to bflb area Adds the board to area Signed-off-by: Camille BAUD --- MAINTAINERS.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index e7b3dfb791d1..1ea17aa2a850 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -738,6 +738,7 @@ Bouffalolab Platforms: - josuah files: - boards/bflb/ + - boards/sipeed/maix_m0s_dock/ - drivers/*/*bflb* - dts/riscv/bflb/ - dts/bindings/*/bflb,* From aca5f0c0210c8b6ed389fbc4464f142e9f1996b9 Mon Sep 17 00:00:00 2001 From: Liang Jiaxiang Date: Thu, 4 Dec 2025 13:43:19 +0800 Subject: [PATCH 0494/3659] drivers: sensor: bmi08x: fix temperature reading and scaling The previous implementation had three issues regarding temperature reading: 1. The unit scaling was incorrect. The datasheet specifies 0.125 C/LSB, but the code multiplied by 125 instead of 125000 for micro-degrees, resulting in values off by a factor of 1000. 2. The MSB and LSB registers were read in two separate transactions, which is not atomic. 3. The bitwise reconstruction of the 11-bit value was inefficient. This commit fixes the scaling factor to 125000, implements a burst read for both temperature registers to ensure atomicity, and optimizes the bit manipulation logic. Signed-off-by: Liang Jiaxiang --- drivers/sensor/bosch/bmi08x/bmi08x_accel.c | 38 +++++----------------- 1 file changed, 8 insertions(+), 30 deletions(-) diff --git a/drivers/sensor/bosch/bmi08x/bmi08x_accel.c b/drivers/sensor/bosch/bmi08x/bmi08x_accel.c index e8f0eafa7141..a19679e6370f 100644 --- a/drivers/sensor/bosch/bmi08x/bmi08x_accel.c +++ b/drivers/sensor/bosch/bmi08x/bmi08x_accel.c @@ -231,20 +231,6 @@ int bmi08x_accel_byte_read(const struct device *dev, uint8_t reg_addr, uint8_t * return bmi08x_accel_transceive(dev, reg_addr | BIT(7), false, byte, 1); } -static int bmi08x_accel_word_read(const struct device *dev, uint8_t reg_addr, uint16_t *word) -{ - int ret; - - ret = bmi08x_accel_transceive(dev, reg_addr | BIT(7), false, word, 2); - if (ret != 0) { - return ret; - } - - *word = sys_le16_to_cpu(*word); - - return ret; -} - int bmi08x_accel_byte_write(const struct device *dev, uint8_t reg_addr, uint8_t byte) { return bmi08x_accel_transceive(dev, reg_addr & 0x7F, true, &byte, 1); @@ -440,32 +426,24 @@ static inline void bmi08x_acc_channel_get(const struct device *dev, enum sensor_ static int bmi08x_temp_channel_get(const struct device *dev, struct sensor_value *val) { - uint16_t temp_raw = 0U; + uint8_t temp_raw[2] = {0}; int32_t temp_micro = 0; int16_t temp_int11 = 0; int ret; - ret = bmi08x_accel_word_read(dev, BMI08X_REG_TEMP_MSB, &temp_raw); - if (!ret) { - temp_int11 = (temp_raw & 0xFF) << 3; - } else { - LOG_ERR("Error reading BMI08X_REG_TEMP_MSB. (err %d)", ret); + ret = bmi08x_accel_read(dev, BMI08X_REG_TEMP_MSB, temp_raw, sizeof(temp_raw)); + if (ret < 0) { + LOG_ERR("Error reading BMI08X temperature registers. (err %d)", ret); return ret; } - if (temp_raw == 0x80) { + if (temp_raw[0] == 0x80) { /* temperature invalid */ LOG_ERR("BMI08X returned invalid temperature."); return -ENODATA; } - ret = bmi08x_accel_word_read(dev, BMI08X_REG_TEMP_LSB, &temp_raw); - if (!ret) { - temp_int11 |= (temp_raw & 0xE0) >> 5; - } else { - LOG_ERR("Error reading BMI08X_REG_TEMP_LSB. (err %d)", ret); - return ret; - } + temp_int11 = ((int16_t)temp_raw[0] << 3) | ((temp_raw[1] & 0xE0) >> 5); /* * int11 type ranges in [-1024, 1023] * the 11st bit declares +/- @@ -475,8 +453,8 @@ static int bmi08x_temp_channel_get(const struct device *dev, struct sensor_value temp_int11 -= 2048; } /* the value ranges in [-504, 496] */ - /* the scale is 0.125°C/LSB = 125 micro degrees */ - temp_micro = temp_int11 * 125 + 23 * 1000000; + /* the scale is 0.125°C/LSB = 125000 micro degrees */ + temp_micro = temp_int11 * 125000 + 23 * 1000000; val->val1 = temp_micro / 1000000ULL; val->val2 = temp_micro % 1000000ULL; From 7f3567cf7458b88a40c6d277cd8e59f63ffff6ba Mon Sep 17 00:00:00 2001 From: Robert Perkel Date: Mon, 8 Dec 2025 15:03:44 -0700 Subject: [PATCH 0495/3659] drivers: sensor: mtch9010 Fixed heartbeat bugs Fixed the following bugs with the heartbeat monitor - State did not update on CHAN_ALL - Adjusted semaphore behavior - Fixed interrupt setup - Fixed time calculation bug - Split heartbeat update into seperate function call Signed-off-by: Robert Perkel --- drivers/sensor/microchip/mtch9010/mtch9010.c | 92 ++++++++++++-------- 1 file changed, 56 insertions(+), 36 deletions(-) diff --git a/drivers/sensor/microchip/mtch9010/mtch9010.c b/drivers/sensor/microchip/mtch9010/mtch9010.c index e5ddd6d3f8c4..cfd9d4da0cc2 100644 --- a/drivers/sensor/microchip/mtch9010/mtch9010.c +++ b/drivers/sensor/microchip/mtch9010/mtch9010.c @@ -48,6 +48,7 @@ static int mtch9010_device_reset(const struct device *dev); static int mtch9010_timeout_receive(const struct device *dev, char *buffer, uint8_t buffer_len, uint16_t milliseconds); static int mtch9010_lock_settings(const struct device *dev); +static int mtch9010_update_heartbeat(const struct device *dev); /* Callbacks */ static void mtch9010_heartbeat_callback(const struct device *dev, struct gpio_callback *cb, @@ -313,7 +314,7 @@ static int mtch9010_init(const struct device *dev) mtch9010_verify_uart(dev); /* Configure heartbeat timing */ - k_sem_init(&data->heartbeat_sem, 0, 1); + k_sem_init(&data->heartbeat_sem, 1, 1); /* Configure device I/O, as needed */ mtch9010_configure_gpio(dev); @@ -517,21 +518,24 @@ static int mtch9010_configure_int_gpio(const struct device *dev) if (gpio_is_ready_dt(&config->heartbeat_gpio)) { gpio_pin_configure_dt(&config->heartbeat_gpio, GPIO_INPUT); #ifdef CONFIG_MTCH9010_HEARTBEAT_MONITORING_ENABLE - gpio_init_callback(&data->heartbeat_cb, mtch9010_heartbeat_callback, - BIT(config->heartbeat_gpio.pin)); - rtn = gpio_add_callback_dt(&config->heartbeat_gpio, &data->heartbeat_cb); - if (rtn == 0) { - rtn = gpio_pin_interrupt_configure_dt(&config->heartbeat_gpio, + rtn = gpio_pin_interrupt_configure_dt(&config->heartbeat_gpio, GPIO_INT_EDGE_RISING); - if (rtn < 0) { - LOG_INST_ERR(config->log, "Unable to configure interrupt; code %d", - rtn); + if (rtn < 0) { + LOG_INST_ERR(config->log, "Unable to configure interrupt; code %d", + rtn); + } else { + LOG_INST_DBG(config->log, "Configured Heartbeat Interrupt"); + gpio_init_callback(&data->heartbeat_cb, mtch9010_heartbeat_callback, + BIT(config->heartbeat_gpio.pin)); + rtn = gpio_add_callback_dt(&config->heartbeat_gpio, &data->heartbeat_cb); + if (rtn == 0) { + LOG_INST_DBG(config->log, "Added Heartbeat Callback"); } else { - LOG_INST_DBG(config->log, "Configured Heartbeat Interrupt"); + LOG_INST_ERR(config->log, "Unable to add callback; code %d", rtn); } - } else { - LOG_INST_ERR(config->log, "Unable to add callback; code %d", rtn); } + + #endif } else { LOG_INST_DBG(config->log, "Heartbeat line is not ready."); @@ -669,6 +673,38 @@ static int mtch9010_lock_settings(const struct device *dev) return 0; } +static int mtch9010_update_heartbeat(const struct device *dev) +{ + struct mtch9010_data *data = dev->data; + const struct mtch9010_config *config = dev->config; + int64_t time_delta; + +#ifdef CONFIG_MTCH9010_HEARTBEAT_MONITORING_ENABLE + if (k_sem_take(&data->heartbeat_sem, K_MSEC(MTCH9010_UART_COMMAND_TIMEOUT_MS)) < 0) { + data->heartbeat_error_state = true; + LOG_INST_ERR(config->log, "Unable to acquire heartbeat semaphore"); + return -EBUSY; + } + + /* Compute the last access time */ + time_delta = k_uptime_get() - data->last_heartbeat; + + k_sem_give(&data->heartbeat_sem); + + if (time_delta > MTCH9010_ERROR_PERIOD_MS) { + data->heartbeat_error_state = true; + } else { + data->heartbeat_error_state = false; + } + + return 0; +#else + LOG_INST_DBG(config->log, "Heartbeat monitoring not enabled"); + data->heartbeat_error_state = false; + return -ENOTSUP; +#endif +} + static int mtch9010_sample_fetch(const struct device *dev, enum sensor_channel chan) { const struct mtch9010_config *config = dev->config; @@ -763,30 +799,12 @@ static int mtch9010_sample_fetch(const struct device *dev, enum sensor_channel c LOG_INST_ERR(config->log, "Unable to decode result for channel %u", chan); return -EINVAL; } + + mtch9010_update_heartbeat(dev); } break; case SENSOR_CHAN_MTCH9010_HEARTBEAT_ERROR_STATE: { /* Returns true if the heartbeat is an error state */ -#ifdef CONFIG_MTCH9010_HEARTBEAT_MONITORING_ENABLE - if (k_sem_take(&data->heartbeat_sem, K_MSEC(MTCH9010_UART_COMMAND_TIMEOUT_MS)) < - 0) { - return -EBUSY; - } - - /* Compute the last access time */ - int64_t time_delta = k_uptime_delta(&data->last_heartbeat); - - k_sem_give(&data->heartbeat_sem); - - if (time_delta < MTCH9010_ERROR_PERIOD_MS) { - data->heartbeat_error_state = true; - } else { - data->heartbeat_error_state = false; - } - - return 0; -#else - return -ENOTSUP; -#endif + mtch9010_update_heartbeat(dev); } default: { return -ENOTSUP; @@ -878,10 +896,12 @@ static void mtch9010_heartbeat_callback(const struct device *dev, struct gpio_ca struct mtch9010_data *data = CONTAINER_OF(cb, struct mtch9010_data, heartbeat_cb); - if (k_sem_take(&data->heartbeat_sem, K_NO_WAIT) == 0) { - data->last_heartbeat = k_uptime_get(); - k_sem_give(&data->heartbeat_sem); + if (k_sem_take(&data->heartbeat_sem, K_NO_WAIT) < 0) { + return; } + + data->last_heartbeat = k_uptime_get(); + k_sem_give(&data->heartbeat_sem); } /* Sensor APIs */ From 798652841a57450870dca1417855eb12ff043570 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20G=C5=82=C4=85b?= Date: Tue, 9 Dec 2025 14:35:10 +0100 Subject: [PATCH 0496/3659] boards: nordic: nrf54h20dk: Add workaround for RISC-V debugging MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add workaround that enables `west debug` and `west attach` on nrf54h20dk/nrf54h20/cpuppr and cpuflpr. Remove "-if SW" as this generates warning WARNING: runners.jlink: "f SW" does not match any known pattern And breaks JLinkGDBServer command by setting option `-select` to `usb=f SW`. Signed-off-by: Sebastian Głąb --- boards/nordic/nrf54h20dk/board.cmake | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/boards/nordic/nrf54h20dk/board.cmake b/boards/nordic/nrf54h20dk/board.cmake index b9383042b0c7..cabb050253e9 100644 --- a/boards/nordic/nrf54h20dk/board.cmake +++ b/boards/nordic/nrf54h20dk/board.cmake @@ -20,6 +20,7 @@ if(CONFIG_BOARD_NRF54H20DK_NRF54H20_CPUPPR OR CONFIG_BOARD_NRF54H20DK_NRF54H20_C set(JLINKSCRIPTFILE ${CMAKE_CURRENT_LIST_DIR}/support/nrf54h20_cpuflpr.JLinkScript) endif() - board_runner_args(jlink "--device=RISC-V" "--speed=4000" "-if SW" "--tool-opt=-jlinkscriptfile ${JLINKSCRIPTFILE}") + # Workaround: Use device nRF54L15_RV32 until nRF54H20_RV32 is defined. + board_runner_args(jlink "--device=nRF54L15_RV32" "--speed=4000" "--tool-opt=-jlinkscriptfile ${JLINKSCRIPTFILE}") include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) endif() From 3f3e833745f5cac3018669dbf640a032ca1fcedf Mon Sep 17 00:00:00 2001 From: Guido Roncarolo Date: Mon, 29 Sep 2025 15:38:36 +0200 Subject: [PATCH 0497/3659] soc: mcxn947: disable SystemInit when TFM is ON Avoid initialization as this is already been taken care from TF-M secure part Signed-off-by: Guido Roncarolo --- soc/nxp/mcx/mcxn/flash_clock_setup.c | 6 +++++- soc/nxp/mcx/mcxn/soc.c | 2 ++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/soc/nxp/mcx/mcxn/flash_clock_setup.c b/soc/nxp/mcx/mcxn/flash_clock_setup.c index c53128730355..b621944fbe09 100644 --- a/soc/nxp/mcx/mcxn/flash_clock_setup.c +++ b/soc/nxp/mcx/mcxn/flash_clock_setup.c @@ -1,5 +1,5 @@ /* - * Copyright 2024 NXP + * Copyright 2024-2025 NXP * SPDX-License-Identifier: Apache-2.0 */ @@ -7,6 +7,7 @@ uint32_t flexspi_clock_set_freq(uint32_t clock_name, uint32_t rate) { +#if !defined(CONFIG_TRUSTED_EXECUTION_NONSECURE) /* PLL0 is set to 150 MHz */ uint32_t pll_rate = 150000000; uint8_t divider; @@ -21,13 +22,16 @@ uint32_t flexspi_clock_set_freq(uint32_t clock_name, uint32_t rate) /* Switch FLEXSPI to PLL0 */ SYSCON->FLEXSPICLKSEL = 1; +#endif /* ! CONFIG_TRUSTED_EXECUTION_NONSECURE */ return 0; } void flexspi_clock_safe_config(void) { +#if !defined(CONFIG_TRUSTED_EXECUTION_NONSECURE) /* Switch FLEXSPI to FRO_HF */ SYSCON->FLEXSPICLKSEL = 3; +#endif /* ! CONFIG_TRUSTED_EXECUTION_NONSECURE */ } diff --git a/soc/nxp/mcx/mcxn/soc.c b/soc/nxp/mcx/mcxn/soc.c index 42334f00bf75..e7f59ab51571 100644 --- a/soc/nxp/mcx/mcxn/soc.c +++ b/soc/nxp/mcx/mcxn/soc.c @@ -21,7 +21,9 @@ void soc_reset_hook(void) { +#if !defined(CONFIG_TRUSTED_EXECUTION_NONSECURE) SystemInit(); +#endif /* ! CONFIG_TRUSTED_EXECUTION_NONSECURE */ } #endif From 120768833c02d0f8095026d5dce156827caae8dd Mon Sep 17 00:00:00 2001 From: Guido Roncarolo Date: Thu, 9 Oct 2025 08:16:11 +0200 Subject: [PATCH 0498/3659] boards: nxp: mcxn947: add ns board support Add initial TF-M support for mcxn947 target - added ns_decofnig and yml files - added non secure dts for the MCXN974 SOC - added checks with CPU0 enabelement in SOC - added ns memory slot and configs Signed-off-by: Guido Roncarolo Signed-off-by: Waqar Tahir --- boards/nxp/frdm_mcxn947/Kconfig.frdm_mcxn947 | 4 +- boards/nxp/frdm_mcxn947/board.cmake | 7 +- boards/nxp/frdm_mcxn947/board.yml | 2 + .../frdm_mcxn947_mcxn947_cpu0_ns.dts | 277 ++++++++++++++++++ .../frdm_mcxn947_mcxn947_cpu0_ns.yaml | 17 ++ .../frdm_mcxn947_mcxn947_cpu0_ns_defconfig | 19 ++ 6 files changed, 323 insertions(+), 3 deletions(-) create mode 100644 boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_ns.dts create mode 100644 boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_ns.yaml create mode 100644 boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_ns_defconfig diff --git a/boards/nxp/frdm_mcxn947/Kconfig.frdm_mcxn947 b/boards/nxp/frdm_mcxn947/Kconfig.frdm_mcxn947 index fde729ba7363..73af92c4b8a9 100644 --- a/boards/nxp/frdm_mcxn947/Kconfig.frdm_mcxn947 +++ b/boards/nxp/frdm_mcxn947/Kconfig.frdm_mcxn947 @@ -1,7 +1,7 @@ -# Copyright 2024 NXP +# Copyright 2024-2025 NXP # SPDX-License-Identifier: Apache-2.0 config BOARD_FRDM_MCXN947 - select SOC_MCXN947_CPU0 if BOARD_FRDM_MCXN947_MCXN947_CPU0 || BOARD_FRDM_MCXN947_MCXN947_CPU0_QSPI + select SOC_MCXN947_CPU0 if BOARD_FRDM_MCXN947_MCXN947_CPU0 || BOARD_FRDM_MCXN947_MCXN947_CPU0_QSPI || BOARD_FRDM_MCXN947_MCXN947_CPU0_NS select SOC_MCXN947_CPU1 if BOARD_FRDM_MCXN947_MCXN947_CPU1 select SOC_PART_NUMBER_MCXN947VDF diff --git a/boards/nxp/frdm_mcxn947/board.cmake b/boards/nxp/frdm_mcxn947/board.cmake index f26f08890bfb..716926504f5c 100644 --- a/boards/nxp/frdm_mcxn947/board.cmake +++ b/boards/nxp/frdm_mcxn947/board.cmake @@ -1,5 +1,5 @@ # -# Copyright 2024 NXP +# Copyright 2024-2025 NXP # # SPDX-License-Identifier: Apache-2.0 # @@ -35,3 +35,8 @@ board_runner_args(pyocd "--target=mcxn947") include(${ZEPHYR_BASE}/boards/common/linkserver.board.cmake) include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake) + +if(CONFIG_BUILD_WITH_TFM) + # Flash merged TF-M + Zephyr binary + set_property(TARGET runners_yaml_props_target PROPERTY hex_file tfm_merged.hex) +endif() diff --git a/boards/nxp/frdm_mcxn947/board.yml b/boards/nxp/frdm_mcxn947/board.yml index dd17fc68dc48..a3f5e3a49052 100644 --- a/boards/nxp/frdm_mcxn947/board.yml +++ b/boards/nxp/frdm_mcxn947/board.yml @@ -7,3 +7,5 @@ board: variants: - name: qspi cpucluster: 'cpu0' + - name: ns + cpucluster: 'cpu0' diff --git a/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_ns.dts b/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_ns.dts new file mode 100644 index 000000000000..2162914ddff0 --- /dev/null +++ b/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_ns.dts @@ -0,0 +1,277 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include "frdm_mcxn947.dtsi" + +/ { + model = "NXP FRDM_N94 board"; + compatible = "nxp,mcxn947", "nxp,mcx"; + + cpus { + /delete-node/ cpu@1; + }; + + chosen { + zephyr,sram = &non_secure_ram; + zephyr,flash = &flash; + zephyr,code-partition = &slot0_ns_partition; + zephyr,flash-controller = &fmu; + zephyr,uart-mcumgr = &flexcomm4_lpuart4; + zephyr,console = &flexcomm4_lpuart4; + zephyr,shell-uart = &flexcomm4_lpuart4; + zephyr,canbus = &flexcan0; + }; + + reserved-memory { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + /* RAM split used by TFM */ + secure_ram: partition@20000000 { + label = "secure-memory"; + reg = <0x20000000 DT_SIZE_K(196)>; + }; + + non_secure_ram: partition@20030000 { + label = "non-secure-memory"; + reg = <0x20030000 DT_SIZE_K(128)>; + }; + }; +}; + +&flash { + /delete-node/ partitions; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + /* + * Partition sizes must be aligned + * to the flash memory sector size of 8KB. + */ + slot0_ns_partition: partition@80000 { + label = "image-0-nonsecure"; + reg = <0x00080000 DT_SIZE_K(512)>; + }; + }; +}; + +/* + * Default for this board is to allocate SRAM0-5 to cpu0 but the + * application can have an application specific device tree to + * allocate the SRAM0-7 differently. + * + * For example, SRAM0-6 could be allocated to cpu0 with only SRAM7 + * for cpu1. This would require the value of sram0 to have a DT_SIZE_K + * of 384. You would have to make updates to cpu1 sram settings as well. + */ + +&mbox { + status = "okay"; +}; + +&gpio4 { + status = "okay"; +}; + +&gpio1 { + status = "okay"; +}; + +&gpio0 { + status = "okay"; +}; + +&gpio2 { + status = "okay"; +}; + +&green_led { + status = "okay"; +}; + +&red_led { + status = "okay"; +}; + +&user_button_2 { + status = "okay"; +}; + +&edma0 { + status = "okay"; +}; + +&flexcomm1 { + status = "okay"; +}; + +&flexcomm1_lpspi1 { + status = "okay"; +}; + +&flexcomm2 { + status = "okay"; +}; + +&flexcomm2_lpi2c2 { + status = "okay"; +}; + +/* + *LPFLEXCOMM supports UART and I2C on the same instance, enable this for + * LFLEXCOMM2 + */ +&flexcomm2_lpuart2 { + status = "okay"; +}; + +&flexcomm4 { + status = "okay"; +}; + +&flexcomm4_lpuart4 { + status = "okay"; +}; + +&flexcomm7 { + status = "okay"; +}; + +&flexcomm7_lpi2c7 { + status = "okay"; +}; + +&flexspi { + status = "okay"; +}; + +&w25q64jvssiq { + status = "okay"; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + storage_partition: partition@0 { + label = "storage"; + reg = <0x0 DT_SIZE_M(8)>; + }; + }; +}; + +&dac0 { + status = "okay"; +}; + +&enet { + status = "okay"; +}; + +&enet_mac { + status = "okay"; +}; + +&enet_mdio { + status = "okay"; +}; + +&phy { + status = "okay"; +}; + +&wwdt0 { + status = "okay"; +}; + +&flexpwm1_pwm0 { + status = "okay"; +}; + +&flexcan0 { + status = "okay"; +}; + +&ctimer0 { + status = "okay"; +}; + +&usdhc0 { + status = "okay"; + + sdmmc { + compatible = "zephyr,sdmmc-disk"; + disk-name = "SD"; + status = "okay"; + }; +}; + +&vref { + status = "okay"; +}; + +&lpadc0 { + status = "okay"; +}; + +zephyr_udc0: &usb1 { + status = "okay"; + phy-handle = <&usbphy1>; +}; + +&usbphy1 { + status = "okay"; + tx-d-cal = <4>; + tx-cal-45-dp-ohms = <7>; + tx-cal-45-dm-ohms = <7>; +}; + +&lpcmp0 { + status = "okay"; +}; + +&lptmr0 { + status = "okay"; +}; + +&i3c1 { + status = "okay"; +}; + +&flexio0 { + status = "okay"; +}; + +&mrt0_channel0 { + status = "okay"; +}; + +&rtc { + status = "okay"; +}; + +&sc_timer { + status = "okay"; +}; + +&sai1 { + status = "okay"; +}; + +&sai0 { + status = "okay"; +}; + +&fmu { + status = "okay"; +}; diff --git a/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_ns.yaml b/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_ns.yaml new file mode 100644 index 000000000000..1c9ffac1c989 --- /dev/null +++ b/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_ns.yaml @@ -0,0 +1,17 @@ +# +# Copyright 2025 NXP +# +# SPDX-License-Identifier: Apache-2.0 +# + +identifier: frdm_mcxn947/mcxn947/cpu0/ns +name: NXP FRDM MCXN947 (CPU0) (Non-Secure) +type: mcu +arch: arm +ram: 128 +flash: 512 +toolchain: + - zephyr + - gnuarmemb +supported: [] +vendor: nxp diff --git a/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_ns_defconfig b/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_ns_defconfig new file mode 100644 index 000000000000..5c8a0bc5c59e --- /dev/null +++ b/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_ns_defconfig @@ -0,0 +1,19 @@ +# +# Copyright 2025 NXP +# +# SPDX-License-Identifier: Apache-2.0 +# + +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_UART_INTERRUPT_DRIVEN=y +CONFIG_GPIO=y + +CONFIG_ARM_MPU=y +CONFIG_HW_STACK_PROTECTION=y +CONFIG_TRUSTED_EXECUTION_NONSECURE=y + +CONFIG_TFM_BL2=n +CONFIG_BUILD_WITH_TFM=y +CONFIG_FLASH_BASE_ADDRESS=0x80000 \ No newline at end of file From 6cf47cae57ce07828f9144fbec18f731dc64b5b5 Mon Sep 17 00:00:00 2001 From: Guido Roncarolo Date: Mon, 17 Nov 2025 13:45:32 +0100 Subject: [PATCH 0499/3659] modules: tf-m: add MCNX947 in cmake and kconfig Added MCNX947 support in trusted-firmware-m module Cmake and Kconfig. Cmake is cleaned, removed unused variables. Signed-off-by: Guido Roncarolo --- .../nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_ns_defconfig | 2 +- modules/trusted-firmware-m/CMakeLists.txt | 6 ------ modules/trusted-firmware-m/Kconfig.tfm | 2 ++ 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_ns_defconfig b/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_ns_defconfig index 5c8a0bc5c59e..9f421c6b50bb 100644 --- a/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_ns_defconfig +++ b/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_ns_defconfig @@ -16,4 +16,4 @@ CONFIG_TRUSTED_EXECUTION_NONSECURE=y CONFIG_TFM_BL2=n CONFIG_BUILD_WITH_TFM=y -CONFIG_FLASH_BASE_ADDRESS=0x80000 \ No newline at end of file +CONFIG_FLASH_BASE_ADDRESS=0x80000 diff --git a/modules/trusted-firmware-m/CMakeLists.txt b/modules/trusted-firmware-m/CMakeLists.txt index 20d2f48aa632..d18a1e44f7f0 100644 --- a/modules/trusted-firmware-m/CMakeLists.txt +++ b/modules/trusted-firmware-m/CMakeLists.txt @@ -253,12 +253,6 @@ if(CONFIG_BUILD_WITH_TFM) string(REPLACE "toolchain" "toolchain_ns" TFM_TOOLCHAIN_NS_FILE ${TFM_TOOLCHAIN_FILE}) - if(CONFIG_BOARD_LPCXPRESSO55S69_LPC55S69_CPU0_NS) - # Supply path to NXP HAL sources used for TF-M build - set(TFM_PLATFORM_NXP_HAL_FILE_PATH ${ZEPHYR_TRUSTED_FIRMWARE_M_MODULE_DIR}/platform/ext/target/nxp/) - list(APPEND TFM_CMAKE_ARGS -DTFM_PLATFORM_NXP_HAL_FILE_PATH=${TFM_PLATFORM_NXP_HAL_FILE_PATH}) - endif() - if(CONFIG_BOARD_MAX32657EVKIT_MAX32657_NS OR CONFIG_BOARD_MAX32658EVKIT_MAX32658_NS) # Supply path to hal_adi for TF-M build list(APPEND TFM_CMAKE_ARGS -DHAL_ADI_PATH=${ZEPHYR_ADI_MODULE_DIR}) diff --git a/modules/trusted-firmware-m/Kconfig.tfm b/modules/trusted-firmware-m/Kconfig.tfm index 692cd9efa5e9..e28c087736e8 100644 --- a/modules/trusted-firmware-m/Kconfig.tfm +++ b/modules/trusted-firmware-m/Kconfig.tfm @@ -3,6 +3,7 @@ # Copyright (c) 2019, 2020 Linaro Limited # Copyright (c) 2020, 2021 Nordic Semiconductor ASA # Copyright 2024-2025 Arm Limited and/or its affiliates +# Copyright 2025 NXP # SPDX-License-Identifier: Apache-2.0 config ZEPHYR_TRUSTED_FIRMWARE_M_MODULE @@ -12,6 +13,7 @@ config TFM_BOARD string default "adi/max32657" if BOARD_MAX32657EVKIT_MAX32657_NS || BOARD_MAX32658EVKIT_MAX32658_NS default "arm/mps2/an521" if BOARD_MPS2_AN521_CPU0_NS + default "nxp/frdmmcxn947" if BOARD_FRDM_MCXN947_MCXN947_CPU0_NS default "arm/mps3/corstone300/fvp" if BOARD_MPS3_CORSTONE300_FVP_NS default "arm/mps3/corstone300/an547" if BOARD_MPS3_CORSTONE300_AN547_NS default "arm/mps3/corstone300/an552" if BOARD_MPS3_CORSTONE300_AN552_NS From 3dec364bd8713c059f8cac87307e69d916eb4bfc Mon Sep 17 00:00:00 2001 From: Guido Roncarolo Date: Tue, 18 Nov 2025 07:10:48 +0100 Subject: [PATCH 0500/3659] boards: disable trng in ns-dts and get it working with zephyr 4.3 25a71f39727cc3257c218d4cd9205fe97a159e5f changes the behavior so that : if "zephyr,entropy" is set in the DT then CONFIG_CSPRNG_AVAILABLE get enabled; This breaks our implementation, disable the trng in ns world for now Signed-off-by: Guido Roncarolo --- boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_ns.dts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_ns.dts b/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_ns.dts index 2162914ddff0..07e3d36cebfa 100644 --- a/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_ns.dts +++ b/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_ns.dts @@ -26,6 +26,7 @@ zephyr,console = &flexcomm4_lpuart4; zephyr,shell-uart = &flexcomm4_lpuart4; zephyr,canbus = &flexcan0; + zephyr,entropy = &trng; }; reserved-memory { @@ -275,3 +276,8 @@ zephyr_udc0: &usb1 { &fmu { status = "okay"; }; + +&trng { + /* Disable TRNG in NS to avoid auto-enabling csprng_available option */ + status = "disabled"; +}; From 48fa32c76f3363cb8c3a641ae6207e06e29ad545 Mon Sep 17 00:00:00 2001 From: Waqar Tahir Date: Wed, 10 Dec 2025 17:09:21 +0100 Subject: [PATCH 0501/3659] samples: tfm: Add mcxn947 in TF-M samples yaml Add mcxn947 non secure target for the tfm_ipc and tfm_regression samples. Signed-off-by: Waqar Tahir --- samples/tfm_integration/tfm_ipc/sample.yaml | 1 + samples/tfm_integration/tfm_regression_test/sample.yaml | 1 + 2 files changed, 2 insertions(+) diff --git a/samples/tfm_integration/tfm_ipc/sample.yaml b/samples/tfm_integration/tfm_ipc/sample.yaml index e9dccceb5050..b049f7a82a16 100644 --- a/samples/tfm_integration/tfm_ipc/sample.yaml +++ b/samples/tfm_integration/tfm_ipc/sample.yaml @@ -37,6 +37,7 @@ tests: - nrf54l15dk/nrf54l15/cpuapp/ns - nrf54l15dk/nrf54l10/cpuapp/ns - nrf54lm20dk/nrf54lm20a/cpuapp/ns + - frdm_mcxn947/mcxn947/cpu0/ns extra_configs: - CONFIG_TFM_BL2=n harness: console diff --git a/samples/tfm_integration/tfm_regression_test/sample.yaml b/samples/tfm_integration/tfm_regression_test/sample.yaml index df68fee84a74..467b9890fe6c 100644 --- a/samples/tfm_integration/tfm_regression_test/sample.yaml +++ b/samples/tfm_integration/tfm_regression_test/sample.yaml @@ -10,6 +10,7 @@ common: - nrf9161dk/nrf9161/ns - v2m_musca_s1/musca_s1/ns - stm32h573i_dk/stm32h573xx/ns + - frdm_mcxn947/mcxn947/cpu0/ns integration_platforms: - nrf5340dk/nrf5340/cpuapp/ns harness: console From 3e1f0bb5b87dbca741531ac74ae2b9960afec681 Mon Sep 17 00:00:00 2001 From: Waqar Tahir Date: Thu, 11 Dec 2025 11:12:19 +0100 Subject: [PATCH 0502/3659] manifest: tf-m: support for mcxn947 Updated the TF-M repo for support of mcxn947 Signed-off-by: Waqar Tahir --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index e8920224fb0e..9f45c2a7640c 100644 --- a/west.yml +++ b/west.yml @@ -385,7 +385,7 @@ manifest: groups: - tee - name: trusted-firmware-m - revision: db82030ab21def6d170a7a7ef8def5081ed6f328 + revision: e9ea674ed02e8ee00548f1bb994d52df23c8068d path: modules/tee/tf-m/trusted-firmware-m groups: - tee From 9fe6302151ad70d74bd3b576953844c9bf178489 Mon Sep 17 00:00:00 2001 From: Yerrajennugari Raj Kumar Date: Thu, 11 Dec 2025 14:57:25 +0530 Subject: [PATCH 0503/3659] drivers: espi: npcx: Add config to disable auto-ack and use callback Added configuration option to disable auto acknowledgment for virtual wire WARN signals and added a callback to handle them. This change introduces: 1. Support to disable automatic acknowledgment for VW WARN signals. 2. A callback mechanism to notify application firmware for explicit handling. Behavior: 1. If auto-ack is disabled, the callback notifies the application to handle VW WARN signals. 2. If auto-ack is enabled, the driver acknowledges VW WARN signals without notifying the application. Signed-off-by: Yerrajennugari Raj Kumar --- drivers/espi/espi_npcx.c | 45 +++++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/drivers/espi/espi_npcx.c b/drivers/espi/espi_npcx.c index f656082fee8f..dab266336230 100644 --- a/drivers/espi/espi_npcx.c +++ b/drivers/espi/espi_npcx.c @@ -600,27 +600,34 @@ static void espi_vw_notify_host_warning(const struct device *dev, espi_npcx_receive_vwire(dev, signal, &wire); k_busy_wait(NPCX_ESPI_VWIRE_ACK_DELAY); - switch (signal) { - case ESPI_VWIRE_SIGNAL_HOST_RST_WARN: - espi_npcx_send_vwire(dev, - ESPI_VWIRE_SIGNAL_HOST_RST_ACK, - wire); - break; - case ESPI_VWIRE_SIGNAL_SUS_WARN: - espi_npcx_send_vwire(dev, ESPI_VWIRE_SIGNAL_SUS_ACK, - wire); - break; - case ESPI_VWIRE_SIGNAL_OOB_RST_WARN: - espi_npcx_send_vwire(dev, ESPI_VWIRE_SIGNAL_OOB_RST_ACK, - wire); - break; + if (!IS_ENABLED(CONFIG_ESPI_AUTOMATIC_WARNING_ACKNOWLEDGE)) { + struct espi_npcx_data *const data = dev->data; + struct espi_event evt = {ESPI_BUS_EVENT_VWIRE_RECEIVED, 0, 0 }; + + evt.evt_details = signal; + evt.evt_data = wire; + espi_send_callbacks(&data->callbacks, dev, evt); + } else { + switch (signal) { + case ESPI_VWIRE_SIGNAL_HOST_RST_WARN: + espi_npcx_send_vwire(dev, ESPI_VWIRE_SIGNAL_HOST_RST_ACK, + wire); + break; + case ESPI_VWIRE_SIGNAL_SUS_WARN: + espi_npcx_send_vwire(dev, ESPI_VWIRE_SIGNAL_SUS_ACK, + wire); + break; + case ESPI_VWIRE_SIGNAL_OOB_RST_WARN: + espi_npcx_send_vwire(dev, ESPI_VWIRE_SIGNAL_OOB_RST_ACK, + wire); + break; #if DT_NODE_EXISTS(DT_CHILD(DT_PATH(npcx_espi_vws_map), vw_dnx_warn)) - case ESPI_VWIRE_SIGNAL_DNX_WARN: - espi_npcx_send_vwire(dev, ESPI_VWIRE_SIGNAL_DNX_ACK, wire); - break; + case ESPI_VWIRE_SIGNAL_DNX_WARN: + espi_npcx_send_vwire(dev, ESPI_VWIRE_SIGNAL_DNX_ACK, wire); + break; #endif - default: - break; + default: + break; } } From 858acad5ac4e12b10ef5508d20215544505985a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20K=C3=A4sser?= Date: Sat, 13 Dec 2025 15:19:42 +0100 Subject: [PATCH 0504/3659] doc: fix CONFIG_PM_DEVICE_RUNTIME_ASYNC typo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixed typo CONFIOG_PM_DEVICE_RUNTIME_ASYNC to CONFIG_PM_DEVICE_RUNTIME_ASYNC in device runtime PM documentation. Signed-off-by: Tobias Kässer --- doc/services/pm/device_runtime.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/services/pm/device_runtime.rst b/doc/services/pm/device_runtime.rst index 19b5bc122fcc..b69e6b4b3d53 100644 --- a/doc/services/pm/device_runtime.rst +++ b/doc/services/pm/device_runtime.rst @@ -126,7 +126,7 @@ Drivers that require this behavior can explicitly request it by enabling For targets with constrained resources that do not need asynchronous operations, this functionality can be disabled altogether by -de-selecting :kconfig:option:`CONFIOG_PM_DEVICE_RUNTIME_ASYNC`, reducing +de-selecting :kconfig:option:`CONFIG_PM_DEVICE_RUNTIME_ASYNC`, reducing memory usage and system complexity. From 443862ddffb7cccf71fbcde844c8132e84fb8cd0 Mon Sep 17 00:00:00 2001 From: Sylvio Alves Date: Sat, 13 Dec 2025 19:28:01 -0300 Subject: [PATCH 0505/3659] drivers: uart: esp32: fix async RX byte count from DMA descriptor In async UART mode with DMA, the RX completion callback was incorrectly relying on rx_counter which is never updated in DMA mode since data bypasses the UART FIFO via UHCI+GDMA. Fix by reading the actual transferred byte count from the DMA descriptor's length field using gdma_ll_rx_get_success_eof_desc_addr(). Direct LL calls are used because this runs in ISR context where dma_get_status() is not IRAM-safe. Signed-off-by: Sylvio Alves --- drivers/serial/uart_esp32.c | 94 +++++++++++++++++++++++++++++++++---- 1 file changed, 84 insertions(+), 10 deletions(-) diff --git a/drivers/serial/uart_esp32.c b/drivers/serial/uart_esp32.c index e82f775e5617..ffff07096917 100644 --- a/drivers/serial/uart_esp32.c +++ b/drivers/serial/uart_esp32.c @@ -42,6 +42,9 @@ #include #include #include +#include +#include +#include #endif #include #include @@ -552,13 +555,37 @@ static void IRAM_ATTR uart_esp32_dma_rx_done(const struct device *dma_dev, void const struct device *uart_dev = user_data; const struct uart_esp32_config *config = uart_dev->config; struct uart_esp32_data *data = uart_dev->data; + gdma_hal_context_t *dma_hal = dma_dev->data; struct uart_event evt = {0}; + dma_descriptor_t *desc; + size_t rx_bytes; unsigned int key = irq_lock(); - /* If the receive buffer is not complete we reload the DMA at current buffer position and - * let the timeout callback handle the notifications + /* + * Read actual transferred bytes from DMA descriptor. + * Direct LL calls used because this ISR context requires IRAM-safe code. + * Note: We SET rx_counter (not add) because the UART ISR also increments + * rx_counter on RXFIFO_FULL interrupts, and the DMA descriptor contains + * the authoritative byte count. + */ + desc = (dma_descriptor_t *)gdma_ll_rx_get_success_eof_desc_addr(dma_hal->dev, + config->rx_dma_channel / 2); + if (desc) { + rx_bytes = desc->dw0.length; + } else { + /* Fallback to full buffer if descriptor unavailable */ + rx_bytes = data->async.rx_len; + } + + data->async.rx_counter = data->async.rx_offset + rx_bytes; + + /* + * If buffer is not full and no timeout is configured, reload DMA to + * continue receiving into the same buffer. The timeout callback will + * handle notifications for partial data. */ - if (data->async.rx_counter != data->async.rx_len) { + if (data->async.rx_counter < data->async.rx_len && + data->async.rx_timeout == SYS_FOREVER_US) { dma_reload(config->dma_dev, config->rx_dma_channel, 0, (uint32_t)data->async.rx_buf + data->async.rx_counter, data->async.rx_len - data->async.rx_counter); @@ -568,7 +595,7 @@ static void IRAM_ATTR uart_esp32_dma_rx_done(const struct device *dma_dev, void return; } - /*Notify RX_RDY*/ + /* Notify RX_RDY */ evt.type = UART_RX_RDY; evt.data.rx.buf = data->async.rx_buf; evt.data.rx.len = data->async.rx_counter - data->async.rx_offset; @@ -581,14 +608,14 @@ static void IRAM_ATTR uart_esp32_dma_rx_done(const struct device *dma_dev, void data->async.rx_offset = 0; data->async.rx_counter = 0; - /*Release current buffer*/ + /* Release current buffer */ evt.type = UART_RX_BUF_RELEASED; evt.data.rx_buf.buf = data->async.rx_buf; if (data->async.cb) { data->async.cb(uart_dev, &evt, data->async.user_data); } - /*Load next buffer and request another*/ + /* Load next buffer and request another */ data->async.rx_buf = data->async.rx_next_buf; data->async.rx_len = data->async.rx_next_len; data->async.rx_next_buf = NULL; @@ -598,14 +625,14 @@ static void IRAM_ATTR uart_esp32_dma_rx_done(const struct device *dma_dev, void data->async.cb(uart_dev, &evt, data->async.user_data); } - /*Notify RX_DISABLED when there is no buffer*/ + /* Notify RX_DISABLED when there is no buffer */ if (!data->async.rx_buf) { evt.type = UART_RX_DISABLED; if (data->async.cb) { data->async.cb(uart_dev, &evt, data->async.user_data); } } else { - /*Reload DMA with new buffer*/ + /* Reload DMA with new buffer */ dma_reload(config->dma_dev, config->rx_dma_channel, 0, (uint32_t)data->async.rx_buf, data->async.rx_len); dma_start(config->dma_dev, config->rx_dma_channel); @@ -642,12 +669,24 @@ static int uart_esp32_async_tx_abort(const struct device *dev) { const struct uart_esp32_config *config = dev->config; struct uart_esp32_data *data = dev->data; + struct dma_status dma_status = {0}; struct uart_event evt = {0}; + size_t tx_sent; int err = 0; unsigned int key = irq_lock(); k_work_cancel_delayable(&data->async.tx_timeout_work); + /* + * Get actual transferred bytes from DMA status before stopping. + * This tells us how many bytes were actually sent before the abort. + */ + if (dma_get_status(config->dma_dev, config->tx_dma_channel, &dma_status) == 0) { + tx_sent = dma_status.total_copied; + } else { + tx_sent = data->async.tx_len; + } + err = dma_stop(config->dma_dev, config->tx_dma_channel); if (err) { LOG_ERR("Error stopping Tx DMA (%d)", err); @@ -656,7 +695,7 @@ static int uart_esp32_async_tx_abort(const struct device *dev) evt.type = UART_TX_ABORTED; evt.data.tx.buf = data->async.tx_buf; - evt.data.tx.len = data->async.tx_len; + evt.data.tx.len = tx_sent; if (data->async.cb) { data->async.cb(dev, &evt, data->async.user_data); @@ -683,8 +722,29 @@ static void uart_esp32_async_rx_timeout(struct k_work *work) struct uart_esp32_async_data *async = CONTAINER_OF(dwork, struct uart_esp32_async_data, rx_timeout_work); struct uart_esp32_data *data = CONTAINER_OF(async, struct uart_esp32_data, async); + const struct uart_esp32_config *config = data->uart_dev->config; + struct dma_status dma_status = {0}; struct uart_event evt = {0}; - unsigned int key = irq_lock(); + size_t rx_count; + unsigned int key; + + /* + * Get actual transferred bytes from DMA descriptor. + * In DMA mode, data goes directly to memory via UHCI+GDMA, bypassing + * the UART FIFO. So rx_counter (updated by FIFO Full ISR) is not reliable. + * Instead, read total_copied from DMA status. + */ + if (dma_get_status(config->dma_dev, config->rx_dma_channel, &dma_status) == 0) { + rx_count = dma_status.total_copied; + } else { + /* Fallback to rx_counter if DMA status unavailable */ + rx_count = data->async.rx_counter; + } + + key = irq_lock(); + + /* Update rx_counter with actual DMA progress */ + data->async.rx_counter = rx_count; evt.type = UART_RX_RDY; evt.data.rx.buf = data->async.rx_buf; @@ -842,6 +902,20 @@ static int uart_esp32_async_rx_enable(const struct device *dev, uint8_t *buf, si data->uhci_dev->pkt_thres.thrs = len; + /* + * Configure UHCI EOF mode based on timeout setting. + * For SYS_FOREVER_US, only use length-based EOF to avoid spurious + * callbacks when UART goes idle before buffer is full. + * For other timeouts, also enable idle-based EOF. + */ + if (timeout == SYS_FOREVER_US) { + data->uhci_dev->conf0.len_eof_en = 1; + data->uhci_dev->conf0.uart_idle_eof_en = 0; + } else { + data->uhci_dev->conf0.len_eof_en = 1; + data->uhci_dev->conf0.uart_idle_eof_en = 1; + } + /** * Request next buffer */ From 97f497155b03a3f338a554ae644bae3e023cfd1f Mon Sep 17 00:00:00 2001 From: Holt Sun Date: Sun, 14 Dec 2025 18:02:23 +0800 Subject: [PATCH 0506/3659] drivers: flash: mcux_flexspi: fix cache unused variable warning Preserve original write length for DCACHE_InvalidateByRange() Guard declaration of `size` with CONFIG_HAS_MCUX_CACHE to avoid unused-variable warnings when cache is disabled Add pointer validity checks before cache invalidation Signed-off-by: Holt Sun --- drivers/flash/flash_mcux_flexspi_mx25um51345g.c | 10 ++++++++++ drivers/flash/flash_mcux_flexspi_nor.c | 13 +++++++++++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/drivers/flash/flash_mcux_flexspi_mx25um51345g.c b/drivers/flash/flash_mcux_flexspi_mx25um51345g.c index fc712f12489a..690c3e8638a8 100644 --- a/drivers/flash/flash_mcux_flexspi_mx25um51345g.c +++ b/drivers/flash/flash_mcux_flexspi_mx25um51345g.c @@ -388,7 +388,9 @@ static int flash_flexspi_nor_write(const struct device *dev, off_t offset, const void *buffer, size_t len) { struct flash_flexspi_nor_data *data = dev->data; +#ifdef CONFIG_HAS_MCUX_CACHE size_t size = len; +#endif uint8_t *src = (uint8_t *) buffer; int i; unsigned int key = 0; @@ -397,6 +399,10 @@ static int flash_flexspi_nor_write(const struct device *dev, off_t offset, data->port, offset); + if (!dst) { + return -EINVAL; + } + if (memc_flexspi_is_running_xip(data->controller)) { /* * ==== ENTER CRITICAL SECTION ==== @@ -465,6 +471,10 @@ static int flash_flexspi_nor_erase(const struct device *dev, off_t offset, data->port, offset); + if (!dst) { + return -EINVAL; + } + if (offset % SPI_NOR_SECTOR_SIZE) { LOG_ERR("Invalid offset"); return -EINVAL; diff --git a/drivers/flash/flash_mcux_flexspi_nor.c b/drivers/flash/flash_mcux_flexspi_nor.c index 61752717ee2f..934c2922489c 100644 --- a/drivers/flash/flash_mcux_flexspi_nor.c +++ b/drivers/flash/flash_mcux_flexspi_nor.c @@ -357,7 +357,9 @@ static int flash_flexspi_nor_write(const struct device *dev, off_t offset, const void *buffer, size_t len) { struct flash_flexspi_nor_data *data = dev->data; - +#ifdef CONFIG_HAS_MCUX_CACHE + size_t size = len; +#endif if (!buffer) { return -EINVAL; } @@ -366,7 +368,6 @@ static int flash_flexspi_nor_write(const struct device *dev, off_t offset, return -EINVAL; } - size_t size = len; uint8_t *src = (uint8_t *) buffer; int i; unsigned int key = 0; @@ -375,6 +376,10 @@ static int flash_flexspi_nor_write(const struct device *dev, off_t offset, data->port, offset); + if (!dst) { + return -EINVAL; + } + if (memc_flexspi_is_running_xip(&data->controller)) { /* * ==== ENTER CRITICAL SECTION ==== @@ -441,6 +446,10 @@ static int flash_flexspi_nor_erase(const struct device *dev, off_t offset, data->port, offset); + if (!dst) { + return -EINVAL; + } + if (offset % SPI_NOR_SECTOR_SIZE) { LOG_ERR("Invalid offset"); return -EINVAL; From cbd5687fc2b671b35e30f1de7c44e9bf43653878 Mon Sep 17 00:00:00 2001 From: Jordan Yates Date: Mon, 15 Dec 2025 10:02:21 +1000 Subject: [PATCH 0507/3659] wifi: nrf_wifi: return errors when bringups fail The combination of two different return variables (`status` and `ret`) resulted in most failure paths through the bringup code still returning success. Signed-off-by: Jordan Yates --- drivers/wifi/nrf_wifi/src/net_if.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/wifi/nrf_wifi/src/net_if.c b/drivers/wifi/nrf_wifi/src/net_if.c index ea1b146e0538..9a9d7d670267 100644 --- a/drivers/wifi/nrf_wifi/src/net_if.c +++ b/drivers/wifi/nrf_wifi/src/net_if.c @@ -780,6 +780,7 @@ int nrf_wifi_if_start_zep(const struct device *dev) if (!rpu_ctx_zep) { LOG_ERR("%s: rpu_ctx_zep is NULL", __func__); + ret = -EIO; goto out; } @@ -795,6 +796,7 @@ int nrf_wifi_if_start_zep(const struct device *dev) if (status != NRF_WIFI_STATUS_SUCCESS) { LOG_ERR("%s: nrf_wifi_fmac_dev_add_zep failed", __func__); + ret = -EIO; goto out; } fmac_dev_added = true; @@ -820,6 +822,7 @@ int nrf_wifi_if_start_zep(const struct device *dev) if (vif_ctx_zep->vif_idx >= MAX_NUM_VIFS) { LOG_ERR("%s: FMAC returned invalid interface index", __func__); + ret = -EIO; goto dev_rem; } @@ -837,6 +840,7 @@ int nrf_wifi_if_start_zep(const struct device *dev) if (status != NRF_WIFI_STATUS_SUCCESS) { LOG_ERR("%s: Failed to get MAC address", __func__); + ret = -EIO; goto del_vif; } net_if_set_link_addr(vif_ctx_zep->zep_net_if_ctx, @@ -854,6 +858,7 @@ int nrf_wifi_if_start_zep(const struct device *dev) if (status != NRF_WIFI_STATUS_SUCCESS) { LOG_ERR("%s: MAC address change failed", __func__); + ret = -EIO; goto del_vif; } @@ -875,6 +880,7 @@ int nrf_wifi_if_start_zep(const struct device *dev) if (status != NRF_WIFI_STATUS_SUCCESS) { LOG_ERR("%s: nrf_wifi_sys_fmac_chg_vif_state failed", __func__); + ret = -EIO; goto del_vif; } @@ -889,6 +895,7 @@ int nrf_wifi_if_start_zep(const struct device *dev) if (status != NRF_WIFI_STATUS_SUCCESS) { LOG_ERR("%s: nrf_wifi_sys_fmac_set_power_save failed", __func__); + ret = -EIO; goto dev_rem; } #endif /* CONFIG_NRF_WIFI_LOW_POWER */ From c13420333c568fa6d822e08f1eac29fc051e1b6a Mon Sep 17 00:00:00 2001 From: Jordan Yates Date: Mon, 15 Dec 2025 10:03:44 +1000 Subject: [PATCH 0508/3659] wifi: nrf_wifi: respect `SHELL_STACK_SIZE` dependencies `SHELL_STACK_SIZE` should not be redefined as a symbol with no dependencies, it should be applying a new default to the existing symbol. Signed-off-by: Jordan Yates --- drivers/wifi/nrf_wifi/Kconfig.nrfwifi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/wifi/nrf_wifi/Kconfig.nrfwifi b/drivers/wifi/nrf_wifi/Kconfig.nrfwifi index cb45ea90b575..a4603cf96a9b 100644 --- a/drivers/wifi/nrf_wifi/Kconfig.nrfwifi +++ b/drivers/wifi/nrf_wifi/Kconfig.nrfwifi @@ -646,7 +646,7 @@ endif # NRF_WIFI_USE_VARIABLE_NET_BUFS config MAIN_STACK_SIZE default 4096 -config SHELL_STACK_SIZE +configdefault SHELL_STACK_SIZE default 4096 # Override the Wi-Fi subsystems WIFI_MGMT_SCAN_SSID_FILT_MAX parameter, From b362eca3b0517dec1dfe5acdbd6278976304aea1 Mon Sep 17 00:00:00 2001 From: Jordan Yates Date: Mon, 15 Dec 2025 14:32:16 +1000 Subject: [PATCH 0509/3659] modules: nrf_wifi: bus: SPI keep ACTIVE Add an option to keep the SPI bus in `ACTIVE` while the WiFi module is powered up. Previous testing has shown transitioning the bus on every SPI transaction to reduce UDP uplink throughput from 8 Mbps to 6 Mbps. Signed-off-by: Jordan Yates --- modules/nrf_wifi/bus/Kconfig | 10 ++++++++++ modules/nrf_wifi/bus/spi_if.c | 9 +++++++++ 2 files changed, 19 insertions(+) diff --git a/modules/nrf_wifi/bus/Kconfig b/modules/nrf_wifi/bus/Kconfig index 430cf3ba9ffd..91b198cb3cb0 100644 --- a/modules/nrf_wifi/bus/Kconfig +++ b/modules/nrf_wifi/bus/Kconfig @@ -53,4 +53,14 @@ config NRF70_LOG_VERBOSE bool "Maintains the verbosity of information in logs" default y +config NRF70_SPI_PM_CLAIM_WHILE_ACTIVE + bool "Keep SPI bus in ACTIVE state while nRF70 is powered" + depends on PM_DEVICE_RUNTIME + depends on NRF70_ON_SPI + help + Requesting and releasing the SPI bus on every bus transaction when PM + device runtime is enabled has a negative impact on data throughput. + Enabling this option keeps the bus in the active state while the interface + is powered up. + endif # NRF70_BUSLIB diff --git a/modules/nrf_wifi/bus/spi_if.c b/modules/nrf_wifi/bus/spi_if.c index 402cf565af21..a7a3e4f825f5 100644 --- a/modules/nrf_wifi/bus/spi_if.c +++ b/modules/nrf_wifi/bus/spi_if.c @@ -14,6 +14,7 @@ #include #include #include +#include #include "spi_if.h" @@ -286,11 +287,19 @@ int spim_init(struct qspi_config *config) spi_spec.config.frequency / MHZ(1)); LOG_INF("SPIM %s: latency = %d", spi_spec.bus->name, spim_config->qspi_slave_latency); +#ifdef CONFIG_NRF70_SPI_PM_CLAIM_WHILE_ACTIVE + return pm_device_runtime_get(spi_spec.bus); +#else return 0; +#endif /* CONFIG_NRF70_SPI_PM_CLAIM_WHILE_ACTIVE */ } int spim_deinit(void) { +#ifdef CONFIG_NRF70_SPI_PM_CLAIM_WHILE_ACTIVE + (void)pm_device_runtime_put(spi_spec.bus); +#endif /* CONFIG_NRF70_SPI_PM_CLAIM_WHILE_ACTIVE */ + return spi_release_dt(&spi_spec); } From 7c67dea76a9081f790766391cec1ac1302eec842 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Mon, 15 Dec 2025 17:36:43 +0200 Subject: [PATCH 0510/3659] intel_adsp: common: gdbstub: Fix compilation DEBUG_SLOT_MANAGER=n The GDB is not compiled by default and a recent change in the slot manager series contained a typo in ifdef and missed by not compiling the GDB support. Fixes: ebb5625bee8a ("intel_adsp: Add debug slot manager") Signed-off-by: Peter Ujfalusi --- soc/intel/intel_adsp/common/gdbstub_backend_sram.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/soc/intel/intel_adsp/common/gdbstub_backend_sram.c b/soc/intel/intel_adsp/common/gdbstub_backend_sram.c index 4a33e9397d60..4a0f908fc8a7 100644 --- a/soc/intel/intel_adsp/common/gdbstub_backend_sram.c +++ b/soc/intel/intel_adsp/common/gdbstub_backend_sram.c @@ -60,7 +60,7 @@ static inline int ring_have_data(const volatile struct gdb_sram_ring *ring) static volatile struct gdb_sram_ring *rx; static volatile struct gdb_sram_ring *tx; -#ifndef CONFIG_INTEL_ADSP_DEBUG_SLOT_MANAGER +#ifdef CONFIG_INTEL_ADSP_DEBUG_SLOT_MANAGER static int gdb_get_debug_slot(void) { struct adsp_dw_desc slot_desc = { .type = ADSP_DW_SLOT_GDB_STUB, }; @@ -83,6 +83,7 @@ static int gdb_get_debug_slot(void) return 0; } +#else #define RX_UNCACHED (uint8_t *) (HP_SRAM_WIN2_BASE + SOF_GDB_WINDOW_OFFSET) #define TX_UNCACHED (uint8_t *) (RX_UNCACHED + sizeof(struct gdb_sram_ring)) #endif From d38432761faac899095deb0dc4d56e0f9df8a85c Mon Sep 17 00:00:00 2001 From: James Smith Date: Tue, 16 Dec 2025 16:30:02 -0800 Subject: [PATCH 0511/3659] drivers: i2c: silabs: Don't fail to init is clock is already enabled Don't fail to initialize i2c if it was already initialized, for example by mcuboot. Signed-off-by: James Smith --- drivers/i2c/i2c_silabs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/i2c/i2c_silabs.c b/drivers/i2c/i2c_silabs.c index 94bc61833aa4..3edd9fd0c426 100644 --- a/drivers/i2c/i2c_silabs.c +++ b/drivers/i2c/i2c_silabs.c @@ -428,7 +428,7 @@ static int i2c_silabs_dev_init(const struct device *dev) /* Enable clock */ ret = clock_control_on(config->clock, (clock_control_subsys_t)&config->clock_cfg); - if (ret < 0) { + if (ret < 0 && ret != -EALREADY) { return ret; } From f3fed0bb8bd3bb1416df589f4a077abb1b9880a1 Mon Sep 17 00:00:00 2001 From: The Nguyen Date: Fri, 5 Dec 2025 06:06:26 +0000 Subject: [PATCH 0512/3659] manifest: update hal_renesas revision Update hal_renesas revision to fix Renesas RA SDRAM macro typo Signed-off-by: The Nguyen --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 9f45c2a7640c..01700efd6443 100644 --- a/west.yml +++ b/west.yml @@ -231,7 +231,7 @@ manifest: - hal - name: hal_renesas path: modules/hal/renesas - revision: d01039075990309dcbbec9b86510ed9f70a01dff + revision: 69c3df17e3788f1ba8c7ace191e21e20bbd8d641 groups: - hal - name: hal_rpi_pico From d1d99918e5d876a41146806008ee8d6c911821cc Mon Sep 17 00:00:00 2001 From: The Nguyen Date: Fri, 5 Dec 2025 05:36:25 +0000 Subject: [PATCH 0513/3659] dt-binding: memc: renesas: fix macro name misspelling Some macros defined for SDRAM timing configuration have typo. This commit fixes the mistake and updates the macro used in the code. Signed-off-by: The Nguyen --- boards/renesas/ek_ra8d1/ek_ra8d1.dts | 4 +- boards/renesas/ek_ra8d2/ek_ra8d2.dtsi | 4 +- boards/renesas/ek_ra8p1/ek_ra8p1.dtsi | 4 +- .../ra8d1_vision_board/ra8d1_vision_board.dts | 4 +- .../memory-controller/renesas,ra-sdram.h | 69 ++++++++++--------- 5 files changed, 43 insertions(+), 42 deletions(-) diff --git a/boards/renesas/ek_ra8d1/ek_ra8d1.dts b/boards/renesas/ek_ra8d1/ek_ra8d1.dts index ce3a34657dc2..e3920943da78 100644 --- a/boards/renesas/ek_ra8d1/ek_ra8d1.dts +++ b/boards/renesas/ek_ra8d1/ek_ra8d1.dts @@ -425,8 +425,8 @@ pinctrl-0 = <&sdram_default>; pinctrl-names = "default"; status = "okay"; - auto-refresh-interval = ; - auto-refresh-count = ; + auto-refresh-interval = ; + auto-refresh-count = ; precharge-cycle-count = ; multiplex-addr-shift = "10-bit"; edian-mode = "little-endian"; diff --git a/boards/renesas/ek_ra8d2/ek_ra8d2.dtsi b/boards/renesas/ek_ra8d2/ek_ra8d2.dtsi index 85d6734513c4..1358af594e5d 100644 --- a/boards/renesas/ek_ra8d2/ek_ra8d2.dtsi +++ b/boards/renesas/ek_ra8d2/ek_ra8d2.dtsi @@ -203,8 +203,8 @@ pinctrl-0 = <&sdram_default>; pinctrl-names = "default"; status = "okay"; - auto-refresh-interval = ; - auto-refresh-count = ; + auto-refresh-interval = ; + auto-refresh-count = ; precharge-cycle-count = ; multiplex-addr-shift = "9-bit"; edian-mode = "little-endian"; diff --git a/boards/renesas/ek_ra8p1/ek_ra8p1.dtsi b/boards/renesas/ek_ra8p1/ek_ra8p1.dtsi index 9adfec33e7f3..e1530200bfe6 100644 --- a/boards/renesas/ek_ra8p1/ek_ra8p1.dtsi +++ b/boards/renesas/ek_ra8p1/ek_ra8p1.dtsi @@ -203,8 +203,8 @@ pinctrl-0 = <&sdram_default>; pinctrl-names = "default"; status = "okay"; - auto-refresh-interval = ; - auto-refresh-count = ; + auto-refresh-interval = ; + auto-refresh-count = ; precharge-cycle-count = ; multiplex-addr-shift = "9-bit"; edian-mode = "little-endian"; diff --git a/boards/ruiside/ra8d1_vision_board/ra8d1_vision_board.dts b/boards/ruiside/ra8d1_vision_board/ra8d1_vision_board.dts index f5323c0d154e..4ebc27577765 100644 --- a/boards/ruiside/ra8d1_vision_board/ra8d1_vision_board.dts +++ b/boards/ruiside/ra8d1_vision_board/ra8d1_vision_board.dts @@ -179,8 +179,8 @@ pinctrl-0 = <&sdram_default>; pinctrl-names = "default"; status = "okay"; - auto-refresh-interval = ; - auto-refresh-count = ; + auto-refresh-interval = ; + auto-refresh-count = ; precharge-cycle-count = ; multiplex-addr-shift = "9-bit"; edian-mode = "little-endian"; diff --git a/include/zephyr/dt-bindings/memory-controller/renesas,ra-sdram.h b/include/zephyr/dt-bindings/memory-controller/renesas,ra-sdram.h index 2e443cc8a885..9797f5d59473 100644 --- a/include/zephyr/dt-bindings/memory-controller/renesas,ra-sdram.h +++ b/include/zephyr/dt-bindings/memory-controller/renesas,ra-sdram.h @@ -1,5 +1,6 @@ /* - * Copyright (c) 2024 Renesas Electronics Corporation + * Copyright (c) 2024-2025 Renesas Electronics Corporation + * * SPDX-License-Identifier: Apache-2.0 */ @@ -52,40 +53,40 @@ #define SDRAM_TREFW_15CYCLES (15) #define SDRAM_TREFW_16CYCLES (16) -#define SDRAM_AUTO_REFREDSH_INTERVEL_3CYCLES (3) -#define SDRAM_AUTO_REFREDSH_INTERVEL_4CYCLES (4) -#define SDRAM_AUTO_REFREDSH_INTERVEL_5CYCLES (5) -#define SDRAM_AUTO_REFREDSH_INTERVEL_6CYCLES (6) -#define SDRAM_AUTO_REFREDSH_INTERVEL_7CYCLES (7) -#define SDRAM_AUTO_REFREDSH_INTERVEL_8CYCLES (8) -#define SDRAM_AUTO_REFREDSH_INTERVEL_9CYCLES (9) -#define SDRAM_AUTO_REFREDSH_INTERVEL_10CYCLES (10) -#define SDRAM_AUTO_REFREDSH_INTERVEL_11CYCLES (11) -#define SDRAM_AUTO_REFREDSH_INTERVEL_12CYCLES (12) -#define SDRAM_AUTO_REFREDSH_INTERVEL_13CYCLES (13) -#define SDRAM_AUTO_REFREDSH_INTERVEL_14CYCLES (14) -#define SDRAM_AUTO_REFREDSH_INTERVEL_15CYCLES (15) -#define SDRAM_AUTO_REFREDSH_INTERVEL_16CYCLES (16) -#define SDRAM_AUTO_REFREDSH_INTERVEL_17CYCLES (17) -#define SDRAM_AUTO_REFREDSH_INTERVEL_18CYCLES (18) -#define SDRAM_AUTO_REFREDSH_INTERVEL_19CYCLES (19) -#define SDRAM_AUTO_REFREDSH_INTERVEL_20CYCLES (20) +#define SDRAM_AUTO_REFRESH_INTERVAL_3CYCLES (3) +#define SDRAM_AUTO_REFRESH_INTERVAL_4CYCLES (4) +#define SDRAM_AUTO_REFRESH_INTERVAL_5CYCLES (5) +#define SDRAM_AUTO_REFRESH_INTERVAL_6CYCLES (6) +#define SDRAM_AUTO_REFRESH_INTERVAL_7CYCLES (7) +#define SDRAM_AUTO_REFRESH_INTERVAL_8CYCLES (8) +#define SDRAM_AUTO_REFRESH_INTERVAL_9CYCLES (9) +#define SDRAM_AUTO_REFRESH_INTERVAL_10CYCLES (10) +#define SDRAM_AUTO_REFRESH_INTERVAL_11CYCLES (11) +#define SDRAM_AUTO_REFRESH_INTERVAL_12CYCLES (12) +#define SDRAM_AUTO_REFRESH_INTERVAL_13CYCLES (13) +#define SDRAM_AUTO_REFRESH_INTERVAL_14CYCLES (14) +#define SDRAM_AUTO_REFRESH_INTERVAL_15CYCLES (15) +#define SDRAM_AUTO_REFRESH_INTERVAL_16CYCLES (16) +#define SDRAM_AUTO_REFRESH_INTERVAL_17CYCLES (17) +#define SDRAM_AUTO_REFRESH_INTERVAL_18CYCLES (18) +#define SDRAM_AUTO_REFRESH_INTERVAL_19CYCLES (19) +#define SDRAM_AUTO_REFRESH_INTERVAL_20CYCLES (20) -#define SDRAM_AUTO_REFREDSH_COUNT_1TIMES (1) -#define SDRAM_AUTO_REFREDSH_COUNT_2TIMES (2) -#define SDRAM_AUTO_REFREDSH_COUNT_3TIMES (3) -#define SDRAM_AUTO_REFREDSH_COUNT_4TIMES (4) -#define SDRAM_AUTO_REFREDSH_COUNT_5TIMES (5) -#define SDRAM_AUTO_REFREDSH_COUNT_6TIMES (6) -#define SDRAM_AUTO_REFREDSH_COUNT_7TIMES (7) -#define SDRAM_AUTO_REFREDSH_COUNT_8TIMES (8) -#define SDRAM_AUTO_REFREDSH_COUNT_9TIMES (9) -#define SDRAM_AUTO_REFREDSH_COUNT_10TIMES (10) -#define SDRAM_AUTO_REFREDSH_COUNT_11TIMES (11) -#define SDRAM_AUTO_REFREDSH_COUNT_12TIMES (12) -#define SDRAM_AUTO_REFREDSH_COUNT_13TIMES (13) -#define SDRAM_AUTO_REFREDSH_COUNT_14TIMES (14) -#define SDRAM_AUTO_REFREDSH_COUNT_15TIMES (15) +#define SDRAM_AUTO_REFRESH_COUNT_1TIMES (1) +#define SDRAM_AUTO_REFRESH_COUNT_2TIMES (2) +#define SDRAM_AUTO_REFRESH_COUNT_3TIMES (3) +#define SDRAM_AUTO_REFRESH_COUNT_4TIMES (4) +#define SDRAM_AUTO_REFRESH_COUNT_5TIMES (5) +#define SDRAM_AUTO_REFRESH_COUNT_6TIMES (6) +#define SDRAM_AUTO_REFRESH_COUNT_7TIMES (7) +#define SDRAM_AUTO_REFRESH_COUNT_8TIMES (8) +#define SDRAM_AUTO_REFRESH_COUNT_9TIMES (9) +#define SDRAM_AUTO_REFRESH_COUNT_10TIMES (10) +#define SDRAM_AUTO_REFRESH_COUNT_11TIMES (11) +#define SDRAM_AUTO_REFRESH_COUNT_12TIMES (12) +#define SDRAM_AUTO_REFRESH_COUNT_13TIMES (13) +#define SDRAM_AUTO_REFRESH_COUNT_14TIMES (14) +#define SDRAM_AUTO_REFRESH_COUNT_15TIMES (15) #define SDRAM_AUTO_PRECHARGE_CYCLE_3CYCLES (3) #define SDRAM_AUTO_PRECHARGE_CYCLE_4CYCLES (4) From e45df54ba1b619cdf62666d746e579ffd5e6b2f6 Mon Sep 17 00:00:00 2001 From: The Nguyen Date: Fri, 5 Dec 2025 05:51:05 +0000 Subject: [PATCH 0514/3659] dts: bindings: memc: correct spelling for renesas,ra-sdram Fix typo for property name in renesas,ra-sdram. Update property name used in code. Signed-off-by: The Nguyen --- boards/renesas/ek_ra8d1/ek_ra8d1.dts | 2 +- boards/renesas/ek_ra8d2/ek_ra8d2.dtsi | 2 +- boards/renesas/ek_ra8p1/ek_ra8p1.dtsi | 2 +- boards/ruiside/ra8d1_vision_board/ra8d1_vision_board.dts | 2 +- dts/bindings/memory-controllers/renesas,ra-sdram.yaml | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/boards/renesas/ek_ra8d1/ek_ra8d1.dts b/boards/renesas/ek_ra8d1/ek_ra8d1.dts index e3920943da78..e941eaa577c9 100644 --- a/boards/renesas/ek_ra8d1/ek_ra8d1.dts +++ b/boards/renesas/ek_ra8d1/ek_ra8d1.dts @@ -429,7 +429,7 @@ auto-refresh-count = ; precharge-cycle-count = ; multiplex-addr-shift = "10-bit"; - edian-mode = "little-endian"; + endian-mode = "little-endian"; continuous-access; bus-width = "16-bit"; diff --git a/boards/renesas/ek_ra8d2/ek_ra8d2.dtsi b/boards/renesas/ek_ra8d2/ek_ra8d2.dtsi index 1358af594e5d..d2a2c7b02db2 100644 --- a/boards/renesas/ek_ra8d2/ek_ra8d2.dtsi +++ b/boards/renesas/ek_ra8d2/ek_ra8d2.dtsi @@ -207,7 +207,7 @@ auto-refresh-count = ; precharge-cycle-count = ; multiplex-addr-shift = "9-bit"; - edian-mode = "little-endian"; + endian-mode = "little-endian"; continuous-access; bus-width = "32-bit"; diff --git a/boards/renesas/ek_ra8p1/ek_ra8p1.dtsi b/boards/renesas/ek_ra8p1/ek_ra8p1.dtsi index e1530200bfe6..f123a2fefc94 100644 --- a/boards/renesas/ek_ra8p1/ek_ra8p1.dtsi +++ b/boards/renesas/ek_ra8p1/ek_ra8p1.dtsi @@ -207,7 +207,7 @@ auto-refresh-count = ; precharge-cycle-count = ; multiplex-addr-shift = "9-bit"; - edian-mode = "little-endian"; + endian-mode = "little-endian"; continuous-access; bus-width = "32-bit"; diff --git a/boards/ruiside/ra8d1_vision_board/ra8d1_vision_board.dts b/boards/ruiside/ra8d1_vision_board/ra8d1_vision_board.dts index 4ebc27577765..6ee870de5e8c 100644 --- a/boards/ruiside/ra8d1_vision_board/ra8d1_vision_board.dts +++ b/boards/ruiside/ra8d1_vision_board/ra8d1_vision_board.dts @@ -183,7 +183,7 @@ auto-refresh-count = ; precharge-cycle-count = ; multiplex-addr-shift = "9-bit"; - edian-mode = "little-endian"; + endian-mode = "little-endian"; continuous-access; bus-width = "16-bit"; diff --git a/dts/bindings/memory-controllers/renesas,ra-sdram.yaml b/dts/bindings/memory-controllers/renesas,ra-sdram.yaml index c4dcfec4745b..4dd1b4a55575 100644 --- a/dts/bindings/memory-controllers/renesas,ra-sdram.yaml +++ b/dts/bindings/memory-controllers/renesas,ra-sdram.yaml @@ -11,7 +11,7 @@ description: | auto-refresh-count = <8>; precharge-cycle-count = <3>; multiplex-addr-shift = "10-bit"; - edian-mode = "little-endian"; + endian-mode = "little-endian"; continuous-access; bus-width = "16-bit"; bank@0 { @@ -85,7 +85,7 @@ properties: Select the size of the shift towards the lower half of the row address in row address/column address multiplexing. - edian-mode: + endian-mode: type: string default: "little-endian" enum: From 466dec3b3efd3d3ee9a7cab47fb1884fff883cfc Mon Sep 17 00:00:00 2001 From: Lyle Zhu Date: Sat, 13 Dec 2025 14:33:48 +0800 Subject: [PATCH 0515/3659] Bluetooth: HFP AG: Add feature support check for voice recognition Add feature support validation in `bt_hfp_ag_voice_recognition()` to verify that both HF and AG support voice recognition feature before attempting to activate/deactivate it. This prevents attempting voice recognition operations when the feature is not supported by either the Hands-Free device or the Audio Gateway, returning -ENOTSUP in such cases. Signed-off-by: Lyle Zhu --- subsys/bluetooth/host/classic/hfp_ag.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/subsys/bluetooth/host/classic/hfp_ag.c b/subsys/bluetooth/host/classic/hfp_ag.c index 9b7b639e7219..99233ac82f90 100644 --- a/subsys/bluetooth/host/classic/hfp_ag.c +++ b/subsys/bluetooth/host/classic/hfp_ag.c @@ -5286,6 +5286,13 @@ int bt_hfp_ag_voice_recognition(struct bt_hfp_ag *ag, bool activate) } hfp_ag_unlock(ag); + feature = BOTH_SUPT_FEAT(ag, BT_HFP_HF_FEATURE_VOICE_RECG, + BT_HFP_AG_FEATURE_VOICE_RECG); + if (!feature) { + LOG_WRN("VR feature is unsupported"); + return -ENOTSUP; + } + if (activate && atomic_test_bit(ag->flags, BT_HFP_AG_VRE_ACTIVATE)) { LOG_WRN("VR has been activated"); return -ENOTSUP; From bf802d0237ec23777803bf6df704072ad3611276 Mon Sep 17 00:00:00 2001 From: Lyle Zhu Date: Fri, 14 Nov 2025 10:29:08 +0800 Subject: [PATCH 0516/3659] Bluetooth: Classic: HFP_AG: Auto-select support highest quality codec In current implementation, if the codec is not selected, the codec CVSD will be used to as default value to start audio connection procedure. Optimize the codec selection to select the supported highest quality codec as the default value. Signed-off-by: Lyle Zhu --- subsys/bluetooth/host/classic/hfp_ag.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/subsys/bluetooth/host/classic/hfp_ag.c b/subsys/bluetooth/host/classic/hfp_ag.c index 99233ac82f90..18a906b1c0c8 100644 --- a/subsys/bluetooth/host/classic/hfp_ag.c +++ b/subsys/bluetooth/host/classic/hfp_ag.c @@ -1599,6 +1599,24 @@ static int hfp_ag_open_sco(struct bt_hfp_ag *ag, struct bt_hfp_ag_call *call) return 0; } +static void bt_hfp_ag_auto_select_codec(struct bt_hfp_ag *ag) +{ + uint32_t supported_codec; + + supported_codec = BT_HFP_AG_SUPPORTED_CODEC_IDS & ag->hf_codec_ids; + + /* Automatically select the best available codec */ + if (supported_codec == 0) { + LOG_WRN("No supported Codec. Selected Codec CVSD as default"); + ag->selected_codec_id = BT_HFP_AG_CODEC_CVSD; + + return; + } + + ag->selected_codec_id = find_msb_set(supported_codec) - 1; + LOG_DBG("Selected codec ID: %u", ag->selected_codec_id); +} + static int bt_hfp_ag_codec_select(struct bt_hfp_ag *ag) { int err; @@ -1607,8 +1625,8 @@ static int bt_hfp_ag_codec_select(struct bt_hfp_ag *ag) hfp_ag_lock(ag); if (ag->selected_codec_id == 0) { - LOG_WRN("Codec is invalid, set default value"); - ag->selected_codec_id = BT_HFP_AG_CODEC_CVSD; + bt_hfp_ag_auto_select_codec(ag); + LOG_WRN("Codec is invalid, selected codec ID: %u", ag->selected_codec_id); } if (!(ag->hf_codec_ids & BIT(ag->selected_codec_id))) { From f0d78d572e506a525dcbd88e0bd70eb3c21547d6 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Wed, 17 Dec 2025 12:30:54 +0100 Subject: [PATCH 0517/3659] boards renesas cpkcor_ra8d1b: Fix DTS typos A few typos that prevent building for this target Signed-off-by: Alberto Escolar Piedras --- boards/renesas/cpkcor_ra8d1b/cpkcor_ra8d1b.dts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/boards/renesas/cpkcor_ra8d1b/cpkcor_ra8d1b.dts b/boards/renesas/cpkcor_ra8d1b/cpkcor_ra8d1b.dts index dd1d5cdfb073..9d1efcd347ea 100644 --- a/boards/renesas/cpkcor_ra8d1b/cpkcor_ra8d1b.dts +++ b/boards/renesas/cpkcor_ra8d1b/cpkcor_ra8d1b.dts @@ -192,11 +192,11 @@ pinctrl-0 = <&sdram_default>; pinctrl-names = "default"; status = "okay"; - auto-refresh-interval = ; - auto-refresh-count = ; + auto-refresh-interval = ; + auto-refresh-count = ; precharge-cycle-count = ; multiplex-addr-shift = "8-bit"; - edian-mode = "little-endian"; + endian-mode = "little-endian"; continuous-access; bus-width = "16-bit"; From 0ed8c6fa936f10f56cef630f13b412c2cd297052 Mon Sep 17 00:00:00 2001 From: Thinh Le Cong Date: Thu, 4 Sep 2025 17:21:43 +0700 Subject: [PATCH 0518/3659] drivers: adc: Adding ADC 16-bit driver support for board EK-RA2A1 Adding ADC 16-bit driver compatible to support ADC16 on RA2A1 Signed-off-by: Thinh Le Cong --- drivers/adc/Kconfig.renesas_ra | 2 +- drivers/adc/adc_renesas_ra.c | 223 +++++++++++++++--- ...s,ra-adc.yaml => renesas,ra-adc-base.yaml} | 30 ++- dts/bindings/adc/renesas,ra-adc12.yaml | 8 + dts/bindings/adc/renesas,ra-adc16.yaml | 8 + 5 files changed, 229 insertions(+), 42 deletions(-) rename dts/bindings/adc/{renesas,ra-adc.yaml => renesas,ra-adc-base.yaml} (52%) create mode 100644 dts/bindings/adc/renesas,ra-adc12.yaml create mode 100644 dts/bindings/adc/renesas,ra-adc16.yaml diff --git a/drivers/adc/Kconfig.renesas_ra b/drivers/adc/Kconfig.renesas_ra index b63050b7f535..d2b626779fc5 100644 --- a/drivers/adc/Kconfig.renesas_ra +++ b/drivers/adc/Kconfig.renesas_ra @@ -6,7 +6,7 @@ config ADC_RENESAS_RA bool "Renesas RA ADC" default y - depends on DT_HAS_RENESAS_RA_ADC_ENABLED + depends on DT_HAS_RENESAS_RA_ADC12_ENABLED || DT_HAS_RENESAS_RA_ADC16_ENABLED select USE_RA_FSP_ADC select PINCTRL help diff --git a/drivers/adc/adc_renesas_ra.c b/drivers/adc/adc_renesas_ra.c index e448fcb4c402..c9571b34c1ce 100644 --- a/drivers/adc/adc_renesas_ra.c +++ b/drivers/adc/adc_renesas_ra.c @@ -4,8 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#define DT_DRV_COMPAT renesas_ra_adc - #include #include #include @@ -14,6 +12,8 @@ #include #include +#include "rp_adc.h" + #include LOG_MODULE_REGISTER(adc_ra, CONFIG_ADC_LOG_LEVEL); @@ -21,14 +21,24 @@ LOG_MODULE_REGISTER(adc_ra, CONFIG_ADC_LOG_LEVEL); #define ADC_CONTEXT_USES_KERNEL_TIMER #include "adc_context.h" -#define ADC_RA_MAX_RESOLUTION 12 -#define ADC_AVERAGE_1 ADC_ADD_OFF -#define ADC_AVERAGE_2 ADC_ADD_AVERAGE_TWO -#define ADC_AVERAGE_4 ADC_ADD_AVERAGE_FOUR -#define ADC_AVERAGE_8 ADC_ADD_AVERAGE_EIGHT -#define ADC_AVERAGE_16 ADC_ADD_AVERAGE_SIXTEEN +#define ADC_AVERAGE_1 ADC_ADD_OFF +#define ADC_AVERAGE_2 ADC_ADD_AVERAGE_TWO +#define ADC_AVERAGE_4 ADC_ADD_AVERAGE_FOUR +#define ADC_AVERAGE_8 ADC_ADD_AVERAGE_EIGHT +#define ADC_AVERAGE_16 ADC_ADD_AVERAGE_SIXTEEN -void adc_scan_end_isr(void); +#define ADC_VARIANT_ADC12 12 +#define ADC_VARIANT_ADC16 16 + +#define ADC_CHANNEL_BIT_MASK (0x01U) + +enum ra_adc_reference { + RA_ADC_REF_VDD, + RA_ADC_REF_INTERNAL, + RA_ADC_REF_EXTERNAL, +}; + +extern void adc_scan_end_isr(void); /** * @brief RA ADC config @@ -40,6 +50,14 @@ struct adc_ra_config { uint32_t channel_available_mask; /** pinctrl configs */ const struct pinctrl_dev_config *pcfg; + /** Variant support ADC16 or ADC12 */ + uint8_t variant; + /** Mapping reference voltage */ + uint32_t reference; + /** Resolution support */ + uint8_t resolution; + /** Sampling time in nanoseconds */ + uint32_t sampling_time_ns; /** function pointer to irq setup */ void (*irq_configure)(void); }; @@ -66,8 +84,20 @@ struct adc_ra_data { uint32_t channels; /** Buffer id */ uint16_t buf_id; + /** Calibration process semaphore */ + struct k_sem calibrate_sem; }; +static adc_sample_state_reg_t map_channel_to_sample_state_reg(uint8_t channel_id) +{ + if (channel_id <= 15) { + return (adc_sample_state_reg_t)channel_id; + } + + /* Channel IDs 16–31 share the same sample state register */ + return ADC_SAMPLE_STATE_CHANNEL_16_TO_31; +} + /** * @brief Setup channels before starting to scan ADC * @@ -83,6 +113,8 @@ static int adc_ra_channel_setup(const struct device *dev, const struct adc_chann fsp_err_t fsp_err = FSP_SUCCESS; struct adc_ra_data *data = dev->data; const struct adc_ra_config *config = dev->config; + adc_sample_state_t sample_state; + uint32_t sample_states = 0; if (!((config->channel_available_mask & (1 << channel_cfg->channel_id)) != 0)) { LOG_ERR("unsupported channel id '%d'", channel_cfg->channel_id); @@ -104,6 +136,18 @@ static int adc_ra_channel_setup(const struct device *dev, const struct adc_chann return -EINVAL; } + fsp_err = RP_ADC_SampleStateCalculation(config->sampling_time_ns, &sample_states); + if (FSP_SUCCESS != fsp_err) { + return -ENOTSUP; + } + + sample_state.reg_id = map_channel_to_sample_state_reg(channel_cfg->channel_id); + sample_state.num_states = sample_states; + fsp_err = R_ADC_SampleStateCountSet(&data->adc, &sample_state); + if (FSP_SUCCESS != fsp_err) { + return -ENOTSUP; + } + data->f_channel_cfg.scan_mask |= (1U << channel_cfg->channel_id); /* Configure ADC channel specific settings */ fsp_err = R_ADC_ScanCfg(&data->adc, &data->f_channel_cfg); @@ -114,32 +158,86 @@ static int adc_ra_channel_setup(const struct device *dev, const struct adc_chann return 0; } -/** - * Interrupt handler - */ -static void adc_ra_isr(const struct device *dev) +static void renesas_ra_adc_callback(adc_callback_args_t *p_args) { + const struct device *dev = p_args->p_context; struct adc_ra_data *data = dev->data; fsp_err_t fsp_err = FSP_SUCCESS; adc_channel_t channel_id = 0; uint32_t channels = 0; int16_t *sample_buffer = (int16_t *)data->buf; - channels = data->channels; - for (channel_id = 0; channels > 0; channel_id++) { - /* Check if it is right channel id */ - if ((channels & 0x01) != 0) { - fsp_err = R_ADC_Read(&data->adc, channel_id, &sample_buffer[data->buf_id]); - if (FSP_SUCCESS != fsp_err) { - break; + if (p_args->event == ADC_EVENT_SCAN_COMPLETE) { + channels = data->channels; + for (channel_id = 0; channels > 0; channel_id++) { + /* Check if it is right channel id */ + if ((channels & ADC_CHANNEL_BIT_MASK) != 0) { + fsp_err = R_ADC_Read(&data->adc, channel_id, + &sample_buffer[data->buf_id]); + if (FSP_SUCCESS != fsp_err) { + break; + } + /* Do not return negative value for single-ended configuration */ + if (sample_buffer[data->buf_id] < 0) { + sample_buffer[data->buf_id] = 0; + } + data->buf_id = data->buf_id + 1; + + fsp_err = R_ADC_ScanStop(&data->adc); + if (FSP_SUCCESS != fsp_err) { + break; + } } - data->buf_id = data->buf_id + 1; + + channels = channels >> 1; + } + adc_context_on_sampling_done(&data->ctx, dev); + } + + else if (p_args->event == ADC_EVENT_CALIBRATION_COMPLETE) { + k_sem_give(&data->calibrate_sem); + } +} + +/** + * Voltage reference covert handler + */ +static int adc_map_vref(const struct adc_ra_config *cfg, adc_extended_cfg_t *extend) +{ + switch (cfg->variant) { + case ADC_VARIANT_ADC16: + switch (cfg->reference) { + case RA_ADC_REF_INTERNAL: + extend->adc_vref_control = ADC_VREF_CONTROL_2_5V_OUTPUT; + return 0; + case RA_ADC_REF_EXTERNAL: + extend->adc_vref_control = ADC_VREF_CONTROL_VREFH; + return 0; + default: + LOG_ERR("Reference %d not supported", cfg->reference); + return -ENOTSUP; + } + + case ADC_VARIANT_ADC12: + switch (cfg->reference) { + case RA_ADC_REF_VDD: + extend->adc_vref_control = ADC_VREF_CONTROL_AVCC0_AVSS0; + return 0; + case RA_ADC_REF_EXTERNAL: + extend->adc_vref_control = ADC_VREF_CONTROL_VREFH0_VREFL0; + return 0; + case RA_ADC_REF_INTERNAL: + extend->adc_vref_control = ADC_VREF_CONTROL_IVREF_AVSS0; + return 0; + default: + LOG_ERR("Reference %d not supported", cfg->reference); + return -ENOTSUP; } - channels = channels >> 1; + default: + LOG_ERR("Variant %d not supported", cfg->variant); + return -ENOTSUP; } - adc_scan_end_isr(); - adc_context_on_sampling_done(&data->ctx, dev); } /** @@ -187,9 +285,18 @@ static int adc_ra_start_read(const struct device *dev, const struct adc_sequence { const struct adc_ra_config *config = dev->config; struct adc_ra_data *data = dev->data; + fsp_err_t fsp_err = FSP_SUCCESS; int err; - if (sequence->resolution > ADC_RA_MAX_RESOLUTION || sequence->resolution == 0) { + if (config->variant == ADC_VARIANT_ADC16) { + uint8_t expected = config->resolution - 1; + + if (sequence->resolution != expected) { + LOG_ERR("unsupported resolution %d for single-ended mode, must be %d", + sequence->resolution, expected); + return -ENOTSUP; + } + } else if (sequence->resolution != config->resolution) { LOG_ERR("unsupported resolution %d", sequence->resolution); return -ENOTSUP; } @@ -207,6 +314,21 @@ static int adc_ra_start_read(const struct device *dev, const struct adc_sequence data->buf_id = 0; data->buf = sequence->buffer; + + if (config->variant == ADC_VARIANT_ADC16) { + if (!sequence->calibrate) { + return -ENOTSUP; + } + + /* Start calibration process */ + k_sem_reset(&data->calibrate_sem); + fsp_err = R_ADC_Calibrate(&data->adc, NULL); + if (FSP_SUCCESS != fsp_err) { + return -EIO; + } + k_sem_take(&data->calibrate_sem, K_FOREVER); + } + adc_context_start_read(&data->ctx, sequence); adc_context_wait_for_completion(&data->ctx); @@ -293,12 +415,21 @@ static int adc_ra_init(const struct device *dev) struct adc_ra_data *data = dev->data; int ret; fsp_err_t fsp_err = FSP_SUCCESS; + adc_extended_cfg_t *extend = (adc_extended_cfg_t *)data->f_config.p_extend; + + /* Override reference voltage */ + ret = adc_map_vref(config, extend); + if (ret < 0) { + return ret; + } ret = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT); if (ret < 0) { return ret; } + k_sem_init(&data->calibrate_sem, 0, 1); + /* Open ADC module */ fsp_err = R_ADC_Open(&data->adc, &data->f_config); if (FSP_SUCCESS != fsp_err) { @@ -307,28 +438,38 @@ static int adc_ra_init(const struct device *dev) config->irq_configure(); + if (config->variant == ADC_VARIANT_ADC16) { + /* Start calibration process */ + fsp_err = R_ADC_Calibrate(&data->adc, NULL); + if (FSP_SUCCESS != fsp_err) { + return -EIO; + } + k_sem_take(&data->calibrate_sem, K_FOREVER); + } + adc_context_unlock_unconditionally(&data->ctx); return 0; } -#define EVENT_ADC_SCAN_END(idx) BSP_PRV_IELS_ENUM(CONCAT(EVENT_ADC, idx, _SCAN_END)) +#define EVENT_ADC_SCAN_END(unit) BSP_PRV_IELS_ENUM(CONCAT(EVENT_ADC, unit, _SCAN_END)) #define IRQ_CONFIGURE_FUNC(idx) \ static void adc_ra_configure_func_##idx(void) \ { \ - R_ICU->IELSR[DT_INST_IRQ_BY_NAME(idx, scanend, irq)] = EVENT_ADC_SCAN_END(idx); \ + R_ICU->IELSR[DT_INST_IRQ_BY_NAME(idx, scanend, irq)] = \ + EVENT_ADC_SCAN_END(DT_PROP(DT_DRV_INST(idx), unit)); \ IRQ_CONNECT(DT_INST_IRQ_BY_NAME(idx, scanend, irq), \ - DT_INST_IRQ_BY_NAME(idx, scanend, priority), adc_ra_isr, \ - DEVICE_DT_INST_GET(idx), 0); \ + DT_INST_IRQ_BY_NAME(idx, scanend, priority), adc_scan_end_isr, NULL, \ + 0); \ irq_enable(DT_INST_IRQ_BY_NAME(idx, scanend, irq)); \ } #define IRQ_CONFIGURE_DEFINE(idx) .irq_configure = adc_ra_configure_func_##idx -#define ADC_RA_INIT(idx) \ +#define ADC_RA_INIT_VARIANT(idx, VARIANT, RES_NUM, RES_ENUM) \ IRQ_CONFIGURE_FUNC(idx) \ PINCTRL_DT_INST_DEFINE(idx); \ - static const adc_extended_cfg_t g_adc_cfg_extend_##idx = { \ + static adc_extended_cfg_t g_adc_cfg_extend_##idx = { \ .add_average_count = UTIL_CAT(ADC_AVERAGE_, DT_INST_PROP(idx, average_count)), \ .clearing = ADC_CLEAR_AFTER_READ_ON, \ .trigger_group_b = ADC_START_SOURCE_DISABLED, \ @@ -348,6 +489,10 @@ static int adc_ra_init(const struct device *dev) IF_ENABLED(CONFIG_ADC_ASYNC, (.read_async = adc_ra_read_async))}; \ static const struct adc_ra_config adc_ra_config_##idx = { \ .channel_available_mask = DT_INST_PROP(idx, channel_available_mask), \ + .variant = VARIANT, \ + .reference = DT_INST_ENUM_IDX(idx, reference), \ + .resolution = RES_NUM, \ + .sampling_time_ns = DT_INST_PROP_OR(idx, sampling_time_ns, UNSPECIFIED), \ .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(idx), \ IRQ_CONFIGURE_DEFINE(idx), \ }; \ @@ -358,13 +503,13 @@ static int adc_ra_init(const struct device *dev) .dev = DEVICE_DT_INST_GET(idx), \ .f_config = \ { \ - .unit = idx, \ + .unit = DT_INST_PROP(idx, unit), \ .mode = ADC_MODE_SINGLE_SCAN, \ - .resolution = ADC_RESOLUTION_12_BIT, \ + .resolution = RES_ENUM, \ .alignment = (adc_alignment_t)ADC_ALIGNMENT_RIGHT, \ .trigger = 0, \ - .p_callback = NULL, \ - .p_context = NULL, \ + .p_callback = renesas_ra_adc_callback, \ + .p_context = (void *)DEVICE_DT_GET(DT_DRV_INST(idx)), \ .p_extend = &g_adc_cfg_extend_##idx, \ .scan_end_irq = DT_INST_IRQ_BY_NAME(idx, scanend, irq), \ .scan_end_ipl = DT_INST_IRQ_BY_NAME(idx, scanend, priority), \ @@ -386,4 +531,10 @@ static int adc_ra_init(const struct device *dev) DEVICE_DT_INST_DEFINE(idx, adc_ra_init, NULL, &adc_ra_data_##idx, &adc_ra_config_##idx, \ POST_KERNEL, CONFIG_ADC_INIT_PRIORITY, &adc_ra_api_##idx) -DT_INST_FOREACH_STATUS_OKAY(ADC_RA_INIT); +#define DT_DRV_COMPAT renesas_ra_adc12 +DT_INST_FOREACH_STATUS_OKAY_VARGS(ADC_RA_INIT_VARIANT, ADC_VARIANT_ADC12, 12, ADC_RESOLUTION_12_BIT) +#undef DT_DRV_COMPAT + +#define DT_DRV_COMPAT renesas_ra_adc16 +DT_INST_FOREACH_STATUS_OKAY_VARGS(ADC_RA_INIT_VARIANT, ADC_VARIANT_ADC16, 16, ADC_RESOLUTION_16_BIT) +#undef DT_DRV_COMPAT diff --git a/dts/bindings/adc/renesas,ra-adc.yaml b/dts/bindings/adc/renesas,ra-adc-base.yaml similarity index 52% rename from dts/bindings/adc/renesas,ra-adc.yaml rename to dts/bindings/adc/renesas,ra-adc-base.yaml index 0ce2649529a8..2542c918873d 100644 --- a/dts/bindings/adc/renesas,ra-adc.yaml +++ b/dts/bindings/adc/renesas,ra-adc-base.yaml @@ -1,10 +1,6 @@ -# Copyright (c) 2024 Renesas Electronics Corporation +# Copyright (c) 2025 Renesas Electronics Corporation # SPDX-License-Identifier: Apache-2.0 -description: Renesas RA ADC node - -compatible: "renesas,ra-adc" - include: [adc-controller.yaml, pinctrl-device.yaml] properties: @@ -32,5 +28,29 @@ properties: The ADC module will take multiple samples of an analog signal and averages them to reduce noise and enhance accuracy + reference: + type: string + enum: + - vdd + - internal + - external + default: vdd + description: | + ADC reference voltage source: + - vdd: use VDD as reference + - internal: use internal reference + - external: use external reference + + sampling-time-ns: + type: int + description: | + Sampling time in nanoseconds, i.e. the duration the ADC input + signal is sampled before conversion starts. + + unit: + type: int + required: true + description: Indicates the unit number of the ADC device. + io-channel-cells: - input diff --git a/dts/bindings/adc/renesas,ra-adc12.yaml b/dts/bindings/adc/renesas,ra-adc12.yaml new file mode 100644 index 000000000000..a8be17757523 --- /dev/null +++ b/dts/bindings/adc/renesas,ra-adc12.yaml @@ -0,0 +1,8 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +description: Renesas RA 12-bit resolution ADC (ADC12) + +compatible: "renesas,ra-adc12" + +include: renesas,ra-adc-base.yaml diff --git a/dts/bindings/adc/renesas,ra-adc16.yaml b/dts/bindings/adc/renesas,ra-adc16.yaml new file mode 100644 index 000000000000..3a7f444cc422 --- /dev/null +++ b/dts/bindings/adc/renesas,ra-adc16.yaml @@ -0,0 +1,8 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +description: Renesas RA 16-bit resolution ADC (ADC16) + +compatible: "renesas,ra-adc16" + +include: renesas,ra-adc-base.yaml From 67284c5515b27c7c06aaff18115231d5f719268c Mon Sep 17 00:00:00 2001 From: Thinh Le Cong Date: Thu, 4 Sep 2025 17:24:16 +0700 Subject: [PATCH 0519/3659] dts: arm: renesas: Add ADC device node for EK-RA2A1 and set unit prop Add ADC device node to support ADC 16-bit on EK-RA2A1 Update other Renesas board nodes to include the "unit" property Signed-off-by: Thinh Le Cong --- dts/arm/renesas/ra/ra2/ra2l1.dtsi | 3 ++- dts/arm/renesas/ra/ra2/ra2xx.dtsi | 12 ++++++++++++ dts/arm/renesas/ra/ra4/r7fa4c1bx.dtsi | 3 ++- dts/arm/renesas/ra/ra4/r7fa4l1bx.dtsi | 3 ++- dts/arm/renesas/ra/ra4/ra4-cm33-common.dtsi | 6 ++++-- dts/arm/renesas/ra/ra4/ra4-cm4-common.dtsi | 3 ++- dts/arm/renesas/ra/ra6/ra6-cm33-common.dtsi | 6 ++++-- dts/arm/renesas/ra/ra6/ra6-cm4-common.dtsi | 4 +++- dts/arm/renesas/ra/ra8/ra8x1.dtsi | 6 ++++-- 9 files changed, 35 insertions(+), 11 deletions(-) diff --git a/dts/arm/renesas/ra/ra2/ra2l1.dtsi b/dts/arm/renesas/ra/ra2/ra2l1.dtsi index 8f642fa3c65f..53bb8257108e 100644 --- a/dts/arm/renesas/ra/ra2/ra2l1.dtsi +++ b/dts/arm/renesas/ra/ra2/ra2l1.dtsi @@ -452,7 +452,8 @@ }; adc0: adc@4005c000 { - compatible = "renesas,ra-adc"; + compatible = "renesas,ra-adc12"; + unit = <0>; reg = <0x4005c000 0x100>; #io-channel-cells = <1>; vref-mv = <3300>; diff --git a/dts/arm/renesas/ra/ra2/ra2xx.dtsi b/dts/arm/renesas/ra/ra2/ra2xx.dtsi index ec6917ecefe5..2a52836e01ef 100644 --- a/dts/arm/renesas/ra/ra2/ra2xx.dtsi +++ b/dts/arm/renesas/ra/ra2/ra2xx.dtsi @@ -303,6 +303,18 @@ interrupt-names = "frdyi"; }; + adc0: adc@4005c000 { + compatible = "renesas,ra-adc16"; + unit = <0>; + reg = <0x4005c000 0x100>; + #io-channel-cells = <1>; + vref-mv = <3300>; + channel-available-mask = <0x00ff01ff>; + reference = "external"; + average-count = <16>; + status = "disabled"; + }; + agt0: agt@40084000 { compatible = "renesas,ra-agt"; channel = <0>; diff --git a/dts/arm/renesas/ra/ra4/r7fa4c1bx.dtsi b/dts/arm/renesas/ra/ra4/r7fa4c1bx.dtsi index 23c37fa535a9..6d8a15ab55fd 100644 --- a/dts/arm/renesas/ra/ra4/r7fa4c1bx.dtsi +++ b/dts/arm/renesas/ra/ra4/r7fa4c1bx.dtsi @@ -317,7 +317,8 @@ }; adc0: adc@40170000 { - compatible = "renesas,ra-adc"; + compatible = "renesas,ra-adc12"; + unit = <0>; reg = <0x40170000 0x100>; #io-channel-cells = <1>; vref-mv = <3300>; diff --git a/dts/arm/renesas/ra/ra4/r7fa4l1bx.dtsi b/dts/arm/renesas/ra/ra4/r7fa4l1bx.dtsi index c3115c21dbbf..a22606f22921 100644 --- a/dts/arm/renesas/ra/ra4/r7fa4l1bx.dtsi +++ b/dts/arm/renesas/ra/ra4/r7fa4l1bx.dtsi @@ -312,9 +312,10 @@ }; adc0: adc@40170000 { - compatible = "renesas,ra-adc"; + compatible = "renesas,ra-adc12"; interrupts = <38 1>; interrupt-names = "scanend"; + unit = <0>; reg = <0x40170000 0x100>; #io-channel-cells = <1>; vref-mv = <3300>; diff --git a/dts/arm/renesas/ra/ra4/ra4-cm33-common.dtsi b/dts/arm/renesas/ra/ra4/ra4-cm33-common.dtsi index f0f1378abdc0..e181195da0f4 100644 --- a/dts/arm/renesas/ra/ra4/ra4-cm33-common.dtsi +++ b/dts/arm/renesas/ra/ra4/ra4-cm33-common.dtsi @@ -301,9 +301,10 @@ }; adc0: adc@40170000 { - compatible = "renesas,ra-adc"; + compatible = "renesas,ra-adc12"; interrupts = <38 1>; interrupt-names = "scanend"; + unit = <0>; reg = <0x40170000 0x100>; #io-channel-cells = <1>; vref-mv = <3300>; @@ -311,9 +312,10 @@ }; adc1: adc@40170200 { - compatible = "renesas,ra-adc"; + compatible = "renesas,ra-adc12"; interrupts = <39 1>; interrupt-names = "scanend"; + unit = <1>; reg = <0x40170200 0x100>; #io-channel-cells = <1>; vref-mv = <3300>; diff --git a/dts/arm/renesas/ra/ra4/ra4-cm4-common.dtsi b/dts/arm/renesas/ra/ra4/ra4-cm4-common.dtsi index a59b558fabb6..2e70d63e9986 100644 --- a/dts/arm/renesas/ra/ra4/ra4-cm4-common.dtsi +++ b/dts/arm/renesas/ra/ra4/ra4-cm4-common.dtsi @@ -258,8 +258,9 @@ }; adc0: adc@4005c000 { - compatible = "renesas,ra-adc"; + compatible = "renesas,ra-adc12"; interrupt-names = "scanend"; + unit = <0>; reg = <0x4005c000 0x100>; #io-channel-cells = <1>; vref-mv = <3300>; diff --git a/dts/arm/renesas/ra/ra6/ra6-cm33-common.dtsi b/dts/arm/renesas/ra/ra6/ra6-cm33-common.dtsi index fa44b13dfdb0..44537c60b809 100644 --- a/dts/arm/renesas/ra/ra6/ra6-cm33-common.dtsi +++ b/dts/arm/renesas/ra/ra6/ra6-cm33-common.dtsi @@ -297,9 +297,10 @@ }; adc0: adc@40170000 { - compatible = "renesas,ra-adc"; + compatible = "renesas,ra-adc12"; interrupts = <38 1>; interrupt-names = "scanend"; + unit = <0>; reg = <0x40170000 0x100>; #io-channel-cells = <1>; vref-mv = <3300>; @@ -307,9 +308,10 @@ }; adc1: adc@40170200 { - compatible = "renesas,ra-adc"; + compatible = "renesas,ra-adc12"; interrupts = <39 1>; interrupt-names = "scanend"; + unit = <1>; reg = <0x40170200 0x100>; #io-channel-cells = <1>; vref-mv = <3300>; diff --git a/dts/arm/renesas/ra/ra6/ra6-cm4-common.dtsi b/dts/arm/renesas/ra/ra6/ra6-cm4-common.dtsi index 16e4c2cb76b0..906f0e1bd641 100644 --- a/dts/arm/renesas/ra/ra6/ra6-cm4-common.dtsi +++ b/dts/arm/renesas/ra/ra6/ra6-cm4-common.dtsi @@ -360,9 +360,10 @@ }; adc0: adc@4005c000 { - compatible = "renesas,ra-adc"; + compatible = "renesas,ra-adc12"; interrupts = <38 1>; interrupt-names = "scanend"; + unit = <0>; reg = <0x4005c000 0x100>; #io-channel-cells = <1>; vref-mv = <3300>; @@ -373,6 +374,7 @@ compatible = "renesas,ra-adc"; interrupts = <39 1>; interrupt-names = "scanend"; + unit = <1>; reg = <0x4005c200 0x100>; #io-channel-cells = <1>; vref-mv = <3300>; diff --git a/dts/arm/renesas/ra/ra8/ra8x1.dtsi b/dts/arm/renesas/ra/ra8/ra8x1.dtsi index cde53b045488..9774b1c95852 100644 --- a/dts/arm/renesas/ra/ra8/ra8x1.dtsi +++ b/dts/arm/renesas/ra/ra8/ra8x1.dtsi @@ -445,9 +445,10 @@ }; adc0: adc@40332000 { - compatible = "renesas,ra-adc"; + compatible = "renesas,ra-adc12"; interrupts = <38 1>; interrupt-names = "scanend"; + unit = <0>; reg = <0x40332000 0x100>; #io-channel-cells = <1>; vref-mv = <3300>; @@ -456,9 +457,10 @@ }; adc1: adc@40332200 { - compatible = "renesas,ra-adc"; + compatible = "renesas,ra-adc12"; interrupts = <39 1>; interrupt-names = "scanend"; + unit = <1>; reg = <0x40332200 0x100>; #io-channel-cells = <1>; vref-mv = <3300>; From 25fd4d2393d0a9f3b37a938008ceb0c5ac5a40ef Mon Sep 17 00:00:00 2001 From: Thinh Le Cong Date: Tue, 9 Sep 2025 15:34:19 +0700 Subject: [PATCH 0520/3659] boards: renesas: Add ADC device node for EK-RA2A1 board Add ADC device node on board layer to support ADC 16-bit on EK-RA2A1 Signed-off-by: Thinh Le Cong --- boards/renesas/ek_ra2a1/ek_ra2a1-pinctrl.dtsi | 8 ++++++++ boards/renesas/ek_ra2a1/ek_ra2a1.dts | 9 +++++++++ 2 files changed, 17 insertions(+) diff --git a/boards/renesas/ek_ra2a1/ek_ra2a1-pinctrl.dtsi b/boards/renesas/ek_ra2a1/ek_ra2a1-pinctrl.dtsi index b18dd709a6e8..5cdbb9f77609 100644 --- a/boards/renesas/ek_ra2a1/ek_ra2a1-pinctrl.dtsi +++ b/boards/renesas/ek_ra2a1/ek_ra2a1-pinctrl.dtsi @@ -45,6 +45,14 @@ }; }; + adc0_default: adc0_default { + group1 { + /* input */ + psels = ; + renesas,analog-enable; + }; + }; + dac0_default: dac0_default { group1 { /* output */ diff --git a/boards/renesas/ek_ra2a1/ek_ra2a1.dts b/boards/renesas/ek_ra2a1/ek_ra2a1.dts index 142c58724bfa..48e422257383 100644 --- a/boards/renesas/ek_ra2a1/ek_ra2a1.dts +++ b/boards/renesas/ek_ra2a1/ek_ra2a1.dts @@ -7,6 +7,7 @@ #include #include +#include #include #include "ek_ra2a1-pinctrl.dtsi" @@ -120,6 +121,14 @@ status = "okay"; }; +&adc0 { + pinctrl-0 = <&adc0_default>; + pinctrl-names = "default"; + interrupts = <13 3>; + interrupt-names = "scanend"; + status = "okay"; +}; + &dac0 { pinctrl-0 = <&dac0_default>; pinctrl-names = "default"; From 231bf62f7fb2e4ad397e15b41dcdd75751a00042 Mon Sep 17 00:00:00 2001 From: Thinh Le Cong Date: Thu, 4 Sep 2025 17:27:39 +0700 Subject: [PATCH 0521/3659] tests: drivers: adc: Add tests support for ADC driver on EK-RA2A1 board Add Renesas EK-RA2A1 board support for these tests: - tests/drivers/adc/adc_api - tests/drivers/adc/adc_accuracy_test Signed-off-by: Thinh Le Cong --- tests/drivers/adc/adc_accuracy_test/Kconfig | 4 ++ .../adc_accuracy_test/boards/ek_ra2a1.overlay | 44 +++++++++++++++ .../adc/adc_accuracy_test/src/dac_source.c | 3 ++ .../adc/adc_accuracy_test/testcase.yaml | 37 ++++++------- tests/drivers/adc/adc_api/Kconfig | 4 ++ .../adc/adc_api/boards/ek_ra2a1.overlay | 54 +++++++++++++++++++ tests/drivers/adc/adc_api/src/test_adc.c | 18 +++++++ 7 files changed, 146 insertions(+), 18 deletions(-) create mode 100644 tests/drivers/adc/adc_accuracy_test/boards/ek_ra2a1.overlay create mode 100644 tests/drivers/adc/adc_api/boards/ek_ra2a1.overlay diff --git a/tests/drivers/adc/adc_accuracy_test/Kconfig b/tests/drivers/adc/adc_accuracy_test/Kconfig index f062824b19be..fa67d9fb6264 100644 --- a/tests/drivers/adc/adc_accuracy_test/Kconfig +++ b/tests/drivers/adc/adc_accuracy_test/Kconfig @@ -26,6 +26,10 @@ config NUMBER_OF_PASSES int "Number of passes" default 5 +config TEST_ADC_CALIBRATE_REQUIRED + bool "Require calibrate field in ADC test" + default y if DT_HAS_RENESAS_RA_ADC16_ENABLED + if DAC_SOURCE_TEST config DAC_BUFFER_NOT_SUPPORTED diff --git a/tests/drivers/adc/adc_accuracy_test/boards/ek_ra2a1.overlay b/tests/drivers/adc/adc_accuracy_test/boards/ek_ra2a1.overlay new file mode 100644 index 000000000000..32b34dcc919b --- /dev/null +++ b/tests/drivers/adc/adc_accuracy_test/boards/ek_ra2a1.overlay @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2024-2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + zephyr,user { + io-channels = <&adc0 3>; + dac = <&dac0>; + dac-channel-id = <0>; + dac-resolution = <12>; + }; +}; + +&pinctrl { + adc0_default: adc0_default { + group1 { + /* input */ + psels = ; + renesas,analog-enable; + }; + }; +}; + +&adc0 { + #address-cells = <1>; + #size-cells = <0>; + interrupts = <31 1>; + interrupt-names = "scanend"; + status = "okay"; + + /* + * Channel 3 is used in single ended mode, with 15 bit resolution + */ + channel@3 { + reg = <3>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_EXTERNAL0"; + zephyr,acquisition-time = ; + zephyr,resolution = <15>; + zephyr,vref-mv = <3300>; + }; +}; diff --git a/tests/drivers/adc/adc_accuracy_test/src/dac_source.c b/tests/drivers/adc/adc_accuracy_test/src/dac_source.c index 23b832a66ed3..a4063d095c7b 100644 --- a/tests/drivers/adc/adc_accuracy_test/src/dac_source.c +++ b/tests/drivers/adc/adc_accuracy_test/src/dac_source.c @@ -43,6 +43,9 @@ static int test_dac_to_adc(void) struct adc_sequence sequence = { .buffer = &sample_buffer, .buffer_size = sizeof(sample_buffer), +#if CONFIG_TEST_ADC_CALIBRATE_REQUIRED + .calibrate = true, +#endif }; const struct device *dac_dev = init_dac(); diff --git a/tests/drivers/adc/adc_accuracy_test/testcase.yaml b/tests/drivers/adc/adc_accuracy_test/testcase.yaml index c555ed66f96d..8fdd6d968c1b 100644 --- a/tests/drivers/adc/adc_accuracy_test/testcase.yaml +++ b/tests/drivers/adc/adc_accuracy_test/testcase.yaml @@ -18,25 +18,8 @@ tests: fixture: dac_adc_loopback platform_allow: - frdm_k64f - drivers.adc.accuracy.ref_volt: - extra_configs: - - CONFIG_REFERENCE_VOLTAGE_TEST=y - # Test scenario is filtered if Kconfig dependencies are not satisfied - filter: CONFIG_REFERENCE_VOLTAGE_TEST - harness_config: - fixture: adc_ref_volt - platform_allow: - - frdm_kl25z - - ek_ra8m1 - - frdm_mcxc242 - - frdm_mcxc444 - - nrf52840dk/nrf52840 - - nrf54h20dk/nrf54h20/cpuapp - - nrf54h20dk/nrf54h20/cpuppr - - nrf54l15dk/nrf54l15/cpuapp - - nrf54lm20dk/nrf54lm20a/cpuapp - - ophelia4ev/nrf54l15/cpuapp - ek_ra8d1 + - ek_ra8m1 - mck_ra8t1 - ek_ra6e2 - ek_ra6m1 @@ -47,9 +30,26 @@ tests: - fpb_ra6e1 - fpb_ra6e2 - ek_ra4e2 + - ek_ra4l1 + - ek_ra4m1 - ek_ra4m2 - ek_ra4m3 - ek_ra4w1 + - fpb_ra4e1 + - ek_ra2a1 + - ek_ra2l1 + drivers.adc.accuracy.ref_volt: + harness_config: + fixture: adc_ref_volt + platform_allow: + - frdm_kl25z + - frdm_mcxc242 + - frdm_mcxc444 + - nrf52840dk/nrf52840 + - nrf54h20dk/nrf54h20/cpuapp + - nrf54l15dk/nrf54l15/cpuapp + - nrf54lm20dk/nrf54lm20a/cpuapp + - ophelia4ev/nrf54l15/cpuapp - sltb010a - xg23_rb4210a - xg24_dk2601b @@ -58,6 +58,7 @@ tests: - xg29_rb4412a - bg29_rb4420a - slwrb4180a + - ek_ra4c1 integration_platforms: - frdm_kl25z - nrf54l15dk/nrf54l15/cpuapp diff --git a/tests/drivers/adc/adc_api/Kconfig b/tests/drivers/adc/adc_api/Kconfig index f4748c6d3805..daf18e7f7415 100644 --- a/tests/drivers/adc/adc_api/Kconfig +++ b/tests/drivers/adc/adc_api/Kconfig @@ -13,3 +13,7 @@ config ADC_API_SAMPLE_INTERVAL_US config ADC_32_BITS_DATA bool "ADC data is 32-bits long" + +config TEST_ADC_CALIBRATE_REQUIRED + bool "Require calibrate field in ADC test" + default y if DT_HAS_RENESAS_RA_ADC16_ENABLED diff --git a/tests/drivers/adc/adc_api/boards/ek_ra2a1.overlay b/tests/drivers/adc/adc_api/boards/ek_ra2a1.overlay new file mode 100644 index 000000000000..96337abf1ced --- /dev/null +++ b/tests/drivers/adc/adc_api/boards/ek_ra2a1.overlay @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + zephyr,user { + io-channels = <&adc0 0>, <&adc0 1>; + }; +}; + +&pinctrl { + adc0_default: adc0_default { + group1 { + /* input */ + psels = , + ; + renesas,analog-enable; + }; + }; +}; + +&adc0 { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <31 1>; + interrupt-names = "scanend"; + + /* + * Channel 0 is used in single ended mode, with 15 bit resolution + */ + channel@0 { + reg = <0>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_EXTERNAL0"; + zephyr,resolution = <15>; + zephyr,acquisition-time = ; + zephyr,vref-mv = <3300>; + }; + + /* + * Channel 1 is used in single ended mode, with 15 bit resolution + */ + channel@1 { + reg = <1>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_EXTERNAL0"; + zephyr,resolution = <15>; + zephyr,acquisition-time = ; + zephyr,vref-mv = <3300>; + }; +}; diff --git a/tests/drivers/adc/adc_api/src/test_adc.c b/tests/drivers/adc/adc_api/src/test_adc.c index 49af36dc0d4c..d3a7186db84e 100644 --- a/tests/drivers/adc/adc_api/src/test_adc.c +++ b/tests/drivers/adc/adc_api/src/test_adc.c @@ -136,6 +136,9 @@ static int test_task_one_channel(void) struct adc_sequence sequence = { .buffer = m_sample_buffer, .buffer_size = sizeof(m_sample_buffer), +#if CONFIG_TEST_ADC_CALIBRATE_REQUIRED + .calibrate = true, +#endif }; init_adc(); @@ -163,6 +166,9 @@ static int test_task_multiple_channels(void) struct adc_sequence sequence = { .buffer = m_sample_buffer, .buffer_size = sizeof(m_sample_buffer), +#if CONFIG_TEST_ADC_CALIBRATE_REQUIRED + .calibrate = true, +#endif }; init_adc(); @@ -210,6 +216,9 @@ static int test_task_asynchronous_call(void) .options = &options, .buffer = m_sample_buffer, .buffer_size = sizeof(m_sample_buffer), +#if CONFIG_TEST_ADC_CALIBRATE_REQUIRED + .calibrate = true, +#endif }; struct k_poll_event async_evt = K_POLL_EVENT_INITIALIZER(K_POLL_TYPE_SIGNAL, @@ -272,6 +281,9 @@ static int test_task_with_interval(void) .options = &options, .buffer = m_sample_buffer, .buffer_size = sizeof(m_sample_buffer), +#if CONFIG_TEST_ADC_CALIBRATE_REQUIRED + .calibrate = true, +#endif }; init_adc(); @@ -349,6 +361,9 @@ static int test_task_repeated_samplings(void) .options = &options, .buffer = m_sample_buffer, .buffer_size = sizeof(m_sample_buffer), +#if CONFIG_TEST_ADC_CALIBRATE_REQUIRED + .calibrate = true, +#endif }; init_adc(); @@ -383,6 +398,9 @@ static int test_task_invalid_request(void) .buffer = m_sample_buffer, .buffer_size = sizeof(m_sample_buffer), .resolution = 0, /* intentionally invalid value */ +#if CONFIG_TEST_ADC_CALIBRATE_REQUIRED + .calibrate = true, +#endif }; init_adc(); From 57361327d83af6d7465b74a8ef2491db48dc413a Mon Sep 17 00:00:00 2001 From: Thinh Le Cong Date: Thu, 4 Sep 2025 17:28:42 +0700 Subject: [PATCH 0522/3659] samples: drivers: adc: Add tests support for ADC driver on EK-RA2A1 board Add Renesas EK-RA2A1 board support for sample: - samples/drivers/adc/adc_dt Signed-off-by: Thinh Le Cong --- samples/drivers/adc/adc_dt/Kconfig | 11 ++++ .../adc/adc_dt/boards/ek_ra2a1.overlay | 54 +++++++++++++++++++ samples/drivers/adc/adc_dt/src/main.c | 3 ++ 3 files changed, 68 insertions(+) create mode 100644 samples/drivers/adc/adc_dt/Kconfig create mode 100644 samples/drivers/adc/adc_dt/boards/ek_ra2a1.overlay diff --git a/samples/drivers/adc/adc_dt/Kconfig b/samples/drivers/adc/adc_dt/Kconfig new file mode 100644 index 000000000000..e8cc8c945525 --- /dev/null +++ b/samples/drivers/adc/adc_dt/Kconfig @@ -0,0 +1,11 @@ +# Copyright The Zephyr Project Contributors +# SPDX-License-Identifier: Apache-2.0 + +mainmenu "ADC DT sample" + +source "Kconfig.zephyr" + + +config SAMPLE_ADC_CALIBRATE_REQUIRED + bool "Require calibrate field in ADC" + default y if DT_HAS_RENESAS_RA_ADC16_ENABLED diff --git a/samples/drivers/adc/adc_dt/boards/ek_ra2a1.overlay b/samples/drivers/adc/adc_dt/boards/ek_ra2a1.overlay new file mode 100644 index 000000000000..96337abf1ced --- /dev/null +++ b/samples/drivers/adc/adc_dt/boards/ek_ra2a1.overlay @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + zephyr,user { + io-channels = <&adc0 0>, <&adc0 1>; + }; +}; + +&pinctrl { + adc0_default: adc0_default { + group1 { + /* input */ + psels = , + ; + renesas,analog-enable; + }; + }; +}; + +&adc0 { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <31 1>; + interrupt-names = "scanend"; + + /* + * Channel 0 is used in single ended mode, with 15 bit resolution + */ + channel@0 { + reg = <0>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_EXTERNAL0"; + zephyr,resolution = <15>; + zephyr,acquisition-time = ; + zephyr,vref-mv = <3300>; + }; + + /* + * Channel 1 is used in single ended mode, with 15 bit resolution + */ + channel@1 { + reg = <1>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_EXTERNAL0"; + zephyr,resolution = <15>; + zephyr,acquisition-time = ; + zephyr,vref-mv = <3300>; + }; +}; diff --git a/samples/drivers/adc/adc_dt/src/main.c b/samples/drivers/adc/adc_dt/src/main.c index cb607a0ff0d1..535db23956d8 100644 --- a/samples/drivers/adc/adc_dt/src/main.c +++ b/samples/drivers/adc/adc_dt/src/main.c @@ -38,6 +38,9 @@ int main(void) .buffer = &buf, /* buffer size in bytes, not number of samples */ .buffer_size = sizeof(buf), +#if CONFIG_SAMPLE_ADC_CALIBRATE_REQUIRED + .calibrate = true, +#endif }; /* Configure channels individually prior to sampling. */ From a218c9259284f04f971f05b7778788ca619f15f2 Mon Sep 17 00:00:00 2001 From: Thinh Le Cong Date: Mon, 8 Sep 2025 11:16:20 +0700 Subject: [PATCH 0523/3659] drivers: adc: Remove doxygen comment blocks Remove all doxygen comment blocks on driver Signed-off-by: Thinh Le Cong --- drivers/adc/adc_renesas_ra.c | 72 ------------------------------------ 1 file changed, 72 deletions(-) diff --git a/drivers/adc/adc_renesas_ra.c b/drivers/adc/adc_renesas_ra.c index c9571b34c1ce..1cedacfadbd4 100644 --- a/drivers/adc/adc_renesas_ra.c +++ b/drivers/adc/adc_renesas_ra.c @@ -98,16 +98,6 @@ static adc_sample_state_reg_t map_channel_to_sample_state_reg(uint8_t channel_id return ADC_SAMPLE_STATE_CHANNEL_16_TO_31; } -/** - * @brief Setup channels before starting to scan ADC - * - * @param dev RA ADC device - * @param channel_cfg channel configuration - * - * @return 0 on success - * @return -ENOTSUP if channel id or differential is wrong value - * @return -EINVAL if channel configuration is invalid - */ static int adc_ra_channel_setup(const struct device *dev, const struct adc_channel_cfg *channel_cfg) { fsp_err_t fsp_err = FSP_SUCCESS; @@ -199,9 +189,6 @@ static void renesas_ra_adc_callback(adc_callback_args_t *p_args) } } -/** - * Voltage reference covert handler - */ static int adc_map_vref(const struct adc_ra_config *cfg, adc_extended_cfg_t *extend) { switch (cfg->variant) { @@ -240,15 +227,6 @@ static int adc_map_vref(const struct adc_ra_config *cfg, adc_extended_cfg_t *ext } } -/** - * @brief Check if buffer in @p sequence is big enough to hold all ADC samples - * - * @param dev RA ADC device - * @param sequence ADC sequence description - * - * @return 0 on success - * @return -ENOMEM if buffer is not big enough - */ static int adc_ra_check_buffer_size(const struct device *dev, const struct adc_sequence *sequence) { uint8_t channels = 0; @@ -268,19 +246,6 @@ static int adc_ra_check_buffer_size(const struct device *dev, const struct adc_s return 0; } -/** - * @brief Start processing read request - * - * @param dev RA ADC device - * @param sequence ADC sequence description - * - * @return 0 on success - * @return -ENOTSUP if requested resolution or channel is out side of supported - * range - * @return -ENOMEM if buffer is not big enough - * (see @ref adc_ra_check_buffer_size) - * @return other error code returned by adc_context_wait_for_completion - */ static int adc_ra_start_read(const struct device *dev, const struct adc_sequence *sequence) { const struct adc_ra_config *config = dev->config; @@ -336,20 +301,6 @@ static int adc_ra_start_read(const struct device *dev, const struct adc_sequence return 0; } -/** - * @brief Start processing read request asynchronously - * - * @param dev RA ADC device - * @param sequence ADC sequence description - * @param async async pointer to asynchronous signal - * - * @return 0 on success - * @return -ENOTSUP if requested resolution or channel is out side of supported - * range - * @return -ENOMEM if buffer is not big enough - * (see @ref adc_ra_check_buffer_size) - * @return other error code returned by adc_context_wait_for_completion - */ static int adc_ra_read_async(const struct device *dev, const struct adc_sequence *sequence, struct k_poll_signal *async) { @@ -363,19 +314,6 @@ static int adc_ra_read_async(const struct device *dev, const struct adc_sequence return err; } -/** - * @brief Start processing read request synchronously - * - * @param dev RA ADC device - * @param sequence ADC sequence description - * - * @return 0 on success - * @return -ENOTSUP if requested resolution or channel is out side of supported - * range - * @return -ENOMEM if buffer is not big enough - * (see @ref adc_ra_check_buffer_size) - * @return other error code returned by adc_context_wait_for_completion - */ static int adc_ra_read(const struct device *dev, const struct adc_sequence *sequence) { return adc_ra_read_async(dev, sequence, NULL); @@ -399,16 +337,6 @@ static void adc_context_update_buffer_pointer(struct adc_context *ctx, bool repe } } -/** - * @brief Function called on init for each RA ADC device. It setups all - * channels to return constant 0 mV and create acquisition thread. - * - * @param dev RA ADC device - * - * @return -EIO if error - * - * @return 0 on success - */ static int adc_ra_init(const struct device *dev) { const struct adc_ra_config *config = dev->config; From 5fdd2a67bcbe9611a7126c2269c57668cb80c862 Mon Sep 17 00:00:00 2001 From: Thinh Le Cong Date: Tue, 30 Sep 2025 17:41:45 +0700 Subject: [PATCH 0524/3659] doc: releases: Update migration guilde for ADC driver Update the migration guilde for ADC driver when support 16-bit resolution Signed-off-by: Thinh Le Cong --- doc/releases/migration-guide-4.4.rst | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/doc/releases/migration-guide-4.4.rst b/doc/releases/migration-guide-4.4.rst index cffc4cdbb2e2..c5dba858826b 100644 --- a/doc/releases/migration-guide-4.4.rst +++ b/doc/releases/migration-guide-4.4.rst @@ -39,6 +39,17 @@ Device Drivers and Devicetree .. zephyr-keep-sorted-start re(^\w) +ADC +=== + +* The :dtcompatible:`renesas,ra-adc` compatible has been replaced by + :dtcompatible:`renesas,ra-adc12`. Applications using the old compatible + must update their devicetree nodes. + +* The :dtcompatible:`renesas,ra-adc16` compatible was added. This must be + used when working with the EK-RA2A1 board, which provides a 16-bit ADC + resolution. + Controller Area Network (CAN) ============================= From 9e42f9fc34443b6ec76deed24f2f9a942942c922 Mon Sep 17 00:00:00 2001 From: Lucien Zhao Date: Wed, 12 Nov 2025 17:35:05 +0800 Subject: [PATCH 0525/3659] arch: arm: mpu: Add Kconfig options for SRAM Write-Through cache policy - CONFIG_ARM_MPU_SRAM_WRITE_THROUGH: enables Write-Through cache policy for SRAM regions instead of default Write-Back Includes corresponding MPU attribute macros for ARMv7-M and ARMv8-M architectures. Maintains backward compatibility with existing configurations. Signed-off-by: Lucien Zhao --- arch/arm/core/mpu/Kconfig | 6 ++++++ arch/arm/core/mpu/arm_mpu.c | 5 +++++ arch/arm/core/mpu/arm_mpu_regions.c | 10 ++++++++-- include/zephyr/arch/arm/mpu/arm_mpu_v7m.h | 3 +++ include/zephyr/arch/arm/mpu/arm_mpu_v8.h | 17 +++++++++++++++++ .../dt-bindings/memory-attr/memory-attr-arm.h | 2 ++ 6 files changed, 41 insertions(+), 2 deletions(-) diff --git a/arch/arm/core/mpu/Kconfig b/arch/arm/core/mpu/Kconfig index 698b2bb270a8..828122e86b8e 100644 --- a/arch/arm/core/mpu/Kconfig +++ b/arch/arm/core/mpu/Kconfig @@ -79,6 +79,12 @@ config ARM_MPU_PXN unprivileged mode and executing such region from privileged mode will result in a Memory Management fault. +config ARM_MPU_SRAM_WRITE_THROUGH + bool "Use Write-Through cache policy for SRAM regions" + help + When enabled, SRAM regions will use Write-Through cache policy + instead of the default Write-Back policy. + endif # ARM_MPU endif # CPU_HAS_MPU diff --git a/arch/arm/core/mpu/arm_mpu.c b/arch/arm/core/mpu/arm_mpu.c index d37d36967c78..602e56010bff 100644 --- a/arch/arm/core/mpu/arm_mpu.c +++ b/arch/arm/core/mpu/arm_mpu.c @@ -156,6 +156,11 @@ static int mpu_configure_regions_from_dt(uint8_t *reg_index) case DT_MEM_ARM_MPU_EXTMEM: region_conf = _BUILD_REGION_CONF(region[idx], REGION_EXTMEM_ATTR); break; +#endif +#ifdef REGION_RAM_WT_ATTR + case DT_MEM_ARM_MPU_RAM_WT: + region_conf = _BUILD_REGION_CONF(region[idx], REGION_RAM_WT_ATTR); + break; #endif default: /* Attribute other than ARM-specific is set. diff --git a/arch/arm/core/mpu/arm_mpu_regions.c b/arch/arm/core/mpu/arm_mpu_regions.c index f5f725a75fb6..4771c5914ce6 100644 --- a/arch/arm/core/mpu/arm_mpu_regions.c +++ b/arch/arm/core/mpu/arm_mpu_regions.c @@ -9,6 +9,12 @@ #include +#ifdef CONFIG_ARM_MPU_SRAM_WRITE_THROUGH +#define ARM_MPU_SRAM_REGION_ATTR REGION_RAM_WT_ATTR +#else +#define ARM_MPU_SRAM_REGION_ATTR REGION_RAM_ATTR +#endif + static const struct arm_mpu_region mpu_regions[] = { #ifdef CONFIG_XIP /* Region 0 */ @@ -26,10 +32,10 @@ static const struct arm_mpu_region mpu_regions[] = { MPU_REGION_ENTRY("SRAM_0", CONFIG_SRAM_BASE_ADDRESS, #if defined(CONFIG_ARMV8_M_BASELINE) || defined(CONFIG_ARMV8_M_MAINLINE) - REGION_RAM_ATTR(CONFIG_SRAM_BASE_ADDRESS, \ + ARM_MPU_SRAM_REGION_ATTR(CONFIG_SRAM_BASE_ADDRESS, CONFIG_SRAM_SIZE * 1024)), #else - REGION_RAM_ATTR(REGION_SRAM_SIZE)), + ARM_MPU_SRAM_REGION_ATTR(REGION_SRAM_SIZE)), #endif }; diff --git a/include/zephyr/arch/arm/mpu/arm_mpu_v7m.h b/include/zephyr/arch/arm/mpu/arm_mpu_v7m.h index 3b1c6637b8f8..20742cc06f06 100644 --- a/include/zephyr/arch/arm/mpu/arm_mpu_v7m.h +++ b/include/zephyr/arch/arm/mpu/arm_mpu_v7m.h @@ -118,6 +118,9 @@ #define REGION_RAM_ATTR(size) \ {(NORMAL_OUTER_INNER_WRITE_BACK_WRITE_READ_ALLOCATE_NON_SHAREABLE | \ IF_ENABLED(CONFIG_XIP, (MPU_RASR_XN_Msk |)) size | P_RW_U_NA_Msk)} +#define REGION_RAM_WT_ATTR(size) \ + {(NORMAL_OUTER_INNER_WRITE_THROUGH_NON_SHAREABLE | \ + IF_ENABLED(CONFIG_XIP, (MPU_RASR_XN_Msk |)) size | P_RW_U_NA_Msk)} #define REGION_RAM_NOCACHE_ATTR(size) \ {(NORMAL_OUTER_INNER_NON_CACHEABLE_NON_SHAREABLE | MPU_RASR_XN_Msk | size | P_RW_U_NA_Msk)} #if defined(CONFIG_MPU_ALLOW_FLASH_WRITE) diff --git a/include/zephyr/arch/arm/mpu/arm_mpu_v8.h b/include/zephyr/arch/arm/mpu/arm_mpu_v8.h index e063f392f07d..e0fd7c787838 100644 --- a/include/zephyr/arch/arm/mpu/arm_mpu_v8.h +++ b/include/zephyr/arch/arm/mpu/arm_mpu_v8.h @@ -250,6 +250,15 @@ IF_ENABLED(CONFIG_ARM_MPU_PXN, (.pxn = !PRIV_EXEC_NEVER,)) \ } +#define REGION_RAM_WT_ATTR(base, size) \ + { \ + .rbar = IF_ENABLED(CONFIG_XIP, (NOT_EXEC |)) P_RW_U_NA_Msk | \ + NON_SHAREABLE_Msk, /* AP, XN, SH */ \ + .mair_idx = MPU_MAIR_INDEX_FLASH, /* Cache-ability */ \ + .r_limit = REGION_LIMIT_ADDR(base, size), /* Region Limit */ \ + IF_ENABLED(CONFIG_ARM_MPU_PXN, (.pxn = !PRIV_EXEC_NEVER,)) \ + } + #if defined(CONFIG_ARM_MPU_PXN) /* Use this attr to define an MPU region in RAM that has code intended to be executed in * un-privileged mode but not in privileged mode. @@ -261,6 +270,14 @@ .r_limit = REGION_LIMIT_ADDR(base, size), /* Region Limit */ \ .pxn = PRIV_EXEC_NEVER, \ } + +#define REGION_RAM_WT_ATTR_PXN(base, size) \ + { \ + .rbar = P_RO_U_RO_Msk | NON_SHAREABLE_Msk,/* AP, XN, SH */ \ + .mair_idx = MPU_MAIR_INDEX_FLASH, /* Cache-ability */ \ + .r_limit = REGION_LIMIT_ADDR(base, size), /* Region Limit */ \ + .pxn = PRIV_EXEC_NEVER, \ + } #endif #define REGION_RAM_NOCACHE_ATTR(base, size) \ diff --git a/include/zephyr/dt-bindings/memory-attr/memory-attr-arm.h b/include/zephyr/dt-bindings/memory-attr/memory-attr-arm.h index c4a7b01774db..69c8a6e91fa5 100644 --- a/include/zephyr/dt-bindings/memory-attr/memory-attr-arm.h +++ b/include/zephyr/dt-bindings/memory-attr/memory-attr-arm.h @@ -31,6 +31,7 @@ #define ATTR_MPU_EXTMEM BIT(5) #define ATTR_MPU_RAM_PXN BIT(6) #define ATTR_MPU_DEVICE BIT(7) +#define ATTR_MPU_RAM_WT BIT(8) #define DT_MEM_ARM_MPU_RAM DT_MEM_ARM(ATTR_MPU_RAM) #define DT_MEM_ARM_MPU_RAM_NOCACHE DT_MEM_ARM(ATTR_MPU_RAM_NOCACHE) @@ -40,6 +41,7 @@ #define DT_MEM_ARM_MPU_EXTMEM DT_MEM_ARM(ATTR_MPU_EXTMEM) #define DT_MEM_ARM_MPU_RAM_PXN DT_MEM_ARM(ATTR_MPU_RAM_PXN) #define DT_MEM_ARM_MPU_DEVICE DT_MEM_ARM(ATTR_MPU_DEVICE) +#define DT_MEM_ARM_MPU_RAM_WT DT_MEM_ARM(ATTR_MPU_RAM_WT) #define DT_MEM_ARM_MPU_UNKNOWN DT_MEM_ARCH_ATTR_UNKNOWN #endif /* ZEPHYR_INCLUDE_DT_BINDINGS_MEM_ATTR_ARM_H_ */ From 9a1dd6ebab5483b6b66330686947fecd75d6ca45 Mon Sep 17 00:00:00 2001 From: Lucien Zhao Date: Wed, 26 Nov 2025 10:13:09 +0800 Subject: [PATCH 0526/3659] tests: arch: arm: add ARM MPU write-through test Add test suite for ARM MPU write-through cache functionality including: - Cache coherency validation with dma ways - Cache coherency validation Support case on mimxrt1180_evk cm33/cm7 cores Signed-off-by: Lucien Zhao --- boards/nxp/mimxrt1180_evk/cm7/mpu_regions.c | 10 +- tests/arch/arm/arm_mpu_wt/CMakeLists.txt | 7 + .../mimxrt1180_evk_mimxrt1189_cm33.overlay | 16 + .../mimxrt1180_evk_mimxrt1189_cm7.overlay | 11 + tests/arch/arm/arm_mpu_wt/prj.conf | 7 + tests/arch/arm/arm_mpu_wt/src/main.c | 518 ++++++++++++++++++ tests/arch/arm/arm_mpu_wt/testcase.yaml | 15 + 7 files changed, 582 insertions(+), 2 deletions(-) create mode 100644 tests/arch/arm/arm_mpu_wt/CMakeLists.txt create mode 100644 tests/arch/arm/arm_mpu_wt/boards/mimxrt1180_evk_mimxrt1189_cm33.overlay create mode 100644 tests/arch/arm/arm_mpu_wt/boards/mimxrt1180_evk_mimxrt1189_cm7.overlay create mode 100644 tests/arch/arm/arm_mpu_wt/prj.conf create mode 100644 tests/arch/arm/arm_mpu_wt/src/main.c create mode 100644 tests/arch/arm/arm_mpu_wt/testcase.yaml diff --git a/boards/nxp/mimxrt1180_evk/cm7/mpu_regions.c b/boards/nxp/mimxrt1180_evk/cm7/mpu_regions.c index cd444ea4ec67..63693357a308 100644 --- a/boards/nxp/mimxrt1180_evk/cm7/mpu_regions.c +++ b/boards/nxp/mimxrt1180_evk/cm7/mpu_regions.c @@ -7,6 +7,12 @@ #include #include +#ifdef CONFIG_ARM_MPU_SRAM_WRITE_THROUGH +#define ARM_MPU_SRAM_REGION_ATTR REGION_RAM_WT_ATTR +#else +#define ARM_MPU_SRAM_REGION_ATTR REGION_RAM_ATTR +#endif + #define MEMORY_REGION_SIZE_KB(SIZE) (SIZE / 1024) #define ITCM_SIZE DT_REG_SIZE_BY_IDX(DT_NODELABEL(itcm), 0) @@ -60,7 +66,7 @@ static const struct arm_mpu_region mpu_regions[] = { #if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(ocram1)) MPU_REGION_ENTRY("OCRAM1", REGION_OCRAM1_SHM_BASE_ADDRESS, - REGION_RAM_ATTR(REGION_OCRAM1_SHM_SIZE)), + ARM_MPU_SRAM_REGION_ATTR(REGION_OCRAM1_SHM_SIZE)), #endif #if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(ocram2)) @@ -70,7 +76,7 @@ static const struct arm_mpu_region mpu_regions[] = { #if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(hyperram0)) MPU_REGION_ENTRY("HYPER_RAM", REGION_HYPER_RAM_BASE_ADDRESS, - REGION_RAM_ATTR(REGION_HYPER_RAM_SIZE)), + ARM_MPU_SRAM_REGION_ATTR(REGION_HYPER_RAM_SIZE)), #endif #if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(w25q128jw)) diff --git a/tests/arch/arm/arm_mpu_wt/CMakeLists.txt b/tests/arch/arm/arm_mpu_wt/CMakeLists.txt new file mode 100644 index 000000000000..4b3c03ecf8de --- /dev/null +++ b/tests/arch/arm/arm_mpu_wt/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(arm_mpu_wt) + +target_sources(app PRIVATE src/main.c) diff --git a/tests/arch/arm/arm_mpu_wt/boards/mimxrt1180_evk_mimxrt1189_cm33.overlay b/tests/arch/arm/arm_mpu_wt/boards/mimxrt1180_evk_mimxrt1189_cm33.overlay new file mode 100644 index 000000000000..885bb481da86 --- /dev/null +++ b/tests/arch/arm/arm_mpu_wt/boards/mimxrt1180_evk_mimxrt1189_cm33.overlay @@ -0,0 +1,16 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + test-dma = &edma3; + test-memory = &ocram2; + }; +}; + +&ocram2 { + zephyr,memory-attr = ; +}; diff --git a/tests/arch/arm/arm_mpu_wt/boards/mimxrt1180_evk_mimxrt1189_cm7.overlay b/tests/arch/arm/arm_mpu_wt/boards/mimxrt1180_evk_mimxrt1189_cm7.overlay new file mode 100644 index 000000000000..87d12957164c --- /dev/null +++ b/tests/arch/arm/arm_mpu_wt/boards/mimxrt1180_evk_mimxrt1189_cm7.overlay @@ -0,0 +1,11 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + test-dma = &edma3; + }; +}; diff --git a/tests/arch/arm/arm_mpu_wt/prj.conf b/tests/arch/arm/arm_mpu_wt/prj.conf new file mode 100644 index 000000000000..7df34b6917bd --- /dev/null +++ b/tests/arch/arm/arm_mpu_wt/prj.conf @@ -0,0 +1,7 @@ +CONFIG_HEAP_MEM_POOL_SIZE=16384 +CONFIG_KERNEL_MEM_POOL=y +CONFIG_MAIN_STACK_SIZE=2048 +CONFIG_ZTEST_STACK_SIZE=2048 +CONFIG_DMA=y +CONFIG_LOG=y +CONFIG_ZTEST=y diff --git a/tests/arch/arm/arm_mpu_wt/src/main.c b/tests/arch/arm/arm_mpu_wt/src/main.c new file mode 100644 index 000000000000..92e77087013d --- /dev/null +++ b/tests/arch/arm/arm_mpu_wt/src/main.c @@ -0,0 +1,518 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(arm_mpu_wt_test, LOG_LEVEL_INF); + +/* Test memory configuration */ +#define TEST_PATTERN_COUNT 8 +#define TEST_MEMORY_SIZE (sizeof(uint32_t) * TEST_PATTERN_COUNT) +#define CACHE_LINE_SIZE 32 /* Typical cache line size for ARM Cortex-M7/M33 */ +#define DMA_TIMEOUT_MS 1000 +#define DMA_CHANNEL 0 + +/* Memory region configuration from device tree */ +#if DT_NODE_EXISTS(DT_ALIAS(test_memory)) +#define TEST_MEMORY_NODE DT_ALIAS(test_memory) +#define TEST_MEMORY_BASE DT_REG_ADDR(TEST_MEMORY_NODE) +#define TEST_MEMORY_REGION_SIZE DT_REG_SIZE(TEST_MEMORY_NODE) +#define USE_CUSTOM_MEMORY 1 +#else +#define USE_CUSTOM_MEMORY 0 +#endif + +static const uint32_t test_patterns[] = { + 0x12345678U, 0xDEADBEEFU, 0xCAFEBABEU, 0x87654321U, + 0xA5A5A5A5U, 0x5A5A5A5AU, 0xFFFFFFFFU, 0x00000000U +}; + +/* DMA completion tracking */ +static volatile bool dma_transfer_done; +static struct k_sem dma_sem; + +/* Memory region tracking */ +struct memory_region { + uintptr_t base; + size_t size; + const char *name; + bool use_malloc; +}; + +static struct memory_region current_test_region; + +/** + * @brief Initialize test memory region + * + * @param region Pointer to memory region structure + * @return 0 on success, negative error code on failure + */ +static int init_test_memory_region(struct memory_region *region) +{ +#if USE_CUSTOM_MEMORY + region->base = TEST_MEMORY_BASE; + region->size = TEST_MEMORY_REGION_SIZE; + region->name = DT_NODE_FULL_NAME(TEST_MEMORY_NODE); + region->use_malloc = false; + + LOG_INF("Using custom memory region from device tree:"); + LOG_INF(" Node: %s", region->name); + LOG_INF(" Base: 0x%08x", (uint32_t)region->base); + LOG_INF(" Size: %zu bytes", region->size); +#else + /* Fallback to malloc-based allocation */ + region->base = 0; + region->size = 0; + region->name = "malloc (default SRAM)"; + region->use_malloc = true; + + LOG_INF("Using malloc-based memory allocation (default SRAM)"); +#endif + + return 0; +} + +/** + * @brief Get memory region information string + * + * @return String describing current memory region + */ +static const char *get_memory_region_info(void) +{ + static char info_buf[128]; + + if (current_test_region.use_malloc) { + snprintf(info_buf, sizeof(info_buf), "malloc (default SRAM)"); + } else { + snprintf(info_buf, sizeof(info_buf), "%s @ 0x%08x (%zu bytes)", + current_test_region.name, + (uint32_t)current_test_region.base, + current_test_region.size); + } + + return info_buf; +} + +/** + * @brief DMA callback function + * + * @param dev DMA device + * @param user_data User data (unused) + * @param channel DMA channel + * @param status Transfer status + */ +static void dma_callback(const struct device *dev, void *user_data, + uint32_t channel, int status) +{ + LOG_INF("DMA callback: dev=%s, channel=%d, status=%d", + dev ? dev->name : "NULL", channel, status); + + if (status == 0) { + LOG_INF("DMA transfer successful"); + dma_transfer_done = true; + k_sem_give(&dma_sem); + } else { + LOG_ERR("DMA transfer failed with status: %d", status); + dma_transfer_done = false; + k_sem_give(&dma_sem); + } +} + +/** + * @brief Allocate memory from test region + * + * @param size Size to allocate + * @return Pointer to allocated memory or NULL on failure + */ +static void *alloc_test_memory(size_t size) +{ + void *ptr; + static uintptr_t next_offset; + + if (current_test_region.use_malloc) { + /* Use standard malloc */ + ptr = k_malloc(size); + if (ptr != NULL && ((uintptr_t)ptr & (sizeof(uint32_t) - 1)) == 0) { + LOG_DBG("Allocated %zu bytes at %p via malloc", size, ptr); + return ptr; + } + + if (ptr != NULL) { + k_free(ptr); + } + return NULL; + } + + /* Use custom memory region */ + if (next_offset + size > current_test_region.size) { + LOG_ERR("Not enough space in custom memory region"); + LOG_ERR(" Requested: %zu bytes", size); + LOG_ERR(" Available: %zu bytes", (size_t)(current_test_region.size - next_offset)); + return NULL; + } + + ptr = (void *)(current_test_region.base + next_offset); + next_offset += ROUND_UP(size, sizeof(uint32_t)); + + LOG_DBG("Allocated %zu bytes at %p from custom region (offset: %zu)", + size, ptr, (size_t)(next_offset - ROUND_UP(size, sizeof(uint32_t)))); + + return ptr; +} + +/** + * @brief Free memory allocated from test region + * + * @param ptr Pointer to free + */ +static void free_test_memory(void *ptr) +{ + if (current_test_region.use_malloc && ptr != NULL) { + k_free(ptr); + LOG_DBG("Freed memory at %p via malloc", ptr); + } + /* For custom memory region, we don't actually free (simple bump allocator) */ +} + +/** + * @brief Get available DMA device + * + * @return Pointer to DMA device or NULL if not available + */ +static const struct device *get_dma_device(void) +{ +#if DT_NODE_EXISTS(DT_ALIAS(test_dma)) + const struct device *dma_dev = DEVICE_DT_GET(DT_ALIAS(test_dma)); + + if (device_is_ready(dma_dev)) { + return dma_dev; + } +#endif + return NULL; +} + +/** + * @brief Execute DMA transfer for coherency testing + * + * @param dma_dev DMA device + * @param src Source address + * @param dst Destination address + * @param size Transfer size in bytes + * @return 0 on success, negative error code on failure + */ +static int execute_dma_transfer(const struct device *dma_dev, void *src, + void *dst, size_t size) +{ + struct dma_config dma_cfg = {0}; + struct dma_block_config dma_block = {0}; + int ret; + + if (dma_dev == NULL) { + return -ENODEV; + } + + /* Validate alignment requirements for EDMA */ + if (((uintptr_t)src & (sizeof(uint32_t) - 1)) != 0 || + ((uintptr_t)dst & (sizeof(uint32_t) - 1)) != 0) { + LOG_ERR("Source or destination not properly aligned"); + return -EINVAL; + } + + if ((size & (sizeof(uint32_t) - 1)) != 0) { + LOG_ERR("Transfer size not multiple of %zu bytes", sizeof(uint32_t)); + return -EINVAL; + } + + dma_transfer_done = false; + +#ifdef CONFIG_CACHE_MANAGEMENT + /* Clean source cache to ensure data is written to memory */ + sys_cache_data_flush_range(src, size); + + /* Invalidate destination cache to ensure fresh read from memory */ + sys_cache_data_invd_range(dst, size); +#endif + + /* Configure DMA block */ + dma_block.source_address = (uintptr_t)src; + dma_block.dest_address = (uintptr_t)dst; + dma_block.block_size = size; + + LOG_INF("DMA config: src=0x%08x, dst=0x%08x, size=%zu", + (uint32_t)src, (uint32_t)dst, size); + + /* Configure DMA with proper settings for EDMA */ + dma_cfg.channel_direction = MEMORY_TO_MEMORY; + dma_cfg.source_data_size = 1; + dma_cfg.dest_data_size = 1; + dma_cfg.source_burst_length = 32; + dma_cfg.dest_burst_length = 32; + dma_cfg.block_count = 1; + dma_cfg.head_block = &dma_block; + dma_cfg.dma_callback = dma_callback; + dma_cfg.complete_callback_en = 1U; /* Enable completion callback */ + dma_cfg.error_callback_dis = 0U; /* Enable error callback */ + dma_cfg.user_data = NULL; + + LOG_INF("Configuring DMA channel %d", DMA_CHANNEL); + ret = dma_config(dma_dev, DMA_CHANNEL, &dma_cfg); + if (ret != 0) { + LOG_ERR("DMA config failed: %d", ret); + return ret; + } + + LOG_INF("Starting DMA transfer"); + ret = dma_start(dma_dev, DMA_CHANNEL); + if (ret != 0) { + LOG_ERR("DMA start failed: %d", ret); + return ret; + } + + LOG_INF("Waiting for DMA completion (timeout: %d ms)", DMA_TIMEOUT_MS); + ret = k_sem_take(&dma_sem, K_MSEC(DMA_TIMEOUT_MS)); + if (ret != 0) { + LOG_ERR("DMA transfer timeout"); + + /* Check DMA status */ + struct dma_status status; + int status_ret = dma_get_status(dma_dev, DMA_CHANNEL, &status); + + if (status_ret == 0) { + LOG_INF("DMA status: busy=%d, dir=%d, pending=%d", + status.busy, status.dir, status.pending_length); + } + + (void)dma_stop(dma_dev, DMA_CHANNEL); + return ret; + } + +#ifdef CONFIG_CACHE_MANAGEMENT + /* Invalidate destination cache after DMA to ensure CPU reads fresh data */ + sys_cache_data_invd_range(dst, size); +#endif + + LOG_INF("DMA transfer completed successfully"); + return 0; +} + +/** + * @brief Test Write-Through cache coherency using DMA with multiple patterns + */ +ZTEST(arm_mpu_wt, test_wt_dma_coherency) +{ + const struct device *dma_dev; + uint32_t *cpu_buffer; + uint32_t *dma_buffer; + int ret; + + dma_dev = get_dma_device(); + if (dma_dev == NULL) { + LOG_WRN("DMA device not available, skipping DMA coherency test"); + ztest_test_skip(); + return; + } + + LOG_INF("Using DMA device: %s", dma_dev->name); + LOG_INF("Testing memory region: %s", get_memory_region_info()); + + /* Allocate buffers large enough for all test patterns */ + cpu_buffer = alloc_test_memory(TEST_MEMORY_SIZE); + dma_buffer = alloc_test_memory(TEST_MEMORY_SIZE); + + if (cpu_buffer == NULL || dma_buffer == NULL) { + LOG_ERR("Failed to allocate test buffers"); + if (cpu_buffer != NULL) { + free_test_memory((void *)cpu_buffer); + } + if (dma_buffer != NULL) { + free_test_memory(dma_buffer); + } + ztest_test_skip(); + return; + } + + LOG_INF("Testing Write-Through DMA coherency with %d patterns", TEST_PATTERN_COUNT); + LOG_INF("CPU buffer: %p, DMA buffer: %p", (void *)cpu_buffer, (void *)dma_buffer); + LOG_INF("Buffer spacing: %d bytes", + (int)((uintptr_t)dma_buffer - (uintptr_t)cpu_buffer)); + LOG_INF("Transfer size: %u bytes", (unsigned int)TEST_MEMORY_SIZE); + + /* Initialize DMA buffer with known pattern (inverse of test patterns) */ + for (int i = 0; i < TEST_PATTERN_COUNT; i++) { + dma_buffer[i] = ~test_patterns[i]; /* Inverted pattern */ + } + + /* CPU writes all test patterns to buffer */ + for (int i = 0; i < TEST_PATTERN_COUNT; i++) { + cpu_buffer[i] = test_patterns[i]; + LOG_DBG("CPU wrote pattern[%d] = 0x%08x to %p", + i, test_patterns[i], (void *)&cpu_buffer[i]); + } + + /* + * With Write-Through cache: + * - CPU writes automatically go to both cache and memory + * - No explicit flush needed + * - Only need barrier to ensure write ordering before DMA starts + */ + barrier_dsync_fence_full(); + + LOG_INF("CPU wrote %d patterns to buffer at %p", + TEST_PATTERN_COUNT, (void *)cpu_buffer); + + /* DMA reads directly from memory (bypassing CPU cache) */ + ret = execute_dma_transfer(dma_dev, (void *)cpu_buffer, dma_buffer, + TEST_MEMORY_SIZE); + + if (ret == 0) { +#ifdef CONFIG_CACHE_MANAGEMENT + /* + * Invalidate destination cache to ensure CPU reads fresh data + * This is needed because DMA wrote to memory, bypassing cache + */ + sys_cache_data_invd_range(dma_buffer, TEST_MEMORY_SIZE); +#endif + + LOG_INF("DMA transfer completed, verifying %d patterns", TEST_PATTERN_COUNT); + + /* Verify all patterns were transferred correctly */ + bool all_passed = true; + + for (int i = 0; i < TEST_PATTERN_COUNT; i++) { + uint32_t expected = test_patterns[i]; + uint32_t actual = dma_buffer[i]; + + if (actual != expected) { + LOG_ERR("Pattern[%d] mismatch: expected 0x%08x, got 0x%08x", + i, expected, actual); + all_passed = false; + } else { + LOG_DBG("Pattern[%d] OK: 0x%08x", i, actual); + } + + /* + * Write-Through: DMA should read the value CPU just wrote + * because WT cache already wrote it to memory + */ + zassert_equal(actual, expected, + "DMA coherency test failed at pattern[%d]: " + "expected 0x%08x, got 0x%08x. " + "Write-Through may not be working correctly.", + i, expected, actual); + } + + if (all_passed) { + LOG_INF("DMA coherency test PASSED - All %d patterns verified", + TEST_PATTERN_COUNT); + LOG_INF("Write-Through cache is working correctly"); + } + } else { + LOG_ERR("DMA transfer failed: %d", ret); + ztest_test_fail(); + } + + free_test_memory((void *)cpu_buffer); + free_test_memory(dma_buffer); +} + +/** + * @brief Test Write-Through with cache invalidation using multiple patterns + */ +ZTEST(arm_mpu_wt, test_wt_cache_invalidate) +{ +#ifdef CONFIG_CACHE_MANAGEMENT + uint32_t *test_addr; + + /* Allocate enough space for all test patterns */ + test_addr = alloc_test_memory(TEST_MEMORY_SIZE); + if (test_addr == NULL) { + ztest_test_skip(); + return; + } + + LOG_INF("Testing cache invalidation with Write-Through"); + LOG_INF("Memory region: %s", get_memory_region_info()); + LOG_INF("Test address: %p (cache line aligned)", (void *)test_addr); + LOG_INF("Testing with %d patterns", TEST_PATTERN_COUNT); + + /* CPU writes all test patterns */ + for (int i = 0; i < TEST_PATTERN_COUNT; i++) { + test_addr[i] = test_patterns[i]; + LOG_DBG("Wrote pattern[%d] = 0x%08x", i, test_patterns[i]); + } + + /* Invalidate CPU cache to force read from memory */ + sys_cache_data_invd_range((void *)test_addr, TEST_MEMORY_SIZE); + barrier_dsync_fence_full(); + + LOG_INF("Cache invalidated, reading back from memory"); + + /* Read after invalidation - should read from memory */ + bool all_passed = true; + + for (int i = 0; i < TEST_PATTERN_COUNT; i++) { + uint32_t expected = test_patterns[i]; + uint32_t actual = test_addr[i]; + + if (actual != expected) { + LOG_ERR("Pattern[%d] mismatch after invalidation: " + "expected 0x%08x, got 0x%08x", + i, expected, actual); + all_passed = false; + } else { + LOG_DBG("Pattern[%d] OK after invalidation: 0x%08x", i, actual); + } + + /* + * Write-Through: Data should still be in memory after cache invalidation + * because WT cache already wrote it there + */ + zassert_equal(actual, expected, + "Cache invalidate test failed at pattern[%d]: " + "expected 0x%08x, got 0x%08x. " + "Write-Through should maintain memory consistency.", + i, expected, actual); + } + + if (all_passed) { + LOG_INF("Cache invalidation test PASSED - All %d patterns verified", + TEST_PATTERN_COUNT); + } + + free_test_memory((void *)test_addr); +#else + LOG_WRN("Cache management not enabled, skipping test"); + ztest_test_skip(); +#endif +} + +/** + * @brief Test suite setup function + * + * @return Test fixture data (NULL) + */ +static void *arm_mpu_wt_setup(void) +{ + /* Initialize DMA semaphore */ + k_sem_init(&dma_sem, 0, 1); + + /* Initialize test memory region */ + init_test_memory_region(¤t_test_region); + + LOG_INF("ARM MPU Write-Through test suite initialized"); + LOG_INF("Test memory region: %s", get_memory_region_info()); + + return NULL; +} + +ZTEST_SUITE(arm_mpu_wt, NULL, arm_mpu_wt_setup, NULL, NULL, NULL); diff --git a/tests/arch/arm/arm_mpu_wt/testcase.yaml b/tests/arch/arm/arm_mpu_wt/testcase.yaml new file mode 100644 index 000000000000..9116774d5475 --- /dev/null +++ b/tests/arch/arm/arm_mpu_wt/testcase.yaml @@ -0,0 +1,15 @@ +tests: + arch.arm.mpu.write_through: + tags: + - arm + - mpu + - cache + - dma + arch_allow: + - arm + filter: CONFIG_ARM_MPU and dt_alias_exists("test-dma") + integration_platforms: + - mimxrt1180_evk/mimxrt1189/cm33 + - mimxrt1180_evk/mimxrt1189/cm7 + extra_configs: + - CONFIG_ARM_MPU_SRAM_WRITE_THROUGH=y From 720408036e7a2e9267b503ea8e13c26328cc8101 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Thu, 11 Dec 2025 10:48:24 +0200 Subject: [PATCH 0527/3659] net: pkt_filter: Add API for catching UDP/TCP packets Allow user to setup a hook function that is called for each received UDP or TCP packet. Signed-off-by: Jukka Rissanen --- include/zephyr/net/net_pkt_filter.h | 43 +++++++++++++++++++++++++++++ subsys/net/pkt_filter/base.c | 21 ++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/include/zephyr/net/net_pkt_filter.h b/include/zephyr/net/net_pkt_filter.h index fe46db0dea06..07bd56c1000c 100644 --- a/include/zephyr/net/net_pkt_filter.h +++ b/include/zephyr/net/net_pkt_filter.h @@ -60,6 +60,7 @@ enum npf_test_type { NPF_TEST_TYPE_ETH_TYPE_UNMATCH, NPF_TEST_TYPE_ETH_VLAN_TYPE_MATCH, NPF_TEST_TYPE_ETH_VLAN_TYPE_UNMATCH, + NPF_TEST_TYPE_LOCAL_IN_MATCH, }; #if defined(CONFIG_NET_PKT_FILTER_LOG_LEVEL_DBG) || \ @@ -682,6 +683,48 @@ extern npf_test_fn_t npf_eth_vlan_type_unmatch; .test.type = NPF_TEST_TYPE_ETH_VLAN_TYPE_UNMATCH,)) \ } +/** + * @typedef npf_local_in_fn_t + * + * @brief Function that is called to get the verdict what should happen to + * the network packet. + * + * @param pkt Pointer to the network packet to be evaluated + * @param user_data A valid pointer to user data or NULL + * + * @return True if the packet matches, false otherwise + */ +typedef bool (npf_local_in_fn_t)(struct net_pkt *pkt, void *user_data); + +/** @cond INTERNAL_HIDDEN */ + +extern npf_test_fn_t npf_local_in_match; + +struct npf_test_local_in { + struct npf_test test; + npf_local_in_fn_t *fn; /* local_in hook function */ + void *user_data; /* optional user data */ +}; + +/** @endcond */ + +/** + * @brief Statically define a "local_in match" packet filter condition + * + * @param _name Name of the condition + * @param _handler Function to call for the local_in hook + * @param _user_data Optional user data pointer passed to the handler + */ +#define NPF_LOCAL_IN_MATCH(_name, _handler, _user_data) \ + struct npf_test_local_in _name = { \ + .test.fn = npf_local_in_match, \ + .fn = (_handler), \ + .user_data = (_user_data), \ + IF_ENABLED(NPF_TEST_ENABLE_NAME, \ + (.test.name = "local_in", \ + .test.type = NPF_TEST_TYPE_LOCAL_IN_MATCH,)) \ + } + /** Type of the packet filter rule. */ enum npf_rule_type { NPF_RULE_TYPE_UNKNOWN = 0, /**< Unknown rule type */ diff --git a/subsys/net/pkt_filter/base.c b/subsys/net/pkt_filter/base.c index 7825361f2379..a0ae39e509e4 100644 --- a/subsys/net/pkt_filter/base.c +++ b/subsys/net/pkt_filter/base.c @@ -328,6 +328,20 @@ static void rules_cb(struct npf_rule_list *rules, enum npf_rule_type type, } } +#ifdef CONFIG_NET_PKT_FILTER_LOCAL_IN_HOOK +bool npf_local_in_match(struct npf_test *test, struct net_pkt *pkt) +{ + struct npf_test_local_in *test_local_in = + CONTAINER_OF(test, struct npf_test_local_in, test); + + if (test_local_in->fn == NULL) { + return true; + } + + return test_local_in->fn(pkt, test_local_in->user_data); +} +#endif /* CONFIG_NET_PKT_FILTER_LOCAL_IN_HOOK */ + void npf_rules_foreach(npf_rule_cb_t cb, void *user_data) { rules_cb(&npf_send_rules, NPF_RULE_TYPE_SEND, cb, user_data); @@ -462,6 +476,13 @@ const char *npf_test_get_str(struct npf_test *test, char *buf, size_t len) CONTAINER_OF(test, struct npf_test_eth_type, test); snprintk(buf, len, "[0x%04x]", net_ntohs(test_eth->type)); + + } else if (test->type == NPF_TEST_TYPE_LOCAL_IN_MATCH) { + struct npf_test_local_in *test_local_in = + CONTAINER_OF(test, struct npf_test_local_in, test); + + snprintk(buf, len, "[fn=%p, data=%p]", + test_local_in->fn, test_local_in->user_data); } out: From d51356fd070776538f0bcfc7b9077b598c22a39f Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Thu, 11 Dec 2025 10:52:37 +0200 Subject: [PATCH 0528/3659] samples: net: pkt_filter: Add example of how to handle UDP/TCP packets Add support for LOCAL_IN rules that can be tracked UDP or TCP packets. Signed-off-by: Jukka Rissanen --- samples/net/pkt_filter/src/main.c | 32 +++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/samples/net/pkt_filter/src/main.c b/samples/net/pkt_filter/src/main.c index 60b6eefa2930..aa1c91e6ea05 100644 --- a/samples/net/pkt_filter/src/main.c +++ b/samples/net/pkt_filter/src/main.c @@ -86,6 +86,35 @@ static NPF_IP_SRC_ADDR_BLOCKLIST(ipv6_src_block, static NPF_RULE(ipv4_addr_block, NET_OK, ipv4_src_block); static NPF_RULE(ipv6_addr_block, NET_OK, ipv6_src_block); +/* Rules for other upper layer protocols like UDP or TCP */ +/* The pkt_counter is used to count matched packets in the handler. It is optional + * and it is up to the application how to use it. + */ +static int user_data_pkt_counter; + +static bool handler_local_in(struct net_pkt *pkt, void *user_data) +{ + int *pkt_counter = (int *)user_data; + + if (pkt_counter != NULL) { + (*pkt_counter)++; + + LOG_DBG("Local-in matched packets: %d", *pkt_counter); + } else { + LOG_DBG("Local-in matched packet"); + } + + /* We can evaluate the packet here and return true/false based on that. + * For this sample, we just return true to match all the received packets. + */ + + return true; +} + +/* Note that the user_data argument is optional and can be NULL */ +static NPF_LOCAL_IN_MATCH(local_in_match, handler_local_in, &user_data_pkt_counter); +static NPF_RULE(local_in_rule, NET_OK, local_in_match); + static void iface_cb(struct net_if *iface, void *user_data) { int count = 0; @@ -181,6 +210,9 @@ static void init_app(void) /* We block packets from specific IPv6 addresses */ npf_append_ipv6_recv_rule(&ipv6_addr_block); + + /* Catch other upper layer protocols like UDP / TCP */ + npf_append_local_in_recv_rule(&local_in_rule); } int main(void) From 0267faf22cd33550ded0b28f6fe1ec897389f3e9 Mon Sep 17 00:00:00 2001 From: Martin Lampacher Date: Fri, 12 Dec 2025 10:08:39 +0000 Subject: [PATCH 0529/3659] boards: st: update board.cmake and docs for nucleo_u0x Added stlink_gdbserver as a runner for the nucleo_u0x boards. Updated the boards' documentation to mention that JLink runners do not work with the onboard debug probe and removed mention of the unsupported openocd runner. Signed-off-by: Martin Lampacher --- boards/st/nucleo_u031r8/board.cmake | 3 +++ boards/st/nucleo_u031r8/doc/index.rst | 13 ++++++++++++- boards/st/nucleo_u083rc/board.cmake | 3 +++ boards/st/nucleo_u083rc/doc/index.rst | 13 ++++++++++++- 4 files changed, 30 insertions(+), 2 deletions(-) diff --git a/boards/st/nucleo_u031r8/board.cmake b/boards/st/nucleo_u031r8/board.cmake index fbd5f1ed8e76..81c22c73645e 100644 --- a/boards/st/nucleo_u031r8/board.cmake +++ b/boards/st/nucleo_u031r8/board.cmake @@ -5,7 +5,10 @@ board_runner_args(pyocd "--target=stm32u031r8tx") board_runner_args(jlink "--device=STM32U031R8" "--reset-after-load") +board_runner_args(stlink_gdbserver "--apid=0") + # keep first include(${ZEPHYR_BASE}/boards/common/stm32cubeprogrammer.board.cmake) include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake) include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) +include(${ZEPHYR_BASE}/boards/common/stlink_gdbserver.board.cmake) diff --git a/boards/st/nucleo_u031r8/doc/index.rst b/boards/st/nucleo_u031r8/doc/index.rst index 8645101911ba..3129d397017a 100644 --- a/boards/st/nucleo_u031r8/doc/index.rst +++ b/boards/st/nucleo_u031r8/doc/index.rst @@ -171,6 +171,15 @@ Programming and Debugging Nucleo U031R8 board includes an ST-LINK/V3 embedded debug tool interface. This probe allows to flash the board using various tools. +.. warning:: + The onboard ST-LINK/V3 debug probe cannot be `converted into a JLink probe`_; + as such, usage of the JLink runner requires an external JLink debug probe. + +.. warning:: + There are known issues about the usage of the pyOCD runner with this board. + If issues are encountered (e.g., debugging does not work), use the + :ref:`ST-Link GDB Server ` runner instead. + Flashing ======== @@ -223,7 +232,6 @@ You should see the following message on the console: Debugging ========= -Default flasher for this board is openocd. It could be used in the usual way. Here is an example for the :zephyr:code-sample:`blinky` application. .. zephyr-app-commands:: @@ -245,3 +253,6 @@ Here is an example for the :zephyr:code-sample:`blinky` application. .. _STM32CubeProgrammer: https://www.st.com/en/development-tools/stm32cubeprog.html + +.. _converted into a JLink probe: + https://www.segger.com/products/debug-probes/j-link/models/other-j-links/st-link-on-board/ diff --git a/boards/st/nucleo_u083rc/board.cmake b/boards/st/nucleo_u083rc/board.cmake index 0a9ce749ed05..9883d879e1e9 100644 --- a/boards/st/nucleo_u083rc/board.cmake +++ b/boards/st/nucleo_u083rc/board.cmake @@ -7,7 +7,10 @@ board_runner_args(pyocd "--flash-opt=-O connect_mode=under-reset") board_runner_args(jlink "--device=STM32U083RC" "--reset-after-load") +board_runner_args(stlink_gdbserver "--apid=0") + # keep first include(${ZEPHYR_BASE}/boards/common/stm32cubeprogrammer.board.cmake) include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake) include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) +include(${ZEPHYR_BASE}/boards/common/stlink_gdbserver.board.cmake) diff --git a/boards/st/nucleo_u083rc/doc/index.rst b/boards/st/nucleo_u083rc/doc/index.rst index 8fb0af2a60bd..c1d7ba90ec8b 100644 --- a/boards/st/nucleo_u083rc/doc/index.rst +++ b/boards/st/nucleo_u083rc/doc/index.rst @@ -184,6 +184,15 @@ Programming and Debugging Nucleo U083RC board includes an ST-LINK/V3 embedded debug tool interface. This probe allows to flash the board using various tools. +.. warning:: + The onboard ST-LINK/V3 debug probe cannot be `converted into a JLink probe`_; + as such, usage of the JLink runner requires an external JLink debug probe. + +.. warning:: + There are known issues about the usage of the pyOCD runner with this board. + If issues are encountered (e.g., debugging does not work), use the + :ref:`ST-Link GDB Server ` runner instead. + Flashing ======== @@ -236,7 +245,6 @@ You should see the following message on the console: Debugging ========= -Default flasher for this board is openocd. It could be used in the usual way. Here is an example for the :zephyr:code-sample:`blinky` application. .. zephyr-app-commands:: @@ -258,3 +266,6 @@ Here is an example for the :zephyr:code-sample:`blinky` application. .. _STM32CubeProgrammer: https://www.st.com/en/development-tools/stm32cubeprog.html + +.. _converted into a JLink probe: + https://www.segger.com/products/debug-probes/j-link/models/other-j-links/st-link-on-board/ From c3229f04b57d3ab78a5afdf227b133d6ed65b38b Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 15 Dec 2025 11:09:37 +0100 Subject: [PATCH 0530/3659] manifest: Update nRF hw models to latest Update the HW models module to: 0f0c43748111c65800c6920f1c0690676423a351 Including the following: 0f0c437 nrfx: Replace nrfx_gppi_domain_id_get() (requires new nrfx) 1bead00 nrf_ppi: Add support for NRF_PPI_ENDPOINT_IS_EVENT in simulation 9f11c2f NHW_misc: Add API to convert from/to simulated addr to real HW ones Note: This requires an nrfx 4.0.x which is newer than 2025/12/03, i.e. modules/hal/nordic 0dbbf4794156ca09dc2d4bad8c42dcdb54acd662 or newer which is has been used in Zephyr main since Zephyr's 242bf65d1d5432d43821b44f146e35d63c5334f0 Signed-off-by: Alberto Escolar Piedras --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 01700efd6443..c8f4c2c50126 100644 --- a/west.yml +++ b/west.yml @@ -344,7 +344,7 @@ manifest: groups: - tools - name: nrf_hw_models - revision: 5eec7aca321735f5fc8e3e7c79e162f0e9810b16 + revision: 0f0c43748111c65800c6920f1c0690676423a351 path: modules/bsim_hw_models/nrf_hw_models - name: nrf_wifi revision: 9f09f0785f9fc716514d8956a2a446021697400c From 516bca6e05d6c892e610ebf79ea3832f50c10760 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Wed, 17 Dec 2025 07:41:58 -0500 Subject: [PATCH 0531/3659] ci: assigner: fix condition for running script Wrong logic in condition results in running the script with the wrong arguments. Signed-off-by: Anas Nashif --- .github/workflows/assigner.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/assigner.yml b/.github/workflows/assigner.yml index e1dc1006f85b..5ee44a84ce9c 100644 --- a/.github/workflows/assigner.yml +++ b/.github/workflows/assigner.yml @@ -63,7 +63,7 @@ jobs: FLAGS+=" -r ${{ github.event.repository.name }}" FLAGS+=" -M MAINTAINERS.yml" if [ "${{ github.event_name }}" = "pull_request_target" ]; then - if [ "${{ github.base_ref }}" != "main" ]; then + if [ "${{ github.base_ref }}" = "main" ]; then FLAGS+=" -P ${{ github.event.pull_request.number }} --updated-manifest pr_west.yml --updated-maintainer-file pr_MAINTAINERS.yml" else FLAGS+=" -P ${{ github.event.pull_request.number }}" From 0e041f9c5974895930e754b0f430683ff5f6c1f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Wed, 17 Dec 2025 12:54:36 +0100 Subject: [PATCH 0532/3659] doc: index.html: fix overflow bug on welcome admonition. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix a rare bug where some browsers seem to consider the welcome admonition is overflowing. This fixes zephyrproject-rtos/zephyr#101167. Signed-off-by: Benjamin Cabé --- doc/index.html | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/index.html b/doc/index.html index 3decdcbb97ce..09b6e57ca955 100644 --- a/doc/index.html +++ b/doc/index.html @@ -7,6 +7,7 @@ background: transparent; border-left: 2px solid var(--navbar-scrollbar-active-color); padding: 0 0 0 1rem; + overflow: visible; .admonition-title { color: var(--body-color); From 16164b35dc648b9ac79dca234d0b1eb50853df45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Wed, 17 Dec 2025 14:27:42 +0100 Subject: [PATCH 0533/3659] MAINTAINERS: add doc/index.html to Documentation area MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit add this file to make sure edits to it get proper maintainers/collaborators pulled in Signed-off-by: Benjamin Cabé --- MAINTAINERS.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index 1ea17aa2a850..9faf170ff2de 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -1218,6 +1218,7 @@ Documentation: - doc/substitutions.txt - doc/images/Zephyr-Kite-in-tree.png - doc/index-tex.rst + - doc/index.html - doc/index.rst - doc/kconfig.rst - doc/templates/sample.tmpl From c88758fdfb8bb5ce39ac030812c0565a246e5e29 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Mon, 15 Dec 2025 17:31:43 +0100 Subject: [PATCH 0534/3659] llext: make 2 arguments of llext_get_section_header() const ext and loader aren't modified inside llext_get_section_header(), they are just passed to llext_section_shndx(), where they're already const. Make them const in this function too. Signed-off-by: Guennadi Liakhovetski --- include/zephyr/llext/llext.h | 2 +- subsys/llext/llext.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/zephyr/llext/llext.h b/include/zephyr/llext/llext.h index 5cf4606acbd8..4a5272568329 100644 --- a/include/zephyr/llext/llext.h +++ b/include/zephyr/llext/llext.h @@ -396,7 +396,7 @@ ssize_t llext_find_section(struct llext_loader *loader, const char *search_name) * @retval -ENOTSUP "peek" method not supported * @retval -ENOENT section not found */ -int llext_get_section_header(struct llext_loader *loader, struct llext *ext, +int llext_get_section_header(const struct llext_loader *loader, const struct llext *ext, const char *search_name, elf_shdr_t *shdr); /** diff --git a/subsys/llext/llext.c b/subsys/llext/llext.c index b20a79c19de4..d52486b8bf0c 100644 --- a/subsys/llext/llext.c +++ b/subsys/llext/llext.c @@ -39,8 +39,8 @@ int llext_section_shndx(const struct llext_loader *ldr, const struct llext *ext, return -ENOENT; } -int llext_get_section_header(struct llext_loader *ldr, struct llext *ext, const char *search_name, - elf_shdr_t *shdr) +int llext_get_section_header(const struct llext_loader *ldr, const struct llext *ext, + const char *search_name, elf_shdr_t *shdr) { int ret; From a9d1932b2360d4158621fc9f03439a3c8a903740 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Stasiak?= Date: Mon, 15 Dec 2025 15:12:12 +0100 Subject: [PATCH 0535/3659] dts: nordic: nrf54lm20a: remove clockpin from TDM MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Not needed as nRF54LM20A does not support clockpin feature in GPIO. Signed-off-by: Michał Stasiak --- dts/vendor/nordic/nrf54lm20a.dtsi | 2 -- 1 file changed, 2 deletions(-) diff --git a/dts/vendor/nordic/nrf54lm20a.dtsi b/dts/vendor/nordic/nrf54lm20a.dtsi index 1b467f1171ed..4d4eb645ac7b 100644 --- a/dts/vendor/nordic/nrf54lm20a.dtsi +++ b/dts/vendor/nordic/nrf54lm20a.dtsi @@ -616,8 +616,6 @@ interrupts = <232 NRF_DEFAULT_IRQ_PRIORITY>; status = "disabled"; clocks = <&pclk32m>; - nordic,clockpin-enable = , - ; }; i2c23: i2c@ed000 { From a5ca188d84a60478a6b8d769f3058a6083852a3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20G=C5=82=C4=85b?= Date: Mon, 15 Dec 2025 13:38:42 +0100 Subject: [PATCH 0536/3659] tests: boards: nrf: i2s: Remove test that checks I2S clock divider MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove test from tests/boards/nrf/i2s/i2s_divider. The i2s_divider test was relying on debug log from I2S driver. With the recent NRFX updates log was removed. Better test, that counts rising edges on I2S_LRCLK line was added in downstream (https://github.com/nrfconnect/sdk-nrf/pull/26230). Signed-off-by: Sebastian Głąb --- .../boards/nrf/i2s/i2s_divider/CMakeLists.txt | 9 - .../boards/nrf52840dk_nrf52840.overlay | 28 --- .../boards/nrf5340dk_nrf5340_cpuapp.overlay | 32 ---- .../boards/nrf54l15dk_nrf54l15_cpuapp.overlay | 28 --- tests/boards/nrf/i2s/i2s_divider/prj.conf | 3 - tests/boards/nrf/i2s/i2s_divider/src/main.c | 167 ------------------ .../boards/nrf/i2s/i2s_divider/testcase.yaml | 32 ---- 7 files changed, 299 deletions(-) delete mode 100644 tests/boards/nrf/i2s/i2s_divider/CMakeLists.txt delete mode 100644 tests/boards/nrf/i2s/i2s_divider/boards/nrf52840dk_nrf52840.overlay delete mode 100644 tests/boards/nrf/i2s/i2s_divider/boards/nrf5340dk_nrf5340_cpuapp.overlay delete mode 100644 tests/boards/nrf/i2s/i2s_divider/boards/nrf54l15dk_nrf54l15_cpuapp.overlay delete mode 100644 tests/boards/nrf/i2s/i2s_divider/prj.conf delete mode 100644 tests/boards/nrf/i2s/i2s_divider/src/main.c delete mode 100644 tests/boards/nrf/i2s/i2s_divider/testcase.yaml diff --git a/tests/boards/nrf/i2s/i2s_divider/CMakeLists.txt b/tests/boards/nrf/i2s/i2s_divider/CMakeLists.txt deleted file mode 100644 index 35157bf3d443..000000000000 --- a/tests/boards/nrf/i2s/i2s_divider/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -cmake_minimum_required(VERSION 3.20.0) - -find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) -project(i2s_divider) - -FILE(GLOB app_sources src/*.c) -target_sources(app PRIVATE ${app_sources}) diff --git a/tests/boards/nrf/i2s/i2s_divider/boards/nrf52840dk_nrf52840.overlay b/tests/boards/nrf/i2s/i2s_divider/boards/nrf52840dk_nrf52840.overlay deleted file mode 100644 index ca21135bca4f..000000000000 --- a/tests/boards/nrf/i2s/i2s_divider/boards/nrf52840dk_nrf52840.overlay +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2025 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/ { - aliases { - i2s-node0 = &i2s0; - }; -}; - -&pinctrl { - i2s0_default_alt: i2s0_default_alt { - group1 { - psels = , - , - , - ; - }; - }; -}; - -&i2s0 { - status = "okay"; - pinctrl-0 = <&i2s0_default_alt>; - pinctrl-names = "default"; -}; diff --git a/tests/boards/nrf/i2s/i2s_divider/boards/nrf5340dk_nrf5340_cpuapp.overlay b/tests/boards/nrf/i2s/i2s_divider/boards/nrf5340dk_nrf5340_cpuapp.overlay deleted file mode 100644 index a4c595b1bcdb..000000000000 --- a/tests/boards/nrf/i2s/i2s_divider/boards/nrf5340dk_nrf5340_cpuapp.overlay +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2025 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/ { - aliases { - i2s-node0 = &i2s0; - }; -}; - -&pinctrl { - i2s0_default_alt: i2s0_default_alt { - group1 { - psels = , - , - , - ; - }; - }; -}; - -&uart1 { - status = "disabled"; -}; - -&i2s0 { - status = "okay"; - pinctrl-0 = <&i2s0_default_alt>; - pinctrl-names = "default"; -}; diff --git a/tests/boards/nrf/i2s/i2s_divider/boards/nrf54l15dk_nrf54l15_cpuapp.overlay b/tests/boards/nrf/i2s/i2s_divider/boards/nrf54l15dk_nrf54l15_cpuapp.overlay deleted file mode 100644 index 08de6a76c7c5..000000000000 --- a/tests/boards/nrf/i2s/i2s_divider/boards/nrf54l15dk_nrf54l15_cpuapp.overlay +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2025 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/ { - aliases { - i2s-node0 = &i2s20; - }; -}; - -&pinctrl { - i2s20_default_alt: i2s20_default_alt { - group1 { - psels = , - , - , - ; - }; - }; -}; - -&i2s20 { - status = "okay"; - pinctrl-0 = <&i2s20_default_alt>; - pinctrl-names = "default"; -}; diff --git a/tests/boards/nrf/i2s/i2s_divider/prj.conf b/tests/boards/nrf/i2s/i2s_divider/prj.conf deleted file mode 100644 index 38455942679e..000000000000 --- a/tests/boards/nrf/i2s/i2s_divider/prj.conf +++ /dev/null @@ -1,3 +0,0 @@ -CONFIG_ZTEST=y -CONFIG_I2S=y -CONFIG_I2S_LOG_LEVEL_INF=y diff --git a/tests/boards/nrf/i2s/i2s_divider/src/main.c b/tests/boards/nrf/i2s/i2s_divider/src/main.c deleted file mode 100644 index bc4176d3284b..000000000000 --- a/tests/boards/nrf/i2s/i2s_divider/src/main.c +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright (c) 2025 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include - -#define I2S_DEV_NODE DT_ALIAS(i2s_node0) - -#define WORD_SIZE 16U -#define NUMBER_OF_CHANNELS 2 -#define FRAME_CLK_FREQ 44100 - -#define NUM_BLOCKS 2 -#define TIMEOUT 1000 - -#define SAMPLES_COUNT 4 -/* Each word has one bit set */ -static const int16_t data[SAMPLES_COUNT] = {16, 32, 64, 128}; - -#define BLOCK_SIZE (2 * sizeof(data)) - -#ifdef CONFIG_NOCACHE_MEMORY - #define MEM_SLAB_CACHE_ATTR __nocache -#else - #define MEM_SLAB_CACHE_ATTR -#endif /* CONFIG_NOCACHE_MEMORY */ - -static char MEM_SLAB_CACHE_ATTR __aligned(WB_UP(32)) - _k_mem_slab_buf_tx_0_mem_slab[NUM_BLOCKS * WB_UP(BLOCK_SIZE)]; -STRUCT_SECTION_ITERABLE(k_mem_slab, tx_0_mem_slab) = - Z_MEM_SLAB_INITIALIZER(tx_0_mem_slab, _k_mem_slab_buf_tx_0_mem_slab, - WB_UP(BLOCK_SIZE), NUM_BLOCKS); - -static const struct device *dev_i2s; - -static const struct i2s_config default_i2s_cfg = { - .word_size = WORD_SIZE, - .channels = NUMBER_OF_CHANNELS, - .format = I2S_FMT_DATA_FORMAT_I2S, - .frame_clk_freq = FRAME_CLK_FREQ, - .block_size = BLOCK_SIZE, - .timeout = TIMEOUT, - .options = I2S_OPT_FRAME_CLK_MASTER | I2S_OPT_BIT_CLK_MASTER, - .mem_slab = &tx_0_mem_slab, -}; - -/** @brief Check actual PCM rate at frame_clk_freq=8000. - * - * - Configure I2S stream. - */ -ZTEST(drivers_i2s_clk_div, test_i2s_frame_clk_freq_08000) -{ - struct i2s_config i2s_cfg = default_i2s_cfg; - int ret; - - i2s_cfg.frame_clk_freq = 8000; - - ret = i2s_configure(dev_i2s, I2S_DIR_TX, &i2s_cfg); - zassert_ok(ret, "i2s_configure() returned %d", ret); -} - -/** @brief Check actual PCM rate at frame_clk_freq=16000. - * - * - Configure I2S stream. - */ -ZTEST(drivers_i2s_clk_div, test_i2s_frame_clk_freq_16000) -{ - struct i2s_config i2s_cfg = default_i2s_cfg; - int ret; - - i2s_cfg.frame_clk_freq = 16000; - - ret = i2s_configure(dev_i2s, I2S_DIR_TX, &i2s_cfg); - zassert_ok(ret, "i2s_configure() returned %d", ret); -} - -/** @brief Check actual PCM rate at frame_clk_freq=32000. - * - * - Configure I2S stream. - */ -ZTEST(drivers_i2s_clk_div, test_i2s_frame_clk_freq_32000) -{ - struct i2s_config i2s_cfg = default_i2s_cfg; - int ret; - - i2s_cfg.frame_clk_freq = 32000; - - ret = i2s_configure(dev_i2s, I2S_DIR_TX, &i2s_cfg); - zassert_ok(ret, "i2s_configure() returned %d", ret); -} - -/** @brief Check actual PCM rate at frame_clk_freq=44100. - * - * - Configure I2S stream. - */ -ZTEST(drivers_i2s_clk_div, test_i2s_frame_clk_freq_44100) -{ - struct i2s_config i2s_cfg = default_i2s_cfg; - int ret; - - i2s_cfg.frame_clk_freq = 44100; - - ret = i2s_configure(dev_i2s, I2S_DIR_TX, &i2s_cfg); - zassert_ok(ret, "i2s_configure() returned %d", ret); -} - -/** @brief Check actual PCM rate at frame_clk_freq=48000. - * - * - Configure I2S stream. - */ -ZTEST(drivers_i2s_clk_div, test_i2s_frame_clk_freq_48000) -{ - struct i2s_config i2s_cfg = default_i2s_cfg; - int ret; - - i2s_cfg.frame_clk_freq = 48000; - - ret = i2s_configure(dev_i2s, I2S_DIR_TX, &i2s_cfg); - zassert_ok(ret, "i2s_configure() returned %d", ret); -} - -/** @brief Check actual PCM rate at frame_clk_freq=88200. - * - * - Configure I2S stream. - */ -ZTEST(drivers_i2s_clk_div, test_i2s_frame_clk_freq_88200) -{ - struct i2s_config i2s_cfg = default_i2s_cfg; - int ret; - - i2s_cfg.frame_clk_freq = 88200; - - ret = i2s_configure(dev_i2s, I2S_DIR_TX, &i2s_cfg); - zassert_ok(ret, "i2s_configure() returned %d", ret); -} - -/** @brief Check actual PCM rate at frame_clk_freq=96000. - * - * - Configure I2S stream. - */ -ZTEST(drivers_i2s_clk_div, test_i2s_frame_clk_freq_96000) -{ - struct i2s_config i2s_cfg = default_i2s_cfg; - int ret; - - i2s_cfg.frame_clk_freq = 96000; - - ret = i2s_configure(dev_i2s, I2S_DIR_TX, &i2s_cfg); - zassert_ok(ret, "i2s_configure() returned %d", ret); -} - -static void *suite_setup(void) -{ - /* Check I2S Device. */ - dev_i2s = DEVICE_DT_GET_OR_NULL(I2S_DEV_NODE); - zassert_not_null(dev_i2s, "I2S device not found"); - zassert(device_is_ready(dev_i2s), "I2S device not ready"); - - return 0; -} - -ZTEST_SUITE(drivers_i2s_clk_div, NULL, suite_setup, NULL, NULL, NULL); diff --git a/tests/boards/nrf/i2s/i2s_divider/testcase.yaml b/tests/boards/nrf/i2s/i2s_divider/testcase.yaml deleted file mode 100644 index 55d6912d7b54..000000000000 --- a/tests/boards/nrf/i2s/i2s_divider/testcase.yaml +++ /dev/null @@ -1,32 +0,0 @@ -tests: - boards.nrf.i2s.i2s_divider: - tags: - - drivers - - i2s - harness: console - harness_config: - type: multi_line - ordered: true - regex: - - "test_i2s_frame_clk_freq_08000" - - "I2S MCK frequency: 256000, actual PCM rate: 8000" - - "test_i2s_frame_clk_freq_16000" - - "I2S MCK frequency: 507936, actual PCM rate: 15873" - - "test_i2s_frame_clk_freq_32000" - - "I2S MCK frequency: 1032258, actual PCM rate: 32258" - - "test_i2s_frame_clk_freq_44100" - - "I2S MCK frequency: 1391304, actual PCM rate: 43478" - - "test_i2s_frame_clk_freq_48000" - - "I2S MCK frequency: 1523809, actual PCM rate: 47619" - - "test_i2s_frame_clk_freq_88200" - - "I2S MCK frequency: 2909090, actual PCM rate: 90909" - - "test_i2s_frame_clk_freq_96000" - - "I2S MCK frequency: 3200000, actual PCM rate: 100000" - - "PROJECT EXECUTION SUCCESSFUL" - platform_allow: - - nrf52840dk/nrf52840 - - nrf5340dk/nrf5340/cpuapp - - nrf54l15dk/nrf54l15/cpuapp - integration_platforms: - - nrf52840dk/nrf52840 - - nrf54l15dk/nrf54l15/cpuapp From 12b2174e6647b87470104f14aec842f1b85fe7cf Mon Sep 17 00:00:00 2001 From: Ayush Singh Date: Mon, 15 Dec 2025 17:44:24 +0530 Subject: [PATCH 0537/3659] samples: net: mdns_responder: Add 802154-subg overlay - Tested on BeagleConnect Freedom Signed-off-by: Ayush Singh --- .../mdns_responder/overlay-802154-subg.conf | 18 ++++++++++++++++++ samples/net/mdns_responder/sample.yaml | 3 +++ 2 files changed, 21 insertions(+) create mode 100644 samples/net/mdns_responder/overlay-802154-subg.conf diff --git a/samples/net/mdns_responder/overlay-802154-subg.conf b/samples/net/mdns_responder/overlay-802154-subg.conf new file mode 100644 index 000000000000..cfa509d8cf42 --- /dev/null +++ b/samples/net/mdns_responder/overlay-802154-subg.conf @@ -0,0 +1,18 @@ +CONFIG_BT=n + +# Disable IPv4 +CONFIG_NET_IPV4=n + +CONFIG_NET_CONFIG_NEED_IPV6=y +CONFIG_NET_CONFIG_NEED_IPV4=n +CONFIG_NET_CONFIG_MY_IPV4_ADDR="" +CONFIG_NET_CONFIG_PEER_IPV4_ADDR="" + +CONFIG_NET_L2_IEEE802154=y +CONFIG_NET_L2_IEEE802154_SHELL=y +CONFIG_NET_L2_IEEE802154_LOG_LEVEL_INF=y + +# Uncomment for 868 MHz +#CONFIG_NET_CONFIG_IEEE802154_CHANNEL=0 +# Uncomment for 906 MHz: +CONFIG_NET_CONFIG_IEEE802154_CHANNEL=1 diff --git a/samples/net/mdns_responder/sample.yaml b/samples/net/mdns_responder/sample.yaml index 48ab0bf70506..5e2ee79d7d8c 100644 --- a/samples/net/mdns_responder/sample.yaml +++ b/samples/net/mdns_responder/sample.yaml @@ -26,3 +26,6 @@ tests: - CONFIG_BUILD_ONLY_NO_BLOBS=y platform_allow: - nrf7002dk/nrf5340/cpuapp + sample.net.mdns_responder.802154.subg: + extra_args: EXTRA_CONF_FILE="overlay-802154-subg.conf" + platform_allow: beagleconnect_freedom From c64de6f1de3e304386636d344fa530f64115ac17 Mon Sep 17 00:00:00 2001 From: Ayush Singh Date: Mon, 15 Dec 2025 17:49:22 +0530 Subject: [PATCH 0538/3659] samples: net: dns_resolve: Add 802154-subg support - Tested on BeagleConnect Freedom along with mdns_responder sample. Signed-off-by: Ayush Singh --- .../boards/beagleconnect_freedom.conf | 1 + .../net/dns_resolve/overlay-802154-subg.conf | 18 ++++++++++++++++++ samples/net/dns_resolve/sample.yaml | 3 +++ 3 files changed, 22 insertions(+) create mode 100644 samples/net/dns_resolve/boards/beagleconnect_freedom.conf create mode 100644 samples/net/dns_resolve/overlay-802154-subg.conf diff --git a/samples/net/dns_resolve/boards/beagleconnect_freedom.conf b/samples/net/dns_resolve/boards/beagleconnect_freedom.conf new file mode 100644 index 000000000000..2147f297cb2a --- /dev/null +++ b/samples/net/dns_resolve/boards/beagleconnect_freedom.conf @@ -0,0 +1 @@ +CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=1504 diff --git a/samples/net/dns_resolve/overlay-802154-subg.conf b/samples/net/dns_resolve/overlay-802154-subg.conf new file mode 100644 index 000000000000..cfa509d8cf42 --- /dev/null +++ b/samples/net/dns_resolve/overlay-802154-subg.conf @@ -0,0 +1,18 @@ +CONFIG_BT=n + +# Disable IPv4 +CONFIG_NET_IPV4=n + +CONFIG_NET_CONFIG_NEED_IPV6=y +CONFIG_NET_CONFIG_NEED_IPV4=n +CONFIG_NET_CONFIG_MY_IPV4_ADDR="" +CONFIG_NET_CONFIG_PEER_IPV4_ADDR="" + +CONFIG_NET_L2_IEEE802154=y +CONFIG_NET_L2_IEEE802154_SHELL=y +CONFIG_NET_L2_IEEE802154_LOG_LEVEL_INF=y + +# Uncomment for 868 MHz +#CONFIG_NET_CONFIG_IEEE802154_CHANNEL=0 +# Uncomment for 906 MHz: +CONFIG_NET_CONFIG_IEEE802154_CHANNEL=1 diff --git a/samples/net/dns_resolve/sample.yaml b/samples/net/dns_resolve/sample.yaml index f62c25fccc81..fc15c2c5ba15 100644 --- a/samples/net/dns_resolve/sample.yaml +++ b/samples/net/dns_resolve/sample.yaml @@ -26,3 +26,6 @@ tests: - CONFIG_BUILD_ONLY_NO_BLOBS=y platform_allow: - nrf7002dk/nrf5340/cpuapp + sample.net.dns_resolve.802154.subg: + extra_args: EXTRA_CONF_FILE="overlay-802154-subg.conf" + platform_allow: beagleconnect_freedom From 58212cd70e151686ac85eb65642a7f106b389b4a Mon Sep 17 00:00:00 2001 From: Thomas Hebb Date: Sun, 14 Dec 2025 01:17:00 -0500 Subject: [PATCH 0539/3659] drivers: wifi: airoc: Populate band in scan results The driver gives us this information, so we just need to translate it to Zephyr's type like we already do for security. Signed-off-by: Thomas Hebb --- drivers/wifi/infineon/airoc_wifi.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/drivers/wifi/infineon/airoc_wifi.c b/drivers/wifi/infineon/airoc_wifi.c index d11bd34e5fd9..be934c2fc068 100644 --- a/drivers/wifi/infineon/airoc_wifi.c +++ b/drivers/wifi/infineon/airoc_wifi.c @@ -231,12 +231,33 @@ static whd_security_t convert_zephyr_security_to_whd(int security) return whd_security; } +static uint8_t convert_whd_band_to_zephyr(whd_802_11_band_t band) +{ + uint8_t zephyr_band = WIFI_FREQ_BAND_UNKNOWN; + + switch (band) { + case WHD_802_11_BAND_2_4GHZ: + zephyr_band = WIFI_FREQ_BAND_2_4_GHZ; + break; + + case WHD_802_11_BAND_5GHZ: + zephyr_band = WIFI_FREQ_BAND_5_GHZ; + break; + + case WHD_802_11_BAND_6GHZ: + zephyr_band = WIFI_FREQ_BAND_6_GHZ; + break; + } + return zephyr_band; +} + static void parse_scan_result(whd_scan_result_t *p_whd_result, struct wifi_scan_result *p_zy_result) { if (p_whd_result->SSID.length != 0) { p_zy_result->ssid_length = p_whd_result->SSID.length; strncpy(p_zy_result->ssid, p_whd_result->SSID.value, p_whd_result->SSID.length); p_zy_result->channel = p_whd_result->channel; + p_zy_result->band = convert_whd_band_to_zephyr(p_whd_result->band); p_zy_result->security = convert_whd_security_to_zephyr(p_whd_result->security); p_zy_result->rssi = (int8_t)p_whd_result->signal_strength; p_zy_result->mac_length = 6; From 6d5754978c0353131f3da3a1b79c3582a682f5ce Mon Sep 17 00:00:00 2001 From: Sylvio Alves Date: Mon, 15 Dec 2025 13:42:29 -0300 Subject: [PATCH 0540/3659] drivers: flash: esp32: preserve volatile qualifier in IPM callback Preserve the volatile qualifier when casting the shared memory pointer in flash_cpu01_receive_cb() to avoid dropping volatile semantics during inter-processor communication. Signed-off-by: Sylvio Alves --- drivers/flash/flash_esp32.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/flash/flash_esp32.c b/drivers/flash/flash_esp32.c index d1f8ebde3f3f..6bb967a9272f 100644 --- a/drivers/flash/flash_esp32.c +++ b/drivers/flash/flash_esp32.c @@ -673,7 +673,7 @@ static void flash_cpu01_receive_cb(const struct device *ipm, void *user_data, ui volatile void *shm) { struct flash_esp32_dev_data *data = (struct flash_esp32_dev_data *) user_data; - struct flash_req *req = (struct flash_req *) shm; + volatile struct flash_req *req = (volatile struct flash_req *)shm; #ifdef CONFIG_ESP_FLASH_HOST if (id == CMD_REQUEST) { From f8d2e00a0ea263c0c224a093b7b8fa99ee71289c Mon Sep 17 00:00:00 2001 From: Sylvio Alves Date: Sat, 13 Dec 2025 22:53:40 -0300 Subject: [PATCH 0541/3659] includes: remove duplicated entries in zephyr-tree Remove duplicated #include directives within the same preprocessor scope across the Zephyr tree. Duplicates inside different #ifdef branches are preserved as they may be intentional. Signed-off-by: Sylvio Alves --- arch/x86/core/x86_mmu.c | 1 - arch/x86/include/ia32/kernel_arch_data.h | 1 - arch/xtensa/core/vector_handlers.c | 1 - drivers/adc/adc_stm32.c | 2 -- drivers/audio/tlv320aic3110.c | 1 - drivers/audio/tlv320dac310x.c | 1 - drivers/bluetooth/hci/hci_infineon_cyw208xx.c | 1 - drivers/bluetooth/hci/hci_infineon_psoc6_bless.c | 1 - drivers/counter/timer_dtmr_cmsdk_apb.c | 1 - drivers/dma/dma_bflb.c | 1 - drivers/ethernet/eth_adin2111.c | 2 -- drivers/ethernet/eth_lan865x.c | 2 -- drivers/flash/flash_esp32.c | 9 ++------- drivers/gnss/gnss_nmea0183.c | 1 - drivers/gpio/gpio_mcux_lpc.c | 3 --- drivers/gpio/gpio_rzt2m.c | 1 - drivers/gpio/gpio_sn74hc595.c | 1 - drivers/i2c/i2c_dw.c | 2 -- drivers/i2c/i2c_infineon.c | 1 - drivers/i2c/i2c_stm32_v2.c | 1 - drivers/i2s/i2s_mcux_sai.c | 1 - drivers/i2s/i2s_silabs_siwx91x.c | 1 - drivers/ieee802154/ieee802154_dw1000.c | 1 - drivers/ieee802154/ieee802154_esp32.c | 1 - drivers/ieee802154/ieee802154_mcr20a.c | 1 - drivers/ieee802154/ieee802154_nrf5.c | 1 - drivers/input/input_kbd_matrix.c | 1 - drivers/interrupt_controller/intc_arcv2_irq_unit.c | 1 - drivers/modem/modem_cellular.c | 1 - drivers/peci/peci_ite_it8xxx2.c | 1 - drivers/power_domain/power_domain_intel_adsp.c | 4 ---- drivers/sensor/adi/adxl345/adxl345.h | 1 - drivers/sensor/bosch/bmm150/bmm150.h | 3 --- drivers/sensor/bosch/bmm350/bmm350.h | 3 --- drivers/sensor/ist8310/ist8310.h | 1 - drivers/sensor/nxp/mcux_lpcmp/mcux_lpcmp.c | 1 - drivers/sensor/st/lis2dux12/lis2dux12_trigger.c | 1 - drivers/sensor/st/lis2dw12/lis2dw12.h | 1 - drivers/sensor/st/lsm6dso/lsm6dso.h | 1 - drivers/serial/uart_native_pty_bottom.c | 1 - drivers/spi/spi_max32.c | 1 - drivers/usb/device/usb_dc_mcux.c | 1 - drivers/usb/udc/udc_ambiq.c | 1 - drivers/usb/uhc/uhc_mcux_common.c | 1 - drivers/usb/uhc/uhc_mcux_ehci.c | 1 - drivers/usb/uhc/uhc_mcux_ip3516hs.c | 1 - drivers/usb/uhc/uhc_mcux_khci.c | 1 - drivers/usb/uhc/uhc_mcux_ohci.c | 1 - drivers/watchdog/wdt_gecko.c | 1 - drivers/wifi/eswifi/eswifi_core.c | 1 - drivers/wifi/nrf_wifi/src/fmac_main.c | 1 - drivers/wifi/winc1500/wifi_winc1500.c | 2 -- include/zephyr/arch/arm64/timer.h | 1 - include/zephyr/bluetooth/iso.h | 1 - include/zephyr/drivers/mic_privacy/intel/mic_privacy.h | 1 - lib/libc/minimal/source/string/strspn.c | 1 - .../platform/nrf_802154_spinel_backend_ipc.c | 4 ---- modules/hostap/src/supp_main.c | 1 - modules/openthread/platform/infra_if.c | 2 -- modules/openthread/platform/mdns_socket.c | 1 - samples/bluetooth/bap_unicast_client/src/stream_lc3.c | 1 - samples/bluetooth/bap_unicast_server/src/stream_lc3.c | 1 - samples/bluetooth/direction_finding_central/src/main.c | 1 - samples/bluetooth/hci_uart_async/src/hci_uart_async.c | 1 - samples/bluetooth/peripheral_csc/src/main.c | 1 - samples/boards/nordic/clock_control/src/main.c | 1 - samples/boards/renesas/comparator/src/main.c | 1 - samples/boards/renesas/lvd/src/main.c | 1 - .../renesas/openamp_linux_zephyr/src/main_remote.c | 1 - samples/drivers/clock_control_xec/src/main.c | 1 - samples/net/ethernet/dsa/src/dsa_lldp.c | 1 - samples/net/prometheus/src/main.c | 1 - samples/net/prometheus/src/stats.c | 1 - samples/net/sockets/echo_server/src/ws_console/ws.c | 1 - samples/sensor/grove_temperature/src/main.c | 1 - samples/sensor/stream_drdy/src/main.c | 1 - samples/subsys/ipc/openamp_rsc_table/src/main_remote.c | 1 - .../portability/cmsis_rtos_v1/philosophers/src/main.c | 1 - .../portability/cmsis_rtos_v2/philosophers/src/main.c | 1 - soc/infineon/cat1a/psoc6_legacy/soc.c | 1 - soc/intel/intel_adsp/cavs/power.c | 1 - soc/intel/intel_adsp/common/include/intel_adsp_hda.h | 1 - soc/microchip/mec/mec174x/soc.h | 1 - subsys/bluetooth/audio/bap_broadcast_sink.c | 1 - subsys/bluetooth/audio/cap_internal.h | 1 - subsys/bluetooth/audio/shell/csip_set_coordinator.c | 1 - subsys/bluetooth/controller/ll_sw/nordic/lll/lll_df.c | 1 - .../controller/ll_sw/nordic/lll/lll_peripheral.c | 1 - subsys/bluetooth/controller/ll_sw/ull_sync.c | 1 - subsys/bluetooth/services/ias/shell/ias.c | 1 - subsys/debug/gdbstub/gdbstub.c | 1 - subsys/debug/thread_analyzer/thread_analyzer.c | 1 - subsys/dfu/img_util/flash_img.c | 1 - subsys/fs/shell.c | 1 - subsys/logging/log_minimal.c | 1 - subsys/mgmt/mcumgr/grp/os_mgmt/src/os_mgmt.c | 2 -- subsys/net/ip/net_context.c | 4 ---- subsys/net/lib/shell/ppp.c | 1 - subsys/testsuite/ztest/src/ztest.c | 1 - subsys/usb/device_next/class/usbd_uvc.c | 2 -- tests/bluetooth/audio/cap_initiator/uut/csip.c | 3 --- tests/bluetooth/audio/mocks/include/conn.h | 1 - tests/bluetooth/audio/mocks/include/expects_util.h | 2 -- tests/bluetooth/audio/mocks/src/conn.c | 2 -- .../controller/ctrl_data_length_update/src/main.c | 1 - .../controller/ctrl_feature_exchange/src/main.c | 1 - .../controller/ctrl_feature_exchange/src/main_hci.c | 1 - tests/bluetooth/controller/ctrl_hci/src/main.c | 1 - tests/bluetooth/tester/src/audio/btp_bap_broadcast.c | 1 - tests/bluetooth/tester/src/audio/btp_mcp.c | 1 - tests/boards/native_sim/rtc/src/main.c | 1 - tests/bsim/bluetooth/audio/src/bap_broadcast_sink_test.c | 1 - tests/bsim/bluetooth/host/iso/frag_2/src/broadcaster.c | 1 - .../bluetooth/host/misc/conn_stress/central/src/main.c | 1 - .../host/misc/conn_stress/peripheral/src/main.c | 1 - tests/bsim/bluetooth/ll/bis/src/test_past.c | 3 --- tests/drivers/adc/adc_accuracy_test/src/dac_source.c | 1 - tests/net/shell/src/main.c | 1 - tests/net/udp/src/main.c | 1 - tests/subsys/fs/multi-fs/src/test_fat_mount.c | 1 - tests/unit/util/main.c | 1 - 121 files changed, 2 insertions(+), 156 deletions(-) diff --git a/arch/x86/core/x86_mmu.c b/arch/x86/core/x86_mmu.c index b2458d027674..9bece5dd9f5c 100644 --- a/arch/x86/core/x86_mmu.c +++ b/arch/x86/core/x86_mmu.c @@ -20,7 +20,6 @@ #include #include #include -#include #include LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL); diff --git a/arch/x86/include/ia32/kernel_arch_data.h b/arch/x86/include/ia32/kernel_arch_data.h index 97de17cc9d5b..1a57010917cf 100644 --- a/arch/x86/include/ia32/kernel_arch_data.h +++ b/arch/x86/include/ia32/kernel_arch_data.h @@ -53,7 +53,6 @@ #ifndef _ASMLANGUAGE -#include #ifdef __cplusplus extern "C" { diff --git a/arch/xtensa/core/vector_handlers.c b/arch/xtensa/core/vector_handlers.c index 0b66863ef59f..ba1a429373e3 100644 --- a/arch/xtensa/core/vector_handlers.c +++ b/arch/xtensa/core/vector_handlers.c @@ -16,7 +16,6 @@ #include #include -#include #include #include diff --git a/drivers/adc/adc_stm32.c b/drivers/adc/adc_stm32.c index 226acd3164fe..cd53b6e3339b 100644 --- a/drivers/adc/adc_stm32.c +++ b/drivers/adc/adc_stm32.c @@ -35,7 +35,6 @@ #ifdef CONFIG_ADC_STM32_DMA #include #include -#include #include #endif @@ -54,7 +53,6 @@ LOG_MODULE_REGISTER(adc_stm32); #if defined(CONFIG_SOC_SERIES_STM32H7X) || defined(CONFIG_SOC_SERIES_STM32H7RSX) #include -#include #endif #include diff --git a/drivers/audio/tlv320aic3110.c b/drivers/audio/tlv320aic3110.c index d51cd602e857..a494d3f93aea 100644 --- a/drivers/audio/tlv320aic3110.c +++ b/drivers/audio/tlv320aic3110.c @@ -13,7 +13,6 @@ #include #include -#include #include #include #include "tlv320aic3110.h" diff --git a/drivers/audio/tlv320dac310x.c b/drivers/audio/tlv320dac310x.c index 7821f5b54b5a..abf840b33cde 100644 --- a/drivers/audio/tlv320dac310x.c +++ b/drivers/audio/tlv320dac310x.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include "tlv320dac310x.h" diff --git a/drivers/bluetooth/hci/hci_infineon_cyw208xx.c b/drivers/bluetooth/hci/hci_infineon_cyw208xx.c index ac9c3fcf309c..43c588fca202 100644 --- a/drivers/bluetooth/hci/hci_infineon_cyw208xx.c +++ b/drivers/bluetooth/hci/hci_infineon_cyw208xx.c @@ -72,7 +72,6 @@ #include "cyhal_syspm.h" #define LOG_LEVEL CONFIG_BT_HCI_DRIVER_LOG_LEVEL -#include LOG_MODULE_REGISTER(cyw208xx); #define DT_DRV_COMPAT infineon_cyw208xx_hci diff --git a/drivers/bluetooth/hci/hci_infineon_psoc6_bless.c b/drivers/bluetooth/hci/hci_infineon_psoc6_bless.c index db042572b2f5..42800043f315 100644 --- a/drivers/bluetooth/hci/hci_infineon_psoc6_bless.c +++ b/drivers/bluetooth/hci/hci_infineon_psoc6_bless.c @@ -24,7 +24,6 @@ #include #define LOG_LEVEL CONFIG_BT_HCI_DRIVER_LOG_LEVEL -#include LOG_MODULE_REGISTER(psoc6_bless); #include "cy_ble_stack_pvt.h" diff --git a/drivers/counter/timer_dtmr_cmsdk_apb.c b/drivers/counter/timer_dtmr_cmsdk_apb.c index b5eab830dd07..1730c1ff3e76 100644 --- a/drivers/counter/timer_dtmr_cmsdk_apb.c +++ b/drivers/counter/timer_dtmr_cmsdk_apb.c @@ -15,7 +15,6 @@ #include #include #include -#include #include "dualtimer_cmsdk_apb.h" diff --git a/drivers/dma/dma_bflb.c b/drivers/dma/dma_bflb.c index a474ad969e2f..3f8c83e86140 100644 --- a/drivers/dma/dma_bflb.c +++ b/drivers/dma/dma_bflb.c @@ -14,7 +14,6 @@ #include LOG_MODULE_REGISTER(dma_bflb, CONFIG_DMA_LOG_LEVEL); -#include #include #include #include diff --git a/drivers/ethernet/eth_adin2111.c b/drivers/ethernet/eth_adin2111.c index da3ec1ffc22f..f778204c0891 100644 --- a/drivers/ethernet/eth_adin2111.c +++ b/drivers/ethernet/eth_adin2111.c @@ -18,8 +18,6 @@ LOG_MODULE_REGISTER(eth_adin2111, CONFIG_ETHERNET_LOG_LEVEL); #include #include -#include -#include #include #include "phy/phy_adin2111_priv.h" diff --git a/drivers/ethernet/eth_lan865x.c b/drivers/ethernet/eth_lan865x.c index 75c21efb0096..1d67f2125774 100644 --- a/drivers/ethernet/eth_lan865x.c +++ b/drivers/ethernet/eth_lan865x.c @@ -16,8 +16,6 @@ LOG_MODULE_REGISTER(eth_lan865x, CONFIG_ETHERNET_LOG_LEVEL); #include #include -#include -#include #include #include "eth_lan865x_priv.h" diff --git a/drivers/flash/flash_esp32.c b/drivers/flash/flash_esp32.c index 6bb967a9272f..f023bc3e516e 100644 --- a/drivers/flash/flash_esp32.c +++ b/drivers/flash/flash_esp32.c @@ -24,12 +24,13 @@ #include #include #include +#include #include #include #include +#include #include #include - #ifdef CONFIG_ESP_FLASH_ASYNC_IPM #include #endif @@ -131,12 +132,6 @@ static inline void flash_esp32_sem_give(const struct device *dev) #endif /* CONFIG_MULTITHREADING && !CONFIG_ESP_FLASH_ASYNC */ -#include -#include -#include -#include -#include - #ifdef CONFIG_ESP_FLASH_HOST #ifndef CONFIG_MCUBOOT static int flash_esp32_read_check_enc(off_t address, void *buffer, size_t length) diff --git a/drivers/gnss/gnss_nmea0183.c b/drivers/gnss/gnss_nmea0183.c index bbeb50a5c7de..3b084f1f4599 100644 --- a/drivers/gnss/gnss_nmea0183.c +++ b/drivers/gnss/gnss_nmea0183.c @@ -8,7 +8,6 @@ #include #include -#include #include "gnss_nmea0183.h" #include "gnss_parse.h" diff --git a/drivers/gpio/gpio_mcux_lpc.c b/drivers/gpio/gpio_mcux_lpc.c index 4d17eee0c681..9ebc9a474d90 100644 --- a/drivers/gpio/gpio_mcux_lpc.c +++ b/drivers/gpio/gpio_mcux_lpc.c @@ -28,9 +28,6 @@ #endif #include #include -#ifdef MCI_IO_MUX -#include -#endif /* Interrupt sources, matching int-source enum in DTS binding definition */ #define INT_SOURCE_PINT 0 diff --git a/drivers/gpio/gpio_rzt2m.c b/drivers/gpio/gpio_rzt2m.c index 2bb347db43b0..52a42ec5b959 100644 --- a/drivers/gpio/gpio_rzt2m.c +++ b/drivers/gpio/gpio_rzt2m.c @@ -14,7 +14,6 @@ #include #include #include -#include #include static const struct device *const ns_portnf_md_dev = DEVICE_DT_GET(DT_NODELABEL(ns_portnf_md)); diff --git a/drivers/gpio/gpio_sn74hc595.c b/drivers/gpio/gpio_sn74hc595.c index 5211e4e149a9..9c4b316b35c3 100644 --- a/drivers/gpio/gpio_sn74hc595.c +++ b/drivers/gpio/gpio_sn74hc595.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include diff --git a/drivers/i2c/i2c_dw.c b/drivers/i2c/i2c_dw.c index e39197d191c6..14f1ae98e039 100644 --- a/drivers/i2c/i2c_dw.c +++ b/drivers/i2c/i2c_dw.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include @@ -50,7 +49,6 @@ #include "i2c_dw_registers.h" #define LOG_LEVEL CONFIG_I2C_LOG_LEVEL #include -#include LOG_MODULE_REGISTER(i2c_dw); #include "i2c-priv.h" diff --git a/drivers/i2c/i2c_infineon.c b/drivers/i2c/i2c_infineon.c index a5a22da08e42..d72e1fdc37b6 100644 --- a/drivers/i2c/i2c_infineon.c +++ b/drivers/i2c/i2c_infineon.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include diff --git a/drivers/i2c/i2c_stm32_v2.c b/drivers/i2c/i2c_stm32_v2.c index 81ed208c754e..856755ab52be 100644 --- a/drivers/i2c/i2c_stm32_v2.c +++ b/drivers/i2c/i2c_stm32_v2.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/i2s/i2s_mcux_sai.c b/drivers/i2s/i2s_mcux_sai.c index 1873288b32be..de7765e023fa 100644 --- a/drivers/i2s/i2s_mcux_sai.c +++ b/drivers/i2s/i2s_mcux_sai.c @@ -26,7 +26,6 @@ #endif #include -#include #include #include diff --git a/drivers/i2s/i2s_silabs_siwx91x.c b/drivers/i2s/i2s_silabs_siwx91x.c index 323a82762f44..4e321cb12cb2 100644 --- a/drivers/i2s/i2s_silabs_siwx91x.c +++ b/drivers/i2s/i2s_silabs_siwx91x.c @@ -26,7 +26,6 @@ #include "rsi_power_save.h" #include "rsi_pll.h" #include "rsi_ulpss_clk.h" -#include "clock_update.h" #define DMA_MAX_TRANSFER_COUNT 1024 #define I2S_SIWX91X_UNSUPPORTED_OPTIONS \ diff --git a/drivers/ieee802154/ieee802154_dw1000.c b/drivers/ieee802154/ieee802154_dw1000.c index b68fdb1abc4f..c9520eb1e080 100644 --- a/drivers/ieee802154/ieee802154_dw1000.c +++ b/drivers/ieee802154/ieee802154_dw1000.c @@ -19,7 +19,6 @@ LOG_MODULE_REGISTER(dw1000, LOG_LEVEL_INF); #include #include #include -#include #include #include diff --git a/drivers/ieee802154/ieee802154_esp32.c b/drivers/ieee802154/ieee802154_esp32.c index 64546aa03997..b40ae5a16f43 100644 --- a/drivers/ieee802154/ieee802154_esp32.c +++ b/drivers/ieee802154/ieee802154_esp32.c @@ -26,7 +26,6 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #include #include -#include #include #include diff --git a/drivers/ieee802154/ieee802154_mcr20a.c b/drivers/ieee802154/ieee802154_mcr20a.c index 6e033d301b37..c72f4229c192 100644 --- a/drivers/ieee802154/ieee802154_mcr20a.c +++ b/drivers/ieee802154/ieee802154_mcr20a.c @@ -28,7 +28,6 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #include #include #include -#include #include diff --git a/drivers/ieee802154/ieee802154_nrf5.c b/drivers/ieee802154/ieee802154_nrf5.c index 0258adb88f21..911120d2783c 100644 --- a/drivers/ieee802154/ieee802154_nrf5.c +++ b/drivers/ieee802154/ieee802154_nrf5.c @@ -34,7 +34,6 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #include #include -#include #include #include diff --git a/drivers/input/input_kbd_matrix.c b/drivers/input/input_kbd_matrix.c index 7cd8badef3bb..30f170bbf57d 100644 --- a/drivers/input/input_kbd_matrix.c +++ b/drivers/input/input_kbd_matrix.c @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/interrupt_controller/intc_arcv2_irq_unit.c b/drivers/interrupt_controller/intc_arcv2_irq_unit.c index 8825e1a73458..5ad0ecf8f366 100644 --- a/drivers/interrupt_controller/intc_arcv2_irq_unit.c +++ b/drivers/interrupt_controller/intc_arcv2_irq_unit.c @@ -19,7 +19,6 @@ #include #include #include -#include #define DT_DRV_COMPAT snps_arcv2_intc diff --git a/drivers/modem/modem_cellular.c b/drivers/modem/modem_cellular.c index a166ecdfe058..28b698241219 100644 --- a/drivers/modem/modem_cellular.c +++ b/drivers/modem/modem_cellular.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include diff --git a/drivers/peci/peci_ite_it8xxx2.c b/drivers/peci/peci_ite_it8xxx2.c index ca34aaaa5742..c0e01ad0bfff 100644 --- a/drivers/peci/peci_ite_it8xxx2.c +++ b/drivers/peci/peci_ite_it8xxx2.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/power_domain/power_domain_intel_adsp.c b/drivers/power_domain/power_domain_intel_adsp.c index 71c0aff0e593..ec3f9328d8b5 100644 --- a/drivers/power_domain/power_domain_intel_adsp.c +++ b/drivers/power_domain/power_domain_intel_adsp.c @@ -10,10 +10,6 @@ #include #include -#if CONFIG_SOC_INTEL_ACE15_MTPM -#include -#endif /* CONFIG_SOC_INTEL_ACE15_MTPM */ - #include LOG_MODULE_REGISTER(power_domain_intel_adsp, LOG_LEVEL_INF); diff --git a/drivers/sensor/adi/adxl345/adxl345.h b/drivers/sensor/adi/adxl345/adxl345.h index 136217f28b2d..6c6293e8a649 100644 --- a/drivers/sensor/adi/adxl345/adxl345.h +++ b/drivers/sensor/adi/adxl345/adxl345.h @@ -28,7 +28,6 @@ #if DT_ANY_INST_ON_BUS_STATUS_OKAY(spi) #include #endif -#include /* ADXL345 communication commands */ #define ADXL345_WRITE_CMD 0x00 diff --git a/drivers/sensor/bosch/bmm150/bmm150.h b/drivers/sensor/bosch/bmm150/bmm150.h index c606d92a5796..1c192a0de19e 100644 --- a/drivers/sensor/bosch/bmm150/bmm150.h +++ b/drivers/sensor/bosch/bmm150/bmm150.h @@ -52,13 +52,10 @@ extern const struct bmm150_bus_io bmm150_bus_io_spi; extern const struct bmm150_bus_io bmm150_bus_io_i2c; #endif -#include -#include #include #include #include -#include #include #include #include diff --git a/drivers/sensor/bosch/bmm350/bmm350.h b/drivers/sensor/bosch/bmm350/bmm350.h index 1ac6f682fa55..5588deee141c 100644 --- a/drivers/sensor/bosch/bmm350/bmm350.h +++ b/drivers/sensor/bosch/bmm350/bmm350.h @@ -56,12 +56,9 @@ struct bmm350_bus_io { extern const struct bmm350_bus_io bmm350_bus_rtio; -#include -#include #include #include -#include #include #include #include diff --git a/drivers/sensor/ist8310/ist8310.h b/drivers/sensor/ist8310/ist8310.h index 289b51d84a7c..83cba0f6180f 100644 --- a/drivers/sensor/ist8310/ist8310.h +++ b/drivers/sensor/ist8310/ist8310.h @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/sensor/nxp/mcux_lpcmp/mcux_lpcmp.c b/drivers/sensor/nxp/mcux_lpcmp/mcux_lpcmp.c index f476405062ad..9e7698c9c3a1 100644 --- a/drivers/sensor/nxp/mcux_lpcmp/mcux_lpcmp.c +++ b/drivers/sensor/nxp/mcux_lpcmp/mcux_lpcmp.c @@ -15,7 +15,6 @@ #include #include #include -#include LOG_MODULE_REGISTER(mcux_lpcmp, CONFIG_SENSOR_LOG_LEVEL); diff --git a/drivers/sensor/st/lis2dux12/lis2dux12_trigger.c b/drivers/sensor/st/lis2dux12/lis2dux12_trigger.c index 2939d6332621..074fdf8bdda4 100644 --- a/drivers/sensor/st/lis2dux12/lis2dux12_trigger.c +++ b/drivers/sensor/st/lis2dux12/lis2dux12_trigger.c @@ -11,7 +11,6 @@ #include #include "lis2dux12.h" -#include "lis2dux12.h" #include "lis2dux12_rtio.h" LOG_MODULE_DECLARE(LIS2DUX12, CONFIG_SENSOR_LOG_LEVEL); diff --git a/drivers/sensor/st/lis2dw12/lis2dw12.h b/drivers/sensor/st/lis2dw12/lis2dw12.h index 6f9011a42317..895443445707 100644 --- a/drivers/sensor/st/lis2dw12/lis2dw12.h +++ b/drivers/sensor/st/lis2dw12/lis2dw12.h @@ -11,7 +11,6 @@ #ifndef ZEPHYR_DRIVERS_SENSOR_LIS2DW12_LIS2DW12_H_ #define ZEPHYR_DRIVERS_SENSOR_LIS2DW12_LIS2DW12_H_ -#include #include #include #include diff --git a/drivers/sensor/st/lsm6dso/lsm6dso.h b/drivers/sensor/st/lsm6dso/lsm6dso.h index 17fac4156c9f..d71d730cd548 100644 --- a/drivers/sensor/st/lsm6dso/lsm6dso.h +++ b/drivers/sensor/st/lsm6dso/lsm6dso.h @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include "lsm6dso_reg.h" diff --git a/drivers/serial/uart_native_pty_bottom.c b/drivers/serial/uart_native_pty_bottom.c index 6c2060ce9c60..3901eddb2944 100644 --- a/drivers/serial/uart_native_pty_bottom.c +++ b/drivers/serial/uart_native_pty_bottom.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #define ERROR nsi_print_error_and_exit diff --git a/drivers/spi/spi_max32.c b/drivers/spi/spi_max32.c index 5b553d901b67..43b64d320d82 100644 --- a/drivers/spi/spi_max32.c +++ b/drivers/spi/spi_max32.c @@ -20,7 +20,6 @@ #include #include #include -#include #include diff --git a/drivers/usb/device/usb_dc_mcux.c b/drivers/usb/device/usb_dc_mcux.c index fa11d7a0233f..1e50c061f3c8 100644 --- a/drivers/usb/device/usb_dc_mcux.c +++ b/drivers/usb/device/usb_dc_mcux.c @@ -9,7 +9,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/usb/udc/udc_ambiq.c b/drivers/usb/udc/udc_ambiq.c index 6c6ed46495ce..f98b62271f3b 100644 --- a/drivers/usb/udc/udc_ambiq.c +++ b/drivers/usb/udc/udc_ambiq.c @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/usb/uhc/uhc_mcux_common.c b/drivers/usb/uhc/uhc_mcux_common.c index d8e96d42d580..ff651721c78e 100644 --- a/drivers/usb/uhc/uhc_mcux_common.c +++ b/drivers/usb/uhc/uhc_mcux_common.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include "uhc_common.h" diff --git a/drivers/usb/uhc/uhc_mcux_ehci.c b/drivers/usb/uhc/uhc_mcux_ehci.c index 4ce0c8c2bf24..90ba04b6f6f5 100644 --- a/drivers/usb/uhc/uhc_mcux_ehci.c +++ b/drivers/usb/uhc/uhc_mcux_ehci.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include diff --git a/drivers/usb/uhc/uhc_mcux_ip3516hs.c b/drivers/usb/uhc/uhc_mcux_ip3516hs.c index eb261b8d0f7d..ac9f36c83a98 100644 --- a/drivers/usb/uhc/uhc_mcux_ip3516hs.c +++ b/drivers/usb/uhc/uhc_mcux_ip3516hs.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include diff --git a/drivers/usb/uhc/uhc_mcux_khci.c b/drivers/usb/uhc/uhc_mcux_khci.c index 7096e0a08549..3f840d64245f 100644 --- a/drivers/usb/uhc/uhc_mcux_khci.c +++ b/drivers/usb/uhc/uhc_mcux_khci.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include diff --git a/drivers/usb/uhc/uhc_mcux_ohci.c b/drivers/usb/uhc/uhc_mcux_ohci.c index a31a4c1c7a48..fad210bf91b8 100644 --- a/drivers/usb/uhc/uhc_mcux_ohci.c +++ b/drivers/usb/uhc/uhc_mcux_ohci.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include diff --git a/drivers/watchdog/wdt_gecko.c b/drivers/watchdog/wdt_gecko.c index f9f8f857f063..5a6e2c802958 100644 --- a/drivers/watchdog/wdt_gecko.c +++ b/drivers/watchdog/wdt_gecko.c @@ -14,7 +14,6 @@ #include #include -#include LOG_MODULE_REGISTER(wdt_gecko, CONFIG_WDT_LOG_LEVEL); #ifdef cmuClock_CORELE diff --git a/drivers/wifi/eswifi/eswifi_core.c b/drivers/wifi/eswifi/eswifi_core.c index 976037c19fe2..ddf32ab6f094 100644 --- a/drivers/wifi/eswifi/eswifi_core.c +++ b/drivers/wifi/eswifi/eswifi_core.c @@ -30,7 +30,6 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #include #include #include -#include #include #include diff --git a/drivers/wifi/nrf_wifi/src/fmac_main.c b/drivers/wifi/nrf_wifi/src/fmac_main.c index a113563cce16..e8e04f12d0cc 100644 --- a/drivers/wifi/nrf_wifi/src/fmac_main.c +++ b/drivers/wifi/nrf_wifi/src/fmac_main.c @@ -38,7 +38,6 @@ #endif /* CONFIG_NRF70_STA_MODE */ #include -#include #else #include #endif /* !CONFIG_NRF70_RADIO_TEST */ diff --git a/drivers/wifi/winc1500/wifi_winc1500.c b/drivers/wifi/winc1500/wifi_winc1500.c index 806391d1e586..a6d9bafd6ce5 100644 --- a/drivers/wifi/winc1500/wifi_winc1500.c +++ b/drivers/wifi/winc1500/wifi_winc1500.c @@ -108,8 +108,6 @@ typedef struct { struct sockaddr_in strRemoteAddr; } tstrSocketRecvMsg; -#include -#include #if defined(CONFIG_WIFI_WINC1500_REGION_NORTH_AMERICA) #define WINC1500_REGION NORTH_AMERICA diff --git a/include/zephyr/arch/arm64/timer.h b/include/zephyr/arch/arm64/timer.h index 0973e327dfc7..eadf6f181511 100644 --- a/include/zephyr/arch/arm64/timer.h +++ b/include/zephyr/arch/arm64/timer.h @@ -13,7 +13,6 @@ #include #include -#include #ifdef __cplusplus extern "C" { diff --git a/include/zephyr/bluetooth/iso.h b/include/zephyr/bluetooth/iso.h index 631d48b0c3de..f5e0182f2d66 100644 --- a/include/zephyr/bluetooth/iso.h +++ b/include/zephyr/bluetooth/iso.h @@ -35,7 +35,6 @@ #include #include #include -#include #ifdef __cplusplus extern "C" { diff --git a/include/zephyr/drivers/mic_privacy/intel/mic_privacy.h b/include/zephyr/drivers/mic_privacy/intel/mic_privacy.h index 950add9bab37..33fbee53ad88 100644 --- a/include/zephyr/drivers/mic_privacy/intel/mic_privacy.h +++ b/include/zephyr/drivers/mic_privacy/intel/mic_privacy.h @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include diff --git a/lib/libc/minimal/source/string/strspn.c b/lib/libc/minimal/source/string/strspn.c index 3af7d542a7bc..c627948b130b 100644 --- a/lib/libc/minimal/source/string/strspn.c +++ b/lib/libc/minimal/source/string/strspn.c @@ -5,7 +5,6 @@ */ #include -#include size_t strspn(const char *s, const char *accept) diff --git a/modules/hal_nordic/nrf_802154/serialization/platform/nrf_802154_spinel_backend_ipc.c b/modules/hal_nordic/nrf_802154/serialization/platform/nrf_802154_spinel_backend_ipc.c index 9071b57c5165..148bf60c2201 100644 --- a/modules/hal_nordic/nrf_802154/serialization/platform/nrf_802154_spinel_backend_ipc.c +++ b/modules/hal_nordic/nrf_802154/serialization/platform/nrf_802154_spinel_backend_ipc.c @@ -20,10 +20,6 @@ #include "../../spinel_base/spinel.h" #include "../../src/include/nrf_802154_spinel.h" -#if defined(CONFIG_SOC_NRF5340_CPUAPP) -#include -#endif - #define LOG_LEVEL LOG_LEVEL_INFO #define LOG_MODULE_NAME spinel_ipc_backend LOG_MODULE_REGISTER(LOG_MODULE_NAME); diff --git a/modules/hostap/src/supp_main.c b/modules/hostap/src/supp_main.c index d1f8c360cb50..37c4128a2bcc 100644 --- a/modules/hostap/src/supp_main.c +++ b/modules/hostap/src/supp_main.c @@ -43,7 +43,6 @@ static K_THREAD_STACK_DEFINE(iface_wq_stack, CONFIG_WIFI_NM_WPA_SUPPLICANT_WQ_ST #include "wpa_supplicant/config.h" #include "wpa_supplicant_i.h" #include "fst/fst.h" -#include "includes.h" #include "wpa_cli_zephyr.h" #include "ctrl_iface_zephyr.h" #ifdef CONFIG_WIFI_NM_HOSTAPD_AP diff --git a/modules/openthread/platform/infra_if.c b/modules/openthread/platform/infra_if.c index 58189e8ba9a9..dfebd3a1499f 100644 --- a/modules/openthread/platform/infra_if.c +++ b/modules/openthread/platform/infra_if.c @@ -21,11 +21,9 @@ #include #include #include -#include #include #if defined(CONFIG_OPENTHREAD_NAT64_TRANSLATOR) -#include #include #include #endif /* CONFIG_OPENTHREAD_NAT64_TRANSLATOR */ diff --git a/modules/openthread/platform/mdns_socket.c b/modules/openthread/platform/mdns_socket.c index f6ace92c4200..f2e95ad90a13 100644 --- a/modules/openthread/platform/mdns_socket.c +++ b/modules/openthread/platform/mdns_socket.c @@ -19,7 +19,6 @@ #include #include #include -#include #include "sockets_internal.h" #include diff --git a/samples/bluetooth/bap_unicast_client/src/stream_lc3.c b/samples/bluetooth/bap_unicast_client/src/stream_lc3.c index c87764a58d51..2f0e3e718a2b 100644 --- a/samples/bluetooth/bap_unicast_client/src/stream_lc3.c +++ b/samples/bluetooth/bap_unicast_client/src/stream_lc3.c @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ #include -#include #include #include #include diff --git a/samples/bluetooth/bap_unicast_server/src/stream_lc3.c b/samples/bluetooth/bap_unicast_server/src/stream_lc3.c index c87764a58d51..2f0e3e718a2b 100644 --- a/samples/bluetooth/bap_unicast_server/src/stream_lc3.c +++ b/samples/bluetooth/bap_unicast_server/src/stream_lc3.c @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ #include -#include #include #include #include diff --git a/samples/bluetooth/direction_finding_central/src/main.c b/samples/bluetooth/direction_finding_central/src/main.c index 45e31add8fd3..c4caffedbba3 100644 --- a/samples/bluetooth/direction_finding_central/src/main.c +++ b/samples/bluetooth/direction_finding_central/src/main.c @@ -17,7 +17,6 @@ #include #include #include -#include #include /* Latency set to zero, to enforce PDU exchange every connection event */ 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 bdefdb3c1698..be490e6f44c7 100644 --- a/samples/bluetooth/hci_uart_async/src/hci_uart_async.c +++ b/samples/bluetooth/hci_uart_async/src/hci_uart_async.c @@ -10,7 +10,6 @@ #include #include -#include #include #include #include diff --git a/samples/bluetooth/peripheral_csc/src/main.c b/samples/bluetooth/peripheral_csc/src/main.c index 5090641433da..60d0faaf0594 100644 --- a/samples/bluetooth/peripheral_csc/src/main.c +++ b/samples/bluetooth/peripheral_csc/src/main.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #define CSC_SUPPORTED_LOCATIONS { CSC_LOC_OTHER, \ diff --git a/samples/boards/nordic/clock_control/src/main.c b/samples/boards/nordic/clock_control/src/main.c index d2823db92ac4..bf74dbf66c5a 100644 --- a/samples/boards/nordic/clock_control/src/main.c +++ b/samples/boards/nordic/clock_control/src/main.c @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include #include #include diff --git a/samples/boards/renesas/comparator/src/main.c b/samples/boards/renesas/comparator/src/main.c index 053280da0e4a..37c635944fac 100644 --- a/samples/boards/renesas/comparator/src/main.c +++ b/samples/boards/renesas/comparator/src/main.c @@ -8,7 +8,6 @@ #include #include #include -#include #include #include #ifdef CONFIG_DAC_REFERENCE_SOURCE diff --git a/samples/boards/renesas/lvd/src/main.c b/samples/boards/renesas/lvd/src/main.c index 14572b96663d..80592911bf87 100644 --- a/samples/boards/renesas/lvd/src/main.c +++ b/samples/boards/renesas/lvd/src/main.c @@ -8,7 +8,6 @@ #include #include #include -#include #include #include diff --git a/samples/boards/renesas/openamp_linux_zephyr/src/main_remote.c b/samples/boards/renesas/openamp_linux_zephyr/src/main_remote.c index 7baf58760532..5a931dcb1ed0 100644 --- a/samples/boards/renesas/openamp_linux_zephyr/src/main_remote.c +++ b/samples/boards/renesas/openamp_linux_zephyr/src/main_remote.c @@ -9,7 +9,6 @@ #include #include #include -#include #include diff --git a/samples/drivers/clock_control_xec/src/main.c b/samples/drivers/clock_control_xec/src/main.c index 21d598fa5016..e9a8183ad538 100644 --- a/samples/drivers/clock_control_xec/src/main.c +++ b/samples/drivers/clock_control_xec/src/main.c @@ -15,7 +15,6 @@ #include LOG_MODULE_REGISTER(clock32k, CONFIG_CLOCK_CONTROL_LOG_LEVEL); -#include #ifdef CONFIG_SOC_SERIES_MEC15XX static void pcr_clock_regs(void) diff --git a/samples/net/ethernet/dsa/src/dsa_lldp.c b/samples/net/ethernet/dsa/src/dsa_lldp.c index 8cb05b136b47..1336cc59ff68 100644 --- a/samples/net/ethernet/dsa/src/dsa_lldp.c +++ b/samples/net/ethernet/dsa/src/dsa_lldp.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include diff --git a/samples/net/prometheus/src/main.c b/samples/net/prometheus/src/main.c index f4380ef45bed..735522d46b35 100644 --- a/samples/net/prometheus/src/main.c +++ b/samples/net/prometheus/src/main.c @@ -6,7 +6,6 @@ #include #include -#include #include #include #include diff --git a/samples/net/prometheus/src/stats.c b/samples/net/prometheus/src/stats.c index ffc47a952da6..0028ebd1fafb 100644 --- a/samples/net/prometheus/src/stats.c +++ b/samples/net/prometheus/src/stats.c @@ -7,7 +7,6 @@ #include LOG_MODULE_DECLARE(main, LOG_LEVEL_DBG); -#include #include #include #include diff --git a/samples/net/sockets/echo_server/src/ws_console/ws.c b/samples/net/sockets/echo_server/src/ws_console/ws.c index 8a2b898f7b90..a64d070a6e82 100644 --- a/samples/net/sockets/echo_server/src/ws_console/ws.c +++ b/samples/net/sockets/echo_server/src/ws_console/ws.c @@ -54,7 +54,6 @@ struct http_resource_detail_static favicon_16x16_png_gz_resource_detail = { }; #if defined(CONFIG_NET_SAMPLE_HTTPS_SERVICE) -#include #include "../certificate.h" static const sec_tag_t sec_tag_list_verify_none[] = { diff --git a/samples/sensor/grove_temperature/src/main.c b/samples/sensor/grove_temperature/src/main.c index c49137f60184..c0f3a7c336e1 100644 --- a/samples/sensor/grove_temperature/src/main.c +++ b/samples/sensor/grove_temperature/src/main.c @@ -11,7 +11,6 @@ #ifdef CONFIG_GROVE_LCD_RGB #include -#include #include #endif diff --git a/samples/sensor/stream_drdy/src/main.c b/samples/sensor/stream_drdy/src/main.c index d46048981f58..dcc835409a8d 100644 --- a/samples/sensor/stream_drdy/src/main.c +++ b/samples/sensor/stream_drdy/src/main.c @@ -12,7 +12,6 @@ #include #include #include -#include #define STREAMDEV_ALIAS(i) DT_ALIAS(_CONCAT(stream, i)) #define STREAMDEV_DEVICE(i, _) \ diff --git a/samples/subsys/ipc/openamp_rsc_table/src/main_remote.c b/samples/subsys/ipc/openamp_rsc_table/src/main_remote.c index 27c8402868ce..51de537ee2e1 100644 --- a/samples/subsys/ipc/openamp_rsc_table/src/main_remote.c +++ b/samples/subsys/ipc/openamp_rsc_table/src/main_remote.c @@ -9,7 +9,6 @@ #include #include #include -#include #include diff --git a/samples/subsys/portability/cmsis_rtos_v1/philosophers/src/main.c b/samples/subsys/portability/cmsis_rtos_v1/philosophers/src/main.c index e031028a671d..59199850464c 100644 --- a/samples/subsys/portability/cmsis_rtos_v1/philosophers/src/main.c +++ b/samples/subsys/portability/cmsis_rtos_v1/philosophers/src/main.c @@ -85,7 +85,6 @@ osSemaphoreId forks[NUM_PHIL]; #define PR_DEBUG(...) #endif -#include "phil_obj_abstract.h" static void set_phil_state_pos(int id) { diff --git a/samples/subsys/portability/cmsis_rtos_v2/philosophers/src/main.c b/samples/subsys/portability/cmsis_rtos_v2/philosophers/src/main.c index bb9250ebe357..5f2ec91b10e8 100644 --- a/samples/subsys/portability/cmsis_rtos_v2/philosophers/src/main.c +++ b/samples/subsys/portability/cmsis_rtos_v2/philosophers/src/main.c @@ -115,7 +115,6 @@ static osThreadAttr_t thread_attr[] = { #define PR_DEBUG(...) #endif -#include "phil_obj_abstract.h" static void set_phil_state_pos(int id) { diff --git a/soc/infineon/cat1a/psoc6_legacy/soc.c b/soc/infineon/cat1a/psoc6_legacy/soc.c index 8a5dd3470d0a..71dc7cd2ce21 100644 --- a/soc/infineon/cat1a/psoc6_legacy/soc.c +++ b/soc/infineon/cat1a/psoc6_legacy/soc.c @@ -12,7 +12,6 @@ #include "cy_syslib.h" #include "cy_gpio.h" #include "cy_scb_uart.h" -#include "cy_syslib.h" #include "cy_syspm.h" #include "cy_sysclk.h" diff --git a/soc/intel/intel_adsp/cavs/power.c b/soc/intel/intel_adsp/cavs/power.c index 26d65dd12cf1..5e5db3620cc1 100644 --- a/soc/intel/intel_adsp/cavs/power.c +++ b/soc/intel/intel_adsp/cavs/power.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include diff --git a/soc/intel/intel_adsp/common/include/intel_adsp_hda.h b/soc/intel/intel_adsp/common/include/intel_adsp_hda.h index 277cf4d34301..755de3c77d3b 100644 --- a/soc/intel/intel_adsp/common/include/intel_adsp_hda.h +++ b/soc/intel/intel_adsp/common/include/intel_adsp_hda.h @@ -11,7 +11,6 @@ #include #include #include -#include /** * @brief HDA stream functionality for Intel ADSP diff --git a/soc/microchip/mec/mec174x/soc.h b/soc/microchip/mec/mec174x/soc.h index 226a3ba85fdb..1a29328c2c77 100644 --- a/soc/microchip/mec/mec174x/soc.h +++ b/soc/microchip/mec/mec174x/soc.h @@ -39,7 +39,6 @@ #include #include -#include #endif #endif diff --git a/subsys/bluetooth/audio/bap_broadcast_sink.c b/subsys/bluetooth/audio/bap_broadcast_sink.c index 8eec57f6f6a8..be4b1aebeeb0 100644 --- a/subsys/bluetooth/audio/bap_broadcast_sink.c +++ b/subsys/bluetooth/audio/bap_broadcast_sink.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include #include diff --git a/subsys/bluetooth/audio/cap_internal.h b/subsys/bluetooth/audio/cap_internal.h index 2aade46edd63..3cbbcc602414 100644 --- a/subsys/bluetooth/audio/cap_internal.h +++ b/subsys/bluetooth/audio/cap_internal.h @@ -9,7 +9,6 @@ #include #include #include -#include #include #include diff --git a/subsys/bluetooth/audio/shell/csip_set_coordinator.c b/subsys/bluetooth/audio/shell/csip_set_coordinator.c index 72baa43d6a87..d8174791e502 100644 --- a/subsys/bluetooth/audio/shell/csip_set_coordinator.c +++ b/subsys/bluetooth/audio/shell/csip_set_coordinator.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include "host/shell/bt.h" diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_df.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_df.c index a9a575a32306..a24ed4c7103c 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_df.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_df.c @@ -30,7 +30,6 @@ #include "lll_df.h" #include "lll_df_internal.h" -#include #include "hal/debug.h" /* Minimum number of antenna switch patterns required by Direction Finding Extension to be diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral.c index a25265400db8..6222d523c29c 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral.c @@ -18,7 +18,6 @@ #include "util/util.h" #include "util/memq.h" #include "util/dbuf.h" -#include "util/util.h" #include "pdu_df.h" #include "pdu_vendor.h" diff --git a/subsys/bluetooth/controller/ll_sw/ull_sync.c b/subsys/bluetooth/controller/ll_sw/ull_sync.c index 183e8bc72bfb..dbca3e77c7a4 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_sync.c +++ b/subsys/bluetooth/controller/ll_sw/ull_sync.c @@ -65,7 +65,6 @@ #include "ull_llcp.h" #include "ll.h" -#include #include "hal/debug.h" /* Check that timeout_reload member is at safe offset when ll_sync_set is diff --git a/subsys/bluetooth/services/ias/shell/ias.c b/subsys/bluetooth/services/ias/shell/ias.c index 8da9818e4744..186a833b01d1 100644 --- a/subsys/bluetooth/services/ias/shell/ias.c +++ b/subsys/bluetooth/services/ias/shell/ias.c @@ -11,7 +11,6 @@ #include #include -#include #include #include #include diff --git a/subsys/debug/gdbstub/gdbstub.c b/subsys/debug/gdbstub/gdbstub.c index 2bd2819ec5ad..af29df25c27e 100644 --- a/subsys/debug/gdbstub/gdbstub.c +++ b/subsys/debug/gdbstub/gdbstub.c @@ -19,7 +19,6 @@ LOG_MODULE_REGISTER(gdbstub); #include #include #include -#include #include #include "gdbstub_backend.h" diff --git a/subsys/debug/thread_analyzer/thread_analyzer.c b/subsys/debug/thread_analyzer/thread_analyzer.c index 817bbb72f81d..611eb50c7f3d 100644 --- a/subsys/debug/thread_analyzer/thread_analyzer.c +++ b/subsys/debug/thread_analyzer/thread_analyzer.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include diff --git a/subsys/dfu/img_util/flash_img.c b/subsys/dfu/img_util/flash_img.c index d3c9749401b2..8c597b77129a 100644 --- a/subsys/dfu/img_util/flash_img.c +++ b/subsys/dfu/img_util/flash_img.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include diff --git a/subsys/fs/shell.c b/subsys/fs/shell.c index a591a96bb571..ebd33c2b7219 100644 --- a/subsys/fs/shell.c +++ b/subsys/fs/shell.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include diff --git a/subsys/logging/log_minimal.c b/subsys/logging/log_minimal.c index 1340cf59c270..ff07e92080cc 100644 --- a/subsys/logging/log_minimal.c +++ b/subsys/logging/log_minimal.c @@ -7,7 +7,6 @@ #include #include #include -#include #include #define HEXDUMP_BYTES_IN_LINE 8U diff --git a/subsys/mgmt/mcumgr/grp/os_mgmt/src/os_mgmt.c b/subsys/mgmt/mcumgr/grp/os_mgmt/src/os_mgmt.c index a175cdf78fe1..23862cf7aa88 100644 --- a/subsys/mgmt/mcumgr/grp/os_mgmt/src/os_mgmt.c +++ b/subsys/mgmt/mcumgr/grp/os_mgmt/src/os_mgmt.c @@ -45,7 +45,6 @@ #endif #if defined(CONFIG_MCUMGR_GRP_OS_INFO) || defined(CONFIG_MCUMGR_GRP_OS_BOOTLOADER_INFO) -#include #include #if defined(CONFIG_MCUMGR_GRP_OS_INFO) #include @@ -53,7 +52,6 @@ #if defined(CONFIG_MCUMGR_GRP_OS_BOOTLOADER_INFO) #include #endif -#include #if defined(CONFIG_NET_HOSTNAME_ENABLE) #include #elif defined(CONFIG_BT) diff --git a/subsys/net/ip/net_context.c b/subsys/net/ip/net_context.c index 80f468dae5ab..260b6dcbd62c 100644 --- a/subsys/net/ip/net_context.c +++ b/subsys/net/ip/net_context.c @@ -41,10 +41,6 @@ LOG_MODULE_REGISTER(net_ctx, CONFIG_NET_CONTEXT_LOG_LEVEL); #include "net_stats.h" #include "pmtu.h" -#if defined(CONFIG_NET_TCP) -#include "tcp_internal.h" -#endif - #ifdef CONFIG_NET_INITIAL_MCAST_TTL #define INITIAL_MCAST_TTL CONFIG_NET_INITIAL_MCAST_TTL #else diff --git a/subsys/net/lib/shell/ppp.c b/subsys/net/lib/shell/ppp.c index f63c6ca33241..15b03a8dd165 100644 --- a/subsys/net/lib/shell/ppp.c +++ b/subsys/net/lib/shell/ppp.c @@ -13,7 +13,6 @@ LOG_MODULE_DECLARE(net_shell); #include "net_shell_private.h" #if defined(CONFIG_NET_L2_PPP) -#include #include "ppp/ppp_internal.h" #endif diff --git a/subsys/testsuite/ztest/src/ztest.c b/subsys/testsuite/ztest/src/ztest.c index 28653d06aebb..af18f9ea1166 100644 --- a/subsys/testsuite/ztest/src/ztest.c +++ b/subsys/testsuite/ztest/src/ztest.c @@ -409,7 +409,6 @@ void ztest_skip_failed_assumption(void) */ #include /* parasoft-suppress MISRAC2012-RULE_21_4-a MISRAC2012-RULE_21_4-b*/ #include -#include #include #define FAIL_FAST 0 diff --git a/subsys/usb/device_next/class/usbd_uvc.c b/subsys/usb/device_next/class/usbd_uvc.c index 91e19c003141..a6772f6aafad 100644 --- a/subsys/usb/device_next/class/usbd_uvc.c +++ b/subsys/usb/device_next/class/usbd_uvc.c @@ -20,9 +20,7 @@ #include #include -#include #include -#include #include #include "usbd_uvc.h" diff --git a/tests/bluetooth/audio/cap_initiator/uut/csip.c b/tests/bluetooth/audio/cap_initiator/uut/csip.c index 45e1940b8812..17c753c2ac0e 100644 --- a/tests/bluetooth/audio/cap_initiator/uut/csip.c +++ b/tests/bluetooth/audio/cap_initiator/uut/csip.c @@ -9,9 +9,6 @@ #include #include -#include -#include -#include #include #include diff --git a/tests/bluetooth/audio/mocks/include/conn.h b/tests/bluetooth/audio/mocks/include/conn.h index 16814160d8f3..69126bfe8cac 100644 --- a/tests/bluetooth/audio/mocks/include/conn.h +++ b/tests/bluetooth/audio/mocks/include/conn.h @@ -9,7 +9,6 @@ #define MOCKS_CONN_H_ #include -#include #include #include diff --git a/tests/bluetooth/audio/mocks/include/expects_util.h b/tests/bluetooth/audio/mocks/include/expects_util.h index 978baa25e814..5079996d3f5b 100644 --- a/tests/bluetooth/audio/mocks/include/expects_util.h +++ b/tests/bluetooth/audio/mocks/include/expects_util.h @@ -9,12 +9,10 @@ #include #include -#include #include #include #include -#include #include #include diff --git a/tests/bluetooth/audio/mocks/src/conn.c b/tests/bluetooth/audio/mocks/src/conn.c index abfd4912e0f9..eb9ebdf84424 100644 --- a/tests/bluetooth/audio/mocks/src/conn.c +++ b/tests/bluetooth/audio/mocks/src/conn.c @@ -4,13 +4,11 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include #include #include #include #include - #include #include #include diff --git a/tests/bluetooth/controller/ctrl_data_length_update/src/main.c b/tests/bluetooth/controller/ctrl_data_length_update/src/main.c index 1aae721539c7..c0e6a60133ad 100644 --- a/tests/bluetooth/controller/ctrl_data_length_update/src/main.c +++ b/tests/bluetooth/controller/ctrl_data_length_update/src/main.c @@ -11,7 +11,6 @@ #define ULL_LLCP_UNITTEST #include -#include #include #include #include "hal/ccm.h" diff --git a/tests/bluetooth/controller/ctrl_feature_exchange/src/main.c b/tests/bluetooth/controller/ctrl_feature_exchange/src/main.c index b1aec894edd4..e50279df5d9c 100644 --- a/tests/bluetooth/controller/ctrl_feature_exchange/src/main.c +++ b/tests/bluetooth/controller/ctrl_feature_exchange/src/main.c @@ -11,7 +11,6 @@ #define ULL_LLCP_UNITTEST #include -#include #include #include #include "hal/ccm.h" diff --git a/tests/bluetooth/controller/ctrl_feature_exchange/src/main_hci.c b/tests/bluetooth/controller/ctrl_feature_exchange/src/main_hci.c index d717d6f651f1..459422621521 100644 --- a/tests/bluetooth/controller/ctrl_feature_exchange/src/main_hci.c +++ b/tests/bluetooth/controller/ctrl_feature_exchange/src/main_hci.c @@ -11,7 +11,6 @@ #define ULL_LLCP_UNITTEST #include -#include #include #include #include "hal/ccm.h" diff --git a/tests/bluetooth/controller/ctrl_hci/src/main.c b/tests/bluetooth/controller/ctrl_hci/src/main.c index fe38eb3d0174..8aaa89a2e3e9 100644 --- a/tests/bluetooth/controller/ctrl_hci/src/main.c +++ b/tests/bluetooth/controller/ctrl_hci/src/main.c @@ -11,7 +11,6 @@ #define ULL_LLCP_UNITTEST #include -#include #include #include #include "hal/ccm.h" diff --git a/tests/bluetooth/tester/src/audio/btp_bap_broadcast.c b/tests/bluetooth/tester/src/audio/btp_bap_broadcast.c index ec5125522bd0..b2222be38c3a 100644 --- a/tests/bluetooth/tester/src/audio/btp_bap_broadcast.c +++ b/tests/bluetooth/tester/src/audio/btp_bap_broadcast.c @@ -36,7 +36,6 @@ #include "btp_bap_audio_stream.h" #include "bap_endpoint.h" #include "btp/btp.h" -#include "btp_bap_audio_stream.h" #include "btp_bap_broadcast.h" #define LOG_MODULE_NAME bttester_bap_broadcast diff --git a/tests/bluetooth/tester/src/audio/btp_mcp.c b/tests/bluetooth/tester/src/audio/btp_mcp.c index f2559b5824d3..46e367c07a18 100644 --- a/tests/bluetooth/tester/src/audio/btp_mcp.c +++ b/tests/bluetooth/tester/src/audio/btp_mcp.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include diff --git a/tests/boards/native_sim/rtc/src/main.c b/tests/boards/native_sim/rtc/src/main.c index 261778148682..c79982519a0f 100644 --- a/tests/boards/native_sim/rtc/src/main.c +++ b/tests/boards/native_sim/rtc/src/main.c @@ -16,7 +16,6 @@ #include #include "native_rtc.h" -#include static char *us_time_to_str(char *dest, uint64_t time) { diff --git a/tests/bsim/bluetooth/audio/src/bap_broadcast_sink_test.c b/tests/bsim/bluetooth/audio/src/bap_broadcast_sink_test.c index d7cb7867bf69..0b1c5fc275c2 100644 --- a/tests/bsim/bluetooth/audio/src/bap_broadcast_sink_test.c +++ b/tests/bsim/bluetooth/audio/src/bap_broadcast_sink_test.c @@ -10,7 +10,6 @@ #include #include -#include #include #include #include diff --git a/tests/bsim/bluetooth/host/iso/frag_2/src/broadcaster.c b/tests/bsim/bluetooth/host/iso/frag_2/src/broadcaster.c index 34d30251a379..ded36483b370 100644 --- a/tests/bsim/bluetooth/host/iso/frag_2/src/broadcaster.c +++ b/tests/bsim/bluetooth/host/iso/frag_2/src/broadcaster.c @@ -5,7 +5,6 @@ */ #include -#include #include #include #include diff --git a/tests/bsim/bluetooth/host/misc/conn_stress/central/src/main.c b/tests/bsim/bluetooth/host/misc/conn_stress/central/src/main.c index 6140084b1a5b..8f2cbdd43034 100644 --- a/tests/bsim/bluetooth/host/misc/conn_stress/central/src/main.c +++ b/tests/bsim/bluetooth/host/misc/conn_stress/central/src/main.c @@ -27,7 +27,6 @@ LOG_MODULE_REGISTER(central, LOG_LEVEL_INF); #include "bstests.h" #include "bs_types.h" #include "bs_tracing.h" -#include "bstests.h" #include "bs_pc_backchannel.h" #include "babblekit/testcase.h" diff --git a/tests/bsim/bluetooth/host/misc/conn_stress/peripheral/src/main.c b/tests/bsim/bluetooth/host/misc/conn_stress/peripheral/src/main.c index f88caf2d00ae..2ec1a3ecb141 100644 --- a/tests/bsim/bluetooth/host/misc/conn_stress/peripheral/src/main.c +++ b/tests/bsim/bluetooth/host/misc/conn_stress/peripheral/src/main.c @@ -29,7 +29,6 @@ LOG_MODULE_REGISTER(peripheral, LOG_LEVEL_INF); #include "bstests.h" #include "bs_types.h" #include "bs_tracing.h" -#include "bstests.h" #include "bs_pc_backchannel.h" #include "argparse.h" diff --git a/tests/bsim/bluetooth/ll/bis/src/test_past.c b/tests/bsim/bluetooth/ll/bis/src/test_past.c index 9103bdceddc7..fe46881efd34 100644 --- a/tests/bsim/bluetooth/ll/bis/src/test_past.c +++ b/tests/bsim/bluetooth/ll/bis/src/test_past.c @@ -10,18 +10,15 @@ #include #include #include -#include #include #include #include #include #include -#include #include #include #include -#include #include "subsys/bluetooth/host/hci_core.h" #include "subsys/bluetooth/controller/include/ll.h" diff --git a/tests/drivers/adc/adc_accuracy_test/src/dac_source.c b/tests/drivers/adc/adc_accuracy_test/src/dac_source.c index a4063d095c7b..83afc3dadb0a 100644 --- a/tests/drivers/adc/adc_accuracy_test/src/dac_source.c +++ b/tests/drivers/adc/adc_accuracy_test/src/dac_source.c @@ -6,7 +6,6 @@ #include #include -#include #include #define DIV 2 diff --git a/tests/net/shell/src/main.c b/tests/net/shell/src/main.c index 2f052652c750..ebf1dad3b34f 100644 --- a/tests/net/shell/src/main.c +++ b/tests/net/shell/src/main.c @@ -48,7 +48,6 @@ LOG_MODULE_REGISTER(net_test, NET_LOG_LEVEL); #define NET_LOG_ENABLED 1 #endif #include "net_private.h" -#include "ipv4.h" static bool test_failed; static struct k_sem recv_lock; diff --git a/tests/net/udp/src/main.c b/tests/net/udp/src/main.c index 6d0a48bedcba..b855e6fcd3d2 100644 --- a/tests/net/udp/src/main.c +++ b/tests/net/udp/src/main.c @@ -48,7 +48,6 @@ LOG_MODULE_REGISTER(net_test, NET_LOG_LEVEL); #define NET_LOG_ENABLED 1 #endif #include "net_private.h" -#include "ipv4.h" static bool test_failed; static bool fail = true; diff --git a/tests/subsys/fs/multi-fs/src/test_fat_mount.c b/tests/subsys/fs/multi-fs/src/test_fat_mount.c index 1042ac4c321c..6fdf4a94ba4c 100644 --- a/tests/subsys/fs/multi-fs/src/test_fat_mount.c +++ b/tests/subsys/fs/multi-fs/src/test_fat_mount.c @@ -8,7 +8,6 @@ #include #include "test_common.h" #include "test_fs_shell.h" -#include "test_fat.h" #include "test_fat_priv.h" /* for mount using FS api */ diff --git a/tests/unit/util/main.c b/tests/unit/util/main.c index 33822b811447..231f3e3c442a 100644 --- a/tests/unit/util/main.c +++ b/tests/unit/util/main.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include From b96c49d737f6bf1678edab755ccafb550a5f5a01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Fri, 12 Dec 2025 16:43:21 +0100 Subject: [PATCH 0542/3659] doc: hardware: scmi: fix formatting of SCMI docs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix incorrect indentation that caused some elements to render as defintion lists. Added proper nesting of the various headings as everything was top-level Signed-off-by: Benjamin Cabé --- doc/hardware/arch/arm-scmi.rst | 153 +++++++++++++++++---------------- 1 file changed, 79 insertions(+), 74 deletions(-) diff --git a/doc/hardware/arch/arm-scmi.rst b/doc/hardware/arch/arm-scmi.rst index 1055f5d6b896..6f2b92de112c 100644 --- a/doc/hardware/arch/arm-scmi.rst +++ b/doc/hardware/arch/arm-scmi.rst @@ -7,7 +7,7 @@ Overview ******** What is SCMI? -************* +============= System Control and Management Interface (SCMI) is a specification developed by ARM, which describes a set of OS-agnostic software interfaces used to perform @@ -15,52 +15,53 @@ system management (e.g: clock control, pinctrl, etc...). Agent, platform, protocol and transport -*************************************** +======================================= The SCMI specification defines **four** key terms, which will also be used throughout this documentation: - #. Agent - Entity that performs SCMI requests (e.g: gating a clock or configuring - a pin). In this context, Zephyr itself is an agent. - #. Platform - This refers to a set of hardware components that handle the requests from - agents and provide the necessary functionality. In some cases, the requests - are handled by a firmware, running on a core dedicated to performing system - management tasks. - #. Protocol - A protocol is a set of messages grouped by functionality. Intuitively, a message - can be thought of as a remote procedure call. - - The SCMI specification defines ten standard protocols: - - #. **Base** (0x10) - #. **Power domain management** (0x11) - #. **System power management** (0x12) - #. **Performance domain management** (0x13) - #. **Clock management** (0x14) - #. **Sensor management** (0x15) - #. **Reset domain management** (0x16) - #. **Voltage domain management** (0x17) - #. **Power capping and monitoring** (0x18) - #. **Pin Control** (0x19) - - where each of these protocols is identified by an unique protocol ID - (listed between brackets). - - Apart from the standard protocols, the SCMI specification reserves the - **0x80-0xFF** protocol ID range for vendor-specific protocols. - - - #. Transport - This describes how messages are exchanged between agents and the platform. - The communication itself happens through channels. +#. Agent + Entity that performs SCMI requests (e.g: gating a clock or configuring + a pin). In this context, Zephyr itself is an agent. + +#. Platform + This refers to a set of hardware components that handle the requests from + agents and provide the necessary functionality. In some cases, the requests + are handled by a firmware, running on a core dedicated to performing system + management tasks. + +#. Protocol + A protocol is a set of messages grouped by functionality. Intuitively, a message + can be thought of as a remote procedure call. + + The SCMI specification defines ten standard protocols: + + #. **Base** (0x10) + #. **Power domain management** (0x11) + #. **System power management** (0x12) + #. **Performance domain management** (0x13) + #. **Clock management** (0x14) + #. **Sensor management** (0x15) + #. **Reset domain management** (0x16) + #. **Voltage domain management** (0x17) + #. **Power capping and monitoring** (0x18) + #. **Pin Control** (0x19) + + where each of these protocols is identified by an unique protocol ID + (listed between brackets). + + Apart from the standard protocols, the SCMI specification reserves the + **0x80-0xFF** protocol ID range for vendor-specific protocols. + +#. Transport + This describes how messages are exchanged between agents and the platform. + The communication itself happens through channels. .. note:: A system may have more than one agent. Channels -******** +======== A **channel** is the medium through which agents and the platform exchange messages. The structure of a channel and the way it works is solely dependent on the transport. @@ -71,31 +72,34 @@ by two different agents for example. Channels are **bidirectional** (exception: FastChannels), and, depending on which entity initiates the communication, can be one of **two** types: - #. A2P (agent to platform) - The agent is the initiator/requester. The messages passed through these - channels are known as **commands**. - #. P2A (platform to agent) - The platform is the initiator/requester. +#. A2P (agent to platform) + The agent is the initiator/requester. The messages passed through these + channels are known as **commands**. + +#. P2A (platform to agent) + The platform is the initiator/requester. Messages -******** +======== The SCMI specification defines **four** types of messages: - #. Synchronous - These are commands that block until the platform has completed the - requested work and are sent over A2P channels. - #. Asynchronous - For these commands, the platform schedules the requested work to - be performed at a later time. As such, they return almost immediately. - These commands are sent over A2P channels. - #. Delayed response - These messages indicate the completion of the work associated - with an asynchronous command. These are sent over P2A channels. - - #. Notification - These messages are used to notify agents of events that take place on - the platform. These are sent over P2A channels. +#. Synchronous + These are commands that block until the platform has completed the + requested work and are sent over A2P channels. + +#. Asynchronous + For these commands, the platform schedules the requested work to + be performed at a later time. As such, they return almost immediately. + These commands are sent over A2P channels. + +#. Delayed response + These messages indicate the completion of the work associated + with an asynchronous command. These are sent over P2A channels. + +#. Notification + These messages are used to notify agents of events that take place on + the platform. These are sent over P2A channels. The Zephyr support for SCMI is based on the documentation provided by ARM: `DEN0056E `_. For more details @@ -105,7 +109,7 @@ SCMI support in Zephyr ********************** Shared memory and doorbell-based transport -****************************************** +========================================== This form of transport uses shared memory for reading/writing messages and doorbells for signaling. The interaction with the shared @@ -120,10 +124,10 @@ transport driver (:file:`drivers/firmware/scmi/mailbox.c`). The steps below exemplify how the communication between the Zephyr agent and the platform may happen using this transport: - #. Write message to the shared memory area. - #. Zephyr rings request doorbell. If in ``PRE_KERNEL_1`` or ``PRE_KERNEL_2`` phase start polling for reply, otherwise wait for reply doorbell ring. - #. Platform reads message from shared memory area, processes it, writes the reply back to the same area and rings the reply doorbell. - #. Zephyr reads reply from the shared memory area. +#. Write message to the shared memory area. +#. Zephyr rings request doorbell. If in ``PRE_KERNEL_1`` or ``PRE_KERNEL_2`` phase start polling for reply, otherwise wait for reply doorbell ring. +#. Platform reads message from shared memory area, processes it, writes the reply back to the same area and rings the reply doorbell. +#. Zephyr reads reply from the shared memory area. In the context of this transport, a channel is comprised of a **single** shared memory area and one or more mailbox channels. This is because users may need/want @@ -131,19 +135,20 @@ to use different mailbox channels for the request/reply doorbells. Protocols -********* +========= Currently, Zephyr has support for the following standard protocols: - #. **Power domain management** - #. **Clock management** - #. **Pin Control** +#. **Power domain management** +#. **Clock management** +#. **Pin Control** NXP-specific protocols: - #. **CPU domain management** + +#. **CPU domain management** Power domain management -*********************** +----------------------- This protocol is intended for management of power states of power domains. This is done via a set of functions implementing various commands, for @@ -153,8 +158,8 @@ example, ``POWER_STATE_GET`` and ``POWER_STATE_SET``. This driver is vendor-agnostic. As such, it may be used on any system that uses SCMI for power domain management operations. -Clock management protocol -************************* +Clock management +---------------- This protocol is used to perform clock management operations. This is done via a driver (:file:`drivers/clock_control/clock_control_arm_scmi.c`), which @@ -166,8 +171,8 @@ management driver. This driver is vendor-agnostic. As such, it may be used on any system that uses SCMI for clock management operations. -Pin Control protocol -******************** +Pin Control +----------- This protocol is used to perform pin configuration operations. This is done via a set of functions implementing various commands. Currently, the only @@ -181,7 +186,7 @@ supported command is ``PINCTRL_SETTINGS_CONFIGURE``. ``PINCTRL_SETTINGS_CONFIGURE`` command. NXP - CPU domain management -*************************** +--------------------------- This protocol is intended for management of cpu states. This is done via a set of functions implementing various commands, for From 008116935940401aa00106e7db7eae186cf19790 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Mon, 15 Dec 2025 16:13:01 +0100 Subject: [PATCH 0543/3659] doc: hardware: scmi: add System power management as supported protocol MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is an implementation of the System power management protocol in the SCMI driver, so mention it. Signed-off-by: Benjamin Cabé --- doc/hardware/arch/arm-scmi.rst | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/doc/hardware/arch/arm-scmi.rst b/doc/hardware/arch/arm-scmi.rst index 6f2b92de112c..8b217494fe80 100644 --- a/doc/hardware/arch/arm-scmi.rst +++ b/doc/hardware/arch/arm-scmi.rst @@ -140,6 +140,7 @@ Protocols Currently, Zephyr has support for the following standard protocols: #. **Power domain management** +#. **System power management** #. **Clock management** #. **Pin Control** @@ -158,6 +159,16 @@ example, ``POWER_STATE_GET`` and ``POWER_STATE_SET``. This driver is vendor-agnostic. As such, it may be used on any system that uses SCMI for power domain management operations. +System power management +----------------------- + +This protocol is intended for system power management. This is done via a set +of functions implementing various commands, for example, ``SYSTEM_POWER_STATE_SET``. + +.. note:: + This driver is vendor-agnostic. As such, it may be used on any + system that uses SCMI for system power management operations. + Clock management ---------------- From 66d6edaf5cc80341852bce1597c8f0314ca37ed5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Mon, 15 Dec 2025 16:22:55 +0100 Subject: [PATCH 0544/3659] include: firmware: scmi: add proper doxygen groups for SCMI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This adds proper doxygen groups for all public SCMI headers Signed-off-by: Benjamin Cabé --- doc/hardware/arch/arm-scmi.rst | 6 ++++++ include/zephyr/drivers/firmware/scmi/clk.h | 14 ++++++++++++- .../zephyr/drivers/firmware/scmi/pinctrl.h | 14 ++++++++++++- include/zephyr/drivers/firmware/scmi/power.h | 14 ++++++++++++- .../zephyr/drivers/firmware/scmi/protocol.h | 20 ++++++++++++++++++- include/zephyr/drivers/firmware/scmi/shmem.h | 14 ++++++++++++- include/zephyr/drivers/firmware/scmi/system.h | 14 ++++++++++++- .../zephyr/drivers/firmware/scmi/transport.h | 14 ++++++++++++- include/zephyr/drivers/firmware/scmi/util.h | 14 ++++++++++++- 9 files changed, 116 insertions(+), 8 deletions(-) diff --git a/doc/hardware/arch/arm-scmi.rst b/doc/hardware/arch/arm-scmi.rst index 8b217494fe80..41ceebd46528 100644 --- a/doc/hardware/arch/arm-scmi.rst +++ b/doc/hardware/arch/arm-scmi.rst @@ -159,6 +159,8 @@ example, ``POWER_STATE_GET`` and ``POWER_STATE_SET``. This driver is vendor-agnostic. As such, it may be used on any system that uses SCMI for power domain management operations. +.. doxygengroup:: scmi_power + System power management ----------------------- @@ -169,6 +171,8 @@ of functions implementing various commands, for example, ``SYSTEM_POWER_STATE_SE This driver is vendor-agnostic. As such, it may be used on any system that uses SCMI for system power management operations. +.. doxygengroup:: scmi_system + Clock management ---------------- @@ -196,6 +200,8 @@ supported command is ``PINCTRL_SETTINGS_CONFIGURE``. call into the SCMI pin control protocol function implementing the ``PINCTRL_SETTINGS_CONFIGURE`` command. +.. doxygengroup:: scmi_pinctrl + NXP - CPU domain management --------------------------- diff --git a/include/zephyr/drivers/firmware/scmi/clk.h b/include/zephyr/drivers/firmware/scmi/clk.h index c3b511c4f517..2554a9f2ac50 100644 --- a/include/zephyr/drivers/firmware/scmi/clk.h +++ b/include/zephyr/drivers/firmware/scmi/clk.h @@ -6,7 +6,8 @@ /** * @file - * @brief SCMI clock protocol helpers + * @ingroup scmi_clk + * @brief Header file for the SCMI Clock Protocol. */ #ifndef _INCLUDE_ZEPHYR_DRIVERS_FIRMWARE_SCMI_CLK_H_ @@ -14,6 +15,13 @@ #include +/** + * @brief Clock management operations via SCMI + * @defgroup scmi_clk Clock Protocol + * @ingroup scmi_protocols + * @{ + */ + #define SCMI_CLK_CONFIG_DISABLE_ENABLE_MASK GENMASK(1, 0) #define SCMI_CLK_CONFIG_ENABLE_DISABLE(x)\ ((uint32_t)(x) & SCMI_CLK_CONFIG_DISABLE_ENABLE_MASK) @@ -149,4 +157,8 @@ int scmi_clock_parent_get(struct scmi_protocol *proto, uint32_t clk_id, uint32_t */ int scmi_clock_parent_set(struct scmi_protocol *proto, uint32_t clk_id, uint32_t parent_id); +/** + * @} + */ + #endif /* _INCLUDE_ZEPHYR_DRIVERS_FIRMWARE_SCMI_CLK_H_ */ diff --git a/include/zephyr/drivers/firmware/scmi/pinctrl.h b/include/zephyr/drivers/firmware/scmi/pinctrl.h index cb6a39a765e2..7e5d6b22d95e 100644 --- a/include/zephyr/drivers/firmware/scmi/pinctrl.h +++ b/include/zephyr/drivers/firmware/scmi/pinctrl.h @@ -6,7 +6,8 @@ /** * @file - * @brief SCMI pinctrl protocol helpers + * @ingroup scmi_pinctrl + * @brief Header file for the SCMI Pin Control Protocol. */ #ifndef _INCLUDE_ZEPHYR_DRIVERS_FIRMWARE_SCMI_PINCTRL_H_ @@ -14,6 +15,13 @@ #include +/** + * @brief Pin configuration and control via SCMI + * @defgroup scmi_pinctrl Pin Control Protocol + * @ingroup scmi_protocols + * @{ + */ + #define ARM_SCMI_PINCTRL_MAX_CONFIG_SIZE (10 * 2) #define SCMI_PINCTRL_NO_FUNCTION 0xFFFFFFFF @@ -102,4 +110,8 @@ struct scmi_pinctrl_settings { */ int scmi_pinctrl_settings_configure(struct scmi_pinctrl_settings *settings); +/** + * @} + */ + #endif /* _INCLUDE_ZEPHYR_DRIVERS_FIRMWARE_SCMI_PINCTRL_H_ */ diff --git a/include/zephyr/drivers/firmware/scmi/power.h b/include/zephyr/drivers/firmware/scmi/power.h index 7545da9ef968..2b8c76655c59 100644 --- a/include/zephyr/drivers/firmware/scmi/power.h +++ b/include/zephyr/drivers/firmware/scmi/power.h @@ -6,7 +6,8 @@ /** * @file - * @brief SCMI power domain protocol helpers + * @ingroup scmi_power + * @brief Header file for the SCMI Power Domain Protocol. */ #ifndef _INCLUDE_ZEPHYR_DRIVERS_FIRMWARE_SCMI_POWER_H_ @@ -14,6 +15,13 @@ #include +/** + * @brief Power domain state management via SCMI + * @defgroup scmi_power Power Domain Protocol + * @ingroup scmi_protocols + * @{ + */ + #define SCMI_POWER_STATE_SET_FLAGS_ASYNC BIT(0) #define SCMI_POWER_DOMAIN_PROTOCOL_SUPPORTED_VERSION 0x30001 @@ -103,4 +111,8 @@ int scmi_power_state_set(struct scmi_power_state_config *cfg); */ int scmi_power_state_get(uint32_t domain_id, uint32_t *power_state); +/** + * @} + */ + #endif /* _INCLUDE_ZEPHYR_DRIVERS_FIRMWARE_SCMI_POWER_H_ */ diff --git a/include/zephyr/drivers/firmware/scmi/protocol.h b/include/zephyr/drivers/firmware/scmi/protocol.h index a03d8cf493f8..dff3febef608 100644 --- a/include/zephyr/drivers/firmware/scmi/protocol.h +++ b/include/zephyr/drivers/firmware/scmi/protocol.h @@ -6,12 +6,20 @@ /** * @file - * @brief SCMI protocol generic functions and structures + * @ingroup scmi_interface + * @brief Header file for the SCMI (System Control and Management Interface) driver API. */ #ifndef _INCLUDE_ZEPHYR_DRIVERS_FIRMWARE_SCMI_PROTOCOL_H_ #define _INCLUDE_ZEPHYR_DRIVERS_FIRMWARE_SCMI_PROTOCOL_H_ +/** + * @brief Interfaces for ARM System Control and Management Interface (SCMI) + * @defgroup scmi_interface SCMI + * @ingroup io_interfaces + * @{ + */ + #include #include #include @@ -184,4 +192,14 @@ int scmi_protocol_message_attributes_get(struct scmi_protocol *proto, */ int scmi_protocol_version_negotiate(struct scmi_protocol *proto, uint32_t version); +/** + * @} + */ + +/** + * @brief Standard SCMI Protocol definitions + * @defgroup scmi_protocols Protocols + * @ingroup scmi_interface + */ + #endif /* _INCLUDE_ZEPHYR_DRIVERS_FIRMWARE_SCMI_PROTOCOL_H_ */ diff --git a/include/zephyr/drivers/firmware/scmi/shmem.h b/include/zephyr/drivers/firmware/scmi/shmem.h index 662bf7933735..ec984a47bd77 100644 --- a/include/zephyr/drivers/firmware/scmi/shmem.h +++ b/include/zephyr/drivers/firmware/scmi/shmem.h @@ -6,7 +6,8 @@ /** * @file - * @brief SCMI SHMEM API + * @ingroup scmi_shmem + * @brief Header file for the SCMI Shared Memory. */ #ifndef _INCLUDE_ZEPHYR_DRIVERS_FIRMWARE_SCMI_SHMEM_H_ @@ -16,6 +17,13 @@ #include #include +/** + * @brief Shared memory transport definitions for SCMI + * @defgroup scmi_shmem Shared Memory + * @ingroup scmi_transport + * @{ + */ + #define SCMI_SHMEM_CHAN_STATUS_BUSY_BIT BIT(0) #define SCMI_SHMEM_CHAN_FLAG_IRQ_BIT BIT(0) @@ -93,4 +101,8 @@ int scmi_shmem_vendor_write_message(struct scmi_shmem_layout *layout); */ int scmi_shmem_vendor_read_message(const struct scmi_shmem_layout *layout); +/** + * @} + */ + #endif /* _INCLUDE_ZEPHYR_DRIVERS_FIRMWARE_SCMI_SHMEM_H_ */ diff --git a/include/zephyr/drivers/firmware/scmi/system.h b/include/zephyr/drivers/firmware/scmi/system.h index b947d89b3607..c8c44189f9fc 100644 --- a/include/zephyr/drivers/firmware/scmi/system.h +++ b/include/zephyr/drivers/firmware/scmi/system.h @@ -9,13 +9,21 @@ /** * @file - * @brief SCMI System Power Management Protocol + * @ingroup scmi_system + * @brief Header file for the SCMI System Power Management Protocol. */ #include #include #include +/** + * @brief System-wide power state management via SCMI + * @defgroup scmi_system System Power Protocol + * @ingroup scmi_protocols + * @{ + */ + #ifdef __cplusplus extern "C" { #endif @@ -150,4 +158,8 @@ int scmi_system_power_state_set(struct scmi_system_power_state_config *cfg); } #endif +/** + * @} + */ + #endif /* ZEPHYR_INCLUDE_DRIVERS_FIRMWARE_SCMI_SYSTEM_H_ */ diff --git a/include/zephyr/drivers/firmware/scmi/transport.h b/include/zephyr/drivers/firmware/scmi/transport.h index 2cb72a2b9042..773b1e7d478f 100644 --- a/include/zephyr/drivers/firmware/scmi/transport.h +++ b/include/zephyr/drivers/firmware/scmi/transport.h @@ -6,7 +6,8 @@ /** * @file - * @brief Public APIs for the SCMI transport layer drivers + * @ingroup scmi_transport + * @brief Header file for the SCMI Transport Layer. */ #ifndef _INCLUDE_ZEPHYR_DRIVERS_FIRMWARE_SCMI_TRANSPORT_H_ @@ -15,6 +16,13 @@ #include #include +/** + * @brief SCMI Transport Layer abstraction and definitions + * @defgroup scmi_transport Transport + * @ingroup scmi_interface + * @{ + */ + struct scmi_message; struct scmi_channel; @@ -271,4 +279,8 @@ static inline bool scmi_transport_channel_is_free(const struct device *transport */ int scmi_core_transport_init(const struct device *transport); +/** + * @} + */ + #endif /* _INCLUDE_ZEPHYR_DRIVERS_FIRMWARE_SCMI_TRANSPORT_H_ */ diff --git a/include/zephyr/drivers/firmware/scmi/util.h b/include/zephyr/drivers/firmware/scmi/util.h index 55bceeaaf904..56b6d3cbc69a 100644 --- a/include/zephyr/drivers/firmware/scmi/util.h +++ b/include/zephyr/drivers/firmware/scmi/util.h @@ -6,7 +6,8 @@ /** * @file - * @brief ARM SCMI utility header + * @ingroup scmi_util + * @brief Header file for SCMI Utility Macros. * * Contains various utility macros and macros used for protocol and * transport "registration". @@ -15,6 +16,13 @@ #ifndef _INCLUDE_ZEPHYR_DRIVERS_FIRMWARE_SCMI_UTIL_H_ #define _INCLUDE_ZEPHYR_DRIVERS_FIRMWARE_SCMI_UTIL_H_ +/** + * @brief Helper macros and utilities for SCMI drivers + * @defgroup scmi_util Utilities + * @ingroup scmi_interface + * @{ + */ + /** * @brief Build protocol name from its ID * @@ -286,4 +294,8 @@ #define SCMI_PROTOCOL_PCAP_MONITOR 24 #define SCMI_PROTOCOL_PINCTRL 25 +/** + * @} + */ + #endif /* _INCLUDE_ZEPHYR_DRIVERS_FIRMWARE_SCMI_UTIL_H_ */ From 4c983d00f6c3e7bd99bc1be5a6e81270ee67030f Mon Sep 17 00:00:00 2001 From: Charles Hardin Date: Thu, 11 Dec 2025 14:45:00 -0800 Subject: [PATCH 0545/3659] drivers: ethernet: lan9250: cleanup some un-needed code From the prior change b38a46badea27f66bba4e6b8923d6a812c14f74e adding in the mac configuration in the device tree it is appropriate to remove the local mac address bindings. This is done in this commit. There is no intended functional change Signed-off-by: Charles Hardin --- drivers/ethernet/eth_lan9250.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/ethernet/eth_lan9250.c b/drivers/ethernet/eth_lan9250.c index 339cf794ad93..c5f22edbad23 100644 --- a/drivers/ethernet/eth_lan9250.c +++ b/drivers/ethernet/eth_lan9250.c @@ -744,7 +744,6 @@ static int lan9250_init(const struct device *dev) #define LAN9250_DEFINE(inst) \ static struct lan9250_runtime lan9250_##inst##_runtime = { \ - .mac_address = DT_INST_PROP_OR(inst, local_mac_address, {0}), \ .tx_rx_sem = Z_SEM_INITIALIZER(lan9250_##inst##_runtime.tx_rx_sem, 1, UINT_MAX), \ .int_sem = Z_SEM_INITIALIZER(lan9250_##inst##_runtime.int_sem, 0, UINT_MAX), \ }; \ From 1a738a56c58d142ddb4395c192096afd71392eb7 Mon Sep 17 00:00:00 2001 From: Charles Hardin Date: Thu, 11 Dec 2025 16:10:20 -0800 Subject: [PATCH 0546/3659] drivers: ethernet: w5500: update the driver to use mac config bindings Since the w5500 is used in arduino shields it should use the current code patterns since it will be examined as a reference for other drivers. So, this is just trying to catch up to the changes that have been made in the microchip, litex, and virtio drivers. Use the net_eth_mac_load code pattern from those other drivers and update a few things to the code guidelines as well. Signed-off-by: Charles Hardin --- drivers/ethernet/eth_w5500.c | 48 +++++++++++++++++++------------ drivers/ethernet/eth_w5500_priv.h | 1 + 2 files changed, 30 insertions(+), 19 deletions(-) diff --git a/drivers/ethernet/eth_w5500.c b/drivers/ethernet/eth_w5500.c index 0b3febde9bf9..9a87a0a70c73 100644 --- a/drivers/ethernet/eth_w5500.c +++ b/drivers/ethernet/eth_w5500.c @@ -501,10 +501,6 @@ static void w5500_set_macaddr(const struct device *dev) { struct w5500_runtime *ctx = dev->data; -#if DT_INST_PROP(0, zephyr_random_mac_address) - gen_random_mac(ctx->mac_addr, WIZNET_OUI_B0, WIZNET_OUI_B1, WIZNET_OUI_B2); -#endif - w5500_spi_write(dev, W5500_SHAR, ctx->mac_addr, sizeof(ctx->mac_addr)); } @@ -543,40 +539,56 @@ static int w5500_init(const struct device *dev) return -EINVAL; } - if (gpio_pin_configure_dt(&config->interrupt, GPIO_INPUT)) { + err = gpio_pin_configure_dt(&config->interrupt, GPIO_INPUT); + if (err < 0) { LOG_ERR("Unable to configure GPIO pin %u", config->interrupt.pin); - return -EINVAL; + return err; } gpio_init_callback(&(ctx->gpio_cb), w5500_gpio_callback, BIT(config->interrupt.pin)); - - if (gpio_add_callback(config->interrupt.port, &(ctx->gpio_cb))) { - return -EINVAL; + err = gpio_add_callback(config->interrupt.port, &(ctx->gpio_cb)); + if (err < 0) { + LOG_ERR("Unable to add GPIO callback %u", config->interrupt.pin); + return err; } - gpio_pin_interrupt_configure_dt(&config->interrupt, - GPIO_INT_EDGE_FALLING); + err = gpio_pin_interrupt_configure_dt(&config->interrupt, + GPIO_INT_EDGE_FALLING); + if (err < 0) { + LOG_ERR("Unable to enable GPIO INT %u", config->interrupt.pin); + return err; + } - if (config->reset.port) { + if (config->reset.port != NULL) { if (!gpio_is_ready_dt(&config->reset)) { LOG_ERR("GPIO port %s not ready", config->reset.port->name); return -EINVAL; } - if (gpio_pin_configure_dt(&config->reset, GPIO_OUTPUT)) { + + err = gpio_pin_configure_dt(&config->reset, GPIO_OUTPUT_INACTIVE); + if (err < 0) { LOG_ERR("Unable to configure GPIO pin %u", config->reset.pin); - return -EINVAL; + return err; } - gpio_pin_set_dt(&config->reset, 0); + + /* See Section 5.5.1 of the W5500 datasheet + * Trc = 500us + * Tpl = 1ms + */ + gpio_pin_set_dt(&config->reset, 1); k_usleep(500); + gpio_pin_set_dt(&config->reset, 0); + k_msleep(1); } err = w5500_soft_reset(dev); - if (err) { + if (err != 0) { LOG_ERR("Reset failed"); return err; } + (void)net_eth_mac_load(&config->mac_cfg, ctx->mac_addr); w5500_set_macaddr(dev); w5500_memory_configure(dev); @@ -601,9 +613,6 @@ static int w5500_init(const struct device *dev) } static struct w5500_runtime w5500_0_runtime = { -#if NODE_HAS_VALID_MAC_ADDR(DT_DRV_INST(0)) - .mac_addr = DT_INST_PROP(0, local_mac_address), -#endif .tx_sem = Z_SEM_INITIALIZER(w5500_0_runtime.tx_sem, 1, UINT_MAX), .int_sem = Z_SEM_INITIALIZER(w5500_0_runtime.int_sem, @@ -615,6 +624,7 @@ static const struct w5500_config w5500_0_config = { .interrupt = GPIO_DT_SPEC_INST_GET(0, int_gpios), .reset = GPIO_DT_SPEC_INST_GET_OR(0, reset_gpios, { 0 }), .timeout = CONFIG_ETH_W5500_TIMEOUT, + .mac_cfg = NET_ETH_MAC_DT_INST_CONFIG_INIT(0), }; ETH_NET_DEVICE_DT_INST_DEFINE(0, diff --git a/drivers/ethernet/eth_w5500_priv.h b/drivers/ethernet/eth_w5500_priv.h index 79383d9004be..50235481aa64 100644 --- a/drivers/ethernet/eth_w5500_priv.h +++ b/drivers/ethernet/eth_w5500_priv.h @@ -84,6 +84,7 @@ struct w5500_config { struct gpio_dt_spec interrupt; struct gpio_dt_spec reset; int32_t timeout; + struct net_eth_mac_config mac_cfg; }; struct w5500_runtime { From 0a06f5b91afe86ffab567315fdfc49967900b043 Mon Sep 17 00:00:00 2001 From: Sreeram Tatapudi Date: Sat, 6 Dec 2025 13:00:11 -0800 Subject: [PATCH 0547/3659] dts: bindings: Drop cat1 from the infineon binding files Drop cat1 from the binding files to enable reuse by other category devices as well. Fixes #99174 Signed-off-by: Sreeram Tatapudi --- .../cy8ckit_062s2_ai/cy8ckit_062s2_ai.dts | 6 +- .../infineon/cy8ckit_062s4/cy8ckit_062s4.dts | 4 +- .../cy8cproto_062_4343w.dts | 6 +- .../cy8cproto_063_ble/cy8cproto_063_ble.dts | 2 +- .../cyw920829m2evk_02/cyw920829m2evk_02.dtsi | 4 +- .../cyw920829m2evk_02/cyw920829m2ipa2.dtsi | 2 +- .../kit_psc3m5_evk/kit_psc3m5_evk.dts | 2 +- .../kit_psc3m5_evk_psc3m5fds2afq1_ns.dts | 2 +- .../kit_pse84_ai/kit_pse84_ai_common.dtsi | 2 +- .../kit_pse84_ai/kit_pse84_ai_memory_map.dtsi | 2 +- .../kit_pse84_eval/kit_pse84_eval_common.dtsi | 2 +- .../kit_pse84_eval_memory_map.dtsi | 2 +- .../kit_t2g_b_h_evk_common.dtsi | 2 +- .../kit_t2g_b_h_lite_common.dtsi | 2 +- .../kit_xmc72_evk/kit_xmc72_evk_common.dtsi | 2 +- drivers/adc/Kconfig.infineon | 2 +- drivers/adc/adc_infineon.c | 2 +- drivers/bluetooth/hci/CMakeLists.txt | 2 +- drivers/bluetooth/hci/Kconfig | 2 +- .../bluetooth/hci/hci_infineon_psoc6_bless.c | 2 +- drivers/counter/Kconfig.infineon | 2 +- drivers/counter/counter_infineon.c | 2 +- drivers/dma/Kconfig.infineon | 4 +- drivers/dma/dma_infineon.c | 2 +- drivers/dma/dma_infineon_pdl.c | 2 +- drivers/flash/Kconfig.infineon | 4 +- drivers/flash/flash_infineon.c | 4 +- drivers/flash/flash_infineon_qspi.c | 4 +- .../flash/flash_infineon_serial_memory_qspi.c | 4 +- drivers/gpio/Kconfig.infineon | 2 +- drivers/gpio/gpio_infineon.c | 2 +- drivers/i2c/Kconfig.infineon | 4 +- drivers/i2c/i2c_infineon.c | 4 +- drivers/i2c/i2c_infineon_pdl.c | 4 +- drivers/pinctrl/Kconfig.infineon | 2 +- drivers/rtc/Kconfig.infineon | 2 +- drivers/rtc/rtc_infineon.c | 2 +- drivers/sdhc/Kconfig.infineon | 2 +- drivers/sdhc/infineon_sdio.c | 2 +- drivers/serial/Kconfig.infineon | 4 +- drivers/serial/uart_infineon.c | 2 +- drivers/serial/uart_infineon_pdl.c | 2 +- drivers/spi/Kconfig.infineon | 4 +- drivers/spi/spi_infineon.c | 2 +- drivers/spi/spi_infineon_pdl.c | 2 +- drivers/timer/Kconfig.infineon_lp | 2 +- drivers/timer/infineon_lp_timer.c | 2 +- drivers/watchdog/Kconfig.infineon | 2 +- drivers/watchdog/wdt_infineon.c | 4 +- dts/arm/infineon/cat1a/legacy/psoc6.dtsi | 2 +- dts/arm/infineon/cat1a/psoc6_01/psoc6_01.dtsi | 134 ++-- dts/arm/infineon/cat1a/psoc6_02/psoc6_02.dtsi | 136 ++-- dts/arm/infineon/cat1a/psoc6_03/psoc6_03.dtsi | 50 +- dts/arm/infineon/cat1a/psoc6_04/psoc6_04.dtsi | 52 +- dts/arm/infineon/cat1b/cyw20829/cyw20829.dtsi | 34 +- .../infineon/cat1b/mpns/cyw20829b1240.dtsi | 2 +- .../infineon/cat1b/mpns/cyw20829b1340.dtsi | 2 +- .../infineon/cat1b/mpns/cyw89829b0232.dtsi | 2 +- .../infineon/cat1b/mpns/cyw89829b1232.dtsi | 2 +- dts/arm/infineon/cat1b/mpns/psc3m3edabq1.dtsi | 2 +- .../infineon/cat1b/mpns/psc3m3edabq1_s.dtsi | 2 +- dts/arm/infineon/cat1b/mpns/psc3m3edacq1.dtsi | 2 +- .../infineon/cat1b/mpns/psc3m3edacq1_s.dtsi | 2 +- dts/arm/infineon/cat1b/mpns/psc3m3edlgq1.dtsi | 2 +- .../infineon/cat1b/mpns/psc3m3edlgq1_s.dtsi | 2 +- dts/arm/infineon/cat1b/mpns/psc3m3edlhq1.dtsi | 2 +- .../infineon/cat1b/mpns/psc3m3edlhq1_s.dtsi | 2 +- .../infineon/cat1b/mpns/psc3m3fds2abq1.dtsi | 2 +- .../infineon/cat1b/mpns/psc3m3fds2abq1_s.dtsi | 2 +- .../infineon/cat1b/mpns/psc3m3fds2acq1.dtsi | 2 +- .../infineon/cat1b/mpns/psc3m3fds2acq1_s.dtsi | 2 +- .../infineon/cat1b/mpns/psc3m3fds2lgq1.dtsi | 2 +- .../infineon/cat1b/mpns/psc3m3fds2lgq1_s.dtsi | 2 +- .../infineon/cat1b/mpns/psc3m3fds2lhq1.dtsi | 2 +- .../infineon/cat1b/mpns/psc3m3fds2lhq1_s.dtsi | 2 +- dts/arm/infineon/cat1b/mpns/psc3m5edabq1.dtsi | 2 +- .../infineon/cat1b/mpns/psc3m5edabq1_s.dtsi | 2 +- dts/arm/infineon/cat1b/mpns/psc3m5edacq1.dtsi | 2 +- .../infineon/cat1b/mpns/psc3m5edacq1_s.dtsi | 2 +- dts/arm/infineon/cat1b/mpns/psc3m5edafq1.dtsi | 2 +- .../infineon/cat1b/mpns/psc3m5edafq1_s.dtsi | 2 +- dts/arm/infineon/cat1b/mpns/psc3m5edlgq1.dtsi | 2 +- .../infineon/cat1b/mpns/psc3m5edlgq1_s.dtsi | 2 +- dts/arm/infineon/cat1b/mpns/psc3m5edlhq1.dtsi | 2 +- .../infineon/cat1b/mpns/psc3m5edlhq1_s.dtsi | 2 +- .../infineon/cat1b/mpns/psc3m5fds2abq1.dtsi | 2 +- .../infineon/cat1b/mpns/psc3m5fds2abq1_s.dtsi | 2 +- .../infineon/cat1b/mpns/psc3m5fds2acq1.dtsi | 2 +- .../infineon/cat1b/mpns/psc3m5fds2acq1_s.dtsi | 2 +- .../infineon/cat1b/mpns/psc3m5fds2afq1.dtsi | 2 +- .../infineon/cat1b/mpns/psc3m5fds2afq1_s.dtsi | 2 +- .../infineon/cat1b/mpns/psc3m5fds2lgq1.dtsi | 2 +- .../infineon/cat1b/mpns/psc3m5fds2lgq1_s.dtsi | 2 +- .../infineon/cat1b/mpns/psc3m5fds2lhq1.dtsi | 2 +- .../infineon/cat1b/mpns/psc3m5fds2lhq1_s.dtsi | 2 +- dts/arm/infineon/cat1b/mpns/psc3p2edabq1.dtsi | 2 +- .../infineon/cat1b/mpns/psc3p2edabq1_s.dtsi | 2 +- dts/arm/infineon/cat1b/mpns/psc3p2edacq1.dtsi | 2 +- .../infineon/cat1b/mpns/psc3p2edacq1_s.dtsi | 2 +- dts/arm/infineon/cat1b/mpns/psc3p2edlgq1.dtsi | 2 +- .../infineon/cat1b/mpns/psc3p2edlgq1_s.dtsi | 2 +- dts/arm/infineon/cat1b/mpns/psc3p2edlhq1.dtsi | 2 +- .../infineon/cat1b/mpns/psc3p2edlhq1_s.dtsi | 2 +- .../infineon/cat1b/mpns/psc3p2fds2abq1.dtsi | 2 +- .../infineon/cat1b/mpns/psc3p2fds2abq1_s.dtsi | 2 +- .../infineon/cat1b/mpns/psc3p2fds2acq1.dtsi | 2 +- .../infineon/cat1b/mpns/psc3p2fds2acq1_s.dtsi | 2 +- .../infineon/cat1b/mpns/psc3p2fds2lgq1.dtsi | 2 +- .../infineon/cat1b/mpns/psc3p2fds2lgq1_s.dtsi | 2 +- .../infineon/cat1b/mpns/psc3p2fds2lhq1.dtsi | 2 +- .../infineon/cat1b/mpns/psc3p2fds2lhq1_s.dtsi | 2 +- dts/arm/infineon/cat1b/mpns/psc3p5edabq1.dtsi | 2 +- .../infineon/cat1b/mpns/psc3p5edabq1_s.dtsi | 2 +- dts/arm/infineon/cat1b/mpns/psc3p5edacq1.dtsi | 2 +- .../infineon/cat1b/mpns/psc3p5edacq1_s.dtsi | 2 +- dts/arm/infineon/cat1b/mpns/psc3p5edlgq1.dtsi | 2 +- .../infineon/cat1b/mpns/psc3p5edlgq1_s.dtsi | 2 +- dts/arm/infineon/cat1b/mpns/psc3p5edlhq1.dtsi | 2 +- .../infineon/cat1b/mpns/psc3p5edlhq1_s.dtsi | 2 +- .../infineon/cat1b/mpns/psc3p5fds2abq1.dtsi | 2 +- .../infineon/cat1b/mpns/psc3p5fds2abq1_s.dtsi | 2 +- .../infineon/cat1b/mpns/psc3p5fds2acq1.dtsi | 2 +- .../infineon/cat1b/mpns/psc3p5fds2acq1_s.dtsi | 2 +- .../infineon/cat1b/mpns/psc3p5fds2lgq1.dtsi | 2 +- .../infineon/cat1b/mpns/psc3p5fds2lgq1_s.dtsi | 2 +- .../infineon/cat1b/mpns/psc3p5fds2lhq1.dtsi | 2 +- .../infineon/cat1b/mpns/psc3p5fds2lhq1_s.dtsi | 2 +- dts/arm/infineon/cat1b/psc3/psc3.dtsi | 48 +- dts/arm/infineon/cat1b/psc3/psc3_s.dtsi | 48 +- dts/arm/infineon/cat1c/xmc7200/xmc7200.dtsi | 584 +++++++++--------- dts/arm/infineon/edge/pse84/pse84.dtsi | 92 +-- dts/arm/infineon/edge/pse84/pse84_s.dtsi | 92 +-- ...fineon,cat1-adc.yaml => infineon,adc.yaml} | 2 +- ...fineon,cat1-scb.yaml => infineon,scb.yaml} | 2 +- ...bless-hci.yaml => infineon,bless-hci.yaml} | 2 +- ...at1-counter.yaml => infineon,counter.yaml} | 2 +- ...fineon,cat1-dma.yaml => infineon,dma.yaml} | 2 +- ...er.yaml => infineon,flash-controller.yaml} | 2 +- ...pi-flash.yaml => infineon,qspi-flash.yaml} | 2 +- ...neon,cat1-gpio.yaml => infineon,gpio.yaml} | 2 +- ...fineon,cat1-i2c.yaml => infineon,i2c.yaml} | 6 +- ...at1-pinctrl.yaml => infineon,pinctrl.yaml} | 2 +- ...fineon,cat1-rtc.yaml => infineon,rtc.yaml} | 2 +- ...sdhc-sdio.yaml => infineon,sdhc-sdio.yaml} | 2 +- ...neon,cat1-uart.yaml => infineon,uart.yaml} | 4 +- ...fineon,cat1-spi.yaml => infineon,spi.yaml} | 2 +- ...1-lp-timer.yaml => infineon,lp-timer.yaml} | 2 +- ...1-watchdog.yaml => infineon,watchdog.yaml} | 2 +- .../async_api/boards/cy8ckit_062s2_ai.overlay | 4 +- .../boards/cy8cproto_062_4343w.overlay | 4 +- .../boards/cy8cproto_063_ble.overlay | 2 +- .../async_api/boards/kit_psc3m5_evk.overlay | 2 +- ...it_pse84_eval_pse846gps2dbzc4a_m33.overlay | 2 +- ...it_pse84_eval_pse846gps2dbzc4a_m55.overlay | 2 +- .../i2c_api/boards/cy8cproto_063_ble.overlay | 2 +- .../boards/cyw920829m2evk_02_common.overlay | 2 +- .../boards/cy8cproto_062_4343w.overlay | 2 +- .../boards/cy8cproto_063_ble.overlay | 2 +- .../boards/kit_psc3m5_evk.overlay | 2 +- .../boards/kit_pse84_eval_common.overlay | 2 +- .../boards/cy8ckit_062s2_ai.overlay | 4 +- .../boards/cy8cproto_062_4343w.overlay | 4 +- .../boards/cy8cproto_063_ble.overlay | 2 +- .../boards/cyw920829m2evk_02_common.overlay | 4 +- .../boards/kit_psc3m5_evk.overlay | 2 +- ...it_pse84_eval_pse846gps2dbzc4a_m33.overlay | 2 +- ...it_pse84_eval_pse846gps2dbzc4a_m55.overlay | 2 +- 167 files changed, 817 insertions(+), 817 deletions(-) rename dts/bindings/adc/{infineon,cat1-adc.yaml => infineon,adc.yaml} (95%) rename dts/bindings/arm/{infineon,cat1-scb.yaml => infineon,scb.yaml} (93%) rename dts/bindings/bluetooth/{infineon,cat1-bless-hci.yaml => infineon,bless-hci.yaml} (92%) rename dts/bindings/counter/{infineon,cat1-counter.yaml => infineon,counter.yaml} (95%) rename dts/bindings/dma/{infineon,cat1-dma.yaml => infineon,dma.yaml} (95%) rename dts/bindings/flash_controller/{infineon,cat1-flash-controller.yaml => infineon,flash-controller.yaml} (63%) rename dts/bindings/flash_controller/{infineon,cat1-qspi-flash.yaml => infineon,qspi-flash.yaml} (67%) rename dts/bindings/gpio/{infineon,cat1-gpio.yaml => infineon,gpio.yaml} (94%) rename dts/bindings/i2c/{infineon,cat1-i2c.yaml => infineon,i2c.yaml} (90%) rename dts/bindings/pinctrl/{infineon,cat1-pinctrl.yaml => infineon,pinctrl.yaml} (99%) rename dts/bindings/rtc/{infineon,cat1-rtc.yaml => infineon,rtc.yaml} (90%) rename dts/bindings/sdhc/{infineon,cat1-sdhc-sdio.yaml => infineon,sdhc-sdio.yaml} (93%) rename dts/bindings/serial/{infineon,cat1-uart.yaml => infineon,uart.yaml} (95%) rename dts/bindings/spi/{infineon,cat1-spi.yaml => infineon,spi.yaml} (91%) rename dts/bindings/timer/{infineon,cat1-lp-timer.yaml => infineon,lp-timer.yaml} (89%) rename dts/bindings/watchdog/{infineon,cat1-watchdog.yaml => infineon,watchdog.yaml} (92%) diff --git a/boards/infineon/cy8ckit_062s2_ai/cy8ckit_062s2_ai.dts b/boards/infineon/cy8ckit_062s2_ai/cy8ckit_062s2_ai.dts index 4e7b1c12d18f..ffdb91fff119 100644 --- a/boards/infineon/cy8ckit_062s2_ai/cy8ckit_062s2_ai.dts +++ b/boards/infineon/cy8ckit_062s2_ai/cy8ckit_062s2_ai.dts @@ -93,7 +93,7 @@ /* UART connected to KitProg3 */ uart5: &scb5 { - compatible = "infineon,cat1-uart"; + compatible = "infineon,uart"; status = "okay"; current-speed = <115200>; pinctrl-0 = <&p5_1_scb5_uart_tx &p5_0_scb5_uart_rx>; @@ -101,7 +101,7 @@ uart5: &scb5 { }; uart1: &scb1 { - compatible = "infineon,cat1-uart"; + compatible = "infineon,uart"; status = "okay"; current-speed = <115200>; pinctrl-0 = <&p10_0_scb1_uart_rx &p10_1_scb1_uart_tx>; @@ -109,7 +109,7 @@ uart1: &scb1 { }; i2c0: &scb0 { - compatible = "infineon,cat1-i2c"; + compatible = "infineon,i2c"; status = "okay"; #address-cells = <1>; diff --git a/boards/infineon/cy8ckit_062s4/cy8ckit_062s4.dts b/boards/infineon/cy8ckit_062s4/cy8ckit_062s4.dts index 6992a1378dbc..41ed4640f9e3 100644 --- a/boards/infineon/cy8ckit_062s4/cy8ckit_062s4.dts +++ b/boards/infineon/cy8ckit_062s4/cy8ckit_062s4.dts @@ -68,7 +68,7 @@ }; uart2: &scb2 { - compatible = "infineon,cat1-uart"; + compatible = "infineon,uart"; status = "okay"; current-speed = <115200>; pinctrl-0 = <&p3_0_scb2_uart_rx &p3_1_scb2_uart_tx>; @@ -84,7 +84,7 @@ uart2: &scb2 { }; uart0: &scb0 { - compatible = "infineon,cat1-uart"; + compatible = "infineon,uart"; }; arduino_serial: &uart0 {}; diff --git a/boards/infineon/cy8cproto_062_4343w/cy8cproto_062_4343w.dts b/boards/infineon/cy8cproto_062_4343w/cy8cproto_062_4343w.dts index 5df947eccfed..3aefe67c863d 100644 --- a/boards/infineon/cy8cproto_062_4343w/cy8cproto_062_4343w.dts +++ b/boards/infineon/cy8cproto_062_4343w/cy8cproto_062_4343w.dts @@ -34,7 +34,7 @@ }; uart5: &scb5 { - compatible = "infineon,cat1-uart"; + compatible = "infineon,uart"; status = "okay"; current-speed = <115200>; @@ -43,7 +43,7 @@ uart5: &scb5 { }; uart2: &scb2 { - compatible = "infineon,cat1-uart"; + compatible = "infineon,uart"; status = "okay"; /* The UART bus speed (current_speed) for zephyr_bt_uart should be the same @@ -129,7 +129,7 @@ uart2: &scb2 { }; i2c3: &scb3 { - compatible = "infineon,cat1-i2c"; + compatible = "infineon,i2c"; /* I2C pins */ pinctrl-0 = <&p6_0_scb3_i2c_scl &p6_1_scb3_i2c_sda>; diff --git a/boards/infineon/cy8cproto_063_ble/cy8cproto_063_ble.dts b/boards/infineon/cy8cproto_063_ble/cy8cproto_063_ble.dts index ea61b06df94d..94e4d7f5614c 100644 --- a/boards/infineon/cy8cproto_063_ble/cy8cproto_063_ble.dts +++ b/boards/infineon/cy8cproto_063_ble/cy8cproto_063_ble.dts @@ -81,7 +81,7 @@ }; uart5: &scb5 { - compatible = "infineon,cat1-uart"; + compatible = "infineon,uart"; status = "okay"; current-speed = <115200>; diff --git a/boards/infineon/cyw920829m2evk_02/cyw920829m2evk_02.dtsi b/boards/infineon/cyw920829m2evk_02/cyw920829m2evk_02.dtsi index bcc897ef17e7..1247bcb46833 100644 --- a/boards/infineon/cyw920829m2evk_02/cyw920829m2evk_02.dtsi +++ b/boards/infineon/cyw920829m2evk_02/cyw920829m2evk_02.dtsi @@ -26,7 +26,7 @@ }; uart2: &scb2 { - compatible = "infineon,cat1-uart"; + compatible = "infineon,uart"; status = "okay"; current-speed = <115200>; hw-flow-control; @@ -41,7 +41,7 @@ uart2: &scb2 { &dma0 { #address-cells = <1>; #size-cells = <0>; - compatible = "infineon,cat1-dma"; + compatible = "infineon,dma"; status = "okay"; }; diff --git a/boards/infineon/cyw920829m2evk_02/cyw920829m2ipa2.dtsi b/boards/infineon/cyw920829m2evk_02/cyw920829m2ipa2.dtsi index ef45416a5445..020ba2286713 100644 --- a/boards/infineon/cyw920829m2evk_02/cyw920829m2ipa2.dtsi +++ b/boards/infineon/cyw920829m2evk_02/cyw920829m2ipa2.dtsi @@ -11,7 +11,7 @@ / { qspi_flash: qspi_flash@40890000 { - compatible = "infineon,cat1-qspi-flash"; + compatible = "infineon,qspi-flash"; reg = <0x40890000 0x30000>; #address-cells = <1>; #size-cells = <1>; diff --git a/boards/infineon/kit_psc3m5_evk/kit_psc3m5_evk.dts b/boards/infineon/kit_psc3m5_evk/kit_psc3m5_evk.dts index bcfc3b3eb8ae..e90ff4293d08 100644 --- a/boards/infineon/kit_psc3m5_evk/kit_psc3m5_evk.dts +++ b/boards/infineon/kit_psc3m5_evk/kit_psc3m5_evk.dts @@ -27,7 +27,7 @@ }; uart3: &scb3 { - compatible = "infineon,cat1-uart"; + compatible = "infineon,uart"; status = "okay"; current-speed = <115200>; diff --git a/boards/infineon/kit_psc3m5_evk/kit_psc3m5_evk_psc3m5fds2afq1_ns.dts b/boards/infineon/kit_psc3m5_evk/kit_psc3m5_evk_psc3m5fds2afq1_ns.dts index 6231d9fb5729..3a79fda567b4 100644 --- a/boards/infineon/kit_psc3m5_evk/kit_psc3m5_evk_psc3m5fds2afq1_ns.dts +++ b/boards/infineon/kit_psc3m5_evk/kit_psc3m5_evk_psc3m5fds2afq1_ns.dts @@ -27,7 +27,7 @@ }; uart3: &scb3 { - compatible = "infineon,cat1-uart"; + compatible = "infineon,uart"; status = "okay"; current-speed = <115200>; diff --git a/boards/infineon/kit_pse84_ai/kit_pse84_ai_common.dtsi b/boards/infineon/kit_pse84_ai/kit_pse84_ai_common.dtsi index 08879ec8f6b5..076535698e30 100644 --- a/boards/infineon/kit_pse84_ai/kit_pse84_ai_common.dtsi +++ b/boards/infineon/kit_pse84_ai/kit_pse84_ai_common.dtsi @@ -55,7 +55,7 @@ }; uart2: &scb2 { - compatible = "infineon,cat1-uart"; + compatible = "infineon,uart"; status = "okay"; current-speed = <115200>; diff --git a/boards/infineon/kit_pse84_ai/kit_pse84_ai_memory_map.dtsi b/boards/infineon/kit_pse84_ai/kit_pse84_ai_memory_map.dtsi index c8c7796de4a8..cf0024ff9c2c 100644 --- a/boards/infineon/kit_pse84_ai/kit_pse84_ai_memory_map.dtsi +++ b/boards/infineon/kit_pse84_ai/kit_pse84_ai_memory_map.dtsi @@ -70,7 +70,7 @@ * - 2mb for each of the cores(cm33_s, cm33 and cm55) */ flash_controller: flash_controller@40250000 { - compatible = "infineon,cat1-qspi-flash-mtb-hal"; + compatible = "infineon,qspi-flash-mtb-hal"; reg = <0x40250000 0x10000>; #address-cells = <1>; #size-cells = <1>; diff --git a/boards/infineon/kit_pse84_eval/kit_pse84_eval_common.dtsi b/boards/infineon/kit_pse84_eval/kit_pse84_eval_common.dtsi index c4e5affbee15..c4cfcaa1a9e4 100644 --- a/boards/infineon/kit_pse84_eval/kit_pse84_eval_common.dtsi +++ b/boards/infineon/kit_pse84_eval/kit_pse84_eval_common.dtsi @@ -45,7 +45,7 @@ }; uart2: &scb2 { - compatible = "infineon,cat1-uart"; + compatible = "infineon,uart"; status = "okay"; current-speed = <115200>; diff --git a/boards/infineon/kit_pse84_eval/kit_pse84_eval_memory_map.dtsi b/boards/infineon/kit_pse84_eval/kit_pse84_eval_memory_map.dtsi index 3cb3347c9337..1f9420fa6d73 100644 --- a/boards/infineon/kit_pse84_eval/kit_pse84_eval_memory_map.dtsi +++ b/boards/infineon/kit_pse84_eval/kit_pse84_eval_memory_map.dtsi @@ -71,7 +71,7 @@ */ flash_controller: flash_controller@40250000 { - compatible = "infineon,cat1-qspi-flash"; + compatible = "infineon,qspi-flash"; reg = <0x40250000 0x10000>; #address-cells = <1>; #size-cells = <1>; diff --git a/boards/infineon/kit_t2g_b_h_evk/kit_t2g_b_h_evk_common.dtsi b/boards/infineon/kit_t2g_b_h_evk/kit_t2g_b_h_evk_common.dtsi index 45b5df0cfd0b..8cf985cb47bf 100644 --- a/boards/infineon/kit_t2g_b_h_evk/kit_t2g_b_h_evk_common.dtsi +++ b/boards/infineon/kit_t2g_b_h_evk/kit_t2g_b_h_evk_common.dtsi @@ -55,7 +55,7 @@ }; uart3: &scb3 { - compatible = "infineon,cat1-uart"; + compatible = "infineon,uart"; status = "okay"; current-speed = <115200>; diff --git a/boards/infineon/kit_t2g_b_h_lite/kit_t2g_b_h_lite_common.dtsi b/boards/infineon/kit_t2g_b_h_lite/kit_t2g_b_h_lite_common.dtsi index d09baecea197..46bf6fbdac45 100644 --- a/boards/infineon/kit_t2g_b_h_lite/kit_t2g_b_h_lite_common.dtsi +++ b/boards/infineon/kit_t2g_b_h_lite/kit_t2g_b_h_lite_common.dtsi @@ -55,7 +55,7 @@ }; uart0: &scb0 { - compatible = "infineon,cat1-uart"; + compatible = "infineon,uart"; status = "okay"; current-speed = <115200>; diff --git a/boards/infineon/kit_xmc72_evk/kit_xmc72_evk_common.dtsi b/boards/infineon/kit_xmc72_evk/kit_xmc72_evk_common.dtsi index 43137558abcf..e6bdf31a5c76 100644 --- a/boards/infineon/kit_xmc72_evk/kit_xmc72_evk_common.dtsi +++ b/boards/infineon/kit_xmc72_evk/kit_xmc72_evk_common.dtsi @@ -54,7 +54,7 @@ }; uart3: &scb3 { - compatible = "infineon,cat1-uart"; + compatible = "infineon,uart"; status = "okay"; current-speed = <115200>; diff --git a/drivers/adc/Kconfig.infineon b/drivers/adc/Kconfig.infineon index 1af6efcb48d0..63e6799c3779 100644 --- a/drivers/adc/Kconfig.infineon +++ b/drivers/adc/Kconfig.infineon @@ -8,7 +8,7 @@ config ADC_INFINEON_CAT1 bool "Infineon CAT1 ADC driver" default y - depends on DT_HAS_INFINEON_CAT1_ADC_ENABLED + depends on DT_HAS_INFINEON_ADC_ENABLED select USE_INFINEON_ADC select USE_INFINEON_DMA select ADC_CONFIGURABLE_INPUTS diff --git a/drivers/adc/adc_infineon.c b/drivers/adc/adc_infineon.c index 3a4aa9f8746d..92776d8b9e34 100644 --- a/drivers/adc/adc_infineon.c +++ b/drivers/adc/adc_infineon.c @@ -9,7 +9,7 @@ * @brief ADC driver for Infineon CAT1 MCU family. */ -#define DT_DRV_COMPAT infineon_cat1_adc +#define DT_DRV_COMPAT infineon_adc #include #include diff --git a/drivers/bluetooth/hci/CMakeLists.txt b/drivers/bluetooth/hci/CMakeLists.txt index 7b87340f6b4f..08b513745913 100644 --- a/drivers/bluetooth/hci/CMakeLists.txt +++ b/drivers/bluetooth/hci/CMakeLists.txt @@ -21,7 +21,7 @@ if(CONFIG_DT_HAS_SILABS_BT_HCI_EFR32_ENABLED) zephyr_blobs_verify(MODULE hal_silabs REQUIRED) endif() -if(CONFIG_DT_HAS_INFINEON_CAT1_BLESS_HCI_ENABLED) +if(CONFIG_DT_HAS_INFINEON_BLESS_HCI_ENABLED) zephyr_blobs_verify(MODULE hal_infineon REQUIRED) endif() diff --git a/drivers/bluetooth/hci/Kconfig b/drivers/bluetooth/hci/Kconfig index 5d7ade2f1849..cfdacc064c14 100644 --- a/drivers/bluetooth/hci/Kconfig +++ b/drivers/bluetooth/hci/Kconfig @@ -184,7 +184,7 @@ config BT_ESP32 config BT_PSOC6_BLESS bool default y - depends on DT_HAS_INFINEON_CAT1_BLESS_HCI_ENABLED + depends on DT_HAS_INFINEON_BLESS_HCI_ENABLED depends on ZEPHYR_HAL_INFINEON_MODULE_BLOBS select BT_HCI_SETUP help diff --git a/drivers/bluetooth/hci/hci_infineon_psoc6_bless.c b/drivers/bluetooth/hci/hci_infineon_psoc6_bless.c index 42800043f315..0e6f8859f0e5 100644 --- a/drivers/bluetooth/hci/hci_infineon_psoc6_bless.c +++ b/drivers/bluetooth/hci/hci_infineon_psoc6_bless.c @@ -29,7 +29,7 @@ LOG_MODULE_REGISTER(psoc6_bless); #include "cy_ble_stack_pvt.h" #include "cycfg_ble.h" -#define DT_DRV_COMPAT infineon_cat1_bless_hci +#define DT_DRV_COMPAT infineon_bless_hci struct psoc6_bless_data { bt_hci_recv_t recv; diff --git a/drivers/counter/Kconfig.infineon b/drivers/counter/Kconfig.infineon index 4090911dcdb6..5751e3f4217b 100644 --- a/drivers/counter/Kconfig.infineon +++ b/drivers/counter/Kconfig.infineon @@ -7,7 +7,7 @@ config COUNTER_INFINEON_CAT1 bool "Infineon CAT1 COUNTER driver" default y - depends on DT_HAS_INFINEON_CAT1_COUNTER_ENABLED + depends on DT_HAS_INFINEON_COUNTER_ENABLED select USE_INFINEON_TIMER help This option enables the COUNTER driver for Infineon CAT1 family. diff --git a/drivers/counter/counter_infineon.c b/drivers/counter/counter_infineon.c index cd1068aba46f..9cb19b4302c5 100644 --- a/drivers/counter/counter_infineon.c +++ b/drivers/counter/counter_infineon.c @@ -9,7 +9,7 @@ * @brief Counter driver for Infineon CAT1 MCU family. */ -#define DT_DRV_COMPAT infineon_cat1_counter +#define DT_DRV_COMPAT infineon_counter #include #include diff --git a/drivers/dma/Kconfig.infineon b/drivers/dma/Kconfig.infineon index 529ba603e6f1..cbc647eb307c 100644 --- a/drivers/dma/Kconfig.infineon +++ b/drivers/dma/Kconfig.infineon @@ -8,7 +8,7 @@ config DMA_INFINEON_CAT1_HAL bool "Infineon CAT1 DMA Legacy HAL-based driver" default y - depends on DT_HAS_INFINEON_CAT1_DMA_ENABLED + depends on DT_HAS_INFINEON_DMA_ENABLED depends on USE_INFINEON_LEGACY_HAL select USE_INFINEON_DMA help @@ -17,7 +17,7 @@ config DMA_INFINEON_CAT1_HAL config DMA_INFINEON_CAT1_PDL bool "Infineon CAT1 DMA PDL-based driver" default y - depends on DT_HAS_INFINEON_CAT1_DMA_ENABLED + depends on DT_HAS_INFINEON_DMA_ENABLED depends on !USE_INFINEON_LEGACY_HAL select USE_INFINEON_DMA help diff --git a/drivers/dma/dma_infineon.c b/drivers/dma/dma_infineon.c index 3ae5673e815c..fc55fbeaa456 100644 --- a/drivers/dma/dma_infineon.c +++ b/drivers/dma/dma_infineon.c @@ -9,7 +9,7 @@ * @brief DMA driver for Infineon CAT1 MCU family. */ -#define DT_DRV_COMPAT infineon_cat1_dma +#define DT_DRV_COMPAT infineon_dma #include #include diff --git a/drivers/dma/dma_infineon_pdl.c b/drivers/dma/dma_infineon_pdl.c index ab0875decaaa..dbca67bc6942 100644 --- a/drivers/dma/dma_infineon_pdl.c +++ b/drivers/dma/dma_infineon_pdl.c @@ -9,7 +9,7 @@ * @brief DMA driver for Infineon CAT1 MCU family. */ -#define DT_DRV_COMPAT infineon_cat1_dma +#define DT_DRV_COMPAT infineon_dma #include diff --git a/drivers/flash/Kconfig.infineon b/drivers/flash/Kconfig.infineon index c21c252a2efe..5aa4c9bedc86 100644 --- a/drivers/flash/Kconfig.infineon +++ b/drivers/flash/Kconfig.infineon @@ -8,7 +8,7 @@ config FLASH_INFINEON_CAT1 bool "Infineon CAT1 FLASH driver" default y - depends on DT_HAS_INFINEON_CAT1_FLASH_CONTROLLER_ENABLED && DT_HAS_FIXED_PARTITIONS_ENABLED + depends on DT_HAS_INFINEON_FLASH_CONTROLLER_ENABLED && DT_HAS_FIXED_PARTITIONS_ENABLED select FLASH_HAS_PAGE_LAYOUT select FLASH_HAS_DRIVER_ENABLED select USE_INFINEON_FLASH @@ -19,7 +19,7 @@ config FLASH_INFINEON_CAT1 config INFINEON_CAT1_QSPI_FLASH bool "Infineon CAT1 QSPI FLASH driver" default y - depends on DT_HAS_INFINEON_CAT1_QSPI_FLASH_ENABLED && DT_HAS_FIXED_PARTITIONS_ENABLED + depends on DT_HAS_INFINEON_QSPI_FLASH_ENABLED && DT_HAS_FIXED_PARTITIONS_ENABLED select FLASH_HAS_PAGE_LAYOUT select FLASH_HAS_DRIVER_ENABLED select USE_INFINEON_FLASH diff --git a/drivers/flash/flash_infineon.c b/drivers/flash/flash_infineon.c index 17d93513b93b..ae588feb4766 100644 --- a/drivers/flash/flash_infineon.c +++ b/drivers/flash/flash_infineon.c @@ -5,7 +5,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#define DT_DRV_COMPAT infineon_cat1_flash_controller +#define DT_DRV_COMPAT infineon_flash_controller #define SOC_NV_FLASH_NODE DT_PARENT(DT_INST(0, fixed_partitions)) #define PAGE_LEN DT_PROP(SOC_NV_FLASH_NODE, erase_block_size) @@ -17,7 +17,7 @@ #include "cyhal_flash.h" -LOG_MODULE_REGISTER(flash_infineon_cat1, CONFIG_FLASH_LOG_LEVEL); +LOG_MODULE_REGISTER(flash_infineon, CONFIG_FLASH_LOG_LEVEL); /* Device config structure */ struct ifx_cat1_flash_config { diff --git a/drivers/flash/flash_infineon_qspi.c b/drivers/flash/flash_infineon_qspi.c index 864e2f14ce5d..fd5549bebaad 100644 --- a/drivers/flash/flash_infineon_qspi.c +++ b/drivers/flash/flash_infineon_qspi.c @@ -5,7 +5,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#define DT_DRV_COMPAT infineon_cat1_qspi_flash +#define DT_DRV_COMPAT infineon_qspi_flash #define SOC_NV_FLASH_NODE DT_PARENT(DT_INST(0, fixed_partitions)) #define PAGE_LEN DT_PROP(SOC_NV_FLASH_NODE, erase_block_size) @@ -18,7 +18,7 @@ #include "cy_serial_flash_qspi.h" #include "cy_smif_memslot.h" -LOG_MODULE_REGISTER(flash_infineon_cat1, CONFIG_FLASH_LOG_LEVEL); +LOG_MODULE_REGISTER(flash_infineon, CONFIG_FLASH_LOG_LEVEL); /* Device config structure */ struct ifx_cat1_flash_config { diff --git a/drivers/flash/flash_infineon_serial_memory_qspi.c b/drivers/flash/flash_infineon_serial_memory_qspi.c index 8e8efce654d0..d29c6f7ff79f 100644 --- a/drivers/flash/flash_infineon_serial_memory_qspi.c +++ b/drivers/flash/flash_infineon_serial_memory_qspi.c @@ -5,7 +5,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#define DT_DRV_COMPAT infineon_cat1_qspi_flash +#define DT_DRV_COMPAT infineon_qspi_flash #define SOC_NV_FLASH_NODE DT_PARENT(DT_INST(0, fixed_partitions)) #define PAGE_LEN DT_PROP(SOC_NV_FLASH_NODE, erase_block_size) @@ -19,7 +19,7 @@ #include "mtb_serial_memory.h" #include "cy_device_headers.h" -LOG_MODULE_REGISTER(flash_infineon_cat1, CONFIG_FLASH_LOG_LEVEL); +LOG_MODULE_REGISTER(flash_infineon, CONFIG_FLASH_LOG_LEVEL); #define TIMEOUT_1_MS (1000ul) /* 1 ms timeout for all blocking functions */ #define MEM_SLOT_NUM (0U) diff --git a/drivers/gpio/Kconfig.infineon b/drivers/gpio/Kconfig.infineon index 6491c754525f..d80c7cfc6234 100644 --- a/drivers/gpio/Kconfig.infineon +++ b/drivers/gpio/Kconfig.infineon @@ -7,6 +7,6 @@ config GPIO_INFINEON_CAT1 bool "Infineon CAT1 GPIO driver" default y - depends on DT_HAS_INFINEON_CAT1_GPIO_ENABLED + depends on DT_HAS_INFINEON_GPIO_ENABLED help Enable support for Infineon CAT1 GPIO controllers. diff --git a/drivers/gpio/gpio_infineon.c b/drivers/gpio/gpio_infineon.c index 5cc8981fcefc..5eef4b56c604 100644 --- a/drivers/gpio/gpio_infineon.c +++ b/drivers/gpio/gpio_infineon.c @@ -13,7 +13,7 @@ * is not supported in current version of GPIO CAT1 driver. */ -#define DT_DRV_COMPAT infineon_cat1_gpio +#define DT_DRV_COMPAT infineon_gpio #include #include diff --git a/drivers/i2c/Kconfig.infineon b/drivers/i2c/Kconfig.infineon index 6775b33bd257..2bf2cbbb7eb9 100644 --- a/drivers/i2c/Kconfig.infineon +++ b/drivers/i2c/Kconfig.infineon @@ -8,7 +8,7 @@ config I2C_INFINEON_CAT1_HAL bool "Infineon CAT1 I2C HAL based driver" default y - depends on DT_HAS_INFINEON_CAT1_I2C_ENABLED + depends on DT_HAS_INFINEON_I2C_ENABLED depends on USE_INFINEON_LEGACY_HAL select USE_INFINEON_I2C select PINCTRL @@ -18,7 +18,7 @@ config I2C_INFINEON_CAT1_HAL config I2C_INFINEON_CAT1_PDL bool "Infineon CAT1 I2C PDL based driver" default y - depends on DT_HAS_INFINEON_CAT1_I2C_ENABLED + depends on DT_HAS_INFINEON_I2C_ENABLED depends on !USE_INFINEON_LEGACY_HAL select USE_INFINEON_I2C select PINCTRL diff --git a/drivers/i2c/i2c_infineon.c b/drivers/i2c/i2c_infineon.c index d72e1fdc37b6..c50d3eecd824 100644 --- a/drivers/i2c/i2c_infineon.c +++ b/drivers/i2c/i2c_infineon.c @@ -9,7 +9,7 @@ * @brief I2C driver for Infineon CAT1 MCU family. */ -#define DT_DRV_COMPAT infineon_cat1_i2c +#define DT_DRV_COMPAT infineon_i2c #include #include @@ -18,7 +18,7 @@ #include #include -LOG_MODULE_REGISTER(i2c_infineon_cat1, CONFIG_I2C_LOG_LEVEL); +LOG_MODULE_REGISTER(i2c_infineon, CONFIG_I2C_LOG_LEVEL); #define I2C_CAT1_EVENTS_MASK (CYHAL_I2C_MASTER_WR_CMPLT_EVENT | CYHAL_I2C_MASTER_RD_CMPLT_EVENT | \ CYHAL_I2C_MASTER_ERR_EVENT) diff --git a/drivers/i2c/i2c_infineon_pdl.c b/drivers/i2c/i2c_infineon_pdl.c index 68a115e7982e..8bb6956c4da5 100644 --- a/drivers/i2c/i2c_infineon_pdl.c +++ b/drivers/i2c/i2c_infineon_pdl.c @@ -9,7 +9,7 @@ * @brief I2C driver for Infineon CAT1 MCU family. */ -#define DT_DRV_COMPAT infineon_cat1_i2c +#define DT_DRV_COMPAT infineon_i2c #include @@ -19,7 +19,7 @@ #include #include -LOG_MODULE_REGISTER(i2c_infineon_cat1, CONFIG_I2C_LOG_LEVEL); +LOG_MODULE_REGISTER(i2c_infineon, CONFIG_I2C_LOG_LEVEL); #include "cy_scb_i2c.h" diff --git a/drivers/pinctrl/Kconfig.infineon b/drivers/pinctrl/Kconfig.infineon index d0efe3e1e47a..886d262c577a 100644 --- a/drivers/pinctrl/Kconfig.infineon +++ b/drivers/pinctrl/Kconfig.infineon @@ -7,6 +7,6 @@ config PINCTRL_INFINEON_CAT1 bool "Pin controller driver for Infineon CAT1 MCUs" default y - depends on DT_HAS_INFINEON_CAT1_PINCTRL_ENABLED + depends on DT_HAS_INFINEON_PINCTRL_ENABLED help Enable Pin controller driver for Infineon CAT1 MCUs diff --git a/drivers/rtc/Kconfig.infineon b/drivers/rtc/Kconfig.infineon index 4a2a12f50c42..797b92e4a047 100644 --- a/drivers/rtc/Kconfig.infineon +++ b/drivers/rtc/Kconfig.infineon @@ -8,7 +8,7 @@ config RTC_INFINEON_CAT1 bool "Infineon CAT1 RTC driver" default y - depends on DT_HAS_INFINEON_CAT1_RTC_ENABLED + depends on DT_HAS_INFINEON_RTC_ENABLED select USE_INFINEON_RTC help This option enables the RTC driver for Infineon CAT1 family. diff --git a/drivers/rtc/rtc_infineon.c b/drivers/rtc/rtc_infineon.c index 4c2130a2c3bd..5f9a00090957 100644 --- a/drivers/rtc/rtc_infineon.c +++ b/drivers/rtc/rtc_infineon.c @@ -17,7 +17,7 @@ LOG_MODULE_REGISTER(ifx_cat1_rtc, CONFIG_RTC_LOG_LEVEL); -#define DT_DRV_COMPAT infineon_cat1_rtc +#define DT_DRV_COMPAT infineon_rtc #define _IFX_CAT1_RTC_STATE_UNINITIALIZED 0 #define _IFX_CAT1_RTC_STATE_ENABLED 1 diff --git a/drivers/sdhc/Kconfig.infineon b/drivers/sdhc/Kconfig.infineon index ca67f0fa98f5..efa86bfae04e 100644 --- a/drivers/sdhc/Kconfig.infineon +++ b/drivers/sdhc/Kconfig.infineon @@ -8,7 +8,7 @@ config SDHC_INFINEON_CAT1 bool "Infineon CAT1 SDHC driver" default y - depends on DT_HAS_INFINEON_CAT1_SDHC_SDIO_ENABLED + depends on DT_HAS_INFINEON_SDHC_SDIO_ENABLED select USE_INFINEON_SDIO select SDHC_SUPPORTS_NATIVE_MODE select PINCTRL diff --git a/drivers/sdhc/infineon_sdio.c b/drivers/sdhc/infineon_sdio.c index 4449b532f0b2..f2ef5f03f397 100644 --- a/drivers/sdhc/infineon_sdio.c +++ b/drivers/sdhc/infineon_sdio.c @@ -35,7 +35,7 @@ * > IO_RW_EXTENDED (CMD53) */ -#define DT_DRV_COMPAT infineon_cat1_sdhc_sdio +#define DT_DRV_COMPAT infineon_sdhc_sdio #include #include diff --git a/drivers/serial/Kconfig.infineon b/drivers/serial/Kconfig.infineon index ec9a85478700..69d39b789fb8 100644 --- a/drivers/serial/Kconfig.infineon +++ b/drivers/serial/Kconfig.infineon @@ -7,7 +7,7 @@ config UART_INFINEON_CAT1_HAL bool "Infineon CAT1 UART driver" default y - depends on DT_HAS_INFINEON_CAT1_UART_ENABLED + depends on DT_HAS_INFINEON_UART_ENABLED depends on USE_INFINEON_LEGACY_HAL select SERIAL_HAS_DRIVER select SERIAL_SUPPORT_INTERRUPT @@ -21,7 +21,7 @@ config UART_INFINEON_CAT1_HAL config UART_INFINEON_CAT1_PDL bool "Infineon CAT1 UART driver (PDL)" default y - depends on DT_HAS_INFINEON_CAT1_UART_ENABLED + depends on DT_HAS_INFINEON_UART_ENABLED depends on !USE_INFINEON_LEGACY_HAL select SERIAL_HAS_DRIVER select SERIAL_SUPPORT_INTERRUPT diff --git a/drivers/serial/uart_infineon.c b/drivers/serial/uart_infineon.c index 02d127967a7e..f43b9ec193d4 100644 --- a/drivers/serial/uart_infineon.c +++ b/drivers/serial/uart_infineon.c @@ -10,7 +10,7 @@ * */ -#define DT_DRV_COMPAT infineon_cat1_uart +#define DT_DRV_COMPAT infineon_uart #include #include diff --git a/drivers/serial/uart_infineon_pdl.c b/drivers/serial/uart_infineon_pdl.c index bcd51e53efee..f9d0647951a6 100644 --- a/drivers/serial/uart_infineon_pdl.c +++ b/drivers/serial/uart_infineon_pdl.c @@ -10,7 +10,7 @@ * */ -#define DT_DRV_COMPAT infineon_cat1_uart +#define DT_DRV_COMPAT infineon_uart #include #include diff --git a/drivers/spi/Kconfig.infineon b/drivers/spi/Kconfig.infineon index 16d68cac0613..40339a29d907 100644 --- a/drivers/spi/Kconfig.infineon +++ b/drivers/spi/Kconfig.infineon @@ -6,7 +6,7 @@ config SPI_INFINEON_CAT1_HAL bool "Infineon CAT1 SPI driver" default y - depends on DT_HAS_INFINEON_CAT1_SPI_ENABLED + depends on DT_HAS_INFINEON_SPI_ENABLED depends on USE_INFINEON_LEGACY_HAL select USE_INFINEON_SPI select PINCTRL @@ -17,7 +17,7 @@ config SPI_INFINEON_CAT1_HAL config SPI_INFINEON_CAT1_PDL bool "Infineon CAT1 SPI driver" default y - depends on DT_HAS_INFINEON_CAT1_SPI_ENABLED + depends on DT_HAS_INFINEON_SPI_ENABLED depends on !USE_INFINEON_LEGACY_HAL select USE_INFINEON_SPI select PINCTRL diff --git a/drivers/spi/spi_infineon.c b/drivers/spi/spi_infineon.c index 2a1cf0b6a8bc..33bb70440853 100644 --- a/drivers/spi/spi_infineon.c +++ b/drivers/spi/spi_infineon.c @@ -5,7 +5,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#define DT_DRV_COMPAT infineon_cat1_spi +#define DT_DRV_COMPAT infineon_spi #define LOG_LEVEL CONFIG_SPI_LOG_LEVEL #include diff --git a/drivers/spi/spi_infineon_pdl.c b/drivers/spi/spi_infineon_pdl.c index c5ea19bb6ccd..22849fab9048 100644 --- a/drivers/spi/spi_infineon_pdl.c +++ b/drivers/spi/spi_infineon_pdl.c @@ -5,7 +5,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#define DT_DRV_COMPAT infineon_cat1_spi +#define DT_DRV_COMPAT infineon_spi #include LOG_MODULE_REGISTER(cat1_spi, CONFIG_SPI_LOG_LEVEL); diff --git a/drivers/timer/Kconfig.infineon_lp b/drivers/timer/Kconfig.infineon_lp index dc05bc7a1a86..8a5567cea74b 100644 --- a/drivers/timer/Kconfig.infineon_lp +++ b/drivers/timer/Kconfig.infineon_lp @@ -8,7 +8,7 @@ config INFINEON_CAT1_LP_TIMER bool "Infineon CAT1 Low Power Timer driver" default y - depends on DT_HAS_INFINEON_CAT1_LP_TIMER_ENABLED + depends on DT_HAS_INFINEON_LP_TIMER_ENABLED depends on PM select USE_INFINEON_LPTIMER select TICKLESS_CAPABLE diff --git a/drivers/timer/infineon_lp_timer.c b/drivers/timer/infineon_lp_timer.c index 6b49be7a20fb..7f830e9643ee 100644 --- a/drivers/timer/infineon_lp_timer.c +++ b/drivers/timer/infineon_lp_timer.c @@ -9,7 +9,7 @@ * @brief Low Power timer driver for Infineon CAT1 MCU family. */ -#define DT_DRV_COMPAT infineon_cat1_lp_timer +#define DT_DRV_COMPAT infineon_lp_timer #include #include diff --git a/drivers/watchdog/Kconfig.infineon b/drivers/watchdog/Kconfig.infineon index 94150064f898..84db861c6de2 100644 --- a/drivers/watchdog/Kconfig.infineon +++ b/drivers/watchdog/Kconfig.infineon @@ -8,7 +8,7 @@ config WDT_INFINEON_CAT1 bool "Infineon CAT1 Watchdog Driver" default y - depends on DT_HAS_INFINEON_CAT1_WATCHDOG_ENABLED + depends on DT_HAS_INFINEON_WATCHDOG_ENABLED select USE_INFINEON_WDT help Enable Watchdog driver for Infineon CAT1 devices. diff --git a/drivers/watchdog/wdt_infineon.c b/drivers/watchdog/wdt_infineon.c index da09eb1bb73c..7fdb7bc2b19b 100644 --- a/drivers/watchdog/wdt_infineon.c +++ b/drivers/watchdog/wdt_infineon.c @@ -7,7 +7,7 @@ /* Watchdog timer driver for the Infineon MCU family. */ -#define DT_DRV_COMPAT infineon_cat1_watchdog +#define DT_DRV_COMPAT infineon_watchdog #include "cy_wdt.h" #include "cy_sysclk.h" @@ -16,7 +16,7 @@ #include #include #include -LOG_MODULE_REGISTER(wdt_infineon_cat1, CONFIG_WDT_LOG_LEVEL); +LOG_MODULE_REGISTER(wdt_infineon, CONFIG_WDT_LOG_LEVEL); #define IFX_CAT1_WDT_IS_IRQ_EN DT_NODE_HAS_PROP(DT_DRV_INST(0), interrupts) diff --git a/dts/arm/infineon/cat1a/legacy/psoc6.dtsi b/dts/arm/infineon/cat1a/legacy/psoc6.dtsi index b5a4f9581bd9..af3a996a52ad 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 = "infineon,cat1-pinctrl"; + compatible = "infineon,pinctrl"; #address-cells = <1>; #size-cells = <1>; ranges = <0x40310000 0x40310000 0x2024>; diff --git a/dts/arm/infineon/cat1a/psoc6_01/psoc6_01.dtsi b/dts/arm/infineon/cat1a/psoc6_01/psoc6_01.dtsi index 50acc4c791b2..3543aa7155b2 100644 --- a/dts/arm/infineon/cat1a/psoc6_01/psoc6_01.dtsi +++ b/dts/arm/infineon/cat1a/psoc6_01/psoc6_01.dtsi @@ -26,7 +26,7 @@ }; flash-controller@40250000 { - compatible = "infineon,cat1-flash-controller"; + compatible = "infineon,flash-controller"; reg = <0x40250000 0x10000>; #address-cells = <1>; #size-cells = <1>; @@ -53,21 +53,21 @@ soc { pinctrl: pinctrl@40310000 { - compatible = "infineon,cat1-pinctrl"; + compatible = "infineon,pinctrl"; reg = <0x40310000 0x20000>; #address-cells = <1>; #size-cells = <0>; }; hsiom: hsiom@40310000 { - compatible = "infineon,cat1-hsiom"; + compatible = "infineon,hsiom"; reg = <0x40310000 0x4000>; interrupts = <15 6>, <16 6>; status = "disabled"; }; gpio_prt0: gpio@40320000 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40320000 0x80>; interrupts = <0 6>; gpio-controller; @@ -77,7 +77,7 @@ }; gpio_prt1: gpio@40320080 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40320080 0x80>; interrupts = <1 6>; gpio-controller; @@ -87,7 +87,7 @@ }; gpio_prt2: gpio@40320100 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40320100 0x80>; interrupts = <2 6>; gpio-controller; @@ -97,7 +97,7 @@ }; gpio_prt3: gpio@40320180 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40320180 0x80>; interrupts = <3 6>; gpio-controller; @@ -107,7 +107,7 @@ }; gpio_prt4: gpio@40320200 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40320200 0x80>; interrupts = <4 6>; gpio-controller; @@ -117,7 +117,7 @@ }; gpio_prt5: gpio@40320280 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40320280 0x80>; interrupts = <5 6>; gpio-controller; @@ -127,7 +127,7 @@ }; gpio_prt6: gpio@40320300 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40320300 0x80>; interrupts = <6 6>; gpio-controller; @@ -137,7 +137,7 @@ }; gpio_prt7: gpio@40320380 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40320380 0x80>; interrupts = <7 6>; gpio-controller; @@ -147,7 +147,7 @@ }; gpio_prt8: gpio@40320400 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40320400 0x80>; interrupts = <8 6>; gpio-controller; @@ -157,7 +157,7 @@ }; gpio_prt9: gpio@40320480 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40320480 0x80>; interrupts = <9 6>; gpio-controller; @@ -167,7 +167,7 @@ }; gpio_prt10: gpio@40320500 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40320500 0x80>; interrupts = <10 6>; gpio-controller; @@ -177,7 +177,7 @@ }; gpio_prt11: gpio@40320580 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40320580 0x80>; interrupts = <11 6>; gpio-controller; @@ -187,7 +187,7 @@ }; gpio_prt12: gpio@40320600 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40320600 0x80>; interrupts = <12 6>; gpio-controller; @@ -197,7 +197,7 @@ }; gpio_prt13: gpio@40320680 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40320680 0x80>; interrupts = <13 6>; gpio-controller; @@ -207,7 +207,7 @@ }; gpio_prt14: gpio@40320700 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40320700 0x80>; interrupts = <14 6>; gpio-controller; @@ -217,13 +217,13 @@ }; uid: device_uid@16000600 { - compatible = "infineon,cat1-uid"; + compatible = "infineon,uid"; reg = <0x16000600 0xb>; status = "disabled"; }; adc0: adc@411d0000 { - compatible = "infineon,cat1-adc"; + compatible = "infineon,adc"; reg = <0x411d0000 0x10000>; interrupts = <138 6>; status = "disabled"; @@ -231,7 +231,7 @@ }; scb0: scb@40610000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x40610000 0x10000>; #address-cells = <1>; #size-cells = <0>; @@ -240,7 +240,7 @@ }; scb1: scb@40620000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x40620000 0x10000>; #address-cells = <1>; #size-cells = <0>; @@ -249,7 +249,7 @@ }; scb2: scb@40630000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x40630000 0x10000>; #address-cells = <1>; #size-cells = <0>; @@ -258,7 +258,7 @@ }; scb3: scb@40640000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x40640000 0x10000>; #address-cells = <1>; #size-cells = <0>; @@ -267,7 +267,7 @@ }; scb4: scb@40650000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x40650000 0x10000>; #address-cells = <1>; #size-cells = <0>; @@ -276,7 +276,7 @@ }; scb5: scb@40660000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x40660000 0x10000>; #address-cells = <1>; #size-cells = <0>; @@ -285,7 +285,7 @@ }; scb6: scb@40670000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x40670000 0x10000>; #address-cells = <1>; #size-cells = <0>; @@ -294,7 +294,7 @@ }; scb7: scb@40680000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x40680000 0x10000>; #address-cells = <1>; #size-cells = <0>; @@ -303,7 +303,7 @@ }; scb8: scb@40690000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x40690000 0x10000>; #address-cells = <1>; #size-cells = <0>; @@ -312,34 +312,34 @@ }; timer0: timer@40260200 { - compatible = "infineon,cat1-timer"; + compatible = "infineon,timer"; reg = <0x40260200 0x40>; interrupts = <19 6>; status = "disabled"; }; timer1: timer@40260240 { - compatible = "infineon,cat1-timer"; + compatible = "infineon,timer"; reg = <0x40260240 0x40>; interrupts = <20 6>; status = "disabled"; }; watchdog0: watchdog@40260180 { - compatible = "infineon,cat1-watchdog"; + compatible = "infineon,watchdog"; reg = <0x40260180 0xc>; interrupts = <22 6>; status = "disabled"; }; bluetooth: bless { - compatible = "infineon,cat1-bless-hci"; + compatible = "infineon,bless-hci"; interrupts = <24 1>; status = "disabled"; }; counter0_0: counter@40380100 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40380100 0x40>; interrupts = <90 6>; resolution = <32>; @@ -347,7 +347,7 @@ }; counter0_1: counter@40380140 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40380140 0x40>; interrupts = <91 6>; resolution = <32>; @@ -355,7 +355,7 @@ }; counter0_2: counter@40380180 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40380180 0x40>; interrupts = <92 6>; resolution = <32>; @@ -363,7 +363,7 @@ }; counter0_3: counter@403801c0 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x403801c0 0x40>; interrupts = <93 6>; resolution = <32>; @@ -371,7 +371,7 @@ }; counter0_4: counter@40380200 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40380200 0x40>; interrupts = <94 6>; resolution = <32>; @@ -379,7 +379,7 @@ }; counter0_5: counter@40380240 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40380240 0x40>; interrupts = <95 6>; resolution = <32>; @@ -387,7 +387,7 @@ }; counter0_6: counter@40380280 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40380280 0x40>; interrupts = <96 6>; resolution = <32>; @@ -395,7 +395,7 @@ }; counter0_7: counter@403802c0 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x403802c0 0x40>; interrupts = <97 6>; resolution = <32>; @@ -403,7 +403,7 @@ }; counter1_0: counter@40390100 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40390100 0x40>; interrupts = <98 6>; resolution = <16>; @@ -411,7 +411,7 @@ }; counter1_1: counter@40390140 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40390140 0x40>; interrupts = <99 6>; resolution = <16>; @@ -419,7 +419,7 @@ }; counter1_2: counter@40390180 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40390180 0x40>; interrupts = <100 6>; resolution = <16>; @@ -427,7 +427,7 @@ }; counter1_3: counter@403901c0 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x403901c0 0x40>; interrupts = <101 6>; resolution = <16>; @@ -435,7 +435,7 @@ }; counter1_4: counter@40390200 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40390200 0x40>; interrupts = <102 6>; resolution = <16>; @@ -443,7 +443,7 @@ }; counter1_5: counter@40390240 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40390240 0x40>; interrupts = <103 6>; resolution = <16>; @@ -451,7 +451,7 @@ }; counter1_6: counter@40390280 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40390280 0x40>; interrupts = <104 6>; resolution = <16>; @@ -459,7 +459,7 @@ }; counter1_7: counter@403902c0 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x403902c0 0x40>; interrupts = <105 6>; resolution = <16>; @@ -467,7 +467,7 @@ }; counter1_8: counter@40390300 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40390300 0x40>; interrupts = <106 6>; resolution = <16>; @@ -475,7 +475,7 @@ }; counter1_9: counter@40390340 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40390340 0x40>; interrupts = <107 6>; resolution = <16>; @@ -483,7 +483,7 @@ }; counter1_10: counter@40390380 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40390380 0x40>; interrupts = <108 6>; resolution = <16>; @@ -491,7 +491,7 @@ }; counter1_11: counter@403903c0 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x403903c0 0x40>; interrupts = <109 6>; resolution = <16>; @@ -499,7 +499,7 @@ }; counter1_12: counter@40390400 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40390400 0x40>; interrupts = <110 6>; resolution = <16>; @@ -507,7 +507,7 @@ }; counter1_13: counter@40390440 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40390440 0x40>; interrupts = <111 6>; resolution = <16>; @@ -515,7 +515,7 @@ }; counter1_14: counter@40390480 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40390480 0x40>; interrupts = <112 6>; resolution = <16>; @@ -523,7 +523,7 @@ }; counter1_15: counter@403904c0 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x403904c0 0x40>; interrupts = <113 6>; resolution = <16>; @@ -531,7 +531,7 @@ }; counter1_16: counter@40390500 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40390500 0x40>; interrupts = <114 6>; resolution = <16>; @@ -539,7 +539,7 @@ }; counter1_17: counter@40390540 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40390540 0x40>; interrupts = <115 6>; resolution = <16>; @@ -547,7 +547,7 @@ }; counter1_18: counter@40390580 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40390580 0x40>; interrupts = <116 6>; resolution = <16>; @@ -555,7 +555,7 @@ }; counter1_19: counter@403905c0 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x403905c0 0x40>; interrupts = <117 6>; resolution = <16>; @@ -563,7 +563,7 @@ }; counter1_20: counter@40390600 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40390600 0x40>; interrupts = <118 6>; resolution = <16>; @@ -571,7 +571,7 @@ }; counter1_21: counter@40390640 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40390640 0x40>; interrupts = <119 6>; resolution = <16>; @@ -579,7 +579,7 @@ }; counter1_22: counter@40390680 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40390680 0x40>; interrupts = <120 6>; resolution = <16>; @@ -587,7 +587,7 @@ }; counter1_23: counter@403906c0 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x403906c0 0x40>; interrupts = <121 6>; resolution = <16>; @@ -595,7 +595,7 @@ }; sdhc0: sdhc@40460000 { - compatible = "infineon,cat1-sdhc-sdio"; + compatible = "infineon,sdhc-sdio"; reg = <0x40460000 0x2000>; interrupts = <164 6>; status = "disabled"; @@ -603,7 +603,7 @@ dma0: dw@40280000 { #dma-cells = <1>; - compatible = "infineon,cat1-dma"; + compatible = "infineon,dma"; reg = <0x40280000 0x8700>; dma-channels = <16>; interrupts = <50 6>, /* CH0 */ diff --git a/dts/arm/infineon/cat1a/psoc6_02/psoc6_02.dtsi b/dts/arm/infineon/cat1a/psoc6_02/psoc6_02.dtsi index 76a7387966ef..7deefa2541d3 100644 --- a/dts/arm/infineon/cat1a/psoc6_02/psoc6_02.dtsi +++ b/dts/arm/infineon/cat1a/psoc6_02/psoc6_02.dtsi @@ -26,7 +26,7 @@ }; flash-controller@40240000 { - compatible = "infineon,cat1-flash-controller"; + compatible = "infineon,flash-controller"; reg = <0x40240000 0x10000>; #address-cells = <1>; #size-cells = <1>; @@ -53,20 +53,20 @@ soc { pinctrl: pinctrl@40300000 { - compatible = "infineon,cat1-pinctrl"; + compatible = "infineon,pinctrl"; reg = <0x40300000 0x20000>; #address-cells = <1>; #size-cells = <0>; hsiom: hsiom@40300000 { - compatible = "infineon,cat1-hsiom"; + compatible = "infineon,hsiom"; reg = <0x40300000 0x4000>; interrupts = <15 6>, <16 6>; status = "disabled"; }; gpio_prt0: gpio@40310000 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40310000 0x80>; interrupts = <0 6>; gpio-controller; @@ -76,7 +76,7 @@ }; gpio_prt1: gpio@40310080 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40310080 0x80>; interrupts = <1 6>; gpio-controller; @@ -86,7 +86,7 @@ }; gpio_prt2: gpio@40310100 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40310100 0x80>; interrupts = <2 6>; gpio-controller; @@ -96,7 +96,7 @@ }; gpio_prt3: gpio@40310180 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40310180 0x80>; interrupts = <3 6>; gpio-controller; @@ -106,7 +106,7 @@ }; gpio_prt4: gpio@40310200 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40310200 0x80>; interrupts = <4 6>; gpio-controller; @@ -116,7 +116,7 @@ }; gpio_prt5: gpio@40310280 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40310280 0x80>; interrupts = <5 6>; gpio-controller; @@ -126,7 +126,7 @@ }; gpio_prt6: gpio@40310300 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40310300 0x80>; interrupts = <6 6>; gpio-controller; @@ -136,7 +136,7 @@ }; gpio_prt7: gpio@40310380 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40310380 0x80>; interrupts = <7 6>; gpio-controller; @@ -146,7 +146,7 @@ }; gpio_prt8: gpio@40310400 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40310400 0x80>; interrupts = <8 6>; gpio-controller; @@ -156,7 +156,7 @@ }; gpio_prt9: gpio@40310480 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40310480 0x80>; interrupts = <9 6>; gpio-controller; @@ -166,7 +166,7 @@ }; gpio_prt10: gpio@40310500 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40310500 0x80>; interrupts = <10 6>; gpio-controller; @@ -176,7 +176,7 @@ }; gpio_prt11: gpio@40310580 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40310580 0x80>; interrupts = <11 6>; gpio-controller; @@ -186,7 +186,7 @@ }; gpio_prt12: gpio@40310600 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40310600 0x80>; interrupts = <12 6>; gpio-controller; @@ -196,7 +196,7 @@ }; gpio_prt13: gpio@40310680 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40310680 0x80>; interrupts = <13 6>; gpio-controller; @@ -206,7 +206,7 @@ }; gpio_prt14: gpio@40310700 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40310700 0x80>; interrupts = <14 6>; gpio-controller; @@ -217,7 +217,7 @@ }; scb0: scb@40600000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x40600000 0x10000>; #address-cells = <1>; #size-cells = <0>; @@ -226,7 +226,7 @@ }; scb1: scb@40610000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x40610000 0x10000>; #address-cells = <1>; #size-cells = <0>; @@ -235,7 +235,7 @@ }; scb2: scb@40620000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x40620000 0x10000>; #address-cells = <1>; #size-cells = <0>; @@ -244,7 +244,7 @@ }; scb3: scb@40630000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x40630000 0x10000>; #address-cells = <1>; #size-cells = <0>; @@ -253,7 +253,7 @@ }; scb4: scb@40640000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x40640000 0x10000>; #address-cells = <1>; #size-cells = <0>; @@ -262,7 +262,7 @@ }; scb5: scb@40650000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x40650000 0x10000>; #address-cells = <1>; #size-cells = <0>; @@ -271,7 +271,7 @@ }; scb6: scb@40660000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x40660000 0x10000>; #address-cells = <1>; #size-cells = <0>; @@ -280,7 +280,7 @@ }; scb7: scb@40670000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x40670000 0x10000>; #address-cells = <1>; #size-cells = <0>; @@ -289,7 +289,7 @@ }; scb8: scb@40680000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x40680000 0x10000>; #address-cells = <1>; #size-cells = <0>; @@ -298,7 +298,7 @@ }; scb9: scb@40690000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x40690000 0x10000>; #address-cells = <1>; #size-cells = <0>; @@ -307,7 +307,7 @@ }; scb10: scb@406a0000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x406a0000 0x10000>; #address-cells = <1>; #size-cells = <0>; @@ -316,7 +316,7 @@ }; scb11: scb@406b0000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x406b0000 0x10000>; #address-cells = <1>; #size-cells = <0>; @@ -325,7 +325,7 @@ }; scb12: scb@406c0000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x406c0000 0x10000>; #address-cells = <1>; #size-cells = <0>; @@ -334,7 +334,7 @@ }; adc0: adc@409d0000 { - compatible = "infineon,cat1-adc"; + compatible = "infineon,adc"; reg = <0x409d0000 0x10000>; interrupts = <155 6>; status = "disabled"; @@ -342,14 +342,14 @@ }; watchdog0: watchdog@40260180 { - compatible = "infineon,cat1-watchdog"; + compatible = "infineon,watchdog"; reg = <0x40260180 0xc>; interrupts = <22 6>; status = "disabled"; }; counter0_0: counter@40380100 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40380100 0x40>; interrupts = <123 6>; resolution = <32>; @@ -357,7 +357,7 @@ }; counter0_1: counter@40380140 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40380140 0x40>; interrupts = <124 6>; resolution = <32>; @@ -365,7 +365,7 @@ }; counter0_2: counter@40380180 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40380180 0x40>; interrupts = <125 6>; resolution = <32>; @@ -373,7 +373,7 @@ }; counter0_3: counter@403801c0 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x403801c0 0x40>; interrupts = <126 6>; resolution = <32>; @@ -381,7 +381,7 @@ }; counter0_4: counter@40380200 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40380200 0x40>; interrupts = <127 6>; resolution = <32>; @@ -389,7 +389,7 @@ }; counter0_5: counter@40380240 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40380240 0x40>; interrupts = <128 6>; resolution = <32>; @@ -397,7 +397,7 @@ }; counter0_6: counter@40380280 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40380280 0x40>; interrupts = <129 6>; resolution = <32>; @@ -405,7 +405,7 @@ }; counter0_7: counter@403802c0 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x403802c0 0x40>; interrupts = <130 6>; resolution = <32>; @@ -413,7 +413,7 @@ }; counter1_0: counter@40390100 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40390100 0x40>; interrupts = <131 6>; resolution = <16>; @@ -421,7 +421,7 @@ }; counter1_1: counter@40390140 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40390140 0x40>; interrupts = <132 6>; resolution = <16>; @@ -429,7 +429,7 @@ }; counter1_2: counter@40390180 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40390180 0x40>; interrupts = <133 6>; resolution = <16>; @@ -437,7 +437,7 @@ }; counter1_3: counter@403901c0 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x403901c0 0x40>; interrupts = <134 6>; resolution = <16>; @@ -445,7 +445,7 @@ }; counter1_4: counter@40390200 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40390200 0x40>; interrupts = <135 6>; resolution = <16>; @@ -453,7 +453,7 @@ }; counter1_5: counter@40390240 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40390240 0x40>; interrupts = <136 6>; resolution = <16>; @@ -461,7 +461,7 @@ }; counter1_6: counter@40390280 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40390280 0x40>; interrupts = <137 6>; resolution = <16>; @@ -469,7 +469,7 @@ }; counter1_7: counter@403902c0 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x403902c0 0x40>; interrupts = <138 6>; resolution = <16>; @@ -477,7 +477,7 @@ }; counter1_8: counter@40390300 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40390300 0x40>; interrupts = <139 6>; resolution = <16>; @@ -485,7 +485,7 @@ }; counter1_9: counter@40390340 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40390340 0x40>; interrupts = <140 6>; resolution = <16>; @@ -493,7 +493,7 @@ }; counter1_10: counter@40390380 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40390380 0x40>; interrupts = <141 6>; resolution = <16>; @@ -501,7 +501,7 @@ }; counter1_11: counter@403903c0 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x403903c0 0x40>; interrupts = <142 6>; resolution = <16>; @@ -509,7 +509,7 @@ }; counter1_12: counter@40390400 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40390400 0x40>; interrupts = <143 6>; resolution = <16>; @@ -517,7 +517,7 @@ }; counter1_13: counter@40390440 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40390440 0x40>; interrupts = <144 6>; resolution = <16>; @@ -525,7 +525,7 @@ }; counter1_14: counter@40390480 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40390480 0x40>; interrupts = <145 6>; resolution = <16>; @@ -533,7 +533,7 @@ }; counter1_15: counter@403904c0 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x403904c0 0x40>; interrupts = <146 6>; resolution = <16>; @@ -541,7 +541,7 @@ }; counter1_16: counter@40390500 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40390500 0x40>; interrupts = <147 6>; resolution = <16>; @@ -549,7 +549,7 @@ }; counter1_17: counter@40390540 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40390540 0x40>; interrupts = <148 6>; resolution = <16>; @@ -557,7 +557,7 @@ }; counter1_18: counter@40390580 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40390580 0x40>; interrupts = <149 6>; resolution = <16>; @@ -565,7 +565,7 @@ }; counter1_19: counter@403905c0 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x403905c0 0x40>; interrupts = <150 6>; resolution = <16>; @@ -573,7 +573,7 @@ }; counter1_20: counter@40390600 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40390600 0x40>; interrupts = <151 6>; resolution = <16>; @@ -581,7 +581,7 @@ }; counter1_21: counter@40390640 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40390640 0x40>; interrupts = <152 6>; resolution = <16>; @@ -589,7 +589,7 @@ }; counter1_22: counter@40390680 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40390680 0x40>; interrupts = <153 6>; resolution = <16>; @@ -597,7 +597,7 @@ }; counter1_23: counter@403906c0 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x403906c0 0x40>; interrupts = <154 6>; resolution = <16>; @@ -605,7 +605,7 @@ }; sdhc0: sdhc@40460000 { - compatible = "infineon,cat1-sdhc-sdio"; + compatible = "infineon,sdhc-sdio"; reg = <0x40460000 0x2000>; interrupts = <164 6>; status = "disabled"; @@ -613,7 +613,7 @@ dma0: dw@40280000 { #dma-cells = <1>; - compatible = "infineon,cat1-dma"; + compatible = "infineon,dma"; reg = <0x40280000 0x8700>; dma-channels = <29>; interrupts = <56 6>, /* CH0 */ @@ -650,7 +650,7 @@ dma1: dw@40290000 { #dma-cells = <1>; - compatible = "infineon,cat1-dma"; + compatible = "infineon,dma"; reg = <0x40290000 0x8700>; dma-channels = <29>; interrupts = <85 6>, /* CH0 */ diff --git a/dts/arm/infineon/cat1a/psoc6_03/psoc6_03.dtsi b/dts/arm/infineon/cat1a/psoc6_03/psoc6_03.dtsi index a7c8f164e18a..ea099e3fe15e 100644 --- a/dts/arm/infineon/cat1a/psoc6_03/psoc6_03.dtsi +++ b/dts/arm/infineon/cat1a/psoc6_03/psoc6_03.dtsi @@ -26,7 +26,7 @@ }; flash-controller@40240000 { - compatible = "infineon,cat1-flash-controller"; + compatible = "infineon,flash-controller"; reg = <0x40240000 0x10000>; #address-cells = <1>; #size-cells = <1>; @@ -53,20 +53,20 @@ soc { pinctrl: pinctrl@40300000 { - compatible = "infineon,cat1-pinctrl"; + compatible = "infineon,pinctrl"; reg = <0x40300000 0x20000>; #address-cells = <1>; #size-cells = <0>; hsiom: hsiom@40300000 { - compatible = "infineon,cat1-hsiom"; + compatible = "infineon,hsiom"; reg = <0x40300000 0x4000>; interrupts = <15 6>, <16 6>; status = "disabled"; }; gpio_prt0: gpio@40310000 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40310000 0x80>; interrupts = <0 6>; gpio-controller; @@ -76,7 +76,7 @@ }; gpio_prt2: gpio@40310100 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40310100 0x80>; interrupts = <2 6>; gpio-controller; @@ -86,7 +86,7 @@ }; gpio_prt3: gpio@40310180 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40310180 0x80>; interrupts = <3 6>; gpio-controller; @@ -96,7 +96,7 @@ }; gpio_prt5: gpio@40310280 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40310280 0x80>; interrupts = <5 6>; gpio-controller; @@ -106,7 +106,7 @@ }; gpio_prt6: gpio@40310300 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40310300 0x80>; interrupts = <6 6>; gpio-controller; @@ -116,7 +116,7 @@ }; gpio_prt7: gpio@40310380 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40310380 0x80>; interrupts = <7 6>; gpio-controller; @@ -126,7 +126,7 @@ }; gpio_prt8: gpio@40310400 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40310400 0x80>; interrupts = <8 6>; gpio-controller; @@ -136,7 +136,7 @@ }; gpio_prt9: gpio@40310480 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40310480 0x80>; interrupts = <9 6>; gpio-controller; @@ -146,7 +146,7 @@ }; gpio_prt10: gpio@40310500 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40310500 0x80>; interrupts = <10 6>; gpio-controller; @@ -156,7 +156,7 @@ }; gpio_prt11: gpio@40310580 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40310580 0x80>; interrupts = <11 6>; gpio-controller; @@ -166,7 +166,7 @@ }; gpio_prt12: gpio@40310600 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40310600 0x80>; interrupts = <12 6>; gpio-controller; @@ -176,7 +176,7 @@ }; gpio_prt14: gpio@40310700 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40310700 0x80>; interrupts = <14 6>; gpio-controller; @@ -187,20 +187,20 @@ }; uid: device_uid@16000600 { - compatible = "infineon,cat1-uid"; + compatible = "infineon,uid"; reg = <0x16000600 0xb>; status = "disabled"; }; adc0: adc@409d0000 { - compatible = "infineon,cat1-adc"; + compatible = "infineon,adc"; reg = <0x409d0000 0x10000>; interrupts = <155 6>; status = "disabled"; }; scb0: scb@40600000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x40600000 0x10000>; #address-cells = <1>; #size-cells = <0>; @@ -209,7 +209,7 @@ }; scb1: scb@40610000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x40610000 0x10000>; #address-cells = <1>; #size-cells = <0>; @@ -218,7 +218,7 @@ }; scb2: scb@40620000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x40620000 0x10000>; #address-cells = <1>; #size-cells = <0>; @@ -227,7 +227,7 @@ }; scb3: scb@40630000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x40630000 0x10000>; #address-cells = <1>; #size-cells = <0>; @@ -236,7 +236,7 @@ }; scb4: scb@40640000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x40640000 0x10000>; #address-cells = <1>; #size-cells = <0>; @@ -245,7 +245,7 @@ }; scb5: scb@40650000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x40650000 0x10000>; #address-cells = <1>; #size-cells = <0>; @@ -254,7 +254,7 @@ }; scb6: scb@40660000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x40660000 0x10000>; #address-cells = <1>; #size-cells = <0>; @@ -263,7 +263,7 @@ }; sdhc0: sdhc@40460000 { - compatible = "infineon,cat1-sdhc-sdio"; + compatible = "infineon,sdhc-sdio"; reg = <0x40460000 0x2000>; interrupts = <164 6>; status = "disabled"; diff --git a/dts/arm/infineon/cat1a/psoc6_04/psoc6_04.dtsi b/dts/arm/infineon/cat1a/psoc6_04/psoc6_04.dtsi index 1bc68f3bb323..8b151c304363 100644 --- a/dts/arm/infineon/cat1a/psoc6_04/psoc6_04.dtsi +++ b/dts/arm/infineon/cat1a/psoc6_04/psoc6_04.dtsi @@ -26,7 +26,7 @@ }; flash-controller@40240000 { - compatible = "infineon,cat1-flash-controller"; + compatible = "infineon,flash-controller"; reg = <0x40240000 0x10000>; #address-cells = <1>; #size-cells = <1>; @@ -53,20 +53,20 @@ soc { pinctrl: pinctrl@40300000 { - compatible = "infineon,cat1-pinctrl"; + compatible = "infineon,pinctrl"; reg = <0x40300000 0x20000>; #address-cells = <1>; #size-cells = <0>; hsiom: hsiom@40300000 { - compatible = "infineon,cat1-hsiom"; + compatible = "infineon,hsiom"; reg = <0x40300000 0x4000>; interrupts = <15 6>, <16 6>; status = "disabled"; }; gpio_prt0: gpio@40310000 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40310000 0x80>; interrupts = <0 6>; gpio-controller; @@ -76,7 +76,7 @@ }; gpio_prt1: gpio@40310080 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40310080 0x80>; gpio-controller; ngpios = <3>; @@ -85,7 +85,7 @@ }; gpio_prt2: gpio@40310100 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40310100 0x80>; interrupts = <2 6>; gpio-controller; @@ -95,7 +95,7 @@ }; gpio_prt3: gpio@40310180 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40310180 0x80>; interrupts = <3 6>; gpio-controller; @@ -105,7 +105,7 @@ }; gpio_prt5: gpio@40310280 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40310280 0x80>; interrupts = <5 6>; gpio-controller; @@ -115,7 +115,7 @@ }; gpio_prt6: gpio@40310300 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40310300 0x80>; interrupts = <6 6>; gpio-controller; @@ -125,7 +125,7 @@ }; gpio_prt7: gpio@40310380 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40310380 0x80>; interrupts = <7 6>; gpio-controller; @@ -135,7 +135,7 @@ }; gpio_prt8: gpio@40310400 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40310400 0x80>; interrupts = <8 6>; gpio-controller; @@ -145,7 +145,7 @@ }; gpio_prt9: gpio@40310480 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40310480 0x80>; interrupts = <9 6>; gpio-controller; @@ -155,7 +155,7 @@ }; gpio_prt10: gpio@40310500 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40310500 0x80>; interrupts = <10 6>; gpio-controller; @@ -165,7 +165,7 @@ }; gpio_prt11: gpio@40310580 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40310580 0x80>; interrupts = <11 6>; gpio-controller; @@ -175,7 +175,7 @@ }; gpio_prt12: gpio@40310600 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40310600 0x80>; interrupts = <12 6>; gpio-controller; @@ -185,7 +185,7 @@ }; gpio_prt14: gpio@40310700 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40310700 0x80>; interrupts = <14 6>; gpio-controller; @@ -196,27 +196,27 @@ }; uid: device_uid@16000600 { - compatible = "infineon,cat1-uid"; + compatible = "infineon,uid"; reg = <0x16000600 0xb>; status = "disabled"; }; adc0: adc@409b0000 { - compatible = "infineon,cat1-adc"; + compatible = "infineon,adc"; reg = <0x409b0000 0x10000>; interrupts = <39 6>; status = "disabled"; }; adc1: adc@409c0000 { - compatible = "infineon,cat1-adc"; + compatible = "infineon,adc"; reg = <0x409c0000 0x10000>; interrupts = <40 6>; status = "disabled"; }; scb0: scb@40600000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x40600000 0x10000>; #address-cells = <1>; #size-cells = <0>; @@ -225,7 +225,7 @@ }; scb1: scb@40610000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x40610000 0x10000>; #address-cells = <1>; #size-cells = <0>; @@ -234,7 +234,7 @@ }; scb2: scb@40620000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x40620000 0x10000>; #address-cells = <1>; #size-cells = <0>; @@ -243,7 +243,7 @@ }; scb4: scb@40640000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x40640000 0x10000>; #address-cells = <1>; #size-cells = <0>; @@ -252,7 +252,7 @@ }; scb5: scb@40650000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x40650000 0x10000>; #address-cells = <1>; #size-cells = <0>; @@ -261,7 +261,7 @@ }; scb6: scb@40660000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x40660000 0x10000>; #address-cells = <1>; #size-cells = <0>; @@ -270,7 +270,7 @@ }; sdhc0: sdhc@40460000 { - compatible = "infineon,cat1-sdhc-sdio"; + compatible = "infineon,sdhc-sdio"; reg = <0x40460000 0x2000>; interrupts = <164 6>; status = "disabled"; diff --git a/dts/arm/infineon/cat1b/cyw20829/cyw20829.dtsi b/dts/arm/infineon/cat1b/cyw20829/cyw20829.dtsi index 588320a29148..ac6903faab97 100644 --- a/dts/arm/infineon/cat1b/cyw20829/cyw20829.dtsi +++ b/dts/arm/infineon/cat1b/cyw20829/cyw20829.dtsi @@ -16,19 +16,19 @@ soc { pinctrl: pinctrl@40400000 { - compatible = "infineon,cat1-pinctrl"; + compatible = "infineon,pinctrl"; reg = <0x40400000 0x20000>; }; hsiom: hsiom@40400000 { - compatible = "infineon,cat1-hsiom"; + compatible = "infineon,hsiom"; reg = <0x40400000 0x4000>; interrupts = <7 4>, <6 4>; status = "disabled"; }; gpio_prt0: gpio@40410000 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40410000 0x80>; interrupts = <0 4>; gpio-controller; @@ -38,7 +38,7 @@ }; gpio_prt1: gpio@40410080 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40410080 0x80>; interrupts = <1 4>; gpio-controller; @@ -48,7 +48,7 @@ }; gpio_prt2: gpio@40410100 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40410100 0x80>; interrupts = <2 4>; gpio-controller; @@ -58,7 +58,7 @@ }; gpio_prt3: gpio@40410180 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40410180 0x80>; interrupts = <3 4>; gpio-controller; @@ -68,7 +68,7 @@ }; gpio_prt4: gpio@40410200 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40410200 0x80>; interrupts = <4 4>; gpio-controller; @@ -78,7 +78,7 @@ }; gpio_prt5: gpio@40410280 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40410280 0x80>; interrupts = <5 4>; gpio-controller; @@ -88,7 +88,7 @@ }; adc0: adc@40520000 { - compatible = "infineon,cat1-adc"; + compatible = "infineon,adc"; reg = <0x40520000 0x264>; interrupts = <67 4>; status = "disabled"; @@ -96,49 +96,49 @@ }; ipc0: ipc@401d0000 { - compatible = "infineon,cat1-ipc"; + compatible = "infineon,ipc"; reg = <0x401d0000 0x1200>; status = "disabled"; #ipc-config-cells = <3>; }; scb0: scb@40590000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x40590000 0xfd0>; interrupts = <8 4>; status = "disabled"; }; scb1: scb@405a0000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x405a0000 0xfd0>; interrupts = <17 4>; status = "disabled"; }; scb2: scb@405b0000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x405b0000 0xfd0>; interrupts = <18 4>; status = "disabled"; }; watchdog0: watchdog@4020c000 { - compatible = "infineon,cat1-watchdog"; + compatible = "infineon,watchdog"; reg = <0x4020c000 0x10>; interrupts = <15 4>; status = "disabled"; }; mcwdt0: mcwdt@4020d000 { - compatible = "infineon,cat1-lp-timer"; + compatible = "infineon,lp-timer"; reg = <0x4020d000 0x40>; interrupts = <9 4>; status = "disabled"; }; rtc0: rtc@40220000 { - compatible = "infineon,cat1-rtc"; + compatible = "infineon,rtc"; reg = <0x40220000 0xff0c>; interrupts = <10 4>; alarms-count = <2>; @@ -330,7 +330,7 @@ dma0: dw@40180000 { #dma-cells = <1>; - compatible = "infineon,cat1-dma"; + compatible = "infineon,dma"; reg = <0x40180000 0x10000>; dma-channels = <16>; interrupts = <19 4>, /* CH0 */ diff --git a/dts/arm/infineon/cat1b/mpns/cyw20829b1240.dtsi b/dts/arm/infineon/cat1b/mpns/cyw20829b1240.dtsi index 361cfac2eb0c..5f173ed47507 100644 --- a/dts/arm/infineon/cat1b/mpns/cyw20829b1240.dtsi +++ b/dts/arm/infineon/cat1b/mpns/cyw20829b1240.dtsi @@ -13,7 +13,7 @@ / { qspi_flash: qspi_flash@40890000 { - compatible = "infineon,cat1-qspi-flash"; + compatible = "infineon,qspi-flash"; reg = <0x40890000 0x30000>; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/infineon/cat1b/mpns/cyw20829b1340.dtsi b/dts/arm/infineon/cat1b/mpns/cyw20829b1340.dtsi index 56eebf6dff4c..026c5f3850d8 100644 --- a/dts/arm/infineon/cat1b/mpns/cyw20829b1340.dtsi +++ b/dts/arm/infineon/cat1b/mpns/cyw20829b1340.dtsi @@ -13,7 +13,7 @@ / { qspi_flash: qspi_flash@40890000 { - compatible = "infineon,cat1-qspi-flash"; + compatible = "infineon,qspi-flash"; reg = <0x40890000 0x30000>; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/infineon/cat1b/mpns/cyw89829b0232.dtsi b/dts/arm/infineon/cat1b/mpns/cyw89829b0232.dtsi index d0acd8e635d9..8d571557136b 100644 --- a/dts/arm/infineon/cat1b/mpns/cyw89829b0232.dtsi +++ b/dts/arm/infineon/cat1b/mpns/cyw89829b0232.dtsi @@ -14,7 +14,7 @@ /* QSPI Flash is included in the processor package for this part. */ / { qspi_flash: qspi_flash@40890000 { - compatible = "infineon,cat1-qspi-flash"; + compatible = "infineon,qspi-flash"; reg = <0x40890000 0x30000>; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/infineon/cat1b/mpns/cyw89829b1232.dtsi b/dts/arm/infineon/cat1b/mpns/cyw89829b1232.dtsi index 830308b2b50a..7b41f53225a8 100644 --- a/dts/arm/infineon/cat1b/mpns/cyw89829b1232.dtsi +++ b/dts/arm/infineon/cat1b/mpns/cyw89829b1232.dtsi @@ -14,7 +14,7 @@ /* QSPI Flash is included in the processor package for this part. */ / { qspi_flash: qspi_flash@40890000 { - compatible = "infineon,cat1-qspi-flash"; + compatible = "infineon,qspi-flash"; reg = <0x40890000 0x30000>; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/infineon/cat1b/mpns/psc3m3edabq1.dtsi b/dts/arm/infineon/cat1b/mpns/psc3m3edabq1.dtsi index 194f91f6f338..84e73d4c8007 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3m3edabq1.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3m3edabq1.dtsi @@ -14,7 +14,7 @@ }; flash-controller@42150000 { - compatible = "infineon,cat1-flash-controller"; + compatible = "infineon,flash-controller"; reg = <0x42150000 0x10000>; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/infineon/cat1b/mpns/psc3m3edabq1_s.dtsi b/dts/arm/infineon/cat1b/mpns/psc3m3edabq1_s.dtsi index d0b652d5964c..0fa0a84728a7 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3m3edabq1_s.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3m3edabq1_s.dtsi @@ -14,7 +14,7 @@ }; flash-controller@52150000 { - compatible = "infineon,cat1-flash-controller"; + compatible = "infineon,flash-controller"; reg = <0x52150000 0x10000>; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/infineon/cat1b/mpns/psc3m3edacq1.dtsi b/dts/arm/infineon/cat1b/mpns/psc3m3edacq1.dtsi index 130d8eb5124e..425ba9ed10ab 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3m3edacq1.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3m3edacq1.dtsi @@ -14,7 +14,7 @@ }; flash-controller@42150000 { - compatible = "infineon,cat1-flash-controller"; + compatible = "infineon,flash-controller"; reg = <0x42150000 0x10000>; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/infineon/cat1b/mpns/psc3m3edacq1_s.dtsi b/dts/arm/infineon/cat1b/mpns/psc3m3edacq1_s.dtsi index 19a52afc8c33..1673003ebc62 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3m3edacq1_s.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3m3edacq1_s.dtsi @@ -14,7 +14,7 @@ }; flash-controller@52150000 { - compatible = "infineon,cat1-flash-controller"; + compatible = "infineon,flash-controller"; reg = <0x52150000 0x10000>; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/infineon/cat1b/mpns/psc3m3edlgq1.dtsi b/dts/arm/infineon/cat1b/mpns/psc3m3edlgq1.dtsi index 111eb90aeeed..227a338eeba1 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3m3edlgq1.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3m3edlgq1.dtsi @@ -14,7 +14,7 @@ }; flash-controller@42150000 { - compatible = "infineon,cat1-flash-controller"; + compatible = "infineon,flash-controller"; reg = <0x42150000 0x10000>; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/infineon/cat1b/mpns/psc3m3edlgq1_s.dtsi b/dts/arm/infineon/cat1b/mpns/psc3m3edlgq1_s.dtsi index cdf1e48b2232..14418ffe62ef 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3m3edlgq1_s.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3m3edlgq1_s.dtsi @@ -14,7 +14,7 @@ }; flash-controller@52150000 { - compatible = "infineon,cat1-flash-controller"; + compatible = "infineon,flash-controller"; reg = <0x52150000 0x10000>; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/infineon/cat1b/mpns/psc3m3edlhq1.dtsi b/dts/arm/infineon/cat1b/mpns/psc3m3edlhq1.dtsi index 594cc1ed0d98..800e0e835ec5 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3m3edlhq1.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3m3edlhq1.dtsi @@ -14,7 +14,7 @@ }; flash-controller@42150000 { - compatible = "infineon,cat1-flash-controller"; + compatible = "infineon,flash-controller"; reg = <0x42150000 0x10000>; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/infineon/cat1b/mpns/psc3m3edlhq1_s.dtsi b/dts/arm/infineon/cat1b/mpns/psc3m3edlhq1_s.dtsi index 729f412f29be..1cf6bafe84f3 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3m3edlhq1_s.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3m3edlhq1_s.dtsi @@ -14,7 +14,7 @@ }; flash-controller@52150000 { - compatible = "infineon,cat1-flash-controller"; + compatible = "infineon,flash-controller"; reg = <0x52150000 0x10000>; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/infineon/cat1b/mpns/psc3m3fds2abq1.dtsi b/dts/arm/infineon/cat1b/mpns/psc3m3fds2abq1.dtsi index c423fcf4d2e1..9b6d11aa340b 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3m3fds2abq1.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3m3fds2abq1.dtsi @@ -14,7 +14,7 @@ }; flash-controller@42150000 { - compatible = "infineon,cat1-flash-controller"; + compatible = "infineon,flash-controller"; reg = <0x42150000 0x10000>; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/infineon/cat1b/mpns/psc3m3fds2abq1_s.dtsi b/dts/arm/infineon/cat1b/mpns/psc3m3fds2abq1_s.dtsi index 372c07757615..0233102f3588 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3m3fds2abq1_s.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3m3fds2abq1_s.dtsi @@ -14,7 +14,7 @@ }; flash-controller@52150000 { - compatible = "infineon,cat1-flash-controller"; + compatible = "infineon,flash-controller"; reg = <0x52150000 0x10000>; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/infineon/cat1b/mpns/psc3m3fds2acq1.dtsi b/dts/arm/infineon/cat1b/mpns/psc3m3fds2acq1.dtsi index 806f9e53f52e..3076d8f81153 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3m3fds2acq1.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3m3fds2acq1.dtsi @@ -14,7 +14,7 @@ }; flash-controller@42150000 { - compatible = "infineon,cat1-flash-controller"; + compatible = "infineon,flash-controller"; reg = <0x42150000 0x10000>; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/infineon/cat1b/mpns/psc3m3fds2acq1_s.dtsi b/dts/arm/infineon/cat1b/mpns/psc3m3fds2acq1_s.dtsi index 77338f0e2a7a..1e38e0316e4c 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3m3fds2acq1_s.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3m3fds2acq1_s.dtsi @@ -14,7 +14,7 @@ }; flash-controller@52150000 { - compatible = "infineon,cat1-flash-controller"; + compatible = "infineon,flash-controller"; reg = <0x52150000 0x10000>; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/infineon/cat1b/mpns/psc3m3fds2lgq1.dtsi b/dts/arm/infineon/cat1b/mpns/psc3m3fds2lgq1.dtsi index 25e0eefa4e09..a64647479e69 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3m3fds2lgq1.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3m3fds2lgq1.dtsi @@ -14,7 +14,7 @@ }; flash-controller@42150000 { - compatible = "infineon,cat1-flash-controller"; + compatible = "infineon,flash-controller"; reg = <0x42150000 0x10000>; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/infineon/cat1b/mpns/psc3m3fds2lgq1_s.dtsi b/dts/arm/infineon/cat1b/mpns/psc3m3fds2lgq1_s.dtsi index 84f2ef2b2184..31fa1fa12544 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3m3fds2lgq1_s.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3m3fds2lgq1_s.dtsi @@ -14,7 +14,7 @@ }; flash-controller@52150000 { - compatible = "infineon,cat1-flash-controller"; + compatible = "infineon,flash-controller"; reg = <0x52150000 0x10000>; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/infineon/cat1b/mpns/psc3m3fds2lhq1.dtsi b/dts/arm/infineon/cat1b/mpns/psc3m3fds2lhq1.dtsi index 73d6eb9dbdf2..091f6b451977 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3m3fds2lhq1.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3m3fds2lhq1.dtsi @@ -14,7 +14,7 @@ }; flash-controller@42150000 { - compatible = "infineon,cat1-flash-controller"; + compatible = "infineon,flash-controller"; reg = <0x42150000 0x10000>; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/infineon/cat1b/mpns/psc3m3fds2lhq1_s.dtsi b/dts/arm/infineon/cat1b/mpns/psc3m3fds2lhq1_s.dtsi index 5a792b4a3593..dbe341f5f20e 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3m3fds2lhq1_s.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3m3fds2lhq1_s.dtsi @@ -14,7 +14,7 @@ }; flash-controller@52150000 { - compatible = "infineon,cat1-flash-controller"; + compatible = "infineon,flash-controller"; reg = <0x52150000 0x10000>; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/infineon/cat1b/mpns/psc3m5edabq1.dtsi b/dts/arm/infineon/cat1b/mpns/psc3m5edabq1.dtsi index 46f36f43caed..58a4ceeee120 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3m5edabq1.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3m5edabq1.dtsi @@ -10,7 +10,7 @@ / { flash-controller@42150000 { - compatible = "infineon,cat1-flash-controller"; + compatible = "infineon,flash-controller"; reg = <0x42150000 0x10000>; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/infineon/cat1b/mpns/psc3m5edabq1_s.dtsi b/dts/arm/infineon/cat1b/mpns/psc3m5edabq1_s.dtsi index 3224c022eb93..4058b054d148 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3m5edabq1_s.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3m5edabq1_s.dtsi @@ -10,7 +10,7 @@ / { flash-controller@52150000 { - compatible = "infineon,cat1-flash-controller"; + compatible = "infineon,flash-controller"; reg = <0x52150000 0x10000>; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/infineon/cat1b/mpns/psc3m5edacq1.dtsi b/dts/arm/infineon/cat1b/mpns/psc3m5edacq1.dtsi index 213cc9a87b9c..126687522e89 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3m5edacq1.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3m5edacq1.dtsi @@ -10,7 +10,7 @@ / { flash-controller@42150000 { - compatible = "infineon,cat1-flash-controller"; + compatible = "infineon,flash-controller"; reg = <0x42150000 0x10000>; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/infineon/cat1b/mpns/psc3m5edacq1_s.dtsi b/dts/arm/infineon/cat1b/mpns/psc3m5edacq1_s.dtsi index 67e8788e884f..3ca533edfc4c 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3m5edacq1_s.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3m5edacq1_s.dtsi @@ -10,7 +10,7 @@ / { flash-controller@52150000 { - compatible = "infineon,cat1-flash-controller"; + compatible = "infineon,flash-controller"; reg = <0x52150000 0x10000>; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/infineon/cat1b/mpns/psc3m5edafq1.dtsi b/dts/arm/infineon/cat1b/mpns/psc3m5edafq1.dtsi index 0b923f217d01..edf9fced733e 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3m5edafq1.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3m5edafq1.dtsi @@ -10,7 +10,7 @@ / { flash-controller@42150000 { - compatible = "infineon,cat1-flash-controller"; + compatible = "infineon,flash-controller"; reg = <0x42150000 0x10000>; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/infineon/cat1b/mpns/psc3m5edafq1_s.dtsi b/dts/arm/infineon/cat1b/mpns/psc3m5edafq1_s.dtsi index 5ef19a15151c..4cb94d93957a 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3m5edafq1_s.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3m5edafq1_s.dtsi @@ -10,7 +10,7 @@ / { flash-controller@52150000 { - compatible = "infineon,cat1-flash-controller"; + compatible = "infineon,flash-controller"; reg = <0x52150000 0x10000>; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/infineon/cat1b/mpns/psc3m5edlgq1.dtsi b/dts/arm/infineon/cat1b/mpns/psc3m5edlgq1.dtsi index 831e72573ed9..fe2ee156497e 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3m5edlgq1.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3m5edlgq1.dtsi @@ -10,7 +10,7 @@ / { flash-controller@42150000 { - compatible = "infineon,cat1-flash-controller"; + compatible = "infineon,flash-controller"; reg = <0x42150000 0x10000>; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/infineon/cat1b/mpns/psc3m5edlgq1_s.dtsi b/dts/arm/infineon/cat1b/mpns/psc3m5edlgq1_s.dtsi index eca75efebc87..ca986e03dba8 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3m5edlgq1_s.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3m5edlgq1_s.dtsi @@ -10,7 +10,7 @@ / { flash-controller@52150000 { - compatible = "infineon,cat1-flash-controller"; + compatible = "infineon,flash-controller"; reg = <0x52150000 0x10000>; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/infineon/cat1b/mpns/psc3m5edlhq1.dtsi b/dts/arm/infineon/cat1b/mpns/psc3m5edlhq1.dtsi index b097355818eb..c39890bcf81b 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3m5edlhq1.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3m5edlhq1.dtsi @@ -10,7 +10,7 @@ / { flash-controller@42150000 { - compatible = "infineon,cat1-flash-controller"; + compatible = "infineon,flash-controller"; reg = <0x42150000 0x10000>; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/infineon/cat1b/mpns/psc3m5edlhq1_s.dtsi b/dts/arm/infineon/cat1b/mpns/psc3m5edlhq1_s.dtsi index ff5891cd0c07..7bc908ea2b38 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3m5edlhq1_s.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3m5edlhq1_s.dtsi @@ -10,7 +10,7 @@ / { flash-controller@52150000 { - compatible = "infineon,cat1-flash-controller"; + compatible = "infineon,flash-controller"; reg = <0x52150000 0x10000>; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/infineon/cat1b/mpns/psc3m5fds2abq1.dtsi b/dts/arm/infineon/cat1b/mpns/psc3m5fds2abq1.dtsi index 0bd030ef49c8..0a4c8a1b4ab0 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3m5fds2abq1.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3m5fds2abq1.dtsi @@ -10,7 +10,7 @@ / { flash-controller@42150000 { - compatible = "infineon,cat1-flash-controller"; + compatible = "infineon,flash-controller"; reg = <0x42150000 0x10000>; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/infineon/cat1b/mpns/psc3m5fds2abq1_s.dtsi b/dts/arm/infineon/cat1b/mpns/psc3m5fds2abq1_s.dtsi index c9400633b761..f38f0c7d95dc 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3m5fds2abq1_s.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3m5fds2abq1_s.dtsi @@ -10,7 +10,7 @@ / { flash-controller@52150000 { - compatible = "infineon,cat1-flash-controller"; + compatible = "infineon,flash-controller"; reg = <0x52150000 0x10000>; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/infineon/cat1b/mpns/psc3m5fds2acq1.dtsi b/dts/arm/infineon/cat1b/mpns/psc3m5fds2acq1.dtsi index a323cc485598..cf37e341eb01 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3m5fds2acq1.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3m5fds2acq1.dtsi @@ -10,7 +10,7 @@ / { flash-controller@42150000 { - compatible = "infineon,cat1-flash-controller"; + compatible = "infineon,flash-controller"; reg = <0x42150000 0x10000>; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/infineon/cat1b/mpns/psc3m5fds2acq1_s.dtsi b/dts/arm/infineon/cat1b/mpns/psc3m5fds2acq1_s.dtsi index 5bdad6716cbe..dd965b5d93ba 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3m5fds2acq1_s.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3m5fds2acq1_s.dtsi @@ -10,7 +10,7 @@ / { flash-controller@52150000 { - compatible = "infineon,cat1-flash-controller"; + compatible = "infineon,flash-controller"; reg = <0x52150000 0x10000>; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/infineon/cat1b/mpns/psc3m5fds2afq1.dtsi b/dts/arm/infineon/cat1b/mpns/psc3m5fds2afq1.dtsi index cde246f4c7cb..bb03f5b0c815 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3m5fds2afq1.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3m5fds2afq1.dtsi @@ -10,7 +10,7 @@ / { flash-controller@42150000 { - compatible = "infineon,cat1-flash-controller"; + compatible = "infineon,flash-controller"; reg = <0x42150000 0x10000>; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/infineon/cat1b/mpns/psc3m5fds2afq1_s.dtsi b/dts/arm/infineon/cat1b/mpns/psc3m5fds2afq1_s.dtsi index 21351f78a3ad..11ea1663e6a5 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3m5fds2afq1_s.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3m5fds2afq1_s.dtsi @@ -10,7 +10,7 @@ / { flash-controller@52150000 { - compatible = "infineon,cat1-flash-controller"; + compatible = "infineon,flash-controller"; reg = <0x52150000 0x10000>; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/infineon/cat1b/mpns/psc3m5fds2lgq1.dtsi b/dts/arm/infineon/cat1b/mpns/psc3m5fds2lgq1.dtsi index d2550d306e89..2d03f3f86fca 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3m5fds2lgq1.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3m5fds2lgq1.dtsi @@ -10,7 +10,7 @@ / { flash-controller@42150000 { - compatible = "infineon,cat1-flash-controller"; + compatible = "infineon,flash-controller"; reg = <0x42150000 0x10000>; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/infineon/cat1b/mpns/psc3m5fds2lgq1_s.dtsi b/dts/arm/infineon/cat1b/mpns/psc3m5fds2lgq1_s.dtsi index a9eef5a832ac..0c3da22f29e1 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3m5fds2lgq1_s.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3m5fds2lgq1_s.dtsi @@ -10,7 +10,7 @@ / { flash-controller@52150000 { - compatible = "infineon,cat1-flash-controller"; + compatible = "infineon,flash-controller"; reg = <0x52150000 0x10000>; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/infineon/cat1b/mpns/psc3m5fds2lhq1.dtsi b/dts/arm/infineon/cat1b/mpns/psc3m5fds2lhq1.dtsi index 328c360a707c..48831c6d5bb1 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3m5fds2lhq1.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3m5fds2lhq1.dtsi @@ -10,7 +10,7 @@ / { flash-controller@42150000 { - compatible = "infineon,cat1-flash-controller"; + compatible = "infineon,flash-controller"; reg = <0x42150000 0x10000>; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/infineon/cat1b/mpns/psc3m5fds2lhq1_s.dtsi b/dts/arm/infineon/cat1b/mpns/psc3m5fds2lhq1_s.dtsi index 92750743b64b..90bb53f27f50 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3m5fds2lhq1_s.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3m5fds2lhq1_s.dtsi @@ -10,7 +10,7 @@ / { flash-controller@52150000 { - compatible = "infineon,cat1-flash-controller"; + compatible = "infineon,flash-controller"; reg = <0x52150000 0x10000>; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/infineon/cat1b/mpns/psc3p2edabq1.dtsi b/dts/arm/infineon/cat1b/mpns/psc3p2edabq1.dtsi index 194f91f6f338..84e73d4c8007 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3p2edabq1.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3p2edabq1.dtsi @@ -14,7 +14,7 @@ }; flash-controller@42150000 { - compatible = "infineon,cat1-flash-controller"; + compatible = "infineon,flash-controller"; reg = <0x42150000 0x10000>; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/infineon/cat1b/mpns/psc3p2edabq1_s.dtsi b/dts/arm/infineon/cat1b/mpns/psc3p2edabq1_s.dtsi index d0b652d5964c..0fa0a84728a7 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3p2edabq1_s.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3p2edabq1_s.dtsi @@ -14,7 +14,7 @@ }; flash-controller@52150000 { - compatible = "infineon,cat1-flash-controller"; + compatible = "infineon,flash-controller"; reg = <0x52150000 0x10000>; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/infineon/cat1b/mpns/psc3p2edacq1.dtsi b/dts/arm/infineon/cat1b/mpns/psc3p2edacq1.dtsi index 130d8eb5124e..425ba9ed10ab 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3p2edacq1.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3p2edacq1.dtsi @@ -14,7 +14,7 @@ }; flash-controller@42150000 { - compatible = "infineon,cat1-flash-controller"; + compatible = "infineon,flash-controller"; reg = <0x42150000 0x10000>; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/infineon/cat1b/mpns/psc3p2edacq1_s.dtsi b/dts/arm/infineon/cat1b/mpns/psc3p2edacq1_s.dtsi index 19a52afc8c33..1673003ebc62 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3p2edacq1_s.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3p2edacq1_s.dtsi @@ -14,7 +14,7 @@ }; flash-controller@52150000 { - compatible = "infineon,cat1-flash-controller"; + compatible = "infineon,flash-controller"; reg = <0x52150000 0x10000>; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/infineon/cat1b/mpns/psc3p2edlgq1.dtsi b/dts/arm/infineon/cat1b/mpns/psc3p2edlgq1.dtsi index 111eb90aeeed..227a338eeba1 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3p2edlgq1.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3p2edlgq1.dtsi @@ -14,7 +14,7 @@ }; flash-controller@42150000 { - compatible = "infineon,cat1-flash-controller"; + compatible = "infineon,flash-controller"; reg = <0x42150000 0x10000>; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/infineon/cat1b/mpns/psc3p2edlgq1_s.dtsi b/dts/arm/infineon/cat1b/mpns/psc3p2edlgq1_s.dtsi index cdf1e48b2232..14418ffe62ef 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3p2edlgq1_s.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3p2edlgq1_s.dtsi @@ -14,7 +14,7 @@ }; flash-controller@52150000 { - compatible = "infineon,cat1-flash-controller"; + compatible = "infineon,flash-controller"; reg = <0x52150000 0x10000>; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/infineon/cat1b/mpns/psc3p2edlhq1.dtsi b/dts/arm/infineon/cat1b/mpns/psc3p2edlhq1.dtsi index 594cc1ed0d98..800e0e835ec5 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3p2edlhq1.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3p2edlhq1.dtsi @@ -14,7 +14,7 @@ }; flash-controller@42150000 { - compatible = "infineon,cat1-flash-controller"; + compatible = "infineon,flash-controller"; reg = <0x42150000 0x10000>; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/infineon/cat1b/mpns/psc3p2edlhq1_s.dtsi b/dts/arm/infineon/cat1b/mpns/psc3p2edlhq1_s.dtsi index 729f412f29be..1cf6bafe84f3 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3p2edlhq1_s.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3p2edlhq1_s.dtsi @@ -14,7 +14,7 @@ }; flash-controller@52150000 { - compatible = "infineon,cat1-flash-controller"; + compatible = "infineon,flash-controller"; reg = <0x52150000 0x10000>; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/infineon/cat1b/mpns/psc3p2fds2abq1.dtsi b/dts/arm/infineon/cat1b/mpns/psc3p2fds2abq1.dtsi index c423fcf4d2e1..9b6d11aa340b 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3p2fds2abq1.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3p2fds2abq1.dtsi @@ -14,7 +14,7 @@ }; flash-controller@42150000 { - compatible = "infineon,cat1-flash-controller"; + compatible = "infineon,flash-controller"; reg = <0x42150000 0x10000>; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/infineon/cat1b/mpns/psc3p2fds2abq1_s.dtsi b/dts/arm/infineon/cat1b/mpns/psc3p2fds2abq1_s.dtsi index 372c07757615..0233102f3588 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3p2fds2abq1_s.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3p2fds2abq1_s.dtsi @@ -14,7 +14,7 @@ }; flash-controller@52150000 { - compatible = "infineon,cat1-flash-controller"; + compatible = "infineon,flash-controller"; reg = <0x52150000 0x10000>; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/infineon/cat1b/mpns/psc3p2fds2acq1.dtsi b/dts/arm/infineon/cat1b/mpns/psc3p2fds2acq1.dtsi index 806f9e53f52e..3076d8f81153 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3p2fds2acq1.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3p2fds2acq1.dtsi @@ -14,7 +14,7 @@ }; flash-controller@42150000 { - compatible = "infineon,cat1-flash-controller"; + compatible = "infineon,flash-controller"; reg = <0x42150000 0x10000>; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/infineon/cat1b/mpns/psc3p2fds2acq1_s.dtsi b/dts/arm/infineon/cat1b/mpns/psc3p2fds2acq1_s.dtsi index 77338f0e2a7a..1e38e0316e4c 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3p2fds2acq1_s.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3p2fds2acq1_s.dtsi @@ -14,7 +14,7 @@ }; flash-controller@52150000 { - compatible = "infineon,cat1-flash-controller"; + compatible = "infineon,flash-controller"; reg = <0x52150000 0x10000>; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/infineon/cat1b/mpns/psc3p2fds2lgq1.dtsi b/dts/arm/infineon/cat1b/mpns/psc3p2fds2lgq1.dtsi index 25e0eefa4e09..a64647479e69 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3p2fds2lgq1.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3p2fds2lgq1.dtsi @@ -14,7 +14,7 @@ }; flash-controller@42150000 { - compatible = "infineon,cat1-flash-controller"; + compatible = "infineon,flash-controller"; reg = <0x42150000 0x10000>; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/infineon/cat1b/mpns/psc3p2fds2lgq1_s.dtsi b/dts/arm/infineon/cat1b/mpns/psc3p2fds2lgq1_s.dtsi index 84f2ef2b2184..31fa1fa12544 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3p2fds2lgq1_s.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3p2fds2lgq1_s.dtsi @@ -14,7 +14,7 @@ }; flash-controller@52150000 { - compatible = "infineon,cat1-flash-controller"; + compatible = "infineon,flash-controller"; reg = <0x52150000 0x10000>; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/infineon/cat1b/mpns/psc3p2fds2lhq1.dtsi b/dts/arm/infineon/cat1b/mpns/psc3p2fds2lhq1.dtsi index 73d6eb9dbdf2..091f6b451977 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3p2fds2lhq1.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3p2fds2lhq1.dtsi @@ -14,7 +14,7 @@ }; flash-controller@42150000 { - compatible = "infineon,cat1-flash-controller"; + compatible = "infineon,flash-controller"; reg = <0x42150000 0x10000>; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/infineon/cat1b/mpns/psc3p2fds2lhq1_s.dtsi b/dts/arm/infineon/cat1b/mpns/psc3p2fds2lhq1_s.dtsi index 5a792b4a3593..dbe341f5f20e 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3p2fds2lhq1_s.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3p2fds2lhq1_s.dtsi @@ -14,7 +14,7 @@ }; flash-controller@52150000 { - compatible = "infineon,cat1-flash-controller"; + compatible = "infineon,flash-controller"; reg = <0x52150000 0x10000>; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/infineon/cat1b/mpns/psc3p5edabq1.dtsi b/dts/arm/infineon/cat1b/mpns/psc3p5edabq1.dtsi index 46f36f43caed..58a4ceeee120 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3p5edabq1.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3p5edabq1.dtsi @@ -10,7 +10,7 @@ / { flash-controller@42150000 { - compatible = "infineon,cat1-flash-controller"; + compatible = "infineon,flash-controller"; reg = <0x42150000 0x10000>; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/infineon/cat1b/mpns/psc3p5edabq1_s.dtsi b/dts/arm/infineon/cat1b/mpns/psc3p5edabq1_s.dtsi index 3224c022eb93..4058b054d148 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3p5edabq1_s.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3p5edabq1_s.dtsi @@ -10,7 +10,7 @@ / { flash-controller@52150000 { - compatible = "infineon,cat1-flash-controller"; + compatible = "infineon,flash-controller"; reg = <0x52150000 0x10000>; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/infineon/cat1b/mpns/psc3p5edacq1.dtsi b/dts/arm/infineon/cat1b/mpns/psc3p5edacq1.dtsi index 213cc9a87b9c..126687522e89 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3p5edacq1.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3p5edacq1.dtsi @@ -10,7 +10,7 @@ / { flash-controller@42150000 { - compatible = "infineon,cat1-flash-controller"; + compatible = "infineon,flash-controller"; reg = <0x42150000 0x10000>; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/infineon/cat1b/mpns/psc3p5edacq1_s.dtsi b/dts/arm/infineon/cat1b/mpns/psc3p5edacq1_s.dtsi index 67e8788e884f..3ca533edfc4c 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3p5edacq1_s.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3p5edacq1_s.dtsi @@ -10,7 +10,7 @@ / { flash-controller@52150000 { - compatible = "infineon,cat1-flash-controller"; + compatible = "infineon,flash-controller"; reg = <0x52150000 0x10000>; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/infineon/cat1b/mpns/psc3p5edlgq1.dtsi b/dts/arm/infineon/cat1b/mpns/psc3p5edlgq1.dtsi index 831e72573ed9..fe2ee156497e 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3p5edlgq1.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3p5edlgq1.dtsi @@ -10,7 +10,7 @@ / { flash-controller@42150000 { - compatible = "infineon,cat1-flash-controller"; + compatible = "infineon,flash-controller"; reg = <0x42150000 0x10000>; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/infineon/cat1b/mpns/psc3p5edlgq1_s.dtsi b/dts/arm/infineon/cat1b/mpns/psc3p5edlgq1_s.dtsi index eca75efebc87..ca986e03dba8 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3p5edlgq1_s.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3p5edlgq1_s.dtsi @@ -10,7 +10,7 @@ / { flash-controller@52150000 { - compatible = "infineon,cat1-flash-controller"; + compatible = "infineon,flash-controller"; reg = <0x52150000 0x10000>; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/infineon/cat1b/mpns/psc3p5edlhq1.dtsi b/dts/arm/infineon/cat1b/mpns/psc3p5edlhq1.dtsi index b097355818eb..c39890bcf81b 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3p5edlhq1.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3p5edlhq1.dtsi @@ -10,7 +10,7 @@ / { flash-controller@42150000 { - compatible = "infineon,cat1-flash-controller"; + compatible = "infineon,flash-controller"; reg = <0x42150000 0x10000>; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/infineon/cat1b/mpns/psc3p5edlhq1_s.dtsi b/dts/arm/infineon/cat1b/mpns/psc3p5edlhq1_s.dtsi index ff5891cd0c07..7bc908ea2b38 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3p5edlhq1_s.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3p5edlhq1_s.dtsi @@ -10,7 +10,7 @@ / { flash-controller@52150000 { - compatible = "infineon,cat1-flash-controller"; + compatible = "infineon,flash-controller"; reg = <0x52150000 0x10000>; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/infineon/cat1b/mpns/psc3p5fds2abq1.dtsi b/dts/arm/infineon/cat1b/mpns/psc3p5fds2abq1.dtsi index 0bd030ef49c8..0a4c8a1b4ab0 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3p5fds2abq1.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3p5fds2abq1.dtsi @@ -10,7 +10,7 @@ / { flash-controller@42150000 { - compatible = "infineon,cat1-flash-controller"; + compatible = "infineon,flash-controller"; reg = <0x42150000 0x10000>; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/infineon/cat1b/mpns/psc3p5fds2abq1_s.dtsi b/dts/arm/infineon/cat1b/mpns/psc3p5fds2abq1_s.dtsi index c9400633b761..f38f0c7d95dc 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3p5fds2abq1_s.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3p5fds2abq1_s.dtsi @@ -10,7 +10,7 @@ / { flash-controller@52150000 { - compatible = "infineon,cat1-flash-controller"; + compatible = "infineon,flash-controller"; reg = <0x52150000 0x10000>; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/infineon/cat1b/mpns/psc3p5fds2acq1.dtsi b/dts/arm/infineon/cat1b/mpns/psc3p5fds2acq1.dtsi index a323cc485598..cf37e341eb01 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3p5fds2acq1.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3p5fds2acq1.dtsi @@ -10,7 +10,7 @@ / { flash-controller@42150000 { - compatible = "infineon,cat1-flash-controller"; + compatible = "infineon,flash-controller"; reg = <0x42150000 0x10000>; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/infineon/cat1b/mpns/psc3p5fds2acq1_s.dtsi b/dts/arm/infineon/cat1b/mpns/psc3p5fds2acq1_s.dtsi index 5bdad6716cbe..dd965b5d93ba 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3p5fds2acq1_s.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3p5fds2acq1_s.dtsi @@ -10,7 +10,7 @@ / { flash-controller@52150000 { - compatible = "infineon,cat1-flash-controller"; + compatible = "infineon,flash-controller"; reg = <0x52150000 0x10000>; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/infineon/cat1b/mpns/psc3p5fds2lgq1.dtsi b/dts/arm/infineon/cat1b/mpns/psc3p5fds2lgq1.dtsi index d2550d306e89..2d03f3f86fca 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3p5fds2lgq1.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3p5fds2lgq1.dtsi @@ -10,7 +10,7 @@ / { flash-controller@42150000 { - compatible = "infineon,cat1-flash-controller"; + compatible = "infineon,flash-controller"; reg = <0x42150000 0x10000>; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/infineon/cat1b/mpns/psc3p5fds2lgq1_s.dtsi b/dts/arm/infineon/cat1b/mpns/psc3p5fds2lgq1_s.dtsi index a9eef5a832ac..0c3da22f29e1 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3p5fds2lgq1_s.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3p5fds2lgq1_s.dtsi @@ -10,7 +10,7 @@ / { flash-controller@52150000 { - compatible = "infineon,cat1-flash-controller"; + compatible = "infineon,flash-controller"; reg = <0x52150000 0x10000>; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/infineon/cat1b/mpns/psc3p5fds2lhq1.dtsi b/dts/arm/infineon/cat1b/mpns/psc3p5fds2lhq1.dtsi index 328c360a707c..48831c6d5bb1 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3p5fds2lhq1.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3p5fds2lhq1.dtsi @@ -10,7 +10,7 @@ / { flash-controller@42150000 { - compatible = "infineon,cat1-flash-controller"; + compatible = "infineon,flash-controller"; reg = <0x42150000 0x10000>; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/infineon/cat1b/mpns/psc3p5fds2lhq1_s.dtsi b/dts/arm/infineon/cat1b/mpns/psc3p5fds2lhq1_s.dtsi index 92750743b64b..90bb53f27f50 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3p5fds2lhq1_s.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3p5fds2lhq1_s.dtsi @@ -10,7 +10,7 @@ / { flash-controller@52150000 { - compatible = "infineon,cat1-flash-controller"; + compatible = "infineon,flash-controller"; reg = <0x52150000 0x10000>; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/infineon/cat1b/psc3/psc3.dtsi b/dts/arm/infineon/cat1b/psc3/psc3.dtsi index ab3ab6671f38..af69a69509b7 100644 --- a/dts/arm/infineon/cat1b/psc3/psc3.dtsi +++ b/dts/arm/infineon/cat1b/psc3/psc3.dtsi @@ -17,19 +17,19 @@ soc { pinctrl: pinctrl@42400000 { - compatible = "infineon,cat1-pinctrl"; + compatible = "infineon,pinctrl"; reg = <0x42400000 0x20000>; }; hsiom: hsiom@42400000 { - compatible = "infineon,cat1-hsiom"; + compatible = "infineon,hsiom"; reg = <0x42400000 0x4000>; interrupts = <21 4>, <20 4>; status = "disabled"; }; gpio_prt0: gpio@42410000 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x42410000 0x80>; interrupts = <0 4>; gpio-controller; @@ -39,7 +39,7 @@ }; gpio_prt1: gpio@42410080 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x42410080 0x80>; interrupts = <1 4>; gpio-controller; @@ -49,7 +49,7 @@ }; gpio_prt2: gpio@42410100 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x42410100 0x80>; interrupts = <2 4>; gpio-controller; @@ -59,7 +59,7 @@ }; gpio_prt3: gpio@42410180 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x42410180 0x80>; interrupts = <3 4>; gpio-controller; @@ -69,7 +69,7 @@ }; gpio_prt4: gpio@42410200 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x42410200 0x80>; interrupts = <4 4>; gpio-controller; @@ -79,7 +79,7 @@ }; gpio_prt5: gpio@42410280 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x42410280 0x80>; interrupts = <5 4>; gpio-controller; @@ -89,7 +89,7 @@ }; gpio_prt6: gpio@42410300 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x42410300 0x80>; interrupts = <6 4>; gpio-controller; @@ -99,7 +99,7 @@ }; gpio_prt7: gpio@42410380 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x42410380 0x80>; interrupts = <7 4>; gpio-controller; @@ -109,7 +109,7 @@ }; gpio_prt8: gpio@42410400 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x42410400 0x80>; interrupts = <8 4>; gpio-controller; @@ -119,7 +119,7 @@ }; gpio_prt9: gpio@42410480 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x42410480 0x80>; interrupts = <9 4>; gpio-controller; @@ -145,70 +145,70 @@ }; ipc0: ipc@421d0000 { - compatible = "infineon,cat1-ipc"; + compatible = "infineon,ipc"; reg = <0x421d0000 0x1200>; status = "disabled"; #ipc-config-cells = <3>; }; scb0: scb@42820000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x42820000 0xfd0>; interrupts = <23 4>; status = "disabled"; }; scb1: scb@42840000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x42840000 0xfd0>; interrupts = <31 4>; status = "disabled"; }; scb2: scb@42850000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x42850000 0xfd0>; interrupts = <32 4>; status = "disabled"; }; scb3: scb@42860000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x42860000 0xfd0>; interrupts = <33 4>; status = "disabled"; }; scb4: scb@42870000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x42870000 0xfd0>; interrupts = <34 4>; status = "disabled"; }; scb5: scb@42c00000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x42c00000 0xfd0>; interrupts = <35 4>; status = "disabled"; }; watchdog0: watchdog@4220c000 { - compatible = "infineon,cat1-watchdog"; + compatible = "infineon,watchdog"; reg = <0x4220c000 0x10>; interrupts = <28 4>; status = "disabled"; }; mcwdt0: mcwdt@4220d000 { - compatible = "infineon,cat1-lp-timer"; + compatible = "infineon,lp-timer"; reg = <0x4220d000 0x40>; interrupts = <24 4>; status = "disabled"; }; rtc0: rtc@42220000 { - compatible = "infineon,cat1-rtc"; + compatible = "infineon,rtc"; reg = <0x42220000 0xff0c>; interrupts = <25 4>; alarms-count = <2>; @@ -615,7 +615,7 @@ dma0: dw@42180000 { #dma-cells = <1>; - compatible = "infineon,cat1-dma"; + compatible = "infineon,dma"; reg = <0x42180000 0x10000>; dma-channels = <16>; interrupts = <37 4>, /* CH0 */ @@ -639,7 +639,7 @@ dma1: dw@42190000 { #dma-cells = <1>; - compatible = "infineon,cat1-dma"; + compatible = "infineon,dma"; reg = <0x42190000 0x10000>; dma-channels = <16>; interrupts = <53 4>, /* CH0 */ diff --git a/dts/arm/infineon/cat1b/psc3/psc3_s.dtsi b/dts/arm/infineon/cat1b/psc3/psc3_s.dtsi index ac0b14573b41..1f104298899d 100644 --- a/dts/arm/infineon/cat1b/psc3/psc3_s.dtsi +++ b/dts/arm/infineon/cat1b/psc3/psc3_s.dtsi @@ -17,19 +17,19 @@ soc { pinctrl: pinctrl@52400000 { - compatible = "infineon,cat1-pinctrl"; + compatible = "infineon,pinctrl"; reg = <0x52400000 0x20000>; }; hsiom: hsiom@52400000 { - compatible = "infineon,cat1-hsiom"; + compatible = "infineon,hsiom"; reg = <0x52400000 0x4000>; interrupts = <22 4>, <20 4>; status = "disabled"; }; gpio_prt0: gpio@52410000 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x52410000 0x80>; interrupts = <10 4>; gpio-controller; @@ -39,7 +39,7 @@ }; gpio_prt1: gpio@52410080 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x52410080 0x80>; interrupts = <11 4>; gpio-controller; @@ -49,7 +49,7 @@ }; gpio_prt2: gpio@52410100 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x52410100 0x80>; interrupts = <12 4>; gpio-controller; @@ -59,7 +59,7 @@ }; gpio_prt3: gpio@52410180 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x52410180 0x80>; interrupts = <13 4>; gpio-controller; @@ -69,7 +69,7 @@ }; gpio_prt4: gpio@52410200 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x52410200 0x80>; interrupts = <14 4>; gpio-controller; @@ -79,7 +79,7 @@ }; gpio_prt5: gpio@52410280 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x52410280 0x80>; interrupts = <15 4>; gpio-controller; @@ -89,7 +89,7 @@ }; gpio_prt6: gpio@52410300 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x52410300 0x80>; interrupts = <16 4>; gpio-controller; @@ -99,7 +99,7 @@ }; gpio_prt7: gpio@52410380 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x52410380 0x80>; interrupts = <17 4>; gpio-controller; @@ -109,7 +109,7 @@ }; gpio_prt8: gpio@52410400 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x52410400 0x80>; interrupts = <18 4>; gpio-controller; @@ -119,7 +119,7 @@ }; gpio_prt9: gpio@52410480 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x52410480 0x80>; interrupts = <19 4>; gpio-controller; @@ -145,70 +145,70 @@ }; ipc0: ipc@521d0000 { - compatible = "infineon,cat1-ipc"; + compatible = "infineon,ipc"; reg = <0x521d0000 0x1200>; status = "disabled"; #ipc-config-cells = <3>; }; scb0: scb@52820000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x52820000 0xfd0>; interrupts = <23 4>; status = "disabled"; }; scb1: scb@52840000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x52840000 0xfd0>; interrupts = <31 4>; status = "disabled"; }; scb2: scb@52850000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x52850000 0xfd0>; interrupts = <32 4>; status = "disabled"; }; scb3: scb@52860000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x52860000 0xfd0>; interrupts = <33 4>; status = "disabled"; }; scb4: scb@52870000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x52870000 0xfd0>; interrupts = <34 4>; status = "disabled"; }; scb5: scb@52c00000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x52c00000 0xfd0>; interrupts = <35 4>; status = "disabled"; }; watchdog0: watchdog@5220c000 { - compatible = "infineon,cat1-watchdog"; + compatible = "infineon,watchdog"; reg = <0x5220c000 0x10>; interrupts = <28 4>; status = "disabled"; }; mcwdt0: mcwdt@5220d000 { - compatible = "infineon,cat1-lp-timer"; + compatible = "infineon,lp-timer"; reg = <0x5220d000 0x40>; interrupts = <24 4>; status = "disabled"; }; rtc0: rtc@52220000 { - compatible = "infineon,cat1-rtc"; + compatible = "infineon,rtc"; reg = <0x52220000 0xff0c>; interrupts = <25 4>; alarms-count = <2>; @@ -615,7 +615,7 @@ dma0: dw@52180000 { #dma-cells = <1>; - compatible = "infineon,cat1-dma"; + compatible = "infineon,dma"; reg = <0x52180000 0x10000>; dma-channels = <16>; interrupts = <37 4>, /* CH0 */ @@ -639,7 +639,7 @@ dma1: dw@52190000 { #dma-cells = <1>; - compatible = "infineon,cat1-dma"; + compatible = "infineon,dma"; reg = <0x52190000 0x10000>; dma-channels = <16>; interrupts = <53 4>, /* CH0 */ diff --git a/dts/arm/infineon/cat1c/xmc7200/xmc7200.dtsi b/dts/arm/infineon/cat1c/xmc7200/xmc7200.dtsi index b9c0bdc008d7..96383e67e6b6 100644 --- a/dts/arm/infineon/cat1c/xmc7200/xmc7200.dtsi +++ b/dts/arm/infineon/cat1c/xmc7200/xmc7200.dtsi @@ -9,7 +9,7 @@ / { flash-controller@40240000 { - compatible = "infineon,cat1-flash-controller"; + compatible = "infineon,flash-controller"; reg = <0x40240000 0x10000>; #address-cells = <1>; #size-cells = <1>; @@ -40,19 +40,19 @@ soc { pinctrl: pinctrl@40300000 { - compatible = "infineon,cat1-pinctrl"; + compatible = "infineon,pinctrl"; reg = <0x40300000 0x20000>; }; hsiom: hsiom@40300000 { - compatible = "infineon,cat1-hsiom"; + compatible = "infineon,hsiom"; reg = <0x40300000 0x4000>; system-interrupts = <21 6>, <20 6>; status = "disabled"; }; gpio_prt0: gpio@40310000 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40310000 0x80>; system-interrupts = <22 2>; gpio-controller; @@ -62,7 +62,7 @@ }; gpio_prt1: gpio@40310080 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40310080 0x80>; system-interrupts = <23 2>; gpio-controller; @@ -72,7 +72,7 @@ }; gpio_prt2: gpio@40310100 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40310100 0x80>; system-interrupts = <24 2>; gpio-controller; @@ -82,7 +82,7 @@ }; gpio_prt3: gpio@40310180 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40310180 0x80>; system-interrupts = <25 2>; gpio-controller; @@ -92,7 +92,7 @@ }; gpio_prt4: gpio@40310200 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40310200 0x80>; system-interrupts = <26 2>; gpio-controller; @@ -102,7 +102,7 @@ }; gpio_prt5: gpio@40310280 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40310280 0x80>; system-interrupts = <27 2>; gpio-controller; @@ -112,7 +112,7 @@ }; gpio_prt6: gpio@40310300 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40310300 0x80>; system-interrupts = <28 2>; gpio-controller; @@ -122,7 +122,7 @@ }; gpio_prt7: gpio@40310380 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40310380 0x80>; system-interrupts = <29 2>; gpio-controller; @@ -132,7 +132,7 @@ }; gpio_prt8: gpio@40310400 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40310400 0x80>; system-interrupts = <30 2>; gpio-controller; @@ -142,7 +142,7 @@ }; gpio_prt9: gpio@40310480 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40310480 0x80>; system-interrupts = <31 2>; gpio-controller; @@ -152,7 +152,7 @@ }; gpio_prt10: gpio@40310500 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40310500 0x80>; system-interrupts = <32 2>; gpio-controller; @@ -162,7 +162,7 @@ }; gpio_prt11: gpio@40310580 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40310580 0x80>; system-interrupts = <33 2>; gpio-controller; @@ -172,7 +172,7 @@ }; gpio_prt12: gpio@40310600 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40310600 0x80>; system-interrupts = <34 2>; gpio-controller; @@ -182,7 +182,7 @@ }; gpio_prt13: gpio@40310680 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40310680 0x80>; system-interrupts = <35 2>; gpio-controller; @@ -192,7 +192,7 @@ }; gpio_prt14: gpio@40310700 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40310700 0x80>; system-interrupts = <36 2>; gpio-controller; @@ -202,7 +202,7 @@ }; gpio_prt15: gpio@40310780 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40310780 0x80>; system-interrupts = <37 2>; gpio-controller; @@ -212,7 +212,7 @@ }; gpio_prt16: gpio@40310800 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40310800 0x80>; system-interrupts = <38 2>; gpio-controller; @@ -222,7 +222,7 @@ }; gpio_prt17: gpio@40310880 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40310880 0x80>; system-interrupts = <39 2>; gpio-controller; @@ -232,7 +232,7 @@ }; gpio_prt18: gpio@40310900 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40310900 0x80>; system-interrupts = <40 2>; gpio-controller; @@ -242,7 +242,7 @@ }; gpio_prt19: gpio@40310980 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40310980 0x80>; system-interrupts = <41 2>; gpio-controller; @@ -252,7 +252,7 @@ }; gpio_prt20: gpio@40310a00 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40310a00 0x80>; system-interrupts = <42 2>; gpio-controller; @@ -262,7 +262,7 @@ }; gpio_prt21: gpio@40310a80 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40310a80 0x80>; system-interrupts = <43 2>; gpio-controller; @@ -272,7 +272,7 @@ }; gpio_prt22: gpio@40310b00 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40310b00 0x80>; system-interrupts = <44 2>; gpio-controller; @@ -282,7 +282,7 @@ }; gpio_prt23: gpio@40310b80 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40310b80 0x80>; system-interrupts = <45 2>; gpio-controller; @@ -292,7 +292,7 @@ }; gpio_prt24: gpio@40310c00 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40310c00 0x80>; system-interrupts = <52 2>; gpio-controller; @@ -302,7 +302,7 @@ }; gpio_prt25: gpio@40310c80 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40310c80 0x80>; system-interrupts = <53 2>; gpio-controller; @@ -312,7 +312,7 @@ }; gpio_prt26: gpio@40310d00 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40310d00 0x80>; system-interrupts = <54 2>; gpio-controller; @@ -322,7 +322,7 @@ }; gpio_prt27: gpio@40310d80 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40310d80 0x80>; system-interrupts = <55 2>; gpio-controller; @@ -332,7 +332,7 @@ }; gpio_prt28: gpio@40310e00 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40310e00 0x80>; system-interrupts = <46 2>; gpio-controller; @@ -342,7 +342,7 @@ }; gpio_prt29: gpio@40310e80 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40310e80 0x80>; system-interrupts = <47 2>; gpio-controller; @@ -352,7 +352,7 @@ }; gpio_prt30: gpio@40310f00 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40310f00 0x80>; system-interrupts = <48 2>; gpio-controller; @@ -362,7 +362,7 @@ }; gpio_prt31: gpio@40310f80 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40310f80 0x80>; system-interrupts = <49 2>; gpio-controller; @@ -372,7 +372,7 @@ }; gpio_prt32: gpio@40311000 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40311000 0x80>; system-interrupts = <50 2>; gpio-controller; @@ -382,7 +382,7 @@ }; gpio_prt33: gpio@40311080 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40311080 0x80>; system-interrupts = <56 2>; gpio-controller; @@ -392,7 +392,7 @@ }; gpio_prt34: gpio@40311100 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x40311100 0x80>; system-interrupts = <57 2>; gpio-controller; @@ -402,112 +402,112 @@ }; scb0: scb@40600000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x40600000 0xfd0>; system-interrupts = <18 6>; status = "disabled"; }; scb1: scb@40610000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x40610000 0xfd0>; system-interrupts = <113 6>; status = "disabled"; }; scb2: scb@40620000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x40620000 0xfd0>; system-interrupts = <114 6>; status = "disabled"; }; scb3: scb@40630000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x40630000 0xfd0>; system-interrupts = <115 6>; status = "disabled"; }; scb4: scb@40640000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x40640000 0xfd0>; system-interrupts = <116 6>; status = "disabled"; }; scb5: scb@40650000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x40650000 0xfd0>; system-interrupts = <117 6>; status = "disabled"; }; scb6: scb@40660000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x40660000 0xfd0>; system-interrupts = <118 6>; status = "disabled"; }; scb7: scb@40670000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x40670000 0xfd0>; system-interrupts = <119 6>; status = "disabled"; }; scb8: scb@40680000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x40680000 0xfd0>; system-interrupts = <120 6>; status = "disabled"; }; scb9: scb@40690000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x40690000 0xfd0>; system-interrupts = <121 6>; status = "disabled"; }; scb10: scb@406a0000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x406a0000 0xfd0>; system-interrupts = <122 6>; status = "disabled"; }; watchdog0: watchdog@4026c000 { - compatible = "infineon,cat1-watchdog"; + compatible = "infineon,watchdog"; reg = <0x4026c000 0x80>; system-interrupts = <16 6>; status = "disabled"; }; mcwdt0: mcwdt@40268000 { - compatible = "infineon,cat1-lp-timer"; + compatible = "infineon,lp-timer"; reg = <0x40268000 0x100>; system-interrupts = <13 6>; status = "disabled"; }; mcwdt1: mcwdt@40268100 { - compatible = "infineon,cat1-lp-timer"; + compatible = "infineon,lp-timer"; reg = <0x40268100 0x100>; system-interrupts = <14 6>; status = "disabled"; }; mcwdt2: mcwdt@40268200 { - compatible = "infineon,cat1-lp-timer"; + compatible = "infineon,lp-timer"; reg = <0x40268200 0x100>; system-interrupts = <15 6>; status = "disabled"; }; counter0_0_0: counter@40380000 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40380000 0x80>; system-interrupts = <519 6>; resolution = <16>; @@ -515,7 +515,7 @@ }; counter0_0_1: counter@40380080 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40380080 0x80>; system-interrupts = <520 6>; resolution = <16>; @@ -523,7 +523,7 @@ }; counter0_0_2: counter@40380100 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40380100 0x80>; system-interrupts = <521 6>; resolution = <16>; @@ -531,7 +531,7 @@ }; counter0_1_0: counter@40388000 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40388000 0x80>; system-interrupts = <534 6>; resolution = <16>; @@ -539,7 +539,7 @@ }; counter0_1_1: counter@40388080 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40388080 0x80>; system-interrupts = <535 6>; resolution = <16>; @@ -547,7 +547,7 @@ }; counter0_1_2: counter@40388100 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40388100 0x80>; system-interrupts = <536 6>; resolution = <16>; @@ -555,7 +555,7 @@ }; counter0_2_0: counter@40390000 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40390000 0x80>; system-interrupts = <550 6>; resolution = <32>; @@ -563,7 +563,7 @@ }; counter0_2_1: counter@40390080 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40390080 0x80>; system-interrupts = <551 6>; resolution = <32>; @@ -571,7 +571,7 @@ }; counter0_2_2: counter@40390100 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40390100 0x80>; system-interrupts = <552 6>; resolution = <32>; @@ -579,7 +579,7 @@ }; counter1_0_0: counter@40580000 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40580000 0x80>; system-interrupts = <435 6>; resolution = <16>; @@ -587,7 +587,7 @@ }; counter1_0_1: counter@40580080 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40580080 0x80>; system-interrupts = <436 6>; resolution = <16>; @@ -595,7 +595,7 @@ }; counter1_0_2: counter@40580100 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40580100 0x80>; system-interrupts = <437 6>; resolution = <16>; @@ -603,7 +603,7 @@ }; counter1_0_3: counter@40580180 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40580180 0x80>; system-interrupts = <438 6>; resolution = <16>; @@ -611,7 +611,7 @@ }; counter1_0_4: counter@40580200 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40580200 0x80>; system-interrupts = <439 6>; resolution = <16>; @@ -619,7 +619,7 @@ }; counter1_0_5: counter@40580280 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40580280 0x80>; system-interrupts = <440 6>; resolution = <16>; @@ -627,7 +627,7 @@ }; counter1_0_6: counter@40580300 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40580300 0x80>; system-interrupts = <441 6>; resolution = <16>; @@ -635,7 +635,7 @@ }; counter1_0_7: counter@40580380 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40580380 0x80>; system-interrupts = <442 6>; resolution = <16>; @@ -643,7 +643,7 @@ }; counter1_0_8: counter@40580400 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40580400 0x80>; system-interrupts = <443 6>; resolution = <16>; @@ -651,7 +651,7 @@ }; counter1_0_9: counter@40580480 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40580480 0x80>; system-interrupts = <444 6>; resolution = <16>; @@ -659,7 +659,7 @@ }; counter1_0_10: counter@40580500 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40580500 0x80>; system-interrupts = <445 6>; resolution = <16>; @@ -667,7 +667,7 @@ }; counter1_0_11: counter@40580580 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40580580 0x80>; system-interrupts = <446 6>; resolution = <16>; @@ -675,7 +675,7 @@ }; counter1_0_12: counter@40580600 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40580600 0x80>; system-interrupts = <447 6>; resolution = <16>; @@ -683,7 +683,7 @@ }; counter1_0_13: counter@40580680 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40580680 0x80>; system-interrupts = <448 6>; resolution = <16>; @@ -691,7 +691,7 @@ }; counter1_0_14: counter@40580700 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40580700 0x80>; system-interrupts = <449 6>; resolution = <16>; @@ -699,7 +699,7 @@ }; counter1_0_15: counter@40580780 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40580780 0x80>; system-interrupts = <450 6>; resolution = <16>; @@ -707,7 +707,7 @@ }; counter1_0_16: counter@40580800 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40580800 0x80>; system-interrupts = <451 6>; resolution = <16>; @@ -715,7 +715,7 @@ }; counter1_0_17: counter@40580880 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40580880 0x80>; system-interrupts = <452 6>; resolution = <16>; @@ -723,7 +723,7 @@ }; counter1_0_18: counter@40580900 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40580900 0x80>; system-interrupts = <453 6>; resolution = <16>; @@ -731,7 +731,7 @@ }; counter1_0_19: counter@40580980 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40580980 0x80>; system-interrupts = <454 6>; resolution = <16>; @@ -739,7 +739,7 @@ }; counter1_0_20: counter@40580a00 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40580a00 0x80>; system-interrupts = <455 6>; resolution = <16>; @@ -747,7 +747,7 @@ }; counter1_0_21: counter@40580a80 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40580a80 0x80>; system-interrupts = <456 6>; resolution = <16>; @@ -755,7 +755,7 @@ }; counter1_0_22: counter@40580b00 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40580b00 0x80>; system-interrupts = <457 6>; resolution = <16>; @@ -763,7 +763,7 @@ }; counter1_0_23: counter@40580b80 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40580b80 0x80>; system-interrupts = <458 6>; resolution = <16>; @@ -771,7 +771,7 @@ }; counter1_0_24: counter@40580c00 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40580c00 0x80>; system-interrupts = <459 6>; resolution = <16>; @@ -779,7 +779,7 @@ }; counter1_0_25: counter@40580c80 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40580c80 0x80>; system-interrupts = <460 6>; resolution = <16>; @@ -787,7 +787,7 @@ }; counter1_0_26: counter@40580d00 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40580d00 0x80>; system-interrupts = <461 6>; resolution = <16>; @@ -795,7 +795,7 @@ }; counter1_0_27: counter@40580d80 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40580d80 0x80>; system-interrupts = <462 6>; resolution = <16>; @@ -803,7 +803,7 @@ }; counter1_0_28: counter@40580e00 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40580e00 0x80>; system-interrupts = <463 6>; resolution = <16>; @@ -811,7 +811,7 @@ }; counter1_0_29: counter@40580e80 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40580e80 0x80>; system-interrupts = <464 6>; resolution = <16>; @@ -819,7 +819,7 @@ }; counter1_0_30: counter@40580f00 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40580f00 0x80>; system-interrupts = <465 6>; resolution = <16>; @@ -827,7 +827,7 @@ }; counter1_0_31: counter@40580f80 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40580f80 0x80>; system-interrupts = <466 6>; resolution = <16>; @@ -835,7 +835,7 @@ }; counter1_0_32: counter@40581000 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40581000 0x80>; system-interrupts = <467 6>; resolution = <16>; @@ -843,7 +843,7 @@ }; counter1_0_33: counter@40581080 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40581080 0x80>; system-interrupts = <468 6>; resolution = <16>; @@ -851,7 +851,7 @@ }; counter1_0_34: counter@40581100 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40581100 0x80>; system-interrupts = <469 6>; resolution = <16>; @@ -859,7 +859,7 @@ }; counter1_0_35: counter@40581180 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40581180 0x80>; system-interrupts = <470 6>; resolution = <16>; @@ -867,7 +867,7 @@ }; counter1_0_36: counter@40581200 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40581200 0x80>; system-interrupts = <471 6>; resolution = <16>; @@ -875,7 +875,7 @@ }; counter1_0_37: counter@40581280 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40581280 0x80>; system-interrupts = <472 6>; resolution = <16>; @@ -883,7 +883,7 @@ }; counter1_0_38: counter@40581300 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40581300 0x80>; system-interrupts = <473 6>; resolution = <16>; @@ -891,7 +891,7 @@ }; counter1_0_39: counter@40581380 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40581380 0x80>; system-interrupts = <474 6>; resolution = <16>; @@ -899,7 +899,7 @@ }; counter1_0_40: counter@40581400 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40581400 0x80>; system-interrupts = <475 6>; resolution = <16>; @@ -907,7 +907,7 @@ }; counter1_0_41: counter@40581480 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40581480 0x80>; system-interrupts = <476 6>; resolution = <16>; @@ -915,7 +915,7 @@ }; counter1_0_42: counter@40581500 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40581500 0x80>; system-interrupts = <477 6>; resolution = <16>; @@ -923,7 +923,7 @@ }; counter1_0_43: counter@40581580 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40581580 0x80>; system-interrupts = <478 6>; resolution = <16>; @@ -931,7 +931,7 @@ }; counter1_0_44: counter@40581600 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40581600 0x80>; system-interrupts = <479 6>; resolution = <16>; @@ -939,7 +939,7 @@ }; counter1_0_45: counter@40581680 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40581680 0x80>; system-interrupts = <480 6>; resolution = <16>; @@ -947,7 +947,7 @@ }; counter1_0_46: counter@40581700 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40581700 0x80>; system-interrupts = <481 6>; resolution = <16>; @@ -955,7 +955,7 @@ }; counter1_0_47: counter@40581780 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40581780 0x80>; system-interrupts = <482 6>; resolution = <16>; @@ -963,7 +963,7 @@ }; counter1_0_48: counter@40581800 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40581800 0x80>; system-interrupts = <483 6>; resolution = <16>; @@ -971,7 +971,7 @@ }; counter1_0_49: counter@40581880 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40581880 0x80>; system-interrupts = <484 6>; resolution = <16>; @@ -979,7 +979,7 @@ }; counter1_0_50: counter@40581900 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40581900 0x80>; system-interrupts = <485 6>; resolution = <16>; @@ -987,7 +987,7 @@ }; counter1_0_51: counter@40581980 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40581980 0x80>; system-interrupts = <486 6>; resolution = <16>; @@ -995,7 +995,7 @@ }; counter1_0_52: counter@40581a00 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40581a00 0x80>; system-interrupts = <487 6>; resolution = <16>; @@ -1003,7 +1003,7 @@ }; counter1_0_53: counter@40581a80 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40581a80 0x80>; system-interrupts = <488 6>; resolution = <16>; @@ -1011,7 +1011,7 @@ }; counter1_0_54: counter@40581b00 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40581b00 0x80>; system-interrupts = <489 6>; resolution = <16>; @@ -1019,7 +1019,7 @@ }; counter1_0_55: counter@40581b80 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40581b80 0x80>; system-interrupts = <490 6>; resolution = <16>; @@ -1027,7 +1027,7 @@ }; counter1_0_56: counter@40581c00 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40581c00 0x80>; system-interrupts = <491 6>; resolution = <16>; @@ -1035,7 +1035,7 @@ }; counter1_0_57: counter@40581c80 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40581c80 0x80>; system-interrupts = <492 6>; resolution = <16>; @@ -1043,7 +1043,7 @@ }; counter1_0_58: counter@40581d00 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40581d00 0x80>; system-interrupts = <493 6>; resolution = <16>; @@ -1051,7 +1051,7 @@ }; counter1_0_59: counter@40581d80 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40581d80 0x80>; system-interrupts = <494 6>; resolution = <16>; @@ -1059,7 +1059,7 @@ }; counter1_0_60: counter@40581e00 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40581e00 0x80>; system-interrupts = <495 6>; resolution = <16>; @@ -1067,7 +1067,7 @@ }; counter1_0_61: counter@40581e80 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40581e80 0x80>; system-interrupts = <496 6>; resolution = <16>; @@ -1075,7 +1075,7 @@ }; counter1_0_62: counter@40581f00 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40581f00 0x80>; system-interrupts = <497 6>; resolution = <16>; @@ -1083,7 +1083,7 @@ }; counter1_0_63: counter@40581f80 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40581f80 0x80>; system-interrupts = <498 6>; resolution = <16>; @@ -1091,7 +1091,7 @@ }; counter1_0_64: counter@40582000 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40582000 0x80>; system-interrupts = <499 6>; resolution = <16>; @@ -1099,7 +1099,7 @@ }; counter1_0_65: counter@40582080 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40582080 0x80>; system-interrupts = <500 6>; resolution = <16>; @@ -1107,7 +1107,7 @@ }; counter1_0_66: counter@40582100 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40582100 0x80>; system-interrupts = <501 6>; resolution = <16>; @@ -1115,7 +1115,7 @@ }; counter1_0_67: counter@40582180 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40582180 0x80>; system-interrupts = <502 6>; resolution = <16>; @@ -1123,7 +1123,7 @@ }; counter1_0_68: counter@40582200 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40582200 0x80>; system-interrupts = <503 6>; resolution = <16>; @@ -1131,7 +1131,7 @@ }; counter1_0_69: counter@40582280 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40582280 0x80>; system-interrupts = <504 6>; resolution = <16>; @@ -1139,7 +1139,7 @@ }; counter1_0_70: counter@40582300 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40582300 0x80>; system-interrupts = <505 6>; resolution = <16>; @@ -1147,7 +1147,7 @@ }; counter1_0_71: counter@40582380 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40582380 0x80>; system-interrupts = <506 6>; resolution = <16>; @@ -1155,7 +1155,7 @@ }; counter1_0_72: counter@40582400 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40582400 0x80>; system-interrupts = <507 6>; resolution = <16>; @@ -1163,7 +1163,7 @@ }; counter1_0_73: counter@40582480 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40582480 0x80>; system-interrupts = <508 6>; resolution = <16>; @@ -1171,7 +1171,7 @@ }; counter1_0_74: counter@40582500 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40582500 0x80>; system-interrupts = <509 6>; resolution = <16>; @@ -1179,7 +1179,7 @@ }; counter1_0_75: counter@40582580 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40582580 0x80>; system-interrupts = <510 6>; resolution = <16>; @@ -1187,7 +1187,7 @@ }; counter1_0_76: counter@40582600 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40582600 0x80>; system-interrupts = <511 6>; resolution = <16>; @@ -1195,7 +1195,7 @@ }; counter1_0_77: counter@40582680 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40582680 0x80>; system-interrupts = <512 6>; resolution = <16>; @@ -1203,7 +1203,7 @@ }; counter1_0_78: counter@40582700 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40582700 0x80>; system-interrupts = <513 6>; resolution = <16>; @@ -1211,7 +1211,7 @@ }; counter1_0_79: counter@40582780 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40582780 0x80>; system-interrupts = <514 6>; resolution = <16>; @@ -1219,7 +1219,7 @@ }; counter1_0_80: counter@40582800 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40582800 0x80>; system-interrupts = <515 6>; resolution = <16>; @@ -1227,7 +1227,7 @@ }; counter1_0_81: counter@40582880 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40582880 0x80>; system-interrupts = <516 6>; resolution = <16>; @@ -1235,7 +1235,7 @@ }; counter1_0_82: counter@40582900 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40582900 0x80>; system-interrupts = <517 6>; resolution = <16>; @@ -1243,7 +1243,7 @@ }; counter1_0_83: counter@40582980 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40582980 0x80>; system-interrupts = <518 6>; resolution = <16>; @@ -1251,7 +1251,7 @@ }; counter1_1_0: counter@40588000 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40588000 0x80>; system-interrupts = <522 6>; resolution = <16>; @@ -1259,7 +1259,7 @@ }; counter1_1_1: counter@40588080 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40588080 0x80>; system-interrupts = <523 6>; resolution = <16>; @@ -1267,7 +1267,7 @@ }; counter1_1_2: counter@40588100 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40588100 0x80>; system-interrupts = <524 6>; resolution = <16>; @@ -1275,7 +1275,7 @@ }; counter1_1_3: counter@40588180 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40588180 0x80>; system-interrupts = <525 6>; resolution = <16>; @@ -1283,7 +1283,7 @@ }; counter1_1_4: counter@40588200 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40588200 0x80>; system-interrupts = <526 6>; resolution = <16>; @@ -1291,7 +1291,7 @@ }; counter1_1_5: counter@40588280 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40588280 0x80>; system-interrupts = <527 6>; resolution = <16>; @@ -1299,7 +1299,7 @@ }; counter1_1_6: counter@40588300 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40588300 0x80>; system-interrupts = <528 6>; resolution = <16>; @@ -1307,7 +1307,7 @@ }; counter1_1_7: counter@40588380 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40588380 0x80>; system-interrupts = <529 6>; resolution = <16>; @@ -1315,7 +1315,7 @@ }; counter1_1_8: counter@40588400 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40588400 0x80>; system-interrupts = <530 6>; resolution = <16>; @@ -1323,7 +1323,7 @@ }; counter1_1_9: counter@40588480 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40588480 0x80>; system-interrupts = <531 6>; resolution = <16>; @@ -1331,7 +1331,7 @@ }; counter1_1_10: counter@40588500 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40588500 0x80>; system-interrupts = <532 6>; resolution = <16>; @@ -1339,7 +1339,7 @@ }; counter1_1_11: counter@40588580 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40588580 0x80>; system-interrupts = <533 6>; resolution = <16>; @@ -1347,7 +1347,7 @@ }; counter1_2_0: counter@40590000 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40590000 0x80>; system-interrupts = <537 6>; resolution = <32>; @@ -1355,7 +1355,7 @@ }; counter1_2_1: counter@40590080 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40590080 0x80>; system-interrupts = <538 6>; resolution = <32>; @@ -1363,7 +1363,7 @@ }; counter1_2_2: counter@40590100 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40590100 0x80>; system-interrupts = <539 6>; resolution = <32>; @@ -1371,7 +1371,7 @@ }; counter1_2_3: counter@40590180 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40590180 0x80>; system-interrupts = <540 6>; resolution = <32>; @@ -1379,7 +1379,7 @@ }; counter1_2_4: counter@40590200 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40590200 0x80>; system-interrupts = <541 6>; resolution = <32>; @@ -1387,7 +1387,7 @@ }; counter1_2_5: counter@40590280 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40590280 0x80>; system-interrupts = <542 6>; resolution = <32>; @@ -1395,7 +1395,7 @@ }; counter1_2_6: counter@40590300 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40590300 0x80>; system-interrupts = <543 6>; resolution = <32>; @@ -1403,7 +1403,7 @@ }; counter1_2_7: counter@40590380 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40590380 0x80>; system-interrupts = <544 6>; resolution = <32>; @@ -1411,7 +1411,7 @@ }; counter1_2_8: counter@40590400 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40590400 0x80>; system-interrupts = <545 6>; resolution = <32>; @@ -1419,7 +1419,7 @@ }; counter1_2_9: counter@40590480 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40590480 0x80>; system-interrupts = <546 6>; resolution = <32>; @@ -1427,7 +1427,7 @@ }; counter1_2_10: counter@40590500 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40590500 0x80>; system-interrupts = <547 6>; resolution = <32>; @@ -1435,7 +1435,7 @@ }; counter1_2_11: counter@40590580 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40590580 0x80>; system-interrupts = <548 6>; resolution = <32>; @@ -1443,7 +1443,7 @@ }; counter1_2_12: counter@40590600 { - compatible = "infineon,cat1-counter"; + compatible = "infineon,counter"; reg = <0x40590600 0x80>; system-interrupts = <549 6>; resolution = <32>; @@ -1451,7 +1451,7 @@ }; pwm0_0_0: pwm@40380000 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40380000 0x80>; system-interrupts = <519 6>; resolution = <16>; @@ -1459,7 +1459,7 @@ }; pwm0_0_1: pwm@40380080 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40380080 0x80>; system-interrupts = <520 6>; resolution = <16>; @@ -1467,7 +1467,7 @@ }; pwm0_0_2: pwm@40380100 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40380100 0x80>; system-interrupts = <521 6>; resolution = <16>; @@ -1475,7 +1475,7 @@ }; pwm0_1_0: pwm@40388000 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40388000 0x80>; system-interrupts = <534 6>; resolution = <16>; @@ -1483,7 +1483,7 @@ }; pwm0_1_1: pwm@40388080 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40388080 0x80>; system-interrupts = <535 6>; resolution = <16>; @@ -1491,7 +1491,7 @@ }; pwm0_1_2: pwm@40388100 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40388100 0x80>; system-interrupts = <536 6>; resolution = <16>; @@ -1499,7 +1499,7 @@ }; pwm0_2_0: pwm@40390000 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40390000 0x80>; system-interrupts = <550 6>; resolution = <32>; @@ -1507,7 +1507,7 @@ }; pwm0_2_1: pwm@40390080 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40390080 0x80>; system-interrupts = <551 6>; resolution = <32>; @@ -1515,7 +1515,7 @@ }; pwm0_2_2: pwm@40390100 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40390100 0x80>; system-interrupts = <552 6>; resolution = <32>; @@ -1523,7 +1523,7 @@ }; pwm1_0_0: pwm@40580000 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40580000 0x80>; system-interrupts = <435 6>; resolution = <16>; @@ -1531,7 +1531,7 @@ }; pwm1_0_1: pwm@40580080 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40580080 0x80>; system-interrupts = <436 6>; resolution = <16>; @@ -1539,7 +1539,7 @@ }; pwm1_0_2: pwm@40580100 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40580100 0x80>; system-interrupts = <437 6>; resolution = <16>; @@ -1547,7 +1547,7 @@ }; pwm1_0_3: pwm@40580180 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40580180 0x80>; system-interrupts = <438 6>; resolution = <16>; @@ -1555,7 +1555,7 @@ }; pwm1_0_4: pwm@40580200 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40580200 0x80>; system-interrupts = <439 6>; resolution = <16>; @@ -1563,7 +1563,7 @@ }; pwm1_0_5: pwm@40580280 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40580280 0x80>; system-interrupts = <440 6>; resolution = <16>; @@ -1571,7 +1571,7 @@ }; pwm1_0_6: pwm@40580300 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40580300 0x80>; system-interrupts = <441 6>; resolution = <16>; @@ -1579,7 +1579,7 @@ }; pwm1_0_7: pwm@40580380 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40580380 0x80>; system-interrupts = <442 6>; resolution = <16>; @@ -1587,7 +1587,7 @@ }; pwm1_0_8: pwm@40580400 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40580400 0x80>; system-interrupts = <443 6>; resolution = <16>; @@ -1595,7 +1595,7 @@ }; pwm1_0_9: pwm@40580480 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40580480 0x80>; system-interrupts = <444 6>; resolution = <16>; @@ -1603,7 +1603,7 @@ }; pwm1_0_10: pwm@40580500 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40580500 0x80>; system-interrupts = <445 6>; resolution = <16>; @@ -1611,7 +1611,7 @@ }; pwm1_0_11: pwm@40580580 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40580580 0x80>; system-interrupts = <446 6>; resolution = <16>; @@ -1619,7 +1619,7 @@ }; pwm1_0_12: pwm@40580600 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40580600 0x80>; system-interrupts = <447 6>; resolution = <16>; @@ -1627,7 +1627,7 @@ }; pwm1_0_13: pwm@40580680 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40580680 0x80>; system-interrupts = <448 6>; resolution = <16>; @@ -1635,7 +1635,7 @@ }; pwm1_0_14: pwm@40580700 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40580700 0x80>; system-interrupts = <449 6>; resolution = <16>; @@ -1643,7 +1643,7 @@ }; pwm1_0_15: pwm@40580780 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40580780 0x80>; system-interrupts = <450 6>; resolution = <16>; @@ -1651,7 +1651,7 @@ }; pwm1_0_16: pwm@40580800 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40580800 0x80>; system-interrupts = <451 6>; resolution = <16>; @@ -1659,7 +1659,7 @@ }; pwm1_0_17: pwm@40580880 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40580880 0x80>; system-interrupts = <452 6>; resolution = <16>; @@ -1667,7 +1667,7 @@ }; pwm1_0_18: pwm@40580900 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40580900 0x80>; system-interrupts = <453 6>; resolution = <16>; @@ -1675,7 +1675,7 @@ }; pwm1_0_19: pwm@40580980 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40580980 0x80>; system-interrupts = <454 6>; resolution = <16>; @@ -1683,7 +1683,7 @@ }; pwm1_0_20: pwm@40580a00 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40580a00 0x80>; system-interrupts = <455 6>; resolution = <16>; @@ -1691,7 +1691,7 @@ }; pwm1_0_21: pwm@40580a80 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40580a80 0x80>; system-interrupts = <456 6>; resolution = <16>; @@ -1699,7 +1699,7 @@ }; pwm1_0_22: pwm@40580b00 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40580b00 0x80>; system-interrupts = <457 6>; resolution = <16>; @@ -1707,7 +1707,7 @@ }; pwm1_0_23: pwm@40580b80 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40580b80 0x80>; system-interrupts = <458 6>; resolution = <16>; @@ -1715,7 +1715,7 @@ }; pwm1_0_24: pwm@40580c00 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40580c00 0x80>; system-interrupts = <459 6>; resolution = <16>; @@ -1723,7 +1723,7 @@ }; pwm1_0_25: pwm@40580c80 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40580c80 0x80>; system-interrupts = <460 6>; resolution = <16>; @@ -1731,7 +1731,7 @@ }; pwm1_0_26: pwm@40580d00 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40580d00 0x80>; system-interrupts = <461 6>; resolution = <16>; @@ -1739,7 +1739,7 @@ }; pwm1_0_27: pwm@40580d80 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40580d80 0x80>; system-interrupts = <462 6>; resolution = <16>; @@ -1747,7 +1747,7 @@ }; pwm1_0_28: pwm@40580e00 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40580e00 0x80>; system-interrupts = <463 6>; resolution = <16>; @@ -1755,7 +1755,7 @@ }; pwm1_0_29: pwm@40580e80 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40580e80 0x80>; system-interrupts = <464 6>; resolution = <16>; @@ -1763,7 +1763,7 @@ }; pwm1_0_30: pwm@40580f00 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40580f00 0x80>; system-interrupts = <465 6>; resolution = <16>; @@ -1771,7 +1771,7 @@ }; pwm1_0_31: pwm@40580f80 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40580f80 0x80>; system-interrupts = <466 6>; resolution = <16>; @@ -1779,7 +1779,7 @@ }; pwm1_0_32: pwm@40581000 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40581000 0x80>; system-interrupts = <467 6>; resolution = <16>; @@ -1787,7 +1787,7 @@ }; pwm1_0_33: pwm@40581080 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40581080 0x80>; system-interrupts = <468 6>; resolution = <16>; @@ -1795,7 +1795,7 @@ }; pwm1_0_34: pwm@40581100 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40581100 0x80>; system-interrupts = <469 6>; resolution = <16>; @@ -1803,7 +1803,7 @@ }; pwm1_0_35: pwm@40581180 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40581180 0x80>; system-interrupts = <470 6>; resolution = <16>; @@ -1811,7 +1811,7 @@ }; pwm1_0_36: pwm@40581200 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40581200 0x80>; system-interrupts = <471 6>; resolution = <16>; @@ -1819,7 +1819,7 @@ }; pwm1_0_37: pwm@40581280 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40581280 0x80>; system-interrupts = <472 6>; resolution = <16>; @@ -1827,7 +1827,7 @@ }; pwm1_0_38: pwm@40581300 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40581300 0x80>; system-interrupts = <473 6>; resolution = <16>; @@ -1835,7 +1835,7 @@ }; pwm1_0_39: pwm@40581380 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40581380 0x80>; system-interrupts = <474 6>; resolution = <16>; @@ -1843,7 +1843,7 @@ }; pwm1_0_40: pwm@40581400 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40581400 0x80>; system-interrupts = <475 6>; resolution = <16>; @@ -1851,7 +1851,7 @@ }; pwm1_0_41: pwm@40581480 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40581480 0x80>; system-interrupts = <476 6>; resolution = <16>; @@ -1859,7 +1859,7 @@ }; pwm1_0_42: pwm@40581500 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40581500 0x80>; system-interrupts = <477 6>; resolution = <16>; @@ -1867,7 +1867,7 @@ }; pwm1_0_43: pwm@40581580 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40581580 0x80>; system-interrupts = <478 6>; resolution = <16>; @@ -1875,7 +1875,7 @@ }; pwm1_0_44: pwm@40581600 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40581600 0x80>; system-interrupts = <479 6>; resolution = <16>; @@ -1883,7 +1883,7 @@ }; pwm1_0_45: pwm@40581680 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40581680 0x80>; system-interrupts = <480 6>; resolution = <16>; @@ -1891,7 +1891,7 @@ }; pwm1_0_46: pwm@40581700 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40581700 0x80>; system-interrupts = <481 6>; resolution = <16>; @@ -1899,7 +1899,7 @@ }; pwm1_0_47: pwm@40581780 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40581780 0x80>; system-interrupts = <482 6>; resolution = <16>; @@ -1907,7 +1907,7 @@ }; pwm1_0_48: pwm@40581800 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40581800 0x80>; system-interrupts = <483 6>; resolution = <16>; @@ -1915,7 +1915,7 @@ }; pwm1_0_49: pwm@40581880 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40581880 0x80>; system-interrupts = <484 6>; resolution = <16>; @@ -1923,7 +1923,7 @@ }; pwm1_0_50: pwm@40581900 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40581900 0x80>; system-interrupts = <485 6>; resolution = <16>; @@ -1931,7 +1931,7 @@ }; pwm1_0_51: pwm@40581980 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40581980 0x80>; system-interrupts = <486 6>; resolution = <16>; @@ -1939,7 +1939,7 @@ }; pwm1_0_52: pwm@40581a00 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40581a00 0x80>; system-interrupts = <487 6>; resolution = <16>; @@ -1947,7 +1947,7 @@ }; pwm1_0_53: pwm@40581a80 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40581a80 0x80>; system-interrupts = <488 6>; resolution = <16>; @@ -1955,7 +1955,7 @@ }; pwm1_0_54: pwm@40581b00 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40581b00 0x80>; system-interrupts = <489 6>; resolution = <16>; @@ -1963,7 +1963,7 @@ }; pwm1_0_55: pwm@40581b80 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40581b80 0x80>; system-interrupts = <490 6>; resolution = <16>; @@ -1971,7 +1971,7 @@ }; pwm1_0_56: pwm@40581c00 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40581c00 0x80>; system-interrupts = <491 6>; resolution = <16>; @@ -1979,7 +1979,7 @@ }; pwm1_0_57: pwm@40581c80 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40581c80 0x80>; system-interrupts = <492 6>; resolution = <16>; @@ -1987,7 +1987,7 @@ }; pwm1_0_58: pwm@40581d00 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40581d00 0x80>; system-interrupts = <493 6>; resolution = <16>; @@ -1995,7 +1995,7 @@ }; pwm1_0_59: pwm@40581d80 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40581d80 0x80>; system-interrupts = <494 6>; resolution = <16>; @@ -2003,7 +2003,7 @@ }; pwm1_0_60: pwm@40581e00 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40581e00 0x80>; system-interrupts = <495 6>; resolution = <16>; @@ -2011,7 +2011,7 @@ }; pwm1_0_61: pwm@40581e80 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40581e80 0x80>; system-interrupts = <496 6>; resolution = <16>; @@ -2019,7 +2019,7 @@ }; pwm1_0_62: pwm@40581f00 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40581f00 0x80>; system-interrupts = <497 6>; resolution = <16>; @@ -2027,7 +2027,7 @@ }; pwm1_0_63: pwm@40581f80 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40581f80 0x80>; system-interrupts = <498 6>; resolution = <16>; @@ -2035,7 +2035,7 @@ }; pwm1_0_64: pwm@40582000 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40582000 0x80>; system-interrupts = <499 6>; resolution = <16>; @@ -2043,7 +2043,7 @@ }; pwm1_0_65: pwm@40582080 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40582080 0x80>; system-interrupts = <500 6>; resolution = <16>; @@ -2051,7 +2051,7 @@ }; pwm1_0_66: pwm@40582100 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40582100 0x80>; system-interrupts = <501 6>; resolution = <16>; @@ -2059,7 +2059,7 @@ }; pwm1_0_67: pwm@40582180 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40582180 0x80>; system-interrupts = <502 6>; resolution = <16>; @@ -2067,7 +2067,7 @@ }; pwm1_0_68: pwm@40582200 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40582200 0x80>; system-interrupts = <503 6>; resolution = <16>; @@ -2075,7 +2075,7 @@ }; pwm1_0_69: pwm@40582280 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40582280 0x80>; system-interrupts = <504 6>; resolution = <16>; @@ -2083,7 +2083,7 @@ }; pwm1_0_70: pwm@40582300 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40582300 0x80>; system-interrupts = <505 6>; resolution = <16>; @@ -2091,7 +2091,7 @@ }; pwm1_0_71: pwm@40582380 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40582380 0x80>; system-interrupts = <506 6>; resolution = <16>; @@ -2099,7 +2099,7 @@ }; pwm1_0_72: pwm@40582400 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40582400 0x80>; system-interrupts = <507 6>; resolution = <16>; @@ -2107,7 +2107,7 @@ }; pwm1_0_73: pwm@40582480 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40582480 0x80>; system-interrupts = <508 6>; resolution = <16>; @@ -2115,7 +2115,7 @@ }; pwm1_0_74: pwm@40582500 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40582500 0x80>; system-interrupts = <509 6>; resolution = <16>; @@ -2123,7 +2123,7 @@ }; pwm1_0_75: pwm@40582580 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40582580 0x80>; system-interrupts = <510 6>; resolution = <16>; @@ -2131,7 +2131,7 @@ }; pwm1_0_76: pwm@40582600 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40582600 0x80>; system-interrupts = <511 6>; resolution = <16>; @@ -2139,7 +2139,7 @@ }; pwm1_0_77: pwm@40582680 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40582680 0x80>; system-interrupts = <512 6>; resolution = <16>; @@ -2147,7 +2147,7 @@ }; pwm1_0_78: pwm@40582700 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40582700 0x80>; system-interrupts = <513 6>; resolution = <16>; @@ -2155,7 +2155,7 @@ }; pwm1_0_79: pwm@40582780 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40582780 0x80>; system-interrupts = <514 6>; resolution = <16>; @@ -2163,7 +2163,7 @@ }; pwm1_0_80: pwm@40582800 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40582800 0x80>; system-interrupts = <515 6>; resolution = <16>; @@ -2171,7 +2171,7 @@ }; pwm1_0_81: pwm@40582880 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40582880 0x80>; system-interrupts = <516 6>; resolution = <16>; @@ -2179,7 +2179,7 @@ }; pwm1_0_82: pwm@40582900 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40582900 0x80>; system-interrupts = <517 6>; resolution = <16>; @@ -2187,7 +2187,7 @@ }; pwm1_0_83: pwm@40582980 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40582980 0x80>; system-interrupts = <518 6>; resolution = <16>; @@ -2195,7 +2195,7 @@ }; pwm1_1_0: pwm@40588000 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40588000 0x80>; system-interrupts = <522 6>; resolution = <16>; @@ -2203,7 +2203,7 @@ }; pwm1_1_1: pwm@40588080 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40588080 0x80>; system-interrupts = <523 6>; resolution = <16>; @@ -2211,7 +2211,7 @@ }; pwm1_1_2: pwm@40588100 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40588100 0x80>; system-interrupts = <524 6>; resolution = <16>; @@ -2219,7 +2219,7 @@ }; pwm1_1_3: pwm@40588180 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40588180 0x80>; system-interrupts = <525 6>; resolution = <16>; @@ -2227,7 +2227,7 @@ }; pwm1_1_4: pwm@40588200 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40588200 0x80>; system-interrupts = <526 6>; resolution = <16>; @@ -2235,7 +2235,7 @@ }; pwm1_1_5: pwm@40588280 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40588280 0x80>; system-interrupts = <527 6>; resolution = <16>; @@ -2243,7 +2243,7 @@ }; pwm1_1_6: pwm@40588300 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40588300 0x80>; system-interrupts = <528 6>; resolution = <16>; @@ -2251,7 +2251,7 @@ }; pwm1_1_7: pwm@40588380 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40588380 0x80>; system-interrupts = <529 6>; resolution = <16>; @@ -2259,7 +2259,7 @@ }; pwm1_1_8: pwm@40588400 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40588400 0x80>; system-interrupts = <530 6>; resolution = <16>; @@ -2267,7 +2267,7 @@ }; pwm1_1_9: pwm@40588480 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40588480 0x80>; system-interrupts = <531 6>; resolution = <16>; @@ -2275,7 +2275,7 @@ }; pwm1_1_10: pwm@40588500 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40588500 0x80>; system-interrupts = <532 6>; resolution = <16>; @@ -2283,7 +2283,7 @@ }; pwm1_1_11: pwm@40588580 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40588580 0x80>; system-interrupts = <533 6>; resolution = <16>; @@ -2291,7 +2291,7 @@ }; pwm1_2_0: pwm@40590000 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40590000 0x80>; system-interrupts = <537 6>; resolution = <32>; @@ -2299,7 +2299,7 @@ }; pwm1_2_1: pwm@40590080 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40590080 0x80>; system-interrupts = <538 6>; resolution = <32>; @@ -2307,7 +2307,7 @@ }; pwm1_2_2: pwm@40590100 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40590100 0x80>; system-interrupts = <539 6>; resolution = <32>; @@ -2315,7 +2315,7 @@ }; pwm1_2_3: pwm@40590180 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40590180 0x80>; system-interrupts = <540 6>; resolution = <32>; @@ -2323,7 +2323,7 @@ }; pwm1_2_4: pwm@40590200 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40590200 0x80>; system-interrupts = <541 6>; resolution = <32>; @@ -2331,7 +2331,7 @@ }; pwm1_2_5: pwm@40590280 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40590280 0x80>; system-interrupts = <542 6>; resolution = <32>; @@ -2339,7 +2339,7 @@ }; pwm1_2_6: pwm@40590300 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40590300 0x80>; system-interrupts = <543 6>; resolution = <32>; @@ -2347,7 +2347,7 @@ }; pwm1_2_7: pwm@40590380 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40590380 0x80>; system-interrupts = <544 6>; resolution = <32>; @@ -2355,7 +2355,7 @@ }; pwm1_2_8: pwm@40590400 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40590400 0x80>; system-interrupts = <545 6>; resolution = <32>; @@ -2363,7 +2363,7 @@ }; pwm1_2_9: pwm@40590480 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40590480 0x80>; system-interrupts = <546 6>; resolution = <32>; @@ -2371,7 +2371,7 @@ }; pwm1_2_10: pwm@40590500 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40590500 0x80>; system-interrupts = <547 6>; resolution = <32>; @@ -2379,7 +2379,7 @@ }; pwm1_2_11: pwm@40590580 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40590580 0x80>; system-interrupts = <548 6>; resolution = <32>; @@ -2387,7 +2387,7 @@ }; pwm1_2_12: pwm@40590600 { - compatible = "infineon,cat1-pwm"; + compatible = "infineon,pwm"; reg = <0x40590600 0x80>; system-interrupts = <549 6>; resolution = <32>; @@ -2396,7 +2396,7 @@ dma0: dw@40280000 { #dma-cells = <1>; - compatible = "infineon,cat1-dma"; + compatible = "infineon,dma"; reg = <0x40280000 0x10000>; dma-channels = <143>; system-interrupts = <227 6>, /* CH0 */ @@ -2547,7 +2547,7 @@ dma1: dw@40290000 { #dma-cells = <1>; - compatible = "infineon,cat1-dma"; + compatible = "infineon,dma"; reg = <0x40290000 0x10000>; dma-channels = <65>; system-interrupts = <370 6>, /* CH0 */ @@ -2619,7 +2619,7 @@ }; sdhc0: sdhc@40460000 { - compatible = "infineon,cat1-sdhc-sdio"; + compatible = "infineon,sdhc-sdio"; reg = <0x40460000 0x2000>; system-interrupts = <563 6>, /* SDIO wakeup interrupt for mxsdhc */ <562 6>; /* Consolidated interrupt for mxsdhc */ diff --git a/dts/arm/infineon/edge/pse84/pse84.dtsi b/dts/arm/infineon/edge/pse84/pse84.dtsi index c2fae7edddae..fb0980fdcba2 100644 --- a/dts/arm/infineon/edge/pse84/pse84.dtsi +++ b/dts/arm/infineon/edge/pse84/pse84.dtsi @@ -68,19 +68,19 @@ soc { pinctrl: pinctrl@42800000 { - compatible = "infineon,cat1-pinctrl"; + compatible = "infineon,pinctrl"; reg = <0x42800000 0x20000>; }; hsiom: hsiom@42800000 { - compatible = "infineon,cat1-hsiom"; + compatible = "infineon,hsiom"; reg = <0x42800000 0x4000>; interrupts = <41 4>, <40 4>; status = "disabled"; }; gpio_prt0: gpio@42810000 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x42810000 0x80>; interrupts = <0 4>; gpio-controller; @@ -90,7 +90,7 @@ }; gpio_prt1: gpio@42810080 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x42810080 0x80>; interrupts = <59 4>; gpio-controller; @@ -100,7 +100,7 @@ }; gpio_prt2: gpio@42810100 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x42810100 0x80>; interrupts = <1 4>; gpio-controller; @@ -110,7 +110,7 @@ }; gpio_prt3: gpio@42810180 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x42810180 0x80>; interrupts = <2 4>; gpio-controller; @@ -120,7 +120,7 @@ }; gpio_prt4: gpio@42810200 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x42810200 0x80>; interrupts = <60 4>; gpio-controller; @@ -130,7 +130,7 @@ }; gpio_prt5: gpio@42810280 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x42810280 0x80>; interrupts = <3 4>; gpio-controller; @@ -140,7 +140,7 @@ }; gpio_prt6: gpio@42810300 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x42810300 0x80>; interrupts = <4 4>; gpio-controller; @@ -150,7 +150,7 @@ }; gpio_prt7: gpio@42810380 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x42810380 0x80>; interrupts = <5 4>; gpio-controller; @@ -160,7 +160,7 @@ }; gpio_prt8: gpio@42810400 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x42810400 0x80>; interrupts = <6 4>; gpio-controller; @@ -170,7 +170,7 @@ }; gpio_prt9: gpio@42810480 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x42810480 0x80>; interrupts = <7 4>; gpio-controller; @@ -180,7 +180,7 @@ }; gpio_prt10: gpio@42810500 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x42810500 0x80>; interrupts = <8 4>; gpio-controller; @@ -190,7 +190,7 @@ }; gpio_prt11: gpio@42810580 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x42810580 0x80>; interrupts = <9 4>; gpio-controller; @@ -200,7 +200,7 @@ }; gpio_prt12: gpio@42810600 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x42810600 0x80>; interrupts = <10 4>; gpio-controller; @@ -210,7 +210,7 @@ }; gpio_prt13: gpio@42810680 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x42810680 0x80>; interrupts = <11 4>; gpio-controller; @@ -220,7 +220,7 @@ }; gpio_prt14: gpio@42810700 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x42810700 0x80>; interrupts = <12 4>; gpio-controller; @@ -230,7 +230,7 @@ }; gpio_prt15: gpio@42810780 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x42810780 0x80>; interrupts = <13 4>; gpio-controller; @@ -240,7 +240,7 @@ }; gpio_prt16: gpio@42810800 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x42810800 0x80>; interrupts = <14 4>; gpio-controller; @@ -250,7 +250,7 @@ }; gpio_prt17: gpio@42810880 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x42810880 0x80>; interrupts = <15 4>; gpio-controller; @@ -260,7 +260,7 @@ }; gpio_prt18: gpio@42810900 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x42810900 0x80>; interrupts = <16 4>; gpio-controller; @@ -270,7 +270,7 @@ }; gpio_prt19: gpio@42810980 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x42810980 0x80>; interrupts = <17 4>; gpio-controller; @@ -280,7 +280,7 @@ }; gpio_prt20: gpio@42810a00 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x42810a00 0x80>; interrupts = <18 4>; gpio-controller; @@ -290,7 +290,7 @@ }; gpio_prt21: gpio@42810a80 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x42810a80 0x80>; interrupts = <19 4>; gpio-controller; @@ -317,126 +317,126 @@ }; ipc0: ipc@422a0000 { - compatible = "infineon,cat1-ipc"; + compatible = "infineon,ipc"; reg = <0x422a0000 0x1200>; status = "disabled"; #ipc-config-cells = <3>; }; ipc1: ipc@441d0000 { - compatible = "infineon,cat1-ipc"; + compatible = "infineon,ipc"; reg = <0x441d0000 0x1200>; status = "disabled"; #ipc-config-cells = <3>; }; scb0: scb@42990000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x42990000 0xfd0>; interrupts = <43 4>; status = "disabled"; }; scb2: scb@429a0000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x429a0000 0xfd0>; interrupts = <143 4>; status = "disabled"; }; scb3: scb@429b0000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x429b0000 0xfd0>; interrupts = <144 4>; status = "disabled"; }; scb4: scb@429c0000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x429c0000 0xfd0>; interrupts = <145 4>; status = "disabled"; }; scb5: scb@429d0000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x429d0000 0xfd0>; interrupts = <146 4>; status = "disabled"; }; scb6: scb@429e0000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x429e0000 0xfd0>; interrupts = <147 4>; status = "disabled"; }; scb7: scb@429f0000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x429f0000 0xfd0>; interrupts = <148 4>; status = "disabled"; }; scb8: scb@42a00000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x42a00000 0xfd0>; interrupts = <149 4>; status = "disabled"; }; scb9: scb@42a10000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x42a10000 0xfd0>; interrupts = <150 4>; status = "disabled"; }; scb10: scb@42a20000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x42a20000 0xfd0>; interrupts = <151 4>; status = "disabled"; }; scb11: scb@42a30000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x42a30000 0xfd0>; interrupts = <152 4>; status = "disabled"; }; scb1: scb@42d00000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x42d00000 0xfd0>; interrupts = <142 4>; status = "disabled"; }; i3c0: i3c@42a50000 { - compatible = "infineon,cat1-i3c"; + compatible = "infineon,i3c"; reg = <0x42a50000 0x438>; interrupts = <176 4>; status = "disabled"; }; watchdog0: watchdog@4240c000 { - compatible = "infineon,cat1-watchdog"; + compatible = "infineon,watchdog"; reg = <0x4240c000 0x180>; interrupts = <54 4>; status = "disabled"; }; mcwdt0: mcwdt@4240d000 { - compatible = "infineon,cat1-lp-timer-pdl"; + compatible = "infineon,lp-timer-pdl"; reg = <0x4240d000 0x40>; interrupts = <55 4>; status = "disabled"; }; mcwdt1: mcwdt@4240d040 { - compatible = "infineon,cat1-lp-timer-pdl"; + compatible = "infineon,lp-timer-pdl"; reg = <0x4240d040 0x40>; interrupts = <0 4>; status = "disabled"; @@ -1064,7 +1064,7 @@ dma0: dw@42270000 { #dma-cells = <1>; - compatible = "infineon,cat1-dma"; + compatible = "infineon,dma"; reg = <0x42270000 0x10000>; dma-channels = <16>; interrupts = <82 4>, /* CH0 */ @@ -1088,7 +1088,7 @@ dma1: dw@42280000 { #dma-cells = <1>; - compatible = "infineon,cat1-dma"; + compatible = "infineon,dma"; reg = <0x42280000 0x10000>; dma-channels = <16>; interrupts = <181 4>, /* CH0 */ @@ -1111,7 +1111,7 @@ }; sdhc0: sdhc@44810000 { - compatible = "infineon,cat1-sdhc-sdio"; + compatible = "infineon,sdhc-sdio"; reg = <0x44810000 0x2000>; interrupts = <155 4>, /* SDIO wakeup interrupt for mxsdhc */ <154 6>; /* Consolidated interrupt for mxsdhc */ @@ -1119,7 +1119,7 @@ }; sdhc1: sdhc@44820000 { - compatible = "infineon,cat1-sdhc-sdio"; + compatible = "infineon,sdhc-sdio"; reg = <0x44820000 0x2000>; interrupts = <157 4>, /* SDIO wakeup interrupt for mxsdhc */ <156 6>; /* Consolidated interrupt for mxsdhc */ diff --git a/dts/arm/infineon/edge/pse84/pse84_s.dtsi b/dts/arm/infineon/edge/pse84/pse84_s.dtsi index 9564d3f66b64..06096d5421a5 100644 --- a/dts/arm/infineon/edge/pse84/pse84_s.dtsi +++ b/dts/arm/infineon/edge/pse84/pse84_s.dtsi @@ -56,19 +56,19 @@ soc { pinctrl: pinctrl@52800000 { - compatible = "infineon,cat1-pinctrl"; + compatible = "infineon,pinctrl"; reg = <0x52800000 0x20000>; }; hsiom: hsiom@52800000 { - compatible = "infineon,cat1-hsiom"; + compatible = "infineon,hsiom"; reg = <0x52800000 0x4000>; interrupts = <42 4>, <40 4>; status = "disabled"; }; gpio_prt0: gpio@52810000 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x52810000 0x80>; interrupts = <20 4>; gpio-controller; @@ -78,7 +78,7 @@ }; gpio_prt1: gpio@52810080 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x52810080 0x80>; gpio-controller; ngpios = <8>; @@ -87,7 +87,7 @@ }; gpio_prt2: gpio@52810100 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x52810100 0x80>; interrupts = <21 4>; gpio-controller; @@ -97,7 +97,7 @@ }; gpio_prt3: gpio@52810180 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x52810180 0x80>; interrupts = <22 4>; gpio-controller; @@ -107,7 +107,7 @@ }; gpio_prt4: gpio@52810200 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x52810200 0x80>; gpio-controller; ngpios = <8>; @@ -116,7 +116,7 @@ }; gpio_prt5: gpio@52810280 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x52810280 0x80>; interrupts = <23 4>; gpio-controller; @@ -126,7 +126,7 @@ }; gpio_prt6: gpio@52810300 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x52810300 0x80>; interrupts = <24 4>; gpio-controller; @@ -136,7 +136,7 @@ }; gpio_prt7: gpio@52810380 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x52810380 0x80>; interrupts = <25 4>; gpio-controller; @@ -146,7 +146,7 @@ }; gpio_prt8: gpio@52810400 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x52810400 0x80>; interrupts = <26 4>; gpio-controller; @@ -156,7 +156,7 @@ }; gpio_prt9: gpio@52810480 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x52810480 0x80>; interrupts = <27 4>; gpio-controller; @@ -166,7 +166,7 @@ }; gpio_prt10: gpio@52810500 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x52810500 0x80>; interrupts = <28 4>; gpio-controller; @@ -176,7 +176,7 @@ }; gpio_prt11: gpio@52810580 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x52810580 0x80>; interrupts = <29 4>; gpio-controller; @@ -186,7 +186,7 @@ }; gpio_prt12: gpio@52810600 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x52810600 0x80>; interrupts = <30 4>; gpio-controller; @@ -196,7 +196,7 @@ }; gpio_prt13: gpio@52810680 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x52810680 0x80>; interrupts = <31 4>; gpio-controller; @@ -206,7 +206,7 @@ }; gpio_prt14: gpio@52810700 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x52810700 0x80>; interrupts = <32 4>; gpio-controller; @@ -216,7 +216,7 @@ }; gpio_prt15: gpio@52810780 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x52810780 0x80>; interrupts = <33 4>; gpio-controller; @@ -226,7 +226,7 @@ }; gpio_prt16: gpio@52810800 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x52810800 0x80>; interrupts = <34 4>; gpio-controller; @@ -236,7 +236,7 @@ }; gpio_prt17: gpio@52810880 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x52810880 0x80>; interrupts = <35 4>; gpio-controller; @@ -246,7 +246,7 @@ }; gpio_prt18: gpio@52810900 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x52810900 0x80>; interrupts = <36 4>; gpio-controller; @@ -256,7 +256,7 @@ }; gpio_prt19: gpio@52810980 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x52810980 0x80>; interrupts = <37 4>; gpio-controller; @@ -266,7 +266,7 @@ }; gpio_prt20: gpio@52810a00 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x52810a00 0x80>; interrupts = <38 4>; gpio-controller; @@ -276,7 +276,7 @@ }; gpio_prt21: gpio@52810a80 { - compatible = "infineon,cat1-gpio"; + compatible = "infineon,gpio"; reg = <0x52810a80 0x80>; interrupts = <39 4>; gpio-controller; @@ -303,126 +303,126 @@ }; ipc0: ipc@522a0000 { - compatible = "infineon,cat1-ipc"; + compatible = "infineon,ipc"; reg = <0x522a0000 0x1200>; status = "disabled"; #ipc-config-cells = <3>; }; ipc1: ipc@541d0000 { - compatible = "infineon,cat1-ipc"; + compatible = "infineon,ipc"; reg = <0x541d0000 0x1200>; status = "disabled"; #ipc-config-cells = <3>; }; scb0: scb@52990000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x52990000 0xfd0>; interrupts = <43 4>; status = "disabled"; }; scb2: scb@529a0000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x529a0000 0xfd0>; interrupts = <143 4>; status = "disabled"; }; scb3: scb@529b0000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x529b0000 0xfd0>; interrupts = <144 4>; status = "disabled"; }; scb4: scb@529c0000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x529c0000 0xfd0>; interrupts = <145 4>; status = "disabled"; }; scb5: scb@529d0000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x529d0000 0xfd0>; interrupts = <146 4>; status = "disabled"; }; scb6: scb@529e0000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x529e0000 0xfd0>; interrupts = <147 4>; status = "disabled"; }; scb7: scb@529f0000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x529f0000 0xfd0>; interrupts = <148 4>; status = "disabled"; }; scb8: scb@52a00000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x52a00000 0xfd0>; interrupts = <149 4>; status = "disabled"; }; scb9: scb@52a10000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x52a10000 0xfd0>; interrupts = <150 4>; status = "disabled"; }; scb10: scb@52a20000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x52a20000 0xfd0>; interrupts = <151 4>; status = "disabled"; }; scb11: scb@52a30000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x52a30000 0xfd0>; interrupts = <152 4>; status = "disabled"; }; scb1: scb@52d00000 { - compatible = "infineon,cat1-scb"; + compatible = "infineon,scb"; reg = <0x52d00000 0xfd0>; interrupts = <142 4>; status = "disabled"; }; i3c0: i3c@52a50000 { - compatible = "infineon,cat1-i3c"; + compatible = "infineon,i3c"; reg = <0x52a50000 0x438>; interrupts = <176 4>; status = "disabled"; }; watchdog0: watchdog@5240c000 { - compatible = "infineon,cat1-watchdog"; + compatible = "infineon,watchdog"; reg = <0x5240c000 0x180>; interrupts = <54 4>; status = "disabled"; }; mcwdt0: mcwdt@5240d000 { - compatible = "infineon,cat1-lp-timer-pdl"; + compatible = "infineon,lp-timer-pdl"; reg = <0x5240d000 0x40>; interrupts = <55 4>; status = "disabled"; }; mcwdt1: mcwdt@5240d040 { - compatible = "infineon,cat1-lp-timer-pdl"; + compatible = "infineon,lp-timer-pdl"; reg = <0x5240d040 0x40>; interrupts = <0 4>; status = "disabled"; @@ -1050,7 +1050,7 @@ dma0: dw@52270000 { #dma-cells = <1>; - compatible = "infineon,cat1-dma"; + compatible = "infineon,dma"; reg = <0x52270000 0x10000>; dma-channels = <16>; interrupts = <82 4>, /* CH0 */ @@ -1074,7 +1074,7 @@ dma1: dw@52280000 { #dma-cells = <1>; - compatible = "infineon,cat1-dma"; + compatible = "infineon,dma"; reg = <0x52280000 0x10000>; dma-channels = <16>; interrupts = <181 4>, /* CH0 */ @@ -1097,7 +1097,7 @@ }; sdhc0: sdhc@54810000 { - compatible = "infineon,cat1-sdhc-sdio"; + compatible = "infineon,sdhc-sdio"; reg = <0x54810000 0x2000>; interrupts = <155 4>, /* SDIO wakeup interrupt for mxsdhc */ <154 6>; /* Consolidated interrupt for mxsdhc */ @@ -1105,7 +1105,7 @@ }; sdhc1: sdhc@54820000 { - compatible = "infineon,cat1-sdhc-sdio"; + compatible = "infineon,sdhc-sdio"; reg = <0x54820000 0x2000>; interrupts = <157 4>, /* SDIO wakeup interrupt for mxsdhc */ <156 6>; /* Consolidated interrupt for mxsdhc */ diff --git a/dts/bindings/adc/infineon,cat1-adc.yaml b/dts/bindings/adc/infineon,adc.yaml similarity index 95% rename from dts/bindings/adc/infineon,cat1-adc.yaml rename to dts/bindings/adc/infineon,adc.yaml index 6b58cd1343ab..eca54758269b 100644 --- a/dts/bindings/adc/infineon,cat1-adc.yaml +++ b/dts/bindings/adc/infineon,adc.yaml @@ -10,7 +10,7 @@ description: | the board. For example on the cy8cproto_062_4343w P10.0 is mapped to adc0,channel0 and P10.1 is mapped to adc0,channel1. -compatible: "infineon,cat1-adc" +compatible: "infineon,adc" include: adc-controller.yaml diff --git a/dts/bindings/arm/infineon,cat1-scb.yaml b/dts/bindings/arm/infineon,scb.yaml similarity index 93% rename from dts/bindings/arm/infineon,cat1-scb.yaml rename to dts/bindings/arm/infineon,scb.yaml index bd00278189fc..a43b5406ef3e 100644 --- a/dts/bindings/arm/infineon,cat1-scb.yaml +++ b/dts/bindings/arm/infineon,scb.yaml @@ -5,7 +5,7 @@ description: Infineon Serial Communication Blocks (SCB) node -compatible: "infineon,cat1-scb" +compatible: "infineon,scb" include: [base.yaml, "infineon,system-interrupts.yaml"] diff --git a/dts/bindings/bluetooth/infineon,cat1-bless-hci.yaml b/dts/bindings/bluetooth/infineon,bless-hci.yaml similarity index 92% rename from dts/bindings/bluetooth/infineon,cat1-bless-hci.yaml rename to dts/bindings/bluetooth/infineon,bless-hci.yaml index 1a145908c133..443909a52421 100644 --- a/dts/bindings/bluetooth/infineon,cat1-bless-hci.yaml +++ b/dts/bindings/bluetooth/infineon,bless-hci.yaml @@ -6,7 +6,7 @@ description: | Bluetooth module that uses Infineon's Host Controller Interface -compatible: "infineon,cat1-bless-hci" +compatible: "infineon,bless-hci" include: bt-hci.yaml diff --git a/dts/bindings/counter/infineon,cat1-counter.yaml b/dts/bindings/counter/infineon,counter.yaml similarity index 95% rename from dts/bindings/counter/infineon,cat1-counter.yaml rename to dts/bindings/counter/infineon,counter.yaml index 40be6e835b23..0de8ca31e076 100644 --- a/dts/bindings/counter/infineon,cat1-counter.yaml +++ b/dts/bindings/counter/infineon,counter.yaml @@ -5,7 +5,7 @@ description: Infineon counters -compatible: "infineon,cat1-counter" +compatible: "infineon,counter" include: [base.yaml, "infineon,system-interrupts.yaml"] diff --git a/dts/bindings/dma/infineon,cat1-dma.yaml b/dts/bindings/dma/infineon,dma.yaml similarity index 95% rename from dts/bindings/dma/infineon,cat1-dma.yaml rename to dts/bindings/dma/infineon,dma.yaml index a01ed5291a6e..de0b30101f38 100644 --- a/dts/bindings/dma/infineon,cat1-dma.yaml +++ b/dts/bindings/dma/infineon,dma.yaml @@ -8,7 +8,7 @@ title: Infineon CAT1 DMA description: | DMA for Infineon CAT1 devices -compatible: "infineon,cat1-dma" +compatible: "infineon,dma" include: [dma-controller.yaml, "infineon,system-interrupts.yaml"] diff --git a/dts/bindings/flash_controller/infineon,cat1-flash-controller.yaml b/dts/bindings/flash_controller/infineon,flash-controller.yaml similarity index 63% rename from dts/bindings/flash_controller/infineon,cat1-flash-controller.yaml rename to dts/bindings/flash_controller/infineon,flash-controller.yaml index e78983ef0e61..362a12314972 100644 --- a/dts/bindings/flash_controller/infineon,cat1-flash-controller.yaml +++ b/dts/bindings/flash_controller/infineon,flash-controller.yaml @@ -1,5 +1,5 @@ description: Infineon CAT1 flash controller -compatible: "infineon,cat1-flash-controller" +compatible: "infineon,flash-controller" include: flash-controller.yaml diff --git a/dts/bindings/flash_controller/infineon,cat1-qspi-flash.yaml b/dts/bindings/flash_controller/infineon,qspi-flash.yaml similarity index 67% rename from dts/bindings/flash_controller/infineon,cat1-qspi-flash.yaml rename to dts/bindings/flash_controller/infineon,qspi-flash.yaml index dd79972b8ba7..829a8e536a62 100644 --- a/dts/bindings/flash_controller/infineon,cat1-qspi-flash.yaml +++ b/dts/bindings/flash_controller/infineon,qspi-flash.yaml @@ -1,5 +1,5 @@ description: Infineon CAT1 QSPI flash controller -compatible: "infineon,cat1-qspi-flash" +compatible: "infineon,qspi-flash" include: flash-controller.yaml diff --git a/dts/bindings/gpio/infineon,cat1-gpio.yaml b/dts/bindings/gpio/infineon,gpio.yaml similarity index 94% rename from dts/bindings/gpio/infineon,cat1-gpio.yaml rename to dts/bindings/gpio/infineon,gpio.yaml index 0360c084ed28..21841eb954e3 100644 --- a/dts/bindings/gpio/infineon,cat1-gpio.yaml +++ b/dts/bindings/gpio/infineon,gpio.yaml @@ -6,7 +6,7 @@ description: Infineon CAT1 GPIO Port -compatible: "infineon,cat1-gpio" +compatible: "infineon,gpio" include: [gpio-controller.yaml, base.yaml, "infineon,system-interrupts.yaml"] diff --git a/dts/bindings/i2c/infineon,cat1-i2c.yaml b/dts/bindings/i2c/infineon,i2c.yaml similarity index 90% rename from dts/bindings/i2c/infineon,cat1-i2c.yaml rename to dts/bindings/i2c/infineon,i2c.yaml index ef287709b767..df4108189808 100644 --- a/dts/bindings/i2c/infineon,cat1-i2c.yaml +++ b/dts/bindings/i2c/infineon,i2c.yaml @@ -12,7 +12,7 @@ description: | ranging sensor connected on the bus: i2c3: &scb3 { - compatible = "infineon,cat1-i2c"; + compatible = "infineon,i2c"; status = "okay"; #address-cells = <1>; @@ -40,9 +40,9 @@ description: | input-enable; }; -compatible: "infineon,cat1-i2c" +compatible: "infineon,i2c" -include: [i2c-controller.yaml, pinctrl-device.yaml, "infineon,cat1-scb.yaml"] +include: [i2c-controller.yaml, pinctrl-device.yaml, "infineon,scb.yaml"] properties: reg: diff --git a/dts/bindings/pinctrl/infineon,cat1-pinctrl.yaml b/dts/bindings/pinctrl/infineon,pinctrl.yaml similarity index 99% rename from dts/bindings/pinctrl/infineon,cat1-pinctrl.yaml rename to dts/bindings/pinctrl/infineon,pinctrl.yaml index 3c9e8965213d..0b6065970443 100644 --- a/dts/bindings/pinctrl/infineon,cat1-pinctrl.yaml +++ b/dts/bindings/pinctrl/infineon,pinctrl.yaml @@ -97,7 +97,7 @@ description: | input-enable; }; -compatible: "infineon,cat1-pinctrl" +compatible: "infineon,pinctrl" include: base.yaml diff --git a/dts/bindings/rtc/infineon,cat1-rtc.yaml b/dts/bindings/rtc/infineon,rtc.yaml similarity index 90% rename from dts/bindings/rtc/infineon,cat1-rtc.yaml rename to dts/bindings/rtc/infineon,rtc.yaml index b70868e95bb5..0f53bea58a2e 100644 --- a/dts/bindings/rtc/infineon,cat1-rtc.yaml +++ b/dts/bindings/rtc/infineon,rtc.yaml @@ -5,7 +5,7 @@ description: Infineon CAT1 family RTC device -compatible: "infineon,cat1-rtc" +compatible: "infineon,rtc" include: rtc-device.yaml diff --git a/dts/bindings/sdhc/infineon,cat1-sdhc-sdio.yaml b/dts/bindings/sdhc/infineon,sdhc-sdio.yaml similarity index 93% rename from dts/bindings/sdhc/infineon,cat1-sdhc-sdio.yaml rename to dts/bindings/sdhc/infineon,sdhc-sdio.yaml index bdeae2d88ef1..e32efeff5703 100644 --- a/dts/bindings/sdhc/infineon,cat1-sdhc-sdio.yaml +++ b/dts/bindings/sdhc/infineon,sdhc-sdio.yaml @@ -5,7 +5,7 @@ description: Infineon CAT1 SDHC/SDIO controller -compatible: "infineon,cat1-sdhc-sdio" +compatible: "infineon,sdhc-sdio" include: [sdhc.yaml, pinctrl-device.yaml, "infineon,system-interrupts.yaml"] diff --git a/dts/bindings/serial/infineon,cat1-uart.yaml b/dts/bindings/serial/infineon,uart.yaml similarity index 95% rename from dts/bindings/serial/infineon,cat1-uart.yaml rename to dts/bindings/serial/infineon,uart.yaml index 6998a3bd93b6..5331ab0d0b11 100644 --- a/dts/bindings/serial/infineon,cat1-uart.yaml +++ b/dts/bindings/serial/infineon,uart.yaml @@ -7,12 +7,12 @@ description: Infineon CAT1 UART -compatible: "infineon,cat1-uart" +compatible: "infineon,uart" include: - name: uart-controller.yaml - name: pinctrl-device.yaml - - name: "infineon,cat1-scb.yaml" + - name: "infineon,scb.yaml" - name: "infineon,system-interrupts.yaml" properties: diff --git a/dts/bindings/spi/infineon,cat1-spi.yaml b/dts/bindings/spi/infineon,spi.yaml similarity index 91% rename from dts/bindings/spi/infineon,cat1-spi.yaml rename to dts/bindings/spi/infineon,spi.yaml index 4b1000b34976..c12712a927b5 100644 --- a/dts/bindings/spi/infineon,cat1-spi.yaml +++ b/dts/bindings/spi/infineon,spi.yaml @@ -5,7 +5,7 @@ description: Infineon CAT1 SPI -compatible: "infineon,cat1-spi" +compatible: "infineon,spi" include: [spi-controller.yaml, pinctrl-device.yaml] diff --git a/dts/bindings/timer/infineon,cat1-lp-timer.yaml b/dts/bindings/timer/infineon,lp-timer.yaml similarity index 89% rename from dts/bindings/timer/infineon,cat1-lp-timer.yaml rename to dts/bindings/timer/infineon,lp-timer.yaml index 15fae8c9b5db..c0671ab22128 100644 --- a/dts/bindings/timer/infineon,cat1-lp-timer.yaml +++ b/dts/bindings/timer/infineon,lp-timer.yaml @@ -5,7 +5,7 @@ description: Infineon Cat1 low power timer -compatible: "infineon,cat1-lp-timer" +compatible: "infineon,lp-timer" include: [base.yaml, "infineon,system-interrupts.yaml"] diff --git a/dts/bindings/watchdog/infineon,cat1-watchdog.yaml b/dts/bindings/watchdog/infineon,watchdog.yaml similarity index 92% rename from dts/bindings/watchdog/infineon,cat1-watchdog.yaml rename to dts/bindings/watchdog/infineon,watchdog.yaml index 176293f27d6a..a578f4f338eb 100644 --- a/dts/bindings/watchdog/infineon,cat1-watchdog.yaml +++ b/dts/bindings/watchdog/infineon,watchdog.yaml @@ -5,7 +5,7 @@ description: Infineon CAT1 Watchdog -compatible: "infineon,cat1-watchdog" +compatible: "infineon,watchdog" include: [base.yaml, "infineon,system-interrupts.yaml"] diff --git a/samples/drivers/uart/async_api/boards/cy8ckit_062s2_ai.overlay b/samples/drivers/uart/async_api/boards/cy8ckit_062s2_ai.overlay index 1b8c6960429e..46faf514247d 100644 --- a/samples/drivers/uart/async_api/boards/cy8ckit_062s2_ai.overlay +++ b/samples/drivers/uart/async_api/boards/cy8ckit_062s2_ai.overlay @@ -8,7 +8,7 @@ &dma0 { #address-cells = <1>; #size-cells = <0>; - compatible = "infineon,cat1-dma"; + compatible = "infineon,dma"; status = "okay"; }; @@ -21,7 +21,7 @@ }; dut: &scb3 { - compatible = "infineon,cat1-uart"; + compatible = "infineon,uart"; status = "okay"; current-speed = <115200>; diff --git a/samples/drivers/uart/async_api/boards/cy8cproto_062_4343w.overlay b/samples/drivers/uart/async_api/boards/cy8cproto_062_4343w.overlay index 8ddba811bca9..34cd36029951 100644 --- a/samples/drivers/uart/async_api/boards/cy8cproto_062_4343w.overlay +++ b/samples/drivers/uart/async_api/boards/cy8cproto_062_4343w.overlay @@ -1,7 +1,7 @@ &dma0 { #address-cells = <1>; #size-cells = <0>; - compatible = "infineon,cat1-dma"; + compatible = "infineon,dma"; status = "okay"; }; @@ -14,7 +14,7 @@ }; dut: &scb3 { - compatible = "infineon,cat1-uart"; + compatible = "infineon,uart"; status = "okay"; current-speed = <115200>; diff --git a/samples/drivers/uart/async_api/boards/cy8cproto_063_ble.overlay b/samples/drivers/uart/async_api/boards/cy8cproto_063_ble.overlay index 41d9e39187c7..a23d4d8ccffe 100644 --- a/samples/drivers/uart/async_api/boards/cy8cproto_063_ble.overlay +++ b/samples/drivers/uart/async_api/boards/cy8cproto_063_ble.overlay @@ -1,7 +1,7 @@ &dma0 { #address-cells = <1>; #size-cells = <0>; - compatible = "infineon,cat1-dma"; + compatible = "infineon,dma"; status = "okay"; }; diff --git a/samples/drivers/uart/async_api/boards/kit_psc3m5_evk.overlay b/samples/drivers/uart/async_api/boards/kit_psc3m5_evk.overlay index f251fb497ae2..d88043b14f84 100644 --- a/samples/drivers/uart/async_api/boards/kit_psc3m5_evk.overlay +++ b/samples/drivers/uart/async_api/boards/kit_psc3m5_evk.overlay @@ -10,7 +10,7 @@ }; &scb3 { - compatible = "infineon,cat1-uart"; + compatible = "infineon,uart"; status = "okay"; current-speed = <115200>; diff --git a/samples/drivers/uart/async_api/boards/kit_pse84_eval_pse846gps2dbzc4a_m33.overlay b/samples/drivers/uart/async_api/boards/kit_pse84_eval_pse846gps2dbzc4a_m33.overlay index bfccc50d67a4..dc532928ae89 100644 --- a/samples/drivers/uart/async_api/boards/kit_pse84_eval_pse846gps2dbzc4a_m33.overlay +++ b/samples/drivers/uart/async_api/boards/kit_pse84_eval_pse846gps2dbzc4a_m33.overlay @@ -10,7 +10,7 @@ }; &scb2 { - compatible = "infineon,cat1-uart"; + compatible = "infineon,uart"; status = "okay"; current-speed = <115200>; diff --git a/samples/drivers/uart/async_api/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.overlay b/samples/drivers/uart/async_api/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.overlay index bfccc50d67a4..dc532928ae89 100644 --- a/samples/drivers/uart/async_api/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.overlay +++ b/samples/drivers/uart/async_api/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.overlay @@ -10,7 +10,7 @@ }; &scb2 { - compatible = "infineon,cat1-uart"; + compatible = "infineon,uart"; status = "okay"; current-speed = <115200>; diff --git a/tests/drivers/i2c/i2c_api/boards/cy8cproto_063_ble.overlay b/tests/drivers/i2c/i2c_api/boards/cy8cproto_063_ble.overlay index 1339222cb12a..35cff277f8e6 100644 --- a/tests/drivers/i2c/i2c_api/boards/cy8cproto_063_ble.overlay +++ b/tests/drivers/i2c/i2c_api/boards/cy8cproto_063_ble.overlay @@ -13,7 +13,7 @@ }; i2c1: &scb1 { - compatible = "infineon,cat1-i2c"; + compatible = "infineon,i2c"; status = "okay"; pinctrl-0 = <&p10_0_scb1_i2c_scl &p10_1_scb1_i2c_sda>; diff --git a/tests/drivers/i2c/i2c_api/boards/cyw920829m2evk_02_common.overlay b/tests/drivers/i2c/i2c_api/boards/cyw920829m2evk_02_common.overlay index a2fc820268ce..5bff9089197f 100644 --- a/tests/drivers/i2c/i2c_api/boards/cyw920829m2evk_02_common.overlay +++ b/tests/drivers/i2c/i2c_api/boards/cyw920829m2evk_02_common.overlay @@ -15,7 +15,7 @@ i2c0: &scb0 { #address-cells = <1>; #size-cells = <0>; - compatible = "infineon,cat1-i2c"; + compatible = "infineon,i2c"; status = "okay"; pinctrl-0 = <&p0_2_scb0_i2c_scl &p0_3_scb0_i2c_sda>; pinctrl-names = "default"; diff --git a/tests/drivers/spi/spi_loopback/boards/cy8cproto_062_4343w.overlay b/tests/drivers/spi/spi_loopback/boards/cy8cproto_062_4343w.overlay index 6fb4354214e8..4dc309170d45 100644 --- a/tests/drivers/spi/spi_loopback/boards/cy8cproto_062_4343w.overlay +++ b/tests/drivers/spi/spi_loopback/boards/cy8cproto_062_4343w.overlay @@ -1,5 +1,5 @@ spi1: &scb3 { - compatible = "infineon,cat1-spi"; + compatible = "infineon,spi"; status = "okay"; pinctrl-0 = <&p6_0_scb3_spi_m_mosi &p6_1_scb3_spi_m_miso &p6_2_scb3_spi_m_clk>; diff --git a/tests/drivers/spi/spi_loopback/boards/cy8cproto_063_ble.overlay b/tests/drivers/spi/spi_loopback/boards/cy8cproto_063_ble.overlay index e6ddcc3ef2ee..7e11f6f0ae18 100644 --- a/tests/drivers/spi/spi_loopback/boards/cy8cproto_063_ble.overlay +++ b/tests/drivers/spi/spi_loopback/boards/cy8cproto_063_ble.overlay @@ -17,7 +17,7 @@ }; spi: &scb1 { - compatible = "infineon,cat1-spi"; + compatible = "infineon,spi"; status = "okay"; pinctrl-0 = <&p10_0_scb1_spi_m_mosi &p10_1_scb1_spi_m_miso &p10_2_scb1_spi_m_clk>; diff --git a/tests/drivers/spi/spi_loopback/boards/kit_psc3m5_evk.overlay b/tests/drivers/spi/spi_loopback/boards/kit_psc3m5_evk.overlay index b984480372bf..7dca8da2e8b2 100644 --- a/tests/drivers/spi/spi_loopback/boards/kit_psc3m5_evk.overlay +++ b/tests/drivers/spi/spi_loopback/boards/kit_psc3m5_evk.overlay @@ -8,7 +8,7 @@ spi1: &scb4 { #address-cells = <1>; #size-cells = <0>; - compatible = "infineon,cat1-spi"; + compatible = "infineon,spi"; status = "okay"; pinctrl-0 = <&p4_0_scb4_spi_m_mosi &p4_1_scb4_spi_m_miso &p4_2_scb4_spi_m_clk>; diff --git a/tests/drivers/spi/spi_loopback/boards/kit_pse84_eval_common.overlay b/tests/drivers/spi/spi_loopback/boards/kit_pse84_eval_common.overlay index 48c9e839ecb0..535ff0c02725 100644 --- a/tests/drivers/spi/spi_loopback/boards/kit_pse84_eval_common.overlay +++ b/tests/drivers/spi/spi_loopback/boards/kit_pse84_eval_common.overlay @@ -8,7 +8,7 @@ spi1: &scb10 { #address-cells = <1>; #size-cells = <0>; - compatible = "infineon,cat1-spi"; + compatible = "infineon,spi"; status = "okay"; pinctrl-0 = <&p16_1_scb10_spi_m_mosi &p16_2_scb10_spi_m_miso &p16_0_scb10_spi_m_clk>; diff --git a/tests/drivers/uart/uart_async_api/boards/cy8ckit_062s2_ai.overlay b/tests/drivers/uart/uart_async_api/boards/cy8ckit_062s2_ai.overlay index 1b8c6960429e..46faf514247d 100644 --- a/tests/drivers/uart/uart_async_api/boards/cy8ckit_062s2_ai.overlay +++ b/tests/drivers/uart/uart_async_api/boards/cy8ckit_062s2_ai.overlay @@ -8,7 +8,7 @@ &dma0 { #address-cells = <1>; #size-cells = <0>; - compatible = "infineon,cat1-dma"; + compatible = "infineon,dma"; status = "okay"; }; @@ -21,7 +21,7 @@ }; dut: &scb3 { - compatible = "infineon,cat1-uart"; + compatible = "infineon,uart"; status = "okay"; current-speed = <115200>; diff --git a/tests/drivers/uart/uart_async_api/boards/cy8cproto_062_4343w.overlay b/tests/drivers/uart/uart_async_api/boards/cy8cproto_062_4343w.overlay index 8ddba811bca9..34cd36029951 100644 --- a/tests/drivers/uart/uart_async_api/boards/cy8cproto_062_4343w.overlay +++ b/tests/drivers/uart/uart_async_api/boards/cy8cproto_062_4343w.overlay @@ -1,7 +1,7 @@ &dma0 { #address-cells = <1>; #size-cells = <0>; - compatible = "infineon,cat1-dma"; + compatible = "infineon,dma"; status = "okay"; }; @@ -14,7 +14,7 @@ }; dut: &scb3 { - compatible = "infineon,cat1-uart"; + compatible = "infineon,uart"; status = "okay"; current-speed = <115200>; diff --git a/tests/drivers/uart/uart_async_api/boards/cy8cproto_063_ble.overlay b/tests/drivers/uart/uart_async_api/boards/cy8cproto_063_ble.overlay index 41d9e39187c7..a23d4d8ccffe 100644 --- a/tests/drivers/uart/uart_async_api/boards/cy8cproto_063_ble.overlay +++ b/tests/drivers/uart/uart_async_api/boards/cy8cproto_063_ble.overlay @@ -1,7 +1,7 @@ &dma0 { #address-cells = <1>; #size-cells = <0>; - compatible = "infineon,cat1-dma"; + compatible = "infineon,dma"; status = "okay"; }; diff --git a/tests/drivers/uart/uart_async_api/boards/cyw920829m2evk_02_common.overlay b/tests/drivers/uart/uart_async_api/boards/cyw920829m2evk_02_common.overlay index 4a280db993a5..230792e9344c 100644 --- a/tests/drivers/uart/uart_async_api/boards/cyw920829m2evk_02_common.overlay +++ b/tests/drivers/uart/uart_async_api/boards/cyw920829m2evk_02_common.overlay @@ -8,13 +8,13 @@ &dma0 { #address-cells = <1>; #size-cells = <0>; - compatible = "infineon,cat1-dma"; + compatible = "infineon,dma"; status = "okay"; }; dut: &scb1 { - compatible = "infineon,cat1-uart"; + compatible = "infineon,uart"; status = "okay"; current-speed = <115200>; diff --git a/tests/drivers/uart/uart_async_api/boards/kit_psc3m5_evk.overlay b/tests/drivers/uart/uart_async_api/boards/kit_psc3m5_evk.overlay index afe8f5934daf..32164beaf1d5 100644 --- a/tests/drivers/uart/uart_async_api/boards/kit_psc3m5_evk.overlay +++ b/tests/drivers/uart/uart_async_api/boards/kit_psc3m5_evk.overlay @@ -10,7 +10,7 @@ }; dut: &scb4 { - compatible = "infineon,cat1-uart"; + compatible = "infineon,uart"; status = "okay"; current-speed = <115200>; diff --git a/tests/drivers/uart/uart_async_api/boards/kit_pse84_eval_pse846gps2dbzc4a_m33.overlay b/tests/drivers/uart/uart_async_api/boards/kit_pse84_eval_pse846gps2dbzc4a_m33.overlay index 935f0a30b8c4..36af7f2f6820 100644 --- a/tests/drivers/uart/uart_async_api/boards/kit_pse84_eval_pse846gps2dbzc4a_m33.overlay +++ b/tests/drivers/uart/uart_async_api/boards/kit_pse84_eval_pse846gps2dbzc4a_m33.overlay @@ -10,7 +10,7 @@ }; dut: &scb5 { - compatible = "infineon,cat1-uart"; + compatible = "infineon,uart"; status = "okay"; current-speed = <115200>; diff --git a/tests/drivers/uart/uart_async_api/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.overlay b/tests/drivers/uart/uart_async_api/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.overlay index 935f0a30b8c4..36af7f2f6820 100644 --- a/tests/drivers/uart/uart_async_api/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.overlay +++ b/tests/drivers/uart/uart_async_api/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.overlay @@ -10,7 +10,7 @@ }; dut: &scb5 { - compatible = "infineon,cat1-uart"; + compatible = "infineon,uart"; status = "okay"; current-speed = <115200>; From 11243b1f8ce057ab04b75032daabe592ad1d847c Mon Sep 17 00:00:00 2001 From: Sreeram Tatapudi Date: Mon, 8 Dec 2025 14:48:25 -0800 Subject: [PATCH 0548/3659] doc: releases: migration: 4.4: Add infineon driver rename update Adding details regarding the Infineon driver refactoring to drop cat1 from the driver names and binding files. Signed-off-by: Sreeram Tatapudi --- doc/releases/migration-guide-4.4.rst | 35 ++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/doc/releases/migration-guide-4.4.rst b/doc/releases/migration-guide-4.4.rst index c5dba858826b..80f70333f953 100644 --- a/doc/releases/migration-guide-4.4.rst +++ b/doc/releases/migration-guide-4.4.rst @@ -100,6 +100,41 @@ Ethernet reworked to be used as active low, you may have to set the pin as ``GPIO_ACTIVE_LOW`` in devicetree (:github:`100751`). +Infineon +======== + +* Infineon driver file names have been renamed to remove ``cat1`` from their names to support + reusability across multiple device categories. The following drivers have been renamed + (:github:`99174`): + + * ``adc_ifx_cat1.c`` → ``adc_ifx.c`` + * ``clock_control_ifx_cat1.c`` → ``clock_control_ifx.c`` + * ``counter_ifx_cat1.c`` → ``counter_ifx.c`` + * ``dma_ifx_cat1.c`` → ``dma_ifx.c`` + * ``dma_ifx_cat1_pdl.c`` → ``dma_ifx_pdl.c`` + * ``flash_ifx_cat1.c`` → ``flash_ifx.c`` + * ``flash_ifx_cat1_qspi.c`` → ``flash_ifx_qspi.c`` + * ``flash_ifx_cat1_qspi_mtb_hal.c`` → ``flash_ifx_qspi_mtb_hal.c`` + * ``gpio_ifx_cat1.c`` → ``gpio_ifx.c`` + * ``i2c_ifx_cat1.c`` → ``i2c_ifx.c`` + * ``i2c_ifx_cat1_pdl.c`` → ``i2c_ifx_pdl.c`` + * ``mbox_ifx_cat1.c`` → ``mbox_ifx.c`` + * ``pinctrl_ifx_cat1.c`` → ``pinctrl_ifx.c`` + * ``rtc_ifx_cat1.c`` → ``rtc_ifx.c`` + * ``ifx_cat1_sdio.c`` → ``ifx_sdio.c`` + * ``sdio_ifx_cat1_pdl.c`` → ``sdio_ifx_pdl.c`` + * ``serial_ifx_cat1_uart.c`` → ``serial_ifx_uart.c`` + * ``spi_ifx_cat1.c`` → ``spi_ifx.c`` + * ``spi_ifx_cat1_pdl.c`` → ``spi_ifx_pdl.c`` + * ``uart_ifx_cat1.c`` → ``uart_ifx.c`` + * ``uart_ifx_cat1_pdl.c`` → ``uart_ifx_pdl.c`` + * ``wdt_ifx_cat1.c`` → ``wdt_ifx.c`` + + Corresponding Kconfig symbols and binding files have also been updated: + + * ``CONFIG_*_INFINEON_CAT1`` → ``CONFIG_*_INFINEON`` + * ``compatible: "infineon,cat1-adc"`` → ``compatible: "infineon,adc"`` + MDIO ==== From d7900d6d5bf6f180267f8f00900cc5456378bd96 Mon Sep 17 00:00:00 2001 From: Muzaffar Ahmed Date: Mon, 15 Dec 2025 22:45:11 +0530 Subject: [PATCH 0549/3659] drivers: wifi: siwx91x: Disable automatic rejoin in NWP Disable rejoin by setting max_retry_attempts to 1. This is done to keep the NWP state in sync with Zephyr Host, given that Zephyr does not have a "rejoin ongoing" state. Signed-off-by: Muzaffar Ahmed --- drivers/wifi/siwx91x/siwx91x_wifi.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/wifi/siwx91x/siwx91x_wifi.c b/drivers/wifi/siwx91x/siwx91x_wifi.c index 5f8e978866c0..40778ef8d090 100644 --- a/drivers/wifi/siwx91x/siwx91x_wifi.c +++ b/drivers/wifi/siwx91x/siwx91x_wifi.c @@ -454,6 +454,12 @@ static void siwx91x_iface_init(struct net_if *iface) { const struct siwx91x_config *siwx91x_cfg = iface->if_dev->dev->config; struct siwx91x_dev *sidev = iface->if_dev->dev->data; + sl_wifi_advanced_client_configuration_t client_config = { + .max_retry_attempts = 1, + .scan_interval = 0, + .beacon_missed_count = 0, + .first_time_retry_enable = 0, + }; int ret; sidev->state = WIFI_STATE_INTERFACE_DISABLED; @@ -475,6 +481,12 @@ static void siwx91x_iface_init(struct net_if *iface) return; } + ret = sl_wifi_set_advanced_client_configuration(SL_WIFI_CLIENT_INTERFACE, &client_config); + if (ret != SL_STATUS_OK) { + LOG_ERR("Failed to set advanced client config: 0x%x", ret); + return; + } + ret = sl_wifi_get_mac_address(SL_WIFI_CLIENT_INTERFACE, &sidev->macaddr); if (ret) { LOG_ERR("sl_wifi_get_mac_address(): %#04x", ret); From bba3582b8dcc0aa4a37e33d4315599eac85b17cf Mon Sep 17 00:00:00 2001 From: Jason Yu Date: Fri, 14 Nov 2025 15:58:26 +0800 Subject: [PATCH 0550/3659] drivers: interrupt: pint: Add API to get pin used IRQ slot PINT connects GPIO pin to seperate IRQ slot. This info is hidden in PINT driver, there is no way to know which IRQ actually the GPIO pin is connected to. Add new API to get which IRQ slot is connected to, based on pin index. Signed-off-by: Jason Yu --- drivers/interrupt_controller/intc_nxp_pint.c | 16 ++++++++++++++++ .../drivers/interrupt_controller/nxp_pint.h | 7 +++++++ 2 files changed, 23 insertions(+) diff --git a/drivers/interrupt_controller/intc_nxp_pint.c b/drivers/interrupt_controller/intc_nxp_pint.c index 7ed5a8741c00..ad95e78b6a06 100644 --- a/drivers/interrupt_controller/intc_nxp_pint.c +++ b/drivers/interrupt_controller/intc_nxp_pint.c @@ -175,6 +175,22 @@ void nxp_pint_pin_unset_callback(uint8_t pin) pint_irq_cfg[slot].callback = NULL; } +int nxp_pint_pin_get_slot_index(uint8_t pin) +{ + int slot; + + if (pin > ARRAY_SIZE(pin_pint_id)) { + return -EINVAL; + } + + slot = pin_pint_id[pin]; + if (slot == NO_PINT_ID) { + return -EINVAL; + } + + return slot; +} + /* NXP PINT ISR handler- called with PINT slot ID */ static void nxp_pint_isr(uint8_t *slot) { diff --git a/include/zephyr/drivers/interrupt_controller/nxp_pint.h b/include/zephyr/drivers/interrupt_controller/nxp_pint.h index 6bf6d586d83e..def135616641 100644 --- a/include/zephyr/drivers/interrupt_controller/nxp_pint.h +++ b/include/zephyr/drivers/interrupt_controller/nxp_pint.h @@ -79,5 +79,12 @@ int nxp_pint_pin_set_callback(uint8_t pin, nxp_pint_cb_t cb, void *data); */ void nxp_pint_pin_unset_callback(uint8_t pin); +/** + * @brief Get PINT slot index the pin is allocated to + * + * @param pin: The pin to get the PINT slot index for + * @return The allocated slot index, if not allocated, return -EINVAL. + */ +int nxp_pint_pin_get_slot_index(uint8_t pin); #endif /* ZEPHYR_DRIVERS_INTERRUPT_CONTROLLER_INTC_NXP_PINT_H_ */ From 1c5d236248ed28fb1ed82b0ccec8d03eaf280c90 Mon Sep 17 00:00:00 2001 From: Kate Wang Date: Fri, 5 Dec 2025 15:13:06 +0800 Subject: [PATCH 0551/3659] drivers: display: dcnano_lcdif: Update framebuffer placement and pitch 1. For the situation when the RAM space is limited and the driver's frame buffer cannot be place in RAM, add a new property 'ext-ram' in the binding, so if in device tree this property is assigned to a secondary RAM space, place the frame buffer there. The old way is to define the frame bufeer address in Kconfig, which may cause inconvenience if other data also needs to be placed in the same RAM space. 2. Update the driver to support new requirement on RT700. The IP requires a 64-byte alignment for the frame buffer stride. 3. Update the calculation of frame buffer size. If the pixel format is updated, the frame buffer size shall be updated too. Signed-off-by: Kate Wang --- drivers/display/Kconfig.mcux_dcnano_lcdif | 26 +------ drivers/display/display_mcux_dcnano_lcdif.c | 86 +++++++++++++-------- dts/bindings/display/nxp,dcnano-lcdif.yaml | 8 +- 3 files changed, 62 insertions(+), 58 deletions(-) diff --git a/drivers/display/Kconfig.mcux_dcnano_lcdif b/drivers/display/Kconfig.mcux_dcnano_lcdif index 0b33923693e5..be36f393a5b5 100644 --- a/drivers/display/Kconfig.mcux_dcnano_lcdif +++ b/drivers/display/Kconfig.mcux_dcnano_lcdif @@ -1,4 +1,4 @@ -# Copyright 2023 NXP +# Copyright 2023,2025 NXP # SPDX-License-Identifier: Apache-2.0 @@ -34,28 +34,4 @@ config MCUX_DCNANO_LCDIF_MAINTAIN_CACHE required, unless an external framebuffer is utilized with custom caching settings, or caching is disabled. -config MCUX_DCNANO_LCDIF_EXTERNAL_FB_MEM - bool "Use external memory for framebuffer" - imply MEMC - help - Use external memory for framebuffer. Configures the LCDIF to write - framebuffer data to a memory mapped external device. - - Note that no specific linker section is used for this framebuffer, so - if the application uses the external memory for other purposes, care - should be taken to ensure that the memory allocated for the LCDIF - does not overlap with other data. Each allocated LCDIF buffer will - utilize (lcd_width * lcd_height * bytes_per_pixel) bytes of data, - and buffers will be allocated contiguously. - -if MCUX_DCNANO_LCDIF_EXTERNAL_FB_MEM - -config MCUX_DCNANO_LCDIF_EXTERNAL_FB_ADDR - hex "LCDIF framebuffer address" - help - Address of memory mapped external framebuffer. - Must be 128 byte aligned - -endif # MCUX_DCNANO_LCDIF_EXTERNAL_FB_MEM - endif # DISPLAY_MCUX_DCNANO_LCDIF diff --git a/drivers/display/display_mcux_dcnano_lcdif.c b/drivers/display/display_mcux_dcnano_lcdif.c index f94f09b18538..71fa3630c77e 100644 --- a/drivers/display/display_mcux_dcnano_lcdif.c +++ b/drivers/display/display_mcux_dcnano_lcdif.c @@ -1,5 +1,5 @@ /* - * Copyright 2023,2024 NXP + * Copyright 2023-2025 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -11,7 +11,7 @@ #include #include #include - +#include #include #ifdef CONFIG_HAS_MCUX_CACHE #include @@ -20,6 +20,12 @@ LOG_MODULE_REGISTER(display_mcux_dcnano_lcdif, CONFIG_DISPLAY_LOG_LEVEL); +#if DT_ENUM_IDX_OR(DT_NODELABEL(lcdif), version, 0) == 1 +#define MCUX_DCNANO_LCDIF_FB_PITCH_ALIGN (64) +#else +#define MCUX_DCNANO_LCDIF_FB_PITCH_ALIGN (1) +#endif + struct mcux_dcnano_lcdif_config { LCDIF_Type *base; void (*irq_config_func)(const struct device *dev); @@ -27,8 +33,6 @@ struct mcux_dcnano_lcdif_config { lcdif_dpi_config_t dpi_config; /* Pointer to start of first framebuffer */ uint8_t *fb_ptr; - /* Number of bytes used for each framebuffer */ - uint32_t fb_bytes; }; struct mcux_dcnano_lcdif_data { @@ -37,7 +41,10 @@ struct mcux_dcnano_lcdif_data { uint8_t *fb[CONFIG_MCUX_DCNANO_LCDIF_FB_NUM]; lcdif_fb_config_t fb_config; uint8_t pixel_bytes; + uint16_t pitch_bytes; struct k_sem sem; + /* Number of bytes used for each framebuffer, changed when pixel format is changed. */ + uint32_t fb_bytes; /* Tracks index of next active driver framebuffer */ uint8_t next_idx; }; @@ -78,17 +85,17 @@ static int mcux_dcnano_lcdif_write(const struct device *dev, const uint16_t x, */ src = data->active_fb; dst = data->fb[data->next_idx]; - memcpy(dst, src, config->fb_bytes); + memcpy(dst, src, data->fb_bytes); } /* Write the display update to the active framebuffer */ src = buf; dst = data->fb[data->next_idx]; - dst += data->pixel_bytes * (y * config->dpi_config.panelWidth + x); + dst += data->pixel_bytes * x + (y * data->pitch_bytes); for (h_idx = 0; h_idx < desc->height; h_idx++) { memcpy(dst, src, data->pixel_bytes * desc->width); src += data->pixel_bytes * desc->pitch; - dst += data->pixel_bytes * config->dpi_config.panelWidth; + dst += data->pitch_bytes; } LOG_DBG("Setting FB from %p->%p", (void *) data->active_fb, (void *) data->fb[data->next_idx]); @@ -98,14 +105,13 @@ static int mcux_dcnano_lcdif_write(const struct device *dev, const uint16_t x, #if defined(CONFIG_HAS_MCUX_CACHE) && defined(CONFIG_MCUX_DCNANO_LCDIF_MAINTAIN_CACHE) CACHE64_CleanCacheByRange((uint32_t) data->active_fb, - config->fb_bytes); + data->fb_bytes); #endif k_sem_reset(&data->sem); /* Set new framebuffer */ - LCDIF_SetFrameBufferStride(config->base, 0, - config->dpi_config.panelWidth * data->pixel_bytes); + LCDIF_SetFrameBufferStride(config->base, 0, data->pitch_bytes); LCDIF_SetFrameBufferAddr(config->base, 0, (uint32_t)data->active_fb); LCDIF_SetFrameBufferConfig(config->base, 0, &data->fb_config); @@ -131,6 +137,8 @@ static void mcux_dcnano_lcdif_get_capabilities(const struct device *dev, const struct mcux_dcnano_lcdif_config *config = dev->config; struct mcux_dcnano_lcdif_data *data = dev->data; + memset(capabilities, 0, sizeof(struct display_capabilities)); + capabilities->y_resolution = config->dpi_config.panelHeight; capabilities->x_resolution = config->dpi_config.panelWidth; capabilities->supported_pixel_formats = (PIXEL_FORMAT_RGB_565 | PIXEL_FORMAT_ARGB_8888); @@ -178,6 +186,7 @@ static int mcux_dcnano_lcdif_set_pixel_format(const struct device *dev, pixel_format) { struct mcux_dcnano_lcdif_data *data = dev->data; + const struct mcux_dcnano_lcdif_config *config = dev->config; switch (pixel_format) { case PIXEL_FORMAT_RGB_565: @@ -195,6 +204,15 @@ static int mcux_dcnano_lcdif_set_pixel_format(const struct device *dev, default: return -ENOTSUP; } + + /* + * Update the pitch bytes and framebuffer size based on new pixel format, + * they will be used in pixel write. + */ + data->pitch_bytes = ROUND_UP((config->dpi_config.panelWidth * data->pixel_bytes), + MCUX_DCNANO_LCDIF_FB_PITCH_ALIGN); + data->fb_bytes = data->pitch_bytes * config->dpi_config.panelHeight; + return 0; } @@ -244,16 +262,14 @@ static int mcux_dcnano_lcdif_init(const struct device *dev) for (int i = 0; i < CONFIG_MCUX_DCNANO_LCDIF_FB_NUM; i++) { /* Record pointers to each driver framebuffer */ - data->fb[i] = config->fb_ptr + (config->fb_bytes * i); + data->fb[i] = config->fb_ptr + (data->fb_bytes * i); } data->active_fb = config->fb_ptr; k_sem_init(&data->sem, 1, 1); -#ifdef CONFIG_MCUX_DCNANO_LCDIF_EXTERNAL_FB_MEM /* Clear external memory, as it is uninitialized */ - memset(config->fb_ptr, 0, config->fb_bytes * CONFIG_MCUX_DCNANO_LCDIF_FB_NUM); -#endif + memset(config->fb_ptr, 0, data->fb_bytes * CONFIG_MCUX_DCNANO_LCDIF_FB_NUM); return 0; } @@ -267,27 +283,32 @@ static DEVICE_API(display, mcux_dcnano_lcdif_api) = { .get_framebuffer = mcux_dcnano_lcdif_get_framebuffer, }; +/* + * The initial bytes-per-pixel, pitch and frame buffer size. They can be changed + * if pixel format is changed at runtime. + */ #define MCUX_DCNANO_LCDIF_PIXEL_BYTES(n) \ (DISPLAY_BITS_PER_PIXEL(DT_INST_PROP(n, pixel_format)) / BITS_PER_BYTE) -#define MCUX_DCNANO_LCDIF_FB_SIZE(n) DT_INST_PROP(n, width) * \ - DT_INST_PROP(n, height) * MCUX_DCNANO_LCDIF_PIXEL_BYTES(n) +#define MCUX_DCNANO_LCDIF_PITCH_BYTES(n) \ + ROUND_UP((DT_INST_PROP(n, width) * MCUX_DCNANO_LCDIF_PIXEL_BYTES(n)), \ + MCUX_DCNANO_LCDIF_FB_PITCH_ALIGN) +#define MCUX_DCNANO_LCDIF_FB_SIZE(n) MCUX_DCNANO_LCDIF_PITCH_BYTES(n) * \ + DT_INST_PROP(n, height) + +/* Place the frame buffer in secondary RAM if specified, otherwise use default RAM */ +#define MCUX_DCNANO_LCDIF_FB_PLACEMENT(n) \ + COND_CODE_1(DT_INST_NODE_HAS_PROP(n, ext_ram), \ + (Z_GENERIC_SECTION(LINKER_DT_NODE_REGION_NAME(DT_INST_PHANDLE(n, ext_ram)))), \ + ()) + +/* Use 4 Bpp to calculate the largest possible framebuffer size. */ +#define MCUX_DCNANO_LCDIF_FRAMEBUFFER_DECL(n) \ + MCUX_DCNANO_LCDIF_FB_PLACEMENT(n) static uint8_t \ + __aligned(LCDIF_FB_ALIGN) mcux_dcnano_lcdif_frame_buffer_##n \ + [CONFIG_MCUX_DCNANO_LCDIF_FB_NUM * DT_INST_PROP(n, height) * \ + ROUND_UP((DT_INST_PROP(n, width) * 4U), MCUX_DCNANO_LCDIF_FB_PITCH_ALIGN)] -/* When using external framebuffer mem, we should not allocate framebuffers - * in SRAM. Instead, we use external framebuffer address and size - * from devicetree. - */ -#ifdef CONFIG_MCUX_DCNANO_LCDIF_EXTERNAL_FB_MEM -#define MCUX_DCNANO_LCDIF_FRAMEBUFFER_DECL(n) -#define MCUX_DCNANO_LCDIF_FRAMEBUFFER(n) \ - (uint8_t *)CONFIG_MCUX_DCNANO_LCDIF_EXTERNAL_FB_ADDR -#else -#define MCUX_DCNANO_LCDIF_FRAMEBUFFER_DECL(n) uint8_t __aligned(LCDIF_FB_ALIGN) \ - mcux_dcnano_lcdif_frame_buffer_##n[DT_INST_PROP(n, width) * \ - DT_INST_PROP(n, height) * \ - MCUX_DCNANO_LCDIF_PIXEL_BYTES(n) * \ - CONFIG_MCUX_DCNANO_LCDIF_FB_NUM] #define MCUX_DCNANO_LCDIF_FRAMEBUFFER(n) mcux_dcnano_lcdif_frame_buffer_##n -#endif #if DT_ENUM_IDX_OR(DT_NODELABEL(lcdif), version, 0) == 1 #define MCUX_DCNANO_LCDIF_FB_CONFIG(n) \ @@ -327,6 +348,8 @@ static DEVICE_API(display, mcux_dcnano_lcdif_api) = { MCUX_DCNANO_LCDIF_FB_CONFIG(n) \ .next_idx = 0, \ .pixel_bytes = MCUX_DCNANO_LCDIF_PIXEL_BYTES(n), \ + .pitch_bytes = MCUX_DCNANO_LCDIF_PITCH_BYTES(n),\ + .fb_bytes = MCUX_DCNANO_LCDIF_FB_SIZE(n), \ }; \ struct mcux_dcnano_lcdif_config mcux_dcnano_lcdif_config_##n = { \ .base = (LCDIF_Type *) DT_INST_REG_ADDR(n), \ @@ -366,7 +389,6 @@ static DEVICE_API(display, mcux_dcnano_lcdif_api) = { .format = DT_INST_ENUM_IDX(n, data_bus_width), \ }, \ .fb_ptr = MCUX_DCNANO_LCDIF_FRAMEBUFFER(n), \ - .fb_bytes = MCUX_DCNANO_LCDIF_FB_SIZE(n), \ }; \ DEVICE_DT_INST_DEFINE(n, \ &mcux_dcnano_lcdif_init, \ diff --git a/dts/bindings/display/nxp,dcnano-lcdif.yaml b/dts/bindings/display/nxp,dcnano-lcdif.yaml index 376b61855ef2..a32a3ec808bd 100644 --- a/dts/bindings/display/nxp,dcnano-lcdif.yaml +++ b/dts/bindings/display/nxp,dcnano-lcdif.yaml @@ -1,4 +1,4 @@ -# Copyright 2023,2024 NXP +# Copyright 2023-2025 NXP # SPDX-License-Identifier: Apache-2.0 description: NXP DCNano LCDIF (LCD Interface) controller @@ -40,3 +40,9 @@ properties: enum: - "DCnano" - "DC8000" + + ext-ram: + type: phandle + description: | + Secondary RAM in which the controller's frame buffer(s) will + be stored. If not defined, the 'zephyr,ram' chosen memory will be used. From e55a5022f53f37bca238f366a49703a004c9b75c Mon Sep 17 00:00:00 2001 From: Kate Wang Date: Fri, 28 Nov 2025 20:17:24 +0800 Subject: [PATCH 0552/3659] boards: nxp: move memory region definition to board dts for RT500 It is better to let the FLEXSPI2 memory region in the final linker file be generated from dts, in this way user/developer can place the data in the region in code more easily. Signed-off-by: Kate Wang --- .../nxp/mimxrt595_evk/mimxrt595_evk_mimxrt595s_cm33.dts | 8 ++++++++ soc/nxp/imxrt/imxrt5xx/cm33/linker.ld | 3 --- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/boards/nxp/mimxrt595_evk/mimxrt595_evk_mimxrt595s_cm33.dts b/boards/nxp/mimxrt595_evk/mimxrt595_evk_mimxrt595s_cm33.dts index 08c6d7583ad5..071e9d5b61c9 100644 --- a/boards/nxp/mimxrt595_evk/mimxrt595_evk_mimxrt595s_cm33.dts +++ b/boards/nxp/mimxrt595_evk/mimxrt595_evk_mimxrt595s_cm33.dts @@ -135,6 +135,14 @@ enable-gpios = <&gpio3 15 GPIO_ACTIVE_HIGH>; regulator-boot-on; }; + + psram: memory@0x38000000 { + compatible = "zephyr,memory-region"; + device_type = "memory"; + reg = <0x38000000 0x8000000>; + status = "okay"; + zephyr,memory-region = "FLEXSPI2"; + }; }; /* diff --git a/soc/nxp/imxrt/imxrt5xx/cm33/linker.ld b/soc/nxp/imxrt/imxrt5xx/cm33/linker.ld index 2b6a4d63fba9..06914fa51f6f 100644 --- a/soc/nxp/imxrt/imxrt5xx/cm33/linker.ld +++ b/soc/nxp/imxrt/imxrt5xx/cm33/linker.ld @@ -16,9 +16,6 @@ { #if (DT_REG_SIZE_BY_IDX(DT_NODELABEL(flexspi1), 1) > 0) FLEXSPI1 (wx) : ORIGIN = DT_REG_ADDR_BY_IDX(DT_NODELABEL(flexspi1), 1), LENGTH = DT_REG_SIZE_BY_IDX(DT_NODELABEL(flexspi1), 1) -#endif -#if (DT_REG_SIZE_BY_IDX(DT_NODELABEL(flexspi2), 1) > 0) - FLEXSPI2 (wx) : ORIGIN = DT_REG_ADDR_BY_IDX(DT_NODELABEL(flexspi2), 1), LENGTH = DT_REG_SIZE_BY_IDX(DT_NODELABEL(flexspi2), 1) #endif } #include From bf2a0f1911e40e3ac4d571930aa759c2b26f1368 Mon Sep 17 00:00:00 2001 From: Kate Wang Date: Wed, 3 Dec 2025 11:37:27 +0800 Subject: [PATCH 0553/3659] boards: shields: rk055hdmipi4ma0: Update RT500 configuration Remove the external frame buffer configuration. It shall be set in device tree instead now. Signed-off-by: Kate Wang --- .../boards/mimxrt595_evk_mimxrt595s_cm33.conf | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/boards/shields/rk055hdmipi4ma0/boards/mimxrt595_evk_mimxrt595s_cm33.conf b/boards/shields/rk055hdmipi4ma0/boards/mimxrt595_evk_mimxrt595s_cm33.conf index 000b59e0b43c..fccfc5f86597 100644 --- a/boards/shields/rk055hdmipi4ma0/boards/mimxrt595_evk_mimxrt595s_cm33.conf +++ b/boards/shields/rk055hdmipi4ma0/boards/mimxrt595_evk_mimxrt595s_cm33.conf @@ -1,14 +1,10 @@ # -# Copyright 2023, NXP +# Copyright 2023,2025 NXP # # SPDX-License-Identifier: Apache-2.0 # -# Use external framebuffer memory -CONFIG_MCUX_DCNANO_LCDIF_EXTERNAL_FB_MEM=y CONFIG_LV_Z_VDB_CUSTOM_SECTION=y -# Use FlexSPI2 for framebuffer (pSRAM is present on this bus) -CONFIG_MCUX_DCNANO_LCDIF_EXTERNAL_FB_ADDR=0x38400000 # M33 core and LCDIF both access FlexSPI2 through the same cache, # so coherency does not need to be managed. CONFIG_MCUX_DCNANO_LCDIF_MAINTAIN_CACHE=n From cf7f3f672fddff4260e0c1fe4e9570da46bb8b6e Mon Sep 17 00:00:00 2001 From: Kate Wang Date: Wed, 3 Dec 2025 14:12:32 +0800 Subject: [PATCH 0554/3659] boards: shields: rk055hdmipi4m: Update RT500 configuration Remove the external frame buffer configuration. It shall be set in device tree instead now. Signed-off-by: Kate Wang --- .../rk055hdmipi4m/boards/mimxrt595_evk_mimxrt595s_cm33.conf | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/boards/shields/rk055hdmipi4m/boards/mimxrt595_evk_mimxrt595s_cm33.conf b/boards/shields/rk055hdmipi4m/boards/mimxrt595_evk_mimxrt595s_cm33.conf index 000b59e0b43c..fccfc5f86597 100644 --- a/boards/shields/rk055hdmipi4m/boards/mimxrt595_evk_mimxrt595s_cm33.conf +++ b/boards/shields/rk055hdmipi4m/boards/mimxrt595_evk_mimxrt595s_cm33.conf @@ -1,14 +1,10 @@ # -# Copyright 2023, NXP +# Copyright 2023,2025 NXP # # SPDX-License-Identifier: Apache-2.0 # -# Use external framebuffer memory -CONFIG_MCUX_DCNANO_LCDIF_EXTERNAL_FB_MEM=y CONFIG_LV_Z_VDB_CUSTOM_SECTION=y -# Use FlexSPI2 for framebuffer (pSRAM is present on this bus) -CONFIG_MCUX_DCNANO_LCDIF_EXTERNAL_FB_ADDR=0x38400000 # M33 core and LCDIF both access FlexSPI2 through the same cache, # so coherency does not need to be managed. CONFIG_MCUX_DCNANO_LCDIF_MAINTAIN_CACHE=n From 1ffdbb4b5bdd8a13b9e24f3dd77aea2341d9ae56 Mon Sep 17 00:00:00 2001 From: Kate Wang Date: Fri, 5 Dec 2025 14:48:38 +0800 Subject: [PATCH 0555/3659] boards: nxp: Add memory region definition in board dts for RT700 Add memory region definition for PSRAM space which is controlled by XPSI2 in board dts for RT700. In this way user/developer can place the data in the region in code more easily. This space can be used by media domain masters like DCNano lcdif controller. Signed-off-by: Kate Wang --- .../mimxrt700_evk/mimxrt700_evk_mimxrt798s_cm33_cpu0.dts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/boards/nxp/mimxrt700_evk/mimxrt700_evk_mimxrt798s_cm33_cpu0.dts b/boards/nxp/mimxrt700_evk/mimxrt700_evk_mimxrt798s_cm33_cpu0.dts index 8feb364fd49e..2bf7fa89d26a 100644 --- a/boards/nxp/mimxrt700_evk/mimxrt700_evk_mimxrt798s_cm33_cpu0.dts +++ b/boards/nxp/mimxrt700_evk/mimxrt700_evk_mimxrt798s_cm33_cpu0.dts @@ -109,6 +109,15 @@ zephyr,memory-region = "PSRAM"; }; }; + + /* Memory region controlled by XSPI2, can be used by media domain masters. */ + psram2: memory@70000000 { + compatible = "zephyr,memory-region"; + device_type = "memory"; + reg = <0x70000000 0x8000000>; + status = "okay"; + zephyr,memory-region = "PSRAM2"; + }; }; &ctimer0 { From 036220496b38f0ea3de4ce4cbb5391a6abd3e0da Mon Sep 17 00:00:00 2001 From: Kate Wang Date: Fri, 5 Dec 2025 15:01:17 +0800 Subject: [PATCH 0556/3659] boards: shields: rk055hdmipi4ma0: Update RT700 configuration Remove the external frame buffer configuration. It shall be set in device tree instead now. Signed-off-by: Kate Wang --- .../boards/mimxrt700_evk_mimxrt798s_cm33_cpu0.conf | 4 +--- .../boards/mimxrt700_evk_mimxrt798s_cm33_cpu0.overlay | 3 +++ 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/boards/shields/rk055hdmipi4ma0/boards/mimxrt700_evk_mimxrt798s_cm33_cpu0.conf b/boards/shields/rk055hdmipi4ma0/boards/mimxrt700_evk_mimxrt798s_cm33_cpu0.conf index 74ec3e6b6951..42da2b18b9b5 100644 --- a/boards/shields/rk055hdmipi4ma0/boards/mimxrt700_evk_mimxrt798s_cm33_cpu0.conf +++ b/boards/shields/rk055hdmipi4ma0/boards/mimxrt700_evk_mimxrt798s_cm33_cpu0.conf @@ -1,5 +1,3 @@ -CONFIG_MCUX_DCNANO_LCDIF_EXTERNAL_FB_MEM=y -CONFIG_MCUX_DCNANO_LCDIF_EXTERNAL_FB_ADDR=0x60000000 CONFIG_MCUX_DCNANO_LCDIF_MAINTAIN_CACHE=n -CONFIG_HEAP_MEM_POOL_SIZE=40000 CONFIG_REGULATOR=y +CONFIG_MEMC=y # Enable MEMC to use PSRAM diff --git a/boards/shields/rk055hdmipi4ma0/boards/mimxrt700_evk_mimxrt798s_cm33_cpu0.overlay b/boards/shields/rk055hdmipi4ma0/boards/mimxrt700_evk_mimxrt798s_cm33_cpu0.overlay index 2b2ba10faf4e..c5fe73499eb7 100644 --- a/boards/shields/rk055hdmipi4ma0/boards/mimxrt700_evk_mimxrt798s_cm33_cpu0.overlay +++ b/boards/shields/rk055hdmipi4ma0/boards/mimxrt700_evk_mimxrt798s_cm33_cpu0.overlay @@ -11,6 +11,9 @@ display-timings { clock-frequency = <29333333>; }; + + /* Secondary RAM space for large frame buffer(s). */ + ext-ram = <&psram2>; }; &zephyr_mipi_dsi { From 0798beeb34c7d51db8899c2147334d36006fec15 Mon Sep 17 00:00:00 2001 From: Kate Wang Date: Fri, 5 Dec 2025 15:02:47 +0800 Subject: [PATCH 0557/3659] samples: drivers: display: Enable new panel rk055hdmipi4ma0 for RT700 Add heap size configuration and add new panel rk055hdmipi4ma0 for RT700. It requires extra space for 720p panel. Signed-off-by: Kate Wang --- .../display/boards/mimxrt700_evk_mimxrt798s_cm33_cpu0.conf | 4 ++++ samples/drivers/display/sample.yaml | 1 + 2 files changed, 5 insertions(+) diff --git a/samples/drivers/display/boards/mimxrt700_evk_mimxrt798s_cm33_cpu0.conf b/samples/drivers/display/boards/mimxrt700_evk_mimxrt798s_cm33_cpu0.conf index a3429f2c531f..2fd0fdc4fff3 100644 --- a/samples/drivers/display/boards/mimxrt700_evk_mimxrt798s_cm33_cpu0.conf +++ b/samples/drivers/display/boards/mimxrt700_evk_mimxrt798s_cm33_cpu0.conf @@ -6,3 +6,7 @@ CONFIG_SAMPLE_BUFFER_ADDR_ALIGN=64 CONFIG_SAMPLE_PITCH_ALIGN=64 +# Sample will allocate buffer equal to: (panelwidth / 8) * (panelwidth / 4) * pixel depth. For a +# 1280x720 display in a 32-bpp format (e.g. ARGB8888), this is (720 / 8) * (720 / 4) * 4 = 64800 +# bytes. We include 128 bytes of padding for kernel heap structures +CONFIG_HEAP_MEM_POOL_SIZE=64928 diff --git a/samples/drivers/display/sample.yaml b/samples/drivers/display/sample.yaml index cc1db3fa7eef..661a76ab3349 100644 --- a/samples/drivers/display/sample.yaml +++ b/samples/drivers/display/sample.yaml @@ -99,6 +99,7 @@ tests: - platform:frdm_k22f/mk22f51212:SHIELD=ls013b7dh03 - platform:nrf52833dk/nrf52833:SHIELD=st7735r_ada_160x128 - platform:mimxrt1170_evk/mimxrt1176/cm7:SHIELD=rk055hdmipi4ma0 + - platform:mimxrt700_evk/mimxrt798s/cm33_cpu0:SHIELD=rk055hdmipi4ma0 - platform:da1469x_dk_pro/da14699:DTC_OVERLAY_FILE=da1469x_dk_pro_mipi_dbi.overlay - platform:nrf52840dk/nrf52840:SHIELD=max7219_8x8 - platform:stm32h747i_disco/stm32h747xx/m7:SHIELD=st_b_lcd40_dsi1_mb1166 From acbd8e409a1cd37d2aae738ec98a428b66d7b915 Mon Sep 17 00:00:00 2001 From: Kate Wang Date: Fri, 5 Dec 2025 15:29:25 +0800 Subject: [PATCH 0558/3659] doc: boards: nxp: Add new supported panels for RT700 Add new supported panels RK055HDMIPI4MA0 and ZC143AC72MIPI in board doc. Signed-off-by: Kate Wang --- boards/nxp/mimxrt700_evk/doc/index.rst | 32 ++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/boards/nxp/mimxrt700_evk/doc/index.rst b/boards/nxp/mimxrt700_evk/doc/index.rst index 8395f1fdcf8a..1369c12c681f 100644 --- a/boards/nxp/mimxrt700_evk/doc/index.rst +++ b/boards/nxp/mimxrt700_evk/doc/index.rst @@ -253,3 +253,35 @@ for a list). The display sample can be built for this module like so: :zephyr-app: samples/drivers/display :goals: build :compact: + +NXP RK055HDMIPI4MA0 720p MIPI Display +===================================== + +The :ref:`rk055hdmipi4ma0` connects to the board's MIPI connector J52 +directly, but some modifications are required (see +:zephyr_file:`boards/shields/rk055hdmipi4ma0/boards/mimxrt700_evk_mimxrt798s_cm33_cpu0.overlay` +for a list). This panel has a 720p resolution which needs large frame buffer(s) so PSRAM memory +region must be used, which needs to connect JP45 1-2. The display sample can be built for this +module like so: + +.. zephyr-app-commands:: + :board: mimxrt700_evk + :shield: rk055hdmipi4ma0 + :zephyr-app: samples/drivers/display + :goals: build + :compact: + +NXP ZC143AC72MIPI MIPI Display +============================== + +The :ref:`zc143ac72mipi` connects to the board's MIPI connector J26 +directly, but some modifications are required (see +:zephyr_file:`boards/shields/zc143ac72mipi/boards/mimxrt700_evk_mimxrt798s_cm33_cpu0.overlay` +for a list). The display sample can be built for this module like so: + +.. zephyr-app-commands:: + :board: mimxrt700_evk + :shield: zc143ac72mipi + :zephyr-app: samples/drivers/display + :goals: build + :compact: From 2b6283def76ae1b5343063e5d4eb9f2b95d54f51 Mon Sep 17 00:00:00 2001 From: Kate Wang Date: Mon, 8 Dec 2025 19:59:50 +0800 Subject: [PATCH 0559/3659] samples: drivers: display: Enable new panel zc143ac72mipi for RT700 Add zc143ac72mipi panel configuration for RT700 platform in display sample test configuration. Signed-off-by: Kate Wang --- samples/drivers/display/sample.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/samples/drivers/display/sample.yaml b/samples/drivers/display/sample.yaml index 661a76ab3349..adc5b4b94301 100644 --- a/samples/drivers/display/sample.yaml +++ b/samples/drivers/display/sample.yaml @@ -100,6 +100,7 @@ tests: - platform:nrf52833dk/nrf52833:SHIELD=st7735r_ada_160x128 - platform:mimxrt1170_evk/mimxrt1176/cm7:SHIELD=rk055hdmipi4ma0 - platform:mimxrt700_evk/mimxrt798s/cm33_cpu0:SHIELD=rk055hdmipi4ma0 + - platform:mimxrt700_evk/mimxrt798s/cm33_cpu0:SHIELD=zc143ac72mipi - platform:da1469x_dk_pro/da14699:DTC_OVERLAY_FILE=da1469x_dk_pro_mipi_dbi.overlay - platform:nrf52840dk/nrf52840:SHIELD=max7219_8x8 - platform:stm32h747i_disco/stm32h747xx/m7:SHIELD=st_b_lcd40_dsi1_mb1166 From 29059ec3d6aaef314dbc598485d5d6de6f35ae5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Wed, 17 Dec 2025 16:04:21 +0100 Subject: [PATCH 0560/3659] scripts: ci: refresh requirements-actions.txt pinned versions and SHAs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Refresh pinned dependencies to pick filelock 3.20.1 version since 3.20.0 is subject to CVE-2025-68146. Signed-off-by: Benjamin Cabé --- scripts/requirements-actions.txt | 312 +++++++++++++++---------------- 1 file changed, 156 insertions(+), 156 deletions(-) diff --git a/scripts/requirements-actions.txt b/scripts/requirements-actions.txt index c7d48b0e8486..1825fadd21d8 100644 --- a/scripts/requirements-actions.txt +++ b/scripts/requirements-actions.txt @@ -19,27 +19,27 @@ attrs==25.4.0 \ # jsonschema # referencing # reuse -awscli==1.43.11 \ - --hash=sha256:68a89867e83a65c52e73ec44234e88e6b8e3b32fe1707f0d1e09be0fee1b981a \ - --hash=sha256:c86cc6d674f28e04fce2639f60c74f6e6d58402ddc443e8ece75c2e828a6c706 +awscli==1.44.1 \ + --hash=sha256:90c357477d37ff72edea467bab87e0d26f6661427eb2232d140b3535eb5287c2 \ + --hash=sha256:c99483606431ddf01644c48e57ba6f60597b05cf51d70dca09dde761045f62bd # via -r requirements-actions.in -beartype==0.22.8 \ - --hash=sha256:b19b21c9359722ee3f7cc433f063b3e13997b27ae8226551ea5062e621f61165 \ - --hash=sha256:b832882d04e41a4097bab9f63e6992bc6de58c414ee84cba9b45b67314f5ab2e +beartype==0.22.9 \ + --hash=sha256:8f82b54aa723a2848a56008d18875f91c1db02c32ef6a62319a002e3e25a975f \ + --hash=sha256:d16c9bbc61ea14637596c5f6fbff2ee99cbe3573e46a716401734ef50c3060c2 # via spdx-tools boolean-py==5.0 \ --hash=sha256:60cbc4bad079753721d32649545505362c754e121570ada4658b852a3a318d95 \ --hash=sha256:ef28a70bd43115208441b53a045d1549e2f0ec6e3d08a9d142cbc41c1938e8d9 # via license-expression -botocore==1.42.5 \ - --hash=sha256:37bfc487f14286d9795920807fcb8318b940835b18fff6bec5253449f377136f \ - --hash=sha256:6aa487f1876c881e2143f6a186b7d8faaf042fc05e0ba7421d821f145356a0c9 +botocore==1.42.11 \ + --hash=sha256:4c5278b9e0f6217f428aade811d409e321782bd14f0a202ff95a298d841be1f7 \ + --hash=sha256:73b0796870f16ccd44729c767ade20e8ed62b31b3aa2be07b35377338dcf6d7c # via # awscli # s3transfer -cachetools==6.2.2 \ - --hash=sha256:6c09c98183bf58560c97b2abfcedcbaf6a896a490f534b031b661d3723b45ace \ - --hash=sha256:8e6d266b25e539df852251cfd6f990b4bc3a141db73b939058d809ebd2590fc6 +cachetools==6.2.4 \ + --hash=sha256:69a7a52634fed8b8bf6e24a050fb60bff1c9bd8f6d24572b99c32d4e71e62a51 \ + --hash=sha256:82c5c05585e70b6ba2d3ae09ea60b79548872185d2f24ae1f2709d37299fd607 # via tox canopen==2.4.1 \ --hash=sha256:20a84bc498b34dadd79cece467d3bbe19591c1c02a8f39331bcc6065c4d8b2eb \ @@ -260,25 +260,25 @@ charset-normalizer==3.4.4 \ # via # python-debian # requests -clang-format==21.1.7 \ - --hash=sha256:04ff3007e8d77f8232f2ba10a0553d3123423488ec789c1240222a2348f39eba \ - --hash=sha256:1915fc0e0161ddeedb0a83be3a15fe9d6a8529d0f1bbdb59ac1ee58328c5960b \ - --hash=sha256:217b4a9e55d2014797319d99a27acc4dccbe4ab8530f7b18e06e3fb0657aafa5 \ - --hash=sha256:353f400124ae27b1d3f354e64bd1525d5a765f81adc155568c9332ed9ef291b6 \ - --hash=sha256:3ef0603809f2684cb9eea8898f5cc5ac9e2d3ff3f49e3038aef05edf45286c8b \ - --hash=sha256:48d0bba35eb95781dab9f6c49fedf69399ad55469bff63153886950b499b5030 \ - --hash=sha256:4fa43c8ecbf59b49c2eff6ced59e1c8adbd4643cb702393b3937bbbf32a7ab35 \ - --hash=sha256:58ec6d955f1e8bf14a871562d961db114025a74bb990cdcbeb88d8563dd6f8a9 \ - --hash=sha256:69b5ea0d2380c8a6318af4e4f306ccbecfee4d11e896dc59294e60b5f357e3e0 \ - --hash=sha256:6d08f8a279061f63e4ecb30bcd3283b4fd8d1ba532e90be69cb7b270c450890e \ - --hash=sha256:80488d0cd061ac143b71cced03677b0059de4a7fbe69e38ad2c009c03febeb02 \ - --hash=sha256:8e40d359abbd9a280b12b93ce8a6fb73c1f72c32c0a7d5c3843fccc848f6ab24 \ - --hash=sha256:9f024d47ca28663d419d833ab0f950589ffcae40c191f31357533b59fbf9f6f3 \ - --hash=sha256:b915e27db1e4e6ad71db6d34936efcf6f05e751cc32cde1e5596bb26b2dd4d1f \ - --hash=sha256:c57dd938d405c0594a97c7a78391fe96f1ebd76facf67fa305415b1a923a8748 \ - --hash=sha256:c8728aa97cd7cce8c38f7d10c4cd7eca87530553dbf9bf17d7713a2b174a2ede \ - --hash=sha256:cbb6ca72d5198ffaf03fa997c6955f45a26929ba64c057dd7fce3fc7b2ec08a1 \ - --hash=sha256:ee4f47db1c226d9ffd07a4c8a265d7f894149854d0fae72f89a854875bfdf67d +clang-format==21.1.8 \ + --hash=sha256:10f7d7004d70b5e03fd3f764fc19fae89cd38d68b3482162cb09cac47c12c7b0 \ + --hash=sha256:143d2dffa71058d05ac5ad71321682e23d638bce22c8f2e3d01ed457d841a5f3 \ + --hash=sha256:1aa10b3f647268361d08bf4f17ce70964b8d9c04d5539e7d8acbebd14dc4a49c \ + --hash=sha256:2f5883ca83f718d8c2272e98b3cbda422fec520824b5a1e335c631dc6d812da7 \ + --hash=sha256:303d5fd53090422119136b1a458e98db429dedd5db0add50e70f885f8c95d82a \ + --hash=sha256:4dd0fee9eaee9915ba7fa08e60ee9ddfba1f754d10d71164482d9eb387c431f0 \ + --hash=sha256:6a4b61a743dad5afc5e60be0c5c8f162f6cf27fff9eed56ec0bf65c2bcbd8a8d \ + --hash=sha256:6b9e0b45cfaf4a18336a6db4666dd6a6aae840e38b038e6d568a65f43ade007c \ + --hash=sha256:94de66c5eeca1270825348687d384750d91f1d8d12216b2df0aea892859be33a \ + --hash=sha256:9731aecf954651004f184347d0c589d4e91a39ccda21262ee17c60f80a4408b2 \ + --hash=sha256:99369fe76526ba6be6d7a8093fee6cd266bbf5ce72597a0d79a4ce9a625b28cf \ + --hash=sha256:9a78fabba6b382866819b42a7b220d235a3baf6128a40fb7bd590c037f69879b \ + --hash=sha256:a7606da55e31ebf5b63dd75800392e6cca7c595a74100c2cebcda2d742130732 \ + --hash=sha256:b81f1e909f5e7ef862a7818dc22b302a3ff407f3534e3395aa7ba26746cc890e \ + --hash=sha256:c2a044953efab5f7d0261f3a76aabc01358592faac1b73af38d8c83db6e91a69 \ + --hash=sha256:d12b864b596b80810cdd7f97556c485dc09cfe2952503958535f01359e025fbb \ + --hash=sha256:e10a5dca18a04997ad55c082bc0759edc7e337b24a2373ded109634fde12662a \ + --hash=sha256:f447091c346027a09728a0a96128fe058419fe06cf200ccc3dc98bcd4399e351 # via -r requirements-actions.in click==8.3.1 \ --hash=sha256:12ff4785d337a1bb490bb7e9c2b1ee5da3112e94a8622f26a6c77f5d2fc6842a \ @@ -383,9 +383,9 @@ exceptiongroup==1.3.1 \ # via # -r requirements-actions.in # pytest -filelock==3.20.0 \ - --hash=sha256:339b4732ffda5cd79b13f4e2711a31b0365ce445d95d243bb996273d072546a2 \ - --hash=sha256:711e943b4ec6be42e1d4e6690b48dc175c822967466bb31c0c293f34334c13f4 +filelock==3.20.1 \ + --hash=sha256:15d9e9a67306188a44baa72f569d2bfd803076269365fdea0934385da4dc361a \ + --hash=sha256:b8360948b351b80f420878d8516519a2204b07aefcdcfd24912a5d33127f188c # via # tox # virtualenv @@ -548,83 +548,83 @@ junitparser==4.0.2 \ --hash=sha256:94c3570e41fcaedc64cc3c634ca99457fe41a84dd1aa8ff74e9e12e66223a155 \ --hash=sha256:d5d07cece6d4a600ff3b7b96c8db5ffa45a91eed695cb86c45c3db113c1ca0f8 # via -r requirements-actions.in -librt==0.7.3 \ - --hash=sha256:020c6db391268bcc8ce75105cb572df8cb659a43fd347366aaa407c366e5117a \ - --hash=sha256:0fa9ac2e49a6bee56e47573a6786cb635e128a7b12a0dc7851090037c0d397a3 \ - --hash=sha256:11ad45122bbed42cfc8b0597450660126ef28fd2d9ae1a219bc5af8406f95678 \ - --hash=sha256:120dd21d46ff875e849f1aae19346223cf15656be489242fe884036b23d39e93 \ - --hash=sha256:14569ac5dd38cfccf0a14597a88038fb16811a6fede25c67b79c6d50fc2c8fdc \ - --hash=sha256:1617bea5ab31266e152871208502ee943cb349c224846928a1173c864261375e \ - --hash=sha256:170cdb8436188347af17bf9cccf3249ba581c933ed56d926497119d4cf730cec \ - --hash=sha256:1975eda520957c6e0eb52d12968dd3609ffb7eef05d4223d097893d6daf1d8a7 \ - --hash=sha256:1fe603877e1865b5fd047a5e40379509a4a60204aa7aa0f72b16f7a41c3f0712 \ - --hash=sha256:24d70810f6e2ea853ff79338001533716b373cc0f63e2a0be5bc96129edb5fb5 \ - --hash=sha256:256793988bff98040de23c57cf36e1f4c2f2dc3dcd17537cdac031d3b681db71 \ - --hash=sha256:25711f364c64cab2c910a0247e90b51421e45dbc8910ceeb4eac97a9e132fc6f \ - --hash=sha256:2682162855a708e3270eba4b92026b93f8257c3e65278b456c77631faf0f4f7a \ - --hash=sha256:2cf9d73499486ce39eebbff5f42452518cc1f88d8b7ea4a711ab32962b176ee2 \ - --hash=sha256:2e40520c37926166c24d0c2e0f3bc3a5f46646c34bdf7b4ea9747c297d6ee809 \ - --hash=sha256:2e980cf1ed1a2420a6424e2ed884629cdead291686f1048810a817de07b5eb18 \ - --hash=sha256:2f03484b54bf4ae80ab2e504a8d99d20d551bfe64a7ec91e218010b467d77093 \ - --hash=sha256:35f1609e3484a649bb80431310ddbec81114cd86648f1d9482bc72a3b86ded2e \ - --hash=sha256:399938edbd3d78339f797d685142dd8a623dfaded023cf451033c85955e4838a \ - --hash=sha256:399bbd7bcc1633c3e356ae274a1deb8781c7bf84d9c7962cc1ae0c6e87837292 \ - --hash=sha256:3ec50cf65235ff5c02c5b747748d9222e564ad48597122a361269dd3aa808798 \ - --hash=sha256:3edbf257c40d21a42615e9e332a6b10a8bacaaf58250aed8552a14a70efd0d65 \ - --hash=sha256:440c788f707c061d237c1e83edf6164ff19f5c0f823a3bf054e88804ebf971ec \ - --hash=sha256:44b3689b040df57f492e02cd4f0bacd1b42c5400e4b8048160c9d5e866de8abe \ - --hash=sha256:4887c29cadbdc50640179e3861c276325ff2986791e6044f73136e6e798ff806 \ - --hash=sha256:5460d99ed30f043595bbdc888f542bad2caeb6226b01c33cda3ae444e8f82d42 \ - --hash=sha256:550fdbfbf5bba6a2960b27376ca76d6aaa2bd4b1a06c4255edd8520c306fcfc0 \ - --hash=sha256:56f2a47beda8409061bc1c865bef2d4bd9ff9255219402c0817e68ab5ad89aed \ - --hash=sha256:572a24fc5958c61431da456a0ef1eeea6b4989d81eeb18b8e5f1f3077592200b \ - --hash=sha256:59cb0470612d21fa1efddfa0dd710756b50d9c7fb6c1236bbf8ef8529331dc70 \ - --hash=sha256:6038ccbd5968325a5d6fd393cf6e00b622a8de545f0994b89dd0f748dcf3e19e \ - --hash=sha256:6488e69d408b492e08bfb68f20c4a899a354b4386a446ecd490baff8d0862720 \ - --hash=sha256:687403cced6a29590e6be6964463835315905221d797bc5c934a98750fe1a9af \ - --hash=sha256:6b407c23f16ccc36614c136251d6b32bf30de7a57f8e782378f1107be008ddb0 \ - --hash=sha256:6b4e7bff1d76dd2b46443078519dc75df1b5e01562345f0bb740cea5266d8218 \ - --hash=sha256:6bdd9adfca615903578d2060ee8a6eb1c24eaf54919ff0ddc820118e5718931b \ - --hash=sha256:6eb9295c730e26b849ed1f4022735f36863eb46b14b6e10604c1c39b8b5efaea \ - --hash=sha256:703456146dc2bf430f7832fd1341adac5c893ec3c1430194fdcefba00012555c \ - --hash=sha256:754a0d09997095ad764ccef050dd5bf26cbf457aab9effcba5890dad081d879e \ - --hash=sha256:7af7785f5edd1f418da09a8cdb9ec84b0213e23d597413e06525340bcce1ea4f \ - --hash=sha256:7b29e97273bd6999e2bfe9fe3531b1f4f64effd28327bced048a33e49b99674a \ - --hash=sha256:7b4f57f7a0c65821c5441d98c47ff7c01d359b1e12328219709bdd97fdd37f90 \ - --hash=sha256:8837d5a52a2d7aa9f4c3220a8484013aed1d8ad75240d9a75ede63709ef89055 \ - --hash=sha256:8ccadf260bb46a61b9c7e89e2218f6efea9f3eeaaab4e3d1f58571890e54858e \ - --hash=sha256:8d8cf653e798ee4c4e654062b633db36984a1572f68c3aa25e364a0ddfbbb910 \ - --hash=sha256:93b2a1f325fefa1482516ced160c8c7b4b8d53226763fa6c93d151fa25164207 \ - --hash=sha256:9f0e0927efe87cd42ad600628e595a1a0aa1c64f6d0b55f7e6059079a428641a \ - --hash=sha256:a59a69deeb458c858b8fea6acf9e2acd5d755d76cd81a655256bc65c20dfff5b \ - --hash=sha256:a9f9b661f82693eb56beb0605156c7fca57f535704ab91837405913417d6990b \ - --hash=sha256:abfc57cab3c53c4546aee31859ef06753bfc136c9d208129bad23e2eca39155a \ - --hash=sha256:aca73d70c3f553552ba9133d4a09e767dcfeee352d8d8d3eb3f77e38a3beb3ed \ - --hash=sha256:adeaa886d607fb02563c1f625cf2ee58778a2567c0c109378da8f17ec3076ad7 \ - --hash=sha256:b278a9248a4e3260fee3db7613772ca9ab6763a129d6d6f29555e2f9b168216d \ - --hash=sha256:b7c1239b64b70be7759554ad1a86288220bbb04d68518b527783c4ad3fb4f80b \ - --hash=sha256:bf8c7735fbfc0754111f00edda35cf9e98a8d478de6c47b04eaa9cef4300eaa7 \ - --hash=sha256:c634a0a6db395fdaba0361aa78395597ee72c3aad651b9a307a3a7eaf5efd67e \ - --hash=sha256:cad9971881e4fec00d96af7eaf4b63aa7a595696fc221808b0d3ce7ca9743258 \ - --hash=sha256:cbdb3f337c88b43c3b49ca377731912c101178be91cb5071aac48faa898e6f8e \ - --hash=sha256:cd8551aa21df6c60baa2624fd086ae7486bdde00c44097b32e1d1b1966e365e0 \ - --hash=sha256:d09f677693328503c9e492e33e9601464297c01f9ebd966ea8fc5308f3069bfd \ - --hash=sha256:d376a35c6561e81d2590506804b428fc1075fcc6298fc5bb49b771534c0ba010 \ - --hash=sha256:d39079379a9a28e74f4d57dc6357fa310a1977b51ff12239d7271ec7e71d67f5 \ - --hash=sha256:d86f94743a11873317094326456b23f8a5788bad9161fd2f0e52088c33564620 \ - --hash=sha256:d91e60ac44bbe3a77a67af4a4c13114cbe9f6d540337ce22f2c9eaf7454ca71f \ - --hash=sha256:d9883b2d819ce83f87ba82a746c81d14ada78784db431e57cc9719179847376e \ - --hash=sha256:e094e445c37c57e9ec612847812c301840239d34ccc5d153a982fa9814478c60 \ - --hash=sha256:e19acfde38cb532a560b98f473adc741c941b7a9bc90f7294bc273d08becb58b \ - --hash=sha256:e32d43610dff472eab939f4d7fbdd240d1667794192690433672ae22d7af8445 \ - --hash=sha256:ed028fc3d41adda916320712838aec289956c89b4f0a361ceadf83a53b4c047a \ - --hash=sha256:ef59c938f72bdbc6ab52dc50f81d0637fde0f194b02d636987cea2ab30f8f55a \ - --hash=sha256:f3d4801db8354436fd3936531e7f0e4feb411f62433a6b6cb32bb416e20b529f \ - --hash=sha256:f57aca20e637750a2c18d979f7096e2c2033cc40cf7ed201494318de1182f135 \ - --hash=sha256:f9da128d0edf990cf0d2ca011b02cd6f639e79286774bd5b0351245cbb5a6e51 \ - --hash=sha256:fbd7351d43b80d9c64c3cfcb50008f786cc82cba0450e8599fdd64f264320bd3 \ - --hash=sha256:fcb72249ac4ea81a7baefcbff74df7029c3cb1cf01a711113fa052d563639c9c \ - --hash=sha256:ff21c554304e8226bf80c3a7754be27c6c3549a9fec563a03c06ee8f494da8fc +librt==0.7.4 ; platform_python_implementation != 'PyPy' \ + --hash=sha256:022cc673e69283a42621dd453e2407cf1647e77f8bd857d7ad7499901e62376f \ + --hash=sha256:02a69369862099e37d00765583052a99d6a68af7e19b887e1b78fee0146b755a \ + --hash=sha256:037f5cb6fe5abe23f1dc058054d50e9699fcc90d0677eee4e4f74a8677636a1a \ + --hash=sha256:064a286e6ab0b4c900e228ab4fa9cb3811b4b83d3e0cc5cd816b2d0f548cb61c \ + --hash=sha256:078ae52ffb3f036396cc4aed558e5b61faedd504a3c1f62b8ae34bf95ae39d94 \ + --hash=sha256:07c4d7c9305e75a0edd3427b79c7bd1d019cd7eddaa7c89dbb10e0c7946bffbb \ + --hash=sha256:0e8f864b521f6cfedb314d171630f827efee08f5c3462bcbc2244ab8e1768cd6 \ + --hash=sha256:0f8cac84196d0ffcadf8469d9ded4d4e3a8b1c666095c2a291e22bf58e1e8a9f \ + --hash=sha256:0fd766bb9ace3498f6b93d32f30c0e7c8ce6b727fecbc84d28160e217bb66254 \ + --hash=sha256:114722f35093da080a333b3834fff04ef43147577ed99dd4db574b03a5f7d170 \ + --hash=sha256:1437c3f72a30c7047f16fd3e972ea58b90172c3c6ca309645c1c68984f05526a \ + --hash=sha256:188b4b1a770f7f95ea035d5bbb9d7367248fc9d12321deef78a269ebf46a5729 \ + --hash=sha256:1b668b1c840183e4e38ed5a99f62fac44c3a3eef16870f7f17cfdfb8b47550ed \ + --hash=sha256:1c4c89fb01157dd0a3bfe9e75cd6253b0a1678922befcd664eca0772a4c6c979 \ + --hash=sha256:1ef704e01cb6ad39ad7af668d51677557ca7e5d377663286f0ee1b6b27c28e5f \ + --hash=sha256:21ea710e96c1e050635700695095962a22ea420d4b3755a25e4909f2172b4ff2 \ + --hash=sha256:25cc40d8eb63f0a7ea4c8f49f524989b9df901969cb860a2bc0e4bad4b8cb8a8 \ + --hash=sha256:2857c875f1edd1feef3c371fbf830a61b632fb4d1e57160bb1e6a3206e6abe67 \ + --hash=sha256:28f990e6821204f516d09dc39966ef8b84556ffd648d5926c9a3f681e8de8906 \ + --hash=sha256:2b3ca211ae8ea540569e9c513da052699b7b06928dcda61247cb4f318122bdb5 \ + --hash=sha256:2e734c2c54423c6dcc77f58a8585ba83b9f72e422f9edf09cab1096d4a4bdc82 \ + --hash=sha256:3485b9bb7dfa66167d5500ffdafdc35415b45f0da06c75eb7df131f3357b174a \ + --hash=sha256:3749ef74c170809e6dee68addec9d2458700a8de703de081c888e92a8b015cf9 \ + --hash=sha256:3871af56c59864d5fd21d1ac001eb2fb3b140d52ba0454720f2e4a19812404ba \ + --hash=sha256:39003fc73f925e684f8521b2dbf34f61a5deb8a20a15dcf53e0d823190ce8848 \ + --hash=sha256:3ca1caedf8331d8ad6027f93b52d68ed8f8009f5c420c246a46fe9d3be06be0f \ + --hash=sha256:419eea245e7ec0fe664eb7e85e7ff97dcdb2513ca4f6b45a8ec4a3346904f95a \ + --hash=sha256:42da201c47c77b6cc91fc17e0e2b330154428d35d6024f3278aa2683e7e2daf2 \ + --hash=sha256:43a2515a33f2bc17b15f7fb49ff6426e49cb1d5b2539bc7f8126b9c5c7f37164 \ + --hash=sha256:4450c354b89dbb266730893862dbff06006c9ed5b06b6016d529b2bf644fc681 \ + --hash=sha256:4df7c9def4fc619a9c2ab402d73a0c5b53899abe090e0100323b13ccb5a3dd82 \ + --hash=sha256:4f1ee004942eaaed6e06c087d93ebc1c67e9a293e5f6b9b5da558df6bf23dc5d \ + --hash=sha256:52e34c6af84e12921748c8354aa6acf1912ca98ba60cdaa6920e34793f1a0788 \ + --hash=sha256:543c42fa242faae0466fe72d297976f3c710a357a219b1efde3a0539a68a6997 \ + --hash=sha256:5a72b905420c4bb2c10c87b5c09fe6faf4a76d64730e3802feef255e43dfbf5a \ + --hash=sha256:618b7459bb392bdf373f2327e477597fff8f9e6a1878fffc1b711c013d1b0da4 \ + --hash=sha256:6bb15ee29d95875ad697d449fe6071b67f730f15a6961913a2b0205015ca0843 \ + --hash=sha256:6fc4aa67fedd827a601f97f0e61cc72711d0a9165f2c518e9a7c38fc1568b9ad \ + --hash=sha256:70969229cb23d9c1a80e14225838d56e464dc71fa34c8342c954fc50e7516dee \ + --hash=sha256:71a56f4671f7ff723451f26a6131754d7c1809e04e22ebfbac1db8c9e6767a20 \ + --hash=sha256:721a7b125a817d60bf4924e1eec2a7867bfcf64cfc333045de1df7a0629e4481 \ + --hash=sha256:76b2ba71265c0102d11458879b4d53ccd0b32b0164d14deb8d2b598a018e502f \ + --hash=sha256:772e18696cf5a64afee908662fbcb1f907460ddc851336ee3a848ef7684c8e1e \ + --hash=sha256:7766b57aeebaf3f1dac14fdd4a75c9a61f2ed56d8ebeefe4189db1cb9d2a3783 \ + --hash=sha256:776dbb9bfa0fc5ce64234b446995d8d9f04badf64f544ca036bd6cff6f0732ce \ + --hash=sha256:77772a4b8b5f77d47d883846928c36d730b6e612a6388c74cba33ad9eb149c11 \ + --hash=sha256:7dd3b5c37e0fb6666c27cf4e2c88ae43da904f2155c4cfc1e5a2fdce3b9fcf92 \ + --hash=sha256:7e4b5ffa1614ad4f32237d739699be444be28de95071bfa4e66a8da9fa777798 \ + --hash=sha256:8a461f6456981d8c8e971ff5a55f2e34f4e60871e665d2f5fde23ee74dea4eeb \ + --hash=sha256:95cb80854a355b284c55f79674f6187cc9574df4dc362524e0cce98c89ee8331 \ + --hash=sha256:a34ae11315d4e26326aaf04e21ccd8d9b7de983635fba38d73e203a9c8e3fe3d \ + --hash=sha256:a4f7339d9e445280f23d63dea842c0c77379c4a47471c538fc8feedab9d8d063 \ + --hash=sha256:a5deebb53d7a4d7e2e758a96befcd8edaaca0633ae71857995a0f16033289e44 \ + --hash=sha256:a9c5de1928c486201b23ed0cc4ac92e6e07be5cd7f3abc57c88a9cf4f0f32108 \ + --hash=sha256:adefe0d48ad35b90b6f361f6ff5a1bd95af80c17d18619c093c60a20e7a5b60c \ + --hash=sha256:b35c63f557653c05b5b1b6559a074dbabe0afee28ee2a05b6c9ba21ad0d16a74 \ + --hash=sha256:b370a77be0a16e1ad0270822c12c21462dc40496e891d3b0caf1617c8cc57e20 \ + --hash=sha256:b4c25312c7f4e6ab35ab16211bdf819e6e4eddcba3b2ea632fb51c9a2a97e105 \ + --hash=sha256:b719c8730c02a606dc0e8413287e8e94ac2d32a51153b300baf1f62347858fba \ + --hash=sha256:bc4aebecc79781a1b77d7d4e7d9fe080385a439e198d993b557b60f9117addaf \ + --hash=sha256:c2a6f1236151e6fe1da289351b5b5bce49651c91554ecc7b70a947bced6fe212 \ + --hash=sha256:c66c2b245926ec15188aead25d395091cb5c9df008d3b3207268cd65557d6286 \ + --hash=sha256:c96cb76f055b33308f6858b9b594618f1b46e147a4d03a4d7f0c449e304b9b95 \ + --hash=sha256:c9cab4b3de1f55e6c30a84c8cee20e4d3b2476f4d547256694a1b0163da4fe32 \ + --hash=sha256:ce1b44091355b68cffd16e2abac07c1cafa953fa935852d3a4dd8975044ca3bf \ + --hash=sha256:ce58420e25097b2fc201aef9b9f6d65df1eb8438e51154e1a7feb8847e4a55ab \ + --hash=sha256:d05acd46b9a52087bfc50c59dfdf96a2c480a601e8898a44821c7fd676598f74 \ + --hash=sha256:d31acb5886c16ae1711741f22504195af46edec8315fe69b77e477682a87a83e \ + --hash=sha256:d44a1b1ba44cbd2fc3cb77992bef6d6fdb1028849824e1dd5e4d746e1f7f7f0b \ + --hash=sha256:d854c6dc0f689bad7ed452d2a3ecff58029d80612d336a45b62c35e917f42d23 \ + --hash=sha256:dc300cb5a5a01947b1ee8099233156fdccd5001739e5f596ecfbc0dab07b5a3b \ + --hash=sha256:e710c983d29d9cc4da29113b323647db286eaf384746344f4a233708cca1a82c \ + --hash=sha256:ec72342cc4d62f38b25a94e28b9efefce41839aecdecf5e9627473ed04b7be16 \ + --hash=sha256:ee8d3323d921e0f6919918a97f9b5445a7dfe647270b2629ec1008aa676c0bc0 \ + --hash=sha256:f79bc3595b6ed159a1bf0cdc70ed6ebec393a874565cab7088a219cca14da727 \ + --hash=sha256:f7fa8beef580091c02b4fd26542de046b2abfe0aaefa02e8bcf68acb7618f2b3 # via mypy license-expression==30.4.4 \ --hash=sha256:421788fdcadb41f049d2dc934ce666626265aeccefddd25e162a26f23bcbf8a4 \ @@ -869,45 +869,45 @@ mccabe==0.7.0 \ --hash=sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325 \ --hash=sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e # via pylint -mypy==1.19.0 \ - --hash=sha256:0c01c99d626380752e527d5ce8e69ffbba2046eb8a060db0329690849cf9b6f9 \ - --hash=sha256:0dde5cb375cb94deff0d4b548b993bec52859d1651e073d63a1386d392a95495 \ - --hash=sha256:0e3c3d1e1d62e678c339e7ade72746a9e0325de42cd2cccc51616c7b2ed1a018 \ - --hash=sha256:0ea4fd21bb48f0da49e6d3b37ef6bd7e8228b9fe41bbf4d80d9364d11adbd43c \ - --hash=sha256:0fb3115cb8fa7c5f887c8a8d81ccdcb94cff334684980d847e5a62e926910e1d \ - --hash=sha256:11f7254c15ab3f8ed68f8e8f5cbe88757848df793e31c36aaa4d4f9783fd08ab \ - --hash=sha256:120cffe120cca5c23c03c77f84abc0c14c5d2e03736f6c312480020082f1994b \ - --hash=sha256:16f76ff3f3fd8137aadf593cb4607d82634fca675e8211ad75c43d86033ee6c6 \ - --hash=sha256:1cf9c59398db1c68a134b0b5354a09a1e124523f00bacd68e553b8bd16ff3299 \ - --hash=sha256:318ba74f75899b0e78b847d8c50821e4c9637c79d9a59680fc1259f29338cb3e \ - --hash=sha256:3210d87b30e6af9c8faed61be2642fcbe60ef77cec64fa1ef810a630a4cf671c \ - --hash=sha256:34ec1ac66d31644f194b7c163d7f8b8434f1b49719d403a5d26c87fff7e913f7 \ - --hash=sha256:37af5166f9475872034b56c5efdcf65ee25394e9e1d172907b84577120714364 \ - --hash=sha256:3ad925b14a0bb99821ff6f734553294aa6a3440a8cb082fe1f5b84dfb662afb1 \ - --hash=sha256:510c014b722308c9bd377993bcbf9a07d7e0692e5fa8fc70e639c1eb19fc6bee \ - --hash=sha256:6016c52ab209919b46169651b362068f632efcd5eb8ef9d1735f6f86da7853b2 \ - --hash=sha256:6148ede033982a8c5ca1143de34c71836a09f105068aaa8b7d5edab2b053e6c8 \ - --hash=sha256:63ea6a00e4bd6822adbfc75b02ab3653a17c02c4347f5bb0cf1d5b9df3a05835 \ - --hash=sha256:7686ed65dbabd24d20066f3115018d2dce030d8fa9db01aa9f0a59b6813e9f9e \ - --hash=sha256:7a500ab5c444268a70565e374fc803972bfd1f09545b13418a5174e29883dab7 \ - --hash=sha256:8f44f2ae3c58421ee05fe609160343c25f70e3967f6e32792b5a78006a9d850f \ - --hash=sha256:a18d8abdda14035c5718acb748faec09571432811af129bf0d9e7b2d6699bf18 \ - --hash=sha256:a31e4c28e8ddb042c84c5e977e28a21195d086aaffaf08b016b78e19c9ef8106 \ - --hash=sha256:a9ac09e52bb0f7fb912f5d2a783345c72441a08ef56ce3e17c1752af36340a39 \ - --hash=sha256:b9d491295825182fba01b6ffe2c6fe4e5a49dbf4e2bb4d1217b6ced3b4797bc6 \ - --hash=sha256:c14a98bc63fd867530e8ec82f217dae29d0550c86e70debc9667fff1ec83284e \ - --hash=sha256:c3385246593ac2b97f155a0e9639be906e73534630f663747c71908dfbf26134 \ - --hash=sha256:cabbee74f29aa9cd3b444ec2f1e4fa5a9d0d746ce7567a6a609e224429781f53 \ - --hash=sha256:cb64b0ba5980466a0f3f9990d1c582bcab8db12e29815ecb57f1408d99b4bff7 \ - --hash=sha256:cf7d84f497f78b682edd407f14a7b6e1a2212b433eedb054e2081380b7395aa3 \ - --hash=sha256:e2c1101ab41d01303103ab6ef82cbbfedb81c1a060c868fa7cc013d573d37ab5 \ - --hash=sha256:f188dcf16483b3e59f9278c4ed939ec0254aa8a60e8fc100648d9ab5ee95a431 \ - --hash=sha256:f2e36bed3c6d9b5f35d28b63ca4b727cb0228e480826ffc8953d1892ddc8999d \ - --hash=sha256:f3e19e3b897562276bb331074d64c076dbdd3e79213f36eed4e592272dabd760 \ - --hash=sha256:f6b874ca77f733222641e5c46e4711648c4037ea13646fd0cdc814c2eaec2528 \ - --hash=sha256:f75e60aca3723a23511948539b0d7ed514dda194bc3755eae0bfc7a6b4887aa7 \ - --hash=sha256:fc51a5b864f73a3a182584b1ac75c404396a17eced54341629d8bdcb644a5bba \ - --hash=sha256:fd4a985b2e32f23bead72e2fb4bbe5d6aceee176be471243bd831d5b2644672d +mypy==1.19.1 \ + --hash=sha256:016f2246209095e8eda7538944daa1d60e1e8134d98983b9fc1e92c1fc0cb8dd \ + --hash=sha256:022ea7279374af1a5d78dfcab853fe6a536eebfda4b59deab53cd21f6cd9f00b \ + --hash=sha256:06e6170bd5836770e8104c8fdd58e5e725cfeb309f0a6c681a811f557e97eac1 \ + --hash=sha256:19d88bb05303fe63f71dd2c6270daca27cb9401c4ca8255fe50d1d920e0eb9ba \ + --hash=sha256:21761006a7f497cb0d4de3d8ef4ca70532256688b0523eee02baf9eec895e27b \ + --hash=sha256:28902ee51f12e0f19e1e16fbe2f8f06b6637f482c459dd393efddd0ec7f82045 \ + --hash=sha256:2899753e2f61e571b3971747e302d5f420c3fd09650e1951e99f823bc3089dac \ + --hash=sha256:2abb24cf3f17864770d18d673c85235ba52456b36a06b6afc1e07c1fdcd3d0e6 \ + --hash=sha256:34c81968774648ab5ac09c29a375fdede03ba253f8f8287847bd480782f73a6a \ + --hash=sha256:409088884802d511ee52ca067707b90c883426bd95514e8cfda8281dc2effe24 \ + --hash=sha256:481daf36a4c443332e2ae9c137dfee878fcea781a2e3f895d54bd3002a900957 \ + --hash=sha256:4b84a7a18f41e167f7995200a1d07a4a6810e89d29859df936f1c3923d263042 \ + --hash=sha256:4f28f99c824ecebcdaa2e55d82953e38ff60ee5ec938476796636b86afa3956e \ + --hash=sha256:5f05aa3d375b385734388e844bc01733bd33c644ab48e9684faa54e5389775ec \ + --hash=sha256:7bcfc336a03a1aaa26dfce9fff3e287a3ba99872a157561cbfcebe67c13308e3 \ + --hash=sha256:804bd67b8054a85447c8954215a906d6eff9cabeabe493fb6334b24f4bfff718 \ + --hash=sha256:8bb5c6f6d043655e055be9b542aa5f3bdd30e4f3589163e85f93f3640060509f \ + --hash=sha256:a009ffa5a621762d0c926a078c2d639104becab69e79538a494bcccb62cc0331 \ + --hash=sha256:a8174a03289288c1f6c46d55cef02379b478bfbc8e358e02047487cad44c6ca1 \ + --hash=sha256:ab43590f9cd5108f41aacf9fca31841142c786827a74ab7cc8a2eacb634e09a1 \ + --hash=sha256:b10e7c2cd7870ba4ad9b2d8a6102eb5ffc1f16ca35e3de6bfa390c1113029d13 \ + --hash=sha256:b13cfdd6c87fc3efb69ea4ec18ef79c74c3f98b4e5498ca9b85ab3b2c2329a67 \ + --hash=sha256:b64d987153888790bcdb03a6473d321820597ab8dd9243b27a92153c4fa50fd2 \ + --hash=sha256:b7951a701c07ea584c4fe327834b92a30825514c868b1f69c30445093fdd9d5a \ + --hash=sha256:bdb12f69bcc02700c2b47e070238f42cb87f18c0bc1fc4cdb4fb2bc5fd7a3b8b \ + --hash=sha256:c35d298c2c4bba75feb2195655dfea8124d855dfd7343bf8b8c055421eaf0cf8 \ + --hash=sha256:c608937067d2fc5a4dd1a5ce92fd9e1398691b8c5d012d66e1ddd430e9244376 \ + --hash=sha256:c9a6538e0415310aad77cb94004ca6482330fece18036b5f360b62c45814c4ef \ + --hash=sha256:d8dfc6ab58ca7dda47d9237349157500468e404b17213d44fc1cb77bce532288 \ + --hash=sha256:da4869fc5e7f62a88f3fe0b5c919d1d9f7ea3cef92d3689de2823fd27e40aa75 \ + --hash=sha256:de759aafbae8763283b2ee5869c7255391fbc4de3ff171f8f030b5ec48381b74 \ + --hash=sha256:e3157c7594ff2ef1634ee058aafc56a82db665c9438fd41b390f3bde1ab12250 \ + --hash=sha256:e3f276d8493c3c97930e354b2595a44a21348b320d859fb4a2b9f66da9ed27ab \ + --hash=sha256:ee4c11e460685c3e0c64a4c5de82ae143622410950d6be863303a1c4ba0e36d6 \ + --hash=sha256:f1235f5ea01b7db5468d53ece6aaddf1ad0b88d9e7462b86ef96fe04995d7247 \ + --hash=sha256:f7cee03c9a2e2ee26ec07479f38ea9c884e301d42c6d43a19d20fb014e3ba925 \ + --hash=sha256:f859fb09d9583a985be9a493d5cfc5515b56b08f7447759a0c5deaf68d80506e \ + --hash=sha256:ffcebe56eb09ff0c0885e750036a095e23793ba6c2e894e7e63f6d89ad51f22e # via -r requirements-actions.in mypy-extensions==1.1.0 \ --hash=sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505 \ @@ -1627,9 +1627,9 @@ typing-extensions==4.15.0 \ # referencing # tox # virtualenv -tzdata==2025.2 \ - --hash=sha256:1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8 \ - --hash=sha256:b60a638fcc0daffadf82fe0f57e53d06bdec2f36c4df66280ae79bce6bd6f2b9 +tzdata==2025.3 \ + --hash=sha256:06a47e5700f3081aab02b2e513160914ff0694bce9947d6b76ebd6bf57cfc5d1 \ + --hash=sha256:de39c2ca5dc7b0344f2eba86f49d614019d29f060fc4ebc8a417896a620b56a7 # via arrow unidiff==0.7.5 \ --hash=sha256:2e5f0162052248946b9f0970a40e9e124236bf86c82b70821143a6fc1dea2574 \ @@ -1639,9 +1639,9 @@ uritools==5.0.0 \ --hash=sha256:68180cad154062bd5b5d9ffcdd464f8de6934414b25462ae807b00b8df9345de \ --hash=sha256:cead3a49ba8fbca3f91857343849d506d8639718f4a2e51b62e87393b493bd6f # via spdx-tools -urllib3==2.6.1 \ - --hash=sha256:5379eb6e1aba4088bae84f8242960017ec8d8e3decf30480b3a1abdaa9671a3f \ - --hash=sha256:e67d06fe947c36a7ca39f4994b08d73922d40e6cca949907be05efa6fd75110b +urllib3==2.6.2 \ + --hash=sha256:016f9c98bb7e98085cb2b4b17b87d2c702975664e4f060c6532e64d1c1a5e797 \ + --hash=sha256:ec21cddfe7724fc7cb4ba4bea7aa8e2ef36f607a4bab81aa6ce42a13dc3f03dd # via # botocore # elastic-transport From 854240d26e2cd0d0fb1b4c6c8facb635212b297b Mon Sep 17 00:00:00 2001 From: Muhammad Waleed Badar Date: Wed, 19 Nov 2025 20:26:36 +0500 Subject: [PATCH 0561/3659] dts: arm: add dts bindings for ARMv7 timer This ensures that correct timer node is selected for ARMv7-based platforms. Signed-off-by: Muhammad Waleed Badar --- dts/bindings/timer/arm,armv7-timer.yaml | 9 +++++++++ include/zephyr/drivers/timer/arm_arch_timer.h | 5 +++++ 2 files changed, 14 insertions(+) create mode 100644 dts/bindings/timer/arm,armv7-timer.yaml diff --git a/dts/bindings/timer/arm,armv7-timer.yaml b/dts/bindings/timer/arm,armv7-timer.yaml new file mode 100644 index 000000000000..2bf3112c5877 --- /dev/null +++ b/dts/bindings/timer/arm,armv7-timer.yaml @@ -0,0 +1,9 @@ +description: per-core ARM architected timer + +compatible: "arm,armv7-timer" + +include: base.yaml + +properties: + interrupts: + required: true diff --git a/include/zephyr/drivers/timer/arm_arch_timer.h b/include/zephyr/drivers/timer/arm_arch_timer.h index c1f4412dbb9c..b1956bbeac20 100644 --- a/include/zephyr/drivers/timer/arm_arch_timer.h +++ b/include/zephyr/drivers/timer/arm_arch_timer.h @@ -10,8 +10,13 @@ #include #include +#include +#if DT_HAS_COMPAT_STATUS_OKAY(arm_armv8_timer) #define ARM_TIMER_NODE DT_INST(0, arm_armv8_timer) +#elif DT_HAS_COMPAT_STATUS_OKAY(arm_armv7_timer) +#define ARM_TIMER_NODE DT_INST(0, arm_armv7_timer) +#endif #define ARM_TIMER_SECURE_IRQ DT_IRQ_BY_IDX(ARM_TIMER_NODE, 0, irq) #define ARM_TIMER_NON_SECURE_IRQ DT_IRQ_BY_IDX(ARM_TIMER_NODE, 1, irq) From 9016f96e01186c552709a9aa7becf28225a7d3ba Mon Sep 17 00:00:00 2001 From: Lyle Zhu Date: Thu, 27 Nov 2025 15:46:13 +0800 Subject: [PATCH 0562/3659] Bluetooth: Classic: HFP_HF: Refactor at parser In current implementation, the additional buffer is required by AT to store the parsing AT response data temporarily. To store the parsed AT response data completely, the buffer size is as high as the MTU of the RFCOMM connection. And the buffer is dedicated for each HFP HF connection. That means the RAM usage depends on the MAX HFP HF connection count. Actually, the RFCOMM receiving buffer is valid when processing the received AT response. The changes aim to remove the additional buffer and leverage the receiving buffer to process the AT response. And there is an issue found that the type of the additional buffer length is `uint8_t`, while the configured RFCOMM receiving data length is 65535. When the additional buffer length exceeds 255, the AT cannot process the received data normally. Replace manual buffer management with net_buf_simple in the AT command parser. This change eliminates the need for manual position tracking and buffer length management by leveraging Zephyr's existing buffer utilities. And leverage RFCOMM receiving buffer instead of allocating dedicated buffer. Signed-off-by: Lyle Zhu --- subsys/bluetooth/host/classic/at.c | 439 ++++++++++++++++++------- subsys/bluetooth/host/classic/at.h | 6 +- subsys/bluetooth/host/classic/hfp_hf.c | 10 +- 3 files changed, 320 insertions(+), 135 deletions(-) diff --git a/subsys/bluetooth/host/classic/at.c b/subsys/bluetooth/host/classic/at.c index b56ad286f06f..fc2fa327dd57 100644 --- a/subsys/bluetooth/host/classic/at.c +++ b/subsys/bluetooth/host/classic/at.c @@ -17,11 +17,41 @@ #include "at.h" -static void next_list(struct at_client *at) +typedef bool (*pull_char_t)(uint8_t *c, void *data); + +static void pull_chars(struct net_buf_simple *buf, pull_char_t cb, void *data) +{ + while (buf->len > 0) { + if (!cb(buf->data, data)) { + break; + } + net_buf_simple_pull_u8(buf); + } +} + +struct at_comma_data { + bool found; +}; + +static bool pull_comma(uint8_t *c, void *data) { - if (at->buf[at->pos] == ',') { - at->pos++; + struct at_comma_data *comma_data = data; + + if (comma_data->found) { + return false; } + + comma_data->found = *c == ','; + return comma_data->found; +} + +static void next_list(struct at_client *at) +{ + struct at_comma_data data; + + data.found = false; + + pull_chars(&at->rsp_buf, pull_comma, &data); } int at_check_byte(struct net_buf *buf, char check_byte) @@ -36,52 +66,87 @@ int at_check_byte(struct net_buf *buf, char check_byte) return 0; } +static bool pull_space(uint8_t *c, void *data) +{ + return *c == ' '; +} + static void skip_space(struct at_client *at) { - while (at->buf[at->pos] == ' ') { - at->pos++; + pull_chars(&at->rsp_buf, pull_space, NULL); +} + +struct at_number_data { + uint32_t val; + bool found; +}; + +static bool pull_number(uint8_t *c, void *data) +{ + struct at_number_data *num_data = data; + + if (isdigit((unsigned char)(*c)) == 0) { + return false; } + + num_data->found = true; + num_data->val = num_data->val * 10 + *c - (uint8_t)'0'; + return true; } int at_get_number(struct at_client *at, uint32_t *val) { - uint32_t i; + struct at_number_data data; skip_space(at); - for (i = 0U, *val = 0U; - isdigit((unsigned char)at->buf[at->pos]) != 0; - at->pos++, i++) { - *val = *val * 10U + at->buf[at->pos] - '0'; - } + data.found = false; + data.val = 0; - if (i == 0U) { + pull_chars(&at->rsp_buf, pull_number, &data); + + if (!data.found) { return -ENODATA; } + *val = data.val; + next_list(at); return 0; } -static bool str_has_prefix(const char *str, const char *prefix) +static bool str_has_prefix(struct at_client *at, const char *prefix) { - if (strncmp(str, prefix, strlen(prefix)) != 0) { + size_t len = strlen(prefix); + + if (at->rsp_buf.len < len) { + return false; + } + + if (strncmp(at->rsp_buf.data, prefix, len) != 0) { return false; } return true; } -static int at_parse_result(const char *str, struct net_buf *buf, +static int at_parse_result(struct at_client *at, struct net_buf *buf, enum at_result *result) { + char *ok = "OK"; + char *error = "ERROR"; + size_t ok_len = strlen(ok); + size_t error_len = strlen(error); + /* Map the result and check for end lf */ - if ((!strncmp(str, "OK", 2)) && (at_check_byte(buf, '\n') == 0)) { + if ((at->rsp_buf.len >= ok_len) && (strncmp(at->rsp_buf.data, ok, ok_len) == 0) && + (at_check_byte(buf, '\n') == 0)) { *result = AT_RESULT_OK; return 0; } - if ((!strncmp(str, "ERROR", 5)) && (at_check_byte(buf, '\n')) == 0) { + if ((at->rsp_buf.len >= error_len) && (strncmp(at->rsp_buf.data, error, error_len) == 0) && + (at_check_byte(buf, '\n') == 0)) { *result = AT_RESULT_ERROR; return 0; } @@ -89,31 +154,38 @@ static int at_parse_result(const char *str, struct net_buf *buf, return -ENOMSG; } +static void init_rsp_buffer(struct at_client *at, struct net_buf *buf) +{ + at->rsp_buf.data = buf->data; + at->rsp_buf.__buf = buf->data; + at->rsp_buf.size = buf->len; + /* Although the valid data is buf->data[0:buf->len], at->rsp_buf.len is set to 0 here. + * This is because it is unclear how much data needs to be processed. + * The value at->rsp_buf.len will be updated later when preprocess the received AT + * responses or unsolicited response code. + */ + at->rsp_buf.len = 0; +} + static int get_cmd_value(struct at_client *at, struct net_buf *buf, char stop_byte, enum at_cmd_state cmd_state) { - int cmd_len = 0; - uint8_t pos = at->pos; - const char *str = (char *)buf->data; - - while (cmd_len < buf->len && at->pos != at->buf_max_len) { - if (*str != stop_byte) { - at->buf[at->pos++] = *str; - cmd_len++; - str++; - pos = at->pos; - } else { - cmd_len++; - at->buf[at->pos] = '\0'; - at->pos = 0U; + if (at->rsp_buf.len == 0) { + init_rsp_buffer(at, buf); + } + + while (buf->len > 0) { + if (buf->data[0] == stop_byte) { at->cmd_state = cmd_state; + net_buf_pull_u8(buf); break; } + net_buf_simple_add(&at->rsp_buf, sizeof(uint8_t)); + net_buf_pull_u8(buf); } - net_buf_pull(buf, cmd_len); - if (pos == at->buf_max_len) { - return -ENOBUFS; + if (at->rsp_buf.len == 0) { + return -ENODATA; } return 0; @@ -126,46 +198,45 @@ static bool is_stop_byte(char target, char *stop_string) static bool is_vgm_or_vgs(struct at_client *at) { - if (!strcmp(at->buf, "VGM")) { + if (at->rsp_buf.len == 0) { + return false; + } + + if (!strncmp(at->rsp_buf.data, "VGM", strlen("VGM"))) { return true; } - if (!strcmp(at->buf, "VGS")) { + if (!strncmp(at->rsp_buf.data, "VGS", strlen("VGS"))) { return true; } + return false; } static int get_response_string(struct at_client *at, struct net_buf *buf, char *stop_string, enum at_state state) { - int cmd_len = 0; - uint8_t pos = at->pos; - const char *str = (char *)buf->data; - - while (cmd_len < buf->len && at->pos != at->buf_max_len) { - if (!is_stop_byte(*str, stop_string)) { - at->buf[at->pos++] = *str; - cmd_len++; - str++; - pos = at->pos; - } else { - char stop_byte = at->buf[at->pos]; - - cmd_len++; - at->buf[at->pos] = '\0'; - at->pos = 0U; + if (at->rsp_buf.len == 0) { + init_rsp_buffer(at, buf); + } + + while (buf->len > 0) { + if (is_stop_byte(buf->data[0], stop_string)) { + char stop_byte = buf->data[0]; + at->state = state; if ((stop_byte == '=') && !is_vgm_or_vgs(at)) { return -EINVAL; } + net_buf_pull_u8(buf); break; } + net_buf_simple_add(&at->rsp_buf, sizeof(uint8_t)); + net_buf_pull_u8(buf); } - net_buf_pull(buf, cmd_len); - if (pos == at->buf_max_len) { - return -ENOBUFS; + if (at->rsp_buf.len == 0) { + return -ENODATA; } return 0; @@ -173,8 +244,7 @@ static int get_response_string(struct at_client *at, struct net_buf *buf, char * static void reset_buffer(struct at_client *at) { - (void)memset(at->buf, 0, at->buf_max_len); - at->pos = 0U; + net_buf_simple_init_with_data(&at->rsp_buf, NULL, 0); } static int at_state_start(struct at_client *at, struct net_buf *buf) @@ -224,7 +294,14 @@ static int at_state_get_cmd_string(struct at_client *at, struct net_buf *buf) static bool is_cmer(struct at_client *at) { - if (strncmp(at->buf, "CME ERROR", 9) == 0) { + char *cmer = "CME ERROR"; + size_t len = strlen(cmer); + + if (at->rsp_buf.len < len) { + return false; + } + + if (strncmp(at->rsp_buf.data, cmer, len) == 0) { return true; } @@ -254,7 +331,14 @@ static int at_state_get_result_string(struct at_client *at, struct net_buf *buf) static bool is_ring(struct at_client *at) { - if (strncmp(at->buf, "RING", 4) == 0) { + char *ring = "RING"; + size_t len = strlen(ring); + + if (at->rsp_buf.len < len) { + return false; + } + + if (strncmp(at->rsp_buf.data, ring, len) == 0) { return true; } @@ -271,7 +355,7 @@ static int at_state_process_result(struct at_client *at, struct net_buf *buf) return 0; } - if (at_parse_result(at->buf, buf, &result) == 0) { + if (at_parse_result(at, buf, &result) == 0) { if (at->finish) { /* cme_err is 0 - Is invalid until result is * AT_RESULT_CME_ERROR @@ -359,7 +443,7 @@ static int at_cmd_start(struct at_client *at, struct net_buf *buf, const char *prefix, parse_val_t func, enum at_cmd_type type) { - if (!str_has_prefix(at->buf, prefix)) { + if (!str_has_prefix(at, prefix)) { if (type == AT_CMD_TYPE_NORMAL) { at->state = AT_STATE_UNSOLICITED_CMD; } @@ -447,66 +531,147 @@ int at_parse_cmd_input(struct at_client *at, struct net_buf *buf, return 0; } -int at_has_next_list(struct at_client *at) +struct has_next_list_data { + bool found; +}; + +static bool at_has_next_list_cb(uint8_t *c, void *data) { - return at->buf[at->pos] != '\0' && at->buf[at->pos] != ')'; + struct has_next_list_data *list_data = data; + + list_data->found = *c != ')'; + return false; +} + +bool at_has_next_list(struct at_client *at) +{ + struct has_next_list_data data; + + data.found = false; + + pull_chars(&at->rsp_buf, at_has_next_list_cb, &data); + + return data.found; +} + +struct open_list_data { + bool found; +}; + +static bool at_open_list_cb(uint8_t *c, void *data) +{ + struct open_list_data *list_data = data; + + if (list_data->found) { + return false; + } + + list_data->found = *c == '('; + return list_data->found; } int at_open_list(struct at_client *at) { + struct open_list_data data; + skip_space(at); - /* The list shall start with '(' open parenthesis */ - if (at->buf[at->pos] != '(') { + data.found = false; + + pull_chars(&at->rsp_buf, at_open_list_cb, &data); + + if (!data.found) { return -ENODATA; } - at->pos++; return 0; } +struct close_list_data { + bool found; +}; + +static bool at_close_list_cb(uint8_t *c, void *data) +{ + struct close_list_data *list_data = data; + + if (list_data->found) { + return false; + } + + list_data->found = *c == ')'; + return list_data->found; +} + int at_close_list(struct at_client *at) { + struct close_list_data data; + skip_space(at); - if (at->buf[at->pos] != ')') { + data.found = false; + + pull_chars(&at->rsp_buf, at_close_list_cb, &data); + + if (!data.found) { return -ENODATA; } - at->pos++; - next_list(at); return 0; } -int at_list_get_string(struct at_client *at, char *name, uint8_t len) -{ - int i = 0; +struct get_string_data { + uint8_t *start; + uint8_t *end; +}; - skip_space(at); +static bool at_get_string_cb(uint8_t *c, void *data) +{ + struct get_string_data *str_data = data; - if (at->buf[at->pos] != '"') { - return -ENODATA; + if ((str_data->start != NULL) && (str_data->end != NULL)) { + return false; } - at->pos++; - while (at->buf[at->pos] != '\0' && at->buf[at->pos] != '"') { - if (i == len) { - return -ENODATA; + if (str_data->start == NULL) { + if (*c != '"') { + return false; } - name[i++] = at->buf[at->pos++]; + str_data->start = c + 1; + return true; } - if (i == len) { - return -ENODATA; + if (*c == '"') { + str_data->end = c; } - name[i] = '\0'; + return true; +} + +int at_list_get_string(struct at_client *at, char *name, uint8_t len) +{ + struct get_string_data data; + size_t str_len; + + skip_space(at); + + data.start = NULL; + data.end = NULL; + + pull_chars(&at->rsp_buf, at_get_string_cb, &data); - if (at->buf[at->pos] != '"') { + if (data.start >= data.end) { return -ENODATA; } - at->pos++; + + str_len = data.end - data.start; + if (str_len > (len - 1)) { + return -ENOMEM; + } + + memcpy(name, data.start, str_len); + name[str_len] = '\0'; skip_space(at); next_list(at); @@ -514,28 +679,40 @@ int at_list_get_string(struct at_client *at, char *name, uint8_t len) return 0; } +struct get_range_connector_data { + bool found; +}; + +static bool at_get_range_connector_cb(uint8_t *c, void *data) +{ + struct get_range_connector_data *connector_data = data; + + if (connector_data->found) { + return false; + } + + connector_data->found = *c == '-'; + + return connector_data->found; +} + int at_list_get_range(struct at_client *at, uint32_t *min, uint32_t *max) { + struct get_range_connector_data data; uint32_t low, high; - int ret; + int err; - ret = at_get_number(at, &low); - if (ret < 0) { - return ret; + err = at_get_number(at, &low); + if (err < 0) { + return err; } - if (at->buf[at->pos] == '-') { - at->pos++; - goto out; - } + data.found = false; + pull_chars(&at->rsp_buf, at_get_range_connector_cb, &data); - if (isdigit((unsigned char)at->buf[at->pos]) == 0) { - return -ENODATA; - } -out: - ret = at_get_number(at, &high); - if (ret < 0) { - return ret; + err = at_get_number(at, &high); + if (err < 0) { + return err; } *min = low; @@ -560,56 +737,68 @@ void at_register(struct at_client *at, at_resp_cb_t resp, at_finish_cb_t finish) char *at_get_string(struct at_client *at) { - uint8_t pos = at->pos; - char *string; + struct get_string_data data; skip_space(at); - if (at->buf[at->pos] != '"') { - at->pos = pos; - return NULL; - } - at->pos++; - string = &at->buf[at->pos]; + data.start = NULL; + data.end = NULL; - while (at->buf[at->pos] != '\0' && at->buf[at->pos] != '"') { - at->pos++; - } + pull_chars(&at->rsp_buf, at_get_string_cb, &data); - if (at->buf[at->pos] != '"') { - at->pos = pos; + if (data.start >= data.end) { return NULL; } - at->buf[at->pos] = '\0'; - at->pos++; + data.end[0] = '\0'; skip_space(at); next_list(at); - return string; + return data.start; +} + +struct get_raw_string_data { + uint8_t *start; + uint8_t *end; +}; + +static bool at_get_raw_string_cb(uint8_t *c, void *data) +{ + struct get_raw_string_data *str_data = data; + + if ((*c == ',') || (*c == ')')) { + return false; + } + + if (str_data->start == NULL) { + str_data->start = c; + } + str_data->end = c; + return true; } char *at_get_raw_string(struct at_client *at, size_t *string_len) { - char *string; + struct get_raw_string_data data; skip_space(at); - string = &at->buf[at->pos]; + data.start = NULL; + data.end = NULL; - while (at->buf[at->pos] != '\0' && - at->buf[at->pos] != ',' && - at->buf[at->pos] != ')') { - at->pos++; + pull_chars(&at->rsp_buf, at_get_raw_string_cb, &data); + + if (data.start > data.end) { + return NULL; } - if (string_len) { - *string_len = &at->buf[at->pos] - string; + if (string_len != NULL) { + *string_len = data.end - data.start + 1; } skip_space(at); next_list(at); - return string; + return data.start; } diff --git a/subsys/bluetooth/host/classic/at.h b/subsys/bluetooth/host/classic/at.h index fc6ab68ad2fb..8c3cf293fbc8 100644 --- a/subsys/bluetooth/host/classic/at.h +++ b/subsys/bluetooth/host/classic/at.h @@ -89,9 +89,7 @@ typedef int (*handle_cmd_input_t)(struct at_client *at, struct net_buf *buf, enum at_cmd_type type); struct at_client { - char *buf; - uint8_t pos; - uint8_t buf_max_len; + struct net_buf_simple rsp_buf; uint8_t state; uint8_t cmd_state; at_resp_cb_t resp; @@ -115,6 +113,6 @@ int at_list_get_range(struct at_client *at, uint32_t *min, uint32_t *max); int at_list_get_string(struct at_client *at, char *name, uint8_t len); int at_close_list(struct at_client *at); int at_open_list(struct at_client *at); -int at_has_next_list(struct at_client *at); +bool at_has_next_list(struct at_client *at); char *at_get_string(struct at_client *at); char *at_get_raw_string(struct at_client *at, size_t *string_len); diff --git a/subsys/bluetooth/host/classic/hfp_hf.c b/subsys/bluetooth/host/classic/hfp_hf.c index 0caebcb34ca9..1c1b63c8edab 100644 --- a/subsys/bluetooth/host/classic/hfp_hf.c +++ b/subsys/bluetooth/host/classic/hfp_hf.c @@ -1913,11 +1913,11 @@ static const struct unsolicited { static const struct unsolicited *hfp_hf_unsol_lookup(struct at_client *hf_at) { - int i; + ARRAY_FOR_EACH(handlers, i) { + size_t len = strlen(handlers[i].cmd); - for (i = 0; i < ARRAY_SIZE(handlers); i++) { - if (!strncmp(hf_at->buf, handlers[i].cmd, - strlen(handlers[i].cmd))) { + if ((hf_at->rsp_buf.len >= len) && + (strncmp(hf_at->rsp_buf.data, handlers[i].cmd, len) == 0)) { return &handlers[i]; } } @@ -4419,8 +4419,6 @@ static struct bt_hfp_hf *hfp_hf_create(struct bt_conn *conn) } hf->acl = conn; - hf->at.buf = hf->hf_buffer; - hf->at.buf_max_len = HF_MAX_BUF_LEN; hf->rfcomm_dlc.ops = &ops; hf->rfcomm_dlc.mtu = BT_HFP_MAX_MTU; From ba2bd21156bda1c5ef019813488c545fbf568c66 Mon Sep 17 00:00:00 2001 From: Lyle Zhu Date: Thu, 27 Nov 2025 17:35:21 +0800 Subject: [PATCH 0563/3659] tests: Bluetooth: Update at test suites Remove the dedicated buffer from the test case. Signed-off-by: Lyle Zhu --- tests/bluetooth/at/src/main.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tests/bluetooth/at/src/main.c b/tests/bluetooth/at/src/main.c index 615550175893..b64ec792cef1 100644 --- a/tests/bluetooth/at/src/main.c +++ b/tests/bluetooth/at/src/main.c @@ -15,7 +15,6 @@ #include static struct at_client at; -static char buffer[140]; NET_BUF_POOL_DEFINE(at_pool, 1, 140, 0, NULL); @@ -50,9 +49,6 @@ ZTEST(at_tests, test_at) struct net_buf *buf; int len; - at.buf_max_len = 140U; - at.buf = buffer; - buf = net_buf_alloc(&at_pool, K_FOREVER); zassert_not_null(buf, "Failed to get buffer"); From 77225cb32e30442a8b11206d21a155e2525d58f1 Mon Sep 17 00:00:00 2001 From: Jason Yu Date: Mon, 1 Dec 2025 10:50:25 +0800 Subject: [PATCH 0564/3659] soc: nxp: mcxw2xx: Improve OS tick timer selection When os_timer is enabled in dts, then os_timer will be used as OS tick timer. To make systick as the default OS tick timer, currently os_timer is not enabled in dts. When users want to use os_timer as OS tick timer, they need to override the dts. Improve the method, enable the os_timer is dts, but not enable in Kconfig by default. If need to use os_timer as OS tick, just pass CONFIG_MCUX_OS_TIMER=y Signed-off-by: Jason Yu --- boards/nxp/frdm_mcxw23/frdm_mcxw23_common.dtsi | 9 ++++----- boards/nxp/mcxw23_evk/mcxw23_evk_common.dtsi | 9 ++++----- soc/nxp/mcx/mcxw/mcxw2xx/Kconfig.defconfig | 6 ++++++ 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/boards/nxp/frdm_mcxw23/frdm_mcxw23_common.dtsi b/boards/nxp/frdm_mcxw23/frdm_mcxw23_common.dtsi index 205594e59d76..c40b2b4795dc 100644 --- a/boards/nxp/frdm_mcxw23/frdm_mcxw23_common.dtsi +++ b/boards/nxp/frdm_mcxw23/frdm_mcxw23_common.dtsi @@ -176,15 +176,14 @@ pinctrl-names = "default"; }; -/* - * MCXW23 FRDM board uses SYSTICK timer as the kernel timer. - * In case we need to switch to OS timer, then - * replace &systick with &os_timer - */ &systick { status = "okay"; }; +&os_timer { + status = "okay"; +}; + &wwdt0 { status = "okay"; }; diff --git a/boards/nxp/mcxw23_evk/mcxw23_evk_common.dtsi b/boards/nxp/mcxw23_evk/mcxw23_evk_common.dtsi index c21e8e277696..75e8ed58a176 100644 --- a/boards/nxp/mcxw23_evk/mcxw23_evk_common.dtsi +++ b/boards/nxp/mcxw23_evk/mcxw23_evk_common.dtsi @@ -156,15 +156,14 @@ pinctrl-names = "default"; }; -/* - * MCXW23 EVK board uses SYSTICK timer as the kernel timer. - * In case we need to switch to OS timer, then - * replace &systick with &os_timer - */ &systick { status = "okay"; }; +&os_timer { + status = "okay"; +}; + &wwdt0 { status = "okay"; }; diff --git a/soc/nxp/mcx/mcxw/mcxw2xx/Kconfig.defconfig b/soc/nxp/mcx/mcxw/mcxw2xx/Kconfig.defconfig index 1893b6d2d986..992335c7044d 100644 --- a/soc/nxp/mcx/mcxw/mcxw2xx/Kconfig.defconfig +++ b/soc/nxp/mcx/mcxw/mcxw2xx/Kconfig.defconfig @@ -4,6 +4,12 @@ if SOC_SERIES_MCXW2XX +# MCXW23 uses SYSTICK timer as the kernel timer by default. +# In case we need to switch to OS timer, then +# define CONFIG_MCUX_OS_TIMER=y +configdefault MCUX_OS_TIMER + default n + config CORTEX_M_SYSTICK default n if MCUX_OS_TIMER From 6b46f60580e0bfa0fad688022df8f06a47874ab7 Mon Sep 17 00:00:00 2001 From: Wu Yingxiang Date: Tue, 2 Dec 2025 09:52:32 +0800 Subject: [PATCH 0565/3659] boards: others: add esp32c3_lckfb board support Add board support for LCKFB ESP32-C3 Development Board. This board is based on ESP32-C3 with 8MB SPI flash and includes: - Wi-Fi and Bluetooth Low Energy support - Complete pin configuration for UART, I2C, SPI2, I2S - OpenOCD debugging support - Board documentation with WebP image (optimized size) Signed-off-by: Wu Yingxiang --- boards/others/esp32c3_lckfb/Kconfig | 6 + .../esp32c3_lckfb/Kconfig.esp32c3_lckfb | 7 ++ boards/others/esp32c3_lckfb/Kconfig.sysbuild | 10 ++ boards/others/esp32c3_lckfb/board.cmake | 9 ++ boards/others/esp32c3_lckfb/board.yml | 6 + .../esp32c3_lckfb/doc/img/esp32c3_lckfb.webp | Bin 0 -> 47766 bytes boards/others/esp32c3_lckfb/doc/index.rst | 52 +++++++++ .../esp32c3_lckfb/esp32c3_lckfb-pinctrl.dtsi | 53 +++++++++ boards/others/esp32c3_lckfb/esp32c3_lckfb.dts | 109 ++++++++++++++++++ .../others/esp32c3_lckfb/esp32c3_lckfb.yaml | 21 ++++ .../esp32c3_lckfb/esp32c3_lckfb_defconfig | 6 + .../others/esp32c3_lckfb/support/openocd.cfg | 11 ++ 12 files changed, 290 insertions(+) create mode 100644 boards/others/esp32c3_lckfb/Kconfig create mode 100644 boards/others/esp32c3_lckfb/Kconfig.esp32c3_lckfb create mode 100644 boards/others/esp32c3_lckfb/Kconfig.sysbuild create mode 100644 boards/others/esp32c3_lckfb/board.cmake create mode 100644 boards/others/esp32c3_lckfb/board.yml create mode 100644 boards/others/esp32c3_lckfb/doc/img/esp32c3_lckfb.webp create mode 100644 boards/others/esp32c3_lckfb/doc/index.rst create mode 100644 boards/others/esp32c3_lckfb/esp32c3_lckfb-pinctrl.dtsi create mode 100644 boards/others/esp32c3_lckfb/esp32c3_lckfb.dts create mode 100644 boards/others/esp32c3_lckfb/esp32c3_lckfb.yaml create mode 100644 boards/others/esp32c3_lckfb/esp32c3_lckfb_defconfig create mode 100644 boards/others/esp32c3_lckfb/support/openocd.cfg diff --git a/boards/others/esp32c3_lckfb/Kconfig b/boards/others/esp32c3_lckfb/Kconfig new file mode 100644 index 000000000000..6a4f947820a6 --- /dev/null +++ b/boards/others/esp32c3_lckfb/Kconfig @@ -0,0 +1,6 @@ +# Copyright (c) 2025 LCKFB +# SPDX-License-Identifier: Apache-2.0 + +config HEAP_MEM_POOL_ADD_SIZE_BOARD + int + default 4096 diff --git a/boards/others/esp32c3_lckfb/Kconfig.esp32c3_lckfb b/boards/others/esp32c3_lckfb/Kconfig.esp32c3_lckfb new file mode 100644 index 000000000000..0e674285c1c3 --- /dev/null +++ b/boards/others/esp32c3_lckfb/Kconfig.esp32c3_lckfb @@ -0,0 +1,7 @@ +# ESP32C3 LCKFB board configuration +# +# Copyright (c) 2025 LCKFB +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_ESP32C3_LCKFB + select SOC_ESP32C3 diff --git a/boards/others/esp32c3_lckfb/Kconfig.sysbuild b/boards/others/esp32c3_lckfb/Kconfig.sysbuild new file mode 100644 index 000000000000..72e00d39b797 --- /dev/null +++ b/boards/others/esp32c3_lckfb/Kconfig.sysbuild @@ -0,0 +1,10 @@ +# Copyright (c) 2025 LCKFB +# SPDX-License-Identifier: Apache-2.0 + +choice BOOTLOADER + default BOOTLOADER_MCUBOOT +endchoice + +choice BOOT_SIGNATURE_TYPE + default BOOT_SIGNATURE_TYPE_NONE +endchoice diff --git a/boards/others/esp32c3_lckfb/board.cmake b/boards/others/esp32c3_lckfb/board.cmake new file mode 100644 index 000000000000..2f04d1fe8861 --- /dev/null +++ b/boards/others/esp32c3_lckfb/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/others/esp32c3_lckfb/board.yml b/boards/others/esp32c3_lckfb/board.yml new file mode 100644 index 000000000000..7f6e8471fee5 --- /dev/null +++ b/boards/others/esp32c3_lckfb/board.yml @@ -0,0 +1,6 @@ +board: + name: esp32c3_lckfb + full_name: ESP32-C3 Development Board (LCKFB) + vendor: others + socs: + - name: esp32c3 diff --git a/boards/others/esp32c3_lckfb/doc/img/esp32c3_lckfb.webp b/boards/others/esp32c3_lckfb/doc/img/esp32c3_lckfb.webp new file mode 100644 index 0000000000000000000000000000000000000000..4bee856646a32b2c594be55f507489cc14488076 GIT binary patch literal 47766 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 LA$H+Pm;e9(dP*o& literal 0 HcmV?d00001 diff --git a/boards/others/esp32c3_lckfb/doc/index.rst b/boards/others/esp32c3_lckfb/doc/index.rst new file mode 100644 index 000000000000..051764d87d40 --- /dev/null +++ b/boards/others/esp32c3_lckfb/doc/index.rst @@ -0,0 +1,52 @@ +.. zephyr:board:: esp32c3_lckfb + +Overview +******** + +The LCKFB ESP32-C3 is a feature-rich development board built around the ESP32-C3 SoC with 8 MB of onboard SPI flash. It offers full Wi-Fi and Bluetooth Low Energy connectivity, complemented by a comprehensive set of sensors, audio capabilities, and display interfaces. + +The board is designed for IoT applications requiring motion sensing, environmental monitoring, +audio processing, and graphical display capabilities. + +For more information, check `LCKFB ESP32-C3 Development Board`_. + +Hardware +******** + +.. include:: ../../../espressif/common/soc-esp32c3-features.rst + :start-after: espressif-soc-esp32c3-features + +Supported Features +================== + +.. zephyr:board-supported-hw:: + +System Requirements +******************* + +.. include:: ../../../espressif/common/system-requirements.rst + :start-after: espressif-system-requirements + +Programming and Debugging +************************* + +.. zephyr:board-supported-runners:: + +.. include:: ../../../espressif/common/building-flashing.rst + :start-after: espressif-building-flashing + +.. include:: ../../../espressif/common/board-variants.rst + :start-after: espressif-board-variants + +Debugging +========= + +.. include:: ../../../espressif/common/openocd-debugging.rst + :start-after: espressif-openocd-debugging + +References +********** + +.. target-notes:: + +.. _`LCKFB ESP32-C3 Development Board`: https://wiki.lckfb.com/zh-hans/szpi-esp32c3/ diff --git a/boards/others/esp32c3_lckfb/esp32c3_lckfb-pinctrl.dtsi b/boards/others/esp32c3_lckfb/esp32c3_lckfb-pinctrl.dtsi new file mode 100644 index 000000000000..85a5a184a530 --- /dev/null +++ b/boards/others/esp32c3_lckfb/esp32c3_lckfb-pinctrl.dtsi @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2025 LCKFB + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +&pinctrl { + uart0_default: uart0_default { + group1 { + pinmux = ; + output-high; + }; + + group2 { + pinmux = ; + bias-pull-up; + }; + }; + + spim2_default: spim2_default { + group1 { + pinmux = , + ; + }; + + group2 { + pinmux = ; + output-low; + }; + }; + + i2c0_default: i2c0_default { + group1 { + pinmux = , + ; + bias-pull-up; + drive-open-drain; + output-high; + }; + }; + + i2s_default: i2s_default { + group1 { + pinmux = , + , + ; + }; + }; +}; diff --git a/boards/others/esp32c3_lckfb/esp32c3_lckfb.dts b/boards/others/esp32c3_lckfb/esp32c3_lckfb.dts new file mode 100644 index 000000000000..8a050dc62123 --- /dev/null +++ b/boards/others/esp32c3_lckfb/esp32c3_lckfb.dts @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2025 LCKFB + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include "esp32c3_lckfb-pinctrl.dtsi" +#include +#include + +/ { + model = "LCKFB ESP32-C3 Development Board"; + compatible = "espressif,esp32c3"; + + chosen { + zephyr,sram = &sram1; + zephyr,console = &uart0; + zephyr,shell-uart = &uart0; + zephyr,flash = &flash0; + zephyr,code-partition = &slot0_partition; + zephyr,bt-hci = &esp32_bt_hci; + }; + + aliases { + sw0 = &user_button1; + i2c-0 = &i2c0; + watchdog0 = &wdt0; + }; + + gpio_keys { + compatible = "gpio-keys"; + + user_button1: button_1 { + label = "User Button"; + gpios = <&gpio0 9 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + zephyr,code = ; + }; + }; +}; + +&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"; +}; + +&i2s { + pinctrl-0 = <&i2s_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 = "disabled"; +}; + +&timer1 { + status = "disabled"; +}; + +&esp32_bt_hci { + status = "okay"; +}; + +&wifi { + status = "okay"; +}; + +/* Override flash size to 8MB + * esp32c3_common.dtsi does not define a default flash size, + * and this board uses 8MB flash, so we need to specify it explicitly. + */ +&flash0 { + reg = <0x0 DT_SIZE_M(8)>; +}; diff --git a/boards/others/esp32c3_lckfb/esp32c3_lckfb.yaml b/boards/others/esp32c3_lckfb/esp32c3_lckfb.yaml new file mode 100644 index 000000000000..f3c6245be69c --- /dev/null +++ b/boards/others/esp32c3_lckfb/esp32c3_lckfb.yaml @@ -0,0 +1,21 @@ +identifier: esp32c3_lckfb +name: ESP32-C3 (LCKFB) +type: mcu +arch: riscv +toolchain: + - zephyr +supported: + - adc + - gpio + - i2c + - i2s + - watchdog + - uart + - dma + - pwm + - spi + - counter + - entropy + - crypto + - retained_mem +vendor: others diff --git a/boards/others/esp32c3_lckfb/esp32c3_lckfb_defconfig b/boards/others/esp32c3_lckfb/esp32c3_lckfb_defconfig new file mode 100644 index 000000000000..187793c76e8c --- /dev/null +++ b/boards/others/esp32c3_lckfb/esp32c3_lckfb_defconfig @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_UART_CONSOLE=y +CONFIG_GPIO=y diff --git a/boards/others/esp32c3_lckfb/support/openocd.cfg b/boards/others/esp32c3_lckfb/support/openocd.cfg new file mode 100644 index 000000000000..92a792fecb8e --- /dev/null +++ b/boards/others/esp32c3_lckfb/support/openocd.cfg @@ -0,0 +1,11 @@ +set ESP_RTOS none + +# ESP32C3 has built-in JTAG interface over USB port in pins GPIO18/GPIO19 (D-/D+). +# Uncomment the line below to enable USB debugging. +# source [find interface/esp_usb_jtag.cfg] + +# Otherwise, use external JTAG programmer as ESP-Prog +source [find interface/ftdi/esp32_devkitj_v1.cfg] + +source [find target/esp32c3.cfg] +adapter speed 5000 From 12a5bb2911dc9ae3bb3e8b43a83a46296495d283 Mon Sep 17 00:00:00 2001 From: Kai Vehmanen Date: Thu, 20 Nov 2025 18:10:29 +0200 Subject: [PATCH 0566/3659] soc: intel_adsp: tools: cavstool.py: add I2S offload support Program I2S link for DSP offload, allowing to run DSP tests using the I2S/SSP interface. On ACE1.5 and older, no additional programming is required, I2S link is available by default. Signed-off-by: Kai Vehmanen --- soc/intel/intel_adsp/tools/cavstool.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/soc/intel/intel_adsp/tools/cavstool.py b/soc/intel/intel_adsp/tools/cavstool.py index 9042e9c2891e..611d77489a33 100755 --- a/soc/intel/intel_adsp/tools/cavstool.py +++ b/soc/intel/intel_adsp/tools/cavstool.py @@ -49,6 +49,9 @@ SPA = 16 CPA = 24 +# LCTL bits +OFLEN = 4 + class HDAStream: # creates an hda stream with at 2 buffers of buf_len def __init__(self, stream_id: int): @@ -257,13 +260,15 @@ def map_regs(log_only): hda.SPBFCTL = 0x0704 hda.PPCTL = 0x0804 + if ace20 or ace30: + hda.HDAML_I2S_LCTL = 0x0C40 + 0x40 * 3 + 4 + # Find the ID of the first output stream hda_ostream_id = (hda.GCAP >> 8) & 0x0f # number of input streams log.info(f"Selected output stream {hda_ostream_id} (GCAP = 0x{hda.GCAP:x})") hda.SD_SPIB = 0x0708 + (8 * hda_ostream_id) hda.freeze() - # Standard HD Audio Stream Descriptor sd = Regs(hdamem + 0x0080 + (hda_ostream_id * 0x20)) sd.CTL = 0x00 @@ -395,8 +400,7 @@ def runx(cmd): return subprocess.check_output(cmd, shell=True).decode().rstrip() def mask(bit): - if cavs25: - return 0b1 << bit + return 0b1 << bit def load_firmware(fw_file): try: @@ -539,6 +543,12 @@ def load_firmware_ace(fw_file): log.info("Waiting for DSP subsystem power on") time.sleep(0.1) + if ace20 or ace30: + log.info(f"Enabling offload for I2S link") + # needed to allow DSP to access SSP DAI + hda.HDAML_I2S_LCTL |= mask(OFLEN) + log.debug(f"HDAML.I2S_LCTL 0x{hda.HDAML_I2S_LCTL:x}") + log.info("Turning on Domain0") dsp.HFPWRCTL |= 0x1 # set SPA bit time.sleep(0.002) # needed as the CPA bit may be unstable From b13c7a2fe029c962f8223255058c13cdbaf49f90 Mon Sep 17 00:00:00 2001 From: Ederson de Souza Date: Mon, 15 Dec 2025 14:33:51 -0800 Subject: [PATCH 0567/3659] MAINTAINERS: Add edersondisouza as MCTP collaborator Add edersondisouza as a collaborator to MCTP. Signed-off-by: Ederson de Souza --- MAINTAINERS.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index 9faf170ff2de..ba4406d966f1 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -5970,6 +5970,7 @@ West: collaborators: - nashif - dkalowsk + - edersondisouza files: [] labels: - "area: MCTP" From 30307e9fd1614f53881a3ee8de60d8836c884593 Mon Sep 17 00:00:00 2001 From: John Batch Date: Mon, 15 Dec 2025 16:08:49 -0800 Subject: [PATCH 0568/3659] tests: drivers: dma: Adding DMA test overlays for Infineon PSC3 board Adding test overlays for Infineon kit_psc3m5_evk board. Added tests: * tests/drivers/dma/chan_blen_transfer * tests/drivers/dma/loop_transfer Signed-off-by: John Batch --- .../chan_blen_transfer/boards/kit_psc3m5_evk.overlay | 10 ++++++++++ .../dma/loop_transfer/boards/kit_psc3m5_evk.conf | 6 ++++++ .../dma/loop_transfer/boards/kit_psc3m5_evk.overlay | 10 ++++++++++ 3 files changed, 26 insertions(+) create mode 100644 tests/drivers/dma/chan_blen_transfer/boards/kit_psc3m5_evk.overlay create mode 100644 tests/drivers/dma/loop_transfer/boards/kit_psc3m5_evk.conf create mode 100644 tests/drivers/dma/loop_transfer/boards/kit_psc3m5_evk.overlay diff --git a/tests/drivers/dma/chan_blen_transfer/boards/kit_psc3m5_evk.overlay b/tests/drivers/dma/chan_blen_transfer/boards/kit_psc3m5_evk.overlay new file mode 100644 index 000000000000..70b972a07132 --- /dev/null +++ b/tests/drivers/dma/chan_blen_transfer/boards/kit_psc3m5_evk.overlay @@ -0,0 +1,10 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +tst_dma0: &dma0 { + status = "okay"; +}; diff --git a/tests/drivers/dma/loop_transfer/boards/kit_psc3m5_evk.conf b/tests/drivers/dma/loop_transfer/boards/kit_psc3m5_evk.conf new file mode 100644 index 000000000000..c6ce885f98d4 --- /dev/null +++ b/tests/drivers/dma/loop_transfer/boards/kit_psc3m5_evk.conf @@ -0,0 +1,6 @@ +# Copyright (c) 2025 Infineon Technologies AG, +# or an affiliate of Infineon Technologies AG. +# +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_DMA_LOOP_TRANSFER_SIZE=256 diff --git a/tests/drivers/dma/loop_transfer/boards/kit_psc3m5_evk.overlay b/tests/drivers/dma/loop_transfer/boards/kit_psc3m5_evk.overlay new file mode 100644 index 000000000000..70b972a07132 --- /dev/null +++ b/tests/drivers/dma/loop_transfer/boards/kit_psc3m5_evk.overlay @@ -0,0 +1,10 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +tst_dma0: &dma0 { + status = "okay"; +}; From 5ca16a6696f0ec3c0a72a5a0ebba7dc859023875 Mon Sep 17 00:00:00 2001 From: John Batch Date: Mon, 15 Dec 2025 16:12:20 -0800 Subject: [PATCH 0569/3659] boards: infineon: kit_psc3m5_evk: Adding dma to supported devices Adds DMA to the supported devices list for the Infineon kit_psc3m5_evk board. Signed-off-by: John Batch --- boards/infineon/kit_psc3m5_evk/kit_psc3m5_evk.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/boards/infineon/kit_psc3m5_evk/kit_psc3m5_evk.yaml b/boards/infineon/kit_psc3m5_evk/kit_psc3m5_evk.yaml index 78acdfe1d22d..c4019cb91b8c 100644 --- a/boards/infineon/kit_psc3m5_evk/kit_psc3m5_evk.yaml +++ b/boards/infineon/kit_psc3m5_evk/kit_psc3m5_evk.yaml @@ -16,4 +16,5 @@ supported: - gpio - spi - uart + - dma vendor: infineon From 007f4427f37321acbbe6cc658232466661c7cc92 Mon Sep 17 00:00:00 2001 From: Sylvio Alves Date: Tue, 16 Dec 2025 00:20:50 -0300 Subject: [PATCH 0570/3659] drivers: serial: esp32: add UHCI SLIP encoding control Add devicetree properties to control UHCI SLIP encoding/decoding when using UART with DMA (async API). Both properties default to disabled to prevent unintended data corruption. Signed-off-by: Sylvio Alves --- drivers/serial/uart_esp32.c | 11 ++++++++++- dts/bindings/serial/espressif,esp32-uart.yaml | 16 ++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/drivers/serial/uart_esp32.c b/drivers/serial/uart_esp32.c index ffff07096917..c667a8826da6 100644 --- a/drivers/serial/uart_esp32.c +++ b/drivers/serial/uart_esp32.c @@ -81,6 +81,8 @@ struct uart_esp32_config { const struct device *dma_dev; uint8_t tx_dma_channel; uint8_t rx_dma_channel; + bool uhci_slip_tx; + bool uhci_slip_rx; #endif }; @@ -1047,6 +1049,11 @@ static int uart_esp32_init(const struct device *dev) clock_control_on(config->clock_dev, (clock_control_subsys_t)ESP32_UHCI0_MODULE); uhci_ll_init(data->uhci_dev); uhci_ll_set_eof_mode(data->uhci_dev, UHCI_RX_IDLE_EOF | UHCI_RX_LEN_EOF); + + /* Configure SLIP encoding/decoding */ + data->uhci_dev->escape_conf.tx_c0_esc_en = config->uhci_slip_tx ? 1 : 0; + data->uhci_dev->escape_conf.rx_c0_esc_en = config->uhci_slip_rx ? 1 : 0; + uhci_ll_attach_uart_port(data->uhci_dev, uart_hal_get_port_num(&data->hal)); data->uart_dev = dev; @@ -1095,7 +1102,9 @@ static DEVICE_API(uart, uart_esp32_api) = { #define ESP_UART_DMA_INIT(n) \ .dma_dev = ESP32_DT_INST_DMA_CTLR(n, tx), \ .tx_dma_channel = ESP32_DT_INST_DMA_CELL(n, tx, channel), \ - .rx_dma_channel = ESP32_DT_INST_DMA_CELL(n, rx, channel) + .rx_dma_channel = ESP32_DT_INST_DMA_CELL(n, rx, channel), \ + .uhci_slip_tx = DT_INST_PROP_OR(n, uhci_slip_tx, false), \ + .uhci_slip_rx = DT_INST_PROP_OR(n, uhci_slip_rx, false) #define ESP_UART_UHCI_INIT(n) \ .uhci_dev = COND_CODE_1(DT_INST_NODE_HAS_PROP(n, dmas), (&UHCI0), (NULL)) diff --git a/dts/bindings/serial/espressif,esp32-uart.yaml b/dts/bindings/serial/espressif,esp32-uart.yaml index f1f6abdfa379..1ef807794c41 100644 --- a/dts/bindings/serial/espressif,esp32-uart.yaml +++ b/dts/bindings/serial/espressif,esp32-uart.yaml @@ -31,3 +31,19 @@ properties: Overrides hw-flow-control if both are set. Using this mode, the pin assigned to DTR is asserted during transmission. + + uhci-slip-tx: + type: boolean + description: | + Enable SLIP encoding on TX when using UART with DMA (async API). + When enabled, the UHCI hardware automatically encodes transmitted data + using SLIP framing (0xC0 -> 0xDB 0xDC, 0xDB -> 0xDB 0xDD). + Disabled by default to prevent unintended data corruption. + + uhci-slip-rx: + type: boolean + description: | + Enable SLIP decoding on RX when using UART with DMA (async API). + When enabled, the UHCI hardware automatically decodes received data + using SLIP framing (0xDB 0xDC -> 0xC0, 0xDB 0xDD -> 0xDB). + Disabled by default to prevent unintended data corruption. From 9c710107dac6341596e9e8236a569ea082c09a09 Mon Sep 17 00:00:00 2001 From: Lyle Zhu Date: Tue, 16 Dec 2025 10:58:00 +0800 Subject: [PATCH 0571/3659] bluetooth: hfp_ag: Add Kconfig option for in-band ringtone Add a new Kconfig option CONFIG_BT_HFP_AG_INBAND_RINGTONE to allow enabling/disabling the in-band ringtone capability in HFP AG profile. The in-band ringtone feature is now conditionally compiled based on this configuration option. When disabled, the feature flags are set to 0 and the bt_hfp_ag_inband_ringtone() API returns -ENOTSUP. Signed-off-by: Lyle Zhu --- subsys/bluetooth/host/classic/Kconfig | 6 ++++++ subsys/bluetooth/host/classic/hfp_ag.c | 7 ++++++- subsys/bluetooth/host/classic/hfp_ag_internal.h | 12 ++++++++++-- 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/subsys/bluetooth/host/classic/Kconfig b/subsys/bluetooth/host/classic/Kconfig index 71fc2ae9daa8..bf8222da6444 100644 --- a/subsys/bluetooth/host/classic/Kconfig +++ b/subsys/bluetooth/host/classic/Kconfig @@ -434,6 +434,12 @@ config BT_HFP_AG_GET_ONGOING_CALL_TIMEOUT help This option sets the timeout after the get ongoing calls callback notified +config BT_HFP_AG_INBAND_RINGTONE + bool "In-band ring tone capability" + default y + help + This option enables In-band ring tone capability + endif # BT_HFP_AG config BT_AVDTP diff --git a/subsys/bluetooth/host/classic/hfp_ag.c b/subsys/bluetooth/host/classic/hfp_ag.c index 18a906b1c0c8..5d39deb9e736 100644 --- a/subsys/bluetooth/host/classic/hfp_ag.c +++ b/subsys/bluetooth/host/classic/hfp_ag.c @@ -1752,7 +1752,7 @@ static void bt_hfp_ag_set_in_band_ring(struct bt_hfp_ag *ag) { bool is_inband_ringtone; - is_inband_ringtone = AG_SUPT_FEAT(ag, BT_HFP_AG_FEATURE_INBAND_RINGTONE) ? true : false; + is_inband_ringtone = AG_SUPT_FEAT(ag, BT_HFP_AG_FEATURE_INBAND_RINGTONE_ENABLE); if (is_inband_ringtone && !atomic_test_bit(ag->flags, BT_HFP_AG_INBAND_RING)) { int err = hfp_ag_send_data(ag, NULL, NULL, "\r\n+BSIR:1\r\n"); @@ -5263,6 +5263,11 @@ int bt_hfp_ag_inband_ringtone(struct bt_hfp_ag *ag, bool inband) LOG_DBG(""); + if (!IS_ENABLED(CONFIG_BT_HFP_AG_INBAND_RINGTONE)) { + LOG_ERR("In-band ring tone is unsupported!"); + return -ENOTSUP; + } + if (ag == NULL) { return -EINVAL; } diff --git a/subsys/bluetooth/host/classic/hfp_ag_internal.h b/subsys/bluetooth/host/classic/hfp_ag_internal.h index fdc8d3006508..4e322f7fae96 100644 --- a/subsys/bluetooth/host/classic/hfp_ag_internal.h +++ b/subsys/bluetooth/host/classic/hfp_ag_internal.h @@ -107,10 +107,18 @@ #define BT_HFP_AG_SDP_FEATURE_SUPER_WBS_ENABLE 0 #endif /* CONFIG_BT_HFP_AG_CODEC_LC3_SWB */ +#if defined(CONFIG_BT_HFP_AG_INBAND_RINGTONE) +#define BT_HFP_AG_FEATURE_INBAND_RINGTONE_ENABLE BT_HFP_AG_FEATURE_INBAND_RINGTONE +#define BT_HFP_AG_SDP_FEATURE_INBAND_RINGTONE_ENABLE BT_HFP_AG_SDP_FEATURE_INBAND_RINGTONE +#else +#define BT_HFP_AG_FEATURE_INBAND_RINGTONE_ENABLE 0 +#define BT_HFP_AG_SDP_FEATURE_INBAND_RINGTONE_ENABLE 0 +#endif /* CONFIG_BT_HFP_AG_INBAND_RINGTONE */ + /* HFP AG Supported features */ #define BT_HFP_AG_SUPPORTED_FEATURES (\ BT_HFP_AG_FEATURE_3WAY_CALL_ENABLE | \ - BT_HFP_AG_FEATURE_INBAND_RINGTONE | \ + BT_HFP_AG_FEATURE_INBAND_RINGTONE_ENABLE | \ BT_HFP_AG_FEATURE_EXT_ERR_ENABLE | \ BT_HFP_AG_FEATURE_CODEC_NEG_ENABLE | \ BT_HFP_AG_FEATURE_ECNR_ENABLE | \ @@ -126,7 +134,7 @@ /* HFP AG Supported features in SDP */ #define BT_HFP_AG_SDP_SUPPORTED_FEATURES (\ BT_HFP_AG_SDP_FEATURE_3WAY_CALL_ENABLE | \ - BT_HFP_AG_SDP_FEATURE_INBAND_RINGTONE | \ + BT_HFP_AG_SDP_FEATURE_INBAND_RINGTONE_ENABLE | \ BT_HFP_AG_SDP_FEATURE_ECNR_ENABLE | \ BT_HFP_AG_SDP_FEATURE_VOICE_RECG_ENABLE | \ BT_HFP_AG_SDP_FEATURE_ENH_VOICE_RECG_ENABLE | \ From 5d1e443bdf8e27b88a253f7050977b795d289395 Mon Sep 17 00:00:00 2001 From: Sylvio Alves Date: Tue, 16 Dec 2025 01:05:25 -0300 Subject: [PATCH 0572/3659] drivers: spi: esp32: fix CS handling when using GPIO chip select The driver was unconditionally setting hal_dev->cs_pin_id to the target number, which activates hardware CS lines even when GPIO-based chip select (cs-gpios) is used. This caused issues when using hardware CS via pinctrl with reg > 0. Also update the binding documentation to clarify the interaction between cs-gpios and hardware CS via pinctrl. Signed-off-by: Sylvio Alves --- drivers/spi/spi_esp32_spim.c | 16 ++++++++- dts/bindings/spi/espressif,esp32-spi.yaml | 40 ++++++++++++++++++++++- 2 files changed, 54 insertions(+), 2 deletions(-) diff --git a/drivers/spi/spi_esp32_spim.c b/drivers/spi/spi_esp32_spim.c index b96d11a16fae..35fc62f13db4 100644 --- a/drivers/spi/spi_esp32_spim.c +++ b/drivers/spi/spi_esp32_spim.c @@ -427,7 +427,21 @@ static int IRAM_ATTR spi_esp32_configure(const struct device *dev, return -ENOTSUP; } - hal_dev->cs_pin_id = ctx->config->slave; + /* + * CS handling: + * - When using GPIO CS (cs-gpios property), the spi_context manages + * chip select via GPIO. Hardware CS must be disabled by setting + * cs_pin_id outside valid range (0-2). Any value > 2 disables all + * hardware CS lines per documentation. + * - When using hardware CS (directly via pinctrl), the slave + * number maps to the hardware CS pin (CS0, CS1, CS2). + */ + if (spi_cs_is_gpio(spi_cfg)) { + hal_dev->cs_pin_id = -1; + } else { + hal_dev->cs_pin_id = ctx->config->slave; + } + int ret = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT); if (ret) { diff --git a/dts/bindings/spi/espressif,esp32-spi.yaml b/dts/bindings/spi/espressif,esp32-spi.yaml index 5d25838ca6d6..d3970c4216b5 100644 --- a/dts/bindings/spi/espressif,esp32-spi.yaml +++ b/dts/bindings/spi/espressif,esp32-spi.yaml @@ -1,4 +1,42 @@ -description: ESP32 SPI +description: | + ESP32 SPI controller + + Hardware chip select is directly handled via pinctrl. The reg property of + a child SPI device node corresponds to the hardware CS pin number configured + in pinctrl. ESP32 supports CS0-CS2, while ESP32-S2/S3/C2/C3/C6/H2 support + CS0-CS5. + + Alternatively, GPIO-based chip selects can be used via the cs-gpios property. + When cs-gpios is defined, the hardware CS lines are disabled and the driver + uses GPIO pins for chip select control. In this case, the reg property of + child nodes corresponds to the index in the cs-gpios array. + + Example with hardware CS (directly via pinctrl): + + &spi2 { + pinctrl-0 = <&spim2_default>; /* Must include CS signal */ + pinctrl-names = "default"; + + device@0 { + reg = <0>; /* Uses hardware CS0 */ + }; + }; + + Example with GPIO CS: + + &spi2 { + pinctrl-0 = <&spim2_default>; /* CS signal optional */ + pinctrl-names = "default"; + cs-gpios = <&gpio0 5 GPIO_ACTIVE_LOW>, + <&gpio0 6 GPIO_ACTIVE_LOW>; + + device@0 { + reg = <0>; /* Uses first GPIO (gpio0 pin 5) */ + }; + device@1 { + reg = <1>; /* Uses second GPIO (gpio0 pin 6) */ + }; + }; compatible: "espressif,esp32-spi" From f66f58833f0419ea7b591f2c132c9f2ebdb0d6c4 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Wed, 8 Oct 2025 14:32:28 +0200 Subject: [PATCH 0573/3659] samples: Bluetooth: CAP: Acceptor: Various fixes The sample recently started supporting multiple sink ASEs, but only support a single sink stream. Updated the number of sink streams supported. Modified how/when we reset the requested_bis_sync and FLAG_BROADCAST_SYNC_REQUESTED in the broadcast implementation. Removed a call to bt_bap_broadcast_sink_delete that would always fail because it was already deleted. Modified how/when the total_unicast_rx_iso_packet_count and total_unicast_tx_iso_packet_count values were reset, to support a future case of CAP handover. Signed-off-by: Emil Gydesen --- samples/bluetooth/cap_acceptor/Kconfig | 6 ++-- .../bluetooth/cap_acceptor/src/cap_acceptor.h | 4 +-- .../cap_acceptor/src/cap_acceptor_broadcast.c | 33 ++++++++++-------- .../cap_acceptor/src/cap_acceptor_unicast.c | 11 ++++-- samples/bluetooth/cap_acceptor/src/main.c | 34 +++++++++++++------ .../acceptor/src/cap_acceptor_sample_test.c | 11 +++--- 6 files changed, 62 insertions(+), 37 deletions(-) diff --git a/samples/bluetooth/cap_acceptor/Kconfig b/samples/bluetooth/cap_acceptor/Kconfig index 8bf991475740..e1bd4f8eba7e 100644 --- a/samples/bluetooth/cap_acceptor/Kconfig +++ b/samples/bluetooth/cap_acceptor/Kconfig @@ -1,10 +1,10 @@ -# Copyright (c) 2022 Nordic Semiconductor ASA +# Copyright (c) 2022-2025 Nordic Semiconductor ASA # SPDX-License-Identifier: Apache-2.0 mainmenu "Bluetooth: Common Audio Profile Acceptor sample" config SAMPLE_UNICAST - bool "Whether or not to search for CAP acceptors for unicast audio" + bool "Whether or not advertise connectable support for unicast audio" default y select BT_BAP_UNICAST_SERVER select BT_ISO_PERIPHERAL @@ -19,7 +19,7 @@ config SAMPLE_UNICAST Broadcast Assistants. config SAMPLE_BROADCAST - bool "Whether or not to search for CAP acceptors for unicast audio" + bool "Whether or not advertise connectable support for broadcast audio" default y if !SAMPLE_UNICAST select BT_BAP_SCAN_DELEGATOR select BT_OBSERVER diff --git a/samples/bluetooth/cap_acceptor/src/cap_acceptor.h b/samples/bluetooth/cap_acceptor/src/cap_acceptor.h index 42c181f34dd2..4f9ec41fc2a3 100644 --- a/samples/bluetooth/cap_acceptor/src/cap_acceptor.h +++ b/samples/bluetooth/cap_acceptor/src/cap_acceptor.h @@ -18,8 +18,8 @@ struct peer_config { /** Stream for the source endpoint */ struct bt_cap_stream source_stream; - /** Stream for the sink endpoint */ - struct bt_cap_stream sink_stream; + /** Streams for the sink endpoint */ + struct bt_cap_stream sink_streams[CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT]; /** Semaphore to help wait for a release operation if the source stream is not idle */ struct k_sem source_stream_sem; /** Semaphore to help wait for a release operation if the sink stream is not idle */ diff --git a/samples/bluetooth/cap_acceptor/src/cap_acceptor_broadcast.c b/samples/bluetooth/cap_acceptor/src/cap_acceptor_broadcast.c index d8e653c7846e..13e1c645d8e0 100644 --- a/samples/bluetooth/cap_acceptor/src/cap_acceptor_broadcast.c +++ b/samples/bluetooth/cap_acceptor/src/cap_acceptor_broadcast.c @@ -100,7 +100,6 @@ static int check_start_scan(void) static void broadcast_stream_started_cb(struct bt_bap_stream *bap_stream) { LOG_INF("Started bap_stream %p", bap_stream); - total_broadcast_rx_iso_packet_count = 0U; atomic_clear_bit(flags, FLAG_BROADCAST_SYNCING); atomic_set_bit(flags, FLAG_BROADCAST_SYNCED); @@ -256,11 +255,20 @@ static void syncable_cb(struct bt_bap_broadcast_sink *sink, const struct bt_iso_ } } +static void sink_started_cb(struct bt_bap_broadcast_sink *sink) +{ + LOG_INF("Broadcast sink started"); + + /* Clear requested BIS sync */ + broadcast_sink.requested_bis_sync = 0; + atomic_clear_bit(flags, FLAG_BROADCAST_SYNC_REQUESTED); +} + static void sink_stopped_cb(struct bt_bap_broadcast_sink *sink, uint8_t reason) { int err; - LOG_INF("Broadcast sink stopped with reason %u", reason); + LOG_INF("Broadcast sink stopped with reason 0x%02X", reason); err = bt_bap_broadcast_sink_delete(sink); if (err != 0) { @@ -481,7 +489,10 @@ static int bis_sync_req_cb(struct bt_conn *conn, return -ENOMEM; } - if (broadcast_sink.requested_bis_sync == new_bis_sync_req) { + if (atomic_test_bit(flags, FLAG_BROADCAST_SYNC_REQUESTED) && + broadcast_sink.requested_bis_sync == new_bis_sync_req) { + LOG_INF("New request (0x%08x) is the same as last request; ignoring", + new_bis_sync_req); return 0; /* no op */ } @@ -491,6 +502,8 @@ static int bis_sync_req_cb(struct bt_conn *conn, */ int err; + LOG_INF("Already synced. Stopping current sync and attempt resyncing"); + /* The stream stopped callback will be called as part of this, * and we do not need to wait for any events from the * controller. Thus, when this returns, the broadcast sink is stopped @@ -502,13 +515,7 @@ static int bis_sync_req_cb(struct bt_conn *conn, return err; } - err = bt_bap_broadcast_sink_delete(broadcast_sink.bap_broadcast_sink); - if (err != 0) { - LOG_ERR("Failed to delete Broadcast Sink: %d", err); - - return err; - } - broadcast_sink.bap_broadcast_sink = NULL; + /* Broadcast sink will be deleted and set to NULL in `sink_stopped_cb` */ atomic_clear_bit(flags, FLAG_BROADCAST_SYNCED); } @@ -517,8 +524,6 @@ static int bis_sync_req_cb(struct bt_conn *conn, if (broadcast_sink.requested_bis_sync != 0U) { atomic_set_bit(flags, FLAG_BROADCAST_SYNC_REQUESTED); check_sync_broadcast(); - } else { - atomic_clear_bit(flags, FLAG_BROADCAST_SYNC_REQUESTED); } return 0; @@ -568,10 +573,9 @@ static void bap_pa_sync_terminated_cb(struct bt_le_per_adv_sync *sync, if (sync == broadcast_sink.pa_sync) { int err; - LOG_INF("PA sync %p lost with reason %u", (void *)sync, info->reason); + LOG_INF("PA sync %p lost with reason 0x%02X", (void *)sync, info->reason); /* Without PA we cannot sync to any new BIG - Clear data */ - broadcast_sink.requested_bis_sync = 0; broadcast_sink.pa_sync = NULL; k_work_cancel_delayable(&pa_timer); atomic_clear_bit(flags, FLAG_BROADCAST_SYNCABLE); @@ -736,6 +740,7 @@ int init_cap_acceptor_broadcast(void) static struct bt_bap_broadcast_sink_cb broadcast_sink_cbs = { .base_recv = base_recv_cb, .syncable = syncable_cb, + .started = sink_started_cb, .stopped = sink_stopped_cb, }; static struct bt_bap_stream_ops broadcast_stream_ops = { diff --git a/samples/bluetooth/cap_acceptor/src/cap_acceptor_unicast.c b/samples/bluetooth/cap_acceptor/src/cap_acceptor_unicast.c index 55a9f91099e5..43e26e061263 100644 --- a/samples/bluetooth/cap_acceptor/src/cap_acceptor_unicast.c +++ b/samples/bluetooth/cap_acceptor/src/cap_acceptor_unicast.c @@ -1,7 +1,7 @@ /** @file * @brief Bluetooth Common Audio Profile (CAP) Acceptor unicast. * - * Copyright (c) 2021-2024 Nordic Semiconductor ASA + * Copyright (c) 2021-2025 Nordic Semiconductor ASA * Copyright (c) 2023 NXP * * SPDX-License-Identifier: Apache-2.0 @@ -296,7 +296,6 @@ static void unicast_stream_enabled_cb(struct bt_bap_stream *bap_stream) static void unicast_stream_started_cb(struct bt_bap_stream *bap_stream) { LOG_INF("Started bap_stream %p", bap_stream); - total_unicast_rx_iso_packet_count = 0U; } static void unicast_stream_metadata_updated_cb(struct bt_bap_stream *bap_stream) @@ -438,7 +437,10 @@ int init_cap_acceptor_unicast(struct peer_config *peer) } bt_cap_stream_ops_register(&peer->source_stream, &unicast_stream_ops); - bt_cap_stream_ops_register(&peer->sink_stream, &unicast_stream_ops); + + ARRAY_FOR_EACH_PTR(peer->sink_streams, stream) { + bt_cap_stream_ops_register(stream, &unicast_stream_ops); + } if (IS_ENABLED(CONFIG_BT_ASCS_ASE_SRC)) { static bool thread_started; @@ -459,5 +461,8 @@ int init_cap_acceptor_unicast(struct peer_config *peer) k_sem_init(&peer->source_stream_sem, 0, 1); k_sem_init(&peer->sink_stream_sem, 0, 1); + total_unicast_rx_iso_packet_count = 0U; + total_unicast_tx_iso_packet_count = 0U; + return 0; } diff --git a/samples/bluetooth/cap_acceptor/src/main.c b/samples/bluetooth/cap_acceptor/src/main.c index fc51a8a0ade0..e21c24ccadcd 100644 --- a/samples/bluetooth/cap_acceptor/src/main.c +++ b/samples/bluetooth/cap_acceptor/src/main.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -140,21 +141,32 @@ static int advertise(void) struct bt_cap_stream *stream_alloc(enum bt_audio_dir dir) { - if (dir == BT_AUDIO_DIR_SINK && peer.sink_stream.bap_stream.ep == NULL) { - return &peer.sink_stream; + struct bt_cap_stream *ret_stream; + + if (dir == BT_AUDIO_DIR_SINK) { + ret_stream = NULL; + ARRAY_FOR_EACH_PTR(peer.sink_streams, stream) { + if (stream->bap_stream.ep == NULL) { + ret_stream = stream; + } + } } else if (dir == BT_AUDIO_DIR_SOURCE && peer.source_stream.bap_stream.ep == NULL) { - return &peer.source_stream; + ret_stream = &peer.source_stream; + } else { + ret_stream = NULL; } - return NULL; + return ret_stream; } void stream_released(const struct bt_cap_stream *cap_stream) { if (cap_stream == &peer.source_stream) { k_sem_give(&peer.source_stream_sem); - } else if (cap_stream == &peer.sink_stream) { + } else if (IS_ARRAY_ELEMENT(peer.sink_streams, cap_stream)) { k_sem_give(&peer.sink_stream_sem); + } else { + __ASSERT(false, "Invalid stream: %p", cap_stream); } } @@ -201,11 +213,13 @@ static int reset_cap_acceptor(void) } } - if (peer.sink_stream.bap_stream.ep != NULL) { - err = k_sem_take(&peer.sink_stream_sem, SEM_TIMEOUT); - if (err != 0) { - LOG_ERR("Timeout on sink_stream_sem: %d", err); - return err; + ARRAY_FOR_EACH_PTR(peer.sink_streams, stream) { + if (stream->bap_stream.ep != NULL) { + err = k_sem_take(&peer.sink_stream_sem, SEM_TIMEOUT); + if (err != 0) { + LOG_ERR("Timeout on sink_stream_sem: %d", err); + return err; + } } } diff --git a/tests/bsim/bluetooth/audio_samples/cap/acceptor/src/cap_acceptor_sample_test.c b/tests/bsim/bluetooth/audio_samples/cap/acceptor/src/cap_acceptor_sample_test.c index cc15a7807696..ba0222b2a960 100644 --- a/tests/bsim/bluetooth/audio_samples/cap/acceptor/src/cap_acceptor_sample_test.c +++ b/tests/bsim/bluetooth/audio_samples/cap/acceptor/src/cap_acceptor_sample_test.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023-2024 Nordic Semiconductor ASA + * Copyright (c) 2023-2025 Nordic Semiconductor ASA * Copyright (c) 2017-2019 Oticon A/S * * SPDX-License-Identifier: Apache-2.0 @@ -51,13 +51,14 @@ static void test_cap_acceptor_sample_tick(bs_time_t HW_device_time) extern uint64_t total_unicast_tx_iso_packet_count; bs_trace_info_time(2, "%" PRIu64 " unicast packets received, expected >= %i\n", - total_unicast_tx_iso_packet_count, PASS_THRESHOLD); + total_unicast_rx_iso_packet_count, PASS_THRESHOLD); bs_trace_info_time(2, "%" PRIu64 " unicast packets sent, expected >= %i\n", total_unicast_tx_iso_packet_count, PASS_THRESHOLD); - if (total_unicast_rx_iso_packet_count < PASS_THRESHOLD || + /* Fail if we neither sent or receive any ISO packets */ + if (total_unicast_rx_iso_packet_count < PASS_THRESHOLD && total_unicast_tx_iso_packet_count < PASS_THRESHOLD) { - FAIL("cap_acceptor FAILED with(Did not pass after %d seconds)\n ", + FAIL("cap_acceptor unicast FAILED (Did not pass after %d seconds)\n ", WAIT_TIME); return; } @@ -70,7 +71,7 @@ static void test_cap_acceptor_sample_tick(bs_time_t HW_device_time) total_broadcast_rx_iso_packet_count, PASS_THRESHOLD); if (total_broadcast_rx_iso_packet_count < PASS_THRESHOLD) { - FAIL("cap_acceptor FAILED with (Did not pass after %d seconds)\n ", + FAIL("cap_acceptor broadcast FAILED (Did not pass after %d seconds)\n ", WAIT_TIME); return; } From 15eb9daa87a480bbf59e27dc1e22faf2bf49260d Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Wed, 8 Oct 2025 14:43:01 +0200 Subject: [PATCH 0574/3659] samples: Bluetooth: CAP: Initiator: Fix test count name Renamed total_rx_iso_packet_count to total_unicast_rx_iso_packet_count to make it consistent with total_unicast_tx_iso_packet_count. Signed-off-by: Emil Gydesen --- .../cap_initiator/src/cap_initiator_unicast.c | 13 +++++++------ .../cap/initiator/src/cap_initiator_sample_test.c | 10 +++++----- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/samples/bluetooth/cap_initiator/src/cap_initiator_unicast.c b/samples/bluetooth/cap_initiator/src/cap_initiator_unicast.c index 3fd08baaed7e..1ce2f13a51fd 100644 --- a/samples/bluetooth/cap_initiator/src/cap_initiator_unicast.c +++ b/samples/bluetooth/cap_initiator/src/cap_initiator_unicast.c @@ -45,7 +45,7 @@ LOG_MODULE_REGISTER(cap_initiator_unicast, LOG_LEVEL_INF); static struct bt_bap_lc3_preset unicast_preset_16_2_1 = BT_BAP_LC3_UNICAST_PRESET_16_2_1( BT_AUDIO_LOCATION_MONO_AUDIO, BT_AUDIO_CONTEXT_TYPE_UNSPECIFIED); static struct bt_cap_unicast_group *unicast_group; -uint64_t total_rx_iso_packet_count; /* This value is exposed to test code */ +uint64_t total_unicast_rx_iso_packet_count; /* This value is exposed to test code */ uint64_t total_unicast_tx_iso_packet_count; /* This value is exposed to test code */ /** Struct to contain information for a specific peer (CAP) device */ @@ -119,8 +119,6 @@ static void unicast_stream_enabled_cb(struct bt_bap_stream *stream) static void unicast_stream_started_cb(struct bt_bap_stream *stream) { LOG_INF("Started stream %p", stream); - total_rx_iso_packet_count = 0U; - total_unicast_tx_iso_packet_count = 0U; if (is_tx_stream(stream)) { struct bt_cap_stream *cap_stream = @@ -179,11 +177,11 @@ static void unicast_stream_recv_cb(struct bt_bap_stream *stream, * (see the `info->flags` for which flags to check), */ - if ((total_rx_iso_packet_count % 100U) == 0U) { - LOG_INF("Received %llu HCI ISO data packets", total_rx_iso_packet_count); + if ((total_unicast_rx_iso_packet_count % 100U) == 0U) { + LOG_INF("Received %llu HCI ISO data packets", total_unicast_rx_iso_packet_count); } - total_rx_iso_packet_count++; + total_unicast_rx_iso_packet_count++; } static void unicast_stream_sent_cb(struct bt_bap_stream *stream) @@ -801,6 +799,9 @@ static int reset_cap_initiator(void) k_sem_reset(&sem_state_change); k_sem_reset(&sem_mtu_exchanged); + total_unicast_rx_iso_packet_count = 0U; + total_unicast_tx_iso_packet_count = 0U; + return 0; } diff --git a/tests/bsim/bluetooth/audio_samples/cap/initiator/src/cap_initiator_sample_test.c b/tests/bsim/bluetooth/audio_samples/cap/initiator/src/cap_initiator_sample_test.c index 4c87c4397965..1d843013ad1f 100644 --- a/tests/bsim/bluetooth/audio_samples/cap/initiator/src/cap_initiator_sample_test.c +++ b/tests/bsim/bluetooth/audio_samples/cap/initiator/src/cap_initiator_sample_test.c @@ -46,17 +46,17 @@ static void test_cap_initiator_sample_tick(bs_time_t HW_device_time) */ if (IS_ENABLED(CONFIG_SAMPLE_UNICAST)) { - extern uint64_t total_rx_iso_packet_count; + extern uint64_t total_unicast_rx_iso_packet_count; extern uint64_t total_unicast_tx_iso_packet_count; bs_trace_info_time(2, "%" PRIu64 " unicast packets received, expected >= %i\n", - total_rx_iso_packet_count, PASS_THRESHOLD); + total_unicast_rx_iso_packet_count, PASS_THRESHOLD); bs_trace_info_time(2, "%" PRIu64 " unicast packets sent, expected >= %i\n", total_unicast_tx_iso_packet_count, PASS_THRESHOLD); - if (total_rx_iso_packet_count < PASS_THRESHOLD || + if (total_unicast_rx_iso_packet_count < PASS_THRESHOLD || total_unicast_tx_iso_packet_count < PASS_THRESHOLD) { - FAIL("cap_initiator FAILED with(Did not pass after %d seconds)\n ", + FAIL("cap_initiator unicast FAILED (Did not pass after %d seconds)\n ", WAIT_TIME); return; } @@ -69,7 +69,7 @@ static void test_cap_initiator_sample_tick(bs_time_t HW_device_time) total_broadcast_tx_iso_packet_count, PASS_THRESHOLD); if (total_broadcast_tx_iso_packet_count < PASS_THRESHOLD) { - FAIL("cap_initiator FAILED with (Did not pass after %d seconds)\n ", + FAIL("cap_initiator broadcast FAILED (Did not pass after %d seconds)\n ", WAIT_TIME); return; } From f897a24e68b3486035093ebf254c8dad2eade496 Mon Sep 17 00:00:00 2001 From: Ryan McClelland Date: Tue, 11 Nov 2025 15:43:10 -0800 Subject: [PATCH 0575/3659] drivers: i3c: cdns: fix no ibi payload There was a misunderstanding in the spec, where if the bcr says there is no payload, there are NO data bytes that follow the ibi address. Signed-off-by: Ryan McClelland --- drivers/i3c/i3c_cdns.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/i3c/i3c_cdns.c b/drivers/i3c/i3c_cdns.c index 9ab43441f595..2eeb3537b7bc 100644 --- a/drivers/i3c/i3c_cdns.c +++ b/drivers/i3c/i3c_cdns.c @@ -1101,8 +1101,8 @@ static int cdns_i3c_controller_ibi_enable(const struct device *dev, struct i3c_d sir_cfg |= SIR_MAP_DEV_PL(target->data_length.max_ibi); } } else { - /* Set to 1 for MDB */ - sir_cfg |= SIR_MAP_DEV_PL(1); + /* Set to 0 for no ibi payload */ + sir_cfg |= SIR_MAP_DEV_PL(0); } /* ACK if there is an ibi tir cb or if it is controller capable*/ if ((target->ibi_cb != NULL) || i3c_device_is_controller_capable(target)) { From fef0958ca5dbc747b94d568a6400099bd577c857 Mon Sep 17 00:00:00 2001 From: Thomas Decker Date: Thu, 20 Nov 2025 10:52:47 +0100 Subject: [PATCH 0576/3659] arch: arm: mpu: Add missing define REGION_FLASH_SIZE for 32k and 32M Add missing REGION_FLASH_SIZE defines when CONFIG_FLASH_SIZE is 32k or 32M Signed-off-by: Thomas Decker --- include/zephyr/arch/arm/mpu/arm_mpu_mem_cfg.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/include/zephyr/arch/arm/mpu/arm_mpu_mem_cfg.h b/include/zephyr/arch/arm/mpu/arm_mpu_mem_cfg.h index 5b52a939d2a7..a99223262d64 100644 --- a/include/zephyr/arch/arm/mpu/arm_mpu_mem_cfg.h +++ b/include/zephyr/arch/arm/mpu/arm_mpu_mem_cfg.h @@ -12,7 +12,9 @@ #if !defined(CONFIG_ARMV8_M_BASELINE) && !defined(CONFIG_ARMV8_M_MAINLINE) /* Flash Region Definitions */ -#if CONFIG_FLASH_SIZE <= 64 +#if CONFIG_FLASH_SIZE <= 32 +#define REGION_FLASH_SIZE REGION_32K +#elif CONFIG_FLASH_SIZE <= 64 #define REGION_FLASH_SIZE REGION_64K #elif CONFIG_FLASH_SIZE <= 128 #define REGION_FLASH_SIZE REGION_128K @@ -30,6 +32,8 @@ #define REGION_FLASH_SIZE REGION_8M #elif CONFIG_FLASH_SIZE <= 16384 #define REGION_FLASH_SIZE REGION_16M +#elif CONFIG_FLASH_SIZE <= 32768 +#define REGION_FLASH_SIZE REGION_32M #elif CONFIG_FLASH_SIZE <= 65536 #define REGION_FLASH_SIZE REGION_64M #elif CONFIG_FLASH_SIZE <= 131072 From b185fdea97cb8f3181ffcce6f51d85dacbb4b3b5 Mon Sep 17 00:00:00 2001 From: Jason Yu Date: Tue, 25 Nov 2025 15:00:25 +0800 Subject: [PATCH 0577/3659] drivers: hwinfo: mcux_rcm: Improve get_supported_reset_cause Remove the conditional compilation guard FSL_FEATURE_RCM_HAS_PARAM. `hwinfo_mcux_rcm_xlate_reset_sources` has handled the supported cause using `FSL_FEATURE_xxx` macros, passing `UINT32_MAX` can get all supported reset cause. Signed-off-by: Jason Yu --- drivers/hwinfo/hwinfo_mcux_rcm.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/hwinfo/hwinfo_mcux_rcm.c b/drivers/hwinfo/hwinfo_mcux_rcm.c index ed8122ac73b5..9dddf25ac0d5 100644 --- a/drivers/hwinfo/hwinfo_mcux_rcm.c +++ b/drivers/hwinfo/hwinfo_mcux_rcm.c @@ -117,7 +117,6 @@ int z_impl_hwinfo_clear_reset_cause(void) } #endif /* (defined(FSL_FEATURE_RCM_HAS_SSRS) && FSL_FEATURE_RCM_HAS_SSRS) */ -#if (defined(FSL_FEATURE_RCM_HAS_PARAM) && FSL_FEATURE_RCM_HAS_PARAM) int z_impl_hwinfo_get_supported_reset_cause(uint32_t *supported) { *supported = hwinfo_mcux_rcm_xlate_reset_sources(UINT32_MAX); @@ -126,4 +125,3 @@ int z_impl_hwinfo_get_supported_reset_cause(uint32_t *supported) return 0; } -#endif /* (defined(FSL_FEATURE_RCM_HAS_PARAM) && FSL_FEATURE_RCM_HAS_PARAM) */ From 420c0f94eabc5f3dc2cd6bd29cef6ff806d46484 Mon Sep 17 00:00:00 2001 From: Jason Yu Date: Tue, 25 Nov 2025 14:31:35 +0800 Subject: [PATCH 0578/3659] drivers: hwinfo: rcm: Enable HWINFO RCM for MCXE24x and KE1xZ Enables the MCUX Reset Control Module (RCM) to support hwinfo Signed-off-by: Jason Yu --- soc/nxp/kinetis/ke1xz/Kconfig | 1 + soc/nxp/mcx/mcxe/mcxe24x/Kconfig | 1 + 2 files changed, 2 insertions(+) diff --git a/soc/nxp/kinetis/ke1xz/Kconfig b/soc/nxp/kinetis/ke1xz/Kconfig index f8e878cb13ae..633b24ee7302 100644 --- a/soc/nxp/kinetis/ke1xz/Kconfig +++ b/soc/nxp/kinetis/ke1xz/Kconfig @@ -14,3 +14,4 @@ config SOC_SERIES_KE1XZ select HAS_PM select SOC_RESET_HOOK select SOC_EARLY_INIT_HOOK + select HAS_MCUX_RCM diff --git a/soc/nxp/mcx/mcxe/mcxe24x/Kconfig b/soc/nxp/mcx/mcxe/mcxe24x/Kconfig index 94e69e68b807..6ed62c6bc95e 100644 --- a/soc/nxp/mcx/mcxe/mcxe24x/Kconfig +++ b/soc/nxp/mcx/mcxe/mcxe24x/Kconfig @@ -11,6 +11,7 @@ config SOC_SERIES_MCXE24X select SOC_RESET_HOOK select CPU_HAS_ICACHE select HAS_MCUX_LMEM_CACHE + select HAS_MCUX_RCM if SOC_SERIES_MCXE24X From 2fb46db59bf6b0af69090e616a526c4a0d8a2779 Mon Sep 17 00:00:00 2001 From: Jason Yu Date: Thu, 4 Dec 2025 21:56:23 +0800 Subject: [PATCH 0579/3659] drivers: hwinfo: mcux_rcm: Fix wrong comment Correct mismatched #endif comment to reference the correct macro FSL_FEATURE_RCM_HAS_SSRS Signed-off-by: Jason Yu --- drivers/hwinfo/hwinfo_mcux_rcm.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/hwinfo/hwinfo_mcux_rcm.c b/drivers/hwinfo/hwinfo_mcux_rcm.c index 9dddf25ac0d5..01f961733807 100644 --- a/drivers/hwinfo/hwinfo_mcux_rcm.c +++ b/drivers/hwinfo/hwinfo_mcux_rcm.c @@ -16,7 +16,7 @@ LOG_MODULE_REGISTER(hwinfo_rcm, CONFIG_HWINFO_LOG_LEVEL); * Translate bitmask from MCUX RCM reset source bitmask to Zephyr * hwinfo reset source bitmask. * - * @param NXP MCUX RCM reset source mask. + * @param sources NXP MCUX RCM reset source mask. * @retval Zephyr hwinfo reset source mask. */ static uint32_t hwinfo_mcux_rcm_xlate_reset_sources(uint32_t sources) @@ -92,9 +92,9 @@ int z_impl_hwinfo_get_reset_cause(uint32_t *cause) #if (defined(FSL_FEATURE_RCM_HAS_SSRS) && FSL_FEATURE_RCM_HAS_SSRS) sources = RCM_GetStickyResetSources(RCM) & kRCM_SourceAll; -#else /* (defined(FSL_FEATURE_RCM_HAS_SSRS) && FSL_FEATURE_RCM_HAS_SSRS) */ +#else /* !(defined(FSL_FEATURE_RCM_HAS_SSRS) && FSL_FEATURE_RCM_HAS_SSRS) */ sources = RCM_GetPreviousResetSources(RCM) & kRCM_SourceAll; -#endif /* !(defined(FSL_FEATURE_RCM_HAS_PARAM) && FSL_FEATURE_RCM_HAS_PARAM) */ +#endif /* !(defined(FSL_FEATURE_RCM_HAS_SSRS) && FSL_FEATURE_RCM_HAS_SSRS) */ *cause = hwinfo_mcux_rcm_xlate_reset_sources(sources); From 53dfed0455d5c3578a21f8d9fc3fd52ff92fe5ae Mon Sep 17 00:00:00 2001 From: Petr Buchta Date: Mon, 15 Dec 2025 13:48:58 +0100 Subject: [PATCH 0580/3659] boards: nxp: frdm_mcxe247: Enable flash controller This commit enables use of FTFC flash controller. Together with DT changes it adds support for FTFC into soc_flash_mcux.c driver. Signed-off-by: Petr Buchta --- drivers/flash/Kconfig.mcux | 1 + drivers/flash/soc_flash_mcux.c | 2 ++ dts/arm/nxp/nxp_mcxe247.dtsi | 2 ++ modules/hal_nxp/mcux/mcux-sdk-ng/drivers/drivers.cmake | 2 +- 4 files changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/flash/Kconfig.mcux b/drivers/flash/Kconfig.mcux index 513add2657aa..64fc22b8cd25 100644 --- a/drivers/flash/Kconfig.mcux +++ b/drivers/flash/Kconfig.mcux @@ -6,6 +6,7 @@ config SOC_FLASH_MCUX depends on DT_HAS_NXP_KINETIS_FTFA_ENABLED || \ DT_HAS_NXP_KINETIS_FTFE_ENABLED || \ DT_HAS_NXP_KINETIS_FTFL_ENABLED || \ + DT_HAS_NXP_KINETIS_FTFC_ENABLED || \ DT_HAS_NXP_IAP_FMC55_ENABLED || \ DT_HAS_NXP_IAP_FMC553_ENABLED || \ DT_HAS_NXP_MSF1_ENABLED diff --git a/drivers/flash/soc_flash_mcux.c b/drivers/flash/soc_flash_mcux.c index 052d377fc8ed..8300c0870b99 100644 --- a/drivers/flash/soc_flash_mcux.c +++ b/drivers/flash/soc_flash_mcux.c @@ -28,6 +28,8 @@ LOG_MODULE_REGISTER(flash_mcux); #define DT_DRV_COMPAT nxp_kinetis_ftfe #elif DT_NODE_HAS_STATUS_OKAY(DT_INST(0, nxp_kinetis_ftfl)) #define DT_DRV_COMPAT nxp_kinetis_ftfl +#elif DT_NODE_HAS_STATUS_OKAY(DT_INST(0, nxp_kinetis_ftfc)) +#define DT_DRV_COMPAT nxp_kinetis_ftfc #elif DT_NODE_HAS_STATUS_OKAY(DT_INST(0, nxp_iap_fmc55)) #define DT_DRV_COMPAT nxp_iap_fmc55 #define SOC_HAS_IAP 1 diff --git a/dts/arm/nxp/nxp_mcxe247.dtsi b/dts/arm/nxp/nxp_mcxe247.dtsi index 33824b787672..1eb92edc0795 100644 --- a/dts/arm/nxp/nxp_mcxe247.dtsi +++ b/dts/arm/nxp/nxp_mcxe247.dtsi @@ -37,6 +37,8 @@ }; &ftfc { + status = "okay"; + flash0: flash@0 { compatible = "soc-nv-flash"; reg = <0 DT_SIZE_K(1536)>; diff --git a/modules/hal_nxp/mcux/mcux-sdk-ng/drivers/drivers.cmake b/modules/hal_nxp/mcux/mcux-sdk-ng/drivers/drivers.cmake index 07a8e45d973a..03d907676fca 100644 --- a/modules/hal_nxp/mcux/mcux-sdk-ng/drivers/drivers.cmake +++ b/modules/hal_nxp/mcux/mcux-sdk-ng/drivers/drivers.cmake @@ -241,7 +241,7 @@ else() set_variable_ifdef(CONFIG_MBOX_NXP_IMX_MU CONFIG_MCUX_COMPONENT_driver.mu) endif() -if(CONFIG_SOC_FAMILY_KINETIS OR CONFIG_SOC_FAMILY_MCXC) +if(CONFIG_SOC_FAMILY_KINETIS OR CONFIG_SOC_FAMILY_MCXC OR CONFIG_SOC_SERIES_MCXE24X) set_variable_ifdef(CONFIG_SOC_FLASH_MCUX CONFIG_MCUX_COMPONENT_driver.flash) endif() From c8e73024daeac328850ceebdc177b8b3ffca7563 Mon Sep 17 00:00:00 2001 From: Mathieu Choplain Date: Wed, 17 Dec 2025 12:59:32 +0100 Subject: [PATCH 0581/3659] doc: migration: 4.4: place Video drivers section in sorted block The Video drivers section was mistakenly placed below the end marker of the zephyr-keep-sorted block. Move it back inside the block for proper ordering. Signed-off-by: Mathieu Choplain --- doc/releases/migration-guide-4.4.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/releases/migration-guide-4.4.rst b/doc/releases/migration-guide-4.4.rst index 80f70333f953..6f3b594a67e5 100644 --- a/doc/releases/migration-guide-4.4.rst +++ b/doc/releases/migration-guide-4.4.rst @@ -257,13 +257,13 @@ USB * :dtcompatible:`maxim,max3421e_spi` has been renamed to :dtcompatible:`maxim,max3421e-spi`. -.. zephyr-keep-sorted-stop - Video === * CONFIG_VIDEO_OV7670 is now gone and replaced by CONFIG_VIDEO_OV767X. This allows supporting both the OV7670 and 0V7675. +.. zephyr-keep-sorted-stop + Bluetooth ********* From a2661d380a397125f6810e9155d6fecf7de02aaf Mon Sep 17 00:00:00 2001 From: Bartosz Miller Date: Mon, 15 Dec 2025 15:50:55 +0100 Subject: [PATCH 0582/3659] tests: drivers: uart: Extend UART120 testing for nrf54h20 cpuflpr Run UART tests on 54h20 cpuflpr with uart120 Signed-off-by: Bartosz Miller --- .../nrf54h20dk_nrf54h20_cpuflpr.overlay | 71 +++++++++++++++++++ .../uart/uart_elementary/testcase.yaml | 1 + 2 files changed, 72 insertions(+) create mode 100644 tests/drivers/uart/uart_elementary/boards/nrf54h20dk_nrf54h20_cpuflpr.overlay diff --git a/tests/drivers/uart/uart_elementary/boards/nrf54h20dk_nrf54h20_cpuflpr.overlay b/tests/drivers/uart/uart_elementary/boards/nrf54h20dk_nrf54h20_cpuflpr.overlay new file mode 100644 index 000000000000..ccb2f3342549 --- /dev/null +++ b/tests/drivers/uart/uart_elementary/boards/nrf54h20dk_nrf54h20_cpuflpr.overlay @@ -0,0 +1,71 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +/ { + chosen { + zephyr,console = &uart131; + }; +}; + +&pinctrl { + uart120_default_alt: uart120_default_alt { + group1 { + psels = , + ; + }; + }; + + uart120_sleep_alt: uart120_sleep_alt { + group1 { + psels = , + ; + low-power-enable; + }; + }; + + uart131_default_alt: uart131_default_alt { + group1 { + psels = , + , + , + ; + }; + }; + + uart131_sleep_alt: uart131_sleep_alt { + group1 { + psels = , + , + , + ; + low-power-enable; + }; + }; +}; + +&cpuapp_dma_region { + status = "okay"; +}; + +&dma_fast_region { + status = "okay"; +}; + +&uart131 { + status = "okay"; + memory-regions = <&cpuapp_dma_region>; + pinctrl-0 = <&uart131_default_alt>; + pinctrl-1 = <&uart131_sleep_alt>; + pinctrl-names = "default", "sleep"; + current-speed = <115200>; + hw-flow-control; +}; + +dut: &uart120 { + status = "okay"; + memory-regions = <&dma_fast_region>; + pinctrl-0 = <&uart120_default_alt>; + pinctrl-1 = <&uart120_sleep_alt>; + pinctrl-names = "default", "sleep"; + current-speed = <115200>; + /delete-property/ hw-flow-control; +}; diff --git a/tests/drivers/uart/uart_elementary/testcase.yaml b/tests/drivers/uart/uart_elementary/testcase.yaml index 3dd9e1e779b7..3d0681ed7c56 100644 --- a/tests/drivers/uart/uart_elementary/testcase.yaml +++ b/tests/drivers/uart/uart_elementary/testcase.yaml @@ -11,6 +11,7 @@ tests: filter: CONFIG_SERIAL_SUPPORT_INTERRUPT platform_allow: - nrf54h20dk/nrf54h20/cpuapp + - nrf54h20dk/nrf54h20/cpuflpr - nrf54l15dk/nrf54l15/cpuapp - nrf54l15dk/nrf54l15/cpuflpr - nrf54lm20dk/nrf54lm20a/cpuapp From 1d92d0b5fff519b0e3dbb8b64b4d1071d8fffeae Mon Sep 17 00:00:00 2001 From: Jordan Yates Date: Wed, 3 Dec 2025 10:28:11 +1000 Subject: [PATCH 0583/3659] utils: timeutil: option to disable clock skew Accurately applying clock skew correction in `timeutil_sync_ref_from_local` and `timeutil_sync_local_from_ref` requires double-precision floating point operations. If this is the only usage of double precision logic in the build, but clocks skews are not used, this can be a significant ROM overhead. Disabling this option can save ~2.4 kB of ROM. Signed-off-by: Jordan Yates --- doc/releases/release-notes-4.4.rst | 4 ++++ include/zephyr/sys/timeutil.h | 4 ++++ lib/utils/Kconfig | 10 ++++++++++ lib/utils/timeutil.c | 7 +++++-- 4 files changed, 23 insertions(+), 2 deletions(-) diff --git a/doc/releases/release-notes-4.4.rst b/doc/releases/release-notes-4.4.rst index 7aa852d2ac6e..031f714bbe88 100644 --- a/doc/releases/release-notes-4.4.rst +++ b/doc/releases/release-notes-4.4.rst @@ -180,6 +180,10 @@ New APIs and options * :c:macro:`COND_CASE_1` +* Timeutil + + * :kconfig:option:`CONFIG_TIMEUTIL_APPLY_SKEW` + .. zephyr-keep-sorted-stop New Boards diff --git a/include/zephyr/sys/timeutil.h b/include/zephyr/sys/timeutil.h index 4c7f32424bec..5eb23abfdd06 100644 --- a/include/zephyr/sys/timeutil.h +++ b/include/zephyr/sys/timeutil.h @@ -296,6 +296,8 @@ float timeutil_sync_estimate_skew(const struct timeutil_sync_state *tsp); * produces an error. If interpolation fails the referenced object is * not modified. * + * @note Clock skews are only applied with @kconfig{CONFIG_TIMEUTIL_APPLY_SKEW} + * * @retval 0 if interpolated using a skew of 1 * @retval 1 if interpolated using a skew not equal to 1 * @retval -EINVAL @@ -321,6 +323,8 @@ int timeutil_sync_ref_from_local(const struct timeutil_sync_state *tsp, * time 0 is provided without error. If interpolation fails the * referenced object is not modified. * + * @note Clock skews are only applied with @kconfig{CONFIG_TIMEUTIL_APPLY_SKEW} + * * @retval 0 if successful with a skew of 1 * @retval 1 if successful with a skew not equal to 1 * @retval -EINVAL diff --git a/lib/utils/Kconfig b/lib/utils/Kconfig index c22eae50fbf0..7a3cc8f62875 100644 --- a/lib/utils/Kconfig +++ b/lib/utils/Kconfig @@ -98,4 +98,14 @@ config GETOPT_LONG for other threads by extending function sys_getopt_state_get in getopt_common.c file. +config TIMEUTIL_APPLY_SKEW + bool "Support applying clock skew corrections in conversion functions" + default y + help + Accurately applying clock skew correction in timeutil_sync_ref_from_local + and timeutil_sync_local_from_ref requires double-precision floating point + operations. If this is the only usage of double precision logic in the + build, but clocks skews are not used, this can be a significant ROM + overhead. Disabling this option can save ~2.4 kB of ROM. + endmenu diff --git a/lib/utils/timeutil.c b/lib/utils/timeutil.c index a18b43f4912b..c42d977338f6 100644 --- a/lib/utils/timeutil.c +++ b/lib/utils/timeutil.c @@ -139,12 +139,14 @@ int timeutil_sync_ref_from_local(const struct timeutil_sync_state *tsp, if ((tsp->skew > 0) && (tsp->base.ref > 0) && (refp != NULL)) { const struct timeutil_sync_config *cfg = tsp->cfg; int64_t local_delta = local - tsp->base.local; +#ifdef CONFIG_TIMEUTIL_APPLY_SKEW /* (x * 1.0) != x for large values of x. * Therefore only apply the multiplication if the skew is not one. */ if (tsp->skew != 1.0f) { local_delta *= (double)tsp->skew; } +#endif /* CONFIG_TIMEUTIL_APPLY_SKEW */ int64_t ref_delta = local_delta * cfg->ref_Hz / cfg->local_Hz; int64_t ref_abs = (int64_t)tsp->base.ref + ref_delta; @@ -167,14 +169,15 @@ int timeutil_sync_local_from_ref(const struct timeutil_sync_state *tsp, if ((tsp->skew > 0) && (tsp->base.ref > 0) && (localp != NULL)) { const struct timeutil_sync_config *cfg = tsp->cfg; int64_t ref_delta = (int64_t)(ref - tsp->base.ref); + int64_t local_delta = (ref_delta * cfg->local_Hz) / cfg->ref_Hz; +#ifdef CONFIG_TIMEUTIL_APPLY_SKEW /* (x / 1.0) != x for large values of x. * Therefore only apply the division if the skew is not one. */ - int64_t local_delta = (ref_delta * cfg->local_Hz) / cfg->ref_Hz; - if (tsp->skew != 1.0f) { local_delta /= (double)tsp->skew; } +#endif /* CONFIG_TIMEUTIL_APPLY_SKEW */ int64_t local_abs = (int64_t)tsp->base.local + (int64_t)local_delta; From 9d88c8cfb0f57b965cc744048eca8911d2be35e3 Mon Sep 17 00:00:00 2001 From: Jordan Yates Date: Wed, 3 Dec 2025 10:40:56 +1000 Subject: [PATCH 0584/3659] tests: unit: timeutil: test `CONFIG_TIMEUTIL_APPLY_SKEW=n` Test the `timeutil` libraries compile and behave the same way (excluding the skew application) when `CONFIG_TIMEUTIL_APPLY_SKEW=n`. Signed-off-by: Jordan Yates --- tests/unit/timeutil/test_sync.c | 19 ++++++++++++++++--- tests/unit/timeutil/testcase.yaml | 4 ++++ 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/tests/unit/timeutil/test_sync.c b/tests/unit/timeutil/test_sync.c index 25bc3a22a52b..bafd1bd6da3e 100644 --- a/tests/unit/timeutil/test_sync.c +++ b/tests/unit/timeutil/test_sync.c @@ -225,6 +225,7 @@ static void tref_from_local(const char *tag, }; uint64_t ref = 0; int rv = timeutil_sync_ref_from_local(&ss, 0, &ref); + int skew_factor; zassert_equal(rv, -EINVAL, "%s: unexpected uninit convert: %d", tag, rv); @@ -274,9 +275,15 @@ static void tref_from_local(const char *tag, zassert_equal(rv, 0, "%s: failed set skew", tag); + /* Whether the conversion takes skew into account is controlled + * by the Kconfig option. + */ + skew_factor = IS_ENABLED(CONFIG_TIMEUTIL_APPLY_SKEW) ? 2 : 1; + /* Local at double speed corresponds to half advance in ref */ rv = timeutil_sync_ref_from_local(&ss, ss.base.local - + scale_local(2, cfg), &ref); + + scale_local(skew_factor, cfg), + &ref); zassert_equal(rv, 1, "%s: unexpected skew adj fail", tag); zassert_equal(ref, ss.base.ref + cfg->ref_Hz, @@ -302,6 +309,7 @@ static void tlocal_from_ref(const char *tag, }; int64_t local = 0; int rv = timeutil_sync_local_from_ref(&ss, 0, &local); + int skew_factor; zassert_equal(rv, -EINVAL, "%s: unexpected uninit convert: %d", tag, rv); @@ -336,15 +344,20 @@ static void tlocal_from_ref(const char *tag, zassert_equal(local, scale_local_signed(-2, cfg), "%s: unexpected base-7s convert", tag); - /* Skew of 0.5 means local runs at double speed */ rv = timeutil_sync_state_set_skew(&ss, 0.5, NULL); zassert_equal(rv, 0, "%s: failed set skew", tag); + /* Whether the conversion takes skew into account is controlled + * by the Kconfig option. + */ + skew_factor = IS_ENABLED(CONFIG_TIMEUTIL_APPLY_SKEW) ? 2 : 1; + /* Local at double speed corresponds to half advance in ref */ rv = timeutil_sync_local_from_ref(&ss, ss.base.ref - + scale_ref(1, cfg) / 2, &local); + + scale_ref(1, cfg) / skew_factor, + &local); zassert_equal(rv, 1, "%s: unexpected skew adj fail", tag); zassert_equal(local, ss.base.local + scale_local(1, cfg), diff --git a/tests/unit/timeutil/testcase.yaml b/tests/unit/timeutil/testcase.yaml index eac190d82adf..d854dcc756f1 100644 --- a/tests/unit/timeutil/testcase.yaml +++ b/tests/unit/timeutil/testcase.yaml @@ -8,3 +8,7 @@ tests: utilities.time.64bit: extra_args: M64_MODE=1 + + utilities.time.no_skew: + extra_configs: + - CONFIG_TIMEUTIL_APPLY_SKEW=n From 235aa1aa7f7cff394fbbb217ff1eb924e228ff09 Mon Sep 17 00:00:00 2001 From: Jordan Yates Date: Thu, 11 Dec 2025 14:19:44 +1000 Subject: [PATCH 0585/3659] flash: flash_simulator: static programmable unit buffer Move the programmable unit buffer used to detect double writes out of the function stack. This fixes stack overflows when simulating flash devices with large programming units (SPI-NAND, 2-4 kB). Signed-off-by: Jordan Yates --- drivers/flash/flash_simulator.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/flash/flash_simulator.c b/drivers/flash/flash_simulator.c index e9795d68440e..035db8883928 100644 --- a/drivers/flash/flash_simulator.c +++ b/drivers/flash/flash_simulator.c @@ -158,6 +158,8 @@ static uint8_t mock_flash[FLASH_SIMULATOR_FLASH_SIZE]; #endif #endif /* CONFIG_ARCH_POSIX */ +uint8_t prog_unit_buf[FLASH_SIMULATOR_PROG_UNIT]; + static DEVICE_API(flash, flash_sim_api); static const struct flash_parameters flash_sim_parameters = { @@ -217,7 +219,6 @@ static int flash_sim_read(const struct device *dev, const off_t offset, static int flash_sim_write(const struct device *dev, const off_t offset, const void *data, const size_t len) { - uint8_t buf[FLASH_SIMULATOR_PROG_UNIT]; ARG_UNUSED(dev); if (!flash_range_is_valid(dev, offset, len)) { @@ -233,12 +234,12 @@ static int flash_sim_write(const struct device *dev, const off_t offset, #if defined(CONFIG_FLASH_SIMULATOR_EXPLICIT_ERASE) /* check if any unit has been already programmed */ - memset(buf, FLASH_SIMULATOR_ERASE_VALUE, sizeof(buf)); + memset(prog_unit_buf, FLASH_SIMULATOR_ERASE_VALUE, sizeof(prog_unit_buf)); #else - memcpy(buf, MOCK_FLASH(offset), sizeof(buf)); + memcpy(prog_unit_buf, MOCK_FLASH(offset), sizeof(prog_unit_buf)); #endif for (uint32_t i = 0; i < len; i += FLASH_SIMULATOR_PROG_UNIT) { - if (memcmp(buf, MOCK_FLASH(offset + i), sizeof(buf))) { + if (memcmp(prog_unit_buf, MOCK_FLASH(offset + i), sizeof(prog_unit_buf))) { FLASH_SIM_STATS_INC(flash_sim_stats, double_writes); #if !CONFIG_FLASH_SIMULATOR_DOUBLE_WRITES return -EIO; From b196917f6c93fd7f4978623342cbd6a7b866da99 Mon Sep 17 00:00:00 2001 From: Biwen Li Date: Thu, 4 Dec 2025 16:19:02 +0900 Subject: [PATCH 0586/3659] tests: bluetooth: audio: ascs: fix build issues Fix build issues, - error: format %x expects argument of type unsigned int, but argument 7 has type ssize_t {aka long int} [-Werror=format=] zassert_false(ret < 0, "attr->read returned unexpected (err 0x%02x)" , BT_GATT_ERR(ret)); Signed-off-by: Biwen Li --- tests/bluetooth/audio/ascs/src/main.c | 3 ++- .../audio/ascs/src/test_ase_control_params.c | 2 +- .../src/test_ase_state_transition_invalid.c | 3 ++- tests/bluetooth/audio/ascs/src/test_common.c | 27 ++++++++++++------- 4 files changed, 23 insertions(+), 12 deletions(-) diff --git a/tests/bluetooth/audio/ascs/src/main.c b/tests/bluetooth/audio/ascs/src/main.c index 7da8c8fdd323..6d1e9ca5ecde 100644 --- a/tests/bluetooth/audio/ascs/src/main.c +++ b/tests/bluetooth/audio/ascs/src/main.c @@ -164,7 +164,8 @@ ZTEST_F(ascs_test_suite, test_sink_ase_read_state_idle) zexpect_not_null(fixture->ase_snk.attr); ret = ase->read(conn, ase, &hdr, sizeof(hdr), 0); - zassert_false(ret < 0, "attr->read returned unexpected (err 0x%02x)", BT_GATT_ERR(ret)); + zassert_false(ret < 0, "attr->read returned unexpected (err 0x%02x)", + (uint8_t)BT_GATT_ERR(ret)); zassert_equal(0x00, hdr.ase_state, "unexpected ASE_State 0x%02x", hdr.ase_state); } diff --git a/tests/bluetooth/audio/ascs/src/test_ase_control_params.c b/tests/bluetooth/audio/ascs/src/test_ase_control_params.c index f33f5893dca6..3706134d7288 100644 --- a/tests/bluetooth/audio/ascs/src/test_ase_control_params.c +++ b/tests/bluetooth/audio/ascs/src/test_ase_control_params.c @@ -111,7 +111,7 @@ ZTEST_F(test_ase_control_params, test_sink_ase_control_operation_zero_length_wri ret = fixture->ase_cp->write(&fixture->conn, fixture->ase_cp, (void *)buf, 0, 0, 0); zassert_true(ret < 0, "ase_cp_attr->write returned unexpected (err 0x%02x)", - BT_GATT_ERR(ret)); + (uint8_t)BT_GATT_ERR(ret)); } static void test_expect_unsupported_opcode(struct test_ase_control_params_fixture *fixture, diff --git a/tests/bluetooth/audio/ascs/src/test_ase_state_transition_invalid.c b/tests/bluetooth/audio/ascs/src/test_ase_state_transition_invalid.c index 300c18e150c2..55145d6cb2e0 100644 --- a/tests/bluetooth/audio/ascs/src/test_ase_state_transition_invalid.c +++ b/tests/bluetooth/audio/ascs/src/test_ase_state_transition_invalid.c @@ -375,7 +375,8 @@ static void expect_ase_state_releasing(struct bt_conn *conn, const struct bt_gat zexpect_not_null(ase); ret = ase->read(conn, ase, &hdr, sizeof(hdr), 0); - zassert_false(ret < 0, "attr->read returned unexpected (err 0x%02x)", BT_GATT_ERR(ret)); + zassert_false(ret < 0, "attr->read returned unexpected (err 0x%02x)", + (uint8_t)BT_GATT_ERR(ret)); zassert_equal(BT_BAP_EP_STATE_RELEASING, hdr.ase_state, "unexpected ASE_State 0x%02x", hdr.ase_state); } diff --git a/tests/bluetooth/audio/ascs/src/test_common.c b/tests/bluetooth/audio/ascs/src/test_common.c index 362107d5a15a..1c9a0cf56ebb 100644 --- a/tests/bluetooth/audio/ascs/src/test_common.c +++ b/tests/bluetooth/audio/ascs/src/test_common.c @@ -130,7 +130,8 @@ uint8_t test_ase_id_get(const struct bt_gatt_attr *ase) ssize_t ret; ret = ase->read(NULL, ase, &hdr, sizeof(hdr), 0); - zassert_false(ret < 0, "ase->read returned unexpected (err 0x%02x)", BT_GATT_ERR(ret)); + zassert_false(ret < 0, "ase->read returned unexpected (err 0x%02x)", + (uint8_t)BT_GATT_ERR(ret)); return hdr.ase_id; } @@ -177,7 +178,8 @@ void test_ase_control_client_config_codec(struct bt_conn *conn, uint8_t ase_id, mock_bap_unicast_server_cb_config_fake.custom_fake = unicast_server_cb_config_custom_fake; ret = attr->write(conn, attr, (void *)buf, sizeof(buf), 0, 0); - zassert_false(ret < 0, "cp_attr->write returned unexpected (err 0x%02x)", BT_GATT_ERR(ret)); + zassert_false(ret < 0, "cp_attr->write returned unexpected (err 0x%02x)", + (uint8_t)BT_GATT_ERR(ret)); stream_allocated = NULL; @@ -204,7 +206,8 @@ void test_ase_control_client_config_qos(struct bt_conn *conn, uint8_t ase_id) ssize_t ret; ret = attr->write(conn, attr, (void *)buf, sizeof(buf), 0, 0); - zassert_false(ret < 0, "attr->write returned unexpected (err 0x%02x)", BT_GATT_ERR(ret)); + zassert_false(ret < 0, "attr->write returned unexpected (err 0x%02x)", + (uint8_t)BT_GATT_ERR(ret)); test_drain_syswq(); /* Ensure that state transitions are completed */ } @@ -221,7 +224,8 @@ void test_ase_control_client_enable(struct bt_conn *conn, uint8_t ase_id) ssize_t ret; ret = attr->write(conn, attr, (void *)buf, sizeof(buf), 0, 0); - zassert_false(ret < 0, "attr->write returned unexpected (err 0x%02x)", BT_GATT_ERR(ret)); + zassert_false(ret < 0, "attr->write returned unexpected (err 0x%02x)", + (uint8_t)BT_GATT_ERR(ret)); test_drain_syswq(); /* Ensure that state transitions are completed */ } @@ -237,7 +241,8 @@ void test_ase_control_client_disable(struct bt_conn *conn, uint8_t ase_id) ssize_t ret; ret = attr->write(conn, attr, (void *)buf, sizeof(buf), 0, 0); - zassert_false(ret < 0, "attr->write returned unexpected (err 0x%02x)", BT_GATT_ERR(ret)); + zassert_false(ret < 0, "attr->write returned unexpected (err 0x%02x)", + (uint8_t)BT_GATT_ERR(ret)); test_drain_syswq(); /* Ensure that state transitions are completed */ } @@ -253,7 +258,8 @@ void test_ase_control_client_release(struct bt_conn *conn, uint8_t ase_id) ssize_t ret; ret = attr->write(conn, attr, (void *)buf, sizeof(buf), 0, 0); - zassert_false(ret < 0, "attr->write returned unexpected (err 0x%02x)", BT_GATT_ERR(ret)); + zassert_false(ret < 0, "attr->write returned unexpected (err 0x%02x)", + (uint8_t)BT_GATT_ERR(ret)); test_drain_syswq(); /* Ensure that state transitions are completed */ } @@ -271,7 +277,8 @@ void test_ase_control_client_update_metadata(struct bt_conn *conn, uint8_t ase_i ssize_t ret; ret = attr->write(conn, attr, (void *)buf, sizeof(buf), 0, 0); - zassert_false(ret < 0, "attr->write returned unexpected (err 0x%02x)", BT_GATT_ERR(ret)); + zassert_false(ret < 0, "attr->write returned unexpected (err 0x%02x)", + (uint8_t)BT_GATT_ERR(ret)); test_drain_syswq(); /* Ensure that state transitions are completed */ } @@ -287,7 +294,8 @@ void test_ase_control_client_receiver_start_ready(struct bt_conn *conn, uint8_t ssize_t ret; ret = attr->write(conn, attr, (void *)buf, sizeof(buf), 0, 0); - zassert_false(ret < 0, "attr->write returned unexpected (err 0x%02x)", BT_GATT_ERR(ret)); + zassert_false(ret < 0, "attr->write returned unexpected (err 0x%02x)", + (uint8_t)BT_GATT_ERR(ret)); test_drain_syswq(); /* Ensure that state transitions are completed */ } @@ -303,7 +311,8 @@ void test_ase_control_client_receiver_stop_ready(struct bt_conn *conn, uint8_t a ssize_t ret; ret = attr->write(conn, attr, (void *)buf, sizeof(buf), 0, 0); - zassert_false(ret < 0, "attr->write returned unexpected (err 0x%02x)", BT_GATT_ERR(ret)); + zassert_false(ret < 0, "attr->write returned unexpected (err 0x%02x)", + (uint8_t)BT_GATT_ERR(ret)); test_drain_syswq(); /* Ensure that state transitions are completed */ } From 2cf2f8c58ab929dd51f1e0712eb477fe5ce2f7af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fin=20Maa=C3=9F?= Date: Mon, 8 Dec 2025 11:21:53 +0100 Subject: [PATCH 0587/3659] drivers: ethernet: microchip_lan9250: use timeout directly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit use Kconfig timeout directly. Signed-off-by: Fin Maaß --- drivers/ethernet/eth_lan9250.c | 4 +--- drivers/ethernet/eth_lan9250_priv.h | 1 - 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/ethernet/eth_lan9250.c b/drivers/ethernet/eth_lan9250.c index c5f22edbad23..6821079fdd72 100644 --- a/drivers/ethernet/eth_lan9250.c +++ b/drivers/ethernet/eth_lan9250.c @@ -455,7 +455,6 @@ static int lan9250_read_buf(const struct device *dev, uint8_t *data_buffer, uint static int lan9250_rx(const struct device *dev) { - const struct lan9250_config *config = dev->config; struct lan9250_runtime *ctx = dev->data; const uint16_t buf_rx_size = CONFIG_NET_BUF_DATA_SIZE; struct net_pkt *pkt; @@ -487,7 +486,7 @@ static int lan9250_rx(const struct device *dev) /* Get the frame from the buffer */ pkt = net_pkt_rx_alloc_with_buffer(ctx->iface, pkt_len, NET_AF_UNSPEC, 0, - K_MSEC(config->timeout)); + K_MSEC(CONFIG_ETH_LAN9250_BUF_ALLOC_TIMEOUT)); if (!pkt) { LOG_ERR("%s: Could not allocate rx buffer", dev->name); eth_stats_update_errors_rx(ctx->iface); @@ -752,7 +751,6 @@ static int lan9250_init(const struct device *dev) .spi = SPI_DT_SPEC_INST_GET(inst, SPI_WORD_SET(8)), \ .interrupt = GPIO_DT_SPEC_INST_GET(inst, int_gpios), \ .reset = GPIO_DT_SPEC_INST_GET_OR(inst, reset_gpios, {0}), \ - .timeout = CONFIG_ETH_LAN9250_BUF_ALLOC_TIMEOUT, \ .mac_cfg = NET_ETH_MAC_DT_INST_CONFIG_INIT(inst), \ }; \ \ diff --git a/drivers/ethernet/eth_lan9250_priv.h b/drivers/ethernet/eth_lan9250_priv.h index 8e755c0239b9..4c80c1e8173f 100644 --- a/drivers/ethernet/eth_lan9250_priv.h +++ b/drivers/ethernet/eth_lan9250_priv.h @@ -311,7 +311,6 @@ struct lan9250_config { struct gpio_dt_spec interrupt; struct gpio_dt_spec reset; uint8_t full_duplex; - int32_t timeout; struct net_eth_mac_config mac_cfg; }; From f017a99f07674252c7f1e9d82b9bef6a94c0808b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fin=20Maa=C3=9F?= Date: Mon, 8 Dec 2025 11:22:28 +0100 Subject: [PATCH 0588/3659] drivers: ethernet: microchip_lan865x: use timeout directly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit use Kconfig timeout directly. Signed-off-by: Fin Maaß --- drivers/ethernet/eth_lan865x.c | 4 +--- drivers/ethernet/eth_lan865x_priv.h | 1 - 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/ethernet/eth_lan865x.c b/drivers/ethernet/eth_lan865x.c index 1d67f2125774..8162cf5b4022 100644 --- a/drivers/ethernet/eth_lan865x.c +++ b/drivers/ethernet/eth_lan865x.c @@ -285,13 +285,12 @@ static void lan865x_int_callback(const struct device *dev, struct gpio_callback static void lan865x_read_chunks(const struct device *dev) { - const struct lan865x_config *cfg = dev->config; struct lan865x_data *ctx = dev->data; struct oa_tc6 *tc6 = ctx->tc6; struct net_pkt *pkt; int ret; - pkt = net_pkt_rx_alloc(K_MSEC(cfg->timeout)); + pkt = net_pkt_rx_alloc(K_MSEC(CONFIG_ETH_LAN865X_TIMEOUT)); if (!pkt) { LOG_ERR("OA RX: Could not allocate packet!"); return; @@ -479,7 +478,6 @@ static const struct ethernet_api lan865x_api_func = { .spi = SPI_DT_SPEC_INST_GET(inst, SPI_WORD_SET(8)), \ .interrupt = GPIO_DT_SPEC_INST_GET(inst, int_gpios), \ .reset = GPIO_DT_SPEC_INST_GET(inst, rst_gpios), \ - .timeout = CONFIG_ETH_LAN865X_TIMEOUT, \ .phy = DEVICE_DT_GET( \ DT_CHILD(DT_INST_CHILD(inst, lan865x_mdio), ethernet_phy_##inst)), \ .mac_cfg = NET_ETH_MAC_DT_INST_CONFIG_INIT(inst), \ diff --git a/drivers/ethernet/eth_lan865x_priv.h b/drivers/ethernet/eth_lan865x_priv.h index 1b22b1b9e6f3..a92f8bd93e6e 100644 --- a/drivers/ethernet/eth_lan865x_priv.h +++ b/drivers/ethernet/eth_lan865x_priv.h @@ -50,7 +50,6 @@ struct lan865x_config { struct spi_dt_spec spi; struct gpio_dt_spec interrupt; struct gpio_dt_spec reset; - int32_t timeout; struct net_eth_mac_config mac_cfg; /* MAC */ From a7d48d94b43fc74733ed69eff36c28f2c9037be0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fin=20Maa=C3=9F?= Date: Mon, 8 Dec 2025 11:23:20 +0100 Subject: [PATCH 0589/3659] drivers: ethernet: microchip_enc28j60: use timeout directly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit use Kconfig timeout directly. Signed-off-by: Fin Maaß --- drivers/ethernet/eth_enc28j60.c | 6 ++---- drivers/ethernet/eth_enc28j60_priv.h | 1 - 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/ethernet/eth_enc28j60.c b/drivers/ethernet/eth_enc28j60.c index 6383f0aa665d..eca03502d841 100644 --- a/drivers/ethernet/eth_enc28j60.c +++ b/drivers/ethernet/eth_enc28j60.c @@ -550,7 +550,6 @@ static int eth_enc28j60_tx(const struct device *dev, struct net_pkt *pkt) static void enc28j60_read_packet(const struct device *dev, uint16_t frm_len) { - const struct eth_enc28j60_config *config = dev->config; struct eth_enc28j60_runtime *context = dev->data; struct net_buf *pkt_buf; struct net_pkt *pkt; @@ -558,8 +557,8 @@ static void enc28j60_read_packet(const struct device *dev, uint16_t frm_len) uint8_t dummy[4]; /* Get the frame from the buffer */ - pkt = net_pkt_rx_alloc_with_buffer(get_iface(context), frm_len, - NET_AF_UNSPEC, 0, K_MSEC(config->timeout)); + pkt = net_pkt_rx_alloc_with_buffer(get_iface(context), frm_len, NET_AF_UNSPEC, 0, + K_MSEC(CONFIG_ETH_ENC28J60_TIMEOUT)); if (!pkt) { LOG_ERR("%s: Could not allocate rx buffer", dev->name); eth_stats_update_errors_rx(get_iface(context)); @@ -917,7 +916,6 @@ static int eth_enc28j60_init(const struct device *dev) .spi = SPI_DT_SPEC_INST_GET(inst, SPI_WORD_SET(8)), \ .interrupt = GPIO_DT_SPEC_INST_GET(inst, int_gpios), \ .full_duplex = DT_INST_PROP(0, full_duplex), \ - .timeout = CONFIG_ETH_ENC28J60_TIMEOUT, \ .hw_rx_filter = DT_INST_PROP_OR(inst, hw_rx_filter, ENC28J60_RECEIVE_FILTERS), \ .random_mac = DT_INST_PROP(inst, zephyr_random_mac_address), \ }; \ diff --git a/drivers/ethernet/eth_enc28j60_priv.h b/drivers/ethernet/eth_enc28j60_priv.h index 2f2eb4ffb5d6..98ad07217cc7 100644 --- a/drivers/ethernet/eth_enc28j60_priv.h +++ b/drivers/ethernet/eth_enc28j60_priv.h @@ -223,7 +223,6 @@ struct eth_enc28j60_config { struct spi_dt_spec spi; struct gpio_dt_spec interrupt; uint8_t full_duplex; - int32_t timeout; uint8_t hw_rx_filter; bool random_mac; }; From 97a2d6bc479d57c905ba6f7db479cea4eb10fd91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fin=20Maa=C3=9F?= Date: Mon, 8 Dec 2025 11:23:44 +0100 Subject: [PATCH 0590/3659] drivers: ethernet: microchip_enc424j600: use timeout directly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit use Kconfig timeout directly. Signed-off-by: Fin Maaß --- drivers/ethernet/eth_enc424j600.c | 7 ++----- drivers/ethernet/eth_enc424j600_priv.h | 1 - 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/ethernet/eth_enc424j600.c b/drivers/ethernet/eth_enc424j600.c index 14fb048aff6e..80e870e1cafd 100644 --- a/drivers/ethernet/eth_enc424j600.c +++ b/drivers/ethernet/eth_enc424j600.c @@ -347,7 +347,6 @@ static int enc424j600_tx(const struct device *dev, struct net_pkt *pkt) static int enc424j600_rx(const struct device *dev) { struct enc424j600_runtime *context = dev->data; - const struct enc424j600_config *config = dev->config; uint8_t info[ENC424J600_RSV_SIZE + ENC424J600_PTR_NXP_PKT_SIZE]; struct net_buf *pkt_buf = NULL; struct net_pkt *pkt; @@ -386,9 +385,8 @@ static int enc424j600_rx(const struct device *dev) } /* Get the frame from the buffer */ - pkt = net_pkt_rx_alloc_with_buffer(context->iface, frm_len, - NET_AF_UNSPEC, 0, - K_MSEC(config->timeout)); + pkt = net_pkt_rx_alloc_with_buffer(context->iface, frm_len, NET_AF_UNSPEC, 0, + K_MSEC(CONFIG_ETH_ENC424J600_TIMEOUT)); if (!pkt) { LOG_ERR("Could not allocate rx buffer"); eth_stats_update_errors_rx(context->iface); @@ -780,7 +778,6 @@ static struct enc424j600_runtime enc424j600_0_runtime = { static const struct enc424j600_config enc424j600_0_config = { .spi = SPI_DT_SPEC_INST_GET(0, SPI_WORD_SET(8)), .interrupt = GPIO_DT_SPEC_INST_GET(0, int_gpios), - .timeout = CONFIG_ETH_ENC424J600_TIMEOUT, }; ETH_NET_DEVICE_DT_INST_DEFINE(0, diff --git a/drivers/ethernet/eth_enc424j600_priv.h b/drivers/ethernet/eth_enc424j600_priv.h index 02f544c1eda9..5a468935ec89 100644 --- a/drivers/ethernet/eth_enc424j600_priv.h +++ b/drivers/ethernet/eth_enc424j600_priv.h @@ -277,7 +277,6 @@ struct enc424j600_config { struct spi_dt_spec spi; struct gpio_dt_spec interrupt; uint8_t full_duplex; - int32_t timeout; }; struct enc424j600_runtime { From ccdc0c3007693fb6f992124d7f8e7998c9de304f Mon Sep 17 00:00:00 2001 From: Qingsong Gou Date: Thu, 11 Dec 2025 08:30:53 +0800 Subject: [PATCH 0591/3659] drivers: adc: sf32lb: add adc read_async support Add adc read_async support for sf32lb Signed-off-by: Qingsong Gou --- drivers/adc/adc_sf32lb.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/drivers/adc/adc_sf32lb.c b/drivers/adc/adc_sf32lb.c index 1f092d96df90..bc5ae60163c0 100644 --- a/drivers/adc/adc_sf32lb.c +++ b/drivers/adc/adc_sf32lb.c @@ -213,9 +213,41 @@ static int adc_sf32lb_read(const struct device *dev, const struct adc_sequence * return error; } +static int adc_sf32lb_read_async(const struct device *dev, + const struct adc_sequence *sequence, + struct k_poll_signal *async) +{ + struct adc_sf32lb_data *data = dev->data; + int error; + + if (sequence->resolution != 12U) { + LOG_ERR("Resolution %d is not supported", sequence->resolution); + return -ENOTSUP; + } + + if (sequence->oversampling) { + LOG_ERR("Oversampling is not supported"); + return -ENOTSUP; + } + + if (sequence->calibrate) { + LOG_ERR("Calibration is not supported"); + return -ENOTSUP; + } + + adc_context_lock(&data->ctx, true, async); + error = start_read(dev, sequence); + adc_context_release(&data->ctx, error); + + return error; +} + static DEVICE_API(adc, adc_sf32lb_driver_api) = { .channel_setup = adc_sf32lb_channel_setup, .read = adc_sf32lb_read, +#ifdef CONFIG_ADC_ASYNC + .read_async = adc_sf32lb_read_async, +#endif .ref_internal = ADC_SF32LB_DEFAULT_VREF_INTERNAL, }; From df3823b8121e58737da09d137f0af7bdfc986b41 Mon Sep 17 00:00:00 2001 From: Albort Xue Date: Mon, 15 Dec 2025 16:43:07 +0800 Subject: [PATCH 0592/3659] samples: drivers: spi_flash: Add supports of flexspi_nor Added supports of nxp_imx_flexspi_nor flash. Signed-off-by: Albort Xue --- samples/drivers/spi_flash/src/main.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/samples/drivers/spi_flash/src/main.c b/samples/drivers/spi_flash/src/main.c index c7034245039f..b8721386af00 100644 --- a/samples/drivers/spi_flash/src/main.c +++ b/samples/drivers/spi_flash/src/main.c @@ -65,6 +65,8 @@ #define SPI_FLASH_COMPAT renesas_rz_qspi_spibsc #elif DT_HAS_COMPAT_STATUS_OKAY(nxp_xspi_nor) #define SPI_FLASH_COMPAT nxp_xspi_nor +#elif DT_HAS_COMPAT_STATUS_OKAY(nxp_imx_flexspi_nor) +#define SPI_FLASH_COMPAT nxp_imx_flexspi_nor #else #define SPI_FLASH_COMPAT invalid #endif From 8401bcfb7a169dcde955aef797a25fe2950a3255 Mon Sep 17 00:00:00 2001 From: Ederson de Souza Date: Tue, 9 Dec 2025 10:32:57 -0800 Subject: [PATCH 0593/3659] subsys/pmci/mctp: Fix I2C-GPIO target reading State machine handling RX data wasn't transitioning to "receive" mode. Signed-off-by: Ederson de Souza --- subsys/pmci/mctp/mctp_i2c_gpio_target.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/subsys/pmci/mctp/mctp_i2c_gpio_target.c b/subsys/pmci/mctp/mctp_i2c_gpio_target.c index bd3525e223df..876e5be5fbf3 100644 --- a/subsys/pmci/mctp/mctp_i2c_gpio_target.c +++ b/subsys/pmci/mctp/mctp_i2c_gpio_target.c @@ -45,6 +45,8 @@ int mctp_i2c_gpio_target_write_received(struct i2c_target_config *config, uint8_ case MCTP_I2C_GPIO_RX_MSG_LEN_ADDR: b->rxtx = true; b->rx_pkt = mctp_pktbuf_alloc(&b->binding, (size_t)val); + /* Reset state machine to wait for next register */ + b->reg_addr = MCTP_I2C_GPIO_INVALID_ADDR; break; case MCTP_I2C_GPIO_RX_MSG_ADDR: b->rxtx = true; From 0cdf8694e0ccde599ca45e354849d64ee4e46f78 Mon Sep 17 00:00:00 2001 From: Ederson de Souza Date: Mon, 15 Dec 2025 13:28:02 -0800 Subject: [PATCH 0594/3659] subsys/pmci/mctp: I2C-GPIO controller interrupt fix MCTP I2C-GPIO controller wasn't properly reenabling interrupt on the GPIO line after disabling it during transfer. This patch also uses `GPIO_INT_LEVEL_ACTIVE` instead of `GPIO_INT_LEVEL_HIGH` to respect GPIO active state. Signed-off-by: Ederson de Souza --- subsys/pmci/mctp/mctp_i2c_gpio_controller.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/subsys/pmci/mctp/mctp_i2c_gpio_controller.c b/subsys/pmci/mctp/mctp_i2c_gpio_controller.c index fe2653efc13e..0a7f13b2fae1 100644 --- a/subsys/pmci/mctp/mctp_i2c_gpio_controller.c +++ b/subsys/pmci/mctp/mctp_i2c_gpio_controller.c @@ -43,7 +43,7 @@ static void rx_completion(struct rtio *r, const struct rtio_sqe *sqe, int result struct mctp_i2c_gpio_controller_cb *cb = b->inflight_rx; /* Re-enable the GPIO interrupt */ - gpio_pin_interrupt_configure_dt(&b->endpoint_gpios[cb->index], GPIO_INT_ENABLE); + gpio_pin_interrupt_configure_dt(&b->endpoint_gpios[cb->index], GPIO_INT_LEVEL_ACTIVE); /* Try and start the next transfer if one is pending */ mctp_start_rx(b, true); @@ -232,7 +232,7 @@ int mctp_i2c_gpio_controller_start(struct mctp_binding *binding) mctp_binding_set_tx_enabled(binding, true); for (int i = 0; i < b->num_endpoints; i++) { - gpio_pin_interrupt_configure_dt(&b->endpoint_gpios[i], GPIO_INT_LEVEL_HIGH); + gpio_pin_interrupt_configure_dt(&b->endpoint_gpios[i], GPIO_INT_LEVEL_ACTIVE); } LOG_DBG("started"); From 5f5e17e08ca427949bba14bfd8b2218bd5cbb3f9 Mon Sep 17 00:00:00 2001 From: Ederson de Souza Date: Mon, 15 Dec 2025 13:40:26 -0800 Subject: [PATCH 0595/3659] samples/subsys/pmci/mctp: Set allocation functions on I2C samples Without those, allocation for MCTP packets can cause subtle - or not so subtle - bugs. Signed-off-by: Ederson de Souza --- samples/subsys/pmci/mctp/i2c_gpio_bus_endpoint/src/main.c | 1 + samples/subsys/pmci/mctp/i2c_gpio_bus_owner/src/main.c | 1 + 2 files changed, 2 insertions(+) diff --git a/samples/subsys/pmci/mctp/i2c_gpio_bus_endpoint/src/main.c b/samples/subsys/pmci/mctp/i2c_gpio_bus_endpoint/src/main.c index 8fa84cb93fe5..c82bca0ac118 100644 --- a/samples/subsys/pmci/mctp/i2c_gpio_bus_endpoint/src/main.c +++ b/samples/subsys/pmci/mctp/i2c_gpio_bus_endpoint/src/main.c @@ -33,6 +33,7 @@ int main(void) LOG_INF("MCTP Host EID:%d on %s\n", mctp_i2c_ctrl.endpoint_id, CONFIG_BOARD_TARGET); + mctp_set_alloc_ops(malloc, free, realloc); mctp_ctx = mctp_init(); __ASSERT_NO_MSG(mctp_ctx != NULL); mctp_register_bus(mctp_ctx, &mctp_i2c_ctrl.binding, mctp_i2c_ctrl.endpoint_id); diff --git a/samples/subsys/pmci/mctp/i2c_gpio_bus_owner/src/main.c b/samples/subsys/pmci/mctp/i2c_gpio_bus_owner/src/main.c index 1280773563af..8b4260277ac9 100644 --- a/samples/subsys/pmci/mctp/i2c_gpio_bus_owner/src/main.c +++ b/samples/subsys/pmci/mctp/i2c_gpio_bus_owner/src/main.c @@ -33,6 +33,7 @@ int main(void) LOG_INF("MCTP Host EID:%d on %s\n", LOCAL_EID, CONFIG_BOARD_TARGET); + mctp_set_alloc_ops(malloc, free, realloc); mctp_ctx = mctp_init(); __ASSERT_NO_MSG(mctp_ctx != NULL); mctp_register_bus(mctp_ctx, &mctp_i2c_ctrl.binding, LOCAL_EID); From b9f10bec523e828366cb9db3c2ec1664fafb1bda Mon Sep 17 00:00:00 2001 From: Ederson de Souza Date: Mon, 15 Dec 2025 13:42:17 -0800 Subject: [PATCH 0596/3659] samples/subsys/pmci/mctp: More friendly I2C-GPIO samples messages This is done by: - No more sending periodic messages from endpoint to owner - keep parity with UART sample: owner sends periodic ping to endpoint, that replies to those; - Waiting one second between each message sent by the owner, so people can actually see what's going on; - Wrapping the content of the messages (strings "ping" and "pong") in quotes, so it's clear what they are; - Toning down the logging to INF - no need for DBG. Signed-off-by: Ederson de Souza --- .../pmci/mctp/i2c_gpio_bus_endpoint/prj.conf | 2 -- .../mctp/i2c_gpio_bus_endpoint/src/main.c | 28 +++++++++---------- .../pmci/mctp/i2c_gpio_bus_owner/prj.conf | 2 -- .../pmci/mctp/i2c_gpio_bus_owner/src/main.c | 6 ++-- 4 files changed, 17 insertions(+), 21 deletions(-) diff --git a/samples/subsys/pmci/mctp/i2c_gpio_bus_endpoint/prj.conf b/samples/subsys/pmci/mctp/i2c_gpio_bus_endpoint/prj.conf index 77886465f539..e339194ba67a 100644 --- a/samples/subsys/pmci/mctp/i2c_gpio_bus_endpoint/prj.conf +++ b/samples/subsys/pmci/mctp/i2c_gpio_bus_endpoint/prj.conf @@ -2,7 +2,5 @@ CONFIG_I2C=y CONFIG_I2C_TARGET=y CONFIG_MCTP=y CONFIG_MCTP_I2C_GPIO_TARGET=y -CONFIG_MCTP_LOG_LEVEL_DBG=y CONFIG_LOG=y -#CONFIG_LOG_MODE_IMMEDIATE=y CONFIG_LOG_BUFFER_SIZE=4096 diff --git a/samples/subsys/pmci/mctp/i2c_gpio_bus_endpoint/src/main.c b/samples/subsys/pmci/mctp/i2c_gpio_bus_endpoint/src/main.c index c82bca0ac118..abe6e6ffe40d 100644 --- a/samples/subsys/pmci/mctp/i2c_gpio_bus_endpoint/src/main.c +++ b/samples/subsys/pmci/mctp/i2c_gpio_bus_endpoint/src/main.c @@ -17,20 +17,26 @@ LOG_MODULE_REGISTER(mctp_i2c_gpio_bus_endpoint); MCTP_I2C_GPIO_TARGET_DT_DEFINE(mctp_i2c_ctrl, DT_NODELABEL(mctp_i2c)); +K_SEM_DEFINE(mctp_rx, 0, 1); + +struct mctp *mctp_ctx; + +#define BUS_OWNER_ID 20 + static void rx_message(uint8_t eid, bool tag_owner, uint8_t msg_tag, void *data, void *msg, size_t len) { - LOG_INF("received message \"%s\" from endpoint %d, msg_tag %d, len %zu", (char *)msg, eid, - msg_tag, len); + LOG_INF("received message \"%s\" from endpoint %d, replying with \"pong\"", (char *)msg, + eid); + + mctp_message_tx(mctp_ctx, BUS_OWNER_ID, false, 0, "pong", sizeof("pong")); + + k_sem_give(&mctp_rx); } -#define BUS_OWNER_ID 20 int main(void) { - int rc; - struct mctp *mctp_ctx; - LOG_INF("MCTP Host EID:%d on %s\n", mctp_i2c_ctrl.endpoint_id, CONFIG_BOARD_TARGET); mctp_set_alloc_ops(malloc, free, realloc); @@ -40,16 +46,10 @@ int main(void) mctp_set_rx_all(mctp_ctx, rx_message, NULL); /* - * 1. MCTP poll loop, send "ping" to each endpoint and get "pong" back - * 2. Then send a broadcast "hello" to each endpoint and get a "from endoint %d" back + * MCTP poll loop, listening for messages. */ while (true) { - rc = mctp_message_tx(mctp_ctx, BUS_OWNER_ID, false, - 0, "ping", sizeof("ping")); - if (rc != 0) { - LOG_WRN("Failed to send message \"ping\", errno %d\n", rc); - } - k_msleep(500); + k_sem_take(&mctp_rx, K_FOREVER); } return 0; diff --git a/samples/subsys/pmci/mctp/i2c_gpio_bus_owner/prj.conf b/samples/subsys/pmci/mctp/i2c_gpio_bus_owner/prj.conf index 26fc84e775b2..640be169dee6 100644 --- a/samples/subsys/pmci/mctp/i2c_gpio_bus_owner/prj.conf +++ b/samples/subsys/pmci/mctp/i2c_gpio_bus_owner/prj.conf @@ -1,9 +1,7 @@ -# nothing here CONFIG_I2C=y CONFIG_I2C_MCUX_LPI2C_BUS_RECOVERY=y CONFIG_I2C_RTIO=y CONFIG_MCTP=y CONFIG_MCTP_I2C_GPIO_CONTROLLER=y -CONFIG_MCTP_LOG_LEVEL_DBG=y CONFIG_LOG=y CONFIG_LOG_BUFFER_SIZE=4096 diff --git a/samples/subsys/pmci/mctp/i2c_gpio_bus_owner/src/main.c b/samples/subsys/pmci/mctp/i2c_gpio_bus_owner/src/main.c index 8b4260277ac9..9cf13d01479d 100644 --- a/samples/subsys/pmci/mctp/i2c_gpio_bus_owner/src/main.c +++ b/samples/subsys/pmci/mctp/i2c_gpio_bus_owner/src/main.c @@ -22,8 +22,8 @@ MCTP_I2C_GPIO_CONTROLLER_DT_DEFINE(mctp_i2c_ctrl, DT_NODELABEL(mctp_i2c)); static void rx_message(uint8_t eid, bool tag_owner, uint8_t msg_tag, void *data, void *msg, size_t len) { - LOG_INF("received message %s from endpoint %d to %d, msg_tag %d, len %zu", (char *)msg, eid, - LOCAL_EID, msg_tag, len); + LOG_INF("received message \"%s\" from endpoint %d to %d, msg_tag %d, len %zu", (char *)msg, + eid, LOCAL_EID, msg_tag, len); } int main(void) @@ -51,7 +51,7 @@ int main(void) " errno %d\n", mctp_i2c_ctrl.endpoint_ids[i], rc); } - k_msleep(500); + k_msleep(1000); } } From 621a7aa686bdd3316d217cec36c8372db01769b3 Mon Sep 17 00:00:00 2001 From: Ederson de Souza Date: Mon, 15 Dec 2025 13:53:33 -0800 Subject: [PATCH 0597/3659] samples/subsys/pmci/mctp: Keep board specific config on board file So that users of other boards don't see meaningless warnings during build. Signed-off-by: Ederson de Souza --- .../i2c_gpio_bus_owner/boards/frdm_mcxn947_mcxn947_cpu0.conf | 1 + samples/subsys/pmci/mctp/i2c_gpio_bus_owner/prj.conf | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 samples/subsys/pmci/mctp/i2c_gpio_bus_owner/boards/frdm_mcxn947_mcxn947_cpu0.conf diff --git a/samples/subsys/pmci/mctp/i2c_gpio_bus_owner/boards/frdm_mcxn947_mcxn947_cpu0.conf b/samples/subsys/pmci/mctp/i2c_gpio_bus_owner/boards/frdm_mcxn947_mcxn947_cpu0.conf new file mode 100644 index 000000000000..cff6533bca48 --- /dev/null +++ b/samples/subsys/pmci/mctp/i2c_gpio_bus_owner/boards/frdm_mcxn947_mcxn947_cpu0.conf @@ -0,0 +1 @@ +CONFIG_I2C_MCUX_LPI2C_BUS_RECOVERY=y diff --git a/samples/subsys/pmci/mctp/i2c_gpio_bus_owner/prj.conf b/samples/subsys/pmci/mctp/i2c_gpio_bus_owner/prj.conf index 640be169dee6..88b04bef98c7 100644 --- a/samples/subsys/pmci/mctp/i2c_gpio_bus_owner/prj.conf +++ b/samples/subsys/pmci/mctp/i2c_gpio_bus_owner/prj.conf @@ -1,5 +1,4 @@ CONFIG_I2C=y -CONFIG_I2C_MCUX_LPI2C_BUS_RECOVERY=y CONFIG_I2C_RTIO=y CONFIG_MCTP=y CONFIG_MCTP_I2C_GPIO_CONTROLLER=y From ace1b87e153b08e69f4acddd9009c4427aba9d1c Mon Sep 17 00:00:00 2001 From: Ederson de Souza Date: Mon, 15 Dec 2025 14:01:19 -0800 Subject: [PATCH 0598/3659] samples/subsys/pmci/mctp: Add npcx4m8f_evb overlays for I2C-GPIO So that one can run the I2C-GPIO owner/endpoint samples on it. Signed-off-by: Ederson de Souza --- .../boards/npcx4m8f_evb.overlay | 18 ++++++++++++++++++ .../boards/npcx4m8f_evb.overlay | 18 ++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 samples/subsys/pmci/mctp/i2c_gpio_bus_endpoint/boards/npcx4m8f_evb.overlay create mode 100644 samples/subsys/pmci/mctp/i2c_gpio_bus_owner/boards/npcx4m8f_evb.overlay diff --git a/samples/subsys/pmci/mctp/i2c_gpio_bus_endpoint/boards/npcx4m8f_evb.overlay b/samples/subsys/pmci/mctp/i2c_gpio_bus_endpoint/boards/npcx4m8f_evb.overlay new file mode 100644 index 000000000000..c6a878731376 --- /dev/null +++ b/samples/subsys/pmci/mctp/i2c_gpio_bus_endpoint/boards/npcx4m8f_evb.overlay @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2025 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + /* SDA J18.2 */ + /* SCL J18.1 */ + /* GPIO J17.2 */ + mctp_i2c: mctp_i2c { + compatible = "zephyr,mctp-i2c-gpio-target"; + i2c = <&i2c0_0>; + i2c-addr = <70>; + endpoint-id = <11>; + endpoint-gpios = <&gpio4 3 GPIO_ACTIVE_HIGH>; + }; +}; diff --git a/samples/subsys/pmci/mctp/i2c_gpio_bus_owner/boards/npcx4m8f_evb.overlay b/samples/subsys/pmci/mctp/i2c_gpio_bus_owner/boards/npcx4m8f_evb.overlay new file mode 100644 index 000000000000..2973ea615fae --- /dev/null +++ b/samples/subsys/pmci/mctp/i2c_gpio_bus_owner/boards/npcx4m8f_evb.overlay @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2025 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + /* SDA J18.2 */ + /* SCL J18.1 */ + /* GPIO J17.2 */ + mctp_i2c: mctp_i2c { + compatible = "zephyr,mctp-i2c-gpio-controller"; + i2c = <&i2c0_0>; + endpoint-ids = <11>; + endpoint-addrs = <70>; + endpoint-gpios = <&gpio4 3 GPIO_ACTIVE_HIGH>; + }; +}; From da5755f893c585600440bb9e17b9ae79dac98b4b Mon Sep 17 00:00:00 2001 From: Andrej Butok Date: Tue, 16 Dec 2025 10:41:13 +0100 Subject: [PATCH 0599/3659] MAINTAINERS: add butok collaborator for NXP drivers Add butok (Andrej Butok) as a collaborator for "NXP Platform Drivers". Signed-off-by: Andrej Butok --- MAINTAINERS.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index ba4406d966f1..cd43332449bc 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -3493,6 +3493,7 @@ NXP Platform Drivers: - dbaluta - Holt-Sun - zejiang0jason + - butok files-regex: - ^drivers/.*nxp.* - ^drivers/.*mcux.* From 510e4d1ceef052b277f8750547291b2725cf9ce9 Mon Sep 17 00:00:00 2001 From: William Tang Date: Tue, 16 Dec 2025 13:54:11 +0800 Subject: [PATCH 0600/3659] soc: nxp: rw: fix GAU clock configuration for ADC accuracy Configure the GAU (General Analog Unit) clock from T3 PLL 256M with a divider of 4 to achieve 64MHz, replacing the previous configuration that used the main clock at 260MHz main clock with a divider of 1. The GAU ADC has a maximum clock frequency limit of 64MHz. The previous 260MHz clock configuration caused incorrect conversion results when operating at 12-bit and 14-bit resolutions. Using the T3 PLL 256M source divided by 4 provides the correct 64MHz clock frequency. This change also corrects a typo in the comment from "Attack clock" to "Set 64M GAU clock from T3 PLL 256M and reset". Signed-off-by: William Tang --- soc/nxp/rw/soc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/soc/nxp/rw/soc.c b/soc/nxp/rw/soc.c index 428622433208..902874d47825 100644 --- a/soc/nxp/rw/soc.c +++ b/soc/nxp/rw/soc.c @@ -149,9 +149,9 @@ __weak __ramfunc void clock_init(void) #if defined(CONFIG_ADC_MCUX_GAU) || defined(CONFIG_DAC_MCUX_GAU) || \ defined(CONFIG_COMPARATOR_NXP_ACOMP) - /* Attack clock for GAU and reset */ - CLOCK_AttachClk(kMAIN_CLK_to_GAU_CLK); - CLOCK_SetClkDiv(kCLOCK_DivGauClk, 1U); + /* Set 64M GAU clock from T3 PLL 256M and reset */ + CLOCK_AttachClk(kT3PLL_MCI_256M_to_GAU_CLK); + CLOCK_SetClkDiv(kCLOCK_DivGauClk, 4U); CLOCK_EnableClock(kCLOCK_Gau); RESET_PeripheralReset(kGAU_RST_SHIFT_RSTn); GAU_BG->CTRL &= ~BG_CTRL_PD_MASK; From aaf36d65b50614d21ad5cc09cf432332f2693380 Mon Sep 17 00:00:00 2001 From: Qingsong Gou Date: Tue, 25 Nov 2025 12:35:29 +0800 Subject: [PATCH 0601/3659] drivers: spi: sf32lb: add spi_sf32lb_transceive_async async API Add spi async API support for sf32lb Signed-off-by: Qingsong Gou --- drivers/spi/spi_sf32lb.c | 139 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 138 insertions(+), 1 deletion(-) diff --git a/drivers/spi/spi_sf32lb.c b/drivers/spi/spi_sf32lb.c index 3464bce39bab..87364d13f8c6 100644 --- a/drivers/spi/spi_sf32lb.c +++ b/drivers/spi/spi_sf32lb.c @@ -28,6 +28,9 @@ struct spi_sf32lb_config { uintptr_t base; struct sf32lb_clock_dt_spec clock; const struct pinctrl_dev_config *pcfg; +#ifdef CONFIG_SPI_ASYNC + void (*irq_config_func)(void); +#endif }; struct spi_sf32lb_data { @@ -39,6 +42,71 @@ static bool spi_sf32lb_transfer_ongoing(struct spi_sf32lb_data *data) return spi_context_tx_on(&data->ctx) || spi_context_rx_on(&data->ctx); } +#ifdef CONFIG_SPI_ASYNC +void spi_sf32lb_complete(const struct device *dev, int status) +{ + const struct spi_sf32lb_config *cfg = dev->config; + struct spi_sf32lb_data *data = dev->data; + + sys_set_bits(cfg->base + SPI_STATUS, SPI_STATUS_ROR | SPI_STATUS_TUR); + + sys_clear_bits(cfg->base + SPI_INTE, SPI_INTE_RIE | SPI_INTE_TIE); + + spi_context_complete(&data->ctx, dev, status); +} + +static void spi_sf32lb_isr(const struct device *dev) +{ + const struct spi_sf32lb_config *cfg = dev->config; + struct spi_sf32lb_data *data = dev->data; + struct spi_context *ctx = &data->ctx; + uint32_t status = sys_read32(cfg->base + SPI_STATUS); + uint16_t tx_frame, rx_frame; + uint8_t word_size = SPI_WORD_SIZE_GET(ctx->config->operation); + + if (status & (SPI_STATUS_ROR | SPI_STATUS_TUR)) { + spi_sf32lb_complete(dev, -EIO); + return; + } + + if (IS_BIT_SET(status, SPI_STATUS_RFS_Pos) && spi_context_rx_buf_on(ctx)) { + if (word_size == 8) { + rx_frame = sys_read8(cfg->base + SPI_DATA); + UNALIGNED_PUT(rx_frame, (uint8_t *)data->ctx.rx_buf); + spi_context_update_rx(ctx, 1, 1); + } else { + rx_frame = sys_read32(cfg->base + SPI_DATA); + UNALIGNED_PUT(rx_frame, (uint16_t *)data->ctx.rx_buf); + spi_context_update_rx(ctx, 2, 1); + } + + if (!spi_context_rx_buf_on(ctx)) { + sys_clear_bit(cfg->base + SPI_INTE, SPI_INTE_RIE_Pos); + } + } + + if (IS_BIT_SET(status, SPI_STATUS_TNF_Pos) && spi_context_tx_buf_on(ctx)) { + if (word_size == 8) { + tx_frame = UNALIGNED_GET((uint8_t *)(data->ctx.tx_buf)); + sys_write8(tx_frame, cfg->base + SPI_DATA); + spi_context_update_tx(ctx, 1, 1); + } else { + tx_frame = UNALIGNED_GET((uint16_t *)(data->ctx.tx_buf)); + sys_write32(tx_frame, cfg->base + SPI_DATA); + spi_context_update_tx(ctx, 2, 1); + } + + if (!spi_context_tx_buf_on(ctx)) { + sys_clear_bit(cfg->base + SPI_INTE, SPI_INTE_TIE_Pos); + } + } + + if (!spi_sf32lb_transfer_ongoing(data)) { + spi_sf32lb_complete(dev, 0); + } +} +#endif + static int spi_sf32lb_configure(const struct device *dev, const struct spi_config *config) { const struct spi_sf32lb_config *cfg = dev->config; @@ -194,6 +262,58 @@ static int spi_sf32lb_transceive(const struct device *dev, const struct spi_conf return ret; } +static int spi_sf32lb_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) +{ + const struct spi_sf32lb_config *cfg = dev->config; + struct spi_sf32lb_data *data = dev->data; + uint8_t dfs; + int ret; + + spi_context_lock(&data->ctx, true, cb, userdata, config); + + ret = spi_sf32lb_configure(dev, config); + if (ret < 0) { + spi_context_release(&data->ctx, ret); + return ret; + } + + dfs = SPI_WORD_SIZE_GET(config->operation) >> 3; + spi_context_buffers_setup(&data->ctx, tx_bufs, rx_bufs, dfs); + spi_context_cs_control(&data->ctx, true); + + sys_set_bits(cfg->base + SPI_STATUS, SPI_STATUS_ROR | SPI_STATUS_TUR); + + sys_clear_bits(cfg->base + SPI_INTE, SPI_INTE_RIE | SPI_INTE_TIE); + + if (spi_context_tx_buf_on(&data->ctx)) { + sys_set_bit(cfg->base + SPI_INTE, SPI_INTE_TIE_Pos); + } + if (spi_context_rx_buf_on(&data->ctx)) { + sys_set_bit(cfg->base + SPI_INTE, SPI_INTE_RIE_Pos); + } + + /* Enable error interrupt */ + sys_set_bit(cfg->base + SPI_INTE, SPI_INTE_TINTE_Pos); + + /* Enable SPI peripheral if not already enabled */ + if (!sys_test_bit(cfg->base + SPI_TOP_CTRL, SPI_TOP_CTRL_SSE_Pos)) { + sys_set_bit(cfg->base + SPI_TOP_CTRL, SPI_TOP_CTRL_SSE_Pos); + } + + ret = spi_context_wait_for_completion(&data->ctx); + + spi_context_cs_control(&data->ctx, false); + + spi_context_release(&data->ctx, ret); + + return ret; +} + static int spi_sf32lb_release(const struct device *dev, const struct spi_config *config) { struct spi_sf32lb_data *data = dev->data; @@ -205,6 +325,9 @@ static int spi_sf32lb_release(const struct device *dev, const struct spi_config static DEVICE_API(spi, spi_sf32lb_api) = { .transceive = spi_sf32lb_transceive, +#ifdef CONFIG_SPI_ASYNC + .transceive_async = spi_sf32lb_transceive_async, +#endif .release = spi_sf32lb_release, }; @@ -237,11 +360,16 @@ static int spi_sf32lb_init(const struct device *dev) } spi_context_unlock_unconditionally(&data->ctx); +#ifdef CONFIG_SPI_ASYNC + cfg->irq_config_func(); +#endif return err; } #define SPI_SF32LB_DEFINE(n) \ + IF_ENABLED(CONFIG_SPI_ASYNC, \ + (static void spi_sf32lb_irq_config_func_##n(void);)) \ PINCTRL_DT_INST_DEFINE(n); \ static struct spi_sf32lb_data spi_sf32lb_data_##n = { \ SPI_CONTEXT_INIT_LOCK(spi_sf32lb_data_##n, ctx), \ @@ -252,9 +380,18 @@ static int spi_sf32lb_init(const struct device *dev) .base = DT_INST_REG_ADDR(n), \ .clock = SF32LB_CLOCK_DT_INST_SPEC_GET(n), \ .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ + IF_ENABLED(CONFIG_SPI_ASYNC, \ + (.irq_config_func = spi_sf32lb_irq_config_func_##n,)) \ }; \ DEVICE_DT_INST_DEFINE(n, spi_sf32lb_init, NULL, &spi_sf32lb_data_##n, \ &spi_sf32lb_config_##n, POST_KERNEL, CONFIG_SPI_INIT_PRIORITY, \ - &spi_sf32lb_api); + &spi_sf32lb_api); \ + IF_ENABLED(CONFIG_SPI_ASYNC, \ + (static void spi_sf32lb_irq_config_func_##n(void) \ + { \ + IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority), spi_sf32lb_isr, \ + DEVICE_DT_INST_GET(n), 0); \ + irq_enable(DT_INST_IRQN(n)); \ + })) DT_INST_FOREACH_STATUS_OKAY(SPI_SF32LB_DEFINE) From 48059d126b236d72987c7dfc28b5e997280ce943 Mon Sep 17 00:00:00 2001 From: Emil Hammarstrom Date: Tue, 23 Sep 2025 16:12:37 +0200 Subject: [PATCH 0602/3659] tests: lib: hash_map: Expect sys_hashmap_remove to erase entry After removing an entry the user does not expect it back after sys_hashmap_insert Signed-off-by: Emil Hammarstrom --- tests/lib/hash_map/src/remove.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/tests/lib/hash_map/src/remove.c b/tests/lib/hash_map/src/remove.c index a11a756be0fb..5d2db3f3bdc6 100644 --- a/tests/lib/hash_map/src/remove.c +++ b/tests/lib/hash_map/src/remove.c @@ -37,3 +37,24 @@ ZTEST(hash_map, test_remove_false) zassert_equal(1, sys_hashmap_insert(&map, 1, 1, NULL)); zassert_false(sys_hashmap_remove(&map, 42, NULL)); } + +ZTEST(hash_map, test_remove_entry) +{ + uint64_t entry = 0xF00DF00DF00DF00DU; + uint64_t old_value; + + /* Fill hashmap so that the rehashing condition is not always met when running the test */ + for (size_t i = 0; i < 20; ++i) { + zassert_false(sys_hashmap_insert(&map, i, i, NULL) < 0); + } + + /* Remove key 16, expecting its entry to be erased */ + old_value = 0; + zassert_true(sys_hashmap_remove(&map, 16, &old_value)); + zassert_equal(16, old_value); + + /* Insert an entry at key 16, expecting no old entry to be returned */ + old_value = 0; + zassert_equal(1, sys_hashmap_insert(&map, 16, entry, &old_value)); + zassert_equal(0, old_value); +} From 12986286deae1dfbf4c400bb9f0d74061414a1be Mon Sep 17 00:00:00 2001 From: Emil Hammarstrom Date: Tue, 23 Sep 2025 16:15:54 +0200 Subject: [PATCH 0603/3659] lib: hash: Ensure OA/LP hmap inserts don't return tombstones According to the hashmap interface specification sys_hashmap_remove will "Erase the entry associated with key `key`, if one exists" If a rehash is performed OA/LP will return 1 and no old_value for sys_hashmap_insert. If a rehash is NOT performed OA/LP will return 0 and a stale old_value for sys_hashmap_insert even though the user requested the entry for that key to be removed. This patch makes OA/LP not return the value of tombstoned entries. Signed-off-by: Emil Hammarstrom --- lib/hash/hash_map_oa_lp.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/lib/hash/hash_map_oa_lp.c b/lib/hash/hash_map_oa_lp.c index e40112dfad32..e6e47ac65cf9 100644 --- a/lib/hash/hash_map_oa_lp.c +++ b/lib/hash/hash_map_oa_lp.c @@ -84,23 +84,22 @@ static int sys_hashmap_oa_lp_insert_no_rehash(struct sys_hashmap *map, uint64_t __ASSERT_NO_MSG(entry != NULL); switch (entry->state) { - case UNUSED: - ++data->size; - ret = 1; - break; case TOMBSTONE: --data->n_tombstones; ++data->size; - ret = 0; + ret = 1; break; case USED: - default: + if (old_value != NULL) { + *old_value = entry->value; + } ret = 0; break; - } - - if (old_value != NULL) { - *old_value = entry->value; + case UNUSED: + default: + ++data->size; + ret = 1; + break; } entry->state = USED; From d7a22685ec49ce8c295cecbecadf179d096faa31 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Sat, 8 Nov 2025 21:49:42 +0530 Subject: [PATCH 0604/3659] boards: shields: nrf7002eb: Add 54H coex shield This shield is a standalone coex shield without relying on the base Wi-Fi shield (edge_connector). Signed-off-by: Chaitanya Tata --- boards/shields/nrf7002eb/Kconfig.shield | 3 +++ boards/shields/nrf7002eb/doc/index.rst | 1 + .../nrf7002eb/nrf7002eb_coex_sa.overlay | 24 +++++++++++++++++++ boards/shields/nrf7002eb/shield.yml | 6 +++++ 4 files changed, 34 insertions(+) create mode 100644 boards/shields/nrf7002eb/nrf7002eb_coex_sa.overlay diff --git a/boards/shields/nrf7002eb/Kconfig.shield b/boards/shields/nrf7002eb/Kconfig.shield index e369cfe3de42..03c85ebdb2a5 100644 --- a/boards/shields/nrf7002eb/Kconfig.shield +++ b/boards/shields/nrf7002eb/Kconfig.shield @@ -6,3 +6,6 @@ config SHIELD_NRF7002EB config SHIELD_NRF7002EB_COEX def_bool $(shields_list_contains,nrf7002eb_coex) + +config SHIELD_NRF7002EB_COEX_SA + def_bool $(shields_list_contains,nrf7002eb_coex_sa) diff --git a/boards/shields/nrf7002eb/doc/index.rst b/boards/shields/nrf7002eb/doc/index.rst index 637f91ae21b4..7b7ce2108a91 100644 --- a/boards/shields/nrf7002eb/doc/index.rst +++ b/boards/shields/nrf7002eb/doc/index.rst @@ -51,6 +51,7 @@ edge-connector on some boards, like earlier revisions of the Thingy53 than v1.0. - ``nrf7002eb``: The default variant. - ``nrf7002eb_coex``: Variant which includes the COEX pins. +- ``nrf7002eb_coex_sa``: Variant which includes the COEX pins and is standalone. SR Co-existence *************** diff --git a/boards/shields/nrf7002eb/nrf7002eb_coex_sa.overlay b/boards/shields/nrf7002eb/nrf7002eb_coex_sa.overlay new file mode 100644 index 000000000000..e65c2f776a31 --- /dev/null +++ b/boards/shields/nrf7002eb/nrf7002eb_coex_sa.overlay @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + nrf_radio_coex: coex { + compatible = "nordic,nrf7002-coex"; + status = "okay"; + + status0-gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>; + req-gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>; + grant-gpios = <&gpio1 3 (GPIO_PULL_DOWN | GPIO_ACTIVE_LOW)>; + }; +}; + +&gpio1 { + status = "okay"; +}; + +&gpiote130 { + status = "okay"; +}; diff --git a/boards/shields/nrf7002eb/shield.yml b/boards/shields/nrf7002eb/shield.yml index 43ab36ad9951..f765158d0f7e 100644 --- a/boards/shields/nrf7002eb/shield.yml +++ b/boards/shields/nrf7002eb/shield.yml @@ -10,3 +10,9 @@ shields: vendor: nordic supported_features: - wifi + + - name: nrf7002eb_coex_sa + full_name: nRF7002 Evaluation Board Shield (SR Co-Existence) standalone + vendor: nordic + supported_features: + - wifi From 9ea5170f09266b32864a1d802c1953581817efd3 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Tue, 11 Nov 2025 00:43:29 +0530 Subject: [PATCH 0605/3659] boards: nordic: nrf54h20dk: Fix CPURAD MPSL init failure Allocate one GPIOTE channel for coex grant GPIO pin. This fixes a nrfx assert during MPSL init in CPURAD. Signed-off-by: Chaitanya Tata --- boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts | 3 ++- boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpurad.dts | 5 +++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts index 01d75ffa3556..a59ca6ffc3be 100644 --- a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts +++ b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts @@ -219,9 +219,10 @@ slot3_partition: &cpurad_slot1_partition { memory-regions = <&cpuapp_dma_region>; }; +/* Leave one channel for CPURAD */ &gpiote130 { status = "okay"; - owned-channels = <0 1 2 3 4 5 6 7>; + owned-channels = <0 1 2 3 4 5 6>; }; &gpio0 { diff --git a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpurad.dts b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpurad.dts index d5fea020431f..ef5698d139ef 100644 --- a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpurad.dts +++ b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpurad.dts @@ -135,3 +135,8 @@ zephyr_udc0: &usbhs { }; }; }; + +/* For coex-grant GPIO */ +&gpiote130 { + owned-channels = <7>; +}; From 8d525c4f20aa98f71f74feb7f68c87b8ec824b58 Mon Sep 17 00:00:00 2001 From: Jun Lin Date: Thu, 18 Dec 2025 16:55:02 +0800 Subject: [PATCH 0606/3659] driver: eSPI: npcx: fix the missing closing brace This commit fixed the missing closing brace of the switch statement to resolve the compiler error. Signed-off-by: Jun Lin --- drivers/espi/espi_npcx.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/espi/espi_npcx.c b/drivers/espi/espi_npcx.c index dab266336230..64104d1ddc9c 100644 --- a/drivers/espi/espi_npcx.c +++ b/drivers/espi/espi_npcx.c @@ -628,6 +628,7 @@ static void espi_vw_notify_host_warning(const struct device *dev, #endif default: break; + } } } From dfe251554b26412dd683ee26474925d7132218ac Mon Sep 17 00:00:00 2001 From: Jun Lin Date: Thu, 18 Dec 2025 16:56:28 +0800 Subject: [PATCH 0607/3659] driver: eSPI: npcx: fix minor sonarqube issues Fix the Quality Gate failed from sonaqube. Signed-off-by: Jun Lin --- drivers/espi/espi_npcx.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/espi/espi_npcx.c b/drivers/espi/espi_npcx.c index 64104d1ddc9c..6ba7105c177b 100644 --- a/drivers/espi/espi_npcx.c +++ b/drivers/espi/espi_npcx.c @@ -713,6 +713,8 @@ static void espi_vw_generic_isr(const struct device *dev, struct npcx_wui *wui) espi_vw_notify_host_warning(dev, signal); } else if (signal == ESPI_VWIRE_SIGNAL_PLTRST) { espi_vw_notify_plt_rst(dev); + } else { + LOG_WRN("Unhandled VW signal: %d", signal); } } @@ -1050,7 +1052,6 @@ static int espi_npcx_send_oob(const struct device *dev, inst->OOBCTL = oob_data; while (IS_BIT_SET(inst->OOBCTL, NPCX_OOBCTL_OOB_AVAIL)) { - ; } LOG_DBG("%s issued!!", __func__); From 79f972db8909308cecfd7d88231d5ebbb7b9f721 Mon Sep 17 00:00:00 2001 From: Robert Cheng Date: Tue, 21 Oct 2025 10:36:20 +0800 Subject: [PATCH 0608/3659] dt-bindings: focaltech: ft9001: add clock, reset, uart Add devicetree bindings for the FocalTech FT9001 SoC: - Clock controller - Reset controller - UART These bindings are required by the SoC and drivers added in subsequent commits. Headers are placed under include/zephyr/dt-bindings/. Signed-off-by: Robert Cheng --- dts/bindings/clock/focaltech,ft9001-cpm.yaml | 17 ++ .../reset/focaltech,ft9001-cpm-rctl.yaml | 18 ++ .../serial/focaltech,ft9001-usart.yaml | 33 ++ .../clock/focaltech_ft9001_clocks.h | 287 ++++++++++++++++++ .../pinctrl/focaltech_ft9001_pinctrl.h | 72 +++++ .../reset/focaltech_ft9001_reset.h | 287 ++++++++++++++++++ 6 files changed, 714 insertions(+) create mode 100644 dts/bindings/clock/focaltech,ft9001-cpm.yaml create mode 100644 dts/bindings/reset/focaltech,ft9001-cpm-rctl.yaml create mode 100644 dts/bindings/serial/focaltech,ft9001-usart.yaml create mode 100644 include/zephyr/dt-bindings/clock/focaltech_ft9001_clocks.h create mode 100644 include/zephyr/dt-bindings/pinctrl/focaltech_ft9001_pinctrl.h create mode 100644 include/zephyr/dt-bindings/reset/focaltech_ft9001_reset.h diff --git a/dts/bindings/clock/focaltech,ft9001-cpm.yaml b/dts/bindings/clock/focaltech,ft9001-cpm.yaml new file mode 100644 index 000000000000..aed29a03393d --- /dev/null +++ b/dts/bindings/clock/focaltech,ft9001-cpm.yaml @@ -0,0 +1,17 @@ +# Copyright (c) 2025, FocalTech Systems CO.,Ltd +# SPDX-License-Identifier: Apache-2.0 + +description: | + FocalTech FT9001 Clock & Power Manager (CPM) specifiers use the packed IDs + defined in include/zephyr/dt-bindings/clock/focaltech_ft9001_clock.h + +compatible: "focaltech,ft9001-cpm" + +include: [clock-controller.yaml, base.yaml] + +properties: + "#clock-cells": + const: 1 + +clock-cells: + - id diff --git a/dts/bindings/reset/focaltech,ft9001-cpm-rctl.yaml b/dts/bindings/reset/focaltech,ft9001-cpm-rctl.yaml new file mode 100644 index 000000000000..02a513c4b4f6 --- /dev/null +++ b/dts/bindings/reset/focaltech,ft9001-cpm-rctl.yaml @@ -0,0 +1,18 @@ +# Copyright (c) 2025, FocalTech Systems CO.,Ltd +# SPDX-License-Identifier: Apache-2.0 + +description: | + FocalTech FT9001 Reset controller (CPM subnode). + Reset specifiers use the packed IDs defined in + include/zephyr/dt-bindings/reset/focaltech_ft9001_reset.h + +compatible: "focaltech,ft9001-cpm-rctl" + +include: [reset-controller.yaml] + +properties: + "#reset-cells": + const: 1 + +reset-cells: + - id diff --git a/dts/bindings/serial/focaltech,ft9001-usart.yaml b/dts/bindings/serial/focaltech,ft9001-usart.yaml new file mode 100644 index 000000000000..f81462aef914 --- /dev/null +++ b/dts/bindings/serial/focaltech,ft9001-usart.yaml @@ -0,0 +1,33 @@ +# Copyright (c) 2025, FocalTech Systems CO.,Ltd +# SPDX-License-Identifier: Apache-2.0 + +description: | + FocalTech FT9001 USART controller node + + The FT9001 USART (Universal Synchronous/Asynchronous Receiver/Transmitter) + controller provides serial communication capabilities with support for: + - Asynchronous UART communication + - Configurable baud rates + - Hardware flow control (optional) + - Interrupt-driven and polling operation modes + - 7, 8, or 9-bit data formats + - Even, odd, or no parity + - 1 or 2 stop bits + - FIFO buffering for improved performance + +compatible: "focaltech,ft9001-usart" + +include: [uart-controller.yaml, reset-device.yaml, pinctrl-device.yaml] + +properties: + reg: + required: true + + interrupts: + required: true + + resets: + required: true + + clocks: + required: true diff --git a/include/zephyr/dt-bindings/clock/focaltech_ft9001_clocks.h b/include/zephyr/dt-bindings/clock/focaltech_ft9001_clocks.h new file mode 100644 index 000000000000..cb6f2d0b2f3c --- /dev/null +++ b/include/zephyr/dt-bindings/clock/focaltech_ft9001_clocks.h @@ -0,0 +1,287 @@ +/* + * Copyright (c) 2025, FocalTech Systems CO.,Ltd + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_FOCALTECH_FT9001_CLOCKS_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_FOCALTECH_FT9001_CLOCKS_H_ + +/** + * @defgroup focaltech_clock_macros FocalTech Clock Configuration Macros + * @brief Macros for encoding clock register and bit information + * @{ + */ + +#define FOCALTECH_CLOCK_SHIFT 6U +#define FOCALTECH_CLOCK_MASK ((1U << FOCALTECH_CLOCK_SHIFT) - 1U) + +#define FOCALTECH_CLOCK_CONFIG(reg, bit) \ + (((FOCALTECH_##reg##_OFFSET) << FOCALTECH_CLOCK_SHIFT) | ((bit) & FOCALTECH_CLOCK_MASK)) + +/** @} */ + +/** + * @defgroup focaltech_clk_regs FocalTech Clock Power Module Registers + * @brief Clock Power Module Register offsets + * @{ + */ + +/** Multi Clock Gate Control Register */ +#define FOCALTECH_MULTICGCR_OFFSET 0x3CU +/** System Clock Gate Control Register */ +#define FOCALTECH_SYSCGCR_OFFSET 0x40U +/** AHB3 Clock Gate Control Register */ +#define FOCALTECH_AHB3CGCR_OFFSET 0x44U +/** Algorithm Clock Gate Control Register */ +#define FOCALTECH_ARITHCGCR_OFFSET 0x48U +/** IPS Clock Gate Control Register */ +#define FOCALTECH_IPSCGCR_OFFSET 0x4CU +/** EPORT Clock Gate Control Register */ +#define FOCALTECH_EPORTCGCR_OFFSET 0x84U + +/** @} */ + +/** + * @defgroup focaltech_clk_enables FocalTech Clock Enable/Disable Definitions + * @brief Clock enable/disable definitions for peripherals + * @{ + */ + +/** + * @defgroup focaltech_multicgcr_clocks MULTICGCR Clock Control + * @brief Multi Clock Gate Control Register peripherals + * @{ + */ + +/** OTP AHB clock */ +#define FOCALTECH_CLOCK_OTP_AHB FOCALTECH_CLOCK_CONFIG(MULTICGCR, 0U) +/** MCC clock */ +#define FOCALTECH_CLOCK_MCC FOCALTECH_CLOCK_CONFIG(MULTICGCR, 1U) +/** MCC address clock */ +#define FOCALTECH_CLOCK_MCCADR FOCALTECH_CLOCK_CONFIG(MULTICGCR, 2U) +/** ADC clock */ +#define FOCALTECH_CLOCK_ADC FOCALTECH_CLOCK_CONFIG(MULTICGCR, 3U) +/** MESH clock */ +#define FOCALTECH_CLOCK_MESH FOCALTECH_CLOCK_CONFIG(MULTICGCR, 4U) +/** TC clock */ +#define FOCALTECH_CLOCK_TC FOCALTECH_CLOCK_CONFIG(MULTICGCR, 5U) +/** Clock output */ +#define FOCALTECH_CLOCK_CLKOUT FOCALTECH_CLOCK_CONFIG(MULTICGCR, 6U) +/** Key controller clock */ +#define FOCALTECH_CLOCK_KEY_CTRL FOCALTECH_CLOCK_CONFIG(MULTICGCR, 7U) +/** CCM reset clock */ +#define FOCALTECH_CLOCK_CCM_RESET FOCALTECH_CLOCK_CONFIG(MULTICGCR, 8U) +/** OTP IPS clock */ +#define FOCALTECH_CLOCK_OTP_IPS FOCALTECH_CLOCK_CONFIG(MULTICGCR, 9U) +/** CPM IPS clock */ +#define FOCALTECH_CLOCK_CPM_IPS FOCALTECH_CLOCK_CONFIG(MULTICGCR, 10U) +/** Trace clock */ +#define FOCALTECH_CLOCK_TRACE FOCALTECH_CLOCK_CONFIG(MULTICGCR, 11U) +/** I2S master clock */ +#define FOCALTECH_CLOCK_I2S_M FOCALTECH_CLOCK_CONFIG(MULTICGCR, 12U) +/** I2S slave clock */ +#define FOCALTECH_CLOCK_I2S_S FOCALTECH_CLOCK_CONFIG(MULTICGCR, 13U) +/** CRC0 clock */ +#define FOCALTECH_CLOCK_CRC0 FOCALTECH_CLOCK_CONFIG(MULTICGCR, 14U) +/** CRC1 clock */ +#define FOCALTECH_CLOCK_CRC1 FOCALTECH_CLOCK_CONFIG(MULTICGCR, 15U) + +/** @} */ + +/** + * @defgroup focaltech_syscgcr_clocks SYSCGCR Clock Control + * @brief System Clock Gate Control Register peripherals + * @{ + */ + +/** SSI slave 1 clock */ +#define FOCALTECH_CLOCK_SSISLV1 FOCALTECH_CLOCK_CONFIG(SYSCGCR, 0U) +/** DMAC1 clock */ +#define FOCALTECH_CLOCK_DMAC1 FOCALTECH_CLOCK_CONFIG(SYSCGCR, 1U) +/** DMAC2 clock */ +#define FOCALTECH_CLOCK_DMAC2 FOCALTECH_CLOCK_CONFIG(SYSCGCR, 2U) +/** AHB2 MUX clock */ +#define FOCALTECH_CLOCK_AHB2_MUX FOCALTECH_CLOCK_CONFIG(SYSCGCR, 3U) +/** PXLP1 AHB clock */ +#define FOCALTECH_CLOCK_PXLP1_AHB FOCALTECH_CLOCK_CONFIG(SYSCGCR, 10U) +/** PXLP2 AHB clock */ +#define FOCALTECH_CLOCK_PXLP2_AHB FOCALTECH_CLOCK_CONFIG(SYSCGCR, 11U) +/** SRAM data clock */ +#define FOCALTECH_CLOCK_SRAMD FOCALTECH_CLOCK_CONFIG(SYSCGCR, 12U) +/** SRAM0 clock */ +#define FOCALTECH_CLOCK_SRAM0 FOCALTECH_CLOCK_CONFIG(SYSCGCR, 13U) +/** SRAM1 clock */ +#define FOCALTECH_CLOCK_SRAM1 FOCALTECH_CLOCK_CONFIG(SYSCGCR, 14U) +/** SRAM2 clock */ +#define FOCALTECH_CLOCK_SRAM2 FOCALTECH_CLOCK_CONFIG(SYSCGCR, 15U) +/** SRAM3/4 clock */ +#define FOCALTECH_CLOCK_SRAM3_4 FOCALTECH_CLOCK_CONFIG(SYSCGCR, 16U) +/** SSI4 clock */ +#define FOCALTECH_CLOCK_SSI4 FOCALTECH_CLOCK_CONFIG(SYSCGCR, 17U) +/** SSI5 clock */ +#define FOCALTECH_CLOCK_SSI5 FOCALTECH_CLOCK_CONFIG(SYSCGCR, 18U) +/** SSI6 clock */ +#define FOCALTECH_CLOCK_SSI6 FOCALTECH_CLOCK_CONFIG(SYSCGCR, 19U) + +/** @} */ + +/** + * @defgroup focaltech_ahb3cgcr_clocks AHB3CGCR Clock Control + * @brief AHB3 Clock Gate Control Register peripherals + * @{ + */ + +/** ROM clock */ +#define FOCALTECH_CLOCK_ROM FOCALTECH_CLOCK_CONFIG(AHB3CGCR, 0U) +/** ROM OTP MUX clock */ +#define FOCALTECH_CLOCK_ROM_OTP_MUX FOCALTECH_CLOCK_CONFIG(AHB3CGCR, 1U) +/** AHB3 MUX clock */ +#define FOCALTECH_CLOCK_AHB3_MUX FOCALTECH_CLOCK_CONFIG(AHB3CGCR, 2U) +/** USB controller clock */ +#define FOCALTECH_CLOCK_USBC FOCALTECH_CLOCK_CONFIG(AHB3CGCR, 3U) +/** PXLP1 APB clock */ +#define FOCALTECH_CLOCK_PXLP1_APB FOCALTECH_CLOCK_CONFIG(AHB3CGCR, 4U) +/** PXLP2 APB clock */ +#define FOCALTECH_CLOCK_PXLP2_APB FOCALTECH_CLOCK_CONFIG(AHB3CGCR, 5U) +/** I2S1 clock */ +#define FOCALTECH_CLOCK_I2S1 FOCALTECH_CLOCK_CONFIG(AHB3CGCR, 6U) +/** I2S2 clock */ +#define FOCALTECH_CLOCK_I2S2 FOCALTECH_CLOCK_CONFIG(AHB3CGCR, 7U) + +/** @} */ + +/** + * @defgroup focaltech_arithcgcr_clocks ARITHCGCR Clock Control + * @brief Algorithm Clock Gate Control Register peripherals + * @{ + */ + +/** AES clock */ +#define FOCALTECH_CLOCK_AES FOCALTECH_CLOCK_CONFIG(ARITHCGCR, 1U) +/** SM4 clock */ +#define FOCALTECH_CLOCK_SM4 FOCALTECH_CLOCK_CONFIG(ARITHCGCR, 2U) +/** RF AES SM4 clock */ +#define FOCALTECH_CLOCK_RF_AES_SM4 FOCALTECH_CLOCK_CONFIG(ARITHCGCR, 4U) +/** Crypto clock */ +#define FOCALTECH_CLOCK_CRYPTO FOCALTECH_CLOCK_CONFIG(ARITHCGCR, 5U) +/** SHA clock */ +#define FOCALTECH_CLOCK_SHA FOCALTECH_CLOCK_CONFIG(ARITHCGCR, 6U) +/** EDMAC0 clock */ +#define FOCALTECH_CLOCK_EDMAC0 FOCALTECH_CLOCK_CONFIG(ARITHCGCR, 7U) +/** DES clock */ +#define FOCALTECH_CLOCK_DES FOCALTECH_CLOCK_CONFIG(ARITHCGCR, 8U) +/** ZUC clock */ +#define FOCALTECH_CLOCK_ZUC FOCALTECH_CLOCK_CONFIG(ARITHCGCR, 9U) +/** AHB2MLB clock */ +#define FOCALTECH_CLOCK_AHB2MLB FOCALTECH_CLOCK_CONFIG(ARITHCGCR, 10U) +/** AHB2IPS2 clock */ +#define FOCALTECH_CLOCK_AHB2IPS2 FOCALTECH_CLOCK_CONFIG(ARITHCGCR, 11U) +/** TRNG clock */ +#define FOCALTECH_CLOCK_TRNG FOCALTECH_CLOCK_CONFIG(ARITHCGCR, 12U) + +/** @} */ + +/** + * @defgroup focaltech_ipscgcr_clocks IPSCGCR Clock Control + * @brief IPS Clock Gate Control Register peripherals + * @{ + */ + +/** IO controller clock */ +#define FOCALTECH_CLOCK_IO_CTRL FOCALTECH_CLOCK_CONFIG(IPSCGCR, 0U) +/** Watchdog timer clock */ +#define FOCALTECH_CLOCK_WDT FOCALTECH_CLOCK_CONFIG(IPSCGCR, 1U) +/** RTC clock */ +#define FOCALTECH_CLOCK_RTC FOCALTECH_CLOCK_CONFIG(IPSCGCR, 2U) +/** PIT1 clock */ +#define FOCALTECH_CLOCK_PIT1 FOCALTECH_CLOCK_CONFIG(IPSCGCR, 3U) +/** PIT2 clock */ +#define FOCALTECH_CLOCK_PIT2 FOCALTECH_CLOCK_CONFIG(IPSCGCR, 4U) +/** USI1 clock */ +#define FOCALTECH_CLOCK_USI1 FOCALTECH_CLOCK_CONFIG(IPSCGCR, 5U) +/** EDMAC1 clock */ +#define FOCALTECH_CLOCK_EDMAC1 FOCALTECH_CLOCK_CONFIG(IPSCGCR, 6U) +/** SPI1 clock */ +#define FOCALTECH_CLOCK_SPI1 FOCALTECH_CLOCK_CONFIG(IPSCGCR, 7U) +/** SPI2 clock */ +#define FOCALTECH_CLOCK_SPI2 FOCALTECH_CLOCK_CONFIG(IPSCGCR, 8U) +/** SPI3 clock */ +#define FOCALTECH_CLOCK_SPI3 FOCALTECH_CLOCK_CONFIG(IPSCGCR, 9U) +/** SCI1 clock */ +#define FOCALTECH_CLOCK_SCI1 FOCALTECH_CLOCK_CONFIG(IPSCGCR, 10U) +/** SCI2 clock */ +#define FOCALTECH_CLOCK_SCI2 FOCALTECH_CLOCK_CONFIG(IPSCGCR, 11U) +/** USI2 clock */ +#define FOCALTECH_CLOCK_USI2 FOCALTECH_CLOCK_CONFIG(IPSCGCR, 12U) +/** CAN1 clock */ +#define FOCALTECH_CLOCK_CAN1 FOCALTECH_CLOCK_CONFIG(IPSCGCR, 13U) +/** I2C1 clock */ +#define FOCALTECH_CLOCK_I2C1 FOCALTECH_CLOCK_CONFIG(IPSCGCR, 14U) +/** PWM0 clock */ +#define FOCALTECH_CLOCK_PWM0 FOCALTECH_CLOCK_CONFIG(IPSCGCR, 15U) +/** I2C2 clock */ +#define FOCALTECH_CLOCK_I2C2 FOCALTECH_CLOCK_CONFIG(IPSCGCR, 16U) +/** CAN2 clock */ +#define FOCALTECH_CLOCK_CAN2 FOCALTECH_CLOCK_CONFIG(IPSCGCR, 17U) +/** SCI3 clock */ +#define FOCALTECH_CLOCK_SCI3 FOCALTECH_CLOCK_CONFIG(IPSCGCR, 18U) +/** QADC clock */ +#define FOCALTECH_CLOCK_QADC FOCALTECH_CLOCK_CONFIG(IPSCGCR, 20U) +/** DAC clock */ +#define FOCALTECH_CLOCK_DAC FOCALTECH_CLOCK_CONFIG(IPSCGCR, 21U) +/** MCC IPS clock */ +#define FOCALTECH_CLOCK_MCC_IPS FOCALTECH_CLOCK_CONFIG(IPSCGCR, 22U) +/** PWMT1 clock */ +#define FOCALTECH_CLOCK_PWMT1 FOCALTECH_CLOCK_CONFIG(IPSCGCR, 23U) +/** LD clock */ +#define FOCALTECH_CLOCK_LD FOCALTECH_CLOCK_CONFIG(IPSCGCR, 24U) +/** PWMT2 clock */ +#define FOCALTECH_CLOCK_PWMT2 FOCALTECH_CLOCK_CONFIG(IPSCGCR, 25U) +/** PGD clock */ +#define FOCALTECH_CLOCK_PGD FOCALTECH_CLOCK_CONFIG(IPSCGCR, 26U) +/** Security detector clock */ +#define FOCALTECH_CLOCK_SEC_DET FOCALTECH_CLOCK_CONFIG(IPSCGCR, 27U) +/** PCI clock */ +#define FOCALTECH_CLOCK_PCI FOCALTECH_CLOCK_CONFIG(IPSCGCR, 28U) +/** PMU RTC clock */ +#define FOCALTECH_CLOCK_PMURTC FOCALTECH_CLOCK_CONFIG(IPSCGCR, 29U) +/** AHB2IPS clock */ +#define FOCALTECH_CLOCK_AHB2IPS FOCALTECH_CLOCK_CONFIG(IPSCGCR, 30U) +/** PWMT3 clock */ +#define FOCALTECH_CLOCK_PWMT3 FOCALTECH_CLOCK_CONFIG(IPSCGCR, 31U) + +/** @} */ + +/** + * @defgroup focaltech_eportcgcr_clocks EPORTCGCR Clock Control + * @brief EPORT Clock Gate Control Register peripherals + * @{ + */ + +/** EPORT0 clock */ +#define FOCALTECH_CLOCK_EPORT0 FOCALTECH_CLOCK_CONFIG(EPORTCGCR, 0U) +/** EPORT1 clock */ +#define FOCALTECH_CLOCK_EPORT1 FOCALTECH_CLOCK_CONFIG(EPORTCGCR, 1U) +/** EPORT2 clock */ +#define FOCALTECH_CLOCK_EPORT2 FOCALTECH_CLOCK_CONFIG(EPORTCGCR, 2U) +/** EPORT3 clock */ +#define FOCALTECH_CLOCK_EPORT3 FOCALTECH_CLOCK_CONFIG(EPORTCGCR, 3U) +/** EPORT4 clock */ +#define FOCALTECH_CLOCK_EPORT4 FOCALTECH_CLOCK_CONFIG(EPORTCGCR, 4U) +/** EPORT5 clock */ +#define FOCALTECH_CLOCK_EPORT5 FOCALTECH_CLOCK_CONFIG(EPORTCGCR, 5U) +/** EPORT6 clock */ +#define FOCALTECH_CLOCK_EPORT6 FOCALTECH_CLOCK_CONFIG(EPORTCGCR, 6U) +/** EPORT7 clock */ +#define FOCALTECH_CLOCK_EPORT7 FOCALTECH_CLOCK_CONFIG(EPORTCGCR, 7U) +/** ACMP1 clock */ +#define FOCALTECH_CLOCK_ACMP1 FOCALTECH_CLOCK_CONFIG(EPORTCGCR, 8U) +/** ACMP2 clock */ +#define FOCALTECH_CLOCK_ACMP2 FOCALTECH_CLOCK_CONFIG(EPORTCGCR, 9U) + +/** @} */ + +/** @} */ + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_FOCALTECH_FT9001_CLOCKS_H_ */ diff --git a/include/zephyr/dt-bindings/pinctrl/focaltech_ft9001_pinctrl.h b/include/zephyr/dt-bindings/pinctrl/focaltech_ft9001_pinctrl.h new file mode 100644 index 000000000000..09bb6d1649d7 --- /dev/null +++ b/include/zephyr/dt-bindings/pinctrl/focaltech_ft9001_pinctrl.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2025, FocalTech Systems CO.,Ltd + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_FOCALTECH_FT9001_PINCTRL_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_FOCALTECH_FT9001_PINCTRL_H_ + +/** + * @defgroup focaltech_pinctrl_macros FocalTech IOCTRL Pin Control + * @brief Pin control macros for FocalTech FT9001 SoC + * @{ + */ + +/* + * Pinmux encoding: + * bit[0:0] - VALUE (0 = default, 1 = alternate) + * bit[5:1] - BIT position in register + * bit[25:6] - Register offset + */ +#define FOCALTECH_IOCTRL_BASE 0x40000000U + +#define FOCALTECH_PINCTRL_VALUE_POS 0U +#define FOCALTECH_PINCTRL_BIT_POS 1U +#define FOCALTECH_PINCTRL_REG_POS 6U + +#define FOCALTECH_PINCTRL_VALUE_MASK 0x1U +#define FOCALTECH_PINCTRL_BIT_MASK 0x1FU +#define FOCALTECH_PINCTRL_REG_MASK 0xFFFFFU + +#define FOCALTECH_PINMUX(reg, bit, value) \ + (((reg) << FOCALTECH_PINCTRL_REG_POS) | ((bit) << FOCALTECH_PINCTRL_BIT_POS) | \ + ((value) << FOCALTECH_PINCTRL_VALUE_POS)) + +#define FOCALTECH_PINCTRL_REG_GET(pinmux) \ + ((((pinmux) >> FOCALTECH_PINCTRL_REG_POS) & FOCALTECH_PINCTRL_REG_MASK) | \ + FOCALTECH_IOCTRL_BASE) + +#define FOCALTECH_PINCTRL_BIT_GET(pinmux) \ + (((pinmux) >> FOCALTECH_PINCTRL_BIT_POS) & FOCALTECH_PINCTRL_BIT_MASK) + +#define FOCALTECH_PINCTRL_VALUE_GET(pinmux) \ + (((pinmux) >> FOCALTECH_PINCTRL_VALUE_POS) & FOCALTECH_PINCTRL_VALUE_MASK) + +/** + * @defgroup focaltech_pinctrl_regs IOCTRL Register Offsets + * @brief IOCTRL register offsets + * @{ + */ + +#define FOCALTECH_IOCTRL_SPICR_OFFSET 0x00000U +#define FOCALTECH_IOCTRL_I2CCR_OFFSET 0x00008U +#define FOCALTECH_IOCTRL_SCICR_OFFSET 0x0000CU +#define FOCALTECH_IOCTRL_SWAPCR_OFFSET 0x0001CU +#define FOCALTECH_IOCTRL_CLKRSTCR_OFFSET 0x00044U +#define FOCALTECH_IOCTRL_EPORT2CR_OFFSET 0x00054U +#define FOCALTECH_IOCTRL_EPORT3CR_OFFSET 0x00058U +#define FOCALTECH_IOCTRL_EPORT4CR_OFFSET 0x0005CU +#define FOCALTECH_IOCTRL_EPORT5CR_OFFSET 0x00060U +#define FOCALTECH_IOCTRL_EPORT6CR_OFFSET 0x00064U +#define FOCALTECH_IOCTRL_EPORT7CR_OFFSET 0x00068U +#define FOCALTECH_IOCTRL_SWAPCR2_OFFSET 0x0006CU +#define FOCALTECH_IOCTRL_SWAPCR3_OFFSET 0x00070U +#define FOCALTECH_IOCTRL_SWAPCR4_OFFSET 0x00074U +#define FOCALTECH_IOCTRL_SWAPCR5_OFFSET 0x00078U + +/** @} */ + +/** @} */ + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_FOCALTECH_FT9001_PINCTRL_H_ */ diff --git a/include/zephyr/dt-bindings/reset/focaltech_ft9001_reset.h b/include/zephyr/dt-bindings/reset/focaltech_ft9001_reset.h new file mode 100644 index 000000000000..bc1c90b2d821 --- /dev/null +++ b/include/zephyr/dt-bindings/reset/focaltech_ft9001_reset.h @@ -0,0 +1,287 @@ +/* + * Copyright (c) 2025, FocalTech Systems CO.,Ltd + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_RESET_FOCALTECH_FT9001_RESET_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_RESET_FOCALTECH_FT9001_RESET_H_ + +/** + * @defgroup focaltech_reset_macros FocalTech Reset Configuration Macros + * @brief Macros for encoding reset register and bit information + * @{ + */ + +#define FOCALTECH_RESET_SHIFT 6U +#define FOCALTECH_RESET_MASK ((1U << FOCALTECH_RESET_SHIFT) - 1U) + +#define FOCALTECH_RESET_CONFIG(reg, bit) \ + (((FOCALTECH_##reg##_OFFSET) << FOCALTECH_RESET_SHIFT) | ((bit) & FOCALTECH_RESET_MASK)) + +/** @} */ + +/** + * @defgroup focaltech_reset_regs FocalTech Reset Control Module Registers + * @brief Reset Control Module Register offsets + * @{ + */ + +/** EPORT Reset Control Register */ +#define FOCALTECH_EPORTRSTCR_OFFSET 0x88U +/** Multi Reset Control Register */ +#define FOCALTECH_MULTIRSTCR_OFFSET 0xACU +/** System Reset Control Register */ +#define FOCALTECH_SYSRSTCR_OFFSET 0xB0U +/** AHB3 Reset Control Register */ +#define FOCALTECH_AHB3RSTCR_OFFSET 0xB4U +/** Algorithm Reset Control Register */ +#define FOCALTECH_ARITHRSTCR_OFFSET 0xB8U +/** IPS Reset Control Register */ +#define FOCALTECH_IPSRSTCR_OFFSET 0xBCU + +/** @} */ + +/** + * @defgroup focaltech_reset_enables FocalTech Reset Enable/Disable Definitions + * @brief Reset enable/disable definitions for peripherals + * @{ + */ + +/** + * @defgroup focaltech_eportrstr_resets EPORTRSTR Reset Control + * @brief EPORT Reset Control Register peripherals + * @{ + */ + +/** EPORT0 reset */ +#define FOCALTECH_RESET_EPORT0 FOCALTECH_RESET_CONFIG(EPORTRSTCR, 0U) +/** EPORT1 reset */ +#define FOCALTECH_RESET_EPORT1 FOCALTECH_RESET_CONFIG(EPORTRSTCR, 1U) +/** EPORT2 reset */ +#define FOCALTECH_RESET_EPORT2 FOCALTECH_RESET_CONFIG(EPORTRSTCR, 2U) +/** EPORT3 reset */ +#define FOCALTECH_RESET_EPORT3 FOCALTECH_RESET_CONFIG(EPORTRSTCR, 3U) +/** EPORT4 reset */ +#define FOCALTECH_RESET_EPORT4 FOCALTECH_RESET_CONFIG(EPORTRSTCR, 4U) +/** EPORT5 reset */ +#define FOCALTECH_RESET_EPORT5 FOCALTECH_RESET_CONFIG(EPORTRSTCR, 5U) +/** EPORT6 reset */ +#define FOCALTECH_RESET_EPORT6 FOCALTECH_RESET_CONFIG(EPORTRSTCR, 6U) +/** EPORT7 reset */ +#define FOCALTECH_RESET_EPORT7 FOCALTECH_RESET_CONFIG(EPORTRSTCR, 7U) +/** ACMP1 reset */ +#define FOCALTECH_RESET_ACMP1 FOCALTECH_RESET_CONFIG(EPORTRSTCR, 8U) +/** ACMP2 reset */ +#define FOCALTECH_RESET_ACMP2 FOCALTECH_RESET_CONFIG(EPORTRSTCR, 9U) + +/** @} */ + +/** + * @defgroup focaltech_multirstcr_resets MULTIRSTCR Reset Control + * @brief Multi Reset Control Register peripherals + * @{ + */ + +/** OTP AHB reset */ +#define FOCALTECH_RESET_OTP_AHB FOCALTECH_RESET_CONFIG(MULTIRSTCR, 0U) +/** MCC reset */ +#define FOCALTECH_RESET_MCC FOCALTECH_RESET_CONFIG(MULTIRSTCR, 1U) +/** MCC address reset */ +#define FOCALTECH_RESET_MCCADR FOCALTECH_RESET_CONFIG(MULTIRSTCR, 2U) +/** ADC reset */ +#define FOCALTECH_RESET_ADC FOCALTECH_RESET_CONFIG(MULTIRSTCR, 3U) +/** MESH reset */ +#define FOCALTECH_RESET_MESH FOCALTECH_RESET_CONFIG(MULTIRSTCR, 4U) +/** TC reset */ +#define FOCALTECH_RESET_TC FOCALTECH_RESET_CONFIG(MULTIRSTCR, 5U) +/** Clock output reset */ +#define FOCALTECH_RESET_CLKOUT FOCALTECH_RESET_CONFIG(MULTIRSTCR, 6U) +/** Key controller reset */ +#define FOCALTECH_RESET_KEY_CTRL FOCALTECH_RESET_CONFIG(MULTIRSTCR, 7U) +/** CCM reset */ +#define FOCALTECH_RESET_CCM_RESET FOCALTECH_RESET_CONFIG(MULTIRSTCR, 8U) +/** OTP IPS reset */ +#define FOCALTECH_RESET_OTP_IPS FOCALTECH_RESET_CONFIG(MULTIRSTCR, 9U) +/** CPM IPS reset */ +#define FOCALTECH_RESET_CPM_IPS FOCALTECH_RESET_CONFIG(MULTIRSTCR, 10U) +/** Trace reset */ +#define FOCALTECH_RESET_TRACE FOCALTECH_RESET_CONFIG(MULTIRSTCR, 11U) +/** I2S master reset */ +#define FOCALTECH_RESET_I2S_M FOCALTECH_RESET_CONFIG(MULTIRSTCR, 12U) +/** I2S slave reset */ +#define FOCALTECH_RESET_I2S_S FOCALTECH_RESET_CONFIG(MULTIRSTCR, 13U) +/** CRC0 reset */ +#define FOCALTECH_RESET_CRC0 FOCALTECH_RESET_CONFIG(MULTIRSTCR, 14U) +/** CRC1 reset */ +#define FOCALTECH_RESET_CRC1 FOCALTECH_RESET_CONFIG(MULTIRSTCR, 15U) + +/** @} */ + +/** + * @defgroup focaltech_sysrstcr_resets SYSRSTCR Reset Control + * @brief System Reset Control Register peripherals + * @{ + */ + +/** SSI slave 1 reset */ +#define FOCALTECH_RESET_SSISLV1 FOCALTECH_RESET_CONFIG(SYSRSTCR, 0U) +/** DMAC1 reset */ +#define FOCALTECH_RESET_DMAC1 FOCALTECH_RESET_CONFIG(SYSRSTCR, 1U) +/** DMAC2 reset */ +#define FOCALTECH_RESET_DMAC2 FOCALTECH_RESET_CONFIG(SYSRSTCR, 2U) +/** AHB2 MUX reset */ +#define FOCALTECH_RESET_AHB2_MUX FOCALTECH_RESET_CONFIG(SYSRSTCR, 3U) +/** PXLP1 AHB reset */ +#define FOCALTECH_RESET_PXLP1_AHB FOCALTECH_RESET_CONFIG(SYSRSTCR, 10U) +/** PXLP2 AHB reset */ +#define FOCALTECH_RESET_PXLP2_AHB FOCALTECH_RESET_CONFIG(SYSRSTCR, 11U) +/** SRAM data reset */ +#define FOCALTECH_RESET_SRAMD FOCALTECH_RESET_CONFIG(SYSRSTCR, 12U) +/** SRAM0 reset */ +#define FOCALTECH_RESET_SRAM0 FOCALTECH_RESET_CONFIG(SYSRSTCR, 13U) +/** SRAM1 reset */ +#define FOCALTECH_RESET_SRAM1 FOCALTECH_RESET_CONFIG(SYSRSTCR, 14U) +/** SRAM2 reset */ +#define FOCALTECH_RESET_SRAM2 FOCALTECH_RESET_CONFIG(SYSRSTCR, 15U) +/** SRAM3/4 reset */ +#define FOCALTECH_RESET_SRAM3_4 FOCALTECH_RESET_CONFIG(SYSRSTCR, 16U) +/** SSI4 reset */ +#define FOCALTECH_RESET_SSI4 FOCALTECH_RESET_CONFIG(SYSRSTCR, 17U) +/** SSI5 reset */ +#define FOCALTECH_RESET_SSI5 FOCALTECH_RESET_CONFIG(SYSRSTCR, 18U) +/** SSI6 reset */ +#define FOCALTECH_RESET_SSI6 FOCALTECH_RESET_CONFIG(SYSRSTCR, 19U) + +/** @} */ + +/** + * @defgroup focaltech_ahb3rstcr_resets AHB3RSTCR Reset Control + * @brief AHB3 Reset Control Register peripherals + * @{ + */ + +/** ROM reset */ +#define FOCALTECH_RESET_ROM FOCALTECH_RESET_CONFIG(AHB3RSTCR, 0U) +/** ROM OTP MUX reset */ +#define FOCALTECH_RESET_ROM_OTP_MUX FOCALTECH_RESET_CONFIG(AHB3RSTCR, 1U) +/** AHB3 MUX reset */ +#define FOCALTECH_RESET_AHB3_MUX FOCALTECH_RESET_CONFIG(AHB3RSTCR, 2U) +/** USB controller reset */ +#define FOCALTECH_RESET_USBC FOCALTECH_RESET_CONFIG(AHB3RSTCR, 3U) +/** PXLP1 APB reset */ +#define FOCALTECH_RESET_PXLP1_APB FOCALTECH_RESET_CONFIG(AHB3RSTCR, 4U) +/** PXLP2 APB reset */ +#define FOCALTECH_RESET_PXLP2_APB FOCALTECH_RESET_CONFIG(AHB3RSTCR, 5U) +/** I2S1 reset */ +#define FOCALTECH_RESET_I2S1 FOCALTECH_RESET_CONFIG(AHB3RSTCR, 6U) +/** I2S2 reset */ +#define FOCALTECH_RESET_I2S2 FOCALTECH_RESET_CONFIG(AHB3RSTCR, 7U) + +/** @} */ + +/** + * @defgroup focaltech_arithrstcr_resets ARITHRSTCR Reset Control + * @brief Algorithm Reset Control Register peripherals + * @{ + */ + +/** AES reset */ +#define FOCALTECH_RESET_AES FOCALTECH_RESET_CONFIG(ARITHRSTCR, 1U) +/** SM4 reset */ +#define FOCALTECH_RESET_SM4 FOCALTECH_RESET_CONFIG(ARITHRSTCR, 2U) +/** RF AES SM4 reset */ +#define FOCALTECH_RESET_RF_AES_SM4 FOCALTECH_RESET_CONFIG(ARITHRSTCR, 4U) +/** Crypto reset */ +#define FOCALTECH_RESET_CRYPTO FOCALTECH_RESET_CONFIG(ARITHRSTCR, 5U) +/** SHA reset */ +#define FOCALTECH_RESET_SHA FOCALTECH_RESET_CONFIG(ARITHRSTCR, 6U) +/** EDMAC0 reset */ +#define FOCALTECH_RESET_EDMAC0 FOCALTECH_RESET_CONFIG(ARITHRSTCR, 7U) +/** DES reset */ +#define FOCALTECH_RESET_DES FOCALTECH_RESET_CONFIG(ARITHRSTCR, 8U) +/** ZUC reset */ +#define FOCALTECH_RESET_ZUC FOCALTECH_RESET_CONFIG(ARITHRSTCR, 9U) +/** AHB2MLB reset */ +#define FOCALTECH_RESET_AHB2MLB FOCALTECH_RESET_CONFIG(ARITHRSTCR, 10U) +/** AHB2IPS2 reset */ +#define FOCALTECH_RESET_AHB2IPS2 FOCALTECH_RESET_CONFIG(ARITHRSTCR, 11U) +/** TRNG reset */ +#define FOCALTECH_RESET_TRNG FOCALTECH_RESET_CONFIG(ARITHRSTCR, 12U) + +/** @} */ + +/** + * @defgroup focaltech_ipsrstcr_resets IPSRSTCR Reset Control + * @brief IPS Reset Control Register peripherals + * @{ + */ + +/** IO controller reset */ +#define FOCALTECH_RESET_IO_CTRL FOCALTECH_RESET_CONFIG(IPSRSTCR, 0U) +/** Watchdog timer reset */ +#define FOCALTECH_RESET_WDT FOCALTECH_RESET_CONFIG(IPSRSTCR, 1U) +/** RTC reset */ +#define FOCALTECH_RESET_RTC FOCALTECH_RESET_CONFIG(IPSRSTCR, 2U) +/** PIT1 reset */ +#define FOCALTECH_RESET_PIT1 FOCALTECH_RESET_CONFIG(IPSRSTCR, 3U) +/** PIT2 reset */ +#define FOCALTECH_RESET_PIT2 FOCALTECH_RESET_CONFIG(IPSRSTCR, 4U) +/** USI1 reset */ +#define FOCALTECH_RESET_USI1 FOCALTECH_RESET_CONFIG(IPSRSTCR, 5U) +/** EDMAC1 reset */ +#define FOCALTECH_RESET_EDMAC1 FOCALTECH_RESET_CONFIG(IPSRSTCR, 6U) +/** SPI1 reset */ +#define FOCALTECH_RESET_SPI1 FOCALTECH_RESET_CONFIG(IPSRSTCR, 7U) +/** SPI2 reset */ +#define FOCALTECH_RESET_SPI2 FOCALTECH_RESET_CONFIG(IPSRSTCR, 8U) +/** SPI3 reset */ +#define FOCALTECH_RESET_SPI3 FOCALTECH_RESET_CONFIG(IPSRSTCR, 9U) +/** SCI1 reset */ +#define FOCALTECH_RESET_SCI1 FOCALTECH_RESET_CONFIG(IPSRSTCR, 10U) +/** SCI2 reset */ +#define FOCALTECH_RESET_SCI2 FOCALTECH_RESET_CONFIG(IPSRSTCR, 11U) +/** USI2 reset */ +#define FOCALTECH_RESET_USI2 FOCALTECH_RESET_CONFIG(IPSRSTCR, 12U) +/** CAN1 reset */ +#define FOCALTECH_RESET_CAN1 FOCALTECH_RESET_CONFIG(IPSRSTCR, 13U) +/** I2C1 reset */ +#define FOCALTECH_RESET_I2C1 FOCALTECH_RESET_CONFIG(IPSRSTCR, 14U) +/** PWM0 reset */ +#define FOCALTECH_RESET_PWM0 FOCALTECH_RESET_CONFIG(IPSRSTCR, 15U) +/** I2C2 reset */ +#define FOCALTECH_RESET_I2C2 FOCALTECH_RESET_CONFIG(IPSRSTCR, 16U) +/** CAN2 reset */ +#define FOCALTECH_RESET_CAN2 FOCALTECH_RESET_CONFIG(IPSRSTCR, 17U) +/** SCI3 reset */ +#define FOCALTECH_RESET_SCI3 FOCALTECH_RESET_CONFIG(IPSRSTCR, 18U) +/** QADC reset */ +#define FOCALTECH_RESET_QADC FOCALTECH_RESET_CONFIG(IPSRSTCR, 20U) +/** DAC reset */ +#define FOCALTECH_RESET_DAC FOCALTECH_RESET_CONFIG(IPSRSTCR, 21U) +/** MCC IPS reset */ +#define FOCALTECH_RESET_MCC_IPS FOCALTECH_RESET_CONFIG(IPSRSTCR, 22U) +/** PWMT1 reset */ +#define FOCALTECH_RESET_PWMT1 FOCALTECH_RESET_CONFIG(IPSRSTCR, 23U) +/** LD reset */ +#define FOCALTECH_RESET_LD FOCALTECH_RESET_CONFIG(IPSRSTCR, 24U) +/** PWMT2 reset */ +#define FOCALTECH_RESET_PWMT2 FOCALTECH_RESET_CONFIG(IPSRSTCR, 25U) +/** PGD reset */ +#define FOCALTECH_RESET_PGD FOCALTECH_RESET_CONFIG(IPSRSTCR, 26U) +/** Security detector reset */ +#define FOCALTECH_RESET_SEC_DET FOCALTECH_RESET_CONFIG(IPSRSTCR, 27U) +/** PCI reset */ +#define FOCALTECH_RESET_PCI FOCALTECH_RESET_CONFIG(IPSRSTCR, 28U) +/** PMU RTC reset */ +#define FOCALTECH_RESET_PMURTC FOCALTECH_RESET_CONFIG(IPSRSTCR, 29U) +/** AHB2IPS reset */ +#define FOCALTECH_RESET_AHB2IPS FOCALTECH_RESET_CONFIG(IPSRSTCR, 30U) +/** PWMT3 reset */ +#define FOCALTECH_RESET_PWMT3 FOCALTECH_RESET_CONFIG(IPSRSTCR, 31U) + +/** @} */ + +/** @} */ + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_RESET_FOCALTECH_FT9001_RESET_H_ */ From c3d0a3703fa46f580c898c906ac5213cd4745a71 Mon Sep 17 00:00:00 2001 From: Robert Cheng Date: Tue, 21 Oct 2025 10:36:20 +0800 Subject: [PATCH 0609/3659] soc: focaltech: ft9001: add SoC support Add initial support for the FocalTech FT9001 ARM Cortex-M SoC including: - SoC Kconfig and dtsi integration points - Early init and core setup - Pinctrl base definitions This prepares the tree for the FT9001 board and drivers. Signed-off-by: Robert Cheng --- soc/focaltech/CMakeLists.txt | 4 + soc/focaltech/Kconfig | 4 + soc/focaltech/Kconfig.defconfig | 4 + soc/focaltech/Kconfig.soc | 4 + soc/focaltech/ft9001/CMakeLists.txt | 13 +++ soc/focaltech/ft9001/Kconfig | 13 +++ soc/focaltech/ft9001/Kconfig.defconfig | 12 +++ soc/focaltech/ft9001/Kconfig.soc | 10 +++ soc/focaltech/ft9001/pinctrl_soc.h | 120 +++++++++++++++++++++++++ soc/focaltech/ft9001/soc.c | 18 ++++ soc/focaltech/ft9001/soc.h | 12 +++ soc/focaltech/ft9001/xip.c | 25 ++++++ soc/focaltech/soc.yml | 2 + 13 files changed, 241 insertions(+) create mode 100644 soc/focaltech/CMakeLists.txt create mode 100644 soc/focaltech/Kconfig create mode 100644 soc/focaltech/Kconfig.defconfig create mode 100644 soc/focaltech/Kconfig.soc create mode 100644 soc/focaltech/ft9001/CMakeLists.txt create mode 100644 soc/focaltech/ft9001/Kconfig create mode 100644 soc/focaltech/ft9001/Kconfig.defconfig create mode 100644 soc/focaltech/ft9001/Kconfig.soc create mode 100644 soc/focaltech/ft9001/pinctrl_soc.h create mode 100644 soc/focaltech/ft9001/soc.c create mode 100644 soc/focaltech/ft9001/soc.h create mode 100644 soc/focaltech/ft9001/xip.c create mode 100644 soc/focaltech/soc.yml diff --git a/soc/focaltech/CMakeLists.txt b/soc/focaltech/CMakeLists.txt new file mode 100644 index 000000000000..e06b1c03c776 --- /dev/null +++ b/soc/focaltech/CMakeLists.txt @@ -0,0 +1,4 @@ +# Copyright (c) 2025, FocalTech Systems CO.,Ltd +# SPDX-License-Identifier: Apache-2.0 + +add_subdirectory(ft9001) diff --git a/soc/focaltech/Kconfig b/soc/focaltech/Kconfig new file mode 100644 index 000000000000..6686b285bd69 --- /dev/null +++ b/soc/focaltech/Kconfig @@ -0,0 +1,4 @@ +# Copyright (c) 2025, FocalTech Systems CO.,Ltd +# SPDX-License-Identifier: Apache-2.0 + +rsource "*/Kconfig" diff --git a/soc/focaltech/Kconfig.defconfig b/soc/focaltech/Kconfig.defconfig new file mode 100644 index 000000000000..cebbc042e215 --- /dev/null +++ b/soc/focaltech/Kconfig.defconfig @@ -0,0 +1,4 @@ +# Copyright (c) 2025, FocalTech Systems CO.,Ltd +# SPDX-License-Identifier: Apache-2.0 + +rsource "*/Kconfig.defconfig" diff --git a/soc/focaltech/Kconfig.soc b/soc/focaltech/Kconfig.soc new file mode 100644 index 000000000000..8efd3a16508a --- /dev/null +++ b/soc/focaltech/Kconfig.soc @@ -0,0 +1,4 @@ +# Copyright (c) 2025, FocalTech Systems CO.,Ltd +# SPDX-License-Identifier: Apache-2.0 + +rsource "*/Kconfig.soc" diff --git a/soc/focaltech/ft9001/CMakeLists.txt b/soc/focaltech/ft9001/CMakeLists.txt new file mode 100644 index 000000000000..c04a73ef4adf --- /dev/null +++ b/soc/focaltech/ft9001/CMakeLists.txt @@ -0,0 +1,13 @@ +# Copyright (c) 2025, FocalTech Systems CO.,Ltd +# SPDX-License-Identifier: Apache-2.0 + +zephyr_sources( + soc.c + xip.c +) + +zephyr_include_directories(.) + +zephyr_code_relocate(FILES xip.c LOCATION RAM) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/focaltech/ft9001/Kconfig b/soc/focaltech/ft9001/Kconfig new file mode 100644 index 000000000000..1c8ba2b1fadd --- /dev/null +++ b/soc/focaltech/ft9001/Kconfig @@ -0,0 +1,13 @@ +# Copyright (c) 2025, FocalTech Systems CO.,Ltd +# SPDX-License-Identifier: Apache-2.0 + +config SOC_FT9001 + select ARM + select CPU_CORTEX_M4 + select CPU_HAS_FPU + select CPU_HAS_ARM_MPU + select CPU_CORTEX_M_HAS_SYSTICK + select CPU_CORTEX_M_HAS_VTOR + select SOC_EARLY_INIT_HOOK + select BUILD_OUTPUT_HEX + select HAS_SEGGER_RTT if ZEPHYR_SEGGER_MODULE diff --git a/soc/focaltech/ft9001/Kconfig.defconfig b/soc/focaltech/ft9001/Kconfig.defconfig new file mode 100644 index 000000000000..e143323de742 --- /dev/null +++ b/soc/focaltech/ft9001/Kconfig.defconfig @@ -0,0 +1,12 @@ +# Copyright (c) 2025, FocalTech Systems CO.,Ltd +# SPDX-License-Identifier: Apache-2.0 + +if SOC_FT9001 + +config SYS_CLOCK_HW_CYCLES_PER_SEC + default $(dt_node_int_prop_int,/cpus/cpu@0,clock-frequency) + +config NUM_IRQS + default 140 + +endif # SOC_FT9001 diff --git a/soc/focaltech/ft9001/Kconfig.soc b/soc/focaltech/ft9001/Kconfig.soc new file mode 100644 index 000000000000..e2701dc8e4b0 --- /dev/null +++ b/soc/focaltech/ft9001/Kconfig.soc @@ -0,0 +1,10 @@ +# Copyright (c) 2025, FocalTech Systems Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 + +config SOC_FT9001 + bool + help + Build for the FocalTech FT9001 MCU (ARM Cortex-M4F). + +config SOC + default "ft9001" if SOC_FT9001 diff --git a/soc/focaltech/ft9001/pinctrl_soc.h b/soc/focaltech/ft9001/pinctrl_soc.h new file mode 100644 index 000000000000..1d02d80250b2 --- /dev/null +++ b/soc/focaltech/ft9001/pinctrl_soc.h @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2025, FocalTech Systems CO.,Ltd + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief FocalTech FT9001 SoC specific helpers for pinctrl driver + */ + +#ifndef ZEPHYR_SOC_ARM_FOCALTECH_FT9001_PINCTRL_SOC_H_ +#define ZEPHYR_SOC_ARM_FOCALTECH_FT9001_PINCTRL_SOC_H_ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @cond INTERNAL_HIDDEN */ + +/** @brief Type for FT9001 pin configuration. + * + * Bits: + * - 0-25: FT9001_PINMUX bit field. + * - 26-31: Pin configuration bit field (@ref FT9001_PINCFG). + */ +typedef uint32_t pinctrl_soc_pin_t; + +/** + * @brief Utility macro to initialize each pin. + * + * @param node_id Node identifier. + * @param prop Property name. + * @param idx Property entry index. + */ +#define Z_PINCTRL_STATE_PIN_INIT(node_id, prop, idx) \ + (DT_PROP_BY_IDX(node_id, prop, idx) | \ + ((FT9001_PUPD_PULLUP * DT_PROP(node_id, bias_pull_up)) << FT9001_PUPD_POS) | \ + ((FT9001_PUPD_PULLDOWN * DT_PROP(node_id, bias_pull_down)) << FT9001_PUPD_POS) | \ + ((FT9001_OTYPE_OD * DT_PROP(node_id, drive_open_drain)) << FT9001_OTYPE_POS) | \ + (DT_ENUM_IDX(node_id, slew_rate) << FT9001_OSPEED_POS)), + +/** + * @brief Utility macro to initialize state pins contained in a given property. + * + * @param node_id Node identifier. + * @param prop Property name describing state pins. + */ +#define Z_PINCTRL_STATE_PINS_INIT(node_id, prop) \ + {DT_FOREACH_CHILD_VARGS(DT_PHANDLE(node_id, prop), DT_FOREACH_PROP_ELEM, pinmux, \ + Z_PINCTRL_STATE_PIN_INIT)} + +/** @endcond */ + +/** + * @name FT9001 pull-up/down configuration + * @{ + */ +#define FT9001_PUPD_NONE 0U /**< No pull-up/down */ +#define FT9001_PUPD_PULLUP 1U /**< Pull-up */ +#define FT9001_PUPD_PULLDOWN 2U /**< Pull-down */ +/** @} */ + +/** + * @name FT9001 output type configuration + * @{ + */ +#define FT9001_OTYPE_PP 0U /**< Push-pull */ +#define FT9001_OTYPE_OD 1U /**< Open-drain */ +/** @} */ + +/** + * @name FT9001 output speed configuration + * @{ + */ +#define FT9001_OSPEED_10MHZ 0U /**< Maximum 10MHz */ +#define FT9001_OSPEED_2MHZ 1U /**< Maximum 2MHz */ +#define FT9001_OSPEED_50MHZ 2U /**< Maximum 50MHz */ +#define FT9001_OSPEED_MAX 3U /**< Maximum speed */ +/** @} */ + +/** + * @name FT9001 pin configuration bit field positions and masks + * @{ + */ +#define FT9001_PUPD_POS 29U /**< PUPD field position */ +#define FT9001_PUPD_MSK 0x3U /**< PUPD field mask */ +#define FT9001_OTYPE_POS 28U /**< OTYPE field position */ +#define FT9001_OTYPE_MSK 0x1U /**< OTYPE field mask */ +#define FT9001_OSPEED_POS 26U /**< OSPEED field position */ +#define FT9001_OSPEED_MSK 0x3U /**< OSPEED field mask */ +/** @} */ + +/** + * @brief Obtain PUPD field from pinctrl_soc_pin_t configuration. + * @param pincfg pinctrl_soc_pin_t bit field value. + */ +#define FT9001_PUPD_GET(pincfg) (((pincfg) >> FT9001_PUPD_POS) & FT9001_PUPD_MSK) + +/** + * @brief Obtain OTYPE field from pinctrl_soc_pin_t configuration. + * @param pincfg pinctrl_soc_pin_t bit field value. + */ +#define FT9001_OTYPE_GET(pincfg) (((pincfg) >> FT9001_OTYPE_POS) & FT9001_OTYPE_MSK) + +/** + * @brief Obtain OSPEED field from pinctrl_soc_pin_t configuration. + * @param pincfg pinctrl_soc_pin_t bit field value. + */ +#define FT9001_OSPEED_GET(pincfg) (((pincfg) >> FT9001_OSPEED_POS) & FT9001_OSPEED_MSK) + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_SOC_ARM_FOCALTECH_FT9001_PINCTRL_SOC_H_ */ diff --git a/soc/focaltech/ft9001/soc.c b/soc/focaltech/ft9001/soc.c new file mode 100644 index 000000000000..0248ca71f2b8 --- /dev/null +++ b/soc/focaltech/ft9001/soc.c @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2025, FocalTech Systems CO.,Ltd + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#define XIP_CLKDIV_BOOT 1U + +void xip_clock_switch(uint32_t clk_div); + +void soc_early_init_hook(void) +{ +#ifdef CONFIG_XIP + xip_clock_switch(XIP_CLKDIV_BOOT); +#endif +} diff --git a/soc/focaltech/ft9001/soc.h b/soc/focaltech/ft9001/soc.h new file mode 100644 index 000000000000..fab63718f10b --- /dev/null +++ b/soc/focaltech/ft9001/soc.h @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2025, FocalTech Systems CO.,Ltd + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _SOC_ARM_FOCALTECH_FT9001_SOC_H_ +#define _SOC_ARM_FOCALTECH_FT9001_SOC_H_ + +#include + +#endif /* _SOC_ARM_FOCALTECH_FT9001_SOC_H_ */ diff --git a/soc/focaltech/ft9001/xip.c b/soc/focaltech/ft9001/xip.c new file mode 100644 index 000000000000..ea539d66e555 --- /dev/null +++ b/soc/focaltech/ft9001/xip.c @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2025, FocalTech Systems CO.,Ltd + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/* clocks (soc-specific) */ +#define FT9001_CLK_CFG_ADDR 0x40004008u +#define FT9001_CLK_UPD_ADDR 0x40004018u +#define FT9001_CLK_UPD_GO_MASK 0x02u + +__ramfunc void xip_clock_switch(uint32_t clk_div) +{ + uint32_t val = sys_read32(FT9001_CLK_CFG_ADDR); + + val = (val & 0xFFFFFFF0u) | (clk_div & 0x0Fu); + sys_write32(val, FT9001_CLK_CFG_ADDR); + sys_write32(sys_read32(FT9001_CLK_UPD_ADDR) | FT9001_CLK_UPD_GO_MASK, FT9001_CLK_UPD_ADDR); + + barrier_dsync_fence_full(); + barrier_isync_fence_full(); +} diff --git a/soc/focaltech/soc.yml b/soc/focaltech/soc.yml new file mode 100644 index 000000000000..1facbf685b2d --- /dev/null +++ b/soc/focaltech/soc.yml @@ -0,0 +1,2 @@ +socs: + - name: ft9001 From 48760eea64d89cf2d0cfbe40a0113e5645ef4c87 Mon Sep 17 00:00:00 2001 From: Robert Cheng Date: Tue, 21 Oct 2025 10:36:20 +0800 Subject: [PATCH 0610/3659] dts: arm: focaltech: add ft9001 SoC dtsi Introduce the base devicetree description for the FT9001 SoC. Signed-off-by: Robert Cheng --- dts/arm/focaltech/ft9001/ft9001.dtsi | 285 +++++++++++++++++++++++++++ 1 file changed, 285 insertions(+) create mode 100644 dts/arm/focaltech/ft9001/ft9001.dtsi diff --git a/dts/arm/focaltech/ft9001/ft9001.dtsi b/dts/arm/focaltech/ft9001/ft9001.dtsi new file mode 100644 index 000000000000..d9c59119ad17 --- /dev/null +++ b/dts/arm/focaltech/ft9001/ft9001.dtsi @@ -0,0 +1,285 @@ +/* + * Copyright (c) 2025, FocalTech Systems CO.,Ltd + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include + +/ { + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-m4f"; + reg = <0>; + clock-frequency = ; + #address-cells = <1>; + #size-cells = <1>; + + mpu: mpu@e000ed90 { + compatible = "arm,armv7m-mpu"; + reg = <0xe000ed90 0x40>; + }; + }; + }; + + soc { + sram0: memory@20000000 { + compatible = "mmio-sram"; + reg = <0x20000000 DT_SIZE_K(224)>; + }; + + sramd0: memory@1fff8000 { + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x1fff8000 DT_SIZE_K(32)>; + zephyr,memory-region = "DTCM"; + }; + + pinctrl: pin-controller@40000000 { + compatible = "focaltech,ft9001-pinctrl"; + reg = <0x40000000 0x1000>; + clocks = <&cpm FOCALTECH_CLOCK_IO_CTRL>; + status = "disabled"; + }; + + ccm: ccm@40001000 { + compatible = "focaltech,ft9001-ccm"; + reg = <0x40001000 0x1000>; + status = "disabled"; + }; + + cpm: cpm@40004000 { + compatible = "focaltech,ft9001-cpm"; + reg = <0x40004000 0x1000>; + #clock-cells = <1>; + status = "okay"; + + rctl: reset-controller { + compatible = "focaltech,ft9001-cpm-rctl"; + #reset-cells = <1>; + status = "okay"; + }; + }; + + flash_ctrl: flash-controller@40003000 { + compatible = "focaltech,ft9001-flash-controller"; + reg = <0x40003000 0x1000>; + #address-cells = <1>; + #size-cells = <1>; + status = "okay"; + + flash0: flash@10000000 { + compatible = "focaltech,ft9001-nv-flash", "soc-nv-flash"; + reg = <0x10000000 0x200000>; + write-block-size = <1>; + }; + }; + + usart2: usart@40014000 { + compatible = "focaltech,ft9001-usart"; + reg = <0x40014000 0x1000>; + interrupts = <33 0>; + clocks = <&cpm FOCALTECH_CLOCK_SCI2>; + resets = <&rctl FOCALTECH_RESET_SCI2>; + status = "disabled"; + }; + + usart3: usart@4001d000 { + compatible = "focaltech,ft9001-usart"; + reg = <0x4001d000 0x1000>; + interrupts = <61 0>; + clocks = <&cpm FOCALTECH_CLOCK_SCI3>; + resets = <&rctl FOCALTECH_RESET_SCI3>; + status = "disabled"; + }; + + eport0: eport@40019000 { + compatible = "focaltech,ft9001-eport", "focaltech,ft9001-gpio"; + gpio-controller; + #gpio-cells = <2>; + reg = <0x40019000 0x1000>; + interrupts = <41 0>, + <42 0>, + <43 0>, + <44 0>, + <45 0>, + <46 0>, + <47 0>, + <48 0>; + clocks = <&cpm FOCALTECH_CLOCK_EPORT0>; + resets = <&rctl FOCALTECH_RESET_EPORT0>; + mask = <0xff>; + ngpios = <8>; + status = "okay"; + }; + + eport1: eport@4001a000 { + compatible = "focaltech,ft9001-eport", "focaltech,ft9001-gpio"; + gpio-controller; + #gpio-cells = <2>; + reg = <0x4001a000 0x1000>; + interrupts = <49 0>, + <50 0>, + <51 0>, + <52 0>, + <53 0>, + <54 0>, + <55 0>, + <56 0>; + clocks = <&cpm FOCALTECH_CLOCK_EPORT1>; + resets = <&rctl FOCALTECH_RESET_EPORT1>; + mask = <0x20>; + ngpios = <8>; + status = "okay"; + }; + + eport2: eport@40024000 { + compatible = "focaltech,ft9001-eport", "focaltech,ft9001-gpio"; + gpio-controller; + #gpio-cells = <2>; + reg = <0x40024000 0x1000>; + interrupts = <92 0>, + <93 0>, + <94 0>, + <95 0>, + <96 0>, + <97 0>, + <98 0>, + <99 0>; + clocks = <&cpm FOCALTECH_CLOCK_EPORT2>; + resets = <&rctl FOCALTECH_RESET_EPORT2>; + mask = <0xff>; + ngpios = <8>; + status = "okay"; + }; + + eport3: gpio@40025000 { + compatible = "focaltech,ft9001-eport", "focaltech,ft9001-gpio"; + gpio-controller; + reg = <0x40025000 0x1000>; + #gpio-cells = <2>; + interrupts = <100 0>, + <101 0>, + <102 0>, + <103 0>, + <104 0>, + <105 0>, + <106 0>, + <107 0>; + clocks = <&cpm FOCALTECH_CLOCK_EPORT3>; + resets = <&rctl FOCALTECH_RESET_EPORT3>; + mask = <0xff>; + ngpios = <8>; + status = "okay"; + }; + + eport4: eport@40026000 { + compatible = "focaltech,ft9001-eport", "focaltech,ft9001-gpio"; + gpio-controller; + #gpio-cells = <2>; + reg = <0x40026000 0x1000>; + interrupts = <108 0>, + <109 0>, + <110 0>, + <111 0>, + <112 0>, + <113 0>, + <114 0>, + <115 0>; + clocks = <&cpm FOCALTECH_CLOCK_EPORT4>; + resets = <&rctl FOCALTECH_RESET_EPORT4>; + mask = <0xff>; + ngpios = <8>; + status = "okay"; + }; + + eport5: eport@40027000 { + compatible = "focaltech,ft9001-eport", "focaltech,ft9001-gpio"; + gpio-controller; + #gpio-cells = <2>; + reg = <0x40027000 0x1000>; + interrupts = <116 0>, + <117 0>, + <118 0>, + <119 0>, + <120 0>, + <121 0>, + <122 0>, + <123 0>; + clocks = <&cpm FOCALTECH_CLOCK_EPORT5>; + resets = <&rctl FOCALTECH_RESET_EPORT5>; + mask = <0xff>; + ngpios = <8>; + status = "okay"; + }; + + eport6: eport@40028000 { + compatible = "focaltech,ft9001-eport", "focaltech,ft9001-gpio"; + gpio-controller; + #gpio-cells = <2>; + reg = <0x40028000 0x1000>; + interrupts = <124 0>, + <125 0>, + <126 0>, + <127 0>, + <128 0>, + <129 0>, + <130 0>, + <131 0>; + clocks = <&cpm FOCALTECH_CLOCK_EPORT6>; + resets = <&rctl FOCALTECH_RESET_EPORT6>; + mask = <0xff>; + ngpios = <8>; + status = "okay"; + }; + + eport7: eport@40029000 { + compatible = "focaltech,ft9001-eport", "focaltech,ft9001-gpio"; + gpio-controller; + #gpio-cells = <2>; + reg = <0x40029000 0x1000>; + interrupts = <132 0>, + <133 0>, + <134 0>, + <135 0>, + <136 0>, + <137 0>, + <138 0>, + <139 0>; + clocks = <&cpm FOCALTECH_CLOCK_EPORT7>; + resets = <&rctl FOCALTECH_RESET_EPORT7>; + mask = <0x3c>; + ngpios = <8>; + status = "okay"; + }; + + wdt0: watchdog@40005000 { + compatible = "focaltech,ft9001-wdt"; + reg = <0x40005000 0x1000>; + clocks = <&cpm FOCALTECH_CLOCK_WDT>; + resets = <&rctl FOCALTECH_RESET_WDT>; + status = "disabled"; + }; + + tc0: timer@40006000 { + compatible = "focaltech,ft9001-timer"; + reg = <0x40006000 0x1000>; + interrupts = <2 0>; + clocks = <&cpm FOCALTECH_CLOCK_TC>; + resets = <&rctl FOCALTECH_RESET_TC>; + status = "disabled"; + }; + }; +}; + +&nvic { + arm,num-irq-priority-bits = <3>; +}; From 8dc21030747fdac31849fcc83dd3f84f188e48af Mon Sep 17 00:00:00 2001 From: Robert Cheng Date: Tue, 21 Oct 2025 10:36:21 +0800 Subject: [PATCH 0611/3659] drivers: clock_control: focaltech: add ft9001 clock control driver Add clock control driver for the FocalTech FT9001 SoC. Signed-off-by: Robert Cheng --- drivers/clock_control/CMakeLists.txt | 1 + drivers/clock_control/Kconfig | 1 + drivers/clock_control/Kconfig.focaltech | 14 +++ drivers/clock_control/clock_control_ft9001.c | 102 +++++++++++++++++++ 4 files changed, 118 insertions(+) create mode 100644 drivers/clock_control/Kconfig.focaltech create mode 100644 drivers/clock_control/clock_control_ft9001.c diff --git a/drivers/clock_control/CMakeLists.txt b/drivers/clock_control/CMakeLists.txt index 94daa099509a..11667f22f112 100644 --- a/drivers/clock_control/CMakeLists.txt +++ b/drivers/clock_control/CMakeLists.txt @@ -74,6 +74,7 @@ zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_BOUFFALOLAB_BL61X clock_contro zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_BOUFFALOLAB_BL70X clock_control_bl70x.c) zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_ESP32 clock_control_esp32.c) zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_FIXED_RATE_CLOCK clock_control_fixed_rate.c) +zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_FOCALTECH_FT9001 clock_control_ft9001.c) zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_GD32 clock_control_gd32.c) zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_IFX_FIXED_CLOCK clock_control_infineon_fixed_clock.c) zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_IFX_FIXED_FACTOR_CLOCK clock_control_infineon_fixed_factor_clock.c) diff --git a/drivers/clock_control/Kconfig b/drivers/clock_control/Kconfig index 707959873578..7afb982a7abc 100644 --- a/drivers/clock_control/Kconfig +++ b/drivers/clock_control/Kconfig @@ -36,6 +36,7 @@ source "drivers/clock_control/Kconfig.bflb" source "drivers/clock_control/Kconfig.cavs" source "drivers/clock_control/Kconfig.esp32" source "drivers/clock_control/Kconfig.fixed" +source "drivers/clock_control/Kconfig.focaltech" source "drivers/clock_control/Kconfig.gd32" source "drivers/clock_control/Kconfig.infineon" source "drivers/clock_control/Kconfig.it51xxx" diff --git a/drivers/clock_control/Kconfig.focaltech b/drivers/clock_control/Kconfig.focaltech new file mode 100644 index 000000000000..650802511411 --- /dev/null +++ b/drivers/clock_control/Kconfig.focaltech @@ -0,0 +1,14 @@ +# Copyright (c) 2025, FocalTech Systems CO.,Ltd +# SPDX-License-Identifier: Apache-2.0 + +config CLOCK_CONTROL_FOCALTECH_FT9001 + bool "FocalTech FT9001 Clock Power Module (CPM) driver" + default y + depends on DT_HAS_FOCALTECH_FT9001_CPM_ENABLED + help + Enable clock control driver for FocalTech FT9001 SoC. + This driver provides support for controlling peripheral + clocks through the Clock Power Module (CPM) which manages + clock gating for various on-chip peripherals including + UART, SPI, I2C, CAN, USB, crypto engines, and memory + controllers. diff --git a/drivers/clock_control/clock_control_ft9001.c b/drivers/clock_control/clock_control_ft9001.c new file mode 100644 index 000000000000..a006758830e7 --- /dev/null +++ b/drivers/clock_control/clock_control_ft9001.c @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2025, FocalTech Systems CO.,Ltd + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT focaltech_ft9001_cpm + +#include +#include +#include +#include +#include + +/** Clock register offset (from encoded id) */ +#define FT9001_CLOCK_REG_OFFSET(id) (((id) >> FOCALTECH_CLOCK_SHIFT) & 0xFFFFU) +/** Clock control bit (from encoded id) */ +#define FT9001_CLOCK_BIT(id) ((id) & FOCALTECH_CLOCK_MASK) + +struct clock_control_ft9001_config { + uint32_t base; +}; + +/** + * @brief Enable a clock + * + * @param dev Clock control device + * @param sys Clock subsystem ID + * + * @retval 0 Always successful + */ +static int clock_control_ft9001_on(const struct device *dev, clock_control_subsys_t sys) +{ + const struct clock_control_ft9001_config *config = dev->config; + uint32_t id = POINTER_TO_UINT(sys); + uint32_t reg_offset = FT9001_CLOCK_REG_OFFSET(id); + uint32_t bit = FT9001_CLOCK_BIT(id); + volatile uint32_t *reg = (volatile uint32_t *)(config->base + reg_offset); + + *reg |= BIT(bit); + + return 0; +} + +/** + * @brief Disable a clock + * + * @param dev Clock control device + * @param sys Clock subsystem ID + * + * @retval 0 Always successful + */ +static int clock_control_ft9001_off(const struct device *dev, clock_control_subsys_t sys) +{ + const struct clock_control_ft9001_config *config = dev->config; + uint32_t id = POINTER_TO_UINT(sys); + uint32_t reg_offset = FT9001_CLOCK_REG_OFFSET(id); + uint32_t bit = FT9001_CLOCK_BIT(id); + volatile uint32_t *reg = (volatile uint32_t *)(config->base + reg_offset); + + *reg &= ~BIT(bit); + + return 0; +} + +/** + * @brief Get clock status + * + * @param dev Clock control device + * @param sys Clock subsystem ID + * + * @retval CLOCK_CONTROL_STATUS_ON if clock is enabled + * @retval CLOCK_CONTROL_STATUS_OFF if clock is disabled + */ +static enum clock_control_status clock_control_ft9001_get_status(const struct device *dev, + clock_control_subsys_t sys) +{ + const struct clock_control_ft9001_config *config = dev->config; + uint32_t id = POINTER_TO_UINT(sys); + uint32_t reg_offset = FT9001_CLOCK_REG_OFFSET(id); + uint32_t bit = FT9001_CLOCK_BIT(id); + volatile uint32_t *reg = (volatile uint32_t *)(config->base + reg_offset); + + if ((*reg & BIT(bit)) != 0) { + return CLOCK_CONTROL_STATUS_ON; + } + + return CLOCK_CONTROL_STATUS_OFF; +} + +static const struct clock_control_driver_api clock_control_ft9001_api = { + .on = clock_control_ft9001_on, + .off = clock_control_ft9001_off, + .get_status = clock_control_ft9001_get_status, +}; + +static const struct clock_control_ft9001_config ft9001_cpm_config = { + .base = DT_INST_REG_ADDR(0), +}; + +DEVICE_DT_INST_DEFINE(0, NULL, NULL, NULL, &ft9001_cpm_config, PRE_KERNEL_1, + CONFIG_CLOCK_CONTROL_INIT_PRIORITY, &clock_control_ft9001_api); From 384be5329dc29b87786d5e2024df7c5ffb178436 Mon Sep 17 00:00:00 2001 From: Robert Cheng Date: Tue, 21 Oct 2025 10:36:21 +0800 Subject: [PATCH 0612/3659] drivers: reset: focaltech: add ft9001 reset controller driver Add reset controller driver for the FocalTech FT9001 SoC. Signed-off-by: Robert Cheng --- drivers/reset/CMakeLists.txt | 1 + drivers/reset/Kconfig | 1 + drivers/reset/Kconfig.focaltech | 14 ++++ drivers/reset/reset_ft9001.c | 113 ++++++++++++++++++++++++++++++++ 4 files changed, 129 insertions(+) create mode 100644 drivers/reset/Kconfig.focaltech create mode 100644 drivers/reset/reset_ft9001.c diff --git a/drivers/reset/CMakeLists.txt b/drivers/reset/CMakeLists.txt index acfac9a896c1..b44038098b91 100644 --- a/drivers/reset/CMakeLists.txt +++ b/drivers/reset/CMakeLists.txt @@ -6,6 +6,7 @@ zephyr_library() # zephyr-keep-sorted-start zephyr_library_sources_ifdef(CONFIG_RESET_AST10X0 reset_ast10x0.c) +zephyr_library_sources_ifdef(CONFIG_RESET_FOCALTECH_FT9001 reset_ft9001.c) zephyr_library_sources_ifdef(CONFIG_RESET_GD32 reset_gd32.c) zephyr_library_sources_ifdef(CONFIG_RESET_INTEL_SOCFPGA reset_intel_socfpga.c) zephyr_library_sources_ifdef(CONFIG_RESET_MCHP_MSS reset_mchp_mss.c) diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index 0aa7ee70f0dc..268063b964b3 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -29,6 +29,7 @@ comment "Reset Controller Drivers" # zephyr-keep-sorted-start rsource "Kconfig.aspeed" +rsource "Kconfig.focaltech" rsource "Kconfig.gd32" rsource "Kconfig.intel_socfpga" rsource "Kconfig.lpc_syscon" diff --git a/drivers/reset/Kconfig.focaltech b/drivers/reset/Kconfig.focaltech new file mode 100644 index 000000000000..1ce18376ce57 --- /dev/null +++ b/drivers/reset/Kconfig.focaltech @@ -0,0 +1,14 @@ +# Copyright (c) 2025, FocalTech Systems CO.,Ltd +# SPDX-License-Identifier: Apache-2.0 + +config RESET_FOCALTECH_FT9001 + bool "FocalTech FT9001 Reset Control Module driver" + default y + depends on DT_HAS_FOCALTECH_FT9001_CPM_RCTL_ENABLED + help + Enable reset control driver for FocalTech FT9001 SoC. + This driver provides support for controlling peripheral + resets through the Reset Control Module which manages + reset signals for various on-chip peripherals including + UART, SPI, I2C, CAN, USB, crypto engines, and memory + controllers. diff --git a/drivers/reset/reset_ft9001.c b/drivers/reset/reset_ft9001.c new file mode 100644 index 000000000000..239a5c78f735 --- /dev/null +++ b/drivers/reset/reset_ft9001.c @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2025, FocalTech Systems CO.,Ltd + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT focaltech_ft9001_cpm_rctl + +#include +#include +#include +#include +#include + +/** Reset register offset (from encoded id) */ +#define FT9001_RESET_REG_OFFSET(id) (((id) >> FOCALTECH_RESET_SHIFT) & 0xFFFFU) +/** Reset control bit (from encoded id) */ +#define FT9001_RESET_BIT(id) ((id) & FOCALTECH_RESET_MASK) + +struct reset_ft9001_config { + uint32_t base; +}; + +/** + * @brief Get reset line status + * + * @param dev Reset controller device + * @param id Reset line ID + * @param status Pointer to store reset line status (0=deasserted, 1=asserted) + * + * @retval 0 Always successful + */ +static int reset_ft9001_status(const struct device *dev, uint32_t id, uint8_t *status) +{ + const struct reset_ft9001_config *config = dev->config; + uint32_t reg_offset = FT9001_RESET_REG_OFFSET(id); + uint32_t bit = FT9001_RESET_BIT(id); + volatile uint32_t *reg = (volatile uint32_t *)(config->base + reg_offset); + + *status = !!(*reg & BIT(bit)); + + return 0; +} + +/** + * @brief Assert a reset line + * + * @param dev Reset controller device + * @param id Reset line ID + * + * @retval 0 Always successful + */ +static int reset_ft9001_line_assert(const struct device *dev, uint32_t id) +{ + const struct reset_ft9001_config *config = dev->config; + uint32_t reg_offset = FT9001_RESET_REG_OFFSET(id); + uint32_t bit = FT9001_RESET_BIT(id); + volatile uint32_t *reg = (volatile uint32_t *)(config->base + reg_offset); + + *reg |= BIT(bit); + + return 0; +} + +/** + * @brief Deassert a reset line + * + * @param dev Reset controller device + * @param id Reset line ID + * + * @retval 0 Always successful + */ +static int reset_ft9001_line_deassert(const struct device *dev, uint32_t id) +{ + const struct reset_ft9001_config *config = dev->config; + uint32_t reg_offset = FT9001_RESET_REG_OFFSET(id); + uint32_t bit = FT9001_RESET_BIT(id); + volatile uint32_t *reg = (volatile uint32_t *)(config->base + reg_offset); + + *reg &= ~BIT(bit); + + return 0; +} + +/** + * @brief Toggle a reset line (assert then deassert) + * + * @param dev Reset controller device + * @param id Reset line ID + * + * @retval 0 Always successful + */ +static int reset_ft9001_line_toggle(const struct device *dev, uint32_t id) +{ + reset_ft9001_line_assert(dev, id); + reset_ft9001_line_deassert(dev, id); + + return 0; +} + +static const struct reset_driver_api reset_ft9001_driver_api = { + .status = reset_ft9001_status, + .line_assert = reset_ft9001_line_assert, + .line_deassert = reset_ft9001_line_deassert, + .line_toggle = reset_ft9001_line_toggle, +}; + +static const struct reset_ft9001_config ft9001_reset_config = { + .base = DT_REG_ADDR(DT_PARENT(DT_DRV_INST(0))), +}; + +DEVICE_DT_INST_DEFINE(0, NULL, NULL, NULL, &ft9001_reset_config, PRE_KERNEL_1, + CONFIG_RESET_INIT_PRIORITY, &reset_ft9001_driver_api); From 5e1d28b49ced5e9b8a3884263e2abd762201af9b Mon Sep 17 00:00:00 2001 From: Robert Cheng Date: Tue, 21 Oct 2025 10:36:21 +0800 Subject: [PATCH 0613/3659] drivers: serial: focaltech: add ft9001 serial driver Add the UART driver for the FocalTech FT9001 SoC. Signed-off-by: Robert Cheng --- drivers/serial/CMakeLists.txt | 1 + drivers/serial/Kconfig | 1 + drivers/serial/Kconfig.focaltech | 13 + drivers/serial/uart_ft9001.c | 602 +++++++++++++++++++++++++++++++ 4 files changed, 617 insertions(+) create mode 100644 drivers/serial/Kconfig.focaltech create mode 100644 drivers/serial/uart_ft9001.c diff --git a/drivers/serial/CMakeLists.txt b/drivers/serial/CMakeLists.txt index 0f558417d211..f19ada1ec867 100644 --- a/drivers/serial/CMakeLists.txt +++ b/drivers/serial/CMakeLists.txt @@ -38,6 +38,7 @@ zephyr_library_sources_ifdef(CONFIG_UART_EMUL uart_emul.c) zephyr_library_sources_ifdef(CONFIG_UART_ENE_KB106X uart_ene_kb106x.c) zephyr_library_sources_ifdef(CONFIG_UART_ENE_KB1200 uart_ene_kb1200.c) zephyr_library_sources_ifdef(CONFIG_UART_ESP32 uart_esp32.c) +zephyr_library_sources_ifdef(CONFIG_UART_FOCALTECH uart_ft9001.c) zephyr_library_sources_ifdef(CONFIG_UART_GECKO uart_gecko.c) zephyr_library_sources_ifdef(CONFIG_UART_HOSTLINK uart_hostlink.c) zephyr_library_sources_ifdef(CONFIG_UART_IMX uart_imx.c) diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index bdb34c100ecf..f9837c53bbaa 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -178,6 +178,7 @@ rsource "Kconfig.efinix_sapphire" rsource "Kconfig.emul" rsource "Kconfig.ene" rsource "Kconfig.esp32" +rsource "Kconfig.focaltech" rsource "Kconfig.gd32" rsource "Kconfig.gecko" rsource "Kconfig.hostlink" diff --git a/drivers/serial/Kconfig.focaltech b/drivers/serial/Kconfig.focaltech new file mode 100644 index 000000000000..4b6660ca7dbd --- /dev/null +++ b/drivers/serial/Kconfig.focaltech @@ -0,0 +1,13 @@ +# Copyright (c) 2025, FocalTech Systems CO.,Ltd +# SPDX-License-Identifier: Apache-2.0 + +config UART_FOCALTECH + bool "FocalTech FT9001 MCU serial driver" + default y + depends on DT_HAS_FOCALTECH_FT9001_USART_ENABLED + select SERIAL_HAS_DRIVER + select SERIAL_SUPPORT_INTERRUPT + select RESET + select CLOCK_CONTROL + help + Enable UART driver for FocalTech FT9001 SoC. diff --git a/drivers/serial/uart_ft9001.c b/drivers/serial/uart_ft9001.c new file mode 100644 index 000000000000..e18a844b4b9e --- /dev/null +++ b/drivers/serial/uart_ft9001.c @@ -0,0 +1,602 @@ +/* + * Copyright (c) 2025, FocalTech Systems Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT focaltech_ft9001_usart + +#include +#include +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(uart_ft9001, CONFIG_UART_LOG_LEVEL); + +/* Control Register 1 bits */ +#define SCICR1_PT_MASK 0x01 /* Parity type */ +#define SCICR1_PE_MASK 0x02 /* Parity enable */ +#define SCICR1_M_MASK 0x10 /* Frame length */ + +/* Control Register 2 bits */ +#define SCICR2_RE_MASK 0x04 /* Receiver enable */ +#define SCICR2_TE_MASK 0x08 /* Transmitter enable */ + +/* FIFO Control Register bits */ +#define SCIFCR_TFEN 0x40 /* TX FIFO enable */ +#define SCIFCR_RFEN 0x80 /* RX FIFO enable */ +#define SCIFCR_RXFLSEL_1_8 0x00 /* RX FIFO trigger level */ +#define SCIFCR_TXFLSEL_1_8 0x04 /* TX FIFO trigger level */ + +/* FIFO Control Register 2 bits */ +#define SCIFCR2_RXFCLR 0x01 /* RX FIFO clear */ +#define SCIFCR2_TXFCLR 0x02 /* TX FIFO clear */ +#define SCIFCR2_RXFTOE 0x04 /* RX FIFO timeout enable */ +#define SCIFCR2_RXFTOIE 0x08 /* RX FIFO timeout interrupt enable */ +#define SCIFCR2_RXORIE 0x10 /* RX overrun interrupt enable */ +#define SCIFCR2_RXFIE 0x20 /* RX FIFO interrupt enable */ +#define SCIFCR2_TXFIE 0x80 /* TX FIFO interrupt enable */ + +/* FIFO Status Register bits */ +#define SCIFSR_REMPTY_MASK 0x01 /* RX FIFO empty */ +#define SCIFSR_TEMPTY_MASK 0x04 /* TX FIFO empty */ +#define SCIFSR_TFULL_MASK 0x08 /* TX FIFO full */ +#define SCIFSR_RFTS_MASK 0x20 /* RX FIFO trigger level reached */ +#define SCIFSR_FTC_MASK 0x40 /* Frame transmission complete */ + +/* FIFO Status Register 2 bits */ +#define SCIFSR2_FXPF_MASK 0x01 /* Parity error */ +#define SCIFSR2_FXFE_MASK 0x02 /* Frame error */ +#define SCIFSR2_FXNF_MASK 0x04 /* Noise error */ +#define SCIFSR2_FXOR_MASK 0x08 /* FIFO overrun */ +#define SCIFSR2_W1C_MASK \ + (SCIFSR2_FXPF_MASK | SCIFSR2_FXFE_MASK | SCIFSR2_FXNF_MASK | SCIFSR2_FXOR_MASK) + +#define UART_DATA_FRAME_LEN_10BIT 0 +#define UART_DATA_FRAME_LEN_11BIT SCICR1_M_MASK + +#define SCIBDL_OFFSET 0x00 +#define SCIBDH_OFFSET 0x01 +#define SCICR2_OFFSET 0x02 +#define SCICR1_OFFSET 0x03 +#define SCIDRL_OFFSET 0x06 +#define SCIBRDF_OFFSET 0x0A +#define SCIFCR_OFFSET 0x0E +#define SCIFSR_OFFSET 0x11 +#define SCIFCR2_OFFSET 0x13 +#define SCIFSR2_OFFSET 0x15 + +struct uart_ft9001_config { + mm_reg_t base; + uint32_t clkid; + struct reset_dt_spec reset; +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + uart_irq_config_func_t irq_config_func; +#endif +}; + +struct uart_ft9001_data { + struct uart_config uart_cfg; +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + uart_irq_callback_user_data_t cb; + void *cb_data; +#endif +}; + +#define DEV_CFG(dev) ((const struct uart_ft9001_config *)(dev)->config) +#define DEV_DATA(dev) ((struct uart_ft9001_data *)(dev)->data) + +/** + * @brief Configure UART hardware + */ +static void uart_ft9001_hw_init(mm_reg_t base, const struct uart_config *cfg, uint32_t sys_freq) +{ + uint32_t scaled_baud; + uint16_t bauddiv_i; + uint8_t bauddiv_f; + uint8_t bauddiv_h; + uint8_t bauddiv_l; + uint8_t value; + + /* Calculate baud rate divisors */ + scaled_baud = (uint32_t)((sys_freq * 4u) / cfg->baudrate); + bauddiv_i = (uint16_t)(scaled_baud >> 6); + bauddiv_f = (uint8_t)((((scaled_baud << 1) + 1u) >> 1) & 0x3f); + bauddiv_h = (uint8_t)((bauddiv_i >> 8) & 0xff); + bauddiv_l = (uint8_t)(bauddiv_i & 0xff); + + /* Disable UART */ + sys_write8(0, base + SCICR2_OFFSET); + sys_write8(0, base + SCIFCR_OFFSET); + + /* Enable FIFO mode */ + sys_write8(SCIFCR_RFEN | SCIFCR_TFEN, base + SCIFCR_OFFSET); + + /* Set baud rate (write fraction before integer) */ + sys_write8(bauddiv_f, base + SCIBRDF_OFFSET); + sys_write8(bauddiv_h, base + SCIBDH_OFFSET); + sys_write8(bauddiv_l, base + SCIBDL_OFFSET); + + /* Configure frame format */ + value = 0; + + if (cfg->data_bits == UART_CFG_DATA_BITS_9) { + value |= UART_DATA_FRAME_LEN_11BIT; + } else { + value |= UART_DATA_FRAME_LEN_10BIT; + } + + /* Configure parity */ + if (cfg->parity != UART_CFG_PARITY_NONE) { + value |= SCICR1_PE_MASK; + + if (cfg->parity == UART_CFG_PARITY_ODD) { + value |= SCICR1_PT_MASK; + } + } + + sys_write8(value, base + SCICR1_OFFSET); + + /* Set FIFO waterlines */ + value = sys_read8(base + SCIFCR_OFFSET); + value |= (SCIFCR_RXFLSEL_1_8 | SCIFCR_TXFLSEL_1_8); + sys_write8(value, base + SCIFCR_OFFSET); + + /* Configure FIFO control 2 */ + value = (SCIFCR2_RXFTOE | SCIFCR2_RXFCLR | SCIFCR2_TXFCLR); + sys_write8(value, base + SCIFCR2_OFFSET); + + /* Clear status registers */ + sys_write8(SCIFSR2_W1C_MASK, base + SCIFSR2_OFFSET); + + /* Enable transmitter and receiver */ + value = sys_read8(base + SCICR2_OFFSET); + value |= (SCICR2_TE_MASK | SCICR2_RE_MASK); + sys_write8(value, base + SCICR2_OFFSET); +} + +/** + * @brief Initialize the UART device + */ +static int uart_ft9001_init(const struct device *dev) +{ + const struct device *clk = DEVICE_DT_GET(DT_NODELABEL(cpm)); + const struct uart_ft9001_config *config = DEV_CFG(dev); + struct uart_ft9001_data *data = DEV_DATA(dev); + uint32_t sys_freq; + uint8_t value; + int ret; + + /* Enable UART clock */ + ret = clock_control_on(clk, (clock_control_subsys_t *)(uintptr_t)config->clkid); + if (ret < 0) { + return ret; + } + + /* Get system frequency */ + ret = clock_control_get_rate(clk, (clock_control_subsys_t *)(uintptr_t)config->clkid, + &sys_freq); + if (ret < 0) { + sys_freq = 160000000 / 2; + } + + /* Toggle reset line */ + ret = reset_line_toggle_dt(&config->reset); + if (ret < 0) { + return ret; + } + + /* Initialize hardware */ + uart_ft9001_hw_init(config->base, &data->uart_cfg, sys_freq); + +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + /* Configure interrupts */ + config->irq_config_func(dev); + /* Initially disable all interrupts */ + value = sys_read8(config->base + SCIFCR2_OFFSET); + value &= ~(SCIFCR2_TXFIE | SCIFCR2_RXFIE | SCIFCR2_RXFTOIE | SCIFCR2_RXORIE); + sys_write8(value, config->base + SCIFCR2_OFFSET); +#endif + + return 0; +} + +/** + * @brief Read a character from UART (polling mode) + */ +static int uart_ft9001_poll_in(const struct device *dev, unsigned char *c) +{ + const struct uart_ft9001_config *config = DEV_CFG(dev); + + if (sys_read8(config->base + SCIFSR_OFFSET) & SCIFSR_REMPTY_MASK) { + return -1; /* No data available */ + } + + *c = sys_read8(config->base + SCIDRL_OFFSET); + + return 0; +} + +/** + * @brief Send a character via UART (polling mode) + */ +static void uart_ft9001_poll_out(const struct device *dev, unsigned char c) +{ + const struct uart_ft9001_config *config = DEV_CFG(dev); + uint8_t value; + + /* Wait for TX FIFO not full */ + while (sys_read8(config->base + SCIFSR_OFFSET) & SCIFSR_TFULL_MASK) { + /* Wait */ + } + + /* Send character */ + sys_write8(c, config->base + SCIDRL_OFFSET); + + /* Wait for transmission complete */ + while (1) { + value = sys_read8(config->base + SCIFSR_OFFSET); + if ((value & SCIFSR_TEMPTY_MASK) && (value & SCIFSR_FTC_MASK)) { + break; + } + } +} + +/** + * @brief Check for UART errors + */ +static int uart_ft9001_err_check(const struct device *dev) +{ + const struct uart_ft9001_config *config = DEV_CFG(dev); + uint8_t value; + int err = 0; + + /* Check error flags */ + value = sys_read8(config->base + SCIFSR2_OFFSET); + if (value & SCIFSR2_FXOR_MASK) { + err |= UART_ERROR_OVERRUN; + } + if (value & SCIFSR2_FXPF_MASK) { + err |= UART_ERROR_PARITY; + } + if (value & SCIFSR2_FXFE_MASK) { + err |= UART_ERROR_FRAMING; + } + if (value & SCIFSR2_FXNF_MASK) { + err |= UART_ERROR_NOISE; + } + + /* Clear error flags */ + sys_write8(value & SCIFSR2_W1C_MASK, config->base + SCIFSR2_OFFSET); + + return err; +} + +#ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE +/** + * @brief Configure UART parameters at runtime + */ +static int uart_ft9001_configure(const struct device *dev, const struct uart_config *cfg) +{ + const struct uart_ft9001_config *config = DEV_CFG(dev); + struct uart_ft9001_data *data = DEV_DATA(dev); + const struct device *clk = DEVICE_DT_GET(DT_NODELABEL(cpm)); + uint32_t sys_freq; + int ret; + + /* Validate configuration */ + if (cfg->stop_bits != UART_CFG_STOP_BITS_1) { + return -ENOTSUP; + } + if (cfg->data_bits != UART_CFG_DATA_BITS_8 && cfg->data_bits != UART_CFG_DATA_BITS_9) { + return -ENOTSUP; + } + if (cfg->flow_ctrl != UART_CFG_FLOW_CTRL_NONE) { + return -ENOTSUP; + } + + /* Get clock frequency */ + ret = clock_control_get_rate(clk, (clock_control_subsys_t *)(uintptr_t)config->clkid, + &sys_freq); + if (ret < 0) { + sys_freq = 160000000 / 2; + } + + /* Reconfigure hardware */ + uart_ft9001_hw_init(config->base, cfg, sys_freq); + + /* Update stored configuration */ + data->uart_cfg = *cfg; + + return 0; +} + +/** + * @brief Get current UART configuration + */ +static int uart_ft9001_config_get(const struct device *dev, struct uart_config *cfg) +{ + const struct uart_ft9001_data *data = DEV_DATA(dev); + + *cfg = data->uart_cfg; + return 0; +} +#endif /* CONFIG_UART_USE_RUNTIME_CONFIGURE */ + +#ifdef CONFIG_UART_INTERRUPT_DRIVEN +/** + * @brief Fill TX FIFO with data + */ +static int uart_ft9001_fifo_fill(const struct device *dev, const uint8_t *tx_data, int size) +{ + const struct uart_ft9001_config *config = DEV_CFG(dev); + int num_tx; + + for (num_tx = 0; num_tx < size; num_tx++) { + if (sys_read8(config->base + SCIFSR_OFFSET) & SCIFSR_TFULL_MASK) { + break; /* TX FIFO full */ + } + sys_write8(tx_data[num_tx], config->base + SCIDRL_OFFSET); + } + + return num_tx; +} + +/** + * @brief Read data from RX FIFO + */ +static int uart_ft9001_fifo_read(const struct device *dev, uint8_t *rx_data, const int size) +{ + const struct uart_ft9001_config *config = DEV_CFG(dev); + int i = 0; + + while (!(sys_read8(config->base + SCIFSR_OFFSET) & SCIFSR_REMPTY_MASK) && (i < size)) { + rx_data[i] = sys_read8(config->base + SCIDRL_OFFSET); + i++; + } + + return i; +} + +/** + * @brief Enable TX interrupt + */ +static void uart_ft9001_irq_tx_enable(const struct device *dev) +{ + const struct uart_ft9001_config *config = DEV_CFG(dev); + uint8_t value; + + value = sys_read8(config->base + SCIFCR2_OFFSET); + value |= SCIFCR2_TXFIE; + sys_write8(value, config->base + SCIFCR2_OFFSET); +} + +/** + * @brief Disable TX interrupt + */ +static void uart_ft9001_irq_tx_disable(const struct device *dev) +{ + const struct uart_ft9001_config *config = DEV_CFG(dev); + uint8_t value; + + value = sys_read8(config->base + SCIFCR2_OFFSET); + value &= ~SCIFCR2_TXFIE; + sys_write8(value, config->base + SCIFCR2_OFFSET); +} + +/** + * @brief Check if TX is ready + */ +static int uart_ft9001_irq_tx_ready(const struct device *dev) +{ + const struct uart_ft9001_config *config = DEV_CFG(dev); + uint8_t value; + + value = sys_read8(config->base + SCIFSR_OFFSET); + value &= SCIFSR_TFULL_MASK; + + return !value; +} + +/** + * @brief Enable RX interrupt + */ +static void uart_ft9001_irq_rx_enable(const struct device *dev) +{ + const struct uart_ft9001_config *config = DEV_CFG(dev); + uint8_t value; + + value = sys_read8(config->base + SCIFCR2_OFFSET); + value |= (SCIFCR2_RXFIE | SCIFCR2_RXFTOIE); + sys_write8(value, config->base + SCIFCR2_OFFSET); +} + +/** + * @brief Disable RX interrupt + */ +static void uart_ft9001_irq_rx_disable(const struct device *dev) +{ + const struct uart_ft9001_config *config = DEV_CFG(dev); + uint8_t value; + + value = sys_read8(config->base + SCIFCR2_OFFSET); + value &= ~(SCIFCR2_RXFIE | SCIFCR2_RXFTOIE); + sys_write8(value, config->base + SCIFCR2_OFFSET); +} + +/** + * @brief Check if TX is complete + */ +static int uart_ft9001_irq_tx_complete(const struct device *dev) +{ + const struct uart_ft9001_config *config = DEV_CFG(dev); + uint8_t value; + + value = sys_read8(config->base + SCIFSR_OFFSET); + + return ((value & SCIFSR_TEMPTY_MASK) && (value & SCIFSR_FTC_MASK)); +} + +/** + * @brief Check if RX data is ready + */ +static int uart_ft9001_irq_rx_ready(const struct device *dev) +{ + const struct uart_ft9001_config *config = DEV_CFG(dev); + uint8_t value; + + value = sys_read8(config->base + SCIFSR_OFFSET); + + return ((value & SCIFSR_RFTS_MASK) || !(value & SCIFSR_REMPTY_MASK)); +} + +/** + * @brief Enable error interrupt + */ +static void uart_ft9001_irq_err_enable(const struct device *dev) +{ + const struct uart_ft9001_config *config = DEV_CFG(dev); + uint8_t value; + + value = sys_read8(config->base + SCIFCR2_OFFSET); + value |= (SCIFCR2_RXORIE | SCIFCR2_RXFTOIE); + sys_write8(value, config->base + SCIFCR2_OFFSET); +} + +/** + * @brief Disable error interrupt + */ +static void uart_ft9001_irq_err_disable(const struct device *dev) +{ + const struct uart_ft9001_config *config = DEV_CFG(dev); + uint8_t value; + + value = sys_read8(config->base + SCIFCR2_OFFSET); + value &= ~(SCIFCR2_RXORIE | SCIFCR2_RXFTOIE); + sys_write8(value, config->base + SCIFCR2_OFFSET); +} + +/** + * @brief Check if interrupt is pending + */ +static int uart_ft9001_irq_is_pending(const struct device *dev) +{ + const struct uart_ft9001_config *config = DEV_CFG(dev); + uint8_t fsr, fcr2; + + fsr = sys_read8(config->base + SCIFSR_OFFSET); + fcr2 = sys_read8(config->base + SCIFCR2_OFFSET); + + /* Check if TX or RX interrupts are pending */ + return ((!(fsr & SCIFSR_TFULL_MASK) && (fcr2 & SCIFCR2_TXFIE)) || + (((fsr & SCIFSR_RFTS_MASK) || !(fsr & SCIFSR_REMPTY_MASK)) && + (fcr2 & SCIFCR2_RXFIE))); +} + +/** + * @brief Update interrupt status + */ +static int uart_ft9001_irq_update(const struct device *dev) +{ + return 1; +} + +/** + * @brief Set interrupt callback + */ +static void uart_ft9001_irq_callback_set(const struct device *dev, uart_irq_callback_user_data_t cb, + void *cb_data) +{ + struct uart_ft9001_data *data = DEV_DATA(dev); + + data->cb = cb; + data->cb_data = cb_data; +} + +/** + * @brief UART interrupt service routine + */ +static void uart_ft9001_isr(const struct device *dev) +{ + struct uart_ft9001_data *data = DEV_DATA(dev); + + if (data->cb) { + data->cb(dev, data->cb_data); + } +} + +#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ + +/* UART driver API structure */ +static const struct uart_driver_api uart_ft9001_driver_api = { + .poll_in = uart_ft9001_poll_in, + .poll_out = uart_ft9001_poll_out, + .err_check = uart_ft9001_err_check, +#ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE + .configure = uart_ft9001_configure, + .config_get = uart_ft9001_config_get, +#endif +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + .fifo_fill = uart_ft9001_fifo_fill, + .fifo_read = uart_ft9001_fifo_read, + .irq_tx_enable = uart_ft9001_irq_tx_enable, + .irq_tx_disable = uart_ft9001_irq_tx_disable, + .irq_tx_ready = uart_ft9001_irq_tx_ready, + .irq_rx_enable = uart_ft9001_irq_rx_enable, + .irq_rx_disable = uart_ft9001_irq_rx_disable, + .irq_tx_complete = uart_ft9001_irq_tx_complete, + .irq_rx_ready = uart_ft9001_irq_rx_ready, + .irq_err_enable = uart_ft9001_irq_err_enable, + .irq_err_disable = uart_ft9001_irq_err_disable, + .irq_is_pending = uart_ft9001_irq_is_pending, + .irq_update = uart_ft9001_irq_update, + .irq_callback_set = uart_ft9001_irq_callback_set, +#endif +}; + +#ifdef CONFIG_UART_INTERRUPT_DRIVEN +#define FOCALTECH_UART_IRQ_HANDLER(idx) \ + static void uart_ft9001_cfg_func_##idx(const struct device *dev) \ + { \ + IRQ_CONNECT(DT_INST_IRQN(idx), DT_INST_IRQ(idx, priority), uart_ft9001_isr, \ + DEVICE_DT_INST_GET(idx), 0); \ + irq_enable(DT_INST_IRQN(idx)); \ + } +#define FOCALTECH_UART_IRQ_HANDLER_FUNC_INIT(idx) .irq_config_func = uart_ft9001_cfg_func_##idx, +#else +#define FOCALTECH_UART_IRQ_HANDLER(idx) +#define FOCALTECH_UART_IRQ_HANDLER_FUNC_INIT(idx) +#endif + +/** + * @brief Macro to define a FocalTech FT9001 UART device instance + */ +#define UART_FOCALTECH_FT9001_DEVICE(idx) \ + FOCALTECH_UART_IRQ_HANDLER(idx) \ + \ + static struct uart_ft9001_data uart_ft9001_data_##idx = { \ + .uart_cfg = \ + { \ + .baudrate = DT_INST_PROP(idx, current_speed), \ + .parity = UART_CFG_PARITY_NONE, \ + .stop_bits = UART_CFG_STOP_BITS_1, \ + .data_bits = UART_CFG_DATA_BITS_8, \ + .flow_ctrl = UART_CFG_FLOW_CTRL_NONE, \ + }, \ + }; \ + \ + static const struct uart_ft9001_config uart_ft9001_cfg_##idx = { \ + .base = (mm_reg_t)DT_INST_REG_ADDR(idx), \ + .clkid = DT_INST_CLOCKS_CELL(idx, id), \ + .reset = RESET_DT_SPEC_INST_GET(idx), \ + FOCALTECH_UART_IRQ_HANDLER_FUNC_INIT(idx)}; \ + \ + DEVICE_DT_INST_DEFINE(idx, uart_ft9001_init, NULL, &uart_ft9001_data_##idx, \ + &uart_ft9001_cfg_##idx, PRE_KERNEL_1, CONFIG_SERIAL_INIT_PRIORITY, \ + (void *)&uart_ft9001_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(UART_FOCALTECH_FT9001_DEVICE); From 44dc69d323c3f0af603f7eb5715480523948eec9 Mon Sep 17 00:00:00 2001 From: Robert Cheng Date: Tue, 21 Oct 2025 10:36:20 +0800 Subject: [PATCH 0614/3659] boards: focaltech: ft9001_eval: add evaluation board MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add support for the FocalTech FT9001 evaluation board: - Board dts/dtsi and pinmux - defconfig and board.cmake - Basic documentation The board has been tested with the following Zephyr sample: – samples/hello_world Signed-off-by: Robert Cheng --- .../focaltech/ft9001_eval/Kconfig.ft9001_eval | 5 ++ boards/focaltech/ft9001_eval/board.cmake | 7 ++ boards/focaltech/ft9001_eval/board.yml | 6 ++ .../ft9001_eval/doc/ft9001_eval.webp | Bin 0 -> 28754 bytes boards/focaltech/ft9001_eval/doc/index.rst | 45 ++++++++++++ .../ft9001_eval/ft9001_eval-pinctrl.dtsi | 66 ++++++++++++++++++ boards/focaltech/ft9001_eval/ft9001_eval.dts | 54 ++++++++++++++ boards/focaltech/ft9001_eval/ft9001_eval.yaml | 12 ++++ .../ft9001_eval/ft9001_eval_defconfig | 10 +++ .../focaltech/ft9001_eval/support/openocd.cfg | 31 ++++++++ 10 files changed, 236 insertions(+) create mode 100644 boards/focaltech/ft9001_eval/Kconfig.ft9001_eval create mode 100644 boards/focaltech/ft9001_eval/board.cmake create mode 100644 boards/focaltech/ft9001_eval/board.yml create mode 100644 boards/focaltech/ft9001_eval/doc/ft9001_eval.webp create mode 100644 boards/focaltech/ft9001_eval/doc/index.rst create mode 100644 boards/focaltech/ft9001_eval/ft9001_eval-pinctrl.dtsi create mode 100644 boards/focaltech/ft9001_eval/ft9001_eval.dts create mode 100644 boards/focaltech/ft9001_eval/ft9001_eval.yaml create mode 100644 boards/focaltech/ft9001_eval/ft9001_eval_defconfig create mode 100644 boards/focaltech/ft9001_eval/support/openocd.cfg diff --git a/boards/focaltech/ft9001_eval/Kconfig.ft9001_eval b/boards/focaltech/ft9001_eval/Kconfig.ft9001_eval new file mode 100644 index 000000000000..34da2097ad19 --- /dev/null +++ b/boards/focaltech/ft9001_eval/Kconfig.ft9001_eval @@ -0,0 +1,5 @@ +# Copyright (c) 2025, FocalTech Systems CO.,Ltd +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_FT9001_EVAL + select SOC_FT9001 diff --git a/boards/focaltech/ft9001_eval/board.cmake b/boards/focaltech/ft9001_eval/board.cmake new file mode 100644 index 000000000000..d882a5aff90a --- /dev/null +++ b/boards/focaltech/ft9001_eval/board.cmake @@ -0,0 +1,7 @@ +# Copyright (c) 2025, FocalTech Systems CO.,Ltd +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(jlink "--device=FT9001" "--speed=4000") + +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/focaltech/ft9001_eval/board.yml b/boards/focaltech/ft9001_eval/board.yml new file mode 100644 index 000000000000..0c5e33a1c191 --- /dev/null +++ b/boards/focaltech/ft9001_eval/board.yml @@ -0,0 +1,6 @@ +board: + name: ft9001_eval + full_name: FocalTech FT9001 Evaluation Board + vendor: focaltech + socs: + - name: ft9001 diff --git a/boards/focaltech/ft9001_eval/doc/ft9001_eval.webp b/boards/focaltech/ft9001_eval/doc/ft9001_eval.webp new file mode 100644 index 0000000000000000000000000000000000000000..b7c6aaea7eb634b1b3a99d17b203cb813dd035a2 GIT binary patch literal 28754 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 N01j>6TI1jV001|9U&jCd literal 0 HcmV?d00001 diff --git a/boards/focaltech/ft9001_eval/doc/index.rst b/boards/focaltech/ft9001_eval/doc/index.rst new file mode 100644 index 000000000000..2cb3f1bcda27 --- /dev/null +++ b/boards/focaltech/ft9001_eval/doc/index.rst @@ -0,0 +1,45 @@ +:orphan: + +.. zephyr:board:: ft9001_eval + +Overview +******** + +The FT9001-EVAL board is an evaluation platform for the FocalTech FT9001 MCU +(Arm Cortex-M4F, up to 160 MHz). + +Hardware +******** + +- FocalTech FT9001 SoC (ARM Cortex-M4F compatible) +- 32 KB boot ROM +- 256 KB on-chip SRAM: + + - 224 KB standard SRAM + - 32 KB DBUS-connected SRAM + +- 2 MB external flash memory (SPI interface) +- 2x UART interfaces +- 2x SPI interfaces +- External GPIO pins with interrupt capability + +Supported Features +================== + +.. zephyr:board-supported-hw:: + +Programming and Debugging +************************* + +.. zephyr:board-supported-runners:: + +Flashing +======== + +Build and flash the :zephyr:code-sample:`hello_world` sample application: + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: ft9001_eval + :goals: build flash + :compact: diff --git a/boards/focaltech/ft9001_eval/ft9001_eval-pinctrl.dtsi b/boards/focaltech/ft9001_eval/ft9001_eval-pinctrl.dtsi new file mode 100644 index 000000000000..38d84c9c00ad --- /dev/null +++ b/boards/focaltech/ft9001_eval/ft9001_eval-pinctrl.dtsi @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2025, FocalTech Systems CO.,Ltd + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&pinctrl { + usart3_default: usart3_default { + group1 { + pinmux = , + ; + }; + + group2 { + pinmux = , + ; + }; + + group3 { + pinmux = , + ; + }; + }; + + gint40_default: gint40_default { + group1 { + pinmux = ; + }; + + group2 { + pinmux = ; + }; + }; + + gint41_default: gint41_default { + group1 { + pinmux = ; + }; + + group2 { + pinmux = ; + }; + }; + + gint42_default: gint42_default { + group1 { + pinmux = ; + }; + + group2 { + pinmux = ; + }; + }; + + gint43_default: gint43_default { + group1 { + pinmux = ; + }; + + group2 { + pinmux = ; + }; + }; +}; diff --git a/boards/focaltech/ft9001_eval/ft9001_eval.dts b/boards/focaltech/ft9001_eval/ft9001_eval.dts new file mode 100644 index 000000000000..64fca08709be --- /dev/null +++ b/boards/focaltech/ft9001_eval/ft9001_eval.dts @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2025, FocalTech Systems CO.,Ltd + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include "ft9001_eval-pinctrl.dtsi" +#include + +/ { + model = "FocalTech FT9001 Evaluation Board"; + compatible = "focaltech,ft9001-eval", "focaltech,ft9001"; + + chosen { + zephyr,console = &usart2; + zephyr,shell-uart = &usart2; + zephyr,flash = &flash0; + zephyr,sram = &sram0; + zephyr,sram2 = &sramd0; + zephyr,flash-controller = &flash_ctrl; + zephyr,code-partition = &app_partition; + }; +}; + +&flash0 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + romcfg_partition: partition@0 { + label = "romcfg"; + reg = <0x00000000 0x00001000>; + read-only; + }; + + app_partition: partition@1000 { + label = "app"; + reg = <0x00001000 0x001FF000>; + }; + }; +}; + +&usart2 { + current-speed = <115200>; + parity = "none"; + stop-bits = "1"; + data-bits = <8>; + hw-flow-control; + status = "okay"; +}; diff --git a/boards/focaltech/ft9001_eval/ft9001_eval.yaml b/boards/focaltech/ft9001_eval/ft9001_eval.yaml new file mode 100644 index 000000000000..18b062d4c590 --- /dev/null +++ b/boards/focaltech/ft9001_eval/ft9001_eval.yaml @@ -0,0 +1,12 @@ +identifier: ft9001_eval +name: FocalTech FT9001 Evaluation Board +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb +ram: 256 +flash: 2048 +supported: + - serial +vendor: focaltech diff --git a/boards/focaltech/ft9001_eval/ft9001_eval_defconfig b/boards/focaltech/ft9001_eval/ft9001_eval_defconfig new file mode 100644 index 000000000000..b45a1af7a7da --- /dev/null +++ b/boards/focaltech/ft9001_eval/ft9001_eval_defconfig @@ -0,0 +1,10 @@ +# Copyright (c) 2025, FocalTech Systems CO.,Ltd +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_ARM_MPU=y +CONFIG_HW_STACK_PROTECTION=y +CONFIG_SERIAL=y +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_UART_INTERRUPT_DRIVEN=y +CONFIG_USE_DT_CODE_PARTITION=y diff --git a/boards/focaltech/ft9001_eval/support/openocd.cfg b/boards/focaltech/ft9001_eval/support/openocd.cfg new file mode 100644 index 000000000000..a4225eeabcd7 --- /dev/null +++ b/boards/focaltech/ft9001_eval/support/openocd.cfg @@ -0,0 +1,31 @@ +# Copyright (c) 2025, FocalTech Systems CO.,Ltd +# SPDX-License-Identifier: Apache-2.0 + +# FT9001 OpenOCD Configuration +# +# This configuration supports debugging the FT9001 evaluation board +# using CMSIS-DAP compatible debuggers (such as DAPLink, J-Link, etc.) +# +# Usage: openocd -f boards/arm/ft9001_eval/support/openocd.cfg + +source [find interface/cmsis-dap.cfg] +transport select swd + +set CHIPNAME ft9001 +set CPUTAPID 0x790007a3 + +source [find target/stm32f4x.cfg] + +reset_config trst_and_srst separate + +# Configure target events for better debugging experience +$_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 +} From 7273479e43f9bbaf7d8f59a579369815da0ed6f3 Mon Sep 17 00:00:00 2001 From: Vincent Tardy Date: Fri, 10 Oct 2025 09:06:15 +0200 Subject: [PATCH 0615/3659] soc: st: stm32wba: hci_if: allow forcing ISR registration Add parameter to the link_layer_register_isr() to force or not the link layer isr registration in case of multiple function calls. This change fixes the interrupt service when resuming from a PM standby state. Update Bluetooth hci_stm32wba.c driver and IEEE 802.15.4 ieee802154_stm32wba.c driver accordingly. Signed-off-by: Vincent Tardy --- drivers/bluetooth/hci/hci_stm32wba.c | 4 ++-- drivers/ieee802154/ieee802154_stm32wba.c | 4 ++-- soc/st/stm32/stm32wbax/hci_if/linklayer_plat_adapt.c | 10 ++++++++-- soc/st/stm32/stm32wbax/hci_if/linklayer_plat_local.h | 6 +++++- 4 files changed, 17 insertions(+), 7 deletions(-) diff --git a/drivers/bluetooth/hci/hci_stm32wba.c b/drivers/bluetooth/hci/hci_stm32wba.c index c60e41bcbd58..6b847c80fec6 100644 --- a/drivers/bluetooth/hci/hci_stm32wba.c +++ b/drivers/bluetooth/hci/hci_stm32wba.c @@ -452,7 +452,7 @@ 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(); + link_layer_register_isr(false); ret = bt_ble_ctlr_init(); if (ret == 0) { @@ -563,7 +563,7 @@ static int radio_pm_action(const struct device *dev, enum pm_device_action actio #if defined(CONFIG_PM_S2RAM) if (LL_PWR_IsActiveFlag_SB() == 1U) { /* Put the radio in active state */ - link_layer_register_isr(); + link_layer_register_isr(true); } #endif /* CONFIG_PM_S2RAM */ LINKLAYER_PLAT_NotifyWFIExit(); diff --git a/drivers/ieee802154/ieee802154_stm32wba.c b/drivers/ieee802154/ieee802154_stm32wba.c index bab8f61c065a..5a5afdcdadbf 100644 --- a/drivers/ieee802154/ieee802154_stm32wba.c +++ b/drivers/ieee802154/ieee802154_stm32wba.c @@ -686,7 +686,7 @@ static void stm32wba_802154_iface_init(struct net_if *iface) .stm32wba_802154_ral_cbk_tx_ack_started = stm32wba_802154_tx_ack_started, }; - link_layer_register_isr(); + link_layer_register_isr(false); #if !defined(CONFIG_NET_L2_CUSTOM_IEEE802154_STM32WBA) ll_sys_thread_init(); @@ -995,7 +995,7 @@ static int radio_pm_action(const struct device *dev, enum pm_device_action actio if (LL_PWR_IsActiveFlag_SB() == 1U) { /* Put the radio in active state */ LL_AHB5_GRP1_EnableClock(LL_AHB5_GRP1_PERIPH_RADIO); - link_layer_register_isr(); + link_layer_register_isr(true); } LINKLAYER_PLAT_NotifyWFIExit(); ll_sys_dp_slp_exit(); diff --git a/soc/st/stm32/stm32wbax/hci_if/linklayer_plat_adapt.c b/soc/st/stm32/stm32wbax/hci_if/linklayer_plat_adapt.c index d091af938818..952b50156cd0 100644 --- a/soc/st/stm32/stm32wbax/hci_if/linklayer_plat_adapt.c +++ b/soc/st/stm32/stm32wbax/hci_if/linklayer_plat_adapt.c @@ -38,7 +38,6 @@ static uint32_t primask_bit; /* Radio SW low ISR global variable */ volatile uint8_t radio_sw_low_isr_is_running_high_prio; - void LINKLAYER_PLAT_DelayUs(uint32_t delay) { k_busy_wait(delay); @@ -96,8 +95,15 @@ void radio_low_prio_isr(void) } -void link_layer_register_isr(void) +void link_layer_register_isr(bool force) { + static bool is_isr_registered; + + if (!force && is_isr_registered) { + return; + } + is_isr_registered = true; + ARM_IRQ_DIRECT_DYNAMIC_CONNECT(RADIO_INTR_NUM, 0, 0, reschedule); /* Ensure the IRQ is disabled before enabling it at run time */ diff --git a/soc/st/stm32/stm32wbax/hci_if/linklayer_plat_local.h b/soc/st/stm32/stm32wbax/hci_if/linklayer_plat_local.h index 1cf621b89ded..92c1a08c7c59 100644 --- a/soc/st/stm32/stm32wbax/hci_if/linklayer_plat_local.h +++ b/soc/st/stm32/stm32wbax/hci_if/linklayer_plat_local.h @@ -8,6 +8,10 @@ #ifndef _STM32WBA_LINK_LAYER_PLAT_LOCAL_H_ #define _STM32WBA_LINK_LAYER_PLAT_LOCAL_H_ -void link_layer_register_isr(void); +/* + * @brief Link Layer ISR registration + * @param force: force ISR registration even if already done before + */ +void link_layer_register_isr(bool force); #endif /* _STM32WBA_LINK_LAYER_PLAT_LOCAL_H_ */ From f6fccc57e1e3952293d3035e1a9ad58a0bbe72e2 Mon Sep 17 00:00:00 2001 From: farsin NASAR V A Date: Wed, 26 Mar 2025 12:01:32 +0530 Subject: [PATCH 0616/3659] tests: drivers: dma: Added sam_e54 test support files Added sam_e54.overlay for dma test projects. Signed-off-by: farsin NASAR V A --- .../dma/chan_blen_transfer/boards/sam_e54_xpro.overlay | 9 +++++++++ tests/drivers/dma/chan_blen_transfer/testcase.yaml | 1 + .../dma/loop_transfer/boards/sam_e54_xpro.overlay | 9 +++++++++ 3 files changed, 19 insertions(+) create mode 100644 tests/drivers/dma/chan_blen_transfer/boards/sam_e54_xpro.overlay create mode 100644 tests/drivers/dma/loop_transfer/boards/sam_e54_xpro.overlay diff --git a/tests/drivers/dma/chan_blen_transfer/boards/sam_e54_xpro.overlay b/tests/drivers/dma/chan_blen_transfer/boards/sam_e54_xpro.overlay new file mode 100644 index 000000000000..904818666506 --- /dev/null +++ b/tests/drivers/dma/chan_blen_transfer/boards/sam_e54_xpro.overlay @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +tst_dma0: &dmac { + status = "okay"; +}; diff --git a/tests/drivers/dma/chan_blen_transfer/testcase.yaml b/tests/drivers/dma/chan_blen_transfer/testcase.yaml index fb8a89663978..e6ed619bfa6f 100644 --- a/tests/drivers/dma/chan_blen_transfer/testcase.yaml +++ b/tests/drivers/dma/chan_blen_transfer/testcase.yaml @@ -18,3 +18,4 @@ tests: filter: dt_nodelabel_enabled("tst_dma0") platform_allow: - nucleo_c031c6 + - sam_e54_xpro diff --git a/tests/drivers/dma/loop_transfer/boards/sam_e54_xpro.overlay b/tests/drivers/dma/loop_transfer/boards/sam_e54_xpro.overlay new file mode 100644 index 000000000000..904818666506 --- /dev/null +++ b/tests/drivers/dma/loop_transfer/boards/sam_e54_xpro.overlay @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +tst_dma0: &dmac { + status = "okay"; +}; From 2bfd1501284a611509cc69844c230a3b9e099f93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Wed, 10 Dec 2025 12:52:18 +0100 Subject: [PATCH 0617/3659] cmake: hwmv2: optimize hardware list parsing with CMake lists MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace inefficient string parsing loop with CMake list iteration for processing list_hardware.py output. The previous implementation used repeated string operations on the entire output string for each line, which is increasingly slow as hardware list grows. Local tests show hwmv2.cmake module loading in ~350 ms instead of 540 ms on my machine. Signed-off-by: Benjamin Cabé --- cmake/modules/hwm_v2.cmake | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/cmake/modules/hwm_v2.cmake b/cmake/modules/hwm_v2.cmake index e3d31dc696c9..41e0dec4d2fe 100644 --- a/cmake/modules/hwm_v2.cmake +++ b/cmake/modules/hwm_v2.cmake @@ -54,11 +54,13 @@ endif() set(kconfig_soc_source_dir) -while(TRUE) - string(FIND "${ret_hw}" "\n" idx REVERSE) - math(EXPR start "${idx} + 1") - string(SUBSTRING "${ret_hw}" ${start} -1 line) - string(SUBSTRING "${ret_hw}" 0 ${idx} ret_hw) +# Convert to list format (protecting existing semicolons) +string(REPLACE ";" "@@SEMICOLON@@" ret_hw_escaped "${ret_hw}") +string(REPLACE "\n" ";" hw_lines "${ret_hw_escaped}") +list(REVERSE hw_lines) + +foreach(line IN LISTS hw_lines) + string(REPLACE "@@SEMICOLON@@" ";" line "${line}") cmake_parse_arguments(HWM "" "TYPE" "" ${line}) if(HWM_TYPE STREQUAL "arch") @@ -87,11 +89,7 @@ while(TRUE) set(SOC_${HWM_TYPE_UPPER}_${SOC_V2_NAME_UPPER}_DIR ${SOC_V2_DIR}) endif() endif() - - if(idx EQUAL -1) - break() - endif() -endwhile() +endforeach() list(REMOVE_DUPLICATES kconfig_soc_source_dir) # Support multiple ARCH_ROOT, SOC_ROOT and BOARD_ROOT From e6226da7348b863e01449f492d889107d562625a Mon Sep 17 00:00:00 2001 From: Fabrice DJIATSA Date: Tue, 16 Dec 2025 10:47:08 +0100 Subject: [PATCH 0618/3659] boards: st: stm32_f3_disco: add zephyr dtcm chosen property In the STM32F3 series, the CCM RAM can interface with the Arm Cortex-M4 core via the I-BUS, which makes it possible to run the vector table relocation test. See Refman 0316 Page 50. Signed-off-by: Fabrice DJIATSA --- boards/st/stm32f3_disco/stm32f3_disco.dts | 1 + 1 file changed, 1 insertion(+) diff --git a/boards/st/stm32f3_disco/stm32f3_disco.dts b/boards/st/stm32f3_disco/stm32f3_disco.dts index 854a221ecd2f..32afc828d991 100644 --- a/boards/st/stm32f3_disco/stm32f3_disco.dts +++ b/boards/st/stm32f3_disco/stm32f3_disco.dts @@ -20,6 +20,7 @@ zephyr,flash = &flash0; zephyr,code-partition = &slot0_partition; zephyr,canbus = &can1; + zephyr,dtcm = &ccm0; }; leds { From 6d17ab8058ee210c68fe52eaee3fe7162a43fdf7 Mon Sep 17 00:00:00 2001 From: Fabrice DJIATSA Date: Mon, 15 Dec 2025 15:00:30 +0100 Subject: [PATCH 0619/3659] test: app_development: vector_table_relocation: exclude stm32f4 serie The vector_table_relocation.dtcm test assumes that the vector table can be relocated to a DTCM region and executed from there. However, on STM32F4 (Cortex-M4),this is not possible due to architectural constraints. The CCM RAM on STM32F4 series is connected via the D-bus, not the ICode bus, and therefore cannot serve as an executable boot space for the vector table. Signed-off-by: Fabrice DJIATSA --- .../vector_table_relocation/testcase.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/application_development/vector_table_relocation/testcase.yaml b/tests/application_development/vector_table_relocation/testcase.yaml index 75fd51d4548d..20071387397e 100644 --- a/tests/application_development/vector_table_relocation/testcase.yaml +++ b/tests/application_development/vector_table_relocation/testcase.yaml @@ -14,7 +14,11 @@ tests: application_development.vector_table_relocation.dtcm: arch_allow: arm + # Exclude STM32F4 series due to architectural constraints. STM32F4 CCM is only accessible + # over the D-bus but exception vectors are fetched over the I-bus. + # As such, the vector table can't be relocated to CCM. filter: CONFIG_CPU_CORTEX_M_HAS_VTOR and dt_chosen_enabled("zephyr,dtcm") + and not CONFIG_SOC_SERIES_STM32F4X extra_configs: - CONFIG_ARM_VECTOR_TABLE_DTCM=y From ba84bfea3c04b1979488e896ce61f8bdef0c3eab Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Tue, 16 Dec 2025 10:18:07 +0100 Subject: [PATCH 0620/3659] usb: legacy: Fix net API use In c52c206e26f90df85eceafd7dbbebaae5066c753 this code was changed to use the Zephyr native net_ prefixed API, but some were forgotten (ntohs()). Let's change it now. Without this fix/change the code still builds as we are by now setting CONFIG_NET_NAMESPACE_COMPAT_MODE. But when this is not set, things fail to build. Signed-off-by: Alberto Escolar Piedras --- subsys/usb/device/class/netusb/function_ecm.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/subsys/usb/device/class/netusb/function_ecm.c b/subsys/usb/device/class/netusb/function_ecm.c index a90ac3883ac5..b7dae81d8312 100644 --- a/subsys/usb/device/class/netusb/function_ecm.c +++ b/subsys/usb/device/class/netusb/function_ecm.c @@ -227,13 +227,13 @@ static size_t ecm_eth_size(void *ecm_pkt, size_t len) return 0; } - switch (ntohs(hdr->type)) { + switch (net_ntohs(hdr->type)) { case NET_ETH_PTYPE_IP: case NET_ETH_PTYPE_ARP: - ip_len = ntohs(((struct net_ipv4_hdr *)ip_data)->len); + ip_len = net_ntohs(((struct net_ipv4_hdr *)ip_data)->len); break; case NET_ETH_PTYPE_IPV6: - ip_len = ntohs(((struct net_ipv6_hdr *)ip_data)->len); + ip_len = net_ntohs(((struct net_ipv6_hdr *)ip_data)->len); break; default: LOG_DBG("Unknown hdr type 0x%04x", hdr->type); From b5709a3cf43b5607f64e12d32447622b94321eba Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Tue, 16 Dec 2025 10:20:59 +0100 Subject: [PATCH 0621/3659] usb: next: Fix net API use In 32059d74142487935562408379ec3658387cd163 this code was changed to use the Zephyr native net_ prefixed API, but some were forgotten (ntohs()). Let's change it now. Without this fix/change the code still builds as we are by now setting CONFIG_NET_NAMESPACE_COMPAT_MODE. But when this is not set, things fail to build. Signed-off-by: Alberto Escolar Piedras --- subsys/usb/device_next/class/usbd_cdc_ecm.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/subsys/usb/device_next/class/usbd_cdc_ecm.c b/subsys/usb/device_next/class/usbd_cdc_ecm.c index 3aac3aefd3d1..d749ca6f538e 100644 --- a/subsys/usb/device_next/class/usbd_cdc_ecm.c +++ b/subsys/usb/device_next/class/usbd_cdc_ecm.c @@ -184,14 +184,14 @@ static size_t ecm_eth_size(void *const ecm_pkt, const size_t len) return 0; } - switch (ntohs(hdr->type)) { + switch (net_ntohs(hdr->type)) { case NET_ETH_PTYPE_IP: __fallthrough; case NET_ETH_PTYPE_ARP: - ip_len = ntohs(((struct net_ipv4_hdr *)ip_data)->len); + ip_len = net_ntohs(((struct net_ipv4_hdr *)ip_data)->len); break; case NET_ETH_PTYPE_IPV6: - ip_len = ntohs(((struct net_ipv6_hdr *)ip_data)->len); + ip_len = net_ntohs(((struct net_ipv6_hdr *)ip_data)->len); break; default: LOG_DBG("Unknown hdr type 0x%04x", hdr->type); From 18bf241ec48f9bc1274ee99ab94c552b4787caad Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Tue, 16 Dec 2025 10:22:20 +0100 Subject: [PATCH 0622/3659] usb: host: usbip: Fix net API use In c52c206e26f90df85eceafd7dbbebaae5066c753 & 32059d74142487935562408379ec3658387cd163 the USB code was changed to use the Zephyr native net_ prefixed API, but some were forgotten (nto[hn][ls]()). Let's change it now. Without this fix/change the code still builds as we are by now setting CONFIG_NET_NAMESPACE_COMPAT_MODE. But when this is not set, things fail to build. Signed-off-by: Alberto Escolar Piedras --- subsys/usb/host/usbip.c | 90 ++++++++++++++++++++--------------------- 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/subsys/usb/host/usbip.c b/subsys/usb/host/usbip.c index fc6072c65bad..91e1d414843c 100644 --- a/subsys/usb/host/usbip.c +++ b/subsys/usb/host/usbip.c @@ -68,20 +68,20 @@ K_MEM_SLAB_DEFINE(usbip_slab, sizeof(struct usbip_cmd_node), static void usbip_ntoh_command(struct usbip_command *const cmd) { - cmd->hdr.command = ntohl(cmd->hdr.command); - cmd->hdr.seqnum = ntohl(cmd->hdr.seqnum); - cmd->hdr.devid = ntohl(cmd->hdr.devid); - cmd->hdr.direction = ntohl(cmd->hdr.direction); - cmd->hdr.ep = ntohl(cmd->hdr.ep); + cmd->hdr.command = net_ntohl(cmd->hdr.command); + cmd->hdr.seqnum = net_ntohl(cmd->hdr.seqnum); + cmd->hdr.devid = net_ntohl(cmd->hdr.devid); + cmd->hdr.direction = net_ntohl(cmd->hdr.direction); + cmd->hdr.ep = net_ntohl(cmd->hdr.ep); if (cmd->hdr.command == USBIP_CMD_SUBMIT) { - cmd->submit.flags = ntohl(cmd->submit.flags); - cmd->submit.length = ntohl(cmd->submit.length); - cmd->submit.start_frame = ntohl(cmd->submit.start_frame); - cmd->submit.numof_iso_pkts = ntohl(cmd->submit.numof_iso_pkts); - cmd->submit.interval = ntohl(cmd->submit.interval); + cmd->submit.flags = net_ntohl(cmd->submit.flags); + cmd->submit.length = net_ntohl(cmd->submit.length); + cmd->submit.start_frame = net_ntohl(cmd->submit.start_frame); + cmd->submit.numof_iso_pkts = net_ntohl(cmd->submit.numof_iso_pkts); + cmd->submit.interval = net_ntohl(cmd->submit.interval); } else { - cmd->unlink.seqnum = ntohl(cmd->unlink.seqnum); + cmd->unlink.seqnum = net_ntohl(cmd->unlink.seqnum); } } @@ -130,16 +130,16 @@ static int usbip_req_cb(struct usb_device *const udev, struct uhc_transfer *cons LOG_INF("SUBMIT seqnum %u finished err %d ep 0x%02x", cmd->hdr.seqnum, xfer->err, xfer->ep); - ret.hdr.command = htonl(USBIP_RET_SUBMIT); - ret.hdr.seqnum = htonl(cmd->hdr.seqnum); - ret.hdr.devid = htonl(cmd->hdr.devid); - ret.hdr.ep = htonl(xfer->ep); - ret.hdr.direction = htonl(cmd->hdr.direction); + ret.hdr.command = net_htonl(USBIP_RET_SUBMIT); + ret.hdr.seqnum = net_htonl(cmd->hdr.seqnum); + ret.hdr.devid = net_htonl(cmd->hdr.devid); + ret.hdr.ep = net_htonl(xfer->ep); + ret.hdr.direction = net_htonl(cmd->hdr.direction); memset(&ret.submit, 0, sizeof(ret.submit)); - ret.submit.status = htonl(xfer->err); - ret.submit.start_frame = htonl(cmd->submit.start_frame); - ret.submit.numof_iso_pkts = htonl(0xFFFFFFFFUL); + ret.submit.status = net_htonl(xfer->err); + ret.submit.start_frame = net_htonl(cmd->submit.start_frame); + ret.submit.numof_iso_pkts = net_htonl(0xFFFFFFFFUL); if (xfer->err == -ECONNRESET) { LOG_INF("URB seqnum %u unlinked (ECONNRESET)", cmd->hdr.seqnum); @@ -152,9 +152,9 @@ static int usbip_req_cb(struct usb_device *const udev, struct uhc_transfer *cons if (xfer->err == 0 && cmd->submit.length != 0) { if (USB_EP_DIR_IS_IN(xfer->ep)) { - ret.submit.actual_length = htonl(buf->len); + ret.submit.actual_length = net_htonl(buf->len); } else { - ret.submit.actual_length = htonl(cmd->submit.length); + ret.submit.actual_length = net_htonl(cmd->submit.length); } } @@ -337,7 +337,7 @@ static int usbip_handle_unlink(struct usbip_dev_ctx *const dev_ctx, } memcpy(&rsp.hdr, &cmd->hdr, sizeof(rsp.hdr)); - rsp.hdr.command = htonl(USBIP_RET_UNLINK); + rsp.hdr.command = net_htonl(USBIP_RET_UNLINK); usbip_ntoh_command(cmd); @@ -349,7 +349,7 @@ static int usbip_handle_unlink(struct usbip_dev_ctx *const dev_ctx, key = irq_lock(); SYS_DLIST_FOR_EACH_CONTAINER(&dev_ctx->dlist, cmd_nd, node) { if (cmd_nd->cmd.hdr.seqnum == cmd->unlink.seqnum) { - rsp.unlink.status = htonl(-ECONNRESET); + rsp.unlink.status = net_htonl(-ECONNRESET); usbh_xfer_dequeue(dev_ctx->udev, cmd_nd->xfer); break; } @@ -376,7 +376,7 @@ static int usbip_handle_cmd(struct usbip_dev_ctx *const dev_ctx) LOG_HEXDUMP_DBG((uint8_t *)&cmd.hdr, sizeof(cmd.hdr), "cmd.hdr"); - switch (ntohl(cmd.hdr.command)) { + switch (net_ntohl(cmd.hdr.command)) { case USBIP_CMD_SUBMIT: ret = usbip_handle_submit(dev_ctx, &cmd); break; @@ -384,7 +384,7 @@ static int usbip_handle_cmd(struct usbip_dev_ctx *const dev_ctx) ret = usbip_handle_unlink(dev_ctx, &cmd); break; default: - LOG_ERR("Unknown command: 0x%x", ntohl(cmd.hdr.command)); + LOG_ERR("Unknown command: 0x%x", net_ntohl(cmd.hdr.command)); break; } @@ -420,13 +420,13 @@ static int handle_devlist_device(struct usb_device *const udev, const uint32_t devnum = udev->addr; int err; - devlist.busnum = htonl(busnum); - devlist.devnum = htonl(devnum); + devlist.busnum = net_htonl(busnum); + devlist.devnum = net_htonl(devnum); - devlist.speed = htonl(udev->speed); - devlist.idVendor = htons(d_desc->idVendor); - devlist.idProduct = htons(d_desc->idProduct); - devlist.bcdDevice = htons(d_desc->bcdDevice); + devlist.speed = net_htonl(udev->speed); + devlist.idVendor = net_htons(d_desc->idVendor); + devlist.idProduct = net_htons(d_desc->idProduct); + devlist.bcdDevice = net_htons(d_desc->bcdDevice); devlist.bDeviceClass = d_desc->bDeviceClass; devlist.bDeviceSubClass = d_desc->bDeviceSubClass; devlist.bDeviceProtocol = d_desc->bDeviceProtocol; @@ -487,10 +487,10 @@ static int handle_devlist_device_iface(struct usb_device *const udev, int connfd static int usbip_handle_devlist(struct usbip_bus_ctx *const bus_ctx, int connfd) { struct usbip_devlist_header rep_hdr = { - .version = htons(USBIP_VERSION), - .code = htons(USBIP_OP_REP_DEVLIST), + .version = net_htons(USBIP_VERSION), + .code = net_htons(USBIP_OP_REP_DEVLIST), .status = 0, - .ndev = htonl(1), + .ndev = net_htonl(1), }; struct usb_device *udev; uint32_t ndev = 0; @@ -500,7 +500,7 @@ static int usbip_handle_devlist(struct usbip_bus_ctx *const bus_ctx, int connfd) ndev++; } - rep_hdr.ndev = htonl(ndev); + rep_hdr.ndev = net_htonl(ndev); /* Send reply header with the number of USB devices */ err = zsock_send(connfd, &rep_hdr, sizeof(rep_hdr), 0); if (err != sizeof(rep_hdr)) { @@ -565,8 +565,8 @@ static struct usbip_dev_ctx *get_free_dev_ctx(struct usbip_bus_ctx *const bus_ct static int usbip_handle_import(struct usbip_bus_ctx *const bus_ctx, int connfd) { struct usbip_req_header rep_hdr = { - .version = htons(USBIP_VERSION), - .code = htons(USBIP_OP_REP_IMPORT), + .version = net_htons(USBIP_VERSION), + .code = net_htons(USBIP_OP_REP_IMPORT), .status = 0, }; struct usbip_dev_ctx *dev_ctx; @@ -580,12 +580,12 @@ static int usbip_handle_import(struct usbip_bus_ctx *const bus_ctx, int connfd) dev_ctx = get_free_dev_ctx(bus_ctx); if (dev_ctx == NULL) { - rep_hdr.status = htonl(-1); + rep_hdr.status = net_htonl(-1); LOG_ERR("No free device context to export a device"); } else { dev_ctx->udev = get_device_by_busid(bus_ctx, busid); if (dev_ctx->udev == NULL) { - rep_hdr.status = htonl(-1); + rep_hdr.status = net_htonl(-1); dev_ctx = NULL; LOG_ERR("No USB device with busid %s", busid); } @@ -624,9 +624,9 @@ static int usbip_handle_connection(struct usbip_bus_ctx *const bus_ctx, int conn } LOG_HEXDUMP_DBG((uint8_t *)&hdr, sizeof(hdr), "header"); - LOG_INF("Code: 0x%x", ntohs(hdr.code)); + LOG_INF("Code: 0x%x", net_ntohs(hdr.code)); - switch (ntohs(hdr.code)) { + switch (net_ntohs(hdr.code)) { case USBIP_OP_REQ_DEVLIST: ret = usbip_handle_devlist(bus_ctx, connfd); zsock_close(connfd); @@ -638,7 +638,7 @@ static int usbip_handle_connection(struct usbip_bus_ctx *const bus_ctx, int conn } break; default: - LOG_ERR("Unknown request: 0x%x", ntohs(hdr.code)); + LOG_ERR("Unknown request: 0x%x", net_ntohs(hdr.code)); ret = -1; break; } @@ -668,8 +668,8 @@ static void usbip_thread_handler(void *const a, void *const b, void *const c) } srv.sin_family = NET_AF_INET; - srv.sin_addr.s_addr = htonl(NET_INADDR_ANY); - srv.sin_port = htons(USBIP_PORT); + srv.sin_addr.s_addr = net_htonl(NET_INADDR_ANY); + srv.sin_port = net_htons(USBIP_PORT); if (zsock_bind(listenfd, (struct net_sockaddr *)&srv, sizeof(srv)) < 0) { LOG_ERR("bind() failed: %s", strerror(errno)); @@ -683,7 +683,7 @@ static void usbip_thread_handler(void *const a, void *const b, void *const c) while (true) { struct net_sockaddr_in client_addr; - socklen_t client_addr_len = sizeof(client_addr); + net_socklen_t client_addr_len = sizeof(client_addr); char addr_str[NET_INET_ADDRSTRLEN]; int err; From 89c3443a4d532648dca74c0b942bc6b05dcfe7a8 Mon Sep 17 00:00:00 2001 From: Jaagup Averin Date: Tue, 16 Dec 2025 12:53:00 +0200 Subject: [PATCH 0623/3659] dts: arm: st: f2: add adc2 and adc3 Add missing ADC2 and ADC3 nodes to stm32f2.dtsi. Signed-off-by: Jaagup Averin --- dts/arm/st/f2/stm32f2.dtsi | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/dts/arm/st/f2/stm32f2.dtsi b/dts/arm/st/f2/stm32f2.dtsi index 9d3b53f96a1a..03ea58a55f42 100644 --- a/dts/arm/st/f2/stm32f2.dtsi +++ b/dts/arm/st/f2/stm32f2.dtsi @@ -388,6 +388,44 @@ status = "disabled"; }; + adc2: adc@40012100 { + compatible = "st,stm32f4-adc", "st,stm32-adc"; + reg = <0x40012100 0x50>; + clocks = <&rcc STM32_CLOCK(APB2, 9)>; + clock-names = "adcx"; + interrupts = <18 0>; + #io-channel-cells = <1>; + resolutions = ; + sampling-times = <3 15 28 58 84 112 144 480>; + st,adc-clock-source = "SYNC"; + st,adc-sequencer = "programmable"; + st,adc-oversampler = "none"; + st,adc-internal-regulator = "none"; + status = "disabled"; + }; + + adc3: adc@40012200 { + compatible = "st,stm32f4-adc", "st,stm32-adc"; + reg = <0x40012200 0x50>; + clocks = <&rcc STM32_CLOCK(APB2, 10)>; + clock-names = "adcx"; + interrupts = <18 0>; + #io-channel-cells = <1>; + resolutions = ; + sampling-times = <3 15 28 58 84 112 144 480>; + st,adc-clock-source = "SYNC"; + st,adc-sequencer = "programmable"; + st,adc-oversampler = "none"; + st,adc-internal-regulator = "none"; + status = "disabled"; + }; + dma1: dma@40026000 { compatible = "st,stm32-dma-v1"; #dma-cells = <4>; From 455a0436e5e9c00ad2a2213b26d17aad7a69c70b Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Tue, 16 Dec 2025 11:29:02 +0100 Subject: [PATCH 0624/3659] net: zperf: Fix net API use In d45cd6716bbab3a805e3a5fd461934f0dcdc13e5 the mayority of the Zephyr codebased was changed to use the Zephyr native net_ prefixed types, but some were forgotten. Without this fix/change the code still builds as we are by now setting CONFIG_NET_NAMESPACE_COMPAT_MODE. But when this is not set, things fail to build. Signed-off-by: Alberto Escolar Piedras --- subsys/net/lib/zperf/zperf_common.c | 2 +- subsys/net/lib/zperf/zperf_shell.c | 2 +- subsys/net/lib/zperf/zperf_tcp_receiver.c | 16 ++++++++-------- subsys/net/lib/zperf/zperf_udp_receiver.c | 12 ++++++------ subsys/net/lib/zperf/zperf_udp_uploader.c | 6 +++--- 5 files changed, 19 insertions(+), 19 deletions(-) diff --git a/subsys/net/lib/zperf/zperf_common.c b/subsys/net/lib/zperf/zperf_common.c index d90ea56080e4..86e19ec761cf 100644 --- a/subsys/net/lib/zperf/zperf_common.c +++ b/subsys/net/lib/zperf/zperf_common.c @@ -240,7 +240,7 @@ int zperf_prepare_upload_sock(const struct net_sockaddr *peer_addr, uint8_t tos, goto error; } - if (zsock_setsockopt(sock, SOL_SOCKET, SO_PRIORITY, + if (zsock_setsockopt(sock, ZSOCK_SOL_SOCKET, ZSOCK_SO_PRIORITY, &prio, sizeof(prio)) != 0) { NET_WARN("Failed to set SOL_SOCKET - SO_PRIORITY socket option."); diff --git a/subsys/net/lib/zperf/zperf_shell.c b/subsys/net/lib/zperf/zperf_shell.c index 6ab73c10cfce..0452ada18cb2 100644 --- a/subsys/net/lib/zperf/zperf_shell.c +++ b/subsys/net/lib/zperf/zperf_shell.c @@ -230,7 +230,7 @@ static int zperf_bind_host(const struct shell *sh, return ret; } - memcpy(¶m->addr, &addr, sizeof(struct sockaddr)); + memcpy(¶m->addr, &addr, sizeof(struct net_sockaddr)); } return 0; diff --git a/subsys/net/lib/zperf/zperf_tcp_receiver.c b/subsys/net/lib/zperf/zperf_tcp_receiver.c index e1907c9c5f49..a3bdb19046ec 100644 --- a/subsys/net/lib/zperf/zperf_tcp_receiver.c +++ b/subsys/net/lib/zperf/zperf_tcp_receiver.c @@ -136,10 +136,10 @@ static int tcp_recv_data(struct net_socket_service_event *pev) if ((pev->event.revents & ZSOCK_POLLERR) || (pev->event.revents & ZSOCK_POLLNVAL)) { - (void)zsock_getsockopt(pev->event.fd, SOL_SOCKET, - SO_DOMAIN, &family, &optlen); - (void)zsock_getsockopt(pev->event.fd, SOL_SOCKET, - SO_ERROR, &sock_error, &optlen); + (void)zsock_getsockopt(pev->event.fd, ZSOCK_SOL_SOCKET, + ZSOCK_SO_DOMAIN, &family, &optlen); + (void)zsock_getsockopt(pev->event.fd, ZSOCK_SOL_SOCKET, + ZSOCK_SO_ERROR, &sock_error, &optlen); NET_ERR("TCP receiver IPv%d socket error (%d)", family == NET_AF_INET ? 4 : 6, sock_error); ret = -sock_error; @@ -161,8 +161,8 @@ static int tcp_recv_data(struct net_socket_service_event *pev) &addrlen); if (sock < 0) { ret = -errno; - (void)zsock_getsockopt(pev->event.fd, SOL_SOCKET, - SO_DOMAIN, &family, &optlen); + (void)zsock_getsockopt(pev->event.fd, ZSOCK_SOL_SOCKET, + ZSOCK_SO_DOMAIN, &family, &optlen); NET_ERR("TCP receiver IPv%d accept error (%d)", family == NET_AF_INET ? 4 : 6, ret); goto error; @@ -191,8 +191,8 @@ static int tcp_recv_data(struct net_socket_service_event *pev) } else { ret = zsock_recv(pev->event.fd, buf, sizeof(buf), 0); if (ret < 0) { - (void)zsock_getsockopt(pev->event.fd, SOL_SOCKET, - SO_DOMAIN, &family, &optlen); + (void)zsock_getsockopt(pev->event.fd, ZSOCK_SOL_SOCKET, + ZSOCK_SO_DOMAIN, &family, &optlen); NET_ERR("recv failed on IPv%d socket (%d)", family == NET_AF_INET ? 4 : 6, errno); diff --git a/subsys/net/lib/zperf/zperf_udp_receiver.c b/subsys/net/lib/zperf/zperf_udp_receiver.c index 4ae7024336f9..05ab321e8b5e 100644 --- a/subsys/net/lib/zperf/zperf_udp_receiver.c +++ b/subsys/net/lib/zperf/zperf_udp_receiver.c @@ -327,10 +327,10 @@ static int udp_recv_data(struct net_socket_service_event *pev) if ((pev->event.revents & ZSOCK_POLLERR) || (pev->event.revents & ZSOCK_POLLNVAL)) { - (void)zsock_getsockopt(pev->event.fd, SOL_SOCKET, - SO_DOMAIN, &family, &optlen); - (void)zsock_getsockopt(pev->event.fd, SOL_SOCKET, - SO_ERROR, &sock_error, &optlen); + (void)zsock_getsockopt(pev->event.fd, ZSOCK_SOL_SOCKET, + ZSOCK_SO_DOMAIN, &family, &optlen); + (void)zsock_getsockopt(pev->event.fd, ZSOCK_SOL_SOCKET, + ZSOCK_SO_ERROR, &sock_error, &optlen); NET_ERR("UDP receiver IPv%d socket error (%d)", family == NET_AF_INET ? 4 : 6, sock_error); ret = -sock_error; @@ -351,8 +351,8 @@ static int udp_recv_data(struct net_socket_service_event *pev) if (ret < 0) { ret = -errno; - (void)zsock_getsockopt(pev->event.fd, SOL_SOCKET, - SO_DOMAIN, &family, &optlen); + (void)zsock_getsockopt(pev->event.fd, ZSOCK_SOL_SOCKET, + ZSOCK_SO_DOMAIN, &family, &optlen); NET_ERR("recv failed on IPv%d socket (%d)", family == NET_AF_INET ? 4 : 6, -ret); goto error; diff --git a/subsys/net/lib/zperf/zperf_udp_uploader.c b/subsys/net/lib/zperf/zperf_udp_uploader.c index f6c33e9623d0..c42d5e112888 100644 --- a/subsys/net/lib/zperf/zperf_udp_uploader.c +++ b/subsys/net/lib/zperf/zperf_udp_uploader.c @@ -114,7 +114,7 @@ static inline int zperf_upload_fin(int sock, continue; } else { /* Receive statistics */ - ret = zsock_setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &rcvtimeo, + ret = zsock_setsockopt(sock, ZSOCK_SOL_SOCKET, ZSOCK_SO_RCVTIMEO, &rcvtimeo, sizeof(rcvtimeo)); if (ret < 0) { NET_ERR("setsockopt error (%d)", errno); @@ -408,7 +408,7 @@ int zperf_udp_upload(const struct zperf_upload_params *param, int port = 0; int sock; int ret; - struct ifreq req; + struct net_ifreq req; if (param == NULL || result == NULL) { return -EINVAL; @@ -438,7 +438,7 @@ int zperf_udp_upload(const struct zperf_upload_params *param, if (zsock_setsockopt(sock, ZSOCK_SOL_SOCKET, ZSOCK_SO_BINDTODEVICE, &req, - sizeof(struct ifreq)) != 0) { + sizeof(struct net_ifreq)) != 0) { NET_WARN("setsockopt SO_BINDTODEVICE error (%d)", -errno); } } From f5959a898a72761f0d59c2ce1c13c38a4b12fce7 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Tue, 16 Dec 2025 11:30:11 +0100 Subject: [PATCH 0625/3659] samples: net: zperf: Do not enable the POSIX_API This sample does not need it, and having it enabled masks uses of the non native API by this code. Signed-off-by: Alberto Escolar Piedras --- samples/net/zperf/prj.conf | 1 - 1 file changed, 1 deletion(-) diff --git a/samples/net/zperf/prj.conf b/samples/net/zperf/prj.conf index 8889a1ccc440..b31c653bc3a6 100644 --- a/samples/net/zperf/prj.conf +++ b/samples/net/zperf/prj.conf @@ -23,7 +23,6 @@ CONFIG_NET_TC_TX_COUNT=1 CONFIG_NET_SOCKETS=y CONFIG_NET_SOCKETS_SERVICE_THREAD_PRIO=-1 CONFIG_ZVFS_POLL_MAX=9 -CONFIG_POSIX_API=y CONFIG_INIT_STACKS=y CONFIG_TEST_RANDOM_GENERATOR=y From ddfdd8b3895a81bac1d9865fdf7bbf3edc02a841 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Tue, 16 Dec 2025 13:18:16 +0100 Subject: [PATCH 0626/3659] tests: net: all: Also build zperf Also build the zperf common and server code. Signed-off-by: Alberto Escolar Piedras --- tests/net/all/prj.conf | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/net/all/prj.conf b/tests/net/all/prj.conf index a2e9f66640bb..580dad8d50a7 100644 --- a/tests/net/all/prj.conf +++ b/tests/net/all/prj.conf @@ -690,3 +690,5 @@ CONFIG_TFTP_LIB=y CONFIG_NET_PKT_FILTER=y CONFIG_NET_LATMON=y +CONFIG_NET_ZPERF=y +CONFIG_NET_ZPERF_SERVER=y From 1a347f6f6c09cf0ef4cb411c08a995b490cd4dd4 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Tue, 16 Dec 2025 13:23:16 +0100 Subject: [PATCH 0627/3659] tests: net: all: Do not disable sys_getopt users Since the shell (and its use of sys_getopt) does not have any dependency on the POSIX_API anymore, we do not need to disable it when we disable the POSIX_API compatibility layer. Signed-off-by: Alberto Escolar Piedras --- tests/net/all/testcase.yaml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/tests/net/all/testcase.yaml b/tests/net/all/testcase.yaml index 2e33dfddb898..36e9cdc456f4 100644 --- a/tests/net/all/testcase.yaml +++ b/tests/net/all/testcase.yaml @@ -19,8 +19,6 @@ tests: extra_configs: - CONFIG_NET_NAMESPACE_COMPAT_MODE=n - CONFIG_POSIX_API=n - - CONFIG_SHELL_GETOPT=n - - CONFIG_NET_L2_WIFI_SHELL=n net.build.compat_namespacing: platform_allow: qemu_x86 extra_configs: @@ -33,8 +31,6 @@ tests: extra_configs: - CONFIG_NET_NAMESPACE_COMPAT_MODE=n - CONFIG_POSIX_API=n - - CONFIG_SHELL_GETOPT=n - - CONFIG_NET_L2_WIFI_SHELL=n - CONFIG_NET_CANBUS=y - CONFIG_CAN=y - CONFIG_NET_SOCKETS_CAN=y @@ -50,8 +46,6 @@ tests: extra_configs: - CONFIG_NET_NAMESPACE_COMPAT_MODE=n - CONFIG_POSIX_API=n - - CONFIG_SHELL_GETOPT=n - - CONFIG_NET_L2_WIFI_SHELL=n - CONFIG_NET_L2_OPENTHREAD=y - CONFIG_CPP=y - CONFIG_NET_SLIP_TAP=n From 64efa7dcb3eb2a119cbc5832b69fd263aa1d4d67 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 15 Dec 2025 15:56:28 +0100 Subject: [PATCH 0628/3659] modem: ppp: Fix remaining net API use In d45cd6716bbab3a805e3a5fd461934f0dcdc13e5 the mayority of the Zephyr codebased was changed to use the Zephyr native net_ prefixed types, but some were forgotten. Without this fix/change the code still builds as we are by now setting CONFIG_NET_NAMESPACE_COMPAT_MODE. But when this is not set, things fail to build. Signed-off-by: Alberto Escolar Piedras --- subsys/modem/modem_ppp.c | 2 +- tests/subsys/modem/modem_ppp/src/main.c | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/subsys/modem/modem_ppp.c b/subsys/modem/modem_ppp.c index 47c898979d68..602081155d82 100644 --- a/subsys/modem/modem_ppp.c +++ b/subsys/modem/modem_ppp.c @@ -232,7 +232,7 @@ static void modem_ppp_process_received_byte(struct modem_ppp *ppp, uint8_t byte) case MODEM_PPP_RECEIVE_STATE_HDR_23: if (modem_ppp_is_byte_expected(byte, 0x23)) { ppp->rx_pkt = net_pkt_rx_alloc_with_buffer(ppp->iface, - CONFIG_MODEM_PPP_NET_BUF_FRAG_SIZE, AF_UNSPEC, 0, K_NO_WAIT); + CONFIG_MODEM_PPP_NET_BUF_FRAG_SIZE, NET_AF_UNSPEC, 0, K_NO_WAIT); if (ppp->rx_pkt == NULL) { LOG_WRN("Dropped frame, no net_pkt available"); diff --git a/tests/subsys/modem/modem_ppp/src/main.c b/tests/subsys/modem/modem_ppp/src/main.c index 742667748641..71871741567b 100644 --- a/tests/subsys/modem/modem_ppp/src/main.c +++ b/tests/subsys/modem/modem_ppp/src/main.c @@ -377,7 +377,7 @@ ZTEST(modem_ppp, test_ppp_frame_send) int ret; /* Allocate net pkt */ - pkt = net_pkt_alloc_with_buffer(&test_iface, 256, AF_UNSPEC, 0, K_NO_WAIT); + pkt = net_pkt_alloc_with_buffer(&test_iface, 256, NET_AF_UNSPEC, 0, K_NO_WAIT); zassert_true(pkt != NULL, "Failed to allocate network packet"); @@ -406,7 +406,7 @@ ZTEST(modem_ppp, test_ppp_frame_send_custom_accm1) int ret; /* Allocate net pkt */ - pkt = net_pkt_alloc_with_buffer(&test_iface, 256, AF_UNSPEC, 0, K_NO_WAIT); + pkt = net_pkt_alloc_with_buffer(&test_iface, 256, NET_AF_UNSPEC, 0, K_NO_WAIT); zassert_true(pkt != NULL, "Failed to allocate network packet"); @@ -437,7 +437,7 @@ ZTEST(modem_ppp, test_ppp_frame_send_custom_accm2) int ret; /* Allocate net pkt */ - pkt = net_pkt_alloc_with_buffer(&test_iface, 256, AF_UNSPEC, 0, K_NO_WAIT); + pkt = net_pkt_alloc_with_buffer(&test_iface, 256, NET_AF_UNSPEC, 0, K_NO_WAIT); zassert_true(pkt != NULL, "Failed to allocate network packet"); @@ -495,7 +495,7 @@ ZTEST(modem_ppp, test_ip_frame_send) int ret; /* Allocate net pkt */ - pkt = net_pkt_alloc_with_buffer(&test_iface, 256, AF_UNSPEC, 0, K_NO_WAIT); + pkt = net_pkt_alloc_with_buffer(&test_iface, 256, NET_AF_UNSPEC, 0, K_NO_WAIT); zassert_true(pkt != NULL, "Failed to allocate network packet"); /* Set network packet data */ @@ -524,7 +524,7 @@ ZTEST(modem_ppp, test_ip_frame_send_multiple) /* Allocate net pkts */ for (uint8_t i = 0; i < TEST_MODEM_PPP_IP_FRAME_SEND_MULT_N; i++) { - pkts[i] = net_pkt_alloc_with_buffer(&test_iface, 256, AF_UNSPEC, 0, K_NO_WAIT); + pkts[i] = net_pkt_alloc_with_buffer(&test_iface, 256, NET_AF_UNSPEC, 0, K_NO_WAIT); zassert_true(pkts[i] != NULL, "Failed to allocate network packet"); net_pkt_cursor_init(pkts[i]); ret = net_pkt_write(pkts[i], ip_frame_unwrapped, sizeof(ip_frame_unwrapped)); @@ -551,7 +551,7 @@ ZTEST(modem_ppp, test_ip_frame_send_large) int ret; pkt = net_pkt_alloc_with_buffer(&test_iface, TEST_MODEM_PPP_IP_FRAME_SEND_LARGE_N, - AF_UNSPEC, 0, K_NO_WAIT); + NET_AF_UNSPEC, 0, K_NO_WAIT); net_pkt_cursor_init(pkt); net_pkt_set_family(pkt, NET_AF_INET); From 56a84e81116bce11d3729b010b39389d4509be03 Mon Sep 17 00:00:00 2001 From: Pieter De Gendt Date: Wed, 17 Dec 2025 12:03:05 +0100 Subject: [PATCH 0629/3659] scripts: ci: Add ignorecase option to zephyr-keep-sorted Allow making the zephyr-keep-sorted check ignore cases, for example: // zephyr-keep-sorted-start ignorecase .... // zephyr-keep-sorted-stop Signed-off-by: Pieter De Gendt --- scripts/ci/check_compliance.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/scripts/ci/check_compliance.py b/scripts/ci/check_compliance.py index 19e50cbb7582..c9baa2adcd04 100755 --- a/scripts/ci/check_compliance.py +++ b/scripts/ci/check_compliance.py @@ -2362,7 +2362,7 @@ class KeepSorted(ComplianceTest): MARKER = "zephyr-keep-sorted" - def block_check_sorted(self, block_data, *, regex, strip, fold): + def block_check_sorted(self, block_data, *, regex, strip, fold, icase): def _test_indent(txt: str): return txt.startswith((" ", "\t")) @@ -2393,6 +2393,9 @@ def _test_indent(txt: str): for cont in takewhile(_test_indent, lines[idx + 1 :]): line += cont.strip() + if icase: + line = line.casefold() + if line < last: return idx @@ -2414,10 +2417,12 @@ def check_file(self, file, fp): regex_marker = r"re\(([^)]+)\)" strip_marker = r"strip\(([^)]+)\)" nofold_marker = "nofold" + ignorecase_marker = "ignorecase" start_line = 0 regex = None strip = None fold = True + icase = False for line_num, line in enumerate(fp.readlines(), start=1): if start_marker in line: @@ -2436,13 +2441,16 @@ def check_file(self, file, fp): strip = match.group(1) if match else None fold = nofold_marker not in line + icase = ignorecase_marker in line elif stop_marker in line: if not in_block: desc = f"{stop_marker} without {start_marker}" self.fmtd_failure("error", "KeepSorted", file, line_num, desc=desc) in_block = False - idx = self.block_check_sorted(block_data, regex=regex, strip=strip, fold=fold) + idx = self.block_check_sorted( + block_data, regex=regex, strip=strip, fold=fold, icase=icase + ) if idx >= 0: desc = f"sorted block has out-of-order line at {start_line + idx}" self.fmtd_failure("error", "KeepSorted", file, line_num, desc=desc) From 36abed53776e84695143821516a2fbf3b63ecca6 Mon Sep 17 00:00:00 2001 From: Bill Waters Date: Mon, 13 Oct 2025 13:09:33 -0700 Subject: [PATCH 0630/3659] drivers: counter: add support for Infineon PSE84 device - Update the driver to support the PSE84 device - Update to new peripheral clock allocation scheme Signed-off-by: Bill Waters --- drivers/counter/counter_infineon_tcpwm.c | 84 +++++++++++-------- .../counter/infineon,tcpwm-counter.yaml | 5 -- 2 files changed, 50 insertions(+), 39 deletions(-) diff --git a/drivers/counter/counter_infineon_tcpwm.c b/drivers/counter/counter_infineon_tcpwm.c index ad824d772378..f46f49be4b8b 100644 --- a/drivers/counter/counter_infineon_tcpwm.c +++ b/drivers/counter/counter_infineon_tcpwm.c @@ -45,7 +45,6 @@ struct ifx_tcpwm_counter_data { struct counter_top_cfg top_value_cfg_counter; uint32_t guard_period; struct ifx_cat1_clock clock; - uint8_t clock_peri_group; }; static const cy_stc_tcpwm_counter_config_t counter_default_config = { @@ -138,25 +137,8 @@ static int ifx_tcpwm_counter_init(const struct device *dev) cy_rslt_t rslt; struct ifx_tcpwm_counter_data *const data = dev->data; const struct ifx_tcpwm_counter_config *config = dev->config; - uint32_t clk_connection; cy_stc_tcpwm_counter_config_t counter_config = counter_default_config; - /* Calculate clock connection based on TCPWM index */ - if (config->resolution_32_bits) { - clk_connection = PCLK_TCPWM0_CLOCK_COUNTER_EN0 + config->index; - } else { - clk_connection = PCLK_TCPWM0_CLOCK_COUNTER_EN256 + config->index; - } - /* Configure PWM clock */ - Cy_SysClk_PeriPclkDisableDivider((en_clk_dst_t)clk_connection, config->divider_type, - config->divider_sel); - Cy_SysClk_PeriPclkSetDivider((en_clk_dst_t)clk_connection, config->divider_type, - config->divider_sel, config->divider_val); - Cy_SysClk_PeriPclkEnableDivider((en_clk_dst_t)clk_connection, config->divider_type, - config->divider_sel); - - Cy_SysClk_PeriPclkAssignDivider(clk_connection, config->divider_type, config->divider_sel); - /* Initialize counter structure */ data->alarm_irq_flag = false; data->top_value_cfg_counter.ticks = config->counter_info.max_top_value; @@ -212,6 +194,24 @@ static int ifx_tcpwm_counter_stop(const struct device *dev) return 0; } +static uint32_t ifx_tcpwm_counter_get_freq(const struct device *dev) +{ + struct ifx_tcpwm_counter_data *const data = dev->data; + const struct ifx_tcpwm_counter_config *config = dev->config; + en_clk_dst_t clk_connection; + + /* Determine tcpwm block number based on its resolution */ + uint32_t tcpwm_block = config->resolution_32_bits ? 0 : 1; + + /* Calculate clock connection based on TCPWM index */ + clk_connection = ifx_cat1_tcpwm_get_clock_index(tcpwm_block, config->index); + + uint32_t frequency = ifx_cat1_utils_peri_pclk_get_frequency(clk_connection, + &data->clock); + + return frequency; +} + static int ifx_tcpwm_counter_get_value(const struct device *dev, uint32_t *ticks) { __ASSERT_NO_MSG(dev != NULL); @@ -432,6 +432,7 @@ static int ifx_tcpwm_counter_set_guard_period(const struct device *dev, uint32_t static DEVICE_API(counter, counter_api) = { .start = ifx_tcpwm_counter_start, .stop = ifx_tcpwm_counter_stop, + .get_freq = ifx_tcpwm_counter_get_freq, .get_value = ifx_tcpwm_counter_get_value, .set_alarm = ifx_tcpwm_counter_set_alarm, .cancel_alarm = ifx_tcpwm_counter_cancel_alarm, @@ -447,32 +448,50 @@ static DEVICE_API(counter, counter_api) = { (DT_GET_CYHAL_GPIO_FROM_DT_GPIOS(DT_INST(inst, DT_DRV_COMPAT), gpios_prop)), \ (default)) +#if defined(CONFIG_SOC_FAMILY_INFINEON_EDGE) +#define COUNTER_PERI_CLOCK_INSTANCE(n) DT_PROP_BY_IDX(DT_INST_PHANDLE(n, clocks), peri_group, 0), +#else +#define COUNTER_PERI_CLOCK_INSTANCE(n) +#endif + +#if defined(CONFIG_SOC_FAMILY_INFINEON_EDGE) +#define COUNTER_PERI_CLOCK_INIT(n) \ + .clock = \ + { \ + .block = IFX_CAT1_PERIPHERAL_GROUP_ADJUST( \ + DT_PROP_BY_IDX(DT_INST_PHANDLE(n, clocks), peri_group, 0), \ + DT_PROP_BY_IDX(DT_INST_PHANDLE(n, clocks), peri_group, 1), \ + DT_INST_PROP_BY_PHANDLE(n, clocks, div_type)), \ + .channel = DT_INST_PROP_BY_PHANDLE(n, clocks, channel), \ + } +#else +#define COUNTER_PERI_CLOCK_INIT(n) \ + .clock = \ + { \ + .block = IFX_CAT1_PERIPHERAL_GROUP_ADJUST( \ + DT_PROP_BY_IDX(DT_INST_PHANDLE(n, clocks), peri_group, 1), \ + DT_INST_PROP_BY_PHANDLE(n, clocks, div_type)), \ + .channel = DT_INST_PROP_BY_PHANDLE(n, clocks, channel), \ + } +#endif + /* Counter driver init macros */ #define INFINEON_TCPWM_COUNTER_INIT(n) \ \ - static void ifx_cat1_spi_irq_enable_func_##n(const struct device *dev) \ + static void ifx_counter_irq_enable_func_##n(const struct device *dev) \ { \ IRQ_CONNECT(DT_IRQN(DT_INST_PARENT(n)), DT_IRQ(DT_INST_PARENT(n), priority), \ counter_isr_handler, DEVICE_DT_INST_GET(n), 0); \ irq_enable(DT_IRQN(DT_INST_PARENT(n))); \ } \ \ - static struct ifx_tcpwm_counter_data ifx_tcpwm_counter##n##_data = { \ - .clock = \ - { \ - .block = IFX_CAT1_PERIPHERAL_GROUP_ADJUST( \ - DT_PROP_BY_IDX(DT_INST_PHANDLE(n, clocks), clk_dst, 1), \ - DT_INST_PROP_BY_PHANDLE(n, clocks, div_type)), \ - .channel = DT_INST_PROP_BY_PHANDLE(n, clocks, div_num), \ - }, \ - .clock_peri_group = DT_PROP_BY_IDX(DT_INST_PHANDLE(n, clocks), clk_dst, 1), \ - }; \ + static struct ifx_tcpwm_counter_data ifx_tcpwm_counter##n##_data = \ + {COUNTER_PERI_CLOCK_INIT(n)}; \ \ static const struct ifx_tcpwm_counter_config ifx_tcpwm_counter##n##_config = { \ .counter_info = {.max_top_value = (DT_PROP(DT_INST_PARENT(n), resolution) == 32) \ ? UINT32_MAX \ : UINT16_MAX, \ - .freq = DT_INST_PROP(n, clock_frequency), \ .flags = COUNTER_CONFIG_INFO_COUNT_UP, \ .channels = 1}, \ .reg_base = (TCPWM_GRP_CNT_Type *)DT_REG_ADDR(DT_INST_PARENT(n)), \ @@ -482,10 +501,7 @@ static DEVICE_API(counter, counter_api) = { .irq_num = DT_IRQN(DT_INST_PARENT(n)), \ .resolution_32_bits = \ (DT_PROP(DT_INST_PARENT(n), resolution) == 32) ? true : false, \ - .divider_type = DT_PROP(DT_INST_PARENT(n), divider_type), \ - .divider_sel = DT_PROP(DT_INST_PARENT(n), divider_sel), \ - .divider_val = DT_PROP(DT_INST_PARENT(n), divider_val), \ - .irq_enable_func = ifx_cat1_spi_irq_enable_func_##n, \ + .irq_enable_func = ifx_counter_irq_enable_func_##n, \ }; \ \ DEVICE_DT_INST_DEFINE(n, ifx_tcpwm_counter_init, NULL, &ifx_tcpwm_counter##n##_data, \ diff --git a/dts/bindings/counter/infineon,tcpwm-counter.yaml b/dts/bindings/counter/infineon,tcpwm-counter.yaml index 356ca00ce857..dca3cd4a55d6 100644 --- a/dts/bindings/counter/infineon,tcpwm-counter.yaml +++ b/dts/bindings/counter/infineon,tcpwm-counter.yaml @@ -10,11 +10,6 @@ compatible: "infineon,tcpwm-counter" include: [base.yaml, "infineon,system-interrupts.yaml"] properties: - clock-frequency: - type: int - description: | - Frequency that the counter runs - external-trigger-gpios: type: phandle-array description: | From 4926960746d9b6192e4bae880b0c6e47e1554a31 Mon Sep 17 00:00:00 2001 From: Bill Waters Date: Mon, 13 Oct 2025 13:11:49 -0700 Subject: [PATCH 0631/3659] samples: counter: add Infineon kit_pse84_eval Add overlay files for the alarm sample Signed-off-by: Bill Waters --- .../boards/kit_pse84_eval_common.overlay | 25 +++++++++++++++++++ ...it_pse84_eval_pse846gps2dbzc4a_m33.overlay | 8 ++++++ ...it_pse84_eval_pse846gps2dbzc4a_m55.overlay | 8 ++++++ samples/drivers/counter/alarm/src/main.c | 2 +- 4 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 samples/drivers/counter/alarm/boards/kit_pse84_eval_common.overlay create mode 100644 samples/drivers/counter/alarm/boards/kit_pse84_eval_pse846gps2dbzc4a_m33.overlay create mode 100644 samples/drivers/counter/alarm/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.overlay diff --git a/samples/drivers/counter/alarm/boards/kit_pse84_eval_common.overlay b/samples/drivers/counter/alarm/boards/kit_pse84_eval_common.overlay new file mode 100644 index 000000000000..b207ad5a5b14 --- /dev/null +++ b/samples/drivers/counter/alarm/boards/kit_pse84_eval_common.overlay @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&tcpwm0_1 { + status = "okay"; + + counter0_1 { + status = "okay"; + clocks = <&peri0_group1_16bit_1>; + }; +}; + +&peri0_group1_16bit_1 { + status = "okay"; + resource-type = ; + resource-instance = <0>; + resource-channel = <1>; + clock-div = <9600>; +}; diff --git a/samples/drivers/counter/alarm/boards/kit_pse84_eval_pse846gps2dbzc4a_m33.overlay b/samples/drivers/counter/alarm/boards/kit_pse84_eval_pse846gps2dbzc4a_m33.overlay new file mode 100644 index 000000000000..533ab3852f0e --- /dev/null +++ b/samples/drivers/counter/alarm/boards/kit_pse84_eval_pse846gps2dbzc4a_m33.overlay @@ -0,0 +1,8 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "kit_pse84_eval_common.overlay" diff --git a/samples/drivers/counter/alarm/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.overlay b/samples/drivers/counter/alarm/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.overlay new file mode 100644 index 000000000000..533ab3852f0e --- /dev/null +++ b/samples/drivers/counter/alarm/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.overlay @@ -0,0 +1,8 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "kit_pse84_eval_common.overlay" diff --git a/samples/drivers/counter/alarm/src/main.c b/samples/drivers/counter/alarm/src/main.c index 838781f7c894..beb7f5cb0f9d 100644 --- a/samples/drivers/counter/alarm/src/main.c +++ b/samples/drivers/counter/alarm/src/main.c @@ -54,7 +54,7 @@ struct counter_alarm_cfg alarm_cfg; #endif #define TIMER DT_CHOSEN(silabs_sleeptimer) #elif defined(CONFIG_COUNTER_INFINEON_CAT1) || defined(CONFIG_COUNTER_INFINEON_TCPWM) -#define TIMER DT_NODELABEL(counter0_0) +#define TIMER DT_NODELABEL(counter0_1) #elif defined(CONFIG_COUNTER_AMBIQ) #ifdef TIMER #undef TIMER From 47e8e1fd682d310b04d72cbc5839babb8e85ad4b Mon Sep 17 00:00:00 2001 From: Fabrice DJIATSA Date: Mon, 15 Dec 2025 11:34:43 +0100 Subject: [PATCH 0632/3659] boards: st: stm32l562e_dk: add arduino_gpio as supported periph This is required to perform the /tests/drivers/gpio/gpio_basic_api test. Signed-off-by: Fabrice DJIATSA --- boards/st/stm32l562e_dk/stm32l562e_dk.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/boards/st/stm32l562e_dk/stm32l562e_dk.yaml b/boards/st/stm32l562e_dk/stm32l562e_dk.yaml index 1703d4c99338..938f8f2f3699 100644 --- a/boards/st/stm32l562e_dk/stm32l562e_dk.yaml +++ b/boards/st/stm32l562e_dk/stm32l562e_dk.yaml @@ -18,6 +18,7 @@ supported: - ble - dma - usart + - arduino_gpio - arduino_spi - usb_device - nvs From 95f6318b688049a18809b0dae27672ef1b3ad2b5 Mon Sep 17 00:00:00 2001 From: Fabrice DJIATSA Date: Mon, 15 Dec 2025 11:49:29 +0100 Subject: [PATCH 0633/3659] boards: st: stm32l562e_dk: enable sdmmc1 iDMA to fix sector write failures MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The disk_access test failed during 8‑sector writes with: - sd write error 16 - Failed to write to sector zero (assert in tests/drivers/disk/disk_access) Enabling idma on &sdmmc1 allows proper multi‑block transfers and eliminates the write failure. Signed-off-by: Fabrice DJIATSA --- boards/st/stm32l562e_dk/stm32l562e_dk_common.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boards/st/stm32l562e_dk/stm32l562e_dk_common.dtsi b/boards/st/stm32l562e_dk/stm32l562e_dk_common.dtsi index f07b8c8c0f35..2e1c97da5a20 100644 --- a/boards/st/stm32l562e_dk/stm32l562e_dk_common.dtsi +++ b/boards/st/stm32l562e_dk/stm32l562e_dk_common.dtsi @@ -313,7 +313,7 @@ zephyr_udc0: &usb { &sdmmc1_cmd_pd2>; pinctrl-names = "default"; - + idma; cd-gpios = <&gpiof 2 GPIO_ACTIVE_LOW>; }; From e4d5f3ba0b9cb6d46895014e154137b248dad0ae Mon Sep 17 00:00:00 2001 From: Fabrice DJIATSA Date: Mon, 15 Dec 2025 11:53:35 +0100 Subject: [PATCH 0634/3659] tests: drivers: spi: spi_loopback: update stm32l562e_dk spi node Move from SPI1 to SPI3 node (arduino header). Signed-off-by: Fabrice DJIATSA --- .../spi/spi_loopback/boards/stm32l562e_dk.overlay | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/tests/drivers/spi/spi_loopback/boards/stm32l562e_dk.overlay b/tests/drivers/spi/spi_loopback/boards/stm32l562e_dk.overlay index 1f0786fc0308..c12a7d9820b4 100644 --- a/tests/drivers/spi/spi_loopback/boards/stm32l562e_dk.overlay +++ b/tests/drivers/spi/spi_loopback/boards/stm32l562e_dk.overlay @@ -4,9 +4,15 @@ * SPDX-License-Identifier: Apache-2.0 */ -&spi1 { - dmas = <&dmamux1 0 12 STM32_DMA_PERIPH_TX>, - <&dmamux1 7 11 STM32_DMA_PERIPH_RX>; +/* SPI bus pins are exposed in the Arduino Uno header. + * SPI3 MISO Arduino D12 + * SPI3 MOSI Arduino D11 + * Short Pin PB4(D12) to PB5(D11) for the test to pass. + */ + +&spi3 { + dmas = <&dmamux1 0 16 STM32_DMA_PERIPH_TX>, + <&dmamux1 7 15 STM32_DMA_PERIPH_RX>; dma-names = "tx", "rx"; slow@0 { From 668737229358993fb86b3c92b525b8005bf2dbad Mon Sep 17 00:00:00 2001 From: Fabrice DJIATSA Date: Mon, 15 Dec 2025 11:57:35 +0100 Subject: [PATCH 0635/3659] tests: drivers: i2c: i2c_target_api: add support for stm32l562e_dk - add an overlay file and enable i2c1 and i2c2 nodes. - add stm32l562e_dk to testcase.yaml for CI testing. Signed-off-by: Fabrice DJIATSA --- .../boards/stm32l562e_dk.overlay | 34 +++++++++++++++++++ .../drivers/i2c/i2c_target_api/testcase.yaml | 1 + 2 files changed, 35 insertions(+) create mode 100644 tests/drivers/i2c/i2c_target_api/boards/stm32l562e_dk.overlay diff --git a/tests/drivers/i2c/i2c_target_api/boards/stm32l562e_dk.overlay b/tests/drivers/i2c/i2c_target_api/boards/stm32l562e_dk.overlay new file mode 100644 index 000000000000..e7bf3e9d8a47 --- /dev/null +++ b/tests/drivers/i2c/i2c_target_api/boards/stm32l562e_dk.overlay @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2025 STMicroelectronics + * SPDX-License-Identifier: Apache-2.0 + */ + +/* I2C bus pins are exposed in the Arduino Uno header and Pmod. + * + * Bus SDA SCL + * Pin Hdr Pin Hdr + * i2c1 PB7 CN11:9 PB6 CN11:10 + * i2c2 PB11 CN12:2 PB13 CN4:1 + * + * Short Pin PB7 to PB11, and PB6 to PB13, for the test to pass. + */ + +&i2c1 { + eeprom0: eeprom@54 { + compatible = "zephyr,i2c-target-eeprom"; + reg = <0x54>; + size = <256>; + }; +}; + +&i2c2 { + pinctrl-0 = <&i2c2_scl_pb13 &i2c2_sda_pb11>; + pinctrl-names = "default"; + status = "okay"; + + eeprom1: eeprom@56 { + compatible = "zephyr,i2c-target-eeprom"; + reg = <0x56>; + size = <256>; + }; +}; diff --git a/tests/drivers/i2c/i2c_target_api/testcase.yaml b/tests/drivers/i2c/i2c_target_api/testcase.yaml index a97331d311c6..707f5293718d 100644 --- a/tests/drivers/i2c/i2c_target_api/testcase.yaml +++ b/tests/drivers/i2c/i2c_target_api/testcase.yaml @@ -17,6 +17,7 @@ tests: - stm32f072b_disco - stm32f3_disco - stm32h573i_dk + - stm32l562e_dk - stm32n6570_dk/stm32n657xx/sb - stm32u083c_dk - nucleo_c071rb From 1912d88fc98b284fac9ddd1b85bd58657c97636a Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 15 Dec 2025 16:08:28 +0100 Subject: [PATCH 0636/3659] samples: net: promiscuous_mode: Fix remaining net API use In d45cd6716bbab3a805e3a5fd461934f0dcdc13e5 the mayority of the Zephyr codebased was changed to use the Zephyr native net_ prefixed types, but some were forgotten. Without this fix/change the code still builds as we are by now setting CONFIG_NET_NAMESPACE_COMPAT_MODE. But when this is not set, things fail to build. Signed-off-by: Alberto Escolar Piedras --- samples/net/promiscuous_mode/src/main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/samples/net/promiscuous_mode/src/main.c b/samples/net/promiscuous_mode/src/main.c index 1d1536dfdcfe..e2f77c8f811e 100644 --- a/samples/net/promiscuous_mode/src/main.c +++ b/samples/net/promiscuous_mode/src/main.c @@ -49,8 +49,8 @@ static int get_ports(struct net_pkt *pkt, uint16_t *src, uint16_t *dst) return -EINVAL; } - *src = ntohs(udp_hdr->src_port); - *dst = ntohs(udp_hdr->dst_port); + *src = net_ntohs(udp_hdr->src_port); + *dst = net_ntohs(udp_hdr->dst_port); return 0; } @@ -60,7 +60,7 @@ static void print_info(struct net_pkt *pkt) char src_addr_buf[NET_IPV6_ADDR_LEN], *src_addr; char dst_addr_buf[NET_IPV6_ADDR_LEN], *dst_addr; uint16_t dst_port = 0U, src_port = 0U; - sa_family_t family = AF_UNSPEC; + net_sa_family_t family = NET_AF_UNSPEC; void *dst, *src; uint8_t next_hdr; const char *proto; From 555887ec111bf5514d96dc052e4df0c9c7e619fa Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Tue, 16 Dec 2025 10:33:24 +0100 Subject: [PATCH 0637/3659] net: Fix net API use In d45cd6716bbab3a805e3a5fd461934f0dcdc13e5 the mayority of the Zephyr codebased was changed to use the Zephyr native net_ prefixed types, but some were forgotten. Without this fix/change the code still builds as we are by now setting CONFIG_NET_NAMESPACE_COMPAT_MODE. But when this is not set, things fail to build. Signed-off-by: Alberto Escolar Piedras --- subsys/net/ip/connection.c | 2 +- subsys/net/lib/shell/sockets.c | 2 +- tests/net/socket/af_inet_raw/src/main.c | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/subsys/net/ip/connection.c b/subsys/net/ip/connection.c index 2b31fe90a877..86fb2675c5af 100644 --- a/subsys/net/ip/connection.c +++ b/subsys/net/ip/connection.c @@ -780,7 +780,7 @@ enum net_verdict net_conn_can_input(struct net_pkt *pkt, uint8_t proto) net_conn_cb_t cb = NULL; void *user_data = NULL; - /* Only accept input with AF_CAN family and CAN_RAW protocol. */ + /* Only accept input with NET_AF_CAN family and NET_CAN_RAW protocol. */ if (net_pkt_family(pkt) != NET_AF_CAN || proto != NET_CAN_RAW) { return NET_DROP; } diff --git a/subsys/net/lib/shell/sockets.c b/subsys/net/lib/shell/sockets.c index 1eb32bf4619d..a1e5c1117bb4 100644 --- a/subsys/net/lib/shell/sockets.c +++ b/subsys/net/lib/shell/sockets.c @@ -69,7 +69,7 @@ int walk_sockets(struct k_obj_core *obj_core, void *user_data) thread_name, obj->reg->name, obj->socket_family == NET_AF_INET6 ? '6' : (obj->socket_family == NET_AF_INET ? '4' : - (obj->socket_family == AF_NET_MGMT ? 'M' : ' ')), + (obj->socket_family == NET_AF_NET_MGMT ? 'M' : ' ')), obj->socket_type == NET_SOCK_DGRAM ? 'D' : (obj->socket_type == NET_SOCK_STREAM ? 'S' : (obj->socket_type == NET_SOCK_RAW ? 'R' : ' ')), diff --git a/tests/net/socket/af_inet_raw/src/main.c b/tests/net/socket/af_inet_raw/src/main.c index 071a08fcc988..991596bad6ae 100644 --- a/tests/net/socket/af_inet_raw/src/main.c +++ b/tests/net/socket/af_inet_raw/src/main.c @@ -35,14 +35,14 @@ * - test_raw_v6_sock_send_proto_match * - test_raw_v6_sock_send_proto_mismatch * - * * (NET_AF_INET/6, NET_SOCK_RAW, IPPROTO_RAW) - The IP header needs to be supplied by + * * (NET_AF_INET/6, NET_SOCK_RAW, NET_IPPROTO_RAW) - The IP header needs to be supplied by * the user in the data: * - test_raw_v4_sock_send_proto_ipproto_raw * - test_raw_v6_sock_send_proto_ipproto_raw * * Receiving data (RX) * - * * (NET_AF_INET/6, NET_SOCK_RAW, 0) - 0 value is also `IPPROTO_IP` which is + * * (NET_AF_INET/6, NET_SOCK_RAW, 0) - 0 value is also `NET_IPPROTO_IP` which is * "wildcard" value. The packet is received for any IP protocol. It works in * similar way as in FreeBSD: * - test_raw_v4_sock_recv_proto_wildcard @@ -58,7 +58,7 @@ * - test_raw_v4_sock_recv_proto_match * - test_raw_v6_sock_recv_proto_match * - * * (NET_AF_INET/6, NET_SOCK_RAW, IPPROTO_RAW) - Receiving of all IP protocols via + * * (NET_AF_INET/6, NET_SOCK_RAW, NET_IPPROTO_RAW) - Receiving of all IP protocols via * NET_IPPROTO_RAW is not * possible using raw sockets. https://man7.org/linux/man-pages/man7/raw.7.html: * - test_raw_v4_sock_recv_proto_ipproto_raw From 88f1faec327704b785a96b62d493eb470c99f91c Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Tue, 16 Dec 2025 14:33:02 +0100 Subject: [PATCH 0638/3659] tests: net: all: Also build net shell disabled commands It seems no other test (or sample) was building this. So let's enable them in this test, so we at least build test them somewhere. Signed-off-by: Alberto Escolar Piedras --- tests/net/all/prj.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/net/all/prj.conf b/tests/net/all/prj.conf index 580dad8d50a7..cd48a5e1af62 100644 --- a/tests/net/all/prj.conf +++ b/tests/net/all/prj.conf @@ -44,6 +44,7 @@ CONFIG_NET_PKT_TIMESTAMP_STACK_SIZE=1024 CONFIG_NETWORKING=y CONFIG_NET_SHELL=y CONFIG_NET_SHELL_DYN_CMD_COMPLETION=y +CONFIG_NET_SHELL_SHOW_DISABLED_COMMANDS=y CONFIG_NET_IP_ADDR_CHECK=y CONFIG_NET_ICMPV4_ACCEPT_BROADCAST=y CONFIG_NET_PROMISC_LOG_LEVEL_DBG=y From 0be25778f78d8149fcbd873519eb30134f43b168 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Tue, 16 Dec 2025 14:34:50 +0100 Subject: [PATCH 0639/3659] net: sockets: objcore: Fix net API use In d45cd6716bbab3a805e3a5fd461934f0dcdc13e5 the mayority of the Zephyr codebased was changed to use the Zephyr native net_ prefixed types, but some were forgotten. Without this fix/change the code still builds as we are by now setting CONFIG_NET_NAMESPACE_COMPAT_MODE. But when this is not set, things fail to build. Signed-off-by: Alberto Escolar Piedras --- subsys/net/lib/sockets/socket_obj_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/net/lib/sockets/socket_obj_core.c b/subsys/net/lib/sockets/socket_obj_core.c index de484b9b6850..0b4897ecd7c0 100644 --- a/subsys/net/lib/sockets/socket_obj_core.c +++ b/subsys/net/lib/sockets/socket_obj_core.c @@ -174,7 +174,7 @@ int sock_obj_core_alloc_find(int sock, int new_sock, int type) goto out; } - ret = zsock_getsockopt(sock, SOL_SOCKET, SO_DOMAIN, &family, &optlen); + ret = zsock_getsockopt(sock, ZSOCK_SOL_SOCKET, ZSOCK_SO_DOMAIN, &family, &optlen); if (ret < 0) { NET_ERR("Cannot get socket domain (%d)", -errno); goto out; From 3b4cde81320c418a18509d42516bf0c15ce1f5a0 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Tue, 16 Dec 2025 10:34:37 +0100 Subject: [PATCH 0640/3659] shell: backends: websocket: Fix net API use In d45cd6716bbab3a805e3a5fd461934f0dcdc13e5 the mayority of the Zephyr codebased was changed to use the Zephyr native net_ prefixed types, but some were forgotten. Without this fix/change the code still builds as we are by now setting CONFIG_NET_NAMESPACE_COMPAT_MODE. But when this is not set, things fail to build. Signed-off-by: Alberto Escolar Piedras --- subsys/shell/backends/shell_websocket.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/subsys/shell/backends/shell_websocket.c b/subsys/shell/backends/shell_websocket.c index 92b839653183..69b69b34ff5c 100644 --- a/subsys/shell/backends/shell_websocket.c +++ b/subsys/shell/backends/shell_websocket.c @@ -155,7 +155,7 @@ static void ws_recv(struct shell_websocket *ws, struct zsock_pollfd *pollfd) static void ws_server_cb(struct net_socket_service_event *evt) { - socklen_t optlen = sizeof(int); + net_socklen_t optlen = sizeof(int); struct shell_websocket *ws; int sock_error; @@ -163,8 +163,8 @@ static void ws_server_cb(struct net_socket_service_event *evt) if ((evt->event.revents & ZSOCK_POLLERR) || (evt->event.revents & ZSOCK_POLLNVAL)) { - (void)zsock_getsockopt(evt->event.fd, SOL_SOCKET, - SO_ERROR, &sock_error, &optlen); + (void)zsock_getsockopt(evt->event.fd, ZSOCK_SOL_SOCKET, + ZSOCK_SO_ERROR, &sock_error, &optlen); LOG_ERR("Websocket socket %d error (%d)", evt->event.fd, sock_error); if (evt->event.fd == ws->fds[0].fd) { From bb0035755765e55e5a858b8dfe92696ea5e5b8b9 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Tue, 16 Dec 2025 10:28:33 +0100 Subject: [PATCH 0641/3659] net: lib: http: Fix net API use In d45cd6716bbab3a805e3a5fd461934f0dcdc13e5 the mayority of the Zephyr codebased was changed to use the Zephyr native net_ prefixed types, but some were forgotten. Without this fix/change the code still builds as we are by now setting CONFIG_NET_NAMESPACE_COMPAT_MODE. But when this is not set, things fail to build. Signed-off-by: Alberto Escolar Piedras --- include/zephyr/net/http/parser.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/zephyr/net/http/parser.h b/include/zephyr/net/http/parser.h index dab7d43b6aef..d7b754e5dac5 100644 --- a/include/zephyr/net/http/parser.h +++ b/include/zephyr/net/http/parser.h @@ -193,7 +193,7 @@ struct http_parser { /* Remote socket address of http connection, where parser can initiate * replies if necessary. */ - const struct sockaddr *addr; + const struct net_sockaddr *addr; }; From fe1607844c5c8b327ad8d0a4e2d8f209cfbc9b25 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 15 Dec 2025 16:09:19 +0100 Subject: [PATCH 0642/3659] mgmt: mcumgr: Fix remaining net API use In d45cd6716bbab3a805e3a5fd461934f0dcdc13e5 the mayority of the Zephyr codebased was changed to use the Zephyr native net_ prefixed types, but some were forgotten. Without this fix/change the code still builds as we are by now setting CONFIG_NET_NAMESPACE_COMPAT_MODE. But when this is not set, things fail to build. Signed-off-by: Alberto Escolar Piedras --- .../zephyr/mgmt/mcumgr/transport/smp_udp.h | 2 +- subsys/mgmt/mcumgr/transport/src/smp_udp.c | 28 +++++++++---------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/include/zephyr/mgmt/mcumgr/transport/smp_udp.h b/include/zephyr/mgmt/mcumgr/transport/smp_udp.h index f775f16473be..abde790e7a9c 100644 --- a/include/zephyr/mgmt/mcumgr/transport/smp_udp.h +++ b/include/zephyr/mgmt/mcumgr/transport/smp_udp.h @@ -58,7 +58,7 @@ int smp_udp_close(void); * @return 0 on success * @return -errno code on failure. */ -int smp_client_udp_set_host_addr(struct smp_client_object *obj, struct sockaddr *addr); +int smp_client_udp_set_host_addr(struct smp_client_object *obj, struct net_sockaddr *addr); #endif #ifdef __cplusplus diff --git a/subsys/mgmt/mcumgr/transport/src/smp_udp.c b/subsys/mgmt/mcumgr/transport/src/smp_udp.c index b7303ff0d126..c9b469b9b178 100644 --- a/subsys/mgmt/mcumgr/transport/src/smp_udp.c +++ b/subsys/mgmt/mcumgr/transport/src/smp_udp.c @@ -165,8 +165,8 @@ static int smp_udp_ud_copy(struct net_buf *dst, const struct net_buf *src) static void smp_udp_ud_init(struct net_buf *nb, void *priv) { - struct sockaddr *ud = net_buf_user_data(nb); - const struct sockaddr *addr = priv; + struct net_sockaddr *ud = net_buf_user_data(nb); + const struct net_sockaddr *addr = priv; if (addr) { memcpy(ud, addr, sizeof(*addr)); @@ -179,10 +179,10 @@ static int create_socket(enum proto_type proto, int *sock) int err; struct net_sockaddr_storage addr_storage; struct net_sockaddr *addr = (struct net_sockaddr *)&addr_storage; - socklen_t addr_len = 0; + net_socklen_t addr_len = 0; #if defined(CONFIG_MCUMGR_TRANSPORT_UDP_DTLS) - int socket_role = TLS_DTLS_ROLE_SERVER; + int socket_role = ZSOCK_TLS_DTLS_ROLE_SERVER; #endif if (IS_ENABLED(CONFIG_MCUMGR_TRANSPORT_UDP_IPV4) && @@ -192,8 +192,8 @@ static int create_socket(enum proto_type proto, int *sock) addr_len = sizeof(*addr4); memset(addr4, 0, sizeof(*addr4)); addr4->sin_family = NET_AF_INET; - addr4->sin_port = htons(CONFIG_MCUMGR_TRANSPORT_UDP_PORT); - addr4->sin_addr.s_addr = htonl(INADDR_ANY); + addr4->sin_port = net_htons(CONFIG_MCUMGR_TRANSPORT_UDP_PORT); + addr4->sin_addr.s_addr = net_htonl(NET_INADDR_ANY); } else if (IS_ENABLED(CONFIG_MCUMGR_TRANSPORT_UDP_IPV6) && proto == PROTOCOL_IPV6) { struct net_sockaddr_in6 *addr6 = (struct net_sockaddr_in6 *)addr; @@ -201,8 +201,8 @@ static int create_socket(enum proto_type proto, int *sock) addr_len = sizeof(*addr6); memset(addr6, 0, sizeof(*addr6)); addr6->sin6_family = NET_AF_INET6; - addr6->sin6_port = htons(CONFIG_MCUMGR_TRANSPORT_UDP_PORT); - addr6->sin6_addr = in6addr_any; + addr6->sin6_port = net_htons(CONFIG_MCUMGR_TRANSPORT_UDP_PORT); + addr6->sin6_addr = net_in6addr_any; } #if defined(CONFIG_MCUMGR_TRANSPORT_UDP_DTLS) @@ -224,7 +224,7 @@ static int create_socket(enum proto_type proto, int *sock) CONFIG_MCUMGR_TRANSPORT_UDP_DTLS_TLS_TAG, }; - err = zsock_setsockopt(tmp_sock, SOL_TLS, TLS_SEC_TAG_LIST, sec_tag_list, + err = zsock_setsockopt(tmp_sock, ZSOCK_SOL_TLS, ZSOCK_TLS_SEC_TAG_LIST, sec_tag_list, sizeof(sec_tag_list)); if (err < 0) { @@ -233,7 +233,7 @@ static int create_socket(enum proto_type proto, int *sock) } /* Set role to DTLS server */ - err = zsock_setsockopt(tmp_sock, SOL_TLS, TLS_DTLS_ROLE, &socket_role, + err = zsock_setsockopt(tmp_sock, ZSOCK_SOL_TLS, ZSOCK_TLS_DTLS_ROLE, &socket_role, sizeof(socket_role)); if (err < 0) { @@ -276,7 +276,7 @@ static void smp_udp_receive_thread(void *p1, void *p2, void *p3) while (1) { struct net_sockaddr addr; - socklen_t addr_len = sizeof(addr); + net_socklen_t addr_len = sizeof(addr); int len = zsock_recvfrom(conf->sock, conf->recv_buffer, CONFIG_MCUMGR_TRANSPORT_UDP_MTU, 0, &addr, &addr_len); @@ -496,16 +496,16 @@ static void smp_udp_start(void) } #ifdef CONFIG_SMP_CLIENT -int smp_client_udp_set_host_addr(struct smp_client_object *obj, struct sockaddr *addr) +int smp_client_udp_set_host_addr(struct smp_client_object *obj, struct net_sockaddr *addr) { #ifdef CONFIG_MCUMGR_TRANSPORT_UDP_IPV4 - if (obj->smpt == smp_udp_configs.ipv4_transport.smpt && addr->sa_family == AF_INET) { + if (obj->smpt == smp_udp_configs.ipv4_transport.smpt && addr->sa_family == NET_AF_INET) { smp_client_object_set_data(obj, addr); return 0; } #endif #ifdef CONFIG_MCUMGR_TRANSPORT_UDP_IPV6 - if (obj->smpt == smp_udp_configs.ipv6_transport.smpt && addr->sa_family == AF_INET6) { + if (obj->smpt == smp_udp_configs.ipv6_transport.smpt && addr->sa_family == NET_AF_INET6) { smp_client_object_set_data(obj, addr); return 0; } From f64dc213fb535df5792f682598041242aaf3ea97 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 15 Dec 2025 18:01:42 +0100 Subject: [PATCH 0643/3659] drivers: ethernet: dsa_nxp_imx_netc: Fix net API use In e6daacf3c9e3fbe879fe5b3cd451550d64d60784 the mayority of the ethernet drivers code was changed to use the Zephyr native net_ prefixed symbols, but some were forgotten. Without this fix/change the code still builds as we are by now setting CONFIG_NET_NAMESPACE_COMPAT_MODE. But when this is not set, things fail to build. Signed-off-by: Alberto Escolar Piedras --- drivers/ethernet/dsa/dsa_nxp_imx_netc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ethernet/dsa/dsa_nxp_imx_netc.c b/drivers/ethernet/dsa/dsa_nxp_imx_netc.c index 8d0c0bc5597d..4cd2e3952f8d 100644 --- a/drivers/ethernet/dsa/dsa_nxp_imx_netc.c +++ b/drivers/ethernet/dsa/dsa_nxp_imx_netc.c @@ -142,7 +142,7 @@ static int dsa_netc_switch_setup(const struct dsa_switch_context *dsa_switch_ctx * Trap gPTP frames to cpu port to perform gPTP protocol. */ netc_tb_ipf_config_t ipf_entry_cfg = { - .keye.etherType = htons(NET_ETH_PTYPE_PTP), + .keye.etherType = net_htons(NET_ETH_PTYPE_PTP), .keye.etherTypeMask = 0xffff, .keye.srcPort = 0, .keye.srcPortMask = 0x0, From 3e908843dec8f7d182f189d470860036c76bb7e7 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Tue, 16 Dec 2025 16:57:15 +0100 Subject: [PATCH 0644/3659] drivers: modem: wncm14a2a: Fix net API use In b5588ed684365eedfb55822804af3d0c3cd944ab, and after in e19d78e6070c4c3a2d315219d38ea66a100ec161 the mayority of the Zephyr modem drivers were changed to use the Zephyr native net_ prefixed types, but a few were missing. Without this fix/change the code still builds as we are by now setting CONFIG_NET_NAMESPACE_COMPAT_MODE. But when this is not set, things fail to build. Signed-off-by: Alberto Escolar Piedras --- drivers/modem/wncm14a2a.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/modem/wncm14a2a.c b/drivers/modem/wncm14a2a.c index b9249a2dcce0..6167caf8a678 100644 --- a/drivers/modem/wncm14a2a.c +++ b/drivers/modem/wncm14a2a.c @@ -1465,7 +1465,7 @@ static int offload_get(net_sa_family_t family, static int offload_bind(struct net_context *context, const struct net_sockaddr *addr, - socklen_t addrlen) + net_socklen_t addrlen) { struct wncm14a2a_socket *sock = NULL; @@ -1505,7 +1505,7 @@ static int offload_listen(struct net_context *context, int backlog) static int offload_connect(struct net_context *context, const struct net_sockaddr *addr, - socklen_t addrlen, + net_socklen_t addrlen, net_context_connect_cb_t cb, int32_t timeout, void *user_data) @@ -1590,7 +1590,7 @@ static int offload_accept(struct net_context *context, static int offload_sendto(struct net_pkt *pkt, const struct net_sockaddr *dst_addr, - socklen_t addrlen, + net_socklen_t addrlen, net_context_send_cb_t cb, int32_t timeout, void *user_data) @@ -1629,7 +1629,7 @@ static int offload_send(struct net_pkt *pkt, void *user_data) { struct net_context *context = net_pkt_context(pkt); - socklen_t addrlen; + net_socklen_t addrlen; if (IS_ENABLED(CONFIG_NET_IPV6) && net_pkt_family(pkt) == NET_AF_INET6) { addrlen = sizeof(struct net_sockaddr_in6); From fe41b6daf2e08b03e1db1f585b5a3ef5ca9edfb4 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Tue, 16 Dec 2025 16:59:00 +0100 Subject: [PATCH 0645/3659] drivers: modem: sim7080: Fix net API use In b5588ed684365eedfb55822804af3d0c3cd944ab, and after in e19d78e6070c4c3a2d315219d38ea66a100ec161 the mayority of the Zephyr modem drivers were changed to use the Zephyr native net_ prefixed types, but a few were missing. Without this fix/change the code still builds as we are by now setting CONFIG_NET_NAMESPACE_COMPAT_MODE. But when this is not set, things fail to build. Signed-off-by: Alberto Escolar Piedras --- drivers/modem/simcom/sim7080/sim7080_dns.c | 4 ++-- drivers/modem/simcom/sim7080/sim7080_sock.c | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/modem/simcom/sim7080/sim7080_dns.c b/drivers/modem/simcom/sim7080/sim7080_dns.c index e5e96cabcb69..c571f2b0ccf3 100644 --- a/drivers/modem/simcom/sim7080/sim7080_dns.c +++ b/drivers/modem/simcom/sim7080/sim7080_dns.c @@ -99,7 +99,7 @@ static int offload_getaddrinfo(const char *node, const char *service, if (port > 0U) { if (dns_result.ai_family == NET_AF_INET) { - net_sin(&dns_result_addr)->sin_port = htons(port); + net_sin(&dns_result_addr)->sin_port = net_htons(port); } } @@ -111,7 +111,7 @@ static int offload_getaddrinfo(const char *node, const char *service, } /* user flagged node as numeric host, but we failed net_addr_pton */ - if (hints && hints->ai_flags & AI_NUMERICHOST) { + if (hints && hints->ai_flags & ZSOCK_AI_NUMERICHOST) { return DNS_EAI_NONAME; } diff --git a/drivers/modem/simcom/sim7080/sim7080_sock.c b/drivers/modem/simcom/sim7080/sim7080_sock.c index 0b6961d051eb..ebef507c4243 100644 --- a/drivers/modem/simcom/sim7080/sim7080_sock.c +++ b/drivers/modem/simcom/sim7080/sim7080_sock.c @@ -31,7 +31,7 @@ MODEM_CMD_DEFINE(on_cmd_caopen) /* * Connects an modem socket. Protocol can either be TCP or UDP. */ -static int offload_connect(void *obj, const struct net_sockaddr *addr, socklen_t addrlen) +static int offload_connect(void *obj, const struct net_sockaddr *addr, net_socklen_t addrlen) { struct modem_socket *sock = (struct modem_socket *)obj; uint16_t dst_port = 0; @@ -67,7 +67,7 @@ static int offload_connect(void *obj, const struct net_sockaddr *addr, socklen_t } /* Get protocol */ - protocol = (sock->type == SOCK_STREAM) ? "TCP" : "UDP"; + protocol = (sock->type == NET_SOCK_STREAM) ? "TCP" : "UDP"; ret = modem_context_sprint_ip_addr(addr, ip_str, sizeof(ip_str)); if (ret != 0) { @@ -304,7 +304,7 @@ MODEM_CMD_DEFINE(on_cmd_carecv) * Read data from a given socket. */ static ssize_t offload_recvfrom(void *obj, void *buf, size_t max_len, int flags, - struct net_sockaddr *src_addr, socklen_t *addrlen) + struct net_sockaddr *src_addr, net_socklen_t *addrlen) { struct modem_socket *sock = (struct modem_socket *)obj; char sendbuf[sizeof("AT+CARECV=##,####")]; From d9b34059d95cdefa7fe2add6177ab09093bce4f5 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Tue, 16 Dec 2025 16:59:45 +0100 Subject: [PATCH 0646/3659] drivers: modem: quectel-bg9x: Fix net API use In b5588ed684365eedfb55822804af3d0c3cd944ab, and after in e19d78e6070c4c3a2d315219d38ea66a100ec161 the mayority of the Zephyr modem drivers were changed to use the Zephyr native net_ prefixed types, but a few were missing. Without this fix/change the code still builds as we are by now setting CONFIG_NET_NAMESPACE_COMPAT_MODE. But when this is not set, things fail to build. Signed-off-by: Alberto Escolar Piedras --- drivers/modem/quectel-bg9x.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/modem/quectel-bg9x.c b/drivers/modem/quectel-bg9x.c index c54ad26a065c..b41c8169e25f 100644 --- a/drivers/modem/quectel-bg9x.c +++ b/drivers/modem/quectel-bg9x.c @@ -519,7 +519,7 @@ static ssize_t send_socket_data(struct modem_socket *sock, */ static ssize_t offload_sendto(void *obj, const void *buf, size_t len, int flags, const struct net_sockaddr *to, - socklen_t tolen) + net_socklen_t tolen) { int ret; struct modem_socket *sock = (struct modem_socket *) obj; @@ -576,7 +576,7 @@ static ssize_t offload_sendto(void *obj, const void *buf, size_t len, */ static ssize_t offload_recvfrom(void *obj, void *buf, size_t len, int flags, struct net_sockaddr *from, - socklen_t *fromlen) + net_socklen_t *fromlen) { struct modem_socket *sock = (struct modem_socket *)obj; char sendbuf[sizeof("AT+QIRD=##,####")] = {0}; @@ -685,7 +685,7 @@ static int offload_ioctl(void *obj, unsigned int request, va_list args) * Desc: This function will connect with a provided TCP. */ static int offload_connect(void *obj, const struct net_sockaddr *addr, - socklen_t addrlen) + net_socklen_t addrlen) { struct modem_socket *sock = (struct modem_socket *) obj; uint16_t dst_port = 0; From edcc44fb80b43986b523f1e58c632bfd3620a7e1 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Tue, 16 Dec 2025 17:00:44 +0100 Subject: [PATCH 0647/3659] drivers: modem: hl78xx: Fix net API use In b5588ed684365eedfb55822804af3d0c3cd944ab, and after in e19d78e6070c4c3a2d315219d38ea66a100ec161 the mayority of the Zephyr modem drivers were changed to use the Zephyr native net_ prefixed types, but a few were missing. Without this fix/change the code still builds as we are by now setting CONFIG_NET_NAMESPACE_COMPAT_MODE. But when this is not set, things fail to build. Signed-off-by: Alberto Escolar Piedras --- drivers/modem/hl78xx/hl78xx_sockets.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/modem/hl78xx/hl78xx_sockets.c b/drivers/modem/hl78xx/hl78xx_sockets.c index 748a10ccbaee..88c46d0ad9c3 100644 --- a/drivers/modem/hl78xx/hl78xx_sockets.c +++ b/drivers/modem/hl78xx/hl78xx_sockets.c @@ -60,11 +60,11 @@ RING_BUF_DECLARE(mdm_recv_pool, CONFIG_MODEM_HL78XX_UART_BUFFER_SIZES); struct hl78xx_dns_info { #ifdef CONFIG_NET_IPV4 char v4_string[NET_IPV4_ADDR_LEN]; - struct in_addr v4; + struct net_in_addr v4; #endif #ifdef CONFIG_NET_IPV6 char v6_string[NET_IPV6_ADDR_LEN]; - struct in6_addr v6; + struct net_in6_addr v6; #endif bool ready; }; @@ -72,19 +72,19 @@ struct hl78xx_dns_info { /* IPv4 information is optional and only present when IPv4 is enabled */ #ifdef CONFIG_NET_IPV4 struct hl78xx_ipv4_info { - struct in_addr addr; - struct in_addr subnet; - struct in_addr gateway; - struct in_addr new_addr; + struct net_in_addr addr; + struct net_in_addr subnet; + struct net_in_addr gateway; + struct net_in_addr new_addr; }; #endif /* IPv6 information is optional and only present when IPv6 is enabled */ #ifdef CONFIG_NET_IPV6 struct hl78xx_ipv6_info { - struct in6_addr addr; - struct in6_addr subnet; - struct in6_addr gateway; - struct in6_addr new_addr; + struct net_in6_addr addr; + struct net_in6_addr subnet; + struct net_in6_addr gateway; + struct net_in6_addr new_addr; }; #endif /* TLS information is optional and only present when TLS is enabled */ @@ -1776,7 +1776,7 @@ static void check_tcp_state_if_needed(struct hl78xx_socket_data *socket_data, { const char *check_ktcp_stat = "AT+KTCPSTAT"; /* Only check for TCP sockets */ - if (sock->type != SOCK_STREAM) { + if (sock->type != NET_SOCK_STREAM) { return; } if (atomic_test_and_clear_bit(&socket_data->mdata_global->state_leftover, @@ -2229,7 +2229,7 @@ static ssize_t offload_write(void *obj, const void *buffer, size_t count) static ssize_t offload_sendmsg(void *obj, const struct net_msghdr *msg, int flags) { ssize_t sent = 0; - struct iovec bkp_iovec = {0}; + struct net_iovec bkp_iovec = {0}; struct net_msghdr crafted_msg = { .msg_name = msg->msg_name, .msg_namelen = msg->msg_namelen From 4cc278ffc9d70b5d0c267f45cd3cc22b4107e396 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Tue, 16 Dec 2025 16:22:36 +0000 Subject: [PATCH 0648/3659] drivers: spi: esp32: set dma tx/rx separately Split the code for DMA setting to consider the tx and rx buffers separately, this makes the driver work for use cases where tx only or rx only is needed, such as when using this with the ws2812 driver. Signed-off-by: Fabio Baltieri --- drivers/spi/spi_esp32_spim.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/spi/spi_esp32_spim.c b/drivers/spi/spi_esp32_spim.c index 35fc62f13db4..5d2165842118 100644 --- a/drivers/spi/spi_esp32_spim.c +++ b/drivers/spi/spi_esp32_spim.c @@ -191,7 +191,7 @@ static int IRAM_ATTR spi_esp32_transfer(const struct device *dev) spi_hal_setup_trans(hal, hal_dev, hal_trans); #if defined(SOC_GDMA_SUPPORTED) - if (cfg->dma_enabled && hal_trans->rcv_buffer && hal_trans->send_buffer) { + if (cfg->dma_enabled && hal_trans->rcv_buffer) { /* setup DMA channels via DMA driver */ spi_ll_dma_rx_fifo_reset(hal->hw); spi_ll_infifo_full_clr(hal->hw); @@ -202,7 +202,9 @@ static int IRAM_ATTR spi_esp32_transfer(const struct device *dev) if (err) { goto free; } + } + if (cfg->dma_enabled && hal_trans->send_buffer) { spi_ll_dma_tx_fifo_reset(hal->hw); spi_ll_outfifo_empty_clr(hal->hw); spi_ll_dma_tx_enable(hal->hw, 1); From 46cf6e707eef0454d63f73725f67c49bcbe655dc Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Tue, 16 Dec 2025 17:30:03 +0100 Subject: [PATCH 0649/3659] tests: net: socket: offload_dispatcher: Add extra test case for TLS Socket dispatcher should create a native TLS socket with a native underlying socket even if the socket is only bound to a native interface, it shouldn't be needed to call ZSOCK_TLS_NATIVE specifically. This works just fine, so add a test case for this scenario to make sure it remains that way. Signed-off-by: Robert Lubos --- .../net/socket/offload_dispatcher/src/main.c | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/tests/net/socket/offload_dispatcher/src/main.c b/tests/net/socket/offload_dispatcher/src/main.c index 24f73c2a2620..7df867250703 100644 --- a/tests/net/socket/offload_dispatcher/src/main.c +++ b/tests/net/socket/offload_dispatcher/src/main.c @@ -845,6 +845,44 @@ ZTEST(net_socket_offload_tls, test_tls_native_iface_native) zassert_equal(0, ret, "sendto() should've been dispatched to native iface"); } +/* Verify that the TLS and underlying sockets are dispatched to a native socket + * implementation if the socket is bound to a native interface. + */ +ZTEST(net_socket_offload_tls, test_tls_native_iface_native_bindtodevice_only) +{ + int ret; + const struct fd_op_vtable *vtable; + void *obj; + struct net_ifreq ifreq = { +#if defined(CONFIG_NET_INTERFACE_NAME) + .ifr_name = "dummy0" +#else + .ifr_name = "dummy_native" +#endif + }; + struct net_sockaddr_in addr = test_peer_addr; + + ret = zsock_setsockopt(test_sock, ZSOCK_SOL_SOCKET, ZSOCK_SO_BINDTODEVICE, + &ifreq, sizeof(ifreq)); + zassert_ok(ret, "setsockopt() failed"); + zassert_false(test_socket_ctx[OFFLOAD_1].socket_called, + "Underlying socket dispatched to wrong iface"); + zassert_false(test_socket_ctx[OFFLOAD_2].socket_called, + "Underlying socket dispatched to wrong iface"); + + obj = zvfs_get_fd_obj_and_vtable(test_sock, &vtable, NULL); + zassert_not_null(obj, "No obj found"); + zassert_true(net_socket_is_tls(obj), "Socket is not a native TLS sock"); + + /* Ignore connect result as it will fail anyway. Just verify the + * call/packets were forwarded to a valid iface. + */ + (void)zsock_connect(test_sock, (struct net_sockaddr *)&addr, sizeof(addr)); + + ret = k_sem_take(&test_native_send_called, K_MSEC(200)); + zassert_ok(ret, "sendto() should've been dispatched to native iface"); +} + ZTEST_SUITE(net_socket_offload_udp, NULL, NULL, test_socket_setup_udp, test_socket_teardown, NULL); ZTEST_SUITE(net_socket_offload_tls, NULL, NULL, test_socket_setup_tls, From e861b2681dbfaf75ad18258740acb56288175c5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Thu, 18 Dec 2025 12:02:52 +0100 Subject: [PATCH 0650/3659] drivers: dts: ti: fix typo in "Texas Instruments" company name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit s/Texas Instrument/Texas Instruments/g Signed-off-by: Benjamin Cabé --- drivers/serial/Kconfig.stellaris | 2 +- dts/bindings/adc/ti,ads1013.yaml | 2 +- dts/bindings/adc/ti,ads1014.yaml | 2 +- dts/bindings/adc/ti,ads1015.yaml | 2 +- dts/bindings/adc/ti,ads1112.yaml | 2 +- dts/bindings/adc/ti,ads1113.yaml | 2 +- dts/bindings/adc/ti,ads1114.yaml | 2 +- dts/bindings/adc/ti,ads1115.yaml | 2 +- dts/bindings/adc/ti,ads1119.yaml | 2 +- dts/bindings/adc/ti,ads114s06.yaml | 2 +- dts/bindings/adc/ti,ads114s08.yaml | 2 +- dts/bindings/adc/ti,ads124s06.yaml | 2 +- dts/bindings/adc/ti,ads124s08.yaml | 2 +- dts/bindings/adc/ti,ads131m02.yaml | 2 +- dts/bindings/adc/ti,ads7052.yaml | 2 +- 15 files changed, 15 insertions(+), 15 deletions(-) diff --git a/drivers/serial/Kconfig.stellaris b/drivers/serial/Kconfig.stellaris index 824ff124aa29..f4650147049b 100644 --- a/drivers/serial/Kconfig.stellaris +++ b/drivers/serial/Kconfig.stellaris @@ -9,7 +9,7 @@ menuconfig UART_STELLARIS help This option enables the Stellaris serial driver. This specific driver can be used for the serial hardware - available at the Texas Instrument LM3S6965 board. + available at the Texas Instruments LM3S6965 board. if UART_STELLARIS diff --git a/dts/bindings/adc/ti,ads1013.yaml b/dts/bindings/adc/ti,ads1013.yaml index 636ced6f4ab8..762313b9401d 100644 --- a/dts/bindings/adc/ti,ads1013.yaml +++ b/dts/bindings/adc/ti,ads1013.yaml @@ -1,4 +1,4 @@ -description: Texas Instrument ADS1013 I2C ADC +description: Texas Instruments ADS1013 I2C ADC compatible: "ti,ads1013" diff --git a/dts/bindings/adc/ti,ads1014.yaml b/dts/bindings/adc/ti,ads1014.yaml index c08d80c1e0b2..8bd94f67c857 100644 --- a/dts/bindings/adc/ti,ads1014.yaml +++ b/dts/bindings/adc/ti,ads1014.yaml @@ -1,4 +1,4 @@ -description: Texas Instrument ADS1014 I2C ADC +description: Texas Instruments ADS1014 I2C ADC compatible: "ti,ads1014" diff --git a/dts/bindings/adc/ti,ads1015.yaml b/dts/bindings/adc/ti,ads1015.yaml index c6b33b1688ab..b611c80e55f3 100644 --- a/dts/bindings/adc/ti,ads1015.yaml +++ b/dts/bindings/adc/ti,ads1015.yaml @@ -1,4 +1,4 @@ -description: Texas Instrument ADS1015 I2C ADC +description: Texas Instruments ADS1015 I2C ADC compatible: "ti,ads1015" diff --git a/dts/bindings/adc/ti,ads1112.yaml b/dts/bindings/adc/ti,ads1112.yaml index aac1d695d9ed..794013a15fb8 100644 --- a/dts/bindings/adc/ti,ads1112.yaml +++ b/dts/bindings/adc/ti,ads1112.yaml @@ -1,4 +1,4 @@ -description: Texas Instrument ADS1112 I2C ADC +description: Texas Instruments ADS1112 I2C ADC compatible: "ti,ads1112" diff --git a/dts/bindings/adc/ti,ads1113.yaml b/dts/bindings/adc/ti,ads1113.yaml index 55deb561ffe8..c893e04e69ed 100644 --- a/dts/bindings/adc/ti,ads1113.yaml +++ b/dts/bindings/adc/ti,ads1113.yaml @@ -1,4 +1,4 @@ -description: Texas Instrument ADS1113 I2C ADC +description: Texas Instruments ADS1113 I2C ADC compatible: "ti,ads1113" diff --git a/dts/bindings/adc/ti,ads1114.yaml b/dts/bindings/adc/ti,ads1114.yaml index eb0522cb98c3..eccf6bf84c81 100644 --- a/dts/bindings/adc/ti,ads1114.yaml +++ b/dts/bindings/adc/ti,ads1114.yaml @@ -1,4 +1,4 @@ -description: Texas Instrument ADS1114 I2C ADC +description: Texas Instruments ADS1114 I2C ADC compatible: "ti,ads1114" diff --git a/dts/bindings/adc/ti,ads1115.yaml b/dts/bindings/adc/ti,ads1115.yaml index f0b9c0bc1c63..b8858b1b9922 100644 --- a/dts/bindings/adc/ti,ads1115.yaml +++ b/dts/bindings/adc/ti,ads1115.yaml @@ -1,4 +1,4 @@ -description: Texas Instrument ADS1115 I2C ADC +description: Texas Instruments ADS1115 I2C ADC compatible: "ti,ads1115" diff --git a/dts/bindings/adc/ti,ads1119.yaml b/dts/bindings/adc/ti,ads1119.yaml index bb512eec1b4f..5ee9609c64b0 100644 --- a/dts/bindings/adc/ti,ads1119.yaml +++ b/dts/bindings/adc/ti,ads1119.yaml @@ -1,7 +1,7 @@ # Copyright (c) 2021, Innoseis # SPDX-License-Identifier: Apache-2.0 -description: Texas Instrument 4 channels I2C ADC +description: Texas Instruments 4 channels I2C ADC compatible: "ti,ads1119" diff --git a/dts/bindings/adc/ti,ads114s06.yaml b/dts/bindings/adc/ti,ads114s06.yaml index 7a9d65e12691..8b90c2a5d205 100644 --- a/dts/bindings/adc/ti,ads114s06.yaml +++ b/dts/bindings/adc/ti,ads114s06.yaml @@ -1,7 +1,7 @@ # Copyright (c) 2024 The Zephyr Project Contributors # SPDX-License-Identifier: Apache-2.0 -description: Texas Instrument 6 channels 16 bit SPI ADC +description: Texas Instruments 6 channels 16 bit SPI ADC compatible: "ti,ads114s06" diff --git a/dts/bindings/adc/ti,ads114s08.yaml b/dts/bindings/adc/ti,ads114s08.yaml index 45a376e50e37..783aab7e6be8 100644 --- a/dts/bindings/adc/ti,ads114s08.yaml +++ b/dts/bindings/adc/ti,ads114s08.yaml @@ -1,7 +1,7 @@ # Copyright (c) 2023 SILA Embedded Solutions GmbH # SPDX-License-Identifier: Apache-2.0 -description: Texas Instrument 12 channels 16 bit SPI ADC +description: Texas Instruments 12 channels 16 bit SPI ADC compatible: "ti,ads114s08" diff --git a/dts/bindings/adc/ti,ads124s06.yaml b/dts/bindings/adc/ti,ads124s06.yaml index ca113e746264..c85767ac345f 100644 --- a/dts/bindings/adc/ti,ads124s06.yaml +++ b/dts/bindings/adc/ti,ads124s06.yaml @@ -1,7 +1,7 @@ # Copyright (c) 2024 The Zephyr Project Contributors # SPDX-License-Identifier: Apache-2.0 -description: Texas Instrument 6 channels 24 bit SPI ADC +description: Texas Instruments 6 channels 24 bit SPI ADC compatible: "ti,ads124s06" diff --git a/dts/bindings/adc/ti,ads124s08.yaml b/dts/bindings/adc/ti,ads124s08.yaml index ab38b3f89258..18b7b1422177 100644 --- a/dts/bindings/adc/ti,ads124s08.yaml +++ b/dts/bindings/adc/ti,ads124s08.yaml @@ -1,7 +1,7 @@ # Copyright (c) 2024 The Zephyr Project Contributors # SPDX-License-Identifier: Apache-2.0 -description: Texas Instrument 12 channels 24 bit SPI ADC +description: Texas Instruments 12 channels 24 bit SPI ADC compatible: "ti,ads124s08" diff --git a/dts/bindings/adc/ti,ads131m02.yaml b/dts/bindings/adc/ti,ads131m02.yaml index bc58c5e60daf..159f395fd0ee 100644 --- a/dts/bindings/adc/ti,ads131m02.yaml +++ b/dts/bindings/adc/ti,ads131m02.yaml @@ -1,7 +1,7 @@ # Copyright (c) 2024 Linumiz # SPDX-License-Identifier: Apache-2.0 -description: Texas Instrument 2 channels SPI ADC +description: Texas Instruments 2 channels SPI ADC compatible: "ti,ads131m02" diff --git a/dts/bindings/adc/ti,ads7052.yaml b/dts/bindings/adc/ti,ads7052.yaml index 5ca385a492ab..b181fcc6d7b7 100644 --- a/dts/bindings/adc/ti,ads7052.yaml +++ b/dts/bindings/adc/ti,ads7052.yaml @@ -1,7 +1,7 @@ # Copyright (c) 2023, Google LLC # SPDX-License-Identifier: Apache-2.0 -description: Texas Instrument Single Channel SPI ADC +description: Texas Instruments Single Channel SPI ADC compatible: "ti,ads7052" From ecb5d3c898f9299d5ce3f769867fe279c171ba55 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Tue, 16 Dec 2025 18:09:47 +0100 Subject: [PATCH 0651/3659] drivers: wifi: esp_at: Fix net API use In 55c49cdb8f7e93b018f908fc8356212cc0e42da8 wifi drivers were changed to use the Zephyr native net_ prefixed types, but some were forgotten. Without this fix/change the code still builds as we are by now setting CONFIG_NET_NAMESPACE_COMPAT_MODE. But when this is not set, things fail to build. Signed-off-by: Alberto Escolar Piedras --- drivers/wifi/esp_at/esp.c | 4 ++-- drivers/wifi/esp_at/esp.h | 6 +++--- drivers/wifi/esp_at/esp_offload.c | 6 +++--- drivers/wifi/esp_at/esp_socket.c | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/wifi/esp_at/esp.c b/drivers/wifi/esp_at/esp.c index 483849a2129a..b5a6be9d04ce 100644 --- a/drivers/wifi/esp_at/esp.c +++ b/drivers/wifi/esp_at/esp.c @@ -575,7 +575,7 @@ MODEM_CMD_DEFINE(on_cmd_cipdns) } addrs[i].sin_family = NET_AF_INET; - addrs[i].sin_port = htons(53); + addrs[i].sin_port = net_htons(53); valid_servers++; } @@ -891,7 +891,7 @@ static int cmd_ipd_parse_hdr(struct esp_data *dev, } recv_addr->sin_family = NET_AF_INET; - recv_addr->sin_port = htons(port); + recv_addr->sin_port = net_htons(port); } *data_offset = (str - ipd_buf); diff --git a/drivers/wifi/esp_at/esp.h b/drivers/wifi/esp_at/esp.h index c196f8798404..2e539377a856 100644 --- a/drivers/wifi/esp_at/esp.h +++ b/drivers/wifi/esp_at/esp.h @@ -224,9 +224,9 @@ struct esp_data { enum wifi_conn_status conn_status; /* addresses */ - struct in_addr ip; - struct in_addr gw; - struct in_addr nm; + struct net_in_addr ip; + struct net_in_addr gw; + struct net_in_addr nm; uint8_t mac_addr[6]; #if defined(ESP_MAX_DNS) struct net_sockaddr_in dns_addresses[ESP_MAX_DNS]; diff --git a/drivers/wifi/esp_at/esp_offload.c b/drivers/wifi/esp_at/esp_offload.c index 744ca2840a4a..c3d1f695ab79 100644 --- a/drivers/wifi/esp_at/esp_offload.c +++ b/drivers/wifi/esp_at/esp_offload.c @@ -151,7 +151,7 @@ void esp_connect_work(struct k_work *work) } static int esp_bind(struct net_context *context, const struct net_sockaddr *addr, - socklen_t addrlen) + net_socklen_t addrlen) { struct esp_socket *sock; struct esp_data *dev; @@ -182,7 +182,7 @@ static int esp_bind(struct net_context *context, const struct net_sockaddr *addr static int esp_connect(struct net_context *context, const struct net_sockaddr *addr, - socklen_t addrlen, + net_socklen_t addrlen, net_context_connect_cb_t cb, int32_t timeout, void *user_data) @@ -422,7 +422,7 @@ void esp_send_work(struct k_work *work) static int esp_sendto(struct net_pkt *pkt, const struct net_sockaddr *dst_addr, - socklen_t addrlen, + net_socklen_t addrlen, net_context_send_cb_t cb, int32_t timeout, void *user_data) diff --git a/drivers/wifi/esp_at/esp_socket.c b/drivers/wifi/esp_at/esp_socket.c index 3174e2f177e8..a256d18ec60c 100644 --- a/drivers/wifi/esp_at/esp_socket.c +++ b/drivers/wifi/esp_at/esp_socket.c @@ -180,7 +180,7 @@ void esp_socket_rx(struct esp_socket *sock, struct net_buf *buf, pkt = esp_socket_prepare_pkt(sock, buf, offset, len); if (!pkt) { LOG_ERR("Failed to get net_pkt: len %zu", len); - if (esp_socket_type(sock) == SOCK_STREAM) { + if (esp_socket_type(sock) == NET_SOCK_STREAM) { if (!esp_socket_flags_test_and_set(sock, ESP_SOCK_CLOSE_PENDING)) { esp_socket_work_submit(sock, &sock->close_work); From b7261fad59d686a79fda3db1a5785a67af57f7c2 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Tue, 16 Dec 2025 18:10:50 +0100 Subject: [PATCH 0652/3659] drivers: wifi: eswifi: Fix net API use In 55c49cdb8f7e93b018f908fc8356212cc0e42da8 wifi drivers were changed to use the Zephyr native net_ prefixed types, but some were forgotten. Without this fix/change the code still builds as we are by now setting CONFIG_NET_NAMESPACE_COMPAT_MODE. But when this is not set, things fail to build. Signed-off-by: Alberto Escolar Piedras --- drivers/wifi/eswifi/eswifi.h | 2 +- drivers/wifi/eswifi/eswifi_core.c | 2 +- drivers/wifi/eswifi/eswifi_offload.c | 10 +++++----- drivers/wifi/eswifi/eswifi_socket.c | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/wifi/eswifi/eswifi.h b/drivers/wifi/eswifi/eswifi.h index 97fd02af6903..f0418bc33caf 100644 --- a/drivers/wifi/eswifi/eswifi.h +++ b/drivers/wifi/eswifi/eswifi.h @@ -141,7 +141,7 @@ int __eswifi_off_start_client(struct eswifi_dev *eswifi, int __eswifi_listen(struct eswifi_dev *eswifi, struct eswifi_off_socket *socket, int backlog); int __eswifi_accept(struct eswifi_dev *eswifi, struct eswifi_off_socket *socket); int __eswifi_bind(struct eswifi_dev *eswifi, struct eswifi_off_socket *socket, - const struct net_sockaddr *addr, socklen_t addrlen); + const struct net_sockaddr *addr, net_socklen_t addrlen); #if defined(CONFIG_NET_SOCKETS_OFFLOAD) int eswifi_socket_offload_init(struct eswifi_dev *leswifi); #endif diff --git a/drivers/wifi/eswifi/eswifi_core.c b/drivers/wifi/eswifi/eswifi_core.c index ddf32ab6f094..8e86b4a9456e 100644 --- a/drivers/wifi/eswifi/eswifi_core.c +++ b/drivers/wifi/eswifi/eswifi_core.c @@ -256,7 +256,7 @@ static void eswifi_scan(struct eswifi_dev *eswifi) static int eswifi_connect(struct eswifi_dev *eswifi) { char connect[] = "C0\r"; - struct in_addr addr; + struct net_in_addr addr; char *rsp; int err; diff --git a/drivers/wifi/eswifi/eswifi_offload.c b/drivers/wifi/eswifi/eswifi_offload.c index 57e5369cee67..33ccc6ec3750 100644 --- a/drivers/wifi/eswifi/eswifi_offload.c +++ b/drivers/wifi/eswifi/eswifi_offload.c @@ -22,7 +22,7 @@ LOG_MODULE_DECLARE(LOG_MODULE_NAME); static int eswifi_off_bind(struct net_context *context, const struct net_sockaddr *addr, - socklen_t addrlen) + net_socklen_t addrlen) { struct eswifi_off_socket *socket = context->offload_context; struct eswifi_dev *eswifi = eswifi_by_iface_idx(context->iface); @@ -98,7 +98,7 @@ static void eswifi_off_connect_work(struct k_work *work) static int eswifi_off_connect(struct net_context *context, const struct net_sockaddr *addr, - socklen_t addrlen, + net_socklen_t addrlen, net_context_connect_cb_t cb, int32_t timeout, void *user_data) @@ -295,7 +295,7 @@ static int eswifi_off_send(struct net_pkt *pkt, static int eswifi_off_sendto(struct net_pkt *pkt, const struct net_sockaddr *dst_addr, - socklen_t addrlen, + net_socklen_t addrlen, net_context_send_cb_t cb, int32_t timeout, void *user_data) @@ -446,7 +446,7 @@ void eswifi_offload_async_msg(struct eswifi_dev *eswifi, char *msg, size_t len) if (!strncmp(msg, msg_tcp_accept, sizeof(msg_tcp_accept) - 1)) { struct eswifi_off_socket *socket = NULL; - struct in_addr *sin_addr; + struct net_in_addr *sin_addr; uint8_t ip[4]; uint16_t port = 0; char *str; @@ -488,7 +488,7 @@ void eswifi_offload_async_msg(struct eswifi_dev *eswifi, char *msg, size_t len) sin_addr = &peer->sin_addr; memcpy(&sin_addr->s4_addr, ip, 4); - peer->sin_port = htons(port); + peer->sin_port = net_htons(port); peer->sin_family = NET_AF_INET; socket->state = ESWIFI_SOCKET_STATE_CONNECTED; socket->usage++; diff --git a/drivers/wifi/eswifi/eswifi_socket.c b/drivers/wifi/eswifi/eswifi_socket.c index 427004034b89..500192677191 100644 --- a/drivers/wifi/eswifi/eswifi_socket.c +++ b/drivers/wifi/eswifi/eswifi_socket.c @@ -75,7 +75,7 @@ static int __read_data(struct eswifi_dev *eswifi, size_t len, char **data) } int __eswifi_bind(struct eswifi_dev *eswifi, struct eswifi_off_socket *socket, - const struct net_sockaddr *addr, socklen_t addrlen) + const struct net_sockaddr *addr, net_socklen_t addrlen) { int err; @@ -196,7 +196,7 @@ int __eswifi_off_start_client(struct eswifi_dev *eswifi, struct eswifi_off_socket *socket) { struct net_sockaddr *addr = &socket->peer_addr; - struct in_addr *sin_addr = &net_sin(addr)->sin_addr; + struct net_in_addr *sin_addr = &net_sin(addr)->sin_addr; int err; LOG_DBG(""); From 9010e20e9fe243fbab9ecd91288e0f3733292e87 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Tue, 16 Dec 2025 18:11:30 +0100 Subject: [PATCH 0653/3659] drivers: wifi: nxp: Fix net API use In 55c49cdb8f7e93b018f908fc8356212cc0e42da8 wifi drivers were changed to use the Zephyr native net_ prefixed types, but some were forgotten. Without this fix/change the code still builds as we are by now setting CONFIG_NET_NAMESPACE_COMPAT_MODE. But when this is not set, things fail to build. Signed-off-by: Alberto Escolar Piedras --- drivers/wifi/nxp/nxp_wifi_drv.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/wifi/nxp/nxp_wifi_drv.c b/drivers/wifi/nxp/nxp_wifi_drv.c index e02caa0d7e25..8ad22b21cc61 100644 --- a/drivers/wifi/nxp/nxp_wifi_drv.c +++ b/drivers/wifi/nxp/nxp_wifi_drv.c @@ -107,9 +107,9 @@ int nxp_wifi_wlan_event_callback(enum wlan_event_reason reason, void *data) static int auth_fail; #ifdef CONFIG_NXP_WIFI_SOFTAP_SUPPORT wlan_uap_client_disassoc_t *disassoc_resp = data; - struct in_addr dhcps_addr4; - struct in_addr base_addr; - struct in_addr netmask_addr; + struct net_in_addr dhcps_addr4; + struct net_in_addr base_addr; + struct net_in_addr netmask_addr; struct wifi_ap_sta_info ap_sta_info = { 0 }; #endif From 1fcb10298399fd8d924484eb5ae8e3fee841c802 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Tue, 16 Dec 2025 18:12:33 +0100 Subject: [PATCH 0654/3659] drivers: wifi: simplelink: Fix net API use In 55c49cdb8f7e93b018f908fc8356212cc0e42da8 wifi drivers were changed to use the Zephyr native net_ prefixed types, but some were forgotten. Without this fix/change the code still builds as we are by now setting CONFIG_NET_NAMESPACE_COMPAT_MODE. But when this is not set, things fail to build. Signed-off-by: Alberto Escolar Piedras --- drivers/wifi/simplelink/simplelink_sockets.c | 45 ++++++++++---------- drivers/wifi/simplelink/simplelink_support.c | 2 +- 2 files changed, 23 insertions(+), 24 deletions(-) diff --git a/drivers/wifi/simplelink/simplelink_sockets.c b/drivers/wifi/simplelink/simplelink_sockets.c index 446bd408fcf9..7b031eed89a2 100644 --- a/drivers/wifi/simplelink/simplelink_sockets.c +++ b/drivers/wifi/simplelink/simplelink_sockets.c @@ -32,8 +32,7 @@ LOG_MODULE_DECLARE(LOG_MODULE_NAME); #define SD_TO_OBJ(sd) ((void *)(sd + 1)) #define OBJ_TO_SD(obj) (((int)obj) - 1) -static int simplelink_socket_accept(void *obj, struct net_sockaddr *addr, - socklen_t *addrlen); +static int simplelink_socket_accept(void *obj, struct net_sockaddr *addr, net_socklen_t *addrlen); /* * Convert SL error codes into BSD errno values @@ -204,13 +203,13 @@ static int simplelink_socket_family_from_posix(int family, int *family_sl) static int simplelink_socket_type_from_posix(int type, int *type_sl) { switch (type) { - case SOCK_STREAM: + case NET_SOCK_STREAM: *type_sl = SL_SOCK_STREAM; break; - case SOCK_DGRAM: + case NET_SOCK_DGRAM: *type_sl = SL_SOCK_DGRAM; break; - case SOCK_RAW: + case NET_SOCK_RAW: *type_sl = SL_SOCK_RAW; break; default: @@ -717,10 +716,10 @@ static int simplelink_setsockopt(void *obj, int level, int optname, int sd = OBJ_TO_SD(obj); int retval; - if (IS_ENABLED(CONFIG_NET_SOCKETS_SOCKOPT_TLS) && level == SOL_TLS) { + if (IS_ENABLED(CONFIG_NET_SOCKETS_SOCKOPT_TLS) && level == ZSOCK_SOL_TLS) { /* Handle Zephyr's SOL_TLS secure socket options: */ switch (optname) { - case TLS_SEC_TAG_LIST: + case ZSOCK_TLS_SEC_TAG_LIST: /* Bind credential filenames to this socket: */ retval = map_credentials(sd, optval, optlen); if (retval != 0) { @@ -728,12 +727,12 @@ static int simplelink_setsockopt(void *obj, int level, int optname, goto exit; } break; - case TLS_HOSTNAME: + case ZSOCK_TLS_HOSTNAME: retval = sl_SetSockOpt(sd, SL_SOL_SOCKET, _SEC_DOMAIN_VERIF, (const char *)optval, optlen); break; - case TLS_PEER_VERIFY: + case ZSOCK_TLS_PEER_VERIFY: if (optval) { /* * Not currently supported. Verification @@ -756,8 +755,8 @@ static int simplelink_setsockopt(void *obj, int level, int optname, goto exit; } break; - case TLS_CIPHERSUITE_LIST: - case TLS_DTLS_ROLE: + case ZSOCK_TLS_CIPHERSUITE_LIST: + case ZSOCK_TLS_DTLS_ROLE: /* Not yet supported: */ retval = slcb_SetErrno(ENOTSUP); goto exit; @@ -770,7 +769,7 @@ static int simplelink_setsockopt(void *obj, int level, int optname, /* Note: this logic should match SimpleLink SDK's socket.c: */ switch (optname) { - case TCP_NODELAY: + case ZSOCK_TCP_NODELAY: if (optval) { /* if user wishes to have TCP_NODELAY = FALSE, * we return EINVAL and fail in the cases below. @@ -785,9 +784,9 @@ static int simplelink_setsockopt(void *obj, int level, int optname, * EINVAL in order to not break "off-the-shelf" BSD * code. */ - case SO_BROADCAST: - case SO_REUSEADDR: - case SO_SNDBUF: + case ZSOCK_SO_BROADCAST: + case ZSOCK_SO_REUSEADDR: + case ZSOCK_SO_SNDBUF: retval = slcb_SetErrno(EINVAL); goto exit; default: @@ -811,12 +810,12 @@ static int simplelink_getsockopt(void *obj, int level, int optname, int sd = OBJ_TO_SD(obj); int retval; - if (IS_ENABLED(CONFIG_NET_SOCKETS_SOCKOPT_TLS) && level == SOL_TLS) { + if (IS_ENABLED(CONFIG_NET_SOCKETS_SOCKOPT_TLS) && level == ZSOCK_SOL_TLS) { /* Handle Zephyr's SOL_TLS secure socket options: */ switch (optname) { - case TLS_SEC_TAG_LIST: - case TLS_CIPHERSUITE_LIST: - case TLS_CIPHERSUITE_USED: + case ZSOCK_TLS_SEC_TAG_LIST: + case ZSOCK_TLS_CIPHERSUITE_LIST: + case ZSOCK_TLS_CIPHERSUITE_USED: /* Not yet supported: */ retval = slcb_SetErrno(ENOTSUP); goto exit; @@ -830,7 +829,7 @@ static int simplelink_getsockopt(void *obj, int level, int optname, /* Note: this logic should match SimpleLink SDK's socket.c: */ switch (optname) { /* TCP_NODELAY always set by the NWP, so return True */ - case TCP_NODELAY: + case ZSOCK_TCP_NODELAY: if (optval) { (*(_u32 *)optval) = TRUE; retval = 0; @@ -841,9 +840,9 @@ static int simplelink_getsockopt(void *obj, int level, int optname, * errno to EINVAL in order to not break "off-the-shelf" * BSD code. */ - case SO_BROADCAST: - case SO_REUSEADDR: - case SO_SNDBUF: + case ZSOCK_SO_BROADCAST: + case ZSOCK_SO_REUSEADDR: + case ZSOCK_SO_SNDBUF: retval = slcb_SetErrno(EINVAL); goto exit; default: diff --git a/drivers/wifi/simplelink/simplelink_support.c b/drivers/wifi/simplelink/simplelink_support.c index 3edb1b58cf00..898eb673e5eb 100644 --- a/drivers/wifi/simplelink/simplelink_support.c +++ b/drivers/wifi/simplelink/simplelink_support.c @@ -97,7 +97,7 @@ static int32_t configure_simplelink(void) uint8_t power; #if defined(CONFIG_NET_IPV4) && defined(CONFIG_NET_CONFIG_MY_IPV4_ADDR) - struct in_addr addr4; + struct net_in_addr addr4; SlNetCfgIpV4Args_t ipV4; memset(&ipV4, 0, sizeof(ipV4)); From 0a8d5881d4ac8bb4f15227dc2ae48ba467e742cc Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Tue, 16 Dec 2025 18:12:55 +0100 Subject: [PATCH 0655/3659] drivers: wifi: winc1500: Fix net API use In 55c49cdb8f7e93b018f908fc8356212cc0e42da8 wifi drivers were changed to use the Zephyr native net_ prefixed types, but some were forgotten. Without this fix/change the code still builds as we are by now setting CONFIG_NET_NAMESPACE_COMPAT_MODE. But when this is not set, things fail to build. Signed-off-by: Alberto Escolar Piedras --- drivers/wifi/winc1500/wifi_winc1500.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/wifi/winc1500/wifi_winc1500.c b/drivers/wifi/winc1500/wifi_winc1500.c index a6d9bafd6ce5..ae5b727f94c8 100644 --- a/drivers/wifi/winc1500/wifi_winc1500.c +++ b/drivers/wifi/winc1500/wifi_winc1500.c @@ -324,8 +324,8 @@ static int winc1500_get(net_sa_family_t family, * This function is called when user wants to bind to local IP address. */ static int winc1500_bind(struct net_context *context, - const struct sockaddr *addr, - socklen_t addrlen) + const struct net_sockaddr *addr, + net_socklen_t addrlen) { SOCKET socket = (intptr_t)context->offload_context; int ret; @@ -381,8 +381,8 @@ static int winc1500_listen(struct net_context *context, int backlog) * to a peer host. */ static int winc1500_connect(struct net_context *context, - const struct sockaddr *addr, - socklen_t addrlen, + const struct net_sockaddr *addr, + net_socklen_t addrlen, net_context_connect_cb_t cb, int32_t timeout, void *user_data) @@ -483,8 +483,8 @@ static int winc1500_send(struct net_pkt *pkt, * This function is called when user wants to send data to peer host. */ static int winc1500_sendto(struct net_pkt *pkt, - const struct sockaddr *dst_addr, - socklen_t addrlen, + const struct net_sockaddr *dst_addr, + net_socklen_t addrlen, net_context_send_cb_t cb, int32_t timeout, void *user_data) @@ -590,7 +590,7 @@ static int winc1500_put(struct net_context *context) struct socket_data *sd = &w1500_data.socket_data[sock]; int ret; - memset(&(context->remote), 0, sizeof(struct sockaddr_in)); + memset(&(context->remote), 0, sizeof(struct net_sockaddr_in)); context->flags &= ~NET_CONTEXT_REMOTE_ADDR_SET; ret = winc1500_close(sock); @@ -652,7 +652,7 @@ static void handle_wifi_con_state_changed(void *pvMsg) static void handle_wifi_dhcp_conf(void *pvMsg) { uint8_t *pu8IPAddress = (uint8_t *)pvMsg; - struct in_addr addr; + struct net_in_addr addr; uint8_t i; /* Connected and got IP address*/ @@ -916,8 +916,8 @@ static void handle_socket_msg_accept(struct socket_data *sd, void *pvMsg) a_sd->context->flags |= NET_CONTEXT_REMOTE_ADDR_SET; sd->accept_cb(a_sd->context, - (struct sockaddr *)&accept_msg->strAddr, - sizeof(struct sockaddr_in), + (struct net_sockaddr *)&accept_msg->strAddr, + sizeof(struct net_sockaddr_in), (accept_msg->sock > 0) ? 0 : accept_msg->sock, sd->accept_user_data); From 9a0e8a4148ceb6e3dc223c5f854eb19472843d90 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Tue, 16 Dec 2025 10:29:42 +0100 Subject: [PATCH 0656/3659] modules: nrf_wifi: Fix net API use In d45cd6716bbab3a805e3a5fd461934f0dcdc13e5 the mayority of the Zephyr codebased was changed to use the Zephyr native net_ prefixed types, but some were forgotten. Without this fix/change the code still builds as we are by now setting CONFIG_NET_NAMESPACE_COMPAT_MODE. But when this is not set, things fail to build. Signed-off-by: Alberto Escolar Piedras --- modules/nrf_wifi/os/shim.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/nrf_wifi/os/shim.c b/modules/nrf_wifi/os/shim.c index 7fe6373b485d..99224b665338 100644 --- a/modules/nrf_wifi/os/shim.c +++ b/modules/nrf_wifi/os/shim.c @@ -607,7 +607,7 @@ void *net_raw_pkt_from_nbuf(void *iface, void *frm, goto out; } - pkt = net_pkt_rx_alloc_with_buffer(iface, total_len, AF_PACKET, ETH_P_ALL, K_MSEC(100)); + pkt = net_pkt_rx_alloc_with_buffer(iface, total_len, NET_AF_PACKET, ETH_P_ALL, K_MSEC(100)); if (!pkt) { LOG_ERR("%s: Unable to allocate net packet buffer", __func__); goto out; From a73e3df5103461b1cde868a2f490a2f4c598372c Mon Sep 17 00:00:00 2001 From: Alex Hogen Date: Wed, 3 Dec 2025 17:34:11 -0800 Subject: [PATCH 0657/3659] drivers: regulator/fixed: Add voltage getter to fix device never ready When regulator-min-microvolt and regulator-max-microvolt properties are provided in the devicetree node, a fixed regulator is never ready due to failed initialization in regulator_common_init(). At at commit 9463d9a51d9cb1094bf98ef437a39850a7b5705d regulator_common.c lines 68-71, if min or max voltages are set, then regulator_common_init() attempts to get the regulator's current voltage setting so that it might "Snap to closest interval value if out of range." However regulator-fixed has not implemented the regulator_get_voltage() api, so regulator_common_init() fails. Adding an implementation for regulator_get_voltage() which returns min voltage, just like regulator_fixed_list_voltage() does, resolves this issue. Fixes zephyrproject-rtos/zephyr#99339 Signed-off-by: Alex Hogen --- drivers/regulator/regulator_fixed.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/regulator/regulator_fixed.c b/drivers/regulator/regulator_fixed.c index f56ab01d8d3c..7e024b608872 100644 --- a/drivers/regulator/regulator_fixed.c +++ b/drivers/regulator/regulator_fixed.c @@ -74,11 +74,17 @@ static int regulator_fixed_list_voltage(const struct device *dev, return 0; } +static int regulator_fixed_get_voltage(const struct device *dev, int32_t *volt_uv) +{ + return regulator_common_get_min_voltage(dev, volt_uv); +} + static DEVICE_API(regulator, regulator_fixed_api) = { .enable = regulator_fixed_enable, .disable = regulator_fixed_disable, .count_voltages = regulator_fixed_count_voltages, .list_voltage = regulator_fixed_list_voltage, + .get_voltage = regulator_fixed_get_voltage, }; static int regulator_fixed_init(const struct device *dev) From ed2af53f591e37f96736093b90225c04df99dcc3 Mon Sep 17 00:00:00 2001 From: Jason Yu Date: Thu, 6 Nov 2025 15:12:10 +0800 Subject: [PATCH 0658/3659] drivers: dma: dma_mcux_lpc: Support power device constraint Call pm_policy_device_power_lock_put/pm_policy_device_power_lock_get to coordinate with system level power modes. Signed-off-by: Jason Yu --- drivers/dma/dma_mcux_lpc.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/dma/dma_mcux_lpc.c b/drivers/dma/dma_mcux_lpc.c index 2cc7500dfc2a..42b9f3bb92ba 100644 --- a/drivers/dma/dma_mcux_lpc.c +++ b/drivers/dma/dma_mcux_lpc.c @@ -23,6 +23,7 @@ #include #include #include +#include #define DT_DRV_COMPAT nxp_lpc_dma @@ -108,6 +109,10 @@ static void nxp_lpc_dma_callback(dma_handle_t *handle, void *param, ret = DMA_STATUS_COMPLETE; } + if (!data->busy) { + pm_policy_device_power_lock_put(data->dev); + } + if (data->dma_callback) { data->dma_callback(data->dev, data->user_data, channel, ret); } @@ -563,6 +568,7 @@ static int dma_mcux_lpc_configure(const struct device *dev, uint32_t channel, if (data->busy) { DMA_AbortTransfer(p_handle); + pm_policy_device_power_lock_put(dev); } LOG_DBG("channel is %d", p_handle->channel); @@ -815,6 +821,7 @@ static int dma_mcux_lpc_start(const struct device *dev, uint32_t channel) LOG_DBG("START TRANSFER"); LOG_DBG("DMA CTRL 0x%x", DEV_BASE(dev)->CTRL); data->busy = true; + pm_policy_device_power_lock_get(dev); /* In case of a restart after a stop, reinstall the DMA callback * that was removed by the stop. */ @@ -836,7 +843,10 @@ static int dma_mcux_lpc_stop(const struct device *dev, uint32_t channel) DMA_AbortTransfer(p_handle); DMA_DisableChannel(DEV_BASE(dev), p_handle->channel); - data->busy = false; + if (data->busy) { + data->busy = false; + pm_policy_device_power_lock_put(dev); + } /* Handle race condition where if this is called from an ISR * and the DMA channel completion interrupt becomes pending From 24f8ed75cb56a41b8e989d49f6a22c1757a41164 Mon Sep 17 00:00:00 2001 From: Jason Yu Date: Fri, 14 Nov 2025 15:56:58 +0800 Subject: [PATCH 0659/3659] drivers: dma: dma_mcux_lpc: Add register backup and restore Add for the case that the registers are not kept in some low power modes. Signed-off-by: Jason Yu --- drivers/dma/dma_mcux_lpc.c | 93 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) diff --git a/drivers/dma/dma_mcux_lpc.c b/drivers/dma/dma_mcux_lpc.c index 42b9f3bb92ba..4f75c8cc34a0 100644 --- a/drivers/dma/dma_mcux_lpc.c +++ b/drivers/dma/dma_mcux_lpc.c @@ -29,6 +29,28 @@ LOG_MODULE_REGISTER(dma_mcux_lpc, CONFIG_DMA_LOG_LEVEL); +#if CONFIG_PM_DEVICE +/* + * Data structures to backup DMA registers when the + * register content lost in low power modes. + */ +struct dma_backup_reg { + /* + * Backup the control registers. + * Don't need to backup CTRL and SRAMBASE, they + * are configured in function DMA_Init. + */ + uint32_t enableset; /* Register ENABLESET */ + uint32_t intenset; /* Register INTENSET */ +}; + +struct dma_ch_backup_reg { + /* Don't need to backup status register CTLSTAT. */ + uint32_t cfg; /* Register CFG */ + uint32_t xfercfg; /* Register XFERCFG */ +}; +#endif /* CONFIG_PM_DEVICE */ + struct dma_mcux_lpc_config { DMA_Type *base; uint32_t otrig_base_address; @@ -54,6 +76,9 @@ struct channel_data { uint8_t num_of_descriptors; bool descriptors_queued; bool busy; +#if CONFIG_PM_DEVICE + struct dma_ch_backup_reg backup_reg; +#endif /* CONFIG_PM_DEVICE */ }; struct dma_otrig { @@ -68,6 +93,9 @@ struct dma_mcux_lpc_dma_data { struct dma_otrig *otrig_array; int8_t *channel_index; uint8_t num_channels_used; +#if CONFIG_PM_DEVICE + struct dma_backup_reg backup_reg; +#endif /* CONFIG_PM_DEVICE */ }; struct k_spinlock configuring_otrigs; @@ -948,6 +976,69 @@ static int dma_mcux_lpc_get_attribute(const struct device *dev, uint32_t type, u return 0; } +#if CONFIG_PM_DEVICE +static void dma_mcux_lpc_backup_reg(const struct device *dev) +{ + struct dma_mcux_lpc_dma_data *dma_data = dev->data; + const struct dma_mcux_lpc_config *config = dev->config; + struct channel_data *p_channel_data; + uint32_t virtual_channel; + DMA_Type *dma_base = DEV_BASE(dev); + + dma_data->backup_reg.enableset = dma_base->COMMON[0].ENABLESET; + dma_data->backup_reg.intenset = dma_base->COMMON[0].INTENSET; + + /* Only backup the used channels */ + virtual_channel = 0; + for (uint32_t channel = 0; channel < config->num_of_channels; channel++) { + if (dma_data->channel_index[channel] != -1) { + p_channel_data = &dma_data->channel_data[virtual_channel]; + + p_channel_data->backup_reg.xfercfg = dma_base->CHANNEL[channel].XFERCFG; + p_channel_data->backup_reg.cfg = dma_base->CHANNEL[channel].CFG; + virtual_channel++; + } + } +} + +static void dma_mcux_lpc_restore_reg(const struct device *dev) +{ + struct dma_mcux_lpc_dma_data *dma_data = dev->data; + const struct dma_mcux_lpc_config *config = dev->config; + struct channel_data *p_channel_data; + uint32_t virtual_channel; + DMA_Type *dma_base = DEV_BASE(dev); + + dma_base->COMMON[0].ENABLESET = dma_data->backup_reg.enableset; + dma_base->COMMON[0].INTENSET = dma_data->backup_reg.intenset; + + /* Only backup the used channels */ + virtual_channel = 0; + for (uint32_t channel = 0; channel < config->num_of_channels; channel++) { + if (dma_data->channel_index[channel] != -1) { + p_channel_data = &dma_data->channel_data[virtual_channel]; + + dma_base->CHANNEL[channel].XFERCFG = p_channel_data->backup_reg.xfercfg; + dma_base->CHANNEL[channel].CFG = p_channel_data->backup_reg.cfg; + virtual_channel++; + } + } +} + +#else /* !CONFIG_PM_DEVICE */ + +static inline void dma_mcux_lpc_backup_reg(const struct device *dev) +{ + ARG_UNUSED(dev); +} + +static inline void dma_mcux_lpc_restore_reg(const struct device *dev) +{ + ARG_UNUSED(dev); +} + +#endif /* CONFIG_PM_DEVICE */ + static int dma_mcux_lpc_pm_action(const struct device *dev, enum pm_device_action action) { switch (action) { @@ -956,9 +1047,11 @@ static int dma_mcux_lpc_pm_action(const struct device *dev, enum pm_device_actio case PM_DEVICE_ACTION_SUSPEND: break; case PM_DEVICE_ACTION_TURN_OFF: + dma_mcux_lpc_backup_reg(dev); break; case PM_DEVICE_ACTION_TURN_ON: DMA_Init(DEV_BASE(dev)); + dma_mcux_lpc_restore_reg(dev); break; default: return -ENOTSUP; From cb2a3aafe4753bec83b5dbce433ca584fd5b7676 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Fri, 12 Dec 2025 11:49:11 +0100 Subject: [PATCH 0660/3659] doc: css: add padding to search form gear icon MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit "Touch targets with sufficient size and spacing help users who may have difficulty targeting small controls to activate the targets", so move the gear icon a bit to give it more air. Signed-off-by: Benjamin Cabé --- doc/_static/css/custom.css | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/_static/css/custom.css b/doc/_static/css/custom.css index e6c0853b1c48..5f7cc6e3d9ac 100644 --- a/doc/_static/css/custom.css +++ b/doc/_static/css/custom.css @@ -1100,6 +1100,7 @@ div.graphviz > object { transform: translateY(-50%); cursor: pointer; opacity: 0.8; + padding: 10px; } #search-se-menu { From bdd8a67a6fb32a00fd2a16407571048bd7e2a9ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Fri, 12 Dec 2025 22:30:03 +0100 Subject: [PATCH 0661/3659] doc: index.html: drop red border on hover for contribute card MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This isn't really needed / is incosistent with how other cards react on hover. Signed-off-by: Benjamin Cabé --- doc/index.html | 1 - 1 file changed, 1 deletion(-) diff --git a/doc/index.html b/doc/index.html index 09b6e57ca955..7f5f608cdf7c 100644 --- a/doc/index.html +++ b/doc/index.html @@ -276,7 +276,6 @@ &:hover { transform: translateY(-2px); box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2); - border-color: rgba(236, 72, 153, 0.5); text-decoration: none; .cta-text { color: #fff; From cef4fa9fb543a76c4a1548b27cd3e3a36da635e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Fri, 12 Dec 2025 10:13:36 +0100 Subject: [PATCH 0662/3659] doc: index.html: css: improve contrast MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some tweaks to the CSS to have better contrast of the cards on the homepage, and a few other places. Signed-off-by: Benjamin Cabé --- doc/_static/css/dark.css | 2 ++ doc/_static/css/light.css | 14 ++++++++------ doc/index.html | 39 +++++++++++++++++++++++---------------- 3 files changed, 33 insertions(+), 22 deletions(-) diff --git a/doc/_static/css/dark.css b/doc/_static/css/dark.css index bb1c20c0b5cd..370beb0c6d53 100644 --- a/doc/_static/css/dark.css +++ b/doc/_static/css/dark.css @@ -95,4 +95,6 @@ --footer-color: #aaa; --graphviz-filter: invert(0.9) brightness(1.2); + + --landing-card-background-color: var(--navbar-background-color); } diff --git a/doc/_static/css/light.css b/doc/_static/css/light.css index eb019863c8b2..56966c21bd9f 100644 --- a/doc/_static/css/light.css +++ b/doc/_static/css/light.css @@ -26,7 +26,7 @@ --navbar-scrollbar-active-color: #7929d2; --navbar-scrollbar-background: #131e2b; - --link-color: #237ab3; + --link-color: #2273a9; --link-color-hover: #3091d1; --link-color-active: #105078; --link-color-visited: #9b59b6; @@ -37,7 +37,7 @@ --table-row-odd-background-color: #f3f6f6; --code-background-color: #fff; --code-border-color: #e1e4e5; - --code-literal-color: #d04c60; + --code-literal-color: #c7254e; --input-background-color: #fcfcfc; --input-focus-border-color: #5f8cff; @@ -65,19 +65,19 @@ --admonition-note-background-color: #e7f2fa; --admonition-note-color: #404040; - --admonition-note-title-background-color: #6ab0de; + --admonition-note-title-background-color: #1a5c8a; --admonition-note-title-color: #fff; --admonition-attention-background-color: #ffedcc; --admonition-attention-color: #404040; - --admonition-attention-title-background-color: #f0b37e; + --admonition-attention-title-background-color: #b94a00; --admonition-attention-title-color: #fff; --admonition-danger-background-color: #fcf3f2; --admonition-danger-color: #404040; - --admonition-danger-title-background-color: #e9a499; + --admonition-danger-title-background-color: #a93226; --admonition-danger-title-color: #fff; --admonition-tip-background-color: #dbfaf4; --admonition-tip-color: #404040; - --admonition-tip-title-background-color: #1abc9c; + --admonition-tip-title-background-color: #00695c; --admonition-tip-title-color: #fff; --kbd-background-color: #fafbfc; @@ -93,4 +93,6 @@ --footer-color: #747474; --graphviz-filter: none; + + --landing-card-background-color: var(--admonition-note-background-color); } diff --git a/doc/index.html b/doc/index.html index 7f5f608cdf7c..2caf084f432c 100644 --- a/doc/index.html +++ b/doc/index.html @@ -1,4 +1,9 @@
`;export class DarkModeToggle extends HTMLElement{static get observedAttributes(){return[f,m,u,d,s,r,c]}constructor(){super();W(this,f);W(this,m);W(this,d);W(this,s);W(this,r);W(this,h);W(this,c);w(this,u);this.t=null;this.i=null;e.addEventListener(k,(e=>{this.mode=e.detail.colorScheme;this.h();this.o();this.l()}));e.addEventListener(y,(e=>{this.permanent=e.detail.permanent;this.p.checked=this.permanent;this.l()}));this.m()}m(){const t=this.attachShadow({mode:"open"});t.append(x.content.cloneNode(true));this.t=e.querySelectorAll(`${n}[${a}*=${i}][${a}*="${r}"]`);this.i=e.querySelectorAll(`${n}[${a}*=${i}][${a}*="${s}"]`);this.u=t.querySelector("[part=lightRadio]");this.k=t.querySelector("[part=lightLabel]");this.v=t.querySelector("[part=darkRadio]");this.$=t.querySelector("[part=darkLabel]");this.L=t.querySelector("[part=toggleCheckbox]");this.T=t.querySelector("[part=toggleLabel]");this.W=t.querySelector("[part=lightThreeWayRadio]");this.R=t.querySelector("[part=lightThreeWayLabel]");this.C=t.querySelector("[part=systemThreeWayRadio]");this.M=t.querySelector("[part=systemThreeWayLabel]");this.S=t.querySelector("[part=darkThreeWayRadio]");this._=t.querySelector("[part=darkThreeWayLabel]");this.A=t.querySelector("legend");this.D=t.querySelector("aside");this.p=t.querySelector("[part=permanentCheckbox]");this.O=t.querySelector("[part=permanentLabel]")}connectedCallback(){const e=matchMedia(o).media!==$;if(e){matchMedia(o).addListener((({matches:e})=>{if(this.permanent){return}this.mode=e?r:s;this.j(k,{colorScheme:this.mode})}))}let i=false;try{i=t.getItem(L)}catch(e){}if(i&&[r,s].includes(i)){this.mode=i;this.p.checked=true;this.permanent=true}else if(e){this.mode=matchMedia(l).matches?s:r}if(!this.mode){this.mode=s}if(this.permanent&&!i){try{t.setItem(L,this.mode)}catch(e){}}if(!this.appearance){this.appearance=p}this.P();this.h();this.o();this.l();[this.u,this.v].forEach((e=>{e.addEventListener("change",(()=>{this.mode=this.u.checked?s:r;this.o();this.l();this.j(k,{colorScheme:this.mode})}))}));this.L.addEventListener("change",(()=>{this.mode=this.L.checked?r:s;this.h();this.l();this.j(k,{colorScheme:this.mode})}));this.W.addEventListener("change",(()=>{this.mode=s;this.permanent=true;this.o();this.h();this.l();this.j(k,{colorScheme:this.mode});this.j(y,{permanent:this.permanent})}));this.S.addEventListener("change",(()=>{this.mode=r;this.permanent=true;this.o();this.h();this.l();this.j(k,{colorScheme:this.mode});this.j(y,{permanent:this.permanent})}));this.C.addEventListener("change",(()=>{this.mode=this.H();this.permanent=false;this.o();this.h();this.l();this.j(k,{colorScheme:this.mode});this.j(y,{permanent:this.permanent})}));this.p.addEventListener("change",(()=>{this.permanent=this.p.checked;this.l();this.j(y,{permanent:this.permanent})}));this.q();this.j(k,{colorScheme:this.mode});this.j(y,{permanent:this.permanent})}attributeChangedCallback(e,i,a){if(e===f){const e=[s,h,r];if(!e.includes(a)){throw new RangeError(`Allowed values are: "${e.join(`", "`)}".`)}if(matchMedia("(hover:none)").matches&&this.remember){this.B()}if(this.permanent){try{t.setItem(L,this.mode)}catch(e){}}this.h();this.o();this.l();this.q()}else if(e===m){const e=[p,b,g];if(!e.includes(a)){throw new RangeError(`Allowed values are: "${e.join(`", "`)}".`)}this.P()}else if(e===u){if(this.permanent){if(this.mode){try{t.setItem(L,this.mode)}catch(e){}}}else{try{t.removeItem(L)}catch(e){}}this.p.checked=this.permanent}else if(e===d){this.A.textContent=a}else if(e===c){this.O.textContent=a}else if(e===s){this.k.textContent=a;if(this.mode===s){this.T.textContent=a}}else if(e===r){this.$.textContent=a;if(this.mode===r){this.T.textContent=a}}}H(){return matchMedia(l).matches?s:r}j(e,t){this.dispatchEvent(new CustomEvent(e,{bubbles:true,composed:true,detail:t}))}P(){this.u.hidden=this.k.hidden=this.v.hidden=this.$.hidden=this.L.hidden=this.T.hidden=this.W.hidden=this.R.hidden=this.C.hidden=this.M.hidden=this.S.hidden=this._.hidden=true;switch(this.appearance){case b:this.u.hidden=this.k.hidden=this.v.hidden=this.$.hidden=false;break;case g:this.W.hidden=this.R.hidden=this.C.hidden=this.M.hidden=this.S.hidden=this._.hidden=false;break;case p:default:this.L.hidden=this.T.hidden=false;break}}h(){if(this.mode===s){this.u.checked=true}else{this.v.checked=true}}o(){if(this.mode===s){this.T.style.setProperty(`--${L}-checkbox-icon`,`var(--${L}-light-icon,url("${T}moon.png"))`);this.T.textContent=this.light;if(!this.light){this.T.ariaLabel=r}this.L.checked=false}else{this.T.style.setProperty(`--${L}-checkbox-icon`,`var(--${L}-dark-icon,url("${T}sun.png"))`);this.T.textContent=this.dark;if(!this.dark){this.T.ariaLabel=s}this.L.checked=true}}l(){this.R.ariaLabel=s;this.M.ariaLabel=h;this.R.ariaLabel=r;this.R.textContent=this.light;this.M.textContent=this.system;this._.textContent=this.dark;if(this.permanent){if(this.mode===s){this.W.checked=true}else{this.S.checked=true}}else{this.C.checked=true}}q(){if(this.mode===s){this.i.forEach((e=>{e.media=v;e.disabled=false}));this.t.forEach((e=>{e.media=$;e.disabled=true}))}else{this.t.forEach((e=>{e.media=v;e.disabled=false}));this.i.forEach((e=>{e.media=$;e.disabled=true}))}}B(){this.D.style.visibility="visible";setTimeout((()=>{this.D.style.visibility="hidden"}),3e3)}}customElements.define(L,DarkModeToggle); \ No newline at end of file +const e=document;let t={};try{t=localStorage}catch(e){}const i="prefers-color-scheme";const a="media";const s="light";const r="dark";const h="system";const o=`(${i}:${r})`;const l=`(${i}:${s})`;const n="link[rel=stylesheet]";const c="style";const d="remember";const p="legend";const b="toggle";const g="switch";const m="three-way";const u="appearance";const f="permanent";const k="mode";const y="colorschemechange";const $="permanentcolorscheme";const v="all";const L="not all";const T="dark-mode-toggle";const W="https://googlechromelabs.github.io/dark-mode-toggle/demo/";const w=(e,t,i=t)=>{Object.defineProperty(e,i,{enumerable:true,get(){const e=this.getAttribute(t);return e===null?"":e},set(e){this.setAttribute(t,e)}})};const x=(e,t,i=t)=>{Object.defineProperty(e,i,{enumerable:true,get(){return this.hasAttribute(t)},set(e){if(e){this.setAttribute(t,"")}else{this.removeAttribute(t)}}})};const R=e.createElement("template");R.innerHTML=`
`;export class DarkModeToggle extends HTMLElement{static get observedAttributes(){return[k,u,f,p,s,r,d]}constructor(){super();w(this,k);w(this,u);w(this,p);w(this,s);w(this,r);w(this,h);w(this,d);x(this,f);this.t=null;this.i=null;e.addEventListener(y,e=>{this.mode=e.detail.colorScheme;this.h();this.o();this.l()});e.addEventListener($,e=>{this.permanent=e.detail.permanent;this.p.checked=this.permanent;this.l()});this.m()}m(){const t=this.attachShadow({mode:"open"});t.append(R.content.cloneNode(true));this.t=e.querySelectorAll(`${n}[${a}*=${i}][${a}*="${r}"],\n ${c}[${a}*=${i}][${a}*="${r}"]`);this.i=e.querySelectorAll(`${n}[${a}*=${i}][${a}*="${s}"], \n ${c}[${a}*=${i}][${a}*="${s}"]`);this.u=t.querySelector("[part=lightRadio]");this.k=t.querySelector("[part=lightLabel]");this.$=t.querySelector("[part=darkRadio]");this.v=t.querySelector("[part=darkLabel]");this.L=t.querySelector("[part=toggleCheckbox]");this.T=t.querySelector("[part=toggleLabel]");this.W=t.querySelector("[part=lightThreeWayRadio]");this.R=t.querySelector("[part=lightThreeWayLabel]");this.C=t.querySelector("[part=systemThreeWayRadio]");this.M=t.querySelector("[part=systemThreeWayLabel]");this.S=t.querySelector("[part=darkThreeWayRadio]");this._=t.querySelector("[part=darkThreeWayLabel]");this.A=t.querySelector("legend");this.D=t.querySelector("aside");this.p=t.querySelector("[part=permanentCheckbox]");this.O=t.querySelector("[part=permanentLabel]")}connectedCallback(){const e=matchMedia(o).media!==L;if(e){matchMedia(o).addListener(({matches:e})=>{if(this.permanent){return}this.mode=e?r:s;this.j(y,{colorScheme:this.mode})})}let i=false;try{i=t.getItem(T)}catch(e){}if(i&&[r,s].includes(i)){this.mode=i;this.p.checked=true;this.permanent=true}else if(e){this.mode=matchMedia(l).matches?s:r}if(!this.mode){this.mode=s}if(this.permanent&&!i){try{t.setItem(T,this.mode)}catch(e){}}if(!this.appearance){this.appearance=b}this.P();this.h();this.o();this.l();[this.u,this.$].forEach(e=>{e.addEventListener("change",()=>{this.mode=this.u.checked?s:r;this.o();this.l();this.j(y,{colorScheme:this.mode})})});this.L.addEventListener("change",()=>{this.mode=this.L.checked?r:s;this.h();this.l();this.j(y,{colorScheme:this.mode})});this.W.addEventListener("change",()=>{this.mode=s;this.permanent=true;this.o();this.h();this.l();this.j(y,{colorScheme:this.mode});this.j($,{permanent:this.permanent})});this.S.addEventListener("change",()=>{this.mode=r;this.permanent=true;this.o();this.h();this.l();this.j(y,{colorScheme:this.mode});this.j($,{permanent:this.permanent})});this.C.addEventListener("change",()=>{this.mode=this.H();this.permanent=false;this.o();this.h();this.l();this.j(y,{colorScheme:this.mode});this.j($,{permanent:this.permanent})});this.p.addEventListener("change",()=>{this.permanent=this.p.checked;this.l();this.j($,{permanent:this.permanent})});this.q();this.j(y,{colorScheme:this.mode});this.j($,{permanent:this.permanent})}attributeChangedCallback(e,i,a){if(e===k){const e=[s,h,r];if(!e.includes(a)){throw new RangeError(`Allowed values are: "${e.join(`", "`)}".`)}if(matchMedia("(hover:none)").matches&&this.remember){this.B()}if(this.permanent){try{t.setItem(T,this.mode)}catch(e){}}this.h();this.o();this.l();this.q()}else if(e===u){const e=[b,g,m];if(!e.includes(a)){throw new RangeError(`Allowed values are: "${e.join(`", "`)}".`)}this.P()}else if(e===f){if(this.permanent){if(this.mode){try{t.setItem(T,this.mode)}catch(e){}}}else{try{t.removeItem(T)}catch(e){}}this.p.checked=this.permanent}else if(e===p){this.A.textContent=a}else if(e===d){this.O.textContent=a}else if(e===s){this.k.textContent=a;if(this.mode===s){this.T.textContent=a}}else if(e===r){this.v.textContent=a;if(this.mode===r){this.T.textContent=a}}}H(){return matchMedia(l).matches?s:r}j(e,t){this.dispatchEvent(new CustomEvent(e,{bubbles:true,composed:true,detail:t}))}P(){this.u.hidden=this.k.hidden=this.$.hidden=this.v.hidden=this.L.hidden=this.T.hidden=this.W.hidden=this.R.hidden=this.C.hidden=this.M.hidden=this.S.hidden=this._.hidden=true;switch(this.appearance){case g:this.u.hidden=this.k.hidden=this.$.hidden=this.v.hidden=false;break;case m:this.W.hidden=this.R.hidden=this.C.hidden=this.M.hidden=this.S.hidden=this._.hidden=false;break;case b:default:this.L.hidden=this.T.hidden=false;break}}h(){if(this.mode===s){this.u.checked=true}else{this.$.checked=true}}o(){if(this.mode===s){this.T.style.setProperty(`--${T}-checkbox-icon`,`var(--${T}-light-icon,url("${W}moon.png"))`);this.T.textContent=this.light;if(!this.light){this.T.ariaLabel=r}this.L.checked=false}else{this.T.style.setProperty(`--${T}-checkbox-icon`,`var(--${T}-dark-icon,url("${W}sun.png"))`);this.T.textContent=this.dark;if(!this.dark){this.T.ariaLabel=s}this.L.checked=true}}l(){this.R.ariaLabel=s;this.M.ariaLabel=h;this._.ariaLabel=r;this.R.textContent=this.light;this.M.textContent=this.system;this._.textContent=this.dark;if(this.permanent){if(this.mode===s){this.W.checked=true}else{this.S.checked=true}}else{this.C.checked=true}}q(){if(this.mode===s){this.i.forEach(e=>{e.media=v;e.disabled=false});this.t.forEach(e=>{e.media=L;e.disabled=true})}else{this.t.forEach(e=>{e.media=v;e.disabled=false});this.i.forEach(e=>{e.media=L;e.disabled=true})}}B(){this.D.style.visibility="visible";setTimeout(()=>{this.D.style.visibility="hidden"},3e3)}}customElements.define(T,DarkModeToggle); \ No newline at end of file From a0096984dceb3c26f8af1ddb55df7f713bf9830a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Fri, 12 Dec 2025 16:32:17 +0100 Subject: [PATCH 0665/3659] doc: index.html: fix `aria-hidden`typo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix typo in attribute; add a missing one. Signed-off-by: Benjamin Cabé --- doc/index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/index.html b/doc/index.html index 2caf084f432c..14db65b6d4e0 100644 --- a/doc/index.html +++ b/doc/index.html @@ -544,7 +544,7 @@

Going to Production

  • - + Long-term Support
  • @@ -577,7 +577,7 @@

    Read the Guidelines - +
    From 5224283ea9bd912fd79915f7d6f36cfd6d99bf1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Tue, 16 Dec 2025 18:33:03 +0100 Subject: [PATCH 0666/3659] doc: css: re-style definition lists MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Definition lists are key for explaining terminology, and making them visually cohesive can help the reader better scan information. This change introduces a distinct visual hierarchy by: - Adding a vertical border to group the list items. - Highlighting terms (dt) with a background color and rounded corners. - Adding decorative indicators (bullets) to separate entries clearly. The new style is also intentionally more visually distinct so that _incorrect_ usage of definition lists (usually due to bad indentation) can be more easily detected as it won't look good when not used for things meant to be "definition lists" :) Signed-off-by: Benjamin Cabé --- doc/_static/css/custom.css | 113 ++++++++----------------------------- 1 file changed, 25 insertions(+), 88 deletions(-) diff --git a/doc/_static/css/custom.css b/doc/_static/css/custom.css index 5f7cc6e3d9ac..0fb4f02a70c1 100644 --- a/doc/_static/css/custom.css +++ b/doc/_static/css/custom.css @@ -121,94 +121,6 @@ hr, border-color: var(--hr-color); } -/* JavaScript documentation directives */ -html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) dt, -html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) dl:not(.field-list) > dt { - background-color: var(--admonition-note-background-color); - border-color: var(--admonition-note-title-background-color); - color: var(--admonition-note-color); -} -html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) dl dt { - background-color: transparent; - border-color: transparent; - color: var(--footer-color); -} -html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple).class dt, -html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple).function dt, -html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple).method dt, -html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple).attribute dt { - font-weight: 600; - padding: 0 8px; - margin-bottom: 1px; - width: 100%; -} -html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple).class > dt, -html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple).function > dt, -html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple).method > dt, -html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple).attribute > dt { - font-family: var(--monospace-font-family); - font-variant-ligatures: none; - font-size: 90%; - font-weight: normal; - margin-bottom: 16px; - padding: 6px 8px; -} -html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .sig-prename.descclassname { - color: var(--highlight-type2-color); - font-weight: normal; -} -html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .sig-name.descname { - color: var(--highlight-function-color); - font-weight: 700; -} -html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .sig-paren, -html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .optional { - color: var(--highlight-operator-color) !important; - font-weight: normal; - padding: 0 2px; -} -html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .optional { - font-style: italic; -} -html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .sig-param, -html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple).class dt > em, -html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple).function dt > em, -html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple).method dt > em { - color: var(--code-literal-color); - font-style: normal; - padding: 0 4px; -} -html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .k { - font-style: normal; -} -html.writer-html5 .rst-content dl:not(.docutils) > dt, html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) > dt { - border-top-color: var(--highlight-background-emph-color); - background: var(--highlight-background-color); -} -html.writer-html5 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) > dt, html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) > dt { - border-left-color: var(--highlight-background-emph-color); - background: var(--highlight-background-color); -} -html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .sig-param, -html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple).class dt > .optional ~ em, -html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple).function dt > .optional ~ em, -html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple).method dt > .optional ~ em { - color: var(--highlight-number-color); - font-style: italic; -} -html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple).class dt > em.property { - color: var(--highlight-keyword-color); -} -html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) dt a.headerlink { - color: var(--link-color) !important; -} -html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) dt a.headerlink:visited { - color: var(--link-color-visited); -} -html.writer-html5 .rst-content dl.field-list > dd strong { - font-family: var(--monospace-font-family); - font-variant-ligatures: none; -} footer, #search-results .context { @@ -607,6 +519,31 @@ kbd, .kbd, font-weight: 100; } +/* Definition lists */ +.rst-content dl { + border-left: 4px solid var(--admonition-note-background-color); +} + +.rst-content dl:not(.field-list) > dt { + position: relative; + padding-left: 1rem; + line-height: 1.8rem; + background: var(--highlight-background-color); + border-radius: 0 16px 16px 0; +} + +.rst-content dl:not(.field-list) > dt::before { + content: ''; + position: absolute; + left: -10px; + top: 6px; + width: 16px; + height: 16px; + background: var(--admonition-note-title-background-color); + border-radius: 50%; + border: 4px solid var(--content-background-color); +} + /* Buttons */ .btn-neutral { From 18c1a63891e719e749d38b5e56148c1c4c4a9c88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Tue, 16 Dec 2025 20:22:59 +0100 Subject: [PATCH 0667/3659] doc: fix bad indentation causing elements to render as definition lists MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes documents where blocks where indented to the right of their parent causing them to render as definition lists. Signed-off-by: Benjamin Cabé --- boards/96boards/aerocore2/doc/index.rst | 3 +- boards/96boards/carbon/doc/stm32f401xe.rst | 5 +- .../96boards/stm32_sensor_mez/doc/index.rst | 15 ++- .../nrf52_adafruit_feather/doc/index.rst | 4 +- boards/adi/max32657evkit/doc/index.rst | 9 +- boards/adi/max32658evkit/doc/index.rst | 9 +- boards/adi/sdp_k1/doc/index.rst | 14 ++- .../alientek/pandora_stm32l475/doc/index.rst | 66 ++++++----- boards/dragino/nbsn95/doc/index.rst | 6 +- .../pic32c/pic32cx_sg41_cult/doc/index.rst | 12 +- boards/nxp/mimxrt685_evk/doc/index.rst | 20 ++-- boards/nxp/mimxrt700_evk/doc/index.rst | 16 ++- boards/nxp/mr_canhubk3/doc/index.rst | 24 ++-- boards/nxp/ucans32k1sic/doc/index.rst | 22 ++-- boards/others/black_f407ve/doc/index.rst | 10 +- boards/others/black_f407zg_pro/doc/index.rst | 10 +- .../shields/p3t1755dp_ard_i2c/doc/index.rst | 23 ++-- .../shields/p3t1755dp_ard_i3c/doc/index.rst | 5 +- boards/shields/x_nucleo_bnrg2a1/doc/index.rst | 3 +- boards/shields/x_nucleo_idb05a1/doc/index.rst | 3 +- boards/shields/x_nucleo_iks01a1/doc/index.rst | 3 +- boards/shields/x_nucleo_iks01a2/doc/index.rst | 3 +- boards/shields/x_nucleo_wb05kn1/doc/index.rst | 3 +- boards/st/b_g474e_dpow1/doc/index.rst | 10 +- boards/st/b_l4s5i_iot01a/doc/index.rst | 79 +++++++------ boards/st/b_u585i_iot02a/doc/index.rst | 9 +- boards/st/disco_l475_iot1/doc/index.rst | 84 +++++++------ boards/st/nucleo_f722ze/doc/index.rst | 95 +++++++++------ boards/st/stm3210c_eval/doc/index.rst | 13 +- boards/st/stm32373c_eval/doc/index.rst | 14 ++- boards/st/stm32f072_eval/doc/index.rst | 5 +- boards/st/stm32f072b_disco/doc/index.rst | 5 +- boards/st/stm32f3_disco/doc/index.rst | 13 +- boards/st/stm32f411e_disco/doc/index.rst | 21 ++-- boards/st/stm32f412g_disco/doc/index.rst | 19 +-- boards/st/stm32f413h_disco/doc/index.rst | 19 +-- boards/st/stm32f429i_disc1/doc/index.rst | 11 +- boards/st/stm32f469i_disco/doc/index.rst | 11 +- boards/st/stm32f4_disco/doc/index.rst | 17 +-- boards/st/stm32g071b_disco/doc/index.rst | 22 ++-- boards/st/stm32g081b_eval/doc/index.rst | 111 ++++++++++-------- boards/st/stm32h7b3i_dk/doc/index.rst | 30 +++-- boards/st/stm32l476g_disco/doc/index.rst | 82 +++++++------ boards/ti/sk_am64/doc/index.rst | 11 +- boards/weact/mini_stm32h743/doc/index.rst | 15 +-- .../toolchains/arm_toolchain_for_embedded.rst | 18 +-- doc/develop/west/manifest.rst | 31 +++-- doc/kernel/object_cores/index.rst | 25 ++-- doc/kernel/usermode/overview.rst | 6 +- doc/services/sensing/index.rst | 30 ++--- doc/services/smf/index.rst | 29 ++--- samples/modules/lvgl/demos/README.rst | 24 ++-- samples/modules/lvgl/multi_display/README.rst | 24 ++-- samples/net/openthread/coprocessor/README.rst | 18 +-- 54 files changed, 672 insertions(+), 517 deletions(-) diff --git a/boards/96boards/aerocore2/doc/index.rst b/boards/96boards/aerocore2/doc/index.rst index 489433e09f3b..4750f8ee359f 100644 --- a/boards/96boards/aerocore2/doc/index.rst +++ b/boards/96boards/aerocore2/doc/index.rst @@ -43,7 +43,8 @@ Hardware - DMA Controller More information about STM32F427VIT6 can be found here: - - `STM32F427 on www.st.com`_ + +- `STM32F427 on www.st.com`_ Supported Features ================== diff --git a/boards/96boards/carbon/doc/stm32f401xe.rst b/boards/96boards/carbon/doc/stm32f401xe.rst index c493c0a7fd62..0e199eb36691 100644 --- a/boards/96boards/carbon/doc/stm32f401xe.rst +++ b/boards/96boards/carbon/doc/stm32f401xe.rst @@ -67,8 +67,9 @@ Hardware - Bluetooth LE over SPI, provided by nRF51822 More information about STM32F401RE can be found here: - - `STM32F401RE on www.st.com`_ - - `STM32F401 reference manual`_ + +- `STM32F401RE on www.st.com`_ +- `STM32F401 reference manual`_ Supported Features ================== diff --git a/boards/96boards/stm32_sensor_mez/doc/index.rst b/boards/96boards/stm32_sensor_mez/doc/index.rst index 1539a8148a18..83e88a8c6ea0 100644 --- a/boards/96boards/stm32_sensor_mez/doc/index.rst +++ b/boards/96boards/stm32_sensor_mez/doc/index.rst @@ -110,16 +110,19 @@ exposed via on-board Micro USB connector. Default settings are 115200 8N1. The default USART mappings for the remaining ones are: - USART1: Connected to AP via UART0 on the 96Boards Low-Speed Header. - - TX: PA9 - - RX: PA10 + + - TX: PA9 + - RX: PA10 - USART2: Connected to D0(RX) and D1(TX) on the Arduino Header. - - TX: PD5 - - RX: PD6 + + - TX: PD5 + - RX: PD6 - USART3: Broken out to Grove connector J10. - - TX: PD8 - - RX: PD9 + + - TX: PD8 + - RX: PD9 I2C --- diff --git a/boards/adafruit/nrf52_adafruit_feather/doc/index.rst b/boards/adafruit/nrf52_adafruit_feather/doc/index.rst index 4e318acd7935..c507fae1103a 100644 --- a/boards/adafruit/nrf52_adafruit_feather/doc/index.rst +++ b/boards/adafruit/nrf52_adafruit_feather/doc/index.rst @@ -62,12 +62,12 @@ Programming and Debugging The ``nrf52_adafruit_feather`` board is available in two different versions: -- `Adafruit Feather nRF52 Pro with myNewt Bootloader`_ +`Adafruit Feather nRF52 Pro with myNewt Bootloader`_ This board version is the recommended one to use. It has the SWD header already populated and comes with the Mynewt serial bootloader installed by default. -- `Adafruit Feather nRF52 Bluefruit LE`_ +`Adafruit Feather nRF52 Bluefruit LE`_ This board is identical to the board above, but the SWD header is not populated and ships with an Arduino friendly bootloader. To be able to work with this version a 2*5pin 0.5" SWD header (e.g. `Adafruit SWD connector`_) diff --git a/boards/adi/max32657evkit/doc/index.rst b/boards/adi/max32657evkit/doc/index.rst index 99e243a9496b..61a242f8798f 100644 --- a/boards/adi/max32657evkit/doc/index.rst +++ b/boards/adi/max32657evkit/doc/index.rst @@ -344,10 +344,11 @@ using :zephyr:code-sample:`blinky` sample: :goals: build The above command will: - * Build a bootloader image (MCUboot) - * Build a TF-M (secure) firmware image - * Build Zephyr application as non-secure firmware image - * Merge them as ``tfm_merged.hex`` which contain all images. + +* Build a bootloader image (MCUboot) +* Build a TF-M (secure) firmware image +* Build Zephyr application as non-secure firmware image +* Merge them as ``tfm_merged.hex`` which contain all images. Note: diff --git a/boards/adi/max32658evkit/doc/index.rst b/boards/adi/max32658evkit/doc/index.rst index 89caa6766f41..58cd31062b1f 100644 --- a/boards/adi/max32658evkit/doc/index.rst +++ b/boards/adi/max32658evkit/doc/index.rst @@ -340,10 +340,11 @@ using :zephyr:code-sample:`blinky` sample: :goals: build The above command will: - * Build a bootloader image (MCUboot) - * Build a TF-M (secure) firmware image - * Build Zephyr application as non-secure firmware image - * Merge them as ``tfm_merged.hex`` which contain all images. + +* Build a bootloader image (MCUboot) +* Build a TF-M (secure) firmware image +* Build Zephyr application as non-secure firmware image +* Merge them as ``tfm_merged.hex`` which contain all images. Note: diff --git a/boards/adi/sdp_k1/doc/index.rst b/boards/adi/sdp_k1/doc/index.rst index d684c53374c9..c89d1e8fea33 100644 --- a/boards/adi/sdp_k1/doc/index.rst +++ b/boards/adi/sdp_k1/doc/index.rst @@ -12,10 +12,11 @@ ADI components. - USB debug interface supporting CMSIS-DAP through a NXP Freescale microcontroller - Flexible board power supply - - USB VBUS 5 V max. 500 mA - - 5.5mm DC power jack 7 - 12 V min. 300 mA - - VIN from Arduino* compatible connectors - - VIN from 120-pin connector 5 V min. 300 mA + + - USB VBUS 5 V max. 500 mA + - 5.5mm DC power jack 7 - 12 V min. 300 mA + - VIN from Arduino* compatible connectors + - VIN from 120-pin connector 5 V min. 300 mA - 3 color LEDs (green, orange, red) and 1 status LED - One push-buttons: RESET - 16MB SDRAM @@ -59,8 +60,9 @@ ADI SDP-K1 provides the following hardware components: - DMA Controller More information about STM32F469NI can be found here: - - `STM32F469NI product page`_ - - `STM32F469 reference manual`_ + +- `STM32F469NI product page`_ +- `STM32F469 reference manual`_ Supported Features ================== diff --git a/boards/alientek/pandora_stm32l475/doc/index.rst b/boards/alientek/pandora_stm32l475/doc/index.rst index 671570b64099..8fb35400d9bf 100644 --- a/boards/alientek/pandora_stm32l475/doc/index.rst +++ b/boards/alientek/pandora_stm32l475/doc/index.rst @@ -41,41 +41,51 @@ The STM32L475VE SoC provides the following hardware features: - Ultra-low-power with FlexPowerControl (down to 130 nA Standby mode and 100 uA/MHz run mode) - Core: ARM |reg| 32-bit Cortex |reg|-M4 CPU with FPU, frequency up to 80 MHz, 100DMIPS/1.25DMIPS/MHz (Dhrystone 2.1) - Clock Sources: - - 4 to 48 MHz crystal oscillator - - 32 kHz crystal oscillator for RTC (LSE) - - Internal 16 MHz factory-trimmed RC ( |plusminus| 1%) - - Internal low-power 32 kHz RC ( |plusminus| 5%) - - Internal multispeed 100 kHz to 48 MHz oscillator, auto-trimmed by - LSE (better than |plusminus| 0.25 % accuracy) - - 3 PLLs for system clock, USB, audio, ADC + + - 4 to 48 MHz crystal oscillator + - 32 kHz crystal oscillator for RTC (LSE) + - Internal 16 MHz factory-trimmed RC ( |plusminus| 1%) + - Internal low-power 32 kHz RC ( |plusminus| 5%) + - Internal multispeed 100 kHz to 48 MHz oscillator, auto-trimmed by + LSE (better than |plusminus| 0.25 % accuracy) + - 3 PLLs for system clock, USB, audio, ADC + - RTC with HW calendar, alarms and calibration - 16x timers: - - 2x 16-bit advanced motor-control - - 2x 32-bit and 7x 16-bit general purpose - - 2x 16-bit basic - - 2x low-power 16-bit timers (available in Stop mode) - - 2x watchdogs - - SysTick timer + + - 2x 16-bit advanced motor-control + - 2x 32-bit and 7x 16-bit general purpose + - 2x 16-bit basic + - 2x low-power 16-bit timers (available in Stop mode) + - 2x watchdogs + - SysTick timer + - Up to 82 fast I/Os, most 5 V-tolerant, up to 14 I/Os with independent supply down to 1.08 V + - Memories - - Up to 1 MB Flash, 2 banks read-while-write, proprietary code readout protection - - Up to 128 KB of SRAM including 32 KB with hardware parity check - - External memory interface for static memories supporting SRAM, PSRAM, NOR and NAND memories - - Quad SPI memory interface + + - Up to 1 MB Flash, 2 banks read-while-write, proprietary code readout protection + - Up to 128 KB of SRAM including 32 KB with hardware parity check + - External memory interface for static memories supporting SRAM, PSRAM, NOR and NAND memories + - Quad SPI memory interface - 4x digital filters for sigma delta modulator - Rich analog peripherals (independent supply) - - 3x 12-bit ADC 5 MSPS, up to 16-bit with hardware oversampling, 200 uA/MSPS - - 2x 12-bit DAC, low-power sample and hold - - 2x operational amplifiers with built-in PGA - - 2x ultra-low-power comparators + + - 3x 12-bit ADC 5 MSPS, up to 16-bit with hardware oversampling, 200 uA/MSPS + - 2x 12-bit DAC, low-power sample and hold + - 2x operational amplifiers with built-in PGA + - 2x ultra-low-power comparators + - 18x communication interfaces - - USB OTG 2.0 full-speed, LPM and BCD - - 2x SAIs (serial audio interface) - - 3x I2C FM+(1 Mbit/s), SMBus/PMBus - - 6x USARTs (ISO 7816, LIN, IrDA, modem) - - 3x SPIs (4x SPIs with the Quad SPI) - - CAN (2.0B Active) and SDMMC interface - - SWPMI single wire protocol master I/F + + - USB OTG 2.0 full-speed, LPM and BCD + - 2x SAIs (serial audio interface) + - 3x I2C FM+(1 Mbit/s), SMBus/PMBus + - 6x USARTs (ISO 7816, LIN, IrDA, modem) + - 3x SPIs (4x SPIs with the Quad SPI) + - CAN (2.0B Active) and SDMMC interface + - SWPMI single wire protocol master I/F + - 14-channel DMA controller - True random number generator - CRC calculation unit, 96-bit unique ID diff --git a/boards/dragino/nbsn95/doc/index.rst b/boards/dragino/nbsn95/doc/index.rst index c99e6c87bdcd..baa1763e4386 100644 --- a/boards/dragino/nbsn95/doc/index.rst +++ b/boards/dragino/nbsn95/doc/index.rst @@ -13,8 +13,10 @@ This kit provides: - STM32L072CZ MCU - Quectel BC95-G NB-IoT -- Expansion connectors: - - PMOD +- Expansion connectors + + - PMOD + - Li/SOCI2 Unchargable Battery - GPIOs exposed via screw terminals on the carrier board - Housing diff --git a/boards/microchip/pic32c/pic32cx_sg41_cult/doc/index.rst b/boards/microchip/pic32c/pic32cx_sg41_cult/doc/index.rst index 69b3701e35e7..a022d55043a5 100644 --- a/boards/microchip/pic32c/pic32cx_sg41_cult/doc/index.rst +++ b/boards/microchip/pic32c/pic32cx_sg41_cult/doc/index.rst @@ -23,7 +23,9 @@ Hardware - 64 Mbit Quad SPI Flash - AT24MAC402 Serial EEPROM with EUI-48™ MAC address - Ethernet 10/100 Mbps - - RMII Interface with modular PHY Header + + - RMII Interface with modular PHY Header + - SD/SDIO card connector - Two CAN interfaces with on-board transceivers - I²C-based temperature sensor @@ -31,9 +33,13 @@ Hardware - mikroBUS header connector - Arduino Uno header connectors - CoreSight 10 connector - - 10-pin Cortex® Debug header (SWD) + + - 10-pin Cortex® Debug header (SWD) + - CoreSight 20 connector - - 20-pin Cortex Debug + ETM Connector (SWD and 4-bit Trace) + + - 20-pin Cortex Debug + ETM Connector (SWD and 4-bit Trace) + - Virtual COM port (CDC) - USB powered - Power Header and Barrel Jack connector for external power sources diff --git a/boards/nxp/mimxrt685_evk/doc/index.rst b/boards/nxp/mimxrt685_evk/doc/index.rst index 530b314da0c0..9490f6a8e755 100644 --- a/boards/nxp/mimxrt685_evk/doc/index.rst +++ b/boards/nxp/mimxrt685_evk/doc/index.rst @@ -305,17 +305,19 @@ earlier packages and ``xt-lang`` newer ones) and the To build a project: - Set up toolchain environment - - No special configuration needed for the GCC variant in the Zephyr SDK. - - For the proprietary Xtensa toolchain, set ``XTENSA_CORE``, - ``XTENSA_TOOLCHAIN_PATH`` and ``TOOLCHAIN_VER`` according to your - installed version. ``ZEPHYR_TOOLCHAIN_VARIANT`` should be either ``xcc`` - or ``xt-clang``. + + - No special configuration needed for the GCC variant in the Zephyr SDK. + - For the proprietary Xtensa toolchain, set ``XTENSA_CORE``, + ``XTENSA_TOOLCHAIN_PATH`` and ``TOOLCHAIN_VER`` according to your + installed version. ``ZEPHYR_TOOLCHAIN_VARIANT`` should be either ``xcc`` + or ``xt-clang``. + - Build the project with: -.. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: mimxrt685_evk/mimxrt685s/hifi4 - :goals: build + .. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: mimxrt685_evk/mimxrt685s/hifi4 + :goals: build Debugging can be directly carried out using the J-Link GDB server with ``xt-gdb`` (Xtensa proprietary) or ``gdb`` (Zephyr SDK) connected. It's diff --git a/boards/nxp/mimxrt700_evk/doc/index.rst b/boards/nxp/mimxrt700_evk/doc/index.rst index 1369c12c681f..65303b10f6ca 100644 --- a/boards/nxp/mimxrt700_evk/doc/index.rst +++ b/boards/nxp/mimxrt700_evk/doc/index.rst @@ -24,12 +24,16 @@ Hardware ******** - Main Compute Subsystem: - - Arm Cortex-M33 up to 325 MHz - - HiFi 4 DSP up to 325 MHz - - eIQ Neutron NPU up to 325 MHz -- Sense Compute Subsystem: - - Arm Cortex-M33 up to 250 MHz - - HiFi 1 DSP up to 250 MHz + + - Arm Cortex-M33 up to 325 MHz + - HiFi 4 DSP up to 325 MHz + - eIQ Neutron NPU up to 325 MHz + +- Sense Compute Subsystem + + - Arm Cortex-M33 up to 250 MHz + - HiFi 1 DSP up to 250 MHz + - 7.5 MB on-chip SRAM - Three xSPI interfaces for off-chip memory expansion, supporting up to 16b wide external memories up to 250 MHz DDR - eUSB support with integrated PHY diff --git a/boards/nxp/mr_canhubk3/doc/index.rst b/boards/nxp/mr_canhubk3/doc/index.rst index 1c5a5e6a06de..3332695b69b7 100644 --- a/boards/nxp/mr_canhubk3/doc/index.rst +++ b/boards/nxp/mr_canhubk3/doc/index.rst @@ -12,20 +12,22 @@ Hardware ******** - NXP S32K344 - - Arm Cortex-M7 (Lock-Step), 160 MHz (Max.) - - 4 MB of program flash, with ECC - - 320 KB RAM, with ECC - - Ethernet 100 Mbps, CAN FD, FlexIO, QSPI - - 12-bit 1 Msps ADC, 16-bit eMIOS timer + + - Arm Cortex-M7 (Lock-Step), 160 MHz (Max.) + - 4 MB of program flash, with ECC + - 320 KB RAM, with ECC + - Ethernet 100 Mbps, CAN FD, FlexIO, QSPI + - 12-bit 1 Msps ADC, 16-bit eMIOS timer - `NXP FS26 Safety System Basis Chip`_ -- Interfaces: - - Console UART - - 6x CAN FD - - 100Base-T1 Ethernet - - JST-GH connectors and I/O headers for I2C, SPI, GPIO, - PWM, etc. +- Interfaces + + - Console UART + - 6x CAN FD + - 100Base-T1 Ethernet + - JST-GH connectors and I/O headers for I2C, SPI, GPIO, + PWM, etc. More information about the hardware and design resources can be found at `NXP MR-CANHUBK3`_ website. diff --git a/boards/nxp/ucans32k1sic/doc/index.rst b/boards/nxp/ucans32k1sic/doc/index.rst index 9a0ec3adcbbb..d876afb5a803 100644 --- a/boards/nxp/ucans32k1sic/doc/index.rst +++ b/boards/nxp/ucans32k1sic/doc/index.rst @@ -12,18 +12,20 @@ Hardware ******** - NXP S32K146 - - Arm Cortex-M4F @ up to 112 Mhz - - 1 MB Flash - - 128 KB SRAM - - up to 127 I/Os - - 3x FlexCAN with 2x FD - - eDMA, 12-bit ADC, MPU, ECC and more. + + - Arm Cortex-M4F @ up to 112 Mhz + - 1 MB Flash + - 128 KB SRAM + - up to 127 I/Os + - 3x FlexCAN with 2x FD + - eDMA, 12-bit ADC, MPU, ECC and more. - Interfaces: - - DCD-LZ debug interface with SWD + Console / UART - - Dual CAN FD PHYs with dual connectors for daisy chain operation - - JST-GH DroneCode compliant standard connectors and I/O headers - - user RGB LED and button. + + - DCD-LZ debug interface with SWD + Console / UART + - Dual CAN FD PHYs with dual connectors for daisy chain operation + - JST-GH DroneCode compliant standard connectors and I/O headers + - User RGB LED and button. More information about the hardware and design resources can be found at `NXP UCANS32K1SIC`_ website. diff --git a/boards/others/black_f407ve/doc/index.rst b/boards/others/black_f407ve/doc/index.rst index b15012459fcd..fe2e952c1987 100644 --- a/boards/others/black_f407ve/doc/index.rst +++ b/boards/others/black_f407ve/doc/index.rst @@ -13,13 +13,13 @@ Here are some highlights of the BLACK_F407VE board: board and easy probing - Flexible board power supply: - - USB VBUS or external source (3.3V, 5V) - - Power management access point + - USB VBUS or external source (3.3V, 5V) + - Power management access point - Three LEDs: - - 3.3 V power on (LD0) - - Two user LEDs: green (LD1), green (LD2) + - 3.3 V power on (LD0) + - Two user LEDs: green (LD1), green (LD2) - Four push-buttons: RESET, K0, K1 and WK_UP - Mini-AB connector @@ -76,7 +76,7 @@ BLACK_F407VE board provides the following hardware components: - Dimensions: 85.1mm x 72.45mm More information about STM32F407VE SOC can be found here: - - `STM32F407VE on www.st.com`_ +- `STM32F407VE on www.st.com`_ Supported Features ================== diff --git a/boards/others/black_f407zg_pro/doc/index.rst b/boards/others/black_f407zg_pro/doc/index.rst index db45dd7b539f..f70032676324 100644 --- a/boards/others/black_f407zg_pro/doc/index.rst +++ b/boards/others/black_f407zg_pro/doc/index.rst @@ -13,13 +13,13 @@ Here are some highlights of the BLACK_F407ZG_PRO board: board and easy probing - Flexible board power supply: - - USB VBUS or external source (3.3V, 5V) - - Power management access point + - USB VBUS or external source (3.3V, 5V) + - Power management access point - Three LEDs: - - 3.3 V power on (LD0) - - Two user LEDs: green (LD1), green (LD2) + - 3.3 V power on (LD0) + - Two user LEDs: green (LD1), green (LD2) - Four push-buttons: RESET, K0, K1 and WK_UP - Mini-AB connector @@ -73,7 +73,7 @@ BLACK_F407ZG_PRO board provides the following hardware components: - Dimensions: 102.5mm x 74.56mm More information about STM32F407ZG SOC can be found here: - - `STM32F407ZG on www.st.com`_ +- `STM32F407ZG on www.st.com`_ Supported Features ================== diff --git a/boards/shields/p3t1755dp_ard_i2c/doc/index.rst b/boards/shields/p3t1755dp_ard_i2c/doc/index.rst index 866ecfd6dd5f..52f52f67f947 100644 --- a/boards/shields/p3t1755dp_ard_i2c/doc/index.rst +++ b/boards/shields/p3t1755dp_ard_i2c/doc/index.rst @@ -29,17 +29,18 @@ For more information about P3T1755DP-ARD see these NXP documents: Hardware Connection ******************* -- Shield board p3t1755dp_ard in I3C mode - J10, J11, J12 3-5, the i3c addr is 0x4800000236152a0090 - JP2, Jp3 1-2 - I3C is from J13 - The VDD from arduino is 3v3 JP1 2-3 - -- Shield board p3t1755dp_ard in I2C mode - J10, J11, J12 3-5, the i2c addr is 0x48 - JP2, Jp3 2-3 - The I2C is from Arduino J5 pin9(SCL_ARD) pin10(SDA_ARD) - The VDD from arduino is 3v3 JP1 2-3 + +Shield board p3t1755dp_ard in I3C mode + - J10, J11, J12 3-5, the i3c addr is 0x4800000236152a0090 + - JP2, Jp3 1-2 + - I3C is from J13 + - The VDD from arduino is 3v3 JP1 2-3 + +Shield board p3t1755dp_ard in I2C mode + - J10, J11, J12 3-5, the i2c addr is 0x48 + - JP2, Jp3 2-3 + - The I2C is from Arduino J5 pin9(SCL_ARD) pin10(SDA_ARD) + - The VDD from arduino is 3v3 JP1 2-3 Programming *********** diff --git a/boards/shields/p3t1755dp_ard_i3c/doc/index.rst b/boards/shields/p3t1755dp_ard_i3c/doc/index.rst index ff76ea334109..1a58292f78b6 100644 --- a/boards/shields/p3t1755dp_ard_i3c/doc/index.rst +++ b/boards/shields/p3t1755dp_ard_i3c/doc/index.rst @@ -29,13 +29,14 @@ For more information about P3T1755DP-ARD see these NXP documents: Hardware Connection ******************* -- Shield board p3t1755dp_ard in I3C mode + +Shield board p3t1755dp_ard in I3C mode J10, J11, J12 3-5, the i3c addr is 0x4800000236152a0090 JP2, Jp3 1-2 I3C is from J13 The VDD from arduino is 3v3 JP1 2-3 -- Shield board p3t1755dp_ard in I2C mode +Shield board p3t1755dp_ard in I2C mode J10, J11, J12 3-5, the i2c addr is 0x48 JP2, Jp3 2-3 The I2C is from Arduino J5 pin9(SCL_ARD) pin10(SDA_ARD) diff --git a/boards/shields/x_nucleo_bnrg2a1/doc/index.rst b/boards/shields/x_nucleo_bnrg2a1/doc/index.rst index 411c4982818a..fdc36ffcadd5 100644 --- a/boards/shields/x_nucleo_bnrg2a1/doc/index.rst +++ b/boards/shields/x_nucleo_bnrg2a1/doc/index.rst @@ -57,7 +57,8 @@ X-NUCLEO-BNRG2A1 provides a BlueNRG-M2SP chip with the following key features: - BLE data packet length extension More information about X-NUCLEO-BNRG2A1 can be found here: - - `X-NUCLEO-BNRG2A1 databrief`_ + +- `X-NUCLEO-BNRG2A1 databrief`_ Programming *********** diff --git a/boards/shields/x_nucleo_idb05a1/doc/index.rst b/boards/shields/x_nucleo_idb05a1/doc/index.rst index 57e23ae92e85..cd40ff80b9aa 100644 --- a/boards/shields/x_nucleo_idb05a1/doc/index.rst +++ b/boards/shields/x_nucleo_idb05a1/doc/index.rst @@ -67,7 +67,8 @@ X-NUCLEO-IDB05A1 provides a SPBTLE-RF chip with the following key features: - Chip antenna More information about X-NUCLEO-IDB05A1 can be found here: - - `X-NUCLEO-IDB05A1 databrief`_ + +- `X-NUCLEO-IDB05A1 databrief`_ Programming *********** diff --git a/boards/shields/x_nucleo_iks01a1/doc/index.rst b/boards/shields/x_nucleo_iks01a1/doc/index.rst index 329471e89f15..77fe585fdb99 100644 --- a/boards/shields/x_nucleo_iks01a1/doc/index.rst +++ b/boards/shields/x_nucleo_iks01a1/doc/index.rst @@ -38,7 +38,8 @@ X-NUCLEO-IKS01A1 provides the following key features: More information about X-NUCLEO-IKS01A1 can be found here: - - `X-NUCLEO-IKS01A1 data sheet`_ + +- `X-NUCLEO-IKS01A1 data sheet`_ Programming diff --git a/boards/shields/x_nucleo_iks01a2/doc/index.rst b/boards/shields/x_nucleo_iks01a2/doc/index.rst index 9fa9d2535207..39f77600ca19 100644 --- a/boards/shields/x_nucleo_iks01a2/doc/index.rst +++ b/boards/shields/x_nucleo_iks01a2/doc/index.rst @@ -40,7 +40,8 @@ X-NUCLEO-IKS01A2 provides the following key features: More information about X-NUCLEO-IKS01A2 can be found here: - - `X-NUCLEO-IKS01A2 databrief`_ + +- `X-NUCLEO-IKS01A2 databrief`_ Hardware Configuration ********************** diff --git a/boards/shields/x_nucleo_wb05kn1/doc/index.rst b/boards/shields/x_nucleo_wb05kn1/doc/index.rst index a723f90ed605..a6cbe138588a 100644 --- a/boards/shields/x_nucleo_wb05kn1/doc/index.rst +++ b/boards/shields/x_nucleo_wb05kn1/doc/index.rst @@ -74,7 +74,8 @@ IRQ and reset pins are also necessary in addition to SPI pins. +----------------+-----------------------+ More information about X-NUCLEO-WB05KN1 can be found here: - - `X-NUCLEO-WB05KN1 datasheet`_ + +- `X-NUCLEO-WB05KN1 datasheet`_ Programming *********** diff --git a/boards/st/b_g474e_dpow1/doc/index.rst b/boards/st/b_g474e_dpow1/doc/index.rst index 3ce1acb1bb79..5ad823adac75 100644 --- a/boards/st/b_g474e_dpow1/doc/index.rst +++ b/boards/st/b_g474e_dpow1/doc/index.rst @@ -23,10 +23,12 @@ the STLINK-V3E debugger and programmer. - 3 LEDs for power and ST-LINK communication - 4-direction joystick with a selection button - Reset push-button -- Board connectors: - - USB Type-C |reg| - - USB Micro-B - - 2 x 32-pin header, 2.54 mm pitch, daughterboard extension connector for breadboard connection +- Board connectors + + - USB Type-C |reg| + - USB Micro-B + - 2 x 32-pin header, 2.54 mm pitch, daughterboard extension connector for breadboard connection + - Flexible power-supply options: ST-LINK USB VBUS or USB Type-C |reg| VBUS or external source - On-board STLINK-V3E debugger/programmer with USB re-enumeration capability: mass storage, Virtual COM port, and debug port diff --git a/boards/st/b_l4s5i_iot01a/doc/index.rst b/boards/st/b_l4s5i_iot01a/doc/index.rst index 82cfef309350..8d73a76187cd 100644 --- a/boards/st/b_l4s5i_iot01a/doc/index.rst +++ b/boards/st/b_l4s5i_iot01a/doc/index.rst @@ -32,10 +32,10 @@ some highlights of the B_L4S5I_IOT01A Discovery kit: - MCU current ammeter with 4 ranges and auto-calibration - Flexible power supply options: - - ST-LINK/V2-1 - - USB FS connector - - External 5 V + - ST-LINK/V2-1 + - USB FS connector + - External 5 V More information about the board can be found at the `B L4S5I IOT01A Discovery kit website`_. @@ -47,43 +47,53 @@ The STM32L4S5VI SoC provides the following hardware features: - Ultra-low-power with FlexPowerControl (down to 130 nA Standby mode and 100 uA/MHz run mode) - Core: ARM |reg| 32-bit Cortex |reg|-M4 CPU with FPU, frequency up to 120 MHz, 100DMIPS/1.25DMIPS/MHz (Dhrystone 2.1) - Clock Sources: - - 4 to 48 MHz crystal oscillator - - 32 kHz crystal oscillator for RTC (LSE) - - Internal 16 MHz factory-trimmed RC ( |plusminus| 1%) - - Internal low-power 32 kHz RC ( |plusminus| 5%) - - Internal multispeed 100 kHz to 48 MHz oscillator, auto-trimmed by - LSE (better than |plusminus| 0.25 % accuracy) - - 3 PLLs for system clock, USB, audio, ADC + + - 4 to 48 MHz crystal oscillator + - 32 kHz crystal oscillator for RTC (LSE) + - Internal 16 MHz factory-trimmed RC ( |plusminus| 1%) + - Internal low-power 32 kHz RC ( |plusminus| 5%) + - Internal multispeed 100 kHz to 48 MHz oscillator, auto-trimmed by + LSE (better than |plusminus| 0.25 % accuracy) + - 3 PLLs for system clock, USB, audio, ADC + - RTC with HW calendar, alarms and calibration - Up to 21 capacitive sensing channels: support touchkey, linear and rotary touch sensors - 16x timers: - - 2x 16-bit advanced control - - 2x 32-bit and 5x 16-bit general purpose - - 2x 16-bit basic - - 2x low-power 16-bit timers (available in Stop mode) - - 2x watchdogs - - SysTick timer + + - 2x 16-bit advanced control + - 2x 32-bit and 5x 16-bit general purpose + - 2x 16-bit basic + - 2x low-power 16-bit timers (available in Stop mode) + - 2x watchdogs + - SysTick timer + - Up to 83 fast I/Os, most 5 V-tolerant - Memories - - Up to 2 MB Flash, 2 banks read-while-write, proprietary code readout protection - - Up to 640 KB of SRAM including 32 KB with hardware parity check - - External memory interface for static memories supporting SRAM, PSRAM, NOR and NAND memories - - Octo SPI memory interface + + - Up to 2 MB Flash, 2 banks read-while-write, proprietary code readout protection + - Up to 640 KB of SRAM including 32 KB with hardware parity check + - External memory interface for static memories supporting SRAM, PSRAM, NOR and NAND memories + - Octo SPI memory interface + - 4x digital filters for sigma delta modulator - Rich analog peripherals (independent supply) - - 1x 12-bit ADC 5 MSPS, up to 16-bit with hardware oversampling, 200 uA/MSPS - - 2x 12-bit DAC, low-power sample and hold - - 2x operational amplifiers with built-in PGA - - 2x ultra-low-power comparators + + - 1x 12-bit ADC 5 MSPS, up to 16-bit with hardware oversampling, 200 uA/MSPS + - 2x 12-bit DAC, low-power sample and hold + - 2x operational amplifiers with built-in PGA + - 2x ultra-low-power comparators + - 18x communication interfaces - - USB OTG 2.0 full-speed, LPM and BCD - - 2x SAIs (serial audio interface) - - 4x I2C FM+(1 Mbit/s), SMBus/PMBus - - 6x USARTs (ISO 7816, LIN, IrDA, modem) - - 3x SPIs (4x SPIs with the Quad SPI) - - CAN (2.0B Active) and SDMMC interface - - SDMMC I/F - - DCMI camera interface + + - USB OTG 2.0 full-speed, LPM and BCD + - 2x SAIs (serial audio interface) + - 4x I2C FM+(1 Mbit/s), SMBus/PMBus + - 6x USARTs (ISO 7816, LIN, IrDA, modem) + - 3x SPIs (4x SPIs with the Quad SPI) + - CAN (2.0B Active) and SDMMC interface + - SDMMC I/F + - DCMI camera interface + - 14-channel DMA controller with multiplex request router - True random number generator - CRC calculation unit, 96-bit unique ID @@ -92,8 +102,9 @@ The STM32L4S5VI SoC provides the following hardware features: More information about STM32L4S5VI can be found here: - - `STM32L4S5VI on www.st.com`_ - - `STM32L4S5 reference manual`_ + +- `STM32L4S5VI on www.st.com`_ +- `STM32L4S5 reference manual`_ Supported Features diff --git a/boards/st/b_u585i_iot02a/doc/index.rst b/boards/st/b_u585i_iot02a/doc/index.rst index 214f84b9d18d..fe4a2f1fd6b7 100644 --- a/boards/st/b_u585i_iot02a/doc/index.rst +++ b/boards/st/b_u585i_iot02a/doc/index.rst @@ -26,10 +26,11 @@ some highlights of the B_U585I_IOT02A Discovery kit: - 2 push-buttons (user and reset) - 2 user LEDs -- Flexible power supply options: - - ST-LINK/V3 - - USB Vbus - - External sources +- Flexible power supply options + + - ST-LINK/V3 + - USB Vbus + - External sources More information about the board can be found at the `B U585I IOT02A Discovery kit website`_. diff --git a/boards/st/disco_l475_iot1/doc/index.rst b/boards/st/disco_l475_iot1/doc/index.rst index 60523b3cfe1e..dc118d845723 100644 --- a/boards/st/disco_l475_iot1/doc/index.rst +++ b/boards/st/disco_l475_iot1/doc/index.rst @@ -25,12 +25,17 @@ This kit provides: - 2 push-buttons (user and reset) - USB OTG FS with Micro-AB connector - Expansion connectors: - - Arduino |trade| Uno V3 - - PMOD + + - Arduino |trade| Uno V3 + - PMOD + - Flexible power-supply options: - - ST LINK USB VBUS or external sources + + - ST LINK USB VBUS or external sources + - On-board ST-LINK/V2-1 debugger/programmer with USB re-enumeration capability: - - mass storage, virtual COM port and debug port + + - Mass storage, virtual COM port and debug port More information about the board can be found at the `Disco L475 IoT1 website`_. @@ -43,42 +48,52 @@ The STM32L475VG SoC provides the following hardware IPs: - Ultra-low-power with FlexPowerControl (down to 120 nA Standby mode and 100 uA/MHz run mode) - Core: ARM |reg| 32-bit Cortex |reg|-M4 CPU with FPU, frequency up to 80 MHz, 100DMIPS/1.25DMIPS/MHz (Dhrystone 2.1) - Clock Sources: - - 4 to 48 MHz crystal oscillator - - 32 kHz crystal oscillator for RTC (LSE) - - Internal 16 MHz factory-trimmed RC ( |plusminus| 1%) - - Internal low-power 32 kHz RC ( |plusminus| 5%) - - Internal multispeed 100 kHz to 48 MHz oscillator, auto-trimmed by - LSE (better than |plusminus| 0.25 % accuracy) - - 3 PLLs for system clock, USB, audio, ADC + + - 4 to 48 MHz crystal oscillator + - 32 kHz crystal oscillator for RTC (LSE) + - Internal 16 MHz factory-trimmed RC ( |plusminus| 1%) + - Internal low-power 32 kHz RC ( |plusminus| 5%) + - Internal multispeed 100 kHz to 48 MHz oscillator, auto-trimmed by + LSE (better than |plusminus| 0.25 % accuracy) + - 3 PLLs for system clock, USB, audio, ADC + - RTC with HW calendar, alarms and calibration - Up to 24 capacitive sensing channels: support touchkey, linear and rotary touch sensors - 16x timers: - - 2x 16-bit advanced motor-control - - 2x 32-bit and 5x 16-bit general purpose - - 2x 16-bit basic - - 2x low-power 16-bit timers (available in Stop mode) - - 2x watchdogs - - SysTick timer + + - 2x 16-bit advanced motor-control + - 2x 32-bit and 5x 16-bit general purpose + - 2x 16-bit basic + - 2x low-power 16-bit timers (available in Stop mode) + - 2x watchdogs + - SysTick timer + - Up to 114 fast I/Os, most 5 V-tolerant, up to 14 I/Os with independent supply down to 1.08 V - Memories - - Up to 1 MB Flash, 2 banks read-while-write, proprietary code readout protection - - Up to 128 KB of SRAM including 32 KB with hardware parity check - - External memory interface for static memories supporting SRAM, PSRAM, NOR and NAND memories - - Quad SPI memory interface + + - Up to 1 MB Flash, 2 banks read-while-write, proprietary code readout protection + - Up to 128 KB of SRAM including 32 KB with hardware parity check + - External memory interface for static memories supporting SRAM, PSRAM, NOR and NAND memories + - Quad SPI memory interface + - 4x digital filters for sigma delta modulator - Rich analog peripherals (independent supply) - - 2x 12-bit ADC 5 MSPS, up to 16-bit with hardware oversampling, 200 uA/MSPS - - 2x 12-bit DAC, low-power sample and hold - - 2x operational amplifiers with built-in PGA - - 2x ultra-low-power comparators + + - 2x 12-bit ADC 5 MSPS, up to 16-bit with hardware oversampling, 200 uA/MSPS + - 2x 12-bit DAC, low-power sample and hold + - 2x operational amplifiers with built-in PGA + - 2x ultra-low-power comparators + - 18x communication interfaces - - USB OTG 2.0 full-speed, LPM and BCD - - 2x SAIs (serial audio interface) - - 3x I2C FM+(1 Mbit/s), SMBus/PMBus - - 6x USARTs (ISO 7816, LIN, IrDA, modem) - - 3x SPIs (4x SPIs with the Quad SPI) - - CAN (2.0B Active) and SDMMC interface - - SWPMI single wire protocol master I/F + + - USB OTG 2.0 full-speed, LPM and BCD + - 2x SAIs (serial audio interface) + - 3x I2C FM+(1 Mbit/s), SMBus/PMBus + - 6x USARTs (ISO 7816, LIN, IrDA, modem) + - 3x SPIs (4x SPIs with the Quad SPI) + - CAN (2.0B Active) and SDMMC interface + - SWPMI single wire protocol master I/F + - 14-channel DMA controller - True random number generator - CRC calculation unit, 96-bit unique ID @@ -86,8 +101,9 @@ The STM32L475VG SoC provides the following hardware IPs: More information about STM32L475VG can be found here: - - `STM32L475VG on www.st.com`_ - - `STM32L475 reference manual`_ + +- `STM32L475VG on www.st.com`_ +- `STM32L475 reference manual`_ Supported Features ================== diff --git a/boards/st/nucleo_f722ze/doc/index.rst b/boards/st/nucleo_f722ze/doc/index.rst index 8a98d09ee18c..805cc3f36c4b 100644 --- a/boards/st/nucleo_f722ze/doc/index.rst +++ b/boards/st/nucleo_f722ze/doc/index.rst @@ -13,10 +13,12 @@ Key Features: - 1 user button and 1 reset button - 32.768 kHz crystal oscillator - Board connectors: - - USB Micro-AB - - SWD - - ST Zio connector (Arduino Uno R3 compatible) - - ST Morpho connector + + - USB Micro-AB + - SWD + - ST Zio connector (Arduino Uno R3 compatible) + - ST Morpho connector + - On-board ST-LINK debugger/programmer - Flexible power supply options, including ST-LINK VBUS and external sources. @@ -60,48 +62,69 @@ Connections and IOs =================== - SDMMC1: Pins marked as "SDMMC" on the ST Zio connector. - - D0: PC8 (CN8 pin 2) - - D1: PC9 (CN8 pin 4) - - D2: PC10 (CN8 pin 6) - - D3: PC11 (CN8 pin 8) - - CK: PC12 (CN8 pin 10) - - CMD: PD2 (CN8 pin 12) + + - D0: PC8 (CN8 pin 2) + - D1: PC9 (CN8 pin 4) + - D2: PC10 (CN8 pin 6) + - D3: PC11 (CN8 pin 8) + - CK: PC12 (CN8 pin 10) + - CMD: PD2 (CN8 pin 12) + - ADC1: - - IN3: PA3 (CN9 pin 1, Arduino A0) - - IN10: PC0 (CN9 pin 3, Arduino A1) + + - IN3: PA3 (CN9 pin 1, Arduino A0) + - IN10: PC0 (CN9 pin 3, Arduino A1) + - DAC1: - - OUT1: PA4 (CN7 pin 17) + + - OUT1: PA4 (CN7 pin 17) + - I2C2: Pins marked as "I2C" on the ST Zio connector. - - SCL: PF1 (CN9 pin 19) - - SDA: PF0 (CN9 pin 21) + + - SCL: PF1 (CN9 pin 19) + - SDA: PF0 (CN9 pin 21) + - CAN1: Pins marked as "CAN" on the ST Zio connector. - - RX: PD0 (CN9 pin 25) - - TX: PD1 (CN9 pin 27) + + - RX: PD0 (CN9 pin 25) + - TX: PD1 (CN9 pin 27) + - USART2: Pins marked as "USART" on the ST Zio connector. - - RX: PD6 (CN9 pin 4) - - TX: PD5 (CN9 pin 6) - - RTS: PD4 (CN9 pin 8) - - CTS: PD3 (CN9 pin 10) + + - RX: PD6 (CN9 pin 4) + - TX: PD5 (CN9 pin 6) + - RTS: PD4 (CN9 pin 8) + - CTS: PD3 (CN9 pin 10) + - PWM1: Uses TIMER1. - - PE13 (CN10 pin 10, Arduino D3) - - PE11 (CN10 pin 6, Arduino D5) + + - PE13 (CN10 pin 10, Arduino D3) + - PE11 (CN10 pin 6, Arduino D5) + - USART3: Connected to ST-Link virtual COM port. - - TX: PD8 - - RX: PD9 + + - TX: PD8 + - RX: PD9 + - USART6: Arduino UART port. - - RX: PG9 (CN10 pin 16, Arduino D0) - - TX: PG14 (CN10 pin 14, Arduino D1) + + - RX: PG9 (CN10 pin 16, Arduino D0) + - TX: PG14 (CN10 pin 14, Arduino D1) + - USBOTG_FS: Connected to USB Micro-AB connector (CN13) - - DM: PA11 - - DP: PA12 - - ID: PA10 + + - DM: PA11 + - DP: PA12 + - ID: PA10 + - QUADSPI: Pins marked as "QSPI" on the ST Zio connector. - - CS: PB6 (CN10 pin 13) - - CLK: PB2 (CN10 pin 15) - - IO3: PD13 (CN10 pin 19) - - IO1: PD12 (CN10 pin 21) - - IO0: PD11 (CN10 pin 23) - - IO2: PE2 (CN10 pin 25) + + - CS: PB6 (CN10 pin 13) + - CLK: PB2 (CN10 pin 15) + - IO3: PD13 (CN10 pin 19) + - IO1: PD12 (CN10 pin 21) + - IO0: PD11 (CN10 pin 23) + - IO2: PE2 (CN10 pin 25) System Clock ------------ diff --git a/boards/st/stm3210c_eval/doc/index.rst b/boards/st/stm3210c_eval/doc/index.rst index 61e8fd3a20ba..c7682ec0c873 100644 --- a/boards/st/stm3210c_eval/doc/index.rst +++ b/boards/st/stm3210c_eval/doc/index.rst @@ -19,10 +19,12 @@ Hardware STM3210C-EVAL provides the following hardware components: -- Three 5 V power supply options: - - Power jack - - USB connector - - daughterboard +- Three 5 V power supply options + + - Power jack + - USB connector + - Daughterboard + - Boot from user Flash, system memory or SRAM. - I2S audio DAC, stereo audio jack. - 2 GByte (or more) microSD CardTM. @@ -44,7 +46,8 @@ STM3210C-EVAL provides the following hardware components: - Extension connector for daughterboard or wrapping board. More information about STM32F107VCT can be found here: - - `STM32F107VCT reference manual`_ + +- `STM32F107VCT reference manual`_ Supported Features diff --git a/boards/st/stm32373c_eval/doc/index.rst b/boards/st/stm32373c_eval/doc/index.rst index 28758854910b..91ed0da30b62 100644 --- a/boards/st/stm32373c_eval/doc/index.rst +++ b/boards/st/stm32373c_eval/doc/index.rst @@ -16,11 +16,12 @@ Hardware STM32373C-EVAL provides the following hardware components: - STM32F373VCT6 microcontroller -- Four 5 V power supply options: - - Power jack - - ST-LINK/V2 USB connector - - User USB connector - - Daughter board +- Four 5 V power supply options + - Power jack + - ST-LINK/V2 USB connector + - User USB connector + - Daughter board + - Audio jack connected to I2 S DAC - Microphone connected to ADC through an amplifier - 2-GByte (or more) MicroSD card on SPI @@ -48,7 +49,8 @@ STM32373C-EVAL provides the following hardware components: - Embedded ST-LINK/V2 More information about STM32F373VCT6 can be found here: - - `STM32F373VCT6 reference manual`_ + +- `STM32F373VCT6 reference manual`_ Supported Features diff --git a/boards/st/stm32f072_eval/doc/index.rst b/boards/st/stm32f072_eval/doc/index.rst index 19cf2e4e8f65..437b9acd58ea 100644 --- a/boards/st/stm32f072_eval/doc/index.rst +++ b/boards/st/stm32f072_eval/doc/index.rst @@ -62,8 +62,9 @@ STM32F072-EVAL Discovery kit provides the following hardware components: - Up to 87 fast I/Os: 68 I/Os with 5V tolerant capability and 19 with independent supply More information about STM32F072VB can be found here: - - `STM32F072VB on www.st.com`_ - - `STM32F072 reference manual`_ + +- `STM32F072VB on www.st.com`_ +- `STM32F072 reference manual`_ Supported Features ================== diff --git a/boards/st/stm32f072b_disco/doc/index.rst b/boards/st/stm32f072b_disco/doc/index.rst index 3794fc098fae..08a414a83fc6 100644 --- a/boards/st/stm32f072b_disco/doc/index.rst +++ b/boards/st/stm32f072b_disco/doc/index.rst @@ -54,8 +54,9 @@ STM32F072B-DISCO Discovery kit provides the following hardware components: - 24 capacitive sensing channels for touchkey, linear and rotary touch sensors More information about STM32F072RB can be found here: - - `STM32F072RB on www.st.com`_ - - `STM32F072xB reference manual`_ + +- `STM32F072RB on www.st.com`_ +- `STM32F072xB reference manual`_ Supported Features ================== diff --git a/boards/st/stm32f3_disco/doc/index.rst b/boards/st/stm32f3_disco/doc/index.rst index c73c6768499a..aa77e36acca3 100644 --- a/boards/st/stm32f3_disco/doc/index.rst +++ b/boards/st/stm32f3_disco/doc/index.rst @@ -18,10 +18,10 @@ started quickly. Here are some highlights of the STM32F3DISCOVERY board: - Ten LEDs: - - 3.3 V power on (LD1) - - USB communication (LD2) - - Eight user LEDs: red (LD3/LD10), blue (LD4/LD9), orange (LD5/LD9) - and green (LD6/LD7) + - 3.3 V power on (LD1) + - USB communication (LD2) + - Eight user LEDs: red (LD3/LD10), blue (LD4/LD9), orange (LD5/LD9) + and green (LD6/LD7) - Two push-buttons: USER and RESET - USB USER with Mini-B connector @@ -61,8 +61,9 @@ STM32F3DISCOVERY Discovery kit provides the following hardware components: - DMA Controller More information about STM32F303VC can be found here: - - `STM32F303VC on www.st.com`_ - - `STM32F303xC reference manual`_ + +- `STM32F303VC on www.st.com`_ +- `STM32F303xC reference manual`_ Supported Features ================== diff --git a/boards/st/stm32f411e_disco/doc/index.rst b/boards/st/stm32f411e_disco/doc/index.rst index efa5b7717fc1..72cc16557b04 100644 --- a/boards/st/stm32f411e_disco/doc/index.rst +++ b/boards/st/stm32f411e_disco/doc/index.rst @@ -15,13 +15,15 @@ Here are some highlights of the STM32F411E-DISCO board: - LSM303DLHC(rev B) or LSM303AGR(rev D): ST MEMS system-in-package featuring a 3D digital linear acceleration sensor and a 3D digital magnetic sensor. - MP45DT02(rev B) or IMP34DT05(rev D), ST MEMS audio sensor, omnidirectional digital microphone - CS43L22, audio DAC with integrated class D speaker driver -- Eight LEDs: - - LD1 (red/green) for USB communication - - LD2 (red) for 3.3 V power on - - Four user LEDs: - LD3 (orange), LD4 (green), LD5 (red) and LD6 (blue) - - Two USB OTG LEDs: - LD7 (green) VBus and LD8 (red) over-current +- Eight LEDs + + - LD1 (red/green) for USB communication + - LD2 (red) for 3.3 V power on + - Four user LEDs: + LD3 (orange), LD4 (green), LD5 (red) and LD6 (blue) + - Two USB OTG LEDs: + LD7 (green) VBus and LD8 (red) over-current + - Two pushbuttons (user and reset) - USB OTG with micro-AB connector - Extension header for LQFP100 I/Os for a quick connection to the prototyping board and an easy probing @@ -53,8 +55,9 @@ STM32F411E-DISCO Discovery kit provides the following hardware components: - RTC More information about STM32F411VE can be found here: - - `STM32F411VE website`_ - - `STM32F411x reference manual`_ + +- `STM32F411VE website`_ +- `STM32F411x reference manual`_ Supported Features ================== diff --git a/boards/st/stm32f412g_disco/doc/index.rst b/boards/st/stm32f412g_disco/doc/index.rst index fb7fa80482ce..d1ef9837ae0b 100644 --- a/boards/st/stm32f412g_disco/doc/index.rst +++ b/boards/st/stm32f412g_disco/doc/index.rst @@ -11,9 +11,9 @@ some highlights of the STM32F412G-DISCO board: - STM32F412ZGT6 microcontroller featuring 1 Mbyte of Flash memory and 256 Kbytes of RAM in an LQFP144 package - On-board ST-LINK/V2-1 SWD debugger supporting USB re-enumeration capability: - - USB virtual COM port - - mass storage - - debug port + - USB virtual COM port + - Mass storage + - Debug port - 1.54 inch 240x240 pixel TFT color LCD with parallel interface and capacitive touchscreen - I2S Audio CODEC, with a stereo headset jack, including analog microphone input and a loudspeaker output @@ -26,10 +26,10 @@ some highlights of the STM32F412G-DISCO board: - USB OTG FS with Micro-AB connector - Four power supply options: - - ST-LINK/V2-1 USB connector - - User USB FS connector - - VIN from Arduino* connectors - - + 5 V from Arduino* connectors + - ST-LINK/V2-1 USB connector + - User USB FS connector + - VIN from Arduino* connectors + - + 5 V from Arduino* connectors - Two power supplies for MCU: 2.0 V and 3.3 V - Compatible with Arduino(tm) Uno revision 3 connectors @@ -66,8 +66,9 @@ STM32F412G-DISCO Discovery kit provides the following hardware components: - DMA Controller More information about STM32F412ZG can be found here: - - `STM32F412ZG on www.st.com`_ - - `STM32F412 reference manual`_ + +- `STM32F412ZG on www.st.com`_ +- `STM32F412 reference manual`_ Supported Features ================== diff --git a/boards/st/stm32f413h_disco/doc/index.rst b/boards/st/stm32f413h_disco/doc/index.rst index be2433a18c58..cf2ad937a6bd 100644 --- a/boards/st/stm32f413h_disco/doc/index.rst +++ b/boards/st/stm32f413h_disco/doc/index.rst @@ -11,9 +11,9 @@ some highlights of the STM32F413H-DISCO board: - STM32F413ZHT6 microcontroller featuring 1.5 Mbyte of Flash memory and 320 Kbytes of RAM in an LQFP144 package - On-board ST-LINK/V2-1 SWD debugger supporting USB re-enumeration capability: - - USB virtual COM port - - mass storage - - debug port + - USB virtual COM port + - Mass storage + - Debug port - 1.54 inch 240x240 pixel TFT color LCD with parallel interface and capacitive touchscreen - I2S Audio CODEC, with a stereo headset jack, including analog microphone input and a loudspeaker output @@ -27,10 +27,10 @@ some highlights of the STM32F413H-DISCO board: - USB OTG FS with Micro-AB connector - Four power supply options: - - ST-LINK/V2-1 USB connector - - User USB FS connector - - VIN from Arduino* connectors - - + 5 V from Arduino* connectors + - ST-LINK/V2-1 USB connector + - User USB FS connector + - VIN from Arduino* connectors + - + 5 V from Arduino* connectors - Two power supplies for MCU: 2.0 V and 3.3 V - Compatible with Arduino(tm) Uno revision 3 connectors @@ -69,8 +69,9 @@ STM32F413H-DISCO Discovery kit provides the following hardware components: - DMA Controller More information about STM32F413ZH can be found here: - - `STM32F413ZH on www.st.com`_ - - `STM32F413 reference manual`_ + +- `STM32F413ZH on www.st.com`_ +- `STM32F413 reference manual`_ Supported Features ================== diff --git a/boards/st/stm32f429i_disc1/doc/index.rst b/boards/st/stm32f429i_disc1/doc/index.rst index 6bac481d9b2f..cddad1e0f5b5 100644 --- a/boards/st/stm32f429i_disc1/doc/index.rst +++ b/boards/st/stm32f429i_disc1/doc/index.rst @@ -12,9 +12,9 @@ some highlights of the STM32F429I-DISC1 board: - On-board ST-LINK/V2-B debugger/programmer with SWD connector - Flexible board power supply: - - ST-LINK/V2-1 USB connector - - User USB FS connector - - VIN from Arduino* compatible connectors + - ST-LINK/V2-1 USB connector + - User USB FS connector + - VIN from Arduino* compatible connectors - Two push-buttons: USER and RESET - USB OTG FS with micro-AB connector @@ -62,8 +62,9 @@ The STM32F429I-DISC1 Discovery kit provides the following hardware components: - DMA Controller More information about STM32F429ZI can be found here: - - `STM32F429ZI on www.st.com`_ - - `STM32F429 Reference Manual`_ + +- `STM32F429ZI on www.st.com`_ +- `STM32F429 Reference Manual`_ Supported Features ================== diff --git a/boards/st/stm32f469i_disco/doc/index.rst b/boards/st/stm32f469i_disco/doc/index.rst index e6830efb2be4..0deebfce9708 100644 --- a/boards/st/stm32f469i_disco/doc/index.rst +++ b/boards/st/stm32f469i_disco/doc/index.rst @@ -12,9 +12,9 @@ some highlights of the STM32F469I-DISCO board: - On-board ST-LINK/V2-1 debugger/programmer, supporting USB reenumeration capability - Flexible board power supply: - - ST-LINK/V2-1 USB connector - - User USB FS connector - - VIN from Arduino* compatible connectors + - ST-LINK/V2-1 USB connector + - User USB FS connector + - VIN from Arduino* compatible connectors - Four user LEDs - Two push-buttons: USER and RESET @@ -66,8 +66,9 @@ STM32F469I-DISCO Discovery kit provides the following hardware components: - DMA Controller More information about STM32F469NI can be found here: - - `STM32F469NI on www.st.com`_ - - `STM32F469 reference manual`_ + +- `STM32F469NI on www.st.com`_ +- `STM32F469 reference manual`_ Supported Features ================== diff --git a/boards/st/stm32f4_disco/doc/index.rst b/boards/st/stm32f4_disco/doc/index.rst index 18e8ac7e2be9..274c20a517f0 100644 --- a/boards/st/stm32f4_disco/doc/index.rst +++ b/boards/st/stm32f4_disco/doc/index.rst @@ -13,15 +13,15 @@ some highlights of the STM32F4DISCOVERY board: - On-board ST-LINK/V2 debugger/programmer with SWD connector - Flexible board power supply: - - USB VBUS or external source(3.3V, 5V, 7 - 12V) - - Power management access point + - USB VBUS or external source(3.3V, 5V, 7 - 12V) + - Power management access point - Eight LEDs: - - USB communication (LD1) - - 3.3 V power on (LD2) - - Four user LEDs: orange (LD3), green (LD4), red (LD5), and blue (LD6) - - 2 USB OTG LEDs for VBUS (LD7) and over-current (LD8) + - USB communication (LD1) + - 3.3 V power on (LD2) + - Four user LEDs: orange (LD3), green (LD4), red (LD5), and blue (LD6) + - 2 USB OTG LEDs for VBUS (LD7) and over-current (LD8) - Two push-buttons: USER and RESET - USB OTG FS with micro-AB connector @@ -63,8 +63,9 @@ STM32F4DISCOVERY Discovery kit provides the following hardware components: - DMA Controller More information about STM32F407VG can be found here: - - `STM32F407VG on www.st.com`_ - - `STM32F407 reference manual`_ + +- `STM32F407VG on www.st.com`_ +- `STM32F407 reference manual`_ Supported Features ================== diff --git a/boards/st/stm32g071b_disco/doc/index.rst b/boards/st/stm32g071b_disco/doc/index.rst index 8e7f08f337d5..6063ed55a8e6 100644 --- a/boards/st/stm32g071b_disco/doc/index.rst +++ b/boards/st/stm32g071b_disco/doc/index.rst @@ -26,16 +26,20 @@ as a USB Type-C |reg| and Power Delivery analyzer. - 3 LEDs for power and ST-LINK communication - 4-way joystick with selection button - 1 reset push-button -- Board external connectors: - - USB Type-C |reg| plug cable - - USB Type-C |reg| receptacle connector - - 8-pin user extension connector including ADC, SPI, USART and - I2C communication signals - - USB with Micro-AB (ST-LINK) +- Board external connectors + + - USB Type-C |reg| plug cable + - USB Type-C |reg| receptacle connector + - 8-pin user extension connector including ADC, SPI, USART and + I2C communication signals + - USB with Micro-AB (ST-LINK) + - Board internal connectors: - - 2 x 8-pin GPIOs free pins from microcontroller - (accessible internally when case is removed) - - USB Type-C |reg| test points for main signals + + - 2 x 8-pin GPIOs free pins from microcontroller + (accessible internally when case is removed) + - USB Type-C |reg| test points for main signals + - Flexible power-supply options: ST-LINK USB VBUS or USB Type-C |reg| VBUS - On-board ST-LINK/V2-1 debugger/programmer with USB enumeration capability: mass storage, Virtual COM port and debug port diff --git a/boards/st/stm32g081b_eval/doc/index.rst b/boards/st/stm32g081b_eval/doc/index.rst index 18d9bdedaffa..d49294318c49 100644 --- a/boards/st/stm32g081b_eval/doc/index.rst +++ b/boards/st/stm32g081b_eval/doc/index.rst @@ -29,61 +29,68 @@ only. Both support USB PD protocol and alternate mode functionality. Application firmware examples are provided to evaluate the USB-C technology through various use cases. - - -- Mother board - - STM32G081RBT6 microcontroller with 128 Kbytes of Flash memory and - 32 Kbytes of RAM in LQFP64 package - - MCU voltage choice fixed 3.3 V or adjustable from 1.65 V to 3.6 V - - I2C compatible serial interface - - RTC with backup battery - - 8-Gbyte or more SPI interface microSD card - - Potentiometer - - 4 color user LEDs and one LED as MCU low-power alarm - - Reset, Tamper and User buttons - - 4-direction control and selection joystick - - Board connectors: - - 5 V power jack - - RS-232 and RS485 communications - - Stereo audio jack including analog microphone input - - microSD card - - Extension I2C connector - - Motor-control connector - - Board extension connectors: - - Daughterboard connectors for legacy peripheral daughter board or - USB-C daughterboard - - Extension connectors for daughterboard or wire-wrap board - - Flexible power-supply options: - - 5 V power jack - - ST-LINK/V2-1 USB connector - - Daughterboard - - On-board ST-LINK/V2-1 debugger/programmer with USB re-enumeration - capability: mass storage, virtual COM port and debug port - - Legacy peripheral daughterboard - - IrDA transceiver - - IR LED and IR receiver - - Light dependent resistor (LDR) - - Temperature Sensor - - Board connectors: - - Two HDMI connectors with DDC and CEC - - Smart card slot - - USB-C and Power Delivery daughterboard - - Mux for USB3.1 Gen1 / DisplayPort input and Type-C port1 output - - Mux for Type-C port2 input and DisplayPort output / USB2.0 - - VCONN on Type-C port1 - - USB PD on Type-C port1 - - Board connectors: - - Type-C port1 DRP (dual-role port) - - Type-C port2 Sink - - DisplayPort input - - DisplayPort output - - USB 3.1 Gen1 Type-B receptacle - - USB2.0 Type-A receptacle - - 19 V power jack for USB PD +- STM32G081RBT6 microcontroller with 128 Kbytes of Flash memory and + 32 Kbytes of RAM in LQFP64 package +- MCU voltage choice fixed 3.3 V or adjustable from 1.65 V to 3.6 V +- I2C compatible serial interface +- RTC with backup battery +- 8-Gbyte or more SPI interface microSD card +- Potentiometer +- 4 color user LEDs and one LED as MCU low-power alarm +- Reset, Tamper and User buttons +- 4-direction control and selection joystick +- Board connectors + + - 5 V power jack + - RS-232 and RS485 communications + - Stereo audio jack including analog microphone input + - microSD card + - Extension I2C connector + - Motor-control connector + +- Board extension connectors: + + - Daughterboard connectors for legacy peripheral daughter board or + USB-C daughterboard + - Extension connectors for daughterboard or wire-wrap board + +- Flexible power-supply options: + + - 5 V power jack + - ST-LINK/V2-1 USB connector + - Daughterboard + +- On-board ST-LINK/V2-1 debugger/programmer with USB re-enumeration + capability: mass storage, virtual COM port and debug port +- Legacy peripheral daughterboard + + - IrDA transceiver + - IR LED and IR receiver + - Light dependent resistor (LDR) + - Temperature Sensor + - Board connectors + + - Two HDMI connectors with DDC and CEC + - Smart card slot + +- USB-C and Power Delivery daughterboard + + - Mux for USB3.1 Gen1 / DisplayPort input and Type-C port1 output + - Mux for Type-C port2 input and DisplayPort output / USB2.0 + - VCONN on Type-C port1 + - USB PD on Type-C port1 + - Board connectors + + - Type-C port1 DRP (dual-role port) + - Type-C port2 Sink + - DisplayPort input + - DisplayPort output + - USB 3.1 Gen1 Type-B receptacle + - USB2.0 Type-A receptacle + - 19 V power jack for USB PD More information about the board can be found at the `STM32G081B-EVAL website`_. - More information about STM32G081RB can be found here: - `G081RB on www.st.com`_ diff --git a/boards/st/stm32h7b3i_dk/doc/index.rst b/boards/st/stm32h7b3i_dk/doc/index.rst index 13fb0eeea67f..4e9dbe69d11c 100644 --- a/boards/st/stm32h7b3i_dk/doc/index.rst +++ b/boards/st/stm32h7b3i_dk/doc/index.rst @@ -31,20 +31,24 @@ Important board features include: - User and Reset push-buttons - Fanout daughterboard - 1x FDCAN -- Board connectors: - - Camera (8 bit) - - USB with Micro-AB - - Stereo headset jack including analog microphone input - - Audio jack for external speakers - - microSD |trade| card - - TAG-Connect 10-pin footprint - - Arm |reg| Cortex |reg| 10-pin 1.27mm-pitch debug connector over STDC14 footprint - - ARDUINO |reg| Uno V3 expansion connector - - STMod+ expansion connector - - Audio daughterboard expansion connector - - External I2C expansion connector +- Board connectors + + - Camera (8 bit) + - USB with Micro-AB + - Stereo headset jack including analog microphone input + - Audio jack for external speakers + - microSD |trade| card + - TAG-Connect 10-pin footprint + - Arm |reg| Cortex |reg| 10-pin 1.27mm-pitch debug connector over STDC14 footprint + - ARDUINO |reg| Uno V3 expansion connector + - STMod+ expansion connector + - Audio daughterboard expansion connector + - External I2C expansion connector + - Flexible power-supply options: - - ST-LINK USB VBUS, USB OTG HS connector, or external sources + + - ST-LINK USB VBUS, USB OTG HS connector, or external sources + - On-board STLINK-V3E debugger/programmer with USB re-enumeration capability More information about the board can be found at the `STM32H7B3I-DK website`_. diff --git a/boards/st/stm32l476g_disco/doc/index.rst b/boards/st/stm32l476g_disco/doc/index.rst index 868590f70335..59267ad2d537 100644 --- a/boards/st/stm32l476g_disco/doc/index.rst +++ b/boards/st/stm32l476g_disco/doc/index.rst @@ -33,11 +33,12 @@ some highlights of the STM32L476G Discovery board: - 128-Mbit Quad-SPI Flash memory - MCU current ammeter with 4 ranges and auto-calibration - Connector for external board or RF-EEPROM -- Four power supply options: - - ST-LINK/V2-1 - - USB FS connector - - External 5 V - - CR2032 battery (not provided) +- Four power supply options + + - ST-LINK/V2-1 + - USB FS connector + - External 5 V + - CR2032 battery (not provided) More information about the board can be found at the `STM32L476G Discovery website`_. @@ -49,43 +50,53 @@ The STM32L476VG SoC provides the following hardware features: - Ultra-low-power with FlexPowerControl (down to 130 nA Standby mode and 100 uA/MHz run mode) - Core: ARM |reg| 32-bit Cortex |reg|-M4 CPU with FPU, frequency up to 80 MHz, 100DMIPS/1.25DMIPS/MHz (Dhrystone 2.1) - Clock Sources: - - 4 to 48 MHz crystal oscillator - - 32 kHz crystal oscillator for RTC (LSE) - - Internal 16 MHz factory-trimmed RC ( |plusminus| 1%) - - Internal low-power 32 kHz RC ( |plusminus| 5%) - - Internal multispeed 100 kHz to 48 MHz oscillator, auto-trimmed by - LSE (better than |plusminus| 0.25 % accuracy) - - 3 PLLs for system clock, USB, audio, ADC + + - 4 to 48 MHz crystal oscillator + - 32 kHz crystal oscillator for RTC (LSE) + - Internal 16 MHz factory-trimmed RC ( |plusminus| 1%) + - Internal low-power 32 kHz RC ( |plusminus| 5%) + - Internal multispeed 100 kHz to 48 MHz oscillator, auto-trimmed by + LSE (better than |plusminus| 0.25 % accuracy) + - 3 PLLs for system clock, USB, audio, ADC + - RTC with HW calendar, alarms and calibration - LCD 8 x 40 or 4 x 44 with step-up converter - Up to 24 capacitive sensing channels: support touchkey, linear and rotary touch sensors - 16x timers: - - 2x 16-bit advanced motor-control - - 2x 32-bit and 5x 16-bit general purpose - - 2x 16-bit basic - - 2x low-power 16-bit timers (available in Stop mode) - - 2x watchdogs - - SysTick timer + + - 2x 16-bit advanced motor-control + - 2x 32-bit and 5x 16-bit general purpose + - 2x 16-bit basic + - 2x low-power 16-bit timers (available in Stop mode) + - 2x watchdogs + - SysTick timer + - Up to 114 fast I/Os, most 5 V-tolerant, up to 14 I/Os with independent supply down to 1.08 V - Memories - - Up to 1 MB Flash, 2 banks read-while-write, proprietary code readout protection - - Up to 128 KB of SRAM including 32 KB with hardware parity check - - External memory interface for static memories supporting SRAM, PSRAM, NOR and NAND memories - - Quad SPI memory interface + + - Up to 1 MB Flash, 2 banks read-while-write, proprietary code readout protection + - Up to 128 KB of SRAM including 32 KB with hardware parity check + - External memory interface for static memories supporting SRAM, PSRAM, NOR and NAND memories + - Quad SPI memory interface + - 4x digital filters for sigma delta modulator - Rich analog peripherals (independent supply) - - 3x 12-bit ADC 5 MSPS, up to 16-bit with hardware oversampling, 200 uA/MSPS - - 2x 12-bit DAC, low-power sample and hold - - 2x operational amplifiers with built-in PGA - - 2x ultra-low-power comparators + + - 3x 12-bit ADC 5 MSPS, up to 16-bit with hardware oversampling, 200 uA/MSPS + - 2x 12-bit DAC, low-power sample and hold + - 2x operational amplifiers with built-in PGA + - 2x ultra-low-power comparators + - 18x communication interfaces - - USB OTG 2.0 full-speed, LPM and BCD - - 2x SAIs (serial audio interface) - - 3x I2C FM+(1 Mbit/s), SMBus/PMBus - - 6x USARTs (ISO 7816, LIN, IrDA, modem) - - 3x SPIs (4x SPIs with the Quad SPI) - - CAN (2.0B Active) and SDMMC interface - - SWPMI single wire protocol master I/F + + - USB OTG 2.0 full-speed, LPM and BCD + - 2x SAIs (serial audio interface) + - 3x I2C FM+(1 Mbit/s), SMBus/PMBus + - 6x USARTs (ISO 7816, LIN, IrDA, modem) + - 3x SPIs (4x SPIs with the Quad SPI) + - CAN (2.0B Active) and SDMMC interface + - SWPMI single wire protocol master I/F + - 14-channel DMA controller - True random number generator - CRC calculation unit, 96-bit unique ID @@ -93,8 +104,9 @@ The STM32L476VG SoC provides the following hardware features: More information about STM32L476VG can be found here: - - `STM32L476VG on www.st.com`_ - - `STM32L476 reference manual`_ + +- `STM32L476VG on www.st.com`_ +- `STM32L476 reference manual`_ Supported Features diff --git a/boards/ti/sk_am64/doc/index.rst b/boards/ti/sk_am64/doc/index.rst index c55ad7eb989c..299cea54f8f5 100644 --- a/boards/ti/sk_am64/doc/index.rst +++ b/boards/ti/sk_am64/doc/index.rst @@ -17,17 +17,20 @@ cluster and a single Cortex-M4 core in the MCU domain. Zephyr is ported to run o the M4F core and the following listed hardware specifications are used: - Low-power ARM Cortex-M4F - - 256KB of SRAM + + - 256KB of SRAM - 2x ARM Dual-Core Cortex-R5F - - 64KB of SRAM each + + - 64KB of SRAM each - Memory - - 2GB of DDR4 + + - 2GB of DDR4 - Debug - - XDS110 based JTAG + - XDS110 based JTAG Supported Features ================== diff --git a/boards/weact/mini_stm32h743/doc/index.rst b/boards/weact/mini_stm32h743/doc/index.rst index c1ca99c2ea8e..1dd09e943d26 100644 --- a/boards/weact/mini_stm32h743/doc/index.rst +++ b/boards/weact/mini_stm32h743/doc/index.rst @@ -16,13 +16,14 @@ Key Features - User, boot, and reset push-buttons - 32.768 kHz and 25MHz HSE crystal oscillators - External NOR Flash memories: 64-Mbit Quad-SPI and 64-Mbit SPI -- Board connectors: - - Camera (8 bit) connector - - ST7735 TFT-LCD 160 x 80 pixels (RGB565 3-SPI) - - microSD |trade| card - - USB Type-C Connector - - SWD header for external debugger - - 2x 40-pin GPIO connector +- Board connectors + + - Camera (8 bit) connector + - ST7735 TFT-LCD 160 x 80 pixels (RGB565 3-SPI) + - microSD |trade| card + - USB Type-C Connector + - SWD header for external debugger + - 2x 40-pin GPIO connector More information about the board can be found on the `Mini_STM32H743 website`_. diff --git a/doc/develop/toolchains/arm_toolchain_for_embedded.rst b/doc/develop/toolchains/arm_toolchain_for_embedded.rst index 838053e0094f..06ee40ef2361 100644 --- a/doc/develop/toolchains/arm_toolchain_for_embedded.rst +++ b/doc/develop/toolchains/arm_toolchain_for_embedded.rst @@ -61,7 +61,7 @@ Installation #. You can also set ``ZEPHYR_TOOLCHAIN_VARIANT`` and ``LLVM_TOOLCHAIN_PATH`` as CMake variables when generating a build system for a Zephyr application, like so: - .. code-block:: console + .. code-block:: console west build ... -- -DZEPHYR_TOOLCHAIN_VARIANT=llvm -DLLVM_TOOLCHAIN_PATH=... @@ -69,16 +69,16 @@ Toolchain settings ****************** Because LLVM is widely compatible with GNU tools, When builiding with any - LLVM toolchain, you have to specify some settings to let the compiler - know what tools to use: +LLVM toolchain, you have to specify some settings to let the compiler +know what tools to use: -Linker: - Set :envvar:`CONFIG_LLVM_USE_LLD=y` to use LLVM linker. - set :envvar:`CONFIG_LLVM_USE_LD=y` to use the GNU LD linker. +Linker + * Set :envvar:`CONFIG_LLVM_USE_LLD=y` to use LLVM linker. + * Set :envvar:`CONFIG_LLVM_USE_LD=y` to use the GNU LD linker. -Runtime library: - Set :envvar:`CONFIG_COMPILER_RT_RTLIB=y` to use LLVM runtime library. - Set :envvar:`CONFIG_LIBGCC_RTLIB=y` to use LibGCC runtime library. +Runtime library + * Set :envvar:`CONFIG_COMPILER_RT_RTLIB=y` to use LLVM runtime library. + * Set :envvar:`CONFIG_LIBGCC_RTLIB=y` to use LibGCC runtime library. .. code-block:: console diff --git a/doc/develop/west/manifest.rst b/doc/develop/west/manifest.rst index f989cdcae1e2..c29f9d6e45a7 100644 --- a/doc/develop/west/manifest.rst +++ b/doc/develop/west/manifest.rst @@ -1258,21 +1258,28 @@ The ``import`` key can be a boolean, path, mapping, or sequence. We'll describe these in order, using examples: - :ref:`Boolean ` - - :ref:`west-manifest-ex1.1` - - :ref:`west-manifest-ex1.2` - - :ref:`west-manifest-ex1.3` + + - :ref:`west-manifest-ex1.1` + - :ref:`west-manifest-ex1.2` + - :ref:`west-manifest-ex1.3` + - :ref:`Relative path ` - - :ref:`west-manifest-ex2.1` - - :ref:`west-manifest-ex2.2` - - :ref:`west-manifest-ex2.3` + + - :ref:`west-manifest-ex2.1` + - :ref:`west-manifest-ex2.2` + - :ref:`west-manifest-ex2.3` + - :ref:`Mapping with additional configuration ` - - :ref:`west-manifest-ex3.1` - - :ref:`west-manifest-ex3.2` - - :ref:`west-manifest-ex3.3` - - :ref:`west-manifest-ex3.4` + + - :ref:`west-manifest-ex3.1` + - :ref:`west-manifest-ex3.2` + - :ref:`west-manifest-ex3.3` + - :ref:`west-manifest-ex3.4` + - :ref:`Sequence of paths and mappings ` - - :ref:`west-manifest-ex4.1` - - :ref:`west-manifest-ex4.2` + + - :ref:`west-manifest-ex4.1` + - :ref:`west-manifest-ex4.2` A more :ref:`formal description ` of how this works is last, after the examples. diff --git a/doc/kernel/object_cores/index.rst b/doc/kernel/object_cores/index.rst index ae28d33082c9..7d01900b8bed 100644 --- a/doc/kernel/object_cores/index.rst +++ b/doc/kernel/object_cores/index.rst @@ -22,18 +22,19 @@ linked together via a singly linked list. Together, this can allow debugging tools to traverse all the objects in the system. Object cores have been integrated into following kernel objects: - * :ref:`Condition Variables ` - * :ref:`Events ` - * :ref:`FIFOs ` and :ref:`LIFOs ` - * :ref:`Mailboxes ` - * :ref:`Memory Slabs ` - * :ref:`Message Queues ` - * :ref:`Mutexes ` - * :ref:`Pipes ` - * :ref:`Semaphores ` - * :ref:`Threads ` - * :ref:`Timers ` - * :ref:`System Memory Blocks ` + +* :ref:`Condition Variables ` +* :ref:`Events ` +* :ref:`FIFOs ` and :ref:`LIFOs ` +* :ref:`Mailboxes ` +* :ref:`Memory Slabs ` +* :ref:`Message Queues ` +* :ref:`Mutexes ` +* :ref:`Pipes ` +* :ref:`Semaphores ` +* :ref:`Threads ` +* :ref:`Timers ` +* :ref:`System Memory Blocks ` Developers are free to integrate them if desired into other objects within their projects. diff --git a/doc/kernel/usermode/overview.rst b/doc/kernel/usermode/overview.rst index 2af3d5d54556..4f5ed3d008b6 100644 --- a/doc/kernel/usermode/overview.rst +++ b/doc/kernel/usermode/overview.rst @@ -51,10 +51,10 @@ For threads running in a non-privileged CPU state (hereafter referred to as - A user thread may have read/write access to the stacks of other user threads in the same memory domain, depending on hardware. - - On MPU systems, threads may only access their own stack buffer. + - On MPU systems, threads may only access their own stack buffer. - - On MMU systems, threads may access any user thread stack in the same - memory domain. Portable code should not assume this. + - On MMU systems, threads may access any user thread stack in the same + memory domain. Portable code should not assume this. - By default, program text and read-only data are accessible to all threads on read-only basis, kernel-wide. This policy may be adjusted. diff --git a/doc/services/sensing/index.rst b/doc/services/sensing/index.rst index db661c31a3c6..a31ebb9524ee 100644 --- a/doc/services/sensing/index.rst +++ b/doc/services/sensing/index.rst @@ -64,25 +64,27 @@ Configurability Main Features ************* -* Scope - * Focus on framework for sensor fusion, multiple clients, arbitration, data sampling, timing - management and scheduling. +Scope + Focus on framework for sensor fusion, multiple clients, arbitration, data sampling, timing + management and scheduling. -* Sensor Abstraction - * ``Physical sensor``: interacts with Zephyr sensor device drivers, focus on data collecting. - * ``Virtual sensor``: relies on other sensor(s), ``physical`` or ``virtual``, focus on - data fusion. +Sensor Abstraction + * **Physical sensor**: interacts with Zephyr sensor device drivers, focus on data collecting. + * **Virtual sensor**: relies on other sensor(s), **physical** or **virtual**, focus on + data fusion. -* Data Driven Model - * ``Polling mode``: periodical sampling rate - * ``Interrupt mode``: data ready, threshold interrupt etc. +Data Driven Model + * **Polling mode**: periodical sampling rate + * **Interrupt mode**: data ready, threshold interrupt etc. -* Scheduling - * single thread main loop for all sensor objects sampling and process. +Scheduling + Single thread main loop for all sensor objects sampling and process. -* Buffer Mode for Batching +Buffer Mode for Batching + .. -* Configurable Via Device Tree +Configurable Via Devicetree + .. Below diagram shows the API position and scope: diff --git a/doc/services/smf/index.rst b/doc/services/smf/index.rst index eb0de648902a..2a502486c0af 100644 --- a/doc/services/smf/index.rst +++ b/doc/services/smf/index.rst @@ -396,20 +396,21 @@ Code:: } When designing hierarchical state machines, the following should be considered: - - Ancestor entry actions are executed before the sibling entry actions. For - example, the parent_entry function is called before the s0_entry function. - - Transitioning from one sibling to another with a shared ancestry does not - re-execute the ancestor\'s entry action or execute the exit action. - For example, the parent_entry function is not called when transitioning - from S0 to S1, nor is the parent_exit function called. - - Ancestor exit actions are executed after the exit action of the current - state. For example, the s1_exit function is called before the parent_exit - function is called. - - The parent_run function only executes if the child_run function does not - call either :c:func:`smf_set_state` or return :c:enum:`SMF_EVENT_HANDLED`. - - Avoid malformed hierarchical state machines by ensuring the state always - transitions to a leaf state when :kconfig:option:`CONFIG_SMF_INITIAL_TRANSITION` - is not enabled, or when a parent state's initial state is undefined. + +- Ancestor entry actions are executed before the sibling entry actions. For + example, the parent_entry function is called before the s0_entry function. +- Transitioning from one sibling to another with a shared ancestry does not + re-execute the ancestor\'s entry action or execute the exit action. + For example, the parent_entry function is not called when transitioning + from S0 to S1, nor is the parent_exit function called. +- Ancestor exit actions are executed after the exit action of the current + state. For example, the s1_exit function is called before the parent_exit + function is called. +- The parent_run function only executes if the child_run function does not + call either :c:func:`smf_set_state` or return :c:enum:`SMF_EVENT_HANDLED`. +- Avoid malformed hierarchical state machines by ensuring the state always + transitions to a leaf state when :kconfig:option:`CONFIG_SMF_INITIAL_TRANSITION` + is not enabled, or when a parent state's initial state is undefined. Event Driven State Machine Example ********************************** diff --git a/samples/modules/lvgl/demos/README.rst b/samples/modules/lvgl/demos/README.rst index 0f7ef9e241dc..a2279aa240dd 100644 --- a/samples/modules/lvgl/demos/README.rst +++ b/samples/modules/lvgl/demos/README.rst @@ -9,18 +9,18 @@ Overview A sample showcasing upstream LVGL demos. -* Music - The music player demo shows what kind of modern, smartphone-like user interfaces can be created on LVGL. -* Benchmark - The benchmark demo tests the performance in various cases. For example rectangle, border, shadow, text, image blending, image transformation, blending modes, etc. -* Stress - A stress test for LVGL. It contains a lot of object creation, deletion, animations, styles usage, and so on. It can be used if there is any memory corruption during heavy usage or any memory leaks. -* Widgets - Shows how the widgets look like out of the box using the built-in material theme. -* Keypad and Encoder - Shows how to control widget with a keypad and hardware encoder. -* Render - Collection of multiple rendering tests. +Music + The music player demo shows what kind of modern, smartphone-like user interfaces can be created on LVGL. +Benchmark + The benchmark demo tests the performance in various cases. For example rectangle, border, shadow, text, image blending, image transformation, blending modes, etc. +Stress + A stress test for LVGL. It contains a lot of object creation, deletion, animations, styles usage, and so on. It can be used if there is any memory corruption during heavy usage or any memory leaks. +Widgets + Shows how the widgets look like out of the box using the built-in material theme. +Keypad and Encoder + Shows how to control widget with a keypad and hardware encoder. +Render + Collection of multiple rendering tests. More details can be found in `LVGL demos Readme`_. diff --git a/samples/modules/lvgl/multi_display/README.rst b/samples/modules/lvgl/multi_display/README.rst index 614bd6ece8fc..fd2760663747 100644 --- a/samples/modules/lvgl/multi_display/README.rst +++ b/samples/modules/lvgl/multi_display/README.rst @@ -14,18 +14,18 @@ By default, it runs the Music demo on the first display, and the Widgets demo on Which demos are run can be changed by modifying the value of CONFIG_LV_Z_DEMO_FIRST_DISP## and CONFIG_LV_Z_DEMO_OTHER_DISPS## Kconfig symbols. -* Music - The music player demo shows what kind of modern, smartphone-like user interfaces can be - created on LVGL. -* Benchmark - The benchmark demo tests the performance in various cases. For example rectangle, border, - shadow, text, image blending, image transformation, blending modes, etc. -* Stress - A stress test for LVGL. It contains a lot of object creation, deletion, animations, styles - usage, and so on. It can be used if there is any memory corruption during heavy usage or any - memory leaks. -* Widgets - Shows how the widgets look like out of the box using the built-in material theme. +Music + The music player demo shows what kind of modern, smartphone-like user interfaces can be + created on LVGL. +Benchmark + The benchmark demo tests the performance in various cases. For example rectangle, border, + shadow, text, image blending, image transformation, blending modes, etc. +Stress + A stress test for LVGL. It contains a lot of object creation, deletion, animations, styles + usage, and so on. It can be used if there is any memory corruption during heavy usage or any + memory leaks. +Widgets + Shows how the widgets look like out of the box using the built-in material theme. More details on the demos can be found in `LVGL demos Readme`_. diff --git a/samples/net/openthread/coprocessor/README.rst b/samples/net/openthread/coprocessor/README.rst index 9fa548201af7..aa35c4fee241 100644 --- a/samples/net/openthread/coprocessor/README.rst +++ b/samples/net/openthread/coprocessor/README.rst @@ -55,16 +55,16 @@ Example building for the nrf52840dk/nrf52840 for RCP: There are configuration files for different boards and setups in the coprocessor directory: -- :file:`prj.conf` - Generic NCP config file. Use this, if you want the NCP configuration. +:file:`prj.conf` + Generic NCP config file. Use this, if you want the NCP configuration. -- :file:`overlay-rcp.conf` +:file:`overlay-rcp.conf` RCP overlay file. Use this in combination with prj.conf, if you want the RCP configuration. -- :file:`overlay-tri-n4m-br.conf` - This is an overlay for the dedicated Thread Border Router hardware - https://www.tridonic.com/com/en/download/data_sheets/net4more_Borderrouter_PoE-Thread_en.pdf. - The board support is not part of the Zephyr repositories, but the - product is based on NXP K64 and AT86RF233. This file can be used as an - example for a development set-up based on development boards. +:file:`overlay-tri-n4m-br.conf` + This is an overlay for the dedicated Thread Border Router hardware + https://www.tridonic.com/com/en/download/data_sheets/net4more_Borderrouter_PoE-Thread_en.pdf. + The board support is not part of the Zephyr repositories, but the + product is based on NXP K64 and AT86RF233. This file can be used as an + example for a development set-up based on development boards. From fa352c30303be808cc105b51b4a202455519f8f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Tue, 16 Dec 2025 20:39:01 +0100 Subject: [PATCH 0668/3659] doc: twister: keep definition lists uninterrupted MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move reference labels within definitions so that they do not break the flow of definition lists. Signed-off-by: Benjamin Cabé --- doc/develop/test/twister.rst | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/doc/develop/test/twister.rst b/doc/develop/test/twister.rst index 6a6eeadf1c23..dc1a59ff5373 100644 --- a/doc/develop/test/twister.rst +++ b/doc/develop/test/twister.rst @@ -202,7 +202,7 @@ testing: testing relating keywords to provide best coverage for the features of this board. -.. _twister_default_testing_board: + .. _twister_default_testing_board: binaries: A list of custom binaries to be kept for device testing. @@ -215,10 +215,9 @@ testing: tags. only_tags: Only execute tests with this list of tags on a specific platform. - - .. _twister_board_timeout_multiplier: - timeout_multiplier: (default 1) + .. _twister_board_timeout_multiplier: + Multiply each test scenario timeout by specified ratio. This option allows to tune timeouts only for required platform. It can be useful in case naturally slow platform I.e.: HW board with power-efficient but slow CPU or simulation platform which can perform instruction accurate From acbad46c1b686f30251058a3f6a176ecfa210502 Mon Sep 17 00:00:00 2001 From: Bill Waters Date: Tue, 16 Dec 2025 11:40:05 -0800 Subject: [PATCH 0669/3659] modules: hal_infineon: CMakeLists.txt - Only compile the mtb-hal-cat1 module's source when CONFIG_USE_INFINEON_LEGACY_HAL is set. - The serial-flash sub-module relies on the legacy hal. It was getting added to all builds, including ones that don't use the legacy hal. Signed-off-by: Bill Waters --- modules/hal_infineon/CMakeLists.txt | 9 +++++---- modules/hal_infineon/serial-flash/CMakeLists.txt | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/modules/hal_infineon/CMakeLists.txt b/modules/hal_infineon/CMakeLists.txt index 397b72c51c13..c3071524e6fc 100644 --- a/modules/hal_infineon/CMakeLists.txt +++ b/modules/hal_infineon/CMakeLists.txt @@ -35,13 +35,15 @@ if(CONFIG_SOC_FAMILY_INFINEON_CAT1 add_subdirectory(mtb-template-cat1) endif() +if(CONFIG_USE_INFINEON_LEGACY_HAL + AND NOT CONFIG_SOC_FAMILY_PSOC6_LEGACY) + add_subdirectory(mtb-hal-cat1) +endif() + if(CONFIG_SOC_FAMILY_INFINEON_CAT1 AND NOT CONFIG_SOC_FAMILY_PSOC6_LEGACY AND NOT CONFIG_SOC_FAMILY_INFINEON_EDGE) - ## Add mtb-hal-cat1 sources for CAT1 devices - add_subdirectory(mtb-hal-cat1) - ## Add catcm0p sleep images for CM0 Devices if(CONFIG_SOC_PSOC6_CM0P_IMAGE_SLEEP) add_subdirectory(cat1cm0p) @@ -51,7 +53,6 @@ if(CONFIG_SOC_FAMILY_INFINEON_CAT1 add_subdirectory(abstraction-rtos) add_subdirectory(serial-flash) - endif() if(CONFIG_SOC_FAMILY_INFINEON_EDGE) diff --git a/modules/hal_infineon/serial-flash/CMakeLists.txt b/modules/hal_infineon/serial-flash/CMakeLists.txt index 49ef6358f2d9..b6ce3bf9129c 100644 --- a/modules/hal_infineon/serial-flash/CMakeLists.txt +++ b/modules/hal_infineon/serial-flash/CMakeLists.txt @@ -7,4 +7,4 @@ set(serial_flash_dir ${ZEPHYR_HAL_INFINEON_MODULE_DIR}/serial-flash) zephyr_include_directories(${serial_flash_dir}) -zephyr_library_sources(${serial_flash_dir}/cy_serial_flash_qspi.c) +zephyr_library_sources_ifdef(CONFIG_USE_INFINEON_SMIF ${serial_flash_dir}/cy_serial_flash_qspi.c) From ecd8a4bc7cf7926877807b130c4d975d44b03545 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Tue, 16 Dec 2025 19:41:44 +0000 Subject: [PATCH 0670/3659] cmake: modules: hwm_v2: Skip writing output on no change Skips updating files if the output already matches the file contents, this prevents a random occurance whereby sysbuild reconfigures itself after a reconfiguration for no known discernable reason Signed-off-by: Jamie McCrae --- cmake/modules/hwm_v2.cmake | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/cmake/modules/hwm_v2.cmake b/cmake/modules/hwm_v2.cmake index 41e0dec4d2fe..1cce62763b49 100644 --- a/cmake/modules/hwm_v2.cmake +++ b/cmake/modules/hwm_v2.cmake @@ -21,14 +21,16 @@ include_guard(GLOBAL) # Internal helper function for creation of Kconfig files. function(kconfig_gen bin_dir file dirs comment) - set(kconfig_header "# Load ${comment} descriptions.\n") + set(kconfig_output "# Load ${comment} descriptions.\n") set(kconfig_file ${KCONFIG_BINARY_DIR}/${bin_dir}/${file}) - file(WRITE ${kconfig_file} "${kconfig_header}") foreach(dir ${dirs}) cmake_path(CONVERT "${dir}" TO_CMAKE_PATH_LIST dir) - file(APPEND ${kconfig_file} "osource \"${dir}/${file}\"\n") + string(APPEND kconfig_output "osource \"${dir}/${file}\"\n") endforeach() + + file(WRITE ${kconfig_file}.tmp "${kconfig_output}") + file(COPY_FILE ${kconfig_file}.tmp ${kconfig_file} ONLY_IF_DIFFERENT) endfunction() # 'SOC_ROOT' and 'ARCH_ROOT' are prioritized lists of directories where their From e157c16fabaec53c6cc4fd6eed467937b4135298 Mon Sep 17 00:00:00 2001 From: Dima Kushchevskyi Date: Fri, 10 Oct 2025 02:44:15 +0300 Subject: [PATCH 0671/3659] tests: bluetooth: ascs: make callback expectation checks more generic The existing ASCS test callback verification functions scale poorly and are not easily reusable across different cases. This change introduces a more generic approach to expectation checks by adding `expect_bt_bap_unicast_server_cb_release_called(_expected_count, _streams)` and similar functions, improving readability and maintainability of ASCS unit tests. Fixes #58034 Signed-off-by: Dima Kushchevskyi --- .../ascs/include/bap_unicast_server_expects.h | 366 ++++++++++-------- tests/bluetooth/audio/ascs/src/main.c | 62 +-- .../ascs/src/test_ase_state_transition.c | 345 +++++++++-------- .../audio/mocks/include/bap_stream_expects.h | 278 ++++++------- 4 files changed, 532 insertions(+), 519 deletions(-) diff --git a/tests/bluetooth/audio/ascs/include/bap_unicast_server_expects.h b/tests/bluetooth/audio/ascs/include/bap_unicast_server_expects.h index 7fc479432ae2..6423022020e9 100644 --- a/tests/bluetooth/audio/ascs/include/bap_unicast_server_expects.h +++ b/tests/bluetooth/audio/ascs/include/bap_unicast_server_expects.h @@ -13,180 +13,204 @@ #include "bap_unicast_server.h" #include "expects_util.h" -#define expect_bt_bap_unicast_server_cb_config_called_once(_conn, _ep, _dir, _codec) \ -do { \ - const char *func_name = "bt_bap_unicast_server_cb.config"; \ - \ - zexpect_call_count(func_name, 1, mock_bap_unicast_server_cb_config_fake.call_count); \ - \ - IF_NOT_EMPTY(_conn, ( \ - zassert_equal_ptr(_conn, mock_bap_unicast_server_cb_config_fake.arg0_val, \ - "'%s()' was called with incorrect '%s' value", \ - func_name, "conn");)) \ - \ - IF_NOT_EMPTY(_ep, ( \ - zassert_equal_ptr(_ep, mock_bap_unicast_server_cb_config_fake.arg1_val, \ - "'%s()' was called with incorrect '%s' value", \ - func_name, "ep");)) \ - \ - IF_NOT_EMPTY(_dir, ( \ - zassert_equal(_dir, mock_bap_unicast_server_cb_config_fake.arg2_val, \ - "'%s()' was called with incorrect '%s' value", \ - func_name, "_dir");)) \ - \ - IF_NOT_EMPTY(_codec, ( \ - /* TODO */ \ - zassert_unreachable("Not implemented");)) \ -} while (0) - -#define expect_bt_bap_unicast_server_cb_reconfig_called_once(_stream, _dir, _codec) \ -do { \ - const char *func_name = "bt_bap_unicast_server_cb.reconfig"; \ - \ - zexpect_call_count(func_name, 1, mock_bap_unicast_server_cb_reconfig_fake.call_count); \ - \ - IF_NOT_EMPTY(_stream, ( \ - zassert_equal_ptr(_stream, mock_bap_unicast_server_cb_reconfig_fake.arg0_val, \ - "'%s()' was called with incorrect '%s' value", \ - func_name, "stream");)) \ - \ - IF_NOT_EMPTY(_dir, ( \ - zassert_equal(_dir, mock_bap_unicast_server_cb_reconfig_fake.arg1_val, \ - "'%s()' was called with incorrect '%s' value", \ - func_name, "_dir");)) \ - \ - IF_NOT_EMPTY(_codec, ( \ - /* TODO */ \ - zassert_unreachable("Not implemented");)) \ -} while (0) - -#define expect_bt_bap_unicast_server_cb_qos_called_once(_stream, _qos) \ -do { \ - const char *func_name = "bt_bap_unicast_server_cb.qos"; \ - \ - zexpect_call_count(func_name, 1, mock_bap_unicast_server_cb_qos_fake.call_count); \ - \ - IF_NOT_EMPTY(_stream, ( \ - zassert_equal_ptr(_stream, mock_bap_unicast_server_cb_qos_fake.arg0_val, \ - "'%s()' was called with incorrect '%s' value", \ - func_name, "stream");)) \ - \ - IF_NOT_EMPTY(_qos, ( \ - /* TODO */ \ - zassert_unreachable("Not implemented");)) \ -} while (0) - -#define expect_bt_bap_unicast_server_cb_enable_called_once(_stream, _meta, _meta_len) \ -do { \ - const char *func_name = "bt_bap_unicast_server_cb.enable"; \ - \ - zexpect_call_count(func_name, 1, mock_bap_unicast_server_cb_enable_fake.call_count); \ - \ - IF_NOT_EMPTY(_stream, ( \ - zassert_equal_ptr(_stream, mock_bap_unicast_server_cb_enable_fake.arg0_val, \ - "'%s()' was called with incorrect '%s' value", \ - func_name, "stream");)) \ - \ - IF_NOT_EMPTY(_meta, ( \ - /* TODO */ \ - zassert_unreachable("Not implemented");)) \ - \ - IF_NOT_EMPTY(_meta_len, ( \ - /* TODO */ \ - zassert_unreachable("Not implemented");)) \ -} while (0) - -#define expect_bt_bap_unicast_server_cb_metadata_called_once(_stream, _meta, _meta_len) \ -do { \ - const char *func_name = "bt_bap_unicast_server_cb.enable"; \ - \ - zexpect_call_count(func_name, 1, mock_bap_unicast_server_cb_metadata_fake.call_count); \ - \ - IF_NOT_EMPTY(_stream, ( \ - zassert_equal_ptr(_stream, mock_bap_unicast_server_cb_metadata_fake.arg0_val, \ - "'%s()' was called with incorrect '%s' value", \ - func_name, "stream");)) \ - \ - IF_NOT_EMPTY(_meta, ( \ - /* TODO */ \ - zassert_unreachable("Not implemented");)) \ - \ - IF_NOT_EMPTY(_meta_len, ( \ - /* TODO */ \ - zassert_unreachable("Not implemented");)) \ -} while (0) - -#define expect_bt_bap_unicast_server_cb_disable_called_once(_stream) \ -do { \ - const char *func_name = "bt_bap_unicast_server_cb.disable"; \ - \ - zexpect_call_count(func_name, 1, mock_bap_unicast_server_cb_disable_fake.call_count); \ - \ - IF_NOT_EMPTY(_stream, ( \ - zassert_equal_ptr(_stream, mock_bap_unicast_server_cb_disable_fake.arg0_val, \ - "'%s()' was called with incorrect '%s' value", \ - func_name, "stream");)) \ -} while (0) - -#define expect_bt_bap_unicast_server_cb_release_called_once(_stream) \ -do { \ - const char *func_name = "bt_bap_unicast_server_cb.release"; \ - \ - zexpect_call_count(func_name, 1, mock_bap_unicast_server_cb_release_fake.call_count); \ - \ - IF_NOT_EMPTY(_stream, ( \ - zassert_equal_ptr(_stream, mock_bap_unicast_server_cb_release_fake.arg0_val, \ - "'%s()' was called with incorrect '%s' value", \ - func_name, "stream");)) \ -} while (0) - -#define expect_bt_bap_unicast_server_cb_release_called_twice(_streams) \ -do { \ - const char *func_name = "bt_bap_unicast_server_cb.release"; \ - \ - zexpect_call_count(func_name, 2, mock_bap_unicast_server_cb_release_fake.call_count); \ - \ - IF_NOT_EMPTY(_stream[0], ( \ - zassert_equal_ptr(_streams[0], \ - mock_bap_unicast_server_cb_release_fake.arg0_history[0], \ - "'%s()' was called with incorrect '%s' value", \ - func_name, "stream[0]");)) \ - IF_NOT_EMPTY(_stream[1], ( \ - zassert_equal_ptr(_streams[1], \ - mock_bap_unicast_server_cb_release_fake.arg0_history[1], \ - "'%s()' was called with incorrect '%s' value", \ - func_name, "stream[1]");)) \ -} while (0) - -#define expect_bt_bap_unicast_server_cb_start_called_once(_stream) \ -do { \ - const char *func_name = "bt_bap_unicast_server_cb.start"; \ - \ - zexpect_call_count(func_name, 1, mock_bap_unicast_server_cb_start_fake.call_count); \ - \ - IF_NOT_EMPTY(_stream, ( \ - zassert_equal_ptr(_stream, mock_bap_unicast_server_cb_start_fake.arg0_val, \ - "'%s()' was called with incorrect '%s' value", \ - func_name, "stream");)) \ -} while (0) - -#define expect_bt_bap_unicast_server_cb_stop_called_once(_stream) \ -do { \ - const char *func_name = "bt_bap_unicast_server_cb.stop"; \ - \ - zexpect_call_count(func_name, 1, mock_bap_unicast_server_cb_stop_fake.call_count); \ - \ - IF_NOT_EMPTY(_stream, ( \ - zassert_equal_ptr(_stream, mock_bap_unicast_server_cb_stop_fake.arg0_val, \ - "'%s()' was called with incorrect '%s' value", \ - func_name, "stream");)) \ -} while (0) - -static inline void expect_bt_bap_unicast_server_cb_config_not_called(void) +static inline void expect_bt_bap_unicast_server_cb_config_called( + unsigned int expected_count, + struct bt_conn *conns[], + struct bt_bap_ep *eps[], + enum bt_audio_dir dirs[], + void *codec[]) { const char *func_name = "bt_bap_unicast_server_cb.config"; - zexpect_call_count(func_name, 0, mock_bap_unicast_server_cb_config_fake.call_count); + zexpect_call_count(func_name, + expected_count, mock_bap_unicast_server_cb_config_fake.call_count); + + for (unsigned int i = 0; i < mock_bap_unicast_server_cb_config_fake.call_count; i++) { + zassert_equal_ptr(conns[i], + mock_bap_unicast_server_cb_config_fake.arg0_history[i], + "'%s()' was called with incorrect 'conn[%i]' value", func_name, i); + if (eps) { + zassert_equal_ptr(eps[i], + mock_bap_unicast_server_cb_config_fake.arg1_history[i], + "'%s()' was called with incorrect 'ep[%i]' value", func_name, i); + } + zassert_equal(dirs[i], + mock_bap_unicast_server_cb_config_fake.arg2_history[i], + "'%s()' was called with incorrect 'dir[%i]' value", func_name, i); + } + + if (codec) { + /* TODO */ + zassert_unreachable("Not implemented"); + } +} + +static inline void expect_bt_bap_unicast_server_cb_reconfig_called( + unsigned int expected_count, + struct bt_bap_stream *streams[], + const enum bt_audio_dir dirs[], + void *codec[]) +{ + const char *func_name = "bt_bap_unicast_server_cb.reconfig"; + + zexpect_call_count(func_name, + expected_count, mock_bap_unicast_server_cb_reconfig_fake.call_count); + + for (unsigned int i = 0; i < mock_bap_unicast_server_cb_reconfig_fake.call_count; i++) { + zassert_equal_ptr(streams[i], + mock_bap_unicast_server_cb_reconfig_fake.arg0_history[i], + "'%s()' was called with incorrect 'stream[%i]' value", func_name, i); + zassert_equal(dirs[i], + mock_bap_unicast_server_cb_reconfig_fake.arg1_history[i], + "'%s()' was called with incorrect 'dir[%i]' value", func_name, i); + } + + if (codec) { + /* TODO */ + zassert_unreachable("Not implemented"); + } +} + +static inline void expect_bt_bap_unicast_server_cb_qos_called( + unsigned int expected_count, + struct bt_bap_stream *streams[], + void *qos[]) +{ + const char *func_name = "bt_bap_unicast_server_cb.qos"; + + zexpect_call_count(func_name, + expected_count, mock_bap_unicast_server_cb_qos_fake.call_count); + + for (unsigned int i = 0; i < mock_bap_unicast_server_cb_qos_fake.call_count; i++) { + zassert_equal_ptr(streams[i], + mock_bap_unicast_server_cb_qos_fake.arg0_history[i], + "'%s()' was called with incorrect 'stream[%i]' value", func_name, i); + } + + if (qos) { + /* TODO */ + zassert_unreachable("Not implemented"); + } +} + +static inline void expect_bt_bap_unicast_server_cb_enable_called( + unsigned int expected_count, + struct bt_bap_stream *streams[], + void *meta[], + void *meta_len[]) +{ + const char *func_name = "bt_bap_unicast_server_cb.enable"; + + zexpect_call_count(func_name, + expected_count, mock_bap_unicast_server_cb_enable_fake.call_count); + + for (unsigned int i = 0; i < mock_bap_unicast_server_cb_enable_fake.call_count; i++) { + zassert_equal_ptr(streams[i], + mock_bap_unicast_server_cb_enable_fake.arg0_history[i], + "'%s()' was called with incorrect 'stream[%i]' value", func_name, i); + } + + if (meta) { + /* TODO */ + zassert_unreachable("Not implemented"); + } + + if (meta_len) { + /* TODO */ + zassert_unreachable("Not implemented"); + } +} + +static inline void expect_bt_bap_unicast_server_cb_metadata_called( + unsigned int expected_count, + struct bt_bap_stream *streams[], + void *meta[], + void *meta_len[]) +{ + const char *func_name = "bt_bap_unicast_server_cb.enable"; + + zexpect_call_count(func_name, + expected_count, mock_bap_unicast_server_cb_metadata_fake.call_count); + + for (unsigned int i = 0; i < mock_bap_unicast_server_cb_metadata_fake.call_count; i++) { + zassert_equal_ptr(streams[i], + mock_bap_unicast_server_cb_metadata_fake.arg0_history[i], + "'%s()' was called with incorrect 'stream[%i]' value", func_name, i); + } + + if (meta) { + /* TODO */ + zassert_unreachable("Not implemented"); + } + + if (meta_len) { + /* TODO */ + zassert_unreachable("Not implemented"); + } +} + +static inline void expect_bt_bap_unicast_server_cb_disable_called( + unsigned int expected_count, + struct bt_bap_stream *streams[]) +{ + const char *func_name = "bt_bap_unicast_server_cb.disable"; + + zexpect_call_count(func_name, + expected_count, mock_bap_unicast_server_cb_disable_fake.call_count); + + for (unsigned int i = 0; i < mock_bap_unicast_server_cb_disable_fake.call_count; i++) { + zassert_equal_ptr(streams[i], + mock_bap_unicast_server_cb_disable_fake.arg0_history[i], + "'%s()' was called with incorrect 'stream[%i]' value", func_name, i); + } +} + +static inline void expect_bt_bap_unicast_server_cb_release_called( + unsigned int expected_count, + struct bt_bap_stream *streams[]) +{ + const char *func_name = "bt_bap_unicast_server_cb.release"; + + zexpect_call_count(func_name, + expected_count, mock_bap_unicast_server_cb_release_fake.call_count); + + for (unsigned int i = 0; i < mock_bap_unicast_server_cb_release_fake.call_count; i++) { + zassert_equal_ptr(streams[i], + mock_bap_unicast_server_cb_release_fake.arg0_history[i], + "'%s()' was called with incorrect 'stream[%i]' value", func_name, i); + } +} + +static inline void expect_bt_bap_unicast_server_cb_start_called( + unsigned int expected_count, + struct bt_bap_stream *streams[]) +{ + const char *func_name = "bt_bap_unicast_server_cb.start"; + + zexpect_call_count(func_name, + expected_count, mock_bap_unicast_server_cb_start_fake.call_count); + + for (unsigned int i = 0; i < mock_bap_unicast_server_cb_start_fake.call_count; i++) { + zassert_equal_ptr(streams[i], + mock_bap_unicast_server_cb_start_fake.arg0_history[i], + "'%s()' was called with incorrect 'stream[%i]' value", func_name, i); + } +} + +static inline void expect_bt_bap_unicast_server_cb_stop_called( + unsigned int expected_count, + struct bt_bap_stream *streams[]) +{ + const char *func_name = "bt_bap_unicast_server_cb.stop"; + + zexpect_call_count(func_name, + expected_count, mock_bap_unicast_server_cb_stop_fake.call_count); + + for (unsigned int i = 0; i < mock_bap_unicast_server_cb_stop_fake.call_count; i++) { + zassert_equal_ptr(streams[i], + mock_bap_unicast_server_cb_stop_fake.arg0_history[i], + "'%s()' was called with incorrect 'stream[%i]' value", func_name, i); + } } #endif /* MOCKS_BAP_UNICAST_SERVER_EXPECTS_H_ */ diff --git a/tests/bluetooth/audio/ascs/src/main.c b/tests/bluetooth/audio/ascs/src/main.c index 6d1e9ca5ecde..73d81e27ef57 100644 --- a/tests/bluetooth/audio/ascs/src/main.c +++ b/tests/bluetooth/audio/ascs/src/main.c @@ -205,8 +205,8 @@ ZTEST_F(ascs_test_suite, test_release_ase_on_callback_unregister) test_drain_syswq(); /* Ensure that state transitions are completed */ /* Expected to notify the upper layers */ - expect_bt_bap_unicast_server_cb_release_called_once(stream); - expect_bt_bap_stream_ops_released_called_once(stream); + expect_bt_bap_unicast_server_cb_release_called(1, &stream); + expect_bt_bap_stream_ops_released_called(1, (const struct bt_bap_stream **)&stream); /* Expected to notify the client */ expect_bt_gatt_notify_cb_called_once(conn, ase->uuid, ase, EMPTY, sizeof(*hdr)); @@ -286,7 +286,7 @@ ZTEST_F(ascs_test_suite, test_release_ase_on_acl_disconnection) mock_bt_conn_disconnected(conn, BT_HCI_ERR_CONN_TIMEOUT); /* Expected to notify the upper layers */ - expect_bt_bap_stream_ops_released_called_once(stream); + expect_bt_bap_stream_ops_released_called(1, (const struct bt_bap_stream **)&stream); /* Mock CIS disconnection */ mock_bt_iso_disconnected(chan, BT_HCI_ERR_CONN_TIMEOUT); @@ -344,9 +344,9 @@ ZTEST_F(ascs_test_suite, test_release_ase_pair_on_acl_disconnection) mock_bt_conn_disconnected(conn, BT_HCI_ERR_CONN_TIMEOUT); /* Expected to notify the upper layers */ - const struct bt_bap_stream *streams[2] = { &snk_stream, &src_stream }; + const struct bt_bap_stream *streams[] = { &snk_stream, &src_stream }; - expect_bt_bap_stream_ops_released_called(streams, 2); + expect_bt_bap_stream_ops_released_called(ARRAY_SIZE(streams), streams); /* Mock CIS disconnection */ mock_bt_iso_disconnected(chan, BT_HCI_ERR_CONN_TIMEOUT); @@ -375,7 +375,7 @@ ZTEST_F(ascs_test_suite, test_recv_in_streaming_state) chan->ops->recv(chan, &info, &buf); /* Verification */ - expect_bt_bap_stream_ops_recv_called_once(stream, &info, &buf); + expect_bt_bap_stream_ops_recv_called(1, &stream, &info, &buf); } ZTEST_F(ascs_test_suite, test_recv_in_enabling_state) @@ -406,7 +406,7 @@ ZTEST_F(ascs_test_suite, test_recv_in_enabling_state) chan->ops->recv(chan, &info, &buf); /* Verification */ - expect_bt_bap_stream_ops_recv_not_called(); + expect_bt_bap_stream_ops_recv_called(0, NULL, NULL, NULL); } ZTEST_F(ascs_test_suite, test_cis_link_loss_in_streaming_state) @@ -440,10 +440,10 @@ ZTEST_F(ascs_test_suite, test_cis_link_loss_in_streaming_state) test_drain_syswq(); /* Ensure that state transitions are completed */ /* Expected to notify the upper layers */ - expect_bt_bap_stream_ops_qos_set_called_once(stream); - expect_bt_bap_stream_ops_disabled_called_once(stream); - expect_bt_bap_stream_ops_released_not_called(); - expect_bt_bap_stream_ops_disconnected_called_once(stream); + expect_bt_bap_stream_ops_qos_set_called(1, &stream); + expect_bt_bap_stream_ops_disabled_called(1, &stream); + expect_bt_bap_stream_ops_released_called(0, NULL); + expect_bt_bap_stream_ops_disconnected_called(1, (const struct bt_bap_stream **)&stream); } static void test_cis_link_loss_in_disabling_state(struct ascs_test_suite_fixture *fixture, @@ -476,7 +476,7 @@ static void test_cis_link_loss_in_disabling_state(struct ascs_test_suite_fixture test_ase_control_client_disable(conn, ase_id); - expect_bt_bap_stream_ops_disabled_called_once(stream); + expect_bt_bap_stream_ops_disabled_called(1, &stream); test_mocks_reset(); @@ -486,10 +486,10 @@ static void test_cis_link_loss_in_disabling_state(struct ascs_test_suite_fixture test_drain_syswq(); /* Ensure that state transitions are completed */ /* Expected to notify the upper layers */ - expect_bt_bap_stream_ops_qos_set_called_once(stream); - expect_bt_bap_stream_ops_disabled_not_called(); - expect_bt_bap_stream_ops_released_not_called(); - expect_bt_bap_stream_ops_disconnected_called_once(stream); + expect_bt_bap_stream_ops_qos_set_called(1, &stream); + expect_bt_bap_stream_ops_disabled_called(0, NULL); + expect_bt_bap_stream_ops_released_called(0, NULL); + expect_bt_bap_stream_ops_disconnected_called(1, (const struct bt_bap_stream **)&stream); } ZTEST_F(ascs_test_suite, test_cis_link_loss_in_disabling_state_v1) @@ -536,9 +536,9 @@ ZTEST_F(ascs_test_suite, test_cis_link_loss_in_enabling_state) test_drain_syswq(); /* Ensure that state transitions are completed */ /* Expected no change in ASE state */ - expect_bt_bap_stream_ops_qos_set_not_called(); - expect_bt_bap_stream_ops_released_not_called(); - expect_bt_bap_stream_ops_disconnected_called_once(stream); + expect_bt_bap_stream_ops_qos_set_called(0, NULL); + expect_bt_bap_stream_ops_released_called(0, NULL); + expect_bt_bap_stream_ops_disconnected_called(1, (const struct bt_bap_stream **)&stream); err = bt_bap_stream_disable(stream); zassert_equal(0, err, "Failed to disable stream: err %d", err); @@ -546,11 +546,11 @@ ZTEST_F(ascs_test_suite, test_cis_link_loss_in_enabling_state) test_drain_syswq(); /* Ensure that state transitions are completed */ if (IS_ENABLED(CONFIG_BT_ASCS_ASE_SNK)) { - expect_bt_bap_stream_ops_qos_set_called_once(stream); - expect_bt_bap_stream_ops_disabled_called_once(stream); + expect_bt_bap_stream_ops_qos_set_called(1, &stream); + expect_bt_bap_stream_ops_disabled_called(1, &stream); } else { /* Server-initiated disable operation that shall not cause transition to QoS */ - expect_bt_bap_stream_ops_qos_set_not_called(); + expect_bt_bap_stream_ops_qos_set_called(0, NULL); } } @@ -579,7 +579,7 @@ ZTEST_F(ascs_test_suite, test_cis_link_loss_in_enabling_state_client_retries) test_preamble_state_enabling(conn, ase_id, stream); err = mock_bt_iso_accept(conn, 0x01, 0x01, &chan); zassert_equal(0, err, "Failed to connect iso: err %d", err); - expect_bt_bap_stream_ops_connected_called_once(stream); + expect_bt_bap_stream_ops_connected_called(1, (const struct bt_bap_stream **)&stream); /* Mock CIS disconnection */ mock_bt_iso_disconnected(chan, BT_HCI_ERR_CONN_FAIL_TO_ESTAB); @@ -587,9 +587,9 @@ ZTEST_F(ascs_test_suite, test_cis_link_loss_in_enabling_state_client_retries) test_drain_syswq(); /* Ensure that state transitions are completed */ /* Expected to not notify the upper layers */ - expect_bt_bap_stream_ops_qos_set_not_called(); - expect_bt_bap_stream_ops_released_not_called(); - expect_bt_bap_stream_ops_disconnected_called_once(stream); + expect_bt_bap_stream_ops_qos_set_called(0, NULL); + expect_bt_bap_stream_ops_released_called(0, NULL); + expect_bt_bap_stream_ops_disconnected_called(1, (const struct bt_bap_stream **)&stream); /* Client retries to establish CIS */ err = mock_bt_iso_accept(conn, 0x01, 0x01, &chan); @@ -603,8 +603,10 @@ ZTEST_F(ascs_test_suite, test_cis_link_loss_in_enabling_state_client_retries) test_drain_syswq(); /* Ensure that state transitions are completed */ - expect_bt_bap_stream_ops_connected_called_twice(stream); - expect_bt_bap_stream_ops_started_called_once(stream); + const struct bt_bap_stream *streams[] = { stream, stream }; + + expect_bt_bap_stream_ops_connected_called(ARRAY_SIZE(streams), streams); + expect_bt_bap_stream_ops_started_called(1, &stream); } static struct bt_bap_stream *stream_allocated; @@ -674,7 +676,7 @@ ZTEST_F(ascs_test_suite, test_ase_state_notification_retry) cp->write(conn, cp, (void *)buf, sizeof(buf), 0, 0); /* Verification */ - expect_bt_bap_stream_ops_configured_not_called(); + expect_bt_bap_stream_ops_configured_called(0, NULL, NULL); mock_bt_gatt_notify_cb_fake.return_val = 0; @@ -684,5 +686,5 @@ ZTEST_F(ascs_test_suite, test_ase_state_notification_retry) /* Wait for ASE state notification retry */ k_sleep(K_USEC(info.le.interval_us)); - expect_bt_bap_stream_ops_configured_called_once(stream, EMPTY); + expect_bt_bap_stream_ops_configured_called(1, &stream, NULL); } diff --git a/tests/bluetooth/audio/ascs/src/test_ase_state_transition.c b/tests/bluetooth/audio/ascs/src/test_ase_state_transition.c index a9b47288938a..335c38b3cc13 100644 --- a/tests/bluetooth/audio/ascs/src/test_ase_state_transition.c +++ b/tests/bluetooth/audio/ascs/src/test_ase_state_transition.c @@ -148,9 +148,12 @@ ZTEST_F(test_sink_ase_state_transition, test_client_idle_to_codec_configured) test_ase_control_client_config_codec(conn, ase_id, stream); /* Verification */ - expect_bt_bap_unicast_server_cb_config_called_once(conn, EMPTY, BT_AUDIO_DIR_SINK, EMPTY); - expect_bt_bap_stream_ops_configured_called_once(stream, EMPTY); + enum bt_audio_dir dir = BT_AUDIO_DIR_SINK; + + expect_bt_bap_unicast_server_cb_config_called(1, &conn, NULL, &dir, NULL); + expect_bt_bap_stream_ops_configured_called(1, &stream, NULL); } + ZTEST_F(test_sink_ase_state_transition, test_client_codec_configured_to_qos_configured) { struct bt_bap_stream *stream = &fixture->stream; @@ -164,9 +167,9 @@ ZTEST_F(test_sink_ase_state_transition, test_client_codec_configured_to_qos_conf test_ase_control_client_config_qos(conn, ase_id); /* Verification */ - expect_bt_bap_unicast_server_cb_qos_called_once(stream, EMPTY); - expect_bt_bap_stream_ops_qos_set_called_once(stream); - expect_bt_bap_stream_ops_disabled_not_called(); + expect_bt_bap_unicast_server_cb_qos_called(1, &stream, NULL); + expect_bt_bap_stream_ops_qos_set_called(1, &stream); + expect_bt_bap_stream_ops_disabled_called(0, NULL); } ZTEST_F(test_sink_ase_state_transition, test_client_qos_configured_to_enabling) @@ -182,8 +185,8 @@ ZTEST_F(test_sink_ase_state_transition, test_client_qos_configured_to_enabling) test_ase_control_client_enable(conn, ase_id); /* Verification */ - expect_bt_bap_unicast_server_cb_enable_called_once(stream, EMPTY, EMPTY); - expect_bt_bap_stream_ops_enabled_called_once(stream); + expect_bt_bap_unicast_server_cb_enable_called(1, &stream, NULL, NULL); + expect_bt_bap_stream_ops_enabled_called(1, &stream); } ZTEST_F(test_sink_ase_state_transition, test_client_enabling_to_qos_configured) @@ -199,9 +202,9 @@ ZTEST_F(test_sink_ase_state_transition, test_client_enabling_to_qos_configured) test_ase_control_client_disable(conn, ase_id); /* Verification */ - expect_bt_bap_unicast_server_cb_disable_called_once(stream); - expect_bt_bap_stream_ops_qos_set_called_once(stream); - expect_bt_bap_stream_ops_disabled_called_once(stream); + expect_bt_bap_unicast_server_cb_disable_called(1, &stream); + expect_bt_bap_stream_ops_qos_set_called(1, &stream); + expect_bt_bap_stream_ops_disabled_called(1, &stream); } ZTEST_F(test_sink_ase_state_transition, test_client_qos_configured_to_releasing) @@ -217,8 +220,8 @@ ZTEST_F(test_sink_ase_state_transition, test_client_qos_configured_to_releasing) test_ase_control_client_release(conn, ase_id); /* Verification */ - expect_bt_bap_unicast_server_cb_release_called_once(stream); - expect_bt_bap_stream_ops_released_called_once(stream); + expect_bt_bap_unicast_server_cb_release_called(1, &stream); + expect_bt_bap_stream_ops_released_called(1, (const struct bt_bap_stream **)&stream); } ZTEST_F(test_sink_ase_state_transition, test_client_codec_configured_to_codec_configured) @@ -234,9 +237,11 @@ ZTEST_F(test_sink_ase_state_transition, test_client_codec_configured_to_codec_co test_ase_control_client_config_codec(conn, ase_id, stream); /* Verification */ - expect_bt_bap_unicast_server_cb_config_not_called(); - expect_bt_bap_unicast_server_cb_reconfig_called_once(stream, BT_AUDIO_DIR_SINK, EMPTY); - expect_bt_bap_stream_ops_configured_called_once(stream, EMPTY); + const enum bt_audio_dir dir = BT_AUDIO_DIR_SINK; + + expect_bt_bap_unicast_server_cb_config_called(0, NULL, NULL, NULL, NULL); + expect_bt_bap_unicast_server_cb_reconfig_called(1, &stream, &dir, NULL); + expect_bt_bap_stream_ops_configured_called(1, &stream, NULL); } ZTEST_F(test_sink_ase_state_transition, test_client_qos_configured_to_qos_configured) @@ -252,9 +257,9 @@ ZTEST_F(test_sink_ase_state_transition, test_client_qos_configured_to_qos_config test_ase_control_client_config_qos(conn, ase_id); /* Verification */ - expect_bt_bap_unicast_server_cb_qos_called_once(stream, EMPTY); - expect_bt_bap_stream_ops_qos_set_called_once(stream); - expect_bt_bap_stream_ops_disabled_not_called(); + expect_bt_bap_unicast_server_cb_qos_called(1, &stream, NULL); + expect_bt_bap_stream_ops_qos_set_called(1, &stream); + expect_bt_bap_stream_ops_disabled_called(0, NULL); } ZTEST_F(test_sink_ase_state_transition, test_client_qos_configured_to_codec_configured) @@ -270,8 +275,10 @@ ZTEST_F(test_sink_ase_state_transition, test_client_qos_configured_to_codec_conf test_ase_control_client_config_codec(conn, ase_id, stream); /* Verification */ - expect_bt_bap_unicast_server_cb_reconfig_called_once(stream, BT_AUDIO_DIR_SINK, EMPTY); - expect_bt_bap_stream_ops_configured_called_once(stream, EMPTY); + const enum bt_audio_dir dir = BT_AUDIO_DIR_SINK; + + expect_bt_bap_unicast_server_cb_reconfig_called(1, &stream, &dir, NULL); + expect_bt_bap_stream_ops_configured_called(1, &stream, NULL); } ZTEST_F(test_sink_ase_state_transition, test_client_codec_configured_to_releasing) @@ -287,8 +294,8 @@ ZTEST_F(test_sink_ase_state_transition, test_client_codec_configured_to_releasin test_ase_control_client_release(conn, ase_id); /* Verification */ - expect_bt_bap_unicast_server_cb_release_called_once(stream); - expect_bt_bap_stream_ops_released_called_once(stream); + expect_bt_bap_unicast_server_cb_release_called(1, &stream); + expect_bt_bap_stream_ops_released_called(1, (const struct bt_bap_stream **)&stream); } ZTEST_F(test_sink_ase_state_transition, test_client_enabling_to_releasing) @@ -304,9 +311,9 @@ ZTEST_F(test_sink_ase_state_transition, test_client_enabling_to_releasing) test_ase_control_client_release(conn, ase_id); /* Verification */ - expect_bt_bap_unicast_server_cb_release_called_once(stream); - expect_bt_bap_stream_ops_released_called_once(stream); - expect_bt_bap_stream_ops_disabled_not_called(); + expect_bt_bap_unicast_server_cb_release_called(1, &stream); + expect_bt_bap_stream_ops_released_called(1, (const struct bt_bap_stream **)&stream); + expect_bt_bap_stream_ops_disabled_called(0, NULL); } ZTEST_F(test_sink_ase_state_transition, test_client_enabling_to_enabling) @@ -322,9 +329,9 @@ ZTEST_F(test_sink_ase_state_transition, test_client_enabling_to_enabling) test_ase_control_client_update_metadata(conn, ase_id); /* Verification */ - expect_bt_bap_unicast_server_cb_metadata_called_once(stream, EMPTY, EMPTY); - expect_bt_bap_stream_ops_metadata_updated_called_once(stream); - expect_bt_bap_stream_ops_disabled_not_called(); + expect_bt_bap_unicast_server_cb_metadata_called(1, &stream, NULL, NULL); + expect_bt_bap_stream_ops_metadata_updated_called(1, &stream); + expect_bt_bap_stream_ops_disabled_called(0, NULL); } ZTEST_F(test_sink_ase_state_transition, test_client_streaming_to_releasing) @@ -346,11 +353,13 @@ ZTEST_F(test_sink_ase_state_transition, test_client_streaming_to_releasing) test_drain_syswq(); /* Ensure that state transitions are completed */ /* Verification */ - expect_bt_bap_unicast_server_cb_release_called_once(stream); - expect_bt_bap_stream_ops_stopped_called_once(stream, BT_HCI_ERR_REMOTE_USER_TERM_CONN); - expect_bt_bap_stream_ops_released_called_once(stream); - expect_bt_bap_stream_ops_disabled_not_called(); - expect_bt_bap_stream_ops_disconnected_called_once(stream); + const uint8_t reason = BT_HCI_ERR_REMOTE_USER_TERM_CONN; + + expect_bt_bap_unicast_server_cb_release_called(1, &stream); + expect_bt_bap_stream_ops_stopped_called(1, &stream, &reason); + expect_bt_bap_stream_ops_released_called(1, (const struct bt_bap_stream **)&stream); + expect_bt_bap_stream_ops_disabled_called(0, NULL); + expect_bt_bap_stream_ops_disconnected_called(1, (const struct bt_bap_stream **)&stream); } ZTEST_F(test_sink_ase_state_transition, test_client_streaming_to_streaming) @@ -367,9 +376,9 @@ ZTEST_F(test_sink_ase_state_transition, test_client_streaming_to_streaming) test_ase_control_client_update_metadata(conn, ase_id); /* Verification */ - expect_bt_bap_unicast_server_cb_metadata_called_once(stream, EMPTY, EMPTY); - expect_bt_bap_stream_ops_metadata_updated_called_once(stream); - expect_bt_bap_stream_ops_disabled_not_called(); + expect_bt_bap_unicast_server_cb_metadata_called(1, &stream, NULL, NULL); + expect_bt_bap_stream_ops_metadata_updated_called(1, &stream); + expect_bt_bap_stream_ops_disabled_called(0, NULL); } ZTEST_F(test_sink_ase_state_transition, test_client_streaming_to_qos_configured) @@ -386,10 +395,12 @@ ZTEST_F(test_sink_ase_state_transition, test_client_streaming_to_qos_configured) test_ase_control_client_disable(conn, ase_id); /* Verification */ - expect_bt_bap_unicast_server_cb_disable_called_once(stream); - expect_bt_bap_stream_ops_stopped_called_once(stream, BT_HCI_ERR_REMOTE_USER_TERM_CONN); - expect_bt_bap_stream_ops_qos_set_called_once(stream); - expect_bt_bap_stream_ops_disabled_called_once(stream); + const uint8_t reason = BT_HCI_ERR_REMOTE_USER_TERM_CONN; + + expect_bt_bap_unicast_server_cb_disable_called(1, &stream); + expect_bt_bap_stream_ops_stopped_called(1, &stream, &reason); + expect_bt_bap_stream_ops_qos_set_called(1, &stream); + expect_bt_bap_stream_ops_disabled_called(1, &stream); } ZTEST_F(test_sink_ase_state_transition, test_server_idle_to_codec_configured) @@ -409,8 +420,8 @@ ZTEST_F(test_sink_ase_state_transition, test_server_idle_to_codec_configured) test_drain_syswq(); /* Ensure that state transitions are completed */ /* Verification */ - expect_bt_bap_unicast_server_cb_config_not_called(); - expect_bt_bap_stream_ops_configured_called_once(stream, EMPTY); + expect_bt_bap_unicast_server_cb_config_called(0, NULL, NULL, NULL, NULL); + expect_bt_bap_stream_ops_configured_called(1, &stream, NULL); } ZTEST_F(test_sink_ase_state_transition, test_server_codec_configured_to_codec_configured) @@ -433,8 +444,10 @@ ZTEST_F(test_sink_ase_state_transition, test_server_codec_configured_to_codec_co test_drain_syswq(); /* Ensure that state transitions are completed */ /* Verification */ - expect_bt_bap_unicast_server_cb_reconfig_called_once(stream, BT_AUDIO_DIR_SINK, EMPTY); - expect_bt_bap_stream_ops_configured_called_once(stream, EMPTY); + const enum bt_audio_dir dir = BT_AUDIO_DIR_SINK; + + expect_bt_bap_unicast_server_cb_reconfig_called(1, &stream, &dir, NULL); + expect_bt_bap_stream_ops_configured_called(1, &stream, NULL); } ZTEST_F(test_sink_ase_state_transition, test_server_codec_configured_to_releasing) @@ -454,8 +467,8 @@ ZTEST_F(test_sink_ase_state_transition, test_server_codec_configured_to_releasin test_drain_syswq(); /* Ensure that state transitions are completed */ /* Verification */ - expect_bt_bap_unicast_server_cb_release_called_once(stream); - expect_bt_bap_stream_ops_released_called_once(stream); + expect_bt_bap_unicast_server_cb_release_called(1, &stream); + expect_bt_bap_stream_ops_released_called(1, (const struct bt_bap_stream **)&stream); } ZTEST_F(test_sink_ase_state_transition, test_server_qos_configured_to_codec_configured) @@ -478,8 +491,10 @@ ZTEST_F(test_sink_ase_state_transition, test_server_qos_configured_to_codec_conf test_drain_syswq(); /* Ensure that state transitions are completed */ /* Verification */ - expect_bt_bap_unicast_server_cb_reconfig_called_once(stream, BT_AUDIO_DIR_SINK, EMPTY); - expect_bt_bap_stream_ops_configured_called_once(stream, EMPTY); + const enum bt_audio_dir dir = BT_AUDIO_DIR_SINK; + + expect_bt_bap_unicast_server_cb_reconfig_called(1, &stream, &dir, NULL); + expect_bt_bap_stream_ops_configured_called(1, &stream, NULL); } ZTEST_F(test_sink_ase_state_transition, test_server_qos_configured_to_releasing) @@ -499,8 +514,8 @@ ZTEST_F(test_sink_ase_state_transition, test_server_qos_configured_to_releasing) test_drain_syswq(); /* Ensure that state transitions are completed */ /* Verification */ - expect_bt_bap_unicast_server_cb_release_called_once(stream); - expect_bt_bap_stream_ops_released_called_once(stream); + expect_bt_bap_unicast_server_cb_release_called(1, &stream); + expect_bt_bap_stream_ops_released_called(1, (const struct bt_bap_stream **)&stream); } ZTEST_F(test_sink_ase_state_transition, test_server_enabling_to_releasing) @@ -520,9 +535,9 @@ ZTEST_F(test_sink_ase_state_transition, test_server_enabling_to_releasing) test_drain_syswq(); /* Ensure that state transitions are completed */ /* Verification */ - expect_bt_bap_unicast_server_cb_release_called_once(stream); - expect_bt_bap_stream_ops_released_called_once(stream); - expect_bt_bap_stream_ops_disabled_not_called(); + expect_bt_bap_unicast_server_cb_release_called(1, &stream); + expect_bt_bap_stream_ops_released_called(1, (const struct bt_bap_stream **)&stream); + expect_bt_bap_stream_ops_disabled_called(0, NULL); } ZTEST_F(test_sink_ase_state_transition, test_server_enabling_to_enabling) @@ -546,9 +561,9 @@ ZTEST_F(test_sink_ase_state_transition, test_server_enabling_to_enabling) test_drain_syswq(); /* Ensure that state transitions are completed */ /* Verification */ - expect_bt_bap_unicast_server_cb_metadata_called_once(stream, EMPTY, EMPTY); - expect_bt_bap_stream_ops_metadata_updated_called_once(stream); - expect_bt_bap_stream_ops_disabled_not_called(); + expect_bt_bap_unicast_server_cb_metadata_called(1, &stream, NULL, NULL); + expect_bt_bap_stream_ops_metadata_updated_called(1, &stream); + expect_bt_bap_stream_ops_disabled_called(0, NULL); } ZTEST_F(test_sink_ase_state_transition, test_server_enabling_to_qos_configured) @@ -568,9 +583,9 @@ ZTEST_F(test_sink_ase_state_transition, test_server_enabling_to_qos_configured) test_drain_syswq(); /* Ensure that state transitions are completed */ /* Verification */ - expect_bt_bap_unicast_server_cb_disable_called_once(stream); - expect_bt_bap_stream_ops_qos_set_called_once(stream); - expect_bt_bap_stream_ops_disabled_called_once(stream); + expect_bt_bap_unicast_server_cb_disable_called(1, &stream); + expect_bt_bap_stream_ops_qos_set_called(1, &stream); + expect_bt_bap_stream_ops_disabled_called(1, &stream); } ZTEST_F(test_sink_ase_state_transition, test_server_enabling_to_streaming) @@ -594,9 +609,9 @@ ZTEST_F(test_sink_ase_state_transition, test_server_enabling_to_streaming) test_drain_syswq(); /* Ensure that state transitions are completed */ /* Verification */ - expect_bt_bap_stream_ops_connected_called_once(stream); - expect_bt_bap_stream_ops_started_called_once(stream); - expect_bt_bap_stream_ops_disabled_not_called(); + expect_bt_bap_stream_ops_connected_called(1, (const struct bt_bap_stream **)&stream); + expect_bt_bap_stream_ops_started_called(1, &stream); + expect_bt_bap_stream_ops_disabled_called(0, NULL); /* XXX: unicast_server_cb->start is not called for Sink ASE */ } @@ -622,9 +637,9 @@ ZTEST_F(test_sink_ase_state_transition, test_server_streaming_to_streaming) test_drain_syswq(); /* Ensure that state transitions are completed */ /* Verification */ - expect_bt_bap_unicast_server_cb_metadata_called_once(stream, EMPTY, EMPTY); - expect_bt_bap_stream_ops_metadata_updated_called_once(stream); - expect_bt_bap_stream_ops_disabled_not_called(); + expect_bt_bap_unicast_server_cb_metadata_called(1, &stream, NULL, NULL); + expect_bt_bap_stream_ops_metadata_updated_called(1, &stream); + expect_bt_bap_stream_ops_disabled_called(0, NULL); } ZTEST_F(test_sink_ase_state_transition, test_server_streaming_to_qos_configured) @@ -645,10 +660,12 @@ ZTEST_F(test_sink_ase_state_transition, test_server_streaming_to_qos_configured) test_drain_syswq(); /* Ensure that state transitions are completed */ /* Verification */ - expect_bt_bap_unicast_server_cb_disable_called_once(stream); - expect_bt_bap_stream_ops_stopped_called_once(stream, BT_HCI_ERR_LOCALHOST_TERM_CONN); - expect_bt_bap_stream_ops_qos_set_called_once(stream); - expect_bt_bap_stream_ops_disabled_called_once(stream); + const uint8_t reason = BT_HCI_ERR_LOCALHOST_TERM_CONN; + + expect_bt_bap_unicast_server_cb_disable_called(1, &stream); + expect_bt_bap_stream_ops_stopped_called(1, &stream, &reason); + expect_bt_bap_stream_ops_qos_set_called(1, &stream); + expect_bt_bap_stream_ops_disabled_called(1, &stream); } ZTEST_F(test_sink_ase_state_transition, test_server_streaming_to_releasing) @@ -674,11 +691,13 @@ ZTEST_F(test_sink_ase_state_transition, test_server_streaming_to_releasing) test_drain_syswq(); /* Ensure that state transitions are completed */ /* Verification */ - expect_bt_bap_unicast_server_cb_release_called_once(stream); - expect_bt_bap_stream_ops_stopped_called_once(stream, BT_HCI_ERR_LOCALHOST_TERM_CONN); - expect_bt_bap_stream_ops_released_called_once(stream); - expect_bt_bap_stream_ops_disabled_not_called(); - expect_bt_bap_stream_ops_disconnected_called_once(stream); + const uint8_t reason = BT_HCI_ERR_LOCALHOST_TERM_CONN; + + expect_bt_bap_unicast_server_cb_release_called(1, &stream); + expect_bt_bap_stream_ops_stopped_called(1, &stream, &reason); + expect_bt_bap_stream_ops_released_called(1, (const struct bt_bap_stream **)&stream); + expect_bt_bap_stream_ops_disabled_called(0, NULL); + expect_bt_bap_stream_ops_disconnected_called(1, (const struct bt_bap_stream **)&stream); } static void *test_source_ase_state_transition_setup(void) @@ -713,8 +732,10 @@ ZTEST_F(test_source_ase_state_transition, test_client_idle_to_codec_configured) test_ase_control_client_config_codec(conn, ase_id, stream); /* Verification */ - expect_bt_bap_unicast_server_cb_config_called_once(conn, EMPTY, BT_AUDIO_DIR_SOURCE, EMPTY); - expect_bt_bap_stream_ops_configured_called_once(stream, EMPTY); + enum bt_audio_dir dir = BT_AUDIO_DIR_SOURCE; + + expect_bt_bap_unicast_server_cb_config_called(1, &conn, NULL, &dir, NULL); + expect_bt_bap_stream_ops_configured_called(1, &stream, NULL); } ZTEST_F(test_source_ase_state_transition, test_client_codec_configured_to_qos_configured) @@ -730,9 +751,9 @@ ZTEST_F(test_source_ase_state_transition, test_client_codec_configured_to_qos_co test_ase_control_client_config_qos(conn, ase_id); /* Verification */ - expect_bt_bap_unicast_server_cb_qos_called_once(stream, EMPTY); - expect_bt_bap_stream_ops_qos_set_called_once(stream); - expect_bt_bap_stream_ops_disabled_not_called(); + expect_bt_bap_unicast_server_cb_qos_called(1, &stream, NULL); + expect_bt_bap_stream_ops_qos_set_called(1, &stream); + expect_bt_bap_stream_ops_disabled_called(0, NULL); } ZTEST_F(test_source_ase_state_transition, test_client_qos_configured_to_enabling) @@ -748,8 +769,8 @@ ZTEST_F(test_source_ase_state_transition, test_client_qos_configured_to_enabling test_ase_control_client_enable(conn, ase_id); /* Verification */ - expect_bt_bap_unicast_server_cb_enable_called_once(stream, EMPTY, EMPTY); - expect_bt_bap_stream_ops_enabled_called_once(stream); + expect_bt_bap_unicast_server_cb_enable_called(1, &stream, NULL, NULL); + expect_bt_bap_stream_ops_enabled_called(1, &stream); } ZTEST_F(test_source_ase_state_transition, test_client_enabling_to_disabling) @@ -765,8 +786,8 @@ ZTEST_F(test_source_ase_state_transition, test_client_enabling_to_disabling) test_ase_control_client_disable(conn, ase_id); /* Verification */ - expect_bt_bap_unicast_server_cb_disable_called_once(stream); - expect_bt_bap_stream_ops_disabled_called_once(stream); + expect_bt_bap_unicast_server_cb_disable_called(1, &stream); + expect_bt_bap_stream_ops_disabled_called(1, &stream); } ZTEST_F(test_source_ase_state_transition, test_client_qos_configured_to_releasing) @@ -782,8 +803,8 @@ ZTEST_F(test_source_ase_state_transition, test_client_qos_configured_to_releasin test_ase_control_client_release(conn, ase_id); /* Verification */ - expect_bt_bap_unicast_server_cb_release_called_once(stream); - expect_bt_bap_stream_ops_released_called_once(stream); + expect_bt_bap_unicast_server_cb_release_called(1, &stream); + expect_bt_bap_stream_ops_released_called(1, (const struct bt_bap_stream **)&stream); } ZTEST_F(test_source_ase_state_transition, test_client_enabling_to_streaming) @@ -804,10 +825,10 @@ ZTEST_F(test_source_ase_state_transition, test_client_enabling_to_streaming) test_ase_control_client_receiver_start_ready(conn, ase_id); /* Verification */ - expect_bt_bap_unicast_server_cb_start_called_once(stream); - expect_bt_bap_stream_ops_connected_called_once(stream); - expect_bt_bap_stream_ops_started_called_once(stream); - expect_bt_bap_stream_ops_disabled_not_called(); + expect_bt_bap_unicast_server_cb_start_called(1, &stream); + expect_bt_bap_stream_ops_connected_called(1, (const struct bt_bap_stream **)&stream); + expect_bt_bap_stream_ops_started_called(1, &stream); + expect_bt_bap_stream_ops_disabled_called(0, NULL); } ZTEST_F(test_source_ase_state_transition, test_client_codec_configured_to_codec_configured) @@ -823,8 +844,10 @@ ZTEST_F(test_source_ase_state_transition, test_client_codec_configured_to_codec_ test_ase_control_client_config_codec(conn, ase_id, stream); /* Verification */ - expect_bt_bap_unicast_server_cb_reconfig_called_once(stream, BT_AUDIO_DIR_SOURCE, EMPTY); - expect_bt_bap_stream_ops_configured_called_once(stream, EMPTY); + const enum bt_audio_dir dir = BT_AUDIO_DIR_SOURCE; + + expect_bt_bap_unicast_server_cb_reconfig_called(1, &stream, &dir, NULL); + expect_bt_bap_stream_ops_configured_called(1, &stream, NULL); } ZTEST_F(test_source_ase_state_transition, test_client_qos_configured_to_qos_configured) @@ -840,9 +863,9 @@ ZTEST_F(test_source_ase_state_transition, test_client_qos_configured_to_qos_conf test_ase_control_client_config_qos(conn, ase_id); /* Verification */ - expect_bt_bap_unicast_server_cb_qos_called_once(stream, EMPTY); - expect_bt_bap_stream_ops_qos_set_called_once(stream); - expect_bt_bap_stream_ops_disabled_not_called(); + expect_bt_bap_unicast_server_cb_qos_called(1, &stream, NULL); + expect_bt_bap_stream_ops_qos_set_called(1, &stream); + expect_bt_bap_stream_ops_disabled_called(0, NULL); } ZTEST_F(test_source_ase_state_transition, test_client_qos_configured_to_codec_configured) @@ -858,8 +881,10 @@ ZTEST_F(test_source_ase_state_transition, test_client_qos_configured_to_codec_co test_ase_control_client_config_codec(conn, ase_id, stream); /* Verification */ - expect_bt_bap_unicast_server_cb_reconfig_called_once(stream, BT_AUDIO_DIR_SOURCE, EMPTY); - expect_bt_bap_stream_ops_configured_called_once(stream, EMPTY); + const enum bt_audio_dir dir = BT_AUDIO_DIR_SOURCE; + + expect_bt_bap_unicast_server_cb_reconfig_called(1, &stream, &dir, NULL); + expect_bt_bap_stream_ops_configured_called(1, &stream, NULL); } ZTEST_F(test_source_ase_state_transition, test_client_codec_configured_to_releasing) @@ -875,8 +900,8 @@ ZTEST_F(test_source_ase_state_transition, test_client_codec_configured_to_releas test_ase_control_client_release(conn, ase_id); /* Verification */ - expect_bt_bap_unicast_server_cb_release_called_once(stream); - expect_bt_bap_stream_ops_released_called_once(stream); + expect_bt_bap_unicast_server_cb_release_called(1, &stream); + expect_bt_bap_stream_ops_released_called(1, (const struct bt_bap_stream **)&stream); } ZTEST_F(test_source_ase_state_transition, test_client_enabling_to_releasing) @@ -892,9 +917,9 @@ ZTEST_F(test_source_ase_state_transition, test_client_enabling_to_releasing) test_ase_control_client_release(conn, ase_id); /* Verification */ - expect_bt_bap_unicast_server_cb_release_called_once(stream); - expect_bt_bap_stream_ops_released_called_once(stream); - expect_bt_bap_stream_ops_disabled_not_called(); + expect_bt_bap_unicast_server_cb_release_called(1, &stream); + expect_bt_bap_stream_ops_released_called(1, (const struct bt_bap_stream **)&stream); + expect_bt_bap_stream_ops_disabled_called(0, NULL); } ZTEST_F(test_source_ase_state_transition, test_client_enabling_to_enabling) @@ -910,9 +935,9 @@ ZTEST_F(test_source_ase_state_transition, test_client_enabling_to_enabling) test_ase_control_client_update_metadata(conn, ase_id); /* Verification */ - expect_bt_bap_unicast_server_cb_metadata_called_once(stream, EMPTY, EMPTY); - expect_bt_bap_stream_ops_metadata_updated_called_once(stream); - expect_bt_bap_stream_ops_disabled_not_called(); + expect_bt_bap_unicast_server_cb_metadata_called(1, &stream, NULL, NULL); + expect_bt_bap_stream_ops_metadata_updated_called(1, &stream); + expect_bt_bap_stream_ops_disabled_called(0, NULL); } ZTEST_F(test_source_ase_state_transition, test_client_streaming_to_releasing) @@ -934,11 +959,13 @@ ZTEST_F(test_source_ase_state_transition, test_client_streaming_to_releasing) test_drain_syswq(); /* Ensure that state transitions are completed */ /* Verification */ - expect_bt_bap_unicast_server_cb_release_called_once(stream); - expect_bt_bap_stream_ops_stopped_called_once(stream, BT_HCI_ERR_REMOTE_USER_TERM_CONN); - expect_bt_bap_stream_ops_released_called_once(stream); - expect_bt_bap_stream_ops_disabled_not_called(); - expect_bt_bap_stream_ops_disconnected_called_once(stream); + const uint8_t reason = BT_HCI_ERR_REMOTE_USER_TERM_CONN; + + expect_bt_bap_unicast_server_cb_release_called(1, &stream); + expect_bt_bap_stream_ops_stopped_called(1, &stream, &reason); + expect_bt_bap_stream_ops_released_called(1, (const struct bt_bap_stream **)&stream); + expect_bt_bap_stream_ops_disabled_called(0, NULL); + expect_bt_bap_stream_ops_disconnected_called(1, (const struct bt_bap_stream **)&stream); } ZTEST_F(test_source_ase_state_transition, test_client_streaming_to_streaming) @@ -955,9 +982,9 @@ ZTEST_F(test_source_ase_state_transition, test_client_streaming_to_streaming) test_ase_control_client_update_metadata(conn, ase_id); /* Verification */ - expect_bt_bap_unicast_server_cb_metadata_called_once(stream, EMPTY, EMPTY); - expect_bt_bap_stream_ops_metadata_updated_called_once(stream); - expect_bt_bap_stream_ops_disabled_not_called(); + expect_bt_bap_unicast_server_cb_metadata_called(1, &stream, NULL, NULL); + expect_bt_bap_stream_ops_metadata_updated_called(1, &stream); + expect_bt_bap_stream_ops_disabled_called(0, NULL); } ZTEST_F(test_source_ase_state_transition, test_client_streaming_to_disabling) @@ -974,9 +1001,11 @@ ZTEST_F(test_source_ase_state_transition, test_client_streaming_to_disabling) test_ase_control_client_disable(conn, ase_id); /* Verification */ - expect_bt_bap_unicast_server_cb_disable_called_once(stream); - expect_bt_bap_stream_ops_stopped_called_once(stream, BT_HCI_ERR_REMOTE_USER_TERM_CONN); - expect_bt_bap_stream_ops_disabled_called_once(stream); + const uint8_t reason = BT_HCI_ERR_REMOTE_USER_TERM_CONN; + + expect_bt_bap_unicast_server_cb_disable_called(1, &stream); + expect_bt_bap_stream_ops_stopped_called(1, &stream, &reason); + expect_bt_bap_stream_ops_disabled_called(1, &stream); } ZTEST_F(test_source_ase_state_transition, test_client_enabling_to_disabling_to_qos_configured) @@ -989,16 +1018,16 @@ ZTEST_F(test_source_ase_state_transition, test_client_enabling_to_disabling_to_q test_preamble_state_enabling(conn, ase_id, stream); test_ase_control_client_disable(conn, ase_id); - expect_bt_bap_stream_ops_disabled_called_once(stream); + expect_bt_bap_stream_ops_disabled_called(1, &stream); test_mocks_reset(); test_ase_control_client_receiver_stop_ready(conn, ase_id); /* Verification */ - expect_bt_bap_unicast_server_cb_stop_called_once(stream); - expect_bt_bap_stream_ops_qos_set_called_once(stream); - expect_bt_bap_stream_ops_disabled_not_called(); + expect_bt_bap_unicast_server_cb_stop_called(1, &stream); + expect_bt_bap_stream_ops_qos_set_called(1, &stream); + expect_bt_bap_stream_ops_disabled_called(0, NULL); } ZTEST_F(test_source_ase_state_transition, test_client_streaming_to_disabling_to_qos_configured) @@ -1014,8 +1043,10 @@ ZTEST_F(test_source_ase_state_transition, test_client_streaming_to_disabling_to_ test_ase_control_client_disable(conn, ase_id); /* Verify that stopped callback was called by disable */ - expect_bt_bap_stream_ops_disabled_called_once(stream); - expect_bt_bap_stream_ops_stopped_called_once(stream, BT_HCI_ERR_REMOTE_USER_TERM_CONN); + const uint8_t reason = BT_HCI_ERR_REMOTE_USER_TERM_CONN; + + expect_bt_bap_stream_ops_disabled_called(1, &stream); + expect_bt_bap_stream_ops_stopped_called(1, &stream, &reason); test_mocks_reset(); @@ -1023,9 +1054,9 @@ ZTEST_F(test_source_ase_state_transition, test_client_streaming_to_disabling_to_ test_ase_control_client_receiver_stop_ready(conn, ase_id); /* Verification */ - expect_bt_bap_unicast_server_cb_stop_called_once(stream); - expect_bt_bap_stream_ops_qos_set_called_once(stream); - expect_bt_bap_stream_ops_disabled_not_called(); + expect_bt_bap_unicast_server_cb_stop_called(1, &stream); + expect_bt_bap_stream_ops_qos_set_called(1, &stream); + expect_bt_bap_stream_ops_disabled_called(0, NULL); } ZTEST_F(test_source_ase_state_transition, test_server_idle_to_codec_configured) @@ -1045,8 +1076,8 @@ ZTEST_F(test_source_ase_state_transition, test_server_idle_to_codec_configured) test_drain_syswq(); /* Ensure that state transitions are completed */ /* Verification */ - expect_bt_bap_unicast_server_cb_config_not_called(); - expect_bt_bap_stream_ops_configured_called_once(stream, EMPTY); + expect_bt_bap_unicast_server_cb_config_called(0, NULL, NULL, NULL, NULL); + expect_bt_bap_stream_ops_configured_called(1, &stream, NULL); } ZTEST_F(test_source_ase_state_transition, test_server_codec_configured_to_codec_configured) @@ -1069,8 +1100,10 @@ ZTEST_F(test_source_ase_state_transition, test_server_codec_configured_to_codec_ test_drain_syswq(); /* Ensure that state transitions are completed */ /* Verification */ - expect_bt_bap_unicast_server_cb_reconfig_called_once(stream, BT_AUDIO_DIR_SOURCE, EMPTY); - expect_bt_bap_stream_ops_configured_called_once(stream, EMPTY); + const enum bt_audio_dir dir = BT_AUDIO_DIR_SOURCE; + + expect_bt_bap_unicast_server_cb_reconfig_called(1, &stream, &dir, NULL); + expect_bt_bap_stream_ops_configured_called(1, &stream, NULL); } ZTEST_F(test_source_ase_state_transition, test_server_codec_configured_to_releasing) @@ -1090,8 +1123,8 @@ ZTEST_F(test_source_ase_state_transition, test_server_codec_configured_to_releas test_drain_syswq(); /* Ensure that state transitions are completed */ /* Verification */ - expect_bt_bap_unicast_server_cb_release_called_once(stream); - expect_bt_bap_stream_ops_released_called_once(stream); + expect_bt_bap_unicast_server_cb_release_called(1, &stream); + expect_bt_bap_stream_ops_released_called(1, (const struct bt_bap_stream **)&stream); } ZTEST_F(test_source_ase_state_transition, test_server_qos_configured_to_codec_configured) @@ -1114,8 +1147,10 @@ ZTEST_F(test_source_ase_state_transition, test_server_qos_configured_to_codec_co test_drain_syswq(); /* Ensure that state transitions are completed */ /* Verification */ - expect_bt_bap_unicast_server_cb_reconfig_called_once(stream, BT_AUDIO_DIR_SOURCE, EMPTY); - expect_bt_bap_stream_ops_configured_called_once(stream, EMPTY); + const enum bt_audio_dir dir = BT_AUDIO_DIR_SOURCE; + + expect_bt_bap_unicast_server_cb_reconfig_called(1, &stream, &dir, NULL); + expect_bt_bap_stream_ops_configured_called(1, &stream, NULL); } ZTEST_F(test_source_ase_state_transition, test_server_qos_configured_to_releasing) @@ -1135,8 +1170,8 @@ ZTEST_F(test_source_ase_state_transition, test_server_qos_configured_to_releasin test_drain_syswq(); /* Ensure that state transitions are completed */ /* Verification */ - expect_bt_bap_unicast_server_cb_release_called_once(stream); - expect_bt_bap_stream_ops_released_called_once(stream); + expect_bt_bap_unicast_server_cb_release_called(1, &stream); + expect_bt_bap_stream_ops_released_called(1, (const struct bt_bap_stream **)&stream); } ZTEST_F(test_source_ase_state_transition, test_server_enabling_to_releasing) @@ -1156,9 +1191,9 @@ ZTEST_F(test_source_ase_state_transition, test_server_enabling_to_releasing) test_drain_syswq(); /* Ensure that state transitions are completed */ /* Verification */ - expect_bt_bap_unicast_server_cb_release_called_once(stream); - expect_bt_bap_stream_ops_released_called_once(stream); - expect_bt_bap_stream_ops_disabled_not_called(); + expect_bt_bap_unicast_server_cb_release_called(1, &stream); + expect_bt_bap_stream_ops_released_called(1, (const struct bt_bap_stream **)&stream); + expect_bt_bap_stream_ops_disabled_called(0, NULL); } ZTEST_F(test_source_ase_state_transition, test_server_enabling_to_enabling) @@ -1182,9 +1217,9 @@ ZTEST_F(test_source_ase_state_transition, test_server_enabling_to_enabling) test_drain_syswq(); /* Ensure that state transitions are completed */ /* Verification */ - expect_bt_bap_unicast_server_cb_metadata_called_once(stream, EMPTY, EMPTY); - expect_bt_bap_stream_ops_metadata_updated_called_once(stream); - expect_bt_bap_stream_ops_disabled_not_called(); + expect_bt_bap_unicast_server_cb_metadata_called(1, &stream, NULL, NULL); + expect_bt_bap_stream_ops_metadata_updated_called(1, &stream); + expect_bt_bap_stream_ops_disabled_called(0, NULL); } ZTEST_F(test_source_ase_state_transition, test_server_enabling_to_disabling) @@ -1204,8 +1239,8 @@ ZTEST_F(test_source_ase_state_transition, test_server_enabling_to_disabling) test_drain_syswq(); /* Ensure that state transitions are completed */ /* Verification */ - expect_bt_bap_unicast_server_cb_disable_called_once(stream); - expect_bt_bap_stream_ops_disabled_called_once(stream); + expect_bt_bap_unicast_server_cb_disable_called(1, &stream); + expect_bt_bap_stream_ops_disabled_called(1, &stream); } ZTEST_F(test_source_ase_state_transition, test_server_streaming_to_streaming) @@ -1230,9 +1265,9 @@ ZTEST_F(test_source_ase_state_transition, test_server_streaming_to_streaming) test_drain_syswq(); /* Ensure that state transitions are completed */ /* Verification */ - expect_bt_bap_unicast_server_cb_metadata_called_once(stream, EMPTY, EMPTY); - expect_bt_bap_stream_ops_metadata_updated_called_once(stream); - expect_bt_bap_stream_ops_disabled_not_called(); + expect_bt_bap_unicast_server_cb_metadata_called(1, &stream, NULL, NULL); + expect_bt_bap_stream_ops_metadata_updated_called(1, &stream); + expect_bt_bap_stream_ops_disabled_called(0, NULL); } ZTEST_F(test_source_ase_state_transition, test_server_streaming_to_disabling) @@ -1253,9 +1288,11 @@ ZTEST_F(test_source_ase_state_transition, test_server_streaming_to_disabling) test_drain_syswq(); /* Ensure that state transitions are completed */ /* Verification */ - expect_bt_bap_unicast_server_cb_disable_called_once(stream); - expect_bt_bap_stream_ops_stopped_called_once(stream, BT_HCI_ERR_LOCALHOST_TERM_CONN); - expect_bt_bap_stream_ops_disabled_called_once(stream); + const uint8_t reason = BT_HCI_ERR_LOCALHOST_TERM_CONN; + + expect_bt_bap_unicast_server_cb_disable_called(1, &stream); + expect_bt_bap_stream_ops_stopped_called(1, &stream, &reason); + expect_bt_bap_stream_ops_disabled_called(1, &stream); } ZTEST_F(test_source_ase_state_transition, test_server_streaming_to_releasing) @@ -1281,9 +1318,11 @@ ZTEST_F(test_source_ase_state_transition, test_server_streaming_to_releasing) test_drain_syswq(); /* Ensure that state transitions are completed */ /* Verification */ - expect_bt_bap_unicast_server_cb_release_called_once(stream); - expect_bt_bap_stream_ops_stopped_called_once(stream, BT_HCI_ERR_LOCALHOST_TERM_CONN); - expect_bt_bap_stream_ops_released_called_once(stream); - expect_bt_bap_stream_ops_disabled_not_called(); - expect_bt_bap_stream_ops_disconnected_called_once(stream); + const uint8_t reason = BT_HCI_ERR_LOCALHOST_TERM_CONN; + + expect_bt_bap_unicast_server_cb_release_called(1, &stream); + expect_bt_bap_stream_ops_stopped_called(1, &stream, &reason); + expect_bt_bap_stream_ops_released_called(1, (const struct bt_bap_stream **)&stream); + expect_bt_bap_stream_ops_disabled_called(0, NULL); + expect_bt_bap_stream_ops_disconnected_called(1, (const struct bt_bap_stream **)&stream); } diff --git a/tests/bluetooth/audio/mocks/include/bap_stream_expects.h b/tests/bluetooth/audio/mocks/include/bap_stream_expects.h index 0a936bdaf04f..ab2eba652c73 100644 --- a/tests/bluetooth/audio/mocks/include/bap_stream_expects.h +++ b/tests/bluetooth/audio/mocks/include/bap_stream_expects.h @@ -17,116 +17,100 @@ #include "bap_stream.h" #include "expects_util.h" -#define expect_bt_bap_stream_ops_configured_called_once(_stream, _pref) \ -do { \ - const char *func_name = "bt_bap_stream_ops.configured"; \ - \ - zexpect_call_count(func_name, 1, mock_bap_stream_configured_cb_fake.call_count); \ - \ - if (mock_bap_stream_configured_cb_fake.call_count > 0) { \ - IF_NOT_EMPTY(_stream, ( \ - zexpect_equal_ptr(_stream, mock_bap_stream_configured_cb_fake.arg0_val, \ - "'%s()' was called with incorrect '%s' value", \ - func_name, "stream");)) \ - \ - IF_NOT_EMPTY(_pref, ( \ - /* TODO */ \ - zassert_unreachable("Not implemented");)) \ - } \ -} while (0) - -static inline void expect_bt_bap_stream_ops_configured_not_called(void) +static inline void expect_bt_bap_stream_ops_configured_called( + unsigned int expected_count, + struct bt_bap_stream *streams[], + void *pref[]) { const char *func_name = "bt_bap_stream_ops.configured"; - zexpect_call_count(func_name, 0, mock_bap_stream_configured_cb_fake.call_count); -} - -static inline void expect_bt_bap_stream_ops_qos_set_called_once(struct bt_bap_stream *stream) -{ - const char *func_name = "bt_bap_stream_ops.qos_set"; + zexpect_call_count(func_name, + expected_count, mock_bap_stream_configured_cb_fake.call_count); - zexpect_call_count(func_name, 1, mock_bap_stream_qos_set_cb_fake.call_count); + for (unsigned int i = 0; i < mock_bap_stream_configured_cb_fake.call_count; i++) { + zexpect_equal_ptr(streams[i], + mock_bap_stream_configured_cb_fake.arg0_history[i], + "'%s()' was called with incorrect 'stream[%i]' value", + func_name, i); + } - if (mock_bap_stream_qos_set_cb_fake.call_count > 0) { - zexpect_equal_ptr(stream, mock_bap_stream_qos_set_cb_fake.arg0_val, - "'%s()' was called with incorrect '%s'", func_name, "stream"); + if (pref) { + /* TODO */ + zassert_unreachable("Not implemented"); } } -static inline void expect_bt_bap_stream_ops_qos_set_not_called(void) +static inline void expect_bt_bap_stream_ops_qos_set_called( + unsigned int expected_count, + struct bt_bap_stream *streams[]) { const char *func_name = "bt_bap_stream_ops.qos_set"; - zexpect_call_count(func_name, 0, mock_bap_stream_qos_set_cb_fake.call_count); -} + zexpect_call_count(func_name, + expected_count, mock_bap_stream_qos_set_cb_fake.call_count); -static inline void expect_bt_bap_stream_ops_enabled_called_once(struct bt_bap_stream *stream) -{ - const char *func_name = "bt_bap_stream_ops.enabled"; - - zexpect_call_count(func_name, 1, mock_bap_stream_enabled_cb_fake.call_count); - - if (mock_bap_stream_enabled_cb_fake.call_count > 0) { - zexpect_equal_ptr(stream, mock_bap_stream_enabled_cb_fake.arg0_val, - "'%s()' was called with incorrect '%s'", func_name, "stream"); + for (unsigned int i = 0; i < mock_bap_stream_qos_set_cb_fake.call_count; i++) { + zexpect_equal_ptr(streams[i], + mock_bap_stream_qos_set_cb_fake.arg0_history[i], + "'%s()' was called with incorrect '%s[%i]'", func_name, "stream", i); } } -static inline void expect_bt_bap_stream_ops_enabled_not_called(void) +static inline void expect_bt_bap_stream_ops_enabled_called( + unsigned int expected_count, + struct bt_bap_stream *streams[]) { const char *func_name = "bt_bap_stream_ops.enabled"; - zexpect_call_count(func_name, 0, mock_bap_stream_enabled_cb_fake.call_count); -} - -static inline void expect_bt_bap_stream_ops_metadata_updated_called_once( - struct bt_bap_stream *stream) -{ - const char *func_name = "bt_bap_stream_ops.metadata_updated"; - - zexpect_call_count(func_name, 1, mock_bap_stream_metadata_updated_cb_fake.call_count); + zexpect_call_count(func_name, expected_count, mock_bap_stream_enabled_cb_fake.call_count); - if (mock_bap_stream_metadata_updated_cb_fake.call_count > 0) { - zexpect_equal_ptr(stream, mock_bap_stream_metadata_updated_cb_fake.arg0_val, - "'%s()' was called with incorrect '%s'", func_name, "stream"); + for (unsigned int i = 0; i < mock_bap_stream_enabled_cb_fake.call_count; i++) { + zexpect_equal_ptr(streams[i], + mock_bap_stream_enabled_cb_fake.arg0_history[i], + "'%s()' was called with incorrect '%s[%i]'", func_name, "stream", i); } } -static inline void expect_bt_bap_stream_ops_metadata_updated_not_called(void) +static inline void expect_bt_bap_stream_ops_metadata_updated_called( + int expected_count, + struct bt_bap_stream *streams[]) { const char *func_name = "bt_bap_stream_ops.metadata_updated"; - zexpect_call_count(func_name, 0, mock_bap_stream_metadata_updated_cb_fake.call_count); -} - -static inline void expect_bt_bap_stream_ops_disabled_called_once(struct bt_bap_stream *stream) -{ - const char *func_name = "bt_bap_stream_ops.disabled"; - - zexpect_call_count(func_name, 1, mock_bap_stream_disabled_cb_fake.call_count); + zexpect_call_count(func_name, + expected_count, mock_bap_stream_metadata_updated_cb_fake.call_count); - if (mock_bap_stream_disabled_cb_fake.call_count > 0) { - zexpect_equal_ptr(stream, mock_bap_stream_disabled_cb_fake.arg0_val, - "'%s()' was called with incorrect '%s'", func_name, "stream"); + for (unsigned int i = 0; i < mock_bap_stream_metadata_updated_cb_fake.call_count; i++) { + zexpect_equal_ptr(streams[i], + mock_bap_stream_metadata_updated_cb_fake.arg0_history[i], + "'%s()' was called with incorrect '%s[%i]'", func_name, "stream", i); } } -static inline void expect_bt_bap_stream_ops_disabled_not_called(void) +static inline void expect_bt_bap_stream_ops_disabled_called( + unsigned int expected_count, + struct bt_bap_stream *streams[]) { const char *func_name = "bt_bap_stream_ops.disabled"; - zexpect_call_count(func_name, 0, mock_bap_stream_disabled_cb_fake.call_count); + zexpect_call_count(func_name, expected_count, mock_bap_stream_disabled_cb_fake.call_count); + + for (unsigned int i = 0; i < mock_bap_stream_disabled_cb_fake.call_count; i++) { + zexpect_equal_ptr(streams[i], + mock_bap_stream_disabled_cb_fake.arg0_history[i], + "'%s()' was called with incorrect '%s[%i]'", func_name, "stream", i); + } } -static inline void expect_bt_bap_stream_ops_released_called(const struct bt_bap_stream *streams[], - unsigned int count) +static inline void expect_bt_bap_stream_ops_released_called( + unsigned int expected_count, + const struct bt_bap_stream *streams[]) { const char *func_name = "bt_bap_stream_ops.released"; - zexpect_call_count(func_name, count, mock_bap_stream_released_cb_fake.call_count); + zexpect_call_count(func_name, expected_count, mock_bap_stream_released_cb_fake.call_count); - for (unsigned int i = 0; i < count; i++) { + for (unsigned int i = 0; i < expected_count; i++) { bool found = false; for (unsigned int j = 0; j < mock_bap_stream_released_cb_fake.call_count; j++) { @@ -140,143 +124,107 @@ static inline void expect_bt_bap_stream_ops_released_called(const struct bt_bap_ } } -static inline void expect_bt_bap_stream_ops_released_called_once(const struct bt_bap_stream *stream) -{ - expect_bt_bap_stream_ops_released_called(&stream, 1); -} - -static inline void expect_bt_bap_stream_ops_released_not_called(void) -{ - const char *func_name = "bt_bap_stream_ops.released"; - - zexpect_equal(0, mock_bap_stream_released_cb_fake.call_count, - "'%s()' was called unexpectedly", func_name); -} - -static inline void expect_bt_bap_stream_ops_started_called_once(struct bt_bap_stream *stream) +static inline void expect_bt_bap_stream_ops_started_called( + unsigned int expected_count, + struct bt_bap_stream *streams[]) { const char *func_name = "bt_bap_stream_ops.started"; - zexpect_call_count(func_name, 1, mock_bap_stream_started_cb_fake.call_count); + zexpect_call_count(func_name, expected_count, mock_bap_stream_started_cb_fake.call_count); - if (mock_bap_stream_started_cb_fake.call_count > 0) { - zexpect_equal_ptr(stream, mock_bap_stream_started_cb_fake.arg0_val, - "'%s()' was called with incorrect '%s'", func_name, "stream"); + for (unsigned int i = 0; i < mock_bap_stream_started_cb_fake.call_count; i++) { + zexpect_equal_ptr(streams[i], + mock_bap_stream_started_cb_fake.arg0_history[i], + "'%s()' was called with incorrect '%s[%i]'", func_name, "stream", i); } } -static inline void expect_bt_bap_stream_ops_started_not_called(void) -{ - const char *func_name = "bt_bap_stream_ops.started"; - - zexpect_call_count(func_name, 0, mock_bap_stream_started_cb_fake.call_count); -} - -#define expect_bt_bap_stream_ops_stopped_called_once(_stream, _reason) \ -do { \ - const char *func_name = "bt_bap_stream_ops.stopped"; \ - \ - zexpect_call_count(func_name, 1, mock_bap_stream_stopped_cb_fake.call_count); \ - \ - if (mock_bap_stream_stopped_cb_fake.call_count > 0) { \ - IF_NOT_EMPTY(_stream, ( \ - zexpect_equal_ptr(_stream, mock_bap_stream_stopped_cb_fake.arg0_val, \ - "'%s()' was called with incorrect '%s' value", \ - func_name, "stream");)) \ - \ - IF_NOT_EMPTY(_reason, ( \ - zexpect_equal(_reason, mock_bap_stream_stopped_cb_fake.arg1_val, \ - "'%s()' was called with incorrect '%s' value", \ - func_name, "reason");)) \ - } \ -} while (0) - -static inline void expect_bt_bap_stream_ops_stopped_not_called(void) +static inline void expect_bt_bap_stream_ops_stopped_called( + unsigned int expected_count, + struct bt_bap_stream *streams[], + const uint8_t reasons[]) { const char *func_name = "bt_bap_stream_ops.stopped"; - zexpect_call_count(func_name, 0, mock_bap_stream_stopped_cb_fake.call_count); -} - -static inline void -expect_bt_bap_stream_ops_connected_called_once(const struct bt_bap_stream *stream) -{ - const char *func_name = "bt_bap_stream_ops.connected"; - - zexpect_call_count(func_name, 1, mock_bap_stream_connected_cb_fake.call_count); + zexpect_call_count(func_name, expected_count, mock_bap_stream_stopped_cb_fake.call_count); - if (mock_bap_stream_connected_cb_fake.call_count > 0) { - zexpect_equal_ptr(stream, mock_bap_stream_connected_cb_fake.arg0_val, - "'%s()' was called with incorrect '%s'", func_name, "stream"); + for (unsigned int i = 0; i < mock_bap_stream_stopped_cb_fake.call_count; i++) { + zexpect_equal_ptr(streams[i], + mock_bap_stream_stopped_cb_fake.arg0_history[i], + "'%s()' was called with incorrect '%s[%i]' value", func_name, "stream", i); + zexpect_equal(reasons[i], + mock_bap_stream_stopped_cb_fake.arg1_history[i], + "'%s()' was called with incorrect '%s[%i]' value", func_name, "reason", i); } } static inline void -expect_bt_bap_stream_ops_connected_called_twice(const struct bt_bap_stream *stream) +expect_bt_bap_stream_ops_connected_called( + unsigned int expected_count, + const struct bt_bap_stream *streams[]) { const char *func_name = "bt_bap_stream_ops.connected"; - zexpect_call_count(func_name, 2, mock_bap_stream_connected_cb_fake.call_count); + zexpect_call_count(func_name, + expected_count, mock_bap_stream_connected_cb_fake.call_count); - if (mock_bap_stream_connected_cb_fake.call_count > 0) { - zexpect_equal_ptr(stream, mock_bap_stream_connected_cb_fake.arg0_val, - "'%s()' was called with incorrect '%s'", func_name, "stream"); + for (unsigned int i = 0; i < mock_bap_stream_connected_cb_fake.call_count; i++) { + zexpect_equal_ptr(streams[i], + mock_bap_stream_connected_cb_fake.arg0_history[i], + "'%s()' was called with incorrect '%s[%i]'", func_name, "stream", i); } } static inline void -expect_bt_bap_stream_ops_disconnected_called_once(const struct bt_bap_stream *stream) +expect_bt_bap_stream_ops_disconnected_called( + unsigned int expected_count, + const struct bt_bap_stream *streams[]) { const char *func_name = "bt_bap_stream_ops.disconnected"; - zexpect_call_count(func_name, 1, mock_bap_stream_disconnected_cb_fake.call_count); + zexpect_call_count(func_name, + expected_count, mock_bap_stream_disconnected_cb_fake.call_count); - if (mock_bap_stream_disconnected_cb_fake.call_count > 0) { - zexpect_equal_ptr(stream, mock_bap_stream_disconnected_cb_fake.arg0_val, - "'%s()' was called with incorrect '%s'", func_name, "stream"); + for (unsigned int i = 0; i < mock_bap_stream_disconnected_cb_fake.call_count; i++) { + zexpect_equal_ptr(streams[i], + mock_bap_stream_disconnected_cb_fake.arg0_history[i], + "'%s()' was called with incorrect '%s[%i]'", func_name, "stream", i); } } -static inline void expect_bt_bap_stream_ops_recv_called_once(struct bt_bap_stream *stream, - const struct bt_iso_recv_info *info, - struct net_buf *buf) +static inline void +expect_bt_bap_stream_ops_recv_called( + unsigned int expected_count, + struct bt_bap_stream *streams[], + const struct bt_iso_recv_info *info, + struct net_buf *buf) { const char *func_name = "bt_bap_stream_ops.recv"; - zexpect_call_count(func_name, 1, mock_bap_stream_recv_cb_fake.call_count); + zexpect_call_count(func_name, expected_count, mock_bap_stream_recv_cb_fake.call_count); - if (mock_bap_stream_recv_cb_fake.call_count > 0) { - zexpect_equal_ptr(stream, mock_bap_stream_recv_cb_fake.arg0_val, - "'%s()' was called with incorrect '%s'", func_name, "stream"); + for (unsigned int i = 0; i < mock_bap_stream_recv_cb_fake.call_count; i++) { + zexpect_equal_ptr(streams[i], + mock_bap_stream_recv_cb_fake.arg0_history[i], + "'%s()' was called with incorrect '%s[%i]'", func_name, "stream", i); } /* TODO: validate info && buf */ } -static inline void expect_bt_bap_stream_ops_recv_not_called(void) -{ - const char *func_name = "bt_bap_stream_ops.recv"; - - zexpect_call_count(func_name, 0, mock_bap_stream_recv_cb_fake.call_count); -} - -static inline void expect_bt_bap_stream_ops_sent_called_once(struct bt_bap_stream *stream) +static inline void expect_bt_bap_stream_ops_sent_called( + unsigned int expected_count, + struct bt_bap_stream *streams[]) { const char *func_name = "bt_bap_stream_ops.sent"; - zexpect_call_count(func_name, 1, mock_bap_stream_sent_cb_fake.call_count); + zexpect_call_count(func_name, expected_count, mock_bap_stream_sent_cb_fake.call_count); - if (mock_bap_stream_sent_cb_fake.call_count > 0) { - zexpect_equal_ptr(stream, mock_bap_stream_sent_cb_fake.arg0_val, - "'%s()' was called with incorrect '%s'", func_name, "stream"); + for (unsigned int i = 0; i < mock_bap_stream_sent_cb_fake.call_count; i++) { + zexpect_equal_ptr(streams[i], + mock_bap_stream_sent_cb_fake.arg0_history[i], + "'%s()' was called with incorrect '%s[%i]'", func_name, "stream", i); } } -static inline void expect_bt_bap_stream_ops_sent_not_called(void) -{ - const char *func_name = "bt_bap_stream_ops.sent"; - - zexpect_call_count(func_name, 0, mock_bap_stream_sent_cb_fake.call_count); -} - #endif /* MOCKS_BAP_STREAM_EXPECTS_H_ */ From 53af11f76309cda946eac38e9dd992b5d8a2a57d Mon Sep 17 00:00:00 2001 From: Yasushi SHOJI Date: Sun, 26 Oct 2025 01:31:54 +0900 Subject: [PATCH 0672/3659] drivers: timer: Remove unused CONFIG_XLNX_PSTTC_TIMER_INDEX CONFIG_XLNX_PSTTC_TIMER_INDEX has been unused since commit 57784fb9d52 (v2.3 era), which switched to using the `DT_INST_` macro and defaulted to the first instance via `DT_INST_REG_ADDR(0)`. Remove the obsolete and broken CONFIG_XLNX_PSTTC_TIMER_INDEX. Signed-off-by: Yasushi SHOJI --- drivers/timer/Kconfig.xlnx_psttc | 8 -------- drivers/timer/xlnx_psttc_timer.c | 2 -- 2 files changed, 10 deletions(-) diff --git a/drivers/timer/Kconfig.xlnx_psttc b/drivers/timer/Kconfig.xlnx_psttc index 3004086c834e..f79661a9954c 100644 --- a/drivers/timer/Kconfig.xlnx_psttc +++ b/drivers/timer/Kconfig.xlnx_psttc @@ -13,11 +13,3 @@ config XLNX_PSTTC_TIMER Zynq UltraScale+ MPSoC (ZynqMP) and Versal platforms. This TTC-based timer driver provides the "standard system clock driver" interface. If disabled, the TTC will not be used as the system timer. - -config XLNX_PSTTC_TIMER_INDEX - int "Xilinx PS Triple-Timer Counter index" - range 0 3 - default 0 - depends on XLNX_PSTTC_TIMER - help - This is the index of TTC timer picked to provide system clock. diff --git a/drivers/timer/xlnx_psttc_timer.c b/drivers/timer/xlnx_psttc_timer.c index c50f104e20d8..67022c26f155 100644 --- a/drivers/timer/xlnx_psttc_timer.c +++ b/drivers/timer/xlnx_psttc_timer.c @@ -15,8 +15,6 @@ #include #include "xlnx_psttc_timer_priv.h" -#define TIMER_INDEX CONFIG_XLNX_PSTTC_TIMER_INDEX - #define TIMER_IRQ DT_INST_IRQN(0) #define TIMER_BASE_ADDR DT_INST_REG_ADDR(0) #define TIMER_CLOCK_FREQUECY DT_INST_PROP(0, clock_frequency) From 2baeae776d9da9c7c5c1e30fe486a72d35121cd7 Mon Sep 17 00:00:00 2001 From: Thinh Le Cong Date: Mon, 20 Oct 2025 16:12:12 +0700 Subject: [PATCH 0673/3659] soc: renesas: ra: Initial support for IAR build tool on Renesas RA Support IAR build tool on Renesas RA devices Signed-off-by: Thinh Le Cong --- soc/renesas/ra/ra2a1/CMakeLists.txt | 29 ++++++++++++++-- soc/renesas/ra/ra2l1/CMakeLists.txt | 28 ++++++++++++++-- soc/renesas/ra/ra4c1/CMakeLists.txt | 47 ++++++++++++++++++++++++-- soc/renesas/ra/ra4e1/CMakeLists.txt | 35 ++++++++++++++++++-- soc/renesas/ra/ra4e2/CMakeLists.txt | 1 + soc/renesas/ra/ra4l1/CMakeLists.txt | 47 ++++++++++++++++++++++++-- soc/renesas/ra/ra4m1/CMakeLists.txt | 29 ++++++++++++++-- soc/renesas/ra/ra4m2/CMakeLists.txt | 35 ++++++++++++++++++-- soc/renesas/ra/ra4m3/CMakeLists.txt | 43 ++++++++++++++++++++++-- soc/renesas/ra/ra4w1/CMakeLists.txt | 28 ++++++++++++++-- soc/renesas/ra/ra6e1/CMakeLists.txt | 47 ++++++++++++++++++++++++-- soc/renesas/ra/ra6e2/CMakeLists.txt | 31 ++++++++++++++++-- soc/renesas/ra/ra6m1/CMakeLists.txt | 28 ++++++++++++++-- soc/renesas/ra/ra6m2/CMakeLists.txt | 28 ++++++++++++++-- soc/renesas/ra/ra6m3/CMakeLists.txt | 28 ++++++++++++++-- soc/renesas/ra/ra6m4/CMakeLists.txt | 47 ++++++++++++++++++++++++-- soc/renesas/ra/ra6m5/CMakeLists.txt | 47 ++++++++++++++++++++++++-- soc/renesas/ra/ra8d1/CMakeLists.txt | 51 +++++++++++++++++++++++++++-- soc/renesas/ra/ra8d2/CMakeLists.txt | 47 ++++++++++++++++++++++++-- soc/renesas/ra/ra8m1/CMakeLists.txt | 51 +++++++++++++++++++++++++++-- soc/renesas/ra/ra8m2/CMakeLists.txt | 47 ++++++++++++++++++++++++-- soc/renesas/ra/ra8p1/CMakeLists.txt | 47 ++++++++++++++++++++++++-- soc/renesas/ra/ra8t1/CMakeLists.txt | 51 +++++++++++++++++++++++++++-- 23 files changed, 821 insertions(+), 51 deletions(-) diff --git a/soc/renesas/ra/ra2a1/CMakeLists.txt b/soc/renesas/ra/ra2a1/CMakeLists.txt index 428e74e14452..6a1ea740c99e 100644 --- a/soc/renesas/ra/ra2a1/CMakeLists.txt +++ b/soc/renesas/ra/ra2a1/CMakeLists.txt @@ -8,8 +8,31 @@ zephyr_sources( soc.c ) -zephyr_linker_sources(SECTIONS sections.ld) -zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) -zephyr_linker_sources(ROM_START rom_start.ld) +dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") +dt_nodelabel(option_setting_ofs1 NODELABEL "option_setting_ofs1") +dt_nodelabel(option_setting_secmpu NODELABEL "option_setting_secmpu") +dt_nodelabel(option_setting_osis NODELABEL "option_setting_osis") + +dt_reg_addr(ofs0_addr PATH ${option_setting_ofs0}) +dt_reg_addr(ofs1_addr PATH ${option_setting_ofs1}) +dt_reg_addr(secmpu_addr PATH ${option_setting_secmpu}) +dt_reg_addr(osis_addr PATH ${option_setting_osis}) + +if(CONFIG_CMAKE_LINKER_GENERATOR) + zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) + zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") + zephyr_linker_section(NAME .option_setting_ofs0 GROUP FLASH ADDRESS ${ofs0_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") + zephyr_linker_section(NAME .option_setting_ofs1 GROUP FLASH ADDRESS ${ofs1_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs1 KEEP INPUT ".option_setting_ofs1*") + zephyr_linker_section(NAME .option_setting_secmpu GROUP FLASH ADDRESS ${secmpu_addr}) + zephyr_linker_section_configure(SECTION .option_setting_secmpu KEEP INPUT ".option_setting_secmpu*") + zephyr_linker_section(NAME .option_setting_osis GROUP OFS_OSIS_MEMORY ADDRESS ${osis_addr}) + zephyr_linker_section_configure(SECTION .option_setting_osis KEEP INPUT ".option_setting_osis*") +elseif(CONFIG_LD_LINKER_TEMPLATE) + zephyr_linker_sources(ROM_START rom_start.ld) + zephyr_linker_sources(SECTIONS sections.ld) + zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) +endif() set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra2l1/CMakeLists.txt b/soc/renesas/ra/ra2l1/CMakeLists.txt index 7c68d4378516..9f12447715f4 100644 --- a/soc/renesas/ra/ra2l1/CMakeLists.txt +++ b/soc/renesas/ra/ra2l1/CMakeLists.txt @@ -8,9 +8,31 @@ zephyr_sources( soc.c ) -zephyr_linker_sources(ROM_START rom_start.ld) +dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") +dt_nodelabel(option_setting_ofs1 NODELABEL "option_setting_ofs1") +dt_nodelabel(option_setting_secmpu NODELABEL "option_setting_secmpu") +dt_nodelabel(option_setting_osis NODELABEL "option_setting_osis") -zephyr_linker_sources(SECTIONS sections.ld) -zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) +dt_reg_addr(ofs0_addr PATH ${option_setting_ofs0}) +dt_reg_addr(ofs1_addr PATH ${option_setting_ofs1}) +dt_reg_addr(secmpu_addr PATH ${option_setting_secmpu}) +dt_reg_addr(osis_addr PATH ${option_setting_osis}) + +if(CONFIG_CMAKE_LINKER_GENERATOR) + zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) + zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") + zephyr_linker_section(NAME .option_setting_ofs0 GROUP FLASH ADDRESS ${ofs0_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") + zephyr_linker_section(NAME .option_setting_ofs1 GROUP FLASH ADDRESS ${ofs1_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs1 KEEP INPUT ".option_setting_ofs1*") + zephyr_linker_section(NAME .option_setting_secmpu GROUP FLASH ADDRESS ${secmpu_addr}) + zephyr_linker_section_configure(SECTION .option_setting_secmpu KEEP INPUT ".option_setting_secmpu*") + zephyr_linker_section(NAME .option_setting_osis GROUP OFS_OSIS_MEMORY ADDRESS ${osis_addr}) + zephyr_linker_section_configure(SECTION .option_setting_osis KEEP INPUT ".option_setting_osis*") +elseif(CONFIG_LD_LINKER_TEMPLATE) + zephyr_linker_sources(ROM_START rom_start.ld) + zephyr_linker_sources(SECTIONS sections.ld) + zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) +endif() set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra4c1/CMakeLists.txt b/soc/renesas/ra/ra4c1/CMakeLists.txt index 9bada9b094e9..ffda9d47ec78 100644 --- a/soc/renesas/ra/ra4c1/CMakeLists.txt +++ b/soc/renesas/ra/ra4c1/CMakeLists.txt @@ -7,7 +7,50 @@ zephyr_sources( soc.c ) -zephyr_linker_sources(SECTIONS sections.ld) -zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) +dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") +dt_nodelabel(option_setting_dualsel NODELABEL "option_setting_dualsel") +dt_nodelabel(option_setting_ofs1_sec NODELABEL "option_setting_ofs1_sec") +dt_nodelabel(option_setting_banksel_sec NODELABEL "option_setting_banksel_sec") +dt_nodelabel(option_setting_bps_sec NODELABEL "option_setting_bps_sec") +dt_nodelabel(option_setting_pbps_sec NODELABEL "option_setting_pbps_sec") +dt_nodelabel(option_setting_ofs1_sel NODELABEL "option_setting_ofs1_sel") +dt_nodelabel(option_setting_banksel_sel NODELABEL "option_setting_banksel_sel") +dt_nodelabel(option_setting_bps_sel NODELABEL "option_setting_bps_sel") + +dt_reg_addr(ofs0_addr PATH ${option_setting_ofs0}) +dt_reg_addr(dualsel_addr PATH ${option_setting_dualsel}) +dt_reg_addr(ofs1_sec_addr PATH ${option_setting_ofs1_sec}) +dt_reg_addr(banksel_sec_addr PATH ${option_setting_banksel_sec}) +dt_reg_addr(bps_sec_addr PATH ${option_setting_bps_sec}) +dt_reg_addr(pbps_sec_addr PATH ${option_setting_pbps_sec}) +dt_reg_addr(ofs1_sel_addr PATH ${option_setting_ofs1_sel}) +dt_reg_addr(banksel_sel_addr PATH ${option_setting_banksel_sel}) +dt_reg_addr(bps_sel_addr PATH ${option_setting_bps_sel}) + +if(CONFIG_CMAKE_LINKER_GENERATOR) + zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) + zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") + zephyr_linker_section(NAME .option_setting_ofs0 GROUP OFS_OFS0_MEMORY ADDRESS ${ofs0_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") + zephyr_linker_section(NAME .option_setting_dualsel GROUP OFS_DUALSEL_MEMORY ADDRESS ${dualsel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_dualsel KEEP INPUT ".option_setting_dualsel*") + zephyr_linker_section(NAME .option_setting_ofs1_sec GROUP OFS_OFS1_SEC_MEMORY ADDRESS ${ofs1_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs1_sec KEEP INPUT ".option_setting_ofs1_sec*") + zephyr_linker_section(NAME .option_setting_banksel_sec GROUP OFS_BANKSEL_SEC_MEMORY ADDRESS ${banksel_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_banksel_sec KEEP INPUT ".option_setting_banksel_sec*") + zephyr_linker_section(NAME .option_setting_ofs1_sel GROUP OFS_OFS1_SEL_MEMORY ADDRESS ${ofs1_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs1_sel KEEP INPUT ".option_setting_ofs1_sel*") + zephyr_linker_section(NAME .option_setting_banksel_sel GROUP OFS_BANKSEL_SEL_MEMORY ADDRESS ${banksel_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_banksel_sel KEEP INPUT ".option_setting_banksel_sel*") + zephyr_linker_section(NAME .option_setting_bps_sec GROUP OFS_BPS_SEC_MEMORY ADDRESS ${bps_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_bps_sec KEEP INPUT ".option_setting_bps_sec*") + zephyr_linker_section(NAME .option_setting_pbps_sec GROUP OFS_PBPS_SEC_MEMORY ADDRESS ${pbps_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_pbps_sec KEEP INPUT ".option_setting_pbps_sec*") + zephyr_linker_section(NAME .option_setting_bps_sel GROUP OFS_BPS_SEL_MEMORY ADDRESS ${bps_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_bps_sel KEEP INPUT ".option_setting_bps_sel*") +elseif(CONFIG_LD_LINKER_TEMPLATE) + zephyr_linker_sources(SECTIONS sections.ld) + zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) +endif() set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra4e1/CMakeLists.txt b/soc/renesas/ra/ra4e1/CMakeLists.txt index 9bada9b094e9..df61c861d354 100644 --- a/soc/renesas/ra/ra4e1/CMakeLists.txt +++ b/soc/renesas/ra/ra4e1/CMakeLists.txt @@ -7,7 +7,38 @@ zephyr_sources( soc.c ) -zephyr_linker_sources(SECTIONS sections.ld) -zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) +dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") +dt_nodelabel(option_setting_ofs1_sec NODELABEL "option_setting_ofs1_sec") +dt_nodelabel(option_setting_bps_sec NODELABEL "option_setting_bps_sec") +dt_nodelabel(option_setting_pbps_sec NODELABEL "option_setting_pbps_sec") +dt_nodelabel(option_setting_ofs1_sel NODELABEL "option_setting_ofs1_sel") +dt_nodelabel(option_setting_bps_sel NODELABEL "option_setting_bps_sel") + +dt_reg_addr(ofs0_addr PATH ${option_setting_ofs0}) +dt_reg_addr(ofs1_sec_addr PATH ${option_setting_ofs1_sec}) +dt_reg_addr(bps_sec_addr PATH ${option_setting_bps_sec}) +dt_reg_addr(pbps_sec_addr PATH ${option_setting_pbps_sec}) +dt_reg_addr(ofs1_sel_addr PATH ${option_setting_ofs1_sel}) +dt_reg_addr(bps_sel_addr PATH ${option_setting_bps_sel}) + +if(CONFIG_CMAKE_LINKER_GENERATOR) + zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) + zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") + zephyr_linker_section(NAME .option_setting_ofs0 GROUP OFS_OFS0_MEMORY ADDRESS ${ofs0_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") + zephyr_linker_section(NAME .option_setting_ofs1_sec GROUP OFS_OFS1_SEC_MEMORY ADDRESS ${ofs1_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs1_sec KEEP INPUT ".option_setting_ofs1_sec*") + zephyr_linker_section(NAME .option_setting_ofs1_sel GROUP OFS_OFS1_SEL_MEMORY ADDRESS ${ofs1_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs1_sel KEEP INPUT ".option_setting_ofs1_sel*") + zephyr_linker_section(NAME .option_setting_bps_sec GROUP OFS_BPS_SEC_MEMORY ADDRESS ${bps_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_bps_sec KEEP INPUT ".option_setting_bps_sec*") + zephyr_linker_section(NAME .option_setting_pbps_sec GROUP OFS_PBPS_SEC_MEMORY ADDRESS ${pbps_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_pbps_sec KEEP INPUT ".option_setting_pbps_sec*") + zephyr_linker_section(NAME .option_setting_bps_sel GROUP OFS_BPS_SEL_MEMORY ADDRESS ${bps_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_bps_sel KEEP INPUT ".option_setting_bps_sel*") +elseif(CONFIG_LD_LINKER_TEMPLATE) + zephyr_linker_sources(SECTIONS sections.ld) + zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) +endif() set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra4e2/CMakeLists.txt b/soc/renesas/ra/ra4e2/CMakeLists.txt index 6102e76b6505..0918f899601f 100644 --- a/soc/renesas/ra/ra4e2/CMakeLists.txt +++ b/soc/renesas/ra/ra4e2/CMakeLists.txt @@ -12,6 +12,7 @@ dt_nodelabel(option_setting_osis NODELABEL "option_setting_osis") dt_nodelabel(option_setting_ofs1_sec NODELABEL "option_setting_ofs1_sec") dt_nodelabel(option_setting_bps_sec NODELABEL "option_setting_bps_sec") dt_nodelabel(option_setting_pbps_sec NODELABEL "option_setting_pbps_sec") + dt_reg_addr(ofs0_addr PATH ${option_setting_ofs0}) dt_reg_addr(osis_addr PATH ${option_setting_osis}) dt_reg_addr(ofs1_sec_addr PATH ${option_setting_ofs1_sec}) diff --git a/soc/renesas/ra/ra4l1/CMakeLists.txt b/soc/renesas/ra/ra4l1/CMakeLists.txt index 9bada9b094e9..ffda9d47ec78 100644 --- a/soc/renesas/ra/ra4l1/CMakeLists.txt +++ b/soc/renesas/ra/ra4l1/CMakeLists.txt @@ -7,7 +7,50 @@ zephyr_sources( soc.c ) -zephyr_linker_sources(SECTIONS sections.ld) -zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) +dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") +dt_nodelabel(option_setting_dualsel NODELABEL "option_setting_dualsel") +dt_nodelabel(option_setting_ofs1_sec NODELABEL "option_setting_ofs1_sec") +dt_nodelabel(option_setting_banksel_sec NODELABEL "option_setting_banksel_sec") +dt_nodelabel(option_setting_bps_sec NODELABEL "option_setting_bps_sec") +dt_nodelabel(option_setting_pbps_sec NODELABEL "option_setting_pbps_sec") +dt_nodelabel(option_setting_ofs1_sel NODELABEL "option_setting_ofs1_sel") +dt_nodelabel(option_setting_banksel_sel NODELABEL "option_setting_banksel_sel") +dt_nodelabel(option_setting_bps_sel NODELABEL "option_setting_bps_sel") + +dt_reg_addr(ofs0_addr PATH ${option_setting_ofs0}) +dt_reg_addr(dualsel_addr PATH ${option_setting_dualsel}) +dt_reg_addr(ofs1_sec_addr PATH ${option_setting_ofs1_sec}) +dt_reg_addr(banksel_sec_addr PATH ${option_setting_banksel_sec}) +dt_reg_addr(bps_sec_addr PATH ${option_setting_bps_sec}) +dt_reg_addr(pbps_sec_addr PATH ${option_setting_pbps_sec}) +dt_reg_addr(ofs1_sel_addr PATH ${option_setting_ofs1_sel}) +dt_reg_addr(banksel_sel_addr PATH ${option_setting_banksel_sel}) +dt_reg_addr(bps_sel_addr PATH ${option_setting_bps_sel}) + +if(CONFIG_CMAKE_LINKER_GENERATOR) + zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) + zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") + zephyr_linker_section(NAME .option_setting_ofs0 GROUP OFS_OFS0_MEMORY ADDRESS ${ofs0_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") + zephyr_linker_section(NAME .option_setting_dualsel GROUP OFS_DUALSEL_MEMORY ADDRESS ${dualsel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_dualsel KEEP INPUT ".option_setting_dualsel*") + zephyr_linker_section(NAME .option_setting_ofs1_sec GROUP OFS_OFS1_SEC_MEMORY ADDRESS ${ofs1_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs1_sec KEEP INPUT ".option_setting_ofs1_sec*") + zephyr_linker_section(NAME .option_setting_banksel_sec GROUP OFS_BANKSEL_SEC_MEMORY ADDRESS ${banksel_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_banksel_sec KEEP INPUT ".option_setting_banksel_sec*") + zephyr_linker_section(NAME .option_setting_ofs1_sel GROUP OFS_OFS1_SEL_MEMORY ADDRESS ${ofs1_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs1_sel KEEP INPUT ".option_setting_ofs1_sel*") + zephyr_linker_section(NAME .option_setting_banksel_sel GROUP OFS_BANKSEL_SEL_MEMORY ADDRESS ${banksel_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_banksel_sel KEEP INPUT ".option_setting_banksel_sel*") + zephyr_linker_section(NAME .option_setting_bps_sec GROUP OFS_BPS_SEC_MEMORY ADDRESS ${bps_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_bps_sec KEEP INPUT ".option_setting_bps_sec*") + zephyr_linker_section(NAME .option_setting_pbps_sec GROUP OFS_PBPS_SEC_MEMORY ADDRESS ${pbps_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_pbps_sec KEEP INPUT ".option_setting_pbps_sec*") + zephyr_linker_section(NAME .option_setting_bps_sel GROUP OFS_BPS_SEL_MEMORY ADDRESS ${bps_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_bps_sel KEEP INPUT ".option_setting_bps_sel*") +elseif(CONFIG_LD_LINKER_TEMPLATE) + zephyr_linker_sources(SECTIONS sections.ld) + zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) +endif() set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra4m1/CMakeLists.txt b/soc/renesas/ra/ra4m1/CMakeLists.txt index 43812e3cd7e6..78d60b405889 100644 --- a/soc/renesas/ra/ra4m1/CMakeLists.txt +++ b/soc/renesas/ra/ra4m1/CMakeLists.txt @@ -6,8 +6,31 @@ zephyr_include_directories(.) zephyr_library_sources(soc.c) -zephyr_linker_sources(SECTIONS sections.ld) -zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) -zephyr_linker_sources(ROM_START rom_start.ld) +dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") +dt_nodelabel(option_setting_ofs1 NODELABEL "option_setting_ofs1") +dt_nodelabel(option_setting_secmpu NODELABEL "option_setting_secmpu") +dt_nodelabel(option_setting_osis NODELABEL "option_setting_osis") + +dt_reg_addr(ofs0_addr PATH ${option_setting_ofs0}) +dt_reg_addr(ofs1_addr PATH ${option_setting_ofs1}) +dt_reg_addr(secmpu_addr PATH ${option_setting_secmpu}) +dt_reg_addr(osis_addr PATH ${option_setting_osis}) + +if(CONFIG_CMAKE_LINKER_GENERATOR) + zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) + zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") + zephyr_linker_section(NAME .option_setting_ofs0 GROUP FLASH ADDRESS ${ofs0_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") + zephyr_linker_section(NAME .option_setting_ofs1 GROUP FLASH ADDRESS ${ofs1_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs1 KEEP INPUT ".option_setting_ofs1*") + zephyr_linker_section(NAME .option_setting_secmpu GROUP FLASH ADDRESS ${secmpu_addr}) + zephyr_linker_section_configure(SECTION .option_setting_secmpu KEEP INPUT ".option_setting_secmpu*") + zephyr_linker_section(NAME .option_setting_osis GROUP OFS_OSIS_MEMORY ADDRESS ${osis_addr}) + zephyr_linker_section_configure(SECTION .option_setting_osis KEEP INPUT ".option_setting_osis*") +elseif(CONFIG_LD_LINKER_TEMPLATE) + zephyr_linker_sources(ROM_START rom_start.ld) + zephyr_linker_sources(SECTIONS sections.ld) + zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) +endif() set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra4m2/CMakeLists.txt b/soc/renesas/ra/ra4m2/CMakeLists.txt index f8147e805910..af909123ab61 100644 --- a/soc/renesas/ra/ra4m2/CMakeLists.txt +++ b/soc/renesas/ra/ra4m2/CMakeLists.txt @@ -7,7 +7,38 @@ zephyr_sources( soc.c ) -zephyr_linker_sources(SECTIONS sections.ld) -zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) +dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") +dt_nodelabel(option_setting_ofs1_sec NODELABEL "option_setting_ofs1_sec") +dt_nodelabel(option_setting_bps_sec NODELABEL "option_setting_bps_sec") +dt_nodelabel(option_setting_pbps_sec NODELABEL "option_setting_pbps_sec") +dt_nodelabel(option_setting_ofs1_sel NODELABEL "option_setting_ofs1_sel") +dt_nodelabel(option_setting_bps_sel NODELABEL "option_setting_bps_sel") + +dt_reg_addr(ofs0_addr PATH ${option_setting_ofs0}) +dt_reg_addr(ofs1_sec_addr PATH ${option_setting_ofs1_sec}) +dt_reg_addr(bps_sec_addr PATH ${option_setting_bps_sec}) +dt_reg_addr(pbps_sec_addr PATH ${option_setting_pbps_sec}) +dt_reg_addr(ofs1_sel_addr PATH ${option_setting_ofs1_sel}) +dt_reg_addr(bps_sel_addr PATH ${option_setting_bps_sel}) + +if(CONFIG_CMAKE_LINKER_GENERATOR) + zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) + zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") + zephyr_linker_section(NAME .option_setting_ofs0 GROUP OFS_OFS0_MEMORY ADDRESS ${ofs0_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") + zephyr_linker_section(NAME .option_setting_ofs1_sec GROUP OFS_OFS1_SEC_MEMORY ADDRESS ${ofs1_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs1_sec KEEP INPUT ".option_setting_ofs1_sec*") + zephyr_linker_section(NAME .option_setting_ofs1_sel GROUP OFS_OFS1_SEL_MEMORY ADDRESS ${ofs1_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs1_sel KEEP INPUT ".option_setting_ofs1_sel*") + zephyr_linker_section(NAME .option_setting_bps_sec GROUP OFS_BPS_SEC_MEMORY ADDRESS ${bps_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_bps_sec KEEP INPUT ".option_setting_bps_sec*") + zephyr_linker_section(NAME .option_setting_pbps_sec GROUP OFS_PBPS_SEC_MEMORY ADDRESS ${pbps_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_pbps_sec KEEP INPUT ".option_setting_pbps_sec*") + zephyr_linker_section(NAME .option_setting_bps_sel GROUP OFS_BPS_SEL_MEMORY ADDRESS ${bps_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_bps_sel KEEP INPUT ".option_setting_bps_sel*") +elseif(CONFIG_LD_LINKER_TEMPLATE) + zephyr_linker_sources(SECTIONS sections.ld) + zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) +endif() set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra4m3/CMakeLists.txt b/soc/renesas/ra/ra4m3/CMakeLists.txt index f8147e805910..db314a4fd56a 100644 --- a/soc/renesas/ra/ra4m3/CMakeLists.txt +++ b/soc/renesas/ra/ra4m3/CMakeLists.txt @@ -7,7 +7,46 @@ zephyr_sources( soc.c ) -zephyr_linker_sources(SECTIONS sections.ld) -zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) +dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") +dt_nodelabel(option_setting_ofs1_sec NODELABEL "option_setting_ofs1_sec") +dt_nodelabel(option_setting_banksel_sec NODELABEL "option_setting_banksel_sec") +dt_nodelabel(option_setting_bps_sec NODELABEL "option_setting_bps_sec") +dt_nodelabel(option_setting_pbps_sec NODELABEL "option_setting_pbps_sec") +dt_nodelabel(option_setting_ofs1_sel NODELABEL "option_setting_ofs1_sel") +dt_nodelabel(option_setting_banksel_sel NODELABEL "option_setting_banksel_sel") +dt_nodelabel(option_setting_bps_sel NODELABEL "option_setting_bps_sel") + +dt_reg_addr(ofs0_addr PATH ${option_setting_ofs0}) +dt_reg_addr(ofs1_sec_addr PATH ${option_setting_ofs1_sec}) +dt_reg_addr(banksel_sec_addr PATH ${option_setting_banksel_sec}) +dt_reg_addr(bps_sec_addr PATH ${option_setting_bps_sec}) +dt_reg_addr(pbps_sec_addr PATH ${option_setting_pbps_sec}) +dt_reg_addr(ofs1_sel_addr PATH ${option_setting_ofs1_sel}) +dt_reg_addr(banksel_sel_addr PATH ${option_setting_banksel_sel}) +dt_reg_addr(bps_sel_addr PATH ${option_setting_bps_sel}) + +if(CONFIG_CMAKE_LINKER_GENERATOR) + zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) + zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") + zephyr_linker_section(NAME .option_setting_ofs0 GROUP OFS_OFS0_MEMORY ADDRESS ${ofs0_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") + zephyr_linker_section(NAME .option_setting_ofs1_sec GROUP OFS_OFS1_SEC_MEMORY ADDRESS ${ofs1_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs1_sec KEEP INPUT ".option_setting_ofs1_sec*") + zephyr_linker_section(NAME .option_setting_banksel_sec GROUP OFS_BANKSEL_SEC_MEMORY ADDRESS ${banksel_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_banksel_sec KEEP INPUT ".option_setting_banksel_sec*") + zephyr_linker_section(NAME .option_setting_ofs1_sel GROUP OFS_OFS1_SEL_MEMORY ADDRESS ${ofs1_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs1_sel KEEP INPUT ".option_setting_ofs1_sel*") + zephyr_linker_section(NAME .option_setting_banksel_sel GROUP OFS_BANKSEL_SEL_MEMORY ADDRESS ${banksel_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_banksel_sel KEEP INPUT ".option_setting_banksel_sel*") + zephyr_linker_section(NAME .option_setting_bps_sec GROUP OFS_BPS_SEC_MEMORY ADDRESS ${bps_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_bps_sec KEEP INPUT ".option_setting_bps_sec*") + zephyr_linker_section(NAME .option_setting_pbps_sec GROUP OFS_PBPS_SEC_MEMORY ADDRESS ${pbps_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_pbps_sec KEEP INPUT ".option_setting_pbps_sec*") + zephyr_linker_section(NAME .option_setting_bps_sel GROUP OFS_BPS_SEL_MEMORY ADDRESS ${bps_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_bps_sel KEEP INPUT ".option_setting_bps_sel*") +elseif(CONFIG_LD_LINKER_TEMPLATE) + zephyr_linker_sources(SECTIONS sections.ld) + zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) +endif() set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra4w1/CMakeLists.txt b/soc/renesas/ra/ra4w1/CMakeLists.txt index 6d685a499965..36a5f177990b 100644 --- a/soc/renesas/ra/ra4w1/CMakeLists.txt +++ b/soc/renesas/ra/ra4w1/CMakeLists.txt @@ -7,9 +7,31 @@ zephyr_sources( soc.c ) -zephyr_linker_sources(ROM_START rom_start.ld) +dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") +dt_nodelabel(option_setting_ofs1 NODELABEL "option_setting_ofs1") +dt_nodelabel(option_setting_secmpu NODELABEL "option_setting_secmpu") +dt_nodelabel(option_setting_osis NODELABEL "option_setting_osis") -zephyr_linker_sources(SECTIONS sections.ld) -zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) +dt_reg_addr(ofs0_addr PATH ${option_setting_ofs0}) +dt_reg_addr(ofs1_addr PATH ${option_setting_ofs1}) +dt_reg_addr(secmpu_addr PATH ${option_setting_secmpu}) +dt_reg_addr(osis_addr PATH ${option_setting_osis}) + +if(CONFIG_CMAKE_LINKER_GENERATOR) + zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) + zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") + zephyr_linker_section(NAME .option_setting_ofs0 GROUP FLASH ADDRESS ${ofs0_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") + zephyr_linker_section(NAME .option_setting_ofs1 GROUP FLASH ADDRESS ${ofs1_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs1 KEEP INPUT ".option_setting_ofs1*") + zephyr_linker_section(NAME .option_setting_secmpu GROUP FLASH ADDRESS ${secmpu_addr}) + zephyr_linker_section_configure(SECTION .option_setting_secmpu KEEP INPUT ".option_setting_secmpu*") + zephyr_linker_section(NAME .option_setting_osis GROUP OFS_OSIS_MEMORY ADDRESS ${osis_addr}) + zephyr_linker_section_configure(SECTION .option_setting_osis KEEP INPUT ".option_setting_osis*") +elseif(CONFIG_LD_LINKER_TEMPLATE) + zephyr_linker_sources(ROM_START rom_start.ld) + zephyr_linker_sources(SECTIONS sections.ld) + zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) +endif() set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra6e1/CMakeLists.txt b/soc/renesas/ra/ra6e1/CMakeLists.txt index f8147e805910..b25240222960 100644 --- a/soc/renesas/ra/ra6e1/CMakeLists.txt +++ b/soc/renesas/ra/ra6e1/CMakeLists.txt @@ -7,7 +7,50 @@ zephyr_sources( soc.c ) -zephyr_linker_sources(SECTIONS sections.ld) -zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) +dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") +dt_nodelabel(option_setting_dualsel NODELABEL "option_setting_dualsel") +dt_nodelabel(option_setting_ofs1_sec NODELABEL "option_setting_ofs1_sec") +dt_nodelabel(option_setting_banksel_sec NODELABEL "option_setting_banksel_sec") +dt_nodelabel(option_setting_bps_sec NODELABEL "option_setting_bps_sec") +dt_nodelabel(option_setting_pbps_sec NODELABEL "option_setting_pbps_sec") +dt_nodelabel(option_setting_ofs1_sel NODELABEL "option_setting_ofs1_sel") +dt_nodelabel(option_setting_banksel_sel NODELABEL "option_setting_banksel_sel") +dt_nodelabel(option_setting_bps_sel NODELABEL "option_setting_bps_sel") + +dt_reg_addr(ofs0_addr PATH ${option_setting_ofs0}) +dt_reg_addr(dualsel_addr PATH ${option_setting_dualsel}) +dt_reg_addr(ofs1_sec_addr PATH ${option_setting_ofs1_sec}) +dt_reg_addr(banksel_sec_addr PATH ${option_setting_banksel_sec}) +dt_reg_addr(bps_sec_addr PATH ${option_setting_bps_sec}) +dt_reg_addr(pbps_sec_addr PATH ${option_setting_pbps_sec}) +dt_reg_addr(ofs1_sel_addr PATH ${option_setting_ofs1_sel}) +dt_reg_addr(banksel_sel_addr PATH ${option_setting_banksel_sel}) +dt_reg_addr(bps_sel_addr PATH ${option_setting_bps_sel}) + +if(CONFIG_CMAKE_LINKER_GENERATOR) + zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) + zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") + zephyr_linker_section(NAME .option_setting_ofs0 GROUP OFS_OFS0_MEMORY ADDRESS ${ofs0_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") + zephyr_linker_section(NAME .option_setting_dualsel GROUP OFS_DUALSEL_MEMORY ADDRESS ${dualsel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_dualsel KEEP INPUT ".option_setting_dualsel*") + zephyr_linker_section(NAME .option_setting_ofs1_sec GROUP OFS_OFS1_SEC_MEMORY ADDRESS ${ofs1_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs1_sec KEEP INPUT ".option_setting_ofs1_sec*") + zephyr_linker_section(NAME .option_setting_banksel_sec GROUP OFS_BANKSEL_SEC_MEMORY ADDRESS ${banksel_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_banksel_sec KEEP INPUT ".option_setting_banksel_sec*") + zephyr_linker_section(NAME .option_setting_ofs1_sel GROUP OFS_OFS1_SEL_MEMORY ADDRESS ${ofs1_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs1_sel KEEP INPUT ".option_setting_ofs1_sel*") + zephyr_linker_section(NAME .option_setting_banksel_sel GROUP OFS_BANKSEL_SEL_MEMORY ADDRESS ${banksel_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_banksel_sel KEEP INPUT ".option_setting_banksel_sel*") + zephyr_linker_section(NAME .option_setting_bps_sec GROUP OFS_BPS_SEC_MEMORY ADDRESS ${bps_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_bps_sec KEEP INPUT ".option_setting_bps_sec*") + zephyr_linker_section(NAME .option_setting_pbps_sec GROUP OFS_PBPS_SEC_MEMORY ADDRESS ${pbps_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_pbps_sec KEEP INPUT ".option_setting_pbps_sec*") + zephyr_linker_section(NAME .option_setting_bps_sel GROUP OFS_BPS_SEL_MEMORY ADDRESS ${bps_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_bps_sel KEEP INPUT ".option_setting_bps_sel*") +elseif(CONFIG_LD_LINKER_TEMPLATE) + zephyr_linker_sources(SECTIONS sections.ld) + zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) +endif() set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra6e2/CMakeLists.txt b/soc/renesas/ra/ra6e2/CMakeLists.txt index f8147e805910..0918f899601f 100644 --- a/soc/renesas/ra/ra6e2/CMakeLists.txt +++ b/soc/renesas/ra/ra6e2/CMakeLists.txt @@ -7,7 +7,34 @@ zephyr_sources( soc.c ) -zephyr_linker_sources(SECTIONS sections.ld) -zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) +dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") +dt_nodelabel(option_setting_osis NODELABEL "option_setting_osis") +dt_nodelabel(option_setting_ofs1_sec NODELABEL "option_setting_ofs1_sec") +dt_nodelabel(option_setting_bps_sec NODELABEL "option_setting_bps_sec") +dt_nodelabel(option_setting_pbps_sec NODELABEL "option_setting_pbps_sec") + +dt_reg_addr(ofs0_addr PATH ${option_setting_ofs0}) +dt_reg_addr(osis_addr PATH ${option_setting_osis}) +dt_reg_addr(ofs1_sec_addr PATH ${option_setting_ofs1_sec}) +dt_reg_addr(bps_sec_addr PATH ${option_setting_bps_sec}) +dt_reg_addr(pbps_sec_addr PATH ${option_setting_pbps_sec}) + +if(CONFIG_CMAKE_LINKER_GENERATOR) + zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) + zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") + zephyr_linker_section(NAME .option_setting_ofs0 GROUP OFS_OFS0_MEMORY ADDRESS ${ofs0_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") + zephyr_linker_section(NAME .option_setting_osis GROUP OFS_OSIS_MEMORY ADDRESS ${osis_addr}) + zephyr_linker_section_configure(SECTION .option_setting_osis KEEP INPUT ".option_setting_osis*") + zephyr_linker_section(NAME .option_setting_ofs1_sec GROUP OFS_OFS1_SEC_MEMORY ADDRESS ${ofs1_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs1_sec KEEP INPUT ".option_setting_ofs1_sec*") + zephyr_linker_section(NAME .option_setting_bps_sec GROUP OFS_BPS_SEC_MEMORY ADDRESS ${bps_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_bps_sec KEEP INPUT ".option_setting_bps_sec*") + zephyr_linker_section(NAME .option_setting_pbps_sec GROUP OFS_PBPS_SEC_MEMORY ADDRESS ${pbps_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_pbps_sec KEEP INPUT ".option_setting_pbps_sec*") +elseif(CONFIG_LD_LINKER_TEMPLATE) + zephyr_linker_sources(SECTIONS sections.ld) + zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) +endif() set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra6m1/CMakeLists.txt b/soc/renesas/ra/ra6m1/CMakeLists.txt index 6d685a499965..36a5f177990b 100644 --- a/soc/renesas/ra/ra6m1/CMakeLists.txt +++ b/soc/renesas/ra/ra6m1/CMakeLists.txt @@ -7,9 +7,31 @@ zephyr_sources( soc.c ) -zephyr_linker_sources(ROM_START rom_start.ld) +dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") +dt_nodelabel(option_setting_ofs1 NODELABEL "option_setting_ofs1") +dt_nodelabel(option_setting_secmpu NODELABEL "option_setting_secmpu") +dt_nodelabel(option_setting_osis NODELABEL "option_setting_osis") -zephyr_linker_sources(SECTIONS sections.ld) -zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) +dt_reg_addr(ofs0_addr PATH ${option_setting_ofs0}) +dt_reg_addr(ofs1_addr PATH ${option_setting_ofs1}) +dt_reg_addr(secmpu_addr PATH ${option_setting_secmpu}) +dt_reg_addr(osis_addr PATH ${option_setting_osis}) + +if(CONFIG_CMAKE_LINKER_GENERATOR) + zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) + zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") + zephyr_linker_section(NAME .option_setting_ofs0 GROUP FLASH ADDRESS ${ofs0_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") + zephyr_linker_section(NAME .option_setting_ofs1 GROUP FLASH ADDRESS ${ofs1_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs1 KEEP INPUT ".option_setting_ofs1*") + zephyr_linker_section(NAME .option_setting_secmpu GROUP FLASH ADDRESS ${secmpu_addr}) + zephyr_linker_section_configure(SECTION .option_setting_secmpu KEEP INPUT ".option_setting_secmpu*") + zephyr_linker_section(NAME .option_setting_osis GROUP OFS_OSIS_MEMORY ADDRESS ${osis_addr}) + zephyr_linker_section_configure(SECTION .option_setting_osis KEEP INPUT ".option_setting_osis*") +elseif(CONFIG_LD_LINKER_TEMPLATE) + zephyr_linker_sources(ROM_START rom_start.ld) + zephyr_linker_sources(SECTIONS sections.ld) + zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) +endif() set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra6m2/CMakeLists.txt b/soc/renesas/ra/ra6m2/CMakeLists.txt index 6d685a499965..36a5f177990b 100644 --- a/soc/renesas/ra/ra6m2/CMakeLists.txt +++ b/soc/renesas/ra/ra6m2/CMakeLists.txt @@ -7,9 +7,31 @@ zephyr_sources( soc.c ) -zephyr_linker_sources(ROM_START rom_start.ld) +dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") +dt_nodelabel(option_setting_ofs1 NODELABEL "option_setting_ofs1") +dt_nodelabel(option_setting_secmpu NODELABEL "option_setting_secmpu") +dt_nodelabel(option_setting_osis NODELABEL "option_setting_osis") -zephyr_linker_sources(SECTIONS sections.ld) -zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) +dt_reg_addr(ofs0_addr PATH ${option_setting_ofs0}) +dt_reg_addr(ofs1_addr PATH ${option_setting_ofs1}) +dt_reg_addr(secmpu_addr PATH ${option_setting_secmpu}) +dt_reg_addr(osis_addr PATH ${option_setting_osis}) + +if(CONFIG_CMAKE_LINKER_GENERATOR) + zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) + zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") + zephyr_linker_section(NAME .option_setting_ofs0 GROUP FLASH ADDRESS ${ofs0_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") + zephyr_linker_section(NAME .option_setting_ofs1 GROUP FLASH ADDRESS ${ofs1_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs1 KEEP INPUT ".option_setting_ofs1*") + zephyr_linker_section(NAME .option_setting_secmpu GROUP FLASH ADDRESS ${secmpu_addr}) + zephyr_linker_section_configure(SECTION .option_setting_secmpu KEEP INPUT ".option_setting_secmpu*") + zephyr_linker_section(NAME .option_setting_osis GROUP OFS_OSIS_MEMORY ADDRESS ${osis_addr}) + zephyr_linker_section_configure(SECTION .option_setting_osis KEEP INPUT ".option_setting_osis*") +elseif(CONFIG_LD_LINKER_TEMPLATE) + zephyr_linker_sources(ROM_START rom_start.ld) + zephyr_linker_sources(SECTIONS sections.ld) + zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) +endif() set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra6m3/CMakeLists.txt b/soc/renesas/ra/ra6m3/CMakeLists.txt index 6d685a499965..36a5f177990b 100644 --- a/soc/renesas/ra/ra6m3/CMakeLists.txt +++ b/soc/renesas/ra/ra6m3/CMakeLists.txt @@ -7,9 +7,31 @@ zephyr_sources( soc.c ) -zephyr_linker_sources(ROM_START rom_start.ld) +dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") +dt_nodelabel(option_setting_ofs1 NODELABEL "option_setting_ofs1") +dt_nodelabel(option_setting_secmpu NODELABEL "option_setting_secmpu") +dt_nodelabel(option_setting_osis NODELABEL "option_setting_osis") -zephyr_linker_sources(SECTIONS sections.ld) -zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) +dt_reg_addr(ofs0_addr PATH ${option_setting_ofs0}) +dt_reg_addr(ofs1_addr PATH ${option_setting_ofs1}) +dt_reg_addr(secmpu_addr PATH ${option_setting_secmpu}) +dt_reg_addr(osis_addr PATH ${option_setting_osis}) + +if(CONFIG_CMAKE_LINKER_GENERATOR) + zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) + zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") + zephyr_linker_section(NAME .option_setting_ofs0 GROUP FLASH ADDRESS ${ofs0_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") + zephyr_linker_section(NAME .option_setting_ofs1 GROUP FLASH ADDRESS ${ofs1_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs1 KEEP INPUT ".option_setting_ofs1*") + zephyr_linker_section(NAME .option_setting_secmpu GROUP FLASH ADDRESS ${secmpu_addr}) + zephyr_linker_section_configure(SECTION .option_setting_secmpu KEEP INPUT ".option_setting_secmpu*") + zephyr_linker_section(NAME .option_setting_osis GROUP OFS_OSIS_MEMORY ADDRESS ${osis_addr}) + zephyr_linker_section_configure(SECTION .option_setting_osis KEEP INPUT ".option_setting_osis*") +elseif(CONFIG_LD_LINKER_TEMPLATE) + zephyr_linker_sources(ROM_START rom_start.ld) + zephyr_linker_sources(SECTIONS sections.ld) + zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) +endif() set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra6m4/CMakeLists.txt b/soc/renesas/ra/ra6m4/CMakeLists.txt index 6b526e37972f..49d3c9d48bd7 100644 --- a/soc/renesas/ra/ra6m4/CMakeLists.txt +++ b/soc/renesas/ra/ra6m4/CMakeLists.txt @@ -7,8 +7,51 @@ zephyr_sources( soc.c ) -zephyr_linker_sources(SECTIONS sections.ld) -zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) +dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") +dt_nodelabel(option_setting_dualsel NODELABEL "option_setting_dualsel") +dt_nodelabel(option_setting_ofs1_sec NODELABEL "option_setting_ofs1_sec") +dt_nodelabel(option_setting_banksel_sec NODELABEL "option_setting_banksel_sec") +dt_nodelabel(option_setting_bps_sec NODELABEL "option_setting_bps_sec") +dt_nodelabel(option_setting_pbps_sec NODELABEL "option_setting_pbps_sec") +dt_nodelabel(option_setting_ofs1_sel NODELABEL "option_setting_ofs1_sel") +dt_nodelabel(option_setting_banksel_sel NODELABEL "option_setting_banksel_sel") +dt_nodelabel(option_setting_bps_sel NODELABEL "option_setting_bps_sel") + +dt_reg_addr(ofs0_addr PATH ${option_setting_ofs0}) +dt_reg_addr(dualsel_addr PATH ${option_setting_dualsel}) +dt_reg_addr(ofs1_sec_addr PATH ${option_setting_ofs1_sec}) +dt_reg_addr(banksel_sec_addr PATH ${option_setting_banksel_sec}) +dt_reg_addr(bps_sec_addr PATH ${option_setting_bps_sec}) +dt_reg_addr(pbps_sec_addr PATH ${option_setting_pbps_sec}) +dt_reg_addr(ofs1_sel_addr PATH ${option_setting_ofs1_sel}) +dt_reg_addr(banksel_sel_addr PATH ${option_setting_banksel_sel}) +dt_reg_addr(bps_sel_addr PATH ${option_setting_bps_sel}) + +if(CONFIG_CMAKE_LINKER_GENERATOR) + zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) + zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") + zephyr_linker_section(NAME .option_setting_ofs0 GROUP OFS_OFS0_MEMORY ADDRESS ${ofs0_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") + zephyr_linker_section(NAME .option_setting_dualsel GROUP OFS_DUALSEL_MEMORY ADDRESS ${dualsel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_dualsel KEEP INPUT ".option_setting_dualsel*") + zephyr_linker_section(NAME .option_setting_ofs1_sec GROUP OFS_OFS1_SEC_MEMORY ADDRESS ${ofs1_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs1_sec KEEP INPUT ".option_setting_ofs1_sec*") + zephyr_linker_section(NAME .option_setting_banksel_sec GROUP OFS_BANKSEL_SEC_MEMORY ADDRESS ${banksel_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_banksel_sec KEEP INPUT ".option_setting_banksel_sec*") + zephyr_linker_section(NAME .option_setting_ofs1_sel GROUP OFS_OFS1_SEL_MEMORY ADDRESS ${ofs1_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs1_sel KEEP INPUT ".option_setting_ofs1_sel*") + zephyr_linker_section(NAME .option_setting_banksel_sel GROUP OFS_BANKSEL_SEL_MEMORY ADDRESS ${banksel_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_banksel_sel KEEP INPUT ".option_setting_banksel_sel*") + zephyr_linker_section(NAME .option_setting_bps_sec GROUP OFS_BPS_SEC_MEMORY ADDRESS ${bps_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_bps_sec KEEP INPUT ".option_setting_bps_sec*") + zephyr_linker_section(NAME .option_setting_pbps_sec GROUP OFS_PBPS_SEC_MEMORY ADDRESS ${pbps_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_pbps_sec KEEP INPUT ".option_setting_pbps_sec*") + zephyr_linker_section(NAME .option_setting_bps_sel GROUP OFS_BPS_SEL_MEMORY ADDRESS ${bps_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_bps_sel KEEP INPUT ".option_setting_bps_sel*") +elseif(CONFIG_LD_LINKER_TEMPLATE) + zephyr_linker_sources(SECTIONS sections.ld) + zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) +endif() if(CONFIG_ETH_RENESAS_RA_USE_NS_BUF) # In ra6m4 ethernet peripheral is always non-secure, even in flat project. diff --git a/soc/renesas/ra/ra6m5/CMakeLists.txt b/soc/renesas/ra/ra6m5/CMakeLists.txt index 9fa416963475..693af82ebaab 100644 --- a/soc/renesas/ra/ra6m5/CMakeLists.txt +++ b/soc/renesas/ra/ra6m5/CMakeLists.txt @@ -7,8 +7,51 @@ zephyr_sources( soc.c ) -zephyr_linker_sources(SECTIONS sections.ld) -zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) +dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") +dt_nodelabel(option_setting_dualsel NODELABEL "option_setting_dualsel") +dt_nodelabel(option_setting_ofs1_sec NODELABEL "option_setting_ofs1_sec") +dt_nodelabel(option_setting_banksel_sec NODELABEL "option_setting_banksel_sec") +dt_nodelabel(option_setting_bps_sec NODELABEL "option_setting_bps_sec") +dt_nodelabel(option_setting_pbps_sec NODELABEL "option_setting_pbps_sec") +dt_nodelabel(option_setting_ofs1_sel NODELABEL "option_setting_ofs1_sel") +dt_nodelabel(option_setting_banksel_sel NODELABEL "option_setting_banksel_sel") +dt_nodelabel(option_setting_bps_sel NODELABEL "option_setting_bps_sel") + +dt_reg_addr(ofs0_addr PATH ${option_setting_ofs0}) +dt_reg_addr(dualsel_addr PATH ${option_setting_dualsel}) +dt_reg_addr(ofs1_sec_addr PATH ${option_setting_ofs1_sec}) +dt_reg_addr(banksel_sec_addr PATH ${option_setting_banksel_sec}) +dt_reg_addr(bps_sec_addr PATH ${option_setting_bps_sec}) +dt_reg_addr(pbps_sec_addr PATH ${option_setting_pbps_sec}) +dt_reg_addr(ofs1_sel_addr PATH ${option_setting_ofs1_sel}) +dt_reg_addr(banksel_sel_addr PATH ${option_setting_banksel_sel}) +dt_reg_addr(bps_sel_addr PATH ${option_setting_bps_sel}) + +if(CONFIG_CMAKE_LINKER_GENERATOR) + zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) + zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") + zephyr_linker_section(NAME .option_setting_ofs0 GROUP OFS_OFS0_MEMORY ADDRESS ${ofs0_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") + zephyr_linker_section(NAME .option_setting_dualsel GROUP OFS_DUALSEL_MEMORY ADDRESS ${dualsel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_dualsel KEEP INPUT ".option_setting_dualsel*") + zephyr_linker_section(NAME .option_setting_ofs1_sec GROUP OFS_OFS1_SEC_MEMORY ADDRESS ${ofs1_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs1_sec KEEP INPUT ".option_setting_ofs1_sec*") + zephyr_linker_section(NAME .option_setting_banksel_sec GROUP OFS_BANKSEL_SEC_MEMORY ADDRESS ${banksel_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_banksel_sec KEEP INPUT ".option_setting_banksel_sec*") + zephyr_linker_section(NAME .option_setting_ofs1_sel GROUP OFS_OFS1_SEL_MEMORY ADDRESS ${ofs1_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs1_sel KEEP INPUT ".option_setting_ofs1_sel*") + zephyr_linker_section(NAME .option_setting_banksel_sel GROUP OFS_BANKSEL_SEL_MEMORY ADDRESS ${banksel_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_banksel_sel KEEP INPUT ".option_setting_banksel_sel*") + zephyr_linker_section(NAME .option_setting_bps_sec GROUP OFS_BPS_SEC_MEMORY ADDRESS ${bps_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_bps_sec KEEP INPUT ".option_setting_bps_sec*") + zephyr_linker_section(NAME .option_setting_pbps_sec GROUP OFS_PBPS_SEC_MEMORY ADDRESS ${pbps_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_pbps_sec KEEP INPUT ".option_setting_pbps_sec*") + zephyr_linker_section(NAME .option_setting_bps_sel GROUP OFS_BPS_SEL_MEMORY ADDRESS ${bps_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_bps_sel KEEP INPUT ".option_setting_bps_sel*") +elseif(CONFIG_LD_LINKER_TEMPLATE) + zephyr_linker_sources(SECTIONS sections.ld) + zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) +endif() if(CONFIG_ETH_RENESAS_RA_USE_NS_BUF) # In ra6m5 ethernet peripheral is always non-secure, even in flat project. diff --git a/soc/renesas/ra/ra8d1/CMakeLists.txt b/soc/renesas/ra/ra8d1/CMakeLists.txt index 627bfa4063ed..956a3e7bb0ff 100644 --- a/soc/renesas/ra/ra8d1/CMakeLists.txt +++ b/soc/renesas/ra/ra8d1/CMakeLists.txt @@ -11,7 +11,54 @@ zephyr_sources_ifdef(CONFIG_PM power.c ) -zephyr_linker_sources(SECTIONS sections.ld) -zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) +dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") +dt_nodelabel(option_setting_ofs2 NODELABEL "option_setting_ofs2") +dt_nodelabel(option_setting_dualsel NODELABEL "option_setting_dualsel") +dt_nodelabel(option_setting_ofs1_sec NODELABEL "option_setting_ofs1_sec") +dt_nodelabel(option_setting_banksel_sec NODELABEL "option_setting_banksel_sec") +dt_nodelabel(option_setting_bps_sec NODELABEL "option_setting_bps_sec") +dt_nodelabel(option_setting_pbps_sec NODELABEL "option_setting_pbps_sec") +dt_nodelabel(option_setting_ofs1_sel NODELABEL "option_setting_ofs1_sel") +dt_nodelabel(option_setting_banksel_sel NODELABEL "option_setting_banksel_sel") +dt_nodelabel(option_setting_bps_sel NODELABEL "option_setting_bps_sel") + +dt_reg_addr(ofs0_addr PATH ${option_setting_ofs0}) +dt_reg_addr(ofs2_addr PATH ${option_setting_ofs2}) +dt_reg_addr(dualsel_addr PATH ${option_setting_dualsel}) +dt_reg_addr(ofs1_sec_addr PATH ${option_setting_ofs1_sec}) +dt_reg_addr(banksel_sec_addr PATH ${option_setting_banksel_sec}) +dt_reg_addr(bps_sec_addr PATH ${option_setting_bps_sec}) +dt_reg_addr(otp_pbps_sec_addr PATH ${option_setting_pbps_sec}) +dt_reg_addr(ofs1_sel_addr PATH ${option_setting_ofs1_sel}) +dt_reg_addr(banksel_sel_addr PATH ${option_setting_banksel_sel}) +dt_reg_addr(bps_sel_addr PATH ${option_setting_bps_sel}) + +if(CONFIG_CMAKE_LINKER_GENERATOR) + zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) + zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") + zephyr_linker_section(NAME .option_setting_ofs0 GROUP OFS_OFS0_MEMORY ADDRESS ${ofs0_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") + zephyr_linker_section(NAME .option_setting_ofs2 GROUP OFS_OFS2_MEMORY ADDRESS ${ofs2_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs2 KEEP INPUT ".option_setting_ofs2*") + zephyr_linker_section(NAME .option_setting_dualsel GROUP OFS_DUALSEL_MEMORY ADDRESS ${dualsel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_dualsel KEEP INPUT ".option_setting_dualsel*") + zephyr_linker_section(NAME .option_setting_ofs1_sec GROUP OFS_OFS1_SEC_MEMORY ADDRESS ${ofs1_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs1_sec KEEP INPUT ".option_setting_ofs1_sec*") + zephyr_linker_section(NAME .option_setting_banksel_sec GROUP OFS_BANKSEL_SEC_MEMORY ADDRESS ${banksel_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_banksel_sec KEEP INPUT ".option_setting_banksel_sec*") + zephyr_linker_section(NAME .option_setting_ofs1_sel GROUP OFS_OFS1_SEL_MEMORY ADDRESS ${ofs1_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs1_sel KEEP INPUT ".option_setting_ofs1_sel*") + zephyr_linker_section(NAME .option_setting_banksel_sel GROUP OFS_BANKSEL_SEL_MEMORY ADDRESS ${banksel_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_banksel_sel KEEP INPUT ".option_setting_banksel_sel*") + zephyr_linker_section(NAME .option_setting_bps_sec GROUP OFS_BPS_SEC_MEMORY ADDRESS ${bps_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_bps_sec KEEP INPUT ".option_setting_bps_sec*") + zephyr_linker_section(NAME .option_setting_pbps_sec GROUP OFS_PBPS_SEC_MEMORY ADDRESS ${otp_pbps_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_pbps_sec KEEP INPUT ".option_setting_pbps_sec*") + zephyr_linker_section(NAME .option_setting_bps_sel GROUP OFS_BPS_SEL_MEMORY ADDRESS ${bps_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_bps_sel KEEP INPUT ".option_setting_bps_sel*") +elseif(CONFIG_LD_LINKER_TEMPLATE) + zephyr_linker_sources(SECTIONS sections.ld) + zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) +endif() set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra8d2/CMakeLists.txt b/soc/renesas/ra/ra8d2/CMakeLists.txt index 7f3c66c46e47..9782f69e5390 100644 --- a/soc/renesas/ra/ra8d2/CMakeLists.txt +++ b/soc/renesas/ra/ra8d2/CMakeLists.txt @@ -11,7 +11,50 @@ zephyr_sources_ifdef(CONFIG_PM power.c ) -zephyr_linker_sources(SECTIONS sections.ld) -zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) +dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") +dt_nodelabel(option_setting_ofs2 NODELABEL "option_setting_ofs2") +dt_nodelabel(option_setting_sas NODELABEL "option_setting_sas") +dt_nodelabel(option_setting_ofs1_sec NODELABEL "option_setting_ofs1_sec") +dt_nodelabel(option_setting_ofs3_sec NODELABEL "option_setting_ofs3_sec") +dt_nodelabel(option_setting_ofs1_sel NODELABEL "option_setting_ofs1_sel") +dt_nodelabel(option_setting_ofs3_sel NODELABEL "option_setting_ofs3_sel") +dt_nodelabel(option_setting_bps_sec NODELABEL "option_setting_bps_sec") +dt_nodelabel(option_setting_otp_pbps_sec NODELABEL "option_setting_otp_pbps_sec") + +dt_reg_addr(ofs0_addr PATH ${option_setting_ofs0}) +dt_reg_addr(ofs2_addr PATH ${option_setting_ofs2}) +dt_reg_addr(sas_addr PATH ${option_setting_sas}) +dt_reg_addr(ofs1_sec_addr PATH ${option_setting_ofs1_sec}) +dt_reg_addr(ofs3_sec_addr PATH ${option_setting_ofs3_sec}) +dt_reg_addr(ofs1_sel_addr PATH ${option_setting_ofs1_sel}) +dt_reg_addr(ofs3_sel_addr PATH ${option_setting_ofs3_sel}) +dt_reg_addr(bps_sec_addr PATH ${option_setting_bps_sec}) +dt_reg_addr(otp_pbps_sec_addr PATH ${option_setting_otp_pbps_sec}) + +if(CONFIG_CMAKE_LINKER_GENERATOR) + zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) + zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") + zephyr_linker_section(NAME .option_setting_ofs0 GROUP OFS_OFS0_MEMORY ADDRESS ${ofs0_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") + zephyr_linker_section(NAME .option_setting_ofs2 GROUP OFS_OFS2_MEMORY ADDRESS ${ofs2_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs2 KEEP INPUT ".option_setting_ofs2*") + zephyr_linker_section(NAME .option_setting_sas GROUP OFS_SAS_MEMORY ADDRESS ${sas_addr}) + zephyr_linker_section_configure(SECTION .option_setting_sas KEEP INPUT ".option_setting_sas*") + zephyr_linker_section(NAME .option_setting_ofs1_sec GROUP OFS_OFS1_SEC_MEMORY ADDRESS ${ofs1_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs1_sec KEEP INPUT ".option_setting_ofs1_sec*") + zephyr_linker_section(NAME .option_setting_ofs3_sec GROUP OFS_OFS3_SEC_MEMORY ADDRESS ${ofs3_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs3_sec KEEP INPUT ".option_setting_ofs3_sec*") + zephyr_linker_section(NAME .option_setting_ofs1_sel GROUP OFS_OFS1_SEL_MEMORY ADDRESS ${ofs1_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs1_sel KEEP INPUT ".option_setting_ofs1_sel*") + zephyr_linker_section(NAME .option_setting_ofs3_sel GROUP OFS_OFS3_SEL_MEMORY ADDRESS ${ofs3_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs3_sel KEEP INPUT ".option_setting_ofs3_sel*") + zephyr_linker_section(NAME .option_setting_bps_sec GROUP OFS_BPS_SEC_MEMORY ADDRESS ${bps_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_bps_sec KEEP INPUT ".option_setting_bps_sec*") + zephyr_linker_section(NAME .option_setting_otp_pbps_sec GROUP OFS_OTP_PBPS_SEC_MEMORY ADDRESS ${otp_pbps_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_otp_pbps_sec KEEP INPUT ".option_setting_otp_pbps_sec*") +elseif(CONFIG_LD_LINKER_TEMPLATE) + zephyr_linker_sources(SECTIONS sections.ld) + zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) +endif() set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra8m1/CMakeLists.txt b/soc/renesas/ra/ra8m1/CMakeLists.txt index 627bfa4063ed..956a3e7bb0ff 100644 --- a/soc/renesas/ra/ra8m1/CMakeLists.txt +++ b/soc/renesas/ra/ra8m1/CMakeLists.txt @@ -11,7 +11,54 @@ zephyr_sources_ifdef(CONFIG_PM power.c ) -zephyr_linker_sources(SECTIONS sections.ld) -zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) +dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") +dt_nodelabel(option_setting_ofs2 NODELABEL "option_setting_ofs2") +dt_nodelabel(option_setting_dualsel NODELABEL "option_setting_dualsel") +dt_nodelabel(option_setting_ofs1_sec NODELABEL "option_setting_ofs1_sec") +dt_nodelabel(option_setting_banksel_sec NODELABEL "option_setting_banksel_sec") +dt_nodelabel(option_setting_bps_sec NODELABEL "option_setting_bps_sec") +dt_nodelabel(option_setting_pbps_sec NODELABEL "option_setting_pbps_sec") +dt_nodelabel(option_setting_ofs1_sel NODELABEL "option_setting_ofs1_sel") +dt_nodelabel(option_setting_banksel_sel NODELABEL "option_setting_banksel_sel") +dt_nodelabel(option_setting_bps_sel NODELABEL "option_setting_bps_sel") + +dt_reg_addr(ofs0_addr PATH ${option_setting_ofs0}) +dt_reg_addr(ofs2_addr PATH ${option_setting_ofs2}) +dt_reg_addr(dualsel_addr PATH ${option_setting_dualsel}) +dt_reg_addr(ofs1_sec_addr PATH ${option_setting_ofs1_sec}) +dt_reg_addr(banksel_sec_addr PATH ${option_setting_banksel_sec}) +dt_reg_addr(bps_sec_addr PATH ${option_setting_bps_sec}) +dt_reg_addr(otp_pbps_sec_addr PATH ${option_setting_pbps_sec}) +dt_reg_addr(ofs1_sel_addr PATH ${option_setting_ofs1_sel}) +dt_reg_addr(banksel_sel_addr PATH ${option_setting_banksel_sel}) +dt_reg_addr(bps_sel_addr PATH ${option_setting_bps_sel}) + +if(CONFIG_CMAKE_LINKER_GENERATOR) + zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) + zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") + zephyr_linker_section(NAME .option_setting_ofs0 GROUP OFS_OFS0_MEMORY ADDRESS ${ofs0_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") + zephyr_linker_section(NAME .option_setting_ofs2 GROUP OFS_OFS2_MEMORY ADDRESS ${ofs2_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs2 KEEP INPUT ".option_setting_ofs2*") + zephyr_linker_section(NAME .option_setting_dualsel GROUP OFS_DUALSEL_MEMORY ADDRESS ${dualsel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_dualsel KEEP INPUT ".option_setting_dualsel*") + zephyr_linker_section(NAME .option_setting_ofs1_sec GROUP OFS_OFS1_SEC_MEMORY ADDRESS ${ofs1_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs1_sec KEEP INPUT ".option_setting_ofs1_sec*") + zephyr_linker_section(NAME .option_setting_banksel_sec GROUP OFS_BANKSEL_SEC_MEMORY ADDRESS ${banksel_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_banksel_sec KEEP INPUT ".option_setting_banksel_sec*") + zephyr_linker_section(NAME .option_setting_ofs1_sel GROUP OFS_OFS1_SEL_MEMORY ADDRESS ${ofs1_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs1_sel KEEP INPUT ".option_setting_ofs1_sel*") + zephyr_linker_section(NAME .option_setting_banksel_sel GROUP OFS_BANKSEL_SEL_MEMORY ADDRESS ${banksel_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_banksel_sel KEEP INPUT ".option_setting_banksel_sel*") + zephyr_linker_section(NAME .option_setting_bps_sec GROUP OFS_BPS_SEC_MEMORY ADDRESS ${bps_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_bps_sec KEEP INPUT ".option_setting_bps_sec*") + zephyr_linker_section(NAME .option_setting_pbps_sec GROUP OFS_PBPS_SEC_MEMORY ADDRESS ${otp_pbps_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_pbps_sec KEEP INPUT ".option_setting_pbps_sec*") + zephyr_linker_section(NAME .option_setting_bps_sel GROUP OFS_BPS_SEL_MEMORY ADDRESS ${bps_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_bps_sel KEEP INPUT ".option_setting_bps_sel*") +elseif(CONFIG_LD_LINKER_TEMPLATE) + zephyr_linker_sources(SECTIONS sections.ld) + zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) +endif() set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra8m2/CMakeLists.txt b/soc/renesas/ra/ra8m2/CMakeLists.txt index 7f3c66c46e47..9782f69e5390 100644 --- a/soc/renesas/ra/ra8m2/CMakeLists.txt +++ b/soc/renesas/ra/ra8m2/CMakeLists.txt @@ -11,7 +11,50 @@ zephyr_sources_ifdef(CONFIG_PM power.c ) -zephyr_linker_sources(SECTIONS sections.ld) -zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) +dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") +dt_nodelabel(option_setting_ofs2 NODELABEL "option_setting_ofs2") +dt_nodelabel(option_setting_sas NODELABEL "option_setting_sas") +dt_nodelabel(option_setting_ofs1_sec NODELABEL "option_setting_ofs1_sec") +dt_nodelabel(option_setting_ofs3_sec NODELABEL "option_setting_ofs3_sec") +dt_nodelabel(option_setting_ofs1_sel NODELABEL "option_setting_ofs1_sel") +dt_nodelabel(option_setting_ofs3_sel NODELABEL "option_setting_ofs3_sel") +dt_nodelabel(option_setting_bps_sec NODELABEL "option_setting_bps_sec") +dt_nodelabel(option_setting_otp_pbps_sec NODELABEL "option_setting_otp_pbps_sec") + +dt_reg_addr(ofs0_addr PATH ${option_setting_ofs0}) +dt_reg_addr(ofs2_addr PATH ${option_setting_ofs2}) +dt_reg_addr(sas_addr PATH ${option_setting_sas}) +dt_reg_addr(ofs1_sec_addr PATH ${option_setting_ofs1_sec}) +dt_reg_addr(ofs3_sec_addr PATH ${option_setting_ofs3_sec}) +dt_reg_addr(ofs1_sel_addr PATH ${option_setting_ofs1_sel}) +dt_reg_addr(ofs3_sel_addr PATH ${option_setting_ofs3_sel}) +dt_reg_addr(bps_sec_addr PATH ${option_setting_bps_sec}) +dt_reg_addr(otp_pbps_sec_addr PATH ${option_setting_otp_pbps_sec}) + +if(CONFIG_CMAKE_LINKER_GENERATOR) + zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) + zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") + zephyr_linker_section(NAME .option_setting_ofs0 GROUP OFS_OFS0_MEMORY ADDRESS ${ofs0_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") + zephyr_linker_section(NAME .option_setting_ofs2 GROUP OFS_OFS2_MEMORY ADDRESS ${ofs2_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs2 KEEP INPUT ".option_setting_ofs2*") + zephyr_linker_section(NAME .option_setting_sas GROUP OFS_SAS_MEMORY ADDRESS ${sas_addr}) + zephyr_linker_section_configure(SECTION .option_setting_sas KEEP INPUT ".option_setting_sas*") + zephyr_linker_section(NAME .option_setting_ofs1_sec GROUP OFS_OFS1_SEC_MEMORY ADDRESS ${ofs1_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs1_sec KEEP INPUT ".option_setting_ofs1_sec*") + zephyr_linker_section(NAME .option_setting_ofs3_sec GROUP OFS_OFS3_SEC_MEMORY ADDRESS ${ofs3_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs3_sec KEEP INPUT ".option_setting_ofs3_sec*") + zephyr_linker_section(NAME .option_setting_ofs1_sel GROUP OFS_OFS1_SEL_MEMORY ADDRESS ${ofs1_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs1_sel KEEP INPUT ".option_setting_ofs1_sel*") + zephyr_linker_section(NAME .option_setting_ofs3_sel GROUP OFS_OFS3_SEL_MEMORY ADDRESS ${ofs3_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs3_sel KEEP INPUT ".option_setting_ofs3_sel*") + zephyr_linker_section(NAME .option_setting_bps_sec GROUP OFS_BPS_SEC_MEMORY ADDRESS ${bps_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_bps_sec KEEP INPUT ".option_setting_bps_sec*") + zephyr_linker_section(NAME .option_setting_otp_pbps_sec GROUP OFS_OTP_PBPS_SEC_MEMORY ADDRESS ${otp_pbps_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_otp_pbps_sec KEEP INPUT ".option_setting_otp_pbps_sec*") +elseif(CONFIG_LD_LINKER_TEMPLATE) + zephyr_linker_sources(SECTIONS sections.ld) + zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) +endif() set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra8p1/CMakeLists.txt b/soc/renesas/ra/ra8p1/CMakeLists.txt index 7f3c66c46e47..9782f69e5390 100644 --- a/soc/renesas/ra/ra8p1/CMakeLists.txt +++ b/soc/renesas/ra/ra8p1/CMakeLists.txt @@ -11,7 +11,50 @@ zephyr_sources_ifdef(CONFIG_PM power.c ) -zephyr_linker_sources(SECTIONS sections.ld) -zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) +dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") +dt_nodelabel(option_setting_ofs2 NODELABEL "option_setting_ofs2") +dt_nodelabel(option_setting_sas NODELABEL "option_setting_sas") +dt_nodelabel(option_setting_ofs1_sec NODELABEL "option_setting_ofs1_sec") +dt_nodelabel(option_setting_ofs3_sec NODELABEL "option_setting_ofs3_sec") +dt_nodelabel(option_setting_ofs1_sel NODELABEL "option_setting_ofs1_sel") +dt_nodelabel(option_setting_ofs3_sel NODELABEL "option_setting_ofs3_sel") +dt_nodelabel(option_setting_bps_sec NODELABEL "option_setting_bps_sec") +dt_nodelabel(option_setting_otp_pbps_sec NODELABEL "option_setting_otp_pbps_sec") + +dt_reg_addr(ofs0_addr PATH ${option_setting_ofs0}) +dt_reg_addr(ofs2_addr PATH ${option_setting_ofs2}) +dt_reg_addr(sas_addr PATH ${option_setting_sas}) +dt_reg_addr(ofs1_sec_addr PATH ${option_setting_ofs1_sec}) +dt_reg_addr(ofs3_sec_addr PATH ${option_setting_ofs3_sec}) +dt_reg_addr(ofs1_sel_addr PATH ${option_setting_ofs1_sel}) +dt_reg_addr(ofs3_sel_addr PATH ${option_setting_ofs3_sel}) +dt_reg_addr(bps_sec_addr PATH ${option_setting_bps_sec}) +dt_reg_addr(otp_pbps_sec_addr PATH ${option_setting_otp_pbps_sec}) + +if(CONFIG_CMAKE_LINKER_GENERATOR) + zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) + zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") + zephyr_linker_section(NAME .option_setting_ofs0 GROUP OFS_OFS0_MEMORY ADDRESS ${ofs0_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") + zephyr_linker_section(NAME .option_setting_ofs2 GROUP OFS_OFS2_MEMORY ADDRESS ${ofs2_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs2 KEEP INPUT ".option_setting_ofs2*") + zephyr_linker_section(NAME .option_setting_sas GROUP OFS_SAS_MEMORY ADDRESS ${sas_addr}) + zephyr_linker_section_configure(SECTION .option_setting_sas KEEP INPUT ".option_setting_sas*") + zephyr_linker_section(NAME .option_setting_ofs1_sec GROUP OFS_OFS1_SEC_MEMORY ADDRESS ${ofs1_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs1_sec KEEP INPUT ".option_setting_ofs1_sec*") + zephyr_linker_section(NAME .option_setting_ofs3_sec GROUP OFS_OFS3_SEC_MEMORY ADDRESS ${ofs3_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs3_sec KEEP INPUT ".option_setting_ofs3_sec*") + zephyr_linker_section(NAME .option_setting_ofs1_sel GROUP OFS_OFS1_SEL_MEMORY ADDRESS ${ofs1_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs1_sel KEEP INPUT ".option_setting_ofs1_sel*") + zephyr_linker_section(NAME .option_setting_ofs3_sel GROUP OFS_OFS3_SEL_MEMORY ADDRESS ${ofs3_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs3_sel KEEP INPUT ".option_setting_ofs3_sel*") + zephyr_linker_section(NAME .option_setting_bps_sec GROUP OFS_BPS_SEC_MEMORY ADDRESS ${bps_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_bps_sec KEEP INPUT ".option_setting_bps_sec*") + zephyr_linker_section(NAME .option_setting_otp_pbps_sec GROUP OFS_OTP_PBPS_SEC_MEMORY ADDRESS ${otp_pbps_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_otp_pbps_sec KEEP INPUT ".option_setting_otp_pbps_sec*") +elseif(CONFIG_LD_LINKER_TEMPLATE) + zephyr_linker_sources(SECTIONS sections.ld) + zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) +endif() set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra8t1/CMakeLists.txt b/soc/renesas/ra/ra8t1/CMakeLists.txt index 627bfa4063ed..956a3e7bb0ff 100644 --- a/soc/renesas/ra/ra8t1/CMakeLists.txt +++ b/soc/renesas/ra/ra8t1/CMakeLists.txt @@ -11,7 +11,54 @@ zephyr_sources_ifdef(CONFIG_PM power.c ) -zephyr_linker_sources(SECTIONS sections.ld) -zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) +dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") +dt_nodelabel(option_setting_ofs2 NODELABEL "option_setting_ofs2") +dt_nodelabel(option_setting_dualsel NODELABEL "option_setting_dualsel") +dt_nodelabel(option_setting_ofs1_sec NODELABEL "option_setting_ofs1_sec") +dt_nodelabel(option_setting_banksel_sec NODELABEL "option_setting_banksel_sec") +dt_nodelabel(option_setting_bps_sec NODELABEL "option_setting_bps_sec") +dt_nodelabel(option_setting_pbps_sec NODELABEL "option_setting_pbps_sec") +dt_nodelabel(option_setting_ofs1_sel NODELABEL "option_setting_ofs1_sel") +dt_nodelabel(option_setting_banksel_sel NODELABEL "option_setting_banksel_sel") +dt_nodelabel(option_setting_bps_sel NODELABEL "option_setting_bps_sel") + +dt_reg_addr(ofs0_addr PATH ${option_setting_ofs0}) +dt_reg_addr(ofs2_addr PATH ${option_setting_ofs2}) +dt_reg_addr(dualsel_addr PATH ${option_setting_dualsel}) +dt_reg_addr(ofs1_sec_addr PATH ${option_setting_ofs1_sec}) +dt_reg_addr(banksel_sec_addr PATH ${option_setting_banksel_sec}) +dt_reg_addr(bps_sec_addr PATH ${option_setting_bps_sec}) +dt_reg_addr(otp_pbps_sec_addr PATH ${option_setting_pbps_sec}) +dt_reg_addr(ofs1_sel_addr PATH ${option_setting_ofs1_sel}) +dt_reg_addr(banksel_sel_addr PATH ${option_setting_banksel_sel}) +dt_reg_addr(bps_sel_addr PATH ${option_setting_bps_sel}) + +if(CONFIG_CMAKE_LINKER_GENERATOR) + zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) + zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") + zephyr_linker_section(NAME .option_setting_ofs0 GROUP OFS_OFS0_MEMORY ADDRESS ${ofs0_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") + zephyr_linker_section(NAME .option_setting_ofs2 GROUP OFS_OFS2_MEMORY ADDRESS ${ofs2_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs2 KEEP INPUT ".option_setting_ofs2*") + zephyr_linker_section(NAME .option_setting_dualsel GROUP OFS_DUALSEL_MEMORY ADDRESS ${dualsel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_dualsel KEEP INPUT ".option_setting_dualsel*") + zephyr_linker_section(NAME .option_setting_ofs1_sec GROUP OFS_OFS1_SEC_MEMORY ADDRESS ${ofs1_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs1_sec KEEP INPUT ".option_setting_ofs1_sec*") + zephyr_linker_section(NAME .option_setting_banksel_sec GROUP OFS_BANKSEL_SEC_MEMORY ADDRESS ${banksel_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_banksel_sec KEEP INPUT ".option_setting_banksel_sec*") + zephyr_linker_section(NAME .option_setting_ofs1_sel GROUP OFS_OFS1_SEL_MEMORY ADDRESS ${ofs1_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs1_sel KEEP INPUT ".option_setting_ofs1_sel*") + zephyr_linker_section(NAME .option_setting_banksel_sel GROUP OFS_BANKSEL_SEL_MEMORY ADDRESS ${banksel_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_banksel_sel KEEP INPUT ".option_setting_banksel_sel*") + zephyr_linker_section(NAME .option_setting_bps_sec GROUP OFS_BPS_SEC_MEMORY ADDRESS ${bps_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_bps_sec KEEP INPUT ".option_setting_bps_sec*") + zephyr_linker_section(NAME .option_setting_pbps_sec GROUP OFS_PBPS_SEC_MEMORY ADDRESS ${otp_pbps_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_pbps_sec KEEP INPUT ".option_setting_pbps_sec*") + zephyr_linker_section(NAME .option_setting_bps_sel GROUP OFS_BPS_SEL_MEMORY ADDRESS ${bps_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_bps_sel KEEP INPUT ".option_setting_bps_sel*") +elseif(CONFIG_LD_LINKER_TEMPLATE) + zephyr_linker_sources(SECTIONS sections.ld) + zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) +endif() set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") From 661536331ff3d65758c3e5c7bb10f7c87d086663 Mon Sep 17 00:00:00 2001 From: Thinh Le Cong Date: Mon, 10 Nov 2025 11:19:59 +0700 Subject: [PATCH 0674/3659] soc: renesas: ra: Add condition check for special cases Add condition check for dts node and multi-image build Signed-off-by: Thinh Le Cong --- soc/renesas/ra/ra2a1/CMakeLists.txt | 40 +++++--- soc/renesas/ra/ra2l1/CMakeLists.txt | 42 ++++++--- soc/renesas/ra/ra4c1/CMakeLists.txt | 123 +++++++++++++++++-------- soc/renesas/ra/ra4e1/CMakeLists.txt | 87 ++++++++++++------ soc/renesas/ra/ra4e2/CMakeLists.txt | 75 ++++++++++----- soc/renesas/ra/ra4l1/CMakeLists.txt | 123 +++++++++++++++++-------- soc/renesas/ra/ra4m1/CMakeLists.txt | 44 ++++++--- soc/renesas/ra/ra4m2/CMakeLists.txt | 87 ++++++++++++------ soc/renesas/ra/ra4m3/CMakeLists.txt | 113 +++++++++++++++-------- soc/renesas/ra/ra4w1/CMakeLists.txt | 42 ++++++--- soc/renesas/ra/ra6e1/CMakeLists.txt | 125 ++++++++++++++++--------- soc/renesas/ra/ra6e2/CMakeLists.txt | 75 ++++++++++----- soc/renesas/ra/ra6m1/CMakeLists.txt | 42 ++++++--- soc/renesas/ra/ra6m2/CMakeLists.txt | 42 ++++++--- soc/renesas/ra/ra6m3/CMakeLists.txt | 42 ++++++--- soc/renesas/ra/ra6m4/CMakeLists.txt | 123 +++++++++++++++++-------- soc/renesas/ra/ra6m5/CMakeLists.txt | 123 +++++++++++++++++-------- soc/renesas/ra/ra8d1/CMakeLists.txt | 137 +++++++++++++++++++--------- soc/renesas/ra/ra8d2/CMakeLists.txt | 129 +++++++++++++++++--------- soc/renesas/ra/ra8m1/CMakeLists.txt | 137 +++++++++++++++++++--------- soc/renesas/ra/ra8m2/CMakeLists.txt | 129 +++++++++++++++++--------- soc/renesas/ra/ra8p1/CMakeLists.txt | 129 +++++++++++++++++--------- soc/renesas/ra/ra8t1/CMakeLists.txt | 137 +++++++++++++++++++--------- soc/renesas/ra/ra8t2/CMakeLists.txt | 129 +++++++++++++++++--------- 24 files changed, 1537 insertions(+), 738 deletions(-) diff --git a/soc/renesas/ra/ra2a1/CMakeLists.txt b/soc/renesas/ra/ra2a1/CMakeLists.txt index 6a1ea740c99e..a40c57077c89 100644 --- a/soc/renesas/ra/ra2a1/CMakeLists.txt +++ b/soc/renesas/ra/ra2a1/CMakeLists.txt @@ -8,31 +8,45 @@ zephyr_sources( soc.c ) -dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") -dt_nodelabel(option_setting_ofs1 NODELABEL "option_setting_ofs1") -dt_nodelabel(option_setting_secmpu NODELABEL "option_setting_secmpu") -dt_nodelabel(option_setting_osis NODELABEL "option_setting_osis") +if(CONFIG_CMAKE_LINKER_GENERATOR) + dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") + dt_nodelabel(option_setting_ofs1 NODELABEL "option_setting_ofs1") + dt_nodelabel(option_setting_secmpu NODELABEL "option_setting_secmpu") + dt_nodelabel(option_setting_osis NODELABEL "option_setting_osis") -dt_reg_addr(ofs0_addr PATH ${option_setting_ofs0}) -dt_reg_addr(ofs1_addr PATH ${option_setting_ofs1}) -dt_reg_addr(secmpu_addr PATH ${option_setting_secmpu}) -dt_reg_addr(osis_addr PATH ${option_setting_osis}) + dt_reg_addr(ofs0_addr PATH ${option_setting_ofs0}) + dt_reg_addr(ofs1_addr PATH ${option_setting_ofs1}) + dt_reg_addr(secmpu_addr PATH ${option_setting_secmpu}) + dt_reg_addr(osis_addr PATH ${option_setting_osis}) + + dt_node_has_status(osis_status PATH ${option_setting_osis} STATUS okay) + + if(CONFIG_USE_RA_FSP_DTC) + zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) + zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") + endif() -if(CONFIG_CMAKE_LINKER_GENERATOR) - zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) - zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") zephyr_linker_section(NAME .option_setting_ofs0 GROUP FLASH ADDRESS ${ofs0_addr}) zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") + zephyr_linker_section(NAME .option_setting_ofs1 GROUP FLASH ADDRESS ${ofs1_addr}) zephyr_linker_section_configure(SECTION .option_setting_ofs1 KEEP INPUT ".option_setting_ofs1*") + zephyr_linker_section(NAME .option_setting_secmpu GROUP FLASH ADDRESS ${secmpu_addr}) zephyr_linker_section_configure(SECTION .option_setting_secmpu KEEP INPUT ".option_setting_secmpu*") - zephyr_linker_section(NAME .option_setting_osis GROUP OFS_OSIS_MEMORY ADDRESS ${osis_addr}) - zephyr_linker_section_configure(SECTION .option_setting_osis KEEP INPUT ".option_setting_osis*") + + if(${osis_status}) + zephyr_linker_section(NAME .option_setting_osis GROUP OFS_OSIS_MEMORY ADDRESS ${osis_addr}) + zephyr_linker_section_configure(SECTION .option_setting_osis KEEP INPUT ".option_setting_osis*") + endif() + elseif(CONFIG_LD_LINKER_TEMPLATE) zephyr_linker_sources(ROM_START rom_start.ld) zephyr_linker_sources(SECTIONS sections.ld) zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) + +else() + message(WARNING "Unsupported linker template.") endif() set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra2l1/CMakeLists.txt b/soc/renesas/ra/ra2l1/CMakeLists.txt index 9f12447715f4..ab4b876205ee 100644 --- a/soc/renesas/ra/ra2l1/CMakeLists.txt +++ b/soc/renesas/ra/ra2l1/CMakeLists.txt @@ -1,5 +1,5 @@ # Copyright (c) 2022-2024 MUNIC SA -# Copyright (c) 2024 Renesas Electronics Corporation +# Copyright (c) 2025 Renesas Electronics Corporation # SPDX-License-Identifier: Apache-2.0 zephyr_include_directories(.) @@ -8,31 +8,45 @@ zephyr_sources( soc.c ) -dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") -dt_nodelabel(option_setting_ofs1 NODELABEL "option_setting_ofs1") -dt_nodelabel(option_setting_secmpu NODELABEL "option_setting_secmpu") -dt_nodelabel(option_setting_osis NODELABEL "option_setting_osis") +if(CONFIG_CMAKE_LINKER_GENERATOR) + dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") + dt_nodelabel(option_setting_ofs1 NODELABEL "option_setting_ofs1") + dt_nodelabel(option_setting_secmpu NODELABEL "option_setting_secmpu") + dt_nodelabel(option_setting_osis NODELABEL "option_setting_osis") -dt_reg_addr(ofs0_addr PATH ${option_setting_ofs0}) -dt_reg_addr(ofs1_addr PATH ${option_setting_ofs1}) -dt_reg_addr(secmpu_addr PATH ${option_setting_secmpu}) -dt_reg_addr(osis_addr PATH ${option_setting_osis}) + dt_reg_addr(ofs0_addr PATH ${option_setting_ofs0}) + dt_reg_addr(ofs1_addr PATH ${option_setting_ofs1}) + dt_reg_addr(secmpu_addr PATH ${option_setting_secmpu}) + dt_reg_addr(osis_addr PATH ${option_setting_osis}) + + dt_node_has_status(osis_status PATH ${option_setting_osis} STATUS okay) + + if(CONFIG_USE_RA_FSP_DTC) + zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) + zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") + endif() -if(CONFIG_CMAKE_LINKER_GENERATOR) - zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) - zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") zephyr_linker_section(NAME .option_setting_ofs0 GROUP FLASH ADDRESS ${ofs0_addr}) zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") + zephyr_linker_section(NAME .option_setting_ofs1 GROUP FLASH ADDRESS ${ofs1_addr}) zephyr_linker_section_configure(SECTION .option_setting_ofs1 KEEP INPUT ".option_setting_ofs1*") + zephyr_linker_section(NAME .option_setting_secmpu GROUP FLASH ADDRESS ${secmpu_addr}) zephyr_linker_section_configure(SECTION .option_setting_secmpu KEEP INPUT ".option_setting_secmpu*") - zephyr_linker_section(NAME .option_setting_osis GROUP OFS_OSIS_MEMORY ADDRESS ${osis_addr}) - zephyr_linker_section_configure(SECTION .option_setting_osis KEEP INPUT ".option_setting_osis*") + + if(${osis_status}) + zephyr_linker_section(NAME .option_setting_osis GROUP OFS_OSIS_MEMORY ADDRESS ${osis_addr}) + zephyr_linker_section_configure(SECTION .option_setting_osis KEEP INPUT ".option_setting_osis*") + endif() + elseif(CONFIG_LD_LINKER_TEMPLATE) zephyr_linker_sources(ROM_START rom_start.ld) zephyr_linker_sources(SECTIONS sections.ld) zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) + +else() + message(WARNING "Unsupported linker template.") endif() set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra4c1/CMakeLists.txt b/soc/renesas/ra/ra4c1/CMakeLists.txt index ffda9d47ec78..695c35a40947 100644 --- a/soc/renesas/ra/ra4c1/CMakeLists.txt +++ b/soc/renesas/ra/ra4c1/CMakeLists.txt @@ -7,50 +7,93 @@ zephyr_sources( soc.c ) -dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") -dt_nodelabel(option_setting_dualsel NODELABEL "option_setting_dualsel") -dt_nodelabel(option_setting_ofs1_sec NODELABEL "option_setting_ofs1_sec") -dt_nodelabel(option_setting_banksel_sec NODELABEL "option_setting_banksel_sec") -dt_nodelabel(option_setting_bps_sec NODELABEL "option_setting_bps_sec") -dt_nodelabel(option_setting_pbps_sec NODELABEL "option_setting_pbps_sec") -dt_nodelabel(option_setting_ofs1_sel NODELABEL "option_setting_ofs1_sel") -dt_nodelabel(option_setting_banksel_sel NODELABEL "option_setting_banksel_sel") -dt_nodelabel(option_setting_bps_sel NODELABEL "option_setting_bps_sel") - -dt_reg_addr(ofs0_addr PATH ${option_setting_ofs0}) -dt_reg_addr(dualsel_addr PATH ${option_setting_dualsel}) -dt_reg_addr(ofs1_sec_addr PATH ${option_setting_ofs1_sec}) -dt_reg_addr(banksel_sec_addr PATH ${option_setting_banksel_sec}) -dt_reg_addr(bps_sec_addr PATH ${option_setting_bps_sec}) -dt_reg_addr(pbps_sec_addr PATH ${option_setting_pbps_sec}) -dt_reg_addr(ofs1_sel_addr PATH ${option_setting_ofs1_sel}) -dt_reg_addr(banksel_sel_addr PATH ${option_setting_banksel_sel}) -dt_reg_addr(bps_sel_addr PATH ${option_setting_bps_sel}) - if(CONFIG_CMAKE_LINKER_GENERATOR) - zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) - zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") - zephyr_linker_section(NAME .option_setting_ofs0 GROUP OFS_OFS0_MEMORY ADDRESS ${ofs0_addr}) - zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") - zephyr_linker_section(NAME .option_setting_dualsel GROUP OFS_DUALSEL_MEMORY ADDRESS ${dualsel_addr}) - zephyr_linker_section_configure(SECTION .option_setting_dualsel KEEP INPUT ".option_setting_dualsel*") - zephyr_linker_section(NAME .option_setting_ofs1_sec GROUP OFS_OFS1_SEC_MEMORY ADDRESS ${ofs1_sec_addr}) - zephyr_linker_section_configure(SECTION .option_setting_ofs1_sec KEEP INPUT ".option_setting_ofs1_sec*") - zephyr_linker_section(NAME .option_setting_banksel_sec GROUP OFS_BANKSEL_SEC_MEMORY ADDRESS ${banksel_sec_addr}) - zephyr_linker_section_configure(SECTION .option_setting_banksel_sec KEEP INPUT ".option_setting_banksel_sec*") - zephyr_linker_section(NAME .option_setting_ofs1_sel GROUP OFS_OFS1_SEL_MEMORY ADDRESS ${ofs1_sel_addr}) - zephyr_linker_section_configure(SECTION .option_setting_ofs1_sel KEEP INPUT ".option_setting_ofs1_sel*") - zephyr_linker_section(NAME .option_setting_banksel_sel GROUP OFS_BANKSEL_SEL_MEMORY ADDRESS ${banksel_sel_addr}) - zephyr_linker_section_configure(SECTION .option_setting_banksel_sel KEEP INPUT ".option_setting_banksel_sel*") - zephyr_linker_section(NAME .option_setting_bps_sec GROUP OFS_BPS_SEC_MEMORY ADDRESS ${bps_sec_addr}) - zephyr_linker_section_configure(SECTION .option_setting_bps_sec KEEP INPUT ".option_setting_bps_sec*") - zephyr_linker_section(NAME .option_setting_pbps_sec GROUP OFS_PBPS_SEC_MEMORY ADDRESS ${pbps_sec_addr}) - zephyr_linker_section_configure(SECTION .option_setting_pbps_sec KEEP INPUT ".option_setting_pbps_sec*") - zephyr_linker_section(NAME .option_setting_bps_sel GROUP OFS_BPS_SEL_MEMORY ADDRESS ${bps_sel_addr}) - zephyr_linker_section_configure(SECTION .option_setting_bps_sel KEEP INPUT ".option_setting_bps_sel*") + dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") + dt_nodelabel(option_setting_dualsel NODELABEL "option_setting_dualsel") + dt_nodelabel(option_setting_ofs1_sec NODELABEL "option_setting_ofs1_sec") + dt_nodelabel(option_setting_banksel_sec NODELABEL "option_setting_banksel_sec") + dt_nodelabel(option_setting_bps_sec NODELABEL "option_setting_bps_sec") + dt_nodelabel(option_setting_pbps_sec NODELABEL "option_setting_pbps_sec") + dt_nodelabel(option_setting_ofs1_sel NODELABEL "option_setting_ofs1_sel") + dt_nodelabel(option_setting_banksel_sel NODELABEL "option_setting_banksel_sel") + dt_nodelabel(option_setting_bps_sel NODELABEL "option_setting_bps_sel") + + dt_reg_addr(ofs0_addr PATH ${option_setting_ofs0}) + dt_reg_addr(dualsel_addr PATH ${option_setting_dualsel}) + dt_reg_addr(ofs1_sec_addr PATH ${option_setting_ofs1_sec}) + dt_reg_addr(banksel_sec_addr PATH ${option_setting_banksel_sec}) + dt_reg_addr(bps_sec_addr PATH ${option_setting_bps_sec}) + dt_reg_addr(pbps_sec_addr PATH ${option_setting_pbps_sec}) + dt_reg_addr(ofs1_sel_addr PATH ${option_setting_ofs1_sel}) + dt_reg_addr(banksel_sel_addr PATH ${option_setting_banksel_sel}) + dt_reg_addr(bps_sel_addr PATH ${option_setting_bps_sel}) + + dt_node_has_status(ofs0_status PATH ${option_setting_ofs0} STATUS okay) + dt_node_has_status(dualsel_status PATH ${option_setting_dualsel} STATUS okay) + dt_node_has_status(ofs1_sec_status PATH ${option_setting_ofs1_sec} STATUS okay) + dt_node_has_status(banksel_sec_status PATH ${option_setting_banksel_sec} STATUS okay) + dt_node_has_status(bps_sec_status PATH ${option_setting_bps_sec} STATUS okay) + dt_node_has_status(pbps_sec_status PATH ${option_setting_pbps_sec} STATUS okay) + dt_node_has_status(ofs1_sel_status PATH ${option_setting_ofs1_sel} STATUS okay) + dt_node_has_status(banksel_sel_status PATH ${option_setting_banksel_sel} STATUS okay) + dt_node_has_status(bps_sel_status PATH ${option_setting_bps_sel} STATUS okay) + + if(CONFIG_USE_RA_FSP_DTC) + zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) + zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") + endif() + + if(${ofs0_status}) + zephyr_linker_section(NAME .option_setting_ofs0 GROUP OFS_OFS0_MEMORY ADDRESS ${ofs0_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") + endif() + + if(${dualsel_status}) + zephyr_linker_section(NAME .option_setting_dualsel GROUP OFS_DUALSEL_MEMORY ADDRESS ${dualsel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_dualsel KEEP INPUT ".option_setting_dualsel*") + endif() + + if(${ofs1_sec_status}) + zephyr_linker_section(NAME .option_setting_ofs1_sec GROUP OFS_OFS1_SEC_MEMORY ADDRESS ${ofs1_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs1_sec KEEP INPUT ".option_setting_ofs1_sec*") + endif() + + if(${banksel_sec_status}) + zephyr_linker_section(NAME .option_setting_banksel_sec GROUP OFS_BANKSEL_SEC_MEMORY ADDRESS ${banksel_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_banksel_sec KEEP INPUT ".option_setting_banksel_sec*") + endif() + + if(${ofs1_sel_status}) + zephyr_linker_section(NAME .option_setting_ofs1_sel GROUP OFS_OFS1_SEL_MEMORY ADDRESS ${ofs1_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs1_sel KEEP INPUT ".option_setting_ofs1_sel*") + endif() + + if(${banksel_sel_status}) + zephyr_linker_section(NAME .option_setting_banksel_sel GROUP OFS_BANKSEL_SEL_MEMORY ADDRESS ${banksel_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_banksel_sel KEEP INPUT ".option_setting_banksel_sel*") + endif() + + if(${bps_sec_status}) + zephyr_linker_section(NAME .option_setting_bps_sec GROUP OFS_BPS_SEC_MEMORY ADDRESS ${bps_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_bps_sec KEEP INPUT ".option_setting_bps_sec*") + endif() + + if(${pbps_sec_status}) + zephyr_linker_section(NAME .option_setting_pbps_sec GROUP OFS_PBPS_SEC_MEMORY ADDRESS ${pbps_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_pbps_sec KEEP INPUT ".option_setting_pbps_sec*") + endif() + + if(${bps_sel_status}) + zephyr_linker_section(NAME .option_setting_bps_sel GROUP OFS_BPS_SEL_MEMORY ADDRESS ${bps_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_bps_sel KEEP INPUT ".option_setting_bps_sel*") + endif() + elseif(CONFIG_LD_LINKER_TEMPLATE) zephyr_linker_sources(SECTIONS sections.ld) zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) + +else() + message(WARNING "Unsupported linker template.") endif() set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra4e1/CMakeLists.txt b/soc/renesas/ra/ra4e1/CMakeLists.txt index df61c861d354..82681b5184b3 100644 --- a/soc/renesas/ra/ra4e1/CMakeLists.txt +++ b/soc/renesas/ra/ra4e1/CMakeLists.txt @@ -7,38 +7,69 @@ zephyr_sources( soc.c ) -dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") -dt_nodelabel(option_setting_ofs1_sec NODELABEL "option_setting_ofs1_sec") -dt_nodelabel(option_setting_bps_sec NODELABEL "option_setting_bps_sec") -dt_nodelabel(option_setting_pbps_sec NODELABEL "option_setting_pbps_sec") -dt_nodelabel(option_setting_ofs1_sel NODELABEL "option_setting_ofs1_sel") -dt_nodelabel(option_setting_bps_sel NODELABEL "option_setting_bps_sel") - -dt_reg_addr(ofs0_addr PATH ${option_setting_ofs0}) -dt_reg_addr(ofs1_sec_addr PATH ${option_setting_ofs1_sec}) -dt_reg_addr(bps_sec_addr PATH ${option_setting_bps_sec}) -dt_reg_addr(pbps_sec_addr PATH ${option_setting_pbps_sec}) -dt_reg_addr(ofs1_sel_addr PATH ${option_setting_ofs1_sel}) -dt_reg_addr(bps_sel_addr PATH ${option_setting_bps_sel}) - if(CONFIG_CMAKE_LINKER_GENERATOR) - zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) - zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") - zephyr_linker_section(NAME .option_setting_ofs0 GROUP OFS_OFS0_MEMORY ADDRESS ${ofs0_addr}) - zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") - zephyr_linker_section(NAME .option_setting_ofs1_sec GROUP OFS_OFS1_SEC_MEMORY ADDRESS ${ofs1_sec_addr}) - zephyr_linker_section_configure(SECTION .option_setting_ofs1_sec KEEP INPUT ".option_setting_ofs1_sec*") - zephyr_linker_section(NAME .option_setting_ofs1_sel GROUP OFS_OFS1_SEL_MEMORY ADDRESS ${ofs1_sel_addr}) - zephyr_linker_section_configure(SECTION .option_setting_ofs1_sel KEEP INPUT ".option_setting_ofs1_sel*") - zephyr_linker_section(NAME .option_setting_bps_sec GROUP OFS_BPS_SEC_MEMORY ADDRESS ${bps_sec_addr}) - zephyr_linker_section_configure(SECTION .option_setting_bps_sec KEEP INPUT ".option_setting_bps_sec*") - zephyr_linker_section(NAME .option_setting_pbps_sec GROUP OFS_PBPS_SEC_MEMORY ADDRESS ${pbps_sec_addr}) - zephyr_linker_section_configure(SECTION .option_setting_pbps_sec KEEP INPUT ".option_setting_pbps_sec*") - zephyr_linker_section(NAME .option_setting_bps_sel GROUP OFS_BPS_SEL_MEMORY ADDRESS ${bps_sel_addr}) - zephyr_linker_section_configure(SECTION .option_setting_bps_sel KEEP INPUT ".option_setting_bps_sel*") + dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") + dt_nodelabel(option_setting_ofs1_sec NODELABEL "option_setting_ofs1_sec") + dt_nodelabel(option_setting_bps_sec NODELABEL "option_setting_bps_sec") + dt_nodelabel(option_setting_pbps_sec NODELABEL "option_setting_pbps_sec") + dt_nodelabel(option_setting_ofs1_sel NODELABEL "option_setting_ofs1_sel") + dt_nodelabel(option_setting_bps_sel NODELABEL "option_setting_bps_sel") + + dt_reg_addr(ofs0_addr PATH ${option_setting_ofs0}) + dt_reg_addr(ofs1_sec_addr PATH ${option_setting_ofs1_sec}) + dt_reg_addr(bps_sec_addr PATH ${option_setting_bps_sec}) + dt_reg_addr(pbps_sec_addr PATH ${option_setting_pbps_sec}) + dt_reg_addr(ofs1_sel_addr PATH ${option_setting_ofs1_sel}) + dt_reg_addr(bps_sel_addr PATH ${option_setting_bps_sel}) + + dt_node_has_status(ofs0_status PATH ${option_setting_ofs0} STATUS okay) + dt_node_has_status(ofs1_sec_status PATH ${option_setting_ofs1_sec} STATUS okay) + dt_node_has_status(bps_sec_status PATH ${option_setting_bps_sec} STATUS okay) + dt_node_has_status(pbps_sec_status PATH ${option_setting_pbps_sec} STATUS okay) + dt_node_has_status(ofs1_sel_status PATH ${option_setting_ofs1_sel} STATUS okay) + dt_node_has_status(bps_sel_status PATH ${option_setting_bps_sel} STATUS okay) + + if(CONFIG_USE_RA_FSP_DTC) + zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) + zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") + endif() + + if(${ofs0_status}) + zephyr_linker_section(NAME .option_setting_ofs0 GROUP OFS_OFS0_MEMORY ADDRESS ${ofs0_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") + endif() + + if(${ofs1_sec_status}) + zephyr_linker_section(NAME .option_setting_ofs1_sec GROUP OFS_OFS1_SEC_MEMORY ADDRESS ${ofs1_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs1_sec KEEP INPUT ".option_setting_ofs1_sec*") + endif() + + if(${ofs1_sel_status}) + zephyr_linker_section(NAME .option_setting_ofs1_sel GROUP OFS_OFS1_SEL_MEMORY ADDRESS ${ofs1_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs1_sel KEEP INPUT ".option_setting_ofs1_sel*") + endif() + + if(${bps_sec_status}) + zephyr_linker_section(NAME .option_setting_bps_sec GROUP OFS_BPS_SEC_MEMORY ADDRESS ${bps_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_bps_sec KEEP INPUT ".option_setting_bps_sec*") + endif() + + if(${pbps_sec_status}) + zephyr_linker_section(NAME .option_setting_pbps_sec GROUP OFS_PBPS_SEC_MEMORY ADDRESS ${pbps_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_pbps_sec KEEP INPUT ".option_setting_pbps_sec*") + endif() + + if(${bps_sel_status}) + zephyr_linker_section(NAME .option_setting_bps_sel GROUP OFS_BPS_SEL_MEMORY ADDRESS ${bps_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_bps_sel KEEP INPUT ".option_setting_bps_sel*") + endif() + elseif(CONFIG_LD_LINKER_TEMPLATE) zephyr_linker_sources(SECTIONS sections.ld) zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) + +else() + message(WARNING "Unsupported linker template.") endif() set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra4e2/CMakeLists.txt b/soc/renesas/ra/ra4e2/CMakeLists.txt index 0918f899601f..4eea413d6825 100644 --- a/soc/renesas/ra/ra4e2/CMakeLists.txt +++ b/soc/renesas/ra/ra4e2/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2024 Renesas Electronics Corporation +# Copyright (c) 2024-2025 Renesas Electronics Corporation # SPDX-License-Identifier: Apache-2.0 zephyr_include_directories(.) @@ -7,34 +7,61 @@ zephyr_sources( soc.c ) -dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") -dt_nodelabel(option_setting_osis NODELABEL "option_setting_osis") -dt_nodelabel(option_setting_ofs1_sec NODELABEL "option_setting_ofs1_sec") -dt_nodelabel(option_setting_bps_sec NODELABEL "option_setting_bps_sec") -dt_nodelabel(option_setting_pbps_sec NODELABEL "option_setting_pbps_sec") +if(CONFIG_CMAKE_LINKER_GENERATOR) + dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") + dt_nodelabel(option_setting_osis NODELABEL "option_setting_osis") + dt_nodelabel(option_setting_ofs1_sec NODELABEL "option_setting_ofs1_sec") + dt_nodelabel(option_setting_bps_sec NODELABEL "option_setting_bps_sec") + dt_nodelabel(option_setting_pbps_sec NODELABEL "option_setting_pbps_sec") -dt_reg_addr(ofs0_addr PATH ${option_setting_ofs0}) -dt_reg_addr(osis_addr PATH ${option_setting_osis}) -dt_reg_addr(ofs1_sec_addr PATH ${option_setting_ofs1_sec}) -dt_reg_addr(bps_sec_addr PATH ${option_setting_bps_sec}) -dt_reg_addr(pbps_sec_addr PATH ${option_setting_pbps_sec}) + dt_reg_addr(ofs0_addr PATH ${option_setting_ofs0}) + dt_reg_addr(osis_addr PATH ${option_setting_osis}) + dt_reg_addr(ofs1_sec_addr PATH ${option_setting_ofs1_sec}) + dt_reg_addr(bps_sec_addr PATH ${option_setting_bps_sec}) + dt_reg_addr(pbps_sec_addr PATH ${option_setting_pbps_sec}) + + dt_node_has_status(ofs0_status PATH ${option_setting_ofs0} STATUS okay) + dt_node_has_status(osis_status PATH ${option_setting_osis} STATUS okay) + dt_node_has_status(ofs1_sec_status PATH ${option_setting_ofs1_sec} STATUS okay) + dt_node_has_status(bps_sec_status PATH ${option_setting_bps_sec} STATUS okay) + dt_node_has_status(pbps_sec_status PATH ${option_setting_pbps_sec} STATUS okay) + + if(CONFIG_USE_RA_FSP_DTC) + zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) + zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") + endif() + + if(${ofs0_status}) + zephyr_linker_section(NAME .option_setting_ofs0 GROUP OFS_OFS0_MEMORY ADDRESS ${ofs0_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") + endif() + + if(${osis_status}) + zephyr_linker_section(NAME .option_setting_osis GROUP OFS_OSIS_MEMORY ADDRESS ${osis_addr}) + zephyr_linker_section_configure(SECTION .option_setting_osis KEEP INPUT ".option_setting_osis*") + endif() + + if(${ofs1_sec_status}) + zephyr_linker_section(NAME .option_setting_ofs1_sec GROUP OFS_OFS1_SEC_MEMORY ADDRESS ${ofs1_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs1_sec KEEP INPUT ".option_setting_ofs1_sec*") + endif() + + if(${bps_sec_status}) + zephyr_linker_section(NAME .option_setting_bps_sec GROUP OFS_BPS_SEC_MEMORY ADDRESS ${bps_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_bps_sec KEEP INPUT ".option_setting_bps_sec*") + endif() + + if(${pbps_sec_status}) + zephyr_linker_section(NAME .option_setting_pbps_sec GROUP OFS_PBPS_SEC_MEMORY ADDRESS ${pbps_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_pbps_sec KEEP INPUT ".option_setting_pbps_sec*") + endif() -if(CONFIG_CMAKE_LINKER_GENERATOR) - zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) - zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") - zephyr_linker_section(NAME .option_setting_ofs0 GROUP OFS_OFS0_MEMORY ADDRESS ${ofs0_addr}) - zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") - zephyr_linker_section(NAME .option_setting_osis GROUP OFS_OSIS_MEMORY ADDRESS ${osis_addr}) - zephyr_linker_section_configure(SECTION .option_setting_osis KEEP INPUT ".option_setting_osis*") - zephyr_linker_section(NAME .option_setting_ofs1_sec GROUP OFS_OFS1_SEC_MEMORY ADDRESS ${ofs1_sec_addr}) - zephyr_linker_section_configure(SECTION .option_setting_ofs1_sec KEEP INPUT ".option_setting_ofs1_sec*") - zephyr_linker_section(NAME .option_setting_bps_sec GROUP OFS_BPS_SEC_MEMORY ADDRESS ${bps_sec_addr}) - zephyr_linker_section_configure(SECTION .option_setting_bps_sec KEEP INPUT ".option_setting_bps_sec*") - zephyr_linker_section(NAME .option_setting_pbps_sec GROUP OFS_PBPS_SEC_MEMORY ADDRESS ${pbps_sec_addr}) - zephyr_linker_section_configure(SECTION .option_setting_pbps_sec KEEP INPUT ".option_setting_pbps_sec*") elseif(CONFIG_LD_LINKER_TEMPLATE) zephyr_linker_sources(SECTIONS sections.ld) zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) + +else() + message(WARNING "Unsupported linker template.") endif() set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra4l1/CMakeLists.txt b/soc/renesas/ra/ra4l1/CMakeLists.txt index ffda9d47ec78..695c35a40947 100644 --- a/soc/renesas/ra/ra4l1/CMakeLists.txt +++ b/soc/renesas/ra/ra4l1/CMakeLists.txt @@ -7,50 +7,93 @@ zephyr_sources( soc.c ) -dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") -dt_nodelabel(option_setting_dualsel NODELABEL "option_setting_dualsel") -dt_nodelabel(option_setting_ofs1_sec NODELABEL "option_setting_ofs1_sec") -dt_nodelabel(option_setting_banksel_sec NODELABEL "option_setting_banksel_sec") -dt_nodelabel(option_setting_bps_sec NODELABEL "option_setting_bps_sec") -dt_nodelabel(option_setting_pbps_sec NODELABEL "option_setting_pbps_sec") -dt_nodelabel(option_setting_ofs1_sel NODELABEL "option_setting_ofs1_sel") -dt_nodelabel(option_setting_banksel_sel NODELABEL "option_setting_banksel_sel") -dt_nodelabel(option_setting_bps_sel NODELABEL "option_setting_bps_sel") - -dt_reg_addr(ofs0_addr PATH ${option_setting_ofs0}) -dt_reg_addr(dualsel_addr PATH ${option_setting_dualsel}) -dt_reg_addr(ofs1_sec_addr PATH ${option_setting_ofs1_sec}) -dt_reg_addr(banksel_sec_addr PATH ${option_setting_banksel_sec}) -dt_reg_addr(bps_sec_addr PATH ${option_setting_bps_sec}) -dt_reg_addr(pbps_sec_addr PATH ${option_setting_pbps_sec}) -dt_reg_addr(ofs1_sel_addr PATH ${option_setting_ofs1_sel}) -dt_reg_addr(banksel_sel_addr PATH ${option_setting_banksel_sel}) -dt_reg_addr(bps_sel_addr PATH ${option_setting_bps_sel}) - if(CONFIG_CMAKE_LINKER_GENERATOR) - zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) - zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") - zephyr_linker_section(NAME .option_setting_ofs0 GROUP OFS_OFS0_MEMORY ADDRESS ${ofs0_addr}) - zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") - zephyr_linker_section(NAME .option_setting_dualsel GROUP OFS_DUALSEL_MEMORY ADDRESS ${dualsel_addr}) - zephyr_linker_section_configure(SECTION .option_setting_dualsel KEEP INPUT ".option_setting_dualsel*") - zephyr_linker_section(NAME .option_setting_ofs1_sec GROUP OFS_OFS1_SEC_MEMORY ADDRESS ${ofs1_sec_addr}) - zephyr_linker_section_configure(SECTION .option_setting_ofs1_sec KEEP INPUT ".option_setting_ofs1_sec*") - zephyr_linker_section(NAME .option_setting_banksel_sec GROUP OFS_BANKSEL_SEC_MEMORY ADDRESS ${banksel_sec_addr}) - zephyr_linker_section_configure(SECTION .option_setting_banksel_sec KEEP INPUT ".option_setting_banksel_sec*") - zephyr_linker_section(NAME .option_setting_ofs1_sel GROUP OFS_OFS1_SEL_MEMORY ADDRESS ${ofs1_sel_addr}) - zephyr_linker_section_configure(SECTION .option_setting_ofs1_sel KEEP INPUT ".option_setting_ofs1_sel*") - zephyr_linker_section(NAME .option_setting_banksel_sel GROUP OFS_BANKSEL_SEL_MEMORY ADDRESS ${banksel_sel_addr}) - zephyr_linker_section_configure(SECTION .option_setting_banksel_sel KEEP INPUT ".option_setting_banksel_sel*") - zephyr_linker_section(NAME .option_setting_bps_sec GROUP OFS_BPS_SEC_MEMORY ADDRESS ${bps_sec_addr}) - zephyr_linker_section_configure(SECTION .option_setting_bps_sec KEEP INPUT ".option_setting_bps_sec*") - zephyr_linker_section(NAME .option_setting_pbps_sec GROUP OFS_PBPS_SEC_MEMORY ADDRESS ${pbps_sec_addr}) - zephyr_linker_section_configure(SECTION .option_setting_pbps_sec KEEP INPUT ".option_setting_pbps_sec*") - zephyr_linker_section(NAME .option_setting_bps_sel GROUP OFS_BPS_SEL_MEMORY ADDRESS ${bps_sel_addr}) - zephyr_linker_section_configure(SECTION .option_setting_bps_sel KEEP INPUT ".option_setting_bps_sel*") + dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") + dt_nodelabel(option_setting_dualsel NODELABEL "option_setting_dualsel") + dt_nodelabel(option_setting_ofs1_sec NODELABEL "option_setting_ofs1_sec") + dt_nodelabel(option_setting_banksel_sec NODELABEL "option_setting_banksel_sec") + dt_nodelabel(option_setting_bps_sec NODELABEL "option_setting_bps_sec") + dt_nodelabel(option_setting_pbps_sec NODELABEL "option_setting_pbps_sec") + dt_nodelabel(option_setting_ofs1_sel NODELABEL "option_setting_ofs1_sel") + dt_nodelabel(option_setting_banksel_sel NODELABEL "option_setting_banksel_sel") + dt_nodelabel(option_setting_bps_sel NODELABEL "option_setting_bps_sel") + + dt_reg_addr(ofs0_addr PATH ${option_setting_ofs0}) + dt_reg_addr(dualsel_addr PATH ${option_setting_dualsel}) + dt_reg_addr(ofs1_sec_addr PATH ${option_setting_ofs1_sec}) + dt_reg_addr(banksel_sec_addr PATH ${option_setting_banksel_sec}) + dt_reg_addr(bps_sec_addr PATH ${option_setting_bps_sec}) + dt_reg_addr(pbps_sec_addr PATH ${option_setting_pbps_sec}) + dt_reg_addr(ofs1_sel_addr PATH ${option_setting_ofs1_sel}) + dt_reg_addr(banksel_sel_addr PATH ${option_setting_banksel_sel}) + dt_reg_addr(bps_sel_addr PATH ${option_setting_bps_sel}) + + dt_node_has_status(ofs0_status PATH ${option_setting_ofs0} STATUS okay) + dt_node_has_status(dualsel_status PATH ${option_setting_dualsel} STATUS okay) + dt_node_has_status(ofs1_sec_status PATH ${option_setting_ofs1_sec} STATUS okay) + dt_node_has_status(banksel_sec_status PATH ${option_setting_banksel_sec} STATUS okay) + dt_node_has_status(bps_sec_status PATH ${option_setting_bps_sec} STATUS okay) + dt_node_has_status(pbps_sec_status PATH ${option_setting_pbps_sec} STATUS okay) + dt_node_has_status(ofs1_sel_status PATH ${option_setting_ofs1_sel} STATUS okay) + dt_node_has_status(banksel_sel_status PATH ${option_setting_banksel_sel} STATUS okay) + dt_node_has_status(bps_sel_status PATH ${option_setting_bps_sel} STATUS okay) + + if(CONFIG_USE_RA_FSP_DTC) + zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) + zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") + endif() + + if(${ofs0_status}) + zephyr_linker_section(NAME .option_setting_ofs0 GROUP OFS_OFS0_MEMORY ADDRESS ${ofs0_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") + endif() + + if(${dualsel_status}) + zephyr_linker_section(NAME .option_setting_dualsel GROUP OFS_DUALSEL_MEMORY ADDRESS ${dualsel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_dualsel KEEP INPUT ".option_setting_dualsel*") + endif() + + if(${ofs1_sec_status}) + zephyr_linker_section(NAME .option_setting_ofs1_sec GROUP OFS_OFS1_SEC_MEMORY ADDRESS ${ofs1_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs1_sec KEEP INPUT ".option_setting_ofs1_sec*") + endif() + + if(${banksel_sec_status}) + zephyr_linker_section(NAME .option_setting_banksel_sec GROUP OFS_BANKSEL_SEC_MEMORY ADDRESS ${banksel_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_banksel_sec KEEP INPUT ".option_setting_banksel_sec*") + endif() + + if(${ofs1_sel_status}) + zephyr_linker_section(NAME .option_setting_ofs1_sel GROUP OFS_OFS1_SEL_MEMORY ADDRESS ${ofs1_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs1_sel KEEP INPUT ".option_setting_ofs1_sel*") + endif() + + if(${banksel_sel_status}) + zephyr_linker_section(NAME .option_setting_banksel_sel GROUP OFS_BANKSEL_SEL_MEMORY ADDRESS ${banksel_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_banksel_sel KEEP INPUT ".option_setting_banksel_sel*") + endif() + + if(${bps_sec_status}) + zephyr_linker_section(NAME .option_setting_bps_sec GROUP OFS_BPS_SEC_MEMORY ADDRESS ${bps_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_bps_sec KEEP INPUT ".option_setting_bps_sec*") + endif() + + if(${pbps_sec_status}) + zephyr_linker_section(NAME .option_setting_pbps_sec GROUP OFS_PBPS_SEC_MEMORY ADDRESS ${pbps_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_pbps_sec KEEP INPUT ".option_setting_pbps_sec*") + endif() + + if(${bps_sel_status}) + zephyr_linker_section(NAME .option_setting_bps_sel GROUP OFS_BPS_SEL_MEMORY ADDRESS ${bps_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_bps_sel KEEP INPUT ".option_setting_bps_sel*") + endif() + elseif(CONFIG_LD_LINKER_TEMPLATE) zephyr_linker_sources(SECTIONS sections.ld) zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) + +else() + message(WARNING "Unsupported linker template.") endif() set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra4m1/CMakeLists.txt b/soc/renesas/ra/ra4m1/CMakeLists.txt index 78d60b405889..63b6ca88b63c 100644 --- a/soc/renesas/ra/ra4m1/CMakeLists.txt +++ b/soc/renesas/ra/ra4m1/CMakeLists.txt @@ -4,33 +4,49 @@ zephyr_include_directories(.) -zephyr_library_sources(soc.c) +zephyr_sources( + soc.c +) -dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") -dt_nodelabel(option_setting_ofs1 NODELABEL "option_setting_ofs1") -dt_nodelabel(option_setting_secmpu NODELABEL "option_setting_secmpu") -dt_nodelabel(option_setting_osis NODELABEL "option_setting_osis") +if(CONFIG_CMAKE_LINKER_GENERATOR) + dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") + dt_nodelabel(option_setting_ofs1 NODELABEL "option_setting_ofs1") + dt_nodelabel(option_setting_secmpu NODELABEL "option_setting_secmpu") + dt_nodelabel(option_setting_osis NODELABEL "option_setting_osis") -dt_reg_addr(ofs0_addr PATH ${option_setting_ofs0}) -dt_reg_addr(ofs1_addr PATH ${option_setting_ofs1}) -dt_reg_addr(secmpu_addr PATH ${option_setting_secmpu}) -dt_reg_addr(osis_addr PATH ${option_setting_osis}) + dt_reg_addr(ofs0_addr PATH ${option_setting_ofs0}) + dt_reg_addr(ofs1_addr PATH ${option_setting_ofs1}) + dt_reg_addr(secmpu_addr PATH ${option_setting_secmpu}) + dt_reg_addr(osis_addr PATH ${option_setting_osis}) + + dt_node_has_status(osis_status PATH ${option_setting_osis} STATUS okay) + + if(CONFIG_USE_RA_FSP_DTC) + zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) + zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") + endif() -if(CONFIG_CMAKE_LINKER_GENERATOR) - zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) - zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") zephyr_linker_section(NAME .option_setting_ofs0 GROUP FLASH ADDRESS ${ofs0_addr}) zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") + zephyr_linker_section(NAME .option_setting_ofs1 GROUP FLASH ADDRESS ${ofs1_addr}) zephyr_linker_section_configure(SECTION .option_setting_ofs1 KEEP INPUT ".option_setting_ofs1*") + zephyr_linker_section(NAME .option_setting_secmpu GROUP FLASH ADDRESS ${secmpu_addr}) zephyr_linker_section_configure(SECTION .option_setting_secmpu KEEP INPUT ".option_setting_secmpu*") - zephyr_linker_section(NAME .option_setting_osis GROUP OFS_OSIS_MEMORY ADDRESS ${osis_addr}) - zephyr_linker_section_configure(SECTION .option_setting_osis KEEP INPUT ".option_setting_osis*") + + if(${osis_status}) + zephyr_linker_section(NAME .option_setting_osis GROUP OFS_OSIS_MEMORY ADDRESS ${osis_addr}) + zephyr_linker_section_configure(SECTION .option_setting_osis KEEP INPUT ".option_setting_osis*") + endif() + elseif(CONFIG_LD_LINKER_TEMPLATE) zephyr_linker_sources(ROM_START rom_start.ld) zephyr_linker_sources(SECTIONS sections.ld) zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) + +else() + message(WARNING "Unsupported linker template.") endif() set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra4m2/CMakeLists.txt b/soc/renesas/ra/ra4m2/CMakeLists.txt index af909123ab61..074db41fdceb 100644 --- a/soc/renesas/ra/ra4m2/CMakeLists.txt +++ b/soc/renesas/ra/ra4m2/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2024 Renesas Electronics Corporation +# Copyright (c) 2024-2025 Renesas Electronics Corporation # SPDX-License-Identifier: Apache-2.0 zephyr_include_directories(.) @@ -7,38 +7,69 @@ zephyr_sources( soc.c ) -dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") -dt_nodelabel(option_setting_ofs1_sec NODELABEL "option_setting_ofs1_sec") -dt_nodelabel(option_setting_bps_sec NODELABEL "option_setting_bps_sec") -dt_nodelabel(option_setting_pbps_sec NODELABEL "option_setting_pbps_sec") -dt_nodelabel(option_setting_ofs1_sel NODELABEL "option_setting_ofs1_sel") -dt_nodelabel(option_setting_bps_sel NODELABEL "option_setting_bps_sel") +if(CONFIG_CMAKE_LINKER_GENERATOR) + dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") + dt_nodelabel(option_setting_ofs1_sec NODELABEL "option_setting_ofs1_sec") + dt_nodelabel(option_setting_bps_sec NODELABEL "option_setting_bps_sec") + dt_nodelabel(option_setting_pbps_sec NODELABEL "option_setting_pbps_sec") + dt_nodelabel(option_setting_ofs1_sel NODELABEL "option_setting_ofs1_sel") + dt_nodelabel(option_setting_bps_sel NODELABEL "option_setting_bps_sel") -dt_reg_addr(ofs0_addr PATH ${option_setting_ofs0}) -dt_reg_addr(ofs1_sec_addr PATH ${option_setting_ofs1_sec}) -dt_reg_addr(bps_sec_addr PATH ${option_setting_bps_sec}) -dt_reg_addr(pbps_sec_addr PATH ${option_setting_pbps_sec}) -dt_reg_addr(ofs1_sel_addr PATH ${option_setting_ofs1_sel}) -dt_reg_addr(bps_sel_addr PATH ${option_setting_bps_sel}) + dt_reg_addr(ofs0_addr PATH ${option_setting_ofs0}) + dt_reg_addr(ofs1_sec_addr PATH ${option_setting_ofs1_sec}) + dt_reg_addr(bps_sec_addr PATH ${option_setting_bps_sec}) + dt_reg_addr(pbps_sec_addr PATH ${option_setting_pbps_sec}) + dt_reg_addr(ofs1_sel_addr PATH ${option_setting_ofs1_sel}) + dt_reg_addr(bps_sel_addr PATH ${option_setting_bps_sel}) + + dt_node_has_status(ofs0_status PATH ${option_setting_ofs0} STATUS okay) + dt_node_has_status(ofs1_sec_status PATH ${option_setting_ofs1_sec} STATUS okay) + dt_node_has_status(bps_sec_status PATH ${option_setting_bps_sec} STATUS okay) + dt_node_has_status(pbps_sec_status PATH ${option_setting_pbps_sec} STATUS okay) + dt_node_has_status(ofs1_sel_status PATH ${option_setting_ofs1_sel} STATUS okay) + dt_node_has_status(bps_sel_status PATH ${option_setting_bps_sel} STATUS okay) + + if(CONFIG_USE_RA_FSP_DTC) + zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) + zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") + endif() + + if(${ofs0_status}) + zephyr_linker_section(NAME .option_setting_ofs0 GROUP OFS_OFS0_MEMORY ADDRESS ${ofs0_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") + endif() + + if(${ofs1_sec_status}) + zephyr_linker_section(NAME .option_setting_ofs1_sec GROUP OFS_OFS1_SEC_MEMORY ADDRESS ${ofs1_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs1_sec KEEP INPUT ".option_setting_ofs1_sec*") + endif() + + if(${ofs1_sel_status}) + zephyr_linker_section(NAME .option_setting_ofs1_sel GROUP OFS_OFS1_SEL_MEMORY ADDRESS ${ofs1_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs1_sel KEEP INPUT ".option_setting_ofs1_sel*") + endif() + + if(${bps_sec_status}) + zephyr_linker_section(NAME .option_setting_bps_sec GROUP OFS_BPS_SEC_MEMORY ADDRESS ${bps_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_bps_sec KEEP INPUT ".option_setting_bps_sec*") + endif() + + if(${pbps_sec_status}) + zephyr_linker_section(NAME .option_setting_pbps_sec GROUP OFS_PBPS_SEC_MEMORY ADDRESS ${pbps_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_pbps_sec KEEP INPUT ".option_setting_pbps_sec*") + endif() + + if(${bps_sel_status}) + zephyr_linker_section(NAME .option_setting_bps_sel GROUP OFS_BPS_SEL_MEMORY ADDRESS ${bps_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_bps_sel KEEP INPUT ".option_setting_bps_sel*") + endif() -if(CONFIG_CMAKE_LINKER_GENERATOR) - zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) - zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") - zephyr_linker_section(NAME .option_setting_ofs0 GROUP OFS_OFS0_MEMORY ADDRESS ${ofs0_addr}) - zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") - zephyr_linker_section(NAME .option_setting_ofs1_sec GROUP OFS_OFS1_SEC_MEMORY ADDRESS ${ofs1_sec_addr}) - zephyr_linker_section_configure(SECTION .option_setting_ofs1_sec KEEP INPUT ".option_setting_ofs1_sec*") - zephyr_linker_section(NAME .option_setting_ofs1_sel GROUP OFS_OFS1_SEL_MEMORY ADDRESS ${ofs1_sel_addr}) - zephyr_linker_section_configure(SECTION .option_setting_ofs1_sel KEEP INPUT ".option_setting_ofs1_sel*") - zephyr_linker_section(NAME .option_setting_bps_sec GROUP OFS_BPS_SEC_MEMORY ADDRESS ${bps_sec_addr}) - zephyr_linker_section_configure(SECTION .option_setting_bps_sec KEEP INPUT ".option_setting_bps_sec*") - zephyr_linker_section(NAME .option_setting_pbps_sec GROUP OFS_PBPS_SEC_MEMORY ADDRESS ${pbps_sec_addr}) - zephyr_linker_section_configure(SECTION .option_setting_pbps_sec KEEP INPUT ".option_setting_pbps_sec*") - zephyr_linker_section(NAME .option_setting_bps_sel GROUP OFS_BPS_SEL_MEMORY ADDRESS ${bps_sel_addr}) - zephyr_linker_section_configure(SECTION .option_setting_bps_sel KEEP INPUT ".option_setting_bps_sel*") elseif(CONFIG_LD_LINKER_TEMPLATE) zephyr_linker_sources(SECTIONS sections.ld) zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) + +else() + message(WARNING "Unsupported linker template.") endif() set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra4m3/CMakeLists.txt b/soc/renesas/ra/ra4m3/CMakeLists.txt index db314a4fd56a..7f86249065cb 100644 --- a/soc/renesas/ra/ra4m3/CMakeLists.txt +++ b/soc/renesas/ra/ra4m3/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2024 Renesas Electronics Corporation +# Copyright (c) 2024-2025 Renesas Electronics Corporation # SPDX-License-Identifier: Apache-2.0 zephyr_include_directories(.) @@ -7,46 +7,85 @@ zephyr_sources( soc.c ) -dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") -dt_nodelabel(option_setting_ofs1_sec NODELABEL "option_setting_ofs1_sec") -dt_nodelabel(option_setting_banksel_sec NODELABEL "option_setting_banksel_sec") -dt_nodelabel(option_setting_bps_sec NODELABEL "option_setting_bps_sec") -dt_nodelabel(option_setting_pbps_sec NODELABEL "option_setting_pbps_sec") -dt_nodelabel(option_setting_ofs1_sel NODELABEL "option_setting_ofs1_sel") -dt_nodelabel(option_setting_banksel_sel NODELABEL "option_setting_banksel_sel") -dt_nodelabel(option_setting_bps_sel NODELABEL "option_setting_bps_sel") - -dt_reg_addr(ofs0_addr PATH ${option_setting_ofs0}) -dt_reg_addr(ofs1_sec_addr PATH ${option_setting_ofs1_sec}) -dt_reg_addr(banksel_sec_addr PATH ${option_setting_banksel_sec}) -dt_reg_addr(bps_sec_addr PATH ${option_setting_bps_sec}) -dt_reg_addr(pbps_sec_addr PATH ${option_setting_pbps_sec}) -dt_reg_addr(ofs1_sel_addr PATH ${option_setting_ofs1_sel}) -dt_reg_addr(banksel_sel_addr PATH ${option_setting_banksel_sel}) -dt_reg_addr(bps_sel_addr PATH ${option_setting_bps_sel}) - if(CONFIG_CMAKE_LINKER_GENERATOR) - zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) - zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") - zephyr_linker_section(NAME .option_setting_ofs0 GROUP OFS_OFS0_MEMORY ADDRESS ${ofs0_addr}) - zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") - zephyr_linker_section(NAME .option_setting_ofs1_sec GROUP OFS_OFS1_SEC_MEMORY ADDRESS ${ofs1_sec_addr}) - zephyr_linker_section_configure(SECTION .option_setting_ofs1_sec KEEP INPUT ".option_setting_ofs1_sec*") - zephyr_linker_section(NAME .option_setting_banksel_sec GROUP OFS_BANKSEL_SEC_MEMORY ADDRESS ${banksel_sec_addr}) - zephyr_linker_section_configure(SECTION .option_setting_banksel_sec KEEP INPUT ".option_setting_banksel_sec*") - zephyr_linker_section(NAME .option_setting_ofs1_sel GROUP OFS_OFS1_SEL_MEMORY ADDRESS ${ofs1_sel_addr}) - zephyr_linker_section_configure(SECTION .option_setting_ofs1_sel KEEP INPUT ".option_setting_ofs1_sel*") - zephyr_linker_section(NAME .option_setting_banksel_sel GROUP OFS_BANKSEL_SEL_MEMORY ADDRESS ${banksel_sel_addr}) - zephyr_linker_section_configure(SECTION .option_setting_banksel_sel KEEP INPUT ".option_setting_banksel_sel*") - zephyr_linker_section(NAME .option_setting_bps_sec GROUP OFS_BPS_SEC_MEMORY ADDRESS ${bps_sec_addr}) - zephyr_linker_section_configure(SECTION .option_setting_bps_sec KEEP INPUT ".option_setting_bps_sec*") - zephyr_linker_section(NAME .option_setting_pbps_sec GROUP OFS_PBPS_SEC_MEMORY ADDRESS ${pbps_sec_addr}) - zephyr_linker_section_configure(SECTION .option_setting_pbps_sec KEEP INPUT ".option_setting_pbps_sec*") - zephyr_linker_section(NAME .option_setting_bps_sel GROUP OFS_BPS_SEL_MEMORY ADDRESS ${bps_sel_addr}) - zephyr_linker_section_configure(SECTION .option_setting_bps_sel KEEP INPUT ".option_setting_bps_sel*") + dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") + dt_nodelabel(option_setting_ofs1_sec NODELABEL "option_setting_ofs1_sec") + dt_nodelabel(option_setting_banksel_sec NODELABEL "option_setting_banksel_sec") + dt_nodelabel(option_setting_bps_sec NODELABEL "option_setting_bps_sec") + dt_nodelabel(option_setting_pbps_sec NODELABEL "option_setting_pbps_sec") + dt_nodelabel(option_setting_ofs1_sel NODELABEL "option_setting_ofs1_sel") + dt_nodelabel(option_setting_banksel_sel NODELABEL "option_setting_banksel_sel") + dt_nodelabel(option_setting_bps_sel NODELABEL "option_setting_bps_sel") + + dt_reg_addr(ofs0_addr PATH ${option_setting_ofs0}) + dt_reg_addr(ofs1_sec_addr PATH ${option_setting_ofs1_sec}) + dt_reg_addr(banksel_sec_addr PATH ${option_setting_banksel_sec}) + dt_reg_addr(bps_sec_addr PATH ${option_setting_bps_sec}) + dt_reg_addr(pbps_sec_addr PATH ${option_setting_pbps_sec}) + dt_reg_addr(ofs1_sel_addr PATH ${option_setting_ofs1_sel}) + dt_reg_addr(banksel_sel_addr PATH ${option_setting_banksel_sel}) + dt_reg_addr(bps_sel_addr PATH ${option_setting_bps_sel}) + + dt_node_has_status(ofs0_status PATH ${option_setting_ofs0} STATUS okay) + dt_node_has_status(ofs1_sec_status PATH ${option_setting_ofs1_sec} STATUS okay) + dt_node_has_status(banksel_sec_status PATH ${option_setting_banksel_sec} STATUS okay) + dt_node_has_status(bps_sec_status PATH ${option_setting_bps_sec} STATUS okay) + dt_node_has_status(pbps_sec_status PATH ${option_setting_pbps_sec} STATUS okay) + dt_node_has_status(ofs1_sel_status PATH ${option_setting_ofs1_sel} STATUS okay) + dt_node_has_status(banksel_sel_status PATH ${option_setting_banksel_sel} STATUS okay) + dt_node_has_status(bps_sel_status PATH ${option_setting_bps_sel} STATUS okay) + + if(CONFIG_USE_RA_FSP_DTC) + zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) + zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") + endif() + + if(${ofs0_status}) + zephyr_linker_section(NAME .option_setting_ofs0 GROUP OFS_OFS0_MEMORY ADDRESS ${ofs0_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") + endif() + + if(${ofs1_sec_status}) + zephyr_linker_section(NAME .option_setting_ofs1_sec GROUP OFS_OFS1_SEC_MEMORY ADDRESS ${ofs1_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs1_sec KEEP INPUT ".option_setting_ofs1_sec*") + endif() + + if(${banksel_sec_status}) + zephyr_linker_section(NAME .option_setting_banksel_sec GROUP OFS_BANKSEL_SEC_MEMORY ADDRESS ${banksel_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_banksel_sec KEEP INPUT ".option_setting_banksel_sec*") + endif() + + if(${ofs1_sel_status}) + zephyr_linker_section(NAME .option_setting_ofs1_sel GROUP OFS_OFS1_SEL_MEMORY ADDRESS ${ofs1_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs1_sel KEEP INPUT ".option_setting_ofs1_sel*") + endif() + + if(${banksel_sel_status}) + zephyr_linker_section(NAME .option_setting_banksel_sel GROUP OFS_BANKSEL_SEL_MEMORY ADDRESS ${banksel_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_banksel_sel KEEP INPUT ".option_setting_banksel_sel*") + endif() + + if(${bps_sec_status}) + zephyr_linker_section(NAME .option_setting_bps_sec GROUP OFS_BPS_SEC_MEMORY ADDRESS ${bps_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_bps_sec KEEP INPUT ".option_setting_bps_sec*") + endif() + + if(${pbps_sec_status}) + zephyr_linker_section(NAME .option_setting_pbps_sec GROUP OFS_PBPS_SEC_MEMORY ADDRESS ${pbps_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_pbps_sec KEEP INPUT ".option_setting_pbps_sec*") + endif() + + if(${bps_sel_status}) + zephyr_linker_section(NAME .option_setting_bps_sel GROUP OFS_BPS_SEL_MEMORY ADDRESS ${bps_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_bps_sel KEEP INPUT ".option_setting_bps_sel*") + endif() + elseif(CONFIG_LD_LINKER_TEMPLATE) zephyr_linker_sources(SECTIONS sections.ld) zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) + +else() + message(WARNING "Unsupported linker template.") endif() set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra4w1/CMakeLists.txt b/soc/renesas/ra/ra4w1/CMakeLists.txt index 36a5f177990b..7cd1d9afe6a9 100644 --- a/soc/renesas/ra/ra4w1/CMakeLists.txt +++ b/soc/renesas/ra/ra4w1/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2024 Renesas Electronics Corporation +# Copyright (c) 2024-2025 Renesas Electronics Corporation # SPDX-License-Identifier: Apache-2.0 zephyr_include_directories(.) @@ -7,31 +7,45 @@ zephyr_sources( soc.c ) -dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") -dt_nodelabel(option_setting_ofs1 NODELABEL "option_setting_ofs1") -dt_nodelabel(option_setting_secmpu NODELABEL "option_setting_secmpu") -dt_nodelabel(option_setting_osis NODELABEL "option_setting_osis") +if(CONFIG_CMAKE_LINKER_GENERATOR) + dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") + dt_nodelabel(option_setting_ofs1 NODELABEL "option_setting_ofs1") + dt_nodelabel(option_setting_secmpu NODELABEL "option_setting_secmpu") + dt_nodelabel(option_setting_osis NODELABEL "option_setting_osis") -dt_reg_addr(ofs0_addr PATH ${option_setting_ofs0}) -dt_reg_addr(ofs1_addr PATH ${option_setting_ofs1}) -dt_reg_addr(secmpu_addr PATH ${option_setting_secmpu}) -dt_reg_addr(osis_addr PATH ${option_setting_osis}) + dt_reg_addr(ofs0_addr PATH ${option_setting_ofs0}) + dt_reg_addr(ofs1_addr PATH ${option_setting_ofs1}) + dt_reg_addr(secmpu_addr PATH ${option_setting_secmpu}) + dt_reg_addr(osis_addr PATH ${option_setting_osis}) + + dt_node_has_status(osis_status PATH ${option_setting_osis} STATUS okay) + + if(CONFIG_USE_RA_FSP_DTC) + zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) + zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") + endif() -if(CONFIG_CMAKE_LINKER_GENERATOR) - zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) - zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") zephyr_linker_section(NAME .option_setting_ofs0 GROUP FLASH ADDRESS ${ofs0_addr}) zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") + zephyr_linker_section(NAME .option_setting_ofs1 GROUP FLASH ADDRESS ${ofs1_addr}) zephyr_linker_section_configure(SECTION .option_setting_ofs1 KEEP INPUT ".option_setting_ofs1*") + zephyr_linker_section(NAME .option_setting_secmpu GROUP FLASH ADDRESS ${secmpu_addr}) zephyr_linker_section_configure(SECTION .option_setting_secmpu KEEP INPUT ".option_setting_secmpu*") - zephyr_linker_section(NAME .option_setting_osis GROUP OFS_OSIS_MEMORY ADDRESS ${osis_addr}) - zephyr_linker_section_configure(SECTION .option_setting_osis KEEP INPUT ".option_setting_osis*") + + if(${osis_status}) + zephyr_linker_section(NAME .option_setting_osis GROUP OFS_OSIS_MEMORY ADDRESS ${osis_addr}) + zephyr_linker_section_configure(SECTION .option_setting_osis KEEP INPUT ".option_setting_osis*") + endif() + elseif(CONFIG_LD_LINKER_TEMPLATE) zephyr_linker_sources(ROM_START rom_start.ld) zephyr_linker_sources(SECTIONS sections.ld) zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) + +else() + message(WARNING "Unsupported linker template.") endif() set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra6e1/CMakeLists.txt b/soc/renesas/ra/ra6e1/CMakeLists.txt index b25240222960..0459d4214b8d 100644 --- a/soc/renesas/ra/ra6e1/CMakeLists.txt +++ b/soc/renesas/ra/ra6e1/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2024 Renesas Electronics Corporation +# Copyright (c) 2024-2025 Renesas Electronics Corporation # SPDX-License-Identifier: Apache-2.0 zephyr_include_directories(.) @@ -7,50 +7,93 @@ zephyr_sources( soc.c ) -dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") -dt_nodelabel(option_setting_dualsel NODELABEL "option_setting_dualsel") -dt_nodelabel(option_setting_ofs1_sec NODELABEL "option_setting_ofs1_sec") -dt_nodelabel(option_setting_banksel_sec NODELABEL "option_setting_banksel_sec") -dt_nodelabel(option_setting_bps_sec NODELABEL "option_setting_bps_sec") -dt_nodelabel(option_setting_pbps_sec NODELABEL "option_setting_pbps_sec") -dt_nodelabel(option_setting_ofs1_sel NODELABEL "option_setting_ofs1_sel") -dt_nodelabel(option_setting_banksel_sel NODELABEL "option_setting_banksel_sel") -dt_nodelabel(option_setting_bps_sel NODELABEL "option_setting_bps_sel") - -dt_reg_addr(ofs0_addr PATH ${option_setting_ofs0}) -dt_reg_addr(dualsel_addr PATH ${option_setting_dualsel}) -dt_reg_addr(ofs1_sec_addr PATH ${option_setting_ofs1_sec}) -dt_reg_addr(banksel_sec_addr PATH ${option_setting_banksel_sec}) -dt_reg_addr(bps_sec_addr PATH ${option_setting_bps_sec}) -dt_reg_addr(pbps_sec_addr PATH ${option_setting_pbps_sec}) -dt_reg_addr(ofs1_sel_addr PATH ${option_setting_ofs1_sel}) -dt_reg_addr(banksel_sel_addr PATH ${option_setting_banksel_sel}) -dt_reg_addr(bps_sel_addr PATH ${option_setting_bps_sel}) - if(CONFIG_CMAKE_LINKER_GENERATOR) - zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) - zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") - zephyr_linker_section(NAME .option_setting_ofs0 GROUP OFS_OFS0_MEMORY ADDRESS ${ofs0_addr}) - zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") - zephyr_linker_section(NAME .option_setting_dualsel GROUP OFS_DUALSEL_MEMORY ADDRESS ${dualsel_addr}) - zephyr_linker_section_configure(SECTION .option_setting_dualsel KEEP INPUT ".option_setting_dualsel*") - zephyr_linker_section(NAME .option_setting_ofs1_sec GROUP OFS_OFS1_SEC_MEMORY ADDRESS ${ofs1_sec_addr}) - zephyr_linker_section_configure(SECTION .option_setting_ofs1_sec KEEP INPUT ".option_setting_ofs1_sec*") - zephyr_linker_section(NAME .option_setting_banksel_sec GROUP OFS_BANKSEL_SEC_MEMORY ADDRESS ${banksel_sec_addr}) - zephyr_linker_section_configure(SECTION .option_setting_banksel_sec KEEP INPUT ".option_setting_banksel_sec*") - zephyr_linker_section(NAME .option_setting_ofs1_sel GROUP OFS_OFS1_SEL_MEMORY ADDRESS ${ofs1_sel_addr}) - zephyr_linker_section_configure(SECTION .option_setting_ofs1_sel KEEP INPUT ".option_setting_ofs1_sel*") - zephyr_linker_section(NAME .option_setting_banksel_sel GROUP OFS_BANKSEL_SEL_MEMORY ADDRESS ${banksel_sel_addr}) - zephyr_linker_section_configure(SECTION .option_setting_banksel_sel KEEP INPUT ".option_setting_banksel_sel*") - zephyr_linker_section(NAME .option_setting_bps_sec GROUP OFS_BPS_SEC_MEMORY ADDRESS ${bps_sec_addr}) - zephyr_linker_section_configure(SECTION .option_setting_bps_sec KEEP INPUT ".option_setting_bps_sec*") - zephyr_linker_section(NAME .option_setting_pbps_sec GROUP OFS_PBPS_SEC_MEMORY ADDRESS ${pbps_sec_addr}) - zephyr_linker_section_configure(SECTION .option_setting_pbps_sec KEEP INPUT ".option_setting_pbps_sec*") - zephyr_linker_section(NAME .option_setting_bps_sel GROUP OFS_BPS_SEL_MEMORY ADDRESS ${bps_sel_addr}) - zephyr_linker_section_configure(SECTION .option_setting_bps_sel KEEP INPUT ".option_setting_bps_sel*") + dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") + dt_nodelabel(option_setting_dualsel NODELABEL "option_setting_dualsel") + dt_nodelabel(option_setting_ofs1_sec NODELABEL "option_setting_ofs1_sec") + dt_nodelabel(option_setting_banksel_sec NODELABEL "option_setting_banksel_sec") + dt_nodelabel(option_setting_bps_sec NODELABEL "option_setting_bps_sec") + dt_nodelabel(option_setting_pbps_sec NODELABEL "option_setting_pbps_sec") + dt_nodelabel(option_setting_ofs1_sel NODELABEL "option_setting_ofs1_sel") + dt_nodelabel(option_setting_banksel_sel NODELABEL "option_setting_banksel_sel") + dt_nodelabel(option_setting_bps_sel NODELABEL "option_setting_bps_sel") + + dt_reg_addr(ofs0_addr PATH ${option_setting_ofs0}) + dt_reg_addr(dualsel_addr PATH ${option_setting_dualsel}) + dt_reg_addr(ofs1_sec_addr PATH ${option_setting_ofs1_sec}) + dt_reg_addr(banksel_sec_addr PATH ${option_setting_banksel_sec}) + dt_reg_addr(bps_sec_addr PATH ${option_setting_bps_sec}) + dt_reg_addr(pbps_sec_addr PATH ${option_setting_pbps_sec}) + dt_reg_addr(ofs1_sel_addr PATH ${option_setting_ofs1_sel}) + dt_reg_addr(banksel_sel_addr PATH ${option_setting_banksel_sel}) + dt_reg_addr(bps_sel_addr PATH ${option_setting_bps_sel}) + + dt_node_has_status(ofs0_status PATH ${option_setting_ofs0} STATUS okay) + dt_node_has_status(dualsel_status PATH ${option_setting_dualsel} STATUS okay) + dt_node_has_status(ofs1_sec_status PATH ${option_setting_ofs1_sec} STATUS okay) + dt_node_has_status(banksel_sec_status PATH ${option_setting_banksel_sec} STATUS okay) + dt_node_has_status(bps_sec_status PATH ${option_setting_bps_sec} STATUS okay) + dt_node_has_status(pbps_sec_status PATH ${option_setting_pbps_sec} STATUS okay) + dt_node_has_status(ofs1_sel_status PATH ${option_setting_ofs1_sel} STATUS okay) + dt_node_has_status(banksel_sel_status PATH ${option_setting_banksel_sel} STATUS okay) + dt_node_has_status(bps_sel_status PATH ${option_setting_bps_sel} STATUS okay) + + if(CONFIG_USE_RA_FSP_DTC) + zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) + zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") + endif() + + if(${ofs0_status}) + zephyr_linker_section(NAME .option_setting_ofs0 GROUP OFS_OFS0_MEMORY ADDRESS ${ofs0_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") + endif() + + if(${dualsel_status}) + zephyr_linker_section(NAME .option_setting_dualsel GROUP OFS_DUALSEL_MEMORY ADDRESS ${dualsel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_dualsel KEEP INPUT ".option_setting_dualsel*") + endif() + + if(${ofs1_sec_status}) + zephyr_linker_section(NAME .option_setting_ofs1_sec GROUP OFS_OFS1_SEC_MEMORY ADDRESS ${ofs1_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs1_sec KEEP INPUT ".option_setting_ofs1_sec*") + endif() + + if(${banksel_sec_status}) + zephyr_linker_section(NAME .option_setting_banksel_sec GROUP OFS_BANKSEL_SEC_MEMORY ADDRESS ${banksel_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_banksel_sec KEEP INPUT ".option_setting_banksel_sec*") + endif() + + if(${ofs1_sel_status}) + zephyr_linker_section(NAME .option_setting_ofs1_sel GROUP OFS_OFS1_SEL_MEMORY ADDRESS ${ofs1_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs1_sel KEEP INPUT ".option_setting_ofs1_sel*") + endif() + + if(${banksel_sel_status}) + zephyr_linker_section(NAME .option_setting_banksel_sel GROUP OFS_BANKSEL_SEL_MEMORY ADDRESS ${banksel_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_banksel_sel KEEP INPUT ".option_setting_banksel_sel*") + endif() + + if(${bps_sec_status}) + zephyr_linker_section(NAME .option_setting_bps_sec GROUP OFS_BPS_SEC_MEMORY ADDRESS ${bps_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_bps_sec KEEP INPUT ".option_setting_bps_sec*") + endif() + + if(${pbps_sec_status}) + zephyr_linker_section(NAME .option_setting_pbps_sec GROUP OFS_PBPS_SEC_MEMORY ADDRESS ${pbps_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_pbps_sec KEEP INPUT ".option_setting_pbps_sec*") + endif() + + if(${bps_sel_status}) + zephyr_linker_section(NAME .option_setting_bps_sel GROUP OFS_BPS_SEL_MEMORY ADDRESS ${bps_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_bps_sel KEEP INPUT ".option_setting_bps_sel*") + endif() + elseif(CONFIG_LD_LINKER_TEMPLATE) zephyr_linker_sources(SECTIONS sections.ld) zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) + +else() + message(WARNING "Unsupported linker template.") endif() set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra6e2/CMakeLists.txt b/soc/renesas/ra/ra6e2/CMakeLists.txt index 0918f899601f..4eea413d6825 100644 --- a/soc/renesas/ra/ra6e2/CMakeLists.txt +++ b/soc/renesas/ra/ra6e2/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2024 Renesas Electronics Corporation +# Copyright (c) 2024-2025 Renesas Electronics Corporation # SPDX-License-Identifier: Apache-2.0 zephyr_include_directories(.) @@ -7,34 +7,61 @@ zephyr_sources( soc.c ) -dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") -dt_nodelabel(option_setting_osis NODELABEL "option_setting_osis") -dt_nodelabel(option_setting_ofs1_sec NODELABEL "option_setting_ofs1_sec") -dt_nodelabel(option_setting_bps_sec NODELABEL "option_setting_bps_sec") -dt_nodelabel(option_setting_pbps_sec NODELABEL "option_setting_pbps_sec") +if(CONFIG_CMAKE_LINKER_GENERATOR) + dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") + dt_nodelabel(option_setting_osis NODELABEL "option_setting_osis") + dt_nodelabel(option_setting_ofs1_sec NODELABEL "option_setting_ofs1_sec") + dt_nodelabel(option_setting_bps_sec NODELABEL "option_setting_bps_sec") + dt_nodelabel(option_setting_pbps_sec NODELABEL "option_setting_pbps_sec") -dt_reg_addr(ofs0_addr PATH ${option_setting_ofs0}) -dt_reg_addr(osis_addr PATH ${option_setting_osis}) -dt_reg_addr(ofs1_sec_addr PATH ${option_setting_ofs1_sec}) -dt_reg_addr(bps_sec_addr PATH ${option_setting_bps_sec}) -dt_reg_addr(pbps_sec_addr PATH ${option_setting_pbps_sec}) + dt_reg_addr(ofs0_addr PATH ${option_setting_ofs0}) + dt_reg_addr(osis_addr PATH ${option_setting_osis}) + dt_reg_addr(ofs1_sec_addr PATH ${option_setting_ofs1_sec}) + dt_reg_addr(bps_sec_addr PATH ${option_setting_bps_sec}) + dt_reg_addr(pbps_sec_addr PATH ${option_setting_pbps_sec}) + + dt_node_has_status(ofs0_status PATH ${option_setting_ofs0} STATUS okay) + dt_node_has_status(osis_status PATH ${option_setting_osis} STATUS okay) + dt_node_has_status(ofs1_sec_status PATH ${option_setting_ofs1_sec} STATUS okay) + dt_node_has_status(bps_sec_status PATH ${option_setting_bps_sec} STATUS okay) + dt_node_has_status(pbps_sec_status PATH ${option_setting_pbps_sec} STATUS okay) + + if(CONFIG_USE_RA_FSP_DTC) + zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) + zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") + endif() + + if(${ofs0_status}) + zephyr_linker_section(NAME .option_setting_ofs0 GROUP OFS_OFS0_MEMORY ADDRESS ${ofs0_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") + endif() + + if(${osis_status}) + zephyr_linker_section(NAME .option_setting_osis GROUP OFS_OSIS_MEMORY ADDRESS ${osis_addr}) + zephyr_linker_section_configure(SECTION .option_setting_osis KEEP INPUT ".option_setting_osis*") + endif() + + if(${ofs1_sec_status}) + zephyr_linker_section(NAME .option_setting_ofs1_sec GROUP OFS_OFS1_SEC_MEMORY ADDRESS ${ofs1_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs1_sec KEEP INPUT ".option_setting_ofs1_sec*") + endif() + + if(${bps_sec_status}) + zephyr_linker_section(NAME .option_setting_bps_sec GROUP OFS_BPS_SEC_MEMORY ADDRESS ${bps_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_bps_sec KEEP INPUT ".option_setting_bps_sec*") + endif() + + if(${pbps_sec_status}) + zephyr_linker_section(NAME .option_setting_pbps_sec GROUP OFS_PBPS_SEC_MEMORY ADDRESS ${pbps_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_pbps_sec KEEP INPUT ".option_setting_pbps_sec*") + endif() -if(CONFIG_CMAKE_LINKER_GENERATOR) - zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) - zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") - zephyr_linker_section(NAME .option_setting_ofs0 GROUP OFS_OFS0_MEMORY ADDRESS ${ofs0_addr}) - zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") - zephyr_linker_section(NAME .option_setting_osis GROUP OFS_OSIS_MEMORY ADDRESS ${osis_addr}) - zephyr_linker_section_configure(SECTION .option_setting_osis KEEP INPUT ".option_setting_osis*") - zephyr_linker_section(NAME .option_setting_ofs1_sec GROUP OFS_OFS1_SEC_MEMORY ADDRESS ${ofs1_sec_addr}) - zephyr_linker_section_configure(SECTION .option_setting_ofs1_sec KEEP INPUT ".option_setting_ofs1_sec*") - zephyr_linker_section(NAME .option_setting_bps_sec GROUP OFS_BPS_SEC_MEMORY ADDRESS ${bps_sec_addr}) - zephyr_linker_section_configure(SECTION .option_setting_bps_sec KEEP INPUT ".option_setting_bps_sec*") - zephyr_linker_section(NAME .option_setting_pbps_sec GROUP OFS_PBPS_SEC_MEMORY ADDRESS ${pbps_sec_addr}) - zephyr_linker_section_configure(SECTION .option_setting_pbps_sec KEEP INPUT ".option_setting_pbps_sec*") elseif(CONFIG_LD_LINKER_TEMPLATE) zephyr_linker_sources(SECTIONS sections.ld) zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) + +else() + message(WARNING "Unsupported linker template.") endif() set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra6m1/CMakeLists.txt b/soc/renesas/ra/ra6m1/CMakeLists.txt index 36a5f177990b..7cd1d9afe6a9 100644 --- a/soc/renesas/ra/ra6m1/CMakeLists.txt +++ b/soc/renesas/ra/ra6m1/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2024 Renesas Electronics Corporation +# Copyright (c) 2024-2025 Renesas Electronics Corporation # SPDX-License-Identifier: Apache-2.0 zephyr_include_directories(.) @@ -7,31 +7,45 @@ zephyr_sources( soc.c ) -dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") -dt_nodelabel(option_setting_ofs1 NODELABEL "option_setting_ofs1") -dt_nodelabel(option_setting_secmpu NODELABEL "option_setting_secmpu") -dt_nodelabel(option_setting_osis NODELABEL "option_setting_osis") +if(CONFIG_CMAKE_LINKER_GENERATOR) + dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") + dt_nodelabel(option_setting_ofs1 NODELABEL "option_setting_ofs1") + dt_nodelabel(option_setting_secmpu NODELABEL "option_setting_secmpu") + dt_nodelabel(option_setting_osis NODELABEL "option_setting_osis") -dt_reg_addr(ofs0_addr PATH ${option_setting_ofs0}) -dt_reg_addr(ofs1_addr PATH ${option_setting_ofs1}) -dt_reg_addr(secmpu_addr PATH ${option_setting_secmpu}) -dt_reg_addr(osis_addr PATH ${option_setting_osis}) + dt_reg_addr(ofs0_addr PATH ${option_setting_ofs0}) + dt_reg_addr(ofs1_addr PATH ${option_setting_ofs1}) + dt_reg_addr(secmpu_addr PATH ${option_setting_secmpu}) + dt_reg_addr(osis_addr PATH ${option_setting_osis}) + + dt_node_has_status(osis_status PATH ${option_setting_osis} STATUS okay) + + if(CONFIG_USE_RA_FSP_DTC) + zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) + zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") + endif() -if(CONFIG_CMAKE_LINKER_GENERATOR) - zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) - zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") zephyr_linker_section(NAME .option_setting_ofs0 GROUP FLASH ADDRESS ${ofs0_addr}) zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") + zephyr_linker_section(NAME .option_setting_ofs1 GROUP FLASH ADDRESS ${ofs1_addr}) zephyr_linker_section_configure(SECTION .option_setting_ofs1 KEEP INPUT ".option_setting_ofs1*") + zephyr_linker_section(NAME .option_setting_secmpu GROUP FLASH ADDRESS ${secmpu_addr}) zephyr_linker_section_configure(SECTION .option_setting_secmpu KEEP INPUT ".option_setting_secmpu*") - zephyr_linker_section(NAME .option_setting_osis GROUP OFS_OSIS_MEMORY ADDRESS ${osis_addr}) - zephyr_linker_section_configure(SECTION .option_setting_osis KEEP INPUT ".option_setting_osis*") + + if(${osis_status}) + zephyr_linker_section(NAME .option_setting_osis GROUP OFS_OSIS_MEMORY ADDRESS ${osis_addr}) + zephyr_linker_section_configure(SECTION .option_setting_osis KEEP INPUT ".option_setting_osis*") + endif() + elseif(CONFIG_LD_LINKER_TEMPLATE) zephyr_linker_sources(ROM_START rom_start.ld) zephyr_linker_sources(SECTIONS sections.ld) zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) + +else() + message(WARNING "Unsupported linker template.") endif() set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra6m2/CMakeLists.txt b/soc/renesas/ra/ra6m2/CMakeLists.txt index 36a5f177990b..7cd1d9afe6a9 100644 --- a/soc/renesas/ra/ra6m2/CMakeLists.txt +++ b/soc/renesas/ra/ra6m2/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2024 Renesas Electronics Corporation +# Copyright (c) 2024-2025 Renesas Electronics Corporation # SPDX-License-Identifier: Apache-2.0 zephyr_include_directories(.) @@ -7,31 +7,45 @@ zephyr_sources( soc.c ) -dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") -dt_nodelabel(option_setting_ofs1 NODELABEL "option_setting_ofs1") -dt_nodelabel(option_setting_secmpu NODELABEL "option_setting_secmpu") -dt_nodelabel(option_setting_osis NODELABEL "option_setting_osis") +if(CONFIG_CMAKE_LINKER_GENERATOR) + dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") + dt_nodelabel(option_setting_ofs1 NODELABEL "option_setting_ofs1") + dt_nodelabel(option_setting_secmpu NODELABEL "option_setting_secmpu") + dt_nodelabel(option_setting_osis NODELABEL "option_setting_osis") -dt_reg_addr(ofs0_addr PATH ${option_setting_ofs0}) -dt_reg_addr(ofs1_addr PATH ${option_setting_ofs1}) -dt_reg_addr(secmpu_addr PATH ${option_setting_secmpu}) -dt_reg_addr(osis_addr PATH ${option_setting_osis}) + dt_reg_addr(ofs0_addr PATH ${option_setting_ofs0}) + dt_reg_addr(ofs1_addr PATH ${option_setting_ofs1}) + dt_reg_addr(secmpu_addr PATH ${option_setting_secmpu}) + dt_reg_addr(osis_addr PATH ${option_setting_osis}) + + dt_node_has_status(osis_status PATH ${option_setting_osis} STATUS okay) + + if(CONFIG_USE_RA_FSP_DTC) + zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) + zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") + endif() -if(CONFIG_CMAKE_LINKER_GENERATOR) - zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) - zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") zephyr_linker_section(NAME .option_setting_ofs0 GROUP FLASH ADDRESS ${ofs0_addr}) zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") + zephyr_linker_section(NAME .option_setting_ofs1 GROUP FLASH ADDRESS ${ofs1_addr}) zephyr_linker_section_configure(SECTION .option_setting_ofs1 KEEP INPUT ".option_setting_ofs1*") + zephyr_linker_section(NAME .option_setting_secmpu GROUP FLASH ADDRESS ${secmpu_addr}) zephyr_linker_section_configure(SECTION .option_setting_secmpu KEEP INPUT ".option_setting_secmpu*") - zephyr_linker_section(NAME .option_setting_osis GROUP OFS_OSIS_MEMORY ADDRESS ${osis_addr}) - zephyr_linker_section_configure(SECTION .option_setting_osis KEEP INPUT ".option_setting_osis*") + + if(${osis_status}) + zephyr_linker_section(NAME .option_setting_osis GROUP OFS_OSIS_MEMORY ADDRESS ${osis_addr}) + zephyr_linker_section_configure(SECTION .option_setting_osis KEEP INPUT ".option_setting_osis*") + endif() + elseif(CONFIG_LD_LINKER_TEMPLATE) zephyr_linker_sources(ROM_START rom_start.ld) zephyr_linker_sources(SECTIONS sections.ld) zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) + +else() + message(WARNING "Unsupported linker template.") endif() set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra6m3/CMakeLists.txt b/soc/renesas/ra/ra6m3/CMakeLists.txt index 36a5f177990b..7cd1d9afe6a9 100644 --- a/soc/renesas/ra/ra6m3/CMakeLists.txt +++ b/soc/renesas/ra/ra6m3/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2024 Renesas Electronics Corporation +# Copyright (c) 2024-2025 Renesas Electronics Corporation # SPDX-License-Identifier: Apache-2.0 zephyr_include_directories(.) @@ -7,31 +7,45 @@ zephyr_sources( soc.c ) -dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") -dt_nodelabel(option_setting_ofs1 NODELABEL "option_setting_ofs1") -dt_nodelabel(option_setting_secmpu NODELABEL "option_setting_secmpu") -dt_nodelabel(option_setting_osis NODELABEL "option_setting_osis") +if(CONFIG_CMAKE_LINKER_GENERATOR) + dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") + dt_nodelabel(option_setting_ofs1 NODELABEL "option_setting_ofs1") + dt_nodelabel(option_setting_secmpu NODELABEL "option_setting_secmpu") + dt_nodelabel(option_setting_osis NODELABEL "option_setting_osis") -dt_reg_addr(ofs0_addr PATH ${option_setting_ofs0}) -dt_reg_addr(ofs1_addr PATH ${option_setting_ofs1}) -dt_reg_addr(secmpu_addr PATH ${option_setting_secmpu}) -dt_reg_addr(osis_addr PATH ${option_setting_osis}) + dt_reg_addr(ofs0_addr PATH ${option_setting_ofs0}) + dt_reg_addr(ofs1_addr PATH ${option_setting_ofs1}) + dt_reg_addr(secmpu_addr PATH ${option_setting_secmpu}) + dt_reg_addr(osis_addr PATH ${option_setting_osis}) + + dt_node_has_status(osis_status PATH ${option_setting_osis} STATUS okay) + + if(CONFIG_USE_RA_FSP_DTC) + zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) + zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") + endif() -if(CONFIG_CMAKE_LINKER_GENERATOR) - zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) - zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") zephyr_linker_section(NAME .option_setting_ofs0 GROUP FLASH ADDRESS ${ofs0_addr}) zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") + zephyr_linker_section(NAME .option_setting_ofs1 GROUP FLASH ADDRESS ${ofs1_addr}) zephyr_linker_section_configure(SECTION .option_setting_ofs1 KEEP INPUT ".option_setting_ofs1*") + zephyr_linker_section(NAME .option_setting_secmpu GROUP FLASH ADDRESS ${secmpu_addr}) zephyr_linker_section_configure(SECTION .option_setting_secmpu KEEP INPUT ".option_setting_secmpu*") - zephyr_linker_section(NAME .option_setting_osis GROUP OFS_OSIS_MEMORY ADDRESS ${osis_addr}) - zephyr_linker_section_configure(SECTION .option_setting_osis KEEP INPUT ".option_setting_osis*") + + if(${osis_status}) + zephyr_linker_section(NAME .option_setting_osis GROUP OFS_OSIS_MEMORY ADDRESS ${osis_addr}) + zephyr_linker_section_configure(SECTION .option_setting_osis KEEP INPUT ".option_setting_osis*") + endif() + elseif(CONFIG_LD_LINKER_TEMPLATE) zephyr_linker_sources(ROM_START rom_start.ld) zephyr_linker_sources(SECTIONS sections.ld) zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) + +else() + message(WARNING "Unsupported linker template.") endif() set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra6m4/CMakeLists.txt b/soc/renesas/ra/ra6m4/CMakeLists.txt index 49d3c9d48bd7..4ecf42a5fc63 100644 --- a/soc/renesas/ra/ra6m4/CMakeLists.txt +++ b/soc/renesas/ra/ra6m4/CMakeLists.txt @@ -7,50 +7,93 @@ zephyr_sources( soc.c ) -dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") -dt_nodelabel(option_setting_dualsel NODELABEL "option_setting_dualsel") -dt_nodelabel(option_setting_ofs1_sec NODELABEL "option_setting_ofs1_sec") -dt_nodelabel(option_setting_banksel_sec NODELABEL "option_setting_banksel_sec") -dt_nodelabel(option_setting_bps_sec NODELABEL "option_setting_bps_sec") -dt_nodelabel(option_setting_pbps_sec NODELABEL "option_setting_pbps_sec") -dt_nodelabel(option_setting_ofs1_sel NODELABEL "option_setting_ofs1_sel") -dt_nodelabel(option_setting_banksel_sel NODELABEL "option_setting_banksel_sel") -dt_nodelabel(option_setting_bps_sel NODELABEL "option_setting_bps_sel") - -dt_reg_addr(ofs0_addr PATH ${option_setting_ofs0}) -dt_reg_addr(dualsel_addr PATH ${option_setting_dualsel}) -dt_reg_addr(ofs1_sec_addr PATH ${option_setting_ofs1_sec}) -dt_reg_addr(banksel_sec_addr PATH ${option_setting_banksel_sec}) -dt_reg_addr(bps_sec_addr PATH ${option_setting_bps_sec}) -dt_reg_addr(pbps_sec_addr PATH ${option_setting_pbps_sec}) -dt_reg_addr(ofs1_sel_addr PATH ${option_setting_ofs1_sel}) -dt_reg_addr(banksel_sel_addr PATH ${option_setting_banksel_sel}) -dt_reg_addr(bps_sel_addr PATH ${option_setting_bps_sel}) - if(CONFIG_CMAKE_LINKER_GENERATOR) - zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) - zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") - zephyr_linker_section(NAME .option_setting_ofs0 GROUP OFS_OFS0_MEMORY ADDRESS ${ofs0_addr}) - zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") - zephyr_linker_section(NAME .option_setting_dualsel GROUP OFS_DUALSEL_MEMORY ADDRESS ${dualsel_addr}) - zephyr_linker_section_configure(SECTION .option_setting_dualsel KEEP INPUT ".option_setting_dualsel*") - zephyr_linker_section(NAME .option_setting_ofs1_sec GROUP OFS_OFS1_SEC_MEMORY ADDRESS ${ofs1_sec_addr}) - zephyr_linker_section_configure(SECTION .option_setting_ofs1_sec KEEP INPUT ".option_setting_ofs1_sec*") - zephyr_linker_section(NAME .option_setting_banksel_sec GROUP OFS_BANKSEL_SEC_MEMORY ADDRESS ${banksel_sec_addr}) - zephyr_linker_section_configure(SECTION .option_setting_banksel_sec KEEP INPUT ".option_setting_banksel_sec*") - zephyr_linker_section(NAME .option_setting_ofs1_sel GROUP OFS_OFS1_SEL_MEMORY ADDRESS ${ofs1_sel_addr}) - zephyr_linker_section_configure(SECTION .option_setting_ofs1_sel KEEP INPUT ".option_setting_ofs1_sel*") - zephyr_linker_section(NAME .option_setting_banksel_sel GROUP OFS_BANKSEL_SEL_MEMORY ADDRESS ${banksel_sel_addr}) - zephyr_linker_section_configure(SECTION .option_setting_banksel_sel KEEP INPUT ".option_setting_banksel_sel*") - zephyr_linker_section(NAME .option_setting_bps_sec GROUP OFS_BPS_SEC_MEMORY ADDRESS ${bps_sec_addr}) - zephyr_linker_section_configure(SECTION .option_setting_bps_sec KEEP INPUT ".option_setting_bps_sec*") - zephyr_linker_section(NAME .option_setting_pbps_sec GROUP OFS_PBPS_SEC_MEMORY ADDRESS ${pbps_sec_addr}) - zephyr_linker_section_configure(SECTION .option_setting_pbps_sec KEEP INPUT ".option_setting_pbps_sec*") - zephyr_linker_section(NAME .option_setting_bps_sel GROUP OFS_BPS_SEL_MEMORY ADDRESS ${bps_sel_addr}) - zephyr_linker_section_configure(SECTION .option_setting_bps_sel KEEP INPUT ".option_setting_bps_sel*") + dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") + dt_nodelabel(option_setting_dualsel NODELABEL "option_setting_dualsel") + dt_nodelabel(option_setting_ofs1_sec NODELABEL "option_setting_ofs1_sec") + dt_nodelabel(option_setting_banksel_sec NODELABEL "option_setting_banksel_sec") + dt_nodelabel(option_setting_bps_sec NODELABEL "option_setting_bps_sec") + dt_nodelabel(option_setting_pbps_sec NODELABEL "option_setting_pbps_sec") + dt_nodelabel(option_setting_ofs1_sel NODELABEL "option_setting_ofs1_sel") + dt_nodelabel(option_setting_banksel_sel NODELABEL "option_setting_banksel_sel") + dt_nodelabel(option_setting_bps_sel NODELABEL "option_setting_bps_sel") + + dt_reg_addr(ofs0_addr PATH ${option_setting_ofs0}) + dt_reg_addr(dualsel_addr PATH ${option_setting_dualsel}) + dt_reg_addr(ofs1_sec_addr PATH ${option_setting_ofs1_sec}) + dt_reg_addr(banksel_sec_addr PATH ${option_setting_banksel_sec}) + dt_reg_addr(bps_sec_addr PATH ${option_setting_bps_sec}) + dt_reg_addr(pbps_sec_addr PATH ${option_setting_pbps_sec}) + dt_reg_addr(ofs1_sel_addr PATH ${option_setting_ofs1_sel}) + dt_reg_addr(banksel_sel_addr PATH ${option_setting_banksel_sel}) + dt_reg_addr(bps_sel_addr PATH ${option_setting_bps_sel}) + + dt_node_has_status(ofs0_status PATH ${option_setting_ofs0} STATUS okay) + dt_node_has_status(dualsel_status PATH ${option_setting_dualsel} STATUS okay) + dt_node_has_status(ofs1_sec_status PATH ${option_setting_ofs1_sec} STATUS okay) + dt_node_has_status(banksel_sec_status PATH ${option_setting_banksel_sec} STATUS okay) + dt_node_has_status(bps_sec_status PATH ${option_setting_bps_sec} STATUS okay) + dt_node_has_status(pbps_sec_status PATH ${option_setting_pbps_sec} STATUS okay) + dt_node_has_status(ofs1_sel_status PATH ${option_setting_ofs1_sel} STATUS okay) + dt_node_has_status(banksel_sel_status PATH ${option_setting_banksel_sel} STATUS okay) + dt_node_has_status(bps_sel_status PATH ${option_setting_bps_sel} STATUS okay) + + if(CONFIG_USE_RA_FSP_DTC) + zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) + zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") + endif() + + if(${ofs0_status}) + zephyr_linker_section(NAME .option_setting_ofs0 GROUP OFS_OFS0_MEMORY ADDRESS ${ofs0_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") + endif() + + if(${dualsel_status}) + zephyr_linker_section(NAME .option_setting_dualsel GROUP OFS_DUALSEL_MEMORY ADDRESS ${dualsel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_dualsel KEEP INPUT ".option_setting_dualsel*") + endif() + + if(${ofs1_sec_status}) + zephyr_linker_section(NAME .option_setting_ofs1_sec GROUP OFS_OFS1_SEC_MEMORY ADDRESS ${ofs1_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs1_sec KEEP INPUT ".option_setting_ofs1_sec*") + endif() + + if(${banksel_sec_status}) + zephyr_linker_section(NAME .option_setting_banksel_sec GROUP OFS_BANKSEL_SEC_MEMORY ADDRESS ${banksel_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_banksel_sec KEEP INPUT ".option_setting_banksel_sec*") + endif() + + if(${ofs1_sel_status}) + zephyr_linker_section(NAME .option_setting_ofs1_sel GROUP OFS_OFS1_SEL_MEMORY ADDRESS ${ofs1_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs1_sel KEEP INPUT ".option_setting_ofs1_sel*") + endif() + + if(${banksel_sel_status}) + zephyr_linker_section(NAME .option_setting_banksel_sel GROUP OFS_BANKSEL_SEL_MEMORY ADDRESS ${banksel_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_banksel_sel KEEP INPUT ".option_setting_banksel_sel*") + endif() + + if(${bps_sec_status}) + zephyr_linker_section(NAME .option_setting_bps_sec GROUP OFS_BPS_SEC_MEMORY ADDRESS ${bps_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_bps_sec KEEP INPUT ".option_setting_bps_sec*") + endif() + + if(${pbps_sec_status}) + zephyr_linker_section(NAME .option_setting_pbps_sec GROUP OFS_PBPS_SEC_MEMORY ADDRESS ${pbps_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_pbps_sec KEEP INPUT ".option_setting_pbps_sec*") + endif() + + if(${bps_sel_status}) + zephyr_linker_section(NAME .option_setting_bps_sel GROUP OFS_BPS_SEL_MEMORY ADDRESS ${bps_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_bps_sel KEEP INPUT ".option_setting_bps_sel*") + endif() + elseif(CONFIG_LD_LINKER_TEMPLATE) zephyr_linker_sources(SECTIONS sections.ld) zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) + +else() + message(WARNING "Unsupported linker template.") endif() if(CONFIG_ETH_RENESAS_RA_USE_NS_BUF) diff --git a/soc/renesas/ra/ra6m5/CMakeLists.txt b/soc/renesas/ra/ra6m5/CMakeLists.txt index 693af82ebaab..b1b8a9d88f15 100644 --- a/soc/renesas/ra/ra6m5/CMakeLists.txt +++ b/soc/renesas/ra/ra6m5/CMakeLists.txt @@ -7,50 +7,93 @@ zephyr_sources( soc.c ) -dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") -dt_nodelabel(option_setting_dualsel NODELABEL "option_setting_dualsel") -dt_nodelabel(option_setting_ofs1_sec NODELABEL "option_setting_ofs1_sec") -dt_nodelabel(option_setting_banksel_sec NODELABEL "option_setting_banksel_sec") -dt_nodelabel(option_setting_bps_sec NODELABEL "option_setting_bps_sec") -dt_nodelabel(option_setting_pbps_sec NODELABEL "option_setting_pbps_sec") -dt_nodelabel(option_setting_ofs1_sel NODELABEL "option_setting_ofs1_sel") -dt_nodelabel(option_setting_banksel_sel NODELABEL "option_setting_banksel_sel") -dt_nodelabel(option_setting_bps_sel NODELABEL "option_setting_bps_sel") - -dt_reg_addr(ofs0_addr PATH ${option_setting_ofs0}) -dt_reg_addr(dualsel_addr PATH ${option_setting_dualsel}) -dt_reg_addr(ofs1_sec_addr PATH ${option_setting_ofs1_sec}) -dt_reg_addr(banksel_sec_addr PATH ${option_setting_banksel_sec}) -dt_reg_addr(bps_sec_addr PATH ${option_setting_bps_sec}) -dt_reg_addr(pbps_sec_addr PATH ${option_setting_pbps_sec}) -dt_reg_addr(ofs1_sel_addr PATH ${option_setting_ofs1_sel}) -dt_reg_addr(banksel_sel_addr PATH ${option_setting_banksel_sel}) -dt_reg_addr(bps_sel_addr PATH ${option_setting_bps_sel}) - if(CONFIG_CMAKE_LINKER_GENERATOR) - zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) - zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") - zephyr_linker_section(NAME .option_setting_ofs0 GROUP OFS_OFS0_MEMORY ADDRESS ${ofs0_addr}) - zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") - zephyr_linker_section(NAME .option_setting_dualsel GROUP OFS_DUALSEL_MEMORY ADDRESS ${dualsel_addr}) - zephyr_linker_section_configure(SECTION .option_setting_dualsel KEEP INPUT ".option_setting_dualsel*") - zephyr_linker_section(NAME .option_setting_ofs1_sec GROUP OFS_OFS1_SEC_MEMORY ADDRESS ${ofs1_sec_addr}) - zephyr_linker_section_configure(SECTION .option_setting_ofs1_sec KEEP INPUT ".option_setting_ofs1_sec*") - zephyr_linker_section(NAME .option_setting_banksel_sec GROUP OFS_BANKSEL_SEC_MEMORY ADDRESS ${banksel_sec_addr}) - zephyr_linker_section_configure(SECTION .option_setting_banksel_sec KEEP INPUT ".option_setting_banksel_sec*") - zephyr_linker_section(NAME .option_setting_ofs1_sel GROUP OFS_OFS1_SEL_MEMORY ADDRESS ${ofs1_sel_addr}) - zephyr_linker_section_configure(SECTION .option_setting_ofs1_sel KEEP INPUT ".option_setting_ofs1_sel*") - zephyr_linker_section(NAME .option_setting_banksel_sel GROUP OFS_BANKSEL_SEL_MEMORY ADDRESS ${banksel_sel_addr}) - zephyr_linker_section_configure(SECTION .option_setting_banksel_sel KEEP INPUT ".option_setting_banksel_sel*") - zephyr_linker_section(NAME .option_setting_bps_sec GROUP OFS_BPS_SEC_MEMORY ADDRESS ${bps_sec_addr}) - zephyr_linker_section_configure(SECTION .option_setting_bps_sec KEEP INPUT ".option_setting_bps_sec*") - zephyr_linker_section(NAME .option_setting_pbps_sec GROUP OFS_PBPS_SEC_MEMORY ADDRESS ${pbps_sec_addr}) - zephyr_linker_section_configure(SECTION .option_setting_pbps_sec KEEP INPUT ".option_setting_pbps_sec*") - zephyr_linker_section(NAME .option_setting_bps_sel GROUP OFS_BPS_SEL_MEMORY ADDRESS ${bps_sel_addr}) - zephyr_linker_section_configure(SECTION .option_setting_bps_sel KEEP INPUT ".option_setting_bps_sel*") + dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") + dt_nodelabel(option_setting_dualsel NODELABEL "option_setting_dualsel") + dt_nodelabel(option_setting_ofs1_sec NODELABEL "option_setting_ofs1_sec") + dt_nodelabel(option_setting_banksel_sec NODELABEL "option_setting_banksel_sec") + dt_nodelabel(option_setting_bps_sec NODELABEL "option_setting_bps_sec") + dt_nodelabel(option_setting_pbps_sec NODELABEL "option_setting_pbps_sec") + dt_nodelabel(option_setting_ofs1_sel NODELABEL "option_setting_ofs1_sel") + dt_nodelabel(option_setting_banksel_sel NODELABEL "option_setting_banksel_sel") + dt_nodelabel(option_setting_bps_sel NODELABEL "option_setting_bps_sel") + + dt_reg_addr(ofs0_addr PATH ${option_setting_ofs0}) + dt_reg_addr(dualsel_addr PATH ${option_setting_dualsel}) + dt_reg_addr(ofs1_sec_addr PATH ${option_setting_ofs1_sec}) + dt_reg_addr(banksel_sec_addr PATH ${option_setting_banksel_sec}) + dt_reg_addr(bps_sec_addr PATH ${option_setting_bps_sec}) + dt_reg_addr(pbps_sec_addr PATH ${option_setting_pbps_sec}) + dt_reg_addr(ofs1_sel_addr PATH ${option_setting_ofs1_sel}) + dt_reg_addr(banksel_sel_addr PATH ${option_setting_banksel_sel}) + dt_reg_addr(bps_sel_addr PATH ${option_setting_bps_sel}) + + dt_node_has_status(ofs0_status PATH ${option_setting_ofs0} STATUS okay) + dt_node_has_status(dualsel_status PATH ${option_setting_dualsel} STATUS okay) + dt_node_has_status(ofs1_sec_status PATH ${option_setting_ofs1_sec} STATUS okay) + dt_node_has_status(banksel_sec_status PATH ${option_setting_banksel_sec} STATUS okay) + dt_node_has_status(bps_sec_status PATH ${option_setting_bps_sec} STATUS okay) + dt_node_has_status(pbps_sec_status PATH ${option_setting_pbps_sec} STATUS okay) + dt_node_has_status(ofs1_sel_status PATH ${option_setting_ofs1_sel} STATUS okay) + dt_node_has_status(banksel_sel_status PATH ${option_setting_banksel_sel} STATUS okay) + dt_node_has_status(bps_sel_status PATH ${option_setting_bps_sel} STATUS okay) + + if(CONFIG_USE_RA_FSP_DTC) + zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) + zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") + endif() + + if(${ofs0_status}) + zephyr_linker_section(NAME .option_setting_ofs0 GROUP OFS_OFS0_MEMORY ADDRESS ${ofs0_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") + endif() + + if(${dualsel_status}) + zephyr_linker_section(NAME .option_setting_dualsel GROUP OFS_DUALSEL_MEMORY ADDRESS ${dualsel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_dualsel KEEP INPUT ".option_setting_dualsel*") + endif() + + if(${ofs1_sec_status}) + zephyr_linker_section(NAME .option_setting_ofs1_sec GROUP OFS_OFS1_SEC_MEMORY ADDRESS ${ofs1_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs1_sec KEEP INPUT ".option_setting_ofs1_sec*") + endif() + + if(${banksel_sec_status}) + zephyr_linker_section(NAME .option_setting_banksel_sec GROUP OFS_BANKSEL_SEC_MEMORY ADDRESS ${banksel_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_banksel_sec KEEP INPUT ".option_setting_banksel_sec*") + endif() + + if(${ofs1_sel_status}) + zephyr_linker_section(NAME .option_setting_ofs1_sel GROUP OFS_OFS1_SEL_MEMORY ADDRESS ${ofs1_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs1_sel KEEP INPUT ".option_setting_ofs1_sel*") + endif() + + if(${banksel_sel_status}) + zephyr_linker_section(NAME .option_setting_banksel_sel GROUP OFS_BANKSEL_SEL_MEMORY ADDRESS ${banksel_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_banksel_sel KEEP INPUT ".option_setting_banksel_sel*") + endif() + + if(${bps_sec_status}) + zephyr_linker_section(NAME .option_setting_bps_sec GROUP OFS_BPS_SEC_MEMORY ADDRESS ${bps_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_bps_sec KEEP INPUT ".option_setting_bps_sec*") + endif() + + if(${pbps_sec_status}) + zephyr_linker_section(NAME .option_setting_pbps_sec GROUP OFS_PBPS_SEC_MEMORY ADDRESS ${pbps_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_pbps_sec KEEP INPUT ".option_setting_pbps_sec*") + endif() + + if(${bps_sel_status}) + zephyr_linker_section(NAME .option_setting_bps_sel GROUP OFS_BPS_SEL_MEMORY ADDRESS ${bps_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_bps_sel KEEP INPUT ".option_setting_bps_sel*") + endif() + elseif(CONFIG_LD_LINKER_TEMPLATE) zephyr_linker_sources(SECTIONS sections.ld) zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) + +else() + message(WARNING "Unsupported linker template.") endif() if(CONFIG_ETH_RENESAS_RA_USE_NS_BUF) diff --git a/soc/renesas/ra/ra8d1/CMakeLists.txt b/soc/renesas/ra/ra8d1/CMakeLists.txt index 956a3e7bb0ff..b0b66d221709 100644 --- a/soc/renesas/ra/ra8d1/CMakeLists.txt +++ b/soc/renesas/ra/ra8d1/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2024 Renesas Electronics Corporation +# Copyright (c) 2024-2025 Renesas Electronics Corporation # SPDX-License-Identifier: Apache-2.0 zephyr_include_directories(.) @@ -11,54 +11,101 @@ zephyr_sources_ifdef(CONFIG_PM power.c ) -dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") -dt_nodelabel(option_setting_ofs2 NODELABEL "option_setting_ofs2") -dt_nodelabel(option_setting_dualsel NODELABEL "option_setting_dualsel") -dt_nodelabel(option_setting_ofs1_sec NODELABEL "option_setting_ofs1_sec") -dt_nodelabel(option_setting_banksel_sec NODELABEL "option_setting_banksel_sec") -dt_nodelabel(option_setting_bps_sec NODELABEL "option_setting_bps_sec") -dt_nodelabel(option_setting_pbps_sec NODELABEL "option_setting_pbps_sec") -dt_nodelabel(option_setting_ofs1_sel NODELABEL "option_setting_ofs1_sel") -dt_nodelabel(option_setting_banksel_sel NODELABEL "option_setting_banksel_sel") -dt_nodelabel(option_setting_bps_sel NODELABEL "option_setting_bps_sel") - -dt_reg_addr(ofs0_addr PATH ${option_setting_ofs0}) -dt_reg_addr(ofs2_addr PATH ${option_setting_ofs2}) -dt_reg_addr(dualsel_addr PATH ${option_setting_dualsel}) -dt_reg_addr(ofs1_sec_addr PATH ${option_setting_ofs1_sec}) -dt_reg_addr(banksel_sec_addr PATH ${option_setting_banksel_sec}) -dt_reg_addr(bps_sec_addr PATH ${option_setting_bps_sec}) -dt_reg_addr(otp_pbps_sec_addr PATH ${option_setting_pbps_sec}) -dt_reg_addr(ofs1_sel_addr PATH ${option_setting_ofs1_sel}) -dt_reg_addr(banksel_sel_addr PATH ${option_setting_banksel_sel}) -dt_reg_addr(bps_sel_addr PATH ${option_setting_bps_sel}) - if(CONFIG_CMAKE_LINKER_GENERATOR) - zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) - zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") - zephyr_linker_section(NAME .option_setting_ofs0 GROUP OFS_OFS0_MEMORY ADDRESS ${ofs0_addr}) - zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") - zephyr_linker_section(NAME .option_setting_ofs2 GROUP OFS_OFS2_MEMORY ADDRESS ${ofs2_addr}) - zephyr_linker_section_configure(SECTION .option_setting_ofs2 KEEP INPUT ".option_setting_ofs2*") - zephyr_linker_section(NAME .option_setting_dualsel GROUP OFS_DUALSEL_MEMORY ADDRESS ${dualsel_addr}) - zephyr_linker_section_configure(SECTION .option_setting_dualsel KEEP INPUT ".option_setting_dualsel*") - zephyr_linker_section(NAME .option_setting_ofs1_sec GROUP OFS_OFS1_SEC_MEMORY ADDRESS ${ofs1_sec_addr}) - zephyr_linker_section_configure(SECTION .option_setting_ofs1_sec KEEP INPUT ".option_setting_ofs1_sec*") - zephyr_linker_section(NAME .option_setting_banksel_sec GROUP OFS_BANKSEL_SEC_MEMORY ADDRESS ${banksel_sec_addr}) - zephyr_linker_section_configure(SECTION .option_setting_banksel_sec KEEP INPUT ".option_setting_banksel_sec*") - zephyr_linker_section(NAME .option_setting_ofs1_sel GROUP OFS_OFS1_SEL_MEMORY ADDRESS ${ofs1_sel_addr}) - zephyr_linker_section_configure(SECTION .option_setting_ofs1_sel KEEP INPUT ".option_setting_ofs1_sel*") - zephyr_linker_section(NAME .option_setting_banksel_sel GROUP OFS_BANKSEL_SEL_MEMORY ADDRESS ${banksel_sel_addr}) - zephyr_linker_section_configure(SECTION .option_setting_banksel_sel KEEP INPUT ".option_setting_banksel_sel*") - zephyr_linker_section(NAME .option_setting_bps_sec GROUP OFS_BPS_SEC_MEMORY ADDRESS ${bps_sec_addr}) - zephyr_linker_section_configure(SECTION .option_setting_bps_sec KEEP INPUT ".option_setting_bps_sec*") - zephyr_linker_section(NAME .option_setting_pbps_sec GROUP OFS_PBPS_SEC_MEMORY ADDRESS ${otp_pbps_sec_addr}) - zephyr_linker_section_configure(SECTION .option_setting_pbps_sec KEEP INPUT ".option_setting_pbps_sec*") - zephyr_linker_section(NAME .option_setting_bps_sel GROUP OFS_BPS_SEL_MEMORY ADDRESS ${bps_sel_addr}) - zephyr_linker_section_configure(SECTION .option_setting_bps_sel KEEP INPUT ".option_setting_bps_sel*") + dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") + dt_nodelabel(option_setting_ofs2 NODELABEL "option_setting_ofs2") + dt_nodelabel(option_setting_dualsel NODELABEL "option_setting_dualsel") + dt_nodelabel(option_setting_ofs1_sec NODELABEL "option_setting_ofs1_sec") + dt_nodelabel(option_setting_banksel_sec NODELABEL "option_setting_banksel_sec") + dt_nodelabel(option_setting_bps_sec NODELABEL "option_setting_bps_sec") + dt_nodelabel(option_setting_pbps_sec NODELABEL "option_setting_pbps_sec") + dt_nodelabel(option_setting_ofs1_sel NODELABEL "option_setting_ofs1_sel") + dt_nodelabel(option_setting_banksel_sel NODELABEL "option_setting_banksel_sel") + dt_nodelabel(option_setting_bps_sel NODELABEL "option_setting_bps_sel") + + dt_reg_addr(ofs0_addr PATH ${option_setting_ofs0}) + dt_reg_addr(ofs2_addr PATH ${option_setting_ofs2}) + dt_reg_addr(dualsel_addr PATH ${option_setting_dualsel}) + dt_reg_addr(ofs1_sec_addr PATH ${option_setting_ofs1_sec}) + dt_reg_addr(banksel_sec_addr PATH ${option_setting_banksel_sec}) + dt_reg_addr(bps_sec_addr PATH ${option_setting_bps_sec}) + dt_reg_addr(pbps_sec_addr PATH ${option_setting_pbps_sec}) + dt_reg_addr(ofs1_sel_addr PATH ${option_setting_ofs1_sel}) + dt_reg_addr(banksel_sel_addr PATH ${option_setting_banksel_sel}) + dt_reg_addr(bps_sel_addr PATH ${option_setting_bps_sel}) + + dt_node_has_status(ofs0_status PATH ${option_setting_ofs0} STATUS okay) + dt_node_has_status(ofs2_status PATH ${option_setting_ofs2} STATUS okay) + dt_node_has_status(dualsel_status PATH ${option_setting_dualsel} STATUS okay) + dt_node_has_status(ofs1_sec_status PATH ${option_setting_ofs1_sec} STATUS okay) + dt_node_has_status(banksel_sec_status PATH ${option_setting_banksel_sec} STATUS okay) + dt_node_has_status(bps_sec_status PATH ${option_setting_bps_sec} STATUS okay) + dt_node_has_status(pbps_sec_status PATH ${option_setting_pbps_sec} STATUS okay) + dt_node_has_status(ofs1_sel_status PATH ${option_setting_ofs1_sel} STATUS okay) + dt_node_has_status(banksel_sel_status PATH ${option_setting_banksel_sel} STATUS okay) + dt_node_has_status(bps_sel_status PATH ${option_setting_bps_sel} STATUS okay) + + if(CONFIG_USE_RA_FSP_DTC) + zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) + zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") + endif() + + if(${ofs0_status}) + zephyr_linker_section(NAME .option_setting_ofs0 GROUP OFS_OFS0_MEMORY ADDRESS ${ofs0_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") + endif() + + if(${ofs2_status}) + zephyr_linker_section(NAME .option_setting_ofs2 GROUP OFS_OFS2_MEMORY ADDRESS ${ofs2_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs2 KEEP INPUT ".option_setting_ofs2*") + endif() + + if(${dualsel_status}) + zephyr_linker_section(NAME .option_setting_dualsel GROUP OFS_DUALSEL_MEMORY ADDRESS ${dualsel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_dualsel KEEP INPUT ".option_setting_dualsel*") + endif() + + if(${ofs1_sec_status}) + zephyr_linker_section(NAME .option_setting_ofs1_sec GROUP OFS_OFS1_SEC_MEMORY ADDRESS ${ofs1_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs1_sec KEEP INPUT ".option_setting_ofs1_sec*") + endif() + + if(${banksel_sec_status}) + zephyr_linker_section(NAME .option_setting_banksel_sec GROUP OFS_BANKSEL_SEC_MEMORY ADDRESS ${banksel_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_banksel_sec KEEP INPUT ".option_setting_banksel_sec*") + endif() + + if(${ofs1_sel_status}) + zephyr_linker_section(NAME .option_setting_ofs1_sel GROUP OFS_OFS1_SEL_MEMORY ADDRESS ${ofs1_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs1_sel KEEP INPUT ".option_setting_ofs1_sel*") + endif() + + if(${banksel_sel_status}) + zephyr_linker_section(NAME .option_setting_banksel_sel GROUP OFS_BANKSEL_SEL_MEMORY ADDRESS ${banksel_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_banksel_sel KEEP INPUT ".option_setting_banksel_sel*") + endif() + + if(${bps_sec_status}) + zephyr_linker_section(NAME .option_setting_bps_sec GROUP OFS_BPS_SEC_MEMORY ADDRESS ${bps_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_bps_sec KEEP INPUT ".option_setting_bps_sec*") + endif() + + if(${pbps_sec_status}) + zephyr_linker_section(NAME .option_setting_pbps_sec GROUP OFS_PBPS_SEC_MEMORY ADDRESS ${pbps_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_pbps_sec KEEP INPUT ".option_setting_pbps_sec*") + endif() + + if(${bps_sel_status}) + zephyr_linker_section(NAME .option_setting_bps_sel GROUP OFS_BPS_SEL_MEMORY ADDRESS ${bps_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_bps_sel KEEP INPUT ".option_setting_bps_sel*") + endif() + elseif(CONFIG_LD_LINKER_TEMPLATE) zephyr_linker_sources(SECTIONS sections.ld) zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) + +else() + message(WARNING "Unsupported linker template.") endif() set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra8d2/CMakeLists.txt b/soc/renesas/ra/ra8d2/CMakeLists.txt index 9782f69e5390..2e8d68f94cd9 100644 --- a/soc/renesas/ra/ra8d2/CMakeLists.txt +++ b/soc/renesas/ra/ra8d2/CMakeLists.txt @@ -11,50 +11,97 @@ zephyr_sources_ifdef(CONFIG_PM power.c ) -dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") -dt_nodelabel(option_setting_ofs2 NODELABEL "option_setting_ofs2") -dt_nodelabel(option_setting_sas NODELABEL "option_setting_sas") -dt_nodelabel(option_setting_ofs1_sec NODELABEL "option_setting_ofs1_sec") -dt_nodelabel(option_setting_ofs3_sec NODELABEL "option_setting_ofs3_sec") -dt_nodelabel(option_setting_ofs1_sel NODELABEL "option_setting_ofs1_sel") -dt_nodelabel(option_setting_ofs3_sel NODELABEL "option_setting_ofs3_sel") -dt_nodelabel(option_setting_bps_sec NODELABEL "option_setting_bps_sec") -dt_nodelabel(option_setting_otp_pbps_sec NODELABEL "option_setting_otp_pbps_sec") - -dt_reg_addr(ofs0_addr PATH ${option_setting_ofs0}) -dt_reg_addr(ofs2_addr PATH ${option_setting_ofs2}) -dt_reg_addr(sas_addr PATH ${option_setting_sas}) -dt_reg_addr(ofs1_sec_addr PATH ${option_setting_ofs1_sec}) -dt_reg_addr(ofs3_sec_addr PATH ${option_setting_ofs3_sec}) -dt_reg_addr(ofs1_sel_addr PATH ${option_setting_ofs1_sel}) -dt_reg_addr(ofs3_sel_addr PATH ${option_setting_ofs3_sel}) -dt_reg_addr(bps_sec_addr PATH ${option_setting_bps_sec}) -dt_reg_addr(otp_pbps_sec_addr PATH ${option_setting_otp_pbps_sec}) - if(CONFIG_CMAKE_LINKER_GENERATOR) - zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) - zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") - zephyr_linker_section(NAME .option_setting_ofs0 GROUP OFS_OFS0_MEMORY ADDRESS ${ofs0_addr}) - zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") - zephyr_linker_section(NAME .option_setting_ofs2 GROUP OFS_OFS2_MEMORY ADDRESS ${ofs2_addr}) - zephyr_linker_section_configure(SECTION .option_setting_ofs2 KEEP INPUT ".option_setting_ofs2*") - zephyr_linker_section(NAME .option_setting_sas GROUP OFS_SAS_MEMORY ADDRESS ${sas_addr}) - zephyr_linker_section_configure(SECTION .option_setting_sas KEEP INPUT ".option_setting_sas*") - zephyr_linker_section(NAME .option_setting_ofs1_sec GROUP OFS_OFS1_SEC_MEMORY ADDRESS ${ofs1_sec_addr}) - zephyr_linker_section_configure(SECTION .option_setting_ofs1_sec KEEP INPUT ".option_setting_ofs1_sec*") - zephyr_linker_section(NAME .option_setting_ofs3_sec GROUP OFS_OFS3_SEC_MEMORY ADDRESS ${ofs3_sec_addr}) - zephyr_linker_section_configure(SECTION .option_setting_ofs3_sec KEEP INPUT ".option_setting_ofs3_sec*") - zephyr_linker_section(NAME .option_setting_ofs1_sel GROUP OFS_OFS1_SEL_MEMORY ADDRESS ${ofs1_sel_addr}) - zephyr_linker_section_configure(SECTION .option_setting_ofs1_sel KEEP INPUT ".option_setting_ofs1_sel*") - zephyr_linker_section(NAME .option_setting_ofs3_sel GROUP OFS_OFS3_SEL_MEMORY ADDRESS ${ofs3_sel_addr}) - zephyr_linker_section_configure(SECTION .option_setting_ofs3_sel KEEP INPUT ".option_setting_ofs3_sel*") - zephyr_linker_section(NAME .option_setting_bps_sec GROUP OFS_BPS_SEC_MEMORY ADDRESS ${bps_sec_addr}) - zephyr_linker_section_configure(SECTION .option_setting_bps_sec KEEP INPUT ".option_setting_bps_sec*") - zephyr_linker_section(NAME .option_setting_otp_pbps_sec GROUP OFS_OTP_PBPS_SEC_MEMORY ADDRESS ${otp_pbps_sec_addr}) - zephyr_linker_section_configure(SECTION .option_setting_otp_pbps_sec KEEP INPUT ".option_setting_otp_pbps_sec*") + if(CONFIG_USE_RA_FSP_DTC) + zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) + zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") + endif() + + if((NOT CONFIG_BOOTLOADER_MCUBOOT) AND (NOT CONFIG_SOC_RA_SECOND_CORE_BUILD)) + dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") + dt_nodelabel(option_setting_ofs2 NODELABEL "option_setting_ofs2") + dt_nodelabel(option_setting_sas NODELABEL "option_setting_sas") + dt_nodelabel(option_setting_ofs1_sec NODELABEL "option_setting_ofs1_sec") + dt_nodelabel(option_setting_ofs3_sec NODELABEL "option_setting_ofs3_sec") + dt_nodelabel(option_setting_ofs1_sel NODELABEL "option_setting_ofs1_sel") + dt_nodelabel(option_setting_ofs3_sel NODELABEL "option_setting_ofs3_sel") + dt_nodelabel(option_setting_bps_sec NODELABEL "option_setting_bps_sec") + dt_nodelabel(option_setting_otp_pbps_sec NODELABEL "option_setting_otp_pbps_sec") + + dt_reg_addr(ofs0_addr PATH ${option_setting_ofs0}) + dt_reg_addr(ofs2_addr PATH ${option_setting_ofs2}) + dt_reg_addr(sas_addr PATH ${option_setting_sas}) + dt_reg_addr(ofs1_sec_addr PATH ${option_setting_ofs1_sec}) + dt_reg_addr(ofs3_sec_addr PATH ${option_setting_ofs3_sec}) + dt_reg_addr(ofs1_sel_addr PATH ${option_setting_ofs1_sel}) + dt_reg_addr(ofs3_sel_addr PATH ${option_setting_ofs3_sel}) + dt_reg_addr(bps_sec_addr PATH ${option_setting_bps_sec}) + dt_reg_addr(otp_pbps_sec_addr PATH ${option_setting_otp_pbps_sec}) + + dt_node_has_status(ofs0_status PATH ${option_setting_ofs0} STATUS okay) + dt_node_has_status(ofs2_status PATH ${option_setting_ofs2} STATUS okay) + dt_node_has_status(sas_status PATH ${option_setting_sas} STATUS okay) + dt_node_has_status(ofs1_sec_status PATH ${option_setting_ofs1_sec} STATUS okay) + dt_node_has_status(ofs3_sec_status PATH ${option_setting_ofs3_sec} STATUS okay) + dt_node_has_status(ofs1_sel_status PATH ${option_setting_ofs1_sel} STATUS okay) + dt_node_has_status(ofs3_sel_status PATH ${option_setting_ofs3_sel} STATUS okay) + dt_node_has_status(bps_sec_status PATH ${option_setting_bps_sec} STATUS okay) + dt_node_has_status(otp_pbps_sec_status PATH ${option_setting_otp_pbps_sec} STATUS okay) + + if(${ofs0_status}) + zephyr_linker_section(NAME .option_setting_ofs0 GROUP OFS_OFS0_MEMORY ADDRESS ${ofs0_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") + endif() + + if(${ofs2_status}) + zephyr_linker_section(NAME .option_setting_ofs2 GROUP OFS_OFS2_MEMORY ADDRESS ${ofs2_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs2 KEEP INPUT ".option_setting_ofs2*") + endif() + + if(${sas_status}) + zephyr_linker_section(NAME .option_setting_sas GROUP OFS_SAS_MEMORY ADDRESS ${sas_addr}) + zephyr_linker_section_configure(SECTION .option_setting_sas KEEP INPUT ".option_setting_sas*") + endif() + + if(${ofs1_sec_status}) + zephyr_linker_section(NAME .option_setting_ofs1_sec GROUP OFS_OFS1_SEC_MEMORY ADDRESS ${ofs1_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs1_sec KEEP INPUT ".option_setting_ofs1_sec*") + endif() + + if(${ofs3_sec_status}) + zephyr_linker_section(NAME .option_setting_ofs3_sec GROUP OFS_OFS3_SEC_MEMORY ADDRESS ${ofs3_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs3_sec KEEP INPUT ".option_setting_ofs3_sec*") + endif() + + if(${ofs1_sel_status}) + zephyr_linker_section(NAME .option_setting_ofs1_sel GROUP OFS_OFS1_SEL_MEMORY ADDRESS ${ofs1_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs1_sel KEEP INPUT ".option_setting_ofs1_sel*") + endif() + + if(${ofs3_sel_status}) + zephyr_linker_section(NAME .option_setting_ofs3_sel GROUP OFS_OFS3_SEL_MEMORY ADDRESS ${ofs3_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs3_sel KEEP INPUT ".option_setting_ofs3_sel*") + endif() + + if(${bps_sec_status}) + zephyr_linker_section(NAME .option_setting_bps_sec GROUP OFS_BPS_SEC_MEMORY ADDRESS ${bps_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_bps_sec KEEP INPUT ".option_setting_bps_sec*") + endif() + + if(${otp_pbps_sec_status}) + zephyr_linker_section(NAME .option_setting_otp_pbps_sec GROUP OFS_OTP_PBPS_SEC_MEMORY ADDRESS ${otp_pbps_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_otp_pbps_sec KEEP INPUT ".option_setting_otp_pbps_sec*") + endif() + endif() + elseif(CONFIG_LD_LINKER_TEMPLATE) - zephyr_linker_sources(SECTIONS sections.ld) + if((NOT CONFIG_BOOTLOADER_MCUBOOT) AND (NOT CONFIG_SOC_RA_SECOND_CORE_BUILD)) + zephyr_linker_sources(SECTIONS sections.ld) + endif() zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) + +else() + message(WARNING "Unsupported linker template.") endif() set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra8m1/CMakeLists.txt b/soc/renesas/ra/ra8m1/CMakeLists.txt index 956a3e7bb0ff..8550175d0e02 100644 --- a/soc/renesas/ra/ra8m1/CMakeLists.txt +++ b/soc/renesas/ra/ra8m1/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2024 Renesas Electronics Corporation +# Copyright (c) 2024-2025 Renesas Electronics Corporation # SPDX-License-Identifier: Apache-2.0 zephyr_include_directories(.) @@ -11,54 +11,101 @@ zephyr_sources_ifdef(CONFIG_PM power.c ) -dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") -dt_nodelabel(option_setting_ofs2 NODELABEL "option_setting_ofs2") -dt_nodelabel(option_setting_dualsel NODELABEL "option_setting_dualsel") -dt_nodelabel(option_setting_ofs1_sec NODELABEL "option_setting_ofs1_sec") -dt_nodelabel(option_setting_banksel_sec NODELABEL "option_setting_banksel_sec") -dt_nodelabel(option_setting_bps_sec NODELABEL "option_setting_bps_sec") -dt_nodelabel(option_setting_pbps_sec NODELABEL "option_setting_pbps_sec") -dt_nodelabel(option_setting_ofs1_sel NODELABEL "option_setting_ofs1_sel") -dt_nodelabel(option_setting_banksel_sel NODELABEL "option_setting_banksel_sel") -dt_nodelabel(option_setting_bps_sel NODELABEL "option_setting_bps_sel") - -dt_reg_addr(ofs0_addr PATH ${option_setting_ofs0}) -dt_reg_addr(ofs2_addr PATH ${option_setting_ofs2}) -dt_reg_addr(dualsel_addr PATH ${option_setting_dualsel}) -dt_reg_addr(ofs1_sec_addr PATH ${option_setting_ofs1_sec}) -dt_reg_addr(banksel_sec_addr PATH ${option_setting_banksel_sec}) -dt_reg_addr(bps_sec_addr PATH ${option_setting_bps_sec}) -dt_reg_addr(otp_pbps_sec_addr PATH ${option_setting_pbps_sec}) -dt_reg_addr(ofs1_sel_addr PATH ${option_setting_ofs1_sel}) -dt_reg_addr(banksel_sel_addr PATH ${option_setting_banksel_sel}) -dt_reg_addr(bps_sel_addr PATH ${option_setting_bps_sel}) - if(CONFIG_CMAKE_LINKER_GENERATOR) - zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) - zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") - zephyr_linker_section(NAME .option_setting_ofs0 GROUP OFS_OFS0_MEMORY ADDRESS ${ofs0_addr}) - zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") - zephyr_linker_section(NAME .option_setting_ofs2 GROUP OFS_OFS2_MEMORY ADDRESS ${ofs2_addr}) - zephyr_linker_section_configure(SECTION .option_setting_ofs2 KEEP INPUT ".option_setting_ofs2*") - zephyr_linker_section(NAME .option_setting_dualsel GROUP OFS_DUALSEL_MEMORY ADDRESS ${dualsel_addr}) - zephyr_linker_section_configure(SECTION .option_setting_dualsel KEEP INPUT ".option_setting_dualsel*") - zephyr_linker_section(NAME .option_setting_ofs1_sec GROUP OFS_OFS1_SEC_MEMORY ADDRESS ${ofs1_sec_addr}) - zephyr_linker_section_configure(SECTION .option_setting_ofs1_sec KEEP INPUT ".option_setting_ofs1_sec*") - zephyr_linker_section(NAME .option_setting_banksel_sec GROUP OFS_BANKSEL_SEC_MEMORY ADDRESS ${banksel_sec_addr}) - zephyr_linker_section_configure(SECTION .option_setting_banksel_sec KEEP INPUT ".option_setting_banksel_sec*") - zephyr_linker_section(NAME .option_setting_ofs1_sel GROUP OFS_OFS1_SEL_MEMORY ADDRESS ${ofs1_sel_addr}) - zephyr_linker_section_configure(SECTION .option_setting_ofs1_sel KEEP INPUT ".option_setting_ofs1_sel*") - zephyr_linker_section(NAME .option_setting_banksel_sel GROUP OFS_BANKSEL_SEL_MEMORY ADDRESS ${banksel_sel_addr}) - zephyr_linker_section_configure(SECTION .option_setting_banksel_sel KEEP INPUT ".option_setting_banksel_sel*") - zephyr_linker_section(NAME .option_setting_bps_sec GROUP OFS_BPS_SEC_MEMORY ADDRESS ${bps_sec_addr}) - zephyr_linker_section_configure(SECTION .option_setting_bps_sec KEEP INPUT ".option_setting_bps_sec*") - zephyr_linker_section(NAME .option_setting_pbps_sec GROUP OFS_PBPS_SEC_MEMORY ADDRESS ${otp_pbps_sec_addr}) - zephyr_linker_section_configure(SECTION .option_setting_pbps_sec KEEP INPUT ".option_setting_pbps_sec*") - zephyr_linker_section(NAME .option_setting_bps_sel GROUP OFS_BPS_SEL_MEMORY ADDRESS ${bps_sel_addr}) - zephyr_linker_section_configure(SECTION .option_setting_bps_sel KEEP INPUT ".option_setting_bps_sel*") + dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") + dt_nodelabel(option_setting_ofs2 NODELABEL "option_setting_ofs2") + dt_nodelabel(option_setting_dualsel NODELABEL "option_setting_dualsel") + dt_nodelabel(option_setting_ofs1_sec NODELABEL "option_setting_ofs1_sec") + dt_nodelabel(option_setting_banksel_sec NODELABEL "option_setting_banksel_sec") + dt_nodelabel(option_setting_bps_sec NODELABEL "option_setting_bps_sec") + dt_nodelabel(option_setting_pbps_sec NODELABEL "option_setting_pbps_sec") + dt_nodelabel(option_setting_ofs1_sel NODELABEL "option_setting_ofs1_sel") + dt_nodelabel(option_setting_banksel_sel NODELABEL "option_setting_banksel_sel") + dt_nodelabel(option_setting_bps_sel NODELABEL "option_setting_bps_sel") + + dt_reg_addr(ofs0_addr PATH ${option_setting_ofs0}) + dt_reg_addr(ofs2_addr PATH ${option_setting_ofs2}) + dt_reg_addr(dualsel_addr PATH ${option_setting_dualsel}) + dt_reg_addr(ofs1_sec_addr PATH ${option_setting_ofs1_sec}) + dt_reg_addr(banksel_sec_addr PATH ${option_setting_banksel_sec}) + dt_reg_addr(bps_sec_addr PATH ${option_setting_bps_sec}) + dt_reg_addr(otp_pbps_sec_addr PATH ${option_setting_pbps_sec}) + dt_reg_addr(ofs1_sel_addr PATH ${option_setting_ofs1_sel}) + dt_reg_addr(banksel_sel_addr PATH ${option_setting_banksel_sel}) + dt_reg_addr(bps_sel_addr PATH ${option_setting_bps_sel}) + + dt_node_has_status(ofs0_status PATH ${option_setting_ofs0} STATUS okay) + dt_node_has_status(ofs2_status PATH ${option_setting_ofs2} STATUS okay) + dt_node_has_status(dualsel_status PATH ${option_setting_dualsel} STATUS okay) + dt_node_has_status(ofs1_sec_status PATH ${option_setting_ofs1_sec} STATUS okay) + dt_node_has_status(banksel_sec_status PATH ${option_setting_banksel_sec} STATUS okay) + dt_node_has_status(bps_sec_status PATH ${option_setting_bps_sec} STATUS okay) + dt_node_has_status(pbps_sec_status PATH ${option_setting_pbps_sec} STATUS okay) + dt_node_has_status(ofs1_sel_status PATH ${option_setting_ofs1_sel} STATUS okay) + dt_node_has_status(banksel_sel_status PATH ${option_setting_banksel_sel} STATUS okay) + dt_node_has_status(bps_sel_status PATH ${option_setting_bps_sel} STATUS okay) + + if(CONFIG_USE_RA_FSP_DTC) + zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) + zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") + endif() + + if(${ofs0_status}) + zephyr_linker_section(NAME .option_setting_ofs0 GROUP OFS_OFS0_MEMORY ADDRESS ${ofs0_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") + endif() + + if(${ofs2_status}) + zephyr_linker_section(NAME .option_setting_ofs2 GROUP OFS_OFS2_MEMORY ADDRESS ${ofs2_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs2 KEEP INPUT ".option_setting_ofs2*") + endif() + + if(${dualsel_status}) + zephyr_linker_section(NAME .option_setting_dualsel GROUP OFS_DUALSEL_MEMORY ADDRESS ${dualsel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_dualsel KEEP INPUT ".option_setting_dualsel*") + endif() + + if(${ofs1_sec_status}) + zephyr_linker_section(NAME .option_setting_ofs1_sec GROUP OFS_OFS1_SEC_MEMORY ADDRESS ${ofs1_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs1_sec KEEP INPUT ".option_setting_ofs1_sec*") + endif() + + if(${banksel_sec_status}) + zephyr_linker_section(NAME .option_setting_banksel_sec GROUP OFS_BANKSEL_SEC_MEMORY ADDRESS ${banksel_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_banksel_sec KEEP INPUT ".option_setting_banksel_sec*") + endif() + + if(${ofs1_sel_status}) + zephyr_linker_section(NAME .option_setting_ofs1_sel GROUP OFS_OFS1_SEL_MEMORY ADDRESS ${ofs1_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs1_sel KEEP INPUT ".option_setting_ofs1_sel*") + endif() + + if(${banksel_sel_status}) + zephyr_linker_section(NAME .option_setting_banksel_sel GROUP OFS_BANKSEL_SEL_MEMORY ADDRESS ${banksel_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_banksel_sel KEEP INPUT ".option_setting_banksel_sel*") + endif() + + if(${bps_sec_status}) + zephyr_linker_section(NAME .option_setting_bps_sec GROUP OFS_BPS_SEC_MEMORY ADDRESS ${bps_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_bps_sec KEEP INPUT ".option_setting_bps_sec*") + endif() + + if(${pbps_sec_status}) + zephyr_linker_section(NAME .option_setting_pbps_sec GROUP OFS_PBPS_SEC_MEMORY ADDRESS ${otp_pbps_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_pbps_sec KEEP INPUT ".option_setting_pbps_sec*") + endif() + + if(${bps_sel_status}) + zephyr_linker_section(NAME .option_setting_bps_sel GROUP OFS_BPS_SEL_MEMORY ADDRESS ${bps_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_bps_sel KEEP INPUT ".option_setting_bps_sel*") + endif() + elseif(CONFIG_LD_LINKER_TEMPLATE) zephyr_linker_sources(SECTIONS sections.ld) zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) + +else() + message(WARNING "Unsupported linker template.") endif() set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra8m2/CMakeLists.txt b/soc/renesas/ra/ra8m2/CMakeLists.txt index 9782f69e5390..2e8d68f94cd9 100644 --- a/soc/renesas/ra/ra8m2/CMakeLists.txt +++ b/soc/renesas/ra/ra8m2/CMakeLists.txt @@ -11,50 +11,97 @@ zephyr_sources_ifdef(CONFIG_PM power.c ) -dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") -dt_nodelabel(option_setting_ofs2 NODELABEL "option_setting_ofs2") -dt_nodelabel(option_setting_sas NODELABEL "option_setting_sas") -dt_nodelabel(option_setting_ofs1_sec NODELABEL "option_setting_ofs1_sec") -dt_nodelabel(option_setting_ofs3_sec NODELABEL "option_setting_ofs3_sec") -dt_nodelabel(option_setting_ofs1_sel NODELABEL "option_setting_ofs1_sel") -dt_nodelabel(option_setting_ofs3_sel NODELABEL "option_setting_ofs3_sel") -dt_nodelabel(option_setting_bps_sec NODELABEL "option_setting_bps_sec") -dt_nodelabel(option_setting_otp_pbps_sec NODELABEL "option_setting_otp_pbps_sec") - -dt_reg_addr(ofs0_addr PATH ${option_setting_ofs0}) -dt_reg_addr(ofs2_addr PATH ${option_setting_ofs2}) -dt_reg_addr(sas_addr PATH ${option_setting_sas}) -dt_reg_addr(ofs1_sec_addr PATH ${option_setting_ofs1_sec}) -dt_reg_addr(ofs3_sec_addr PATH ${option_setting_ofs3_sec}) -dt_reg_addr(ofs1_sel_addr PATH ${option_setting_ofs1_sel}) -dt_reg_addr(ofs3_sel_addr PATH ${option_setting_ofs3_sel}) -dt_reg_addr(bps_sec_addr PATH ${option_setting_bps_sec}) -dt_reg_addr(otp_pbps_sec_addr PATH ${option_setting_otp_pbps_sec}) - if(CONFIG_CMAKE_LINKER_GENERATOR) - zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) - zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") - zephyr_linker_section(NAME .option_setting_ofs0 GROUP OFS_OFS0_MEMORY ADDRESS ${ofs0_addr}) - zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") - zephyr_linker_section(NAME .option_setting_ofs2 GROUP OFS_OFS2_MEMORY ADDRESS ${ofs2_addr}) - zephyr_linker_section_configure(SECTION .option_setting_ofs2 KEEP INPUT ".option_setting_ofs2*") - zephyr_linker_section(NAME .option_setting_sas GROUP OFS_SAS_MEMORY ADDRESS ${sas_addr}) - zephyr_linker_section_configure(SECTION .option_setting_sas KEEP INPUT ".option_setting_sas*") - zephyr_linker_section(NAME .option_setting_ofs1_sec GROUP OFS_OFS1_SEC_MEMORY ADDRESS ${ofs1_sec_addr}) - zephyr_linker_section_configure(SECTION .option_setting_ofs1_sec KEEP INPUT ".option_setting_ofs1_sec*") - zephyr_linker_section(NAME .option_setting_ofs3_sec GROUP OFS_OFS3_SEC_MEMORY ADDRESS ${ofs3_sec_addr}) - zephyr_linker_section_configure(SECTION .option_setting_ofs3_sec KEEP INPUT ".option_setting_ofs3_sec*") - zephyr_linker_section(NAME .option_setting_ofs1_sel GROUP OFS_OFS1_SEL_MEMORY ADDRESS ${ofs1_sel_addr}) - zephyr_linker_section_configure(SECTION .option_setting_ofs1_sel KEEP INPUT ".option_setting_ofs1_sel*") - zephyr_linker_section(NAME .option_setting_ofs3_sel GROUP OFS_OFS3_SEL_MEMORY ADDRESS ${ofs3_sel_addr}) - zephyr_linker_section_configure(SECTION .option_setting_ofs3_sel KEEP INPUT ".option_setting_ofs3_sel*") - zephyr_linker_section(NAME .option_setting_bps_sec GROUP OFS_BPS_SEC_MEMORY ADDRESS ${bps_sec_addr}) - zephyr_linker_section_configure(SECTION .option_setting_bps_sec KEEP INPUT ".option_setting_bps_sec*") - zephyr_linker_section(NAME .option_setting_otp_pbps_sec GROUP OFS_OTP_PBPS_SEC_MEMORY ADDRESS ${otp_pbps_sec_addr}) - zephyr_linker_section_configure(SECTION .option_setting_otp_pbps_sec KEEP INPUT ".option_setting_otp_pbps_sec*") + if(CONFIG_USE_RA_FSP_DTC) + zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) + zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") + endif() + + if((NOT CONFIG_BOOTLOADER_MCUBOOT) AND (NOT CONFIG_SOC_RA_SECOND_CORE_BUILD)) + dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") + dt_nodelabel(option_setting_ofs2 NODELABEL "option_setting_ofs2") + dt_nodelabel(option_setting_sas NODELABEL "option_setting_sas") + dt_nodelabel(option_setting_ofs1_sec NODELABEL "option_setting_ofs1_sec") + dt_nodelabel(option_setting_ofs3_sec NODELABEL "option_setting_ofs3_sec") + dt_nodelabel(option_setting_ofs1_sel NODELABEL "option_setting_ofs1_sel") + dt_nodelabel(option_setting_ofs3_sel NODELABEL "option_setting_ofs3_sel") + dt_nodelabel(option_setting_bps_sec NODELABEL "option_setting_bps_sec") + dt_nodelabel(option_setting_otp_pbps_sec NODELABEL "option_setting_otp_pbps_sec") + + dt_reg_addr(ofs0_addr PATH ${option_setting_ofs0}) + dt_reg_addr(ofs2_addr PATH ${option_setting_ofs2}) + dt_reg_addr(sas_addr PATH ${option_setting_sas}) + dt_reg_addr(ofs1_sec_addr PATH ${option_setting_ofs1_sec}) + dt_reg_addr(ofs3_sec_addr PATH ${option_setting_ofs3_sec}) + dt_reg_addr(ofs1_sel_addr PATH ${option_setting_ofs1_sel}) + dt_reg_addr(ofs3_sel_addr PATH ${option_setting_ofs3_sel}) + dt_reg_addr(bps_sec_addr PATH ${option_setting_bps_sec}) + dt_reg_addr(otp_pbps_sec_addr PATH ${option_setting_otp_pbps_sec}) + + dt_node_has_status(ofs0_status PATH ${option_setting_ofs0} STATUS okay) + dt_node_has_status(ofs2_status PATH ${option_setting_ofs2} STATUS okay) + dt_node_has_status(sas_status PATH ${option_setting_sas} STATUS okay) + dt_node_has_status(ofs1_sec_status PATH ${option_setting_ofs1_sec} STATUS okay) + dt_node_has_status(ofs3_sec_status PATH ${option_setting_ofs3_sec} STATUS okay) + dt_node_has_status(ofs1_sel_status PATH ${option_setting_ofs1_sel} STATUS okay) + dt_node_has_status(ofs3_sel_status PATH ${option_setting_ofs3_sel} STATUS okay) + dt_node_has_status(bps_sec_status PATH ${option_setting_bps_sec} STATUS okay) + dt_node_has_status(otp_pbps_sec_status PATH ${option_setting_otp_pbps_sec} STATUS okay) + + if(${ofs0_status}) + zephyr_linker_section(NAME .option_setting_ofs0 GROUP OFS_OFS0_MEMORY ADDRESS ${ofs0_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") + endif() + + if(${ofs2_status}) + zephyr_linker_section(NAME .option_setting_ofs2 GROUP OFS_OFS2_MEMORY ADDRESS ${ofs2_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs2 KEEP INPUT ".option_setting_ofs2*") + endif() + + if(${sas_status}) + zephyr_linker_section(NAME .option_setting_sas GROUP OFS_SAS_MEMORY ADDRESS ${sas_addr}) + zephyr_linker_section_configure(SECTION .option_setting_sas KEEP INPUT ".option_setting_sas*") + endif() + + if(${ofs1_sec_status}) + zephyr_linker_section(NAME .option_setting_ofs1_sec GROUP OFS_OFS1_SEC_MEMORY ADDRESS ${ofs1_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs1_sec KEEP INPUT ".option_setting_ofs1_sec*") + endif() + + if(${ofs3_sec_status}) + zephyr_linker_section(NAME .option_setting_ofs3_sec GROUP OFS_OFS3_SEC_MEMORY ADDRESS ${ofs3_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs3_sec KEEP INPUT ".option_setting_ofs3_sec*") + endif() + + if(${ofs1_sel_status}) + zephyr_linker_section(NAME .option_setting_ofs1_sel GROUP OFS_OFS1_SEL_MEMORY ADDRESS ${ofs1_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs1_sel KEEP INPUT ".option_setting_ofs1_sel*") + endif() + + if(${ofs3_sel_status}) + zephyr_linker_section(NAME .option_setting_ofs3_sel GROUP OFS_OFS3_SEL_MEMORY ADDRESS ${ofs3_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs3_sel KEEP INPUT ".option_setting_ofs3_sel*") + endif() + + if(${bps_sec_status}) + zephyr_linker_section(NAME .option_setting_bps_sec GROUP OFS_BPS_SEC_MEMORY ADDRESS ${bps_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_bps_sec KEEP INPUT ".option_setting_bps_sec*") + endif() + + if(${otp_pbps_sec_status}) + zephyr_linker_section(NAME .option_setting_otp_pbps_sec GROUP OFS_OTP_PBPS_SEC_MEMORY ADDRESS ${otp_pbps_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_otp_pbps_sec KEEP INPUT ".option_setting_otp_pbps_sec*") + endif() + endif() + elseif(CONFIG_LD_LINKER_TEMPLATE) - zephyr_linker_sources(SECTIONS sections.ld) + if((NOT CONFIG_BOOTLOADER_MCUBOOT) AND (NOT CONFIG_SOC_RA_SECOND_CORE_BUILD)) + zephyr_linker_sources(SECTIONS sections.ld) + endif() zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) + +else() + message(WARNING "Unsupported linker template.") endif() set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra8p1/CMakeLists.txt b/soc/renesas/ra/ra8p1/CMakeLists.txt index 9782f69e5390..2e8d68f94cd9 100644 --- a/soc/renesas/ra/ra8p1/CMakeLists.txt +++ b/soc/renesas/ra/ra8p1/CMakeLists.txt @@ -11,50 +11,97 @@ zephyr_sources_ifdef(CONFIG_PM power.c ) -dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") -dt_nodelabel(option_setting_ofs2 NODELABEL "option_setting_ofs2") -dt_nodelabel(option_setting_sas NODELABEL "option_setting_sas") -dt_nodelabel(option_setting_ofs1_sec NODELABEL "option_setting_ofs1_sec") -dt_nodelabel(option_setting_ofs3_sec NODELABEL "option_setting_ofs3_sec") -dt_nodelabel(option_setting_ofs1_sel NODELABEL "option_setting_ofs1_sel") -dt_nodelabel(option_setting_ofs3_sel NODELABEL "option_setting_ofs3_sel") -dt_nodelabel(option_setting_bps_sec NODELABEL "option_setting_bps_sec") -dt_nodelabel(option_setting_otp_pbps_sec NODELABEL "option_setting_otp_pbps_sec") - -dt_reg_addr(ofs0_addr PATH ${option_setting_ofs0}) -dt_reg_addr(ofs2_addr PATH ${option_setting_ofs2}) -dt_reg_addr(sas_addr PATH ${option_setting_sas}) -dt_reg_addr(ofs1_sec_addr PATH ${option_setting_ofs1_sec}) -dt_reg_addr(ofs3_sec_addr PATH ${option_setting_ofs3_sec}) -dt_reg_addr(ofs1_sel_addr PATH ${option_setting_ofs1_sel}) -dt_reg_addr(ofs3_sel_addr PATH ${option_setting_ofs3_sel}) -dt_reg_addr(bps_sec_addr PATH ${option_setting_bps_sec}) -dt_reg_addr(otp_pbps_sec_addr PATH ${option_setting_otp_pbps_sec}) - if(CONFIG_CMAKE_LINKER_GENERATOR) - zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) - zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") - zephyr_linker_section(NAME .option_setting_ofs0 GROUP OFS_OFS0_MEMORY ADDRESS ${ofs0_addr}) - zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") - zephyr_linker_section(NAME .option_setting_ofs2 GROUP OFS_OFS2_MEMORY ADDRESS ${ofs2_addr}) - zephyr_linker_section_configure(SECTION .option_setting_ofs2 KEEP INPUT ".option_setting_ofs2*") - zephyr_linker_section(NAME .option_setting_sas GROUP OFS_SAS_MEMORY ADDRESS ${sas_addr}) - zephyr_linker_section_configure(SECTION .option_setting_sas KEEP INPUT ".option_setting_sas*") - zephyr_linker_section(NAME .option_setting_ofs1_sec GROUP OFS_OFS1_SEC_MEMORY ADDRESS ${ofs1_sec_addr}) - zephyr_linker_section_configure(SECTION .option_setting_ofs1_sec KEEP INPUT ".option_setting_ofs1_sec*") - zephyr_linker_section(NAME .option_setting_ofs3_sec GROUP OFS_OFS3_SEC_MEMORY ADDRESS ${ofs3_sec_addr}) - zephyr_linker_section_configure(SECTION .option_setting_ofs3_sec KEEP INPUT ".option_setting_ofs3_sec*") - zephyr_linker_section(NAME .option_setting_ofs1_sel GROUP OFS_OFS1_SEL_MEMORY ADDRESS ${ofs1_sel_addr}) - zephyr_linker_section_configure(SECTION .option_setting_ofs1_sel KEEP INPUT ".option_setting_ofs1_sel*") - zephyr_linker_section(NAME .option_setting_ofs3_sel GROUP OFS_OFS3_SEL_MEMORY ADDRESS ${ofs3_sel_addr}) - zephyr_linker_section_configure(SECTION .option_setting_ofs3_sel KEEP INPUT ".option_setting_ofs3_sel*") - zephyr_linker_section(NAME .option_setting_bps_sec GROUP OFS_BPS_SEC_MEMORY ADDRESS ${bps_sec_addr}) - zephyr_linker_section_configure(SECTION .option_setting_bps_sec KEEP INPUT ".option_setting_bps_sec*") - zephyr_linker_section(NAME .option_setting_otp_pbps_sec GROUP OFS_OTP_PBPS_SEC_MEMORY ADDRESS ${otp_pbps_sec_addr}) - zephyr_linker_section_configure(SECTION .option_setting_otp_pbps_sec KEEP INPUT ".option_setting_otp_pbps_sec*") + if(CONFIG_USE_RA_FSP_DTC) + zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) + zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") + endif() + + if((NOT CONFIG_BOOTLOADER_MCUBOOT) AND (NOT CONFIG_SOC_RA_SECOND_CORE_BUILD)) + dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") + dt_nodelabel(option_setting_ofs2 NODELABEL "option_setting_ofs2") + dt_nodelabel(option_setting_sas NODELABEL "option_setting_sas") + dt_nodelabel(option_setting_ofs1_sec NODELABEL "option_setting_ofs1_sec") + dt_nodelabel(option_setting_ofs3_sec NODELABEL "option_setting_ofs3_sec") + dt_nodelabel(option_setting_ofs1_sel NODELABEL "option_setting_ofs1_sel") + dt_nodelabel(option_setting_ofs3_sel NODELABEL "option_setting_ofs3_sel") + dt_nodelabel(option_setting_bps_sec NODELABEL "option_setting_bps_sec") + dt_nodelabel(option_setting_otp_pbps_sec NODELABEL "option_setting_otp_pbps_sec") + + dt_reg_addr(ofs0_addr PATH ${option_setting_ofs0}) + dt_reg_addr(ofs2_addr PATH ${option_setting_ofs2}) + dt_reg_addr(sas_addr PATH ${option_setting_sas}) + dt_reg_addr(ofs1_sec_addr PATH ${option_setting_ofs1_sec}) + dt_reg_addr(ofs3_sec_addr PATH ${option_setting_ofs3_sec}) + dt_reg_addr(ofs1_sel_addr PATH ${option_setting_ofs1_sel}) + dt_reg_addr(ofs3_sel_addr PATH ${option_setting_ofs3_sel}) + dt_reg_addr(bps_sec_addr PATH ${option_setting_bps_sec}) + dt_reg_addr(otp_pbps_sec_addr PATH ${option_setting_otp_pbps_sec}) + + dt_node_has_status(ofs0_status PATH ${option_setting_ofs0} STATUS okay) + dt_node_has_status(ofs2_status PATH ${option_setting_ofs2} STATUS okay) + dt_node_has_status(sas_status PATH ${option_setting_sas} STATUS okay) + dt_node_has_status(ofs1_sec_status PATH ${option_setting_ofs1_sec} STATUS okay) + dt_node_has_status(ofs3_sec_status PATH ${option_setting_ofs3_sec} STATUS okay) + dt_node_has_status(ofs1_sel_status PATH ${option_setting_ofs1_sel} STATUS okay) + dt_node_has_status(ofs3_sel_status PATH ${option_setting_ofs3_sel} STATUS okay) + dt_node_has_status(bps_sec_status PATH ${option_setting_bps_sec} STATUS okay) + dt_node_has_status(otp_pbps_sec_status PATH ${option_setting_otp_pbps_sec} STATUS okay) + + if(${ofs0_status}) + zephyr_linker_section(NAME .option_setting_ofs0 GROUP OFS_OFS0_MEMORY ADDRESS ${ofs0_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") + endif() + + if(${ofs2_status}) + zephyr_linker_section(NAME .option_setting_ofs2 GROUP OFS_OFS2_MEMORY ADDRESS ${ofs2_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs2 KEEP INPUT ".option_setting_ofs2*") + endif() + + if(${sas_status}) + zephyr_linker_section(NAME .option_setting_sas GROUP OFS_SAS_MEMORY ADDRESS ${sas_addr}) + zephyr_linker_section_configure(SECTION .option_setting_sas KEEP INPUT ".option_setting_sas*") + endif() + + if(${ofs1_sec_status}) + zephyr_linker_section(NAME .option_setting_ofs1_sec GROUP OFS_OFS1_SEC_MEMORY ADDRESS ${ofs1_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs1_sec KEEP INPUT ".option_setting_ofs1_sec*") + endif() + + if(${ofs3_sec_status}) + zephyr_linker_section(NAME .option_setting_ofs3_sec GROUP OFS_OFS3_SEC_MEMORY ADDRESS ${ofs3_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs3_sec KEEP INPUT ".option_setting_ofs3_sec*") + endif() + + if(${ofs1_sel_status}) + zephyr_linker_section(NAME .option_setting_ofs1_sel GROUP OFS_OFS1_SEL_MEMORY ADDRESS ${ofs1_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs1_sel KEEP INPUT ".option_setting_ofs1_sel*") + endif() + + if(${ofs3_sel_status}) + zephyr_linker_section(NAME .option_setting_ofs3_sel GROUP OFS_OFS3_SEL_MEMORY ADDRESS ${ofs3_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs3_sel KEEP INPUT ".option_setting_ofs3_sel*") + endif() + + if(${bps_sec_status}) + zephyr_linker_section(NAME .option_setting_bps_sec GROUP OFS_BPS_SEC_MEMORY ADDRESS ${bps_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_bps_sec KEEP INPUT ".option_setting_bps_sec*") + endif() + + if(${otp_pbps_sec_status}) + zephyr_linker_section(NAME .option_setting_otp_pbps_sec GROUP OFS_OTP_PBPS_SEC_MEMORY ADDRESS ${otp_pbps_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_otp_pbps_sec KEEP INPUT ".option_setting_otp_pbps_sec*") + endif() + endif() + elseif(CONFIG_LD_LINKER_TEMPLATE) - zephyr_linker_sources(SECTIONS sections.ld) + if((NOT CONFIG_BOOTLOADER_MCUBOOT) AND (NOT CONFIG_SOC_RA_SECOND_CORE_BUILD)) + zephyr_linker_sources(SECTIONS sections.ld) + endif() zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) + +else() + message(WARNING "Unsupported linker template.") endif() set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra8t1/CMakeLists.txt b/soc/renesas/ra/ra8t1/CMakeLists.txt index 956a3e7bb0ff..8550175d0e02 100644 --- a/soc/renesas/ra/ra8t1/CMakeLists.txt +++ b/soc/renesas/ra/ra8t1/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2024 Renesas Electronics Corporation +# Copyright (c) 2024-2025 Renesas Electronics Corporation # SPDX-License-Identifier: Apache-2.0 zephyr_include_directories(.) @@ -11,54 +11,101 @@ zephyr_sources_ifdef(CONFIG_PM power.c ) -dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") -dt_nodelabel(option_setting_ofs2 NODELABEL "option_setting_ofs2") -dt_nodelabel(option_setting_dualsel NODELABEL "option_setting_dualsel") -dt_nodelabel(option_setting_ofs1_sec NODELABEL "option_setting_ofs1_sec") -dt_nodelabel(option_setting_banksel_sec NODELABEL "option_setting_banksel_sec") -dt_nodelabel(option_setting_bps_sec NODELABEL "option_setting_bps_sec") -dt_nodelabel(option_setting_pbps_sec NODELABEL "option_setting_pbps_sec") -dt_nodelabel(option_setting_ofs1_sel NODELABEL "option_setting_ofs1_sel") -dt_nodelabel(option_setting_banksel_sel NODELABEL "option_setting_banksel_sel") -dt_nodelabel(option_setting_bps_sel NODELABEL "option_setting_bps_sel") - -dt_reg_addr(ofs0_addr PATH ${option_setting_ofs0}) -dt_reg_addr(ofs2_addr PATH ${option_setting_ofs2}) -dt_reg_addr(dualsel_addr PATH ${option_setting_dualsel}) -dt_reg_addr(ofs1_sec_addr PATH ${option_setting_ofs1_sec}) -dt_reg_addr(banksel_sec_addr PATH ${option_setting_banksel_sec}) -dt_reg_addr(bps_sec_addr PATH ${option_setting_bps_sec}) -dt_reg_addr(otp_pbps_sec_addr PATH ${option_setting_pbps_sec}) -dt_reg_addr(ofs1_sel_addr PATH ${option_setting_ofs1_sel}) -dt_reg_addr(banksel_sel_addr PATH ${option_setting_banksel_sel}) -dt_reg_addr(bps_sel_addr PATH ${option_setting_bps_sel}) - if(CONFIG_CMAKE_LINKER_GENERATOR) - zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) - zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") - zephyr_linker_section(NAME .option_setting_ofs0 GROUP OFS_OFS0_MEMORY ADDRESS ${ofs0_addr}) - zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") - zephyr_linker_section(NAME .option_setting_ofs2 GROUP OFS_OFS2_MEMORY ADDRESS ${ofs2_addr}) - zephyr_linker_section_configure(SECTION .option_setting_ofs2 KEEP INPUT ".option_setting_ofs2*") - zephyr_linker_section(NAME .option_setting_dualsel GROUP OFS_DUALSEL_MEMORY ADDRESS ${dualsel_addr}) - zephyr_linker_section_configure(SECTION .option_setting_dualsel KEEP INPUT ".option_setting_dualsel*") - zephyr_linker_section(NAME .option_setting_ofs1_sec GROUP OFS_OFS1_SEC_MEMORY ADDRESS ${ofs1_sec_addr}) - zephyr_linker_section_configure(SECTION .option_setting_ofs1_sec KEEP INPUT ".option_setting_ofs1_sec*") - zephyr_linker_section(NAME .option_setting_banksel_sec GROUP OFS_BANKSEL_SEC_MEMORY ADDRESS ${banksel_sec_addr}) - zephyr_linker_section_configure(SECTION .option_setting_banksel_sec KEEP INPUT ".option_setting_banksel_sec*") - zephyr_linker_section(NAME .option_setting_ofs1_sel GROUP OFS_OFS1_SEL_MEMORY ADDRESS ${ofs1_sel_addr}) - zephyr_linker_section_configure(SECTION .option_setting_ofs1_sel KEEP INPUT ".option_setting_ofs1_sel*") - zephyr_linker_section(NAME .option_setting_banksel_sel GROUP OFS_BANKSEL_SEL_MEMORY ADDRESS ${banksel_sel_addr}) - zephyr_linker_section_configure(SECTION .option_setting_banksel_sel KEEP INPUT ".option_setting_banksel_sel*") - zephyr_linker_section(NAME .option_setting_bps_sec GROUP OFS_BPS_SEC_MEMORY ADDRESS ${bps_sec_addr}) - zephyr_linker_section_configure(SECTION .option_setting_bps_sec KEEP INPUT ".option_setting_bps_sec*") - zephyr_linker_section(NAME .option_setting_pbps_sec GROUP OFS_PBPS_SEC_MEMORY ADDRESS ${otp_pbps_sec_addr}) - zephyr_linker_section_configure(SECTION .option_setting_pbps_sec KEEP INPUT ".option_setting_pbps_sec*") - zephyr_linker_section(NAME .option_setting_bps_sel GROUP OFS_BPS_SEL_MEMORY ADDRESS ${bps_sel_addr}) - zephyr_linker_section_configure(SECTION .option_setting_bps_sel KEEP INPUT ".option_setting_bps_sel*") + dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") + dt_nodelabel(option_setting_ofs2 NODELABEL "option_setting_ofs2") + dt_nodelabel(option_setting_dualsel NODELABEL "option_setting_dualsel") + dt_nodelabel(option_setting_ofs1_sec NODELABEL "option_setting_ofs1_sec") + dt_nodelabel(option_setting_banksel_sec NODELABEL "option_setting_banksel_sec") + dt_nodelabel(option_setting_bps_sec NODELABEL "option_setting_bps_sec") + dt_nodelabel(option_setting_pbps_sec NODELABEL "option_setting_pbps_sec") + dt_nodelabel(option_setting_ofs1_sel NODELABEL "option_setting_ofs1_sel") + dt_nodelabel(option_setting_banksel_sel NODELABEL "option_setting_banksel_sel") + dt_nodelabel(option_setting_bps_sel NODELABEL "option_setting_bps_sel") + + dt_reg_addr(ofs0_addr PATH ${option_setting_ofs0}) + dt_reg_addr(ofs2_addr PATH ${option_setting_ofs2}) + dt_reg_addr(dualsel_addr PATH ${option_setting_dualsel}) + dt_reg_addr(ofs1_sec_addr PATH ${option_setting_ofs1_sec}) + dt_reg_addr(banksel_sec_addr PATH ${option_setting_banksel_sec}) + dt_reg_addr(bps_sec_addr PATH ${option_setting_bps_sec}) + dt_reg_addr(otp_pbps_sec_addr PATH ${option_setting_pbps_sec}) + dt_reg_addr(ofs1_sel_addr PATH ${option_setting_ofs1_sel}) + dt_reg_addr(banksel_sel_addr PATH ${option_setting_banksel_sel}) + dt_reg_addr(bps_sel_addr PATH ${option_setting_bps_sel}) + + dt_node_has_status(ofs0_status PATH ${option_setting_ofs0} STATUS okay) + dt_node_has_status(ofs2_status PATH ${option_setting_ofs2} STATUS okay) + dt_node_has_status(dualsel_status PATH ${option_setting_dualsel} STATUS okay) + dt_node_has_status(ofs1_sec_status PATH ${option_setting_ofs1_sec} STATUS okay) + dt_node_has_status(banksel_sec_status PATH ${option_setting_banksel_sec} STATUS okay) + dt_node_has_status(bps_sec_status PATH ${option_setting_bps_sec} STATUS okay) + dt_node_has_status(pbps_sec_status PATH ${option_setting_pbps_sec} STATUS okay) + dt_node_has_status(ofs1_sel_status PATH ${option_setting_ofs1_sel} STATUS okay) + dt_node_has_status(banksel_sel_status PATH ${option_setting_banksel_sel} STATUS okay) + dt_node_has_status(bps_sel_status PATH ${option_setting_bps_sel} STATUS okay) + + if(CONFIG_USE_RA_FSP_DTC) + zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) + zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") + endif() + + if(${ofs0_status}) + zephyr_linker_section(NAME .option_setting_ofs0 GROUP OFS_OFS0_MEMORY ADDRESS ${ofs0_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") + endif() + + if(${ofs2_status}) + zephyr_linker_section(NAME .option_setting_ofs2 GROUP OFS_OFS2_MEMORY ADDRESS ${ofs2_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs2 KEEP INPUT ".option_setting_ofs2*") + endif() + + if(${dualsel_status}) + zephyr_linker_section(NAME .option_setting_dualsel GROUP OFS_DUALSEL_MEMORY ADDRESS ${dualsel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_dualsel KEEP INPUT ".option_setting_dualsel*") + endif() + + if(${ofs1_sec_status}) + zephyr_linker_section(NAME .option_setting_ofs1_sec GROUP OFS_OFS1_SEC_MEMORY ADDRESS ${ofs1_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs1_sec KEEP INPUT ".option_setting_ofs1_sec*") + endif() + + if(${banksel_sec_status}) + zephyr_linker_section(NAME .option_setting_banksel_sec GROUP OFS_BANKSEL_SEC_MEMORY ADDRESS ${banksel_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_banksel_sec KEEP INPUT ".option_setting_banksel_sec*") + endif() + + if(${ofs1_sel_status}) + zephyr_linker_section(NAME .option_setting_ofs1_sel GROUP OFS_OFS1_SEL_MEMORY ADDRESS ${ofs1_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs1_sel KEEP INPUT ".option_setting_ofs1_sel*") + endif() + + if(${banksel_sel_status}) + zephyr_linker_section(NAME .option_setting_banksel_sel GROUP OFS_BANKSEL_SEL_MEMORY ADDRESS ${banksel_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_banksel_sel KEEP INPUT ".option_setting_banksel_sel*") + endif() + + if(${bps_sec_status}) + zephyr_linker_section(NAME .option_setting_bps_sec GROUP OFS_BPS_SEC_MEMORY ADDRESS ${bps_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_bps_sec KEEP INPUT ".option_setting_bps_sec*") + endif() + + if(${pbps_sec_status}) + zephyr_linker_section(NAME .option_setting_pbps_sec GROUP OFS_PBPS_SEC_MEMORY ADDRESS ${otp_pbps_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_pbps_sec KEEP INPUT ".option_setting_pbps_sec*") + endif() + + if(${bps_sel_status}) + zephyr_linker_section(NAME .option_setting_bps_sel GROUP OFS_BPS_SEL_MEMORY ADDRESS ${bps_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_bps_sel KEEP INPUT ".option_setting_bps_sel*") + endif() + elseif(CONFIG_LD_LINKER_TEMPLATE) zephyr_linker_sources(SECTIONS sections.ld) zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) + +else() + message(WARNING "Unsupported linker template.") endif() set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra8t2/CMakeLists.txt b/soc/renesas/ra/ra8t2/CMakeLists.txt index 9782f69e5390..2e8d68f94cd9 100644 --- a/soc/renesas/ra/ra8t2/CMakeLists.txt +++ b/soc/renesas/ra/ra8t2/CMakeLists.txt @@ -11,50 +11,97 @@ zephyr_sources_ifdef(CONFIG_PM power.c ) -dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") -dt_nodelabel(option_setting_ofs2 NODELABEL "option_setting_ofs2") -dt_nodelabel(option_setting_sas NODELABEL "option_setting_sas") -dt_nodelabel(option_setting_ofs1_sec NODELABEL "option_setting_ofs1_sec") -dt_nodelabel(option_setting_ofs3_sec NODELABEL "option_setting_ofs3_sec") -dt_nodelabel(option_setting_ofs1_sel NODELABEL "option_setting_ofs1_sel") -dt_nodelabel(option_setting_ofs3_sel NODELABEL "option_setting_ofs3_sel") -dt_nodelabel(option_setting_bps_sec NODELABEL "option_setting_bps_sec") -dt_nodelabel(option_setting_otp_pbps_sec NODELABEL "option_setting_otp_pbps_sec") - -dt_reg_addr(ofs0_addr PATH ${option_setting_ofs0}) -dt_reg_addr(ofs2_addr PATH ${option_setting_ofs2}) -dt_reg_addr(sas_addr PATH ${option_setting_sas}) -dt_reg_addr(ofs1_sec_addr PATH ${option_setting_ofs1_sec}) -dt_reg_addr(ofs3_sec_addr PATH ${option_setting_ofs3_sec}) -dt_reg_addr(ofs1_sel_addr PATH ${option_setting_ofs1_sel}) -dt_reg_addr(ofs3_sel_addr PATH ${option_setting_ofs3_sel}) -dt_reg_addr(bps_sec_addr PATH ${option_setting_bps_sec}) -dt_reg_addr(otp_pbps_sec_addr PATH ${option_setting_otp_pbps_sec}) - if(CONFIG_CMAKE_LINKER_GENERATOR) - zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) - zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") - zephyr_linker_section(NAME .option_setting_ofs0 GROUP OFS_OFS0_MEMORY ADDRESS ${ofs0_addr}) - zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") - zephyr_linker_section(NAME .option_setting_ofs2 GROUP OFS_OFS2_MEMORY ADDRESS ${ofs2_addr}) - zephyr_linker_section_configure(SECTION .option_setting_ofs2 KEEP INPUT ".option_setting_ofs2*") - zephyr_linker_section(NAME .option_setting_sas GROUP OFS_SAS_MEMORY ADDRESS ${sas_addr}) - zephyr_linker_section_configure(SECTION .option_setting_sas KEEP INPUT ".option_setting_sas*") - zephyr_linker_section(NAME .option_setting_ofs1_sec GROUP OFS_OFS1_SEC_MEMORY ADDRESS ${ofs1_sec_addr}) - zephyr_linker_section_configure(SECTION .option_setting_ofs1_sec KEEP INPUT ".option_setting_ofs1_sec*") - zephyr_linker_section(NAME .option_setting_ofs3_sec GROUP OFS_OFS3_SEC_MEMORY ADDRESS ${ofs3_sec_addr}) - zephyr_linker_section_configure(SECTION .option_setting_ofs3_sec KEEP INPUT ".option_setting_ofs3_sec*") - zephyr_linker_section(NAME .option_setting_ofs1_sel GROUP OFS_OFS1_SEL_MEMORY ADDRESS ${ofs1_sel_addr}) - zephyr_linker_section_configure(SECTION .option_setting_ofs1_sel KEEP INPUT ".option_setting_ofs1_sel*") - zephyr_linker_section(NAME .option_setting_ofs3_sel GROUP OFS_OFS3_SEL_MEMORY ADDRESS ${ofs3_sel_addr}) - zephyr_linker_section_configure(SECTION .option_setting_ofs3_sel KEEP INPUT ".option_setting_ofs3_sel*") - zephyr_linker_section(NAME .option_setting_bps_sec GROUP OFS_BPS_SEC_MEMORY ADDRESS ${bps_sec_addr}) - zephyr_linker_section_configure(SECTION .option_setting_bps_sec KEEP INPUT ".option_setting_bps_sec*") - zephyr_linker_section(NAME .option_setting_otp_pbps_sec GROUP OFS_OTP_PBPS_SEC_MEMORY ADDRESS ${otp_pbps_sec_addr}) - zephyr_linker_section_configure(SECTION .option_setting_otp_pbps_sec KEEP INPUT ".option_setting_otp_pbps_sec*") + if(CONFIG_USE_RA_FSP_DTC) + zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) + zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") + endif() + + if((NOT CONFIG_BOOTLOADER_MCUBOOT) AND (NOT CONFIG_SOC_RA_SECOND_CORE_BUILD)) + dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") + dt_nodelabel(option_setting_ofs2 NODELABEL "option_setting_ofs2") + dt_nodelabel(option_setting_sas NODELABEL "option_setting_sas") + dt_nodelabel(option_setting_ofs1_sec NODELABEL "option_setting_ofs1_sec") + dt_nodelabel(option_setting_ofs3_sec NODELABEL "option_setting_ofs3_sec") + dt_nodelabel(option_setting_ofs1_sel NODELABEL "option_setting_ofs1_sel") + dt_nodelabel(option_setting_ofs3_sel NODELABEL "option_setting_ofs3_sel") + dt_nodelabel(option_setting_bps_sec NODELABEL "option_setting_bps_sec") + dt_nodelabel(option_setting_otp_pbps_sec NODELABEL "option_setting_otp_pbps_sec") + + dt_reg_addr(ofs0_addr PATH ${option_setting_ofs0}) + dt_reg_addr(ofs2_addr PATH ${option_setting_ofs2}) + dt_reg_addr(sas_addr PATH ${option_setting_sas}) + dt_reg_addr(ofs1_sec_addr PATH ${option_setting_ofs1_sec}) + dt_reg_addr(ofs3_sec_addr PATH ${option_setting_ofs3_sec}) + dt_reg_addr(ofs1_sel_addr PATH ${option_setting_ofs1_sel}) + dt_reg_addr(ofs3_sel_addr PATH ${option_setting_ofs3_sel}) + dt_reg_addr(bps_sec_addr PATH ${option_setting_bps_sec}) + dt_reg_addr(otp_pbps_sec_addr PATH ${option_setting_otp_pbps_sec}) + + dt_node_has_status(ofs0_status PATH ${option_setting_ofs0} STATUS okay) + dt_node_has_status(ofs2_status PATH ${option_setting_ofs2} STATUS okay) + dt_node_has_status(sas_status PATH ${option_setting_sas} STATUS okay) + dt_node_has_status(ofs1_sec_status PATH ${option_setting_ofs1_sec} STATUS okay) + dt_node_has_status(ofs3_sec_status PATH ${option_setting_ofs3_sec} STATUS okay) + dt_node_has_status(ofs1_sel_status PATH ${option_setting_ofs1_sel} STATUS okay) + dt_node_has_status(ofs3_sel_status PATH ${option_setting_ofs3_sel} STATUS okay) + dt_node_has_status(bps_sec_status PATH ${option_setting_bps_sec} STATUS okay) + dt_node_has_status(otp_pbps_sec_status PATH ${option_setting_otp_pbps_sec} STATUS okay) + + if(${ofs0_status}) + zephyr_linker_section(NAME .option_setting_ofs0 GROUP OFS_OFS0_MEMORY ADDRESS ${ofs0_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") + endif() + + if(${ofs2_status}) + zephyr_linker_section(NAME .option_setting_ofs2 GROUP OFS_OFS2_MEMORY ADDRESS ${ofs2_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs2 KEEP INPUT ".option_setting_ofs2*") + endif() + + if(${sas_status}) + zephyr_linker_section(NAME .option_setting_sas GROUP OFS_SAS_MEMORY ADDRESS ${sas_addr}) + zephyr_linker_section_configure(SECTION .option_setting_sas KEEP INPUT ".option_setting_sas*") + endif() + + if(${ofs1_sec_status}) + zephyr_linker_section(NAME .option_setting_ofs1_sec GROUP OFS_OFS1_SEC_MEMORY ADDRESS ${ofs1_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs1_sec KEEP INPUT ".option_setting_ofs1_sec*") + endif() + + if(${ofs3_sec_status}) + zephyr_linker_section(NAME .option_setting_ofs3_sec GROUP OFS_OFS3_SEC_MEMORY ADDRESS ${ofs3_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs3_sec KEEP INPUT ".option_setting_ofs3_sec*") + endif() + + if(${ofs1_sel_status}) + zephyr_linker_section(NAME .option_setting_ofs1_sel GROUP OFS_OFS1_SEL_MEMORY ADDRESS ${ofs1_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs1_sel KEEP INPUT ".option_setting_ofs1_sel*") + endif() + + if(${ofs3_sel_status}) + zephyr_linker_section(NAME .option_setting_ofs3_sel GROUP OFS_OFS3_SEL_MEMORY ADDRESS ${ofs3_sel_addr}) + zephyr_linker_section_configure(SECTION .option_setting_ofs3_sel KEEP INPUT ".option_setting_ofs3_sel*") + endif() + + if(${bps_sec_status}) + zephyr_linker_section(NAME .option_setting_bps_sec GROUP OFS_BPS_SEC_MEMORY ADDRESS ${bps_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_bps_sec KEEP INPUT ".option_setting_bps_sec*") + endif() + + if(${otp_pbps_sec_status}) + zephyr_linker_section(NAME .option_setting_otp_pbps_sec GROUP OFS_OTP_PBPS_SEC_MEMORY ADDRESS ${otp_pbps_sec_addr}) + zephyr_linker_section_configure(SECTION .option_setting_otp_pbps_sec KEEP INPUT ".option_setting_otp_pbps_sec*") + endif() + endif() + elseif(CONFIG_LD_LINKER_TEMPLATE) - zephyr_linker_sources(SECTIONS sections.ld) + if((NOT CONFIG_BOOTLOADER_MCUBOOT) AND (NOT CONFIG_SOC_RA_SECOND_CORE_BUILD)) + zephyr_linker_sources(SECTIONS sections.ld) + endif() zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) + +else() + message(WARNING "Unsupported linker template.") endif() set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") From 2a9df8d23b76682bafe9be03e647196cdeaf1788 Mon Sep 17 00:00:00 2001 From: Thinh Le Cong Date: Thu, 13 Nov 2025 11:32:18 +0700 Subject: [PATCH 0675/3659] soc: renesas: ra: Resolve issue when using GNU and cmake linker Switch OFS-related linker sections from GROUP FLASH to GROUP ROM_REGION to avoid overlapiping placement with .text when build with GNU and CONFIG_CMAKE_LINKER_GENERATOR=y of RA boards that have OFS in FLASH Signed-off-by: Thinh Le Cong --- soc/renesas/ra/ra2a1/CMakeLists.txt | 6 +++--- soc/renesas/ra/ra2l1/CMakeLists.txt | 6 +++--- soc/renesas/ra/ra4m1/CMakeLists.txt | 6 +++--- soc/renesas/ra/ra4w1/CMakeLists.txt | 6 +++--- soc/renesas/ra/ra6m1/CMakeLists.txt | 6 +++--- soc/renesas/ra/ra6m2/CMakeLists.txt | 6 +++--- soc/renesas/ra/ra6m3/CMakeLists.txt | 6 +++--- 7 files changed, 21 insertions(+), 21 deletions(-) diff --git a/soc/renesas/ra/ra2a1/CMakeLists.txt b/soc/renesas/ra/ra2a1/CMakeLists.txt index a40c57077c89..5fe711b4a9ca 100644 --- a/soc/renesas/ra/ra2a1/CMakeLists.txt +++ b/soc/renesas/ra/ra2a1/CMakeLists.txt @@ -26,13 +26,13 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") endif() - zephyr_linker_section(NAME .option_setting_ofs0 GROUP FLASH ADDRESS ${ofs0_addr}) + zephyr_linker_section(NAME .option_setting_ofs0 GROUP ROM_REGION ADDRESS ${ofs0_addr}) zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") - zephyr_linker_section(NAME .option_setting_ofs1 GROUP FLASH ADDRESS ${ofs1_addr}) + zephyr_linker_section(NAME .option_setting_ofs1 GROUP ROM_REGION ADDRESS ${ofs1_addr}) zephyr_linker_section_configure(SECTION .option_setting_ofs1 KEEP INPUT ".option_setting_ofs1*") - zephyr_linker_section(NAME .option_setting_secmpu GROUP FLASH ADDRESS ${secmpu_addr}) + zephyr_linker_section(NAME .option_setting_secmpu GROUP ROM_REGION ADDRESS ${secmpu_addr}) zephyr_linker_section_configure(SECTION .option_setting_secmpu KEEP INPUT ".option_setting_secmpu*") if(${osis_status}) diff --git a/soc/renesas/ra/ra2l1/CMakeLists.txt b/soc/renesas/ra/ra2l1/CMakeLists.txt index ab4b876205ee..313103836ab3 100644 --- a/soc/renesas/ra/ra2l1/CMakeLists.txt +++ b/soc/renesas/ra/ra2l1/CMakeLists.txt @@ -26,13 +26,13 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") endif() - zephyr_linker_section(NAME .option_setting_ofs0 GROUP FLASH ADDRESS ${ofs0_addr}) + zephyr_linker_section(NAME .option_setting_ofs0 GROUP ROM_REGION ADDRESS ${ofs0_addr}) zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") - zephyr_linker_section(NAME .option_setting_ofs1 GROUP FLASH ADDRESS ${ofs1_addr}) + zephyr_linker_section(NAME .option_setting_ofs1 GROUP ROM_REGION ADDRESS ${ofs1_addr}) zephyr_linker_section_configure(SECTION .option_setting_ofs1 KEEP INPUT ".option_setting_ofs1*") - zephyr_linker_section(NAME .option_setting_secmpu GROUP FLASH ADDRESS ${secmpu_addr}) + zephyr_linker_section(NAME .option_setting_secmpu GROUP ROM_REGION ADDRESS ${secmpu_addr}) zephyr_linker_section_configure(SECTION .option_setting_secmpu KEEP INPUT ".option_setting_secmpu*") if(${osis_status}) diff --git a/soc/renesas/ra/ra4m1/CMakeLists.txt b/soc/renesas/ra/ra4m1/CMakeLists.txt index 63b6ca88b63c..ca978b75717f 100644 --- a/soc/renesas/ra/ra4m1/CMakeLists.txt +++ b/soc/renesas/ra/ra4m1/CMakeLists.txt @@ -26,13 +26,13 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") endif() - zephyr_linker_section(NAME .option_setting_ofs0 GROUP FLASH ADDRESS ${ofs0_addr}) + zephyr_linker_section(NAME .option_setting_ofs0 GROUP ROM_REGION ADDRESS ${ofs0_addr}) zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") - zephyr_linker_section(NAME .option_setting_ofs1 GROUP FLASH ADDRESS ${ofs1_addr}) + zephyr_linker_section(NAME .option_setting_ofs1 GROUP ROM_REGION ADDRESS ${ofs1_addr}) zephyr_linker_section_configure(SECTION .option_setting_ofs1 KEEP INPUT ".option_setting_ofs1*") - zephyr_linker_section(NAME .option_setting_secmpu GROUP FLASH ADDRESS ${secmpu_addr}) + zephyr_linker_section(NAME .option_setting_secmpu GROUP ROM_REGION ADDRESS ${secmpu_addr}) zephyr_linker_section_configure(SECTION .option_setting_secmpu KEEP INPUT ".option_setting_secmpu*") if(${osis_status}) diff --git a/soc/renesas/ra/ra4w1/CMakeLists.txt b/soc/renesas/ra/ra4w1/CMakeLists.txt index 7cd1d9afe6a9..ca3bfeb34a4a 100644 --- a/soc/renesas/ra/ra4w1/CMakeLists.txt +++ b/soc/renesas/ra/ra4w1/CMakeLists.txt @@ -25,13 +25,13 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") endif() - zephyr_linker_section(NAME .option_setting_ofs0 GROUP FLASH ADDRESS ${ofs0_addr}) + zephyr_linker_section(NAME .option_setting_ofs0 GROUP ROM_REGION ADDRESS ${ofs0_addr}) zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") - zephyr_linker_section(NAME .option_setting_ofs1 GROUP FLASH ADDRESS ${ofs1_addr}) + zephyr_linker_section(NAME .option_setting_ofs1 GROUP ROM_REGION ADDRESS ${ofs1_addr}) zephyr_linker_section_configure(SECTION .option_setting_ofs1 KEEP INPUT ".option_setting_ofs1*") - zephyr_linker_section(NAME .option_setting_secmpu GROUP FLASH ADDRESS ${secmpu_addr}) + zephyr_linker_section(NAME .option_setting_secmpu GROUP ROM_REGION ADDRESS ${secmpu_addr}) zephyr_linker_section_configure(SECTION .option_setting_secmpu KEEP INPUT ".option_setting_secmpu*") if(${osis_status}) diff --git a/soc/renesas/ra/ra6m1/CMakeLists.txt b/soc/renesas/ra/ra6m1/CMakeLists.txt index 7cd1d9afe6a9..ca3bfeb34a4a 100644 --- a/soc/renesas/ra/ra6m1/CMakeLists.txt +++ b/soc/renesas/ra/ra6m1/CMakeLists.txt @@ -25,13 +25,13 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") endif() - zephyr_linker_section(NAME .option_setting_ofs0 GROUP FLASH ADDRESS ${ofs0_addr}) + zephyr_linker_section(NAME .option_setting_ofs0 GROUP ROM_REGION ADDRESS ${ofs0_addr}) zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") - zephyr_linker_section(NAME .option_setting_ofs1 GROUP FLASH ADDRESS ${ofs1_addr}) + zephyr_linker_section(NAME .option_setting_ofs1 GROUP ROM_REGION ADDRESS ${ofs1_addr}) zephyr_linker_section_configure(SECTION .option_setting_ofs1 KEEP INPUT ".option_setting_ofs1*") - zephyr_linker_section(NAME .option_setting_secmpu GROUP FLASH ADDRESS ${secmpu_addr}) + zephyr_linker_section(NAME .option_setting_secmpu GROUP ROM_REGION ADDRESS ${secmpu_addr}) zephyr_linker_section_configure(SECTION .option_setting_secmpu KEEP INPUT ".option_setting_secmpu*") if(${osis_status}) diff --git a/soc/renesas/ra/ra6m2/CMakeLists.txt b/soc/renesas/ra/ra6m2/CMakeLists.txt index 7cd1d9afe6a9..ca3bfeb34a4a 100644 --- a/soc/renesas/ra/ra6m2/CMakeLists.txt +++ b/soc/renesas/ra/ra6m2/CMakeLists.txt @@ -25,13 +25,13 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") endif() - zephyr_linker_section(NAME .option_setting_ofs0 GROUP FLASH ADDRESS ${ofs0_addr}) + zephyr_linker_section(NAME .option_setting_ofs0 GROUP ROM_REGION ADDRESS ${ofs0_addr}) zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") - zephyr_linker_section(NAME .option_setting_ofs1 GROUP FLASH ADDRESS ${ofs1_addr}) + zephyr_linker_section(NAME .option_setting_ofs1 GROUP ROM_REGION ADDRESS ${ofs1_addr}) zephyr_linker_section_configure(SECTION .option_setting_ofs1 KEEP INPUT ".option_setting_ofs1*") - zephyr_linker_section(NAME .option_setting_secmpu GROUP FLASH ADDRESS ${secmpu_addr}) + zephyr_linker_section(NAME .option_setting_secmpu GROUP ROM_REGION ADDRESS ${secmpu_addr}) zephyr_linker_section_configure(SECTION .option_setting_secmpu KEEP INPUT ".option_setting_secmpu*") if(${osis_status}) diff --git a/soc/renesas/ra/ra6m3/CMakeLists.txt b/soc/renesas/ra/ra6m3/CMakeLists.txt index 7cd1d9afe6a9..ca3bfeb34a4a 100644 --- a/soc/renesas/ra/ra6m3/CMakeLists.txt +++ b/soc/renesas/ra/ra6m3/CMakeLists.txt @@ -25,13 +25,13 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") endif() - zephyr_linker_section(NAME .option_setting_ofs0 GROUP FLASH ADDRESS ${ofs0_addr}) + zephyr_linker_section(NAME .option_setting_ofs0 GROUP ROM_REGION ADDRESS ${ofs0_addr}) zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") - zephyr_linker_section(NAME .option_setting_ofs1 GROUP FLASH ADDRESS ${ofs1_addr}) + zephyr_linker_section(NAME .option_setting_ofs1 GROUP ROM_REGION ADDRESS ${ofs1_addr}) zephyr_linker_section_configure(SECTION .option_setting_ofs1 KEEP INPUT ".option_setting_ofs1*") - zephyr_linker_section(NAME .option_setting_secmpu GROUP FLASH ADDRESS ${secmpu_addr}) + zephyr_linker_section(NAME .option_setting_secmpu GROUP ROM_REGION ADDRESS ${secmpu_addr}) zephyr_linker_section_configure(SECTION .option_setting_secmpu KEEP INPUT ".option_setting_secmpu*") if(${osis_status}) From c66c4fceaa41e5a31711b912b1634c564ef39c7b Mon Sep 17 00:00:00 2001 From: Thinh Le Cong Date: Fri, 21 Nov 2025 15:34:59 +0700 Subject: [PATCH 0676/3659] soc: renesas: ra: add rom_padding workaround for IAR ROM placement The arbitrary ordering of ILINK may cause the .last_section to be placed between the gaps of consecutive sections in the ROMABLE region. This commit adds a workaround for Renesas RA devices, which have OFS registers placed in FLASH. Adding a small .rom_padding section at the beginning of the ROM_REGION stabilizes the placement order and ensures that all ROM sections remain within the expected region. Signed-off-by: Thinh Le Cong Signed-off-by: The Nguyen --- soc/renesas/ra/ra2a1/CMakeLists.txt | 3 +++ soc/renesas/ra/ra2l1/CMakeLists.txt | 3 +++ soc/renesas/ra/ra4m1/CMakeLists.txt | 3 +++ soc/renesas/ra/ra4w1/CMakeLists.txt | 3 +++ soc/renesas/ra/ra6m1/CMakeLists.txt | 3 +++ soc/renesas/ra/ra6m2/CMakeLists.txt | 3 +++ soc/renesas/ra/ra6m3/CMakeLists.txt | 3 +++ 7 files changed, 21 insertions(+) diff --git a/soc/renesas/ra/ra2a1/CMakeLists.txt b/soc/renesas/ra/ra2a1/CMakeLists.txt index 5fe711b4a9ca..04f2ebbc433a 100644 --- a/soc/renesas/ra/ra2a1/CMakeLists.txt +++ b/soc/renesas/ra/ra2a1/CMakeLists.txt @@ -26,6 +26,9 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") endif() + zephyr_linker_section(NAME .rom_padding GROUP ROM_REGION ADDRESS 0x000000C0) + zephyr_linker_section_configure(SECTION .rom_padding KEEP INPUT ".rom_padding*") + zephyr_linker_section(NAME .option_setting_ofs0 GROUP ROM_REGION ADDRESS ${ofs0_addr}) zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") diff --git a/soc/renesas/ra/ra2l1/CMakeLists.txt b/soc/renesas/ra/ra2l1/CMakeLists.txt index 313103836ab3..1d8891f222cb 100644 --- a/soc/renesas/ra/ra2l1/CMakeLists.txt +++ b/soc/renesas/ra/ra2l1/CMakeLists.txt @@ -26,6 +26,9 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") endif() + zephyr_linker_section(NAME .rom_padding GROUP ROM_REGION ADDRESS 0x000000C0) + zephyr_linker_section_configure(SECTION .rom_padding KEEP INPUT ".rom_padding*") + zephyr_linker_section(NAME .option_setting_ofs0 GROUP ROM_REGION ADDRESS ${ofs0_addr}) zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") diff --git a/soc/renesas/ra/ra4m1/CMakeLists.txt b/soc/renesas/ra/ra4m1/CMakeLists.txt index ca978b75717f..94e1769c22f4 100644 --- a/soc/renesas/ra/ra4m1/CMakeLists.txt +++ b/soc/renesas/ra/ra4m1/CMakeLists.txt @@ -26,6 +26,9 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") endif() + zephyr_linker_section(NAME .rom_padding GROUP ROM_REGION ADDRESS 0x000000C0) + zephyr_linker_section_configure(SECTION .rom_padding KEEP INPUT ".rom_padding*") + zephyr_linker_section(NAME .option_setting_ofs0 GROUP ROM_REGION ADDRESS ${ofs0_addr}) zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") diff --git a/soc/renesas/ra/ra4w1/CMakeLists.txt b/soc/renesas/ra/ra4w1/CMakeLists.txt index ca3bfeb34a4a..ffb74974499d 100644 --- a/soc/renesas/ra/ra4w1/CMakeLists.txt +++ b/soc/renesas/ra/ra4w1/CMakeLists.txt @@ -25,6 +25,9 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") endif() + zephyr_linker_section(NAME .rom_padding GROUP ROM_REGION ADDRESS 0x000000C0) + zephyr_linker_section_configure(SECTION .rom_padding KEEP INPUT ".rom_padding*") + zephyr_linker_section(NAME .option_setting_ofs0 GROUP ROM_REGION ADDRESS ${ofs0_addr}) zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") diff --git a/soc/renesas/ra/ra6m1/CMakeLists.txt b/soc/renesas/ra/ra6m1/CMakeLists.txt index ca3bfeb34a4a..f13469eb33c6 100644 --- a/soc/renesas/ra/ra6m1/CMakeLists.txt +++ b/soc/renesas/ra/ra6m1/CMakeLists.txt @@ -25,6 +25,9 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") endif() + zephyr_linker_section(NAME .rom_padding GROUP ROM_REGION ADDRESS 0x000001C0) + zephyr_linker_section_configure(SECTION .rom_padding KEEP INPUT ".rom_padding*") + zephyr_linker_section(NAME .option_setting_ofs0 GROUP ROM_REGION ADDRESS ${ofs0_addr}) zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") diff --git a/soc/renesas/ra/ra6m2/CMakeLists.txt b/soc/renesas/ra/ra6m2/CMakeLists.txt index ca3bfeb34a4a..f13469eb33c6 100644 --- a/soc/renesas/ra/ra6m2/CMakeLists.txt +++ b/soc/renesas/ra/ra6m2/CMakeLists.txt @@ -25,6 +25,9 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") endif() + zephyr_linker_section(NAME .rom_padding GROUP ROM_REGION ADDRESS 0x000001C0) + zephyr_linker_section_configure(SECTION .rom_padding KEEP INPUT ".rom_padding*") + zephyr_linker_section(NAME .option_setting_ofs0 GROUP ROM_REGION ADDRESS ${ofs0_addr}) zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") diff --git a/soc/renesas/ra/ra6m3/CMakeLists.txt b/soc/renesas/ra/ra6m3/CMakeLists.txt index ca3bfeb34a4a..f13469eb33c6 100644 --- a/soc/renesas/ra/ra6m3/CMakeLists.txt +++ b/soc/renesas/ra/ra6m3/CMakeLists.txt @@ -25,6 +25,9 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") endif() + zephyr_linker_section(NAME .rom_padding GROUP ROM_REGION ADDRESS 0x000001C0) + zephyr_linker_section_configure(SECTION .rom_padding KEEP INPUT ".rom_padding*") + zephyr_linker_section(NAME .option_setting_ofs0 GROUP ROM_REGION ADDRESS ${ofs0_addr}) zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") From a713f52fe4f3292894e0d58083b9373ede46cc6b Mon Sep 17 00:00:00 2001 From: The Nguyen Date: Thu, 11 Dec 2025 07:50:30 +0000 Subject: [PATCH 0677/3659] manifest: update hal_renesas rev to latest Update the hal_renesas rev to fix the USB device not sending ZLP at the end of the DCP data stage Signed-off-by: The Nguyen --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index c8f4c2c50126..a2534973610c 100644 --- a/west.yml +++ b/west.yml @@ -231,7 +231,7 @@ manifest: - hal - name: hal_renesas path: modules/hal/renesas - revision: 69c3df17e3788f1ba8c7ace191e21e20bbd8d641 + revision: 0164f2f515ad196674103f33cab10a7d547ce3cf groups: - hal - name: hal_rpi_pico From 010991d04963bf57b78942ed187b20b90e104cca Mon Sep 17 00:00:00 2001 From: Jason Yu Date: Wed, 17 Dec 2025 10:31:50 +0800 Subject: [PATCH 0678/3659] soc: nxp: imxrt118x: Change to use __rom_region_start symbol The boot container was using a non-standard symbol name `__rom_start_address` for the ROM start address. This symbol is not defined when build with `-DCONFIG_CMAKE_LINKER_GENERATOR=y`. This commit use the symbol `__rom_region_start` which is available for both cases. Signed-off-by: Jason Yu --- soc/nxp/imxrt/imxrt118x/soc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/soc/nxp/imxrt/imxrt118x/soc.c b/soc/nxp/imxrt/imxrt118x/soc.c index 461bff3508ef..4ec8961c4bbc 100644 --- a/soc/nxp/imxrt/imxrt118x/soc.c +++ b/soc/nxp/imxrt/imxrt118x/soc.c @@ -31,7 +31,7 @@ LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); extern char __start[]; extern char _flash_used[]; -extern char __rom_start_address[]; +extern char __rom_region_start[]; const __imx_boot_container_section container boot_header = { .hdr = { CNT_VERSION, @@ -48,7 +48,7 @@ const __imx_boot_container_section container boot_header = { { (uint32_t)(-1 * CONFIG_IMAGE_CONTAINER_OFFSET), (uint32_t)_flash_used, - (uint32_t)__rom_start_address, + (uint32_t)__rom_region_start, 0x00000000, (uint32_t)__start, 0x00000000, From c2d201d24e240ead347633b0a2811a9d88f4e693 Mon Sep 17 00:00:00 2001 From: Biwen Li Date: Wed, 17 Dec 2025 14:28:15 +0900 Subject: [PATCH 0679/3659] firmware: scmi: fix build issue arch reboot is not included in PM flow, so drop the option CONFIG_PM_LOG_LEVEL to fix build issue: - error: CONFIG_PM_LOG_LEVEL undeclared here (not in a function) Signed-off-by: Biwen Li --- drivers/firmware/scmi/reboot.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/firmware/scmi/reboot.c b/drivers/firmware/scmi/reboot.c index d00c3ff201ae..18b02a082439 100644 --- a/drivers/firmware/scmi/reboot.c +++ b/drivers/firmware/scmi/reboot.c @@ -9,7 +9,7 @@ #include #include -LOG_MODULE_REGISTER(scmi_reboot, CONFIG_PM_LOG_LEVEL); +LOG_MODULE_REGISTER(scmi_reboot); static int scmi_reboot_handler(int type) { From e37b89f0b4c7c896bf8e75afc723a692e26673e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Stasiak?= Date: Wed, 17 Dec 2025 08:10:19 +0100 Subject: [PATCH 0680/3659] drivers: i2s: nrf_tdm: fix application of buffer size workaround MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The workaround should be applied only when needed, based on errata symbols. Signed-off-by: Michał Stasiak --- drivers/i2s/i2s_nrf_tdm.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/i2s/i2s_nrf_tdm.c b/drivers/i2s/i2s_nrf_tdm.c index f1a691e0cefb..2ff437707e3c 100644 --- a/drivers/i2s/i2s_nrf_tdm.c +++ b/drivers/i2s/i2s_nrf_tdm.c @@ -32,10 +32,12 @@ LOG_MODULE_REGISTER(tdm_nrf, CONFIG_I2S_LOG_LEVEL); */ #define NRFX_TDM_STATUS_TRANSFER_STOPPED BIT(1) +#if NRF_ERRATA_STATIC_CHECK(54H, 39) /* Due to hardware limitations, the TDM peripheral requires the rx/tx size * to be greater than 8 bytes. */ #define NRFX_TDM_MIN_TRANSFER_SIZE_ALLOWED 8 +#endif /* Maximum clock divider value. Corresponds to CKDIV2. */ #define NRFX_TDM_MAX_SCK_DIV_VALUE TDM_CONFIG_SCK_DIV_SCKDIV_Max @@ -480,12 +482,14 @@ static int tdm_nrf_configure(const struct device *dev, enum i2s_dir dir, __ASSERT_NO_MSG(tdm_cfg->mem_slab != NULL && tdm_cfg->block_size != 0); - if ((tdm_cfg->block_size % sizeof(uint32_t)) != 0 || +#if NRF_ERRATA_STATIC_CHECK(54H, 39) + if (NRF_ERRATA_DYNAMIC_CHECK(54H, 39) || (tdm_cfg->block_size % sizeof(uint32_t)) != 0 || tdm_cfg->block_size <= NRFX_TDM_MIN_TRANSFER_SIZE_ALLOWED) { LOG_ERR("This device can only transmit full 32-bit words greater than %u bytes.", NRFX_TDM_MIN_TRANSFER_SIZE_ALLOWED); return -EINVAL; } +#endif switch (tdm_cfg->word_size) { case 8: @@ -686,11 +690,14 @@ static int tdm_nrf_write(const struct device *dev, void *mem_block, size_t size) return -EIO; } - if ((size % sizeof(uint32_t)) != 0 || size <= NRFX_TDM_MIN_TRANSFER_SIZE_ALLOWED) { +#if NRF_ERRATA_STATIC_CHECK(54H, 39) + if (NRF_ERRATA_DYNAMIC_CHECK(54H, 39) || (size % sizeof(uint32_t)) != 0 || + size <= NRFX_TDM_MIN_TRANSFER_SIZE_ALLOWED) { LOG_ERR("This device can only write full 32-bit words greater than %u bytes.", NRFX_TDM_MIN_TRANSFER_SIZE_ALLOWED); return -EIO; } +#endif ret = dmm_buffer_out_prepare(drv_cfg->mem_reg, buf.mem_block, buf.size, (void **)&buf.dmm_buf); From 26a08c86f66c47b2368482d0611f92060ce652d1 Mon Sep 17 00:00:00 2001 From: Jeremy Truttmann Date: Wed, 17 Dec 2025 12:30:26 +0100 Subject: [PATCH 0681/3659] net: ethernet: Allow to disable the auto-start of ethernet interfaces Adds CONFIG_ETH_NET_IF_NO_AUTO_START to allow pre-configuration of Ethernet interfaces (e.g., filters, mac) before they become operational. When enabled, net_if_up() must be explicitly called by the application. Signed-off-by: Jeremy Truttmann --- drivers/ethernet/Kconfig | 10 ++++++++++ subsys/net/l2/ethernet/ethernet.c | 5 +++++ 2 files changed, 15 insertions(+) diff --git a/drivers/ethernet/Kconfig b/drivers/ethernet/Kconfig index 3c7b4b795b7e..3103a3308d45 100644 --- a/drivers/ethernet/Kconfig +++ b/drivers/ethernet/Kconfig @@ -99,3 +99,13 @@ config ETH_INIT_PRIORITY Do not mess with it unless you know what you are doing. Note that the priority needs to be lower than the net stack so that it can start before the networking sub-system. + +config ETH_NET_IF_NO_AUTO_START + bool "Disable Ethernet interface auto-start" + depends on NET_L2_ETHERNET || ETH_DRIVER + help + This option allows user to set any configuration before the interface + becomes operational. For instance, the MAC address can be configured using + net_if_set_link_addr(iface, mac, 6, NET_LINK_ETHERNET). + When all configurations are done net_if_up() has to be invoked to + bring the interface up. diff --git a/subsys/net/l2/ethernet/ethernet.c b/subsys/net/l2/ethernet/ethernet.c index c9d7f292f5a1..f15eec57cfb9 100644 --- a/subsys/net/l2/ethernet/ethernet.c +++ b/subsys/net/l2/ethernet/ethernet.c @@ -1070,6 +1070,11 @@ void ethernet_init(struct net_if *iface) dsa_eth_init(iface); #endif + if (IS_ENABLED(CONFIG_ETH_NET_IF_NO_AUTO_START)) { + /* Do not start Ethernet interface automatically */ + net_if_flag_set(iface, NET_IF_NO_AUTO_START); + } + ctx->ethernet_l2_flags = NET_L2_MULTICAST; ctx->iface = iface; k_work_init(&ctx->carrier_work, carrier_on_off); From b0229771d5f31c137c7c50fe6cd34700b2bc1510 Mon Sep 17 00:00:00 2001 From: Ayush Singh Date: Wed, 17 Dec 2025 13:17:50 +0530 Subject: [PATCH 0682/3659] net: dns: resolve: Enable discovery of all service instances The DNS-based Service Discovery has the following abstract: This document specifies how DNS resource records are named and structured to facilitate service discovery. Given a type of service that a client is looking for, and a domain in which the client is looking for that service, this mechanism allows clients to discover a list of named instances of that desired service, using standard DNS queries. This mechanism is referred to as DNS-based Service Discovery, or DNS-SD. As is stated here, DNS-based service discovery is designed to find all instances implementing a service, not just the first one. Currently, zephyr `dns_resolve_service` will call the callback for only the first client instance found. It still does receive the responses from other instances, but those are dropped since the query is already marked as finished. The seems incorrect behavior. With that said, the changes in this commit are API breaking, since even the docs already state that only the first response is currently used. So I am fine with creating a new function for discovering all instances if that is more acceptable. Since DNS-SD queries expect multiple responses, timeout or manual cancellation are the only methods to stop an in-flight request. When a timeout happens, the callback is called with one of the following responses: - `DNS_EAI_ALLDONE`: If at least one successful response was received. - `DNS_EAI_CANCELED`: If no successful response was received. Tested with 3 BeagleConnect Freedoms (2 running mdns_responder and 1 running dns_resolve sample). Signed-off-by: Ayush Singh --- include/zephyr/net/dns_resolve.h | 8 +++++--- subsys/net/lib/dns/resolve.c | 21 +++++++++++++++++---- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/include/zephyr/net/dns_resolve.h b/include/zephyr/net/dns_resolve.h index 83aa8c2354ef..a8426895b6dd 100644 --- a/include/zephyr/net/dns_resolve.h +++ b/include/zephyr/net/dns_resolve.h @@ -516,6 +516,9 @@ struct dns_resolve_context { * cannot be used to find correct pending query. */ uint16_t query_hash; + + /** Flag to indicate that the callback has been called at least once. */ + bool cb_called; } queries[DNS_NUM_CONCUR_QUERIES]; /** Is this context in use */ @@ -768,9 +771,8 @@ int dns_resolve_name(struct dns_resolve_context *ctx, * Note that this is an asynchronous call, the function will return immediately * and the system will call the callback after resolving has finished or a timeout * has occurred. - * We might send the query to multiple servers (if there are more than one - * server configured), but we only use the result of the first received - * response. + * The callback is called for each response received. The query needs to be either cancelled + * manually, or by the timeout. * * @param ctx DNS context * @param query What the caller wants to resolve. diff --git a/subsys/net/lib/dns/resolve.c b/subsys/net/lib/dns/resolve.c index 8b929faeee81..f7bc4a761f77 100644 --- a/subsys/net/lib/dns/resolve.c +++ b/subsys/net/lib/dns/resolve.c @@ -1555,10 +1555,18 @@ static int dns_read(struct dns_resolve_context *ctx, } #endif /* CONFIG_DNS_RESOLVER_PACKET_FORWARDING */ - invoke_query_callback(ret, NULL, &ctx->queries[query_idx]); + /* Mark the query as success. Only used in case of DNS-SD query which need to wait for + * multiple responses. + */ + ctx->queries[query_idx].cb_called = true; - /* Marks the end of the results */ - release_query(&ctx->queries[query_idx]); + /* DNS service discovery can have multiple responses. */ + if (ctx->queries[query_idx].query_type != DNS_QUERY_TYPE_PTR) { + invoke_query_callback(ret, NULL, &ctx->queries[query_idx]); + + /* Marks the end of the results */ + release_query(&ctx->queries[query_idx]); + } return 0; @@ -1709,7 +1717,11 @@ static int dns_write(struct dns_resolve_context *ctx, /* Must be invoked with context lock held */ static void dns_resolve_cancel_slot(struct dns_resolve_context *ctx, int slot) { - invoke_query_callback(DNS_EAI_CANCELED, NULL, &ctx->queries[slot]); + if (ctx->queries[slot].cb_called) { + invoke_query_callback(DNS_EAI_ALLDONE, NULL, &ctx->queries[slot]); + } else { + invoke_query_callback(DNS_EAI_CANCELED, NULL, &ctx->queries[slot]); + } release_query(&ctx->queries[slot]); } @@ -2087,6 +2099,7 @@ int dns_resolve_name_internal(struct dns_resolve_context *ctx, ctx->queries[i].user_data = user_data; ctx->queries[i].ctx = ctx; ctx->queries[i].query_hash = 0; + ctx->queries[i].cb_called = false; k_work_init_delayable(&ctx->queries[i].timer, query_timeout); From 799d189a28f82a1828cda9a28d56d84573df70ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wouter=20Horr=C3=A9?= Date: Wed, 17 Dec 2025 08:21:14 +0100 Subject: [PATCH 0683/3659] rtio: executor: release mempool buffer before resetting it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `rtio_executor_handle_multishot` releases the RX buffer in case of cancellation or error. However, in case of an sqe that uses a mempool, it reset the buffer before that, making the release a NOOP. Fix that by moving the reset of the buffer to right before pushing the sqe back onto the queue. Signed-off-by: Wouter Horré --- subsys/rtio/rtio_executor.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/subsys/rtio/rtio_executor.c b/subsys/rtio/rtio_executor.c index 155fd1334deb..9850e06d9000 100644 --- a/subsys/rtio/rtio_executor.c +++ b/subsys/rtio/rtio_executor.c @@ -158,12 +158,6 @@ static inline void rtio_executor_handle_multishot(struct rtio_iodev_sqe *iodev_s uint32_t cqe_flags = rtio_cqe_compute_flags(iodev_sqe); void *userdata = iodev_sqe->sqe.userdata; - if (iodev_sqe->sqe.op == RTIO_OP_RX && uses_mempool) { - /* Reset the buffer info so the next request can get a new one */ - iodev_sqe->sqe.rx.buf = NULL; - iodev_sqe->sqe.rx.buf_len = 0; - } - /** We're releasing reasources when erroring as an error handling scheme of multi-shot * submissions by requiring to stop re-submitting if something goes wrong. Let the * application decide what's best for handling the corresponding error: whether @@ -176,6 +170,12 @@ static inline void rtio_executor_handle_multishot(struct rtio_iodev_sqe *iodev_s rtio_sqe_pool_free(r->sqe_pool, iodev_sqe); } else { /* Request was not canceled, put the SQE back in the queue */ + if (iodev_sqe->sqe.op == RTIO_OP_RX && uses_mempool) { + /* Reset the buffer info so the next request can get a new one */ + iodev_sqe->sqe.rx.buf = NULL; + iodev_sqe->sqe.rx.buf_len = 0; + } + mpsc_push(&r->sq, &iodev_sqe->q); rtio_executor_submit(r); } From 3ee9ac3898aeb527882afe6da79c187fcfb84e1d Mon Sep 17 00:00:00 2001 From: Zhaoxiang Jin Date: Thu, 18 Dec 2025 12:52:57 +0800 Subject: [PATCH 0684/3659] doc: releases: Fix heading underline in migration guide 4.4 Fix the Video section heading underline to use the correct number of equal signs to match the heading length. Signed-off-by: Zhaoxiang Jin --- doc/releases/migration-guide-4.4.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/releases/migration-guide-4.4.rst b/doc/releases/migration-guide-4.4.rst index 6f3b594a67e5..2cefd3783bd3 100644 --- a/doc/releases/migration-guide-4.4.rst +++ b/doc/releases/migration-guide-4.4.rst @@ -258,7 +258,7 @@ USB * :dtcompatible:`maxim,max3421e_spi` has been renamed to :dtcompatible:`maxim,max3421e-spi`. Video -=== +===== * CONFIG_VIDEO_OV7670 is now gone and replaced by CONFIG_VIDEO_OV767X. This allows supporting both the OV7670 and 0V7675. From c848b0512643674ee42f048b2cdcd03a90e30f8f Mon Sep 17 00:00:00 2001 From: Lyle Zhu Date: Fri, 19 Sep 2025 16:47:04 +0800 Subject: [PATCH 0685/3659] Bluetooth: Classic: Monitor setup_sco and accept_sco_req HCI commands For some controllers, such as NXP IW612 Chipset, the PCM pins of controller needs to be configured before the SCO connection is established. And it requires to get the `air_coding_format` to configure the PCM pins of controller. So, it requires to known when the SCO connection will be established and what the `air_coding_format` of the SCO connection. Add the function `bt_sco_hci_cb_register()` to monitor the HCI commands `setup_sco` and `accept_sco_req`. Add the function `bt_sco_hci_cb_unregister()` to remove the monitor. Signed-off-by: Lyle Zhu --- .../zephyr/linker/common-rom/common-rom-bt.ld | 1 + subsys/bluetooth/host/classic/sco.c | 67 +++++++++++++++++ subsys/bluetooth/host/classic/sco_internal.h | 72 +++++++++++++++++++ 3 files changed, 140 insertions(+) diff --git a/include/zephyr/linker/common-rom/common-rom-bt.ld b/include/zephyr/linker/common-rom/common-rom-bt.ld index 1cdbbbe43703..00c4d6977261 100644 --- a/include/zephyr/linker/common-rom/common-rom-bt.ld +++ b/include/zephyr/linker/common-rom/common-rom-bt.ld @@ -14,6 +14,7 @@ #if defined(CONFIG_BT_CLASSIC) ITERABLE_SECTION_ROM(bt_sco_conn_cb, Z_LINK_ITERABLE_SUBALIGN) + ITERABLE_SECTION_ROM(bt_sco_hci_cb, Z_LINK_ITERABLE_SUBALIGN) #endif ITERABLE_SECTION_ROM(bt_gatt_service_static, Z_LINK_ITERABLE_SUBALIGN) diff --git a/subsys/bluetooth/host/classic/sco.c b/subsys/bluetooth/host/classic/sco.c index 0ed21482382e..6abdabbe6a72 100644 --- a/subsys/bluetooth/host/classic/sco.c +++ b/subsys/bluetooth/host/classic/sco.c @@ -35,6 +35,7 @@ struct bt_sco_server *sco_server; #define SCO_CHAN(_sco) ((_sco)->sco.chan); static sys_slist_t sco_conn_cbs = SYS_SLIST_STATIC_INIT(&sco_conn_cbs); +static sys_slist_t sco_hci_cbs = SYS_SLIST_STATIC_INIT(&sco_hci_cbs); int bt_sco_server_register(struct bt_sco_server *server) { @@ -112,6 +113,40 @@ static void notify_disconnected(struct bt_conn *conn) } } +static void notify_setup_sco_cmd(struct bt_conn *conn, struct bt_hci_cp_setup_sync_conn *cp) +{ + struct bt_sco_hci_cb *callback; + + SYS_SLIST_FOR_EACH_CONTAINER(&sco_hci_cbs, callback, _node) { + if (callback->setup != NULL) { + callback->setup(conn, cp); + } + } + + STRUCT_SECTION_FOREACH(bt_sco_hci_cb, cb) { + if (cb->setup != NULL) { + cb->setup(conn, cp); + } + } +} + +static void notify_accept_sco_req_cmd(struct bt_hci_cp_accept_sync_conn_req *cp) +{ + struct bt_sco_hci_cb *callback; + + SYS_SLIST_FOR_EACH_CONTAINER(&sco_hci_cbs, callback, _node) { + if (callback->accept != NULL) { + callback->accept(cp); + } + } + + STRUCT_SECTION_FOREACH(bt_sco_hci_cb, cb) { + if (cb->accept != NULL) { + cb->accept(cp); + } + } +} + void bt_sco_connected(struct bt_conn *sco) { struct bt_sco_chan *chan; @@ -312,6 +347,8 @@ static int accept_sco_conn(const bt_addr_t *bdaddr, struct bt_conn *sco_conn) cp->retrans_effort = BT_HCI_SCO_RETRANS_EFFORT_DEFAULT; cp->content_format = sys_cpu_to_le16(sco_conn->sco.chan->voice_setting); + notify_accept_sco_req_cmd(cp); + err = bt_hci_cmd_send_sync(BT_HCI_OP_ACCEPT_SYNC_CONN_REQ, buf, NULL); if (err) { return err; @@ -393,6 +430,8 @@ static int sco_setup_sync_conn(struct bt_conn *sco_conn) cp->retrans_effort = BT_HCI_SCO_RETRANS_EFFORT_DEFAULT; cp->content_format = sys_cpu_to_le16(sco_conn->sco.chan->voice_setting); + notify_setup_sco_cmd(sco_conn->sco.acl, cp); + err = bt_hci_cmd_send_sync(BT_HCI_OP_SETUP_SYNC_CONN, buf, NULL); if (err < 0) { return err; @@ -471,3 +510,31 @@ int bt_sco_conn_cb_unregister(struct bt_sco_conn_cb *cb) return 0; } + +int bt_sco_hci_cb_register(struct bt_sco_hci_cb *cb) +{ + CHECKIF(cb == NULL) { + return -EINVAL; + } + + if (sys_slist_find(&sco_hci_cbs, &cb->_node, NULL)) { + return -EEXIST; + } + + sys_slist_append(&sco_hci_cbs, &cb->_node); + + return 0; +} + +int bt_sco_hci_cb_unregister(struct bt_sco_hci_cb *cb) +{ + CHECKIF(cb == NULL) { + return -EINVAL; + } + + if (!sys_slist_find_and_remove(&sco_hci_cbs, &cb->_node)) { + return -ENOENT; + } + + return 0; +} diff --git a/subsys/bluetooth/host/classic/sco_internal.h b/subsys/bluetooth/host/classic/sco_internal.h index dd9226263a1f..32f71e0e601e 100644 --- a/subsys/bluetooth/host/classic/sco_internal.h +++ b/subsys/bluetooth/host/classic/sco_internal.h @@ -224,3 +224,75 @@ int bt_sco_conn_cb_unregister(struct bt_sco_conn_cb *cb); */ #define BT_SCO_CONN_CB_DEFINE(_name) \ static const STRUCT_SECTION_ITERABLE(bt_sco_conn_cb, _CONCAT(bt_sco_conn_cb_, _name)) + +/** + * @brief SCO HCI callback structure for handling SCO connection events + * + * This structure defines callback functions that are invoked during SCO + * (Synchronous Connection-Oriented) connection establishment process. + * It allows upper layer protocols to customize HCI command parameters + * before they are sent to the controller. + * + * The callbacks are typically used by audio profiles like HFP/HSP to + * configure codec parameters, packet types, and other connection-specific + * settings based on negotiated audio codec and quality requirements. + * + * @note Callbacks are optional and may be NULL if default behavior is desired + */ +struct bt_sco_hci_cb { + /** + * @brief Setup callback for outgoing SCO connection + * + * Called before sending HCI_Setup_Synchronous_Connection command to monitor the HCI + * activity of SCO connections. + * + * @param acl_conn Pointer to the underlying ACL connection. + * @param cp Pointer to HCI setup synchronous connection command parameters. + */ + void (*setup)(struct bt_conn *acl_conn, struct bt_hci_cp_setup_sync_conn *cp); + + /** + * @brief Accept callback for incoming SCO connection + * + * Called before sending HCI_Accept_Synchronous_Connection_Request command to monitor the + * HCI activity of SCO connections. + * + * @param cp Pointer to HCI accept synchronous connection request command parameters. + */ + void (*accept)(struct bt_hci_cp_accept_sync_conn_req *cp); + + sys_snode_t _node; +}; + +/** @brief Register SCO HCI activity callbacks. + * + * Register callbacks to monitor the HCI activity of SCO. + * + * @param cb Callback struct. Must point to memory that remains valid. + * + * @retval 0 Success. + * @retval -EINVAL If @p cb is NULL. + * @retval -EEXIST if @p cb was already registered. + */ +int bt_sco_hci_cb_register(struct bt_sco_hci_cb *cb); + +/** + * @brief Unregister SCO HCI activity callbacks. + * + * Unregister the HCI activity monitor of SCO callbacks. + * + * @param cb Callback struct point to memory that remains valid. + * + * @retval 0 Success. + * @retval -EINVAL If @p cb is NULL. + * @retval -ENOENT if @p cb was not registered. + */ +int bt_sco_hci_cb_unregister(struct bt_sco_hci_cb *cb); + +/** + * @brief Register a callback structure for SCO HCI activity. + * + * @param _name Name of callback structure. + */ +#define BT_SCO_HCI_CB_DEFINE(_name) \ + static const STRUCT_SECTION_ITERABLE(bt_sco_hci_cb, _CONCAT(bt_sco_hci_cb_, _name)) From 5ead2dde41cc96d14ccbc3382b7bc244966ae33f Mon Sep 17 00:00:00 2001 From: Lyle Zhu Date: Fri, 19 Sep 2025 17:02:46 +0800 Subject: [PATCH 0686/3659] modules: hal_nxp: mcux: Send VS commands to configure controller Send VS commands to configure the PCM pins before establishing SCO connection. Send VS commands to start the voice transferring when SCO connection has been established. Send VS commands to stop the voice transferring when SCO connection has been broken. Signed-off-by: Lyle Zhu --- modules/hal_nxp/mcux/Kconfig.mcux | 6 + .../hal_nxp/mcux/mcux-sdk-ng/CMakeLists.txt | 5 + .../middleware/bt_controller/hci_nxp_sco.c | 232 ++++++++++++++++++ 3 files changed, 243 insertions(+) create mode 100644 modules/hal_nxp/mcux/mcux-sdk-ng/middleware/bt_controller/hci_nxp_sco.c diff --git a/modules/hal_nxp/mcux/Kconfig.mcux b/modules/hal_nxp/mcux/Kconfig.mcux index b81e5c84eb87..33a85c4044e6 100644 --- a/modules/hal_nxp/mcux/Kconfig.mcux +++ b/modules/hal_nxp/mcux/Kconfig.mcux @@ -100,3 +100,9 @@ config NXP_IEEE802154_MAC MAC interface. endif # HAS_MCUX + +config BT_NXP_PCM_PINS_DIR_REVERSE + bool "Reverse BT module PCM pins direction" + depends on BT_H4_NXP_CTLR + help + If enabled, PCM pins direction for the Bluetooth module will be reversed. diff --git a/modules/hal_nxp/mcux/mcux-sdk-ng/CMakeLists.txt b/modules/hal_nxp/mcux/mcux-sdk-ng/CMakeLists.txt index 8a3d1eaa659a..b435af9dd3e6 100644 --- a/modules/hal_nxp/mcux/mcux-sdk-ng/CMakeLists.txt +++ b/modules/hal_nxp/mcux/mcux-sdk-ng/CMakeLists.txt @@ -11,6 +11,11 @@ if((${MCUX_DEVICE} MATCHES "RW61") AND (NOT DEFINED CONFIG_MINIMAL_LIBC)) zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/mcux/mcux-sdk-ng/components/misc_utilities/fsl_memcpy.S) endif() +if(CONFIG_BT_H4_NXP_CTLR AND CONFIG_BT_CLASSIC) + # Add SCO specific configuration source file if BT Classic is enabled + zephyr_library_sources(middleware/bt_controller/hci_nxp_sco.c) +endif() + include(middleware/middleware.cmake) include(components/components.cmake) include(drivers/drivers.cmake) diff --git a/modules/hal_nxp/mcux/mcux-sdk-ng/middleware/bt_controller/hci_nxp_sco.c b/modules/hal_nxp/mcux/mcux-sdk-ng/middleware/bt_controller/hci_nxp_sco.c new file mode 100644 index 000000000000..d23e46449c15 --- /dev/null +++ b/modules/hal_nxp/mcux/mcux-sdk-ng/middleware/bt_controller/hci_nxp_sco.c @@ -0,0 +1,232 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#include +#include +#include + +#include +#include + +#define LOG_LEVEL CONFIG_BT_HCI_DRIVER_LOG_LEVEL +#include +LOG_MODULE_REGISTER(bt_nxp_sco); + +#include "common/bt_str.h" + +#include "host/conn_internal.h" +#include "host/classic/sco_internal.h" + +#define NXP_VS_CMD(_opcode, _flags, _data...) \ + { \ + .opcode = (_opcode), \ + .flags = (_flags), \ + .data_len = sizeof((uint8_t[]){ _data }), \ + .data = (uint8_t[]){ _data } \ + } + +#define NXP_VS_CMD_FLAG_NARROWBAND BIT(0) +#define NXP_VS_CMD_FLAG_WIDEBAND BIT(1) +#define NXP_VS_CMD_FLAG_NORMAL_PINS BIT(2) +#define NXP_VS_CMD_FLAG_REVERSE_PINS BIT(3) + +#define NXP_VS_CMD_FLAG_BAND_NC (NXP_VS_CMD_FLAG_NARROWBAND | NXP_VS_CMD_FLAG_WIDEBAND) +#define NXP_VS_CMD_FLAG_PINS_NC (NXP_VS_CMD_FLAG_NORMAL_PINS | NXP_VS_CMD_FLAG_REVERSE_PINS) + +struct bt_hci_nxp_vs_cmd { + uint16_t opcode; + uint8_t flags; + uint16_t data_len; + uint8_t *data; +}; + +static const struct bt_hci_nxp_vs_cmd sco_init_vs_cmds[] = { + NXP_VS_CMD(BT_OP(BT_OGF_VS, 0x0028), NXP_VS_CMD_FLAG_NARROWBAND | NXP_VS_CMD_FLAG_PINS_NC, + 0x03, 0x00, 0x03), + NXP_VS_CMD(BT_OP(BT_OGF_VS, 0x0028), NXP_VS_CMD_FLAG_WIDEBAND | NXP_VS_CMD_FLAG_PINS_NC, + 0x03, 0x00, 0x07), + NXP_VS_CMD(BT_OP(BT_OGF_VS, 0x0007), NXP_VS_CMD_FLAG_BAND_NC | NXP_VS_CMD_FLAG_REVERSE_PINS, + 0x03), + NXP_VS_CMD(BT_OP(BT_OGF_VS, 0x0007), NXP_VS_CMD_FLAG_BAND_NC | NXP_VS_CMD_FLAG_NORMAL_PINS, + 0x02), + NXP_VS_CMD(BT_OP(BT_OGF_VS, 0x0029), NXP_VS_CMD_FLAG_BAND_NC | NXP_VS_CMD_FLAG_PINS_NC, + 0x04, 0x00), + NXP_VS_CMD(BT_OP(BT_OGF_VS, 0x001d), NXP_VS_CMD_FLAG_BAND_NC | NXP_VS_CMD_FLAG_PINS_NC, + 0x01), + NXP_VS_CMD(BT_OP(BT_OGF_VS, 0x0070), NXP_VS_CMD_FLAG_BAND_NC | NXP_VS_CMD_FLAG_PINS_NC, + 0x01), + NXP_VS_CMD(BT_OP(BT_OGF_VS, 0x0073), NXP_VS_CMD_FLAG_NARROWBAND | NXP_VS_CMD_FLAG_PINS_NC, + 0x00), + NXP_VS_CMD(BT_OP(BT_OGF_VS, 0x0073), NXP_VS_CMD_FLAG_WIDEBAND | NXP_VS_CMD_FLAG_PINS_NC, + 0x01), + NXP_VS_CMD(BT_OP(BT_OGF_VS, 0x0028), NXP_VS_CMD_FLAG_NARROWBAND | NXP_VS_CMD_FLAG_PINS_NC, + 0x03, 0x00, 0x03), + NXP_VS_CMD(BT_OP(BT_OGF_VS, 0x0028), NXP_VS_CMD_FLAG_WIDEBAND | NXP_VS_CMD_FLAG_PINS_NC, + 0x03, 0x00, 0x07), +}; + +static const struct bt_hci_nxp_vs_cmd sco_start_vs_cmds[] = { + NXP_VS_CMD(BT_OP(BT_OGF_VS, 0x006f), NXP_VS_CMD_FLAG_BAND_NC | NXP_VS_CMD_FLAG_PINS_NC, + 0x00, 0x00, 0x08, 0x00, 0x00, 0x00), +}; + +static const struct bt_hci_nxp_vs_cmd sco_stop_vs_cmds[] = { + NXP_VS_CMD(BT_OP(BT_OGF_VS, 0x0073), NXP_VS_CMD_FLAG_NARROWBAND | NXP_VS_CMD_FLAG_PINS_NC, + 0x00), + NXP_VS_CMD(BT_OP(BT_OGF_VS, 0x0073), NXP_VS_CMD_FLAG_WIDEBAND | NXP_VS_CMD_FLAG_PINS_NC, + 0x01), +}; + +static int nxp_send_vs_cmd(const struct bt_hci_nxp_vs_cmd *cmd, uint8_t flags) +{ + int err; + struct net_buf *buf; + + if ((cmd->flags & flags) != flags) { + /* Skip the VS command */ + return 0; + } + + buf = bt_hci_cmd_alloc(K_FOREVER); + if (buf == NULL) { + return -ENOBUFS; + } + + __ASSERT(net_buf_tailroom(buf) >= cmd->data_len, "No space in buffer"); + + net_buf_add_mem(buf, cmd->data, cmd->data_len); + err = bt_hci_cmd_send_sync(cmd->opcode, buf, NULL); + if (err == -EACCES) { + LOG_WRN("VS opcode %04x is disallowed", cmd->opcode); + /* Ignore the disallowed command and continue */ + return 0; + } + + if (err != 0) { + LOG_ERR("Failed to send VS cmd"); + } + + return err; +} + +static void bt_nxp_sco_init(uint16_t voice_setting) +{ + uint8_t air_coding_fmt; + uint8_t flags; + + air_coding_fmt = BT_HCI_VOICE_SETTING_AIR_CODING_FMT_GET(voice_setting); + + switch (air_coding_fmt) { + case BT_HCI_VOICE_SETTING_AIR_CODING_FMT_CVSD: + flags = NXP_VS_CMD_FLAG_NARROWBAND; + break; + case BT_HCI_VOICE_SETTING_AIR_CODING_FMT_TRANSPARENT: + flags = NXP_VS_CMD_FLAG_WIDEBAND; + break; + default: + LOG_ERR("Unsupported air coding format %u", air_coding_fmt); + return; + } + + flags |= IS_ENABLED(CONFIG_BT_NXP_PCM_PINS_DIR_REVERSE) ? NXP_VS_CMD_FLAG_REVERSE_PINS + : NXP_VS_CMD_FLAG_NORMAL_PINS; + + ARRAY_FOR_EACH(sco_init_vs_cmds, i) { + if (nxp_send_vs_cmd(&sco_init_vs_cmds[i], flags) != 0) { + LOG_ERR("Failed to send VS cmd %u", i); + return; + } + } +} + +static void bt_nxp_setup_sco(struct bt_conn *acl_conn, struct bt_hci_cp_setup_sync_conn *cp) +{ + uint16_t voice_setting; + + voice_setting = sys_le16_to_cpu(cp->content_format); + + LOG_DBG("Setup SCO with voice setting %04x", voice_setting); + bt_nxp_sco_init(voice_setting); +} + +static void bt_nxp_accept_sco(struct bt_hci_cp_accept_sync_conn_req *cp) +{ + uint16_t voice_setting; + + voice_setting = sys_le16_to_cpu(cp->content_format); + LOG_DBG("Accept SCO req with voice setting %04x", voice_setting); + bt_nxp_sco_init(voice_setting); +} + +BT_SCO_HCI_CB_DEFINE(hci_nxp_sco_hci_cbs) = { + .setup = bt_nxp_setup_sco, + .accept = bt_nxp_accept_sco, +}; + +void bt_nxp_sco_connected(struct bt_conn *conn, uint8_t err) +{ + uint8_t flags; + uint8_t air_mode; + + if (err != BT_HCI_ERR_SUCCESS) { + return; + } + + air_mode = conn->sco.air_mode; + switch (air_mode) { + case BT_HCI_CODING_FORMAT_CVSD: + flags = NXP_VS_CMD_FLAG_NARROWBAND; + break; + case BT_HCI_CODING_FORMAT_TRANSPARENT: + flags = NXP_VS_CMD_FLAG_WIDEBAND; + break; + default: + LOG_ERR("Unsupported air mode %u", air_mode); + return; + } + + ARRAY_FOR_EACH(sco_start_vs_cmds, i) { + if (nxp_send_vs_cmd(&sco_start_vs_cmds[i], flags) != 0) { + LOG_ERR("Failed to send VS cmd %u", i); + return; + } + } +} + +void bt_nxp_sco_disconnected(struct bt_conn *conn, uint8_t reason) +{ + uint8_t flags; + uint8_t air_mode; + + air_mode = conn->sco.air_mode; + switch (air_mode) { + case BT_HCI_CODING_FORMAT_CVSD: + flags = NXP_VS_CMD_FLAG_NARROWBAND; + break; + case BT_HCI_CODING_FORMAT_TRANSPARENT: + flags = NXP_VS_CMD_FLAG_WIDEBAND; + break; + default: + LOG_ERR("Unsupported air mode %u", air_mode); + return; + } + + ARRAY_FOR_EACH(sco_stop_vs_cmds, i) { + if (nxp_send_vs_cmd(&sco_stop_vs_cmds[i], flags) != 0) { + LOG_ERR("Failed to send VS cmd %u", i); + return; + } + } +} + +BT_SCO_CONN_CB_DEFINE(hci_nxp_sco_conn_cb) = { + .connected = bt_nxp_sco_connected, + .disconnected = bt_nxp_sco_disconnected, +}; From fae78f60c4cb6ecc9bcf968934ca7a7602329468 Mon Sep 17 00:00:00 2001 From: Lyle Zhu Date: Wed, 17 Sep 2025 20:30:35 +0800 Subject: [PATCH 0687/3659] sample: Bluetooth: HFP: Support voice transmission and playback Capture the voice from PCM and play voice through Codec if the SCO connection has been established. Capture the voice from Codec and send out through PCM if the SCO connection has been established. Signed-off-by: Lyle Zhu --- .../mimxrt1170_evk-pinctrl.dtsi | 13 + boards/nxp/mimxrt1170_evk/mimxrt1170_evk.dtsi | 5 + samples/bluetooth/classic/handsfree/Kconfig | 47 +++ .../bluetooth/classic/handsfree/README.rst | 63 +++- .../mimxrt1170_evk_mimxrt1176_cm7_B.conf | 7 + .../mimxrt1170_evk_mimxrt1176_cm7_B.overlay | 18 +- .../bluetooth/classic/handsfree/src/codec.c | 324 ++++++++++++++++++ .../bluetooth/classic/handsfree/src/codec.h | 21 ++ .../bluetooth/classic/handsfree/src/main.c | 88 +++++ samples/bluetooth/classic/handsfree/src/pcm.c | 284 +++++++++++++++ samples/bluetooth/classic/handsfree/src/pcm.h | 21 ++ 11 files changed, 888 insertions(+), 3 deletions(-) create mode 100644 samples/bluetooth/classic/handsfree/Kconfig create mode 100644 samples/bluetooth/classic/handsfree/src/codec.c create mode 100644 samples/bluetooth/classic/handsfree/src/codec.h create mode 100644 samples/bluetooth/classic/handsfree/src/pcm.c create mode 100644 samples/bluetooth/classic/handsfree/src/pcm.h diff --git a/boards/nxp/mimxrt1170_evk/mimxrt1170_evk-pinctrl.dtsi b/boards/nxp/mimxrt1170_evk/mimxrt1170_evk-pinctrl.dtsi index 9b60004c9f96..93fc31befc70 100644 --- a/boards/nxp/mimxrt1170_evk/mimxrt1170_evk-pinctrl.dtsi +++ b/boards/nxp/mimxrt1170_evk/mimxrt1170_evk-pinctrl.dtsi @@ -326,6 +326,19 @@ }; }; + pinmux_sai3: pinmux_sai3 { + group0 { + pinmux = <&iomuxc_gpio_emc_b2_17_sai3_mclk>, + <&iomuxc_gpio_emc_b2_16_sai3_tx_sync>, + <&iomuxc_gpio_emc_b2_15_sai3_tx_bclk>, + <&iomuxc_gpio_emc_b2_14_sai3_tx_data>, + <&iomuxc_gpio_emc_b2_13_sai3_rx_data>; + drive-strength = "high"; + slew-rate = "fast"; + input-enable; + }; + }; + pinmux_sai4: pinmux_sai4 { group0 { pinmux = <&iomuxc_lpsr_gpio_lpsr_09_sai4_tx_data>, diff --git a/boards/nxp/mimxrt1170_evk/mimxrt1170_evk.dtsi b/boards/nxp/mimxrt1170_evk/mimxrt1170_evk.dtsi index f1571826ebec..5059c202dd5f 100644 --- a/boards/nxp/mimxrt1170_evk/mimxrt1170_evk.dtsi +++ b/boards/nxp/mimxrt1170_evk/mimxrt1170_evk.dtsi @@ -236,6 +236,11 @@ arduino_spi: &lpspi1 { pinctrl-names = "default"; }; +&sai3 { + pinctrl-0 = <&pinmux_sai3>; + pinctrl-names = "default"; +}; + &lpadc1 { pinctrl-0 = <&pinmux_lpadc1>; pinctrl-names = "default"; diff --git a/samples/bluetooth/classic/handsfree/Kconfig b/samples/bluetooth/classic/handsfree/Kconfig new file mode 100644 index 000000000000..dc735b162111 --- /dev/null +++ b/samples/bluetooth/classic/handsfree/Kconfig @@ -0,0 +1,47 @@ +# Copyright (c) 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +source "Kconfig.zephyr" + +config AUDIO_TRANSFER_INTERVAL + int "Audio transfer interval" + default 10 + range 1 100 + help + Controls the audio transfer interval. + +config PCM_BUFFERS + int "PCM Buffer Count" + default 4 + help + Controls the initial count of audio data blocks. + +config PCM_RX_THREAD_STACK_SIZE + int "PCM RX thread stack size" + default 1024 + help + Controls the PCM RX thread stack size in bytes. + +config PCM_RX_THREAD_PRIO + int "PCM RX thread priority" + default 4 + help + Controls the PCM RX thread priority + +config CODEC_BUFFERS + int "CODEC Buffer Count" + default PCM_BUFFERS + help + Controls the initial count of audio data blocks. + +config CODEC_RX_THREAD_STACK_SIZE + int "CODEC RX thread stack size" + default 1024 + help + Controls the CODEC RX thread stack size in bytes. + +config CODEC_RX_THREAD_PRIO + int "CODEC RX thread priority" + default 4 + help + Controls the CODEC RX thread priority diff --git a/samples/bluetooth/classic/handsfree/README.rst b/samples/bluetooth/classic/handsfree/README.rst index 7ed396d6f3ce..6de944bf2883 100644 --- a/samples/bluetooth/classic/handsfree/README.rst +++ b/samples/bluetooth/classic/handsfree/README.rst @@ -15,7 +15,66 @@ Requirements * BlueZ running on the host, or * A board with Bluetooth BR/EDR (Classic) support -Building and Running -******************** +Building +******** See :zephyr:code-sample-category:`bluetooth` samples for details. + +Running +******* + +The application works a Hands-Free uint. After the Bluetooth Host stack is initialized, the +connectable and discoverable will be automatically enabled. The peer device AG (Audio Gateway) can +discover and connect to the device. + +When the SCO connect is established, the application will initialize the codec and pcm interface +for voice streaming if the codec and pcm configurations are available. + +The HFP application requires the following optional configuration options: +The codec depends on the devicetree alias named ``i2s-codec-rx`` and ``i2s-codec-tx``. +The PCM interface depends on the devicetree alias named ``pcm-rxtx``, or ``pcm-tx`` and ``pcm-rx``. + +This sample has been tested on :zephyr:board:`mimxrt1170_evk@B/mimxrt1176/cm7 `. + + +.. graphviz:: + :caption: Bluetooth Hands-Free voice streaming topology + + + digraph bluetooth_hfp { + rankdir=LR; + node [shape=box, style=rounded]; + edge [fontname=Courier, fontsize=9]; + init [shape=point]; + + subgraph cluster_ag { + label="Audio Gateway (Phone/Car)"; + style=filled; + AG [label="HFP AG"]; + } + + subgraph cluster_hf { + label="Zephyr HF Device"; + style=filled; + + BT_HOST [label="Host Stack"]; + BT_CTRL [label="Controller"]; + HFP_APP [label="HFP HF Application"]; + CODEC [label="Audio Subsystem"]; + SPK [label="Speaker"]; + MIC [label="Microphone"]; + } + + AG -> BT_CTRL [label="SCO Link\n(BR/EDR)"]; + BT_CTRL -> AG [label="SCO Link\n(BR/EDR)"]; + BT_HOST -> BT_CTRL [label="HCI"]; + BT_CTRL -> BT_HOST [label="HCI"]; + BT_HOST -> HFP_APP [label="HF Callbacks"]; + HFP_APP -> BT_HOST [label="HF APIs"]; + HFP_APP -> CODEC [label="Peer voice"]; + CODEC -> HFP_APP [label="Local voice"]; + HFP_APP -> BT_CTRL [label="Local voice\nPCM output"]; + BT_CTRL -> HFP_APP [label="Peer voice\nPCM input"]; + CODEC -> SPK [label="Audio output"] + MIC -> CODEC [label="Audio input"] + } diff --git a/samples/bluetooth/classic/handsfree/boards/mimxrt1170_evk_mimxrt1176_cm7_B.conf b/samples/bluetooth/classic/handsfree/boards/mimxrt1170_evk_mimxrt1176_cm7_B.conf index 9e8851c73af1..07b2ece70355 100644 --- a/samples/bluetooth/classic/handsfree/boards/mimxrt1170_evk_mimxrt1176_cm7_B.conf +++ b/samples/bluetooth/classic/handsfree/boards/mimxrt1170_evk_mimxrt1176_cm7_B.conf @@ -1,2 +1,9 @@ #select NXP NW612 Chipset CONFIG_BT_NXP_NW612=y + +CONFIG_I2S=y +CONFIG_DMA_TCD_QUEUE_SIZE=4 +CONFIG_AUDIO=y +CONFIG_AUDIO_CODEC=y + +CONFIG_DMA_MCUX_USE_DTCM_FOR_DMA_DESCRIPTORS=n diff --git a/samples/bluetooth/classic/handsfree/boards/mimxrt1170_evk_mimxrt1176_cm7_B.overlay b/samples/bluetooth/classic/handsfree/boards/mimxrt1170_evk_mimxrt1176_cm7_B.overlay index 96ef63ad60b2..16aa9ae4a521 100644 --- a/samples/bluetooth/classic/handsfree/boards/mimxrt1170_evk_mimxrt1176_cm7_B.overlay +++ b/samples/bluetooth/classic/handsfree/boards/mimxrt1170_evk_mimxrt1176_cm7_B.overlay @@ -1,5 +1,5 @@ /* - * Copyright 2024 NXP + * Copyright 2024-2025 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -8,4 +8,20 @@ chosen { zephyr,sram = &dtcm; }; + + aliases { + i2s-codec-rx = &sai1; + pcm-rxtx = &sai3; + }; +}; + +&sai1 { + status = "okay"; + mclk-output; + nxp,rx-sync-mode; +}; + +&sai3 { + status = "okay"; + nxp,rx-sync-mode; }; diff --git a/samples/bluetooth/classic/handsfree/src/codec.c b/samples/bluetooth/classic/handsfree/src/codec.c new file mode 100644 index 000000000000..a1530976dafc --- /dev/null +++ b/samples/bluetooth/classic/handsfree/src/codec.c @@ -0,0 +1,324 @@ +/* codec.c - CODEC implementation for Bluetooth Hands-Free Profile */ + +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +#include + +#include "codec.h" + +#if DT_HAS_ALIAS(i2s_codec_tx) && DT_HAS_ALIAS(i2s_codec_rx) +#define I2S_CODEC_TX DT_ALIAS(i2s_codec_tx) +#define I2S_CODEC_RX DT_ALIAS(i2s_codec_rx) +#define I2C_CODEC DT_NODELABEL(audio_codec) + +#define MAX_SAMPLE_FREQ 16000 +#define MAX_SAMPLE_BIT_WIDTH 16 +#define MAX_CHANNELS 2 + +#define SAMPLES_PER_BLOCK ((MAX_SAMPLE_FREQ * CONFIG_AUDIO_TRANSFER_INTERVAL / 1000) * MAX_CHANNELS) + +#define BLOCK_SIZE (MAX_SAMPLE_BIT_WIDTH * SAMPLES_PER_BLOCK / 8) +#define RX_BLOCK_COUNT (CONFIG_CODEC_BUFFERS) +#define TX_BLOCK_COUNT (CONFIG_CODEC_BUFFERS) +#define TIMEOUT (2 * 1000 / CONFIG_AUDIO_TRANSFER_INTERVAL) + +static const struct device *i2s_codec_tx = DEVICE_DT_GET(I2S_CODEC_TX); +static const struct device *i2s_codec_rx = DEVICE_DT_GET(I2S_CODEC_RX); +static const struct device *i2c_codec = DEVICE_DT_GET(I2C_CODEC); + +K_MEM_SLAB_DEFINE_IN_SECT_STATIC(tx_mem_slab, __nocache, BLOCK_SIZE, TX_BLOCK_COUNT, 4); +K_MEM_SLAB_DEFINE_IN_SECT_STATIC(rx_mem_slab, __nocache, BLOCK_SIZE, RX_BLOCK_COUNT, 4); + +static int configure_codec_streams(const struct device *i2s_codec_rx, + const struct device *i2s_codec_tx, struct i2s_config *config) +{ + int err; + + config->mem_slab = &rx_mem_slab; + err = i2s_configure(i2s_codec_rx, I2S_DIR_RX, config); + if (err < 0) { + printk("Failed to configure CODEC RX stream: %d\n", err); + return err; + } + + config->mem_slab = &tx_mem_slab; + err = i2s_configure(i2s_codec_tx, I2S_DIR_TX, config); + if (err < 0) { + printk("Failed to configure CODEC TX stream: %d\n", err); + return err; + } + + return 0; +} + +static struct k_sem codec_rx_thread_notify; +static codec_rx_cb_t codec_rx_cb; + +#define CODEC_RX_FLAG_STOPPED 0 +#define CODEC_RX_FLAG_STARTED 1 +#define CODEC_RX_FLAG_STOPPING 2 + +static atomic_t codec_rx_flag[1]; + +static void codec_rx_task(void *p1, void *p2, void *p3) +{ + int err; + void *mem_block; + uint32_t block_size; + + while (true) { + err = k_sem_take(&codec_rx_thread_notify, K_FOREVER); + if (err < 0) { + continue; + } + + if (atomic_test_and_clear_bit(codec_rx_flag, CODEC_RX_FLAG_STOPPING)) { + err = i2s_trigger(i2s_codec_rx, I2S_DIR_RX, I2S_TRIGGER_STOP); + if (err < 0) { + printk("Failed to stop CODEC RX %d\n", err); + } + atomic_clear_bit(codec_rx_flag, CODEC_RX_FLAG_STARTED); + atomic_set_bit(codec_rx_flag, CODEC_RX_FLAG_STOPPED); + } + + if (!atomic_test_bit(codec_rx_flag, CODEC_RX_FLAG_STARTED)) { + continue; + } else { + k_sem_give(&codec_rx_thread_notify); + } + + err = i2s_read(i2s_codec_rx, &mem_block, &block_size); + if (err < 0) { + continue; + } + + if (codec_rx_cb != NULL) { + codec_rx_cb(mem_block, block_size); + } + k_mem_slab_free(&rx_mem_slab, (void *)mem_block); + } +} + +static K_KERNEL_STACK_MEMBER(codec_rx_thread_stack, CONFIG_CODEC_RX_THREAD_STACK_SIZE); + +int codec_init(uint8_t air_mode) +{ + struct i2s_config config; + struct audio_codec_cfg audio_cfg; + int err; + uint8_t word_size; + uint8_t channels; + uint32_t sample_rate; + + static bool is_initiated; + static struct k_thread codec_rx_thread; + static k_tid_t codec_rx_thread_id; + + if (is_initiated) { + return 0; + } + + if (!device_is_ready(i2s_codec_rx)) { + printk("%s is not ready\n", i2s_codec_rx->name); + return -EINVAL; + } + + if (i2s_codec_rx != i2s_codec_tx && !device_is_ready(i2s_codec_tx)) { + printk("%s is not ready\n", i2s_codec_tx->name); + return -EINVAL; + } + + if (!device_is_ready(i2c_codec)) { + printk("%s is not ready\n", i2c_codec->name); + return -EINVAL; + } + + switch (air_mode) { + case BT_HCI_CODING_FORMAT_CVSD: + word_size = 16; + channels = 2; + sample_rate = 8000; + break; + case BT_HCI_CODING_FORMAT_TRANSPARENT: + word_size = 16; + channels = 2; + sample_rate = 16000; + break; + case BT_HCI_CODING_FORMAT_ULAW_LOG: + case BT_HCI_CODING_FORMAT_ALAW_LOG: + case BT_HCI_CODING_FORMAT_LINEAR_PCM: + case BT_HCI_CODING_FORMAT_MSBC: + case BT_HCI_CODING_FORMAT_LC3: + case BT_HCI_CODING_FORMAT_G729A: + case BT_HCI_CODING_FORMAT_VS: + default: + printk("Unsupported air mode: %d\n", air_mode); + return -ENOTSUP; + } + + audio_cfg.dai_route = AUDIO_ROUTE_PLAYBACK_CAPTURE; + audio_cfg.dai_type = AUDIO_DAI_TYPE_I2S; + audio_cfg.dai_cfg.i2s.word_size = word_size; + audio_cfg.dai_cfg.i2s.channels = channels; + audio_cfg.dai_cfg.i2s.format = I2S_FMT_DATA_FORMAT_I2S; + audio_cfg.dai_cfg.i2s.options = I2S_OPT_FRAME_CLK_SLAVE | I2S_OPT_BIT_CLK_SLAVE; + audio_cfg.dai_cfg.i2s.frame_clk_freq = sample_rate; + audio_cfg.dai_cfg.i2s.mem_slab = &rx_mem_slab; + audio_cfg.dai_cfg.i2s.block_size = BLOCK_SIZE; + err = audio_codec_configure(i2c_codec, &audio_cfg); + if (err != 0) { + printk("Failed to configure audio codec: %d\n", err); + return err; + } + + config.word_size = word_size; + config.channels = channels; + config.format = I2S_FMT_DATA_FORMAT_I2S; + config.options = I2S_OPT_FRAME_CLK_MASTER | I2S_OPT_BIT_CLK_MASTER; + config.frame_clk_freq = sample_rate; + config.block_size = BLOCK_SIZE; + config.timeout = TIMEOUT; + + err = configure_codec_streams(i2s_codec_rx, i2s_codec_tx, &config); + if (err < 0) { + return err; + } + + if (codec_rx_thread_id == NULL) { + k_sem_init(&codec_rx_thread_notify, 0, 1); + codec_rx_thread_id = k_thread_create(&codec_rx_thread, codec_rx_thread_stack, + K_KERNEL_STACK_SIZEOF(codec_rx_thread_stack), + codec_rx_task, NULL, NULL, NULL, + K_PRIO_COOP(CONFIG_CODEC_RX_THREAD_PRIO), 0, + K_NO_WAIT); + k_thread_name_set(codec_rx_thread_id, "HFP CODEC RX"); + } + + atomic_set_bit(codec_rx_flag, CODEC_RX_FLAG_STOPPED); + is_initiated = true; + + return 0; +} + +int codec_rx_start(codec_rx_cb_t cb) +{ + int err; + + if (!atomic_test_bit(codec_rx_flag, CODEC_RX_FLAG_STOPPED)) { + printk("CODEC RX is not idle\n"); + return -EBUSY; + } + + codec_rx_cb = cb; + + err = i2s_trigger(i2s_codec_rx, I2S_DIR_RX, I2S_TRIGGER_START); + if (err < 0) { + printk("Failed to trigger start on RX: %d\n", err); + return err; + } + + + atomic_clear_bit(codec_rx_flag, CODEC_RX_FLAG_STOPPED); + atomic_set_bit(codec_rx_flag, CODEC_RX_FLAG_STARTED); + k_sem_give(&codec_rx_thread_notify); + + return 0; +} + +int codec_rx_stop(void) +{ + if (!atomic_test_bit(codec_rx_flag, CODEC_RX_FLAG_STARTED)) { + return 0; + } + + atomic_set_bit(codec_rx_flag, CODEC_RX_FLAG_STOPPING); + k_sem_give(&codec_rx_thread_notify); + + return 0; +} + +int codec_tx(const uint8_t *data, uint32_t len) +{ + int err; + void *mem_block; + + static bool tx_started; + static uint32_t tx_count; + + if (len * 2 != BLOCK_SIZE) { + printk("Invalid data len %u != %u\n", len * 2, BLOCK_SIZE); + return -EINVAL; + } + + err = k_mem_slab_alloc(&tx_mem_slab, &mem_block, K_NO_WAIT); + if (err < 0) { + printk("Failed to allocate TX block: %d\n", err); + return err; + } + + for (uint32_t i = 0; i < len; i += 2) { + uint32_t *dst; + uint16_t *src; + + dst = (uint32_t *)&((uint8_t *)mem_block)[i * 2]; + src = (uint16_t *)&data[i]; + + *dst = (*src) | ((*src) << 16); + } + + err = i2s_write(i2s_codec_tx, mem_block, BLOCK_SIZE); + if (err < 0) { + k_mem_slab_free(&tx_mem_slab, mem_block); + printk("Failed to write block: %d\n", err); + return err; + } + + tx_count += 1; + + /* Only start the TX when more than one frame wrote. */ + if (!tx_started && tx_count > 1) { + err = i2s_trigger(i2s_codec_tx, I2S_DIR_TX, I2S_TRIGGER_START); + if (err < 0) { + printk("Failed to trigger start on TX: %d\n", err); + return err; + } + tx_started = true; + } + + return 0; +} + +#else + +int codec_init(uint8_t air_mode) +{ + printk("Codec is unsupported\n"); + return 0; +} + +int codec_tx(const uint8_t *data, uint32_t len) +{ + return 0; +} + +int codec_rx_start(codec_rx_cb_t cb) +{ + return 0; +} + +int codec_rx_stop(void) +{ + return 0; +} + +#endif /* DT_HAS_ALIAS(i2s_codec_tx) && DT_HAS_ALIAS(i2s_codec_rx) */ diff --git a/samples/bluetooth/classic/handsfree/src/codec.h b/samples/bluetooth/classic/handsfree/src/codec.h new file mode 100644 index 000000000000..e43bb4624681 --- /dev/null +++ b/samples/bluetooth/classic/handsfree/src/codec.h @@ -0,0 +1,21 @@ +/* codec.h - CODEC implementation for Bluetooth Hands-Free Profile */ + +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _ZEPHYR_SAMPLES_CLASSIC_HANDSFREE_CODEC_H_ +#define _ZEPHYR_SAMPLES_CLASSIC_HANDSFREE_CODEC_H_ + +#include + +typedef void (*codec_rx_cb_t)(const uint8_t *data, uint32_t len); + +int codec_init(uint8_t air_mode); +int codec_tx(const uint8_t *data, uint32_t len); +int codec_rx_start(codec_rx_cb_t cb); +int codec_rx_stop(void); + +#endif /* _ZEPHYR_SAMPLES_CLASSIC_HANDSFREE_CODEC_H_ */ diff --git a/samples/bluetooth/classic/handsfree/src/main.c b/samples/bluetooth/classic/handsfree/src/main.c index 140eed4a350d..08fe0d0b16ab 100644 --- a/samples/bluetooth/classic/handsfree/src/main.c +++ b/samples/bluetooth/classic/handsfree/src/main.c @@ -19,6 +19,11 @@ #include #include +#include "pcm.h" +#include "codec.h" + +static struct bt_conn *active_sco_conn; + static void hf_connected(struct bt_conn *conn, struct bt_hfp_hf *hf) { printk("HFP HF Connected!\n"); @@ -29,13 +34,96 @@ static void hf_disconnected(struct bt_hfp_hf *hf) printk("HFP HF Disconnected!\n"); } +static void pcm_rx_cb(const uint8_t *data, uint32_t len) +{ + int err; + + if (active_sco_conn == NULL) { + return; + } + + err = codec_tx(data, len); + if (err != 0) { + printk("Failed to transmit PCM data: %d\n", err); + } +} + +static void codec_rx_cb(const uint8_t *data, uint32_t len) +{ + int err; + + if (active_sco_conn == NULL) { + return; + } + + err = pcm_tx(data, len); + if (err != 0) { + printk("Failed to transmit Codec data: %d\n", err); + } +} + static void hf_sco_connected(struct bt_hfp_hf *hf, struct bt_conn *sco_conn) { + struct bt_conn_info info; + int err; + printk("HF SCO connected\n"); + active_sco_conn = bt_conn_ref(sco_conn); + + err = bt_conn_get_info(sco_conn, &info); + if (err != 0) { + printk("Failed to get sco conn %p info\n", sco_conn); + return; + } + + printk("SCO air mode %u\n", info.sco.air_mode); + + err = pcm_init(info.sco.air_mode); + if (err != 0) { + printk("Failed to initialize PCM for air mode %u\n", info.sco.air_mode); + return; + } + + err = codec_init(info.sco.air_mode); + if (err != 0) { + printk("Failed to initialize CODEC for air mode %u\n", info.sco.air_mode); + return; + } + + err = pcm_rx_start(pcm_rx_cb); + if (err != 0) { + printk("Failed to start PCM\n"); + return; + } + + err = codec_rx_start(codec_rx_cb); + if (err != 0) { + printk("Failed to start CODEC\n"); + return; + } } static void hf_sco_disconnected(struct bt_conn *sco_conn, uint8_t reason) { + int err; + + if (active_sco_conn != sco_conn) { + return; + } + + bt_conn_unref(active_sco_conn); + active_sco_conn = NULL; + + err = pcm_rx_stop(); + if (err != 0) { + printk("Failed to stop PCM\n"); + } + + err = codec_rx_stop(); + if (err != 0) { + printk("Failed to stop CODEC\n"); + } + printk("HF SCO disconnected\n"); } diff --git a/samples/bluetooth/classic/handsfree/src/pcm.c b/samples/bluetooth/classic/handsfree/src/pcm.c new file mode 100644 index 000000000000..2dcb4150dd31 --- /dev/null +++ b/samples/bluetooth/classic/handsfree/src/pcm.c @@ -0,0 +1,284 @@ +/* pcm.c - PCM implementation for Bluetooth Hands-Free Profile */ + +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +#include + +#include "pcm.h" + +#if DT_HAS_ALIAS(pcm_rxtx) || (DT_HAS_ALIAS(pcm_rx) && DT_HAS_ALIAS(pcm_tx)) +#if DT_NODE_EXISTS(DT_ALIAS(pcm_rxtx)) +#define PCM_RX DT_ALIAS(pcm_rxtx) +#define PCM_TX DT_ALIAS(pcm_rxtx) +#else +#define PCM_RX DT_ALIAS(pcm_rx) +#define PCM_TX DT_ALIAS(pcm_tx) +#endif + +#define MAX_SAMPLE_FREQ 16000 +#define MAX_SAMPLE_BIT_WIDTH 16 +#define MAX_CHANNELS 1 + +#define SAMPLES_PER_BLOCK ((MAX_SAMPLE_FREQ * CONFIG_AUDIO_TRANSFER_INTERVAL / 1000) * MAX_CHANNELS) + +#define BLOCK_SIZE (MAX_SAMPLE_BIT_WIDTH * SAMPLES_PER_BLOCK / 8) +#define RX_BLOCK_COUNT (CONFIG_PCM_BUFFERS) +#define TX_BLOCK_COUNT (CONFIG_PCM_BUFFERS) +#define TIMEOUT (2 * 1000 / CONFIG_AUDIO_TRANSFER_INTERVAL) + +static const struct device *pcm_rx_dev = DEVICE_DT_GET(PCM_RX); +static const struct device *pcm_tx_dev = DEVICE_DT_GET(PCM_TX); + +K_MEM_SLAB_DEFINE_IN_SECT_STATIC(rx_mem_slab, __nocache, BLOCK_SIZE, RX_BLOCK_COUNT, 4); +K_MEM_SLAB_DEFINE_IN_SECT_STATIC(tx_mem_slab, __nocache, BLOCK_SIZE, TX_BLOCK_COUNT, 4); + +static int configure_pcm_streams(const struct device *pcm_rx_dev, const struct device *pcm_tx_dev, + struct i2s_config *config) +{ + int err; + + config->mem_slab = &rx_mem_slab; + err = i2s_configure(pcm_rx_dev, I2S_DIR_RX, config); + if (err < 0) { + printk("Failed to configure PCM RX stream: %d\n", err); + return err; + } + + config->mem_slab = &tx_mem_slab; + err = i2s_configure(pcm_tx_dev, I2S_DIR_TX, config); + if (err < 0) { + printk("Failed to configure PCM TX stream: %d\n", err); + return err; + } + + return 0; +} + +static struct k_sem pcm_rx_thread_notify; +static pcm_rx_cb_t pcm_rx_cb; + +#define PCM_RX_FLAG_STOPPED 0 +#define PCM_RX_FLAG_STARTED 1 +#define PCM_RX_FLAG_STOPPING 2 + +static atomic_t pcm_rx_flag[1]; + +static void pcm_rx_task(void *p1, void *p2, void *p3) +{ + int err; + void *mem_block; + uint32_t block_size; + + while (true) { + err = k_sem_take(&pcm_rx_thread_notify, K_FOREVER); + if (err < 0) { + continue; + } + + if (!atomic_test_bit(pcm_rx_flag, PCM_RX_FLAG_STARTED)) { + continue; + } else { + k_sem_give(&pcm_rx_thread_notify); + } + + err = i2s_read(pcm_rx_dev, &mem_block, &block_size); + if (err < 0) { + continue; + } + + if (pcm_rx_cb != NULL) { + pcm_rx_cb((const uint8_t *)mem_block, block_size); + } + k_mem_slab_free(&rx_mem_slab, (void *)mem_block); + } +} + +static K_KERNEL_STACK_MEMBER(pcm_rx_thread_stack, CONFIG_PCM_RX_THREAD_STACK_SIZE); + +int pcm_init(uint8_t air_mode) +{ + struct i2s_config config; + int err; + uint8_t word_size; + uint8_t channels; + uint32_t sample_rate; + + static bool is_initiated; + static struct k_thread pcm_rx_thread; + static k_tid_t pcm_rx_thread_id; + + if (is_initiated) { + return 0; + } + + if (!device_is_ready(pcm_rx_dev)) { + printk("%s is not ready\n", pcm_rx_dev->name); + return -EINVAL; + } + + if (pcm_rx_dev != pcm_tx_dev && !device_is_ready(pcm_tx_dev)) { + printk("%s is not ready\n", pcm_tx_dev->name); + return -EINVAL; + } + + switch (air_mode) { + case BT_HCI_CODING_FORMAT_CVSD: + word_size = 16; + channels = 1; + sample_rate = 8000; + break; + case BT_HCI_CODING_FORMAT_TRANSPARENT: + word_size = 16; + channels = 1; + sample_rate = 16000; + break; + case BT_HCI_CODING_FORMAT_ULAW_LOG: + case BT_HCI_CODING_FORMAT_ALAW_LOG: + case BT_HCI_CODING_FORMAT_LINEAR_PCM: + case BT_HCI_CODING_FORMAT_MSBC: + case BT_HCI_CODING_FORMAT_LC3: + case BT_HCI_CODING_FORMAT_G729A: + case BT_HCI_CODING_FORMAT_VS: + default: + printk("Unsupported air mode: %d\n", air_mode); + return -ENOTSUP; + } + + config.word_size = word_size; + config.channels = channels; + config.format = I2S_FMT_DATA_FORMAT_PCM_SHORT; + config.options = I2S_OPT_BIT_CLK_SLAVE | I2S_OPT_FRAME_CLK_SLAVE; + config.frame_clk_freq = sample_rate; + config.block_size = BLOCK_SIZE; + config.timeout = TIMEOUT; + + err = configure_pcm_streams(pcm_rx_dev, pcm_tx_dev, &config); + if (err < 0) { + return err; + } + + if (pcm_rx_thread_id == NULL) { + k_sem_init(&pcm_rx_thread_notify, 0, 1); + pcm_rx_thread_id = k_thread_create(&pcm_rx_thread, pcm_rx_thread_stack, + K_KERNEL_STACK_SIZEOF(pcm_rx_thread_stack), + pcm_rx_task, NULL, NULL, NULL, + K_PRIO_COOP(CONFIG_PCM_RX_THREAD_PRIO), 0, + K_NO_WAIT); + k_thread_name_set(pcm_rx_thread_id, "HFP PCM RX"); + } + + atomic_set_bit(pcm_rx_flag, PCM_RX_FLAG_STOPPED); + is_initiated = true; + + return 0; +} + +int pcm_rx_start(pcm_rx_cb_t cb) +{ + int err; + + if (!atomic_test_bit(pcm_rx_flag, PCM_RX_FLAG_STOPPED)) { + return 0; + } + + pcm_rx_cb = cb; + + err = i2s_trigger(pcm_rx_dev, I2S_DIR_RX, I2S_TRIGGER_START); + if (err < 0) { + printk("Failed to trigger start on RX: %d\n", err); + return err; + } + + atomic_clear_bit(pcm_rx_flag, PCM_RX_FLAG_STOPPED); + atomic_set_bit(pcm_rx_flag, PCM_RX_FLAG_STARTED); + k_sem_give(&pcm_rx_thread_notify); + + return 0; +} + +int pcm_rx_stop(void) +{ + return 0; +} + +int pcm_tx(const uint8_t *data, uint32_t len) +{ + int err; + void *mem_block; + + static bool tx_started; + static uint32_t tx_count; + + if (len != (BLOCK_SIZE * 2)) { + printk("Invalid data len %u != %u\n", len, BLOCK_SIZE * 2); + return -EINVAL; + } + + err = k_mem_slab_alloc(&tx_mem_slab, &mem_block, K_NO_WAIT); + if (err < 0) { + printk("Failed to allocate TX block: %d\n", err); + return err; + } + + for (uint32_t i = 0; i < BLOCK_SIZE; i += 2) { + uint16_t *dst; + uint32_t *src; + + dst = (uint16_t *)&((uint8_t *)mem_block)[i]; + src = (uint32_t *)&data[i * 2 + 2]; + + *dst = (uint16_t)(*src); + } + + err = i2s_write(pcm_tx_dev, mem_block, BLOCK_SIZE); + if (err < 0) { + k_mem_slab_free(&tx_mem_slab, mem_block); + printk("Failed to write block: %d\n", err); + return err; + } + + tx_count += 1; + + /* Only start the TX when more than one frame wrote. */ + if (!tx_started && tx_count > 1) { + err = i2s_trigger(pcm_tx_dev, I2S_DIR_TX, I2S_TRIGGER_START); + if (err < 0) { + printk("Failed to trigger start on TX: %d\n", err); + return err; + } + tx_started = true; + } + + return 0; +} +#else +int pcm_init(uint8_t air_mode) +{ + printk("PCM is unsupported\n"); + return 0; +} + +int pcm_tx(const uint8_t *data, uint32_t len) +{ + return 0; +} + +int pcm_rx_start(pcm_rx_cb_t cb) +{ + return 0; +} + +int pcm_rx_stop(void) +{ + return 0; +} +#endif /* DT_HAS_ALIAS(pcm_rxtx) || (DT_HAS_ALIAS(pcm_rx) && DT_HAS_ALIAS(pcm_tx)) */ diff --git a/samples/bluetooth/classic/handsfree/src/pcm.h b/samples/bluetooth/classic/handsfree/src/pcm.h new file mode 100644 index 000000000000..5f9536003b8d --- /dev/null +++ b/samples/bluetooth/classic/handsfree/src/pcm.h @@ -0,0 +1,21 @@ +/* pcm.h - PCM implementation for Bluetooth Hands-Free Profile */ + +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _ZEPHYR_SAMPLES_CLASSIC_HANDSFREE_PCM_H_ +#define _ZEPHYR_SAMPLES_CLASSIC_HANDSFREE_PCM_H_ + +#include + +typedef void (*pcm_rx_cb_t)(const uint8_t *data, uint32_t len); + +int pcm_init(uint8_t air_mode); +int pcm_tx(const uint8_t *data, uint32_t len); +int pcm_rx_start(pcm_rx_cb_t cb); +int pcm_rx_stop(void); + +#endif /* _ZEPHYR_SAMPLES_CLASSIC_HANDSFREE_PCM_H_ */ From fa8681f57fd552dd7e56af12e3f4b1982df21bfd Mon Sep 17 00:00:00 2001 From: Lyle Zhu Date: Mon, 22 Sep 2025 18:09:45 +0800 Subject: [PATCH 0688/3659] Samples: Bluetooth: HFP_HF: Enable codec negotiation and codec mSBC Add callback `codec_negotiate` if the `CONFIG_BT_HFP_HF_CODEC_NEG` is set. Calling the function `bt_hfp_hf_select_codec()` if the codec ID is valid in the callback `codec_negotiate`. Signed-off-by: Lyle Zhu --- .../mimxrt1170_evk_mimxrt1176_cm7_B.conf | 3 ++ .../bluetooth/classic/handsfree/src/main.c | 28 +++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/samples/bluetooth/classic/handsfree/boards/mimxrt1170_evk_mimxrt1176_cm7_B.conf b/samples/bluetooth/classic/handsfree/boards/mimxrt1170_evk_mimxrt1176_cm7_B.conf index 07b2ece70355..067b6ed722db 100644 --- a/samples/bluetooth/classic/handsfree/boards/mimxrt1170_evk_mimxrt1176_cm7_B.conf +++ b/samples/bluetooth/classic/handsfree/boards/mimxrt1170_evk_mimxrt1176_cm7_B.conf @@ -6,4 +6,7 @@ CONFIG_DMA_TCD_QUEUE_SIZE=4 CONFIG_AUDIO=y CONFIG_AUDIO_CODEC=y +CONFIG_BT_HFP_HF_CODEC_NEG=y +CONFIG_BT_HFP_HF_CODEC_MSBC=y + CONFIG_DMA_MCUX_USE_DTCM_FOR_DMA_DESCRIPTORS=n diff --git a/samples/bluetooth/classic/handsfree/src/main.c b/samples/bluetooth/classic/handsfree/src/main.c index 08fe0d0b16ab..a3a9d6aeb626 100644 --- a/samples/bluetooth/classic/handsfree/src/main.c +++ b/samples/bluetooth/classic/handsfree/src/main.c @@ -187,6 +187,31 @@ static void hf_ring_indication(struct bt_hfp_hf_call *call) printk("HF call %p ring\n", call); } +#if defined(CONFIG_BT_HFP_HF_CODEC_NEG) +static void hf_codec_negotiate(struct bt_hfp_hf *hf, uint8_t id) +{ + int err; + + printk("HF codec negotiate 0x%02x\n", id); + + if (id == BT_HFP_HF_CODEC_CVSD) { + printk("HF codec negotiate CVSD\n"); + } else if (IS_ENABLED(CONFIG_BT_HFP_HF_CODEC_MSBC) && id == BT_HFP_HF_CODEC_MSBC) { + printk("HF codec negotiate mSBC\n"); + } else if (IS_ENABLED(CONFIG_BT_HFP_HF_CODEC_LC3_SWB) && id == BT_HFP_HF_CODEC_LC3_SWB) { + printk("HF codec negotiate LC3 SWB\n"); + } else { + printk("HF codec negotiate unknown codec\n"); + return; + } + + err = bt_hfp_hf_select_codec(hf, id); + if (err != 0) { + printk("Failed to send codec id: %d\n", err); + } +} +#endif /* defined(CONFIG_BT_HFP_HF_CODEC_NEG) */ + static struct bt_hfp_hf_cb hf_cb = { .connected = hf_connected, .disconnected = hf_disconnected, @@ -204,6 +229,9 @@ static struct bt_hfp_hf_cb hf_cb = { .roam = hf_roam, .battery = hf_battery, .ring_indication = hf_ring_indication, +#if defined(CONFIG_BT_HFP_HF_CODEC_NEG) + .codec_negotiate = hf_codec_negotiate, +#endif /* defined(CONFIG_BT_HFP_HF_CODEC_NEG) */ }; static void bt_ready(int err) From 1cb59d8e08fec3bfa066061417443c5c79fe58e3 Mon Sep 17 00:00:00 2001 From: Thomas Decker Date: Wed, 17 Dec 2025 09:11:45 +0100 Subject: [PATCH 0689/3659] drivers: power_domain: Fix Kconfig endif comments Fix the endif comments so they match to the corresponding if Signed-off-by: Thomas Decker --- drivers/power_domain/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/power_domain/Kconfig b/drivers/power_domain/Kconfig index a4e7c0ef68f1..a064b1e94ca1 100644 --- a/drivers/power_domain/Kconfig +++ b/drivers/power_domain/Kconfig @@ -35,7 +35,7 @@ config POWER_DOMAIN_GPIO_INIT_PRIORITY help GPIO power domain initialization priority. -endif #POWER_DOMAIN_GPIO_MONITOR +endif #POWER_DOMAIN_GPIO config POWER_DOMAIN_INTEL_ADSP bool "Use Intel ADSP power gating mechanisms" @@ -129,4 +129,4 @@ rsource "Kconfig.nrfs_swext" rsource "Kconfig.silabs_siwx91x" # zephyr-keep-sorted-stop -endif +endif #POWER_DOMAIN From 995d2894529b373e39cb50c1098534afe93f02e1 Mon Sep 17 00:00:00 2001 From: Lucien Zhao Date: Wed, 17 Dec 2025 16:22:40 +0800 Subject: [PATCH 0690/3659] drivers: Kconfig.mcux_edma: add slot value for mcxe24x set DMA_MCUX_TEST_SLOT_START value as 62 for mcxe24x Signed-off-by: Lucien Zhao --- drivers/dma/Kconfig.mcux_edma | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/dma/Kconfig.mcux_edma b/drivers/dma/Kconfig.mcux_edma index 2eaa79d970a2..bbf98e599dcd 100644 --- a/drivers/dma/Kconfig.mcux_edma +++ b/drivers/dma/Kconfig.mcux_edma @@ -51,11 +51,11 @@ config DMA_TCD_QUEUE_SIZE config DMA_MCUX_TEST_SLOT_START int "test slot start num" depends on (SOC_SERIES_KINETIS_K6X || SOC_SERIES_KINETIS_KE1XF \ - || SOC_SERIES_S32K3 || SOC_SERIES_S32ZE || SOC_SERIES_KE1XZ) + || SOC_SERIES_S32K3 || SOC_SERIES_S32ZE || SOC_SERIES_KE1XZ || SOC_SERIES_MCXE24X) default 58 if SOC_SERIES_KINETIS_K6X default 60 if SOC_SERIES_KINETIS_KE1XF default 60 if SOC_SERIES_KE1XZ - default 62 if SOC_SERIES_S32K3 || SOC_SERIES_S32ZE + default 62 if SOC_SERIES_S32K3 || SOC_SERIES_S32ZE || SOC_SERIES_MCXE24X help test slot start num From 70f696692005afd5899c535254a9464f92a3f214 Mon Sep 17 00:00:00 2001 From: Lucien Zhao Date: Wed, 17 Dec 2025 16:29:12 +0800 Subject: [PATCH 0691/3659] boards: nxp: frdm_mcxe247: support edma feature Enable dma case for frdm_mcxe247: - chan_blen_transfer - chan_link_transfer - loop_transfer - scatter_gather Signed-off-by: Lucien Zhao --- boards/nxp/frdm_mcxe247/frdm_mcxe247.yaml | 1 + .../dma/chan_blen_transfer/boards/frdm_mcxe247.overlay | 7 +++++++ .../dma/chan_link_transfer/boards/frdm_mcxe247.overlay | 8 ++++++++ tests/drivers/dma/chan_link_transfer/testcase.yaml | 1 + .../drivers/dma/loop_transfer/boards/frdm_mcxe247.overlay | 7 +++++++ tests/drivers/dma/scatter_gather/boards/frdm_mcxe247.conf | 1 + .../dma/scatter_gather/boards/frdm_mcxe247.overlay | 7 +++++++ tests/drivers/dma/scatter_gather/testcase.yaml | 1 + 8 files changed, 33 insertions(+) create mode 100644 tests/drivers/dma/chan_blen_transfer/boards/frdm_mcxe247.overlay create mode 100644 tests/drivers/dma/chan_link_transfer/boards/frdm_mcxe247.overlay create mode 100644 tests/drivers/dma/loop_transfer/boards/frdm_mcxe247.overlay create mode 100644 tests/drivers/dma/scatter_gather/boards/frdm_mcxe247.conf create mode 100644 tests/drivers/dma/scatter_gather/boards/frdm_mcxe247.overlay diff --git a/boards/nxp/frdm_mcxe247/frdm_mcxe247.yaml b/boards/nxp/frdm_mcxe247/frdm_mcxe247.yaml index fdcfaebc97fb..e9517905ece3 100644 --- a/boards/nxp/frdm_mcxe247/frdm_mcxe247.yaml +++ b/boards/nxp/frdm_mcxe247/frdm_mcxe247.yaml @@ -19,4 +19,5 @@ supported: - adc - arduino_gpio - comparator + - dma vendor: nxp diff --git a/tests/drivers/dma/chan_blen_transfer/boards/frdm_mcxe247.overlay b/tests/drivers/dma/chan_blen_transfer/boards/frdm_mcxe247.overlay new file mode 100644 index 000000000000..d4eda55afe34 --- /dev/null +++ b/tests/drivers/dma/chan_blen_transfer/boards/frdm_mcxe247.overlay @@ -0,0 +1,7 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +tst_dma0: &edma {}; diff --git a/tests/drivers/dma/chan_link_transfer/boards/frdm_mcxe247.overlay b/tests/drivers/dma/chan_link_transfer/boards/frdm_mcxe247.overlay new file mode 100644 index 000000000000..eee7026d2ae0 --- /dev/null +++ b/tests/drivers/dma/chan_link_transfer/boards/frdm_mcxe247.overlay @@ -0,0 +1,8 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +tst_dma0: &edma {}; diff --git a/tests/drivers/dma/chan_link_transfer/testcase.yaml b/tests/drivers/dma/chan_link_transfer/testcase.yaml index 30f76159a18d..c3865d0c5620 100644 --- a/tests/drivers/dma/chan_link_transfer/testcase.yaml +++ b/tests/drivers/dma/chan_link_transfer/testcase.yaml @@ -7,6 +7,7 @@ tests: - dma platform_allow: - frdm_k64f + - frdm_mcxe247 - mimxrt595_evk/mimxrt595s/cm33 - mimxrt1010_evk - mimxrt1050_evk/mimxrt1052/hyperflash diff --git a/tests/drivers/dma/loop_transfer/boards/frdm_mcxe247.overlay b/tests/drivers/dma/loop_transfer/boards/frdm_mcxe247.overlay new file mode 100644 index 000000000000..d4eda55afe34 --- /dev/null +++ b/tests/drivers/dma/loop_transfer/boards/frdm_mcxe247.overlay @@ -0,0 +1,7 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +tst_dma0: &edma {}; diff --git a/tests/drivers/dma/scatter_gather/boards/frdm_mcxe247.conf b/tests/drivers/dma/scatter_gather/boards/frdm_mcxe247.conf new file mode 100644 index 000000000000..61f2d18ca3c7 --- /dev/null +++ b/tests/drivers/dma/scatter_gather/boards/frdm_mcxe247.conf @@ -0,0 +1 @@ +CONFIG_DMA_TCD_QUEUE_SIZE=4 diff --git a/tests/drivers/dma/scatter_gather/boards/frdm_mcxe247.overlay b/tests/drivers/dma/scatter_gather/boards/frdm_mcxe247.overlay new file mode 100644 index 000000000000..d4eda55afe34 --- /dev/null +++ b/tests/drivers/dma/scatter_gather/boards/frdm_mcxe247.overlay @@ -0,0 +1,7 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +tst_dma0: &edma {}; diff --git a/tests/drivers/dma/scatter_gather/testcase.yaml b/tests/drivers/dma/scatter_gather/testcase.yaml index 59ef8726b601..bb8191b5eeeb 100644 --- a/tests/drivers/dma/scatter_gather/testcase.yaml +++ b/tests/drivers/dma/scatter_gather/testcase.yaml @@ -7,6 +7,7 @@ tests: platform_allow: - intel_adsp/cavs25 - frdm_k64f + - frdm_mcxe247 - mimxrt1010_evk - mimxrt685_evk/mimxrt685s/cm33 - mimxrt1060_evk/mimxrt1062/qspi From 80b4cdb744e98b09fc0d146d5f2bd55cd571c4fc Mon Sep 17 00:00:00 2001 From: Ivan Iushkov Date: Wed, 17 Dec 2025 09:36:54 +0100 Subject: [PATCH 0692/3659] toolchain: llvm: add -Wunaligned-access suppression TOOLCHAIN_WARNING_UNALIGNED_ACCESS can be used to suppress false-positive warnings generated by llvm clang compiler caused by -Wunaligned-access option Signed-off-by: Ivan Iushkov --- include/zephyr/toolchain/llvm.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/zephyr/toolchain/llvm.h b/include/zephyr/toolchain/llvm.h index c278cb035670..87d10192c4aa 100644 --- a/include/zephyr/toolchain/llvm.h +++ b/include/zephyr/toolchain/llvm.h @@ -55,6 +55,7 @@ #define TOOLCHAIN_WARNING_SIZEOF_ARRAY_DECAY "-Wsizeof-array-decay" #define TOOLCHAIN_WARNING_UNNEEDED_INTERNAL_DECLARATION "-Wunneeded-internal-declaration" #define TOOLCHAIN_WARNING_USED_BUT_MARKED_UNUSED "-Wused-but-marked-unused" +#define TOOLCHAIN_WARNING_UNALIGNED_ACCESS "-Wunaligned-access" #define TOOLCHAIN_DISABLE_CLANG_WARNING(warning) _TOOLCHAIN_DISABLE_WARNING(clang, warning) #define TOOLCHAIN_ENABLE_CLANG_WARNING(warning) _TOOLCHAIN_ENABLE_WARNING(clang, warning) From c3190d34aa912d39cd082db822f6ebb332806a2b Mon Sep 17 00:00:00 2001 From: Ivan Iushkov Date: Wed, 17 Dec 2025 09:39:42 +0100 Subject: [PATCH 0693/3659] Bluetooth: mesh: suppress clang warning in net.c struct net_val is a packed struct containing `struct bt_mesh_key dev_key` member which contains uint32_t variable inside. Compiling this code with llvm clang produces the following warning: ` error: field dev_key within 'struct net_val' is less aligned than 'struct bt_mesh_key' and is usually due to 'struct net_val' being packed, which can lead to unaligned accesses [-Werror,-Wunaligned-access] ` However, the `struct bt_mesh_key dev_key` is handled in accordance to its actual alignment. I.e., it is copied using memcpy() which prevents any alignment issues. This commit resolves the following Zephyr issue: https://github.com/zephyrproject-rtos/zephyr/issues/101144 by suppressing -Wunaligned-access warning on the `struct net_val` declaration. Signed-off-by: Ivan Iushkov --- subsys/bluetooth/mesh/net.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/subsys/bluetooth/mesh/net.c b/subsys/bluetooth/mesh/net.c index f85f3e7a050c..026a9ba0ed60 100644 --- a/subsys/bluetooth/mesh/net.c +++ b/subsys/bluetooth/mesh/net.c @@ -62,11 +62,16 @@ struct pdu_ctx { struct bt_mesh_net_rx *rx; }; +/* Suppress `net_val is less aligned than bt_mesh_key` clang warning. + * dev_key is handled in the source code according to it's alignment + */ +TOOLCHAIN_DISABLE_CLANG_WARNING(TOOLCHAIN_WARNING_UNALIGNED_ACCESS) /* Mesh network information for persistent storage. */ struct net_val { uint16_t primary_addr; struct bt_mesh_key dev_key; } __packed; +TOOLCHAIN_ENABLE_CLANG_WARNING(TOOLCHAIN_WARNING_UNALIGNED_ACCESS) /* Sequence number information for persistent storage. */ struct seq_val { From 64be8d84b10ab4b248fb73dbb9656820ec295b93 Mon Sep 17 00:00:00 2001 From: Nikodem Kastelik Date: Mon, 1 Dec 2025 15:22:48 +0100 Subject: [PATCH 0694/3659] drivers: pwm: nrf: fix nrfx instance being zeroed on suspend PWM driver clears its runtime state on each suspend event. However, since nrfx 4.0 integration nrfx driver instance is part of the runtime state structure, so clear action must be limited. Signed-off-by: Nikodem Kastelik --- drivers/pwm/pwm_nrfx.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/pwm/pwm_nrfx.c b/drivers/pwm/pwm_nrfx.c index 2a97aa47dfdc..ef3c2c030ff8 100644 --- a/drivers/pwm/pwm_nrfx.c +++ b/drivers/pwm/pwm_nrfx.c @@ -354,7 +354,11 @@ static int pwm_suspend(const struct device *dev) while (!nrfx_pwm_stopped_check(&data->pwm)) { } - memset(dev->data, 0, sizeof(struct pwm_nrfx_data)); + /* Explicitly clear driver state that might be invalid after subsequent resume. */ + data->period_cycles = 0; + data->pwm_needed = 0; + data->prescaler = 0; + data->stop_requested = 0; (void)pinctrl_apply_state(config->pcfg, PINCTRL_STATE_SLEEP); return 0; From e68ae84e5b5802e2d08a2b9f290d3df2f32d3e63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Bainczyk?= Date: Wed, 3 Dec 2025 12:45:42 +0100 Subject: [PATCH 0695/3659] manifest: update hal_nordic to have fixes for examples MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update hal_nordic to have examples with SPIM+SPIS and TWIM+TWIS examples fixed. Signed-off-by: Michał Bainczyk --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index a2534973610c..800e12cfbdb5 100644 --- a/west.yml +++ b/west.yml @@ -200,7 +200,7 @@ manifest: groups: - hal - name: hal_nordic - revision: 09f24fd6cc7df57a5b5d08102ceb4a38381e2c82 + revision: 248eadcacf976bbd27f1c0bc0dd3f11d8ec8657e path: modules/hal/nordic groups: - hal From 63c3c34f74227847215467f50b80f25af6248c4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rados=C5=82aw=20Koppel?= Date: Wed, 3 Dec 2025 00:35:37 +0100 Subject: [PATCH 0696/3659] drivers/flash/flash_simulator: Add write and erase callbacks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add the functionality that allows to register write and erase callbacks. The callbacks can modify the behaviour of this operations. It are meant to be used during testing of the situation when the memory starts to generate errors or the data cannot be trusted anymore. It expands the testing possibility, for a situation when the module is tested that checks the data integrity and and we cannot just jump in between its internal write and read operations to inject an error. Signed-off-by: Radosław Koppel --- drivers/flash/Kconfig.simulator | 8 ++ drivers/flash/flash_simulator.c | 110 ++++++++++++++++-- .../zephyr/drivers/flash/flash_simulator.h | 84 +++++++++++++ 3 files changed, 191 insertions(+), 11 deletions(-) diff --git a/drivers/flash/Kconfig.simulator b/drivers/flash/Kconfig.simulator index fd75479b3168..e86f7a951774 100644 --- a/drivers/flash/Kconfig.simulator +++ b/drivers/flash/Kconfig.simulator @@ -14,6 +14,14 @@ menuconfig FLASH_SIMULATOR if FLASH_SIMULATOR +config FLASH_SIMULATOR_CALLBACKS + bool "Provide callback mechanism" + help + If selected the flash_simulator_set_callbacks is implemented allowing + to change write and erase functions behavior. + This option is meant to be used with tests when checking module reaction + to different write/erase errors in the memory. + config FLASH_SIMULATOR_UNALIGNED_READ bool "Allow read access to be unaligned" default y diff --git a/drivers/flash/flash_simulator.c b/drivers/flash/flash_simulator.c index 035db8883928..22eeba1506fd 100644 --- a/drivers/flash/flash_simulator.c +++ b/drivers/flash/flash_simulator.c @@ -17,6 +17,8 @@ #include #include +#include + #ifdef CONFIG_ARCH_POSIX #include "flash_simulator_native.h" @@ -172,6 +174,20 @@ static const struct flash_parameters flash_sim_parameters = { }, }; + +#ifdef CONFIG_FLASH_SIMULATOR_CALLBACKS +static const struct flash_simulator_params flash_sim_params = { + .memory_size = FLASH_SIMULATOR_FLASH_SIZE, + .base_offset = FLASH_SIMULATOR_BASE_OFFSET, + .erase_unit = FLASH_SIMULATOR_ERASE_UNIT, + .prog_unit = FLASH_SIMULATOR_PROG_UNIT, + .explicit_erase = IS_ENABLED(CONFIG_FLASH_SIMULATOR_EXPLICIT_ERASE), + .erase_value = FLASH_SIMULATOR_ERASE_VALUE, +}; +static const struct flash_simulator_cb *flash_simulator_cbs; +#endif /* CONFIG_FLASH_SIMULATOR_CALLBACKS */ + + static int flash_range_is_valid(const struct device *dev, off_t offset, size_t len) { @@ -232,7 +248,7 @@ 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) +#ifdef CONFIG_FLASH_SIMULATOR_EXPLICIT_ERASE /* check if any unit has been already programmed */ memset(prog_unit_buf, FLASH_SIMULATOR_ERASE_VALUE, sizeof(prog_unit_buf)); #else @@ -265,6 +281,15 @@ static int flash_sim_write(const struct device *dev, const off_t offset, } #endif +#ifdef CONFIG_FLASH_SIMULATOR_CALLBACKS + flash_simulator_write_byte_cb_t write_cb = NULL; + const struct flash_simulator_cb *cb = flash_simulator_cbs; + + if (cb != NULL) { + write_cb = cb->write_byte; + } +#endif /* CONFIG_FLASH_SIMULATOR_CALLBACKS */ + for (uint32_t i = 0; i < len; i++) { #ifdef CONFIG_FLASH_SIMULATOR_STATS if (data_part_ignored) { @@ -274,16 +299,28 @@ static int flash_sim_write(const struct device *dev, const off_t offset, } #endif /* CONFIG_FLASH_SIMULATOR_STATS */ - /* only pull bits to zero */ -#if defined(CONFIG_FLASH_SIMULATOR_EXPLICIT_ERASE) + uint8_t data_val = *((const uint8_t *)data + i); + +#ifdef CONFIG_FLASH_SIMULATOR_EXPLICIT_ERASE #if FLASH_SIMULATOR_ERASE_VALUE == 0xFF - *(MOCK_FLASH(offset + i)) &= *((uint8_t *)data + i); + /* only pull bits to zero */ + data_val &= *(MOCK_FLASH(offset + i)); #else - *(MOCK_FLASH(offset + i)) |= *((uint8_t *)data + i); + /* only pull bits to one */ + data_val |= *(MOCK_FLASH(offset + i)); #endif -#else - *(MOCK_FLASH(offset + i)) = *((uint8_t *)data + i); #endif +#ifdef CONFIG_FLASH_SIMULATOR_CALLBACKS + if (write_cb != NULL) { + int ret = write_cb(dev, offset + i, data_val); + + if (ret < 0) { + return ret; + } + data_val = (uint8_t)ret; + } +#endif /* CONFIG_FLASH_SIMULATOR_CALLBACKS */ + *(MOCK_FLASH(offset + i)) = data_val; } FLASH_SIM_STATS_INCN(flash_sim_stats, bytes_written, len); @@ -298,20 +335,31 @@ static int flash_sim_write(const struct device *dev, const off_t offset, return 0; } -static void unit_erase(const uint32_t unit) +static int unit_erase(const struct device *dev, const uint32_t unit) { const off_t unit_addr = unit * FLASH_SIMULATOR_ERASE_UNIT; +#ifdef CONFIG_FLASH_SIMULATOR_CALLBACKS + flash_simulator_erase_unit_cb_t erase_cb = NULL; + const struct flash_simulator_cb *cb = flash_simulator_cbs; + + if (cb != NULL) { + erase_cb = cb->erase_unit; + } + if (erase_cb != NULL) { + return erase_cb(dev, unit_addr); + } +#endif /* CONFIG_FLASH_SIMULATOR_CALLBACKS */ + /* erase the memory unit by setting it to erase value */ memset(MOCK_FLASH(unit_addr), FLASH_SIMULATOR_ERASE_VALUE, FLASH_SIMULATOR_ERASE_UNIT); + return 0; } static int flash_sim_erase(const struct device *dev, const off_t offset, const size_t len) { - ARG_UNUSED(dev); - if (!flash_range_is_valid(dev, offset, len)) { return -EINVAL; } @@ -336,8 +384,13 @@ static int flash_sim_erase(const struct device *dev, const off_t offset, /* erase as many units as necessary and increase their erase counter */ for (uint32_t i = 0; i < len / FLASH_SIMULATOR_ERASE_UNIT; i++) { + int ret; + ERASE_CYCLES_INC(unit_start + i); - unit_erase(unit_start + i); + ret = unit_erase(dev, unit_start + i); + if (ret < 0) { + return ret; + } } #ifdef CONFIG_FLASH_SIMULATOR_SIMULATE_TIMING @@ -499,6 +552,26 @@ void *z_impl_flash_simulator_get_memory(const struct device *dev, return mock_flash; } +const struct flash_simulator_params *z_impl_flash_simulator_get_params(const struct device *dev) +{ + ARG_UNUSED(dev); + +#ifdef CONFIG_FLASH_SIMULATOR_CALLBACKS + return &flash_sim_params; +#else + return NULL; +#endif +} + +#ifdef CONFIG_FLASH_SIMULATOR_CALLBACKS +void z_impl_flash_simulator_set_callbacks(const struct device *dev, + const struct flash_simulator_cb *cb) +{ + ARG_UNUSED(dev); + flash_simulator_cbs = cb; +} +#endif /* CONFIG_FLASH_SIMULATOR_CALLBACKS */ + #ifdef CONFIG_USERSPACE #include @@ -511,6 +584,21 @@ void *z_vrfy_flash_simulator_get_memory(const struct device *dev, return z_impl_flash_simulator_get_memory(dev, mock_size); } +void z_vrfy_flash_simulator_set_callbacks(const struct device *dev, + const struct flash_simulator_cb *cb) +{ + K_OOPS(K_SYSCALL_SPECIFIC_DRIVER(dev, K_OBJ_DRIVER_FLASH, &flash_sim_api)); + + z_impl_flash_simulator_set_callbacks(dev, cb); +} + +const struct flash_simulator_params *z_vrfy_flash_simulator_get_params(const struct device *dev) +{ + K_OOPS(K_SYSCALL_SPECIFIC_DRIVER(dev, K_OBJ_DRIVER_FLASH, &flash_sim_api)); + + return z_impl_flash_simulator_get_params(dev); +} + #include #endif /* CONFIG_USERSPACE */ diff --git a/include/zephyr/drivers/flash/flash_simulator.h b/include/zephyr/drivers/flash/flash_simulator.h index e1a201b62b3a..c84e6c283a50 100644 --- a/include/zephyr/drivers/flash/flash_simulator.h +++ b/include/zephyr/drivers/flash/flash_simulator.h @@ -10,6 +10,10 @@ extern "C" { #endif +#include +#include +#include + /** * @file * @brief Flash simulator specific API. @@ -17,6 +21,86 @@ extern "C" { * Extension for flash simulator. */ +/** + * @brief Flash simulator parameters structure + * + * Auxiliary structure containing flash simulator parameters to be used by callbacks + * that can modify the behavior of the flash simulator driver. + */ +struct flash_simulator_params { + size_t memory_size; /**< @brief The total size of the memory */ + size_t base_offset; /**< @brief The base offset of the flash simulator */ + size_t erase_unit; /**< @brief The erase unit size */ + size_t prog_unit; /**< @brief The program unit size */ + bool explicit_erase; /**< @brief Whether explicit erase is required */ + uint8_t erase_value; /**< @brief The value used to represent erased memory */ +}; + +/** + * @brief Flash simulator write byte callback type + * + * Callback used to overwrite single byte write. The callback gets the requested data + * and offset as the parameter. The offset is the same offset passed to the flash write. + * The callback must return a value to be written at the specified offset or negative value + * in case of error. + * + * @param dev Flash simulator device pointer. + * @param offset Offset within the flash simulator memory. + * @param data Data byte to be written. + * @return Value to be written at the specified offset or negative value in case of error. + */ +typedef int (*flash_simulator_write_byte_cb_t)(const struct device *dev, + off_t offset, + uint8_t data); + +/** + * @brief Flash simulator erase unit callback type + * + * Callback used to overwrite unit erase operation. The callback gets the unit offset + * as the parameter. The offset is the same offset passed to the flash erase. The callback + * must return 0 in case of success or negative value in case of error. + * + * @note If this callback is set, the flash simulator driver will not perform any erase operation + * by itself. + * + * @param dev Flash simulator device pointer. + * @param unit_offset Offset within the flash simulator memory. + * @return 0 in case of success or negative value in case of error. + */ +typedef int (*flash_simulator_erase_unit_cb_t)(const struct device *dev, off_t unit_offset); + +/** + * @brief Flash simulator callbacks structure + * + * Structure containing flash simulator operation callbacks. + */ +struct flash_simulator_cb { + flash_simulator_write_byte_cb_t write_byte; /**< @brief Byte write callback */ + flash_simulator_erase_unit_cb_t erase_unit; /**< @brief Unit erase callback */ +}; + +/** + * @brief Get flash simulator parameters + * + * This function allows the caller to get the flash simulator parameters used by the driver. + * + * @param[in] dev flash simulator device pointer. + * @return Pointer to the flash simulator parameters structure. + */ +__syscall const struct flash_simulator_params *flash_simulator_get_params(const struct device *dev); + +/** + * @brief Set flash simulator callbacks + * + * This function allows the caller to set custom callbacks for byte write and + * unit erase operations performed by the flash simulator. + * + * @param[in] dev flash simulator device pointer. + * @param[in] cb pointer to the structure containing the callbacks. + */ +__syscall void flash_simulator_set_callbacks(const struct device *dev, + const struct flash_simulator_cb *cb); + /** * @brief Obtain a pointer to the RAM buffer used but by the simulator * From 9c69cf1710cd02593c6208555899268c14a2d830 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rados=C5=82aw=20Koppel?= Date: Thu, 4 Dec 2025 00:44:02 +0100 Subject: [PATCH 0697/3659] tests/flash_simulator: Test callbacks for erase and write operations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This test checks the functionality of the callbacks for erase and write operations. The callbacks allows the modification of the simulated flash behaviour during this operations. Signed-off-by: Radosław Koppel --- .../flash_simulator/flash_sim_impl/prj.conf | 1 + .../flash_sim_impl/src/callbacks.c | 223 ++++++++++++++++++ 2 files changed, 224 insertions(+) create mode 100644 tests/drivers/flash_simulator/flash_sim_impl/src/callbacks.c diff --git a/tests/drivers/flash_simulator/flash_sim_impl/prj.conf b/tests/drivers/flash_simulator/flash_sim_impl/prj.conf index c9fb30e0402f..d8a60c274c0c 100644 --- a/tests/drivers/flash_simulator/flash_sim_impl/prj.conf +++ b/tests/drivers/flash_simulator/flash_sim_impl/prj.conf @@ -1,5 +1,6 @@ CONFIG_ZTEST=y CONFIG_FLASH=y CONFIG_FLASH_SIMULATOR=y +CONFIG_FLASH_SIMULATOR_CALLBACKS=y CONFIG_FLASH_SIMULATOR_DOUBLE_WRITES=n CONFIG_FLASH_SIMULATOR_UNALIGNED_READ=n diff --git a/tests/drivers/flash_simulator/flash_sim_impl/src/callbacks.c b/tests/drivers/flash_simulator/flash_sim_impl/src/callbacks.c new file mode 100644 index 000000000000..22d32c031b9f --- /dev/null +++ b/tests/drivers/flash_simulator/flash_sim_impl/src/callbacks.c @@ -0,0 +1,223 @@ +/* + * Copyright (c) 2025 Koppel Electronic + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include +#include +#include + +/* Test the flash simulator callbacks to modify the behaviour of the + * flash simulator on the fly. + */ + +/* configuration derived from DT */ +#ifdef CONFIG_ARCH_POSIX +#define SOC_NV_FLASH_NODE DT_CHILD(DT_INST(0, zephyr_sim_flash), flash_0) +#else +#define SOC_NV_FLASH_NODE DT_CHILD(DT_INST(0, zephyr_sim_flash), flash_sim_0) +#endif /* CONFIG_ARCH_POSIX */ +#define FLASH_SIMULATOR_BASE_OFFSET DT_REG_ADDR(SOC_NV_FLASH_NODE) +#define FLASH_SIMULATOR_ERASE_UNIT DT_PROP(SOC_NV_FLASH_NODE, erase_block_size) +#define FLASH_SIMULATOR_PROG_UNIT DT_PROP(SOC_NV_FLASH_NODE, write_block_size) +#define FLASH_SIMULATOR_FLASH_SIZE DT_REG_SIZE(SOC_NV_FLASH_NODE) + +#define FLASH_SIMULATOR_ERASE_VALUE \ + DT_PROP(DT_PARENT(SOC_NV_FLASH_NODE), erase_value) + +#if (defined(CONFIG_ARCH_POSIX) || defined(CONFIG_BOARD_QEMU_X86)) +static const struct device *const flash_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_flash_controller)); +#else +static const struct device *const flash_dev = DEVICE_DT_GET(DT_NODELABEL(sim_flash_controller)); +#endif + + +/* We are simulating the broken FLASH memory. + * Simulate different types of errors depending on the erase page. + * Page 0: behaves normal + * Page 1: erase works as expected, all writes fails (no write, -EIO returned) + * Page 2: erase works as expected, all writes silently corrupt data (bits 0, 1, 20 in sticks to 1) + * Page 3: erase fails (no erase, -EIO returned), all writes fails (-EIO returned) + * Page 4: erase fails silently (erases writes 0x55 to all bytes), all writes fails (-EIO returned) + */ +enum test_page_type { + TEST_PAGE_TYPE_NORMAL, + TEST_PAGE_TYPE_ERASE_OK_WRITE_FAIL, + TEST_PAGE_TYPE_ERASE_OK_WRITE_CORRUPT, + TEST_PAGE_TYPE_ERASE_FAIL_WRITE_FAIL, + TEST_PAGE_TYPE_ERASE_CORRUPT_WRITE_FAIL, +}; + +/* Corruption pattern for write operations: bits 0, 1, and 20 in 32-bit word */ +static const uint32_t test_write_corruption_pattern = 0x00100003; + +static int test_write_byte_callback(const struct device *dev, off_t offset, uint8_t data) +{ + const struct flash_simulator_params *params = flash_simulator_get_params(dev); + enum test_page_type page = offset / params->erase_unit; + + switch (page) { + case TEST_PAGE_TYPE_ERASE_OK_WRITE_FAIL: + case TEST_PAGE_TYPE_ERASE_FAIL_WRITE_FAIL: + case TEST_PAGE_TYPE_ERASE_CORRUPT_WRITE_FAIL: + return -EIO; + case TEST_PAGE_TYPE_ERASE_OK_WRITE_CORRUPT: { + /* Apply corruption pattern based on byte position within word */ + uint8_t byte_in_word = offset & 0x3; + uint8_t corruption_byte = + (test_write_corruption_pattern >> (byte_in_word * 8)) & 0xFF; + + return data | corruption_byte; + } + case TEST_PAGE_TYPE_NORMAL: + default: + return data; + } +} + +static int test_erase_unit_callback(const struct device *dev, off_t offset) +{ + const struct flash_simulator_params *params = flash_simulator_get_params(dev); + enum test_page_type page = offset / params->erase_unit; + size_t flash_size; + uint8_t *flash_mock = flash_simulator_get_memory(dev, &flash_size); + + zassert_true(offset < flash_size, "Offset 0x%lx out of range (flash size 0x%zx)", + (long)offset, flash_size); + + switch (page) { + case TEST_PAGE_TYPE_ERASE_FAIL_WRITE_FAIL: + return -EIO; + case TEST_PAGE_TYPE_ERASE_CORRUPT_WRITE_FAIL: + /* Corrupt erase by writing 0x55 to all bytes */ + memset(flash_mock + offset, 0x55, params->erase_unit); + return 0; + case TEST_PAGE_TYPE_NORMAL: + case TEST_PAGE_TYPE_ERASE_OK_WRITE_FAIL: + case TEST_PAGE_TYPE_ERASE_OK_WRITE_CORRUPT: + default: + /* Normal erase behavior - callback must perform the erase */ + memset(flash_mock + offset, params->erase_value, params->erase_unit); + return 0; + } +} + +static struct flash_simulator_cb test_flash_sim_cbs = { + .write_byte = test_write_byte_callback, + .erase_unit = test_erase_unit_callback, +}; + +void *flash_sim_cbs_setup(void) +{ + zassert_true(device_is_ready(flash_dev), + "Simulated flash device not ready"); + + flash_simulator_set_callbacks(flash_dev, &test_flash_sim_cbs); + + return NULL; +} + +/* Disable callbacks after tests to restore default simulator behavior */ +static void flash_sim_cbs_teardown(void *fixture) +{ + ARG_UNUSED(fixture); + flash_simulator_set_callbacks(flash_dev, NULL); +} + +ZTEST(flash_sim_cbs, test_page_behaviors) +{ + int ret; + uint32_t write_buf[FLASH_SIMULATOR_ERASE_UNIT / sizeof(uint32_t)]; + uint32_t read_buf[FLASH_SIMULATOR_ERASE_UNIT / sizeof(uint32_t)]; + off_t page_offset; + size_t buf_size = sizeof(write_buf); + + /* Initialize write buffer with pseudo-random pattern */ + srand(0x12345678); + for (size_t i = 0; i < ARRAY_SIZE(write_buf); i++) { + write_buf[i] = ((uint32_t)rand() << 16) | (uint32_t)rand(); + } + + /* Test Page 0: TEST_PAGE_TYPE_NORMAL - behaves normal */ + page_offset = TEST_PAGE_TYPE_NORMAL * FLASH_SIMULATOR_ERASE_UNIT; + + ret = flash_erase(flash_dev, page_offset, FLASH_SIMULATOR_ERASE_UNIT); + zassert_equal(ret, 0, "Page 0: Erase should succeed"); + + ret = flash_write(flash_dev, page_offset, write_buf, buf_size); + zassert_equal(ret, 0, "Page 0: Write should succeed"); + + ret = flash_read(flash_dev, page_offset, read_buf, buf_size); + zassert_equal(ret, 0, "Page 0: Read should succeed"); + zassert_mem_equal(read_buf, write_buf, buf_size, + "Page 0: Data should match written data"); + + /* Test Page 1: TEST_PAGE_TYPE_ERASE_OK_WRITE_FAIL - erase OK, write fails */ + page_offset = TEST_PAGE_TYPE_ERASE_OK_WRITE_FAIL * FLASH_SIMULATOR_ERASE_UNIT; + + ret = flash_erase(flash_dev, page_offset, FLASH_SIMULATOR_ERASE_UNIT); + zassert_equal(ret, 0, "Page 1: Erase should succeed"); + + ret = flash_read(flash_dev, page_offset, read_buf, buf_size); + zassert_equal(ret, 0, "Page 1: Read after erase should succeed"); + for (size_t i = 0; i < ARRAY_SIZE(read_buf); i++) { + uint32_t expected = FLASH_SIMULATOR_ERASE_VALUE; + + expected |= (expected << 8) | (expected << 16) | (expected << 24); + zassert_equal(read_buf[i], expected, + "Page 1: After erase, data should be erase value"); + } + + ret = flash_write(flash_dev, page_offset, write_buf, buf_size); + zassert_equal(ret, -EIO, "Page 1: Write should fail with -EIO"); + + /* Test Page 2: TEST_PAGE_TYPE_ERASE_OK_WRITE_CORRUPT - erase OK, write corrupts */ + page_offset = TEST_PAGE_TYPE_ERASE_OK_WRITE_CORRUPT * FLASH_SIMULATOR_ERASE_UNIT; + + ret = flash_erase(flash_dev, page_offset, FLASH_SIMULATOR_ERASE_UNIT); + zassert_equal(ret, 0, "Page 2: Erase should succeed"); + + ret = flash_write(flash_dev, page_offset, write_buf, buf_size); + zassert_equal(ret, 0, "Page 2: Write should succeed (but corrupt data)"); + + ret = flash_read(flash_dev, page_offset, read_buf, buf_size); + zassert_equal(ret, 0, "Page 2: Read should succeed"); + + /* Verify corruption pattern: bits 0, 1, and 20 should be set */ + for (size_t i = 0; i < ARRAY_SIZE(read_buf); i++) { + uint32_t expected = write_buf[i] | test_write_corruption_pattern; + + zassert_equal(read_buf[i], expected, + "Page 2: Data should be corrupted with pattern 0x%08x", + test_write_corruption_pattern); + } + + /* Test Page 3: TEST_PAGE_TYPE_ERASE_FAIL_WRITE_FAIL - both fail */ + page_offset = TEST_PAGE_TYPE_ERASE_FAIL_WRITE_FAIL * FLASH_SIMULATOR_ERASE_UNIT; + + ret = flash_erase(flash_dev, page_offset, FLASH_SIMULATOR_ERASE_UNIT); + zassert_equal(ret, -EIO, "Page 3: Erase should fail with -EIO"); + + ret = flash_write(flash_dev, page_offset, write_buf, buf_size); + zassert_equal(ret, -EIO, "Page 3: Write should fail with -EIO"); + + /* Test Page 4: TEST_PAGE_TYPE_ERASE_CORRUPT_WRITE_FAIL - erase corrupts, write fails */ + page_offset = TEST_PAGE_TYPE_ERASE_CORRUPT_WRITE_FAIL * FLASH_SIMULATOR_ERASE_UNIT; + + ret = flash_erase(flash_dev, page_offset, FLASH_SIMULATOR_ERASE_UNIT); + zassert_equal(ret, 0, "Page 4: Erase should succeed (but corrupt)"); + + ret = flash_read(flash_dev, page_offset, read_buf, buf_size); + zassert_equal(ret, 0, "Page 4: Read after erase should succeed"); + for (size_t i = 0; i < ARRAY_SIZE(read_buf); i++) { + zassert_equal(read_buf[i], 0x55555555, + "Page 4: After erase, data should be 0x55555555 (corrupted erase)"); + } + + ret = flash_write(flash_dev, page_offset, write_buf, buf_size); + zassert_equal(ret, -EIO, "Page 4: Write should fail with -EIO"); +} + +ZTEST_SUITE(flash_sim_cbs, NULL, flash_sim_cbs_setup, NULL, NULL, flash_sim_cbs_teardown); From 564c6c1101566629b3d1469639c524ff02c70b37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Pouiller?= Date: Thu, 11 Dec 2025 11:27:09 +0100 Subject: [PATCH 0698/3659] manifest: silabs: Include last fixes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit hal_silabs has been updated with a few fixes related to WiFi. Signed-off-by: Jérôme Pouiller --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 800e12cfbdb5..42cdfad188be 100644 --- a/west.yml +++ b/west.yml @@ -245,7 +245,7 @@ manifest: groups: - hal - name: hal_silabs - revision: 091a5bbd2f83b83d4f00f166c6781b19bee0d03d + revision: 6bde23d62ffd16347d1696ba15db92b070907828 path: modules/hal/silabs groups: - hal From 8827ea2643893f6b747c0320b6d6f9514dff2c3d Mon Sep 17 00:00:00 2001 From: Grzegorz Chwierut Date: Fri, 12 Dec 2025 18:59:53 +0100 Subject: [PATCH 0699/3659] twister: prevent infinite loop in required app resolution When using --only-failed with required applications, twister could enter an infinite loop during application dependency resolution. Fixes #100808 Signed-off-by: Grzegorz Chwierut --- scripts/pylib/twister/twisterlib/testplan.py | 32 +++++++++++++++----- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/scripts/pylib/twister/twisterlib/testplan.py b/scripts/pylib/twister/twisterlib/testplan.py index e418ab14ecaa..adfffe047f9a 100755 --- a/scripts/pylib/twister/twisterlib/testplan.py +++ b/scripts/pylib/twister/twisterlib/testplan.py @@ -746,7 +746,7 @@ def load_from_file(self, file, filter_platform=None): except FileNotFoundError as e: logger.error(f"{e}") return 1 - self.apply_changes_for_required_applications(loaded_from_file=True) + self.apply_changes_for_required_applications() def check_platform(self, platform, platform_list): return any(p in platform.aliases for p in platform_list) @@ -1225,6 +1225,20 @@ def apply_filters(self, **kwargs): build_list_duration = time.time() - build_list_start logger.info(f"Built testsuite list in {build_list_duration:.2f} seconds") + def _should_instance_be_processed(self, instance: TestInstance) -> bool: + """Check if instance will be added to processing queue by runner.""" + # Based on add_tasks_to_queue from runner.py, + # removed FILTER status to process HW with build_only + do_not_process = [ + TwisterStatus.PASS, + TwisterStatus.SKIP, + TwisterStatus.NOTRUN + ] + if not self.options.retry_build_errors: + do_not_process.append(TwisterStatus.ERROR) + + return instance.status not in do_not_process + def _find_required_instance(self, required_app, instance: TestInstance) -> TestInstance | None: if req_platform := required_app.get("platform", None): platform = self.get_platform(req_platform) @@ -1238,7 +1252,9 @@ def _find_required_instance(self, required_app, instance: TestInstance) -> TestI for inst in self.instances.values(): if required_app["name"] == inst.testsuite.id and req_platform == inst.platform.name: - return inst + if self._should_instance_be_processed(inst): + return inst + break return None def _find_required_application_in_outdir(self, required_app, @@ -1267,7 +1283,7 @@ def _find_required_application_in_outdir(self, required_app, logger.debug(f"Found existing build directory for required app: {build_dirs[0]}") return build_dirs[0] - def apply_changes_for_required_applications(self, loaded_from_file=False) -> None: + def apply_changes_for_required_applications(self) -> None: # check if required applications are in scope for instance in self.instances.values(): if not instance.testsuite.required_applications: @@ -1312,10 +1328,12 @@ def apply_changes_for_required_applications(self, loaded_from_file=False) -> Non if req_instance.status == TwisterStatus.FILTER: # check if required application is filtered because is not runnable - if loaded_from_file or ( - self.options.device_testing and not req_instance.run - and len(req_instance.filters) == 1 - and req_instance.reason == "Not runnable on device"): + if ( + self.options.device_testing + and not req_instance.run + and len(req_instance.filters) == 1 + and req_instance.reason == "Not runnable on device" + ): # clear status flag to build required application self.instances[req_instance.name].status = TwisterStatus.NONE else: From 96985a32e862c94ec292b98366e27da9e7feb7c6 Mon Sep 17 00:00:00 2001 From: Grzegorz Chwierut Date: Mon, 15 Dec 2025 17:15:19 +0100 Subject: [PATCH 0700/3659] twister: pytest: fix duplicate log lines from pytest The combination of pytest's `-s` (--capture=no) option and `--log-cli-level=DEBUG` was causing duplicate log output. Fixed by replacing `--log-cli-level=DEBUG` with `--log-level=DEBUG`. `--log-cli-format` removed as is not used. Signed-off-by: Grzegorz Chwierut --- scripts/pylib/twister/twisterlib/harness.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/scripts/pylib/twister/twisterlib/harness.py b/scripts/pylib/twister/twisterlib/harness.py index 0f9d967183c1..f3eb9c391cdf 100644 --- a/scripts/pylib/twister/twisterlib/harness.py +++ b/scripts/pylib/twister/twisterlib/harness.py @@ -403,6 +403,7 @@ def generate_command(self): 'pytest', '--twister-harness', '-s', '-v', + '--log-level=DEBUG', f'--build-dir={self.running_dir}', f'--junit-xml={self.report_file}', f'--platform={self.instance.platform.name}' @@ -414,12 +415,6 @@ def generate_command(self): if pytest_dut_scope: command.append(f'--dut-scope={pytest_dut_scope}') - # Always pass output from the pytest test and the test image up to Twister log. - command.extend([ - '--log-cli-level=DEBUG', - '--log-cli-format=%(levelname)s: %(message)s' - ]) - # Use the test timeout as the base timeout for pytest base_timeout = handler.get_test_timeout() command.append(f'--base-timeout={base_timeout}') From d74ccc1bdb083735215d76ca8a1d6028de3d6f8d Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Wed, 17 Dec 2025 11:00:51 +0100 Subject: [PATCH 0701/3659] cmake: Do not warn on deprecated symbols w CONFIG_WARN_DEPRECATED=n CONFIG_WARN_DEPRECATED is 'y' by default. When a user actively disables CONFIG_WARN_DEPRECATED, one would expect that they would stop getting all deprecation warnings, not just the ones from kconfig. Otherwise users continue getting tons of these warnings when building deprecated functionality. So let's indeed disable them also for symbols and macros. Signed-off-by: Alberto Escolar Piedras --- CMakeLists.txt | 2 +- Kconfig.zephyr | 3 ++- include/zephyr/toolchain/gcc.h | 2 +- include/zephyr/toolchain/iar/iccarm.h | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2e38f42de789..6a716a4a6591 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -166,7 +166,7 @@ if(CONFIG_COMPILER_WARNINGS_AS_ERRORS) zephyr_link_libraries($) endif() -if(CONFIG_DEPRECATION_TEST) +if(CONFIG_DEPRECATION_TEST OR NOT CONFIG_WARN_DEPRECATED) zephyr_compile_options($<$:$>) zephyr_compile_options($<$:$>) zephyr_compile_options($<$:$>) diff --git a/Kconfig.zephyr b/Kconfig.zephyr index d534c1c7543d..8e3934ac7461 100644 --- a/Kconfig.zephyr +++ b/Kconfig.zephyr @@ -1021,7 +1021,8 @@ config WARN_DEPRECATED prompt "Warn on deprecated usage" help Print a warning when the Kconfig tree is parsed if any deprecated - features are enabled. + features are enabled, or at compile time, when deprecated macros or + symbols are used. config EXPERIMENTAL bool diff --git a/include/zephyr/toolchain/gcc.h b/include/zephyr/toolchain/gcc.h index fde3b9c0cb7a..899e245ed37f 100644 --- a/include/zephyr/toolchain/gcc.h +++ b/include/zephyr/toolchain/gcc.h @@ -349,7 +349,7 @@ do { \ #define __WARN1(s) _Pragma(#s) /* Generic message */ -#ifndef CONFIG_DEPRECATION_TEST +#if !(defined(CONFIG_DEPRECATION_TEST) || !defined(CONFIG_WARN_DEPRECATED)) #define __DEPRECATED_MACRO __WARN("Macro is deprecated") /* When adding this, remember to follow the instructions in * https://docs.zephyrproject.org/latest/develop/api/api_lifecycle.html#deprecated diff --git a/include/zephyr/toolchain/iar/iccarm.h b/include/zephyr/toolchain/iar/iccarm.h index 99d7e2cf1fd4..8d197ddf04b5 100644 --- a/include/zephyr/toolchain/iar/iccarm.h +++ b/include/zephyr/toolchain/iar/iccarm.h @@ -248,7 +248,7 @@ do { \ #define __WARN1(s) __PRAGMA(message = #s) /* Generic message */ -#ifndef CONFIG_DEPRECATION_TEST +#if !(defined(CONFIG_DEPRECATION_TEST) || !defined(CONFIG_WARN_DEPRECATED)) #define __DEPRECATED_MACRO __WARN("Macro is deprecated") #else #define __DEPRECATED_MACRO From 8c200c0f2fc34dee67d9509150448498dd5ec913 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Wed, 8 Oct 2025 14:56:28 +0200 Subject: [PATCH 0702/3659] xtensa: mmu: (cosmetic) clean up pointer types Use void * cleanly: avoid needless type-casts and use void * for generic pointers instead of uint8_t *. Signed-off-by: Guennadi Liakhovetski --- arch/xtensa/core/ptables.c | 10 ++++------ drivers/mm/mm_drv_common.c | 24 ++++++++++++------------ 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/arch/xtensa/core/ptables.c b/arch/xtensa/core/ptables.c index a78609b3ba18..b9d5bf2dcda2 100644 --- a/arch/xtensa/core/ptables.c +++ b/arch/xtensa/core/ptables.c @@ -561,8 +561,7 @@ static inline void __arch_mem_map(void *vaddr, uintptr_t paddr, uint32_t attrs, { bool ret; - ret = l2_page_table_map(xtensa_kernel_ptables, (void *)vaddr, paddr, - attrs, is_user); + ret = l2_page_table_map(xtensa_kernel_ptables, vaddr, paddr, attrs, is_user); __ASSERT(ret, "Cannot map virtual address (%p)", vaddr); #ifndef CONFIG_USERSPACE @@ -577,8 +576,7 @@ static inline void __arch_mem_map(void *vaddr, uintptr_t paddr, uint32_t attrs, SYS_SLIST_FOR_EACH_NODE(&xtensa_domain_list, node) { domain = CONTAINER_OF(node, struct arch_mem_domain, node); - ret = l2_page_table_map(domain->ptables, (void *)vaddr, paddr, - attrs, is_user); + ret = l2_page_table_map(domain->ptables, vaddr, paddr, attrs, is_user); __ASSERT(ret, "Cannot map virtual address (%p) for domain %p", vaddr, domain); @@ -730,7 +728,7 @@ static void l2_page_table_unmap(uint32_t *l1_table, void *vaddr) static inline void __arch_mem_unmap(void *vaddr) { - l2_page_table_unmap(xtensa_kernel_ptables, (void *)vaddr); + l2_page_table_unmap(xtensa_kernel_ptables, vaddr); #ifdef CONFIG_USERSPACE sys_snode_t *node; @@ -741,7 +739,7 @@ static inline void __arch_mem_unmap(void *vaddr) SYS_SLIST_FOR_EACH_NODE(&xtensa_domain_list, node) { domain = CONTAINER_OF(node, struct arch_mem_domain, node); - (void)l2_page_table_unmap(domain->ptables, (void *)vaddr); + (void)l2_page_table_unmap(domain->ptables, vaddr); } k_spin_unlock(&z_mem_domain_lock, key); #endif /* CONFIG_USERSPACE */ diff --git a/drivers/mm/mm_drv_common.c b/drivers/mm/mm_drv_common.c index 52f2ad543a2c..769a5bff4f15 100644 --- a/drivers/mm/mm_drv_common.c +++ b/drivers/mm/mm_drv_common.c @@ -81,7 +81,7 @@ bool sys_mm_drv_is_virt_region_mapped(void *virt, size_t size) bool ret = true; for (offset = 0; offset < size; offset += CONFIG_MM_DRV_PAGE_SIZE) { - uint8_t *va = (uint8_t *)virt + offset; + void *va = (uint8_t *)virt + offset; if (sys_mm_drv_page_phys_get(va, NULL) != 0) { ret = false; @@ -98,7 +98,7 @@ bool sys_mm_drv_is_virt_region_unmapped(void *virt, size_t size) bool ret = true; for (offset = 0; offset < size; offset += CONFIG_MM_DRV_PAGE_SIZE) { - uint8_t *va = (uint8_t *)virt + offset; + void *va = (uint8_t *)virt + offset; if (sys_mm_drv_page_phys_get(va, NULL) != -EFAULT) { ret = false; @@ -126,7 +126,7 @@ static int unmap_locked(void *virt, size_t size, bool is_reset) size_t offset; for (offset = 0; offset < size; offset += CONFIG_MM_DRV_PAGE_SIZE) { - uint8_t *va = (uint8_t *)virt + offset; + void *va = (uint8_t *)virt + offset; int ret2 = sys_mm_drv_unmap_page(va); @@ -161,7 +161,7 @@ int sys_mm_drv_simple_map_region(void *virt, uintptr_t phys, 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; + void *va = (uint8_t *)virt + offset; uintptr_t pa = phys + offset; ret = sys_mm_drv_map_page(va, pa, flags); @@ -207,7 +207,7 @@ int sys_mm_drv_simple_map_array(void *virt, uintptr_t *phys, offset = 0; idx = 0; while (idx < cnt) { - uint8_t *va = (uint8_t *)virt + offset; + void *va = (uint8_t *)virt + offset; ret = sys_mm_drv_map_page(va, phys[idx], flags); @@ -289,8 +289,8 @@ int sys_mm_drv_simple_remap_region(void *virt_old, size_t size, } for (offset = 0; offset < size; offset += CONFIG_MM_DRV_PAGE_SIZE) { - uint8_t *va_old = (uint8_t *)virt_old + offset; - uint8_t *va_new = (uint8_t *)virt_new + offset; + void *va_old = (uint8_t *)virt_old + offset; + void *va_new = (uint8_t *)virt_new + offset; uintptr_t pa; uint32_t flags; @@ -387,8 +387,8 @@ int sys_mm_drv_simple_move_region(void *virt_old, size_t size, } for (offset = 0; offset < size; offset += CONFIG_MM_DRV_PAGE_SIZE) { - uint8_t *va_old = (uint8_t *)virt_old + offset; - uint8_t *va_new = (uint8_t *)virt_new + offset; + void *va_old = (uint8_t *)virt_old + offset; + void *va_new = (uint8_t *)virt_new + offset; uintptr_t pa = phys_new + offset; uint32_t flags; @@ -474,8 +474,8 @@ int sys_mm_drv_simple_move_array(void *virt_old, size_t size, offset = 0; idx = 0; while (idx < phys_cnt) { - uint8_t *va_old = (uint8_t *)virt_old + offset; - uint8_t *va_new = (uint8_t *)virt_new + offset; + void *va_old = (uint8_t *)virt_old + offset; + void *va_new = (uint8_t *)virt_new + offset; uint32_t flags; ret = sys_mm_drv_page_flag_get(va_old, &flags); @@ -547,7 +547,7 @@ int sys_mm_drv_simple_update_region_flags(void *virt, size_t size, uint32_t flag 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; + void *va = (uint8_t *)virt + offset; int ret2 = sys_mm_drv_update_page_flags(va, flags); From 9fd0737c7f883334fd90169a85ee8d7e693bdade Mon Sep 17 00:00:00 2001 From: Tomi Fontanilles Date: Wed, 17 Dec 2025 15:11:21 +0200 Subject: [PATCH 0703/3659] manifest: add missing group to tf-m-tests Add tf-m-tests to the tee group for consistency. Signed-off-by: Tomi Fontanilles --- west.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/west.yml b/west.yml index 42cdfad188be..3e5262fd93e5 100644 --- a/west.yml +++ b/west.yml @@ -379,6 +379,7 @@ manifest: path: modules/tee/tf-m/tf-m-tests groups: - testing + - tee - name: trusted-firmware-a revision: 0a29cac8fe0f7bdb835b469d9ea11b8e17377a92 path: modules/tee/tf-a/trusted-firmware-a From 458e6f8ae3df3a182782de2349e832be8bdf1cd1 Mon Sep 17 00:00:00 2001 From: Mathieu Choplain Date: Fri, 19 Dec 2025 10:23:50 +0100 Subject: [PATCH 0704/3659] doc: migration-guide: 4.4: ignore case for order in drivers section The drivers section of migration guides has always been kept ordered using a zephyr-keep-sorted block. However, due to the default sorting order, the list elements are not always in alphabetical order: for example, 'STM32' comes before 'Shell' because of the uppercase 'T'. Turn on case-insensitive sorting to ensure the list is sorted in alphabetical order and adjust the existing contents accordingly. Signed-off-by: Mathieu Choplain --- doc/releases/migration-guide-4.4.rst | 78 ++++++++++++++-------------- 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/doc/releases/migration-guide-4.4.rst b/doc/releases/migration-guide-4.4.rst index 2cefd3783bd3..19d27563f2a4 100644 --- a/doc/releases/migration-guide-4.4.rst +++ b/doc/releases/migration-guide-4.4.rst @@ -37,7 +37,7 @@ Boards Device Drivers and Devicetree ***************************** -.. zephyr-keep-sorted-start re(^\w) +.. zephyr-keep-sorted-start re(^\w) ignorecase ADC === @@ -164,44 +164,6 @@ Radio * Device trees and overlays using the old compatible strings must be updated to use the new names. -STM32 -===== - -* STM32 power supply configuration is now performed using Devicetree properties. - New bindings :dtcompatible:`st,stm32h7-pwr`, :dtcompatible:`st,stm32h7rs-pwr` - and :dtcompatible:`st,stm32-dualreg-pwr` have been introduced, and all Kconfig - symbols related to power supply configuration have been removed: - - * ``CONFIG_POWER_SUPPLY_LDO`` - - * ``CONFIG_POWER_SUPPLY_DIRECT_SMPS``, - - * ``CONFIG_POWER_SUPPLY_SMPS_1V8_SUPPLIES_LDO`` - - * ``CONFIG_POWER_SUPPLY_SMPS_2V5_SUPPLIES_LDO``, - - * ``CONFIG_POWER_SUPPLY_SMPS_1V8_SUPPLIES_EXT_AND_LDO`` - - * ``CONFIG_POWER_SUPPLY_SMPS_2V5_SUPPLIES_EXT_AND_LDO`` - - * ``CONFIG_POWER_SUPPLY_SMPS_1V8_SUPPLIES_EXT`` - - * ``CONFIG_POWER_SUPPLY_SMPS_2V5_SUPPLIES_EXT`` - - * ``CONFIG_POWER_SUPPLY_EXTERNAL_SOURCE`` - -* The ST-specific chosen property ``/chosen/zephyr,ccm`` is replaced by ``/chosen/zephyr,dtcm``. - Attribute macros ``__ccm_data_section``, ``__ccm_bss_section`` and ``__ccm_noinit_section`` are - deprecated, but retained for backwards compatibility; **they will be removed in Zephyr 4.5**. - The generic ``__dtcm_{data,bss,noinit}_section`` macros should be used instead. (:github:`100590`) - -* STM32 platforms now use the default MCUboot operating mode ``swap using offset`` - (:kconfig:option:`SB_CONFIG_MCUBOOT_MODE_SWAP_USING_OFFSET`). To support this bootloader mode, - some changes to the board devicetrees are required. Several boards already support this mode - (see :github:`100385`). - The previous ``swap using move`` mode can still be selected in sysbuild by enabling - :kconfig:option:`SB_CONFIG_MCUBOOT_MODE_SWAP_USING_MOVE`. - Shell ===== @@ -252,6 +214,44 @@ Stepper * :dtcompatible:`adi,tmc50xx-stepper-drv` and :dtcompatible:`adi,tmc51xx-stepper-drv` drivers implement :c:group:`stepper_drv_interface`. +STM32 +===== + +* STM32 power supply configuration is now performed using Devicetree properties. + New bindings :dtcompatible:`st,stm32h7-pwr`, :dtcompatible:`st,stm32h7rs-pwr` + and :dtcompatible:`st,stm32-dualreg-pwr` have been introduced, and all Kconfig + symbols related to power supply configuration have been removed: + + * ``CONFIG_POWER_SUPPLY_LDO`` + + * ``CONFIG_POWER_SUPPLY_DIRECT_SMPS``, + + * ``CONFIG_POWER_SUPPLY_SMPS_1V8_SUPPLIES_LDO`` + + * ``CONFIG_POWER_SUPPLY_SMPS_2V5_SUPPLIES_LDO``, + + * ``CONFIG_POWER_SUPPLY_SMPS_1V8_SUPPLIES_EXT_AND_LDO`` + + * ``CONFIG_POWER_SUPPLY_SMPS_2V5_SUPPLIES_EXT_AND_LDO`` + + * ``CONFIG_POWER_SUPPLY_SMPS_1V8_SUPPLIES_EXT`` + + * ``CONFIG_POWER_SUPPLY_SMPS_2V5_SUPPLIES_EXT`` + + * ``CONFIG_POWER_SUPPLY_EXTERNAL_SOURCE`` + +* The ST-specific chosen property ``/chosen/zephyr,ccm`` is replaced by ``/chosen/zephyr,dtcm``. + Attribute macros ``__ccm_data_section``, ``__ccm_bss_section`` and ``__ccm_noinit_section`` are + deprecated, but retained for backwards compatibility; **they will be removed in Zephyr 4.5**. + The generic ``__dtcm_{data,bss,noinit}_section`` macros should be used instead. (:github:`100590`) + +* STM32 platforms now use the default MCUboot operating mode ``swap using offset`` + (:kconfig:option:`SB_CONFIG_MCUBOOT_MODE_SWAP_USING_OFFSET`). To support this bootloader mode, + some changes to the board devicetrees are required. Several boards already support this mode + (see :github:`100385`). + The previous ``swap using move`` mode can still be selected in sysbuild by enabling + :kconfig:option:`SB_CONFIG_MCUBOOT_MODE_SWAP_USING_MOVE`. + USB === From 074cda5a930a1bede763607b8967b76ec54ef184 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Fri, 19 Dec 2025 15:02:10 +0100 Subject: [PATCH 0705/3659] net: websocket: Remove unnecessary includes Since d45cd6716bbab3a805e3a5fd461934f0dcdc13e5 this code does not use types defined in the POSIX_API and therefore we do not need to work around header include issues. Signed-off-by: Alberto Escolar Piedras --- subsys/net/lib/websocket/websocket.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/subsys/net/lib/websocket/websocket.c b/subsys/net/lib/websocket/websocket.c index b0e5f0d393e7..fdcd9fe2c85a 100644 --- a/subsys/net/lib/websocket/websocket.c +++ b/subsys/net/lib/websocket/websocket.c @@ -22,12 +22,7 @@ LOG_MODULE_REGISTER(net_websocket, CONFIG_NET_WEBSOCKET_LOG_LEVEL); #include #include #include -#if defined(CONFIG_POSIX_API) -#include -#include -#else #include -#endif #include #include From 7b7966c440c8a443afbf2376cde5509f438c3e6b Mon Sep 17 00:00:00 2001 From: Tom Burdick Date: Wed, 17 Dec 2025 10:33:17 -0600 Subject: [PATCH 0706/3659] modules: hal_infineon: Fix whd includes Updates hal_infineon to remove stray includes of cyhal that broke the build for folks using our wireless parts with non-Infineon microcontrollers when building with Zephyr. Wrap #include's of cyhal such that they are not included when building. Signed-off-by: Tom Burdick --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 3e5262fd93e5..41084170af1c 100644 --- a/west.yml +++ b/west.yml @@ -185,7 +185,7 @@ manifest: groups: - hal - name: hal_infineon - revision: e81d26f77faa419a6b2286418dbe6796c92ed18a + revision: 470f874ce432763a2b82cd322d0ff6efc89240cd path: modules/hal/infineon groups: - hal From 31437d571d142855538d8e7211df1f49578266a3 Mon Sep 17 00:00:00 2001 From: Fabrice DJIATSA Date: Wed, 17 Dec 2025 16:59:52 +0100 Subject: [PATCH 0707/3659] tests: boot: with_mcumgr: exclude wba6 platforms These platforms were mistakenly not excluded during PR #100385 Signed-off-by: Fabrice DJIATSA --- tests/boot/with_mcumgr/testcase.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/boot/with_mcumgr/testcase.yaml b/tests/boot/with_mcumgr/testcase.yaml index b293ae2a5897..00a9b317a416 100644 --- a/tests/boot/with_mcumgr/testcase.yaml +++ b/tests/boot/with_mcumgr/testcase.yaml @@ -44,9 +44,11 @@ tests: - nucleo_u385rg_q - nucleo_wb55rg - nucleo_wba55cg + - nucleo_wba65ri - nucleo_wl55jc - stm32f3_disco - stm32u083c_dk + - stm32wba65i_dk1 integration_platforms: - nrf52840dk/nrf52840 extra_args: EXTRA_CONF_FILE="overlay-bt.conf" From 6ef3de03fa6600dd303f63cc5de4356c61209704 Mon Sep 17 00:00:00 2001 From: Zhaoxiang Jin Date: Wed, 17 Dec 2025 23:51:46 +0800 Subject: [PATCH 0708/3659] MAINTAINERS: add ZhaoxiangJin collaborator for Drivers: ADC Add ZhaoxiangJin as a collaborator for "Drivers: ADC". Signed-off-by: Zhaoxiang Jin --- MAINTAINERS.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index cd43332449bc..4f056de3a8d0 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -1255,6 +1255,7 @@ Documentation Infrastructure: status: odd fixes collaborators: - anangl + - ZhaoxiangJin files: - drivers/adc/ - include/zephyr/drivers/adc.h From 3756fa3c1aff4fe9d3f4055bf0e81150ec3e2b45 Mon Sep 17 00:00:00 2001 From: Lucien Zhao Date: Wed, 17 Dec 2025 23:01:03 +0800 Subject: [PATCH 0709/3659] boards: nxp: frdm_mcxe247: add i2c feature - support accel feature using lpi2c0 and enable accel cases: accel_trig/accel_polling - enable i2c_target_api case using lpi2c0 and lpi2c1 Signed-off-by: Lucien Zhao --- .../frdm_mcxe247/frdm_mcxe247-pinctrl.dtsi | 20 ++++++++++++ boards/nxp/frdm_mcxe247/frdm_mcxe247.dts | 19 ++++++++++++ boards/nxp/frdm_mcxe247/frdm_mcxe247.yaml | 1 + .../accel_trig/boards/frdm_mcxe247.conf | 1 + .../accel_trig/boards/frdm_mcxe247.overlay | 11 +++++++ .../boards/frdm_mcxe247.overlay | 31 +++++++++++++++++++ 6 files changed, 83 insertions(+) create mode 100644 samples/sensor/accel_trig/boards/frdm_mcxe247.conf create mode 100644 samples/sensor/accel_trig/boards/frdm_mcxe247.overlay create mode 100644 tests/drivers/i2c/i2c_target_api/boards/frdm_mcxe247.overlay diff --git a/boards/nxp/frdm_mcxe247/frdm_mcxe247-pinctrl.dtsi b/boards/nxp/frdm_mcxe247/frdm_mcxe247-pinctrl.dtsi index d7d5f1868221..cfa57658e2bd 100644 --- a/boards/nxp/frdm_mcxe247/frdm_mcxe247-pinctrl.dtsi +++ b/boards/nxp/frdm_mcxe247/frdm_mcxe247-pinctrl.dtsi @@ -26,6 +26,26 @@ }; }; + pinmux_lpi2c0: pinmux_lpi2c0 { + group0 { + pinmux = , + ; + drive-strength = "low"; + slew-rate = "slow"; + input-enable; + }; + }; + + pinmux_lpi2c1: pinmux_lpi2c1 { + group0 { + pinmux = , + ; + drive-strength = "low"; + slew-rate = "slow"; + input-enable; + }; + }; + pinmux_adc0: pinmux_adc0 { group0 { pinmux = , diff --git a/boards/nxp/frdm_mcxe247/frdm_mcxe247.dts b/boards/nxp/frdm_mcxe247/frdm_mcxe247.dts index ece371f6dc0e..ef8498491a5c 100644 --- a/boards/nxp/frdm_mcxe247/frdm_mcxe247.dts +++ b/boards/nxp/frdm_mcxe247/frdm_mcxe247.dts @@ -22,6 +22,7 @@ sw0 = &user_button_2; sw1 = &user_button_3; rtc = &counter_rtc; + accel0 = &fxls8974; }; chosen { @@ -221,6 +222,24 @@ status = "okay"; }; +&lpi2c0 { + pinctrl-0 = <&pinmux_lpi2c0>; + pinctrl-names = "default"; + status = "okay"; + + fxls8974: fxls8974@18 { + compatible = "nxp,fxls8974"; + reg = <0x18>; + status = "okay"; + }; +}; + +&lpi2c1 { + pinctrl-0 = <&pinmux_lpi2c1>; + pinctrl-names = "default"; + status = "okay"; +}; + &edma { status = "okay"; }; diff --git a/boards/nxp/frdm_mcxe247/frdm_mcxe247.yaml b/boards/nxp/frdm_mcxe247/frdm_mcxe247.yaml index e9517905ece3..078eb94b0a3b 100644 --- a/boards/nxp/frdm_mcxe247/frdm_mcxe247.yaml +++ b/boards/nxp/frdm_mcxe247/frdm_mcxe247.yaml @@ -15,6 +15,7 @@ toolchain: - gnuarmemb supported: - uart + - i2c - gpio - adc - arduino_gpio diff --git a/samples/sensor/accel_trig/boards/frdm_mcxe247.conf b/samples/sensor/accel_trig/boards/frdm_mcxe247.conf new file mode 100644 index 000000000000..9dc813d038c5 --- /dev/null +++ b/samples/sensor/accel_trig/boards/frdm_mcxe247.conf @@ -0,0 +1 @@ +CONFIG_FXLS8974_TRIGGER_OWN_THREAD=y diff --git a/samples/sensor/accel_trig/boards/frdm_mcxe247.overlay b/samples/sensor/accel_trig/boards/frdm_mcxe247.overlay new file mode 100644 index 000000000000..87db13bb47f2 --- /dev/null +++ b/samples/sensor/accel_trig/boards/frdm_mcxe247.overlay @@ -0,0 +1,11 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright 2025 NXP + */ + +&fxls8974 { + status = "okay"; + int1-gpios = <&gpioe 14 GPIO_ACTIVE_LOW>; + int2-gpios = <&gpioe 11 GPIO_ACTIVE_LOW>; +}; diff --git a/tests/drivers/i2c/i2c_target_api/boards/frdm_mcxe247.overlay b/tests/drivers/i2c/i2c_target_api/boards/frdm_mcxe247.overlay new file mode 100644 index 000000000000..2636ce02dff9 --- /dev/null +++ b/tests/drivers/i2c/i2c_target_api/boards/frdm_mcxe247.overlay @@ -0,0 +1,31 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* To test this sample, connect + * LPI2C0 SCL(J2-20) --> LPI2C3 SCL(J5-5) + * LPI2C0 SDA(J2-18) --> LPI2C3 SDA(J5-6) + */ + +&lpi2c0 { + eeprom0: eeprom@54 { + compatible = "zephyr,i2c-target-eeprom"; + reg = <0x54>; + size = <256>; + }; +}; + +&lpi2c1 { + eeprom1: eeprom@56 { + compatible = "zephyr,i2c-target-eeprom"; + reg = <0x56>; + size = <256>; + }; +}; + +/* Disable the FXLS8974 sensor to avoid conflict with accel samples */ +&fxls8974 { + status = "disabled"; +}; From aecb78a358c78ab125f5269348fd138419fb1968 Mon Sep 17 00:00:00 2001 From: Lucien Zhao Date: Wed, 17 Dec 2025 23:24:49 +0800 Subject: [PATCH 0710/3659] boards: nxp: frdm_mcxe247: add lpspi feature support lpspi feature by enabling spi_loopback case Signed-off-by: Lucien Zhao --- .../frdm_mcxe247/frdm_mcxe247-pinctrl.dtsi | 12 ++++++++++ boards/nxp/frdm_mcxe247/frdm_mcxe247.dts | 6 +++++ boards/nxp/frdm_mcxe247/frdm_mcxe247.yaml | 1 + .../spi_loopback/boards/frdm_mcxe247.overlay | 22 +++++++++++++++++++ 4 files changed, 41 insertions(+) create mode 100644 tests/drivers/spi/spi_loopback/boards/frdm_mcxe247.overlay diff --git a/boards/nxp/frdm_mcxe247/frdm_mcxe247-pinctrl.dtsi b/boards/nxp/frdm_mcxe247/frdm_mcxe247-pinctrl.dtsi index cfa57658e2bd..c183221437fb 100644 --- a/boards/nxp/frdm_mcxe247/frdm_mcxe247-pinctrl.dtsi +++ b/boards/nxp/frdm_mcxe247/frdm_mcxe247-pinctrl.dtsi @@ -46,6 +46,18 @@ }; }; + pinmux_lpspi1: pinmux_lpspi1 { + group0 { + pinmux = , + , + , + ; + slew-rate = "fast"; + drive-strength = "low"; + input-enable; + }; + }; + pinmux_adc0: pinmux_adc0 { group0 { pinmux = , diff --git a/boards/nxp/frdm_mcxe247/frdm_mcxe247.dts b/boards/nxp/frdm_mcxe247/frdm_mcxe247.dts index ef8498491a5c..9207f2088820 100644 --- a/boards/nxp/frdm_mcxe247/frdm_mcxe247.dts +++ b/boards/nxp/frdm_mcxe247/frdm_mcxe247.dts @@ -240,6 +240,12 @@ status = "okay"; }; +&lpspi1 { + status = "okay"; + pinctrl-0 = <&pinmux_lpspi1>; + pinctrl-names = "default"; +}; + &edma { status = "okay"; }; diff --git a/boards/nxp/frdm_mcxe247/frdm_mcxe247.yaml b/boards/nxp/frdm_mcxe247/frdm_mcxe247.yaml index 078eb94b0a3b..30db9142c02d 100644 --- a/boards/nxp/frdm_mcxe247/frdm_mcxe247.yaml +++ b/boards/nxp/frdm_mcxe247/frdm_mcxe247.yaml @@ -16,6 +16,7 @@ toolchain: supported: - uart - i2c + - spi - gpio - adc - arduino_gpio diff --git a/tests/drivers/spi/spi_loopback/boards/frdm_mcxe247.overlay b/tests/drivers/spi/spi_loopback/boards/frdm_mcxe247.overlay new file mode 100644 index 000000000000..3900076a7f0e --- /dev/null +++ b/tests/drivers/spi/spi_loopback/boards/frdm_mcxe247.overlay @@ -0,0 +1,22 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* To test this sample, connect + * LPSPI1 MOSI(J2-8, LPSPI1_SOUT) --> LPSPI1 MISO(J2-10, LPSPI1_SIN) + */ +&lpspi1 { + slow@0 { + compatible = "test-spi-loopback-slow"; + reg = <0>; + spi-max-frequency = <500000>; + }; + + fast@0 { + compatible = "test-spi-loopback-fast"; + reg = <0>; + spi-max-frequency = <16000000>; + }; +}; From 3824b87c197a7d64511a055495ebcc6732c22831 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Wed, 17 Dec 2025 16:58:11 +0200 Subject: [PATCH 0711/3659] doc: net: Update the overview.rst document The document was missing recent updates, also some entries were missing RFC links. Signed-off-by: Jukka Rissanen --- doc/connectivity/networking/overview.rst | 101 +++++++++++++++-------- 1 file changed, 68 insertions(+), 33 deletions(-) diff --git a/doc/connectivity/networking/overview.rst b/doc/connectivity/networking/overview.rst index c6008efebc1b..a57bb1ff021c 100644 --- a/doc/connectivity/networking/overview.rst +++ b/doc/connectivity/networking/overview.rst @@ -15,7 +15,7 @@ configuration options. You can minimize system memory consumption by enabling only those network features required by your application. Almost all features can be disabled if not needed. -* **IPv6** The support for IPv6 is enabled by default. Various IPv6 sub-options +* **IPv6** (:rfc:`8200`) is supported. Various IPv6 sub-options can be enabled or disabled depending on networking needs. * Developer can set the number of unicast and multicast IPv6 addresses that @@ -26,19 +26,19 @@ can be disabled if not needed. IPv6 prefix count can be configured at build time. * The IPv6 neighbor cache can be disabled if not needed, and its size can be configured at build time. - * The IPv6 neighbor discovery support - (:rfc:`4861`) is enabled by default. - * Multicast Listener Discovery v2 support - (:rfc:`3810`) is enabled by default. + * The IPv6 neighbor discovery support (:rfc:`4861`) is enabled by default. + * Multicast Listener Discovery v2 support (:rfc:`3810`) is enabled by default. * IPv6 header compression (6lo) is available for IPv6 connectivity for IEEE 802.15.4 networks (:rfc:`4944`). + * DHCPv6 (Dynamic Host Configuration Protocol for IPv6) (:rfc:`8415`) client + functionality is supported. + * The IPv6 privacy extension (:rfc:`8981`) is supported. -* **IPv4** The legacy IPv4 is supported by the networking stack. It - cannot be used by IEEE 802.15.4 as this network technology supports - only IPv6. IPv4 can be used in Ethernet based networks. By default - IPv4 support is disabled. +* **IPv4** (:rfc:`791`) is supported. It cannot be used by IEEE 802.15.4 as + this network technology supports only IPv6. IPv4 can be used for example + in Ethernet, Wi-Fi and Cellular based networks. - * DHCP (Dynamic Host Configuration Protocol) client is supported + * DHCP (Dynamic Host Configuration Protocol) client and server is supported (:rfc:`2131`). * The IPv4 address can also be configured manually. Static IPv4 addresses are supported by default. @@ -52,26 +52,29 @@ can be disabled if not needed. support). * **TCP** Transmission Control Protocol (:rfc:`793`) is supported. Both server - (:rfc:`793`) is supported. Both server and client roles can be used the application. The amount of TCP sockets that are available to applications can be configured at build time. * **BSD Sockets API** Support for a subset of a :ref:`BSD sockets compatible API ` is implemented. Both blocking and non-blocking datagram (UDP) and stream (TCP) - sockets are supported. + sockets are supported. Packet sockets (``AF_PACKET``) are also supported. * **Secure Sockets API** Experimental support for TLS/DTLS secure protocols and configuration options for sockets API. Secure functions for the implementation are provided by mbedTLS library. -* **MQTT** Message Queue Telemetry Transport (ISO/IEC PRF 20922) is supported. - A sample :zephyr:code-sample:`mqtt-publisher` client application for MQTT v3.1.1 is - implemented. +* **MQTT** Message Queue Telemetry Transport (ISO/IEC PRF 20922) versions 3.1.1 and 5.0 + are supported. + A sample :zephyr:code-sample:`mqtt-publisher` client application for MQTT v3.1.1 and v5.0 + is provided. + +* **MQTT-SN** MQTT for Sensor Networks version 1.2 is supported. + A sample :zephyr:code-sample:`mqtt-sn-publisher` client application is provided. * **CoAP** Constrained Application Protocol (:rfc:`7252`) is supported. Both :zephyr:code-sample:`coap-client` and :zephyr:code-sample:`coap-server` sample - applications are implemented. + applications are provided. * **LWM2M** OMA Lightweight Machine-to-Machine Protocol (`LwM2M specification 1.0.2`_) is supported via the "Bootstrap", "Client @@ -88,17 +91,19 @@ can be disabled if not needed. :zephyr:code-sample:`sockets-http-client` and :zephyr:code-sample:`sockets-http-server` samples are provided. -* **DNS** Domain Name Service - (:rfc:`1035`) client functionality - is supported. +* **Websocket** (:rfc:`6455`) client is supported. + :zephyr:code-sample:`sockets-websocket-client` sample is provided. + +* **DNS** Domain Name Service (:rfc:`1035`) client functionality is supported. Applications can use the DNS API to query domain name information or IP addresses from the DNS server. Both IPv4 (A) and IPv6 (AAAA) records can be queried. Both multicast DNS (mDNS) (:rfc:`6762`) and link-local multicast name resolution (LLMNR, :rfc:`4795`) are supported. + The DNS Service Discovery (:rfc:`6763`) is also supported. * **Network Management API.** Applications can use network management API to - listen management events generated by core stack when for example IP address + listen management events generated by core network stack when for example IP address is added to the device, or network interface is coming up etc. * **Wi-Fi Management API.** Applications can use Wi-Fi management API to @@ -128,20 +133,46 @@ can be disabled if not needed. be prioritized depending on application needs. See :ref:`traffic classification ` for more details. -* **Time Sensitive Networking.** The gPTP (generalized Precision Time Protocol) - is supported. See :ref:`gPTP support ` for more details. +* **Time Sensitive Networking.** Both the gPTP (generalized Precision Time Protocol) + and PTP (Precision Time Protocol, IEEE 1588) are supported. + See :ref:`gPTP support ` and :ref:`PTP support ` + for more details. + +* **SNTP** Simple Network Time Protocol (:rfc:`5905`) client is supported. + :zephyr:code-sample:`sntp-client` sample is provided. + +* **SOCKS5** proxy version 5 (:rfc:`1928`) is supported. + +* **TFTP** Trivial File Transfer Protocol (:rfc:`1350`) client is supported. + :zephyr:code-sample:`tftp-client` sample is provided. + +* **MIDI2** MIDI 2.0 network UDP transport is supported. + :zephyr:code-sample:`netmidi2` sample is provided. + +* **OCPP** Open Charge Point Protocol is supported. + :zephyr:code-sample:`ocpp` sample is provided. + +* **Prometheus** Metric Server functionality is supported. + :zephyr:code-sample:`prometheus` is provided. * **Network shell.** The network shell provides helpers for figuring out network status, enabling/disabling features, and issuing commands like ping or DNS resolving. The net-shell is useful when developing network software. See :ref:`network shell ` for more details. -Additionally these network technologies (link layers) are supported in -Zephyr OS v1.7 and later: +* **zperf** is an iPerf v2 network performance and bandwidth measurement tool. + Both client and server functionality is supported. :zephyr:code-sample:`zperf` + sample is provided. + +Additionally these network technologies (link layers) are supported in Zephyr OS: * IEEE 802.15.4 * Bluetooth -* Ethernet +* Ethernet, IEEE 802.3 +* Wi-Fi, IEEE 802.11 +* Cellular / PPP (:rfc:`1661`) +* Thread (:zephyr:code-sample-category:`openthread` samples are provided) +* CAN bus for SocketCAN * SLIP (IP over serial line). Used for testing with QEMU. It provides ethernet interface to host system (like Linux) and test applications can be run in Linux host and send network data to Zephyr OS device. @@ -151,29 +182,33 @@ Source Tree Layout The networking stack source code tree is organized as follows: -``subsys/net/ip/`` - This is where the IP stack code is located. +:zephyr_file:`subsys/net/` + Various optional network stack components like connection manager, + packet filter code and hostname handling are located here. + +:zephyr_file:`subsys/net/ip/` + This is where the core network stack code is located. -``subsys/net/l2/`` +:zephyr_file:`subsys/net/l2` This is where the IP stack layer 2 code is located. This includes generic support for Ethernet, IEEE 802.15.4 and Wi-Fi. -``subsys/net/lib/`` +:zephyr_file:`subsys/net/lib/` Application-level protocols (DNS, MQTT, etc.) and additional stack components (BSD Sockets, etc.). -``include/zephyr/net/`` +:zephyr_file:`include/zephyr/net/` Public API header files. These are the header files applications need to include to use IP networking functionality. -``samples/net/`` +:zephyr_file:`samples/net/` Sample networking code. This is a good reference to get started with network application development. -``tests/net/`` +:zephyr_file:`tests/net/` Test applications. These applications are used to verify the functionality of the IP stack, but are not the best - source for sample code (see ``samples/net`` instead). + source for sample code (see :zephyr_file:`samples/net/` instead). .. _LwM2M specification 1.0.2: https://www.openmobilealliance.org/release/LightweightM2M/V1_0_2-20180209-A/OMA-TS-LightweightM2M-V1_0_2-20180209-A.pdf From 84ac9af572bdf6dfb74c51140911bd36ac3bfc76 Mon Sep 17 00:00:00 2001 From: Sylvio Alves Date: Wed, 17 Dec 2025 11:35:40 -0300 Subject: [PATCH 0712/3659] drivers: bluetooth: hci: esp32: enable coded PHY support Select BT_CTLR_PHY_CODED_SUPPORT for ESP32 variants that support Bluetooth 5.0 coded PHY (long range). The original ESP32 series is excluded as it only supports Bluetooth 4.2. Signed-off-by: Sylvio Alves --- drivers/bluetooth/hci/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/bluetooth/hci/Kconfig b/drivers/bluetooth/hci/Kconfig index cfdacc064c14..88ce87d8e8ad 100644 --- a/drivers/bluetooth/hci/Kconfig +++ b/drivers/bluetooth/hci/Kconfig @@ -177,6 +177,7 @@ config BT_ESP32 select BT_CTLR_PHY_UPDATE_SUPPORT if !SOC_SERIES_ESP32 select BT_CTLR_EXT_REJ_IND_SUPPORT if !SOC_SERIES_ESP32 select BT_CTLR_PHY_2M_SUPPORT if !SOC_SERIES_ESP32 + select BT_CTLR_PHY_CODED_SUPPORT if !SOC_SERIES_ESP32 select BT_CTLR_CHAN_SEL_2_SUPPORT if !SOC_SERIES_ESP32 help Espressif HCI bluetooth interface From 05e5bbeb9b6217abed395d2465c3f1b8c0bb58f3 Mon Sep 17 00:00:00 2001 From: Vincent Tardy Date: Wed, 29 Oct 2025 15:29:02 +0100 Subject: [PATCH 0713/3659] bluetooth: stm32wbax: add BT_STM32WBA_LIB_CONFIG KConfig Add new KConfig BT_STM32WBA_LIB_CONFIG specifying the configuration of the stm32wba ble library (full or basic) depending to bluetooth features. Signed-off-by: Vincent Tardy --- drivers/bluetooth/hci/Kconfig.stm32 | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/drivers/bluetooth/hci/Kconfig.stm32 b/drivers/bluetooth/hci/Kconfig.stm32 index 52695cba04a4..e739eeb13a02 100644 --- a/drivers/bluetooth/hci/Kconfig.stm32 +++ b/drivers/bluetooth/hci/Kconfig.stm32 @@ -12,4 +12,33 @@ config BT_STM32WBA_USE_TEMP_BASED_CALIB select STM32_TEMP help Allows the linklayer to calibrate itself on the current temperature read on the ADC4 + +choice BT_STM32WBA_LIB_CONFIG + prompt "STM32WBA Bluetooth library configuration" + default BT_STM32WBA_FULL_LIB if \ + BT_EXT_ADV || BT_PER_ADV || BT_PER_ADV_SYNC || BT_SCA_UPDATE || BT_DF_CTE_RX_AOA \ + || BT_CTLR_DF_ANT_SWITCH_RX || BT_CTLR_DF_ANT_SWITCH_TX || BT_DF_CTE_TX_AOD \ + || BT_PER_ADV_SYNC_TRANSFER_RECEIVER || BT_PER_ADV_SYNC_TRANSFER_SENDER \ + || BT_CTLR_SYNC_PERIODIC || BT_ISO_UNICAST || BT_ISO_BROADCASTER \ + || BT_ISO_SYNC_RECEIVER || BT_TRANSMIT_POWER_CONTROL || BT_SUBRATING \ + || BT_CTLR_ADV_PERIODIC_ADI_SUPPORT || BT_EXT_ADV_CODING_SELECTION + default BT_STM32WBA_BASIC_LIB + help + Sets the library configuration according to the required Bluetooth features. + +config BT_STM32WBA_BASIC_LIB + bool "STM32WBA Bluetooth library basic configuration" + help + Embed basic Bluetooth features support in STM32WBA: + Advertising, Scanning, Connection Peripheral and Central, Privacy, + Channel Selection Algorithm #2, Data Length Extension, LE Encryption, + Legacy Pairing, LE secure connections, LE 2Mbit PHY, LE Coded PHY. + +config BT_STM32WBA_FULL_LIB + bool "STM32WBA Bluetooth library full configuration" + help + Embed full Bluetooth features support in STM32WBA. + +endchoice + endmenu From 6497aa45b8a0b9a8f7621512e4d4390ea6869752 Mon Sep 17 00:00:00 2001 From: Vincent Tardy Date: Tue, 16 Dec 2025 15:28:22 +0100 Subject: [PATCH 0714/3659] west.yml: update hal_stm32 revision for lib selection thanks to KConfig Update hal_stm32 revision to support ble and link layer libraries selection thanks to KConfig BT_STM32WBA_LIB_CONFIG Signed-off-by: Vincent Tardy --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 41084170af1c..beabfcc50873 100644 --- a/west.yml +++ b/west.yml @@ -255,7 +255,7 @@ manifest: groups: - hal - name: hal_stm32 - revision: 9d05ebdff47b5071fa092de243a1244e7c27f518 + revision: 9325b43737ffca79ffe1af6300c90ffde98919da path: modules/hal/stm32 groups: - hal From 7f97d3dd0a54869189856327e002d4fcc57ba5fd Mon Sep 17 00:00:00 2001 From: Pieter De Gendt Date: Fri, 5 Dec 2025 10:37:38 +0100 Subject: [PATCH 0715/3659] scripts: west: packages: Print warning on windows or run new command On non-Windows systems execute a new program, replacing the west packages call, when trying to install packages using pip. For Windows, update the documented way of installing python packages, or using 'west packages pip --install' print a warning. Signed-off-by: Pieter De Gendt --- doc/develop/beyond-GSG.rst | 39 ++++++++++++++++----- doc/develop/getting_started/index.rst | 22 ++++++++++-- scripts/utils/west-packages-pip-install.cmd | 27 ++++++++++++++ scripts/west_commands/packages.py | 39 ++++++++++++++++++--- 4 files changed, 112 insertions(+), 15 deletions(-) create mode 100644 scripts/utils/west-packages-pip-install.cmd diff --git a/doc/develop/beyond-GSG.rst b/doc/develop/beyond-GSG.rst index 3f2baea422ee..0447415a01e6 100644 --- a/doc/develop/beyond-GSG.rst +++ b/doc/develop/beyond-GSG.rst @@ -136,16 +136,39 @@ Keeping Zephyr updated To update the Zephyr project source code, you need to get the latest changes via ``git``. Afterwards, run ``west update`` as mentioned in the previous paragraph. -Additionally, in the case of updated or added Python dependencies, running -``west packages pip --install`` will make sure these are up-to-date. +Additionally, check for updated or added Python dependencies. -.. code-block:: console +.. tabs:: - # replace zephyrproject with the path you gave west init - cd zephyrproject/zephyr - git pull - west update - west packages pip --install + .. group-tab:: Linux/macOS + + .. code-block:: console + + # replace zephyrproject with the path you gave west init + cd zephyrproject/zephyr + git pull + west update + west packages pip --install + + .. group-tab:: Windows + + .. tabs:: + + .. code-tab:: bat + + :: replace zephyrproject with the path you gave west init + cd zephyrproject\zephyr + git pull + west update + cmd /c scripts\utils\west-packages-pip-install.cmd + + .. code-tab:: powershell + + # replace zephyrproject with the path you gave west init + cd zephyrproject\zephyr + git pull + west update + python -m pip install @((west packages pip) -split ' ') Export Zephyr CMake package *************************** diff --git a/doc/develop/getting_started/index.rst b/doc/develop/getting_started/index.rst index bfa24afb71d4..be451daf7b73 100644 --- a/doc/develop/getting_started/index.rst +++ b/doc/develop/getting_started/index.rst @@ -266,6 +266,10 @@ chosen. You'll also install Zephyr's additional Python dependencies in a west packages pip --install + .. note:: + + This could downgrade or upgrade west itself. + .. group-tab:: macOS #. Create a new virtual environment: @@ -317,6 +321,10 @@ chosen. You'll also install Zephyr's additional Python dependencies in a west packages pip --install + .. note:: + + This could downgrade or upgrade west itself. + .. group-tab:: Windows #. Open a ``cmd.exe`` or PowerShell terminal window **as a regular user** @@ -389,9 +397,19 @@ chosen. You'll also install Zephyr's additional Python dependencies in a #. Install Python dependencies using ``west packages``. - .. code-block:: bat + .. tabs:: - west packages pip --install + .. code-tab:: bat + + cmd /c scripts\utils\west-packages-pip-install.cmd + + .. code-tab:: powershell + + python -m pip install @((west packages pip) -split ' ') + + .. note:: + + This could downgrade or upgrade west itself. Install the Zephyr SDK ********************** diff --git a/scripts/utils/west-packages-pip-install.cmd b/scripts/utils/west-packages-pip-install.cmd new file mode 100644 index 000000000000..e05495b7c8e4 --- /dev/null +++ b/scripts/utils/west-packages-pip-install.cmd @@ -0,0 +1,27 @@ +:: SPDX-FileCopyrightText: Copyright The Zephyr Project Contributors +:: SPDX-License-Identifier: Apache-2.0 + +@echo off +rem Collect packages from west and install them with a single pip call. +setlocal enabledelayedexpansion + +set "PACKAGES=" + +for /f "usebackq delims=" %%p in (`west packages pip`) do ( + if defined PACKAGES ( + set "PACKAGES=!PACKAGES! %%p" + ) else ( + set "PACKAGES=%%p" + ) +) + +if not defined PACKAGES ( + echo west packages pip returned no packages to install. + exit /b 0 +) + +echo Installing packages with: python.exe -m pip install %PACKAGES% +python.exe -m pip install %PACKAGES% +set "RESULT=%ERRORLEVEL%" + +endlocal & exit /b %RESULT% diff --git a/scripts/west_commands/packages.py b/scripts/west_commands/packages.py index 795f3d4fe139..30c1d26fe268 100644 --- a/scripts/west_commands/packages.py +++ b/scripts/west_commands/packages.py @@ -4,13 +4,15 @@ import argparse import os +import platform import subprocess import sys import textwrap from itertools import chain -from pathlib import Path +from pathlib import Path, PureWindowsPath from west.commands import WestCommand +from west.util import quote_sh_list from zephyr_ext_common import ZEPHYR_BASE sys.path.append(os.fspath(Path(__file__).parent.parent)) @@ -157,11 +159,38 @@ def do_run_pip(self, args, manager_args): self.die("Running pip install outside of a virtual environment") if len(requirements) > 0: - subprocess.check_call( - [sys.executable, "-m", "pip", "install"] - + list(chain.from_iterable([("-r", r) for r in requirements])) - + manager_args + cmd = [sys.executable, "-m", "pip", "install"] + cmd += chain.from_iterable([("-r", str(r)) for r in requirements]) + cmd += manager_args + self.dbg(quote_sh_list(cmd)) + + # Use os.execv to execute a new program, replacing the current west process, + # this unloads all python modules first and allows for pip to update packages safely + if platform.system() != 'Windows': + os.execv(cmd[0], cmd) + + # Only reachable on Windows systems + # Windows does not really support os.execv: + # https://github.com/python/cpython/issues/63323 + # https://github.com/python/cpython/issues/101191 + # Warn the users about permission errors as those reported in: + # https://github.com/zephyrproject-rtos/zephyr/issues/100296 + cmdscript = ( + PureWindowsPath(__file__).parents[1] / "utils" / "west-packages-pip-install.cmd" ) + self.wrn( + "Updating packages on Windows with 'west packages pip --install', that are " + "currently in use by west, results in permission errors. Leaving your " + "environment with conflicting package versions. Recommended is to start with " + "a new environment in that case.\n\n" + "To avoid this using powershell run the following command instead:\n" + f"{sys.executable} -m pip install @((west packages pip) -split ' ')\n\n" + "Using cmd.exe execute the helper script:\n" + f"cmd /c {cmdscript}\n\n" + "Running 'west packages pip --install -- --dry-run' can provide information " + "without actually updating the environment." + ) + subprocess.check_call(cmd) else: self.inf("Nothing to install") return From 5df75500d55b56b8732c907991d7aa33b28c1b8c Mon Sep 17 00:00:00 2001 From: Vit Stanicek Date: Thu, 6 Nov 2025 14:15:35 +0100 Subject: [PATCH 0716/3659] Revert "drivers: audio: dmic_mcux: remove arbitrary mapping of pdm to dmic channel" This reverts commit 1f69b91e909cc37301ac15d7e7f30e87c413ab21. Chose to revert it because its changes constitute a deviation from the dmic API, resulting in failing tests on affected platforms (mimxrt685s and mimxrt595s mainly). Signed-off-by: Vit Stanicek --- drivers/audio/dmic_mcux.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/audio/dmic_mcux.c b/drivers/audio/dmic_mcux.c index 751ecaba04a6..ec2b9f0eecda 100644 --- a/drivers/audio/dmic_mcux.c +++ b/drivers/audio/dmic_mcux.c @@ -67,11 +67,18 @@ static uint8_t dmic_mcux_hw_chan(struct mcux_dmic_drv_data *drv_data, enum pdm_lr lr; uint8_t hw_chan; + /* This function assigns hardware channel "n" to the left channel, + * and hardware channel "n+1" to the right channel. This choice is + * arbitrary, but must be followed throughout the driver. + */ dmic_parse_channel_map(drv_data->chan_map_lo, drv_data->chan_map_hi, log_chan, &hw_chan, &lr); - - return hw_chan; + if (lr == PDM_CHAN_LEFT) { + return hw_chan * 2; + } else { + return (hw_chan * 2) + 1; + } } static void dmic_mcux_activate_channels(struct mcux_dmic_drv_data *drv_data, @@ -494,9 +501,9 @@ static int dmic_mcux_configure(const struct device *dev, dmic_parse_channel_map(channel->req_chan_map_lo, channel->req_chan_map_hi, chan + 1, &hw_chan_1, &lr_1); - /* Verify that paired channels use consecutive hardware index */ + /* Verify that paired channels use same hardware index */ if ((lr_0 == lr_1) || - (hw_chan_1 != (hw_chan_0 + 1))) { + (hw_chan_0 != hw_chan_1)) { return -EINVAL; } } From d98fb0b2e5a13ddec7350e83e4daaa6c26f5a62a Mon Sep 17 00:00:00 2001 From: Vit Stanicek Date: Thu, 6 Nov 2025 14:19:41 +0100 Subject: [PATCH 0717/3659] Revert "samples: i2s_codec: Modify DMIC channel mapping" This reverts commit d11474ce6463c89a8e43565142fae5914850c845. Follows the reversal of 1f69b91e909cc37301ac15d7e7f30e87c413ab21, as this commit reflects changes made in there. Signed-off-by: Vit Stanicek --- samples/drivers/i2s/i2s_codec/src/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/drivers/i2s/i2s_codec/src/main.c b/samples/drivers/i2s/i2s_codec/src/main.c index b71b560fa7b5..34108ae368c2 100644 --- a/samples/drivers/i2s/i2s_codec/src/main.c +++ b/samples/drivers/i2s/i2s_codec/src/main.c @@ -132,7 +132,7 @@ int main(void) #if CONFIG_USE_DMIC cfg.channel.req_num_chan = 2; cfg.channel.req_chan_map_lo = dmic_build_channel_map(0, 0, PDM_CHAN_LEFT) | - dmic_build_channel_map(1, 1, PDM_CHAN_RIGHT); + dmic_build_channel_map(1, 0, PDM_CHAN_RIGHT); cfg.streams[0].pcm_rate = SAMPLE_FREQUENCY; cfg.streams[0].block_size = BLOCK_SIZE; From d98f7ffa382c43a899838a3cb686b483d58c5182 Mon Sep 17 00:00:00 2001 From: Appana Durga Kedareswara rao Date: Sat, 18 Oct 2025 20:28:10 +0530 Subject: [PATCH 0718/3659] boards: amd: versalnet_rpu: Document PDI requirements for targets Clarify the different requirements for QEMU emulation versus real hardware deployment in the versalnet_rpu board documentation. For QEMU target: - XSDB (Xilinx System Debugger) is not used - PDI (Programmable Device Image) is not required - QEMU provides direct emulation without hardware initialization files For real hardware target: - XSDB and PDI file are required - PDI contains the hardware initialization and boot configuration needed for the physical device This documentation update helps users understand why PDI is optional for QEMU testing but mandatory for physical board deployment. Signed-off-by: Appana Durga Kedareswara rao --- boards/amd/versalnet_rpu/doc/index.rst | 40 ++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/boards/amd/versalnet_rpu/doc/index.rst b/boards/amd/versalnet_rpu/doc/index.rst index 35d3ea5f22df..1e793e6d9c5b 100644 --- a/boards/amd/versalnet_rpu/doc/index.rst +++ b/boards/amd/versalnet_rpu/doc/index.rst @@ -54,12 +54,48 @@ Programming and Debugging .. zephyr:board-supported-runners:: -Build and flash in the usual way. Here is an example for the :zephyr:code-sample:`hello_world` application. +This board supports two deployment targets: + +QEMU Emulation +============== + +For QEMU target, XSDB (Xilinx System Debugger) is not used and therefore PDI +(Programmable Device Image) is not required. QEMU provides direct emulation +without needing hardware initialization files. + +Build and run with QEMU: + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: versalnet_rpu + :goals: build run + +Alternatively, you can build and run separately: + +.. code-block:: console + + west build -b versalnet_rpu samples/hello_world + west build -t run + +Real Hardware +============= + +For deployment on real Versal Net hardware, XSDB and a PDI file are required. +The PDI file contains the hardware initialization and boot configuration needed +for the physical device. + +Build the application: .. zephyr-app-commands:: :zephyr-app: samples/hello_world :board: versalnet_rpu - :goals: build flash + :goals: build + +Flash to real hardware with PDI file: + +.. code-block:: console + + west flash --runner xsdb --pdi /path/to/your.pdi You should see the following message on the console: From 66cf8c502b5289328fcf192b76a56844eb75b397 Mon Sep 17 00:00:00 2001 From: Bill Waters Date: Fri, 17 Oct 2025 14:06:50 -0700 Subject: [PATCH 0719/3659] drivers: timer: infineon pdl lp_timer Add PDL-based low-power timer for the E84 board Signed-off-by: Bill Waters --- .../kit_pse84_eval/kit_pse84_eval_m33.dts | 4 + .../kit_pse84_eval_m33_defconfig | 1 - .../kit_pse84_eval/kit_pse84_eval_m55.dts | 4 + drivers/timer/CMakeLists.txt | 3 +- drivers/timer/Kconfig.infineon_lp | 26 +- drivers/timer/infineon_lp_timer_pdl.c | 370 ++++++++++++++++++ dts/arm/infineon/cat1b/psc3/psc3.dtsi | 5 +- dts/arm/infineon/cat1b/psc3/psc3_s.dtsi | 5 +- dts/arm/infineon/edge/pse84/pse84.dtsi | 4 +- dts/arm/infineon/edge/pse84/pse84_s.dtsi | 4 +- .../timer/infineon,cat1-lp-timer-pdl.yaml | 20 + dts/bindings/timer/infineon,lp-timer.yaml | 8 +- soc/infineon/edge/pse84/Kconfig.defconfig | 10 +- .../edge/pse84/security_config/pse84_boot.c | 2 + 14 files changed, 443 insertions(+), 23 deletions(-) create mode 100644 drivers/timer/infineon_lp_timer_pdl.c create mode 100644 dts/bindings/timer/infineon,cat1-lp-timer-pdl.yaml diff --git a/boards/infineon/kit_pse84_eval/kit_pse84_eval_m33.dts b/boards/infineon/kit_pse84_eval/kit_pse84_eval_m33.dts index bbff96224444..79f147c56ef7 100644 --- a/boards/infineon/kit_pse84_eval/kit_pse84_eval_m33.dts +++ b/boards/infineon/kit_pse84_eval/kit_pse84_eval_m33.dts @@ -31,6 +31,10 @@ }; }; +&mcwdt0 { + status = "okay"; +}; + /* For the dpll clocks declared below * The clock-frequency value is here for dts reference, but * it does not affect the frequency set by the clock_control diff --git a/boards/infineon/kit_pse84_eval/kit_pse84_eval_m33_defconfig b/boards/infineon/kit_pse84_eval/kit_pse84_eval_m33_defconfig index cf7084e84d45..c8c4ea550b9a 100644 --- a/boards/infineon/kit_pse84_eval/kit_pse84_eval_m33_defconfig +++ b/boards/infineon/kit_pse84_eval/kit_pse84_eval_m33_defconfig @@ -8,7 +8,6 @@ CONFIG_FPU=y CONFIG_FPU_SHARING=y # General configuration -CONFIG_CORTEX_M_SYSTICK=y CONFIG_BUILD_OUTPUT_HEX=y CONFIG_ARM_MPU=y diff --git a/boards/infineon/kit_pse84_eval/kit_pse84_eval_m55.dts b/boards/infineon/kit_pse84_eval/kit_pse84_eval_m55.dts index 506c0a8e51a0..4a5257296be3 100644 --- a/boards/infineon/kit_pse84_eval/kit_pse84_eval_m55.dts +++ b/boards/infineon/kit_pse84_eval/kit_pse84_eval_m55.dts @@ -34,3 +34,7 @@ zephyr,shell-uart = &uart2; }; }; + +&mcwdt1 { + status = "okay"; +}; diff --git a/drivers/timer/CMakeLists.txt b/drivers/timer/CMakeLists.txt index 15490ca85cbd..805f6e7fd147 100644 --- a/drivers/timer/CMakeLists.txt +++ b/drivers/timer/CMakeLists.txt @@ -18,7 +18,8 @@ zephyr_library_sources_ifdef(CONFIG_CORTEX_M_SYSTICK cortex_m_systick.c) zephyr_library_sources_ifdef(CONFIG_ESP32_SYS_TIMER esp32_sys_timer.c) zephyr_library_sources_ifdef(CONFIG_GECKO_BURTC_TIMER gecko_burtc_timer.c) zephyr_library_sources_ifdef(CONFIG_HPET_TIMER hpet.c) -zephyr_library_sources_ifdef(CONFIG_INFINEON_CAT1_LP_TIMER infineon_lp_timer.c) +zephyr_library_sources_ifdef(CONFIG_INFINEON_LP_TIMER_HAL infineon_lp_timer.c) +zephyr_library_sources_ifdef(CONFIG_INFINEON_LP_TIMER_PDL infineon_lp_timer_pdl.c) zephyr_library_sources_ifdef(CONFIG_INTEL_ADSP_TIMER intel_adsp_timer.c) zephyr_library_sources_ifdef(CONFIG_ITE_IT51XXX_TIMER ite_it51xxx_timer.c) zephyr_library_sources_ifdef(CONFIG_ITE_IT8XXX2_TIMER ite_it8xxx2_timer.c) diff --git a/drivers/timer/Kconfig.infineon_lp b/drivers/timer/Kconfig.infineon_lp index 8a5567cea74b..aff0a0ed4ea1 100644 --- a/drivers/timer/Kconfig.infineon_lp +++ b/drivers/timer/Kconfig.infineon_lp @@ -1,17 +1,29 @@ -# Infineon CAT1 LPTIMER configuration options - -# Copyright (c) 2025 Cypress Semiconductor Corporation (an Infineon company) or -# an affiliate of Cypress Semiconductor Corporation +# Copyright (c) 2025 Infineon Technologies AG, +# or an affiliate of Infineon Technologies AG. # # SPDX-License-Identifier: Apache-2.0 +# +# Infineon CAT1 LPTIMER configuration options -config INFINEON_CAT1_LP_TIMER - bool "Infineon CAT1 Low Power Timer driver" +config INFINEON_LP_TIMER_HAL + bool "Infineon Low Power Timer driver" default y depends on DT_HAS_INFINEON_LP_TIMER_ENABLED - depends on PM + depends on USE_INFINEON_LEGACY_HAL select USE_INFINEON_LPTIMER select TICKLESS_CAPABLE help This module implements a kernel device driver for the LowPower Timer + and provides the standard "system clock driver" interfaces. This implementation + is based on the Infineon Legacy HAL. + +config INFINEON_LP_TIMER_PDL + bool "Infineon Low Power Timer driver" + default y + depends on DT_HAS_INFINEON_LP_TIMER_ENABLED + depends on !USE_INFINEON_LEGACY_HAL + select USE_INFINEON_LPTIMER + select TICKLESS_CAPABLE + help + This module implements a PDL based kernel device driver for the LowPower Timer and provides the standard "system clock driver" interfaces. diff --git a/drivers/timer/infineon_lp_timer_pdl.c b/drivers/timer/infineon_lp_timer_pdl.c new file mode 100644 index 000000000000..26bf2f7e0d52 --- /dev/null +++ b/drivers/timer/infineon_lp_timer_pdl.c @@ -0,0 +1,370 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @brief Low Power timer driver for Infineon CAT1 MCU family. + */ + +#define DT_DRV_COMPAT infineon_lp_timer + +#include +#include +#include +#include +#include +#include + +#include +LOG_MODULE_REGISTER(ifx_cat1_lp_timer_pdl, CONFIG_KERNEL_LOG_LEVEL); + +/* Enable the LPTimer counters. Here we enable two 16-bit counters and one 32-bit counter to + * create a 64-bit counter + */ +#define LPTIMER_COUNTERS (CY_MCWDT_CTR0 | CY_MCWDT_CTR1 | CY_MCWDT_CTR2) + +/* The application only needs one lptimer. Report an error if more than one is selected. */ +#if DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) > 1 +#error Only one LPTIMER instance should be enabled +#endif /* DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) > 1 */ + +/* Minimum amount of lfclk cycles of that LPTIMER can delay for. */ +#define LPTIMER_MIN_DELAY (3U) +/* ~36hours. Not set to 0xffffffff to avoid C0 and C1 both overflowing */ +#define LPTIMER_MAX_DELAY_TICKS (0xfff0ffffUL) + +static bool clear_int_mask; +static uint8_t isr_instruction; + +static MCWDT_STRUCT_Type *reg_addr = (MCWDT_STRUCT_Type *)DT_INST_REG_ADDR(0); +static const uint32_t clock_frequency = DT_INST_PROP(0, clock_frequency); + +#define DEFAULT_TIMEOUT (0xFFFFUL) + +#include "cy_mcwdt.h" + +#if defined(CY_IP_MXS40SSRSS) +static const uint16_t LPTIMER_RESET_TIME_US = 93; +#else +static const uint16_t LPTIMER_RESET_TIME_US = 62; +#endif + +/* The value of this variable is intended to be 0 */ +static const uint16_t LPTIMER_SETMATCH_TIME_US; + +static const cy_stc_mcwdt_config_t lptimer_default_cfg = {.c0Match = 0xFFFF, + .c1Match = 0xFFFF, + .c0Mode = CY_MCWDT_MODE_INT, + .c1Mode = CY_MCWDT_MODE_INT, + .c2Mode = CY_MCWDT_MODE_NONE, + .c2ToggleBit = 0, + .c0ClearOnMatch = false, + .c1ClearOnMatch = false, + .c0c1Cascade = true, + .c1c2Cascade = false}; + +static uint64_t last_lptimer_value; +static struct k_spinlock lock; + +static void lptimer_enable_event(bool enable) +{ +#define LPTIMER_ISR_CALL_USER_CB_MASK (0x01) + isr_instruction &= ~LPTIMER_ISR_CALL_USER_CB_MASK; + isr_instruction |= (uint8_t)enable; + + if (enable) { + Cy_MCWDT_ClearInterrupt(reg_addr, CY_MCWDT_CTR1); + Cy_MCWDT_SetInterruptMask(reg_addr, CY_MCWDT_CTR1); + + } else { + Cy_MCWDT_ClearInterrupt(reg_addr, CY_MCWDT_CTR1); + Cy_MCWDT_SetInterruptMask(reg_addr, 0); + } +} + +static void lptimer_set_delay(uint32_t delay) +{ + uint16_t c0_old_match; + unsigned int key; + uint32_t timeout = DEFAULT_TIMEOUT; + uint16_t c0_current_ticks; + uint16_t c0_match; + uint32_t c0_new_ticks; + uint16_t c1_current_ticks; + uint16_t c1_match; + + clear_int_mask = true; + + if ((Cy_MCWDT_GetEnabledStatus(reg_addr, CY_MCWDT_COUNTER0) == 0UL) || + (Cy_MCWDT_GetEnabledStatus(reg_addr, CY_MCWDT_COUNTER1) == 0UL) || + (Cy_MCWDT_GetEnabledStatus(reg_addr, CY_MCWDT_COUNTER2) == 0UL)) { + return; + } + + /* - 16 bit Counter0 (C0) & Counter1 (C1) are cascaded to generated a 32 bit counter. + * - Counter2 (C2) is a free running counter. + * - C0 continues counting after reaching its match value. On PSoC™ 4 Counter1 is reset on + * match. On PSoC™ 6 it continues counting. + * - An interrupt is generated when C1 reaches the match value. On PSoC™ 4 this happens + * when the counter increments to the same value as match. On PSoC™ 6 this happens when it + * increments past the match value. + * + * EXAMPLE: + * Supposed T=C0=C1=0, and we need to trigger an interrupt at T=0x18000. + * We set C0_match to 0x8000 and C1 match to 1. + * At T = 0x8000, C0_value matches C0_match so C1 get incremented. C1/C0=0x18000. + * At T = 0x18000, C0_value matches C0_match again so C1 get incremented from 1 to 2. + * When C1 get incremented from 1 to 2 the interrupt is generated. + * At T = 0x18000, C1/C0 = 0x28000. + */ + + if (delay <= LPTIMER_MIN_DELAY) { + delay = LPTIMER_MIN_DELAY; + } + if (delay > LPTIMER_MAX_DELAY_TICKS) { + delay = LPTIMER_MAX_DELAY_TICKS; + } + + Cy_MCWDT_ClearInterrupt(reg_addr, CY_MCWDT_CTR1); + c0_old_match = (uint16_t)Cy_MCWDT_GetMatch(reg_addr, CY_MCWDT_COUNTER0); + key = irq_lock(); + + /* Cascading from C0 match into C1 is queued and can take 1 full LF clk cycle. + * There are 3 cases: + * Case 1: if c0 = match0 then the cascade into C1 will happen 1 cycle from now. The value + * c1_current_ticks is 1 lower than expected. Case 2: if c0 = match0 -1 then cascade may or + * not happen before new match value would occur. Match occurs on rising clock edge. + * Synchronizing match value occurs on falling edge. Wait until c0 = match0 to + * ensure cascade occurs. Case 3: everything works as expected. + * + * Note: timeout is needed here just in case the LFCLK source gives out. This avoids device + * lockup. + * + * ((2 * Cycles_LFClk) / Cycles_cpu_iteration) * (HFCLk_max / LFClk_min) = + * Iterations_required Typical case: (2 / 100) * ((150x10^6)/33576) = 89 iterations Worst + * case: (2 / 100) * ((150x10^6)/1) = 3x10^6 iterations Compromise: (2 / 100) * + * ((150x10^6)/0xFFFF iterations) = 45 Hz = LFClk_min + */ + c0_current_ticks = (uint16_t)Cy_MCWDT_GetCount(reg_addr, CY_MCWDT_COUNTER0); + /* Wait until the cascade has definitively happened. It takes a clock cycle for the + * cascade to happen, and potentially another a full LFCLK clock cycle for the + * cascade to propagate up to the HFCLK-domain registers that the CPU reads. + */ + while (((((uint16_t)(c0_old_match - 1)) == c0_current_ticks) || + (c0_old_match == c0_current_ticks) || + (((uint16_t)(c0_old_match + 1)) == c0_current_ticks)) && + (timeout != 0UL)) { + c0_current_ticks = (uint16_t)Cy_MCWDT_GetCount(reg_addr, CY_MCWDT_COUNTER0); + timeout--; + } + + if (timeout == 0UL) { + /* Timeout has occurred. There could have been a clock failure while waiting for the + * count value to update. + */ + irq_unlock(key); + return; + } + + c0_match = (uint16_t)(c0_current_ticks + delay); + /* Changes can take up to 2 clk_lf cycles to propagate. If we set the match within this + * window of the current value, then it is nondeterministic whether the first cascade will + * trigger immediately or after 2^16 cycles. Wait until c0 is in a more predictable state. + */ + timeout = DEFAULT_TIMEOUT; + c0_new_ticks = c0_current_ticks; + + while (((c0_new_ticks == c0_match) || (c0_new_ticks == ((uint16_t)(c0_match + 1))) || + (c0_new_ticks == ((uint16_t)(c0_match + 2)))) && + (timeout != 0UL)) { + c0_new_ticks = (uint16_t)Cy_MCWDT_GetCount(reg_addr, CY_MCWDT_COUNTER0); + timeout--; + } + + delay -= (c0_new_ticks >= c0_current_ticks) + ? (uint32_t)(c0_new_ticks - c0_current_ticks) + : (uint32_t)((0xFFFFU - c0_current_ticks) + c0_new_ticks); + + c0_match = (uint16_t)(c0_current_ticks + delay); + c1_current_ticks = (uint16_t)Cy_MCWDT_GetCount(reg_addr, CY_MCWDT_COUNTER1); + c1_match = (uint16_t)(c1_current_ticks + (delay >> 16)); + + Cy_MCWDT_SetMatch(reg_addr, CY_MCWDT_COUNTER0, c0_match, LPTIMER_SETMATCH_TIME_US); + Cy_MCWDT_SetMatch(reg_addr, CY_MCWDT_COUNTER1, c1_match, LPTIMER_SETMATCH_TIME_US); + + irq_unlock(key); + Cy_MCWDT_SetInterruptMask(reg_addr, CY_MCWDT_CTR1); +} + +void sys_clock_set_timeout(int32_t ticks, bool idle) +{ + uint64_t current_cycles; + uint32_t cycles_per_tick; + uint32_t delay_cycles; + uint64_t next_tick_cycles; + k_spinlock_key_t key; + + ARG_UNUSED(idle); + + if (!IS_ENABLED(CONFIG_TICKLESS_KERNEL)) { + return; + } + + if (ticks == K_TICKS_FOREVER) { + /* Disable the LPTIMER events */ + lptimer_enable_event(false); + return; + } + + /* Configure and Enable the LPTIMER events */ + lptimer_enable_event(true); + + /* passing ticks==1 means "announce the next tick", ticks value of zero (or even negative) + * is legal and treated identically: it simply indicates the kernel would like the next + * tick announcement as soon as possible. + */ + if (ticks < 1) { + ticks = 1; + } + + /* Calculate cycles per tick */ + cycles_per_tick = ((clock_frequency / CONFIG_SYS_CLOCK_TICKS_PER_SEC)); + + /* Get current cycle count from the free-running counter */ + key = k_spin_lock(&lock); + current_cycles = Cy_MCWDT_GetCount(reg_addr, CY_MCWDT_COUNTER2); + + /* Calculate the next tick-aligned cycle count that is at least 'ticks' in the future. + * This ensures: next_tick_cycles % cycles_per_tick == 0 (tick-aligned) + * AND: next_tick_cycles >= current_cycles + ticks * cycles_per_tick + */ + next_tick_cycles = ((current_cycles / cycles_per_tick) + ticks) * cycles_per_tick; + + /* Verify we're at least ticks * cycles_per_tick in the future. + * Due to integer division, we may be slightly less if not at a tick boundary. + * Add one more tick period if needed to satisfy the invariant. + */ + if (next_tick_cycles < current_cycles + (ticks * cycles_per_tick)) { + next_tick_cycles += cycles_per_tick; + } + + /* Calculate delay from current position to next tick-aligned position. + * Unsigned arithmetic handles rollover correctly. + */ + delay_cycles = next_tick_cycles - current_cycles; + + /* Ensure minimum delay requirement and check for excessive delays. + * The hardware requires a minimum delay and has a maximum delay constraint. + */ + if (delay_cycles < LPTIMER_MIN_DELAY) { + /* If calculated delay is too short, move to next tick boundary */ + next_tick_cycles += cycles_per_tick; + delay_cycles = next_tick_cycles - current_cycles; + } + + if (delay_cycles > LPTIMER_MAX_DELAY_TICKS) { + /* Delay exceeds maximum supported by hardware, clamp to maximum */ + delay_cycles = LPTIMER_MAX_DELAY_TICKS; + } + + /* Set the delay value for the next wakeup interrupt */ + lptimer_set_delay(delay_cycles); + k_spin_unlock(&lock, key); +} + +uint32_t sys_clock_elapsed(void) +{ + uint32_t current_cycles; + uint32_t cycles_per_tick; + uint32_t delta_cycles; + uint32_t delta_ticks; + + if (!IS_ENABLED(CONFIG_TICKLESS_KERNEL)) { + return 0; + } + + cycles_per_tick = clock_frequency / CONFIG_SYS_CLOCK_TICKS_PER_SEC; + + k_spinlock_key_t key = k_spin_lock(&lock); + + current_cycles = Cy_MCWDT_GetCount(reg_addr, CY_MCWDT_COUNTER2); + + /* Calculate elapsed hardware cycles since the last announcement */ + delta_cycles = current_cycles - (uint32_t)last_lptimer_value; + + k_spin_unlock(&lock, key); + + /* Convert hardware cycles to kernel ticks */ + delta_ticks = delta_cycles / cycles_per_tick; + + return delta_ticks; +} + +uint32_t sys_clock_cycle_get_32(void) +{ + uint32_t cycles; + + /* Read the current hardware cycle count from free-running counter */ + k_spinlock_key_t key = k_spin_lock(&lock); + + cycles = Cy_MCWDT_GetCount(reg_addr, CY_MCWDT_COUNTER2); + + k_spin_unlock(&lock, key); + + return cycles; +} + +static void lptimer_isr(void) +{ + Cy_MCWDT_ClearInterrupt(reg_addr, LPTIMER_COUNTERS); + + /* Clear interrupt mask if set only from lptimer_set_delay() function */ + if (clear_int_mask) { + Cy_MCWDT_SetInterruptMask(reg_addr, 0); + } + + if ((isr_instruction & LPTIMER_ISR_CALL_USER_CB_MASK) != 0) { + /* Announce the number of ticks that have elapsed since the last announcement */ + uint32_t current_cycles = Cy_MCWDT_GetCount(reg_addr, CY_MCWDT_COUNTER2); + uint32_t cycles_per_tick = clock_frequency / CONFIG_SYS_CLOCK_TICKS_PER_SEC; + uint64_t delta_ticks; + k_spinlock_key_t key = k_spin_lock(&lock); + + delta_ticks = (uint64_t)((current_cycles - last_lptimer_value) / cycles_per_tick); + + /* Update last announced position to maintain tick alignment */ + last_lptimer_value += delta_ticks * cycles_per_tick; + k_spin_unlock(&lock, key); + + sys_clock_announce(IS_ENABLED(CONFIG_TICKLESS_KERNEL) ? delta_ticks + : (delta_ticks > 0)); + } +} + +static int lptimer_init(void) +{ + cy_rslt_t rslt = CY_MCWDT_BAD_PARAM; + cy_stc_mcwdt_config_t cfg = lptimer_default_cfg; + + clear_int_mask = false; + isr_instruction = LPTIMER_ISR_CALL_USER_CB_MASK; + + rslt = (cy_rslt_t)Cy_MCWDT_Init(reg_addr, &cfg); + if (rslt == CY_RSLT_SUCCESS) { + Cy_MCWDT_Enable(reg_addr, LPTIMER_COUNTERS, LPTIMER_RESET_TIME_US); + } else { + Cy_MCWDT_Disable(reg_addr, LPTIMER_COUNTERS, LPTIMER_RESET_TIME_US); + Cy_MCWDT_DeInit(reg_addr); + return -EINVAL; + } + + IRQ_CONNECT(DT_INST_IRQN(0), DT_INST_IRQ(0, priority), lptimer_isr, NULL, 0); + irq_enable(DT_INST_IRQN(0)); + + return 0; +} + +SYS_INIT(lptimer_init, PRE_KERNEL_2, CONFIG_SYSTEM_CLOCK_INIT_PRIORITY); diff --git a/dts/arm/infineon/cat1b/psc3/psc3.dtsi b/dts/arm/infineon/cat1b/psc3/psc3.dtsi index af69a69509b7..fd69683e5d92 100644 --- a/dts/arm/infineon/cat1b/psc3/psc3.dtsi +++ b/dts/arm/infineon/cat1b/psc3/psc3.dtsi @@ -1,9 +1,8 @@ /* - * copyright (c) (2016-2025), Cypress Semiconductor Corporation - * (an Infineon company) or an affiliate of Cypress Semiconductor Corporation. + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. * * SPDX-License-Identifier: Apache-2.0 - * */ #include diff --git a/dts/arm/infineon/cat1b/psc3/psc3_s.dtsi b/dts/arm/infineon/cat1b/psc3/psc3_s.dtsi index 1f104298899d..a0aa8336573d 100644 --- a/dts/arm/infineon/cat1b/psc3/psc3_s.dtsi +++ b/dts/arm/infineon/cat1b/psc3/psc3_s.dtsi @@ -1,9 +1,8 @@ /* - * copyright (c) (2016-2025), Cypress Semiconductor Corporation - * (an Infineon company) or an affiliate of Cypress Semiconductor Corporation. + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. * * SPDX-License-Identifier: Apache-2.0 - * */ #include diff --git a/dts/arm/infineon/edge/pse84/pse84.dtsi b/dts/arm/infineon/edge/pse84/pse84.dtsi index fb0980fdcba2..3f41755e1841 100644 --- a/dts/arm/infineon/edge/pse84/pse84.dtsi +++ b/dts/arm/infineon/edge/pse84/pse84.dtsi @@ -429,14 +429,14 @@ }; mcwdt0: mcwdt@4240d000 { - compatible = "infineon,lp-timer-pdl"; + compatible = "infineon,lp-timer"; reg = <0x4240d000 0x40>; interrupts = <55 4>; status = "disabled"; }; mcwdt1: mcwdt@4240d040 { - compatible = "infineon,lp-timer-pdl"; + compatible = "infineon,lp-timer"; reg = <0x4240d040 0x40>; interrupts = <0 4>; status = "disabled"; diff --git a/dts/arm/infineon/edge/pse84/pse84_s.dtsi b/dts/arm/infineon/edge/pse84/pse84_s.dtsi index 06096d5421a5..85e4a6b0029b 100644 --- a/dts/arm/infineon/edge/pse84/pse84_s.dtsi +++ b/dts/arm/infineon/edge/pse84/pse84_s.dtsi @@ -415,14 +415,14 @@ }; mcwdt0: mcwdt@5240d000 { - compatible = "infineon,lp-timer-pdl"; + compatible = "infineon,lp-timer"; reg = <0x5240d000 0x40>; interrupts = <55 4>; status = "disabled"; }; mcwdt1: mcwdt@5240d040 { - compatible = "infineon,lp-timer-pdl"; + compatible = "infineon,lp-timer"; reg = <0x5240d040 0x40>; interrupts = <0 4>; status = "disabled"; diff --git a/dts/bindings/timer/infineon,cat1-lp-timer-pdl.yaml b/dts/bindings/timer/infineon,cat1-lp-timer-pdl.yaml new file mode 100644 index 000000000000..1e5a968a6479 --- /dev/null +++ b/dts/bindings/timer/infineon,cat1-lp-timer-pdl.yaml @@ -0,0 +1,20 @@ +# Copyright (c) 2025 Infineon Technologies AG, +# or an affiliate of Infineon Technologies AG. +# +# SPDX-License-Identifier: Apache-2.0 + +description: Infineon CAT1 low power timer + +compatible: "infineon,cat1-lp-timer-pdl" + +include: [base.yaml, "infineon,system-interrupts.yaml"] + +properties: + reg: + required: true + + clock-frequency: + type: int + default: 32768 + description: | + Clock frequency (Hz) for tick increment operations diff --git a/dts/bindings/timer/infineon,lp-timer.yaml b/dts/bindings/timer/infineon,lp-timer.yaml index c0671ab22128..26f895093284 100644 --- a/dts/bindings/timer/infineon,lp-timer.yaml +++ b/dts/bindings/timer/infineon,lp-timer.yaml @@ -3,7 +3,7 @@ # # SPDX-License-Identifier: Apache-2.0 -description: Infineon Cat1 low power timer +description: Infineon low power timer compatible: "infineon,lp-timer" @@ -12,3 +12,9 @@ include: [base.yaml, "infineon,system-interrupts.yaml"] properties: reg: required: true + + clock-frequency: + type: int + default: 32768 + description: | + Clock frequency (Hz) for tick increment operations diff --git a/soc/infineon/edge/pse84/Kconfig.defconfig b/soc/infineon/edge/pse84/Kconfig.defconfig index b4c6e9141625..1dccc5c85419 100644 --- a/soc/infineon/edge/pse84/Kconfig.defconfig +++ b/soc/infineon/edge/pse84/Kconfig.defconfig @@ -8,7 +8,7 @@ if SOC_SERIES_PSE84 config CORTEX_M_SYSTICK - default y + default n if INFINEON_LP_TIMER_PDL choice NULL_POINTER_EXCEPTION_DETECTION default NULL_POINTER_EXCEPTION_DETECTION_NONE @@ -19,8 +19,12 @@ config NUM_IRQS default 174 if CPU_CORTEX_M55 config SYS_CLOCK_HW_CYCLES_PER_SEC - default $(dt_node_int_prop_int,/cpus/cpu@0,clock-frequency) if CPU_CORTEX_M33 - default $(dt_node_int_prop_int,/cpus/cpu@1,clock-frequency) if CPU_CORTEX_M55 + default $(dt_node_int_prop_int,/cpus/cpu@0,clock-frequency) if CPU_CORTEX_M33 && CORTEX_M_SYSTICK + default $(dt_node_int_prop_int,/cpus/cpu@1,clock-frequency) if CPU_CORTEX_M55 && CORTEX_M_SYSTICK + default $(dt_node_int_prop_int,/clk_pilo,clock-frequency) if USE_INFINEON_LPTIMER + +config SYS_CLOCK_TICKS_PER_SEC + default $(dt_node_int_prop_int,/clk_pilo,clock-frequency) if USE_INFINEON_LPTIMER config BUILD_OUTPUT_ADJUST_LMA depends on XIP diff --git a/soc/infineon/edge/pse84/security_config/pse84_boot.c b/soc/infineon/edge/pse84/security_config/pse84_boot.c index 5026fc25136a..d93021c29b3a 100644 --- a/soc/infineon/edge/pse84/security_config/pse84_boot.c +++ b/soc/infineon/edge/pse84/security_config/pse84_boot.c @@ -65,7 +65,9 @@ void ifx_pse84_cm55_startup(void) cy_ppc0_init(); cy_ppc1_init(); +#ifdef CONFIG_CORTEX_M_SYSTICK sys_clock_disable(); +#endif for (;;) { } From ce51e5881932ba82b864dcab486712628075a169 Mon Sep 17 00:00:00 2001 From: McAtee Maxwell Date: Fri, 19 Dec 2025 11:40:22 -0800 Subject: [PATCH 0720/3659] drivers: enable lp_timer default for kit_psc3m5_evk - Enable lp_timer for kit_psc3m5_evk - Modify configuration, enabling lp_timer as default before systick Signed-off-by: McAtee Maxwell --- .../clock_control_infineon_fixed_clock.c | 19 +++++++++++++++++++ drivers/timer/Kconfig.infineon_lp | 1 + .../infineon/cat1b/psc3/system_clocks.dtsi | 9 +++++++++ soc/infineon/cat1b/psc3/Kconfig | 1 - soc/infineon/cat1b/psc3/Kconfig.defconfig | 9 ++++++++- 5 files changed, 37 insertions(+), 2 deletions(-) diff --git a/drivers/clock_control/clock_control_infineon_fixed_clock.c b/drivers/clock_control/clock_control_infineon_fixed_clock.c index 90299aef146f..55e216ff1ba0 100644 --- a/drivers/clock_control/clock_control_infineon_fixed_clock.c +++ b/drivers/clock_control/clock_control_infineon_fixed_clock.c @@ -19,6 +19,7 @@ #include #include +#include #define DT_DRV_COMPAT infineon_fixed_clock @@ -46,6 +47,7 @@ static void clock_startup_error(uint32_t error) #endif #define CY_CFG_SYSCLK_PLL_ERROR 3 +#define CY_CFG_SYSCLK_WCO_ERROR 5 #if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(dpll_lp0)) || \ DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(dpll_lp1)) @@ -123,6 +125,17 @@ static void clk_dpll_hp_init(cy_stc_dpll_hp_config_t dpll_hp_config) } #endif +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(clk_wco)) +static void clk_wco_init(void) +{ + (void)Cy_GPIO_Pin_FastInit(GPIO_PRT0, 1U, 0x00U, 0x00U, HSIOM_SEL_GPIO); + (void)Cy_GPIO_Pin_FastInit(GPIO_PRT0, 0U, 0x00U, 0x00U, HSIOM_SEL_GPIO); + if (CY_SYSCLK_SUCCESS != Cy_SysClk_WcoEnable(1000000UL)) { + clock_startup_error(CY_CFG_SYSCLK_WCO_ERROR); + } +} +#endif + static int fixed_rate_clk_init(const struct device *dev) { const struct fixed_rate_clock_config *const config = dev->config; @@ -156,6 +169,12 @@ static int fixed_rate_clk_init(const struct device *dev) break; #endif +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(clk_wco)) + case IFX_WCO: + clk_wco_init(); + break; +#endif + #if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(dpll_lp0)) case IFX_DPLL250_0: #ifdef WA__DRIVERS_21925 diff --git a/drivers/timer/Kconfig.infineon_lp b/drivers/timer/Kconfig.infineon_lp index aff0a0ed4ea1..c09cb859f07f 100644 --- a/drivers/timer/Kconfig.infineon_lp +++ b/drivers/timer/Kconfig.infineon_lp @@ -10,6 +10,7 @@ config INFINEON_LP_TIMER_HAL default y depends on DT_HAS_INFINEON_LP_TIMER_ENABLED depends on USE_INFINEON_LEGACY_HAL + depends on PM select USE_INFINEON_LPTIMER select TICKLESS_CAPABLE help diff --git a/dts/arm/infineon/cat1b/psc3/system_clocks.dtsi b/dts/arm/infineon/cat1b/psc3/system_clocks.dtsi index 68796d637721..04894ffe9567 100644 --- a/dts/arm/infineon/cat1b/psc3/system_clocks.dtsi +++ b/dts/arm/infineon/cat1b/psc3/system_clocks.dtsi @@ -40,6 +40,15 @@ status = "okay"; }; + /* wco */ + clk_wco: clk_wco { + #clock-cells = <0>; + compatible = "infineon,fixed-clock"; + clock-frequency = <32768>; + system-clock = ; + status = "okay"; + }; + /* fll */ fll0: fll0 { #clock-cells = <0>; diff --git a/soc/infineon/cat1b/psc3/Kconfig b/soc/infineon/cat1b/psc3/Kconfig index 028629bc2cca..8ca1975b8e21 100644 --- a/soc/infineon/cat1b/psc3/Kconfig +++ b/soc/infineon/cat1b/psc3/Kconfig @@ -29,4 +29,3 @@ config SOC_SERIES_PSC3 select SOC_EARLY_INIT_HOOK select CPU_CORTEX_M33 select NOINIT_SNIPPET_FIRST - select CORTEX_M_SYSTICK diff --git a/soc/infineon/cat1b/psc3/Kconfig.defconfig b/soc/infineon/cat1b/psc3/Kconfig.defconfig index ef796085a5a0..c91d28b7eff3 100644 --- a/soc/infineon/cat1b/psc3/Kconfig.defconfig +++ b/soc/infineon/cat1b/psc3/Kconfig.defconfig @@ -19,11 +19,18 @@ if SOC_SERIES_PSC3 +config CORTEX_M_SYSTICK + default n if INFINEON_LP_TIMER_PDL + config NUM_IRQS default 140 config SYS_CLOCK_HW_CYCLES_PER_SEC - default $(dt_node_int_prop_int,/cpus/cpu@0,clock-frequency) + default $(dt_node_int_prop_int,/cpus/cpu@0,clock-frequency) if CORTEX_M_SYSTICK + default $(dt_node_int_prop_int,/clocks/clk_wco,clock-frequency) if USE_INFINEON_LPTIMER + +config SYS_CLOCK_TICKS_PER_SEC + default $(dt_node_int_prop_int,/clocks/clk_wco,clock-frequency) if USE_INFINEON_LPTIMER # add additional die specific params From da1df411a5a002d1b36ba90fc8a357c8bf79d9de Mon Sep 17 00:00:00 2001 From: Jason Yu Date: Mon, 1 Dec 2025 11:26:25 +0800 Subject: [PATCH 0721/3659] soc: nxp: mcxw2xx: Enable the power management Enabled modes: idle: SLEEP suspend: DEEP-SLEEP standby: POWER-DOWN with CPU retention OS Time Base: OSTIMER with 32K clock source Signed-off-by: Jason Yu --- dts/arm/nxp/nxp_mcxw23x_common.dtsi | 51 +++++ soc/nxp/mcx/mcxw/mcxw2xx/Kconfig.defconfig | 43 ++++- soc/nxp/mcx/mcxw/mcxw2xx/power.c | 207 ++++++++++++++++++++- soc/nxp/mcx/mcxw/mcxw2xx/soc.c | 20 +- 4 files changed, 313 insertions(+), 8 deletions(-) diff --git a/dts/arm/nxp/nxp_mcxw23x_common.dtsi b/dts/arm/nxp/nxp_mcxw23x_common.dtsi index 1a32a00672a6..8604526bec49 100644 --- a/dts/arm/nxp/nxp_mcxw23x_common.dtsi +++ b/dts/arm/nxp/nxp_mcxw23x_common.dtsi @@ -32,12 +32,47 @@ reg = <0>; #address-cells = <1>; #size-cells = <1>; + cpu-power-states = <&idle &suspend &standby>; mpu: mpu@e000ed90 { compatible = "arm,armv8m-mpu"; reg = <0xe000ed90 0x40>; }; }; + + power-states { + /* Idle mode maps to Sleep mode. */ + idle: idle { + compatible = "zephyr,power-state"; + power-state-name = "runtime-idle"; + min-residency-us = <60>; + exit-latency-us = <16>; + zephyr,pm-device-disabled; + }; + + /* Suspend mode maps to Deep Sleep mode. */ + suspend: suspend { + compatible = "zephyr,power-state"; + power-state-name = "suspend-to-idle"; + min-residency-us = <1300>; + exit-latency-us = <749>; + }; + + /* Standby mode maps to Power Down mode with CPU retention . */ + standby: standby { + compatible = "zephyr,power-state"; + power-state-name = "standby"; + min-residency-us = <2000>; + exit-latency-us = <1345>; + }; + }; + }; + + /* For the resource which will be off and lose content. */ + standby_off_domain: standby-off-domain { + compatible = "power-domain-soc-state-change"; + #power-domain-cells = <0>; + onoff-power-states = <&standby>; }; sysclk: system-clock { @@ -175,6 +210,7 @@ mode = <0>; input = <0>; prescale = <0>; + zephyr,disabling-power-states = <&suspend &standby>; }; ctimer1: ctimer@9000 { @@ -187,6 +223,7 @@ mode = <0>; input = <0>; prescale = <0>; + zephyr,disabling-power-states = <&suspend &standby>; }; ctimer2: ctimer@28000 { @@ -199,6 +236,7 @@ mode = <0>; input = <0>; prescale = <0>; + zephyr,disabling-power-states = <&suspend &standby>; }; ctimer3: ctimer@29000 { @@ -211,6 +249,7 @@ mode = <0>; input = <0>; prescale = <0>; + zephyr,disabling-power-states = <&suspend &standby>; }; ctimer4: ctimer@2a000 { @@ -223,6 +262,7 @@ mode = <0>; input = <0>; prescale = <0>; + zephyr,disabling-power-states = <&suspend &standby>; }; sc_timer: pwm@85000 { @@ -232,6 +272,7 @@ status = "disabled"; clocks = <&syscon MCUX_SCTIMER_CLK>; prescaler = <2>; + zephyr,disabling-power-states = <&suspend &standby>; #pwm-cells = <3>; }; @@ -251,6 +292,7 @@ resets = <&reset NXP_SYSCON_RESET(1, 11)>; dmas = <&dma0 4 &dma0 5>; dma-names = "rx", "tx"; + zephyr,disabling-power-states = <&suspend &standby>; status = "disabled"; }; @@ -262,6 +304,8 @@ resets = <&reset NXP_SYSCON_RESET(1, 12)>; dmas = <&dma0 6 &dma0 7>; dma-names = "rx", "tx"; + zephyr,disabling-power-states = <&suspend &standby>; + power-domains = <&standby_off_domain>; status = "disabled"; }; @@ -273,6 +317,8 @@ resets = <&reset NXP_SYSCON_RESET(1, 13)>; dmas = <&dma0 8 &dma0 9>; dma-names = "rx", "tx"; + zephyr,disabling-power-states = <&suspend &standby>; + power-domains = <&standby_off_domain>; status = "disabled"; }; @@ -288,6 +334,8 @@ reg = <0x82000 0x1000>; interrupts = <1 1>; dma-channels = <23>; + zephyr,disabling-power-states = <&suspend &standby>; + power-domains = <&standby_off_domain>; status = "disabled"; #dma-cells = <1>; }; @@ -297,6 +345,8 @@ reg = <0xa7000 0x1000>; interrupts = <58 1>; dma-channels = <10>; + zephyr,disabling-power-states = <&suspend &standby>; + power-domains = <&standby_off_domain>; status = "disabled"; #dma-cells = <1>; }; @@ -329,6 +379,7 @@ resets = <&reset NXP_SYSCON_RESET(1, 0)>; #address-cells = <1>; #size-cells = <0>; + zephyr,disabling-power-states = <&suspend &standby>; mrt0_channel0: mrt0_channel@0 { compatible = "nxp,mrt-channel"; diff --git a/soc/nxp/mcx/mcxw/mcxw2xx/Kconfig.defconfig b/soc/nxp/mcx/mcxw/mcxw2xx/Kconfig.defconfig index 992335c7044d..f40676e5ae64 100644 --- a/soc/nxp/mcx/mcxw/mcxw2xx/Kconfig.defconfig +++ b/soc/nxp/mcx/mcxw/mcxw2xx/Kconfig.defconfig @@ -8,7 +8,8 @@ if SOC_SERIES_MCXW2XX # In case we need to switch to OS timer, then # define CONFIG_MCUX_OS_TIMER=y configdefault MCUX_OS_TIMER - default n + default y if PM + default n if !PM config CORTEX_M_SYSTICK default n if MCUX_OS_TIMER @@ -18,10 +19,15 @@ config NUM_IRQS DT_SYSCLK_PATH := $(dt_nodelabel_path,sysclk) -config SYS_CLOCK_HW_CYCLES_PER_SEC - default 1000000 if MCUX_OS_TIMER +configdefault SYS_CLOCK_HW_CYCLES_PER_SEC + default 32768 if MCUX_OS_TIMER && PM + default 1000000 if MCUX_OS_TIMER && !PM default $(dt_node_int_prop_int,$(DT_SYSCLK_PATH),clock-frequency) if CORTEX_M_SYSTICK +configdefault SYS_CLOCK_TICKS_PER_SEC + default 1024 if MCUX_OS_TIMER && PM + default 1000 if MCUX_OS_TIMER && !PM + # Set to the minimal size of data which can be written. config FLASH_FILL_BUFFER_SIZE default 512 @@ -45,4 +51,35 @@ config SYSTEM_WORKQUEUE_STACK_SIZE endif # BT +if PM + +# Enable PM_DEVICE for Suspend mode and Standby mode, +# because some devices can't work in these modes. +configdefault PM_DEVICE + default y if "$(dt_nodelabel_enabled,standby)" || "$(dt_nodelabel_enabled,suspend)" + +configdefault PM_POLICY_DEVICE_CONSTRAINTS + default y if PM_DEVICE + +configdefault IDLE_STACK_SIZE + default 640 + +configdefault TICKLESS_KERNEL + default y + +if BT +choice PM_POLICY + default PM_POLICY_CUSTOM +endchoice +endif # BT + +endif # PM + +if PM_DEVICE + +configdefault POWER_DOMAIN + default y + +endif # PM_DEVICE + endif # SOC_SERIES_MCXW2XX diff --git a/soc/nxp/mcx/mcxw/mcxw2xx/power.c b/soc/nxp/mcx/mcxw/mcxw2xx/power.c index 9c92e8275e32..2f178b3bf6b3 100644 --- a/soc/nxp/mcx/mcxw/mcxw2xx/power.c +++ b/soc/nxp/mcx/mcxw/mcxw2xx/power.c @@ -5,24 +5,223 @@ */ #include +#include #include +#include +#include +#include +#include -void pm_state_set(enum pm_state state, uint8_t id) +#if CONFIG_PM_POLICY_CUSTOM +#include +#endif /* CONFIG_PM_POLICY_CUSTOM */ + +#ifdef CONFIG_BT +#include "ll_intf.h" +#endif /* CONFIG_BT */ + +LOG_MODULE_DECLARE(soc, CONFIG_SOC_LOG_LEVEL); + +/* Wakeup pin. */ +#if CONFIG_GPIO && DT_NODE_EXISTS(DT_NODELABEL(btn_wk)) +#define WAKEUP_PIN_ENABLE 1 +#else +#define WAKEUP_PIN_ENABLE 0 +#endif + +#if WAKEUP_PIN_ENABLE +#define WAKEUP_BUTTON_NODE DT_NODELABEL(btn_wk) +static const struct gpio_dt_spec wakeup_pin_dt = GPIO_DT_SPEC_GET(WAKEUP_BUTTON_NODE, gpios); +#endif /* WAKEUP_PIN_ENABLE */ + +#if defined(CONFIG_BT) && !defined(CONFIG_PM_POLICY_CUSTOM) +#error Select CONFIG_PM_POLICY_CUSTOM when CONFIG_BT is selected +#endif + +#if CONFIG_PM_POLICY_CUSTOM +__weak const struct pm_state_info *pm_policy_next_state(uint8_t cpu, int32_t ticks) +{ + uint8_t num_cpu_states; + const struct pm_state_info *cpu_states; + const struct pm_state_info *out_state = NULL; + +#ifdef CONFIG_PM_NEED_ALL_DEVICES_IDLE + if (pm_device_is_any_busy()) { + return NULL; + } +#endif + +#ifdef CONFIG_BT + if (bt_is_ready()) { + uint32_t remaining_time; + ble_stat_t stat; + + stat = BLEController_GetRemainingTimeForNextEventUnsafe(&remaining_time); + /* Is link layer busy? */ + if ((stat != SUCCESS) || (remaining_time == 0)) { + return NULL; + } + /* Any future activity? */ + if (remaining_time < 0xffffffff) { + ticks = MIN(ticks, k_us_to_ticks_floor32(remaining_time)); + } + } +#endif /* CONFIG_BT */ + + num_cpu_states = pm_state_cpu_get_all(cpu, &cpu_states); + + for (uint32_t i = 0; i < num_cpu_states; i++) { + const struct pm_state_info *state = &cpu_states[i]; + uint32_t min_residency_ticks = 0; + uint32_t min_residency_us = state->min_residency_us + state->exit_latency_us; + + /* If the input is zero, avoid 64-bit conversion from microseconds to ticks. */ + if (min_residency_us > 0) { + min_residency_ticks = k_us_to_ticks_ceil32(min_residency_us); + } + + if (ticks < min_residency_ticks) { + /* If current state has higher residency then use the previous state; */ + break; + } + + /* check if state is available. */ + if (!pm_policy_state_is_available(state->state, state->substate_id)) { + continue; + } + + out_state = state; + } + + return out_state; +} +#endif /* CONFIG_PM_POLICY_CUSTOM */ + +static void pm_get_lowpower_resource_list(uint32_t *exclude_from_pd, + uint64_t *wakeup_sources, + bool is_standby) +{ + *exclude_from_pd = kLOWPOWERCFG_DCDC_BYPASS; + *wakeup_sources = 0; + +#ifdef CONFIG_BT + /* BT needs 32kHz clock. */ + *exclude_from_pd |= (kLOWPOWERCFG_XTAL32K | kLOWPOWERCFG_BLE_WUP); +#endif + +#ifdef CONFIG_MCUX_OS_TIMER + /* OS_TIMER uses 32K clock as clock source, keep it running. */ + *exclude_from_pd |= kLOWPOWERCFG_XTAL32K; + *wakeup_sources |= kWAKEUP_OS_EVENT; +#endif + +#if WAKEUP_PIN_ENABLE + static const wakeup_irq_t pint_wakeup_sources[] = { + kWAKEUP_PIN_INT0, + kWAKEUP_PIN_INT1, + kWAKEUP_PIN_INT2, + kWAKEUP_PIN_INT3, + kWAKEUP_PIN_INT4, + kWAKEUP_PIN_INT5, + kWAKEUP_PIN_INT6, + kWAKEUP_PIN_INT7 + }; + + /* PINT doesn't work in standby mode. */ + if (!is_standby) { + int slot = nxp_pint_pin_get_slot_index(wakeup_pin_dt.pin); + + if (slot >= 0 && slot < ARRAY_SIZE(pint_wakeup_sources)) { + *wakeup_sources |= pint_wakeup_sources[slot]; + } + } +#endif +} + +__weak void pm_state_set(enum pm_state state, uint8_t id) { ARG_UNUSED(id); + uint32_t exclude_from_pd; + uint64_t wakeup_sources; + status_t status; + + /* Set PRIMASK */ + __disable_irq(); + /* Set BASEPRI to 0 */ + irq_unlock(0); switch (state) { case PM_STATE_RUNTIME_IDLE: - k_cpu_idle(); + POWER_EnterSleep(); + break; + + case PM_STATE_SUSPEND_TO_IDLE: + pm_get_lowpower_resource_list(&exclude_from_pd, &wakeup_sources, false); + status = POWER_EnterDeepSleep(exclude_from_pd, wakeup_sources); + if (status != kStatus_Success) { + LOG_ERR("Failed to enter deep sleep mode: %d", status); + } break; - default: + case PM_STATE_STANDBY: + pm_get_lowpower_resource_list(&exclude_from_pd, &wakeup_sources, true); + status = POWER_EnterPowerDown(exclude_from_pd, wakeup_sources, 1); + if (status != kStatus_Success) { + LOG_ERR("Failed to enter power down mode: %d", status); + } + break; + + default: + LOG_DBG("Unsupported power state %u", state); break; } } -void pm_state_exit_post_ops(enum pm_state state, uint8_t id) +__weak void pm_state_exit_post_ops(enum pm_state state, uint8_t id) { ARG_UNUSED(state); ARG_UNUSED(id); + + /* Clear PRIMASK */ + __enable_irq(); +} + +#if WAKEUP_PIN_ENABLE +static void init_wakeup_gpio_pins(void) +{ + int ret; + + if (!device_is_ready(wakeup_pin_dt.port)) { + LOG_ERR("Wake-up GPIO device not ready"); + return; + } + + ret = gpio_pin_configure_dt(&wakeup_pin_dt, GPIO_INPUT); + if (ret != 0) { + LOG_ERR("Error %d: failed to configure wakeup pin\n", ret); + return; + } + + ret = gpio_pin_interrupt_configure_dt(&wakeup_pin_dt, GPIO_INT_EDGE_TO_ACTIVE); + if (ret != 0) { + LOG_ERR("Error %d: failed to configure wakeup pin interrupt\n", ret); + return; + } +} +#endif + +static int nxp_mcxw2xx_power_init(void) +{ +#if WAKEUP_PIN_ENABLE + init_wakeup_gpio_pins(); +#endif /* WAKEUP_PIN_ENABLE */ + + return 0; } + +void nxp_mcxw2xx_power_early_init(void) +{ + POWER_Init(); +} + +SYS_INIT(nxp_mcxw2xx_power_init, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); diff --git a/soc/nxp/mcx/mcxw/mcxw2xx/soc.c b/soc/nxp/mcx/mcxw/mcxw2xx/soc.c index e561ca8d7e78..6b35ab5dbb8b 100644 --- a/soc/nxp/mcx/mcxw/mcxw2xx/soc.c +++ b/soc/nxp/mcx/mcxw/mcxw2xx/soc.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -28,10 +29,16 @@ #include #endif +LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); + /* System clock frequency */ extern uint32_t SystemCoreClock; extern void nxp_nbu_init(void); +#if CONFIG_PM +void nxp_mcxw2xx_power_early_init(void); +#endif /* CONFIG_PM */ + #define CTIMER_CLOCK_SOURCE(node_id) \ TO_CTIMER_CLOCK_SOURCE(DT_CLOCKS_CELL(node_id, name), DT_PROP(node_id, clk_source)) #define TO_CTIMER_CLOCK_SOURCE(inst, val) TO_CLOCK_ATTACH_ID(inst, val) @@ -98,10 +105,17 @@ __weak void clock_init(void) configure_32k_osc(); #if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(os_timer), nxp_os_timer, okay) - /*!< OS event timer select FRO 1 MHz clock */ + /* + * OS event timer generally uses FRO 1 MHz clock. + * When power management is enabled, uses 32K clock for lower power. + */ PMC->OSTIMERr &= ~PMC_OSTIMER_OSTIMERCLKSEL_MASK; +#if CONFIG_PM + PMC->OSTIMERr |= OSTIMERCLKSEL_32768 << PMC_OSTIMER_OSTIMERCLKSEL_SHIFT; +#else PMC->OSTIMERr |= OSTIMERCLKSEL_FRO_1MHz << PMC_OSTIMER_OSTIMERCLKSEL_SHIFT; #endif +#endif #if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(iap), nxp_iap_fmc55, okay) /* kCLOCK_Sysctl must be enabled for FLASH_CacheClear, @@ -132,6 +146,10 @@ void soc_early_init_hook(void) { z_arm_clear_faults(); +#if CONFIG_PM + nxp_mcxw2xx_power_early_init(); +#endif /* CONFIG_PM */ + /* Initialize FRO/system clock to 96 MHz */ clock_init(); From dad7f6ae959d6ce37f12f746a856ea97b6d3f01f Mon Sep 17 00:00:00 2001 From: Jason Yu Date: Mon, 17 Nov 2025 16:20:34 +0800 Subject: [PATCH 0722/3659] soc: nxp: mcxw2xx: Add poweroff support Add poweroff MCXW2xx SoCs, support btn_wk pin wakeup. Signed-off-by: Jason Yu --- soc/nxp/mcx/mcxw/mcxw2xx/CMakeLists.txt | 2 ++ soc/nxp/mcx/mcxw/mcxw2xx/Kconfig | 3 +++ soc/nxp/mcx/mcxw/mcxw2xx/poweroff.c | 34 +++++++++++++++++++++++++ 3 files changed, 39 insertions(+) create mode 100644 soc/nxp/mcx/mcxw/mcxw2xx/poweroff.c diff --git a/soc/nxp/mcx/mcxw/mcxw2xx/CMakeLists.txt b/soc/nxp/mcx/mcxw/mcxw2xx/CMakeLists.txt index 6b55a6def056..1ad3b988cf4c 100644 --- a/soc/nxp/mcx/mcxw/mcxw2xx/CMakeLists.txt +++ b/soc/nxp/mcx/mcxw/mcxw2xx/CMakeLists.txt @@ -6,6 +6,8 @@ zephyr_sources(soc.c) zephyr_sources_ifdef(CONFIG_PM power.c) +zephyr_sources_ifdef(CONFIG_POWEROFF poweroff.c) + zephyr_include_directories(./) set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld CACHE INTERNAL "") diff --git a/soc/nxp/mcx/mcxw/mcxw2xx/Kconfig b/soc/nxp/mcx/mcxw/mcxw2xx/Kconfig index 7172ccebf93b..210dbc43eb2e 100644 --- a/soc/nxp/mcx/mcxw/mcxw2xx/Kconfig +++ b/soc/nxp/mcx/mcxw/mcxw2xx/Kconfig @@ -1,3 +1,6 @@ # Copyright 2025 NXP # # SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_MCXW2XX + select HAS_POWEROFF diff --git a/soc/nxp/mcx/mcxw/mcxw2xx/poweroff.c b/soc/nxp/mcx/mcxw/mcxw2xx/poweroff.c new file mode 100644 index 000000000000..31e250d26277 --- /dev/null +++ b/soc/nxp/mcx/mcxw/mcxw2xx/poweroff.c @@ -0,0 +1,34 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +#if CONFIG_GPIO && DT_NODE_EXISTS(DT_NODELABEL(btn_wk)) + +#if (DT_GPIO_FLAGS(DT_NODELABEL(btn_wk), gpios)) & GPIO_ACTIVE_LOW +#define POWEROFF_WAKEUP (kWAKEUP_PIN_ENABLE | \ + kWAKEUP_PIN_PUP_EN | \ + kWAKEUP_PIN_WAKEUP_LOW_LVL) +#else /* !GPIO_ACTIVE_LOW */ +#define POWEROFF_WAKEUP (kWAKEUP_PIN_ENABLE | \ + kWAKEUP_PIN_PDN_EN | \ + kWAKEUP_PIN_WAKEUP_HIGH_LVL) +#endif /* GPIO_ACTIVE_LOW */ + +#else +#define POWEROFF_WAKEUP kWAKEUP_PIN_DISABLE +#endif /* CONFIG_GPIO && DT_NODE_EXISTS(DT_NODELABEL(btn_wk)) */ + +void z_sys_poweroff(void) +{ + POWER_EnterPowerOff(0, POWEROFF_WAKEUP); + + CODE_UNREACHABLE; +} From 5194dfa38036215a0c4c7d58bc4479e8f0d3490a Mon Sep 17 00:00:00 2001 From: Jason Yu Date: Fri, 7 Nov 2025 10:46:18 +0800 Subject: [PATCH 0723/3659] boards: nxp: mcxw23: Add power management MCXW23 board Add mcxw23_evk and frdm_mcxw23 platforms to the power management test suite to validate power management functionality on MCXW23 hardware. Signed-off-by: Jason Yu --- boards/nxp/frdm_mcxw23/doc/index.rst | 8 ++++++++ boards/nxp/mcxw23_evk/doc/index.rst | 8 ++++++++ tests/subsys/pm/power_mgmt_soc/testcase.yaml | 2 ++ 3 files changed, 18 insertions(+) diff --git a/boards/nxp/frdm_mcxw23/doc/index.rst b/boards/nxp/frdm_mcxw23/doc/index.rst index eaf5ed522c2d..dfb4e6fa5655 100644 --- a/boards/nxp/frdm_mcxw23/doc/index.rst +++ b/boards/nxp/frdm_mcxw23/doc/index.rst @@ -198,6 +198,14 @@ should see the following message in the terminal: *** Booting Zephyr OS build v4.2.0-2105-g48f2ffda26de *** Hello World! frdm_mcxw23/mcxw236 +Power Management +================ + +When Power Management is enabled :kconfig:option:`CONFIG_PM`, OSTIMER is used as +OS tick timer. + +Limitation: Wakeup pin can't be used as wakeup source in Standby mode. + .. include:: ../../common/board-footer.rst.inc .. _MCXW23 SoC Website: diff --git a/boards/nxp/mcxw23_evk/doc/index.rst b/boards/nxp/mcxw23_evk/doc/index.rst index 866dc06715f6..49285337fe9b 100644 --- a/boards/nxp/mcxw23_evk/doc/index.rst +++ b/boards/nxp/mcxw23_evk/doc/index.rst @@ -180,6 +180,14 @@ should see the following message in the terminal: *** Booting Zephyr OS build v4.2.0-2105-g9da1d56da9e7 *** Hello World! mcxw23_evk/mcxw236 +Power Management +================ + +When Power Management is enabled :kconfig:option:`CONFIG_PM`, OSTIMER is used as +OS tick timer. + +Limitation: Wakeup pin can't be used as wakeup source in Standby mode. + .. include:: ../../common/board-footer.rst.inc .. _MCXW23 SoC Website: diff --git a/tests/subsys/pm/power_mgmt_soc/testcase.yaml b/tests/subsys/pm/power_mgmt_soc/testcase.yaml index 731835841516..7e0bc1dc345b 100644 --- a/tests/subsys/pm/power_mgmt_soc/testcase.yaml +++ b/tests/subsys/pm/power_mgmt_soc/testcase.yaml @@ -30,6 +30,8 @@ tests: - ek_ra8d2/r7ka8d2kflcac/cm85 - ek_ra8m2/r7ka8m2jflcac/cm85 - frdm_mcxn236 + - mcxw23_evk + - frdm_mcxw23 tags: pm integration_platforms: - mec15xxevb_assy6853 From 98ef5b1c44d3825ea8b9ecaeb8a505ce8ea19364 Mon Sep 17 00:00:00 2001 From: Pieter De Gendt Date: Thu, 11 Dec 2025 13:54:38 +0100 Subject: [PATCH 0724/3659] REUSE.toml: Default annotate json files It's not possible to add comments to a json file, so there's no option to add license or copyright text. Signed-off-by: Pieter De Gendt --- REUSE.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/REUSE.toml b/REUSE.toml index 6ff874b060d8..83f6d8fed7dd 100644 --- a/REUSE.toml +++ b/REUSE.toml @@ -1,6 +1,6 @@ version = 1 -# Declare default license and copyright text for files that typically do not include them. +# Declare default license and copyright text for files that typically do not or cannot include them. [[annotations]] path = [ # zephyr-keep-sorted-start @@ -9,6 +9,7 @@ path = [ "**/*.conf", "**/*.ecl", "**/*.html", + "**/*.json", "**/*.rst", "**/*.yaml", "**/*.yml", From 1a31990457feb95401d95eb2b5a1337536c343cb Mon Sep 17 00:00:00 2001 From: Nikhil Namjoshi Date: Fri, 12 Dec 2025 22:35:36 +0000 Subject: [PATCH 0725/3659] drivers: memc: Add imx-flexspi-is66wvs8m8 driver Tested: Verified that reading and writing data to the PSRAM with MCU's FlexSPI controller in Quad Mode, works as expected. Signed-off-by: Nikhil Namjoshi --- drivers/memc/CMakeLists.txt | 1 + drivers/memc/Kconfig.mcux | 6 + drivers/memc/memc_mcux_flexspi_is66wvs8m8.c | 172 ++++++++++++++++++ .../mtd/nxp,imx-flexspi-is66wvs8m8.yaml | 8 + 4 files changed, 187 insertions(+) create mode 100644 drivers/memc/memc_mcux_flexspi_is66wvs8m8.c create mode 100644 dts/bindings/mtd/nxp,imx-flexspi-is66wvs8m8.yaml diff --git a/drivers/memc/CMakeLists.txt b/drivers/memc/CMakeLists.txt index b3f94d8df4f8..0229e5d74962 100644 --- a/drivers/memc/CMakeLists.txt +++ b/drivers/memc/CMakeLists.txt @@ -21,6 +21,7 @@ zephyr_library_sources_ifdef(CONFIG_MEMC_MCUX_FLEXSPI memc_mcux_flexspi.c) zephyr_library_sources_ifdef(CONFIG_MEMC_MCUX_FLEXSPI_APS6404L memc_mcux_flexspi_aps6404l.c) zephyr_library_sources_ifdef(CONFIG_MEMC_MCUX_FLEXSPI_APS6408L memc_mcux_flexspi_aps6408l.c) zephyr_library_sources_ifdef(CONFIG_MEMC_MCUX_FLEXSPI_IS66WVQ8M4 memc_mcux_flexspi_is66wvq8m4.c) +zephyr_library_sources_ifdef(CONFIG_MEMC_MCUX_FLEXSPI_IS66WVS8M8 memc_mcux_flexspi_is66wvs8m8.c) zephyr_library_sources_ifdef(CONFIG_MEMC_MCUX_FLEXSPI_S27KS0641 memc_mcux_flexspi_s27ks0641.c) zephyr_library_sources_ifdef(CONFIG_MEMC_MCUX_FLEXSPI_W956A8MBYA memc_mcux_flexspi_w956a8mbya.c) zephyr_library_sources_ifdef(CONFIG_MEMC_MCUX_XSPI memc_mcux_xspi.c) diff --git a/drivers/memc/Kconfig.mcux b/drivers/memc/Kconfig.mcux index b62f4d815c92..71107b56e3a9 100644 --- a/drivers/memc/Kconfig.mcux +++ b/drivers/memc/Kconfig.mcux @@ -30,6 +30,12 @@ config MEMC_MCUX_FLEXSPI_IS66WVQ8M4 depends on DT_HAS_NXP_IMX_FLEXSPI_IS66WVQ8M4_ENABLED select MEMC_MCUX_FLEXSPI +config MEMC_MCUX_FLEXSPI_IS66WVS8M8 + bool "MCUX FlexSPI ISSI IS66WVS8M8 pSRAM driver" + default y + depends on DT_HAS_NXP_IMX_FLEXSPI_IS66WVS8M8_ENABLED + select MEMC_MCUX_FLEXSPI + config MEMC_MCUX_FLEXSPI_APS6404L bool "MCUX FlexSPI AP Memory APS6404L pSRAM driver" default y diff --git a/drivers/memc/memc_mcux_flexspi_is66wvs8m8.c b/drivers/memc/memc_mcux_flexspi_is66wvs8m8.c new file mode 100644 index 000000000000..9918fa45eaf6 --- /dev/null +++ b/drivers/memc/memc_mcux_flexspi_is66wvs8m8.c @@ -0,0 +1,172 @@ +/* + * Copyright 2023 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT nxp_imx_flexspi_is66wvs8m8 + +#include +#include +#include + +#include "memc_mcux_flexspi.h" + +LOG_MODULE_REGISTER(memc_flexspi_is66wvs8m8, CONFIG_MEMC_LOG_LEVEL); + +/* Vendor ID for ISSI device */ +#define ISSI_VENDOR_ID 0x9D + +enum { + READ_DATA = 0, + WRITE_DATA, + READ_ID, + DPD_ENTRY, + SET_BURST_LENGTH, +}; + +struct memc_flexspi_is66wvs8m8_config { + flexspi_port_t port; + flexspi_device_config_t config; +}; + +/* Device variables used in critical sections should be in this structure */ +struct memc_flexspi_is66wvs8m8_data { + const struct device *controller; +}; + +/* is66wvs8m8 configuration register constants */ +#define is66wvs8m8_LATENCY_MASK BIT(3) +#define is66wvs8m8_LATENCY_FIXED BIT(3) + +static const uint32_t memc_flexspi_is66wvs8m8_lut[][4] = { + /* Read Data (Quad IO read) */ + [READ_DATA] = { + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0xEB, + kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_4PAD, 24), + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DUMMY_SDR, kFLEXSPI_4PAD, 6, + kFLEXSPI_Command_READ_SDR, kFLEXSPI_4PAD, 0x0), + }, + /* Write Data (Quad IO Write) */ + [WRITE_DATA] = { + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x38, + kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_4PAD, 24), + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_WRITE_SDR, kFLEXSPI_4PAD, 0x0, + kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0x00), + }, + /* Read Identification register */ + [READ_ID] = { + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x9F, + kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 24), + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x00, + kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0x00), + }, + [DPD_ENTRY] = { + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0xB9, + kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0x00), + }, + [SET_BURST_LENGTH] = { + FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0xC0, + kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0x00), + }, +}; + +/* Read vendor ID from identification register */ +static int memc_flexspi_is66wvs8m8_get_vendor_id(const struct device *dev, uint8_t *vendor_id) +{ + const struct memc_flexspi_is66wvs8m8_config *config = dev->config; + struct memc_flexspi_is66wvs8m8_data *data = dev->data; + uint8_t buffer[8] = {0}; + int ret; + + flexspi_transfer_t transfer = { + .deviceAddress = 0x00, /* Not used by this command */ + .port = config->port, + .cmdType = kFLEXSPI_Read, + .seqIndex = READ_ID, + .SeqNumber = 1, + .data = (uint32_t *)&buffer, + .dataSize = 8, + }; + + ret = memc_flexspi_transfer(data->controller, &transfer); + + *vendor_id = buffer[0]; + + return ret; +} + +static int memc_flexspi_is66wvs8m8_init(const struct device *dev) +{ + const struct memc_flexspi_is66wvs8m8_config *config = dev->config; + struct memc_flexspi_is66wvs8m8_data *data = dev->data; + uint8_t vendor_id; + + if (!device_is_ready(data->controller)) { + LOG_ERR("Controller device not ready"); + return -ENODEV; + } + + if (memc_flexspi_set_device_config( + data->controller, &config->config, + (const uint32_t *)memc_flexspi_is66wvs8m8_lut, + sizeof(memc_flexspi_is66wvs8m8_lut) / MEMC_FLEXSPI_CMD_SIZE, config->port)) { + LOG_ERR("Could not set device configuration"); + return -EINVAL; + } + + if (memc_flexspi_is66wvs8m8_get_vendor_id(dev, &vendor_id)) { + LOG_ERR("Could not read vendor id"); + return -EIO; + } + + if (vendor_id != ISSI_VENDOR_ID) { + LOG_WRN("Vendor ID does not match expected value of 0x%0x", ISSI_VENDOR_ID); + } + + return 0; +} + +#define CONCAT3(x, y, z) x##y##z + +#define CS_INTERVAL_UNIT(unit) CONCAT3(kFLEXSPI_CsIntervalUnit, unit, SckCycle) + +#define AHB_WRITE_WAIT_UNIT(unit) CONCAT3(kFLEXSPI_AhbWriteWaitUnit, unit, AhbCycle) + +#define MEMC_FLEXSPI_DEVICE_CONFIG(n) \ + { \ + .flexspiRootClk = DT_INST_PROP(n, spi_max_frequency), \ + .isSck2Enabled = false, \ + .flashSize = DT_INST_PROP(n, size) / 8 / KB(1), \ + .CSIntervalUnit = CS_INTERVAL_UNIT(DT_INST_PROP(n, cs_interval_unit)), \ + .CSInterval = DT_INST_PROP(n, cs_interval), \ + .CSHoldTime = DT_INST_PROP(n, cs_hold_time), \ + .CSSetupTime = DT_INST_PROP(n, cs_setup_time), \ + .dataValidTime = DT_INST_PROP(n, data_valid_time), \ + .columnspace = DT_INST_PROP(n, column_space), \ + .enableWordAddress = DT_INST_PROP(n, word_addressable), \ + .AWRSeqIndex = WRITE_DATA, \ + .AWRSeqNumber = 1, \ + .ARDSeqIndex = READ_DATA, \ + .ARDSeqNumber = 1, \ + .AHBWriteWaitUnit = AHB_WRITE_WAIT_UNIT(DT_INST_PROP(n, ahb_write_wait_unit)), \ + .AHBWriteWaitInterval = DT_INST_PROP(n, ahb_write_wait_interval), \ + .enableWriteMask = false, \ + } + +#define MEMC_FLEXSPI_ISS66VWS8M8(n) \ + static const struct memc_flexspi_is66wvs8m8_config memc_flexspi_is66wvs8m8_config_##n = { \ + .port = DT_INST_REG_ADDR(n), \ + .config = MEMC_FLEXSPI_DEVICE_CONFIG(n), \ + }; \ + \ + static struct memc_flexspi_is66wvs8m8_data memc_flexspi_is66wvs8m8_data_##n = { \ + .controller = DEVICE_DT_GET(DT_INST_BUS(n)), \ + }; \ + \ + DEVICE_DT_INST_DEFINE(n, memc_flexspi_is66wvs8m8_init, NULL, \ + &memc_flexspi_is66wvs8m8_data_##n, \ + &memc_flexspi_is66wvs8m8_config_##n, POST_KERNEL, \ + CONFIG_MEMC_INIT_PRIORITY, NULL); + +DT_INST_FOREACH_STATUS_OKAY(MEMC_FLEXSPI_ISS66VWS8M8) diff --git a/dts/bindings/mtd/nxp,imx-flexspi-is66wvs8m8.yaml b/dts/bindings/mtd/nxp,imx-flexspi-is66wvs8m8.yaml new file mode 100644 index 000000000000..ea11e0c592f5 --- /dev/null +++ b/dts/bindings/mtd/nxp,imx-flexspi-is66wvs8m8.yaml @@ -0,0 +1,8 @@ +# Copyright 2023 NXP +# SPDX-License-Identifier: Apache-2.0 + +description: ISSI IS66WVS8M8 pSRAM on NXP FlexSPI bus + +compatible: "nxp,imx-flexspi-is66wvs8m8" + +include: nxp,imx-flexspi-device.yaml From c8f8fab1edbb73a95d94a6f1e3f65b4733e629a5 Mon Sep 17 00:00:00 2001 From: Nikhil Namjoshi Date: Wed, 17 Dec 2025 20:26:37 +0000 Subject: [PATCH 0726/3659] drivers: memc: Fix copyright and add example DTS config Example DTS config comment is meant to help users of the driver, with the PSRAM device tree configuration. Signed-off-by: Nikhil Namjoshi --- drivers/memc/memc_mcux_flexspi_is66wvs8m8.c | 57 ++++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff --git a/drivers/memc/memc_mcux_flexspi_is66wvs8m8.c b/drivers/memc/memc_mcux_flexspi_is66wvs8m8.c index 9918fa45eaf6..c8f2f9b47cef 100644 --- a/drivers/memc/memc_mcux_flexspi_is66wvs8m8.c +++ b/drivers/memc/memc_mcux_flexspi_is66wvs8m8.c @@ -1,5 +1,5 @@ /* - * Copyright 2023 NXP + * Copyright 2025 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -14,6 +14,61 @@ LOG_MODULE_REGISTER(memc_flexspi_is66wvs8m8, CONFIG_MEMC_LOG_LEVEL); +/* + * Example PSRAM and FlexSPI Controller DTS setting. + * + / { + // Add External PSRAM to the Linker Map. + psram0: psram_region@90800000 { + compatible = "zephyr,memory-region", "mmio-sram"; + zephyr,memory-region = "EXT_PSRAM"; + device_type = "memory"; + reg = <0x90800000 0x800000>; + }; + }; + + &flexspi { + status = "okay"; + pinctrl-0 = <&pinmux_flexspi>; + pinctrl-names = "default"; + rx-clock-source = <1>; + /delete-property/ combination-mode; + /delete-property/ ahb-cacheable; + /delete-property/ ahb-bufferable; + /delete-property/ ahb-prefetch; + /delete-property/ ahb-read-addr-opt; + + // Account for both the memories (w25q64jvssiq & is66wvs8m8) + // on the FlexSPI controller. + reg = <0x500c8000 0x1000>, + <0x90000000 DT_SIZE_M(16)>; + + w25q64jvssiq: w25q64jvssiq@0 { + ........ + } + + is66wvs8m8: is66wvs8m8@2 { + compatible = "nxp,imx-flexspi-is66wvs8m8"; + // IS66WVS8M8 is 8MB, 64MBit SerialRAM + size = ; + reg = <2>; + spi-max-frequency = <100000000>; + // PSRAM cannot be enabled while board is in default XIP + // configuration, as it will conflict with flash chip. + // + status = "okay"; + cs-interval-unit = <1>; + cs-interval = <3>; + cs-hold-time = <3>; + cs-setup-time = <3>; + data-valid-time = <1>; + column-space = <0>; + ahb-write-wait-unit = <2>; + ahb-write-wait-interval = <1>; + }; + }; +*/ + /* Vendor ID for ISSI device */ #define ISSI_VENDOR_ID 0x9D From c17e057dfd7ae1f81593f60e5fad1c61a0331212 Mon Sep 17 00:00:00 2001 From: Kevin Chan Date: Sun, 14 Dec 2025 17:46:56 -0800 Subject: [PATCH 0727/3659] soc: infinoen: edge: pse84: system clock Update system clock related variables otherwise Cy_SysLib_Delay or Cy_SysLib_DelayUs are incorrect Signed-off-by: Kevin Chan --- soc/infineon/edge/pse84/soc_pse84_m55.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/soc/infineon/edge/pse84/soc_pse84_m55.c b/soc/infineon/edge/pse84/soc_pse84_m55.c index a17dbe898300..ea192bfbce67 100644 --- a/soc/infineon/edge/pse84/soc_pse84_m55.c +++ b/soc/infineon/edge/pse84/soc_pse84_m55.c @@ -95,6 +95,9 @@ void soc_early_init_hook(void) /* Initializes the system */ ifx_cycfg_init(); + /* Initialize SystemCoreClock variable. */ + SystemCoreClockUpdate(); + static cy_stc_ipc_pipe_ep_t systemIpcPipeEpArray[CY_IPC_MAX_ENDPOINTS]; Cy_IPC_Pipe_Config(systemIpcPipeEpArray); From 58f59c13a508f5e04416be99b4135c78772ea4b6 Mon Sep 17 00:00:00 2001 From: Neil Chen Date: Mon, 15 Dec 2025 11:02:25 +0800 Subject: [PATCH 0728/3659] soc: nxp: mcxa156: add new parts for MCXA156 Add new parts MCXA156VFT and MCXA156VLH support Signed-off-by: Neil Chen --- soc/nxp/mcx/mcxa/Kconfig.soc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/soc/nxp/mcx/mcxa/Kconfig.soc b/soc/nxp/mcx/mcxa/Kconfig.soc index e0e94968d5d9..6572bf376c05 100644 --- a/soc/nxp/mcx/mcxa/Kconfig.soc +++ b/soc/nxp/mcx/mcxa/Kconfig.soc @@ -65,6 +65,12 @@ config SOC_PART_NUMBER_MCXA156VLL config SOC_PART_NUMBER_MCXA156VMP bool +config SOC_PART_NUMBER_MCXA156VFT + bool + +config SOC_PART_NUMBER_MCXA156VLH + bool + config SOC_PART_NUMBER_MCXA346VLQ bool @@ -130,6 +136,8 @@ config SOC_PART_NUMBER default "MCXA156VPJ" if SOC_PART_NUMBER_MCXA156VPJ default "MCXA156VLL" if SOC_PART_NUMBER_MCXA156VLL default "MCXA156VMP" if SOC_PART_NUMBER_MCXA156VMP + default "MCXA156VFT" if SOC_PART_NUMBER_MCXA156VFT + default "MCXA156VLH" if SOC_PART_NUMBER_MCXA156VLH default "MCXA346VLQ" if SOC_PART_NUMBER_MCXA346VLQ default "MCXA346VLL" if SOC_PART_NUMBER_MCXA346VLL default "MCXA346VLH" if SOC_PART_NUMBER_MCXA346VLH From 454c2fae98cc68db4eef97351b4f669b843fb5a8 Mon Sep 17 00:00:00 2001 From: Mohamed Moawad Date: Mon, 15 Dec 2025 09:54:53 +0200 Subject: [PATCH 0729/3659] tests: crypto: mbedtls_psa: enable malloc arena for Mbed TLS The PSA Crypto implementation in Mbed TLS requires some heap to operate. Provide a small malloc arena to ensure this test remains compatible with MINIMAL_LIBC configurations where the arena is disabled by default. Signed-off-by: Mohamed Moawad --- tests/crypto/mbedtls_psa/testcase.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/crypto/mbedtls_psa/testcase.yaml b/tests/crypto/mbedtls_psa/testcase.yaml index 96fb7315b222..be128b46912b 100644 --- a/tests/crypto/mbedtls_psa/testcase.yaml +++ b/tests/crypto/mbedtls_psa/testcase.yaml @@ -41,3 +41,5 @@ tests: - CONFIG_MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG=y - CONFIG_MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG_ALLOW_NON_CSPRNG=y - CONFIG_TEST_RANDOM_GENERATOR=y + # PSA Crypto needs some heap, but MINIMAL_LIBC has none by default. + - CONFIG_COMMON_LIBC_MALLOC_ARENA_SIZE=2048 From 03699e24fc702dc2a1610905b1cb1ff60888f252 Mon Sep 17 00:00:00 2001 From: Hou Zhiqiang Date: Mon, 15 Dec 2025 14:03:58 +0800 Subject: [PATCH 0730/3659] drivers: serial: mcux_lpuart: add clock enablement Add the clock emablement in the LPUART driver to avoid depending on the default enablement settings. Signed-off-by: Hou Zhiqiang --- drivers/serial/uart_mcux_lpuart.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/serial/uart_mcux_lpuart.c b/drivers/serial/uart_mcux_lpuart.c index 676856730651..ecb18f4e031c 100644 --- a/drivers/serial/uart_mcux_lpuart.c +++ b/drivers/serial/uart_mcux_lpuart.c @@ -1166,6 +1166,11 @@ static int mcux_lpuart_configure_init(const struct device *dev, const struct uar return ret; } + ret = clock_control_on(config->clock_dev, config->clock_subsys); + if (ret) { + return ret; + } + LPUART_Init(config->base, &uart_config, clock_freq); #ifdef LPUART_HAS_MODEM From 5116dcc3cd0f736c8dcbf32f167540d9a11a2da4 Mon Sep 17 00:00:00 2001 From: Aiden Hu Date: Wed, 10 Dec 2025 14:05:02 +0800 Subject: [PATCH 0731/3659] boards: nxp: rw612_bga: enable USB host support Add USB host support for rw612_bga board: - Update board YAML to include usb_host - Add zephyr_uhc0 node in device tree with status "okay" Signed-off-by: Aiden Hu --- boards/nxp/rd_rw612_bga/rd_rw612_bga.dtsi | 4 ++++ boards/nxp/rd_rw612_bga/rd_rw612_bga.yaml | 1 + 2 files changed, 5 insertions(+) diff --git a/boards/nxp/rd_rw612_bga/rd_rw612_bga.dtsi b/boards/nxp/rd_rw612_bga/rd_rw612_bga.dtsi index 9d9333053486..601de422aab8 100644 --- a/boards/nxp/rd_rw612_bga/rd_rw612_bga.dtsi +++ b/boards/nxp/rd_rw612_bga/rd_rw612_bga.dtsi @@ -257,6 +257,10 @@ zephyr_udc0: &usb_otg { status = "okay"; }; +zephyr_uhc0: &usbh { + status = "okay"; +}; + &dma0 { status = "okay"; }; diff --git a/boards/nxp/rd_rw612_bga/rd_rw612_bga.yaml b/boards/nxp/rd_rw612_bga/rd_rw612_bga.yaml index a47f0063dae9..de886b57e84a 100644 --- a/boards/nxp/rd_rw612_bga/rd_rw612_bga.yaml +++ b/boards/nxp/rd_rw612_bga/rd_rw612_bga.yaml @@ -28,6 +28,7 @@ supported: - pwm - spi - usb_device + - usb_host - watchdog - netif:eth - netif:openthread From 0756973f92b43cea01a89da415294f5c02e74d9a Mon Sep 17 00:00:00 2001 From: Holt Sun Date: Thu, 18 Dec 2025 10:35:48 +0800 Subject: [PATCH 0732/3659] MAINTAINERS: Add Holt Sun as RTC driver collaborator Add Holt Sun as a collaborator for "Drivers: RTC". Signed-off-by: Holt Sun --- MAINTAINERS.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index 4f056de3a8d0..14c9b876f075 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -2255,6 +2255,8 @@ Documentation Infrastructure: status: maintained maintainers: - bjarki-andreasen + collaborators: + - Holt-Sun files: - drivers/rtc/ - include/zephyr/drivers/rtc/ From 2cc9d794dc9803cbb5bb92bf9399ad5b8535be52 Mon Sep 17 00:00:00 2001 From: Adrien Lessard Date: Wed, 17 Dec 2025 20:11:37 -0500 Subject: [PATCH 0733/3659] drivers: counter: stm32: fix rtc subsecond register read According to the reference manual, 'When the BYPSHAD control bit is set in the RTC_CR register [...] the value of one of the registers may be incorrect if an RTCCLK edge occurs during the read operation'. We need to read te subseconds register until two successive reads are equal. Signed-off-by: Adrien Lessard --- drivers/counter/counter_stm32_rtc.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/drivers/counter/counter_stm32_rtc.c b/drivers/counter/counter_stm32_rtc.c index b1838d53079a..358e17abedc9 100644 --- a/drivers/counter/counter_stm32_rtc.c +++ b/drivers/counter/counter_stm32_rtc.c @@ -413,25 +413,29 @@ tick_t rtc_stm32_read(const struct device *dev) uint32_t rtc_date, rtc_time; tick_t ticks; #ifdef CONFIG_COUNTER_RTC_STM32_SUBSECONDS - uint32_t rtc_subseconds; + uint32_t rtc_subsecond; #endif /* CONFIG_COUNTER_RTC_STM32_SUBSECONDS */ ARG_UNUSED(dev); - /* Read time and date registers. Make sure value of the previous register - * hasn't been changed while reading the next one. - */ do { + /* read date, time and subseconds and relaunch if a day increment occurred + * while doing so as it will result in an erroneous result otherwise + */ rtc_date = LL_RTC_DATE_Get(RTC); - -#ifdef CONFIG_COUNTER_RTC_STM32_SUBSECONDS do { + /* read time and subseconds and relaunch if a second increment occurred + * while doing so as it will result in an erroneous result otherwise + */ rtc_time = LL_RTC_TIME_Get(RTC); - rtc_subseconds = LL_RTC_TIME_GetSubSecond(RTC); +#if CONFIG_COUNTER_RTC_STM32_SUBSECONDS + do { + /* read subseconds and relaunch if a second increment occurred + * while doing so as it will result in an erroneous result otherwise + */ + rtc_subsecond = LL_RTC_TIME_GetSubSecond(RTC); + } while (rtc_subsecond != LL_RTC_TIME_GetSubSecond(RTC)); +#endif /* CONFIG_COUNTER_RTC_STM32_SUBSECONDS */ } while (rtc_time != LL_RTC_TIME_Get(RTC)); -#else /* CONFIG_COUNTER_RTC_STM32_SUBSECONDS */ - rtc_time = LL_RTC_TIME_Get(RTC); -#endif - } while (rtc_date != LL_RTC_DATE_Get(RTC)); /* Convert calendar datetime to UNIX timestamp */ @@ -460,7 +464,7 @@ tick_t rtc_stm32_read(const struct device *dev) * down starting from the sync prescaler value. Add already counted * ticks. */ - ticks += RTC_SYNCPRE - rtc_subseconds; + ticks += RTC_SYNCPRE - rtc_subsecond; #endif /* CONFIG_COUNTER_RTC_STM32_SUBSECONDS */ return ticks; From 9929ac33f4f9fdeba2912b4294c7f146dffacf73 Mon Sep 17 00:00:00 2001 From: Adrien Lessard Date: Wed, 17 Dec 2025 20:14:10 -0500 Subject: [PATCH 0734/3659] drivers: rtc: stm32: fix rtc subsecond register read According to the reference manual, 'When the BYPSHAD control bit is set in the RTC_CR register [...] the value of one of the registers may be incorrect if an RTCCLK edge occurs during the read operation'. We need to read te subseconds register until two successive reads are equal. Signed-off-by: Adrien Lessard --- drivers/rtc/rtc_stm32.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/rtc/rtc_stm32.c b/drivers/rtc/rtc_stm32.c index 243db4b20aea..6e94cb0b516e 100644 --- a/drivers/rtc/rtc_stm32.c +++ b/drivers/rtc/rtc_stm32.c @@ -649,9 +649,14 @@ static int rtc_stm32_get_time(const struct device *dev, struct rtc_time *timeptr /* read time and subseconds and relaunch if a second increment occurred * while doing so as it will result in an erroneous result otherwise */ - rtc_time = LL_RTC_TIME_Get(RTC); + rtc_time = LL_RTC_TIME_Get(RTC); #if HW_SUBSECOND_SUPPORT - rtc_subsecond = LL_RTC_TIME_GetSubSecond(RTC); + do { + /* read subseconds and relaunch if a second increment occurred + * while doing so as it will result in an erroneous result otherwise + */ + rtc_subsecond = LL_RTC_TIME_GetSubSecond(RTC); + } while (rtc_subsecond != LL_RTC_TIME_GetSubSecond(RTC)); #endif /* HW_SUBSECOND_SUPPORT */ } while (rtc_time != LL_RTC_TIME_Get(RTC)); } while (rtc_date != LL_RTC_DATE_Get(RTC)); From 72360f821a610b64fda3bd300b6ca4577f6abe8c Mon Sep 17 00:00:00 2001 From: Lucien Zhao Date: Tue, 16 Dec 2025 23:24:08 +0800 Subject: [PATCH 0735/3659] dts: arm: nxp: rt118x: correct ocram1_available address correct ocram1_available reg address to fix warning log Signed-off-by: Lucien Zhao --- dts/arm/nxp/nxp_rt118x.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dts/arm/nxp/nxp_rt118x.dtsi b/dts/arm/nxp/nxp_rt118x.dtsi index 1686320996c5..28b9d6caacea 100644 --- a/dts/arm/nxp/nxp_rt118x.dtsi +++ b/dts/arm/nxp/nxp_rt118x.dtsi @@ -1628,7 +1628,7 @@ ocram1_available: memory@4000 { /* OCRAM1 first 16K access is blocked by TRDC */ - reg = <0x0 DT_SIZE_K(496)>; + reg = <0x4000 DT_SIZE_K(496)>; }; }; From 242b69e1ac04ed99d2bef85c2c64461cf9db1ee3 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Sat, 20 Dec 2025 09:39:42 +0100 Subject: [PATCH 0736/3659] tests: net: dns_resolver: Increase heap size The test fails on 64bit targets running out of heap. Let's just increase it. Circumstantially it started failing after d5982f0f89f8200ceaeeeabb6fb45b3759008eba Signed-off-by: Alberto Escolar Piedras --- tests/net/lib/dns_resolve/prj.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/net/lib/dns_resolve/prj.conf b/tests/net/lib/dns_resolve/prj.conf index 9dde97ee4c58..93ebf2b27591 100644 --- a/tests/net/lib/dns_resolve/prj.conf +++ b/tests/net/lib/dns_resolve/prj.conf @@ -29,7 +29,7 @@ CONFIG_PRINTK=y CONFIG_ZTEST=y CONFIG_MAIN_STACK_SIZE=1344 -CONFIG_HEAP_MEM_POOL_SIZE=1024 +CONFIG_HEAP_MEM_POOL_SIZE=2048 CONFIG_ZVFS_POLL_MAX=9 CONFIG_ZVFS_OPEN_IGNORE_MIN=y From 51adafd3f3f34a9725241396fac11a7f5845df57 Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Fri, 19 Dec 2025 16:21:35 -0800 Subject: [PATCH 0737/3659] kernel: mem_domain: remove extra newline character for logging There is no need for the newline characters when using logging macros. So remove them. Signed-off-by: Daniel Leung --- kernel/mem_domain.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/kernel/mem_domain.c b/kernel/mem_domain.c index dc1cfe01126a..ced45f7caff6 100644 --- a/kernel/mem_domain.c +++ b/kernel/mem_domain.c @@ -192,7 +192,7 @@ int k_mem_domain_add_partition(struct k_mem_domain *domain, goto unlock_out; } - LOG_DBG("add partition base %lx size %zu to domain %p\n", + LOG_DBG("add partition base %lx size %zu to domain %p", part->start, part->size, domain); domain->partitions[p_idx].start = part->start; @@ -240,7 +240,7 @@ int k_mem_domain_remove_partition(struct k_mem_domain *domain, goto unlock_out; } - LOG_DBG("remove partition base %lx size %zu from domain %p\n", + LOG_DBG("remove partition base %lx size %zu from domain %p", part->start, part->size, domain); #ifdef CONFIG_ARCH_MEM_DOMAIN_SYNCHRONOUS_API @@ -267,7 +267,7 @@ static int add_thread_locked(struct k_mem_domain *domain, __ASSERT_NO_MSG(domain != NULL); __ASSERT_NO_MSG(thread != NULL); - LOG_DBG("add thread %p to domain %p\n", thread, domain); + LOG_DBG("add thread %p to domain %p", thread, domain); #ifdef CONFIG_MEM_DOMAIN_HAS_THREAD_LIST sys_dlist_append(&domain->thread_mem_domain_list, @@ -288,7 +288,7 @@ static int remove_thread_locked(struct k_thread *thread) int ret = 0; __ASSERT_NO_MSG(thread != NULL); - LOG_DBG("remove thread %p from memory domain %p\n", + LOG_DBG("remove thread %p from memory domain %p", thread, thread->mem_domain_info.mem_domain); #ifdef CONFIG_MEM_DOMAIN_HAS_THREAD_LIST From f02e15acc22a1f9b9686728d7a21609d65f622d7 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Fri, 19 Dec 2025 14:24:37 +0100 Subject: [PATCH 0738/3659] samples/drivers/ipm/ipm_esp32: Remove unnecessary headers None of these headers are needed by this file for anything. Let's just remove them. Signed-off-by: Alberto Escolar Piedras --- samples/drivers/ipm/ipm_esp32/src/procpu_shell.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/samples/drivers/ipm/ipm_esp32/src/procpu_shell.c b/samples/drivers/ipm/ipm_esp32/src/procpu_shell.c index e036b6608e62..7240c36a21ed 100644 --- a/samples/drivers/ipm/ipm_esp32/src/procpu_shell.c +++ b/samples/drivers/ipm/ipm_esp32/src/procpu_shell.c @@ -9,11 +9,6 @@ #include #include -#include -#include -#include -#include -#include #include #include From 71457bd4913ea5fd9f41dfb19773f6458ce70818 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Fri, 19 Dec 2025 14:28:50 +0100 Subject: [PATCH 0739/3659] samples/shields/npm6001_ek: Remove unnecessary header To use the shell one does not need anymore to pull unistd.h, if one uses sys_getopt, we need to include sys/sys_getopt.h Signed-off-by: Alberto Escolar Piedras --- samples/shields/npm6001_ek/src/main.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/samples/shields/npm6001_ek/src/main.c b/samples/shields/npm6001_ek/src/main.c index f73e39108308..25fdfbf26c66 100644 --- a/samples/shields/npm6001_ek/src/main.c +++ b/samples/shields/npm6001_ek/src/main.c @@ -11,10 +11,8 @@ #include #include #include -#include #include #include - #include struct regulators_map { From 5a58989daddda2a8a3c87396acaf4275b6c72596 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Fri, 19 Dec 2025 14:30:00 +0100 Subject: [PATCH 0740/3659] samples/subsys/shell/shell_module: Remove unnecessary header To use the shell one does not need anymore to pull unistd.h, if one uses sys_getopt, we need to include sys/sys_getopt.h Signed-off-by: Alberto Escolar Piedras --- samples/subsys/shell/shell_module/src/main.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/samples/subsys/shell/shell_module/src/main.c b/samples/subsys/shell/shell_module/src/main.c index 4df37646026c..2a310863ef9f 100644 --- a/samples/subsys/shell/shell_module/src/main.c +++ b/samples/subsys/shell/shell_module/src/main.c @@ -12,12 +12,6 @@ #include #include -#ifdef CONFIG_NATIVE_LIBC -#include -#else -#include -#endif - LOG_MODULE_REGISTER(app); extern void foo(void); From 419a0944991d74759eb5e9dbbf4a38240e60a2b9 Mon Sep 17 00:00:00 2001 From: Duy Nguyen Date: Thu, 18 Dec 2025 07:47:24 +0000 Subject: [PATCH 0741/3659] dts: renesas: ra: Fix adc compatible for ra6-cm4 The `renesas,ra-adc` compatible was replaced by `renesas,ra-adc12`, at #95710 but one ADC devicetree node was not updated accordingly. This commit updates the missing node to use the correct `renesas,ra-adc12` compatible. Signed-off-by: Duy Nguyen --- dts/arm/renesas/ra/ra6/ra6-cm4-common.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dts/arm/renesas/ra/ra6/ra6-cm4-common.dtsi b/dts/arm/renesas/ra/ra6/ra6-cm4-common.dtsi index 906f0e1bd641..8a5f28691373 100644 --- a/dts/arm/renesas/ra/ra6/ra6-cm4-common.dtsi +++ b/dts/arm/renesas/ra/ra6/ra6-cm4-common.dtsi @@ -371,7 +371,7 @@ }; adc1: adc@4005c200 { - compatible = "renesas,ra-adc"; + compatible = "renesas,ra-adc12"; interrupts = <39 1>; interrupt-names = "scanend"; unit = <1>; From c960d0ed0f9ad1b3f11372e271c8f80b0d1e221e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=AD=20Bol=C3=ADvar?= Date: Wed, 3 Dec 2025 08:51:45 -0800 Subject: [PATCH 0742/3659] devicetree: clean up some code inconsistencies MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The documentation is generally using 'inst' consistently to refer to instance numbers, but a few helper macros have gone their own way. Clean this up to restore consistency. This addresses changes introduced somewhere around the following commits: - 4c8ed7dd9a1 ("devicetree.h: Rework DT_ANY_INST_HAS_PROP_STATUS_OKAY") - ca6645d508a ("devicetree: shorten DT_ANY_INST_HAS_*_STATUS_OKAY") - 75ab4d5507c ("devicetree: add DT_ALL_INST_HAS_PROP_STATUS_OKAY() macro") - 35a8e37ac29 ("devicetree: add DT_ALL_INST_HAS_BOOL_STATUS_OKAY() macro") Signed-off-by: Martí Bolívar --- include/zephyr/devicetree.h | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/include/zephyr/devicetree.h b/include/zephyr/devicetree.h index 2dca998435ca..6fca2c19e463 100644 --- a/include/zephyr/devicetree.h +++ b/include/zephyr/devicetree.h @@ -5488,60 +5488,60 @@ /** @brief Helper for DT_ANY_INST_HAS_PROP_STATUS_OKAY * * This macro generates token "1," for instance of a device, - * identified by index @p idx, if instance has property @p prop. + * identified by index @p inst, if instance has property @p prop. * - * @param idx instance number + * @param inst instance number * @param prop property to check for * * @return Macro evaluates to `1,` if instance has the property, * otherwise it evaluates to literal nothing. */ -#define DT_ANY_INST_HAS_PROP_STATUS_OKAY_(idx, prop) \ - IF_ENABLED(DT_INST_NODE_HAS_PROP(idx, prop), (1,)) +#define DT_ANY_INST_HAS_PROP_STATUS_OKAY_(inst, prop) \ + IF_ENABLED(DT_INST_NODE_HAS_PROP(inst, prop), (1,)) /** @brief Helper for DT_ANY_INST_HAS_BOOL_STATUS_OKAY * * This macro generates token "1," for instance of a device, - * identified by index @p idx, if instance has boolean property + * identified by index @p inst, if instance has boolean property * @p prop with value 1. * - * @param idx instance number + * @param inst instance number * @param prop property to check for * * @return Macro evaluates to `1,` if instance property value is 1, * otherwise it evaluates to literal nothing. */ -#define DT_ANY_INST_HAS_BOOL_STATUS_OKAY_(idx, prop) \ - IF_ENABLED(DT_INST_PROP(idx, prop), (1,)) +#define DT_ANY_INST_HAS_BOOL_STATUS_OKAY_(inst, prop) \ + IF_ENABLED(DT_INST_PROP(inst, prop), (1,)) /** @brief Helper for DT_ALL_INST_HAS_PROP_STATUS_OKAY * * This macro generates token "1," for instance of a device, - * identified by index @p idx, if instance has no property @p prop. + * identified by index @p inst, if instance has no property @p prop. * - * @param idx instance number + * @param inst instance number * @param prop property to check for * * @return Macro evaluates to `1,` if instance has the property, * otherwise it evaluates to literal nothing. */ -#define DT_ALL_INST_HAS_PROP_STATUS_OKAY_(idx, prop) \ - IF_DISABLED(DT_INST_NODE_HAS_PROP(idx, prop), (1,)) +#define DT_ALL_INST_HAS_PROP_STATUS_OKAY_(inst, prop) \ + IF_DISABLED(DT_INST_NODE_HAS_PROP(inst, prop), (1,)) /** @brief Helper for DT_ALL_INST_HAS_BOOL_STATUS_OKAY * * This macro generates token "1," for instance of a device, - * identified by index @p idx, if instance has no boolean property + * identified by index @p inst, if instance has no boolean property * @p prop with value 1. * - * @param idx instance number + * @param inst instance number * @param prop property to check for * * @return Macro evaluates to `1,` if instance property value is 0, * otherwise it evaluates to literal nothing. */ -#define DT_ALL_INST_HAS_BOOL_STATUS_OKAY_(idx, prop) \ - IF_DISABLED(DT_INST_PROP(idx, prop), (1,)) +#define DT_ALL_INST_HAS_BOOL_STATUS_OKAY_(inst, prop) \ + IF_DISABLED(DT_INST_PROP(inst, prop), (1,)) #define DT_PATH_INTERNAL(...) \ UTIL_CAT(DT_ROOT, MACRO_MAP_CAT(DT_S_PREFIX, __VA_ARGS__)) From 6a2bb8b0e2d79c6d3521eab5289fd594fc225d62 Mon Sep 17 00:00:00 2001 From: zjian zhang Date: Tue, 16 Dec 2025 21:28:12 +0800 Subject: [PATCH 0743/3659] west.yml: add support for amebad add low level support for amebad Signed-off-by: zjian zhang --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index beabfcc50873..ed1c1afeecd6 100644 --- a/west.yml +++ b/west.yml @@ -226,7 +226,7 @@ manifest: - hal - name: hal_realtek path: modules/hal/realtek - revision: c769be0fb9e385edba12e9626ee516c0a44b9907 + revision: 4f8703eb110220e3a98c7e883f672a575679b9e8 groups: - hal - name: hal_renesas From acb831f5c0c0cf21111ac27736dfac021ca2d8dc Mon Sep 17 00:00:00 2001 From: zjian zhang Date: Wed, 18 Jun 2025 20:50:34 +0800 Subject: [PATCH 0744/3659] dts: arm: introduce amebad SOC Devicetree add initial version of devicetree for amebad SOC. amebad devicetree file is main platform dtsi file, which should be included from board dts (e.g rtl872xd_evb.dts) Signed-off-by: zjian zhang --- dts/arm/realtek/amebad/amebad.dtsi | 96 ++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 dts/arm/realtek/amebad/amebad.dtsi diff --git a/dts/arm/realtek/amebad/amebad.dtsi b/dts/arm/realtek/amebad/amebad.dtsi new file mode 100644 index 000000000000..0ec2d9324c03 --- /dev/null +++ b/dts/arm/realtek/amebad/amebad.dtsi @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor Corp. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +/ { + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-m33"; + reg = <0>; + d-cache-line-size = <32>; + #address-cells = <1>; + #size-cells = <1>; + }; + }; + + clocks { + clk_sys: clk_sys { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = ; + }; + }; + + soc { + sram0: memory@10003020 { + compatible = "mmio-sram"; + reg = <0x10003020 0x00074000>; + }; + + ram_image2_entry: memory@10003000 { + compatible = "zephyr,memory-region"; + reg = <0x10003000 0x20>; + zephyr,memory-region = "KM4_IMG2_ENTRY"; + }; + + pinctrl: pinctrl@48000400 { + compatible = "realtek,ameba-pinctrl"; + reg = <0x48000400 0x200>; + }; + + loguart: serial@48012000 { + compatible = "realtek,ameba-loguart"; + reg = <0x48012000 0x100>; + interrupts = <3 0>; + current-speed = <1500000>; + status = "disabled"; + }; + + spic: flash-controller@48080000 { + compatible = "realtek,ameba-flash-controller"; + reg = <0x48080000 0x200>; + + #address-cells = <1>; + #size-cells = <1>; + status = "disabled"; + + flash0: flash@E000020 { + compatible = "soc-nv-flash"; + erase-block-size = ; + write-block-size = <4>; + }; + }; + + gpioa: gpio@48014000 { + compatible = "realtek,ameba-gpio"; + reg = <0x48014000 0x400>; + gpio-controller; + #gpio-cells = <2>; + interrupts = <4 0>; + status = "disabled"; + }; + + gpiob: gpio@48014400 { + compatible = "realtek,ameba-gpio"; + reg = <0x48014400 0x400>; + gpio-controller; + #gpio-cells = <2>; + interrupts = <8 0>; + status = "disabled"; + }; + }; +}; + +&nvic { + arm,num-irq-priority-bits = <3>; +}; From 6ad245a55427a66d81aa11719bbc737fb811f4a5 Mon Sep 17 00:00:00 2001 From: zjian zhang Date: Thu, 19 Jun 2025 10:11:01 +0800 Subject: [PATCH 0745/3659] soc: add realtek amebad SOC integration Add initial version of Amebad Soc integration Signed-off-by: zjian zhang --- soc/realtek/ameba/amebad/CMakeLists.txt | 9 ++++ soc/realtek/ameba/amebad/Kconfig | 16 ++++++ soc/realtek/ameba/amebad/Kconfig.defconfig | 15 ++++++ soc/realtek/ameba/amebad/Kconfig.soc | 16 ++++++ soc/realtek/ameba/amebad/boot_section.ld | 24 +++++++++ soc/realtek/ameba/amebad/pinctrl_soc.h | 54 +++++++++++++++++++++ soc/realtek/ameba/amebad/soc.c | 44 +++++++++++++++++ soc/realtek/ameba/amebad/soc.h | 17 +++++++ soc/realtek/ameba/amebad/soc_cpu_idle.h | 8 +++ soc/realtek/ameba/amebadplus/CMakeLists.txt | 25 ---------- soc/realtek/ameba/soc.yml | 3 ++ 11 files changed, 206 insertions(+), 25 deletions(-) create mode 100644 soc/realtek/ameba/amebad/CMakeLists.txt create mode 100644 soc/realtek/ameba/amebad/Kconfig create mode 100644 soc/realtek/ameba/amebad/Kconfig.defconfig create mode 100644 soc/realtek/ameba/amebad/Kconfig.soc create mode 100644 soc/realtek/ameba/amebad/boot_section.ld create mode 100644 soc/realtek/ameba/amebad/pinctrl_soc.h create mode 100644 soc/realtek/ameba/amebad/soc.c create mode 100644 soc/realtek/ameba/amebad/soc.h create mode 100644 soc/realtek/ameba/amebad/soc_cpu_idle.h diff --git a/soc/realtek/ameba/amebad/CMakeLists.txt b/soc/realtek/ameba/amebad/CMakeLists.txt new file mode 100644 index 000000000000..0c500760564b --- /dev/null +++ b/soc/realtek/ameba/amebad/CMakeLists.txt @@ -0,0 +1,9 @@ +# Copyright (c) 2024 Realtek Semiconductor Corp. +# SPDX-License-Identifier: Apache-2.0 + +zephyr_include_directories(.) + +zephyr_sources(soc.c) + +zephyr_linker_sources(SECTIONS boot_section.ld) +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/realtek/ameba/amebad/Kconfig b/soc/realtek/ameba/amebad/Kconfig new file mode 100644 index 000000000000..072b82da3f66 --- /dev/null +++ b/soc/realtek/ameba/amebad/Kconfig @@ -0,0 +1,16 @@ +# Copyright (c) 2024 Realtek Semiconductor Corp. +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_AMEBAD + select ARM + select CPU_CORTEX_M33 + select CPU_HAS_DCACHE + select CPU_HAS_ICACHE + select CPU_HAS_ARM_SAU + select CPU_HAS_FPU + select CPU_HAS_VFP + select ARMV8_M_DSP + select CPU_HAS_ARM_MPU + select ARM_MPU + select ARM_TRUSTZONE_M + select ARM_ON_EXIT_CPU_IDLE diff --git a/soc/realtek/ameba/amebad/Kconfig.defconfig b/soc/realtek/ameba/amebad/Kconfig.defconfig new file mode 100644 index 000000000000..c4b2ce5cd795 --- /dev/null +++ b/soc/realtek/ameba/amebad/Kconfig.defconfig @@ -0,0 +1,15 @@ +# Copyright (c) 2024 Realtek Semiconductor Corp. +# SPDX-License-Identifier: Apache-2.0 + +if SOC_SERIES_AMEBAD + +config NUM_IRQS + default 64 + +config SYS_CLOCK_HW_CYCLES_PER_SEC + default $(dt_node_int_prop_int,/clocks/clk_sys,clock-frequency) + +config CACHE_MANAGEMENT + default y + +endif #SOC_SERIES_AMEBAD diff --git a/soc/realtek/ameba/amebad/Kconfig.soc b/soc/realtek/ameba/amebad/Kconfig.soc new file mode 100644 index 000000000000..f2a48dee6c6d --- /dev/null +++ b/soc/realtek/ameba/amebad/Kconfig.soc @@ -0,0 +1,16 @@ +# Copyright (c) 2024 Realtek Semiconductor Corp. +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_AMEBAD + bool + select SOC_FAMILY_REALTEK_AMEBA + +config SOC_SERIES + default "amebad" if SOC_SERIES_AMEBAD + +config SOC_RTL872XD + bool + select SOC_SERIES_AMEBAD + +config SOC + default "rtl872xd" if SOC_RTL872XD diff --git a/soc/realtek/ameba/amebad/boot_section.ld b/soc/realtek/ameba/amebad/boot_section.ld new file mode 100644 index 000000000000..8f952d818a6d --- /dev/null +++ b/soc/realtek/ameba/amebad/boot_section.ld @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor Corp. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +SECTION_PROLOGUE(.ram_image2.entry,,SUBALIGN(32)) +{ + __image2_entry_func__ = .; + KEEP(*(SORT(.image2.entry.data*))) + . = ALIGN(32); +} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) + +SECTION_PROLOGUE(.psram_image2.text.data,,) +{ + __image2_backtrace_start__ = .; + *(*.sramdram.only.text) + + __ipc_table_start__ = .; + KEEP(*(*.ipc.table.data*)) + __ipc_table_end__ = .; + + __image2_backtrace_end__ = .; +} GROUP_LINK_IN(ROMABLE_REGION) diff --git a/soc/realtek/ameba/amebad/pinctrl_soc.h b/soc/realtek/ameba/amebad/pinctrl_soc.h new file mode 100644 index 000000000000..134c58915b49 --- /dev/null +++ b/soc/realtek/ameba/amebad/pinctrl_soc.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor Corp. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_SOC_REALTEK_AMEBA_AMEBAD_PINCTRL_SOC_H_ +#define ZEPHYR_SOC_REALTEK_AMEBA_AMEBAD_PINCTRL_SOC_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct pinctrl_soc_pin { + uint32_t pinmux: 15; + /* bit[14:13] port + * bit[12:8] pin + * bit[7:0] function ID + */ + uint32_t pull_down: 1; + uint32_t pull_up: 1; + uint32_t schmitt_disable: 1; + uint32_t slew_rate_slow: 1; + uint32_t drive_strength_low: 1; + uint32_t digital_input_disable: 1; + uint32_t swd_off: 1; +}; + +typedef struct pinctrl_soc_pin pinctrl_soc_pin_t; + +#define Z_PINCTRL_STATE_PIN_INIT(node_id, prop, idx) \ + { \ + .pinmux = DT_PROP_BY_IDX(node_id, prop, idx), \ + .pull_down = DT_PROP(node_id, bias_pull_down), \ + .pull_up = DT_PROP(node_id, bias_pull_up), \ + .schmitt_disable = DT_PROP(node_id, input_schmitt_disable), \ + .slew_rate_slow = DT_PROP(node_id, slew_rate_slow), \ + .drive_strength_low = DT_PROP(node_id, drive_strength_low), \ + .digital_input_disable = DT_PROP(node_id, digital_input_disable), \ + .swd_off = DT_PROP(node_id, swd_off), \ + }, + +#define Z_PINCTRL_STATE_PINS_INIT(node_id, prop) \ + {DT_FOREACH_CHILD_VARGS(DT_PHANDLE(node_id, prop), DT_FOREACH_PROP_ELEM, pinmux, \ + Z_PINCTRL_STATE_PIN_INIT)} + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_SOC_REALTEK_AMEBA_AMEBAD_PINCTRL_SOC_H_ */ diff --git a/soc/realtek/ameba/amebad/soc.c b/soc/realtek/ameba/amebad/soc.c new file mode 100644 index 000000000000..979af8d352c8 --- /dev/null +++ b/soc/realtek/ameba/amebad/soc.c @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor Corp. + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include +#include +#include +#include +#include "ameba_system.h" + +void z_arm_reset(void); + +IMAGE2_ENTRY_SECTION +RAM_START_FUNCTION Img2EntryFun0 = {z_arm_reset, NULL, /* BOOT_RAM_WakeFromPG, */ + (uint32_t)NewVectorTable}; + +static void app_vdd1833_detect(void) +{ + uint32_t temp; + + if (is_power_supply18() == false) { + temp = sys_read32(SYSTEM_CTRL_BASE_HP + REG_HS_RFAFE_IND_VIO1833); + temp |= BIT_RFAFE_IND_VIO1833; + sys_write32(temp, SYSTEM_CTRL_BASE_HP + REG_HS_RFAFE_IND_VIO1833); + } +} + +void soc_early_init_hook(void) +{ + /* + * Cache is enabled by default at reset, disable it before + * sys_cache*-functions can enable them. + */ + Cache_Enable(DISABLE); + sys_cache_data_enable(); + sys_cache_instr_enable(); + + SystemSetCpuClk(CLK_KM4_200M); + + app_vdd1833_detect(); +} diff --git a/soc/realtek/ameba/amebad/soc.h b/soc/realtek/ameba/amebad/soc.h new file mode 100644 index 000000000000..f29948817bd3 --- /dev/null +++ b/soc/realtek/ameba/amebad/soc.h @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor Corp. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_SOC_REALTEK_AMEBA_AMEBAD_H_ +#define ZEPHYR_SOC_REALTEK_AMEBA_AMEBAD_H_ + +#ifndef _ASMLANGUAGE + +#include +#include "cmsis_cpu.h" + +#endif /* _ASMLANGUAGE */ + +#endif /* ZEPHYR_SOC_REALTEK_AMEBA_AMEBAD_H_ */ diff --git a/soc/realtek/ameba/amebad/soc_cpu_idle.h b/soc/realtek/ameba/amebad/soc_cpu_idle.h new file mode 100644 index 000000000000..a730b7e37c29 --- /dev/null +++ b/soc/realtek/ameba/amebad/soc_cpu_idle.h @@ -0,0 +1,8 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor Corp. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* Workaround for WFI fused instruction issue */ +#define SOC_ON_EXIT_CPU_IDLE __NOP(); diff --git a/soc/realtek/ameba/amebadplus/CMakeLists.txt b/soc/realtek/ameba/amebadplus/CMakeLists.txt index 6b3fb8c38fbe..0c500760564b 100644 --- a/soc/realtek/ameba/amebadplus/CMakeLists.txt +++ b/soc/realtek/ameba/amebadplus/CMakeLists.txt @@ -1,34 +1,9 @@ # Copyright (c) 2024 Realtek Semiconductor Corp. # SPDX-License-Identifier: Apache-2.0 -zephyr_include_directories(${ZEPHYR_BASE}/drivers) zephyr_include_directories(.) zephyr_sources(soc.c) zephyr_linker_sources(SECTIONS boot_section.ld) set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") - -# west sign -file(GLOB BIN_FILES "${ZEPHYR_HAL_REALTEK_MODULE_DIR}/zephyr/blobs/${CONFIG_SOC_SERIES}/bin/*.bin") - -if(BIN_FILES) - set(python_script_args - --soc ${CONFIG_SOC_SERIES} - --bin-file ${ZEPHYR_BINARY_DIR}/${KERNEL_BIN_NAME} - --out-dir ${CMAKE_BINARY_DIR} - --module-dir ${ZEPHYR_HAL_REALTEK_MODULE_DIR} - ) - - add_custom_target(zephyr.raw.map ALL - DEPENDS ${ZEPHYR_BINARY_DIR}/${KERNEL_NAME}.raw.map - ) - - add_custom_command( - OUTPUT ${ZEPHYR_BINARY_DIR}/${KERNEL_NAME}.raw.map - COMMAND ${CMAKE_NM} ${ZEPHYR_BINARY_DIR}/${KERNEL_ELF_NAME} | sort > ${ZEPHYR_BINARY_DIR}/${KERNEL_NAME}.raw.map - COMMAND ${CMAKE_OBJDUMP} -d ${ZEPHYR_BINARY_DIR}/${KERNEL_ELF_NAME} > ${ZEPHYR_BINARY_DIR}/${KERNEL_NAME}.asm - COMMAND ${PYTHON_EXECUTABLE} ${ZEPHYR_HAL_REALTEK_MODULE_DIR}/ameba/scripts/merge_bin.py ${python_script_args} - DEPENDS ${ZEPHYR_BINARY_DIR}/${KERNEL_ELF_NAME} ${ZEPHYR_HAL_REALTEK_MODULE_DIR}/ameba/${CONFIG_SOC_SERIES}/manifest.json5 - ) -endif() diff --git a/soc/realtek/ameba/soc.yml b/soc/realtek/ameba/soc.yml index 602bbb18bea7..adf40721b29c 100644 --- a/soc/realtek/ameba/soc.yml +++ b/soc/realtek/ameba/soc.yml @@ -1,6 +1,9 @@ family: - name: realtek_ameba series: + - name: amebad + socs: + - name: rtl872xd - name: amebadplus socs: - name: rtl8721dx From 14e396a3b17f130b69f95968fde3374d474edfe4 Mon Sep 17 00:00:00 2001 From: zjian zhang Date: Thu, 19 Jun 2025 10:24:02 +0800 Subject: [PATCH 0746/3659] drivers: serial: add amebad loguart support loguart driver support for amebad Signed-off-by: zjian zhang --- drivers/serial/uart_ameba_loguart.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/serial/uart_ameba_loguart.c b/drivers/serial/uart_ameba_loguart.c index 5196ba71fe83..7e92ad422743 100644 --- a/drivers/serial/uart_ameba_loguart.c +++ b/drivers/serial/uart_ameba_loguart.c @@ -239,8 +239,7 @@ static void loguart_ameba_irq_callback_set(const struct device *dev, static int loguart_ameba_init(const struct device *dev) { LOGUART_RxCmd(LOGUART_DEV, DISABLE); - LOGUART_INTCoreConfig(LOGUART_DEV, LOGUART_BIT_INTR_MASK_KM0, DISABLE); - LOGUART_INTCoreConfig(LOGUART_DEV, LOGUART_BIT_INTR_MASK_KM4, ENABLE); + LOGUART_INT_NP2AP(); #if defined(CONFIG_UART_INTERRUPT_DRIVEN) const struct loguart_ameba_config *config = dev->config; From 97d266e777afa294234226d7b74798d1e1bfe52c Mon Sep 17 00:00:00 2001 From: zjian zhang Date: Tue, 16 Dec 2025 21:17:22 +0800 Subject: [PATCH 0747/3659] drivers: gpio: fixed compile warning fixed gpio driver compile warning Signed-off-by: zjian zhang --- drivers/gpio/gpio_ameba.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/gpio/gpio_ameba.c b/drivers/gpio/gpio_ameba.c index 3b49ee4b6404..f488e9c4fb32 100644 --- a/drivers/gpio/gpio_ameba.c +++ b/drivers/gpio/gpio_ameba.c @@ -265,8 +265,6 @@ static const struct gpio_driver_api gpio_ameba_driver_api = { #define GPIO_AMEBA_INIT(n) \ static int gpio_ameba_port##n##_init(const struct device *dev) \ { \ - const struct gpio_ameba_config *cfg = dev->config; \ - \ IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority), gpio_ameba_isr, \ DEVICE_DT_INST_GET(n), 0); \ irq_enable(DT_INST_IRQN(n)); \ From d70318f825d5f43e3803fe90a960fe4774244f27 Mon Sep 17 00:00:00 2001 From: zjian zhang Date: Thu, 19 Jun 2025 10:32:38 +0800 Subject: [PATCH 0748/3659] boards: add rtl872xd_evb board add initial version of rtl872xd_evb board Signed-off-by: zjian zhang --- .../realtek/rtl872xd_evb/Kconfig.rtl872xd_evb | 5 + boards/realtek/rtl872xd_evb/board.cmake | 6 ++ boards/realtek/rtl872xd_evb/board.yml | 5 + boards/realtek/rtl872xd_evb/doc/index.rst | 90 ++++++++++++++++++ .../rtl872xd_evb/doc/rtl872xd_evb.webp | Bin 0 -> 20638 bytes .../rtl872xd_evb/rtl872xd_evb-pinctrl.dtsi | 20 ++++ boards/realtek/rtl872xd_evb/rtl872xd_evb.dts | 38 ++++++++ boards/realtek/rtl872xd_evb/rtl872xd_evb.yaml | 16 ++++ .../rtl872xd_evb/rtl872xd_evb_defconfig | 15 +++ .../dt-bindings/pinctrl/amebad-pinctrl.h | 54 +++++++++++ 10 files changed, 249 insertions(+) create mode 100644 boards/realtek/rtl872xd_evb/Kconfig.rtl872xd_evb create mode 100644 boards/realtek/rtl872xd_evb/board.cmake create mode 100644 boards/realtek/rtl872xd_evb/board.yml create mode 100644 boards/realtek/rtl872xd_evb/doc/index.rst create mode 100644 boards/realtek/rtl872xd_evb/doc/rtl872xd_evb.webp create mode 100644 boards/realtek/rtl872xd_evb/rtl872xd_evb-pinctrl.dtsi create mode 100644 boards/realtek/rtl872xd_evb/rtl872xd_evb.dts create mode 100644 boards/realtek/rtl872xd_evb/rtl872xd_evb.yaml create mode 100644 boards/realtek/rtl872xd_evb/rtl872xd_evb_defconfig create mode 100644 include/zephyr/dt-bindings/pinctrl/amebad-pinctrl.h diff --git a/boards/realtek/rtl872xd_evb/Kconfig.rtl872xd_evb b/boards/realtek/rtl872xd_evb/Kconfig.rtl872xd_evb new file mode 100644 index 000000000000..2d696fe9ad2f --- /dev/null +++ b/boards/realtek/rtl872xd_evb/Kconfig.rtl872xd_evb @@ -0,0 +1,5 @@ +# Copyright (c) 2024 Realtek Semiconductor Corp. +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_RTL872XD_EVB + select SOC_RTL872XD diff --git a/boards/realtek/rtl872xd_evb/board.cmake b/boards/realtek/rtl872xd_evb/board.cmake new file mode 100644 index 000000000000..79ab10f7e1d8 --- /dev/null +++ b/boards/realtek/rtl872xd_evb/board.cmake @@ -0,0 +1,6 @@ +# Copyright (c) 2024 Realtek Semiconductor Corp. +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(jlink "--device=Cortex-M33" "--speed=4000") + +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/realtek/rtl872xd_evb/board.yml b/boards/realtek/rtl872xd_evb/board.yml new file mode 100644 index 000000000000..300c8479ca02 --- /dev/null +++ b/boards/realtek/rtl872xd_evb/board.yml @@ -0,0 +1,5 @@ +board: + name: rtl872xd_evb + vendor: realtek + socs: + - name: rtl872xd diff --git a/boards/realtek/rtl872xd_evb/doc/index.rst b/boards/realtek/rtl872xd_evb/doc/index.rst new file mode 100644 index 000000000000..6f9fcc98f728 --- /dev/null +++ b/boards/realtek/rtl872xd_evb/doc/index.rst @@ -0,0 +1,90 @@ +.. zephyr:board:: rtl872xd_evb + +Overview +******** + +The Realtek RTL872xD Series is a Combo SoC that supports dual-band Wi-Fi 4 (2.4GHz + 5GHz) and +BLE 5.0 specifications. With ultra-low power consumption, complete encryption strategy and abundant +peripheral resources, it is widely in various products such as Home appliance control panel, +Smart door, Smart toy, Smart voice, Smart remote control, Bluetooth gateway, Headset, Wi-Fi gamepad, +Smart POS, etc. For more information, check `RTL872XD-EVB`_. + +The features include the following: + +- Dual cores: Real-M300 and Real-M200 +- 512KB + 64KB on-chip SRAM +- 802.11 a/b/g/n 1 x 1, 2.4GHz + 5GHz +- Supports BLE 5.0 +- Peripheral Interface: + + - Multi-communication interfaces: SPI x 2, UART x 4, I2C x 1 + - Hardware Key-scan interface supports up to 36 keys + - Hardware Quad-decoder supports statistical and comparison functions + - Hardware IR transceiver can easily adapt to various IR protocols + - SDIO/USB high speed interface (both host and slave) + - Supports real-time clock together with 18 channels of PWM output + - Supports 5 channels of touch pad and 6 channels of GDMA + - Supports 7 channels of normal 12-bit ADC and 1 channel of VBAT + - Integrated LCDC supports both RGB and I8080 interfaces + - Integrated hardware crypto engine supports AES256/192/128 and SHA256 + - Integrated audio codec + +For more information, Get application note and datasheet at `RTL872xCS/D Series`_ depending on chip you use. + +Supported Features +================== + +.. zephyr:board-supported-hw:: + +Prerequisites +************* + +Realtek HAL requires binary blobs in order work. Run the command below to retrieve those files. + +.. code-block:: console + + west blobs fetch hal_realtek + +.. note:: + + It is recommended running the command above after ``west update``. + +Building +******** + +Here is an example for building the :zephyr:code-sample:`hello_world` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: rtl872xd_evb + :goals: build + +Flashing +******** + +When the build finishes, downloading images into flash by `AmebaImageTool`_: + +See the ApplicationNote chapter Image Tool from documentation links for more details. + +#. Environment Requirements: EX. WinXP, Win 7 or later, Microsoft .NET Framework 4.0. +#. Connect chip and PC with USB wire. +#. Choose the Device profiles according to the chip you use. +#. Select the corresponding serial port and transmission baud rate. The default baud rate is 1500000. +#. Select the images to be programmed and set the start address and end address according to the flash layout, refer to [ameba_flashcfg.c/Flash_layout]. +#. Click the Download button and start. The progress bar will show the download progress of each image and the log window will show the operation status. + +.. note:: + + For an empty chip, the bootloader and app image shall be downloaded. + +Debugging +********* + +Using SWD through PB3(SWD_CLK) and PA27(SWD_DAT). + +References +********** + +.. _`RTL872XD-EVB`: https://www.realmcu.com/en/Home/Products/RTL872xCS-RTL872xD-Series# +.. _`RTL872xCS/D Series`: https://www.realmcu.com +.. _`AmebaImageTool`: https://github.com/Ameba-AIoT/ameba-rtos/tree/master/tools/ameba/ImageTool_Legacy/AmebaImageTool.exe diff --git a/boards/realtek/rtl872xd_evb/doc/rtl872xd_evb.webp b/boards/realtek/rtl872xd_evb/doc/rtl872xd_evb.webp new file mode 100644 index 0000000000000000000000000000000000000000..15314fd6c2b93aa4323fe4439620a25920076553 GIT binary patch literal 20638 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

    %Z#`VMxg*hHf1=q-&kRTW_NLb4!O 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 J+K$=)001%YKZXDR literal 0 HcmV?d00001 diff --git a/boards/realtek/rtl872xd_evb/rtl872xd_evb-pinctrl.dtsi b/boards/realtek/rtl872xd_evb/rtl872xd_evb-pinctrl.dtsi new file mode 100644 index 000000000000..2418704899b9 --- /dev/null +++ b/boards/realtek/rtl872xd_evb/rtl872xd_evb-pinctrl.dtsi @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor Corp. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&pinctrl { + compatible = "realtek,ameba-pinctrl"; + + /* PA30 is SWD_CLK, PA31 is SWD_DAT(both pull-up internally) */ + loguart_default: loguart_default { + group1 { + pinmux = , /* RXD */ + ; /* TXD */ + bias-pull-up; + }; + }; +}; diff --git a/boards/realtek/rtl872xd_evb/rtl872xd_evb.dts b/boards/realtek/rtl872xd_evb/rtl872xd_evb.dts new file mode 100644 index 000000000000..dbc9c3499b83 --- /dev/null +++ b/boards/realtek/rtl872xd_evb/rtl872xd_evb.dts @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor Corp. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include "rtl872xd_evb-pinctrl.dtsi" + +/ { + model = "RealTek AmebaD RTL872XD EVB"; + compatible = "realtek,rtl872xd_evb"; + + chosen { + zephyr,console = &loguart; + zephyr,shell-uart = &loguart; + zephyr,sram = &sram0; + zephyr,flash = &flash0; + }; +}; + +&flash0 { + reg = <0x0e000020 DT_SIZE_M(4)>; +}; + +&loguart { + status = "okay"; +}; + +&gpioa { + status = "okay"; +}; + +&gpiob { + status = "okay"; +}; diff --git a/boards/realtek/rtl872xd_evb/rtl872xd_evb.yaml b/boards/realtek/rtl872xd_evb/rtl872xd_evb.yaml new file mode 100644 index 000000000000..fa0b4d3cbe1b --- /dev/null +++ b/boards/realtek/rtl872xd_evb/rtl872xd_evb.yaml @@ -0,0 +1,16 @@ +# Copyright (c) 2024 Realtek Semiconductor Corp. +# SPDX-License-Identifier: Apache-2.0 + +identifier: rtl872xd_evb +name: Realtek rtl872xd evaluation board +vendor: realtek +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb +ram: 512 +flash: 4096 +supported: + - pinctrl + - serial diff --git a/boards/realtek/rtl872xd_evb/rtl872xd_evb_defconfig b/boards/realtek/rtl872xd_evb/rtl872xd_evb_defconfig new file mode 100644 index 000000000000..79f80e3ba4de --- /dev/null +++ b/boards/realtek/rtl872xd_evb/rtl872xd_evb_defconfig @@ -0,0 +1,15 @@ +# Copyright (c) 2024 Realtek Semiconductor Corp. +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_HW_STACK_PROTECTION=y + +# This board implies building Non-Secure firmware +CONFIG_TRUSTED_EXECUTION_NONSECURE=y + +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# Enable LogUart +CONFIG_SERIAL=y + +CONFIG_GPIO=y diff --git a/include/zephyr/dt-bindings/pinctrl/amebad-pinctrl.h b/include/zephyr/dt-bindings/pinctrl/amebad-pinctrl.h new file mode 100644 index 000000000000..da68b684ae86 --- /dev/null +++ b/include/zephyr/dt-bindings/pinctrl/amebad-pinctrl.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2024 Realtek Semiconductor Corp. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_AMEBAD_PINCTRL_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_AMEBAD_PINCTRL_H_ + +/* PINMUX Function definitions */ +#define AMEBA_GPIO 0 +#define AMEBA_UART 1 +#define AMEBA_UART_RTSCTS 2 +#define AMEBA_LOGUART 2 +#define AMEBA_SPIM 3 +#define AMEBA_SPIS 3 +#define AMEBA_RTC 4 +#define AMEBA_TIMINPUT 4 +#define AMEBA_IR 5 +#define AMEBA_SPIF 6 +#define AMEBA_I2C 7 +#define AMEBA_SDIOD 8 +#define AMEBA_SDIOH 8 +#define AMEBA_PWM 9 +#define AMEBA_PWM_HS 9 +#define AMEBA_PWM_LP 10 +#define AMEBA_SWD 11 +#define AMEBA_I2S 12 +#define AMEBA_DMIC 12 +#define AMEBA_LCD 13 +#define AMEBA_USB 14 +#define AMEBA_QDEC 15 +#define AMEBA_SGPIO 16 +#define AMEBA_RFE 18 +#define AMEBA_BTCOEX 19 +#define AMEBA_WIFIFW 20 +#define AMEBA_EXT_PCM 20 +#define AMEBA_EXT_BT 20 +#define AMEBA_BB_PIN 21 +#define AMEBA_SIC 22 +#define AMEBA_TIMINPUT_HS 22 +#define AMEBA_DBGPORT 23 +#define AMEBA_BBDBG 25 +#define AMEBA_EXT32K 28 +#define AMEBA_RTCOUT 28 +#define AMEBA_KEYSCAN_ROW 29 +#define AMEBA_KEYSCAN_COL 30 +#define AMEBA_WAKEUP 31 + +/* Define pins number: bit[14:13] port, bit[12:8] pin, bit[7:0] function ID */ +#define AMEBA_PORT_PIN(port, line) ((((port) - 'A') << 5) + (line)) +#define AMEBA_PINMUX(port, line, funcid) (((AMEBA_PORT_PIN(port, line)) << 8) | (funcid)) + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_AMEBAD_PINCTRL_H_ */ From 9b4501977b6763e59f7382aa59b4692e223e0bd1 Mon Sep 17 00:00:00 2001 From: Mark Wang Date: Tue, 26 Aug 2025 19:04:47 +0800 Subject: [PATCH 0749/3659] bluetooth: a2dp: implement remaining a2dp SBC codec API functions Add implementations for the following SBC codec parameter getter functions: bt_a2dp_sbc_get_channel_mode(): returns the channel mode (mono, dual, stereo, joint stereo); bt_a2dp_sbc_get_subband_num(): returns the number of subbands (4 or 8); bt_a2dp_sbc_get_block_length(): returns the block length (4, 8, 12, or 16); bt_a2dp_sbc_get_allocation_method(): returns the allocation method (SNR or loudness). These functions parse the SBC codec configuration parameters and return the corresponding values, completing the API defined in a2dp_codec_sbc.h. Signed-off-by: Mark Wang --- .../zephyr/bluetooth/classic/a2dp_codec_sbc.h | 32 ++++++++++ .../bluetooth/host/classic/a2dp_codec_sbc.c | 60 ++++++++++++++++++- 2 files changed, 91 insertions(+), 1 deletion(-) diff --git a/include/zephyr/bluetooth/classic/a2dp_codec_sbc.h b/include/zephyr/bluetooth/classic/a2dp_codec_sbc.h index 43f4c44f3355..2a8013d02d22 100644 --- a/include/zephyr/bluetooth/classic/a2dp_codec_sbc.h +++ b/include/zephyr/bluetooth/classic/a2dp_codec_sbc.h @@ -111,6 +111,14 @@ struct bt_a2dp_codec_sbc_params { */ uint8_t bt_a2dp_sbc_get_channel_num(struct bt_a2dp_codec_sbc_params *sbc_codec); +/** @brief get channel mode of a2dp sbc config. + * + * @param sbc_codec The a2dp sbc parameter. + * + * @return the channel mode. + */ +enum sbc_ch_mode bt_a2dp_sbc_get_channel_mode(struct bt_a2dp_codec_sbc_params *sbc_codec); + /** @brief get sample rate of a2dp sbc config. * * @param sbc_codec The a2dp sbc parameter. @@ -119,6 +127,30 @@ uint8_t bt_a2dp_sbc_get_channel_num(struct bt_a2dp_codec_sbc_params *sbc_codec); */ uint32_t bt_a2dp_sbc_get_sampling_frequency(struct bt_a2dp_codec_sbc_params *sbc_codec); +/** @brief get subband num of a2dp sbc config. + * + * @param sbc_codec The a2dp sbc parameter. + * + * @return the subband num. + */ +uint8_t bt_a2dp_sbc_get_subband_num(struct bt_a2dp_codec_sbc_params *sbc_codec); + +/** @brief get block length of a2dp sbc config. + * + * @param sbc_codec The a2dp sbc parameter. + * + * @return the block length. + */ +uint8_t bt_a2dp_sbc_get_block_length(struct bt_a2dp_codec_sbc_params *sbc_codec); + +/** @brief get allocation method of a2dp sbc config. + * + * @param sbc_codec The a2dp sbc parameter. + * + * @return the allocation method. + */ +enum sbc_alloc_mthd bt_a2dp_sbc_get_allocation_method(struct bt_a2dp_codec_sbc_params *sbc_codec); + #ifdef __cplusplus } #endif diff --git a/subsys/bluetooth/host/classic/a2dp_codec_sbc.c b/subsys/bluetooth/host/classic/a2dp_codec_sbc.c index 33c1a39a098f..601ab9a22f7b 100644 --- a/subsys/bluetooth/host/classic/a2dp_codec_sbc.c +++ b/subsys/bluetooth/host/classic/a2dp_codec_sbc.c @@ -14,7 +14,7 @@ #include #include - +#include uint8_t bt_a2dp_sbc_get_channel_num(struct bt_a2dp_codec_sbc_params *sbc_codec) { @@ -33,6 +33,23 @@ uint8_t bt_a2dp_sbc_get_channel_num(struct bt_a2dp_codec_sbc_params *sbc_codec) } } +enum sbc_ch_mode bt_a2dp_sbc_get_channel_mode(struct bt_a2dp_codec_sbc_params *sbc_codec) +{ + __ASSERT_NO_MSG(sbc_codec != NULL); + + if (sbc_codec->config[0] & A2DP_SBC_CH_MODE_MONO) { + return SBC_CH_MODE_MONO; + } else if (sbc_codec->config[0] & A2DP_SBC_CH_MODE_DUAL) { + return SBC_CH_MODE_DUAL_CHANNEL; + } else if (sbc_codec->config[0] & A2DP_SBC_CH_MODE_STEREO) { + return SBC_CH_MODE_STEREO; + } else if (sbc_codec->config[0] & A2DP_SBC_CH_MODE_JOINT) { + return SBC_CH_MODE_JOINT_STEREO; + } else { + return SBC_CH_MODE_MONO; + } +} + uint32_t bt_a2dp_sbc_get_sampling_frequency(struct bt_a2dp_codec_sbc_params *sbc_codec) { __ASSERT_NO_MSG(sbc_codec != NULL); @@ -49,3 +66,44 @@ uint32_t bt_a2dp_sbc_get_sampling_frequency(struct bt_a2dp_codec_sbc_params *sbc return 0U; } } + +uint8_t bt_a2dp_sbc_get_subband_num(struct bt_a2dp_codec_sbc_params *sbc_codec) +{ + __ASSERT_NO_MSG(sbc_codec != NULL); + + if (sbc_codec->config[1] & A2DP_SBC_SUBBAND_4) { + return 4U; + } else if (sbc_codec->config[1] & A2DP_SBC_SUBBAND_8) { + return 8U; + } else { + return 0U; + } +} + +uint8_t bt_a2dp_sbc_get_block_length(struct bt_a2dp_codec_sbc_params *sbc_codec) +{ + __ASSERT_NO_MSG(sbc_codec != NULL); + + if (sbc_codec->config[1] & A2DP_SBC_BLK_LEN_4) { + return 4U; + } else if (sbc_codec->config[1] & A2DP_SBC_BLK_LEN_8) { + return 8U; + } else if (sbc_codec->config[1] & A2DP_SBC_BLK_LEN_12) { + return 12U; + } else if (sbc_codec->config[1] & A2DP_SBC_BLK_LEN_16) { + return 16U; + } else { + return 0U; + } +} + +enum sbc_alloc_mthd bt_a2dp_sbc_get_allocation_method(struct bt_a2dp_codec_sbc_params *sbc_codec) +{ + __ASSERT_NO_MSG(sbc_codec != NULL); + + if (sbc_codec->config[1] & A2DP_SBC_ALLOC_MTHD_SNR) { + return SBC_ALLOC_MTHD_SNR; + } else { + return SBC_ALLOC_MTHD_LOUDNESS; + } +} From a72acbc807adad69da27b752d1ce69bf7054e4a2 Mon Sep 17 00:00:00 2001 From: Mark Wang Date: Tue, 26 Aug 2025 19:22:07 +0800 Subject: [PATCH 0750/3659] samples: bluetooth: a2dp: implement a2dp source sample implement the a2dp source sample. Signed-off-by: Mark Wang --- .../classic/a2dp_source/CMakeLists.txt | 10 + samples/bluetooth/classic/a2dp_source/Kconfig | 41 + .../bluetooth/classic/a2dp_source/README.rst | 31 + .../mimxrt1170_evk_mimxrt1176_cm7_B.conf | 2 + .../mimxrt1170_evk_mimxrt1176_cm7_B.overlay | 11 + .../bluetooth/classic/a2dp_source/prj.conf | 7 + .../bluetooth/classic/a2dp_source/sample.yaml | 21 + .../bluetooth/classic/a2dp_source/src/main.c | 710 ++++++++++++++++++ .../bluetooth/classic/a2dp_source/src/sine.h | 439 +++++++++++ 9 files changed, 1272 insertions(+) create mode 100644 samples/bluetooth/classic/a2dp_source/CMakeLists.txt create mode 100644 samples/bluetooth/classic/a2dp_source/Kconfig create mode 100644 samples/bluetooth/classic/a2dp_source/README.rst create mode 100644 samples/bluetooth/classic/a2dp_source/boards/mimxrt1170_evk_mimxrt1176_cm7_B.conf create mode 100644 samples/bluetooth/classic/a2dp_source/boards/mimxrt1170_evk_mimxrt1176_cm7_B.overlay create mode 100644 samples/bluetooth/classic/a2dp_source/prj.conf create mode 100644 samples/bluetooth/classic/a2dp_source/sample.yaml create mode 100644 samples/bluetooth/classic/a2dp_source/src/main.c create mode 100644 samples/bluetooth/classic/a2dp_source/src/sine.h diff --git a/samples/bluetooth/classic/a2dp_source/CMakeLists.txt b/samples/bluetooth/classic/a2dp_source/CMakeLists.txt new file mode 100644 index 000000000000..2fa9249268ce --- /dev/null +++ b/samples/bluetooth/classic/a2dp_source/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}) +project(a2dp_source) + +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources}) + +zephyr_library_include_directories(${ZEPHYR_BASE}/samples/bluetooth) diff --git a/samples/bluetooth/classic/a2dp_source/Kconfig b/samples/bluetooth/classic/a2dp_source/Kconfig new file mode 100644 index 000000000000..bd43a56f4741 --- /dev/null +++ b/samples/bluetooth/classic/a2dp_source/Kconfig @@ -0,0 +1,41 @@ +# +# Copyright 2025 NXP +# +# SPDX-License-Identifier: Apache-2.0 +# + +mainmenu "Bluetooth: A2DP Source" + +config BT_A2DP_SOURCE_DISCOVER_RESULT_COUNT + int "Maximum result count per device discovery" + default 10 + +config BT_A2DP_SOURCE_EPS_DISCOVER_COUNT + int "Maximum result count per a2dp endpoint discovery" + default 5 + +config BT_A2DP_SOURCE_SBC_BIT_RATE_DEFAULT + int "default sbc bit rate" + default 229 + +config BT_A2DP_SOURCE_DATA_SEND_INTERVAL + int "data send interval (ms)" + default 10 + +config BT_A2DP_SOURCE_DATA_BUF_SIZE + int "data buffer size (bytes)" + default 1000 + +config BT_A2DP_SOURCE_DATA_BUF_COUNT + int "data buffer count" + default 5 + +config BT_A2DP_SOURCE_DATA_SEND_WORKQ_STACK_SIZE + int "the data sending work queue stack size" + default 1024 + +config BT_A2DP_SOURCE_DATA_SEND_WORKQ_PRIORITY + int "the data sending work queue priority" + default SYSTEM_WORKQUEUE_PRIORITY + +source "Kconfig.zephyr" diff --git a/samples/bluetooth/classic/a2dp_source/README.rst b/samples/bluetooth/classic/a2dp_source/README.rst new file mode 100644 index 000000000000..451aca614ed3 --- /dev/null +++ b/samples/bluetooth/classic/a2dp_source/README.rst @@ -0,0 +1,31 @@ +.. zephyr:code-sample:: bluetooth_a2dp_source + :name: A2DP Source + :relevant-api: bt_a2dp bluetooth + + Use A2DP (Advanced Audio Distribution Profile) source functionality. + +Overview +******** + +This sample demonstrates the A2DP (Advanced Audio Distribution Profile) source +functionality using Zephyr's Bluetooth Classic APIs. The application acts as an +A2DP source device, it discovers and connects to a A2DP sink device such as +Bluetooth speaker and headphone, and streams audio data to it automatically. + +Requirements +************ + +* Running on the host with Bluetooth BR/EDR (Classic) support, or +* A board with Bluetooth BR/EDR (Classic) support + +Building and Running +******************** + +1. Build and flash the sample to the board. +2. The device will discover a2dp sink devices nearby. +3. Connect and stream audio automatically. + +This sample can be found under :zephyr_file:`samples/bluetooth/classic/a2dp_source` in +the Zephyr tree. + +See :zephyr:code-sample-category:`bluetooth` samples for details. diff --git a/samples/bluetooth/classic/a2dp_source/boards/mimxrt1170_evk_mimxrt1176_cm7_B.conf b/samples/bluetooth/classic/a2dp_source/boards/mimxrt1170_evk_mimxrt1176_cm7_B.conf new file mode 100644 index 000000000000..9e8851c73af1 --- /dev/null +++ b/samples/bluetooth/classic/a2dp_source/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/classic/a2dp_source/boards/mimxrt1170_evk_mimxrt1176_cm7_B.overlay b/samples/bluetooth/classic/a2dp_source/boards/mimxrt1170_evk_mimxrt1176_cm7_B.overlay new file mode 100644 index 000000000000..2571c82dc0e5 --- /dev/null +++ b/samples/bluetooth/classic/a2dp_source/boards/mimxrt1170_evk_mimxrt1176_cm7_B.overlay @@ -0,0 +1,11 @@ +/* + * Copyright 2024 - 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + chosen { + zephyr,sram = &dtcm; + }; +}; diff --git a/samples/bluetooth/classic/a2dp_source/prj.conf b/samples/bluetooth/classic/a2dp_source/prj.conf new file mode 100644 index 000000000000..daed4df0abd8 --- /dev/null +++ b/samples/bluetooth/classic/a2dp_source/prj.conf @@ -0,0 +1,7 @@ +CONFIG_BT=y +CONFIG_BT_CLASSIC=y +CONFIG_BT_AVDTP=y +CONFIG_BT_A2DP=y +CONFIG_BT_A2DP_SOURCE=y +CONFIG_BT_CENTRAL=y +CONFIG_BT_DEVICE_NAME="a2dp-source" diff --git a/samples/bluetooth/classic/a2dp_source/sample.yaml b/samples/bluetooth/classic/a2dp_source/sample.yaml new file mode 100644 index 000000000000..99bb9afb32cd --- /dev/null +++ b/samples/bluetooth/classic/a2dp_source/sample.yaml @@ -0,0 +1,21 @@ +sample: + name: Bluetooth A2DP Source +tests: + sample.bluetooth.a2dp.source: + harness: bluetooth + platform_allow: + - qemu_cortex_m3 + - qemu_x86 + tags: bluetooth + integration_platforms: + - qemu_cortex_m3 + sample.bluetooth.a2dp.source.no_blobs: + platform_allow: + - mimxrt1170_evk@B/mimxrt1176/cm7 + tags: + - bluetooth + - gap + extra_args: + - CONFIG_BUILD_ONLY_NO_BLOBS=y + timeout: 600 + build_only: true diff --git a/samples/bluetooth/classic/a2dp_source/src/main.c b/samples/bluetooth/classic/a2dp_source/src/main.c new file mode 100644 index 000000000000..70a789f613b4 --- /dev/null +++ b/samples/bluetooth/classic/a2dp_source/src/main.c @@ -0,0 +1,710 @@ +/* main.c - Application main entry point */ + +/* + * Copyright 2024-2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "sine.h" + +static struct bt_br_discovery_param br_discover; +static struct bt_br_discovery_result scan_result[CONFIG_BT_A2DP_SOURCE_DISCOVER_RESULT_COUNT]; +struct k_work discover_work; + +static struct bt_conn *default_conn; +struct bt_a2dp *default_a2dp; +static struct bt_a2dp_stream sbc_stream; +struct sbc_encoder encoder; + +BT_A2DP_SBC_SOURCE_EP_DEFAULT(sbc_source_ep); +static bool peer_sbc_found; +struct bt_a2dp_codec_ie sbc_sink_ep_capabilities; +static struct bt_a2dp_ep sbc_sink_ep = { + .codec_cap = &sbc_sink_ep_capabilities, +}; +BT_A2DP_SBC_EP_CFG_DEFAULT(sbc_cfg_default, A2DP_SBC_SAMP_FREQ_44100); + +/* sbc audio stream control variables */ +static int64_t ref_time; +static uint32_t a2dp_src_missed_count; +static volatile bool a2dp_src_playback; +static volatile int media_index; +static uint32_t a2dp_src_sf; +static uint8_t a2dp_src_nc; +static uint32_t send_samples_count; +static uint16_t send_count; +/* max pcm data size per interval. The max sample freq is 48K. + * interval * 48 * 2 (max channels) * 2 (sample width) * 2 (the worst case: send two intervals' + * data if timer is blocked) + */ +static uint8_t a2dp_pcm_buffer[CONFIG_BT_A2DP_SOURCE_DATA_SEND_INTERVAL * 48 * 2 * 2 * 2]; +NET_BUF_POOL_DEFINE(a2dp_tx_pool, CONFIG_BT_A2DP_SOURCE_DATA_BUF_COUNT, + BT_L2CAP_BUF_SIZE(CONFIG_BT_A2DP_SOURCE_DATA_BUF_SIZE), + CONFIG_BT_CONN_TX_USER_DATA_SIZE, NULL); +static void a2dp_playback_timeout_handler(struct k_timer *timer); +K_TIMER_DEFINE(a2dp_player_timer, a2dp_playback_timeout_handler, NULL); + +NET_BUF_POOL_DEFINE(sdp_discover_pool, 10, BT_L2CAP_BUF_SIZE(CONFIG_BT_L2CAP_TX_MTU), + CONFIG_BT_CONN_TX_USER_DATA_SIZE, NULL); + +struct k_work_q audio_play_work_q; +static K_KERNEL_STACK_DEFINE(audio_play_work_q_thread_stack, + CONFIG_BT_A2DP_SOURCE_DATA_SEND_WORKQ_STACK_SIZE); + +#define A2DP_VERSION 0x0104 + +static struct bt_sdp_attribute a2dp_source_attrs[] = { + BT_SDP_NEW_SERVICE, + BT_SDP_LIST( + BT_SDP_ATTR_SVCLASS_ID_LIST, + BT_SDP_TYPE_SIZE_VAR(BT_SDP_SEQ8, 3), + BT_SDP_DATA_ELEM_LIST( + { + BT_SDP_TYPE_SIZE(BT_SDP_UUID16), + BT_SDP_ARRAY_16(BT_SDP_AUDIO_SOURCE_SVCLASS) + }, + ) + ), + BT_SDP_LIST( + BT_SDP_ATTR_PROTO_DESC_LIST, + BT_SDP_TYPE_SIZE_VAR(BT_SDP_SEQ8, 16), + BT_SDP_DATA_ELEM_LIST( + { + BT_SDP_TYPE_SIZE_VAR(BT_SDP_SEQ8, 6), + BT_SDP_DATA_ELEM_LIST( + { + BT_SDP_TYPE_SIZE(BT_SDP_UUID16), + BT_SDP_ARRAY_16(BT_SDP_PROTO_L2CAP) + }, + { + BT_SDP_TYPE_SIZE(BT_SDP_UINT16), + BT_SDP_ARRAY_16(BT_UUID_AVDTP_VAL) + }, + ) + }, + { + BT_SDP_TYPE_SIZE_VAR(BT_SDP_SEQ8, 6), + BT_SDP_DATA_ELEM_LIST( + { + BT_SDP_TYPE_SIZE(BT_SDP_UUID16), + BT_SDP_ARRAY_16(BT_UUID_AVDTP_VAL) + }, + { + BT_SDP_TYPE_SIZE(BT_SDP_UINT16), + BT_SDP_ARRAY_16(AVDTP_VERSION) + }, + ) + }, + ) + ), + BT_SDP_LIST( + BT_SDP_ATTR_PROFILE_DESC_LIST, + BT_SDP_TYPE_SIZE_VAR(BT_SDP_SEQ8, 8), + BT_SDP_DATA_ELEM_LIST( + { + BT_SDP_TYPE_SIZE_VAR(BT_SDP_SEQ8, 6), + BT_SDP_DATA_ELEM_LIST( + { + BT_SDP_TYPE_SIZE(BT_SDP_UUID16), + BT_SDP_ARRAY_16(BT_SDP_ADVANCED_AUDIO_SVCLASS) + }, + { + BT_SDP_TYPE_SIZE(BT_SDP_UINT16), + BT_SDP_ARRAY_16(A2DP_VERSION) + }, + ) + }, + ) + ), + BT_SDP_SERVICE_NAME("A2DPSource"), + BT_SDP_SUPPORTED_FEATURES(0x0001U), +}; + +static struct bt_sdp_record a2dp_source_rec = BT_SDP_RECORD(a2dp_source_attrs); + +static bool a2dp_produce_media_check(uint32_t samples_num) +{ + uint16_t medialen; + + /* Music Audio is Stereo */ + medialen = (samples_num * a2dp_src_nc * 2); + + /* need to use a2dp_pcm_buffer to do memcpy */ + if ((a2dp_src_nc == 1) || ((media_index + (samples_num << 2)) > sizeof(media_data))) { + if (medialen > sizeof(a2dp_pcm_buffer)) { + return false; + } + } + + return true; +} + +static uint8_t *a2dp_produce_media(uint32_t samples_num) +{ + uint8_t *media = NULL; + uint16_t medialen; + + /* Music Audio is Stereo */ + medialen = (samples_num * a2dp_src_nc * 2); + + /* For mono or dual configuration, skip alternative samples */ + if (a2dp_src_nc == 1) { + uint16_t index; + + media = (uint8_t *)&a2dp_pcm_buffer[0]; + + for (index = 0; index < samples_num; index++) { + media[(2 * index)] = *((uint8_t *)media_data + media_index); + media[(2 * index) + 1] = *((uint8_t *)media_data + media_index + 1); + /* Update the tone index */ + media_index += 4u; + if (media_index >= sizeof(media_data)) { + media_index = 0U; + } + } + } else { + if ((media_index + (samples_num << 2)) > sizeof(media_data)) { + media = (uint8_t *)&a2dp_pcm_buffer[0]; + memcpy(media, ((uint8_t *)media_data + media_index), + sizeof(media_data) - media_index); + memcpy(&media[sizeof(media_data) - media_index], + ((uint8_t *)media_data), + ((samples_num << 2) - (sizeof(media_data) - media_index))); + /* Update the tone index */ + media_index = ((samples_num << 2) - + (sizeof(media_data) - media_index)); + } else { + media = ((uint8_t *)media_data + media_index); + /* Update the tone index */ + media_index += (samples_num << 2); + if (media_index >= sizeof(media_data)) { + media_index = 0U; + } + } + } + + return media; +} + +static void audio_play_check(void) +{ + uint32_t a2dp_src_num_samples; + uint32_t pcm_frame_samples; + uint8_t frame_num; + struct net_buf *buf; + uint32_t pdu_len; + + a2dp_src_num_samples = (uint16_t)((CONFIG_BT_A2DP_SOURCE_DATA_SEND_INTERVAL * a2dp_src_sf) + / 1000); + pcm_frame_samples = sbc_frame_samples(&encoder); + frame_num = a2dp_src_num_samples / pcm_frame_samples; + if (frame_num * pcm_frame_samples < a2dp_src_num_samples) { + frame_num++; + } + a2dp_src_num_samples = frame_num * pcm_frame_samples; + + buf = bt_a2dp_stream_create_pdu(&a2dp_tx_pool, K_FOREVER); + pdu_len = frame_num * sbc_frame_encoded_bytes(&encoder); + + if (pdu_len > net_buf_tailroom(buf)) { + printk("need increase buf size %d > %d\n", pdu_len, net_buf_tailroom(buf)); + } + + pdu_len += buf->len; + if (pdu_len > bt_a2dp_get_mtu(&sbc_stream)) { + printk("need decrease CONFIG_BT_A2DP_SOURCE_DATA_SEND_INTERVAL %d > %d\n", pdu_len, + bt_a2dp_get_mtu(&sbc_stream)); + } + + if (!a2dp_produce_media_check(a2dp_src_num_samples)) { + printk("need increase a2dp_pcm_buffer\n"); + } + + net_buf_unref(buf); +} + +static void audio_work_handler(struct k_work *work) +{ + int64_t period_ms; + uint32_t a2dp_src_num_samples; + uint8_t *pcm_data; + uint8_t index; + uint32_t pcm_frame_size; + uint32_t pcm_frame_samples; + uint32_t encoded_frame_size; + struct net_buf *buf; + uint8_t *sbc_hdr; + uint32_t pdu_len; + uint32_t out_size; + int err; + uint8_t frame_num = 0; + uint8_t remaining_frame_num; + + /* If stopped then return */ + if (!a2dp_src_playback || default_a2dp == NULL) { + return; + } + + buf = bt_a2dp_stream_create_pdu(&a2dp_tx_pool, K_FOREVER); + if (buf == NULL) { + /* fail */ + printk("no buf\n"); + return; + } + + period_ms = k_uptime_delta(&ref_time); + + pcm_frame_size = sbc_frame_bytes(&encoder); + pcm_frame_samples = sbc_frame_samples(&encoder); + encoded_frame_size = sbc_frame_encoded_bytes(&encoder); + + sbc_hdr = net_buf_add(buf, 1u); + /* Get the number of samples */ + a2dp_src_num_samples = (uint16_t)((period_ms * a2dp_src_sf) / 1000); + a2dp_src_missed_count += (uint32_t)((period_ms * a2dp_src_sf) % 1000); + a2dp_src_missed_count += ((a2dp_src_num_samples % pcm_frame_samples) * 1000); + a2dp_src_num_samples = (a2dp_src_num_samples / pcm_frame_samples) * pcm_frame_samples; + remaining_frame_num = a2dp_src_num_samples / pcm_frame_samples; + + pdu_len = buf->len + remaining_frame_num * encoded_frame_size; + + /* Raw adjust for the drift */ + while (a2dp_src_missed_count >= (1000 * pcm_frame_samples)) { + pdu_len += encoded_frame_size; + a2dp_src_num_samples += pcm_frame_samples; + remaining_frame_num++; + a2dp_src_missed_count -= (1000 * pcm_frame_samples); + } + + do { + frame_num = remaining_frame_num; + /* adjust the buf size */ + while ((pdu_len - buf->len > net_buf_tailroom(buf)) || + (pdu_len > bt_a2dp_get_mtu(&sbc_stream)) || + (!a2dp_produce_media_check(a2dp_src_num_samples))) { + pdu_len -= encoded_frame_size; + a2dp_src_missed_count += 1000 * pcm_frame_samples; + a2dp_src_num_samples -= pcm_frame_samples; + frame_num--; + } + + pcm_data = a2dp_produce_media(a2dp_src_num_samples); + if (pcm_data == NULL) { + net_buf_unref(buf); + printk("no media data\n"); + return; + } + + for (index = 0; index < frame_num; index++) { + out_size = sbc_encode(&encoder, + (uint8_t *)&pcm_data[index * pcm_frame_size], + net_buf_tail(buf)); + if (encoded_frame_size != out_size) { + printk("sbc encode fail\n"); + continue; + } + + net_buf_add(buf, encoded_frame_size); + } + + *sbc_hdr = (uint8_t)BT_A2DP_SBC_MEDIA_HDR_ENCODE(frame_num, 0, 0, 0); + + err = bt_a2dp_stream_send(&sbc_stream, buf, send_count, send_samples_count); + if (err != 0) { + net_buf_unref(buf); + printk(" Failed to send SBC audio data on streams(%d)\n", err); + } + + send_count++; + send_samples_count += a2dp_src_num_samples; + remaining_frame_num -= frame_num; + } while (remaining_frame_num > 0); +} + +static K_WORK_DEFINE(audio_work, audio_work_handler); + +static void a2dp_playback_timeout_handler(struct k_timer *timer) +{ + k_work_submit_to_queue(&audio_play_work_q, &audio_work); +} + +static void sbc_stream_configured(struct bt_a2dp_stream *stream) +{ + struct sbc_encoder_init_param param; + struct bt_a2dp_codec_sbc_params *sbc_config = (struct bt_a2dp_codec_sbc_params *) + &sbc_cfg_default.codec_config->codec_ie[0]; + + printk("stream configured\n"); + + a2dp_src_sf = bt_a2dp_sbc_get_sampling_frequency(sbc_config); + a2dp_src_nc = bt_a2dp_sbc_get_channel_num(sbc_config); + + param.bit_rate = CONFIG_BT_A2DP_SOURCE_SBC_BIT_RATE_DEFAULT; + param.samp_freq = a2dp_src_sf; + param.blk_len = bt_a2dp_sbc_get_block_length(sbc_config); + param.subband = bt_a2dp_sbc_get_subband_num(sbc_config); + param.alloc_mthd = bt_a2dp_sbc_get_allocation_method(sbc_config); + param.ch_mode = bt_a2dp_sbc_get_channel_mode(sbc_config); + param.ch_num = bt_a2dp_sbc_get_channel_num(sbc_config); + param.min_bitpool = sbc_config->min_bitpool; + param.max_bitpool = sbc_config->max_bitpool; + + if (sbc_setup_encoder(&encoder, ¶m) != 0) { + printk("sbc encoder initialization fail\n"); + return; + } + + bt_a2dp_stream_establish(stream); +} + +static void sbc_stream_established(struct bt_a2dp_stream *stream) +{ + printk("stream established\n"); + audio_play_check(); + bt_a2dp_stream_start(&sbc_stream); +} + +static void sbc_stream_released(struct bt_a2dp_stream *stream) +{ + printk("stream released\n"); + k_timer_stop(&a2dp_player_timer); +} + +static void sbc_stream_started(struct bt_a2dp_stream *stream) +{ + uint32_t audio_time_interval = CONFIG_BT_A2DP_SOURCE_DATA_SEND_INTERVAL; + + printk("stream started\n"); + /* Start Audio Source */ + a2dp_src_playback = true; + + k_uptime_delta(&ref_time); + k_timer_start(&a2dp_player_timer, K_MSEC(audio_time_interval), K_MSEC(audio_time_interval)); +} + +static struct bt_a2dp_stream_ops sbc_stream_ops = { + .configured = sbc_stream_configured, + .established = sbc_stream_established, + .released = sbc_stream_released, + .started = sbc_stream_started, +}; + +static uint8_t a2dp_discover_ep_cb(struct bt_a2dp *a2dp, struct bt_a2dp_ep_info *info, + struct bt_a2dp_ep **ep) +{ + if (peer_sbc_found) { + int err; + + bt_a2dp_stream_cb_register(&sbc_stream, &sbc_stream_ops); + err = bt_a2dp_stream_config(a2dp, &sbc_stream, + &sbc_source_ep, &sbc_sink_ep, + &sbc_cfg_default); + if (err != 0) { + printk("fail to configure\n"); + } + + return BT_A2DP_DISCOVER_EP_STOP; + } + + if (info != NULL) { + printk("find one endpoint:"); + + if (info->codec_type == BT_A2DP_SBC) { + printk("it is SBC codec and use it\n"); + + if (ep != NULL && !peer_sbc_found) { + peer_sbc_found = true; + *ep = &sbc_sink_ep; + } + } else { + printk("it is not SBC codecs\n"); + } + } + + return BT_A2DP_DISCOVER_EP_CONTINUE; +} + +static struct bt_avdtp_sep_info found_seps[CONFIG_BT_A2DP_SOURCE_EPS_DISCOVER_COUNT]; + +static struct bt_a2dp_discover_param ep_discover_param = { + .cb = a2dp_discover_ep_cb, + .seps_info = &found_seps[0], + .sep_count = CONFIG_BT_A2DP_SOURCE_EPS_DISCOVER_COUNT, +}; + +static void app_a2dp_connected(struct bt_a2dp *a2dp, int err) +{ + if (err == 0) { + peer_sbc_found = false; + + err = bt_a2dp_discover(a2dp, &ep_discover_param); + if (err != 0) { + printk("fail to discover\n"); + } + + printk("a2dp connected success\n"); + } else { + if (default_a2dp != NULL) { + default_a2dp = NULL; + } + + printk("a2dp connected fail\n"); + } +} + +static void app_a2dp_disconnected(struct bt_a2dp *a2dp) +{ + if (default_a2dp != NULL) { + default_a2dp = NULL; + } + + a2dp_src_playback = false; + /* stop timer */ + k_timer_stop(&a2dp_player_timer); + printk("a2dp disconnected\n"); +} + +static uint8_t sdp_discover_cb(struct bt_conn *conn, struct bt_sdp_client_result *result, + const struct bt_sdp_discover_params *params) +{ + int err; + uint16_t value; + + printk("Discover done\n"); + + if (result != NULL && result->resp_buf != NULL) { + err = bt_sdp_get_proto_param(result->resp_buf, BT_SDP_PROTO_L2CAP, &value); + + if (err != 0) { + printk("PSM is not found\n"); + } else if (value == BT_UUID_AVDTP_VAL) { + printk("The A2DP server found, connecting a2dp\n"); + default_a2dp = bt_a2dp_connect(conn); + if (default_a2dp == NULL) { + printk("Fail to create A2DP connection (err %d)\n", err); + } + } + } + + return BT_SDP_DISCOVER_UUID_STOP; +} + +static struct bt_sdp_discover_params sdp_discover = { + .type = BT_SDP_DISCOVER_SERVICE_SEARCH_ATTR, + .func = sdp_discover_cb, + .pool = &sdp_discover_pool, + .uuid = BT_UUID_DECLARE_16(BT_SDP_AUDIO_SINK_SVCLASS), +}; + +static void connected(struct bt_conn *conn, uint8_t err) +{ + int res; + + if (err != 0) { + if (default_conn != NULL) { + default_conn = NULL; + } + + printk("Connection failed, err 0x%02x %s\n", err, bt_hci_err_to_str(err)); + } else { + if (default_conn == conn) { + struct bt_conn_info info; + + bt_conn_get_info(conn, &info); + if (info.type != BT_CONN_TYPE_BR) { + return; + } + + /* + * Do an SDP Query on Successful ACL connection complete with the + * required device + */ + res = bt_sdp_discover(default_conn, &sdp_discover); + if (res != 0) { + printk("SDP discovery failed (err %d)\n", res); + } else { + printk("SDP discovery started\n"); + } + printk("Connected\n"); + } + } +} + +static void disconnected(struct bt_conn *conn, uint8_t reason) +{ + printk("Disconnected, reason 0x%02x %s\n", reason, bt_hci_err_to_str(reason)); + + if (default_conn == conn) { + default_conn = NULL; + } +} + +static void security_changed(struct bt_conn *conn, bt_security_t level, enum bt_security_err err) +{ + char addr[BT_ADDR_LE_STR_LEN]; + struct bt_conn_info info; + + bt_conn_get_info(conn, &info); + + bt_addr_to_str(info.br.dst, addr, sizeof(addr)); + + printk("Security changed: %s level %u, err %s(%d)\n", addr, level, + bt_security_err_to_str(err), err); +} + +static struct bt_conn_cb conn_callbacks = { + .connected = connected, + .disconnected = disconnected, + .security_changed = security_changed, +}; + +static void discovery_timeout_cb(const struct bt_br_discovery_result *results, size_t count) +{ + char addr[BT_ADDR_LE_STR_LEN]; + const uint8_t *eir; + bool cod_a2dp = false; + static uint8_t temp[240]; + size_t len = sizeof(results->eir); + uint8_t major_device; + uint8_t minor_device; + size_t i; + + for (i = 0; i < count; i++) { + bt_addr_to_str(&results[i].addr, addr, sizeof(addr)); + printk("Device[%d]: %s, rssi %d, cod 0x%02x%02x%02x", i, addr, results[i].rssi, + results[i].cod[0], results[i].cod[1], results[i].cod[2]); + + major_device = (uint8_t)BT_COD_MAJOR_DEVICE_CLASS(results[i].cod); + minor_device = (uint8_t)BT_COD_MINOR_DEVICE_CLASS(results[i].cod); + + if ((major_device & BT_COD_MAJOR_AUDIO_VIDEO) != 0 && + (minor_device & BT_COD_MAJOR_AUDIO_VIDEO_MINOR_WEARABLE_HEADSET) != 0) { + cod_a2dp = true; + } + + eir = results[i].eir; + + while ((eir[0] > 2) && (len > eir[0])) { + switch (eir[1]) { + case BT_DATA_NAME_SHORTENED: + case BT_DATA_NAME_COMPLETE: + memcpy(temp, &eir[2], eir[0] - 1); + temp[eir[0] - 1] = '\0'; /* Set end flag */ + printk(", name %s", temp); + break; + default: + /* Skip the EIR */ + break; + } + len = len - eir[0] - 1; + eir = eir + eir[0] + 1; + } + printk("\n"); + + if (cod_a2dp) { + break; + } + } + + if (!cod_a2dp) { + (void)k_work_submit(&discover_work); + } else { + (void)k_work_cancel(&discover_work); + default_conn = bt_conn_create_br(&results[i].addr, BT_BR_CONN_PARAM_DEFAULT); + + if (default_conn == NULL) { + printk("Fail to create the connection\n"); + } else { + bt_conn_unref(default_conn); + } + } +} + +static void discover_work_handler(struct k_work *work) +{ + int err; + + br_discover.length = 10; + br_discover.limited = false; + + err = bt_br_discovery_start(&br_discover, scan_result, + CONFIG_BT_A2DP_SOURCE_DISCOVER_RESULT_COUNT); + if (err != 0) { + printk("Fail to start discovery (err %d)\n", err); + return; + } +} + +static struct bt_br_discovery_cb discovery_cb = { + .timeout = discovery_timeout_cb, +}; + +static struct bt_a2dp_cb a2dp_cb = { + .connected = app_a2dp_connected, + .disconnected = app_a2dp_disconnected, +}; + +static void bt_ready(int err) +{ + if (err != 0) { + printk("Bluetooth init failed (err %d)\n", err); + return; + } + + if (IS_ENABLED(CONFIG_SETTINGS)) { + settings_load(); + } + + printk("Bluetooth initialized\n"); + + bt_conn_cb_register(&conn_callbacks); + + bt_br_discovery_cb_register(&discovery_cb); + + bt_sdp_register_service(&a2dp_source_rec); + + bt_a2dp_register_ep(&sbc_source_ep, BT_AVDTP_AUDIO, BT_AVDTP_SOURCE); + + bt_a2dp_register_cb(&a2dp_cb); + + k_work_queue_init(&audio_play_work_q); + k_work_queue_start(&audio_play_work_q, audio_play_work_q_thread_stack, + CONFIG_BT_A2DP_SOURCE_DATA_SEND_WORKQ_STACK_SIZE, + K_PRIO_COOP(CONFIG_BT_A2DP_SOURCE_DATA_SEND_WORKQ_PRIORITY), NULL); + k_thread_name_set(&audio_play_work_q.thread, "audio play"); + + k_work_init(&discover_work, discover_work_handler); + + (void)k_work_submit(&discover_work); +} + +int main(void) +{ + int err; + + printk("Bluetooth A2DP Source demo start...\n"); + + err = bt_enable(bt_ready); + if (err != 0) { + printk("Bluetooth init failed (err %d)\n", err); + } + return 0; +} diff --git a/samples/bluetooth/classic/a2dp_source/src/sine.h b/samples/bluetooth/classic/a2dp_source/src/sine.h new file mode 100644 index 000000000000..90fecda15046 --- /dev/null +++ b/samples/bluetooth/classic/a2dp_source/src/sine.h @@ -0,0 +1,439 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_SINE_H_ +#define ZEPHYR_INCLUDE_SINE_H_ + +static const uint8_t media_data[] = { + 0x00, 0x00, 0x00, 0x00, 0x08, 0x0b, 0x08, 0x0b, 0xbb, 0x15, 0xbb, 0x15, 0xc9, 0x1f, 0xc9, + 0x1f, 0xe4, 0x28, 0xe4, 0x28, 0xc8, 0x30, 0xc8, 0x30, 0x38, 0x37, 0x38, 0x37, 0x03, 0x3c, + 0x03, 0x3c, 0x04, 0x3f, 0x04, 0x3f, 0x25, 0x40, 0x25, 0x40, 0x5d, 0x3f, 0x5d, 0x3f, 0xb1, + 0x3c, 0xb1, 0x3c, 0x38, 0x38, 0x38, 0x38, 0x11, 0x32, 0x11, 0x32, 0x6d, 0x2a, 0x6d, 0x2a, + 0x85, 0x21, 0x85, 0x21, 0x9e, 0x17, 0x9e, 0x17, 0x02, 0x0d, 0x02, 0x0d, 0x04, 0x02, 0x04, + 0x02, 0xf6, 0xf6, 0xf6, 0xf6, 0x2d, 0xec, 0x2d, 0xec, 0xfb, 0xe1, 0xfb, 0xe1, 0xae, 0xd8, + 0xae, 0xd8, 0x8d, 0xd0, 0x8d, 0xd0, 0xd6, 0xc9, 0xd6, 0xc9, 0xbb, 0xc4, 0xbb, 0xc4, 0x65, + 0xc1, 0x65, 0xc1, 0xeb, 0xbf, 0xeb, 0xbf, 0x5b, 0xc0, 0x5b, 0xc0, 0xaf, 0xc2, 0xaf, 0xc2, + 0xd7, 0xc6, 0xd7, 0xc6, 0xb3, 0xcc, 0xb3, 0xcc, 0x16, 0xd4, 0x16, 0xd4, 0xc7, 0xdc, 0xc7, + 0xdc, 0x86, 0xe6, 0x86, 0xe6, 0x06, 0xf1, 0x06, 0xf1, 0xf9, 0xfb, 0xf9, 0xfb, 0x0a, 0x07, + 0x0a, 0x07, 0xe6, 0x11, 0xe6, 0x11, 0x39, 0x1c, 0x39, 0x1c, 0xb5, 0x25, 0xb5, 0x25, 0x12, + 0x2e, 0x12, 0x2e, 0x0f, 0x35, 0x0f, 0x35, 0x78, 0x3a, 0x78, 0x3a, 0x23, 0x3e, 0x23, 0x3e, + 0xf4, 0x3f, 0xf4, 0x3f, 0xde, 0x3f, 0xde, 0x3f, 0xe1, 0x3d, 0xe1, 0x3d, 0x0c, 0x3a, 0x0c, + 0x3a, 0x7c, 0x34, 0x7c, 0x34, 0x5d, 0x2d, 0x5d, 0x2d, 0xe3, 0x24, 0xe3, 0x24, 0x51, 0x1b, + 0x51, 0x1b, 0xee, 0x10, 0xee, 0x10, 0x0a, 0x06, 0x0a, 0x06, 0xf7, 0xfa, 0xf7, 0xfa, 0x0c, + 0xf0, 0x0c, 0xf0, 0x9a, 0xe5, 0x9a, 0xe5, 0xf1, 0xdb, 0xf1, 0xdb, 0x5b, 0xd3, 0x5b, 0xd3, + 0x1a, 0xcc, 0x1a, 0xcc, 0x64, 0xc6, 0x64, 0xc6, 0x65, 0xc2, 0x65, 0xc2, 0x3c, 0xc0, 0x3c, + 0xc0, 0xfa, 0xbf, 0xfa, 0xbf, 0x9f, 0xc1, 0x9f, 0xc1, 0x20, 0xc5, 0x20, 0xc5, 0x62, 0xca, + 0x62, 0xca, 0x3c, 0xd1, 0x3c, 0xd1, 0x7b, 0xd9, 0x7b, 0xd9, 0xe0, 0xe2, 0xe0, 0xe2, 0x23, + 0xed, 0x23, 0xed, 0xf6, 0xf7, 0xf6, 0xf7, 0x06, 0x03, 0x06, 0x03, 0xff, 0x0d, 0xff, 0x0d, + 0x8d, 0x18, 0x8d, 0x18, 0x60, 0x22, 0x60, 0x22, 0x2d, 0x2b, 0x2d, 0x2b, 0xb1, 0x32, 0xb1, + 0x32, 0xb2, 0x38, 0xb2, 0x38, 0x03, 0x3d, 0x03, 0x3d, 0x83, 0x3f, 0x83, 0x3f, 0x1f, 0x40, + 0x1f, 0x40, 0xd2, 0x3e, 0xd2, 0x3e, 0xa6, 0x3b, 0xa6, 0x3b, 0xb3, 0x36, 0xb3, 0x36, 0x1f, + 0x30, 0x1f, 0x30, 0x1c, 0x28, 0x1c, 0x28, 0xe8, 0x1e, 0xe8, 0x1e, 0xc8, 0x14, 0xc8, 0x14, + 0x09, 0x0a, 0x09, 0x0a, 0xfe, 0xfe, 0xfe, 0xfe, 0xfb, 0xf3, 0xfb, 0xf3, 0x53, 0xe9, 0x53, + 0xe9, 0x58, 0xdf, 0x58, 0xdf, 0x56, 0xd6, 0x56, 0xd6, 0x92, 0xce, 0x92, 0xce, 0x47, 0xc8, + 0x47, 0xc8, 0xa4, 0xc3, 0xa4, 0xc3, 0xce, 0xc0, 0xce, 0xc0, 0xd9, 0xbf, 0xd9, 0xbf, 0xce, + 0xc0, 0xce, 0xc0, 0xa4, 0xc3, 0xa4, 0xc3, 0x47, 0xc8, 0x47, 0xc8, 0x92, 0xce, 0x92, 0xce, + 0x56, 0xd6, 0x56, 0xd6, 0x58, 0xdf, 0x58, 0xdf, 0x53, 0xe9, 0x53, 0xe9, 0xfb, 0xf3, 0xfb, + 0xf3, 0xfe, 0xfe, 0xfe, 0xfe, 0x09, 0x0a, 0x09, 0x0a, 0xc8, 0x14, 0xc8, 0x14, 0xe8, 0x1e, + 0xe8, 0x1e, 0x1c, 0x28, 0x1c, 0x28, 0x1f, 0x30, 0x1f, 0x30, 0xb3, 0x36, 0xb3, 0x36, 0xa6, + 0x3b, 0xa6, 0x3b, 0xd2, 0x3e, 0xd2, 0x3e, 0x1f, 0x40, 0x1f, 0x40, 0x83, 0x3f, 0x83, 0x3f, + 0x03, 0x3d, 0x03, 0x3d, 0xb2, 0x38, 0xb2, 0x38, 0xb1, 0x32, 0xb1, 0x32, 0x2d, 0x2b, 0x2d, + 0x2b, 0x60, 0x22, 0x60, 0x22, 0x8d, 0x18, 0x8d, 0x18, 0xff, 0x0d, 0xff, 0x0d, 0x06, 0x03, + 0x06, 0x03, 0xf6, 0xf7, 0xf6, 0xf7, 0x23, 0xed, 0x23, 0xed, 0xe0, 0xe2, 0xe0, 0xe2, 0x7b, + 0xd9, 0x7b, 0xd9, 0x3c, 0xd1, 0x3c, 0xd1, 0x62, 0xca, 0x62, 0xca, 0x20, 0xc5, 0x20, 0xc5, + 0x9f, 0xc1, 0x9f, 0xc1, 0xfa, 0xbf, 0xfa, 0xbf, 0x3c, 0xc0, 0x3c, 0xc0, 0x65, 0xc2, 0x65, + 0xc2, 0x64, 0xc6, 0x64, 0xc6, 0x1a, 0xcc, 0x1a, 0xcc, 0x5b, 0xd3, 0x5b, 0xd3, 0xf1, 0xdb, + 0xf1, 0xdb, 0x9a, 0xe5, 0x9a, 0xe5, 0x0c, 0xf0, 0x0c, 0xf0, 0xf7, 0xfa, 0xf7, 0xfa, 0x0a, + 0x06, 0x0a, 0x06, 0xee, 0x10, 0xee, 0x10, 0x51, 0x1b, 0x51, 0x1b, 0xe3, 0x24, 0xe3, 0x24, + 0x5d, 0x2d, 0x5d, 0x2d, 0x7c, 0x34, 0x7c, 0x34, 0x0c, 0x3a, 0x0c, 0x3a, 0xe1, 0x3d, 0xe1, + 0x3d, 0xde, 0x3f, 0xde, 0x3f, 0xf4, 0x3f, 0xf4, 0x3f, 0x23, 0x3e, 0x23, 0x3e, 0x78, 0x3a, + 0x78, 0x3a, 0x0f, 0x35, 0x0f, 0x35, 0x12, 0x2e, 0x12, 0x2e, 0xb5, 0x25, 0xb5, 0x25, 0x39, + 0x1c, 0x39, 0x1c, 0xe6, 0x11, 0xe6, 0x11, 0x0a, 0x07, 0x0a, 0x07, 0xf9, 0xfb, 0xf9, 0xfb, + 0x06, 0xf1, 0x06, 0xf1, 0x86, 0xe6, 0x86, 0xe6, 0xc7, 0xdc, 0xc7, 0xdc, 0x16, 0xd4, 0x16, + 0xd4, 0xb3, 0xcc, 0xb3, 0xcc, 0xd7, 0xc6, 0xd7, 0xc6, 0xaf, 0xc2, 0xaf, 0xc2, 0x5b, 0xc0, + 0x5b, 0xc0, 0xeb, 0xbf, 0xeb, 0xbf, 0x65, 0xc1, 0x65, 0xc1, 0xbb, 0xc4, 0xbb, 0xc4, 0xd6, + 0xc9, 0xd6, 0xc9, 0x8d, 0xd0, 0x8d, 0xd0, 0xae, 0xd8, 0xae, 0xd8, 0xfb, 0xe1, 0xfb, 0xe1, + 0x2d, 0xec, 0x2d, 0xec, 0xf6, 0xf6, 0xf6, 0xf6, 0x04, 0x02, 0x04, 0x02, 0x02, 0x0d, 0x02, + 0x0d, 0x9e, 0x17, 0x9e, 0x17, 0x85, 0x21, 0x85, 0x21, 0x6d, 0x2a, 0x6d, 0x2a, 0x11, 0x32, + 0x11, 0x32, 0x38, 0x38, 0x38, 0x38, 0xb1, 0x3c, 0xb1, 0x3c, 0x5d, 0x3f, 0x5d, 0x3f, 0x25, + 0x40, 0x25, 0x40, 0x04, 0x3f, 0x04, 0x3f, 0x03, 0x3c, 0x03, 0x3c, 0x38, 0x37, 0x38, 0x37, + 0xc8, 0x30, 0xc8, 0x30, 0xe4, 0x28, 0xe4, 0x28, 0xc9, 0x1f, 0xc9, 0x1f, 0xbb, 0x15, 0xbb, + 0x15, 0x08, 0x0b, 0x08, 0x0b, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xf4, 0xf8, 0xf4, 0x45, 0xea, + 0x45, 0xea, 0x37, 0xe0, 0x37, 0xe0, 0x1c, 0xd7, 0x1c, 0xd7, 0x38, 0xcf, 0x38, 0xcf, 0xc8, + 0xc8, 0xc8, 0xc8, 0xfd, 0xc3, 0xfd, 0xc3, 0xfc, 0xc0, 0xfc, 0xc0, 0xdb, 0xbf, 0xdb, 0xbf, + 0xa3, 0xc0, 0xa3, 0xc0, 0x4f, 0xc3, 0x4f, 0xc3, 0xc8, 0xc7, 0xc8, 0xc7, 0xef, 0xcd, 0xef, + 0xcd, 0x93, 0xd5, 0x93, 0xd5, 0x7b, 0xde, 0x7b, 0xde, 0x62, 0xe8, 0x62, 0xe8, 0xfe, 0xf2, + 0xfe, 0xf2, 0xfc, 0xfd, 0xfc, 0xfd, 0x0a, 0x09, 0x0a, 0x09, 0xd3, 0x13, 0xd3, 0x13, 0x05, + 0x1e, 0x05, 0x1e, 0x52, 0x27, 0x52, 0x27, 0x73, 0x2f, 0x73, 0x2f, 0x2a, 0x36, 0x2a, 0x36, + 0x45, 0x3b, 0x45, 0x3b, 0x9b, 0x3e, 0x9b, 0x3e, 0x15, 0x40, 0x15, 0x40, 0xa5, 0x3f, 0xa5, + 0x3f, 0x51, 0x3d, 0x51, 0x3d, 0x29, 0x39, 0x29, 0x39, 0x4d, 0x33, 0x4d, 0x33, 0xea, 0x2b, + 0xea, 0x2b, 0x39, 0x23, 0x39, 0x23, 0x7a, 0x19, 0x7a, 0x19, 0xfa, 0x0e, 0xfa, 0x0e, 0x07, + 0x04, 0x07, 0x04, 0xf6, 0xf8, 0xf6, 0xf8, 0x1a, 0xee, 0x1a, 0xee, 0xc7, 0xe3, 0xc7, 0xe3, + 0x4b, 0xda, 0x4b, 0xda, 0xee, 0xd1, 0xee, 0xd1, 0xf1, 0xca, 0xf1, 0xca, 0x88, 0xc5, 0x88, + 0xc5, 0xdd, 0xc1, 0xdd, 0xc1, 0x0c, 0xc0, 0x0c, 0xc0, 0x22, 0xc0, 0x22, 0xc0, 0x1f, 0xc2, + 0x1f, 0xc2, 0xf4, 0xc5, 0xf4, 0xc5, 0x84, 0xcb, 0x84, 0xcb, 0xa3, 0xd2, 0xa3, 0xd2, 0x1d, + 0xdb, 0x1d, 0xdb, 0xaf, 0xe4, 0xaf, 0xe4, 0x12, 0xef, 0x12, 0xef, 0xf6, 0xf9, 0xf6, 0xf9, + 0x09, 0x05, 0x09, 0x05, 0xf4, 0x0f, 0xf4, 0x0f, 0x66, 0x1a, 0x66, 0x1a, 0x0f, 0x24, 0x0f, + 0x24, 0xa5, 0x2c, 0xa5, 0x2c, 0xe6, 0x33, 0xe6, 0x33, 0x9c, 0x39, 0x9c, 0x39, 0x9b, 0x3d, + 0x9b, 0x3d, 0xc4, 0x3f, 0xc4, 0x3f, 0x06, 0x40, 0x06, 0x40, 0x61, 0x3e, 0x61, 0x3e, 0xe0, + 0x3a, 0xe0, 0x3a, 0x9e, 0x35, 0x9e, 0x35, 0xc4, 0x2e, 0xc4, 0x2e, 0x85, 0x26, 0x85, 0x26, + 0x20, 0x1d, 0x20, 0x1d, 0xdd, 0x12, 0xdd, 0x12, 0x0a, 0x08, 0x0a, 0x08, 0xfa, 0xfc, 0xfa, + 0xfc, 0x01, 0xf2, 0x01, 0xf2, 0x73, 0xe7, 0x73, 0xe7, 0xa0, 0xdd, 0xa0, 0xdd, 0xd3, 0xd4, + 0xd3, 0xd4, 0x4f, 0xcd, 0x4f, 0xcd, 0x4e, 0xc7, 0x4e, 0xc7, 0xfd, 0xc2, 0xfd, 0xc2, 0x7d, + 0xc0, 0x7d, 0xc0, 0xe1, 0xbf, 0xe1, 0xbf, 0x2e, 0xc1, 0x2e, 0xc1, 0x5a, 0xc4, 0x5a, 0xc4, + 0x4d, 0xc9, 0x4d, 0xc9, 0xe1, 0xcf, 0xe1, 0xcf, 0xe4, 0xd7, 0xe4, 0xd7, 0x18, 0xe1, 0x18, + 0xe1, 0x38, 0xeb, 0x38, 0xeb, 0xf7, 0xf5, 0xf7, 0xf5, 0x02, 0x01, 0x02, 0x01, 0x05, 0x0c, + 0x05, 0x0c, 0xad, 0x16, 0xad, 0x16, 0xa8, 0x20, 0xa8, 0x20, 0xaa, 0x29, 0xaa, 0x29, 0x6e, + 0x31, 0x6e, 0x31, 0xb9, 0x37, 0xb9, 0x37, 0x5c, 0x3c, 0x5c, 0x3c, 0x32, 0x3f, 0x32, 0x3f, + 0x27, 0x40, 0x27, 0x40, 0x32, 0x3f, 0x32, 0x3f, 0x5c, 0x3c, 0x5c, 0x3c, 0xb9, 0x37, 0xb9, + 0x37, 0x6e, 0x31, 0x6e, 0x31, 0xaa, 0x29, 0xaa, 0x29, 0xa8, 0x20, 0xa8, 0x20, 0xad, 0x16, + 0xad, 0x16, 0x05, 0x0c, 0x05, 0x0c, 0x02, 0x01, 0x02, 0x01, 0xf7, 0xf5, 0xf7, 0xf5, 0x38, + 0xeb, 0x38, 0xeb, 0x18, 0xe1, 0x18, 0xe1, 0xe4, 0xd7, 0xe4, 0xd7, 0xe1, 0xcf, 0xe1, 0xcf, + 0x4d, 0xc9, 0x4d, 0xc9, 0x5a, 0xc4, 0x5a, 0xc4, 0x2e, 0xc1, 0x2e, 0xc1, 0xe1, 0xbf, 0xe1, + 0xbf, 0x7d, 0xc0, 0x7d, 0xc0, 0xfd, 0xc2, 0xfd, 0xc2, 0x4e, 0xc7, 0x4e, 0xc7, 0x4f, 0xcd, + 0x4f, 0xcd, 0xd3, 0xd4, 0xd3, 0xd4, 0xa0, 0xdd, 0xa0, 0xdd, 0x73, 0xe7, 0x73, 0xe7, 0x01, + 0xf2, 0x01, 0xf2, 0xfa, 0xfc, 0xfa, 0xfc, 0x0a, 0x08, 0x0a, 0x08, 0xdd, 0x12, 0xdd, 0x12, + 0x20, 0x1d, 0x20, 0x1d, 0x85, 0x26, 0x85, 0x26, 0xc4, 0x2e, 0xc4, 0x2e, 0x9e, 0x35, 0x9e, + 0x35, 0xe0, 0x3a, 0xe0, 0x3a, 0x61, 0x3e, 0x61, 0x3e, 0x06, 0x40, 0x06, 0x40, 0xc4, 0x3f, + 0xc4, 0x3f, 0x9b, 0x3d, 0x9b, 0x3d, 0x9c, 0x39, 0x9c, 0x39, 0xe6, 0x33, 0xe6, 0x33, 0xa5, + 0x2c, 0xa5, 0x2c, 0x0f, 0x24, 0x0f, 0x24, 0x66, 0x1a, 0x66, 0x1a, 0xf4, 0x0f, 0xf4, 0x0f, + 0x09, 0x05, 0x09, 0x05, 0xf6, 0xf9, 0xf6, 0xf9, 0x12, 0xef, 0x12, 0xef, 0xaf, 0xe4, 0xaf, + 0xe4, 0x1d, 0xdb, 0x1d, 0xdb, 0xa3, 0xd2, 0xa3, 0xd2, 0x84, 0xcb, 0x84, 0xcb, 0xf4, 0xc5, + 0xf4, 0xc5, 0x1f, 0xc2, 0x1f, 0xc2, 0x22, 0xc0, 0x22, 0xc0, 0x0c, 0xc0, 0x0c, 0xc0, 0xdd, + 0xc1, 0xdd, 0xc1, 0x88, 0xc5, 0x88, 0xc5, 0xf1, 0xca, 0xf1, 0xca, 0xee, 0xd1, 0xee, 0xd1, + 0x4b, 0xda, 0x4b, 0xda, 0xc7, 0xe3, 0xc7, 0xe3, 0x1a, 0xee, 0x1a, 0xee, 0xf6, 0xf8, 0xf6, + 0xf8, 0x07, 0x04, 0x07, 0x04, 0xfa, 0x0e, 0xfa, 0x0e, 0x7a, 0x19, 0x7a, 0x19, 0x39, 0x23, + 0x39, 0x23, 0xea, 0x2b, 0xea, 0x2b, 0x4d, 0x33, 0x4d, 0x33, 0x29, 0x39, 0x29, 0x39, 0x51, + 0x3d, 0x51, 0x3d, 0xa5, 0x3f, 0xa5, 0x3f, 0x15, 0x40, 0x15, 0x40, 0x9b, 0x3e, 0x9b, 0x3e, + 0x45, 0x3b, 0x45, 0x3b, 0x2a, 0x36, 0x2a, 0x36, 0x73, 0x2f, 0x73, 0x2f, 0x52, 0x27, 0x52, + 0x27, 0x05, 0x1e, 0x05, 0x1e, 0xd3, 0x13, 0xd3, 0x13, 0x0a, 0x09, 0x0a, 0x09, 0xfc, 0xfd, + 0xfc, 0xfd, 0xfe, 0xf2, 0xfe, 0xf2, 0x62, 0xe8, 0x62, 0xe8, 0x7b, 0xde, 0x7b, 0xde, 0x93, + 0xd5, 0x93, 0xd5, 0xef, 0xcd, 0xef, 0xcd, 0xc8, 0xc7, 0xc8, 0xc7, 0x4f, 0xc3, 0x4f, 0xc3, + 0xa3, 0xc0, 0xa3, 0xc0, 0xdb, 0xbf, 0xdb, 0xbf, 0xfc, 0xc0, 0xfc, 0xc0, 0xfd, 0xc3, 0xfd, + 0xc3, 0xc8, 0xc8, 0xc8, 0xc8, 0x38, 0xcf, 0x38, 0xcf, 0x1c, 0xd7, 0x1c, 0xd7, 0x37, 0xe0, + 0x37, 0xe0, 0x45, 0xea, 0x45, 0xea, 0xf8, 0xf4, 0xf8, 0xf4, 0x00, 0x00, 0x00, 0x00, 0x08, + 0x0b, 0x08, 0x0b, 0xbb, 0x15, 0xbb, 0x15, 0xc9, 0x1f, 0xc9, 0x1f, 0xe4, 0x28, 0xe4, 0x28, + 0xc8, 0x30, 0xc8, 0x30, 0x38, 0x37, 0x38, 0x37, 0x03, 0x3c, 0x03, 0x3c, 0x04, 0x3f, 0x04, + 0x3f, 0x25, 0x40, 0x25, 0x40, 0x5d, 0x3f, 0x5d, 0x3f, 0xb1, 0x3c, 0xb1, 0x3c, 0x38, 0x38, + 0x38, 0x38, 0x11, 0x32, 0x11, 0x32, 0x6d, 0x2a, 0x6d, 0x2a, 0x85, 0x21, 0x85, 0x21, 0x9e, + 0x17, 0x9e, 0x17, 0x02, 0x0d, 0x02, 0x0d, 0x04, 0x02, 0x04, 0x02, 0xf6, 0xf6, 0xf6, 0xf6, + 0x2d, 0xec, 0x2d, 0xec, 0xfb, 0xe1, 0xfb, 0xe1, 0xae, 0xd8, 0xae, 0xd8, 0x8d, 0xd0, 0x8d, + 0xd0, 0xd6, 0xc9, 0xd6, 0xc9, 0xbb, 0xc4, 0xbb, 0xc4, 0x65, 0xc1, 0x65, 0xc1, 0xeb, 0xbf, + 0xeb, 0xbf, 0x5b, 0xc0, 0x5b, 0xc0, 0xaf, 0xc2, 0xaf, 0xc2, 0xd7, 0xc6, 0xd7, 0xc6, 0xb3, + 0xcc, 0xb3, 0xcc, 0x16, 0xd4, 0x16, 0xd4, 0xc7, 0xdc, 0xc7, 0xdc, 0x86, 0xe6, 0x86, 0xe6, + 0x06, 0xf1, 0x06, 0xf1, 0xf9, 0xfb, 0xf9, 0xfb, 0x0a, 0x07, 0x0a, 0x07, 0xe6, 0x11, 0xe6, + 0x11, 0x39, 0x1c, 0x39, 0x1c, 0xb5, 0x25, 0xb5, 0x25, 0x12, 0x2e, 0x12, 0x2e, 0x0f, 0x35, + 0x0f, 0x35, 0x78, 0x3a, 0x78, 0x3a, 0x23, 0x3e, 0x23, 0x3e, 0xf4, 0x3f, 0xf4, 0x3f, 0xde, + 0x3f, 0xde, 0x3f, 0xe1, 0x3d, 0xe1, 0x3d, 0x0c, 0x3a, 0x0c, 0x3a, 0x7c, 0x34, 0x7c, 0x34, + 0x5d, 0x2d, 0x5d, 0x2d, 0xe3, 0x24, 0xe3, 0x24, 0x51, 0x1b, 0x51, 0x1b, 0xee, 0x10, 0xee, + 0x10, 0x0a, 0x06, 0x0a, 0x06, 0xf7, 0xfa, 0xf7, 0xfa, 0x0c, 0xf0, 0x0c, 0xf0, 0x9a, 0xe5, + 0x9a, 0xe5, 0xf1, 0xdb, 0xf1, 0xdb, 0x5b, 0xd3, 0x5b, 0xd3, 0x1a, 0xcc, 0x1a, 0xcc, 0x64, + 0xc6, 0x64, 0xc6, 0x65, 0xc2, 0x65, 0xc2, 0x3c, 0xc0, 0x3c, 0xc0, 0xfa, 0xbf, 0xfa, 0xbf, + 0x9f, 0xc1, 0x9f, 0xc1, 0x20, 0xc5, 0x20, 0xc5, 0x62, 0xca, 0x62, 0xca, 0x3c, 0xd1, 0x3c, + 0xd1, 0x7b, 0xd9, 0x7b, 0xd9, 0xe0, 0xe2, 0xe0, 0xe2, 0x23, 0xed, 0x23, 0xed, 0xf6, 0xf7, + 0xf6, 0xf7, 0x06, 0x03, 0x06, 0x03, 0xff, 0x0d, 0xff, 0x0d, 0x8d, 0x18, 0x8d, 0x18, 0x60, + 0x22, 0x60, 0x22, 0x2d, 0x2b, 0x2d, 0x2b, 0xb1, 0x32, 0xb1, 0x32, 0xb2, 0x38, 0xb2, 0x38, + 0x03, 0x3d, 0x03, 0x3d, 0x83, 0x3f, 0x83, 0x3f, 0x1f, 0x40, 0x1f, 0x40, 0xd2, 0x3e, 0xd2, + 0x3e, 0xa6, 0x3b, 0xa6, 0x3b, 0xb3, 0x36, 0xb3, 0x36, 0x1f, 0x30, 0x1f, 0x30, 0x1c, 0x28, + 0x1c, 0x28, 0xe8, 0x1e, 0xe8, 0x1e, 0xc8, 0x14, 0xc8, 0x14, 0x09, 0x0a, 0x09, 0x0a, 0xfe, + 0xfe, 0xfe, 0xfe, 0xfb, 0xf3, 0xfb, 0xf3, 0x53, 0xe9, 0x53, 0xe9, 0x58, 0xdf, 0x58, 0xdf, + 0x56, 0xd6, 0x56, 0xd6, 0x92, 0xce, 0x92, 0xce, 0x47, 0xc8, 0x47, 0xc8, 0xa4, 0xc3, 0xa4, + 0xc3, 0xce, 0xc0, 0xce, 0xc0, 0xd9, 0xbf, 0xd9, 0xbf, 0xce, 0xc0, 0xce, 0xc0, 0xa4, 0xc3, + 0xa4, 0xc3, 0x47, 0xc8, 0x47, 0xc8, 0x92, 0xce, 0x92, 0xce, 0x56, 0xd6, 0x56, 0xd6, 0x58, + 0xdf, 0x58, 0xdf, 0x53, 0xe9, 0x53, 0xe9, 0xfb, 0xf3, 0xfb, 0xf3, 0xfe, 0xfe, 0xfe, 0xfe, + 0x09, 0x0a, 0x09, 0x0a, 0xc8, 0x14, 0xc8, 0x14, 0xe8, 0x1e, 0xe8, 0x1e, 0x1c, 0x28, 0x1c, + 0x28, 0x1f, 0x30, 0x1f, 0x30, 0xb3, 0x36, 0xb3, 0x36, 0xa6, 0x3b, 0xa6, 0x3b, 0xd2, 0x3e, + 0xd2, 0x3e, 0x1f, 0x40, 0x1f, 0x40, 0x83, 0x3f, 0x83, 0x3f, 0x03, 0x3d, 0x03, 0x3d, 0xb2, + 0x38, 0xb2, 0x38, 0xb1, 0x32, 0xb1, 0x32, 0x2d, 0x2b, 0x2d, 0x2b, 0x60, 0x22, 0x60, 0x22, + 0x8d, 0x18, 0x8d, 0x18, 0xff, 0x0d, 0xff, 0x0d, 0x06, 0x03, 0x06, 0x03, 0xf6, 0xf7, 0xf6, + 0xf7, 0x23, 0xed, 0x23, 0xed, 0xe0, 0xe2, 0xe0, 0xe2, 0x7b, 0xd9, 0x7b, 0xd9, 0x3c, 0xd1, + 0x3c, 0xd1, 0x62, 0xca, 0x62, 0xca, 0x20, 0xc5, 0x20, 0xc5, 0x9f, 0xc1, 0x9f, 0xc1, 0xfa, + 0xbf, 0xfa, 0xbf, 0x3c, 0xc0, 0x3c, 0xc0, 0x65, 0xc2, 0x65, 0xc2, 0x64, 0xc6, 0x64, 0xc6, + 0x1a, 0xcc, 0x1a, 0xcc, 0x5b, 0xd3, 0x5b, 0xd3, 0xf1, 0xdb, 0xf1, 0xdb, 0x9a, 0xe5, 0x9a, + 0xe5, 0x0c, 0xf0, 0x0c, 0xf0, 0xf7, 0xfa, 0xf7, 0xfa, 0x0a, 0x06, 0x0a, 0x06, 0xee, 0x10, + 0xee, 0x10, 0x51, 0x1b, 0x51, 0x1b, 0xe3, 0x24, 0xe3, 0x24, 0x5d, 0x2d, 0x5d, 0x2d, 0x7c, + 0x34, 0x7c, 0x34, 0x0c, 0x3a, 0x0c, 0x3a, 0xe1, 0x3d, 0xe1, 0x3d, 0xde, 0x3f, 0xde, 0x3f, + 0xf4, 0x3f, 0xf4, 0x3f, 0x23, 0x3e, 0x23, 0x3e, 0x78, 0x3a, 0x78, 0x3a, 0x0f, 0x35, 0x0f, + 0x35, 0x12, 0x2e, 0x12, 0x2e, 0xb5, 0x25, 0xb5, 0x25, 0x39, 0x1c, 0x39, 0x1c, 0xe6, 0x11, + 0xe6, 0x11, 0x0a, 0x07, 0x0a, 0x07, 0xf9, 0xfb, 0xf9, 0xfb, 0x06, 0xf1, 0x06, 0xf1, 0x86, + 0xe6, 0x86, 0xe6, 0xc7, 0xdc, 0xc7, 0xdc, 0x16, 0xd4, 0x16, 0xd4, 0xb3, 0xcc, 0xb3, 0xcc, + 0xd7, 0xc6, 0xd7, 0xc6, 0xaf, 0xc2, 0xaf, 0xc2, 0x5b, 0xc0, 0x5b, 0xc0, 0xeb, 0xbf, 0xeb, + 0xbf, 0x65, 0xc1, 0x65, 0xc1, 0xbb, 0xc4, 0xbb, 0xc4, 0xd6, 0xc9, 0xd6, 0xc9, 0x8d, 0xd0, + 0x8d, 0xd0, 0xae, 0xd8, 0xae, 0xd8, 0xfb, 0xe1, 0xfb, 0xe1, 0x2d, 0xec, 0x2d, 0xec, 0xf6, + 0xf6, 0xf6, 0xf6, 0x04, 0x02, 0x04, 0x02, 0x02, 0x0d, 0x02, 0x0d, 0x9e, 0x17, 0x9e, 0x17, + 0x85, 0x21, 0x85, 0x21, 0x6d, 0x2a, 0x6d, 0x2a, 0x11, 0x32, 0x11, 0x32, 0x38, 0x38, 0x38, + 0x38, 0xb1, 0x3c, 0xb1, 0x3c, 0x5d, 0x3f, 0x5d, 0x3f, 0x25, 0x40, 0x25, 0x40, 0x04, 0x3f, + 0x04, 0x3f, 0x03, 0x3c, 0x03, 0x3c, 0x38, 0x37, 0x38, 0x37, 0xc8, 0x30, 0xc8, 0x30, 0xe4, + 0x28, 0xe4, 0x28, 0xc9, 0x1f, 0xc9, 0x1f, 0xbb, 0x15, 0xbb, 0x15, 0x08, 0x0b, 0x08, 0x0b, + 0x00, 0x00, 0x00, 0x00, 0xf8, 0xf4, 0xf8, 0xf4, 0x45, 0xea, 0x45, 0xea, 0x37, 0xe0, 0x37, + 0xe0, 0x1c, 0xd7, 0x1c, 0xd7, 0x38, 0xcf, 0x38, 0xcf, 0xc8, 0xc8, 0xc8, 0xc8, 0xfd, 0xc3, + 0xfd, 0xc3, 0xfc, 0xc0, 0xfc, 0xc0, 0xdb, 0xbf, 0xdb, 0xbf, 0xa3, 0xc0, 0xa3, 0xc0, 0x4f, + 0xc3, 0x4f, 0xc3, 0xc8, 0xc7, 0xc8, 0xc7, 0xef, 0xcd, 0xef, 0xcd, 0x93, 0xd5, 0x93, 0xd5, + 0x7b, 0xde, 0x7b, 0xde, 0x62, 0xe8, 0x62, 0xe8, 0xfe, 0xf2, 0xfe, 0xf2, 0xfc, 0xfd, 0xfc, + 0xfd, 0x0a, 0x09, 0x0a, 0x09, 0xd3, 0x13, 0xd3, 0x13, 0x05, 0x1e, 0x05, 0x1e, 0x52, 0x27, + 0x52, 0x27, 0x73, 0x2f, 0x73, 0x2f, 0x2a, 0x36, 0x2a, 0x36, 0x45, 0x3b, 0x45, 0x3b, 0x9b, + 0x3e, 0x9b, 0x3e, 0x15, 0x40, 0x15, 0x40, 0xa5, 0x3f, 0xa5, 0x3f, 0x51, 0x3d, 0x51, 0x3d, + 0x29, 0x39, 0x29, 0x39, 0x4d, 0x33, 0x4d, 0x33, 0xea, 0x2b, 0xea, 0x2b, 0x39, 0x23, 0x39, + 0x23, 0x7a, 0x19, 0x7a, 0x19, 0xfa, 0x0e, 0xfa, 0x0e, 0x07, 0x04, 0x07, 0x04, 0xf6, 0xf8, + 0xf6, 0xf8, 0x1a, 0xee, 0x1a, 0xee, 0xc7, 0xe3, 0xc7, 0xe3, 0x4b, 0xda, 0x4b, 0xda, 0xee, + 0xd1, 0xee, 0xd1, 0xf1, 0xca, 0xf1, 0xca, 0x88, 0xc5, 0x88, 0xc5, 0xdd, 0xc1, 0xdd, 0xc1, + 0x0c, 0xc0, 0x0c, 0xc0, 0x22, 0xc0, 0x22, 0xc0, 0x1f, 0xc2, 0x1f, 0xc2, 0xf4, 0xc5, 0xf4, + 0xc5, 0x84, 0xcb, 0x84, 0xcb, 0xa3, 0xd2, 0xa3, 0xd2, 0x1d, 0xdb, 0x1d, 0xdb, 0xaf, 0xe4, + 0xaf, 0xe4, 0x12, 0xef, 0x12, 0xef, 0xf6, 0xf9, 0xf6, 0xf9, 0x09, 0x05, 0x09, 0x05, 0xf4, + 0x0f, 0xf4, 0x0f, 0x66, 0x1a, 0x66, 0x1a, 0x0f, 0x24, 0x0f, 0x24, 0xa5, 0x2c, 0xa5, 0x2c, + 0xe6, 0x33, 0xe6, 0x33, 0x9c, 0x39, 0x9c, 0x39, 0x9b, 0x3d, 0x9b, 0x3d, 0xc4, 0x3f, 0xc4, + 0x3f, 0x06, 0x40, 0x06, 0x40, 0x61, 0x3e, 0x61, 0x3e, 0xe0, 0x3a, 0xe0, 0x3a, 0x9e, 0x35, + 0x9e, 0x35, 0xc4, 0x2e, 0xc4, 0x2e, 0x85, 0x26, 0x85, 0x26, 0x20, 0x1d, 0x20, 0x1d, 0xdd, + 0x12, 0xdd, 0x12, 0x0a, 0x08, 0x0a, 0x08, 0xfa, 0xfc, 0xfa, 0xfc, 0x01, 0xf2, 0x01, 0xf2, + 0x73, 0xe7, 0x73, 0xe7, 0xa0, 0xdd, 0xa0, 0xdd, 0xd3, 0xd4, 0xd3, 0xd4, 0x4f, 0xcd, 0x4f, + 0xcd, 0x4e, 0xc7, 0x4e, 0xc7, 0xfd, 0xc2, 0xfd, 0xc2, 0x7d, 0xc0, 0x7d, 0xc0, 0xe1, 0xbf, + 0xe1, 0xbf, 0x2e, 0xc1, 0x2e, 0xc1, 0x5a, 0xc4, 0x5a, 0xc4, 0x4d, 0xc9, 0x4d, 0xc9, 0xe1, + 0xcf, 0xe1, 0xcf, 0xe4, 0xd7, 0xe4, 0xd7, 0x18, 0xe1, 0x18, 0xe1, 0x38, 0xeb, 0x38, 0xeb, + 0xf7, 0xf5, 0xf7, 0xf5, 0x02, 0x01, 0x02, 0x01, 0x05, 0x0c, 0x05, 0x0c, 0xad, 0x16, 0xad, + 0x16, 0xa8, 0x20, 0xa8, 0x20, 0xaa, 0x29, 0xaa, 0x29, 0x6e, 0x31, 0x6e, 0x31, 0xb9, 0x37, + 0xb9, 0x37, 0x5c, 0x3c, 0x5c, 0x3c, 0x32, 0x3f, 0x32, 0x3f, 0x27, 0x40, 0x27, 0x40, 0x32, + 0x3f, 0x32, 0x3f, 0x5c, 0x3c, 0x5c, 0x3c, 0xb9, 0x37, 0xb9, 0x37, 0x6e, 0x31, 0x6e, 0x31, + 0xaa, 0x29, 0xaa, 0x29, 0xa8, 0x20, 0xa8, 0x20, 0xad, 0x16, 0xad, 0x16, 0x05, 0x0c, 0x05, + 0x0c, 0x02, 0x01, 0x02, 0x01, 0xf7, 0xf5, 0xf7, 0xf5, 0x38, 0xeb, 0x38, 0xeb, 0x18, 0xe1, + 0x18, 0xe1, 0xe4, 0xd7, 0xe4, 0xd7, 0xe1, 0xcf, 0xe1, 0xcf, 0x4d, 0xc9, 0x4d, 0xc9, 0x5a, + 0xc4, 0x5a, 0xc4, 0x2e, 0xc1, 0x2e, 0xc1, 0xe1, 0xbf, 0xe1, 0xbf, 0x7d, 0xc0, 0x7d, 0xc0, + 0xfd, 0xc2, 0xfd, 0xc2, 0x4e, 0xc7, 0x4e, 0xc7, 0x4f, 0xcd, 0x4f, 0xcd, 0xd3, 0xd4, 0xd3, + 0xd4, 0xa0, 0xdd, 0xa0, 0xdd, 0x73, 0xe7, 0x73, 0xe7, 0x01, 0xf2, 0x01, 0xf2, 0xfa, 0xfc, + 0xfa, 0xfc, 0x0a, 0x08, 0x0a, 0x08, 0xdd, 0x12, 0xdd, 0x12, 0x20, 0x1d, 0x20, 0x1d, 0x85, + 0x26, 0x85, 0x26, 0xc4, 0x2e, 0xc4, 0x2e, 0x9e, 0x35, 0x9e, 0x35, 0xe0, 0x3a, 0xe0, 0x3a, + 0x61, 0x3e, 0x61, 0x3e, 0x06, 0x40, 0x06, 0x40, 0xc4, 0x3f, 0xc4, 0x3f, 0x9b, 0x3d, 0x9b, + 0x3d, 0x9c, 0x39, 0x9c, 0x39, 0xe6, 0x33, 0xe6, 0x33, 0xa5, 0x2c, 0xa5, 0x2c, 0x0f, 0x24, + 0x0f, 0x24, 0x66, 0x1a, 0x66, 0x1a, 0xf4, 0x0f, 0xf4, 0x0f, 0x09, 0x05, 0x09, 0x05, 0xf6, + 0xf9, 0xf6, 0xf9, 0x12, 0xef, 0x12, 0xef, 0xaf, 0xe4, 0xaf, 0xe4, 0x1d, 0xdb, 0x1d, 0xdb, + 0xa3, 0xd2, 0xa3, 0xd2, 0x84, 0xcb, 0x84, 0xcb, 0xf4, 0xc5, 0xf4, 0xc5, 0x1f, 0xc2, 0x1f, + 0xc2, 0x22, 0xc0, 0x22, 0xc0, 0x0c, 0xc0, 0x0c, 0xc0, 0xdd, 0xc1, 0xdd, 0xc1, 0x88, 0xc5, + 0x88, 0xc5, 0xf1, 0xca, 0xf1, 0xca, 0xee, 0xd1, 0xee, 0xd1, 0x4b, 0xda, 0x4b, 0xda, 0xc7, + 0xe3, 0xc7, 0xe3, 0x1a, 0xee, 0x1a, 0xee, 0xf6, 0xf8, 0xf6, 0xf8, 0x07, 0x04, 0x07, 0x04, + 0xfa, 0x0e, 0xfa, 0x0e, 0x7a, 0x19, 0x7a, 0x19, 0x39, 0x23, 0x39, 0x23, 0xea, 0x2b, 0xea, + 0x2b, 0x4d, 0x33, 0x4d, 0x33, 0x29, 0x39, 0x29, 0x39, 0x51, 0x3d, 0x51, 0x3d, 0xa5, 0x3f, + 0xa5, 0x3f, 0x15, 0x40, 0x15, 0x40, 0x9b, 0x3e, 0x9b, 0x3e, 0x45, 0x3b, 0x45, 0x3b, 0x2a, + 0x36, 0x2a, 0x36, 0x73, 0x2f, 0x73, 0x2f, 0x52, 0x27, 0x52, 0x27, 0x05, 0x1e, 0x05, 0x1e, + 0xd3, 0x13, 0xd3, 0x13, 0x0a, 0x09, 0x0a, 0x09, 0xfc, 0xfd, 0xfc, 0xfd, 0xfe, 0xf2, 0xfe, + 0xf2, 0x62, 0xe8, 0x62, 0xe8, 0x7b, 0xde, 0x7b, 0xde, 0x93, 0xd5, 0x93, 0xd5, 0xef, 0xcd, + 0xef, 0xcd, 0xc8, 0xc7, 0xc8, 0xc7, 0x4f, 0xc3, 0x4f, 0xc3, 0xa3, 0xc0, 0xa3, 0xc0, 0xdb, + 0xbf, 0xdb, 0xbf, 0xfc, 0xc0, 0xfc, 0xc0, 0xfd, 0xc3, 0xfd, 0xc3, 0xc8, 0xc8, 0xc8, 0xc8, + 0x38, 0xcf, 0x38, 0xcf, 0x1c, 0xd7, 0x1c, 0xd7, 0x37, 0xe0, 0x37, 0xe0, 0x45, 0xea, 0x45, + 0xea, 0xf8, 0xf4, 0xf8, 0xf4, 0x00, 0x00, 0x00, 0x00, 0x08, 0x0b, 0x08, 0x0b, 0xbb, 0x15, + 0xbb, 0x15, 0xc9, 0x1f, 0xc9, 0x1f, 0xe4, 0x28, 0xe4, 0x28, 0xc8, 0x30, 0xc8, 0x30, 0x38, + 0x37, 0x38, 0x37, 0x03, 0x3c, 0x03, 0x3c, 0x04, 0x3f, 0x04, 0x3f, 0x25, 0x40, 0x25, 0x40, + 0x5d, 0x3f, 0x5d, 0x3f, 0xb1, 0x3c, 0xb1, 0x3c, 0x38, 0x38, 0x38, 0x38, 0x11, 0x32, 0x11, + 0x32, 0x6d, 0x2a, 0x6d, 0x2a, 0x85, 0x21, 0x85, 0x21, 0x9e, 0x17, 0x9e, 0x17, 0x02, 0x0d, + 0x02, 0x0d, 0x04, 0x02, 0x04, 0x02, 0xf6, 0xf6, 0xf6, 0xf6, 0x2d, 0xec, 0x2d, 0xec, 0xfb, + 0xe1, 0xfb, 0xe1, 0xae, 0xd8, 0xae, 0xd8, 0x8d, 0xd0, 0x8d, 0xd0, 0xd6, 0xc9, 0xd6, 0xc9, + 0xbb, 0xc4, 0xbb, 0xc4, 0x65, 0xc1, 0x65, 0xc1, 0xeb, 0xbf, 0xeb, 0xbf, 0x5b, 0xc0, 0x5b, + 0xc0, 0xaf, 0xc2, 0xaf, 0xc2, 0xd7, 0xc6, 0xd7, 0xc6, 0xb3, 0xcc, 0xb3, 0xcc, 0x16, 0xd4, + 0x16, 0xd4, 0xc7, 0xdc, 0xc7, 0xdc, 0x86, 0xe6, 0x86, 0xe6, 0x06, 0xf1, 0x06, 0xf1, 0xf9, + 0xfb, 0xf9, 0xfb, 0x0a, 0x07, 0x0a, 0x07, 0xe6, 0x11, 0xe6, 0x11, 0x39, 0x1c, 0x39, 0x1c, + 0xb5, 0x25, 0xb5, 0x25, 0x12, 0x2e, 0x12, 0x2e, 0x0f, 0x35, 0x0f, 0x35, 0x78, 0x3a, 0x78, + 0x3a, 0x23, 0x3e, 0x23, 0x3e, 0xf4, 0x3f, 0xf4, 0x3f, 0xde, 0x3f, 0xde, 0x3f, 0xe1, 0x3d, + 0xe1, 0x3d, 0x0c, 0x3a, 0x0c, 0x3a, 0x7c, 0x34, 0x7c, 0x34, 0x5d, 0x2d, 0x5d, 0x2d, 0xe3, + 0x24, 0xe3, 0x24, 0x51, 0x1b, 0x51, 0x1b, 0xee, 0x10, 0xee, 0x10, 0x0a, 0x06, 0x0a, 0x06, + 0xf7, 0xfa, 0xf7, 0xfa, 0x0c, 0xf0, 0x0c, 0xf0, 0x9a, 0xe5, 0x9a, 0xe5, 0xf1, 0xdb, 0xf1, + 0xdb, 0x5b, 0xd3, 0x5b, 0xd3, 0x1a, 0xcc, 0x1a, 0xcc, 0x64, 0xc6, 0x64, 0xc6, 0x65, 0xc2, + 0x65, 0xc2, 0x3c, 0xc0, 0x3c, 0xc0, 0xfa, 0xbf, 0xfa, 0xbf, 0x9f, 0xc1, 0x9f, 0xc1, 0x20, + 0xc5, 0x20, 0xc5, 0x62, 0xca, 0x62, 0xca, 0x3c, 0xd1, 0x3c, 0xd1, 0x7b, 0xd9, 0x7b, 0xd9, + 0xe0, 0xe2, 0xe0, 0xe2, 0x23, 0xed, 0x23, 0xed, 0xf6, 0xf7, 0xf6, 0xf7, 0x06, 0x03, 0x06, + 0x03, 0xff, 0x0d, 0xff, 0x0d, 0x8d, 0x18, 0x8d, 0x18, 0x60, 0x22, 0x60, 0x22, 0x2d, 0x2b, + 0x2d, 0x2b, 0xb1, 0x32, 0xb1, 0x32, 0xb2, 0x38, 0xb2, 0x38, 0x03, 0x3d, 0x03, 0x3d, 0x83, + 0x3f, 0x83, 0x3f, 0x1f, 0x40, 0x1f, 0x40, 0xd2, 0x3e, 0xd2, 0x3e, 0xa6, 0x3b, 0xa6, 0x3b, + 0xb3, 0x36, 0xb3, 0x36, 0x1f, 0x30, 0x1f, 0x30, 0x1c, 0x28, 0x1c, 0x28, 0xe8, 0x1e, 0xe8, + 0x1e, 0xc8, 0x14, 0xc8, 0x14, 0x09, 0x0a, 0x09, 0x0a, 0xfe, 0xfe, 0xfe, 0xfe, 0xfb, 0xf3, + 0xfb, 0xf3, 0x53, 0xe9, 0x53, 0xe9, 0x58, 0xdf, 0x58, 0xdf, 0x56, 0xd6, 0x56, 0xd6, 0x92, + 0xce, 0x92, 0xce, 0x47, 0xc8, 0x47, 0xc8, 0xa4, 0xc3, 0xa4, 0xc3, 0xce, 0xc0, 0xce, 0xc0, + 0xd9, 0xbf, 0xd9, 0xbf, 0xce, 0xc0, 0xce, 0xc0, 0xa4, 0xc3, 0xa4, 0xc3, 0x47, 0xc8, 0x47, + 0xc8, 0x92, 0xce, 0x92, 0xce, 0x56, 0xd6, 0x56, 0xd6, 0x58, 0xdf, 0x58, 0xdf, 0x53, 0xe9, + 0x53, 0xe9, 0xfb, 0xf3, 0xfb, 0xf3, 0xfe, 0xfe, 0xfe, 0xfe, 0x09, 0x0a, 0x09, 0x0a, 0xc8, + 0x14, 0xc8, 0x14, 0xe8, 0x1e, 0xe8, 0x1e, 0x1c, 0x28, 0x1c, 0x28, 0x1f, 0x30, 0x1f, 0x30, + 0xb3, 0x36, 0xb3, 0x36, 0xa6, 0x3b, 0xa6, 0x3b, 0xd2, 0x3e, 0xd2, 0x3e, 0x1f, 0x40, 0x1f, + 0x40, 0x83, 0x3f, 0x83, 0x3f, 0x03, 0x3d, 0x03, 0x3d, 0xb2, 0x38, 0xb2, 0x38, 0xb1, 0x32, + 0xb1, 0x32, 0x2d, 0x2b, 0x2d, 0x2b, 0x60, 0x22, 0x60, 0x22, 0x8d, 0x18, 0x8d, 0x18, 0xff, + 0x0d, 0xff, 0x0d, 0x06, 0x03, 0x06, 0x03, 0xf6, 0xf7, 0xf6, 0xf7, 0x23, 0xed, 0x23, 0xed, + 0xe0, 0xe2, 0xe0, 0xe2, 0x7b, 0xd9, 0x7b, 0xd9, 0x3c, 0xd1, 0x3c, 0xd1, 0x62, 0xca, 0x62, + 0xca, 0x20, 0xc5, 0x20, 0xc5, 0x9f, 0xc1, 0x9f, 0xc1, 0xfa, 0xbf, 0xfa, 0xbf, 0x3c, 0xc0, + 0x3c, 0xc0, 0x65, 0xc2, 0x65, 0xc2, 0x64, 0xc6, 0x64, 0xc6, 0x1a, 0xcc, 0x1a, 0xcc, 0x5b, + 0xd3, 0x5b, 0xd3, 0xf1, 0xdb, 0xf1, 0xdb, 0x9a, 0xe5, 0x9a, 0xe5, 0x0c, 0xf0, 0x0c, 0xf0, + 0xf7, 0xfa, 0xf7, 0xfa, 0x0a, 0x06, 0x0a, 0x06, 0xee, 0x10, 0xee, 0x10, 0x51, 0x1b, 0x51, + 0x1b, 0xe3, 0x24, 0xe3, 0x24, 0x5d, 0x2d, 0x5d, 0x2d, 0x7c, 0x34, 0x7c, 0x34, 0x0c, 0x3a, + 0x0c, 0x3a, 0xe1, 0x3d, 0xe1, 0x3d, 0xde, 0x3f, 0xde, 0x3f, 0xf4, 0x3f, 0xf4, 0x3f, 0x23, + 0x3e, 0x23, 0x3e, 0x78, 0x3a, 0x78, 0x3a, 0x0f, 0x35, 0x0f, 0x35, 0x12, 0x2e, 0x12, 0x2e, + 0xb5, 0x25, 0xb5, 0x25, 0x39, 0x1c, 0x39, 0x1c, 0xe6, 0x11, 0xe6, 0x11, 0x0a, 0x07, 0x0a, + 0x07, 0xf9, 0xfb, 0xf9, 0xfb, 0x06, 0xf1, 0x06, 0xf1, 0x86, 0xe6, 0x86, 0xe6, 0xc7, 0xdc, + 0xc7, 0xdc, 0x16, 0xd4, 0x16, 0xd4, 0xb3, 0xcc, 0xb3, 0xcc, 0xd7, 0xc6, 0xd7, 0xc6, 0xaf, + 0xc2, 0xaf, 0xc2, 0x5b, 0xc0, 0x5b, 0xc0, 0xeb, 0xbf, 0xeb, 0xbf, 0x65, 0xc1, 0x65, 0xc1, + 0xbb, 0xc4, 0xbb, 0xc4, 0xd6, 0xc9, 0xd6, 0xc9, 0x8d, 0xd0, 0x8d, 0xd0, 0xae, 0xd8, 0xae, + 0xd8, 0xfb, 0xe1, 0xfb, 0xe1, 0x2d, 0xec, 0x2d, 0xec, 0xf6, 0xf6, 0xf6, 0xf6, 0x04, 0x02, + 0x04, 0x02, 0x02, 0x0d, 0x02, 0x0d, 0x9e, 0x17, 0x9e, 0x17, 0x85, 0x21, 0x85, 0x21, 0x6d, + 0x2a, 0x6d, 0x2a, 0x11, 0x32, 0x11, 0x32, 0x38, 0x38, 0x38, 0x38, 0xb1, 0x3c, 0xb1, 0x3c, + 0x5d, 0x3f, 0x5d, 0x3f, 0x25, 0x40, 0x25, 0x40, 0x04, 0x3f, 0x04, 0x3f, 0x03, 0x3c, 0x03, + 0x3c, 0x38, 0x37, 0x38, 0x37, 0xc8, 0x30, 0xc8, 0x30, 0xe4, 0x28, 0xe4, 0x28, 0xc9, 0x1f, + 0xc9, 0x1f, 0xbb, 0x15, 0xbb, 0x15, 0x08, 0x0b, 0x08, 0x0b, 0x00, 0x00, 0x00, 0x00, 0xf8, + 0xf4, 0xf8, 0xf4, 0x45, 0xea, 0x45, 0xea, 0x37, 0xe0, 0x37, 0xe0, 0x1c, 0xd7, 0x1c, 0xd7, + 0x38, 0xcf, 0x38, 0xcf, 0xc8, 0xc8, 0xc8, 0xc8, 0xfd, 0xc3, 0xfd, 0xc3, 0xfc, 0xc0, 0xfc, + 0xc0, 0xdb, 0xbf, 0xdb, 0xbf, 0xa3, 0xc0, 0xa3, 0xc0, 0x4f, 0xc3, 0x4f, 0xc3, 0xc8, 0xc7, + 0xc8, 0xc7, 0xef, 0xcd, 0xef, 0xcd, 0x93, 0xd5, 0x93, 0xd5, 0x7b, 0xde, 0x7b, 0xde, 0x62, + 0xe8, 0x62, 0xe8, 0xfe, 0xf2, 0xfe, 0xf2, 0xfc, 0xfd, 0xfc, 0xfd, 0x0a, 0x09, 0x0a, 0x09, + 0xd3, 0x13, 0xd3, 0x13, 0x05, 0x1e, 0x05, 0x1e, 0x52, 0x27, 0x52, 0x27, 0x73, 0x2f, 0x73, + 0x2f, 0x2a, 0x36, 0x2a, 0x36, 0x45, 0x3b, 0x45, 0x3b, 0x9b, 0x3e, 0x9b, 0x3e, 0x15, 0x40, + 0x15, 0x40, 0xa5, 0x3f, 0xa5, 0x3f, 0x51, 0x3d, 0x51, 0x3d, 0x29, 0x39, 0x29, 0x39, 0x4d, + 0x33, 0x4d, 0x33, 0xea, 0x2b, 0xea, 0x2b, 0x39, 0x23, 0x39, 0x23, 0x7a, 0x19, 0x7a, 0x19, + 0xfa, 0x0e, 0xfa, 0x0e, 0x07, 0x04, 0x07, 0x04, 0xf6, 0xf8, 0xf6, 0xf8, 0x1a, 0xee, 0x1a, + 0xee, 0xc7, 0xe3, 0xc7, 0xe3, 0x4b, 0xda, 0x4b, 0xda, 0xee, 0xd1, 0xee, 0xd1, 0xf1, 0xca, + 0xf1, 0xca, 0x88, 0xc5, 0x88, 0xc5, 0xdd, 0xc1, 0xdd, 0xc1, 0x0c, 0xc0, 0x0c, 0xc0, 0x22, + 0xc0, 0x22, 0xc0, 0x1f, 0xc2, 0x1f, 0xc2, 0xf4, 0xc5, 0xf4, 0xc5, 0x84, 0xcb, 0x84, 0xcb, + 0xa3, 0xd2, 0xa3, 0xd2, 0x1d, 0xdb, 0x1d, 0xdb, 0xaf, 0xe4, 0xaf, 0xe4, 0x12, 0xef, 0x12, + 0xef, 0xf6, 0xf9, 0xf6, 0xf9, 0x09, 0x05, 0x09, 0x05, 0xf4, 0x0f, 0xf4, 0x0f, 0x66, 0x1a, + 0x66, 0x1a, 0x0f, 0x24, 0x0f, 0x24, 0xa5, 0x2c, 0xa5, 0x2c, 0xe6, 0x33, 0xe6, 0x33, 0x9c, + 0x39, 0x9c, 0x39, 0x9b, 0x3d, 0x9b, 0x3d, 0xc4, 0x3f, 0xc4, 0x3f, 0x06, 0x40, 0x06, 0x40, + 0x61, 0x3e, 0x61, 0x3e, 0xe0, 0x3a, 0xe0, 0x3a, 0x9e, 0x35, 0x9e, 0x35, 0xc4, 0x2e, 0xc4, + 0x2e, 0x85, 0x26, 0x85, 0x26, 0x20, 0x1d, 0x20, 0x1d, 0xdd, 0x12, 0xdd, 0x12, 0x0a, 0x08, + 0x0a, 0x08, 0xfa, 0xfc, 0xfa, 0xfc, 0x01, 0xf2, 0x01, 0xf2, 0x73, 0xe7, 0x73, 0xe7, 0xa0, + 0xdd, 0xa0, 0xdd, 0xd3, 0xd4, 0xd3, 0xd4, 0x4f, 0xcd, 0x4f, 0xcd, 0x4e, 0xc7, 0x4e, 0xc7, + 0xfd, 0xc2, 0xfd, 0xc2, 0x7d, 0xc0, 0x7d, 0xc0, 0xe1, 0xbf, 0xe1, 0xbf, 0x2e, 0xc1, 0x2e, + 0xc1, 0x5a, 0xc4, 0x5a, 0xc4, 0x4d, 0xc9, 0x4d, 0xc9, 0xe1, 0xcf, 0xe1, 0xcf, 0xe4, 0xd7, + 0xe4, 0xd7, 0x18, 0xe1, 0x18, 0xe1, 0x38, 0xeb, 0x38, 0xeb, 0xf7, 0xf5, 0xf7, 0xf5, 0x02, + 0x01, 0x02, 0x01, 0x05, 0x0c, 0x05, 0x0c, 0xad, 0x16, 0xad, 0x16, 0xa8, 0x20, 0xa8, 0x20, + 0xaa, 0x29, 0xaa, 0x29, 0x6e, 0x31, 0x6e, 0x31, 0xb9, 0x37, 0xb9, 0x37, 0x5c, 0x3c, 0x5c, + 0x3c, 0x32, 0x3f, 0x32, 0x3f, 0x27, 0x40, 0x27, 0x40, 0x32, 0x3f, 0x32, 0x3f, 0x5c, 0x3c, + 0x5c, 0x3c, 0xb9, 0x37, 0xb9, 0x37, 0x6e, 0x31, 0x6e, 0x31, 0xaa, 0x29, 0xaa, 0x29, 0xa8, + 0x20, 0xa8, 0x20, 0xad, 0x16, 0xad, 0x16, 0x05, 0x0c, 0x05, 0x0c, 0x02, 0x01, 0x02, 0x01, + 0xf7, 0xf5, 0xf7, 0xf5, 0x38, 0xeb, 0x38, 0xeb, 0x18, 0xe1, 0x18, 0xe1, 0xe4, 0xd7, 0xe4, + 0xd7, 0xe1, 0xcf, 0xe1, 0xcf, 0x4d, 0xc9, 0x4d, 0xc9, 0x5a, 0xc4, 0x5a, 0xc4, 0x2e, 0xc1, + 0x2e, 0xc1, 0xe1, 0xbf, 0xe1, 0xbf, 0x7d, 0xc0, 0x7d, 0xc0, 0xfd, 0xc2, 0xfd, 0xc2, 0x4e, + 0xc7, 0x4e, 0xc7, 0x4f, 0xcd, 0x4f, 0xcd, 0xd3, 0xd4, 0xd3, 0xd4, 0xa0, 0xdd, 0xa0, 0xdd, + 0x73, 0xe7, 0x73, 0xe7, 0x01, 0xf2, 0x01, 0xf2, 0xfa, 0xfc, 0xfa, 0xfc, 0x0a, 0x08, 0x0a, + 0x08, 0xdd, 0x12, 0xdd, 0x12, 0x20, 0x1d, 0x20, 0x1d, 0x85, 0x26, 0x85, 0x26, 0xc4, 0x2e, + 0xc4, 0x2e, 0x9e, 0x35, 0x9e, 0x35, 0xe0, 0x3a, 0xe0, 0x3a, 0x61, 0x3e, 0x61, 0x3e, 0x06, + 0x40, 0x06, 0x40, 0xc4, 0x3f, 0xc4, 0x3f, 0x9b, 0x3d, 0x9b, 0x3d, 0x9c, 0x39, 0x9c, 0x39, + 0xe6, 0x33, 0xe6, 0x33, 0xa5, 0x2c, 0xa5, 0x2c, 0x0f, 0x24, 0x0f, 0x24, 0x66, 0x1a, 0x66, + 0x1a, 0xf4, 0x0f, 0xf4, 0x0f, 0x09, 0x05, 0x09, 0x05, 0xf6, 0xf9, 0xf6, 0xf9, 0x12, 0xef, + 0x12, 0xef, 0xaf, 0xe4, 0xaf, 0xe4, 0x1d, 0xdb, 0x1d, 0xdb, 0xa3, 0xd2, 0xa3, 0xd2, 0x84, + 0xcb, 0x84, 0xcb, 0xf4, 0xc5, 0xf4, 0xc5, 0x1f, 0xc2, 0x1f, 0xc2, 0x22, 0xc0, 0x22, 0xc0, + 0x0c, 0xc0, 0x0c, 0xc0, 0xdd, 0xc1, 0xdd, 0xc1, 0x88, 0xc5, 0x88, 0xc5, 0xf1, 0xca, 0xf1, + 0xca, 0xee, 0xd1, 0xee, 0xd1, 0x4b, 0xda, 0x4b, 0xda, 0xc7, 0xe3, 0xc7, 0xe3, 0x1a, 0xee, + 0x1a, 0xee, 0xf6, 0xf8, 0xf6, 0xf8, 0x07, 0x04, 0x07, 0x04, 0xfa, 0x0e, 0xfa, 0x0e, 0x7a, + 0x19, 0x7a, 0x19, 0x39, 0x23, 0x39, 0x23, 0xea, 0x2b, 0xea, 0x2b, 0x4d, 0x33, 0x4d, 0x33, + 0x29, 0x39, 0x29, 0x39, 0x51, 0x3d, 0x51, 0x3d, 0xa5, 0x3f, 0xa5, 0x3f, 0x15, 0x40, 0x15, + 0x40, 0x9b, 0x3e, 0x9b, 0x3e, 0x45, 0x3b, 0x45, 0x3b, 0x2a, 0x36, 0x2a, 0x36, 0x73, 0x2f, + 0x73, 0x2f, 0x52, 0x27, 0x52, 0x27, 0x05, 0x1e, 0x05, 0x1e, 0xd3, 0x13, 0xd3, 0x13, 0x0a, + 0x09, 0x0a, 0x09, 0xfc, 0xfd, 0xfc, 0xfd, 0xfe, 0xf2, 0xfe, 0xf2, 0x62, 0xe8, 0x62, 0xe8, + 0x7b, 0xde, 0x7b, 0xde, 0x93, 0xd5, 0x93, 0xd5, 0xef, 0xcd, 0xef, 0xcd, 0xc8, 0xc7, 0xc8, + 0xc7, 0x4f, 0xc3, 0x4f, 0xc3, 0xa3, 0xc0, 0xa3, 0xc0, 0xdb, 0xbf, 0xdb, 0xbf, 0xfc, 0xc0, + 0xfc, 0xc0, 0xfd, 0xc3, 0xfd, 0xc3, 0xc8, 0xc8, 0xc8, 0xc8, 0x38, 0xcf, 0x38, 0xcf, 0x1c, + 0xd7, 0x1c, 0xd7, 0x37, 0xe0, 0x37, 0xe0, 0x45, 0xea, 0x45, 0xea, 0xf8, 0xf4, 0xf8, 0xf4, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x0b, 0x08, 0x0b, 0xbb, 0x15, 0xbb, 0x15, 0xc9, 0x1f, 0xc9, + 0x1f, 0xe4, 0x28, 0xe4, 0x28, 0xc8, 0x30, 0xc8, 0x30, 0x38, 0x37, 0x38, 0x37, 0x03, 0x3c, + 0x03, 0x3c, 0x04, 0x3f, 0x04, 0x3f, 0x25, 0x40, 0x25, 0x40, 0x5d, 0x3f, 0x5d, 0x3f, 0xb1, + 0x3c, 0xb1, 0x3c, 0x38, 0x38, 0x38, 0x38, 0x11, 0x32, 0x11, 0x32, 0x6d, 0x2a, 0x6d, 0x2a, + 0x85, 0x21, 0x85, 0x21, 0x9e, 0x17, 0x9e, 0x17, 0x02, 0x0d, 0x02, 0x0d, 0x04, 0x02, 0x04, + 0x02, 0xf6, 0xf6, 0xf6, 0xf6, 0x2d, 0xec, 0x2d, 0xec, 0xfb, 0xe1, 0xfb, 0xe1, 0xae, 0xd8, + 0xae, 0xd8, 0x8d, 0xd0, 0x8d, 0xd0, 0xd6, 0xc9, 0xd6, 0xc9, 0xbb, 0xc4, 0xbb, 0xc4, 0x65, + 0xc1, 0x65, 0xc1, 0xeb, 0xbf, 0xeb, 0xbf, 0x5b, 0xc0, 0x5b, 0xc0, 0xaf, 0xc2, 0xaf, 0xc2, + 0xd7, 0xc6, 0xd7, 0xc6, 0xb3, 0xcc, 0xb3, 0xcc, 0x16, 0xd4, 0x16, 0xd4, 0xc7, 0xdc, 0xc7, + 0xdc, 0x86, 0xe6, 0x86, 0xe6, 0x06, 0xf1, 0x06, 0xf1, 0xf9, 0xfb, 0xf9, 0xfb, 0x0a, 0x07, + 0x0a, 0x07, 0xe6, 0x11, 0xe6, 0x11, 0x39, 0x1c, 0x39, 0x1c, 0xb5, 0x25, 0xb5, 0x25, 0x12, + 0x2e, 0x12, 0x2e, 0x0f, 0x35, 0x0f, 0x35, 0x78, 0x3a, 0x78, 0x3a, 0x23, 0x3e, 0x23, 0x3e, + 0xf4, 0x3f, 0xf4, 0x3f, 0xde, 0x3f, 0xde, 0x3f, 0xe1, 0x3d, 0xe1, 0x3d, 0x0c, 0x3a, 0x0c, + 0x3a, 0x7c, 0x34, 0x7c, 0x34, 0x5d, 0x2d, 0x5d, 0x2d, 0xe3, 0x24, 0xe3, 0x24, 0x51, 0x1b, + 0x51, 0x1b, 0xee, 0x10, 0xee, 0x10, 0x0a, 0x06, 0x0a, 0x06, 0xf7, 0xfa, 0xf7, 0xfa, 0x0c, + 0xf0, 0x0c, 0xf0, 0x9a, 0xe5, 0x9a, 0xe5, 0xf1, 0xdb, 0xf1, 0xdb, 0x5b, 0xd3, 0x5b, 0xd3, + 0x1a, 0xcc, 0x1a, 0xcc, 0x64, 0xc6, 0x64, 0xc6, 0x65, 0xc2, 0x65, 0xc2, 0x3c, 0xc0, 0x3c, + 0xc0, 0xfa, 0xbf, 0xfa, 0xbf, 0x9f, 0xc1, 0x9f, 0xc1, 0x20, 0xc5, 0x20, 0xc5, 0x62, 0xca, + 0x62, 0xca, 0x3c, 0xd1, 0x3c, 0xd1, 0x7b, 0xd9, 0x7b, 0xd9, 0xe0, 0xe2, 0xe0, 0xe2, 0x23, + 0xed, 0x23, 0xed, 0xf6, 0xf7, 0xf6, 0xf7, 0x06, 0x03, 0x06, 0x03, 0xff, 0x0d, 0xff, 0x0d, + 0x8d, 0x18, 0x8d, 0x18, 0x60, 0x22, 0x60, 0x22, 0x2d, 0x2b, 0x2d, 0x2b, 0xb1, 0x32, 0xb1, + 0x32, 0xb2, 0x38, 0xb2, 0x38, 0x03, 0x3d, 0x03, 0x3d, 0x83, 0x3f, 0x83, 0x3f, 0x1f, 0x40, + 0x1f, 0x40, 0xd2, 0x3e, 0xd2, 0x3e, 0xa6, 0x3b, 0xa6, 0x3b, 0xb3, 0x36, 0xb3, 0x36, 0x1f, + 0x30, 0x1f, 0x30, 0x1c, 0x28, 0x1c, 0x28, 0xe8, 0x1e, 0xe8, 0x1e, 0xc8, 0x14, 0xc8, 0x14, + 0x09, 0x0a, 0x09, 0x0a, 0xfe, 0xfe, 0xfe, 0xfe, 0xfb, 0xf3, 0xfb, 0xf3, 0x53, 0xe9, 0x53, + 0xe9, 0x58, 0xdf, 0x58, 0xdf, 0x56, 0xd6, 0x56, 0xd6, 0x92, 0xce, 0x92, 0xce, 0x47, 0xc8, + 0x47, 0xc8, 0xa4, 0xc3, 0xa4, 0xc3, 0xce, 0xc0, 0xce, 0xc0, 0xd9, 0xbf, 0xd9, 0xbf, 0xce, + 0xc0, 0xce, 0xc0, 0xa4, 0xc3, 0xa4, 0xc3, 0x47, 0xc8, 0x47, 0xc8, 0x92, 0xce, 0x92, 0xce, + 0x56, 0xd6, 0x56, 0xd6, 0x58, 0xdf, 0x58, 0xdf, 0x53, 0xe9, 0x53, 0xe9, 0xfb, 0xf3, 0xfb, + 0xf3, 0xfe, 0xfe, 0xfe, 0xfe, 0x09, 0x0a, 0x09, 0x0a, 0xc8, 0x14, 0xc8, 0x14, 0xe8, 0x1e, + 0xe8, 0x1e, 0x1c, 0x28, 0x1c, 0x28, 0x1f, 0x30, 0x1f, 0x30, 0xb3, 0x36, 0xb3, 0x36, 0xa6, + 0x3b, 0xa6, 0x3b, 0xd2, 0x3e, 0xd2, 0x3e, 0x1f, 0x40, 0x1f, 0x40, 0x83, 0x3f, 0x83, 0x3f, + 0x03, 0x3d, 0x03, 0x3d, 0xb2, 0x38, 0xb2, 0x38, 0xb1, 0x32, 0xb1, 0x32, 0x2d, 0x2b, 0x2d, + 0x2b, 0x60, 0x22, 0x60, 0x22, 0x8d, 0x18, 0x8d, 0x18, 0xff, 0x0d, 0xff, 0x0d, 0x06, 0x03, + 0x06, 0x03, 0xf6, 0xf7, 0xf6, 0xf7, 0x23, 0xed, 0x23, 0xed, 0xe0, 0xe2, 0xe0, 0xe2, 0x7b, + 0xd9, 0x7b, 0xd9, 0x3c, 0xd1, 0x3c, 0xd1, 0x62, 0xca, 0x62, 0xca, 0x20, 0xc5, 0x20, 0xc5, + 0x9f, 0xc1, 0x9f, 0xc1, 0xfa, 0xbf, 0xfa, 0xbf, 0x3c, 0xc0, 0x3c, 0xc0, 0x65, 0xc2, 0x65, + 0xc2, 0x64, 0xc6, 0x64, 0xc6, 0x1a, 0xcc, 0x1a, 0xcc, 0x5b, 0xd3, 0x5b, 0xd3, 0xf1, 0xdb, + 0xf1, 0xdb, 0x9a, 0xe5, 0x9a, 0xe5, 0x0c, 0xf0, 0x0c, 0xf0, 0xf7, 0xfa, 0xf7, 0xfa, 0x0a, + 0x06, 0x0a, 0x06, 0xee, 0x10, 0xee, 0x10, 0x51, 0x1b, 0x51, 0x1b, 0xe3, 0x24, 0xe3, 0x24, + 0x5d, 0x2d, 0x5d, 0x2d, 0x7c, 0x34, 0x7c, 0x34, 0x0c, 0x3a, 0x0c, 0x3a, 0xe1, 0x3d, 0xe1, + 0x3d, 0xde, 0x3f, 0xde, 0x3f, 0xf4, 0x3f, 0xf4, 0x3f, 0x23, 0x3e, 0x23, 0x3e, 0x78, 0x3a, + 0x78, 0x3a, 0x0f, 0x35, 0x0f, 0x35, 0x12, 0x2e, 0x12, 0x2e, 0xb5, 0x25, 0xb5, 0x25, 0x39, + 0x1c, 0x39, 0x1c, 0xe6, 0x11, 0xe6, 0x11, 0x0a, 0x07, 0x0a, 0x07, 0xf9, 0xfb, 0xf9, 0xfb, + 0x06, 0xf1, 0x06, 0xf1, 0x86, 0xe6, 0x86, 0xe6, 0xc7, 0xdc, 0xc7, 0xdc, 0x16, 0xd4, 0x16, + 0xd4, 0xb3, 0xcc, 0xb3, 0xcc, 0xd7, 0xc6, 0xd7, 0xc6, 0xaf, 0xc2, 0xaf, 0xc2, 0x5b, 0xc0, + 0x5b, 0xc0, 0xeb, 0xbf, 0xeb, 0xbf, 0x65, 0xc1, 0x65, 0xc1, 0xbb, 0xc4, 0xbb, 0xc4, 0xd6, + 0xc9, 0xd6, 0xc9, 0x8d, 0xd0, 0x8d, 0xd0, 0xae, 0xd8, 0xae, 0xd8, 0xfb, 0xe1, 0xfb, 0xe1, + 0x2d, 0xec, 0x2d, 0xec, 0xf6, 0xf6, 0xf6, 0xf6, 0x04, 0x02, 0x04, 0x02, 0x02, 0x0d, 0x02, + 0x0d, 0x9e, 0x17, 0x9e, 0x17, 0x85, 0x21, 0x85, 0x21, 0x6d, 0x2a, 0x6d, 0x2a, 0x11, 0x32, + 0x11, 0x32, 0x38, 0x38, 0x38, 0x38, 0xb1, 0x3c, 0xb1, 0x3c, 0x5d, 0x3f, 0x5d, 0x3f, 0x25, + 0x40, 0x25, 0x40, 0x04, 0x3f, 0x04, 0x3f, 0x03, 0x3c, 0x03, 0x3c, 0x38, 0x37, 0x38, 0x37, + 0xc8, 0x30, 0xc8, 0x30, 0xe4, 0x28, 0xe4, 0x28, 0xc9, 0x1f, 0xc9, 0x1f, 0xbb, 0x15, 0xbb, + 0x15, 0x08, 0x0b, 0x08, 0x0b, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xf4, 0xf8, 0xf4, 0x45, 0xea, + 0x45, 0xea, 0x37, 0xe0, 0x37, 0xe0, 0x1c, 0xd7, 0x1c, 0xd7, 0x38, 0xcf, 0x38, 0xcf, 0xc8, + 0xc8, 0xc8, 0xc8, 0xfd, 0xc3, 0xfd, 0xc3, 0xfc, 0xc0, 0xfc, 0xc0, 0xdb, 0xbf, 0xdb, 0xbf, + 0xa3, 0xc0, 0xa3, 0xc0, 0x4f, 0xc3, 0x4f, 0xc3, 0xc8, 0xc7, 0xc8, 0xc7, 0xef, 0xcd, 0xef, + 0xcd, 0x93, 0xd5, 0x93, 0xd5, 0x7b, 0xde, 0x7b, 0xde, 0x62, 0xe8, 0x62, 0xe8, 0xfe, 0xf2, + 0xfe, 0xf2, 0xfc, 0xfd, 0xfc, 0xfd, 0x0a, 0x09, 0x0a, 0x09, 0xd3, 0x13, 0xd3, 0x13, 0x05, + 0x1e, 0x05, 0x1e, 0x52, 0x27, 0x52, 0x27, 0x73, 0x2f, 0x73, 0x2f, 0x2a, 0x36, 0x2a, 0x36, + 0x45, 0x3b, 0x45, 0x3b, 0x9b, 0x3e, 0x9b, 0x3e, 0x15, 0x40, 0x15, 0x40, 0xa5, 0x3f, 0xa5, + 0x3f, 0x51, 0x3d, 0x51, 0x3d, 0x29, 0x39, 0x29, 0x39, 0x4d, 0x33, 0x4d, 0x33, 0xea, 0x2b, + 0xea, 0x2b, 0x39, 0x23, 0x39, 0x23, 0x7a, 0x19, 0x7a, 0x19, 0xfa, 0x0e, 0xfa, 0x0e, 0x07, + 0x04, 0x07, 0x04, 0xf6, 0xf8, 0xf6, 0xf8, 0x1a, 0xee, 0x1a, 0xee, 0xc7, 0xe3, 0xc7, 0xe3, + 0x4b, 0xda, 0x4b, 0xda, 0xee, 0xd1, 0xee, 0xd1, 0xf1, 0xca, 0xf1, 0xca, 0x88, 0xc5, 0x88, + 0xc5, 0xdd, 0xc1, 0xdd, 0xc1, 0x0c, 0xc0, 0x0c, 0xc0, 0x22, 0xc0, 0x22, 0xc0, 0x1f, 0xc2, + 0x1f, 0xc2, 0xf4, 0xc5, 0xf4, 0xc5, 0x84, 0xcb, 0x84, 0xcb, 0xa3, 0xd2, 0xa3, 0xd2, 0x1d, + 0xdb, 0x1d, 0xdb, 0xaf, 0xe4, 0xaf, 0xe4, 0x12, 0xef, 0x12, 0xef, 0xf6, 0xf9, 0xf6, 0xf9, + 0x09, 0x05, 0x09, 0x05, 0xf4, 0x0f, 0xf4, 0x0f, 0x66, 0x1a, 0x66, 0x1a, 0x0f, 0x24, 0x0f, + 0x24, 0xa5, 0x2c, 0xa5, 0x2c, 0xe6, 0x33, 0xe6, 0x33, 0x9c, 0x39, 0x9c, 0x39, 0x9b, 0x3d, + 0x9b, 0x3d, 0xc4, 0x3f, 0xc4, 0x3f, 0x06, 0x40, 0x06, 0x40, 0x61, 0x3e, 0x61, 0x3e, 0xe0, + 0x3a, 0xe0, 0x3a, 0x9e, 0x35, 0x9e, 0x35, 0xc4, 0x2e, 0xc4, 0x2e, 0x85, 0x26, 0x85, 0x26, + 0x20, 0x1d, 0x20, 0x1d, 0xdd, 0x12, 0xdd, 0x12, 0x0a, 0x08, 0x0a, 0x08, 0xfa, 0xfc, 0xfa, + 0xfc, 0x01, 0xf2, 0x01, 0xf2, 0x73, 0xe7, 0x73, 0xe7, 0xa0, 0xdd, 0xa0, 0xdd, 0xd3, 0xd4, + 0xd3, 0xd4, 0x4f, 0xcd, 0x4f, 0xcd, 0x4e, 0xc7, 0x4e, 0xc7, 0xfd, 0xc2, 0xfd, 0xc2, 0x7d, + 0xc0, 0x7d, 0xc0, 0xe1, 0xbf, 0xe1, 0xbf, 0x2e, 0xc1, 0x2e, 0xc1, 0x5a, 0xc4, 0x5a, 0xc4, + 0x4d, 0xc9, 0x4d, 0xc9, 0xe1, 0xcf, 0xe1, 0xcf, 0xe4, 0xd7, 0xe4, 0xd7, 0x18, 0xe1, 0x18, + 0xe1, 0x38, 0xeb, 0x38, 0xeb, 0xf7, 0xf5, 0xf7, 0xf5, 0x02, 0x01, 0x02, 0x01, 0x05, 0x0c, + 0x05, 0x0c, 0xad, 0x16, 0xad, 0x16, 0xa8, 0x20, 0xa8, 0x20, 0xaa, 0x29, 0xaa, 0x29, 0x6e, + 0x31, 0x6e, 0x31, 0xb9, 0x37, 0xb9, 0x37, 0x5c, 0x3c, 0x5c, 0x3c, 0x32, 0x3f, 0x32, 0x3f, + 0x27, 0x40, 0x27, 0x40, 0x32, 0x3f, 0x32, 0x3f, 0x5c, 0x3c, 0x5c, 0x3c, 0xb9, 0x37, 0xb9, + 0x37, 0x6e, 0x31, 0x6e, 0x31, 0xaa, 0x29, 0xaa, 0x29, 0xa8, 0x20, 0xa8, 0x20, 0xad, 0x16, + 0xad, 0x16, 0x05, 0x0c, 0x05, 0x0c, 0x02, 0x01, 0x02, 0x01, 0xf7, 0xf5, 0xf7, 0xf5, 0x38, + 0xeb, 0x38, 0xeb, 0x18, 0xe1, 0x18, 0xe1, 0xe4, 0xd7, 0xe4, 0xd7, 0xe1, 0xcf, 0xe1, 0xcf, + 0x4d, 0xc9, 0x4d, 0xc9, 0x5a, 0xc4, 0x5a, 0xc4, 0x2e, 0xc1, 0x2e, 0xc1, 0xe1, 0xbf, 0xe1, + 0xbf, 0x7d, 0xc0, 0x7d, 0xc0, 0xfd, 0xc2, 0xfd, 0xc2, 0x4e, 0xc7, 0x4e, 0xc7, 0x4f, 0xcd, + 0x4f, 0xcd, 0xd3, 0xd4, 0xd3, 0xd4, 0xa0, 0xdd, 0xa0, 0xdd, 0x73, 0xe7, 0x73, 0xe7, 0x01, + 0xf2, 0x01, 0xf2, 0xfa, 0xfc, 0xfa, 0xfc, 0x0a, 0x08, 0x0a, 0x08, 0xdd, 0x12, 0xdd, 0x12, + 0x20, 0x1d, 0x20, 0x1d, 0x85, 0x26, 0x85, 0x26, 0xc4, 0x2e, 0xc4, 0x2e, 0x9e, 0x35, 0x9e, + 0x35, 0xe0, 0x3a, 0xe0, 0x3a, 0x61, 0x3e, 0x61, 0x3e, 0x06, 0x40, 0x06, 0x40, 0xc4, 0x3f, + 0xc4, 0x3f, 0x9b, 0x3d, 0x9b, 0x3d, 0x9c, 0x39, 0x9c, 0x39, 0xe6, 0x33, 0xe6, 0x33, 0xa5, + 0x2c, 0xa5, 0x2c, 0x0f, 0x24, 0x0f, 0x24, 0x66, 0x1a, 0x66, 0x1a, 0xf4, 0x0f, 0xf4, 0x0f, + 0x09, 0x05, 0x09, 0x05, 0xf6, 0xf9, 0xf6, 0xf9, 0x12, 0xef, 0x12, 0xef, 0xaf, 0xe4, 0xaf, + 0xe4, 0x1d, 0xdb, 0x1d, 0xdb, 0xa3, 0xd2, 0xa3, 0xd2, 0x84, 0xcb, 0x84, 0xcb, 0xf4, 0xc5, + 0xf4, 0xc5, 0x1f, 0xc2, 0x1f, 0xc2, 0x22, 0xc0, 0x22, 0xc0, 0x0c, 0xc0, 0x0c, 0xc0, 0xdd, + 0xc1, 0xdd, 0xc1, 0x88, 0xc5, 0x88, 0xc5, 0xf1, 0xca, 0xf1, 0xca, 0xee, 0xd1, 0xee, 0xd1, + 0x4b, 0xda, 0x4b, 0xda, 0xc7, 0xe3, 0xc7, 0xe3, 0x1a, 0xee, 0x1a, 0xee, 0xf6, 0xf8, 0xf6, + 0xf8, 0x07, 0x04, 0x07, 0x04, 0xfa, 0x0e, 0xfa, 0x0e, 0x7a, 0x19, 0x7a, 0x19, 0x39, 0x23, + 0x39, 0x23, 0xea, 0x2b, 0xea, 0x2b, 0x4d, 0x33, 0x4d, 0x33, 0x29, 0x39, 0x29, 0x39, 0x51, + 0x3d, 0x51, 0x3d, 0xa5, 0x3f, 0xa5, 0x3f, 0x15, 0x40, 0x15, 0x40, 0x9b, 0x3e, 0x9b, 0x3e, + 0x45, 0x3b, 0x45, 0x3b, 0x2a, 0x36, 0x2a, 0x36, 0x73, 0x2f, 0x73, 0x2f, 0x52, 0x27, 0x52, + 0x27, 0x05, 0x1e, 0x05, 0x1e, 0xd3, 0x13, 0xd3, 0x13, 0x0a, 0x09, 0x0a, 0x09, 0xfc, 0xfd, + 0xfc, 0xfd, 0xfe, 0xf2, 0xfe, 0xf2, 0x62, 0xe8, 0x62, 0xe8, 0x7b, 0xde, 0x7b, 0xde, 0x93, + 0xd5, 0x93, 0xd5, 0xef, 0xcd, 0xef, 0xcd, 0xc8, 0xc7, 0xc8, 0xc7, 0x4f, 0xc3, 0x4f, 0xc3, + 0xa3, 0xc0, 0xa3, 0xc0, 0xdb, 0xbf, 0xdb, 0xbf, 0xfc, 0xc0, 0xfc, 0xc0, 0xfd, 0xc3, 0xfd, + 0xc3, 0xc8, 0xc8, 0xc8, 0xc8, 0x38, 0xcf, 0x38, 0xcf, 0x1c, 0xd7, 0x1c, 0xd7, 0x37, 0xe0, + 0x37, 0xe0, 0x45, 0xea, 0x45, 0xea, 0xf8, 0xf4, 0xf8, 0xf4}; + +#endif /* ZEPHYR_INCLUDE_SINE_H_ */ From 37b22586f68a84b6eb2811f6ec0d9bbda14c8680 Mon Sep 17 00:00:00 2001 From: Mark Wang Date: Tue, 26 Aug 2025 19:24:38 +0800 Subject: [PATCH 0751/3659] samples: bluetooth: a2dp: implement a2dp sink sample implement the a2dp sink sample, only mimxrt1170_evk@B board's codec is supported now. Signed-off-by: Mark Wang --- .../classic/a2dp_sink/CMakeLists.txt | 11 + samples/bluetooth/classic/a2dp_sink/Kconfig | 29 ++ .../bluetooth/classic/a2dp_sink/README.rst | 32 +++ .../mimxrt1170_evk_mimxrt1176_cm7_B.conf | 7 + .../mimxrt1170_evk_mimxrt1176_cm7_B.overlay | 21 ++ samples/bluetooth/classic/a2dp_sink/prj.conf | 9 + .../bluetooth/classic/a2dp_sink/sample.yaml | 21 ++ .../classic/a2dp_sink/src/audio_buf.c | 235 ++++++++++++++++ .../classic/a2dp_sink/src/audio_buf.h | 22 ++ .../classic/a2dp_sink/src/codec_play.c | 225 +++++++++++++++ .../classic/a2dp_sink/src/codec_play.h | 20 ++ .../bluetooth/classic/a2dp_sink/src/main.c | 266 ++++++++++++++++++ 12 files changed, 898 insertions(+) create mode 100644 samples/bluetooth/classic/a2dp_sink/CMakeLists.txt create mode 100644 samples/bluetooth/classic/a2dp_sink/Kconfig create mode 100644 samples/bluetooth/classic/a2dp_sink/README.rst create mode 100644 samples/bluetooth/classic/a2dp_sink/boards/mimxrt1170_evk_mimxrt1176_cm7_B.conf create mode 100644 samples/bluetooth/classic/a2dp_sink/boards/mimxrt1170_evk_mimxrt1176_cm7_B.overlay create mode 100644 samples/bluetooth/classic/a2dp_sink/prj.conf create mode 100644 samples/bluetooth/classic/a2dp_sink/sample.yaml create mode 100644 samples/bluetooth/classic/a2dp_sink/src/audio_buf.c create mode 100644 samples/bluetooth/classic/a2dp_sink/src/audio_buf.h create mode 100644 samples/bluetooth/classic/a2dp_sink/src/codec_play.c create mode 100644 samples/bluetooth/classic/a2dp_sink/src/codec_play.h create mode 100644 samples/bluetooth/classic/a2dp_sink/src/main.c diff --git a/samples/bluetooth/classic/a2dp_sink/CMakeLists.txt b/samples/bluetooth/classic/a2dp_sink/CMakeLists.txt new file mode 100644 index 000000000000..4f7d020fc048 --- /dev/null +++ b/samples/bluetooth/classic/a2dp_sink/CMakeLists.txt @@ -0,0 +1,11 @@ +#SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(a2dp_sink) + +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources}) + +zephyr_library_include_directories(${ZEPHYR_BASE}/samples/bluetooth) +target_include_directories(app PRIVATE src) diff --git a/samples/bluetooth/classic/a2dp_sink/Kconfig b/samples/bluetooth/classic/a2dp_sink/Kconfig new file mode 100644 index 000000000000..d222c99defb5 --- /dev/null +++ b/samples/bluetooth/classic/a2dp_sink/Kconfig @@ -0,0 +1,29 @@ +# +# Copyright 2025 NXP +# +# SPDX-License-Identifier: Apache-2.0 +# + +mainmenu "Bluetooth: A2DP Sink" + +config USE_CODEC_CLOCK + bool "I2S BCK is generated by a selected codec device" + help + If selected, the I2S selected peripheral will be configured to consume + (receive) the I2S BCK and WS signals and the codec will be configured + to generate those. If not selected, the I2S peripheral will generate + them and the codec will be expected to consume them. + +config A2DP_SBC_PCM_BUFFER_PLAY_COUNT + int "The buffer count that every size is 480*2*2 bytes" + default 50 + +config A2DP_BOARD_CODEC_PLAY_COUNT + int "The play count of the board codec interface (i2s)" + default 4 + +config A2DP_BOARD_CODEC_PLAY_THRESHOLD + int "The threshold of pcm buffer when playing data to codec (n%)" + default 20 + +source "Kconfig.zephyr" diff --git a/samples/bluetooth/classic/a2dp_sink/README.rst b/samples/bluetooth/classic/a2dp_sink/README.rst new file mode 100644 index 000000000000..f38597670536 --- /dev/null +++ b/samples/bluetooth/classic/a2dp_sink/README.rst @@ -0,0 +1,32 @@ +.. zephyr:code-sample:: bluetooth_a2dp_sink + :name: A2DP Sink + :relevant-api: bt_a2dp bluetooth + + Use A2DP (Advanced Audio Distribution Profile) sink functionality. + +Overview +******** + +This sample demonstrates the A2DP (Advanced Audio Distribution Profile) sink +functionality using Zephyr's Bluetooth Classic APIs. The application acts as an +A2DP sink device, it can be discovered and connected from A2DP source devices +such as smartphones, tablets, and computers, and receive and process audio streams +from A2DP source devices. + +Requirements +************ + +* Running on the host with Bluetooth BR/EDR (Classic) support, or +* A board with Bluetooth BR/EDR (Classic) support + +Building and Running +******************** + +1. Build and flash the sample to the board. +2. The device will become discoverable as "a2dp_sink". +3. Connect and stream audio on your A2DP source device. + +This sample can be found under :zephyr_file:`samples/bluetooth/classic/a2dp_sink` in +the Zephyr tree. + +See :zephyr:code-sample-category:`bluetooth` samples for details. diff --git a/samples/bluetooth/classic/a2dp_sink/boards/mimxrt1170_evk_mimxrt1176_cm7_B.conf b/samples/bluetooth/classic/a2dp_sink/boards/mimxrt1170_evk_mimxrt1176_cm7_B.conf new file mode 100644 index 000000000000..809e58d1fc3b --- /dev/null +++ b/samples/bluetooth/classic/a2dp_sink/boards/mimxrt1170_evk_mimxrt1176_cm7_B.conf @@ -0,0 +1,7 @@ +#select NXP NW612 Chipset +CONFIG_BT_NXP_NW612=y + +CONFIG_I2S=y +CONFIG_AUDIO=y +CONFIG_AUDIO_CODEC=y +CONFIG_DMA_TCD_QUEUE_SIZE=4 diff --git a/samples/bluetooth/classic/a2dp_sink/boards/mimxrt1170_evk_mimxrt1176_cm7_B.overlay b/samples/bluetooth/classic/a2dp_sink/boards/mimxrt1170_evk_mimxrt1176_cm7_B.overlay new file mode 100644 index 000000000000..2860bd75edfa --- /dev/null +++ b/samples/bluetooth/classic/a2dp_sink/boards/mimxrt1170_evk_mimxrt1176_cm7_B.overlay @@ -0,0 +1,21 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + chosen { + zephyr,sram = &ocram1; + }; +}; + +&sai1 { + mclk-output; + podf = <32>; + pll-clocks = <&anatop 0 0 0>, + <&anatop 0 0 30>, + <&anatop 0 0 1>, + <&anatop 0 0 106>, + <&anatop 0 0 1000>; +}; diff --git a/samples/bluetooth/classic/a2dp_sink/prj.conf b/samples/bluetooth/classic/a2dp_sink/prj.conf new file mode 100644 index 000000000000..2f7af4ff40bf --- /dev/null +++ b/samples/bluetooth/classic/a2dp_sink/prj.conf @@ -0,0 +1,9 @@ +CONFIG_BT=y +CONFIG_BT_CLASSIC=y +CONFIG_BT_PERIPHERAL=y +CONFIG_BT_AVDTP=y +CONFIG_BT_A2DP=y +CONFIG_BT_A2DP_SINK=y +CONFIG_BT_DEVICE_NAME="a2dp_sink" +CONFIG_BT_COD=0x200404 +CONFIG_BT_BUF_ACL_RX_SIZE=1300 diff --git a/samples/bluetooth/classic/a2dp_sink/sample.yaml b/samples/bluetooth/classic/a2dp_sink/sample.yaml new file mode 100644 index 000000000000..8910833cbdd8 --- /dev/null +++ b/samples/bluetooth/classic/a2dp_sink/sample.yaml @@ -0,0 +1,21 @@ +sample: + name: Bluetooth A2DP Sink +tests: + sample.bluetooth.a2dp.sink: + harness: bluetooth + platform_allow: + - qemu_cortex_m3 + - qemu_x86 + tags: bluetooth + integration_platforms: + - qemu_cortex_m3 + sample.bluetooth.a2dp.sink.no_blobs: + platform_allow: + - mimxrt1170_evk@B/mimxrt1176/cm7 + tags: + - bluetooth + - gap + extra_args: + - CONFIG_BUILD_ONLY_NO_BLOBS=y + timeout: 600 + build_only: true diff --git a/samples/bluetooth/classic/a2dp_sink/src/audio_buf.c b/samples/bluetooth/classic/a2dp_sink/src/audio_buf.c new file mode 100644 index 000000000000..cd93b0be098f --- /dev/null +++ b/samples/bluetooth/classic/a2dp_sink/src/audio_buf.c @@ -0,0 +1,235 @@ +/* + * Copyright 2024-2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "audio_buf.h" + +#if DT_HAS_ALIAS(i2s_codec_tx) && IS_ENABLED(CONFIG_I2S) && IS_ENABLED(CONFIG_AUDIO_CODEC) + +/* The whole PCM buffer (save the audio data after decoding) size */ +#define A2DP_SBC_DECODER_PCM_BUFFER_SIZE (A2DP_SBC_DATA_PLAY_SIZE_48K *\ + CONFIG_A2DP_SBC_PCM_BUFFER_PLAY_COUNT) +uint32_t pcm_buffer_size; /* set it dynamically based on frequency */ +/* The PCM data size for one sbc frame + * (channel num: 2, sample size: 2, max subband: 8, max block length: 16) + */ +#define A2DP_SBC_ONE_FRAME_MAX_SIZE (2 * 2 * 16 * 8) +/* audio stream control variables */ +static volatile uint32_t pcm_r; +static volatile uint32_t pcm_w; +static volatile uint32_t pcm_rm; +static volatile uint32_t pcm_w_count; +static volatile uint32_t pcm_r_count; +static volatile uint32_t pcm_rm_count; +static struct sbc_decoder decoder; +static volatile bool sbc_first_data; +static uint32_t sbc_expected_ts; +static uint16_t pcm_frame_buffer[A2DP_SBC_ONE_FRAME_MAX_SIZE / 2]; +static __aligned(4) uint8_t decoded_pcm_buf[A2DP_SBC_DECODER_PCM_BUFFER_SIZE]; + +static uint32_t audio_pcm_buffer_free_size(void) +{ + /* Calculate available data space, handling uint32_t wraparound. + * Direct subtraction works correctly even when pcm_w_count wraps around: + * - Normal case (pcm_w_count >= pcm_rm_count): data_space = pcm_w_count - pcm_rm_count + * - Wraparound case (pcm_w_count < pcm_rm_count): unsigned arithmetic automatically + * produces the correct result due to modulo 2^32 behavior. + */ + return pcm_buffer_size - (pcm_w_count - pcm_rm_count); +} + +static uint32_t audio_add_pcm_data(uint8_t *data, uint32_t length) +{ + uint32_t free_space; + + free_space = audio_pcm_buffer_free_size(); + + if (free_space < length) { + length = free_space; + } + + /* copy data to buffer */ + if ((pcm_w + length) <= pcm_buffer_size) { + if (data != NULL) { + memcpy(&decoded_pcm_buf[pcm_w], data, length); + } else { + memset(&decoded_pcm_buf[pcm_w], 0, length); + } + + pcm_w += length; + } else { + if (data != NULL) { + memcpy(&decoded_pcm_buf[pcm_w], data, (pcm_buffer_size - pcm_w)); + memcpy(&decoded_pcm_buf[0], &data[(pcm_buffer_size - pcm_w)], + length - (pcm_buffer_size - pcm_w)); + } else { + memset(&decoded_pcm_buf[pcm_w], 0, (pcm_buffer_size - pcm_w)); + memset(&decoded_pcm_buf[0], 0, length - (pcm_buffer_size - pcm_w)); + } + + pcm_w = length - (pcm_buffer_size - pcm_w); + } + pcm_w_count += length; + + if (pcm_w == pcm_buffer_size) { + pcm_w = 0; + } + + return length; +} + +int audio_media_sync(uint8_t *data, uint16_t datalen) +{ + if (data != NULL) { + pcm_rm += datalen; + pcm_rm_count += datalen; + + if (pcm_rm >= pcm_buffer_size) { + pcm_rm -= pcm_buffer_size; + } + } + + return 0; +} + +void audio_get_pcm_data(uint8_t **data, uint32_t length) +{ + static bool reach_threshold; + uint32_t data_space; + uint32_t w_count = pcm_w_count; + uint32_t r_count = pcm_r_count; + + /* Calculate available data space, handling uint32_t wraparound. + * Direct subtraction works correctly even when w_count wraps around: + * - Normal case (w_count >= r_count): data_space = w_count - r_count + * - Wraparound case (w_count < r_count): unsigned arithmetic automatically + * produces the correct result due to modulo 2^32 behavior. + * Example: w_count=5, r_count=0xFFFFFFF0 + * Result: 5 - 0xFFFFFFF0 = 0x15 (21 in decimal), which is correct + * because w_count has wrapped and is actually 0x100000005 in the sequence. + */ + data_space = w_count - r_count; + + if (!reach_threshold) { + if (data_space > CONFIG_A2DP_BOARD_CODEC_PLAY_THRESHOLD * pcm_buffer_size / 100) { + reach_threshold = true; + } else { + *data = NULL; + return; + } + } + + if (data_space < length) { + *data = NULL; + reach_threshold = false; + } else { + pcm_r_count += length; + *data = &decoded_pcm_buf[pcm_r]; + pcm_r += length; + + if (pcm_r >= pcm_buffer_size) { + pcm_r = 0; + } + } +} + +void audio_process_sbc_buf(uint8_t sbc_hdr, uint8_t *data, size_t len, uint16_t seq_num, + uint32_t ts, uint8_t channel_num) +{ + const void *in_data; + size_t samples_count; + size_t out_size; + size_t samples_lost; + uint8_t num_frames; + int err; + + samples_lost = 0; + + if (!sbc_first_data) { + sbc_first_data = true; + sbc_expected_ts = ts; + } else { + if (sbc_expected_ts != ts) { + if (sbc_expected_ts < ts) { + samples_lost = ts - sbc_expected_ts; + } + } + } + + if (samples_lost != 0) { + (void)audio_add_pcm_data(NULL, samples_lost * 2U * channel_num); + sbc_expected_ts = sbc_expected_ts + samples_lost; + } + + num_frames = BT_A2DP_SBC_MEDIA_HDR_NUM_FRAMES_GET(sbc_hdr); + + samples_count = 0; + in_data = (void *)data; + for (uint8_t i = 0; i < num_frames; ++i) { + if (audio_pcm_buffer_free_size() == 0) { + /* if no enough space, don't need decode. */ + continue; + } + + out_size = sizeof(pcm_frame_buffer); + err = sbc_decode(&decoder, &in_data, &len, pcm_frame_buffer, &out_size); + + if (err == 0) { + audio_add_pcm_data((uint8_t *)pcm_frame_buffer, out_size); + } else { + printk("decode err\n"); + break; + } + + samples_count += (out_size / 2 / channel_num); + } + + sbc_expected_ts = ts + samples_count; +} + +void audio_buf_reset(uint32_t fs) +{ + pcm_r = 0; + pcm_w = 0; + pcm_rm = 0; + pcm_w_count = 0; + pcm_r_count = 0; + pcm_rm_count = 0; + + sbc_setup_decoder(&decoder); + + if (fs == 48000) { + pcm_buffer_size = A2DP_SBC_DECODER_PCM_BUFFER_SIZE; + } else if (fs == 44100) { + pcm_buffer_size = A2DP_SBC_DECODER_PCM_BUFFER_SIZE - + A2DP_SBC_DECODER_PCM_BUFFER_SIZE % A2DP_SBC_DATA_PLAY_SIZE_44_1K; + } else { + printk("wrong frequency\n"); + } + + sbc_first_data = false; +} + +#else + +void audio_buf_reset(uint32_t fs) +{ +} + +void audio_process_sbc_buf(uint8_t sbc_hdr, uint8_t *data, size_t len, uint16_t seq_num, + uint32_t ts, uint8_t channel_num) +{ +} + +#endif diff --git a/samples/bluetooth/classic/a2dp_sink/src/audio_buf.h b/samples/bluetooth/classic/a2dp_sink/src/audio_buf.h new file mode 100644 index 000000000000..2abd84da1292 --- /dev/null +++ b/samples/bluetooth/classic/a2dp_sink/src/audio_buf.h @@ -0,0 +1,22 @@ +/* + * Copyright 2024-2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_AUDIO_BUF_H_ +#define ZEPHYR_INCLUDE_AUDIO_BUF_H_ + +/* The played audio data is 10ms data size */ +#define A2DP_SBC_DATA_PLAY_SIZE_44_1K (441 * 2 * 2) +#define A2DP_SBC_DATA_PLAY_SIZE_48K (480 * 2 * 2) + +void audio_buf_reset(uint32_t fs); + +void audio_process_sbc_buf(uint8_t sbc_hdr, uint8_t *data, size_t len, uint16_t seq_num, + uint32_t ts, uint8_t channel_num); + +int audio_media_sync(uint8_t *data, uint16_t datalen); + +void audio_get_pcm_data(uint8_t **data, uint32_t length); +#endif diff --git a/samples/bluetooth/classic/a2dp_sink/src/codec_play.c b/samples/bluetooth/classic/a2dp_sink/src/codec_play.c new file mode 100644 index 000000000000..afb5ce0fedcf --- /dev/null +++ b/samples/bluetooth/classic/a2dp_sink/src/codec_play.c @@ -0,0 +1,225 @@ +/* + * Copyright 2024-2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "audio_buf.h" +#include "codec_play.h" + +#if DT_HAS_ALIAS(i2s_codec_tx) && IS_ENABLED(CONFIG_I2S) && IS_ENABLED(CONFIG_AUDIO_CODEC) + +#if CONFIG_NOCACHE_MEMORY +#define __NOCACHE __attribute__((__section__(".nocache"))) +#elif defined(CONFIG_DT_DEFINED_NOCACHE) +#define __NOCACHE __attribute__((__section__(CONFIG_DT_DEFINED_NOCACHE_NAME))) +#else /* CONFIG_NOCACHE_MEMORY */ +#define __NOCACHE +#endif /* CONFIG_NOCACHE_MEMORY */ + +/* audio stream control variables */ +static volatile bool audio_start; +static uint32_t audio_sample_rate; +static uint8_t *audio_data_sync_buf[CONFIG_A2DP_BOARD_CODEC_PLAY_COUNT]; +static uint32_t audio_data_sync_buf_size[CONFIG_A2DP_BOARD_CODEC_PLAY_COUNT]; +static uint8_t audio_data_sync_buf_w; +static uint8_t audio_data_sync_buf_r; +static __NOCACHE __aligned(4) uint8_t a2dp_silence_data[A2DP_SBC_DATA_PLAY_SIZE_48K]; +#define I2S_CODEC_TX DT_ALIAS(i2s_codec_tx) +#define I2S_TIMEOUT (2000U) + +const struct device *const codec_tx = DEVICE_DT_GET(I2S_CODEC_TX); + +static __NOCACHE __aligned(4) uint8_t mem_slab_buffer[CONFIG_A2DP_BOARD_CODEC_PLAY_COUNT * + A2DP_SBC_DATA_PLAY_SIZE_48K]; +static struct k_mem_slab mem_slab; + +int codec_play_init(void) +{ + const struct device *const codec_dev = DEVICE_DT_GET(DT_NODELABEL(audio_codec)); + + if (!device_is_ready(codec_tx)) { + printk("%s is not ready\n", codec_tx->name); + return -EIO; + } + + if (!device_is_ready(codec_dev)) { + printk("%s is not ready\n", codec_dev->name); + return -EIO; + } + + return 0; +} + +void codec_play_configure(uint32_t sample_rate, uint8_t sample_width, uint8_t channels) +{ + const struct device *const codec_dev = DEVICE_DT_GET(DT_NODELABEL(audio_codec)); + struct i2s_config config; + struct audio_codec_cfg audio_cfg; + size_t block_size; + + audio_sample_rate = sample_rate; + if (sample_rate == 44100) { + block_size = A2DP_SBC_DATA_PLAY_SIZE_44_1K; + } else { + block_size = A2DP_SBC_DATA_PLAY_SIZE_48K; + } + + audio_cfg.dai_route = AUDIO_ROUTE_PLAYBACK; + audio_cfg.dai_type = AUDIO_DAI_TYPE_I2S; + audio_cfg.dai_cfg.i2s.word_size = sample_width; + audio_cfg.dai_cfg.i2s.channels = channels; + audio_cfg.dai_cfg.i2s.format = I2S_FMT_DATA_FORMAT_I2S; +#ifdef CONFIG_USE_CODEC_CLOCK + audio_cfg.dai_cfg.i2s.options = I2S_OPT_FRAME_CLK_MASTER | I2S_OPT_BIT_CLK_MASTER; +#else + audio_cfg.dai_cfg.i2s.options = I2S_OPT_FRAME_CLK_SLAVE | I2S_OPT_BIT_CLK_SLAVE; +#endif + audio_cfg.dai_cfg.i2s.frame_clk_freq = sample_rate; + audio_cfg.dai_cfg.i2s.mem_slab = &mem_slab; + audio_cfg.dai_cfg.i2s.block_size = block_size; + audio_codec_configure(codec_dev, &audio_cfg); + k_msleep(1000); + + config.word_size = sample_width; + config.channels = channels; + config.format = I2S_FMT_DATA_FORMAT_I2S; +#ifdef CONFIG_USE_CODEC_CLOCK + config.options = I2S_OPT_BIT_CLK_SLAVE | I2S_OPT_FRAME_CLK_SLAVE; +#else + config.options = I2S_OPT_BIT_CLK_MASTER | I2S_OPT_FRAME_CLK_MASTER; +#endif + config.frame_clk_freq = sample_rate; + config.mem_slab = &mem_slab; + config.block_size = block_size; + config.timeout = I2S_TIMEOUT; + if (i2s_configure(codec_tx, I2S_DIR_TX, &config)) { + printk("failure to config streams\n"); + } + + k_mem_slab_init(&mem_slab, mem_slab_buffer, block_size, CONFIG_A2DP_BOARD_CODEC_PLAY_COUNT); +} + +static void codec_play_to_dev(uint8_t *data, uint32_t length) +{ + int ret; + + ret = i2s_buf_write(codec_tx, data, length); + if (ret < 0) { + printk("Failed to write data: %d\n", ret); + } +} + +static void codec_play_data(uint8_t *data, uint32_t length) +{ + audio_data_sync_buf[audio_data_sync_buf_w % CONFIG_A2DP_BOARD_CODEC_PLAY_COUNT] = data; + audio_data_sync_buf_size[audio_data_sync_buf_w % CONFIG_A2DP_BOARD_CODEC_PLAY_COUNT] = + length; + audio_data_sync_buf_w++; + + if (!audio_start) { + return; + } + + if ((data != NULL) && (length != 0U)) { + codec_play_to_dev(data, length); + } else { + codec_play_to_dev(a2dp_silence_data, + audio_sample_rate == 48000 ? + A2DP_SBC_DATA_PLAY_SIZE_48K : A2DP_SBC_DATA_PLAY_SIZE_44_1K); + } +} + +void codec_play_start(void) +{ + if (audio_start) { + return; + } + + audio_start = true; + + for (uint8_t i = 0; i < CONFIG_A2DP_BOARD_CODEC_PLAY_COUNT; i++) { + codec_play_data(a2dp_silence_data, + audio_sample_rate == 48000 ? + A2DP_SBC_DATA_PLAY_SIZE_48K : A2DP_SBC_DATA_PLAY_SIZE_44_1K); + + if (i == 0) { + i2s_trigger(codec_tx, I2S_DIR_TX, I2S_TRIGGER_START); + } + } +} + +void codec_play_stop(void) +{ + if (!audio_start) { + return; + } + + audio_start = false; + /* Don't need to stop codec_tx. After all the written buf is sent, the I2S tx is stopped. */ + /* i2s_trigger(codec_tx, I2S_DIR_TX, I2S_TRIGGER_STOP); */ +} + +void codec_keep_play(void) +{ + uint8_t *get_data; + uint32_t length; + + while (true) { + if (!audio_start) { + continue; + } + + if (audio_sample_rate == 44100) { + length = A2DP_SBC_DATA_PLAY_SIZE_44_1K; + } else { + length = A2DP_SBC_DATA_PLAY_SIZE_48K; + } + /* play data */ + audio_get_pcm_data(&get_data, length); + codec_play_data(get_data, length); + + /* sync the already played media data */ + audio_media_sync(audio_data_sync_buf[audio_data_sync_buf_r % + CONFIG_A2DP_BOARD_CODEC_PLAY_COUNT], + audio_data_sync_buf_size[audio_data_sync_buf_r % + CONFIG_A2DP_BOARD_CODEC_PLAY_COUNT]); + + audio_data_sync_buf_r++; + } +} + +#else + +void codec_play_configure(uint32_t sample_rate, uint8_t sample_width, uint8_t channels) +{ + printk("Codec is unsupported\n"); +} + +int codec_play_init(void) +{ + return 0; +} + +void codec_play_start(void) +{ +} + +void codec_play_stop(void) +{ +} + +void codec_keep_play(void) +{ +} + +#endif diff --git a/samples/bluetooth/classic/a2dp_sink/src/codec_play.h b/samples/bluetooth/classic/a2dp_sink/src/codec_play.h new file mode 100644 index 000000000000..d8a283821144 --- /dev/null +++ b/samples/bluetooth/classic/a2dp_sink/src/codec_play.h @@ -0,0 +1,20 @@ +/* + * Copyright 2024-2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_CODEC_PLAY_H_ +#define ZEPHYR_INCLUDE_CODEC_PLAY_H_ + +int codec_play_init(void); + +void codec_play_configure(uint32_t sample_rate, uint8_t sample_width, uint8_t channels); + +void codec_play_start(void); + +void codec_play_stop(void); + +void codec_keep_play(void); + +#endif diff --git a/samples/bluetooth/classic/a2dp_sink/src/main.c b/samples/bluetooth/classic/a2dp_sink/src/main.c new file mode 100644 index 000000000000..aabf31c2ee7a --- /dev/null +++ b/samples/bluetooth/classic/a2dp_sink/src/main.c @@ -0,0 +1,266 @@ +/* main.c - Application main entry point */ + +/* + * Copyright 2024-2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include "audio_buf.h" +#include "codec_play.h" + +#define SAMPLE_BIT_WIDTH (16U) + +struct bt_a2dp *default_a2dp; +BT_A2DP_SBC_SINK_EP_DEFAULT(sbc_sink_ep); +static struct bt_a2dp_stream sbc_stream; +BT_A2DP_SBC_EP_CFG_DEFAULT(sbc_cfg, A2DP_SBC_SAMP_FREQ_44100); + +#define A2DP_VERSION 0x0104 + +static struct bt_sdp_attribute a2dp_sink_attrs[] = { + BT_SDP_NEW_SERVICE, + BT_SDP_LIST( + BT_SDP_ATTR_SVCLASS_ID_LIST, + BT_SDP_TYPE_SIZE_VAR(BT_SDP_SEQ8, 3), /* 35 03 */ + BT_SDP_DATA_ELEM_LIST( + { + BT_SDP_TYPE_SIZE(BT_SDP_UUID16), /* 19 */ + BT_SDP_ARRAY_16(BT_SDP_AUDIO_SINK_SVCLASS) /* 11 0B */ + }, + ) + ), + BT_SDP_LIST( + BT_SDP_ATTR_PROTO_DESC_LIST, + BT_SDP_TYPE_SIZE_VAR(BT_SDP_SEQ8, 16),/* 35 10 */ + BT_SDP_DATA_ELEM_LIST( + { + BT_SDP_TYPE_SIZE_VAR(BT_SDP_SEQ8, 6),/* 35 06 */ + BT_SDP_DATA_ELEM_LIST( + { + BT_SDP_TYPE_SIZE(BT_SDP_UUID16), /* 19 */ + BT_SDP_ARRAY_16(BT_SDP_PROTO_L2CAP) /* 01 00 */ + }, + { + BT_SDP_TYPE_SIZE(BT_SDP_UINT16), /* 09 */ + BT_SDP_ARRAY_16(BT_UUID_AVDTP_VAL) /* 00 19 */ + }, + ) + }, + { + BT_SDP_TYPE_SIZE_VAR(BT_SDP_SEQ8, 6),/* 35 06 */ + BT_SDP_DATA_ELEM_LIST( + { + BT_SDP_TYPE_SIZE(BT_SDP_UUID16), /* 19 */ + BT_SDP_ARRAY_16(BT_UUID_AVDTP_VAL) /* 00 19 */ + }, + { + BT_SDP_TYPE_SIZE(BT_SDP_UINT16), /* 09 */ + BT_SDP_ARRAY_16(AVDTP_VERSION) /* AVDTP version: 01 03 */ + }, + ) + }, + ) + ), + BT_SDP_LIST( + BT_SDP_ATTR_PROFILE_DESC_LIST, + BT_SDP_TYPE_SIZE_VAR(BT_SDP_SEQ8, 8), /* 35 08 */ + BT_SDP_DATA_ELEM_LIST( + { + BT_SDP_TYPE_SIZE_VAR(BT_SDP_SEQ8, 6), /* 35 06 */ + BT_SDP_DATA_ELEM_LIST( + { + BT_SDP_TYPE_SIZE(BT_SDP_UUID16), /* 19 */ + BT_SDP_ARRAY_16(BT_SDP_ADVANCED_AUDIO_SVCLASS) /* 11 0d */ + }, + { + BT_SDP_TYPE_SIZE(BT_SDP_UINT16), /* 09 */ + BT_SDP_ARRAY_16(A2DP_VERSION) /* 01 04 */ + }, + ) + }, + ) + ), + BT_SDP_SERVICE_NAME("A2DPSink"), + BT_SDP_SUPPORTED_FEATURES(0x0001U), +}; + +static struct bt_sdp_record a2dp_sink_rec = BT_SDP_RECORD(a2dp_sink_attrs); + +static void sbc_stop_play(void) +{ + printk("stream stopped\n"); + codec_play_stop(); +} + +void sbc_stream_configured(struct bt_a2dp_stream *stream) +{ + uint32_t sample_freq; + uint8_t channel_num; + struct bt_a2dp_codec_sbc_params *sbc_config = (struct bt_a2dp_codec_sbc_params *) + &sbc_cfg.codec_config->codec_ie[0]; + + channel_num = bt_a2dp_sbc_get_channel_num(sbc_config); + sample_freq = bt_a2dp_sbc_get_sampling_frequency(sbc_config); + codec_play_configure(sample_freq, SAMPLE_BIT_WIDTH, channel_num); + + printk("stream configured\n"); +} + +void sbc_stream_established(struct bt_a2dp_stream *stream) +{ + printk("stream established\n"); +} + +void sbc_stream_released(struct bt_a2dp_stream *stream) +{ + sbc_stop_play(); +} + +void sbc_stream_started(struct bt_a2dp_stream *stream) +{ + printk("stream started\n"); + + uint32_t sample_freq; + struct bt_a2dp_codec_sbc_params *sbc_config = (struct bt_a2dp_codec_sbc_params *) + &sbc_cfg.codec_config->codec_ie[0]; + + sample_freq = bt_a2dp_sbc_get_sampling_frequency(sbc_config); + audio_buf_reset(sample_freq); + codec_play_start(); +} + +void sbc_stream_suspended(struct bt_a2dp_stream *stream) +{ + sbc_stop_play(); +} + +void sbc_stream_recv(struct bt_a2dp_stream *stream, struct net_buf *buf, uint16_t seq_num, + uint32_t ts) +{ + uint8_t channel_num; + struct bt_a2dp_codec_sbc_params *sbc_config = (struct bt_a2dp_codec_sbc_params *) + &sbc_cfg.codec_config->codec_ie[0]; + + channel_num = bt_a2dp_sbc_get_channel_num(sbc_config); + + audio_process_sbc_buf(net_buf_pull_u8(buf), buf->data, buf->len, seq_num, ts, channel_num); +} + +static struct bt_a2dp_stream_ops stream_ops = { + .configured = sbc_stream_configured, + .established = sbc_stream_established, + .released = sbc_stream_released, + .started = sbc_stream_started, + .suspended = sbc_stream_suspended, + .recv = sbc_stream_recv, +}; + +void app_a2dp_connected(struct bt_a2dp *a2dp, int err) +{ + if (err == 0) { + default_a2dp = a2dp; + printk("a2dp connected success\n"); + } else { + printk("a2dp connected fail\n"); + } +} + +void app_a2dp_disconnected(struct bt_a2dp *a2dp) +{ + default_a2dp = NULL; + codec_play_stop(); + printk("a2dp disconnected\n"); +} + +int app_a2dp_config_req(struct bt_a2dp *a2dp, struct bt_a2dp_ep *ep, + struct bt_a2dp_codec_cfg *codec_cfg, struct bt_a2dp_stream **stream, + uint8_t *rsp_err_code) +{ + uint32_t sample_rate; + + *sbc_cfg.codec_config = *codec_cfg->codec_config; + + bt_a2dp_stream_cb_register(&sbc_stream, &stream_ops); + *stream = &sbc_stream; + *rsp_err_code = 0; + + printk("receive requesting config and accept\n"); + sample_rate = bt_a2dp_sbc_get_sampling_frequency( + (struct bt_a2dp_codec_sbc_params *)&codec_cfg->codec_config->codec_ie[0]); + printk("sample rate %dHz\n", sample_rate); + + return 0; +} + +static struct bt_a2dp_cb a2dp_cb = { + .connected = app_a2dp_connected, + .disconnected = app_a2dp_disconnected, + .config_req = app_a2dp_config_req, +}; + +static void bt_ready(int err) +{ + if (err != 0) { + printk("Bluetooth init failed (err %d)\n", err); + return; + } + + if (IS_ENABLED(CONFIG_SETTINGS)) { + settings_load(); + } + + printk("Bluetooth initialized\n"); + + bt_sdp_register_service(&a2dp_sink_rec); + + bt_a2dp_register_ep(&sbc_sink_ep, BT_AVDTP_AUDIO, BT_AVDTP_SINK); + bt_a2dp_register_cb(&a2dp_cb); + + err = bt_br_set_connectable(true); + if (err != 0) { + printk("BR/EDR set/rest connectable failed (err %d)\n", err); + return; + } + err = bt_br_set_discoverable(true, false); + if (err != 0) { + printk("BR/EDR set discoverable failed (err %d)\n", err); + return; + } + + printk("BR/EDR set connectable and discoverable done\n"); +} + +int main(void) +{ + int err; + + if (codec_play_init() != 0) { + printk("codec initialization fail\n"); + return 0; + } + + err = bt_enable(bt_ready); + if (err != 0) { + printk("Bluetooth init failed (err %d)\n", err); + return 0; + } + + codec_keep_play(); + + return 0; +} From 8fbdc4bc69ca569540509847d61cc49a458cc316 Mon Sep 17 00:00:00 2001 From: Vincent Liao Date: Wed, 17 Dec 2025 12:20:09 +0800 Subject: [PATCH 0752/3659] drivers: misc: pio_rpi_pico: fix linker error with -O0 The pio_rpi_pico_get_pio function was defined as 'inline' in the header file. This caused 'undefined reference' linker errors when building with CONFIG_NO_OPTIMIZATIONS=y (-O0), as the compiler doesn't inline the function and no external symbol is provided. This patch changes the definition to 'static inline' to ensure a local copy is generated in each translation unit when not inlined, consistent with other helper functions in Zephyr and the Linux kernel. Fixes #101155 Signed-off-by: Vincent Liao --- include/zephyr/drivers/misc/pio_rpi_pico/pio_rpi_pico.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/zephyr/drivers/misc/pio_rpi_pico/pio_rpi_pico.h b/include/zephyr/drivers/misc/pio_rpi_pico/pio_rpi_pico.h index 3339391c0ae5..e4498fe1f348 100644 --- a/include/zephyr/drivers/misc/pio_rpi_pico/pio_rpi_pico.h +++ b/include/zephyr/drivers/misc/pio_rpi_pico/pio_rpi_pico.h @@ -148,7 +148,7 @@ * @param dev Pointer to device structure for rpi_pio device instance * @return PIO object */ -inline PIO pio_rpi_pico_get_pio(const struct device *dev) +static inline PIO pio_rpi_pico_get_pio(const struct device *dev) { return *(PIO *)(dev->config); } From ae21970a79de6aa9bd0b1fbd7a76c61c210ea5bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5vard=20Reierstad?= Date: Thu, 18 Dec 2025 08:58:42 +0100 Subject: [PATCH 0753/3659] Bluetooth: Host: Add L2CAP chan send warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds a warning to `bt_l2cap_chan_send` that the user must not pass buffers to this function whose pool has implemented a destroy callback (net_buf_pool::destroy) that uses synchronization primitives. This is due to the HCI driver interface not having defined rules for where a buffer may be freed, leading to the possibility of the callback being called from the ISR. This warning can be removed at a later point if the HCI driver interface is redesigned to not pass the net_bufs directly. Signed-off-by: Håvard Reierstad --- include/zephyr/bluetooth/l2cap.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/zephyr/bluetooth/l2cap.h b/include/zephyr/bluetooth/l2cap.h index 633d2b0bc478..782303be6c29 100644 --- a/include/zephyr/bluetooth/l2cap.h +++ b/include/zephyr/bluetooth/l2cap.h @@ -1046,6 +1046,12 @@ int bt_l2cap_chan_disconnect(struct bt_l2cap_chan *chan); * @note Buffer ownership is transferred to the stack in case of success, in * case of an error the caller retains the ownership of the buffer. * + * @warning If the buffer's pool has a destroy callback defined, that callback + * may be invoked from the ISR context when the HCI driver releases the buffer. + * Thus, the destroy callback must not call any synchronization primitives + * that are unsafe in the ISR context, i. e. blocking calls or locking the + * scheduler. + * * @param chan The channel to send the data to. See @ref bt_l2cap_chan_connect * for more details. * @param buf Buffer containing the data. From cf04a046803e2cc433365d8da3f713b4c4aa2bf8 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Thu, 18 Dec 2025 12:11:46 +0100 Subject: [PATCH 0754/3659] net: mqtt: Allow to force native TLS on MQTT socket Add a parameter to MQTT TLS configuration that allows to force native TLS on a socket if offload dispatcher is used. This allows for MQTT to use native TLS implementation with an offloaded TCP socket. Signed-off-by: Robert Lubos --- doc/connectivity/networking/api/mqtt.rst | 4 ++++ include/zephyr/net/mqtt.h | 3 +++ subsys/net/lib/mqtt/mqtt_transport_socket_tls.c | 12 ++++++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/connectivity/networking/api/mqtt.rst b/doc/connectivity/networking/api/mqtt.rst index 8ebaea1268cf..dd57be626068 100644 --- a/doc/connectivity/networking/api/mqtt.rst +++ b/doc/connectivity/networking/api/mqtt.rst @@ -150,6 +150,7 @@ additional configuration information: tls_config->sec_tag_list = m_sec_tags; tls_config->sec_tag_count = ARRAY_SIZE(m_sec_tags); tls_config->hostname = MQTT_BROKER_HOSTNAME; + tls_config->set_native_tls = true; In this sample code, the ``m_sec_tags`` array holds a list of tags, referencing TLS credentials that the MQTT library should use for authentication. We do not specify @@ -162,6 +163,9 @@ Note, that TLS credentials referenced by the ``m_sec_tags`` array must be registered in the system first. For more information on how to do that, refer to :ref:`secure sockets documentation `. +Finally, ``set_native_tls`` can be optionally set to enable native TLS support +instead of offloading TLS operations to an offloaded socket. + An example of how to use TLS with MQTT is also present in :zephyr:code-sample:`mqtt-publisher` sample application. diff --git a/include/zephyr/net/mqtt.h b/include/zephyr/net/mqtt.h index 3f1fca45ed11..a4d961a502ef 100644 --- a/include/zephyr/net/mqtt.h +++ b/include/zephyr/net/mqtt.h @@ -768,6 +768,9 @@ struct mqtt_sec_config { /** Indicates the preference for copying certificates to the heap. */ int cert_nocopy; + + /** Set socket to use native TLS (used with socket offloading). */ + bool set_native_tls; }; /** @brief MQTT transport type. */ diff --git a/subsys/net/lib/mqtt/mqtt_transport_socket_tls.c b/subsys/net/lib/mqtt/mqtt_transport_socket_tls.c index c86dec88e16d..8565d227f858 100644 --- a/subsys/net/lib/mqtt/mqtt_transport_socket_tls.c +++ b/subsys/net/lib/mqtt/mqtt_transport_socket_tls.c @@ -32,6 +32,18 @@ int mqtt_client_tls_connect(struct mqtt_client *client) NET_DBG("Created socket %d", client->transport.tls.sock); + if (IS_ENABLED(CONFIG_NET_SOCKETS_OFFLOAD_DISPATCHER) && tls_config->set_native_tls) { + int tls_native = 1; + + ret = zsock_setsockopt(client->transport.tls.sock, ZSOCK_SOL_TLS, + ZSOCK_TLS_NATIVE, &tls_native, + sizeof(tls_native)); + if (ret < 0) { + NET_ERR("Failed to set native TLS (%d)", -errno); + goto error; + } + } + if (client->transport.if_name != NULL) { struct net_ifreq ifname = { 0 }; From afbdea899577a826d4fa9abd4befe355c8369536 Mon Sep 17 00:00:00 2001 From: Kai Vehmanen Date: Thu, 24 Oct 2024 15:43:55 +0300 Subject: [PATCH 0755/3659] soc: intel_adsp: tools: add Intel NVL support to cavstool.py Add support for intel_adsp/ace40/nvl platforms into cavstool.py. Signed-off-by: Kai Vehmanen --- soc/intel/intel_adsp/tools/cavstool.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/soc/intel/intel_adsp/tools/cavstool.py b/soc/intel/intel_adsp/tools/cavstool.py index 611d77489a33..ca168b372a3f 100755 --- a/soc/intel/intel_adsp/tools/cavstool.py +++ b/soc/intel/intel_adsp/tools/cavstool.py @@ -202,7 +202,7 @@ def reset(self): log.info(f"Reset stream {self.stream_id}") def adsp_is_ace(): - return ace15 or ace20 or ace30 + return ace15 or ace20 or ace30 or ace40 def adsp_mem_window_config(): if adsp_is_ace(): @@ -223,13 +223,14 @@ def map_regs(log_only): pcidir = os.path.dirname(p) # Platform/quirk detection. ID lists cribbed from the SOF kernel driver - global cavs25, ace15, ace20, ace30 + global cavs25, ace15, ace20, ace30, ace40 did = int(open(f"{pcidir}/device").read().rstrip(), 16) cavs25 = did in [ 0x43c8, 0x4b55, 0x4b58, 0x51c8, 0x51ca, 0x51cb, 0x51ce, 0x51cf, 0x54c8, 0x7ad0, 0xa0c8 ] ace15 = did in [ 0x7728, 0x7f50, 0x7e28 ] ace20 = did in [ 0xa828 ] ace30 = did in [ 0xe428 ] + ace40 = did in [ 0x6e50 ] # Check sysfs for a loaded driver and remove it if os.path.exists(f"{pcidir}/driver"): @@ -260,7 +261,7 @@ def map_regs(log_only): hda.SPBFCTL = 0x0704 hda.PPCTL = 0x0804 - if ace20 or ace30: + if ace20 or ace30 or ace40: hda.HDAML_I2S_LCTL = 0x0C40 + 0x40 * 3 + 4 # Find the ID of the first output stream @@ -543,7 +544,7 @@ def load_firmware_ace(fw_file): log.info("Waiting for DSP subsystem power on") time.sleep(0.1) - if ace20 or ace30: + if ace20 or ace30 or ace40: log.info(f"Enabling offload for I2S link") # needed to allow DSP to access SSP DAI hda.HDAML_I2S_LCTL |= mask(OFLEN) From 6efe5cb6875ea119724fc4b60043e233ef6f7e63 Mon Sep 17 00:00:00 2001 From: Kai Vehmanen Date: Thu, 18 Dec 2025 11:25:29 +0200 Subject: [PATCH 0756/3659] soc: intel_adsp: tools: add Intel WCL support to cavstool.py Add PCI DID for Intel Wildcat Lake to cavstool.py. Signed-off-by: Kai Vehmanen --- soc/intel/intel_adsp/tools/cavstool.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/soc/intel/intel_adsp/tools/cavstool.py b/soc/intel/intel_adsp/tools/cavstool.py index ca168b372a3f..ab4341f0abb7 100755 --- a/soc/intel/intel_adsp/tools/cavstool.py +++ b/soc/intel/intel_adsp/tools/cavstool.py @@ -229,7 +229,7 @@ def map_regs(log_only): 0x7ad0, 0xa0c8 ] ace15 = did in [ 0x7728, 0x7f50, 0x7e28 ] ace20 = did in [ 0xa828 ] - ace30 = did in [ 0xe428 ] + ace30 = did in [ 0xe428, 0x4d28 ] ace40 = did in [ 0x6e50 ] # Check sysfs for a loaded driver and remove it From 020d0fe5d82129882835f65741fc7876406686a8 Mon Sep 17 00:00:00 2001 From: Camille BAUD Date: Fri, 19 Dec 2025 00:28:10 +0100 Subject: [PATCH 0757/3659] soc: bflb: Increase default main stack size Set it to something more appropriate Signed-off-by: Camille BAUD --- soc/bflb/Kconfig.defconfig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/soc/bflb/Kconfig.defconfig b/soc/bflb/Kconfig.defconfig index 717d3b4b9680..fd70218c672d 100644 --- a/soc/bflb/Kconfig.defconfig +++ b/soc/bflb/Kconfig.defconfig @@ -7,6 +7,9 @@ if SOC_FAMILY_BFLB config SYS_CLOCK_HW_CYCLES_PER_SEC default $(dt_node_int_prop_int,/cpus,timebase-frequency) +config MAIN_STACK_SIZE + default 4096 + rsource "*/Kconfig.defconfig" endif # SOC_FAMILY_BFLB From af171d4d3bb5b943f472c431403ca88dde6366cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Fri, 19 Dec 2025 21:09:03 +0100 Subject: [PATCH 0758/3659] drivers: uart: fix incorrect handler check in uart_configure syscall MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The z_vrfy_uart_configure function was incorrectly checking for the existence of the 'config_get' handler instead of 'configure'. Signed-off-by: Benjamin Cabé --- drivers/serial/uart_handlers.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/serial/uart_handlers.c b/drivers/serial/uart_handlers.c index 24707bde7547..cfcc1dc77b18 100644 --- a/drivers/serial/uart_handlers.c +++ b/drivers/serial/uart_handlers.c @@ -72,7 +72,7 @@ static inline int z_vrfy_uart_config_get(const struct device *dev, static inline int z_vrfy_uart_configure(const struct device *dev, const struct uart_config *cfg) { - K_OOPS(K_SYSCALL_DRIVER_UART(dev, config_get)); + K_OOPS(K_SYSCALL_DRIVER_UART(dev, configure)); K_OOPS(K_SYSCALL_MEMORY_READ(cfg, sizeof(struct uart_config))); return z_impl_uart_configure(dev, cfg); From 0d448cc2c16a272f78558da0bc80601400adda6d Mon Sep 17 00:00:00 2001 From: UMA PRASEEDA Date: Tue, 16 Dec 2025 11:41:14 +0100 Subject: [PATCH 0759/3659] doc: Add info about supported boards for nRF52840 debug Add info about supported boards for nRF52840 debug in the nRF52840 DK page Signed-off-by: UMA PRASEEDA --- boards/nordic/nrf52840dk/doc/index.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/boards/nordic/nrf52840dk/doc/index.rst b/boards/nordic/nrf52840dk/doc/index.rst index 1c7c30449f9e..c9fc919764e5 100644 --- a/boards/nordic/nrf52840dk/doc/index.rst +++ b/boards/nordic/nrf52840dk/doc/index.rst @@ -71,6 +71,10 @@ built, flashed, and debugged in the usual way. See :ref:`build_an_application` and :ref:`application_run` for more details on building and running. +The nRF52840 DK supports programming and debugging external boards with +nRF51 Series or nRF52 Series System on Chip (SoC)s. For more information, +see the documentation on `nRF52840 DK Debug output`_. + Flashing ======== @@ -190,5 +194,6 @@ References .. _nRF52840 DK website: https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-DK .. _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 +.. _nRF52840 DK Debug output: https://docs.nordicsemi.com/bundle/ug_nrf52840_dk/page/UG/dk/hw_debug_out.html .. _J-Link Software and documentation pack: https://www.segger.com/jlink-software.html .. _nRF52811 website: https://www.nordicsemi.com/Products/Low-power-short-range-wireless/nRF52811 From 1b7810f0cb74bae33f074573c1b7b6f3d3d2cbf3 Mon Sep 17 00:00:00 2001 From: Grzegorz Chwierut Date: Mon, 24 Nov 2025 17:13:25 +0100 Subject: [PATCH 0760/3659] scripts: twister: Support multiple ports in pytest-twister-harness Add support for multiple connections (e.g. UART) from one device, enabling communication with second core UARTs. Feature implemented by extracting connection logic from DeviceAdapter to new DeviceConnection class with specialized implementations: - SerialConnection for hardware UART ports - ProcessConnection for native simulation - FifoConnection for QEMU communication Each connection maintains separate log files (handler.log, handler_1.log, etc.) and can be accessed via connection_index parameter in device methods like readline() and write(). This enables testing multi-core applications where different cores communicate through separate UART interfaces. Signed-off-by: Grzegorz Chwierut --- .ruff-excludes.toml | 23 - .../twister_harness/device/binary_adapter.py | 78 ++- .../twister_harness/device/device_adapter.py | 342 +++++-------- .../device/device_connection.py | 476 ++++++++++++++++++ .../src/twister_harness/device/factory.py | 2 +- .../twister_harness/device/fifo_handler.py | 21 +- .../device/hardware_adapter.py | 183 ++----- .../twister_harness/device/qemu_adapter.py | 67 --- .../src/twister_harness/fixtures.py | 2 +- .../twister_harness/twister_harness_config.py | 25 +- 10 files changed, 707 insertions(+), 512 deletions(-) create mode 100644 scripts/pylib/pytest-twister-harness/src/twister_harness/device/device_connection.py delete mode 100755 scripts/pylib/pytest-twister-harness/src/twister_harness/device/qemu_adapter.py diff --git a/.ruff-excludes.toml b/.ruff-excludes.toml index 57fbe6eb5646..3cd7ccf10941 100644 --- a/.ruff-excludes.toml +++ b/.ruff-excludes.toml @@ -310,32 +310,14 @@ "I001", # https://docs.astral.sh/ruff/rules/unsorted-imports "UP015", # https://docs.astral.sh/ruff/rules/redundant-open-modes ] -"./scripts/pylib/pytest-twister-harness/src/twister_harness/device/binary_adapter.py" = [ - "E501", # https://docs.astral.sh/ruff/rules/line-too-long - "SIM103", # https://docs.astral.sh/ruff/rules/needless-bool -] -"./scripts/pylib/pytest-twister-harness/src/twister_harness/device/device_adapter.py" = [ - "E501", # https://docs.astral.sh/ruff/rules/line-too-long - "I001", # https://docs.astral.sh/ruff/rules/unsorted-imports -] "./scripts/pylib/pytest-twister-harness/src/twister_harness/device/factory.py" = [ "I001", # https://docs.astral.sh/ruff/rules/unsorted-imports "UP006", # https://docs.astral.sh/ruff/rules/non-pep585-annotation "UP035", # https://docs.astral.sh/ruff/rules/deprecated-import ] "./scripts/pylib/pytest-twister-harness/src/twister_harness/device/fifo_handler.py" = [ - "E501", # https://docs.astral.sh/ruff/rules/line-too-long "SIM115", # https://docs.astral.sh/ruff/rules/open-file-with-context-handler ] -"./scripts/pylib/pytest-twister-harness/src/twister_harness/device/hardware_adapter.py" = [ - "E501", # https://docs.astral.sh/ruff/rules/line-too-long - "I001", # https://docs.astral.sh/ruff/rules/unsorted-imports - "UP024", # https://docs.astral.sh/ruff/rules/os-error-alias -] -"./scripts/pylib/pytest-twister-harness/src/twister_harness/device/qemu_adapter.py" = [ - "E501", # https://docs.astral.sh/ruff/rules/line-too-long - "I001", # https://docs.astral.sh/ruff/rules/unsorted-imports -] "./scripts/pylib/pytest-twister-harness/src/twister_harness/fixtures.py" = [ "E501", # https://docs.astral.sh/ruff/rules/line-too-long "I001", # https://docs.astral.sh/ruff/rules/unsorted-imports @@ -956,11 +938,6 @@ exclude = [ "./scripts/net/enumerate_http_status.py", "./scripts/profiling/stackcollapse.py", "./scripts/pylib/build_helpers/domains.py", - "./scripts/pylib/pytest-twister-harness/src/twister_harness/device/binary_adapter.py", - "./scripts/pylib/pytest-twister-harness/src/twister_harness/device/device_adapter.py", - "./scripts/pylib/pytest-twister-harness/src/twister_harness/device/fifo_handler.py", - "./scripts/pylib/pytest-twister-harness/src/twister_harness/device/hardware_adapter.py", - "./scripts/pylib/pytest-twister-harness/src/twister_harness/device/qemu_adapter.py", "./scripts/pylib/pytest-twister-harness/src/twister_harness/fixtures.py", "./scripts/pylib/pytest-twister-harness/src/twister_harness/helpers/mcumgr.py", "./scripts/pylib/pytest-twister-harness/src/twister_harness/plugin.py", diff --git a/scripts/pylib/pytest-twister-harness/src/twister_harness/device/binary_adapter.py b/scripts/pylib/pytest-twister-harness/src/twister_harness/device/binary_adapter.py index a6fe30da9ecc..64ea0e3f7dcf 100755 --- a/scripts/pylib/pytest-twister-harness/src/twister_harness/device/binary_adapter.py +++ b/scripts/pylib/pytest-twister-harness/src/twister_harness/device/binary_adapter.py @@ -35,8 +35,9 @@ def __init__(self, device_config: DeviceConfig) -> None: def generate_command(self) -> None: """Generate and set command which will be used during running device.""" - def _flash_and_run(self) -> None: + def _device_launch(self) -> None: self._run_subprocess() + self.connect() def _run_subprocess(self) -> None: if not self.command: @@ -46,6 +47,9 @@ def _run_subprocess(self) -> None: log_command(logger, 'Running command', self.command, level=logging.DEBUG) try: self._process = subprocess.Popen(self.command, **self.process_kwargs) + # Update all ProcessConnection instances with the new process + for conn in self.connections: + conn.update(process=self._process) except subprocess.SubprocessError as exc: msg = f'Running subprocess failed due to SubprocessError {exc}' logger.error(msg) @@ -59,22 +63,6 @@ def _run_subprocess(self) -> None: logger.error(msg) raise TwisterHarnessException(msg) from exc - def _connect_device(self) -> None: - """ - This method was implemented only to imitate standard connect behavior - like in Serial class. - """ - - def _disconnect_device(self) -> None: - """ - This method was implemented only to imitate standard disconnect behavior - like in serial connection. - """ - - def _close_device(self) -> None: - """Terminate subprocess""" - self._stop_subprocess() - def _stop_subprocess(self) -> None: if self._process is None: # subprocess already stopped @@ -84,30 +72,14 @@ def _stop_subprocess(self) -> None: terminate_process(self._process, self.base_timeout) return_code = self._process.wait(self.base_timeout) self._process = None + for conn in self.connections: + if hasattr(conn, '_process'): + conn._process = None logger.debug('Running subprocess finished with return code %s', return_code) - def _read_device_output(self) -> bytes: - return self._process.stdout.readline() - - def _write_to_device(self, data: bytes) -> None: - self._process.stdin.write(data) - self._process.stdin.flush() - - def _flush_device_output(self) -> None: - if self.is_device_running(): - self._process.stdout.flush() - - def is_device_running(self) -> bool: - return self._device_run.is_set() and self._is_binary_running() - - def _is_binary_running(self) -> bool: - if self._process is None or self._process.poll() is not None: - return False - return True - - def is_device_connected(self) -> bool: - """Return true if device is connected.""" - return self.is_device_running() and self._device_connected.is_set() + def _close_device(self) -> None: + """Terminate subprocess""" + self._stop_subprocess() def _clear_internal_resources(self) -> None: super()._clear_internal_resources() @@ -131,6 +103,32 @@ def generate_command(self) -> None: class CustomSimulatorAdapter(BinaryAdapterBase): + """Simulator adapter to run custom simulator""" + + def generate_command(self) -> None: + """Set command to run.""" + self.command = [ + self.west, + 'build', + '-d', + str(self.device_config.app_build_dir), + '-t', + 'run', + ] + + +class QemuAdapter(BinaryAdapterBase): + """Simulator adapter to run QEMU""" + def generate_command(self) -> None: """Set command to run.""" - self.command = [self.west, 'build', '-d', str(self.device_config.app_build_dir), '-t', 'run'] + self.command = [ + self.west, + 'build', + '-d', + str(self.device_config.app_build_dir), + '-t', + 'run', + ] + if 'stdin' in self.process_kwargs: + self.process_kwargs.pop('stdin') diff --git a/scripts/pylib/pytest-twister-harness/src/twister_harness/device/device_adapter.py b/scripts/pylib/pytest-twister-harness/src/twister_harness/device/device_adapter.py index 6544d33da2f5..5680760f84ca 100644 --- a/scripts/pylib/pytest-twister-harness/src/twister_harness/device/device_adapter.py +++ b/scripts/pylib/pytest-twister-harness/src/twister_harness/device/device_adapter.py @@ -7,19 +7,13 @@ import abc import logging import os -import queue -import re import shutil import threading -import time from datetime import datetime from pathlib import Path -from serial import SerialException -from twister_harness.exceptions import ( - TwisterHarnessException, - TwisterHarnessTimeoutException, -) +from twister_harness.device.device_connection import DeviceConnection, create_device_connections +from twister_harness.exceptions import TwisterHarnessException from twister_harness.twister_harness_config import DeviceConfig logger = logging.getLogger(__name__) @@ -32,24 +26,16 @@ class DeviceAdapter(abc.ABC): it. """ + _west: str | None = None + def __init__(self, device_config: DeviceConfig) -> None: - """ - :param device_config: device configuration - """ self.device_config: DeviceConfig = device_config self.base_timeout: float = device_config.base_timeout - self._device_read_queue: queue.Queue = queue.Queue() - self._reader_thread: threading.Thread | None = None - self._device_run: threading.Event = threading.Event() - self._device_connected: threading.Event = threading.Event() + self._reader_started: threading.Event = threading.Event() self.command: list[str] = [] - self._west: str | None = None - - self.handler_log_path: Path = device_config.build_dir / 'handler.log' - self._log_files: list[Path] = [self.handler_log_path] - def __repr__(self) -> str: - return f'{self.__class__.__name__}()' + self.connections: list[DeviceConnection] = create_device_connections(device_config) + self._log_files: list[Path] = [conn.log_path for conn in self.connections] @property def env(self) -> dict[str, str]: @@ -57,171 +43,117 @@ def env(self) -> dict[str, str]: return env def launch(self) -> None: - """ - Start by closing previously running application (no effect if not - needed). Then, flash and run test application. Finally, start an - internal reader thread capturing an output from a device. + """Launch the test application on the target device. + + This method performs the complete device initialization sequence: + + - Close any previously running application (cleanup) + - Generate the execution command if not already set + - Add any extra test arguments to the command + - Start reader threads to capture device output + - Launch the application (flash for hardware, execute for simulators) + + The launch process varies by device type: + + - Hardware devices: Flash the application and establish serial communication. + May connect before or after flashing depending on device configuration. + - QEMU/simulators: Start subprocess and establish FIFO/pipe communication + - Native simulators: Execute binary and connect via process pipes """ self.close() - self._clear_internal_resources() if not self.command: self.generate_command() if self.device_config.extra_test_args: self.command.extend(self.device_config.extra_test_args.split()) - if self.device_config.type != 'hardware': - self._flash_and_run() - self._device_run.set() - self._start_reader_thread() - self.connect() - return - - self._device_run.set() - self._start_reader_thread() - - if self.device_config.flash_before: - # For hardware devices with shared USB or software USB, connect after flashing. - # Retry for up to 10 seconds for USB-CDC based devices to enumerate. - self._flash_and_run() - self.connect(retry_s = 10) - else: - # On hardware, flash after connecting to COM port, otherwise some messages - # from target can be lost. - self.connect() - self._flash_and_run() + self.start_reader() + self._device_launch() def close(self) -> None: - """Disconnect, close device and close reader thread.""" - if not self._device_run.is_set(): - # device already closed - return + """Disconnect, close device and close reader threads.""" self.disconnect() self._close_device() - self._device_run.clear() - self._join_reader_thread() + self.stop_reader() + self._clear_internal_resources() def connect(self, retry_s: int = 0) -> None: """Connect to device - allow for output gathering.""" - if self.is_device_connected(): - logger.debug('Device already connected') - return - if not self.is_device_running(): - msg = 'Cannot connect to not working device' - logger.error(msg) - raise TwisterHarnessException(msg) - - if retry_s > 0: - retry_cycles = retry_s * 10 - for i in range(retry_cycles): - try: - self._connect_device() - break - except SerialException: - if i == retry_cycles - 1: - raise - time.sleep(0.1) - else: - self._connect_device() - - self._device_connected.set() + for connection in self.connections: + connection.connect() def disconnect(self) -> None: """Disconnect device - block output gathering.""" - if not self.is_device_connected(): - logger.debug("Device already disconnected") - return - self._disconnect_device() - self._device_connected.clear() + for connection in self.connections: + connection.disconnect() - def readline(self, timeout: float | None = None, print_output: bool = True) -> str: - """ - Read line from device output. If timeout is not provided, then use - base_timeout. - """ - timeout = timeout or self.base_timeout - if self.is_device_connected() or not self._device_read_queue.empty(): - data = self._read_from_queue(timeout) - else: - msg = 'No connection to the device and no more data to read.' + def check_connection(self, connection_index: int = 0) -> None: + """Validate that the specified connection index exists.""" + if connection_index >= len(self.connections): + msg = f'Connection index {connection_index} is out of range.' logger.error(msg) - raise TwisterHarnessException('No connection to the device and no more data to read.') - if print_output: - logger.debug('#: %s', data) - return data - - def readlines_until( - self, - regex: str | None = None, - num_of_lines: int | None = None, - timeout: float | None = None, - print_output: bool = True, - ) -> list[str]: - """ - Read available output lines produced by device from internal buffer - until following conditions: + raise TwisterHarnessException(msg) - 1. If regex is provided - read until regex regex is found in read - line (or until timeout). - 2. If num_of_lines is provided - read until number of read lines is - equal to num_of_lines (or until timeout). - 3. If none of above is provided - return immediately lines collected so - far in internal buffer. + def readline(self, connection_index: int = 0, **kwargs) -> str: + """Read a single line from device output. - If timeout is not provided, then use base_timeout. + :param connection_index: Connection port to read from (0=main UART, 1=second core, etc.) + :param kwargs: Additional keyword arguments (timeout, print_output) + :returns: Single line of text without trailing newlines """ - __tracebackhide__ = True # pylint: disable=unused-variable - timeout = timeout or self.base_timeout - if regex: - regex_compiled = re.compile(regex) - lines: list[str] = [] - if regex or num_of_lines: - timeout_time: float = time.time() + timeout - while time.time() < timeout_time: - try: - line = self.readline(0.1, print_output) - except TwisterHarnessTimeoutException: - continue - lines.append(line) - if regex and regex_compiled.search(line): - break - if num_of_lines and len(lines) == num_of_lines: - break - else: - if regex is not None: - msg = f'Did not find line "{regex}" within {timeout} seconds' - else: - msg = f'Did not find expected number of lines within {timeout} seconds' - logger.error(msg) - raise AssertionError(msg) - else: - lines = self.readlines(print_output) - return lines + self.check_connection(connection_index) + if kwargs.get('timeout') is None: + kwargs['timeout'] = self.base_timeout + return self.connections[connection_index].readline(**kwargs) - def readlines(self, print_output: bool = True) -> list[str]: - """ - Read all available output lines produced by device from internal buffer. + def readlines(self, connection_index: int = 0, **kwargs) -> list[str]: + """Read all available output lines produced by device from internal buffer.""" + self.check_connection(connection_index) + return self.connections[connection_index].readlines(**kwargs) + + def readlines_until(self, connection_index: int = 0, **kwargs) -> list[str]: + """Read lines from device output until a specific condition is met. + + This method provides flexible ways to collect device output: wait for a specific + pattern, collect a fixed number of lines, or get all currently available lines. + + :param connection_index: Index of the connection/port to read from (default: 0). + For hardware devices: 0 = main UART, 1 = second core UART, etc. + For QEMU and native: always use 0 (only one connection available) + :param kwargs: Keyword arguments passed to underlying connection including: + + - regex - Regular expression pattern to search for + - num_of_lines - Exact number of lines to read + - timeout - Maximum time in seconds to wait (uses base_timeout if not provided) + - print_output - Whether to log each line as it's read (default: True) + :returns: List of output lines without trailing newlines + :raises AssertionError: If timeout expires before condition is met """ - lines: list[str] = [] - while not self._device_read_queue.empty(): - line = self.readline(0.1, print_output) - lines.append(line) - return lines + self.check_connection(connection_index) + return self.connections[connection_index].readlines_until(**kwargs) def clear_buffer(self) -> None: - """ - Remove all available output produced by device from internal buffer - (queue). - """ - self.readlines(print_output=False) + """Remove all available output produced by device from internal buffer.""" + for connection in self.connections: + connection.clear_buffer() - def write(self, data: bytes) -> None: - """Write data bytes to device.""" - if not self.is_device_connected(): - msg = 'No connection to the device' + def write(self, data: bytes, connection_index: int = 0) -> None: + """Write data bytes to the target device. + + Sends raw bytes to the device through the appropriate communication channel. + The underlying transport mechanism varies by device type: Hardware devices + write to serial/UART port, QEMU devices write to FIFO queue, and Native + simulators write to process stdin pipes. + + :param data: Raw bytes to send to the device + :param connection_index: Index of the connection/port to write to (default: 0) + """ + self.check_connection(connection_index) + if not self.connections[connection_index].is_device_connected(): + msg = f'Cannot write to not connected device on connection index {connection_index}.' logger.error(msg) raise TwisterHarnessException(msg) - self._write_to_device(data) + self.connections[connection_index]._write_to_device(data) def initialize_log_files(self, test_name: str = '') -> None: """ @@ -232,46 +164,27 @@ def initialize_log_files(self, test_name: str = '') -> None: with open(log_file_path, 'a+') as log_file: log_file.write(f'\n==== Test {test_name} started at {datetime.now()} ====\n') - def _start_reader_thread(self) -> None: - self._reader_thread = threading.Thread(target=self._handle_device_output, daemon=True) - self._reader_thread.start() - - def _handle_device_output(self) -> None: - """ - This method is dedicated to run it in separate thread to read output - from device and put them into internal queue and save to log file. - """ - with open(self.handler_log_path, 'a+') as log_file: - while self.is_device_running(): - if self.is_device_connected(): - output = self._read_device_output().decode(errors='replace').rstrip("\r\n") - if output: - self._device_read_queue.put(output) - log_file.write(f'{output}\n') - log_file.flush() - else: - # ignore output from device - self._flush_device_output() - time.sleep(0.1) - - def _read_from_queue(self, timeout: float) -> str: - """Read data from internal queue""" - try: - data: str | object = self._device_read_queue.get(timeout=timeout) - except queue.Empty as exc: - raise TwisterHarnessTimeoutException(f'Read from device timeout occurred ({timeout}s)') from exc - return data - - def _join_reader_thread(self) -> None: - if self._reader_thread is not None: - self._reader_thread.join(self.base_timeout) - self._reader_thread = None + def start_reader(self) -> None: + """Start internal reader threads for all connections.""" + if self._reader_started.is_set(): + # reader already started + return + self._reader_started.set() + for connection in self.connections: + connection.start_reader_thread(self._reader_started) + + def stop_reader(self) -> None: + """Stop internal reader threads for all connections.""" + if not self._reader_started.is_set(): + # reader already stopped + return + self._reader_started.clear() + for connection in self.connections: + connection.join_reader_thread(self.base_timeout) def _clear_internal_resources(self) -> None: - self._reader_thread = None - self._device_read_queue = queue.Queue() - self._device_run.clear() - self._device_connected.clear() + for connection in self.connections: + connection._clear_internal_resources() @property def west(self) -> str: @@ -296,42 +209,17 @@ def generate_command(self) -> None: """ @abc.abstractmethod - def _flash_and_run(self) -> None: - """Flash and run application on a device.""" - - @abc.abstractmethod - def _connect_device(self) -> None: - """Connect with the device (e.g. via serial port).""" - - @abc.abstractmethod - def _disconnect_device(self) -> None: - """Disconnect from the device (e.g. from serial port).""" + def _device_launch(self) -> None: + """Launch the application on the target device.""" @abc.abstractmethod def _close_device(self) -> None: - """Stop application""" + """Stop application on the target device.""" - @abc.abstractmethod - def _read_device_output(self) -> bytes: - """ - Read device output directly through serial, subprocess, FIFO, etc. - Even if device is not connected, this method has to return something - (e.g. empty bytes string). This assumption is made to maintain - compatibility between various adapters and their reading technique. + def is_device_connected(self) -> bool: """ + Check if the primary device connection is active. - @abc.abstractmethod - def _write_to_device(self, data: bytes) -> None: - """Write to device directly through serial, subprocess, FIFO, etc.""" - - @abc.abstractmethod - def _flush_device_output(self) -> None: - """Flush device connection (serial, subprocess output, FIFO, etc.)""" - - @abc.abstractmethod - def is_device_running(self) -> bool: - """Return true if application is running on device.""" - - @abc.abstractmethod - def is_device_connected(self) -> bool: - """Return true if device is connected.""" + Added to keep backward compatibility as it is used in fixtures. + """ + return self.connections and self.connections[0].is_device_connected() diff --git a/scripts/pylib/pytest-twister-harness/src/twister_harness/device/device_connection.py b/scripts/pylib/pytest-twister-harness/src/twister_harness/device/device_connection.py new file mode 100644 index 000000000000..1b5d56e26e7c --- /dev/null +++ b/scripts/pylib/pytest-twister-harness/src/twister_harness/device/device_connection.py @@ -0,0 +1,476 @@ +# Copyright (c) 2025 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 + +import abc +import logging +import os +import re + +if os.name != 'nt': + import pty +import queue +import subprocess +import threading +import time +from pathlib import Path + +import serial + +from twister_harness.device.fifo_handler import FifoHandler +from twister_harness.exceptions import TwisterHarnessException, TwisterHarnessTimeoutException +from twister_harness.twister_harness_config import DeviceConfig, DeviceSerialConfig + +logger = logging.getLogger(__name__) + + +class DeviceConnection(abc.ABC): + """ + Interface for device communication transport layer. + Handles the actual connection mechanism (Serial/UART, FIFO, process, etc.) + """ + + def __init__(self, log_path: Path, timeout: float) -> None: + """Initialize the device connection""" + self.log_path = log_path + self.timeout = timeout + self._device_read_queue: queue.Queue = queue.Queue() + self._reader_thread: threading.Thread | None = None + # Prefix for log messages to differentiate between multiple connections + self.log_prefix: str = '' + + def start_reader_thread(self, reader_started: threading.Event) -> None: + """Start the internal reader thread for the device connection.""" + if self._reader_thread is None or not self._reader_thread.is_alive(): + self._reader_thread = threading.Thread( + target=self._handle_device_output, args=(reader_started,), daemon=True + ) + self._reader_thread.start() + + def join_reader_thread(self, timeout: float) -> None: + """Join the internal reader thread for the device connection.""" + if self._reader_thread is not None: + self._reader_thread.join(timeout) + if self._reader_thread.is_alive(): + logger.warning("Reader thread did not terminate within timeout") + self._reader_thread = None + + def update(self, **kwargs) -> None: # noqa: B027 + """Update connection parameters based on provided keyword arguments.""" + + def _clear_internal_resources(self) -> None: + self._reader_thread = None + self._device_read_queue = queue.Queue() + + def _handle_device_output(self, reader_started: threading.Event) -> None: + """ + This method is dedicated to run it in separate thread to read output + from device and put them into internal queue and save to log file. + """ + with open(self.log_path, 'a+', encoding='utf-8', errors='replace') as log_file: + while reader_started.is_set(): + if self.is_device_connected(): + output = self._read_device_output().decode(errors='replace').rstrip("\r\n") + if output: + self._device_read_queue.put(output) + log_file.write(f'{output}\n') + log_file.flush() + else: + # ignore output from device + self._flush_device_output() + time.sleep(0.1) + + def _read_from_queue(self, timeout: float) -> str: + """Read data from internal queue""" + try: + data: str | object = self._device_read_queue.get(timeout=timeout) + except queue.Empty as exc: + raise TwisterHarnessTimeoutException( + f'Read from device timeout occurred ({timeout}s)' + ) from exc + return data + + def readline(self, timeout: float | None = None, print_output: bool = True) -> str: + """ + Read line from device output. If timeout is not provided, then use + base_timeout. + """ + timeout = timeout or self.timeout + if self.is_device_connected() or not self._device_read_queue.empty(): + data = self._read_from_queue(timeout) + else: + msg = 'No connection to the device and no more data to read.' + logger.error(msg) + raise TwisterHarnessException('No connection to the device and no more data to read.') + if print_output: + logger.debug('%s#: %s', self.log_prefix, data) + return data + + def readlines_until( + self, + regex: str | None = None, + num_of_lines: int | None = None, + timeout: float | None = None, + print_output: bool = True, + ) -> list[str]: + """ + Read lines from device output until a specific condition is met. + + This method provides flexible ways to collect device output from your test device: + - Wait for a specific pattern/message to appear in the output + - Collect a fixed number of lines + - Get all currently available lines immediately + """ + __tracebackhide__ = True # pylint: disable=unused-variable + timeout = timeout or self.timeout + if regex: + regex_compiled = re.compile(regex) + lines: list[str] = [] + if regex or num_of_lines: + timeout_time: float = time.time() + timeout + while time.time() < timeout_time: + try: + line = self.readline(0.1, print_output) + except TwisterHarnessTimeoutException: + continue + lines.append(line) + if regex and regex_compiled.search(line): + break + if num_of_lines and len(lines) == num_of_lines: + break + else: + if regex is not None: + msg = f'Did not find line "{regex}" within {timeout} seconds' + else: + msg = f'Did not find expected number of lines within {timeout} seconds' + logger.error(msg) + raise AssertionError(msg) + else: + lines = self.readlines(print_output) + return lines + + def readlines(self, print_output: bool = True) -> list[str]: + """ + Read all available output lines produced by device from internal buffer. + """ + lines: list[str] = [] + while not self._device_read_queue.empty(): + line = self.readline(0.1, print_output) + lines.append(line) + return lines + + def clear_buffer(self) -> None: + """ + Remove all available output produced by device from internal buffer. + """ + self.readlines(print_output=False) + + def connect(self) -> None: + """Connect to device - allow for output gathering.""" + if self.is_device_connected(): + # Device already connected + return + self._connect_device() + + def disconnect(self) -> None: + """Disconnect device - block output gathering.""" + if not self.is_device_connected(): + # Device already disconnected + return + self._disconnect_device() + + @abc.abstractmethod + def _connect_device(self) -> None: + """Connect with the device (e.g. via serial port).""" + + @abc.abstractmethod + def _disconnect_device(self) -> None: + """Disconnect from the device (e.g. from serial port).""" + + @abc.abstractmethod + def _read_device_output(self) -> bytes: + """ + Read device output directly through serial, subprocess, FIFO, etc. + Even if device is not connected, this method has to return something + (e.g. empty bytes string). This assumption is made to maintain + compatibility between various adapters and their reading technique. + """ + + @abc.abstractmethod + def is_device_connected(self) -> bool: + """Return true if device is connected.""" + + @abc.abstractmethod + def _write_to_device(self, data: bytes) -> None: + """Write to device directly through serial, subprocess, FIFO, etc.""" + + @abc.abstractmethod + def _flush_device_output(self) -> None: + """Flush device connection (serial, subprocess output, FIFO, etc.)""" + + +class SerialConnection(DeviceConnection): + """Serial/UART connection implementation for hardware devices""" + + def __init__(self, log_path: Path, timeout: float, serial_config: DeviceSerialConfig) -> None: + """ + Initialize serial connection. + """ + super().__init__(log_path, timeout) + self.serial_config: DeviceSerialConfig = serial_config + self._serial_connection: serial.Serial | None = None + self._serial_pty_proc: subprocess.Popen | None = None + self._serial_buffer: bytearray = bytearray() + + def _connect_device(self) -> None: + if self.is_device_connected(): + # Device already connected + return + serial_name = self._open_serial_pty() or self.serial_config.port + logger.debug('Opening serial connection for %s', serial_name) + try: + self._serial_connection = serial.Serial( + serial_name, + baudrate=self.serial_config.baud, + parity=serial.PARITY_NONE, + stopbits=serial.STOPBITS_ONE, + bytesize=serial.EIGHTBITS, + timeout=self.timeout, + ) + except serial.SerialException as exc: + logger.exception('Cannot open connection: %s', exc) + self._close_serial_pty() + raise + + self._serial_connection.flush() + self._serial_connection.reset_input_buffer() + self._serial_connection.reset_output_buffer() + + def is_device_connected(self) -> bool: + return self._serial_connection and self._serial_connection.is_open + + def _open_serial_pty(self) -> str | None: + """Open a pty pair, run process and return tty name""" + if not self.serial_config.serial_pty: + return None + + try: + master, slave = pty.openpty() + except NameError as exc: + logger.exception('PTY module is not available.') + raise exc + + try: + self._serial_pty_proc = subprocess.Popen( + re.split('[, ]', self.serial_config.serial_pty), + stdout=master, + stdin=master, + stderr=master, + ) + except subprocess.CalledProcessError as exc: + logger.exception('Failed to run subprocess, error %s', str(exc)) + raise + return os.ttyname(slave) + + def _disconnect_device(self) -> None: + if self._serial_connection: + serial_name = self._serial_connection.port + self._serial_connection.close() + self._serial_connection = None + logger.debug('Closed serial connection for %s', serial_name) + self._close_serial_pty() + + def _close_serial_pty(self) -> None: + """Terminate the process opened for serial pty script""" + if self._serial_pty_proc: + self._serial_pty_proc.terminate() + self._serial_pty_proc.communicate(timeout=self.timeout) + logger.debug('Process %s terminated', self.serial_config.serial_pty) + self._serial_pty_proc = None + + def _read_device_output(self) -> bytes: + try: + output = self._readline_serial() + except (OSError, TypeError): + # serial was probably disconnected + output = b'' + return output + + def _readline_serial(self) -> bytes: + """ + This method was created to avoid using PySerial built-in readline + method which cause blocking reader thread even if there is no data to + read. Instead for this, following implementation try to read data only + if they are available. Inspiration for this code was taken from this + comment: + https://github.com/pyserial/pyserial/issues/216#issuecomment-369414522 + """ + line = self._readline_from_serial_buffer() + if line is not None: + return line + while True: + if self._serial_connection is None or not self._serial_connection.is_open: + return b'' + elif self._serial_connection.in_waiting == 0: + time.sleep(0.05) + else: + bytes_to_read = max(1, min(2048, self._serial_connection.in_waiting)) + output = self._serial_connection.read(bytes_to_read) + self._serial_buffer.extend(output) + line = self._readline_from_serial_buffer() + if line is not None: + return line + + def _readline_from_serial_buffer(self) -> bytes | None: + idx = self._serial_buffer.find(b"\n") + if idx >= 0: + line = self._serial_buffer[: idx + 1] + self._serial_buffer = self._serial_buffer[idx + 1 :] + return bytes(line) + else: + return None + + def _write_to_device(self, data: bytes) -> None: + self._serial_connection.write(data) + + def _flush_device_output(self) -> None: + if self.is_device_connected(): + self._serial_connection.flush() + self._serial_connection.reset_input_buffer() + + def _clear_internal_resources(self) -> None: + super()._clear_internal_resources() + self._serial_connection = None + self._serial_pty_proc = None + self._serial_buffer.clear() + + +class ProcessConnection(DeviceConnection): + """Process pipe connection implementation for native simulation""" + + def __init__(self, log_path: Path, timeout: float) -> None: + """ + Initialize serial connection. + """ + super().__init__(log_path, timeout) + self._process: subprocess.Popen | None = None + + def update(self, **kwargs) -> None: + """ + The process instance is set after connection initialization and must be + provided by the binary adapter via this method. + """ + if 'process' in kwargs: + self._process = kwargs['process'] + + def _read_device_output(self) -> bytes: + return self._process.stdout.readline() + + def _connect_device(self) -> None: + """Connect with the device. Left empty for native simulation.""" + + def _disconnect_device(self) -> None: + """Disconnect from the device. Left empty for native simulation.""" + + def is_device_connected(self) -> bool: + return self._is_binary_running() + + def _is_binary_running(self) -> bool: + return self._process is not None and self._process.poll() is None + + def _write_to_device(self, data: bytes) -> None: + if self.is_device_connected(): + self._process.stdin.write(data) + self._process.stdin.flush() + + def _flush_device_output(self) -> None: + if self.is_device_connected(): + self._process.stdout.flush() + + +class FifoConnection(ProcessConnection): + """FIFO queue connection implementation for QEMU""" + + def __init__(self, log_path: Path, timeout: float, fifo_file: Path) -> None: + """ + Initialize serial connection. + """ + super().__init__(log_path, timeout) + self._fifo_connection: FifoHandler = FifoHandler(fifo_file, timeout) + + def _connect_device(self) -> None: + """Create fifo connection""" + if self.is_device_connected(): + # Device already connected + return + if not self._is_binary_running(): + msg = 'Cannot connect to not working device.' + logger.error(msg) + raise TwisterHarnessException(msg) + self._fifo_connection.initiate_connection() + timeout_time: float = time.time() + self.timeout + while time.time() < timeout_time and self._is_binary_running(): + if self._fifo_connection.is_open: + # to flush after reconnection + self._write_to_device(b'\n') + return + time.sleep(0.1) + msg = 'Cannot establish communication with QEMU device.' + logger.error(msg) + raise TwisterHarnessException(msg) + + def _disconnect_device(self) -> None: + """Disconnect fifo connection""" + if self._fifo_connection.is_open: + self._fifo_connection.disconnect() + + def _read_device_output(self) -> bytes: + try: + output = self._fifo_connection.readline() + except (OSError, ValueError): + # emulation was probably finished and thus fifo file was closed too + output = b'' + return output + + def is_device_connected(self) -> bool: + return super().is_device_connected() and self._fifo_connection.is_open + + def _write_to_device(self, data: bytes) -> None: + if self.is_device_connected(): + self._fifo_connection.write(data) + self._fifo_connection.flush_write() + + def _flush_device_output(self) -> None: + if self.is_device_connected(): + self._fifo_connection.flush_read() + + def _clear_internal_resources(self) -> None: + super()._clear_internal_resources() + self._fifo_connection.cleanup() + + +def create_device_connections(device_config: DeviceConfig) -> list[DeviceConnection]: + """Factory method to create device connections based on device configuration.""" + connections: list[DeviceConnection] = [] + + log_path: Path = device_config.build_dir / 'handler.log' + timeout = device_config.base_timeout + + if device_config.type == "hardware": + for core, serial_config in enumerate(device_config.serial_configs): + if core > 0: + log_path = device_config.build_dir / f'handler_{core}.log' + connection = SerialConnection(log_path, timeout, serial_config) + connections.append(connection) + elif device_config.type == "qemu": + fifo_file = device_config.build_dir / 'qemu-fifo' + connection = FifoConnection(log_path, timeout, fifo_file) + connections.append(connection) + else: # native + connection = ProcessConnection(log_path, timeout) + connections.append(connection) + + # Update log prefixes only for extra connections (not for the first one) + for index, _ in enumerate(connections[1:], start=1): + connections[index].log_prefix = f"[{index}]" + return connections diff --git a/scripts/pylib/pytest-twister-harness/src/twister_harness/device/factory.py b/scripts/pylib/pytest-twister-harness/src/twister_harness/device/factory.py index 3d76f89de641..d1eca520e65f 100644 --- a/scripts/pylib/pytest-twister-harness/src/twister_harness/device/factory.py +++ b/scripts/pylib/pytest-twister-harness/src/twister_harness/device/factory.py @@ -9,11 +9,11 @@ from twister_harness.device.device_adapter import DeviceAdapter from twister_harness.device.hardware_adapter import HardwareAdapter -from twister_harness.device.qemu_adapter import QemuAdapter from twister_harness.device.binary_adapter import ( CustomSimulatorAdapter, NativeSimulatorAdapter, UnitSimulatorAdapter, + QemuAdapter, ) from twister_harness.exceptions import TwisterHarnessException diff --git a/scripts/pylib/pytest-twister-harness/src/twister_harness/device/fifo_handler.py b/scripts/pylib/pytest-twister-harness/src/twister_harness/device/fifo_handler.py index 2398cd8728e3..48265a454b2f 100755 --- a/scripts/pylib/pytest-twister-harness/src/twister_harness/device/fifo_handler.py +++ b/scripts/pylib/pytest-twister-harness/src/twister_harness/device/fifo_handler.py @@ -44,13 +44,17 @@ def initiate_connection(self) -> None: thread when timeout will expire. """ self._stop_waiting_for_opening.clear() + self._fifo_opened.clear() self._make_fifo_file(self._fifo_out_path) self._make_fifo_file(self._fifo_in_path) - if self._open_fifo_thread is None: + # Only create new threads if they don't exist or are not alive + if self._open_fifo_thread is None or not self._open_fifo_thread.is_alive(): self._open_fifo_thread = threading.Thread(target=self._open_fifo, daemon=True) self._open_fifo_thread.start() - if self._opening_monitor_thread is None: - self._opening_monitor_thread = threading.Thread(target=self._opening_monitor, daemon=True) + if self._opening_monitor_thread is None or not self._opening_monitor_thread.is_alive(): + self._opening_monitor_thread = threading.Thread( + target=self._opening_monitor, daemon=True + ) self._opening_monitor_thread.start() @staticmethod @@ -90,6 +94,7 @@ def _unblock_open_fifo_operation(self) -> None: def disconnect(self) -> None: self._stop_waiting_for_opening.set() + if self._open_fifo_thread and self._open_fifo_thread.is_alive(): self._open_fifo_thread.join(timeout=1) self._open_fifo_thread = None @@ -100,9 +105,13 @@ def disconnect(self) -> None: if self._fifo_out_file: self._fifo_out_file.close() + self._fifo_out_file = None if self._fifo_in_file: self._fifo_in_file.close() + self._fifo_in_file = None + def cleanup(self): + """Clean up FIFO files when object is destroyed""" if os.path.exists(self._fifo_out_path): os.unlink(self._fifo_out_path) if os.path.exists(self._fifo_in_path): @@ -113,8 +122,10 @@ def is_open(self) -> bool: try: return bool( self._fifo_opened.is_set() - and self._fifo_in_file is not None and self._fifo_out_file is not None - and self._fifo_in_file.fileno() and self._fifo_out_file.fileno() + and self._fifo_in_file is not None + and self._fifo_out_file is not None + and self._fifo_in_file.fileno() + and self._fifo_out_file.fileno() ) except ValueError: return False diff --git a/scripts/pylib/pytest-twister-harness/src/twister_harness/device/hardware_adapter.py b/scripts/pylib/pytest-twister-harness/src/twister_harness/device/hardware_adapter.py index 93f55101233e..2de075d2d98b 100644 --- a/scripts/pylib/pytest-twister-harness/src/twister_harness/device/hardware_adapter.py +++ b/scripts/pylib/pytest-twister-harness/src/twister_harness/device/hardware_adapter.py @@ -5,21 +5,18 @@ from __future__ import annotations import logging -import os -if os.name != 'nt': - import pty -import re import subprocess import time from pathlib import Path -import serial +from serial import SerialException + from twister_harness.device.device_adapter import DeviceAdapter +from twister_harness.device.utils import log_command, terminate_process from twister_harness.exceptions import ( TwisterHarnessException, TwisterHarnessTimeoutException, ) -from twister_harness.device.utils import log_command, terminate_process from twister_harness.twister_harness_config import DeviceConfig logger = logging.getLogger(__name__) @@ -31,9 +28,6 @@ class HardwareAdapter(DeviceAdapter): def __init__(self, device_config: DeviceConfig) -> None: super().__init__(device_config) self._flashing_timeout: float = device_config.flash_timeout - self._serial_connection: serial.Serial | None = None - self._serial_pty_proc: subprocess.Popen | None = None - self._serial_buffer: bytearray = bytearray() self.device_log_path: Path = device_config.build_dir / 'device.log' self._log_files.append(self.device_log_path) @@ -59,7 +53,8 @@ def generate_command(self) -> None: self.west, 'flash', '--no-rebuild', - '--build-dir', str(self.device_config.build_dir), + '--build-dir', + str(self.device_config.build_dir), ] command_extra_args = [] @@ -94,7 +89,10 @@ def _prepare_runner_args(self) -> tuple[list[str], list[str]]: elif runner in ('nrfjprog', 'nrfutil', 'nrfutil_next'): extra_args.append('--dev-id') extra_args.append(board_id) - elif runner == 'openocd' and self.device_config.product in ['STM32 STLink', 'STLINK-V3']: + elif runner == 'openocd' and self.device_config.product in [ + 'STM32 STLink', + 'STLINK-V3', + ]: extra_args.append('--cmd-pre-init') extra_args.append(f'hla_serial {board_id}') elif runner == 'openocd' and self.device_config.product == 'EDBG CMSIS-DAP': @@ -103,13 +101,38 @@ def _prepare_runner_args(self) -> tuple[list[str], list[str]]: elif runner == "openocd" and self.device_config.product == "LPC-LINK2 CMSIS-DAP": extra_args.append("--cmd-pre-init") extra_args.append(f'adapter serial {board_id}') - elif runner == 'jlink' or (runner == 'stm32cubeprogrammer' and self.device_config.product != "BOOT-SERIAL"): + elif runner == 'jlink' or ( + runner == 'stm32cubeprogrammer' and self.device_config.product != "BOOT-SERIAL" + ): base_args.append('--dev-id') base_args.append(board_id) elif runner == 'linkserver': base_args.append(f'--probe={board_id}') return base_args, extra_args + def _device_launch(self) -> None: + """Flash and run application on a device and connect with serial port.""" + if self.device_config.flash_before: + # For hardware devices with shared USB or software USB, connect after flashing. + # Retry for up to 10 seconds for USB-CDC based devices to enumerate. + self._flash_and_run() + attempt = 0 + while True: + try: + self.connect() + break + except SerialException: + if attempt < 100: + attempt += 1 + time.sleep(0.1) + else: + raise + else: + # On hardware, flash after connecting to COM port, otherwise some messages + # from target can be lost. + self.connect() + self._flash_and_run() + def _flash_and_run(self) -> None: """Flash application on a device.""" if not self.command: @@ -126,7 +149,9 @@ def _flash_and_run(self) -> None: process = stdout = None try: - process = subprocess.Popen(self.command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, env=self.env) + process = subprocess.Popen( + self.command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, env=self.env + ) stdout, _ = process.communicate(timeout=self._flashing_timeout) except subprocess.TimeoutExpired as exc: process.kill() @@ -151,141 +176,15 @@ def _flash_and_run(self) -> None: logger.error(msg) raise TwisterHarnessException(msg) - def _connect_device(self) -> None: - serial_name = self._open_serial_pty() or self.device_config.serial - logger.debug('Opening serial connection for %s', serial_name) - try: - self._serial_connection = serial.Serial( - serial_name, - baudrate=self.device_config.baud, - parity=serial.PARITY_NONE, - stopbits=serial.STOPBITS_ONE, - bytesize=serial.EIGHTBITS, - timeout=self.base_timeout, - ) - except serial.SerialException as exc: - logger.exception('Cannot open connection: %s', exc) - self._close_serial_pty() - raise - - self._serial_connection.flush() - self._serial_connection.reset_input_buffer() - self._serial_connection.reset_output_buffer() - - def _open_serial_pty(self) -> str | None: - """Open a pty pair, run process and return tty name""" - if not self.device_config.serial_pty: - return None - - try: - master, slave = pty.openpty() - except NameError as exc: - logger.exception('PTY module is not available.') - raise exc - - try: - self._serial_pty_proc = subprocess.Popen( - re.split(',| ', self.device_config.serial_pty), - stdout=master, - stdin=master, - stderr=master - ) - except subprocess.CalledProcessError as exc: - logger.exception('Failed to run subprocess %s, error %s', self.device_config.serial_pty, str(exc)) - raise - return os.ttyname(slave) - - def _disconnect_device(self) -> None: - if self._serial_connection: - serial_name = self._serial_connection.port - self._serial_connection.close() - # self._serial_connection = None - logger.debug('Closed serial connection for %s', serial_name) - self._close_serial_pty() - - def _close_serial_pty(self) -> None: - """Terminate the process opened for serial pty script""" - if self._serial_pty_proc: - self._serial_pty_proc.terminate() - self._serial_pty_proc.communicate(timeout=self.base_timeout) - logger.debug('Process %s terminated', self.device_config.serial_pty) - self._serial_pty_proc = None - def _close_device(self) -> None: if self.device_config.post_script: self._run_custom_script(self.device_config.post_script, self.base_timeout) - def is_device_running(self) -> bool: - return self._device_run.is_set() - - def is_device_connected(self) -> bool: - return bool( - self.is_device_running() - and self._device_connected.is_set() - and self._serial_connection - and self._serial_connection.is_open - ) - - def _read_device_output(self) -> bytes: - try: - output = self._readline_serial() - except (serial.SerialException, TypeError, IOError): - # serial was probably disconnected - output = b'' - return output - - def _readline_serial(self) -> bytes: - """ - This method was created to avoid using PySerial built-in readline - method which cause blocking reader thread even if there is no data to - read. Instead for this, following implementation try to read data only - if they are available. Inspiration for this code was taken from this - comment: - https://github.com/pyserial/pyserial/issues/216#issuecomment-369414522 - """ - line = self._readline_from_serial_buffer() - if line is not None: - return line - while True: - if self._serial_connection is None or not self._serial_connection.is_open: - return b'' - elif self._serial_connection.in_waiting == 0: - time.sleep(0.05) - continue - else: - bytes_to_read = max(1, min(2048, self._serial_connection.in_waiting)) - output = self._serial_connection.read(bytes_to_read) - self._serial_buffer.extend(output) - line = self._readline_from_serial_buffer() - if line is not None: - return line - - def _readline_from_serial_buffer(self) -> bytes | None: - idx = self._serial_buffer.find(b"\n") - if idx >= 0: - line = self._serial_buffer[:idx+1] - self._serial_buffer = self._serial_buffer[idx+1:] - return bytes(line) - else: - return None - - def _write_to_device(self, data: bytes) -> None: - self._serial_connection.write(data) - - def _flush_device_output(self) -> None: - if self.is_device_connected(): - self._serial_connection.flush() - self._serial_connection.reset_input_buffer() - - def _clear_internal_resources(self) -> None: - super()._clear_internal_resources() - self._serial_connection = None - self._serial_pty_proc = None - self._serial_buffer.clear() - @staticmethod def _run_custom_script(script_path: str | Path, timeout: float) -> None: - with subprocess.Popen(str(script_path), stderr=subprocess.PIPE, stdout=subprocess.PIPE) as proc: + with subprocess.Popen( + str(script_path), stderr=subprocess.PIPE, stdout=subprocess.PIPE + ) as proc: try: stdout, stderr = proc.communicate(timeout=timeout) logger.debug(stdout.decode()) diff --git a/scripts/pylib/pytest-twister-harness/src/twister_harness/device/qemu_adapter.py b/scripts/pylib/pytest-twister-harness/src/twister_harness/device/qemu_adapter.py deleted file mode 100755 index 110ce601c231..000000000000 --- a/scripts/pylib/pytest-twister-harness/src/twister_harness/device/qemu_adapter.py +++ /dev/null @@ -1,67 +0,0 @@ -# Copyright (c) 2023 Nordic Semiconductor ASA -# -# SPDX-License-Identifier: Apache-2.0 - -from __future__ import annotations - -import logging -import time - -from twister_harness.device.fifo_handler import FifoHandler -from twister_harness.device.binary_adapter import BinaryAdapterBase -from twister_harness.exceptions import TwisterHarnessException -from twister_harness.twister_harness_config import DeviceConfig - -logger = logging.getLogger(__name__) - - -class QemuAdapter(BinaryAdapterBase): - def __init__(self, device_config: DeviceConfig) -> None: - super().__init__(device_config) - qemu_fifo_file_path = self.device_config.build_dir / 'qemu-fifo' - self._fifo_connection: FifoHandler = FifoHandler(qemu_fifo_file_path, self.base_timeout) - - def generate_command(self) -> None: - """Set command to run.""" - self.command = [self.west, 'build', '-d', str(self.device_config.app_build_dir), '-t', 'run'] - if 'stdin' in self.process_kwargs: - self.process_kwargs.pop('stdin') - - def _flash_and_run(self) -> None: - super()._flash_and_run() - self._create_fifo_connection() - - def _create_fifo_connection(self) -> None: - self._fifo_connection.initiate_connection() - timeout_time: float = time.time() + self.base_timeout - while time.time() < timeout_time and self._is_binary_running(): - if self._fifo_connection.is_open: - return - time.sleep(0.1) - msg = 'Cannot establish communication with QEMU device.' - logger.error(msg) - raise TwisterHarnessException(msg) - - def _stop_subprocess(self) -> None: - super()._stop_subprocess() - self._fifo_connection.disconnect() - - def _read_device_output(self) -> bytes: - try: - output = self._fifo_connection.readline() - except (OSError, ValueError): - # emulation was probably finished and thus fifo file was closed too - output = b'' - return output - - def _write_to_device(self, data: bytes) -> None: - self._fifo_connection.write(data) - self._fifo_connection.flush_write() - - def _flush_device_output(self) -> None: - if self.is_device_running(): - self._fifo_connection.flush_read() - - def is_device_connected(self) -> bool: - """Return true if device is connected.""" - return bool(super().is_device_connected() and self._fifo_connection.is_open) diff --git a/scripts/pylib/pytest-twister-harness/src/twister_harness/fixtures.py b/scripts/pylib/pytest-twister-harness/src/twister_harness/fixtures.py index 765da163312a..7e6640d7ba8c 100644 --- a/scripts/pylib/pytest-twister-harness/src/twister_harness/fixtures.py +++ b/scripts/pylib/pytest-twister-harness/src/twister_harness/fixtures.py @@ -97,7 +97,7 @@ def mcumgr(device_object: DeviceAdapter) -> Generator[MCUmgr, None, None]: """Fixture to create an MCUmgr instance for serial connection.""" if not MCUmgr.is_available(): pytest.skip('mcumgr not available') - yield MCUmgr.create_for_serial(device_object.device_config.serial) + yield MCUmgr.create_for_serial(device_object.device_config.serial_configs[0].port) @pytest.fixture() 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 1e088fc95eef..937c4ebf566b 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 @@ -15,6 +15,13 @@ logger = logging.getLogger(__name__) +@dataclass +class DeviceSerialConfig: + port: str + baud: int = 115200 + serial_pty: str = '' + + @dataclass class DeviceConfig: type: str @@ -22,13 +29,11 @@ class DeviceConfig: base_timeout: float = 60.0 # [s] flash_timeout: float = 60.0 # [s] platform: str = '' - serial: str = '' - baud: int = 115200 + serial_configs: list[DeviceSerialConfig] = field(default_factory=list) runner: str = '' runner_params: list[str] = field(default_factory=list, repr=False) id: str = '' product: str = '' - serial_pty: str = '' flash_before: bool = False west_flash_extra_args: list[str] = field(default_factory=list, repr=False) flash_command: str = '' @@ -68,19 +73,27 @@ def create(cls, config: pytest.Config) -> TwisterHarnessConfig: runner_params: list[str] = [] if config.option.runner_params: runner_params = [w.strip() for w in config.option.runner_params] + serial_configs: list[DeviceSerialConfig] = [] + if config.option.device_serial: + for serial_port in config.option.device_serial: + serial_configs.append( + DeviceSerialConfig( + port=serial_port, + baud=config.option.device_serial_baud, + serial_pty=config.option.device_serial_pty + ) + ) device_from_cli = DeviceConfig( type=config.option.device_type, build_dir=_cast_to_path(config.option.build_dir), base_timeout=config.option.base_timeout, flash_timeout=config.option.flash_timeout, platform=config.option.platform, - serial=config.option.device_serial[0] if config.option.device_serial else '', - baud=config.option.device_serial_baud, + serial_configs=serial_configs, runner=config.option.runner, runner_params=runner_params, id=config.option.device_id, product=config.option.device_product, - serial_pty=config.option.device_serial_pty, flash_before=bool(config.option.flash_before), west_flash_extra_args=west_flash_extra_args, flash_command=flash_command, From 4b6ad9db3ce80f88d700e8001c0cce2ac908e536 Mon Sep 17 00:00:00 2001 From: Grzegorz Chwierut Date: Mon, 24 Nov 2025 17:14:16 +0100 Subject: [PATCH 0761/3659] tests: twister: Update unit tests to support miltiple ports Updated unit tests from pytest-twister-harness with wupport of multiple connextions. Signed-off-by: Grzegorz Chwierut --- .../tests/device/binary_adapter_test.py | 55 +++++-------------- .../tests/device/hardware_adapter_test.py | 24 ++++---- .../tests/device/qemu_adapter_test.py | 18 +++--- .../tests/plugin_test.py | 2 +- 4 files changed, 38 insertions(+), 61 deletions(-) diff --git a/scripts/pylib/pytest-twister-harness/tests/device/binary_adapter_test.py b/scripts/pylib/pytest-twister-harness/tests/device/binary_adapter_test.py index 24b85b9c8183..bd1eb75be414 100755 --- a/scripts/pylib/pytest-twister-harness/tests/device/binary_adapter_test.py +++ b/scripts/pylib/pytest-twister-harness/tests/device/binary_adapter_test.py @@ -2,7 +2,6 @@ # # SPDX-License-Identifier: Apache-2.0 -import logging import os import subprocess import time @@ -58,8 +57,8 @@ def test_if_binary_adapter_runs_without_errors(launched_device: NativeSimulatorA lines = device.readlines_until(regex='Returns with code') device.close() assert 'Readability counts.' in lines - assert os.path.isfile(device.handler_log_path) - with open(device.handler_log_path, 'r') as file: + assert os.path.isfile(device.connections[0].log_path) + with open(device.connections[0].log_path, 'r') as file: file_lines = [line.strip() for line in file.readlines()] assert file_lines[-2:] == lines[-2:] @@ -68,14 +67,14 @@ def test_if_binary_adapter_finishes_after_timeout_while_there_is_no_data_from_su device: NativeSimulatorAdapter, script_path: str ) -> None: """Test if thread finishes after timeout when there is no data on stdout, but subprocess is still running""" - device.base_timeout = 0.3 + device.connections[0].timeout = 0.3 device.command = ['python3', script_path, '--long-sleep', '--sleep=5'] device.launch() with pytest.raises(AssertionError, match='Did not find line "Returns with code" within 0.3 seconds'): device.readlines_until(regex='Returns with code') device.close() assert device._process is None - with open(device.handler_log_path, 'r') as file: + with open(device.connections[0].log_path, 'r') as file: file_lines = [line.strip() for line in file.readlines()] # this message should not be printed because script has been terminated due to timeout assert 'End of script' not in file_lines, 'Script has not been terminated before end' @@ -85,7 +84,7 @@ def test_if_binary_adapter_raises_exception_empty_command(device: NativeSimulato device.command = [] exception_msg = 'Run command is empty, please verify if it was generated properly.' with pytest.raises(TwisterHarnessException, match=exception_msg): - device._flash_and_run() + device._device_launch() @mock.patch('subprocess.Popen', side_effect=subprocess.SubprocessError(1, 'Exception message')) @@ -94,7 +93,7 @@ def test_if_binary_adapter_raises_exception_when_subprocess_raised_subprocess_er ) -> None: device.command = ['echo', 'TEST'] with pytest.raises(TwisterHarnessException, match='Exception message'): - device._flash_and_run() + device._device_launch() @mock.patch('subprocess.Popen', side_effect=FileNotFoundError(1, 'File not found', 'fake_file.txt')) @@ -103,7 +102,7 @@ def test_if_binary_adapter_raises_exception_file_not_found( ) -> None: device.command = ['echo', 'TEST'] with pytest.raises(TwisterHarnessException, match='fake_file.txt'): - device._flash_and_run() + device._device_launch() @mock.patch('subprocess.Popen', side_effect=Exception(1, 'Raised other exception')) @@ -112,43 +111,17 @@ def test_if_binary_adapter_raises_exception_when_subprocess_raised_an_error( ) -> None: device.command = ['echo', 'TEST'] with pytest.raises(TwisterHarnessException, match='Raised other exception'): - device._flash_and_run() - - -def test_if_binary_adapter_connect_disconnect_print_warnings_properly( - caplog: pytest.LogCaptureFixture, launched_device: NativeSimulatorAdapter -) -> None: - device = launched_device - assert device._device_connected.is_set() and device.is_device_connected() - caplog.set_level(logging.DEBUG) - device.connect() - warning_msg = 'Device already connected' - assert warning_msg in caplog.text - for record in caplog.records: - if record.message == warning_msg: - assert record.levelname == 'DEBUG' - break - device.disconnect() - assert not device._device_connected.is_set() and not device.is_device_connected() - device.disconnect() - warning_msg = 'Device already disconnected' - assert warning_msg in caplog.text - for record in caplog.records: - if record.message == warning_msg: - assert record.levelname == 'DEBUG' - break + device._device_launch() def test_if_binary_adapter_raise_exc_during_connect_read_and_write_after_close( launched_device: NativeSimulatorAdapter ) -> None: device = launched_device - assert device._device_run.is_set() and device.is_device_running() + assert device._reader_started.is_set() and device.connections[0]._is_binary_running() device.close() - assert not device._device_run.is_set() and not device.is_device_running() - with pytest.raises(TwisterHarnessException, match='Cannot connect to not working device'): - device.connect() - with pytest.raises(TwisterHarnessException, match='No connection to the device'): + assert not device._reader_started.is_set() and not device.connections[0]._is_binary_running() + with pytest.raises(TwisterHarnessException, match='Cannot write to not connected device'): device.write(b'') device.clear_buffer() with pytest.raises(TwisterHarnessException, match='No connection to the device and no more data to read.'): @@ -159,8 +132,8 @@ def test_if_binary_adapter_raise_exc_during_read_and_write_after_close( launched_device: NativeSimulatorAdapter ) -> None: device = launched_device - device.disconnect() - with pytest.raises(TwisterHarnessException, match='No connection to the device'): + device.close() + with pytest.raises(TwisterHarnessException, match='Cannot write to not connected device'): device.write(b'') device.clear_buffer() with pytest.raises(TwisterHarnessException, match='No connection to the device and no more data to read.'): @@ -179,8 +152,8 @@ def test_if_binary_adapter_is_able_to_read_leftovers_after_disconnect_or_close( device.connect() device.readlines_until(regex='Flat is better than nested.') time.sleep(0.1) - device.close() assert len(device.readlines()) > 0 + device.close() def test_if_binary_adapter_properly_send_data_to_subprocess( diff --git a/scripts/pylib/pytest-twister-harness/tests/device/hardware_adapter_test.py b/scripts/pylib/pytest-twister-harness/tests/device/hardware_adapter_test.py index 7561a352ef46..288b567e6d0b 100644 --- a/scripts/pylib/pytest-twister-harness/tests/device/hardware_adapter_test.py +++ b/scripts/pylib/pytest-twister-harness/tests/device/hardware_adapter_test.py @@ -11,13 +11,14 @@ from twister_harness.device.hardware_adapter import HardwareAdapter from twister_harness.exceptions import TwisterHarnessException -from twister_harness.twister_harness_config import DeviceConfig +from twister_harness.twister_harness_config import DeviceConfig, DeviceSerialConfig @pytest.fixture(name='device') def fixture_adapter(tmp_path) -> HardwareAdapter: build_dir = tmp_path / 'build_dir' os.mkdir(build_dir) + serial_configs = [DeviceSerialConfig(port='')] device_config = DeviceConfig( type='hardware', build_dir=build_dir, @@ -26,6 +27,7 @@ def fixture_adapter(tmp_path) -> HardwareAdapter: id='p_id', base_timeout=5.0, flash_command='', + serial_configs=serial_configs, ) return HardwareAdapter(device_config) @@ -214,28 +216,28 @@ def test_device_log_correct_error_handle(patched_popen, device: HardwareAdapter, assert 'flashing error' in file.readlines() -@mock.patch('twister_harness.device.hardware_adapter.subprocess.Popen') -@mock.patch('twister_harness.device.hardware_adapter.serial.Serial') +@mock.patch('twister_harness.device.device_connection.subprocess.Popen') +@mock.patch('twister_harness.device.device_connection.serial.Serial') def test_if_hardware_adapter_uses_serial_pty( patched_serial, patched_popen, device: HardwareAdapter, monkeypatch: pytest.MonkeyPatch ): - device.device_config.serial_pty = 'script.py' + device.device_config.serial_configs[0].serial_pty = 'script.py' popen_mock = mock.Mock() popen_mock.communicate.return_value = (b'output', b'error') patched_popen.return_value = popen_mock - monkeypatch.setattr('twister_harness.device.hardware_adapter.pty.openpty', lambda: (123, 456)) - monkeypatch.setattr('twister_harness.device.hardware_adapter.os.ttyname', lambda x: f'/pty/ttytest/{x}') + monkeypatch.setattr('twister_harness.device.device_connection.pty.openpty', lambda: (123, 456)) + monkeypatch.setattr('twister_harness.device.device_connection.os.ttyname', lambda x: f'/pty/ttytest/{x}') serial_mock = mock.Mock() serial_mock.port = '/pty/ttytest/456' patched_serial.return_value = serial_mock - device._device_run.set() + device._reader_started.set() device.connect() - assert device._serial_connection.port == '/pty/ttytest/456' # type: ignore[union-attr] - assert device._serial_pty_proc + assert device.connections[0]._serial_connection.port == '/pty/ttytest/456' # type: ignore[union-attr] + assert device.connections[0]._serial_pty_proc patched_popen.assert_called_with( ['script.py'], stdout=123, @@ -244,7 +246,7 @@ def test_if_hardware_adapter_uses_serial_pty( ) device.disconnect() - assert not device._serial_pty_proc + assert not device.connections[0]._serial_pty_proc def test_if_hardware_adapter_properly_send_data_to_subprocess( @@ -255,7 +257,7 @@ def test_if_hardware_adapter_properly_send_data_to_subprocess( output. Flashing command is mocked by "dummy" echo command. """ device.command = ['echo', 'TEST'] # only to mock flashing command - device.device_config.serial_pty = f'python3 {shell_simulator_path}' + device.device_config.serial_configs[0].serial_pty = f'python3 {shell_simulator_path}' device.launch() time.sleep(0.1) device.write(b'zen\n') diff --git a/scripts/pylib/pytest-twister-harness/tests/device/qemu_adapter_test.py b/scripts/pylib/pytest-twister-harness/tests/device/qemu_adapter_test.py index 42406cb702d1..93162106fc4a 100755 --- a/scripts/pylib/pytest-twister-harness/tests/device/qemu_adapter_test.py +++ b/scripts/pylib/pytest-twister-harness/tests/device/qemu_adapter_test.py @@ -7,9 +7,10 @@ from typing import Generator from unittest.mock import patch +from unittest import mock import pytest -from twister_harness.device.qemu_adapter import QemuAdapter +from twister_harness.device.binary_adapter import QemuAdapter from twister_harness.exceptions import TwisterHarnessException from twister_harness.twister_harness_config import DeviceConfig @@ -36,21 +37,22 @@ def test_if_qemu_adapter_runs_without_errors(resources, device: QemuAdapter) -> fifo_file_path = str(device.device_config.build_dir / 'qemu-fifo') script_path = resources.joinpath('fifo_mock.py') device.command = ['python', str(script_path), fifo_file_path] + device.connections[0]._write_to_device = mock.Mock() device.launch() lines = device.readlines_until(regex='Namespaces are one honking great idea') device.close() assert 'Readability counts.' in lines - assert os.path.isfile(device.handler_log_path) - with open(device.handler_log_path, 'r') as file: + assert os.path.isfile(device.connections[0].log_path) + with open(device.connections[0].log_path, 'r') as file: file_lines = [line.strip() for line in file.readlines()] assert file_lines[-2:] == lines[-2:] def test_if_qemu_adapter_raise_exception_due_to_no_fifo_connection(device: QemuAdapter) -> None: - device.base_timeout = 0.3 + device.connections[0].timeout = 0.3 device.command = ['sleep', '1'] with pytest.raises(TwisterHarnessException, match='Cannot establish communication with QEMU device.'): - device._flash_and_run() - device._close_device() - assert not os.path.exists(device._fifo_connection._fifo_out_path) - assert not os.path.exists(device._fifo_connection._fifo_in_path) + device.launch() + device.close() + assert not os.path.exists(device.connections[0]._fifo_connection._fifo_out_path) + assert not os.path.exists(device.connections[0]._fifo_connection._fifo_in_path) diff --git a/scripts/pylib/pytest-twister-harness/tests/plugin_test.py b/scripts/pylib/pytest-twister-harness/tests/plugin_test.py index 51fc79392ca8..72cb09a500e8 100644 --- a/scripts/pylib/pytest-twister-harness/tests/plugin_test.py +++ b/scripts/pylib/pytest-twister-harness/tests/plugin_test.py @@ -15,7 +15,7 @@ 'import_path, class_name, device_type', [ ('twister_harness.device.binary_adapter', 'NativeSimulatorAdapter', 'native'), - ('twister_harness.device.qemu_adapter', 'QemuAdapter', 'qemu'), + ('twister_harness.device.binary_adapter', 'QemuAdapter', 'qemu'), ('twister_harness.device.hardware_adapter', 'HardwareAdapter', 'hardware'), ], ids=[ From 10533cedbe8c64bedeae5d41b4a9b093087547d7 Mon Sep 17 00:00:00 2001 From: Grzegorz Chwierut Date: Mon, 24 Nov 2025 17:16:28 +0100 Subject: [PATCH 0762/3659] doc: twister: Add multi-core testing support documentation Document the new multiple UART connection support in pytest-twister-harness plugin. Hardware devices can now access multiple connections using the connection_index parameter (0=main UART, 1=second core UART). Also update readlines_until() examples to use explicit regex= parameter for improved API clarity. Signed-off-by: Grzegorz Chwierut --- doc/develop/test/pytest.rst | 10 +++------- doc/develop/test/twister.rst | 33 ++++++++++++++++++++++++++++++--- 2 files changed, 33 insertions(+), 10 deletions(-) diff --git a/doc/develop/test/pytest.rst b/doc/develop/test/pytest.rst index 88137a691747..c4db74a5a349 100644 --- a/doc/develop/test/pytest.rst +++ b/doc/develop/test/pytest.rst @@ -120,7 +120,7 @@ writing tests which are device-type-agnostic. Scope of this fixture is determine from twister_harness import DeviceAdapter def test_sample(dut: DeviceAdapter): - dut.readlines_until('Hello world') + dut.readlines_until(regex='Hello world') shell ===== @@ -182,7 +182,7 @@ device. def test_sample(unlaunched_dut: DeviceAdapter): unlaunched_dut.launch() - unlaunched_dut.readlines_until('Hello world') + unlaunched_dut.readlines_until(regex='Hello world') Classes ******* @@ -194,7 +194,7 @@ DeviceAdapter .. automethod:: launch - .. automethod:: connect + .. automethod:: close .. automethod:: readline @@ -204,10 +204,6 @@ DeviceAdapter .. automethod:: write - .. automethod:: disconnect - - .. automethod:: close - .. _shell_class: Shell diff --git a/doc/develop/test/twister.rst b/doc/develop/test/twister.rst index dc1a59ff5373..57209962c4ff 100644 --- a/doc/develop/test/twister.rst +++ b/doc/develop/test/twister.rst @@ -1564,9 +1564,8 @@ The ``--device-serial`` option denotes the serial device the board is connected This needs to be accessible by the user running twister. You can run this on only one board at a time, specified using the ``--platform`` option. If the platform supports multiple serial ports, you can provide ``--device-serial`` -multiple times, and it will be passed to the pytest harness. -However, currently the pytest-twister-harness plugin handles only the first serial port, -other ports must be opened manually in the test code. +multiple times, and it will be passed to the pytest harness. Alternatively you can use +the hardware map, see :ref:`multi-core testing ` for more details The ``--device-serial-baud`` option is only needed if your device does not run at 115200 baud. @@ -1914,6 +1913,34 @@ Using Single Board For Multiple Variants runner: nrfjprog serial: /dev/ttyACM1 +.. _twister_multi_core_testing: + +Multi-Core testing support +-------------------------- + +Twister supports testing multi-core applications where different cores use +separate UART interfaces. This feature works only with the pytest harness +(``harness: pytest``). Generated hardware map should contain multiple entries +for the same physical device, each representing a different core connection. +For example: + +.. code-block:: yaml + + - connected: true + id: 001234567890 + serial: /dev/ttyACM0 + - connected: true + id: 001234567890 + platform: + - nrf54l15dk/nrf54l15/cpuapp + product: J-Link + runner: nrfutil + serial: /dev/ttyACM1 + +Both instances share the same device ID but have different serial ports, allowing +tests to interact with multiple cores simultaneously. Each connection +is handled independently with separate log files. + Quarantine ---------- From 2d80ffafb4b12d6fb3c7ab244c797dd5513ed8d5 Mon Sep 17 00:00:00 2001 From: Grzegorz Chwierut Date: Mon, 24 Nov 2025 17:20:52 +0100 Subject: [PATCH 0763/3659] samples: sysbuild: hello_world: Simplify dual UART test with new API Replace manual serial port handling with the new multiple UART connection support from pytest-twister-harness. The test now uses connection_index=1 to read from the second core UART instead of managing a separate serial connection fixture. Signed-off-by: Grzegorz Chwierut --- .../hello_world/pytest/test_both_uart.py | 55 ++----------------- samples/sysbuild/hello_world/sample.yaml | 2 + 2 files changed, 6 insertions(+), 51 deletions(-) diff --git a/samples/sysbuild/hello_world/pytest/test_both_uart.py b/samples/sysbuild/hello_world/pytest/test_both_uart.py index 15e652e1cf68..ad920034d31f 100644 --- a/samples/sysbuild/hello_world/pytest/test_both_uart.py +++ b/samples/sysbuild/hello_world/pytest/test_both_uart.py @@ -3,64 +3,17 @@ # # SPDX-License-Identifier: Apache-2.0 # - -import logging -import re -import time -from collections.abc import Generator - -import pytest -import serial from twister_harness import DeviceAdapter -from twister_harness.fixtures import determine_scope - -logger = logging.getLogger("test_both_uart") -logger.setLevel(logging.DEBUG) - -@pytest.fixture(scope=determine_scope) -def second_serial( - request: pytest.FixtureRequest, device_object: DeviceAdapter -) -> Generator[serial.Serial | None, None, None]: - """Return second serial port if provided.""" - device_serials = request.config.getoption('--device-serial') - - if not device_serials or len(device_serials) <= 1: - pytest.skip("Second serial not available") - - logger.debug(f"Opening serial connection for {device_serials[1]}") - second_serial = serial.Serial( - port=device_serials[1], - baudrate=device_object.device_config.baud, - timeout=1, - rtscts=True, - ) - yield second_serial - second_serial.close() +timeout = 5 +regex = "Hello world from .*" def test_uart_in_app(dut: DeviceAdapter): """Verify logs from uart in application""" - timeout = 5 - regex = "Hello world from .*" dut.readlines_until(regex=regex, print_output=True, timeout=timeout) -def test_uart_in_second_core(second_serial: serial.Serial | None, dut: DeviceAdapter): +def test_uart_in_second_core(dut: DeviceAdapter): """Verify logs from uart in second core""" - timeout = 5 - regex = "Hello world from .*" - - regex_compiled = re.compile(regex) - timeout_time: float = time.time() + timeout - while time.time() < timeout_time: - try: - line = second_serial.readline().decode("utf-8") - logger.debug(f"Second serial: -{line}-") - except serial.SerialException: - logger.exception("Second serial") - if regex_compiled.search(line): - logger.debug("Second serial - found") - break - else: - raise AssertionError(f"Second serial - regex not found: {regex}") + dut.readlines_until(connection_index=1, regex=regex, print_output=True, timeout=timeout) diff --git a/samples/sysbuild/hello_world/sample.yaml b/samples/sysbuild/hello_world/sample.yaml index 8fda71e4805d..47a95b35bb05 100644 --- a/samples/sysbuild/hello_world/sample.yaml +++ b/samples/sysbuild/hello_world/sample.yaml @@ -7,6 +7,8 @@ sample: common: sysbuild: true harness: pytest + harness_config: + pytest_dut_scope: session tests: sample.sysbuild.hello_world.nrf5340dk_cpuapp_cpunet: From fca50869b8731836fef65ec862da4d04c361216a Mon Sep 17 00:00:00 2001 From: Grzegorz Chwierut Date: Mon, 24 Nov 2025 17:24:23 +0100 Subject: [PATCH 0764/3659] samples: icmsg: Updated to verify output from both cores Changed 'harness: console' to 'harness: pytest' to verify output from both application and network cores using the new multiple UART connection support. The pytest test reads from connection_index=0 (application core) and connection_index=1 (network/remote core) to validate IPC communication on both sides. Signed-off-by: Grzegorz Chwierut --- .../icmsg/pytest/test_ipc_icmsg.py | 27 +++++ .../subsys/ipc/ipc_service/icmsg/sample.yaml | 109 +++--------------- 2 files changed, 40 insertions(+), 96 deletions(-) create mode 100644 samples/subsys/ipc/ipc_service/icmsg/pytest/test_ipc_icmsg.py diff --git a/samples/subsys/ipc/ipc_service/icmsg/pytest/test_ipc_icmsg.py b/samples/subsys/ipc/ipc_service/icmsg/pytest/test_ipc_icmsg.py new file mode 100644 index 000000000000..492c7c33e305 --- /dev/null +++ b/samples/subsys/ipc/ipc_service/icmsg/pytest/test_ipc_icmsg.py @@ -0,0 +1,27 @@ +# Copyright (c) 2025 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 + +import pytest +from twister_harness import DeviceAdapter + + +def test_ipc_icmsg(dut: DeviceAdapter): + """Test IPC ICMSG sample application.""" + expected_lines = [ + "*IPC-service * demo started*", + "*Ep bounded*", + "*Perform sends for*", + "*Sent*", + "*Received*", + "*IPC-service * demo ended*", + ] + + # check output from the application core + lines_from_app = dut.readlines_until(regex="demo ended") + pytest.LineMatcher(lines_from_app).fnmatch_lines(expected_lines) + + # check output from the remote core (skip for non-hardware devices, e.g. bsim) + if dut.device_config.type == "hardware": + lines_from_remote = dut.readlines_until(connection_index=1, regex="demo ended") + pytest.LineMatcher(lines_from_remote).fnmatch_lines(expected_lines) diff --git a/samples/subsys/ipc/ipc_service/icmsg/sample.yaml b/samples/subsys/ipc/ipc_service/icmsg/sample.yaml index fae6b067b39a..d084434f7952 100644 --- a/samples/subsys/ipc/ipc_service/icmsg/sample.yaml +++ b/samples/subsys/ipc/ipc_service/icmsg/sample.yaml @@ -2,6 +2,9 @@ sample: name: IPC Service example integration (icmsg backend) common: timeout: 30 + sysbuild: true + tags: ipc + harness: pytest tests: sample.ipc.icmsg: platform_allow: @@ -10,114 +13,52 @@ tests: integration_platforms: - nrf5340dk/nrf5340/cpuapp - nrf5340bsim/nrf5340/cpuapp - tags: ipc - sysbuild: true - harness: console - harness_config: - type: multi_line - ordered: false - regex: - - "host: IPC-service HOST demo started" - - "host: Ep bounded" - - "host: Perform sends for" - - "host: Sent" - - "host: Received" - - "host: IPC-service HOST demo ended" sample.ipc.icmsg.nrf54l15: - platform_allow: nrf54l15dk/nrf54l15/cpuapp + platform_allow: + - nrf54l15dk/nrf54l15/cpuapp integration_platforms: - nrf54l15dk/nrf54l15/cpuapp - tags: ipc extra_args: icmsg_SNIPPET=nordic-flpr - sysbuild: true - harness: console - harness_config: - type: multi_line - ordered: false - regex: - - "host: IPC-service HOST demo started" - - "host: Ep bounded" - - "host: Perform sends for" - - "host: Sent" - - "host: Received" - - "host: IPC-service HOST demo ended" sample.ipc.icmsg.nrf54l15_no_multithreading: - platform_allow: nrf54l15dk/nrf54l15/cpuapp + platform_allow: + - nrf54l15dk/nrf54l15/cpuapp integration_platforms: - nrf54l15dk/nrf54l15/cpuapp - tags: ipc extra_args: - icmsg_SNIPPET=nordic-flpr - icmsg_CONFIG_MULTITHREADING=n - icmsg_CONFIG_LOG_MODE_MINIMAL=y - remote_CONFIG_MULTITHREADING=n - remote_CONFIG_LOG_MODE_MINIMAL=y - sysbuild: true - harness: console - harness_config: - type: multi_line - ordered: false - regex: - - "I: IPC-service HOST demo started" - - "I: Ep bounded" - - "I: Perform sends for" - - "I: Sent" - - "I: Received" - - "I: IPC-service HOST demo ended" sample.ipc.icmsg.nrf54l15_remote_no_multithreading: - platform_allow: nrf54l15dk/nrf54l15/cpuapp + platform_allow: + - nrf54l15dk/nrf54l15/cpuapp integration_platforms: - nrf54l15dk/nrf54l15/cpuapp - tags: ipc extra_args: - icmsg_SNIPPET=nordic-flpr - remote_CONFIG_MULTITHREADING=n - remote_CONFIG_LOG_MODE_MINIMAL=y - sysbuild: true - harness: console - harness_config: - type: multi_line - ordered: false - regex: - - "host: IPC-service HOST demo started" - - "host: Ep bounded" - - "host: Perform sends for" - - "host: Sent" - - "host: Received" - - "host: IPC-service HOST demo ended" sample.ipc.icbmsg.nrf54l15: platform_allow: nrf54l15dk/nrf54l15/cpuapp integration_platforms: - nrf54l15dk/nrf54l15/cpuapp - tags: ipc extra_args: - icmsg_SNIPPET=nordic-flpr - icmsg_CONFIG_IPC_SERVICE_BACKEND_ICBMSG_NUM_EP=1 - icmsg_DTC_OVERLAY_FILE="boards/nrf54l15dk_nrf54l15_cpuapp_icbmsg.overlay" - remote_CONFIG_IPC_SERVICE_BACKEND_ICBMSG_NUM_EP=1 - remote_DTC_OVERLAY_FILE="boards/nrf54l15dk_nrf54l15_cpuflpr_icbmsg.overlay" - sysbuild: true - harness: console - harness_config: - type: multi_line - ordered: false - regex: - - "host: IPC-service HOST demo started" - - "host: Ep bounded" - - "host: Perform sends for" - - "host: Sent" - - "host: Received" - - "host: IPC-service HOST demo ended" sample.ipc.icbmsg.nrf54l15_no_multithreading: - platform_allow: nrf54l15dk/nrf54l15/cpuapp + platform_allow: + - nrf54l15dk/nrf54l15/cpuapp integration_platforms: - nrf54l15dk/nrf54l15/cpuapp - tags: ipc extra_args: - icmsg_SNIPPET=nordic-flpr - icmsg_CONFIG_IPC_SERVICE_BACKEND_ICBMSG_NUM_EP=1 @@ -128,24 +69,12 @@ tests: - remote_DTC_OVERLAY_FILE="boards/nrf54l15dk_nrf54l15_cpuflpr_icbmsg.overlay" - remote_CONFIG_MULTITHREADING=n - remote_CONFIG_LOG_MODE_MINIMAL=y - sysbuild: true - harness: console - harness_config: - type: multi_line - ordered: false - regex: - - "I: IPC-service HOST demo started" - - "I: Ep bounded" - - "I: Perform sends for" - - "I: Sent" - - "I: Received" - - "I: IPC-service HOST demo ended" sample.ipc.icbmsg.nrf54l15_remote_no_multithreading: - platform_allow: nrf54l15dk/nrf54l15/cpuapp + platform_allow: + - nrf54l15dk/nrf54l15/cpuapp integration_platforms: - nrf54l15dk/nrf54l15/cpuapp - tags: ipc extra_args: - icmsg_SNIPPET=nordic-flpr - icmsg_CONFIG_IPC_SERVICE_BACKEND_ICBMSG_NUM_EP=1 @@ -154,15 +83,3 @@ tests: - remote_DTC_OVERLAY_FILE="boards/nrf54l15dk_nrf54l15_cpuflpr_icbmsg.overlay" - remote_CONFIG_MULTITHREADING=n - remote_CONFIG_LOG_MODE_MINIMAL=y - sysbuild: true - harness: console - harness_config: - type: multi_line - ordered: false - regex: - - "host: IPC-service HOST demo started" - - "host: Ep bounded" - - "host: Perform sends for" - - "host: Sent" - - "host: Received" - - "host: IPC-service HOST demo ended" From 29e8a95004c6426130f661b3504e9b3c432f5727 Mon Sep 17 00:00:00 2001 From: Grzegorz Chwierut Date: Mon, 24 Nov 2025 17:30:00 +0100 Subject: [PATCH 0765/3659] tests: Aligned with changes in pytest-twister-harness plugin Aligned with changes in pytest plugin, where added support of multiple connections from one device. Signed-off-by: Grzegorz Chwierut --- .../classic/gap_c/pytest/conftest.py | 3 +- .../classic/gap_s/pytest/conftest.py | 3 +- .../classic/l2cap_c/pytest/conftest.py | 4 ++- .../classic/l2cap_s/pytest/conftest.py | 4 ++- .../classic/rfcomm_c/pytest/conftest.py | 3 +- .../classic/rfcomm_s/pytest/conftest.py | 3 +- .../classic/sdp_c/pytest/conftest.py | 3 +- .../classic/sdp_s/pytest/conftest.py | 3 +- .../classic/smp_bonding/pytest/conftest.py | 3 +- .../classic/smp_general/pytest/conftest.py | 33 ++----------------- .../classic/smp_io_cap/pytest/conftest.py | 3 +- .../smp_key_persist/pytest/conftest.py | 3 +- .../smp_key_persist/pytest/test_smp.py | 30 ----------------- .../classic/smp_sc_only/pytest/conftest.py | 3 +- .../pytest/test_downgrade_prevention.py | 2 +- tests/boot/with_mcumgr/pytest/test_upgrade.py | 10 +++--- tests/misc/llext-edk/pytest/test_edk.py | 2 +- .../pytest/test_app_vs_openssl.py | 3 +- 18 files changed, 37 insertions(+), 81 deletions(-) diff --git a/tests/bluetooth/classic/gap_c/pytest/conftest.py b/tests/bluetooth/classic/gap_c/pytest/conftest.py index 512036b94854..42210fb4fa9f 100644 --- a/tests/bluetooth/classic/gap_c/pytest/conftest.py +++ b/tests/bluetooth/classic/gap_c/pytest/conftest.py @@ -1,6 +1,7 @@ # Copyright 2025 NXP # # SPDX-License-Identifier: Apache-2.0 +# pylint: disable=duplicate-code import logging import re @@ -31,7 +32,7 @@ def fixture_initialize(request, shell: Shell, dut: DeviceAdapter): assert hci is not None lines = shell.exec_command("bt init") - lines = dut.readlines_until("Bluetooth initialized") + lines = dut.readlines_until(regex="Bluetooth initialized") regex = r'Identity: (?P(.*?):(.*?):(.*?):(.*?):(.*?):(.*?) *\((.*?)\))' bd_addr = None for line in lines: diff --git a/tests/bluetooth/classic/gap_s/pytest/conftest.py b/tests/bluetooth/classic/gap_s/pytest/conftest.py index 512036b94854..42210fb4fa9f 100644 --- a/tests/bluetooth/classic/gap_s/pytest/conftest.py +++ b/tests/bluetooth/classic/gap_s/pytest/conftest.py @@ -1,6 +1,7 @@ # Copyright 2025 NXP # # SPDX-License-Identifier: Apache-2.0 +# pylint: disable=duplicate-code import logging import re @@ -31,7 +32,7 @@ def fixture_initialize(request, shell: Shell, dut: DeviceAdapter): assert hci is not None lines = shell.exec_command("bt init") - lines = dut.readlines_until("Bluetooth initialized") + lines = dut.readlines_until(regex="Bluetooth initialized") regex = r'Identity: (?P(.*?):(.*?):(.*?):(.*?):(.*?):(.*?) *\((.*?)\))' bd_addr = None for line in lines: diff --git a/tests/bluetooth/classic/l2cap_c/pytest/conftest.py b/tests/bluetooth/classic/l2cap_c/pytest/conftest.py index ea805f20d38d..5710ed285a8d 100644 --- a/tests/bluetooth/classic/l2cap_c/pytest/conftest.py +++ b/tests/bluetooth/classic/l2cap_c/pytest/conftest.py @@ -1,6 +1,8 @@ # Copyright 2024 NXP # # SPDX-License-Identifier: Apache-2.0 +# pylint: disable=duplicate-code + import re import pytest @@ -28,7 +30,7 @@ def fixture_initialize(request, shell: Shell, dut: DeviceAdapter): assert hci is not None shell.exec_command("bt init") - lines = dut.readlines_until("Bluetooth initialized") + lines = dut.readlines_until(regex="Bluetooth initialized") regex = r'Identity: *(?P([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2}) *\((.*?)\))' bd_addr = None for line in lines: diff --git a/tests/bluetooth/classic/l2cap_s/pytest/conftest.py b/tests/bluetooth/classic/l2cap_s/pytest/conftest.py index ea805f20d38d..5710ed285a8d 100644 --- a/tests/bluetooth/classic/l2cap_s/pytest/conftest.py +++ b/tests/bluetooth/classic/l2cap_s/pytest/conftest.py @@ -1,6 +1,8 @@ # Copyright 2024 NXP # # SPDX-License-Identifier: Apache-2.0 +# pylint: disable=duplicate-code + import re import pytest @@ -28,7 +30,7 @@ def fixture_initialize(request, shell: Shell, dut: DeviceAdapter): assert hci is not None shell.exec_command("bt init") - lines = dut.readlines_until("Bluetooth initialized") + lines = dut.readlines_until(regex="Bluetooth initialized") regex = r'Identity: *(?P([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2}) *\((.*?)\))' bd_addr = None for line in lines: diff --git a/tests/bluetooth/classic/rfcomm_c/pytest/conftest.py b/tests/bluetooth/classic/rfcomm_c/pytest/conftest.py index 891497101975..c92e715a3806 100644 --- a/tests/bluetooth/classic/rfcomm_c/pytest/conftest.py +++ b/tests/bluetooth/classic/rfcomm_c/pytest/conftest.py @@ -1,6 +1,7 @@ # Copyright 2025 NXP # # SPDX-License-Identifier: Apache-2.0 +# pylint: disable=duplicate-code import logging import re @@ -31,7 +32,7 @@ def fixture_initialize(request, shell: Shell, dut: DeviceAdapter): assert hci is not None lines = shell.exec_command("bt init") - lines = dut.readlines_until("Bluetooth initialized") + lines = dut.readlines_until(regex="Bluetooth initialized") regex = r'Identity: *(?P([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2}) *\((.*?)\))' bd_addr = None for line in lines: diff --git a/tests/bluetooth/classic/rfcomm_s/pytest/conftest.py b/tests/bluetooth/classic/rfcomm_s/pytest/conftest.py index 5f7b3a9c0b59..53d31b13809a 100644 --- a/tests/bluetooth/classic/rfcomm_s/pytest/conftest.py +++ b/tests/bluetooth/classic/rfcomm_s/pytest/conftest.py @@ -1,6 +1,7 @@ # Copyright 2025 NXP # # SPDX-License-Identifier: Apache-2.0 +# pylint: disable=duplicate-code import logging import re @@ -31,7 +32,7 @@ def fixture_initialize(request, shell: Shell, dut: DeviceAdapter): assert hci is not None shell.exec_command("bt init") - lines = dut.readlines_until("Bluetooth initialized") + lines = dut.readlines_until(regex="Bluetooth initialized") regex = r'Identity: *(?P([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2}) *\((.*?)\))' bd_addr = None for line in lines: diff --git a/tests/bluetooth/classic/sdp_c/pytest/conftest.py b/tests/bluetooth/classic/sdp_c/pytest/conftest.py index aae74a19cfe5..91c12db2eaf1 100644 --- a/tests/bluetooth/classic/sdp_c/pytest/conftest.py +++ b/tests/bluetooth/classic/sdp_c/pytest/conftest.py @@ -1,6 +1,7 @@ # Copyright 2024 NXP # # SPDX-License-Identifier: Apache-2.0 +# pylint: disable=duplicate-code import logging import re @@ -31,7 +32,7 @@ def fixture_initialize(request, shell: Shell, dut: DeviceAdapter): assert hci is not None lines = shell.exec_command("bt init") - lines = dut.readlines_until("Bluetooth initialized") + lines = dut.readlines_until(regex="Bluetooth initialized") regex = r'Identity: *(?P(.*?):(.*?):(.*?):(.*?):(.*?):(.*?)*\((.*?)\))' bd_addr = None for line in lines: diff --git a/tests/bluetooth/classic/sdp_s/pytest/conftest.py b/tests/bluetooth/classic/sdp_s/pytest/conftest.py index 6b15e12ed346..a6c63a8e6325 100644 --- a/tests/bluetooth/classic/sdp_s/pytest/conftest.py +++ b/tests/bluetooth/classic/sdp_s/pytest/conftest.py @@ -1,6 +1,7 @@ # Copyright 2024 NXP # # SPDX-License-Identifier: Apache-2.0 +# pylint: disable=duplicate-code import logging import re @@ -31,7 +32,7 @@ def fixture_initialize(request, shell: Shell, dut: DeviceAdapter): assert hci is not None lines = shell.exec_command("bt init") - lines = dut.readlines_until("Bluetooth initialized") + lines = dut.readlines_until(regex="Bluetooth initialized") regex = r'Identity: *(?P(.*?):(.*?):(.*?):(.*?):(.*?):(.*?)*\((.*?)\))' bd_addr = None for line in lines: diff --git a/tests/bluetooth/classic/smp_bonding/pytest/conftest.py b/tests/bluetooth/classic/smp_bonding/pytest/conftest.py index accfcf20a511..c6b16adbe248 100644 --- a/tests/bluetooth/classic/smp_bonding/pytest/conftest.py +++ b/tests/bluetooth/classic/smp_bonding/pytest/conftest.py @@ -1,6 +1,7 @@ # Copyright 2025 NXP # # SPDX-License-Identifier: Apache-2.0 +# pylint: disable=duplicate-code import logging import re @@ -31,7 +32,7 @@ def fixture_initialize(request, shell: Shell, dut: DeviceAdapter): assert hci is not None shell.exec_command("bt init") - lines = dut.readlines_until("Settings Loaded") + lines = dut.readlines_until(regex="Settings Loaded") regex = r'Identity: *(?P([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2}) *\((.*?)\))' bd_addr = None for line in lines: diff --git a/tests/bluetooth/classic/smp_general/pytest/conftest.py b/tests/bluetooth/classic/smp_general/pytest/conftest.py index 0ea9089ef6e2..f6d88f646743 100644 --- a/tests/bluetooth/classic/smp_general/pytest/conftest.py +++ b/tests/bluetooth/classic/smp_general/pytest/conftest.py @@ -1,11 +1,10 @@ # Copyright 2025 NXP # # SPDX-License-Identifier: Apache-2.0 +# pylint: disable=duplicate-code -import contextlib import logging import re -import time import pytest from twister_harness import DeviceAdapter, Shell @@ -33,7 +32,7 @@ def fixture_initialize(request, shell: Shell, dut: DeviceAdapter): assert hci is not None shell.exec_command("bt init") - dut.readlines_until("Settings Loaded") + dut.readlines_until(regex="Settings Loaded") regex = r'(?P([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2}) *\((.*?)\))' bd_addr = None lines = shell.exec_command("bt id-show") @@ -57,31 +56,3 @@ def smp_initiator_dut(initialize): logger.info('Start running testcase') yield initialize logger.info('Done') - - -def app_handle_device_output(self) -> None: - """ - This method is dedicated to run it in separate thread to read output - from device and put them into internal queue and save to log file. - """ - with open(self.handler_log_path, 'a+') as log_file: - while self.is_device_running(): - if self.is_device_connected(): - output = self._read_device_output().decode(errors='replace').rstrip("\r\n") - if output: - self._device_read_queue.put(output) - logger.debug(f'{output}\n') - try: - log_file.write(f'{output}\n') - except Exception: - contextlib.suppress(Exception) - log_file.flush() - else: - # ignore output from device - self._flush_device_output() - time.sleep(0.1) - - -# After reboot, there may be gbk character in the console, so replace _handle_device_output to -# handle the exception. -DeviceAdapter._handle_device_output = app_handle_device_output diff --git a/tests/bluetooth/classic/smp_io_cap/pytest/conftest.py b/tests/bluetooth/classic/smp_io_cap/pytest/conftest.py index ec8778af7949..6ec65617718c 100644 --- a/tests/bluetooth/classic/smp_io_cap/pytest/conftest.py +++ b/tests/bluetooth/classic/smp_io_cap/pytest/conftest.py @@ -1,6 +1,7 @@ # Copyright 2024 NXP # # SPDX-License-Identifier: Apache-2.0 +# pylint: disable=duplicate-code import logging import re @@ -31,7 +32,7 @@ def fixture_initialize(request, shell: Shell, dut: DeviceAdapter): assert hci is not None shell.exec_command("bt init") - lines = dut.readlines_until("Bluetooth initialized") + lines = dut.readlines_until(regex="Bluetooth initialized") regex = r'Identity: *(?P([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2}) *\((.*?)\))' bd_addr = None for line in lines: diff --git a/tests/bluetooth/classic/smp_key_persist/pytest/conftest.py b/tests/bluetooth/classic/smp_key_persist/pytest/conftest.py index d05efcd477dd..1c3d7eceb6ce 100644 --- a/tests/bluetooth/classic/smp_key_persist/pytest/conftest.py +++ b/tests/bluetooth/classic/smp_key_persist/pytest/conftest.py @@ -1,6 +1,7 @@ # Copyright 2024 NXP # # SPDX-License-Identifier: Apache-2.0 +# pylint: disable=duplicate-code import logging import re @@ -31,7 +32,7 @@ def fixture_initialize(request, shell: Shell, dut: DeviceAdapter): assert hci is not None lines = shell.exec_command("bt init") - lines = dut.readlines_until("Settings Loaded") + lines = dut.readlines_until(regex="Settings Loaded") regex = r'Identity: *(?P(.*?):(.*?):(.*?):(.*?):(.*?):(.*?) *\((.*?)\))' bd_addr = None for line in lines: diff --git a/tests/bluetooth/classic/smp_key_persist/pytest/test_smp.py b/tests/bluetooth/classic/smp_key_persist/pytest/test_smp.py index f9615c129ea8..e792471baad7 100644 --- a/tests/bluetooth/classic/smp_key_persist/pytest/test_smp.py +++ b/tests/bluetooth/classic/smp_key_persist/pytest/test_smp.py @@ -4,11 +4,9 @@ import asyncio -import contextlib import logging import re import sys -import time from bumble.core import ( BT_BR_EDR_TRANSPORT, @@ -32,34 +30,6 @@ logger = logging.getLogger(__name__) -def app_handle_device_output(self) -> None: - """ - This method is dedicated to run it in separate thread to read output - from device and put them into internal queue and save to log file. - """ - with open(self.handler_log_path, 'a+') as log_file: - while self.is_device_running(): - if self.is_device_connected(): - output = self._read_device_output().decode(errors='replace').rstrip("\r\n") - if output: - self._device_read_queue.put(output) - logger.debug(f'{output}\n') - try: - log_file.write(f'{output}\n') - except Exception: - contextlib.suppress(Exception) - log_file.flush() - else: - # ignore output from device - self._flush_device_output() - time.sleep(0.1) - - -# After reboot, there may be gbk character in the console, so replace _handle_device_output to -# handle the exception. -DeviceAdapter._handle_device_output = app_handle_device_output - - # power on dongle async def device_power_on(device) -> None: while True: diff --git a/tests/bluetooth/classic/smp_sc_only/pytest/conftest.py b/tests/bluetooth/classic/smp_sc_only/pytest/conftest.py index ec8778af7949..6ec65617718c 100644 --- a/tests/bluetooth/classic/smp_sc_only/pytest/conftest.py +++ b/tests/bluetooth/classic/smp_sc_only/pytest/conftest.py @@ -1,6 +1,7 @@ # Copyright 2024 NXP # # SPDX-License-Identifier: Apache-2.0 +# pylint: disable=duplicate-code import logging import re @@ -31,7 +32,7 @@ def fixture_initialize(request, shell: Shell, dut: DeviceAdapter): assert hci is not None shell.exec_command("bt init") - lines = dut.readlines_until("Bluetooth initialized") + lines = dut.readlines_until(regex="Bluetooth initialized") regex = r'Identity: *(?P([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2}) *\((.*?)\))' bd_addr = None for line in lines: diff --git a/tests/boot/with_mcumgr/pytest/test_downgrade_prevention.py b/tests/boot/with_mcumgr/pytest/test_downgrade_prevention.py index eb5ebc1c78d0..59e461aeea6c 100755 --- a/tests/boot/with_mcumgr/pytest/test_downgrade_prevention.py +++ b/tests/boot/with_mcumgr/pytest/test_downgrade_prevention.py @@ -48,7 +48,7 @@ def test_downgrade_prevention(dut: DeviceAdapter, shell: Shell, mcumgr: MCUmgr): mcumgr.reset_device() dut.connect() - output = dut.readlines_until(WELCOME_STRING) + output = dut.readlines_until(regex=WELCOME_STRING) match_no_lines(output, ['Starting swap using move algorithm']) match_lines(output, ['erased due to downgrade prevention']) logger.info('Verify that the original APP is booted') diff --git a/tests/boot/with_mcumgr/pytest/test_upgrade.py b/tests/boot/with_mcumgr/pytest/test_upgrade.py index 9d88da445edb..349eee6fd782 100755 --- a/tests/boot/with_mcumgr/pytest/test_upgrade.py +++ b/tests/boot/with_mcumgr/pytest/test_upgrade.py @@ -80,7 +80,7 @@ def run_upgrade_with_confirm(dut: DeviceAdapter, shell: Shell, mcumgr: MCUmgr): mcumgr.reset_device() dut.connect() - output = dut.readlines_until(WELCOME_STRING) + output = dut.readlines_until(regex=WELCOME_STRING) upgrade_string_to_verify = get_upgrade_string_to_verify(dut.device_config.build_dir) match_lines(output, [ 'Swap type: test', @@ -96,7 +96,7 @@ def run_upgrade_with_confirm(dut: DeviceAdapter, shell: Shell, mcumgr: MCUmgr): mcumgr.reset_device() dut.connect() - output = dut.readlines_until(WELCOME_STRING) + output = dut.readlines_until(regex=WELCOME_STRING) match_no_lines(output, [ upgrade_string_to_verify ]) @@ -141,7 +141,7 @@ def test_upgrade_with_revert(dut: DeviceAdapter, shell: Shell, mcumgr: MCUmgr): mcumgr.reset_device() dut.connect() - output = dut.readlines_until(WELCOME_STRING) + output = dut.readlines_until(regex=WELCOME_STRING) upgrade_string_to_verify = get_upgrade_string_to_verify(dut.device_config.build_dir) match_lines(output, [ 'Swap type: test', @@ -156,7 +156,7 @@ def test_upgrade_with_revert(dut: DeviceAdapter, shell: Shell, mcumgr: MCUmgr): mcumgr.reset_device() dut.connect() - output = dut.readlines_until(WELCOME_STRING) + output = dut.readlines_until(regex=WELCOME_STRING) match_lines(output, [ 'Swap type: revert', upgrade_string_to_verify @@ -216,7 +216,7 @@ def test_upgrade_signature(dut: DeviceAdapter, shell: Shell, mcumgr: MCUmgr, key mcumgr.reset_device() dut.connect() - output = dut.readlines_until(WELCOME_STRING) + output = dut.readlines_until(regex=WELCOME_STRING) upgrade_string_to_verify = get_upgrade_string_to_verify(dut.device_config.build_dir) match_no_lines(output, [upgrade_string_to_verify]) match_lines(output, ['Image in the secondary slot is not valid']) diff --git a/tests/misc/llext-edk/pytest/test_edk.py b/tests/misc/llext-edk/pytest/test_edk.py index 9c5159373f30..57f2beb7820f 100644 --- a/tests/misc/llext-edk/pytest/test_edk.py +++ b/tests/misc/llext-edk/pytest/test_edk.py @@ -109,7 +109,7 @@ def test_edk(unlaunched_dut: DeviceAdapter): logger.debug(f"Running application with extension in {tempdir_extension}") try: unlaunched_dut.launch() - lines = unlaunched_dut.readlines_until("Done") + lines = unlaunched_dut.readlines_until(regex="Done") assert "Calling extension from kernel" in lines assert "Calling extension from user" in lines diff --git a/tests/net/socket/tls_configurations/pytest/test_app_vs_openssl.py b/tests/net/socket/tls_configurations/pytest/test_app_vs_openssl.py index f01d3a9c8bf9..5b0c66f1c434 100755 --- a/tests/net/socket/tls_configurations/pytest/test_app_vs_openssl.py +++ b/tests/net/socket/tls_configurations/pytest/test_app_vs_openssl.py @@ -1,6 +1,7 @@ # Copyright (c) 2024 Nordic Semiconductor ASA # # SPDX-License-Identifier: Apache-2.0 +# pylint: disable=duplicate-code import logging import os @@ -78,4 +79,4 @@ def openssl_server(server_type, port): def test_app_vs_openssl(dut: DeviceAdapter, openssl_server): logger.info("Launch Zephyr application") dut.launch() - dut.readlines_until("Test PASSED", timeout=3.0) + dut.readlines_until(regex="Test PASSED", timeout=3.0) From 58cf208b8fbb02714d3b13f4fae2cac27b3edbb7 Mon Sep 17 00:00:00 2001 From: Tahsin Mutlugun Date: Mon, 8 Dec 2025 16:41:14 +0300 Subject: [PATCH 0766/3659] drivers: timer: cortex_m_systick: Restore SysTick config after reset Restore the clock source and exception bits in the CTRL register after waking from low-power modes that reset SysTick. Also reconfigure the interrupt priority. Signed-off-by: Tahsin Mutlugun --- drivers/timer/cortex_m_systick.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/timer/cortex_m_systick.c b/drivers/timer/cortex_m_systick.c index 1c1a9a27dbcb..bf30bc868a15 100644 --- a/drivers/timer/cortex_m_systick.c +++ b/drivers/timer/cortex_m_systick.c @@ -556,7 +556,14 @@ void sys_clock_idle_exit(void) last_load = CYC_PER_TICK; SysTick->LOAD = last_load - 1; SysTick->VAL = 0; /* resets timer to last_load */ - SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; + if (!IS_ENABLED(CONFIG_CORTEX_M_SYSTICK_RESET_BY_LPM)) { + SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; + } else { + NVIC_SetPriority(SysTick_IRQn, _IRQ_PRIO_OFFSET); + SysTick->CTRL |= (SysTick_CTRL_ENABLE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_CLKSOURCE_Msk); + } } } } From 014ccd3c40e8b989ae7aadd2dacf086d281b4ea7 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Wed, 3 Dec 2025 07:38:18 +0000 Subject: [PATCH 0767/3659] boards: nordic: Add default Kconfig for (Q)SPI NOR page size Changes the default page size to 4096 (4KiB) for SPI/QSPI NOR flash devices if MCUboot is enabled to allow for swap updates to work by default Signed-off-by: Jamie McCrae --- boards/nordic/nrf52840dk/Kconfig.defconfig | 7 +++++++ boards/nordic/nrf5340dk/Kconfig.defconfig | 7 +++++++ boards/nordic/nrf54l15dk/Kconfig.defconfig | 7 +++++++ boards/nordic/nrf7002dk/Kconfig.defconfig | 7 +++++++ boards/nordic/nrf9160dk/Kconfig.defconfig | 7 +++++++ boards/nordic/thingy53/Kconfig.defconfig | 7 +++++++ 6 files changed, 42 insertions(+) diff --git a/boards/nordic/nrf52840dk/Kconfig.defconfig b/boards/nordic/nrf52840dk/Kconfig.defconfig index 96aa4159c27e..f7f8c8e47090 100644 --- a/boards/nordic/nrf52840dk/Kconfig.defconfig +++ b/boards/nordic/nrf52840dk/Kconfig.defconfig @@ -8,4 +8,11 @@ if BOARD_NRF52840DK config HW_STACK_PROTECTION default ARCH_HAS_STACK_PROTECTION +if NORDIC_QSPI_NOR + +config NORDIC_QSPI_NOR_FLASH_LAYOUT_PAGE_SIZE + default 4096 if MCUBOOT || BOOTLOADER_MCUBOOT + +endif # NORDIC_QSPI_NOR + endif # BOARD_NRF52840DK diff --git a/boards/nordic/nrf5340dk/Kconfig.defconfig b/boards/nordic/nrf5340dk/Kconfig.defconfig index 497113310bfa..7cfbc6731930 100644 --- a/boards/nordic/nrf5340dk/Kconfig.defconfig +++ b/boards/nordic/nrf5340dk/Kconfig.defconfig @@ -6,6 +6,13 @@ config HW_STACK_PROTECTION default ARCH_HAS_STACK_PROTECTION +if NORDIC_QSPI_NOR + +config NORDIC_QSPI_NOR_FLASH_LAYOUT_PAGE_SIZE + default 4096 if MCUBOOT || BOOTLOADER_MCUBOOT + +endif # NORDIC_QSPI_NOR + if BOARD_NRF5340DK_NRF5340_CPUAPP || BOARD_NRF5340DK_NRF5340_CPUAPP_NS # Code Partition: diff --git a/boards/nordic/nrf54l15dk/Kconfig.defconfig b/boards/nordic/nrf54l15dk/Kconfig.defconfig index f57b30c2c42d..70bbff4b47f8 100644 --- a/boards/nordic/nrf54l15dk/Kconfig.defconfig +++ b/boards/nordic/nrf54l15dk/Kconfig.defconfig @@ -4,6 +4,13 @@ config HW_STACK_PROTECTION default ARCH_HAS_STACK_PROTECTION +if SPI_NOR + +config SPI_NOR_FLASH_LAYOUT_PAGE_SIZE + default 4096 if MCUBOOT || BOOTLOADER_MCUBOOT + +endif # SPI_NOR + if BOARD_NRF54L15DK_NRF54L15_CPUAPP_NS || BOARD_NRF54L15DK_NRF54L10_CPUAPP_NS config BOARD_NRF54L15DK diff --git a/boards/nordic/nrf7002dk/Kconfig.defconfig b/boards/nordic/nrf7002dk/Kconfig.defconfig index 48510d6e24f8..a6cf1d7fbca1 100644 --- a/boards/nordic/nrf7002dk/Kconfig.defconfig +++ b/boards/nordic/nrf7002dk/Kconfig.defconfig @@ -8,4 +8,11 @@ if BOARD_NRF7002DK config HW_STACK_PROTECTION default ARCH_HAS_STACK_PROTECTION +if SPI_NOR + +config SPI_NOR_FLASH_LAYOUT_PAGE_SIZE + default 4096 if MCUBOOT || BOOTLOADER_MCUBOOT + +endif # SPI_NOR + endif # BOARD_NRF7002DK diff --git a/boards/nordic/nrf9160dk/Kconfig.defconfig b/boards/nordic/nrf9160dk/Kconfig.defconfig index f27b36a40d16..8dba84f88ad3 100644 --- a/boards/nordic/nrf9160dk/Kconfig.defconfig +++ b/boards/nordic/nrf9160dk/Kconfig.defconfig @@ -20,6 +20,13 @@ config BT_WAIT_NOP config I2C default $(dt_compat_on_bus,$(DT_COMPAT_NXP_PCAL6408A),i2c) +if SPI_NOR && BOARD_REVISION = "0.14.0" + +config SPI_NOR_FLASH_LAYOUT_PAGE_SIZE + default 4096 if MCUBOOT || BOOTLOADER_MCUBOOT + +endif # SPI_NOR && BOARD_REVISION = "0.14.0" + endif # BOARD_NRF9160DK_NRF9160 || BOARD_NRF9160DK_NRF9160_NS if BOARD_NRF9160DK_NRF52840 diff --git a/boards/nordic/thingy53/Kconfig.defconfig b/boards/nordic/thingy53/Kconfig.defconfig index c1139f0dca10..c5b54f30cb79 100644 --- a/boards/nordic/thingy53/Kconfig.defconfig +++ b/boards/nordic/thingy53/Kconfig.defconfig @@ -6,6 +6,13 @@ config HW_STACK_PROTECTION default ARCH_HAS_STACK_PROTECTION +if NORDIC_QSPI_NOR + +config NORDIC_QSPI_NOR_FLASH_LAYOUT_PAGE_SIZE + default 4096 if MCUBOOT || BOOTLOADER_MCUBOOT + +endif # NORDIC_QSPI_NOR + if BOARD_THINGY53_NRF5340_CPUAPP || BOARD_THINGY53_NRF5340_CPUAPP_NS # Code Partition: From 64459fbb5008efb2a4552b53059809f3f3bcc2ab Mon Sep 17 00:00:00 2001 From: Seppo Takalo Date: Mon, 22 Dec 2025 10:53:47 +0200 Subject: [PATCH 0768/3659] modem: cmux: Drop invalid response frames Drop invalid response frames when in connected state. Signed-off-by: Seppo Takalo --- subsys/modem/modem_cmux.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/subsys/modem/modem_cmux.c b/subsys/modem/modem_cmux.c index 5ba3f0cbd83d..b01d84ddbed4 100644 --- a/subsys/modem/modem_cmux.c +++ b/subsys/modem/modem_cmux.c @@ -1024,7 +1024,8 @@ static void modem_cmux_on_control_frame(struct modem_cmux *cmux) modem_cmux_log_received_frame(&cmux->frame); if (is_connected(cmux) && cmux->frame.cr == cmux->initiator) { - LOG_DBG("Received a response frame"); + LOG_DBG("Drop a response frame"); + return; } switch (cmux->frame.type) { From f833ff533d20cc6e2b216b991bed08f7674d424c Mon Sep 17 00:00:00 2001 From: Seppo Takalo Date: Wed, 17 Dec 2025 10:15:52 +0200 Subject: [PATCH 0769/3659] modem: cmux: Add retry counter for SABM, CLD and DISC control messages Add retry counter for opening and closing CMUX as well as opening and closing the DLCI channel. Use same retry counter for both DLCI control messages as well as CMUX control messages as there is very minimal room for race condition. DLCI messages are only send when CMUX control channel is open. Where relevant, use disconnect(cmux) for all closing calls. So we have one entry point for cleaning. Similarly refactor modem_cmux_on_dlci_frame_dm() to dlci_close() as this is the single function to close and clean up a channel. Signed-off-by: Seppo Takalo --- include/zephyr/modem/cmux.h | 1 + subsys/modem/modem_cmux.c | 82 +++++++++++++++++++++++++++++++------ 2 files changed, 71 insertions(+), 12 deletions(-) diff --git a/include/zephyr/modem/cmux.h b/include/zephyr/modem/cmux.h index 0faa8d5d4b38..6589f37691c6 100644 --- a/include/zephyr/modem/cmux.h +++ b/include/zephyr/modem/cmux.h @@ -177,6 +177,7 @@ struct modem_cmux { /* State */ enum modem_cmux_state state; + uint8_t retry_count; bool flow_control_on : 1; bool initiator : 1; diff --git a/subsys/modem/modem_cmux.c b/subsys/modem/modem_cmux.c index b01d84ddbed4..ae13d3be2a14 100644 --- a/subsys/modem/modem_cmux.c +++ b/subsys/modem/modem_cmux.c @@ -40,6 +40,7 @@ LOG_MODULE_REGISTER(modem_cmux, CONFIG_MODEM_CMUX_LOG_LEVEL); #define MODEM_CMUX_T1_TIMEOUT (K_MSEC(330)) #define MODEM_CMUX_T2_TIMEOUT (K_MSEC(660)) #define MODEM_CMUX_T3_TIMEOUT (K_SECONDS(CONFIG_MODEM_CMUX_T3_TIMEOUT)) +#define MODEM_CMUX_N2_RETRIES 3 enum modem_cmux_frame_types { MODEM_CMUX_FRAME_TYPE_RR = 0x01, @@ -798,6 +799,7 @@ static void disconnect(struct modem_cmux *cmux) { LOG_DBG("CMUX disconnected"); k_work_cancel_delayable(&cmux->disconnect_work); + k_work_cancel_delayable(&cmux->connect_work); set_state(cmux, MODEM_CMUX_STATE_DISCONNECTED); k_mutex_lock(&cmux->transmit_rb_lock, K_FOREVER); cmux->flow_control_on = false; @@ -821,6 +823,10 @@ static void modem_cmux_on_cld_command(struct modem_cmux *cmux, struct modem_cmux disconnect(cmux); } else { set_state(cmux, MODEM_CMUX_STATE_DISCONNECTING); + /* We did not initiate the disconnect, so don't retry, just wait for our + * response to be sent&handled, then close our side. + */ + cmux->retry_count = MODEM_CMUX_N2_RETRIES; k_work_schedule(&cmux->disconnect_work, MODEM_CMUX_T1_TIMEOUT); } } @@ -1063,11 +1069,17 @@ static struct modem_cmux_dlci *modem_cmux_find_dlci(struct modem_cmux *cmux, uin return NULL; } -static void modem_cmux_on_dlci_frame_dm(struct modem_cmux_dlci *dlci) +static void dlci_close(struct modem_cmux_dlci *dlci) { dlci->state = MODEM_CMUX_DLCI_STATE_CLOSED; modem_pipe_notify_closed(&dlci->pipe); k_work_cancel_delayable(&dlci->close_work); + k_work_cancel_delayable(&dlci->open_work); +} + +static void modem_cmux_on_dlci_frame_dm(struct modem_cmux_dlci *dlci) +{ + return dlci_close(dlci); } static void modem_cmux_on_dlci_frame_ua(struct modem_cmux_dlci *dlci) @@ -1097,7 +1109,7 @@ static void modem_cmux_on_dlci_frame_ua(struct modem_cmux_dlci *dlci) case MODEM_CMUX_DLCI_STATE_CLOSING: LOG_DBG("DLCI %u closed", dlci->dlci_address); - modem_cmux_on_dlci_frame_dm(dlci); + dlci_close(dlci); break; default: @@ -1564,8 +1576,7 @@ static bool powersave_wait_wakeup(struct modem_cmux *cmux) if (is_waking_up(cmux)) { if (sys_timepoint_expired(cmux->t3_timepoint)) { LOG_ERR("Wake up timed out, link dead"); - set_state(cmux, MODEM_CMUX_STATE_DISCONNECTED); - modem_cmux_raise_event(cmux, MODEM_CMUX_EVENT_DISCONNECTED); + disconnect(cmux); return true; } if (cmux->receive_state != MODEM_CMUX_RECEIVE_STATE_RESYNC) { @@ -1656,8 +1667,18 @@ static void modem_cmux_connect_handler(struct k_work *item) dwork = k_work_delayable_from_work(item); cmux = CONTAINER_OF(dwork, struct modem_cmux, connect_work); - set_state(cmux, MODEM_CMUX_STATE_CONNECTING); - cmux->initiator = true; + if (cmux->state == MODEM_CMUX_STATE_CONNECTING) { + cmux->retry_count++; + if (cmux->retry_count > MODEM_CMUX_N2_RETRIES) { + LOG_ERR("CMUX connection failed after %u retries", MODEM_CMUX_N2_RETRIES); + disconnect(cmux); + return; + } + } else { + set_state(cmux, MODEM_CMUX_STATE_CONNECTING); + cmux->initiator = true; + cmux->retry_count = 0; + } static const struct modem_cmux_frame frame = { .dlci_address = 0, @@ -1678,10 +1699,20 @@ static void modem_cmux_disconnect_handler(struct k_work *item) struct modem_cmux *cmux = CONTAINER_OF(dwork, struct modem_cmux, disconnect_work); if (cmux->state == MODEM_CMUX_STATE_DISCONNECTING) { - disconnect(cmux); - } else { + cmux->retry_count++; + if (cmux->retry_count > MODEM_CMUX_N2_RETRIES) { + /* NOTE: We end up here also after responding to CLD, so this is not always + * an error, so don't LOG_ERR + */ + disconnect(cmux); + return; + } + } else if (cmux->state != MODEM_CMUX_STATE_DISCONNECTED) { set_state(cmux, MODEM_CMUX_STATE_DISCONNECTING); - k_work_schedule(&cmux->disconnect_work, MODEM_CMUX_T1_TIMEOUT); + cmux->retry_count = 0; + } else { + /* Already disconnected */ + return; } struct modem_cmux_command command = { @@ -1863,6 +1894,7 @@ static void modem_cmux_dlci_open_handler(struct k_work *item) { struct k_work_delayable *dwork; struct modem_cmux_dlci *dlci; + struct modem_cmux *cmux; if (item == NULL) { return; @@ -1870,9 +1902,21 @@ static void modem_cmux_dlci_open_handler(struct k_work *item) dwork = k_work_delayable_from_work(item); dlci = CONTAINER_OF(dwork, struct modem_cmux_dlci, open_work); + cmux = dlci->cmux; - dlci->state = MODEM_CMUX_DLCI_STATE_OPENING; - dlci->msc_sent = false; + if (dlci->state == MODEM_CMUX_DLCI_STATE_OPENING) { + dlci->cmux->retry_count++; + if (dlci->cmux->retry_count > MODEM_CMUX_N2_RETRIES) { + LOG_ERR("DLCI %u open failed after %u retries", dlci->dlci_address, + MODEM_CMUX_N2_RETRIES); + dlci_close(dlci); + return; + } + } else { + dlci->state = MODEM_CMUX_DLCI_STATE_OPENING; + dlci->msc_sent = false; + cmux->retry_count = 0; + } struct modem_cmux_frame frame = { .dlci_address = dlci->dlci_address, @@ -1902,7 +1946,21 @@ static void modem_cmux_dlci_close_handler(struct k_work *item) dlci = CONTAINER_OF(dwork, struct modem_cmux_dlci, close_work); cmux = dlci->cmux; - dlci->state = MODEM_CMUX_DLCI_STATE_CLOSING; + if (dlci->state == MODEM_CMUX_DLCI_STATE_CLOSING) { + cmux->retry_count++; + if (cmux->retry_count > MODEM_CMUX_N2_RETRIES) { + LOG_ERR("DLCI %u close failed after %u retries", dlci->dlci_address, + MODEM_CMUX_N2_RETRIES); + dlci_close(dlci); + return; + } + } else if (dlci->state == MODEM_CMUX_DLCI_STATE_OPEN) { + dlci->state = MODEM_CMUX_DLCI_STATE_CLOSING; + cmux->retry_count = 0; + } else { + /* DLCI already closed */ + return; + } struct modem_cmux_frame frame = { .dlci_address = dlci->dlci_address, From 7774970cccbb6cbd0f468ef7be4dd5cbdaa119c3 Mon Sep 17 00:00:00 2001 From: Qingsong Gou Date: Mon, 20 Oct 2025 13:53:31 +0800 Subject: [PATCH 0770/3659] drivers: i2c: sf32lb: add i2c interrupt-driven support for sf32lb Add i2c interrupt-driven support for sf32lb platform Signed-off-by: Qingsong Gou --- drivers/i2c/i2c_sf32lb.c | 207 +++++++++++++++++++++++++++++++++------ 1 file changed, 176 insertions(+), 31 deletions(-) diff --git a/drivers/i2c/i2c_sf32lb.c b/drivers/i2c/i2c_sf32lb.c index 402718bf8c63..aeba015ad4ba 100644 --- a/drivers/i2c/i2c_sf32lb.c +++ b/drivers/i2c/i2c_sf32lb.c @@ -46,13 +46,122 @@ struct i2c_sf32lb_config { const struct pinctrl_dev_config *pincfg; struct sf32lb_clock_dt_spec clock; uint32_t bitrate; + void (*irq_cfg_func)(void); }; struct i2c_sf32lb_data { struct k_mutex lock; uint8_t rw_flags; + struct k_sem i2c_compl; + struct i2c_msg *current_msg; + uint8_t *buf_ptr; + uint32_t remaining; + bool is_tx; + int error; }; +static void i2c_sf32lb_tx_helper(const struct device *dev, uint32_t sr) +{ + const struct i2c_sf32lb_config *config = dev->config; + struct i2c_sf32lb_data *data = dev->data; + uint32_t tcr; + + if (IS_BIT_SET(sr, I2C_SR_TE_Pos)) { + sys_set_bit(config->base + I2C_SR, I2C_SR_TE_Pos); + if (IS_BIT_SET(sr, I2C_SR_NACK_Pos)) { + data->error = -EIO; + sys_write32(0, config->base + I2C_IER); + data->current_msg = NULL; + k_sem_give(&data->i2c_compl); + return; + } + + if (data->remaining > 0) { + sys_write8(*data->buf_ptr, config->base + I2C_DBR); + data->buf_ptr++; + data->remaining--; + + tcr = I2C_TCR_TB; + if (data->remaining == 0 && i2c_is_stop_op(data->current_msg)) { + tcr |= I2C_TCR_STOP; + } + sys_write32(tcr, config->base + I2C_TCR); + } else { + sys_write32(0, config->base + I2C_IER); + data->current_msg = NULL; + k_sem_give(&data->i2c_compl); + } + } + + if (IS_BIT_SET(sr, I2C_SR_MSD_Pos) && (data->remaining == 0)) { + sys_set_bit(config->base + I2C_SR, I2C_SR_MSD_Pos); + sys_write32(0, config->base + I2C_IER); + data->current_msg = NULL; + k_sem_give(&data->i2c_compl); + } +} + +static void i2c_sf32lb_rx_helper(const struct device *dev, uint32_t sr) +{ + const struct i2c_sf32lb_config *config = dev->config; + struct i2c_sf32lb_data *data = dev->data; + uint32_t tcr; + + if (IS_BIT_SET(sr, I2C_SR_RF_Pos)) { + sys_set_bit(config->base + I2C_SR, I2C_SR_RF_Pos); + + if (data->remaining > 0) { + if (IS_BIT_SET(sr, I2C_SR_NACK_Pos)) { + data->error = -EIO; + data->current_msg = NULL; + k_sem_give(&data->i2c_compl); + return; + } + *data->buf_ptr = sys_read8(config->base + I2C_DBR); + data->buf_ptr++; + data->remaining--; + + tcr = I2C_TCR_TB; + if (data->remaining == 0) { + if (i2c_is_stop_op(data->current_msg)) { + tcr |= I2C_TCR_STOP; + } + tcr |= I2C_TCR_NACK; + } + sys_write32(tcr, config->base + I2C_TCR); + } + } + + if (IS_BIT_SET(sr, I2C_SR_MSD_Pos) && (data->remaining == 0)) { + sys_set_bit(config->base + I2C_SR, I2C_SR_MSD_Pos); + sys_write32(0, config->base + I2C_IER); + data->current_msg = NULL; + k_sem_give(&data->i2c_compl); + } +} + +static void i2c_sf32lb_isr(const struct device *dev) +{ + const struct i2c_sf32lb_config *config = dev->config; + struct i2c_sf32lb_data *data = dev->data; + uint32_t sr = sys_read32(config->base + I2C_SR); + + if (IS_BIT_SET(sr, I2C_SR_BED_Pos)) { + sys_set_bit(config->base + I2C_SR, I2C_SR_BED_Pos); + data->error = -EIO; + sys_write32(0, config->base + I2C_IER); + data->current_msg = NULL; + k_sem_give(&data->i2c_compl); + return; + } + + if (data->is_tx) { + i2c_sf32lb_tx_helper(dev, sr); + } else { + i2c_sf32lb_rx_helper(dev, sr); + } +} + static int i2c_sf32lb_send_addr(const struct device *dev, uint16_t addr, struct i2c_msg *msg) { int ret = 0; @@ -117,31 +226,43 @@ static int i2c_sf32lb_master_send(const struct device *dev, uint16_t addr, struc } } - for (uint32_t j = 0U; j < msg->len; j++) { - bool last = ((msg->len - j) == 1U) ? true : false; + if (msg->len == 0) { + /* Zero-length message already handled in send_addr */ + return ret; + } - if (last && stop_needed) { - tcr |= I2C_TCR_STOP; - } + data->current_msg = msg; + data->buf_ptr = msg->buf; + data->remaining = msg->len; + data->is_tx = true; + data->error = 0; - sys_write8(msg->buf[j], cfg->base + I2C_DBR); + sys_set_bit(cfg->base + I2C_SR, I2C_SR_TE_Pos); - sys_write32(tcr, cfg->base + I2C_TCR); + sys_write8(*data->buf_ptr, cfg->base + I2C_DBR); + data->buf_ptr++; + data->remaining--; - while (!sys_test_bit(cfg->base + I2C_SR, I2C_SR_TE_Pos)) { - } + if (data->remaining == 0 && stop_needed) { + tcr |= I2C_TCR_STOP; + } + sys_write32(tcr, cfg->base + I2C_TCR); - sys_set_bit(cfg->base + I2C_SR, I2C_SR_TE_Pos); + sys_set_bit(cfg->base + I2C_IER, I2C_IER_TEIE_Pos); + sys_set_bit(cfg->base + I2C_IER, I2C_IER_MSDIE_Pos); + sys_set_bit(cfg->base + I2C_IER, I2C_IER_BEDIE_Pos); - if (sys_test_bit(cfg->base + I2C_SR, I2C_SR_NACK_Pos)) { - ret = -EIO; - break; - } + if (k_sem_take(&data->i2c_compl, K_MSEC(SF32LB_I2C_TIMEOUT_MAX_US / 1000)) != 0) { + LOG_ERR("master sent timeout"); + sys_write32(0, cfg->base + I2C_IER); + data->current_msg = NULL; + return -ETIMEDOUT; } - if (stop_needed) { - while (sys_test_bit(cfg->base + I2C_SR, I2C_SR_UB_Pos)) { - } + sys_write32(0, cfg->base + I2C_IER); + + if (data->error != 0) { + ret = data->error; } return ret; @@ -149,7 +270,7 @@ static int i2c_sf32lb_master_send(const struct device *dev, uint16_t addr, struc static int i2c_sf32lb_master_recv(const struct device *dev, uint16_t addr, struct i2c_msg *msg) { - int ret = 0; + int ret; const struct i2c_sf32lb_config *cfg = dev->config; struct i2c_sf32lb_data *data = dev->data; uint32_t tcr = I2C_TCR_TB; @@ -162,26 +283,40 @@ static int i2c_sf32lb_master_recv(const struct device *dev, uint16_t addr, struc return ret; } - for (uint32_t j = 0U; j < msg->len; j++) { - bool last = (j == (msg->len - 1U)) ? true : false; + if (msg->len == 0) { + return ret; + } - if (last && stop_needed) { - tcr |= (I2C_TCR_STOP | I2C_TCR_NACK); - } + data->current_msg = msg; + data->buf_ptr = msg->buf; + data->remaining = msg->len; + data->is_tx = false; + data->error = 0; - sys_write32(tcr, cfg->base + I2C_TCR); + sys_set_bit(cfg->base + I2C_SR, I2C_SR_RF_Pos); - while (!sys_test_bit(cfg->base + I2C_SR, I2C_SR_RF_Pos)) { + if (data->remaining == 1) { + if (stop_needed) { + tcr |= I2C_TCR_STOP; } + tcr |= I2C_TCR_NACK; + } + sys_write32(tcr, cfg->base + I2C_TCR); - sys_set_bit(cfg->base + I2C_SR, I2C_SR_RF_Pos); + sys_set_bit(cfg->base + I2C_CR, I2C_CR_MSDE_Pos); + sys_set_bits(cfg->base + I2C_IER, I2C_IER_RFIE | I2C_IER_MSDIE | I2C_IER_BEDIE); - msg->buf[j] = sys_read8(cfg->base + I2C_DBR); + if (k_sem_take(&data->i2c_compl, K_MSEC(SF32LB_I2C_TIMEOUT_MAX_US / 1000)) != 0) { + LOG_ERR("master recv timeout"); + sys_write32(0, cfg->base + I2C_IER); + data->current_msg = NULL; + return -ETIMEDOUT; } - if (stop_needed) { - while (sys_test_bit(cfg->base + I2C_SR, I2C_SR_UB_Pos)) { - } + sys_write32(0, cfg->base + I2C_IER); + + if (data->error != 0) { + ret = data->error; } return ret; @@ -354,21 +489,31 @@ static int i2c_sf32lb_init(const struct device *dev) data->rw_flags = I2C_MSG_READ; + config->irq_cfg_func(); + return ret; } #define I2C_SF32LB_DEFINE(n) \ PINCTRL_DT_INST_DEFINE(n); \ + static void i2c_sf32lb_irq_config_func_##n(void) \ + { \ + IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority), i2c_sf32lb_isr, \ + DEVICE_DT_INST_GET(n), 0); \ + irq_enable(DT_INST_IRQN(n)); \ + }; \ static struct i2c_sf32lb_data i2c_sf32lb_data_##n = { \ .lock = Z_MUTEX_INITIALIZER(i2c_sf32lb_data_##n.lock), \ + .i2c_compl = Z_SEM_INITIALIZER(i2c_sf32lb_data_##n.i2c_compl, 0, 1), \ }; \ static const struct i2c_sf32lb_config i2c_sf32lb_config_##n = { \ .base = DT_INST_REG_ADDR(n), \ .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ .clock = SF32LB_CLOCK_DT_INST_SPEC_GET(n), \ .bitrate = DT_INST_PROP_OR(n, clock_frequency, 100000), \ + .irq_cfg_func = i2c_sf32lb_irq_config_func_##n, \ }; \ - DEVICE_DT_INST_DEFINE(n, &i2c_sf32lb_init, NULL, &i2c_sf32lb_data_##n, \ + DEVICE_DT_INST_DEFINE(n, i2c_sf32lb_init, NULL, &i2c_sf32lb_data_##n, \ &i2c_sf32lb_config_##n, POST_KERNEL, CONFIG_I2C_INIT_PRIORITY, \ &i2c_sf32lb_driver_api); From 07eec81f931722dd469e08dd93fa8b6f5c5576bf Mon Sep 17 00:00:00 2001 From: Seppo Takalo Date: Wed, 17 Dec 2025 12:08:36 +0200 Subject: [PATCH 0771/3659] modem: cmux: Change default timeouts to match 3GPP TS 27.010 3GPP TS 27.010 defines default timeouts as follows: * Acknowledgment Timer (T1), min 10ms, max 2.5s default 100ms * Response Timer for multiplexer control channel (T2), min 20ms, max 2.5s, default 300ms * Add Kconfig for both T1 and T2 timers The Response Timer for wake-up procedure(T3) is already a Kconfig and its default match the specification. Signed-off-by: Seppo Takalo --- subsys/modem/Kconfig | 21 ++++++++ subsys/modem/modem_cmux.c | 4 +- tests/subsys/modem/modem_cmux/src/main.c | 61 +++++++++++++----------- 3 files changed, 55 insertions(+), 31 deletions(-) diff --git a/subsys/modem/Kconfig b/subsys/modem/Kconfig index 3ebc6cfcc070..e68c33820e64 100644 --- a/subsys/modem/Kconfig +++ b/subsys/modem/Kconfig @@ -78,6 +78,27 @@ config MODEM_CMUX_MSC_FC_THRESHOLD This only works if the peer supports MSC messages. Disable flow control by setting this value to 0. +config MODEM_CMUX_T1_TIMEOUT + int "CMUX T1 timeout in milliseconds" + range 10 2550 + default 100 + help + Acknowledgment Timer (T1). + Time in milliseconds to wait for an acknowledgment before retransmitting + a frame. + +config MODEM_CMUX_T2_TIMEOUT + int "CMUX T2 timeout in milliseconds" + range 20 2550 + default 300 + help + Response Timer for multiplexer control channel (T2). + Time in milliseconds to wait for a response to a multiplexer control + command before considering the link dead. + NOTE: Zephyr's CMUX implementation deviates from the 3GPP TS 27.010 + specification by using T1 for all retry timers and T2 only for + a total response timeout. + config MODEM_CMUX_T3_TIMEOUT int "CMUX T3 timeout in seconds" range 1 255 diff --git a/subsys/modem/modem_cmux.c b/subsys/modem/modem_cmux.c index ae13d3be2a14..4a60bf189129 100644 --- a/subsys/modem/modem_cmux.c +++ b/subsys/modem/modem_cmux.c @@ -37,8 +37,8 @@ LOG_MODULE_REGISTER(modem_cmux, CONFIG_MODEM_CMUX_LOG_LEVEL); #define MODEM_CMUX_CMD_FRAME_SIZE_MAX (MODEM_CMUX_HEADER_SIZE + \ MODEM_CMUX_CMD_DATA_SIZE_MAX) -#define MODEM_CMUX_T1_TIMEOUT (K_MSEC(330)) -#define MODEM_CMUX_T2_TIMEOUT (K_MSEC(660)) +#define MODEM_CMUX_T1_TIMEOUT (K_MSEC(CONFIG_MODEM_CMUX_T1_TIMEOUT)) +#define MODEM_CMUX_T2_TIMEOUT (K_MSEC(CONFIG_MODEM_CMUX_T2_TIMEOUT)) #define MODEM_CMUX_T3_TIMEOUT (K_SECONDS(CONFIG_MODEM_CMUX_T3_TIMEOUT)) #define MODEM_CMUX_N2_RETRIES 3 diff --git a/tests/subsys/modem/modem_cmux/src/main.c b/tests/subsys/modem/modem_cmux/src/main.c index 27ebf92849f2..6518e046dee9 100644 --- a/tests/subsys/modem/modem_cmux/src/main.c +++ b/tests/subsys/modem/modem_cmux/src/main.c @@ -29,6 +29,7 @@ #define EVENT_CMUX_DISCONNECTED BIT(9) #define CMUX_BASIC_HRD_SMALL_SIZE 6 #define CMUX_BASIC_HRD_LARGE_SIZE 7 +#define TRANSMISSION_DELAY_MS 10 /*************************************************************************************************/ /* Instances */ @@ -357,6 +358,8 @@ static void test_modem_cmux_before(void *f) /* Reset mock pipes */ modem_backend_mock_reset(&bus_mock); + cmux.state = MODEM_CMUX_STATE_CONNECTED; + k_event_set(&cmux.event, BIT(cmux.state)); } ZTEST(modem_cmux, test_modem_cmux_receive_dlci2_at) @@ -370,7 +373,7 @@ ZTEST(modem_cmux, test_modem_cmux_receive_dlci2_at) modem_backend_mock_put(&bus_mock, cmux_frame_dlci2_at_newline, sizeof(cmux_frame_dlci2_at_newline)); - k_msleep(100); + k_msleep(TRANSMISSION_DELAY_MS); events = k_event_test(&cmux_event, EVENT_CMUX_DLCI2_RECEIVE_READY); zassert_equal(events, EVENT_CMUX_DLCI2_RECEIVE_READY, @@ -400,7 +403,7 @@ ZTEST(modem_cmux, test_modem_cmux_receive_dlci1_at) modem_backend_mock_put(&bus_mock, cmux_frame_dlci1_at_newline, sizeof(cmux_frame_dlci1_at_newline)); - k_msleep(100); + k_msleep(TRANSMISSION_DELAY_MS); events = k_event_test(&cmux_event, EVENT_CMUX_DLCI1_RECEIVE_READY); zassert_equal(events, EVENT_CMUX_DLCI1_RECEIVE_READY, @@ -432,7 +435,7 @@ ZTEST(modem_cmux, test_modem_cmux_receive_dlci2_ppp) modem_backend_mock_prime(&bus_mock, &transaction_dlci2_ppp_with_msc); modem_backend_mock_put(&bus_mock, cmux_frame_dlci2_ppp_52, sizeof(cmux_frame_dlci2_ppp_52)); modem_backend_mock_put(&bus_mock, cmux_frame_dlci2_ppp_18, sizeof(cmux_frame_dlci2_ppp_18)); - k_msleep(100); + k_msleep(TRANSMISSION_DELAY_MS); events = k_event_test(&cmux_event, EVENT_CMUX_DLCI2_RECEIVE_READY); zassert_equal(events, EVENT_CMUX_DLCI2_RECEIVE_READY, @@ -493,7 +496,7 @@ ZTEST(modem_cmux, test_modem_cmux_resync) modem_backend_mock_put(&bus_mock, cmux_frame_dlci1_at_newline, sizeof(cmux_frame_dlci1_at_newline)); - k_msleep(100); + k_msleep(TRANSMISSION_DELAY_MS); ret = modem_pipe_receive(dlci1_pipe, buffer1, sizeof(buffer1)); @@ -518,7 +521,7 @@ ZTEST(modem_cmux, test_modem_cmux_flow_control_dlci2) modem_backend_mock_put(&bus_mock, cmux_frame_control_fcoff_cmd, sizeof(cmux_frame_control_fcoff_cmd)); - k_msleep(100); + k_msleep(TRANSMISSION_DELAY_MS); ret = modem_backend_mock_get(&bus_mock, buffer1, sizeof(buffer1)); zassert_true(ret == sizeof(cmux_frame_control_fcoff_ack), @@ -538,7 +541,7 @@ ZTEST(modem_cmux, test_modem_cmux_flow_control_dlci2) modem_backend_mock_put(&bus_mock, cmux_frame_control_fcon_cmd, sizeof(cmux_frame_control_fcon_cmd)); - k_msleep(100); + k_msleep(TRANSMISSION_DELAY_MS); ret = modem_backend_mock_get(&bus_mock, buffer1, sizeof(buffer1)); zassert_true(ret == sizeof(cmux_frame_control_fcon_ack), @@ -554,7 +557,7 @@ ZTEST(modem_cmux, test_modem_cmux_flow_control_dlci2) zassert_true(ret == sizeof(cmux_frame_data_dlci2_ppp_52), "Transmit failed after flow control is enabled"); - k_msleep(100); + k_msleep(TRANSMISSION_DELAY_MS); ret = modem_backend_mock_get(&bus_mock, buffer1, sizeof(buffer1)); zassert_true(ret == sizeof(cmux_frame_dlci2_ppp_52), @@ -572,7 +575,7 @@ ZTEST(modem_cmux, test_modem_cmux_msc_cmd_ack) modem_backend_mock_put(&bus_mock, cmux_frame_control_msc_cmd, sizeof(cmux_frame_control_msc_cmd)); - k_msleep(100); + k_msleep(TRANSMISSION_DELAY_MS); ret = modem_backend_mock_get(&bus_mock, buffer1, sizeof(buffer1)); zassert_true(ret == sizeof(cmux_frame_control_msc_ack), @@ -591,7 +594,7 @@ ZTEST(modem_cmux, test_modem_cmux_dlci1_close_open) /* Close DLCI1 */ zassert_true(modem_pipe_close_async(dlci1_pipe) == 0, "Failed to close DLCI1 pipe"); - k_msleep(100); + k_msleep(TRANSMISSION_DELAY_MS); ret = modem_backend_mock_get(&bus_mock, buffer1, sizeof(buffer1)); zassert_true(ret == sizeof(cmux_frame_dlci1_disc_cmd), @@ -610,8 +613,8 @@ ZTEST(modem_cmux, test_modem_cmux_dlci1_close_open) zassert_true((events & EVENT_CMUX_DLCI1_CLOSED), "DLCI1 not closed as expected"); - /* Wait for potential T1 timeout */ - k_msleep(500); + /* Wait for potential T2 timeout */ + k_msleep(CONFIG_MODEM_CMUX_T2_TIMEOUT + TRANSMISSION_DELAY_MS); ret = modem_backend_mock_get(&bus_mock, buffer1, sizeof(buffer1)); zassert_true(ret == 0, "Received unexpected data"); @@ -619,7 +622,7 @@ ZTEST(modem_cmux, test_modem_cmux_dlci1_close_open) /* Open DLCI1 */ zassert_true(modem_pipe_open_async(dlci1_pipe) == 0, "Failed to open DLCI1 pipe"); - k_msleep(100); + k_msleep(TRANSMISSION_DELAY_MS); ret = modem_backend_mock_get(&bus_mock, buffer1, sizeof(buffer1)); zassert_true(ret == sizeof(cmux_frame_dlci1_sabm_cmd), @@ -670,7 +673,7 @@ ZTEST(modem_cmux, test_modem_cmux_disconnect_connect) modem_backend_mock_reset(&bus_mock); zassert_true(modem_cmux_disconnect_async(&cmux) == 0, "Failed to disconnect CMUX"); - k_msleep(100); + k_msleep(TRANSMISSION_DELAY_MS); ret = modem_backend_mock_get(&bus_mock, buffer1, sizeof(buffer1)); @@ -687,8 +690,8 @@ ZTEST(modem_cmux, test_modem_cmux_disconnect_connect) events = k_event_wait_all(&cmux_event, (EVENT_CMUX_DISCONNECTED), false, K_MSEC(100)); zassert_true((events & EVENT_CMUX_DISCONNECTED), "Failed to disconnect CMUX"); - /* Wait for potential T1 timeout */ - k_msleep(500); + /* Wait for potential T2 timeout */ + k_msleep(CONFIG_MODEM_CMUX_T2_TIMEOUT + TRANSMISSION_DELAY_MS); ret = modem_backend_mock_get(&bus_mock, buffer1, sizeof(buffer1)); zassert_true(ret == 0, "Received unexpected data"); @@ -696,7 +699,7 @@ ZTEST(modem_cmux, test_modem_cmux_disconnect_connect) /* Reconnect CMUX */ zassert_true(modem_cmux_connect_async(&cmux) == 0, "Failed to connect CMUX"); - k_msleep(100); + k_msleep(TRANSMISSION_DELAY_MS); ret = modem_backend_mock_get(&bus_mock, buffer1, sizeof(buffer1)); zassert_true(ret == sizeof(cmux_frame_control_sabm_cmd), @@ -712,8 +715,8 @@ ZTEST(modem_cmux, test_modem_cmux_disconnect_connect) events = k_event_wait_all(&cmux_event, (EVENT_CMUX_CONNECTED), false, K_MSEC(100)); zassert_true((events & EVENT_CMUX_CONNECTED), "Failed to connect CMUX"); - /* Wait for potential T1 timeout */ - k_msleep(500); + /* Wait for potential T2 timeout */ + k_msleep(CONFIG_MODEM_CMUX_T2_TIMEOUT + TRANSMISSION_DELAY_MS); ret = modem_backend_mock_get(&bus_mock, buffer1, sizeof(buffer1)); zassert_true(ret == 0, "Received unexpected data"); @@ -721,7 +724,7 @@ ZTEST(modem_cmux, test_modem_cmux_disconnect_connect) /* Open DLCI1 */ zassert_true(modem_pipe_open_async(dlci1_pipe) == 0, "Failed to open DLCI1 pipe"); - k_msleep(100); + k_msleep(TRANSMISSION_DELAY_MS); ret = modem_backend_mock_get(&bus_mock, buffer1, sizeof(buffer1)); zassert_true(ret == sizeof(cmux_frame_dlci1_sabm_cmd), @@ -743,8 +746,8 @@ ZTEST(modem_cmux, test_modem_cmux_disconnect_connect) modem_backend_mock_prime(&bus_mock, &transaction_dlci1_msc); modem_backend_mock_wait_for_transaction(&bus_mock); - /* Wait for potential T1 timeout */ - k_msleep(500); + /* Wait for potential T2 timeout */ + k_msleep(CONFIG_MODEM_CMUX_T2_TIMEOUT + TRANSMISSION_DELAY_MS); ret = modem_backend_mock_get(&bus_mock, buffer1, sizeof(buffer1)); zassert_true(ret == 0, "Received unexpected data"); @@ -752,7 +755,7 @@ ZTEST(modem_cmux, test_modem_cmux_disconnect_connect) /* Open DLCI2 */ zassert_true(modem_pipe_open_async(dlci2_pipe) == 0, "Failed to open DLCI2 pipe"); - k_msleep(100); + k_msleep(TRANSMISSION_DELAY_MS); ret = modem_backend_mock_get(&bus_mock, buffer1, sizeof(buffer1)); zassert_true(ret == sizeof(cmux_frame_dlci2_sabm_cmd), @@ -773,8 +776,8 @@ ZTEST(modem_cmux, test_modem_cmux_disconnect_connect) modem_backend_mock_prime(&bus_mock, &transaction_dlci2_msc); modem_backend_mock_wait_for_transaction(&bus_mock); - /* Wait for potential T1 timeout */ - k_msleep(500); + /* Wait for potential T2 timeout */ + k_msleep(CONFIG_MODEM_CMUX_T2_TIMEOUT + TRANSMISSION_DELAY_MS); ret = modem_backend_mock_get(&bus_mock, buffer1, sizeof(buffer1)); zassert_true(ret == 0, "Received unexpected data"); @@ -841,13 +844,13 @@ ZTEST(modem_cmux, test_modem_cmux_prevent_work_while_released) zassert_ok(modem_pipe_open_async(dlci2_pipe)); /* Wait for and validate CMUX is sending requests */ - k_msleep(500); + k_msleep(CONFIG_MODEM_CMUX_T2_TIMEOUT + TRANSMISSION_DELAY_MS); zassert_true(modem_backend_mock_get(&bus_mock, buffer1, sizeof(buffer1)) > 0); /* Release CMUX and validate no more requests are sent */ modem_cmux_release(&cmux); modem_backend_mock_get(&bus_mock, buffer1, sizeof(buffer1)); - k_msleep(500); + k_msleep(CONFIG_MODEM_CMUX_T2_TIMEOUT + TRANSMISSION_DELAY_MS); zassert_true(modem_backend_mock_get(&bus_mock, buffer1, sizeof(buffer1)) == 0); /* Validate no new requests can be submitted */ @@ -861,7 +864,7 @@ ZTEST(modem_cmux, test_modem_cmux_prevent_work_while_released) modem_pipe_receive(dlci2_pipe, receive, sizeof(receive)); modem_pipe_close(dlci1_pipe, K_SECONDS(10)); modem_pipe_close(dlci2_pipe, K_SECONDS(10)); - k_msleep(500); + k_msleep(CONFIG_MODEM_CMUX_T2_TIMEOUT + TRANSMISSION_DELAY_MS); zassert_true(modem_backend_mock_get(&bus_mock, buffer1, sizeof(buffer1)) == 0); /* Restore CMUX */ @@ -885,7 +888,7 @@ ZTEST(modem_cmux, test_modem_drop_frames_with_invalid_length) modem_backend_mock_put(&bus_mock, cmux_frame_dlci2_at_cgdcont_invalid_length, sizeof(cmux_frame_dlci2_at_cgdcont_invalid_length)); - k_msleep(100); + k_msleep(TRANSMISSION_DELAY_MS); events = k_event_test(&cmux_event, EVENT_CMUX_DLCI2_RECEIVE_READY); @@ -898,7 +901,7 @@ ZTEST(modem_cmux, test_modem_drop_frames_with_invalid_length) modem_backend_mock_put(&bus_mock, cmux_frame_dlci2_at_newline, sizeof(cmux_frame_dlci2_at_newline)); - k_msleep(100); + k_msleep(TRANSMISSION_DELAY_MS); events = k_event_test(&cmux_event, EVENT_CMUX_DLCI2_RECEIVE_READY); zassert_equal(events, EVENT_CMUX_DLCI2_RECEIVE_READY, From c57042e3cab9ac1a6afee48c4f326fa3f079564d Mon Sep 17 00:00:00 2001 From: Seppo Takalo Date: Thu, 18 Dec 2025 14:54:12 +0200 Subject: [PATCH 0772/3659] net: lib: shell: dns: Don't hard code the timeout to 2s The hard coded 2s timeout might be too small for LTE and Nb-IoT networks. Instead use already existing CONFIG_NET_SOCKETS_DNS_TIMEOUT Signed-off-by: Seppo Takalo --- subsys/net/lib/shell/dns.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/subsys/net/lib/shell/dns.c b/subsys/net/lib/shell/dns.c index f74309086392..31496455ffd2 100644 --- a/subsys/net/lib/shell/dns.c +++ b/subsys/net/lib/shell/dns.c @@ -18,6 +18,8 @@ LOG_MODULE_DECLARE(net_shell); #include "net_shell_private.h" +#define DNS_TIMEOUT CONFIG_NET_SOCKETS_DNS_TIMEOUT + #if defined(CONFIG_DNS_RESOLVER) static void dns_result_cb(enum dns_resolve_status status, struct dns_addrinfo *info, @@ -262,7 +264,6 @@ static int cmd_net_dns_query(const struct shell *sh, size_t argc, char *argv[]) { #if defined(CONFIG_DNS_RESOLVER) -#define DNS_QUERY_TIMEOUT (MSEC_PER_SEC * 2) /* ms */ struct dns_resolve_context *ctx; enum dns_query_type qtype = DNS_QUERY_TYPE_A; char *host, *type = NULL; @@ -311,7 +312,7 @@ static int cmd_net_dns_query(const struct shell *sh, size_t argc, char *argv[]) } ret = dns_resolve_name(ctx, host, qtype, NULL, dns_result_cb, - (void *)sh, DNS_QUERY_TIMEOUT); + (void *)sh, DNS_TIMEOUT); if (ret < 0) { PR_WARNING("Cannot resolve '%s' (%d)\n", host, ret); } else { @@ -403,7 +404,6 @@ static int cmd_net_dns_list(const struct shell *sh, size_t argc, char *argv[]) static int cmd_net_dns_service(const struct shell *sh, size_t argc, char *argv[]) { #if defined(CONFIG_DNS_RESOLVER) -#define DNS_SERVICE_TIMEOUT (MSEC_PER_SEC * 4) /* ms */ struct dns_resolve_context *ctx; char *cp; char *service; @@ -427,7 +427,7 @@ static int cmd_net_dns_service(const struct shell *sh, size_t argc, char *argv[] } ret = dns_resolve_service(ctx, service, &dns_id, dns_service_cb, - (void *)sh, DNS_SERVICE_TIMEOUT); + (void *)sh, DNS_TIMEOUT); if (ret < 0) { PR_WARNING("Cannot resolve '%s' (%d)\n", service, ret); return ret; @@ -444,7 +444,7 @@ static int cmd_net_dns_service(const struct shell *sh, size_t argc, char *argv[] char in6[NET_INET6_ADDRSTRLEN]; } str; - ret = k_msgq_get(&dns_infoq, &info, K_MSEC(DNS_SERVICE_TIMEOUT)); + ret = k_msgq_get(&dns_infoq, &info, K_MSEC(DNS_TIMEOUT)); if (ret < 0) { /* just assume a timeout so no more data to process */ break; @@ -476,7 +476,7 @@ static int cmd_net_dns_service(const struct shell *sh, size_t argc, char *argv[] ret = dns_resolve_name(ctx, query, qtype, &dns_id, dns_service_cb, (void *)sh, - DNS_SERVICE_TIMEOUT); + DNS_TIMEOUT); if (ret < 0) { return ret; } @@ -508,7 +508,7 @@ static int cmd_net_dns_service(const struct shell *sh, size_t argc, char *argv[] &dns_id, dns_service_cb, (void *)sh, - DNS_SERVICE_TIMEOUT); + DNS_TIMEOUT); if (ret < 0) { return ret; } From 1aebea1490bb9c7ba822254051cbbeccd9e56cf1 Mon Sep 17 00:00:00 2001 From: Mathieu Choplain Date: Fri, 5 Dec 2025 17:36:20 +0100 Subject: [PATCH 0773/3659] soc: st: stm32: handle debug power mode in common code for WBA series Perform call to LL_DBGMCU_{Dis,En}ableDBGStandbyMode() for STM32WBA series in the common code, as done with other series. While at it, also add missing call to LL_DBGMCU_{Dis,En}ableDBGStopMode(). Signed-off-by: Mathieu Choplain --- soc/st/stm32/common/soc_config.c | 6 ++++++ soc/st/stm32/stm32wbax/power.c | 3 --- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/soc/st/stm32/common/soc_config.c b/soc/st/stm32/common/soc_config.c index 159a581ff918..7bdff80eaa25 100644 --- a/soc/st/stm32/common/soc_config.c +++ b/soc/st/stm32/common/soc_config.c @@ -80,6 +80,9 @@ static int st_stm32_common_config(void) LL_DBGMCU_EnableDebugInStopMode(); #elif defined(CONFIG_SOC_SERIES_STM32WB0X) LL_PWR_EnableDEEPSTOP2(); +#elif defined(CONFIG_SOC_SERIES_STM32WBAX) + LL_DBGMCU_EnableDBGStopMode(); + LL_DBGMCU_EnableDBGStandbyMode(); #elif defined(CONFIG_SOC_SERIES_STM32MP13X) LL_DBGMCU_EnableDebugInLowPowerMode(); #else /* all other parts */ @@ -100,6 +103,9 @@ static int st_stm32_common_config(void) LL_DBGMCU_DisableDebugInStopMode(); #elif defined(CONFIG_SOC_SERIES_STM32WB0X) LL_PWR_DisableDEEPSTOP2(); +#elif defined(CONFIG_SOC_SERIES_STM32WBAX) + LL_DBGMCU_DisableDBGStopMode(); + LL_DBGMCU_DisableDBGStandbyMode(); #elif defined(CONFIG_SOC_SERIES_STM32MP13X) LL_DBGMCU_DisableDebugInLowPowerMode(); #else /* all other parts */ diff --git a/soc/st/stm32/stm32wbax/power.c b/soc/st/stm32/stm32wbax/power.c index 3683823baf6b..e65cf649b36b 100644 --- a/soc/st/stm32/stm32wbax/power.c +++ b/soc/st/stm32/stm32wbax/power.c @@ -245,11 +245,8 @@ void stm32_power_init(void) LL_AHB4_GRP1_EnableClock(LL_AHB4_GRP1_PERIPH_PWR); #ifdef CONFIG_DEBUG - LL_DBGMCU_EnableDBGStandbyMode(); LL_DBGMCU_APB7_GRP1_FreezePeriph(LL_DBGMCU_APB7_GRP1_RTC_STOP); LL_DBGMCU_APB7_GRP1_FreezePeriph(LL_DBGMCU_APB7_GRP1_LPTIM1_STOP); -#else - LL_DBGMCU_DisableDBGStandbyMode(); #endif /* Enable SRAM full retention */ From 348ec106d36caa5d96441c791724b9f10f8cd059 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Thu, 18 Dec 2025 16:27:55 +0100 Subject: [PATCH 0774/3659] include: display: mipi_display: add missing doxygen comments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ensure that all enumerators have proper doxygen comments. Signed-off-by: Benjamin Cabé --- include/zephyr/display/mipi_display.h | 102 ++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) diff --git a/include/zephyr/display/mipi_display.h b/include/zephyr/display/mipi_display.h index cd271334e7af..2f58ad47113e 100644 --- a/include/zephyr/display/mipi_display.h +++ b/include/zephyr/display/mipi_display.h @@ -29,67 +29,128 @@ extern "C" { * @{ */ +/** NOP */ #define MIPI_DCS_NOP 0x00U +/** Soft Reset */ #define MIPI_DCS_SOFT_RESET 0x01U +/** Get Compression Mode */ #define MIPI_DCS_GET_COMPRESSION_MODE 0x03U +/** Get Display ID */ #define MIPI_DCS_GET_DISPLAY_ID 0x04U +/** Get Red Channel */ #define MIPI_DCS_GET_RED_CHANNEL 0x06U +/** Get Green Channel */ #define MIPI_DCS_GET_GREEN_CHANNEL 0x07U +/** Get Blue Channel */ #define MIPI_DCS_GET_BLUE_CHANNEL 0x08U +/** Get Display Status */ #define MIPI_DCS_GET_DISPLAY_STATUS 0x09U +/** Get Power Mode */ #define MIPI_DCS_GET_POWER_MODE 0x0AU +/** Get Address Mode */ #define MIPI_DCS_GET_ADDRESS_MODE 0x0BU +/** Get Pixel Format */ #define MIPI_DCS_GET_PIXEL_FORMAT 0x0CU +/** Get Display Mode */ #define MIPI_DCS_GET_DISPLAY_MODE 0x0DU +/** Get Signal Mode */ #define MIPI_DCS_GET_SIGNAL_MODE 0x0EU +/** Get Diagnostic Result */ #define MIPI_DCS_GET_DIAGNOSTIC_RESULT 0x0FU +/** Enter Sleep Mode */ #define MIPI_DCS_ENTER_SLEEP_MODE 0x10U +/** Exit Sleep Mode */ #define MIPI_DCS_EXIT_SLEEP_MODE 0x11U +/** Enter Partial Mode */ #define MIPI_DCS_ENTER_PARTIAL_MODE 0x12U +/** Enter Normal Mode */ #define MIPI_DCS_ENTER_NORMAL_MODE 0x13U +/** Exit Invert Mode */ #define MIPI_DCS_EXIT_INVERT_MODE 0x20U +/** Enter Invert Mode */ #define MIPI_DCS_ENTER_INVERT_MODE 0x21U +/** Set Gamma Curve */ #define MIPI_DCS_SET_GAMMA_CURVE 0x26U +/** Set Display Off */ #define MIPI_DCS_SET_DISPLAY_OFF 0x28U +/** Set Display On */ #define MIPI_DCS_SET_DISPLAY_ON 0x29U +/** Set Column Address */ #define MIPI_DCS_SET_COLUMN_ADDRESS 0x2AU +/** Set Page Address */ #define MIPI_DCS_SET_PAGE_ADDRESS 0x2BU +/** Write Memory Start */ #define MIPI_DCS_WRITE_MEMORY_START 0x2CU +/** Write LUT */ #define MIPI_DCS_WRITE_LUT 0x2DU +/** Read Memory Start */ #define MIPI_DCS_READ_MEMORY_START 0x2EU +/** Set Partial Rows */ #define MIPI_DCS_SET_PARTIAL_ROWS 0x30U +/** Set Partial Columns */ #define MIPI_DCS_SET_PARTIAL_COLUMNS 0x31U +/** Set Scroll Area */ #define MIPI_DCS_SET_SCROLL_AREA 0x33U +/** Set Tear Off */ #define MIPI_DCS_SET_TEAR_OFF 0x34U +/** Set Tear On */ #define MIPI_DCS_SET_TEAR_ON 0x35U +/** Set Address Mode */ #define MIPI_DCS_SET_ADDRESS_MODE 0x36U +/** Set Scroll Start */ #define MIPI_DCS_SET_SCROLL_START 0x37U +/** Exit Idle Mode */ #define MIPI_DCS_EXIT_IDLE_MODE 0x38U +/** Enter Idle Mode */ #define MIPI_DCS_ENTER_IDLE_MODE 0x39U +/** Set Pixel Format */ #define MIPI_DCS_SET_PIXEL_FORMAT 0x3AU +/** Write Memory Continue */ #define MIPI_DCS_WRITE_MEMORY_CONTINUE 0x3CU +/** Set 3D Control */ #define MIPI_DCS_SET_3D_CONTROL 0x3DU +/** Read Memory Continue */ #define MIPI_DCS_READ_MEMORY_CONTINUE 0x3EU +/** Get 3D Control */ #define MIPI_DCS_GET_3D_CONTROL 0x3FU +/** Set VSync Timing */ #define MIPI_DCS_SET_VSYNC_TIMING 0x40U +/** Set Tear Scanline */ #define MIPI_DCS_SET_TEAR_SCANLINE 0x44U +/** Get Scanline */ #define MIPI_DCS_GET_SCANLINE 0x45U +/** Set Display Brightness */ #define MIPI_DCS_SET_DISPLAY_BRIGHTNESS 0x51U +/** Get Display Brightness */ #define MIPI_DCS_GET_DISPLAY_BRIGHTNESS 0x52U +/** Write Control Display */ #define MIPI_DCS_WRITE_CONTROL_DISPLAY 0x53U +/** Get Control Display */ #define MIPI_DCS_GET_CONTROL_DISPLAY 0x54U +/** Write Power Save */ #define MIPI_DCS_WRITE_POWER_SAVE 0x55U +/** Get Power Save */ #define MIPI_DCS_GET_POWER_SAVE 0x56U +/** Set CABC Min Brightness */ #define MIPI_DCS_SET_CABC_MIN_BRIGHTNESS 0x5EU +/** Get CABC Min Brightness */ #define MIPI_DCS_GET_CABC_MIN_BRIGHTNESS 0x5FU +/** Read DDB Start */ #define MIPI_DCS_READ_DDB_START 0xA1U +/** Read DDB Continue */ #define MIPI_DCS_READ_DDB_CONTINUE 0xA8U +/** 24-bit Pixel Format */ #define MIPI_DCS_PIXEL_FORMAT_24BIT 0x77 +/** 18-bit Pixel Format */ #define MIPI_DCS_PIXEL_FORMAT_18BIT 0x66 +/** 16-bit Pixel Format */ #define MIPI_DCS_PIXEL_FORMAT_16BIT 0x55 +/** 12-bit Pixel Format */ #define MIPI_DCS_PIXEL_FORMAT_12BIT 0x33 +/** 8-bit Pixel Format */ #define MIPI_DCS_PIXEL_FORMAT_8BIT 0x22 +/** 3-bit Pixel Format */ #define MIPI_DCS_PIXEL_FORMAT_3BIT 0x11 /** @} */ @@ -99,13 +160,21 @@ extern "C" { * @{ */ +/** Mirror Y */ #define MIPI_DCS_ADDRESS_MODE_MIRROR_Y BIT(7) +/** Mirror X */ #define MIPI_DCS_ADDRESS_MODE_MIRROR_X BIT(6) +/** Swap XY */ #define MIPI_DCS_ADDRESS_MODE_SWAP_XY BIT(5) +/** Refresh Bottom to Top */ #define MIPI_DCS_ADDRESS_MODE_REFRESH_BT BIT(4) +/** BGR Order */ #define MIPI_DCS_ADDRESS_MODE_BGR BIT(3) +/** Latch Right to Left */ #define MIPI_DCS_ADDRESS_MODE_LATCH_RL BIT(2) +/** Flip X */ #define MIPI_DCS_ADDRESS_MODE_FLIP_X BIT(1) +/** Flip Y */ #define MIPI_DCS_ADDRESS_MODE_FLIP_Y BIT(0) /** @} */ @@ -115,38 +184,71 @@ extern "C" { * @{ */ +/** Sync Event, V Sync Start */ #define MIPI_DSI_V_SYNC_START 0x01U +/** Sync Event, V Sync End */ #define MIPI_DSI_V_SYNC_END 0x11U +/** Sync Event, H Sync Start */ #define MIPI_DSI_H_SYNC_START 0x21U +/** Sync Event, H Sync End */ #define MIPI_DSI_H_SYNC_END 0x31U +/** Color Mode Off Command */ #define MIPI_DSI_COLOR_MODE_OFF 0x02U +/** Color Mode On Command */ #define MIPI_DSI_COLOR_MODE_ON 0x12U +/** Shutdown Peripheral Command */ #define MIPI_DSI_SHUTDOWN_PERIPHERAL 0x22U +/** Turn On Peripheral Command */ #define MIPI_DSI_TURN_ON_PERIPHERAL 0x32U +/** Generic Short WRITE Packet with 0 parameters */ #define MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM 0x03U +/** Generic Short WRITE Packet with 1 parameter */ #define MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM 0x13U +/** Generic Short WRITE Packet with 2 parameters */ #define MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM 0x23U +/** Generic READ Request with 0 parameters */ #define MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM 0x04U +/** Generic READ Request with 1 parameter */ #define MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM 0x14U +/** Generic READ Request with 2 parameters */ #define MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM 0x24U +/** DCS Short Write Command with 0 parameters */ #define MIPI_DSI_DCS_SHORT_WRITE 0x05U +/** DCS Short Write Command with 1 parameter */ #define MIPI_DSI_DCS_SHORT_WRITE_PARAM 0x15U +/** DCS Read Request with 0 parameters */ #define MIPI_DSI_DCS_READ 0x06U +/** Set Maximum Return Packet Size Command */ #define MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE 0x37U +/** End of Transmission Packet (EoTp) */ #define MIPI_DSI_END_OF_TRANSMISSION 0x08U +/** Null Packet (Long) */ #define MIPI_DSI_NULL_PACKET 0x09U +/** Blanking Packet (Long) */ #define MIPI_DSI_BLANKING_PACKET 0x19U +/** Generic Long Write */ #define MIPI_DSI_GENERIC_LONG_WRITE 0x29U +/** DCS Long Write / write_LUT Command */ #define MIPI_DSI_DCS_LONG_WRITE 0x39U +/** Loosely Packed Pixel Stream, 20-bit YCbCr 4:2:2 Format */ #define MIPI_DSI_LOOSELY_PACKED_PIXEL_STREAM_YCBCR20 0x0CU +/** Packed Pixel Stream, 24-bit YCbCr 4:2:2 Format */ #define MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR24 0x1CU +/** Packed Pixel Stream, 16-bit YCbCr 4:2:2 Format */ #define MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16 0x2CU +/** Packed Pixel Stream, 30-bit Format */ #define MIPI_DSI_PACKED_PIXEL_STREAM_30 0x0DU +/** Packed Pixel Stream, 36-bit Format */ #define MIPI_DSI_PACKED_PIXEL_STREAM_36 0x1DU +/** Packed Pixel Stream, 12-bit YCbCr 4:2:0 Format */ #define MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12 0x3DU +/** Packed Pixel Stream, 16-bit Format */ #define MIPI_DSI_PACKED_PIXEL_STREAM_16 0x0EU +/** Packed Pixel Stream, 18-bit Format */ #define MIPI_DSI_PACKED_PIXEL_STREAM_18 0x1EU +/** Pixel Stream, 18-bit Format in Three Bytes */ #define MIPI_DSI_PIXEL_STREAM_3BYTE_18 0x2EU +/** Packed Pixel Stream, 24-bit Format */ #define MIPI_DSI_PACKED_PIXEL_STREAM_24 0x3EU /** @} */ From 29c7d7a3f0e96c89c88dc6ad3019f457f7536928 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Thu, 18 Dec 2025 16:39:32 +0100 Subject: [PATCH 0775/3659] include: display: add doxygen group for Display API extensions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Similar to how it's done for other driver classes, create a new doxygen group to put all device-specific Display API extensions under. Signed-off-by: Benjamin Cabé --- include/zephyr/drivers/display.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/zephyr/drivers/display.h b/include/zephyr/drivers/display.h index 39911d08baad..f662abfd065e 100644 --- a/include/zephyr/drivers/display.h +++ b/include/zephyr/drivers/display.h @@ -20,6 +20,11 @@ * @version 0.8.0 * @ingroup io_interfaces * @{ + * + * @defgroup display_interface_ext Device-specific Display API extensions + * @{ + * @} + * */ #include From 2954eff7f147c85cc94740b6d5f815a7273ecaa4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Thu, 18 Dec 2025 16:40:03 +0100 Subject: [PATCH 0776/3659] include: display: ssd16xx:: add doxygen docs for ssd16xx extended API MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds doxygen documentation for the extended API of the Solomon SSD16XX EPD display controller driver. Signed-off-by: Benjamin Cabé --- include/zephyr/display/ssd16xx.h | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/include/zephyr/display/ssd16xx.h b/include/zephyr/display/ssd16xx.h index 9c287c3f1acb..53eb05b07cad 100644 --- a/include/zephyr/display/ssd16xx.h +++ b/include/zephyr/display/ssd16xx.h @@ -4,13 +4,28 @@ * SPDX-License-Identifier: Apache-2.0 */ +/** + * @file + * @brief Header file for extended Display API of SSD16XX + * @ingroup ssd16xx_interface + */ + #ifndef ZEPHYR_INCLUDE_DISPLAY_SSD16XX_H_ #define ZEPHYR_INCLUDE_DISPLAY_SSD16XX_H_ +/** + * @brief Solomon SSD16xx EPD display controller + * @defgroup ssd16xx_interface SSD16xx + * @ingroup display_interface_ext + * @{ + */ + #include /** * SSD16xx RAM type for direct RAM access + * + * @see ssd16xx_read_ram */ enum ssd16xx_ram { /** The black RAM buffer. This is typically the buffer used to @@ -18,7 +33,7 @@ enum ssd16xx_ram { * refresh. */ SSD16XX_RAM_BLACK = 0, - /* The red RAM buffer. This is typically the old frame buffer + /** The red RAM buffer. This is typically the old frame buffer * when performing partial refreshes or an additional color * channel. */ @@ -26,7 +41,7 @@ enum ssd16xx_ram { }; /** - * @brief Read data directly from the display controller's internal + * @brief Read data directly from an SSD16xx display controller's internal * RAM. * * @param dev Pointer to device structure @@ -43,4 +58,6 @@ int ssd16xx_read_ram(const struct device *dev, enum ssd16xx_ram ram_type, const struct display_buffer_descriptor *desc, void *buf); +/** @} */ + #endif /* ZEPHYR_INCLUDE_DISPLAY_SSD16XX_H_ */ From 5fdffd8e1e780b19ee2921b5976737f9c141797c Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Tue, 16 Dec 2025 12:15:30 +0100 Subject: [PATCH 0777/3659] boards: doc: Update information regarding memory sizes for stm32g474re MCU According to STM's website: https://www.st.com/en/microcontrollers-microprocessors/stm32g474re.html the stm32g474re has larger FLASH and SRAM sizes than stated in the Zephyr's documentation. Signed-off-by: Lukasz Majewski --- boards/st/nucleo_g474re/doc/index.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/boards/st/nucleo_g474re/doc/index.rst b/boards/st/nucleo_g474re/doc/index.rst index 433941e3349a..2bf4471d3dfa 100644 --- a/boards/st/nucleo_g474re/doc/index.rst +++ b/boards/st/nucleo_g474re/doc/index.rst @@ -51,8 +51,8 @@ The STM32G474RE SoC provides the following hardware IPs: - Up to 86 fast I/Os, most 5 V-tolerant - Memories - - Up to 128 KB single bank Flash, proprietary code readout protection - - Up to 22 KB of SRAM including 16 KB with hardware parity check + - Up to 512 KB single bank Flash, proprietary code readout protection + - Up to 128 KB of SRAM including 32 KB with hardware parity check - Rich analog peripherals (independent supply) From 2c004260b84cf28d13a10502ff5c4aa5d06b598a Mon Sep 17 00:00:00 2001 From: Mathieu Choplain Date: Thu, 18 Dec 2025 17:19:23 +0100 Subject: [PATCH 0778/3659] drivers: entropy: stm32: fix build breakage on STM32WB06/07 These SoCs don't have LL_PKA_IsEnabled() due to the PKA IP being different. Since PKA can operate without RNG clock on entire STM32WB0 series, skip the check on the entire series which avoids the call to non-existent function on STM32WB06/07 and fixes build. Signed-off-by: Mathieu Choplain --- drivers/entropy/entropy_stm32.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/drivers/entropy/entropy_stm32.c b/drivers/entropy/entropy_stm32.c index 81b416a6f6bb..e40105c12c47 100644 --- a/drivers/entropy/entropy_stm32.c +++ b/drivers/entropy/entropy_stm32.c @@ -140,8 +140,18 @@ static int entropy_stm32_suspend(void) LL_RNG_SetAesReset(rng, 1); #endif /* CONFIG_SOC_STM32WB09XX */ -/* PKA module isn't currently supported in Zephyr, but it could be used outside Zephyr */ -#if defined(PKA) +/* + * The PKA IP is currently not supported by Zephyr but may be used by + * external code, such as wireless stack for example. Since the RNG + * clock must be enabled when PKA is used on certain series, check if + * the PKA is in use and keep RNG clock active if so. + * + * A notable exception is the STM32WB0 series where PKA can operate + * autonomously and, on certain SoCs, lacks PKA_CR.EN and corresponding + * LL_PKA_IsEnabled(). Since RNG clock is not required by PKA, we can + * ignore the check on this series. + */ +#if defined(PKA) && !defined(CONFIG_SOC_SERIES_STM32WB0X) if (__HAL_RCC_PKA_IS_CLK_ENABLED() && LL_PKA_IsEnabled(PKA)) { #if defined(CONFIG_SOC_SERIES_STM32WBX) || defined(CONFIG_STM32H7_DUAL_CORE) z_stm32_hsem_unlock(CFG_HW_RNG_SEMID); @@ -150,7 +160,7 @@ static int entropy_stm32_suspend(void) /* PKA needs RNG clock, so exit here if in use */ return 0; } -#endif /* PKA */ +#endif /* PKA && !CONFIG_SOC_SERIES_STM32WB0X */ #ifdef CONFIG_SOC_SERIES_STM32WBAX uint32_t wait_cycles, rng_rate; From 31bc3b016b9815775bec9176d67d44f5610cd904 Mon Sep 17 00:00:00 2001 From: Ayush Singh Date: Thu, 18 Dec 2025 22:31:22 +0530 Subject: [PATCH 0779/3659] net: dns: resolve: Add additional record support for PTR query As described in Section 12 of RFC 6763 [0], DNS-SD responses can contain SRV, TXT and A/AAAA under additional records. This is done even in the zephyr DNS service advertisement. So these additional records should be passed to the user for handling. Most of the code for additional records is taken from normal dns answer unpacking. However, I have split the handling into a separate function since I have only added additional records handling for DNS-SD. The same code should be usable for answer record as well if required. The main thing missing from additional record code is that we do not need to match the query type to the response type. Tested on BeagleConnect Freedom. [0]: https://datatracker.ietf.org/doc/html/rfc6763.html#section-12 Signed-off-by: Ayush Singh --- subsys/net/lib/dns/resolve.c | 147 +++++++++++++++++++++++++++++++++++ 1 file changed, 147 insertions(+) diff --git a/subsys/net/lib/dns/resolve.c b/subsys/net/lib/dns/resolve.c index f7bc4a761f77..708d6f87936c 100644 --- a/subsys/net/lib/dns/resolve.c +++ b/subsys/net/lib/dns/resolve.c @@ -1089,6 +1089,137 @@ static int update_query_idx(struct dns_resolve_context *ctx, return ret; } +static int dns_validate_additional_record(struct dns_resolve_context *ctx, + struct dns_msg_t *dns_msg, struct dns_addrinfo *info) +{ + enum dns_rr_type answer_type = DNS_RR_TYPE_INVALID; + uint32_t ttl; /* RR ttl, so far it is not passed to caller */ + uint8_t *addr, *pos, *src; + int ret, address_size; + + /* dname_ptr no longer seems to be used. So just passing 0. */ + ret = dns_unpack_answer(dns_msg, 0, &ttl, &answer_type); + if (ret < 0) { + return DNS_EAI_SYSTEM; + } + + switch (dns_msg->response_type) { + case DNS_RESPONSE_DATA: + case DNS_RESPONSE_IP: { + if (answer_type == DNS_RR_TYPE_A) { + address_size = DNS_IPV4_LEN; + addr = (uint8_t *)&net_sin(&info->ai_addr)->sin_addr; + info->ai_family = NET_AF_INET; + info->ai_addr.sa_family = NET_AF_INET; + info->ai_addrlen = sizeof(struct net_sockaddr_in); + } else if (answer_type == DNS_RR_TYPE_AAAA) { +/* We cannot resolve IPv6 address if IPv6 is + * disabled. The reason being that + * "struct net_sockaddr" does not have enough space + * for IPv6 address in that case. + */ +#if defined(CONFIG_NET_IPV6) + address_size = DNS_IPV6_LEN; + addr = (uint8_t *)&net_sin6(&info->ai_addr)->sin6_addr; + info->ai_family = NET_AF_INET6; + info->ai_addr.sa_family = NET_AF_INET6; + info->ai_addrlen = sizeof(struct net_sockaddr_in6); +#else + return DNS_EAI_FAMILY; +#endif + } else { + return DNS_EAI_SYSTEM; + } + + if (dns_msg->response_length < address_size) { + /* it seems this is a malformed message */ + errno = EMSGSIZE; + return DNS_EAI_SYSTEM; + } + + if ((dns_msg->response_position + address_size) > dns_msg->msg_size) { + /* Too short message */ + errno = EMSGSIZE; + return DNS_EAI_SYSTEM; + } + + src = dns_msg->msg + dns_msg->response_position; + memcpy(addr, src, address_size); + + break; + } + case DNS_RESPONSE_TXT: + pos = dns_msg->msg + dns_msg->response_position; + + info->ai_family = NET_AF_UNSPEC; + info->ai_extension = DNS_RESOLVE_TXT; + info->ai_txt.textlen = MIN(dns_msg->response_length, DNS_MAX_TEXT_SIZE); + memcpy(info->ai_txt.text, pos, info->ai_txt.textlen); + info->ai_txt.text[info->ai_txt.textlen] = '\0'; + break; + + case DNS_RESPONSE_SRV: { + int priority; + int weight; + int port; + struct net_buf *target; + + address_size = MIN(dns_msg->response_length, 6 + DNS_MAX_NAME_SIZE); + if (address_size < 6) { + /* 3 tuples of be16 - priority, weight, port */ + errno = EMSGSIZE; + return DNS_EAI_SYSTEM; + } + + /* Temporary buffer that is needed by dns_unpack_name() + * to unpack the target. + */ + target = net_buf_alloc(&dns_qname_pool, ctx->buf_timeout); + if (target == NULL) { + NET_DBG("Cannot allocate buffer for DNS query target"); + return DNS_EAI_MEMORY; + } + + pos = dns_msg->msg + dns_msg->response_position; + + priority = dns_unpack_srv_priority(pos); + weight = dns_unpack_srv_weight(pos); + port = dns_unpack_srv_port(pos); + + ret = dns_unpack_name(dns_msg->msg, dns_msg->msg_size, pos + 6, target, NULL); + if (ret < 0) { + errno = -ret; + net_buf_unref(target); + return DNS_EAI_SYSTEM; + } + + info->ai_family = NET_AF_UNSPEC; + info->ai_extension = DNS_RESOLVE_SRV; + info->ai_srv.priority = priority; + info->ai_srv.weight = weight; + info->ai_srv.port = port; + info->ai_srv.targetlen = MIN(target->len, DNS_MAX_NAME_SIZE); + memcpy(info->ai_srv.target, target->data, info->ai_srv.targetlen); + info->ai_srv.target[info->ai_srv.targetlen] = '\0'; + + net_buf_unref(target); + + break; + } + case DNS_RESPONSE_CNAME_NO_IP: + /* Instead of using the QNAME at DNS_QUERY_POS, + * we will use this CNAME + */ + break; + } + + /* Update the answer offset to point to the next RR (answer) */ + dns_msg->answer_offset += dns_msg->response_position - dns_msg->answer_offset; + dns_msg->answer_offset += dns_msg->response_length; + + return 0; +} + /* Unit test needs to be able to call this function */ #if !defined(CONFIG_NET_TEST) static @@ -1510,6 +1641,22 @@ int dns_validate_msg(struct dns_resolve_context *ctx, } } + /* Deal with Additional records. Only for DNS-SD right now. */ + if (ctx->queries[*query_idx].query_type == DNS_QUERY_TYPE_PTR) { + for (server_idx = 0; server_idx < dns_header_nscount(dns_msg->msg) + + dns_header_arcount(dns_msg->msg); + server_idx++) { + ret = dns_validate_additional_record(ctx, dns_msg, &info); + /* Ignore errors when parsing additional records */ + if (ret < 0) { + NET_WARN("Failed to parse additional record"); + continue; + } + + invoke_query_callback(DNS_EAI_INPROGRESS, &info, &ctx->queries[*query_idx]); + } + } + if (items == 0) { ret = DNS_EAI_NODATA; } else { From 63ff14e3d8d0e14b636a920ecb8870247a8af8ee Mon Sep 17 00:00:00 2001 From: Ayush Singh Date: Fri, 19 Dec 2025 00:12:02 +0530 Subject: [PATCH 0780/3659] net: dns: resolve: Combine AR and AN handling Use the same function to parse all records. The main difference is that answer record handling matches the answer with the initial query, i.e. AAAA query will have AAAA answer record. Additional records do not have any matching with the original query. Also just warns if an additional record parsing fails. But answer record parsing is an error. Tested on BeagleConnect Freedom Signed-off-by: Ayush Singh --- subsys/net/lib/dns/resolve.c | 348 +++++++---------------------------- 1 file changed, 71 insertions(+), 277 deletions(-) diff --git a/subsys/net/lib/dns/resolve.c b/subsys/net/lib/dns/resolve.c index 708d6f87936c..408a694a5ef8 100644 --- a/subsys/net/lib/dns/resolve.c +++ b/subsys/net/lib/dns/resolve.c @@ -1089,30 +1089,63 @@ static int update_query_idx(struct dns_resolve_context *ctx, return ret; } -static int dns_validate_additional_record(struct dns_resolve_context *ctx, - struct dns_msg_t *dns_msg, struct dns_addrinfo *info) +static int dns_validate_record(struct dns_resolve_context *ctx, struct dns_msg_t *dns_msg, + struct dns_addrinfo *info, enum dns_rr_type *answer_type, + uint32_t *ttl) { - enum dns_rr_type answer_type = DNS_RR_TYPE_INVALID; - uint32_t ttl; /* RR ttl, so far it is not passed to caller */ uint8_t *addr, *pos, *src; int ret, address_size; /* dname_ptr no longer seems to be used. So just passing 0. */ - ret = dns_unpack_answer(dns_msg, 0, &ttl, &answer_type); + ret = dns_unpack_answer(dns_msg, 0, ttl, answer_type); if (ret < 0) { + errno = -ret; return DNS_EAI_SYSTEM; } switch (dns_msg->response_type) { - case DNS_RESPONSE_DATA: + case DNS_RESPONSE_DATA: { + /* Synthesize a reply and place the returned info + * in to the ai_canonname field. Use AF_LOCAL address + * family as this is not a real address. + */ + struct net_buf *result; + + address_size = MIN(dns_msg->response_length, DNS_MAX_NAME_SIZE); + + /* Temporary buffer that is needed by dns_unpack_name() + * to unpack the resolved name. + */ + result = net_buf_alloc(&dns_qname_pool, ctx->buf_timeout); + if (result == NULL) { + NET_DBG("Cannot allocate buffer for DNS query result"); + return DNS_EAI_MEMORY; + } + + pos = dns_msg->msg + dns_msg->response_position; + ret = dns_unpack_name(dns_msg->msg, dns_msg->msg_size, pos, result, NULL); + if (ret < 0) { + errno = -ret; + net_buf_unref(result); + return DNS_EAI_SYSTEM; + } + + info->ai_family = NET_AF_LOCAL; + info->ai_addrlen = MIN(result->len, DNS_MAX_NAME_SIZE); + memcpy(info->ai_canonname, result->data, info->ai_addrlen); + info->ai_canonname[info->ai_addrlen] = '\0'; + + net_buf_unref(result); + break; + } case DNS_RESPONSE_IP: { - if (answer_type == DNS_RR_TYPE_A) { + if (*answer_type == DNS_RR_TYPE_A) { address_size = DNS_IPV4_LEN; addr = (uint8_t *)&net_sin(&info->ai_addr)->sin_addr; info->ai_family = NET_AF_INET; info->ai_addr.sa_family = NET_AF_INET; info->ai_addrlen = sizeof(struct net_sockaddr_in); - } else if (answer_type == DNS_RR_TYPE_AAAA) { + } else if (*answer_type == DNS_RR_TYPE_AAAA) { /* We cannot resolve IPv6 address if IPv6 is * disabled. The reason being that * "struct net_sockaddr" does not have enough space @@ -1211,6 +1244,8 @@ static int dns_validate_additional_record(struct dns_resolve_context *ctx, * we will use this CNAME */ break; + default: + return DNS_EAI_FAIL; } /* Update the answer offset to point to the next RR (answer) */ @@ -1231,12 +1266,8 @@ int dns_validate_msg(struct dns_resolve_context *ctx, struct net_buf *dns_cname, uint16_t *query_hash) { - struct dns_addrinfo info = { 0 }; uint32_t ttl; /* RR ttl, so far it is not passed to caller */ - uint8_t *src, *addr; - int address_size; - /* index that points to the current answer being analyzed */ - int answer_ptr; + struct dns_addrinfo info = {0}; int items; int server_idx; int ret = 0; @@ -1326,290 +1357,53 @@ int dns_validate_msg(struct dns_resolve_context *ctx, * are handled the same way. */ - answer_ptr = DNS_QUERY_POS; items = 0; - server_idx = 0; enum dns_rr_type answer_type = DNS_RR_TYPE_INVALID; - while (server_idx < dns_header_ancount(dns_msg->msg)) { - ret = dns_unpack_answer(dns_msg, answer_ptr, &ttl, - &answer_type); + if (*query_idx < 0) { + ret = update_query_idx(ctx, dns_msg, dns_id, query_idx, query_hash); if (ret < 0) { errno = -ret; ret = DNS_EAI_SYSTEM; goto quit; } + } - switch (dns_msg->response_type) { - case DNS_RESPONSE_DATA: - case DNS_RESPONSE_IP: - if (*query_idx < 0) { - ret = update_query_idx(ctx, dns_msg, dns_id, - query_idx, query_hash); - if (ret < 0) { - errno = -ret; - ret = DNS_EAI_SYSTEM; - goto quit; - } - } - - if (ctx->queries[*query_idx].query_type == - DNS_QUERY_TYPE_A) { - if (answer_type != DNS_RR_TYPE_A) { - ret = DNS_EAI_ADDRFAMILY; - goto quit; - } - -rr_qtype_a: - address_size = DNS_IPV4_LEN; - addr = (uint8_t *)&net_sin(&info.ai_addr)-> - sin_addr; - info.ai_family = NET_AF_INET; - info.ai_addr.sa_family = NET_AF_INET; - info.ai_addrlen = sizeof(struct net_sockaddr_in); - - } else if (ctx->queries[*query_idx].query_type == - DNS_QUERY_TYPE_AAAA) { - if (answer_type != DNS_RR_TYPE_AAAA) { - ret = DNS_EAI_ADDRFAMILY; - goto quit; - } - -rr_qtype_aaaa: - /* We cannot resolve IPv6 address if IPv6 is - * disabled. The reason being that - * "struct net_sockaddr" does not have enough space - * for IPv6 address in that case. - */ -#if defined(CONFIG_NET_IPV6) - address_size = DNS_IPV6_LEN; - addr = (uint8_t *)&net_sin6(&info.ai_addr)-> - sin6_addr; - info.ai_family = NET_AF_INET6; - info.ai_addr.sa_family = NET_AF_INET6; - info.ai_addrlen = sizeof(struct net_sockaddr_in6); -#else - ret = DNS_EAI_FAMILY; - goto quit; -#endif - } else if (ctx->queries[*query_idx].query_type == - (enum dns_query_type)DNS_RR_TYPE_ANY) { - /* If we did ANY query, we need to check what - * type of answer we got. Currently only A or AAAA - * are supported. - */ - if (answer_type == DNS_RR_TYPE_A) { - goto rr_qtype_a; - } else if (answer_type == DNS_RR_TYPE_AAAA) { - goto rr_qtype_aaaa; - } else { - ret = DNS_EAI_ADDRFAMILY; - goto quit; - } - - } else if (ctx->queries[*query_idx].query_type == - DNS_QUERY_TYPE_PTR) { - /* Synthesize a reply and place the returned info - * in to the ai_canonname field. Use AF_LOCAL address - * family as this is not a real address. - */ - struct net_buf *result; - uint8_t *pos; - - address_size = MIN(dns_msg->response_length, - DNS_MAX_NAME_SIZE); - - /* Temporary buffer that is needed by dns_unpack_name() - * to unpack the resolved name. - */ - result = net_buf_alloc(&dns_qname_pool, ctx->buf_timeout); - if (result == NULL) { - NET_DBG("Cannot allocate buffer for DNS query result"); - ret = DNS_EAI_MEMORY; - goto quit; - } - - pos = dns_msg->msg + dns_msg->response_position; - ret = dns_unpack_name(dns_msg->msg, dns_msg->msg_size, pos, - result, NULL); - if (ret < 0) { - errno = -ret; - ret = DNS_EAI_SYSTEM; - net_buf_unref(result); - goto quit; - } - - info.ai_family = NET_AF_LOCAL; - info.ai_addrlen = MIN(result->len, DNS_MAX_NAME_SIZE); - memcpy(info.ai_canonname, result->data, info.ai_addrlen); - info.ai_canonname[info.ai_addrlen] = '\0'; - - net_buf_unref(result); - - } else { - ret = DNS_EAI_FAMILY; - goto quit; - } - - if (ctx->queries[*query_idx].query_type == - DNS_QUERY_TYPE_A || - ctx->queries[*query_idx].query_type == - DNS_QUERY_TYPE_AAAA) { - if (dns_msg->response_length < address_size) { - /* it seems this is a malformed message */ - errno = EMSGSIZE; - ret = DNS_EAI_SYSTEM; - goto quit; - } - - if ((dns_msg->response_position + address_size) > - dns_msg->msg_size) { - /* Too short message */ - errno = EMSGSIZE; - ret = DNS_EAI_SYSTEM; - goto quit; - } - - src = dns_msg->msg + dns_msg->response_position; - memcpy(addr, src, address_size); - } - - invoke_query_callback(DNS_EAI_INPROGRESS, &info, - &ctx->queries[*query_idx]); -#ifdef CONFIG_DNS_RESOLVER_CACHE - dns_cache_add(&dns_cache, - ctx->queries[*query_idx].query, &info, ttl); -#endif /* CONFIG_DNS_RESOLVER_CACHE */ - items++; - break; - - case DNS_RESPONSE_TXT: { - uint8_t *pos; - - if (*query_idx < 0) { - ret = update_query_idx(ctx, dns_msg, dns_id, - query_idx, query_hash); - if (ret < 0) { - errno = -ret; - ret = DNS_EAI_SYSTEM; - goto quit; - } - } - - pos = dns_msg->msg + dns_msg->response_position; - - info.ai_family = NET_AF_UNSPEC; - info.ai_extension = DNS_RESOLVE_TXT; - info.ai_txt.textlen = MIN(dns_msg->response_length, - DNS_MAX_TEXT_SIZE); - memcpy(info.ai_txt.text, pos, info.ai_txt.textlen); - info.ai_txt.text[info.ai_txt.textlen] = '\0'; - - invoke_query_callback(DNS_EAI_INPROGRESS, &info, - &ctx->queries[*query_idx]); - break; + for (server_idx = 0; server_idx < dns_header_ancount(dns_msg->msg); server_idx++) { + ret = dns_validate_record(ctx, dns_msg, &info, &answer_type, &ttl); + if (ret < 0) { + goto quit; } - case DNS_RESPONSE_SRV: { - int priority; - int weight; - int port; - struct net_buf *target; - uint8_t *pos; - - if (*query_idx < 0) { - ret = update_query_idx(ctx, dns_msg, dns_id, - query_idx, query_hash); - if (ret < 0) { - errno = -ret; - ret = DNS_EAI_SYSTEM; - goto quit; - } - } - - address_size = MIN(dns_msg->response_length, - 6 + DNS_MAX_NAME_SIZE); - if (address_size < 6) { - /* 3 tuples of be16 - priority, weight, port */ - errno = EMSGSIZE; - ret = DNS_EAI_SYSTEM; - goto quit; - } - - /* Temporary buffer that is needed by dns_unpack_name() - * to unpack the target. - */ - target = net_buf_alloc(&dns_qname_pool, ctx->buf_timeout); - if (target == NULL) { - NET_DBG("Cannot allocate buffer for DNS query target"); - ret = DNS_EAI_MEMORY; - goto quit; - } - - pos = dns_msg->msg + dns_msg->response_position; - - priority = dns_unpack_srv_priority(pos); - weight = dns_unpack_srv_weight(pos); - port = dns_unpack_srv_port(pos); - ret = dns_unpack_name(dns_msg->msg, dns_msg->msg_size, pos + 6, - target, NULL); - if (ret < 0) { - errno = -ret; - ret = DNS_EAI_SYSTEM; - net_buf_unref(target); + if (dns_msg->response_type == DNS_RESPONSE_IP) { + if ((ctx->queries[*query_idx].query_type == DNS_QUERY_TYPE_A && + answer_type != DNS_RR_TYPE_A) || + (ctx->queries[*query_idx].query_type == DNS_QUERY_TYPE_AAAA && + answer_type != DNS_RR_TYPE_AAAA)) { + ret = DNS_EAI_ADDRFAMILY; goto quit; } + } - info.ai_family = NET_AF_UNSPEC; - info.ai_extension = DNS_RESOLVE_SRV; - info.ai_srv.priority = priority; - info.ai_srv.weight = weight; - info.ai_srv.port = port; - info.ai_srv.targetlen = MIN(target->len, DNS_MAX_NAME_SIZE); - memcpy(info.ai_srv.target, target->data, info.ai_srv.targetlen); - info.ai_srv.target[info.ai_srv.targetlen] = '\0'; + /* If we did ANY query, we need to check what + * type of answer we got. Currently only A or AAAA + * are supported. + */ + if (ctx->queries[*query_idx].query_type == (enum dns_query_type)DNS_RR_TYPE_ANY && + answer_type != DNS_RR_TYPE_AAAA && answer_type != DNS_RR_TYPE_A) { + ret = DNS_EAI_ADDRFAMILY; + goto quit; + } - net_buf_unref(target); + invoke_query_callback(DNS_EAI_INPROGRESS, &info, &ctx->queries[*query_idx]); - invoke_query_callback(DNS_EAI_INPROGRESS, &info, - &ctx->queries[*query_idx]); + if (dns_msg->response_type == DNS_RESPONSE_IP || + dns_msg->response_type == DNS_RESPONSE_SRV) { #ifdef CONFIG_DNS_RESOLVER_CACHE dns_cache_add(&dns_cache, ctx->queries[*query_idx].query, &info, ttl); #endif /* CONFIG_DNS_RESOLVER_CACHE */ items++; - break; - } - case DNS_RESPONSE_CNAME_NO_IP: - /* Instead of using the QNAME at DNS_QUERY_POS, - * we will use this CNAME - */ - answer_ptr = dns_msg->response_position; - break; - - default: - ret = DNS_EAI_FAIL; - goto quit; - } - - /* Update the answer offset to point to the next RR (answer) */ - dns_msg->answer_offset += dns_msg->response_position - - dns_msg->answer_offset; - dns_msg->answer_offset += dns_msg->response_length; - - server_idx++; - } - - if (*query_idx < 0) { - /* If the query_idx is still unknown, try to get it here - * and hope it is found. - */ - ret = update_query_idx(ctx, dns_msg, dns_id, - query_idx, query_hash); - if (ret < 0) { - errno = -ret; - ret = DNS_EAI_SYSTEM; - goto quit; } } @@ -1646,7 +1440,7 @@ int dns_validate_msg(struct dns_resolve_context *ctx, for (server_idx = 0; server_idx < dns_header_nscount(dns_msg->msg) + dns_header_arcount(dns_msg->msg); server_idx++) { - ret = dns_validate_additional_record(ctx, dns_msg, &info); + ret = dns_validate_record(ctx, dns_msg, &info, &answer_type, &ttl); /* Ignore errors when parsing additional records */ if (ret < 0) { NET_WARN("Failed to parse additional record"); From 491a86ca53f7cd077c0d0838e127582575841e7d Mon Sep 17 00:00:00 2001 From: Grzegorz Swiderski Date: Mon, 27 Oct 2025 09:57:03 +0100 Subject: [PATCH 0781/3659] fs: zms: Reformulate zms_active_sector_free_space MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The initial implementation had a flaw in it: when an active sector was almost full, the naïve calculation could easily underflow and return a negative value, which would be misinterpreted as an errno. Rewrite this API to satisfy the following, reasonable expectations: * Always return a non-negative value, provided ZMS is initialized. * Always return 0 if no more data can be written into the sector without triggering garbage collection. * Never return a value less than the actual number of bytes that can still be written into the sector. This requires awareness of a few special cases in ZMS. These are now captured in a helper function, which will be reused later. Signed-off-by: Grzegorz Swiderski --- include/zephyr/fs/zms.h | 3 ++- subsys/fs/zms/zms.c | 38 +++++++++++++++++++++++++++++++++++++- 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/include/zephyr/fs/zms.h b/include/zephyr/fs/zms.h index 17f9b5163d11..f14c2d3a95ad 100644 --- a/include/zephyr/fs/zms.h +++ b/include/zephyr/fs/zms.h @@ -232,7 +232,8 @@ ssize_t zms_calc_free_space(struct zms_fs *fs); * * @param fs Pointer to the file system. * - * @retval >=0 Number of free bytes in the currently active sector + * @retval >=0 Number of free bytes in the currently active sector. On success, it will be equal + * to the number of bytes that can be written without automatically advancing to the next sector. * @retval -EACCES if ZMS is still not initialized. * @retval -EINVAL if `fs` is NULL. */ diff --git a/subsys/fs/zms/zms.c b/subsys/fs/zms/zms.c index 93d140663f5c..9a15343b2f60 100644 --- a/subsys/fs/zms/zms.c +++ b/subsys/fs/zms/zms.c @@ -1813,6 +1813,42 @@ ssize_t zms_get_data_length(struct zms_fs *fs, zms_id_t id) return rc; } +/** + * @brief Helper to calculate free space in some actual or would-be sector + * + * @param fs Pointer to file system + * @param data_wra Data write address offset within the sector + * @param ate_wra ATE write address offset within the sector + * + * @retval Number of free bytes as a signed integer, to match the return type + * of zms_calc_free_space() and zms_active_sector_free_space() + */ +static ssize_t zms_free_space(struct zms_fs *fs, uint32_t data_wra, uint32_t ate_wra) +{ + ssize_t free_space; + + if (ate_wra < 2 * fs->ate_size) { + /* zms_write() requires this space to be reserved for a delete ATE. + * This means that the active sector will not accept any more data. + */ + return 0; + } + + /* initial value: available space for data at the top of the sector */ + free_space = ate_wra - data_wra - fs->ate_size; + + if (free_space < 0) { + /* not enough room for an ATE */ + return 0; + } + if (free_space < ZMS_DATA_IN_ATE_SIZE) { + /* more data can be stored inside an ATE */ + return ZMS_DATA_IN_ATE_SIZE; + } + + return free_space; +} + ssize_t zms_calc_free_space(struct zms_fs *fs) { int rc; @@ -1946,7 +1982,7 @@ ssize_t zms_active_sector_free_space(struct zms_fs *fs) return -EACCES; } - return fs->ate_wra - fs->data_wra - fs->ate_size; + return zms_free_space(fs, SECTOR_OFFSET(fs->data_wra), SECTOR_OFFSET(fs->ate_wra)); } int zms_sector_use_next(struct zms_fs *fs) From a39b2779ee1c0872a39428c8cca6507f9bc28116 Mon Sep 17 00:00:00 2001 From: Grzegorz Swiderski Date: Mon, 27 Oct 2025 09:57:03 +0100 Subject: [PATCH 0782/3659] fs: zms: Reformulate zms_calc_free_space The initial implementation had a couple of flaws, including: * Generally overcounting the free space by ATE_SIZE bytes per sector. * Counting multiple ATEs of the same ID if placed in the same sector. The correct behavior is to only count the most recent entry. * When a sector was mostly or completely filled with small data sizes, there was a correction term applied in the wrong location. * The same correction term would be mistakenly applied when a sector was filled with only delete ATEs, which resulted in undercounting the free space in that sector. This is addressed by rewriting the API according to a simple principle: the total free space in a filesystem should equal the sum of free space in every GC'd sector (minus 1 sector reserved for GC itself). This should work because during garbage collection, ATEs are not moved between sectors arbitrarily. Only one sector gets GC'd at a time and every entry in sector N gets either removed or copied to sector N-1. This means that any two valid entries that occupy a single sector would still occupy a (different) single sector before and after the operation. This property lets us simplify the total free space calculation by considering one sector at a time and reapplying the calculation which was just introduced for `zms_active_sector_free_space()`. Signed-off-by: Grzegorz Swiderski --- subsys/fs/zms/zms.c | 133 ++++++++++++++++++++------------------------ 1 file changed, 59 insertions(+), 74 deletions(-) diff --git a/subsys/fs/zms/zms.c b/subsys/fs/zms/zms.c index 9a15343b2f60..693a7c165e5d 100644 --- a/subsys/fs/zms/zms.c +++ b/subsys/fs/zms/zms.c @@ -1852,7 +1852,6 @@ static ssize_t zms_free_space(struct zms_fs *fs, uint32_t data_wra, uint32_t ate ssize_t zms_calc_free_space(struct zms_fs *fs) { int rc; - int previous_sector_num = ZMS_INVALID_SECTOR_NUM; int prev_found = 0; int sec_closed; struct zms_ate step_ate; @@ -1860,10 +1859,11 @@ ssize_t zms_calc_free_space(struct zms_fs *fs) struct zms_ate empty_ate; struct zms_ate close_ate; uint64_t step_addr; - uint64_t wlk_addr; uint64_t step_prev_addr; - uint64_t wlk_prev_addr; - uint64_t data_wra = 0U; + uint64_t close_addr; + uint32_t remaining_sectors; + uint32_t data_wra; + uint32_t ate_wra; uint8_t current_cycle; ssize_t free_space = 0; @@ -1872,73 +1872,70 @@ ssize_t zms_calc_free_space(struct zms_fs *fs) return -EINVAL; } - const uint32_t second_to_last_offset = (2 * fs->ate_size); - if (!fs->ready) { LOG_ERR("zms not initialized"); return -EACCES; } - /* - * There is always a closing ATE , an empty ATE, a GC_done ATE and a reserved ATE for - * deletion in each sector. - * And there is always one reserved Sector for garbage collection operations - */ - free_space = (fs->sector_count - 1) * (fs->sector_size - 4 * fs->ate_size); - step_addr = fs->ate_wra; + current_cycle = fs->sector_cycle; + /* there is always one reserved sector for garbage collection */ + remaining_sectors = fs->sector_count - 1; - do { - step_prev_addr = step_addr; - rc = zms_prev_ate(fs, &step_addr, &step_ate); - if (rc) { - return rc; - } + while (1) { + /* Count entries in the current sector as if it were garbage-collected. + * Initialize data_wra and ate_wra as they would be in an empty sector + * (with bottom space reserved for empty ATE, close ATE, and GC_done ATE). + */ + data_wra = 0; + ate_wra = fs->sector_size - 4 * fs->ate_size; - /* When changing the sector let's get the new cycle counter */ - rc = zms_get_cycle_on_sector_change(fs, step_prev_addr, previous_sector_num, - ¤t_cycle); - if (rc) { - return rc; - } - previous_sector_num = SECTOR_NUM(step_prev_addr); + for (close_addr = zms_close_ate_addr(fs, step_addr); step_addr < close_addr; + step_addr += fs->ate_size) { + rc = zms_flash_ate_rd(fs, step_addr, &step_ate); + if (rc) { + return rc; + } - /* Invalid and deleted ATEs are free spaces. - * Header ATEs are already retrieved from free space - */ - if (!zms_ate_valid_different_sector(fs, &step_ate, current_cycle) || - (step_ate.id == ZMS_HEAD_ID) || (step_ate.len == 0)) { - continue; - } + /* Invalid and deleted ATEs are free spaces. + * Header ATEs are already retrieved from free space + */ + if (!zms_ate_valid_different_sector(fs, &step_ate, current_cycle) || + (step_ate.id == ZMS_HEAD_ID) || (step_ate.len == 0)) { + continue; + } - wlk_addr = step_addr; - /* Try to find if there is a previous valid ATE with same ID */ - prev_found = zms_find_ate_with_id(fs, step_ate.id, wlk_addr, step_addr, &wlk_ate, - &wlk_prev_addr); - if (prev_found < 0) { - return prev_found; - } + /* Search for a more recent, valid ATE with the same ID */ + prev_found = zms_find_ate_with_id(fs, step_ate.id, fs->ate_wra, step_addr, + &wlk_ate, &step_prev_addr); + if (prev_found < 0) { + return prev_found; + } - /* If no previous ATE is found, then this is a valid ATE that cannot be - * Garbage Collected - */ - if (!prev_found || (wlk_prev_addr == step_prev_addr)) { - if (step_ate.len > ZMS_DATA_IN_ATE_SIZE) { - free_space -= zms_al_size(fs, step_ate.len); + if (!prev_found) { + /* this item would not have been garbage collected */ + if (step_ate.len > ZMS_DATA_IN_ATE_SIZE) { + data_wra += zms_al_size(fs, step_ate.len); + } + ate_wra -= fs->ate_size; } - free_space -= fs->ate_size; } - } while (step_addr != fs->ate_wra); - /* we must keep the sector_cycle before we start looking into special cases */ - current_cycle = fs->sector_cycle; + /* reached end of sector */ + free_space += zms_free_space(fs, data_wra, ate_wra); - /* Let's look now for special cases where some sectors have only ATEs with - * small data size. - */ + remaining_sectors--; + if (remaining_sectors == 0) { + /* explored all sectors */ + return free_space; + } - for (int i = 0; i < fs->sector_count; i++) { - step_addr = zms_close_ate_addr(fs, ((uint64_t)i << ADDR_SECT_SHIFT)); + /* jump to previous sector */ + if (SECTOR_NUM(step_addr) == 0U) { + step_addr += ((uint64_t)(fs->sector_count - 1) << ADDR_SECT_SHIFT); + } else { + step_addr -= (1ULL << ADDR_SECT_SHIFT); + } /* verify if the sector is closed */ sec_closed = zms_validate_closed_sector(fs, step_addr, &empty_ate, &close_ate); @@ -1946,28 +1943,16 @@ ssize_t zms_calc_free_space(struct zms_fs *fs) return sec_closed; } - /* If the sector is closed and its offset is pointing to a position less than the - * 3rd to last ATE position in a sector, it means that we need to leave the second - * to last ATE empty. + /* If closed, then update step_addr to point to the last ATE in this sector. + * Otherwise, this sector is empty and step_addr points to its close ATE. */ - if ((sec_closed == 1) && (close_ate.offset <= second_to_last_offset)) { - free_space -= fs->ate_size; - } else if (!sec_closed) { - /* sector is open, let's recover the last ATE */ - fs->sector_cycle = empty_ate.cycle_cnt; - rc = zms_recover_last_ate(fs, &step_addr, &data_wra); - if (rc) { - return rc; - } - if (SECTOR_OFFSET(step_addr) <= second_to_last_offset) { - free_space -= fs->ate_size; - } + if (sec_closed == 1) { + step_addr &= ADDR_SECT_MASK; + step_addr += close_ate.offset; + /* When changing the sector let's get the new cycle counter */ + current_cycle = close_ate.cycle_cnt; } } - /* restore sector cycle */ - fs->sector_cycle = current_cycle; - - return free_space; } ssize_t zms_active_sector_free_space(struct zms_fs *fs) From 0ebf13c3b7ac1d2ba073c23baf3fde0e1fa11e79 Mon Sep 17 00:00:00 2001 From: Grzegorz Swiderski Date: Mon, 27 Oct 2025 09:57:03 +0100 Subject: [PATCH 0783/3659] tests: fs: zms: Add tests for free space calculation functions Previously, there was no proper test coverage of `zms_calc_free_space()` or `zms_active_sector_free_space()`, so they had some undiscovered bugs. Signed-off-by: Grzegorz Swiderski --- tests/subsys/fs/zms/src/main.c | 276 +++++++++++++++++++++++++++++++++ 1 file changed, 276 insertions(+) diff --git a/tests/subsys/fs/zms/src/main.c b/tests/subsys/fs/zms/src/main.c index 05f4c25153c2..bc5b78fc98f5 100644 --- a/tests/subsys/fs/zms/src/main.c +++ b/tests/subsys/fs/zms/src/main.c @@ -1009,3 +1009,279 @@ ZTEST_F(zms, test_zms_id_64bit) zassert_true(len == -ENOENT, "zms_read_hist unexpected failure: %d", len); } } + +/* + * Test zms_active_sector_free_space() and zms_calc_free_space(). + */ +ZTEST_F(zms, test_zms_free_space) +{ + const size_t max_space_in_sector = fixture->fs.sector_size - sizeof(struct zms_ate) * 5; + size_t free_space_sector; + size_t free_space_total; + size_t write_len; + ssize_t len; + zms_id_t id; + int err; + char write_buf[max_space_in_sector + 1]; + + fixture->fs.sector_count = 2; + + err = zms_mount(&fixture->fs); + zassert_true(err == 0, "zms_mount call failure: %d", err); + + /* Set and verify the initial values of free_space_sector and free_space_total */ + + free_space_sector = max_space_in_sector; + zassert_equal(free_space_sector, zms_active_sector_free_space(&fixture->fs), + "unexpected free space in empty sector"); + free_space_total = max_space_in_sector; + zassert_equal(free_space_total, zms_calc_free_space(&fixture->fs), + "unexpected free space in empty filesystem"); + + id = 0; + + len = zms_write(&fixture->fs, id, write_buf, sizeof(write_buf)); + zassert_true(len == -EINVAL, "zms_write unexpected failure: %d", len); + + do { + /* fill the filesystem with a single entry */ + write_len = free_space_total; + len = zms_write(&fixture->fs, id, write_buf, write_len); + zassert_true(len == write_len, "zms_write failed: %d", len); + zassert_equal(0, zms_active_sector_free_space(&fixture->fs), + "expected sector to appear full"); + zassert_equal(0, zms_calc_free_space(&fixture->fs), + "expected filesystem to appear full"); + + /* no space in filesystem -> next write must fail */ + len = zms_write(&fixture->fs, id + 1, write_buf, 1); + zassert_true(len == -ENOSPC, "zms_write unexpected failure: %d", len); + + /* drop the filler entry; expect delete ATE to fit in the active sector */ + err = zms_delete(&fixture->fs, id); + zassert_true(err == 0, "zms_delete call failure: %d", err); + zassert_equal(0, zms_active_sector_free_space(&fixture->fs), + "expected sector to appear full"); + zassert_equal(free_space_total, zms_calc_free_space(&fixture->fs), + "unexpected total free space"); + + /* Check cases where the active sector is filled in such a way + * that there is only room for one ATE, and there is more space + * for data to be stored within that ATE, than outside of it. + * The calculated free space shall be ZMS_DATA_IN_ATE_SIZE. + */ + write_len -= sizeof(struct zms_ate); + while (write_len > ZMS_DATA_IN_ATE_SIZE) { + len = zms_write(&fixture->fs, id, write_buf, write_len); + zassert_true(len == write_len, "zms_write failed: %d", len); + zassert_equal(ZMS_DATA_IN_ATE_SIZE, + zms_active_sector_free_space(&fixture->fs), + "unexpected free space in active sector"); + zassert_equal(ZMS_DATA_IN_ATE_SIZE, zms_calc_free_space(&fixture->fs), + "unexpected total free space"); + + /* no space for data outside of ATE -> next write must fail */ + len = zms_write(&fixture->fs, id + 1, write_buf, ZMS_DATA_IN_ATE_SIZE + 1); + zassert_true(len == -ENOSPC, "zms_write unexpected failure: %d", len); + + /* add ATE with data inside it */ + len = zms_write(&fixture->fs, id + 1, write_buf, ZMS_DATA_IN_ATE_SIZE); + zassert_true(len == ZMS_DATA_IN_ATE_SIZE, "zms_write failed: %d", len); + zassert_equal(0, zms_active_sector_free_space(&fixture->fs), + "expected sector to appear full"); + zassert_equal(0, zms_calc_free_space(&fixture->fs), + "expected filesystem to appear full"); + + /* cleanup; expect delete ATE to fit in the active sector */ + err = zms_delete(&fixture->fs, id + 1); + zassert_true(err == 0, "zms_delete call failure: %d", err); + zassert_equal(0, zms_active_sector_free_space(&fixture->fs), + "expected sector to appear full"); + zassert_equal(ZMS_DATA_IN_ATE_SIZE, zms_calc_free_space(&fixture->fs), + "unexpected total free space"); + + err = zms_delete(&fixture->fs, id); + zassert_true(err == 0, "zms_delete call failure: %d", err); + zassert_equal(0, zms_active_sector_free_space(&fixture->fs), + "expected sector to appear full"); + zassert_equal(free_space_total, zms_calc_free_space(&fixture->fs), + "unexpected total free space"); + + write_len -= fixture->fs.flash_parameters->write_block_size; + + if (write_len < + (free_space_total - sizeof(struct zms_ate) - ZMS_DATA_IN_ATE_SIZE)) { + break; + } + } + + /* add small data ATE with unique ID; these will accumulate until the loop ends */ + len = zms_write(&fixture->fs, id, write_buf, 1); + zassert_true(len == 1, "zms_write failed: %d", len); + id++; + + free_space_sector -= sizeof(struct zms_ate); + zassert_equal(free_space_sector, zms_active_sector_free_space(&fixture->fs), + "unexpected free space in active sector"); + free_space_total = free_space_sector; + zassert_equal(free_space_total, zms_calc_free_space(&fixture->fs), + "unexpected total free space"); + } while (free_space_total > 0); + + /* Filesystem is filled with small data ATEs, now delete them all */ + + for (zms_id_t delete_id = 0; delete_id < id; delete_id++) { + err = zms_delete(&fixture->fs, delete_id); + zassert_true(err == 0, "zms_delete call failure: %d", err); + + free_space_total += sizeof(struct zms_ate); + zassert_equal(free_space_total, zms_calc_free_space(&fixture->fs), + "unexpected total free space"); + + if (free_space_sector == 0) { + free_space_sector = free_space_total; + zassert_equal(0, zms_active_sector_free_space(&fixture->fs), + "unexpected free space in active sector"); + } else { + free_space_sector -= sizeof(struct zms_ate); + zassert_equal(free_space_sector, zms_active_sector_free_space(&fixture->fs), + "unexpected free space in active sector"); + } + } + zassert_equal(free_space_total, max_space_in_sector, "expected file system to be empty"); + + /* Trigger garbage-collection */ + + err = zms_sector_use_next(&fixture->fs); + zassert_true(err == 0, "zms_sector_use_next call failure: %d", err); + + free_space_sector = max_space_in_sector; + zassert_equal(free_space_sector, zms_active_sector_free_space(&fixture->fs), + "unexpected free space in empty sector"); + zassert_equal(free_space_total, zms_calc_free_space(&fixture->fs), + "total free space should not have changed"); + + /* Finally, fill the active sector with redundant entries */ + + write_len = 64; + len = zms_write(&fixture->fs, id, write_buf, write_len); + zassert_true(len == write_len, "zms_write failed: %d", len); + + free_space_sector -= (write_len + sizeof(struct zms_ate)); + zassert_equal(free_space_sector, zms_active_sector_free_space(&fixture->fs), + "unexpected free space in active sector"); + free_space_total -= (write_len + sizeof(struct zms_ate)); + zassert_equal(free_space_total, zms_calc_free_space(&fixture->fs), + "unexpected total free space"); + +#ifndef CONFIG_ZMS_NO_DOUBLE_WRITE + while (free_space_sector >= (write_len + sizeof(struct zms_ate))) { + len = zms_write(&fixture->fs, id, write_buf, write_len); + zassert_true(len == write_len, "zms_write failed: %d", len); + + free_space_sector -= (write_len + sizeof(struct zms_ate)); + zassert_equal(free_space_sector, zms_active_sector_free_space(&fixture->fs), + "unexpected free space in active sector"); + zassert_equal(free_space_total, zms_calc_free_space(&fixture->fs), + "total free space should not have changed"); + } +#else + /* With no double write, the above loop would never terminate */ + len = zms_write(&fixture->fs, id, write_buf, write_len); + zassert_true(len == 0, "zms_write failed: %d", len); + + zassert_equal(free_space_sector, zms_active_sector_free_space(&fixture->fs), + "active sector free space should not have changed"); + zassert_equal(free_space_total, zms_calc_free_space(&fixture->fs), + "total free space should not have changed"); +#endif +} + +/* + * Test zms_calc_free_space() with more than 2 sectors. + * This is to exercise its handling of closed sectors. + */ +ZTEST_F(zms, test_zms_free_space_5sectors) +{ + const size_t max_space_in_sector = fixture->fs.sector_size - sizeof(struct zms_ate) * 5; + size_t free_space_total; + int err; + char write_buf[max_space_in_sector]; + + fixture->fs.sector_count = 5; + + err = zms_mount(&fixture->fs); + zassert_true(err == 0, "zms_mount call failure: %d", err); + + free_space_total = max_space_in_sector * (fixture->fs.sector_count - 1); + zassert_equal(free_space_total, zms_calc_free_space(&fixture->fs), + "unexpected free space in empty filesystem"); + + /* Sector 1: add 3 new ATEs */ + + zms_write(&fixture->fs, 0, write_buf, 100); + zms_write(&fixture->fs, 1, write_buf, 200); + zms_write(&fixture->fs, 2, write_buf, 300); + + free_space_total -= (100 + 200 + 300 + 3 * sizeof(struct zms_ate)); + zassert_equal(free_space_total, zms_calc_free_space(&fixture->fs), + "unexpected total free space"); + + err = zms_sector_use_next(&fixture->fs); + zassert_true(err == 0, "zms_sector_use_next call failure: %d", err); + zassert_equal(free_space_total, zms_calc_free_space(&fixture->fs), + "total free space should not have changed"); + + /* Sector 2: add 1 new ATE and update 1 existing ATE */ + + zms_write(&fixture->fs, 3, write_buf, 100); + zms_write(&fixture->fs, 1, write_buf, 800); + + free_space_total -= (100 + (800 - 200) + sizeof(struct zms_ate)); + zassert_equal(free_space_total, zms_calc_free_space(&fixture->fs), + "unexpected total free space"); + + err = zms_sector_use_next(&fixture->fs); + zassert_true(err == 0, "zms_sector_use_next call failure: %d", err); + zassert_equal(free_space_total, zms_calc_free_space(&fixture->fs), + "total free space should not have changed"); + + /* Sector 3: add 2 new ATEs */ + + zms_write(&fixture->fs, 4, write_buf, max_space_in_sector - sizeof(struct zms_ate)); + zms_write(&fixture->fs, 5, write_buf, ZMS_DATA_IN_ATE_SIZE); + + free_space_total -= max_space_in_sector; + zassert_equal(free_space_total, zms_calc_free_space(&fixture->fs), + "unexpected total free space"); + + err = zms_sector_use_next(&fixture->fs); + zassert_true(err == 0, "zms_sector_use_next call failure: %d", err); + zassert_equal(free_space_total, zms_calc_free_space(&fixture->fs), + "total free space should not have changed"); + + /* Sector 4: update 1 existing ATE */ + + zms_write(&fixture->fs, 4, write_buf, max_space_in_sector); + + free_space_total -= sizeof(struct zms_ate); + zassert_equal(free_space_total, zms_calc_free_space(&fixture->fs), + "unexpected total free space"); + + err = zms_sector_use_next(&fixture->fs); + zassert_true(err == 0, "zms_sector_use_next call failure: %d", err); + zassert_equal(free_space_total, zms_calc_free_space(&fixture->fs), + "total free space should not have changed"); + + /* GC all sectors and verify relation with zms_active_sector_free_space() */ + + free_space_total = 0; + for (int i = 0; i < fixture->fs.sector_count - 1; i++) { + free_space_total += zms_active_sector_free_space(&fixture->fs); + + err = zms_sector_use_next(&fixture->fs); + zassert_true(err == 0, "zms_sector_use_next call failure: %d", err); + } + zassert_equal(free_space_total, zms_calc_free_space(&fixture->fs), + "total free space did not match sum of gc'd sectors"); +} From 298798a4b839175e48312b2886ca009f8b83715a Mon Sep 17 00:00:00 2001 From: Grzegorz Swiderski Date: Mon, 27 Oct 2025 09:57:03 +0100 Subject: [PATCH 0784/3659] tests: fs: zms: Refine test_zms_id_64bit By request, add another loop to fill an extra sector with small data entries only (4 bytes per entry in the 64 bit ID case). This should cover ZMS' special case handling of different data sizes. Signed-off-by: Grzegorz Swiderski --- tests/subsys/fs/zms/src/main.c | 57 +++++++++++++++++++++++++++------- 1 file changed, 45 insertions(+), 12 deletions(-) diff --git a/tests/subsys/fs/zms/src/main.c b/tests/subsys/fs/zms/src/main.c index bc5b78fc98f5..06d20f6153b6 100644 --- a/tests/subsys/fs/zms/src/main.c +++ b/tests/subsys/fs/zms/src/main.c @@ -975,8 +975,11 @@ ZTEST_F(zms, test_zms_id_64bit) { int err; ssize_t len; - uint64_t data; - uint64_t filling_id = 0xdeadbeefULL; + uint64_t data_wra; + uint64_t filling_id_1 = 0xdeadbeefULL; + uint64_t filling_id_2 = 0xdefacedbULL; + uint64_t data_1; + uint32_t data_2; Z_TEST_SKIP_IFNDEF(CONFIG_ZMS_ID_64BIT); @@ -985,27 +988,57 @@ ZTEST_F(zms, test_zms_id_64bit) /* Fill the first sector with writes of different IDs */ - while (fixture->fs.data_wra + sizeof(data) + sizeof(struct zms_ate) <= + while (fixture->fs.data_wra + sizeof(data_1) + sizeof(struct zms_ate) <= fixture->fs.ate_wra) { - data = filling_id; - len = zms_write(&fixture->fs, (zms_id_t)filling_id, &data, sizeof(data)); - zassert_true(len == sizeof(data), "zms_write failed: %d", len); + data_1 = filling_id_1; + len = zms_write(&fixture->fs, (zms_id_t)filling_id_1, &data_1, sizeof(data_1)); + zassert_true(len == sizeof(data_1), "zms_write failed: %d", len); /* Choose the next ID so that its lower 32 bits stay invariant. * The purpose is to test that ZMS doesn't mistakenly cast the * 64 bit ID to a 32 bit one somewhere. */ - filling_id += BIT64(32); + filling_id_1 += BIT64(32); + } + + /* Fill the second sector similarly, except with small data in ATE */ + + err = zms_sector_use_next(&fixture->fs); + zassert_true(err == 0, "zms_sector_use_next call failure: %d", err); + + data_wra = fixture->fs.data_wra; + while (data_wra + sizeof(data_2) + sizeof(struct zms_ate) <= fixture->fs.ate_wra) { + /* Again, the lower 32 bits are invariant, so use the upper bits + * to get unique data contents. + */ + data_2 = (uint32_t)(filling_id_2 >> 32); + len = zms_write(&fixture->fs, (zms_id_t)filling_id_2, &data_2, sizeof(data_2)); + zassert_true(len == sizeof(data_2), "zms_write failed: %d", len); + + /* Expect no data to be stored outside of the ATE */ + zassert_equal(data_wra, fixture->fs.data_wra, "data_wra should not have changed"); + + filling_id_2 += BIT64(32); } /* Read back the written entries and check that they're all unique */ - for (uint64_t id = 0xdeadbeefULL; id < filling_id; id += BIT64(32)) { - len = zms_read_hist(&fixture->fs, (zms_id_t)id, &data, sizeof(data), 0); - zassert_true(len == sizeof(data), "zms_read_hist unexpected failure: %d", len); - zassert_equal(data, id, "read unexpected data: %llx instead of %llx", data, id); + for (uint64_t id = 0xdeadbeefULL; id < filling_id_1; id += BIT64(32)) { + len = zms_read_hist(&fixture->fs, (zms_id_t)id, &data_1, sizeof(data_1), 0); + zassert_true(len == sizeof(data_1), "zms_read_hist unexpected failure: %d", len); + zassert_equal(id, data_1, "read unexpected data for id %llx: %llx", id, data_1); + + len = zms_read_hist(&fixture->fs, (zms_id_t)id, &data_1, sizeof(data_1), 1); + zassert_true(len == -ENOENT, "zms_read_hist unexpected failure: %d", len); + } + + for (uint64_t id = 0xdefacedbULL; id < filling_id_2; id += BIT64(32)) { + len = zms_read_hist(&fixture->fs, (zms_id_t)id, &data_2, sizeof(data_2), 0); + zassert_true(len == sizeof(data_2), "zms_read_hist unexpected failure: %d", len); + zassert_equal((uint32_t)(id >> 32), data_2, "read unexpected data for id %llx: %x", + id, data_2); - len = zms_read_hist(&fixture->fs, (zms_id_t)id, &data, sizeof(data), 1); + len = zms_read_hist(&fixture->fs, (zms_id_t)id, &data_2, sizeof(data_2), 1); zassert_true(len == -ENOENT, "zms_read_hist unexpected failure: %d", len); } } From 83d3092d30adddb6107845bafc0bce4a9a9dc817 Mon Sep 17 00:00:00 2001 From: Grzegorz Swiderski Date: Mon, 27 Oct 2025 09:57:03 +0100 Subject: [PATCH 0785/3659] samples: fs: zms: Update to showcase 64 bit ID support ZMS IDs are not necessarily 32 bit anymore, so the sample ought to reflect that. When the sample is built with CONFIG_ZMS_ID_64BIT=y, the KEY_VALUE_ID will use a 64 bit value, chosen so that it would conflict with CNT_ID only if 64 bit IDs were not handled properly. Signed-off-by: Grzegorz Swiderski --- samples/subsys/fs/zms/sample.yaml | 12 ++++++++++++ samples/subsys/fs/zms/src/main.c | 16 ++++++++-------- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/samples/subsys/fs/zms/sample.yaml b/samples/subsys/fs/zms/sample.yaml index c28770ec78a8..d82d02d2dbe1 100644 --- a/samples/subsys/fs/zms/sample.yaml +++ b/samples/subsys/fs/zms/sample.yaml @@ -12,3 +12,15 @@ tests: type: one_line regex: - "Sample code finished Successfully" + sample.zms.id_64bit: + extra_configs: + - CONFIG_ZMS_ID_64BIT=y + tags: zms + platform_allow: + - qemu_x86 + - native_sim + harness: console + harness_config: + type: one_line + regex: + - "Sample code finished Successfully" diff --git a/samples/subsys/fs/zms/src/main.c b/samples/subsys/fs/zms/src/main.c index a9615823608f..a17ffd68f72d 100644 --- a/samples/subsys/fs/zms/src/main.c +++ b/samples/subsys/fs/zms/src/main.c @@ -22,11 +22,11 @@ static struct zms_fs fs; #define ZMS_PARTITION_OFFSET FIXED_PARTITION_OFFSET(ZMS_PARTITION) #define IP_ADDRESS_ID 1 -#define KEY_VALUE_ID 0xbeefdead +#define KEY_VALUE_ID COND_CODE_1(CONFIG_ZMS_ID_64BIT, (0xbeefdead00000002ULL), (0xbeefdeadULL)) #define CNT_ID 2 #define LONG_DATA_ID 3 -static int delete_and_verify_items(struct zms_fs *fs, uint32_t id) +static int delete_and_verify_items(struct zms_fs *fs, zms_id_t id) { int rc = 0; @@ -59,7 +59,7 @@ static int delete_basic_items(struct zms_fs *fs) } rc = delete_and_verify_items(fs, KEY_VALUE_ID); if (rc) { - printk("Error while deleting item %x rc=%d\n", KEY_VALUE_ID, rc); + printk("Error while deleting item %llx rc=%d\n", KEY_VALUE_ID, rc); return rc; } rc = delete_and_verify_items(fs, CNT_ID); @@ -82,7 +82,7 @@ int main(void) uint8_t key[8] = {0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF}, longarray[128]; uint32_t i_cnt = 0U; uint32_t i; - uint32_t id = 0; + zms_id_t id = 0; ssize_t free_space = 0; struct flash_pages_info info; @@ -141,14 +141,14 @@ int main(void) */ rc = zms_read(&fs, KEY_VALUE_ID, &key, sizeof(key)); if (rc > 0) { /* item was found, show it */ - printk("Id: %x, Key: ", KEY_VALUE_ID); + printk("Id: %llx, Key: ", KEY_VALUE_ID); for (uint8_t n = 0; n < 8; n++) { printk("%x ", key[n]); } printk("\n"); } /* Rewriting KEY_VALUE even if we found it */ - printk("Adding key/value at id %x\n", KEY_VALUE_ID); + printk("Adding key/value at id %llx\n", KEY_VALUE_ID); rc = zms_write(&fs, KEY_VALUE_ID, &key, sizeof(key)); if (rc < 0) { printk("Error while writing Entry rc=%d\n", rc); @@ -230,10 +230,10 @@ int main(void) printk("Memory is full let's delete all items\n"); /* Now delete all previously written items */ - for (uint32_t n = 0; n < id; n++) { + for (uint64_t n = 0; n < id; n++) { rc = delete_and_verify_items(&fs, n); if (rc) { - printk("Error deleting at id %u\n", n); + printk("Error deleting at id %llu\n", n); return 0; } } From 3a8c9797ca13fbd9246fd17adbcda1bf20309ed7 Mon Sep 17 00:00:00 2001 From: Peter Mitsis Date: Thu, 18 Dec 2025 11:07:32 -0800 Subject: [PATCH 0786/3659] kernel: Re-instate metaIRQ z_is_thread_ready() check Re-instate a z_is_thread_ready() check on the preempted metaIRQ thread before selecting it as the preferred next thread to schedule. This code exists because of a corner case where it is possible for the thread that was recorded as being pre-empted by a meta-IRQ thread can be marked as not 'ready to run' when the meta-IRQ thread(s) complete. Such a scenario may occur if an interrupt ... 1. suspends the interrupted thread, then 2. readies a meta-IRQ thread, then 3. exits The resulting reschedule can result in the suspended interrupted thread being recorded as being interrupted by a meta-IRQ thread. There may be other scenarios too. Fixes #101296 Signed-off-by: Peter Mitsis --- kernel/sched.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/kernel/sched.c b/kernel/sched.c index 1b40c93bf6fd..9f45fc5c4440 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -193,7 +193,11 @@ static ALWAYS_INLINE struct k_thread *next_up(void) struct k_thread *mirqp = _current_cpu->metairq_preempted; if (mirqp != NULL && (thread == NULL || !thread_is_metairq(thread))) { - thread = mirqp; + if (z_is_thread_ready(mirqp)) { + thread = mirqp; + } else { + _current_cpu->metairq_preempted = NULL; + } } #endif /* CONFIG_NUM_METAIRQ_PRIORITIES > 0 */ From 81ac3f9a7fce2d735804055efbe4d83dea33b507 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Thu, 18 Dec 2025 21:52:02 +0100 Subject: [PATCH 0787/3659] include: Bluetooth: Host: add doxygen docs for GAP timer macros MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This adds proper doxygen documentation for the GAP timers macros. Signed-off-by: Benjamin Cabé --- include/zephyr/bluetooth/gap.h | 66 ++++++++++++++++++++++------------ 1 file changed, 44 insertions(+), 22 deletions(-) diff --git a/include/zephyr/bluetooth/gap.h b/include/zephyr/bluetooth/gap.h index b446ad521d4c..9324ea418d26 100644 --- a/include/zephyr/bluetooth/gap.h +++ b/include/zephyr/bluetooth/gap.h @@ -36,30 +36,52 @@ extern "C" { */ /** - * @name Defined GAP timers + * @name Defined GAP timers. + * As per Bluetooth Core Specification 6.2, Vol 3, Part C, Appendix A. * @{ */ -#define BT_GAP_SCAN_FAST_INTERVAL_MIN 0x0030 /* 30 ms */ -#define BT_GAP_SCAN_FAST_INTERVAL 0x0060 /* 60 ms */ -#define BT_GAP_SCAN_FAST_WINDOW 0x0030 /* 30 ms */ -#define BT_GAP_SCAN_SLOW_INTERVAL_1 0x0800 /* 1.28 s */ -#define BT_GAP_SCAN_SLOW_WINDOW_1 0x0012 /* 11.25 ms */ -#define BT_GAP_SCAN_SLOW_INTERVAL_2 0x1000 /* 2.56 s */ -#define BT_GAP_SCAN_SLOW_WINDOW_2 0x0012 /* 11.25 ms */ -#define BT_GAP_ADV_FAST_INT_MIN_1 0x0030 /* 30 ms */ -#define BT_GAP_ADV_FAST_INT_MAX_1 0x0060 /* 60 ms */ -#define BT_GAP_ADV_FAST_INT_MIN_2 0x00a0 /* 100 ms */ -#define BT_GAP_ADV_FAST_INT_MAX_2 0x00f0 /* 150 ms */ -#define BT_GAP_ADV_SLOW_INT_MIN 0x0640 /* 1 s */ -#define BT_GAP_ADV_SLOW_INT_MAX 0x0780 /* 1.2 s */ -#define BT_GAP_PER_ADV_FAST_INT_MIN_1 0x0018 /* 30 ms */ -#define BT_GAP_PER_ADV_FAST_INT_MAX_1 0x0030 /* 60 ms */ -#define BT_GAP_PER_ADV_FAST_INT_MIN_2 0x0050 /* 100 ms */ -#define BT_GAP_PER_ADV_FAST_INT_MAX_2 0x0078 /* 150 ms */ -#define BT_GAP_PER_ADV_SLOW_INT_MIN 0x0320 /* 1 s */ -#define BT_GAP_PER_ADV_SLOW_INT_MAX 0x03C0 /* 1.2 s */ -#define BT_GAP_INIT_CONN_INT_MIN 0x0018 /* 30 ms */ -#define BT_GAP_INIT_CONN_INT_MAX 0x0028 /* 50 ms */ +/** Recommended minimum scan interval for fast scanning. 30 ms. */ +#define BT_GAP_SCAN_FAST_INTERVAL_MIN 0x0030 +/** Recommended maximum scan interval for fast scanning. 60 ms. */ +#define BT_GAP_SCAN_FAST_INTERVAL 0x0060 +/** Recommended scan window for fast scanning. 30 ms. */ +#define BT_GAP_SCAN_FAST_WINDOW 0x0030 +/** Recommended scan interval for slow scanning (mode 1). 1.28 s. */ +#define BT_GAP_SCAN_SLOW_INTERVAL_1 0x0800 +/** Recommended scan window for slow scanning (mode 1). 11.25 ms. */ +#define BT_GAP_SCAN_SLOW_WINDOW_1 0x0012 +/** Recommended scan interval for slow scanning (mode 2). 2.56 s. */ +#define BT_GAP_SCAN_SLOW_INTERVAL_2 0x1000 +/** Recommended scan window for slow scanning (mode 2). 11.25 ms. */ +#define BT_GAP_SCAN_SLOW_WINDOW_2 0x0012 +/** Recommended minimum advertising interval for fast advertising (mode 1). 30 ms. */ +#define BT_GAP_ADV_FAST_INT_MIN_1 0x0030 +/** Recommended maximum advertising interval for fast advertising (mode 1). 60 ms. */ +#define BT_GAP_ADV_FAST_INT_MAX_1 0x0060 +/** Recommended minimum advertising interval for fast advertising (mode 2). 100 ms. */ +#define BT_GAP_ADV_FAST_INT_MIN_2 0x00a0 +/** Recommended maximum advertising interval for fast advertising (mode 2). 150 ms. */ +#define BT_GAP_ADV_FAST_INT_MAX_2 0x00f0 +/** Recommended minimum advertising interval for slow advertising. 1 s. */ +#define BT_GAP_ADV_SLOW_INT_MIN 0x0640 +/** Recommended maximum advertising interval for slow advertising. 1.2 s. */ +#define BT_GAP_ADV_SLOW_INT_MAX 0x0780 +/** Recommended minimum periodic advertising interval for fast advertising (mode 1). 30 ms. */ +#define BT_GAP_PER_ADV_FAST_INT_MIN_1 0x0018 +/** Recommended maximum periodic advertising interval for fast advertising (mode 1). 60 ms. */ +#define BT_GAP_PER_ADV_FAST_INT_MAX_1 0x0030 +/** Recommended minimum periodic advertising interval for fast advertising (mode 2). 100 ms. */ +#define BT_GAP_PER_ADV_FAST_INT_MIN_2 0x0050 +/** Recommended maximum periodic advertising interval for fast advertising (mode 2). 150 ms. */ +#define BT_GAP_PER_ADV_FAST_INT_MAX_2 0x0078 +/** Recommended minimum periodic advertising interval for slow advertising. 1 s. */ +#define BT_GAP_PER_ADV_SLOW_INT_MIN 0x0320 +/** Recommended maximum periodic advertising interval for slow advertising. 1.2 s. */ +#define BT_GAP_PER_ADV_SLOW_INT_MAX 0x03C0 +/** Recommended minimum initial connection interval. 30 ms. */ +#define BT_GAP_INIT_CONN_INT_MIN 0x0018 +/** Recommended maximum initial connection interval. 50 ms. */ +#define BT_GAP_INIT_CONN_INT_MAX 0x0028 /** * @} */ From ae9f04b5562a823e7861652e0dc42c9fb5c0825c Mon Sep 17 00:00:00 2001 From: Camille BAUD Date: Thu, 18 Dec 2025 20:45:10 +0100 Subject: [PATCH 0788/3659] drivers: i2c: bflb: Fix I2C again Take nuclear option to handling compiler failing at compiling Signed-off-by: Camille BAUD --- drivers/i2c/i2c_bflb.c | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/drivers/i2c/i2c_bflb.c b/drivers/i2c/i2c_bflb.c index 089761a9bd24..6ebb9df39e9e 100644 --- a/drivers/i2c/i2c_bflb.c +++ b/drivers/i2c/i2c_bflb.c @@ -222,7 +222,7 @@ static int i2c_bflb_configure_freqs(const struct device *dev, uint32_t frequency return 0; } -static void i2c_bflb_trigger(const struct device *dev) +static inline void i2c_bflb_trigger(const struct device *dev) { uint32_t tmp = 0; const struct i2c_bflb_cfg *config = dev->config; @@ -232,7 +232,7 @@ static void i2c_bflb_trigger(const struct device *dev) sys_write32(tmp, config->base + I2C_CONFIG_OFFSET); } -static void i2c_bflb_detrigger(const struct device *dev) +static inline void i2c_bflb_detrigger(const struct device *dev) { uint32_t tmp = 0; const struct i2c_bflb_cfg *config = dev->config; @@ -253,7 +253,7 @@ static void i2c_bflb_detrigger(const struct device *dev) sys_write32(tmp, config->base + I2C_INT_STS_OFFSET); } -static int i2c_bflb_triggered(const struct device *dev) +static inline int i2c_bflb_triggered(const struct device *dev) { const struct i2c_bflb_cfg *config = dev->config; @@ -376,7 +376,7 @@ static void i2c_bflb_set_address(const struct device *dev, uint32_t address, boo sys_write32(tmp, config->base + I2C_CONFIG_OFFSET); } -static bool i2c_bflb_busy(const struct device *dev) +static inline bool i2c_bflb_busy(const struct device *dev) { const struct i2c_bflb_cfg *config = dev->config; uint32_t tmp = sys_read32(config->base + I2C_BUS_BUSY_OFFSET); @@ -384,7 +384,7 @@ static bool i2c_bflb_busy(const struct device *dev) return (tmp & I2C_STS_I2C_BUS_BUSY) != 0; } -static bool i2c_bflb_ended(const struct device *dev) +static inline bool i2c_bflb_ended(const struct device *dev) { const struct i2c_bflb_cfg *config = dev->config; uint32_t tmp = sys_read32(config->base + I2C_INT_STS_OFFSET); @@ -392,7 +392,7 @@ static bool i2c_bflb_ended(const struct device *dev) return (tmp & I2C_END_INT) != 0; } -static bool i2c_bflb_nacked(const struct device *dev) +static inline bool i2c_bflb_nacked(const struct device *dev) { const struct i2c_bflb_cfg *config = dev->config; uint32_t tmp = sys_read32(config->base + I2C_INT_STS_OFFSET); @@ -400,7 +400,7 @@ static bool i2c_bflb_nacked(const struct device *dev) return (tmp & I2C_NAK_INT) != 0; } -static bool i2c_bflb_errored(const struct device *dev) +static inline bool i2c_bflb_errored(const struct device *dev) { const struct i2c_bflb_cfg *config = dev->config; uint32_t tmp = sys_read32(config->base + I2C_INT_STS_OFFSET); @@ -408,11 +408,10 @@ static bool i2c_bflb_errored(const struct device *dev) return (tmp & I2C_ARB_INT) != 0 || (tmp & I2C_FER_INT) != 0; } -static int i2c_bflb_write(const struct device *dev, uint8_t *buf, uint8_t len) +static inline int i2c_bflb_write(const struct device *dev, uint8_t *buf, uint8_t len) { const struct i2c_bflb_cfg *config = dev->config; - /* Very important volatile! GCC will break this code if this is not volatile! */ - volatile uint32_t tmp; + uint32_t tmp; k_timepoint_t end_timeout; uint8_t j; @@ -446,11 +445,10 @@ static int i2c_bflb_write(const struct device *dev, uint8_t *buf, uint8_t len) return 0; } -static int i2c_bflb_read(const struct device *dev, uint8_t *buf, uint8_t len) +static inline int i2c_bflb_read(const struct device *dev, uint8_t *buf, uint8_t len) { const struct i2c_bflb_cfg *config = dev->config; - /* Very important volatile! GCC will break this code if this is not volatile! */ - volatile uint32_t tmp; + uint32_t tmp; k_timepoint_t end_timeout; uint8_t j; @@ -482,7 +480,7 @@ static int i2c_bflb_read(const struct device *dev, uint8_t *buf, uint8_t len) return 0; } -static int i2c_bflb_prepare_transfer(const struct device *dev, +static inline int i2c_bflb_prepare_transfer(const struct device *dev, struct i2c_msg *msgs, uint8_t num_msgs) { struct i2c_bflb_data *data = dev->data; @@ -528,14 +526,14 @@ static int i2c_bflb_prepare_transfer(const struct device *dev, return i; } -static int i2c_bflb_transfer(const struct device *dev, +/* GCC somehow keeps mangling that function into nonfunctionality. Nuke optimization. */ +__no_optimization static int i2c_bflb_transfer(const struct device *dev, struct i2c_msg *msgs, uint8_t num_msgs, uint16_t addr) { struct i2c_bflb_data *data = dev->data; - /* Very important volatile! GCC will break this code if this is not volatile! */ - volatile k_timepoint_t end_timeout = sys_timepoint_calc(K_MSEC(I2C_WAIT_TIMEOUT_MS)); + k_timepoint_t end_timeout = sys_timepoint_calc(K_MSEC(I2C_WAIT_TIMEOUT_MS)); bool addr_10b = false; int ret; uint8_t *p; From 348ae31ccce003257fc5340cbaba0bf25f9df96c Mon Sep 17 00:00:00 2001 From: Derek Snell Date: Thu, 18 Dec 2025 16:28:49 -0500 Subject: [PATCH 0789/3659] doc: nxp: add link to Board Support Status Adds to common footer for all board doc pages. Signed-off-by: Derek Snell --- boards/nxp/common/board-footer.rst.inc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/boards/nxp/common/board-footer.rst.inc b/boards/nxp/common/board-footer.rst.inc index 65740d828c3d..1221f6f464f9 100644 --- a/boards/nxp/common/board-footer.rst.inc +++ b/boards/nxp/common/board-footer.rst.inc @@ -1,11 +1,15 @@ Support Resources for Zephyr ============================ +- `NXP Board Support Status`_ - `NXP Zephyr Downstream Software Development Kit`_ - `MCUXpresso for VS Code`_, `wiki`_ documentation and `Zephyr lab guides`_ - `NXP Zephyr Knowledge Hub`_ - `NXP’s Zephyr landing page`_ (including training resources) - `NXP Support Community forum for Zephyr`_ +.. _NXP Board Support Status: + https://github.com/nxp-zephyr/nxp-zsdk/blob/main/doc/releases/Board-Support-Status.md + .. _NXP Zephyr Downstream Software Development Kit: https://github.com/nxp-zephyr/nxp-zsdk From 2f47985a9e3f2a3e6b0d86e03f3a49b4aef1d0cf Mon Sep 17 00:00:00 2001 From: Jordan Yates Date: Fri, 12 Jul 2024 14:51:40 +1000 Subject: [PATCH 0790/3659] sd: sd_ops: add block_erase implementation Add a function for erasing a chunk of blocks. The SD Card Association Pt1 Simplified Physical Layer Specification recommends to erase many blocks simultaneously in order to enhance data throughput (4.3.5.1). Signed-off-by: Jordan Yates --- subsys/sd/sd_ops.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++ subsys/sd/sd_ops.h | 3 ++ 2 files changed, 82 insertions(+) diff --git a/subsys/sd/sd_ops.c b/subsys/sd/sd_ops.c index da5e0ff74f96..7011d599e84b 100644 --- a/subsys/sd/sd_ops.c +++ b/subsys/sd/sd_ops.c @@ -770,6 +770,85 @@ int card_write_blocks(struct sd_card *card, const uint8_t *wbuf, uint32_t start_ return 0; } +static int card_erase(struct sd_card *card, uint32_t start_block, uint32_t num_blocks) +{ + int ret; + struct sdhc_command cmd; + + LOG_DBG("ERASE: Sector = %u, Count = %u", start_block, num_blocks); + cmd.retries = CONFIG_SD_DATA_RETRIES; + cmd.timeout_ms = CONFIG_SD_CMD_TIMEOUT; + + cmd.opcode = SD_ERASE_BLOCK_START; + cmd.response_type = (SD_RSP_TYPE_R1 | SD_SPI_RSP_TYPE_R1); + cmd.arg = start_block; + if (!(card->flags & SD_HIGH_CAPACITY_FLAG)) { + /* Standard capacity cards use byte unit address */ + cmd.arg *= card->block_size; + } + ret = sdhc_request(card->sdhc, &cmd, NULL); + if (ret) { + LOG_DBG("SD_ERASE_BLOCK_START failed (%d)", ret); + return ret; + } + + cmd.opcode = SD_ERASE_BLOCK_END; + cmd.response_type = (SD_RSP_TYPE_R1 | SD_SPI_RSP_TYPE_R1); + cmd.arg = start_block + num_blocks - 1; + if (!(card->flags & SD_HIGH_CAPACITY_FLAG)) { + /* Standard capacity cards use byte unit address */ + cmd.arg *= card->block_size; + } + ret = sdhc_request(card->sdhc, &cmd, NULL); + if (ret) { + LOG_DBG("SD_ERASE_BLOCK_END failed (%d)", ret); + return ret; + } + + cmd.opcode = SD_ERASE_BLOCK_OPERATION; + cmd.response_type = (SD_RSP_TYPE_R1b | SD_SPI_RSP_TYPE_R1b); + cmd.arg = 0x00000000; + ret = sdhc_request(card->sdhc, &cmd, NULL); + if (ret) { + LOG_DBG("SD_ERASE_BLOCK_OPERATION failed (%d)", ret); + return ret; + } + + /* Verify card is back in transfer state after erase */ + ret = sdmmc_wait_ready(card); + if (ret) { + LOG_ERR("Card did not return to ready state"); + return -ETIMEDOUT; + } + return 0; +} + +/* Erase blocks from SD card memory card */ +int card_erase_blocks(struct sd_card *card, uint32_t start_block, uint32_t num_blocks) +{ + int ret; + + /* Overflow aware ((start_block + num_blocks) > card->block_count) */ + if (num_blocks > card->block_count || (card->block_count - num_blocks) < start_block) { + return -EINVAL; + } + if (card->type == CARD_SDIO) { + LOG_WRN("SDIO does not support MMC commands"); + return -ENOTSUP; + } + ret = k_mutex_lock(&card->lock, K_MSEC(CONFIG_SD_DATA_TIMEOUT)); + if (ret) { + LOG_WRN("Could not get SD card mutex"); + return -EBUSY; + } + ret = card_erase(card, start_block, num_blocks); + k_mutex_unlock(&card->lock); + if (ret) { + LOG_ERR("Erase failed"); + } + return ret; +} + /* IO Control handler for SD MMC */ int card_ioctl(struct sd_card *card, uint8_t cmd, void *buf) { diff --git a/subsys/sd/sd_ops.h b/subsys/sd/sd_ops.h index c12a020a018a..f9378016276f 100644 --- a/subsys/sd/sd_ops.h +++ b/subsys/sd/sd_ops.h @@ -53,6 +53,9 @@ int card_read_blocks(struct sd_card *card, uint8_t *rbuf, int card_write_blocks(struct sd_card *card, const uint8_t *wbuf, uint32_t start_block, uint32_t num_blocks); +int card_erase_blocks(struct sd_card *card, uint32_t start_block, + uint32_t num_blocks); + int card_app_command(struct sd_card *card, int relative_card_address); int sdmmc_read_status(struct sd_card *card); From 3050daaecc1fff63d1095230e0e212e2ba459856 Mon Sep 17 00:00:00 2001 From: Jordan Yates Date: Fri, 12 Jul 2024 15:05:24 +1000 Subject: [PATCH 0791/3659] storage: disk_access: add `disk_access_erase` Add the `disk_access_erase` command to complement the read and write commands. As a backwards compatible new feature, this increments the API version from `1.0.0` to `1.1.0`. Signed-off-by: Jordan Yates --- include/zephyr/drivers/disk.h | 3 ++- include/zephyr/storage/disk_access.h | 20 +++++++++++++++++++ subsys/disk/disk_access.c | 30 ++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 1 deletion(-) diff --git a/include/zephyr/drivers/disk.h b/include/zephyr/drivers/disk.h index 18b1c0f3ede3..899a3e25be5d 100644 --- a/include/zephyr/drivers/disk.h +++ b/include/zephyr/drivers/disk.h @@ -23,7 +23,7 @@ * @brief Interfaces for disks. * @defgroup disk_driver_interface Disk Access * @since 1.6 - * @version 1.0.0 + * @version 1.1.0 * @ingroup io_interfaces * @{ */ @@ -110,6 +110,7 @@ struct disk_operations { uint32_t start_sector, uint32_t num_sector); int (*write)(struct disk_info *disk, const uint8_t *data_buf, uint32_t start_sector, uint32_t num_sector); + int (*erase)(struct disk_info *disk, uint32_t start_sector, uint32_t num_sector); int (*ioctl)(struct disk_info *disk, uint8_t cmd, void *buff); }; diff --git a/include/zephyr/storage/disk_access.h b/include/zephyr/storage/disk_access.h index c06d7d1baf28..4608cb7bb67d 100644 --- a/include/zephyr/storage/disk_access.h +++ b/include/zephyr/storage/disk_access.h @@ -100,6 +100,26 @@ int disk_access_read(const char *pdrv, uint8_t *data_buf, int disk_access_write(const char *pdrv, const uint8_t *data_buf, uint32_t start_sector, uint32_t num_sector); +enum disk_access_erase_type { + /** Erase the physical bytes on the disk to their natural erase value (0x00 or 0xFF) */ + DISK_ACCESS_ERASE_PHYSICAL = 0, +}; + +/** + * @brief erase data from disk + * + * The result of this operation depends on the type of erase, as specified by @a erase_type. + * + * @param[in] pdrv Disk name + * @param[in] start_sector Start disk sector to erase + * @param[in] num_sector Number of disk sectors to erase + * @param[in] erase_type Type of erase to perform + * + * @return 0 on success, negative errno code on fail + */ +int disk_access_erase(const char *pdrv, uint32_t start_sector, uint32_t num_sector, + enum disk_access_erase_type erase_type); + /** * @brief Get/Configure disk parameters * diff --git a/subsys/disk/disk_access.c b/subsys/disk/disk_access.c index 313c937c15d3..b9512a788abc 100644 --- a/subsys/disk/disk_access.c +++ b/subsys/disk/disk_access.c @@ -118,6 +118,36 @@ int disk_access_write(const char *pdrv, const uint8_t *data_buf, return rc; } +int disk_access_erase(const char *pdrv, uint32_t start_sector, uint32_t num_sector, + enum disk_access_erase_type erase_type) +{ + struct disk_info *disk = disk_access_get_di(pdrv); + uint32_t erase_sector_size; + int rc = -EINVAL; + + /* Only support physical erase for now. + * This parameter is not passed through to the underlying disk to leave the design + * space open for future erase types (Other erase types may be dedicated functions). + */ + if (erase_type != DISK_ACCESS_ERASE_PHYSICAL) { + return -EINVAL; + } + + /* Validate sector sizes, if underlying driver exposes a way to query it */ + if (disk_access_ioctl(pdrv, DISK_IOCTL_GET_ERASE_BLOCK_SZ, &erase_sector_size) == 0) { + /* Alignment check on both start and range of erase request */ + if ((start_sector % erase_sector_size) || (num_sector % erase_sector_size)) { + return -EINVAL; + } + } + + if ((disk != NULL) && (disk->ops != NULL) && (disk->ops->erase != NULL)) { + rc = disk->ops->erase(disk, start_sector, num_sector); + } + + return rc; +} + int disk_access_ioctl(const char *pdrv, uint8_t cmd, void *buf) { struct disk_info *disk = disk_access_get_di(pdrv); From 36a926f93285652d6b13e09ff3e5936569df12ca Mon Sep 17 00:00:00 2001 From: Jordan Yates Date: Fri, 12 Jul 2024 15:08:06 +1000 Subject: [PATCH 0792/3659] disk: sdmmc: implement `disk_access_erase` Implement the `disk_access_erase` function by calling out to the lower layer SD card drivers. Signed-off-by: Jordan Yates --- drivers/disk/sdmmc_subsys.c | 9 +++++++++ include/zephyr/sd/sdmmc.h | 14 ++++++++++++++ subsys/sd/sdmmc.c | 6 ++++++ 3 files changed, 29 insertions(+) diff --git a/drivers/disk/sdmmc_subsys.c b/drivers/disk/sdmmc_subsys.c index 6fc8d7fd6e3f..76c2eaf5beb4 100644 --- a/drivers/disk/sdmmc_subsys.c +++ b/drivers/disk/sdmmc_subsys.c @@ -85,6 +85,14 @@ static int disk_sdmmc_access_write(struct disk_info *disk, const uint8_t *buf, return sdmmc_write_blocks(&data->card, buf, sector, count); } +static int disk_sdmmc_access_erase(struct disk_info *disk, uint32_t sector, uint32_t count) +{ + const struct device *dev = disk->dev; + struct sdmmc_data *data = dev->data; + + return sdmmc_erase_blocks(&data->card, sector, count); +} + static int disk_sdmmc_access_ioctl(struct disk_info *disk, uint8_t cmd, void *buf) { const struct device *dev = disk->dev; @@ -109,6 +117,7 @@ static const struct disk_operations sdmmc_disk_ops = { .status = disk_sdmmc_access_status, .read = disk_sdmmc_access_read, .write = disk_sdmmc_access_write, + .erase = disk_sdmmc_access_erase, .ioctl = disk_sdmmc_access_ioctl, }; diff --git a/include/zephyr/sd/sdmmc.h b/include/zephyr/sd/sdmmc.h index acb4e9538d15..4a67566ddea2 100644 --- a/include/zephyr/sd/sdmmc.h +++ b/include/zephyr/sd/sdmmc.h @@ -20,6 +20,20 @@ extern "C" { #endif +/** + * @brief Erase blocks from SD card + * + * @param card SD card to write from + * @param start_block first block to erase + * @param num_blocks number of blocks to erase + * @retval 0 erase succeeded + * @retval -EBUSY: card is busy with another request + * @retval -EINVAL: requested erase outside of card bounds + * @retval -ETIMEDOUT: card write timed out + * @retval -EIO: I/O error + */ +int sdmmc_erase_blocks(struct sd_card *card, uint32_t start_block, uint32_t num_blocks); + /** * @brief Write blocks to SD card from buffer * diff --git a/subsys/sd/sdmmc.c b/subsys/sd/sdmmc.c index ebcc1236291f..8ba9c2b11890 100644 --- a/subsys/sd/sdmmc.c +++ b/subsys/sd/sdmmc.c @@ -793,3 +793,9 @@ int sdmmc_write_blocks(struct sd_card *card, const uint8_t *wbuf, uint32_t start { return card_write_blocks(card, wbuf, start_block, num_blocks); } + +int sdmmc_erase_blocks(struct sd_card *card, uint32_t start_block, + uint32_t num_blocks) +{ + return card_erase_blocks(card, start_block, num_blocks); +} From e02b85a3781d4df9bbba202d5d89021b65258421 Mon Sep 17 00:00:00 2001 From: Jordan Yates Date: Fri, 12 Jul 2024 15:10:01 +1000 Subject: [PATCH 0793/3659] disk: ramdisk: implement `disk_access_erase` Implement `disk_access_erase` by setting all bytes to 0x00, with the same bounds checking as `disk_access_write`. Signed-off-by: Jordan Yates --- drivers/disk/ramdisk.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/drivers/disk/ramdisk.c b/drivers/disk/ramdisk.c index d4da37ea9d9d..71cba3902952 100644 --- a/drivers/disk/ramdisk.c +++ b/drivers/disk/ramdisk.c @@ -77,6 +77,24 @@ static int disk_ram_access_write(struct disk_info *disk, const uint8_t *buff, return 0; } +static int disk_ram_access_erase(struct disk_info *disk, uint32_t sector, + uint32_t count) +{ + const struct device *dev = disk->dev; + const struct ram_disk_config *config = dev->config; + uint32_t last_sector = sector + count; + + if (last_sector < sector || last_sector > config->sector_count) { + LOG_ERR("Sector %" PRIu32 " is outside the range %zu", + last_sector, config->sector_count); + return -EINVAL; + } + + memset(lba_to_address(dev, sector), 0, count * config->sector_size); + + return 0; +} + static int disk_ram_access_ioctl(struct disk_info *disk, uint8_t cmd, void *buff) { const struct ram_disk_config *config = disk->dev->config; @@ -122,6 +140,7 @@ static const struct disk_operations ram_disk_ops = { .status = disk_ram_access_status, .read = disk_ram_access_read, .write = disk_ram_access_write, + .erase = disk_ram_access_erase, .ioctl = disk_ram_access_ioctl, }; From 16d0daec8a6e33cfff7ab723e827b9b1d3bd32d6 Mon Sep 17 00:00:00 2001 From: Jordan Yates Date: Fri, 12 Jul 2024 15:20:38 +1000 Subject: [PATCH 0794/3659] disk: flashdisk: implement `disk_access_erase` Implement `disk_access_erase` for flash disks. Signed-off-by: Jordan Yates --- drivers/disk/flashdisk.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/drivers/disk/flashdisk.c b/drivers/disk/flashdisk.c index 37606f541390..1959f94b0ed3 100644 --- a/drivers/disk/flashdisk.c +++ b/drivers/disk/flashdisk.c @@ -427,6 +427,40 @@ static int disk_flash_access_write(struct disk_info *disk, const uint8_t *buff, return rc; } +static int disk_flash_access_erase(struct disk_info *disk, uint32_t start_sector, + uint32_t sector_count) +{ + struct flashdisk_data *ctx; + off_t fl_start, fl_end; + uint32_t size; + int rc = 0; + + ctx = CONTAINER_OF(disk, struct flashdisk_data, info); + + if (!sectors_in_range(ctx, start_sector, sector_count)) { + return -EINVAL; + } + + fl_start = ctx->offset + start_sector * ctx->sector_size; + size = (sector_count * ctx->sector_size); + fl_end = fl_start + size; + + k_mutex_lock(&ctx->lock, K_FOREVER); + + /* Erase the provided sectors */ + if (flash_erase(ctx->info.dev, fl_start, size) < 0) { + rc = -EIO; + } + /* Invalidate cache if it was pointing in this address range */ + if (ctx->cache_valid && ((fl_start <= ctx->cached_addr) && (ctx->cached_addr < fl_end))) { + ctx->cache_valid = false; + ctx->cache_dirty = false; + } + k_mutex_unlock(&ctx->lock); + + return rc; +} + static int disk_flash_access_ioctl(struct disk_info *disk, uint8_t cmd, void *buff) { int rc; @@ -466,6 +500,7 @@ static const struct disk_operations flash_disk_ops = { .status = disk_flash_access_status, .read = disk_flash_access_read, .write = disk_flash_access_write, + .erase = disk_flash_access_erase, .ioctl = disk_flash_access_ioctl, }; From f52fa40b04591f20effa1896d15e18921eb47f3d Mon Sep 17 00:00:00 2001 From: Jordan Yates Date: Fri, 12 Jul 2024 16:19:14 +1000 Subject: [PATCH 0795/3659] disk: loopback: implement `disk_access_erase` Implement `disk_access_erase`, which requires a sector sized buffer of 0's to provide to `fs_write`. Signed-off-by: Jordan Yates --- drivers/disk/loopback_disk.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/drivers/disk/loopback_disk.c b/drivers/disk/loopback_disk.c index 5fa89a6457c4..d21da5c8684c 100644 --- a/drivers/disk/loopback_disk.c +++ b/drivers/disk/loopback_disk.c @@ -93,6 +93,34 @@ static int loopback_disk_access_write(struct disk_info *disk, const uint8_t *dat return 0; } +static int loopback_disk_access_erase(struct disk_info *disk, uint32_t start_sector, + uint32_t num_sector) +{ + const uint8_t erase_bytes[CONFIG_LOOPBACK_DISK_SECTOR_SIZE] = { 0x00 }; + struct loopback_disk_access *ctx = get_ctx(disk); + + if (start_sector + num_sector > ctx->num_sectors) { + LOG_WRN("Tried to erase past end of backing file"); + return -EINVAL; + } + + int ret = fs_seek(&ctx->file, start_sector * LOOPBACK_SECTOR_SIZE, FS_SEEK_SET); + + if (ret != 0) { + LOG_ERR("Failed to seek backing file: %d", ret); + return ret; + } + + for (int i = 0; i < num_sector; i++) { + ret = fs_write(&ctx->file, erase_bytes, LOOPBACK_SECTOR_SIZE); + if (ret < 0) { + LOG_ERR("Failed to erase backing file: %d", ret); + return ret; + } + } + + return 0; +} static int loopback_disk_access_ioctl(struct disk_info *disk, uint8_t cmd, void *buff) { struct loopback_disk_access *ctx = get_ctx(disk); @@ -125,6 +153,7 @@ static const struct disk_operations loopback_disk_operations = { .status = loopback_disk_access_status, .read = loopback_disk_access_read, .write = loopback_disk_access_write, + .erase = loopback_disk_access_erase, .ioctl = loopback_disk_access_ioctl, }; From b11c0f1b600be20670c060839e515c5106535488 Mon Sep 17 00:00:00 2001 From: Jordan Yates Date: Sat, 7 Jun 2025 10:05:48 +1000 Subject: [PATCH 0796/3659] disk: sdmmc_stm32: implement `disk_access_erase` Add support for erasing blocks to the STM32 SDMMC driver. Signed-off-by: Jordan Yates --- drivers/disk/sdmmc_stm32.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/drivers/disk/sdmmc_stm32.c b/drivers/disk/sdmmc_stm32.c index fc70b3b2c14a..bde5a8fa555a 100644 --- a/drivers/disk/sdmmc_stm32.c +++ b/drivers/disk/sdmmc_stm32.c @@ -696,6 +696,29 @@ static int stm32_sdmmc_access_write(struct disk_info *disk, return err; } +static int stm32_sdmmc_access_erase(struct disk_info *disk, uint32_t sector, uint32_t count) +{ + const struct device *dev = disk->dev; + struct stm32_sdmmc_priv *priv = dev->data; + int err; + + k_sem_take(&priv->thread_lock, K_FOREVER); + + err = HAL_SD_Erase(&priv->hsd, sector, sector + count); + if (err != HAL_OK) { + LOG_ERR("sd erase block failed %d", err); + err = -EIO; + goto end; + } + + while (!stm32_sdmmc_is_card_in_transfer(&priv->hsd)) { + } + +end: + k_sem_give(&priv->thread_lock); + return err; +} + static int stm32_sdmmc_get_card_info(HandleTypeDef *hsd, CardInfoTypeDef *info) { #ifdef CONFIG_SDMMC_STM32_EMMC @@ -749,6 +772,7 @@ static const struct disk_operations stm32_sdmmc_ops = { .status = stm32_sdmmc_access_status, .read = stm32_sdmmc_access_read, .write = stm32_sdmmc_access_write, + .erase = stm32_sdmmc_access_erase, .ioctl = stm32_sdmmc_access_ioctl, }; From 8d51481128f3af090395c190bb868e64db537133 Mon Sep 17 00:00:00 2001 From: Jordan Yates Date: Fri, 12 Jul 2024 21:28:08 +1000 Subject: [PATCH 0797/3659] tests: disk: disk_access: align sector and erase sizes Ensure that `sector-size` and `erase-size` match for the test. Signed-off-by: Jordan Yates --- tests/drivers/disk/disk_access/boards/native_sim.overlay | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/drivers/disk/disk_access/boards/native_sim.overlay b/tests/drivers/disk/disk_access/boards/native_sim.overlay index c5414d6de260..565dbb84edfd 100644 --- a/tests/drivers/disk/disk_access/boards/native_sim.overlay +++ b/tests/drivers/disk/disk_access/boards/native_sim.overlay @@ -10,6 +10,7 @@ &flash0 { reg = <0x00000000 DT_SIZE_K(1024)>; + erase-block-size = <512>; partitions { compatible = "fixed-partitions"; From d2cd86800c102580d0dcc9afe7d440f7548fcaf6 Mon Sep 17 00:00:00 2001 From: Jordan Yates Date: Fri, 12 Jul 2024 15:41:17 +1000 Subject: [PATCH 0798/3659] tests: disk: disk_access: test `disk_access_erase` Test the disk erase functionality. Signed-off-by: Jordan Yates --- tests/drivers/disk/disk_access/README.txt | 7 ++ tests/drivers/disk/disk_access/src/main.c | 122 +++++++++++++++++++--- 2 files changed, 115 insertions(+), 14 deletions(-) diff --git a/tests/drivers/disk/disk_access/README.txt b/tests/drivers/disk/disk_access/README.txt index 834d7c9f7d82..dad89c572a85 100644 --- a/tests/drivers/disk/disk_access/README.txt +++ b/tests/drivers/disk/disk_access/README.txt @@ -25,3 +25,10 @@ disk devices as well. The test has the following phases: of various length to various sectors (once again, the driver must reject writes that would be outside the bounds of the disk), then performs multiple writes to the same location. + +* Erase test: Verifies that the driver can consistently erase sectors. This test + follows the same flow as the write test, but at each step erases the data + written to the disk and reads it back to ensure all data is 0x00 or 0xFF. The + test first performs writes of various length to various sectors (once again, + the driver must reject erases that would be outside the bounds of the disk), + then performs multiple erases to the same location. diff --git a/tests/drivers/disk/disk_access/src/main.c b/tests/drivers/disk/disk_access/src/main.c index 769d4047f18d..020bbadb6215 100644 --- a/tests/drivers/disk/disk_access/src/main.c +++ b/tests/drivers/disk/disk_access/src/main.c @@ -47,10 +47,11 @@ #define SECTOR_SIZE 512 /* Sector counts to read */ -#define SECTOR_COUNT1 8 -#define SECTOR_COUNT2 1 -#define SECTOR_COUNT3 29 -#define SECTOR_COUNT4 31 +#define SECTOR_COUNT1 8 +#define SECTOR_COUNT2 1 +#define SECTOR_COUNT3 29 +#define SECTOR_COUNT4 31 +#define SECTOR_COUNT_MAX 32 #define OVERFLOW_CANARY 0xDE @@ -59,10 +60,10 @@ static uint32_t disk_sector_count; static uint32_t disk_sector_size; /* + 4 to make sure the second buffer is dword-aligned for NVME */ -static uint8_t scratch_buf[2][SECTOR_COUNT4 * SECTOR_SIZE + 4]; +static uint8_t scratch_buf[2][SECTOR_COUNT_MAX * SECTOR_SIZE + 4]; #ifdef CONFIG_DISK_DRIVER_LOOPBACK -#define BACKING_PATH "/"DISK_NAME_PHYS":" +#define BACKING_PATH "/" DISK_NAME_PHYS ":" static struct loopback_disk_access lo_access; static FATFS fat_fs; @@ -126,7 +127,7 @@ static void test_setup(void) * just verify our assumed maximum size */ zassert_true(cmd_buf <= SECTOR_SIZE, - "Test will fail, SECTOR_SIZE definition must be increased"); + "Test will fail, SECTOR_SIZE definition must be increased"); } /* Reads sectors, verifying overflow does not occur */ @@ -139,7 +140,7 @@ static int read_sector(uint8_t *buf, uint32_t start, uint32_t num_sectors) rc = disk_access_read(disk_pdrv, buf, start, num_sectors); /* Check canary */ zassert_equal(buf[num_sectors * disk_sector_size], OVERFLOW_CANARY, - "Read overflowed requested length"); + "Read overflowed requested length"); return rc; /* Let calling function check return code */ } @@ -173,8 +174,7 @@ static void test_sector_read(uint8_t *buf, uint32_t num_sectors) /* Write sector of disk, and check the data to ensure it is valid * WARNING: this test is destructive- it will overwrite data on the disk! */ -static int write_sector_checked(uint8_t *wbuf, uint8_t *rbuf, - uint32_t start, uint32_t num_sectors) +static int write_sector_checked(uint8_t *wbuf, uint8_t *rbuf, uint32_t start, uint32_t num_sectors) { int rc, i; @@ -195,10 +195,34 @@ static int write_sector_checked(uint8_t *wbuf, uint8_t *rbuf, } /* Check the read data versus the written data */ zassert_mem_equal(wbuf, rbuf, num_sectors * disk_sector_size, - "Read data did not match data written to disk"); + "Read data did not match data written to disk"); return rc; } +static int erase_sector_checked(uint8_t *rbuf, uint32_t start, uint32_t num_sectors) +{ + int rc, i; + + /* Erase the specified sectors */ + rc = disk_access_erase(disk_pdrv, start, num_sectors, DISK_ACCESS_ERASE_PHYSICAL); + if (rc) { + return rc; /* Let calling function handle disk error */ + } + + /* Read the erased sectors */ + rc = read_sector(rbuf, start, num_sectors); + if (rc) { + return rc; + } + + /* All data should be equal 0x00 or 0xFF */ + for (i = 0; i < num_sectors * disk_sector_size; i++) { + zassert_true((rbuf[i] == 0x00) || (rbuf[i] == 0xFF), + "Data not erased from disk sector %u", start + i); + } + return 0; +} + /* Tests writing to a variety of sectors * WARNING: this test is destructive- it will overwrite data on the disk! */ @@ -228,6 +252,49 @@ static void test_sector_write(uint8_t *wbuf, uint8_t *rbuf, uint32_t num_sectors } } +/* Tests erasing a variety of sectors + * WARNING: this test is destructive- it will overwrite data on the disk! + */ +static void test_sector_erase(uint8_t *wbuf, uint8_t *rbuf, uint32_t num_sectors) +{ + int rc, sector; + + TC_PRINT("Testing erase of %u sectors\n", num_sectors); + /* Write and erase disk sector zero */ + rc = write_sector_checked(wbuf, rbuf, 0, num_sectors); + zassert_equal(rc, 0, "Failed to write to sector zero"); + rc = erase_sector_checked(rbuf, 0, num_sectors); + zassert_equal(rc, 0, "Failed to erase sector zero"); + + /* Write and erase sectors in the "middle" of the disk */ + if (disk_sector_count / 2 > num_sectors) { + sector = disk_sector_count / 2 - num_sectors; + } else { + sector = 0; + } + rc = write_sector_checked(wbuf, rbuf, sector, num_sectors); + zassert_equal(rc, 0, "Failed to write to mid disk sector"); + rc = erase_sector_checked(rbuf, sector, num_sectors); + zassert_equal(rc, 0, "Failed to erase mid disk sector"); + + /* Write and erase the last sector */ + rc = write_sector_checked(wbuf, rbuf, disk_sector_count - num_sectors, num_sectors); + zassert_equal(rc, 0, "Failed to write to last sector"); + rc = erase_sector_checked(rbuf, disk_sector_count - num_sectors, num_sectors); + zassert_equal(rc, 0, "Failed to erase last sector"); + + /* Try and erase past the last sector */ + rc = erase_sector_checked(rbuf, disk_sector_count - num_sectors + 1, num_sectors); + zassert_equal(rc, -EINVAL, + "Unexpected error code when attempting to erase past end of disk"); + rc = erase_sector_checked(rbuf, disk_sector_count + 1, num_sectors); + zassert_equal(rc, -EINVAL, + "Unexpected error code when attempting to erase past end of disk"); + rc = erase_sector_checked(rbuf, UINT32_MAX, num_sectors); + zassert_equal(rc, -EINVAL, + "Unexpected error code when attempting to erase past end of disk"); +} + /* Test multiple reads in series, and reading from a variety of blocks */ ZTEST(disk_driver, test_read) { @@ -248,9 +315,8 @@ ZTEST(disk_driver, test_read) memset(scratch_buf[1], 0xff, SECTOR_COUNT1 * disk_sector_size); rc = read_sector(scratch_buf[1], 0, SECTOR_COUNT1); zassert_equal(rc, 0, "Failed to read from disk at same sector location"); - zassert_mem_equal(scratch_buf[1], scratch_buf[0], - SECTOR_COUNT1 * disk_sector_size, - "Multiple reads mismatch"); + zassert_mem_equal(scratch_buf[1], scratch_buf[0], SECTOR_COUNT1 * disk_sector_size, + "Multiple reads mismatch"); } } @@ -275,6 +341,34 @@ ZTEST(disk_driver, test_write) } } +/* Test multiple erases in series, and erasing from a variety of blocks */ +ZTEST(disk_driver, test_erase) +{ + int rc, i; + + /* Skip the test if erasing not supported by the driver */ + if (disk_access_erase(disk_pdrv, 0, 1, DISK_ACCESS_ERASE_PHYSICAL) == -EINVAL) { + ztest_test_skip(); + return; + } + + /* Test erasing with a bad erase type */ + rc = disk_access_erase(disk_pdrv, 0, 1, DISK_ACCESS_ERASE_PHYSICAL + 1); + zassert_equal(-EINVAL, rc); + + /* Verify a range of erase sizes work */ + test_sector_erase(scratch_buf[0], scratch_buf[1], 8); + test_sector_erase(scratch_buf[0], scratch_buf[1], 16); + test_sector_erase(scratch_buf[0], scratch_buf[1], 24); + test_sector_erase(scratch_buf[0], scratch_buf[1], 32); + + /* Verify that multiple erases to the same location work */ + for (i = 0; i < 10; i++) { + rc = erase_sector_checked(scratch_buf[1], 0, 16); + zassert_equal(0, rc, "Failed to erase sector zero"); + } +} + static void *disk_driver_setup(void) { #ifdef CONFIG_DISK_DRIVER_LOOPBACK From fdd6cb446910b63c1faed92769d32aefd9122465 Mon Sep 17 00:00:00 2001 From: Greter Raffael Date: Wed, 27 Aug 2025 14:33:38 +0000 Subject: [PATCH 0799/3659] drivers: display: ssd1306: Allow rotation at run-time Implement set_orientation api Inverting segment_remap and com_invdir at the same time, rotates the screen by 180 degrees. Signed-off-by: Greter Raffael --- drivers/display/ssd1306.c | 53 +++++++++++++++++++++++++++++++++------ 1 file changed, 46 insertions(+), 7 deletions(-) diff --git a/drivers/display/ssd1306.c b/drivers/display/ssd1306.c index f1ed5d73a33e..60fc9a187b4a 100644 --- a/drivers/display/ssd1306.c +++ b/drivers/display/ssd1306.c @@ -66,6 +66,7 @@ struct ssd1306_config { struct ssd1306_data { enum display_pixel_format pf; + enum display_orientation orientation; }; #if (DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(solomon_ssd1306fb, i2c) || \ @@ -154,13 +155,21 @@ static inline int ssd1306_write_bus(const struct device *dev, uint8_t *buf, size return config->write_bus(dev, buf, len, command); } -static inline int ssd1306_set_panel_orientation(const struct device *dev) +static inline int ssd1306_set_panel_orientation(const struct device *dev, bool rotate_180_degrees) { const struct ssd1306_config *config = dev->config; - uint8_t cmd_buf[] = {(config->segment_remap ? SSD1306_SET_SEGMENT_MAP_REMAPED - : SSD1306_SET_SEGMENT_MAP_NORMAL), - (config->com_invdir ? SSD1306_SET_COM_OUTPUT_SCAN_FLIPPED - : SSD1306_SET_COM_OUTPUT_SCAN_NORMAL)}; + bool segment_remap = config->segment_remap; + bool com_invdir = config->com_invdir; + + if (rotate_180_degrees) { + com_invdir = !com_invdir; + segment_remap = !segment_remap; + } + + uint8_t cmd_buf[] = {(segment_remap ? SSD1306_SET_SEGMENT_MAP_REMAPED + : SSD1306_SET_SEGMENT_MAP_NORMAL), + (com_invdir ? SSD1306_SET_COM_OUTPUT_SCAN_FLIPPED + : SSD1306_SET_COM_OUTPUT_SCAN_NORMAL)}; return ssd1306_write_bus(dev, cmd_buf, sizeof(cmd_buf), true); } @@ -378,7 +387,35 @@ static void ssd1306_get_capabilities(const struct device *dev, caps->supported_pixel_formats = PIXEL_FORMAT_MONO10 | PIXEL_FORMAT_MONO01; caps->current_pixel_format = data->pf; caps->screen_info = SCREEN_INFO_MONO_VTILED; - caps->current_orientation = DISPLAY_ORIENTATION_NORMAL; + caps->current_orientation = data->orientation; +} + +static int ssd1306_set_orientation(const struct device *dev, + const enum display_orientation orientation) +{ + struct ssd1306_data *data = dev->data; + int ret; + + if (orientation == data->orientation) { + return 0; + } + + if (orientation == DISPLAY_ORIENTATION_NORMAL) { + ret = ssd1306_set_panel_orientation(dev, false); + } else if (orientation == DISPLAY_ORIENTATION_ROTATED_180) { + ret = ssd1306_set_panel_orientation(dev, true); + } else { + LOG_WRN("Unsupported orientation"); + return -ENOTSUP; + } + + if (ret) { + return ret; + } + + data->orientation = orientation; + + return 0; } static int ssd1306_set_pixel_format(const struct device *dev, @@ -450,9 +487,10 @@ static int ssd1306_init_device(const struct device *dev) return -EIO; } - if (ssd1306_set_panel_orientation(dev)) { + if (ssd1306_set_panel_orientation(dev, false)) { return -EIO; } + data->orientation = DISPLAY_ORIENTATION_NORMAL; if (!config->ssd1309_compatible) { if (ssd1306_set_charge_pump(dev)) { @@ -528,6 +566,7 @@ static DEVICE_API(display, ssd1306_driver_api) = { .set_contrast = ssd1306_set_contrast, .get_capabilities = ssd1306_get_capabilities, .set_pixel_format = ssd1306_set_pixel_format, + .set_orientation = ssd1306_set_orientation, }; #define SSD1306_CONFIG_SPI(node_id) \ From f45e1d528b4116d31588a3202bf28bf30a35012e Mon Sep 17 00:00:00 2001 From: Yangbo Lu Date: Mon, 20 Oct 2025 09:52:51 +0800 Subject: [PATCH 0800/3659] drivers: sdhc: introduce scatter gather transfer support Introduced scatter gather transfer support. Signed-off-by: Yangbo Lu --- drivers/sdhc/Kconfig | 12 ++++++++++++ include/zephyr/drivers/sdhc.h | 6 +++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/drivers/sdhc/Kconfig b/drivers/sdhc/Kconfig index d73a551ba002..3f6cef8ed987 100644 --- a/drivers/sdhc/Kconfig +++ b/drivers/sdhc/Kconfig @@ -41,6 +41,18 @@ config SDHC_BUFFER_ALIGNMENT this value if they require alignment. This represents the alignment of buffers required in bytes +config SDHC_SCATTER_GATHER_TRANSFER + bool "Scatter-Gather API" + depends on SDHC_SUPPORTS_SCATTER_GATHER_TRANSFER + help + Enable SDHC scatter-gather API. + +config SDHC_SUPPORTS_SCATTER_GATHER_TRANSFER + bool + help + Selected by host controller driver if scatter-gather transfer support + is present. + config SDHC_SUPPORTS_UHS bool help diff --git a/include/zephyr/drivers/sdhc.h b/include/zephyr/drivers/sdhc.h index 7bb5df4f3cd3..cfce0f88a435 100644 --- a/include/zephyr/drivers/sdhc.h +++ b/include/zephyr/drivers/sdhc.h @@ -1,5 +1,5 @@ /* - * Copyright 2022 NXP + * Copyright 2022, 2025 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -15,6 +15,7 @@ #include #include +#include #include /** @@ -67,6 +68,9 @@ struct sdhc_data { unsigned int block_size; /*!< Block size */ unsigned int blocks; /*!< Number of blocks */ unsigned int bytes_xfered; /*!< populated with number of bytes sent by SDHC */ +#if defined(CONFIG_SDHC_SCATTER_GATHER_TRANSFER) || defined(__DOXYGEN__) + bool is_sg_data; /*!< Is scatter gather data using net_buf data structure */ +#endif void *data; /*!< Data to transfer or receive */ int timeout_ms; /*!< data timeout in milliseconds */ }; From e212f3e8f42fe6982a538b89dc18f28ba94b2bbc Mon Sep 17 00:00:00 2001 From: Yangbo Lu Date: Fri, 17 Oct 2025 14:01:26 +0800 Subject: [PATCH 0801/3659] sd: sd_ops: initialize sdhc_data variables Initialize sdhc_data variables. Signed-off-by: Yangbo Lu --- subsys/sd/sd_ops.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/subsys/sd/sd_ops.c b/subsys/sd/sd_ops.c index 7011d599e84b..9c50ea6422b4 100644 --- a/subsys/sd/sd_ops.c +++ b/subsys/sd/sd_ops.c @@ -1,5 +1,5 @@ /* - * Copyright 2022,2024 NXP + * Copyright 2022, 2024-2025 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -205,7 +205,7 @@ static inline void sdmmc_decode_cid(struct sd_cid *cid, uint32_t *raw_cid) static int sdmmc_spi_read_cxd(struct sd_card *card, uint32_t opcode, uint32_t *cxd) { struct sdhc_command cmd; - struct sdhc_data data; + struct sdhc_data data = {0}; int ret, i; /* Use internal card buffer for data transfer */ uint32_t *cxd_be = (uint32_t *)card->card_buffer; @@ -492,7 +492,7 @@ static int card_read(struct sd_card *card, uint8_t *rbuf, uint32_t start_block, { int ret; struct sdhc_command cmd; - struct sdhc_data data; + struct sdhc_data data = {0}; /* * Note: The SD specification allows for CMD23 to be sent before a @@ -613,7 +613,7 @@ static int card_query_written(struct sd_card *card, uint32_t *num_written) { int ret; struct sdhc_command cmd; - struct sdhc_data data; + struct sdhc_data data = {0}; uint32_t *blocks = (uint32_t *)card->card_buffer; ret = card_app_command(card, card->relative_addr); @@ -656,7 +656,7 @@ static int card_write(struct sd_card *card, const uint8_t *wbuf, uint32_t start_ int ret; uint32_t blocks; struct sdhc_command cmd; - struct sdhc_data data; + struct sdhc_data data = {0}; /* * See the note in card_read() above. We will not issue CMD23 From c3a3c2bd9946e4bb77093b219ae88ea3d55f14e4 Mon Sep 17 00:00:00 2001 From: Yangbo Lu Date: Tue, 21 Oct 2025 10:37:28 +0800 Subject: [PATCH 0802/3659] drivers: sdhc: imx_usdhc: support scatter gather DMA transfer Supported scatter gather DMA transfer. Signed-off-by: Yangbo Lu --- drivers/sdhc/Kconfig.imx | 10 +++- drivers/sdhc/imx_usdhc.c | 104 ++++++++++++++++++++++++++++++++- modules/hal_nxp/CMakeLists.txt | 2 + 3 files changed, 113 insertions(+), 3 deletions(-) diff --git a/drivers/sdhc/Kconfig.imx b/drivers/sdhc/Kconfig.imx index 47bb84db553f..16f35fb27989 100644 --- a/drivers/sdhc/Kconfig.imx +++ b/drivers/sdhc/Kconfig.imx @@ -7,6 +7,7 @@ config IMX_USDHC depends on DT_HAS_NXP_IMX_USDHC_ENABLED select SDHC_SUPPORTS_UHS select SDHC_SUPPORTS_NATIVE_MODE + select SDHC_SUPPORTS_SCATTER_GATHER_TRANSFER if IMX_USDHC_DMA_SUPPORT select PINCTRL help Enable the NXP IMX SD Host controller driver @@ -38,8 +39,13 @@ config IMX_USDHC_DMA_BUFFER_SIZE help Size of USDHC ADMA descriptor buffer in bytes -endif # IMX_USDHC_DMA_SUPPORT - +config IMX_USDHC_DMA_SCATTER_GATHER_BUF_COUNT + int "Scatter-Gather buffers count allocated" + default 36 + depends on SDHC_SCATTER_GATHER_TRANSFER + help + Count of USDHC Scatter-Gather buffers allocated. +endif # IMX_USDHC_DMA_SUPPORT endif diff --git a/drivers/sdhc/imx_usdhc.c b/drivers/sdhc/imx_usdhc.c index f0b3e5a299f3..3d5059e3b9ae 100644 --- a/drivers/sdhc/imx_usdhc.c +++ b/drivers/sdhc/imx_usdhc.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 NXP + * Copyright 2022, 2025 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -47,7 +47,11 @@ enum transfer_callback_status { #define DEV_DATA(_dev) ((struct usdhc_data *)(_dev)->data) struct usdhc_host_transfer { +#ifdef CONFIG_SDHC_SCATTER_GATHER_TRANSFER + usdhc_scatter_gather_transfer_t *transfer; +#else usdhc_transfer_t *transfer; +#endif k_timeout_t command_timeout; k_timeout_t data_timeout; }; @@ -96,6 +100,9 @@ struct usdhc_data { #ifdef CONFIG_IMX_USDHC_DMA_SUPPORT uint32_t *usdhc_dma_descriptor; /* ADMA descriptor table (noncachable) */ uint32_t dma_descriptor_len; /* DMA descriptor table length in words */ +#ifdef CONFIG_SDHC_SCATTER_GATHER_TRANSFER + usdhc_scatter_gather_data_list_t sg_buf[CONFIG_IMX_USDHC_DMA_SCATTER_GATHER_BUF_COUNT]; +#endif #endif }; @@ -461,8 +468,13 @@ static int imx_usdhc_transfer(const struct device *dev, struct usdhc_host_transf /* Reset semaphore */ k_sem_reset(&dev_data->transfer_sem); #ifdef CONFIG_IMX_USDHC_DMA_SUPPORT +#ifdef CONFIG_SDHC_SCATTER_GATHER_TRANSFER + error = USDHC_TransferScatterGatherADMANonBlocking(base, &dev_data->transfer_handle, + &dma_config, request->transfer); +#else error = USDHC_TransferNonBlocking(base, &dev_data->transfer_handle, &dma_config, request->transfer); +#endif #else error = USDHC_TransferNonBlocking(base, &dev_data->transfer_handle, NULL, request->transfer); @@ -500,7 +512,11 @@ static void imx_usdhc_stop_transmission(const struct device *dev) { usdhc_command_t stop_cmd = {0}; struct usdhc_host_transfer request; +#ifdef CONFIG_SDHC_SCATTER_GATHER_TRANSFER + usdhc_scatter_gather_transfer_t transfer; +#else usdhc_transfer_t transfer; +#endif /* Send CMD12 to stop transmission */ stop_cmd.index = SD_STOP_TRANSMISSION; @@ -531,6 +547,64 @@ static int imx_usdhc_card_busy(const struct device *dev) : 1; } +#ifdef CONFIG_SDHC_SCATTER_GATHER_TRANSFER +/* Convert normal usdhc_data_t to usdhc_scatter_gather_data_t */ +static void imx_usdhc_to_sg_data(usdhc_scatter_gather_data_t *sg_data, usdhc_data_t *data) +{ + sg_data->enableAutoCommand12 = data->enableAutoCommand12; + sg_data->enableAutoCommand23 = data->enableAutoCommand23; + sg_data->enableIgnoreError = data->enableIgnoreError; + sg_data->dataType = data->dataType; + sg_data->blockSize = data->blockSize; + + if (data->rxData != NULL) { + sg_data->dataDirection = kUSDHC_TransferDirectionReceive; + sg_data->sgData.dataAddr = data->rxData; + } else { + sg_data->dataDirection = kUSDHC_TransferDirectionSend; + sg_data->sgData.dataAddr = (uint32_t *)data->txData; + } + + sg_data->sgData.dataSize = data->blockSize * data->blockCount; + sg_data->sgData.dataList = NULL; +} + +static int imx_usdhc_fill_sg_list(struct usdhc_data *dev_data, + usdhc_scatter_gather_data_t *usdhc_sg_data, + struct net_buf *sg_data) +{ + usdhc_scatter_gather_data_list_t *usg = &(usdhc_sg_data->sgData); + struct net_buf *sg = sg_data; + int i = 0; + + memset(dev_data->sg_buf, 0, sizeof(dev_data->sg_buf)); + + usg->dataAddr = (uint32_t *)sg->data; + usg->dataSize = sg->len; + + for (i = 0; i < CONFIG_IMX_USDHC_DMA_SCATTER_GATHER_BUF_COUNT; i++) { + if (sg->frags == NULL) { + return 0; + } + + /* Pick the usdhc sg buffer to set up */ + usg->dataList = &dev_data->sg_buf[i]; + + /* Move to the fragment */ + sg = sg->frags; + usg = usg->dataList; + + /* Set up data and length */ + usg->dataAddr = (uint32_t *)sg->data; + usg->dataSize = sg->len; + } + + LOG_ERR("scatter gather buffer count is not enough"); + return -ENOMEM; +} + +#endif + /* * Execute card tuning */ @@ -540,7 +614,12 @@ static int imx_usdhc_execute_tuning(const struct device *dev) usdhc_command_t cmd = {0}; usdhc_data_t data = {0}; struct usdhc_host_transfer request; +#ifdef CONFIG_SDHC_SCATTER_GATHER_TRANSFER + usdhc_scatter_gather_data_t sg_data = {0}; + usdhc_scatter_gather_transfer_t transfer; +#else usdhc_transfer_t transfer; +#endif int ret; bool retry_tuning = true; USDHC_Type *base = get_base(dev); @@ -565,7 +644,12 @@ static int imx_usdhc_execute_tuning(const struct device *dev) data.dataType = kUSDHC_TransferDataTuning; transfer.command = &cmd; +#ifdef CONFIG_SDHC_SCATTER_GATHER_TRANSFER + imx_usdhc_to_sg_data(&sg_data, &data); + transfer.data = &sg_data; +#else transfer.data = &data; +#endif /* Reset tuning circuit */ USDHC_Reset(base, kUSDHC_ResetTuning, 100U); @@ -632,7 +716,12 @@ static int imx_usdhc_request(const struct device *dev, struct sdhc_command *cmd, usdhc_command_t host_cmd = {0}; usdhc_data_t host_data = {0}; struct usdhc_host_transfer request; +#ifdef CONFIG_SDHC_SCATTER_GATHER_TRANSFER + usdhc_scatter_gather_data_t sg_data = {0}; + usdhc_scatter_gather_transfer_t transfer; +#else usdhc_transfer_t transfer; +#endif int busy_timeout = IMX_USDHC_DEFAULT_TIMEOUT; int ret = 0; int retries = (int)cmd->retries; @@ -707,7 +796,20 @@ static int imx_usdhc_request(const struct device *dev, struct sdhc_command *cmd, default: return -ENOTSUP; } +#ifdef CONFIG_SDHC_SCATTER_GATHER_TRANSFER + imx_usdhc_to_sg_data(&sg_data, &host_data); + /* sdhc is requesting scatter gather data transfer */ + if (data->is_sg_data) { + ret = imx_usdhc_fill_sg_list(dev_data, &sg_data, data->data); + if (ret != 0) { + return ret; + } + } + + transfer.data = &sg_data; +#else transfer.data = &host_data; +#endif if (data->timeout_ms == SDHC_TIMEOUT_FOREVER) { request.data_timeout = K_FOREVER; } else { diff --git a/modules/hal_nxp/CMakeLists.txt b/modules/hal_nxp/CMakeLists.txt index 7f962faaf45a..b8281b3c20ed 100644 --- a/modules/hal_nxp/CMakeLists.txt +++ b/modules/hal_nxp/CMakeLists.txt @@ -22,6 +22,8 @@ if(CONFIG_HAS_MCUX OR CONFIG_HAS_IMX_HAL OR CONFIG_HAS_NXP_S32_HAL) zephyr_compile_definitions_ifdef(CONFIG_ETH_NXP_IMX_NETC FSL_ETH_ENABLE_CACHE_CONTROL=1) + zephyr_compile_definitions_ifdef(CONFIG_SDHC_SCATTER_GATHER_TRANSFER FSL_USDHC_ENABLE_SCATTER_GATHER_TRANSFER=1) + if(CONFIG_I2S_MCUX_SAI) zephyr_compile_definitions(MCUX_SDK_SAI_ALLOW_NULL_FIFO_WATERMARK=1) endif() From 3c295aa883c6a1027e8e3c9b5bf89ef9a4b12bef Mon Sep 17 00:00:00 2001 From: Chen Xingyu Date: Tue, 18 Nov 2025 21:22:12 +0800 Subject: [PATCH 0803/3659] boards: m5stack: fire: Fix Grove PORT.C UART pinctrl According to the M5Stack Fire v2.7 documentation, the HY2.0-4P Grove PORT.C is wired to GPIO16 and GPIO17. Update the DTS pinctrl configuration to route the PORT.C UART to these pins so that the Grove connector matches the official hardware documentation. Signed-off-by: Chen Xingyu --- .../m5stack_fire/m5stack_fire-pinctrl.dtsi | 16 ++++------------ .../m5stack/m5stack_fire/m5stack_fire_procpu.dts | 2 +- 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/boards/m5stack/m5stack_fire/m5stack_fire-pinctrl.dtsi b/boards/m5stack/m5stack_fire/m5stack_fire-pinctrl.dtsi index 56e8ad104d8d..a2b9937b61a1 100644 --- a/boards/m5stack/m5stack_fire/m5stack_fire-pinctrl.dtsi +++ b/boards/m5stack/m5stack_fire/m5stack_fire-pinctrl.dtsi @@ -20,20 +20,12 @@ bias-pull-up; }; - uart1_rx_gpio33: uart1_rx_gpio33 { - pinmux = ; + uart1_tx_gpio16: uart1_tx_gpio16 { + pinmux = ; }; - uart2_rx_gpio13: uart2_rx_gpio13 { - pinmux = ; - }; - - uart2_tx_gpio14: uart2_rx_gpio14 { - pinmux = ; - }; - - uart1_tx_gpio32: uart1_tx_gpio32 { - pinmux = ; + uart1_rx_gpio17: uart1_rx_gpio17 { + pinmux = ; }; spim3_default: spim3_default { diff --git a/boards/m5stack/m5stack_fire/m5stack_fire_procpu.dts b/boards/m5stack/m5stack_fire/m5stack_fire_procpu.dts index 9cc132a6963f..884c9d24d1a2 100644 --- a/boards/m5stack/m5stack_fire/m5stack_fire_procpu.dts +++ b/boards/m5stack/m5stack_fire/m5stack_fire_procpu.dts @@ -122,7 +122,7 @@ &uart1 { status = "disabled"; current-speed = <115200>; - pinctrl-0 = <&uart1_rx_gpio33 &uart1_tx_gpio32>; + pinctrl-0 = <&uart1_tx_gpio16 &uart1_rx_gpio17>; pinctrl-names = "default"; }; From d7f6275d1cc1e6013f069d8d863d3d4f75a82594 Mon Sep 17 00:00:00 2001 From: Chen Xingyu Date: Tue, 18 Nov 2025 21:34:11 +0800 Subject: [PATCH 0804/3659] boards: m5stack: fire: Add node label for PORT.A Add a `zephyr_i2c` node label pointing to `i2c0`, which is the bus used by Units connected through Grove PORT.A. This follows the convention already used on the Core2 and CoreS3 boards. Signed-off-by: Chen Xingyu --- boards/m5stack/m5stack_fire/grove_connectors.dtsi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/boards/m5stack/m5stack_fire/grove_connectors.dtsi b/boards/m5stack/m5stack_fire/grove_connectors.dtsi index b9f7dd253e39..b5764977c7d8 100644 --- a/boards/m5stack/m5stack_fire/grove_connectors.dtsi +++ b/boards/m5stack/m5stack_fire/grove_connectors.dtsi @@ -35,4 +35,6 @@ }; }; +zephyr_i2c: &i2c0 {}; + grove_uart: &uart1 {}; From 595a8e8c11b371b35956b4b90f737ae4feed6ac7 Mon Sep 17 00:00:00 2001 From: Chen Xingyu Date: Tue, 18 Nov 2025 22:27:08 +0800 Subject: [PATCH 0805/3659] doc: migration-guide-4.4: Document M5Stack Fire pinctrl changes Add a migration entry describing the pinctrl changes on the M5Stack Fire board. Signed-off-by: Chen Xingyu --- doc/releases/migration-guide-4.4.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/releases/migration-guide-4.4.rst b/doc/releases/migration-guide-4.4.rst index 19d27563f2a4..57df54e9f2ff 100644 --- a/doc/releases/migration-guide-4.4.rst +++ b/doc/releases/migration-guide-4.4.rst @@ -34,6 +34,10 @@ Kernel Boards ****** +* m5stack_fire: Removed unused pinctrl entries for UART2, and updated the UART1 + pin mapping from GPIO32/GPIO33 to GPIO16/GPIO17 to match the documented Grove + PORT.C wiring. + Device Drivers and Devicetree ***************************** From 9b6c862121003f4f124f8ef6d8c6109cc5fe82a7 Mon Sep 17 00:00:00 2001 From: Nicolas Moreno Date: Mon, 17 Nov 2025 11:13:32 -0400 Subject: [PATCH 0806/3659] dt-bindings: mipi_dbi: fixing pulse diagrams Some diagrams on the file dt-bindings/mipi_dbi/mpi_dbi.h doesn't deploy the correponsing pulse signal, many of them the rising flag looks moved some spaces before or after the rising/falling time. This is fixed by replacing tasb with spaces Signed-off-by: Nicolas Moreno --- include/zephyr/dt-bindings/mipi_dbi/mipi_dbi.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/include/zephyr/dt-bindings/mipi_dbi/mipi_dbi.h b/include/zephyr/dt-bindings/mipi_dbi/mipi_dbi.h index a83ba669d388..4d36f8519b72 100644 --- a/include/zephyr/dt-bindings/mipi_dbi/mipi_dbi.h +++ b/include/zephyr/dt-bindings/mipi_dbi/mipi_dbi.h @@ -26,7 +26,7 @@ * -'---'---'---'---'---'---'---'---'---'---'---'---'---'---'---'- * | Word 1 | Word n * - * -. .- + * -. .- * CS '-----------------------------------------------------------' */ #define MIPI_DBI_MODE_SPI_3WIRE 0x1 @@ -43,7 +43,7 @@ * -'---'---'---'---'---'---'---'---'---'---'---'---'---'---'---'---'- * | Word 1 | Word n * - * -. .- + * -. .- * CS '---------------------------------------------------------------' * * -.-------------------------------.-------------------------------.- @@ -60,7 +60,7 @@ * ------------------------------------------- * RESX * - * .-------------------------------- + * .-------------------------------- * D/CX ----------' * * @@ -85,17 +85,17 @@ /** * @name Parallel Bus protocol for MIPI DBI Type B based on Intel 8080 bus. * - * -. .- + * -. .- * CS '---------------------------------------' * * ------------------------------------------- * RESX * - * --. .---------------------------- + * --. .---------------------------- * D/CX '-----------' * * ---. .--------. .---------------------- - * WRX '---' '---' + * WRX '---' '---' * * ------------------------------------------- * RDX @@ -232,7 +232,7 @@ * -'---'---'---'---'---'---'---'---'---'---'---'---'---'---'---'---'- * | Word 1 (stuffing) : (byte) | * - * -. .- + * -. .- * CS '---------------------------------------------------------------' * * -.---------------------------------------------------------------.- From 5671a4357b3240737e7f392fa8e42c337517c138 Mon Sep 17 00:00:00 2001 From: Kate Wang Date: Fri, 5 Dec 2025 19:22:19 +0800 Subject: [PATCH 0807/3659] drivers: mipi_dbi: Fix typo for color coding Fix typo for color coding Signed-off-by: Kate Wang --- include/zephyr/dt-bindings/mipi_dbi/mipi_dbi.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/zephyr/dt-bindings/mipi_dbi/mipi_dbi.h b/include/zephyr/dt-bindings/mipi_dbi/mipi_dbi.h index 4d36f8519b72..68da112e14c9 100644 --- a/include/zephyr/dt-bindings/mipi_dbi/mipi_dbi.h +++ b/include/zephyr/dt-bindings/mipi_dbi/mipi_dbi.h @@ -160,15 +160,15 @@ */ #define MIPI_DBI_MODE_RGB666_2 (0x5 << 4U) /** - * RGB666 (18 bpp). + * RGB888 (24 bpp). * - * - For 8-bit data bus width, #MIPI_DBI_MODE_RGB666_1 and #MIPI_DBI_MODE_RGB666_2 are the same. + * - For 8-bit data bus width, #MIPI_DBI_MODE_RGB888_1 and #MIPI_DBI_MODE_RGB888_2 are the same. * 1 pixel is sent in 3 cycles, R component first. - * - For 16-bit data bus width, #MIPI_DBI_MODE_RGB666_1 is option 1, 2 pixels are sent in 3 cycles. + * - For 16-bit data bus width, #MIPI_DBI_MODE_RGB888_1 is option 1, 2 pixels are sent in 3 cycles. * The first pixel's R/G/B components are sent in cycle 1 bits 8-15, cycle 1 bits 0-7 and cycle 2 * bits 0-15. The second pixel's R/G/B components are sent in cycle 2 bits 0-7, cycle 3 bits 8-15 * and cycle 3 bits 0-7. - * #MIPI_DBI_MODE_RGB666_2 is option 2, 1 pixel is sent in 2 cycles. The pixel's R/G/B components + * #MIPI_DBI_MODE_RGB888_2 is option 2, 1 pixel is sent in 2 cycles. The pixel's R/G/B components * are sent in cycle 1 bits 0-7, cycle 2 bits 8-15 and cycle 2 bits 0-7. */ #define MIPI_DBI_MODE_RGB888_1 (0x6 << 4U) From 68988108ee0e223adf3c80a3aef84713101a11dc Mon Sep 17 00:00:00 2001 From: Kate Wang Date: Fri, 5 Dec 2025 19:31:14 +0800 Subject: [PATCH 0808/3659] drivers: mipi_dbi: add support for DBI color coding Add new configuration item color_coding in the structure mipi_dbi_config and in mipi-dbi-device binding property. The color coding is defined by MIPI Alliance Standard for Display Bus Interface v2.0, which is required by some display controllers and device. Signed-off-by: Kate Wang --- dts/bindings/mipi-dbi/mipi-dbi-device.yaml | 14 ++++++++++++++ include/zephyr/drivers/mipi_dbi.h | 2 ++ 2 files changed, 16 insertions(+) diff --git a/dts/bindings/mipi-dbi/mipi-dbi-device.yaml b/dts/bindings/mipi-dbi/mipi-dbi-device.yaml index 57e2f42770b4..28b880f59d43 100644 --- a/dts/bindings/mipi-dbi/mipi-dbi-device.yaml +++ b/dts/bindings/mipi-dbi/mipi-dbi-device.yaml @@ -27,6 +27,20 @@ properties: - "MIPI_DBI_MODE_8080_BUS_9_BIT" - "MIPI_DBI_MODE_8080_BUS_8_BIT" + color-coding: + type: string + description: | + Color coding for MIPI DBI Type A or Type B(6800/8080) interface. These definitions + should match those in dt-bindings/mipi_dbi/mipi_dbi.h + enum: + - "MIPI_DBI_MODE_RGB332" + - "MIPI_DBI_MODE_RGB444" + - "MIPI_DBI_MODE_RGB565" + - "MIPI_DBI_MODE_RGB666_1" + - "MIPI_DBI_MODE_RGB666_2" + - "MIPI_DBI_MODE_RGB888_1" + - "MIPI_DBI_MODE_RGB888_2" + te-mode: type: string default: "MIPI_DBI_TE_NO_EDGE" diff --git a/include/zephyr/drivers/mipi_dbi.h b/include/zephyr/drivers/mipi_dbi.h index b47c9b1749ae..0cef48a1d97b 100644 --- a/include/zephyr/drivers/mipi_dbi.h +++ b/include/zephyr/drivers/mipi_dbi.h @@ -157,6 +157,8 @@ extern "C" { struct mipi_dbi_config { /** MIPI DBI mode */ uint8_t mode; + /** MIPI DBI color coding for Type A or Type B(6800/8080) interface. */ + uint8_t color_coding; /** SPI configuration */ struct spi_config config; }; From 7199c4081f7ead8e14d129d500b9ccc316cadcf2 Mon Sep 17 00:00:00 2001 From: Peter Wang Date: Thu, 11 Dec 2025 11:01:54 +0800 Subject: [PATCH 0809/3659] boards: frdm_mcxaxx6,frdm_mcxa577: enable reset driver 1. enable reset driver for frdm mcxa boards below: - frdm_mcxa266 - frdm_mcxa346 - frdm_mcxa366 - frdm_mcxa577 Signed-off-by: Peter Wang --- dts/arm/nxp/nxp_mcxa5x_common.dtsi | 2 +- dts/arm/nxp/nxp_mcxaxx6_common.dtsi | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dts/arm/nxp/nxp_mcxa5x_common.dtsi b/dts/arm/nxp/nxp_mcxa5x_common.dtsi index 31f1564c6d17..a9ead5e1359b 100644 --- a/dts/arm/nxp/nxp_mcxa5x_common.dtsi +++ b/dts/arm/nxp/nxp_mcxa5x_common.dtsi @@ -94,7 +94,7 @@ #clock-cells = <1>; reset: reset { - compatible = "nxp,lpc-syscon-reset"; + compatible = "nxp,mrcc-reset"; #reset-cells = <1>; }; }; diff --git a/dts/arm/nxp/nxp_mcxaxx6_common.dtsi b/dts/arm/nxp/nxp_mcxaxx6_common.dtsi index cdf103553b91..1e04c05d5248 100644 --- a/dts/arm/nxp/nxp_mcxaxx6_common.dtsi +++ b/dts/arm/nxp/nxp_mcxaxx6_common.dtsi @@ -42,7 +42,7 @@ #clock-cells = <1>; reset: reset { - compatible = "nxp,lpc-syscon-reset"; + compatible = "nxp,mrcc-reset"; #reset-cells = <1>; }; }; From 17c2a3f8fcda7189becae525ae7a798c2aea296f Mon Sep 17 00:00:00 2001 From: Fengming Ye Date: Mon, 15 Dec 2025 14:11:22 +0900 Subject: [PATCH 0810/3659] manifest: update hal_nxp revision to support custom host platform for WiFi Add CONFIG_NXP_WIFI_CUSTOM_HOST to customize host platform for NXP Wi-Fi card. Signed-off-by: Fengming Ye --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index ed1c1afeecd6..84745a842f89 100644 --- a/west.yml +++ b/west.yml @@ -210,7 +210,7 @@ manifest: groups: - hal - name: hal_nxp - revision: d622701b7fced803edb96b979fb97c10e8518759 + revision: e8a0f68e8d5797ac174580b872df379bdf2f5c4a path: modules/hal/nxp groups: - hal From a957c6311d540f9a81878a99973ee6d6e1ea12e8 Mon Sep 17 00:00:00 2001 From: Fengming Ye Date: Mon, 15 Dec 2025 12:21:27 +0900 Subject: [PATCH 0811/3659] wifi: nxp: support nxp wifi with custom host platform Add CONFIG_NXP_WIFI_CUSTOM_HOST to build with custom host platform. Signed-off-by: Fengming Ye --- drivers/wifi/nxp/Kconfig.nxp | 20 ++++++++++++++++++-- drivers/wifi/nxp/nxp_wifi_drv.c | 3 ++- modules/hal_nxp/CMakeLists.txt | 4 ++++ modules/hal_nxp/mcux/CMakeLists.txt | 5 ----- modules/hal_nxp/mcux/Kconfig.mcux | 6 ------ modules/hal_nxp/wifi/CMakeLists.txt | 26 ++++++++++++++++++++++++++ 6 files changed, 50 insertions(+), 14 deletions(-) create mode 100644 modules/hal_nxp/wifi/CMakeLists.txt diff --git a/drivers/wifi/nxp/Kconfig.nxp b/drivers/wifi/nxp/Kconfig.nxp index 8d66855fda82..eb10ac59a2ef 100644 --- a/drivers/wifi/nxp/Kconfig.nxp +++ b/drivers/wifi/nxp/Kconfig.nxp @@ -26,6 +26,22 @@ config HEAP_MEM_POOL_ADD_SIZE_NXP_WIFI config WIFI_MGMT_SCAN_CHAN_MAX_MANUAL default 50 +config NXP_MONOLITHIC_WIFI + bool "WiFi firmware monolithic build" + default y + depends on !NXP_WIFI_CUSTOM + help + If enabled, the WiFi firmware used by the device will be linked with the + application directly. + +config NXP_WIFI_CUSTOM_HOST + bool "Custom host platform for NXP Wi-Fi" + default y if BOARD_NATIVE_SIM + default y if !HAS_MCUX && !HAS_IMX_HAL && !HAS_NXP_S32_HAL + depends on !NXP_RW610 + help + Customize host platform eg. non NXP host platform for NXP Wi-Fi. + config NXP_WIFI_CUSTOM bool "Custom NXP Wi-Fi part" help @@ -830,8 +846,8 @@ config NXP_WIFI_CSI_AMI config NXP_WIFI_RESET bool "Wi-Fi reset" default y - imply NXP_WIFI_IND_DNLD if NXP_IW610 - imply NXP_WIFI_IND_RESET if NXP_IW610 + imply NXP_WIFI_IND_DNLD if NXP_IW610 && !NXP_WIFI_CUSTOM_HOST + imply NXP_WIFI_IND_RESET if NXP_IW610 && !NXP_WIFI_CUSTOM_HOST help This option is used to enable/disable/reset Wi-Fi. diff --git a/drivers/wifi/nxp/nxp_wifi_drv.c b/drivers/wifi/nxp/nxp_wifi_drv.c index 8ad22b21cc61..778c4096c113 100644 --- a/drivers/wifi/nxp/nxp_wifi_drv.c +++ b/drivers/wifi/nxp/nxp_wifi_drv.c @@ -111,6 +111,7 @@ int nxp_wifi_wlan_event_callback(enum wlan_event_reason reason, void *data) struct net_in_addr base_addr; struct net_in_addr netmask_addr; struct wifi_ap_sta_info ap_sta_info = { 0 }; + sta_node *con_sta_info; #endif LOG_DBG("WLAN: received event %d", reason); @@ -293,7 +294,7 @@ int nxp_wifi_wlan_event_callback(enum wlan_event_reason reason, void *data) #endif break; case WLAN_REASON_UAP_CLIENT_ASSOC: - sta_node *con_sta_info = (sta_node *)data; + con_sta_info = (sta_node *)data; if (con_sta_info->is_11n_enabled) { ap_sta_info.link_mode = WIFI_4; diff --git a/modules/hal_nxp/CMakeLists.txt b/modules/hal_nxp/CMakeLists.txt index b8281b3c20ed..b275f43afb79 100644 --- a/modules/hal_nxp/CMakeLists.txt +++ b/modules/hal_nxp/CMakeLists.txt @@ -36,4 +36,8 @@ else() add_subdirectory_ifdef(CONFIG_HAS_MCUX mcux) endif() +if(CONFIG_WIFI_NXP) + add_subdirectory(wifi) +endif() + add_subdirectory(${ZEPHYR_CURRENT_MODULE_DIR}/zephyr/src hal_nxp) diff --git a/modules/hal_nxp/mcux/CMakeLists.txt b/modules/hal_nxp/mcux/CMakeLists.txt index bfd39eb8994d..50562f3d1cd1 100644 --- a/modules/hal_nxp/mcux/CMakeLists.txt +++ b/modules/hal_nxp/mcux/CMakeLists.txt @@ -135,11 +135,6 @@ add_subdirectory_ifdef(CONFIG_IEEE802154_KW41Z ${CMAKE_CURRENT_BINARY_DIR}/middleware/wireless/framework ) -add_subdirectory_ifdef(CONFIG_WIFI_NXP - ${ZEPHYR_CURRENT_MODULE_DIR}/mcux/middleware/wifi_nxp - ${CMAKE_CURRENT_BINARY_DIR}/middleware/wifi_nxp - ) - add_subdirectory(${ZEPHYR_CURRENT_MODULE_DIR}/mcux/middleware ${CMAKE_CURRENT_BINARY_DIR}/middleware ) diff --git a/modules/hal_nxp/mcux/Kconfig.mcux b/modules/hal_nxp/mcux/Kconfig.mcux index 33a85c4044e6..628428c57d92 100644 --- a/modules/hal_nxp/mcux/Kconfig.mcux +++ b/modules/hal_nxp/mcux/Kconfig.mcux @@ -73,12 +73,6 @@ config NXP_FW_LOADER The firmware loader is used to load firmwares to embedded transceivers. It is needed to enable connectivity features. -config NXP_MONOLITHIC_WIFI - bool "WiFi firmware monolithic build" - help - If enabled, the WiFi firmware used by the device will be linked with the - application directly. - config NXP_MONOLITHIC_NBU bool "Narrowband Unit (BT/15.4) firmware monolithic build" depends on HAS_NXP_MONOLITHIC_NBU diff --git a/modules/hal_nxp/wifi/CMakeLists.txt b/modules/hal_nxp/wifi/CMakeLists.txt new file mode 100644 index 000000000000..e3438c48beef --- /dev/null +++ b/modules/hal_nxp/wifi/CMakeLists.txt @@ -0,0 +1,26 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +add_subdirectory( + ${ZEPHYR_CURRENT_MODULE_DIR}/mcux/middleware/wifi_nxp + ${CMAKE_CURRENT_BINARY_DIR}/middleware/wifi_nxp +) + +add_subdirectory( + ${ZEPHYR_CURRENT_MODULE_DIR}/mcux/mcux-sdk-ng/components/osa + ${CMAKE_CURRENT_BINARY_DIR}/components/osa +) + +add_subdirectory( + ${ZEPHYR_CURRENT_MODULE_DIR}/mcux/mcux-sdk-ng/components/wifi_bt_module + ${CMAKE_CURRENT_BINARY_DIR}/components/wifi_bt_module +) + +zephyr_compile_definitions_ifdef(CONFIG_NXP_WIFI_CUSTOM_HOST + SDK_COMPONENT_DEPENDENCY_FSL_COMMON=0 +) + +set(CONFIG_MCUX_COMPONENT_component.wifi_bt_module.tx_pwr_limits ON) +set(CONFIG_MCUX_COMPONENT_component.osa_template_config ON) +set(CONFIG_MCUX_COMPONENT_component.osa_zephyr ON) +set(CONFIG_MCUX_COMPONENT_component.osa_interface ON) From c728da88d852663546ce5f7aba93bf9625b01309 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrzej=20G=C5=82=C4=85bek?= Date: Wed, 17 Dec 2025 16:04:31 +0100 Subject: [PATCH 0812/3659] drivers: mspi_dw: Fix conditionally defined masks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is a follow-up to commit 59d8fbc0a9554311e9296a3d6773e510fb35a154. Add missing brackets in mask definitions that use `COND_CODE_1()`. Without those, the call to `__DEBRACKET()` that is done inside `COND_CODE_1()` removes the outer brackets provided by `GENMASK()`, what causes problems when the mask is directly used with another operator like `~`. Remove also no longer needed brackets added in `start_next_packet()` by the commit mentioned above as a workaround for this problem, the root cause of which was not identified at that time. Signed-off-by: Andrzej Głąbek --- drivers/mspi/mspi_dw.c | 6 +++--- drivers/mspi/mspi_dw.h | 14 +++++++------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/mspi/mspi_dw.c b/drivers/mspi/mspi_dw.c index 66bdf670c02d..df33d5f88208 100644 --- a/drivers/mspi/mspi_dw.c +++ b/drivers/mspi/mspi_dw.c @@ -1105,9 +1105,9 @@ static int start_next_packet(const struct device *dev) dev_data->dummy_bytes = 0; dev_data->bytes_to_discard = 0; - dev_data->ctrlr0 &= ~(CTRLR0_TMOD_MASK) - & ~(CTRLR0_DFS_MASK) - & ~(CTRLR0_DFS32_MASK); + dev_data->ctrlr0 &= ~CTRLR0_TMOD_MASK + & ~CTRLR0_DFS_MASK + & ~CTRLR0_DFS32_MASK; dev_data->spi_ctrlr0 &= ~SPI_CTRLR0_WAIT_CYCLES_MASK; diff --git a/drivers/mspi/mspi_dw.h b/drivers/mspi/mspi_dw.h index 0d015ae3db03..38b0a3ca6d4e 100644 --- a/drivers/mspi/mspi_dw.h +++ b/drivers/mspi/mspi_dw.h @@ -20,24 +20,24 @@ /* CTRLR0 - Control Register 0 */ #define CTRLR0_SSI_IS_MST_BIT BIT(31) -#define CTRLR0_SPI_FRF_MASK COND_CODE_1(SSI_VERSION_2, GENMASK(22, 21), GENMASK(23, 22)) +#define CTRLR0_SPI_FRF_MASK COND_CODE_1(SSI_VERSION_2, (GENMASK(22, 21)), (GENMASK(23, 22))) #define CTRLR0_SPI_FRF_STANDARD 0UL #define CTRLR0_SPI_FRF_DUAL 1UL #define CTRLR0_SPI_FRF_QUAD 2UL #define CTRLR0_SPI_FRF_OCTAL 3UL -#define CTRLR0_TMOD_MASK COND_CODE_1(SSI_VERSION_2, GENMASK(9, 8), GENMASK(11, 10)) +#define CTRLR0_TMOD_MASK COND_CODE_1(SSI_VERSION_2, (GENMASK(9, 8)), (GENMASK(11, 10))) #define CTRLR0_TMOD_TX_RX 0UL #define CTRLR0_TMOD_TX 1UL #define CTRLR0_TMOD_RX 2UL #define CTRLR0_TMOD_EEPROM 3UL -#define CTRLR0_SCPOL_BIT COND_CODE_1(SSI_VERSION_2, BIT(7), BIT(9)) -#define CTRLR0_SCPH_BIT COND_CODE_1(SSI_VERSION_2, BIT(6), BIT(8)) -#define CTRLR0_FRF_MASK COND_CODE_1(SSI_VERSION_2, GENMASK(5, 4), GENMASK(7, 6)) +#define CTRLR0_SCPOL_BIT COND_CODE_1(SSI_VERSION_2, (BIT(7)), (BIT(9))) +#define CTRLR0_SCPH_BIT COND_CODE_1(SSI_VERSION_2, (BIT(6)), (BIT(8))) +#define CTRLR0_FRF_MASK COND_CODE_1(SSI_VERSION_2, (GENMASK(5, 4)), (GENMASK(7, 6))) #define CTRLR0_FRF_SPI 0UL #define CTRLR0_FRF_SSP 1UL #define CTRLR0_FRF_MICROWIRE 2UL -#define CTRLR0_DFS_MASK COND_CODE_1(SSI_VERSION_2, GENMASK(3, 0), GENMASK(4, 0)) -#define CTRLR0_DFS32_MASK COND_CODE_1(SSI_VERSION_2, GENMASK(20, 16), (0)) +#define CTRLR0_DFS_MASK COND_CODE_1(SSI_VERSION_2, (GENMASK(3, 0)), (GENMASK(4, 0))) +#define CTRLR0_DFS32_MASK COND_CODE_1(SSI_VERSION_2, (GENMASK(20, 16)), (0UL)) /* CTRLR1- Control Register 1 */ #define CTRLR1_NDF_MASK GENMASK(15, 0) From 7778a15d1eb5469e5af7cc71fa4e6a8850a76861 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Thu, 18 Dec 2025 14:59:31 +0100 Subject: [PATCH 0813/3659] include: disk: add doxygen group for device-specific Disk Access extensions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Similar to how it's done for other driver classes, create a new doxygen group to put all device-specific Disk Access extensions under. Signed-off-by: Benjamin Cabé --- include/zephyr/drivers/disk.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/zephyr/drivers/disk.h b/include/zephyr/drivers/disk.h index 899a3e25be5d..8a8beb806cbe 100644 --- a/include/zephyr/drivers/disk.h +++ b/include/zephyr/drivers/disk.h @@ -26,6 +26,11 @@ * @version 1.1.0 * @ingroup io_interfaces * @{ + * + * @defgroup disk_driver_interface_ext Device-specific Disk Access API extensions + * + * @{ + * @} */ #include From 0a3bc8fa701670dd1c2fb6aacf5255b18ca939b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Thu, 18 Dec 2025 15:00:20 +0100 Subject: [PATCH 0814/3659] include: disk: add doxygen docs for stm32_sdmmc extended API MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds doxygen documentation for the extended API of the STM32 SDMMC driver. Signed-off-by: Benjamin Cabé --- include/zephyr/drivers/disk/sdmmc_stm32.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/include/zephyr/drivers/disk/sdmmc_stm32.h b/include/zephyr/drivers/disk/sdmmc_stm32.h index 2472aaf3aacc..ec16798adc77 100644 --- a/include/zephyr/drivers/disk/sdmmc_stm32.h +++ b/include/zephyr/drivers/disk/sdmmc_stm32.h @@ -4,12 +4,25 @@ * SPDX-License-Identifier: Apache-2.0 */ +/** + * @file + * @brief Header file for extended Disk API of STM32 SDMMC + * @ingroup stm32_sdmmc_disk_interface + */ + #ifndef ZEPHYR_INCLUDE_DRIVERS_DISK_SDMMC_STM32_H_ #define ZEPHYR_INCLUDE_DRIVERS_DISK_SDMMC_STM32_H_ #include #include +/** + * @brief STM32 SDMMC controller + * @defgroup stm32_sdmmc_disk_interface STM32 SDMMC + * @ingroup disk_driver_interface_ext + * @{ + */ + /** * @brief Get the CID (Card Identification) information from the SD/MMC card. * @@ -46,4 +59,6 @@ void stm32_sdmmc_get_card_cid(const struct device *dev, uint32_t cid[4]); */ void stm32_sdmmc_get_card_csd(const struct device *dev, uint32_t csd[4]); +/** @} */ + #endif /* ZEPHYR_INCLUDE_DRIVERS_DISK_SDMMC_STM32_H_ */ From 4468fbfae0906608dd53ad3654d4fb78c11e6e4e Mon Sep 17 00:00:00 2001 From: Kyle Bonnici Date: Fri, 19 Dec 2025 00:38:47 +0100 Subject: [PATCH 0815/3659] Boards: align ranges to DTS spec Spec - Section 2.3.8 > If the property is defined with an value, it specifies that the parent and child address space is identical, and no address translation is required. Spec - Table 2.3 > : Value is empty. Used for conveying true-false information, when the presence or absence of the property itself is sufficiently descriptive. `ranges = <>;` should be interpreted as `` with empty array, when processing the child the ranges should be used and given it is and empty array we will fail to map and behaviour is undefined by the dts spec! Hence IMO `ranges;` is the correct syntax here. This leaves no space for uncertainty and undefined behaviour by tools and user interpretation. Signed-off-by: Kyle Bonnici --- dts/arm/nxp/nxp_mcxn23x_common.dtsi | 16 +++++++-------- dts/arm/nxp/nxp_mcxnx4x_common.dtsi | 20 +++++++++--------- dts/arm/nxp/nxp_mcxw7x_common.dtsi | 2 +- dts/arm/nxp/nxp_rt7xx_cm33_cpu0.dtsi | 28 +++++++++++++------------- dts/arm/nxp/nxp_rt7xx_cm33_cpu1.dtsi | 8 ++++---- dts/arm/nxp/nxp_rw6xx_common.dtsi | 2 +- dts/vendor/nordic/nrf54h20.dtsi | 2 +- dts/xtensa/nxp/nxp_imxrt700_hifi4.dtsi | 4 ++-- 8 files changed, 41 insertions(+), 41 deletions(-) diff --git a/dts/arm/nxp/nxp_mcxn23x_common.dtsi b/dts/arm/nxp/nxp_mcxn23x_common.dtsi index 5045c844645b..a3930e6899d5 100644 --- a/dts/arm/nxp/nxp_mcxn23x_common.dtsi +++ b/dts/arm/nxp/nxp_mcxn23x_common.dtsi @@ -288,7 +288,7 @@ interrupts = <35 0>; status = "disabled"; - ranges = <>; + ranges; #address-cells = <1>; #size-cells = <1>; @@ -326,7 +326,7 @@ interrupts = <36 0>; status = "disabled"; - ranges = <>; + ranges; #address-cells = <1>; #size-cells = <1>; @@ -370,7 +370,7 @@ interrupts = <37 0>; status = "disabled"; - ranges = <>; + ranges; #address-cells = <1>; #size-cells = <1>; @@ -414,7 +414,7 @@ interrupts = <38 0>; status = "disabled"; - ranges = <>; + ranges; #address-cells = <1>; #size-cells = <1>; @@ -452,7 +452,7 @@ interrupts = <39 0>; status = "disabled"; - ranges = <>; + ranges; #address-cells = <1>; #size-cells = <1>; @@ -496,7 +496,7 @@ interrupts = <40 0>; status = "disabled"; - ranges = <>; + ranges; #address-cells = <1>; #size-cells = <1>; @@ -534,7 +534,7 @@ interrupts = <41 0>; status = "disabled"; - ranges = <>; + ranges; #address-cells = <1>; #size-cells = <1>; @@ -572,7 +572,7 @@ interrupts = <42 0>; status = "disabled"; - ranges = <>; + ranges; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/nxp/nxp_mcxnx4x_common.dtsi b/dts/arm/nxp/nxp_mcxnx4x_common.dtsi index 8f97403da617..cfbc52f9471b 100644 --- a/dts/arm/nxp/nxp_mcxnx4x_common.dtsi +++ b/dts/arm/nxp/nxp_mcxnx4x_common.dtsi @@ -267,7 +267,7 @@ status = "disabled"; /* Empty ranges property implies parent and child address space is identical */ - ranges = <>; + ranges; #address-cells = <1>; #size-cells = <1>; @@ -305,7 +305,7 @@ interrupts = <36 0>; status = "disabled"; - ranges = <>; + ranges; #address-cells = <1>; #size-cells = <1>; @@ -349,7 +349,7 @@ interrupts = <37 0>; status = "disabled"; - ranges = <>; + ranges; #address-cells = <1>; #size-cells = <1>; @@ -393,7 +393,7 @@ interrupts = <38 0>; status = "disabled"; - ranges = <>; + ranges; #address-cells = <1>; #size-cells = <1>; @@ -431,7 +431,7 @@ interrupts = <39 0>; status = "disabled"; - ranges = <>; + ranges; #address-cells = <1>; #size-cells = <1>; @@ -475,7 +475,7 @@ interrupts = <40 0>; status = "disabled"; - ranges = <>; + ranges; #address-cells = <1>; #size-cells = <1>; @@ -513,7 +513,7 @@ interrupts = <41 0>; status = "disabled"; - ranges = <>; + ranges; #address-cells = <1>; #size-cells = <1>; @@ -551,7 +551,7 @@ interrupts = <42 0>; status = "disabled"; - ranges = <>; + ranges; #address-cells = <1>; #size-cells = <1>; @@ -589,7 +589,7 @@ interrupts = <43 0>; status = "disabled"; - ranges = <>; + ranges; #address-cells = <1>; #size-cells = <1>; @@ -627,7 +627,7 @@ interrupts = <44 0>; status = "disabled"; - ranges = <>; + ranges; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/nxp/nxp_mcxw7x_common.dtsi b/dts/arm/nxp/nxp_mcxw7x_common.dtsi index d29a88276074..4a9d46ded9c9 100644 --- a/dts/arm/nxp/nxp_mcxw7x_common.dtsi +++ b/dts/arm/nxp/nxp_mcxw7x_common.dtsi @@ -97,7 +97,7 @@ #size-cells = <1>; pbridge2: pbridge2@0 { - ranges = <>; + ranges; #address-cells = <1>; #size-cells = <1>; }; diff --git a/dts/arm/nxp/nxp_rt7xx_cm33_cpu0.dtsi b/dts/arm/nxp/nxp_rt7xx_cm33_cpu0.dtsi index c42a7dc4c518..3f79461a26ed 100644 --- a/dts/arm/nxp/nxp_rt7xx_cm33_cpu0.dtsi +++ b/dts/arm/nxp/nxp_rt7xx_cm33_cpu0.dtsi @@ -306,7 +306,7 @@ status = "disabled"; /* Empty ranges property implies parent and child address space is identical */ - ranges = <>; + ranges; #address-cells = <1>; #size-cells = <1>; @@ -345,7 +345,7 @@ status = "disabled"; /* Empty ranges property implies parent and child address space is identical */ - ranges = <>; + ranges; #address-cells = <1>; #size-cells = <1>; @@ -384,7 +384,7 @@ status = "disabled"; /* Empty ranges property implies parent and child address space is identical */ - ranges = <>; + ranges; #address-cells = <1>; #size-cells = <1>; @@ -423,7 +423,7 @@ status = "disabled"; /* Empty ranges property implies parent and child address space is identical */ - ranges = <>; + ranges; #address-cells = <1>; #size-cells = <1>; @@ -462,7 +462,7 @@ status = "disabled"; /* Empty ranges property implies parent and child address space is identical */ - ranges = <>; + ranges; #address-cells = <1>; #size-cells = <1>; @@ -501,7 +501,7 @@ status = "disabled"; /* Empty ranges property implies parent and child address space is identical */ - ranges = <>; + ranges; #address-cells = <1>; #size-cells = <1>; @@ -540,7 +540,7 @@ status = "disabled"; /* Empty ranges property implies parent and child address space is identical */ - ranges = <>; + ranges; #address-cells = <1>; #size-cells = <1>; @@ -579,7 +579,7 @@ status = "disabled"; /* Empty ranges property implies parent and child address space is identical */ - ranges = <>; + ranges; #address-cells = <1>; #size-cells = <1>; @@ -618,7 +618,7 @@ status = "disabled"; /* Empty ranges property implies parent and child address space is identical */ - ranges = <>; + ranges; #address-cells = <1>; #size-cells = <1>; @@ -657,7 +657,7 @@ status = "disabled"; /* Empty ranges property implies parent and child address space is identical */ - ranges = <>; + ranges; #address-cells = <1>; #size-cells = <1>; @@ -696,7 +696,7 @@ status = "disabled"; /* Empty ranges property implies parent and child address space is identical */ - ranges = <>; + ranges; #address-cells = <1>; #size-cells = <1>; @@ -735,7 +735,7 @@ status = "disabled"; /* Empty ranges property implies parent and child address space is identical */ - ranges = <>; + ranges; #address-cells = <1>; #size-cells = <1>; @@ -774,7 +774,7 @@ status = "disabled"; /* Empty ranges property implies parent and child address space is identical */ - ranges = <>; + ranges; #address-cells = <1>; #size-cells = <1>; @@ -813,7 +813,7 @@ status = "disabled"; /* Empty ranges property implies parent and child address space is identical */ - ranges = <>; + ranges; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/nxp/nxp_rt7xx_cm33_cpu1.dtsi b/dts/arm/nxp/nxp_rt7xx_cm33_cpu1.dtsi index eaa2976f38d5..0c7fe6cdcaed 100644 --- a/dts/arm/nxp/nxp_rt7xx_cm33_cpu1.dtsi +++ b/dts/arm/nxp/nxp_rt7xx_cm33_cpu1.dtsi @@ -166,7 +166,7 @@ status = "disabled"; /* Empty ranges property implies parent and child address space is identical */ - ranges = <>; + ranges; #address-cells = <1>; #size-cells = <1>; @@ -205,7 +205,7 @@ status = "disabled"; /* Empty ranges property implies parent and child address space is identical */ - ranges = <>; + ranges; #address-cells = <1>; #size-cells = <1>; @@ -244,7 +244,7 @@ status = "disabled"; /* Empty ranges property implies parent and child address space is identical */ - ranges = <>; + ranges; #address-cells = <1>; #size-cells = <1>; @@ -283,7 +283,7 @@ status = "disabled"; /* Empty ranges property implies parent and child address space is identical */ - ranges = <>; + ranges; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/arm/nxp/nxp_rw6xx_common.dtsi b/dts/arm/nxp/nxp_rw6xx_common.dtsi index 50f766ef3e15..6015ac85275b 100644 --- a/dts/arm/nxp/nxp_rw6xx_common.dtsi +++ b/dts/arm/nxp/nxp_rw6xx_common.dtsi @@ -574,7 +574,7 @@ }; gau { - ranges = <>; + ranges; #address-cells = <1>; #size-cells = <1>; diff --git a/dts/vendor/nordic/nrf54h20.dtsi b/dts/vendor/nordic/nrf54h20.dtsi index a6a2f10c19ab..c53ba69a9edf 100644 --- a/dts/vendor/nordic/nrf54h20.dtsi +++ b/dts/vendor/nordic/nrf54h20.dtsi @@ -157,7 +157,7 @@ reserved-memory { #address-cells = <1>; #size-cells = <1>; - ranges = <>; + ranges; }; clocks { diff --git a/dts/xtensa/nxp/nxp_imxrt700_hifi4.dtsi b/dts/xtensa/nxp/nxp_imxrt700_hifi4.dtsi index 8143a1c2a571..8067641d9039 100644 --- a/dts/xtensa/nxp/nxp_imxrt700_hifi4.dtsi +++ b/dts/xtensa/nxp/nxp_imxrt700_hifi4.dtsi @@ -129,7 +129,7 @@ #size-cells = <1>; /* Empty ranges property implies parent and child address space is identical */ - ranges = <>; + ranges; reg = <0x110000 0x1000>; interrupts = <6 0 0>; @@ -179,7 +179,7 @@ #size-cells = <1>; /* Empty ranges property implies parent and child address space is identical */ - ranges = <>; + ranges; reg = <0x112000 0x1000>; interrupts = <7 0 0>; From 1bc9b2d05a63c30d9fcce3e1d6c2aed33c4c9002 Mon Sep 17 00:00:00 2001 From: Braeden Lane Date: Thu, 18 Dec 2025 17:05:24 -0800 Subject: [PATCH 0816/3659] drivers: counter: infineon_tcpwm: refactor to use TCPWM block base Refactor the Infineon TCPWM counter driver to use the TCPWM block base address instead of the counter instance base address. This change aligns with the standard Infineon PDL API which requires the TCPWM block base and counter index as separate parameters. This modification maintains functional compatibility while providing better alignment with the underlying hardware abstraction layer. This also aligns with PR feedback to move the ifx_tcpwm.h header file from the include folder (public APIs) to the drivers folder. Instead, this refactoring prepares to remove that header file entirely. Signed-off-by: Braeden Lane --- drivers/counter/counter_infineon_tcpwm.c | 63 +++++++++++++----------- 1 file changed, 33 insertions(+), 30 deletions(-) diff --git a/drivers/counter/counter_infineon_tcpwm.c b/drivers/counter/counter_infineon_tcpwm.c index f46f49be4b8b..33eca426e135 100644 --- a/drivers/counter/counter_infineon_tcpwm.c +++ b/drivers/counter/counter_infineon_tcpwm.c @@ -24,7 +24,7 @@ LOG_MODULE_REGISTER(ifx_tcpwm_counter, CONFIG_COUNTER_LOG_LEVEL); struct ifx_tcpwm_counter_config { struct counter_config_info counter_info; - TCPWM_GRP_CNT_Type *reg_base; + TCPWM_Type *reg_base; uint32_t index; bool resolution_32_bits; IRQn_Type irq_num; @@ -84,16 +84,16 @@ static void counter_enable_event(const struct device *dev, counter_event_t event { const struct ifx_tcpwm_counter_config *const config = dev->config; uint32_t savedIntrStatus = Cy_SysLib_EnterCriticalSection(); - uint32_t old_mask = IFX_TCPWM_GetInterruptMask(config->reg_base); + uint32_t old_mask = Cy_TCPWM_GetInterruptMask(config->reg_base, config->index); uint32_t new_event; if (enable) { /* Clear any newly enabled events so that old IRQs don't trigger ISRs */ - IFX_TCPWM_ClearInterrupt(config->reg_base, ~old_mask & event); + Cy_TCPWM_ClearInterrupt(config->reg_base, config->index, ~old_mask & event); } new_event = enable ? (old_mask | event) : (old_mask & ~event); - IFX_TCPWM_SetInterruptMask(config->reg_base, new_event); + Cy_TCPWM_SetInterruptMask(config->reg_base, config->index, new_event); Cy_SysLib_ExitCriticalSection(savedIntrStatus); } @@ -104,8 +104,8 @@ static void counter_isr_handler(const struct device *dev) const struct ifx_tcpwm_counter_config *const config = dev->config; uint32_t pending_int; - pending_int = IFX_TCPWM_GetInterruptStatusMasked(config->reg_base); - IFX_TCPWM_ClearInterrupt(config->reg_base, pending_int); + pending_int = Cy_TCPWM_GetInterruptStatusMasked(config->reg_base, config->index); + Cy_TCPWM_ClearInterrupt(config->reg_base, config->index, pending_int); NVIC_ClearPendingIRQ(config->irq_num); /* Alarm compare/capture interrupt */ @@ -116,8 +116,9 @@ static void counter_isr_handler(const struct device *dev) counter_enable_event(dev, COUNTER_IRQ_CAPTURE_COMPARE, false); /* Call User callback for Alarm */ - data->alarm_cfg.callback(dev, 1, IFX_TCPWM_Counter_GetCounter(config->reg_base), - data->alarm_cfg.user_data); + data->alarm_cfg.callback( + dev, 1, Cy_TCPWM_Counter_GetCounter(config->reg_base, config->index), + data->alarm_cfg.user_data); data->alarm_irq_flag = false; } @@ -150,20 +151,20 @@ static int ifx_tcpwm_counter_init(const struct device *dev) counter_config.compare0 = data->compare_value; /* DeInit will clear the interrupt mask; save it now and restore after we re-nit */ - uint32_t old_mask = IFX_TCPWM_GetInterruptMask(config->reg_base); + uint32_t old_mask = Cy_TCPWM_GetInterruptMask(config->reg_base, config->index); - IFX_TCPWM_Counter_DeInit(config->reg_base, &counter_config); + Cy_TCPWM_Counter_DeInit(config->reg_base, config->index, &counter_config); - rslt = (cy_rslt_t)IFX_TCPWM_Counter_Init(config->reg_base, &counter_config); + rslt = (cy_rslt_t)Cy_TCPWM_Counter_Init(config->reg_base, config->index, &counter_config); if (rslt != CY_RSLT_SUCCESS) { return -EIO; } - IFX_TCPWM_Counter_Enable(config->reg_base); - IFX_TCPWM_SetInterruptMask(config->reg_base, old_mask); + Cy_TCPWM_Counter_Enable(config->reg_base, config->index); + Cy_TCPWM_SetInterruptMask(config->reg_base, config->index, old_mask); - /* This must be called after IFX_TCPWM_Counter_Init */ - IFX_TCPWM_Counter_SetCounter(config->reg_base, data->value); + /* This must be called after Cy_TCPWM_Counter_Init */ + Cy_TCPWM_Counter_SetCounter(config->reg_base, config->index, data->value); /* enable the counter interrupt */ config->irq_enable_func(dev); @@ -177,8 +178,8 @@ static int ifx_tcpwm_counter_start(const struct device *dev) const struct ifx_tcpwm_counter_config *config = dev->config; - IFX_TCPWM_Counter_Enable(config->reg_base); - IFX_TCPWM_TriggerStart_Single(config->reg_base); + Cy_TCPWM_Counter_Enable(config->reg_base, config->index); + Cy_TCPWM_TriggerStart_Single(config->reg_base, config->index); return 0; } @@ -189,7 +190,7 @@ static int ifx_tcpwm_counter_stop(const struct device *dev) const struct ifx_tcpwm_counter_config *config = dev->config; - IFX_TCPWM_Counter_Disable(config->reg_base); + Cy_TCPWM_Counter_Disable(config->reg_base, config->index); return 0; } @@ -219,7 +220,7 @@ static int ifx_tcpwm_counter_get_value(const struct device *dev, uint32_t *ticks const struct ifx_tcpwm_counter_config *config = dev->config; - *ticks = IFX_TCPWM_Counter_GetCounter(config->reg_base); + *ticks = Cy_TCPWM_Counter_GetCounter(config->reg_base, config->index); return 0; } @@ -247,12 +248,12 @@ static int ifx_tcpwm_counter_set_top_value(const struct device *dev, /* timer_configure resets timer counter register to value * defined in config structure 'data->value', so update * counter value with current value of counter (read by - * IFX_TCPWM_Counter_GetCounter function). + * Cy_TCPWM_Counter_GetCounter function). */ - data->value = IFX_TCPWM_Counter_GetCounter(config->reg_base); + data->value = Cy_TCPWM_Counter_GetCounter(config->reg_base, config->index); } - IFX_TCPWM_Block_SetPeriod(config->reg_base, cfg->ticks); + Cy_TCPWM_Block_SetPeriod(config->reg_base, config->index, cfg->ticks); /* Register an top_value terminal count event callback handler if * callback is not NULL. @@ -344,14 +345,15 @@ static int ifx_tcpwm_counter_set_alarm(const struct device *dev, uint8_t chan_id /* limit max to detect short relative being set too late. */ max_rel_val = irq_on_late ? (top_val / 2U) : top_val; - compare_value = counter_ticks_add(IFX_TCPWM_Counter_GetCounter(config->reg_base), - compare_value, top_val); + compare_value = counter_ticks_add( + Cy_TCPWM_Counter_GetCounter(config->reg_base, config->index), compare_value, + top_val); } /* Decrement value to detect the case when compare_value == counter_read(dev). Otherwise, * condition would need to include comparing diff against 0. */ - uint32_t curr = IFX_TCPWM_Counter_GetCounter(config->reg_base); + uint32_t curr = Cy_TCPWM_Counter_GetCounter(config->reg_base, config->index); uint32_t diff = counter_ticks_sub((compare_value - 1), curr, top_val); if ((absolute && (compare_value < curr)) || (diff > max_rel_val)) { @@ -362,7 +364,8 @@ static int ifx_tcpwm_counter_set_alarm(const struct device *dev, uint8_t chan_id if (irq_on_late) { data->alarm_irq_flag = true; counter_enable_event(dev, COUNTER_IRQ_CAPTURE_COMPARE, true); - IFX_TCPWM_SetInterrupt(config->reg_base, COUNTER_IRQ_CAPTURE_COMPARE); + Cy_TCPWM_SetInterrupt(config->reg_base, config->index, + COUNTER_IRQ_CAPTURE_COMPARE); } if (absolute) { @@ -374,13 +377,13 @@ static int ifx_tcpwm_counter_set_alarm(const struct device *dev, uint8_t chan_id * timer_configure resets timer counter register to value * defined in config structure 'data->value', so update * counter value with current value of counter (read by - * IFX_TCPWM_Counter_GetCounter function). + * Cy_TCPWM_Counter_GetCounter function). */ - data->value = IFX_TCPWM_Counter_GetCounter(config->reg_base); + data->value = Cy_TCPWM_Counter_GetCounter(config->reg_base, config->index); data->compare_value = compare_value; /* Reconfigure timer */ - IFX_TCPWM_Block_SetCC0Val(config->reg_base, compare_value); + Cy_TCPWM_Block_SetCC0Val(config->reg_base, config->index, compare_value); counter_enable_event(dev, COUNTER_IRQ_CAPTURE_COMPARE, true); } @@ -494,7 +497,7 @@ static DEVICE_API(counter, counter_api) = { : UINT16_MAX, \ .flags = COUNTER_CONFIG_INFO_COUNT_UP, \ .channels = 1}, \ - .reg_base = (TCPWM_GRP_CNT_Type *)DT_REG_ADDR(DT_INST_PARENT(n)), \ + .reg_base = (TCPWM_Type *)DT_REG_ADDR(DT_PARENT(DT_INST_PARENT(n))), \ .index = (DT_REG_ADDR(DT_INST_PARENT(n)) - \ DT_REG_ADDR(DT_PARENT(DT_INST_PARENT(n)))) / \ DT_REG_SIZE(DT_INST_PARENT(n)), \ From 1001d9aad7aa78579a344f611c430431ee2f6160 Mon Sep 17 00:00:00 2001 From: Hake Huang Date: Fri, 19 Dec 2025 11:31:22 +0800 Subject: [PATCH 0817/3659] boards: frdm_mcxn947: add net:ether support add support for ethernet for integration and testing Signed-off-by: Hake Huang --- boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0.yaml | 1 + boards/nxp/mcx_nx4x_evk/mcx_n9xx_evk_mcxn947_cpu0.yaml | 1 + 2 files changed, 2 insertions(+) diff --git a/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0.yaml b/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0.yaml index 0fd1ac9dbb0a..a4b4a7b1e254 100644 --- a/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0.yaml +++ b/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0.yaml @@ -28,6 +28,7 @@ supported: - i2c - i2s - i3c + - netif:eth - nvs - pwm - regulator diff --git a/boards/nxp/mcx_nx4x_evk/mcx_n9xx_evk_mcxn947_cpu0.yaml b/boards/nxp/mcx_nx4x_evk/mcx_n9xx_evk_mcxn947_cpu0.yaml index dd0b5d2e7732..9bf4a314b0f7 100644 --- a/boards/nxp/mcx_nx4x_evk/mcx_n9xx_evk_mcxn947_cpu0.yaml +++ b/boards/nxp/mcx_nx4x_evk/mcx_n9xx_evk_mcxn947_cpu0.yaml @@ -25,6 +25,7 @@ supported: - i2s - i3c - nvs + - netif:eth - pwm - regulator - rtc From c99b9ab3cb915c9380ff969ed3a63cde38627816 Mon Sep 17 00:00:00 2001 From: Farsin Nasar V A Date: Mon, 15 Dec 2025 13:22:31 +0530 Subject: [PATCH 0818/3659] drivers: hwinfo: microchip: Update g1 hwinfo driver replace reset cause masks with RSTC G1 bit names. Signed-off-by: Farsin Nasar V A --- drivers/hwinfo/hwinfo_mchp_g1.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/hwinfo/hwinfo_mchp_g1.c b/drivers/hwinfo/hwinfo_mchp_g1.c index 9b28a0255c8b..db58a6fed8e8 100644 --- a/drivers/hwinfo/hwinfo_mchp_g1.c +++ b/drivers/hwinfo/hwinfo_mchp_g1.c @@ -7,6 +7,7 @@ #include #include #include +#include #include LOG_MODULE_REGISTER(hwinfo_mchp_g1, LOG_LEVEL_ERR); @@ -64,25 +65,25 @@ int z_impl_hwinfo_get_reset_cause(uint32_t *cause) return -EINVAL; } - if ((rcause & RSTC_RCAUSE_POR_Msk) != 0) { + if ((rcause & BIT(RSTC_G1_RCAUSE_POR)) != 0) { result |= RESET_POR; } - if ((rcause & RSTC_RCAUSE_BODCORE_Msk) != 0) { + if ((rcause & BIT(RSTC_G1_RCAUSE_BOD12)) != 0) { result |= RESET_BROWNOUT; } - if ((rcause & RSTC_RCAUSE_BODVDD_Msk) != 0) { + if ((rcause & BIT(RSTC_G1_RCAUSE_BOD33)) != 0) { result |= RESET_BROWNOUT; } - if ((rcause & RSTC_RCAUSE_EXT_Msk) != 0) { + if ((rcause & BIT(RSTC_G1_RCAUSE_EXT)) != 0) { result |= RESET_PIN | RESET_USER; } - if ((rcause & RSTC_RCAUSE_WDT_Msk) != 0) { + if ((rcause & BIT(RSTC_G1_RCAUSE_WDT)) != 0) { result |= RESET_WATCHDOG; } - if ((rcause & RSTC_RCAUSE_SYST_Msk) != 0) { + if ((rcause & BIT(RSTC_G1_RCAUSE_SYST)) != 0) { result |= RESET_SOFTWARE; } - if ((rcause & RSTC_RCAUSE_BACKUP_Msk) != 0) { + if ((rcause & BIT(RSTC_G1_RCAUSE_BACKUP)) != 0) { result |= RESET_LOW_POWER_WAKE; } From 965e921aeac5f867180fe73d4f4007afb405f638 Mon Sep 17 00:00:00 2001 From: Zhaoxiang Jin Date: Fri, 19 Dec 2025 13:41:25 +0800 Subject: [PATCH 0819/3659] scripts: check_compliance: read text files as UTF-8 on Windows KeepSorted can fail on Windows when the active code page is not UTF-8 (e.g. GBK), because text files in the Zephyr tree are UTF-8. Detect file type via libmagic and only process text/* files, avoiding attempts to decode binary content. Open text files via GIT_TOP / with encoding="utf-8" (and errors="surrogateescape") to prevent UnicodeDecodeError during local compliance runs without changing the KeepSorted sorting rules. Signed-off-by: Zhaoxiang Jin --- scripts/ci/check_compliance.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/scripts/ci/check_compliance.py b/scripts/ci/check_compliance.py index c9baa2adcd04..dae58cf20bdd 100755 --- a/scripts/ci/check_compliance.py +++ b/scripts/ci/check_compliance.py @@ -2404,11 +2404,6 @@ def _test_indent(txt: str): return -1 def check_file(self, file, fp): - mime_type = magic.from_file(os.fspath(file), mime=True) - - if not mime_type.startswith("text/"): - return - block_data = "" in_block = False @@ -2462,7 +2457,16 @@ def check_file(self, file, fp): def run(self): for file in get_files(filter="d"): - with open(file) as fp: + file_path = GIT_TOP / file + + mime_type = magic.from_file(os.fspath(file_path), mime=True) + if not mime_type.startswith("text/"): + continue + + # Text in the Zephyr tree is UTF-8. On Windows, the default text + # encoding depends on the active code page (e.g. GBK), which can + # break local runs with UnicodeDecodeError. + with open(file_path, encoding="utf-8", errors="surrogateescape") as fp: self.check_file(file, fp) From c6b369e1a31a50175e17ebc5c9d2a7e47195f07d Mon Sep 17 00:00:00 2001 From: Carlo Caione Date: Fri, 12 Dec 2025 19:25:29 +0100 Subject: [PATCH 0820/3659] drivers: lora: lbm: Add DIO1 GPIO callback API Add functions to register and unregister user GPIO callbacks for DIO1 interrupts on LBM lora radio devices. This allows external code (e.g., the LoRa Basics Modem HAL) to receive notifications when DIO1 fires. The driver configures the pin mask automatically based on the DIO1 pin from devicetree. Signed-off-by: Carlo Caione --- drivers/lora/lora_basics_modem/lbm_common.h | 37 ++++++++++++++ drivers/lora/lora_basics_modem/lbm_sx126x.c | 53 +++++++++++++++++++++ 2 files changed, 90 insertions(+) diff --git a/drivers/lora/lora_basics_modem/lbm_common.h b/drivers/lora/lora_basics_modem/lbm_common.h index 8ce24e780d5f..0194f22dc336 100644 --- a/drivers/lora/lora_basics_modem/lbm_common.h +++ b/drivers/lora/lora_basics_modem/lbm_common.h @@ -105,3 +105,40 @@ static inline int lbm_optional_gpio_set_dt(const struct gpio_dt_spec *spec, int /* Common LBM implementation of the LoRa API */ extern const struct lora_driver_api lbm_lora_api; + +/** + * @brief Add a GPIO callback for DIO1 interrupts + * + * This function registers a user callback that will be invoked from interrupt + * context when the DIO1 interrupt fires. The user must provide a pre-allocated + * gpio_callback structure. The driver will initialize the callback with the + * provided handler and the correct pin mask for the DIO1 pin. + * + * @param dev Modem device + * @param callback GPIO callback structure (will be initialized by driver) + * @param handler Callback handler function to be invoked on DIO1 interrupt + * + * @retval 0 On success + * @retval -ENODEV If device is not ready + * @retval -EINVAL If callback or handler is NULL + * @retval -ENOTSUP If GPIO driver doesn't support callbacks + * @retval -errno Other negative errno code on failure + */ +int lbm_driver_add_dio1_gpio_callback(const struct device *dev, + struct gpio_callback *callback, + gpio_callback_handler_t handler); + +/** + * @brief Remove a GPIO callback for DIO1 interrupts + * + * Remove a previously added GPIO callback. + * + * @param dev Modem device + * @param callback GPIO callback structure to remove + * + * @retval 0 On success + * @retval -EINVAL If callback not found + * @retval -errno Negative errno code on failure + */ +int lbm_driver_remove_dio1_gpio_callback(const struct device *dev, + struct gpio_callback *callback); diff --git a/drivers/lora/lora_basics_modem/lbm_sx126x.c b/drivers/lora/lora_basics_modem/lbm_sx126x.c index fa93a5e3218d..2908297d3e4c 100644 --- a/drivers/lora/lora_basics_modem/lbm_sx126x.c +++ b/drivers/lora/lora_basics_modem/lbm_sx126x.c @@ -440,6 +440,59 @@ static void sx126x_dio1_callback(const struct device *dev, struct gpio_callback k_work_schedule(&data->lbm_common.op_done_work, K_NO_WAIT); } +int lbm_driver_add_dio1_gpio_callback(const struct device *dev, + struct gpio_callback *callback, + gpio_callback_handler_t handler) +{ + const struct lbm_sx126x_config *config = dev->config; + int ret; + + if (!device_is_ready(dev)) { + return -ENODEV; + } + + if (callback == NULL || handler == NULL) { + return -EINVAL; + } + + gpio_init_callback(callback, handler, BIT(config->dio1.pin)); + + ret = gpio_add_callback(config->dio1.port, callback); + if (ret < 0) { + LOG_ERR("Failed to add GPIO callback: %d", ret); + return ret; + } + + gpio_pin_interrupt_configure_dt(&config->dio1, GPIO_INT_EDGE_TO_ACTIVE); + + LOG_DBG("Added user GPIO callback"); + return 0; +} + +int lbm_driver_remove_dio1_gpio_callback(const struct device *dev, + struct gpio_callback *callback) +{ + const struct lbm_sx126x_config *config = dev->config; + int ret; + + if (!device_is_ready(dev)) { + return -ENODEV; + } + + if (callback == NULL) { + return -EINVAL; + } + + ret = gpio_remove_callback(config->dio1.port, callback); + if (ret < 0) { + LOG_ERR("Failed to remove GPIO callback: %d", ret); + return ret; + } + + LOG_DBG("Removed user GPIO callback"); + return 0; +} + static int sx126x_init(const struct device *dev) { const struct lbm_sx126x_config *config = dev->config; From 54d4cdc8979554969e4d5c40f7b215739f1a2643 Mon Sep 17 00:00:00 2001 From: Carlo Caione Date: Fri, 12 Dec 2025 19:26:09 +0100 Subject: [PATCH 0821/3659] drivers: lora: lbm: Defer radio initialization until first config Split device initialization into two phases across all LBM drivers: 1. Boot-time init: Minimal device initialization 2. First config: Radio hardware initialization This deferred initialization approach provides full control over the radio hardware, allowing applications to perform any necessary setup before the radio is initialized. The radio init is automatically triggered on the first call to lora_config(). Signed-off-by: Carlo Caione --- drivers/lora/lora_basics_modem/Kconfig | 8 +++ drivers/lora/lora_basics_modem/lbm_common.c | 9 +++ drivers/lora/lora_basics_modem/lbm_common.h | 15 +++++ drivers/lora/lora_basics_modem/lbm_sx126x.c | 68 +++++++++++++-------- drivers/lora/lora_basics_modem/lbm_sx127x.c | 60 ++++++++++++------ 5 files changed, 119 insertions(+), 41 deletions(-) diff --git a/drivers/lora/lora_basics_modem/Kconfig b/drivers/lora/lora_basics_modem/Kconfig index 561984468e37..2ef28b2f972d 100644 --- a/drivers/lora/lora_basics_modem/Kconfig +++ b/drivers/lora/lora_basics_modem/Kconfig @@ -34,4 +34,12 @@ config LORA_BASICS_MODEM_RSSI_REPORT_TYPE_SIGNAL endchoice +config LORA_BASICS_MODEM_DEFERRED_INIT + bool "Defer radio initialization until first use" + help + When enabled, radio hardware initialization (reset, interrupt + configuration) is deferred until the first call to lora_config(). + This allows applications to perform setup before the radio is + initialized. When disabled, the radio is fully initialized at boot. + endif diff --git a/drivers/lora/lora_basics_modem/lbm_common.c b/drivers/lora/lora_basics_modem/lbm_common.c index 9edb6b8c74c2..a7fce9dac74b 100644 --- a/drivers/lora/lora_basics_modem/lbm_common.c +++ b/drivers/lora/lora_basics_modem/lbm_common.c @@ -90,6 +90,15 @@ int lbm_lora_config(const struct device *dev, struct lora_modem_config *lora_con ral_status_t status; int ret; + /* Perform deferred radio initialization on first config */ + if (IS_ENABLED(CONFIG_LORA_BASICS_MODEM_DEFERRED_INIT) && !data->radio_initialized) { + ret = lbm_driver_radio_init(dev); + if (ret < 0) { + return ret; + } + data->radio_initialized = true; + } + /* Ensure available, decremented after configuration */ if (!modem_acquire(dev)) { return -EBUSY; diff --git a/drivers/lora/lora_basics_modem/lbm_common.h b/drivers/lora/lora_basics_modem/lbm_common.h index 0194f22dc336..e78b500a5b87 100644 --- a/drivers/lora/lora_basics_modem/lbm_common.h +++ b/drivers/lora/lora_basics_modem/lbm_common.h @@ -65,6 +65,8 @@ struct lbm_lora_data_common { /* Current modem state */ atomic_t modem_state; enum lbm_modem_mode modem_mode; + /* Radio initialization state */ + bool radio_initialized; }; /** @@ -77,6 +79,19 @@ struct lbm_lora_data_common { */ int lbm_lora_common_init(const struct device *dev); +/** + * @brief Initialize radio hardware + * + * Called by lbm_lora_config on first configuration to defer radio + * initialization until needed. Each driver must implement this function. + * + * @param dev Modem to initialize + * + * @retval 0 On success + * @retval -errno On failure + */ +int lbm_driver_radio_init(const struct device *dev); + /** * @brief Configure modem for a given mode * diff --git a/drivers/lora/lora_basics_modem/lbm_sx126x.c b/drivers/lora/lora_basics_modem/lbm_sx126x.c index 2908297d3e4c..ab71e64d16e4 100644 --- a/drivers/lora/lora_basics_modem/lbm_sx126x.c +++ b/drivers/lora/lora_basics_modem/lbm_sx126x.c @@ -493,13 +493,50 @@ int lbm_driver_remove_dio1_gpio_callback(const struct device *dev, return 0; } -static int sx126x_init(const struct device *dev) +int lbm_driver_radio_init(const struct device *dev) { const struct lbm_sx126x_config *config = dev->config; struct lbm_sx126x_data *data = dev->data; ral_status_t status; int ret; + /* Reset chip */ + status = ral_reset(&config->lbm_common.ralf.ral); + if (status != RAL_STATUS_OK) { + LOG_ERR("Reset failure (%d)", status); + return -EIO; + } + + /* Wait for chip to be ready */ + ret = sx126x_ensure_device_ready(dev, K_MSEC(100)); + if (ret) { + LOG_ERR("Failed to return to ready after reset"); + return -EIO; + } + + /* Common structure init */ + ret = lbm_lora_common_init(dev); + if (ret < 0) { + return ret; + } + + /* Configure and enable interrupts */ + gpio_init_callback(&data->dio1_callback, sx126x_dio1_callback, BIT(config->dio1.pin)); + if (gpio_add_callback(config->dio1.port, &data->dio1_callback) < 0) { + LOG_ERR("Could not set GPIO callback for DIO1 interrupt."); + return -EIO; + } + gpio_pin_interrupt_configure_dt(&config->dio1, GPIO_INT_EDGE_TO_ACTIVE); + + LOG_INF("Radio initialized"); + return 0; +} + +static int sx126x_init(const struct device *dev) +{ + const struct lbm_sx126x_config *config = dev->config; + struct lbm_sx126x_data *data = dev->data; + /* Validate hardware is ready */ if (!spi_is_ready_dt(&config->spi)) { LOG_ERR("SPI bus %s not ready", config->spi.bus->name); @@ -523,32 +560,15 @@ static int sx126x_init(const struct device *dev) gpio_pin_configure_dt(&config->rx_enable, GPIO_OUTPUT_INACTIVE); } - /* Configure interrupts */ - gpio_init_callback(&data->dio1_callback, sx126x_dio1_callback, BIT(config->dio1.pin)); - if (gpio_add_callback(config->dio1.port, &data->dio1_callback) < 0) { - LOG_ERR("Could not set GPIO callback for DIO1 interrupt."); - return -EIO; - } + /* Initialize data structure */ + data->dev = dev; - /* Reset chip on boot */ - status = ral_reset(&config->lbm_common.ralf.ral); - if (status != RAL_STATUS_OK) { - LOG_ERR("Reset failure (%d)", status); - return -EIO; + if (!IS_ENABLED(CONFIG_LORA_BASICS_MODEM_DEFERRED_INIT)) { + return lbm_driver_radio_init(dev); } - /* Wait for chip to be ready */ - ret = sx126x_ensure_device_ready(dev, K_MSEC(100)); - if (ret) { - LOG_ERR("Failed to return to ready after reset"); - return -EIO; - } - - /* Enable interrupts */ - gpio_pin_interrupt_configure_dt(&config->dio1, GPIO_INT_EDGE_TO_ACTIVE); - - /* Common structure init */ - return lbm_lora_common_init(dev); + LOG_INF("Device initialized (radio initialization deferred)"); + return 0; } #define SX126X_DEFINE(node_id, sx_variant) \ diff --git a/drivers/lora/lora_basics_modem/lbm_sx127x.c b/drivers/lora/lora_basics_modem/lbm_sx127x.c index 200fadee597e..7a62c1709ed8 100644 --- a/drivers/lora/lora_basics_modem/lbm_sx127x.c +++ b/drivers/lora/lora_basics_modem/lbm_sx127x.c @@ -365,11 +365,45 @@ static void sx127x_irq_handler(void *irq_context) k_work_reschedule(&data->lbm_common.op_done_work, K_NO_WAIT); } -static int sx127x_driver_init(const struct device *dev) +int lbm_driver_radio_init(const struct device *dev) { const struct lbm_sx127x_config *config = dev->config; struct lbm_sx127x_data *data = dev->data; ral_status_t status; + int ret; + + /* Reset chip */ + status = ral_reset(&config->lbm_common.ralf.ral); + if (status != RAL_STATUS_OK) { + LOG_ERR("Reset failure (%d)", status); + return -EIO; + } + + /* Common structure init */ + ret = lbm_lora_common_init(dev); + if (ret < 0) { + return ret; + } + + /* Configure and enable interrupts */ + for (int i = 0; i < MIN(config->num_dios, 3); i++) { + gpio_init_callback(&data->dio_packages[i].callback, sx127x_dio_callback, + BIT(config->dios[i].pin)); + if (gpio_add_callback(config->dios[i].port, &data->dio_packages[i].callback) < 0) { + LOG_ERR("Could not set GPIO callback for DIO%d interrupt.", i); + return -EIO; + } + gpio_pin_interrupt_configure_dt(&config->dios[i], GPIO_INT_EDGE_RISING); + } + + LOG_INF("Radio initialized"); + return 0; +} + +static int sx127x_driver_init(const struct device *dev) +{ + const struct lbm_sx127x_config *config = dev->config; + struct lbm_sx127x_data *data = dev->data; data->radio.hal_context = dev; data->radio.irq_handler_context = (void *)dev; @@ -403,30 +437,22 @@ static int sx127x_driver_init(const struct device *dev) gpio_pin_configure_dt(&config->tcxo_power, GPIO_OUTPUT_INACTIVE); } - /* Configure interrupts */ + /* Configure interrupt structures */ for (int i = 0; i < MIN(config->num_dios, 3); i++) { data->dio_packages[i].idx = i; k_work_init(&data->dio_packages[i].worker, dio_work_function); - gpio_pin_configure_dt(&config->dios[i], GPIO_INPUT); - gpio_init_callback(&data->dio_packages[i].callback, sx127x_dio_callback, - BIT(config->dios[i].pin)); - if (gpio_add_callback(config->dios[i].port, &data->dio_packages[i].callback) < 0) { - LOG_ERR("Could not set GPIO callback for DIO%d interrupt.", i); - return -EIO; - } - gpio_pin_interrupt_configure_dt(&config->dios[i], GPIO_INT_EDGE_RISING); } - /* Reset chip on boot */ - status = ral_reset(&config->lbm_common.ralf.ral); - if (status != RAL_STATUS_OK) { - LOG_ERR("Reset failure (%d)", status); - return -EIO; + /* Initialize data structure */ + data->dev = dev; + + if (!IS_ENABLED(CONFIG_LORA_BASICS_MODEM_DEFERRED_INIT)) { + return lbm_driver_radio_init(dev); } - /* Common structure init */ - return lbm_lora_common_init(dev); + LOG_INF("Device initialized (radio initialization deferred)"); + return 0; } #define SX127X_DIO_GPIO_ELEM(idx, node_id) GPIO_DT_SPEC_GET_BY_IDX(node_id, dio_gpios, idx) From 7371e94ec7a5d140003ca7cdf887681fe76a7c46 Mon Sep 17 00:00:00 2001 From: Zhaoxiang Jin Date: Thu, 18 Dec 2025 22:05:36 +0800 Subject: [PATCH 0822/3659] dts: bindings: rename nxp,lpcmp.yaml to nxp,sensor-lpcmp.yaml We are planning to implement a new LPCMP driver based on the comparator API and deprecate the current sensor-based driver. We would like to use the nxp,lpcmp binding for the new comparator-based driver implementation. To avoid naming conflicts, we are renaming the current sensor binding to nxp,sensor-lpcmp. Signed-off-by: Zhaoxiang Jin --- drivers/sensor/nxp/mcux_lpcmp/Kconfig | 2 +- drivers/sensor/nxp/mcux_lpcmp/mcux_lpcmp.c | 2 +- dts/bindings/sensor/{nxp,lpcmp.yaml => nxp,sensor-lpcmp.yaml} | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) rename dts/bindings/sensor/{nxp,lpcmp.yaml => nxp,sensor-lpcmp.yaml} (97%) diff --git a/drivers/sensor/nxp/mcux_lpcmp/Kconfig b/drivers/sensor/nxp/mcux_lpcmp/Kconfig index 3e04b3c26c82..0b3948106f90 100644 --- a/drivers/sensor/nxp/mcux_lpcmp/Kconfig +++ b/drivers/sensor/nxp/mcux_lpcmp/Kconfig @@ -6,7 +6,7 @@ config MCUX_LPCMP bool "NXP LPCMP driver" default y - depends on DT_HAS_NXP_LPCMP_ENABLED + depends on DT_HAS_NXP_SENSOR_LPCMP_ENABLED select PINCTRL help Enable the MCUX LPCMP driver. diff --git a/drivers/sensor/nxp/mcux_lpcmp/mcux_lpcmp.c b/drivers/sensor/nxp/mcux_lpcmp/mcux_lpcmp.c index 9e7698c9c3a1..ab205e8081e3 100644 --- a/drivers/sensor/nxp/mcux_lpcmp/mcux_lpcmp.c +++ b/drivers/sensor/nxp/mcux_lpcmp/mcux_lpcmp.c @@ -5,7 +5,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#define DT_DRV_COMPAT nxp_lpcmp +#define DT_DRV_COMPAT nxp_sensor_lpcmp #include #include diff --git a/dts/bindings/sensor/nxp,lpcmp.yaml b/dts/bindings/sensor/nxp,sensor-lpcmp.yaml similarity index 97% rename from dts/bindings/sensor/nxp,lpcmp.yaml rename to dts/bindings/sensor/nxp,sensor-lpcmp.yaml index 841215956326..bef97defae17 100644 --- a/dts/bindings/sensor/nxp,lpcmp.yaml +++ b/dts/bindings/sensor/nxp,sensor-lpcmp.yaml @@ -3,7 +3,7 @@ description: NXP low-power analog comparator (LPCMP) -compatible: "nxp,lpcmp" +compatible: "nxp,sensor-lpcmp" include: [sensor-device.yaml, pinctrl-device.yaml] From f85158fea5472eba852e1bb2c77b05a091e1f743 Mon Sep 17 00:00:00 2001 From: Zhaoxiang Jin Date: Thu, 18 Dec 2025 22:10:37 +0800 Subject: [PATCH 0823/3659] drivers: sensor: mark mcux_lpcmp as deprecated We are planning to implement a new lpcmp driver based on the comparator API and deprecate the current sensor-based driver. We now mark the mcux_lpcmp as deprecated. Signed-off-by: Zhaoxiang Jin --- drivers/sensor/nxp/mcux_lpcmp/Kconfig | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/sensor/nxp/mcux_lpcmp/Kconfig b/drivers/sensor/nxp/mcux_lpcmp/Kconfig index 0b3948106f90..4c37c80443fd 100644 --- a/drivers/sensor/nxp/mcux_lpcmp/Kconfig +++ b/drivers/sensor/nxp/mcux_lpcmp/Kconfig @@ -4,15 +4,22 @@ # SPDX-License-Identifier: Apache-2.0 config MCUX_LPCMP - bool "NXP LPCMP driver" + bool "NXP LPCMP driver [DEPRECATED]" default y depends on DT_HAS_NXP_SENSOR_LPCMP_ENABLED select PINCTRL + select DEPRECATED help Enable the MCUX LPCMP driver. + This driver is deprecated and will be removed in a future release. + It is currently scheduled to be removed in Zephyr 4.6. + We will implement a new LPCMP driver based on the comparator driver + API and enable test cases for boards/SoCs that previously supported + the mcux_lpcmp driver and sample. + config MCUX_LPCMP_TRIGGER - bool "Trigger support" + bool "Trigger support [DEPRECATED]" depends on MCUX_LPCMP help Enable trigger support for the NXP LPCMP. From f6f8c42b67e9ce9ac5dbe3b67140a01bb13e2dd2 Mon Sep 17 00:00:00 2001 From: Zhaoxiang Jin Date: Sun, 14 Dec 2025 12:30:11 +0800 Subject: [PATCH 0824/3659] drivers: comparator: enable nxp lpcmp driver enable nxp lpcmp driver based on the comparator driver API Signed-off-by: Zhaoxiang Jin --- drivers/comparator/CMakeLists.txt | 1 + drivers/comparator/Kconfig | 1 + drivers/comparator/Kconfig.nxp_lpcmp | 8 + drivers/comparator/comparator_nxp_lpcmp.c | 350 ++++++++++++++++++++++ dts/bindings/comparator/nxp,lpcmp.yaml | 122 ++++++++ 5 files changed, 482 insertions(+) create mode 100644 drivers/comparator/Kconfig.nxp_lpcmp create mode 100644 drivers/comparator/comparator_nxp_lpcmp.c create mode 100644 dts/bindings/comparator/nxp,lpcmp.yaml diff --git a/drivers/comparator/CMakeLists.txt b/drivers/comparator/CMakeLists.txt index 2b2fd1df69b4..e15c0f7d227c 100644 --- a/drivers/comparator/CMakeLists.txt +++ b/drivers/comparator/CMakeLists.txt @@ -17,6 +17,7 @@ zephyr_library_sources_ifdef(CONFIG_COMPARATOR_NRF_LPCOMP comparator_nrf_lpcomp. zephyr_library_sources_ifdef(CONFIG_COMPARATOR_NXP_ACOMP comparator_nxp_acomp.c) zephyr_library_sources_ifdef(CONFIG_COMPARATOR_NXP_CMP comparator_nxp_cmp.c) zephyr_library_sources_ifdef(CONFIG_COMPARATOR_NXP_HSCMP comparator_nxp_hscmp.c) +zephyr_library_sources_ifdef(CONFIG_COMPARATOR_NXP_LPCMP comparator_nxp_lpcmp.c) zephyr_library_sources_ifdef(CONFIG_COMPARATOR_RENESAS_RA comparator_renesas_ra.c) zephyr_library_sources_ifdef(CONFIG_COMPARATOR_RENESAS_RA_LVD comparator_renesas_ra_lvd.c) zephyr_library_sources_ifdef(CONFIG_COMPARATOR_RENESAS_RX_LVD comparator_renesas_rx_lvd.c) diff --git a/drivers/comparator/Kconfig b/drivers/comparator/Kconfig index 778ea63d13d4..d6c9c7ce9c3d 100644 --- a/drivers/comparator/Kconfig +++ b/drivers/comparator/Kconfig @@ -28,6 +28,7 @@ rsource "Kconfig.nrf_lpcomp" rsource "Kconfig.nxp_acomp" rsource "Kconfig.nxp_cmp" rsource "Kconfig.nxp_hscmp" +rsource "Kconfig.nxp_lpcmp" rsource "Kconfig.renesas_ra" rsource "Kconfig.renesas_rx" rsource "Kconfig.shell" diff --git a/drivers/comparator/Kconfig.nxp_lpcmp b/drivers/comparator/Kconfig.nxp_lpcmp new file mode 100644 index 000000000000..94a1660fee7d --- /dev/null +++ b/drivers/comparator/Kconfig.nxp_lpcmp @@ -0,0 +1,8 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +config COMPARATOR_NXP_LPCMP + bool "NXP LPCMP comparator driver" + default y + depends on DT_HAS_NXP_LPCMP_ENABLED + select CLOCK_CONTROL diff --git a/drivers/comparator/comparator_nxp_lpcmp.c b/drivers/comparator/comparator_nxp_lpcmp.c new file mode 100644 index 000000000000..eee0a2a91efe --- /dev/null +++ b/drivers/comparator/comparator_nxp_lpcmp.c @@ -0,0 +1,350 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(nxp_lpcmp, CONFIG_COMPARATOR_LOG_LEVEL); + +#define DT_DRV_COMPAT nxp_lpcmp + +struct nxp_lpcmp_config { + LPCMP_Type *base; + bool enable_stop_mode; + bool invert_output; + bool enable_pin_out; + bool use_unfiltered_output; + bool positive_mux_is_dac; + bool negative_mux_is_dac; + uint8_t filter_count; + uint8_t filter_period; + uint8_t positive_mux_input; + uint8_t negative_mux_input; + uint8_t dac_value; + uint8_t dac_vref_source; + uint8_t hysteresis_mode; + uint8_t power_mode; + const struct device *clock_dev; + clock_control_subsys_t clock_subsys; + void (*irq_config_func)(const struct device *dev); +}; + +struct nxp_lpcmp_data { + uint8_t interrupt_mask; + comparator_callback_t callback; + void *user_data; +}; + +static int nxp_lpcmp_get_output(const struct device *dev) +{ + const struct nxp_lpcmp_config *config = dev->config; + + return (config->base->CSR & LPCMP_CSR_COUT_MASK) ? 1 : 0; +} + +static int nxp_lpcmp_set_trigger(const struct device *dev, enum comparator_trigger trigger) +{ + const struct nxp_lpcmp_config *config = dev->config; + struct nxp_lpcmp_data *data = dev->data; + + config->base->IER &= ~(LPCMP_IER_CFR_IE_MASK | LPCMP_IER_CFF_IE_MASK); + data->interrupt_mask = 0U; + + switch (trigger) { + case COMPARATOR_TRIGGER_NONE: + break; + case COMPARATOR_TRIGGER_RISING_EDGE: + data->interrupt_mask = LPCMP_IER_CFR_IE_MASK; + break; + case COMPARATOR_TRIGGER_FALLING_EDGE: + data->interrupt_mask = LPCMP_IER_CFF_IE_MASK; + break; + case COMPARATOR_TRIGGER_BOTH_EDGES: + data->interrupt_mask = LPCMP_IER_CFR_IE_MASK | LPCMP_IER_CFF_IE_MASK; + break; + default: + LOG_ERR("Invalid trigger type."); + return -EINVAL; + } + + /* Clear latched status flags before enabling interrupts. */ + config->base->CSR |= (LPCMP_CSR_CFF_MASK | LPCMP_CSR_CFR_MASK); + + if ((data->interrupt_mask != 0U) && (data->callback != NULL)) { + config->base->IER |= data->interrupt_mask; + } + + return 0; +} + +static int nxp_lpcmp_trigger_is_pending(const struct device *dev) +{ + const struct nxp_lpcmp_config *config = dev->config; + struct nxp_lpcmp_data *data = dev->data; + uint32_t status_flags; + + status_flags = config->base->CSR & (LPCMP_CSR_CFF_MASK | LPCMP_CSR_CFR_MASK); + config->base->CSR |= (LPCMP_CSR_CFF_MASK | LPCMP_CSR_CFR_MASK); + + if (((data->interrupt_mask & LPCMP_IER_CFF_IE_MASK) != 0U) && + ((status_flags & LPCMP_CSR_CFF_MASK) != 0U)) { + return 1; + } + + if (((data->interrupt_mask & LPCMP_IER_CFR_IE_MASK) != 0U) && + ((status_flags & LPCMP_CSR_CFR_MASK) != 0U)) { + return 1; + } + + return 0; +} + +static int nxp_lpcmp_set_trigger_callback(const struct device *dev, comparator_callback_t callback, + void *user_data) +{ + const struct nxp_lpcmp_config *config = dev->config; + struct nxp_lpcmp_data *data = dev->data; + + config->base->CCR0 &= ~LPCMP_CCR0_CMP_EN_MASK; + + data->callback = callback; + data->user_data = user_data; + + /* Clear any pending flags when (re)arming the callback. */ + config->base->CSR |= (LPCMP_CSR_CFF_MASK | LPCMP_CSR_CFR_MASK); + + if ((data->callback != NULL) && (data->interrupt_mask != 0U)) { + config->base->IER |= data->interrupt_mask; + } else { + config->base->IER &= ~(LPCMP_IER_CFR_IE_MASK | LPCMP_IER_CFF_IE_MASK); + } + + config->base->CCR0 |= LPCMP_CCR0_CMP_EN_MASK; + + return 0; +} + +static void nxp_lpcmp_irq_handler(const struct device *dev) +{ + const struct nxp_lpcmp_config *config = dev->config; + struct nxp_lpcmp_data *data = dev->data; + + /* Clear interrupt status flags */ + config->base->CSR |= (LPCMP_CSR_CFF_MASK | LPCMP_CSR_CFR_MASK); + + if (data->callback == NULL) { + LOG_WRN("No callback can be executed."); + return; + } + + data->callback(dev, data->user_data); +} + +#if CONFIG_PM_DEVICE +static int nxp_lpcmp_pm_callback(const struct device *dev, enum pm_device_action action) +{ + const struct nxp_lpcmp_config *config = dev->config; + + if (action == PM_DEVICE_ACTION_RESUME) { + config->base->CCR0 |= LPCMP_CCR0_CMP_EN_MASK; + return 0; + } + + if (action == PM_DEVICE_ACTION_SUSPEND) { + config->base->CCR0 &= ~LPCMP_CCR0_CMP_EN_MASK; + return 0; + } + + return -ENOTSUP; +} +#endif + +static int nxp_lpcmp_init(const struct device *dev) +{ + const struct nxp_lpcmp_config *config = dev->config; + LPCMP_Type *base = config->base; + int ret; + + if (config->clock_dev != NULL) { + if (!device_is_ready(config->clock_dev)) { + LOG_ERR("Clock device is not ready"); + return -ENODEV; + } + + ret = clock_control_on(config->clock_dev, config->clock_subsys); + if (ret != 0) { + LOG_ERR("Device clock turn on failed (%d)", ret); + return ret; + } + } + + /* Disable comparator before configuring. */ + base->CCR0 &= ~LPCMP_CCR0_CMP_EN_MASK; + +#if defined(LPCMP_CCR0_CMP_STOP_EN_MASK) + base->CCR0 = ((base->CCR0 & ~(LPCMP_CCR0_CMP_STOP_EN_MASK)) | + LPCMP_CCR0_CMP_STOP_EN(config->enable_stop_mode ? 1U : 0U)); +#endif + + uint32_t ccr1 = base->CCR1; + + ccr1 = ((ccr1 & ~(LPCMP_CCR1_COUT_INV_MASK | LPCMP_CCR1_COUT_PEN_MASK | + LPCMP_CCR1_COUT_SEL_MASK | LPCMP_CCR1_FILT_CNT_MASK | + LPCMP_CCR1_FILT_PER_MASK)) | + LPCMP_CCR1_COUT_INV(config->invert_output ? 1U : 0U) | + LPCMP_CCR1_COUT_PEN(config->enable_pin_out ? 1U : 0U)); + + if (config->use_unfiltered_output) { + ccr1 |= LPCMP_CCR1_COUT_SEL_MASK; + } else { + ccr1 &= ~LPCMP_CCR1_COUT_SEL_MASK; + if (config->filter_count != 0U) { + ccr1 |= LPCMP_CCR1_FILT_CNT(config->filter_count); + ccr1 |= LPCMP_CCR1_FILT_PER(config->filter_period); + } + } + base->CCR1 = ccr1; + + uint32_t ccr2 = base->CCR2; + + ccr2 = ((ccr2 & ~(LPCMP_CCR2_CMP_HPMD_MASK | LPCMP_CCR2_HYSTCTR_MASK | + LPCMP_CCR2_PSEL_MASK | LPCMP_CCR2_MSEL_MASK)) | + LPCMP_CCR2_HYSTCTR(config->hysteresis_mode) | + LPCMP_CCR2_CMP_HPMD(config->power_mode == 1U)); + +#if defined(LPCMP_CCR2_INPSEL_MASK) && defined(LPCMP_CCR2_INMSEL_MASK) + ccr2 &= ~(LPCMP_CCR2_INPSEL_MASK | LPCMP_CCR2_INMSEL_MASK); + + if (config->positive_mux_is_dac) { + ccr2 |= LPCMP_CCR2_INPSEL(0U); + } else { + ccr2 |= (LPCMP_CCR2_INPSEL(1U) | LPCMP_CCR2_PSEL(config->positive_mux_input)); + } + + if (config->negative_mux_is_dac) { + ccr2 |= LPCMP_CCR2_INMSEL(0U); + } else { + ccr2 |= (LPCMP_CCR2_INMSEL(1U) | LPCMP_CCR2_MSEL(config->negative_mux_input)); + } +#else + uint8_t psel, msel; + + if (config->positive_mux_is_dac) { + psel = 7U; + } else { + psel = config->positive_mux_input; + } + + if (config->negative_mux_is_dac) { + msel = 7U; + } else { + msel = config->negative_mux_input; + } + + ccr2 |= (LPCMP_CCR2_PSEL(psel) | LPCMP_CCR2_MSEL(msel)); +#endif + + base->CCR2 = ccr2; + + /* Configure DAC if needed. */ + base->DCR &= ~(LPCMP_DCR_DAC_EN_MASK | LPCMP_DCR_VRSEL_MASK | LPCMP_DCR_DAC_DATA_MASK); + + if (config->positive_mux_is_dac || config->negative_mux_is_dac) { + base->DCR |= (LPCMP_DCR_VRSEL(config->dac_vref_source) | + LPCMP_DCR_DAC_DATA(config->dac_value) | LPCMP_DCR_DAC_EN_MASK); + } + + /* Clear status flags before enabling interrupts or the comparator. */ + base->CSR = (LPCMP_CSR_CFF_MASK | LPCMP_CSR_CFR_MASK); + base->IER &= ~(LPCMP_IER_CFR_IE_MASK | LPCMP_IER_CFF_IE_MASK); + + config->irq_config_func(dev); + + base->CCR0 |= LPCMP_CCR0_CMP_EN_MASK; + +#if CONFIG_PM_DEVICE + return pm_device_driver_init(dev, nxp_lpcmp_pm_callback); +#else + return 0; +#endif +} + +static DEVICE_API(comparator, nxp_lpcmp_api) = { + .get_output = nxp_lpcmp_get_output, + .set_trigger = nxp_lpcmp_set_trigger, + .set_trigger_callback = nxp_lpcmp_set_trigger_callback, + .trigger_is_pending = nxp_lpcmp_trigger_is_pending, +}; + +#define LPCMP_DT_ENUM_IDX(inst, prop, default_val) \ + DT_ENUM_IDX_OR(DT_DRV_INST(inst), prop, default_val) + +#define LPCMP_DT_MUX_IDX(inst, prop) LPCMP_DT_ENUM_IDX(inst, prop, 0) + +#define LPCMP_DT_MUX_IS_DAC(inst, prop) DT_ENUM_HAS_VALUE(DT_DRV_INST(inst), prop, dac) + +#if CONFIG_PM_DEVICE +#define LPCMP_PM_DEVICE_DEFINE PM_DEVICE_DT_INST_DEFINE(inst, nxp_lpcmp_pm_callback); +#define LPCMP_PM_DEVICE_GET PM_DEVICE_DT_INST_GET(inst) +#else +#define LPCMP_PM_DEVICE_DEFINE +#define LPCMP_PM_DEVICE_GET NULL +#endif + +#define LPCMP_HAS_CLOCKS(inst) DT_INST_NODE_HAS_PROP(inst, clocks) + +#define LPCMP_CLOCK_DEV(inst) \ + COND_CODE_1(LPCMP_HAS_CLOCKS(inst), (DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(inst))), (NULL)) + +#define LPCMP_CLOCK_SUBSYS(inst) \ + COND_CODE_1(LPCMP_HAS_CLOCKS(inst), \ + ((clock_control_subsys_t)DT_INST_CLOCKS_CELL(inst, name)), (NULL)) + +#define NXP_LPCMP_DEVICE_INIT(inst) \ + \ + static struct nxp_lpcmp_data _CONCAT(data, inst) = { \ + .interrupt_mask = 0U, \ + }; \ + \ + LPCMP_PM_DEVICE_DEFINE \ + \ + static void _CONCAT(nxp_lpcmp_irq_config, inst)(const struct device *dev) \ + { \ + IRQ_CONNECT(DT_INST_IRQN(inst), DT_INST_IRQ(inst, priority), \ + nxp_lpcmp_irq_handler, DEVICE_DT_INST_GET(inst), 0); \ + irq_enable(DT_INST_IRQN(inst)); \ + } \ + \ + static const struct nxp_lpcmp_config _CONCAT(config, inst) = { \ + .base = (LPCMP_Type *)DT_INST_REG_ADDR(inst), \ + .enable_stop_mode = DT_INST_PROP_OR(inst, enable_stop_mode, 0), \ + .invert_output = DT_INST_PROP_OR(inst, invert_output, 0), \ + .enable_pin_out = DT_INST_PROP_OR(inst, enable_pin_out, 0), \ + .use_unfiltered_output = DT_INST_PROP_OR(inst, use_unfiltered_output, 0), \ + .filter_count = DT_INST_PROP_OR(inst, filter_count, 0), \ + .filter_period = DT_INST_PROP_OR(inst, filter_period, 0), \ + .positive_mux_is_dac = LPCMP_DT_MUX_IS_DAC(inst, positive_mux_input), \ + .negative_mux_is_dac = LPCMP_DT_MUX_IS_DAC(inst, negative_mux_input), \ + .positive_mux_input = LPCMP_DT_MUX_IDX(inst, positive_mux_input), \ + .negative_mux_input = LPCMP_DT_MUX_IDX(inst, negative_mux_input), \ + .dac_value = DT_INST_PROP_OR(inst, dac_value, 0), \ + .dac_vref_source = LPCMP_DT_ENUM_IDX(inst, dac_vref_source, 0), \ + .hysteresis_mode = DT_INST_ENUM_IDX_OR(inst, hysteresis_mode, 0), \ + .power_mode = LPCMP_DT_ENUM_IDX(inst, power_mode, 0), \ + .clock_dev = LPCMP_CLOCK_DEV(inst), \ + .clock_subsys = LPCMP_CLOCK_SUBSYS(inst), \ + .irq_config_func = _CONCAT(nxp_lpcmp_irq_config, inst), \ + }; \ + \ + DEVICE_DT_INST_DEFINE(inst, nxp_lpcmp_init, LPCMP_PM_DEVICE_GET, \ + &_CONCAT(data, inst), &_CONCAT(config, inst), POST_KERNEL, \ + CONFIG_COMPARATOR_INIT_PRIORITY, &nxp_lpcmp_api); + +DT_INST_FOREACH_STATUS_OKAY(NXP_LPCMP_DEVICE_INIT) diff --git a/dts/bindings/comparator/nxp,lpcmp.yaml b/dts/bindings/comparator/nxp,lpcmp.yaml new file mode 100644 index 000000000000..38ec925287ae --- /dev/null +++ b/dts/bindings/comparator/nxp,lpcmp.yaml @@ -0,0 +1,122 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +description: | + NXP Low Power Comparator (LPCMP) + +compatible: "nxp,lpcmp" + +include: + - base.yaml + - pinctrl-device.yaml + +properties: + reg: + required: true + + interrupts: + required: true + + power-mode: + type: string + enum: + - "low_speed" + - "high_speed" + description: | + Select comparator power/speed mode. + + hysteresis-mode: + type: string + enum: + - "LEVEL0" + - "LEVEL1" + - "LEVEL2" + - "LEVEL3" + description: | + Comparator hysteresis level. + + enable-stop-mode: + type: boolean + description: | + Allow the comparator to remain enabled in STOP/STANDBY mode. + NOTE: This property is not available on MCXN23x devices. + + invert-output: + type: boolean + description: | + Invert comparator output. + + enable-pin-out: + type: boolean + description: | + Drive comparator output on the associated pin. + + use-unfiltered-output: + type: boolean + description: | + Route unfiltered comparator output (COUTA) to the module output. + When false, the filtered output (COUT) is used and filter parameters + are taken from filter-count and filter-period. + + filter-count: + type: int + enum: [0, 1, 2, 3, 4, 5, 6, 7] + description: | + Number of consecutive samples that must agree before updating + the filtered output. Set to 0 to bypass the filter. + + filter-period: + type: int + description: | + Sampling period for the filter in bus clock cycles. + Valid range: 0 - 255. + + dac-vref-source: + type: string + enum: + - "VREFH0" + - "VREFH1" + description: | + DAC reference high-voltage source selection. + + dac-value: + type: int + description: | + 8-bit DAC code used when an input is set to DAC output. + Valid range: 0 - 255. + + positive-mux-input: + type: string + enum: + - "IN0" + - "IN1" + - "IN2" + - "IN3" + - "IN4" + - "IN5" + - "IN6" + - "IN7" + - "DAC" + required: true + description: | + Positive input selection. "DAC" routes the internal DAC output. + NOTE: For MCXN/A devices, IN6 and IN7 are not available, only + IN0-IN5 and DAC. + + negative-mux-input: + type: string + enum: + - "IN0" + - "IN1" + - "IN2" + - "IN3" + - "IN4" + - "IN5" + - "IN6" + - "IN7" + - "DAC" + required: true + description: | + Negative input selection. "DAC" routes the internal DAC output. + NOTE: For MCXN/A devices, IN6 and IN7 are not available, only + IN0-IN5 and DAC. From 3cf811e30263e57a7d942093880f79e532b963d5 Mon Sep 17 00:00:00 2001 From: Zhaoxiang Jin Date: Sun, 14 Dec 2025 11:51:24 +0800 Subject: [PATCH 0825/3659] drivers: clock_control: Enable clock control for lpcmp 1. Enable MCXA/MCXN platforms' LPCMP clock control through the clock driver (syscon). 2. Enable MCXE platform's LPCMP clock control through the clock driver (mc_cgm). Signed-off-by: Zhaoxiang Jin --- .../clock_control/clock_control_mcux_syscon.c | 33 +++++++++++++++++++ .../clock_control/clock_control_nxp_mc_cgm.c | 16 +++++++++ .../dt-bindings/clock/mcux_lpc_syscon_clock.h | 4 +++ 3 files changed, 53 insertions(+) diff --git a/drivers/clock_control/clock_control_mcux_syscon.c b/drivers/clock_control/clock_control_mcux_syscon.c index 62817337dab9..b7d98e0cad5a 100644 --- a/drivers/clock_control/clock_control_mcux_syscon.c +++ b/drivers/clock_control/clock_control_mcux_syscon.c @@ -221,6 +221,39 @@ static int mcux_lpc_syscon_clock_control_on(const struct device *dev, #endif #endif +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(lpcmp0)) + if ((uint32_t)sub_system == MCUX_LPCMP0_CLK) { +#if defined(CONFIG_SOC_FAMILY_MCXA) + CLOCK_EnableClock(kCLOCK_GateCMP0); +#elif defined(CONFIG_SOC_FAMILY_MCXN) +#else + CLOCK_EnableClock(kCLOCK_Lpcmp0); +#endif + } +#endif + +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(lpcmp1)) + if ((uint32_t)sub_system == MCUX_LPCMP1_CLK) { +#if defined(CONFIG_SOC_FAMILY_MCXA) + CLOCK_EnableClock(kCLOCK_GateCMP1); +#elif defined(CONFIG_SOC_FAMILY_MCXN) +#else + CLOCK_EnableClock(kCLOCK_Lpcmp1); +#endif + } +#endif + +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(lpcmp2)) + if ((uint32_t)sub_system == MCUX_LPCMP2_CLK) { +#if defined(CONFIG_SOC_FAMILY_MCXA) + CLOCK_EnableClock(kCLOCK_GateCMP2); +#elif defined(CONFIG_SOC_FAMILY_MCXN) +#else + CLOCK_EnableClock(kCLOCK_Lpcmp2); +#endif + } +#endif + return 0; } diff --git a/drivers/clock_control/clock_control_nxp_mc_cgm.c b/drivers/clock_control/clock_control_nxp_mc_cgm.c index 6a0ffdae8972..0a200b2e7d65 100644 --- a/drivers/clock_control/clock_control_nxp_mc_cgm.c +++ b/drivers/clock_control/clock_control_nxp_mc_cgm.c @@ -173,6 +173,22 @@ static int mc_cgm_clock_control_on(const struct device *dev, clock_control_subsy } #endif /* defined(CONFIG_COUNTER_MCUX_STM) */ +#if defined(CONFIG_COMPARATOR_NXP_LPCMP) + switch ((uint32_t)sub_system) { + case MCUX_CMP0_CLK: + CLOCK_EnableClock(kCLOCK_Lpcmp0); + break; + case MCUX_CMP1_CLK: + CLOCK_EnableClock(kCLOCK_Lpcmp1); + break; + case MCUX_CMP2_CLK: + CLOCK_EnableClock(kCLOCK_Lpcmp2); + break; + default: + break; + } +#endif /* CONFIG_COMPARATOR_NXP_HSCMP */ + return 0; } 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 1b7949707821..632a872f3727 100644 --- a/include/zephyr/dt-bindings/clock/mcux_lpc_syscon_clock.h +++ b/include/zephyr/dt-bindings/clock/mcux_lpc_syscon_clock.h @@ -152,4 +152,8 @@ #define MCUX_HSCMP1_CLK MCUX_LPC_CLK_ID(0x21, 0x01) #define MCUX_HSCMP2_CLK MCUX_LPC_CLK_ID(0x21, 0x02) +#define MCUX_LPCMP0_CLK MCUX_LPC_CLK_ID(0x22, 0x00) +#define MCUX_LPCMP1_CLK MCUX_LPC_CLK_ID(0x22, 0x01) +#define MCUX_LPCMP2_CLK MCUX_LPC_CLK_ID(0x22, 0x02) + #endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_MCUX_LPC_SYSCON_H_ */ From f70d57a60743d096a0a05266645cb4ecf45336cc Mon Sep 17 00:00:00 2001 From: Zhaoxiang Jin Date: Thu, 18 Dec 2025 22:26:54 +0800 Subject: [PATCH 0826/3659] dts: nxp: Update lpcmp nodes for some SoCs 1. We shall set the proper clock source for lpcmp. 2. The property '#io-channel-cells' is currently not needed for LPCMP. Signed-off-by: Zhaoxiang Jin --- dts/arm/nxp/nxp_mcxa153.dtsi | 4 ++-- dts/arm/nxp/nxp_mcxa156.dtsi | 4 ++-- dts/arm/nxp/nxp_mcxaxx6_common.dtsi | 6 +++--- dts/arm/nxp/nxp_mcxe31x_common.dtsi | 3 +++ dts/arm/nxp/nxp_mcxn23x_common.dtsi | 2 -- dts/arm/nxp/nxp_mcxn94x_common.dtsi | 1 - dts/arm/nxp/nxp_mcxnx4x_common.dtsi | 2 -- 7 files changed, 10 insertions(+), 12 deletions(-) diff --git a/dts/arm/nxp/nxp_mcxa153.dtsi b/dts/arm/nxp/nxp_mcxa153.dtsi index ea4d87569d7b..33ffda8f7801 100644 --- a/dts/arm/nxp/nxp_mcxa153.dtsi +++ b/dts/arm/nxp/nxp_mcxa153.dtsi @@ -245,7 +245,7 @@ reg = <0x400b1000 0x1000>; interrupts = <64 0>; status = "disabled"; - #io-channel-cells = <2>; + clocks = <&syscon MCUX_LPCMP0_CLK>; }; lpcmp1: lpcmp@400b2000 { @@ -253,7 +253,7 @@ reg = <0x400b2000 0x1000>; interrupts = <65 0>; status = "disabled"; - #io-channel-cells = <2>; + clocks = <&syscon MCUX_LPCMP1_CLK>; }; lpi2c0: i2c@4009a000 { diff --git a/dts/arm/nxp/nxp_mcxa156.dtsi b/dts/arm/nxp/nxp_mcxa156.dtsi index c4863ef63238..9fd5383c9208 100644 --- a/dts/arm/nxp/nxp_mcxa156.dtsi +++ b/dts/arm/nxp/nxp_mcxa156.dtsi @@ -413,7 +413,7 @@ reg = <0x400b1000 0x1000>; interrupts = <64 0>; status = "disabled"; - #io-channel-cells = <2>; + clocks = <&syscon MCUX_LPCMP0_CLK>; }; lpcmp1: lpcmp@400b2000 { @@ -421,7 +421,7 @@ reg = <0x400b2000 0x1000>; interrupts = <65 0>; status = "disabled"; - #io-channel-cells = <2>; + clocks = <&syscon MCUX_LPCMP1_CLK>; }; opamp0: opamp@400b7000 { diff --git a/dts/arm/nxp/nxp_mcxaxx6_common.dtsi b/dts/arm/nxp/nxp_mcxaxx6_common.dtsi index 1e04c05d5248..55971ef272ed 100644 --- a/dts/arm/nxp/nxp_mcxaxx6_common.dtsi +++ b/dts/arm/nxp/nxp_mcxaxx6_common.dtsi @@ -353,7 +353,7 @@ reg = <0x400b1000 0x1000>; interrupts = <64 0>; status = "disabled"; - #io-channel-cells = <2>; + clocks = <&syscon MCUX_LPCMP0_CLK>; }; lpcmp1: lpcmp@400b2000 { @@ -361,7 +361,7 @@ reg = <0x400b2000 0x1000>; interrupts = <65 0>; status = "disabled"; - #io-channel-cells = <2>; + clocks = <&syscon MCUX_LPCMP1_CLK>; }; lpcmp2: lpcmp@400b3000 { @@ -369,7 +369,7 @@ reg = <0x400b3000 0x1000>; interrupts = <66 0>; status = "disabled"; - #io-channel-cells = <2>; + clocks = <&syscon MCUX_LPCMP2_CLK>; }; opamp0: opamp@400b7000 { diff --git a/dts/arm/nxp/nxp_mcxe31x_common.dtsi b/dts/arm/nxp/nxp_mcxe31x_common.dtsi index 5581bf87998b..9f774a10e52f 100644 --- a/dts/arm/nxp/nxp_mcxe31x_common.dtsi +++ b/dts/arm/nxp/nxp_mcxe31x_common.dtsi @@ -411,6 +411,7 @@ compatible = "nxp,lpcmp"; reg = <0x370000 0x50>; interrupts = <183 0>; + clocks = <&mc_cgm MCUX_CMP0_CLK>; status = "disabled"; }; @@ -418,6 +419,7 @@ compatible = "nxp,lpcmp"; reg = <0x374000 0x50>; interrupts = <184 0>; + clocks = <&mc_cgm MCUX_CMP1_CLK>; status = "disabled"; }; @@ -425,6 +427,7 @@ compatible = "nxp,lpcmp"; reg = <0x4e8000 0x50>; interrupts = <185 0>; + clocks = <&mc_cgm MCUX_CMP2_CLK>; status = "disabled"; }; diff --git a/dts/arm/nxp/nxp_mcxn23x_common.dtsi b/dts/arm/nxp/nxp_mcxn23x_common.dtsi index a3930e6899d5..28c9736c2288 100644 --- a/dts/arm/nxp/nxp_mcxn23x_common.dtsi +++ b/dts/arm/nxp/nxp_mcxn23x_common.dtsi @@ -908,7 +908,6 @@ reg = <0x51000 0x1000>; interrupts = <109 0>; status = "disabled"; - #io-channel-cells = <2>; }; lpcmp1: lpcmp@52000 { @@ -916,7 +915,6 @@ reg = <0x52000 0x1000>; interrupts = <110 0>; status = "disabled"; - #io-channel-cells = <2>; }; flexcan0: can@d4000 { diff --git a/dts/arm/nxp/nxp_mcxn94x_common.dtsi b/dts/arm/nxp/nxp_mcxn94x_common.dtsi index 2190f7b8434b..387133affcf3 100644 --- a/dts/arm/nxp/nxp_mcxn94x_common.dtsi +++ b/dts/arm/nxp/nxp_mcxn94x_common.dtsi @@ -82,7 +82,6 @@ reg = <0x53000 0x1000>; interrupts = <111 0>; status = "disabled"; - #io-channel-cells = <2>; }; opamp0: opamp@110000 { diff --git a/dts/arm/nxp/nxp_mcxnx4x_common.dtsi b/dts/arm/nxp/nxp_mcxnx4x_common.dtsi index cfbc52f9471b..5b48cd0ca641 100644 --- a/dts/arm/nxp/nxp_mcxnx4x_common.dtsi +++ b/dts/arm/nxp/nxp_mcxnx4x_common.dtsi @@ -1062,7 +1062,6 @@ reg = <0x51000 0x1000>; interrupts = <109 0>; status = "disabled"; - #io-channel-cells = <2>; }; lpcmp1: lpcmp@52000 { @@ -1070,7 +1069,6 @@ reg = <0x52000 0x1000>; interrupts = <110 0>; status = "disabled"; - #io-channel-cells = <2>; }; flexcan0: can@d4000 { From fdfed339bc5a12b62a8d4bc1f385d70f3cac8fff Mon Sep 17 00:00:00 2001 From: Zhaoxiang Jin Date: Thu, 18 Dec 2025 22:30:36 +0800 Subject: [PATCH 0827/3659] boards: nxp: remove the lpcmp nodes from the board level dts We shall enable lpcmp in application level. Enabling lpcmp at the board level doesn't make any sense, since the lpcmp input is determined by the application. Signed-off-by: Zhaoxiang Jin --- boards/nxp/frdm_mcxa153/frdm_mcxa153.dts | 6 ------ boards/nxp/frdm_mcxa156/frdm_mcxa156.dts | 6 ------ boards/nxp/frdm_mcxaxx6/board_common.dtsi | 6 ------ boards/nxp/frdm_mcxn236/frdm_mcxn236.dts | 9 --------- boards/nxp/frdm_mcxn947/frdm_mcxn947.dtsi | 5 ----- boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0.dtsi | 4 ---- boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_ns.dts | 4 ---- boards/nxp/mcx_nx4x_evk/mcx_n9xx_evk-pinctrl.dtsi | 4 ++-- boards/nxp/mcx_nx4x_evk/mcx_n9xx_evk.dtsi | 5 ----- boards/nxp/mcx_nx4x_evk/mcx_n9xx_evk_mcxn947_cpu0.dtsi | 4 ---- 10 files changed, 2 insertions(+), 51 deletions(-) diff --git a/boards/nxp/frdm_mcxa153/frdm_mcxa153.dts b/boards/nxp/frdm_mcxa153/frdm_mcxa153.dts index 299e324f2267..340e2188e9c0 100644 --- a/boards/nxp/frdm_mcxa153/frdm_mcxa153.dts +++ b/boards/nxp/frdm_mcxa153/frdm_mcxa153.dts @@ -219,12 +219,6 @@ pinctrl-names = "default"; }; -&lpcmp0 { - status = "okay"; - pinctrl-0 = <&pinmux_lpcmp0>; - pinctrl-names = "default"; -}; - &lpi2c0 { status = "okay"; pinctrl-0 = <&pinmux_lpi2c0>; diff --git a/boards/nxp/frdm_mcxa156/frdm_mcxa156.dts b/boards/nxp/frdm_mcxa156/frdm_mcxa156.dts index c9bc5607ca3b..c42bcb1497f6 100644 --- a/boards/nxp/frdm_mcxa156/frdm_mcxa156.dts +++ b/boards/nxp/frdm_mcxa156/frdm_mcxa156.dts @@ -229,12 +229,6 @@ zephyr_mipi_dbi_parallel: &flexio0_lcd { pinctrl-names = "default"; }; -&lpcmp0 { - status = "okay"; - pinctrl-0 = <&pinmux_lpcmp0>; - pinctrl-names = "default"; -}; - &opamp0 { status = "okay"; pinctrl-0 = <&pinmux_opamp0>; diff --git a/boards/nxp/frdm_mcxaxx6/board_common.dtsi b/boards/nxp/frdm_mcxaxx6/board_common.dtsi index 9f6bbbc20cfb..e58007f8c755 100644 --- a/boards/nxp/frdm_mcxaxx6/board_common.dtsi +++ b/boards/nxp/frdm_mcxaxx6/board_common.dtsi @@ -138,12 +138,6 @@ pinctrl-names = "default"; }; -/* Comparator configuration */ -&lpcmp0 { - pinctrl-0 = <&pinmux_lpcmp0>; - pinctrl-names = "default"; -}; - /* I2C configurations */ &lpi2c1 { status = "okay"; diff --git a/boards/nxp/frdm_mcxn236/frdm_mcxn236.dts b/boards/nxp/frdm_mcxn236/frdm_mcxn236.dts index 0c1ea84eeae1..971182e4b8cf 100644 --- a/boards/nxp/frdm_mcxn236/frdm_mcxn236.dts +++ b/boards/nxp/frdm_mcxn236/frdm_mcxn236.dts @@ -279,10 +279,6 @@ zephyr_udc0: &usb1 { tx-cal-45-dm-ohms = <7>; }; -&lpcmp0 { - status = "okay"; -}; - &i3c1 { status = "okay"; }; @@ -402,11 +398,6 @@ nxp_8080_touch_panel_i2c: &flexcomm2_lpi2c2 { pinctrl-names = "default"; }; -&lpcmp0 { - pinctrl-0 = <&pinmux_lpcmp0>; - pinctrl-names = "default"; -}; - &flexcan1 { pinctrl-0 = <&pinmux_flexcan1>; pinctrl-names = "default"; diff --git a/boards/nxp/frdm_mcxn947/frdm_mcxn947.dtsi b/boards/nxp/frdm_mcxn947/frdm_mcxn947.dtsi index 8cd46a48393c..a02998337b55 100644 --- a/boards/nxp/frdm_mcxn947/frdm_mcxn947.dtsi +++ b/boards/nxp/frdm_mcxn947/frdm_mcxn947.dtsi @@ -384,11 +384,6 @@ zephyr_mipi_dbi_parallel: &flexio0_lcd { pinctrl-names = "default"; }; -&lpcmp0 { - pinctrl-0 = <&pinmux_lpcmp0>; - pinctrl-names = "default"; -}; - &opamp0 { pinctrl-0 = <&pinmux_opamp0>; pinctrl-names = "default"; diff --git a/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0.dtsi b/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0.dtsi index cd40cd6e56e6..9bc32447de94 100644 --- a/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0.dtsi +++ b/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0.dtsi @@ -252,10 +252,6 @@ zephyr_udc0: &usb1 { tx-cal-45-dm-ohms = <7>; }; -&lpcmp0 { - status = "okay"; -}; - &opamp0 { status = "okay"; }; diff --git a/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_ns.dts b/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_ns.dts index 07e3d36cebfa..71cb3a93dc9c 100644 --- a/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_ns.dts +++ b/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_ns.dts @@ -237,10 +237,6 @@ zephyr_udc0: &usb1 { tx-cal-45-dm-ohms = <7>; }; -&lpcmp0 { - status = "okay"; -}; - &lptmr0 { status = "okay"; }; diff --git a/boards/nxp/mcx_nx4x_evk/mcx_n9xx_evk-pinctrl.dtsi b/boards/nxp/mcx_nx4x_evk/mcx_n9xx_evk-pinctrl.dtsi index c5f71871869d..63eff21b8500 100644 --- a/boards/nxp/mcx_nx4x_evk/mcx_n9xx_evk-pinctrl.dtsi +++ b/boards/nxp/mcx_nx4x_evk/mcx_n9xx_evk-pinctrl.dtsi @@ -34,9 +34,9 @@ }; }; - pinmux_lpcmp2: pinmux_lpcmp2 { + pinmux_lpcmp0: pinmux_lpcmp0 { group0 { - pinmux = ; + pinmux = ; drive-strength = "low"; slew-rate = "fast"; bias-pull-up; diff --git a/boards/nxp/mcx_nx4x_evk/mcx_n9xx_evk.dtsi b/boards/nxp/mcx_nx4x_evk/mcx_n9xx_evk.dtsi index 094daa03e933..6b4e2e6806c8 100644 --- a/boards/nxp/mcx_nx4x_evk/mcx_n9xx_evk.dtsi +++ b/boards/nxp/mcx_nx4x_evk/mcx_n9xx_evk.dtsi @@ -12,8 +12,3 @@ pinctrl-0 = <&pinmux_flexpwm1_pwm0>; pinctrl-names = "default"; }; - -&lpcmp2 { - pinctrl-0 = <&pinmux_lpcmp2>; - pinctrl-names = "default"; -}; diff --git a/boards/nxp/mcx_nx4x_evk/mcx_n9xx_evk_mcxn947_cpu0.dtsi b/boards/nxp/mcx_nx4x_evk/mcx_n9xx_evk_mcxn947_cpu0.dtsi index fbe9e75a772d..031bbc98ac24 100644 --- a/boards/nxp/mcx_nx4x_evk/mcx_n9xx_evk_mcxn947_cpu0.dtsi +++ b/boards/nxp/mcx_nx4x_evk/mcx_n9xx_evk_mcxn947_cpu0.dtsi @@ -22,7 +22,3 @@ &flexpwm1_pwm0 { status = "okay"; }; - -&lpcmp2 { - status = "okay"; -}; From 0f9dcd8a3c1a7af3e715ec09e1df12df016e500e Mon Sep 17 00:00:00 2001 From: Zhaoxiang Jin Date: Mon, 22 Dec 2025 21:59:56 +0800 Subject: [PATCH 0828/3659] samples: sensor: mcux_lpcmp: Update board overlays for lpcmp Update the board overlay files for mcux_lpcmp sample to use the sensor-lpcmp driver: 1. Delete the 'compatible' and 'clocks' properties from the SoC-level lpcmp nodes. 2. Set the compatible to "nxp,sensor-lpcmp" to use the sensor-based lpcmp driver. 3. Add '#io-channel-cells = <2>' property for sensor API. 4. Add pinctrl configuration for lpcmp0. 5. Ensure status is set to "okay". Signed-off-by: Zhaoxiang Jin --- samples/sensor/mcux_lpcmp/boards/frdm_mcxa153.overlay | 7 +++++++ samples/sensor/mcux_lpcmp/boards/frdm_mcxa156.overlay | 7 +++++++ samples/sensor/mcux_lpcmp/boards/frdm_mcxa266.overlay | 8 +++++++- samples/sensor/mcux_lpcmp/boards/frdm_mcxa346.overlay | 8 +++++++- samples/sensor/mcux_lpcmp/boards/frdm_mcxa366.overlay | 8 +++++++- samples/sensor/mcux_lpcmp/boards/frdm_mcxn236.overlay | 7 +++++++ .../mcux_lpcmp/boards/frdm_mcxn947_mcxn947_cpu0.overlay | 7 +++++++ .../boards/frdm_mcxn947_mcxn947_cpu0_qspi.overlay | 7 +++++++ .../mcux_lpcmp/boards/mcx_n9xx_evk_mcxn947_cpu0.overlay | 7 +++++++ .../boards/mcx_n9xx_evk_mcxn947_cpu0_qspi.overlay | 7 +++++++ 10 files changed, 70 insertions(+), 3 deletions(-) diff --git a/samples/sensor/mcux_lpcmp/boards/frdm_mcxa153.overlay b/samples/sensor/mcux_lpcmp/boards/frdm_mcxa153.overlay index b162ff17e6a9..781e75efe73c 100644 --- a/samples/sensor/mcux_lpcmp/boards/frdm_mcxa153.overlay +++ b/samples/sensor/mcux_lpcmp/boards/frdm_mcxa153.overlay @@ -5,5 +5,12 @@ */ &lpcmp0 { + /delete-property/ compatible; + /delete-property/ clocks; + #io-channel-cells = <2>; + compatible = "nxp,sensor-lpcmp"; function-clock = "CMP_CLOCK"; + pinctrl-0 = <&pinmux_lpcmp0>; + pinctrl-names = "default"; + status = "okay"; }; diff --git a/samples/sensor/mcux_lpcmp/boards/frdm_mcxa156.overlay b/samples/sensor/mcux_lpcmp/boards/frdm_mcxa156.overlay index cec0ea5e6242..18720d6e283f 100644 --- a/samples/sensor/mcux_lpcmp/boards/frdm_mcxa156.overlay +++ b/samples/sensor/mcux_lpcmp/boards/frdm_mcxa156.overlay @@ -5,5 +5,12 @@ */ &lpcmp0 { + /delete-property/ compatible; + /delete-property/ clocks; + #io-channel-cells = <2>; + compatible = "nxp,sensor-lpcmp"; function-clock = "CMP_CLOCK"; + pinctrl-0 = <&pinmux_lpcmp0>; + pinctrl-names = "default"; + status = "okay"; }; diff --git a/samples/sensor/mcux_lpcmp/boards/frdm_mcxa266.overlay b/samples/sensor/mcux_lpcmp/boards/frdm_mcxa266.overlay index 2a4fe014b308..781e75efe73c 100644 --- a/samples/sensor/mcux_lpcmp/boards/frdm_mcxa266.overlay +++ b/samples/sensor/mcux_lpcmp/boards/frdm_mcxa266.overlay @@ -5,6 +5,12 @@ */ &lpcmp0 { - status = "okay"; + /delete-property/ compatible; + /delete-property/ clocks; + #io-channel-cells = <2>; + compatible = "nxp,sensor-lpcmp"; function-clock = "CMP_CLOCK"; + pinctrl-0 = <&pinmux_lpcmp0>; + pinctrl-names = "default"; + status = "okay"; }; diff --git a/samples/sensor/mcux_lpcmp/boards/frdm_mcxa346.overlay b/samples/sensor/mcux_lpcmp/boards/frdm_mcxa346.overlay index 2a4fe014b308..781e75efe73c 100644 --- a/samples/sensor/mcux_lpcmp/boards/frdm_mcxa346.overlay +++ b/samples/sensor/mcux_lpcmp/boards/frdm_mcxa346.overlay @@ -5,6 +5,12 @@ */ &lpcmp0 { - status = "okay"; + /delete-property/ compatible; + /delete-property/ clocks; + #io-channel-cells = <2>; + compatible = "nxp,sensor-lpcmp"; function-clock = "CMP_CLOCK"; + pinctrl-0 = <&pinmux_lpcmp0>; + pinctrl-names = "default"; + status = "okay"; }; diff --git a/samples/sensor/mcux_lpcmp/boards/frdm_mcxa366.overlay b/samples/sensor/mcux_lpcmp/boards/frdm_mcxa366.overlay index 2a4fe014b308..781e75efe73c 100644 --- a/samples/sensor/mcux_lpcmp/boards/frdm_mcxa366.overlay +++ b/samples/sensor/mcux_lpcmp/boards/frdm_mcxa366.overlay @@ -5,6 +5,12 @@ */ &lpcmp0 { - status = "okay"; + /delete-property/ compatible; + /delete-property/ clocks; + #io-channel-cells = <2>; + compatible = "nxp,sensor-lpcmp"; function-clock = "CMP_CLOCK"; + pinctrl-0 = <&pinmux_lpcmp0>; + pinctrl-names = "default"; + status = "okay"; }; diff --git a/samples/sensor/mcux_lpcmp/boards/frdm_mcxn236.overlay b/samples/sensor/mcux_lpcmp/boards/frdm_mcxn236.overlay index cec0ea5e6242..18720d6e283f 100644 --- a/samples/sensor/mcux_lpcmp/boards/frdm_mcxn236.overlay +++ b/samples/sensor/mcux_lpcmp/boards/frdm_mcxn236.overlay @@ -5,5 +5,12 @@ */ &lpcmp0 { + /delete-property/ compatible; + /delete-property/ clocks; + #io-channel-cells = <2>; + compatible = "nxp,sensor-lpcmp"; function-clock = "CMP_CLOCK"; + pinctrl-0 = <&pinmux_lpcmp0>; + pinctrl-names = "default"; + status = "okay"; }; diff --git a/samples/sensor/mcux_lpcmp/boards/frdm_mcxn947_mcxn947_cpu0.overlay b/samples/sensor/mcux_lpcmp/boards/frdm_mcxn947_mcxn947_cpu0.overlay index cec0ea5e6242..18720d6e283f 100644 --- a/samples/sensor/mcux_lpcmp/boards/frdm_mcxn947_mcxn947_cpu0.overlay +++ b/samples/sensor/mcux_lpcmp/boards/frdm_mcxn947_mcxn947_cpu0.overlay @@ -5,5 +5,12 @@ */ &lpcmp0 { + /delete-property/ compatible; + /delete-property/ clocks; + #io-channel-cells = <2>; + compatible = "nxp,sensor-lpcmp"; function-clock = "CMP_CLOCK"; + pinctrl-0 = <&pinmux_lpcmp0>; + pinctrl-names = "default"; + status = "okay"; }; diff --git a/samples/sensor/mcux_lpcmp/boards/frdm_mcxn947_mcxn947_cpu0_qspi.overlay b/samples/sensor/mcux_lpcmp/boards/frdm_mcxn947_mcxn947_cpu0_qspi.overlay index cec0ea5e6242..18720d6e283f 100644 --- a/samples/sensor/mcux_lpcmp/boards/frdm_mcxn947_mcxn947_cpu0_qspi.overlay +++ b/samples/sensor/mcux_lpcmp/boards/frdm_mcxn947_mcxn947_cpu0_qspi.overlay @@ -5,5 +5,12 @@ */ &lpcmp0 { + /delete-property/ compatible; + /delete-property/ clocks; + #io-channel-cells = <2>; + compatible = "nxp,sensor-lpcmp"; function-clock = "CMP_CLOCK"; + pinctrl-0 = <&pinmux_lpcmp0>; + pinctrl-names = "default"; + status = "okay"; }; diff --git a/samples/sensor/mcux_lpcmp/boards/mcx_n9xx_evk_mcxn947_cpu0.overlay b/samples/sensor/mcux_lpcmp/boards/mcx_n9xx_evk_mcxn947_cpu0.overlay index 45906ef15714..9f47691a3f96 100644 --- a/samples/sensor/mcux_lpcmp/boards/mcx_n9xx_evk_mcxn947_cpu0.overlay +++ b/samples/sensor/mcux_lpcmp/boards/mcx_n9xx_evk_mcxn947_cpu0.overlay @@ -11,5 +11,12 @@ /delete-node/ &lpcmp0; lpcmp0: &lpcmp2 { + /delete-property/ compatible; + /delete-property/ clocks; + #io-channel-cells = <2>; + compatible = "nxp,sensor-lpcmp"; function-clock = "CMP_CLOCK"; + pinctrl-0 = <&pinmux_lpcmp0>; + pinctrl-names = "default"; + status = "okay"; }; diff --git a/samples/sensor/mcux_lpcmp/boards/mcx_n9xx_evk_mcxn947_cpu0_qspi.overlay b/samples/sensor/mcux_lpcmp/boards/mcx_n9xx_evk_mcxn947_cpu0_qspi.overlay index 45906ef15714..9f47691a3f96 100644 --- a/samples/sensor/mcux_lpcmp/boards/mcx_n9xx_evk_mcxn947_cpu0_qspi.overlay +++ b/samples/sensor/mcux_lpcmp/boards/mcx_n9xx_evk_mcxn947_cpu0_qspi.overlay @@ -11,5 +11,12 @@ /delete-node/ &lpcmp0; lpcmp0: &lpcmp2 { + /delete-property/ compatible; + /delete-property/ clocks; + #io-channel-cells = <2>; + compatible = "nxp,sensor-lpcmp"; function-clock = "CMP_CLOCK"; + pinctrl-0 = <&pinmux_lpcmp0>; + pinctrl-names = "default"; + status = "okay"; }; From 62be60aa0fd32b268def238909ca959aa3fb8916 Mon Sep 17 00:00:00 2001 From: Zhaoxiang Jin Date: Thu, 18 Dec 2025 21:50:17 +0800 Subject: [PATCH 0829/3659] tests: comparator: enable gpio_loopback for nxp boards enable gpio_loopback for nxp boards, including: - frdm_mcxa153 - frdm_mcxa156 - frdm_mcxa266 - frdm_mcxa346 - frdm_mcxa366 - frdm_mcxe31b - frdm_mcxn236 - frdm_mcxn947/mcxn947/cpu0/qspi - frdm_mcxn947/mcxn947/cpu0 - mcx_n9xx_evk/mcxn947/cpu0/qspi - mcx_n9xx_evk/mcxn947/cpu0 Signed-off-by: Zhaoxiang Jin --- .../gpio_loopback/boards/frdm_mcxa153.overlay | 28 +++++++++++++++++ .../gpio_loopback/boards/frdm_mcxa156.overlay | 27 +++++++++++++++++ .../gpio_loopback/boards/frdm_mcxa266.overlay | 28 +++++++++++++++++ .../gpio_loopback/boards/frdm_mcxa346.overlay | 28 +++++++++++++++++ .../gpio_loopback/boards/frdm_mcxa366.overlay | 28 +++++++++++++++++ .../gpio_loopback/boards/frdm_mcxe31b.overlay | 30 +++++++++++++++++++ .../gpio_loopback/boards/frdm_mcxn236.overlay | 27 +++++++++++++++++ .../boards/frdm_mcxn947_mcxn947_cpu0.overlay | 27 +++++++++++++++++ .../frdm_mcxn947_mcxn947_cpu0_qspi.overlay | 27 +++++++++++++++++ .../boards/mcx_n9xx_evk_mcxn947_cpu0.overlay | 27 +++++++++++++++++ .../mcx_n9xx_evk_mcxn947_cpu0_qspi.overlay | 27 +++++++++++++++++ .../comparator/gpio_loopback/testcase.yaml | 13 ++++++++ 12 files changed, 317 insertions(+) create mode 100644 tests/drivers/comparator/gpio_loopback/boards/frdm_mcxa153.overlay create mode 100644 tests/drivers/comparator/gpio_loopback/boards/frdm_mcxa156.overlay create mode 100644 tests/drivers/comparator/gpio_loopback/boards/frdm_mcxa266.overlay create mode 100644 tests/drivers/comparator/gpio_loopback/boards/frdm_mcxa346.overlay create mode 100644 tests/drivers/comparator/gpio_loopback/boards/frdm_mcxa366.overlay create mode 100644 tests/drivers/comparator/gpio_loopback/boards/frdm_mcxe31b.overlay create mode 100644 tests/drivers/comparator/gpio_loopback/boards/frdm_mcxn236.overlay create mode 100644 tests/drivers/comparator/gpio_loopback/boards/frdm_mcxn947_mcxn947_cpu0.overlay create mode 100644 tests/drivers/comparator/gpio_loopback/boards/frdm_mcxn947_mcxn947_cpu0_qspi.overlay create mode 100644 tests/drivers/comparator/gpio_loopback/boards/mcx_n9xx_evk_mcxn947_cpu0.overlay create mode 100644 tests/drivers/comparator/gpio_loopback/boards/mcx_n9xx_evk_mcxn947_cpu0_qspi.overlay diff --git a/tests/drivers/comparator/gpio_loopback/boards/frdm_mcxa153.overlay b/tests/drivers/comparator/gpio_loopback/boards/frdm_mcxa153.overlay new file mode 100644 index 000000000000..2c0bc687eb5e --- /dev/null +++ b/tests/drivers/comparator/gpio_loopback/boards/frdm_mcxa153.overlay @@ -0,0 +1,28 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/* To test this case, please connect J3-1(P2_7,VREFI) to JP8-2(VDD). */ +/ { + aliases { + test-comp = &lpcmp0; + }; + + zephyr,user { + test-gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>; /* FRDM-MCXA153 J2-3 */ + }; +}; + +&lpcmp0 { + status = "okay"; + pinctrl-0 = <&pinmux_lpcmp0>; + pinctrl-names = "default"; + positive-mux-input = "IN0"; /* FRDM-MCXA153 J2-9 */ + negative-mux-input = "DAC"; + dac-value = <127>; + dac-vref-source = "VREFH1"; +}; diff --git a/tests/drivers/comparator/gpio_loopback/boards/frdm_mcxa156.overlay b/tests/drivers/comparator/gpio_loopback/boards/frdm_mcxa156.overlay new file mode 100644 index 000000000000..6eeb3c43b343 --- /dev/null +++ b/tests/drivers/comparator/gpio_loopback/boards/frdm_mcxa156.overlay @@ -0,0 +1,27 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/ { + aliases { + test-comp = &lpcmp0; + }; + + zephyr,user { + test-gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>; /* FRDM-MCXA156 J2-1 */ + }; +}; + +&lpcmp0 { + status = "okay"; + pinctrl-0 = <&pinmux_lpcmp0>; + pinctrl-names = "default"; + positive-mux-input = "IN0"; /* FRDM-MCXA156 J2-9 */ + negative-mux-input = "DAC"; + dac-value = <127>; + dac-vref-source = "VREFH1"; +}; diff --git a/tests/drivers/comparator/gpio_loopback/boards/frdm_mcxa266.overlay b/tests/drivers/comparator/gpio_loopback/boards/frdm_mcxa266.overlay new file mode 100644 index 000000000000..813803afc5f6 --- /dev/null +++ b/tests/drivers/comparator/gpio_loopback/boards/frdm_mcxa266.overlay @@ -0,0 +1,28 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/* To test this case, connect J2-1(P2_7,VREFI) to J6-7(VDD). */ +/ { + aliases { + test-comp = &lpcmp0; + }; + + zephyr,user { + test-gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>; /* FRDM-MCXA266 J2-7 */ + }; +}; + +&lpcmp0 { + status = "okay"; + pinctrl-0 = <&pinmux_lpcmp0>; + pinctrl-names = "default"; + positive-mux-input = "IN1"; /* FRDM-MCXA266 J2-17 */ + negative-mux-input = "DAC"; + dac-value = <127>; + dac-vref-source = "VREFH1"; +}; diff --git a/tests/drivers/comparator/gpio_loopback/boards/frdm_mcxa346.overlay b/tests/drivers/comparator/gpio_loopback/boards/frdm_mcxa346.overlay new file mode 100644 index 000000000000..68b98d384a32 --- /dev/null +++ b/tests/drivers/comparator/gpio_loopback/boards/frdm_mcxa346.overlay @@ -0,0 +1,28 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/* To test this case, connect J2-1(P2_7,VREFI) to J6-7(VDD). */ +/ { + aliases { + test-comp = &lpcmp0; + }; + + zephyr,user { + test-gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>; /* FRDM-MCXA346 J2-7 */ + }; +}; + +&lpcmp0 { + status = "okay"; + pinctrl-0 = <&pinmux_lpcmp0>; + pinctrl-names = "default"; + positive-mux-input = "IN1"; /* FRDM-MCXA346 J2-17 */ + negative-mux-input = "DAC"; + dac-value = <127>; + dac-vref-source = "VREFH1"; +}; diff --git a/tests/drivers/comparator/gpio_loopback/boards/frdm_mcxa366.overlay b/tests/drivers/comparator/gpio_loopback/boards/frdm_mcxa366.overlay new file mode 100644 index 000000000000..945dfb2f0ff9 --- /dev/null +++ b/tests/drivers/comparator/gpio_loopback/boards/frdm_mcxa366.overlay @@ -0,0 +1,28 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/* To test this case, connect J2-1(P2_7,VREFI) to J6-7(VDD). */ +/ { + aliases { + test-comp = &lpcmp0; + }; + + zephyr,user { + test-gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>; /* FRDM-MCXA366 J2-7 */ + }; +}; + +&lpcmp0 { + status = "okay"; + pinctrl-0 = <&pinmux_lpcmp0>; + pinctrl-names = "default"; + positive-mux-input = "IN1"; /* FRDM-MCXA366 J2-17 */ + negative-mux-input = "DAC"; + dac-value = <127>; + dac-vref-source = "VREFH1"; +}; diff --git a/tests/drivers/comparator/gpio_loopback/boards/frdm_mcxe31b.overlay b/tests/drivers/comparator/gpio_loopback/boards/frdm_mcxe31b.overlay new file mode 100644 index 000000000000..9550f08841b1 --- /dev/null +++ b/tests/drivers/comparator/gpio_loopback/boards/frdm_mcxe31b.overlay @@ -0,0 +1,30 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/ { + aliases { + test-comp = &lpcmp_1; + }; + + zephyr,user { + test-gpios = <&gpioa_l 1 GPIO_ACTIVE_HIGH>; /* FRDM-MCXE31B J9-5 */ + }; +}; + +&gpioa_l { + status = "okay"; +}; + +&lpcmp_1 { + status = "okay"; + positive-mux-input = "IN0"; /* FRDM-MCXE31B J9-3 */ + negative-mux-input = "DAC"; + dac-vref-source = "VREFH1"; + dac-value = <127>; + dac-vref-source = "VREFH1"; +}; diff --git a/tests/drivers/comparator/gpio_loopback/boards/frdm_mcxn236.overlay b/tests/drivers/comparator/gpio_loopback/boards/frdm_mcxn236.overlay new file mode 100644 index 000000000000..c8aebcd33f17 --- /dev/null +++ b/tests/drivers/comparator/gpio_loopback/boards/frdm_mcxn236.overlay @@ -0,0 +1,27 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/ { + aliases { + test-comp = &lpcmp0; + }; + + zephyr,user { + test-gpios = <&gpio1 2 GPIO_ACTIVE_HIGH>; /* FRDM-MCXN236 J2-10 */ + }; +}; + +&lpcmp0 { + status = "okay"; + pinctrl-0 = <&pinmux_lpcmp0>; + pinctrl-names = "default"; + positive-mux-input = "IN0"; /* FRDM-MCXN236 J2-8 */ + negative-mux-input = "DAC"; + dac-value = <127>; + dac-vref-source = "VREFH1"; +}; diff --git a/tests/drivers/comparator/gpio_loopback/boards/frdm_mcxn947_mcxn947_cpu0.overlay b/tests/drivers/comparator/gpio_loopback/boards/frdm_mcxn947_mcxn947_cpu0.overlay new file mode 100644 index 000000000000..15c35c75f5c0 --- /dev/null +++ b/tests/drivers/comparator/gpio_loopback/boards/frdm_mcxn947_mcxn947_cpu0.overlay @@ -0,0 +1,27 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/ { + aliases { + test-comp = &lpcmp0; + }; + + zephyr,user { + test-gpios = <&gpio1 12 GPIO_ACTIVE_HIGH>; /* FRDM-MCXN947 J2-11 */ + }; +}; + +&lpcmp0 { + status = "okay"; + pinctrl-0 = <&pinmux_lpcmp0>; + pinctrl-names = "default"; + positive-mux-input = "IN0"; /* FRDM-MCXN947 J2-17 */ + negative-mux-input = "DAC"; + dac-value = <127>; + dac-vref-source = "VREFH1"; +}; diff --git a/tests/drivers/comparator/gpio_loopback/boards/frdm_mcxn947_mcxn947_cpu0_qspi.overlay b/tests/drivers/comparator/gpio_loopback/boards/frdm_mcxn947_mcxn947_cpu0_qspi.overlay new file mode 100644 index 000000000000..15c35c75f5c0 --- /dev/null +++ b/tests/drivers/comparator/gpio_loopback/boards/frdm_mcxn947_mcxn947_cpu0_qspi.overlay @@ -0,0 +1,27 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/ { + aliases { + test-comp = &lpcmp0; + }; + + zephyr,user { + test-gpios = <&gpio1 12 GPIO_ACTIVE_HIGH>; /* FRDM-MCXN947 J2-11 */ + }; +}; + +&lpcmp0 { + status = "okay"; + pinctrl-0 = <&pinmux_lpcmp0>; + pinctrl-names = "default"; + positive-mux-input = "IN0"; /* FRDM-MCXN947 J2-17 */ + negative-mux-input = "DAC"; + dac-value = <127>; + dac-vref-source = "VREFH1"; +}; diff --git a/tests/drivers/comparator/gpio_loopback/boards/mcx_n9xx_evk_mcxn947_cpu0.overlay b/tests/drivers/comparator/gpio_loopback/boards/mcx_n9xx_evk_mcxn947_cpu0.overlay new file mode 100644 index 000000000000..c86180eb044b --- /dev/null +++ b/tests/drivers/comparator/gpio_loopback/boards/mcx_n9xx_evk_mcxn947_cpu0.overlay @@ -0,0 +1,27 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/ { + aliases { + test-comp = &lpcmp0; + }; + + zephyr,user { + test-gpios = <&gpio1 1 GPIO_ACTIVE_HIGH>; /* MCXN947-EVK J2-15 */ + }; +}; + +&lpcmp0 { + status = "okay"; + pinctrl-0 = <&pinmux_lpcmp0>; + pinctrl-names = "default"; + positive-mux-input = "IN0"; /* MCXN947-EVK J2-17 */ + negative-mux-input = "DAC"; + dac-value = <127>; + dac-vref-source = "VREFH1"; +}; diff --git a/tests/drivers/comparator/gpio_loopback/boards/mcx_n9xx_evk_mcxn947_cpu0_qspi.overlay b/tests/drivers/comparator/gpio_loopback/boards/mcx_n9xx_evk_mcxn947_cpu0_qspi.overlay new file mode 100644 index 000000000000..c86180eb044b --- /dev/null +++ b/tests/drivers/comparator/gpio_loopback/boards/mcx_n9xx_evk_mcxn947_cpu0_qspi.overlay @@ -0,0 +1,27 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/ { + aliases { + test-comp = &lpcmp0; + }; + + zephyr,user { + test-gpios = <&gpio1 1 GPIO_ACTIVE_HIGH>; /* MCXN947-EVK J2-15 */ + }; +}; + +&lpcmp0 { + status = "okay"; + pinctrl-0 = <&pinmux_lpcmp0>; + pinctrl-names = "default"; + positive-mux-input = "IN0"; /* MCXN947-EVK J2-17 */ + negative-mux-input = "DAC"; + dac-value = <127>; + dac-vref-source = "VREFH1"; +}; diff --git a/tests/drivers/comparator/gpio_loopback/testcase.yaml b/tests/drivers/comparator/gpio_loopback/testcase.yaml index 2d1b07d42cf8..0bb7c95758b0 100644 --- a/tests/drivers/comparator/gpio_loopback/testcase.yaml +++ b/tests/drivers/comparator/gpio_loopback/testcase.yaml @@ -51,3 +51,16 @@ tests: drivers.comparator.gpio_loopback.nxp_acomp: platform_allow: - frdm_rw612 + drivers.comparator.gpio_loopback.nxp_lpcmp: + platform_allow: + - frdm_mcxa153 + - frdm_mcxa156 + - frdm_mcxa266 + - frdm_mcxa346 + - frdm_mcxa366 + - frdm_mcxe31b + - frdm_mcxn236 + - frdm_mcxn947/mcxn947/cpu0/qspi + - frdm_mcxn947/mcxn947/cpu0 + - mcx_n9xx_evk/mcxn947/cpu0/qspi + - mcx_n9xx_evk/mcxn947/cpu0 From 2f56bbc6e45d13c9d8d355f394a454b8b07b4211 Mon Sep 17 00:00:00 2001 From: Zhaoxiang Jin Date: Thu, 18 Dec 2025 21:20:11 +0800 Subject: [PATCH 0830/3659] doc: release-notes-4.4: Record mcux_lpcmp driver change Update the release-notes-4.4 to document: 1. The mcux_lpcmp driver will be deprecated. 2. The compatible 'nxp,lpcmp' for mcux_lpcmp has now been changed to 'nxp,sensor-lpcmp'. 3. A new lpcmp driver based on the comparator driver API has been created, and the 'nxp,lpcmp' compatible is used for it. Signed-off-by: Zhaoxiang Jin --- doc/releases/release-notes-4.4.rst | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/doc/releases/release-notes-4.4.rst b/doc/releases/release-notes-4.4.rst index 031f714bbe88..cd2f013a57b2 100644 --- a/doc/releases/release-notes-4.4.rst +++ b/doc/releases/release-notes-4.4.rst @@ -84,6 +84,20 @@ Deprecated APIs and options :c:member:`bt_conn_le_info.interval_us` instead. Note that the units have changed: ``interval`` was in units of 1.25 milliseconds, while ``interval_us`` is in microseconds. +* Sensors + + * NXP + + * Deprecated the ``mcux_lpcmp`` driver (:zephyr_file:`drivers/sensor/nxp/mcux_lpcmp/mcux_lpcmp.c`). It is + currently scheduled to be removed in Zephyr 4.6, along with the ``mcux_lpcmp`` sample. + * The new ``comparator_nxp_lpcmp`` driver (:zephyr_file:`drivers/comparator/comparator_nxp_lpcmp.c`) has + been introduced to support NXP LPCMP peripheral. SoCs and boards that previously supported the ``mcux_lpcmp`` + driver and its associated sample have now migrated to use the ``comparator_nxp_lpcmp`` driver along with the + ``gpio_loopback`` test case (:zephyr_file:`tests/drivers/comparator/gpio_loopback/src/test.c`). + * The original :dtcompatible:`nxp,lpcmp` has been renamed to :dtcompatible:`nxp,sensor-lpcmp`, applications + using the old compatible must update their devicetree nodes to use the ``mcux_lpcmp`` driver. The + :dtcompatible:`nxp,lpcmp` now is used for the ``comparator_nxp_lpcmp`` driver. (:github:`100998`). + New APIs and options ==================== .. From 781d35c4f1c6038fcaed5a7c10dad72ce43d9c94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Thu, 18 Dec 2025 11:09:10 +0100 Subject: [PATCH 0831/3659] include: adc: add doxygen group for device-specific ADC API extensions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Similar to how it's done for other driver classes, create a new doxygen group to put all device-specific ADC API extensions under. Signed-off-by: Benjamin Cabé --- include/zephyr/drivers/adc.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/zephyr/drivers/adc.h b/include/zephyr/drivers/adc.h index 59d582204aa8..66af2859515e 100644 --- a/include/zephyr/drivers/adc.h +++ b/include/zephyr/drivers/adc.h @@ -31,6 +31,11 @@ extern "C" { * @version 1.0.0 * @ingroup io_interfaces * @{ + * + * @defgroup adc_interface_ext Device-specific ADC API extensions + * + * @{ + * @} */ /** @brief ADC channel gain factors. */ From 3aa26516809b0fa7c634341a3b2713d1bc73d9d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Thu, 18 Dec 2025 11:37:55 +0100 Subject: [PATCH 0832/3659] include: adc: add doxygen docs for ads1x4s0x extended API MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds doxygen documentation for the extended API of the ADS1x4s0x ADC driver. Signed-off-by: Benjamin Cabé --- include/zephyr/drivers/adc/ads1x4s0x.h | 91 ++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) diff --git a/include/zephyr/drivers/adc/ads1x4s0x.h b/include/zephyr/drivers/adc/ads1x4s0x.h index 2f4c7a148290..35084c5c122d 100644 --- a/include/zephyr/drivers/adc/ads1x4s0x.h +++ b/include/zephyr/drivers/adc/ads1x4s0x.h @@ -4,32 +4,123 @@ * SPDX-License-Identifier: Apache-2.0 */ +/** + * @file + * @brief Header file for extended API of ADS1x4s0x ADC + * @ingroup ads1x4s0x_interface + */ + #ifndef ZEPHYR_INCLUDE_DRIVERS_ADC_ADS1X4S0X_H_ #define ZEPHYR_INCLUDE_DRIVERS_ADC_ADS1X4S0X_H_ #include #include +/** + * @brief Texas Instruments ADS1x4s0x + * @defgroup ads1x4s0x_interface ADS1x4s0x + * @ingroup adc_interface_ext + * @{ + */ + +/** + * @brief Configure a GPIO pin of an ADS1x4s0x ADC as an output. + * + * @param dev Pointer to the device structure for the driver instance. + * @param pin Pin number. + * @param initial_value Initial value of the pin. + * + * @retval 0 success. + * @retval -errno negative errno on failure. + */ int ads1x4s0x_gpio_set_output(const struct device *dev, uint8_t pin, bool initial_value); +/** + * @brief Configure a GPIO pin of an ADS1x4s0x ADC as an input. + * + * @param dev Pointer to the device structure for the driver instance. + * @param pin Pin number. + * + * @retval 0 success. + * @retval -errno negative errno on failure. + */ int ads1x4s0x_gpio_set_input(const struct device *dev, uint8_t pin); +/** + * @brief Deconfigure a GPIO pin of an ADS1x4s0x ADC. + * + * @param dev Pointer to the device structure for the driver instance. + * @param pin Pin number. + * + * @retval 0 success. + * @retval -errno negative errno on failure. + */ int ads1x4s0x_gpio_deconfigure(const struct device *dev, uint8_t pin); +/** + * @brief Set the value of a GPIO pin of an ADS1x4s0x ADC. + * + * @param dev Pointer to the device structure for the driver instance. + * @param pin Pin number. + * @param value Value to set. + * + * @retval 0 success. + * @retval -errno negative errno on failure. + */ int ads1x4s0x_gpio_set_pin_value(const struct device *dev, uint8_t pin, bool value); +/** + * @brief Get the value of a GPIO pin of an ADS1x4s0x ADC. + * + * @param dev Pointer to the device structure for the driver instance. + * @param pin Pin number. + * @param value Pointer to where the value will be stored. + * + * @retval 0 success. + * @retval -errno negative errno on failure. + */ int ads1x4s0x_gpio_get_pin_value(const struct device *dev, uint8_t pin, bool *value); +/** + * @brief Get the value of the GPIO port of an ADS1x4s0x ADC. + * + * @param dev Pointer to the device structure for the driver instance. + * @param value Pointer to where the port value will be stored. + * + * @retval 0 success. + * @retval -errno negative errno on failure. + */ int ads1x4s0x_gpio_port_get_raw(const struct device *dev, gpio_port_value_t *value); +/** + * @brief Set the value of the GPIO port of an ADS1x4s0x ADC with a mask. + * + * @param dev Pointer to the device structure for the driver instance. + * @param mask Mask of pins to change. + * @param value Value to set. + * + * @retval 0 success. + * @retval -errno negative errno on failure. + */ int ads1x4s0x_gpio_port_set_masked_raw(const struct device *dev, gpio_port_pins_t mask, gpio_port_value_t value); +/** + * @brief Toggle bits of the GPIO port of an ADS1x4s0x ADC. + * + * @param dev Pointer to the device structure for the driver instance. + * @param pins Mask of pins to toggle. + * + * @retval 0 success. + * @retval -errno negative errno on failure. + */ int ads1x4s0x_gpio_port_toggle_bits(const struct device *dev, gpio_port_pins_t pins); +/** @} */ + #endif /* ZEPHYR_INCLUDE_DRIVERS_ADC_ADS1X4S0X_H_ */ From fb62a29b582a5bff13405a3a666294ffcafc0138 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Thu, 18 Dec 2025 11:49:41 +0100 Subject: [PATCH 0833/3659] include: adc: add doxygen docs for ads131m02 extended API MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds doxygen documentation for the extended API of the ADS131M02 ADC driver. Signed-off-by: Benjamin Cabé --- include/zephyr/drivers/adc/ads131m02.h | 72 ++++++++++++++++++++++++-- 1 file changed, 67 insertions(+), 5 deletions(-) diff --git a/include/zephyr/drivers/adc/ads131m02.h b/include/zephyr/drivers/adc/ads131m02.h index 978684774025..2f1ff9112179 100644 --- a/include/zephyr/drivers/adc/ads131m02.h +++ b/include/zephyr/drivers/adc/ads131m02.h @@ -4,45 +4,107 @@ * SPDX-License-Identifier: Apache-2.0 */ +/** + * @file + * @brief Header file for extended API of ADS131M02 ADC + * @ingroup ads131m02_interface + */ + #ifndef ZEPHYR_INCLUDE_DRIVERS_ADC_ADS131M02_H_ #define ZEPHYR_INCLUDE_DRIVERS_ADC_ADS131M02_H_ #include +/** + * @brief Texas Instruments 2 channels SPI ADC + * @defgroup ads131m02_interface ADS131M02 + * @ingroup adc_interface_ext + * @{ + */ + +/** + * @brief ADS131M02 ADC mode. + */ enum ads131m02_adc_mode { - ADS131M02_CONTINUOUS_MODE, /* Continuous conversion mode */ - ADS131M02_GLOBAL_CHOP_MODE /* Global chop mode */ + ADS131M02_CONTINUOUS_MODE, /**< Continuous conversion mode */ + ADS131M02_GLOBAL_CHOP_MODE /**< Global-chop mode */ }; +/** + * @brief ADS131M02 power mode. + */ enum ads131m02_adc_power_mode { - ADS131M02_VLP, /* Very Low Power */ - ADS131M02_LP, /* Low Power */ - ADS131M02_HR /* High Resolution */ + ADS131M02_VLP, /**< Very Low Power */ + ADS131M02_LP, /**< Low Power */ + ADS131M02_HR /**< High Resolution */ }; +/** + * @brief ADS131M02 global-chop delay. + * + * Delay inserted after the chopping switches toggle in global-chop mode to allow for external input + * circuitry settling. + */ enum ads131m02_gc_delay { + /** 2 sample delay */ ADS131M02_GC_DELAY_2, + /** 4 sample delay */ ADS131M02_GC_DELAY_4, + /** 8 sample delay */ ADS131M02_GC_DELAY_8, + /** 16 sample delay */ ADS131M02_GC_DELAY_16, + /** 32 sample delay */ ADS131M02_GC_DELAY_32, + /** 64 sample delay */ ADS131M02_GC_DELAY_64, + /** 128 sample delay */ ADS131M02_GC_DELAY_128, + /** 256 sample delay */ ADS131M02_GC_DELAY_256, + /** 512 sample delay */ ADS131M02_GC_DELAY_512, + /** 1024 sample delay */ ADS131M02_GC_DELAY_1024, + /** 2048 sample delay */ ADS131M02_GC_DELAY_2048, + /** 4096 sample delay */ ADS131M02_GC_DELAY_4096, + /** 8192 sample delay */ ADS131M02_GC_DELAY_8192, + /** 16384 sample delay */ ADS131M02_GC_DELAY_16384, + /** 32768 sample delay */ ADS131M02_GC_DELAY_32768, + /** 65536 sample delay */ ADS131M02_GC_DELAY_65536 }; +/** + * @brief Set the ADC mode of an ADS131M02 ADC. + * + * @param dev Pointer to the device structure for the driver instance. + * @param mode ADC mode to set. + * @param gc_delay Global chop delay to set (if @p mode is @ref ADS131M02_GLOBAL_CHOP_MODE). + * + * @retval 0 success. + * @retval -errno negative errno on failure. + */ int ads131m02_set_adc_mode(const struct device *dev, enum ads131m02_adc_mode mode, enum ads131m02_gc_delay gc_delay); +/** + * @brief Set the power mode of an ADS131M02 ADC. + * + * @param dev Pointer to the device structure for the driver instance. + * @param mode Power mode to set. + * + * @retval 0 success. + * @retval -errno negative errno on failure. + */ int ads131m02_set_power_mode(const struct device *dev, enum ads131m02_adc_power_mode mode); +/** @} */ + #endif From 327969d5ae38dd6b1ad83a32270ecd7a0c14eaa4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Thu, 18 Dec 2025 11:57:56 +0100 Subject: [PATCH 0834/3659] include: adc: add doxygen docs for voltage_divider extended API MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds doxygen documentation for the extended API of the voltage divider ADC driver. Signed-off-by: Benjamin Cabé --- dts/bindings/iio/afe/voltage-divider.yaml | 2 ++ include/zephyr/drivers/adc/voltage_divider.h | 27 +++++++++++++++++++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/dts/bindings/iio/afe/voltage-divider.yaml b/dts/bindings/iio/afe/voltage-divider.yaml index 92c69d49acb2..7105299795e8 100644 --- a/dts/bindings/iio/afe/voltage-divider.yaml +++ b/dts/bindings/iio/afe/voltage-divider.yaml @@ -1,6 +1,8 @@ # Copyright (c) 2019, Peter Bigot Consulting, LLC # SPDX-License-Identifier: Apache-2.0 +title: Voltage Divider + description: | Description for a voltage divider, with optional ability to measure resistance of the upper leg. diff --git a/include/zephyr/drivers/adc/voltage_divider.h b/include/zephyr/drivers/adc/voltage_divider.h index caf6f821ff20..0fb614972c83 100644 --- a/include/zephyr/drivers/adc/voltage_divider.h +++ b/include/zephyr/drivers/adc/voltage_divider.h @@ -4,14 +4,37 @@ * SPDX-License-Identifier: Apache-2.0 */ +/** + * @file + * @brief Header file for extended API of Voltage Divider + * @ingroup adc_voltage_divider_interface + */ + #ifndef ZEPHYR_INCLUDE_DRIVERS_ADC_VOLTAGE_DIVIDER_H_ #define ZEPHYR_INCLUDE_DRIVERS_ADC_VOLTAGE_DIVIDER_H_ #include +/** + * @brief Voltage Divider + * @defgroup adc_voltage_divider_interface Voltage Divider + * @ingroup adc_interface_ext + * @{ + */ + +/** + * @brief Voltage divider DT struct. + * + * This stores information about a voltage divider obtained from Devicetree. + * + * @see VOLTAGE_DIVIDER_DT_SPEC_GET + */ struct voltage_divider_dt_spec { + /** ADC channel info */ const struct adc_dt_spec port; + /** Full resistance in ohms */ uint32_t full_ohms; + /** Output resistance in ohms */ uint32_t output_ohms; }; @@ -33,7 +56,7 @@ struct voltage_divider_dt_spec { } /** - * @brief Calculates the actual voltage from the measured voltage + * @brief Calculates the actual voltage from a measured voltage * * @param[in] spec voltage divider specification from Devicetree. * @param[in,out] v_to_v Pointer to the measured voltage on input, and the @@ -56,4 +79,6 @@ static inline int voltage_divider_scale_dt(const struct voltage_divider_dt_spec return 0; } +/** @} */ + #endif /* ZEPHYR_INCLUDE_DRIVERS_ADC_VOLTAGE_DIVIDER_H_ */ From 3aec059e0a04aff21264517d4658ca2fec799c43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Thu, 18 Dec 2025 11:59:33 +0100 Subject: [PATCH 0835/3659] include: adc: add doxygen docs for current_sense_shunt extended API MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds doxygen documentation for the extended API of the current sense shunt driver. Signed-off-by: Benjamin Cabé --- .../zephyr/drivers/adc/current_sense_shunt.h | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/include/zephyr/drivers/adc/current_sense_shunt.h b/include/zephyr/drivers/adc/current_sense_shunt.h index 05e402a46aa5..0f0212333c9e 100644 --- a/include/zephyr/drivers/adc/current_sense_shunt.h +++ b/include/zephyr/drivers/adc/current_sense_shunt.h @@ -4,13 +4,35 @@ * SPDX-License-Identifier: Apache-2.0 */ +/** + * @file + * @brief Header file for extended ADC API of Current Sense Shunt + * @ingroup adc_current_sense_shunt_interface + */ + #ifndef ZEPHYR_INCLUDE_DRIVERS_ADC_CURRENT_SENSE_SHUNT_H_ #define ZEPHYR_INCLUDE_DRIVERS_ADC_CURRENT_SENSE_SHUNT_H_ #include +/** + * @brief Current Sense Shunt + * @defgroup adc_current_sense_shunt_interface Current Sense Shunt + * @ingroup adc_interface_ext + * @{ + */ + +/** + * @brief Current sense shunt DT struct. + * + * This stores information about a current sense shunt obtained from Devicetree. + * + * @see CURRENT_SENSE_SHUNT_DT_SPEC_GET + */ struct current_sense_shunt_dt_spec { + /** ADC channel info */ const struct adc_dt_spec port; + /** Shunt resistor value in micro-ohms */ uint32_t shunt_micro_ohms; }; @@ -31,7 +53,7 @@ struct current_sense_shunt_dt_spec { } /** - * @brief Calculates the actual amperage from the measured voltage + * @brief Calculates the actual amperage from a measured voltage * * @param[in] spec current sensor specification from Devicetree. * @param[in,out] v_to_i Pointer to the measured voltage in millivolts on input, and the @@ -49,4 +71,6 @@ static inline void current_sense_shunt_scale_dt(const struct current_sense_shunt *v_to_i = (int32_t)tmp; } +/** @} */ + #endif /* ZEPHYR_INCLUDE_DRIVERS_ADC_CURRENT_SENSE_SHUNT_H_ */ From cecfb5b9a3e3ae0bfc3f067528bdebd21cf34b21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Thu, 18 Dec 2025 11:58:57 +0100 Subject: [PATCH 0836/3659] include: adc: add doxygen docs for current_sense_amplifier extended API MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds doxygen documentation for the extended API of the current sense amplifier driver. Signed-off-by: Benjamin Cabé --- .../drivers/adc/current_sense_amplifier.h | 35 +++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/include/zephyr/drivers/adc/current_sense_amplifier.h b/include/zephyr/drivers/adc/current_sense_amplifier.h index fb7260934c6f..c5b10b89ecbd 100644 --- a/include/zephyr/drivers/adc/current_sense_amplifier.h +++ b/include/zephyr/drivers/adc/current_sense_amplifier.h @@ -4,21 +4,50 @@ * SPDX-License-Identifier: Apache-2.0 */ +/** + * @file + * @brief Header file for extended ADC API of Current Sense Amplifier + * @ingroup adc_current_sense_amplifier_interface + */ + #ifndef ZEPHYR_INCLUDE_DRIVERS_ADC_CURRENT_SENSE_AMPLIFIER_H_ #define ZEPHYR_INCLUDE_DRIVERS_ADC_CURRENT_SENSE_AMPLIFIER_H_ #include #include +/** + * @brief Current Sense Amplifier + * @defgroup adc_current_sense_amplifier_interface Current Sense Amplifier + * @ingroup adc_interface_ext + * @{ + */ + +/** + * @brief Current sense amplifier DT struct. + * + * This stores information about a current sense amplifier obtained from Devicetree. + * + * @see CURRENT_SENSE_AMPLIFIER_DT_SPEC_GET + */ struct current_sense_amplifier_dt_spec { + /** ADC channel info */ struct adc_dt_spec port; + /** GPIO to enable the amplifier */ struct gpio_dt_spec power_gpio; + /** Sense resistor value in milliohms */ uint32_t sense_milli_ohms; + /** Sense amplifier gain multiplier */ uint16_t sense_gain_mult; + /** Sense amplifier gain divider */ uint16_t sense_gain_div; + /** Noise threshold */ uint16_t noise_threshold; + /** Voltage at zero current in millivolts */ int16_t zero_current_voltage_mv; + /** Gain range */ enum adc_gain gain_extended_range; + /** Enable calibration */ bool enable_calibration; }; @@ -46,7 +75,7 @@ struct current_sense_amplifier_dt_spec { } /** - * @brief Calculates the actual amperage from the measured voltage + * @brief Calculates the actual amperage from a measured voltage * * @param[in] spec current sensor specification from Devicetree. * @param[in,out] v_to_i Pointer to the measured voltage in millivolts on input, and the @@ -69,7 +98,7 @@ current_sense_amplifier_scale_dt(const struct current_sense_amplifier_dt_spec *s } /** - * @brief Calculates the actual amperage from the measured voltage + * @brief Calculates the actual amperage from a measured voltage * * @param spec Current sensor specification from Devicetree. * @param microvolts Measured voltage in microvolts. @@ -94,4 +123,6 @@ current_sense_amplifier_scale_ua_dt(const struct current_sense_amplifier_dt_spec return scaled / spec->sense_gain_mult / spec->sense_milli_ohms; } +/** @} */ + #endif /* ZEPHYR_INCLUDE_DRIVERS_ADC_CURRENT_SENSE_AMPLIFIER_H_ */ From 4f2ee86cd44863a9527b91485cbef01d4c711e4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Thu, 18 Dec 2025 11:52:11 +0100 Subject: [PATCH 0837/3659] include: adc: add doxygen docs for lmp90xxx extended API MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds doxygen documentation for the extended API of the LMP90xxx ADC driver. Signed-off-by: Benjamin Cabé --- include/zephyr/drivers/adc/lmp90xxx.h | 105 +++++++++++++++++++++++++- 1 file changed, 104 insertions(+), 1 deletion(-) diff --git a/include/zephyr/drivers/adc/lmp90xxx.h b/include/zephyr/drivers/adc/lmp90xxx.h index 8fc226f5eee8..7f7a07771529 100644 --- a/include/zephyr/drivers/adc/lmp90xxx.h +++ b/include/zephyr/drivers/adc/lmp90xxx.h @@ -4,39 +4,142 @@ * SPDX-License-Identifier: Apache-2.0 */ +/** + * @file + * @brief Header file for extended API of LMP90xxx ADC + * @ingroup lmp90xxx_interface + */ + #ifndef ZEPHYR_INCLUDE_DRIVERS_ADC_LMP90XXX_H_ #define ZEPHYR_INCLUDE_DRIVERS_ADC_LMP90XXX_H_ #include #include -/* LMP90xxx supports GPIO D0..D6 */ +/** + * @brief Texas Instruments LMP90xxx Analog Front End (AFE) + * @defgroup lmp90xxx_interface LMP90xxx + * @ingroup adc_interface_ext + * @{ + */ + +/** + * @brief Maximum pin number supported by LMP90xxx + * + * LMP90xxx supports GPIO D0..D6 + */ #define LMP90XXX_GPIO_MAX 6 +/** + * @brief Configure a GPIO pin of an LMP90xxx as an output. + * + * @param dev Pointer to the device structure for the driver instance. + * @param pin Pin number. The value must be between 0 and LMP90XXX_GPIO_MAX. + * + * @retval 0 on success. + * @retval -EIO or other negative errno if communication failed. + */ int lmp90xxx_gpio_set_output(const struct device *dev, uint8_t pin); +/** + * @brief Configure a GPIO pin of an LMP90xxx as an input. + * + * @param dev Pointer to the device structure for the driver instance. + * @param pin Pin number. The value must be between 0 and LMP90XXX_GPIO_MAX. + * + * @retval 0 on success. + * @retval -EIO or other negative errno if communication failed. + */ int lmp90xxx_gpio_set_input(const struct device *dev, uint8_t pin); +/** + * @brief Set the value of a GPIO pin of an LMP90xxx. + * + * @param dev Pointer to the device structure for the driver instance. + * @param pin Pin number. The value must be between 0 and LMP90XXX_GPIO_MAX. + * @param value Value to set. + * + * @retval 0 on success. + * @retval -EIO or other negative errno if communication failed. + */ int lmp90xxx_gpio_set_pin_value(const struct device *dev, uint8_t pin, bool value); +/** + * @brief Get the value of a GPIO pin of an LMP90xxx. + * + * @param dev Pointer to the device structure for the driver instance. + * @param pin Pin number. The value must be between 0 and LMP90XXX_GPIO_MAX. + * @param value Pointer to where the value will be stored. + * + * @retval 0 on success. + * @retval -EIO or other negative errno if communication failed. + */ int lmp90xxx_gpio_get_pin_value(const struct device *dev, uint8_t pin, bool *value); +/** + * @brief Get the value of the GPIO port of an LMP90xxx. + * + * @param dev Pointer to the device structure for the driver instance. + * @param value Pointer to where the port value will be stored. + * + * @retval 0 on success. + * @retval -EIO or other negative errno if communication failed. + */ int lmp90xxx_gpio_port_get_raw(const struct device *dev, gpio_port_value_t *value); +/** + * @brief Set the value of the GPIO port of an LMP90xxx with a mask. + * + * @param dev Pointer to the device structure for the driver instance. + * @param mask Mask of pins to change. + * @param value Value to set. + * + * @retval 0 on success. + * @retval -EIO or other negative errno if communication failed. + */ int lmp90xxx_gpio_port_set_masked_raw(const struct device *dev, gpio_port_pins_t mask, gpio_port_value_t value); +/** + * @brief Set bits of the GPIO port of an LMP90xxx. + * + * @param dev Pointer to the device structure for the driver instance. + * @param pins Mask of pins to set. + * + * @retval 0 on success. + * @retval -EIO or other negative errno if communication failed. + */ int lmp90xxx_gpio_port_set_bits_raw(const struct device *dev, gpio_port_pins_t pins); +/** + * @brief Clear bits of the GPIO port of an LMP90xxx. + * + * @param dev Pointer to the device structure for the driver instance. + * @param pins Mask of pins to clear. + * + * @retval 0 on success. + * @retval -EIO or other negative errno if communication failed. + */ int lmp90xxx_gpio_port_clear_bits_raw(const struct device *dev, gpio_port_pins_t pins); +/** + * @brief Toggle bits of the GPIO port of an LMP90xxx. + * + * @param dev Pointer to the device structure for the driver instance. + * @param pins Mask of pins to toggle. + * + * @retval 0 on success. + * @retval -EIO or other negative errno if communication failed. + */ int lmp90xxx_gpio_port_toggle_bits(const struct device *dev, gpio_port_pins_t pins); +/** @} */ + #endif /* ZEPHYR_INCLUDE_DRIVERS_ADC_LMP90XXX_H_ */ From 5006ca561084eb8c4a7a5a8754e25086b474fe68 Mon Sep 17 00:00:00 2001 From: Evgenii Kosenko Date: Fri, 19 Dec 2025 11:45:08 +0200 Subject: [PATCH 0838/3659] tests: Bluetooth: Tester: Enable Encrypted Advertising Data Btp got support of EAD in f04d0196de7b, enabling config flag will enable GAP/SCN/BV-01-C and GAP/ADV/BV-20-C to be executed Signed-off-by: Evgenii Kosenko --- tests/bluetooth/tester/prj.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/bluetooth/tester/prj.conf b/tests/bluetooth/tester/prj.conf index 16a168d4b197..9c1c540c4d04 100644 --- a/tests/bluetooth/tester/prj.conf +++ b/tests/bluetooth/tester/prj.conf @@ -37,6 +37,7 @@ CONFIG_BT_MAX_PAIRED=3 CONFIG_BT_GATT_NOTIFY_MULTIPLE=y CONFIG_BT_ATT_RETRY_ON_SEC_ERR=n CONFIG_BT_GATT_DYNAMIC_DB=y +CONFIG_BT_EAD=y CONFIG_BT_EXT_ADV=y CONFIG_BT_PER_ADV=y CONFIG_BT_PER_ADV_SYNC=y From e5ce6869ffe65e71e20bde14f699f7442f5fcebd Mon Sep 17 00:00:00 2001 From: Haoran Jiang Date: Fri, 19 Dec 2025 17:55:31 +0800 Subject: [PATCH 0839/3659] dt-bindings: pinctrl: sf32lb52: Generate pinctrl header file for sf32lb Previously, the pinctrl macro definitions on the sf32lb platform relied on manual maintenance, which led to some errors. We will now use scripts to generate the metadata, ensuring accuracy Signed-off-by: Haoran Jiang --- .../dt-bindings/pinctrl/sf32lb52x-pinctrl.h | 1532 ++++++++--------- 1 file changed, 674 insertions(+), 858 deletions(-) diff --git a/include/zephyr/dt-bindings/pinctrl/sf32lb52x-pinctrl.h b/include/zephyr/dt-bindings/pinctrl/sf32lb52x-pinctrl.h index fade2b853c42..e273a664e4df 100644 --- a/include/zephyr/dt-bindings/pinctrl/sf32lb52x-pinctrl.h +++ b/include/zephyr/dt-bindings/pinctrl/sf32lb52x-pinctrl.h @@ -1,6 +1,8 @@ /* - * Copyright (c) 2025 Core Devices LLC + * Copyright (c) 2025 SiFli Technologies(Nanjing) Co., Ltd * SPDX-License-Identifier: Apache-2.0 + * + * Auto-generated by */ #ifndef _INCLUDE_ZEPHYR_DT_BINDINGS_PINCTRL_SF32LB52X_PINCTRL_H_ @@ -16,38 +18,35 @@ #define PA00_ANALOG SF32LB_PINMUX_ANALOG(PA, 0U) #define PA00_GPIO SF32LB_PINMUX(PA, 0U, 0U, 0U, 0U) #define PA00_LCDC1_SPI_RSTB SF32LB_PINMUX(PA, 0U, 1U, 0U, 0U) -/* PA_I2C_UART functions start */ -#define PA00_I2C1_SDA SF32LB_PINMUX(PA, 0U, 4U, 0x48U, 1U) #define PA00_I2C1_SCL SF32LB_PINMUX(PA, 0U, 4U, 0x48U, 0U) -#define PA00_I2C2_SDA SF32LB_PINMUX(PA, 0U, 4U, 0x4CU, 1U) +#define PA00_I2C1_SDA SF32LB_PINMUX(PA, 0U, 4U, 0x48U, 1U) #define PA00_I2C2_SCL SF32LB_PINMUX(PA, 0U, 4U, 0x4CU, 0U) -#define PA00_I2C3_SDA SF32LB_PINMUX(PA, 0U, 4U, 0x50U, 1U) +#define PA00_I2C2_SDA SF32LB_PINMUX(PA, 0U, 4U, 0x4CU, 1U) #define PA00_I2C3_SCL SF32LB_PINMUX(PA, 0U, 4U, 0x50U, 0U) -#define PA00_I2C4_SDA SF32LB_PINMUX(PA, 0U, 4U, 0x54U, 1U) +#define PA00_I2C3_SDA SF32LB_PINMUX(PA, 0U, 4U, 0x50U, 1U) #define PA00_I2C4_SCL SF32LB_PINMUX(PA, 0U, 4U, 0x54U, 0U) -#define PA00_USART1_CTS SF32LB_PINMUX(PA, 0U, 4U, 0x58U, 3U) -#define PA00_USART1_RTS SF32LB_PINMUX(PA, 0U, 4U, 0x58U, 2U) -#define PA00_USART1_RXD SF32LB_PINMUX(PA, 0U, 4U, 0x58U, 1U) +#define PA00_I2C4_SDA SF32LB_PINMUX(PA, 0U, 4U, 0x54U, 1U) #define PA00_USART1_TXD SF32LB_PINMUX(PA, 0U, 4U, 0x58U, 0U) -#define PA00_USART2_CTS SF32LB_PINMUX(PA, 0U, 4U, 0x5CU, 3U) -#define PA00_USART2_RTS SF32LB_PINMUX(PA, 0U, 4U, 0x5CU, 2U) -#define PA00_USART2_RXD SF32LB_PINMUX(PA, 0U, 4U, 0x5CU, 1U) +#define PA00_USART1_RXD SF32LB_PINMUX(PA, 0U, 4U, 0x58U, 1U) +#define PA00_USART1_RTS SF32LB_PINMUX(PA, 0U, 4U, 0x58U, 2U) +#define PA00_USART1_CTS SF32LB_PINMUX(PA, 0U, 4U, 0x58U, 3U) #define PA00_USART2_TXD SF32LB_PINMUX(PA, 0U, 4U, 0x5CU, 0U) -#define PA00_USART3_CTS SF32LB_PINMUX(PA, 0U, 4U, 0x60U, 3U) -#define PA00_USART3_RTS SF32LB_PINMUX(PA, 0U, 4U, 0x60U, 2U) -#define PA00_USART3_RXD SF32LB_PINMUX(PA, 0U, 4U, 0x60U, 1U) +#define PA00_USART2_RXD SF32LB_PINMUX(PA, 0U, 4U, 0x5CU, 1U) +#define PA00_USART2_RTS SF32LB_PINMUX(PA, 0U, 4U, 0x5CU, 2U) +#define PA00_USART2_CTS SF32LB_PINMUX(PA, 0U, 4U, 0x5CU, 3U) #define PA00_USART3_TXD SF32LB_PINMUX(PA, 0U, 4U, 0x60U, 0U) -/* PA_I2C_UART functions end */ -/* PA_TIM functions start */ +#define PA00_USART3_RXD SF32LB_PINMUX(PA, 0U, 4U, 0x60U, 1U) +#define PA00_USART3_RTS SF32LB_PINMUX(PA, 0U, 4U, 0x60U, 2U) +#define PA00_USART3_CTS SF32LB_PINMUX(PA, 0U, 4U, 0x60U, 3U) #define PA00_GPTIM1_CH1 SF32LB_PINMUX(PA, 0U, 5U, 0x64U, 0U) #define PA00_GPTIM1_CH2 SF32LB_PINMUX(PA, 0U, 5U, 0x64U, 1U) #define PA00_GPTIM1_CH3 SF32LB_PINMUX(PA, 0U, 5U, 0x64U, 2U) #define PA00_GPTIM1_CH4 SF32LB_PINMUX(PA, 0U, 5U, 0x64U, 3U) +#define PA00_GPTIM1_ETR SF32LB_PINMUX(PA, 0U, 5U, 0x6CU, 0U) #define PA00_GPTIM2_CH1 SF32LB_PINMUX(PA, 0U, 5U, 0x68U, 0U) #define PA00_GPTIM2_CH2 SF32LB_PINMUX(PA, 0U, 5U, 0x68U, 1U) #define PA00_GPTIM2_CH3 SF32LB_PINMUX(PA, 0U, 5U, 0x68U, 2U) #define PA00_GPTIM2_CH4 SF32LB_PINMUX(PA, 0U, 5U, 0x68U, 3U) -#define PA00_GPTIM1_ETR SF32LB_PINMUX(PA, 0U, 5U, 0x6CU, 0U) #define PA00_GPTIM2_ETR SF32LB_PINMUX(PA, 0U, 5U, 0x6CU, 1U) #define PA00_LPTIM1_IN SF32LB_PINMUX(PA, 0U, 5U, 0x70U, 0U) #define PA00_LPTIM1_OUT SF32LB_PINMUX(PA, 0U, 5U, 0x70U, 1U) @@ -62,47 +61,43 @@ #define PA00_ATIM1_CH1N SF32LB_PINMUX(PA, 0U, 5U, 0x7CU, 0U) #define PA00_ATIM1_CH2N SF32LB_PINMUX(PA, 0U, 5U, 0x7CU, 1U) #define PA00_ATIM1_CH3N SF32LB_PINMUX(PA, 0U, 5U, 0x7CU, 2U) +#define PA00_ATIM1_ETR SF32LB_PINMUX(PA, 0U, 5U, 0x80U, 2U) #define PA00_ATIM1_BK SF32LB_PINMUX(PA, 0U, 5U, 0x80U, 0U) #define PA00_ATIM1_BK2 SF32LB_PINMUX(PA, 0U, 5U, 0x80U, 1U) -#define PA00_ATIM1_ETR SF32LB_PINMUX(PA, 0U, 5U, 0x80U, 2U) -/* PA_TIM functions end */ #define PA00_LCDC1_8080_RSTB SF32LB_PINMUX(PA, 0U, 7U, 0U, 0U) /* PA01 */ #define PA01_ANALOG SF32LB_PINMUX_ANALOG(PA, 1U) #define PA01_GPIO SF32LB_PINMUX(PA, 1U, 0U, 0U, 0U) -/* PA_I2C_UART functions start */ -#define PA01_I2C1_SDA SF32LB_PINMUX(PA, 1U, 4U, 0x48U, 1U) #define PA01_I2C1_SCL SF32LB_PINMUX(PA, 1U, 4U, 0x48U, 0U) -#define PA01_I2C2_SDA SF32LB_PINMUX(PA, 1U, 4U, 0x4CU, 1U) +#define PA01_I2C1_SDA SF32LB_PINMUX(PA, 1U, 4U, 0x48U, 1U) #define PA01_I2C2_SCL SF32LB_PINMUX(PA, 1U, 4U, 0x4CU, 0U) -#define PA01_I2C3_SDA SF32LB_PINMUX(PA, 1U, 4U, 0x50U, 1U) +#define PA01_I2C2_SDA SF32LB_PINMUX(PA, 1U, 4U, 0x4CU, 1U) #define PA01_I2C3_SCL SF32LB_PINMUX(PA, 1U, 4U, 0x50U, 0U) -#define PA01_I2C4_SDA SF32LB_PINMUX(PA, 1U, 4U, 0x54U, 1U) +#define PA01_I2C3_SDA SF32LB_PINMUX(PA, 1U, 4U, 0x50U, 1U) #define PA01_I2C4_SCL SF32LB_PINMUX(PA, 1U, 4U, 0x54U, 0U) -#define PA01_USART1_CTS SF32LB_PINMUX(PA, 1U, 4U, 0x58U, 3U) -#define PA01_USART1_RTS SF32LB_PINMUX(PA, 1U, 4U, 0x58U, 2U) -#define PA01_USART1_RXD SF32LB_PINMUX(PA, 1U, 4U, 0x58U, 1U) +#define PA01_I2C4_SDA SF32LB_PINMUX(PA, 1U, 4U, 0x54U, 1U) #define PA01_USART1_TXD SF32LB_PINMUX(PA, 1U, 4U, 0x58U, 0U) -#define PA01_USART2_CTS SF32LB_PINMUX(PA, 1U, 4U, 0x5CU, 3U) -#define PA01_USART2_RTS SF32LB_PINMUX(PA, 1U, 4U, 0x5CU, 2U) -#define PA01_USART2_RXD SF32LB_PINMUX(PA, 1U, 4U, 0x5CU, 1U) +#define PA01_USART1_RXD SF32LB_PINMUX(PA, 1U, 4U, 0x58U, 1U) +#define PA01_USART1_RTS SF32LB_PINMUX(PA, 1U, 4U, 0x58U, 2U) +#define PA01_USART1_CTS SF32LB_PINMUX(PA, 1U, 4U, 0x58U, 3U) #define PA01_USART2_TXD SF32LB_PINMUX(PA, 1U, 4U, 0x5CU, 0U) -#define PA01_USART3_CTS SF32LB_PINMUX(PA, 1U, 4U, 0x60U, 3U) -#define PA01_USART3_RTS SF32LB_PINMUX(PA, 1U, 4U, 0x60U, 2U) -#define PA01_USART3_RXD SF32LB_PINMUX(PA, 1U, 4U, 0x60U, 1U) +#define PA01_USART2_RXD SF32LB_PINMUX(PA, 1U, 4U, 0x5CU, 1U) +#define PA01_USART2_RTS SF32LB_PINMUX(PA, 1U, 4U, 0x5CU, 2U) +#define PA01_USART2_CTS SF32LB_PINMUX(PA, 1U, 4U, 0x5CU, 3U) #define PA01_USART3_TXD SF32LB_PINMUX(PA, 1U, 4U, 0x60U, 0U) -/* PA_I2C_UART functions end */ -/* PA_TIM functions start */ +#define PA01_USART3_RXD SF32LB_PINMUX(PA, 1U, 4U, 0x60U, 1U) +#define PA01_USART3_RTS SF32LB_PINMUX(PA, 1U, 4U, 0x60U, 2U) +#define PA01_USART3_CTS SF32LB_PINMUX(PA, 1U, 4U, 0x60U, 3U) #define PA01_GPTIM1_CH1 SF32LB_PINMUX(PA, 1U, 5U, 0x64U, 0U) #define PA01_GPTIM1_CH2 SF32LB_PINMUX(PA, 1U, 5U, 0x64U, 1U) #define PA01_GPTIM1_CH3 SF32LB_PINMUX(PA, 1U, 5U, 0x64U, 2U) #define PA01_GPTIM1_CH4 SF32LB_PINMUX(PA, 1U, 5U, 0x64U, 3U) +#define PA01_GPTIM1_ETR SF32LB_PINMUX(PA, 1U, 5U, 0x6CU, 0U) #define PA01_GPTIM2_CH1 SF32LB_PINMUX(PA, 1U, 5U, 0x68U, 0U) #define PA01_GPTIM2_CH2 SF32LB_PINMUX(PA, 1U, 5U, 0x68U, 1U) #define PA01_GPTIM2_CH3 SF32LB_PINMUX(PA, 1U, 5U, 0x68U, 2U) #define PA01_GPTIM2_CH4 SF32LB_PINMUX(PA, 1U, 5U, 0x68U, 3U) -#define PA01_GPTIM1_ETR SF32LB_PINMUX(PA, 1U, 5U, 0x6CU, 0U) #define PA01_GPTIM2_ETR SF32LB_PINMUX(PA, 1U, 5U, 0x6CU, 1U) #define PA01_LPTIM1_IN SF32LB_PINMUX(PA, 1U, 5U, 0x70U, 0U) #define PA01_LPTIM1_OUT SF32LB_PINMUX(PA, 1U, 5U, 0x70U, 1U) @@ -117,48 +112,44 @@ #define PA01_ATIM1_CH1N SF32LB_PINMUX(PA, 1U, 5U, 0x7CU, 0U) #define PA01_ATIM1_CH2N SF32LB_PINMUX(PA, 1U, 5U, 0x7CU, 1U) #define PA01_ATIM1_CH3N SF32LB_PINMUX(PA, 1U, 5U, 0x7CU, 2U) +#define PA01_ATIM1_ETR SF32LB_PINMUX(PA, 1U, 5U, 0x80U, 2U) #define PA01_ATIM1_BK SF32LB_PINMUX(PA, 1U, 5U, 0x80U, 0U) #define PA01_ATIM1_BK2 SF32LB_PINMUX(PA, 1U, 5U, 0x80U, 1U) -#define PA01_ATIM1_ETR SF32LB_PINMUX(PA, 1U, 5U, 0x80U, 2U) -/* PA_TIM functions end */ /* PA02 */ #define PA02_ANALOG SF32LB_PINMUX_ANALOG(PA, 2U) #define PA02_GPIO SF32LB_PINMUX(PA, 2U, 0U, 0U, 0U) #define PA02_LCDC1_SPI_TE SF32LB_PINMUX(PA, 2U, 1U, 0U, 0U) #define PA02_I2S1_MCLK SF32LB_PINMUX(PA, 2U, 3U, 0U, 0U) -/* PA_I2C_UART functions start */ -#define PA02_I2C1_SDA SF32LB_PINMUX(PA, 2U, 4U, 0x48U, 1U) #define PA02_I2C1_SCL SF32LB_PINMUX(PA, 2U, 4U, 0x48U, 0U) -#define PA02_I2C2_SDA SF32LB_PINMUX(PA, 2U, 4U, 0x4CU, 1U) +#define PA02_I2C1_SDA SF32LB_PINMUX(PA, 2U, 4U, 0x48U, 1U) #define PA02_I2C2_SCL SF32LB_PINMUX(PA, 2U, 4U, 0x4CU, 0U) -#define PA02_I2C3_SDA SF32LB_PINMUX(PA, 2U, 4U, 0x50U, 1U) +#define PA02_I2C2_SDA SF32LB_PINMUX(PA, 2U, 4U, 0x4CU, 1U) #define PA02_I2C3_SCL SF32LB_PINMUX(PA, 2U, 4U, 0x50U, 0U) -#define PA02_I2C4_SDA SF32LB_PINMUX(PA, 2U, 4U, 0x54U, 1U) +#define PA02_I2C3_SDA SF32LB_PINMUX(PA, 2U, 4U, 0x50U, 1U) #define PA02_I2C4_SCL SF32LB_PINMUX(PA, 2U, 4U, 0x54U, 0U) -#define PA02_USART1_CTS SF32LB_PINMUX(PA, 2U, 4U, 0x58U, 3U) -#define PA02_USART1_RTS SF32LB_PINMUX(PA, 2U, 4U, 0x58U, 2U) -#define PA02_USART1_RXD SF32LB_PINMUX(PA, 2U, 4U, 0x58U, 1U) +#define PA02_I2C4_SDA SF32LB_PINMUX(PA, 2U, 4U, 0x54U, 1U) #define PA02_USART1_TXD SF32LB_PINMUX(PA, 2U, 4U, 0x58U, 0U) -#define PA02_USART2_CTS SF32LB_PINMUX(PA, 2U, 4U, 0x5CU, 3U) -#define PA02_USART2_RTS SF32LB_PINMUX(PA, 2U, 4U, 0x5CU, 2U) -#define PA02_USART2_RXD SF32LB_PINMUX(PA, 2U, 4U, 0x5CU, 1U) +#define PA02_USART1_RXD SF32LB_PINMUX(PA, 2U, 4U, 0x58U, 1U) +#define PA02_USART1_RTS SF32LB_PINMUX(PA, 2U, 4U, 0x58U, 2U) +#define PA02_USART1_CTS SF32LB_PINMUX(PA, 2U, 4U, 0x58U, 3U) #define PA02_USART2_TXD SF32LB_PINMUX(PA, 2U, 4U, 0x5CU, 0U) -#define PA02_USART3_CTS SF32LB_PINMUX(PA, 2U, 4U, 0x60U, 3U) -#define PA02_USART3_RTS SF32LB_PINMUX(PA, 2U, 4U, 0x60U, 2U) -#define PA02_USART3_RXD SF32LB_PINMUX(PA, 2U, 4U, 0x60U, 1U) +#define PA02_USART2_RXD SF32LB_PINMUX(PA, 2U, 4U, 0x5CU, 1U) +#define PA02_USART2_RTS SF32LB_PINMUX(PA, 2U, 4U, 0x5CU, 2U) +#define PA02_USART2_CTS SF32LB_PINMUX(PA, 2U, 4U, 0x5CU, 3U) #define PA02_USART3_TXD SF32LB_PINMUX(PA, 2U, 4U, 0x60U, 0U) -/* PA_I2C_UART functions end */ -/* PA_TIM functions start */ +#define PA02_USART3_RXD SF32LB_PINMUX(PA, 2U, 4U, 0x60U, 1U) +#define PA02_USART3_RTS SF32LB_PINMUX(PA, 2U, 4U, 0x60U, 2U) +#define PA02_USART3_CTS SF32LB_PINMUX(PA, 2U, 4U, 0x60U, 3U) #define PA02_GPTIM1_CH1 SF32LB_PINMUX(PA, 2U, 5U, 0x64U, 0U) #define PA02_GPTIM1_CH2 SF32LB_PINMUX(PA, 2U, 5U, 0x64U, 1U) #define PA02_GPTIM1_CH3 SF32LB_PINMUX(PA, 2U, 5U, 0x64U, 2U) #define PA02_GPTIM1_CH4 SF32LB_PINMUX(PA, 2U, 5U, 0x64U, 3U) +#define PA02_GPTIM1_ETR SF32LB_PINMUX(PA, 2U, 5U, 0x6CU, 0U) #define PA02_GPTIM2_CH1 SF32LB_PINMUX(PA, 2U, 5U, 0x68U, 0U) #define PA02_GPTIM2_CH2 SF32LB_PINMUX(PA, 2U, 5U, 0x68U, 1U) #define PA02_GPTIM2_CH3 SF32LB_PINMUX(PA, 2U, 5U, 0x68U, 2U) #define PA02_GPTIM2_CH4 SF32LB_PINMUX(PA, 2U, 5U, 0x68U, 3U) -#define PA02_GPTIM1_ETR SF32LB_PINMUX(PA, 2U, 5U, 0x6CU, 0U) #define PA02_GPTIM2_ETR SF32LB_PINMUX(PA, 2U, 5U, 0x6CU, 1U) #define PA02_LPTIM1_IN SF32LB_PINMUX(PA, 2U, 5U, 0x70U, 0U) #define PA02_LPTIM1_OUT SF32LB_PINMUX(PA, 2U, 5U, 0x70U, 1U) @@ -173,10 +164,9 @@ #define PA02_ATIM1_CH1N SF32LB_PINMUX(PA, 2U, 5U, 0x7CU, 0U) #define PA02_ATIM1_CH2N SF32LB_PINMUX(PA, 2U, 5U, 0x7CU, 1U) #define PA02_ATIM1_CH3N SF32LB_PINMUX(PA, 2U, 5U, 0x7CU, 2U) +#define PA02_ATIM1_ETR SF32LB_PINMUX(PA, 2U, 5U, 0x80U, 2U) #define PA02_ATIM1_BK SF32LB_PINMUX(PA, 2U, 5U, 0x80U, 0U) #define PA02_ATIM1_BK2 SF32LB_PINMUX(PA, 2U, 5U, 0x80U, 1U) -#define PA02_ATIM1_ETR SF32LB_PINMUX(PA, 2U, 5U, 0x80U, 2U) -/* PA_TIM functions end */ #define PA02_LCDC1_JDI_B2 SF32LB_PINMUX(PA, 2U, 6U, 0U, 0U) #define PA02_LCDC1_8080_TE SF32LB_PINMUX(PA, 2U, 7U, 0U, 0U) @@ -185,38 +175,35 @@ #define PA03_GPIO SF32LB_PINMUX(PA, 3U, 0U, 0U, 0U) #define PA03_LCDC1_SPI_CS SF32LB_PINMUX(PA, 3U, 1U, 0U, 0U) #define PA03_I2S1_SDO SF32LB_PINMUX(PA, 3U, 3U, 0U, 0U) -/* PA_I2C_UART functions start */ -#define PA03_I2C1_SDA SF32LB_PINMUX(PA, 3U, 4U, 0x48U, 1U) #define PA03_I2C1_SCL SF32LB_PINMUX(PA, 3U, 4U, 0x48U, 0U) -#define PA03_I2C2_SDA SF32LB_PINMUX(PA, 3U, 4U, 0x4CU, 1U) +#define PA03_I2C1_SDA SF32LB_PINMUX(PA, 3U, 4U, 0x48U, 1U) #define PA03_I2C2_SCL SF32LB_PINMUX(PA, 3U, 4U, 0x4CU, 0U) -#define PA03_I2C3_SDA SF32LB_PINMUX(PA, 3U, 4U, 0x50U, 1U) +#define PA03_I2C2_SDA SF32LB_PINMUX(PA, 3U, 4U, 0x4CU, 1U) #define PA03_I2C3_SCL SF32LB_PINMUX(PA, 3U, 4U, 0x50U, 0U) -#define PA03_I2C4_SDA SF32LB_PINMUX(PA, 3U, 4U, 0x54U, 1U) +#define PA03_I2C3_SDA SF32LB_PINMUX(PA, 3U, 4U, 0x50U, 1U) #define PA03_I2C4_SCL SF32LB_PINMUX(PA, 3U, 4U, 0x54U, 0U) -#define PA03_USART1_CTS SF32LB_PINMUX(PA, 3U, 4U, 0x58U, 3U) -#define PA03_USART1_RTS SF32LB_PINMUX(PA, 3U, 4U, 0x58U, 2U) -#define PA03_USART1_RXD SF32LB_PINMUX(PA, 3U, 4U, 0x58U, 1U) +#define PA03_I2C4_SDA SF32LB_PINMUX(PA, 3U, 4U, 0x54U, 1U) #define PA03_USART1_TXD SF32LB_PINMUX(PA, 3U, 4U, 0x58U, 0U) -#define PA03_USART2_CTS SF32LB_PINMUX(PA, 3U, 4U, 0x5CU, 3U) -#define PA03_USART2_RTS SF32LB_PINMUX(PA, 3U, 4U, 0x5CU, 2U) -#define PA03_USART2_RXD SF32LB_PINMUX(PA, 3U, 4U, 0x5CU, 1U) +#define PA03_USART1_RXD SF32LB_PINMUX(PA, 3U, 4U, 0x58U, 1U) +#define PA03_USART1_RTS SF32LB_PINMUX(PA, 3U, 4U, 0x58U, 2U) +#define PA03_USART1_CTS SF32LB_PINMUX(PA, 3U, 4U, 0x58U, 3U) #define PA03_USART2_TXD SF32LB_PINMUX(PA, 3U, 4U, 0x5CU, 0U) -#define PA03_USART3_CTS SF32LB_PINMUX(PA, 3U, 4U, 0x60U, 3U) -#define PA03_USART3_RTS SF32LB_PINMUX(PA, 3U, 4U, 0x60U, 2U) -#define PA03_USART3_RXD SF32LB_PINMUX(PA, 3U, 4U, 0x60U, 1U) +#define PA03_USART2_RXD SF32LB_PINMUX(PA, 3U, 4U, 0x5CU, 1U) +#define PA03_USART2_RTS SF32LB_PINMUX(PA, 3U, 4U, 0x5CU, 2U) +#define PA03_USART2_CTS SF32LB_PINMUX(PA, 3U, 4U, 0x5CU, 3U) #define PA03_USART3_TXD SF32LB_PINMUX(PA, 3U, 4U, 0x60U, 0U) -/* PA_I2C_UART functions end */ -/* PA_TIM functions start */ +#define PA03_USART3_RXD SF32LB_PINMUX(PA, 3U, 4U, 0x60U, 1U) +#define PA03_USART3_RTS SF32LB_PINMUX(PA, 3U, 4U, 0x60U, 2U) +#define PA03_USART3_CTS SF32LB_PINMUX(PA, 3U, 4U, 0x60U, 3U) #define PA03_GPTIM1_CH1 SF32LB_PINMUX(PA, 3U, 5U, 0x64U, 0U) #define PA03_GPTIM1_CH2 SF32LB_PINMUX(PA, 3U, 5U, 0x64U, 1U) #define PA03_GPTIM1_CH3 SF32LB_PINMUX(PA, 3U, 5U, 0x64U, 2U) #define PA03_GPTIM1_CH4 SF32LB_PINMUX(PA, 3U, 5U, 0x64U, 3U) +#define PA03_GPTIM1_ETR SF32LB_PINMUX(PA, 3U, 5U, 0x6CU, 0U) #define PA03_GPTIM2_CH1 SF32LB_PINMUX(PA, 3U, 5U, 0x68U, 0U) #define PA03_GPTIM2_CH2 SF32LB_PINMUX(PA, 3U, 5U, 0x68U, 1U) #define PA03_GPTIM2_CH3 SF32LB_PINMUX(PA, 3U, 5U, 0x68U, 2U) #define PA03_GPTIM2_CH4 SF32LB_PINMUX(PA, 3U, 5U, 0x68U, 3U) -#define PA03_GPTIM1_ETR SF32LB_PINMUX(PA, 3U, 5U, 0x6CU, 0U) #define PA03_GPTIM2_ETR SF32LB_PINMUX(PA, 3U, 5U, 0x6CU, 1U) #define PA03_LPTIM1_IN SF32LB_PINMUX(PA, 3U, 5U, 0x70U, 0U) #define PA03_LPTIM1_OUT SF32LB_PINMUX(PA, 3U, 5U, 0x70U, 1U) @@ -231,10 +218,9 @@ #define PA03_ATIM1_CH1N SF32LB_PINMUX(PA, 3U, 5U, 0x7CU, 0U) #define PA03_ATIM1_CH2N SF32LB_PINMUX(PA, 3U, 5U, 0x7CU, 1U) #define PA03_ATIM1_CH3N SF32LB_PINMUX(PA, 3U, 5U, 0x7CU, 2U) +#define PA03_ATIM1_ETR SF32LB_PINMUX(PA, 3U, 5U, 0x80U, 2U) #define PA03_ATIM1_BK SF32LB_PINMUX(PA, 3U, 5U, 0x80U, 0U) #define PA03_ATIM1_BK2 SF32LB_PINMUX(PA, 3U, 5U, 0x80U, 1U) -#define PA03_ATIM1_ETR SF32LB_PINMUX(PA, 3U, 5U, 0x80U, 2U) -/* PA_TIM functions end */ #define PA03_LCDC1_JDI_B1 SF32LB_PINMUX(PA, 3U, 6U, 0U, 0U) #define PA03_LCDC1_8080_CS SF32LB_PINMUX(PA, 3U, 7U, 0U, 0U) @@ -243,38 +229,35 @@ #define PA04_GPIO SF32LB_PINMUX(PA, 4U, 0U, 0U, 0U) #define PA04_LCDC1_SPI_CLK SF32LB_PINMUX(PA, 4U, 1U, 0U, 0U) #define PA04_I2S1_SDI SF32LB_PINMUX(PA, 4U, 3U, 0U, 0U) -/* PA_I2C_UART functions start */ -#define PA04_I2C1_SDA SF32LB_PINMUX(PA, 4U, 4U, 0x48U, 1U) #define PA04_I2C1_SCL SF32LB_PINMUX(PA, 4U, 4U, 0x48U, 0U) -#define PA04_I2C2_SDA SF32LB_PINMUX(PA, 4U, 4U, 0x4CU, 1U) +#define PA04_I2C1_SDA SF32LB_PINMUX(PA, 4U, 4U, 0x48U, 1U) #define PA04_I2C2_SCL SF32LB_PINMUX(PA, 4U, 4U, 0x4CU, 0U) -#define PA04_I2C3_SDA SF32LB_PINMUX(PA, 4U, 4U, 0x50U, 1U) +#define PA04_I2C2_SDA SF32LB_PINMUX(PA, 4U, 4U, 0x4CU, 1U) #define PA04_I2C3_SCL SF32LB_PINMUX(PA, 4U, 4U, 0x50U, 0U) -#define PA04_I2C4_SDA SF32LB_PINMUX(PA, 4U, 4U, 0x54U, 1U) +#define PA04_I2C3_SDA SF32LB_PINMUX(PA, 4U, 4U, 0x50U, 1U) #define PA04_I2C4_SCL SF32LB_PINMUX(PA, 4U, 4U, 0x54U, 0U) -#define PA04_USART1_CTS SF32LB_PINMUX(PA, 4U, 4U, 0x58U, 3U) -#define PA04_USART1_RTS SF32LB_PINMUX(PA, 4U, 4U, 0x58U, 2U) -#define PA04_USART1_RXD SF32LB_PINMUX(PA, 4U, 4U, 0x58U, 1U) +#define PA04_I2C4_SDA SF32LB_PINMUX(PA, 4U, 4U, 0x54U, 1U) #define PA04_USART1_TXD SF32LB_PINMUX(PA, 4U, 4U, 0x58U, 0U) -#define PA04_USART2_CTS SF32LB_PINMUX(PA, 4U, 4U, 0x5CU, 3U) -#define PA04_USART2_RTS SF32LB_PINMUX(PA, 4U, 4U, 0x5CU, 2U) -#define PA04_USART2_RXD SF32LB_PINMUX(PA, 4U, 4U, 0x5CU, 1U) +#define PA04_USART1_RXD SF32LB_PINMUX(PA, 4U, 4U, 0x58U, 1U) +#define PA04_USART1_RTS SF32LB_PINMUX(PA, 4U, 4U, 0x58U, 2U) +#define PA04_USART1_CTS SF32LB_PINMUX(PA, 4U, 4U, 0x58U, 3U) #define PA04_USART2_TXD SF32LB_PINMUX(PA, 4U, 4U, 0x5CU, 0U) -#define PA04_USART3_CTS SF32LB_PINMUX(PA, 4U, 4U, 0x60U, 3U) -#define PA04_USART3_RTS SF32LB_PINMUX(PA, 4U, 4U, 0x60U, 2U) -#define PA04_USART3_RXD SF32LB_PINMUX(PA, 4U, 4U, 0x60U, 1U) +#define PA04_USART2_RXD SF32LB_PINMUX(PA, 4U, 4U, 0x5CU, 1U) +#define PA04_USART2_RTS SF32LB_PINMUX(PA, 4U, 4U, 0x5CU, 2U) +#define PA04_USART2_CTS SF32LB_PINMUX(PA, 4U, 4U, 0x5CU, 3U) #define PA04_USART3_TXD SF32LB_PINMUX(PA, 4U, 4U, 0x60U, 0U) -/* PA_I2C_UART functions end */ -/* PA_TIM functions start */ +#define PA04_USART3_RXD SF32LB_PINMUX(PA, 4U, 4U, 0x60U, 1U) +#define PA04_USART3_RTS SF32LB_PINMUX(PA, 4U, 4U, 0x60U, 2U) +#define PA04_USART3_CTS SF32LB_PINMUX(PA, 4U, 4U, 0x60U, 3U) #define PA04_GPTIM1_CH1 SF32LB_PINMUX(PA, 4U, 5U, 0x64U, 0U) #define PA04_GPTIM1_CH2 SF32LB_PINMUX(PA, 4U, 5U, 0x64U, 1U) #define PA04_GPTIM1_CH3 SF32LB_PINMUX(PA, 4U, 5U, 0x64U, 2U) #define PA04_GPTIM1_CH4 SF32LB_PINMUX(PA, 4U, 5U, 0x64U, 3U) +#define PA04_GPTIM1_ETR SF32LB_PINMUX(PA, 4U, 5U, 0x6CU, 0U) #define PA04_GPTIM2_CH1 SF32LB_PINMUX(PA, 4U, 5U, 0x68U, 0U) #define PA04_GPTIM2_CH2 SF32LB_PINMUX(PA, 4U, 5U, 0x68U, 1U) #define PA04_GPTIM2_CH3 SF32LB_PINMUX(PA, 4U, 5U, 0x68U, 2U) #define PA04_GPTIM2_CH4 SF32LB_PINMUX(PA, 4U, 5U, 0x68U, 3U) -#define PA04_GPTIM1_ETR SF32LB_PINMUX(PA, 4U, 5U, 0x6CU, 0U) #define PA04_GPTIM2_ETR SF32LB_PINMUX(PA, 4U, 5U, 0x6CU, 1U) #define PA04_LPTIM1_IN SF32LB_PINMUX(PA, 4U, 5U, 0x70U, 0U) #define PA04_LPTIM1_OUT SF32LB_PINMUX(PA, 4U, 5U, 0x70U, 1U) @@ -289,10 +272,9 @@ #define PA04_ATIM1_CH1N SF32LB_PINMUX(PA, 4U, 5U, 0x7CU, 0U) #define PA04_ATIM1_CH2N SF32LB_PINMUX(PA, 4U, 5U, 0x7CU, 1U) #define PA04_ATIM1_CH3N SF32LB_PINMUX(PA, 4U, 5U, 0x7CU, 2U) +#define PA04_ATIM1_ETR SF32LB_PINMUX(PA, 4U, 5U, 0x80U, 2U) #define PA04_ATIM1_BK SF32LB_PINMUX(PA, 4U, 5U, 0x80U, 0U) #define PA04_ATIM1_BK2 SF32LB_PINMUX(PA, 4U, 5U, 0x80U, 1U) -#define PA04_ATIM1_ETR SF32LB_PINMUX(PA, 4U, 5U, 0x80U, 2U) -/* PA_TIM functions end */ #define PA04_LCDC1_JDI_G1 SF32LB_PINMUX(PA, 4U, 6U, 0U, 0U) #define PA04_LCDC1_8080_WR SF32LB_PINMUX(PA, 4U, 7U, 0U, 0U) @@ -301,38 +283,35 @@ #define PA05_GPIO SF32LB_PINMUX(PA, 5U, 0U, 0U, 0U) #define PA05_LCDC1_SPI_DIO0 SF32LB_PINMUX(PA, 5U, 1U, 0U, 0U) #define PA05_I2S1_BCK SF32LB_PINMUX(PA, 5U, 3U, 0U, 0U) -/* PA_I2C_UART functions start */ -#define PA05_I2C1_SDA SF32LB_PINMUX(PA, 5U, 4U, 0x48U, 1U) #define PA05_I2C1_SCL SF32LB_PINMUX(PA, 5U, 4U, 0x48U, 0U) -#define PA05_I2C2_SDA SF32LB_PINMUX(PA, 5U, 4U, 0x4CU, 1U) +#define PA05_I2C1_SDA SF32LB_PINMUX(PA, 5U, 4U, 0x48U, 1U) #define PA05_I2C2_SCL SF32LB_PINMUX(PA, 5U, 4U, 0x4CU, 0U) -#define PA05_I2C3_SDA SF32LB_PINMUX(PA, 5U, 4U, 0x50U, 1U) +#define PA05_I2C2_SDA SF32LB_PINMUX(PA, 5U, 4U, 0x4CU, 1U) #define PA05_I2C3_SCL SF32LB_PINMUX(PA, 5U, 4U, 0x50U, 0U) -#define PA05_I2C4_SDA SF32LB_PINMUX(PA, 5U, 4U, 0x54U, 1U) +#define PA05_I2C3_SDA SF32LB_PINMUX(PA, 5U, 4U, 0x50U, 1U) #define PA05_I2C4_SCL SF32LB_PINMUX(PA, 5U, 4U, 0x54U, 0U) -#define PA05_USART1_CTS SF32LB_PINMUX(PA, 5U, 4U, 0x58U, 3U) -#define PA05_USART1_RTS SF32LB_PINMUX(PA, 5U, 4U, 0x58U, 2U) -#define PA05_USART1_RXD SF32LB_PINMUX(PA, 5U, 4U, 0x58U, 1U) +#define PA05_I2C4_SDA SF32LB_PINMUX(PA, 5U, 4U, 0x54U, 1U) #define PA05_USART1_TXD SF32LB_PINMUX(PA, 5U, 4U, 0x58U, 0U) -#define PA05_USART2_CTS SF32LB_PINMUX(PA, 5U, 4U, 0x5CU, 3U) -#define PA05_USART2_RTS SF32LB_PINMUX(PA, 5U, 4U, 0x5CU, 2U) -#define PA05_USART2_RXD SF32LB_PINMUX(PA, 5U, 4U, 0x5CU, 1U) +#define PA05_USART1_RXD SF32LB_PINMUX(PA, 5U, 4U, 0x58U, 1U) +#define PA05_USART1_RTS SF32LB_PINMUX(PA, 5U, 4U, 0x58U, 2U) +#define PA05_USART1_CTS SF32LB_PINMUX(PA, 5U, 4U, 0x58U, 3U) #define PA05_USART2_TXD SF32LB_PINMUX(PA, 5U, 4U, 0x5CU, 0U) -#define PA05_USART3_CTS SF32LB_PINMUX(PA, 5U, 4U, 0x60U, 3U) -#define PA05_USART3_RTS SF32LB_PINMUX(PA, 5U, 4U, 0x60U, 2U) -#define PA05_USART3_RXD SF32LB_PINMUX(PA, 5U, 4U, 0x60U, 1U) +#define PA05_USART2_RXD SF32LB_PINMUX(PA, 5U, 4U, 0x5CU, 1U) +#define PA05_USART2_RTS SF32LB_PINMUX(PA, 5U, 4U, 0x5CU, 2U) +#define PA05_USART2_CTS SF32LB_PINMUX(PA, 5U, 4U, 0x5CU, 3U) #define PA05_USART3_TXD SF32LB_PINMUX(PA, 5U, 4U, 0x60U, 0U) -/* PA_I2C_UART functions end */ -/* PA_TIM functions start */ +#define PA05_USART3_RXD SF32LB_PINMUX(PA, 5U, 4U, 0x60U, 1U) +#define PA05_USART3_RTS SF32LB_PINMUX(PA, 5U, 4U, 0x60U, 2U) +#define PA05_USART3_CTS SF32LB_PINMUX(PA, 5U, 4U, 0x60U, 3U) #define PA05_GPTIM1_CH1 SF32LB_PINMUX(PA, 5U, 5U, 0x64U, 0U) #define PA05_GPTIM1_CH2 SF32LB_PINMUX(PA, 5U, 5U, 0x64U, 1U) #define PA05_GPTIM1_CH3 SF32LB_PINMUX(PA, 5U, 5U, 0x64U, 2U) #define PA05_GPTIM1_CH4 SF32LB_PINMUX(PA, 5U, 5U, 0x64U, 3U) +#define PA05_GPTIM1_ETR SF32LB_PINMUX(PA, 5U, 5U, 0x6CU, 0U) #define PA05_GPTIM2_CH1 SF32LB_PINMUX(PA, 5U, 5U, 0x68U, 0U) #define PA05_GPTIM2_CH2 SF32LB_PINMUX(PA, 5U, 5U, 0x68U, 1U) #define PA05_GPTIM2_CH3 SF32LB_PINMUX(PA, 5U, 5U, 0x68U, 2U) #define PA05_GPTIM2_CH4 SF32LB_PINMUX(PA, 5U, 5U, 0x68U, 3U) -#define PA05_GPTIM1_ETR SF32LB_PINMUX(PA, 5U, 5U, 0x6CU, 0U) #define PA05_GPTIM2_ETR SF32LB_PINMUX(PA, 5U, 5U, 0x6CU, 1U) #define PA05_LPTIM1_IN SF32LB_PINMUX(PA, 5U, 5U, 0x70U, 0U) #define PA05_LPTIM1_OUT SF32LB_PINMUX(PA, 5U, 5U, 0x70U, 1U) @@ -347,10 +326,9 @@ #define PA05_ATIM1_CH1N SF32LB_PINMUX(PA, 5U, 5U, 0x7CU, 0U) #define PA05_ATIM1_CH2N SF32LB_PINMUX(PA, 5U, 5U, 0x7CU, 1U) #define PA05_ATIM1_CH3N SF32LB_PINMUX(PA, 5U, 5U, 0x7CU, 2U) +#define PA05_ATIM1_ETR SF32LB_PINMUX(PA, 5U, 5U, 0x80U, 2U) #define PA05_ATIM1_BK SF32LB_PINMUX(PA, 5U, 5U, 0x80U, 0U) #define PA05_ATIM1_BK2 SF32LB_PINMUX(PA, 5U, 5U, 0x80U, 1U) -#define PA05_ATIM1_ETR SF32LB_PINMUX(PA, 5U, 5U, 0x80U, 2U) -/* PA_TIM functions end */ #define PA05_LCDC1_JDI_R1 SF32LB_PINMUX(PA, 5U, 6U, 0U, 0U) #define PA05_LCDC1_8080_RD SF32LB_PINMUX(PA, 5U, 7U, 0U, 0U) @@ -359,38 +337,35 @@ #define PA06_GPIO SF32LB_PINMUX(PA, 6U, 0U, 0U, 0U) #define PA06_LCDC1_SPI_DIO1 SF32LB_PINMUX(PA, 6U, 1U, 0U, 0U) #define PA06_I2S1_LRCK SF32LB_PINMUX(PA, 6U, 3U, 0U, 0U) -/* PA_I2C_UART functions start */ -#define PA06_I2C1_SDA SF32LB_PINMUX(PA, 6U, 4U, 0x48U, 1U) #define PA06_I2C1_SCL SF32LB_PINMUX(PA, 6U, 4U, 0x48U, 0U) -#define PA06_I2C2_SDA SF32LB_PINMUX(PA, 6U, 4U, 0x4CU, 1U) +#define PA06_I2C1_SDA SF32LB_PINMUX(PA, 6U, 4U, 0x48U, 1U) #define PA06_I2C2_SCL SF32LB_PINMUX(PA, 6U, 4U, 0x4CU, 0U) -#define PA06_I2C3_SDA SF32LB_PINMUX(PA, 6U, 4U, 0x50U, 1U) +#define PA06_I2C2_SDA SF32LB_PINMUX(PA, 6U, 4U, 0x4CU, 1U) #define PA06_I2C3_SCL SF32LB_PINMUX(PA, 6U, 4U, 0x50U, 0U) -#define PA06_I2C4_SDA SF32LB_PINMUX(PA, 6U, 4U, 0x54U, 1U) +#define PA06_I2C3_SDA SF32LB_PINMUX(PA, 6U, 4U, 0x50U, 1U) #define PA06_I2C4_SCL SF32LB_PINMUX(PA, 6U, 4U, 0x54U, 0U) -#define PA06_USART1_CTS SF32LB_PINMUX(PA, 6U, 4U, 0x58U, 3U) -#define PA06_USART1_RTS SF32LB_PINMUX(PA, 6U, 4U, 0x58U, 2U) -#define PA06_USART1_RXD SF32LB_PINMUX(PA, 6U, 4U, 0x58U, 1U) +#define PA06_I2C4_SDA SF32LB_PINMUX(PA, 6U, 4U, 0x54U, 1U) #define PA06_USART1_TXD SF32LB_PINMUX(PA, 6U, 4U, 0x58U, 0U) -#define PA06_USART2_CTS SF32LB_PINMUX(PA, 6U, 4U, 0x5CU, 3U) -#define PA06_USART2_RTS SF32LB_PINMUX(PA, 6U, 4U, 0x5CU, 2U) -#define PA06_USART2_RXD SF32LB_PINMUX(PA, 6U, 4U, 0x5CU, 1U) +#define PA06_USART1_RXD SF32LB_PINMUX(PA, 6U, 4U, 0x58U, 1U) +#define PA06_USART1_RTS SF32LB_PINMUX(PA, 6U, 4U, 0x58U, 2U) +#define PA06_USART1_CTS SF32LB_PINMUX(PA, 6U, 4U, 0x58U, 3U) #define PA06_USART2_TXD SF32LB_PINMUX(PA, 6U, 4U, 0x5CU, 0U) -#define PA06_USART3_CTS SF32LB_PINMUX(PA, 6U, 4U, 0x60U, 3U) -#define PA06_USART3_RTS SF32LB_PINMUX(PA, 6U, 4U, 0x60U, 2U) -#define PA06_USART3_RXD SF32LB_PINMUX(PA, 6U, 4U, 0x60U, 1U) +#define PA06_USART2_RXD SF32LB_PINMUX(PA, 6U, 4U, 0x5CU, 1U) +#define PA06_USART2_RTS SF32LB_PINMUX(PA, 6U, 4U, 0x5CU, 2U) +#define PA06_USART2_CTS SF32LB_PINMUX(PA, 6U, 4U, 0x5CU, 3U) #define PA06_USART3_TXD SF32LB_PINMUX(PA, 6U, 4U, 0x60U, 0U) -/* PA_I2C_UART functions end */ -/* PA_TIM functions start */ +#define PA06_USART3_RXD SF32LB_PINMUX(PA, 6U, 4U, 0x60U, 1U) +#define PA06_USART3_RTS SF32LB_PINMUX(PA, 6U, 4U, 0x60U, 2U) +#define PA06_USART3_CTS SF32LB_PINMUX(PA, 6U, 4U, 0x60U, 3U) #define PA06_GPTIM1_CH1 SF32LB_PINMUX(PA, 6U, 5U, 0x64U, 0U) #define PA06_GPTIM1_CH2 SF32LB_PINMUX(PA, 6U, 5U, 0x64U, 1U) #define PA06_GPTIM1_CH3 SF32LB_PINMUX(PA, 6U, 5U, 0x64U, 2U) #define PA06_GPTIM1_CH4 SF32LB_PINMUX(PA, 6U, 5U, 0x64U, 3U) +#define PA06_GPTIM1_ETR SF32LB_PINMUX(PA, 6U, 5U, 0x6CU, 0U) #define PA06_GPTIM2_CH1 SF32LB_PINMUX(PA, 6U, 5U, 0x68U, 0U) #define PA06_GPTIM2_CH2 SF32LB_PINMUX(PA, 6U, 5U, 0x68U, 1U) #define PA06_GPTIM2_CH3 SF32LB_PINMUX(PA, 6U, 5U, 0x68U, 2U) #define PA06_GPTIM2_CH4 SF32LB_PINMUX(PA, 6U, 5U, 0x68U, 3U) -#define PA06_GPTIM1_ETR SF32LB_PINMUX(PA, 6U, 5U, 0x6CU, 0U) #define PA06_GPTIM2_ETR SF32LB_PINMUX(PA, 6U, 5U, 0x6CU, 1U) #define PA06_LPTIM1_IN SF32LB_PINMUX(PA, 6U, 5U, 0x70U, 0U) #define PA06_LPTIM1_OUT SF32LB_PINMUX(PA, 6U, 5U, 0x70U, 1U) @@ -405,10 +380,9 @@ #define PA06_ATIM1_CH1N SF32LB_PINMUX(PA, 6U, 5U, 0x7CU, 0U) #define PA06_ATIM1_CH2N SF32LB_PINMUX(PA, 6U, 5U, 0x7CU, 1U) #define PA06_ATIM1_CH3N SF32LB_PINMUX(PA, 6U, 5U, 0x7CU, 2U) +#define PA06_ATIM1_ETR SF32LB_PINMUX(PA, 6U, 5U, 0x80U, 2U) #define PA06_ATIM1_BK SF32LB_PINMUX(PA, 6U, 5U, 0x80U, 0U) #define PA06_ATIM1_BK2 SF32LB_PINMUX(PA, 6U, 5U, 0x80U, 1U) -#define PA06_ATIM1_ETR SF32LB_PINMUX(PA, 6U, 5U, 0x80U, 2U) -/* PA_TIM functions end */ #define PA06_LCDC1_JDI_HST SF32LB_PINMUX(PA, 6U, 6U, 0U, 0U) #define PA06_LCDC1_8080_DC SF32LB_PINMUX(PA, 6U, 7U, 0U, 0U) @@ -417,38 +391,35 @@ #define PA07_GPIO SF32LB_PINMUX(PA, 7U, 0U, 0U, 0U) #define PA07_LCDC1_SPI_DIO2 SF32LB_PINMUX(PA, 7U, 1U, 0U, 0U) #define PA07_PDM1_CLK SF32LB_PINMUX(PA, 7U, 3U, 0U, 0U) -/* PA_I2C_UART functions start */ -#define PA07_I2C1_SDA SF32LB_PINMUX(PA, 7U, 4U, 0x48U, 1U) #define PA07_I2C1_SCL SF32LB_PINMUX(PA, 7U, 4U, 0x48U, 0U) -#define PA07_I2C2_SDA SF32LB_PINMUX(PA, 7U, 4U, 0x4CU, 1U) +#define PA07_I2C1_SDA SF32LB_PINMUX(PA, 7U, 4U, 0x48U, 1U) #define PA07_I2C2_SCL SF32LB_PINMUX(PA, 7U, 4U, 0x4CU, 0U) -#define PA07_I2C3_SDA SF32LB_PINMUX(PA, 7U, 4U, 0x50U, 1U) +#define PA07_I2C2_SDA SF32LB_PINMUX(PA, 7U, 4U, 0x4CU, 1U) #define PA07_I2C3_SCL SF32LB_PINMUX(PA, 7U, 4U, 0x50U, 0U) -#define PA07_I2C4_SDA SF32LB_PINMUX(PA, 7U, 4U, 0x54U, 1U) +#define PA07_I2C3_SDA SF32LB_PINMUX(PA, 7U, 4U, 0x50U, 1U) #define PA07_I2C4_SCL SF32LB_PINMUX(PA, 7U, 4U, 0x54U, 0U) -#define PA07_USART1_CTS SF32LB_PINMUX(PA, 7U, 4U, 0x58U, 3U) -#define PA07_USART1_RTS SF32LB_PINMUX(PA, 7U, 4U, 0x58U, 2U) -#define PA07_USART1_RXD SF32LB_PINMUX(PA, 7U, 4U, 0x58U, 1U) +#define PA07_I2C4_SDA SF32LB_PINMUX(PA, 7U, 4U, 0x54U, 1U) #define PA07_USART1_TXD SF32LB_PINMUX(PA, 7U, 4U, 0x58U, 0U) -#define PA07_USART2_CTS SF32LB_PINMUX(PA, 7U, 4U, 0x5CU, 3U) -#define PA07_USART2_RTS SF32LB_PINMUX(PA, 7U, 4U, 0x5CU, 2U) -#define PA07_USART2_RXD SF32LB_PINMUX(PA, 7U, 4U, 0x5CU, 1U) +#define PA07_USART1_RXD SF32LB_PINMUX(PA, 7U, 4U, 0x58U, 1U) +#define PA07_USART1_RTS SF32LB_PINMUX(PA, 7U, 4U, 0x58U, 2U) +#define PA07_USART1_CTS SF32LB_PINMUX(PA, 7U, 4U, 0x58U, 3U) #define PA07_USART2_TXD SF32LB_PINMUX(PA, 7U, 4U, 0x5CU, 0U) -#define PA07_USART3_CTS SF32LB_PINMUX(PA, 7U, 4U, 0x60U, 3U) -#define PA07_USART3_RTS SF32LB_PINMUX(PA, 7U, 4U, 0x60U, 2U) -#define PA07_USART3_RXD SF32LB_PINMUX(PA, 7U, 4U, 0x60U, 1U) +#define PA07_USART2_RXD SF32LB_PINMUX(PA, 7U, 4U, 0x5CU, 1U) +#define PA07_USART2_RTS SF32LB_PINMUX(PA, 7U, 4U, 0x5CU, 2U) +#define PA07_USART2_CTS SF32LB_PINMUX(PA, 7U, 4U, 0x5CU, 3U) #define PA07_USART3_TXD SF32LB_PINMUX(PA, 7U, 4U, 0x60U, 0U) -/* PA_I2C_UART functions end */ -/* PA_TIM functions start */ +#define PA07_USART3_RXD SF32LB_PINMUX(PA, 7U, 4U, 0x60U, 1U) +#define PA07_USART3_RTS SF32LB_PINMUX(PA, 7U, 4U, 0x60U, 2U) +#define PA07_USART3_CTS SF32LB_PINMUX(PA, 7U, 4U, 0x60U, 3U) #define PA07_GPTIM1_CH1 SF32LB_PINMUX(PA, 7U, 5U, 0x64U, 0U) #define PA07_GPTIM1_CH2 SF32LB_PINMUX(PA, 7U, 5U, 0x64U, 1U) #define PA07_GPTIM1_CH3 SF32LB_PINMUX(PA, 7U, 5U, 0x64U, 2U) #define PA07_GPTIM1_CH4 SF32LB_PINMUX(PA, 7U, 5U, 0x64U, 3U) +#define PA07_GPTIM1_ETR SF32LB_PINMUX(PA, 7U, 5U, 0x6CU, 0U) #define PA07_GPTIM2_CH1 SF32LB_PINMUX(PA, 7U, 5U, 0x68U, 0U) #define PA07_GPTIM2_CH2 SF32LB_PINMUX(PA, 7U, 5U, 0x68U, 1U) #define PA07_GPTIM2_CH3 SF32LB_PINMUX(PA, 7U, 5U, 0x68U, 2U) #define PA07_GPTIM2_CH4 SF32LB_PINMUX(PA, 7U, 5U, 0x68U, 3U) -#define PA07_GPTIM1_ETR SF32LB_PINMUX(PA, 7U, 5U, 0x6CU, 0U) #define PA07_GPTIM2_ETR SF32LB_PINMUX(PA, 7U, 5U, 0x6CU, 1U) #define PA07_LPTIM1_IN SF32LB_PINMUX(PA, 7U, 5U, 0x70U, 0U) #define PA07_LPTIM1_OUT SF32LB_PINMUX(PA, 7U, 5U, 0x70U, 1U) @@ -463,10 +434,9 @@ #define PA07_ATIM1_CH1N SF32LB_PINMUX(PA, 7U, 5U, 0x7CU, 0U) #define PA07_ATIM1_CH2N SF32LB_PINMUX(PA, 7U, 5U, 0x7CU, 1U) #define PA07_ATIM1_CH3N SF32LB_PINMUX(PA, 7U, 5U, 0x7CU, 2U) +#define PA07_ATIM1_ETR SF32LB_PINMUX(PA, 7U, 5U, 0x80U, 2U) #define PA07_ATIM1_BK SF32LB_PINMUX(PA, 7U, 5U, 0x80U, 0U) #define PA07_ATIM1_BK2 SF32LB_PINMUX(PA, 7U, 5U, 0x80U, 1U) -#define PA07_ATIM1_ETR SF32LB_PINMUX(PA, 7U, 5U, 0x80U, 2U) -/* PA_TIM functions end */ #define PA07_LCDC1_JDI_ENB SF32LB_PINMUX(PA, 7U, 6U, 0U, 0U) #define PA07_LCDC1_8080_DIO0 SF32LB_PINMUX(PA, 7U, 7U, 0U, 0U) @@ -475,38 +445,35 @@ #define PA08_GPIO SF32LB_PINMUX(PA, 8U, 0U, 0U, 0U) #define PA08_LCDC1_SPI_DIO3 SF32LB_PINMUX(PA, 8U, 1U, 0U, 0U) #define PA08_PDM1_DATA SF32LB_PINMUX(PA, 8U, 3U, 0U, 0U) -/* PA_I2C_UART functions start */ -#define PA08_I2C1_SDA SF32LB_PINMUX(PA, 8U, 4U, 0x48U, 1U) #define PA08_I2C1_SCL SF32LB_PINMUX(PA, 8U, 4U, 0x48U, 0U) -#define PA08_I2C2_SDA SF32LB_PINMUX(PA, 8U, 4U, 0x4CU, 1U) +#define PA08_I2C1_SDA SF32LB_PINMUX(PA, 8U, 4U, 0x48U, 1U) #define PA08_I2C2_SCL SF32LB_PINMUX(PA, 8U, 4U, 0x4CU, 0U) -#define PA08_I2C3_SDA SF32LB_PINMUX(PA, 8U, 4U, 0x50U, 1U) +#define PA08_I2C2_SDA SF32LB_PINMUX(PA, 8U, 4U, 0x4CU, 1U) #define PA08_I2C3_SCL SF32LB_PINMUX(PA, 8U, 4U, 0x50U, 0U) -#define PA08_I2C4_SDA SF32LB_PINMUX(PA, 8U, 4U, 0x54U, 1U) +#define PA08_I2C3_SDA SF32LB_PINMUX(PA, 8U, 4U, 0x50U, 1U) #define PA08_I2C4_SCL SF32LB_PINMUX(PA, 8U, 4U, 0x54U, 0U) -#define PA08_USART1_CTS SF32LB_PINMUX(PA, 8U, 4U, 0x58U, 3U) -#define PA08_USART1_RTS SF32LB_PINMUX(PA, 8U, 4U, 0x58U, 2U) -#define PA08_USART1_RXD SF32LB_PINMUX(PA, 8U, 4U, 0x58U, 1U) +#define PA08_I2C4_SDA SF32LB_PINMUX(PA, 8U, 4U, 0x54U, 1U) #define PA08_USART1_TXD SF32LB_PINMUX(PA, 8U, 4U, 0x58U, 0U) -#define PA08_USART2_CTS SF32LB_PINMUX(PA, 8U, 4U, 0x5CU, 3U) -#define PA08_USART2_RTS SF32LB_PINMUX(PA, 8U, 4U, 0x5CU, 2U) -#define PA08_USART2_RXD SF32LB_PINMUX(PA, 8U, 4U, 0x5CU, 1U) +#define PA08_USART1_RXD SF32LB_PINMUX(PA, 8U, 4U, 0x58U, 1U) +#define PA08_USART1_RTS SF32LB_PINMUX(PA, 8U, 4U, 0x58U, 2U) +#define PA08_USART1_CTS SF32LB_PINMUX(PA, 8U, 4U, 0x58U, 3U) #define PA08_USART2_TXD SF32LB_PINMUX(PA, 8U, 4U, 0x5CU, 0U) -#define PA08_USART3_CTS SF32LB_PINMUX(PA, 8U, 4U, 0x60U, 3U) -#define PA08_USART3_RTS SF32LB_PINMUX(PA, 8U, 4U, 0x60U, 2U) -#define PA08_USART3_RXD SF32LB_PINMUX(PA, 8U, 4U, 0x60U, 1U) +#define PA08_USART2_RXD SF32LB_PINMUX(PA, 8U, 4U, 0x5CU, 1U) +#define PA08_USART2_RTS SF32LB_PINMUX(PA, 8U, 4U, 0x5CU, 2U) +#define PA08_USART2_CTS SF32LB_PINMUX(PA, 8U, 4U, 0x5CU, 3U) #define PA08_USART3_TXD SF32LB_PINMUX(PA, 8U, 4U, 0x60U, 0U) -/* PA_I2C_UART functions end */ -/* PA_TIM functions start */ +#define PA08_USART3_RXD SF32LB_PINMUX(PA, 8U, 4U, 0x60U, 1U) +#define PA08_USART3_RTS SF32LB_PINMUX(PA, 8U, 4U, 0x60U, 2U) +#define PA08_USART3_CTS SF32LB_PINMUX(PA, 8U, 4U, 0x60U, 3U) #define PA08_GPTIM1_CH1 SF32LB_PINMUX(PA, 8U, 5U, 0x64U, 0U) #define PA08_GPTIM1_CH2 SF32LB_PINMUX(PA, 8U, 5U, 0x64U, 1U) #define PA08_GPTIM1_CH3 SF32LB_PINMUX(PA, 8U, 5U, 0x64U, 2U) #define PA08_GPTIM1_CH4 SF32LB_PINMUX(PA, 8U, 5U, 0x64U, 3U) +#define PA08_GPTIM1_ETR SF32LB_PINMUX(PA, 8U, 5U, 0x6CU, 0U) #define PA08_GPTIM2_CH1 SF32LB_PINMUX(PA, 8U, 5U, 0x68U, 0U) #define PA08_GPTIM2_CH2 SF32LB_PINMUX(PA, 8U, 5U, 0x68U, 1U) #define PA08_GPTIM2_CH3 SF32LB_PINMUX(PA, 8U, 5U, 0x68U, 2U) #define PA08_GPTIM2_CH4 SF32LB_PINMUX(PA, 8U, 5U, 0x68U, 3U) -#define PA08_GPTIM1_ETR SF32LB_PINMUX(PA, 8U, 5U, 0x6CU, 0U) #define PA08_GPTIM2_ETR SF32LB_PINMUX(PA, 8U, 5U, 0x6CU, 1U) #define PA08_LPTIM1_IN SF32LB_PINMUX(PA, 8U, 5U, 0x70U, 0U) #define PA08_LPTIM1_OUT SF32LB_PINMUX(PA, 8U, 5U, 0x70U, 1U) @@ -521,48 +488,44 @@ #define PA08_ATIM1_CH1N SF32LB_PINMUX(PA, 8U, 5U, 0x7CU, 0U) #define PA08_ATIM1_CH2N SF32LB_PINMUX(PA, 8U, 5U, 0x7CU, 1U) #define PA08_ATIM1_CH3N SF32LB_PINMUX(PA, 8U, 5U, 0x7CU, 2U) +#define PA08_ATIM1_ETR SF32LB_PINMUX(PA, 8U, 5U, 0x80U, 2U) #define PA08_ATIM1_BK SF32LB_PINMUX(PA, 8U, 5U, 0x80U, 0U) #define PA08_ATIM1_BK2 SF32LB_PINMUX(PA, 8U, 5U, 0x80U, 1U) -#define PA08_ATIM1_ETR SF32LB_PINMUX(PA, 8U, 5U, 0x80U, 2U) -/* PA_TIM functions end */ #define PA08_LCDC1_JDI_VST SF32LB_PINMUX(PA, 8U, 6U, 0U, 0U) #define PA08_LCDC1_8080_DIO1 SF32LB_PINMUX(PA, 8U, 7U, 0U, 0U) /* PA09 */ #define PA09_ANALOG SF32LB_PINMUX_ANALOG(PA, 9U) #define PA09_GPIO SF32LB_PINMUX(PA, 9U, 0U, 0U, 0U) -/* PA_I2C_UART functions start */ -#define PA09_I2C1_SDA SF32LB_PINMUX(PA, 9U, 4U, 0x48U, 1U) #define PA09_I2C1_SCL SF32LB_PINMUX(PA, 9U, 4U, 0x48U, 0U) -#define PA09_I2C2_SDA SF32LB_PINMUX(PA, 9U, 4U, 0x4CU, 1U) +#define PA09_I2C1_SDA SF32LB_PINMUX(PA, 9U, 4U, 0x48U, 1U) #define PA09_I2C2_SCL SF32LB_PINMUX(PA, 9U, 4U, 0x4CU, 0U) -#define PA09_I2C3_SDA SF32LB_PINMUX(PA, 9U, 4U, 0x50U, 1U) +#define PA09_I2C2_SDA SF32LB_PINMUX(PA, 9U, 4U, 0x4CU, 1U) #define PA09_I2C3_SCL SF32LB_PINMUX(PA, 9U, 4U, 0x50U, 0U) -#define PA09_I2C4_SDA SF32LB_PINMUX(PA, 9U, 4U, 0x54U, 1U) +#define PA09_I2C3_SDA SF32LB_PINMUX(PA, 9U, 4U, 0x50U, 1U) #define PA09_I2C4_SCL SF32LB_PINMUX(PA, 9U, 4U, 0x54U, 0U) -#define PA09_USART1_CTS SF32LB_PINMUX(PA, 9U, 4U, 0x58U, 3U) -#define PA09_USART1_RTS SF32LB_PINMUX(PA, 9U, 4U, 0x58U, 2U) -#define PA09_USART1_RXD SF32LB_PINMUX(PA, 9U, 4U, 0x58U, 1U) +#define PA09_I2C4_SDA SF32LB_PINMUX(PA, 9U, 4U, 0x54U, 1U) #define PA09_USART1_TXD SF32LB_PINMUX(PA, 9U, 4U, 0x58U, 0U) -#define PA09_USART2_CTS SF32LB_PINMUX(PA, 9U, 4U, 0x5CU, 3U) -#define PA09_USART2_RTS SF32LB_PINMUX(PA, 9U, 4U, 0x5CU, 2U) -#define PA09_USART2_RXD SF32LB_PINMUX(PA, 9U, 4U, 0x5CU, 1U) +#define PA09_USART1_RXD SF32LB_PINMUX(PA, 9U, 4U, 0x58U, 1U) +#define PA09_USART1_RTS SF32LB_PINMUX(PA, 9U, 4U, 0x58U, 2U) +#define PA09_USART1_CTS SF32LB_PINMUX(PA, 9U, 4U, 0x58U, 3U) #define PA09_USART2_TXD SF32LB_PINMUX(PA, 9U, 4U, 0x5CU, 0U) -#define PA09_USART3_CTS SF32LB_PINMUX(PA, 9U, 4U, 0x60U, 3U) -#define PA09_USART3_RTS SF32LB_PINMUX(PA, 9U, 4U, 0x60U, 2U) -#define PA09_USART3_RXD SF32LB_PINMUX(PA, 9U, 4U, 0x60U, 1U) +#define PA09_USART2_RXD SF32LB_PINMUX(PA, 9U, 4U, 0x5CU, 1U) +#define PA09_USART2_RTS SF32LB_PINMUX(PA, 9U, 4U, 0x5CU, 2U) +#define PA09_USART2_CTS SF32LB_PINMUX(PA, 9U, 4U, 0x5CU, 3U) #define PA09_USART3_TXD SF32LB_PINMUX(PA, 9U, 4U, 0x60U, 0U) -/* PA_I2C_UART functions end */ -/* PA_TIM functions start */ +#define PA09_USART3_RXD SF32LB_PINMUX(PA, 9U, 4U, 0x60U, 1U) +#define PA09_USART3_RTS SF32LB_PINMUX(PA, 9U, 4U, 0x60U, 2U) +#define PA09_USART3_CTS SF32LB_PINMUX(PA, 9U, 4U, 0x60U, 3U) #define PA09_GPTIM1_CH1 SF32LB_PINMUX(PA, 9U, 5U, 0x64U, 0U) #define PA09_GPTIM1_CH2 SF32LB_PINMUX(PA, 9U, 5U, 0x64U, 1U) #define PA09_GPTIM1_CH3 SF32LB_PINMUX(PA, 9U, 5U, 0x64U, 2U) #define PA09_GPTIM1_CH4 SF32LB_PINMUX(PA, 9U, 5U, 0x64U, 3U) +#define PA09_GPTIM1_ETR SF32LB_PINMUX(PA, 9U, 5U, 0x6CU, 0U) #define PA09_GPTIM2_CH1 SF32LB_PINMUX(PA, 9U, 5U, 0x68U, 0U) #define PA09_GPTIM2_CH2 SF32LB_PINMUX(PA, 9U, 5U, 0x68U, 1U) #define PA09_GPTIM2_CH3 SF32LB_PINMUX(PA, 9U, 5U, 0x68U, 2U) #define PA09_GPTIM2_CH4 SF32LB_PINMUX(PA, 9U, 5U, 0x68U, 3U) -#define PA09_GPTIM1_ETR SF32LB_PINMUX(PA, 9U, 5U, 0x6CU, 0U) #define PA09_GPTIM2_ETR SF32LB_PINMUX(PA, 9U, 5U, 0x6CU, 1U) #define PA09_LPTIM1_IN SF32LB_PINMUX(PA, 9U, 5U, 0x70U, 0U) #define PA09_LPTIM1_OUT SF32LB_PINMUX(PA, 9U, 5U, 0x70U, 1U) @@ -577,46 +540,42 @@ #define PA09_ATIM1_CH1N SF32LB_PINMUX(PA, 9U, 5U, 0x7CU, 0U) #define PA09_ATIM1_CH2N SF32LB_PINMUX(PA, 9U, 5U, 0x7CU, 1U) #define PA09_ATIM1_CH3N SF32LB_PINMUX(PA, 9U, 5U, 0x7CU, 2U) +#define PA09_ATIM1_ETR SF32LB_PINMUX(PA, 9U, 5U, 0x80U, 2U) #define PA09_ATIM1_BK SF32LB_PINMUX(PA, 9U, 5U, 0x80U, 0U) #define PA09_ATIM1_BK2 SF32LB_PINMUX(PA, 9U, 5U, 0x80U, 1U) -#define PA09_ATIM1_ETR SF32LB_PINMUX(PA, 9U, 5U, 0x80U, 2U) -/* PA_TIM functions end */ /* PA10 */ #define PA10_ANALOG SF32LB_PINMUX_ANALOG(PA, 10U) #define PA10_GPIO SF32LB_PINMUX(PA, 10U, 0U, 0U, 0U) -/* PA_I2C_UART functions start */ -#define PA10_I2C1_SDA SF32LB_PINMUX(PA, 10U, 4U, 0x48U, 1U) #define PA10_I2C1_SCL SF32LB_PINMUX(PA, 10U, 4U, 0x48U, 0U) -#define PA10_I2C2_SDA SF32LB_PINMUX(PA, 10U, 4U, 0x4CU, 1U) +#define PA10_I2C1_SDA SF32LB_PINMUX(PA, 10U, 4U, 0x48U, 1U) #define PA10_I2C2_SCL SF32LB_PINMUX(PA, 10U, 4U, 0x4CU, 0U) -#define PA10_I2C3_SDA SF32LB_PINMUX(PA, 10U, 4U, 0x50U, 1U) +#define PA10_I2C2_SDA SF32LB_PINMUX(PA, 10U, 4U, 0x4CU, 1U) #define PA10_I2C3_SCL SF32LB_PINMUX(PA, 10U, 4U, 0x50U, 0U) -#define PA10_I2C4_SDA SF32LB_PINMUX(PA, 10U, 4U, 0x54U, 1U) +#define PA10_I2C3_SDA SF32LB_PINMUX(PA, 10U, 4U, 0x50U, 1U) #define PA10_I2C4_SCL SF32LB_PINMUX(PA, 10U, 4U, 0x54U, 0U) -#define PA10_USART1_CTS SF32LB_PINMUX(PA, 10U, 4U, 0x58U, 3U) -#define PA10_USART1_RTS SF32LB_PINMUX(PA, 10U, 4U, 0x58U, 2U) -#define PA10_USART1_RXD SF32LB_PINMUX(PA, 10U, 4U, 0x58U, 1U) +#define PA10_I2C4_SDA SF32LB_PINMUX(PA, 10U, 4U, 0x54U, 1U) #define PA10_USART1_TXD SF32LB_PINMUX(PA, 10U, 4U, 0x58U, 0U) -#define PA10_USART2_CTS SF32LB_PINMUX(PA, 10U, 4U, 0x5CU, 3U) -#define PA10_USART2_RTS SF32LB_PINMUX(PA, 10U, 4U, 0x5CU, 2U) -#define PA10_USART2_RXD SF32LB_PINMUX(PA, 10U, 4U, 0x5CU, 1U) +#define PA10_USART1_RXD SF32LB_PINMUX(PA, 10U, 4U, 0x58U, 1U) +#define PA10_USART1_RTS SF32LB_PINMUX(PA, 10U, 4U, 0x58U, 2U) +#define PA10_USART1_CTS SF32LB_PINMUX(PA, 10U, 4U, 0x58U, 3U) #define PA10_USART2_TXD SF32LB_PINMUX(PA, 10U, 4U, 0x5CU, 0U) -#define PA10_USART3_CTS SF32LB_PINMUX(PA, 10U, 4U, 0x60U, 3U) -#define PA10_USART3_RTS SF32LB_PINMUX(PA, 10U, 4U, 0x60U, 2U) -#define PA10_USART3_RXD SF32LB_PINMUX(PA, 10U, 4U, 0x60U, 1U) +#define PA10_USART2_RXD SF32LB_PINMUX(PA, 10U, 4U, 0x5CU, 1U) +#define PA10_USART2_RTS SF32LB_PINMUX(PA, 10U, 4U, 0x5CU, 2U) +#define PA10_USART2_CTS SF32LB_PINMUX(PA, 10U, 4U, 0x5CU, 3U) #define PA10_USART3_TXD SF32LB_PINMUX(PA, 10U, 4U, 0x60U, 0U) -/* PA_I2C_UART functions end */ -/* PA_TIM functions start */ +#define PA10_USART3_RXD SF32LB_PINMUX(PA, 10U, 4U, 0x60U, 1U) +#define PA10_USART3_RTS SF32LB_PINMUX(PA, 10U, 4U, 0x60U, 2U) +#define PA10_USART3_CTS SF32LB_PINMUX(PA, 10U, 4U, 0x60U, 3U) #define PA10_GPTIM1_CH1 SF32LB_PINMUX(PA, 10U, 5U, 0x64U, 0U) #define PA10_GPTIM1_CH2 SF32LB_PINMUX(PA, 10U, 5U, 0x64U, 1U) #define PA10_GPTIM1_CH3 SF32LB_PINMUX(PA, 10U, 5U, 0x64U, 2U) #define PA10_GPTIM1_CH4 SF32LB_PINMUX(PA, 10U, 5U, 0x64U, 3U) +#define PA10_GPTIM1_ETR SF32LB_PINMUX(PA, 10U, 5U, 0x6CU, 0U) #define PA10_GPTIM2_CH1 SF32LB_PINMUX(PA, 10U, 5U, 0x68U, 0U) #define PA10_GPTIM2_CH2 SF32LB_PINMUX(PA, 10U, 5U, 0x68U, 1U) #define PA10_GPTIM2_CH3 SF32LB_PINMUX(PA, 10U, 5U, 0x68U, 2U) #define PA10_GPTIM2_CH4 SF32LB_PINMUX(PA, 10U, 5U, 0x68U, 3U) -#define PA10_GPTIM1_ETR SF32LB_PINMUX(PA, 10U, 5U, 0x6CU, 0U) #define PA10_GPTIM2_ETR SF32LB_PINMUX(PA, 10U, 5U, 0x6CU, 1U) #define PA10_LPTIM1_IN SF32LB_PINMUX(PA, 10U, 5U, 0x70U, 0U) #define PA10_LPTIM1_OUT SF32LB_PINMUX(PA, 10U, 5U, 0x70U, 1U) @@ -631,46 +590,42 @@ #define PA10_ATIM1_CH1N SF32LB_PINMUX(PA, 10U, 5U, 0x7CU, 0U) #define PA10_ATIM1_CH2N SF32LB_PINMUX(PA, 10U, 5U, 0x7CU, 1U) #define PA10_ATIM1_CH3N SF32LB_PINMUX(PA, 10U, 5U, 0x7CU, 2U) +#define PA10_ATIM1_ETR SF32LB_PINMUX(PA, 10U, 5U, 0x80U, 2U) #define PA10_ATIM1_BK SF32LB_PINMUX(PA, 10U, 5U, 0x80U, 0U) #define PA10_ATIM1_BK2 SF32LB_PINMUX(PA, 10U, 5U, 0x80U, 1U) -#define PA10_ATIM1_ETR SF32LB_PINMUX(PA, 10U, 5U, 0x80U, 2U) -/* PA_TIM functions end */ /* PA11 */ #define PA11_ANALOG SF32LB_PINMUX_ANALOG(PA, 11U) #define PA11_GPIO SF32LB_PINMUX(PA, 11U, 0U, 0U, 0U) -/* PA_I2C_UART functions start */ -#define PA11_I2C1_SDA SF32LB_PINMUX(PA, 11U, 4U, 0x48U, 1U) #define PA11_I2C1_SCL SF32LB_PINMUX(PA, 11U, 4U, 0x48U, 0U) -#define PA11_I2C2_SDA SF32LB_PINMUX(PA, 11U, 4U, 0x4CU, 1U) +#define PA11_I2C1_SDA SF32LB_PINMUX(PA, 11U, 4U, 0x48U, 1U) #define PA11_I2C2_SCL SF32LB_PINMUX(PA, 11U, 4U, 0x4CU, 0U) -#define PA11_I2C3_SDA SF32LB_PINMUX(PA, 11U, 4U, 0x50U, 1U) +#define PA11_I2C2_SDA SF32LB_PINMUX(PA, 11U, 4U, 0x4CU, 1U) #define PA11_I2C3_SCL SF32LB_PINMUX(PA, 11U, 4U, 0x50U, 0U) -#define PA11_I2C4_SDA SF32LB_PINMUX(PA, 11U, 4U, 0x54U, 1U) +#define PA11_I2C3_SDA SF32LB_PINMUX(PA, 11U, 4U, 0x50U, 1U) #define PA11_I2C4_SCL SF32LB_PINMUX(PA, 11U, 4U, 0x54U, 0U) -#define PA11_USART1_CTS SF32LB_PINMUX(PA, 11U, 4U, 0x58U, 3U) -#define PA11_USART1_RTS SF32LB_PINMUX(PA, 11U, 4U, 0x58U, 2U) -#define PA11_USART1_RXD SF32LB_PINMUX(PA, 11U, 4U, 0x58U, 1U) +#define PA11_I2C4_SDA SF32LB_PINMUX(PA, 11U, 4U, 0x54U, 1U) #define PA11_USART1_TXD SF32LB_PINMUX(PA, 11U, 4U, 0x58U, 0U) -#define PA11_USART2_CTS SF32LB_PINMUX(PA, 11U, 4U, 0x5CU, 3U) -#define PA11_USART2_RTS SF32LB_PINMUX(PA, 11U, 4U, 0x5CU, 2U) -#define PA11_USART2_RXD SF32LB_PINMUX(PA, 11U, 4U, 0x5CU, 1U) +#define PA11_USART1_RXD SF32LB_PINMUX(PA, 11U, 4U, 0x58U, 1U) +#define PA11_USART1_RTS SF32LB_PINMUX(PA, 11U, 4U, 0x58U, 2U) +#define PA11_USART1_CTS SF32LB_PINMUX(PA, 11U, 4U, 0x58U, 3U) #define PA11_USART2_TXD SF32LB_PINMUX(PA, 11U, 4U, 0x5CU, 0U) -#define PA11_USART3_CTS SF32LB_PINMUX(PA, 11U, 4U, 0x60U, 3U) -#define PA11_USART3_RTS SF32LB_PINMUX(PA, 11U, 4U, 0x60U, 2U) -#define PA11_USART3_RXD SF32LB_PINMUX(PA, 11U, 4U, 0x60U, 1U) +#define PA11_USART2_RXD SF32LB_PINMUX(PA, 11U, 4U, 0x5CU, 1U) +#define PA11_USART2_RTS SF32LB_PINMUX(PA, 11U, 4U, 0x5CU, 2U) +#define PA11_USART2_CTS SF32LB_PINMUX(PA, 11U, 4U, 0x5CU, 3U) #define PA11_USART3_TXD SF32LB_PINMUX(PA, 11U, 4U, 0x60U, 0U) -/* PA_I2C_UART functions end */ -/* PA_TIM functions start */ +#define PA11_USART3_RXD SF32LB_PINMUX(PA, 11U, 4U, 0x60U, 1U) +#define PA11_USART3_RTS SF32LB_PINMUX(PA, 11U, 4U, 0x60U, 2U) +#define PA11_USART3_CTS SF32LB_PINMUX(PA, 11U, 4U, 0x60U, 3U) #define PA11_GPTIM1_CH1 SF32LB_PINMUX(PA, 11U, 5U, 0x64U, 0U) #define PA11_GPTIM1_CH2 SF32LB_PINMUX(PA, 11U, 5U, 0x64U, 1U) #define PA11_GPTIM1_CH3 SF32LB_PINMUX(PA, 11U, 5U, 0x64U, 2U) #define PA11_GPTIM1_CH4 SF32LB_PINMUX(PA, 11U, 5U, 0x64U, 3U) +#define PA11_GPTIM1_ETR SF32LB_PINMUX(PA, 11U, 5U, 0x6CU, 0U) #define PA11_GPTIM2_CH1 SF32LB_PINMUX(PA, 11U, 5U, 0x68U, 0U) #define PA11_GPTIM2_CH2 SF32LB_PINMUX(PA, 11U, 5U, 0x68U, 1U) #define PA11_GPTIM2_CH3 SF32LB_PINMUX(PA, 11U, 5U, 0x68U, 2U) #define PA11_GPTIM2_CH4 SF32LB_PINMUX(PA, 11U, 5U, 0x68U, 3U) -#define PA11_GPTIM1_ETR SF32LB_PINMUX(PA, 11U, 5U, 0x6CU, 0U) #define PA11_GPTIM2_ETR SF32LB_PINMUX(PA, 11U, 5U, 0x6CU, 1U) #define PA11_LPTIM1_IN SF32LB_PINMUX(PA, 11U, 5U, 0x70U, 0U) #define PA11_LPTIM1_OUT SF32LB_PINMUX(PA, 11U, 5U, 0x70U, 1U) @@ -685,48 +640,44 @@ #define PA11_ATIM1_CH1N SF32LB_PINMUX(PA, 11U, 5U, 0x7CU, 0U) #define PA11_ATIM1_CH2N SF32LB_PINMUX(PA, 11U, 5U, 0x7CU, 1U) #define PA11_ATIM1_CH3N SF32LB_PINMUX(PA, 11U, 5U, 0x7CU, 2U) +#define PA11_ATIM1_ETR SF32LB_PINMUX(PA, 11U, 5U, 0x80U, 2U) #define PA11_ATIM1_BK SF32LB_PINMUX(PA, 11U, 5U, 0x80U, 0U) #define PA11_ATIM1_BK2 SF32LB_PINMUX(PA, 11U, 5U, 0x80U, 1U) -#define PA11_ATIM1_ETR SF32LB_PINMUX(PA, 11U, 5U, 0x80U, 2U) -/* PA_TIM functions end */ /* PA12 */ #define PA12_ANALOG SF32LB_PINMUX_ANALOG(PA, 12U) #define PA12_GPIO SF32LB_PINMUX(PA, 12U, 0U, 0U, 0U) #define PA12_MPI2_CS SF32LB_PINMUX(PA, 12U, 1U, 0U, 0U) #define PA12_SD1_DIO2 SF32LB_PINMUX(PA, 12U, 2U, 0U, 0U) -/* PA_I2C_UART functions start */ -#define PA12_I2C1_SDA SF32LB_PINMUX(PA, 12U, 4U, 0x48U, 1U) #define PA12_I2C1_SCL SF32LB_PINMUX(PA, 12U, 4U, 0x48U, 0U) -#define PA12_I2C2_SDA SF32LB_PINMUX(PA, 12U, 4U, 0x4CU, 1U) +#define PA12_I2C1_SDA SF32LB_PINMUX(PA, 12U, 4U, 0x48U, 1U) #define PA12_I2C2_SCL SF32LB_PINMUX(PA, 12U, 4U, 0x4CU, 0U) -#define PA12_I2C3_SDA SF32LB_PINMUX(PA, 12U, 4U, 0x50U, 1U) +#define PA12_I2C2_SDA SF32LB_PINMUX(PA, 12U, 4U, 0x4CU, 1U) #define PA12_I2C3_SCL SF32LB_PINMUX(PA, 12U, 4U, 0x50U, 0U) -#define PA12_I2C4_SDA SF32LB_PINMUX(PA, 12U, 4U, 0x54U, 1U) +#define PA12_I2C3_SDA SF32LB_PINMUX(PA, 12U, 4U, 0x50U, 1U) #define PA12_I2C4_SCL SF32LB_PINMUX(PA, 12U, 4U, 0x54U, 0U) -#define PA12_USART1_CTS SF32LB_PINMUX(PA, 12U, 4U, 0x58U, 3U) -#define PA12_USART1_RTS SF32LB_PINMUX(PA, 12U, 4U, 0x58U, 2U) -#define PA12_USART1_RXD SF32LB_PINMUX(PA, 12U, 4U, 0x58U, 1U) -#define PA12_USART1_TXD SF32LB_PINMUX(PA, 12U, 4U, 0x58U, 0U) -#define PA12_USART2_CTS SF32LB_PINMUX(PA, 12U, 4U, 0x5CU, 3U) -#define PA12_USART2_RTS SF32LB_PINMUX(PA, 12U, 4U, 0x5CU, 2U) -#define PA12_USART2_RXD SF32LB_PINMUX(PA, 12U, 4U, 0x5CU, 1U) +#define PA12_I2C4_SDA SF32LB_PINMUX(PA, 12U, 4U, 0x54U, 1U) +#define PA12_USART1_TXD SF32LB_PINMUX(PA, 12U, 4U, 0x58U, 0U) +#define PA12_USART1_RXD SF32LB_PINMUX(PA, 12U, 4U, 0x58U, 1U) +#define PA12_USART1_RTS SF32LB_PINMUX(PA, 12U, 4U, 0x58U, 2U) +#define PA12_USART1_CTS SF32LB_PINMUX(PA, 12U, 4U, 0x58U, 3U) #define PA12_USART2_TXD SF32LB_PINMUX(PA, 12U, 4U, 0x5CU, 0U) -#define PA12_USART3_CTS SF32LB_PINMUX(PA, 12U, 4U, 0x60U, 3U) -#define PA12_USART3_RTS SF32LB_PINMUX(PA, 12U, 4U, 0x60U, 2U) -#define PA12_USART3_RXD SF32LB_PINMUX(PA, 12U, 4U, 0x60U, 1U) +#define PA12_USART2_RXD SF32LB_PINMUX(PA, 12U, 4U, 0x5CU, 1U) +#define PA12_USART2_RTS SF32LB_PINMUX(PA, 12U, 4U, 0x5CU, 2U) +#define PA12_USART2_CTS SF32LB_PINMUX(PA, 12U, 4U, 0x5CU, 3U) #define PA12_USART3_TXD SF32LB_PINMUX(PA, 12U, 4U, 0x60U, 0U) -/* PA_I2C_UART functions end */ -/* PA_TIM functions start */ +#define PA12_USART3_RXD SF32LB_PINMUX(PA, 12U, 4U, 0x60U, 1U) +#define PA12_USART3_RTS SF32LB_PINMUX(PA, 12U, 4U, 0x60U, 2U) +#define PA12_USART3_CTS SF32LB_PINMUX(PA, 12U, 4U, 0x60U, 3U) #define PA12_GPTIM1_CH1 SF32LB_PINMUX(PA, 12U, 5U, 0x64U, 0U) #define PA12_GPTIM1_CH2 SF32LB_PINMUX(PA, 12U, 5U, 0x64U, 1U) #define PA12_GPTIM1_CH3 SF32LB_PINMUX(PA, 12U, 5U, 0x64U, 2U) #define PA12_GPTIM1_CH4 SF32LB_PINMUX(PA, 12U, 5U, 0x64U, 3U) +#define PA12_GPTIM1_ETR SF32LB_PINMUX(PA, 12U, 5U, 0x6CU, 0U) #define PA12_GPTIM2_CH1 SF32LB_PINMUX(PA, 12U, 5U, 0x68U, 0U) #define PA12_GPTIM2_CH2 SF32LB_PINMUX(PA, 12U, 5U, 0x68U, 1U) #define PA12_GPTIM2_CH3 SF32LB_PINMUX(PA, 12U, 5U, 0x68U, 2U) #define PA12_GPTIM2_CH4 SF32LB_PINMUX(PA, 12U, 5U, 0x68U, 3U) -#define PA12_GPTIM1_ETR SF32LB_PINMUX(PA, 12U, 5U, 0x6CU, 0U) #define PA12_GPTIM2_ETR SF32LB_PINMUX(PA, 12U, 5U, 0x6CU, 1U) #define PA12_LPTIM1_IN SF32LB_PINMUX(PA, 12U, 5U, 0x70U, 0U) #define PA12_LPTIM1_OUT SF32LB_PINMUX(PA, 12U, 5U, 0x70U, 1U) @@ -741,48 +692,44 @@ #define PA12_ATIM1_CH1N SF32LB_PINMUX(PA, 12U, 5U, 0x7CU, 0U) #define PA12_ATIM1_CH2N SF32LB_PINMUX(PA, 12U, 5U, 0x7CU, 1U) #define PA12_ATIM1_CH3N SF32LB_PINMUX(PA, 12U, 5U, 0x7CU, 2U) +#define PA12_ATIM1_ETR SF32LB_PINMUX(PA, 12U, 5U, 0x80U, 2U) #define PA12_ATIM1_BK SF32LB_PINMUX(PA, 12U, 5U, 0x80U, 0U) #define PA12_ATIM1_BK2 SF32LB_PINMUX(PA, 12U, 5U, 0x80U, 1U) -#define PA12_ATIM1_ETR SF32LB_PINMUX(PA, 12U, 5U, 0x80U, 2U) -/* PA_TIM functions end */ /* PA13 */ #define PA13_ANALOG SF32LB_PINMUX_ANALOG(PA, 13U) #define PA13_GPIO SF32LB_PINMUX(PA, 13U, 0U, 0U, 0U) #define PA13_MPI2_DIO1 SF32LB_PINMUX(PA, 13U, 1U, 0U, 0U) #define PA13_SD1_DIO3 SF32LB_PINMUX(PA, 13U, 2U, 0U, 0U) -/* PA_I2C_UART functions start */ -#define PA13_I2C1_SDA SF32LB_PINMUX(PA, 13U, 4U, 0x48U, 1U) #define PA13_I2C1_SCL SF32LB_PINMUX(PA, 13U, 4U, 0x48U, 0U) -#define PA13_I2C2_SDA SF32LB_PINMUX(PA, 13U, 4U, 0x4CU, 1U) +#define PA13_I2C1_SDA SF32LB_PINMUX(PA, 13U, 4U, 0x48U, 1U) #define PA13_I2C2_SCL SF32LB_PINMUX(PA, 13U, 4U, 0x4CU, 0U) -#define PA13_I2C3_SDA SF32LB_PINMUX(PA, 13U, 4U, 0x50U, 1U) +#define PA13_I2C2_SDA SF32LB_PINMUX(PA, 13U, 4U, 0x4CU, 1U) #define PA13_I2C3_SCL SF32LB_PINMUX(PA, 13U, 4U, 0x50U, 0U) -#define PA13_I2C4_SDA SF32LB_PINMUX(PA, 13U, 4U, 0x54U, 1U) +#define PA13_I2C3_SDA SF32LB_PINMUX(PA, 13U, 4U, 0x50U, 1U) #define PA13_I2C4_SCL SF32LB_PINMUX(PA, 13U, 4U, 0x54U, 0U) -#define PA13_USART1_CTS SF32LB_PINMUX(PA, 13U, 4U, 0x58U, 3U) -#define PA13_USART1_RTS SF32LB_PINMUX(PA, 13U, 4U, 0x58U, 2U) -#define PA13_USART1_RXD SF32LB_PINMUX(PA, 13U, 4U, 0x58U, 1U) +#define PA13_I2C4_SDA SF32LB_PINMUX(PA, 13U, 4U, 0x54U, 1U) #define PA13_USART1_TXD SF32LB_PINMUX(PA, 13U, 4U, 0x58U, 0U) -#define PA13_USART2_CTS SF32LB_PINMUX(PA, 13U, 4U, 0x5CU, 3U) -#define PA13_USART2_RTS SF32LB_PINMUX(PA, 13U, 4U, 0x5CU, 2U) -#define PA13_USART2_RXD SF32LB_PINMUX(PA, 13U, 4U, 0x5CU, 1U) +#define PA13_USART1_RXD SF32LB_PINMUX(PA, 13U, 4U, 0x58U, 1U) +#define PA13_USART1_RTS SF32LB_PINMUX(PA, 13U, 4U, 0x58U, 2U) +#define PA13_USART1_CTS SF32LB_PINMUX(PA, 13U, 4U, 0x58U, 3U) #define PA13_USART2_TXD SF32LB_PINMUX(PA, 13U, 4U, 0x5CU, 0U) -#define PA13_USART3_CTS SF32LB_PINMUX(PA, 13U, 4U, 0x60U, 3U) -#define PA13_USART3_RTS SF32LB_PINMUX(PA, 13U, 4U, 0x60U, 2U) -#define PA13_USART3_RXD SF32LB_PINMUX(PA, 13U, 4U, 0x60U, 1U) +#define PA13_USART2_RXD SF32LB_PINMUX(PA, 13U, 4U, 0x5CU, 1U) +#define PA13_USART2_RTS SF32LB_PINMUX(PA, 13U, 4U, 0x5CU, 2U) +#define PA13_USART2_CTS SF32LB_PINMUX(PA, 13U, 4U, 0x5CU, 3U) #define PA13_USART3_TXD SF32LB_PINMUX(PA, 13U, 4U, 0x60U, 0U) -/* PA_I2C_UART functions end */ -/* PA_TIM functions start */ +#define PA13_USART3_RXD SF32LB_PINMUX(PA, 13U, 4U, 0x60U, 1U) +#define PA13_USART3_RTS SF32LB_PINMUX(PA, 13U, 4U, 0x60U, 2U) +#define PA13_USART3_CTS SF32LB_PINMUX(PA, 13U, 4U, 0x60U, 3U) #define PA13_GPTIM1_CH1 SF32LB_PINMUX(PA, 13U, 5U, 0x64U, 0U) #define PA13_GPTIM1_CH2 SF32LB_PINMUX(PA, 13U, 5U, 0x64U, 1U) #define PA13_GPTIM1_CH3 SF32LB_PINMUX(PA, 13U, 5U, 0x64U, 2U) #define PA13_GPTIM1_CH4 SF32LB_PINMUX(PA, 13U, 5U, 0x64U, 3U) +#define PA13_GPTIM1_ETR SF32LB_PINMUX(PA, 13U, 5U, 0x6CU, 0U) #define PA13_GPTIM2_CH1 SF32LB_PINMUX(PA, 13U, 5U, 0x68U, 0U) #define PA13_GPTIM2_CH2 SF32LB_PINMUX(PA, 13U, 5U, 0x68U, 1U) #define PA13_GPTIM2_CH3 SF32LB_PINMUX(PA, 13U, 5U, 0x68U, 2U) #define PA13_GPTIM2_CH4 SF32LB_PINMUX(PA, 13U, 5U, 0x68U, 3U) -#define PA13_GPTIM1_ETR SF32LB_PINMUX(PA, 13U, 5U, 0x6CU, 0U) #define PA13_GPTIM2_ETR SF32LB_PINMUX(PA, 13U, 5U, 0x6CU, 1U) #define PA13_LPTIM1_IN SF32LB_PINMUX(PA, 13U, 5U, 0x70U, 0U) #define PA13_LPTIM1_OUT SF32LB_PINMUX(PA, 13U, 5U, 0x70U, 1U) @@ -797,48 +744,44 @@ #define PA13_ATIM1_CH1N SF32LB_PINMUX(PA, 13U, 5U, 0x7CU, 0U) #define PA13_ATIM1_CH2N SF32LB_PINMUX(PA, 13U, 5U, 0x7CU, 1U) #define PA13_ATIM1_CH3N SF32LB_PINMUX(PA, 13U, 5U, 0x7CU, 2U) +#define PA13_ATIM1_ETR SF32LB_PINMUX(PA, 13U, 5U, 0x80U, 2U) #define PA13_ATIM1_BK SF32LB_PINMUX(PA, 13U, 5U, 0x80U, 0U) #define PA13_ATIM1_BK2 SF32LB_PINMUX(PA, 13U, 5U, 0x80U, 1U) -#define PA13_ATIM1_ETR SF32LB_PINMUX(PA, 13U, 5U, 0x80U, 2U) -/* PA_TIM functions end */ /* PA14 */ #define PA14_ANALOG SF32LB_PINMUX_ANALOG(PA, 14U) #define PA14_GPIO SF32LB_PINMUX(PA, 14U, 0U, 0U, 0U) #define PA14_MPI2_DIO2 SF32LB_PINMUX(PA, 14U, 1U, 0U, 0U) #define PA14_SD1_CLK SF32LB_PINMUX(PA, 14U, 2U, 0U, 0U) -/* PA_I2C_UART functions start */ -#define PA14_I2C1_SDA SF32LB_PINMUX(PA, 14U, 4U, 0x48U, 1U) #define PA14_I2C1_SCL SF32LB_PINMUX(PA, 14U, 4U, 0x48U, 0U) -#define PA14_I2C2_SDA SF32LB_PINMUX(PA, 14U, 4U, 0x4CU, 1U) +#define PA14_I2C1_SDA SF32LB_PINMUX(PA, 14U, 4U, 0x48U, 1U) #define PA14_I2C2_SCL SF32LB_PINMUX(PA, 14U, 4U, 0x4CU, 0U) -#define PA14_I2C3_SDA SF32LB_PINMUX(PA, 14U, 4U, 0x50U, 1U) +#define PA14_I2C2_SDA SF32LB_PINMUX(PA, 14U, 4U, 0x4CU, 1U) #define PA14_I2C3_SCL SF32LB_PINMUX(PA, 14U, 4U, 0x50U, 0U) -#define PA14_I2C4_SDA SF32LB_PINMUX(PA, 14U, 4U, 0x54U, 1U) +#define PA14_I2C3_SDA SF32LB_PINMUX(PA, 14U, 4U, 0x50U, 1U) #define PA14_I2C4_SCL SF32LB_PINMUX(PA, 14U, 4U, 0x54U, 0U) -#define PA14_USART1_CTS SF32LB_PINMUX(PA, 14U, 4U, 0x58U, 3U) -#define PA14_USART1_RTS SF32LB_PINMUX(PA, 14U, 4U, 0x58U, 2U) -#define PA14_USART1_RXD SF32LB_PINMUX(PA, 14U, 4U, 0x58U, 1U) +#define PA14_I2C4_SDA SF32LB_PINMUX(PA, 14U, 4U, 0x54U, 1U) #define PA14_USART1_TXD SF32LB_PINMUX(PA, 14U, 4U, 0x58U, 0U) -#define PA14_USART2_CTS SF32LB_PINMUX(PA, 14U, 4U, 0x5CU, 3U) -#define PA14_USART2_RTS SF32LB_PINMUX(PA, 14U, 4U, 0x5CU, 2U) -#define PA14_USART2_RXD SF32LB_PINMUX(PA, 14U, 4U, 0x5CU, 1U) +#define PA14_USART1_RXD SF32LB_PINMUX(PA, 14U, 4U, 0x58U, 1U) +#define PA14_USART1_RTS SF32LB_PINMUX(PA, 14U, 4U, 0x58U, 2U) +#define PA14_USART1_CTS SF32LB_PINMUX(PA, 14U, 4U, 0x58U, 3U) #define PA14_USART2_TXD SF32LB_PINMUX(PA, 14U, 4U, 0x5CU, 0U) -#define PA14_USART3_CTS SF32LB_PINMUX(PA, 14U, 4U, 0x60U, 3U) -#define PA14_USART3_RTS SF32LB_PINMUX(PA, 14U, 4U, 0x60U, 2U) -#define PA14_USART3_RXD SF32LB_PINMUX(PA, 14U, 4U, 0x60U, 1U) +#define PA14_USART2_RXD SF32LB_PINMUX(PA, 14U, 4U, 0x5CU, 1U) +#define PA14_USART2_RTS SF32LB_PINMUX(PA, 14U, 4U, 0x5CU, 2U) +#define PA14_USART2_CTS SF32LB_PINMUX(PA, 14U, 4U, 0x5CU, 3U) #define PA14_USART3_TXD SF32LB_PINMUX(PA, 14U, 4U, 0x60U, 0U) -/* PA_I2C_UART functions end */ -/* PA_TIM functions start */ +#define PA14_USART3_RXD SF32LB_PINMUX(PA, 14U, 4U, 0x60U, 1U) +#define PA14_USART3_RTS SF32LB_PINMUX(PA, 14U, 4U, 0x60U, 2U) +#define PA14_USART3_CTS SF32LB_PINMUX(PA, 14U, 4U, 0x60U, 3U) #define PA14_GPTIM1_CH1 SF32LB_PINMUX(PA, 14U, 5U, 0x64U, 0U) #define PA14_GPTIM1_CH2 SF32LB_PINMUX(PA, 14U, 5U, 0x64U, 1U) #define PA14_GPTIM1_CH3 SF32LB_PINMUX(PA, 14U, 5U, 0x64U, 2U) #define PA14_GPTIM1_CH4 SF32LB_PINMUX(PA, 14U, 5U, 0x64U, 3U) +#define PA14_GPTIM1_ETR SF32LB_PINMUX(PA, 14U, 5U, 0x6CU, 0U) #define PA14_GPTIM2_CH1 SF32LB_PINMUX(PA, 14U, 5U, 0x68U, 0U) #define PA14_GPTIM2_CH2 SF32LB_PINMUX(PA, 14U, 5U, 0x68U, 1U) #define PA14_GPTIM2_CH3 SF32LB_PINMUX(PA, 14U, 5U, 0x68U, 2U) #define PA14_GPTIM2_CH4 SF32LB_PINMUX(PA, 14U, 5U, 0x68U, 3U) -#define PA14_GPTIM1_ETR SF32LB_PINMUX(PA, 14U, 5U, 0x6CU, 0U) #define PA14_GPTIM2_ETR SF32LB_PINMUX(PA, 14U, 5U, 0x6CU, 1U) #define PA14_LPTIM1_IN SF32LB_PINMUX(PA, 14U, 5U, 0x70U, 0U) #define PA14_LPTIM1_OUT SF32LB_PINMUX(PA, 14U, 5U, 0x70U, 1U) @@ -853,48 +796,44 @@ #define PA14_ATIM1_CH1N SF32LB_PINMUX(PA, 14U, 5U, 0x7CU, 0U) #define PA14_ATIM1_CH2N SF32LB_PINMUX(PA, 14U, 5U, 0x7CU, 1U) #define PA14_ATIM1_CH3N SF32LB_PINMUX(PA, 14U, 5U, 0x7CU, 2U) +#define PA14_ATIM1_ETR SF32LB_PINMUX(PA, 14U, 5U, 0x80U, 2U) #define PA14_ATIM1_BK SF32LB_PINMUX(PA, 14U, 5U, 0x80U, 0U) #define PA14_ATIM1_BK2 SF32LB_PINMUX(PA, 14U, 5U, 0x80U, 1U) -#define PA14_ATIM1_ETR SF32LB_PINMUX(PA, 14U, 5U, 0x80U, 2U) -/* PA_TIM functions end */ /* PA15 */ #define PA15_ANALOG SF32LB_PINMUX_ANALOG(PA, 15U) #define PA15_GPIO SF32LB_PINMUX(PA, 15U, 0U, 0U, 0U) #define PA15_MPI2_DIO0 SF32LB_PINMUX(PA, 15U, 1U, 0U, 0U) #define PA15_SD1_CMD SF32LB_PINMUX(PA, 15U, 2U, 0U, 0U) -/* PA_I2C_UART functions start */ -#define PA15_I2C1_SDA SF32LB_PINMUX(PA, 15U, 4U, 0x48U, 1U) #define PA15_I2C1_SCL SF32LB_PINMUX(PA, 15U, 4U, 0x48U, 0U) -#define PA15_I2C2_SDA SF32LB_PINMUX(PA, 15U, 4U, 0x4CU, 1U) +#define PA15_I2C1_SDA SF32LB_PINMUX(PA, 15U, 4U, 0x48U, 1U) #define PA15_I2C2_SCL SF32LB_PINMUX(PA, 15U, 4U, 0x4CU, 0U) -#define PA15_I2C3_SDA SF32LB_PINMUX(PA, 15U, 4U, 0x50U, 1U) +#define PA15_I2C2_SDA SF32LB_PINMUX(PA, 15U, 4U, 0x4CU, 1U) #define PA15_I2C3_SCL SF32LB_PINMUX(PA, 15U, 4U, 0x50U, 0U) -#define PA15_I2C4_SDA SF32LB_PINMUX(PA, 15U, 4U, 0x54U, 1U) +#define PA15_I2C3_SDA SF32LB_PINMUX(PA, 15U, 4U, 0x50U, 1U) #define PA15_I2C4_SCL SF32LB_PINMUX(PA, 15U, 4U, 0x54U, 0U) -#define PA15_USART1_CTS SF32LB_PINMUX(PA, 15U, 4U, 0x58U, 3U) -#define PA15_USART1_RTS SF32LB_PINMUX(PA, 15U, 4U, 0x58U, 2U) -#define PA15_USART1_RXD SF32LB_PINMUX(PA, 15U, 4U, 0x58U, 1U) +#define PA15_I2C4_SDA SF32LB_PINMUX(PA, 15U, 4U, 0x54U, 1U) #define PA15_USART1_TXD SF32LB_PINMUX(PA, 15U, 4U, 0x58U, 0U) -#define PA15_USART2_CTS SF32LB_PINMUX(PA, 15U, 4U, 0x5CU, 3U) -#define PA15_USART2_RTS SF32LB_PINMUX(PA, 15U, 4U, 0x5CU, 2U) -#define PA15_USART2_RXD SF32LB_PINMUX(PA, 15U, 4U, 0x5CU, 1U) +#define PA15_USART1_RXD SF32LB_PINMUX(PA, 15U, 4U, 0x58U, 1U) +#define PA15_USART1_RTS SF32LB_PINMUX(PA, 15U, 4U, 0x58U, 2U) +#define PA15_USART1_CTS SF32LB_PINMUX(PA, 15U, 4U, 0x58U, 3U) #define PA15_USART2_TXD SF32LB_PINMUX(PA, 15U, 4U, 0x5CU, 0U) -#define PA15_USART3_CTS SF32LB_PINMUX(PA, 15U, 4U, 0x60U, 3U) -#define PA15_USART3_RTS SF32LB_PINMUX(PA, 15U, 4U, 0x60U, 2U) -#define PA15_USART3_RXD SF32LB_PINMUX(PA, 15U, 4U, 0x60U, 1U) +#define PA15_USART2_RXD SF32LB_PINMUX(PA, 15U, 4U, 0x5CU, 1U) +#define PA15_USART2_RTS SF32LB_PINMUX(PA, 15U, 4U, 0x5CU, 2U) +#define PA15_USART2_CTS SF32LB_PINMUX(PA, 15U, 4U, 0x5CU, 3U) #define PA15_USART3_TXD SF32LB_PINMUX(PA, 15U, 4U, 0x60U, 0U) -/* PA_I2C_UART functions end */ -/* PA_TIM functions start */ +#define PA15_USART3_RXD SF32LB_PINMUX(PA, 15U, 4U, 0x60U, 1U) +#define PA15_USART3_RTS SF32LB_PINMUX(PA, 15U, 4U, 0x60U, 2U) +#define PA15_USART3_CTS SF32LB_PINMUX(PA, 15U, 4U, 0x60U, 3U) #define PA15_GPTIM1_CH1 SF32LB_PINMUX(PA, 15U, 5U, 0x64U, 0U) #define PA15_GPTIM1_CH2 SF32LB_PINMUX(PA, 15U, 5U, 0x64U, 1U) #define PA15_GPTIM1_CH3 SF32LB_PINMUX(PA, 15U, 5U, 0x64U, 2U) #define PA15_GPTIM1_CH4 SF32LB_PINMUX(PA, 15U, 5U, 0x64U, 3U) +#define PA15_GPTIM1_ETR SF32LB_PINMUX(PA, 15U, 5U, 0x6CU, 0U) #define PA15_GPTIM2_CH1 SF32LB_PINMUX(PA, 15U, 5U, 0x68U, 0U) #define PA15_GPTIM2_CH2 SF32LB_PINMUX(PA, 15U, 5U, 0x68U, 1U) #define PA15_GPTIM2_CH3 SF32LB_PINMUX(PA, 15U, 5U, 0x68U, 2U) #define PA15_GPTIM2_CH4 SF32LB_PINMUX(PA, 15U, 5U, 0x68U, 3U) -#define PA15_GPTIM1_ETR SF32LB_PINMUX(PA, 15U, 5U, 0x6CU, 0U) #define PA15_GPTIM2_ETR SF32LB_PINMUX(PA, 15U, 5U, 0x6CU, 1U) #define PA15_LPTIM1_IN SF32LB_PINMUX(PA, 15U, 5U, 0x70U, 0U) #define PA15_LPTIM1_OUT SF32LB_PINMUX(PA, 15U, 5U, 0x70U, 1U) @@ -909,48 +848,44 @@ #define PA15_ATIM1_CH1N SF32LB_PINMUX(PA, 15U, 5U, 0x7CU, 0U) #define PA15_ATIM1_CH2N SF32LB_PINMUX(PA, 15U, 5U, 0x7CU, 1U) #define PA15_ATIM1_CH3N SF32LB_PINMUX(PA, 15U, 5U, 0x7CU, 2U) +#define PA15_ATIM1_ETR SF32LB_PINMUX(PA, 15U, 5U, 0x80U, 2U) #define PA15_ATIM1_BK SF32LB_PINMUX(PA, 15U, 5U, 0x80U, 0U) #define PA15_ATIM1_BK2 SF32LB_PINMUX(PA, 15U, 5U, 0x80U, 1U) -#define PA15_ATIM1_ETR SF32LB_PINMUX(PA, 15U, 5U, 0x80U, 2U) -/* PA_TIM functions end */ /* PA16 */ #define PA16_ANALOG SF32LB_PINMUX_ANALOG(PA, 16U) #define PA16_GPIO SF32LB_PINMUX(PA, 16U, 0U, 0U, 0U) #define PA16_MPI2_CLK SF32LB_PINMUX(PA, 16U, 1U, 0U, 0U) #define PA16_SD1_DIO0 SF32LB_PINMUX(PA, 16U, 2U, 0U, 0U) -/* PA_I2C_UART functions start */ -#define PA16_I2C1_SDA SF32LB_PINMUX(PA, 16U, 4U, 0x48U, 1U) #define PA16_I2C1_SCL SF32LB_PINMUX(PA, 16U, 4U, 0x48U, 0U) -#define PA16_I2C2_SDA SF32LB_PINMUX(PA, 16U, 4U, 0x4CU, 1U) +#define PA16_I2C1_SDA SF32LB_PINMUX(PA, 16U, 4U, 0x48U, 1U) #define PA16_I2C2_SCL SF32LB_PINMUX(PA, 16U, 4U, 0x4CU, 0U) -#define PA16_I2C3_SDA SF32LB_PINMUX(PA, 16U, 4U, 0x50U, 1U) +#define PA16_I2C2_SDA SF32LB_PINMUX(PA, 16U, 4U, 0x4CU, 1U) #define PA16_I2C3_SCL SF32LB_PINMUX(PA, 16U, 4U, 0x50U, 0U) -#define PA16_I2C4_SDA SF32LB_PINMUX(PA, 16U, 4U, 0x54U, 1U) +#define PA16_I2C3_SDA SF32LB_PINMUX(PA, 16U, 4U, 0x50U, 1U) #define PA16_I2C4_SCL SF32LB_PINMUX(PA, 16U, 4U, 0x54U, 0U) -#define PA16_USART1_CTS SF32LB_PINMUX(PA, 16U, 4U, 0x58U, 3U) -#define PA16_USART1_RTS SF32LB_PINMUX(PA, 16U, 4U, 0x58U, 2U) -#define PA16_USART1_RXD SF32LB_PINMUX(PA, 16U, 4U, 0x58U, 1U) +#define PA16_I2C4_SDA SF32LB_PINMUX(PA, 16U, 4U, 0x54U, 1U) #define PA16_USART1_TXD SF32LB_PINMUX(PA, 16U, 4U, 0x58U, 0U) -#define PA16_USART2_CTS SF32LB_PINMUX(PA, 16U, 4U, 0x5CU, 3U) -#define PA16_USART2_RTS SF32LB_PINMUX(PA, 16U, 4U, 0x5CU, 2U) -#define PA16_USART2_RXD SF32LB_PINMUX(PA, 16U, 4U, 0x5CU, 1U) +#define PA16_USART1_RXD SF32LB_PINMUX(PA, 16U, 4U, 0x58U, 1U) +#define PA16_USART1_RTS SF32LB_PINMUX(PA, 16U, 4U, 0x58U, 2U) +#define PA16_USART1_CTS SF32LB_PINMUX(PA, 16U, 4U, 0x58U, 3U) #define PA16_USART2_TXD SF32LB_PINMUX(PA, 16U, 4U, 0x5CU, 0U) -#define PA16_USART3_CTS SF32LB_PINMUX(PA, 16U, 4U, 0x60U, 3U) -#define PA16_USART3_RTS SF32LB_PINMUX(PA, 16U, 4U, 0x60U, 2U) -#define PA16_USART3_RXD SF32LB_PINMUX(PA, 16U, 4U, 0x60U, 1U) +#define PA16_USART2_RXD SF32LB_PINMUX(PA, 16U, 4U, 0x5CU, 1U) +#define PA16_USART2_RTS SF32LB_PINMUX(PA, 16U, 4U, 0x5CU, 2U) +#define PA16_USART2_CTS SF32LB_PINMUX(PA, 16U, 4U, 0x5CU, 3U) #define PA16_USART3_TXD SF32LB_PINMUX(PA, 16U, 4U, 0x60U, 0U) -/* PA_I2C_UART functions end */ -/* PA_TIM functions start */ +#define PA16_USART3_RXD SF32LB_PINMUX(PA, 16U, 4U, 0x60U, 1U) +#define PA16_USART3_RTS SF32LB_PINMUX(PA, 16U, 4U, 0x60U, 2U) +#define PA16_USART3_CTS SF32LB_PINMUX(PA, 16U, 4U, 0x60U, 3U) #define PA16_GPTIM1_CH1 SF32LB_PINMUX(PA, 16U, 5U, 0x64U, 0U) #define PA16_GPTIM1_CH2 SF32LB_PINMUX(PA, 16U, 5U, 0x64U, 1U) #define PA16_GPTIM1_CH3 SF32LB_PINMUX(PA, 16U, 5U, 0x64U, 2U) #define PA16_GPTIM1_CH4 SF32LB_PINMUX(PA, 16U, 5U, 0x64U, 3U) +#define PA16_GPTIM1_ETR SF32LB_PINMUX(PA, 16U, 5U, 0x6CU, 0U) #define PA16_GPTIM2_CH1 SF32LB_PINMUX(PA, 16U, 5U, 0x68U, 0U) #define PA16_GPTIM2_CH2 SF32LB_PINMUX(PA, 16U, 5U, 0x68U, 1U) #define PA16_GPTIM2_CH3 SF32LB_PINMUX(PA, 16U, 5U, 0x68U, 2U) #define PA16_GPTIM2_CH4 SF32LB_PINMUX(PA, 16U, 5U, 0x68U, 3U) -#define PA16_GPTIM1_ETR SF32LB_PINMUX(PA, 16U, 5U, 0x6CU, 0U) #define PA16_GPTIM2_ETR SF32LB_PINMUX(PA, 16U, 5U, 0x6CU, 1U) #define PA16_LPTIM1_IN SF32LB_PINMUX(PA, 16U, 5U, 0x70U, 0U) #define PA16_LPTIM1_OUT SF32LB_PINMUX(PA, 16U, 5U, 0x70U, 1U) @@ -965,48 +900,44 @@ #define PA16_ATIM1_CH1N SF32LB_PINMUX(PA, 16U, 5U, 0x7CU, 0U) #define PA16_ATIM1_CH2N SF32LB_PINMUX(PA, 16U, 5U, 0x7CU, 1U) #define PA16_ATIM1_CH3N SF32LB_PINMUX(PA, 16U, 5U, 0x7CU, 2U) +#define PA16_ATIM1_ETR SF32LB_PINMUX(PA, 16U, 5U, 0x80U, 2U) #define PA16_ATIM1_BK SF32LB_PINMUX(PA, 16U, 5U, 0x80U, 0U) #define PA16_ATIM1_BK2 SF32LB_PINMUX(PA, 16U, 5U, 0x80U, 1U) -#define PA16_ATIM1_ETR SF32LB_PINMUX(PA, 16U, 5U, 0x80U, 2U) -/* PA_TIM functions end */ /* PA17 */ #define PA17_ANALOG SF32LB_PINMUX_ANALOG(PA, 17U) #define PA17_GPIO SF32LB_PINMUX(PA, 17U, 0U, 0U, 0U) #define PA17_MPI2_DIO3 SF32LB_PINMUX(PA, 17U, 1U, 0U, 0U) #define PA17_SD1_DIO1 SF32LB_PINMUX(PA, 17U, 2U, 0U, 0U) -/* PA_I2C_UART functions start */ -#define PA17_I2C1_SDA SF32LB_PINMUX(PA, 17U, 4U, 0x48U, 1U) #define PA17_I2C1_SCL SF32LB_PINMUX(PA, 17U, 4U, 0x48U, 0U) -#define PA17_I2C2_SDA SF32LB_PINMUX(PA, 17U, 4U, 0x4CU, 1U) +#define PA17_I2C1_SDA SF32LB_PINMUX(PA, 17U, 4U, 0x48U, 1U) #define PA17_I2C2_SCL SF32LB_PINMUX(PA, 17U, 4U, 0x4CU, 0U) -#define PA17_I2C3_SDA SF32LB_PINMUX(PA, 17U, 4U, 0x50U, 1U) +#define PA17_I2C2_SDA SF32LB_PINMUX(PA, 17U, 4U, 0x4CU, 1U) #define PA17_I2C3_SCL SF32LB_PINMUX(PA, 17U, 4U, 0x50U, 0U) -#define PA17_I2C4_SDA SF32LB_PINMUX(PA, 17U, 4U, 0x54U, 1U) +#define PA17_I2C3_SDA SF32LB_PINMUX(PA, 17U, 4U, 0x50U, 1U) #define PA17_I2C4_SCL SF32LB_PINMUX(PA, 17U, 4U, 0x54U, 0U) -#define PA17_USART1_CTS SF32LB_PINMUX(PA, 17U, 4U, 0x58U, 3U) -#define PA17_USART1_RTS SF32LB_PINMUX(PA, 17U, 4U, 0x58U, 2U) -#define PA17_USART1_RXD SF32LB_PINMUX(PA, 17U, 4U, 0x58U, 1U) +#define PA17_I2C4_SDA SF32LB_PINMUX(PA, 17U, 4U, 0x54U, 1U) #define PA17_USART1_TXD SF32LB_PINMUX(PA, 17U, 4U, 0x58U, 0U) -#define PA17_USART2_CTS SF32LB_PINMUX(PA, 17U, 4U, 0x5CU, 3U) -#define PA17_USART2_RTS SF32LB_PINMUX(PA, 17U, 4U, 0x5CU, 2U) -#define PA17_USART2_RXD SF32LB_PINMUX(PA, 17U, 4U, 0x5CU, 1U) +#define PA17_USART1_RXD SF32LB_PINMUX(PA, 17U, 4U, 0x58U, 1U) +#define PA17_USART1_RTS SF32LB_PINMUX(PA, 17U, 4U, 0x58U, 2U) +#define PA17_USART1_CTS SF32LB_PINMUX(PA, 17U, 4U, 0x58U, 3U) #define PA17_USART2_TXD SF32LB_PINMUX(PA, 17U, 4U, 0x5CU, 0U) -#define PA17_USART3_CTS SF32LB_PINMUX(PA, 17U, 4U, 0x60U, 3U) -#define PA17_USART3_RTS SF32LB_PINMUX(PA, 17U, 4U, 0x60U, 2U) -#define PA17_USART3_RXD SF32LB_PINMUX(PA, 17U, 4U, 0x60U, 1U) +#define PA17_USART2_RXD SF32LB_PINMUX(PA, 17U, 4U, 0x5CU, 1U) +#define PA17_USART2_RTS SF32LB_PINMUX(PA, 17U, 4U, 0x5CU, 2U) +#define PA17_USART2_CTS SF32LB_PINMUX(PA, 17U, 4U, 0x5CU, 3U) #define PA17_USART3_TXD SF32LB_PINMUX(PA, 17U, 4U, 0x60U, 0U) -/* PA_I2C_UART functions end */ -/* PA_TIM functions start */ +#define PA17_USART3_RXD SF32LB_PINMUX(PA, 17U, 4U, 0x60U, 1U) +#define PA17_USART3_RTS SF32LB_PINMUX(PA, 17U, 4U, 0x60U, 2U) +#define PA17_USART3_CTS SF32LB_PINMUX(PA, 17U, 4U, 0x60U, 3U) #define PA17_GPTIM1_CH1 SF32LB_PINMUX(PA, 17U, 5U, 0x64U, 0U) #define PA17_GPTIM1_CH2 SF32LB_PINMUX(PA, 17U, 5U, 0x64U, 1U) #define PA17_GPTIM1_CH3 SF32LB_PINMUX(PA, 17U, 5U, 0x64U, 2U) #define PA17_GPTIM1_CH4 SF32LB_PINMUX(PA, 17U, 5U, 0x64U, 3U) +#define PA17_GPTIM1_ETR SF32LB_PINMUX(PA, 17U, 5U, 0x6CU, 0U) #define PA17_GPTIM2_CH1 SF32LB_PINMUX(PA, 17U, 5U, 0x68U, 0U) #define PA17_GPTIM2_CH2 SF32LB_PINMUX(PA, 17U, 5U, 0x68U, 1U) #define PA17_GPTIM2_CH3 SF32LB_PINMUX(PA, 17U, 5U, 0x68U, 2U) #define PA17_GPTIM2_CH4 SF32LB_PINMUX(PA, 17U, 5U, 0x68U, 3U) -#define PA17_GPTIM1_ETR SF32LB_PINMUX(PA, 17U, 5U, 0x6CU, 0U) #define PA17_GPTIM2_ETR SF32LB_PINMUX(PA, 17U, 5U, 0x6CU, 1U) #define PA17_LPTIM1_IN SF32LB_PINMUX(PA, 17U, 5U, 0x70U, 0U) #define PA17_LPTIM1_OUT SF32LB_PINMUX(PA, 17U, 5U, 0x70U, 1U) @@ -1021,47 +952,43 @@ #define PA17_ATIM1_CH1N SF32LB_PINMUX(PA, 17U, 5U, 0x7CU, 0U) #define PA17_ATIM1_CH2N SF32LB_PINMUX(PA, 17U, 5U, 0x7CU, 1U) #define PA17_ATIM1_CH3N SF32LB_PINMUX(PA, 17U, 5U, 0x7CU, 2U) +#define PA17_ATIM1_ETR SF32LB_PINMUX(PA, 17U, 5U, 0x80U, 2U) #define PA17_ATIM1_BK SF32LB_PINMUX(PA, 17U, 5U, 0x80U, 0U) #define PA17_ATIM1_BK2 SF32LB_PINMUX(PA, 17U, 5U, 0x80U, 1U) -#define PA17_ATIM1_ETR SF32LB_PINMUX(PA, 17U, 5U, 0x80U, 2U) -/* PA_TIM functions end */ /* PA18 */ #define PA18_ANALOG SF32LB_PINMUX_ANALOG(PA, 18U) #define PA18_GPIO SF32LB_PINMUX(PA, 18U, 0U, 0U, 0U) #define PA18_SWDIO SF32LB_PINMUX(PA, 18U, 2U, 0U, 0U) -/* PA_I2C_UART functions start */ -#define PA18_I2C1_SDA SF32LB_PINMUX(PA, 18U, 4U, 0x48U, 1U) #define PA18_I2C1_SCL SF32LB_PINMUX(PA, 18U, 4U, 0x48U, 0U) -#define PA18_I2C2_SDA SF32LB_PINMUX(PA, 18U, 4U, 0x4CU, 1U) +#define PA18_I2C1_SDA SF32LB_PINMUX(PA, 18U, 4U, 0x48U, 1U) #define PA18_I2C2_SCL SF32LB_PINMUX(PA, 18U, 4U, 0x4CU, 0U) -#define PA18_I2C3_SDA SF32LB_PINMUX(PA, 18U, 4U, 0x50U, 1U) +#define PA18_I2C2_SDA SF32LB_PINMUX(PA, 18U, 4U, 0x4CU, 1U) #define PA18_I2C3_SCL SF32LB_PINMUX(PA, 18U, 4U, 0x50U, 0U) -#define PA18_I2C4_SDA SF32LB_PINMUX(PA, 18U, 4U, 0x54U, 1U) +#define PA18_I2C3_SDA SF32LB_PINMUX(PA, 18U, 4U, 0x50U, 1U) #define PA18_I2C4_SCL SF32LB_PINMUX(PA, 18U, 4U, 0x54U, 0U) -#define PA18_USART1_CTS SF32LB_PINMUX(PA, 18U, 4U, 0x58U, 3U) -#define PA18_USART1_RTS SF32LB_PINMUX(PA, 18U, 4U, 0x58U, 2U) -#define PA18_USART1_RXD SF32LB_PINMUX(PA, 18U, 4U, 0x58U, 1U) +#define PA18_I2C4_SDA SF32LB_PINMUX(PA, 18U, 4U, 0x54U, 1U) #define PA18_USART1_TXD SF32LB_PINMUX(PA, 18U, 4U, 0x58U, 0U) -#define PA18_USART2_CTS SF32LB_PINMUX(PA, 18U, 4U, 0x5CU, 3U) -#define PA18_USART2_RTS SF32LB_PINMUX(PA, 18U, 4U, 0x5CU, 2U) -#define PA18_USART2_RXD SF32LB_PINMUX(PA, 18U, 4U, 0x5CU, 1U) +#define PA18_USART1_RXD SF32LB_PINMUX(PA, 18U, 4U, 0x58U, 1U) +#define PA18_USART1_RTS SF32LB_PINMUX(PA, 18U, 4U, 0x58U, 2U) +#define PA18_USART1_CTS SF32LB_PINMUX(PA, 18U, 4U, 0x58U, 3U) #define PA18_USART2_TXD SF32LB_PINMUX(PA, 18U, 4U, 0x5CU, 0U) -#define PA18_USART3_CTS SF32LB_PINMUX(PA, 18U, 4U, 0x60U, 3U) -#define PA18_USART3_RTS SF32LB_PINMUX(PA, 18U, 4U, 0x60U, 2U) -#define PA18_USART3_RXD SF32LB_PINMUX(PA, 18U, 4U, 0x60U, 1U) +#define PA18_USART2_RXD SF32LB_PINMUX(PA, 18U, 4U, 0x5CU, 1U) +#define PA18_USART2_RTS SF32LB_PINMUX(PA, 18U, 4U, 0x5CU, 2U) +#define PA18_USART2_CTS SF32LB_PINMUX(PA, 18U, 4U, 0x5CU, 3U) #define PA18_USART3_TXD SF32LB_PINMUX(PA, 18U, 4U, 0x60U, 0U) -/* PA_I2C_UART functions end */ -/* PA_TIM functions start */ +#define PA18_USART3_RXD SF32LB_PINMUX(PA, 18U, 4U, 0x60U, 1U) +#define PA18_USART3_RTS SF32LB_PINMUX(PA, 18U, 4U, 0x60U, 2U) +#define PA18_USART3_CTS SF32LB_PINMUX(PA, 18U, 4U, 0x60U, 3U) #define PA18_GPTIM1_CH1 SF32LB_PINMUX(PA, 18U, 5U, 0x64U, 0U) #define PA18_GPTIM1_CH2 SF32LB_PINMUX(PA, 18U, 5U, 0x64U, 1U) #define PA18_GPTIM1_CH3 SF32LB_PINMUX(PA, 18U, 5U, 0x64U, 2U) #define PA18_GPTIM1_CH4 SF32LB_PINMUX(PA, 18U, 5U, 0x64U, 3U) +#define PA18_GPTIM1_ETR SF32LB_PINMUX(PA, 18U, 5U, 0x6CU, 0U) #define PA18_GPTIM2_CH1 SF32LB_PINMUX(PA, 18U, 5U, 0x68U, 0U) #define PA18_GPTIM2_CH2 SF32LB_PINMUX(PA, 18U, 5U, 0x68U, 1U) #define PA18_GPTIM2_CH3 SF32LB_PINMUX(PA, 18U, 5U, 0x68U, 2U) #define PA18_GPTIM2_CH4 SF32LB_PINMUX(PA, 18U, 5U, 0x68U, 3U) -#define PA18_GPTIM1_ETR SF32LB_PINMUX(PA, 18U, 5U, 0x6CU, 0U) #define PA18_GPTIM2_ETR SF32LB_PINMUX(PA, 18U, 5U, 0x6CU, 1U) #define PA18_LPTIM1_IN SF32LB_PINMUX(PA, 18U, 5U, 0x70U, 0U) #define PA18_LPTIM1_OUT SF32LB_PINMUX(PA, 18U, 5U, 0x70U, 1U) @@ -1076,47 +1003,43 @@ #define PA18_ATIM1_CH1N SF32LB_PINMUX(PA, 18U, 5U, 0x7CU, 0U) #define PA18_ATIM1_CH2N SF32LB_PINMUX(PA, 18U, 5U, 0x7CU, 1U) #define PA18_ATIM1_CH3N SF32LB_PINMUX(PA, 18U, 5U, 0x7CU, 2U) +#define PA18_ATIM1_ETR SF32LB_PINMUX(PA, 18U, 5U, 0x80U, 2U) #define PA18_ATIM1_BK SF32LB_PINMUX(PA, 18U, 5U, 0x80U, 0U) #define PA18_ATIM1_BK2 SF32LB_PINMUX(PA, 18U, 5U, 0x80U, 1U) -#define PA18_ATIM1_ETR SF32LB_PINMUX(PA, 18U, 5U, 0x80U, 2U) -/* PA_TIM functions end */ /* PA19 */ #define PA19_ANALOG SF32LB_PINMUX_ANALOG(PA, 19U) #define PA19_GPIO SF32LB_PINMUX(PA, 19U, 0U, 0U, 0U) #define PA19_SWCLK SF32LB_PINMUX(PA, 19U, 2U, 0U, 0U) -/* PA_I2C_UART functions start */ -#define PA19_I2C1_SDA SF32LB_PINMUX(PA, 19U, 4U, 0x48U, 1U) #define PA19_I2C1_SCL SF32LB_PINMUX(PA, 19U, 4U, 0x48U, 0U) -#define PA19_I2C2_SDA SF32LB_PINMUX(PA, 19U, 4U, 0x4CU, 1U) +#define PA19_I2C1_SDA SF32LB_PINMUX(PA, 19U, 4U, 0x48U, 1U) #define PA19_I2C2_SCL SF32LB_PINMUX(PA, 19U, 4U, 0x4CU, 0U) -#define PA19_I2C3_SDA SF32LB_PINMUX(PA, 19U, 4U, 0x50U, 1U) +#define PA19_I2C2_SDA SF32LB_PINMUX(PA, 19U, 4U, 0x4CU, 1U) #define PA19_I2C3_SCL SF32LB_PINMUX(PA, 19U, 4U, 0x50U, 0U) -#define PA19_I2C4_SDA SF32LB_PINMUX(PA, 19U, 4U, 0x54U, 1U) +#define PA19_I2C3_SDA SF32LB_PINMUX(PA, 19U, 4U, 0x50U, 1U) #define PA19_I2C4_SCL SF32LB_PINMUX(PA, 19U, 4U, 0x54U, 0U) -#define PA19_USART1_CTS SF32LB_PINMUX(PA, 19U, 4U, 0x58U, 3U) -#define PA19_USART1_RTS SF32LB_PINMUX(PA, 19U, 4U, 0x58U, 2U) -#define PA19_USART1_RXD SF32LB_PINMUX(PA, 19U, 4U, 0x58U, 1U) +#define PA19_I2C4_SDA SF32LB_PINMUX(PA, 19U, 4U, 0x54U, 1U) #define PA19_USART1_TXD SF32LB_PINMUX(PA, 19U, 4U, 0x58U, 0U) -#define PA19_USART2_CTS SF32LB_PINMUX(PA, 19U, 4U, 0x5CU, 3U) -#define PA19_USART2_RTS SF32LB_PINMUX(PA, 19U, 4U, 0x5CU, 2U) -#define PA19_USART2_RXD SF32LB_PINMUX(PA, 19U, 4U, 0x5CU, 1U) +#define PA19_USART1_RXD SF32LB_PINMUX(PA, 19U, 4U, 0x58U, 1U) +#define PA19_USART1_RTS SF32LB_PINMUX(PA, 19U, 4U, 0x58U, 2U) +#define PA19_USART1_CTS SF32LB_PINMUX(PA, 19U, 4U, 0x58U, 3U) #define PA19_USART2_TXD SF32LB_PINMUX(PA, 19U, 4U, 0x5CU, 0U) -#define PA19_USART3_CTS SF32LB_PINMUX(PA, 19U, 4U, 0x60U, 3U) -#define PA19_USART3_RTS SF32LB_PINMUX(PA, 19U, 4U, 0x60U, 2U) -#define PA19_USART3_RXD SF32LB_PINMUX(PA, 19U, 4U, 0x60U, 1U) +#define PA19_USART2_RXD SF32LB_PINMUX(PA, 19U, 4U, 0x5CU, 1U) +#define PA19_USART2_RTS SF32LB_PINMUX(PA, 19U, 4U, 0x5CU, 2U) +#define PA19_USART2_CTS SF32LB_PINMUX(PA, 19U, 4U, 0x5CU, 3U) #define PA19_USART3_TXD SF32LB_PINMUX(PA, 19U, 4U, 0x60U, 0U) -/* PA_I2C_UART functions end */ -/* PA_TIM functions start */ +#define PA19_USART3_RXD SF32LB_PINMUX(PA, 19U, 4U, 0x60U, 1U) +#define PA19_USART3_RTS SF32LB_PINMUX(PA, 19U, 4U, 0x60U, 2U) +#define PA19_USART3_CTS SF32LB_PINMUX(PA, 19U, 4U, 0x60U, 3U) #define PA19_GPTIM1_CH1 SF32LB_PINMUX(PA, 19U, 5U, 0x64U, 0U) #define PA19_GPTIM1_CH2 SF32LB_PINMUX(PA, 19U, 5U, 0x64U, 1U) #define PA19_GPTIM1_CH3 SF32LB_PINMUX(PA, 19U, 5U, 0x64U, 2U) #define PA19_GPTIM1_CH4 SF32LB_PINMUX(PA, 19U, 5U, 0x64U, 3U) +#define PA19_GPTIM1_ETR SF32LB_PINMUX(PA, 19U, 5U, 0x6CU, 0U) #define PA19_GPTIM2_CH1 SF32LB_PINMUX(PA, 19U, 5U, 0x68U, 0U) #define PA19_GPTIM2_CH2 SF32LB_PINMUX(PA, 19U, 5U, 0x68U, 1U) #define PA19_GPTIM2_CH3 SF32LB_PINMUX(PA, 19U, 5U, 0x68U, 2U) #define PA19_GPTIM2_CH4 SF32LB_PINMUX(PA, 19U, 5U, 0x68U, 3U) -#define PA19_GPTIM1_ETR SF32LB_PINMUX(PA, 19U, 5U, 0x6CU, 0U) #define PA19_GPTIM2_ETR SF32LB_PINMUX(PA, 19U, 5U, 0x6CU, 1U) #define PA19_LPTIM1_IN SF32LB_PINMUX(PA, 19U, 5U, 0x70U, 0U) #define PA19_LPTIM1_OUT SF32LB_PINMUX(PA, 19U, 5U, 0x70U, 1U) @@ -1131,46 +1054,42 @@ #define PA19_ATIM1_CH1N SF32LB_PINMUX(PA, 19U, 5U, 0x7CU, 0U) #define PA19_ATIM1_CH2N SF32LB_PINMUX(PA, 19U, 5U, 0x7CU, 1U) #define PA19_ATIM1_CH3N SF32LB_PINMUX(PA, 19U, 5U, 0x7CU, 2U) +#define PA19_ATIM1_ETR SF32LB_PINMUX(PA, 19U, 5U, 0x80U, 2U) #define PA19_ATIM1_BK SF32LB_PINMUX(PA, 19U, 5U, 0x80U, 0U) #define PA19_ATIM1_BK2 SF32LB_PINMUX(PA, 19U, 5U, 0x80U, 1U) -#define PA19_ATIM1_ETR SF32LB_PINMUX(PA, 19U, 5U, 0x80U, 2U) -/* PA_TIM functions end */ /* PA20 */ #define PA20_ANALOG SF32LB_PINMUX_ANALOG(PA, 20U) #define PA20_GPIO SF32LB_PINMUX(PA, 20U, 0U, 0U, 0U) -/* PA_I2C_UART functions start */ -#define PA20_I2C1_SDA SF32LB_PINMUX(PA, 20U, 4U, 0x48U, 1U) #define PA20_I2C1_SCL SF32LB_PINMUX(PA, 20U, 4U, 0x48U, 0U) -#define PA20_I2C2_SDA SF32LB_PINMUX(PA, 20U, 4U, 0x4CU, 1U) +#define PA20_I2C1_SDA SF32LB_PINMUX(PA, 20U, 4U, 0x48U, 1U) #define PA20_I2C2_SCL SF32LB_PINMUX(PA, 20U, 4U, 0x4CU, 0U) -#define PA20_I2C3_SDA SF32LB_PINMUX(PA, 20U, 4U, 0x50U, 1U) +#define PA20_I2C2_SDA SF32LB_PINMUX(PA, 20U, 4U, 0x4CU, 1U) #define PA20_I2C3_SCL SF32LB_PINMUX(PA, 20U, 4U, 0x50U, 0U) -#define PA20_I2C4_SDA SF32LB_PINMUX(PA, 20U, 4U, 0x54U, 1U) +#define PA20_I2C3_SDA SF32LB_PINMUX(PA, 20U, 4U, 0x50U, 1U) #define PA20_I2C4_SCL SF32LB_PINMUX(PA, 20U, 4U, 0x54U, 0U) -#define PA20_USART1_CTS SF32LB_PINMUX(PA, 20U, 4U, 0x58U, 3U) -#define PA20_USART1_RTS SF32LB_PINMUX(PA, 20U, 4U, 0x58U, 2U) -#define PA20_USART1_RXD SF32LB_PINMUX(PA, 20U, 4U, 0x58U, 1U) +#define PA20_I2C4_SDA SF32LB_PINMUX(PA, 20U, 4U, 0x54U, 1U) #define PA20_USART1_TXD SF32LB_PINMUX(PA, 20U, 4U, 0x58U, 0U) -#define PA20_USART2_CTS SF32LB_PINMUX(PA, 20U, 4U, 0x5CU, 3U) -#define PA20_USART2_RTS SF32LB_PINMUX(PA, 20U, 4U, 0x5CU, 2U) -#define PA20_USART2_RXD SF32LB_PINMUX(PA, 20U, 4U, 0x5CU, 1U) +#define PA20_USART1_RXD SF32LB_PINMUX(PA, 20U, 4U, 0x58U, 1U) +#define PA20_USART1_RTS SF32LB_PINMUX(PA, 20U, 4U, 0x58U, 2U) +#define PA20_USART1_CTS SF32LB_PINMUX(PA, 20U, 4U, 0x58U, 3U) #define PA20_USART2_TXD SF32LB_PINMUX(PA, 20U, 4U, 0x5CU, 0U) -#define PA20_USART3_CTS SF32LB_PINMUX(PA, 20U, 4U, 0x60U, 3U) -#define PA20_USART3_RTS SF32LB_PINMUX(PA, 20U, 4U, 0x60U, 2U) -#define PA20_USART3_RXD SF32LB_PINMUX(PA, 20U, 4U, 0x60U, 1U) +#define PA20_USART2_RXD SF32LB_PINMUX(PA, 20U, 4U, 0x5CU, 1U) +#define PA20_USART2_RTS SF32LB_PINMUX(PA, 20U, 4U, 0x5CU, 2U) +#define PA20_USART2_CTS SF32LB_PINMUX(PA, 20U, 4U, 0x5CU, 3U) #define PA20_USART3_TXD SF32LB_PINMUX(PA, 20U, 4U, 0x60U, 0U) -/* PA_I2C_UART functions end */ -/* PA_TIM functions start */ +#define PA20_USART3_RXD SF32LB_PINMUX(PA, 20U, 4U, 0x60U, 1U) +#define PA20_USART3_RTS SF32LB_PINMUX(PA, 20U, 4U, 0x60U, 2U) +#define PA20_USART3_CTS SF32LB_PINMUX(PA, 20U, 4U, 0x60U, 3U) #define PA20_GPTIM1_CH1 SF32LB_PINMUX(PA, 20U, 5U, 0x64U, 0U) #define PA20_GPTIM1_CH2 SF32LB_PINMUX(PA, 20U, 5U, 0x64U, 1U) #define PA20_GPTIM1_CH3 SF32LB_PINMUX(PA, 20U, 5U, 0x64U, 2U) #define PA20_GPTIM1_CH4 SF32LB_PINMUX(PA, 20U, 5U, 0x64U, 3U) +#define PA20_GPTIM1_ETR SF32LB_PINMUX(PA, 20U, 5U, 0x6CU, 0U) #define PA20_GPTIM2_CH1 SF32LB_PINMUX(PA, 20U, 5U, 0x68U, 0U) #define PA20_GPTIM2_CH2 SF32LB_PINMUX(PA, 20U, 5U, 0x68U, 1U) #define PA20_GPTIM2_CH3 SF32LB_PINMUX(PA, 20U, 5U, 0x68U, 2U) #define PA20_GPTIM2_CH4 SF32LB_PINMUX(PA, 20U, 5U, 0x68U, 3U) -#define PA20_GPTIM1_ETR SF32LB_PINMUX(PA, 20U, 5U, 0x6CU, 0U) #define PA20_GPTIM2_ETR SF32LB_PINMUX(PA, 20U, 5U, 0x6CU, 1U) #define PA20_LPTIM1_IN SF32LB_PINMUX(PA, 20U, 5U, 0x70U, 0U) #define PA20_LPTIM1_OUT SF32LB_PINMUX(PA, 20U, 5U, 0x70U, 1U) @@ -1185,46 +1104,42 @@ #define PA20_ATIM1_CH1N SF32LB_PINMUX(PA, 20U, 5U, 0x7CU, 0U) #define PA20_ATIM1_CH2N SF32LB_PINMUX(PA, 20U, 5U, 0x7CU, 1U) #define PA20_ATIM1_CH3N SF32LB_PINMUX(PA, 20U, 5U, 0x7CU, 2U) +#define PA20_ATIM1_ETR SF32LB_PINMUX(PA, 20U, 5U, 0x80U, 2U) #define PA20_ATIM1_BK SF32LB_PINMUX(PA, 20U, 5U, 0x80U, 0U) #define PA20_ATIM1_BK2 SF32LB_PINMUX(PA, 20U, 5U, 0x80U, 1U) -#define PA20_ATIM1_ETR SF32LB_PINMUX(PA, 20U, 5U, 0x80U, 2U) -/* PA_TIM functions end */ /* PA21 */ #define PA21_ANALOG SF32LB_PINMUX_ANALOG(PA, 21U) #define PA21_GPIO SF32LB_PINMUX(PA, 21U, 0U, 0U, 0U) -/* PA_I2C_UART functions start */ -#define PA21_I2C1_SDA SF32LB_PINMUX(PA, 21U, 4U, 0x48U, 1U) #define PA21_I2C1_SCL SF32LB_PINMUX(PA, 21U, 4U, 0x48U, 0U) -#define PA21_I2C2_SDA SF32LB_PINMUX(PA, 21U, 4U, 0x4CU, 1U) +#define PA21_I2C1_SDA SF32LB_PINMUX(PA, 21U, 4U, 0x48U, 1U) #define PA21_I2C2_SCL SF32LB_PINMUX(PA, 21U, 4U, 0x4CU, 0U) -#define PA21_I2C3_SDA SF32LB_PINMUX(PA, 21U, 4U, 0x50U, 1U) +#define PA21_I2C2_SDA SF32LB_PINMUX(PA, 21U, 4U, 0x4CU, 1U) #define PA21_I2C3_SCL SF32LB_PINMUX(PA, 21U, 4U, 0x50U, 0U) -#define PA21_I2C4_SDA SF32LB_PINMUX(PA, 21U, 4U, 0x54U, 1U) +#define PA21_I2C3_SDA SF32LB_PINMUX(PA, 21U, 4U, 0x50U, 1U) #define PA21_I2C4_SCL SF32LB_PINMUX(PA, 21U, 4U, 0x54U, 0U) -#define PA21_USART1_CTS SF32LB_PINMUX(PA, 21U, 4U, 0x58U, 3U) -#define PA21_USART1_RTS SF32LB_PINMUX(PA, 21U, 4U, 0x58U, 2U) -#define PA21_USART1_RXD SF32LB_PINMUX(PA, 21U, 4U, 0x58U, 1U) +#define PA21_I2C4_SDA SF32LB_PINMUX(PA, 21U, 4U, 0x54U, 1U) #define PA21_USART1_TXD SF32LB_PINMUX(PA, 21U, 4U, 0x58U, 0U) -#define PA21_USART2_CTS SF32LB_PINMUX(PA, 21U, 4U, 0x5CU, 3U) -#define PA21_USART2_RTS SF32LB_PINMUX(PA, 21U, 4U, 0x5CU, 2U) -#define PA21_USART2_RXD SF32LB_PINMUX(PA, 21U, 4U, 0x5CU, 1U) +#define PA21_USART1_RXD SF32LB_PINMUX(PA, 21U, 4U, 0x58U, 1U) +#define PA21_USART1_RTS SF32LB_PINMUX(PA, 21U, 4U, 0x58U, 2U) +#define PA21_USART1_CTS SF32LB_PINMUX(PA, 21U, 4U, 0x58U, 3U) #define PA21_USART2_TXD SF32LB_PINMUX(PA, 21U, 4U, 0x5CU, 0U) -#define PA21_USART3_CTS SF32LB_PINMUX(PA, 21U, 4U, 0x60U, 3U) -#define PA21_USART3_RTS SF32LB_PINMUX(PA, 21U, 4U, 0x60U, 2U) -#define PA21_USART3_RXD SF32LB_PINMUX(PA, 21U, 4U, 0x60U, 1U) +#define PA21_USART2_RXD SF32LB_PINMUX(PA, 21U, 4U, 0x5CU, 1U) +#define PA21_USART2_RTS SF32LB_PINMUX(PA, 21U, 4U, 0x5CU, 2U) +#define PA21_USART2_CTS SF32LB_PINMUX(PA, 21U, 4U, 0x5CU, 3U) #define PA21_USART3_TXD SF32LB_PINMUX(PA, 21U, 4U, 0x60U, 0U) -/* PA_I2C_UART functions end */ -/* PA_TIM functions start */ +#define PA21_USART3_RXD SF32LB_PINMUX(PA, 21U, 4U, 0x60U, 1U) +#define PA21_USART3_RTS SF32LB_PINMUX(PA, 21U, 4U, 0x60U, 2U) +#define PA21_USART3_CTS SF32LB_PINMUX(PA, 21U, 4U, 0x60U, 3U) #define PA21_GPTIM1_CH1 SF32LB_PINMUX(PA, 21U, 5U, 0x64U, 0U) #define PA21_GPTIM1_CH2 SF32LB_PINMUX(PA, 21U, 5U, 0x64U, 1U) #define PA21_GPTIM1_CH3 SF32LB_PINMUX(PA, 21U, 5U, 0x64U, 2U) #define PA21_GPTIM1_CH4 SF32LB_PINMUX(PA, 21U, 5U, 0x64U, 3U) +#define PA21_GPTIM1_ETR SF32LB_PINMUX(PA, 21U, 5U, 0x6CU, 0U) #define PA21_GPTIM2_CH1 SF32LB_PINMUX(PA, 21U, 5U, 0x68U, 0U) #define PA21_GPTIM2_CH2 SF32LB_PINMUX(PA, 21U, 5U, 0x68U, 1U) #define PA21_GPTIM2_CH3 SF32LB_PINMUX(PA, 21U, 5U, 0x68U, 2U) #define PA21_GPTIM2_CH4 SF32LB_PINMUX(PA, 21U, 5U, 0x68U, 3U) -#define PA21_GPTIM1_ETR SF32LB_PINMUX(PA, 21U, 5U, 0x6CU, 0U) #define PA21_GPTIM2_ETR SF32LB_PINMUX(PA, 21U, 5U, 0x6CU, 1U) #define PA21_LPTIM1_IN SF32LB_PINMUX(PA, 21U, 5U, 0x70U, 0U) #define PA21_LPTIM1_OUT SF32LB_PINMUX(PA, 21U, 5U, 0x70U, 1U) @@ -1239,47 +1154,43 @@ #define PA21_ATIM1_CH1N SF32LB_PINMUX(PA, 21U, 5U, 0x7CU, 0U) #define PA21_ATIM1_CH2N SF32LB_PINMUX(PA, 21U, 5U, 0x7CU, 1U) #define PA21_ATIM1_CH3N SF32LB_PINMUX(PA, 21U, 5U, 0x7CU, 2U) +#define PA21_ATIM1_ETR SF32LB_PINMUX(PA, 21U, 5U, 0x80U, 2U) #define PA21_ATIM1_BK SF32LB_PINMUX(PA, 21U, 5U, 0x80U, 0U) #define PA21_ATIM1_BK2 SF32LB_PINMUX(PA, 21U, 5U, 0x80U, 1U) -#define PA21_ATIM1_ETR SF32LB_PINMUX(PA, 21U, 5U, 0x80U, 2U) -/* PA_TIM functions end */ /* PA22 */ #define PA22_ANALOG SF32LB_PINMUX_ANALOG(PA, 22U) #define PA22_GPIO SF32LB_PINMUX(PA, 22U, 0U, 0U, 0U) #define PA22_PDM1_CLK SF32LB_PINMUX(PA, 22U, 3U, 0U, 0U) -/* PA_I2C_UART functions start */ -#define PA22_I2C1_SDA SF32LB_PINMUX(PA, 22U, 4U, 0x48U, 1U) #define PA22_I2C1_SCL SF32LB_PINMUX(PA, 22U, 4U, 0x48U, 0U) -#define PA22_I2C2_SDA SF32LB_PINMUX(PA, 22U, 4U, 0x4CU, 1U) +#define PA22_I2C1_SDA SF32LB_PINMUX(PA, 22U, 4U, 0x48U, 1U) #define PA22_I2C2_SCL SF32LB_PINMUX(PA, 22U, 4U, 0x4CU, 0U) -#define PA22_I2C3_SDA SF32LB_PINMUX(PA, 22U, 4U, 0x50U, 1U) +#define PA22_I2C2_SDA SF32LB_PINMUX(PA, 22U, 4U, 0x4CU, 1U) #define PA22_I2C3_SCL SF32LB_PINMUX(PA, 22U, 4U, 0x50U, 0U) -#define PA22_I2C4_SDA SF32LB_PINMUX(PA, 22U, 4U, 0x54U, 1U) +#define PA22_I2C3_SDA SF32LB_PINMUX(PA, 22U, 4U, 0x50U, 1U) #define PA22_I2C4_SCL SF32LB_PINMUX(PA, 22U, 4U, 0x54U, 0U) -#define PA22_USART1_CTS SF32LB_PINMUX(PA, 22U, 4U, 0x58U, 3U) -#define PA22_USART1_RTS SF32LB_PINMUX(PA, 22U, 4U, 0x58U, 2U) -#define PA22_USART1_RXD SF32LB_PINMUX(PA, 22U, 4U, 0x58U, 1U) +#define PA22_I2C4_SDA SF32LB_PINMUX(PA, 22U, 4U, 0x54U, 1U) #define PA22_USART1_TXD SF32LB_PINMUX(PA, 22U, 4U, 0x58U, 0U) -#define PA22_USART2_CTS SF32LB_PINMUX(PA, 22U, 4U, 0x5CU, 3U) -#define PA22_USART2_RTS SF32LB_PINMUX(PA, 22U, 4U, 0x5CU, 2U) -#define PA22_USART2_RXD SF32LB_PINMUX(PA, 22U, 4U, 0x5CU, 1U) +#define PA22_USART1_RXD SF32LB_PINMUX(PA, 22U, 4U, 0x58U, 1U) +#define PA22_USART1_RTS SF32LB_PINMUX(PA, 22U, 4U, 0x58U, 2U) +#define PA22_USART1_CTS SF32LB_PINMUX(PA, 22U, 4U, 0x58U, 3U) #define PA22_USART2_TXD SF32LB_PINMUX(PA, 22U, 4U, 0x5CU, 0U) -#define PA22_USART3_CTS SF32LB_PINMUX(PA, 22U, 4U, 0x60U, 3U) -#define PA22_USART3_RTS SF32LB_PINMUX(PA, 22U, 4U, 0x60U, 2U) -#define PA22_USART3_RXD SF32LB_PINMUX(PA, 22U, 4U, 0x60U, 1U) +#define PA22_USART2_RXD SF32LB_PINMUX(PA, 22U, 4U, 0x5CU, 1U) +#define PA22_USART2_RTS SF32LB_PINMUX(PA, 22U, 4U, 0x5CU, 2U) +#define PA22_USART2_CTS SF32LB_PINMUX(PA, 22U, 4U, 0x5CU, 3U) #define PA22_USART3_TXD SF32LB_PINMUX(PA, 22U, 4U, 0x60U, 0U) -/* PA_I2C_UART functions end */ -/* PA_TIM functions start */ +#define PA22_USART3_RXD SF32LB_PINMUX(PA, 22U, 4U, 0x60U, 1U) +#define PA22_USART3_RTS SF32LB_PINMUX(PA, 22U, 4U, 0x60U, 2U) +#define PA22_USART3_CTS SF32LB_PINMUX(PA, 22U, 4U, 0x60U, 3U) #define PA22_GPTIM1_CH1 SF32LB_PINMUX(PA, 22U, 5U, 0x64U, 0U) #define PA22_GPTIM1_CH2 SF32LB_PINMUX(PA, 22U, 5U, 0x64U, 1U) #define PA22_GPTIM1_CH3 SF32LB_PINMUX(PA, 22U, 5U, 0x64U, 2U) #define PA22_GPTIM1_CH4 SF32LB_PINMUX(PA, 22U, 5U, 0x64U, 3U) +#define PA22_GPTIM1_ETR SF32LB_PINMUX(PA, 22U, 5U, 0x6CU, 0U) #define PA22_GPTIM2_CH1 SF32LB_PINMUX(PA, 22U, 5U, 0x68U, 0U) #define PA22_GPTIM2_CH2 SF32LB_PINMUX(PA, 22U, 5U, 0x68U, 1U) #define PA22_GPTIM2_CH3 SF32LB_PINMUX(PA, 22U, 5U, 0x68U, 2U) #define PA22_GPTIM2_CH4 SF32LB_PINMUX(PA, 22U, 5U, 0x68U, 3U) -#define PA22_GPTIM1_ETR SF32LB_PINMUX(PA, 22U, 5U, 0x6CU, 0U) #define PA22_GPTIM2_ETR SF32LB_PINMUX(PA, 22U, 5U, 0x6CU, 1U) #define PA22_LPTIM1_IN SF32LB_PINMUX(PA, 22U, 5U, 0x70U, 0U) #define PA22_LPTIM1_OUT SF32LB_PINMUX(PA, 22U, 5U, 0x70U, 1U) @@ -1294,48 +1205,44 @@ #define PA22_ATIM1_CH1N SF32LB_PINMUX(PA, 22U, 5U, 0x7CU, 0U) #define PA22_ATIM1_CH2N SF32LB_PINMUX(PA, 22U, 5U, 0x7CU, 1U) #define PA22_ATIM1_CH3N SF32LB_PINMUX(PA, 22U, 5U, 0x7CU, 2U) +#define PA22_ATIM1_ETR SF32LB_PINMUX(PA, 22U, 5U, 0x80U, 2U) #define PA22_ATIM1_BK SF32LB_PINMUX(PA, 22U, 5U, 0x80U, 0U) #define PA22_ATIM1_BK2 SF32LB_PINMUX(PA, 22U, 5U, 0x80U, 1U) -#define PA22_ATIM1_ETR SF32LB_PINMUX(PA, 22U, 5U, 0x80U, 2U) -/* PA_TIM functions end */ #define PA22_XTAL32K_XI SF32LB_PINMUX(PA, 22U, 8U, 0U, 0U) /* PA23 */ #define PA23_ANALOG SF32LB_PINMUX_ANALOG(PA, 23U) #define PA23_GPIO SF32LB_PINMUX(PA, 23U, 0U, 0U, 0U) #define PA23_PDM1_DATA SF32LB_PINMUX(PA, 23U, 3U, 0U, 0U) -/* PA_I2C_UART functions start */ -#define PA23_I2C1_SDA SF32LB_PINMUX(PA, 23U, 4U, 0x48U, 1U) #define PA23_I2C1_SCL SF32LB_PINMUX(PA, 23U, 4U, 0x48U, 0U) -#define PA23_I2C2_SDA SF32LB_PINMUX(PA, 23U, 4U, 0x4CU, 1U) +#define PA23_I2C1_SDA SF32LB_PINMUX(PA, 23U, 4U, 0x48U, 1U) #define PA23_I2C2_SCL SF32LB_PINMUX(PA, 23U, 4U, 0x4CU, 0U) -#define PA23_I2C3_SDA SF32LB_PINMUX(PA, 23U, 4U, 0x50U, 1U) +#define PA23_I2C2_SDA SF32LB_PINMUX(PA, 23U, 4U, 0x4CU, 1U) #define PA23_I2C3_SCL SF32LB_PINMUX(PA, 23U, 4U, 0x50U, 0U) -#define PA23_I2C4_SDA SF32LB_PINMUX(PA, 23U, 4U, 0x54U, 1U) +#define PA23_I2C3_SDA SF32LB_PINMUX(PA, 23U, 4U, 0x50U, 1U) #define PA23_I2C4_SCL SF32LB_PINMUX(PA, 23U, 4U, 0x54U, 0U) -#define PA23_USART1_CTS SF32LB_PINMUX(PA, 23U, 4U, 0x58U, 3U) -#define PA23_USART1_RTS SF32LB_PINMUX(PA, 23U, 4U, 0x58U, 2U) -#define PA23_USART1_RXD SF32LB_PINMUX(PA, 23U, 4U, 0x58U, 1U) +#define PA23_I2C4_SDA SF32LB_PINMUX(PA, 23U, 4U, 0x54U, 1U) #define PA23_USART1_TXD SF32LB_PINMUX(PA, 23U, 4U, 0x58U, 0U) -#define PA23_USART2_CTS SF32LB_PINMUX(PA, 23U, 4U, 0x5CU, 3U) -#define PA23_USART2_RTS SF32LB_PINMUX(PA, 23U, 4U, 0x5CU, 2U) -#define PA23_USART2_RXD SF32LB_PINMUX(PA, 23U, 4U, 0x5CU, 1U) +#define PA23_USART1_RXD SF32LB_PINMUX(PA, 23U, 4U, 0x58U, 1U) +#define PA23_USART1_RTS SF32LB_PINMUX(PA, 23U, 4U, 0x58U, 2U) +#define PA23_USART1_CTS SF32LB_PINMUX(PA, 23U, 4U, 0x58U, 3U) #define PA23_USART2_TXD SF32LB_PINMUX(PA, 23U, 4U, 0x5CU, 0U) -#define PA23_USART3_CTS SF32LB_PINMUX(PA, 23U, 4U, 0x60U, 3U) -#define PA23_USART3_RTS SF32LB_PINMUX(PA, 23U, 4U, 0x60U, 2U) -#define PA23_USART3_RXD SF32LB_PINMUX(PA, 23U, 4U, 0x60U, 1U) +#define PA23_USART2_RXD SF32LB_PINMUX(PA, 23U, 4U, 0x5CU, 1U) +#define PA23_USART2_RTS SF32LB_PINMUX(PA, 23U, 4U, 0x5CU, 2U) +#define PA23_USART2_CTS SF32LB_PINMUX(PA, 23U, 4U, 0x5CU, 3U) #define PA23_USART3_TXD SF32LB_PINMUX(PA, 23U, 4U, 0x60U, 0U) -/* PA_I2C_UART functions end */ -/* PA_TIM functions start */ +#define PA23_USART3_RXD SF32LB_PINMUX(PA, 23U, 4U, 0x60U, 1U) +#define PA23_USART3_RTS SF32LB_PINMUX(PA, 23U, 4U, 0x60U, 2U) +#define PA23_USART3_CTS SF32LB_PINMUX(PA, 23U, 4U, 0x60U, 3U) #define PA23_GPTIM1_CH1 SF32LB_PINMUX(PA, 23U, 5U, 0x64U, 0U) #define PA23_GPTIM1_CH2 SF32LB_PINMUX(PA, 23U, 5U, 0x64U, 1U) #define PA23_GPTIM1_CH3 SF32LB_PINMUX(PA, 23U, 5U, 0x64U, 2U) #define PA23_GPTIM1_CH4 SF32LB_PINMUX(PA, 23U, 5U, 0x64U, 3U) +#define PA23_GPTIM1_ETR SF32LB_PINMUX(PA, 23U, 5U, 0x6CU, 0U) #define PA23_GPTIM2_CH1 SF32LB_PINMUX(PA, 23U, 5U, 0x68U, 0U) #define PA23_GPTIM2_CH2 SF32LB_PINMUX(PA, 23U, 5U, 0x68U, 1U) #define PA23_GPTIM2_CH3 SF32LB_PINMUX(PA, 23U, 5U, 0x68U, 2U) #define PA23_GPTIM2_CH4 SF32LB_PINMUX(PA, 23U, 5U, 0x68U, 3U) -#define PA23_GPTIM1_ETR SF32LB_PINMUX(PA, 23U, 5U, 0x6CU, 0U) #define PA23_GPTIM2_ETR SF32LB_PINMUX(PA, 23U, 5U, 0x6CU, 1U) #define PA23_LPTIM1_IN SF32LB_PINMUX(PA, 23U, 5U, 0x70U, 0U) #define PA23_LPTIM1_OUT SF32LB_PINMUX(PA, 23U, 5U, 0x70U, 1U) @@ -1350,10 +1257,9 @@ #define PA23_ATIM1_CH1N SF32LB_PINMUX(PA, 23U, 5U, 0x7CU, 0U) #define PA23_ATIM1_CH2N SF32LB_PINMUX(PA, 23U, 5U, 0x7CU, 1U) #define PA23_ATIM1_CH3N SF32LB_PINMUX(PA, 23U, 5U, 0x7CU, 2U) +#define PA23_ATIM1_ETR SF32LB_PINMUX(PA, 23U, 5U, 0x80U, 2U) #define PA23_ATIM1_BK SF32LB_PINMUX(PA, 23U, 5U, 0x80U, 0U) #define PA23_ATIM1_BK2 SF32LB_PINMUX(PA, 23U, 5U, 0x80U, 1U) -#define PA23_ATIM1_ETR SF32LB_PINMUX(PA, 23U, 5U, 0x80U, 2U) -/* PA_TIM functions end */ #define PA23_XTAL32K_XO SF32LB_PINMUX(PA, 23U, 8U, 0U, 0U) /* PA24 */ @@ -1361,38 +1267,35 @@ #define PA24_GPIO SF32LB_PINMUX(PA, 24U, 0U, 0U, 0U) #define PA24_SPI1_DIO SF32LB_PINMUX(PA, 24U, 2U, 0U, 0U) #define PA24_I2S1_MCLK SF32LB_PINMUX(PA, 24U, 3U, 0U, 0U) -/* PA_I2C_UART functions start */ -#define PA24_I2C1_SDA SF32LB_PINMUX(PA, 24U, 4U, 0x48U, 1U) #define PA24_I2C1_SCL SF32LB_PINMUX(PA, 24U, 4U, 0x48U, 0U) -#define PA24_I2C2_SDA SF32LB_PINMUX(PA, 24U, 4U, 0x4CU, 1U) +#define PA24_I2C1_SDA SF32LB_PINMUX(PA, 24U, 4U, 0x48U, 1U) #define PA24_I2C2_SCL SF32LB_PINMUX(PA, 24U, 4U, 0x4CU, 0U) -#define PA24_I2C3_SDA SF32LB_PINMUX(PA, 24U, 4U, 0x50U, 1U) +#define PA24_I2C2_SDA SF32LB_PINMUX(PA, 24U, 4U, 0x4CU, 1U) #define PA24_I2C3_SCL SF32LB_PINMUX(PA, 24U, 4U, 0x50U, 0U) -#define PA24_I2C4_SDA SF32LB_PINMUX(PA, 24U, 4U, 0x54U, 1U) +#define PA24_I2C3_SDA SF32LB_PINMUX(PA, 24U, 4U, 0x50U, 1U) #define PA24_I2C4_SCL SF32LB_PINMUX(PA, 24U, 4U, 0x54U, 0U) -#define PA24_USART1_CTS SF32LB_PINMUX(PA, 24U, 4U, 0x58U, 3U) -#define PA24_USART1_RTS SF32LB_PINMUX(PA, 24U, 4U, 0x58U, 2U) -#define PA24_USART1_RXD SF32LB_PINMUX(PA, 24U, 4U, 0x58U, 1U) +#define PA24_I2C4_SDA SF32LB_PINMUX(PA, 24U, 4U, 0x54U, 1U) #define PA24_USART1_TXD SF32LB_PINMUX(PA, 24U, 4U, 0x58U, 0U) -#define PA24_USART2_CTS SF32LB_PINMUX(PA, 24U, 4U, 0x5CU, 3U) -#define PA24_USART2_RTS SF32LB_PINMUX(PA, 24U, 4U, 0x5CU, 2U) -#define PA24_USART2_RXD SF32LB_PINMUX(PA, 24U, 4U, 0x5CU, 1U) +#define PA24_USART1_RXD SF32LB_PINMUX(PA, 24U, 4U, 0x58U, 1U) +#define PA24_USART1_RTS SF32LB_PINMUX(PA, 24U, 4U, 0x58U, 2U) +#define PA24_USART1_CTS SF32LB_PINMUX(PA, 24U, 4U, 0x58U, 3U) #define PA24_USART2_TXD SF32LB_PINMUX(PA, 24U, 4U, 0x5CU, 0U) -#define PA24_USART3_CTS SF32LB_PINMUX(PA, 24U, 4U, 0x60U, 3U) -#define PA24_USART3_RTS SF32LB_PINMUX(PA, 24U, 4U, 0x60U, 2U) -#define PA24_USART3_RXD SF32LB_PINMUX(PA, 24U, 4U, 0x60U, 1U) +#define PA24_USART2_RXD SF32LB_PINMUX(PA, 24U, 4U, 0x5CU, 1U) +#define PA24_USART2_RTS SF32LB_PINMUX(PA, 24U, 4U, 0x5CU, 2U) +#define PA24_USART2_CTS SF32LB_PINMUX(PA, 24U, 4U, 0x5CU, 3U) #define PA24_USART3_TXD SF32LB_PINMUX(PA, 24U, 4U, 0x60U, 0U) -/* PA_I2C_UART functions end */ -/* PA_TIM functions start */ +#define PA24_USART3_RXD SF32LB_PINMUX(PA, 24U, 4U, 0x60U, 1U) +#define PA24_USART3_RTS SF32LB_PINMUX(PA, 24U, 4U, 0x60U, 2U) +#define PA24_USART3_CTS SF32LB_PINMUX(PA, 24U, 4U, 0x60U, 3U) #define PA24_GPTIM1_CH1 SF32LB_PINMUX(PA, 24U, 5U, 0x64U, 0U) #define PA24_GPTIM1_CH2 SF32LB_PINMUX(PA, 24U, 5U, 0x64U, 1U) #define PA24_GPTIM1_CH3 SF32LB_PINMUX(PA, 24U, 5U, 0x64U, 2U) #define PA24_GPTIM1_CH4 SF32LB_PINMUX(PA, 24U, 5U, 0x64U, 3U) +#define PA24_GPTIM1_ETR SF32LB_PINMUX(PA, 24U, 5U, 0x6CU, 0U) #define PA24_GPTIM2_CH1 SF32LB_PINMUX(PA, 24U, 5U, 0x68U, 0U) #define PA24_GPTIM2_CH2 SF32LB_PINMUX(PA, 24U, 5U, 0x68U, 1U) #define PA24_GPTIM2_CH3 SF32LB_PINMUX(PA, 24U, 5U, 0x68U, 2U) #define PA24_GPTIM2_CH4 SF32LB_PINMUX(PA, 24U, 5U, 0x68U, 3U) -#define PA24_GPTIM1_ETR SF32LB_PINMUX(PA, 24U, 5U, 0x6CU, 0U) #define PA24_GPTIM2_ETR SF32LB_PINMUX(PA, 24U, 5U, 0x6CU, 1U) #define PA24_LPTIM1_IN SF32LB_PINMUX(PA, 24U, 5U, 0x70U, 0U) #define PA24_LPTIM1_OUT SF32LB_PINMUX(PA, 24U, 5U, 0x70U, 1U) @@ -1407,10 +1310,9 @@ #define PA24_ATIM1_CH1N SF32LB_PINMUX(PA, 24U, 5U, 0x7CU, 0U) #define PA24_ATIM1_CH2N SF32LB_PINMUX(PA, 24U, 5U, 0x7CU, 1U) #define PA24_ATIM1_CH3N SF32LB_PINMUX(PA, 24U, 5U, 0x7CU, 2U) +#define PA24_ATIM1_ETR SF32LB_PINMUX(PA, 24U, 5U, 0x80U, 2U) #define PA24_ATIM1_BK SF32LB_PINMUX(PA, 24U, 5U, 0x80U, 0U) #define PA24_ATIM1_BK2 SF32LB_PINMUX(PA, 24U, 5U, 0x80U, 1U) -#define PA24_ATIM1_ETR SF32LB_PINMUX(PA, 24U, 5U, 0x80U, 2U) -/* PA_TIM functions end */ #define PA24_WKUP_PIN0 SF32LB_PINMUX(PA, 24U, 8U, 0U, 0U) /* PA25 */ @@ -1418,38 +1320,35 @@ #define PA25_GPIO SF32LB_PINMUX(PA, 25U, 0U, 0U, 0U) #define PA25_SPI1_DI SF32LB_PINMUX(PA, 25U, 2U, 0U, 0U) #define PA25_I2S1_SDO SF32LB_PINMUX(PA, 25U, 3U, 0U, 0U) -/* PA_I2C_UART functions start */ -#define PA25_I2C1_SDA SF32LB_PINMUX(PA, 25U, 4U, 0x48U, 1U) #define PA25_I2C1_SCL SF32LB_PINMUX(PA, 25U, 4U, 0x48U, 0U) -#define PA25_I2C2_SDA SF32LB_PINMUX(PA, 25U, 4U, 0x4CU, 1U) +#define PA25_I2C1_SDA SF32LB_PINMUX(PA, 25U, 4U, 0x48U, 1U) #define PA25_I2C2_SCL SF32LB_PINMUX(PA, 25U, 4U, 0x4CU, 0U) -#define PA25_I2C3_SDA SF32LB_PINMUX(PA, 25U, 4U, 0x50U, 1U) +#define PA25_I2C2_SDA SF32LB_PINMUX(PA, 25U, 4U, 0x4CU, 1U) #define PA25_I2C3_SCL SF32LB_PINMUX(PA, 25U, 4U, 0x50U, 0U) -#define PA25_I2C4_SDA SF32LB_PINMUX(PA, 25U, 4U, 0x54U, 1U) +#define PA25_I2C3_SDA SF32LB_PINMUX(PA, 25U, 4U, 0x50U, 1U) #define PA25_I2C4_SCL SF32LB_PINMUX(PA, 25U, 4U, 0x54U, 0U) -#define PA25_USART1_CTS SF32LB_PINMUX(PA, 25U, 4U, 0x58U, 3U) -#define PA25_USART1_RTS SF32LB_PINMUX(PA, 25U, 4U, 0x58U, 2U) -#define PA25_USART1_RXD SF32LB_PINMUX(PA, 25U, 4U, 0x58U, 1U) +#define PA25_I2C4_SDA SF32LB_PINMUX(PA, 25U, 4U, 0x54U, 1U) #define PA25_USART1_TXD SF32LB_PINMUX(PA, 25U, 4U, 0x58U, 0U) -#define PA25_USART2_CTS SF32LB_PINMUX(PA, 25U, 4U, 0x5CU, 3U) -#define PA25_USART2_RTS SF32LB_PINMUX(PA, 25U, 4U, 0x5CU, 2U) -#define PA25_USART2_RXD SF32LB_PINMUX(PA, 25U, 4U, 0x5CU, 1U) +#define PA25_USART1_RXD SF32LB_PINMUX(PA, 25U, 4U, 0x58U, 1U) +#define PA25_USART1_RTS SF32LB_PINMUX(PA, 25U, 4U, 0x58U, 2U) +#define PA25_USART1_CTS SF32LB_PINMUX(PA, 25U, 4U, 0x58U, 3U) #define PA25_USART2_TXD SF32LB_PINMUX(PA, 25U, 4U, 0x5CU, 0U) -#define PA25_USART3_CTS SF32LB_PINMUX(PA, 25U, 4U, 0x60U, 3U) -#define PA25_USART3_RTS SF32LB_PINMUX(PA, 25U, 4U, 0x60U, 2U) -#define PA25_USART3_RXD SF32LB_PINMUX(PA, 25U, 4U, 0x60U, 1U) +#define PA25_USART2_RXD SF32LB_PINMUX(PA, 25U, 4U, 0x5CU, 1U) +#define PA25_USART2_RTS SF32LB_PINMUX(PA, 25U, 4U, 0x5CU, 2U) +#define PA25_USART2_CTS SF32LB_PINMUX(PA, 25U, 4U, 0x5CU, 3U) #define PA25_USART3_TXD SF32LB_PINMUX(PA, 25U, 4U, 0x60U, 0U) -/* PA_I2C_UART functions end */ -/* PA_TIM functions start */ +#define PA25_USART3_RXD SF32LB_PINMUX(PA, 25U, 4U, 0x60U, 1U) +#define PA25_USART3_RTS SF32LB_PINMUX(PA, 25U, 4U, 0x60U, 2U) +#define PA25_USART3_CTS SF32LB_PINMUX(PA, 25U, 4U, 0x60U, 3U) #define PA25_GPTIM1_CH1 SF32LB_PINMUX(PA, 25U, 5U, 0x64U, 0U) #define PA25_GPTIM1_CH2 SF32LB_PINMUX(PA, 25U, 5U, 0x64U, 1U) #define PA25_GPTIM1_CH3 SF32LB_PINMUX(PA, 25U, 5U, 0x64U, 2U) #define PA25_GPTIM1_CH4 SF32LB_PINMUX(PA, 25U, 5U, 0x64U, 3U) +#define PA25_GPTIM1_ETR SF32LB_PINMUX(PA, 25U, 5U, 0x6CU, 0U) #define PA25_GPTIM2_CH1 SF32LB_PINMUX(PA, 25U, 5U, 0x68U, 0U) #define PA25_GPTIM2_CH2 SF32LB_PINMUX(PA, 25U, 5U, 0x68U, 1U) #define PA25_GPTIM2_CH3 SF32LB_PINMUX(PA, 25U, 5U, 0x68U, 2U) #define PA25_GPTIM2_CH4 SF32LB_PINMUX(PA, 25U, 5U, 0x68U, 3U) -#define PA25_GPTIM1_ETR SF32LB_PINMUX(PA, 25U, 5U, 0x6CU, 0U) #define PA25_GPTIM2_ETR SF32LB_PINMUX(PA, 25U, 5U, 0x6CU, 1U) #define PA25_LPTIM1_IN SF32LB_PINMUX(PA, 25U, 5U, 0x70U, 0U) #define PA25_LPTIM1_OUT SF32LB_PINMUX(PA, 25U, 5U, 0x70U, 1U) @@ -1464,48 +1363,44 @@ #define PA25_ATIM1_CH1N SF32LB_PINMUX(PA, 25U, 5U, 0x7CU, 0U) #define PA25_ATIM1_CH2N SF32LB_PINMUX(PA, 25U, 5U, 0x7CU, 1U) #define PA25_ATIM1_CH3N SF32LB_PINMUX(PA, 25U, 5U, 0x7CU, 2U) +#define PA25_ATIM1_ETR SF32LB_PINMUX(PA, 25U, 5U, 0x80U, 2U) #define PA25_ATIM1_BK SF32LB_PINMUX(PA, 25U, 5U, 0x80U, 0U) #define PA25_ATIM1_BK2 SF32LB_PINMUX(PA, 25U, 5U, 0x80U, 1U) -#define PA25_ATIM1_ETR SF32LB_PINMUX(PA, 25U, 5U, 0x80U, 2U) -/* PA_TIM functions end */ #define PA25_XTAL32K_EXT SF32LB_PINMUX(PA, 25U, 7U, 0U, 0U) #define PA25_WKUP_PIN1 SF32LB_PINMUX(PA, 25U, 8U, 0U, 0U) /* PA26 */ #define PA26_ANALOG SF32LB_PINMUX_ANALOG(PA, 26U) #define PA26_GPIO SF32LB_PINMUX(PA, 26U, 0U, 0U, 0U) -/* PA_I2C_UART functions start */ -#define PA26_I2C1_SDA SF32LB_PINMUX(PA, 26U, 4U, 0x48U, 1U) #define PA26_I2C1_SCL SF32LB_PINMUX(PA, 26U, 4U, 0x48U, 0U) -#define PA26_I2C2_SDA SF32LB_PINMUX(PA, 26U, 4U, 0x4CU, 1U) +#define PA26_I2C1_SDA SF32LB_PINMUX(PA, 26U, 4U, 0x48U, 1U) #define PA26_I2C2_SCL SF32LB_PINMUX(PA, 26U, 4U, 0x4CU, 0U) -#define PA26_I2C3_SDA SF32LB_PINMUX(PA, 26U, 4U, 0x50U, 1U) +#define PA26_I2C2_SDA SF32LB_PINMUX(PA, 26U, 4U, 0x4CU, 1U) #define PA26_I2C3_SCL SF32LB_PINMUX(PA, 26U, 4U, 0x50U, 0U) -#define PA26_I2C4_SDA SF32LB_PINMUX(PA, 26U, 4U, 0x54U, 1U) +#define PA26_I2C3_SDA SF32LB_PINMUX(PA, 26U, 4U, 0x50U, 1U) #define PA26_I2C4_SCL SF32LB_PINMUX(PA, 26U, 4U, 0x54U, 0U) -#define PA26_USART1_CTS SF32LB_PINMUX(PA, 26U, 4U, 0x58U, 3U) -#define PA26_USART1_RTS SF32LB_PINMUX(PA, 26U, 4U, 0x58U, 2U) -#define PA26_USART1_RXD SF32LB_PINMUX(PA, 26U, 4U, 0x58U, 1U) +#define PA26_I2C4_SDA SF32LB_PINMUX(PA, 26U, 4U, 0x54U, 1U) #define PA26_USART1_TXD SF32LB_PINMUX(PA, 26U, 4U, 0x58U, 0U) -#define PA26_USART2_CTS SF32LB_PINMUX(PA, 26U, 4U, 0x5CU, 3U) -#define PA26_USART2_RTS SF32LB_PINMUX(PA, 26U, 4U, 0x5CU, 2U) -#define PA26_USART2_RXD SF32LB_PINMUX(PA, 26U, 4U, 0x5CU, 1U) +#define PA26_USART1_RXD SF32LB_PINMUX(PA, 26U, 4U, 0x58U, 1U) +#define PA26_USART1_RTS SF32LB_PINMUX(PA, 26U, 4U, 0x58U, 2U) +#define PA26_USART1_CTS SF32LB_PINMUX(PA, 26U, 4U, 0x58U, 3U) #define PA26_USART2_TXD SF32LB_PINMUX(PA, 26U, 4U, 0x5CU, 0U) -#define PA26_USART3_CTS SF32LB_PINMUX(PA, 26U, 4U, 0x60U, 3U) -#define PA26_USART3_RTS SF32LB_PINMUX(PA, 26U, 4U, 0x60U, 2U) -#define PA26_USART3_RXD SF32LB_PINMUX(PA, 26U, 4U, 0x60U, 1U) +#define PA26_USART2_RXD SF32LB_PINMUX(PA, 26U, 4U, 0x5CU, 1U) +#define PA26_USART2_RTS SF32LB_PINMUX(PA, 26U, 4U, 0x5CU, 2U) +#define PA26_USART2_CTS SF32LB_PINMUX(PA, 26U, 4U, 0x5CU, 3U) #define PA26_USART3_TXD SF32LB_PINMUX(PA, 26U, 4U, 0x60U, 0U) -/* PA_I2C_UART functions end */ -/* PA_TIM functions start */ +#define PA26_USART3_RXD SF32LB_PINMUX(PA, 26U, 4U, 0x60U, 1U) +#define PA26_USART3_RTS SF32LB_PINMUX(PA, 26U, 4U, 0x60U, 2U) +#define PA26_USART3_CTS SF32LB_PINMUX(PA, 26U, 4U, 0x60U, 3U) #define PA26_GPTIM1_CH1 SF32LB_PINMUX(PA, 26U, 5U, 0x64U, 0U) #define PA26_GPTIM1_CH2 SF32LB_PINMUX(PA, 26U, 5U, 0x64U, 1U) #define PA26_GPTIM1_CH3 SF32LB_PINMUX(PA, 26U, 5U, 0x64U, 2U) #define PA26_GPTIM1_CH4 SF32LB_PINMUX(PA, 26U, 5U, 0x64U, 3U) +#define PA26_GPTIM1_ETR SF32LB_PINMUX(PA, 26U, 5U, 0x6CU, 0U) #define PA26_GPTIM2_CH1 SF32LB_PINMUX(PA, 26U, 5U, 0x68U, 0U) #define PA26_GPTIM2_CH2 SF32LB_PINMUX(PA, 26U, 5U, 0x68U, 1U) #define PA26_GPTIM2_CH3 SF32LB_PINMUX(PA, 26U, 5U, 0x68U, 2U) #define PA26_GPTIM2_CH4 SF32LB_PINMUX(PA, 26U, 5U, 0x68U, 3U) -#define PA26_GPTIM1_ETR SF32LB_PINMUX(PA, 26U, 5U, 0x6CU, 0U) #define PA26_GPTIM2_ETR SF32LB_PINMUX(PA, 26U, 5U, 0x6CU, 1U) #define PA26_LPTIM1_IN SF32LB_PINMUX(PA, 26U, 5U, 0x70U, 0U) #define PA26_LPTIM1_OUT SF32LB_PINMUX(PA, 26U, 5U, 0x70U, 1U) @@ -1520,16 +1415,14 @@ #define PA26_ATIM1_CH1N SF32LB_PINMUX(PA, 26U, 5U, 0x7CU, 0U) #define PA26_ATIM1_CH2N SF32LB_PINMUX(PA, 26U, 5U, 0x7CU, 1U) #define PA26_ATIM1_CH3N SF32LB_PINMUX(PA, 26U, 5U, 0x7CU, 2U) +#define PA26_ATIM1_ETR SF32LB_PINMUX(PA, 26U, 5U, 0x80U, 2U) #define PA26_ATIM1_BK SF32LB_PINMUX(PA, 26U, 5U, 0x80U, 0U) #define PA26_ATIM1_BK2 SF32LB_PINMUX(PA, 26U, 5U, 0x80U, 1U) -#define PA26_ATIM1_ETR SF32LB_PINMUX(PA, 26U, 5U, 0x80U, 2U) -/* PA_TIM functions end */ #define PA26_WKUP_PIN2 SF32LB_PINMUX(PA, 26U, 8U, 0U, 0U) /* PA27 */ #define PA27_ANALOG SF32LB_PINMUX_ANALOG(PA, 27U) #define PA27_GPIO SF32LB_PINMUX(PA, 27U, 0U, 0U, 0U) -/* PA_I2C_UART functions start */ #define PA27_I2C1_SCL SF32LB_PINMUX(PA, 27U, 4U, 0x48U, 0U) #define PA27_I2C1_SDA SF32LB_PINMUX(PA, 27U, 4U, 0x48U, 1U) #define PA27_I2C2_SCL SF32LB_PINMUX(PA, 27U, 4U, 0x4CU, 0U) @@ -1538,29 +1431,27 @@ #define PA27_I2C3_SDA SF32LB_PINMUX(PA, 27U, 4U, 0x50U, 1U) #define PA27_I2C4_SCL SF32LB_PINMUX(PA, 27U, 4U, 0x54U, 0U) #define PA27_I2C4_SDA SF32LB_PINMUX(PA, 27U, 4U, 0x54U, 1U) -#define PA27_USART1_CTS SF32LB_PINMUX(PA, 27U, 4U, 0x58U, 0U) -#define PA27_USART1_RTS SF32LB_PINMUX(PA, 27U, 4U, 0x58U, 1U) -#define PA27_USART1_RXD SF32LB_PINMUX(PA, 27U, 4U, 0x58U, 2U) -#define PA27_USART1_TXD SF32LB_PINMUX(PA, 27U, 4U, 0x58U, 3U) -#define PA27_USART2_CTS SF32LB_PINMUX(PA, 27U, 4U, 0x5CU, 0U) -#define PA27_USART2_RTS SF32LB_PINMUX(PA, 27U, 4U, 0x5CU, 1U) -#define PA27_USART2_RXD SF32LB_PINMUX(PA, 27U, 4U, 0x5CU, 2U) -#define PA27_USART2_TXD SF32LB_PINMUX(PA, 27U, 4U, 0x5CU, 3U) -#define PA27_USART3_CTS SF32LB_PINMUX(PA, 27U, 4U, 0x60U, 0U) -#define PA27_USART3_RTS SF32LB_PINMUX(PA, 27U, 4U, 0x60U, 1U) -#define PA27_USART3_RXD SF32LB_PINMUX(PA, 27U, 4U, 0x60U, 2U) -#define PA27_USART3_TXD SF32LB_PINMUX(PA, 27U, 4U, 0x60U, 3U) -/* PA_I2C_UART functions end */ -/* PA_TIM functions start */ +#define PA27_USART1_TXD SF32LB_PINMUX(PA, 27U, 4U, 0x58U, 0U) +#define PA27_USART1_RXD SF32LB_PINMUX(PA, 27U, 4U, 0x58U, 1U) +#define PA27_USART1_RTS SF32LB_PINMUX(PA, 27U, 4U, 0x58U, 2U) +#define PA27_USART1_CTS SF32LB_PINMUX(PA, 27U, 4U, 0x58U, 3U) +#define PA27_USART2_TXD SF32LB_PINMUX(PA, 27U, 4U, 0x5CU, 0U) +#define PA27_USART2_RXD SF32LB_PINMUX(PA, 27U, 4U, 0x5CU, 1U) +#define PA27_USART2_RTS SF32LB_PINMUX(PA, 27U, 4U, 0x5CU, 2U) +#define PA27_USART2_CTS SF32LB_PINMUX(PA, 27U, 4U, 0x5CU, 3U) +#define PA27_USART3_TXD SF32LB_PINMUX(PA, 27U, 4U, 0x60U, 0U) +#define PA27_USART3_RXD SF32LB_PINMUX(PA, 27U, 4U, 0x60U, 1U) +#define PA27_USART3_RTS SF32LB_PINMUX(PA, 27U, 4U, 0x60U, 2U) +#define PA27_USART3_CTS SF32LB_PINMUX(PA, 27U, 4U, 0x60U, 3U) #define PA27_GPTIM1_CH1 SF32LB_PINMUX(PA, 27U, 5U, 0x64U, 0U) #define PA27_GPTIM1_CH2 SF32LB_PINMUX(PA, 27U, 5U, 0x64U, 1U) #define PA27_GPTIM1_CH3 SF32LB_PINMUX(PA, 27U, 5U, 0x64U, 2U) #define PA27_GPTIM1_CH4 SF32LB_PINMUX(PA, 27U, 5U, 0x64U, 3U) +#define PA27_GPTIM1_ETR SF32LB_PINMUX(PA, 27U, 5U, 0x6CU, 0U) #define PA27_GPTIM2_CH1 SF32LB_PINMUX(PA, 27U, 5U, 0x68U, 0U) #define PA27_GPTIM2_CH2 SF32LB_PINMUX(PA, 27U, 5U, 0x68U, 1U) #define PA27_GPTIM2_CH3 SF32LB_PINMUX(PA, 27U, 5U, 0x68U, 2U) #define PA27_GPTIM2_CH4 SF32LB_PINMUX(PA, 27U, 5U, 0x68U, 3U) -#define PA27_GPTIM1_ETR SF32LB_PINMUX(PA, 27U, 5U, 0x6CU, 0U) #define PA27_GPTIM2_ETR SF32LB_PINMUX(PA, 27U, 5U, 0x6CU, 1U) #define PA27_LPTIM1_IN SF32LB_PINMUX(PA, 27U, 5U, 0x70U, 0U) #define PA27_LPTIM1_OUT SF32LB_PINMUX(PA, 27U, 5U, 0x70U, 1U) @@ -1575,10 +1466,9 @@ #define PA27_ATIM1_CH1N SF32LB_PINMUX(PA, 27U, 5U, 0x7CU, 0U) #define PA27_ATIM1_CH2N SF32LB_PINMUX(PA, 27U, 5U, 0x7CU, 1U) #define PA27_ATIM1_CH3N SF32LB_PINMUX(PA, 27U, 5U, 0x7CU, 2U) +#define PA27_ATIM1_ETR SF32LB_PINMUX(PA, 27U, 5U, 0x80U, 2U) #define PA27_ATIM1_BK SF32LB_PINMUX(PA, 27U, 5U, 0x80U, 0U) #define PA27_ATIM1_BK2 SF32LB_PINMUX(PA, 27U, 5U, 0x80U, 1U) -#define PA27_ATIM1_ETR SF32LB_PINMUX(PA, 27U, 5U, 0x80U, 2U) -/* PA_TIM functions end */ #define PA27_WKUP_PIN3 SF32LB_PINMUX(PA, 27U, 8U, 0U, 0U) /* PA28 */ @@ -1586,7 +1476,6 @@ #define PA28_GPIO SF32LB_PINMUX(PA, 28U, 0U, 0U, 0U) #define PA28_SPI1_CLK SF32LB_PINMUX(PA, 28U, 2U, 0U, 0U) #define PA28_I2S1_SDI SF32LB_PINMUX(PA, 28U, 3U, 0U, 0U) -/* PA_I2C_UART functions start */ #define PA28_I2C1_SCL SF32LB_PINMUX(PA, 28U, 4U, 0x48U, 0U) #define PA28_I2C1_SDA SF32LB_PINMUX(PA, 28U, 4U, 0x48U, 1U) #define PA28_I2C2_SCL SF32LB_PINMUX(PA, 28U, 4U, 0x4CU, 0U) @@ -1595,29 +1484,27 @@ #define PA28_I2C3_SDA SF32LB_PINMUX(PA, 28U, 4U, 0x50U, 1U) #define PA28_I2C4_SCL SF32LB_PINMUX(PA, 28U, 4U, 0x54U, 0U) #define PA28_I2C4_SDA SF32LB_PINMUX(PA, 28U, 4U, 0x54U, 1U) -#define PA28_USART1_CTS SF32LB_PINMUX(PA, 28U, 4U, 0x58U, 0U) -#define PA28_USART1_RTS SF32LB_PINMUX(PA, 28U, 4U, 0x58U, 1U) -#define PA28_USART1_RXD SF32LB_PINMUX(PA, 28U, 4U, 0x58U, 2U) -#define PA28_USART1_TXD SF32LB_PINMUX(PA, 28U, 4U, 0x58U, 3U) -#define PA28_USART2_CTS SF32LB_PINMUX(PA, 28U, 4U, 0x5CU, 0U) -#define PA28_USART2_RTS SF32LB_PINMUX(PA, 28U, 4U, 0x5CU, 1U) -#define PA28_USART2_RXD SF32LB_PINMUX(PA, 28U, 4U, 0x5CU, 2U) -#define PA28_USART2_TXD SF32LB_PINMUX(PA, 28U, 4U, 0x5CU, 3U) -#define PA28_USART3_CTS SF32LB_PINMUX(PA, 28U, 4U, 0x60U, 0U) -#define PA28_USART3_RTS SF32LB_PINMUX(PA, 28U, 4U, 0x60U, 1U) -#define PA28_USART3_RXD SF32LB_PINMUX(PA, 28U, 4U, 0x60U, 2U) -#define PA28_USART3_TXD SF32LB_PINMUX(PA, 28U, 4U, 0x60U, 3U) -/* PA_I2C_UART functions end */ -/* PA_TIM functions start */ +#define PA28_USART1_TXD SF32LB_PINMUX(PA, 28U, 4U, 0x58U, 0U) +#define PA28_USART1_RXD SF32LB_PINMUX(PA, 28U, 4U, 0x58U, 1U) +#define PA28_USART1_RTS SF32LB_PINMUX(PA, 28U, 4U, 0x58U, 2U) +#define PA28_USART1_CTS SF32LB_PINMUX(PA, 28U, 4U, 0x58U, 3U) +#define PA28_USART2_TXD SF32LB_PINMUX(PA, 28U, 4U, 0x5CU, 0U) +#define PA28_USART2_RXD SF32LB_PINMUX(PA, 28U, 4U, 0x5CU, 1U) +#define PA28_USART2_RTS SF32LB_PINMUX(PA, 28U, 4U, 0x5CU, 2U) +#define PA28_USART2_CTS SF32LB_PINMUX(PA, 28U, 4U, 0x5CU, 3U) +#define PA28_USART3_TXD SF32LB_PINMUX(PA, 28U, 4U, 0x60U, 0U) +#define PA28_USART3_RXD SF32LB_PINMUX(PA, 28U, 4U, 0x60U, 1U) +#define PA28_USART3_RTS SF32LB_PINMUX(PA, 28U, 4U, 0x60U, 2U) +#define PA28_USART3_CTS SF32LB_PINMUX(PA, 28U, 4U, 0x60U, 3U) #define PA28_GPTIM1_CH1 SF32LB_PINMUX(PA, 28U, 5U, 0x64U, 0U) #define PA28_GPTIM1_CH2 SF32LB_PINMUX(PA, 28U, 5U, 0x64U, 1U) #define PA28_GPTIM1_CH3 SF32LB_PINMUX(PA, 28U, 5U, 0x64U, 2U) #define PA28_GPTIM1_CH4 SF32LB_PINMUX(PA, 28U, 5U, 0x64U, 3U) +#define PA28_GPTIM1_ETR SF32LB_PINMUX(PA, 28U, 5U, 0x6CU, 0U) #define PA28_GPTIM2_CH1 SF32LB_PINMUX(PA, 28U, 5U, 0x68U, 0U) #define PA28_GPTIM2_CH2 SF32LB_PINMUX(PA, 28U, 5U, 0x68U, 1U) #define PA28_GPTIM2_CH3 SF32LB_PINMUX(PA, 28U, 5U, 0x68U, 2U) #define PA28_GPTIM2_CH4 SF32LB_PINMUX(PA, 28U, 5U, 0x68U, 3U) -#define PA28_GPTIM1_ETR SF32LB_PINMUX(PA, 28U, 5U, 0x6CU, 0U) #define PA28_GPTIM2_ETR SF32LB_PINMUX(PA, 28U, 5U, 0x6CU, 1U) #define PA28_LPTIM1_IN SF32LB_PINMUX(PA, 28U, 5U, 0x70U, 0U) #define PA28_LPTIM1_OUT SF32LB_PINMUX(PA, 28U, 5U, 0x70U, 1U) @@ -1632,10 +1519,9 @@ #define PA28_ATIM1_CH1N SF32LB_PINMUX(PA, 28U, 5U, 0x7CU, 0U) #define PA28_ATIM1_CH2N SF32LB_PINMUX(PA, 28U, 5U, 0x7CU, 1U) #define PA28_ATIM1_CH3N SF32LB_PINMUX(PA, 28U, 5U, 0x7CU, 2U) +#define PA28_ATIM1_ETR SF32LB_PINMUX(PA, 28U, 5U, 0x80U, 2U) #define PA28_ATIM1_BK SF32LB_PINMUX(PA, 28U, 5U, 0x80U, 0U) #define PA28_ATIM1_BK2 SF32LB_PINMUX(PA, 28U, 5U, 0x80U, 1U) -#define PA28_ATIM1_ETR SF32LB_PINMUX(PA, 28U, 5U, 0x80U, 2U) -/* PA_TIM functions end */ #define PA28_GPADC_CH0 SF32LB_PINMUX(PA, 28U, 7U, 0U, 0U) /* PA29 */ @@ -1643,7 +1529,6 @@ #define PA29_GPIO SF32LB_PINMUX(PA, 29U, 0U, 0U, 0U) #define PA29_SPI1_CS SF32LB_PINMUX(PA, 29U, 2U, 0U, 0U) #define PA29_I2S1_BCK SF32LB_PINMUX(PA, 29U, 3U, 0U, 0U) -/* PA_I2C_UART functions start */ #define PA29_I2C1_SCL SF32LB_PINMUX(PA, 29U, 4U, 0x48U, 0U) #define PA29_I2C1_SDA SF32LB_PINMUX(PA, 29U, 4U, 0x48U, 1U) #define PA29_I2C2_SCL SF32LB_PINMUX(PA, 29U, 4U, 0x4CU, 0U) @@ -1652,29 +1537,27 @@ #define PA29_I2C3_SDA SF32LB_PINMUX(PA, 29U, 4U, 0x50U, 1U) #define PA29_I2C4_SCL SF32LB_PINMUX(PA, 29U, 4U, 0x54U, 0U) #define PA29_I2C4_SDA SF32LB_PINMUX(PA, 29U, 4U, 0x54U, 1U) -#define PA29_USART1_CTS SF32LB_PINMUX(PA, 29U, 4U, 0x58U, 0U) -#define PA29_USART1_RTS SF32LB_PINMUX(PA, 29U, 4U, 0x58U, 1U) -#define PA29_USART1_RXD SF32LB_PINMUX(PA, 29U, 4U, 0x58U, 2U) -#define PA29_USART1_TXD SF32LB_PINMUX(PA, 29U, 4U, 0x58U, 3U) -#define PA29_USART2_CTS SF32LB_PINMUX(PA, 29U, 4U, 0x5CU, 0U) -#define PA29_USART2_RTS SF32LB_PINMUX(PA, 29U, 4U, 0x5CU, 1U) -#define PA29_USART2_RXD SF32LB_PINMUX(PA, 29U, 4U, 0x5CU, 2U) -#define PA29_USART2_TXD SF32LB_PINMUX(PA, 29U, 4U, 0x5CU, 3U) -#define PA29_USART3_CTS SF32LB_PINMUX(PA, 29U, 4U, 0x60U, 0U) -#define PA29_USART3_RTS SF32LB_PINMUX(PA, 29U, 4U, 0x60U, 1U) -#define PA29_USART3_RXD SF32LB_PINMUX(PA, 29U, 4U, 0x60U, 2U) -#define PA29_USART3_TXD SF32LB_PINMUX(PA, 29U, 4U, 0x60U, 3U) -/* PA_I2C_UART functions end */ -/* PA_TIM functions start */ +#define PA29_USART1_TXD SF32LB_PINMUX(PA, 29U, 4U, 0x58U, 0U) +#define PA29_USART1_RXD SF32LB_PINMUX(PA, 29U, 4U, 0x58U, 1U) +#define PA29_USART1_RTS SF32LB_PINMUX(PA, 29U, 4U, 0x58U, 2U) +#define PA29_USART1_CTS SF32LB_PINMUX(PA, 29U, 4U, 0x58U, 3U) +#define PA29_USART2_TXD SF32LB_PINMUX(PA, 29U, 4U, 0x5CU, 0U) +#define PA29_USART2_RXD SF32LB_PINMUX(PA, 29U, 4U, 0x5CU, 1U) +#define PA29_USART2_RTS SF32LB_PINMUX(PA, 29U, 4U, 0x5CU, 2U) +#define PA29_USART2_CTS SF32LB_PINMUX(PA, 29U, 4U, 0x5CU, 3U) +#define PA29_USART3_TXD SF32LB_PINMUX(PA, 29U, 4U, 0x60U, 0U) +#define PA29_USART3_RXD SF32LB_PINMUX(PA, 29U, 4U, 0x60U, 1U) +#define PA29_USART3_RTS SF32LB_PINMUX(PA, 29U, 4U, 0x60U, 2U) +#define PA29_USART3_CTS SF32LB_PINMUX(PA, 29U, 4U, 0x60U, 3U) #define PA29_GPTIM1_CH1 SF32LB_PINMUX(PA, 29U, 5U, 0x64U, 0U) #define PA29_GPTIM1_CH2 SF32LB_PINMUX(PA, 29U, 5U, 0x64U, 1U) #define PA29_GPTIM1_CH3 SF32LB_PINMUX(PA, 29U, 5U, 0x64U, 2U) #define PA29_GPTIM1_CH4 SF32LB_PINMUX(PA, 29U, 5U, 0x64U, 3U) +#define PA29_GPTIM1_ETR SF32LB_PINMUX(PA, 29U, 5U, 0x6CU, 0U) #define PA29_GPTIM2_CH1 SF32LB_PINMUX(PA, 29U, 5U, 0x68U, 0U) #define PA29_GPTIM2_CH2 SF32LB_PINMUX(PA, 29U, 5U, 0x68U, 1U) #define PA29_GPTIM2_CH3 SF32LB_PINMUX(PA, 29U, 5U, 0x68U, 2U) #define PA29_GPTIM2_CH4 SF32LB_PINMUX(PA, 29U, 5U, 0x68U, 3U) -#define PA29_GPTIM1_ETR SF32LB_PINMUX(PA, 29U, 5U, 0x6CU, 0U) #define PA29_GPTIM2_ETR SF32LB_PINMUX(PA, 29U, 5U, 0x6CU, 1U) #define PA29_LPTIM1_IN SF32LB_PINMUX(PA, 29U, 5U, 0x70U, 0U) #define PA29_LPTIM1_OUT SF32LB_PINMUX(PA, 29U, 5U, 0x70U, 1U) @@ -1689,10 +1572,9 @@ #define PA29_ATIM1_CH1N SF32LB_PINMUX(PA, 29U, 5U, 0x7CU, 0U) #define PA29_ATIM1_CH2N SF32LB_PINMUX(PA, 29U, 5U, 0x7CU, 1U) #define PA29_ATIM1_CH3N SF32LB_PINMUX(PA, 29U, 5U, 0x7CU, 2U) +#define PA29_ATIM1_ETR SF32LB_PINMUX(PA, 29U, 5U, 0x80U, 2U) #define PA29_ATIM1_BK SF32LB_PINMUX(PA, 29U, 5U, 0x80U, 0U) #define PA29_ATIM1_BK2 SF32LB_PINMUX(PA, 29U, 5U, 0x80U, 1U) -#define PA29_ATIM1_ETR SF32LB_PINMUX(PA, 29U, 5U, 0x80U, 2U) -/* PA_TIM functions end */ #define PA29_GPADC_CH1 SF32LB_PINMUX(PA, 29U, 7U, 0U, 0U) /* PA30 */ @@ -1700,7 +1582,6 @@ #define PA30_GPIO SF32LB_PINMUX(PA, 30U, 0U, 0U, 0U) #define PA30_EFUSE_PWR SF32LB_PINMUX(PA, 30U, 2U, 0U, 0U) #define PA30_I2S1_LRCK SF32LB_PINMUX(PA, 30U, 3U, 0U, 0U) -/* PA_I2C_UART functions start */ #define PA30_I2C1_SCL SF32LB_PINMUX(PA, 30U, 4U, 0x48U, 0U) #define PA30_I2C1_SDA SF32LB_PINMUX(PA, 30U, 4U, 0x48U, 1U) #define PA30_I2C2_SCL SF32LB_PINMUX(PA, 30U, 4U, 0x4CU, 0U) @@ -1709,29 +1590,27 @@ #define PA30_I2C3_SDA SF32LB_PINMUX(PA, 30U, 4U, 0x50U, 1U) #define PA30_I2C4_SCL SF32LB_PINMUX(PA, 30U, 4U, 0x54U, 0U) #define PA30_I2C4_SDA SF32LB_PINMUX(PA, 30U, 4U, 0x54U, 1U) -#define PA30_USART1_CTS SF32LB_PINMUX(PA, 30U, 4U, 0x58U, 0U) -#define PA30_USART1_RTS SF32LB_PINMUX(PA, 30U, 4U, 0x58U, 1U) -#define PA30_USART1_RXD SF32LB_PINMUX(PA, 30U, 4U, 0x58U, 2U) -#define PA30_USART1_TXD SF32LB_PINMUX(PA, 30U, 4U, 0x58U, 3U) -#define PA30_USART2_CTS SF32LB_PINMUX(PA, 30U, 4U, 0x5CU, 0U) -#define PA30_USART2_RTS SF32LB_PINMUX(PA, 30U, 4U, 0x5CU, 1U) -#define PA30_USART2_RXD SF32LB_PINMUX(PA, 30U, 4U, 0x5CU, 2U) -#define PA30_USART2_TXD SF32LB_PINMUX(PA, 30U, 4U, 0x5CU, 3U) -#define PA30_USART3_CTS SF32LB_PINMUX(PA, 30U, 4U, 0x60U, 0U) -#define PA30_USART3_RTS SF32LB_PINMUX(PA, 30U, 4U, 0x60U, 1U) -#define PA30_USART3_RXD SF32LB_PINMUX(PA, 30U, 4U, 0x60U, 2U) -#define PA30_USART3_TXD SF32LB_PINMUX(PA, 30U, 4U, 0x60U, 3U) -/* PA_I2C_UART functions end */ -/* PA_TIM functions start */ +#define PA30_USART1_TXD SF32LB_PINMUX(PA, 30U, 4U, 0x58U, 0U) +#define PA30_USART1_RXD SF32LB_PINMUX(PA, 30U, 4U, 0x58U, 1U) +#define PA30_USART1_RTS SF32LB_PINMUX(PA, 30U, 4U, 0x58U, 2U) +#define PA30_USART1_CTS SF32LB_PINMUX(PA, 30U, 4U, 0x58U, 3U) +#define PA30_USART2_TXD SF32LB_PINMUX(PA, 30U, 4U, 0x5CU, 0U) +#define PA30_USART2_RXD SF32LB_PINMUX(PA, 30U, 4U, 0x5CU, 1U) +#define PA30_USART2_RTS SF32LB_PINMUX(PA, 30U, 4U, 0x5CU, 2U) +#define PA30_USART2_CTS SF32LB_PINMUX(PA, 30U, 4U, 0x5CU, 3U) +#define PA30_USART3_TXD SF32LB_PINMUX(PA, 30U, 4U, 0x60U, 0U) +#define PA30_USART3_RXD SF32LB_PINMUX(PA, 30U, 4U, 0x60U, 1U) +#define PA30_USART3_RTS SF32LB_PINMUX(PA, 30U, 4U, 0x60U, 2U) +#define PA30_USART3_CTS SF32LB_PINMUX(PA, 30U, 4U, 0x60U, 3U) #define PA30_GPTIM1_CH1 SF32LB_PINMUX(PA, 30U, 5U, 0x64U, 0U) #define PA30_GPTIM1_CH2 SF32LB_PINMUX(PA, 30U, 5U, 0x64U, 1U) #define PA30_GPTIM1_CH3 SF32LB_PINMUX(PA, 30U, 5U, 0x64U, 2U) #define PA30_GPTIM1_CH4 SF32LB_PINMUX(PA, 30U, 5U, 0x64U, 3U) +#define PA30_GPTIM1_ETR SF32LB_PINMUX(PA, 30U, 5U, 0x6CU, 0U) #define PA30_GPTIM2_CH1 SF32LB_PINMUX(PA, 30U, 5U, 0x68U, 0U) #define PA30_GPTIM2_CH2 SF32LB_PINMUX(PA, 30U, 5U, 0x68U, 1U) #define PA30_GPTIM2_CH3 SF32LB_PINMUX(PA, 30U, 5U, 0x68U, 2U) #define PA30_GPTIM2_CH4 SF32LB_PINMUX(PA, 30U, 5U, 0x68U, 3U) -#define PA30_GPTIM1_ETR SF32LB_PINMUX(PA, 30U, 5U, 0x6CU, 0U) #define PA30_GPTIM2_ETR SF32LB_PINMUX(PA, 30U, 5U, 0x6CU, 1U) #define PA30_LPTIM1_IN SF32LB_PINMUX(PA, 30U, 5U, 0x70U, 0U) #define PA30_LPTIM1_OUT SF32LB_PINMUX(PA, 30U, 5U, 0x70U, 1U) @@ -1746,16 +1625,14 @@ #define PA30_ATIM1_CH1N SF32LB_PINMUX(PA, 30U, 5U, 0x7CU, 0U) #define PA30_ATIM1_CH2N SF32LB_PINMUX(PA, 30U, 5U, 0x7CU, 1U) #define PA30_ATIM1_CH3N SF32LB_PINMUX(PA, 30U, 5U, 0x7CU, 2U) +#define PA30_ATIM1_ETR SF32LB_PINMUX(PA, 30U, 5U, 0x80U, 2U) #define PA30_ATIM1_BK SF32LB_PINMUX(PA, 30U, 5U, 0x80U, 0U) #define PA30_ATIM1_BK2 SF32LB_PINMUX(PA, 30U, 5U, 0x80U, 1U) -#define PA30_ATIM1_ETR SF32LB_PINMUX(PA, 30U, 5U, 0x80U, 2U) -/* PA_TIM functions end */ #define PA30_GPADC_CH2 SF32LB_PINMUX(PA, 30U, 7U, 0U, 0U) /* PA31 */ #define PA31_ANALOG SF32LB_PINMUX_ANALOG(PA, 31U) #define PA31_GPIO SF32LB_PINMUX(PA, 31U, 0U, 0U, 0U) -/* PA_I2C_UART functions start */ #define PA31_I2C1_SCL SF32LB_PINMUX(PA, 31U, 4U, 0x48U, 0U) #define PA31_I2C1_SDA SF32LB_PINMUX(PA, 31U, 4U, 0x48U, 1U) #define PA31_I2C2_SCL SF32LB_PINMUX(PA, 31U, 4U, 0x4CU, 0U) @@ -1764,29 +1641,27 @@ #define PA31_I2C3_SDA SF32LB_PINMUX(PA, 31U, 4U, 0x50U, 1U) #define PA31_I2C4_SCL SF32LB_PINMUX(PA, 31U, 4U, 0x54U, 0U) #define PA31_I2C4_SDA SF32LB_PINMUX(PA, 31U, 4U, 0x54U, 1U) -#define PA31_USART1_CTS SF32LB_PINMUX(PA, 31U, 4U, 0x58U, 0U) -#define PA31_USART1_RTS SF32LB_PINMUX(PA, 31U, 4U, 0x58U, 1U) -#define PA31_USART1_RXD SF32LB_PINMUX(PA, 31U, 4U, 0x58U, 2U) -#define PA31_USART1_TXD SF32LB_PINMUX(PA, 31U, 4U, 0x58U, 3U) -#define PA31_USART2_CTS SF32LB_PINMUX(PA, 31U, 4U, 0x5CU, 0U) -#define PA31_USART2_RTS SF32LB_PINMUX(PA, 31U, 4U, 0x5CU, 1U) -#define PA31_USART2_RXD SF32LB_PINMUX(PA, 31U, 4U, 0x5CU, 2U) -#define PA31_USART2_TXD SF32LB_PINMUX(PA, 31U, 4U, 0x5CU, 3U) -#define PA31_USART3_CTS SF32LB_PINMUX(PA, 31U, 4U, 0x60U, 0U) -#define PA31_USART3_RTS SF32LB_PINMUX(PA, 31U, 4U, 0x60U, 1U) -#define PA31_USART3_RXD SF32LB_PINMUX(PA, 31U, 4U, 0x60U, 2U) -#define PA31_USART3_TXD SF32LB_PINMUX(PA, 31U, 4U, 0x60U, 3U) -/* PA_I2C_UART functions end */ -/* PA_TIM functions start */ +#define PA31_USART1_TXD SF32LB_PINMUX(PA, 31U, 4U, 0x58U, 0U) +#define PA31_USART1_RXD SF32LB_PINMUX(PA, 31U, 4U, 0x58U, 1U) +#define PA31_USART1_RTS SF32LB_PINMUX(PA, 31U, 4U, 0x58U, 2U) +#define PA31_USART1_CTS SF32LB_PINMUX(PA, 31U, 4U, 0x58U, 3U) +#define PA31_USART2_TXD SF32LB_PINMUX(PA, 31U, 4U, 0x5CU, 0U) +#define PA31_USART2_RXD SF32LB_PINMUX(PA, 31U, 4U, 0x5CU, 1U) +#define PA31_USART2_RTS SF32LB_PINMUX(PA, 31U, 4U, 0x5CU, 2U) +#define PA31_USART2_CTS SF32LB_PINMUX(PA, 31U, 4U, 0x5CU, 3U) +#define PA31_USART3_TXD SF32LB_PINMUX(PA, 31U, 4U, 0x60U, 0U) +#define PA31_USART3_RXD SF32LB_PINMUX(PA, 31U, 4U, 0x60U, 1U) +#define PA31_USART3_RTS SF32LB_PINMUX(PA, 31U, 4U, 0x60U, 2U) +#define PA31_USART3_CTS SF32LB_PINMUX(PA, 31U, 4U, 0x60U, 3U) #define PA31_GPTIM1_CH1 SF32LB_PINMUX(PA, 31U, 5U, 0x64U, 0U) #define PA31_GPTIM1_CH2 SF32LB_PINMUX(PA, 31U, 5U, 0x64U, 1U) #define PA31_GPTIM1_CH3 SF32LB_PINMUX(PA, 31U, 5U, 0x64U, 2U) #define PA31_GPTIM1_CH4 SF32LB_PINMUX(PA, 31U, 5U, 0x64U, 3U) +#define PA31_GPTIM1_ETR SF32LB_PINMUX(PA, 31U, 5U, 0x6CU, 0U) #define PA31_GPTIM2_CH1 SF32LB_PINMUX(PA, 31U, 5U, 0x68U, 0U) #define PA31_GPTIM2_CH2 SF32LB_PINMUX(PA, 31U, 5U, 0x68U, 1U) #define PA31_GPTIM2_CH3 SF32LB_PINMUX(PA, 31U, 5U, 0x68U, 2U) #define PA31_GPTIM2_CH4 SF32LB_PINMUX(PA, 31U, 5U, 0x68U, 3U) -#define PA31_GPTIM1_ETR SF32LB_PINMUX(PA, 31U, 5U, 0x6CU, 0U) #define PA31_GPTIM2_ETR SF32LB_PINMUX(PA, 31U, 5U, 0x6CU, 1U) #define PA31_LPTIM1_IN SF32LB_PINMUX(PA, 31U, 5U, 0x70U, 0U) #define PA31_LPTIM1_OUT SF32LB_PINMUX(PA, 31U, 5U, 0x70U, 1U) @@ -1801,16 +1676,14 @@ #define PA31_ATIM1_CH1N SF32LB_PINMUX(PA, 31U, 5U, 0x7CU, 0U) #define PA31_ATIM1_CH2N SF32LB_PINMUX(PA, 31U, 5U, 0x7CU, 1U) #define PA31_ATIM1_CH3N SF32LB_PINMUX(PA, 31U, 5U, 0x7CU, 2U) +#define PA31_ATIM1_ETR SF32LB_PINMUX(PA, 31U, 5U, 0x80U, 2U) #define PA31_ATIM1_BK SF32LB_PINMUX(PA, 31U, 5U, 0x80U, 0U) #define PA31_ATIM1_BK2 SF32LB_PINMUX(PA, 31U, 5U, 0x80U, 1U) -#define PA31_ATIM1_ETR SF32LB_PINMUX(PA, 31U, 5U, 0x80U, 2U) -/* PA_TIM functions end */ #define PA31_GPADC_CH3 SF32LB_PINMUX(PA, 31U, 7U, 0U, 0U) /* PA32 */ #define PA32_ANALOG SF32LB_PINMUX_ANALOG(PA, 32U) #define PA32_GPIO SF32LB_PINMUX(PA, 32U, 0U, 0U, 0U) -/* PA_I2C_UART functions start */ #define PA32_I2C1_SCL SF32LB_PINMUX(PA, 32U, 4U, 0x48U, 0U) #define PA32_I2C1_SDA SF32LB_PINMUX(PA, 32U, 4U, 0x48U, 1U) #define PA32_I2C2_SCL SF32LB_PINMUX(PA, 32U, 4U, 0x4CU, 0U) @@ -1819,29 +1692,27 @@ #define PA32_I2C3_SDA SF32LB_PINMUX(PA, 32U, 4U, 0x50U, 1U) #define PA32_I2C4_SCL SF32LB_PINMUX(PA, 32U, 4U, 0x54U, 0U) #define PA32_I2C4_SDA SF32LB_PINMUX(PA, 32U, 4U, 0x54U, 1U) -#define PA32_USART1_CTS SF32LB_PINMUX(PA, 32U, 4U, 0x58U, 0U) -#define PA32_USART1_RTS SF32LB_PINMUX(PA, 32U, 4U, 0x58U, 1U) -#define PA32_USART1_RXD SF32LB_PINMUX(PA, 32U, 4U, 0x58U, 2U) -#define PA32_USART1_TXD SF32LB_PINMUX(PA, 32U, 4U, 0x58U, 3U) -#define PA32_USART2_CTS SF32LB_PINMUX(PA, 32U, 4U, 0x5CU, 0U) -#define PA32_USART2_RTS SF32LB_PINMUX(PA, 32U, 4U, 0x5CU, 1U) -#define PA32_USART2_RXD SF32LB_PINMUX(PA, 32U, 4U, 0x5CU, 2U) -#define PA32_USART2_TXD SF32LB_PINMUX(PA, 32U, 4U, 0x5CU, 3U) -#define PA32_USART3_CTS SF32LB_PINMUX(PA, 32U, 4U, 0x60U, 0U) -#define PA32_USART3_RTS SF32LB_PINMUX(PA, 32U, 4U, 0x60U, 1U) -#define PA32_USART3_RXD SF32LB_PINMUX(PA, 32U, 4U, 0x60U, 2U) -#define PA32_USART3_TXD SF32LB_PINMUX(PA, 32U, 4U, 0x60U, 3U) -/* PA_I2C_UART functions end */ -/* PA_TIM functions start */ +#define PA32_USART1_TXD SF32LB_PINMUX(PA, 32U, 4U, 0x58U, 0U) +#define PA32_USART1_RXD SF32LB_PINMUX(PA, 32U, 4U, 0x58U, 1U) +#define PA32_USART1_RTS SF32LB_PINMUX(PA, 32U, 4U, 0x58U, 2U) +#define PA32_USART1_CTS SF32LB_PINMUX(PA, 32U, 4U, 0x58U, 3U) +#define PA32_USART2_TXD SF32LB_PINMUX(PA, 32U, 4U, 0x5CU, 0U) +#define PA32_USART2_RXD SF32LB_PINMUX(PA, 32U, 4U, 0x5CU, 1U) +#define PA32_USART2_RTS SF32LB_PINMUX(PA, 32U, 4U, 0x5CU, 2U) +#define PA32_USART2_CTS SF32LB_PINMUX(PA, 32U, 4U, 0x5CU, 3U) +#define PA32_USART3_TXD SF32LB_PINMUX(PA, 32U, 4U, 0x60U, 0U) +#define PA32_USART3_RXD SF32LB_PINMUX(PA, 32U, 4U, 0x60U, 1U) +#define PA32_USART3_RTS SF32LB_PINMUX(PA, 32U, 4U, 0x60U, 2U) +#define PA32_USART3_CTS SF32LB_PINMUX(PA, 32U, 4U, 0x60U, 3U) #define PA32_GPTIM1_CH1 SF32LB_PINMUX(PA, 32U, 5U, 0x64U, 0U) #define PA32_GPTIM1_CH2 SF32LB_PINMUX(PA, 32U, 5U, 0x64U, 1U) #define PA32_GPTIM1_CH3 SF32LB_PINMUX(PA, 32U, 5U, 0x64U, 2U) #define PA32_GPTIM1_CH4 SF32LB_PINMUX(PA, 32U, 5U, 0x64U, 3U) +#define PA32_GPTIM1_ETR SF32LB_PINMUX(PA, 32U, 5U, 0x6CU, 0U) #define PA32_GPTIM2_CH1 SF32LB_PINMUX(PA, 32U, 5U, 0x68U, 0U) #define PA32_GPTIM2_CH2 SF32LB_PINMUX(PA, 32U, 5U, 0x68U, 1U) #define PA32_GPTIM2_CH3 SF32LB_PINMUX(PA, 32U, 5U, 0x68U, 2U) #define PA32_GPTIM2_CH4 SF32LB_PINMUX(PA, 32U, 5U, 0x68U, 3U) -#define PA32_GPTIM1_ETR SF32LB_PINMUX(PA, 32U, 5U, 0x6CU, 0U) #define PA32_GPTIM2_ETR SF32LB_PINMUX(PA, 32U, 5U, 0x6CU, 1U) #define PA32_LPTIM1_IN SF32LB_PINMUX(PA, 32U, 5U, 0x70U, 0U) #define PA32_LPTIM1_OUT SF32LB_PINMUX(PA, 32U, 5U, 0x70U, 1U) @@ -1856,16 +1727,14 @@ #define PA32_ATIM1_CH1N SF32LB_PINMUX(PA, 32U, 5U, 0x7CU, 0U) #define PA32_ATIM1_CH2N SF32LB_PINMUX(PA, 32U, 5U, 0x7CU, 1U) #define PA32_ATIM1_CH3N SF32LB_PINMUX(PA, 32U, 5U, 0x7CU, 2U) +#define PA32_ATIM1_ETR SF32LB_PINMUX(PA, 32U, 5U, 0x80U, 2U) #define PA32_ATIM1_BK SF32LB_PINMUX(PA, 32U, 5U, 0x80U, 0U) #define PA32_ATIM1_BK2 SF32LB_PINMUX(PA, 32U, 5U, 0x80U, 1U) -#define PA32_ATIM1_ETR SF32LB_PINMUX(PA, 32U, 5U, 0x80U, 2U) -/* PA_TIM functions end */ #define PA32_GPADC_CH4 SF32LB_PINMUX(PA, 32U, 7U, 0U, 0U) /* PA33 */ #define PA33_ANALOG SF32LB_PINMUX_ANALOG(PA, 33U) #define PA33_GPIO SF32LB_PINMUX(PA, 33U, 0U, 0U, 0U) -/* PA_I2C_UART functions start */ #define PA33_I2C1_SCL SF32LB_PINMUX(PA, 33U, 4U, 0x48U, 0U) #define PA33_I2C1_SDA SF32LB_PINMUX(PA, 33U, 4U, 0x48U, 1U) #define PA33_I2C2_SCL SF32LB_PINMUX(PA, 33U, 4U, 0x4CU, 0U) @@ -1874,29 +1743,27 @@ #define PA33_I2C3_SDA SF32LB_PINMUX(PA, 33U, 4U, 0x50U, 1U) #define PA33_I2C4_SCL SF32LB_PINMUX(PA, 33U, 4U, 0x54U, 0U) #define PA33_I2C4_SDA SF32LB_PINMUX(PA, 33U, 4U, 0x54U, 1U) -#define PA33_USART1_CTS SF32LB_PINMUX(PA, 33U, 4U, 0x58U, 0U) -#define PA33_USART1_RTS SF32LB_PINMUX(PA, 33U, 4U, 0x58U, 1U) -#define PA33_USART1_RXD SF32LB_PINMUX(PA, 33U, 4U, 0x58U, 2U) -#define PA33_USART1_TXD SF32LB_PINMUX(PA, 33U, 4U, 0x58U, 3U) -#define PA33_USART2_CTS SF32LB_PINMUX(PA, 33U, 4U, 0x5CU, 0U) -#define PA33_USART2_RTS SF32LB_PINMUX(PA, 33U, 4U, 0x5CU, 1U) -#define PA33_USART2_RXD SF32LB_PINMUX(PA, 33U, 4U, 0x5CU, 2U) -#define PA33_USART2_TXD SF32LB_PINMUX(PA, 33U, 4U, 0x5CU, 3U) -#define PA33_USART3_CTS SF32LB_PINMUX(PA, 33U, 4U, 0x60U, 0U) -#define PA33_USART3_RTS SF32LB_PINMUX(PA, 33U, 4U, 0x60U, 1U) -#define PA33_USART3_RXD SF32LB_PINMUX(PA, 33U, 4U, 0x60U, 2U) -#define PA33_USART3_TXD SF32LB_PINMUX(PA, 33U, 4U, 0x60U, 3U) -/* PA_I2C_UART functions end */ -/* PA_TIM functions start */ +#define PA33_USART1_TXD SF32LB_PINMUX(PA, 33U, 4U, 0x58U, 0U) +#define PA33_USART1_RXD SF32LB_PINMUX(PA, 33U, 4U, 0x58U, 1U) +#define PA33_USART1_RTS SF32LB_PINMUX(PA, 33U, 4U, 0x58U, 2U) +#define PA33_USART1_CTS SF32LB_PINMUX(PA, 33U, 4U, 0x58U, 3U) +#define PA33_USART2_TXD SF32LB_PINMUX(PA, 33U, 4U, 0x5CU, 0U) +#define PA33_USART2_RXD SF32LB_PINMUX(PA, 33U, 4U, 0x5CU, 1U) +#define PA33_USART2_RTS SF32LB_PINMUX(PA, 33U, 4U, 0x5CU, 2U) +#define PA33_USART2_CTS SF32LB_PINMUX(PA, 33U, 4U, 0x5CU, 3U) +#define PA33_USART3_TXD SF32LB_PINMUX(PA, 33U, 4U, 0x60U, 0U) +#define PA33_USART3_RXD SF32LB_PINMUX(PA, 33U, 4U, 0x60U, 1U) +#define PA33_USART3_RTS SF32LB_PINMUX(PA, 33U, 4U, 0x60U, 2U) +#define PA33_USART3_CTS SF32LB_PINMUX(PA, 33U, 4U, 0x60U, 3U) #define PA33_GPTIM1_CH1 SF32LB_PINMUX(PA, 33U, 5U, 0x64U, 0U) #define PA33_GPTIM1_CH2 SF32LB_PINMUX(PA, 33U, 5U, 0x64U, 1U) #define PA33_GPTIM1_CH3 SF32LB_PINMUX(PA, 33U, 5U, 0x64U, 2U) #define PA33_GPTIM1_CH4 SF32LB_PINMUX(PA, 33U, 5U, 0x64U, 3U) +#define PA33_GPTIM1_ETR SF32LB_PINMUX(PA, 33U, 5U, 0x6CU, 0U) #define PA33_GPTIM2_CH1 SF32LB_PINMUX(PA, 33U, 5U, 0x68U, 0U) #define PA33_GPTIM2_CH2 SF32LB_PINMUX(PA, 33U, 5U, 0x68U, 1U) #define PA33_GPTIM2_CH3 SF32LB_PINMUX(PA, 33U, 5U, 0x68U, 2U) #define PA33_GPTIM2_CH4 SF32LB_PINMUX(PA, 33U, 5U, 0x68U, 3U) -#define PA33_GPTIM1_ETR SF32LB_PINMUX(PA, 33U, 5U, 0x6CU, 0U) #define PA33_GPTIM2_ETR SF32LB_PINMUX(PA, 33U, 5U, 0x6CU, 1U) #define PA33_LPTIM1_IN SF32LB_PINMUX(PA, 33U, 5U, 0x70U, 0U) #define PA33_LPTIM1_OUT SF32LB_PINMUX(PA, 33U, 5U, 0x70U, 1U) @@ -1911,16 +1778,14 @@ #define PA33_ATIM1_CH1N SF32LB_PINMUX(PA, 33U, 5U, 0x7CU, 0U) #define PA33_ATIM1_CH2N SF32LB_PINMUX(PA, 33U, 5U, 0x7CU, 1U) #define PA33_ATIM1_CH3N SF32LB_PINMUX(PA, 33U, 5U, 0x7CU, 2U) +#define PA33_ATIM1_ETR SF32LB_PINMUX(PA, 33U, 5U, 0x80U, 2U) #define PA33_ATIM1_BK SF32LB_PINMUX(PA, 33U, 5U, 0x80U, 0U) #define PA33_ATIM1_BK2 SF32LB_PINMUX(PA, 33U, 5U, 0x80U, 1U) -#define PA33_ATIM1_ETR SF32LB_PINMUX(PA, 33U, 5U, 0x80U, 2U) -/* PA_TIM functions end */ #define PA33_GPADC_CH5 SF32LB_PINMUX(PA, 33U, 7U, 0U, 0U) /* PA34 */ #define PA34_ANALOG SF32LB_PINMUX_ANALOG(PA, 34U) #define PA34_GPIO SF32LB_PINMUX(PA, 34U, 0U, 0U, 0U) -/* PA_I2C_UART functions start */ #define PA34_I2C1_SCL SF32LB_PINMUX(PA, 34U, 4U, 0x48U, 0U) #define PA34_I2C1_SDA SF32LB_PINMUX(PA, 34U, 4U, 0x48U, 1U) #define PA34_I2C2_SCL SF32LB_PINMUX(PA, 34U, 4U, 0x4CU, 0U) @@ -1929,29 +1794,27 @@ #define PA34_I2C3_SDA SF32LB_PINMUX(PA, 34U, 4U, 0x50U, 1U) #define PA34_I2C4_SCL SF32LB_PINMUX(PA, 34U, 4U, 0x54U, 0U) #define PA34_I2C4_SDA SF32LB_PINMUX(PA, 34U, 4U, 0x54U, 1U) -#define PA34_USART1_CTS SF32LB_PINMUX(PA, 34U, 4U, 0x58U, 0U) -#define PA34_USART1_RTS SF32LB_PINMUX(PA, 34U, 4U, 0x58U, 1U) -#define PA34_USART1_RXD SF32LB_PINMUX(PA, 34U, 4U, 0x58U, 2U) -#define PA34_USART1_TXD SF32LB_PINMUX(PA, 34U, 4U, 0x58U, 3U) -#define PA34_USART2_CTS SF32LB_PINMUX(PA, 34U, 4U, 0x5CU, 0U) -#define PA34_USART2_RTS SF32LB_PINMUX(PA, 34U, 4U, 0x5CU, 1U) -#define PA34_USART2_RXD SF32LB_PINMUX(PA, 34U, 4U, 0x5CU, 2U) -#define PA34_USART2_TXD SF32LB_PINMUX(PA, 34U, 4U, 0x5CU, 3U) -#define PA34_USART3_CTS SF32LB_PINMUX(PA, 34U, 4U, 0x60U, 0U) -#define PA34_USART3_RTS SF32LB_PINMUX(PA, 34U, 4U, 0x60U, 1U) -#define PA34_USART3_RXD SF32LB_PINMUX(PA, 34U, 4U, 0x60U, 2U) -#define PA34_USART3_TXD SF32LB_PINMUX(PA, 34U, 4U, 0x60U, 3U) -/* PA_I2C_UART functions end */ -/* PA_TIM functions start */ +#define PA34_USART1_TXD SF32LB_PINMUX(PA, 34U, 4U, 0x58U, 0U) +#define PA34_USART1_RXD SF32LB_PINMUX(PA, 34U, 4U, 0x58U, 1U) +#define PA34_USART1_RTS SF32LB_PINMUX(PA, 34U, 4U, 0x58U, 2U) +#define PA34_USART1_CTS SF32LB_PINMUX(PA, 34U, 4U, 0x58U, 3U) +#define PA34_USART2_TXD SF32LB_PINMUX(PA, 34U, 4U, 0x5CU, 0U) +#define PA34_USART2_RXD SF32LB_PINMUX(PA, 34U, 4U, 0x5CU, 1U) +#define PA34_USART2_RTS SF32LB_PINMUX(PA, 34U, 4U, 0x5CU, 2U) +#define PA34_USART2_CTS SF32LB_PINMUX(PA, 34U, 4U, 0x5CU, 3U) +#define PA34_USART3_TXD SF32LB_PINMUX(PA, 34U, 4U, 0x60U, 0U) +#define PA34_USART3_RXD SF32LB_PINMUX(PA, 34U, 4U, 0x60U, 1U) +#define PA34_USART3_RTS SF32LB_PINMUX(PA, 34U, 4U, 0x60U, 2U) +#define PA34_USART3_CTS SF32LB_PINMUX(PA, 34U, 4U, 0x60U, 3U) #define PA34_GPTIM1_CH1 SF32LB_PINMUX(PA, 34U, 5U, 0x64U, 0U) #define PA34_GPTIM1_CH2 SF32LB_PINMUX(PA, 34U, 5U, 0x64U, 1U) #define PA34_GPTIM1_CH3 SF32LB_PINMUX(PA, 34U, 5U, 0x64U, 2U) #define PA34_GPTIM1_CH4 SF32LB_PINMUX(PA, 34U, 5U, 0x64U, 3U) +#define PA34_GPTIM1_ETR SF32LB_PINMUX(PA, 34U, 5U, 0x6CU, 0U) #define PA34_GPTIM2_CH1 SF32LB_PINMUX(PA, 34U, 5U, 0x68U, 0U) #define PA34_GPTIM2_CH2 SF32LB_PINMUX(PA, 34U, 5U, 0x68U, 1U) #define PA34_GPTIM2_CH3 SF32LB_PINMUX(PA, 34U, 5U, 0x68U, 2U) #define PA34_GPTIM2_CH4 SF32LB_PINMUX(PA, 34U, 5U, 0x68U, 3U) -#define PA34_GPTIM1_ETR SF32LB_PINMUX(PA, 34U, 5U, 0x6CU, 0U) #define PA34_GPTIM2_ETR SF32LB_PINMUX(PA, 34U, 5U, 0x6CU, 1U) #define PA34_LPTIM1_IN SF32LB_PINMUX(PA, 34U, 5U, 0x70U, 0U) #define PA34_LPTIM1_OUT SF32LB_PINMUX(PA, 34U, 5U, 0x70U, 1U) @@ -1966,10 +1829,9 @@ #define PA34_ATIM1_CH1N SF32LB_PINMUX(PA, 34U, 5U, 0x7CU, 0U) #define PA34_ATIM1_CH2N SF32LB_PINMUX(PA, 34U, 5U, 0x7CU, 1U) #define PA34_ATIM1_CH3N SF32LB_PINMUX(PA, 34U, 5U, 0x7CU, 2U) +#define PA34_ATIM1_ETR SF32LB_PINMUX(PA, 34U, 5U, 0x80U, 2U) #define PA34_ATIM1_BK SF32LB_PINMUX(PA, 34U, 5U, 0x80U, 0U) #define PA34_ATIM1_BK2 SF32LB_PINMUX(PA, 34U, 5U, 0x80U, 1U) -#define PA34_ATIM1_ETR SF32LB_PINMUX(PA, 34U, 5U, 0x80U, 2U) -/* PA_TIM functions end */ #define PA34_GPADC_CH6 SF32LB_PINMUX(PA, 34U, 7U, 0U, 0U) #define PA34_WKUP_PIN10 SF32LB_PINMUX(PA, 34U, 8U, 0U, 0U) @@ -1977,7 +1839,6 @@ #define PA35_ANALOG SF32LB_PINMUX_ANALOG(PA, 35U) #define PA35_GPIO SF32LB_PINMUX(PA, 35U, 0U, 0U, 0U) #define PA35_USB11_DP SF32LB_PINMUX(PA, 35U, 2U, 0U, 0U) -/* PA_I2C_UART functions start */ #define PA35_I2C1_SCL SF32LB_PINMUX(PA, 35U, 4U, 0x48U, 0U) #define PA35_I2C1_SDA SF32LB_PINMUX(PA, 35U, 4U, 0x48U, 1U) #define PA35_I2C2_SCL SF32LB_PINMUX(PA, 35U, 4U, 0x4CU, 0U) @@ -1986,29 +1847,27 @@ #define PA35_I2C3_SDA SF32LB_PINMUX(PA, 35U, 4U, 0x50U, 1U) #define PA35_I2C4_SCL SF32LB_PINMUX(PA, 35U, 4U, 0x54U, 0U) #define PA35_I2C4_SDA SF32LB_PINMUX(PA, 35U, 4U, 0x54U, 1U) -#define PA35_USART1_CTS SF32LB_PINMUX(PA, 35U, 4U, 0x58U, 0U) -#define PA35_USART1_RTS SF32LB_PINMUX(PA, 35U, 4U, 0x58U, 1U) -#define PA35_USART1_RXD SF32LB_PINMUX(PA, 35U, 4U, 0x58U, 2U) -#define PA35_USART1_TXD SF32LB_PINMUX(PA, 35U, 4U, 0x58U, 3U) -#define PA35_USART2_CTS SF32LB_PINMUX(PA, 35U, 4U, 0x5CU, 0U) -#define PA35_USART2_RTS SF32LB_PINMUX(PA, 35U, 4U, 0x5CU, 1U) -#define PA35_USART2_RXD SF32LB_PINMUX(PA, 35U, 4U, 0x5CU, 2U) -#define PA35_USART2_TXD SF32LB_PINMUX(PA, 35U, 4U, 0x5CU, 3U) -#define PA35_USART3_CTS SF32LB_PINMUX(PA, 35U, 4U, 0x60U, 0U) -#define PA35_USART3_RTS SF32LB_PINMUX(PA, 35U, 4U, 0x60U, 1U) -#define PA35_USART3_RXD SF32LB_PINMUX(PA, 35U, 4U, 0x60U, 2U) -#define PA35_USART3_TXD SF32LB_PINMUX(PA, 35U, 4U, 0x60U, 3U) -/* PA_I2C_UART functions end */ -/* PA_TIM functions start */ +#define PA35_USART1_TXD SF32LB_PINMUX(PA, 35U, 4U, 0x58U, 0U) +#define PA35_USART1_RXD SF32LB_PINMUX(PA, 35U, 4U, 0x58U, 1U) +#define PA35_USART1_RTS SF32LB_PINMUX(PA, 35U, 4U, 0x58U, 2U) +#define PA35_USART1_CTS SF32LB_PINMUX(PA, 35U, 4U, 0x58U, 3U) +#define PA35_USART2_TXD SF32LB_PINMUX(PA, 35U, 4U, 0x5CU, 0U) +#define PA35_USART2_RXD SF32LB_PINMUX(PA, 35U, 4U, 0x5CU, 1U) +#define PA35_USART2_RTS SF32LB_PINMUX(PA, 35U, 4U, 0x5CU, 2U) +#define PA35_USART2_CTS SF32LB_PINMUX(PA, 35U, 4U, 0x5CU, 3U) +#define PA35_USART3_TXD SF32LB_PINMUX(PA, 35U, 4U, 0x60U, 0U) +#define PA35_USART3_RXD SF32LB_PINMUX(PA, 35U, 4U, 0x60U, 1U) +#define PA35_USART3_RTS SF32LB_PINMUX(PA, 35U, 4U, 0x60U, 2U) +#define PA35_USART3_CTS SF32LB_PINMUX(PA, 35U, 4U, 0x60U, 3U) #define PA35_GPTIM1_CH1 SF32LB_PINMUX(PA, 35U, 5U, 0x64U, 0U) #define PA35_GPTIM1_CH2 SF32LB_PINMUX(PA, 35U, 5U, 0x64U, 1U) #define PA35_GPTIM1_CH3 SF32LB_PINMUX(PA, 35U, 5U, 0x64U, 2U) #define PA35_GPTIM1_CH4 SF32LB_PINMUX(PA, 35U, 5U, 0x64U, 3U) +#define PA35_GPTIM1_ETR SF32LB_PINMUX(PA, 35U, 5U, 0x6CU, 0U) #define PA35_GPTIM2_CH1 SF32LB_PINMUX(PA, 35U, 5U, 0x68U, 0U) #define PA35_GPTIM2_CH2 SF32LB_PINMUX(PA, 35U, 5U, 0x68U, 1U) #define PA35_GPTIM2_CH3 SF32LB_PINMUX(PA, 35U, 5U, 0x68U, 2U) #define PA35_GPTIM2_CH4 SF32LB_PINMUX(PA, 35U, 5U, 0x68U, 3U) -#define PA35_GPTIM1_ETR SF32LB_PINMUX(PA, 35U, 5U, 0x6CU, 0U) #define PA35_GPTIM2_ETR SF32LB_PINMUX(PA, 35U, 5U, 0x6CU, 1U) #define PA35_LPTIM1_IN SF32LB_PINMUX(PA, 35U, 5U, 0x70U, 0U) #define PA35_LPTIM1_OUT SF32LB_PINMUX(PA, 35U, 5U, 0x70U, 1U) @@ -2023,17 +1882,15 @@ #define PA35_ATIM1_CH1N SF32LB_PINMUX(PA, 35U, 5U, 0x7CU, 0U) #define PA35_ATIM1_CH2N SF32LB_PINMUX(PA, 35U, 5U, 0x7CU, 1U) #define PA35_ATIM1_CH3N SF32LB_PINMUX(PA, 35U, 5U, 0x7CU, 2U) +#define PA35_ATIM1_ETR SF32LB_PINMUX(PA, 35U, 5U, 0x80U, 2U) #define PA35_ATIM1_BK SF32LB_PINMUX(PA, 35U, 5U, 0x80U, 0U) #define PA35_ATIM1_BK2 SF32LB_PINMUX(PA, 35U, 5U, 0x80U, 1U) -#define PA35_ATIM1_ETR SF32LB_PINMUX(PA, 35U, 5U, 0x80U, 2U) -/* PA_TIM functions end */ #define PA35_WKUP_PIN11 SF32LB_PINMUX(PA, 35U, 8U, 0U, 0U) /* PA36 */ #define PA36_ANALOG SF32LB_PINMUX_ANALOG(PA, 36U) #define PA36_GPIO SF32LB_PINMUX(PA, 36U, 0U, 0U, 0U) #define PA36_USB11_DM SF32LB_PINMUX(PA, 36U, 2U, 0U, 0U) -/* PA_I2C_UART functions start */ #define PA36_I2C1_SCL SF32LB_PINMUX(PA, 36U, 4U, 0x48U, 0U) #define PA36_I2C1_SDA SF32LB_PINMUX(PA, 36U, 4U, 0x48U, 1U) #define PA36_I2C2_SCL SF32LB_PINMUX(PA, 36U, 4U, 0x4CU, 0U) @@ -2042,29 +1899,27 @@ #define PA36_I2C3_SDA SF32LB_PINMUX(PA, 36U, 4U, 0x50U, 1U) #define PA36_I2C4_SCL SF32LB_PINMUX(PA, 36U, 4U, 0x54U, 0U) #define PA36_I2C4_SDA SF32LB_PINMUX(PA, 36U, 4U, 0x54U, 1U) -#define PA36_USART1_CTS SF32LB_PINMUX(PA, 36U, 4U, 0x58U, 0U) -#define PA36_USART1_RTS SF32LB_PINMUX(PA, 36U, 4U, 0x58U, 1U) -#define PA36_USART1_RXD SF32LB_PINMUX(PA, 36U, 4U, 0x58U, 2U) -#define PA36_USART1_TXD SF32LB_PINMUX(PA, 36U, 4U, 0x58U, 3U) -#define PA36_USART2_CTS SF32LB_PINMUX(PA, 36U, 4U, 0x5CU, 0U) -#define PA36_USART2_RTS SF32LB_PINMUX(PA, 36U, 4U, 0x5CU, 1U) -#define PA36_USART2_RXD SF32LB_PINMUX(PA, 36U, 4U, 0x5CU, 2U) -#define PA36_USART2_TXD SF32LB_PINMUX(PA, 36U, 4U, 0x5CU, 3U) -#define PA36_USART3_CTS SF32LB_PINMUX(PA, 36U, 4U, 0x60U, 0U) -#define PA36_USART3_RTS SF32LB_PINMUX(PA, 36U, 4U, 0x60U, 1U) -#define PA36_USART3_RXD SF32LB_PINMUX(PA, 36U, 4U, 0x60U, 2U) -#define PA36_USART3_TXD SF32LB_PINMUX(PA, 36U, 4U, 0x60U, 3U) -/* PA_I2C_UART functions end */ -/* PA_TIM functions start */ +#define PA36_USART1_TXD SF32LB_PINMUX(PA, 36U, 4U, 0x58U, 0U) +#define PA36_USART1_RXD SF32LB_PINMUX(PA, 36U, 4U, 0x58U, 1U) +#define PA36_USART1_RTS SF32LB_PINMUX(PA, 36U, 4U, 0x58U, 2U) +#define PA36_USART1_CTS SF32LB_PINMUX(PA, 36U, 4U, 0x58U, 3U) +#define PA36_USART2_TXD SF32LB_PINMUX(PA, 36U, 4U, 0x5CU, 0U) +#define PA36_USART2_RXD SF32LB_PINMUX(PA, 36U, 4U, 0x5CU, 1U) +#define PA36_USART2_RTS SF32LB_PINMUX(PA, 36U, 4U, 0x5CU, 2U) +#define PA36_USART2_CTS SF32LB_PINMUX(PA, 36U, 4U, 0x5CU, 3U) +#define PA36_USART3_TXD SF32LB_PINMUX(PA, 36U, 4U, 0x60U, 0U) +#define PA36_USART3_RXD SF32LB_PINMUX(PA, 36U, 4U, 0x60U, 1U) +#define PA36_USART3_RTS SF32LB_PINMUX(PA, 36U, 4U, 0x60U, 2U) +#define PA36_USART3_CTS SF32LB_PINMUX(PA, 36U, 4U, 0x60U, 3U) #define PA36_GPTIM1_CH1 SF32LB_PINMUX(PA, 36U, 5U, 0x64U, 0U) #define PA36_GPTIM1_CH2 SF32LB_PINMUX(PA, 36U, 5U, 0x64U, 1U) #define PA36_GPTIM1_CH3 SF32LB_PINMUX(PA, 36U, 5U, 0x64U, 2U) #define PA36_GPTIM1_CH4 SF32LB_PINMUX(PA, 36U, 5U, 0x64U, 3U) +#define PA36_GPTIM1_ETR SF32LB_PINMUX(PA, 36U, 5U, 0x6CU, 0U) #define PA36_GPTIM2_CH1 SF32LB_PINMUX(PA, 36U, 5U, 0x68U, 0U) #define PA36_GPTIM2_CH2 SF32LB_PINMUX(PA, 36U, 5U, 0x68U, 1U) #define PA36_GPTIM2_CH3 SF32LB_PINMUX(PA, 36U, 5U, 0x68U, 2U) #define PA36_GPTIM2_CH4 SF32LB_PINMUX(PA, 36U, 5U, 0x68U, 3U) -#define PA36_GPTIM1_ETR SF32LB_PINMUX(PA, 36U, 5U, 0x6CU, 0U) #define PA36_GPTIM2_ETR SF32LB_PINMUX(PA, 36U, 5U, 0x6CU, 1U) #define PA36_LPTIM1_IN SF32LB_PINMUX(PA, 36U, 5U, 0x70U, 0U) #define PA36_LPTIM1_OUT SF32LB_PINMUX(PA, 36U, 5U, 0x70U, 1U) @@ -2079,17 +1934,15 @@ #define PA36_ATIM1_CH1N SF32LB_PINMUX(PA, 36U, 5U, 0x7CU, 0U) #define PA36_ATIM1_CH2N SF32LB_PINMUX(PA, 36U, 5U, 0x7CU, 1U) #define PA36_ATIM1_CH3N SF32LB_PINMUX(PA, 36U, 5U, 0x7CU, 2U) +#define PA36_ATIM1_ETR SF32LB_PINMUX(PA, 36U, 5U, 0x80U, 2U) #define PA36_ATIM1_BK SF32LB_PINMUX(PA, 36U, 5U, 0x80U, 0U) #define PA36_ATIM1_BK2 SF32LB_PINMUX(PA, 36U, 5U, 0x80U, 1U) -#define PA36_ATIM1_ETR SF32LB_PINMUX(PA, 36U, 5U, 0x80U, 2U) -/* PA_TIM functions end */ #define PA36_WKUP_PIN12 SF32LB_PINMUX(PA, 36U, 8U, 0U, 0U) /* PA37 */ #define PA37_ANALOG SF32LB_PINMUX_ANALOG(PA, 37U) #define PA37_GPIO SF32LB_PINMUX(PA, 37U, 0U, 0U, 0U) #define PA37_SPI2_DIO SF32LB_PINMUX(PA, 37U, 2U, 0U, 0U) -/* PA_I2C_UART functions start */ #define PA37_I2C1_SCL SF32LB_PINMUX(PA, 37U, 4U, 0x48U, 0U) #define PA37_I2C1_SDA SF32LB_PINMUX(PA, 37U, 4U, 0x48U, 1U) #define PA37_I2C2_SCL SF32LB_PINMUX(PA, 37U, 4U, 0x4CU, 0U) @@ -2098,29 +1951,27 @@ #define PA37_I2C3_SDA SF32LB_PINMUX(PA, 37U, 4U, 0x50U, 1U) #define PA37_I2C4_SCL SF32LB_PINMUX(PA, 37U, 4U, 0x54U, 0U) #define PA37_I2C4_SDA SF32LB_PINMUX(PA, 37U, 4U, 0x54U, 1U) -#define PA37_USART1_CTS SF32LB_PINMUX(PA, 37U, 4U, 0x58U, 0U) -#define PA37_USART1_RTS SF32LB_PINMUX(PA, 37U, 4U, 0x58U, 1U) -#define PA37_USART1_RXD SF32LB_PINMUX(PA, 37U, 4U, 0x58U, 2U) -#define PA37_USART1_TXD SF32LB_PINMUX(PA, 37U, 4U, 0x58U, 3U) -#define PA37_USART2_CTS SF32LB_PINMUX(PA, 37U, 4U, 0x5CU, 0U) -#define PA37_USART2_RTS SF32LB_PINMUX(PA, 37U, 4U, 0x5CU, 1U) -#define PA37_USART2_RXD SF32LB_PINMUX(PA, 37U, 4U, 0x5CU, 2U) -#define PA37_USART2_TXD SF32LB_PINMUX(PA, 37U, 4U, 0x5CU, 3U) -#define PA37_USART3_CTS SF32LB_PINMUX(PA, 37U, 4U, 0x60U, 0U) -#define PA37_USART3_RTS SF32LB_PINMUX(PA, 37U, 4U, 0x60U, 1U) -#define PA37_USART3_RXD SF32LB_PINMUX(PA, 37U, 4U, 0x60U, 2U) -#define PA37_USART3_TXD SF32LB_PINMUX(PA, 37U, 4U, 0x60U, 3U) -/* PA_I2C_UART functions end */ -/* PA_TIM functions start */ +#define PA37_USART1_TXD SF32LB_PINMUX(PA, 37U, 4U, 0x58U, 0U) +#define PA37_USART1_RXD SF32LB_PINMUX(PA, 37U, 4U, 0x58U, 1U) +#define PA37_USART1_RTS SF32LB_PINMUX(PA, 37U, 4U, 0x58U, 2U) +#define PA37_USART1_CTS SF32LB_PINMUX(PA, 37U, 4U, 0x58U, 3U) +#define PA37_USART2_TXD SF32LB_PINMUX(PA, 37U, 4U, 0x5CU, 0U) +#define PA37_USART2_RXD SF32LB_PINMUX(PA, 37U, 4U, 0x5CU, 1U) +#define PA37_USART2_RTS SF32LB_PINMUX(PA, 37U, 4U, 0x5CU, 2U) +#define PA37_USART2_CTS SF32LB_PINMUX(PA, 37U, 4U, 0x5CU, 3U) +#define PA37_USART3_TXD SF32LB_PINMUX(PA, 37U, 4U, 0x60U, 0U) +#define PA37_USART3_RXD SF32LB_PINMUX(PA, 37U, 4U, 0x60U, 1U) +#define PA37_USART3_RTS SF32LB_PINMUX(PA, 37U, 4U, 0x60U, 2U) +#define PA37_USART3_CTS SF32LB_PINMUX(PA, 37U, 4U, 0x60U, 3U) #define PA37_GPTIM1_CH1 SF32LB_PINMUX(PA, 37U, 5U, 0x64U, 0U) #define PA37_GPTIM1_CH2 SF32LB_PINMUX(PA, 37U, 5U, 0x64U, 1U) #define PA37_GPTIM1_CH3 SF32LB_PINMUX(PA, 37U, 5U, 0x64U, 2U) #define PA37_GPTIM1_CH4 SF32LB_PINMUX(PA, 37U, 5U, 0x64U, 3U) +#define PA37_GPTIM1_ETR SF32LB_PINMUX(PA, 37U, 5U, 0x6CU, 0U) #define PA37_GPTIM2_CH1 SF32LB_PINMUX(PA, 37U, 5U, 0x68U, 0U) #define PA37_GPTIM2_CH2 SF32LB_PINMUX(PA, 37U, 5U, 0x68U, 1U) #define PA37_GPTIM2_CH3 SF32LB_PINMUX(PA, 37U, 5U, 0x68U, 2U) #define PA37_GPTIM2_CH4 SF32LB_PINMUX(PA, 37U, 5U, 0x68U, 3U) -#define PA37_GPTIM1_ETR SF32LB_PINMUX(PA, 37U, 5U, 0x6CU, 0U) #define PA37_GPTIM2_ETR SF32LB_PINMUX(PA, 37U, 5U, 0x6CU, 1U) #define PA37_LPTIM1_IN SF32LB_PINMUX(PA, 37U, 5U, 0x70U, 0U) #define PA37_LPTIM1_OUT SF32LB_PINMUX(PA, 37U, 5U, 0x70U, 1U) @@ -2135,10 +1986,9 @@ #define PA37_ATIM1_CH1N SF32LB_PINMUX(PA, 37U, 5U, 0x7CU, 0U) #define PA37_ATIM1_CH2N SF32LB_PINMUX(PA, 37U, 5U, 0x7CU, 1U) #define PA37_ATIM1_CH3N SF32LB_PINMUX(PA, 37U, 5U, 0x7CU, 2U) +#define PA37_ATIM1_ETR SF32LB_PINMUX(PA, 37U, 5U, 0x80U, 2U) #define PA37_ATIM1_BK SF32LB_PINMUX(PA, 37U, 5U, 0x80U, 0U) #define PA37_ATIM1_BK2 SF32LB_PINMUX(PA, 37U, 5U, 0x80U, 1U) -#define PA37_ATIM1_ETR SF32LB_PINMUX(PA, 37U, 5U, 0x80U, 2U) -/* PA_TIM functions end */ #define PA37_LCDC1_8080_DIO2 SF32LB_PINMUX(PA, 37U, 7U, 0U, 0U) #define PA37_WKUP_PIN13 SF32LB_PINMUX(PA, 37U, 8U, 0U, 0U) @@ -2146,7 +1996,6 @@ #define PA38_ANALOG SF32LB_PINMUX_ANALOG(PA, 38U) #define PA38_GPIO SF32LB_PINMUX(PA, 38U, 0U, 0U, 0U) #define PA38_SPI2_DI SF32LB_PINMUX(PA, 38U, 2U, 0U, 0U) -/* PA_I2C_UART functions start */ #define PA38_I2C1_SCL SF32LB_PINMUX(PA, 38U, 4U, 0x48U, 0U) #define PA38_I2C1_SDA SF32LB_PINMUX(PA, 38U, 4U, 0x48U, 1U) #define PA38_I2C2_SCL SF32LB_PINMUX(PA, 38U, 4U, 0x4CU, 0U) @@ -2155,29 +2004,27 @@ #define PA38_I2C3_SDA SF32LB_PINMUX(PA, 38U, 4U, 0x50U, 1U) #define PA38_I2C4_SCL SF32LB_PINMUX(PA, 38U, 4U, 0x54U, 0U) #define PA38_I2C4_SDA SF32LB_PINMUX(PA, 38U, 4U, 0x54U, 1U) -#define PA38_USART1_CTS SF32LB_PINMUX(PA, 38U, 4U, 0x58U, 0U) -#define PA38_USART1_RTS SF32LB_PINMUX(PA, 38U, 4U, 0x58U, 1U) -#define PA38_USART1_RXD SF32LB_PINMUX(PA, 38U, 4U, 0x58U, 2U) -#define PA38_USART1_TXD SF32LB_PINMUX(PA, 38U, 4U, 0x58U, 3U) -#define PA38_USART2_CTS SF32LB_PINMUX(PA, 38U, 4U, 0x5CU, 0U) -#define PA38_USART2_RTS SF32LB_PINMUX(PA, 38U, 4U, 0x5CU, 1U) -#define PA38_USART2_RXD SF32LB_PINMUX(PA, 38U, 4U, 0x5CU, 2U) -#define PA38_USART2_TXD SF32LB_PINMUX(PA, 38U, 4U, 0x5CU, 3U) -#define PA38_USART3_CTS SF32LB_PINMUX(PA, 38U, 4U, 0x60U, 0U) -#define PA38_USART3_RTS SF32LB_PINMUX(PA, 38U, 4U, 0x60U, 1U) -#define PA38_USART3_RXD SF32LB_PINMUX(PA, 38U, 4U, 0x60U, 2U) -#define PA38_USART3_TXD SF32LB_PINMUX(PA, 38U, 4U, 0x60U, 3U) -/* PA_I2C_UART functions end */ -/* PA_TIM functions start */ +#define PA38_USART1_TXD SF32LB_PINMUX(PA, 38U, 4U, 0x58U, 0U) +#define PA38_USART1_RXD SF32LB_PINMUX(PA, 38U, 4U, 0x58U, 1U) +#define PA38_USART1_RTS SF32LB_PINMUX(PA, 38U, 4U, 0x58U, 2U) +#define PA38_USART1_CTS SF32LB_PINMUX(PA, 38U, 4U, 0x58U, 3U) +#define PA38_USART2_TXD SF32LB_PINMUX(PA, 38U, 4U, 0x5CU, 0U) +#define PA38_USART2_RXD SF32LB_PINMUX(PA, 38U, 4U, 0x5CU, 1U) +#define PA38_USART2_RTS SF32LB_PINMUX(PA, 38U, 4U, 0x5CU, 2U) +#define PA38_USART2_CTS SF32LB_PINMUX(PA, 38U, 4U, 0x5CU, 3U) +#define PA38_USART3_TXD SF32LB_PINMUX(PA, 38U, 4U, 0x60U, 0U) +#define PA38_USART3_RXD SF32LB_PINMUX(PA, 38U, 4U, 0x60U, 1U) +#define PA38_USART3_RTS SF32LB_PINMUX(PA, 38U, 4U, 0x60U, 2U) +#define PA38_USART3_CTS SF32LB_PINMUX(PA, 38U, 4U, 0x60U, 3U) #define PA38_GPTIM1_CH1 SF32LB_PINMUX(PA, 38U, 5U, 0x64U, 0U) #define PA38_GPTIM1_CH2 SF32LB_PINMUX(PA, 38U, 5U, 0x64U, 1U) #define PA38_GPTIM1_CH3 SF32LB_PINMUX(PA, 38U, 5U, 0x64U, 2U) #define PA38_GPTIM1_CH4 SF32LB_PINMUX(PA, 38U, 5U, 0x64U, 3U) +#define PA38_GPTIM1_ETR SF32LB_PINMUX(PA, 38U, 5U, 0x6CU, 0U) #define PA38_GPTIM2_CH1 SF32LB_PINMUX(PA, 38U, 5U, 0x68U, 0U) #define PA38_GPTIM2_CH2 SF32LB_PINMUX(PA, 38U, 5U, 0x68U, 1U) #define PA38_GPTIM2_CH3 SF32LB_PINMUX(PA, 38U, 5U, 0x68U, 2U) #define PA38_GPTIM2_CH4 SF32LB_PINMUX(PA, 38U, 5U, 0x68U, 3U) -#define PA38_GPTIM1_ETR SF32LB_PINMUX(PA, 38U, 5U, 0x6CU, 0U) #define PA38_GPTIM2_ETR SF32LB_PINMUX(PA, 38U, 5U, 0x6CU, 1U) #define PA38_LPTIM1_IN SF32LB_PINMUX(PA, 38U, 5U, 0x70U, 0U) #define PA38_LPTIM1_OUT SF32LB_PINMUX(PA, 38U, 5U, 0x70U, 1U) @@ -2192,18 +2039,15 @@ #define PA38_ATIM1_CH1N SF32LB_PINMUX(PA, 38U, 5U, 0x7CU, 0U) #define PA38_ATIM1_CH2N SF32LB_PINMUX(PA, 38U, 5U, 0x7CU, 1U) #define PA38_ATIM1_CH3N SF32LB_PINMUX(PA, 38U, 5U, 0x7CU, 2U) +#define PA38_ATIM1_ETR SF32LB_PINMUX(PA, 38U, 5U, 0x80U, 2U) #define PA38_ATIM1_BK SF32LB_PINMUX(PA, 38U, 5U, 0x80U, 0U) #define PA38_ATIM1_BK2 SF32LB_PINMUX(PA, 38U, 5U, 0x80U, 1U) -#define PA38_ATIM1_ETR SF32LB_PINMUX(PA, 38U, 5U, 0x80U, 2U) -/* PA_TIM functions end */ -#define PA38_LCDC1_8080_DIO2 SF32LB_PINMUX(PA, 38U, 7U, 0U, 0U) #define PA38_WKUP_PIN14 SF32LB_PINMUX(PA, 38U, 8U, 0U, 0U) /* PA39 */ #define PA39_ANALOG SF32LB_PINMUX_ANALOG(PA, 39U) #define PA39_GPIO SF32LB_PINMUX(PA, 39U, 0U, 0U, 0U) #define PA39_SPI2_CLK SF32LB_PINMUX(PA, 39U, 2U, 0U, 0U) -/* PA_I2C_UART functions start */ #define PA39_I2C1_SCL SF32LB_PINMUX(PA, 39U, 4U, 0x48U, 0U) #define PA39_I2C1_SDA SF32LB_PINMUX(PA, 39U, 4U, 0x48U, 1U) #define PA39_I2C2_SCL SF32LB_PINMUX(PA, 39U, 4U, 0x4CU, 0U) @@ -2212,29 +2056,27 @@ #define PA39_I2C3_SDA SF32LB_PINMUX(PA, 39U, 4U, 0x50U, 1U) #define PA39_I2C4_SCL SF32LB_PINMUX(PA, 39U, 4U, 0x54U, 0U) #define PA39_I2C4_SDA SF32LB_PINMUX(PA, 39U, 4U, 0x54U, 1U) -#define PA39_USART1_CTS SF32LB_PINMUX(PA, 39U, 4U, 0x58U, 0U) -#define PA39_USART1_RTS SF32LB_PINMUX(PA, 39U, 4U, 0x58U, 1U) -#define PA39_USART1_RXD SF32LB_PINMUX(PA, 39U, 4U, 0x58U, 2U) -#define PA39_USART1_TXD SF32LB_PINMUX(PA, 39U, 4U, 0x58U, 3U) -#define PA39_USART2_CTS SF32LB_PINMUX(PA, 39U, 4U, 0x5CU, 0U) -#define PA39_USART2_RTS SF32LB_PINMUX(PA, 39U, 4U, 0x5CU, 1U) -#define PA39_USART2_RXD SF32LB_PINMUX(PA, 39U, 4U, 0x5CU, 2U) -#define PA39_USART2_TXD SF32LB_PINMUX(PA, 39U, 4U, 0x5CU, 3U) -#define PA39_USART3_CTS SF32LB_PINMUX(PA, 39U, 4U, 0x60U, 0U) -#define PA39_USART3_RTS SF32LB_PINMUX(PA, 39U, 4U, 0x60U, 1U) -#define PA39_USART3_RXD SF32LB_PINMUX(PA, 39U, 4U, 0x60U, 2U) -#define PA39_USART3_TXD SF32LB_PINMUX(PA, 39U, 4U, 0x60U, 3U) -/* PA_I2C_UART functions end */ -/* PA_TIM functions start */ +#define PA39_USART1_TXD SF32LB_PINMUX(PA, 39U, 4U, 0x58U, 0U) +#define PA39_USART1_RXD SF32LB_PINMUX(PA, 39U, 4U, 0x58U, 1U) +#define PA39_USART1_RTS SF32LB_PINMUX(PA, 39U, 4U, 0x58U, 2U) +#define PA39_USART1_CTS SF32LB_PINMUX(PA, 39U, 4U, 0x58U, 3U) +#define PA39_USART2_TXD SF32LB_PINMUX(PA, 39U, 4U, 0x5CU, 0U) +#define PA39_USART2_RXD SF32LB_PINMUX(PA, 39U, 4U, 0x5CU, 1U) +#define PA39_USART2_RTS SF32LB_PINMUX(PA, 39U, 4U, 0x5CU, 2U) +#define PA39_USART2_CTS SF32LB_PINMUX(PA, 39U, 4U, 0x5CU, 3U) +#define PA39_USART3_TXD SF32LB_PINMUX(PA, 39U, 4U, 0x60U, 0U) +#define PA39_USART3_RXD SF32LB_PINMUX(PA, 39U, 4U, 0x60U, 1U) +#define PA39_USART3_RTS SF32LB_PINMUX(PA, 39U, 4U, 0x60U, 2U) +#define PA39_USART3_CTS SF32LB_PINMUX(PA, 39U, 4U, 0x60U, 3U) #define PA39_GPTIM1_CH1 SF32LB_PINMUX(PA, 39U, 5U, 0x64U, 0U) #define PA39_GPTIM1_CH2 SF32LB_PINMUX(PA, 39U, 5U, 0x64U, 1U) #define PA39_GPTIM1_CH3 SF32LB_PINMUX(PA, 39U, 5U, 0x64U, 2U) #define PA39_GPTIM1_CH4 SF32LB_PINMUX(PA, 39U, 5U, 0x64U, 3U) +#define PA39_GPTIM1_ETR SF32LB_PINMUX(PA, 39U, 5U, 0x6CU, 0U) #define PA39_GPTIM2_CH1 SF32LB_PINMUX(PA, 39U, 5U, 0x68U, 0U) #define PA39_GPTIM2_CH2 SF32LB_PINMUX(PA, 39U, 5U, 0x68U, 1U) #define PA39_GPTIM2_CH3 SF32LB_PINMUX(PA, 39U, 5U, 0x68U, 2U) #define PA39_GPTIM2_CH4 SF32LB_PINMUX(PA, 39U, 5U, 0x68U, 3U) -#define PA39_GPTIM1_ETR SF32LB_PINMUX(PA, 39U, 5U, 0x6CU, 0U) #define PA39_GPTIM2_ETR SF32LB_PINMUX(PA, 39U, 5U, 0x6CU, 1U) #define PA39_LPTIM1_IN SF32LB_PINMUX(PA, 39U, 5U, 0x70U, 0U) #define PA39_LPTIM1_OUT SF32LB_PINMUX(PA, 39U, 5U, 0x70U, 1U) @@ -2249,10 +2091,9 @@ #define PA39_ATIM1_CH1N SF32LB_PINMUX(PA, 39U, 5U, 0x7CU, 0U) #define PA39_ATIM1_CH2N SF32LB_PINMUX(PA, 39U, 5U, 0x7CU, 1U) #define PA39_ATIM1_CH3N SF32LB_PINMUX(PA, 39U, 5U, 0x7CU, 2U) +#define PA39_ATIM1_ETR SF32LB_PINMUX(PA, 39U, 5U, 0x80U, 2U) #define PA39_ATIM1_BK SF32LB_PINMUX(PA, 39U, 5U, 0x80U, 0U) #define PA39_ATIM1_BK2 SF32LB_PINMUX(PA, 39U, 5U, 0x80U, 1U) -#define PA39_ATIM1_ETR SF32LB_PINMUX(PA, 39U, 5U, 0x80U, 2U) -/* PA_TIM functions end */ #define PA39_LCDC1_JDI_VCK SF32LB_PINMUX(PA, 39U, 6U, 0U, 0U) #define PA39_LCDC1_8080_DIO3 SF32LB_PINMUX(PA, 39U, 7U, 0U, 0U) #define PA39_WKUP_PIN15 SF32LB_PINMUX(PA, 39U, 8U, 0U, 0U) @@ -2261,7 +2102,6 @@ #define PA40_ANALOG SF32LB_PINMUX_ANALOG(PA, 40U) #define PA40_GPIO SF32LB_PINMUX(PA, 40U, 0U, 0U, 0U) #define PA40_SPI2_CS SF32LB_PINMUX(PA, 40U, 2U, 0U, 0U) -/* PA_I2C_UART functions start */ #define PA40_I2C1_SCL SF32LB_PINMUX(PA, 40U, 4U, 0x48U, 0U) #define PA40_I2C1_SDA SF32LB_PINMUX(PA, 40U, 4U, 0x48U, 1U) #define PA40_I2C2_SCL SF32LB_PINMUX(PA, 40U, 4U, 0x4CU, 0U) @@ -2270,29 +2110,27 @@ #define PA40_I2C3_SDA SF32LB_PINMUX(PA, 40U, 4U, 0x50U, 1U) #define PA40_I2C4_SCL SF32LB_PINMUX(PA, 40U, 4U, 0x54U, 0U) #define PA40_I2C4_SDA SF32LB_PINMUX(PA, 40U, 4U, 0x54U, 1U) -#define PA40_USART1_CTS SF32LB_PINMUX(PA, 40U, 4U, 0x58U, 0U) -#define PA40_USART1_RTS SF32LB_PINMUX(PA, 40U, 4U, 0x58U, 1U) -#define PA40_USART1_RXD SF32LB_PINMUX(PA, 40U, 4U, 0x58U, 2U) -#define PA40_USART1_TXD SF32LB_PINMUX(PA, 40U, 4U, 0x58U, 3U) -#define PA40_USART2_CTS SF32LB_PINMUX(PA, 40U, 4U, 0x5CU, 0U) -#define PA40_USART2_RTS SF32LB_PINMUX(PA, 40U, 4U, 0x5CU, 1U) -#define PA40_USART2_RXD SF32LB_PINMUX(PA, 40U, 4U, 0x5CU, 2U) -#define PA40_USART2_TXD SF32LB_PINMUX(PA, 40U, 4U, 0x5CU, 3U) -#define PA40_USART3_CTS SF32LB_PINMUX(PA, 40U, 4U, 0x60U, 0U) -#define PA40_USART3_RTS SF32LB_PINMUX(PA, 40U, 4U, 0x60U, 1U) -#define PA40_USART3_RXD SF32LB_PINMUX(PA, 40U, 4U, 0x60U, 2U) -#define PA40_USART3_TXD SF32LB_PINMUX(PA, 40U, 4U, 0x60U, 3U) -/* PA_I2C_UART functions end */ -/* PA_TIM functions start */ +#define PA40_USART1_TXD SF32LB_PINMUX(PA, 40U, 4U, 0x58U, 0U) +#define PA40_USART1_RXD SF32LB_PINMUX(PA, 40U, 4U, 0x58U, 1U) +#define PA40_USART1_RTS SF32LB_PINMUX(PA, 40U, 4U, 0x58U, 2U) +#define PA40_USART1_CTS SF32LB_PINMUX(PA, 40U, 4U, 0x58U, 3U) +#define PA40_USART2_TXD SF32LB_PINMUX(PA, 40U, 4U, 0x5CU, 0U) +#define PA40_USART2_RXD SF32LB_PINMUX(PA, 40U, 4U, 0x5CU, 1U) +#define PA40_USART2_RTS SF32LB_PINMUX(PA, 40U, 4U, 0x5CU, 2U) +#define PA40_USART2_CTS SF32LB_PINMUX(PA, 40U, 4U, 0x5CU, 3U) +#define PA40_USART3_TXD SF32LB_PINMUX(PA, 40U, 4U, 0x60U, 0U) +#define PA40_USART3_RXD SF32LB_PINMUX(PA, 40U, 4U, 0x60U, 1U) +#define PA40_USART3_RTS SF32LB_PINMUX(PA, 40U, 4U, 0x60U, 2U) +#define PA40_USART3_CTS SF32LB_PINMUX(PA, 40U, 4U, 0x60U, 3U) #define PA40_GPTIM1_CH1 SF32LB_PINMUX(PA, 40U, 5U, 0x64U, 0U) #define PA40_GPTIM1_CH2 SF32LB_PINMUX(PA, 40U, 5U, 0x64U, 1U) #define PA40_GPTIM1_CH3 SF32LB_PINMUX(PA, 40U, 5U, 0x64U, 2U) #define PA40_GPTIM1_CH4 SF32LB_PINMUX(PA, 40U, 5U, 0x64U, 3U) +#define PA40_GPTIM1_ETR SF32LB_PINMUX(PA, 40U, 5U, 0x6CU, 0U) #define PA40_GPTIM2_CH1 SF32LB_PINMUX(PA, 40U, 5U, 0x68U, 0U) #define PA40_GPTIM2_CH2 SF32LB_PINMUX(PA, 40U, 5U, 0x68U, 1U) #define PA40_GPTIM2_CH3 SF32LB_PINMUX(PA, 40U, 5U, 0x68U, 2U) #define PA40_GPTIM2_CH4 SF32LB_PINMUX(PA, 40U, 5U, 0x68U, 3U) -#define PA40_GPTIM1_ETR SF32LB_PINMUX(PA, 40U, 5U, 0x6CU, 0U) #define PA40_GPTIM2_ETR SF32LB_PINMUX(PA, 40U, 5U, 0x6CU, 1U) #define PA40_LPTIM1_IN SF32LB_PINMUX(PA, 40U, 5U, 0x70U, 0U) #define PA40_LPTIM1_OUT SF32LB_PINMUX(PA, 40U, 5U, 0x70U, 1U) @@ -2307,10 +2145,9 @@ #define PA40_ATIM1_CH1N SF32LB_PINMUX(PA, 40U, 5U, 0x7CU, 0U) #define PA40_ATIM1_CH2N SF32LB_PINMUX(PA, 40U, 5U, 0x7CU, 1U) #define PA40_ATIM1_CH3N SF32LB_PINMUX(PA, 40U, 5U, 0x7CU, 2U) +#define PA40_ATIM1_ETR SF32LB_PINMUX(PA, 40U, 5U, 0x80U, 2U) #define PA40_ATIM1_BK SF32LB_PINMUX(PA, 40U, 5U, 0x80U, 0U) #define PA40_ATIM1_BK2 SF32LB_PINMUX(PA, 40U, 5U, 0x80U, 1U) -#define PA40_ATIM1_ETR SF32LB_PINMUX(PA, 40U, 5U, 0x80U, 2U) -/* PA_TIM functions end */ #define PA40_LCDC1_JDI_XRST SF32LB_PINMUX(PA, 40U, 6U, 0U, 0U) #define PA40_LCDC1_8080_DIO4 SF32LB_PINMUX(PA, 40U, 7U, 0U, 0U) #define PA40_WKUP_PIN16 SF32LB_PINMUX(PA, 40U, 8U, 0U, 0U) @@ -2318,7 +2155,6 @@ /* PA41 */ #define PA41_ANALOG SF32LB_PINMUX_ANALOG(PA, 41U) #define PA41_GPIO SF32LB_PINMUX(PA, 41U, 0U, 0U, 0U) -/* PA_I2C_UART functions start */ #define PA41_I2C1_SCL SF32LB_PINMUX(PA, 41U, 4U, 0x48U, 0U) #define PA41_I2C1_SDA SF32LB_PINMUX(PA, 41U, 4U, 0x48U, 1U) #define PA41_I2C2_SCL SF32LB_PINMUX(PA, 41U, 4U, 0x4CU, 0U) @@ -2327,29 +2163,27 @@ #define PA41_I2C3_SDA SF32LB_PINMUX(PA, 41U, 4U, 0x50U, 1U) #define PA41_I2C4_SCL SF32LB_PINMUX(PA, 41U, 4U, 0x54U, 0U) #define PA41_I2C4_SDA SF32LB_PINMUX(PA, 41U, 4U, 0x54U, 1U) -#define PA41_USART1_CTS SF32LB_PINMUX(PA, 41U, 4U, 0x58U, 0U) -#define PA41_USART1_RTS SF32LB_PINMUX(PA, 41U, 4U, 0x58U, 1U) -#define PA41_USART1_RXD SF32LB_PINMUX(PA, 41U, 4U, 0x58U, 2U) -#define PA41_USART1_TXD SF32LB_PINMUX(PA, 41U, 4U, 0x58U, 3U) -#define PA41_USART2_CTS SF32LB_PINMUX(PA, 41U, 4U, 0x5CU, 0U) -#define PA41_USART2_RTS SF32LB_PINMUX(PA, 41U, 4U, 0x5CU, 1U) -#define PA41_USART2_RXD SF32LB_PINMUX(PA, 41U, 4U, 0x5CU, 2U) -#define PA41_USART2_TXD SF32LB_PINMUX(PA, 41U, 4U, 0x5CU, 3U) -#define PA41_USART3_CTS SF32LB_PINMUX(PA, 41U, 4U, 0x60U, 0U) -#define PA41_USART3_RTS SF32LB_PINMUX(PA, 41U, 4U, 0x60U, 1U) -#define PA41_USART3_RXD SF32LB_PINMUX(PA, 41U, 4U, 0x60U, 2U) -#define PA41_USART3_TXD SF32LB_PINMUX(PA, 41U, 4U, 0x60U, 3U) -/* PA_I2C_UART functions end */ -/* PA_TIM functions start */ +#define PA41_USART1_TXD SF32LB_PINMUX(PA, 41U, 4U, 0x58U, 0U) +#define PA41_USART1_RXD SF32LB_PINMUX(PA, 41U, 4U, 0x58U, 1U) +#define PA41_USART1_RTS SF32LB_PINMUX(PA, 41U, 4U, 0x58U, 2U) +#define PA41_USART1_CTS SF32LB_PINMUX(PA, 41U, 4U, 0x58U, 3U) +#define PA41_USART2_TXD SF32LB_PINMUX(PA, 41U, 4U, 0x5CU, 0U) +#define PA41_USART2_RXD SF32LB_PINMUX(PA, 41U, 4U, 0x5CU, 1U) +#define PA41_USART2_RTS SF32LB_PINMUX(PA, 41U, 4U, 0x5CU, 2U) +#define PA41_USART2_CTS SF32LB_PINMUX(PA, 41U, 4U, 0x5CU, 3U) +#define PA41_USART3_TXD SF32LB_PINMUX(PA, 41U, 4U, 0x60U, 0U) +#define PA41_USART3_RXD SF32LB_PINMUX(PA, 41U, 4U, 0x60U, 1U) +#define PA41_USART3_RTS SF32LB_PINMUX(PA, 41U, 4U, 0x60U, 2U) +#define PA41_USART3_CTS SF32LB_PINMUX(PA, 41U, 4U, 0x60U, 3U) #define PA41_GPTIM1_CH1 SF32LB_PINMUX(PA, 41U, 5U, 0x64U, 0U) #define PA41_GPTIM1_CH2 SF32LB_PINMUX(PA, 41U, 5U, 0x64U, 1U) #define PA41_GPTIM1_CH3 SF32LB_PINMUX(PA, 41U, 5U, 0x64U, 2U) #define PA41_GPTIM1_CH4 SF32LB_PINMUX(PA, 41U, 5U, 0x64U, 3U) +#define PA41_GPTIM1_ETR SF32LB_PINMUX(PA, 41U, 5U, 0x6CU, 0U) #define PA41_GPTIM2_CH1 SF32LB_PINMUX(PA, 41U, 5U, 0x68U, 0U) #define PA41_GPTIM2_CH2 SF32LB_PINMUX(PA, 41U, 5U, 0x68U, 1U) #define PA41_GPTIM2_CH3 SF32LB_PINMUX(PA, 41U, 5U, 0x68U, 2U) #define PA41_GPTIM2_CH4 SF32LB_PINMUX(PA, 41U, 5U, 0x68U, 3U) -#define PA41_GPTIM1_ETR SF32LB_PINMUX(PA, 41U, 5U, 0x6CU, 0U) #define PA41_GPTIM2_ETR SF32LB_PINMUX(PA, 41U, 5U, 0x6CU, 1U) #define PA41_LPTIM1_IN SF32LB_PINMUX(PA, 41U, 5U, 0x70U, 0U) #define PA41_LPTIM1_OUT SF32LB_PINMUX(PA, 41U, 5U, 0x70U, 1U) @@ -2364,10 +2198,9 @@ #define PA41_ATIM1_CH1N SF32LB_PINMUX(PA, 41U, 5U, 0x7CU, 0U) #define PA41_ATIM1_CH2N SF32LB_PINMUX(PA, 41U, 5U, 0x7CU, 1U) #define PA41_ATIM1_CH3N SF32LB_PINMUX(PA, 41U, 5U, 0x7CU, 2U) +#define PA41_ATIM1_ETR SF32LB_PINMUX(PA, 41U, 5U, 0x80U, 2U) #define PA41_ATIM1_BK SF32LB_PINMUX(PA, 41U, 5U, 0x80U, 0U) #define PA41_ATIM1_BK2 SF32LB_PINMUX(PA, 41U, 5U, 0x80U, 1U) -#define PA41_ATIM1_ETR SF32LB_PINMUX(PA, 41U, 5U, 0x80U, 2U) -/* PA_TIM functions end */ #define PA41_LCDC1_JDI_HCK SF32LB_PINMUX(PA, 41U, 6U, 0U, 0U) #define PA41_LCDC1_8080_DIO5 SF32LB_PINMUX(PA, 41U, 7U, 0U, 0U) #define PA41_WKUP_PIN17 SF32LB_PINMUX(PA, 41U, 8U, 0U, 0U) @@ -2375,7 +2208,6 @@ /* PA42 */ #define PA42_ANALOG SF32LB_PINMUX_ANALOG(PA, 42U) #define PA42_GPIO SF32LB_PINMUX(PA, 42U, 0U, 0U, 0U) -/* PA_I2C_UART functions start */ #define PA42_I2C1_SCL SF32LB_PINMUX(PA, 42U, 4U, 0x48U, 0U) #define PA42_I2C1_SDA SF32LB_PINMUX(PA, 42U, 4U, 0x48U, 1U) #define PA42_I2C2_SCL SF32LB_PINMUX(PA, 42U, 4U, 0x4CU, 0U) @@ -2384,29 +2216,27 @@ #define PA42_I2C3_SDA SF32LB_PINMUX(PA, 42U, 4U, 0x50U, 1U) #define PA42_I2C4_SCL SF32LB_PINMUX(PA, 42U, 4U, 0x54U, 0U) #define PA42_I2C4_SDA SF32LB_PINMUX(PA, 42U, 4U, 0x54U, 1U) -#define PA42_USART1_CTS SF32LB_PINMUX(PA, 42U, 4U, 0x58U, 0U) -#define PA42_USART1_RTS SF32LB_PINMUX(PA, 42U, 4U, 0x58U, 1U) -#define PA42_USART1_RXD SF32LB_PINMUX(PA, 42U, 4U, 0x58U, 2U) -#define PA42_USART1_TXD SF32LB_PINMUX(PA, 42U, 4U, 0x58U, 3U) -#define PA42_USART2_CTS SF32LB_PINMUX(PA, 42U, 4U, 0x5CU, 0U) -#define PA42_USART2_RTS SF32LB_PINMUX(PA, 42U, 4U, 0x5CU, 1U) -#define PA42_USART2_RXD SF32LB_PINMUX(PA, 42U, 4U, 0x5CU, 2U) -#define PA42_USART2_TXD SF32LB_PINMUX(PA, 42U, 4U, 0x5CU, 3U) -#define PA42_USART3_CTS SF32LB_PINMUX(PA, 42U, 4U, 0x60U, 0U) -#define PA42_USART3_RTS SF32LB_PINMUX(PA, 42U, 4U, 0x60U, 1U) -#define PA42_USART3_RXD SF32LB_PINMUX(PA, 42U, 4U, 0x60U, 2U) -#define PA42_USART3_TXD SF32LB_PINMUX(PA, 42U, 4U, 0x60U, 3U) -/* PA_I2C_UART functions end */ -/* PA_TIM functions start */ +#define PA42_USART1_TXD SF32LB_PINMUX(PA, 42U, 4U, 0x58U, 0U) +#define PA42_USART1_RXD SF32LB_PINMUX(PA, 42U, 4U, 0x58U, 1U) +#define PA42_USART1_RTS SF32LB_PINMUX(PA, 42U, 4U, 0x58U, 2U) +#define PA42_USART1_CTS SF32LB_PINMUX(PA, 42U, 4U, 0x58U, 3U) +#define PA42_USART2_TXD SF32LB_PINMUX(PA, 42U, 4U, 0x5CU, 0U) +#define PA42_USART2_RXD SF32LB_PINMUX(PA, 42U, 4U, 0x5CU, 1U) +#define PA42_USART2_RTS SF32LB_PINMUX(PA, 42U, 4U, 0x5CU, 2U) +#define PA42_USART2_CTS SF32LB_PINMUX(PA, 42U, 4U, 0x5CU, 3U) +#define PA42_USART3_TXD SF32LB_PINMUX(PA, 42U, 4U, 0x60U, 0U) +#define PA42_USART3_RXD SF32LB_PINMUX(PA, 42U, 4U, 0x60U, 1U) +#define PA42_USART3_RTS SF32LB_PINMUX(PA, 42U, 4U, 0x60U, 2U) +#define PA42_USART3_CTS SF32LB_PINMUX(PA, 42U, 4U, 0x60U, 3U) #define PA42_GPTIM1_CH1 SF32LB_PINMUX(PA, 42U, 5U, 0x64U, 0U) #define PA42_GPTIM1_CH2 SF32LB_PINMUX(PA, 42U, 5U, 0x64U, 1U) #define PA42_GPTIM1_CH3 SF32LB_PINMUX(PA, 42U, 5U, 0x64U, 2U) #define PA42_GPTIM1_CH4 SF32LB_PINMUX(PA, 42U, 5U, 0x64U, 3U) +#define PA42_GPTIM1_ETR SF32LB_PINMUX(PA, 42U, 5U, 0x6CU, 0U) #define PA42_GPTIM2_CH1 SF32LB_PINMUX(PA, 42U, 5U, 0x68U, 0U) #define PA42_GPTIM2_CH2 SF32LB_PINMUX(PA, 42U, 5U, 0x68U, 1U) #define PA42_GPTIM2_CH3 SF32LB_PINMUX(PA, 42U, 5U, 0x68U, 2U) #define PA42_GPTIM2_CH4 SF32LB_PINMUX(PA, 42U, 5U, 0x68U, 3U) -#define PA42_GPTIM1_ETR SF32LB_PINMUX(PA, 42U, 5U, 0x6CU, 0U) #define PA42_GPTIM2_ETR SF32LB_PINMUX(PA, 42U, 5U, 0x6CU, 1U) #define PA42_LPTIM1_IN SF32LB_PINMUX(PA, 42U, 5U, 0x70U, 0U) #define PA42_LPTIM1_OUT SF32LB_PINMUX(PA, 42U, 5U, 0x70U, 1U) @@ -2421,10 +2251,9 @@ #define PA42_ATIM1_CH1N SF32LB_PINMUX(PA, 42U, 5U, 0x7CU, 0U) #define PA42_ATIM1_CH2N SF32LB_PINMUX(PA, 42U, 5U, 0x7CU, 1U) #define PA42_ATIM1_CH3N SF32LB_PINMUX(PA, 42U, 5U, 0x7CU, 2U) +#define PA42_ATIM1_ETR SF32LB_PINMUX(PA, 42U, 5U, 0x80U, 2U) #define PA42_ATIM1_BK SF32LB_PINMUX(PA, 42U, 5U, 0x80U, 0U) #define PA42_ATIM1_BK2 SF32LB_PINMUX(PA, 42U, 5U, 0x80U, 1U) -#define PA42_ATIM1_ETR SF32LB_PINMUX(PA, 42U, 5U, 0x80U, 2U) -/* PA_TIM functions end */ #define PA42_LCDC1_JDI_R2 SF32LB_PINMUX(PA, 42U, 6U, 0U, 0U) #define PA42_LCDC1_8080_DIO6 SF32LB_PINMUX(PA, 42U, 7U, 0U, 0U) #define PA42_WKUP_PIN18 SF32LB_PINMUX(PA, 42U, 8U, 0U, 0U) @@ -2432,7 +2261,6 @@ /* PA43 */ #define PA43_ANALOG SF32LB_PINMUX_ANALOG(PA, 43U) #define PA43_GPIO SF32LB_PINMUX(PA, 43U, 0U, 0U, 0U) -/* PA_I2C_UART functions start */ #define PA43_I2C1_SCL SF32LB_PINMUX(PA, 43U, 4U, 0x48U, 0U) #define PA43_I2C1_SDA SF32LB_PINMUX(PA, 43U, 4U, 0x48U, 1U) #define PA43_I2C2_SCL SF32LB_PINMUX(PA, 43U, 4U, 0x4CU, 0U) @@ -2441,29 +2269,27 @@ #define PA43_I2C3_SDA SF32LB_PINMUX(PA, 43U, 4U, 0x50U, 1U) #define PA43_I2C4_SCL SF32LB_PINMUX(PA, 43U, 4U, 0x54U, 0U) #define PA43_I2C4_SDA SF32LB_PINMUX(PA, 43U, 4U, 0x54U, 1U) -#define PA43_USART1_CTS SF32LB_PINMUX(PA, 43U, 4U, 0x58U, 0U) -#define PA43_USART1_RTS SF32LB_PINMUX(PA, 43U, 4U, 0x58U, 1U) -#define PA43_USART1_RXD SF32LB_PINMUX(PA, 43U, 4U, 0x58U, 2U) -#define PA43_USART1_TXD SF32LB_PINMUX(PA, 43U, 4U, 0x58U, 3U) -#define PA43_USART2_CTS SF32LB_PINMUX(PA, 43U, 4U, 0x5CU, 0U) -#define PA43_USART2_RTS SF32LB_PINMUX(PA, 43U, 4U, 0x5CU, 1U) -#define PA43_USART2_RXD SF32LB_PINMUX(PA, 43U, 4U, 0x5CU, 2U) -#define PA43_USART2_TXD SF32LB_PINMUX(PA, 43U, 4U, 0x5CU, 3U) -#define PA43_USART3_CTS SF32LB_PINMUX(PA, 43U, 4U, 0x60U, 0U) -#define PA43_USART3_RTS SF32LB_PINMUX(PA, 43U, 4U, 0x60U, 1U) -#define PA43_USART3_RXD SF32LB_PINMUX(PA, 43U, 4U, 0x60U, 2U) -#define PA43_USART3_TXD SF32LB_PINMUX(PA, 43U, 4U, 0x60U, 3U) -/* PA_I2C_UART functions end */ -/* PA_TIM functions start */ +#define PA43_USART1_TXD SF32LB_PINMUX(PA, 43U, 4U, 0x58U, 0U) +#define PA43_USART1_RXD SF32LB_PINMUX(PA, 43U, 4U, 0x58U, 1U) +#define PA43_USART1_RTS SF32LB_PINMUX(PA, 43U, 4U, 0x58U, 2U) +#define PA43_USART1_CTS SF32LB_PINMUX(PA, 43U, 4U, 0x58U, 3U) +#define PA43_USART2_TXD SF32LB_PINMUX(PA, 43U, 4U, 0x5CU, 0U) +#define PA43_USART2_RXD SF32LB_PINMUX(PA, 43U, 4U, 0x5CU, 1U) +#define PA43_USART2_RTS SF32LB_PINMUX(PA, 43U, 4U, 0x5CU, 2U) +#define PA43_USART2_CTS SF32LB_PINMUX(PA, 43U, 4U, 0x5CU, 3U) +#define PA43_USART3_TXD SF32LB_PINMUX(PA, 43U, 4U, 0x60U, 0U) +#define PA43_USART3_RXD SF32LB_PINMUX(PA, 43U, 4U, 0x60U, 1U) +#define PA43_USART3_RTS SF32LB_PINMUX(PA, 43U, 4U, 0x60U, 2U) +#define PA43_USART3_CTS SF32LB_PINMUX(PA, 43U, 4U, 0x60U, 3U) #define PA43_GPTIM1_CH1 SF32LB_PINMUX(PA, 43U, 5U, 0x64U, 0U) #define PA43_GPTIM1_CH2 SF32LB_PINMUX(PA, 43U, 5U, 0x64U, 1U) #define PA43_GPTIM1_CH3 SF32LB_PINMUX(PA, 43U, 5U, 0x64U, 2U) #define PA43_GPTIM1_CH4 SF32LB_PINMUX(PA, 43U, 5U, 0x64U, 3U) +#define PA43_GPTIM1_ETR SF32LB_PINMUX(PA, 43U, 5U, 0x6CU, 0U) #define PA43_GPTIM2_CH1 SF32LB_PINMUX(PA, 43U, 5U, 0x68U, 0U) #define PA43_GPTIM2_CH2 SF32LB_PINMUX(PA, 43U, 5U, 0x68U, 1U) #define PA43_GPTIM2_CH3 SF32LB_PINMUX(PA, 43U, 5U, 0x68U, 2U) #define PA43_GPTIM2_CH4 SF32LB_PINMUX(PA, 43U, 5U, 0x68U, 3U) -#define PA43_GPTIM1_ETR SF32LB_PINMUX(PA, 43U, 5U, 0x6CU, 0U) #define PA43_GPTIM2_ETR SF32LB_PINMUX(PA, 43U, 5U, 0x6CU, 1U) #define PA43_LPTIM1_IN SF32LB_PINMUX(PA, 43U, 5U, 0x70U, 0U) #define PA43_LPTIM1_OUT SF32LB_PINMUX(PA, 43U, 5U, 0x70U, 1U) @@ -2478,10 +2304,9 @@ #define PA43_ATIM1_CH1N SF32LB_PINMUX(PA, 43U, 5U, 0x7CU, 0U) #define PA43_ATIM1_CH2N SF32LB_PINMUX(PA, 43U, 5U, 0x7CU, 1U) #define PA43_ATIM1_CH3N SF32LB_PINMUX(PA, 43U, 5U, 0x7CU, 2U) +#define PA43_ATIM1_ETR SF32LB_PINMUX(PA, 43U, 5U, 0x80U, 2U) #define PA43_ATIM1_BK SF32LB_PINMUX(PA, 43U, 5U, 0x80U, 0U) #define PA43_ATIM1_BK2 SF32LB_PINMUX(PA, 43U, 5U, 0x80U, 1U) -#define PA43_ATIM1_ETR SF32LB_PINMUX(PA, 43U, 5U, 0x80U, 2U) -/* PA_TIM functions end */ #define PA43_LCDC1_JDI_G2 SF32LB_PINMUX(PA, 43U, 6U, 0U, 0U) #define PA43_LCDC1_8080_DIO7 SF32LB_PINMUX(PA, 43U, 7U, 0U, 0U) #define PA43_WKUP_PIN19 SF32LB_PINMUX(PA, 43U, 8U, 0U, 0U) @@ -2489,7 +2314,6 @@ /* PA44 */ #define PA44_ANALOG SF32LB_PINMUX_ANALOG(PA, 44U) #define PA44_GPIO SF32LB_PINMUX(PA, 44U, 0U, 0U, 0U) -/* PA_I2C_UART functions start */ #define PA44_I2C1_SCL SF32LB_PINMUX(PA, 44U, 4U, 0x48U, 0U) #define PA44_I2C1_SDA SF32LB_PINMUX(PA, 44U, 4U, 0x48U, 1U) #define PA44_I2C2_SCL SF32LB_PINMUX(PA, 44U, 4U, 0x4CU, 0U) @@ -2498,29 +2322,27 @@ #define PA44_I2C3_SDA SF32LB_PINMUX(PA, 44U, 4U, 0x50U, 1U) #define PA44_I2C4_SCL SF32LB_PINMUX(PA, 44U, 4U, 0x54U, 0U) #define PA44_I2C4_SDA SF32LB_PINMUX(PA, 44U, 4U, 0x54U, 1U) -#define PA44_USART1_CTS SF32LB_PINMUX(PA, 44U, 4U, 0x58U, 0U) -#define PA44_USART1_RTS SF32LB_PINMUX(PA, 44U, 4U, 0x58U, 1U) -#define PA44_USART1_RXD SF32LB_PINMUX(PA, 44U, 4U, 0x58U, 2U) -#define PA44_USART1_TXD SF32LB_PINMUX(PA, 44U, 4U, 0x58U, 3U) -#define PA44_USART2_CTS SF32LB_PINMUX(PA, 44U, 4U, 0x5CU, 0U) -#define PA44_USART2_RTS SF32LB_PINMUX(PA, 44U, 4U, 0x5CU, 1U) -#define PA44_USART2_RXD SF32LB_PINMUX(PA, 44U, 4U, 0x5CU, 2U) -#define PA44_USART2_TXD SF32LB_PINMUX(PA, 44U, 4U, 0x5CU, 3U) -#define PA44_USART3_CTS SF32LB_PINMUX(PA, 44U, 4U, 0x60U, 0U) -#define PA44_USART3_RTS SF32LB_PINMUX(PA, 44U, 4U, 0x60U, 1U) -#define PA44_USART3_RXD SF32LB_PINMUX(PA, 44U, 4U, 0x60U, 2U) -#define PA44_USART3_TXD SF32LB_PINMUX(PA, 44U, 4U, 0x60U, 3U) -/* PA_I2C_UART functions end */ -/* PA_TIM functions start */ +#define PA44_USART1_TXD SF32LB_PINMUX(PA, 44U, 4U, 0x58U, 0U) +#define PA44_USART1_RXD SF32LB_PINMUX(PA, 44U, 4U, 0x58U, 1U) +#define PA44_USART1_RTS SF32LB_PINMUX(PA, 44U, 4U, 0x58U, 2U) +#define PA44_USART1_CTS SF32LB_PINMUX(PA, 44U, 4U, 0x58U, 3U) +#define PA44_USART2_TXD SF32LB_PINMUX(PA, 44U, 4U, 0x5CU, 0U) +#define PA44_USART2_RXD SF32LB_PINMUX(PA, 44U, 4U, 0x5CU, 1U) +#define PA44_USART2_RTS SF32LB_PINMUX(PA, 44U, 4U, 0x5CU, 2U) +#define PA44_USART2_CTS SF32LB_PINMUX(PA, 44U, 4U, 0x5CU, 3U) +#define PA44_USART3_TXD SF32LB_PINMUX(PA, 44U, 4U, 0x60U, 0U) +#define PA44_USART3_RXD SF32LB_PINMUX(PA, 44U, 4U, 0x60U, 1U) +#define PA44_USART3_RTS SF32LB_PINMUX(PA, 44U, 4U, 0x60U, 2U) +#define PA44_USART3_CTS SF32LB_PINMUX(PA, 44U, 4U, 0x60U, 3U) #define PA44_GPTIM1_CH1 SF32LB_PINMUX(PA, 44U, 5U, 0x64U, 0U) #define PA44_GPTIM1_CH2 SF32LB_PINMUX(PA, 44U, 5U, 0x64U, 1U) #define PA44_GPTIM1_CH3 SF32LB_PINMUX(PA, 44U, 5U, 0x64U, 2U) #define PA44_GPTIM1_CH4 SF32LB_PINMUX(PA, 44U, 5U, 0x64U, 3U) +#define PA44_GPTIM1_ETR SF32LB_PINMUX(PA, 44U, 5U, 0x6CU, 0U) #define PA44_GPTIM2_CH1 SF32LB_PINMUX(PA, 44U, 5U, 0x68U, 0U) #define PA44_GPTIM2_CH2 SF32LB_PINMUX(PA, 44U, 5U, 0x68U, 1U) #define PA44_GPTIM2_CH3 SF32LB_PINMUX(PA, 44U, 5U, 0x68U, 2U) #define PA44_GPTIM2_CH4 SF32LB_PINMUX(PA, 44U, 5U, 0x68U, 3U) -#define PA44_GPTIM1_ETR SF32LB_PINMUX(PA, 44U, 5U, 0x6CU, 0U) #define PA44_GPTIM2_ETR SF32LB_PINMUX(PA, 44U, 5U, 0x6CU, 1U) #define PA44_LPTIM1_IN SF32LB_PINMUX(PA, 44U, 5U, 0x70U, 0U) #define PA44_LPTIM1_OUT SF32LB_PINMUX(PA, 44U, 5U, 0x70U, 1U) @@ -2535,89 +2357,83 @@ #define PA44_ATIM1_CH1N SF32LB_PINMUX(PA, 44U, 5U, 0x7CU, 0U) #define PA44_ATIM1_CH2N SF32LB_PINMUX(PA, 44U, 5U, 0x7CU, 1U) #define PA44_ATIM1_CH3N SF32LB_PINMUX(PA, 44U, 5U, 0x7CU, 2U) +#define PA44_ATIM1_ETR SF32LB_PINMUX(PA, 44U, 5U, 0x80U, 2U) #define PA44_ATIM1_BK SF32LB_PINMUX(PA, 44U, 5U, 0x80U, 0U) #define PA44_ATIM1_BK2 SF32LB_PINMUX(PA, 44U, 5U, 0x80U, 1U) -#define PA44_ATIM1_ETR SF32LB_PINMUX(PA, 44U, 5U, 0x80U, 2U) -/* PA_TIM functions end */ #define PA44_WKUP_PIN20 SF32LB_PINMUX(PA, 44U, 8U, 0U, 0U) -/* - * SA port pins (SAIO_D0 - SAIO_D12) - * These are dedicated pins for MPI1 (PSRAM/NOR Flash) interface - */ - -/* SA00 (SAIO_D0) */ +/* SA00 */ #define SA00_ANALOG SF32LB_PINMUX_ANALOG(SA, 0U) #define SA00_MPI1_DM SF32LB_PINMUX(SA, 0U, 1U, 0U, 0U) #define SA00_MPI1_DIO2 SF32LB_PINMUX(SA, 0U, 5U, 0U, 0U) -/* SA01 (SAIO_D1) */ +/* SA01 */ #define SA01_ANALOG SF32LB_PINMUX_ANALOG(SA, 1U) #define SA01_MPI1_DIO0 SF32LB_PINMUX(SA, 1U, 1U, 0U, 0U) #define SA01_MPI1_CS SF32LB_PINMUX(SA, 1U, 5U, 0U, 0U) -/* SA02 (SAIO_D2) */ +/* SA02 */ #define SA02_ANALOG SF32LB_PINMUX_ANALOG(SA, 2U) #define SA02_MPI1_DIO1 SF32LB_PINMUX(SA, 2U, 1U, 0U, 0U) #define SA02_MPI1_DIO1_ALT SF32LB_PINMUX(SA, 2U, 5U, 0U, 0U) -/* SA03 (SAIO_D3) */ +/* SA03 */ #define SA03_ANALOG SF32LB_PINMUX_ANALOG(SA, 3U) #define SA03_MPI1_DIO2 SF32LB_PINMUX(SA, 3U, 1U, 0U, 0U) #define SA03_MPI1_DIO2_ALT SF32LB_PINMUX(SA, 3U, 5U, 0U, 0U) -/* SA04 (SAIO_D4) */ +/* SA04 */ #define SA04_ANALOG SF32LB_PINMUX_ANALOG(SA, 4U) #define SA04_MPI1_DIO3 SF32LB_PINMUX(SA, 4U, 1U, 0U, 0U) #define SA04_MPI1_CS SF32LB_PINMUX(SA, 4U, 5U, 0U, 0U) -/* SA05 (SAIO_D5) */ +/* SA05 */ #define SA05_ANALOG SF32LB_PINMUX_ANALOG(SA, 5U) #define SA05_MPI1_CS SF32LB_PINMUX(SA, 5U, 1U, 0U, 0U) #define SA05_MPI1_DIO4 SF32LB_PINMUX(SA, 5U, 3U, 0U, 0U) #define SA05_MPI1_DIO0 SF32LB_PINMUX(SA, 5U, 4U, 0U, 0U) -/* SA06 (SAIO_D6) */ +/* SA06 */ #define SA06_ANALOG SF32LB_PINMUX_ANALOG(SA, 6U) #define SA06_MPI1_CLKB SF32LB_PINMUX(SA, 6U, 1U, 0U, 0U) #define SA06_MPI1_DIO5 SF32LB_PINMUX(SA, 6U, 3U, 0U, 0U) #define SA06_MPI1_DIO2 SF32LB_PINMUX(SA, 6U, 4U, 0U, 0U) -/* SA07 (SAIO_D7) */ +/* SA07 */ #define SA07_ANALOG SF32LB_PINMUX_ANALOG(SA, 7U) #define SA07_MPI1_CLK SF32LB_PINMUX(SA, 7U, 1U, 0U, 0U) #define SA07_MPI1_DIO6 SF32LB_PINMUX(SA, 7U, 3U, 0U, 0U) #define SA07_MPI1_DIO1 SF32LB_PINMUX(SA, 7U, 4U, 0U, 0U) #define SA07_MPI1_DIO0 SF32LB_PINMUX(SA, 7U, 5U, 0U, 0U) -/* SA08 (SAIO_D8) */ +/* SA08 */ #define SA08_ANALOG SF32LB_PINMUX_ANALOG(SA, 8U) #define SA08_MPI1_DIO4 SF32LB_PINMUX(SA, 8U, 1U, 0U, 0U) #define SA08_MPI1_DIO7 SF32LB_PINMUX(SA, 8U, 3U, 0U, 0U) #define SA08_MPI1_CS SF32LB_PINMUX(SA, 8U, 4U, 0U, 0U) #define SA08_MPI1_DIO3 SF32LB_PINMUX(SA, 8U, 5U, 0U, 0U) -/* SA09 (SAIO_D9) */ +/* SA09 */ #define SA09_ANALOG SF32LB_PINMUX_ANALOG(SA, 9U) #define SA09_MPI1_DIO5 SF32LB_PINMUX(SA, 9U, 1U, 0U, 0U) #define SA09_MPI1_DQSDM SF32LB_PINMUX(SA, 9U, 3U, 0U, 0U) #define SA09_MPI1_CLK SF32LB_PINMUX(SA, 9U, 4U, 0U, 0U) #define SA09_MPI1_CLK_ALT SF32LB_PINMUX(SA, 9U, 5U, 0U, 0U) -/* SA10 (SAIO_D10) */ +/* SA10 */ #define SA10_ANALOG SF32LB_PINMUX_ANALOG(SA, 10U) #define SA10_MPI1_DIO6 SF32LB_PINMUX(SA, 10U, 1U, 0U, 0U) #define SA10_MPI1_CLK SF32LB_PINMUX(SA, 10U, 3U, 0U, 0U) #define SA10_MPI1_DIO3 SF32LB_PINMUX(SA, 10U, 4U, 0U, 0U) #define SA10_MPI1_DIO3_ALT SF32LB_PINMUX(SA, 10U, 5U, 0U, 0U) -/* SA11 (SAIO_D11) */ +/* SA11 */ #define SA11_ANALOG SF32LB_PINMUX_ANALOG(SA, 11U) #define SA11_MPI1_DIO7 SF32LB_PINMUX(SA, 11U, 1U, 0U, 0U) #define SA11_MPI1_CS SF32LB_PINMUX(SA, 11U, 3U, 0U, 0U) #define SA11_MPI1_DIO0 SF32LB_PINMUX(SA, 11U, 5U, 0U, 0U) -/* SA12 (SAIO_D12) */ +/* SA12 */ #define SA12_ANALOG SF32LB_PINMUX_ANALOG(SA, 12U) #define SA12_MPI1_DQS SF32LB_PINMUX(SA, 12U, 1U, 0U, 0U) #define SA12_MPI1_DQSDM SF32LB_PINMUX(SA, 12U, 2U, 0U, 0U) From 76e8d2b8fc69c389d6cb9600d795f309de61bf3f Mon Sep 17 00:00:00 2001 From: Thinh Le Cong Date: Tue, 25 Nov 2025 15:23:02 +0700 Subject: [PATCH 0840/3659] linker: ld: correct GNU linker generator output for block linking Fix the issue that occurs when building with GNU and CONFIG_LINKER_GENERATOR=y. Currently, the GROUP {region} directive does not function properly with GNU. The input section cannot link to the memory group defined by "zephyr,memory-region" in the final output linker script. This commit updates the GNU section name parser script, allowing it to look up both group and region for output block generation in the final output linker script. Signed-off-by: Thinh Le Cong Signed-off-by: The Nguyen --- cmake/linker/ld/ld_script.cmake | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cmake/linker/ld/ld_script.cmake b/cmake/linker/ld/ld_script.cmake index 22fd1b66d625..49a3509440f6 100644 --- a/cmake/linker/ld/ld_script.cmake +++ b/cmake/linker/ld/ld_script.cmake @@ -357,6 +357,10 @@ function(section_to_string) if(${parent_type} STREQUAL GROUP) get_property(vma GLOBAL PROPERTY ${parent}_VMA) get_property(lma GLOBAL PROPERTY ${parent}_LMA) + elseif(${parent_type} STREQUAL REGION) + if(NOT DEFINED vma) + get_property(vma GLOBAL PROPERTY ${parent}_NAME) + endif() endif() if(DEFINED vma) From 50409c73855eb87dd18d598e254019e543b970cb Mon Sep 17 00:00:00 2001 From: Chun-Chieh Li Date: Tue, 16 Dec 2025 10:46:36 +0800 Subject: [PATCH 0841/3659] drivers: clock_control: numaker: support get_rate/set_rate This adds support for clock_control_get_rate/clock_control_set_rate API, so that module clock rate can fetch or modify via them in Hz. Note only CANFD support is added as an reference example and other module support will be added as-needed. Signed-off-by: Chun-Chieh Li --- drivers/can/can_numaker.c | 87 +---- .../clock_control/clock_control_numaker_scc.c | 309 +++++++++++++++++- .../clock_control/clock_control_numaker.h | 51 ++- 3 files changed, 349 insertions(+), 98 deletions(-) diff --git a/drivers/can/can_numaker.c b/drivers/can/can_numaker.c index 3a782dded573..0a497f949b3d 100644 --- a/drivers/can/can_numaker.c +++ b/drivers/can/can_numaker.c @@ -16,15 +16,12 @@ #include #include -#if defined(CONFIG_SOC_SERIES_M55M1X) -#include -#endif - LOG_MODULE_REGISTER(can_numaker, CONFIG_CAN_LOG_LEVEL); /* Implementation notes + * * 1. Use Bosch M_CAN driver (m_can) as backend - * 2. Need to modify can_numaker_get_core_clock() for new SOC support + * 2. For new SoC series port, add CAN in clock_control_get_rate() */ struct can_numaker_config { @@ -44,82 +41,16 @@ static int can_numaker_get_core_clock(const struct device *dev, uint32_t *rate) { const struct can_mcan_config *mcan_config = dev->config; const struct can_numaker_config *config = mcan_config->custom; - uint32_t clksrc_rate_idx; - uint32_t clkdiv_divider; - __typeof__(CANFD0_MODULE) clk_modidx_real; - -#if defined(CONFIG_SOC_SERIES_M55M1X) - switch (config->clk_modidx) { - case NUMAKER_CANFD0_MODULE: - clk_modidx_real = CANFD0_MODULE; - break; - case NUMAKER_CANFD1_MODULE: - clk_modidx_real = CANFD1_MODULE; - break; - default: - LOG_ERR("Invalid clock module index"); - return -EIO; - } -#else - clk_modidx_real = config->clk_modidx; -#endif + struct numaker_scc_subsys scc_subsys = {.subsys_id = NUMAKER_SCC_SUBSYS_ID_PCC, + .pcc.clk_modidx = config->clk_modidx}; + int rc; - /* Module clock source rate */ - clksrc_rate_idx = CLK_GetModuleClockSource(clk_modidx_real); - /* Module clock divider */ - clkdiv_divider = CLK_GetModuleClockDivider(clk_modidx_real) + 1; - - switch (clksrc_rate_idx) { -#if defined(CONFIG_SOC_SERIES_M46X) || defined(CONFIG_SOC_SERIES_M333X) - case (CLK_CLKSEL0_CANFD0SEL_HXT >> CLK_CLKSEL0_CANFD0SEL_Pos): - *rate = __HXT / clkdiv_divider; - break; - case (CLK_CLKSEL0_CANFD0SEL_PLL_DIV2 >> CLK_CLKSEL0_CANFD0SEL_Pos): - *rate = (CLK_GetPLLClockFreq() / 2) / clkdiv_divider; - break; - case (CLK_CLKSEL0_CANFD0SEL_HCLK >> CLK_CLKSEL0_CANFD0SEL_Pos): - *rate = CLK_GetHCLKFreq() / clkdiv_divider; - break; - case (CLK_CLKSEL0_CANFD0SEL_HIRC >> CLK_CLKSEL0_CANFD0SEL_Pos): - *rate = __HIRC / clkdiv_divider; - break; -#elif defined(CONFIG_SOC_SERIES_M2L31X) - case (CLK_CLKSEL0_CANFD0SEL_HXT >> CLK_CLKSEL0_CANFD0SEL_Pos): - *rate = __HXT / clkdiv_divider; - break; - case (CLK_CLKSEL0_CANFD0SEL_HIRC48M >> CLK_CLKSEL0_CANFD0SEL_Pos): - *rate = __HIRC48 / clkdiv_divider; - break; - case (CLK_CLKSEL0_CANFD0SEL_HCLK >> CLK_CLKSEL0_CANFD0SEL_Pos): - *rate = CLK_GetHCLKFreq() / clkdiv_divider; - break; - case (CLK_CLKSEL0_CANFD0SEL_HIRC >> CLK_CLKSEL0_CANFD0SEL_Pos): - *rate = __HIRC / clkdiv_divider; - break; -#elif defined(CONFIG_SOC_SERIES_M55M1X) - case (CLK_CANFDSEL_CANFD0SEL_HXT >> CLK_CANFDSEL_CANFD0SEL_Pos): - *rate = __HXT / clkdiv_divider; - break; - case (CLK_CANFDSEL_CANFD0SEL_APLL0_DIV2 >> CLK_CANFDSEL_CANFD0SEL_Pos): - *rate = (CLK_GetAPLL0ClockFreq() / 2) / clkdiv_divider; - break; - case (CLK_CANFDSEL_CANFD0SEL_HCLK0 >> CLK_CANFDSEL_CANFD0SEL_Pos): - *rate = CLK_GetHCLK0Freq() / clkdiv_divider; - break; - case (CLK_CANFDSEL_CANFD0SEL_HIRC >> CLK_CANFDSEL_CANFD0SEL_Pos): - *rate = __HIRC / clkdiv_divider; - break; - case (CLK_CANFDSEL_CANFD0SEL_HIRC48M_DIV4 >> CLK_CANFDSEL_CANFD0SEL_Pos): - *rate = (__HIRC48M / 4) / clkdiv_divider; - break; -#endif - default: - LOG_ERR("Invalid clock source rate index"); - return -EIO; + rc = clock_control_get_rate(config->clk_dev, (clock_control_subsys_t)&scc_subsys, rate); + if (rc < 0) { + LOG_ERR("Failed clock_control_get_rate(): %d", rc); + return rc; } - LOG_DBG("Clock rate index/divider: %d/%d", clksrc_rate_idx, clkdiv_divider); - return 0; } diff --git a/drivers/clock_control/clock_control_numaker_scc.c b/drivers/clock_control/clock_control_numaker_scc.c index fe00c108b862..f1ffc84ccd4f 100644 --- a/drivers/clock_control/clock_control_numaker_scc.c +++ b/drivers/clock_control/clock_control_numaker_scc.c @@ -22,6 +22,18 @@ struct numaker_scc_config { uint32_t core_clock; }; +/* Clock module index + * + * virtual: passed from dts as 32-bit (one dts cell) + * real: passed to BSP CLK driver CLK_EnableModuleClock() and/or + * CLK_SetModuleClock() as: 32-bit or 64-bit + * + * For 32-bit real, real = virtual, e.g. m46x and m2l31x + * For 64-bit real, real = virtual as index into lookup table, e.g. m55m1x + */ +#define NUMAKER_PCC_MODIDX_REAL_TYPE \ + __typeof__(((struct numaker_scc_subsys_pcc_rate *)0)->clk_modidx_real) + #if defined(CONFIG_SOC_SERIES_M55M1X) static const uint64_t numaker_clkmodidx_tab[] = { 0x0000000000000000, 0x0000000000000400, 0x0000800000000000, 0x0001008000800000, @@ -53,7 +65,160 @@ static const uint64_t numaker_clkmodidx_tab[] = { 0x001D0D0880878000, 0x001D800000000000, 0x001E000000000000, 0x001E8D8000800000, 0x001E8D8000800480, 0x001F0F8000800000, 0x001F0F8000800480, }; + +#define NUMAKER_PCC_MODIDX_VIRT2REAL(modidx) \ + ({ \ + __ASSERT_NO_MSG(modidx < ARRAY_SIZE(numaker_clkmodidx_tab)); \ + numaker_clkmodidx_tab[modidx]; \ + }) +#else +#define NUMAKER_PCC_MODIDX_VIRT2REAL(modidx) ((uint32_t)modidx) +#endif + +static inline int numaker_pcc_get_max_divider(NUMAKER_PCC_MODIDX_REAL_TYPE clk_modidx_real, + uint32_t *max_divider) +{ + __ASSERT_NO_MSG(max_divider); + + switch (clk_modidx_real) { +#if defined(CONFIG_SOC_SERIES_M46X) + case CANFD0_MODULE: + case CANFD1_MODULE: + case CANFD2_MODULE: + case CANFD3_MODULE: + *max_divider = (CLK_CLKDIV5_CANFD0DIV_Msk >> CLK_CLKDIV5_CANFD0DIV_Pos) + 1; + break; +#elif defined(CONFIG_SOC_SERIES_M2L31X) + case CANFD0_MODULE: + case CANFD1_MODULE: + *max_divider = (CLK_CLKDIV5_CANFD0DIV_Msk >> CLK_CLKDIV5_CANFD0DIV_Pos) + 1; + break; +#elif defined(CONFIG_SOC_SERIES_M55M1X) + case CANFD0_MODULE: + case CANFD1_MODULE: + *max_divider = (CLK_CANFDDIV_CANFD0DIV_Msk >> CLK_CANFDDIV_CANFD0DIV_Pos) + 1; + break; +#elif defined(CONFIG_SOC_SERIES_M333X) + case CANFD0_MODULE: + case CANFD1_MODULE: + *max_divider = (CLK_CLKDIV1_CANFD0DIV_Msk >> CLK_CLKDIV1_CANFD0DIV_Pos) + 1; + break; +#endif + default: + LOG_ERR("Unsupported clock module index: 0x%" PRIx64, (uint64_t)clk_modidx_real); + return -ENOTSUP; + } + + return 0; +} + +static inline int numaker_pcc_get_source_rate(NUMAKER_PCC_MODIDX_REAL_TYPE clk_modidx_real, + uint32_t clksrc_idx, uint32_t *source_rate) +{ + __ASSERT_NO_MSG(source_rate); + + switch (clk_modidx_real) { +#if defined(CONFIG_SOC_SERIES_M46X) + case CANFD0_MODULE: + case CANFD1_MODULE: + case CANFD2_MODULE: + case CANFD3_MODULE: + switch (clksrc_idx) { + case (CLK_CLKSEL0_CANFD0SEL_HXT >> CLK_CLKSEL0_CANFD0SEL_Pos): + *source_rate = __HXT; + break; + case (CLK_CLKSEL0_CANFD0SEL_PLL_DIV2 >> CLK_CLKSEL0_CANFD0SEL_Pos): + *source_rate = CLK_GetPLLClockFreq() / 2; + break; + case (CLK_CLKSEL0_CANFD0SEL_HCLK >> CLK_CLKSEL0_CANFD0SEL_Pos): + *source_rate = CLK_GetHCLKFreq(); + break; + case (CLK_CLKSEL0_CANFD0SEL_HIRC >> CLK_CLKSEL0_CANFD0SEL_Pos): + *source_rate = __HIRC; + break; + default: + LOG_ERR("Unsupported clock module/source index: 0x%" PRIx64 "/%d", + (uint64_t)clk_modidx_real, clksrc_idx); + return -ENOTSUP; + } + break; +#elif defined(CONFIG_SOC_SERIES_M2L31X) + case CANFD0_MODULE: + case CANFD1_MODULE: + switch (clksrc_idx) { + case (CLK_CLKSEL0_CANFD0SEL_HXT >> CLK_CLKSEL0_CANFD0SEL_Pos): + *source_rate = __HXT; + break; + case (CLK_CLKSEL0_CANFD0SEL_HIRC48M >> CLK_CLKSEL0_CANFD0SEL_Pos): + *source_rate = __HIRC48; + break; + case (CLK_CLKSEL0_CANFD0SEL_HCLK >> CLK_CLKSEL0_CANFD0SEL_Pos): + *source_rate = CLK_GetHCLKFreq(); + break; + case (CLK_CLKSEL0_CANFD0SEL_HIRC >> CLK_CLKSEL0_CANFD0SEL_Pos): + *source_rate = __HIRC; + break; + default: + LOG_ERR("Unsupported clock module/source index: 0x%" PRIx64 "/%d", + (uint64_t)clk_modidx_real, clksrc_idx); + return -ENOTSUP; + } + break; +#elif defined(CONFIG_SOC_SERIES_M55M1X) + case CANFD0_MODULE: + case CANFD1_MODULE: + switch (clksrc_idx) { + case (CLK_CANFDSEL_CANFD0SEL_HXT >> CLK_CANFDSEL_CANFD0SEL_Pos): + *source_rate = __HXT; + break; + case (CLK_CANFDSEL_CANFD0SEL_APLL0_DIV2 >> CLK_CANFDSEL_CANFD0SEL_Pos): + *source_rate = CLK_GetAPLL0ClockFreq() / 2; + break; + case (CLK_CANFDSEL_CANFD0SEL_HCLK0 >> CLK_CANFDSEL_CANFD0SEL_Pos): + *source_rate = CLK_GetHCLK0Freq(); + break; + case (CLK_CANFDSEL_CANFD0SEL_HIRC >> CLK_CANFDSEL_CANFD0SEL_Pos): + *source_rate = __HIRC; + break; + case (CLK_CANFDSEL_CANFD0SEL_HIRC48M_DIV4 >> CLK_CANFDSEL_CANFD0SEL_Pos): + *source_rate = __HIRC48M / 4; + break; + default: + LOG_ERR("Unsupported clock module/source index: 0x%" PRIx64 "/%d", + (uint64_t)clk_modidx_real, clksrc_idx); + return -ENOTSUP; + } + break; +#elif defined(CONFIG_SOC_SERIES_M333X) + case CANFD0_MODULE: + case CANFD1_MODULE: + switch (clksrc_idx) { + case (CLK_CLKSEL0_CANFD0SEL_HXT >> CLK_CLKSEL0_CANFD0SEL_Pos): + *source_rate = __HXT; + break; + case (CLK_CLKSEL0_CANFD0SEL_PLL_DIV2 >> CLK_CLKSEL0_CANFD0SEL_Pos): + *source_rate = CLK_GetPLLClockFreq() / 2; + break; + case (CLK_CLKSEL0_CANFD0SEL_HCLK >> CLK_CLKSEL0_CANFD0SEL_Pos): + *source_rate = CLK_GetHCLKFreq(); + break; + case (CLK_CLKSEL0_CANFD0SEL_HIRC >> CLK_CLKSEL0_CANFD0SEL_Pos): + *source_rate = __HIRC; + break; + default: + LOG_ERR("Unsupported clock module/source index: 0x%" PRIx64 "/%d", + (uint64_t)clk_modidx_real, clksrc_idx); + return -ENOTSUP; + } + break; #endif + default: + LOG_ERR("Unsupported clock module index: 0x%" PRIx64, (uint64_t)clk_modidx_real); + return -ENOTSUP; + } + + return 0; +} static inline int numaker_scc_on(const struct device *dev, clock_control_subsys_t subsys) { @@ -99,22 +264,147 @@ static inline int numaker_scc_off(const struct device *dev, clock_control_subsys return 0; } +static inline int numaker_scc_configure(const struct device *dev, clock_control_subsys_t subsys, + void *data); + static inline int numaker_scc_get_rate(const struct device *dev, clock_control_subsys_t subsys, uint32_t *rate) { + struct numaker_scc_subsys *scc_subsys = (struct numaker_scc_subsys *)subsys; + int rc; + ARG_UNUSED(dev); - ARG_UNUSED(subsys); - ARG_UNUSED(rate); - return -ENOTSUP; + + if (!rate) { + LOG_ERR("NULL rate pointer"); + return -EINVAL; + } + + if (scc_subsys->subsys_id == NUMAKER_SCC_SUBSYS_ID_PCC) { + struct numaker_scc_subsys_pcc *pcc = &scc_subsys->pcc; + uint32_t clk_modidx_virt = pcc->clk_modidx; + NUMAKER_PCC_MODIDX_REAL_TYPE clk_modidx_real = + NUMAKER_PCC_MODIDX_VIRT2REAL(clk_modidx_virt); + uint32_t clksrc_idx; + uint32_t source_rate; + uint32_t clkdiv_value; + + /* Clock source index and rate */ + clksrc_idx = CLK_GetModuleClockSource(clk_modidx_real); + rc = numaker_pcc_get_source_rate(clk_modidx_real, clksrc_idx, &source_rate); + if (rc < 0) { + return rc; + } + + /* Clock divider value */ + clkdiv_value = CLK_GetModuleClockDivider(clk_modidx_real) + 1; + + *rate = source_rate / clkdiv_value; + } else { + LOG_ERR("Invalid subsys (%d)", scc_subsys->subsys_id); + return -EINVAL; + } + + return 0; } static inline int numaker_scc_set_rate(const struct device *dev, clock_control_subsys_t subsys, clock_control_subsys_rate_t rate) { - ARG_UNUSED(dev); - ARG_UNUSED(subsys); - ARG_UNUSED(rate); - return -ENOTSUP; + struct numaker_scc_subsys *scc_subsys = (struct numaker_scc_subsys *)subsys; + struct numaker_scc_subsys_rate *scc_subsys_rate = (struct numaker_scc_subsys_rate *)rate; + int rc; + + if (scc_subsys->subsys_id == NUMAKER_SCC_SUBSYS_ID_PCC) { + struct numaker_scc_subsys scc_subsys_im = *scc_subsys; + struct numaker_scc_subsys_pcc *pcc = &scc_subsys_im.pcc; + struct numaker_scc_subsys_pcc_rate *pcc_rate = &scc_subsys_rate->pcc; + uint32_t clk_modidx_virt = pcc->clk_modidx; + NUMAKER_PCC_MODIDX_REAL_TYPE clk_modidx_real = + NUMAKER_PCC_MODIDX_VIRT2REAL(clk_modidx_virt); + uint32_t clksrc_idx; + uint32_t source_rate; + uint32_t clkdiv_value; + uint32_t clkdiv_value_max; + + /* Degenerate to get_rate on clk_mod_rate being zero */ + + /* Supported max divider value */ + rc = numaker_pcc_get_max_divider(clk_modidx_real, &clkdiv_value_max); + if (rc < 0) { + return rc; + } + + /* First run to prepare for CLK_GetModuleClockSource + * + * CLK_GetModuleClockSource will see CLKSEL register for + * clock source, so first run is needed to get CLKSEL register + * ready. Besides, first run will also set up CLKDIV register + * with max divider value for safe. + */ + if (pcc_rate->clk_mod_rate != 0) { + pcc->clk_div = (clkdiv_value_max - 1) + << ((uint32_t)MODULE_CLKDIV_Pos(clk_modidx_real)); + rc = numaker_scc_configure(dev, &scc_subsys_im, NULL); + if (rc < 0) { + return rc; + } + } + + /* Clock source index and rate */ + clksrc_idx = CLK_GetModuleClockSource(clk_modidx_real); + rc = numaker_pcc_get_source_rate(clk_modidx_real, clksrc_idx, &source_rate); + if (rc < 0) { + return rc; + } + + /* Calculate out proper clock divider value + * + * 1. Equal to or lower than target rate for safe + * 2. Clamp divider value to supported min and max values + * + * NOTE: When max divider value is chosen, configured rate + * can be higher than target rate. + */ + if (pcc_rate->clk_mod_rate != 0) { + clkdiv_value = source_rate / pcc_rate->clk_mod_rate; + if (clkdiv_value == 0) { + clkdiv_value = 1; + } + if (pcc_rate->clk_mod_rate < (source_rate / clkdiv_value)) { + clkdiv_value++; + } + if (clkdiv_value > clkdiv_value_max) { + clkdiv_value = clkdiv_value_max; + } + } else { + /* Clock divider value */ + clkdiv_value = CLK_GetModuleClockDivider(clk_modidx_real) + 1; + } + + /* Second run for real configure */ + if (pcc_rate->clk_mod_rate != 0) { + pcc->clk_div = (clkdiv_value - 1) + << ((uint32_t)MODULE_CLKDIV_Pos(clk_modidx_real)); + rc = numaker_scc_configure(dev, &scc_subsys_im, NULL); + if (rc < 0) { + return rc; + } + } + + /* Detailed PCC module clock information */ + pcc_rate->clk_src_idx = clksrc_idx; + pcc_rate->clk_src_rate = source_rate; + pcc_rate->clk_modidx_real = clk_modidx_real; + pcc_rate->clk_div_value = clkdiv_value; + pcc_rate->clk_div_value_max = clkdiv_value_max; + pcc_rate->clk_mod_rate = source_rate / clkdiv_value; + } else { + LOG_ERR("Invalid subsys (%d)", scc_subsys->subsys_id); + return -EINVAL; + } + + return 0; } static inline int numaker_scc_configure(const struct device *dev, clock_control_subsys_t subsys, @@ -130,8 +420,7 @@ static inline int numaker_scc_configure(const struct device *dev, clock_control_ #if defined(CONFIG_SOC_SERIES_M55M1X) __ASSERT_NO_MSG(scc_subsys->pcc.clk_modidx < ARRAY_SIZE(numaker_clkmodidx_tab)); CLK_SetModuleClock(numaker_clkmodidx_tab[scc_subsys->pcc.clk_modidx], - scc_subsys->pcc.clk_src, - scc_subsys->pcc.clk_div); + scc_subsys->pcc.clk_src, scc_subsys->pcc.clk_div); #else CLK_SetModuleClock(scc_subsys->pcc.clk_modidx, scc_subsys->pcc.clk_src, scc_subsys->pcc.clk_div); @@ -206,7 +495,7 @@ static int numaker_scc_init(const struct device *dev) .core_clock = DT_INST_PROP_OR(inst, core_clock, 0), \ }; \ \ - DEVICE_DT_INST_DEFINE(inst, numaker_scc_init, NULL, NULL, &numaker_scc_config_##inst, \ + DEVICE_DT_INST_DEFINE(inst, numaker_scc_init, NULL, NULL, &numaker_scc_config_##inst, \ PRE_KERNEL_1, CONFIG_CLOCK_CONTROL_INIT_PRIORITY, &numaker_scc_api); DT_INST_FOREACH_STATUS_OKAY(NUMICRO_SCC_INIT); diff --git a/include/zephyr/drivers/clock_control/clock_control_numaker.h b/include/zephyr/drivers/clock_control/clock_control_numaker.h index 25e0d58d92ef..b5d9005e85fe 100644 --- a/include/zephyr/drivers/clock_control/clock_control_numaker.h +++ b/include/zephyr/drivers/clock_control/clock_control_numaker.h @@ -21,20 +21,51 @@ */ #define NUMAKER_SCC_SUBSYS_ID_PCC 1 +/* Peripheral clock control configuration structure + * + * clk_modidx is virtual of u32ModuleIdx/u64ModuleIdx in BSP CLK_SetModuleClock(). + * clk_src is same as u32ClkSrc in BSP CLK_SetModuleClock(). + * clk_div is same as u32ClkDiv in BSP CLK_SetModuleClock(). + */ +struct numaker_scc_subsys_pcc { + uint32_t clk_modidx; + uint32_t clk_src; + uint32_t clk_div; +}; + +/* Peripheral clock control rate structure + * + * clk_modidx_real is real of u32ModuleIdx/u64ModuleIdx in BSP CLK_SetModuleClock(). + * clk_src_idx is decoded clock source index of clk_src. + * clk_src_rate is clock source rate of clk_src_idx. + * clk_div_value is decoded clock divider value of clk_div. + * clk_div_value_max is supported maximum divider value of clk_div_value. + * clk_mod_rate is module rate. + */ +struct numaker_scc_subsys_pcc_rate { +#if defined(CONFIG_SOC_SERIES_M55M1X) + uint64_t clk_modidx_real; +#else + uint32_t clk_modidx_real; +#endif + uint32_t clk_src_idx; + uint32_t clk_src_rate; + uint32_t clk_div_value; + uint32_t clk_div_value_max; + uint32_t clk_mod_rate; +}; + struct numaker_scc_subsys { uint32_t subsys_id; /* SCC subsystem ID */ - /* Peripheral clock control configuration structure - * clk_modidx is same as u32ModuleIdx in BSP CLK_SetModuleClock(). - * clk_src is same as u32ClkSrc in BSP CLK_SetModuleClock(). - * clk_div is same as u32ClkDiv in BSP CLK_SetModuleClock(). - */ union { - struct { - uint32_t clk_modidx; - uint32_t clk_src; - uint32_t clk_div; - } pcc; + struct numaker_scc_subsys_pcc pcc; + }; +}; + +struct numaker_scc_subsys_rate { + union { + struct numaker_scc_subsys_pcc_rate pcc; }; }; From 72fb81eb9f818de108703b7a4b0607ae13184b4f Mon Sep 17 00:00:00 2001 From: Ha Duong Quang Date: Wed, 11 Jun 2025 14:24:16 +0700 Subject: [PATCH 0842/3659] soc: arm: introduce support for NXP S32K566 SoC S32K566 is a member of the S32K5 family which expands s32k3 series to higher performance and larger memory. Zephyr port for S32K5 will support cortex-M7 and cortex-R52 After reset, swt_startup is enabled and starts running, disable it using the watchdog hook. Signed-off-by: Ha Duong Quang Co-authored-by: Dat Nguyen Duy --- dts/arm/nxp/nxp_s32k344_m7.dtsi | 1 + dts/bindings/power/nxp,s32-mc-me.yaml | 6 +- dts/bindings/timer/arm,armv8-timer.yaml | 6 ++ soc/nxp/s32/common/mc_me.c | 37 ++++++++--- soc/nxp/s32/common/mc_me.h | 12 ++++ soc/nxp/s32/s32k5/CMakeLists.txt | 12 ++++ soc/nxp/s32/s32k5/Kconfig | 25 ++++++++ soc/nxp/s32/s32k5/Kconfig.defconfig | 18 ++++++ .../s32/s32k5/Kconfig.defconfig.s32k566.m7 | 11 ++++ .../s32/s32k5/Kconfig.defconfig.s32k566.r52 | 15 +++++ soc/nxp/s32/s32k5/Kconfig.soc | 30 +++++++++ soc/nxp/s32/s32k5/m7/CMakeLists.txt | 9 +++ soc/nxp/s32/s32k5/m7/mpu_regions.c | 44 +++++++++++++ soc/nxp/s32/s32k5/m7/s32k5xx_startup.S | 41 ++++++++++++ soc/nxp/s32/s32k5/m7/sections.ld | 12 ++++ soc/nxp/s32/s32k5/m7/soc.c | 24 +++++++ soc/nxp/s32/s32k5/m7/soc.h | 17 +++++ soc/nxp/s32/s32k5/r52/CMakeLists.txt | 8 +++ soc/nxp/s32/s32k5/r52/mpu_regions.c | 43 +++++++++++++ soc/nxp/s32/s32k5/r52/s32k5xx_startup.S | 62 +++++++++++++++++++ soc/nxp/s32/s32k5/r52/soc.c | 20 ++++++ soc/nxp/s32/s32k5/r52/soc.h | 19 ++++++ soc/nxp/s32/s32k5/swt_disable.c | 34 ++++++++++ soc/nxp/s32/soc.yml | 6 ++ 24 files changed, 502 insertions(+), 10 deletions(-) create mode 100644 soc/nxp/s32/common/mc_me.h create mode 100644 soc/nxp/s32/s32k5/CMakeLists.txt create mode 100644 soc/nxp/s32/s32k5/Kconfig create mode 100644 soc/nxp/s32/s32k5/Kconfig.defconfig create mode 100644 soc/nxp/s32/s32k5/Kconfig.defconfig.s32k566.m7 create mode 100644 soc/nxp/s32/s32k5/Kconfig.defconfig.s32k566.r52 create mode 100644 soc/nxp/s32/s32k5/Kconfig.soc create mode 100644 soc/nxp/s32/s32k5/m7/CMakeLists.txt create mode 100644 soc/nxp/s32/s32k5/m7/mpu_regions.c create mode 100644 soc/nxp/s32/s32k5/m7/s32k5xx_startup.S create mode 100644 soc/nxp/s32/s32k5/m7/sections.ld create mode 100644 soc/nxp/s32/s32k5/m7/soc.c create mode 100644 soc/nxp/s32/s32k5/m7/soc.h create mode 100644 soc/nxp/s32/s32k5/r52/CMakeLists.txt create mode 100644 soc/nxp/s32/s32k5/r52/mpu_regions.c create mode 100644 soc/nxp/s32/s32k5/r52/s32k5xx_startup.S create mode 100644 soc/nxp/s32/s32k5/r52/soc.c create mode 100644 soc/nxp/s32/s32k5/r52/soc.h create mode 100644 soc/nxp/s32/s32k5/swt_disable.c diff --git a/dts/arm/nxp/nxp_s32k344_m7.dtsi b/dts/arm/nxp/nxp_s32k344_m7.dtsi index edc0b953b276..723fe3c761f9 100644 --- a/dts/arm/nxp/nxp_s32k344_m7.dtsi +++ b/dts/arm/nxp/nxp_s32k344_m7.dtsi @@ -892,6 +892,7 @@ mc_me: mc_me@402dc000 { compatible = "nxp,s32-mc-me"; reg = <0x402dc000 0x4000>; + software-reset-supported; }; mc_rgm: mc_rgm@4028c000 { diff --git a/dts/bindings/power/nxp,s32-mc-me.yaml b/dts/bindings/power/nxp,s32-mc-me.yaml index d519214da398..83f32dd4b2d5 100644 --- a/dts/bindings/power/nxp,s32-mc-me.yaml +++ b/dts/bindings/power/nxp,s32-mc-me.yaml @@ -1,4 +1,4 @@ -# Copyright 2024 NXP +# Copyright 2024,2025 NXP # SPDX-License-Identifier: Apache-2.0 description: NXP S32 Module Entry (MC_ME) @@ -10,3 +10,7 @@ include: base.yaml properties: reg: required: true + + software-reset-supported: + type: boolean + description: The module implements a software-based mechanism for initiate the reset sequence. diff --git a/dts/bindings/timer/arm,armv8-timer.yaml b/dts/bindings/timer/arm,armv8-timer.yaml index 6b8400c4616e..a248ee37a1da 100644 --- a/dts/bindings/timer/arm,armv8-timer.yaml +++ b/dts/bindings/timer/arm,armv8-timer.yaml @@ -7,3 +7,9 @@ include: base.yaml properties: interrupts: required: true + + clock-frequency: + type: int + description: | + The clock source frequencey for this timer, in Hz. This value can be used as + the default setting for SYS_CLOCK_HW_CYCLES_PER_SEC at the SoC level. diff --git a/soc/nxp/s32/common/mc_me.c b/soc/nxp/s32/common/mc_me.c index 7b220eccfce8..04fd7b16c410 100644 --- a/soc/nxp/s32/common/mc_me.c +++ b/soc/nxp/s32/common/mc_me.c @@ -1,5 +1,5 @@ /* - * Copyright 2024 NXP + * Copyright 2024-2025 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -79,6 +79,32 @@ #define REG_READ(r) sys_read32((mem_addr_t)(DT_INST_REG_ADDR(0) + (r))) #define REG_WRITE(r, v) sys_write32((v), (mem_addr_t)(DT_INST_REG_ADDR(0) + (r))) +static inline void mc_me_write_ctl_key(void) +{ + REG_WRITE(MC_ME_CTL_KEY, MC_ME_CTL_KEY_KEY(MC_ME_CTL_KEY_DIRECT_KEY)); + REG_WRITE(MC_ME_CTL_KEY, MC_ME_CTL_KEY_KEY(MC_ME_CTL_KEY_INVERTED_KEY)); +} + +void mc_me_configure_cofb(uint8_t partition_idx, uint8_t cofb_idx, uint32_t value) +{ + REG_WRITE(MC_ME_PRTN_COFB_CLKEN(partition_idx, cofb_idx), + REG_READ(MC_ME_PRTN_COFB_CLKEN(partition_idx, cofb_idx)) | value); + + REG_WRITE(MC_ME_PRTN_PUPD(partition_idx), + REG_READ(MC_ME_PRTN_PUPD(partition_idx)) | MC_ME_PRTN_PUPD_PCUD_MASK); + + mc_me_write_ctl_key(); + + while ((REG_READ(MC_ME_PRTN_PUPD(partition_idx)) & MC_ME_PRTN_PUPD_PCUD_MASK)) { + ; + } + + while (!(REG_READ(MC_ME_PRTN_COFB_STAT(partition_idx, cofb_idx)) & value)) { + ; + } +} + +#if defined(CONFIG_REBOOT) && DT_INST_PROP(0, software_reset_supported) /** MC_ME power mode */ enum mc_me_power_mode { /** Destructive Reset Mode */ @@ -87,13 +113,6 @@ enum mc_me_power_mode { MC_ME_FUNC_RESET_MODE, }; -#if defined(CONFIG_REBOOT) -static inline void mc_me_write_ctl_key(void) -{ - REG_WRITE(MC_ME_CTL_KEY, MC_ME_CTL_KEY_KEY(MC_ME_CTL_KEY_DIRECT_KEY)); - REG_WRITE(MC_ME_CTL_KEY, MC_ME_CTL_KEY_KEY(MC_ME_CTL_KEY_INVERTED_KEY)); -} - static inline void mc_me_trigger_mode_update(void) { REG_WRITE(MC_ME_MODE_UPD, MC_ME_MODE_UPD_MODE_UPD(1U)); @@ -155,4 +174,4 @@ void sys_arch_reboot(int type) break; } } -#endif /* CONFIG_REBOOT */ +#endif /* CONFIG_REBOOT && DT_INST_PROP(0, software_reset_supported) */ diff --git a/soc/nxp/s32/common/mc_me.h b/soc/nxp/s32/common/mc_me.h new file mode 100644 index 000000000000..78effcd99d9e --- /dev/null +++ b/soc/nxp/s32/common/mc_me.h @@ -0,0 +1,12 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _NXP_S32_COMMON_MC_ME_H_ +#define _NXP_S32_COMMON_MC_ME_H_ + +void mc_me_configure_cofb(uint8_t partition_idx, uint8_t cofb_idx, uint32_t value); + +#endif /* _NXP_S32_COMMON_MC_ME_H_ */ diff --git a/soc/nxp/s32/s32k5/CMakeLists.txt b/soc/nxp/s32/s32k5/CMakeLists.txt new file mode 100644 index 000000000000..46fc323e7c78 --- /dev/null +++ b/soc/nxp/s32/s32k5/CMakeLists.txt @@ -0,0 +1,12 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +if(CONFIG_SOC_S32K566_M7) + add_subdirectory(m7) +endif() + +if(CONFIG_SOC_S32K566_R52) + add_subdirectory(r52) +endif() + +zephyr_library_sources(swt_disable.c) diff --git a/soc/nxp/s32/s32k5/Kconfig b/soc/nxp/s32/s32k5/Kconfig new file mode 100644 index 000000000000..6e838e46d687 --- /dev/null +++ b/soc/nxp/s32/s32k5/Kconfig @@ -0,0 +1,25 @@ +# NXP S32K5XX MCUs series + +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_S32K5 + select ARM + select HAS_NXP_S32_HAL + select CPU_HAS_FPU + select CPU_HAS_ARM_MPU + select CPU_HAS_ICACHE + select CPU_HAS_DCACHE + select SOC_EARLY_INIT_HOOK + +config SOC_S32K566_M7 + select CPU_CORTEX_M7 + select CPU_HAS_CUSTOM_FIXED_SOC_MPU_REGIONS + select SOC_EARLY_RESET_HOOK if XIP + +config SOC_S32K566_R52 + select ARM_ARCH_TIMER if SYS_CLOCK_EXISTS + select CPU_CORTEX_R52 + select GIC_SINGLE_SECURITY_STATE + select VFP_DP_D16 + select SOC_RESET_HOOK diff --git a/soc/nxp/s32/s32k5/Kconfig.defconfig b/soc/nxp/s32/s32k5/Kconfig.defconfig new file mode 100644 index 000000000000..3fe499f8b150 --- /dev/null +++ b/soc/nxp/s32/s32k5/Kconfig.defconfig @@ -0,0 +1,18 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +if SOC_SERIES_S32K5 + +config SYS_CLOCK_HW_CYCLES_PER_SEC + default $(dt_node_int_prop_int,/cpus/cpu@0,clock-frequency) if CORTEX_M_SYSTICK + default $(dt_node_int_prop_int,/timer,clock-frequency) if ARM_ARCH_TIMER + +config FPU + default y if CPU_HAS_FPU + +config CACHE_MANAGEMENT + default y + +rsource "Kconfig.defconfig.*" + +endif # SOC_SERIES_S32K5 diff --git a/soc/nxp/s32/s32k5/Kconfig.defconfig.s32k566.m7 b/soc/nxp/s32/s32k5/Kconfig.defconfig.s32k566.m7 new file mode 100644 index 000000000000..d0d9c2745107 --- /dev/null +++ b/soc/nxp/s32/s32k5/Kconfig.defconfig.s32k566.m7 @@ -0,0 +1,11 @@ +# NXP S32K5XX MCU series + +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +if SOC_S32K566_M7 + +config NUM_IRQS + default 239 + +endif # SOC_S32K566_M7 diff --git a/soc/nxp/s32/s32k5/Kconfig.defconfig.s32k566.r52 b/soc/nxp/s32/s32k5/Kconfig.defconfig.s32k566.r52 new file mode 100644 index 000000000000..c55bba8dac2b --- /dev/null +++ b/soc/nxp/s32/s32k5/Kconfig.defconfig.s32k566.r52 @@ -0,0 +1,15 @@ +# NXP S32K5XX MCU series + +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +if SOC_S32K566_R52 + +config NUM_IRQS + # must be >= the highest interrupt number used + default 328 + +config MAIN_STACK_SIZE + default 1024 + +endif # SOC_S32K566_R52 diff --git a/soc/nxp/s32/s32k5/Kconfig.soc b/soc/nxp/s32/s32k5/Kconfig.soc new file mode 100644 index 000000000000..82d9fd46e01f --- /dev/null +++ b/soc/nxp/s32/s32k5/Kconfig.soc @@ -0,0 +1,30 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_S32K5 + bool + select SOC_FAMILY_NXP_S32 + +config SOC_SERIES + default "s32k5" if SOC_SERIES_S32K5 + +config SOC_S32K566 + bool + select SOC_SERIES_S32K5 + +config SOC_S32K566_M7 + bool + select SOC_S32K566 + +config SOC_S32K566_R52 + bool + select SOC_S32K566 + +config SOC + default "s32k566" if SOC_S32K566 + +config SOC_PART_NUMBER_S32K566JAMJGS + bool + +config SOC_PART_NUMBER + default "S32K566JAMJGS" if SOC_PART_NUMBER_S32K566JAMJGS diff --git a/soc/nxp/s32/s32k5/m7/CMakeLists.txt b/soc/nxp/s32/s32k5/m7/CMakeLists.txt new file mode 100644 index 000000000000..870abd94f033 --- /dev/null +++ b/soc/nxp/s32/s32k5/m7/CMakeLists.txt @@ -0,0 +1,9 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +zephyr_include_directories(.) +zephyr_library_sources(soc.c) +zephyr_library_sources_ifdef(CONFIG_CPU_HAS_CUSTOM_FIXED_SOC_MPU_REGIONS mpu_regions.c) +zephyr_linker_sources(SECTIONS sections.ld) +zephyr_library_sources_ifdef(CONFIG_SOC_EARLY_RESET_HOOK s32k5xx_startup.S) +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/nxp/s32/s32k5/m7/mpu_regions.c b/soc/nxp/s32/s32k5/m7/mpu_regions.c new file mode 100644 index 000000000000..551178ad753e --- /dev/null +++ b/soc/nxp/s32/s32k5/m7/mpu_regions.c @@ -0,0 +1,44 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#if !defined(CONFIG_XIP) +extern char _rom_attr[]; +#endif + +#define REGION_PERIPHERAL_BASE_ADDRESS 0x40000000 +#define REGION_PERIPHERAL_SIZE REGION_512M +#define REGION_PPB_BASE_ADDRESS 0xE0000000 +#define REGION_PPB_SIZE REGION_1M + +static struct arm_mpu_region mpu_regions[] = { + + /* ERR011573: use first region to prevent speculative access in entire memory space */ + MPU_REGION_ENTRY("UNMAPPED", 0, {REGION_4G | MPU_RASR_XN_Msk | P_NA_U_NA_Msk}), + + /* Keep before CODE region so it can be overlapped by SRAM CODE in non-XIP systems */ + MPU_REGION_ENTRY("SRAM", CONFIG_SRAM_BASE_ADDRESS, REGION_RAM_ATTR(REGION_SRAM_SIZE)), + +#ifdef CONFIG_XIP + MPU_REGION_ENTRY("FLASH", CONFIG_FLASH_BASE_ADDRESS, REGION_FLASH_ATTR(REGION_FLASH_SIZE)), +#else + /* Run from SRAM */ + MPU_REGION_ENTRY("CODE", CONFIG_SRAM_BASE_ADDRESS, {(uint32_t)_rom_attr}), +#endif + + MPU_REGION_ENTRY("PERIPHERALS", REGION_PERIPHERAL_BASE_ADDRESS, + REGION_IO_ATTR(REGION_PERIPHERAL_SIZE)), + + MPU_REGION_ENTRY("PPB", REGION_PPB_BASE_ADDRESS, REGION_PPB_ATTR(REGION_PPB_SIZE)), +}; + +const struct arm_mpu_config mpu_config = { + .num_regions = ARRAY_SIZE(mpu_regions), + .mpu_regions = mpu_regions, +}; diff --git a/soc/nxp/s32/s32k5/m7/s32k5xx_startup.S b/soc/nxp/s32/s32k5/m7/s32k5xx_startup.S new file mode 100644 index 000000000000..a6a66f2546d4 --- /dev/null +++ b/soc/nxp/s32/s32k5/m7/s32k5xx_startup.S @@ -0,0 +1,41 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +_ASM_FILE_PROLOGUE + +GTEXT(soc_early_reset_hook) + +SECTION_FUNC(TEXT, soc_early_reset_hook) + + /* + * SRAM must be initialized to a known value using a 64-bit initiator before + * 32-bit initiators can read or write to them. Note that SRAM retains content + * during functional reset through a hardware mechanism, therefore accesses do not + * cause any content corruption errors. + * + * This is implemented directly in ASM, to ensure no stack access is performed. + */ + ldr r1, = DT_REG_ADDR(DT_CHOSEN(zephyr_sram)) + ldr r2, = DT_REG_SIZE(DT_CHOSEN(zephyr_sram)) + + subs r2, #1 + + ble ECC_END + + movs r0, 0 + movs r3, 0 + +SRAM_LOOP: + stm r1!, {r0,r3} + subs r2, 8 + bge SRAM_LOOP + +ECC_END: + bx lr diff --git a/soc/nxp/s32/s32k5/m7/sections.ld b/soc/nxp/s32/s32k5/m7/sections.ld new file mode 100644 index 000000000000..eb09c7679f56 --- /dev/null +++ b/soc/nxp/s32/s32k5/m7/sections.ld @@ -0,0 +1,12 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define _NORMAL_OUTER_INNER_WRITE_THROUGH_NON_SHAREABLE (1 << 17) +#define _RO_Msk (7 << 24) + +/* ROM region size order for MPU configuration */ +_rom_region_order = ((LOG2CEIL(__rom_region_end - __rom_region_start) - 1) << 1); +_rom_attr = (_NORMAL_OUTER_INNER_WRITE_THROUGH_NON_SHAREABLE | _rom_region_order | _RO_Msk); diff --git a/soc/nxp/s32/s32k5/m7/soc.c b/soc/nxp/s32/s32k5/m7/soc.c new file mode 100644 index 000000000000..3ec832940d47 --- /dev/null +++ b/soc/nxp/s32/s32k5/m7/soc.c @@ -0,0 +1,24 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +#include +#include + +extern void swt_disable(void); + +void soc_early_init_hook(void) +{ + sys_cache_instr_enable(); + sys_cache_data_enable(); + + swt_disable(); + OsIf_Init(NULL); +} diff --git a/soc/nxp/s32/s32k5/m7/soc.h b/soc/nxp/s32/s32k5/m7/soc.h new file mode 100644 index 000000000000..4e27ded5b9ae --- /dev/null +++ b/soc/nxp/s32/s32k5/m7/soc.h @@ -0,0 +1,17 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _NXP_S32_S32K5_M7_SOC_H_ +#define _NXP_S32_S32K5_M7_SOC_H_ + +#include +#include + +#if defined(CONFIG_CMSIS_RTOS_V2) +#include +#endif + +#endif /* _NXP_S32_S32K5_M7_SOC_H_ */ diff --git a/soc/nxp/s32/s32k5/r52/CMakeLists.txt b/soc/nxp/s32/s32k5/r52/CMakeLists.txt new file mode 100644 index 000000000000..c7e53e0e38e5 --- /dev/null +++ b/soc/nxp/s32/s32k5/r52/CMakeLists.txt @@ -0,0 +1,8 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +zephyr_include_directories(.) +zephyr_library_sources(soc.c) +zephyr_library_sources_ifdef(CONFIG_ARM_MPU mpu_regions.c) +zephyr_library_sources_ifdef(CONFIG_SOC_RESET_HOOK s32k5xx_startup.S) +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_a_r/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/nxp/s32/s32k5/r52/mpu_regions.c b/soc/nxp/s32/s32k5/r52/mpu_regions.c new file mode 100644 index 000000000000..0ec7fd2a34cd --- /dev/null +++ b/soc/nxp/s32/s32k5/r52/mpu_regions.c @@ -0,0 +1,43 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#define DEVICE_REGION_START 0x40000000UL +#define DEVICE_REGION_END 0xE00FFFFFUL + +static const struct arm_mpu_region mpu_regions[] = { + MPU_REGION_ENTRY("SRAM_TEXT", + (uintptr_t)__rom_region_start, + REGION_RAM_TEXT_ATTR((uintptr_t)__rodata_region_start)), + + MPU_REGION_ENTRY("SRAM_RODATA", + (uintptr_t)__rodata_region_start, +#ifdef CONFIG_XIP + REGION_RAM_RO_ATTR(CONFIG_FLASH_BASE_ADDRESS + KB(CONFIG_FLASH_SIZE)) +#else + REGION_RAM_RO_ATTR((uintptr_t)__rodata_region_end) +#endif + ), + + MPU_REGION_ENTRY("SRAM_DATA", +#ifdef CONFIG_XIP + (uintptr_t)_image_ram_start, +#else + (uintptr_t)__rom_region_end, +#endif + REGION_RAM_ATTR((uintptr_t)__kernel_ram_end)), + + MPU_REGION_ENTRY("DEVICE", + DEVICE_REGION_START, + REGION_DEVICE_ATTR(DEVICE_REGION_END)), +}; + +const struct arm_mpu_config mpu_config = { + .num_regions = ARRAY_SIZE(mpu_regions), + .mpu_regions = mpu_regions, +}; diff --git a/soc/nxp/s32/s32k5/r52/s32k5xx_startup.S b/soc/nxp/s32/s32k5/r52/s32k5xx_startup.S new file mode 100644 index 000000000000..eca375ff627b --- /dev/null +++ b/soc/nxp/s32/s32k5/r52/s32k5xx_startup.S @@ -0,0 +1,62 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +#define LPE_MC_RGM_BASE 0x42074000 +#define LPE_MC_RGM_DES 0x0 +#define LPE_MC_RGM_FES 0x8 + +_ASM_FILE_PROLOGUE + +GTEXT(soc_reset_hook) + +SECTION_FUNC(TEXT, soc_reset_hook) + + /* Enable peripheral port access at EL1 and EL0 */ + mrc p15, 0, r0, c15, c0, 0 + orr r0, #1 + mcr p15, 0, r0, c15, c0, 0 + + /* + * Take exceptions in Arm mode because Zephyr ASM code for Cortex-R Aarch32 + * is written for Arm + */ + mrc p15, 0, r0, c1, c0, 0 + and r0, r0, #~BIT(30) + mcr p15, 0, r0, c1, c0, 0 + +#if defined(CONFIG_XIP) + /* + * SRAM must be initialized to a known value using a 64-bit initiator before + * 32-bit initiators can read or write to them. Note that SRAM retains content + * during functional reset through a hardware mechanism, therefore accesses do not + * cause any content corruption errors. + * + * This is implemented directly in ASM, to ensure no stack access is performed. + */ + ldr r1, =DT_REG_ADDR(DT_CHOSEN(zephyr_sram)) + ldr r2, =DT_REG_SIZE(DT_CHOSEN(zephyr_sram)) + + subs r2, r2, #1 + ble ECC_END + + mov r0, #0 + mov r3, #0 + +SRAM_LOOP: + stmia r1!, {r0, r3} + subs r2, r2, #8 + bge SRAM_LOOP + +ECC_END: + +#endif /* CONFIG_XIP */ + + bx lr diff --git a/soc/nxp/s32/s32k5/r52/soc.c b/soc/nxp/s32/s32k5/r52/soc.c new file mode 100644 index 000000000000..b634af1ca9e9 --- /dev/null +++ b/soc/nxp/s32/s32k5/r52/soc.c @@ -0,0 +1,20 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include + +extern void swt_disable(void); + +void soc_early_init_hook(void) +{ + sys_cache_instr_enable(); + sys_cache_data_enable(); + + swt_disable(); + OsIf_Init(NULL); +} diff --git a/soc/nxp/s32/s32k5/r52/soc.h b/soc/nxp/s32/s32k5/r52/soc.h new file mode 100644 index 000000000000..0b907d953e83 --- /dev/null +++ b/soc/nxp/s32/s32k5/r52/soc.h @@ -0,0 +1,19 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _NXP_S32_S32K5_R52_SOC_H_ +#define _NXP_S32_S32K5_R52_SOC_H_ + +/* Do not let CMSIS to handle GIC */ +#define __GIC_PRESENT 0 + +#include + +#if defined(CONFIG_CMSIS_RTOS_V2) +#include +#endif + +#endif /* _NXP_S32_S32K5_R52_SOC_H_ */ diff --git a/soc/nxp/s32/s32k5/swt_disable.c b/soc/nxp/s32/s32k5/swt_disable.c new file mode 100644 index 000000000000..d527ec0157c2 --- /dev/null +++ b/soc/nxp/s32/s32k5/swt_disable.c @@ -0,0 +1,34 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +/* SWT Startup Control Register */ +#define SWT_STARTUP_CR 0x404A8000 +/* SWT Control Register bits */ +#define SWT_CR_WEN BIT(0) + +#define MCME_SWT_STARTUP_REQ BIT(10) +#define MCME_SWT_STARTUP_COFB_IDX 1 +#define MCME_SWT_STARTUP_PARTITION_IDX 2 + +/* + * The SWT startup is enabled by default, with a timeout of 320 counter clocks. + * Since the watchdog driver disables the watchdog too late, use the watchdog hook + * to prevent resets. + */ +void swt_disable(void) +{ + uint32_t reg_val; + + mc_me_configure_cofb(MCME_SWT_STARTUP_PARTITION_IDX, + MCME_SWT_STARTUP_COFB_IDX, MCME_SWT_STARTUP_REQ); + + reg_val = sys_read32(SWT_STARTUP_CR); + sys_write32(reg_val & ~SWT_CR_WEN, SWT_STARTUP_CR); +} diff --git a/soc/nxp/s32/soc.yml b/soc/nxp/s32/soc.yml index 8d71e2b53aa6..0b59e3df396f 100644 --- a/soc/nxp/s32/soc.yml +++ b/soc/nxp/s32/soc.yml @@ -14,6 +14,12 @@ family: - name: s32k3 socs: - name: s32k344 + - name: s32k5 + socs: + - name: s32k566 + cpuclusters: + - name: m7 + - name: r52 - name: s32ze socs: - name: s32z270 From 377922dfcfd8e0add0dc91f7017124257936f216 Mon Sep 17 00:00:00 2001 From: Dat Nguyen Duy Date: Thu, 6 Nov 2025 09:22:36 +0700 Subject: [PATCH 0843/3659] drivers: add initial support for NXP S32K566 Initial support for NXP S32K566 M7 & R52: Clock, Pin control, GPIO and Uart Signed-off-by: Dat Nguyen Duy --- drivers/clock_control/clock_control_nxp_s32.c | 7 +- .../interrupt_controller/Kconfig.nxp_siul2 | 2 + drivers/pinctrl/Kconfig.nxp_siul2 | 6 +- dts/arm/nxp/nxp_s32k566.dtsi | 550 ++++++++++++++++++ dts/arm/nxp/nxp_s32k566_m7.dtsi | 168 ++++++ dts/arm/nxp/nxp_s32k566_r52.dtsi | 168 ++++++ dts/bindings/pinctrl/nxp,s32k5-pinctrl.yaml | 117 ++++ .../dt-bindings/clock/nxp_s32k566_clock.h | 378 ++++++++++++ soc/nxp/s32/s32k5/CMakeLists.txt | 2 + soc/nxp/s32/s32k5/Kconfig | 1 + soc/nxp/s32/s32k5/pinctrl_soc.h | 67 +++ west.yml | 2 +- 12 files changed, 1464 insertions(+), 4 deletions(-) create mode 100644 dts/arm/nxp/nxp_s32k566.dtsi create mode 100644 dts/arm/nxp/nxp_s32k566_m7.dtsi create mode 100644 dts/arm/nxp/nxp_s32k566_r52.dtsi create mode 100644 dts/bindings/pinctrl/nxp,s32k5-pinctrl.yaml create mode 100644 include/zephyr/dt-bindings/clock/nxp_s32k566_clock.h create mode 100644 soc/nxp/s32/s32k5/pinctrl_soc.h diff --git a/drivers/clock_control/clock_control_nxp_s32.c b/drivers/clock_control/clock_control_nxp_s32.c index e00de280c1f0..93d13b84f129 100644 --- a/drivers/clock_control/clock_control_nxp_s32.c +++ b/drivers/clock_control/clock_control_nxp_s32.c @@ -1,5 +1,5 @@ /* - * Copyright 2023 NXP + * Copyright 2023,2025 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -10,6 +10,11 @@ #include +#if defined(CLOCK_IP_HAS_FIRC_CLK) && (CLOCK_IP_HAS_FIRC_CLK == 0) +/* Support newer platforms in which CLOCK_IS_OFF is undefined */ +#define CLOCK_IS_OFF -1 +#endif + #define NXP_S32_CLOCK_CONFIG_IDX CONFIG_CLOCK_CONTROL_NXP_S32_CLOCK_CONFIG_IDX BUILD_ASSERT(CLOCK_IP_GET_FREQUENCY_API == STD_ON, diff --git a/drivers/interrupt_controller/Kconfig.nxp_siul2 b/drivers/interrupt_controller/Kconfig.nxp_siul2 index ae2c64f261c5..fcec54b79517 100644 --- a/drivers/interrupt_controller/Kconfig.nxp_siul2 +++ b/drivers/interrupt_controller/Kconfig.nxp_siul2 @@ -15,6 +15,7 @@ if NXP_SIUL2_EIRQ config NXP_SIUL2_EIRQ_EXT_INTERRUPTS_MAX int default 8 if SOC_SERIES_S32ZE + default 16 if SOC_SERIES_S32K5 default 32 if SOC_SERIES_S32K3 || SOC_SERIES_MCXE31X help Number of SIUL2 external interrupts per controller. This is a SoC @@ -23,6 +24,7 @@ config NXP_SIUL2_EIRQ_EXT_INTERRUPTS_MAX config NXP_SIUL2_EIRQ_EXT_INTERRUPTS_GROUP int default 8 + default 16 if SOC_SERIES_S32K5 help Number of SIUL2 external interrupts grouped into a single core interrupt line. This is a SoC integration option. diff --git a/drivers/pinctrl/Kconfig.nxp_siul2 b/drivers/pinctrl/Kconfig.nxp_siul2 index 1650f9d38685..f5000e19fc04 100644 --- a/drivers/pinctrl/Kconfig.nxp_siul2 +++ b/drivers/pinctrl/Kconfig.nxp_siul2 @@ -4,7 +4,9 @@ config PINCTRL_NXP_SIUL2 bool "Pin controller driver for NXP SIUL2" default y - depends on DT_HAS_NXP_S32ZE_SIUL2_PINCTRL_ENABLED || DT_HAS_NXP_S32K3_SIUL2_PINCTRL_ENABLED || \ - DT_HAS_NXP_MCXE31X_SIUL2_PINCTRL_ENABLED + depends on DT_HAS_NXP_S32ZE_SIUL2_PINCTRL_ENABLED || \ + DT_HAS_NXP_S32K3_SIUL2_PINCTRL_ENABLED || \ + DT_HAS_NXP_S32K5_PINCTRL_ENABLED || \ + DT_HAS_NXP_MCXE31X_SIUL2_PINCTRL_ENABLED help Enable pin controller driver for NXP SIUL2. diff --git a/dts/arm/nxp/nxp_s32k566.dtsi b/dts/arm/nxp/nxp_s32k566.dtsi new file mode 100644 index 000000000000..4682ca4e203a --- /dev/null +++ b/dts/arm/nxp/nxp_s32k566.dtsi @@ -0,0 +1,550 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + soc { + sram0: sram@21000000 { + compatible = "mmio-sram"; + reg = <0x21000000 DT_SIZE_K(512)>; + }; + + sram1: sram@21080000 { + compatible = "mmio-sram"; + reg = <0x21080000 DT_SIZE_K(512)>; + }; + + sram2: sram@21100000 { + compatible = "mmio-sram"; + reg = <0x21100000 DT_SIZE_K(512)>; + }; + + /* The boot header occupies the first 256bytes */ + cmram: mram@8000100 { + compatible = "soc-nv-flash"; + reg = <0x8000100 DT_SIZE_M(32)>; + }; + + cpe_sram: sram@22000000 { + compatible = "mmio-sram"; + reg = <0x22000000 DT_SIZE_M(1)>; + }; + + clock: clock-controller@42110000 { + compatible = "nxp,s32-clock"; + reg = <0x42110000 0x4000>, + <0x42118000 0x4000>, + <0x4211c000 0x4000>, + <0x41074000 0x4000>, + <0x41078000 0x4000>, + <0x40094000 0x4000>, + <0x40098000 0x4000>, + <0x402fc000 0x4000>, + <0x404b8000 0x4000>, + <0x40b38000 0x4000>, + <0x40b3c000 0x4000>, + <0x40b40000 0x4000>, + <0x42120000 0x4000>; + #clock-cells = <1>; + status = "okay"; + }; + + /* Dummy pinctrl node, filled with pin mux options at board level */ + pinctrl: pinctrl { + compatible = "nxp,s32k5-pinctrl"; + status = "okay"; + }; + + mc_me: mc_me@40498000 { + compatible = "nxp,s32-mc-me"; + reg = <0x40498000 0x4000>; + }; + + siul2_0: siul2@40014000 { + reg = <0x40014000 0x10000>; + #address-cells = <1>; + #size-cells = <1>; + + eirq0: eirq0@40014010 { + compatible = "nxp,siul2-eirq"; + reg = <0x40014010 0xb4>; + #address-cells = <0>; + interrupt-controller; + #interrupt-cells = <2>; + status = "disabled"; + }; + + gpioa: gpio@40015702 { + compatible = "nxp,siul2-gpio"; + reg = <0x40015702 0x02>, <0x40014240 0x40>; + reg-names = "pgpdo", "mscr"; + interrupt-parent = <&eirq0>; + interrupts = <0 0>, <1 1>, <2 10>, <3 9>, + <4 4>, <8 8>, <10 6>, <11 4>, + <13 5>, <14 13>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <16>; + status = "disabled"; + }; + + gpiob: gpio@40015700 { + compatible = "nxp,siul2-gpio"; + reg = <0x40015700 0x02>, <0x40014280 0x40>; + reg-names = "pgpdo", "mscr"; + interrupt-parent = <&eirq0>; + interrupts = <2 5>, <3 9>, <4 11>, <5 12>, + <6 14>, <7 15>, <10 7>, <13 13>, + <14 11>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <16>; + status = "disabled"; + }; + + gpioc: gpio@40015706 { + compatible = "nxp,siul2-gpio"; + reg = <0x40015706 0x02>, <0x400142c0 0x40>; + reg-names = "pgpdo", "mscr"; + interrupt-parent = <&eirq0>; + interrupts = <1 2>, <3 7>, <4 1>, <7 8>, + <10 15>, <11 2>, <12 10>, + <13 3>, <14 6>, <15 0>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <16>; + status = "disabled"; + }; + + gpiod: gpio@40015704 { + compatible = "nxp,siul2-gpio"; + reg = <0x40015704 0x02>, <0x40014300 0x40>; + reg-names = "pgpdo", "mscr"; + interrupt-parent = <&eirq0>; + interrupts = <1 1>, <5 8>, <6 9>, <9 10>, + <10 14>, <15 11>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <16>; + status = "disabled"; + }; + + gpioe: gpio@4001570a { + compatible = "nxp,siul2-gpio"; + reg = <0x4001570a 0x02>, <0x40014340 0x40>; + reg-names = "pgpdo", "mscr"; + interrupt-parent = <&eirq0>; + interrupts = <0 12>, <1 4>, <2 5>, <3 3>, + <4 6>, <5 9>, <7 2>, <9 7>, + <11 12>, <13 15>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <15>; + status = "disabled"; + }; + }; + + siul2_1: siul2@40204000 { + reg = <0x40204000 0x10000>; + #address-cells = <1>; + #size-cells = <1>; + + eirq1: eirq1@40204010 { + compatible = "nxp,siul2-eirq"; + reg = <0x40204010 0xb4>; + #address-cells = <0>; + interrupt-controller; + #interrupt-cells = <2>; + status = "disabled"; + }; + + gpiof: gpio@40205708 { + compatible = "nxp,siul2-gpio"; + reg = <0x40205708 0x02>, <0x40204380 0x40>; + reg-names = "pgpdo", "mscr"; + interrupt-parent = <&eirq1>; + interrupts = <1 1>, <2 11>, <3 3>, <4 3>, + <5 5>, <6 2>, <7 12>, <9 9>, + <10 10>, <11 4>, <13 7>, <15 8>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <16>; + status = "disabled"; + }; + + gpiog: gpio@4020570e { + compatible = "nxp,siul2-gpio"; + reg = <0x4020570e 0x02>, <0x402043c0 0x40>; + reg-names = "pgpdo", "mscr"; + interrupt-parent = <&eirq1>; + interrupts = <0 9>, <1 0>, <2 10>, <3 1>, + <4 13>, <5 14>, <6 15>, <8 5>, + <9 2>, <10 4>, <13 6>, <14 7>, + <15 6>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <16>; + status = "disabled"; + }; + + gpioh: gpio@4020570c { + compatible = "nxp,siul2-gpio"; + reg = <0x4020570c 0x02>, <0x40204400 0x40>; + reg-names = "pgpdo", "mscr"; + interrupt-parent = <&eirq1>; + interrupts = <0 8>, <4 15>, <14 11>, <15 12>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <16>; + status = "disabled"; + }; + }; + + /* LPE_SIUL2 */ + siul2_2: siul2@4208c000 { + reg = <0x4208c000 0x10000>; + #address-cells = <1>; + #size-cells = <1>; + + eirq2: eirq2@4208c010 { + compatible = "nxp,siul2-eirq"; + reg = <0x4208c010 0xb4>; + #address-cells = <0>; + interrupt-controller; + #interrupt-cells = <2>; + status = "disabled"; + }; + + gpiok: gpio@4208d716 { + compatible = "nxp,siul2-gpio"; + reg = <0x4208d716 0x02>, <0x4208c4c0 0x40>; + reg-names = "pgpdo", "mscr"; + interrupt-parent = <&eirq2>; + interrupts = <0 7>, <1 6>, <4 1>, <5 0>, + <6 10>, <8 11>, <9 12>, + <10 0>, <11 4>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <11>; + status = "disabled"; + }; + + gpiol: gpio@4208d714 { + compatible = "nxp,siul2-gpio"; + reg = <0x4208d714 0x02>, <0x4208c500 0x40>; + reg-names = "pgpdo", "mscr"; + interrupt-parent = <&eirq2>; + interrupts = <0 8>, <2 5>, <3 5>, <4 15>, <7 2>, + <8 4>, <10 3>, <11 14>, <14 3>, <15 6>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <16>; + status = "disabled"; + }; + + gpiom: gpio@4208d71a { + compatible = "nxp,siul2-gpio"; + reg = <0x4208d71a 0x02>, <0x4208c540 0x40>; + reg-names = "pgpdo", "mscr"; + interrupt-parent = <&eirq2>; + interrupts = <2 13>, <3 10>, <4 9>, <5 9>, <6 2>, + <9 0>, <11 1>, <14 3>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <16>; + status = "disabled"; + }; + }; + + siul2_3: siul2@40610000 { + reg = <0x40610000 0x10000>; + #address-cells = <1>; + #size-cells = <1>; + + eirq3: eirq3@40610010 { + compatible = "nxp,siul2-eirq"; + reg = <0x40610010 0xb4>; + #address-cells = <0>; + interrupt-controller; + #interrupt-cells = <2>; + status = "disabled"; + }; + + gpion: gpio@40611718 { + compatible = "nxp,siul2-gpio"; + reg = <0x40611718 0x02>, <0x40610580 0x40>; + reg-names = "pgpdo", "mscr"; + interrupt-parent = <&eirq3>; + interrupts = <0 7>, <1 6>, <4 1>, <5 0>, + <6 10>, <8 11>, <9 12>, + <10 0>, <11 4>, <14 1>, <15 8>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <16>; + status = "disabled"; + }; + + gpioo: gpio@4061171e { + compatible = "nxp,siul2-gpio"; + reg = <0x4061171e 0x02>, <0x406105c0 0x40>; + reg-names = "pgpdo", "mscr"; + interrupt-parent = <&eirq3>; + interrupts = <0 8>, <2 5>, <3 5>, <4 15>, <7 2>, + <8 4>, <10 3>, <11 14>, <14 3>, <15 6>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <16>; + status = "disabled"; + }; + + gpiop: gpio@4061171c { + compatible = "nxp,siul2-gpio"; + reg = <0x4061171c 0x02>, <0x40610600 0x40>; + reg-names = "pgpdo", "mscr"; + interrupt-parent = <&eirq3>; + interrupts = <2 13>, <3 10>, <4 9>, <5 9>, <6 2>, + <9 0>, <11 1>, <14 3>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <15>; + status = "disabled"; + }; + }; + + siul2_4: siul2@40804000 { + reg = <0x40804000 0x10000>; + #address-cells = <1>; + #size-cells = <1>; + + eirq4: eirq4@40804010 { + compatible = "nxp,siul2-eirq"; + reg = <0x40804010 0xb4>; + #address-cells = <0>; + interrupt-controller; + #interrupt-cells = <2>; + status = "disabled"; + }; + + gpiot: gpio@40805724 { + compatible = "nxp,siul2-gpio"; + reg = <0x40805724 0x02>, <0x40804700 0x40>; + reg-names = "pgpdo", "mscr"; + interrupt-parent = <&eirq4>; + interrupts = <0 5>, <1 4>, <2 0>, <3 14>, + <6 11>, <7 6>, <8 7>, <9 8>, + <10 1>, <11 9>, <12 12>, <14 5>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <16>; + status = "disabled"; + }; + + gpiou: gpio@4080572a { + compatible = "nxp,siul2-gpio"; + reg = <0x4080572a 0x02>, <0x40804740 0x40>; + reg-names = "pgpdo", "mscr"; + interrupt-parent = <&eirq4>; + interrupts = <2 13>, <6 0>, <7 15>, <8 2>, + <9 1>, <10 2>, <11 3>, <13 4>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <16>; + status = "disabled"; + }; + + gpiov: gpio@40805728 { + compatible = "nxp,siul2-gpio"; + reg = <0x40805728 0x02>, <0x40804780 0x40>; + reg-names = "pgpdo", "mscr"; + interrupt-parent = <&eirq4>; + interrupts = <0 6>, <1 7>, <2 8>, <3 0>, <4 1>, + <5 2>, <6 3>, <7 4>, <8 5>, <9 6>, + <10 9>, <11 8>, <12 10>, <13 11>, + <14 7>, <15 12>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <16>; + status = "disabled"; + }; + }; + + lpe_lpuart0: uart@42184000 { + compatible = "nxp,lpuart"; + reg = <0x42184000 0x4000>; + clocks = <&clock NXP_S32_LPE_LPUART0_CLK>; + status = "disabled"; + }; + + lpe_lpuart1: uart@42188000 { + compatible = "nxp,lpuart"; + reg = <0x42188000 0x4000>; + clocks = <&clock NXP_S32_LPE_LPUART1_CLK>; + status = "disabled"; + }; + + lpe_lpuart2: uart@4218c000 { + compatible = "nxp,lpuart"; + reg = <0x4218c000 0x4000>; + clocks = <&clock NXP_S32_LPE_LPUART2_CLK>; + status = "disabled"; + }; + + lpuart0: uart@400e0000 { + compatible = "nxp,lpuart"; + reg = <0x400e0000 0x4000>; + clocks = <&clock NXP_S32_LPUART0_CLK>; + status = "disabled"; + }; + + lpuart1: uart@400e4000 { + compatible = "nxp,lpuart"; + reg = <0x400e4000 0x4000>; + clocks = <&clock NXP_S32_LPUART1_CLK>; + status = "disabled"; + }; + + lpuart2: uart@402c8000 { + compatible = "nxp,lpuart"; + reg = <0x402c8000 0x4000>; + clocks = <&clock NXP_S32_LPUART2_CLK>; + status = "disabled"; + }; + + lpuart3: uart@402cc000 { + compatible = "nxp,lpuart"; + reg = <0x402cc000 0x4000>; + clocks = <&clock NXP_S32_LPUART3_CLK>; + status = "disabled"; + }; + + lpuart4: uart@402d0000 { + compatible = "nxp,lpuart"; + reg = <0x402d0000 0x4000>; + clocks = <&clock NXP_S32_LPUART4_CLK>; + status = "disabled"; + }; + + lpuart5: uart@402d4000 { + compatible = "nxp,lpuart"; + reg = <0x402d4000 0x4000>; + clocks = <&clock NXP_S32_LPUART5_CLK>; + status = "disabled"; + }; + + lpuart6: uart@402d8000 { + compatible = "nxp,lpuart"; + reg = <0x402d8000 0x4000>; + clocks = <&clock NXP_S32_LPUART6_CLK>; + status = "disabled"; + }; + + lpuart7: uart@402dc000 { + compatible = "nxp,lpuart"; + reg = <0x402dc000 0x4000>; + clocks = <&clock NXP_S32_LPUART7_CLK>; + status = "disabled"; + }; + + lpuart8: uart@402e0000 { + compatible = "nxp,lpuart"; + reg = <0x402e0000 0x4000>; + clocks = <&clock NXP_S32_LPUART8_CLK>; + status = "disabled"; + }; + + lpuart9: uart@402e4000 { + compatible = "nxp,lpuart"; + reg = <0x402e4000 0x4000>; + clocks = <&clock NXP_S32_LPUART9_CLK>; + status = "disabled"; + }; + + lpuart10: uart@402b8000 { + compatible = "nxp,lpuart"; + reg = <0x402b8000 0x4000>; + clocks = <&clock NXP_S32_LPUART10_CLK>; + status = "disabled"; + }; + + lpuart11: uart@402bc000 { + compatible = "nxp,lpuart"; + reg = <0x402bc000 0x4000>; + clocks = <&clock NXP_S32_LPUART11_CLK>; + status = "disabled"; + }; + + lpuart12: uart@402c0000 { + compatible = "nxp,lpuart"; + reg = <0x402c0000 0x4000>; + clocks = <&clock NXP_S32_LPUART12_CLK>; + status = "disabled"; + }; + + lpuart13: uart@402c4000 { + compatible = "nxp,lpuart"; + reg = <0x402c4000 0x4000>; + clocks = <&clock NXP_S32_LPUART13_CLK>; + status = "disabled"; + }; + + lpuart14: uart@406cc000 { + compatible = "nxp,lpuart"; + reg = <0x406cc000 0x4000>; + clocks = <&clock NXP_S32_LPUART14_CLK>; + status = "disabled"; + }; + + lpuart15: uart@406d0000 { + compatible = "nxp,lpuart"; + reg = <0x406d0000 0x4000>; + clocks = <&clock NXP_S32_LPUART15_CLK>; + status = "disabled"; + }; + + lpuart16: uart@406d4000 { + compatible = "nxp,lpuart"; + reg = <0x406d4000 0x4000>; + clocks = <&clock NXP_S32_LPUART16_CLK>; + status = "disabled"; + }; + + lpuart17: uart@408c4000 { + compatible = "nxp,lpuart"; + reg = <0x408c4000 0x4000>; + clocks = <&clock NXP_S32_LPUART17_CLK>; + status = "disabled"; + }; + + lpuart18: uart@408c8000 { + compatible = "nxp,lpuart"; + reg = <0x408c8000 0x4000>; + clocks = <&clock NXP_S32_LPUART18_CLK>; + status = "disabled"; + }; + + lpuart19: uart@408cc000 { + compatible = "nxp,lpuart"; + reg = <0x408cc000 0x4000>; + clocks = <&clock NXP_S32_LPUART19_CLK>; + status = "disabled"; + }; + + lpuart20: uart@408d0000 { + compatible = "nxp,lpuart"; + reg = <0x408d0000 0x4000>; + clocks = <&clock NXP_S32_LPUART20_CLK>; + status = "disabled"; + }; + + lpuart21: uart@406f4000 { + compatible = "nxp,lpuart"; + reg = <0x406f4000 0x4000>; + status = "disabled"; + }; + }; +}; diff --git a/dts/arm/nxp/nxp_s32k566_m7.dtsi b/dts/arm/nxp/nxp_s32k566_m7.dtsi new file mode 100644 index 000000000000..6c3bbd34502a --- /dev/null +++ b/dts/arm/nxp/nxp_s32k566_m7.dtsi @@ -0,0 +1,168 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +/ { + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-m7"; + reg = <0>; + clock-frequency = ; + }; + + cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-m7"; + reg = <1>; + clock-frequency = ; + }; + + cpu@2 { + device_type = "cpu"; + compatible = "arm,cortex-m7"; + reg = <2>; + clock-frequency = ; + }; + + cpu@3 { + device_type = "cpu"; + compatible = "arm,cortex-m7"; + reg = <3>; + clock-frequency = ; + }; + }; + + soc { + interrupt-parent = <&nvic>; + }; +}; + +&nvic { + arm,num-irq-priority-bits = <4>; +}; + +&eirq0 { + interrupts = <29 0>; +}; + +&eirq1 { + interrupts = <30 0>; +}; + +&eirq2 { + interrupts = <211 0>; +}; + +&eirq3 { + interrupts = <31 0>; +}; + +&eirq4 { + interrupts = <32 0>; +}; + +&lpe_lpuart0 { + interrupts = <233 0>; +}; + +&lpe_lpuart1 { + interrupts = <234 0>; +}; + +&lpe_lpuart2 { + interrupts = <235 0>; +}; + +&lpuart0 { + interrupts = <155 0>; +}; + +&lpuart1 { + interrupts = <156 0>; +}; + +&lpuart2 { + interrupts = <157 0>; +}; + +&lpuart3 { + interrupts = <158 0>; +}; + +&lpuart4 { + interrupts = <159 0>; +}; + +&lpuart5 { + interrupts = <160 0>; +}; + +&lpuart6 { + interrupts = <161 0>; +}; + +&lpuart7 { + interrupts = <162 0>; +}; + +&lpuart8 { + interrupts = <163 0>; +}; + +&lpuart9 { + interrupts = <164 0>; +}; + +&lpuart10 { + interrupts = <165 0>; +}; + +&lpuart11 { + interrupts = <166 0>; +}; + +&lpuart12 { + interrupts = <167 0>; +}; + +&lpuart13 { + interrupts = <168 0>; +}; + +&lpuart14 { + interrupts = <169 0>; +}; + +&lpuart15 { + interrupts = <170 0>; +}; + +&lpuart16 { + interrupts = <171 0>; +}; + +&lpuart17 { + interrupts = <172 0>; +}; + +&lpuart18 { + interrupts = <173 0>; +}; + +&lpuart19 { + interrupts = <174 0>; +}; + +&lpuart20 { + interrupts = <175 0>; +}; diff --git a/dts/arm/nxp/nxp_s32k566_r52.dtsi b/dts/arm/nxp/nxp_s32k566_r52.dtsi new file mode 100644 index 000000000000..9a2762992e7b --- /dev/null +++ b/dts/arm/nxp/nxp_s32k566_r52.dtsi @@ -0,0 +1,168 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +/ { + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-r52"; + reg = <0>; + }; + + cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-r52"; + reg = <1>; + }; + }; + + arch_timer: timer { + compatible = "arm,armv8-timer"; + interrupts = , + , + , + ; + interrupt-parent = <&gic>; + clock-frequency = <4000000>; + }; + + soc { + interrupt-parent = <&gic>; + + gic: interrupt-controller@43000000 { + compatible = "arm,gic-v3", "arm,gic"; + reg = <0x43000000 0x10000>, + <0x43100000 0x40000>; + #address-cells = <0>; + interrupt-controller; + #interrupt-cells = <4>; + status = "okay"; + }; + }; +}; + +&eirq0 { + interrupts = ; +}; + +&eirq1 { + interrupts = ; +}; + +&eirq2 { + interrupts = ; +}; + +&eirq3 { + interrupts = ; +}; + +&eirq4 { + interrupts = ; +}; + +&lpe_lpuart0 { + interrupts = ; +}; + +&lpe_lpuart1 { + interrupts = ; +}; + +&lpe_lpuart2 { + interrupts = ; +}; + +&lpuart0 { + interrupts = ; +}; + +&lpuart1 { + interrupts = ; +}; + +&lpuart2 { + interrupts = ; +}; + +&lpuart3 { + interrupts = ; +}; + +&lpuart4 { + interrupts = ; +}; + +&lpuart5 { + interrupts = ; +}; + +&lpuart6 { + interrupts = ; +}; + +&lpuart7 { + interrupts = ; +}; + +&lpuart8 { + interrupts = ; +}; + +&lpuart9 { + interrupts = ; +}; + +&lpuart10 { + interrupts = ; +}; + +&lpuart11 { + interrupts = ; +}; + +&lpuart12 { + interrupts = ; +}; + +&lpuart13 { + interrupts = ; +}; + +&lpuart14 { + interrupts = ; +}; + +&lpuart15 { + interrupts = ; +}; + +&lpuart16 { + interrupts = ; +}; + +&lpuart17 { + interrupts = ; +}; + +&lpuart18 { + interrupts = ; +}; + +&lpuart19 { + interrupts = ; +}; + +&lpuart20 { + interrupts = ; +}; diff --git a/dts/bindings/pinctrl/nxp,s32k5-pinctrl.yaml b/dts/bindings/pinctrl/nxp,s32k5-pinctrl.yaml new file mode 100644 index 000000000000..449fe9a32bd9 --- /dev/null +++ b/dts/bindings/pinctrl/nxp,s32k5-pinctrl.yaml @@ -0,0 +1,117 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +description: | + NXP S32 Pin Controller for S32K5 SoCs + + The NXP S32 pin controller is a singleton node responsible for controlling + the pin function selection and pin properties. This node, labeled 'pinctrl' in + the SoC's devicetree, will define pin configurations in pin groups. Each group + within the pin configuration defines the pin configuration for a peripheral, + and each numbered subgroup in the pin group defines all the pins for that + peripheral with the same configuration properties. The 'pinmux' property in + a group selects the pins to be configured, and the remaining properties set + configuration values for those pins. + + For example, to configure the pinmux for LPUART3, modify the 'pinctrl' from your + board or application devicetree overlay as follows: + + /* Include the SoC package header containing the predefined pins definitions */ + #include + + &pinctrl { + lpuart3_default: lpuart3_default { + group1 { + pinmux = ; + output-enable; + }; + group2 { + pinmux = ; + input-enable; + }; + }; + }; + + The 'lpuart3_default' node contains the pin configurations for a particular state + of a device. The 'default' state is the active state. Other states for the same + device can be specified in separate child nodes of 'pinctrl'. + + In addition to 'pinmux' property, each group can contain other properties such as + 'bias-pull-up' or 'slew-rate' that will be applied to all the pins defined in + 'pinmux' array. To enable the input buffer use 'input-enable' and to enable the + output buffer use 'output-enable'. + + To link the pin configurations with LPUART3 device, use pinctrl-N property in the + device node, where 'N' is the zero-based state index (0 is the default state). + Following previous example: + + &lpuart3 { + pinctrl-0 = <&lpuart3_default>; + pinctrl-names = "default"; + status = "okay"; + }; + + If only the required properties are supplied, the pin configuration register + will be assigned the following values: + - input and output buffers disabled + - internal pull not enabled + - slew rate "fastest" + - invert disabled + - drive strength disabled. + + Additionally, following settings are currently not supported and default to + the values indicated below: + - Safe Mode Control (disabled) + - Pad Keeping (disabled) + - Input Filter (disabled). + - Injection current detection (disabled). + - Receiver Select (differential VREF based receiver) + +compatible: "nxp,s32k5-pinctrl" + +include: base.yaml + +child-binding: + description: NXP S32 pin controller pin group. + child-binding: + description: NXP S32 pin controller pin configuration node. + + include: + - name: pincfg-node.yaml + property-allowlist: + - bias-disable + - bias-pull-down + - bias-pull-up + - input-enable + - output-enable + + properties: + pinmux: + required: true + type: array + description: | + An array of pins sharing the same group properties. The pins must be + defined using the S32_PINMUX macros that encodes all the pin muxing + information in a 32-bit value. + + slew-rate: + type: string + enum: + - "fastest" + - "slowest" + default: "fastest" + description: | + Slew rate control. Can be either slowest or fastest setting. + See the SoC reference manual for applicability of this setting. + + nxp,invert: + type: boolean + description: | + Invert the signal selected by Source Signal Selection (SSS) before + transmitting it to the associated destination (chip pin or module port). + + nxp,drive-strength: + type: boolean + description: | + Drive strength enable. + See the SoC reference manual for applicability of this setting. diff --git a/include/zephyr/dt-bindings/clock/nxp_s32k566_clock.h b/include/zephyr/dt-bindings/clock/nxp_s32k566_clock.h new file mode 100644 index 000000000000..ccb471bfc994 --- /dev/null +++ b/include/zephyr/dt-bindings/clock/nxp_s32k566_clock.h @@ -0,0 +1,378 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_NXP_S32_S32K566_CLOCK_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_NXP_S32_S32K566_CLOCK_H_ + +#define NXP_S32_FIRC_CLK 0U +#define NXP_S32_FIRCDIV2_CLK 1U +#define NXP_S32_SAFE_CLK 2U +#define NXP_S32_SIRC_CLK 3U +#define NXP_S32_FXOSC_CLK 4U +#define NXP_S32_SXOSC_CLK 5U +#define NXP_S32_PLL0_CLK 25U +#define NXP_S32_PLL0_DIV_CLK 26U +#define NXP_S32_PLL0_DIV0_CLK 27U +#define NXP_S32_PLL0_DIV4_CLK 28U +#define NXP_S32_PLL0_DFS0_CLK 29U +#define NXP_S32_PLL0_DFS1_CLK 30U +#define NXP_S32_PLL0_DFS2_CLK 31U +#define NXP_S32_PLL0_DFS3_CLK 32U +#define NXP_S32_PLL1_CLK 33U +#define NXP_S32_PLL1_DIV_CLK 34U +#define NXP_S32_PLL1_DIV0_CLK 35U +#define NXP_S32_CPE_PLL_CLK 36U +#define NXP_S32_CPE_DIV_CLK 37U +#define NXP_S32_CPE_DIV0_CLK 38U +#define NXP_S32_LPE_CLK 39U +#define NXP_S32_LPE_DIV1_CLK 40U +#define NXP_S32_LPE_DIV2_CLK 41U +#define NXP_S32_LPE_DIV4_CLK 42U +#define NXP_S32_LPE_DIV8_CLK 43U +#define NXP_S32_PLT_CLK 44U +#define NXP_S32_PLTCORE_CLK 45U +#define NXP_S32_PLTDIV1_CLK 46U +#define NXP_S32_PLTDIV2_CLK 47U +#define NXP_S32_PLTDIV4_CLK 48U +#define NXP_S32_ACP_DMA3_H_CLK 50U +#define NXP_S32_ACP_DMA3_IPG_CLK 51U +#define NXP_S32_ADC0_IPG_CLK 52U +#define NXP_S32_ADC1_IPG_CLK 53U +#define NXP_S32_BCTU_IPG_CLK 54U +#define NXP_S32_BCTU_IPS_CLK 55U +#define NXP_S32_CAN_HUB_IPG_CLK 56U +#define NXP_S32_CAN_PE_CLK 57U +#define NXP_S32_CLKBIST_IPG_CLK 58U +#define NXP_S32_CRC0_IPG_CLK 59U +#define NXP_S32_CRC1_IPG_CLK 60U +#define NXP_S32_CSTCU_IPG_CLK 61U +#define NXP_S32_DIG_PHY0_CLK 62U +#define NXP_S32_DIG_PHY1_CLK 63U +#define NXP_S32_DIG_PHY2_CLK 64U +#define NXP_S32_DIG_PHY3_CLK 65U +#define NXP_S32_DMA_CH_MUX0_IPG_CLK 66U +#define NXP_S32_DMA_CH_MUX1_IPG_CLK 67U +#define NXP_S32_DMA4_AXI_CLK 68U +#define NXP_S32_DMA4_IPG_S_CLK 69U +#define NXP_S32_DFT_CLK 70U +#define NXP_S32_DSPI_CLK 71U +#define NXP_S32_DSPI0_IPG_CLK 72U +#define NXP_S32_DSPI1_IPG_CLK 73U +#define NXP_S32_EDMA_TCD_CLK 74U +#define NXP_S32_EIM0_IPG_CLK 75U +#define NXP_S32_EIM1_IPG_CLK 76U +#define NXP_S32_EIM2_IPG_CLK 77U +#define NXP_S32_EIM3_IPG_CLK 78U +#define NXP_S32_EMIOS0_IPG_CLK 79U +#define NXP_S32_EMIOS1_IPG_CLK 80U +#define NXP_S32_EMIOS2_IPG_CLK 81U +#define NXP_S32_ERM0_IPG_CLK 82U +#define NXP_S32_ERM1_IPG_CLK 83U +#define NXP_S32_ERM2_IPG_CLK 84U +#define NXP_S32_ERM3_IPG_CLK 85U +#define NXP_S32_ETH_TS_CLK 86U +#define NXP_S32_ETH0_RX_CLK 87U +#define NXP_S32_ETH0_TX_CLK 88U +#define NXP_S32_ETH1_RX_CLK 89U +#define NXP_S32_ETH1_TX_CLK 90U +#define NXP_S32_ETH2_RX_CLK 91U +#define NXP_S32_ETH2_TX_CLK 92U +#define NXP_S32_ETH3_RX_CLK 93U +#define NXP_S32_ETH3_TX_CLK 94U +#define NXP_S32_ETH4_RX_CLK 95U +#define NXP_S32_ETH4_TX_CLK 96U +#define NXP_S32_FLEXCAN_0to7_PE_CLK 97U +#define NXP_S32_FLEXCAN_8to10_PE_CLK 98U +#define NXP_S32_FLEXCAN_11to16_PE_CLK 99U +#define NXP_S32_FLEXCAN0_IPG_CLK 100U +#define NXP_S32_FLEXCAN0_PE_NOGATE_CLK 101U +#define NXP_S32_FLEXCAN0_TS_CLK 102U +#define NXP_S32_FLEXCAN1_IPG_CLK 103U +#define NXP_S32_FLEXCAN1_PE_NOGATE_CLK 104U +#define NXP_S32_FLEXCAN1_TS_CLK 105U +#define NXP_S32_FLEXCAN2_IPG_CLK 106U +#define NXP_S32_FLEXCAN2_PE_NOGATE_CLK 107U +#define NXP_S32_FLEXCAN2_TS_CLK 108U +#define NXP_S32_FLEXCAN3_IPG_CLK 109U +#define NXP_S32_FLEXCAN3_PE_NOGATE_CLK 110U +#define NXP_S32_FLEXCAN3_TS_CLK 111U +#define NXP_S32_FLEXCAN4_IPG_CLK 112U +#define NXP_S32_FLEXCAN4_PE_NOGATE_CLK 113U +#define NXP_S32_FLEXCAN4_TS_CLK 114U +#define NXP_S32_FLEXCAN5_IPG_CLK 115U +#define NXP_S32_FLEXCAN5_PE_NOGATE_CLK 116U +#define NXP_S32_FLEXCAN5_TS_CLK 117U +#define NXP_S32_FLEXCAN6_IPG_CLK 118U +#define NXP_S32_FLEXCAN6_PE_NOGATE_CLK 119U +#define NXP_S32_FLEXCAN6_TS_CLK 120U +#define NXP_S32_FLEXCAN7_IPG_CLK 121U +#define NXP_S32_FLEXCAN7_PE_NOGATE_CLK 122U +#define NXP_S32_FLEXCAN7_TS_CLK 123U +#define NXP_S32_FLEXCAN8_IPG_CLK 124U +#define NXP_S32_FLEXCAN8_PE_NOGATE_CLK 125U +#define NXP_S32_FLEXCAN8_TS_CLK 126U +#define NXP_S32_FLEXCAN9_IPG_CLK 127U +#define NXP_S32_FLEXCAN9_PE_NOGATE_CLK 128U +#define NXP_S32_FLEXCAN9_TS_CLK 129U +#define NXP_S32_FLEXCAN10_IPG_CLK 130U +#define NXP_S32_FLEXCAN10_PE_NOGATE_CLK 131U +#define NXP_S32_FLEXCAN10_TS_CLK 132U +#define NXP_S32_FLEXCAN11_IPG_CLK 133U +#define NXP_S32_FLEXCAN11_PE_NOGATE_CLK 134U +#define NXP_S32_FLEXCAN11_TS_CLK 135U +#define NXP_S32_FLEXCAN12_IPG_CLK 136U +#define NXP_S32_FLEXCAN12_PE_NOGATE_CLK 137U +#define NXP_S32_FLEXCAN12_TS_CLK 138U +#define NXP_S32_FLEXCAN13_IPG_CLK 139U +#define NXP_S32_FLEXCAN13_PE_NOGATE_CLK 140U +#define NXP_S32_FLEXCAN13_TS_CLK 141U +#define NXP_S32_FLEXCAN14_IPG_CLK 142U +#define NXP_S32_FLEXCAN14_PE_NOGATE_CLK 143U +#define NXP_S32_FLEXCAN14_TS_CLK 144U +#define NXP_S32_FLEXCAN15_IPG_CLK 145U +#define NXP_S32_FLEXCAN15_PE_NOGATE_CLK 146U +#define NXP_S32_FLEXCAN15_TS_CLK 147U +#define NXP_S32_FLEXCAN16_IPG_CLK 148U +#define NXP_S32_FLEXCAN16_PE_NOGATE_CLK 149U +#define NXP_S32_FLEXCAN16_TS_CLK 150U +#define NXP_S32_FLEXIO_CLK 151U +#define NXP_S32_FLEXIO0_IPG_CLK 152U +#define NXP_S32_FLEXIO0_PE_CLK 153U +#define NXP_S32_FLEXIO1_IPG_CLK 154U +#define NXP_S32_FLEXIO1_PE_CLK 155U +#define NXP_S32_GPR0_IPG_CLK 156U +#define NXP_S32_GPR1_IPG_CLK 157U +#define NXP_S32_INTM_IPG_CLK 158U +#define NXP_S32_IPSYNC_CSSI_MC_CGM_MASTER_CLK 159U +#define NXP_S32_IPSYNC_CSSI_MC_CGM_SLAVE_CLK 160U +#define NXP_S32_IPSYNC_CVFCCU_MASTER_CLK 161U +#define NXP_S32_IPSYNC_CVFCCU_SLAVE_CLK 162U +#define NXP_S32_IPSYNC_DSPI_IPI_0_MASTER_CLK 163U +#define NXP_S32_IPSYNC_DSPI_IPI_1_MASTER_CLK 164U +#define NXP_S32_IPSYNC_LPE_D_IP_FLEXCAN3_SYN_MASTER_CLK 165U +#define NXP_S32_IPSYNC_LPE_D_IP_FLEXCAN3_SYN_SLAVE_CLK 166U +#define NXP_S32_IPSYNC_LPE_D_IP_LOGIC_UNIT_SYN_MASTER_CLK 167U +#define NXP_S32_IPSYNC_LPE_D_IP_LOGIC_UNIT_SYN_SLAVE_CLK 168U +#define NXP_S32_IPSYNC_LPE_DA_IP_TEMPSENSE_C16FFC_MASTER_CLK 169U +#define NXP_S32_IPSYNC_LPE_DA_IP_TEMPSENSE_C16FFC_SLAVE_CLK 170U +#define NXP_S32_IPSYNC_LPE_LVFCCU_MASTER_CLK 171U +#define NXP_S32_IPSYNC_LPE_LVFCCU_SLAVE_CLK 172U +#define NXP_S32_IPSYNC_LPE_MC_CGM_MASTER_CLK 173U +#define NXP_S32_IPSYNC_LPE_MC_CGM_SLAVE_CLK 174U +#define NXP_S32_IPSYNC_LPE_MC_RGM_MASTER_CLK 175U +#define NXP_S32_IPSYNC_LPE_MC_RGM_SLAVE_CLK 176U +#define NXP_S32_IPSYNC_LPE_STM_MASTER_CLK 177U +#define NXP_S32_IPSYNC_LPE_STM_SLAVE_CLK 178U +#define NXP_S32_IPSYNC_LVFCCU0_MASTER_CLK 179U +#define NXP_S32_IPSYNC_LVFCCU0_SLAVE_CLK 180U +#define NXP_S32_IPSYNC_LVFCCU1_MASTER_CLK 181U +#define NXP_S32_IPSYNC_LVFCCU1_SLAVE_CLK 182U +#define NXP_S32_IPSYNC_LVFCCU2_MASTER_CLK 183U +#define NXP_S32_IPSYNC_LVFCCU2_SLAVE_CLK 184U +#define NXP_S32_IPSYNC_MC_CGM_MASTER_CLK 185U +#define NXP_S32_IPSYNC_MC_CGM_SLAVE_CLK 186U +#define NXP_S32_IPSYNC_NETC_MC_CGM_MASTER_CLK 187U +#define NXP_S32_IPSYNC_NETC_MC_CGM_SLAVE_CLK 188U +#define NXP_S32_IPSYNC_PERI_MC_CGM_MASTER_CLK 189U +#define NXP_S32_IPSYNC_PERI_MC_CGM_SLAVE_CLK 190U +#define NXP_S32_IPSYNC_SAI0_MC_CGM_MASTER_CLK 191U +#define NXP_S32_IPSYNC_SAI0_MC_CGM_SLAVE_CLK 192U +#define NXP_S32_IPSYNC_SAI1_MC_CGM_MASTER_CLK 193U +#define NXP_S32_IPSYNC_SAI1_MC_CGM_SLAVE_CLK 194U +#define NXP_S32_IPSYNC_STM0_MASTER_CLK 195U +#define NXP_S32_IPSYNC_STM0_SLAVE_CLK 196U +#define NXP_S32_IPSYNC_STM1_MASTER_CLK 197U +#define NXP_S32_IPSYNC_STM1_SLAVE_CLK 198U +#define NXP_S32_IPSYNC_STM2_MASTER_CLK 199U +#define NXP_S32_IPSYNC_STM2_SLAVE_CLK 200U +#define NXP_S32_IPSYNC_STM3_MASTER_CLK 201U +#define NXP_S32_IPSYNC_STM3_SLAVE_CLK 202U +#define NXP_S32_IPSYNC_XSPI_MASTER_CLK 203U +#define NXP_S32_IPSYNC_XSPI_SLAVE_CLK 204U +#define NXP_S32_LCU0_IPG_CLK 205U +#define NXP_S32_LCU1_IPG_CLK 206U +#define NXP_S32_LMEM_HCLK_CLK 207U +#define NXP_S32_LPE_ADC_IPG_CLK 208U +#define NXP_S32_LPE_BCTU_IPG_CLK 209U +#define NXP_S32_LPE_CMU_IPG_CLK 211U +#define NXP_S32_LPE_CRC_IPG_CLK 212U +#define NXP_S32_LPE_CXPI_PE_CLK 213U +#define NXP_S32_LPE_CXPI0_IPG_CLK 214U +#define NXP_S32_LPE_CXPI0_PE_CLK 215U +#define NXP_S32_LPE_CXPI1_IPG_CLK 216U +#define NXP_S32_LPE_CXPI1_PE_CLK 217U +#define NXP_S32_LPE_DIV1_UNGATED_CLK 218U +#define NXP_S32_LPE_DIV2_UNGATED_CLK 219U +#define NXP_S32_LPE_DIV3_UNGATED_CLK 220U +#define NXP_S32_LPE_DIV4_UNGATED_CLK 221U +#define NXP_S32_LPE_DMA_CH_MUX_IPG_CLK 222U +#define NXP_S32_LPE_EIM_IPG_CLK 223U +#define NXP_S32_LPE_FIRC_IPG_CLK 224U +#define NXP_S32_LPE_FLEXCAN_MOD_CLK 225U +#define NXP_S32_LPE_FLEXCAN_PE_CLK 226U +#define NXP_S32_LPE_FTM_IPG_CLK 227U +#define NXP_S32_LPE_FXOSC_IPG_CLK 228U +#define NXP_S32_LPE_GPR0_IPG_CLK 229U +#define NXP_S32_LPE_GPR1_IPG_CLK 230U +#define NXP_S32_LPE_LCU_IPG_CLK 231U +#define NXP_S32_LPE_LPCMP0_IPG_CLK 232U +#define NXP_S32_LPE_LPCMP0_RR_CLK 233U +#define NXP_S32_LPE_LPCMP0_SAMPLE_GATED_CLK 234U +#define NXP_S32_LPE_LPCMP1_IPG_CLK 235U +#define NXP_S32_LPE_LPCMP1_RR_CLK 236U +#define NXP_S32_LPE_LPCMP1_SAMPLE_GATED_CLK 237U +#define NXP_S32_LPE_LPCMP2_IPG_CLK 238U +#define NXP_S32_LPE_LPCMP2_RR_CLK 239U +#define NXP_S32_LPE_LPCMP2_SAMPLE_GATED_CLK 240U +#define NXP_S32_LPE_LPI2C_CLK 241U +#define NXP_S32_LPE_LPI2C_IPG_CLK 242U +#define NXP_S32_LPE_LPI2C_MOD_CLK 243U +#define NXP_S32_LPE_LPSPI_MOD_CLK 244U +#define NXP_S32_LPE_LPSPI0_CLK 245U +#define NXP_S32_LPE_LPSPI0_IPG_CLK 246U +#define NXP_S32_LPE_LPSPI1_CLK 247U +#define NXP_S32_LPE_LPSPI1_IPG_CLK 248U +#define NXP_S32_LPE_LPUART_MOD_CLK 249U +#define NXP_S32_LPE_LPUART0_CLK 250U +#define NXP_S32_LPE_LPUART1_CLK 252U +#define NXP_S32_LPE_LPUART2_CLK 254U +#define NXP_S32_LPE_LSTCU_IPG_CLK 256U +#define NXP_S32_LPE_RTC_API_FIRC_CLK 259U +#define NXP_S32_LPE_RTC_API_FXOSC_CLK 260U +#define NXP_S32_LPE_RTC_API_IPG_CLK 261U +#define NXP_S32_LPE_RTC_API_SIRC_CLK 262U +#define NXP_S32_LPE_RTC_API_SXOSC_CLK 263U +#define NXP_S32_LPE_SEMA42_CLK 264U +#define NXP_S32_LPE_STM_CLK 265U +#define NXP_S32_LPE_STM_IPG_CLK 266U +#define NXP_S32_LPE_SWT_COUNTER_IP_CLK 267U +#define NXP_S32_LPE_SWT_IPG_CLK 268U +#define NXP_S32_LPE_SXOSC_IPG_CLK 269U +#define NXP_S32_LPE_TRGMUX_IPG_CLK 270U +#define NXP_S32_LPE_TSPC_IPG_CLK 271U +#define NXP_S32_LPE_TSU_NS_IPG_CLK 272U +#define NXP_S32_LPE_UNGATED_CLK 273U +#define NXP_S32_LPE_VIRT_IPG_CLK 274U +#define NXP_S32_LPE_WKPU_IPG_CLK 275U +#define NXP_S32_LPI2C0_CLK 277U +#define NXP_S32_LPI2C1_CLK 278U +#define NXP_S32_LPI2C2_CLK 279U +#define NXP_S32_LPI2C3_CLK 280U +#define NXP_S32_LPSPI0_CLK 281U +#define NXP_S32_LPSPI1_CLK 282U +#define NXP_S32_LPSPI2_CLK 283U +#define NXP_S32_LPSPI3_CLK 284U +#define NXP_S32_LPSPI4_CLK 285U +#define NXP_S32_LPSPI5_CLK 286U +#define NXP_S32_LPSPI6_CLK 287U +#define NXP_S32_LPSPI7_CLK 288U +#define NXP_S32_LPUART_MSC_CLK 289U +#define NXP_S32_LPUART0_CLK 291U +#define NXP_S32_LPUART1_CLK 293U +#define NXP_S32_LPUART2_CLK 295U +#define NXP_S32_LPUART3_CLK 297U +#define NXP_S32_LPUART4_CLK 299U +#define NXP_S32_LPUART5_CLK 301U +#define NXP_S32_LPUART6_CLK 303U +#define NXP_S32_LPUART7_CLK 305U +#define NXP_S32_LPUART8_CLK 307U +#define NXP_S32_LPUART9_CLK 309U +#define NXP_S32_LPUART10_CLK 311U +#define NXP_S32_LPUART11_CLK 313U +#define NXP_S32_LPUART12_CLK 315U +#define NXP_S32_LPUART13_CLK 317U +#define NXP_S32_LPUART14_CLK 319U +#define NXP_S32_LPUART15_CLK 321U +#define NXP_S32_LPUART16_CLK 323U +#define NXP_S32_LPUART17_CLK 325U +#define NXP_S32_LPUART18_CLK 327U +#define NXP_S32_LPUART19_CLK 329U +#define NXP_S32_LPUART20_CLK 331U +#define NXP_S32_LSTCU_ACCEL_IPG_CLK 333U +#define NXP_S32_LSTCU_CORE0_IPG_CLK 334U +#define NXP_S32_LSTCU_CORE12_IPG_CLK 335U +#define NXP_S32_LSTCU_CORE3_IPG_CLK 336U +#define NXP_S32_LSTCU_HSPI_IPG_CLK 337U +#define NXP_S32_LSTCU_NETC_IPG_CLK 338U +#define NXP_S32_LSTCU_PBRIDGE1_IPG_CLK 339U +#define NXP_S32_LSTCU_PBRIDGE3_IPG_CLK 340U +#define NXP_S32_LSTCU_PBRIDGE4_IPG_CLK 341U +#define NXP_S32_LSTCU_REST_IPG_CLK 342U +#define NXP_S32_MRAM_IPG_CLK 343U +#define NXP_S32_MRAMC_IPG_CLK 344U +#define NXP_S32_MSCM_IPG_CLK 346U +#define NXP_S32_MSGINTR0_APB_CLK 347U +#define NXP_S32_MSGINTR1_APB_CLK 348U +#define NXP_S32_MSGINTR2_APB_CLK 349U +#define NXP_S32_MSGINTR3_APB_CLK 350U +#define NXP_S32_MSGINTR4_APB_CLK 351U +#define NXP_S32_MSGINTR5_APB_CLK 352U +#define NXP_S32_MSGINTR6_APB_CLK 353U +#define NXP_S32_MSGINTR7_APB_CLK 354U +#define NXP_S32_PERI_HIGH_SPEED_REST_USDHC_CLK 355U +#define NXP_S32_PERI_HIGH_SPEED_REST_XSPI_CLK 356U +#define NXP_S32_PERI_HIGH_SPEED_TRACE_CLK 357U +#define NXP_S32_PHY_ETH_CLK 358U +#define NXP_S32_POST_IPG_CLK 367U +#define NXP_S32_RR_RTC_CLK 368U +#define NXP_S32_RXLUT_ERM_CLK 369U +#define NXP_S32_RXLUT_IPG_CLK 370U +#define NXP_S32_SAI0_IPG_CLK 373U +#define NXP_S32_SAI1_IPG_CLK 375U +#define NXP_S32_SDHC_IPG_CLK 377U +#define NXP_S32_SDHC_PER_CLK 378U +#define NXP_S32_SEMA42_IPG_CLK 379U +#define NXP_S32_SERDES_ALT_REF_CLK 380U +#define NXP_S32_SERDES_AUX_CLK 381U +#define NXP_S32_SERDES_REF_CLK 382U +#define NXP_S32_SINC_IPG_CLK 383U +#define NXP_S32_SOG_REST_CMU_IPG_CLK 384U +#define NXP_S32_SRC_FIRC_CLK 385U +#define NXP_S32_SRC_FIRCDIV2_CLK 386U +#define NXP_S32_SRC_FXOSC_CLK 387U +#define NXP_S32_SRC_LPE_CLK 388U +#define NXP_S32_SRC_LPE_DIV1_CLK 389U +#define NXP_S32_SRC_LPE_DIV2_CLK 390U +#define NXP_S32_SRC_LPE_DIV4_CLK 391U +#define NXP_S32_SRC_LPE_DIV8_CLK 392U +#define NXP_S32_SRC_PLT_CLK 393U +#define NXP_S32_SRC_PLTCORE_CLK 394U +#define NXP_S32_SRC_PLTDIV1_CLK 395U +#define NXP_S32_SRC_PLTDIV2_CLK 396U +#define NXP_S32_SRC_PLTDIV4_CLK 397U +#define NXP_S32_SRC_SIRC_CLK 398U +#define NXP_S32_SRC_SXOSC_CLK 399U +#define NXP_S32_SRAM0_CONTROLLER_IPS_CLK 400U +#define NXP_S32_SRAM1_CONTROLLER_IPS_CLK 401U +#define NXP_S32_SRAM2_CONTROLLER_IPS_CLK 402U +#define NXP_S32_STAM_CLK 403U +#define NXP_S32_STM0_CLK 404U +#define NXP_S32_STM0_IPG_CLK 405U +#define NXP_S32_STM1_CLK 406U +#define NXP_S32_STM1_IPG_CLK 407U +#define NXP_S32_STM2_CLK 408U +#define NXP_S32_STM2_IPG_CLK 409U +#define NXP_S32_STM3_CLK 410U +#define NXP_S32_STM3_IPG_CLK 411U +#define NXP_S32_SWT_STARTUP_IPG_CLK 412U +#define NXP_S32_SWT_STARTUP_IPG_COUNTER_CLK 413U +#define NXP_S32_SWT0_IPG_CLK 414U +#define NXP_S32_SWT0_IPG_COUNTER_CLK 415U +#define NXP_S32_SWT1_IPG_CLK 416U +#define NXP_S32_SWT1_IPG_COUNTER_CLK 417U +#define NXP_S32_SWT2_IPG_CLK 418U +#define NXP_S32_SWT2_IPG_COUNTER_CLK 419U +#define NXP_S32_SWT3_IPG_CLK 420U +#define NXP_S32_SWT3_IPG_COUNTER_CLK 421U +#define NXP_S32_TRACE_CLK 422U +#define NXP_S32_VWRAP0_IPG_CLK 425U +#define NXP_S32_VWRAP1_IPG_CLK 426U +#define NXP_S32_VWRAP2_IPG_CLK 427U +#define NXP_S32_VWRAP3_IPG_CLK 428U +#define NXP_S32_XSPI_IPG_CLK 429U +#define NXP_S32_XSPI_UNGATED_2XSFIF_CLK 430U + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_NXP_S32_S32K566_CLOCK_H_ */ diff --git a/soc/nxp/s32/s32k5/CMakeLists.txt b/soc/nxp/s32/s32k5/CMakeLists.txt index 46fc323e7c78..d357ded30db0 100644 --- a/soc/nxp/s32/s32k5/CMakeLists.txt +++ b/soc/nxp/s32/s32k5/CMakeLists.txt @@ -1,6 +1,8 @@ # Copyright 2025 NXP # SPDX-License-Identifier: Apache-2.0 +zephyr_include_directories(.) + if(CONFIG_SOC_S32K566_M7) add_subdirectory(m7) endif() diff --git a/soc/nxp/s32/s32k5/Kconfig b/soc/nxp/s32/s32k5/Kconfig index 6e838e46d687..1b14dbca1df4 100644 --- a/soc/nxp/s32/s32k5/Kconfig +++ b/soc/nxp/s32/s32k5/Kconfig @@ -6,6 +6,7 @@ config SOC_SERIES_S32K5 select ARM select HAS_NXP_S32_HAL + select HAS_MCUX select CPU_HAS_FPU select CPU_HAS_ARM_MPU select CPU_HAS_ICACHE diff --git a/soc/nxp/s32/s32k5/pinctrl_soc.h b/soc/nxp/s32/s32k5/pinctrl_soc.h new file mode 100644 index 000000000000..0e26e1cdc5c3 --- /dev/null +++ b/soc/nxp/s32/s32k5/pinctrl_soc.h @@ -0,0 +1,67 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_SOC_NXP_S32_S32K5_PINCTRL_SOC_H_ +#define ZEPHYR_SOC_NXP_S32_S32K5_PINCTRL_SOC_H_ + +#include +#include +#include + +/* SIUL2 Multiplexed Signal Configuration */ +#define SIUL2_MSCR_SSS_MASK GENMASK(3, 0) +#define SIUL2_MSCR_SSS(v) FIELD_PREP(SIUL2_MSCR_SSS_MASK, (v)) +#define SIUL2_MSCR_SMC_MASK BIT(5) +#define SIUL2_MSCR_SMC(v) FIELD_PREP(SIUL2_MSCR_SMC_MASK, (v)) +#define SIUL2_MSCR_IFE_MASK BIT(6) +#define SIUL2_MSCR_IFE(v) FIELD_PREP(SIUL2_MSCR_IFE_MASK, (v)) +#define SIUL2_MSCR_DSE_MASK BIT(8) +#define SIUL2_MSCR_DSE(v) FIELD_PREP(SIUL2_MSCR_DSE_MASK, (v)) +#define SIUL2_MSCR_PUE_MASK BIT(10) +#define SIUL2_MSCR_PUE(v) FIELD_PREP(SIUL2_MSCR_PUE_MASK, (v)) +#define SIUL2_MSCR_PUS_MASK BIT(11) +#define SIUL2_MSCR_PUS(v) FIELD_PREP(SIUL2_MSCR_PUS_MASK, (v)) +#define SIUL2_MSCR_SRC_MASK GENMASK(14, 12) +#define SIUL2_MSCR_SRC(v) FIELD_PREP(SIUL2_MSCR_SRC_MASK, (v)) +#define SIUL2_MSCR_PKE_PD1_MASK BIT(15) +#define SIUL2_MSCR_PKE(v) FIELD_PREP(SIUL2_MSCR_PKE_MASK, (v)) +#define SIUL2_MSCR_PKE_PD2_MASK BIT(16) +#define SIUL2_MSCR_PKE(v) FIELD_PREP(SIUL2_MSCR_PKE_MASK, (v)) +#define SIUL2_MSCR_INV_MASK BIT(17) +#define SIUL2_MSCR_INV(v) FIELD_PREP(SIUL2_MSCR_INV_MASK, (v)) +#define SIUL2_MSCR_IBE_MASK BIT(19) +#define SIUL2_MSCR_IBE(v) FIELD_PREP(SIUL2_MSCR_IBE_MASK, (v)) +#define SIUL2_MSCR_OBE_MASK BIT(21) +#define SIUL2_MSCR_OBE(v) FIELD_PREP(SIUL2_MSCR_OBE_MASK, (v)) +#define SIUL2_MSCR_ICE_MASK BIT(22) +#define SIUL2_MSCR_ICE(v) FIELD_PREP(SIUL2_MSCR_ICE_MASK, (v)) +#define SIUL2_MSCR_RCVR_MASK BIT(25) +#define SIUL2_MSCR_RCVR(v) FIELD_PREP(SIUL2_MSCR_RCVR_MASK, (v)) +/* SIUL2 Input Multiplexed Signal Configuration */ +#define SIUL2_IMCR_SSS_MASK GENMASK(3, 0) +#define SIUL2_IMCR_SSS(v) FIELD_PREP(SIUL2_IMCR_SSS_MASK, (v)) + +#define NXP_SIUL2_PINMUX_INIT(group, value) \ + .mscr = { \ + .inst = NXP_SIUL2_PINMUX_GET_MSCR_SIUL2_IDX(value), \ + .idx = NXP_SIUL2_PINMUX_GET_MSCR_IDX(value), \ + .val = SIUL2_MSCR_SSS(NXP_SIUL2_PINMUX_GET_MSCR_SSS(value)) | \ + SIUL2_MSCR_OBE(DT_PROP(group, output_enable)) | \ + SIUL2_MSCR_IBE(DT_PROP(group, input_enable)) | \ + SIUL2_MSCR_PUE(DT_PROP(group, bias_pull_up) || \ + DT_PROP(group, bias_pull_down)) | \ + SIUL2_MSCR_PUS(DT_PROP(group, bias_pull_up)) | \ + SIUL2_MSCR_SRC(DT_ENUM_IDX(group, slew_rate)) | \ + SIUL2_MSCR_DSE(DT_PROP(group, nxp_drive_strength)) | \ + SIUL2_MSCR_INV(DT_PROP(group, nxp_invert)) \ + }, \ + .imcr = { \ + .inst = NXP_SIUL2_PINMUX_GET_IMCR_SIUL2_IDX(value), \ + .idx = NXP_SIUL2_PINMUX_GET_IMCR_IDX(value), \ + .val = SIUL2_IMCR_SSS(NXP_SIUL2_PINMUX_GET_IMCR_SSS(value)), \ + } + +#endif /* ZEPHYR_SOC_NXP_S32_S32K5_PINCTRL_SOC_H_ */ diff --git a/west.yml b/west.yml index 84745a842f89..4bb245f592c3 100644 --- a/west.yml +++ b/west.yml @@ -210,7 +210,7 @@ manifest: groups: - hal - name: hal_nxp - revision: e8a0f68e8d5797ac174580b872df379bdf2f5c4a + revision: e4ab95e7409f2c4e5c7a4f482aa66360433d9f60 path: modules/hal/nxp groups: - hal From b617b92028390e1203be4252291aed491a845d0a Mon Sep 17 00:00:00 2001 From: Ha Duong Quang Date: Mon, 16 Jun 2025 17:07:28 +0700 Subject: [PATCH 0844/3659] boards: nxp: add support for NXP S32K5XXCVB board Add support for NXP S32K5XXCVB boards which features S32K566 SoC. Signed-off-by: Ha Duong Quang Co-authored-by: Dat Nguyen Duy --- boards/nxp/s32k5xxcvb/Kconfig.s32k5xxcvb | 7 + boards/nxp/s32k5xxcvb/board.cmake | 21 ++ boards/nxp/s32k5xxcvb/board.yml | 6 + boards/nxp/s32k5xxcvb/doc/index.rst | 197 ++++++++++++++++++ .../s32k5xxcvb_s32k566-pinctrl.dtsi | 16 ++ boards/nxp/s32k5xxcvb/s32k5xxcvb_s32k566.dtsi | 76 +++++++ .../nxp/s32k5xxcvb/s32k5xxcvb_s32k566_m7.dts | 20 ++ .../nxp/s32k5xxcvb/s32k5xxcvb_s32k566_m7.yaml | 14 ++ .../s32k5xxcvb_s32k566_m7_defconfig | 9 + .../nxp/s32k5xxcvb/s32k5xxcvb_s32k566_r52.dts | 19 ++ .../s32k5xxcvb/s32k5xxcvb_s32k566_r52.yaml | 14 ++ .../s32k5xxcvb_s32k566_r52_defconfig | 8 + boards/nxp/s32k5xxcvb/support/debug.cmm | 13 ++ boards/nxp/s32k5xxcvb/support/flash.cmm | 13 ++ boards/nxp/s32k5xxcvb/support/startup.cmm | 152 ++++++++++++++ 15 files changed, 585 insertions(+) create mode 100644 boards/nxp/s32k5xxcvb/Kconfig.s32k5xxcvb create mode 100644 boards/nxp/s32k5xxcvb/board.cmake create mode 100644 boards/nxp/s32k5xxcvb/board.yml create mode 100644 boards/nxp/s32k5xxcvb/doc/index.rst create mode 100644 boards/nxp/s32k5xxcvb/s32k5xxcvb_s32k566-pinctrl.dtsi create mode 100644 boards/nxp/s32k5xxcvb/s32k5xxcvb_s32k566.dtsi create mode 100644 boards/nxp/s32k5xxcvb/s32k5xxcvb_s32k566_m7.dts create mode 100644 boards/nxp/s32k5xxcvb/s32k5xxcvb_s32k566_m7.yaml create mode 100644 boards/nxp/s32k5xxcvb/s32k5xxcvb_s32k566_m7_defconfig create mode 100644 boards/nxp/s32k5xxcvb/s32k5xxcvb_s32k566_r52.dts create mode 100644 boards/nxp/s32k5xxcvb/s32k5xxcvb_s32k566_r52.yaml create mode 100644 boards/nxp/s32k5xxcvb/s32k5xxcvb_s32k566_r52_defconfig create mode 100644 boards/nxp/s32k5xxcvb/support/debug.cmm create mode 100644 boards/nxp/s32k5xxcvb/support/flash.cmm create mode 100644 boards/nxp/s32k5xxcvb/support/startup.cmm diff --git a/boards/nxp/s32k5xxcvb/Kconfig.s32k5xxcvb b/boards/nxp/s32k5xxcvb/Kconfig.s32k5xxcvb new file mode 100644 index 000000000000..f69fd6331122 --- /dev/null +++ b/boards/nxp/s32k5xxcvb/Kconfig.s32k5xxcvb @@ -0,0 +1,7 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_S32K5XXCVB + select SOC_S32K566_M7 if BOARD_S32K5XXCVB_S32K566_M7 + select SOC_S32K566_R52 if BOARD_S32K5XXCVB_S32K566_R52 + select SOC_PART_NUMBER_S32K566JAMJGS if BOARD_S32K5XXCVB diff --git a/boards/nxp/s32k5xxcvb/board.cmake b/boards/nxp/s32k5xxcvb/board.cmake new file mode 100644 index 000000000000..c16a5f6026cc --- /dev/null +++ b/boards/nxp/s32k5xxcvb/board.cmake @@ -0,0 +1,21 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(trace32 + "--startup-args" + "elfFile=${PROJECT_BINARY_DIR}/${KERNEL_ELF_NAME}" +) + +if(${CONFIG_XIP}) + board_runner_args(trace32 "loadTo=mram") +else() + board_runner_args(trace32 "loadTo=sram") +endif() + +if(${CONFIG_CPU_CORTEX_M7}) + board_runner_args(trace32 "coreType=m7") +else() + board_runner_args(trace32 "coreType=r52") +endif() + +include(${ZEPHYR_BASE}/boards/common/trace32.board.cmake) diff --git a/boards/nxp/s32k5xxcvb/board.yml b/boards/nxp/s32k5xxcvb/board.yml new file mode 100644 index 000000000000..733249f25410 --- /dev/null +++ b/boards/nxp/s32k5xxcvb/board.yml @@ -0,0 +1,6 @@ +board: + name: s32k5xxcvb + full_name: S32K5XXCVB + vendor: nxp + socs: + - name: s32k566 diff --git a/boards/nxp/s32k5xxcvb/doc/index.rst b/boards/nxp/s32k5xxcvb/doc/index.rst new file mode 100644 index 000000000000..fc6a12e4d1ae --- /dev/null +++ b/boards/nxp/s32k5xxcvb/doc/index.rst @@ -0,0 +1,197 @@ +.. zephyr:board:: s32k5xxcvb + +Overview +******** + +The NXP S32K5XXCVB board is based on the `NXP S32K5 Series`_ family of automotive microcontrollers (MCUs), +which expands the S32K3 series to deliver higher performance, larger memory, and increased vehicle network +communication capability, all with lower power consumption. + +The S32K5 MCU features: +- Compute-focused Arm Cortex-R52 cores +- Platform-focused Arm Cortex-M7 cores +- Low-power-focused Arm Cortex-M4 core + +Zephyr OS is ported to run on both the Cortex-M7 and Cortex-R52 cores. + +- ``s32k5xxcvb/s32k566/m7``, for S32K566 Cortex-M7, code executed from code MRAM by default. +- ``s32k5xxcvb/s32k566/r52``, for S32K566 Cortex-R52, code executed from code MRAM by default. + +Hardware +******** + +- NXP S32K566 + - Arm Cortex-M7 (6 cores with two options 3 x Lock-Step or 2 x Lock-Step + 2 x Single-Core, + option 2 is configured by default). + - Arm Cortex-R52 (contains an R52 cluster with two Cortex-R52 cores). + - 1.5 MB SRAM for Cortex-M7, with ECC + - 1 MB of SRAM connected to the Cortex-R52, with ECC + - 32 MB of Code Magnetic RAM for all cores, with ECC + - Ethernet switch integrated, CAN FD/XL, QSPI + - 14-bit 3 Msps ADC, 24-bit eMIOS timer and more. + +Supported Features +================== + +.. zephyr:board-supported-hw:: + +Connections and IOs +=================== + +The Port columns in the Reference Manual (RM) are organized into ports and pins to ensure consistency with +the GPIO driver used in this Zephyr port. + +The table below summarizes the mapping between the Port columns in the RM and Zephyr’s ports and pins. +Please consider this mapping when using the GPIO driver or configuring pin multiplexing for device drivers. + ++-------------------+--------------------+ +| Ports in RM | Zephyr Ports/Pins | ++===================+====================+ +| GPIO0 - GPIO15 | PA0 - PA15 | ++-------------------+--------------------+ +| GPIO16 - GPIO31 | PB0 - PB15 | ++-------------------+--------------------+ +| GPIO32 - GPIO47 | PC0 - PC15 | ++-------------------+--------------------+ +| GPIO48 - GPIO63 | PD0 - PD15 | ++-------------------+--------------------+ +| GPIO64 - GPIO78 | PE0 - PE14 | ++-------------------+--------------------+ +| GPIO80 - GPIO95 | PF0 - PF15 | ++-------------------+--------------------+ +| GPIO96 - GPIO111 | PG0 - PG15 | ++-------------------+--------------------+ +| GPIO112 - GPIO127 | PH0 - PH15 | ++-------------------+--------------------+ +| GPIO128 - GPIO138 | PI0 - PI10 | ++-------------------+--------------------+ +| GPIO160 - GPIO175 | PK0 - PK15 | ++-------------------+--------------------+ +| GPIO176 - GPIO191 | PL0 - PL15 | ++-------------------+--------------------+ +| GPIO192 - GPIO207 | PM0 - PM15 | ++-------------------+--------------------+ +| GPIO208 - GPIO223 | PN0 - PN15 | ++-------------------+--------------------+ +| GPIO224 - GPIO239 | PO0 - PO15 | ++-------------------+--------------------+ +| GPIO240 - GPIO254 | PP0 - PP14 | ++-------------------+--------------------+ +| GPIO256 - GPIO263 | PQ0 - PQ7 | ++-------------------+--------------------+ +| GPIO304 - GPIO319 | PT0 - PT15 | ++-------------------+--------------------+ +| GPIO320 - GPIO335 | PU0 - PU15 | ++-------------------+--------------------+ +| GPIO336 - GPIO351 | PV0 - PV15 | ++-------------------+--------------------+ +| GPIO352 - GPIO363 | PW0 - PW11 | ++-------------------+--------------------+ + +LEDs +---- + +The board has three user RGB LEDs: + +======================= ===== ==== +Devicetree node Color Pin +======================= ===== ==== +led0 / user_led_red Red PP1 +led1 / user_led_green Green PO2 +led2 / user_led_blue Blue PN10 +======================= ===== ==== + +The user can control the LEDs in any way. An output of ``1`` illuminates the LED. + +Buttons +------- + +The board has two user buttons: + +======================= ======= === +Devicetree node Label Pin +======================= ======= === +sw0 / user_button_0 USERSW0 PF3 +sw1 / user_button_1 USERSW1 PF9 +======================= ======= === + +System Clock +============ + +- The Arm Cortex-M7: 200 MHz. +- The Arm Cortex-R52: 800 MHz. + +Set-up the Board +================ + +Connect the external debugger probe to the board's JTAG Cortex ETM connector (``J17``) +and to the host computer via USB or Ethernet, as supported by the probe. + +NXP S32K5XX-MB Shield +===================== + +This Zephyr shield, :ref:`nxp_s32k5xx_mb` expands the board’s available I/O connectivity + +The shield provides access to the following feature: +- Serial UART + +Programming and Debugging +************************* + +.. zephyr:board-supported-runners:: + +Applications for the ``s32k5xxcvb`` board can be built in the usual way as +documented in :ref:`build_an_application`. + +This board supports West runners for the following debug tools: + +- :ref:`Lauterbach TRACE32 ` + +Follow the installation steps of the debug tool you plan to use before loading +your firmware. + +Debugging +========= + +You can build and debug the :zephyr:code-sample:`hello_world` sample for the board +``s32k5xxcvb/s32k566/m7`` with: + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: s32k5xxcvb/s32k566/m7 + :goals: build debug + +Flashing +======== + +Follow these steps if you just want to download the application to the board and run. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: s32k5xxcvb/s32k566/m7 + :goals: build flash + :compact: + +Core selection +============== + +This Zephyr port can only run single core. By default, Zephyr runs on the first core +of the selected board. To execute Zephyr application on other core, all runner parameters +must be overridden from command line: + +.. code-block:: console + + west --startup-args elfFile= coreType= loadTo= core= + +Where ```` is the path to the Zephyr application ELF in the output +directory. + +.. include:: ../../common/board-footer.rst.inc + +References +********** + +.. target-notes:: + +.. _NXP S32K5 Series: + https://www.nxp.com/products/S32K5 diff --git a/boards/nxp/s32k5xxcvb/s32k5xxcvb_s32k566-pinctrl.dtsi b/boards/nxp/s32k5xxcvb/s32k5xxcvb_s32k566-pinctrl.dtsi new file mode 100644 index 000000000000..386373098569 --- /dev/null +++ b/boards/nxp/s32k5xxcvb/s32k5xxcvb_s32k566-pinctrl.dtsi @@ -0,0 +1,16 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&pinctrl { + eirq1_default: eirq1_default { + group1 { + pinmux = , ; + input-enable; + }; + }; +}; diff --git a/boards/nxp/s32k5xxcvb/s32k5xxcvb_s32k566.dtsi b/boards/nxp/s32k5xxcvb/s32k5xxcvb_s32k566.dtsi new file mode 100644 index 000000000000..73322aff0da1 --- /dev/null +++ b/boards/nxp/s32k5xxcvb/s32k5xxcvb_s32k566.dtsi @@ -0,0 +1,76 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "s32k5xxcvb_s32k566-pinctrl.dtsi" + +/ { + aliases { + led0 = &user_led_red; + led1 = &user_led_green; + led2 = &user_led_blue; + sw0 = &user_button_0; + sw1 = &user_button_1; + }; + + leds { + compatible = "gpio-leds"; + + user_led_red: user_led_red { + gpios = <&gpiop 1 GPIO_ACTIVE_HIGH>; + label = "RGBLED0_RED"; + }; + + user_led_green: user_led_green { + gpios = <&gpioo 2 GPIO_ACTIVE_HIGH>; + label = "RGBLED0_GREEN"; + }; + + user_led_blue: user_led_blue { + gpios = <&gpion 10 GPIO_ACTIVE_HIGH>; + label = "RGBLED0_BLUE"; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + + user_button_0: button_0 { + label = "USERSW0"; + gpios = <&gpiof 3 GPIO_ACTIVE_LOW>; + zephyr,code = ; + }; + + user_button_1: button_1 { + label = "USERSW1"; + gpios = <&gpiof 9 GPIO_ACTIVE_LOW>; + zephyr,code = ; + }; + }; +}; + +&gpiof { + status = "okay"; +}; + +&gpion { + status = "okay"; +}; + +&gpioo { + status = "okay"; +}; + +&gpiop { + status = "okay"; +}; + +&eirq1 { + pinctrl-0 = <&eirq1_default>; + pinctrl-names = "default"; + status = "okay"; +}; diff --git a/boards/nxp/s32k5xxcvb/s32k5xxcvb_s32k566_m7.dts b/boards/nxp/s32k5xxcvb/s32k5xxcvb_s32k566_m7.dts new file mode 100644 index 000000000000..41a628258691 --- /dev/null +++ b/boards/nxp/s32k5xxcvb/s32k5xxcvb_s32k566_m7.dts @@ -0,0 +1,20 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include "s32k5xxcvb_s32k566.dtsi" + +/ { + model = "NXP S32K566CVB on Cortex-M7 cores"; + compatible = "nxp,s32k566cvb"; + + chosen { + zephyr,sram = &sram0; + zephyr,flash = &cmram; + }; +}; diff --git a/boards/nxp/s32k5xxcvb/s32k5xxcvb_s32k566_m7.yaml b/boards/nxp/s32k5xxcvb/s32k5xxcvb_s32k566_m7.yaml new file mode 100644 index 000000000000..69eddca6e9bf --- /dev/null +++ b/boards/nxp/s32k5xxcvb/s32k5xxcvb_s32k566_m7.yaml @@ -0,0 +1,14 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +identifier: s32k5xxcvb/s32k566/m7 +name: NXP S32K5XXCVB M7 +type: mcu +arch: arm +ram: 512 +flash: 32768 +toolchain: + - zephyr +supported: + - gpio +vendor: nxp diff --git a/boards/nxp/s32k5xxcvb/s32k5xxcvb_s32k566_m7_defconfig b/boards/nxp/s32k5xxcvb/s32k5xxcvb_s32k566_m7_defconfig new file mode 100644 index 000000000000..d640a2662da5 --- /dev/null +++ b/boards/nxp/s32k5xxcvb/s32k5xxcvb_s32k566_m7_defconfig @@ -0,0 +1,9 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +# Enable MPU +CONFIG_ARM_MPU=y +CONFIG_CLOCK_CONTROL=y + +# Run from Code MRAM +CONFIG_XIP=y diff --git a/boards/nxp/s32k5xxcvb/s32k5xxcvb_s32k566_r52.dts b/boards/nxp/s32k5xxcvb/s32k5xxcvb_s32k566_r52.dts new file mode 100644 index 000000000000..dde0b692455b --- /dev/null +++ b/boards/nxp/s32k5xxcvb/s32k5xxcvb_s32k566_r52.dts @@ -0,0 +1,19 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include "s32k5xxcvb_s32k566.dtsi" + +/ { + model = "NXP S32K566CVB on Cortex-R52 cores"; + compatible = "nxp,s32k566cvb"; + + chosen { + zephyr,sram = &cpe_sram; + zephyr,flash = &cmram; + }; +}; diff --git a/boards/nxp/s32k5xxcvb/s32k5xxcvb_s32k566_r52.yaml b/boards/nxp/s32k5xxcvb/s32k5xxcvb_s32k566_r52.yaml new file mode 100644 index 000000000000..0df9ad33a52e --- /dev/null +++ b/boards/nxp/s32k5xxcvb/s32k5xxcvb_s32k566_r52.yaml @@ -0,0 +1,14 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +identifier: s32k5xxcvb/s32k566/r52 +name: NXP S32K5XXCVB R52 +type: mcu +arch: arm +ram: 1024 +flash: 32768 +toolchain: + - zephyr +supported: + - gpio +vendor: nxp diff --git a/boards/nxp/s32k5xxcvb/s32k5xxcvb_s32k566_r52_defconfig b/boards/nxp/s32k5xxcvb/s32k5xxcvb_s32k566_r52_defconfig new file mode 100644 index 000000000000..39a24d48122c --- /dev/null +++ b/boards/nxp/s32k5xxcvb/s32k5xxcvb_s32k566_r52_defconfig @@ -0,0 +1,8 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_ARM_MPU=y +CONFIG_CLOCK_CONTROL=y + +# Run from Code MRAM +CONFIG_XIP=y diff --git a/boards/nxp/s32k5xxcvb/support/debug.cmm b/boards/nxp/s32k5xxcvb/support/debug.cmm new file mode 100644 index 000000000000..b0f4df774d70 --- /dev/null +++ b/boards/nxp/s32k5xxcvb/support/debug.cmm @@ -0,0 +1,13 @@ +;******************************************************************************* +; Copyright 2025 NXP * +; SPDX-License-Identifier: Apache-2.0 * +; * +; Lauterbach TRACE32 start-up script for debugging s32k5xxcvb * +; * +;******************************************************************************* + +ENTRY %LINE &args + +DO ~~~~/startup.cmm command=debug &args + +ENDDO diff --git a/boards/nxp/s32k5xxcvb/support/flash.cmm b/boards/nxp/s32k5xxcvb/support/flash.cmm new file mode 100644 index 000000000000..0703c172d8bf --- /dev/null +++ b/boards/nxp/s32k5xxcvb/support/flash.cmm @@ -0,0 +1,13 @@ +;******************************************************************************* +; Copyright 2025 NXP * +; SPDX-License-Identifier: Apache-2.0 * +; * +; Lauterbach TRACE32 start-up script for flashing s32k5xxcvb * +; * +;******************************************************************************* + +ENTRY %LINE &args + +DO ~~~~/startup.cmm command=flash &args + +ENDDO diff --git a/boards/nxp/s32k5xxcvb/support/startup.cmm b/boards/nxp/s32k5xxcvb/support/startup.cmm new file mode 100644 index 000000000000..9d115727c6a5 --- /dev/null +++ b/boards/nxp/s32k5xxcvb/support/startup.cmm @@ -0,0 +1,152 @@ +;******************************************************************************* +; Copyright 2025 NXP * +; SPDX-License-Identifier: Apache-2.0 * +; * +; Lauterbach Trace32 start-up script for s32k5xxcvb * +; * +; Parameters: * +; - command operation to execute * +; valid values: flash, debug * +; default: debug * +; - elfFile filepath of ELF to load * +; - coreType type of the application core * +; valid values: m7, r52 * +; - core core index * +; valid values: 0 to 3 * +; default: 0 * +; - loadTo if "mram", the application will be downloaded to SoC * +; MRAM by a flash programming routine; if "sram" it * +; will be downloaded to SoC SRAM. * +; valid values: mram, sram * +; * +;******************************************************************************* + +ENTRY %LINE &args +LOCAL &coreId &cpuName &sramInitTarget + +&command=STRing.SCANAndExtract("&args","command=","debug") +&elfFile=STRing.SCANAndExtract("&args","elfFile=","") +&coreType=STRing.SCANAndExtract("&args","coreType=","") +&core=STRing.SCANAndExtract("&args","core=","0") +&loadTo=STRing.SCANAndExtract("&args","loadTo=","") + +IF ("&elfFile"=="") +( + PRINT %ERROR "Missing ELF file path" + PLIST + STOP + ENDDO +) + +IF ("&coreType"!="m7"&&"&coreType"!="r52") +( + PRINT %ERROR "Invalid core type: &coreType" + PLIST + STOP + ENDDO +) + +IF ("&coreType"=="m7") +( + IF (&core<0||&core>3) + ( + PRINT %ERROR "Invalid core number: &core" + ) + + &cpuName="M7" + &sramInitTarget="CM7" +) +ELSE +( + IF (&core<0||&core>1) + ( + PRINT %ERROR "Invalid core number: &core" + ) + + &cpuName="R52-CPE" + &sramInitTarget="CPE" +) + +; Trace32 indexes are offset by 1 +&coreId=&core+1 + +RESet +SYStem.CPU S32K566-&cpuName +CORE.ASSIGN &coreId +SYStem.CONFIG.DEBUGPORTTYPE SWD +SYStem.MemAccess DAP +SYStem.JtagClock 10MHz +Trace.DISable +SYStem.Mode.Prepare + +DO ~~/demo/arm/hardware/s32k5/misc/s32k5_init_sram.cmm &sramInitTarget + +IF ("&loadTo"=="mram") +( + Data.LOAD.Elf &elfFile /NoCODE + &image_start = ADDRESS.OFFSET(__rom_region_start) + &image_end = ADDRESS.OFFSET(__rom_region_start)+ADDRESS.OFFSET(_flash_used) + + ; Ensure 4-bit alignment at the end + &image_end=&image_end|0xF + + ; Create image and add IVT header, if not part of the ELF file + Data.Set VM:0x08000000..0x080000FF %Long 0x0 + Data.Set VM:0x08000000 %Long 0x710001D1 ; Magic number + Data.Set VM:0x08000004 %Long 0x031E0000 ; Boot configuration word (enable all M7 and R52) + IF ("&coreType"=="m7") + ( + Data.Set VM:0x08000040+(&core*4) %Long ADDRESS.OFFSET(_vector_start) + ) + ELSE + ( + Data.Set VM:0x08000060+(&core*4) %Long ADDRESS.OFFSET(_vector_start) + ) + + Data.Set VM:&image_start..&image_end %Long 0x0 + + Data.LOAD.Elf &elfFile /VM /NosYmbol + + ; Only declares flash, does not execute flash programming + DO ~~/demo/arm/flash/s32k5.cmm PREPAREONLY + FLASH.Program ALL + + ; Create image and add IVT header + Data.COPY VM:0x08000000..0x080000FF EAXI:0x08000000 /Quad + Data.COPY VM:&image_start..&image_end EAXI:&image_start /Quad + + FLASH.Program OFF + + ; Reset the processor + SYStem.Up + IF ("&coreType"=="r52") + ( + ; CPE.GPR Thumb bit is enabled after reset + R.S T 0 + ) +) +ELSE +( + Data.LOAD.Elf &elfFile +) + +IF ("&command"=="flash") +( + ; Execute the application and quit + Go + QUIT +) +ELSE +( + ; Setup minimal debug environment + WinCLEAR + SETUP.Var.%SpotLight + WinPOS 0. 0. 120. 30. + List.auto + WinPOS 125. 0. 80. 10. + Frame.view + WinPOS 125. 18. + Register.view /SpotLight +) + +ENDDO From fde41e87929a65fb69eb7bad4387370649d27a9c Mon Sep 17 00:00:00 2001 From: Dat Nguyen Duy Date: Thu, 6 Nov 2025 09:30:01 +0700 Subject: [PATCH 0845/3659] boards: shields: introduce a shield for s32k5xx mother board There is no USB port or headers for lpuart on the cvb board, thus introducing a shield for the mother board in order to visualize serial output and expand I/O connectivity: Signed-off-by: Dat Nguyen Duy --- boards/shields/nxp_s32k5xx_mb/Kconfig.shield | 5 + boards/shields/nxp_s32k5xx_mb/doc/index.rst | 146 ++++++++++++++++++ .../nxp_s32k5xx_mb/nxp_s32k5xx_mb.conf | 6 + .../nxp_s32k5xx_mb/nxp_s32k5xx_mb.overlay | 21 +++ .../nxp_s32k5xx_mb_pinctrl.dtsi | 21 +++ boards/shields/nxp_s32k5xx_mb/shield.yml | 6 + 6 files changed, 205 insertions(+) create mode 100644 boards/shields/nxp_s32k5xx_mb/Kconfig.shield create mode 100644 boards/shields/nxp_s32k5xx_mb/doc/index.rst create mode 100644 boards/shields/nxp_s32k5xx_mb/nxp_s32k5xx_mb.conf create mode 100644 boards/shields/nxp_s32k5xx_mb/nxp_s32k5xx_mb.overlay create mode 100644 boards/shields/nxp_s32k5xx_mb/nxp_s32k5xx_mb_pinctrl.dtsi create mode 100644 boards/shields/nxp_s32k5xx_mb/shield.yml diff --git a/boards/shields/nxp_s32k5xx_mb/Kconfig.shield b/boards/shields/nxp_s32k5xx_mb/Kconfig.shield new file mode 100644 index 000000000000..b25dd7a135b3 --- /dev/null +++ b/boards/shields/nxp_s32k5xx_mb/Kconfig.shield @@ -0,0 +1,5 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +config SHIELD_NXP_S32K5XX_MB + def_bool $(shields_list_contains,nxp_s32k5xx_mb) diff --git a/boards/shields/nxp_s32k5xx_mb/doc/index.rst b/boards/shields/nxp_s32k5xx_mb/doc/index.rst new file mode 100644 index 000000000000..fcca15fed44d --- /dev/null +++ b/boards/shields/nxp_s32k5xx_mb/doc/index.rst @@ -0,0 +1,146 @@ +.. _nxp_s32k5xx_mb: + +NXP S32K5XX-MB Shield +##################### + +Overview +******** + +This Zephyr shield (NXP S32K5XX motherboard) increases the I/O connectivity available to the for :zephyr:board:`s32k5xxcvb` board. + +GPIO Pin Matrix +*************** + +Refer to the table below for the mapping between the Jxxx symbols in the schematic and the GPIO pin matrix in the board layout. + ++----+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+ +| | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | ++====+=======+=======+=======+=======+=======+=======+=======+=======+=======+=======+ +| A | | | | | | | J207 | J173 | J139 | J447 | ++----+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+ +| B | | | | | | | J208 | J174 | J140 | J105 | ++----+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+ +| C | J404 | J370 | J338 | J305 | J273 | J241 | J209 | J175 | J141 | J106 | ++----+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+ +| D | J405 | J371 | J339 | J306 | J274 | J242 | J210 | J176 | J142 | J107 | ++----+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+ +| E | J406 | J372 | J340 | J307 | J275 | J243 | J211 | J177 | J143 | J108 | ++----+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+ +| F | J407 | J373 | J341 | J308 | J276 | J244 | J212 | J178 | J144 | J109 | ++----+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+ +| G | J408 | J374 | J342 | J309 | J277 | J245 | J213 | J179 | J145 | J110 | ++----+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+ +| H | J409 | J375 | J343 | J310 | J278 | J246 | J214 | J180 | J146 | J111 | ++----+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+ +| I | J410 | J376 | J344 | J311 | J279 | J247 | J215 | J181 | J147 | J112 | ++----+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+ +| J | J411 | J377 | J345 | J312 | J280 | J248 | J216 | J182 | J148 | J113 | ++----+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+ +| K | J412 | J378 | J346 | J313 | J281 | J249 | J217 | J183 | J149 | J114 | ++----+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+ +| L | J413 | J379 | J347 | J314 | J282 | J250 | J218 | J184 | J150 | J115 | ++----+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+ +| M | J414 | J380 | J348 | J315 | J283 | J251 | J219 | J185 | J151 | J116 | ++----+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+ +| N | J415 | J381 | J349 | J316 | J284 | J252 | J220 | J186 | J152 | J117 | ++----+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+ +| O | J416 | J382 | J350 | J317 | J285 | J253 | J221 | J187 | J153 | J118 | ++----+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+ +| P | J417 | J383 | J351 | J318 | J286 | J254 | J222 | J188 | J154 | J119 | ++----+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+ +| Q | J418 | J384 | J352 | J319 | J287 | J255 | J223 | J189 | J155 | J120 | ++----+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+ +| R | J419 | J385 | J353 | J320 | J288 | J256 | J224 | J190 | J156 | J121 | ++----+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+ +| S | J420 | J386 | J354 | J321 | J289 | J257 | J225 | J191 | J157 | J122 | ++----+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+ +| T | J421 | J387 | J355 | J322 | J290 | J258 | J226 | J192 | J158 | J123 | ++----+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+ +| U | J422 | J388 | J356 | J323 | J291 | J259 | J227 | J193 | J159 | J124 | ++----+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+ +| V | J423 | J389 | J357 | J324 | J292 | J260 | J228 | J194 | J160 | J125 | ++----+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+ +| W | J424 | J390 | J358 | J325 | J293 | J261 | J229 | J195 | J161 | J126 | ++----+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+ +| X | J425 | J391 | J359 | J326 | J294 | J262 | J230 | J196 | J162 | J127 | ++----+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+ +| Y | J426 | J392 | J360 | J327 | J295 | J263 | J231 | J197 | J163 | J128 | ++----+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+ +| Z | J427 | J393 | J361 | J328 | J296 | J264 | J232 | J198 | J164 | J129 | ++----+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+ +| AA | J428 | J394 | J362 | J329 | J297 | J265 | J233 | J199 | J165 | J130 | ++----+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+ +| AB | J429 | J395 | J363 | J330 | J298 | J266 | J234 | J200 | J166 | J131 | ++----+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+ +| AC | J430 | J396 | J364 | J331 | J299 | J267 | J235 | J201 | J167 | J132 | ++----+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+ +| AD | J431 | J397 | J365 | J332 | J300 | J268 | J236 | J202 | J168 | J133 | ++----+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+ +| AE | J432 | J398 | J366 | J333 | J301 | J269 | J237 | J203 | J169 | J134 | ++----+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+ +| AF | J433 | J399 | J367 | J334 | J302 | J270 | J238 | J204 | J170 | J135 | ++----+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+ +| AG | J434 | J400 | J368 | J335 | J303 | J271 | J239 | J205 | J171 | J136 | ++----+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+ +| AH | J435 | J401 | J369 | J336 | J304 | J272 | J240 | J206 | J172 | J137 | ++----+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+ +| AI | J437 | J438 | J439 | J440 | J441 | J442 | J443 | J444 | J445 | J446 | ++----+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+ + +Set-up the Board +================ + +First, make sure the motherboard is properly connected to :zephyr:board:`s32k5xxcvb` board. + +A USB to serial converter (e.g., CH340) is required to visualize the serial output, connect it to the board as shown below: + + ++---------------------+------------------+ +| CH340 Converter Pin | GPIO Pin Matrix | ++=====================+==================+ +| TXD | O5 | ++---------------------+------------------+ +| RXD | P5 | ++---------------------+------------------+ +| GND | AI10 | ++---------------------+------------------+ + + +Run your favorite terminal program to listen for output. For example, using the cross-platform `pySerial miniterm`_ terminal: + +.. code-block:: console + + python -m serial.tools.miniterm 115200 + +Replace ```` with the port where the board can be found. For example, +under Linux, ``/dev/ttyUSB0``. + +Programming +*********** + +Below are the supported shields to be used with ``--shield

    ^cE-8UVNNk5`oSfZ`Tws#_F){qK+(J2JOtjV<{h z`vS=|yI1Rkk{5b*4ZoX2#;T+UP|>8R%h(+rz}~BE>dHwp+QPh@t0&QyjZ~5P3;a-I z{C0YZZYdnu2Y&)Pd~-+d%zI*C--_ytIe|zv)P>Ch7O$t3+s|tXsbsUphSkj6V;O6L z!ps0KBr>nv^mZwq#nFL353h*^rb_S^!}dfk@B^81R~q_nR<=n*u3t_$5x}2E;%RHV%cFeUdALJQPC@1U!oSl6tlhw5RAYn$ z_Hq4!{w;;A?8$P zRhfPx8fLl!KXoi(ZyC#T-SV3v3DZEBZPqOm*d-sNb;+PlTe?Ka8Q*bC-hD(wn(iSfWKoGr2%B=ZV z!L`VCO_^?j=`;UXdhC9o+vZAuV*AEVQTV_=tENk~a16^Kug zp<=t|v!+hck4XSq)WT|%@6rfC(en*r8Z6(3fv8O;DwoQQ+iw+eB$dDq; zQ8<@Hr&`lD&?NjKFCN$2L32yi5XFCTpo@-?!8h6-x$AY`Hyqwb|J z@^}!O3Eg;D#kW(p6#wJ>T8u~2Ldj4A(0Y9R6DJKSu|Szq zoRnIdOMRY6%}?^dBU|5MC9NQ@;ZXrEI)uU~1!*XX9Zppy68gW69@4X^@F)|8)UW=P z>OzGI7{=0uZ%!c~r1u5o?Z&W) zzYPL`y((6Fc*I{yG`~5pIf4&yA3ONJ?&>>1!^8l2+u3;Qw?&}e`@~O1wYjvV`yEkq z?|~Yh23&#OaeRC%Sogk30y2haYEO9Q1ds@5?vy93{2^qEfe;`gp_`wNOMSn zfCiV{>N(K4hR``&fXn77w?L8$rU^JC)kfm>R5_O z-5RkH;G0eb>2J6XeQB6Wq7Ga?CN7Ub3%TuC$MmAyTTB3*f)_?abdZ`jB5v-2rTKZx zug!jr<~5;+{(DLozzBMqf6Z!#z9JIw&f3552{QyK*Q|~gKHa*zx9Vt{RYKi>$YwLB zak<(g{w||*YLIA37VH~_$cnXYdqwmj&cbc*Q!ffx*f(w>E3jxPFhz=xWYjvh0IX}>mXm0SSFf6wVdFoVC@mKu04$kPG^9FojL0P-(l$1emuoubn)LbKRjWp zNxp6x^U6MQf7VGY0jb;4$Yx#Bv;aCZ;0k<-dIY zPe;&Q>z++Xt|EHJU2tLF;NbOL8NR5077?7-sB7>i+~99%$`@zIO+CA06RFlIl_Vm? zRRc1p4!=t=N$k1XJFLaLF}fvBPnQ+zBFlfkX1^s;w1Zmi`IS(?_~3y*azkdtD??g< zJp-vqfezS55nv-(^>%@z4>Hb-=Z_)l_Xfe!jrQ1g18=0=aK-uC+i?ViEL!saG!dl_ zAVSUn{@YJ3Ia30{WFGzABT)Y~f}Mx3#q|ncCbrIrnl&c}65Kg2X(-N}fO*~1zwl|$ z0eNV^n6ufeJQibpPg~E5+`2z!gXMiexRVTguMq{9f*d_lGXm#T#UViM&kZX@Y4Cx! z0u;xjr>&uFaN2SEh-Gzv2`*O16s?U8(VY$IQa;@mgYda+QldDg;wnxdTTb{am@?sE>k1KQhVR)IcCiEmvM^;l=l< fatload mmc 0:1 0x40000000 /boot/zephyr.bin + => go 0x40000000 + +You should see the following output on the serial console: + +.. code-block:: text + + *** Booting Zephyr OS vx.x.x-xxx-gxxxxxxxxxxxx *** + Hello World! opi_zero/sun8i_h3 + +.. _Orange Pi Zero: + http://www.orangepi.org/orangepiwiki/index.php/Orange_Pi_Zero/ + +.. _Das U-Boot Website: + https://docs.u-boot.org/en/latest/ + +.. _Using U-Boot With Allwinner SoCs: + https://docs.u-boot.org/en/stable/board/allwinner/sunxi.html diff --git a/boards/xunlong/opi_zero/opi_zero.dts b/boards/xunlong/opi_zero/opi_zero.dts new file mode 100644 index 000000000000..4ee120c25132 --- /dev/null +++ b/boards/xunlong/opi_zero/opi_zero.dts @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2025 Muhammad Waleed Badar + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include + +/ { + model = "Xunlong Orange Pi Zero"; + compatible = "xunlong,orangepi-zero", "allwinner,sun8i-h2-plus"; + #address-cells = <1>; + #size-cells = <1>; + + chosen { + zephyr,console = &uart0; + zephyr,shell-uart = &uart0; + zephyr,sram = &dram0; + }; + + dram0: memory@40000000 { + device_type = "memory"; + compatible = "mmio-sram"; + reg = <0x40000000 DT_SIZE_M(512)>; + }; +}; + +&cpu0 { + clock-frequency = ; +}; + +&uart0 { + status = "okay"; + current-speed = <115200>; +}; diff --git a/boards/xunlong/opi_zero/opi_zero.yaml b/boards/xunlong/opi_zero/opi_zero.yaml new file mode 100644 index 000000000000..12aacb576e4a --- /dev/null +++ b/boards/xunlong/opi_zero/opi_zero.yaml @@ -0,0 +1,10 @@ +# Copyright (c) 2025 Muhammad Waleed Badar +# SPDX-License-Identifier: Apache-2.0 + +identifier: opi_zero +name: Xunlong Orange Pi Zero +type: mcu +arch: arm +toolchain: + - zephyr +vendor: xunlong diff --git a/boards/xunlong/opi_zero/opi_zero_defconfig b/boards/xunlong/opi_zero/opi_zero_defconfig new file mode 100644 index 000000000000..a06b11a61969 --- /dev/null +++ b/boards/xunlong/opi_zero/opi_zero_defconfig @@ -0,0 +1,9 @@ +# Copyright (c) 2025 Muhammad Waleed Badar +# SPDX-License-Identifier: Apache-2.0 + +# Serial Drivers +CONFIG_SERIAL=y + +# Enable Console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y From 552004f3d1518d2dae5bc76caa45ea8a2b349ce8 Mon Sep 17 00:00:00 2001 From: Zhaoxiang Jin Date: Tue, 6 Jan 2026 13:57:43 +0800 Subject: [PATCH 1399/3659] boards: nxp: frdm_mcxn236: enable ostimer in dts The MCXN236 can use ostimer as the kernel timer. We enable it in the dts, and which specific timer to use as the system timer can be controlled through Kconfig option based on application requirements. Signed-off-by: Zhaoxiang Jin --- boards/nxp/frdm_mcxn236/frdm_mcxn236.dts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/boards/nxp/frdm_mcxn236/frdm_mcxn236.dts b/boards/nxp/frdm_mcxn236/frdm_mcxn236.dts index 971182e4b8cf..b5e83a71fb5a 100644 --- a/boards/nxp/frdm_mcxn236/frdm_mcxn236.dts +++ b/boards/nxp/frdm_mcxn236/frdm_mcxn236.dts @@ -340,13 +340,13 @@ nxp_8080_touch_panel_i2c: &flexcomm2_lpi2c2 { clock-frequency = ; }; -/* - * MCXN236 board uses OS timer as the kernel timer - * In case we need to switch to SYSTICK timer, then - * replace &os_timer with &systick +/* The MCXN236 can use ostimer as the kernel timer. + * We enable it in the dts, and which specific timer + * to use as the system timer can be controlled through + * Kconfig option based on application requirements. */ &os_timer { - status = "disabled"; + status = "okay"; }; &systick { From 790598e642dcf6febe73be6ed9f001aa427436ba Mon Sep 17 00:00:00 2001 From: Zhaoxiang Jin Date: Wed, 7 Jan 2026 17:22:13 +0800 Subject: [PATCH 1400/3659] soc: nxp: mcxn: Remove redundant code MCUX_LPTMR_TIMER is default to n, no need to set it again. Signed-off-by: Zhaoxiang Jin --- soc/nxp/mcx/mcxn/Kconfig.defconfig | 3 --- 1 file changed, 3 deletions(-) diff --git a/soc/nxp/mcx/mcxn/Kconfig.defconfig b/soc/nxp/mcx/mcxn/Kconfig.defconfig index d910f2f73a46..869b0886e254 100644 --- a/soc/nxp/mcx/mcxn/Kconfig.defconfig +++ b/soc/nxp/mcx/mcxn/Kconfig.defconfig @@ -16,9 +16,6 @@ config ROM_START_OFFSET default 0x400 if BOOTLOADER_MCUBOOT default 0x1000 if !BOOTLOADER_MCUBOOT && FLASH_MCUX_FLEXSPI_XIP -config MCUX_LPTMR_TIMER - default n if (DT_HAS_NXP_OS_TIMER_ENABLED || DT_HAS_ARM_ARMV8M_SYSTICK_ENABLED) - config SYS_CLOCK_HW_CYCLES_PER_SEC default 1000000 if MCUX_OS_TIMER default 16000 if MCUX_LPTMR_TIMER From 732adf7865bd3ccb88db29ad0e12fb429d09127b Mon Sep 17 00:00:00 2001 From: Zhaoxiang Jin Date: Wed, 7 Jan 2026 17:24:30 +0800 Subject: [PATCH 1401/3659] soc: nxp: mcxn: Add OSTIMER support and refine system timer selection Add MCUX_OS_TIMER configuration with CPU_FREQ-based default selection. Update CORTEX_M_SYSTICK to be disabled when either LPTMR or OSTIMER is selected as the system timer, ensuring only one timer is active. Signed-off-by: Zhaoxiang Jin --- soc/nxp/mcx/mcxn/Kconfig.defconfig | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/soc/nxp/mcx/mcxn/Kconfig.defconfig b/soc/nxp/mcx/mcxn/Kconfig.defconfig index 869b0886e254..e7ec02df805a 100644 --- a/soc/nxp/mcx/mcxn/Kconfig.defconfig +++ b/soc/nxp/mcx/mcxn/Kconfig.defconfig @@ -3,8 +3,14 @@ if SOC_FAMILY_MCXN -config CORTEX_M_SYSTICK - default n if MCUX_LPTMR_TIMER +# Ensure SysTick is not enabled by default if another system timer is selected. +configdefault CORTEX_M_SYSTICK + default n if (MCUX_LPTMR_TIMER || MCUX_OS_TIMER) + +# We override it here so CPU_FREQ controls whether OSTIMER is selected by default. +configdefault MCUX_OS_TIMER + default y if CPU_FREQ + default n config MFD default y if DT_HAS_NXP_LP_FLEXCOMM_ENABLED From 27fdf9863814ed9d0c94062032cc4428d00f18b1 Mon Sep 17 00:00:00 2001 From: Wilfried Chauveau Date: Thu, 11 Dec 2025 23:29:11 +0000 Subject: [PATCH 1402/3659] cmake: package_helper: Remove an empty elseif Cmake complains about this. Signed-off-by: Wilfried Chauveau --- cmake/package_helper.cmake | 1 - 1 file changed, 1 deletion(-) diff --git a/cmake/package_helper.cmake b/cmake/package_helper.cmake index 886dbfff71dd..450befcf1813 100644 --- a/cmake/package_helper.cmake +++ b/cmake/package_helper.cmake @@ -49,7 +49,6 @@ foreach(i RANGE ${CMAKE_ARGC}) if(CMAKE_ARGV${i} MATCHES "^-B(.*)") set(argB ${CMAKE_MATCH_1}) set(argB_index ${i}) - elseif() elseif(CMAKE_ARGV${i} MATCHES "^-S(.*)") set(argS_index ${i}) set(argS ${CMAKE_MATCH_1}) From 2d5b720b62071cc933b1b54edf3a0ac0a6bbe0c8 Mon Sep 17 00:00:00 2001 From: Khai Cao Date: Thu, 8 Jan 2026 01:04:41 +0000 Subject: [PATCH 1403/3659] drivers: can: Fix macro typo in CAN_RENESAS_RA_INIT MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix macro parameter typo (##inst → ##index) in CAN_RENESAS_RA_INIT to ensure unique IRQ configure function names per instance. Signed-off-by: Khai Cao --- drivers/can/can_renesas_ra.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/can/can_renesas_ra.c b/drivers/can/can_renesas_ra.c index 8d487e5cb485..7906dc01858d 100644 --- a/drivers/can/can_renesas_ra.c +++ b/drivers/can/can_renesas_ra.c @@ -1098,7 +1098,7 @@ DT_FOREACH_STATUS_OKAY(renesas_ra_canfd_global, CAN_RENESAS_RA_GLOBAL_DEFINE) static canfd_afl_entry_t canfd_afl##index[DT_INST_PROP(index, rx_max_filters)]; \ struct can_renesas_ra_filter \ can_renesas_ra_rx_filter##index[DT_INST_PROP(index, rx_max_filters)]; \ - static void can_renesas_ra_irq_configure##inst(void) \ + static void can_renesas_ra_irq_configure##index(void) \ { \ R_ICU->IELSR_b[DT_INST_IRQ_BY_NAME(index, rx, irq)].IELS = \ EVENT_CAN_COMFRX(DT_INST_PROP(index, channel)); \ @@ -1135,7 +1135,7 @@ DT_FOREACH_STATUS_OKAY(renesas_ra_canfd_global, CAN_RENESAS_RA_GLOBAL_DEFINE) .stop_bit = DT_INST_CLOCKS_CELL_BY_NAME(index, dllclk, stop_bit), \ }, \ .rx_filter_num = DT_INST_PROP(index, rx_max_filters), \ - .irq_configure = can_renesas_ra_irq_configure##inst, \ + .irq_configure = can_renesas_ra_irq_configure##index, \ }; \ static struct can_renesas_ra_data can_renesas_ra_data##index = { \ .fsp_can = \ From 8b310cf8247d043c9e73dbebbffccc5cd74dbdc1 Mon Sep 17 00:00:00 2001 From: Amneesh Singh Date: Mon, 22 Dec 2025 12:35:47 +0530 Subject: [PATCH 1404/3659] drivers: intc: vim: fix header macros BIT_MASK(32) cannot do (1 << 32) - 1 without causing integer overflow. Hence, for these macros BIT64_MASK(32) is required. Additionally, remove the unnecessary (and presently unused) macros for the register space. All of these can be reliably derived from the present register masks. Signed-off-by: Amneesh Singh --- .../drivers/interrupt_controller/intc_vim.h | 176 +----------------- 1 file changed, 10 insertions(+), 166 deletions(-) diff --git a/include/zephyr/drivers/interrupt_controller/intc_vim.h b/include/zephyr/drivers/interrupt_controller/intc_vim.h index c177943b2c8a..22e1f0e84b58 100644 --- a/include/zephyr/drivers/interrupt_controller/intc_vim.h +++ b/include/zephyr/drivers/interrupt_controller/intc_vim.h @@ -47,236 +47,80 @@ #define VIM_VEC_INT(n) (VIM_BASE_ADDR + (0x2000) + ((n) * 0x4)) /* RAW */ - -#define VIM_GRP_RAW_STS_MASK (BIT_MASK(32)) -#define VIM_GRP_RAW_STS_SHIFT (0x00000000U) -#define VIM_GRP_RAW_STS_RESETVAL (0x00000000U) -#define VIM_GRP_RAW_STS_MAX (BIT_MASK(32)) - -#define VIM_GRP_RAW_RESETVAL (0x00000000U) +#define VIM_GRP_RAW_STS_MASK (BIT64_MASK(32)) /* STS */ - -#define VIM_GRP_STS_MSK_MASK (BIT_MASK(32)) -#define VIM_GRP_STS_MSK_SHIFT (0x00000000U) -#define VIM_GRP_STS_MSK_RESETVAL (0x00000000U) -#define VIM_GRP_STS_MSK_MAX (BIT_MASK(32)) - -#define VIM_GRP_STS_RESETVAL (0x00000000U) +#define VIM_GRP_STS_MSK_MASK (BIT64_MASK(32)) /* INTR_EN_SET */ - -#define VIM_GRP_INTR_EN_SET_MSK_MASK (BIT_MASK(32)) -#define VIM_GRP_INTR_EN_SET_MSK_SHIFT (0x00000000U) -#define VIM_GRP_INTR_EN_SET_MSK_RESETVAL (0x00000000U) -#define VIM_GRP_INTR_EN_SET_MSK_MAX (BIT_MASK(32)) - -#define VIM_GRP_INTR_EN_SET_RESETVAL (0x00000000U) +#define VIM_GRP_INTR_EN_SET_MSK_MASK (BIT64_MASK(32)) /* INTR_EN_CLR */ - -#define VIM_GRP_INTR_EN_CLR_MSK_MASK (BIT_MASK(32)) -#define VIM_GRP_INTR_EN_CLR_MSK_SHIFT (0x00000000U) -#define VIM_GRP_INTR_EN_CLR_MSK_RESETVAL (0x00000000U) -#define VIM_GRP_INTR_EN_CLR_MSK_MAX (BIT_MASK(32)) - -#define VIM_GRP_INTR_EN_CLR_RESETVAL (0x00000000U) +#define VIM_GRP_INTR_EN_CLR_MSK_MASK (BIT64_MASK(32)) /* IRQSTS */ - -#define VIM_GRP_IRQSTS_MSK_MASK (BIT_MASK(32)) -#define VIM_GRP_IRQSTS_MSK_SHIFT (0x00000000U) -#define VIM_GRP_IRQSTS_MSK_RESETVAL (0x00000000U) -#define VIM_GRP_IRQSTS_MSK_MAX (BIT_MASK(32)) - -#define VIM_GRP_IRQSTS_RESETVAL (0x00000000U) +#define VIM_GRP_IRQSTS_MSK_MASK (BIT64_MASK(32)) /* FIQSTS */ - -#define VIM_GRP_FIQSTS_MSK_MASK (BIT_MASK(32)) -#define VIM_GRP_FIQSTS_MSK_SHIFT (0x00000000U) -#define VIM_GRP_FIQSTS_MSK_RESETVAL (0x00000000U) -#define VIM_GRP_FIQSTS_MSK_MAX (BIT_MASK(32)) - -#define VIM_GRP_FIQSTS_RESETVAL (0x00000000U) +#define VIM_GRP_FIQSTS_MSK_MASK (BIT64_MASK(32)) /* INTMAP */ - -#define VIM_GRP_INTMAP_MSK_MASK (BIT_MASK(32)) -#define VIM_GRP_INTMAP_MSK_SHIFT (0x00000000U) -#define VIM_GRP_INTMAP_MSK_RESETVAL (0x00000000U) -#define VIM_GRP_INTMAP_MSK_MAX (BIT_MASK(32)) - -#define VIM_GRP_INTMAP_RESETVAL (0x00000000U) +#define VIM_GRP_INTMAP_MSK_MASK (BIT64_MASK(32)) /* INTTYPE */ - -#define VIM_GRP_INTTYPE_MSK_MASK (BIT_MASK(32)) -#define VIM_GRP_INTTYPE_MSK_SHIFT (0x00000000U) -#define VIM_GRP_INTTYPE_MSK_RESETVAL (0x00000000U) -#define VIM_GRP_INTTYPE_MSK_MAX (BIT_MASK(32)) - -#define VIM_GRP_INTTYPE_RESETVAL (0x00000000U) +#define VIM_GRP_INTTYPE_MSK_MASK (BIT64_MASK(32)) /* INT */ - #define VIM_PRI_INT_VAL_MASK (BIT_MASK(4)) -#define VIM_PRI_INT_VAL_SHIFT (0x00000000U) -#define VIM_PRI_INT_VAL_RESETVAL (BIT_MASK(4)) -#define VIM_PRI_INT_VAL_MAX (BIT_MASK(4)) - -#define VIM_PRI_INT_RESETVAL (BIT_MASK(4)) /* INT */ - #define VIM_VEC_INT_VAL_MASK (0xFFFFFFFCU) -#define VIM_VEC_INT_VAL_SHIFT (0x00000002U) -#define VIM_VEC_INT_VAL_RESETVAL (0x00000000U) -#define VIM_VEC_INT_VAL_MAX (BIT_MASK(30)) - -#define VIM_VEC_INT_RESETVAL (0x00000000U) /* INFO */ - #define VIM_INFO_INTERRUPTS_MASK (BIT_MASK(11)) -#define VIM_INFO_INTERRUPTS_SHIFT (0x00000000U) -#define VIM_INFO_INTERRUPTS_RESETVAL (0x00000400U) -#define VIM_INFO_INTERRUPTS_MAX (BIT_MASK(11)) - -#define VIM_INFO_RESETVAL (0x00000400U) /* PRIIRQ */ - #define VIM_PRIIRQ_VALID_MASK (0x80000000U) -#define VIM_PRIIRQ_VALID_SHIFT (BIT_MASK(5)) -#define VIM_PRIIRQ_VALID_RESETVAL (0x00000000U) -#define VIM_PRIIRQ_VALID_MAX (0x00000001U) - #define VIM_PRIIRQ_VALID_VAL_TRUE (0x1U) #define VIM_PRIIRQ_VALID_VAL_FALSE (0x0U) - #define VIM_PRIIRQ_PRI_MASK (0x000F0000U) -#define VIM_PRIIRQ_PRI_SHIFT (0x00000010U) -#define VIM_PRIIRQ_PRI_RESETVAL (0x00000000U) -#define VIM_PRIIRQ_PRI_MAX (BIT_MASK(4)) - #define VIM_PRIIRQ_NUM_MASK (BIT_MASK(10)) -#define VIM_PRIIRQ_NUM_SHIFT (0x00000000U) -#define VIM_PRIIRQ_NUM_RESETVAL (0x00000000U) -#define VIM_PRIIRQ_NUM_MAX (BIT_MASK(10)) - -#define VIM_PRIIRQ_RESETVAL (0x00000000U) /* PRIFIQ */ - #define VIM_PRIFIQ_VALID_MASK (0x80000000U) -#define VIM_PRIFIQ_VALID_SHIFT (BIT_MASK(5)) -#define VIM_PRIFIQ_VALID_RESETVAL (0x00000000U) -#define VIM_PRIFIQ_VALID_MAX (0x00000001U) - #define VIM_PRIFIQ_VALID_VAL_TRUE (0x1U) #define VIM_PRIFIQ_VALID_VAL_FALSE (0x0U) - #define VIM_PRIFIQ_PRI_MASK (0x000F0000U) -#define VIM_PRIFIQ_PRI_SHIFT (0x00000010U) -#define VIM_PRIFIQ_PRI_RESETVAL (0x00000000U) -#define VIM_PRIFIQ_PRI_MAX (BIT_MASK(4)) - #define VIM_PRIFIQ_NUM_MASK (BIT_MASK(10)) -#define VIM_PRIFIQ_NUM_SHIFT (0x00000000U) -#define VIM_PRIFIQ_NUM_RESETVAL (0x00000000U) -#define VIM_PRIFIQ_NUM_MAX (BIT_MASK(10)) - -#define VIM_PRIFIQ_RESETVAL (0x00000000U) /* IRQGSTS */ - -#define VIM_IRQGSTS_STS_MASK (BIT_MASK(32)) -#define VIM_IRQGSTS_STS_SHIFT (0x00000000U) -#define VIM_IRQGSTS_STS_RESETVAL (0x00000000U) -#define VIM_IRQGSTS_STS_MAX (BIT_MASK(32)) - -#define VIM_IRQGSTS_RESETVAL (0x00000000U) +#define VIM_IRQGSTS_STS_MASK (BIT64_MASK(32)) /* FIQGSTS */ - -#define VIM_FIQGSTS_STS_MASK (BIT_MASK(32)) -#define VIM_FIQGSTS_STS_SHIFT (0x00000000U) -#define VIM_FIQGSTS_STS_RESETVAL (0x00000000U) -#define VIM_FIQGSTS_STS_MAX (BIT_MASK(32)) - -#define VIM_FIQGSTS_RESETVAL (0x00000000U) +#define VIM_FIQGSTS_STS_MASK (BIT64_MASK(32)) /* IRQVEC */ - #define VIM_IRQVEC_ADDR_MASK (0xFFFFFFFCU) -#define VIM_IRQVEC_ADDR_SHIFT (0x00000002U) -#define VIM_IRQVEC_ADDR_RESETVAL (0x00000000U) -#define VIM_IRQVEC_ADDR_MAX (BIT_MASK(30)) - -#define VIM_IRQVEC_RESETVAL (0x00000000U) /* FIQVEC */ - #define VIM_FIQVEC_ADDR_MASK (0xFFFFFFFCU) -#define VIM_FIQVEC_ADDR_SHIFT (0x00000002U) -#define VIM_FIQVEC_ADDR_RESETVAL (0x00000000U) -#define VIM_FIQVEC_ADDR_MAX (BIT_MASK(30)) - -#define VIM_FIQVEC_RESETVAL (0x00000000U) /* ACTIRQ */ - #define VIM_ACTIRQ_VALID_MASK (0x80000000U) -#define VIM_ACTIRQ_VALID_SHIFT (BIT_MASK(5)) -#define VIM_ACTIRQ_VALID_RESETVAL (0x00000000U) -#define VIM_ACTIRQ_VALID_MAX (0x00000001U) - #define VIM_ACTIRQ_VALID_VAL_TRUE (0x1U) #define VIM_ACTIRQ_VALID_VAL_FALSE (0x0U) - #define VIM_ACTIRQ_PRI_MASK (0x000F0000U) -#define VIM_ACTIRQ_PRI_SHIFT (0x00000010U) -#define VIM_ACTIRQ_PRI_RESETVAL (0x00000000U) -#define VIM_ACTIRQ_PRI_MAX (BIT_MASK(4)) - #define VIM_ACTIRQ_NUM_MASK (BIT_MASK(10)) -#define VIM_ACTIRQ_NUM_SHIFT (0x00000000U) -#define VIM_ACTIRQ_NUM_RESETVAL (0x00000000U) -#define VIM_ACTIRQ_NUM_MAX (BIT_MASK(10)) - -#define VIM_ACTIRQ_RESETVAL (0x00000000U) /* ACTFIQ */ - #define VIM_ACTFIQ_VALID_MASK (0x80000000U) -#define VIM_ACTFIQ_VALID_SHIFT (BIT_MASK(5)) -#define VIM_ACTFIQ_VALID_RESETVAL (0x00000000U) -#define VIM_ACTFIQ_VALID_MAX (0x00000001U) - #define VIM_ACTFIQ_VALID_VAL_TRUE (0x1U) #define VIM_ACTFIQ_VALID_VAL_FALSE (0x0U) - #define VIM_ACTFIQ_PRI_MASK (0x000F0000U) -#define VIM_ACTFIQ_PRI_SHIFT (0x00000010U) -#define VIM_ACTFIQ_PRI_RESETVAL (0x00000000U) -#define VIM_ACTFIQ_PRI_MAX (BIT_MASK(4)) - #define VIM_ACTFIQ_NUM_MASK (BIT_MASK(10)) -#define VIM_ACTFIQ_NUM_SHIFT (0x00000000U) -#define VIM_ACTFIQ_NUM_RESETVAL (0x00000000U) -#define VIM_ACTFIQ_NUM_MAX (BIT_MASK(10)) - -#define VIM_ACTFIQ_RESETVAL (0x00000000U) /* DEDVEC */ - #define VIM_DEDVEC_ADDR_MASK (0xFFFFFFFCU) -#define VIM_DEDVEC_ADDR_SHIFT (0x00000002U) -#define VIM_DEDVEC_ADDR_RESETVAL (0x00000000U) -#define VIM_DEDVEC_ADDR_MAX (BIT_MASK(30)) - -#define VIM_DEDVEC_RESETVAL (0x00000000U) /* * VIM Driver Interface Functions From 70ca33598619cdca83a6b0769fb8ee40f1853e48 Mon Sep 17 00:00:00 2001 From: Amneesh Singh Date: Mon, 22 Dec 2025 12:28:49 +0530 Subject: [PATCH 1405/3659] drivers: intc: vim: disable all interrupts at init Disable all interrupts when the VIM interrupt controller is initialized so that it doesn't encounter any stray interrupts that were not enabled on Zephyr. Signed-off-by: Amneesh Singh --- drivers/interrupt_controller/intc_vim.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/interrupt_controller/intc_vim.c b/drivers/interrupt_controller/intc_vim.c index d37aac051d16..f83c537008a5 100644 --- a/drivers/interrupt_controller/intc_vim.c +++ b/drivers/interrupt_controller/intc_vim.c @@ -65,6 +65,11 @@ void z_vim_irq_init(void) "(%" PRIu32 ") interrupts", CONFIG_NUM_IRQS, num_of_irqs); LOG_DBG("VIM: Number of IRQs = %u\n", num_of_irqs); + + /* Start with all interrupts masked */ + for (int i = 0; i <= VIM_MAX_GROUP_NUM; i++) { + sys_write32(VIM_GRP_INTR_EN_CLR_MSK_MASK, VIM_INTR_EN_CLR(i)); + } } void z_vim_irq_priority_set(unsigned int irq, unsigned int prio, uint32_t flags) From b6f601a2b48cf7f8a965c680c59b743a9cf6a867 Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Thu, 1 Jan 2026 18:42:51 +0000 Subject: [PATCH 1406/3659] boards: nxp: frdm_mcxn947: list usbd as supported feature List USB device controller as a supported feature in order to increase test coverage. Signed-off-by: Henrik Brix Andersen --- boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0.yaml | 1 + boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_qspi.yaml | 1 + 2 files changed, 2 insertions(+) diff --git a/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0.yaml b/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0.yaml index a4b4a7b1e254..08de31683cfe 100644 --- a/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0.yaml +++ b/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0.yaml @@ -36,6 +36,7 @@ supported: - sdhc - spi - usb_device + - usbd - video - watchdog vendor: nxp diff --git a/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_qspi.yaml b/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_qspi.yaml index ca5461e8df4c..711d9d771fff 100644 --- a/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_qspi.yaml +++ b/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_qspi.yaml @@ -33,5 +33,6 @@ supported: - sdhc - spi - usb_device + - usbd - watchdog vendor: nxp From ce526f2e1686395a9ce4e0565cc4667466bc9225 Mon Sep 17 00:00:00 2001 From: Ian Morris Date: Sun, 12 Oct 2025 17:00:26 -0700 Subject: [PATCH 1407/3659] boards: shields: Renamed Renesas us159 da14531evz board photograph Reneamed photograph of Renesas US159 DA14531EVZ board to match convention documented in the Board Porting Guide (resolving issue with old image not appearing in list of supported boards on Zephyr website). Signed-off-by: Ian Morris --- .../shields/renesas_us159_da14531evz/doc/index.rst | 2 +- ...1evz-pmod.webp => renesas_us159_da14531evz.webp} | Bin 2 files changed, 1 insertion(+), 1 deletion(-) rename boards/shields/renesas_us159_da14531evz/doc/{us159-da14531evz-pmod.webp => renesas_us159_da14531evz.webp} (100%) diff --git a/boards/shields/renesas_us159_da14531evz/doc/index.rst b/boards/shields/renesas_us159_da14531evz/doc/index.rst index 1b302e4ac149..c4b141925c15 100644 --- a/boards/shields/renesas_us159_da14531evz/doc/index.rst +++ b/boards/shields/renesas_us159_da14531evz/doc/index.rst @@ -9,7 +9,7 @@ Overview The Renesas US159 DA14531EVZ carries a `DA14531MOD`_ Bluetooth LE module in a `Digilent Pmod`_ |trade| form factor. -.. figure:: us159-da14531evz-pmod.webp +.. figure:: renesas_us159_da14531evz.webp :align: center :alt: Renesas US159 DA14531EVZ Pmod diff --git a/boards/shields/renesas_us159_da14531evz/doc/us159-da14531evz-pmod.webp b/boards/shields/renesas_us159_da14531evz/doc/renesas_us159_da14531evz.webp similarity index 100% rename from boards/shields/renesas_us159_da14531evz/doc/us159-da14531evz-pmod.webp rename to boards/shields/renesas_us159_da14531evz/doc/renesas_us159_da14531evz.webp From 6e4ef4484733d19b490743b13243ace697bdb57c Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Tue, 16 Dec 2025 14:43:16 +0100 Subject: [PATCH 1408/3659] kernel: poll: patch recursive lock in z_vrfy_k_poll In z_vrfy_k_poll, there is a memory access check K_SYSCALL_MEMORY_WRITE which is wrapped in a spinlock, the same spinlock used in z_handle_obj_poll_events which is called from k_sem_give() for example. The K_SYSCALL_MEMORY_WRITE() macro conditionally calls LOG_ERR() which may call the UART console, which may call an API like k_sem_give(). This will cause a deadlock since the locked spinlock will be relocked, and a recursive lock if SPINLOCK_VALIDATE and ASSERTS are enabled as the validation will fail, causing a LOG_ERR, causing a k_sem_give() causing a relock... until stack overflows. To solve the issue, only protect the copy of events to events_copy with the spinlock, the content of events is not actually checked, and bound is not shared, so there is no need to do this validation in a critical section. The contents of events is shared so that must be copied in atomically. Signed-off-by: Bjarki Arge Andreasen --- kernel/poll.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/poll.c b/kernel/poll.c index da956a268cc8..f28c0100fc62 100644 --- a/kernel/poll.c +++ b/kernel/poll.c @@ -376,11 +376,11 @@ static inline int z_vrfy_k_poll(struct k_poll_event *events, goto out; } - key = k_spin_lock(&lock); if (K_SYSCALL_MEMORY_WRITE(events, bounds)) { - k_spin_unlock(&lock, key); goto oops_free; } + + key = k_spin_lock(&lock); (void)memcpy(events_copy, events, bounds); k_spin_unlock(&lock, key); From a23cfc3f689ac7f10ff6789af982fb89b703af4f Mon Sep 17 00:00:00 2001 From: Emanuele Di Santo Date: Wed, 17 Dec 2025 12:40:21 +0100 Subject: [PATCH 1409/3659] kernel: nothread: use k_timer to sleep instead of busy waiting The current implementation of k_sleep(), when multi-threading is disabled, busy waits using k_busy_wait() until the sleep timeout has expired. This patch aims to improve power efficiency of k_sleep() for single-threaded applications by starting a timer (k_timer) and idling the CPU until the timer interrupt wakes it up, thus avoiding busy-looping. Signed-off-by: Emanuele Di Santo --- kernel/nothread.c | 35 +++++++++++++---------------------- 1 file changed, 13 insertions(+), 22 deletions(-) diff --git a/kernel/nothread.c b/kernel/nothread.c index 09bf45459611..02876c69f2b8 100644 --- a/kernel/nothread.c +++ b/kernel/nothread.c @@ -14,14 +14,13 @@ bool k_is_in_isr(void) return arch_is_in_isr(); } +static K_TIMER_DEFINE(sleep_timer, NULL, NULL); + /* This is a fallback implementation of k_sleep() for when multi-threading is * disabled. The main implementation is in sched.c. */ int32_t z_impl_k_sleep(k_timeout_t timeout) { - k_ticks_t ticks; - uint32_t ticks_to_wait; - __ASSERT(!arch_is_in_isr(), ""); SYS_PORT_TRACING_FUNC_ENTER(k_thread, sleep, timeout); @@ -35,26 +34,18 @@ int32_t z_impl_k_sleep(k_timeout_t timeout) return (int32_t) K_TICKS_FOREVER; } - ticks = timeout.ticks; - if (Z_IS_TIMEOUT_RELATIVE(timeout)) { - /* ticks is delta timeout */ - ticks_to_wait = ticks; - } else { - /* ticks is absolute timeout expiration */ - uint32_t curr_ticks = sys_clock_tick_get_32(); - - if (Z_TICK_ABS(ticks) > curr_ticks) { - ticks_to_wait = Z_TICK_ABS(ticks) - curr_ticks; - } else { - ticks_to_wait = 0; - } - } - /* busy wait to be time coherent since subsystems may depend on it */ - z_impl_k_busy_wait(k_ticks_to_us_ceil32(ticks_to_wait)); + k_timer_start(&sleep_timer, timeout, K_NO_WAIT); - int32_t ret = k_ticks_to_ms_ceil64(0); + /* When multithreading is disabled, this will enter a low power state + * using k_cpu_idle() until the timer has expired. + */ + k_timer_status_sync(&sleep_timer); - SYS_PORT_TRACING_FUNC_EXIT(k_thread, sleep, timeout, ret); + SYS_PORT_TRACING_FUNC_EXIT(k_thread, sleep, timeout, 0); - return ret; + /* This implementation is compiled when multithreading is disabled. + * Therefore, unlike its multithreaded counterpart, it shall always + * sleep for the entire timeout duration (no thread to awake). + */ + return 0; } From 669a8d0704e889302cff10beb0eb419a28282a53 Mon Sep 17 00:00:00 2001 From: Peter Mitsis Date: Fri, 19 Dec 2025 13:46:17 -0800 Subject: [PATCH 1410/3659] kernel: O(1) search for threads among CPUs Instead of performing a linear search to determine if a given thread is running on another CPU, or if it is marked as being preempted by a metaIRQ on any CPU do this in O(1) time. On SMP systems, Zephyr already tracks the CPU on which a thread executes (or lasted executed). This information is leveraged to do the search in O(1) time. Signed-off-by: Peter Mitsis --- include/zephyr/kernel/thread.h | 2 +- kernel/sched.c | 35 ++++++++++++++++++---------------- kernel/thread.c | 6 ++++++ 3 files changed, 26 insertions(+), 17 deletions(-) diff --git a/include/zephyr/kernel/thread.h b/include/zephyr/kernel/thread.h index c7bd6b31b0b1..3dd40355bc28 100644 --- a/include/zephyr/kernel/thread.h +++ b/include/zephyr/kernel/thread.h @@ -101,7 +101,7 @@ struct _thread_base { /* True for the per-CPU idle threads */ uint8_t is_idle; - /* CPU index on which thread was last run */ + /* Identify CPU on which thread is (or was last) executing */ uint8_t cpu; /* Recursive count of irq_lock() calls */ diff --git a/kernel/sched.c b/kernel/sched.c index 26240612df7e..cc7f45461056 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -322,23 +322,24 @@ static ALWAYS_INLINE void update_cache(int preempt_ok) TOOLCHAIN_ENABLE_WARNING(TOOLCHAIN_WARNING_ALWAYS_INLINE) #endif +/** + * Returns pointer to _cpu if the thread is currently running on + * another CPU. + */ static struct _cpu *thread_active_elsewhere(struct k_thread *thread) { - /* 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; + int thread_cpu_id = thread->base.cpu; + struct _cpu *thread_cpu; - unsigned int num_cpus = arch_num_cpus(); + __ASSERT_NO_MSG((thread_cpu_id >= 0) && + (thread_cpu_id < arch_num_cpus())); - for (int i = 0; i < num_cpus; i++) { - if ((i != currcpu) && - (_kernel.cpus[i].current == thread)) { - return &_kernel.cpus[i]; - } + thread_cpu = &_kernel.cpus[thread_cpu_id]; + if ((thread_cpu->current == thread) && (thread_cpu != _current_cpu)) { + return thread_cpu; } + #endif /* CONFIG_SMP */ ARG_UNUSED(thread); return NULL; @@ -408,11 +409,13 @@ static void thread_halt_spin(struct k_thread *thread, k_spinlock_key_t key) static ALWAYS_INLINE void z_metairq_preempted_clear(struct k_thread *thread) { #if (CONFIG_NUM_METAIRQ_PRIORITIES > 0) - for (unsigned int i = 0; i < CONFIG_MP_MAX_NUM_CPUS; i++) { - if (_kernel.cpus[i].metairq_preempted == thread) { - _kernel.cpus[i].metairq_preempted = NULL; - break; - } + unsigned int cpu_id = 0; + +#if defined(CONFIG_SMP) && (CONFIG_MP_MAX_NUM_CPUS > 1) + cpu_id = thread->base.cpu; +#endif + if (_kernel.cpus[cpu_id].metairq_preempted == thread) { + _kernel.cpus[cpu_id].metairq_preempted = NULL; } #endif } diff --git a/kernel/thread.c b/kernel/thread.c index fb011ef34ea3..97efd493c9cb 100644 --- a/kernel/thread.c +++ b/kernel/thread.c @@ -890,6 +890,12 @@ void z_init_thread_base(struct _thread_base *thread_base, int priority, #ifdef CONFIG_SMP thread_base->is_idle = 0; + + /* + * Pretend that the thread was last executing on CPU0 to prevent + * out-of-bounds memory accesses to the _kernel.cpus[] array. + */ + thread_base->cpu = 0; #endif /* CONFIG_SMP */ #ifdef CONFIG_TIMESLICE_PER_THREAD From 0c3027718bdf5b1bed5c13d0c52f952a612c1cc4 Mon Sep 17 00:00:00 2001 From: Tim Pambor Date: Sun, 21 Dec 2025 18:52:38 +0100 Subject: [PATCH 1411/3659] drivers: mdio: gpio: add clause 45 support Add support for clause 45 MDIO transactions to the GPIO MDIO driver. Signed-off-by: Tim Pambor --- drivers/mdio/mdio_gpio.c | 103 ++++++++++++++++++++++++++++++--------- 1 file changed, 80 insertions(+), 23 deletions(-) diff --git a/drivers/mdio/mdio_gpio.c b/drivers/mdio/mdio_gpio.c index c033e6da3b8e..b13af04f3a9d 100644 --- a/drivers/mdio/mdio_gpio.c +++ b/drivers/mdio/mdio_gpio.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2023 Aleksandr Senin + * Copyright (c) 2025 CodeWrights GmbH * * SPDX-License-Identifier: Apache-2.0 */ @@ -11,13 +12,14 @@ #include #include #include +#include #include LOG_MODULE_REGISTER(mdio_gpio, CONFIG_MDIO_LOG_LEVEL); -#define MDIO_GPIO_READ_OP 0 -#define MDIO_GPIO_WRITE_OP 1 -#define MDIO_GPIO_MSB 0x80000000 +#define MDIO_GPIO_DIR_INPUT 0 +#define MDIO_GPIO_DIR_OUTPUT 1 +#define MDIO_GPIO_MSB 0x80000000 struct mdio_gpio_data { struct k_sem sem; @@ -38,8 +40,9 @@ static ALWAYS_INLINE void mdio_gpio_clock_the_bit(const struct mdio_gpio_config static ALWAYS_INLINE void mdio_gpio_dir(const struct mdio_gpio_config *dev_cfg, uint8_t dir) { - gpio_pin_configure_dt(&dev_cfg->mdio_gpio, dir ? GPIO_OUTPUT_ACTIVE : GPIO_INPUT); - if (dir == 0) { + gpio_pin_configure_dt(&dev_cfg->mdio_gpio, + (dir == MDIO_GPIO_DIR_OUTPUT) ? GPIO_OUTPUT_ACTIVE : GPIO_INPUT); + if (dir == MDIO_GPIO_DIR_INPUT) { mdio_gpio_clock_the_bit(dev_cfg); } } @@ -73,41 +76,39 @@ static ALWAYS_INLINE void mdio_gpio_write(const struct mdio_gpio_config *dev_cfg } } -static int mdio_gpio_transfer(const struct device *dev, uint8_t prtad, uint8_t devad, uint8_t rw, - uint16_t data_in, uint16_t *data_out) +static int mdio_gpio_transfer(const struct device *dev, uint8_t prtad, uint8_t devad, bool c22, + uint8_t op, uint16_t data_in, uint16_t *data_out) { const struct mdio_gpio_config *const dev_cfg = dev->config; - struct mdio_gpio_data *const dev_data = dev->data; - - k_sem_take(&dev_data->sem, K_FOREVER); /* DIR: output */ - mdio_gpio_dir(dev_cfg, MDIO_GPIO_WRITE_OP); + mdio_gpio_dir(dev_cfg, MDIO_GPIO_DIR_OUTPUT); /* PRE32: 32 bits '1' for sync*/ mdio_gpio_write(dev_cfg, 0xFFFFFFFF, 32); - /* ST: 2 bits start of frame */ - mdio_gpio_write(dev_cfg, 0x1, 2); - /* OP: 2 bits opcode, read '10' or write '01' */ - mdio_gpio_write(dev_cfg, rw ? 0x1 : 0x2, 2); + /* ST: 2 bits start of frame, 1 for clause 22, 0 for clause 45 */ + mdio_gpio_write(dev_cfg, c22 ? 0x1 : 0x0, 2); + /* OP: 2 bits opcode */ + mdio_gpio_write(dev_cfg, op, 2); /* PA5: 5 bits PHY address */ mdio_gpio_write(dev_cfg, prtad, 5); /* RA5: 5 bits register address */ mdio_gpio_write(dev_cfg, devad, 5); - if (rw) { /* Write data */ + if ((c22 && (op == MDIO_OP_C22_WRITE)) || + (!c22 && ((op == MDIO_OP_C45_WRITE) || (op == MDIO_OP_C45_ADDRESS)))) { + /* Write data */ /* TA: 2 bits turn-around */ mdio_gpio_write(dev_cfg, 0x2, 2); mdio_gpio_write(dev_cfg, data_in, 16); - } else { /* Read data */ + } else { + /* Read data */ /* Release the MDIO line */ - mdio_gpio_dir(dev_cfg, MDIO_GPIO_READ_OP); + mdio_gpio_dir(dev_cfg, MDIO_GPIO_DIR_INPUT); mdio_gpio_read(dev_cfg, data_out); } /* DIR: input. Tristate MDIO line */ - mdio_gpio_dir(dev_cfg, MDIO_GPIO_READ_OP); - - k_sem_give(&dev_data->sem); + mdio_gpio_dir(dev_cfg, MDIO_GPIO_DIR_INPUT); return 0; } @@ -115,13 +116,67 @@ static int mdio_gpio_transfer(const struct device *dev, uint8_t prtad, uint8_t d static int mdio_gpio_read_mmi(const struct device *dev, uint8_t prtad, uint8_t devad, uint16_t *data) { - return mdio_gpio_transfer(dev, prtad, devad, MDIO_GPIO_READ_OP, 0, data); + int rc; + struct mdio_gpio_data *const dev_data = dev->data; + + k_sem_take(&dev_data->sem, K_FOREVER); + + rc = mdio_gpio_transfer(dev, prtad, devad, true, MDIO_OP_C22_READ, 0, data); + + k_sem_give(&dev_data->sem); + + return rc; } static int mdio_gpio_write_mmi(const struct device *dev, uint8_t prtad, uint8_t devad, uint16_t data) { - return mdio_gpio_transfer(dev, prtad, devad, MDIO_GPIO_WRITE_OP, data, NULL); + int rc; + struct mdio_gpio_data *const dev_data = dev->data; + + k_sem_take(&dev_data->sem, K_FOREVER); + + rc = mdio_gpio_transfer(dev, prtad, devad, true, MDIO_OP_C22_WRITE, data, NULL); + + k_sem_give(&dev_data->sem); + + return rc; +} + +static int mdio_gpio_read_c45_mmi(const struct device *dev, uint8_t prtad, uint8_t devad, + uint16_t regad, uint16_t *data) +{ + int rc; + struct mdio_gpio_data *const dev_data = dev->data; + + k_sem_take(&dev_data->sem, K_FOREVER); + + rc = mdio_gpio_transfer(dev, prtad, devad, false, MDIO_OP_C45_ADDRESS, regad, NULL); + if (rc >= 0) { + rc = mdio_gpio_transfer(dev, prtad, devad, false, MDIO_OP_C45_READ, 0, data); + } + + k_sem_give(&dev_data->sem); + + return rc; +} + +static int mdio_gpio_write_c45_mmi(const struct device *dev, uint8_t prtad, uint8_t devad, + uint16_t regad, uint16_t data) +{ + int rc; + struct mdio_gpio_data *const dev_data = dev->data; + + k_sem_take(&dev_data->sem, K_FOREVER); + + rc = mdio_gpio_transfer(dev, prtad, devad, false, MDIO_OP_C45_ADDRESS, regad, NULL); + if (rc >= 0) { + rc = mdio_gpio_transfer(dev, prtad, devad, false, MDIO_OP_C45_WRITE, data, NULL); + } + + k_sem_give(&dev_data->sem); + + return rc; } static int mdio_gpio_initialize(const struct device *dev) @@ -160,6 +215,8 @@ static int mdio_gpio_initialize(const struct device *dev) static DEVICE_API(mdio, mdio_gpio_driver_api) = { .read = mdio_gpio_read_mmi, .write = mdio_gpio_write_mmi, + .read_c45 = mdio_gpio_read_c45_mmi, + .write_c45 = mdio_gpio_write_c45_mmi, }; #define MDIO_GPIO_CONFIG(inst) \ From cdb7debfb726569440fc22ce6673de2b86c728f7 Mon Sep 17 00:00:00 2001 From: Benedek Kupper Date: Tue, 6 Jan 2026 21:53:04 +0100 Subject: [PATCH 1412/3659] drivers: dma: stm32: fix data sizes in memory to peripheral direction This problem didn't surface earlier, as different sizes weren't permitted. Signed-off-by: Benedek Kupper --- drivers/dma/dma_stm32.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/dma/dma_stm32.c b/drivers/dma/dma_stm32.c index 90360a63cb40..2f0ef7f917ee 100644 --- a/drivers/dma/dma_stm32.c +++ b/drivers/dma/dma_stm32.c @@ -395,16 +395,23 @@ DMA_STM32_EXPORT_API int dma_stm32_configure(const struct device *dev, LOG_WRN("dest_buffer address is null."); } + int source_index = find_lsb_set(config->source_data_size) - 1; + int dest_index = find_lsb_set(config->dest_data_size) - 1; + if (stream->direction == MEMORY_TO_PERIPHERAL) { DMA_InitStruct.MemoryOrM2MDstAddress = config->head_block->source_address; DMA_InitStruct.PeriphOrM2MSrcAddress = config->head_block->dest_address; + DMA_InitStruct.MemoryOrM2MDstDataSize = table_m_size[source_index]; + DMA_InitStruct.PeriphOrM2MSrcDataSize = table_p_size[dest_index]; } else { DMA_InitStruct.PeriphOrM2MSrcAddress = config->head_block->source_address; DMA_InitStruct.MemoryOrM2MDstAddress = config->head_block->dest_address; + DMA_InitStruct.PeriphOrM2MSrcDataSize = table_p_size[source_index]; + DMA_InitStruct.MemoryOrM2MDstDataSize = table_m_size[dest_index]; } uint16_t memory_addr_adj = 0, periph_addr_adj = 0; @@ -464,12 +471,6 @@ DMA_STM32_EXPORT_API int dma_stm32_configure(const struct device *dev, stream->source_periph = (stream->direction == PERIPHERAL_TO_MEMORY); - /* set the data widths */ - int index = find_lsb_set(config->source_data_size) - 1; - DMA_InitStruct.PeriphOrM2MSrcDataSize = table_p_size[index]; - index = find_lsb_set(config->dest_data_size) - 1; - DMA_InitStruct.MemoryOrM2MDstDataSize = table_m_size[index]; - #if defined(CONFIG_DMA_STM32_V1) DMA_InitStruct.MemBurst = stm32_dma_get_mburst(config, stream->source_periph); From c9e934cfddef5b33d8615a45dd5ab212132e05f2 Mon Sep 17 00:00:00 2001 From: Benjamin Klaric Date: Thu, 8 Jan 2026 11:39:24 +0100 Subject: [PATCH 1413/3659] boards: st: stm32h7s78_dk: add Ethernet support Add Ethernet configuration for mac and mdio nodes in stm32h78_dk-common.dtsi. Disable mac node in .overlay files for tests/drivers/memc/ram since ethernet drivers that get enabled by it consume sram1 node and thus fail the test. Update the .yaml files to include Ethernet tag and update documentation to explain Ethernet usage. Signed-off-by: Benjamin Klaric --- boards/st/stm32h7s78_dk/doc/index.rst | 7 +++++ .../stm32h7s78_dk/stm32h7s78_dk-common.dtsi | 30 +++++++++++++++++++ ...m32h7s78_dk_stm32h7s7xx_ext_flash_app.yaml | 1 + .../memc/ram/boards/stm32h7s78_dk.overlay | 8 +++++ ...h7s78_dk_stm32h7s7xx_ext_flash_app.overlay | 18 +++++++++++ 5 files changed, 64 insertions(+) create mode 100644 tests/drivers/memc/ram/boards/stm32h7s78_dk_stm32h7s7xx_ext_flash_app.overlay diff --git a/boards/st/stm32h7s78_dk/doc/index.rst b/boards/st/stm32h7s78_dk/doc/index.rst index 5d5255509772..300e38acb35d 100644 --- a/boards/st/stm32h7s78_dk/doc/index.rst +++ b/boards/st/stm32h7s78_dk/doc/index.rst @@ -181,6 +181,7 @@ Default Zephyr Peripheral Mapping: - XSPI1 NCS/DQS0/DQS1/CLK/IO: PO0/PO2/PO3/PO4/PP0..15 - I2C1 SCL/SDA: PB6/PB9 - FDCAN1 RX/TX : PB8/PB9 +- ETH: PA2/PA7/PB0/PB1/PC1/PC4/PC5/PD7/PG11 System Clock ------------ @@ -208,6 +209,12 @@ STM32H7S78-DK Discovery board has 2 FDCAN bus interfaces. FDCAN1 is configured but not enabled by default. To enable it, make sure that ``i2c1`` is disabled, since they share the PB9 pin. +Ethernet +-------- + +In order to use Ethernet on STM32H7S78-DK, you need to set the ``JP6`` jumper +to PC1 position on the back side of the board. + Programming and Debugging ************************* diff --git a/boards/st/stm32h7s78_dk/stm32h7s78_dk-common.dtsi b/boards/st/stm32h7s78_dk/stm32h7s78_dk-common.dtsi index 0b2a37a8be73..41dab8d3aefc 100644 --- a/boards/st/stm32h7s78_dk/stm32h7s78_dk-common.dtsi +++ b/boards/st/stm32h7s78_dk/stm32h7s78_dk-common.dtsi @@ -11,6 +11,11 @@ #include "zephyr/dt-bindings/display/panel.h" #include +/* + * WARNING: + * JP6 must be in PC1 position when using Ethernet. + */ + / { chosen { zephyr,console = &uart4; @@ -228,6 +233,31 @@ status = "disabled"; }; +&mac { + pinctrl-0 = <ð_rmii_ref_clk_pd7 + ð_rmii_crs_dv_pa7 + ð_rmii_rxd0_pc4 + ð_rmii_rxd1_pc5 + ð_rmii_tx_en_pg11 + ð_rmii_txd0_pb0 + ð_rmii_txd1_pb1>; + pinctrl-names = "default"; + phy-connection-type = "rmii"; + phy-handle = <ð_phy>; + status = "okay"; +}; + +&mdio { + pinctrl-0 = <ð_mdio_pa2 ð_mdc_pc1>; + pinctrl-names = "default"; + status = "okay"; + + eth_phy: ethernet-phy@0 { + compatible = "ethernet-phy"; + reg = <0x00>; + }; +}; + &xspi1 { pinctrl-0 = <&xspim_p1_ncs1_po0 &xspim_p1_dqs0_po2 &xspim_p1_dqs1_po3 &xspim_p1_clk_po4 diff --git a/boards/st/stm32h7s78_dk/stm32h7s78_dk_stm32h7s7xx_ext_flash_app.yaml b/boards/st/stm32h7s78_dk/stm32h7s78_dk_stm32h7s7xx_ext_flash_app.yaml index 92ef6680b284..12d379f83d3a 100644 --- a/boards/st/stm32h7s78_dk/stm32h7s78_dk_stm32h7s7xx_ext_flash_app.yaml +++ b/boards/st/stm32h7s78_dk/stm32h7s78_dk_stm32h7s7xx_ext_flash_app.yaml @@ -17,4 +17,5 @@ supported: - octospi - usbd - memc + - netif:eth vendor: st diff --git a/tests/drivers/memc/ram/boards/stm32h7s78_dk.overlay b/tests/drivers/memc/ram/boards/stm32h7s78_dk.overlay index 9a7568844a39..6b371ffbcd27 100644 --- a/tests/drivers/memc/ram/boards/stm32h7s78_dk.overlay +++ b/tests/drivers/memc/ram/boards/stm32h7s78_dk.overlay @@ -8,3 +8,11 @@ zephyr,memory-attr = ; status = "okay"; }; + +&mac { + /* + * mac is disabled for this test since the ethernet driver that gets + * enabled by this node consumes the sram1 node thus failing this test + */ + status = "disabled"; +}; diff --git a/tests/drivers/memc/ram/boards/stm32h7s78_dk_stm32h7s7xx_ext_flash_app.overlay b/tests/drivers/memc/ram/boards/stm32h7s78_dk_stm32h7s7xx_ext_flash_app.overlay new file mode 100644 index 000000000000..b8020f041f0c --- /dev/null +++ b/tests/drivers/memc/ram/boards/stm32h7s78_dk_stm32h7s7xx_ext_flash_app.overlay @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2025 Benjamin Klaric + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&sram2 { + zephyr,memory-attr = ; + status = "okay"; +}; + +&mac { + /* + * mac is disabled for this test since the ethernet driver that gets + * enabled by this node consumes the sram1 node thus failing this test + */ + status = "disabled"; +}; From 028abf54ba95f1eebe39ee4842455253325b401f Mon Sep 17 00:00:00 2001 From: Woobin Song Date: Wed, 3 Dec 2025 12:54:55 +0900 Subject: [PATCH 1414/3659] drivers: gpio: tca6424a: fix race condition in port_get_raw() Avoid overwriting cached input state while ISR-deferred work is pending. Previously, port_get_raw() updated pins_state.input via update_input_regs(), which could corrupt previous_state used for transition detection. Fix by reading input registers directly without updating the global cache. Signed-off-by: Woobin Song --- drivers/gpio/gpio_tca6424a.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/gpio/gpio_tca6424a.c b/drivers/gpio/gpio_tca6424a.c index b21a43e8bc1c..18f499054a8c 100644 --- a/drivers/gpio/gpio_tca6424a.c +++ b/drivers/gpio/gpio_tca6424a.c @@ -318,7 +318,6 @@ static int tca6424a_pin_config(const struct device *dev, gpio_pin_t pin, gpio_fl static int tca6424a_port_get_raw(const struct device *dev, gpio_port_value_t *value) { - struct tca6424a_drv_data *const drv_data = dev->data; uint32_t buf; int ret; @@ -327,14 +326,11 @@ static int tca6424a_port_get_raw(const struct device *dev, gpio_port_value_t *va return -EWOULDBLOCK; } - k_sem_take(&drv_data->lock, K_FOREVER); - - ret = update_input_regs(dev, &buf); + ret = read_port_regs(dev, TCA6424A_REG_INPUT, &buf); if (ret == 0) { *value = buf; } - k_sem_give(&drv_data->lock); return ret; } From 1179ed63d5d8bc19487a493d86dc6836f1293d18 Mon Sep 17 00:00:00 2001 From: Zafer SEN Date: Fri, 5 Dec 2025 17:56:16 +0000 Subject: [PATCH 1415/3659] drivers: modem: hl78xx: add ERROR handling and unify OK match usage Extend socket-related chat match tables to handle generic "ERROR" responses for both CONNECT and +KUDP_IND URCs, improving detection of failed socket creation and connection attempts. While updating match handling, unify all modem commands to use the standard OK match set by adding hl78xx_get_ok_match_size(). All remaining users of the former sockets-specific OK match are switched to the unified helpers. Additionally, all dynamic command send paths now provide an explicit match count and use MDM_CMD_TIMEOUT instead of the previous hard-coded `1` for script timeout, improving consistency and reliability across: * RAT configuration * band configuration * APN setup * GSM PDP activation * AirVantage DM session control * socket send and TLS configuration paths This brings all command execution onto the same match/timeout model and ensures ERROR responses are handled correctly during socket operations. Signed-off-by: Zafer SEN --- drivers/modem/hl78xx/hl78xx.c | 3 ++- drivers/modem/hl78xx/hl78xx.h | 1 + drivers/modem/hl78xx/hl78xx_apis.c | 12 ++++++++---- drivers/modem/hl78xx/hl78xx_cfg.c | 27 ++++++++++++++++---------- drivers/modem/hl78xx/hl78xx_chat.c | 28 ++++++++++++++++++--------- drivers/modem/hl78xx/hl78xx_chat.h | 3 ++- drivers/modem/hl78xx/hl78xx_sockets.c | 22 ++++++++++----------- 7 files changed, 60 insertions(+), 36 deletions(-) diff --git a/drivers/modem/hl78xx/hl78xx.c b/drivers/modem/hl78xx/hl78xx.c index 5ab1d2633823..df4f1ae946c1 100644 --- a/drivers/modem/hl78xx/hl78xx.c +++ b/drivers/modem/hl78xx/hl78xx.c @@ -1141,7 +1141,8 @@ static int hl78xx_on_rat_cfg_script_state_enter(struct hl78xx_data *data) if (modem_require_restart) { HL78XX_LOG_DBG("Modem restart required to apply new RAT/Band settings"); ret = modem_dynamic_cmd_send(data, NULL, cmd_restart, strlen(cmd_restart), - hl78xx_get_ok_match(), 1, false); + hl78xx_get_ok_match(), hl78xx_get_ok_match_size(), + MDM_CMD_TIMEOUT, false); if (ret < 0) { goto error; } diff --git a/drivers/modem/hl78xx/hl78xx.h b/drivers/modem/hl78xx/hl78xx.h index 0233b3054c43..23330ddb3957 100644 --- a/drivers/modem/hl78xx/hl78xx.h +++ b/drivers/modem/hl78xx/hl78xx.h @@ -73,6 +73,7 @@ #define TERMINATION_PATTERN "+++" #define CONNECT_STRING "CONNECT" #define CME_ERROR_STRING "+CME ERROR: " +#define ERROR_STRING "ERROR" #define OK_STRING "OK" /* RAT (Radio Access Technology) commands */ diff --git a/drivers/modem/hl78xx/hl78xx_apis.c b/drivers/modem/hl78xx/hl78xx_apis.c index 760696a6f940..dcb52778655d 100644 --- a/drivers/modem/hl78xx/hl78xx_apis.c +++ b/drivers/modem/hl78xx/hl78xx_apis.c @@ -266,7 +266,8 @@ int hl78xx_api_func_set_phone_functionality(const struct device *dev, struct hl78xx_data *data = (struct hl78xx_data *)dev->data; /* configure modem functionality with/without restart */ snprintf(cmd_string, sizeof(cmd_string), "AT+CFUN=%d,%d", functionality, reset); - return hl78xx_send_cmd(data, cmd_string, NULL, hl78xx_get_ok_match(), 1); + return hl78xx_send_cmd(data, cmd_string, NULL, hl78xx_get_ok_match(), + hl78xx_get_ok_match_size()); } int hl78xx_api_func_get_phone_functionality(const struct device *dev, @@ -275,7 +276,8 @@ int hl78xx_api_func_get_phone_functionality(const struct device *dev, const char *cmd_string = GET_FULLFUNCTIONAL_MODE_CMD; struct hl78xx_data *data = (struct hl78xx_data *)dev->data; /* get modem phone functionality */ - return hl78xx_send_cmd(data, cmd_string, NULL, hl78xx_get_ok_match(), 1); + return hl78xx_send_cmd(data, cmd_string, NULL, hl78xx_get_ok_match(), + hl78xx_get_ok_match_size()); } int hl78xx_api_func_modem_dynamic_cmd_send(const struct device *dev, const char *cmd, @@ -300,7 +302,8 @@ int hl78xx_start_airvantage_dm_session(const struct device *dev) ret = modem_dynamic_cmd_send(data, NULL, WDSI_USER_INITIATED_CONNECTION_START_CMD, strlen(WDSI_USER_INITIATED_CONNECTION_START_CMD), - hl78xx_get_ok_match(), 1, false); + hl78xx_get_ok_match(), hl78xx_get_ok_match_size(), + MDM_CMD_TIMEOUT, false); if (ret < 0) { LOG_ERR("Start DM session error %d", ret); return ret; @@ -315,7 +318,8 @@ int hl78xx_stop_airvantage_dm_session(const struct device *dev) ret = modem_dynamic_cmd_send(data, NULL, WDSI_USER_INITIATED_CONNECTION_STOP_CMD, strlen(WDSI_USER_INITIATED_CONNECTION_STOP_CMD), - hl78xx_get_ok_match(), 1, false); + hl78xx_get_ok_match(), hl78xx_get_ok_match_size(), + MDM_CMD_TIMEOUT, false); if (ret < 0) { LOG_ERR("Stop DM session error %d", ret); return ret; diff --git a/drivers/modem/hl78xx/hl78xx_cfg.c b/drivers/modem/hl78xx/hl78xx_cfg.c index bddfc7fb6da9..99c3a62dfe11 100644 --- a/drivers/modem/hl78xx/hl78xx_cfg.c +++ b/drivers/modem/hl78xx/hl78xx_cfg.c @@ -35,7 +35,8 @@ int hl78xx_rat_cfg(struct hl78xx_data *data, bool *modem_require_restart, char cmd_kselq[] = "AT+KSELACQ=0," CONFIG_MODEM_HL78XX_AUTORAT_PRL_PROFILES; ret = modem_dynamic_cmd_send(data, NULL, cmd_kselq, strlen(cmd_kselq), - hl78xx_get_ok_match(), 1, false); + hl78xx_get_ok_match(), hl78xx_get_ok_match_size(), + MDM_CMD_TIMEOUT, false); if (ret < 0) { goto error; } else { @@ -52,8 +53,8 @@ int hl78xx_rat_cfg(struct hl78xx_data *data, bool *modem_require_restart, if (data->kselacq_data.rat1 != 0 && data->kselacq_data.rat2 != 0 && data->kselacq_data.rat3 != 0) { ret = modem_dynamic_cmd_send(data, NULL, cmd_kselq_disable, - strlen(cmd_kselq_disable), hl78xx_get_ok_match(), 1, - false); + strlen(cmd_kselq_disable), hl78xx_get_ok_match(), + hl78xx_get_ok_match_size(), MDM_CMD_TIMEOUT, false); if (ret < 0) { goto error; } @@ -97,7 +98,8 @@ int hl78xx_rat_cfg(struct hl78xx_data *data, bool *modem_require_restart, if (*rat_request != data->status.registration.rat_mode) { ret = modem_dynamic_cmd_send(data, NULL, cmd_set_rat, strlen(cmd_set_rat), - hl78xx_get_ok_match(), 1, false); + hl78xx_get_ok_match(), hl78xx_get_ok_match_size(), + MDM_CMD_TIMEOUT, false); if (ret < 0) { goto error; } else { @@ -162,8 +164,9 @@ int hl78xx_band_cfg(struct hl78xx_data *data, bool *modem_require_restart, char cmd_bnd[80] = {0}; snprintf(cmd_bnd, sizeof(cmd_bnd), "AT+KBNDCFG=%d,%s", rat, bnd_bitmap); - ret = modem_dynamic_cmd_send(data, NULL, cmd_bnd, strlen(cmd_bnd), - hl78xx_get_ok_match(), 1, false); + ret = modem_dynamic_cmd_send( + data, NULL, cmd_bnd, strlen(cmd_bnd), hl78xx_get_ok_match(), + hl78xx_get_ok_match_size(), MDM_CMD_TIMEOUT, false); if (ret < 0) { goto error; } else { @@ -205,20 +208,23 @@ int hl78xx_set_apn_internal(struct hl78xx_data *data, const char *apn, uint16_t apn); ret = modem_dynamic_cmd_send(data, NULL, cmd_string, strlen(cmd_string), - hl78xx_get_ok_match(), 1, false); + hl78xx_get_ok_match(), hl78xx_get_ok_match_size(), + MDM_CMD_TIMEOUT, false); if (ret < 0) { goto error; } snprintk(cmd_string, cmd_max_len, "AT+KCNXCFG=1,\"GPRS\",\"%s\",,,\"" MODEM_HL78XX_ADDRESS_FAMILY "\"", apn); ret = modem_dynamic_cmd_send(data, NULL, cmd_string, strlen(cmd_string), - hl78xx_get_ok_match(), 1, false); + hl78xx_get_ok_match(), hl78xx_get_ok_match_size(), + MDM_CMD_TIMEOUT, false); if (ret < 0) { goto error; } #ifdef CONFIG_MODEM_HL78XX_AIRVANTAGE ret = modem_dynamic_cmd_send(data, NULL, "AT+WDSS=2,1", strlen("AT+WDSS=2,1"), - hl78xx_get_ok_match(), 1, false); + hl78xx_get_ok_match(), hl78xx_get_ok_match_size(), + MDM_CMD_TIMEOUT, false); if (ret < 0) { goto error; } @@ -245,7 +251,8 @@ int hl78xx_gsm_pdp_activate(struct hl78xx_data *data) } ret = modem_dynamic_cmd_send(data, NULL, cmd_activate_pdp, strlen(cmd_activate_pdp), - hl78xx_get_ok_match(), 1, false); + hl78xx_get_ok_match(), hl78xx_get_ok_match_size(), + MDM_CMD_TIMEOUT, false); if (ret < 0) { LOG_ERR("GSM PDP activation failed: %d", ret); return ret; diff --git a/drivers/modem/hl78xx/hl78xx_chat.c b/drivers/modem/hl78xx/hl78xx_chat.c index a52ce1792743..8ca45f2d5424 100644 --- a/drivers/modem/hl78xx/hl78xx_chat.c +++ b/drivers/modem/hl78xx/hl78xx_chat.c @@ -74,7 +74,8 @@ void hl78xx_on_wdsi(struct modem_chat *chat, char **argv, uint16_t argc, void *u #endif /* CONFIG_MODEM_HL78XX_AIRVANTAGE */ MODEM_CHAT_MATCH_DEFINE(hl78xx_ok_match, "OK", "", NULL); MODEM_CHAT_MATCHES_DEFINE(hl78xx_allow_match, MODEM_CHAT_MATCH("OK", "", NULL), - MODEM_CHAT_MATCH(CME_ERROR_STRING, "", NULL)); + MODEM_CHAT_MATCH(CME_ERROR_STRING, "", NULL), + MODEM_CHAT_MATCH(ERROR_STRING, "", NULL)); /* clang-format off */ MODEM_CHAT_MATCHES_DEFINE(hl78xx_unsol_matches, MODEM_CHAT_MATCH("+KSUP: ", "", hl78xx_on_ksup), @@ -250,18 +251,17 @@ MODEM_CHAT_SCRIPT_DEFINE(hl78xx_fota_install_accept_script, hl78xx_fota_install_ * definitions. */ MODEM_CHAT_MATCHES_DEFINE(connect_matches, MODEM_CHAT_MATCH(CONNECT_STRING, "", NULL), - MODEM_CHAT_MATCH(CME_ERROR_STRING, "", NULL)); -MODEM_CHAT_MATCH_DEFINE(kudpind_match, "+KUDP_IND: ", ",", hl78xx_on_kudpsocket_create); + MODEM_CHAT_MATCH(CME_ERROR_STRING, "", NULL), + MODEM_CHAT_MATCH(ERROR_STRING, "", NULL), ); +MODEM_CHAT_MATCHES_DEFINE(kudpind_allow_match, + MODEM_CHAT_MATCH("+KUDP_IND: ", ",", hl78xx_on_kudpsocket_create), + MODEM_CHAT_MATCH(CME_ERROR_STRING, "", NULL), + MODEM_CHAT_MATCH(ERROR_STRING, "", NULL), ); MODEM_CHAT_MATCH_DEFINE(ktcpind_match, "+KTCP_IND: ", ",", hl78xx_on_ktcpind); MODEM_CHAT_MATCH_DEFINE(ktcpcfg_match, "+KTCPCFG: ", "", hl78xx_on_ktcpsocket_create); MODEM_CHAT_MATCH_DEFINE(cgdcontrdp_match, "+CGCONTRDP: ", ",", hl78xx_on_cgdcontrdp); MODEM_CHAT_MATCH_DEFINE(ktcp_state_match, "+KTCPSTAT: ", ",", NULL); -const struct modem_chat_match *hl78xx_get_sockets_ok_match(void) -{ - return &hl78xx_ok_match; -} - const struct modem_chat_match *hl78xx_get_connect_matches(void) { return connect_matches; @@ -284,7 +284,12 @@ size_t hl78xx_get_sockets_allow_matches_size(void) const struct modem_chat_match *hl78xx_get_kudpind_match(void) { - return &kudpind_match; + return kudpind_allow_match; +} + +size_t hl78xx_get_kudpind_allow_matches_size(void) +{ + return (size_t)ARRAY_SIZE(kudpind_allow_match); } const struct modem_chat_match *hl78xx_get_ktcpind_match(void) @@ -331,6 +336,11 @@ const struct modem_chat_match *hl78xx_get_ok_match(void) return &hl78xx_ok_match; } +size_t hl78xx_get_ok_match_size(void) +{ + return 1; +} + const struct modem_chat_match *hl78xx_get_abort_matches(void) { return hl78xx_abort_matches; diff --git a/drivers/modem/hl78xx/hl78xx_chat.h b/drivers/modem/hl78xx/hl78xx_chat.h index 5d679e1d215a..490663d66d7b 100644 --- a/drivers/modem/hl78xx/hl78xx_chat.h +++ b/drivers/modem/hl78xx/hl78xx_chat.h @@ -33,6 +33,7 @@ void hl78xx_chat_callback_handler(struct modem_chat *chat, enum modem_chat_scrip */ const struct modem_chat_match *hl78xx_get_at_ready_match(void); const struct modem_chat_match *hl78xx_get_ok_match(void); +size_t hl78xx_get_ok_match_size(void); const struct modem_chat_match *hl78xx_get_abort_matches(void); const struct modem_chat_match *hl78xx_get_unsol_matches(void); size_t hl78xx_get_unsol_matches_size(void); @@ -69,12 +70,12 @@ int hl78xx_run_periodic_script_async(struct hl78xx_data *data); const struct modem_chat_match *hl78xx_get_ksrat_match(void); /* Socket-related chat matches used by the sockets TU */ -const struct modem_chat_match *hl78xx_get_sockets_ok_match(void); const struct modem_chat_match *hl78xx_get_connect_matches(void); size_t hl78xx_get_connect_matches_size(void); const struct modem_chat_match *hl78xx_get_sockets_allow_matches(void); size_t hl78xx_get_sockets_allow_matches_size(void); const struct modem_chat_match *hl78xx_get_kudpind_match(void); +size_t hl78xx_get_kudpind_allow_matches_size(void); const struct modem_chat_match *hl78xx_get_ktcpind_match(void); const struct modem_chat_match *hl78xx_get_ktcpcfg_match(void); const struct modem_chat_match *hl78xx_get_cgdcontrdp_match(void); diff --git a/drivers/modem/hl78xx/hl78xx_sockets.c b/drivers/modem/hl78xx/hl78xx_sockets.c index 88c46d0ad9c3..bd61aac8e095 100644 --- a/drivers/modem/hl78xx/hl78xx_sockets.c +++ b/drivers/modem/hl78xx/hl78xx_sockets.c @@ -1430,7 +1430,7 @@ static int send_udp_config(const struct net_sockaddr *addr, struct hl78xx_socket (addr->sa_family - 1), 0); ret = modem_dynamic_cmd_send(socket_data->mdata_global, NULL, cmd_buf, strlen(cmd_buf), - hl78xx_get_kudpind_match(), 1, false); + hl78xx_get_kudpind_match(), hl78xx_get_kudpind_allow_matches_size(), MDM_CMD_TIMEOUT_MS, false); if (ret < 0) { goto error; } @@ -1998,9 +1998,8 @@ static int transmit_regular_data(struct hl78xx_socket_data *socket_data, const c /* send binary data via the +KUDPSND/+KTCPSND commands */ static ssize_t send_socket_data(void *obj, struct hl78xx_socket_data *socket_data, - const struct net_sockaddr *dst_addr, - const char *buf, size_t buf_len, - k_timeout_t timeout) + const struct net_sockaddr *dst_addr, const char *buf, + size_t buf_len, k_timeout_t timeout) { struct modem_socket *sock = (struct modem_socket *)obj; char cmd_buf[82] = {0}; /* AT+KUDPSND/KTCP=,IP,PORT,LENGTH */ @@ -2030,8 +2029,8 @@ static ssize_t send_socket_data(void *obj, struct hl78xx_socket_data *socket_dat goto cleanup; } modem_chat_attach(&socket_data->mdata_global->chat, socket_data->mdata_global->uart_pipe); - ret = modem_dynamic_cmd_send(socket_data->mdata_global, NULL, "", 0, - hl78xx_get_sockets_ok_match(), 1, false); + ret = modem_dynamic_cmd_send(socket_data->mdata_global, NULL, "", 0, hl78xx_get_ok_match(), + hl78xx_get_ok_match_size(), MDM_CMD_TIMEOUT, false); if (ret < 0) { LOG_ERR("Final confirmation failed: %d", ret); goto cleanup; @@ -2373,9 +2372,10 @@ static int hl78xx_configure_chipper_suit(struct hl78xx_socket_data *socket_data) { const char *cmd_chipper_suit = "AT+KSSLCRYPTO=0,8,1,8192,4,4,3,0"; - return modem_dynamic_cmd_send( - socket_data->mdata_global, NULL, cmd_chipper_suit, strlen(cmd_chipper_suit), - (const struct modem_chat_match *)hl78xx_get_ok_match(), 1, false); + return modem_dynamic_cmd_send(socket_data->mdata_global, NULL, cmd_chipper_suit, + strlen(cmd_chipper_suit), + (const struct modem_chat_match *)hl78xx_get_ok_match(), + hl78xx_get_ok_match_size(), MDM_CMD_TIMEOUT, false); } /* send binary data via the K....STORE commands */ static ssize_t hl78xx_send_cert(struct hl78xx_socket_data *socket_data, const char *cert_data, @@ -2444,8 +2444,8 @@ static ssize_t hl78xx_send_cert(struct hl78xx_socket_data *socket_data, const ch } modem_chat_attach(&socket_data->mdata_global->chat, socket_data->mdata_global->uart_pipe); ret = modem_dynamic_cmd_send(socket_data->mdata_global, NULL, "", 0, - (const struct modem_chat_match *)hl78xx_get_ok_match(), 1, - false); + (const struct modem_chat_match *)hl78xx_get_ok_match(), + hl78xx_get_ok_match_size(), MDM_CMD_TIMEOUT, false); if (ret < 0) { LOG_ERR("Final confirmation failed: %d", ret); goto cleanup; From 53f3e0c5a0dd9bf1d525e68e586d4f03fa91d976 Mon Sep 17 00:00:00 2001 From: Zafer SEN Date: Sat, 6 Dec 2025 02:25:35 +0000 Subject: [PATCH 1416/3659] drivers: modem: hl78xx: support per-command timeout in send API Extend modem_dynamic_cmd_send() with a response_timeout parameter to allow callers to specify the overall script timeout per command. The previously hardcoded 1000 ms timeout is removed (set to 0 in params) and the script timeout is now driven by the passed-in value. Update all internal call sites to provide MDM_CMD_TIMEOUT (in seconds) and increase the default command timeout from 10 s to 40 s. Several chat scripts and configuration paths are updated accordingly. This improves reliability for long-running HL78xx operations and ensures consistent timeout handling across sockets, RAT/band configuration, APN setup, PDP activation, AirVantage DM session control, and TLS/TCP/UDP socket management. Signed-off-by: Zafer SEN --- drivers/modem/hl78xx/hl78xx.c | 6 +++--- drivers/modem/hl78xx/hl78xx.h | 9 ++++++--- drivers/modem/hl78xx/hl78xx_apis.c | 4 ++-- drivers/modem/hl78xx/hl78xx_cfg.c | 2 +- drivers/modem/hl78xx/hl78xx_chat.c | 2 +- drivers/modem/hl78xx/hl78xx_sockets.c | 22 +++++++++++++--------- 6 files changed, 26 insertions(+), 19 deletions(-) diff --git a/drivers/modem/hl78xx/hl78xx.c b/drivers/modem/hl78xx/hl78xx.c index df4f1ae946c1..85343f389a50 100644 --- a/drivers/modem/hl78xx/hl78xx.c +++ b/drivers/modem/hl78xx/hl78xx.c @@ -768,7 +768,7 @@ int modem_dynamic_cmd_send( modem_chat_script_callback script_user_callback, const uint8_t *cmd, uint16_t cmd_size, const struct modem_chat_match *response_matches, uint16_t matches_size, - bool user_cmd + uint16_t response_timeout, bool user_cmd ) { int ret = 0; @@ -784,7 +784,7 @@ int modem_dynamic_cmd_send( .request_size = cmd_size, .response_matches = response_matches, .response_matches_size = matches_size, - .timeout = 1000, + .timeout = 0, /* Has no effect */ }; struct modem_chat_script chat_script = { .name = "dynamic_script", @@ -793,7 +793,7 @@ int modem_dynamic_cmd_send( .abort_matches = hl78xx_get_abort_matches(), .abort_matches_size = hl78xx_get_abort_matches_size(), .callback = script_user_callback, - .timeout = 1000 + .timeout = response_timeout, /* overall script timeout */ }; ret = k_mutex_lock(&data->tx_lock, K_NO_WAIT); diff --git a/drivers/modem/hl78xx/hl78xx.h b/drivers/modem/hl78xx/hl78xx.h index 23330ddb3957..2018e2c05521 100644 --- a/drivers/modem/hl78xx/hl78xx.h +++ b/drivers/modem/hl78xx/hl78xx.h @@ -25,8 +25,8 @@ #include "../modem_context.h" #include "../modem_socket.h" #include - -#define MDM_CMD_TIMEOUT (10) /*K_SECONDS*/ +/* clang-format off */ +#define MDM_CMD_TIMEOUT (40) /*K_SECONDS*/ #define MDM_DNS_TIMEOUT (70) /*K_SECONDS*/ #define MDM_CELL_BAND_SEARCH_TIMEOUT (60) /*K_SECONDS*/ #define MDM_CMD_CONN_TIMEOUT (120) /*K_SECONDS*/ @@ -123,6 +123,8 @@ (LOG_DBG(str, ##__VA_ARGS__)), \ ((void)0)) +/* clang-format on */ + /* HL78XX States */ enum hl78xx_state { MODEM_HL78XX_STATE_IDLE = 0, @@ -473,13 +475,14 @@ void iface_status_work_cb(struct hl78xx_data *data, * @param cmd_len Length of the command in bytes. * @param response_matches Array of expected response match patterns. * @param matches_size Number of elements in the response_matches array. + * @param response_timeout Response timeout in seconds. * * @return 0 on success, negative errno code on failure. */ int modem_dynamic_cmd_send(struct hl78xx_data *data, modem_chat_script_callback script_user_callback, const uint8_t *cmd, uint16_t cmd_len, const struct modem_chat_match *response_matches, - uint16_t matches_size, bool user_cmd); + uint16_t matches_size, uint16_t response_timeout, bool user_cmd); #define HASH_MULTIPLIER 37 /** diff --git a/drivers/modem/hl78xx/hl78xx_apis.c b/drivers/modem/hl78xx/hl78xx_apis.c index dcb52778655d..5d2e11fe5c14 100644 --- a/drivers/modem/hl78xx/hl78xx_apis.c +++ b/drivers/modem/hl78xx/hl78xx_apis.c @@ -28,7 +28,7 @@ static int hl78xx_send_cmd(struct hl78xx_data *data, const char *cmd, return -EINVAL; } return modem_dynamic_cmd_send(data, chat_cb, cmd, (uint16_t)strlen(cmd), matches, - match_count, true); + match_count, MDM_CMD_TIMEOUT, true); } int hl78xx_api_func_get_signal(const struct device *dev, const enum cellular_signal_type type, @@ -292,7 +292,7 @@ int hl78xx_api_func_modem_dynamic_cmd_send(const struct device *dev, const char } /* respect provided matches_size and serialize modem access */ return modem_dynamic_cmd_send(data, NULL, cmd, cmd_size, response_matches, matches_size, - true); + MDM_CMD_TIMEOUT, true); } #ifdef CONFIG_MODEM_HL78XX_AIRVANTAGE int hl78xx_start_airvantage_dm_session(const struct device *dev) diff --git a/drivers/modem/hl78xx/hl78xx_cfg.c b/drivers/modem/hl78xx/hl78xx_cfg.c index 99c3a62dfe11..56b3be676dd2 100644 --- a/drivers/modem/hl78xx/hl78xx_cfg.c +++ b/drivers/modem/hl78xx/hl78xx_cfg.c @@ -61,7 +61,7 @@ int hl78xx_rat_cfg(struct hl78xx_data *data, bool *modem_require_restart, } /* Query current rat */ ret = modem_dynamic_cmd_send(data, NULL, cmd_ksrat_query, strlen(cmd_ksrat_query), - hl78xx_get_ksrat_match(), 1, false); + hl78xx_get_ksrat_match(), 1, MDM_CMD_TIMEOUT, false); if (ret < 0) { goto error; } diff --git a/drivers/modem/hl78xx/hl78xx_chat.c b/drivers/modem/hl78xx/hl78xx_chat.c index 8ca45f2d5424..d120eefc2a1e 100644 --- a/drivers/modem/hl78xx/hl78xx_chat.c +++ b/drivers/modem/hl78xx/hl78xx_chat.c @@ -186,7 +186,7 @@ MODEM_CHAT_SCRIPT_CMDS_DEFINE(hl78xx_post_restart_chat_script_cmds, ); MODEM_CHAT_SCRIPT_DEFINE(hl78xx_post_restart_chat_script, hl78xx_post_restart_chat_script_cmds, - hl78xx_abort_matches, hl78xx_chat_callback_handler, 1000); + hl78xx_abort_matches, hl78xx_chat_callback_handler, 12); /* init_fail_script moved from hl78xx.c */ MODEM_CHAT_SCRIPT_CMDS_DEFINE(init_fail_script_cmds, diff --git a/drivers/modem/hl78xx/hl78xx_sockets.c b/drivers/modem/hl78xx/hl78xx_sockets.c index bd61aac8e095..2095e5e59176 100644 --- a/drivers/modem/hl78xx/hl78xx_sockets.c +++ b/drivers/modem/hl78xx/hl78xx_sockets.c @@ -1179,7 +1179,7 @@ void iface_status_work_cb(struct hl78xx_data *data, modem_chat_script_callback s int ret = 0; ret = modem_dynamic_cmd_send(data, script_user_callback, cmd, strlen(cmd), - hl78xx_get_cgdcontrdp_match(), 1, false); + hl78xx_get_cgdcontrdp_match(), 1, MDM_CMD_TIMEOUT, false); if (ret < 0) { LOG_ERR("Failed to send AT+CGCONTRDP command: %d", ret); return; @@ -1402,7 +1402,7 @@ static int send_tcp_or_tls_config(struct modem_socket *sock, uint16_t dst_port, snprintk(cmd_buf, sizeof(cmd_buf), "AT+KTCPCFG=1,%d,\"%s\",%u,,,,%d,%s,0", mode, socket_data->tls.hostname, dst_port, af, mode == 3 ? "0" : ""); ret = modem_dynamic_cmd_send(socket_data->mdata_global, NULL, cmd_buf, strlen(cmd_buf), - hl78xx_get_ktcpcfg_match(), 1, false); + hl78xx_get_ktcpcfg_match(), 1, MDM_CMD_TIMEOUT, false); if (ret < 0 || socket_data->tcp_conn_status[HL78XX_TCP_STATUS_ID(sock->id)].is_created == false) { LOG_ERR("%s ret:%d", cmd_buf, ret); @@ -1430,7 +1430,9 @@ static int send_udp_config(const struct net_sockaddr *addr, struct hl78xx_socket (addr->sa_family - 1), 0); ret = modem_dynamic_cmd_send(socket_data->mdata_global, NULL, cmd_buf, strlen(cmd_buf), - hl78xx_get_kudpind_match(), hl78xx_get_kudpind_allow_matches_size(), MDM_CMD_TIMEOUT_MS, false); + hl78xx_get_kudpind_match(), + hl78xx_get_kudpind_allow_matches_size(), MDM_CMD_TIMEOUT, + false); if (ret < 0) { goto error; } @@ -1493,7 +1495,8 @@ static int socket_close(struct hl78xx_socket_data *socket_data, struct modem_soc } ret = modem_dynamic_cmd_send(socket_data->mdata_global, NULL, buf, strlen(buf), hl78xx_get_sockets_allow_matches(), - hl78xx_get_sockets_allow_matches_size(), false); + hl78xx_get_sockets_allow_matches_size(), MDM_CMD_TIMEOUT, + false); if (ret < 0) { LOG_ERR("%s ret:%d", buf, ret); } @@ -1516,7 +1519,8 @@ static int socket_delete(struct hl78xx_socket_data *socket_data, struct modem_so snprintk(buf, sizeof(buf), "AT+KTCPDEL=%d", sock->id); ret = modem_dynamic_cmd_send(socket_data->mdata_global, NULL, buf, strlen(buf), hl78xx_get_sockets_allow_matches(), - hl78xx_get_sockets_allow_matches_size(), false); + hl78xx_get_sockets_allow_matches_size(), MDM_CMD_TIMEOUT, + false); if (ret < 0) { LOG_ERR("%s ret:%d", buf, ret); } @@ -1649,7 +1653,7 @@ static int offload_connect(void *obj, const struct net_sockaddr *addr, net_sockl /* send connect command */ snprintk(cmd_buf, sizeof(cmd_buf), "AT+KTCPCNX=%d", sock->id); ret = modem_dynamic_cmd_send(socket_data->mdata_global, NULL, cmd_buf, strlen(cmd_buf), - hl78xx_get_ktcpind_match(), 1, false); + hl78xx_get_ktcpind_match(), 1, MDM_CMD_TIMEOUT, false); if (ret < 0 || socket_data->tcp_conn_status[HL78XX_TCP_STATUS_ID(sock->id)].is_connected == false) { sock->is_connected = false; @@ -1784,7 +1788,7 @@ static void check_tcp_state_if_needed(struct hl78xx_socket_data *socket_data, sock && sock->ip_proto == NET_IPPROTO_TCP) { modem_dynamic_cmd_send(socket_data->mdata_global, NULL, check_ktcp_stat, strlen(check_ktcp_stat), hl78xx_get_ktcp_state_match(), 1, - true); + MDM_CMD_TIMEOUT, true); } } @@ -2016,7 +2020,7 @@ static ssize_t send_socket_data(void *obj, struct hl78xx_socket_data *socket_dat } ret = modem_dynamic_cmd_send(socket_data->mdata_global, NULL, cmd_buf, strlen(cmd_buf), (const struct modem_chat_match *)hl78xx_get_connect_matches(), - hl78xx_get_connect_matches_size(), false); + hl78xx_get_connect_matches_size(), MDM_CMD_TIMEOUT, false); if (ret < 0 || socket_data->socket_data_error) { hl78xx_set_errno_from_code(ret); ret = -1; @@ -2417,7 +2421,7 @@ static ssize_t hl78xx_send_cert(struct hl78xx_socket_data *socket_data, const ch } ret = modem_dynamic_cmd_send(socket_data->mdata_global, NULL, send_buf, strlen(send_buf), (const struct modem_chat_match *)hl78xx_get_connect_matches(), - hl78xx_get_connect_matches_size(), false); + hl78xx_get_connect_matches_size(), MDM_CMD_TIMEOUT, false); if (ret < 0) { LOG_ERR("Error sending AT command %d", ret); } From 6a402b8659d4d8fbfb9f46fcb9d42e1aea504a77 Mon Sep 17 00:00:00 2001 From: Zafer SEN Date: Sat, 6 Dec 2025 02:31:14 +0000 Subject: [PATCH 1417/3659] drivers: modem: hl78xx: add AT command timeout event and handlers Add MODEM_HL78XX_EVENT_AT_CMD_TIMEOUT event to distinguish chat scripts timeouts from other script failures. The chat callback now maps MODEM_CHAT_SCRIPT_RESULT_TIMEOUT to this new event. Update state handlers so AT command timeouts trigger the init fail diagnostic script during startup, and fall back to the power-on pulse in the init-fail state, similar to existing timeout handling. This improves error classification and enables more accurate recovery logic for long-running or stalled AT command exchanges. Signed-off-by: Zafer SEN --- drivers/modem/hl78xx/hl78xx.c | 7 +++++++ drivers/modem/hl78xx/hl78xx_chat.c | 2 ++ 2 files changed, 9 insertions(+) diff --git a/drivers/modem/hl78xx/hl78xx.c b/drivers/modem/hl78xx/hl78xx.c index 85343f389a50..8ebed2f39002 100644 --- a/drivers/modem/hl78xx/hl78xx.c +++ b/drivers/modem/hl78xx/hl78xx.c @@ -176,6 +176,8 @@ static const char *hl78xx_event_str(enum hl78xx_event event) #endif /* CONFIG_MODEM_HL78XX_AIRVANTAGE */ case MODEM_HL78XX_EVENT_MDM_RESTART: return "modem unexpected restart"; + case MODEM_HL78XX_EVENT_AT_CMD_TIMEOUT: + return "AT command timeout"; default: return "unknown event"; } @@ -1022,6 +1024,10 @@ static void hl78xx_await_power_on_event_handler(struct hl78xx_data *data, enum h hl78xx_enter_state(data, MODEM_HL78XX_STATE_RUN_INIT_SCRIPT); break; + case MODEM_HL78XX_EVENT_AT_CMD_TIMEOUT: + hl78xx_enter_state(data, MODEM_HL78XX_STATE_RUN_INIT_FAIL_DIAGNOSTIC_SCRIPT); + break; + default: break; } @@ -1077,6 +1083,7 @@ static void hl78xx_run_init_fail_script_event_handler(struct hl78xx_data *data, } break; case MODEM_HL78XX_EVENT_TIMEOUT: + case MODEM_HL78XX_EVENT_AT_CMD_TIMEOUT: if (hl78xx_gpio_is_enabled(&config->mdm_gpio_pwr_on)) { hl78xx_enter_state(data, MODEM_HL78XX_STATE_POWER_ON_PULSE); break; diff --git a/drivers/modem/hl78xx/hl78xx_chat.c b/drivers/modem/hl78xx/hl78xx_chat.c index d120eefc2a1e..436025a48ee8 100644 --- a/drivers/modem/hl78xx/hl78xx_chat.c +++ b/drivers/modem/hl78xx/hl78xx_chat.c @@ -325,6 +325,8 @@ void hl78xx_chat_callback_handler(struct modem_chat *chat, enum modem_chat_scrip if (result == MODEM_CHAT_SCRIPT_RESULT_SUCCESS) { hl78xx_delegate_event(data, MODEM_HL78XX_EVENT_SCRIPT_SUCCESS); + } else if (result == MODEM_CHAT_SCRIPT_RESULT_TIMEOUT) { + hl78xx_delegate_event(data, MODEM_HL78XX_EVENT_AT_CMD_TIMEOUT); } else { hl78xx_delegate_event(data, MODEM_HL78XX_EVENT_SCRIPT_FAILED); } From 9e2bdfb09ce1183b11a9f55838941d8806ebc649 Mon Sep 17 00:00:00 2001 From: Zafer SEN Date: Sat, 6 Dec 2025 02:33:16 +0000 Subject: [PATCH 1418/3659] drivers: modem: hl78xx: add optional auto-baudrate detection and switching This adds an optional auto-baudrate mechanism that improves robustness when the modem boots with an unknown or changed UART speed. Key additions: * New Kconfig option MODEM_HL78XX_AUTO_BAUDRATE and related settings: - selectable target baud rate - detection baudrate list - detection timeout and retry count - option to persist AT+IPR updates - option to start diagnostics or boot directly with auto-baud logic * UART status tracking added to hl78xx_data, including current and target baud rates * New HL78XX_MODEM_INFO_CURRENT_BAUD_RATE info field * New MODEM_HL78XX_STATE_SET_BAUDRATE state with detection and switching logic * Chat, init, and diagnostic handlers updated to route failures into the auto-baudrate logic when enabled * New helpers: hl78xx_get_uart_config(), hl78xx_try_baudrate(), hl78xx_detect_current_baudrate(), hl78xx_switch_baudrate() * Startup delay increased when auto-baudrate-at-boot is enabled These changes allow the driver to recover from unexpected modem UART rate changes and keep the UART configuration synchronized with the modem. Signed-off-by: Zafer SEN --- drivers/modem/hl78xx/Kconfig.hl78xx | 143 ++++++++++++++- drivers/modem/hl78xx/hl78xx.c | 111 +++++++++++- drivers/modem/hl78xx/hl78xx.h | 12 ++ drivers/modem/hl78xx/hl78xx_apis.c | 3 + drivers/modem/hl78xx/hl78xx_cfg.c | 193 +++++++++++++++++++++ drivers/modem/hl78xx/hl78xx_cfg.h | 10 ++ drivers/modem/hl78xx/hl78xx_chat.c | 4 +- include/zephyr/drivers/modem/hl78xx_apis.h | 2 + 8 files changed, 473 insertions(+), 5 deletions(-) diff --git a/drivers/modem/hl78xx/Kconfig.hl78xx b/drivers/modem/hl78xx/Kconfig.hl78xx index 54cb90a3ccfe..335f48a76c59 100644 --- a/drivers/modem/hl78xx/Kconfig.hl78xx +++ b/drivers/modem/hl78xx/Kconfig.hl78xx @@ -78,6 +78,143 @@ config MODEM_AT_SHELL_RESPONSE_MAX_SIZE endif # MODEM_HL78XX_AT_SHELL +menuconfig MODEM_HL78XX_AUTO_BAUDRATE + bool "Auto Baud Rate Detection and Switching" + select UART_USE_RUNTIME_CONFIGURE if SOC_SERIES_NRF52X + help + Enable automatic baud rate detection and switching for the HL78xx modem. + The driver will attempt to detect the modem's current baud rate and + switch to the configured target baud rate using AT+IPR command. + +if MODEM_HL78XX_AUTO_BAUDRATE + +choice MODEM_HL78XX_TARGET_BAUDRATE + prompt "Target UART Baud Rate" + default MODEM_HL78XX_TARGET_BAUDRATE_115200 + help + Select the target baud rate for communication with the modem. + The driver will configure the modem to use this baud rate after detection. + +config MODEM_HL78XX_TARGET_BAUDRATE_9600 + bool "9600" + help + Set modem baud rate to 9600 bps + +config MODEM_HL78XX_TARGET_BAUDRATE_19200 + bool "19200" + help + Set modem baud rate to 19200 bps + +config MODEM_HL78XX_TARGET_BAUDRATE_38400 + bool "38400" + help + Set modem baud rate to 38400 bps + +config MODEM_HL78XX_TARGET_BAUDRATE_57600 + bool "57600" + help + Set modem baud rate to 57600 bps + +config MODEM_HL78XX_TARGET_BAUDRATE_115200 + bool "115200" + help + Set modem baud rate to 115200 bps (default) + +config MODEM_HL78XX_TARGET_BAUDRATE_230400 + bool "230400" + help + Set modem baud rate to 230400 bps + +config MODEM_HL78XX_TARGET_BAUDRATE_460800 + bool "460800" + help + Set modem baud rate to 460800 bps + +config MODEM_HL78XX_TARGET_BAUDRATE_921600 + bool "921600" + help + Set modem baud rate to 921600 bps + +config MODEM_HL78XX_TARGET_BAUDRATE_3000000 + bool "3000000" + depends on MODEM_HL78XX_12 + help + Set modem baud rate to 3000000 bps +endchoice + +config MODEM_HL78XX_TARGET_BAUDRATE_VALUE + int + default 9600 if MODEM_HL78XX_TARGET_BAUDRATE_9600 + default 19200 if MODEM_HL78XX_TARGET_BAUDRATE_19200 + default 38400 if MODEM_HL78XX_TARGET_BAUDRATE_38400 + default 57600 if MODEM_HL78XX_TARGET_BAUDRATE_57600 + default 115200 if MODEM_HL78XX_TARGET_BAUDRATE_115200 + default 230400 if MODEM_HL78XX_TARGET_BAUDRATE_230400 + default 460800 if MODEM_HL78XX_TARGET_BAUDRATE_460800 + default 921600 if MODEM_HL78XX_TARGET_BAUDRATE_921600 + default 3000000 if MODEM_HL78XX_TARGET_BAUDRATE_3000000 + +config MODEM_HL78XX_AUTOBAUD_DETECTION_BAUDRATES + string "Baud rates to try during auto-detection (comma-separated)" + default "115200,9600,57600,38400,19200" + help + Comma-separated list of baud rates to try when auto-detecting + the modem's current baud rate. The driver will try each rate + in order until it successfully communicates with the modem. + Common baud rates: 9600, 19200, 38400, 57600, 115200 + +config MODEM_HL78XX_AUTOBAUD_TIMEOUT + int "Timeout for each baud rate detection attempt (seconds)" + default 4 + range 1 120 + help + Maximum time to wait for a response from the modem when trying + a specific baud rate during auto-detection. + +config MODEM_HL78XX_AUTOBAUD_RETRY_COUNT + int "Number of retries for baud rate detection" + default 3 + range 1 10 + help + Number of times to retry baud rate detection before giving up. + +config MODEM_HL78XX_AUTOBAUD_CHANGE_PERSISTENT + bool "Save detected baud rate persistently" + default y + help + Enable this option to save the configuration to the modem non-volatile memory, + otherwise it will revert to previous setting on power cycle. + Highly recommended to enable this option to detect unexpected modem reboots + and quick recovery. + + Baudrate change will be permanent across power cycles. + NOTE: Changing phone functionality (AT+CFUN) does reset baud rate to default. + +config MODEM_HL78XX_AUTOBAUD_START_WITH_TARGET_BAUDRATE + bool "Start auto baud rate detection with target baud rate" + default y + help + Enable this option to start the auto baud rate detection process + by first attempting communication at the configured target baud rate. + This can speed up detection if the modem is already set to the target rate. + +config MODEM_HL78XX_AUTOBAUD_ONLY_IF_COMMS_FAIL + bool "Only perform auto baud rate detection on communication failure" + default y + help + Enable this option to perform auto baud rate detection only + if initial uart communication with the modem at the configured + target baud rate fails. + +config MODEM_HL78XX_AUTOBAUD_AT_BOOT + bool "Perform auto baud rate detection at boot (skip KSUP wait)" + help + When enabled, the driver will immediately perform auto baud rate detection + as soon as the modem is powered up, without waiting for the KSUP URC + (startup ready indication). + +endif # MODEM_HL78XX_AUTO_BAUDRATE + choice MODEM_HL78XX_ADDRESS_FAMILY prompt "IP Address family" default MODEM_HL78XX_ADDRESS_FAMILY_IPV4V6 @@ -874,13 +1011,17 @@ config MODEM_HL78XX_DEV_RESET_PULSE_DURATION_MS config MODEM_HL78XX_DEV_STARTUP_TIME_MS int "Wait before assuming the device is ready." - default 120 + default 2000 if MODEM_HL78XX_AUTOBAUD_AT_BOOT + default 120 if !MODEM_HL78XX_AUTOBAUD_AT_BOOT help The expected delay time (in milliseconds) the modem needs to fully power on and become operational.This delay before the driver opens the UART pipe and attaches the chat layer. The value must be long enough for the driver startup code to initialize, but short enough to ensure the pipe is ready before the modem sends its first URCs during boot. + BUT, + if auto baudrate detection at boot is enabled, + a longer delay is recommended to allow the modem to complete its boot sequence. config MODEM_HL78XX_DEV_SHUTDOWN_TIME_MS int "Wait before assuming the device is completely off." diff --git a/drivers/modem/hl78xx/hl78xx.c b/drivers/modem/hl78xx/hl78xx.c index 8ebed2f39002..49cebbb3aa99 100644 --- a/drivers/modem/hl78xx/hl78xx.c +++ b/drivers/modem/hl78xx/hl78xx.c @@ -1017,13 +1017,31 @@ static void hl78xx_await_power_on_event_handler(struct hl78xx_data *data, enum h case MODEM_HL78XX_EVENT_BUS_OPENED: modem_chat_attach(&data->chat, data->uart_pipe); +#ifdef CONFIG_MODEM_HL78XX_AUTOBAUD_AT_BOOT + hl78xx_enter_state(data, MODEM_HL78XX_STATE_SET_BAUDRATE); +#else hl78xx_run_post_restart_script_async(data); +#endif /* CONFIG_MODEM_HL78XX_AUTOBAUD_AT_BOOT */ break; case MODEM_HL78XX_EVENT_SCRIPT_SUCCESS: + (void)hl78xx_get_uart_config(data); + LOG_DBG("Current baudrate after post-restart script: %d", + data->status.uart.current_baudrate); +#if defined(CONFIG_MODEM_HL78XX_AUTOBAUD_ONLY_IF_COMMS_FAIL) || \ + !defined(CONFIG_MODEM_HL78XX_AUTO_BAUDRATE) hl78xx_enter_state(data, MODEM_HL78XX_STATE_RUN_INIT_SCRIPT); +#else + hl78xx_enter_state(data, MODEM_HL78XX_STATE_SET_BAUDRATE); +#endif /* CONFIG_MODEM_HL78XX_AUTOBAUD_ONLY_IF_COMMS_FAIL */ break; + case MODEM_HL78XX_EVENT_SCRIPT_FAILED: +#ifdef CONFIG_MODEM_HL78XX_AUTO_BAUDRATE + hl78xx_enter_state(data, MODEM_HL78XX_STATE_SET_BAUDRATE); +#else + hl78xx_enter_state(data, MODEM_HL78XX_STATE_RUN_INIT_FAIL_DIAGNOSTIC_SCRIPT); +#endif /* CONFIG_MODEM_HL78XX_AUTO_BAUDRATE */ case MODEM_HL78XX_EVENT_AT_CMD_TIMEOUT: hl78xx_enter_state(data, MODEM_HL78XX_STATE_RUN_INIT_FAIL_DIAGNOSTIC_SCRIPT); break; @@ -1032,6 +1050,71 @@ static void hl78xx_await_power_on_event_handler(struct hl78xx_data *data, enum h break; } } + +#ifdef CONFIG_MODEM_HL78XX_AUTO_BAUDRATE +static int hl78xx_on_set_baudrate_state_enter(struct hl78xx_data *data) +{ + int ret; + + data->status.uart.target_baudrate = CONFIG_MODEM_HL78XX_TARGET_BAUDRATE_VALUE; + + /* Detect current baud rate */ + ret = hl78xx_detect_current_baudrate(data); + if (ret < 0) { + LOG_ERR("Baud rate detection failed"); + hl78xx_delegate_event(data, MODEM_HL78XX_EVENT_SCRIPT_FAILED); + return ret; + } + + /* Switch to target baud rate if different */ + ret = hl78xx_switch_baudrate(data, data->status.uart.target_baudrate); + if (ret < 0) { + LOG_ERR("Failed to switch baud rate: %d", ret); + hl78xx_delegate_event(data, MODEM_HL78XX_EVENT_SCRIPT_FAILED); + return ret; + } + data->status.boot.is_booted_previously = true; + hl78xx_delegate_event(data, MODEM_HL78XX_EVENT_SCRIPT_SUCCESS); + return 0; +} + +static void hl78xx_set_baudrate_event_handler(struct hl78xx_data *data, enum hl78xx_event evt) +{ + switch (evt) { + case MODEM_HL78XX_EVENT_SCRIPT_SUCCESS: + hl78xx_enter_state(data, MODEM_HL78XX_STATE_RUN_INIT_SCRIPT); + break; + + case MODEM_HL78XX_EVENT_SCRIPT_FAILED: + /* Increment retry counter */ + data->status.uart.baudrate_detection_retry++; + + /* Retry detection or give up */ + if (data->status.uart.baudrate_detection_retry < + CONFIG_MODEM_HL78XX_AUTOBAUD_RETRY_COUNT) { + LOG_WRN("Retrying baud rate detection (attempt %d/%d)", + data->status.uart.baudrate_detection_retry + 1, + CONFIG_MODEM_HL78XX_AUTOBAUD_RETRY_COUNT); + k_sleep(K_MSEC(500)); + hl78xx_on_set_baudrate_state_enter(data); + } else { + LOG_ERR("Baud rate configuration failed after %d attempts", + data->status.uart.baudrate_detection_retry); + hl78xx_enter_state(data, + MODEM_HL78XX_STATE_RUN_INIT_FAIL_DIAGNOSTIC_SCRIPT); + } + break; + + case MODEM_HL78XX_EVENT_SUSPEND: + hl78xx_enter_state(data, MODEM_HL78XX_STATE_IDLE); + break; + + default: + break; + } +} +#endif /* CONFIG_MODEM_HL78XX_AUTO_BAUDRATE */ + static int hl78xx_on_run_init_script_state_enter(struct hl78xx_data *data) { return hl78xx_run_init_script_async(data); @@ -1083,7 +1166,13 @@ static void hl78xx_run_init_fail_script_event_handler(struct hl78xx_data *data, } break; case MODEM_HL78XX_EVENT_TIMEOUT: + LOG_ERR("Modem initialization failed after diagnostic script"); + hl78xx_enter_state(data, MODEM_HL78XX_STATE_IDLE); + break; case MODEM_HL78XX_EVENT_AT_CMD_TIMEOUT: +#ifdef CONFIG_MODEM_HL78XX_AUTO_BAUDRATE + hl78xx_enter_state(data, MODEM_HL78XX_STATE_SET_BAUDRATE); +#else if (hl78xx_gpio_is_enabled(&config->mdm_gpio_pwr_on)) { hl78xx_enter_state(data, MODEM_HL78XX_STATE_POWER_ON_PULSE); break; @@ -1095,6 +1184,7 @@ static void hl78xx_run_init_fail_script_event_handler(struct hl78xx_data *data, } hl78xx_enter_state(data, MODEM_HL78XX_STATE_IDLE); +#endif /* CONFIG_MODEM_HL78XX_AUTO_BAUDRATE */ break; case MODEM_HL78XX_EVENT_BUS_CLOSED: break; @@ -1169,6 +1259,12 @@ static void hl78xx_run_rat_cfg_script_event_handler(struct hl78xx_data *data, en { switch (evt) { case MODEM_HL78XX_EVENT_TIMEOUT: +#ifdef CONFIG_MODEM_HL78XX_AUTO_BAUDRATE + if (IS_ENABLED(CONFIG_MODEM_HL78XX_AUTOBAUD_CHANGE_PERSISTENT) == false) { + hl78xx_enter_state(data, MODEM_HL78XX_STATE_SET_BAUDRATE); + } + break; +#endif /* CONFIG_MODEM_HL78XX_AUTO_BAUDRATE */ LOG_DBG("Rebooting modem to apply new RAT settings"); break; case MODEM_HL78XX_EVENT_MDM_RESTART: @@ -1827,6 +1923,15 @@ static int hl78xx_init(const struct device *dev) data->buffers.eof_pattern_size = strlen(data->buffers.eof_pattern); data->buffers.termination_pattern_size = strlen(data->buffers.termination_pattern); memset(data->identity.apn, 0, MDM_APN_MAX_LENGTH); +#ifdef CONFIG_MODEM_HL78XX_AUTO_BAUDRATE + data->status.uart.current_baudrate = 0; + data->status.uart.target_baudrate = CONFIG_MODEM_HL78XX_TARGET_BAUDRATE_VALUE; + data->status.uart.baudrate_detection_retry = 0; +#ifdef CONFIG_MODEM_HL78XX_AUTOBAUD_START_WITH_TARGET_BAUDRATE + /* Update baud rate */ + configure_uart_for_auto_baudrate(data, data->status.uart.target_baudrate); +#endif /* CONFIG_MODEM_HL78XX_AUTOBAUD_START_WITH_TARGET_BAUDRATE */ +#endif /* CONFIG_MODEM_HL78XX_AUTO_BAUDRATE */ /* GPIO validation */ const struct gpio_dt_spec *gpio_pins[GPIO_CONFIG_LEN] = { #if HAS_RESET_GPIO @@ -2011,11 +2116,13 @@ const static struct hl78xx_state_handlers hl78xx_state_table[] = { NULL, hl78xx_await_power_on_event_handler }, +#ifdef CONFIG_MODEM_HL78XX_AUTO_BAUDRATE [MODEM_HL78XX_STATE_SET_BAUDRATE] = { + hl78xx_on_set_baudrate_state_enter, NULL, - NULL, - NULL + hl78xx_set_baudrate_event_handler }, +#endif /* CONFIG_MODEM_HL78XX_AUTO_BAUDRATE */ [MODEM_HL78XX_STATE_RUN_INIT_SCRIPT] = { hl78xx_on_run_init_script_state_enter, NULL, diff --git a/drivers/modem/hl78xx/hl78xx.h b/drivers/modem/hl78xx/hl78xx.h index 2018e2c05521..8b4494a5695d 100644 --- a/drivers/modem/hl78xx/hl78xx.h +++ b/drivers/modem/hl78xx/hl78xx.h @@ -113,6 +113,9 @@ */ #define WDSI_USER_INITIATED_CONNECTION_START_CMD "AT+WDSS=1,1" #define WDSI_USER_INITIATED_CONNECTION_STOP_CMD "AT+WDSS=1,0" +/* Baud rate commands */ +#define GET_BAUDRATE_CMD "AT+IPR?" +#define SET_BAUDRATE_CMD_FMT "AT+IPR=%d" /* Helper macros */ #define ATOI(s_, value_, desc_) modem_atoi(s_, value_, desc_, __func__) @@ -184,6 +187,7 @@ enum hl78xx_event { MODEM_HL78XX_EVENT_WDSI_FIRMWARE_INSTALL_SUCCEEDED, MODEM_HL78XX_EVENT_WDSI_FIRMWARE_INSTALL_FAILED, #endif /* CONFIG_MODEM_HL78XX_AIRVANTAGE */ + MODEM_HL78XX_EVENT_AT_CMD_TIMEOUT, MODEM_HL78XX_EVENT_COUNT }; @@ -325,6 +329,13 @@ struct hl78xx_wdsi_status { #endif /* CONFIG_MODEM_HL78XX_AIRVANTAGE */ +struct hl78xx_modem_uart_status { + uint32_t current_baudrate; +#ifdef CONFIG_MODEM_HL78XX_AUTO_BAUDRATE + uint32_t target_baudrate; + uint8_t baudrate_detection_retry; +#endif /* CONFIG_MODEM_HL78XX_AUTO_BAUDRATE */ +}; struct modem_status { struct registration_status registration; int16_t rssi; @@ -343,6 +354,7 @@ struct modem_status { #ifdef CONFIG_MODEM_HL78XX_AIRVANTAGE struct hl78xx_wdsi_status wdsi; #endif /* CONFIG_MODEM_HL78XX_AIRVANTAGE */ + struct hl78xx_modem_uart_status uart; }; struct modem_gpio_callbacks { diff --git a/drivers/modem/hl78xx/hl78xx_apis.c b/drivers/modem/hl78xx/hl78xx_apis.c index 5d2e11fe5c14..1424856912a5 100644 --- a/drivers/modem/hl78xx/hl78xx_apis.c +++ b/drivers/modem/hl78xx/hl78xx_apis.c @@ -179,6 +179,9 @@ int hl78xx_api_func_get_modem_info_vendor(const struct device *dev, safe_strncpy(info, (const char *)data->identity.serial_number, MIN(size, sizeof(data->identity.serial_number))); break; + case HL78XX_MODEM_INFO_CURRENT_BAUD_RATE: + *(uint32_t *)info = data->status.uart.current_baudrate; + break; default: break; } diff --git a/drivers/modem/hl78xx/hl78xx_cfg.c b/drivers/modem/hl78xx/hl78xx_cfg.c index 56b3be676dd2..ebd5d8cd96c0 100644 --- a/drivers/modem/hl78xx/hl78xx_cfg.c +++ b/drivers/modem/hl78xx/hl78xx_cfg.c @@ -21,6 +21,8 @@ LOG_MODULE_DECLARE(hl78xx_dev); #define IMSI_PREFIX_LEN 6 #define MAX_BANDS 32 #define MDM_APN_FULL_STRING_MAX_LEN 256 +/* Delay after AT+IPR command for new rate to take effect */ +#define BAUDRATE_SWITCH_DELAY_MS 2500 int hl78xx_rat_cfg(struct hl78xx_data *data, bool *modem_require_restart, enum hl78xx_cell_rat_mode *rat_request) @@ -649,3 +651,194 @@ void hl78xx_extract_essential_part_apn(const char *full_apn, char *essential_apn essential_apn[max_len - 1] = '\0'; } } + +int hl78xx_get_uart_config(struct hl78xx_data *data) +{ + const struct hl78xx_config *config = (const struct hl78xx_config *)data->dev->config; + struct uart_config uart_cfg; + int ret; + /* Get current UART configuration */ + ret = uart_config_get(config->uart, &uart_cfg); + if (ret < 0) { + LOG_ERR("Failed to get UART config: %d", ret); + return ret; + } + data->status.uart.current_baudrate = uart_cfg.baudrate; + return 0; +} + +#ifdef CONFIG_MODEM_HL78XX_AUTO_BAUDRATE + +int configure_uart_for_auto_baudrate(struct hl78xx_data *data, uint32_t baudrate) +{ + const struct hl78xx_config *config = (const struct hl78xx_config *)data->dev->config; + struct uart_config uart_cfg; + int ret; + + /* Get current UART configuration */ + ret = uart_config_get(config->uart, &uart_cfg); + if (ret < 0) { + LOG_ERR("Failed to get UART config: %d", ret); + return ret; + } + + /* Update baud rate */ + uart_cfg.baudrate = baudrate; + LOG_INF("Trying baud rate: %d", baudrate); + /* Apply new UART configuration */ + ret = uart_configure(config->uart, &uart_cfg); + if (ret < 0) { + LOG_ERR("Failed to set UART baud rate to %d: %d", baudrate, ret); + return ret; + } + + /* Give the modem time to stabilize */ + k_sleep(K_MSEC(50)); + return 0; +} + +int hl78xx_try_baudrate(struct hl78xx_data *data, uint32_t baudrate) +{ + int ret; + /* Configure UART to the target baud rate */ + ret = configure_uart_for_auto_baudrate(data, baudrate); + if (ret < 0) { + return ret; + } + /* Try to send AT command and wait for response */ + const char *test_cmd = "AT"; + + ret = modem_dynamic_cmd_send(data, NULL, test_cmd, strlen(test_cmd), + hl78xx_get_sockets_allow_matches(), + hl78xx_get_sockets_allow_matches_size(), + CONFIG_MODEM_HL78XX_AUTOBAUD_TIMEOUT, false); + + if (ret == 0) { + LOG_INF("Modem responded at %d baud", baudrate); + data->status.uart.current_baudrate = baudrate; + return 0; + } + + return -ENOENT; +} + +int hl78xx_detect_current_baudrate(struct hl78xx_data *data) +{ + const char *baudrate_list = CONFIG_MODEM_HL78XX_AUTOBAUD_DETECTION_BAUDRATES; + char baudrate_str[16]; + const char *ptr = baudrate_list; + int idx = 0; + int ret; + + LOG_INF("Starting baud rate detection..."); + + while (*ptr != '\0') { + /* Extract baud rate from string */ + while (*ptr == ' ' || *ptr == ',') { + ptr++; + } + + if (*ptr == '\0') { + break; + } + + idx = 0; + while (*ptr >= '0' && *ptr <= '9' && idx < sizeof(baudrate_str) - 1) { + baudrate_str[idx++] = *ptr++; + } + baudrate_str[idx] = '\0'; + + if (idx > 0) { + uint32_t baudrate = (uint32_t)strtol(baudrate_str, NULL, 10); + + LOG_DBG("Trying baud rate: %d", baudrate); + ret = hl78xx_try_baudrate(data, baudrate); + if (ret == 0) { + return 0; + } + } + } + + LOG_ERR("Failed to detect modem baud rate"); + return -ENOENT; +} + +int hl78xx_switch_baudrate(struct hl78xx_data *data, uint32_t target_baudrate) +{ + char cmd_buf[32]; + const struct hl78xx_config *config = (const struct hl78xx_config *)data->dev->config; + struct uart_config uart_cfg; + int ret; + + if (data->status.uart.current_baudrate == target_baudrate) { + LOG_INF("Already at target baud rate %d", target_baudrate); + return 0; + } + + LOG_INF("Switching baud rate from %d to %d", data->status.uart.current_baudrate, + target_baudrate); + + /* Send AT+IPR command to set baud rate */ + snprintf(cmd_buf, sizeof(cmd_buf), SET_BAUDRATE_CMD_FMT, target_baudrate); + ret = modem_dynamic_cmd_send(data, NULL, cmd_buf, strlen(cmd_buf), hl78xx_get_ok_match(), + hl78xx_get_ok_match_size(), MDM_CMD_TIMEOUT, false); + + if (ret < 0) { + LOG_ERR("Failed to send baud rate change command: %d", ret); + return ret; + } + + /* Wait for new baud rate to take effect (~2s per AT command guide) */ + LOG_DBG("Waiting %d ms for modem to apply new baud rate", BAUDRATE_SWITCH_DELAY_MS); + k_sleep(K_MSEC(BAUDRATE_SWITCH_DELAY_MS)); + + /* Get current UART configuration */ + ret = uart_config_get(config->uart, &uart_cfg); + if (ret < 0) { + LOG_ERR("Failed to get UART config: %d", ret); + return ret; + } + + /* Update to new baud rate */ + uart_cfg.baudrate = target_baudrate; + ret = uart_configure(config->uart, &uart_cfg); + if (ret < 0) { + LOG_ERR("Failed to configure new baud rate: %d", ret); + return ret; + } + + /* Wait for UART to stabilize */ + k_sleep(K_MSEC(50)); + + /* Verify communication at new baud rate */ + const char *test_cmd = "AT"; + + ret = modem_dynamic_cmd_send(data, NULL, test_cmd, strlen(test_cmd), hl78xx_get_ok_match(), + hl78xx_get_ok_match_size(), + CONFIG_MODEM_HL78XX_AUTOBAUD_TIMEOUT, false); + + if (ret < 0) { + LOG_ERR("Failed to communicate at new baud rate %d", target_baudrate); + return ret; + } + +#ifdef CONFIG_MODEM_HL78XX_AUTOBAUD_CHANGE_PERSISTENT + /* Save configuration to non-volatile memory (required per AT command guide) */ + const char *cmd_save = "AT&W"; + + ret = modem_dynamic_cmd_send(data, NULL, cmd_save, strlen(cmd_save), hl78xx_get_ok_match(), + hl78xx_get_ok_match_size(), MDM_CMD_TIMEOUT, false); + + if (ret < 0) { + LOG_WRN("Failed to save baud rate to NVRAM: %d (will be temporary)", ret); + /* Continue anyway - baud rate is still active for current session */ + } else { + LOG_DBG("Baud rate configuration saved to NVRAM"); + } +#endif /* CONFIG_MODEM_HL78XX_AUTOBAUD_CHANGE_PERSISTENT */ + data->status.uart.current_baudrate = target_baudrate; + LOG_INF("Successfully switched to baud rate %d", target_baudrate); + + return 0; +} +#endif /* CONFIG_MODEM_HL78XX_AUTO_BAUDRATE */ diff --git a/drivers/modem/hl78xx/hl78xx_cfg.h b/drivers/modem/hl78xx/hl78xx_cfg.h index ec4f07db1cf4..a25244161c39 100644 --- a/drivers/modem/hl78xx/hl78xx_cfg.h +++ b/drivers/modem/hl78xx/hl78xx_cfg.h @@ -29,6 +29,16 @@ int hl78xx_gsm_pdp_activate(struct hl78xx_data *data); int hl78xx_set_apn_internal(struct hl78xx_data *data, const char *apn, uint16_t size); +int hl78xx_get_uart_config(struct hl78xx_data *data); + +#ifdef CONFIG_MODEM_HL78XX_AUTO_BAUDRATE +/* Baud rate detection and switching */ +int configure_uart_for_auto_baudrate(struct hl78xx_data *data, uint32_t baudrate); +int hl78xx_try_baudrate(struct hl78xx_data *data, uint32_t baudrate); +int hl78xx_detect_current_baudrate(struct hl78xx_data *data); +int hl78xx_switch_baudrate(struct hl78xx_data *data, uint32_t target_baudrate); +#endif /* CONFIG_MODEM_HL78XX_AUTO_BAUDRATE */ + /** * @brief Convert a binary bitmap to a trimmed hexadecimal string. * diff --git a/drivers/modem/hl78xx/hl78xx_chat.c b/drivers/modem/hl78xx/hl78xx_chat.c index 436025a48ee8..f3e0963e26db 100644 --- a/drivers/modem/hl78xx/hl78xx_chat.c +++ b/drivers/modem/hl78xx/hl78xx_chat.c @@ -252,11 +252,11 @@ MODEM_CHAT_SCRIPT_DEFINE(hl78xx_fota_install_accept_script, hl78xx_fota_install_ */ MODEM_CHAT_MATCHES_DEFINE(connect_matches, MODEM_CHAT_MATCH(CONNECT_STRING, "", NULL), MODEM_CHAT_MATCH(CME_ERROR_STRING, "", NULL), - MODEM_CHAT_MATCH(ERROR_STRING, "", NULL), ); + MODEM_CHAT_MATCH(ERROR_STRING, "", NULL)); MODEM_CHAT_MATCHES_DEFINE(kudpind_allow_match, MODEM_CHAT_MATCH("+KUDP_IND: ", ",", hl78xx_on_kudpsocket_create), MODEM_CHAT_MATCH(CME_ERROR_STRING, "", NULL), - MODEM_CHAT_MATCH(ERROR_STRING, "", NULL), ); + MODEM_CHAT_MATCH(ERROR_STRING, "", NULL)); MODEM_CHAT_MATCH_DEFINE(ktcpind_match, "+KTCP_IND: ", ",", hl78xx_on_ktcpind); MODEM_CHAT_MATCH_DEFINE(ktcpcfg_match, "+KTCPCFG: ", "", hl78xx_on_ktcpsocket_create); MODEM_CHAT_MATCH_DEFINE(cgdcontrdp_match, "+CGCONTRDP: ", ",", hl78xx_on_cgdcontrdp); diff --git a/include/zephyr/drivers/modem/hl78xx_apis.h b/include/zephyr/drivers/modem/hl78xx_apis.h index 9dae64c2df5e..ce2e9dd7d4a3 100644 --- a/include/zephyr/drivers/modem/hl78xx_apis.h +++ b/include/zephyr/drivers/modem/hl78xx_apis.h @@ -106,6 +106,8 @@ enum hl78xx_modem_info_type { HL78XX_MODEM_INFO_NETWORK_OPERATOR, /* */ HL78XX_MODEM_INFO_SERIAL_NUMBER, + /* Current Baud Rate */ + HL78XX_MODEM_INFO_CURRENT_BAUD_RATE, }; /** Cellular network structure */ From 0ffe90c233427930a004af4b1c0c7342f76a3123 Mon Sep 17 00:00:00 2001 From: Zafer SEN Date: Sat, 6 Dec 2025 04:45:40 +0000 Subject: [PATCH 1419/3659] samples: modem: hello_hl78xx: restructure prj.conf and verbose overlay Reorganize the sample configuration files for clarity and easier maintenance. This introduces grouped sections with descriptive comments and improves consistency between prj.conf and the verbose-logging overlay. Main updates: * Add structured headers for system, UART, networking, modem, RAT, AirVantage, shell, and logging settings * Expand verbose overlay with clearer purpose, build notes, and grouped modem logging options * Improve readability by aligning comments and collecting related options * No functional behavior is changed; this is a documentation and structure improvement These changes make the sample configuration easier to understand and simplify future maintenance. Signed-off-by: Zafer SEN --- .../overlay-swir_hl78xx-verbose-logging.conf | 18 +++++- samples/drivers/modem/hello_hl78xx/prj.conf | 60 ++++++++++++------- 2 files changed, 56 insertions(+), 22 deletions(-) diff --git a/samples/drivers/modem/hello_hl78xx/overlay-swir_hl78xx-verbose-logging.conf b/samples/drivers/modem/hello_hl78xx/overlay-swir_hl78xx-verbose-logging.conf index 8fad488237a6..6724b773cdb9 100644 --- a/samples/drivers/modem/hello_hl78xx/overlay-swir_hl78xx-verbose-logging.conf +++ b/samples/drivers/modem/hello_hl78xx/overlay-swir_hl78xx-verbose-logging.conf @@ -1,8 +1,22 @@ -# Logging +# ============================================================================ +# Verbose Logging Configuration for HL78XX Modem +# ============================================================================ +# Use this overlay for detailed debugging and troubleshooting +# Build with: west build -- -DEXTRA_CONF_FILE=overlay-swir_hl78xx-verbose-logging.conf + +# ============================================================================ +# Logging Infrastructure +# ============================================================================ +# Large log buffer to prevent message loss during verbose logging CONFIG_LOG_BUFFER_SIZE=85536 -# For extra verbosity +# ============================================================================ +# Modem Debug Logging +# ============================================================================ +# Enable debug-level logging for all modem modules CONFIG_MODEM_MODULES_LOG_LEVEL_DBG=y CONFIG_MODEM_LOG_LEVEL_DBG=y +# Larger buffer for modem chat logs (captures AT commands and responses) CONFIG_MODEM_CHAT_LOG_BUFFER_SIZE=1024 +# Enable verbose debug context for HL78XX driver CONFIG_MODEM_HL78XX_LOG_CONTEXT_VERBOSE_DEBUG=y diff --git a/samples/drivers/modem/hello_hl78xx/prj.conf b/samples/drivers/modem/hello_hl78xx/prj.conf index f1a0e63ad7e5..eb0f20569b71 100644 --- a/samples/drivers/modem/hello_hl78xx/prj.conf +++ b/samples/drivers/modem/hello_hl78xx/prj.conf @@ -5,67 +5,72 @@ # The HL78xx driver gets its IP settings from the cell network -#system +# ============================================================================ +# System Configuration +# ============================================================================ CONFIG_HEAP_MEM_POOL_SIZE=4096 CONFIG_MAIN_STACK_SIZE=4096 CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096 CONFIG_POSIX_API=y -#PM +# ============================================================================ +# Power Management (Optional) +# ============================================================================ # CONFIG_PM_DEVICE=y -#uart +# ============================================================================ +# UART Configuration +# ============================================================================ CONFIG_UART_ASYNC_API=y +# CONFIG_UART_INTERRUPT_DRIVEN=y +# CONFIG_MODEM_BACKEND_UART_ASYNC_HWFC=y -# Generic networking options +# ============================================================================ +# Networking Stack +# ============================================================================ CONFIG_NETWORKING=y CONFIG_NET_UDP=y CONFIG_NET_TCP=y CONFIG_NET_IPV6=n CONFIG_NET_IPV4=y CONFIG_NET_SOCKETS=y - # DNS CONFIG_DNS_RESOLVER=y CONFIG_NET_SOCKETS_DNS_TIMEOUT=12000 - # Wait for the network to be ready CONFIG_NET_SAMPLE_COMMON_WAIT_DNS_SERVER_ADDITION=y - # Network management CONFIG_NET_MGMT=y CONFIG_NET_MGMT_EVENT=y # NB-IoT has large latency, so increase timeouts. It is ok to use this for Cat-M1 as well. CONFIG_NET_SOCKETS_CONNECT_TIMEOUT=15000 CONFIG_NET_CONNECTION_MANAGER=y - # Network buffers CONFIG_NET_PKT_RX_COUNT=32 CONFIG_NET_PKT_TX_COUNT=16 CONFIG_NET_BUF_RX_COUNT=64 CONFIG_NET_BUF_TX_COUNT=32 -# Modem driver +# ============================================================================ +# Modem Driver - HL78XX +# ============================================================================ CONFIG_MODEM=y - #hl78xx modem CONFIG_MODEM_HL78XX=y - # Statistics CONFIG_MODEM_STATS=y -# shell -CONFIG_SHELL=y -CONFIG_MODEM_HL78XX_AT_SHELL=y -CONFIG_MODEM_AT_SHELL_COMMAND_MAX_SIZE=256 - -#apn source +# ============================================================================ +# APN Configuration (Disabled - using defaults) +# ============================================================================ # CONFIG_MODEM_HL78XX_APN_SOURCE_KCONFIG=y # CONFIG_MODEM_HL78XX_APN="internet" # CONFIG_MODEM_HL78XX_APN_SOURCE_ICCID=y # CONFIG_MODEM_HL78XX_APN_PROFILES="hologram=23450, wm=20601, vodafone=8988239, em=8988303" -# RAT selection +# ============================================================================ +# Radio Access Technology (RAT) Configuration +# ============================================================================ CONFIG_MODEM_HL78XX_AUTORAT=n # CONFIG_MODEM_HL78XX_AUTORAT_PRL_PROFILES="2,1,3" # CONFIG_MODEM_HL78XX_AUTORAT_NB_BAND_CFG="3,8,20,28" @@ -75,13 +80,28 @@ CONFIG_MODEM_HL78XX_AUTORAT=n # Stay in boot mode until registered to a network # CONFIG_MODEM_HL78XX_STAY_IN_BOOT_MODE_FOR_ROAMING=y -# Enable AirVantage support +# ============================================================================ +# AirVantage Over-The-Air (OTA) Support +# ============================================================================ CONFIG_MODEM_HL78XX_AIRVANTAGE=y CONFIG_MODEM_HL78XX_AIRVANTAGE_USER_AGREEMENT=y CONFIG_MODEM_HL78XX_AIRVANTAGE_UA_CONNECT_AIRVANTAGE=y CONFIG_MODEM_HL78XX_AIRVANTAGE_UA_DOWNLOAD_FIRMWARE=y CONFIG_MODEM_HL78XX_AIRVANTAGE_UA_INSTALL_FIRMWARE=y -# Monitor modem events + +# ============================================================================ +# Shell and Debug Tools +# ============================================================================ +CONFIG_SHELL=y +CONFIG_MODEM_HL78XX_AT_SHELL=y +CONFIG_MODEM_AT_SHELL_COMMAND_MAX_SIZE=256 + +# ============================================================================ +# Event Monitoring +# ============================================================================ CONFIG_HL78XX_EVT_MONITOR=y + +# ============================================================================ # Logging +# ============================================================================ CONFIG_LOG=y From f26880b213a5b9b37ce50ec5996a6ea9fcb06b02 Mon Sep 17 00:00:00 2001 From: Zafer SEN Date: Sat, 6 Dec 2025 04:49:25 +0000 Subject: [PATCH 1420/3659] samples: modem: hello_hl78xx: remove POSIX API dependency MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The sample no longer requires the POSIX API layer, so the CONFIG_POSIX_API option is removed from prj.conf. The code is updated to use the native zsock_* APIs instead of the POSIX getaddrinfo(), inet_ntop(), and freeaddrinfo() variants. This aligns the sample with Zephyr’s preferred socket API and avoids pulling in unnecessary POSIX compatibility layers. No functional behavior is changed. Signed-off-by: Zafer SEN --- samples/drivers/modem/hello_hl78xx/prj.conf | 1 - samples/drivers/modem/hello_hl78xx/src/main.c | 14 +++++--------- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/samples/drivers/modem/hello_hl78xx/prj.conf b/samples/drivers/modem/hello_hl78xx/prj.conf index eb0f20569b71..4b482a9e2c8d 100644 --- a/samples/drivers/modem/hello_hl78xx/prj.conf +++ b/samples/drivers/modem/hello_hl78xx/prj.conf @@ -11,7 +11,6 @@ CONFIG_HEAP_MEM_POOL_SIZE=4096 CONFIG_MAIN_STACK_SIZE=4096 CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096 -CONFIG_POSIX_API=y # ============================================================================ # Power Management (Optional) diff --git a/samples/drivers/modem/hello_hl78xx/src/main.c b/samples/drivers/modem/hello_hl78xx/src/main.c index e1f8849851cc..9e9753523625 100644 --- a/samples/drivers/modem/hello_hl78xx/src/main.c +++ b/samples/drivers/modem/hello_hl78xx/src/main.c @@ -16,10 +16,6 @@ #include #include -#include -#include -#include - /* Macros used to subscribe to specific Zephyr NET management events. */ #if defined(CONFIG_NET_SAMPLE_COMMON_WAIT_DNS_SERVER_ADDITION) #define L4_EVENT_MASK (NET_EVENT_DNS_SERVER_ADD | NET_EVENT_L4_DISCONNECTED) @@ -186,9 +182,9 @@ static void hl78xx_on_ok(struct modem_chat *chat, char **argv, uint16_t argc, vo static int resolve_broker_addr(struct sockaddr_in *broker) { int ret; - struct addrinfo *ai = NULL; + struct zsock_addrinfo *ai = NULL; - const struct addrinfo hints = { + const struct zsock_addrinfo hints = { .ai_family = AF_INET, .ai_socktype = SOCK_STREAM, .ai_protocol = 0, @@ -196,19 +192,19 @@ static int resolve_broker_addr(struct sockaddr_in *broker) char port_string[6] = {0}; snprintf(port_string, sizeof(port_string), "%d", TEST_SERVER_PORT); - ret = getaddrinfo(TEST_SERVER_ENDPOINT, port_string, &hints, &ai); + ret = zsock_getaddrinfo(TEST_SERVER_ENDPOINT, port_string, &hints, &ai); if (ret == 0) { char addr_str[INET_ADDRSTRLEN]; memcpy(broker, ai->ai_addr, MIN(ai->ai_addrlen, sizeof(struct sockaddr_storage))); - inet_ntop(AF_INET, &broker->sin_addr, addr_str, sizeof(addr_str)); + zsock_inet_ntop(AF_INET, &broker->sin_addr, addr_str, sizeof(addr_str)); LOG_INF("Resolved: %s:%u", addr_str, htons(broker->sin_port)); } else { LOG_ERR("failed to resolve hostname err = %d (errno = %d)", ret, errno); } - freeaddrinfo(ai); + zsock_freeaddrinfo(ai); return ret; } From 5ed6ed52156a214279d85fc33ecb49eaf0e06adb Mon Sep 17 00:00:00 2001 From: Zafer SEN Date: Sat, 6 Dec 2025 05:01:21 +0000 Subject: [PATCH 1421/3659] samples: modem: hello_hl78xx: demonstrate AirVantage FOTA API Add support for handling AirVantage WDSI indications in the sample application. FOTA update progress, download requests, and completion events are processed and coordinated using a new semaphore. The sample can restart its connection workflow after a successful firmware update. Additional updates include: - add serial number retrieval and logging - add fota_complete_rerun semaphore and status tracking - simplify debug logging in event listener and OK handler - reorganize main loop to support FOTA-triggered reruns This aligns the sample with the modem driver's expanded AirVantage and WDSI support. Signed-off-by: Zafer SEN --- samples/drivers/modem/hello_hl78xx/src/main.c | 81 +++++++++++++++++-- 1 file changed, 74 insertions(+), 7 deletions(-) diff --git a/samples/drivers/modem/hello_hl78xx/src/main.c b/samples/drivers/modem/hello_hl78xx/src/main.c index 9e9753523625..cedff3a3c61d 100644 --- a/samples/drivers/modem/hello_hl78xx/src/main.c +++ b/samples/drivers/modem/hello_hl78xx/src/main.c @@ -30,12 +30,16 @@ LOG_MODULE_REGISTER(main, CONFIG_MODEM_LOG_LEVEL); static K_SEM_DEFINE(network_connected_sem, 0, 1); -const struct device *modem = DEVICE_DT_GET(DT_ALIAS(modem)); +static K_SEM_DEFINE(fota_complete_rerun, 0, 1); +const static struct device *modem = DEVICE_DT_GET(DT_ALIAS(modem)); /* Zephyr NET management event callback structures. */ static struct net_mgmt_event_callback l4_cb; static struct net_mgmt_event_callback conn_cb; - +#ifdef CONFIG_MODEM_HL78XX_AIRVANTAGE +static int fota_update_status = -1; +#endif +/** Convert RAT mode enum to string */ static const char *rat_get_in_string(enum hl78xx_cell_rat_mode rat) { switch (rat) { @@ -144,9 +148,6 @@ static void l4_event_handler(struct net_mgmt_event_callback *cb, uint64_t event, static void evnt_listener(struct hl78xx_evt *event, struct hl78xx_evt_monitor_entry *context) { -#ifdef CONFIG_MODEM_HL78XX_LOG_CONTEXT_VERBOSE_DEBUG - LOG_DBG("%d HL78XX modem Event Received: %d", __LINE__, event->type); -#endif switch (event->type) { /* Do something */ case HL78XX_LTE_RAT_UPDATE: @@ -160,7 +161,40 @@ static void evnt_listener(struct hl78xx_evt *event, struct hl78xx_evt_monitor_en LOG_INF("%d HL78XX modem startup status: %s", __LINE__, hl78xx_module_status_to_string(event->content.value)); break; +#ifdef CONFIG_MODEM_HL78XX_AIRVANTAGE + case HL78XX_LTE_FOTA_UPDATE_STATUS: + LOG_INF("%d HL78XX modem FOTA update status: %d", __LINE__, + event->content.wdsi_indication); + if (event->content.wdsi_indication == WDSI_FIRMWARE_UPDATE_SUCCESS) { + LOG_INF("FOTA update complete, restarting modem..."); + k_sem_reset(&network_connected_sem); + fota_update_status = (int)WDSI_FIRMWARE_UPDATE_SUCCESS; + k_sem_give(&fota_complete_rerun); + } else if (event->content.wdsi_indication == WDSI_FIRMWARE_UPDATE_FAILED) { + LOG_INF("FOTA update failed."); + fota_update_status = (int)WDSI_FIRMWARE_UPDATE_FAILED; + k_sem_give(&fota_complete_rerun); + } else if (event->content.wdsi_indication == WDSI_FIRMWARE_DOWNLOAD_REQUEST && + fota_update_status != (int)WDSI_FIRMWARE_DOWNLOAD_REQUEST) { + LOG_INF("FOTA download requested, starting download..."); + if (fota_update_status != (int)WDSI_SESSION_STARTED) { + return; + } + fota_update_status = (int)WDSI_FIRMWARE_DOWNLOAD_REQUEST; + k_sem_give(&fota_complete_rerun); + } else if (event->content.wdsi_indication == WDSI_SESSION_STARTED) { + LOG_INF("FOTA session started..."); + fota_update_status = (int)WDSI_SESSION_STARTED; + } else { + /* Other WDSI indications can be handled here if needed */ + } + + break; +#endif /* CONFIG_MODEM_HL78XX_AIRVANTAGE */ default: +#ifdef CONFIG_MODEM_HL78XX_LOG_CONTEXT_VERBOSE_DEBUG + LOG_DBG("%d HL78XX modem Event Received: %d", __LINE__, event->type); +#endif break; } } @@ -171,7 +205,7 @@ static void hl78xx_on_ok(struct modem_chat *chat, char **argv, uint16_t argc, vo return; } #ifdef CONFIG_MODEM_HL78XX_LOG_CONTEXT_VERBOSE_DEBUG - LOG_DBG("%d %s %s", __LINE__, __func__, argv[0]); + LOG_DBG("%d %s", __LINE__, argv[0]); #endif } @@ -251,7 +285,6 @@ int main(void) } (void)conn_mgr_if_connect(iface); - LOG_INF("Waiting for network connection..."); k_sem_take(&network_connected_sem, K_FOREVER); } @@ -262,6 +295,7 @@ int main(void) char apn[MDM_APN_MAX_LENGTH] = {0}; char operator[MDM_MODEL_LENGTH] = {0}; char imei[MDM_IMEI_LENGTH] = {0}; + char serial_number[MDM_SERIAL_NUMBER_LENGTH] = {0}; enum hl78xx_cell_rat_mode tech; enum cellular_registration_status status; int16_t rsrp; @@ -289,6 +323,9 @@ int main(void) hl78xx_get_modem_info(modem, HL78XX_MODEM_INFO_APN, (char *)apn, sizeof(apn)); + hl78xx_get_modem_info(modem, HL78XX_MODEM_INFO_SERIAL_NUMBER, (char *)serial_number, + sizeof(serial_number)); + cellular_get_modem_info(modem, CELLULAR_MODEM_INFO_IMEI, imei, sizeof(imei)); #ifdef CONFIG_MODEM_HL78XX_AUTORAT /* In auto rat mode, get the current rat from the modem status */ @@ -308,6 +345,7 @@ int main(void) LOG_RAW("**********************************************************\n"); LOG_INF("Manufacturer: %s", manufacturer); LOG_INF("Firmware Version: %s", fw_ver); + LOG_INF("Module Serial Number: %s", serial_number); LOG_INF("APN: \"%s\"", apn); LOG_INF("Imei: %s", imei); LOG_INF("RAT: %s", rat_get_in_string(tech)); @@ -337,6 +375,35 @@ int main(void) resolve_broker_addr(&test_endpoint_addr); +#ifdef CONFIG_MODEM_HL78XX_AIRVANTAGE +#ifdef CONFIG_MODEM_HL78XX_AIRVANTAGE_UA_CONNECT_AIRVANTAGE + LOG_INF("Starting AirVantage DM session..."); + hl78xx_start_airvantage_dm_session(modem); + k_sem_reset(&fota_complete_rerun); + LOG_INF("Waiting for AirVantage FOTA Creation..."); + /* Wait for FOTA download request, max 120 seconds */ + ret = k_sem_take(&fota_complete_rerun, K_SECONDS(120)); + if (ret < 0) { + LOG_WRN("AirVantage DM session timed out waiting for FOTA download request.%d", + ret); + } else { + k_sem_reset(&fota_complete_rerun); + LOG_INF("Waiting for AirVantage FOTA Completion..."); + /* Wait for FOTA completion */ + ret = k_sem_take(&fota_complete_rerun, K_FOREVER); + if (fota_update_status == (int)WDSI_FIRMWARE_UPDATE_SUCCESS) { + LOG_INF("FOTA update successful, restarting application to apply update."); + } else if (fota_update_status == (int)WDSI_FIRMWARE_UPDATE_FAILED) { + LOG_WRN("FOTA update failed."); + } else { + LOG_WRN("FOTA update status unknown."); + } + } + +#else + LOG_WRN("AirVantage User Agreement not accepted, cannot start DM session."); +#endif +#endif /* CONFIG_MODEM_HL78XX_AIRVANTAGE */ LOG_INF("Sample application finished."); return 0; From c64ae3b9362defa7f0414d35d04c6d2cd11dd8a1 Mon Sep 17 00:00:00 2001 From: Zafer SEN Date: Sat, 6 Dec 2025 05:03:38 +0000 Subject: [PATCH 1422/3659] samples: modem: hello_hl78xx: select RSSI or RSRP based on RAT mode The sample previously always queried RSRP, which is not valid when the HL78xx operates in GSM mode. Use RSSI when GSM RAT is active and RSRP for other RATs. Update the log output and rename the variable for clarity. Signed-off-by: Zafer SEN --- samples/drivers/modem/hello_hl78xx/src/main.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/samples/drivers/modem/hello_hl78xx/src/main.c b/samples/drivers/modem/hello_hl78xx/src/main.c index cedff3a3c61d..8e9764635353 100644 --- a/samples/drivers/modem/hello_hl78xx/src/main.c +++ b/samples/drivers/modem/hello_hl78xx/src/main.c @@ -298,7 +298,7 @@ int main(void) char serial_number[MDM_SERIAL_NUMBER_LENGTH] = {0}; enum hl78xx_cell_rat_mode tech; enum cellular_registration_status status; - int16_t rsrp; + int16_t signal_strength = 0; const char *newapn = ""; const char *sample_cmd = "AT"; @@ -335,7 +335,11 @@ int main(void) /* Get the current registration status */ cellular_get_registration_status(modem, hl78xx_rat_to_access_tech(tech), &status); /* Get the current signal strength */ - cellular_get_signal(modem, CELLULAR_SIGNAL_RSRP, &rsrp); +#ifdef CONFIG_MODEM_HL78XX_RAT_GSM + cellular_get_signal(modem, CELLULAR_SIGNAL_RSSI, &signal_strength); +#else + cellular_get_signal(modem, CELLULAR_SIGNAL_RSRP, &signal_strength); +#endif /* Get the current network operator name */ hl78xx_get_modem_info(modem, HL78XX_MODEM_INFO_NETWORK_OPERATOR, (char *)operator, sizeof(operator)); @@ -350,7 +354,11 @@ int main(void) LOG_INF("Imei: %s", imei); LOG_INF("RAT: %s", rat_get_in_string(tech)); LOG_INF("Connection status: %s(%d)", reg_status_get_in_string(status), status); - LOG_INF("RSRP : %d", rsrp); +#ifdef CONFIG_MODEM_HL78XX_RAT_GSM + LOG_INF("RSSI : %d", signal_strength); +#else + LOG_INF("RSRP : %d", signal_strength); +#endif LOG_INF("Operator: %s", (strlen(operator) > 0) ? operator : "\"\""); LOG_RAW("**********************************************************\n\n"); From 22d4c66676bd4cf9ca9fea0032df7ee9868a7e75 Mon Sep 17 00:00:00 2001 From: Zafer SEN Date: Sat, 6 Dec 2025 05:05:24 +0000 Subject: [PATCH 1423/3659] samples: modem: hello_hl78xx: add auto-baud support and log current baud Enable HL78XX modem auto-baudrate detection and switching in the sample application. Set 921600 bps as the target baudrate with fallback options (9600, 115200, 57600, 38400, 19200). Also read and log the current baudrate from the modem during startup. This helps verify and debug communication speed mismatches between the modem and the device UART. Signed-off-by: Zafer SEN --- samples/drivers/modem/hello_hl78xx/prj.conf | 20 +++++++++++++++++++ samples/drivers/modem/hello_hl78xx/src/main.c | 5 +++++ 2 files changed, 25 insertions(+) diff --git a/samples/drivers/modem/hello_hl78xx/prj.conf b/samples/drivers/modem/hello_hl78xx/prj.conf index 4b482a9e2c8d..137f6a1c519a 100644 --- a/samples/drivers/modem/hello_hl78xx/prj.conf +++ b/samples/drivers/modem/hello_hl78xx/prj.conf @@ -59,6 +59,26 @@ CONFIG_MODEM_HL78XX=y # Statistics CONFIG_MODEM_STATS=y +# ============================================================================ +# Auto Baud Rate Detection and Switching +# ============================================================================ +CONFIG_MODEM_HL78XX_AUTO_BAUDRATE=y +# CONFIG_MODEM_HL78XX_AUTOBAUD_AT_BOOT=y +# CONFIG_MODEM_HL78XX_AUTOBAUD_ONLY_IF_COMMS_FAIL=n +# CONFIG_MODEM_HL78XX_TARGET_BAUDRATE_9600=y +# CONFIG_MODEM_HL78XX_TARGET_BAUDRATE_115200=y +CONFIG_MODEM_HL78XX_TARGET_BAUDRATE_921600=y +CONFIG_MODEM_HL78XX_AUTOBAUD_DETECTION_BAUDRATES="9600,115200,921600,57600,38400,19200" +CONFIG_MODEM_HL78XX_AUTOBAUD_TIMEOUT=4 +CONFIG_MODEM_HL78XX_AUTOBAUD_RETRY_COUNT=3 +# After enabling auto-baud once WITH CONFIG_MODEM_HL78XX_AUTOBAUD_CHANGE_PERSISTENT, +# the modem's baud rate is saved to NV-MEM with AT&W, so it persists across power cycles. +# If you later disable CONFIG_MODEM_HL78XX_AUTO_BAUDRATE, the driver won't detect/switch, +# but the modem is still at the target baud rate (e.g., 921600) +# If your device tree UART is at 115200 but the modem is at 921600, communication will fail +# CONFIG_MODEM_HL78XX_AUTOBAUD_CHANGE_PERSISTENT=n +# CONFIG_MODEM_HL78XX_AUTOBAUD_START_WITH_TARGET_BAUDRATE=n + # ============================================================================ # APN Configuration (Disabled - using defaults) # ============================================================================ diff --git a/samples/drivers/modem/hello_hl78xx/src/main.c b/samples/drivers/modem/hello_hl78xx/src/main.c index 8e9764635353..bc53e5c10df4 100644 --- a/samples/drivers/modem/hello_hl78xx/src/main.c +++ b/samples/drivers/modem/hello_hl78xx/src/main.c @@ -299,6 +299,7 @@ int main(void) enum hl78xx_cell_rat_mode tech; enum cellular_registration_status status; int16_t signal_strength = 0; + uint32_t current_baudrate = 0; const char *newapn = ""; const char *sample_cmd = "AT"; @@ -343,6 +344,9 @@ int main(void) /* Get the current network operator name */ hl78xx_get_modem_info(modem, HL78XX_MODEM_INFO_NETWORK_OPERATOR, (char *)operator, sizeof(operator)); + /* Get the current baudrate */ + hl78xx_get_modem_info(modem, HL78XX_MODEM_INFO_CURRENT_BAUD_RATE, ¤t_baudrate, + sizeof(current_baudrate)); LOG_RAW("\n**********************************************************\n"); LOG_RAW("********* Hello HL78XX Modem Sample Application **********\n"); @@ -360,6 +364,7 @@ int main(void) LOG_INF("RSRP : %d", signal_strength); #endif LOG_INF("Operator: %s", (strlen(operator) > 0) ? operator : "\"\""); + LOG_INF("Current Baudrate: %dbps", current_baudrate); LOG_RAW("**********************************************************\n\n"); LOG_INF("Setting new APN: %s", newapn); From a959429ff22fcbfb287f064dd94f13bab2a3c670 Mon Sep 17 00:00:00 2001 From: Zafer SEN Date: Sat, 6 Dec 2025 06:51:26 +0000 Subject: [PATCH 1424/3659] doc: hl78xx: add auto-baudrate detection and switching docs Add detailed documentation for the HL78xx auto-baudrate feature, including: - auto_baudrate_detailed_readme.md: full description, use cases, configuration options, and troubleshooting - auto_baudrate_quick_reference.md: concise reference for presets, Kconfig options, and supported baud rates Covers: - Feature overview and implementation details - Supported baud rates and Kconfig options - State machine integration - Troubleshooting guidance - Performance and optimization tips - Integration examples This improves usability and provides a quick reference for developers working with the HL78xx modem in Zephyr projects. Signed-off-by: Zafer SEN --- .../auto_baudrate/hl78xx_auto_baudrate.rst | 319 ++++++++++++++++++ .../hl78xx_auto_baudrate_quick_reference.rst | 271 +++++++++++++++ .../shields/swir_hl78xx_ev_kit/doc/index.rst | 18 +- 3 files changed, 604 insertions(+), 4 deletions(-) create mode 100644 boards/shields/swir_hl78xx_ev_kit/doc/auto_baudrate/hl78xx_auto_baudrate.rst create mode 100644 boards/shields/swir_hl78xx_ev_kit/doc/auto_baudrate/hl78xx_auto_baudrate_quick_reference.rst diff --git a/boards/shields/swir_hl78xx_ev_kit/doc/auto_baudrate/hl78xx_auto_baudrate.rst b/boards/shields/swir_hl78xx_ev_kit/doc/auto_baudrate/hl78xx_auto_baudrate.rst new file mode 100644 index 000000000000..52350b812b44 --- /dev/null +++ b/boards/shields/swir_hl78xx_ev_kit/doc/auto_baudrate/hl78xx_auto_baudrate.rst @@ -0,0 +1,319 @@ +.. _hl78xx_auto_baudrate: + +HL78xx Auto Baud Rate Switching +=============================== + +Overview +-------- + +This feature enables automatic baud rate detection and switching for the +Sierra Wireless HL78xx modem driver. The driver can automatically detect +the modem's current baud rate and switch to a configured target baud rate +using the ``AT+IPR`` command. + +Features +-------- + +- **Auto-detection**: Automatically detects the modem's current baud rate + by trying a list of common baud rates +- **Dynamic switching**: Changes the modem's baud rate to the configured + target using the ``AT+IPR`` command +- **Configurable**: Supports multiple baud rates from 9600 to 921600 bps +- **Retry mechanism**: Configurable retry count for robust detection +- **State machine integration**: Seamlessly integrated into the modem + initialization sequence + +Configuration +------------- + +Enable the feature in your project's ``prj.conf``: + +.. code-block:: ini + + # Enable auto baud rate detection and switching + CONFIG_MODEM_HL78XX_AUTO_BAUDRATE=y + + # Set target baud rate (default is 115200) + CONFIG_MODEM_HL78XX_TARGET_BAUDRATE_921600=y + + # Configure detection baud rates (comma-separated list) + CONFIG_MODEM_HL78XX_AUTOBAUD_DETECTION_BAUDRATES="115200,9600,57600,38400,19200" + + # Set timeout for each detection attempt (in seconds) + CONFIG_MODEM_HL78XX_AUTOBAUD_TIMEOUT=4 + + # Set number of retries + CONFIG_MODEM_HL78XX_AUTOBAUD_RETRY_COUNT=3 + + # Save baud rate change to modem NVMEM (default: y, recommended) + CONFIG_MODEM_HL78XX_AUTOBAUD_CHANGE_PERSISTENT=y + + # Try target baud rate first before detection list (default: y, faster) + CONFIG_MODEM_HL78XX_AUTOBAUD_START_WITH_TARGET_BAUDRATE=y + + # Only perform auto-baud if initial communication fails (default: y, efficient) + CONFIG_MODEM_HL78XX_AUTOBAUD_ONLY_IF_COMMS_FAIL=y + + # Perform auto-baud immediately at boot, skip KSUP wait (default: n) + CONFIG_MODEM_HL78XX_AUTOBAUD_AT_BOOT=n + +Supported Baud Rates +-------------------- + +The following baud rates are supported: + +- 9600 bps +- 19200 bps +- 38400 bps +- 57600 bps +- 115200 bps (default) +- 230400 bps +- 460800 bps +- 921600 bps +- 3000000 bps (HL7812 only) + +How It Works +------------ + +Detection Phase (``MODEM_HL78XX_STATE_SET_BAUDRATE``) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +When the modem enters the ``SET_BAUDRATE`` state after power-on: + +1. The driver tries each baud rate from the detection list +2. For each rate, it: + + - Configures the UART to that baud rate + - Sends an ``AT`` command + - Waits for an ``OK`` response + +3. Once a response is received, the current baud rate is identified + +Switching Phase +~~~~~~~~~~~~~~~ + +If the detected baud rate differs from the target: + +1. Send ``AT+IPR=`` at the current baud rate +2. Wait for ``OK`` response +3. Wait 2.5 seconds for the modem to apply the change +4. Reconfigure the host UART to the new baud rate +5. Wait 50 ms for UART stabilization +6. Verify communication by sending an ``AT`` test command +7. Send ``AT&W`` to save configuration to NVMEM + +.. note:: + + After baud rate switching completes, the state machine runs the + post-restart script to wait for the KUSP URC message before proceeding + to initialization. + +State Transitions +~~~~~~~~~~~~~~~~~ + +:: + + AWAIT_POWER_ON --> SET_BAUDRATE --> RUN_INIT_SCRIPT + | + +--> [On Failure] --> RUN_INIT_FAIL_DIAGNOSTIC_SCRIPT + +Use Cases +--------- + +Use Case 1: Unknown Modem Baud Rate +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: ini + + CONFIG_MODEM_HL78XX_AUTO_BAUDRATE=y + CONFIG_MODEM_HL78XX_AUTOBAUD_DETECTION_BAUDRATES="115200,9600,57600,38400,19200" + +Use Case 2: High-Speed Communication +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: ini + + CONFIG_MODEM_HL78XX_AUTO_BAUDRATE=y + CONFIG_MODEM_HL78XX_TARGET_BAUDRATE_921600=y + +Use Case 3: Fast Boot with Known Baud Rate +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: ini + + CONFIG_MODEM_HL78XX_AUTO_BAUDRATE=y + CONFIG_MODEM_HL78XX_TARGET_BAUDRATE_921600=y + CONFIG_MODEM_HL78XX_AUTOBAUD_START_WITH_TARGET_BAUDRATE=y + CONFIG_MODEM_HL78XX_AUTOBAUD_ONLY_IF_COMMS_FAIL=y + CONFIG_MODEM_HL78XX_AUTOBAUD_TIMEOUT=2 + +**Result:** Boot time ~50–100 ms if modem is already at target rate. + +Use Case 4: Production / Field Deployment +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: ini + + CONFIG_MODEM_HL78XX_AUTO_BAUDRATE=y + CONFIG_MODEM_HL78XX_TARGET_BAUDRATE_921600=y + CONFIG_MODEM_HL78XX_AUTOBAUD_DETECTION_BAUDRATES="115200,57600,38400,19200,9600" + CONFIG_MODEM_HL78XX_AUTOBAUD_TIMEOUT=8 + CONFIG_MODEM_HL78XX_AUTOBAUD_RETRY_COUNT=5 + CONFIG_MODEM_HL78XX_AUTOBAUD_CHANGE_PERSISTENT=y + CONFIG_MODEM_HL78XX_AUTOBAUD_START_WITH_TARGET_BAUDRATE=y + CONFIG_MODEM_HL78XX_AUTOBAUD_ONLY_IF_COMMS_FAIL=y + +Use Case 5: Temporary Baud Rate Change +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: ini + + CONFIG_MODEM_HL78XX_AUTO_BAUDRATE=y + CONFIG_MODEM_HL78XX_TARGET_BAUDRATE_921600=y + CONFIG_MODEM_HL78XX_AUTOBAUD_CHANGE_PERSISTENT=n + +.. note:: + + The modem will revert to the previous baud rate after a power cycle + or ``AT+CFUN`` reset. + +AT Commands Used +---------------- + +Query Current Baud Rate +~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + AT+IPR? + +Response:: + + +IPR: + +IPR: 0 + +Set Fixed Baud Rate +~~~~~~~~~~~~~~~~~~~ + +:: + + AT+IPR= + +Where ```` can be: + +- 9600 +- 19200 +- 38400 +- 57600 +- 115200 +- 230400 +- 460800 +- 921600 +- 3000000 (HL7812 only) + +.. important:: + + The new baud rate takes effect after ~2 seconds. Use ``AT&W`` to + persist the configuration across power cycles. + +Troubleshooting +--------------- + +Detection Fails +~~~~~~~~~~~~~~~ + +**Symptoms:** Modem enters diagnostic state after multiple retries + +**Solutions:** + +1. Verify detection list includes the modem's current baud rate +2. Increase timeout +3. Check UART wiring and signal quality +4. Verify modem is powered and responsive + +Switching Fails +~~~~~~~~~~~~~~~ + +**Symptoms:** Detection succeeds but switching fails + +**Solutions:** + +1. Verify target baud rate is supported by modem and UART +2. Check UART clock limitations +3. Try a lower baud rate +4. Verify firmware supports ``AT+IPR`` + +Communication Lost After Switch +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +**Root Cause:** Host UART not reconfigured before sending ``AT&W`` + +**Solutions:** + +1. Reconfigure host UART **before** ``AT&W`` +2. Wait 2.5 seconds after ``AT+IPR`` +3. Wait for KUSP URC +4. Check UART buffering and flow control + +Disabling Auto-Baud Causes Failure +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +**Root Cause:** Modem remains at saved baud rate while UART defaults differ. + +**Solutions:** + +- Keep auto-baud enabled (recommended) +- Update device tree UART speed: + +.. code-block:: dts + + &uart_modem { + current-speed = <921600>; + }; + +- Manually reset modem baud rate before disabling auto-baud + +Implementation Details +---------------------- + +Key Functions +~~~~~~~~~~~~~ + +.. code-block:: c + + static int hl78xx_try_baudrate(struct hl78xx_data *data, uint32_t baudrate); + static int hl78xx_detect_current_baudrate(struct hl78xx_data *data); + static int hl78xx_switch_baudrate(struct hl78xx_data *data, uint32_t target_baudrate); + +State Handler +~~~~~~~~~~~~~ + +.. code-block:: c + + static int hl78xx_on_set_baudrate_state_enter(struct hl78xx_data *data); + static void hl78xx_set_baudrate_event_handler(struct hl78xx_data *data, + enum hl78xx_event evt); + +Data Structure +~~~~~~~~~~~~~~ + +.. code-block:: c + + struct uart_status { + #ifdef CONFIG_MODEM_HL78XX_AUTO_BAUDRATE + uint32_t current_baudrate; + uint32_t target_baudrate; + uint8_t baudrate_detection_retry; + #endif + }; + +License +------- + +Copyright (c) 2025 Netfeasa Ltd. + +SPDX-License-Identifier: Apache-2.0 + +---- + +**Last Updated:** 2025-12-06 diff --git a/boards/shields/swir_hl78xx_ev_kit/doc/auto_baudrate/hl78xx_auto_baudrate_quick_reference.rst b/boards/shields/swir_hl78xx_ev_kit/doc/auto_baudrate/hl78xx_auto_baudrate_quick_reference.rst new file mode 100644 index 000000000000..1c9167a22def --- /dev/null +++ b/boards/shields/swir_hl78xx_ev_kit/doc/auto_baudrate/hl78xx_auto_baudrate_quick_reference.rst @@ -0,0 +1,271 @@ +.. _hl78xx_auto_baudrate_quick_reference: + +HL78xx Auto Baud Rate - Quick Reference +======================================= + +Enable Feature +-------------- + +.. code-block:: ini + + # In prj.conf + CONFIG_MODEM_HL78XX_AUTO_BAUDRATE=y + CONFIG_MODEM_HL78XX_TARGET_BAUDRATE_921600=y # Your target rate + +Common Configurations +--------------------- + +Preset 1: Smart Default (Recommended) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: ini + + CONFIG_MODEM_HL78XX_AUTO_BAUDRATE=y + CONFIG_MODEM_HL78XX_TARGET_BAUDRATE_921600=y + CONFIG_MODEM_HL78XX_AUTOBAUD_DETECTION_BAUDRATES="921600,9600,57600,38400,115200" + CONFIG_MODEM_HL78XX_AUTOBAUD_TIMEOUT=4 + CONFIG_MODEM_HL78XX_AUTOBAUD_RETRY_COUNT=3 + CONFIG_MODEM_HL78XX_AUTOBAUD_CHANGE_PERSISTENT=y + CONFIG_MODEM_HL78XX_AUTOBAUD_START_WITH_TARGET_BAUDRATE=y + CONFIG_MODEM_HL78XX_AUTOBAUD_ONLY_IF_COMMS_FAIL=y + +- **Use when:** General purpose, known and unknown baud rates +- **Boot time impact:** ~50-100 ms (already at target), ~4-20 s (detection) +- **Why smart:** Full detection only runs if initial communication fails + +Preset 2: Ultra-Fast Boot (Known Rate) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: ini + + CONFIG_MODEM_HL78XX_AUTO_BAUDRATE=y + CONFIG_MODEM_HL78XX_TARGET_BAUDRATE_921600=y + CONFIG_MODEM_HL78XX_AUTOBAUD_DETECTION_BAUDRATES="921600" + CONFIG_MODEM_HL78XX_AUTOBAUD_TIMEOUT=1 + CONFIG_MODEM_HL78XX_AUTOBAUD_RETRY_COUNT=1 + CONFIG_MODEM_HL78XX_AUTOBAUD_START_WITH_TARGET_BAUDRATE=y + CONFIG_MODEM_HL78XX_AUTOBAUD_ONLY_IF_COMMS_FAIL=y + +- **Use when:** Modem is known to be at target rate +- **Boot time impact:** ~50-100 ms +- **Warning:** Fails if modem baud rate differs + +Preset 3: High Speed +~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: ini + + CONFIG_MODEM_HL78XX_AUTO_BAUDRATE=y + CONFIG_MODEM_HL78XX_TARGET_BAUDRATE_921600=y + CONFIG_MODEM_HL78XX_AUTOBAUD_DETECTION_BAUDRATES="921600,460800,230400,115200" + CONFIG_MODEM_HL78XX_AUTOBAUD_TIMEOUT=3 + CONFIG_MODEM_HL78XX_AUTOBAUD_RETRY_COUNT=3 + CONFIG_MODEM_HL78XX_AUTOBAUD_CHANGE_PERSISTENT=y + CONFIG_MODEM_HL78XX_AUTOBAUD_START_WITH_TARGET_BAUDRATE=y + CONFIG_MODEM_HL78XX_AUTOBAUD_ONLY_IF_COMMS_FAIL=y + +- **Use when:** High throughput required +- **Boot time impact:** ~50 ms (best), ~3-12 s (worst) +- **Note:** Ensure UART hardware supports high baud rates + +Preset 4: Robust Production +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: ini + + CONFIG_MODEM_HL78XX_AUTO_BAUDRATE=y + CONFIG_MODEM_HL78XX_TARGET_BAUDRATE_921600=y + CONFIG_MODEM_HL78XX_AUTOBAUD_DETECTION_BAUDRATES="115200,57600,38400,19200,9600,921600" + CONFIG_MODEM_HL78XX_AUTOBAUD_TIMEOUT=8 + CONFIG_MODEM_HL78XX_AUTOBAUD_RETRY_COUNT=5 + CONFIG_MODEM_HL78XX_AUTOBAUD_CHANGE_PERSISTENT=y + CONFIG_MODEM_HL78XX_AUTOBAUD_START_WITH_TARGET_BAUDRATE=y + CONFIG_MODEM_HL78XX_AUTOBAUD_ONLY_IF_COMMS_FAIL=y + +- **Use when:** Field deployment, maximum reliability +- **Boot time impact:** ~50 ms (best), ~40 s (worst) +- **Features:** Diagnostic fallback, comprehensive detection + +Preset 5: Testing / Development (Non-Persistent) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: ini + + CONFIG_MODEM_HL78XX_AUTO_BAUDRATE=y + CONFIG_MODEM_HL78XX_TARGET_BAUDRATE_921600=y + CONFIG_MODEM_HL78XX_AUTOBAUD_CHANGE_PERSISTENT=n + CONFIG_MODEM_HL78XX_AUTOBAUD_START_WITH_TARGET_BAUDRATE=y + CONFIG_MODEM_HL78XX_AUTOBAUD_ONLY_IF_COMMS_FAIL=y + +- **Use when:** Temporary testing +- **Note:** Modem reverts baud rate on power cycle + +Supported Baud Rates +-------------------- + +.. list-table:: + :header-rows: 1 + :widths: 15 45 30 + + * - Rate + - Kconfig Option + - Use Case + * - 9600 + - ``CONFIG_MODEM_HL78XX_TARGET_BAUDRATE_9600`` + - Legacy + * - 19200 + - ``CONFIG_MODEM_HL78XX_TARGET_BAUDRATE_19200`` + - Legacy + * - 38400 + - ``CONFIG_MODEM_HL78XX_TARGET_BAUDRATE_38400`` + - Standard + * - 57600 + - ``CONFIG_MODEM_HL78XX_TARGET_BAUDRATE_57600`` + - Standard + * - 115200 + - ``CONFIG_MODEM_HL78XX_TARGET_BAUDRATE_115200`` + - Default (recommended) + * - 230400 + - ``CONFIG_MODEM_HL78XX_TARGET_BAUDRATE_230400`` + - High speed + * - 460800 + - ``CONFIG_MODEM_HL78XX_TARGET_BAUDRATE_460800`` + - High speed + * - 921600 + - ``CONFIG_MODEM_HL78XX_TARGET_BAUDRATE_921600`` + - Very high speed + * - 3000000 + - ``CONFIG_MODEM_HL78XX_TARGET_BAUDRATE_3000000`` + - Maximum (HL7812 only) + +State Flow +---------- + +:: + + Power ON + ↓ + [START_WITH_TARGET=y?] → Try target first → [AUTOBAUD_AT_BOOT=y?] + ↓ ↓ + Wait KSUP → [ONLY_IF_COMMS_FAIL=y?] → Try Target + ↓ ↓ + Post-Restart → Communication Success? → Skip Detection + ↓ ↓ + | Communication Fails + | ↓ + +----------→ Detect Baud Rate + ↓ + Rate Detected? + ↓ + Switch to Target (AT+IPR) + ↓ + [CHANGE_PERSISTENT=y?] → AT&W + ↓ + Initialize Modem + +Log Messages +------------ + +Success - Smart Default +~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + [hl78xx] Checking if modem is ready at target baud rate 921600... + [hl78xx] Modem ready at target rate, skipping detection + [hl78xx] Baud rate switch not needed + +Detection Triggered +~~~~~~~~~~~~~~~~~~~ + +:: + + [hl78xx] Modem not responding at target rate 921600, starting detection... + [hl78xx] Trying baud rate: 9600 + [hl78xx] Modem responded at 9600 baud + [hl78xx] Saving persistent baud rate with AT&W... + +Non-Persistent Mode +~~~~~~~~~~~~~~~~~~~ + +:: + + [hl78xx] Switching baud rate from 9600 to 921600 + [hl78xx] Non-persistent mode: skipping AT&W + +Failure +~~~~~~~ + +:: + + [hl78xx] Failed to detect modem baud rate + [hl78xx] Retrying baud rate detection (attempt 2/3) + +Troubleshooting +--------------- + +.. list-table:: + :header-rows: 1 + :widths: 30 35 35 + + * - Symptom + - Likely Cause + - Solution + * - Failed to detect modem baud rate + - Detection list missing rate + - Add rates to detection list + * - Times out on each rate + - Modem not ready + - Increase timeout + * - Hangs on AT&W + - UART mismatch + - Fixed: UART reconfigured first + * - Rate not persistent + - Persistence disabled + - Enable ``CHANGE_PERSISTENT`` + +AT Commands Reference +--------------------- + +.. code-block:: bash + + AT+IPR? + AT+IPR=115200 + AT&W + +API Functions (Internal) +------------------------ + +.. code-block:: c + + int hl78xx_try_baudrate(struct hl78xx_data *data, uint32_t baudrate); + int hl78xx_detect_current_baudrate(struct hl78xx_data *data); + int hl78xx_switch_baudrate(struct hl78xx_data *data, uint32_t target_baudrate); + +Performance Tips +---------------- + +1. Enable smart flags for fastest boot +2. Order detection list by likelihood +3. Use shorter timeouts in known environments +4. Enable persistence to avoid re-detection +5. Use ``AUTOBAUD_AT_BOOT`` only if timing is controlled + +Compatibility +------------- + +- HL7812 / HL7800 +- Zephyr 4.4+ +- All supported boards +- Smart detection reduces boot from ~20 s to ~50-100 ms + +License +------- + +Copyright (c) 2025 Netfeasa Ltd. + +SPDX-License-Identifier: Apache-2.0 + +---- + +**Last Updated:** 2025-12-06 diff --git a/boards/shields/swir_hl78xx_ev_kit/doc/index.rst b/boards/shields/swir_hl78xx_ev_kit/doc/index.rst index cc6a9ce761f6..f5042201a8eb 100644 --- a/boards/shields/swir_hl78xx_ev_kit/doc/index.rst +++ b/boards/shields/swir_hl78xx_ev_kit/doc/index.rst @@ -14,12 +14,12 @@ for sending AT commands to the HL78 module and initiating data transmission. :align: center :alt: HL/RC Module Evaluation Kit Shield Shield - HL/RC Module Evaluation Kit Shield Shield (Credit: Sierrra Wireless) + HL/RC Module Evaluation Kit Shield Shield (Credit: Sierra Wireless) More information about the shield can be found at the `HL/RC Module Evaluation Kit Shield guide website`_. -Pins Assignment of HL/RC Module Evaluation Kit Shield Shield -============================================================ +Pins Assignment of HL/RC Module Evaluation Kit Shield +===================================================== +--------------------------+----------------------------------------------------------+ | Shield Connector Pin | Function | +==========================+==========================================================+ @@ -67,6 +67,16 @@ example: :shield: swir_hl78xx_ev_kit :goals: build +Documentation +************* + +Automatic baud rate detection: +============================== + +For full details, see :ref:`hl78xx_auto_baudrate`. + +For a condensed overview, see :ref:`hl78xx_auto_baudrate_quick_reference`. + References ********** @@ -76,4 +86,4 @@ References https://source.sierrawireless.com/resources/airprime/development_kits/hl78xx-hl7900-development-kit-guide/ .. _HL/RC Module Evaluation Kit Shield specification website: - https://info.sierrawireless.com/iot-modules-evaluation-kit#guide-for-the-hl78-series-evaluation-kit + https://info.sierrawireless.com/iot-modules-evaluation-kit#guide-for-the-hl78-series-evaluation-kit/ From 1d4be6f7022680f2aa6055dd0acf28f0e3f74658 Mon Sep 17 00:00:00 2001 From: Derek Snell Date: Tue, 6 Jan 2026 19:48:16 -0500 Subject: [PATCH 1425/3659] boards: shields: lcd_par_s035: fix touchscreen orientation Fixes orientation after d4ec3fef5e7342140c7cb5faec65326a3a583d28 update Signed-off-by: Derek Snell --- boards/shields/lcd_par_s035/lcd_par_s035_8080.overlay | 6 +++--- boards/shields/lcd_par_s035/lcd_par_s035_spi.overlay | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/boards/shields/lcd_par_s035/lcd_par_s035_8080.overlay b/boards/shields/lcd_par_s035/lcd_par_s035_8080.overlay index a58ef1a7cf67..8aa3ecd780d0 100644 --- a/boards/shields/lcd_par_s035/lcd_par_s035_8080.overlay +++ b/boards/shields/lcd_par_s035/lcd_par_s035_8080.overlay @@ -29,9 +29,9 @@ irq-gpios = <&nxp_lcd_8080_connector 9 GPIO_ACTIVE_HIGH>; zephyr,deferred-init; swapped-x-y; - inverted-y; - screen-width = <480>; - screen-height = <320>; + inverted-x; + screen-width = <320>; + screen-height = <480>; }; }; diff --git a/boards/shields/lcd_par_s035/lcd_par_s035_spi.overlay b/boards/shields/lcd_par_s035/lcd_par_s035_spi.overlay index 374c3af53888..902222860c83 100644 --- a/boards/shields/lcd_par_s035/lcd_par_s035_spi.overlay +++ b/boards/shields/lcd_par_s035/lcd_par_s035_spi.overlay @@ -30,9 +30,9 @@ irq-gpios = <&nxp_lcd_pmod_connector 12 GPIO_ACTIVE_HIGH>; zephyr,deferred-init; swapped-x-y; - inverted-y; - screen-width = <480>; - screen-height = <320>; + inverted-x; + screen-width = <320>; + screen-height = <480>; }; }; From 23dfe86f4accdc3a8cb1ad740b24fd938e1acd18 Mon Sep 17 00:00:00 2001 From: Jisheng Zhang Date: Tue, 6 Jan 2026 22:48:19 +0800 Subject: [PATCH 1426/3659] arch: arm64: remove ARM64_EXCEPTION_STACK_TRACE After commit 02770ad96376 ("debug: EXCEPTION_STACK_TRACE should depend on arch Kconfigs"), the ARM64_EXCEPTION_STACK_TRACE isn't used any more, remove it. Signed-off-by: Jisheng Zhang --- arch/arm64/core/Kconfig | 7 ------- 1 file changed, 7 deletions(-) diff --git a/arch/arm64/core/Kconfig b/arch/arm64/core/Kconfig index c7d0bac3aa19..b88e8d62f478 100644 --- a/arch/arm64/core/Kconfig +++ b/arch/arm64/core/Kconfig @@ -176,13 +176,6 @@ config ARM64_SAFE_EXCEPTION_STACK used for user stack overflow checking, because kernel stack support the checking work. -config ARM64_EXCEPTION_STACK_TRACE - bool - default y - depends on FRAME_POINTER - help - Internal config to enable runtime stack traces on fatal exceptions. - config ARM64_SAFE_EXCEPTION_STACK_SIZE int "The stack size of the safe exception stack" default 4096 From f80975d025a4339aadc7e2e5991ba1a7bd816ed7 Mon Sep 17 00:00:00 2001 From: Gaetan Perrot Date: Wed, 7 Jan 2026 15:39:38 +0900 Subject: [PATCH 1427/3659] drivers: audio: dmic_nrfx_pdm: fix error propagation The error code returned when nrfx_pdm_start() fails is supposed to be propagated to the caller. This was broken by commit 16b9f60, which overwrote the original error with the result of release_clock(), potentially returning success even though the PDM start failed. Restore the correct error propagation. Signed-off-by: Gaetan Perrot --- drivers/audio/dmic_nrfx_pdm.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/audio/dmic_nrfx_pdm.c b/drivers/audio/dmic_nrfx_pdm.c index b3fc87404f82..8f6acce02bd3 100644 --- a/drivers/audio/dmic_nrfx_pdm.c +++ b/drivers/audio/dmic_nrfx_pdm.c @@ -340,16 +340,14 @@ static int start_transfer(struct dmic_nrfx_pdm_drv_data *drv_data) } LOG_ERR("Failed to start PDM: %d", err); - ret = -EIO; ret = release_clock(drv_data); if (ret < 0) { LOG_ERR("Failed to release clock: %d", ret); - return ret; } drv_data->active = false; - return ret; + return -EIO; } static void clock_started_callback(struct onoff_manager *mgr, From 0574f75fc462d4dd7721c70766c8ef5686cf5fdd Mon Sep 17 00:00:00 2001 From: Muhammad Waleed Badar Date: Wed, 31 Dec 2025 11:59:12 +0500 Subject: [PATCH 1428/3659] boards: rpi_4b: update compatible in root node to use bcm2711 The BCM2711 is the SoC used on the Raspberry Pi 4 boards. Signed-off-by: Muhammad Waleed Badar --- boards/raspberrypi/rpi_4b/rpi_4b.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boards/raspberrypi/rpi_4b/rpi_4b.dts b/boards/raspberrypi/rpi_4b/rpi_4b.dts index e7e1faad4357..822da49a559d 100644 --- a/boards/raspberrypi/rpi_4b/rpi_4b.dts +++ b/boards/raspberrypi/rpi_4b/rpi_4b.dts @@ -11,7 +11,7 @@ / { model = "Raspberry Pi 4 Model B"; - compatible = "raspberrypi,4-model-b", "brcm,bcm2838"; + compatible = "raspberrypi,4-model-b", "brcm,bcm2711"; #address-cells = <1>; #size-cells = <1>; From 4e52bad12937195bcdeee3da8668f7ab1db27ebf Mon Sep 17 00:00:00 2001 From: Muhammad Waleed Badar Date: Wed, 31 Dec 2025 13:07:36 +0500 Subject: [PATCH 1429/3659] boards: rpi_4b: remove empty file from raspberry pi 4 board Remove empty files from the Raspberry Pi 4 Model B board directory. These files does not contain any configuration or build logic. Signed-off-by: Muhammad Waleed Badar --- boards/raspberrypi/rpi_4b/CMakeLists.txt | 1 - boards/raspberrypi/rpi_4b/Kconfig.defconfig | 2 -- boards/raspberrypi/rpi_4b/board.cmake | 1 - 3 files changed, 4 deletions(-) delete mode 100644 boards/raspberrypi/rpi_4b/CMakeLists.txt delete mode 100644 boards/raspberrypi/rpi_4b/Kconfig.defconfig delete mode 100644 boards/raspberrypi/rpi_4b/board.cmake diff --git a/boards/raspberrypi/rpi_4b/CMakeLists.txt b/boards/raspberrypi/rpi_4b/CMakeLists.txt deleted file mode 100644 index 9881313609aa..000000000000 --- a/boards/raspberrypi/rpi_4b/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 diff --git a/boards/raspberrypi/rpi_4b/Kconfig.defconfig b/boards/raspberrypi/rpi_4b/Kconfig.defconfig deleted file mode 100644 index 70e623172483..000000000000 --- a/boards/raspberrypi/rpi_4b/Kconfig.defconfig +++ /dev/null @@ -1,2 +0,0 @@ -# Copyright 2023 honglin leng -# SPDX-License-Identifier: Apache-2.0 diff --git a/boards/raspberrypi/rpi_4b/board.cmake b/boards/raspberrypi/rpi_4b/board.cmake deleted file mode 100644 index 9881313609aa..000000000000 --- a/boards/raspberrypi/rpi_4b/board.cmake +++ /dev/null @@ -1 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 From 67ddf8db300c33796ae9e364114925a209135334 Mon Sep 17 00:00:00 2001 From: Fabin V Martin Date: Tue, 6 Jan 2026 16:33:52 +0530 Subject: [PATCH 1430/3659] drivers: uart: microchip: sercom g1: DMA selection for async mode Allow user to select DMA in the application. Signed-off-by: Fabin V Martin --- drivers/serial/Kconfig.mchp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/serial/Kconfig.mchp b/drivers/serial/Kconfig.mchp index cbd871d28acb..f8c18e4f5509 100644 --- a/drivers/serial/Kconfig.mchp +++ b/drivers/serial/Kconfig.mchp @@ -18,6 +18,6 @@ config UART_MCHP_ASYNC bool default y depends on UART_ASYNC_API - select DMA + depends on DMA endif # UART_MCHP_SERCOM_G1 From 1c2af3a0d6f4f0205b373a15bb935bf173311a94 Mon Sep 17 00:00:00 2001 From: Fabin V Martin Date: Tue, 6 Jan 2026 16:45:04 +0530 Subject: [PATCH 1431/3659] tests: drivers: uart: Add conf files Added config files for selecting DMA for the tests. Signed-off-by: Fabin V Martin --- tests/drivers/uart/uart_async_api/boards/sam_e54_xpro.conf | 2 ++ tests/drivers/uart/uart_async_api/testcase.yaml | 2 -- tests/drivers/uart/uart_errors/boards/sam_e54_xpro_async.conf | 1 + tests/drivers/uart/uart_errors/testcase.yaml | 1 + 4 files changed, 4 insertions(+), 2 deletions(-) create mode 100644 tests/drivers/uart/uart_async_api/boards/sam_e54_xpro.conf create mode 100644 tests/drivers/uart/uart_errors/boards/sam_e54_xpro_async.conf diff --git a/tests/drivers/uart/uart_async_api/boards/sam_e54_xpro.conf b/tests/drivers/uart/uart_async_api/boards/sam_e54_xpro.conf new file mode 100644 index 000000000000..1e530b99924d --- /dev/null +++ b/tests/drivers/uart/uart_async_api/boards/sam_e54_xpro.conf @@ -0,0 +1,2 @@ +CONFIG_UART_ASYNC_API=y +CONFIG_DMA=y diff --git a/tests/drivers/uart/uart_async_api/testcase.yaml b/tests/drivers/uart/uart_async_api/testcase.yaml index 4e6c92d9a2c1..2134301f268e 100644 --- a/tests/drivers/uart/uart_async_api/testcase.yaml +++ b/tests/drivers/uart/uart_async_api/testcase.yaml @@ -168,5 +168,3 @@ tests: filter: CONFIG_SERIAL_SUPPORT_ASYNC platform_allow: - sam_e54_xpro - extra_configs: - - CONFIG_UART_ASYNC_API=y diff --git a/tests/drivers/uart/uart_errors/boards/sam_e54_xpro_async.conf b/tests/drivers/uart/uart_errors/boards/sam_e54_xpro_async.conf new file mode 100644 index 000000000000..73aff8957e7a --- /dev/null +++ b/tests/drivers/uart/uart_errors/boards/sam_e54_xpro_async.conf @@ -0,0 +1 @@ +CONFIG_DMA=y diff --git a/tests/drivers/uart/uart_errors/testcase.yaml b/tests/drivers/uart/uart_errors/testcase.yaml index 6810a75854c8..79860fc5b2f6 100644 --- a/tests/drivers/uart/uart_errors/testcase.yaml +++ b/tests/drivers/uart/uart_errors/testcase.yaml @@ -26,6 +26,7 @@ tests: - nrf5340dk/nrf5340/cpuapp - ophelia4ev/nrf54l15/cpuapp - sam_e54_xpro + extra_args: EXTRA_CONF_FILE="boards/sam_e54_xpro_async.conf" extra_configs: - CONFIG_UART_ASYNC_API=y - CONFIG_UART_INTERRUPT_DRIVEN=n From 9a5d96e4e098e2546c293926e5774d89fd4c4deb Mon Sep 17 00:00:00 2001 From: Yunjie Ye Date: Sun, 23 Nov 2025 04:43:46 +0800 Subject: [PATCH 1432/3659] drivers: video: ov2640: Add pwdn pin support on ov2640. Add handling for the power-down (pwdn) pin of the OV2640 sensor. Signed-off-by: Yunjie Ye --- drivers/video/ov2640.c | 44 ++++++++++++++++++++++------- dts/bindings/video/ovti,ov2640.yaml | 6 ++++ 2 files changed, 40 insertions(+), 10 deletions(-) diff --git a/drivers/video/ov2640.c b/drivers/video/ov2640.c index 08527db125ca..2f7a49162f44 100644 --- a/drivers/video/ov2640.c +++ b/drivers/video/ov2640.c @@ -342,7 +342,7 @@ static const struct ov2640_reg default_regs[] = { { 0xe1, 0x77 }, { 0xdd, 0x7f }, { CTRL0, CTRL0_YUV422 | CTRL0_YUV_EN | CTRL0_RGB_EN }, - { 0x00, 0x00 } + { 0x00, 0x00 }, }; static const struct ov2640_reg uxga_regs[] = { @@ -406,7 +406,7 @@ static const struct ov2640_reg uxga_regs[] = { #define NUM_BRIGHTNESS_LEVELS (5) static const uint8_t brightness_regs[NUM_BRIGHTNESS_LEVELS + 1][5] = { - { BPADDR, BPDATA, BPADDR, BPDATA, BPDATA }, + { BPADDR, BPDATA, BPADDR, BPDATA, BPDATA }, /* reg addr */ { 0x00, 0x04, 0x09, 0x00, 0x00 }, /* -2 */ { 0x00, 0x04, 0x09, 0x10, 0x00 }, /* -1 */ { 0x00, 0x04, 0x09, 0x20, 0x00 }, /* 0 */ @@ -416,7 +416,7 @@ static const uint8_t brightness_regs[NUM_BRIGHTNESS_LEVELS + 1][5] = { #define NUM_CONTRAST_LEVELS (5) static const uint8_t contrast_regs[NUM_CONTRAST_LEVELS + 1][7] = { - { BPADDR, BPDATA, BPADDR, BPDATA, BPDATA, BPDATA, BPDATA }, + { BPADDR, BPDATA, BPADDR, BPDATA, BPDATA, BPDATA, BPDATA }, /* reg addr */ { 0x00, 0x04, 0x07, 0x20, 0x18, 0x34, 0x06 }, /* -2 */ { 0x00, 0x04, 0x07, 0x20, 0x1c, 0x2a, 0x06 }, /* -1 */ { 0x00, 0x04, 0x07, 0x20, 0x20, 0x20, 0x06 }, /* 0 */ @@ -426,7 +426,7 @@ static const uint8_t contrast_regs[NUM_CONTRAST_LEVELS + 1][7] = { #define NUM_SATURATION_LEVELS (5) static const uint8_t saturation_regs[NUM_SATURATION_LEVELS + 1][5] = { - { BPADDR, BPDATA, BPADDR, BPDATA, BPDATA }, + { BPADDR, BPDATA, BPADDR, BPDATA, BPDATA }, /* reg addr */ { 0x00, 0x02, 0x03, 0x28, 0x28 }, /* -2 */ { 0x00, 0x02, 0x03, 0x38, 0x38 }, /* -1 */ { 0x00, 0x02, 0x03, 0x48, 0x48 }, /* 0 */ @@ -438,6 +438,9 @@ struct ov2640_config { struct i2c_dt_spec i2c; #if DT_INST_NODE_HAS_PROP(0, reset_gpios) struct gpio_dt_spec reset_gpio; +#endif +#if DT_INST_NODE_HAS_PROP(0, pwdn_gpios) + struct gpio_dt_spec pwdn_gpio; #endif uint8_t clock_rate_control; }; @@ -468,7 +471,7 @@ struct ov2640_data { .height_min = (height), \ .height_max = (height), \ .width_step = 0, \ - .height_step = 0 \ + .height_step = 0, \ } static const struct video_format_cap fmts[] = { @@ -493,7 +496,7 @@ static const struct video_format_cap fmts[] = { OV2640_VIDEO_FORMAT_CAP(1024, 768, VIDEO_PIX_FMT_JPEG), /* XVGA */ OV2640_VIDEO_FORMAT_CAP(1280, 1024, VIDEO_PIX_FMT_JPEG), /* SXGA */ OV2640_VIDEO_FORMAT_CAP(1600, 1200, VIDEO_PIX_FMT_JPEG), /* UXGA */ - { 0 } + { 0 }, }; static int ov2640_write_reg(const struct i2c_dt_spec *spec, uint8_t reg_addr, @@ -1000,6 +1003,11 @@ static int ov2640_init_controls(const struct device *dev) static int ov2640_init(const struct device *dev) { + +#if DT_INST_NODE_HAS_PROP(0, pwdn_gpios) || DT_INST_NODE_HAS_PROP(0, reset_gpios) + const struct ov2640_config *cfg = dev->config; +#endif + int ret = 0; /* set default/init format SVGA RGB565 */ struct video_format fmt = { @@ -1008,9 +1016,16 @@ static int ov2640_init(const struct device *dev) .height = SVGA_VSIZE, }; -#if DT_INST_NODE_HAS_PROP(0, reset_gpios) - const struct ov2640_config *cfg = dev->config; +#if DT_INST_NODE_HAS_PROP(0, pwdn_gpios) + ret = gpio_pin_configure_dt(&cfg->pwdn_gpio, GPIO_OUTPUT_INACTIVE); + if (ret < 0) { + return ret; + } + k_sleep(K_MSEC(1)); +#endif + +#if DT_INST_NODE_HAS_PROP(0, reset_gpios) ret = gpio_pin_configure_dt(&cfg->reset_gpio, GPIO_OUTPUT_ACTIVE); if (ret) { return ret; @@ -1055,6 +1070,9 @@ static const struct ov2640_config ov2640_cfg_0 = { .i2c = I2C_DT_SPEC_INST_GET(0), #if DT_INST_NODE_HAS_PROP(0, reset_gpios) .reset_gpio = GPIO_DT_SPEC_INST_GET(0, reset_gpios), +#endif +#if DT_INST_NODE_HAS_PROP(0, pwdn_gpios) + .pwdn_gpio = GPIO_DT_SPEC_INST_GET(0, pwdn_gpios), #endif .clock_rate_control = DT_INST_PROP(0, clock_rate_control), }; @@ -1077,8 +1095,14 @@ static int ov2640_init_0(const struct device *dev) } #endif - uint32_t i2c_cfg = I2C_MODE_CONTROLLER | - I2C_SPEED_SET(I2C_SPEED_STANDARD); +#if DT_INST_NODE_HAS_PROP(0, pwdn_gpios) + if (!gpio_is_ready_dt(&cfg->pwdn_gpio)) { + LOG_ERR("%s: device %s is not ready", dev->name, cfg->pwdn_gpio.port->name); + return -ENODEV; + } +#endif + + uint32_t i2c_cfg = I2C_MODE_CONTROLLER | I2C_SPEED_SET(I2C_SPEED_STANDARD); if (i2c_configure(cfg->i2c.bus, i2c_cfg)) { LOG_ERR("Failed to configure ov2640 i2c interface."); diff --git a/dts/bindings/video/ovti,ov2640.yaml b/dts/bindings/video/ovti,ov2640.yaml index 1bc26fcaee88..3093414c3060 100644 --- a/dts/bindings/video/ovti,ov2640.yaml +++ b/dts/bindings/video/ovti,ov2640.yaml @@ -12,6 +12,12 @@ properties: 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 disable the sensor. The sensor + receives this as an active-high signal. + clock-rate-control: type: int default: 0x87 From 7b93c32bd1946da2fb9f87d2d1083d3217424b39 Mon Sep 17 00:00:00 2001 From: Yunjie Ye Date: Mon, 8 Dec 2025 19:59:06 +0800 Subject: [PATCH 1433/3659] drivers: video: ov2640: Running clang-format on ov2640.c file Using clangd to format ov2640.c file, which is not compatible with existing .clang-format file. Signed-off-by: Yunjie Ye --- drivers/video/ov2640.c | 778 ++++++++++++++++++++--------------------- 1 file changed, 385 insertions(+), 393 deletions(-) diff --git a/drivers/video/ov2640.c b/drivers/video/ov2640.c index 2f7a49162f44..85989a00af38 100644 --- a/drivers/video/ov2640.c +++ b/drivers/video/ov2640.c @@ -20,143 +20,143 @@ LOG_MODULE_REGISTER(video_ov2640, CONFIG_VIDEO_LOG_LEVEL); /* DSP register bank FF=0x00*/ -#define QS 0x44 -#define HSIZE 0x51 -#define VSIZE 0x52 -#define XOFFL 0x53 -#define YOFFL 0x54 -#define VHYX 0x55 -#define TEST 0x57 -#define ZMOW 0x5A -#define ZMOH 0x5B -#define ZMHH 0x5C -#define BPADDR 0x7C -#define BPDATA 0x7D -#define SIZEL 0x8C -#define HSIZE8 0xC0 -#define VSIZE8 0xC1 -#define CTRL1 0xC3 - -#define CTRLI 0x50 -#define CTRLI_LP_DP 0x80 - -#define CTRL0 0xC2 -#define CTRL0_YUV422 0x08 -#define CTRL0_YUV_EN 0x04 -#define CTRL0_RGB_EN 0x02 - -#define CTRL2 0x86 -#define CTRL2_DCW_EN 0x20 -#define CTRL2_SDE_EN 0x10 -#define CTRL2_UV_ADJ_EN 0x08 -#define CTRL2_UV_AVG_EN 0x04 -#define CTRL2_CMX_EN 0x01 - -#define CTRL3 0x87 -#define CTRL3_BPC_EN 0x80 -#define CTRL3_WPC_EN 0x40 -#define R_DVP_SP 0xD3 -#define R_DVP_SP_AUTO_MODE 0x80 - -#define R_BYPASS 0x05 -#define R_BYPASS_DSP_EN 0x00 -#define R_BYPASS_DSP_BYPAS 0x01 - -#define IMAGE_MODE 0xDA -#define IMAGE_MODE_JPEG_EN 0x10 -#define IMAGE_MODE_RGB565 0x08 - -#define RESET 0xE0 -#define RESET_JPEG 0x10 -#define RESET_DVP 0x04 - -#define MC_BIST 0xF9 -#define MC_BIST_RESET 0x80 -#define MC_BIST_BOOT_ROM_SEL 0x40 - -#define BANK_SEL 0xFF -#define BANK_SEL_DSP 0x00 -#define BANK_SEL_SENSOR 0x01 +#define QS 0x44 +#define HSIZE 0x51 +#define VSIZE 0x52 +#define XOFFL 0x53 +#define YOFFL 0x54 +#define VHYX 0x55 +#define TEST 0x57 +#define ZMOW 0x5A +#define ZMOH 0x5B +#define ZMHH 0x5C +#define BPADDR 0x7C +#define BPDATA 0x7D +#define SIZEL 0x8C +#define HSIZE8 0xC0 +#define VSIZE8 0xC1 +#define CTRL1 0xC3 + +#define CTRLI 0x50 +#define CTRLI_LP_DP 0x80 + +#define CTRL0 0xC2 +#define CTRL0_YUV422 0x08 +#define CTRL0_YUV_EN 0x04 +#define CTRL0_RGB_EN 0x02 + +#define CTRL2 0x86 +#define CTRL2_DCW_EN 0x20 +#define CTRL2_SDE_EN 0x10 +#define CTRL2_UV_ADJ_EN 0x08 +#define CTRL2_UV_AVG_EN 0x04 +#define CTRL2_CMX_EN 0x01 + +#define CTRL3 0x87 +#define CTRL3_BPC_EN 0x80 +#define CTRL3_WPC_EN 0x40 +#define R_DVP_SP 0xD3 +#define R_DVP_SP_AUTO_MODE 0x80 + +#define R_BYPASS 0x05 +#define R_BYPASS_DSP_EN 0x00 +#define R_BYPASS_DSP_BYPAS 0x01 + +#define IMAGE_MODE 0xDA +#define IMAGE_MODE_JPEG_EN 0x10 +#define IMAGE_MODE_RGB565 0x08 + +#define RESET 0xE0 +#define RESET_JPEG 0x10 +#define RESET_DVP 0x04 + +#define MC_BIST 0xF9 +#define MC_BIST_RESET 0x80 +#define MC_BIST_BOOT_ROM_SEL 0x40 + +#define BANK_SEL 0xFF +#define BANK_SEL_DSP 0x00 +#define BANK_SEL_SENSOR 0x01 /* Sensor register bank FF=0x01*/ -#define COM1 0x03 -#define REG_PID 0x0A -#define REG_PID_VAL 0x26 -#define REG_VER 0x0B -#define REG_VER_VAL 0x42 -#define AEC 0x10 -#define CLKRC 0x11 -#define COM10 0x15 -#define HSTART 0x17 -#define HSTOP 0x18 -#define VSTART 0x19 -#define VSTOP 0x1A -#define AEW 0x24 -#define AEB 0x25 -#define ARCOM2 0x34 -#define FLL 0x46 -#define FLH 0x47 -#define COM19 0x48 -#define ZOOMS 0x49 -#define BD50 0x4F -#define BD60 0x50 -#define REG5D 0x5D -#define REG5E 0x5E -#define REG5F 0x5F -#define REG60 0x60 -#define HISTO_LOW 0x61 -#define HISTO_HIGH 0x62 - -#define REG04 0x04 -#define REG04_DEFAULT 0x28 -#define REG04_HFLIP_IMG 0x80 -#define REG04_VFLIP_IMG 0x40 -#define REG04_VREF_EN 0x10 -#define REG04_HREF_EN 0x08 -#define REG04_SET(x) (REG04_DEFAULT | x) - -#define COM2 0x09 -#define COM2_OUT_DRIVE_3x 0x02 - -#define COM3 0x0C -#define COM3_DEFAULT 0x38 -#define COM3_BAND_AUTO 0x02 -#define COM3_BAND_SET(x) (COM3_DEFAULT | x) - -#define COM7 0x12 -#define COM7_SRST 0x80 -#define COM7_RES_UXGA 0x00 /* UXGA */ -#define COM7_ZOOM_EN 0x04 /* Enable Zoom */ -#define COM7_COLOR_BAR 0x02 /* Enable Color Bar Test */ - -#define COM8 0x13 -#define COM8_DEFAULT 0xC0 -#define COM8_BNDF_EN 0x20 /* Enable Banding filter */ -#define COM8_AGC_EN 0x04 /* AGC Auto/Manual control selection */ -#define COM8_AEC_EN 0x01 /* Auto/Manual Exposure control */ -#define COM8_SET(x) (COM8_DEFAULT | x) - -#define COM9 0x14 /* AGC gain ceiling */ -#define COM9_DEFAULT 0x08 -#define COM9_AGC_GAIN_8x 0x02 /* AGC: 8x */ -#define COM9_AGC_SET(x) (COM9_DEFAULT | (x << 5)) - -#define COM10 0x15 - -#define CTRL1_AWB 0x08 /* Enable AWB */ +#define COM1 0x03 +#define REG_PID 0x0A +#define REG_PID_VAL 0x26 +#define REG_VER 0x0B +#define REG_VER_VAL 0x42 +#define AEC 0x10 +#define CLKRC 0x11 +#define COM10 0x15 +#define HSTART 0x17 +#define HSTOP 0x18 +#define VSTART 0x19 +#define VSTOP 0x1A +#define AEW 0x24 +#define AEB 0x25 +#define ARCOM2 0x34 +#define FLL 0x46 +#define FLH 0x47 +#define COM19 0x48 +#define ZOOMS 0x49 +#define BD50 0x4F +#define BD60 0x50 +#define REG5D 0x5D +#define REG5E 0x5E +#define REG5F 0x5F +#define REG60 0x60 +#define HISTO_LOW 0x61 +#define HISTO_HIGH 0x62 + +#define REG04 0x04 +#define REG04_DEFAULT 0x28 +#define REG04_HFLIP_IMG 0x80 +#define REG04_VFLIP_IMG 0x40 +#define REG04_VREF_EN 0x10 +#define REG04_HREF_EN 0x08 +#define REG04_SET(x) (REG04_DEFAULT | x) + +#define COM2 0x09 +#define COM2_OUT_DRIVE_3x 0x02 + +#define COM3 0x0C +#define COM3_DEFAULT 0x38 +#define COM3_BAND_AUTO 0x02 +#define COM3_BAND_SET(x) (COM3_DEFAULT | x) + +#define COM7 0x12 +#define COM7_SRST 0x80 +#define COM7_RES_UXGA 0x00 /* UXGA */ +#define COM7_ZOOM_EN 0x04 /* Enable Zoom */ +#define COM7_COLOR_BAR 0x02 /* Enable Color Bar Test */ + +#define COM8 0x13 +#define COM8_DEFAULT 0xC0 +#define COM8_BNDF_EN 0x20 /* Enable Banding filter */ +#define COM8_AGC_EN 0x04 /* AGC Auto/Manual control selection */ +#define COM8_AEC_EN 0x01 /* Auto/Manual Exposure control */ +#define COM8_SET(x) (COM8_DEFAULT | x) + +#define COM9 0x14 /* AGC gain ceiling */ +#define COM9_DEFAULT 0x08 +#define COM9_AGC_GAIN_8x 0x02 /* AGC: 8x */ +#define COM9_AGC_SET(x) (COM9_DEFAULT | (x << 5)) + +#define COM10 0x15 + +#define CTRL1_AWB 0x08 /* Enable AWB */ #define VV 0x26 #define VV_AGC_TH_SET(h, l) ((h << 4) | (l & 0x0F)) -#define REG32 0x32 -#define REG32_UXGA 0x36 +#define REG32 0x32 +#define REG32_UXGA 0x36 /* Configuration arrays */ -#define SVGA_HSIZE (800) -#define SVGA_VSIZE (600) +#define SVGA_HSIZE (800) +#define SVGA_VSIZE (600) -#define UXGA_HSIZE (1600) -#define UXGA_VSIZE (1200) +#define UXGA_HSIZE (1600) +#define UXGA_VSIZE (1200) struct ov2640_reg { uint8_t addr; @@ -164,274 +164,273 @@ struct ov2640_reg { }; static const struct ov2640_reg default_regs[] = { - { BANK_SEL, BANK_SEL_DSP }, - { 0x2c, 0xff }, - { 0x2e, 0xdf }, - { BANK_SEL, BANK_SEL_SENSOR }, - { 0x3c, 0x32 }, - { CLKRC, 0x80 }, /* Set PCLK divider */ - { COM2, COM2_OUT_DRIVE_3x }, /* Output drive x2 */ - { REG04, REG04_SET(REG04_HREF_EN)}, - { COM8, COM8_SET(COM8_BNDF_EN | COM8_AGC_EN | COM8_AEC_EN) }, - { COM9, COM9_AGC_SET(COM9_AGC_GAIN_8x)}, - { COM10, 0x00 }, /* Invert VSYNC */ - { 0x2c, 0x0c }, - { 0x33, 0x78 }, - { 0x3a, 0x33 }, - { 0x3b, 0xfb }, - { 0x3e, 0x00 }, - { 0x43, 0x11 }, - { 0x16, 0x10 }, - { 0x39, 0x02 }, - { 0x35, 0x88 }, - { 0x22, 0x0a }, - { 0x37, 0x40 }, - { 0x23, 0x00 }, - { ARCOM2, 0xa0 }, - { 0x06, 0x02 }, - { 0x06, 0x88 }, - { 0x07, 0xc0 }, - { 0x0d, 0xb7 }, - { 0x0e, 0x01 }, - { 0x4c, 0x00 }, - { 0x4a, 0x81 }, - { 0x21, 0x99 }, - { AEW, 0x40 }, - { AEB, 0x38 }, + {BANK_SEL, BANK_SEL_DSP}, + {0x2c, 0xff}, + {0x2e, 0xdf}, + {BANK_SEL, BANK_SEL_SENSOR}, + {0x3c, 0x32}, + {CLKRC, 0x80}, /* Set PCLK divider */ + {COM2, COM2_OUT_DRIVE_3x}, /* Output drive x2 */ + {REG04, REG04_SET(REG04_HREF_EN)}, + {COM8, COM8_SET(COM8_BNDF_EN | COM8_AGC_EN | COM8_AEC_EN)}, + {COM9, COM9_AGC_SET(COM9_AGC_GAIN_8x)}, + {COM10, 0x00}, /* Invert VSYNC */ + {0x2c, 0x0c}, + {0x33, 0x78}, + {0x3a, 0x33}, + {0x3b, 0xfb}, + {0x3e, 0x00}, + {0x43, 0x11}, + {0x16, 0x10}, + {0x39, 0x02}, + {0x35, 0x88}, + {0x22, 0x0a}, + {0x37, 0x40}, + {0x23, 0x00}, + {ARCOM2, 0xa0}, + {0x06, 0x02}, + {0x06, 0x88}, + {0x07, 0xc0}, + {0x0d, 0xb7}, + {0x0e, 0x01}, + {0x4c, 0x00}, + {0x4a, 0x81}, + {0x21, 0x99}, + {AEW, 0x40}, + {AEB, 0x38}, /* AGC/AEC fast mode operating region */ - { VV, VV_AGC_TH_SET(0x08, 0x02) }, - { COM19, 0x00 }, /* Zoom control 2 LSBs */ - { ZOOMS, 0x00 }, /* Zoom control 8 MSBs */ - { 0x5c, 0x00 }, - { 0x63, 0x00 }, - { FLL, 0x00 }, - { FLH, 0x00 }, + {VV, VV_AGC_TH_SET(0x08, 0x02)}, + {COM19, 0x00}, /* Zoom control 2 LSBs */ + {ZOOMS, 0x00}, /* Zoom control 8 MSBs */ + {0x5c, 0x00}, + {0x63, 0x00}, + {FLL, 0x00}, + {FLH, 0x00}, /* Set banding filter */ - { COM3, COM3_BAND_SET(COM3_BAND_AUTO) }, - { REG5D, 0x55 }, - { REG5E, 0x7d }, - { REG5F, 0x7d }, - { REG60, 0x55 }, - { HISTO_LOW, 0x70 }, - { HISTO_HIGH, 0x80 }, - { 0x7c, 0x05 }, - { 0x20, 0x80 }, - { 0x28, 0x30 }, - { 0x6c, 0x00 }, - { 0x6d, 0x80 }, - { 0x6e, 0x00 }, - { 0x70, 0x02 }, - { 0x71, 0x94 }, - { 0x73, 0xc1 }, - { 0x3d, 0x34 }, + {COM3, COM3_BAND_SET(COM3_BAND_AUTO)}, + {REG5D, 0x55}, + {REG5E, 0x7d}, + {REG5F, 0x7d}, + {REG60, 0x55}, + {HISTO_LOW, 0x70}, + {HISTO_HIGH, 0x80}, + {0x7c, 0x05}, + {0x20, 0x80}, + {0x28, 0x30}, + {0x6c, 0x00}, + {0x6d, 0x80}, + {0x6e, 0x00}, + {0x70, 0x02}, + {0x71, 0x94}, + {0x73, 0xc1}, + {0x3d, 0x34}, /* { COM7, COM7_RES_UXGA | COM7_ZOOM_EN }, */ - { 0x5a, 0x57 }, - { BD50, 0xbb }, - { BD60, 0x9c }, - - { BANK_SEL, BANK_SEL_DSP }, - { 0xe5, 0x7f }, - { MC_BIST, MC_BIST_RESET | MC_BIST_BOOT_ROM_SEL }, - { 0x41, 0x24 }, - { RESET, RESET_JPEG | RESET_DVP }, - { 0x76, 0xff }, - { 0x33, 0xa0 }, - { 0x42, 0x20 }, - { 0x43, 0x18 }, - { 0x4c, 0x00 }, - { CTRL3, CTRL3_BPC_EN | CTRL3_WPC_EN | 0x10 }, - { 0x88, 0x3f }, - { 0xd7, 0x03 }, - { 0xd9, 0x10 }, - { R_DVP_SP, R_DVP_SP_AUTO_MODE | 0x2 }, - { 0xc8, 0x08 }, - { 0xc9, 0x80 }, - { BPADDR, 0x00 }, - { BPDATA, 0x00 }, - { BPADDR, 0x03 }, - { BPDATA, 0x48 }, - { BPDATA, 0x48 }, - { BPADDR, 0x08 }, - { BPDATA, 0x20 }, - { BPDATA, 0x10 }, - { BPDATA, 0x0e }, - { 0x90, 0x00 }, - { 0x91, 0x0e }, - { 0x91, 0x1a }, - { 0x91, 0x31 }, - { 0x91, 0x5a }, - { 0x91, 0x69 }, - { 0x91, 0x75 }, - { 0x91, 0x7e }, - { 0x91, 0x88 }, - { 0x91, 0x8f }, - { 0x91, 0x96 }, - { 0x91, 0xa3 }, - { 0x91, 0xaf }, - { 0x91, 0xc4 }, - { 0x91, 0xd7 }, - { 0x91, 0xe8 }, - { 0x91, 0x20 }, - { 0x92, 0x00 }, - { 0x93, 0x06 }, - { 0x93, 0xe3 }, - { 0x93, 0x03 }, - { 0x93, 0x03 }, - { 0x93, 0x00 }, - { 0x93, 0x02 }, - { 0x93, 0x00 }, - { 0x93, 0x00 }, - { 0x93, 0x00 }, - { 0x93, 0x00 }, - { 0x93, 0x00 }, - { 0x93, 0x00 }, - { 0x93, 0x00 }, - { 0x96, 0x00 }, - { 0x97, 0x08 }, - { 0x97, 0x19 }, - { 0x97, 0x02 }, - { 0x97, 0x0c }, - { 0x97, 0x24 }, - { 0x97, 0x30 }, - { 0x97, 0x28 }, - { 0x97, 0x26 }, - { 0x97, 0x02 }, - { 0x97, 0x98 }, - { 0x97, 0x80 }, - { 0x97, 0x00 }, - { 0x97, 0x00 }, - { 0xa4, 0x00 }, - { 0xa8, 0x00 }, - { 0xc5, 0x11 }, - { 0xc6, 0x51 }, - { 0xbf, 0x80 }, - { 0xc7, 0x10 }, - { 0xb6, 0x66 }, - { 0xb8, 0xA5 }, - { 0xb7, 0x64 }, - { 0xb9, 0x7C }, - { 0xb3, 0xaf }, - { 0xb4, 0x97 }, - { 0xb5, 0xFF }, - { 0xb0, 0xC5 }, - { 0xb1, 0x94 }, - { 0xb2, 0x0f }, - { 0xc4, 0x5c }, - { 0xa6, 0x00 }, - { 0xa7, 0x20 }, - { 0xa7, 0xd8 }, - { 0xa7, 0x1b }, - { 0xa7, 0x31 }, - { 0xa7, 0x00 }, - { 0xa7, 0x18 }, - { 0xa7, 0x20 }, - { 0xa7, 0xd8 }, - { 0xa7, 0x19 }, - { 0xa7, 0x31 }, - { 0xa7, 0x00 }, - { 0xa7, 0x18 }, - { 0xa7, 0x20 }, - { 0xa7, 0xd8 }, - { 0xa7, 0x19 }, - { 0xa7, 0x31 }, - { 0xa7, 0x00 }, - { 0xa7, 0x18 }, - { 0x7f, 0x00 }, - { 0xe5, 0x1f }, - { 0xe1, 0x77 }, - { 0xdd, 0x7f }, - { CTRL0, CTRL0_YUV422 | CTRL0_YUV_EN | CTRL0_RGB_EN }, - { 0x00, 0x00 }, + {0x5a, 0x57}, + {BD50, 0xbb}, + {BD60, 0x9c}, + + {BANK_SEL, BANK_SEL_DSP}, + {0xe5, 0x7f}, + {MC_BIST, MC_BIST_RESET | MC_BIST_BOOT_ROM_SEL}, + {0x41, 0x24}, + {RESET, RESET_JPEG | RESET_DVP}, + {0x76, 0xff}, + {0x33, 0xa0}, + {0x42, 0x20}, + {0x43, 0x18}, + {0x4c, 0x00}, + {CTRL3, CTRL3_BPC_EN | CTRL3_WPC_EN | 0x10}, + {0x88, 0x3f}, + {0xd7, 0x03}, + {0xd9, 0x10}, + {R_DVP_SP, R_DVP_SP_AUTO_MODE | 0x2}, + {0xc8, 0x08}, + {0xc9, 0x80}, + {BPADDR, 0x00}, + {BPDATA, 0x00}, + {BPADDR, 0x03}, + {BPDATA, 0x48}, + {BPDATA, 0x48}, + {BPADDR, 0x08}, + {BPDATA, 0x20}, + {BPDATA, 0x10}, + {BPDATA, 0x0e}, + {0x90, 0x00}, + {0x91, 0x0e}, + {0x91, 0x1a}, + {0x91, 0x31}, + {0x91, 0x5a}, + {0x91, 0x69}, + {0x91, 0x75}, + {0x91, 0x7e}, + {0x91, 0x88}, + {0x91, 0x8f}, + {0x91, 0x96}, + {0x91, 0xa3}, + {0x91, 0xaf}, + {0x91, 0xc4}, + {0x91, 0xd7}, + {0x91, 0xe8}, + {0x91, 0x20}, + {0x92, 0x00}, + {0x93, 0x06}, + {0x93, 0xe3}, + {0x93, 0x03}, + {0x93, 0x03}, + {0x93, 0x00}, + {0x93, 0x02}, + {0x93, 0x00}, + {0x93, 0x00}, + {0x93, 0x00}, + {0x93, 0x00}, + {0x93, 0x00}, + {0x93, 0x00}, + {0x93, 0x00}, + {0x96, 0x00}, + {0x97, 0x08}, + {0x97, 0x19}, + {0x97, 0x02}, + {0x97, 0x0c}, + {0x97, 0x24}, + {0x97, 0x30}, + {0x97, 0x28}, + {0x97, 0x26}, + {0x97, 0x02}, + {0x97, 0x98}, + {0x97, 0x80}, + {0x97, 0x00}, + {0x97, 0x00}, + {0xa4, 0x00}, + {0xa8, 0x00}, + {0xc5, 0x11}, + {0xc6, 0x51}, + {0xbf, 0x80}, + {0xc7, 0x10}, + {0xb6, 0x66}, + {0xb8, 0xA5}, + {0xb7, 0x64}, + {0xb9, 0x7C}, + {0xb3, 0xaf}, + {0xb4, 0x97}, + {0xb5, 0xFF}, + {0xb0, 0xC5}, + {0xb1, 0x94}, + {0xb2, 0x0f}, + {0xc4, 0x5c}, + {0xa6, 0x00}, + {0xa7, 0x20}, + {0xa7, 0xd8}, + {0xa7, 0x1b}, + {0xa7, 0x31}, + {0xa7, 0x00}, + {0xa7, 0x18}, + {0xa7, 0x20}, + {0xa7, 0xd8}, + {0xa7, 0x19}, + {0xa7, 0x31}, + {0xa7, 0x00}, + {0xa7, 0x18}, + {0xa7, 0x20}, + {0xa7, 0xd8}, + {0xa7, 0x19}, + {0xa7, 0x31}, + {0xa7, 0x00}, + {0xa7, 0x18}, + {0x7f, 0x00}, + {0xe5, 0x1f}, + {0xe1, 0x77}, + {0xdd, 0x7f}, + {CTRL0, CTRL0_YUV422 | CTRL0_YUV_EN | CTRL0_RGB_EN}, + {0x00, 0x00}, }; static const struct ov2640_reg uxga_regs[] = { - { BANK_SEL, BANK_SEL_SENSOR }, + {BANK_SEL, BANK_SEL_SENSOR}, /* DSP input image resolution and window size control */ - { COM7, COM7_RES_UXGA}, - { COM1, 0x0F }, /* UXGA=0x0F, SVGA=0x0A, CIF=0x06 */ - { REG32, REG32_UXGA }, /* UXGA=0x36, SVGA/CIF=0x09 */ - - { HSTART, 0x11 }, /* UXGA=0x11, SVGA/CIF=0x11 */ - { HSTOP, 0x75 }, /* UXGA=0x75, SVGA/CIF=0x43 */ - - { VSTART, 0x01 }, /* UXGA=0x01, SVGA/CIF=0x00 */ - { VSTOP, 0x97 }, /* UXGA=0x97, SVGA/CIF=0x4b */ - { 0x3d, 0x34 }, /* UXGA=0x34, SVGA/CIF=0x38 */ - - { 0x35, 0x88 }, - { 0x22, 0x0a }, - { 0x37, 0x40 }, - { 0x34, 0xa0 }, - { 0x06, 0x02 }, - { 0x0d, 0xb7 }, - { 0x0e, 0x01 }, - { 0x42, 0x83 }, + {COM7, COM7_RES_UXGA}, + {COM1, 0x0F}, /* UXGA=0x0F, SVGA=0x0A, CIF=0x06 */ + {REG32, REG32_UXGA}, /* UXGA=0x36, SVGA/CIF=0x09 */ + + {HSTART, 0x11}, /* UXGA=0x11, SVGA/CIF=0x11 */ + {HSTOP, 0x75}, /* UXGA=0x75, SVGA/CIF=0x43 */ + + {VSTART, 0x01}, /* UXGA=0x01, SVGA/CIF=0x00 */ + {VSTOP, 0x97}, /* UXGA=0x97, SVGA/CIF=0x4b */ + {0x3d, 0x34}, /* UXGA=0x34, SVGA/CIF=0x38 */ + + {0x35, 0x88}, + {0x22, 0x0a}, + {0x37, 0x40}, + {0x34, 0xa0}, + {0x06, 0x02}, + {0x0d, 0xb7}, + {0x0e, 0x01}, + {0x42, 0x83}, /* * Set DSP input image size and offset. * The sensor output image can be scaled with OUTW/OUTH */ - { BANK_SEL, BANK_SEL_DSP }, - { R_BYPASS, R_BYPASS_DSP_BYPAS }, + {BANK_SEL, BANK_SEL_DSP}, + {R_BYPASS, R_BYPASS_DSP_BYPAS}, - { RESET, RESET_DVP }, - { HSIZE8, (UXGA_HSIZE>>3)}, /* Image Horizontal Size HSIZE[10:3] */ - { VSIZE8, (UXGA_VSIZE>>3)}, /* Image Vertical Size VSIZE[10:3] */ + {RESET, RESET_DVP}, + {HSIZE8, (UXGA_HSIZE >> 3)}, /* Image Horizontal Size HSIZE[10:3] */ + {VSIZE8, (UXGA_VSIZE >> 3)}, /* Image Vertical Size VSIZE[10:3] */ /* {HSIZE[11], HSIZE[2:0], VSIZE[2:0]} */ - { SIZEL, ((UXGA_HSIZE>>6)&0x40) | ((UXGA_HSIZE&0x7)<<3) | (UXGA_VSIZE&0x7)}, + {SIZEL, ((UXGA_HSIZE >> 6) & 0x40) | ((UXGA_HSIZE & 0x7) << 3) | (UXGA_VSIZE & 0x7)}, - { XOFFL, 0x00 }, /* OFFSET_X[7:0] */ - { YOFFL, 0x00 }, /* OFFSET_Y[7:0] */ - { HSIZE, ((UXGA_HSIZE>>2)&0xFF) }, /* H_SIZE[7:0] real/4 */ - { VSIZE, ((UXGA_VSIZE>>2)&0xFF) }, /* V_SIZE[7:0] real/4 */ + {XOFFL, 0x00}, /* OFFSET_X[7:0] */ + {YOFFL, 0x00}, /* OFFSET_Y[7:0] */ + {HSIZE, ((UXGA_HSIZE >> 2) & 0xFF)}, /* H_SIZE[7:0] real/4 */ + {VSIZE, ((UXGA_VSIZE >> 2) & 0xFF)}, /* V_SIZE[7:0] real/4 */ /* V_SIZE[8]/OFFSET_Y[10:8]/H_SIZE[8]/OFFSET_X[10:8] */ - { VHYX, ((UXGA_VSIZE>>3)&0x80) | ((UXGA_HSIZE>>7)&0x08) }, - { TEST, (UXGA_HSIZE>>4)&0x80}, /* H_SIZE[9] */ + {VHYX, ((UXGA_VSIZE >> 3) & 0x80) | ((UXGA_HSIZE >> 7) & 0x08)}, + {TEST, (UXGA_HSIZE >> 4) & 0x80}, /* H_SIZE[9] */ - { CTRL2, CTRL2_DCW_EN | CTRL2_SDE_EN | - CTRL2_UV_AVG_EN | CTRL2_CMX_EN | CTRL2_UV_ADJ_EN }, + {CTRL2, CTRL2_DCW_EN | CTRL2_SDE_EN | CTRL2_UV_AVG_EN | CTRL2_CMX_EN | CTRL2_UV_ADJ_EN}, /* H_DIVIDER/V_DIVIDER */ - { CTRLI, CTRLI_LP_DP | 0x00}, + {CTRLI, CTRLI_LP_DP | 0x00}, /* DVP prescaler */ - { R_DVP_SP, R_DVP_SP_AUTO_MODE | 0x04}, + {R_DVP_SP, R_DVP_SP_AUTO_MODE | 0x04}, - { R_BYPASS, R_BYPASS_DSP_EN }, - { RESET, 0x00 }, + {R_BYPASS, R_BYPASS_DSP_EN}, + {RESET, 0x00}, {0, 0}, }; #define NUM_BRIGHTNESS_LEVELS (5) static const uint8_t brightness_regs[NUM_BRIGHTNESS_LEVELS + 1][5] = { - { BPADDR, BPDATA, BPADDR, BPDATA, BPDATA }, /* reg addr */ - { 0x00, 0x04, 0x09, 0x00, 0x00 }, /* -2 */ - { 0x00, 0x04, 0x09, 0x10, 0x00 }, /* -1 */ - { 0x00, 0x04, 0x09, 0x20, 0x00 }, /* 0 */ - { 0x00, 0x04, 0x09, 0x30, 0x00 }, /* +1 */ - { 0x00, 0x04, 0x09, 0x40, 0x00 }, /* +2 */ + {BPADDR, BPDATA, BPADDR, BPDATA, BPDATA}, /* reg addr */ + {0x00, 0x04, 0x09, 0x00, 0x00}, /* -2 */ + {0x00, 0x04, 0x09, 0x10, 0x00}, /* -1 */ + {0x00, 0x04, 0x09, 0x20, 0x00}, /* 0 */ + {0x00, 0x04, 0x09, 0x30, 0x00}, /* +1 */ + {0x00, 0x04, 0x09, 0x40, 0x00}, /* +2 */ }; #define NUM_CONTRAST_LEVELS (5) static const uint8_t contrast_regs[NUM_CONTRAST_LEVELS + 1][7] = { - { BPADDR, BPDATA, BPADDR, BPDATA, BPDATA, BPDATA, BPDATA }, /* reg addr */ - { 0x00, 0x04, 0x07, 0x20, 0x18, 0x34, 0x06 }, /* -2 */ - { 0x00, 0x04, 0x07, 0x20, 0x1c, 0x2a, 0x06 }, /* -1 */ - { 0x00, 0x04, 0x07, 0x20, 0x20, 0x20, 0x06 }, /* 0 */ - { 0x00, 0x04, 0x07, 0x20, 0x24, 0x16, 0x06 }, /* +1 */ - { 0x00, 0x04, 0x07, 0x20, 0x28, 0x0c, 0x06 }, /* +2 */ + {BPADDR, BPDATA, BPADDR, BPDATA, BPDATA, BPDATA, BPDATA}, /* reg addr */ + {0x00, 0x04, 0x07, 0x20, 0x18, 0x34, 0x06}, /* -2 */ + {0x00, 0x04, 0x07, 0x20, 0x1c, 0x2a, 0x06}, /* -1 */ + {0x00, 0x04, 0x07, 0x20, 0x20, 0x20, 0x06}, /* 0 */ + {0x00, 0x04, 0x07, 0x20, 0x24, 0x16, 0x06}, /* +1 */ + {0x00, 0x04, 0x07, 0x20, 0x28, 0x0c, 0x06}, /* +2 */ }; #define NUM_SATURATION_LEVELS (5) static const uint8_t saturation_regs[NUM_SATURATION_LEVELS + 1][5] = { - { BPADDR, BPDATA, BPADDR, BPDATA, BPDATA }, /* reg addr */ - { 0x00, 0x02, 0x03, 0x28, 0x28 }, /* -2 */ - { 0x00, 0x02, 0x03, 0x38, 0x38 }, /* -1 */ - { 0x00, 0x02, 0x03, 0x48, 0x48 }, /* 0 */ - { 0x00, 0x02, 0x03, 0x58, 0x58 }, /* +1 */ - { 0x00, 0x02, 0x03, 0x58, 0x58 }, /* +2 */ + {BPADDR, BPDATA, BPADDR, BPDATA, BPDATA}, /* reg addr */ + {0x00, 0x02, 0x03, 0x28, 0x28}, /* -2 */ + {0x00, 0x02, 0x03, 0x38, 0x38}, /* -1 */ + {0x00, 0x02, 0x03, 0x48, 0x48}, /* 0 */ + {0x00, 0x02, 0x03, 0x58, 0x58}, /* +1 */ + {0x00, 0x02, 0x03, 0x58, 0x58}, /* +2 */ }; struct ov2640_config { @@ -463,15 +462,15 @@ struct ov2640_data { struct video_format fmt; }; -#define OV2640_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, \ +#define OV2640_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[] = { @@ -496,11 +495,10 @@ static const struct video_format_cap fmts[] = { OV2640_VIDEO_FORMAT_CAP(1024, 768, VIDEO_PIX_FMT_JPEG), /* XVGA */ OV2640_VIDEO_FORMAT_CAP(1280, 1024, VIDEO_PIX_FMT_JPEG), /* SXGA */ OV2640_VIDEO_FORMAT_CAP(1600, 1200, VIDEO_PIX_FMT_JPEG), /* UXGA */ - { 0 }, + {0}, }; -static int ov2640_write_reg(const struct i2c_dt_spec *spec, uint8_t reg_addr, - uint8_t value) +static int ov2640_write_reg(const struct i2c_dt_spec *spec, uint8_t reg_addr, uint8_t value) { uint8_t tries = 3; @@ -545,8 +543,8 @@ static int ov2640_read_reg(const struct i2c_dt_spec *spec, uint8_t reg_addr) return -1; } -static int ov2640_write_all(const struct device *dev, - const struct ov2640_reg *regs, uint16_t reg_num) +static int ov2640_write_all(const struct device *dev, const struct ov2640_reg *regs, + uint16_t reg_num) { uint16_t i = 0; const struct ov2640_config *cfg = dev->config; @@ -577,8 +575,8 @@ static int ov2640_soft_reset(const struct device *dev) return ret; } -static int ov2640_set_level(const struct device *dev, int level, - int max_level, int cols, const uint8_t regs[][cols]) +static int ov2640_set_level(const struct device *dev, int level, int max_level, int cols, + const uint8_t regs[][cols]) { int ret = 0; const struct ov2640_config *cfg = dev->config; @@ -588,15 +586,14 @@ static int ov2640_set_level(const struct device *dev, int level, /* Switch to DSP register bank */ ret |= ov2640_write_reg(&cfg->i2c, BANK_SEL, BANK_SEL_DSP); - for (int i = 0; i < (ARRAY_SIZE(regs[0]) / sizeof(regs[0][0])); i++) { + for (int i = 0; i < (ARRAY_SIZE(regs[0]) / sizeof(regs[0][0])); i++) { ret |= ov2640_write_reg(&cfg->i2c, regs[0][i], regs[level][i]); } return ret; } -static int ov2640_set_output_format(const struct device *dev, - int output_format) +static int ov2640_set_output_format(const struct device *dev, int output_format) { int ret = 0; const struct ov2640_config *cfg = dev->config; @@ -604,10 +601,10 @@ static int ov2640_set_output_format(const struct device *dev, /* Switch to DSP register bank */ ret |= ov2640_write_reg(&cfg->i2c, BANK_SEL, BANK_SEL_DSP); - if (output_format == VIDEO_PIX_FMT_JPEG) { + if (output_format == VIDEO_PIX_FMT_JPEG) { /* Enable JPEG compression */ ret |= ov2640_write_reg(&cfg->i2c, IMAGE_MODE, IMAGE_MODE_JPEG_EN); - } else if (output_format == VIDEO_PIX_FMT_RGB565) { + } else if (output_format == VIDEO_PIX_FMT_RGB565) { /* Disable JPEG compression and set output to RGB565 */ ret |= ov2640_write_reg(&cfg->i2c, IMAGE_MODE, IMAGE_MODE_RGB565); } else { @@ -729,8 +726,7 @@ static int ov2640_set_exposure_ctrl(const struct device *dev, int enable) return ret; } -static int ov2640_set_horizontal_mirror(const struct device *dev, - int enable) +static int ov2640_set_horizontal_mirror(const struct device *dev, int enable) { int ret = 0; const struct ov2640_config *cfg = dev->config; @@ -778,8 +774,7 @@ static int ov2640_set_vertical_flip(const struct device *dev, int enable) return ret; } -static int ov2640_set_resolution(const struct device *dev, - uint16_t img_width, uint16_t img_height) +static int ov2640_set_resolution(const struct device *dev, uint16_t img_width, uint16_t img_height) { int ret = 0; const struct ov2640_config *cfg = dev->config; @@ -794,8 +789,8 @@ static int ov2640_set_resolution(const struct device *dev, /* Write output width */ ret |= ov2640_write_reg(&cfg->i2c, ZMOW, (w >> 2) & 0xFF); /* OUTW[7:0] (real/4) */ ret |= ov2640_write_reg(&cfg->i2c, ZMOH, (h >> 2) & 0xFF); /* OUTH[7:0] (real/4) */ - ret |= ov2640_write_reg(&cfg->i2c, ZMHH, ((h >> 8) & 0x04) | - ((w>>10) & 0x03)); /* OUTH[8]/OUTW[9:8] */ + ret |= ov2640_write_reg(&cfg->i2c, ZMHH, + ((h >> 8) & 0x04) | ((w >> 10) & 0x03)); /* OUTH[8]/OUTW[9:8] */ /* Set CLKRC */ ret |= ov2640_write_reg(&cfg->i2c, BANK_SEL, BANK_SEL_SENSOR); @@ -861,7 +856,7 @@ static int ov2640_set_fmt(const struct device *dev, struct video_format *fmt) /* Check if camera is capable of handling given format */ while (fmts[i].pixelformat) { if (fmts[i].width_min == width && fmts[i].height_min == height && - fmts[i].pixelformat == fmt->pixelformat) { + fmts[i].pixelformat == fmt->pixelformat) { /* Set window size */ ret |= ov2640_set_resolution(dev, fmt->width, fmt->height); return ret; @@ -1089,8 +1084,7 @@ static int ov2640_init_0(const struct device *dev) #if DT_INST_NODE_HAS_PROP(0, reset_gpios) if (!gpio_is_ready_dt(&cfg->reset_gpio)) { - LOG_ERR("%s: device %s is not ready", dev->name, - cfg->reset_gpio.port->name); + LOG_ERR("%s: device %s is not ready", dev->name, cfg->reset_gpio.port->name); return -ENODEV; } #endif @@ -1111,9 +1105,7 @@ static int ov2640_init_0(const struct device *dev) return ov2640_init(dev); } -DEVICE_DT_INST_DEFINE(0, &ov2640_init_0, NULL, - &ov2640_data_0, &ov2640_cfg_0, - POST_KERNEL, CONFIG_VIDEO_INIT_PRIORITY, - &ov2640_driver_api); +DEVICE_DT_INST_DEFINE(0, &ov2640_init_0, NULL, &ov2640_data_0, &ov2640_cfg_0, POST_KERNEL, + CONFIG_VIDEO_INIT_PRIORITY, &ov2640_driver_api); VIDEO_DEVICE_DEFINE(ov2640, DEVICE_DT_INST_GET(0), NULL); From cfb6e150407803927ddc0ac9378a63e6427a63e6 Mon Sep 17 00:00:00 2001 From: Yunjie Ye Date: Thu, 11 Dec 2025 19:52:15 +0800 Subject: [PATCH 1434/3659] drivers: video: ov2640: Fixing the issue of the reset pin for OV2640. The dt binding file requires the reset pin to be configured as `GPIO_ACTIVE_LOW`, but the driver uses the logic of `GPIO_ACTIVE_HIGH`. Therefore, modify the logic in the driver and add a migration guide. Signed-off-by: Yunjie Ye --- doc/releases/migration-guide-4.4.rst | 3 +++ drivers/video/ov2640.c | 3 +-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/doc/releases/migration-guide-4.4.rst b/doc/releases/migration-guide-4.4.rst index b767f9541915..0fefec996e59 100644 --- a/doc/releases/migration-guide-4.4.rst +++ b/doc/releases/migration-guide-4.4.rst @@ -451,6 +451,9 @@ Video :kconfig:option:`CONFIG_VIDEO_BUFFER_POOL_HEAP_SIZE` which represent the size in byte allocated for the whole video buffer pool. +* The :dtcompatible:`ovti,ov2640` reset pin handling has been corrected, resulting in an inverted + active level compared to before, to match the active level expected by the sensor. + .. zephyr-keep-sorted-stop Bluetooth diff --git a/drivers/video/ov2640.c b/drivers/video/ov2640.c index 85989a00af38..baa9cf6f1fbf 100644 --- a/drivers/video/ov2640.c +++ b/drivers/video/ov2640.c @@ -1026,9 +1026,8 @@ static int ov2640_init(const struct device *dev) return ret; } - gpio_pin_set_dt(&cfg->reset_gpio, 0); k_sleep(K_MSEC(1)); - gpio_pin_set_dt(&cfg->reset_gpio, 1); + gpio_pin_set_dt(&cfg->reset_gpio, 0); k_sleep(K_MSEC(1)); #endif From 98749eb58ae39fd16ea3d4d05a609b20ed9c8997 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Fri, 5 Dec 2025 11:07:41 +0100 Subject: [PATCH 1435/3659] soc: nordic: nrf54h: Enable use of RTT on cpuapp MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit RTT need to use RAM which is not cacheable as RTT does not support data cache. Using cpuapp TCM RAM memory section for RTT. Signed-off-by: Krzysztof Chruściński --- boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts | 1 + soc/nordic/nrf54h/Kconfig.defconfig.nrf54h20_cpuapp | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts index a59ca6ffc3be..901ed2939111 100644 --- a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts +++ b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts @@ -44,6 +44,7 @@ watchdog0 = &wdt010; mcuboot-button0 = &button0; mcuboot-led0 = &led0; + rtt-custom-section = &cpuapp_tcm_region; }; buttons { diff --git a/soc/nordic/nrf54h/Kconfig.defconfig.nrf54h20_cpuapp b/soc/nordic/nrf54h/Kconfig.defconfig.nrf54h20_cpuapp index 1260067a2fc5..7659a3a5e747 100644 --- a/soc/nordic/nrf54h/Kconfig.defconfig.nrf54h20_cpuapp +++ b/soc/nordic/nrf54h/Kconfig.defconfig.nrf54h20_cpuapp @@ -20,4 +20,8 @@ config CODE_DATA_RELOCATION config NRF_PERIPHCONF_SECTION default y +choice SEGGER_RTT_SECTION + default SEGGER_RTT_SECTION_CUSTOM_DTS_REGION +endchoice + endif # SOC_NRF54H20_CPUAPP From 3adbf25dffe204c6779b317476cabcdc32e33081 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Fri, 5 Dec 2025 11:06:19 +0100 Subject: [PATCH 1436/3659] drivers: debug: nrf_etr: Add support for RTT backend MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add option to output STM logging on RTT. Signed-off-by: Krzysztof Chruściński --- drivers/debug/Kconfig.nrf | 48 ++++++++++++ drivers/debug/debug_nrf_etr.c | 139 +++++++++++++++++++++++++++------- 2 files changed, 160 insertions(+), 27 deletions(-) diff --git a/drivers/debug/Kconfig.nrf b/drivers/debug/Kconfig.nrf index 7ea5f6bed5f8..266f44efc923 100644 --- a/drivers/debug/Kconfig.nrf +++ b/drivers/debug/Kconfig.nrf @@ -16,6 +16,53 @@ config DEBUG_NRF_ETR if DEBUG_NRF_ETR +DT_CHOSEN_ZEPHYR_CONSOLE := zephyr,console + +config DEBUG_NRF_ETR_BACKEND_UART + default y if $(dt_chosen_enabled,$(DT_CHOSEN_ZEPHYR_CONSOLE)) + bool "UART backend" + +config DEBUG_NRF_ETR_BACKEND_RTT + bool "RTT backend" + select USE_SEGGER_RTT + select SEGGER_RTT_CUSTOM_LOCKING + +if DEBUG_NRF_ETR_BACKEND_RTT + +config DEBUG_NRF_ETR_BACKEND_RTT_BUFFER + int "Buffer number used for logger output." + range 0 SEGGER_RTT_MAX_NUM_UP_BUFFERS + default 0 + help + Select index of up-buffer used for logger output, by default it uses + terminal up-buffer and its settings. + +config DEBUG_NRF_ETR_BACKEND_RTT_BUFFER_SIZE + int "Size of reserved up-buffer for logger output." + default 1024 + depends on DEBUG_NRF_ETR_BACKEND_RTT_BUFFER > 0 + help + Specify reserved size of up-buffer used for logger output. + +config DEBUG_NRF_ETR_BACKEND_RTT_RETRY_CNT + int "Number of retries" + default 4 + help + Number of TX retries before dropping the data and assuming that + RTT session is inactive. + +config DEBUG_NRF_ETR_BACKEND_RTT_RETRY_DELAY_MS + int "Delay between TX retries in milliseconds" + default 5 + help + Sleep period between TX retry attempts. During RTT session, host pulls + data periodically. Period starts from 1-2 milliseconds and can be + increased if traffic on RTT increases (also from host to device). In + case of heavy traffic data can be lost and it may be necessary to + increase delay or number of retries. + +endif + config DEBUG_NRF_ETR_DECODE bool "Decode ETR content" default y if LOG_FRONTEND_STMESP_FSC @@ -80,6 +127,7 @@ config DEBUG_NRF_ETR_SHELL select UART_ASYNC_RX_HELPER select SHELL_LOG_BACKEND_CUSTOM depends on DEBUG_NRF_ETR_DECODE + depends on DEBUG_NRF_ETR_BACKEND_UART default y if SHELL help Enable shell with Coresight STM logging support. diff --git a/drivers/debug/debug_nrf_etr.c b/drivers/debug/debug_nrf_etr.c index 200d6edbc1a7..167671f13006 100644 --- a/drivers/debug/debug_nrf_etr.c +++ b/drivers/debug/debug_nrf_etr.c @@ -22,6 +22,11 @@ #include #include #include + +#ifdef CONFIG_DEBUG_NRF_ETR_BACKEND_RTT +#include +#endif + LOG_MODULE_REGISTER(cs_etr_tbm); #define UART_NODE DT_CHOSEN(zephyr_console) @@ -79,7 +84,7 @@ static uint32_t etr_rd_idx; /* Counts number of new messages completed in the current formatter frame decoding. */ static uint32_t new_msg_cnt; -static bool volatile use_async_uart; +static bool volatile use_blocking; static struct k_sem uart_sem; static const struct device *uart_dev = DEVICE_DT_GET(UART_NODE); @@ -149,27 +154,101 @@ static shell_transport_handler_t shell_handler; static void *shell_context; #endif +#ifdef CONFIG_DEBUG_NRF_ETR_BACKEND_RTT + +#define RTT_LOCK() \ + COND_CODE_0(CONFIG_DEBUG_NRF_ETR_BACKEND_RTT_BUFFER, (SEGGER_RTT_LOCK()), ()) + +#define RTT_UNLOCK() \ + COND_CODE_0(CONFIG_DEBUG_NRF_ETR_BACKEND_RTT_BUFFER, (SEGGER_RTT_UNLOCK()), ()) + +static uint8_t rtt_buf[COND_CODE_0(CONFIG_DEBUG_NRF_ETR_BACKEND_RTT_BUFFER, (1), + (CONFIG_DEBUG_NRF_ETR_BACKEND_RTT_BUFFER_SIZE))]; + +static volatile bool rtt_host_present; + +static void rtt_on_failed_write(int retry_cnt, bool in_panic) +{ + if (retry_cnt == 0) { + rtt_host_present = false; + } else if (in_panic) { + k_busy_wait(USEC_PER_MSEC * CONFIG_DEBUG_NRF_ETR_BACKEND_RTT_RETRY_DELAY_MS); + } else { + k_msleep(CONFIG_DEBUG_NRF_ETR_BACKEND_RTT_RETRY_DELAY_MS); + } +} + +static void rtt_on_write(int retry_cnt, bool in_panic) +{ + rtt_host_present = true; + if (use_blocking) { + /* In panic mode block on each write until host reads it. This + * way it is ensured that if system resets all messages are read + * by the host. While pending on data being read by the host we + * must also detect situation where host is disconnected. + */ + while (SEGGER_RTT_HasDataUp(CONFIG_DEBUG_NRF_ETR_BACKEND_RTT_BUFFER)) { + rtt_on_failed_write(retry_cnt--, in_panic); + } + } + +} + +static void rtt_write(uint8_t *data, size_t length, bool in_panic) +{ + int ret = 0; + int retry_cnt = CONFIG_DEBUG_NRF_ETR_BACKEND_RTT_RETRY_CNT; + + do { + if (!in_panic) { + RTT_LOCK(); + ret = SEGGER_RTT_WriteSkipNoLock(CONFIG_DEBUG_NRF_ETR_BACKEND_RTT_BUFFER, + data, length); + RTT_UNLOCK(); + } else { + ret = SEGGER_RTT_WriteSkipNoLock(CONFIG_DEBUG_NRF_ETR_BACKEND_RTT_BUFFER, + data, length); + } + + if (ret) { + rtt_on_write(retry_cnt, in_panic); + } else if (rtt_host_present) { + retry_cnt--; + rtt_on_failed_write(retry_cnt, in_panic); + } else { + } + } while ((ret == 0) && rtt_host_present); +} +#endif /* CONFIG_DEBUG_NRF_ETR_BACKEND_RTT */ + static int log_output_func(uint8_t *buf, size_t size, void *ctx) { - if (use_async_uart) { - int err; - static uint8_t *tx_buf = (uint8_t *)frame_buf0; + ARG_UNUSED(ctx); - err = k_sem_take(&uart_sem, K_FOREVER); - __ASSERT_NO_MSG(err >= 0); + if (IS_ENABLED(CONFIG_DEBUG_NRF_ETR_BACKEND_UART)) { + if (use_blocking) { + for (int i = 0; i < size; i++) { + uart_poll_out(uart_dev, buf[i]); + } + } else { + int err; + static uint8_t *tx_buf = (uint8_t *)frame_buf0; - memcpy(tx_buf, buf, size); + err = k_sem_take(&uart_sem, K_FOREVER); + __ASSERT_NO_MSG(err >= 0); - err = uart_tx(uart_dev, tx_buf, size, SYS_FOREVER_US); - __ASSERT_NO_MSG(err >= 0); + memcpy(tx_buf, buf, size); - tx_buf = (tx_buf == (uint8_t *)frame_buf0) ? - (uint8_t *)frame_buf1 : (uint8_t *)frame_buf0; - } else { - for (int i = 0; i < size; i++) { - uart_poll_out(uart_dev, buf[i]); + err = uart_tx(uart_dev, tx_buf, size, SYS_FOREVER_US); + __ASSERT_NO_MSG(err >= 0); + + tx_buf = (tx_buf == (uint8_t *)frame_buf0) ? + (uint8_t *)frame_buf1 : (uint8_t *)frame_buf0; } } +#ifdef CONFIG_DEBUG_NRF_ETR_BACKEND_RTT + rtt_write(buf, size, use_blocking); +#endif return size; } @@ -528,16 +607,16 @@ static void dump_frame(uint8_t *buf) { int err; - if (use_async_uart) { + if (use_blocking) { + for (int i = 0; i < CORESIGHT_TRACE_FRAME_SIZE; i++) { + uart_poll_out(uart_dev, buf[i]); + } + } else { err = k_sem_take(&uart_sem, K_FOREVER); __ASSERT_NO_MSG(err >= 0); err = uart_tx(uart_dev, buf, CORESIGHT_TRACE_FRAME_SIZE, SYS_FOREVER_US); __ASSERT_NO_MSG(err >= 0); - } else { - for (int i = 0; i < CORESIGHT_TRACE_FRAME_SIZE; i++) { - uart_poll_out(uart_dev, buf[i]); - } } } @@ -593,7 +672,7 @@ static void process(void) } } else { dump_frame((uint8_t *)frame_buf); - frame_buf = (use_async_uart && (frame_buf == frame_buf0)) ? + frame_buf = (!use_blocking && (frame_buf == frame_buf0)) ? frame_buf1 : frame_buf0; } } @@ -649,7 +728,7 @@ void debug_nrf_etr_flush(void) /* Set flag which forces uart to use blocking polling out instead of * asynchronous API. */ - use_async_uart = false; + use_blocking = true; uint32_t k = irq_lock(); /* Repeat arbitrary number of times to ensure that all that is flushed. */ @@ -754,17 +833,23 @@ static void tbm_event_handler(nrf_tbm_event_t event) int etr_process_init(void) { +#ifdef CONFIG_DEBUG_NRF_ETR_BACKEND_RTT + if (CONFIG_DEBUG_NRF_ETR_BACKEND_RTT_BUFFER > 0) { + SEGGER_RTT_ConfigUpBuffer(CONFIG_DEBUG_NRF_ETR_BACKEND_RTT_BUFFER, "stm_logger", + rtt_buf, sizeof(rtt_buf), + SEGGER_RTT_MODE_NO_BLOCK_SKIP); + } +#endif int err; - k_sem_init(&uart_sem, 1, 1); - - err = uart_callback_set(uart_dev, uart_event_handler, NULL); - use_async_uart = (err == 0); - + if (IS_ENABLED(CONFIG_DEBUG_NRF_ETR_BACKEND_UART)) { + err = uart_callback_set(uart_dev, uart_event_handler, NULL); + use_blocking = (err != 0); + k_sem_init(&uart_sem, 1, 1); + } static const nrfx_tbm_config_t config = {.size = wsize_mask}; nrfx_tbm_init(&config, tbm_event_handler); - IRQ_CONNECT(DT_IRQN(DT_NODELABEL(tbm)), DT_IRQ(DT_NODELABEL(tbm), priority), nrfx_isr, nrfx_tbm_irq_handler, 0); irq_enable(DT_IRQN(DT_NODELABEL(tbm))); From 48978f876e228422bd9ad194440bfcb77e039130 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Fri, 5 Dec 2025 10:59:39 +0100 Subject: [PATCH 1437/3659] samples: boards: nordic: coresight_stm: Add RTT configuration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add sample configuration that uses RTT backend for STM logging. Signed-off-by: Krzysztof Chruściński --- samples/boards/nordic/coresight_stm/sample.yaml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/samples/boards/nordic/coresight_stm/sample.yaml b/samples/boards/nordic/coresight_stm/sample.yaml index 9ff835d8ffad..10f1d153855a 100644 --- a/samples/boards/nordic/coresight_stm/sample.yaml +++ b/samples/boards/nordic/coresight_stm/sample.yaml @@ -41,6 +41,17 @@ tests: - SB_CONFIG_APP_CPUPPR_RUN=y - SB_CONFIG_APP_CPUFLPR_RUN=y + sample.boards.nrf.coresight_stm.rtt: + required_snippets: + - nordic-log-stm + extra_configs: + - CONFIG_DEBUG_NRF_ETR_BACKEND_RTT=y + - CONFIG_DEBUG_NRF_ETR_BACKEND_UART=n + - CONFIG_SEGGER_RTT_BUFFER_SIZE_UP=8192 + extra_args: + - SB_CONFIG_APP_CPUPPR_RUN=y + - SB_CONFIG_APP_CPUFLPR_RUN=y + sample.boards.nrf.coresight_stm.local_uart: harness: console harness_config: From a289e607d4c44a4d1c37aaccbcbb4ed093d9489f Mon Sep 17 00:00:00 2001 From: Fabrice DJIATSA Date: Mon, 5 Jan 2026 15:53:48 +0100 Subject: [PATCH 1438/3659] tests: drivers: disk: disk_access: relax out-of-bounds erase assertion The sector erase tests previously asserted for a specific -EINVAL return code when attempting to erase past the end of the disk. This is too strict for drivers that report a generic I/O error (-EIO) in such situations, e.g. the STM32 SDMMC driver, which maps HAL failures to -EIO without inspecting the precise root cause. We can also note that the same logic was used in test_sector_write() and test_sector_read(). This change avoids spurious test failures with targets that legitimately return non-zero errors other than -EINVAL. Signed-off-by: Fabrice DJIATSA --- tests/drivers/disk/disk_access/src/main.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/tests/drivers/disk/disk_access/src/main.c b/tests/drivers/disk/disk_access/src/main.c index 020bbadb6215..252dd3f6db7f 100644 --- a/tests/drivers/disk/disk_access/src/main.c +++ b/tests/drivers/disk/disk_access/src/main.c @@ -285,14 +285,11 @@ static void test_sector_erase(uint8_t *wbuf, uint8_t *rbuf, uint32_t num_sectors /* Try and erase past the last sector */ rc = erase_sector_checked(rbuf, disk_sector_count - num_sectors + 1, num_sectors); - zassert_equal(rc, -EINVAL, - "Unexpected error code when attempting to erase past end of disk"); + zassert_not_equal(rc, 0, "Should fail when attempting to erase past end of disk"); rc = erase_sector_checked(rbuf, disk_sector_count + 1, num_sectors); - zassert_equal(rc, -EINVAL, - "Unexpected error code when attempting to erase past end of disk"); + zassert_not_equal(rc, 0, "Should fail when attempting to erase past end of disk"); rc = erase_sector_checked(rbuf, UINT32_MAX, num_sectors); - zassert_equal(rc, -EINVAL, - "Unexpected error code when attempting to erase past end of disk"); + zassert_not_equal(rc, 0, "Should fail when attempting to erase past end of disk"); } /* Test multiple reads in series, and reading from a variety of blocks */ From 6915d2f5910cb86c21033ac1a75d12d27a4bcb5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fin=20Maa=C3=9F?= Date: Wed, 19 Nov 2025 09:34:16 +0100 Subject: [PATCH 1439/3659] soc: litex: deprecate 8 bit CSR data width MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 5 years ago LiteX switched to 32 bit csr data width, while the option is still available in litex, it doesn't really work there, even if it can be build, the bios f.e. won't boot. already described in https://github.com/enjoy-digital/litex/issues/1062 So it is currently only here for designs, that are older than 5 years and for fpgas, where also the fpga bitstream can be updated it is time to remove the support and require the users, when they wan't to update zephyr, that they also have to update their fpga bitstream. Signed-off-by: Fin Maaß --- soc/litex/litex_vexriscv/Kconfig | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/soc/litex/litex_vexriscv/Kconfig b/soc/litex/litex_vexriscv/Kconfig index 5543d09bbe72..00d5c6d05bf4 100644 --- a/soc/litex/litex_vexriscv/Kconfig +++ b/soc/litex/litex_vexriscv/Kconfig @@ -19,6 +19,14 @@ config LITEX_CSR_DATA_WIDTH int "Select Control/Status register width" default 32 +config LITEX_CSR_DATA_WIDTH_DEPRECATED + def_bool y + depends on LITEX_CSR_DATA_WIDTH != 32 + select DEPRECATED + help + This option is there to select DEPRECATED, when LITEX_CSR_DATA_WIDTH is + set to a value other than 32. It will be removed in future releases. + choice LITEX_CSR_ORDERING prompt "Select Control/Status register ordering" default LITEX_CSR_ORDERING_BIG From 7c97becb3ebec1e799140964c50be1dde6177940 Mon Sep 17 00:00:00 2001 From: Sandro Scherer Date: Wed, 10 Dec 2025 08:19:27 +0100 Subject: [PATCH 1440/3659] drivers: ethernet: lan865x: fix seed for random backoff To activate changes in mac address registers the top register has to be written Signed-off-by: Sandro Scherer --- drivers/ethernet/eth_lan865x.c | 3 +++ drivers/ethernet/eth_lan865x_priv.h | 1 + 2 files changed, 4 insertions(+) diff --git a/drivers/ethernet/eth_lan865x.c b/drivers/ethernet/eth_lan865x.c index 8162cf5b4022..cdd0e5cce694 100644 --- a/drivers/ethernet/eth_lan865x.c +++ b/drivers/ethernet/eth_lan865x.c @@ -231,6 +231,9 @@ static void lan865x_write_macaddress(const struct device *dev) */ val = (mac[5] << 24) | (mac[4] << 16) | (mac[3] << 8) | mac[2]; oa_tc6_reg_write(ctx->tc6, LAN865x_MAC_SAB1, val); + /* SPEC_ADD1_TOP - write top register too for activation */ + val = mac[1] << 8 | mac[0]; + oa_tc6_reg_write(ctx->tc6, LAN865x_MAC_SAT1, val); } static int lan865x_set_specific_multicast_addr(const struct device *dev) diff --git a/drivers/ethernet/eth_lan865x_priv.h b/drivers/ethernet/eth_lan865x_priv.h index a92f8bd93e6e..238ac9e0a1ae 100644 --- a/drivers/ethernet/eth_lan865x_priv.h +++ b/drivers/ethernet/eth_lan865x_priv.h @@ -33,6 +33,7 @@ #define LAN865x_MAC_HRB MMS_REG(0x1, 0x020) #define LAN865x_MAC_HRT MMS_REG(0x1, 0x021) #define LAN865x_MAC_SAB1 MMS_REG(0x1, 0x022) +#define LAN865x_MAC_SAT1 MMS_REG(0x1, 0x023) #define LAN865x_MAC_SAB2 MMS_REG(0x1, 0x024) #define LAN865x_MAC_SAT2 MMS_REG(0x1, 0x025) /* LAN8650/1 configuration fixup from AN1760 */ From db0a748a7a988b9e9ab32fdb20ae817704fa92aa Mon Sep 17 00:00:00 2001 From: Jiafei Pan Date: Tue, 6 Jan 2026 15:45:22 +0800 Subject: [PATCH 1441/3659] drivers: counter: gpt: remove unused variable "clock_name_t clock_source" is not used by the driver, so remove it. Signed-off-by: Jiafei Pan --- drivers/counter/counter_mcux_gpt.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/counter/counter_mcux_gpt.c b/drivers/counter/counter_mcux_gpt.c index c0e714ea41dc..222f9615c9ce 100644 --- a/drivers/counter/counter_mcux_gpt.c +++ b/drivers/counter/counter_mcux_gpt.c @@ -27,7 +27,6 @@ struct mcux_gpt_config { const struct device *clock_dev; clock_control_subsys_t clock_subsys; - clock_name_t clock_source; void (*irq_config_func)(void); }; From 1523c5913cbdfb5a9d6c5ac8d12064e7e104945a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Tue, 6 Jan 2026 21:02:00 +0100 Subject: [PATCH 1442/3659] boards: intel: add full_name to intel_wcl_crb MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit add full_name for this board in board.yml Signed-off-by: Benjamin Cabé --- boards/intel/wcl/board.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/boards/intel/wcl/board.yml b/boards/intel/wcl/board.yml index c7fc9d37506f..88803532bceb 100644 --- a/boards/intel/wcl/board.yml +++ b/boards/intel/wcl/board.yml @@ -1,5 +1,6 @@ boards: - name: intel_wcl_crb + full_name: Wildcat Lake CRB vendor: intel socs: - name: wildcat_lake From da229a08e01d386ed5eaa061b984fd5d47dc99fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Tue, 6 Jan 2026 21:02:29 +0100 Subject: [PATCH 1443/3659] boards: mediatek: add missing full_name to mediatek boards MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit add full_name for mediatek boards in board.yml Signed-off-by: Benjamin Cabé --- boards/mediatek/mt8186/board.yml | 1 + boards/mediatek/mt8188/board.yml | 1 + boards/mediatek/mt8196/board.yml | 1 + 3 files changed, 3 insertions(+) diff --git a/boards/mediatek/mt8186/board.yml b/boards/mediatek/mt8186/board.yml index 04582e157f7c..5b8635c48d3b 100644 --- a/boards/mediatek/mt8186/board.yml +++ b/boards/mediatek/mt8186/board.yml @@ -1,5 +1,6 @@ boards: - name: mt8186 + full_name: MT8186 ADSP vendor: mediatek socs: - name: mt8186 diff --git a/boards/mediatek/mt8188/board.yml b/boards/mediatek/mt8188/board.yml index f50e9227a82c..12c22abfd94d 100644 --- a/boards/mediatek/mt8188/board.yml +++ b/boards/mediatek/mt8188/board.yml @@ -1,5 +1,6 @@ boards: - name: mt8188 + full_name: MT8188 ADSP vendor: mediatek socs: - name: mt8188 diff --git a/boards/mediatek/mt8196/board.yml b/boards/mediatek/mt8196/board.yml index cf5a2e276992..761ae53eed26 100644 --- a/boards/mediatek/mt8196/board.yml +++ b/boards/mediatek/mt8196/board.yml @@ -1,5 +1,6 @@ boards: - name: mt8196 + full_name: MT8196 ADSP vendor: mediatek socs: - name: mt8196 From 872e66be268c5eacab655bc89e08025f0ca79bbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Tue, 6 Jan 2026 21:02:43 +0100 Subject: [PATCH 1444/3659] boards: openhwgroup: add missing full_name to openhwgroup boards MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit add full_name for openhwgroup boards in board.yml Signed-off-by: Benjamin Cabé --- boards/openhwgroup/cv32a6_genesys_2/board.yml | 1 + boards/openhwgroup/cv64a6_genesys_2/board.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/boards/openhwgroup/cv32a6_genesys_2/board.yml b/boards/openhwgroup/cv32a6_genesys_2/board.yml index 64fbf0833829..2aae44c91914 100644 --- a/boards/openhwgroup/cv32a6_genesys_2/board.yml +++ b/boards/openhwgroup/cv32a6_genesys_2/board.yml @@ -2,6 +2,7 @@ # SPDX-License-Identifier: Apache-2.0 board: name: cv32a6_genesys_2 + full_name: Digilent CV32A6 on Genesys 2 vendor: openhwgroup socs: - name: cv32a6 diff --git a/boards/openhwgroup/cv64a6_genesys_2/board.yml b/boards/openhwgroup/cv64a6_genesys_2/board.yml index 293fab13c58f..e08ea7e79280 100644 --- a/boards/openhwgroup/cv64a6_genesys_2/board.yml +++ b/boards/openhwgroup/cv64a6_genesys_2/board.yml @@ -2,6 +2,7 @@ # SPDX-License-Identifier: Apache-2.0 board: name: cv64a6_genesys_2 + full_name: Digilent CV64A6 on Genesys 2 vendor: openhwgroup socs: - name: cv64a6_imafdc From 55883e4b59471ac1cd900d167d5658f69ab3ec94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Tue, 6 Jan 2026 21:02:56 +0100 Subject: [PATCH 1445/3659] boards: realtek: add missing full_name to realtek boards MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit add full_name for realtek boards in board.yml Signed-off-by: Benjamin Cabé --- boards/realtek/rtl872xd_evb/board.yml | 1 + boards/realtek/rtl872xda_evb/board.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/boards/realtek/rtl872xd_evb/board.yml b/boards/realtek/rtl872xd_evb/board.yml index 300c8479ca02..17eb0cdcfd3d 100644 --- a/boards/realtek/rtl872xd_evb/board.yml +++ b/boards/realtek/rtl872xd_evb/board.yml @@ -1,5 +1,6 @@ board: name: rtl872xd_evb + full_name: RTL872xD Evaluation Board vendor: realtek socs: - name: rtl872xd diff --git a/boards/realtek/rtl872xda_evb/board.yml b/boards/realtek/rtl872xda_evb/board.yml index e92ad06fcade..fecae3eac711 100644 --- a/boards/realtek/rtl872xda_evb/board.yml +++ b/boards/realtek/rtl872xda_evb/board.yml @@ -1,5 +1,6 @@ board: name: rtl872xda_evb + full_name: RTL8721Dx Evaluation Board vendor: realtek socs: - name: rtl8721dx From 9822ca54ec44b67885c6e2cb4ada05ec8464fb6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Tue, 6 Jan 2026 22:23:00 +0100 Subject: [PATCH 1446/3659] boards: unit_testing: add full_name to unit_testing board MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit add full_name to unit_testing in board.yml Signed-off-by: Benjamin Cabé --- subsys/testsuite/boards/unit_testing/unit_testing/board.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/subsys/testsuite/boards/unit_testing/unit_testing/board.yml b/subsys/testsuite/boards/unit_testing/unit_testing/board.yml index c3427dc0c65e..0a3029ebb3c6 100644 --- a/subsys/testsuite/boards/unit_testing/unit_testing/board.yml +++ b/subsys/testsuite/boards/unit_testing/unit_testing/board.yml @@ -1,5 +1,6 @@ board: name: unit_testing + full_name: Unit Testing Board vendor: zephyr socs: - name: unit_testing From 901d21e454af3ae7cff323e46f696eb2a439e5bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Tue, 6 Jan 2026 21:10:53 +0100 Subject: [PATCH 1447/3659] scripts: schemas: make `full_name` a required property for boards MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When initially introduced, the property was kept optional in an attempt to not risk disrupting downstream users by introducing a required property they wouldn't necessarily care about. In practice, this is causing boards contributed upstream to sometimes miss this propery which is important for boards to show up nicely in the boards catalog, and it is therefore being made required. Signed-off-by: Benjamin Cabé --- doc/releases/migration-guide-4.4.rst | 2 ++ scripts/schemas/board-schema.yaml | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/doc/releases/migration-guide-4.4.rst b/doc/releases/migration-guide-4.4.rst index 0fefec996e59..370227487354 100644 --- a/doc/releases/migration-guide-4.4.rst +++ b/doc/releases/migration-guide-4.4.rst @@ -27,6 +27,8 @@ Build System C standard version. If your toolchain does not support this standard you will need to use one of the existing and now deprecated options: :kconfig:option:`CONFIG_STD_C99` or :kconfig:option:`CONFIG_STD_C11`. +* The ``full_name`` property of ``board``/``boards`` entries corresponding to new boards in + board.yml files is now required. Kernel ****** diff --git a/scripts/schemas/board-schema.yaml b/scripts/schemas/board-schema.yaml index dc4ea10944d3..f009e7315c61 100644 --- a/scripts/schemas/board-schema.yaml +++ b/scripts/schemas/board-schema.yaml @@ -165,10 +165,10 @@ $defs: $ref: "#/$defs/extendVariantSchema" # Conditional logic for requirements allOf: - # 'name' and 'extend' are mutually exclusive: we're either defining a new board or extending - # an existing one. + # 'name'/'full_name' and 'extend' are mutually exclusive: we're either defining a new board or + # extending an existing one. - oneOf: - - required: [name] + - required: [name, full_name] - required: [extend] # A base board (identified by 'name') must define its hardware via the 'socs' property. - if: From 6efbec10fb7859980a25b71344b839a5e3c40e25 Mon Sep 17 00:00:00 2001 From: Thomas Decker Date: Thu, 18 Dec 2025 10:54:36 +0100 Subject: [PATCH 1448/3659] drivers: serial: uart_stm32: make ptr to clock device const The pointer to the clock device can be const, as it does never change at runtime. This moves the const struct device *clock from data to config struct and initializes it inside the init macro. The __uart_stm32_get_clock function is no longer needed and removed. Signed-off-by: Thomas Decker --- drivers/serial/uart_stm32.c | 26 +++++++------------------- drivers/serial/uart_stm32.h | 4 ++-- 2 files changed, 9 insertions(+), 21 deletions(-) diff --git a/drivers/serial/uart_stm32.c b/drivers/serial/uart_stm32.c index 831baef61109..a22adb444c26 100644 --- a/drivers/serial/uart_stm32.c +++ b/drivers/serial/uart_stm32.c @@ -177,7 +177,6 @@ static inline int uart_stm32_set_baudrate(const struct device *dev, uint32_t bau { const struct uart_stm32_config *config = dev->config; USART_TypeDef *usart = config->usart; - struct uart_stm32_data *data = dev->data; if (baud_rate == 0) { return -EINVAL; @@ -187,7 +186,7 @@ static inline int uart_stm32_set_baudrate(const struct device *dev, uint32_t bau /* Get clock rate */ if (IS_ENABLED(STM32_UART_DOMAIN_CLOCK_SUPPORT) && (config->pclk_len > 1)) { - int ret = clock_control_get_rate(data->clock, + int ret = clock_control_get_rate(config->clock, (clock_control_subsys_t)&config->pclken[1], &clock_rate); if (ret < 0) { @@ -195,7 +194,7 @@ static inline int uart_stm32_set_baudrate(const struct device *dev, uint32_t bau return ret; } } else { - int ret = clock_control_get_rate(data->clock, + int ret = clock_control_get_rate(config->clock, (clock_control_subsys_t)&config->pclken[0], &clock_rate); if (ret < 0) { @@ -877,14 +876,6 @@ static int uart_stm32_err_check(const struct device *dev) return err; } -static inline void __uart_stm32_get_clock(const struct device *dev) -{ - struct uart_stm32_data *data = dev->data; - const struct device *const clk = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE); - - data->clock = clk; -} - #ifdef CONFIG_UART_INTERRUPT_DRIVEN typedef void (*fifo_fill_fn)(USART_TypeDef *usart, const void *tx_data, const int offset); @@ -2201,18 +2192,15 @@ static DEVICE_API(uart, uart_stm32_driver_api) = { static int uart_stm32_clocks_enable(const struct device *dev) { const struct uart_stm32_config *config = dev->config; - struct uart_stm32_data *data = dev->data; int err; - __uart_stm32_get_clock(dev); - - if (!device_is_ready(data->clock)) { + if (!device_is_ready(config->clock)) { LOG_ERR("clock control device not ready"); return -ENODEV; } /* enable clock */ - err = clock_control_on(data->clock, (clock_control_subsys_t)&config->pclken[0]); + err = clock_control_on(config->clock, (clock_control_subsys_t)&config->pclken[0]); if (err != 0) { LOG_ERR("Could not enable (LP)UART clock"); return err; @@ -2418,7 +2406,6 @@ static void uart_stm32_suspend_setup(const struct device *dev) static int uart_stm32_pm_action(const struct device *dev, enum pm_device_action action) { const struct uart_stm32_config *config = dev->config; - struct uart_stm32_data *data = dev->data; int err; switch (action) { @@ -2430,7 +2417,7 @@ static int uart_stm32_pm_action(const struct device *dev, enum pm_device_action } /* Enable bus clock */ - err = clock_control_on(data->clock, (clock_control_subsys_t)&config->pclken[0]); + err = clock_control_on(config->clock, (clock_control_subsys_t)&config->pclken[0]); if (err < 0) { LOG_ERR("Could not enable (LP)UART clock"); return err; @@ -2462,7 +2449,7 @@ static int uart_stm32_pm_action(const struct device *dev, enum pm_device_action case PM_DEVICE_ACTION_SUSPEND: uart_stm32_suspend_setup(dev); /* Stop device clock. Note: fixed clocks are not handled yet. */ - err = clock_control_off(data->clock, (clock_control_subsys_t)&config->pclken[0]); + err = clock_control_off(config->clock, (clock_control_subsys_t)&config->pclken[0]); if (err < 0) { LOG_ERR("Could not disable (LP)UART clock"); return err; @@ -2658,6 +2645,7 @@ static int uart_stm32_pm_action(const struct device *dev, enum pm_device_action \ static const struct uart_stm32_config uart_stm32_cfg_##index = { \ .usart = (USART_TypeDef *)DT_INST_REG_ADDR(index), \ + .clock = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE), \ .reset = RESET_DT_SPEC_GET(DT_DRV_INST(index)), \ .pclken = pclken_##index, \ .pclk_len = DT_INST_NUM_CLOCKS(index), \ diff --git a/drivers/serial/uart_stm32.h b/drivers/serial/uart_stm32.h index d50dbc77c0d9..a1093c862a76 100644 --- a/drivers/serial/uart_stm32.h +++ b/drivers/serial/uart_stm32.h @@ -22,6 +22,8 @@ struct uart_stm32_config { /* USART instance */ USART_TypeDef *usart; + /* clock device */ + const struct device *clock; /* Reset controller device configuration */ const struct reset_dt_spec reset; /* clock subsystem driving this peripheral */ @@ -81,8 +83,6 @@ struct uart_dma_stream { /* driver data */ struct uart_stm32_data { - /* clock device */ - const struct device *clock; /* uart config */ struct uart_config *uart_cfg; #ifdef CONFIG_UART_INTERRUPT_DRIVEN From 358258c799fea99a8472050cec3cea844838e30e Mon Sep 17 00:00:00 2001 From: Realer Mason Date: Fri, 5 Dec 2025 06:30:16 +0000 Subject: [PATCH 1449/3659] dtsi: espressif: add esp32s3_wroom_n32r16.dtsi Add esp32s3_wroom_n32r16.dtsi for some espressif board Signed-off-by: Realer Mason --- .../espressif/esp32s3/esp32s3_wroom_n32r16.dtsi | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 dts/xtensa/espressif/esp32s3/esp32s3_wroom_n32r16.dtsi diff --git a/dts/xtensa/espressif/esp32s3/esp32s3_wroom_n32r16.dtsi b/dts/xtensa/espressif/esp32s3/esp32s3_wroom_n32r16.dtsi new file mode 100644 index 000000000000..816d3ded352d --- /dev/null +++ b/dts/xtensa/espressif/esp32s3/esp32s3_wroom_n32r16.dtsi @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2023 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp32s3_common.dtsi" + +/* 32MB flash */ +&flash0 { + reg = <0x0 DT_SIZE_M(32)>; +}; + +/* 16MB psram */ +&psram0 { + size = ; +}; From 4cf753bfb2e187ba9067996750c73c91582d1ef8 Mon Sep 17 00:00:00 2001 From: Tomasz Leman Date: Thu, 4 Dec 2025 15:26:01 +0100 Subject: [PATCH 1450/3659] ipc_service: Add ipc_service_send_critical function Add ipc_service_send_critical() as a dedicated API for sending critical high-priority messages over an IPC endpoint. Introduce an optional send_critical() callback in struct ipc_service_backend so backends can implement a special fast path that bypasses normal state and busy checks for critical notifications such as crash reports or fatal errors. The ipc_service_send_critical() wrapper mirrors ipc_service_send() on the service side and delegates the actual behavior to the backend-specific send_critical() implementation. Signed-off-by: Tomasz Leman --- include/zephyr/ipc/ipc_service.h | 30 ++++++++++++++++++++++++ include/zephyr/ipc/ipc_service_backend.h | 23 ++++++++++++++++++ subsys/ipc/ipc_service/ipc_service.c | 24 +++++++++++++++++++ 3 files changed, 77 insertions(+) diff --git a/include/zephyr/ipc/ipc_service.h b/include/zephyr/ipc/ipc_service.h index dbc0b8b7ee48..7bcf6c4ca421 100644 --- a/include/zephyr/ipc/ipc_service.h +++ b/include/zephyr/ipc/ipc_service.h @@ -315,6 +315,36 @@ int ipc_service_deregister_endpoint(struct ipc_ept *ept); */ int ipc_service_send(struct ipc_ept *ept, const void *data, size_t len); +/** @brief Send a high-priority message bypassing normal state checks. + * + * This function sends a high-priority message using the backend in a + * special fast path that skips normal state and busy checking. It is + * intended for critical system notifications such as crash reports, + * fatal errors, or emergency shutdown signals that must be delivered + * even when the IPC channel is otherwise considered busy or blocked. + * + * WARNING: This function should only be used for critical system notifications. + * Misuse can lead to data corruption or system instability. The backend must + * support this operation. + * + * @param[in] ept Registered endpoint by @ref ipc_service_register_endpoint. + * @param[in] data Pointer to the critical message buffer to send. + * @param[in] len Number of bytes to send. + * + * @retval -EIO when no backend is registered or send_critical hook is missing + * from backend. + * @retval -EINVAL when instance or endpoint is invalid. + * @retval -ENOENT when the endpoint is not registered with the instance. + * @retval -EBADMSG when the data is invalid (i.e. invalid data format, + * invalid length exceeds backend limits, ...). + * @retval -ENOTSUP when the operation is not supported by backend. + * @retval -ENOMEM when even critical path buffers are exhausted. + * + * @retval bytes number of bytes sent. + * @retval other errno codes depending on the implementation of the backend. + */ +int ipc_service_send_critical(struct ipc_ept *ept, const void *data, size_t len); + /** @brief Get the TX buffer size * * Get the maximal size of a buffer which can be obtained by @ref diff --git a/include/zephyr/ipc/ipc_service_backend.h b/include/zephyr/ipc/ipc_service_backend.h index 3e2f4b11f180..3f0249715459 100644 --- a/include/zephyr/ipc/ipc_service_backend.h +++ b/include/zephyr/ipc/ipc_service_backend.h @@ -71,6 +71,29 @@ struct ipc_service_backend { int (*send)(const struct device *instance, void *token, const void *data, size_t len); + /** @brief Pointer to the function that sends critical messages bypassing flow control. + * + * This function sends high-priority messages directly, bypassing busy checks + * and normal queuing mechanisms. It should be used only for critical system + * notifications like crash reports or fatal errors. + * + * @param[in] instance Instance pointer. + * @param[in] token Backend-specific token. + * @param[in] data Pointer to the buffer to send. + * @param[in] len Number of bytes to send. + * + * @retval -EINVAL when instance is invalid. + * @retval -ENOENT when the endpoint is not registered with the instance. + * @retval -EBADMSG when the message is invalid. + * @retval -ENOTSUP when critical send is not supported. + * @retval -ENOMEM when even critical buffers are unavailable. + * + * @retval bytes number of bytes sent. + * @retval other errno codes depending on the implementation of the backend. + */ + int (*send_critical)(const struct device *instance, void *token, + const void *data, size_t len); + /** @brief Pointer to the function that will be used to register endpoints. * * @param[in] instance Instance to register the endpoint onto. diff --git a/subsys/ipc/ipc_service/ipc_service.c b/subsys/ipc/ipc_service/ipc_service.c index bc2e1bf7918c..c8aa76c70d62 100644 --- a/subsys/ipc/ipc_service/ipc_service.c +++ b/subsys/ipc/ipc_service/ipc_service.c @@ -144,6 +144,30 @@ int ipc_service_send(struct ipc_ept *ept, const void *data, size_t len) return backend->send(ept->instance, ept->token, data, len); } +int ipc_service_send_critical(struct ipc_ept *ept, const void *data, size_t len) +{ + const struct ipc_service_backend *backend; + + if (!ept) { + LOG_ERR("Invalid endpoint"); + return -EINVAL; + } + + if (!ept->instance) { + LOG_ERR("Endpoint not registered\n"); + return -ENOENT; + } + + backend = ept->instance->api; + + if (!backend || !backend->send_critical) { + LOG_ERR("Invalid backend configuration"); + return -EIO; + } + + return backend->send_critical(ept->instance, ept->token, data, len); +} + int ipc_service_get_tx_buffer_size(struct ipc_ept *ept) { const struct ipc_service_backend *backend; From 15fa6a374ec07b952b9ada7adadbdb81a03aa31b Mon Sep 17 00:00:00 2001 From: Tomasz Leman Date: Fri, 5 Dec 2025 10:49:26 +0100 Subject: [PATCH 1451/3659] ipc: intel_adsp: simplify host IPC service backend Rework the Intel Audio DSP host IPC service backend to use the generic ipc_service data/len conventions and the new critical send and buffer management APIs. Replace the backend-specific intel_adsp_ipc_msg and related enums with a simple two-word payload passed through the standard ipc_service_send() and ipc_service_send_critical() interfaces, and adapt the ISR and receive callback to operate on this representation. Use ipc_service_get_tx_buffer_size() as a readiness check for the host channel and provide hold_rx_buffer() / release_rx_buffer() implementations so ipc_service_release_rx_buffer() can be used to signal when the channel becomes available again. Wire the emergency send path through send_critical() to route urgent messages via the backend's emergency fast path while keeping the normal IPC flow unchanged. Move the synchronous IPC wait logic out of the Intel Audio DSP host IPC backend and into the common intel_adsp_ipc helper used by tests. Update intel_adsp_ipc_send_message_sync() to both send the IPC message through ipc_service_send() and wait on the backend semaphore, and remove the now redundant ipc_send_message_sync() helper from the host IPC backend. Document that intel_adsp_ipc_send_message_sync() is a test-only helper, not used by SOF firmware, and that it is a candidate for future removal or for replacement by an explicit synchronous send primitive in the generic IPC service API or in application code. Signed-off-by: Tomasz Leman --- .../zephyr/ipc/backends/intel_adsp_host_ipc.h | 58 +------ soc/intel/intel_adsp/common/ipc.c | 91 +++++------ .../backends/ipc_intel_adsp_host_ipc.c | 150 ++++++++++-------- 3 files changed, 125 insertions(+), 174 deletions(-) diff --git a/include/zephyr/ipc/backends/intel_adsp_host_ipc.h b/include/zephyr/ipc/backends/intel_adsp_host_ipc.h index 74938e53c86f..7929b8290083 100644 --- a/include/zephyr/ipc/backends/intel_adsp_host_ipc.h +++ b/include/zephyr/ipc/backends/intel_adsp_host_ipc.h @@ -14,54 +14,6 @@ #include -/** Enum on IPC send length argument to indicate IPC message type. */ -enum intel_adsp_send_len { - /** Normal IPC message. */ - INTEL_ADSP_IPC_SEND_MSG, - - /** Synchronous IPC message. */ - INTEL_ADSP_IPC_SEND_MSG_SYNC, - - /** Emergency IPC message. */ - INTEL_ADSP_IPC_SEND_MSG_EMERGENCY, - - /** Send a DONE message. */ - INTEL_ADSP_IPC_SEND_DONE, - - /** Query backend to see if IPC is complete. */ - INTEL_ADSP_IPC_SEND_IS_COMPLETE, -}; - -/** Enum on callback return values. */ -enum intel_adsp_cb_ret { - /** Callback return to indicate no issue. Must be 0. */ - INTEL_ADSP_IPC_CB_RET_OKAY = 0, - - /** Callback return to signal needing external completion. */ - INTEL_ADSP_IPC_CB_RET_EXT_COMPLETE, -}; - -/** Enum on callback length argument to indicate which triggers the callback. */ -enum intel_adsp_cb_len { - /** Callback length to indicate this is an IPC message. */ - INTEL_ADSP_IPC_CB_MSG, - - /** Callback length to indicate this is a DONE message. */ - INTEL_ADSP_IPC_CB_DONE, -}; - -/** Struct for IPC message descriptor. */ -struct intel_adsp_ipc_msg { - /** Header specific to platform. */ - uint32_t data; - - /** Extension specific to platform. */ - uint32_t ext_data; - - /** Timeout for sending synchronuous message. */ - k_timeout_t timeout; -}; - #ifdef CONFIG_INTEL_ADSP_IPC_OLD_INTERFACE /** @@ -89,6 +41,7 @@ struct intel_adsp_ipc_msg { */ typedef bool (*intel_adsp_ipc_handler_t)(const struct device *dev, void *arg, uint32_t data, uint32_t ext_data); +#endif /* CONFIG_INTEL_ADSP_IPC_OLD_INTERFACE */ /** * @brief Intel ADSP IPC Message Complete Callback. @@ -114,8 +67,6 @@ typedef bool (*intel_adsp_ipc_handler_t)(const struct device *dev, void *arg, ui */ typedef bool (*intel_adsp_ipc_done_t)(const struct device *dev, void *arg); -#endif /* CONFIG_INTEL_ADSP_IPC_OLD_INTERFACE */ - #ifdef CONFIG_PM_DEVICE typedef int (*intel_adsp_ipc_resume_handler_t)(const struct device *dev, void *arg); @@ -152,13 +103,13 @@ struct intel_adsp_ipc_data { /** Argument for message handler callback. */ void *handler_arg; +#endif /* CONFIG_INTEL_ADSP_IPC_OLD_INTERFACE */ /** Callback for done notification. */ intel_adsp_ipc_done_t done_notify; /** Argument for done notification callback. */ void *done_arg; -#endif /* CONFIG_INTEL_ADSP_IPC_OLD_INTERFACE */ #ifdef CONFIG_PM_DEVICE /** Pointer to resume handler. */ @@ -179,9 +130,8 @@ struct intel_adsp_ipc_data { * Endpoint private data struct. */ struct intel_adsp_ipc_ept_priv_data { - /** Callback return value (enum intel_adsp_cb_ret). */ - int cb_ret; - + /* Message done flag. */ + bool msg_done; /** Pointer to additional private data. */ void *priv; }; diff --git a/soc/intel/intel_adsp/common/ipc.c b/soc/intel/intel_adsp/common/ipc.c index aff2c2f70ee6..981bbbecb6cf 100644 --- a/soc/intel/intel_adsp/common/ipc.c +++ b/soc/intel/intel_adsp/common/ipc.c @@ -43,94 +43,75 @@ static void intel_adsp_ipc_receive_cb(const void *data, size_t len, void *priv) struct intel_adsp_ipc_data *devdata = dev->data; struct intel_adsp_ipc_ept_priv_data *priv_data = (struct intel_adsp_ipc_ept_priv_data *)priv; - bool done = true; - - if (len == INTEL_ADSP_IPC_CB_MSG) { - const struct intel_adsp_ipc_msg *msg = (const struct intel_adsp_ipc_msg *)data; - - if (devdata->handle_message != NULL) { - done = devdata->handle_message(dev, devdata->handler_arg, msg->data, - msg->ext_data); - } - - if (done) { - priv_data->cb_ret = INTEL_ADSP_IPC_CB_RET_OKAY; - } else { - priv_data->cb_ret = -EBADMSG; - } - } else if (len == INTEL_ADSP_IPC_CB_DONE) { - bool external_completion = false; - - if (devdata->done_notify != NULL) { - external_completion = devdata->done_notify(dev, devdata->done_arg); - } - - if (external_completion) { - priv_data->cb_ret = INTEL_ADSP_IPC_CB_RET_EXT_COMPLETE; - } else { - priv_data->cb_ret = INTEL_ADSP_IPC_CB_RET_OKAY; - } + + __ASSERT(len == sizeof(uint32_t) * 2, "Unexpected IPC payload length: %zu", len); + __ASSERT(data != NULL, "IPC payload pointer is NULL"); + + const uint32_t *msg = (const uint32_t *)data; + + if (devdata->handle_message != NULL) { + priv_data->msg_done = devdata->handle_message(dev, devdata->handler_arg, msg[0], + msg[1]); } } void intel_adsp_ipc_complete(const struct device *dev) { - int ret; - - ret = ipc_service_send(&intel_adsp_ipc_ept, NULL, INTEL_ADSP_IPC_SEND_DONE); + ARG_UNUSED(dev); + int ret = ipc_service_release_rx_buffer(&intel_adsp_ipc_ept, NULL); ARG_UNUSED(ret); + __ASSERT(ret == 0, "ipc_service_release_rx_buffer() failed: %d", ret); } bool intel_adsp_ipc_is_complete(const struct device *dev) { - int ret; - - ret = ipc_service_send(&intel_adsp_ipc_ept, NULL, INTEL_ADSP_IPC_SEND_IS_COMPLETE); - - return ret == 0; + ARG_UNUSED(dev); + return ipc_service_get_tx_buffer_size(&intel_adsp_ipc_ept) > 0; } int intel_adsp_ipc_send_message(const struct device *dev, uint32_t data, uint32_t ext_data) { - struct intel_adsp_ipc_msg msg = {.data = data, .ext_data = ext_data}; - int ret; - - ret = ipc_service_send(&intel_adsp_ipc_ept, &msg, INTEL_ADSP_IPC_SEND_MSG); + ARG_UNUSED(dev); + uint32_t msg[2] = {data, ext_data}; - if (ret < 0) { - return ret; - } - - return 0; + return ipc_service_send(&intel_adsp_ipc_ept, &msg, sizeof(msg)); } +/* + * This helper sends an IPC message and then waits synchronously for completion using the backend + * semaphore. It is currently only used by tests, SOF firmware does not rely on it. + * + * The long‑term plan is to either: + * - remove this helper entirely, + * - move the synchronous wait logic to the application layer (SOF), or + * - extend the generic IPC service API with an explicit synchronous send primitive. + * + * Until that decision is made, the function is kept here only to support existing test code and + * should not be used by new callers. + */ int intel_adsp_ipc_send_message_sync(const struct device *dev, uint32_t data, uint32_t ext_data, k_timeout_t timeout) { - struct intel_adsp_ipc_msg msg = { - .data = data, - .ext_data = ext_data, - .timeout = timeout, - }; - int ret; + uint32_t msg[2] = {data, ext_data}; + struct intel_adsp_ipc_data *devdata = dev->data; - ret = ipc_service_send(&intel_adsp_ipc_ept, &msg, INTEL_ADSP_IPC_SEND_MSG_SYNC); + int ret = ipc_service_send(&intel_adsp_ipc_ept, &msg, sizeof(msg)); if (ret < 0) { - return ret; + k_sem_take(&devdata->sem, timeout); } - return 0; + return ret; } void intel_adsp_ipc_send_message_emergency(const struct device *dev, uint32_t data, uint32_t ext_data) { - struct intel_adsp_ipc_msg msg = {.data = data, .ext_data = ext_data}; int ret; + uint32_t msg[2] = {data, ext_data}; - ret = ipc_service_send(&intel_adsp_ipc_ept, &msg, INTEL_ADSP_IPC_SEND_MSG_EMERGENCY); + ret = ipc_service_send_critical(&intel_adsp_ipc_ept, &msg, sizeof(msg)); ARG_UNUSED(ret); } diff --git a/subsys/ipc/ipc_service/backends/ipc_intel_adsp_host_ipc.c b/subsys/ipc/ipc_service/backends/ipc_intel_adsp_host_ipc.c index 99996c84c0c7..002ac84af0e4 100644 --- a/subsys/ipc/ipc_service/backends/ipc_intel_adsp_host_ipc.c +++ b/subsys/ipc/ipc_service/backends/ipc_intel_adsp_host_ipc.c @@ -68,45 +68,32 @@ static void intel_adsp_ipc_isr(const void *devarg) k_spinlock_key_t key = k_spin_lock(&devdata->lock); if (regs->tdr & INTEL_ADSP_IPC_BUSY) { - bool done = true; - if (ept_cfg->cb.received != NULL) { - struct intel_adsp_ipc_msg cb_msg = { - .data = regs->tdr & ~INTEL_ADSP_IPC_BUSY, - .ext_data = regs->tdd, - }; - - ept_cfg->cb.received(&cb_msg, INTEL_ADSP_IPC_CB_MSG, ept_cfg->priv); + uint32_t msg[2] = {(regs->tdr & ~INTEL_ADSP_IPC_BUSY), regs->tdd}; - done = (priv_data->cb_ret == INTEL_ADSP_IPC_CB_RET_OKAY); + ept_cfg->cb.received(&msg, sizeof(msg), ept_cfg->priv); } regs->tdr = INTEL_ADSP_IPC_BUSY; - if (done) { + if (priv_data->msg_done) { #ifdef CONFIG_SOC_SERIES_INTEL_ADSP_ACE regs->tda = INTEL_ADSP_IPC_ACE1X_TDA_DONE; #else regs->tda = INTEL_ADSP_IPC_DONE; #endif + priv_data->msg_done = false; } } - /* Same signal, but on different bits in 1.5 */ - bool done = (regs->ida & INTEL_ADSP_IPC_DONE); - - if (done) { + /* Same signal, but on different bits in ACE */ + if (regs->ida & INTEL_ADSP_IPC_DONE) { bool external_completion = false; - if (ept_cfg->cb.received != NULL) { - ept_cfg->cb.received(NULL, INTEL_ADSP_IPC_CB_DONE, ept_cfg->priv); - - if (priv_data->cb_ret == INTEL_ADSP_IPC_CB_RET_EXT_COMPLETE) { - external_completion = true; - } + if (devdata->done_notify != NULL) { + external_completion = devdata->done_notify(dev, devdata->done_arg); } devdata->tx_ack_pending = false; - /* * Allow the system to enter the runtime idle state after the IPC acknowledgment * is received. @@ -114,7 +101,7 @@ static void intel_adsp_ipc_isr(const void *devarg) pm_policy_state_lock_put(PM_STATE_RUNTIME_IDLE, PM_ALL_SUBSTATES); k_sem_give(&devdata->sem); - /* IPC completion registers will be set externally. */ + /* IPC completion registers will be set externally */ if (external_completion) { k_spin_unlock(&devdata->lock, key); return; @@ -233,20 +220,6 @@ static int ipc_send_message(const struct device *dev, uint32_t data, uint32_t ex return 0; } -static int ipc_send_message_sync(const struct device *dev, uint32_t data, uint32_t ext_data, - k_timeout_t timeout) -{ - struct intel_adsp_ipc_data *devdata = dev->data; - - int ret = ipc_send_message(dev, data, ext_data); - - if (ret == 0) { - k_sem_take(&devdata->sem, timeout); - } - - return ret; -} - static int ipc_send_message_emergency(const struct device *dev, uint32_t data, uint32_t ext_data) { const struct intel_adsp_ipc_config *const config = dev->config; @@ -301,51 +274,94 @@ static int ipc_send_message_emergency(const struct device *dev, uint32_t data, u */ static int intel_adsp_ipc_send(const struct device *dev, void *token, const void *data, size_t len) { - int ret; + ARG_UNUSED(token); - const struct intel_adsp_ipc_msg *msg = (const struct intel_adsp_ipc_msg *)data; - - switch (len) { - case INTEL_ADSP_IPC_SEND_MSG: { - ret = ipc_send_message(dev, msg->data, msg->ext_data); + if (dev == NULL) { + return -EINVAL; + } - break; + if (len != sizeof(uint32_t) * 2 || data == NULL) { + return -EBADMSG; } - case INTEL_ADSP_IPC_SEND_MSG_SYNC: { - ret = ipc_send_message_sync(dev, msg->data, msg->ext_data, msg->timeout); - break; + const uint32_t *msg = (const uint32_t *)data; + + return ipc_send_message(dev, msg[0], msg[1]); +} + +/* + * Report the availability of the host IPC channel. + * + * This backend uses the TX buffer size query as a way to check whether the host is ready to + * receive the next message. When the IPC channel is idle (no BUSY bit set and no pending TX + * acknowledgment), a single “buffer” of two 32-bit words is considered available and the + * function returns sizeof(uint32_t) * 2. When the channel is still busy, no buffer is + * available and the function returns 0. + * + * Return values: + * - -EINVAL if @p instance is NULL. + * - sizeof(uint32_t) * 2 when the channel is ready for a new message. + * - 0 when the previous message has not yet been fully processed. + */ +int intel_adsp_ipc_get_tx_buffer_size(const struct device *instance, void *token) +{ + ARG_UNUSED(token); + + if (instance == NULL) { + return -EINVAL; } - case INTEL_ADSP_IPC_SEND_MSG_EMERGENCY: { - ret = ipc_send_message_emergency(dev, msg->data, msg->ext_data); - break; + if (ipc_is_complete(instance)) { + return sizeof(uint32_t) * 2; } - case INTEL_ADSP_IPC_SEND_DONE: { - ipc_complete(dev); - ret = 0; + return 0; +} - break; +/* + * This backend does not need to explicitly hold RX buffers because the IPC channel is effectively + * held from the moment the message is received in the interrupt handler until the firmware + * completes the handling. However, we must still provide a hold_rx_buffer() implementation so that + * ipc_service_release_rx_buffer() can check both hold and release callbacks and allow the use of + * ipc_service_release_rx_buffer() to notify the host that the channel is available again. + */ +int intel_adsp_ipc_hold_rx_buffer(const struct device *instance, void *token, void *data) +{ + ARG_UNUSED(instance); + ARG_UNUSED(token); + ARG_UNUSED(data); + return -ENOTSUP; +} + +int intel_adsp_ipc_release_rx_buffer(const struct device *instance, void *token, void *data) +{ + ARG_UNUSED(token); + ARG_UNUSED(data); + + if (instance == NULL) { + return -EINVAL; } - case INTEL_ADSP_IPC_SEND_IS_COMPLETE: { - bool completed = ipc_is_complete(dev); - if (completed) { - ret = 0; - } else { - ret = -EAGAIN; - } + ipc_complete(instance); + return 0; +} - break; +static int intel_adsp_ipc_send_critical(const struct device *dev, void *token, + const void *data, size_t len) +{ + ARG_UNUSED(token); + + if (dev == NULL) { + return -EINVAL; } - default: - ret = -EBADMSG; - break; + if (len != sizeof(uint32_t) * 2 || data == NULL) { + return -EBADMSG; } - return ret; + const uint32_t *msg = (const uint32_t *)data; + + return ipc_send_message_emergency(dev, msg[0], msg[1]); } static int intel_adsp_ipc_dt_init(const struct device *dev) @@ -461,6 +477,10 @@ const static struct ipc_service_backend intel_adsp_ipc_backend_api = { .send = intel_adsp_ipc_send, .register_endpoint = intel_adsp_ipc_register_ept, .deregister_endpoint = intel_adsp_ipc_deregister_ept, + .get_tx_buffer_size = intel_adsp_ipc_get_tx_buffer_size, + .hold_rx_buffer = intel_adsp_ipc_hold_rx_buffer, + .release_rx_buffer = intel_adsp_ipc_release_rx_buffer, + .send_critical = intel_adsp_ipc_send_critical, }; DEVICE_DT_DEFINE(INTEL_ADSP_IPC_HOST_DTNODE, intel_adsp_ipc_dt_init, From 5fae86c69c5e4e82b7fdbfc30efd7686973c70d3 Mon Sep 17 00:00:00 2001 From: Tomasz Leman Date: Mon, 8 Dec 2025 12:03:21 +0100 Subject: [PATCH 1452/3659] intel_adsp: document host IPC backend data model and send hook This patch refreshes the documentation in the Intel Audio DSP host IPC service backend to match the current data model and backend API contracts. The updated comments clarify that ipc_ept_cfg::priv must point to intel_adsp_ipc_ept_priv_data so that the backend can carry state between the ISR and the application callbacks. They also describe that both the send and receive paths operate on a fixed two-word uint32_t IPC payload (header and extended payload) rather than a generic byte buffer, and that len must always be sizeof(uint32_t) * 2. The documentation for intel_adsp_ipc_send() is rewritten to explain the expected payload format, the length and NULL checks performed by the backend, and how the function programs the IPC registers while relying on ipc_send_message() for BUSY and TX acknowledgment handling. The parameter semantics and error returns are aligned with the generic ipc_service send() hook contract to make the backend behaviour easier to understand and reuse. Signed-off-by: Tomasz Leman --- .../backends/ipc_intel_adsp_host_ipc.c | 48 +++++++++---------- 1 file changed, 22 insertions(+), 26 deletions(-) diff --git a/subsys/ipc/ipc_service/backends/ipc_intel_adsp_host_ipc.c b/subsys/ipc/ipc_service/backends/ipc_intel_adsp_host_ipc.c index 002ac84af0e4..3a8938893db4 100644 --- a/subsys/ipc/ipc_service/backends/ipc_intel_adsp_host_ipc.c +++ b/subsys/ipc/ipc_service/backends/ipc_intel_adsp_host_ipc.c @@ -9,16 +9,14 @@ * * @brief IPC service backend for Intel Audio DSP host IPC * - * @note When declaring struct ipt_ept_cfg, the field priv must point to - * a struct intel_adsp_ipc_ept_priv_data. This is used for passing - * callback returns. + * @note When declaring struct ipc_ept_cfg, the field @p priv must point to a struct + * intel_adsp_ipc_ept_priv_data. This is used to pass backend private state between the ISR + * and the application callbacks. * - * @note For sending message and the received callback, the data and len - * arguments are not used to represent a byte array. Instead, - * the data argument points to the descriptor of data to be sent - * (of struct intel_adsp_ipc_msg). The len argument represents - * the type of message to be sent (enum intel_adsp_send_len) and - * the type of callback (enum intel_adsp_cb_len). + * @note For sending messages and in the receive callback, the @p data and @p len arguments + * represent a fixed two-word IPC payload rather than a generic byte buffer. The @p data + * pointer must reference an array of two uint32_t values (header and extended payload) and + * @p len must be sizeof(uint32_t) * 2. */ #define DT_DRV_COMPAT intel_adsp_host_ipc @@ -250,27 +248,25 @@ static int ipc_send_message_emergency(const struct device *dev, uint32_t data, u /** * @brief Send an IPC message. * - * This implements the inner working of ipc_service_send(). + * This implements the backend send() hook used by ipc_service_send() for the Intel Audio DSP host + * IPC. * - * @note Arguments @a data and @a len are not used to point to a byte buffer of data - * to be sent. Instead, @a data must point to a descriptor of data to be sent, - * struct intel_adsp_ipc_msg. And @a len indicates what type of message to send - * as described in enum intel_adsp_send_len. + * The @a data argument is expected to point to an array of two 32-bit words, where the first word + * is the IPC header and the second word is the extended payload. The @a len argument must be + * exactly sizeof(uint32_t) * 2 or the call is rejected. * - * Return values for various message types: - * - For INTEL_ADSP_IPC_SEND_MSG_*, returns 0 when message is sent. Negative errno if - * errors. - * - For INTEL_ADSP_IPC_SEND_DONE, always returns 0 for sending DONE message. - * - For INTEL_ADSP_IPC_SEND_IS_COMPLETE, returns 0 if host has processed the message. - * -EAGAIN if not. + * On success the function programs the IPC registers and starts transmission towards the host, + * enforcing the normal BUSY and TX acknowledgment checks performed by ipc_send_message(). * - * @param[in] dev Pointer to device struct. - * @param[in] token Backend-specific token. - * @param[in] data Descriptor of IPC message to be sent (as struct intel_adsp_ipc_msg). - * @param[in] len Type of message to be sent (described in enum intel_adsp_send_len). + * @param[in] dev Pointer to device struct. + * @param[in] token Backend-specific token (unused). + * @param[in] data Pointer to two-word IPC payload. + * @param[in] len Size of the payload in bytes (must be 8). * - * @return 0 if message is sent successfully or query returns okay. - * Negative errno otherwise. + * @return 0 on success, negative errno on failure. + * -EINVAL if @p dev is NULL. + * -EBADMSG if @p data is NULL or @p len is invalid. + * Propagates error codes from ipc_send_message(). */ static int intel_adsp_ipc_send(const struct device *dev, void *token, const void *data, size_t len) { From 32df2371454654012b6bd9b1425e8017718baedc Mon Sep 17 00:00:00 2001 From: Tomasz Leman Date: Fri, 12 Dec 2025 13:12:30 +0100 Subject: [PATCH 1453/3659] tests: intel_adsp: update smoke IPC tests for new backend This patch updates the intel_adsp smoke tests to use the new host IPC backend data model and APIs. The host IPC smoke test now treats messages as a fixed two-word uint32_t payload instead of using struct intel_adsp_ipc_msg and the INTEL_ADSP_IPC_CB_* message types. The receive callback validates the payload length and pointer, checks the header/payload values against the expected RETURN_MSG_* constants, and sets msg_flag on receipt. The test-specific intel_adsp_ipc_send_message() and intel_adsp_ipc_send_message_sync() helpers are rewritten to send a two-word payload via ipc_service_send(), and the synchronous helper waits on the backend semaphore only when the send succeeds. A dedicated done callback is registered via intel_adsp_ipc_set_done_handler() to drive done_flag, and intel_adsp_ipc_complete() now completes RX by calling ipc_service_release_rx_buffer() and asserting on failure. Completion polling is aligned with the backend by using ipc_service_get_tx_buffer_size(). The clock calibration smoke test is adapted in the same way. It now includes the ipc_service and intel_adsp host IPC backend headers when using the new interface, interprets incoming data as a two-word uint32_t payload, validates the length and pointer, and stores the returned timestamp from the extended payload word into the endpoint private data. The rest of the test flow, including endpoint registration, timestamp requests and clock rate checks, remains unchanged but runs on top of the new IPC backend representation. Signed-off-by: Tomasz Leman --- tests/boards/intel_adsp/smoke/src/clock.c | 19 +++-- tests/boards/intel_adsp/smoke/src/hostipc.c | 83 ++++++++++++--------- 2 files changed, 61 insertions(+), 41 deletions(-) diff --git a/tests/boards/intel_adsp/smoke/src/clock.c b/tests/boards/intel_adsp/smoke/src/clock.c index c7d669ccfc2f..02d16b3a057b 100644 --- a/tests/boards/intel_adsp/smoke/src/clock.c +++ b/tests/boards/intel_adsp/smoke/src/clock.c @@ -9,6 +9,11 @@ #include #include "tests.h" +#ifndef CONFIG_INTEL_ADSP_IPC_OLD_INTERFACE +#include +#include +#endif + #ifdef CONFIG_INTEL_ADSP_IPC_OLD_INTERFACE static volatile uint32_t old_host_dt; @@ -27,15 +32,15 @@ struct intel_adsp_ipc_ept_priv_data test_priv_data; void clock_ipc_receive_cb(const void *data, size_t len, void *priv) { - if (len == INTEL_ADSP_IPC_CB_MSG) { - const struct intel_adsp_ipc_msg *msg = (const struct intel_adsp_ipc_msg *)data; - struct intel_adsp_ipc_ept_priv_data *tpd = - (struct intel_adsp_ipc_ept_priv_data *)priv; + struct intel_adsp_ipc_ept_priv_data *tpd = + (struct intel_adsp_ipc_ept_priv_data *)priv; + const uint32_t *msg = (const uint32_t *)data; - tpd->priv = (void *)msg->data; + zassert_equal(len, sizeof(uint32_t) * 2, "unexpected IPC message length"); + zassert_not_null(data, "IPC payload pointer is NULL"); - tpd->cb_ret = INTEL_ADSP_IPC_CB_RET_OKAY; - } + /* Store returned timestamp from the extended payload word. */ + tpd->priv = (void *)(uintptr_t)msg[1]; } struct ipc_ept_cfg clock_ipc_ept_cfg = { diff --git a/tests/boards/intel_adsp/smoke/src/hostipc.c b/tests/boards/intel_adsp/smoke/src/hostipc.c index 955cd21a4a22..48e4982294b5 100644 --- a/tests/boards/intel_adsp/smoke/src/hostipc.c +++ b/tests/boards/intel_adsp/smoke/src/hostipc.c @@ -38,6 +38,8 @@ static bool ipc_done(const struct device *dev, void *arg) #include #include +typedef bool (*intel_adsp_ipc_done_t)(const struct device *dev, void *arg); + struct ipc_ept host_ipc_ept; void ipc_receive_cb(const void *data, size_t len, void *priv) @@ -45,27 +47,17 @@ void ipc_receive_cb(const void *data, size_t len, void *priv) struct intel_adsp_ipc_ept_priv_data *priv_data = (struct intel_adsp_ipc_ept_priv_data *)priv; - if (len == INTEL_ADSP_IPC_CB_MSG) { - const struct intel_adsp_ipc_msg *msg = (const struct intel_adsp_ipc_msg *)data; - - zassert_equal(msg->data, msg->ext_data, "unequal message data/ext_data"); - zassert_true(msg->data == RETURN_MSG_SYNC_VAL || - msg->data == RETURN_MSG_ASYNC_VAL, "unexpected msg data"); + const uint32_t *msg = (const uint32_t *)data; - msg_flag = true; + ARG_UNUSED(priv_data); - if (msg->data == RETURN_MSG_SYNC_VAL) { - priv_data->cb_ret = INTEL_ADSP_IPC_CB_RET_OKAY; - } else { - priv_data->cb_ret = -EINVAL; - } - } else if (len == INTEL_ADSP_IPC_CB_DONE) { - zassert_false(done_flag, "done called unexpectedly"); + zassert_equal(len, sizeof(uint32_t) * 2, "unexpected IPC message length"); + zassert_not_null(data, "IPC payload pointer is NULL"); - done_flag = true; - - priv_data->cb_ret = INTEL_ADSP_IPC_CB_RET_OKAY; - } + zassert_equal(msg[0], msg[1], "unequal message data/ext_data"); + zassert_true(msg[0] == RETURN_MSG_SYNC_VAL || + msg[0] == RETURN_MSG_ASYNC_VAL, "unexpected msg data"); + msg_flag = true; } static struct intel_adsp_ipc_ept_priv_data host_ipc_priv_data; @@ -78,41 +70,63 @@ struct ipc_ept_cfg host_ipc_ept_cfg = { .priv = &host_ipc_priv_data, }; -static void intel_adsp_ipc_complete(const struct device *dev) +static void intel_adsp_ipc_set_done_handler(const struct device *dev, + intel_adsp_ipc_done_t fn, + void *arg) { - int ret; + struct intel_adsp_ipc_data *devdata = dev->data; + k_spinlock_key_t key = k_spin_lock(&devdata->lock); - ret = ipc_service_send(&host_ipc_ept, NULL, INTEL_ADSP_IPC_SEND_DONE); + devdata->done_notify = fn; + devdata->done_arg = arg; + k_spin_unlock(&devdata->lock, key); +} + +static bool host_ipc_done(const struct device *dev, void *arg) +{ + ARG_UNUSED(dev); + + zassert_is_null(arg, "wrong done arg"); + zassert_false(done_flag, "done called unexpectedly"); + done_flag = true; - ARG_UNUSED(ret); + return false; } -static bool intel_adsp_ipc_is_complete(const struct device *dev) +static void intel_adsp_ipc_complete(const struct device *dev) { int ret; - ret = ipc_service_send(&host_ipc_ept, NULL, INTEL_ADSP_IPC_SEND_IS_COMPLETE); + ARG_UNUSED(dev); + ret = ipc_service_release_rx_buffer(&host_ipc_ept, NULL); + zassert_equal(ret, 0, "ipc_service_release_rx_buffer() failed: %d", ret); +} - return ret == 0; +static bool intel_adsp_ipc_is_complete(const struct device *dev) +{ + ARG_UNUSED(dev); + return ipc_service_get_tx_buffer_size(&host_ipc_ept) > 0; } int intel_adsp_ipc_send_message(const struct device *dev, uint32_t data, uint32_t ext_data) { - struct intel_adsp_ipc_msg msg = {.data = data, .ext_data = ext_data}; - int ret; + ARG_UNUSED(dev); + uint32_t msg[2] = {data, ext_data}; - ret = ipc_service_send(&host_ipc_ept, &msg, INTEL_ADSP_IPC_SEND_MSG); - - return ret; + return ipc_service_send(&host_ipc_ept, &msg, sizeof(msg)); } static int intel_adsp_ipc_send_message_sync(const struct device *dev, uint32_t data, uint32_t ext_data, k_timeout_t timeout) { - struct intel_adsp_ipc_msg msg = {.data = data, .ext_data = ext_data, .timeout = timeout}; - int ret; + uint32_t msg[2] = {data, ext_data}; + struct intel_adsp_ipc_data *devdata = dev->data; - ret = ipc_service_send(&host_ipc_ept, &msg, INTEL_ADSP_IPC_SEND_MSG_SYNC); + int ret = ipc_service_send(&host_ipc_ept, &msg, sizeof(msg)); + + if (ret == 0) { + k_sem_take(&devdata->sem, timeout); + } return ret; } @@ -129,6 +143,7 @@ ZTEST(intel_adsp, test_host_ipc) ret = ipc_service_register_endpoint(INTEL_ADSP_IPC_HOST_DEV, &host_ipc_ept, &host_ipc_ept_cfg); zassert_equal(ret, 0, "cannot register IPC endpoint"); + intel_adsp_ipc_set_done_handler(INTEL_ADSP_IPC_HOST_DEV, host_ipc_done, NULL); #endif /* CONFIG_INTEL_ADSP_IPC_OLD_INTERFACE */ /* Just send a message and wait for it to complete */ @@ -191,10 +206,10 @@ ZTEST(intel_adsp, test_host_ipc) zassert_true(intel_adsp_ipc_is_complete(INTEL_ADSP_IPC_HOST_DEV), "sync message incomplete"); + intel_adsp_ipc_set_done_handler(INTEL_ADSP_IPC_HOST_DEV, NULL, NULL); #ifdef CONFIG_INTEL_ADSP_IPC_OLD_INTERFACE /* Clean up. Further tests might want to use IPC */ intel_adsp_ipc_set_message_handler(INTEL_ADSP_IPC_HOST_DEV, NULL, NULL); - intel_adsp_ipc_set_done_handler(INTEL_ADSP_IPC_HOST_DEV, NULL, NULL); #else /* CONFIG_INTEL_ADSP_IPC_OLD_INTERFACE */ ret = ipc_service_deregister_endpoint(&host_ipc_ept); zassert_equal(ret, 0, "cannot de-register IPC endpoint"); From 69ce1250833236971d05f0de85e86d3f86eb0454 Mon Sep 17 00:00:00 2001 From: Lauren Murphy Date: Thu, 18 Dec 2025 10:52:05 -0800 Subject: [PATCH 1454/3659] twister, west: test extra_conf_files arg to EXTRA_CONF_FILE The extra_conf_files arg in testcase.yaml was being improperly assigned to the CONF_FILE CMake arg, which caused configuration_files.cmake to ignore soc and board Kconfig overlays. Signed-off-by: Lauren Murphy --- samples/boards/nordic/clock_control/prj.conf | 1 + .../pylib/twister/twisterlib/config_parser.py | 20 ++++++++++++------- scripts/pylib/twister/twisterlib/runner.py | 8 ++++++-- scripts/tests/twister/test_runner.py | 16 +++++++++++---- scripts/tests/twister/test_twister.py | 6 +++++- scripts/west_commands/build.py | 2 +- tests/drivers/build_all/modem/prj.conf | 1 + 7 files changed, 39 insertions(+), 15 deletions(-) create mode 100644 samples/boards/nordic/clock_control/prj.conf create mode 100644 tests/drivers/build_all/modem/prj.conf diff --git a/samples/boards/nordic/clock_control/prj.conf b/samples/boards/nordic/clock_control/prj.conf new file mode 100644 index 000000000000..b2a4ba591044 --- /dev/null +++ b/samples/boards/nordic/clock_control/prj.conf @@ -0,0 +1 @@ +# nothing here diff --git a/scripts/pylib/twister/twisterlib/config_parser.py b/scripts/pylib/twister/twisterlib/config_parser.py index 5ffe989f2f5c..992a97689524 100644 --- a/scripts/pylib/twister/twisterlib/config_parser.py +++ b/scripts/pylib/twister/twisterlib/config_parser.py @@ -52,6 +52,7 @@ class TwisterConfigParser: "type": {"type": "str", "default": "integration"}, "extra_args": {"type": "list"}, "extra_configs": {"type": "list"}, + "conf_files": {"type": "list", "default": []}, "extra_conf_files": {"type": "list", "default": []}, "extra_overlay_confs": {"type": "list", "default": []}, "extra_dtc_overlay_files": {"type": "list", "default": []}, @@ -204,17 +205,22 @@ def get_scenario(self, name: str) -> dict[str, Any]: else: d[k] = v - # Compile conf files in to a single list. The order to apply them is: - # (1) CONF_FILEs extracted from common['extra_args'] - # (2) common['extra_conf_files'] - # (3) CONF_FILES extracted from scenarios[name]['extra_args'] - # (4) scenarios[name]['extra_conf_files'] + # Compile extra conf files intended for EXTRA_CONF_FILE into a single list. + # The order to apply them is: + # (1) common['extra_conf_files'] + # (2) scenarios[name]['extra_conf_files'] d["extra_conf_files"] = \ - extracted_common.get("CONF_FILE", []) + \ self.common.get("extra_conf_files", []) + \ - extracted_testsuite.get("CONF_FILE", []) + \ self.scenarios[name].get("extra_conf_files", []) + # Compile conf files intended for CONF_FILE into a single list. + # The order to apply them is: + # (1) CONF_FILEs extracted from common['extra_args'] + # (2) CONF_FILES extracted from scenarios[name]['extra_args'] + d["conf_files"] = \ + extracted_common.get("CONF_FILE", []) + \ + extracted_testsuite.get("CONF_FILE", []) + # Repeat the above for overlay confs and DTC overlay files d["extra_overlay_confs"] = \ extracted_common.get("OVERLAY_CONFIG", []) + \ diff --git a/scripts/pylib/twister/twisterlib/runner.py b/scripts/pylib/twister/twisterlib/runner.py index 577be3e06260..165853e64f58 100644 --- a/scripts/pylib/twister/twisterlib/runner.py +++ b/scripts/pylib/twister/twisterlib/runner.py @@ -1661,7 +1661,7 @@ def name_columns(instance, plat_width, ts_width): sys.stdout.flush() @staticmethod - def cmake_assemble_args(extra_args, handler, extra_conf_files, extra_overlay_confs, + def cmake_assemble_args(extra_args, handler, conf_files, extra_conf_files, extra_overlay_confs, extra_dtc_overlay_files, cmake_extra_args, build_dir): # Retain quotes around config options @@ -1673,8 +1673,11 @@ def cmake_assemble_args(extra_args, handler, extra_conf_files, extra_overlay_con if handler.ready: args.extend(handler.args) + if conf_files: + args.append(f"CONF_FILE=\"{';'.join(conf_files)}\"") + if extra_conf_files: - args.append(f"CONF_FILE=\"{';'.join(extra_conf_files)}\"") + args.append(f"EXTRA_CONF_FILE=\"{';'.join(extra_conf_files)}\"") if extra_dtc_overlay_files: args.append(f"DTC_OVERLAY_FILE=\"{';'.join(extra_dtc_overlay_files)}\"") @@ -1721,6 +1724,7 @@ def cmake(self, filter_stages=None): args = self.cmake_assemble_args( args, self.instance.handler, + self.testsuite.conf_files, self.testsuite.extra_conf_files, self.testsuite.extra_overlay_confs, self.testsuite.extra_dtc_overlay_files, diff --git a/scripts/tests/twister/test_runner.py b/scripts/tests/twister/test_runner.py index e60171243d61..d971727fb5ef 100644 --- a/scripts/tests/twister/test_runner.py +++ b/scripts/tests/twister/test_runner.py @@ -25,6 +25,7 @@ from twisterlib.runner import CMake, ExecutionCounter, FilterBuilder, ProjectBuilder, TwisterRunner from twisterlib.statuses import TwisterStatus +# pylint: disable=no-name-in-module from . import ZEPHYR_BASE @@ -103,6 +104,7 @@ class MockHandler: ["basearg1", "CONFIG_t=\"test\"", "SNIPPET_t=\"test\""], handler, ["a.conf;b.conf", "c.conf"], + ["d.conf;e.conf", "f.conf"], ["extra_overlay.conf"], ["x.overlay;y.overlay", "z.overlay"], ["cmake1=foo", "cmake2=bar"], @@ -113,6 +115,7 @@ class MockHandler: "-Dbasearg1", "-DSNIPPET_t=test", "-Dhandler_arg1", "-Dhandler_arg2", "-DCONF_FILE=a.conf;b.conf;c.conf", + "-DEXTRA_CONF_FILE=d.conf;e.conf;f.conf", "-DDTC_OVERLAY_FILE=x.overlay;y.overlay;z.overlay", "-DOVERLAY_CONFIG=extra_overlay.conf " "/builddir/twister/testsuite_extra.conf", @@ -2158,6 +2161,7 @@ def notrun_increment(value=1, decrement=False): def test_projectbuilder_cmake_assemble_args(): extra_args = ['CONFIG_FOO=y', 'DUMMY_EXTRA="yes"'] handler = mock.Mock(ready=True, args=['dummy_handler']) + conf_files = ['file1.conf', 'file2.conf'] extra_conf_files = ['extrafile1.conf', 'extrafile2.conf'] extra_overlay_confs = ['extra_overlay_conf'] extra_dtc_overlay_files = ['overlay1.dtc', 'overlay2.dtc'] @@ -2166,6 +2170,7 @@ def test_projectbuilder_cmake_assemble_args(): with mock.patch('os.path.exists', return_value=True): results = ProjectBuilder.cmake_assemble_args(extra_args, handler, + conf_files, extra_conf_files, extra_overlay_confs, extra_dtc_overlay_files, @@ -2178,7 +2183,8 @@ def test_projectbuilder_cmake_assemble_args(): '-DCMAKE2=n', '-DDUMMY_EXTRA=yes', '-Ddummy_handler', - '-DCONF_FILE=extrafile1.conf;extrafile2.conf', + '-DCONF_FILE=file1.conf;file2.conf', + '-DEXTRA_CONF_FILE=extrafile1.conf;extrafile2.conf', '-DDTC_OVERLAY_FILE=overlay1.dtc;overlay2.dtc', f'-DOVERLAY_CONFIG=extra_overlay_conf ' \ f'{os.path.join("build", "dir", "twister", "testsuite_extra.conf")}' @@ -2196,9 +2202,10 @@ def test_projectbuilder_cmake(): pb = ProjectBuilder(instance_mock, env_mock, mocked_jobserver) pb.build_dir = 'build_dir' pb.testsuite.extra_args = ['some', 'args'] - pb.testsuite.extra_conf_files = ['some', 'files1'] - pb.testsuite.extra_overlay_confs = ['some', 'files2'] - pb.testsuite.extra_dtc_overlay_files = ['some', 'files3'] + pb.testsuite.conf_files = ['some', 'files1'] + pb.testsuite.extra_conf_files = ['some', 'files2'] + pb.testsuite.extra_overlay_confs = ['some', 'files3'] + pb.testsuite.extra_dtc_overlay_files = ['some', 'files4'] pb.options.extra_args = ['other', 'args'] pb.cmake_assemble_args = mock.Mock(return_value=['dummy']) cmake_res_mock = mock.Mock() @@ -2210,6 +2217,7 @@ def test_projectbuilder_cmake(): pb.cmake_assemble_args.assert_called_once_with( pb.testsuite.extra_args, pb.instance.handler, + pb.testsuite.conf_files, pb.testsuite.extra_conf_files, pb.testsuite.extra_overlay_confs, pb.testsuite.extra_dtc_overlay_files, diff --git a/scripts/tests/twister/test_twister.py b/scripts/tests/twister/test_twister.py index 13182069a474..aaf4c92e16b6 100644 --- a/scripts/tests/twister/test_twister.py +++ b/scripts/tests/twister/test_twister.py @@ -15,6 +15,7 @@ from twisterlib.error import ConfigurationError from twisterlib.testplan import TwisterConfigParser +# pylint: disable=no-name-in-module from . import ZEPHYR_BASE @@ -75,7 +76,10 @@ def test_testsuite_config_files(): # Check that all conf files have been assembled in the correct order assert ";".join(scenario["extra_conf_files"]) == \ - "conf1;conf2;conf3;conf4;conf5;conf6;conf7;conf8" + "conf3;conf4;conf7;conf8" + + assert ";".join(scenario["conf_files"]) == \ + "conf1;conf2;conf5;conf6" # Check that all DTC overlay files have been assembled in the correct order assert ";".join(scenario["extra_dtc_overlay_files"]) == \ diff --git a/scripts/west_commands/build.py b/scripts/west_commands/build.py index 4df2ce0e401b..fc030bc2d157 100644 --- a/scripts/west_commands/build.py +++ b/scripts/west_commands/build.py @@ -418,7 +418,7 @@ def _parse_test_item(self, test_item, board): if found_test_metadata: args = [] if extra_conf_files: - args.append(f"CONF_FILE=\"{';'.join(extra_conf_files)}\"") + args.append(f"EXTRA_CONF_FILE=\"{';'.join(extra_conf_files)}\"") if extra_dtc_overlay_files: args.append(f"DTC_OVERLAY_FILE=\"{';'.join(extra_dtc_overlay_files)}\"") diff --git a/tests/drivers/build_all/modem/prj.conf b/tests/drivers/build_all/modem/prj.conf new file mode 100644 index 000000000000..b2a4ba591044 --- /dev/null +++ b/tests/drivers/build_all/modem/prj.conf @@ -0,0 +1 @@ +# nothing here From d94ed7b316fc05120b8f9886dd86b1cc0212833d Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 22 Dec 2025 09:57:35 +0000 Subject: [PATCH 1455/3659] lib: os: Fix ZVFS leaking without being enabled Fixes this define leaking into all application source files when the feature is not even enabled Co-authored-by: Chris Friedt Signed-off-by: Jamie McCrae --- include/zephyr/sys/fdtable.h | 4 +++ lib/os/CMakeLists.txt | 54 +++++++++++++++++++----------------- lib/os/Kconfig | 1 + 3 files changed, 33 insertions(+), 26 deletions(-) diff --git a/include/zephyr/sys/fdtable.h b/include/zephyr/sys/fdtable.h index 50896db79a37..4903a5ae3416 100644 --- a/include/zephyr/sys/fdtable.h +++ b/include/zephyr/sys/fdtable.h @@ -257,7 +257,11 @@ struct zvfs_pollfd { __syscall int zvfs_poll(struct zvfs_pollfd *fds, int nfds, int poll_timeout); struct zvfs_fd_set { +#ifdef ZVFS_OPEN_SIZE uint32_t bitset[DIV_ROUND_UP(ZVFS_OPEN_SIZE, 32)]; +#else + uint32_t bitset[1]; +#endif }; /** @brief Number of file descriptors which can be added @ref zvfs_fd_set */ diff --git a/lib/os/CMakeLists.txt b/lib/os/CMakeLists.txt index 01fd62258d62..863d7d48ed46 100644 --- a/lib/os/CMakeLists.txt +++ b/lib/os/CMakeLists.txt @@ -13,35 +13,37 @@ zephyr_sources( thread_entry.c ) -if(CONFIG_ZVFS_OPEN_IGNORE_MIN) - set(final_fd_size ${CONFIG_ZVFS_OPEN_MAX}) -else() - # Import all custom ZVFS_OPEN_ size requirements - import_kconfig(CONFIG_ZVFS_OPEN_ADD_SIZE_ ${DOTCONFIG} add_size_keys) - - # Calculate the sum of all "ADD_SIZE" requirements - set(add_size_sum 0) - foreach(add_size ${add_size_keys}) - math(EXPR add_size_sum "${add_size_sum} + ${${add_size}}") - endforeach() - - if(CONFIG_ZVFS_OPEN_MAX LESS "${add_size_sum}") - # Only warn if default value 0 has been modified - if(NOT CONFIG_ZVFS_OPEN_MAX EQUAL 0) - message(WARNING " - CONFIG_ZVFS_OPEN_MAX is less than requested minimum: - ${CONFIG_ZVFS_OPEN_MAX} < ${add_size_sum} - Setting the file descriptor size to ${add_size_sum}") - endif() - - set(final_fd_size ${add_size_sum}) - else() - # CONFIG_ZVFS_OPEN_MAX was greater than the sum of the requirements +if(CONFIG_ZVFS) + if(CONFIG_ZVFS_OPEN_IGNORE_MIN) set(final_fd_size ${CONFIG_ZVFS_OPEN_MAX}) + else() + # Import all custom ZVFS_OPEN_ size requirements + import_kconfig(CONFIG_ZVFS_OPEN_ADD_SIZE_ ${DOTCONFIG} add_size_keys) + + # Calculate the sum of all "ADD_SIZE" requirements + set(add_size_sum 0) + foreach(add_size ${add_size_keys}) + math(EXPR add_size_sum "${add_size_sum} + ${${add_size}}") + endforeach() + + if(CONFIG_ZVFS_OPEN_MAX LESS "${add_size_sum}") + # Only warn if default value 0 has been modified + if(NOT CONFIG_ZVFS_OPEN_MAX EQUAL 0) + message(WARNING " + CONFIG_ZVFS_OPEN_MAX is less than requested minimum: + ${CONFIG_ZVFS_OPEN_MAX} < ${add_size_sum} + Setting the file descriptor size to ${add_size_sum}") + endif() + + set(final_fd_size ${add_size_sum}) + else() + # CONFIG_ZVFS_OPEN_MAX was greater than the sum of the requirements + set(final_fd_size ${CONFIG_ZVFS_OPEN_MAX}) + endif() endif() -endif() -zephyr_compile_definitions(ZVFS_OPEN_SIZE=${final_fd_size}) + zephyr_compile_definitions(ZVFS_OPEN_SIZE=${final_fd_size}) +endif() zephyr_sources_ifdef(CONFIG_CBPRINTF_COMPLETE cbprintf_complete.c) zephyr_sources_ifdef(CONFIG_CBPRINTF_NANO cbprintf_nano.c) diff --git a/lib/os/Kconfig b/lib/os/Kconfig index d550b3b13bf8..1e97a60c90c3 100644 --- a/lib/os/Kconfig +++ b/lib/os/Kconfig @@ -5,6 +5,7 @@ menu "OS Support Library" config ZVFS_OPEN_MAX int "Maximum number of open file descriptors" + depends on ZVFS default 0 help Maximum number of open file descriptors, this includes From 83f1b8ba49350c7132e476d4687a25c749822a28 Mon Sep 17 00:00:00 2001 From: Vijay Sharma Date: Tue, 23 Dec 2025 15:30:01 +0530 Subject: [PATCH 1456/3659] kernel: timer: Add timer observer hooks for extensibility Introduce lifecycle observer callbacks (init, start, stop, expiry) for k_timer using Zephyr's iterable sections pattern. This enables external modules to extend timer functionality without modifying kernel internals. Signed-off-by: Vijay Sharma --- include/zephyr/kernel.h | 53 +++++++++ .../common-rom/common-rom-kernel-devices.ld | 4 + kernel/Kconfig | 6 ++ kernel/timer.c | 52 +++++++++ .../timer/timer_observer/CMakeLists.txt | 8 ++ tests/kernel/timer/timer_observer/prj.conf | 2 + tests/kernel/timer/timer_observer/src/main.c | 101 ++++++++++++++++++ .../kernel/timer/timer_observer/testcase.yaml | 5 + 8 files changed, 231 insertions(+) create mode 100644 tests/kernel/timer/timer_observer/CMakeLists.txt create mode 100644 tests/kernel/timer/timer_observer/prj.conf create mode 100644 tests/kernel/timer/timer_observer/src/main.c create mode 100644 tests/kernel/timer/timer_observer/testcase.yaml diff --git a/include/zephyr/kernel.h b/include/zephyr/kernel.h index c7e6e035d495..a27a4049242f 100644 --- a/include/zephyr/kernel.h +++ b/include/zephyr/kernel.h @@ -1801,6 +1801,23 @@ struct k_timer { */ }; +#ifdef CONFIG_TIMER_OBSERVER +struct k_timer_observer { + /* Invoked upon completion of k_timer initialization */ + void (*on_init)(struct k_timer *timer); + + /* Invoked after the timer transitions to the running state */ + void (*on_start)(struct k_timer *timer, k_timeout_t duration, + k_timeout_t period); + + /* Invoked when the active timer is explicitly stopped */ + void (*on_stop)(struct k_timer *timer); + + /* Executes in ISR context, keep minimal and non-blocking */ + void (*on_expiry)(struct k_timer *timer); +}; +#endif /* CONFIG_TIMER_OBSERVER */ + /** * @cond INTERNAL_HIDDEN */ @@ -1872,6 +1889,42 @@ typedef void (*k_timer_stop_t)(struct k_timer *timer); STRUCT_SECTION_ITERABLE(k_timer, name) = \ Z_TIMER_INITIALIZER(name, expiry_fn, stop_fn) + +#ifdef CONFIG_TIMER_OBSERVER + +/** + * @cond INTERNAL_HIDDEN + */ +#define Z_TIMER_OBSERVER_INITIALIZER(name, init, start, stop, expiry) \ + { \ + .on_init = init, \ + .on_start = start, \ + .on_stop = stop, \ + .on_expiry = expiry \ + } +/** + * INTERNAL_HIDDEN @endcond + */ + +/** + * @brief Statically define and initialize a timer observer. + * + * Iterable-section based observer interface for k_timer lifecycle + * events (init/start/stop/expiry). External modules can register + * additional functionality without modifying kernel internals. + * + * @param name Name of the k_timer_observer variable. + * @param init Pointer to initialization callback (or NULL). + * @param start Pointer to start callback (or NULL). + * @param stop Pointer to stop callback (or NULL). + * @param expiry Pointer to expiry callback (or NULL). + */ +#define K_TIMER_OBSERVER_DEFINE(name, init, start, stop, expiry) \ + static const STRUCT_SECTION_ITERABLE(k_timer_observer, name) = \ + Z_TIMER_OBSERVER_INITIALIZER(name, init, start, stop, expiry) + +#endif /* CONFIG_TIMER_OBSERVER */ + /** * @brief Initialize a timer. * diff --git a/include/zephyr/linker/common-rom/common-rom-kernel-devices.ld b/include/zephyr/linker/common-rom/common-rom-kernel-devices.ld index 716a845134c3..1efafe842a33 100644 --- a/include/zephyr/linker/common-rom/common-rom-kernel-devices.ld +++ b/include/zephyr/linker/common-rom/common-rom-kernel-devices.ld @@ -105,4 +105,8 @@ ITERABLE_SECTION_ROM(_stack_to_hw_shadow_stack_arr, Z_LINK_ITERABLE_SUBALIGN) #endif +#if defined(CONFIG_TIMER_OBSERVER) + ITERABLE_SECTION_ROM(k_timer_observer, Z_LINK_ITERABLE_SUBALIGN) +#endif /* CONFIG_TIMER_OBSERVER */ + #include diff --git a/kernel/Kconfig b/kernel/Kconfig index c4bab69f4846..52ef3d531aae 100644 --- a/kernel/Kconfig +++ b/kernel/Kconfig @@ -717,6 +717,12 @@ config TIMESLICE_PER_THREAD a per-thread basis, with an application callback invoked when a thread reaches the end of its timeslice. +config TIMER_OBSERVER + bool "Support extension points for k_timer lifecycle" + help + Adds iterable‑section support for observing k_timer events. + Supports extending timer behavior without kernel changes. + endmenu menu "Other Kernel Object Options" diff --git a/kernel/timer.c b/kernel/timer.c index ada3e9ce8177..e6d47f82137e 100644 --- a/kernel/timer.c +++ b/kernel/timer.c @@ -19,6 +19,50 @@ static struct k_spinlock lock; static struct k_obj_type obj_type_timer; #endif /* CONFIG_OBJ_CORE_TIMER */ +#if defined(CONFIG_TIMER_OBSERVER) +static inline void z_timer_observer_on_init(struct k_timer *timer) +{ + STRUCT_SECTION_FOREACH(k_timer_observer, obs) { + if (obs->on_init != NULL) { + obs->on_init(timer); + } + } +} + +static inline void z_timer_observer_on_start(struct k_timer *timer, k_timeout_t duration, + k_timeout_t period) +{ + STRUCT_SECTION_FOREACH(k_timer_observer, obs) { + if (obs->on_start != NULL) { + obs->on_start(timer, duration, period); + } + } +} + +static inline void z_timer_observer_on_stop(struct k_timer *timer) +{ + STRUCT_SECTION_FOREACH(k_timer_observer, obs) { + if (obs->on_stop != NULL) { + obs->on_stop(timer); + } + } +} + +static inline void z_timer_observer_on_expiry(struct k_timer *timer) +{ + STRUCT_SECTION_FOREACH(k_timer_observer, obs) { + if (obs->on_expiry != NULL) { + obs->on_expiry(timer); + } + } +} +#else +#define z_timer_observer_on_init(timer) (void)0 +#define z_timer_observer_on_start(timer, duration, period) (void)0 +#define z_timer_observer_on_stop(timer) (void)0 +#define z_timer_observer_on_expiry(timer) (void)0 +#endif /* CONFIG_TIMER_OBSERVER */ + /** * @brief Handle expiration of a kernel timer object. * @@ -80,6 +124,8 @@ void z_timer_expiration_handler(struct _timeout *t) /* update timer's status */ timer->status += 1U; + z_timer_observer_on_expiry(timer); + /* invoke timer expiry function */ if (timer->expiry_fn != NULL) { /* Unlock for user handler. */ @@ -139,6 +185,8 @@ void k_timer_init(struct k_timer *timer, #ifdef CONFIG_OBJ_CORE_TIMER k_obj_core_init_and_link(K_OBJ_CORE(timer), &obj_type_timer); #endif /* CONFIG_OBJ_CORE_TIMER */ + + z_timer_observer_on_init(timer); } @@ -188,6 +236,8 @@ void z_impl_k_timer_start(struct k_timer *timer, k_timeout_t duration, z_add_timeout(&timer->timeout, z_timer_expiration_handler, duration); + z_timer_observer_on_start(timer, duration, period); + k_spin_unlock(&lock, key); } @@ -212,6 +262,8 @@ void z_impl_k_timer_stop(struct k_timer *timer) return; } + z_timer_observer_on_stop(timer); + if (timer->stop_fn != NULL) { SYS_PORT_TRACING_OBJ_FUNC_ENTER(k_timer, stop_fn_expiry, timer); diff --git a/tests/kernel/timer/timer_observer/CMakeLists.txt b/tests/kernel/timer/timer_observer/CMakeLists.txt new file mode 100644 index 000000000000..668427f50cae --- /dev/null +++ b/tests/kernel/timer/timer_observer/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(timer_observer) + +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources}) diff --git a/tests/kernel/timer/timer_observer/prj.conf b/tests/kernel/timer/timer_observer/prj.conf new file mode 100644 index 000000000000..681bd289fedb --- /dev/null +++ b/tests/kernel/timer/timer_observer/prj.conf @@ -0,0 +1,2 @@ +CONFIG_ZTEST=y +CONFIG_TIMER_OBSERVER=y diff --git a/tests/kernel/timer/timer_observer/src/main.c b/tests/kernel/timer/timer_observer/src/main.c new file mode 100644 index 000000000000..dec7be7ccca8 --- /dev/null +++ b/tests/kernel/timer/timer_observer/src/main.c @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2025 Qualcomm Technologies, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +static struct k_timer test_periodic_timer; + +static int expiry_cnt; +static int stop_cnt; + +struct obs_state_s { + int init_cnt; + int start_cnt; + int stop_cnt; + int expiry_cnt; +}; + +static struct obs_state_s obs; + +static void timer_expiry_cb(struct k_timer *timer) +{ + expiry_cnt++; +} + +static void timer_stop_cb(struct k_timer *timer) +{ + stop_cnt++; +} + +__boot_func +static void obs_on_init(struct k_timer *timer) +{ + if (timer == &test_periodic_timer) { + obs.init_cnt++; + } +} + +__boot_func +static void obs_on_start(struct k_timer *timer, k_timeout_t duration, k_timeout_t period) +{ + if (timer == &test_periodic_timer) { + obs.start_cnt++; + } +} + +__boot_func +static void obs_on_stop(struct k_timer *timer) +{ + if (timer == &test_periodic_timer) { + obs.stop_cnt++; + } +} + +__boot_func +static void obs_on_expiry(struct k_timer *timer) +{ + if (timer == &test_periodic_timer) { + obs.expiry_cnt++; + } +} + +ZTEST(timer_observer, test_periodic_expiry_and_explicit_stop) +{ + const int dur_ms = 80; + const int per_ms = 40; + + /* Initialize the timer to trigger on_init path */ + k_timer_init(&test_periodic_timer, timer_expiry_cb, timer_stop_cb); + + /* Start periodic timer*/ + k_timer_start(&test_periodic_timer, K_MSEC(dur_ms), K_MSEC(per_ms)); + + /* Allow a few expiries to happen */ + k_busy_wait((dur_ms + (per_ms * 3)) * 1000); + + /* Now explicitly stop; observer should see on_stop */ + k_timer_stop(&test_periodic_timer); + + /* Small delay to ensure stop path completes */ + k_busy_wait(10 * 1000); + + /* Verify timer on_init was called and updated for the test timer */ + zassert_equal(obs.init_cnt, 1, "obs init count mismatch"); + + /* Observer should have seen start */ + zassert_equal(obs.start_cnt, 1, "obs start count mismatch"); + + zassert_equal(obs.stop_cnt, stop_cnt, "obs stop count mismatch"); + + /* Observer should have seen multiple expiry callbacks */ + zassert_equal(obs.expiry_cnt, expiry_cnt, "obs expiry count mismatch"); +} + +K_TIMER_OBSERVER_DEFINE(observer, obs_on_init, obs_on_start, obs_on_stop, obs_on_expiry); + +ZTEST_SUITE(timer_observer, NULL, NULL, NULL, NULL, NULL); diff --git a/tests/kernel/timer/timer_observer/testcase.yaml b/tests/kernel/timer/timer_observer/testcase.yaml new file mode 100644 index 000000000000..ae8c913030f8 --- /dev/null +++ b/tests/kernel/timer/timer_observer/testcase.yaml @@ -0,0 +1,5 @@ +tests: + kernel.timer.timer_observer: + tags: + - kernel + - timer From 9dbc6450b4f65939ba5a3d33d318659d8d2e4954 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=A9tan=20Froissard?= Date: Wed, 31 Dec 2025 17:41:45 +0100 Subject: [PATCH 1457/3659] soc: st: stm32: h7rsxx: Add MPU region on OTP area MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This configure MPU region over OTP area like ID region. OTP can be directly read and need to use flash HAL API for writing. Signed-off-by: Gaétan Froissard --- soc/st/stm32/stm32h7rsx/mpu_regions.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/soc/st/stm32/stm32h7rsx/mpu_regions.c b/soc/st/stm32/stm32h7rsx/mpu_regions.c index 14bac1bb7849..3013a4c531aa 100644 --- a/soc/st/stm32/stm32h7rsx/mpu_regions.c +++ b/soc/st/stm32/stm32h7rsx/mpu_regions.c @@ -34,14 +34,17 @@ static const struct arm_mpu_region mpu_regions[] = { /* Region 3 */ MPU_REGION_ENTRY("SRAM_0", CONFIG_SRAM_BASE_ADDRESS, REGION_RAM_ATTR(REGION_SRAM_SIZE)), - /* Region 4 - Ready only flash with unique device id, package code and VREF/TS calib*/ + /* Region 4 - OTP area */ + MPU_REGION_ENTRY("OTP", 0x08FFF000, REGION_IO_ATTR(REGION_1K)), + + /* Region 5 - Read-only area provisioned by ST */ MPU_REGION_ENTRY("ID", 0x08FFF800, REGION_IO_ATTR(REGION_512B)), #if defined(sram_eth_node) && DT_NODE_HAS_STATUS_OKAY(sram_eth_node) - /* Region 5 - Ethernet DMA buffer RAM */ + /* Region 6 - Ethernet DMA buffer RAM */ MPU_REGION_ENTRY("SRAM_ETH_BUF", DT_REG_ADDR(sram_eth_node), REGION_RAM_NOCACHE_ATTR(REGION_16K)), - /* Region 6 - Ethernet DMA descriptor RAM (overlays the first 256B of SRAM_ETH_BUF)*/ + /* Region 7 - Ethernet DMA descriptor RAM (overlays the first 256B of SRAM_ETH_BUF) */ MPU_REGION_ENTRY("SRAM_ETH_DESC", DT_REG_ADDR(sram_eth_node), REGION_PPB_ATTR(REGION_256B)), #endif }; From e2e780aae05bae2cc0f42f66b00568a53b41825e Mon Sep 17 00:00:00 2001 From: Vincent Tardy Date: Wed, 3 Dec 2025 15:27:22 +0100 Subject: [PATCH 1458/3659] soc: stm32: add link layer disable isr function Add new function link_layer_disable_isr() to disable radio ISR Signed-off-by: Vincent Tardy --- soc/st/stm32/stm32wbax/hci_if/linklayer_plat_adapt.c | 9 +++++++++ soc/st/stm32/stm32wbax/hci_if/linklayer_plat_local.h | 5 +++++ 2 files changed, 14 insertions(+) diff --git a/soc/st/stm32/stm32wbax/hci_if/linklayer_plat_adapt.c b/soc/st/stm32/stm32wbax/hci_if/linklayer_plat_adapt.c index 952b50156cd0..dded6f736d8f 100644 --- a/soc/st/stm32/stm32wbax/hci_if/linklayer_plat_adapt.c +++ b/soc/st/stm32/stm32wbax/hci_if/linklayer_plat_adapt.c @@ -125,6 +125,15 @@ void link_layer_register_isr(bool force) irq_enable(RADIO_SW_LOW_INTR_NUM); } +void link_layer_disable_isr(void) +{ + irq_disable(RADIO_INTR_NUM); + + irq_disable(RADIO_SW_LOW_INTR_NUM); + + local_basepri_value = __get_BASEPRI(); + __set_BASEPRI_MAX(RADIO_INTR_PRIO_LOW_Z << 4); +} void LINKLAYER_PLAT_TriggerSwLowIT(uint8_t priority) { diff --git a/soc/st/stm32/stm32wbax/hci_if/linklayer_plat_local.h b/soc/st/stm32/stm32wbax/hci_if/linklayer_plat_local.h index 92c1a08c7c59..c3743d906ac3 100644 --- a/soc/st/stm32/stm32wbax/hci_if/linklayer_plat_local.h +++ b/soc/st/stm32/stm32wbax/hci_if/linklayer_plat_local.h @@ -14,4 +14,9 @@ */ void link_layer_register_isr(bool force); +/* + * @brief Link Layer related ISR disable + */ +void link_layer_disable_isr(void); + #endif /* _STM32WBA_LINK_LAYER_PLAT_LOCAL_H_ */ From 8bb85a6cbd295b00898e38a1fe32be8698b5940e Mon Sep 17 00:00:00 2001 From: Vincent Tardy Date: Wed, 3 Dec 2025 15:30:30 +0100 Subject: [PATCH 1459/3659] drivers: bluetooth: hci: support driver close feature Update stm32wbax ble hci driver to support driver close Signed-off-by: Vincent Tardy --- drivers/bluetooth/hci/hci_stm32wba.c | 69 +++++++++++++++++++++++++++- 1 file changed, 67 insertions(+), 2 deletions(-) diff --git a/drivers/bluetooth/hci/hci_stm32wba.c b/drivers/bluetooth/hci/hci_stm32wba.c index 6b847c80fec6..a931c53e4936 100644 --- a/drivers/bluetooth/hci/hci_stm32wba.c +++ b/drivers/bluetooth/hci/hci_stm32wba.c @@ -16,9 +16,7 @@ #include #include #include -#ifdef CONFIG_PM_DEVICE #include "linklayer_plat.h" -#endif /* CONFIG_PM_DEVICE */ #include #include @@ -96,6 +94,21 @@ struct bt_hci_end_radio_activity_evt { } __packed; #endif /* CONFIG_PM_DEVICE */ +/* ACI Reset command */ +#define ACI_RESET 0xFF00 + +struct aci_reset { + uint8_t mode; + uint32_t options; +} __packed; + +/* Bluetooth driver state */ +#define BT_HCI_STATE_DEINIT 0 +#define BT_HCI_STATE_OPENED 1 +#define BT_HCI_STATE_CLOSED 2 + +static uint8_t bt_hci_state = BT_HCI_STATE_DEINIT; + static uint32_t __noinit buffer[DIVC(BLE_DYN_ALLOC_SIZE, 4)]; static uint32_t __noinit gatt_buffer[DIVC(BLE_GATT_BUF_SIZE, 4)]; @@ -452,6 +465,12 @@ static int bt_hci_stm32wba_open(const struct device *dev, bt_hci_recv_t recv) struct hci_data *data = dev->data; int ret = 0; + if (bt_hci_state == BT_HCI_STATE_CLOSED) { +#if !defined(CONFIG_IEEE802154_STM32WBA) + LINKLAYER_PLAT_ClockInit(); +#endif + } + link_layer_register_isr(false); ret = bt_ble_ctlr_init(); @@ -464,9 +483,54 @@ static int bt_hci_stm32wba_open(const struct device *dev, bt_hci_recv_t recv) FD_SetStatus(FD_FLASHACCESS_RFTS_BYPASS, LL_FLASH_DISABLE); } + if (ret == 0) { + bt_hci_state = BT_HCI_STATE_OPENED; + } + return ret; } +static int bt_hci_stm32wba_close(const struct device *dev) +{ + struct aci_reset *param; + struct net_buf *buf; + int err; + + ARG_UNUSED(dev); + + buf = bt_hci_cmd_alloc(K_FOREVER); + if (!buf) { + return -ENOBUFS; + } + + param = net_buf_add(buf, sizeof(*param)); + param->mode = 0; + param->options = CFG_BLE_OPTIONS; + + err = bt_hci_cmd_send_sync(ACI_RESET, buf, NULL); + if (err) { + return err; + } + bt_hci_state = BT_HCI_STATE_CLOSED; + +#if !defined(CONFIG_IEEE802154_STM32WBA) + + /* No radio event scheduled : inform LL to enter in deep sleep */ + (void)ll_sys_dp_slp_enter(LL_DP_SLP_NO_WAKEUP); + + link_layer_disable_isr(); + + /* Disable the clock sources used for the radio */ + LINKLAYER_PLAT_AclkCtrl(0); + + __HAL_RCC_RADIO_CLK_DISABLE(); + + __HAL_RCC_RADIO_CLK_SLEEP_DISABLE(); +#endif + + return err; +} + #if defined(CONFIG_BT_HCI_SETUP) bt_addr_t *bt_get_ble_addr(void) @@ -609,6 +673,7 @@ static DEVICE_API(bt_hci, drv) = { #endif /* CONFIG_BT_HCI_SETUP */ .open = bt_hci_stm32wba_open, .send = bt_hci_stm32wba_send, + .close = bt_hci_stm32wba_close, }; #define HCI_DEVICE_INIT(inst) \ From 59ca598bf83e1cab594ae6c03014c90adc37bb68 Mon Sep 17 00:00:00 2001 From: Mathieu Choplain Date: Wed, 7 Jan 2026 16:07:58 +0100 Subject: [PATCH 1460/3659] dts: arm: st: set zephyr,entropy in root DTSI for all series All series set the "zephyr,entropy" chosen to the internal TRNG by default inside their root DTSI except STM32N6 and STM32WB0. Align these two series with others by declaring "/chosen/zephyr,entropy" in their root DTSI as well. Signed-off-by: Mathieu Choplain --- dts/arm/st/n6/stm32n6.dtsi | 4 ++++ dts/arm/st/wb0/stm32wb0.dtsi | 1 + 2 files changed, 5 insertions(+) diff --git a/dts/arm/st/n6/stm32n6.dtsi b/dts/arm/st/n6/stm32n6.dtsi index 1583e621d3b5..cc1c95c229e0 100644 --- a/dts/arm/st/n6/stm32n6.dtsi +++ b/dts/arm/st/n6/stm32n6.dtsi @@ -20,6 +20,10 @@ #include / { + chosen { + zephyr,entropy = &rng; + }; + cpus { #address-cells = <1>; #size-cells = <0>; diff --git a/dts/arm/st/wb0/stm32wb0.dtsi b/dts/arm/st/wb0/stm32wb0.dtsi index 243e96d13dc2..654e47808df6 100644 --- a/dts/arm/st/wb0/stm32wb0.dtsi +++ b/dts/arm/st/wb0/stm32wb0.dtsi @@ -24,6 +24,7 @@ chosen { zephyr,flash-controller = &flash; zephyr,bt-hci = &bt_hci_wb0; + zephyr,entropy = &rng; }; cpus { From 68fd8b930eebd4f6ce01914b6821014f6cc78df3 Mon Sep 17 00:00:00 2001 From: Mathieu Choplain Date: Wed, 7 Jan 2026 16:08:47 +0100 Subject: [PATCH 1461/3659] boards: st: nucleo_wb0*: don't set /chosen/zephyr,entropy This chosen is now set inside the series' root DTSI file. Signed-off-by: Mathieu Choplain --- boards/st/nucleo_wb05kz/nucleo_wb05kz.dts | 1 - boards/st/nucleo_wb07cc/nucleo_wb07cc.dts | 1 - boards/st/nucleo_wb09ke/nucleo_wb09ke.dts | 1 - 3 files changed, 3 deletions(-) diff --git a/boards/st/nucleo_wb05kz/nucleo_wb05kz.dts b/boards/st/nucleo_wb05kz/nucleo_wb05kz.dts index ab9d3b51c8a0..3f59e151703f 100644 --- a/boards/st/nucleo_wb05kz/nucleo_wb05kz.dts +++ b/boards/st/nucleo_wb05kz/nucleo_wb05kz.dts @@ -24,7 +24,6 @@ zephyr,sram = &sram0; zephyr,flash = &flash0; zephyr,bt-c2h-uart = &usart1; - zephyr,entropy = &rng; }; leds: leds { diff --git a/boards/st/nucleo_wb07cc/nucleo_wb07cc.dts b/boards/st/nucleo_wb07cc/nucleo_wb07cc.dts index b7afca76800c..3a1c70e4608f 100644 --- a/boards/st/nucleo_wb07cc/nucleo_wb07cc.dts +++ b/boards/st/nucleo_wb07cc/nucleo_wb07cc.dts @@ -24,7 +24,6 @@ zephyr,sram = &sram0; zephyr,flash = &flash0; zephyr,bt-c2h-uart = &usart1; - zephyr,entropy = &rng; }; leds: leds { diff --git a/boards/st/nucleo_wb09ke/nucleo_wb09ke.dts b/boards/st/nucleo_wb09ke/nucleo_wb09ke.dts index 39591f28fcdb..c5daca4d975a 100644 --- a/boards/st/nucleo_wb09ke/nucleo_wb09ke.dts +++ b/boards/st/nucleo_wb09ke/nucleo_wb09ke.dts @@ -24,7 +24,6 @@ zephyr,sram = &sram0; zephyr,flash = &flash0; zephyr,bt-c2h-uart = &usart1; - zephyr,entropy = &rng; zephyr,code-partition = &slot0_partition; }; From a78fc02c51d3589046fd7282a691cae7fd0617be Mon Sep 17 00:00:00 2001 From: Mathieu Choplain Date: Wed, 7 Jan 2026 16:10:49 +0100 Subject: [PATCH 1462/3659] tests: drivers: entropy_api: remove STM32WB0 overlays that aren't needed "/chosen/zephyr,entropy" is already set at root DTSI level, and the RNG is already enabled at board DTS level. Remove the now unneeded overlays for these boards. Signed-off-by: Mathieu Choplain --- .../entropy/api/boards/nucleo_wb05kz.overlay | 15 --------------- .../entropy/api/boards/nucleo_wb07cc.overlay | 15 --------------- .../entropy/api/boards/nucleo_wb09ke.overlay | 15 --------------- 3 files changed, 45 deletions(-) delete mode 100644 tests/drivers/entropy/api/boards/nucleo_wb05kz.overlay delete mode 100644 tests/drivers/entropy/api/boards/nucleo_wb07cc.overlay delete mode 100644 tests/drivers/entropy/api/boards/nucleo_wb09ke.overlay diff --git a/tests/drivers/entropy/api/boards/nucleo_wb05kz.overlay b/tests/drivers/entropy/api/boards/nucleo_wb05kz.overlay deleted file mode 100644 index 70954faf6b10..000000000000 --- a/tests/drivers/entropy/api/boards/nucleo_wb05kz.overlay +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright (c) 2024 STMicroelectronics - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/ { - chosen { - zephyr,entropy = &rng; - }; -}; - -&rng { - status = "okay"; -}; diff --git a/tests/drivers/entropy/api/boards/nucleo_wb07cc.overlay b/tests/drivers/entropy/api/boards/nucleo_wb07cc.overlay deleted file mode 100644 index 70954faf6b10..000000000000 --- a/tests/drivers/entropy/api/boards/nucleo_wb07cc.overlay +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright (c) 2024 STMicroelectronics - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/ { - chosen { - zephyr,entropy = &rng; - }; -}; - -&rng { - status = "okay"; -}; diff --git a/tests/drivers/entropy/api/boards/nucleo_wb09ke.overlay b/tests/drivers/entropy/api/boards/nucleo_wb09ke.overlay deleted file mode 100644 index 70954faf6b10..000000000000 --- a/tests/drivers/entropy/api/boards/nucleo_wb09ke.overlay +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright (c) 2024 STMicroelectronics - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/ { - chosen { - zephyr,entropy = &rng; - }; -}; - -&rng { - status = "okay"; -}; From ce582dbf9e21b2d4d533dac222c0e1d502369195 Mon Sep 17 00:00:00 2001 From: Mathieu Choplain Date: Wed, 7 Jan 2026 16:26:45 +0100 Subject: [PATCH 1463/3659] boards: st: stm32n6-based: enable TRNG The TRNG needs to be enabled at boards level by default for tests. It will not actually be used unless the ENTROPY_GENERATOR subsystem is enabled. Signed-off-by: Mathieu Choplain --- boards/st/nucleo_n657x0_q/nucleo_n657x0_q_common.dtsi | 4 ++++ boards/st/stm32n6570_dk/stm32n6570_dk_common.dtsi | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/boards/st/nucleo_n657x0_q/nucleo_n657x0_q_common.dtsi b/boards/st/nucleo_n657x0_q/nucleo_n657x0_q_common.dtsi index 529fc5768a0a..34c2451ac23e 100644 --- a/boards/st/nucleo_n657x0_q/nucleo_n657x0_q_common.dtsi +++ b/boards/st/nucleo_n657x0_q/nucleo_n657x0_q_common.dtsi @@ -314,3 +314,7 @@ csi_interface: &dcmipp { csi_ep_in: endpoint {}; }; }; + +&rng { + status = "okay"; +}; diff --git a/boards/st/stm32n6570_dk/stm32n6570_dk_common.dtsi b/boards/st/stm32n6570_dk/stm32n6570_dk_common.dtsi index ce141b53a939..42a9447a3027 100644 --- a/boards/st/stm32n6570_dk/stm32n6570_dk_common.dtsi +++ b/boards/st/stm32n6570_dk/stm32n6570_dk_common.dtsi @@ -545,3 +545,7 @@ zephyr_h264enc: &venc { zephyr_jpegenc: &jpeg { status = "okay"; }; + +&rng { + status = "okay"; +}; From 84120f91f0bf222c3ce1feda7782001f9a0354cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20Amundsen?= Date: Wed, 7 Jan 2026 18:54:58 +0100 Subject: [PATCH 1464/3659] soc: nordic: disable cache for event report MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The data is updated by both local domains (cpuapp/cpuapp) and IronSide SE (cpusec), so disable caching to avoid coherency issues. Signed-off-by: Håkon Amundsen --- soc/nordic/common/nrf54hx_nrf92x_mpu_regions.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/soc/nordic/common/nrf54hx_nrf92x_mpu_regions.c b/soc/nordic/common/nrf54hx_nrf92x_mpu_regions.c index 38d266729405..83c778928e3f 100644 --- a/soc/nordic/common/nrf54hx_nrf92x_mpu_regions.c +++ b/soc/nordic/common/nrf54hx_nrf92x_mpu_regions.c @@ -6,6 +6,7 @@ #include #include +#include #define USBHS_BASE DT_REG_ADDR_BY_NAME(DT_NODELABEL(usbhs), core) #define USBHS_SIZE DT_REG_SIZE_BY_NAME(DT_NODELABEL(usbhs), core) @@ -49,6 +50,9 @@ static struct arm_mpu_region mpu_regions[] = { MPU_REGION_ENTRY("SOFTPERIPH_RAM", SOFTPERIPH_BASE, REGION_RAM_NOCACHE_ATTR(SOFTPERIPH_BASE, SOFTPERIPH_SIZE)), #endif + MPU_REGION_ENTRY("EVENT_REPORT", IRONSIDE_SE_EVENT_REPORT_ADDRESS, + REGION_RAM_NOCACHE_ATTR(IRONSIDE_SE_EVENT_REPORT_ADDRESS, + IRONSIDE_SE_EVENT_REPORT_SIZE)), }; const struct arm_mpu_config mpu_config = { From fad7535db9ce2a89fc0237ac05aeb3f2dc99f075 Mon Sep 17 00:00:00 2001 From: Pisit Sawangvonganan Date: Thu, 8 Jan 2026 01:43:27 +0700 Subject: [PATCH 1465/3659] drivers: dma: stm32: consolidate callback in `dma_stm32_irq_handler` Refactor IRQ handler to set status variable in each branch and invoke the callback once at the end, reducing code duplication. Signed-off-by: Pisit Sawangvonganan --- drivers/dma/dma_stm32.c | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/drivers/dma/dma_stm32.c b/drivers/dma/dma_stm32.c index 2f0ef7f917ee..b8cbf4b4ea6f 100644 --- a/drivers/dma/dma_stm32.c +++ b/drivers/dma/dma_stm32.c @@ -91,6 +91,7 @@ static void dma_stm32_irq_handler(const struct device *dev, uint32_t id) DMA_TypeDef *dma = (DMA_TypeDef *)(config->base); struct dma_stm32_stream *stream; uint32_t callback_arg; + int status; __ASSERT_NO_MSG(id < config->max_streams); @@ -117,10 +118,7 @@ static void dma_stm32_irq_handler(const struct device *dev, uint32_t id) if (!stream->hal_override) { dma_stm32_clear_ht(dma, id); } - if (stream->dma_callback != NULL) { - stream->dma_callback(dev, stream->user_data, callback_arg, - DMA_STATUS_BLOCK); - } + status = DMA_STATUS_BLOCK; } else if (stm32_dma_is_tc_irq_active(dma, id)) { /* Circular buffer never stops receiving as long as peripheral is enabled */ if (!stream->cyclic) { @@ -130,10 +128,7 @@ static void dma_stm32_irq_handler(const struct device *dev, uint32_t id) if (!stream->hal_override) { dma_stm32_clear_tc(dma, id); } - if (stream->dma_callback != NULL) { - stream->dma_callback(dev, stream->user_data, callback_arg, - DMA_STATUS_COMPLETE); - } + status = DMA_STATUS_COMPLETE; } else if (stm32_dma_is_unexpected_irq_happened(dma, id)) { /* Let HAL DMA handle flags on its own */ if (!stream->hal_override) { @@ -141,9 +136,7 @@ static void dma_stm32_irq_handler(const struct device *dev, uint32_t id) stm32_dma_dump_stream_irq(dma, id); stm32_dma_clear_stream_irq(dma, id); } - if (stream->dma_callback != NULL) { - stream->dma_callback(dev, stream->user_data, callback_arg, -EIO); - } + status = -EIO; } else { /* Let HAL DMA handle flags on its own */ if (!stream->hal_override) { @@ -152,9 +145,11 @@ static void dma_stm32_irq_handler(const struct device *dev, uint32_t id) dma_stm32_dump_stream_irq(dev, id); dma_stm32_clear_stream_irq(dev, id); } - if (stream->dma_callback != NULL) { - stream->dma_callback(dev, stream->user_data, callback_arg, -EIO); - } + status = -EIO; + } + + if (stream->dma_callback != NULL) { + stream->dma_callback(dev, stream->user_data, callback_arg, status); } } From 4f71ba09181e606f19a4a88d90fb4634994e1811 Mon Sep 17 00:00:00 2001 From: Pisit Sawangvonganan Date: Thu, 8 Jan 2026 01:46:17 +0700 Subject: [PATCH 1466/3659] drivers: dma: stm32u5: consolidate callback in `dma_stm32_irq_handler` Refactor IRQ handler to set status variable in each branch and invoke the callback once at the end, reducing code duplication. Add null check for `dma_callback` in dma_stm32u5.c to match with dma_stm32.c pattern. Signed-off-by: Pisit Sawangvonganan --- drivers/dma/dma_stm32u5.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/dma/dma_stm32u5.c b/drivers/dma/dma_stm32u5.c index 81556eee73a0..c3e7ce7004aa 100644 --- a/drivers/dma/dma_stm32u5.c +++ b/drivers/dma/dma_stm32u5.c @@ -253,6 +253,7 @@ static void dma_stm32_irq_handler(const struct device *dev, uint32_t id) DMA_TypeDef *dma = (DMA_TypeDef *)(config->base); struct dma_stm32_stream *stream; uint32_t callback_arg; + int status; __ASSERT_NO_MSG(id < config->max_streams); @@ -274,7 +275,7 @@ static void dma_stm32_irq_handler(const struct device *dev, uint32_t id) if (!stream->hal_override) { dma_stm32_clear_ht(dma, id); } - stream->dma_callback(dev, stream->user_data, callback_arg, DMA_STATUS_BLOCK); + status = DMA_STATUS_BLOCK; } else if (stm32_dma_is_tc_irq_active(dma, id)) { /* Assuming not cyclic transfer */ if (stream->cyclic == false) { @@ -284,14 +285,17 @@ static void dma_stm32_irq_handler(const struct device *dev, uint32_t id) if (!stream->hal_override) { dma_stm32_clear_tc(dma, id); } - stream->dma_callback(dev, stream->user_data, callback_arg, DMA_STATUS_COMPLETE); + status = DMA_STATUS_COMPLETE; } else { LOG_ERR("Transfer Error."); stream->busy = false; dma_stm32_dump_stream_irq(dev, id); dma_stm32_clear_stream_irq(dev, id); - stream->dma_callback(dev, stream->user_data, - callback_arg, -EIO); + status = -EIO; + } + + if (stream->dma_callback != NULL) { + stream->dma_callback(dev, stream->user_data, callback_arg, status); } } From b6f28127bd53c337b8879542f8a4d4134bd5694c Mon Sep 17 00:00:00 2001 From: Pisit Sawangvonganan Date: Thu, 8 Jan 2026 02:07:37 +0700 Subject: [PATCH 1467/3659] drivers: can: mcan: consolidate `filter_id` bounds checking Consolidate lower and upper bounds checking of `filter_id` at `can_mcan_remove_rx_filter` function entry to avoid checking upper bounds while holding the mutex. Signed-off-by: Pisit Sawangvonganan --- drivers/can/can_mcan.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/can/can_mcan.c b/drivers/can/can_mcan.c index d21c0b4301c0..513daad82199 100644 --- a/drivers/can/can_mcan.c +++ b/drivers/can/can_mcan.c @@ -1226,7 +1226,7 @@ void can_mcan_remove_rx_filter(const struct device *dev, int filter_id) struct can_mcan_data *data = dev->data; int err; - if (filter_id < 0) { + if (filter_id < 0 || filter_id >= (cbs->num_std + cbs->num_ext)) { LOG_ERR("filter ID %d out of bounds", filter_id); return; } @@ -1235,11 +1235,6 @@ void can_mcan_remove_rx_filter(const struct device *dev, int filter_id) if (filter_id >= cbs->num_std) { filter_id -= cbs->num_std; - if (filter_id >= cbs->num_ext) { - LOG_ERR("filter ID %d out of bounds", filter_id); - k_mutex_unlock(&data->lock); - return; - } cbs->ext[filter_id].function = NULL; cbs->ext[filter_id].user_data = NULL; From d01a2bc5a5d06e0f2a56f1372eaaa8d6ad769860 Mon Sep 17 00:00:00 2001 From: Lauren Murphy Date: Tue, 9 Dec 2025 10:09:23 -0800 Subject: [PATCH 1468/3659] tests: subsys: llext: intel_adsp build fixes Adds board overlays for Intel ADSP platforms to use CONFIG_LLEXT_TYPE_ELF_RELOCATABLE instead of SHAREDLIB as xt-clang cannot link shared libs for Xtensa, exports symbols used by Intel ADSP with Xtensa toolchain, and adds XTENSA MPU / MMU to "no memory protection" config file. Signed-off-by: Lauren Murphy --- kernel/timeout.c | 3 +++ tests/subsys/llext/boards/intel_adsp_ace15_mtpm.conf | 2 ++ tests/subsys/llext/boards/intel_adsp_ace15_mtpm_sim.conf | 2 ++ tests/subsys/llext/boards/intel_adsp_ace20_lnl.conf | 2 ++ tests/subsys/llext/boards/intel_adsp_ace20_lnl_sim.conf | 2 ++ tests/subsys/llext/boards/intel_adsp_ace30_ptl.conf | 2 ++ tests/subsys/llext/boards/intel_adsp_ace30_ptl_sim.conf | 2 ++ tests/subsys/llext/boards/intel_adsp_ace40_nvl.conf | 2 ++ tests/subsys/llext/boards/intel_adsp_ace40_nvl_sim.conf | 2 ++ tests/subsys/llext/no_mem_protection.conf | 2 ++ 10 files changed, 21 insertions(+) create mode 100644 tests/subsys/llext/boards/intel_adsp_ace15_mtpm.conf create mode 100644 tests/subsys/llext/boards/intel_adsp_ace15_mtpm_sim.conf create mode 100644 tests/subsys/llext/boards/intel_adsp_ace20_lnl.conf create mode 100644 tests/subsys/llext/boards/intel_adsp_ace20_lnl_sim.conf create mode 100644 tests/subsys/llext/boards/intel_adsp_ace30_ptl.conf create mode 100644 tests/subsys/llext/boards/intel_adsp_ace30_ptl_sim.conf create mode 100644 tests/subsys/llext/boards/intel_adsp_ace40_nvl.conf create mode 100644 tests/subsys/llext/boards/intel_adsp_ace40_nvl_sim.conf diff --git a/kernel/timeout.c b/kernel/timeout.c index 74defbf68d4a..fff3d8d6e627 100644 --- a/kernel/timeout.c +++ b/kernel/timeout.c @@ -11,6 +11,7 @@ #include #include #include +#include static uint64_t curr_tick; @@ -202,6 +203,7 @@ k_ticks_t z_timeout_remaining(const struct _timeout *timeout) return ticks; } +EXPORT_SYMBOL(z_timeout_remaining); k_ticks_t z_timeout_expires(const struct _timeout *timeout) { @@ -216,6 +218,7 @@ k_ticks_t z_timeout_expires(const struct _timeout *timeout) return ticks; } +EXPORT_SYMBOL(z_timeout_expires); int32_t z_get_next_timeout_expiry(void) { diff --git a/tests/subsys/llext/boards/intel_adsp_ace15_mtpm.conf b/tests/subsys/llext/boards/intel_adsp_ace15_mtpm.conf new file mode 100644 index 000000000000..6badb3ebf43c --- /dev/null +++ b/tests/subsys/llext/boards/intel_adsp_ace15_mtpm.conf @@ -0,0 +1,2 @@ +# xt-clang cannot link shared libs for xtensa +CONFIG_LLEXT_TYPE_ELF_RELOCATABLE=y diff --git a/tests/subsys/llext/boards/intel_adsp_ace15_mtpm_sim.conf b/tests/subsys/llext/boards/intel_adsp_ace15_mtpm_sim.conf new file mode 100644 index 000000000000..6badb3ebf43c --- /dev/null +++ b/tests/subsys/llext/boards/intel_adsp_ace15_mtpm_sim.conf @@ -0,0 +1,2 @@ +# xt-clang cannot link shared libs for xtensa +CONFIG_LLEXT_TYPE_ELF_RELOCATABLE=y diff --git a/tests/subsys/llext/boards/intel_adsp_ace20_lnl.conf b/tests/subsys/llext/boards/intel_adsp_ace20_lnl.conf new file mode 100644 index 000000000000..6badb3ebf43c --- /dev/null +++ b/tests/subsys/llext/boards/intel_adsp_ace20_lnl.conf @@ -0,0 +1,2 @@ +# xt-clang cannot link shared libs for xtensa +CONFIG_LLEXT_TYPE_ELF_RELOCATABLE=y diff --git a/tests/subsys/llext/boards/intel_adsp_ace20_lnl_sim.conf b/tests/subsys/llext/boards/intel_adsp_ace20_lnl_sim.conf new file mode 100644 index 000000000000..6badb3ebf43c --- /dev/null +++ b/tests/subsys/llext/boards/intel_adsp_ace20_lnl_sim.conf @@ -0,0 +1,2 @@ +# xt-clang cannot link shared libs for xtensa +CONFIG_LLEXT_TYPE_ELF_RELOCATABLE=y diff --git a/tests/subsys/llext/boards/intel_adsp_ace30_ptl.conf b/tests/subsys/llext/boards/intel_adsp_ace30_ptl.conf new file mode 100644 index 000000000000..6badb3ebf43c --- /dev/null +++ b/tests/subsys/llext/boards/intel_adsp_ace30_ptl.conf @@ -0,0 +1,2 @@ +# xt-clang cannot link shared libs for xtensa +CONFIG_LLEXT_TYPE_ELF_RELOCATABLE=y diff --git a/tests/subsys/llext/boards/intel_adsp_ace30_ptl_sim.conf b/tests/subsys/llext/boards/intel_adsp_ace30_ptl_sim.conf new file mode 100644 index 000000000000..6badb3ebf43c --- /dev/null +++ b/tests/subsys/llext/boards/intel_adsp_ace30_ptl_sim.conf @@ -0,0 +1,2 @@ +# xt-clang cannot link shared libs for xtensa +CONFIG_LLEXT_TYPE_ELF_RELOCATABLE=y diff --git a/tests/subsys/llext/boards/intel_adsp_ace40_nvl.conf b/tests/subsys/llext/boards/intel_adsp_ace40_nvl.conf new file mode 100644 index 000000000000..6badb3ebf43c --- /dev/null +++ b/tests/subsys/llext/boards/intel_adsp_ace40_nvl.conf @@ -0,0 +1,2 @@ +# xt-clang cannot link shared libs for xtensa +CONFIG_LLEXT_TYPE_ELF_RELOCATABLE=y diff --git a/tests/subsys/llext/boards/intel_adsp_ace40_nvl_sim.conf b/tests/subsys/llext/boards/intel_adsp_ace40_nvl_sim.conf new file mode 100644 index 000000000000..6badb3ebf43c --- /dev/null +++ b/tests/subsys/llext/boards/intel_adsp_ace40_nvl_sim.conf @@ -0,0 +1,2 @@ +# xt-clang cannot link shared libs for xtensa +CONFIG_LLEXT_TYPE_ELF_RELOCATABLE=y diff --git a/tests/subsys/llext/no_mem_protection.conf b/tests/subsys/llext/no_mem_protection.conf index 76ad5cbc92a8..5a9143699b4e 100644 --- a/tests/subsys/llext/no_mem_protection.conf +++ b/tests/subsys/llext/no_mem_protection.conf @@ -8,3 +8,5 @@ CONFIG_ARM_AARCH32_MMU=n CONFIG_RISCV_PMP=n CONFIG_ARC_MPU_ENABLE=n CONFIG_X86_MMU=n +CONFIG_XTENSA_MMU=n +CONFIG_XTENSA_MPU=n From e593b9f03ab92b4fa31a3719706d641aa7b1fd21 Mon Sep 17 00:00:00 2001 From: Lauren Murphy Date: Sun, 14 Dec 2025 10:53:28 -0800 Subject: [PATCH 1469/3659] tests: subsys: llext: intel_adsp runtime fixes Add a Kconfig option for the test to put extensions in .text. This is useful for platforms for which the linker places .data in memory unsuitable for instruction execution, such as Intel ADSP's uncached memory. The theoretical alternative to support Intel ADSP is to add a platform-specific INSTR_FETCHABLE macro and platform-specific heap definition (placing the heap into .rodata) into llext so that the llext loader can copy text into an executable heap, but per a comment at llext_link's llext_link_plt, Xtensa llext's PLT linking is not valid when not performed inline in the ELF buffer. This is because it uses offsets from the text in the ELF buffer and assumes the text section's position relative to the other sections has not changed during loading. If one or more sections, particularly text, are loaded onto the heap, the relocation addresses calculated by the linker will not land in the correct memory region. Signed-off-by: Lauren Murphy --- tests/subsys/llext/Kconfig | 14 ++++++++ .../llext/boards/intel_adsp_ace15_mtpm.conf | 1 + .../boards/intel_adsp_ace15_mtpm_sim.conf | 1 + .../llext/boards/intel_adsp_ace20_lnl.conf | 1 + .../boards/intel_adsp_ace20_lnl_sim.conf | 1 + .../llext/boards/intel_adsp_ace30_ptl.conf | 1 + .../boards/intel_adsp_ace30_ptl_sim.conf | 1 + .../llext/boards/intel_adsp_ace40_nvl.conf | 1 + .../boards/intel_adsp_ace40_nvl_sim.conf | 1 + tests/subsys/llext/src/test_llext.c | 35 +++++++++++-------- 10 files changed, 42 insertions(+), 15 deletions(-) create mode 100644 tests/subsys/llext/Kconfig diff --git a/tests/subsys/llext/Kconfig b/tests/subsys/llext/Kconfig new file mode 100644 index 000000000000..8c3080cd1b22 --- /dev/null +++ b/tests/subsys/llext/Kconfig @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright (c) 2025 Intel Corporation. + +mainmenu "LLEXT tests" + +source "Kconfig.zephyr" + +config LLEXT_INC_IN_TEXT + bool "Put extension .inc array in .text instead of .data" + help + Put the llext extension .inc arrays from the LLEXT subsys tests + in .text instead of .data by default. This is useful for when the + memory region the linker places .data in by default is not suitable + for execution. diff --git a/tests/subsys/llext/boards/intel_adsp_ace15_mtpm.conf b/tests/subsys/llext/boards/intel_adsp_ace15_mtpm.conf index 6badb3ebf43c..1e4a69fc14e2 100644 --- a/tests/subsys/llext/boards/intel_adsp_ace15_mtpm.conf +++ b/tests/subsys/llext/boards/intel_adsp_ace15_mtpm.conf @@ -1,2 +1,3 @@ # xt-clang cannot link shared libs for xtensa CONFIG_LLEXT_TYPE_ELF_RELOCATABLE=y +CONFIG_LLEXT_INC_IN_TEXT=y diff --git a/tests/subsys/llext/boards/intel_adsp_ace15_mtpm_sim.conf b/tests/subsys/llext/boards/intel_adsp_ace15_mtpm_sim.conf index 6badb3ebf43c..1e4a69fc14e2 100644 --- a/tests/subsys/llext/boards/intel_adsp_ace15_mtpm_sim.conf +++ b/tests/subsys/llext/boards/intel_adsp_ace15_mtpm_sim.conf @@ -1,2 +1,3 @@ # xt-clang cannot link shared libs for xtensa CONFIG_LLEXT_TYPE_ELF_RELOCATABLE=y +CONFIG_LLEXT_INC_IN_TEXT=y diff --git a/tests/subsys/llext/boards/intel_adsp_ace20_lnl.conf b/tests/subsys/llext/boards/intel_adsp_ace20_lnl.conf index 6badb3ebf43c..1e4a69fc14e2 100644 --- a/tests/subsys/llext/boards/intel_adsp_ace20_lnl.conf +++ b/tests/subsys/llext/boards/intel_adsp_ace20_lnl.conf @@ -1,2 +1,3 @@ # xt-clang cannot link shared libs for xtensa CONFIG_LLEXT_TYPE_ELF_RELOCATABLE=y +CONFIG_LLEXT_INC_IN_TEXT=y diff --git a/tests/subsys/llext/boards/intel_adsp_ace20_lnl_sim.conf b/tests/subsys/llext/boards/intel_adsp_ace20_lnl_sim.conf index 6badb3ebf43c..1e4a69fc14e2 100644 --- a/tests/subsys/llext/boards/intel_adsp_ace20_lnl_sim.conf +++ b/tests/subsys/llext/boards/intel_adsp_ace20_lnl_sim.conf @@ -1,2 +1,3 @@ # xt-clang cannot link shared libs for xtensa CONFIG_LLEXT_TYPE_ELF_RELOCATABLE=y +CONFIG_LLEXT_INC_IN_TEXT=y diff --git a/tests/subsys/llext/boards/intel_adsp_ace30_ptl.conf b/tests/subsys/llext/boards/intel_adsp_ace30_ptl.conf index 6badb3ebf43c..1e4a69fc14e2 100644 --- a/tests/subsys/llext/boards/intel_adsp_ace30_ptl.conf +++ b/tests/subsys/llext/boards/intel_adsp_ace30_ptl.conf @@ -1,2 +1,3 @@ # xt-clang cannot link shared libs for xtensa CONFIG_LLEXT_TYPE_ELF_RELOCATABLE=y +CONFIG_LLEXT_INC_IN_TEXT=y diff --git a/tests/subsys/llext/boards/intel_adsp_ace30_ptl_sim.conf b/tests/subsys/llext/boards/intel_adsp_ace30_ptl_sim.conf index 6badb3ebf43c..1e4a69fc14e2 100644 --- a/tests/subsys/llext/boards/intel_adsp_ace30_ptl_sim.conf +++ b/tests/subsys/llext/boards/intel_adsp_ace30_ptl_sim.conf @@ -1,2 +1,3 @@ # xt-clang cannot link shared libs for xtensa CONFIG_LLEXT_TYPE_ELF_RELOCATABLE=y +CONFIG_LLEXT_INC_IN_TEXT=y diff --git a/tests/subsys/llext/boards/intel_adsp_ace40_nvl.conf b/tests/subsys/llext/boards/intel_adsp_ace40_nvl.conf index 6badb3ebf43c..1e4a69fc14e2 100644 --- a/tests/subsys/llext/boards/intel_adsp_ace40_nvl.conf +++ b/tests/subsys/llext/boards/intel_adsp_ace40_nvl.conf @@ -1,2 +1,3 @@ # xt-clang cannot link shared libs for xtensa CONFIG_LLEXT_TYPE_ELF_RELOCATABLE=y +CONFIG_LLEXT_INC_IN_TEXT=y diff --git a/tests/subsys/llext/boards/intel_adsp_ace40_nvl_sim.conf b/tests/subsys/llext/boards/intel_adsp_ace40_nvl_sim.conf index 6badb3ebf43c..1e4a69fc14e2 100644 --- a/tests/subsys/llext/boards/intel_adsp_ace40_nvl_sim.conf +++ b/tests/subsys/llext/boards/intel_adsp_ace40_nvl_sim.conf @@ -1,2 +1,3 @@ # xt-clang cannot link shared libs for xtensa CONFIG_LLEXT_TYPE_ELF_RELOCATABLE=y +CONFIG_LLEXT_INC_IN_TEXT=y diff --git a/tests/subsys/llext/src/test_llext.c b/tests/subsys/llext/src/test_llext.c index b74c275a8020..1ae98167d599 100644 --- a/tests/subsys/llext/src/test_llext.c +++ b/tests/subsys/llext/src/test_llext.c @@ -26,6 +26,11 @@ LOG_MODULE_REGISTER(test_llext); +#ifdef CONFIG_LLEXT_INC_IN_TEXT +#define LLEXT_SECT Z_GENERIC_SECTION(.text) +#else +#define LLEXT_SECT +#endif #ifdef CONFIG_LLEXT_STORAGE_WRITABLE #define LLEXT_CONST @@ -260,7 +265,7 @@ void load_call_unload(const struct llext_test *test_case) */ #define ELF_ALIGN __aligned(4096) -static LLEXT_CONST uint8_t hello_world_ext[] ELF_ALIGN = { +static LLEXT_CONST uint8_t hello_world_ext[] LLEXT_SECT ELF_ALIGN = { #include "hello_world.inc" }; LLEXT_LOAD_UNLOAD(hello_world, @@ -269,7 +274,7 @@ LLEXT_LOAD_UNLOAD(hello_world, /* When compiled with CCAC, init_fini's sections are unfixably out of order */ #if !defined(CONFIG_LLEXT_TYPE_ELF_SHAREDLIB) && !defined(__CCAC__) -static LLEXT_CONST uint8_t init_fini_ext[] ELF_ALIGN = { +static LLEXT_CONST uint8_t init_fini_ext[] LLEXT_SECT ELF_ALIGN = { #include "init_fini.inc" }; @@ -291,39 +296,39 @@ LLEXT_LOAD_UNLOAD(init_fini, ) #endif -static LLEXT_CONST uint8_t logging_ext[] ELF_ALIGN = { +static LLEXT_CONST uint8_t logging_ext[] LLEXT_SECT ELF_ALIGN = { #include "logging.inc" }; LLEXT_LOAD_UNLOAD(logging) -static LLEXT_CONST uint8_t relative_jump_ext[] ELF_ALIGN = { +static LLEXT_CONST uint8_t relative_jump_ext[] LLEXT_SECT ELF_ALIGN = { #include "relative_jump.inc" }; LLEXT_LOAD_UNLOAD(relative_jump) -static LLEXT_CONST uint8_t object_ext[] ELF_ALIGN = { +static LLEXT_CONST uint8_t object_ext[] LLEXT_SECT ELF_ALIGN = { #include "object.inc" }; LLEXT_LOAD_UNLOAD(object) -static LLEXT_CONST uint8_t syscalls_ext[] ELF_ALIGN = { +static LLEXT_CONST uint8_t syscalls_ext[] LLEXT_SECT ELF_ALIGN = { #include "syscalls.inc" }; LLEXT_LOAD_UNLOAD(syscalls) -static LLEXT_CONST uint8_t threads_kernel_objects_ext[] ELF_ALIGN = { +static LLEXT_CONST uint8_t threads_kernel_objects_ext[] LLEXT_SECT ELF_ALIGN = { #include "threads_kernel_objects.inc" }; LLEXT_LOAD_UNLOAD(threads_kernel_objects, .test_setup = threads_objects_test_setup, ) -static LLEXT_CONST uint8_t align_ext[] ELF_ALIGN = { +static LLEXT_CONST uint8_t align_ext[] LLEXT_SECT ELF_ALIGN = { #include "align.inc" }; LLEXT_LOAD_UNLOAD(align) -static LLEXT_CONST uint8_t inspect_ext[] ELF_ALIGN = { +static LLEXT_CONST uint8_t inspect_ext[] LLEXT_SECT ELF_ALIGN = { #include "inspect.inc" }; @@ -404,7 +409,7 @@ ZTEST(llext, test_inspect) } #ifndef CONFIG_LLEXT_TYPE_ELF_OBJECT -static LLEXT_CONST uint8_t multi_file_ext[] ELF_ALIGN = { +static LLEXT_CONST uint8_t multi_file_ext[] LLEXT_SECT ELF_ALIGN = { #include "multi_file.inc" }; LLEXT_LOAD_UNLOAD(multi_file) @@ -426,11 +431,11 @@ LLEXT_LOAD_UNLOAD(riscv_edge_case_non_paired_hi20_lo12) #endif /* !CONFIG_LLEXT_TYPE_ELF_OBJECT */ #ifndef CONFIG_USERSPACE -static LLEXT_CONST uint8_t export_dependent_ext[] ELF_ALIGN = { +static LLEXT_CONST uint8_t export_dependent_ext[] LLEXT_SECT ELF_ALIGN = { #include "export_dependent.inc" }; -static LLEXT_CONST uint8_t export_dependency_ext[] ELF_ALIGN = { +static LLEXT_CONST uint8_t export_dependency_ext[] LLEXT_SECT ELF_ALIGN = { #include "export_dependency.inc" }; @@ -465,7 +470,7 @@ ZTEST(llext, test_inter_ext) #endif #if defined(CONFIG_LLEXT_TYPE_ELF_RELOCATABLE) && defined(CONFIG_XTENSA) -static LLEXT_CONST uint8_t pre_located_ext[] ELF_ALIGN = { +static LLEXT_CONST uint8_t pre_located_ext[] LLEXT_SECT ELF_ALIGN = { #include "pre_located.inc" }; @@ -493,7 +498,7 @@ ZTEST(llext, test_pre_located) #endif #if defined(CONFIG_LLEXT_STORAGE_WRITABLE) -static LLEXT_CONST uint8_t find_section_ext[] ELF_ALIGN = { +static LLEXT_CONST uint8_t find_section_ext[] LLEXT_SECT ELF_ALIGN = { #include "find_section.inc" }; @@ -546,7 +551,7 @@ ZTEST(llext, test_find_section) #ifdef CONFIG_HARVARD static LLEXT_CONST uint8_t test_detached_ext[] Z_GENERIC_SECTION(.text) ELF_ALIGN = { #else -static LLEXT_CONST uint8_t test_detached_ext[] ELF_ALIGN = { +static LLEXT_CONST uint8_t test_detached_ext[] LLEXT_SECT ELF_ALIGN = { #endif #include "detached_fn.inc" }; From ce558ecdc3168d3f346e9cc339dca8a6007482f3 Mon Sep 17 00:00:00 2001 From: Lauren Murphy Date: Mon, 15 Dec 2025 14:03:17 -0800 Subject: [PATCH 1470/3659] boards: intel_adsp: add ram tags Adds RAM tags to select Intel ADSP platforms with the primary goal of getting LLEXT subsys tests to run. Signed-off-by: Lauren Murphy --- boards/intel/adsp/twister.yaml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/boards/intel/adsp/twister.yaml b/boards/intel/adsp/twister.yaml index 73284acebc80..16f5fe3fe720 100644 --- a/boards/intel/adsp/twister.yaml +++ b/boards/intel/adsp/twister.yaml @@ -28,20 +28,27 @@ variants: testing: timeout_multiplier: 8 intel_adsp/ace30/ptl: + ram: 4092 toolchain: - xt-clang - zephyr intel_adsp/ace30: twister: false + intel_adsp/ace20_lnl: + ram: 2048 intel_adsp/ace20_lnl/sim: type: sim + ram: 2048 simulation: - name: custom exec: acesim testing: timeout_multiplier: 4 + intel_adsp/ace15_mtpm: + ram: 2048 intel_adsp/ace15_mtpm/sim: type: sim + ram: 2048 simulation: - name: custom exec: acesim @@ -49,6 +56,7 @@ variants: timeout_multiplier: 4 intel_adsp/ace30/ptl/sim: type: sim + ram: 4096 simulation: - name: custom exec: acesim @@ -61,10 +69,12 @@ variants: toolchain: - xt-clang intel_adsp/ace40/nvl: + ram: 4096 toolchain: - xt-clang intel_adsp/ace40/nvl/sim: type: sim + ram: 4096 toolchain: - xt-clang simulation: From e53da36164703c3ed42f523524c16e7ae37a8436 Mon Sep 17 00:00:00 2001 From: Ederson de Souza Date: Tue, 23 Dec 2025 11:22:28 -0800 Subject: [PATCH 1471/3659] samples: tfm_integration: tfm_secure_partition: Support SFN backend When support for old "Library model" was removed, support for the new Secure Function (SFN) model - the FF-M 1.1 spec that succeded the "Library model" - wasn't implemented. This patch adds it. Signed-off-by: Ederson de Souza --- .../tfm_secure_partition/CMakeLists.txt | 11 +++++++++ .../tfm_secure_partition/README.rst | 3 ++- .../dummy_partition/dummy_partition.c | 14 +++++++++++ ...ition.yaml => tfm_dummy_partition.yaml.in} | 3 ++- .../dummy_partition/tfm_manifest_list.yaml.in | 2 +- .../src/dummy_partition.c | 23 ------------------- scripts/ci/check_compliance.py | 2 ++ 7 files changed, 32 insertions(+), 26 deletions(-) rename samples/tfm_integration/tfm_secure_partition/dummy_partition/{tfm_dummy_partition.yaml => tfm_dummy_partition.yaml.in} (92%) diff --git a/samples/tfm_integration/tfm_secure_partition/CMakeLists.txt b/samples/tfm_integration/tfm_secure_partition/CMakeLists.txt index beadae9230ab..52f5a6668f52 100644 --- a/samples/tfm_integration/tfm_secure_partition/CMakeLists.txt +++ b/samples/tfm_integration/tfm_secure_partition/CMakeLists.txt @@ -14,6 +14,17 @@ configure_file( ${CMAKE_CURRENT_BINARY_DIR}/dummy_partition/tfm_manifest_list.yaml ) +if(CONFIG_TFM_IPC) + set(SPM_BACKEND "IPC") +else() + set(SPM_BACKEND "SFN") +endif() + +configure_file( + ${CMAKE_CURRENT_LIST_DIR}/dummy_partition/tfm_dummy_partition.yaml.in + ${CMAKE_CURRENT_BINARY_DIR}/dummy_partition/tfm_dummy_partition.yaml +) + set_property(TARGET zephyr_property_target APPEND PROPERTY TFM_CMAKE_OPTIONS -DTFM_EXTRA_MANIFEST_LIST_FILES=${CMAKE_CURRENT_BINARY_DIR}/dummy_partition/tfm_manifest_list.yaml diff --git a/samples/tfm_integration/tfm_secure_partition/README.rst b/samples/tfm_integration/tfm_secure_partition/README.rst index 1108856323cf..faa436332c73 100644 --- a/samples/tfm_integration/tfm_secure_partition/README.rst +++ b/samples/tfm_integration/tfm_secure_partition/README.rst @@ -33,7 +33,8 @@ files inside "partition". Building and Running ******************** -This sample can be built with or without CONFIG_TFM_IPC, since it contains code for both. +This sample can be built with either :kconfig:option:`CONFIG_TFM_IPC` or :kconfig:option:`CONFIG_TFM_SFN`, +since it contains code for both. On Target ========= diff --git a/samples/tfm_integration/tfm_secure_partition/dummy_partition/dummy_partition.c b/samples/tfm_integration/tfm_secure_partition/dummy_partition/dummy_partition.c index d618868ddbfd..e7f8b6cb0882 100644 --- a/samples/tfm_integration/tfm_secure_partition/dummy_partition/dummy_partition.c +++ b/samples/tfm_integration/tfm_secure_partition/dummy_partition/dummy_partition.c @@ -89,6 +89,8 @@ static psa_status_t tfm_dp_secret_digest_ipc(psa_msg_t *msg) (void *)msg->handle); } +#if CONFIG_TFM_SPM_BACKEND_IPC == 1 +#pragma message "Dummy partition SPM backend: IPC" static void dp_signal_handle(psa_signal_t signal, dp_func_t pfn) { psa_status_t status; @@ -127,3 +129,15 @@ psa_status_t tfm_dp_req_mngr_init(void) return PSA_ERROR_SERVICE_FAILURE; } +#elif CONFIG_TFM_SPM_BACKEND_SFN == 1 +#pragma message "Dummy partition SPM backend: SFN" +psa_status_t tfm_dp_secret_digest_sfn(const psa_msg_t *msg) +{ + if (msg->type == PSA_IPC_CONNECT || msg->type == PSA_IPC_DISCONNECT) { + return PSA_SUCCESS; + } + return tfm_dp_secret_digest_ipc((psa_msg_t *)msg); +} +#else +#error "No SPM backend selected" +#endif diff --git a/samples/tfm_integration/tfm_secure_partition/dummy_partition/tfm_dummy_partition.yaml b/samples/tfm_integration/tfm_secure_partition/dummy_partition/tfm_dummy_partition.yaml.in similarity index 92% rename from samples/tfm_integration/tfm_secure_partition/dummy_partition/tfm_dummy_partition.yaml rename to samples/tfm_integration/tfm_secure_partition/dummy_partition/tfm_dummy_partition.yaml.in index 953c7246b660..1a6db6159d23 100644 --- a/samples/tfm_integration/tfm_secure_partition/dummy_partition/tfm_dummy_partition.yaml +++ b/samples/tfm_integration/tfm_secure_partition/dummy_partition/tfm_dummy_partition.yaml.in @@ -11,7 +11,8 @@ "name": "TFM_SP_DP", "type": "APPLICATION-ROT", "priority": "NORMAL", - "model": "IPC", + "model": "${SPM_BACKEND}", + # entry_point below is ignored when using the SFN backend "entry_point": "tfm_dp_req_mngr_init", "stack_size": "0x800", diff --git a/samples/tfm_integration/tfm_secure_partition/dummy_partition/tfm_manifest_list.yaml.in b/samples/tfm_integration/tfm_secure_partition/dummy_partition/tfm_manifest_list.yaml.in index 83ace02a491a..f3652e3a3366 100644 --- a/samples/tfm_integration/tfm_secure_partition/dummy_partition/tfm_manifest_list.yaml.in +++ b/samples/tfm_integration/tfm_secure_partition/dummy_partition/tfm_manifest_list.yaml.in @@ -15,7 +15,7 @@ { "description": "Dummy Partition", "short_name": "TFM_DP", - "manifest": "${APPLICATION_SOURCE_DIR}/dummy_partition/tfm_dummy_partition.yaml", + "manifest": "${CMAKE_CURRENT_BINARY_DIR}/dummy_partition/tfm_dummy_partition.yaml", "output_path": "${TFM_BINARY_DIR}/dummy_partition", "tfm_partition_ipc": true, "version_major": 0, diff --git a/samples/tfm_integration/tfm_secure_partition/src/dummy_partition.c b/samples/tfm_integration/tfm_secure_partition/src/dummy_partition.c index 42eea8ac21e8..7935b6255d39 100644 --- a/samples/tfm_integration/tfm_secure_partition/src/dummy_partition.c +++ b/samples/tfm_integration/tfm_secure_partition/src/dummy_partition.c @@ -8,7 +8,6 @@ #include "dummy_partition.h" -#if defined(CONFIG_TFM_IPC) #include "psa/client.h" #include "psa_manifest/sid.h" @@ -40,25 +39,3 @@ psa_status_t dp_secret_digest(uint32_t secret_index, return status; } -#else /* defined(CONFIG_TFM_IPC) */ -psa_status_t dp_secret_digest(uint32_t secret_index, - void *p_digest, - size_t digest_size) -{ - psa_status_t status; - psa_invec in_vec[] = { - { .base = &secret_index, .len = sizeof(secret_index) }, - }; - - psa_outvec out_vec[] = { - { .base = p_digest, .len = digest_size } - }; - - status = tfm_ns_interface_dispatch( - (veneer_fn)tfm_dp_secret_digest_req_veneer, - (uint32_t)in_vec, IOVEC_LEN(in_vec), - (uint32_t)out_vec, IOVEC_LEN(out_vec)); - - return status; -} -#endif /* defined(CONFIG_TFM_IPC) */ diff --git a/scripts/ci/check_compliance.py b/scripts/ci/check_compliance.py index 96bdcdce97f1..701fc1fce02a 100755 --- a/scripts/ci/check_compliance.py +++ b/scripts/ci/check_compliance.py @@ -1610,6 +1610,8 @@ def check_no_undef_outside_kconfig(self, kconf): "STACK_SIZE", # Used as an example in the Kconfig docs "STD_CPP", # Referenced in CMake comment "TEST1", + "TFM_SPM_BACKEND_IPC", # Used in TFM sample dummy partition - belongs to TFM + "TFM_SPM_BACKEND_SFN", # Used in TFM sample dummy partition - belongs to TFM # Defined in modules/hal_nxp/mcux/mcux-sdk-ng/basic.cmake. # It is used by MCUX SDK cmake functions to add content # based on current toolchain. From e76a584fc9e8ea9f125ebf47ca866c92566c7b77 Mon Sep 17 00:00:00 2001 From: Ederson de Souza Date: Tue, 23 Dec 2025 11:22:35 -0800 Subject: [PATCH 1472/3659] samples: tfm_integration: tfm_secure_partition: Add test for SFN backend With SFN support in the sample back, let's test it. Signed-off-by: Ederson de Souza --- .../tfm_integration/tfm_secure_partition/sample.yaml | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/samples/tfm_integration/tfm_secure_partition/sample.yaml b/samples/tfm_integration/tfm_secure_partition/sample.yaml index c5a88b09ccf4..990a4579b85f 100644 --- a/samples/tfm_integration/tfm_secure_partition/sample.yaml +++ b/samples/tfm_integration/tfm_secure_partition/sample.yaml @@ -1,6 +1,7 @@ common: tags: - trusted-firmware-m + - mcuboot platform_allow: - mps2/an521/cpu0/ns - v2m_musca_s1/musca_s1/ns @@ -25,7 +26,9 @@ sample: name: "TFM Secure Partition Sample" tests: - sample.tfm.secure_partition: - tags: - - trusted-firmware-m - - mcuboot + sample.tfm.secure_partition.ipc: + extra_configs: + - CONFIG_TFM_IPC=y + sample.tfm.secure_partition.sfn: + extra_configs: + - CONFIG_TFM_SFN=y From d7ccfc929d6969cef6f593e547938cb7a52e6e58 Mon Sep 17 00:00:00 2001 From: Afonso Oliveira Date: Sat, 3 Jan 2026 17:23:02 +0000 Subject: [PATCH 1473/3659] arch: riscv: guard CSR access macros and helpers from asm The csr_*() macros and Smcsrind indirect CSR access helpers in csr.h are C-only constructs using GNU C statement expressions, but csr.h is also included from assembly sources when building with -D_ASMLANGUAGE. Guard all C-only macros and functions so they are not seen by the assembler, leaving only the numeric CSR definitions in the common (ASM+C) section. Signed-off-by: Afonso Oliveira --- include/zephyr/arch/riscv/csr.h | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/include/zephyr/arch/riscv/csr.h b/include/zephyr/arch/riscv/csr.h index 2ab04e91a5f3..76c639b8605a 100644 --- a/include/zephyr/arch/riscv/csr.h +++ b/include/zephyr/arch/riscv/csr.h @@ -193,6 +193,20 @@ ((val) & ~(which)) | ((fieldval) * ((which) & ~((which)-1))) \ ) \ +#ifdef CONFIG_RISCV_ISA_EXT_SMCSRIND + +#define MISELECT 0x350 +#define MIREG 0x351 +#define MIREG2 0x352 +#define MIREG3 0x353 +#define MIREG4 0x355 +#define MIREG5 0x356 +#define MIREG6 0x357 + +#endif /* CONFIG_RISCV_ISA_EXT_SMCSRIND */ + +#ifndef _ASMLANGUAGE + #define csr_read(csr) \ ({ \ register unsigned long __rv; \ @@ -249,14 +263,6 @@ #ifdef CONFIG_RISCV_ISA_EXT_SMCSRIND -#define MISELECT 0x350 -#define MIREG 0x351 -#define MIREG2 0x352 -#define MIREG3 0x353 -#define MIREG4 0x355 -#define MIREG5 0x356 -#define MIREG6 0x357 - static inline unsigned long icsr_read(unsigned int index) { csr_write(MISELECT, index); @@ -287,4 +293,6 @@ static inline unsigned long icsr_read_clear(unsigned int index, unsigned long ma #endif /* CONFIG_RISCV_ISA_EXT_SMCSRIND */ +#endif /* !_ASMLANGUAGE */ + #endif /* CSR_H_ */ From cb82c96dbbe8799fd3aaa81b91d2969ae8564006 Mon Sep 17 00:00:00 2001 From: Elmo Lan Date: Tue, 6 Jan 2026 15:09:08 +0800 Subject: [PATCH 1474/3659] drivers: i2c_dw: recovery i2c bus after when user abort When the transfer timeout and driver set user abort, we need go recovery flow to make sure bus recovery and reg recovery. Signed-off-by: Elmo Lan --- drivers/i2c/i2c_dw.c | 5 +++++ drivers/i2c/i2c_dw.h | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/i2c/i2c_dw.c b/drivers/i2c/i2c_dw.c index 14f1ae98e039..12f1b83a17a8 100644 --- a/drivers/i2c/i2c_dw.c +++ b/drivers/i2c/i2c_dw.c @@ -133,6 +133,11 @@ static int i2c_dw_error_chk(const struct device *dev) dw->state |= I2C_DW_SDA_STUCK; LOG_ERR("SDA Stuck Low on %s", dev->name); } + /* check if user abort the transmit */ + if (ic_txabrt_src.bits.USRABRT) { + dw->state |= I2C_DW_USER_ABRT; + LOG_ERR("User Abort on %s", dev->name); + } /* clear RTS5912_INTR_STAT_TX_ABRT */ value = read_clr_tx_abrt(reg_base); } diff --git a/drivers/i2c/i2c_dw.h b/drivers/i2c/i2c_dw.h index bf6b8d18776e..78637e46857f 100644 --- a/drivers/i2c/i2c_dw.h +++ b/drivers/i2c/i2c_dw.h @@ -39,14 +39,14 @@ typedef void (*i2c_isr_cb_t)(const struct device *port); #define I2C_DW_CMD_RECV (1 << 1) #define I2C_DW_CMD_ERROR (1 << 2) #define I2C_DW_BUSY (1 << 3) -#define I2C_DW_TX_ABRT (1 << 4) +#define I2C_DW_USER_ABRT (1 << 4) #define I2C_DW_NACK (1 << 5) #define I2C_DW_SCL_STUCK (1 << 6) #define I2C_DW_SDA_STUCK (1 << 7) #define I2C_DW_ERR_MASK (I2C_DW_CMD_ERROR | I2C_DW_SCL_STUCK | I2C_DW_SDA_STUCK | I2C_DW_NACK) -#define I2C_DW_STUCK_ERR_MASK (I2C_DW_SCL_STUCK | I2C_DW_SDA_STUCK) +#define I2C_DW_STUCK_ERR_MASK (I2C_DW_SCL_STUCK | I2C_DW_SDA_STUCK | I2C_DW_USER_ABRT) #ifdef CONFIG_I2C_DW_EXTENDED_SUPPORT #define DW_ENABLE_TX_INT_I2C_MASTER \ From a206401647752c576e5ca9844995f38695f2f11e Mon Sep 17 00:00:00 2001 From: Ben Levinsky Date: Tue, 6 Jan 2026 06:40:49 -0800 Subject: [PATCH 1475/3659] drivers: ipm: ipm_mbox: handle mailbox notifications without payload Some mailbox backends may deliver notifications without an associated data payload. This can occur when the mailbox is used as a signal-only mechanism, where struct mbox_msg is NULL, data is NULL, or size is zero. The IPM mailbox callback currently assumes a valid data payload and unconditionally dereferences data->data, which can lead to a NULL pointer dereference for such mailbox implementations. Update the IPM mailbox callback to tolerate empty mailbox messages and invoke the IPM callback with a NULL payload pointer when no data is present. This preserves notification semantics while preventing runtime faults. Signed-off-by: Ben Levinsky --- drivers/ipm/ipm_mbox.c | 37 ++++++++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/drivers/ipm/ipm_mbox.c b/drivers/ipm/ipm_mbox.c index a8394ba3b3fe..cdd70bb6b116 100644 --- a/drivers/ipm/ipm_mbox.c +++ b/drivers/ipm/ipm_mbox.c @@ -25,13 +25,44 @@ struct ipm_mbox_config { struct mbox_dt_spec mbox_rx; }; -static void ipm_mbox_callback(const struct device *mboxdev, mbox_channel_id_t channel_id, - void *user_data, struct mbox_msg *data) +/** + * @brief Mailbox callback wrapper for IPM + * + * Mailbox notifications may be delivered without a data payload when + * used in signal-only mode. In this case, the IPM callback is invoked + * with a NULL payload pointer. + * + * For signal-only notifications, the mailbox channel identifier + * represents the signal value. Users can distinguish multiple signals + * by using separate mailbox channels. + * + * @param mboxdev Mailbox device instance + * @param channel_id Mailbox channel identifier (used as signal for signal-only) + * @param user_data Pointer to the IPM device + * @param data Mailbox message, may be NULL for signal-only notifications + */ +static void ipm_mbox_callback(const struct device *mboxdev, + mbox_channel_id_t channel_id, + void *user_data, + struct mbox_msg *data) { const struct device *ipmdev = user_data; struct ipm_mbox_data *ipm_mbox_data = ipmdev->data; + void *payload = NULL; + + if (!ipm_mbox_data || !ipm_mbox_data->callback) { + return; + } + + /* Only use the payload if the mailbox provides a non-empty buffer */ + if (data && data->data && data->size > 0) { + payload = data->data; + } - ipm_mbox_data->callback(ipmdev, ipm_mbox_data->user_data, channel_id, (void *)data->data); + ipm_mbox_data->callback(ipmdev, + ipm_mbox_data->user_data, + channel_id, + payload); } static int ipm_mbox_send(const struct device *ipmdev, int wait, uint32_t id, From 353bd994c2d160390622d4bedbeb62ba722864a8 Mon Sep 17 00:00:00 2001 From: Ben Levinsky Date: Tue, 6 Jan 2026 15:20:47 -0800 Subject: [PATCH 1476/3659] doc: release-notes/4.4: Add release note for IPM Add release notes for IPM driver noting ipm_mbox driver issue Signed-off-by: Ben Levinsky --- doc/releases/release-notes-4.4.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/releases/release-notes-4.4.rst b/doc/releases/release-notes-4.4.rst index f087880a8bb4..1bdc2a9fe4d9 100644 --- a/doc/releases/release-notes-4.4.rst +++ b/doc/releases/release-notes-4.4.rst @@ -158,6 +158,12 @@ New APIs and options * :dtcompatible:`jedec,mspi-nor` now allows MSPI configuration of read, write and control commands separately via devicetree. +* IPM + + * IPM callbacks for the mailbox backend now correctly handle signal-only mailbox + mailbox usage. Applications should be prepared to receive a NULL payload pointer + in IPM callbacks when no data buffer is provided by the mailbox. + * Modem * :kconfig:option:`CONFIG_MODEM_HL78XX_AT_SHELL` From 9dc81618701378358c4463bdfd11c0b5148dd068 Mon Sep 17 00:00:00 2001 From: Pete Johanson Date: Thu, 18 Dec 2025 16:42:35 -0700 Subject: [PATCH 1477/3659] drivers: sensor: Add missing get_size_info to ADXL362 decoder Properly report size info for the ADXL362 decoder for streaming data properly from that sensor. Signed-off-by: Pete Johanson --- drivers/sensor/adi/adxl362/adxl362_decoder.c | 21 ++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/drivers/sensor/adi/adxl362/adxl362_decoder.c b/drivers/sensor/adi/adxl362/adxl362_decoder.c index b3d9304a2ce7..0bcfa842ae79 100644 --- a/drivers/sensor/adi/adxl362/adxl362_decoder.c +++ b/drivers/sensor/adi/adxl362/adxl362_decoder.c @@ -216,6 +216,26 @@ static int adxl362_decode_stream(const uint8_t *buffer, struct sensor_chan_spec #endif /* CONFIG_ADXL362_STREAM */ +static int adxl362_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_ACCEL_X: + case SENSOR_CHAN_ACCEL_Y: + case SENSOR_CHAN_ACCEL_Z: + case SENSOR_CHAN_ACCEL_XYZ: + *base_size = sizeof(struct sensor_three_axis_data); + *frame_size = sizeof(struct sensor_three_axis_sample_data); + return 0; + case SENSOR_CHAN_DIE_TEMP: + *base_size = sizeof(struct sensor_q31_data); + *frame_size = sizeof(struct sensor_q31_sample_data); + return 0; + default: + return -ENOTSUP; + } +} + static int adxl362_decoder_get_frame_count(const uint8_t *buffer, struct sensor_chan_spec chan_spec, uint16_t *frame_count) @@ -354,6 +374,7 @@ static bool adxl362_decoder_has_trigger(const uint8_t *buffer, enum sensor_trigg SENSOR_DECODER_API_DT_DEFINE() = { .get_frame_count = adxl362_decoder_get_frame_count, + .get_size_info = adxl362_decoder_get_size_info, .decode = adxl362_decoder_decode, .has_trigger = adxl362_decoder_has_trigger, }; From 6383a7222b58d5ebddc0c4519d0a35cb5940cddb Mon Sep 17 00:00:00 2001 From: Sam Friedman Date: Wed, 7 Jan 2026 15:49:37 -0500 Subject: [PATCH 1478/3659] tests: net: coap_client: allow native_sim/native/64 Fix build failures when compiling for 64-bit native_sim, and add native_sim/native/64 to the platform allow list for the coap client tests. Signed-off-by: Sam Friedman --- tests/net/lib/coap_client/src/main.c | 8 ++++---- tests/net/lib/coap_client/testcase.yaml | 1 + 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/tests/net/lib/coap_client/src/main.c b/tests/net/lib/coap_client/src/main.c index 38fa3b9929b9..75c33dcb52b7 100644 --- a/tests/net/lib/coap_client/src/main.c +++ b/tests/net/lib/coap_client/src/main.c @@ -537,8 +537,8 @@ ZTEST(coap_client, test_request_block) ZTEST(coap_client, test_resend_request) { - int (*sendto_fakes[])(int, void *, size_t, int, const struct net_sockaddr *, - net_socklen_t) = { + ssize_t (*sendto_fakes[])(int, void *, size_t, int, const struct net_sockaddr *, + net_socklen_t) = { z_impl_zsock_sendto_custom_fake_no_reply, z_impl_zsock_sendto_custom_fake_block, z_impl_zsock_sendto_custom_fake, @@ -653,8 +653,8 @@ ZTEST(coap_client, test_separate_response_ack_fail) req.user_data = &sem1; - int (*sendto_fakes[])(int, void *, size_t, int, const struct net_sockaddr *, - net_socklen_t) = { + ssize_t (*sendto_fakes[])(int, void *, size_t, int, const struct net_sockaddr *, + net_socklen_t) = { z_impl_zsock_sendto_custom_fake, z_impl_zsock_sendto_custom_fake_err, }; diff --git a/tests/net/lib/coap_client/testcase.yaml b/tests/net/lib/coap_client/testcase.yaml index 52c0cdc5557b..578cc4b8d0f6 100644 --- a/tests/net/lib/coap_client/testcase.yaml +++ b/tests/net/lib/coap_client/testcase.yaml @@ -4,6 +4,7 @@ tests: net.coap.client: platform_allow: - native_sim + - native_sim/native/64 tags: - coap - net From 88a3b35fcc955800d1fb4cfda8ed4368fd4be9d2 Mon Sep 17 00:00:00 2001 From: McAtee Maxwell Date: Wed, 7 Jan 2026 13:47:14 -0800 Subject: [PATCH 1479/3659] tests: update pwm test overlay for kit_pse84_eval device - Change the pwm periods for kit_pse84_eval in the pwm_gpio_loopback Signed-off-by: McAtee Maxwell --- .../pwm_gpio_loopback/boards/kit_pse84_eval_common.overlay | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/drivers/pwm/pwm_gpio_loopback/boards/kit_pse84_eval_common.overlay b/tests/drivers/pwm/pwm_gpio_loopback/boards/kit_pse84_eval_common.overlay index ad6c563a9ae7..51e796c9a1d9 100644 --- a/tests/drivers/pwm/pwm_gpio_loopback/boards/kit_pse84_eval_common.overlay +++ b/tests/drivers/pwm/pwm_gpio_loopback/boards/kit_pse84_eval_common.overlay @@ -10,8 +10,8 @@ / { zephyr,user { - pwms = <&pwm0_1 0 PWM_MSEC(20) (PWM_POLARITY_NORMAL | PWM_IFX_TCPWM_OUTPUT_HIGHZ)>, - <&pwm1_19 1 PWM_MSEC(20) (PWM_POLARITY_NORMAL | PWM_IFX_TCPWM_OUTPUT_HIGHZ)>; + pwms = <&pwm0_1 0 PWM_MSEC(2) (PWM_POLARITY_NORMAL | PWM_IFX_TCPWM_OUTPUT_HIGHZ)>, + <&pwm1_19 1 PWM_MSEC(2) (PWM_POLARITY_NORMAL | PWM_IFX_TCPWM_OUTPUT_HIGHZ)>; gpios = <&gpio_prt16 2 GPIO_ACTIVE_HIGH>, <&gpio_prt15 3 GPIO_ACTIVE_HIGH>; }; From a989118dba78c5ac41896f00c29787f62f663fe7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Fri, 9 Jan 2026 16:03:10 +0100 Subject: [PATCH 1480/3659] MAINTAINERS: update Zephyr 4.4 release engineers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make Zephyr 4.4 release engineers maintainers of release notes and migration guide for the time being. Signed-off-by: Benjamin Cabé --- MAINTAINERS.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index f7734094b88c..950a89950ecf 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -4463,6 +4463,9 @@ Release: Release Notes: status: maintained maintainers: + - MaureenHelm + - stephanosio + collaborators: - kartben files: - doc/releases/migration-guide-* From 4d2af2647e6bc78ca3390741b8abe06fe4cabc49 Mon Sep 17 00:00:00 2001 From: Gang He Date: Tue, 23 Dec 2025 11:21:03 -0800 Subject: [PATCH 1481/3659] west.yml: hal_sifli: Update to latest revision - Add support to compile with no LCPU patch as CI do not fetch blobs. Signed-off-by: Gang He --- modules/hal_sifli/CMakeLists.txt | 6 ++++++ west.yml | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/modules/hal_sifli/CMakeLists.txt b/modules/hal_sifli/CMakeLists.txt index 99ad33141a9a..8995ac87f3bf 100644 --- a/modules/hal_sifli/CMakeLists.txt +++ b/modules/hal_sifli/CMakeLists.txt @@ -187,6 +187,12 @@ if(CONFIG_HAS_SIFLI_HAL) ${ZEPHYR_HAL_SIFLI_MODULE_DIR}/ipc_queue/sf32lb52x ) endif() + set(LCPU_PATCH_FILE "${ZEPHYR_HAL_SIFLI_MODULE_DIR}/zephyr/blobs/sf32lb52_lcpu.h") + if(EXISTS ${LCPU_PATCH_FILE}) + zephyr_compile_definitions(SF32LB_LCPU_PATCH) + else() + message(WARNING "Patch ${LCPU_INSTALL_FILE} is not available, please call: west blobs fetch hal_sifli") + endif() endif() if(CONFIG_USE_SIFLI_HAL_AES OR CONFIG_USE_SIFLI_HAL_HASH) diff --git a/west.yml b/west.yml index 9af027740c05..b563d0f75b7d 100644 --- a/west.yml +++ b/west.yml @@ -240,7 +240,7 @@ manifest: groups: - hal - name: hal_sifli - revision: faf0646bde76333644b9ec8ca156dd2affe1a9cf + revision: 86fa0e9433fda1a760e0077c19b8407ecceea2f9 path: modules/hal/sifli groups: - hal From e724188a6f6eaccab925e9265869bc12ad1fc183 Mon Sep 17 00:00:00 2001 From: Gang He Date: Mon, 24 Nov 2025 13:41:29 +0800 Subject: [PATCH 1482/3659] drivers: dma: Add half complete callback for SF32LB chipset Add callback of half complete in DMA processing, Fix DMA size bug. Signed-off-by: Gang He --- drivers/dma/dma_sf32lb.c | 65 +++++++++++++++++++++++++++++------- include/zephyr/drivers/dma.h | 10 ++++-- 2 files changed, 60 insertions(+), 15 deletions(-) diff --git a/drivers/dma/dma_sf32lb.c b/drivers/dma/dma_sf32lb.c index 87b68e202032..8d1857f1366f 100644 --- a/drivers/dma/dma_sf32lb.c +++ b/drivers/dma/dma_sf32lb.c @@ -44,6 +44,7 @@ LOG_MODULE_REGISTER(dma_sf32lb, CONFIG_DMA_LOG_LEVEL); #define DMAC_CSELR2 offsetof(DMAC_TypeDef, CSELR2) #define DMAC_ISR_TCIF(n) (DMAC_ISR_TCIF1_Msk << (n * 4U)) +#define DMAC_ISR_HTIF(n) (DMAC_ISR_HTIF1_Msk << (n * 4U)) #define DMAC_IFCR_ALL(n) \ ((DMAC_IFCR_CGIF1_Msk | DMAC_IFCR_CTCIF1_Msk | DMAC_IFCR_CHTIF1_Msk | \ @@ -51,6 +52,7 @@ LOG_MODULE_REGISTER(dma_sf32lb, CONFIG_DMA_LOG_LEVEL); << (n * 4U)) #define DMAC_IFCR_CTCIF(n) (DMAC_IFCR_CTCIF1_Msk << (n * 4U)) #define DMAC_IFCR_CTEIF(n) (DMAC_IFCR_CTEIF1_Msk << (n * 4U)) +#define DMAC_IFCR_CTHIF(n) (DMAC_IFCR_CHTIF1_Msk << (n * 4U)) #define DMAC_CCRX_PSIZE(n) FIELD_PREP(DMAC_CCR1_PSIZE_Msk, LOG2CEIL(n)) #define DMAC_CCRX_MSIZE(n) FIELD_PREP(DMAC_CCR1_MSIZE_Msk, LOG2CEIL(n)) @@ -74,6 +76,7 @@ struct dma_sf32lb_config { struct dma_sf32lb_channel { dma_callback_t callback; void *user_data; + uint32_t size; enum dma_channel_direction direction; }; @@ -93,12 +96,16 @@ static void dma_sf32lb_isr(const struct device *dev, uint8_t channel) isr = sys_read32(config->dmac + DMAC_ISR); if ((isr & DMAC_ISR_TCIF(channel)) != 0U) { status = DMA_STATUS_COMPLETE; + } else if ((isr & DMAC_ISR_HTIF(channel)) != 0U) { + status = DMA_STATUS_HALF_COMPLETE; atomic_clear_bit(data->status, channel); - } else { + } else if (isr) { status = -EIO; + } else { + status = -EINPROGRESS; } - if (config->channels[channel].callback) { + if (status != -EINPROGRESS && config->channels[channel].callback != NULL) { config->channels[channel].callback(dev, config->channels[channel].user_data, channel, status); } @@ -114,16 +121,9 @@ static void dma_sf32lb_isr(const struct device *dev, uint8_t channel) LISTIFY(8, DMA_SF32LB_IRQ_DEFINE, ()) -static int dma_sf32lb_config(const struct device *dev, uint32_t channel, - struct dma_config *config_dma) +static int check_dma_config(uint32_t channel, struct dma_config *config_dma, + const struct dma_sf32lb_config *config) { - const struct dma_sf32lb_config *config = dev->config; - struct dma_sf32lb_data *data = dev->data; - uint32_t ccrx; - uint32_t cselrx; - uint32_t cparx; - uint32_t cm0arx; - if (channel >= config->n_channels) { LOG_ERR("Invalid channel (%" PRIu32 ", max %" PRIu32 ")", channel, config->n_channels); @@ -174,6 +174,30 @@ static int dma_sf32lb_config(const struct device *dev, uint32_t channel, return -EINVAL; } + if (config_dma->dest_data_size != config_dma->source_data_size) { + LOG_ERR("Destination and source sizes not equal"); + return -EINVAL; + } + + return 0; +} + +static int dma_sf32lb_config(const struct device *dev, uint32_t channel, + struct dma_config *config_dma) +{ + int ret; + const struct dma_sf32lb_config *config = dev->config; + struct dma_sf32lb_data *data = dev->data; + uint32_t ccrx; + uint32_t cselrx; + uint32_t cparx; + uint32_t cm0arx; + + ret = check_dma_config(channel, config_dma, config); + if (ret < 0) { + return ret; + } + /* configure transfer parameters */ ccrx = sys_read32(config->dmac + DMAC_CCRX(channel)); if ((ccrx & DMAC_CCR1_EN) != 0U) { @@ -188,6 +212,14 @@ static int dma_sf32lb_config(const struct device *dev, uint32_t channel, ccrx |= FIELD_PREP(DMAC_CCR1_PL_Msk, config_dma->channel_priority); + if (config_dma->head_block->dest_reload_en || config_dma->head_block->source_reload_en) { + ccrx |= DMAC_CCR1_CIRC; + } + + if (config_dma->half_complete_callback_en) { + ccrx |= DMAC_CCR1_HTIE; + } + switch (config_dma->channel_direction) { case MEMORY_TO_MEMORY: ccrx |= DMAC_CCR1_MEM2MEM; @@ -254,6 +286,7 @@ static int dma_sf32lb_config(const struct device *dev, uint32_t channel, config->channels[channel].callback = config_dma->dma_callback; config->channels[channel].user_data = config_dma->user_data; config->channels[channel].direction = config_dma->channel_direction; + config->channels[channel].size = config_dma->source_data_size; return 0; } @@ -284,6 +317,13 @@ static int dma_sf32lb_reload(const struct device *dev, uint32_t channel, uint32_ } /* configure size, src/dst addresses */ + if (config->channels[channel].size == 4) { + size >>= 2; + } else if (config->channels[channel].size == 2) { + size >>= 1; + } else { + } + sys_write32(size, config->dmac + DMAC_CNDTRX(channel)); switch (config->channels[channel].direction) { @@ -321,7 +361,8 @@ static int dma_sf32lb_start(const struct device *dev, uint32_t channel) ccrx = sys_read32(config->dmac + DMAC_CCRX(channel)); if ((ccrx & DMAC_CCR1_EN) != 0U) { - return 0; + LOG_ERR("start not possible with DMA enabled"); + return -EIO; } /* clear all transfer flags */ diff --git a/include/zephyr/drivers/dma.h b/include/zephyr/drivers/dma.h index 51ace1bec8e8..7f116ab4bb52 100644 --- a/include/zephyr/drivers/dma.h +++ b/include/zephyr/drivers/dma.h @@ -164,9 +164,11 @@ struct dma_block_config { }; /** The DMA callback event has occurred at the completion of a transfer list */ -#define DMA_STATUS_COMPLETE 0 +#define DMA_STATUS_COMPLETE 0 /** The DMA callback has occurred at the completion of a single transfer block in a transfer list */ -#define DMA_STATUS_BLOCK 1 +#define DMA_STATUS_BLOCK 1 +/** The DMA callback event has occurred at the half completion of a single transfer block */ +#define DMA_STATUS_HALF_COMPLETE 2 /** * @typedef dma_callback_t @@ -208,6 +210,8 @@ struct dma_config { * - others hardware specific */ uint32_t channel_direction : 3; + /** enable half completion callback when set to 1 */ + uint32_t half_complete_callback_en : 1; /** * Completion callback enable * @@ -249,7 +253,7 @@ struct dma_config { /** Cyclic transfer list, HW specific */ uint32_t cyclic : 1; - uint32_t _reserved : 3; + uint32_t _reserved : 2; /** Width of source data (in bytes) */ uint32_t source_data_size : 16; /** Width of destination data (in bytes) */ From a9fed9aa66a91e9a818749e96633c7b3621d5495 Mon Sep 17 00:00:00 2001 From: Gang He Date: Mon, 24 Nov 2025 13:45:01 +0800 Subject: [PATCH 1483/3659] dts: Add audio codec device tree info for sf32lb52x Add audio codec device tree information for sf32lb52x.dtsi Signed-off-by: Gang He --- dts/arm/sifli/sf32lb52x.dtsi | 7 +++++ dts/bindings/audio/sifli,sf32lb-audcodec.yaml | 28 +++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 dts/bindings/audio/sifli,sf32lb-audcodec.yaml diff --git a/dts/arm/sifli/sf32lb52x.dtsi b/dts/arm/sifli/sf32lb52x.dtsi index d568962346f1..44251630953a 100644 --- a/dts/arm/sifli/sf32lb52x.dtsi +++ b/dts/arm/sifli/sf32lb52x.dtsi @@ -203,6 +203,13 @@ status = "disabled"; }; + audcodec: audio-codec@50088000 { + compatible = "sifli,sf32lb-audcodec"; + reg = <0x50088000 0x400>; + clocks = <&rcc_clk SF32LB52X_CLOCK_AUDCODEC>; + status = "disabled"; + }; + tsen: tsen@50089000 { compatible = "sifli,sf32lb-tsen"; reg = <0x50089000 0x1000>; diff --git a/dts/bindings/audio/sifli,sf32lb-audcodec.yaml b/dts/bindings/audio/sifli,sf32lb-audcodec.yaml new file mode 100644 index 000000000000..033eb0ddce37 --- /dev/null +++ b/dts/bindings/audio/sifli,sf32lb-audcodec.yaml @@ -0,0 +1,28 @@ +# Copyright (c) 2025 Qingsong Gou +# SPDX-License-Identifier: Apache-2.0 + +description: | + Sifli SF32LB audio codec. + +compatible: "sifli,sf32lb-audcodec" + +include: [base.yaml, pinctrl-device.yaml] + +properties: + reg: + required: true + + clocks: + required: true + + dmas: + required: true + + dma-names: + required: true + + pa-power-gpios: + type: phandle-array + description: | + Power Amplifier (PA) enable GPIO. + required: true From cbe9396b505ce87ab6770bfb51c1d29b4b96c7f6 Mon Sep 17 00:00:00 2001 From: Gang He Date: Mon, 24 Nov 2025 13:50:13 +0800 Subject: [PATCH 1484/3659] include: zephyr: audio: Update audio codec interface Support audio device that has both input and output function. Signed-off-by: Gang He --- include/zephyr/audio/codec.h | 294 ++++++++++++++++++++++++++--------- 1 file changed, 220 insertions(+), 74 deletions(-) diff --git a/include/zephyr/audio/codec.h b/include/zephyr/audio/codec.h index 15000839fa63..429eaac0748e 100644 --- a/include/zephyr/audio/codec.h +++ b/include/zephyr/audio/codec.h @@ -19,7 +19,7 @@ * * @defgroup audio_codec_interface Audio Codec Interface * @since 1.13 - * @version 0.1.0 + * @version 0.2.0 * @ingroup audio_interface * @{ */ @@ -35,66 +35,67 @@ extern "C" { * PCM audio sample rates */ typedef enum { - AUDIO_PCM_RATE_8K = 8000, /**< 8 kHz sample rate */ - AUDIO_PCM_RATE_11P025K = 11025, /**< 11.025 kHz sample rate */ - AUDIO_PCM_RATE_16K = 16000, /**< 16 kHz sample rate */ - AUDIO_PCM_RATE_22P05K = 22050, /**< 22.05 kHz sample rate */ - AUDIO_PCM_RATE_24K = 24000, /**< 24 kHz sample rate */ - AUDIO_PCM_RATE_32K = 32000, /**< 32 kHz sample rate */ - AUDIO_PCM_RATE_44P1K = 44100, /**< 44.1 kHz sample rate */ - AUDIO_PCM_RATE_48K = 48000, /**< 48 kHz sample rate */ - AUDIO_PCM_RATE_96K = 96000, /**< 96 kHz sample rate */ - AUDIO_PCM_RATE_192K = 192000, /**< 192 kHz sample rate */ + AUDIO_PCM_RATE_8K = 8000, /**< 8 kHz sample rate */ + AUDIO_PCM_RATE_11P025K = 11025, /**< 11.025 kHz sample rate */ + AUDIO_PCM_RATE_16K = 16000, /**< 16 kHz sample rate */ + AUDIO_PCM_RATE_22P05K = 22050, /**< 22.05 kHz sample rate */ + AUDIO_PCM_RATE_24K = 24000, /**< 24 kHz sample rate */ + AUDIO_PCM_RATE_32K = 32000, /**< 32 kHz sample rate */ + AUDIO_PCM_RATE_44P1K = 44100, /**< 44.1 kHz sample rate */ + AUDIO_PCM_RATE_48K = 48000, /**< 48 kHz sample rate */ + AUDIO_PCM_RATE_96K = 96000, /**< 96 kHz sample rate */ + AUDIO_PCM_RATE_192K = 192000, /**< 192 kHz sample rate */ } audio_pcm_rate_t; /** * PCM audio sample bit widths */ typedef enum { - AUDIO_PCM_WIDTH_16_BITS = 16, /**< 16-bit sample width */ - AUDIO_PCM_WIDTH_20_BITS = 20, /**< 20-bit sample width */ - AUDIO_PCM_WIDTH_24_BITS = 24, /**< 24-bit sample width */ - AUDIO_PCM_WIDTH_32_BITS = 32, /**< 32-bit sample width */ + AUDIO_PCM_WIDTH_16_BITS = 16, /**< 16-bit sample width */ + AUDIO_PCM_WIDTH_20_BITS = 20, /**< 20-bit sample width */ + AUDIO_PCM_WIDTH_24_BITS = 24, /**< 24-bit sample width */ + AUDIO_PCM_WIDTH_32_BITS = 32, /**< 32-bit sample width */ } audio_pcm_width_t; /** * Digital Audio Interface (DAI) type */ typedef enum { - AUDIO_DAI_TYPE_I2S, /**< I2S Interface */ - AUDIO_DAI_TYPE_LEFT_JUSTIFIED, /**< I2S Interface, left justified */ - AUDIO_DAI_TYPE_RIGHT_JUSTIFIED, /**< I2S Interface, right justified */ - AUDIO_DAI_TYPE_PCMA, /**< PCM Interface, variant A */ - AUDIO_DAI_TYPE_PCMB, /**< PCM Interface, variant B */ - AUDIO_DAI_TYPE_INVALID, /**< Other interfaces can be added here */ + AUDIO_DAI_TYPE_I2S, /**< I2S Interface */ + AUDIO_DAI_TYPE_LEFT_JUSTIFIED, /**< I2S Interface, left justified */ + AUDIO_DAI_TYPE_RIGHT_JUSTIFIED, /**< I2S Interface, right justified */ + AUDIO_DAI_TYPE_PCMA, /**< PCM Interface, variant A */ + AUDIO_DAI_TYPE_PCMB, /**< PCM Interface, variant B */ + AUDIO_DAI_TYPE_PCM, /**< PCM Interface */ + AUDIO_DAI_TYPE_INVALID, /**< Other interfaces can be added here */ } audio_dai_type_t; /** * Codec properties that can be set by audio_codec_set_property(). */ typedef enum { - AUDIO_PROPERTY_OUTPUT_VOLUME, /**< Output volume */ - AUDIO_PROPERTY_OUTPUT_MUTE, /**< Output mute/unmute */ - AUDIO_PROPERTY_INPUT_VOLUME, /**< Input volume */ - AUDIO_PROPERTY_INPUT_MUTE /**< Input mute/unmute */ + AUDIO_PROPERTY_OUTPUT_VOLUME, /**< Output volume */ + AUDIO_PROPERTY_OUTPUT_MUTE, /**< Output mute/unmute */ + AUDIO_PROPERTY_INPUT_VOLUME, /**< Input volume */ + AUDIO_PROPERTY_INPUT_MUTE /**< Input mute/unmute */ } audio_property_t; /** * Audio channel identifiers to use in audio_codec_set_property(). */ typedef enum { - AUDIO_CHANNEL_FRONT_LEFT, /**< Front left channel */ - AUDIO_CHANNEL_FRONT_RIGHT, /**< Front right channel */ - AUDIO_CHANNEL_LFE, /**< Low frequency effect channel */ - AUDIO_CHANNEL_FRONT_CENTER, /**< Front center channel */ - AUDIO_CHANNEL_REAR_LEFT, /**< Rear left channel */ - AUDIO_CHANNEL_REAR_RIGHT, /**< Rear right channel */ - AUDIO_CHANNEL_REAR_CENTER, /**< Rear center channel */ - AUDIO_CHANNEL_SIDE_LEFT, /**< Side left channel */ - AUDIO_CHANNEL_SIDE_RIGHT, /**< Side right channel */ - AUDIO_CHANNEL_HEADPHONE_LEFT, /**< Headphone left */ - AUDIO_CHANNEL_HEADPHONE_RIGHT, /**< Headphone right */ - AUDIO_CHANNEL_ALL, /**< All channels */ + AUDIO_CHANNEL_FRONT_LEFT, /**< Front left channel */ + AUDIO_CHANNEL_FRONT_RIGHT, /**< Front right channel */ + AUDIO_CHANNEL_LFE, /**< Low frequency effect channel */ + AUDIO_CHANNEL_FRONT_CENTER, /**< Front center channel */ + AUDIO_CHANNEL_REAR_LEFT, /**< Rear left channel */ + AUDIO_CHANNEL_REAR_RIGHT, /**< Rear right channel */ + AUDIO_CHANNEL_REAR_CENTER, /**< Rear center channel */ + AUDIO_CHANNEL_SIDE_LEFT, /**< Side left channel */ + AUDIO_CHANNEL_SIDE_RIGHT, /**< Side right channel */ + AUDIO_CHANNEL_HEADPHONE_LEFT, /**< Headphone left */ + AUDIO_CHANNEL_HEADPHONE_RIGHT, /**< Headphone right */ + AUDIO_CHANNEL_ALL, /**< All channels */ /** * Number of all common channel identifiers. @@ -113,14 +114,44 @@ typedef enum { AUDIO_CHANNEL_MAX = INT16_MAX } audio_channel_t; +/** + * DAI Direction Bitmap + */ +typedef uint8_t audio_dai_dir_t; +/** Transmit data */ +#define AUDIO_DAI_DIR_TX BIT(0) +/** Receive data */ +#define AUDIO_DAI_DIR_RX BIT(1) +/** Both receive and transmit data */ +#define AUDIO_DAI_DIR_TXRX (AUDIO_DAI_DIR_TX | AUDIO_DAI_DIR_RX) + +/** @struct pcm_config + * @brief PCM configuration options. + */ +struct pcm_config { + /** pcm direction */ + audio_dai_dir_t dir; + /** Number of bits representing one data word. */ + audio_pcm_width_t pcm_width; + /** Number of channels per frame. */ + uint8_t channels; + /** Size of one RX/TX memory block (buffer) in bytes, + * it should be a multiple of 4 for some DMA limits. + */ + size_t block_size; + /** pcm samplerate */ + audio_pcm_rate_t samplerate; +}; + /** * @brief Digital Audio Interface Configuration. * * Configuration is dependent on DAI type */ typedef union { - struct i2s_config i2s; /**< I2S configuration */ - /* Other DAI types go here */ + struct i2s_config i2s; /**< I2S configuration */ + struct pcm_config pcm; /**< PCM configuration */ + /* Other DAI types go here */ } audio_dai_cfg_t; /* @@ -137,18 +168,18 @@ typedef enum { * Codec configuration parameters */ struct audio_codec_cfg { - uint32_t mclk_freq; /**< MCLK input frequency in Hz */ - audio_dai_type_t dai_type; /**< Digital interface type */ - audio_dai_cfg_t dai_cfg; /**< DAI configuration info */ - audio_route_t dai_route; /**< Codec route type */ + uint32_t mclk_freq; /**< MCLK input frequency in Hz */ + audio_dai_type_t dai_type; /**< Digital interface type */ + audio_dai_cfg_t dai_cfg; /**< DAI configuration info */ + audio_route_t dai_route; /**< Codec route type */ }; /** * Codec property values */ typedef union { - int vol; /**< Volume level (codec-specific) */ - bool mute; /**< Mute if @a true, unmute if @a false */ + int vol; /**< Volume level (codec-specific) */ + bool mute; /**< Mute if @a true, unmute if @a false */ } audio_property_value_t; /** @@ -180,26 +211,49 @@ enum audio_codec_error_type { */ typedef void (*audio_codec_error_callback_t)(const struct device *dev, uint32_t errors); +/** + * @typedef audio_codec_tx_done_callback_t + * @brief Callback for one frame(block memory) size data transmitted + * + * @param dev Pointer to the codec device + * @param user_data Pointer to user data + */ +typedef void (*audio_codec_tx_done_callback_t)(const struct device *dev, void *user_data); + +/** + * @typedef audio_codec_rx_done_callback_t + * @brief Callback for coming one frame size data + * + * @param dev Pointer to the codec device + * @param buf Pointer to received data + * @param len received data size in bytes + * @param user_data Pointer to user data + */ +typedef void (*audio_codec_rx_done_callback_t)(const struct device *dev, uint8_t *buf, uint32_t len, + void *user_data); + /** * @cond INTERNAL_HIDDEN * * For internal use only, skip these in public documentation. */ struct audio_codec_api { - int (*configure)(const struct device *dev, - struct audio_codec_cfg *cfg); + int (*configure)(const struct device *dev, struct audio_codec_cfg *cfg); void (*start_output)(const struct device *dev); void (*stop_output)(const struct device *dev); - int (*set_property)(const struct device *dev, - audio_property_t property, - audio_channel_t channel, - audio_property_value_t val); + int (*set_property)(const struct device *dev, audio_property_t property, + audio_channel_t channel, audio_property_value_t val); int (*apply_properties)(const struct device *dev); int (*clear_errors)(const struct device *dev); - int (*register_error_callback)(const struct device *dev, - audio_codec_error_callback_t cb); + int (*register_error_callback)(const struct device *dev, audio_codec_error_callback_t cb); int (*route_input)(const struct device *dev, audio_channel_t channel, uint32_t input); int (*route_output)(const struct device *dev, audio_channel_t channel, uint32_t output); + int (*start)(const struct device *dev, audio_dai_dir_t dir); + int (*stop)(const struct device *dev, audio_dai_dir_t dir); + int (*write)(const struct device *dev, uint8_t *data, size_t data_size); + int (*register_done_callback)(const struct device *dev, + audio_codec_tx_done_callback_t tx_cb, void *tx_cb_user_data, + audio_codec_rx_done_callback_t rx_cb, void *rx_cb_user_data); }; /** * @endcond @@ -216,11 +270,9 @@ struct audio_codec_api { * * @return 0 on success, negative error code on failure */ -static inline int audio_codec_configure(const struct device *dev, - struct audio_codec_cfg *cfg) +static inline int audio_codec_configure(const struct device *dev, struct audio_codec_cfg *cfg) { - const struct audio_codec_api *api = - (const struct audio_codec_api *)dev->api; + const struct audio_codec_api *api = (const struct audio_codec_api *)dev->api; return api->configure(dev, cfg); } @@ -234,8 +286,7 @@ static inline int audio_codec_configure(const struct device *dev, */ static inline void audio_codec_start_output(const struct device *dev) { - const struct audio_codec_api *api = - (const struct audio_codec_api *)dev->api; + const struct audio_codec_api *api = (const struct audio_codec_api *)dev->api; api->start_output(dev); } @@ -249,8 +300,7 @@ static inline void audio_codec_start_output(const struct device *dev) */ static inline void audio_codec_stop_output(const struct device *dev) { - const struct audio_codec_api *api = - (const struct audio_codec_api *)dev->api; + const struct audio_codec_api *api = (const struct audio_codec_api *)dev->api; api->stop_output(dev); } @@ -267,13 +317,10 @@ static inline void audio_codec_stop_output(const struct device *dev) * * @return 0 on success, negative error code on failure */ -static inline int audio_codec_set_property(const struct device *dev, - audio_property_t property, - audio_channel_t channel, - audio_property_value_t val) +static inline int audio_codec_set_property(const struct device *dev, audio_property_t property, + audio_channel_t channel, audio_property_value_t val) { - const struct audio_codec_api *api = - (const struct audio_codec_api *)dev->api; + const struct audio_codec_api *api = (const struct audio_codec_api *)dev->api; return api->set_property(dev, property, channel, val); } @@ -291,8 +338,7 @@ static inline int audio_codec_set_property(const struct device *dev, */ static inline int audio_codec_apply_properties(const struct device *dev) { - const struct audio_codec_api *api = - (const struct audio_codec_api *)dev->api; + const struct audio_codec_api *api = (const struct audio_codec_api *)dev->api; return api->apply_properties(dev); } @@ -309,8 +355,7 @@ static inline int audio_codec_apply_properties(const struct device *dev) */ static inline int audio_codec_clear_errors(const struct device *dev) { - const struct audio_codec_api *api = - (const struct audio_codec_api *)dev->api; + const struct audio_codec_api *api = (const struct audio_codec_api *)dev->api; if (api->clear_errors == NULL) { return -ENOSYS; @@ -334,10 +379,9 @@ static inline int audio_codec_clear_errors(const struct device *dev) * @return 0 if successful, negative errno code if failure. */ static inline int audio_codec_register_error_callback(const struct device *dev, - audio_codec_error_callback_t cb) + audio_codec_error_callback_t cb) { - const struct audio_codec_api *api = - (const struct audio_codec_api *)dev->api; + const struct audio_codec_api *api = (const struct audio_codec_api *)dev->api; if (api->register_error_callback == NULL) { return -ENOSYS; @@ -396,6 +440,108 @@ static inline int audio_codec_route_output(const struct device *dev, audio_chann return api->route_output(dev, channel, output); } +/** + * @brief Set codec to start audio playback or capture + * + * Setup the audio codec device to start the audio playback or capture + * + * @param dev Pointer to the device structure for codec driver instance. + * @param dir device audio playback and capture selection. + * + * @return 0 if successful, negative errno code if failure. + */ +static inline int audio_codec_start(const struct device *dev, audio_dai_dir_t dir) +{ + const struct audio_codec_api *api = (const struct audio_codec_api *)dev->api; + + if (api->start == NULL) { + return -ENOSYS; + } + + return api->start(dev, dir); +} + +/** + * @brief Set codec to stop audio playback or capture. + * + * Setup the audio codec device to stop the audio playback or capture. + * + * @param dev Pointer to the device structure for codec driver instance. + * @param dir device audio playback and capture selection. + * + * @return 0 if successful, negative errno code if failure. + */ +static inline int audio_codec_stop(const struct device *dev, audio_dai_dir_t dir) +{ + const struct audio_codec_api *api = (const struct audio_codec_api *)dev->api; + + if (api->stop == NULL) { + return -ENOSYS; + } + + return api->stop(dev, dir); +} + +/** + * @brief write one block size data for audio playback. + * + * Write audio data to the device for audio playback without waiting for the data + * to be transmitted. This is a non-blocking API: the function returns as soon + * as the driver has accepted (or rejected) the buffer, not when the audio data + * has actually been played out. + * + * @param dev Pointer to the device structure for codec driver instance. + * @param data Pointer to data. + * @param data_size data size in bytes. + * + * @return 0 if successful, negative errno code if failure. + */ +static inline int audio_codec_write(const struct device *dev, uint8_t *data, size_t data_size) +{ + const struct audio_codec_api *api = (const struct audio_codec_api *)dev->api; + + if (api->write == NULL) { + return -ENOSYS; + } + + return api->write(dev, data, data_size); +} + +/** + * @brief Register a callback function for codec one frame data tx/rx done. + * + * The callback will be called from a DMA ISR (interrupt) context. + * Callbacks must therefore: + * - Be very short and avoid deep call stacks or large stack allocations, + * since the ISR stack is limited. + * - Do not sleep or block (do not wait on semaphores, mutexes, queues, etc.). + * - Only call APIs that are explicitly documented as IRQ/ISR-safe. + * - Avoid heavy processing or extensive logging; instead, defer such work + * to thread or workqueue context (for example, by submitting a work item). + * + * @param dev Pointer to the audio codec device + * @param tx_cb The function that should be called when an DMA frame transmitted + * @param tx_cb_user_data The user data that will be passed to tx_cb + * @param rx_cb The function that should be called when an DMA frame received + * @param rx_cb_user_data The user data that will be passed to rx_cb + * + * @return 0 if successful, negative errno code if failure. + */ +static inline int audio_codec_register_done_callback(const struct device *dev, + audio_codec_tx_done_callback_t tx_cb, + void *tx_cb_user_data, + audio_codec_rx_done_callback_t rx_cb, + void *rx_cb_user_data) +{ + const struct audio_codec_api *api = (const struct audio_codec_api *)dev->api; + + if (api->register_done_callback == NULL) { + return -ENOSYS; + } + + return api->register_done_callback(dev, tx_cb, tx_cb_user_data, rx_cb, rx_cb_user_data); +} + #ifdef __cplusplus } #endif From 817d1b7118b1d35684a90fc0bb22052c5a576117 Mon Sep 17 00:00:00 2001 From: Gang He Date: Sat, 1 Nov 2025 18:38:46 +0800 Subject: [PATCH 1485/3659] drivers: audio: sf32lb52x: Add audio codec driver audio playback and capure, extend API in codec.h Signed-off-by: Gang He --- drivers/audio/CMakeLists.txt | 1 + drivers/audio/Kconfig | 1 + drivers/audio/Kconfig.sf32lb | 8 + drivers/audio/sf32lb_codec.c | 1474 ++++++++++++++++++++++++++++++++++ 4 files changed, 1484 insertions(+) create mode 100644 drivers/audio/Kconfig.sf32lb create mode 100644 drivers/audio/sf32lb_codec.c diff --git a/drivers/audio/CMakeLists.txt b/drivers/audio/CMakeLists.txt index 43efe180520c..a713b1bb947b 100644 --- a/drivers/audio/CMakeLists.txt +++ b/drivers/audio/CMakeLists.txt @@ -7,6 +7,7 @@ zephyr_library_sources_ifdef(CONFIG_AUDIO_CODEC_CS43L22 cs43l22.c) zephyr_library_sources_ifdef(CONFIG_AUDIO_CODEC_DA7212 da7212.c) zephyr_library_sources_ifdef(CONFIG_AUDIO_CODEC_MAX98091 max98091.c) zephyr_library_sources_ifdef(CONFIG_AUDIO_CODEC_PCM1681 pcm1681.c) +zephyr_library_sources_ifdef(CONFIG_AUDIO_CODEC_SF32LB sf32lb_codec.c) zephyr_library_sources_ifdef(CONFIG_AUDIO_CODEC_SHELL codec_shell.c) zephyr_library_sources_ifdef(CONFIG_AUDIO_CODEC_WM8904 wm8904.c) zephyr_library_sources_ifdef(CONFIG_AUDIO_CODEC_WM8962 wm8962.c) diff --git a/drivers/audio/Kconfig b/drivers/audio/Kconfig index b2821b861b56..e4cd7ab7bf1d 100644 --- a/drivers/audio/Kconfig +++ b/drivers/audio/Kconfig @@ -40,6 +40,7 @@ source "drivers/audio/Kconfig.cs43l22" source "drivers/audio/Kconfig.da7212" source "drivers/audio/Kconfig.max98091" source "drivers/audio/Kconfig.pcm1681" +source "drivers/audio/Kconfig.sf32lb" source "drivers/audio/Kconfig.tas6422dac" source "drivers/audio/Kconfig.tlv320aic3110" source "drivers/audio/Kconfig.tlv320dac" diff --git a/drivers/audio/Kconfig.sf32lb b/drivers/audio/Kconfig.sf32lb new file mode 100644 index 000000000000..37aaaba88ad3 --- /dev/null +++ b/drivers/audio/Kconfig.sf32lb @@ -0,0 +1,8 @@ +# Copyright (c) 2025 SiFli Technologies(Nanjing) Co., Ltd +# SPDX-License-Identifier: Apache-2.0 + +config AUDIO_CODEC_SF32LB + bool "sf32lb audio codec" + select DMA + default y + depends on DT_HAS_SIFLI_SF32LB_AUDCODEC_ENABLED diff --git a/drivers/audio/sf32lb_codec.c b/drivers/audio/sf32lb_codec.c new file mode 100644 index 000000000000..72dd5d56a1d7 --- /dev/null +++ b/drivers/audio/sf32lb_codec.c @@ -0,0 +1,1474 @@ +/* + * Copyright (c) 2025 SiFli Technologies(Nanjing) Co., Ltd + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT sifli_sf32lb_audcodec + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +LOG_MODULE_REGISTER(sifli_codec, CONFIG_AUDIO_CODEC_LOG_LEVEL); + +#define PMUC_HXT_CR1 offsetof(PMUC_TypeDef, HXT_CR1) + +#define CODEC_ID offsetof(AUDCODEC_TypeDef, ID) +#define CODEC_CFG offsetof(AUDCODEC_TypeDef, CFG) +#define CODEC_IRQ offsetof(AUDCODEC_TypeDef, IRQ) +#define CODEC_IRQ_MSK offsetof(AUDCODEC_TypeDef, IRQ_MSK) +#define CODEC_DAC_CFG offsetof(AUDCODEC_TypeDef, DAC_CFG) +#define CODEC_ADC_CFG offsetof(AUDCODEC_TypeDef, ADC_CFG) +#define CODEC_APB_STAT offsetof(AUDCODEC_TypeDef, APB_STAT) +#define CODEC_RSVD5 offsetof(AUDCODEC_TypeDef, RSVD5) +#define CODEC_ADC_CH0_CFG offsetof(AUDCODEC_TypeDef, ADC_CH0_CFG) +#define CODEC_ADC_CH1_CFG offsetof(AUDCODEC_TypeDef, ADC_CH1_CFG) +#define CODEC_DAC_CH0_CFG offsetof(AUDCODEC_TypeDef, DAC_CH0_CFG) +#define CODEC_DAC_CH0_CFG_EXT offsetof(AUDCODEC_TypeDef, DAC_CH0_CFG_EXT) +#define CODEC_DAC_CH1_CFG offsetof(AUDCODEC_TypeDef, DAC_CH1_CFG) +#define CODEC_DAC_CH1_CFG_EXT offsetof(AUDCODEC_TypeDef, DAC_CH1_CFG_EXT) +#define CODEC_ADC_CH0_ENTRY offsetof(AUDCODEC_TypeDef, ADC_CH0_ENTRY) +#define CODEC_ADC_CH1_ENTRY offsetof(AUDCODEC_TypeDef, ADC_CH1_ENTRY) +#define CODEC_DAC_CH0_ENTRY offsetof(AUDCODEC_TypeDef, DAC_CH0_ENTRY) +#define CODEC_DAC_CH1_ENTRY offsetof(AUDCODEC_TypeDef, DAC_CH1_ENTRY) +#define CODEC_DAC_CH0_DEBUG offsetof(AUDCODEC_TypeDef, DAC_CH0_DEBUG) +#define CODEC_DAC_CH1_DEBUG offsetof(AUDCODEC_TypeDef, DAC_CH1_DEBUG) +#define CODEC_DAC_CH0_DC offsetof(AUDCODEC_TypeDef, DAC_CH0_DC) +#define CODEC_DAC_CH1_DC offsetof(AUDCODEC_TypeDef, DAC_CH1_DC) +#define CODEC_COMMON_CFG offsetof(AUDCODEC_TypeDef, COMMON_CFG) +#define CODEC_BG_CFG0 offsetof(AUDCODEC_TypeDef, BG_CFG0) +#define CODEC_BG_CFG1 offsetof(AUDCODEC_TypeDef, BG_CFG1) +#define CODEC_BG_CFG2 offsetof(AUDCODEC_TypeDef, BG_CFG2) +#define CODEC_REFGEN_CFG offsetof(AUDCODEC_TypeDef, REFGEN_CFG) +#define CODEC_PLL_CFG0 offsetof(AUDCODEC_TypeDef, PLL_CFG0) +#define CODEC_PLL_CFG1 offsetof(AUDCODEC_TypeDef, PLL_CFG1) +#define CODEC_PLL_CFG2 offsetof(AUDCODEC_TypeDef, PLL_CFG2) +#define CODEC_PLL_CFG3 offsetof(AUDCODEC_TypeDef, PLL_CFG3) +#define CODEC_PLL_CFG4 offsetof(AUDCODEC_TypeDef, PLL_CFG4) +#define CODEC_PLL_CFG5 offsetof(AUDCODEC_TypeDef, PLL_CFG5) +#define CODEC_PLL_CFG6 offsetof(AUDCODEC_TypeDef, PLL_CFG6) +#define CODEC_PLL_STAT offsetof(AUDCODEC_TypeDef, PLL_STAT) +#define CODEC_PLL_CAL_CFG offsetof(AUDCODEC_TypeDef, PLL_CAL_CFG) +#define CODEC_PLL_CAL_RESULT offsetof(AUDCODEC_TypeDef, PLL_CAL_RESULT) +#define CODEC_ADC_ANA_CFG offsetof(AUDCODEC_TypeDef, ADC_ANA_CFG) +#define CODEC_ADC1_CFG1 offsetof(AUDCODEC_TypeDef, ADC1_CFG1) +#define CODEC_ADC1_CFG2 offsetof(AUDCODEC_TypeDef, ADC1_CFG2) +#define CODEC_ADC2_CFG1 offsetof(AUDCODEC_TypeDef, ADC2_CFG1) +#define CODEC_ADC2_CFG2 offsetof(AUDCODEC_TypeDef, ADC2_CFG2) +#define CODEC_DAC1_CFG offsetof(AUDCODEC_TypeDef, DAC1_CFG) +#define CODEC_DAC2_CFG offsetof(AUDCODEC_TypeDef, DAC2_CFG) + +#define CODEC_CLK_USING_PLL 0 +#define AUDCODEC_MIN_VOLUME -36 +#define AUDCODEC_MAX_VOLUME 54 + +/** some register read/write need delay some time, based on the chip's IP manual. + * no exact time, generally, it asks for at least how much. + */ +#define WAIT_PLL_STABLE_US 100 +#define WAIT_VCM_STABLE_US 5 +#define WAIT_AMP_STABLE_US 1 +#define WAIT_DAC_STABLE_US 10 +#define WAIT_MICBIAS_STABLE_US 2000 +#define WAIT_RESET_LOW_TO_HIGH_US 1000 + +/* hardware gain of volume, The maximum gain should be tested + * to prevent the speaker from burning out. + */ +#define VOLUME_0_GAIN -55 +#define VOLUME_1_GAIN -34 +#define VOLUME_2_GAIN -32 +#define VOLUME_3_GAIN -30 +#define VOLUME_4_GAIN -28 +#define VOLUME_5_GAIN -26 +#define VOLUME_6_GAIN -24 +#define VOLUME_7_GAIN -22 +#define VOLUME_8_GAIN -20 +#define VOLUME_9_GAIN -17 +#define VOLUME_10_GAIN -14 +#define VOLUME_11_GAIN -11 +#define VOLUME_12_GAIN -10 +#define VOLUME_13_GAIN -8 +#define VOLUME_14_GAIN -6 +#define VOLUME_15_GAIN -2 + +/** Wait time in us before codec state become stable */ +#define CODEC_STABLE_WAIT_US 10 + +enum audio_pll_state { + AUDIO_PLL_CLOSED, + AUDIO_PLL_OPEN, + AUDIO_PLL_ENABLE, +}; + +struct sf32lb_codec_dac_clk { + uint32_t samplerate; + uint8_t clk_src_sel; /* 0:xtal 48M 1:PLL 44.1M */ + uint8_t clk_div; + uint8_t osr_sel; /* 0:100 1:150 2:300 4:64 5:128 6:256 */ + uint16_t sinc_gain; + uint8_t sel_clk_dac_source; /* 0:xtal 48M 1:PLL */ + uint8_t diva_clk_dac; + uint8_t diva_clk_chop_dac; + uint8_t divb_clk_chop_dac; + uint8_t diva_clk_chop_bg; + uint8_t diva_clk_chop_refgen; + uint8_t sel_clk_dac; +}; + +struct sf32lb_codec_adc_clk { + uint32_t samplerate; + uint8_t clk_src_sel; /*0:xtal 48M 1:PLL 44.1M */ + uint8_t clk_div; + uint8_t osr_sel; /* 0:200 1:300 2:400 3:600 */ + uint8_t sel_clk_adc_source; /* 0:xtal 48M 1:PLL */ + uint8_t sel_clk_adc; + uint8_t diva_clk_adc; /* lp pll_cfg6 */ + uint8_t fsp; +}; + +struct sf32lb_codec_dac_cfg { + uint8_t opmode; /* 0:audprc tx to audcode; 1: mem tx to audcodec */ + const struct sf32lb_codec_dac_clk *dac_clk; +}; + +struct sf32lb_codec_adc_cfg { + uint8_t opmode; + const struct sf32lb_codec_adc_clk *adc_clk; +}; + +struct sf32lb_codec_hw_config { + uint16_t en_dly_sel; /* codec enable delay count */ + uint8_t samplerate_index; + struct sf32lb_codec_dac_cfg dac_cfg; /* dac AUDCODEC DAC PATH configure */ + struct sf32lb_codec_adc_cfg adc_cfg; /* dac AUDCODEC ADC PATH configure */ +}; + +struct sf32lb_audcodec_data { + struct k_spinlock lock; + struct sf32lb_codec_hw_config hw_config; + audio_codec_tx_done_callback_t tx_done; + audio_codec_rx_done_callback_t rx_done; + void *tx_cb_user_data; + void *rx_cb_user_data; + uint8_t *tx_buf; + uint8_t *tx_write_ptr; + uint8_t *rx_buf; + uint32_t tx_half_dma_size; + uint32_t rx_half_dma_size; + uint8_t tx_enable; + uint8_t rx_enable; + uint8_t last_volume; + enum audio_pll_state pll_state; + uint32_t pll_samplerate; + int fine_vol_0; + const struct device *dev; +}; + +struct sf32lb_codec_driver_config { + uintptr_t reg; + struct sf32lb_dma_dt_spec dma_tx; + struct sf32lb_dma_dt_spec dma_rx; + struct sf32lb_clock_dt_spec clock; + struct gpio_dt_spec pa_power_dt; +}; + +static const int hardware_gain_of_volume[16] = { + VOLUME_0_GAIN, VOLUME_1_GAIN, VOLUME_2_GAIN, VOLUME_3_GAIN, + VOLUME_4_GAIN, VOLUME_5_GAIN, VOLUME_6_GAIN, VOLUME_7_GAIN, + VOLUME_8_GAIN, VOLUME_9_GAIN, VOLUME_10_GAIN, VOLUME_11_GAIN, + VOLUME_12_GAIN, VOLUME_13_GAIN, VOLUME_14_GAIN, VOLUME_15_GAIN}; + +/* DAC digital sinc filter gain compensation factor. + * Value 0x14D (333 decimal) comes from the AUDCODEC IP reference + * configuration. Do not modify without revalidating audio levels + * against the codec datasheet / characterization results. + */ +#define SINC_GAIN 0x14D + +static const struct sf32lb_codec_dac_clk codec_dac_clk_config[9] = { +#if CODEC_CLK_USING_PLL + {48000, 1, 1, 0, SINC_GAIN, 1, 5, 4, 2, 20, 20, 0}, + {32000, 1, 1, 1, SINC_GAIN, 1, 5, 4, 2, 20, 20, 0}, + {24000, 1, 1, 5, SINC_GAIN, 1, 10, 2, 2, 10, 10, 1}, + {16000, 1, 1, 4, SINC_GAIN, 1, 5, 4, 2, 20, 20, 0}, + {12000, 1, 1, 7, SINC_GAIN, 1, 20, 2, 1, 5, 5, 1}, + {8000, 1, 1, 8, SINC_GAIN, 1, 10, 2, 2, 10, 10, 1}, +#else + {48000, 0, 1, 0, SINC_GAIN, 0, 5, 4, 2, 20, 20, 0}, + {32000, 0, 1, 1, SINC_GAIN, 0, 5, 4, 2, 20, 20, 0}, + {24000, 0, 1, 5, SINC_GAIN, 0, 10, 2, 2, 10, 10, 1}, + {16000, 0, 1, 4, SINC_GAIN, 0, 5, 4, 2, 20, 20, 0}, + {12000, 0, 1, 7, SINC_GAIN, 0, 20, 2, 1, 5, 5, 1}, + {8000, 0, 1, 8, SINC_GAIN, 0, 10, 2, 2, 10, 10, 1}, +#endif + {44100, 1, 1, 0, SINC_GAIN, 1, 5, 4, 2, 20, 20, 0}, + {22050, 1, 1, 5, SINC_GAIN, 1, 10, 2, 2, 10, 10, 1}, + {11025, 1, 1, 7, SINC_GAIN, 1, 20, 2, 1, 5, 5, 1}, +}; + +const struct sf32lb_codec_adc_clk codec_adc_clk_config[9] = { +#if CODEC_CLK_USING_PLL + {48000, 1, 5, 0, 1, 1, 5, 0}, {32000, 1, 5, 1, 1, 1, 5, 0}, {24000, 1, 10, 0, 1, 0, 5, 2}, + {16000, 1, 10, 1, 1, 0, 5, 2}, {12000, 1, 10, 2, 1, 0, 5, 2}, {8000, 1, 10, 3, 1, 0, 5, 2}, +#else + {48000, 0, 5, 0, 0, 1, 5, 0}, {32000, 0, 5, 1, 0, 1, 5, 0}, {24000, 0, 10, 0, 0, 0, 5, 2}, + {16000, 0, 10, 1, 0, 0, 5, 2}, {12000, 0, 10, 2, 0, 0, 5, 2}, {8000, 0, 10, 3, 0, 0, 5, 2}, +#endif + {44100, 1, 5, 0, 1, 1, 5, 1}, {22050, 1, 5, 2, 1, 1, 5, 1}, {11025, 1, 10, 2, 1, 0, 5, 3}, +}; + +struct pll_vco { + uint32_t freq; + uint32_t vco_value; + uint32_t target_cnt; +}; + +struct pll_vco g_pll_vco_tab[2] = { + {48, 0, 2001}, + {44, 0, 1834}, +}; + +static void pmu_enable_audio(int enable) +{ + if (enable) { + sys_set_bit(PMUC_BASE + PMUC_HXT_CR1, PMUC_HXT_CR1_BUF_AUD_EN_Pos); + } else { + sys_clear_bit(PMUC_BASE + PMUC_HXT_CR1, PMUC_HXT_CR1_BUF_AUD_EN_Pos); + } +} + +static int config_dac_path(uintptr_t reg, uint16_t bypass) +{ + uint32_t reg_val; + + if (bypass) { + sys_set_bit(reg + CODEC_DAC_CH0_CFG, AUDCODEC_DAC_CH0_CFG_DOUT_MUTE_Pos); + reg_val = FIELD_PREP(AUDCODEC_DAC_CH0_DEBUG_BYPASS_Msk, 1) | + FIELD_PREP(AUDCODEC_DAC_CH0_DEBUG_DATA_OUT_Msk, 0xFF); + sys_write32(reg_val, reg + CODEC_DAC_CH0_DEBUG); + + sys_set_bit(reg + CODEC_DAC_CH1_CFG, AUDCODEC_DAC_CH1_CFG_DOUT_MUTE_Pos); + reg_val = FIELD_PREP(AUDCODEC_DAC_CH1_DEBUG_BYPASS_Msk, 1) | + FIELD_PREP(AUDCODEC_DAC_CH1_DEBUG_DATA_OUT_Msk, 0xFF); + sys_write32(reg_val, reg + CODEC_DAC_CH1_DEBUG); + } else { + sys_clear_bit(reg + CODEC_DAC_CH0_CFG, AUDCODEC_DAC_CH0_CFG_DOUT_MUTE_Pos); + reg_val = FIELD_PREP(AUDCODEC_DAC_CH0_DEBUG_BYPASS_Msk, 0) | + FIELD_PREP(AUDCODEC_DAC_CH0_DEBUG_DATA_OUT_Msk, 0xFF); + sys_write32(reg_val, reg + CODEC_DAC_CH0_DEBUG); + + sys_clear_bit(reg + CODEC_DAC_CH1_CFG, AUDCODEC_DAC_CH1_CFG_DOUT_MUTE_Pos); + reg_val = FIELD_PREP(AUDCODEC_DAC_CH1_DEBUG_BYPASS_Msk, 0) | + FIELD_PREP(AUDCODEC_DAC_CH1_DEBUG_DATA_OUT_Msk, 0xFF); + sys_write32(reg_val, reg + CODEC_DAC_CH1_DEBUG); + } + + return 0; +} + +static void config_analog_dac_path(uintptr_t reg, const struct sf32lb_codec_dac_clk *clk) +{ + uint32_t reg_val; + + sys_clear_bits(reg + CODEC_PLL_CFG4, AUDCODEC_PLL_CFG4_SEL_CLK_DAC_Msk); + sys_clear_bits(reg + CODEC_PLL_CFG4, AUDCODEC_PLL_CFG4_SEL_CLK_DAC_SOURCE_Msk); + reg_val = sys_read32(reg + CODEC_PLL_CFG4); + reg_val &= ~(AUDCODEC_PLL_CFG4_EN_CLK_CHOP_DAC_Msk | AUDCODEC_PLL_CFG4_EN_CLK_DAC_Msk | + AUDCODEC_PLL_CFG4_SEL_CLK_DAC_SOURCE_Msk | AUDCODEC_PLL_CFG4_SEL_CLK_DAC_Msk | + AUDCODEC_PLL_CFG4_EN_CLK_DIG_Msk); + reg_val |= FIELD_PREP(AUDCODEC_PLL_CFG4_EN_CLK_CHOP_DAC_Msk, 1) | + FIELD_PREP(AUDCODEC_PLL_CFG4_EN_CLK_DAC_Msk, 1) | + FIELD_PREP(AUDCODEC_PLL_CFG4_SEL_CLK_DAC_SOURCE_Msk, clk->sel_clk_dac_source) | + FIELD_PREP(AUDCODEC_PLL_CFG4_SEL_CLK_DAC_Msk, clk->sel_clk_dac) | + FIELD_PREP(AUDCODEC_PLL_CFG4_EN_CLK_DIG_Msk, 1); + sys_write32(reg_val, reg + CODEC_PLL_CFG4); + + reg_val = sys_read32(reg + CODEC_PLL_CFG5); + reg_val &= + ~(AUDCODEC_PLL_CFG5_EN_CLK_CHOP_BG_Msk | AUDCODEC_PLL_CFG5_EN_CLK_CHOP_REFGEN_Msk); + reg_val |= FIELD_PREP(AUDCODEC_PLL_CFG5_EN_CLK_CHOP_BG_Msk, 1) | + FIELD_PREP(AUDCODEC_PLL_CFG5_EN_CLK_CHOP_REFGEN_Msk, 1); + sys_write32(reg_val, reg + CODEC_PLL_CFG5); + + sys_clear_bits(reg + CODEC_PLL_CFG2, AUDCODEC_PLL_CFG2_RSTB_Msk); + + /* wait for pll stable */ + k_busy_wait(WAIT_PLL_STABLE_US); + + sys_set_bit(reg + CODEC_PLL_CFG2, AUDCODEC_PLL_CFG2_RSTB_Pos); + sys_clear_bit(reg + CODEC_DAC1_CFG, AUDCODEC_DAC1_CFG_LP_MODE_Pos); + sys_clear_bits(reg + CODEC_DAC1_CFG, AUDCODEC_DAC1_CFG_EN_OS_DAC_Msk); + sys_clear_bits(reg + CODEC_DAC2_CFG, AUDCODEC_DAC2_CFG_EN_OS_DAC_Msk); + sys_set_bit(reg + CODEC_DAC1_CFG, AUDCODEC_DAC1_CFG_EN_VCM_Pos); + sys_clear_bit(reg + CODEC_DAC2_CFG, AUDCODEC_DAC2_CFG_EN_VCM_Pos); + /* wait for vcm stable */ + k_busy_wait(WAIT_VCM_STABLE_US); + + sys_set_bit(reg + CODEC_DAC1_CFG, AUDCODEC_DAC1_CFG_EN_AMP_Pos); + sys_clear_bits(reg + CODEC_DAC2_CFG, AUDCODEC_DAC2_CFG_EN_AMP_Msk); + /* wait amp stable*/ + k_busy_wait(WAIT_AMP_STABLE_US); + + sys_set_bit(reg + CODEC_DAC1_CFG, AUDCODEC_DAC1_CFG_EN_OS_DAC_Pos); + sys_set_bit(reg + CODEC_DAC2_CFG, AUDCODEC_DAC2_CFG_EN_OS_DAC_Pos); + k_busy_wait(WAIT_DAC_STABLE_US); + sys_set_bit(reg + CODEC_DAC1_CFG, AUDCODEC_DAC1_CFG_EN_DAC_Pos); + sys_clear_bits(reg + CODEC_DAC2_CFG, AUDCODEC_DAC2_CFG_EN_DAC_Msk); + k_busy_wait(WAIT_DAC_STABLE_US); + sys_clear_bits(reg + CODEC_DAC1_CFG, AUDCODEC_DAC1_CFG_SR_Msk); + sys_clear_bits(reg + CODEC_DAC2_CFG, AUDCODEC_DAC2_CFG_SR_Msk); +} + +static void config_analog_adc_path(uintptr_t reg, const struct sf32lb_codec_adc_clk *clk) +{ + uint32_t reg_val; + + sys_clear_bits(reg + CODEC_BG_CFG0, AUDCODEC_BG_CFG0_EN_SMPL_Msk); + sys_set_bit(reg + CODEC_ADC_ANA_CFG, AUDCODEC_ADC_ANA_CFG_MICBIAS_EN_Pos); + sys_clear_bits(reg + CODEC_ADC_ANA_CFG, AUDCODEC_ADC_ANA_CFG_MICBIAS_CHOP_EN_Msk); + /* delay 2ms*/ + k_busy_wait(WAIT_MICBIAS_STABLE_US); + + sys_clear_bits(reg + CODEC_BG_CFG0, AUDCODEC_BG_CFG0_EN_SMPL_Msk); /* noise pop */ + + /* adc1 and adc2 clock */ + reg_val = FIELD_PREP(AUDCODEC_PLL_CFG6_SEL_TST_CLK_Msk, 0) | + FIELD_PREP(AUDCODEC_PLL_CFG6_EN_TST_CLK_Msk, 0) | + FIELD_PREP(AUDCODEC_PLL_CFG6_EN_CLK_RCCAL_Msk, 0) | + FIELD_PREP(AUDCODEC_PLL_CFG6_SEL_CLK_CHOP_MICBIAS_Msk, 3) | + FIELD_PREP(AUDCODEC_PLL_CFG6_EN_CLK_CHOP_MICBIAS_Msk, 1) | + FIELD_PREP(AUDCODEC_PLL_CFG6_SEL_CLK_ADC2_Msk, clk->sel_clk_adc) | + FIELD_PREP(AUDCODEC_PLL_CFG6_DIVA_CLK_ADC2_Msk, clk->diva_clk_adc) | + FIELD_PREP(AUDCODEC_PLL_CFG6_EN_CLK_ADC2_Msk, 1) | + FIELD_PREP(AUDCODEC_PLL_CFG6_SEL_CLK_ADC1_Msk, clk->sel_clk_adc) | + FIELD_PREP(AUDCODEC_PLL_CFG6_DIVA_CLK_ADC1_Msk, clk->diva_clk_adc) | + FIELD_PREP(AUDCODEC_PLL_CFG6_EN_CLK_ADC1_Msk, 1) | + FIELD_PREP(AUDCODEC_PLL_CFG6_SEL_CLK_ADC0_Msk, 1) | + FIELD_PREP(AUDCODEC_PLL_CFG6_DIVA_CLK_ADC0_Msk, 5) | + FIELD_PREP(AUDCODEC_PLL_CFG6_EN_CLK_ADC0_Msk, 1) | + FIELD_PREP(AUDCODEC_PLL_CFG6_SEL_CLK_ADC_SOURCE_Msk, clk->sel_clk_adc_source); + sys_write32(reg_val, reg + CODEC_PLL_CFG6); + + sys_clear_bits(reg + CODEC_PLL_CFG2, AUDCODEC_PLL_CFG2_RSTB_Msk); + + k_busy_wait(WAIT_RESET_LOW_TO_HIGH_US); + + sys_set_bit(reg + CODEC_PLL_CFG2, AUDCODEC_PLL_CFG2_RSTB_Pos); + + sys_clear_bit(reg + CODEC_ADC1_CFG1, AUDCODEC_ADC1_CFG1_DIFF_EN_Pos); + + sys_clear_bit(reg + CODEC_ADC1_CFG1, AUDCODEC_ADC1_CFG1_DACN_EN_Pos); + + sys_clear_bit(reg + CODEC_ADC1_CFG1, AUDCODEC_ADC1_CFG1_FSP_Pos); + reg_val = sys_read32(reg + CODEC_ADC1_CFG1); + reg_val &= ~(AUDCODEC_ADC1_CFG1_FSP_Msk); + reg_val |= FIELD_PREP(AUDCODEC_ADC1_CFG1_FSP_Msk, clk->fsp); + sys_write32(reg_val, reg + CODEC_ADC1_CFG1); + + /* this make long mic startup pulse */ + sys_set_bit(reg + CODEC_ADC1_CFG1, AUDCODEC_ADC1_CFG1_VCMST_Pos); + sys_set_bit(reg + CODEC_ADC1_CFG2, AUDCODEC_ADC1_CFG2_CLEAR_Pos); + + sys_clear_bits(reg + CODEC_ADC1_CFG1, AUDCODEC_ADC1_CFG1_GC_Msk); + reg_val = sys_read32(reg + CODEC_ADC1_CFG1); + reg_val &= ~(AUDCODEC_ADC1_CFG1_GC_Msk); + reg_val |= FIELD_PREP(AUDCODEC_ADC1_CFG1_GC_Msk, 0x4); + sys_write32(reg_val, reg + CODEC_ADC1_CFG1); + + sys_set_bit(reg + CODEC_ADC1_CFG2, AUDCODEC_ADC1_CFG2_EN_Pos); + sys_clear_bits(reg + CODEC_ADC1_CFG2, AUDCODEC_ADC1_CFG2_RSTB_Msk); + + sys_clear_bits(reg + CODEC_ADC1_CFG1, AUDCODEC_ADC1_CFG1_VREF_SEL_Msk); + reg_val = sys_read32(reg + CODEC_ADC1_CFG1); + reg_val &= ~(AUDCODEC_ADC1_CFG1_VREF_SEL_Msk); + reg_val |= FIELD_PREP(AUDCODEC_ADC1_CFG1_VREF_SEL_Msk, 2); + sys_write32(reg_val, reg + CODEC_ADC1_CFG1); + + /* wait 20ms */ + k_sleep(K_MSEC(20)); + + sys_set_bit(reg + CODEC_ADC1_CFG2, AUDCODEC_ADC1_CFG2_RSTB_Pos); + sys_clear_bits(reg + CODEC_ADC1_CFG1, AUDCODEC_ADC1_CFG1_VCMST_Msk); + sys_clear_bits(reg + CODEC_ADC1_CFG2, AUDCODEC_ADC1_CFG2_CLEAR_Msk); +} + +static void config_tx_channel(uintptr_t reg, struct sf32lb_codec_dac_cfg *cfg) +{ + uint32_t reg_val; + const struct sf32lb_codec_dac_clk *dac_clk = cfg->dac_clk; + + reg_val = sys_read32(reg + CODEC_CFG); + reg_val &= ~AUDCODEC_CFG_ADC_EN_DLY_SEL_Msk; + reg_val |= FIELD_PREP(AUDCODEC_CFG_ADC_EN_DLY_SEL_Msk, 3); + sys_write32(reg_val, reg + CODEC_CFG); + + reg_val = FIELD_PREP(AUDCODEC_DAC_CFG_OSR_SEL_Msk, dac_clk->osr_sel) | + FIELD_PREP(AUDCODEC_DAC_CFG_OP_MODE_Msk, cfg->opmode) | + FIELD_PREP(AUDCODEC_DAC_CFG_PATH_RESET_Msk, 0) | + FIELD_PREP(AUDCODEC_DAC_CFG_CLK_SRC_SEL_Msk, dac_clk->clk_src_sel) | + FIELD_PREP(AUDCODEC_DAC_CFG_CLK_DIV_Msk, dac_clk->clk_div); + sys_write32(reg_val, reg + CODEC_DAC_CFG); + + reg_val = FIELD_PREP(AUDCODEC_DAC_CH0_CFG_ENABLE_Msk, 1) | + FIELD_PREP(AUDCODEC_DAC_CH0_CFG_DOUT_MUTE_Msk, 0) | + FIELD_PREP(AUDCODEC_DAC_CH0_CFG_DEM_MODE_Msk, 2) | + FIELD_PREP(AUDCODEC_DAC_CH0_CFG_DMA_EN_Msk, 0) | + FIELD_PREP(AUDCODEC_DAC_CH0_CFG_ROUGH_VOL_Msk, 6) | + FIELD_PREP(AUDCODEC_DAC_CH0_CFG_FINE_VOL_Msk, 0) | + FIELD_PREP(AUDCODEC_DAC_CH0_CFG_DATA_FORMAT_Msk, 1) | + FIELD_PREP(AUDCODEC_DAC_CH0_CFG_SINC_GAIN_Msk, dac_clk->sinc_gain) | + FIELD_PREP(AUDCODEC_DAC_CH0_CFG_DITHER_GAIN_Msk, 0) | + FIELD_PREP(AUDCODEC_DAC_CH0_CFG_DITHER_EN_Msk, 0) | + FIELD_PREP(AUDCODEC_DAC_CH0_CFG_CLK_ANA_POL_Msk, 0); + sys_write32(reg_val, reg + CODEC_DAC_CH0_CFG); + + reg_val = FIELD_PREP(AUDCODEC_DAC_CH0_CFG_EXT_RAMP_EN_Msk, 1) | + FIELD_PREP(AUDCODEC_DAC_CH0_CFG_EXT_RAMP_MODE_Msk, 1) | + FIELD_PREP(AUDCODEC_DAC_CH0_CFG_EXT_ZERO_ADJUST_EN_Msk, 1) | + FIELD_PREP(AUDCODEC_DAC_CH0_CFG_EXT_RAMP_INTERVAL_Msk, 2) | + FIELD_PREP(AUDCODEC_DAC_CH0_CFG_EXT_RAMP_STAT_Msk, 0); + + sys_write32(reg_val, reg + CODEC_DAC_CH0_CFG_EXT); + + reg_val = FIELD_PREP(AUDCODEC_DAC_CH0_DEBUG_BYPASS_Msk, 0) | + FIELD_PREP(AUDCODEC_DAC_CH0_DEBUG_DATA_OUT_Msk, 0xFF); + sys_write32(reg_val, reg + CODEC_DAC_CH0_DEBUG); +} + +static inline void close_analog_adc_path(uintptr_t reg) +{ + sys_clear_bits(reg + CODEC_ADC1_CFG2, AUDCODEC_ADC1_CFG2_EN_Msk); + sys_clear_bits(reg + CODEC_ADC2_CFG2, AUDCODEC_ADC2_CFG2_EN_Msk); + sys_clear_bits(reg + CODEC_ADC_ANA_CFG, AUDCODEC_ADC_ANA_CFG_MICBIAS_EN_Msk); +} + +static inline void close_analog_dac_path(uintptr_t reg) +{ + sys_set_bit(reg + CODEC_DAC1_CFG, AUDCODEC_DAC1_CFG_SR_Pos); + sys_set_bit(reg + CODEC_DAC2_CFG, AUDCODEC_DAC2_CFG_SR_Pos); + /*wait SR clear stable*/ + k_busy_wait(CODEC_STABLE_WAIT_US); + sys_clear_bits(reg + CODEC_DAC1_CFG, AUDCODEC_DAC1_CFG_EN_DAC_Msk); + sys_clear_bits(reg + CODEC_DAC2_CFG, AUDCODEC_DAC2_CFG_EN_DAC_Msk); + /*wait DAC clear stable*/ + k_busy_wait(CODEC_STABLE_WAIT_US); + sys_clear_bits(reg + CODEC_DAC1_CFG, AUDCODEC_DAC1_CFG_EN_VCM_Msk); + sys_clear_bits(reg + CODEC_DAC2_CFG, AUDCODEC_DAC2_CFG_EN_VCM_Msk); + /*wait AMP clear stable*/ + k_busy_wait(CODEC_STABLE_WAIT_US); + sys_clear_bits(reg + CODEC_DAC1_CFG, AUDCODEC_DAC1_CFG_EN_AMP_Msk); + sys_clear_bits(reg + CODEC_DAC2_CFG, AUDCODEC_DAC2_CFG_EN_AMP_Msk); + sys_clear_bits(reg + CODEC_DAC1_CFG, AUDCODEC_DAC1_CFG_EN_OS_DAC_Msk); + sys_clear_bits(reg + CODEC_DAC2_CFG, AUDCODEC_DAC2_CFG_EN_OS_DAC_Msk); +} + +static inline void clear_dac_channel(uintptr_t reg) +{ + sys_clear_bits(reg + CODEC_DAC_CH0_CFG, AUDCODEC_DAC_CH0_CFG_ENABLE_Msk); + sys_clear_bits(reg + CODEC_DAC_CH1_CFG, AUDCODEC_DAC_CH1_CFG_ENABLE_Msk); + sys_set_bit(reg + CODEC_DAC_CFG, AUDCODEC_DAC_CFG_PATH_RESET_Pos); + sys_clear_bits(reg + CODEC_DAC_CFG, AUDCODEC_DAC_CFG_PATH_RESET_Msk); +} + +static inline void clear_adc_channel(uintptr_t reg) +{ + sys_clear_bits(reg + CODEC_ADC_CH0_CFG, AUDCODEC_ADC_CH0_CFG_ENABLE_Msk); + sys_clear_bits(reg + CODEC_ADC_CH1_CFG, AUDCODEC_ADC_CH1_CFG_ENABLE_Msk); + + sys_set_bit(reg + CODEC_ADC_CFG, AUDCODEC_ADC_CFG_PATH_RESET_Pos); + sys_clear_bits(reg + CODEC_ADC_CFG, AUDCODEC_ADC_CFG_PATH_RESET_Msk); +} + +static inline void disable_adc(uintptr_t reg) +{ + sys_clear_bit(reg + CODEC_CFG, AUDCODEC_CFG_ADC_ENABLE_Pos); +} + +static inline void disable_dac(uintptr_t reg) +{ + sys_clear_bit(reg + CODEC_CFG, AUDCODEC_CFG_DAC_ENABLE_Pos); +} + +static void config_dac_path_volume(uintptr_t reg, int volume) +{ + uint32_t reg_val; + uint32_t rough_vol, fine_vol; + + /** parameter volume is 1db unit + * datasheet of audio codec as following: + * dac fine volume control range from 0db to 6db, step is 0.5db. + * 0x0 0db + * 0x1 0.5db + * 0x2 1db + * ...... + * 0xb 5.5db + * 0xc mute + * ----------------------------------------------------------- + * dac rough volume contrl range from -36db to 54db, step is 6db. + * 0x0 -36db + * 0x1 -30db + * .... + * 0x6 0db + * 0x7 6db + * .... + * 0xe 48db + * 0xf 54db + */ + rough_vol = (volume - AUDCODEC_MIN_VOLUME) / 6; + fine_vol = (((volume - AUDCODEC_MIN_VOLUME) % 6) << 1); + + reg_val = sys_read32(reg + CODEC_DAC_CH0_CFG); + reg_val &= ~(AUDCODEC_DAC_CH0_CFG_ROUGH_VOL_Msk | AUDCODEC_DAC_CH0_CFG_FINE_VOL_Msk); + reg_val |= FIELD_PREP(AUDCODEC_DAC_CH0_CFG_ROUGH_VOL_Msk, rough_vol) | + FIELD_PREP(AUDCODEC_DAC_CH0_CFG_FINE_VOL_Msk, fine_vol); + sys_write32(reg_val, reg + CODEC_DAC_CH0_CFG); + + LOG_DBG("set volume rough:%d, fine:%d, cfg0:0x%x", rough_vol, fine_vol, + sys_read32(reg + CODEC_DAC_CH0_CFG)); +} + +static void mute_dac_path(const struct device *dev, uintptr_t reg, int mute) +{ + uint32_t reg_val; + struct sf32lb_audcodec_data *data = dev->data; + + if (mute) { + reg_val = sys_read32(reg + CODEC_DAC_CH0_CFG); + data->fine_vol_0 = FIELD_GET(AUDCODEC_DAC_CH0_CFG_FINE_VOL_Msk, reg_val); + reg_val &= ~AUDCODEC_DAC_CH0_CFG_FINE_VOL_Msk; + reg_val |= FIELD_PREP(AUDCODEC_DAC_CH0_CFG_FINE_VOL_Msk, 0xF); + sys_write32(reg_val, reg + CODEC_DAC_CH0_CFG); + } else { + reg_val = sys_read32(reg + CODEC_DAC_CH0_CFG); + reg_val &= ~AUDCODEC_DAC_CH0_CFG_FINE_VOL_Msk; + reg_val |= FIELD_PREP(AUDCODEC_DAC_CH0_CFG_FINE_VOL_Msk, data->fine_vol_0); + sys_write32(reg_val, reg + CODEC_DAC_CH0_CFG); + } +} + +static void config_rx_channel(uintptr_t reg, struct sf32lb_codec_adc_cfg *cfg) +{ + uint32_t reg_val; + const struct sf32lb_codec_adc_clk *adc_clk = cfg->adc_clk; + + reg_val = FIELD_PREP(AUDCODEC_ADC_CFG_OSR_SEL_Msk, adc_clk->osr_sel) | + FIELD_PREP(AUDCODEC_ADC_CFG_OP_MODE_Msk, cfg->opmode) | + FIELD_PREP(AUDCODEC_ADC_CFG_PATH_RESET_Msk, 0) | + FIELD_PREP(AUDCODEC_ADC_CFG_CLK_SRC_SEL_Msk, adc_clk->clk_src_sel) | + FIELD_PREP(AUDCODEC_ADC_CFG_CLK_DIV_Msk, adc_clk->clk_div); + sys_write32(reg_val, reg + CODEC_ADC_CFG); + + reg_val = FIELD_PREP(AUDCODEC_ADC_CH0_CFG_ENABLE_Msk, 1) | + FIELD_PREP(AUDCODEC_ADC_CH0_CFG_HPF_BYPASS_Msk, 0) | + FIELD_PREP(AUDCODEC_ADC_CH0_CFG_HPF_COEF_Msk, 0x7) | + FIELD_PREP(AUDCODEC_ADC_CH0_CFG_STB_INV_Msk, 0) | + FIELD_PREP(AUDCODEC_ADC_CH0_CFG_DMA_EN_Msk, 0) | + FIELD_PREP(AUDCODEC_ADC_CH0_CFG_ROUGH_VOL_Msk, 0xa) | + FIELD_PREP(AUDCODEC_ADC_CH0_CFG_FINE_VOL_Msk, 0) | + FIELD_PREP(AUDCODEC_ADC_CH0_CFG_DATA_FORMAT_Msk, 1); + sys_write32(reg_val, reg + CODEC_ADC_CH0_CFG); +} + +static inline void refgen_init(uintptr_t reg) +{ + sys_clear_bits(reg + CODEC_BG_CFG0, AUDCODEC_BG_CFG0_EN_SMPL_Msk); + sys_clear_bits(reg + CODEC_REFGEN_CFG, AUDCODEC_REFGEN_CFG_EN_CHOP_Msk); + sys_set_bit(reg + CODEC_REFGEN_CFG, AUDCODEC_REFGEN_CFG_EN_Pos); + sys_clear_bits(reg + CODEC_REFGEN_CFG, AUDCODEC_REFGEN_CFG_LV_MODE_Msk); + sys_set_bit(reg + CODEC_PLL_CFG5, AUDCODEC_PLL_CFG5_EN_CLK_CHOP_BG_Pos); + sys_set_bit(reg + CODEC_PLL_CFG5, AUDCODEC_PLL_CFG5_EN_CLK_CHOP_REFGEN_Pos); + + k_sleep(K_MSEC(2)); + + sys_clear_bits(reg + CODEC_BG_CFG0, AUDCODEC_BG_CFG0_EN_SMPL_Msk); +} + +static void pll_turn_off(uintptr_t reg) +{ + /* turn off pll */ + sys_clear_bits(reg + CODEC_PLL_CFG0, AUDCODEC_PLL_CFG0_EN_IARY_Msk); + sys_clear_bits(reg + CODEC_PLL_CFG0, AUDCODEC_PLL_CFG0_EN_VCO_Msk); + sys_clear_bits(reg + CODEC_PLL_CFG0, AUDCODEC_PLL_CFG0_EN_ANA_Msk); + sys_clear_bits(reg + CODEC_PLL_CFG2, AUDCODEC_PLL_CFG2_EN_DIG_Msk); + sys_clear_bits(reg + CODEC_PLL_CFG3, AUDCODEC_PLL_CFG3_EN_SDM_Msk); + sys_clear_bits(reg + CODEC_PLL_CFG4, AUDCODEC_PLL_CFG4_EN_CLK_DIG_Msk); + + /* turn off refgen */ + sys_clear_bits(reg + CODEC_REFGEN_CFG, AUDCODEC_REFGEN_CFG_EN_Msk); + + /* turn off bandgap */ + sys_write32(0, reg + CODEC_BG_CFG1); + sys_write32(0, reg + CODEC_BG_CFG2); + sys_clear_bits(reg + CODEC_BG_CFG0, AUDCODEC_BG_CFG0_EN_Msk); + sys_clear_bits(reg + CODEC_BG_CFG0, AUDCODEC_BG_CFG0_EN_SMPL_Msk); +} + +static void pll_turn_on(uintptr_t reg) +{ + uint32_t reg_val; + + /* turn on bandgap */ + reg_val = FIELD_PREP(AUDCODEC_BG_CFG0_EN_Msk, 1) | + FIELD_PREP(AUDCODEC_BG_CFG0_LP_MODE_Msk, 0) | + FIELD_PREP(AUDCODEC_BG_CFG0_VREF_SEL_Msk, 0xc) | /* 0xc: 3.3v 2:AVDD = 1.8V */ + FIELD_PREP(AUDCODEC_BG_CFG0_EN_SMPL_Msk, 0) | + FIELD_PREP(AUDCODEC_BG_CFG0_EN_RCFLT_Msk, 1) | + FIELD_PREP(AUDCODEC_BG_CFG0_MIC_VREF_SEL_Msk, 4) | + FIELD_PREP(AUDCODEC_BG_CFG0_EN_AMP_Msk, 1) | + FIELD_PREP(AUDCODEC_BG_CFG0_SET_VC_Msk, 0); + sys_write32(reg_val, reg + CODEC_BG_CFG0); + + /* avoid noise */ + sys_write32(0, reg + CODEC_BG_CFG1); /* 48000 */ + sys_write32(0, reg + CODEC_BG_CFG2); /* 48000000 */ + + /* wait BG CFG stable */ + k_busy_wait(100); + + sys_set_bit(reg + CODEC_PLL_CFG0, AUDCODEC_PLL_CFG0_EN_IARY_Pos); + sys_set_bit(reg + CODEC_PLL_CFG0, AUDCODEC_PLL_CFG0_EN_VCO_Pos); + sys_set_bit(reg + CODEC_PLL_CFG0, AUDCODEC_PLL_CFG0_EN_ANA_Pos); + + sys_clear_bits(reg + CODEC_PLL_CFG0, AUDCODEC_PLL_CFG0_ICP_SEL_Msk); + reg_val = sys_read32(reg + CODEC_PLL_CFG0); + reg_val &= ~(AUDCODEC_PLL_CFG0_ICP_SEL_Msk); + reg_val |= FIELD_PREP(AUDCODEC_PLL_CFG0_ICP_SEL_Msk, 8); + sys_write32(reg_val, reg + CODEC_PLL_CFG0); + + sys_set_bit(reg + CODEC_PLL_CFG2, AUDCODEC_PLL_CFG2_EN_DIG_Pos); + sys_set_bit(reg + CODEC_PLL_CFG3, AUDCODEC_PLL_CFG3_EN_SDM_Pos); + sys_set_bit(reg + CODEC_PLL_CFG4, AUDCODEC_PLL_CFG4_EN_CLK_DIG_Pos); + + reg_val = FIELD_PREP(AUDCODEC_PLL_CFG1_R3_SEL_Msk, 3) | + FIELD_PREP(AUDCODEC_PLL_CFG1_RZ_SEL_Msk, 1) | + FIELD_PREP(AUDCODEC_PLL_CFG1_C2_SEL_Msk, 3) | + FIELD_PREP(AUDCODEC_PLL_CFG1_CZ_SEL_Msk, 6) | + FIELD_PREP(AUDCODEC_PLL_CFG1_CSD_RST_Msk, 0) | + FIELD_PREP(AUDCODEC_PLL_CFG1_CSD_EN_Msk, 0); + sys_write32(reg_val, reg + CODEC_PLL_CFG1); + + /* wait CSD stable */ + k_busy_wait(50); + + refgen_init(reg); +} + +/* type 0: 16k 1024 series 1:44.1k 1024 series 2:16k 1000 series 3: 44.1k 1000 series */ +static int pll_update_freq(uintptr_t reg, uint8_t type) +{ + uint32_t reg_val = 0; + + sys_set_bit(reg + CODEC_PLL_CFG2, AUDCODEC_PLL_CFG2_RSTB_Pos); + /* wait reset stable */ + k_busy_wait(50); + + reg_val = sys_read32(reg + CODEC_PLL_CFG3); + + switch (type) { + case 0: + /* set pll to 49.152M [(fcw+3)+sdin/2^20]*6M */ + reg_val = FIELD_PREP(AUDCODEC_PLL_CFG3_SDIN_Msk, 201327) | + FIELD_PREP(AUDCODEC_PLL_CFG3_FCW_Msk, 5) | + FIELD_PREP(AUDCODEC_PLL_CFG3_SDM_UPDATE_Msk, 0) | + FIELD_PREP(AUDCODEC_PLL_CFG3_SDMIN_BYPASS_Msk, 1) | + FIELD_PREP(AUDCODEC_PLL_CFG3_SDM_MODE_Msk, 0) | + FIELD_PREP(AUDCODEC_PLL_CFG3_EN_SDM_DITHER_Msk, 0) | + FIELD_PREP(AUDCODEC_PLL_CFG3_SDM_DITHER_Msk, 0) | + FIELD_PREP(AUDCODEC_PLL_CFG3_EN_SDM_Msk, 1) | + FIELD_PREP(AUDCODEC_PLL_CFG3_SDMCLK_POL_Msk, 0); + break; + case 1: + /* set pll to 45.1584M */ + reg_val = FIELD_PREP(AUDCODEC_PLL_CFG3_SDIN_Msk, 551970) | + FIELD_PREP(AUDCODEC_PLL_CFG3_FCW_Msk, 4) | + FIELD_PREP(AUDCODEC_PLL_CFG3_SDM_UPDATE_Msk, 0) | + FIELD_PREP(AUDCODEC_PLL_CFG3_SDMIN_BYPASS_Msk, 1) | + FIELD_PREP(AUDCODEC_PLL_CFG3_SDM_MODE_Msk, 0) | + FIELD_PREP(AUDCODEC_PLL_CFG3_EN_SDM_DITHER_Msk, 0) | + FIELD_PREP(AUDCODEC_PLL_CFG3_SDM_DITHER_Msk, 0) | + FIELD_PREP(AUDCODEC_PLL_CFG3_EN_SDM_Msk, 1) | + FIELD_PREP(AUDCODEC_PLL_CFG3_SDMCLK_POL_Msk, 0); + break; + case 2: + /* set pll to 48M */ + reg_val = FIELD_PREP(AUDCODEC_PLL_CFG3_SDIN_Msk, 0) | + FIELD_PREP(AUDCODEC_PLL_CFG3_FCW_Msk, 5) | + FIELD_PREP(AUDCODEC_PLL_CFG3_SDM_UPDATE_Msk, 0) | + FIELD_PREP(AUDCODEC_PLL_CFG3_SDMIN_BYPASS_Msk, 1) | + FIELD_PREP(AUDCODEC_PLL_CFG3_SDM_MODE_Msk, 0) | + FIELD_PREP(AUDCODEC_PLL_CFG3_EN_SDM_DITHER_Msk, 0) | + FIELD_PREP(AUDCODEC_PLL_CFG3_SDM_DITHER_Msk, 0) | + FIELD_PREP(AUDCODEC_PLL_CFG3_EN_SDM_Msk, 1) | + FIELD_PREP(AUDCODEC_PLL_CFG3_SDMCLK_POL_Msk, 0); + break; + case 3: + /* set pll to 44.1M */ + reg_val = FIELD_PREP(AUDCODEC_PLL_CFG3_SDIN_Msk, 0x5999A) | + FIELD_PREP(AUDCODEC_PLL_CFG3_FCW_Msk, 4) | + FIELD_PREP(AUDCODEC_PLL_CFG3_SDM_UPDATE_Msk, 0) | + FIELD_PREP(AUDCODEC_PLL_CFG3_SDMIN_BYPASS_Msk, 1) | + FIELD_PREP(AUDCODEC_PLL_CFG3_SDM_MODE_Msk, 0) | + FIELD_PREP(AUDCODEC_PLL_CFG3_EN_SDM_DITHER_Msk, 0) | + FIELD_PREP(AUDCODEC_PLL_CFG3_SDM_DITHER_Msk, 0) | + FIELD_PREP(AUDCODEC_PLL_CFG3_EN_SDM_Msk, 1) | + FIELD_PREP(AUDCODEC_PLL_CFG3_SDMCLK_POL_Msk, 0); + break; + default: + __ASSERT(0, "Invalid audio PLL configuration index in sf32lb_codec"); + break; + } + sys_write32(reg_val, reg + CODEC_PLL_CFG3); + + sys_set_bit(reg + CODEC_PLL_CFG3, AUDCODEC_PLL_CFG3_SDM_UPDATE_Pos); + sys_clear_bits(reg + CODEC_PLL_CFG3, AUDCODEC_PLL_CFG3_SDMIN_BYPASS_Msk); + sys_clear_bits(reg + CODEC_PLL_CFG2, AUDCODEC_PLL_CFG2_RSTB_Msk); + + /* RSRB change from clear to set, must has enough delay */ + k_busy_wait(50); + + sys_set_bit(reg + CODEC_PLL_CFG2, AUDCODEC_PLL_CFG2_RSTB_Pos); + + /* check pll lock */ + k_busy_wait(50); + + sys_set_bit(reg + CODEC_PLL_CFG1, AUDCODEC_PLL_CFG1_CSD_EN_Pos); + sys_set_bit(reg + CODEC_PLL_CFG1, AUDCODEC_PLL_CFG1_CSD_RST_Pos); + + /* CSD change from set to clear, must has enough delay */ + k_busy_wait(50); + + sys_clear_bits(reg + CODEC_PLL_CFG1, AUDCODEC_PLL_CFG1_CSD_RST_Msk); + + int ret = 0; + + if (sys_test_bit(reg + CODEC_PLL_STAT, AUDCODEC_PLL_STAT_UNLOCK_Pos)) { + LOG_ERR("pll lock fail! freq_type:%d", type); + ret = -1; + } else { + LOG_DBG("pll lock! freq_type:%d", type); + sys_clear_bits(reg + CODEC_PLL_CFG1, AUDCODEC_PLL_CFG1_CSD_EN_Msk); + } + return ret; +} + +static inline void wait_pll_done(uintptr_t reg) +{ + while (!FIELD_GET(AUDCODEC_PLL_CAL_CFG_DONE_Msk, sys_read32(reg + CODEC_PLL_CAL_CFG))) { + } +} + +static inline void fix_pll_vco_table(struct pll_vco *vco, uint32_t delta_cnt, + uint32_t delta_cnt_min, uint32_t delta_cnt_max, + uint32_t fc_vco_min, uint32_t fc_vco_max, uint32_t fc_vco) +{ + if (delta_cnt_min <= delta_cnt && delta_cnt_min <= delta_cnt_max) { + vco->vco_value = fc_vco_min; + } else if (delta_cnt_max <= delta_cnt && delta_cnt_max <= delta_cnt_min) { + vco->vco_value = fc_vco_max; + } else { + vco->vco_value = fc_vco; + } +} + +static inline void adjust_pll_vco(uintptr_t reg, struct pll_vco *vco) +{ + uint32_t reg_val; + uint32_t pll_cnt = 0; + uint32_t xtal_cnt = 0; + uint32_t fc_vco = 16; + uint32_t fc_vco_min = 0; + uint32_t fc_vco_max = 0; + uint32_t delta_cnt = 0; + uint32_t delta_cnt_min = 0; + uint32_t delta_cnt_max = 0; + uint32_t delta_fc_vco = 8; + uint32_t target_cnt = vco->target_cnt; + + /* setup calibration and run + * target pll_cnt = ceil(46MHz/48MHz*2000)+1 = 1918 + * target difference between pll_cnt and + * xtal_cnt should be less than 1 + */ + while (delta_fc_vco != 0) { + sys_clear_bits(reg + CODEC_PLL_CFG0, AUDCODEC_PLL_CFG0_FC_VCO_Msk); + reg_val = sys_read32(reg + CODEC_PLL_CFG0); + reg_val &= ~(AUDCODEC_PLL_CFG0_FC_VCO_Msk); + reg_val |= FIELD_PREP(AUDCODEC_PLL_CFG0_FC_VCO_Msk, fc_vco); + sys_write32(reg_val, reg + CODEC_PLL_CFG0); + sys_set_bit(reg + CODEC_PLL_CAL_CFG, AUDCODEC_PLL_CAL_CFG_EN_Pos); + + wait_pll_done(reg); + + reg_val = sys_read32(reg + CODEC_PLL_CAL_RESULT); + pll_cnt = FIELD_GET(AUDCODEC_PLL_CAL_RESULT_PLL_CNT_Msk, reg_val); + + reg_val = sys_read32(reg + CODEC_PLL_CAL_RESULT); + xtal_cnt = FIELD_GET(AUDCODEC_PLL_CAL_RESULT_XTAL_CNT_Msk, reg_val); + + sys_clear_bits(reg + CODEC_PLL_CAL_CFG, AUDCODEC_PLL_CAL_CFG_EN_Msk); + + if (pll_cnt < target_cnt) { + fc_vco = fc_vco + delta_fc_vco; + delta_cnt = target_cnt - pll_cnt; + } else { + fc_vco = fc_vco - delta_fc_vco; + delta_cnt = pll_cnt - target_cnt; + } + + delta_fc_vco = delta_fc_vco >> 1; + } + + LOG_DBG("call par CFG1(%x)", sys_read32(reg + CODEC_PLL_CFG1)); + + if (fc_vco == 0) { + fc_vco_min = 0; + } else { + fc_vco_min = fc_vco - 1; + } + if (fc_vco == 31) { + fc_vco_max = fc_vco; + } else { + fc_vco_max = fc_vco + 1; + } + + sys_clear_bits(reg + CODEC_PLL_CFG0, AUDCODEC_PLL_CFG0_FC_VCO_Msk); + reg_val = sys_read32(reg + CODEC_PLL_CFG0); + reg_val &= ~(AUDCODEC_PLL_CFG0_FC_VCO_Msk); + reg_val |= FIELD_PREP(AUDCODEC_PLL_CFG0_FC_VCO_Msk, fc_vco_min); + sys_write32(reg_val, reg + CODEC_PLL_CFG0); + + sys_set_bit(reg + CODEC_PLL_CAL_CFG, AUDCODEC_PLL_CAL_CFG_EN_Pos); + + LOG_DBG("fc %d, xtal %d, pll %d", fc_vco, xtal_cnt, pll_cnt); + + wait_pll_done(reg); + + reg_val = sys_read32(reg + CODEC_PLL_CAL_RESULT); + pll_cnt = FIELD_GET(AUDCODEC_PLL_CAL_RESULT_PLL_CNT_Msk, reg_val); + + sys_clear_bits(reg + CODEC_PLL_CAL_CFG, AUDCODEC_PLL_CAL_CFG_EN_Msk); + + if (pll_cnt < target_cnt) { + delta_cnt_min = target_cnt - pll_cnt; + } else { + delta_cnt_min = pll_cnt - target_cnt; + } + + sys_clear_bits(reg + CODEC_PLL_CFG0, AUDCODEC_PLL_CFG0_FC_VCO_Msk); + reg_val = sys_read32(reg + CODEC_PLL_CFG0); + reg_val &= ~(AUDCODEC_PLL_CFG0_FC_VCO_Msk); + reg_val |= FIELD_PREP(AUDCODEC_PLL_CFG0_FC_VCO_Msk, fc_vco_max); + sys_write32(reg_val, reg + CODEC_PLL_CFG0); + sys_set_bit(reg + CODEC_PLL_CAL_CFG, AUDCODEC_PLL_CAL_CFG_EN_Pos); + + wait_pll_done(reg); + + reg_val = sys_read32(reg + CODEC_PLL_CAL_RESULT); + pll_cnt = FIELD_GET(AUDCODEC_PLL_CAL_RESULT_PLL_CNT_Msk, reg_val); + sys_clear_bits(reg + CODEC_PLL_CAL_CFG, AUDCODEC_PLL_CAL_CFG_EN_Msk); + + if (pll_cnt < target_cnt) { + delta_cnt_max = target_cnt - pll_cnt; + } else { + delta_cnt_max = pll_cnt - target_cnt; + } + + fix_pll_vco_table(vco, delta_cnt, delta_cnt_min, delta_cnt_max, fc_vco_min, fc_vco_max, + fc_vco); +} + +static void pll_calibration(uintptr_t reg) +{ + uint32_t reg_val; + + pll_turn_on(reg); + + /* VCO freq calibration */ + sys_set_bit(reg + CODEC_PLL_CFG0, AUDCODEC_PLL_CFG0_OPEN_Pos); + sys_set_bit(reg + CODEC_PLL_CFG2, AUDCODEC_PLL_CFG2_EN_LF_VCIN_Pos); + + reg_val = FIELD_PREP(AUDCODEC_PLL_CAL_CFG_EN_Msk, 0) | + FIELD_PREP(AUDCODEC_PLL_CAL_CFG_LEN_Msk, 2000); + sys_write32(reg_val, reg + CODEC_PLL_CAL_CFG); + + for (uint8_t i = 0; i < ARRAY_SIZE(g_pll_vco_tab); i++) { + adjust_pll_vco(reg, &g_pll_vco_tab[i]); + } + sys_clear_bits(reg + CODEC_PLL_CFG2, AUDCODEC_PLL_CFG2_EN_LF_VCIN_Msk); + sys_clear_bits(reg + CODEC_PLL_CFG0, AUDCODEC_PLL_CFG0_OPEN_Msk); + + pll_turn_off(reg); +} + +static int bf0_update_pll(uintptr_t reg, uint32_t freq, uint8_t type) +{ + uint32_t reg_val; + uint8_t freq_type; + uint8_t test_result; + uint8_t vco_index = 0; + + freq_type = type << 1; + if ((freq == 44100) || (freq == 22050) || (freq == 11025)) { + vco_index = 1; + freq_type += 1; + } + sys_clear_bits(reg + CODEC_PLL_CFG0, AUDCODEC_PLL_CFG0_FC_VCO_Msk); + reg_val = sys_read32(reg + CODEC_PLL_CFG0); + reg_val &= ~(AUDCODEC_PLL_CFG0_FC_VCO_Msk); + reg_val |= FIELD_PREP(AUDCODEC_PLL_CFG0_FC_VCO_Msk, g_pll_vco_tab[vco_index].vco_value); + sys_write32(reg_val, reg + CODEC_PLL_CFG0); + + LOG_DBG("new PLL_ENABLE vco:%d, freq_type:%d", g_pll_vco_tab[vco_index].vco_value, + freq_type); + do { + test_result = pll_update_freq(reg, freq_type); + } while (test_result != 0); + + return test_result; +} + +static int pll_enable(uintptr_t reg, uint32_t freq, uint8_t type) +{ + LOG_DBG("enable pll"); + pll_turn_on(reg); + return bf0_update_pll(reg, freq, type); +} + +static void bf0_audio_pll_config(const struct sf32lb_codec_driver_config *cfg, + struct sf32lb_audcodec_data *data, + const struct sf32lb_codec_adc_clk *adc_clk, + const struct sf32lb_codec_dac_clk *dac_clk, audio_dai_dir_t dir) +{ + if ((dir & AUDIO_DAI_DIR_TX)) { + if (dac_clk->clk_src_sel != 0) { /* pll */ + if (data->pll_state == AUDIO_PLL_CLOSED) { + pll_enable(cfg->reg, dac_clk->samplerate, 1); + data->pll_state = AUDIO_PLL_ENABLE; + data->pll_samplerate = dac_clk->samplerate; + } else { + bf0_update_pll(cfg->reg, dac_clk->samplerate, 1); + data->pll_state = AUDIO_PLL_ENABLE; + data->pll_samplerate = dac_clk->samplerate; + } + } else { /* xtal */ + if (data->pll_state == AUDIO_PLL_CLOSED) { + pll_turn_on(cfg->reg); + data->pll_state = AUDIO_PLL_OPEN; + } + } + } + if ((dir & AUDIO_DAI_DIR_RX)) { + if (adc_clk->clk_src_sel != 0) { /* pll */ + if (data->pll_state == AUDIO_PLL_CLOSED) { + pll_enable(cfg->reg, adc_clk->samplerate, 1); + data->pll_state = AUDIO_PLL_ENABLE; + data->pll_samplerate = adc_clk->samplerate; + } else { + bf0_update_pll(cfg->reg, adc_clk->samplerate, 1); + data->pll_state = AUDIO_PLL_ENABLE; + data->pll_samplerate = adc_clk->samplerate; + } + } else { /* xtal */ + if (data->pll_state == AUDIO_PLL_CLOSED) { + pll_turn_on(cfg->reg); + data->pll_state = AUDIO_PLL_OPEN; + } + } + } + LOG_DBG("pll config state:%d, samplerate:%d", data->pll_state, data->pll_samplerate); +} + +static void sf32lb_codec_set_dac_volume(const struct device *dev, uint8_t volume) +{ + struct sf32lb_audcodec_data *data = dev->data; + const struct sf32lb_codec_driver_config *cfg = dev->config; + + if (volume > 15) { + volume = 15; + } + + int gain = hardware_gain_of_volume[volume]; + + if (gain > AUDCODEC_MAX_VOLUME) { + gain = AUDCODEC_MAX_VOLUME; + } + if (gain < AUDCODEC_MIN_VOLUME) { + gain = AUDCODEC_MIN_VOLUME; + } + + config_dac_path_volume(cfg->reg, gain); + + data->last_volume = volume; +} + +static int codec_set_property(const struct device *dev, audio_property_t property, + audio_channel_t channel, audio_property_value_t val) +{ + int ret = 0; + const struct sf32lb_codec_driver_config *cfg = dev->config; + + switch (property) { + case AUDIO_PROPERTY_OUTPUT_MUTE: + mute_dac_path(dev, cfg->reg, val.mute); + break; + case AUDIO_PROPERTY_OUTPUT_VOLUME: + sf32lb_codec_set_dac_volume(dev, (uint8_t)val.vol); + break; + default: + ret = -ENOTSUP; + break; + } + + return ret; +} + +int codec_apply_properties(const struct device *dev) +{ + /* Properties are applied immediately in codec_set_property(), so nothing to do here. */ + (void)dev; + return 0; +} + +int codec_register_done_callback(const struct device *dev, audio_codec_tx_done_callback_t tx_cb, + void *tx_cb_user_data, audio_codec_rx_done_callback_t rx_cb, + void *rx_cb_user_data) +{ + struct sf32lb_audcodec_data *data = dev->data; + + data->tx_cb_user_data = tx_cb_user_data; + data->rx_cb_user_data = rx_cb_user_data; + data->tx_done = tx_cb; + data->rx_done = rx_cb; + + return 0; +} + +static int codec_write(const struct device *dev, uint8_t *data, size_t size) +{ + struct sf32lb_audcodec_data *dev_data = dev->data; + + if (!data || size > dev_data->tx_half_dma_size) { + return -EINVAL; + } + + K_SPINLOCK(&dev_data->lock) { + memcpy(dev_data->tx_write_ptr, data, size); + if (size < dev_data->tx_half_dma_size) { + memset(dev_data->tx_write_ptr + size, 0, dev_data->tx_half_dma_size - size); + } + } + return 0; +} + +static int codec_configure(const struct device *dev, struct audio_codec_cfg *cfg) +{ + struct sf32lb_audcodec_data *data = dev->data; + const struct sf32lb_codec_driver_config *sf32lb_cfg = dev->config; + struct sf32lb_codec_hw_config *hw_cfg = &data->hw_config; + struct pcm_config *pcm_cfg; + int r; + + if (cfg->dai_type != AUDIO_DAI_TYPE_PCM) { + LOG_ERR("dai_type must be AUDIO_DAI_TYPE_PCM"); + return -EINVAL; + } + + r = sf32lb_clock_control_on_dt(&sf32lb_cfg->clock); + if (r < 0) { + LOG_ERR("Clock required is not on"); + return r; + } + pcm_cfg = &cfg->dai_cfg.pcm; + + if ((pcm_cfg->dir & AUDIO_DAI_DIR_TX)) { + uint8_t i; + + for (i = 0; i < ARRAY_SIZE(codec_dac_clk_config); i++) { + if (pcm_cfg->samplerate == codec_dac_clk_config[i].samplerate) { + hw_cfg->samplerate_index = i; + hw_cfg->dac_cfg.dac_clk = &codec_dac_clk_config[i]; + break; + } + } + __ASSERT(i < ARRAY_SIZE(codec_dac_clk_config), "tx smprate error"); + + data->tx_half_dma_size = pcm_cfg->block_size; + if (!data->tx_buf) { + data->tx_buf = + k_aligned_alloc(sizeof(uint32_t), data->tx_half_dma_size * 2); + } + + if (!data->tx_buf) { + return -ENOMEM; + } + + memset(data->tx_buf, 0, data->tx_half_dma_size * 2); + sys_write32((uint32_t)data->tx_buf, (uintptr_t)&data->tx_write_ptr); + + hw_cfg->dac_cfg.opmode = 1; /* not work with audprc */ + config_tx_channel(sf32lb_cfg->reg, &hw_cfg->dac_cfg); + + LOG_DBG("tx samperate=%d", hw_cfg->dac_cfg.dac_clk->samplerate); + } + + if ((pcm_cfg->dir & AUDIO_DAI_DIR_RX)) { + uint8_t i; + + for (i = 0; i < ARRAY_SIZE(codec_adc_clk_config); i++) { + if (pcm_cfg->samplerate == codec_adc_clk_config[i].samplerate) { + hw_cfg->samplerate_index = i; + hw_cfg->adc_cfg.adc_clk = &codec_adc_clk_config[i]; + break; + } + } + __ASSERT(i < ARRAY_SIZE(codec_adc_clk_config), "rx smprate error"); + + data->rx_half_dma_size = pcm_cfg->block_size; + if (!data->rx_buf) { + data->rx_buf = + k_aligned_alloc(sizeof(uint32_t), data->rx_half_dma_size * 2); + } + + if (!data->rx_buf) { + return -ENOMEM; + } + memset(data->rx_buf, 0, data->rx_half_dma_size * 2); + + hw_cfg->adc_cfg.opmode = 1; /* not work with audprc */ + config_rx_channel(sf32lb_cfg->reg, &hw_cfg->adc_cfg); + + LOG_DBG("rx samperate=%d", hw_cfg->adc_cfg.adc_clk->samplerate); + } + + return r; +} + +void dma_tx_callback(const struct device *dev_dma, void *user_data, uint32_t channel, int status) +{ + struct sf32lb_audcodec_data *data = (struct sf32lb_audcodec_data *)user_data; + const struct device *dev = data->dev; + + if (status == DMA_STATUS_HALF_COMPLETE) { + /* half DMA finished, update pointer of DMA circle buffer for writing new data + */ + sys_write32((uint32_t)data->tx_buf, (uintptr_t)&data->tx_write_ptr); + + if (data->tx_done) { + data->tx_done(dev, data->tx_cb_user_data); + } + } else if (status == DMA_STATUS_COMPLETE) { + sys_write32((uint32_t)data->tx_buf + data->tx_half_dma_size, + (uintptr_t)&data->tx_write_ptr); + + if (data->tx_done) { + data->tx_done(dev, data->tx_cb_user_data); + } + } else { + LOG_ERR("dma tx err:%d", status); + } +} + +void dma_rx_callback(const struct device *dev_dma, void *user_data, uint32_t channel, int status) +{ + struct sf32lb_audcodec_data *data = (struct sf32lb_audcodec_data *)user_data; + const struct device *dev = data->dev; + + if (status == DMA_STATUS_COMPLETE) { + if (data->rx_done) { + data->rx_done(dev, data->rx_buf + data->rx_half_dma_size, + data->rx_half_dma_size, data->rx_cb_user_data); + } + } else if (status == DMA_STATUS_HALF_COMPLETE) { + if (data->rx_done) { + data->rx_done(dev, data->rx_buf, data->rx_half_dma_size, + data->rx_cb_user_data); + } + } else { + LOG_ERR("dma rx err:%d", status); + } +} + +static void pa_power_enable(const struct gpio_dt_spec *spec) +{ + /* configure PA power pin */ + (void)gpio_pin_configure_dt(spec, GPIO_OUTPUT_HIGH); + k_sleep(K_MSEC(10)); /* wait for PA power stable */ +} + +static void pa_power_disable(const struct gpio_dt_spec *spec) +{ + /* configure PA power pin */ + (void)gpio_pin_configure_dt(spec, GPIO_OUTPUT_LOW); + k_sleep(K_MSEC(10)); /* wait for PA power stable */ +} + +static int codec_start(const struct device *dev, audio_dai_dir_t dir) +{ + struct sf32lb_audcodec_data *data = dev->data; + const struct sf32lb_codec_driver_config *cfg = dev->config; + struct sf32lb_codec_hw_config *hw_cfg = &data->hw_config; + + bool start_rx = (!data->rx_enable && (dir & AUDIO_DAI_DIR_RX)); + bool start_tx = (!data->tx_enable && (dir & AUDIO_DAI_DIR_TX)); + + if (start_rx || start_tx) { + bf0_audio_pll_config(cfg, data, &codec_adc_clk_config[hw_cfg->samplerate_index], + &codec_dac_clk_config[hw_cfg->samplerate_index], dir); + } else { + LOG_ERR("start err"); + return -EIO; + } + + if (start_rx) { + LOG_DBG("codec start rx, blk=%d", data->rx_half_dma_size); + if (!data->rx_buf) { + LOG_ERR("must configure before start rx"); + return -EIO; + } + + if (sf32lb_dma_reload_dt(&cfg->dma_rx, (uintptr_t)(cfg->reg + CODEC_ADC_CH0_ENTRY), + (uintptr_t)data->rx_buf, data->rx_half_dma_size * 2) < 0) { + LOG_ERR("DMA Rx reload failed\n"); + return -EIO; + } + + if (sf32lb_dma_start_dt(&cfg->dma_rx) < 0) { + LOG_ERR("DMA Rx start failed\n"); + return -EIO; + } + + sys_set_bit(cfg->reg + CODEC_ADC_CH0_CFG, AUDCODEC_ADC_CH0_CFG_DMA_EN_Pos); + + config_analog_adc_path(cfg->reg, hw_cfg->adc_cfg.adc_clk); + } + + if (start_tx) { + LOG_DBG("codec start tx, blk=%d", data->tx_half_dma_size); + if (!data->tx_buf) { + LOG_ERR("must configure before start tx"); + return -EIO; + } + + if (sf32lb_dma_reload_dt(&cfg->dma_tx, (uintptr_t)data->tx_buf, + (uintptr_t)(cfg->reg + CODEC_DAC_CH0_ENTRY), + data->tx_half_dma_size * 2) < 0) { + LOG_ERR("DMA Tx reload failed\n"); + return -EIO; + } + + mute_dac_path(dev, cfg->reg, 1); + + if (sf32lb_dma_start_dt(&cfg->dma_tx) < 0) { + LOG_ERR("DMA Tx start failed\n"); + return -EIO; + } + + sys_set_bit(cfg->reg + CODEC_DAC_CH0_CFG, AUDCODEC_DAC_CH0_CFG_DMA_EN_Pos); + + config_dac_path(cfg->reg, 1); + config_analog_dac_path(cfg->reg, hw_cfg->dac_cfg.dac_clk); + config_dac_path(cfg->reg, 0); + } + + /* speech echo cancellation algorithm requires a fixed delay time between ADC and DAC, + * enable at last. + */ + if (start_tx) { + data->tx_enable = 1; + sys_set_bit(cfg->reg + CODEC_CFG, AUDCODEC_CFG_DAC_ENABLE_Pos); + + pa_power_enable(&cfg->pa_power_dt); + mute_dac_path(dev, cfg->reg, 0); + } + + if (start_rx) { + data->rx_enable = 1; + sys_set_bit(cfg->reg + CODEC_CFG, AUDCODEC_CFG_ADC_ENABLE_Pos); + } + + return 0; +} + +static int codec_stop(const struct device *dev, audio_dai_dir_t dir) +{ + struct sf32lb_audcodec_data *data = dev->data; + const struct sf32lb_codec_driver_config *cfg = dev->config; + bool stop_rx = (data->rx_enable && (dir & AUDIO_DAI_DIR_RX)); + bool stop_tx = (data->tx_enable && (dir & AUDIO_DAI_DIR_TX)); + int r = 0; + + if (stop_tx) { + LOG_DBG("stop tx"); + pa_power_disable(&cfg->pa_power_dt); + mute_dac_path(dev, cfg->reg, 1); /* avoid pop noise */ + sf32lb_dma_stop_dt(&cfg->dma_tx); + config_dac_path(cfg->reg, 1); + close_analog_dac_path(cfg->reg); + disable_dac(cfg->reg); + clear_dac_channel(cfg->reg); + if (data->tx_buf) { + k_free(data->tx_buf); + data->tx_buf = NULL; + } + data->tx_enable = 0; + } + + if (stop_rx) { + LOG_DBG("stop rx"); + sf32lb_dma_stop_dt(&cfg->dma_rx); + disable_adc(cfg->reg); + close_analog_adc_path(cfg->reg); + clear_adc_channel(cfg->reg); + if (data->rx_buf) { + k_free(data->rx_buf); + data->rx_buf = NULL; + } + data->rx_enable = 0; + } + + if (stop_rx || stop_tx) { + pll_turn_off(cfg->reg); + data->pll_state = AUDIO_PLL_CLOSED; + } else { + LOG_ERR("stop err"); + r = -EIO; + } + return r; +} + +static void codec_start_output(const struct device *dev) +{ + LOG_WRN("start_output is not supported, please use start function for this device"); + ARG_UNUSED(dev); +} + +static void codec_stop_output(const struct device *dev) +{ + LOG_WRN("stop_output is not supported, please use stop function for this device"); + ARG_UNUSED(dev); +} + +static void config_audcodec_dma(const struct device *dev, uint8_t is_tx) +{ + int ret; + const struct sf32lb_dma_dt_spec *spec; + const struct sf32lb_codec_driver_config *cfg = dev->config; + struct dma_config config_dma = {0}; + struct dma_block_config block_cfg = {0}; + struct sf32lb_audcodec_data *data = dev->data; + + if (is_tx) { + block_cfg.source_addr_adj = DMA_ADDR_ADJ_INCREMENT; + block_cfg.dest_addr_adj = DMA_ADDR_ADJ_NO_CHANGE; + config_dma.channel_direction = MEMORY_TO_PERIPHERAL; + block_cfg.source_reload_en = 1U; + block_cfg.dest_reload_en = 0U; + config_dma.dma_callback = dma_tx_callback; + spec = &cfg->dma_tx; + } else { + block_cfg.source_addr_adj = DMA_ADDR_ADJ_NO_CHANGE; + block_cfg.dest_addr_adj = DMA_ADDR_ADJ_INCREMENT; + config_dma.channel_direction = PERIPHERAL_TO_MEMORY; + block_cfg.source_reload_en = 0U; + block_cfg.dest_reload_en = 1U; + config_dma.dma_callback = dma_rx_callback; + spec = &cfg->dma_rx; + } + + sf32lb_dma_config_init_dt(spec, &config_dma); + + config_dma.head_block = &block_cfg; + /* audio must 4 bytes unit */ + config_dma.source_data_size = 4U; + config_dma.dest_data_size = 4U; + config_dma.half_complete_callback_en = 1U; + config_dma.error_callback_dis = 1U; + config_dma.block_count = 1U; + config_dma.user_data = (void *)data; + data->dev = dev; + + ret = sf32lb_dma_config_dt(spec, &config_dma); + + if (ret < 0) { + LOG_ERR("dma cfg err=%d", ret); + } +} + +static int codec_driver_init(const struct device *dev) +{ + const struct sf32lb_codec_driver_config *cfg = dev->config; + struct sf32lb_audcodec_data *data = dev->data; + struct sf32lb_codec_hw_config *hw_cfg = &data->hw_config; + int r = 0; + + if (!sf32lb_dma_is_ready_dt(&cfg->dma_tx) || !sf32lb_dma_is_ready_dt(&cfg->dma_rx)) { + r = -ENODEV; + goto end; + } + + if (!sf32lb_clock_is_ready_dt(&cfg->clock)) { + r = -ENODEV; + goto end; + } + + /* set clock */ + hw_cfg->en_dly_sel = 0; + hw_cfg->dac_cfg.opmode = 1; + hw_cfg->adc_cfg.opmode = 1; + + pmu_enable_audio(1); + + r = sf32lb_clock_control_on_dt(&cfg->clock); + if (r < 0) { + LOG_ERR("Clock required is not on"); + } else { + config_audcodec_dma(dev, 1); + config_audcodec_dma(dev, 0); + pll_calibration(cfg->reg); + } + +end: + return r; +} + +static const struct audio_codec_api codec_driver_api = { + .configure = codec_configure, + .start_output = codec_start_output, + .stop_output = codec_stop_output, + .set_property = codec_set_property, + .apply_properties = codec_apply_properties, + .start = codec_start, + .stop = codec_stop, + .write = codec_write, + .register_done_callback = codec_register_done_callback, +}; + +#define SF32LB_AUDIO_CODEC_DEFINE(n) \ + static const struct sf32lb_codec_driver_config config##n = { \ + .reg = DT_INST_REG_ADDR(n), \ + .dma_tx = SF32LB_DMA_DT_INST_SPEC_GET_BY_NAME(n, tx), \ + .dma_rx = SF32LB_DMA_DT_INST_SPEC_GET_BY_NAME(n, rx), \ + .clock = SF32LB_CLOCK_DT_INST_SPEC_GET(n), \ + .pa_power_dt = GPIO_DT_SPEC_INST_GET(n, pa_power_gpios), \ + }; \ + \ + static struct sf32lb_audcodec_data data##n; \ + \ + DEVICE_DT_INST_DEFINE(n, codec_driver_init, NULL, &data##n, &config##n, POST_KERNEL, \ + CONFIG_AUDIO_CODEC_INIT_PRIORITY, &codec_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(SF32LB_AUDIO_CODEC_DEFINE) From a623bf1078cb68d467935127aef104685777e7dd Mon Sep 17 00:00:00 2001 From: Gang He Date: Mon, 24 Nov 2025 13:53:23 +0800 Subject: [PATCH 1486/3659] board: sifli: sf32lb62_devkit_lcd: Add audio codec Add audio codec in board device tree, including PA control pin. Signed-off-by: Gang He --- boards/sifli/sf32lb52_devkit_lcd/sf32lb52_devkit_lcd.dts | 9 +++++++++ .../sifli/sf32lb52_devkit_lcd/sf32lb52_devkit_lcd.yaml | 1 + 2 files changed, 10 insertions(+) diff --git a/boards/sifli/sf32lb52_devkit_lcd/sf32lb52_devkit_lcd.dts b/boards/sifli/sf32lb52_devkit_lcd/sf32lb52_devkit_lcd.dts index fe834b823410..c89660ad5151 100644 --- a/boards/sifli/sf32lb52_devkit_lcd/sf32lb52_devkit_lcd.dts +++ b/boards/sifli/sf32lb52_devkit_lcd/sf32lb52_devkit_lcd.dts @@ -55,6 +55,7 @@ }; aliases { + codec0 = &audcodec; led0 = &led0; sw0 = &key1; sw1 = &key2; @@ -143,6 +144,14 @@ pinctrl-names = "default"; }; +&audcodec { + dmas = <&dmac 1 SF32LB52X_DMA_REQ_AUDAC_CH0 SF32LB_DMA_PL_HIGH>, + <&dmac 4 SF32LB52X_DMA_REQ_AUDADC_CH0 SF32LB_DMA_PL_HIGH>; + dma-names = "tx", "rx"; + pa-power-gpios = <&gpioa_00_31 10 GPIO_ACTIVE_HIGH>; + status = "okay"; +}; + &wdt { status = "okay"; }; diff --git a/boards/sifli/sf32lb52_devkit_lcd/sf32lb52_devkit_lcd.yaml b/boards/sifli/sf32lb52_devkit_lcd/sf32lb52_devkit_lcd.yaml index 2a4029777699..e3882be98bab 100644 --- a/boards/sifli/sf32lb52_devkit_lcd/sf32lb52_devkit_lcd.yaml +++ b/boards/sifli/sf32lb52_devkit_lcd/sf32lb52_devkit_lcd.yaml @@ -14,4 +14,5 @@ supported: - gpio - watchdog - bluetooth + - audio vendor: sifli From 19a592fa10f66447fc83e1c83eb6c2940366e280 Mon Sep 17 00:00:00 2001 From: Gang He Date: Mon, 24 Nov 2025 14:26:07 +0800 Subject: [PATCH 1487/3659] samples: drivers: audio: Add codec loopback sample. Add audio loop back sample Signed-off-by: Gang He --- samples/drivers/audio/codec/CMakeLists.txt | 8 ++ samples/drivers/audio/codec/README.rst | 38 ++++++ samples/drivers/audio/codec/prj.conf | 4 + samples/drivers/audio/codec/sample.yaml | 16 +++ samples/drivers/audio/codec/src/main.c | 140 +++++++++++++++++++++ 5 files changed, 206 insertions(+) create mode 100644 samples/drivers/audio/codec/CMakeLists.txt create mode 100644 samples/drivers/audio/codec/README.rst create mode 100644 samples/drivers/audio/codec/prj.conf create mode 100644 samples/drivers/audio/codec/sample.yaml create mode 100644 samples/drivers/audio/codec/src/main.c diff --git a/samples/drivers/audio/codec/CMakeLists.txt b/samples/drivers/audio/codec/CMakeLists.txt new file mode 100644 index 000000000000..e1f6c116c31e --- /dev/null +++ b/samples/drivers/audio/codec/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(codec) + +target_sources(app PRIVATE src/main.c) diff --git a/samples/drivers/audio/codec/README.rst b/samples/drivers/audio/codec/README.rst new file mode 100644 index 000000000000..5e56e8ed6ef7 --- /dev/null +++ b/samples/drivers/audio/codec/README.rst @@ -0,0 +1,38 @@ +.. zephyr:code-sample:: codec + :name: audio codec + + mic to speaker loopback. + +Overview +******** + +A simple sample that to demo audio speaker play, and mic to speaker loopback functions. + +Building and Running +******************** + +This application can be built and executed on board as follows: + +.. zephyr-app-commands:: + :zephyr-app: samples/drivers/audio/codec + :host-os: unix + :board: sf32lb52_devkit_lcd + :goals: run + :compact: + +To build for another board, change "sf32lb52_devkit_lcd" above to that board's name. + +Sample Output +============= + +.. code-block:: console + + Audio codec sample + codec device is ready + codec playback example + playback started + codec transfer stopped + codec loopback example + loopback started + loopback stopped + Exiting diff --git a/samples/drivers/audio/codec/prj.conf b/samples/drivers/audio/codec/prj.conf new file mode 100644 index 000000000000..8402732ccb73 --- /dev/null +++ b/samples/drivers/audio/codec/prj.conf @@ -0,0 +1,4 @@ +CONFIG_AUDIO=y +CONFIG_LOG=y +CONFIG_AUDIO_CODEC=y +CONFIG_HEAP_MEM_POOL_SIZE=32000 diff --git a/samples/drivers/audio/codec/sample.yaml b/samples/drivers/audio/codec/sample.yaml new file mode 100644 index 000000000000..7390ff0bf51b --- /dev/null +++ b/samples/drivers/audio/codec/sample.yaml @@ -0,0 +1,16 @@ +sample: + description: onchip audio codec example application + name: audio codec sample +tests: + sample.drivers.audio.codec: + filter: dt_nodelabel_enabled("audcodec") + tags: codec + integration_platforms: + - sf32lb52_devkit_lcd + harness: console + harness_config: + type: multi_line + ordered: true + regex: + - "Audio codec sample" + - "Exiting" diff --git a/samples/drivers/audio/codec/src/main.c b/samples/drivers/audio/codec/src/main.c new file mode 100644 index 000000000000..b796383fdfee --- /dev/null +++ b/samples/drivers/audio/codec/src/main.c @@ -0,0 +1,140 @@ +/* + * Copyright 2025 SiFli Technologies(Nanjing) Co., Ltd + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +LOG_MODULE_REGISTER(codec_sample); + +#define AUDIO_BLOCK_SIZE 320 +#define SPEAKER_VOL 15 + +static bool loopback; +static uint8_t *audio_data_p; + +/* PCM data is word-aligned for efficient access (e.g. by the codec/DMA). + */ +static uint8_t __aligned(4) pcm_16k[] = { + 0x01, 0x00, 0xFE, 0x17, 0x55, 0x2C, 0xEB, 0x39, 0xB1, 0x3E, 0xEC, 0x39, 0x55, 0x2C, 0xFE, + 0x17, 0x01, 0x00, 0x02, 0xE8, 0xAC, 0xD3, 0x15, 0xC6, 0x4F, 0xC1, 0x15, 0xC6, 0xAC, 0xD3, + 0x03, 0xE8, 0x00, 0x00, 0xFD, 0x17, 0x54, 0x2C, 0xEB, 0x39, 0xB1, 0x3E, 0xEC, 0x39, 0x54, + 0x2C, 0xFE, 0x17, 0x00, 0x00, 0x02, 0xE8, 0xAB, 0xD3, 0x15, 0xC6, 0x4F, 0xC1, 0x15, 0xC6, + 0xAC, 0xD3, 0x02, 0xE8, 0x00, 0x00, 0xFD, 0x17, 0x54, 0x2C, 0xEC, 0x39, 0xB1, 0x3E, 0xEB, + 0x39, 0x55, 0x2C, 0xFE, 0x17, 0xFF, 0xFF, 0x03, 0xE8, 0xAB, 0xD3, 0x14, 0xC6, 0x4F, 0xC1, + 0x14, 0xC6, 0xAB, 0xD3, 0x02, 0xE8, 0x00, 0x00, 0xFE, 0x17, 0x55, 0x2C, 0xEC, 0x39, 0xB1, + 0x3E, 0xEC, 0x39, 0x54, 0x2C, 0xFD, 0x17, 0x01, 0x00, 0x02, 0xE8, 0xAC, 0xD3, 0x15, 0xC6, + 0x4F, 0xC1, 0x15, 0xC6, 0xAB, 0xD3, 0x02, 0xE8, 0x00, 0x00, 0xFE, 0x17, 0x55, 0x2C, 0xEB, + 0x39, 0xB1, 0x3E, 0xEB, 0x39, 0x54, 0x2C, 0xFD, 0x17, 0x00, 0x00, 0x02, 0xE8, 0xAC, 0xD3, + 0x14, 0xC6, 0x50, 0xC1, 0x14, 0xC6, 0xAC, 0xD3, 0x02, 0xE8, 0x01, 0x00, 0xFE, 0x17, 0x54, + 0x2C, 0xEB, 0x39, 0xB1, 0x3E, 0xEB, 0x39, 0x54, 0x2C, 0xFE, 0x17, 0x00, 0x00, 0x03, 0xE8, + 0xAC, 0xD3, 0x14, 0xC6, 0x4F, 0xC1, 0x14, 0xC6, 0xAC, 0xD3, 0x02, 0xE8, 0x00, 0x00, 0xFD, + 0x17, 0x55, 0x2C, 0xEB, 0x39, 0xB1, 0x3E, 0xEB, 0x39, 0x54, 0x2C, 0xFD, 0x17, 0x00, 0x00, + 0x02, 0xE8, 0xAC, 0xD3, 0x14, 0xC6, 0x4F, 0xC1, 0x15, 0xC6, 0xAB, 0xD3, 0x02, 0xE8, 0x01, + 0x00, 0xFD, 0x17, 0x55, 0x2C, 0xEB, 0x39, 0xB1, 0x3E, 0xEB, 0x39, 0x54, 0x2C, 0xFD, 0x17, + 0x00, 0x00, 0x02, 0xE8, 0xAB, 0xD3, 0x14, 0xC6, 0x50, 0xC1, 0x15, 0xC6, 0xAB, 0xD3, 0x02, + 0xE8, 0x00, 0x00, 0xFD, 0x17, 0x55, 0x2C, 0xEB, 0x39, 0xB1, 0x3E, 0xEC, 0x39, 0x54, 0x2C, + 0xFE, 0x17, 0x00, 0x00, 0x02, 0xE8, 0xAB, 0xD3, 0x15, 0xC6, 0x4F, 0xC1, 0x14, 0xC6, 0xAC, + 0xD3, 0x03, 0xE8, 0x00, 0x00, 0xFD, 0x17, 0x54, 0x2C, 0xEC, 0x39, 0xB2, 0x3E, 0xEB, 0x39, + 0x54, 0x2C, 0xFE, 0x17, 0x00, 0x00, 0x02, 0xE8, 0xAB, 0xD3, 0x15, 0xC6, 0x4F, 0xC1, 0x14, + 0xC6, 0xAB, 0xD3, 0x03, 0xE8, +}; + +static void tx_done(const struct device *dev, void *user_data) +{ + if (!loopback) { + size_t offset = (size_t)(audio_data_p - pcm_16k); + size_t remaining = sizeof(pcm_16k) - offset; + + if (remaining < AUDIO_BLOCK_SIZE) { + audio_data_p = pcm_16k; + } + audio_codec_write(dev, audio_data_p, AUDIO_BLOCK_SIZE); + audio_data_p += AUDIO_BLOCK_SIZE; + } +} +static void rx_done(const struct device *dev, uint8_t *buf, uint32_t len, void *user_data) +{ + if (loopback) { + audio_codec_write(dev, buf, AUDIO_BLOCK_SIZE); + } +} + +int main(void) +{ + static const struct device *dev; + audio_property_value_t val; + struct audio_codec_cfg cfg = { + .dai_type = AUDIO_DAI_TYPE_PCM, + .dai_cfg.pcm.dir = AUDIO_DAI_DIR_TX, + .dai_cfg.pcm.pcm_width = AUDIO_PCM_WIDTH_16_BITS, + .dai_cfg.pcm.channels = 1, + .dai_cfg.pcm.block_size = AUDIO_BLOCK_SIZE, + .dai_cfg.pcm.samplerate = AUDIO_PCM_RATE_16K, + }; + + LOG_INF("Audio codec sample"); +#if DT_NODE_HAS_STATUS_OKAY(DT_ALIAS(codec0)) + dev = DEVICE_DT_GET(DT_ALIAS(codec0)); +#else + LOG_ERR("No audio codec on this board. Skipping audio test.\n"); + return 0; +#endif + if (!device_is_ready(dev)) { + LOG_ERR("codec device is not ready\n"); + return -EBUSY; + } + LOG_INF("codec device is ready"); + k_sleep(K_MSEC(1000)); + + LOG_INF("codec playback example"); + loopback = false; + audio_data_p = pcm_16k; + if (audio_codec_configure(dev, &cfg) < 0) { + LOG_ERR("configure codec error\n"); + return -EIO; + } + if (audio_codec_register_done_callback(dev, tx_done, NULL, rx_done, NULL) < 0) { + LOG_ERR("could not register codec callbacks\n"); + return -EIO; + } + audio_codec_start(dev, AUDIO_DAI_DIR_TX); + LOG_INF("playback started"); + val.vol = SPEAKER_VOL; + if (audio_codec_set_property(dev, AUDIO_PROPERTY_OUTPUT_VOLUME, 0, val) < 0) { + LOG_ERR("could not set volume\n"); + return -EIO; + } + k_sleep(K_MSEC(15000)); + audio_codec_stop(dev, AUDIO_DAI_DIR_TX); + LOG_INF("codec transfer stopped"); + + LOG_INF("codec loopback example"); + loopback = true; + cfg.dai_cfg.pcm.dir = AUDIO_DAI_DIR_TXRX; + if (audio_codec_configure(dev, &cfg) < 0) { + LOG_ERR("configure codec error\n"); + return -EIO; + } + if (audio_codec_register_done_callback(dev, tx_done, NULL, rx_done, NULL) < 0) { + LOG_ERR("could not register codec callbacks\n"); + return -EIO; + } + audio_codec_start(dev, AUDIO_DAI_DIR_TXRX); + LOG_INF("loopback started"); + if (audio_codec_set_property(dev, AUDIO_PROPERTY_OUTPUT_VOLUME, 0, val) < 0) { + LOG_ERR("could not set volume\n"); + return -EIO; + } + k_sleep(K_MSEC(15000)); + audio_codec_stop(dev, AUDIO_DAI_DIR_TXRX); + LOG_INF("loopback stopped"); + + LOG_INF("Exiting"); + return 0; +} From 29c95ff3fdb0d32be2941998261ff0ead633afd4 Mon Sep 17 00:00:00 2001 From: Jonas Berg Date: Sun, 21 Dec 2025 18:07:45 +0100 Subject: [PATCH 1488/3659] boards: Add support for Cytron Maker Pi RP2040 Tested with the commands mentioned in index.rst Product photo from https://www.cytron.io/p-maker-pi-rp2040-simplifying-robotics-with-raspberry-pi-rp2040 Signed-off-by: Jonas Berg --- boards/cytron/maker_pi_rp2040/Kconfig | 5 + .../cytron/maker_pi_rp2040/Kconfig.defconfig | 16 + .../maker_pi_rp2040/Kconfig.maker_pi_rp2040 | 5 + boards/cytron/maker_pi_rp2040/board.cmake | 38 +++ boards/cytron/maker_pi_rp2040/board.yml | 6 + .../doc/img/maker_pi_rp2040.webp | Bin 0 -> 33214 bytes boards/cytron/maker_pi_rp2040/doc/index.rst | 283 ++++++++++++++++++ .../maker_pi_rp2040/grove_connectors.dtsi | 70 +++++ .../maker_pi_rp2040-pinctrl.dtsi | 48 +++ .../maker_pi_rp2040/maker_pi_rp2040.dts | 219 ++++++++++++++ .../maker_pi_rp2040/maker_pi_rp2040.yaml | 21 ++ .../maker_pi_rp2040/maker_pi_rp2040_defconfig | 14 + .../maker_pi_rp2040/support/openocd.cfg | 11 + 13 files changed, 736 insertions(+) create mode 100644 boards/cytron/maker_pi_rp2040/Kconfig create mode 100644 boards/cytron/maker_pi_rp2040/Kconfig.defconfig create mode 100644 boards/cytron/maker_pi_rp2040/Kconfig.maker_pi_rp2040 create mode 100644 boards/cytron/maker_pi_rp2040/board.cmake create mode 100644 boards/cytron/maker_pi_rp2040/board.yml create mode 100644 boards/cytron/maker_pi_rp2040/doc/img/maker_pi_rp2040.webp create mode 100644 boards/cytron/maker_pi_rp2040/doc/index.rst create mode 100644 boards/cytron/maker_pi_rp2040/grove_connectors.dtsi create mode 100644 boards/cytron/maker_pi_rp2040/maker_pi_rp2040-pinctrl.dtsi create mode 100644 boards/cytron/maker_pi_rp2040/maker_pi_rp2040.dts create mode 100644 boards/cytron/maker_pi_rp2040/maker_pi_rp2040.yaml create mode 100644 boards/cytron/maker_pi_rp2040/maker_pi_rp2040_defconfig create mode 100644 boards/cytron/maker_pi_rp2040/support/openocd.cfg diff --git a/boards/cytron/maker_pi_rp2040/Kconfig b/boards/cytron/maker_pi_rp2040/Kconfig new file mode 100644 index 000000000000..57ba620750b2 --- /dev/null +++ b/boards/cytron/maker_pi_rp2040/Kconfig @@ -0,0 +1,5 @@ +# Copyright (c) 2025 Jonas Berg +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_MAKER_PI_RP2040 + select RP2_FLASH_W25Q080 diff --git a/boards/cytron/maker_pi_rp2040/Kconfig.defconfig b/boards/cytron/maker_pi_rp2040/Kconfig.defconfig new file mode 100644 index 000000000000..e538c0388a60 --- /dev/null +++ b/boards/cytron/maker_pi_rp2040/Kconfig.defconfig @@ -0,0 +1,16 @@ +# Copyright (c) 2022 Peter Johanson +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_MAKER_PI_RP2040 + +if I2C_DW + +config I2C_DW_CLOCK_SPEED + default 125 + +endif # I2C_DW + +config USB_SELF_POWERED + default n + +endif # BOARD_MAKER_PI_RP2040 diff --git a/boards/cytron/maker_pi_rp2040/Kconfig.maker_pi_rp2040 b/boards/cytron/maker_pi_rp2040/Kconfig.maker_pi_rp2040 new file mode 100644 index 000000000000..d8ff2e55b571 --- /dev/null +++ b/boards/cytron/maker_pi_rp2040/Kconfig.maker_pi_rp2040 @@ -0,0 +1,5 @@ +# Copyright (c) 2025 Jonas Berg +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_MAKER_PI_RP2040 + select SOC_RP2040 diff --git a/boards/cytron/maker_pi_rp2040/board.cmake b/boards/cytron/maker_pi_rp2040/board.cmake new file mode 100644 index 000000000000..5a702fc5e030 --- /dev/null +++ b/boards/cytron/maker_pi_rp2040/board.cmake @@ -0,0 +1,38 @@ +# SPDX-License-Identifier: Apache-2.0 +# Adapted from boards/raspberrypi/rpi_pico/board.cmake + +# This configuration allows selecting what debug adapter debugging rpi_pico +# by a command-line argument. +# It is mainly intended to support both the 'picoprobe' and 'raspberrypi-swd' +# adapter described in "Getting started with Raspberry Pi Pico". +# And any other SWD debug adapter might also be usable with this configuration. + +# Set RPI_PICO_DEBUG_ADAPTER to select debug adapter by command-line arguments. +# e.g.) west build -b rpi_pico -- -DRPI_PICO_DEBUG_ADAPTER=raspberrypi-swd +# The value is treated as a part of an interface file name that +# the debugger's configuration file. +# The value must be the 'stem' part of the name of one of the files +# in the openocd interface configuration file. +# The setting is store to CMakeCache.txt. +if("${RPI_PICO_DEBUG_ADAPTER}" STREQUAL "") + set(RPI_PICO_DEBUG_ADAPTER "cmsis-dap") +endif() + +board_runner_args(openocd --cmd-pre-init "source [find interface/${RPI_PICO_DEBUG_ADAPTER}.cfg]") +board_runner_args(openocd --cmd-pre-init "transport select swd") +board_runner_args(openocd --cmd-pre-init "source [find target/rp2040.cfg]") + +# The adapter speed is expected to be set by interface configuration. +# But if not so, set 2000 to adapter speed. +board_runner_args(openocd --cmd-pre-init "set_adapter_speed_if_not_set 2000") + +board_runner_args(jlink "--device=RP2040_M0_0") +board_runner_args(uf2 "--board-id=RPI-RP2") +board_runner_args(pyocd "--target=rp2040") + +# Default runner should be listed first +include(${ZEPHYR_BASE}/boards/common/uf2.board.cmake) +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) +include(${ZEPHYR_BASE}/boards/common/blackmagicprobe.board.cmake) +include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake) diff --git a/boards/cytron/maker_pi_rp2040/board.yml b/boards/cytron/maker_pi_rp2040/board.yml new file mode 100644 index 000000000000..30861061a71a --- /dev/null +++ b/boards/cytron/maker_pi_rp2040/board.yml @@ -0,0 +1,6 @@ +board: + name: maker_pi_rp2040 + full_name: Cytron Maker Pi RP2040 + vendor: cytron + socs: + - name: rp2040 diff --git a/boards/cytron/maker_pi_rp2040/doc/img/maker_pi_rp2040.webp b/boards/cytron/maker_pi_rp2040/doc/img/maker_pi_rp2040.webp new file mode 100644 index 0000000000000000000000000000000000000000..b97c43ed72aeff988cc24fc93fb9abb68dea0be7 GIT binary patch literal 33214 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 B4$=Ss literal 0 HcmV?d00001 diff --git a/boards/cytron/maker_pi_rp2040/doc/index.rst b/boards/cytron/maker_pi_rp2040/doc/index.rst new file mode 100644 index 000000000000..ae9089f3d593 --- /dev/null +++ b/boards/cytron/maker_pi_rp2040/doc/index.rst @@ -0,0 +1,283 @@ +.. zephyr:board:: maker_pi_rp2040 + +Overview +******** + +The `Cytron Maker Pi RP2040`_ board is based on the RP2040 microcontroller from Raspberry Pi Ltd. +The board has motor drivers, servo headers, Grove connectors and a micro USB connector. + + +Hardware +******** + +- Microcontroller Raspberry Pi RP2040, with a max frequency of 133 MHz +- Dual ARM Cortex M0+ cores +- 264 kByte SRAM +- 2 Mbyte QSPI flash +- 17 GPIO pins +- 3 ADC pins +- Supply voltage measurement +- I2C +- UART +- Micro USB connector +- LiPo charger +- Reset, boot and 2 user buttons +- 2 RGB LEDs (Neopixels) +- Piezo buzzer with mute switch +- 4 servo ports +- 2 Motor drivers, with 4 manual test bottons +- 7 Grove connectors, of which one can be used as a Maker/Qwiic/Stemma QT/zephyr_i2c connector +- 13 status indicators for digital pins + + +Default Zephyr Peripheral Mapping +================================= + ++---------------+--------+-----------------------+-----------------+ +| Description | Pin | Default pin mux | Zephyr PWM name | ++===============+========+=======================+=================+ +| RGB LEDs | GPIO18 | PIO0 | | ++---------------+--------+-----------------------+-----------------+ +| Buzzer | GPIO22 | PWM3A | 6 | ++---------------+--------+-----------------------+-----------------+ +| Button 1 | GPIO20 | (Alias sw0) | | ++---------------+--------+-----------------------+-----------------+ +| Button 2 | GPIO21 | (Alias sw1) | | ++---------------+--------+-----------------------+-----------------+ +| Voltage sense | GPIO29 | ADC3, voltage divider | | ++---------------+--------+-----------------------+-----------------+ + +Servo header: + ++-------+--------+-----------------+-----------------+ +| Label | Pin | Default pin mux | Zephyr PWM name | ++=======+========+=================+=================+ +| GP12 | GPIO12 | PWM6A | 12 | ++-------+--------+-----------------+-----------------+ +| GP13 | GPIO13 | PWM6B | 13 | ++-------+--------+-----------------+-----------------+ +| GP14 | GPIO14 | PWM7A | 14 | ++-------+--------+-----------------+-----------------+ +| GP15 | GPIO15 | PWM7B | 15 | ++-------+--------+-----------------+-----------------+ + +Motor drivers: + ++-------+--------+-----------------+-----------------+ +| Label | Pin | Default pin mux | Zephyr PWM name | ++=======+========+=================+=================+ +| M1A | GPIO8 | PWM4A | 8 | ++-------+--------+-----------------+-----------------+ +| M1B | GPIO9 | PWM4B | 9 | ++-------+--------+-----------------+-----------------+ +| M2A | GPIO10 | PWM5A | 10 | ++-------+--------+-----------------+-----------------+ +| M2B | GPIO11 | PWM5B | 11 | ++-------+--------+-----------------+-----------------+ + +Grove connector 1: + ++-------+--------+-----------------+ +| Label | Pin | Default pin mux | ++=======+========+=================+ +| GP0 | GPIO0 | UART0 TX | ++-------+--------+-----------------+ +| GP1 | GPIO1 | UART0 RX | ++-------+--------+-----------------+ + +Grove connector 2: + +Use an adapter cable to connect Qwiic/Stemma QT sensors (that use I2C) to this connector, which +is mapped to the ``zephyr_i2c`` devicetree node label. + ++-------+--------+-----------------+ +| Label | Pin | Default pin mux | ++=======+========+=================+ +| GP2 | GPIO2 | I2C1 SDA | ++-------+--------+-----------------+ +| GP3 | GPIO3 | I2C1 SCL | ++-------+--------+-----------------+ + +Grove connector 3: + ++-------+--------+------------+ +| Label | Pin | Notes | ++=======+========+============+ +| GP4 | GPIO4 | Alias led0 | ++-------+--------+------------+ +| GP5 | GPIO5 | Alias led1 | ++-------+--------+------------+ + +Grove connector 4: + ++-------+--------+ +| Label | Pin | ++=======+========+ +| GP16 | GPIO16 | ++-------+--------+ +| GP17 | GPIO17 | ++-------+--------+ + +Grove connector 5: + ++-------+--------+-----------------+-----------------+ +| Label | Pin | Default pin mux | Notes | ++=======+========+=================+=================+ +| GP6 | GPIO6 | | | ++-------+--------+-----------------+-----------------+ +| GP26 | GPIO26 | ADC0 | Also in Grove 6 | ++-------+--------+-----------------+-----------------+ + +Grove connector 6: + ++-------+--------+-----------------+-----------------+ +| Label | Pin | Default pin mux | Notes | ++=======+========+=================+=================+ +| GP26 | GPIO26 | ADC0 | Also in Grove 5 | ++-------+--------+-----------------+-----------------+ +| GP27 | GPIO27 | ADC1 | | ++-------+--------+-----------------+-----------------+ + +Grove connector 7: + ++-------+--------+-----------------+ +| Label | Pin | Default pin mux | ++=======+========+=================+ +| GP7 | GPIO7 | | ++-------+--------+-----------------+ +| GP28 | GPIO28 | ADC2 | ++-------+--------+-----------------+ + +See also `schematic`_. + + +Supported Features +================== + +.. zephyr:board-supported-hw:: + + +Programming and Debugging +************************* + +.. zephyr:board-supported-runners:: + +By default programming is done via the USB connector. Press and hold the BOOT button, and then +press the RST button, and the device will appear as a USB mass storage unit. +Building your application will result in a :file:`build/zephyr/zephyr.uf2` file. +Drag and drop the file to the USB mass storage unit, and the board will be reprogrammed. + +It is also possible to program and debug the board via the SWDIO and SWCLK pins in the DEBUG +connector. You must solder a 3-pin header to the board in order to use this feature. +A separate programming hardware tool is required, and for example the :command:`openocd` software +is used. Typically the ``OPENOCD`` and ``OPENOCD_DEFAULT_PATH`` values should be set when +building, and the ``--runner openocd`` argument should be used when flashing. +For more details on programming RP2040-based boards, see :ref:`rpi_pico_programming_and_debugging`. + + +Flashing +======== + +To run the :zephyr:code-sample:`blinky` sample: + +.. zephyr-app-commands:: + :zephyr-app: samples/basic/blinky/ + :board: maker_pi_rp2040 + :goals: build flash + +Try also the :zephyr:code-sample:`led-strip`, :zephyr:code-sample:`hello_world`, +:zephyr:code-sample:`button`, :zephyr:code-sample:`input-dump` and +:zephyr:code-sample:`adc_dt` samples. + +The use of the Maker/Qwiic/Stemma QT I2C connector (Grove 2) is demonstrated using the +:zephyr:code-sample:`light_sensor_polling` sample and a separate shield: + +.. zephyr-app-commands:: + :zephyr-app: samples/sensor/light_polling + :board: maker_pi_rp2040 + :shield: adafruit_veml7700 + :goals: build flash + +Use the shell to control the GPIO pins: + +.. zephyr-app-commands:: + :zephyr-app: samples/sensor/sensor_shell + :board: maker_pi_rp2040 + :gen-args: -DCONFIG_GPIO=y -DCONFIG_GPIO_SHELL=y + :goals: build flash + +To set one of the GPIO pins high, use these commands in the shell, and study the indicator LEDs: + +.. code-block:: shell + + gpio conf gpio0 16 o + gpio set gpio0 16 1 + +Servo motor control is done via PWM outputs. The :zephyr:code-sample:`servo-motor` +sample sets servo position timing (via an overlay file) for the output GP12: + +.. zephyr-app-commands:: + :zephyr-app: samples/basic/servo_motor/ + :board: maker_pi_rp2040 + :goals: build flash + +It is also possible to control servos via the pwm shell: + +.. zephyr-app-commands:: + :zephyr-app: samples/sensor/sensor_shell + :board: maker_pi_rp2040 + :gen-args: -DCONFIG_PWM=y -DCONFIG_PWM_SHELL=y + :goals: build flash + +Use shell commands to set the position of the servo. Most servo motors can handle pulse +times between 800 and 2000 microseconds: + +.. code-block:: shell + + pwm usec pwm@40050000 12 20000 800 + pwm usec pwm@40050000 12 20000 2000 + +To use the buzzer, you must turn on the buzzer switch on the short side of the board. +Then build using the same command as above for the sensor_shell. +Use these shell commands to turn on and off the buzzer: + +.. code-block:: shell + + pwm usec pwm@40050000 6 1000 500 + pwm usec pwm@40050000 6 1000 0 + +You can also control the motor outputs via the shell. To set the speed of motor 1 to +100%, 50%, 20% and 0% respectively, use these commands: + +.. code-block:: shell + + pwm usec pwm@40050000 8 1000 1000 + pwm usec pwm@40050000 8 1000 500 + pwm usec pwm@40050000 8 1000 200 + pwm usec pwm@40050000 8 1000 0 + +To run the motor in the opposite direction at 80%: + +.. code-block:: shell + + pwm usec pwm@40050000 9 1000 800 + +The sensor_shell sample is used also to measure the supply voltage. This is the result when +running on a Vin voltage slightly less than 6 Volt: + +.. code-block:: shell + + sensor get vbatt + channel type=33(voltage) index=0 shift=3 num_samples=1 value=32688380776ns (5.977999) + + +References +********** + +.. target-notes:: + +.. _Cytron Maker Pi RP2040: + https://www.cytron.io/p-maker-pi-rp2040-simplifying-robotics-with-raspberry-pi-rp2040 + +.. _schematic: + https://drive.google.com/file/d/1BNqbxXScMXnL3-2YYfbR66nFCD1li71X/view diff --git a/boards/cytron/maker_pi_rp2040/grove_connectors.dtsi b/boards/cytron/maker_pi_rp2040/grove_connectors.dtsi new file mode 100644 index 000000000000..dbc5d9808468 --- /dev/null +++ b/boards/cytron/maker_pi_rp2040/grove_connectors.dtsi @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2026 Jonas Berg + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + grove_header1: grove_header1 { + compatible = "grove-header"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <0 0 &gpio0 1 0>, /* RX */ + <1 0 &gpio0 0 0>; /* TX */ + }; + + grove_header2: grove_header2 { + compatible = "grove-header"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <0 0 &gpio0 3 0>, /* SCL */ + <1 0 &gpio0 2 0>; /* SDA */ + }; + + grove_header3: grove_header3 { + compatible = "grove-header"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <0 0 &gpio0 5 0>, + <1 0 &gpio0 4 0>; + }; + + grove_header4: grove_header4 { + compatible = "grove-header"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <0 0 &gpio0 17 0>, + <1 0 &gpio0 16 0>; + }; + + grove_header5: grove_header5 { + compatible = "grove-header"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <0 0 &gpio0 26 0>, /* ADC0 */ + <1 0 &gpio0 6 0>; + }; + + grove_header6: grove_header6 { + compatible = "grove-header"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <0 0 &gpio0 27 0>, /* ADC1 */ + <1 0 &gpio0 26 0>; /* ADC0 */ + }; + + grove_header7: grove_header7 { + compatible = "grove-header"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <0 0 &gpio0 28 0>, /* ADC2 */ + <1 0 &gpio0 7 0>; + }; +}; diff --git a/boards/cytron/maker_pi_rp2040/maker_pi_rp2040-pinctrl.dtsi b/boards/cytron/maker_pi_rp2040/maker_pi_rp2040-pinctrl.dtsi new file mode 100644 index 000000000000..568e1f67521a --- /dev/null +++ b/boards/cytron/maker_pi_rp2040/maker_pi_rp2040-pinctrl.dtsi @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2025 Jonas Berg + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&pinctrl { + adc_default: adc_default { + group1 { + pinmux = , , , ; + input-enable; + }; + }; + + i2c1_default: i2c1_default { + group1 { + pinmux = , ; + input-enable; + }; + }; + + uart0_default: uart0_default { + group1 { + pinmux = ; + }; + + group2 { + pinmux = ; + input-enable; + }; + }; + + pwm_default: pwm_default { + group1 { + pinmux = , , , , + , , , , + ; + }; + }; + + ws2812_pio0_default: ws2812_pio0_default { + ws2812 { + pinmux = ; + }; + }; +}; diff --git a/boards/cytron/maker_pi_rp2040/maker_pi_rp2040.dts b/boards/cytron/maker_pi_rp2040/maker_pi_rp2040.dts new file mode 100644 index 000000000000..493fbcaa1232 --- /dev/null +++ b/boards/cytron/maker_pi_rp2040/maker_pi_rp2040.dts @@ -0,0 +1,219 @@ +/* + * Copyright (c) 2021 Yonatan Schachter + * Copyright (c) 2022 Peter Johanson + * Copyright (c) 2025 Jonas Berg + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include +#include +#include +#include "maker_pi_rp2040-pinctrl.dtsi" +#include "grove_connectors.dtsi" + +/ { + model = "Cytron Maker Pi RP2040"; + compatible = "cytron,maker_pi_rp2040"; + + chosen { + zephyr,sram = &sram0; + zephyr,flash = &flash0; + zephyr,flash-controller = &ssi; + zephyr,console = &uart0; + zephyr,shell-uart = &uart0; + zephyr,code-partition = &code_partition; + }; + + aliases { + led-strip = &ws2812; + led0 = &led_gp4; + led1 = &led_gp5; + sw0 = &button_gp20; + sw1 = &button_gp21; + watchdog0 = &wdt0; + }; + + zephyr,user { + io-channels = <&adc 0>, <&adc 1>, <&adc 2>, <&adc 3>; + }; + + vbatt: vbatt { + compatible = "voltage-divider"; + io-channels = <&adc 3>; + output-ohms = <10000>; + full-ohms = <(10000 + 10000)>; + }; + + gpio_keys { + compatible = "gpio-keys"; + + button_gp20: button_gp20 { + label = "Button GP20"; + gpios = <&gpio0 20 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + zephyr,code = ; + }; + + button_gp21: button_gp21 { + label = "Button GP21"; + gpios = <&gpio0 21 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + zephyr,code = ; + }; + }; + + leds: leds { + compatible = "gpio-leds"; + + led_gp4: led_gp4 { + gpios = <&gpio0 4 GPIO_ACTIVE_HIGH>; + label = "LED GP4"; + }; + + led_gp5: led_gp5 { + gpios = <&gpio0 5 GPIO_ACTIVE_HIGH>; + label = "LED GP5"; + }; + }; +}; + +&flash0 { + reg = <0x10000000 DT_SIZE_M(2)>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + /* Reserved memory for the second stage bootloader */ + second_stage_bootloader: partition@0 { + label = "second_stage_bootloader"; + reg = <0x00000000 0x100>; + read-only; + }; + + /* + * Usable flash. Starts at 0x100, after the bootloader. The partition + * size is 2 MB minus the 0x100 bytes taken by the bootloader. + */ + code_partition: partition@100 { + label = "code-partition"; + reg = <0x100 (DT_SIZE_M(2) - 0x100)>; + read-only; + }; + }; +}; + +&gpio0 { + status = "okay"; +}; + +&uart0 { + current-speed = <115200>; + status = "okay"; + pinctrl-0 = <&uart0_default>; + pinctrl-names = "default"; +}; + +zephyr_i2c: &i2c1 { + status = "okay"; + pinctrl-0 = <&i2c1_default>; + pinctrl-names = "default"; + clock-frequency = ; +}; + +&timer { + status = "okay"; +}; + +&wdt0 { + status = "okay"; +}; + +&adc { + status = "okay"; + pinctrl-0 = <&adc_default>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + + channel@0 { + reg = <0>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; + + channel@1 { + reg = <1>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; + + channel@2 { + reg = <2>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; + + channel@3 { + reg = <3>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; +}; + +&pwm { + pinctrl-0 = <&pwm_default>; + pinctrl-names = "default"; + status = "okay"; +}; + +&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 18 GPIO_ACTIVE_HIGH>; + chain-length = <2>; + color-mapping = ; + reset-delay = <280>; + frequency = <800000>; + }; + }; +}; + +zephyr_udc0: &usbd { + status = "okay"; +}; + +&die_temp { + status = "okay"; +}; + +&vreg { + regulator-always-on; + regulator-allowed-modes = ; +}; + +&xosc { + startup-delay-multiplier = <64>; +}; diff --git a/boards/cytron/maker_pi_rp2040/maker_pi_rp2040.yaml b/boards/cytron/maker_pi_rp2040/maker_pi_rp2040.yaml new file mode 100644 index 000000000000..91881a9a9be1 --- /dev/null +++ b/boards/cytron/maker_pi_rp2040/maker_pi_rp2040.yaml @@ -0,0 +1,21 @@ +identifier: maker_pi_rp2040 +name: Cytron Maker Pi RP2040 +type: mcu +arch: arm +flash: 2048 +ram: 264 +toolchain: + - zephyr + - gnuarmemb +supported: + - adc + - clock + - counter + - dma + - flash + - gpio + - hwinfo + - i2c + - pwm + - uart + - watchdog diff --git a/boards/cytron/maker_pi_rp2040/maker_pi_rp2040_defconfig b/boards/cytron/maker_pi_rp2040/maker_pi_rp2040_defconfig new file mode 100644 index 000000000000..40aec62529fa --- /dev/null +++ b/boards/cytron/maker_pi_rp2040/maker_pi_rp2040_defconfig @@ -0,0 +1,14 @@ +# Copyright (c) 2025 Jonas Berg +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_BUILD_OUTPUT_HEX=y +CONFIG_BUILD_OUTPUT_UF2=y +CONFIG_CLOCK_CONTROL=y +CONFIG_CONSOLE=y +CONFIG_GPIO=y +CONFIG_PIO_RPI_PICO=y +CONFIG_RESET=y +CONFIG_SERIAL=y +CONFIG_UART_CONSOLE=y +CONFIG_UART_INTERRUPT_DRIVEN=y +CONFIG_USE_DT_CODE_PARTITION=y diff --git a/boards/cytron/maker_pi_rp2040/support/openocd.cfg b/boards/cytron/maker_pi_rp2040/support/openocd.cfg new file mode 100644 index 000000000000..34ab592b1861 --- /dev/null +++ b/boards/cytron/maker_pi_rp2040/support/openocd.cfg @@ -0,0 +1,11 @@ +# Copyright (c) 2022 Tokita, Hiroshi +# SPDX-License-Identifier: Apache-2.0 + +# Checking and set 'adapter speed'. +# Set the adaptor speed, if unset, and given as an argument. +proc set_adapter_speed_if_not_set { speed } { + puts "checking adapter speed..." + if { [catch {adapter speed} ret] } { + adapter speed $speed + } +} From 2e6955100e86ff476daaa1471a169b1a4cd93442 Mon Sep 17 00:00:00 2001 From: Jonas Berg Date: Sun, 21 Dec 2025 18:07:45 +0100 Subject: [PATCH 1489/3659] samples: servo-motor: Add overlay for Cytron Maker Pi RP2040 Enable servo port GP12. Add commented-out entries for the other ports, as is done for the other overlay files. Signed-off-by: Jonas Berg --- .../servo_motor/boards/maker_pi_rp2040.overlay | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 samples/basic/servo_motor/boards/maker_pi_rp2040.overlay diff --git a/samples/basic/servo_motor/boards/maker_pi_rp2040.overlay b/samples/basic/servo_motor/boards/maker_pi_rp2040.overlay new file mode 100644 index 000000000000..50bf8708dcd9 --- /dev/null +++ b/samples/basic/servo_motor/boards/maker_pi_rp2040.overlay @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* Copyright 2025 Jonas Berg */ + +#include + +/ { + servo: servo { + compatible = "pwm-servo"; + pwms = <&pwm 12 PWM_MSEC(20) PWM_POLARITY_NORMAL>; /* GP12 */ + /* <&pwm 13 PWM_MSEC(20) PWM_POLARITY_NORMAL> */ /* GP13 */ + /* <&pwm 14 PWM_MSEC(20) PWM_POLARITY_NORMAL> */ /* GP14 */ + /* <&pwm 15 PWM_MSEC(20) PWM_POLARITY_NORMAL> */ /* GP15 */ + min-pulse = ; + max-pulse = ; + }; +}; From 5dc238591492ad6da83d84703bb45659033835ac Mon Sep 17 00:00:00 2001 From: Aleksandr Senin Date: Sat, 27 Dec 2025 17:53:28 +0300 Subject: [PATCH 1490/3659] drivers: serial: gd32: add UART runtime configure support Add uart_configure()/uart_config_get() support to usart_gd32. Store runtime config in driver data and init it from DT defaults. Signed-off-by: Aleksandr Senin --- drivers/serial/usart_gd32.c | 141 +++++++++++++++++++++++++++++++++++- 1 file changed, 140 insertions(+), 1 deletion(-) diff --git a/drivers/serial/usart_gd32.c b/drivers/serial/usart_gd32.c index bbccf6525cea..1df15300efa3 100644 --- a/drivers/serial/usart_gd32.c +++ b/drivers/serial/usart_gd32.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2021, ATL Electronics + * Copyright (c) 2025 Aleksandr Senin * SPDX-License-Identifier: Apache-2.0 */ @@ -38,6 +39,13 @@ struct gd32_usart_data { uart_irq_callback_user_data_t user_cb; void *user_data; #endif /* CONFIG_UART_INTERRUPT_DRIVEN */ +#ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE + enum uart_config_parity parity; + enum uart_config_stop_bits stop_bits; + enum uart_config_data_bits data_bits; + enum uart_config_flow_control flow_ctrl; + bool initialized; +#endif /* CONFIG_UART_USE_RUNTIME_CONFIGURE */ }; #ifdef CONFIG_UART_INTERRUPT_DRIVEN @@ -102,7 +110,14 @@ static int usart_gd32_init(const struct device *dev) #ifdef CONFIG_UART_INTERRUPT_DRIVEN cfg->irq_config_func(dev); #endif /* CONFIG_UART_INTERRUPT_DRIVEN */ - +#ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE + /* Initialize runtime configuration from Devicetree defaults */ + data->parity = cfg->parity; + data->data_bits = UART_CFG_DATA_BITS_8; + data->stop_bits = UART_CFG_STOP_BITS_1; + data->flow_ctrl = UART_CFG_FLOW_CTRL_NONE; + data->initialized = true; +#endif /* CONFIG_UART_USE_RUNTIME_CONFIGURE */ return 0; } @@ -162,6 +177,126 @@ static int usart_gd32_err_check(const struct device *dev) return errors; } +#ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE +static int usart_gd32_configure(const struct device *dev, const struct uart_config *cfg_new) +{ + const struct gd32_usart_config *const cfg = dev->config; + struct gd32_usart_data *const data = dev->data; + uint32_t parity_bits; + uint32_t word_length; + uint32_t stop_bits_hw; + + if (cfg_new == NULL) { + return -EINVAL; + } + + if (cfg_new->baudrate == 0U) { + return -EINVAL; + } + + if (cfg_new->flow_ctrl != UART_CFG_FLOW_CTRL_NONE) { + return -ENOTSUP; + } + + switch (cfg_new->parity) { + case UART_CFG_PARITY_NONE: + parity_bits = USART_PM_NONE; + break; + case UART_CFG_PARITY_ODD: + parity_bits = USART_PM_ODD; + break; + case UART_CFG_PARITY_EVEN: + parity_bits = USART_PM_EVEN; + break; + default: + return -EINVAL; + } + + switch (cfg_new->data_bits) { + case UART_CFG_DATA_BITS_8: + case UART_CFG_DATA_BITS_7: + break; + default: + return -EINVAL; + } + + if (cfg_new->data_bits == UART_CFG_DATA_BITS_7 && cfg_new->parity == UART_CFG_PARITY_NONE) { + return -EINVAL; + } + + /* Map word length depending on requested data bits and parity */ + if (cfg_new->parity == UART_CFG_PARITY_NONE) { + /* 8N* uses 8-bit word length */ + word_length = USART_WL_8BIT; + } else { + /* With parity: 8 data bits -> 9-bit word length, 7 data bits -> 8-bit */ + word_length = (cfg_new->data_bits == UART_CFG_DATA_BITS_8) ? USART_WL_9BIT + : USART_WL_8BIT; + } + + switch (cfg_new->stop_bits) { + case UART_CFG_STOP_BITS_1: + stop_bits_hw = USART_STB_1BIT; + break; + case UART_CFG_STOP_BITS_2: + stop_bits_hw = USART_STB_2BIT; + break; + default: + return -EINVAL; + } + + if (data->baud_rate == cfg_new->baudrate && data->parity == cfg_new->parity && + data->data_bits == cfg_new->data_bits && data->stop_bits == cfg_new->stop_bits && + data->flow_ctrl == cfg_new->flow_ctrl) { + return 0; + } + + unsigned int key = irq_lock(); + + usart_disable(cfg->reg); + + usart_parity_config(cfg->reg, parity_bits); + usart_word_length_set(cfg->reg, word_length); + usart_stop_bit_set(cfg->reg, stop_bits_hw); + usart_baudrate_set(cfg->reg, cfg_new->baudrate); + + usart_receive_config(cfg->reg, USART_RECEIVE_ENABLE); + usart_transmit_config(cfg->reg, USART_TRANSMIT_ENABLE); + usart_enable(cfg->reg); + + irq_unlock(key); + + data->baud_rate = cfg_new->baudrate; + data->parity = cfg_new->parity; + data->data_bits = cfg_new->data_bits; + data->stop_bits = cfg_new->stop_bits; + data->flow_ctrl = cfg_new->flow_ctrl; + + return 0; +} + +static int usart_gd32_config_get(const struct device *dev, struct uart_config *cfg_out) +{ + struct gd32_usart_data *const data = dev->data; + + if (cfg_out == NULL) { + return -EINVAL; + } + + if (!data->initialized) { + return -ENODEV; + } + + cfg_out->baudrate = data->baud_rate; + cfg_out->parity = data->parity; + cfg_out->stop_bits = data->stop_bits; + cfg_out->data_bits = data->data_bits; + cfg_out->flow_ctrl = data->flow_ctrl; + + return 0; +} +#endif /* CONFIG_UART_USE_RUNTIME_CONFIGURE */ + #ifdef CONFIG_UART_INTERRUPT_DRIVEN int usart_gd32_fifo_fill(const struct device *dev, const uint8_t *tx_data, int len) @@ -288,6 +423,10 @@ static DEVICE_API(uart, usart_gd32_driver_api) = { .poll_in = usart_gd32_poll_in, .poll_out = usart_gd32_poll_out, .err_check = usart_gd32_err_check, +#ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE + .configure = usart_gd32_configure, + .config_get = usart_gd32_config_get, +#endif /* CONFIG_UART_USE_RUNTIME_CONFIGURE */ #ifdef CONFIG_UART_INTERRUPT_DRIVEN .fifo_fill = usart_gd32_fifo_fill, .fifo_read = usart_gd32_fifo_read, From b788fbd9648911f6176d2531e4efa5376769bfd4 Mon Sep 17 00:00:00 2001 From: Aleksandr Senin Date: Sat, 27 Dec 2025 17:56:05 +0300 Subject: [PATCH 1491/3659] tests: uart: add GD32 build-only scenario Add a build-only scenario that enables UART runtime configure and builds on selected GD32 boards to ensure the driver compiles. Signed-off-by: Aleksandr Senin --- tests/drivers/uart/uart_elementary/testcase.yaml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/drivers/uart/uart_elementary/testcase.yaml b/tests/drivers/uart/uart_elementary/testcase.yaml index c61feff2d146..7de614defbaf 100644 --- a/tests/drivers/uart/uart_elementary/testcase.yaml +++ b/tests/drivers/uart/uart_elementary/testcase.yaml @@ -114,3 +114,12 @@ tests: extra_configs: - CONFIG_NRF_SYS_EVENT=y - CONFIG_SOC_NRF_FORCE_CONSTLAT=y + drivers.uart.uart_elementary.build_gd32: + build_only: true + harness: "" + depends_on: [] + platform_allow: + - gd32f470i_eval + extra_configs: + - CONFIG_SERIAL=y + - CONFIG_UART_USE_RUNTIME_CONFIGURE=y From 43d3387634e59a0aa10880d4f60dda0374c1d2b5 Mon Sep 17 00:00:00 2001 From: Tim Pambor Date: Fri, 9 Jan 2026 10:33:48 +0100 Subject: [PATCH 1492/3659] net: http_server: clarify naming of HTTP server callback status enum Rename enum http_data_status to enum http_transaction_status to better reflect its purpose, which is to indicate the status of the overall HTTP transaction, not just data transfer. Signed-off-by: Tim Pambor --- .../networking/api/http_server.rst | 24 ++++++++--------- doc/releases/migration-guide-4.4.rst | 12 +++++++++ include/zephyr/net/http/server.h | 10 +++---- samples/net/prometheus/src/main.c | 4 +-- samples/net/prometheus/src/stats.c | 4 +-- samples/net/sockets/http_server/src/main.c | 18 ++++++------- subsys/net/lib/http/headers/server_internal.h | 2 +- subsys/net/lib/http/http_server_core.c | 6 ++--- subsys/net/lib/http/http_server_http1.c | 13 ++++----- subsys/net/lib/http/http_server_http2.c | 27 ++++++++++--------- tests/net/lib/http_client/src/main.c | 6 ++--- tests/net/lib/http_server/core/src/main.c | 16 ++++++----- 12 files changed, 80 insertions(+), 62 deletions(-) diff --git a/doc/connectivity/networking/api/http_server.rst b/doc/connectivity/networking/api/http_server.rst index 40fe09f0ee18..ba58b18e222f 100644 --- a/doc/connectivity/networking/api/http_server.rst +++ b/doc/connectivity/networking/api/http_server.rst @@ -189,13 +189,13 @@ customised 404 response. .. code-block:: c - static int default_handler(struct http_client_ctx *client, enum http_data_status status, + static int default_handler(struct http_client_ctx *client, enum http_transaction_status status, const struct http_request_ctx *request_ctx, struct http_response_ctx *response_ctx, void *user_data) { static const char response_404[] = "Oops, page not found!"; - if (status == HTTP_SERVER_DATA_FINAL) { + if (status == HTTP_SERVER_REQUEST_DATA_FINAL) { response_ctx->status = 404; response_ctx->body = response_404; response_ctx->body_len = sizeof(response_404) - 1; @@ -331,7 +331,7 @@ resource handler, which echoes received data back to the client: .. code-block:: c - static int dyn_handler(struct http_client_ctx *client, enum http_data_status status, + static int dyn_handler(struct http_client_ctx *client, enum http_transaction_status status, const struct http_request_ctx *request_ctx, struct http_response_ctx *response_ctx, void *user_data) { @@ -342,7 +342,7 @@ resource handler, which echoes received data back to the client: __ASSERT_NO_MSG(buffer != NULL); - if (status == HTTP_SERVER_DATA_ABORTED) { + if (status == HTTP_SERVER_TRANSACTION_ABORTED) { LOG_DBG("Transaction aborted after %zd bytes.", processed); processed = 0; return 0; @@ -354,7 +354,7 @@ resource handler, which echoes received data back to the client: http_method_str(method), request_ctx->data_len); LOG_HEXDUMP_DBG(request_ctx->data, request_ctx->data_len, print_str); - if (status == HTTP_SERVER_DATA_FINAL) { + if (status == HTTP_SERVER_REQUEST_DATA_FINAL) { LOG_DBG("All data received (%zd bytes).", processed); processed = 0; } @@ -362,7 +362,7 @@ resource handler, which echoes received data back to the client: /* Echo data back to client */ response_ctx->body = request_ctx->data; response_ctx->body_len = request_ctx->data_len; - response_ctx->final_chunk = (status == HTTP_SERVER_DATA_FINAL); + response_ctx->final_chunk = (status == HTTP_SERVER_REQUEST_DATA_FINAL); return 0; } @@ -386,14 +386,14 @@ the application should be able to keep track of the received data progress. The ``status`` field informs the application about the progress in passing request payload from the server to the application. As long as the status -reports :c:enumerator:`HTTP_SERVER_DATA_MORE`, the application should expect +reports :c:enumerator:`HTTP_SERVER_REQUEST_DATA_MORE`, the application should expect more data to be provided in a consecutive callback calls. Once all request payload has been passed to the application, the server reports -:c:enumerator:`HTTP_SERVER_DATA_FINAL` status. In case of communication errors -during request processing (for example client closed the connection before +:c:enumerator:`HTTP_SERVER_REQUEST_DATA_FINAL` status. In case of communication +errors during request processing (for example client closed the connection before complete payload has been received), the server reports -:c:enumerator:`HTTP_SERVER_DATA_ABORTED`. Either of the two events indicate that -the application shall reset any progress recorded for the resource, and await +:c:enumerator:`HTTP_SERVER_TRANSACTION_ABORTED`. Either of the two events indicate +that the application shall reset any progress recorded for the resource, and await a new request to come. The server guarantees that the resource can only be accessed by single client at a time. @@ -488,7 +488,7 @@ from within the dynamic resource callback: HTTP_SERVER_REGISTER_HEADER_CAPTURE(capture_user_agent, "User-Agent"); - static int dyn_handler(struct http_client_ctx *client, enum http_data_status status, + static int dyn_handler(struct http_client_ctx *client, enum http_transaction_status status, uint8_t *buffer, size_t len, void *user_data) { size_t header_count = client->header_capture_ctx.count; diff --git a/doc/releases/migration-guide-4.4.rst b/doc/releases/migration-guide-4.4.rst index 370227487354..96945c16b67c 100644 --- a/doc/releases/migration-guide-4.4.rst +++ b/doc/releases/migration-guide-4.4.rst @@ -507,6 +507,18 @@ Networking code cannot use POSIX APIs, then the relevant network API prefix needs to be added to the code calling a network API. +* The enum for HTTP server transaction status has been renamed from ``http_data_status`` + to ``http_transaction_status`` to better reflect its purpose. The enum values have also been + renamed as follows: + + - ``HTTP_SERVER_DATA_ABORTED`` → ``HTTP_SERVER_TRANSACTION_ABORTED`` + - ``HTTP_SERVER_DATA_MORE`` → ``HTTP_SERVER_REQUEST_DATA_MORE`` + - ``HTTP_SERVER_DATA_FINAL`` → ``HTTP_SERVER_REQUEST_DATA_FINAL`` + + The handler callback type for dynamic resources has been updated accordingly to use the new enum + and its renamed values. Applications using dynamic HTTP resources must update their handler + callbacks to use the new enum and handle the renamed values. + Modem ***** diff --git a/include/zephyr/net/http/server.h b/include/zephyr/net/http/server.h index 461ac22187e6..903006e37693 100644 --- a/include/zephyr/net/http/server.h +++ b/include/zephyr/net/http/server.h @@ -171,13 +171,13 @@ struct http_content_type { struct http_client_ctx; /** Indicates the status of the currently processed piece of data. */ -enum http_data_status { +enum http_transaction_status { /** Transaction aborted, data incomplete. */ - HTTP_SERVER_DATA_ABORTED = -1, + HTTP_SERVER_TRANSACTION_ABORTED = -1, /** Transaction incomplete, more data expected. */ - HTTP_SERVER_DATA_MORE = 0, + HTTP_SERVER_REQUEST_DATA_MORE = 0, /** Final data fragment in current transaction. */ - HTTP_SERVER_DATA_FINAL = 1, + HTTP_SERVER_REQUEST_DATA_FINAL = 1, }; /** @brief Status of captured request headers */ @@ -227,7 +227,7 @@ struct http_response_ctx { * <0 error, close the connection. */ typedef int (*http_resource_dynamic_cb_t)(struct http_client_ctx *client, - enum http_data_status status, + enum http_transaction_status status, const struct http_request_ctx *request_ctx, struct http_response_ctx *response_ctx, void *user_data); diff --git a/samples/net/prometheus/src/main.c b/samples/net/prometheus/src/main.c index 735522d46b35..3850afbe2b02 100644 --- a/samples/net/prometheus/src/main.c +++ b/samples/net/prometheus/src/main.c @@ -41,14 +41,14 @@ static uint16_t test_http_service_port = CONFIG_NET_SAMPLE_HTTP_SERVER_SERVICE_P HTTP_SERVICE_DEFINE(test_http_service, CONFIG_NET_CONFIG_MY_IPV4_ADDR, &test_http_service_port, CONFIG_HTTP_SERVER_MAX_CLIENTS, 10, NULL, NULL, NULL); -static int dyn_handler(struct http_client_ctx *client, enum http_data_status status, +static int dyn_handler(struct http_client_ctx *client, enum http_transaction_status status, const struct http_request_ctx *request_ctx, struct http_response_ctx *response_ctx, void *user_data) { int ret; static uint8_t prom_buffer[256]; - if (status == HTTP_SERVER_DATA_FINAL) { + if (status == HTTP_SERVER_REQUEST_DATA_FINAL) { /* incrase counter per request */ prometheus_counter_inc(prom_context.counter); diff --git a/samples/net/prometheus/src/stats.c b/samples/net/prometheus/src/stats.c index 0028ebd1fafb..4adefbbb769e 100644 --- a/samples/net/prometheus/src/stats.c +++ b/samples/net/prometheus/src/stats.c @@ -31,14 +31,14 @@ static struct prometheus_counter *http_request_counter; static struct prometheus_collector *stats_collector; static struct prometheus_collector_walk_context walk_ctx; -static int stats_handler(struct http_client_ctx *client, enum http_data_status status, +static int stats_handler(struct http_client_ctx *client, enum http_transaction_status status, const struct http_request_ctx *request_ctx, struct http_response_ctx *response_ctx, void *user_data) { int ret; static uint8_t prom_buffer[1024]; - if (status == HTTP_SERVER_DATA_FINAL) { + if (status == HTTP_SERVER_REQUEST_DATA_FINAL) { /* incrase counter per request */ prometheus_counter_inc(http_request_counter); diff --git a/samples/net/sockets/http_server/src/main.c b/samples/net/sockets/http_server/src/main.c index ff2ec17ac250..e0a066b3a95c 100644 --- a/samples/net/sockets/http_server/src/main.c +++ b/samples/net/sockets/http_server/src/main.c @@ -72,7 +72,7 @@ static struct http_resource_detail_static main_js_gz_resource_detail = { .static_data_len = sizeof(main_js_gz), }; -static int echo_handler(struct http_client_ctx *client, enum http_data_status status, +static int echo_handler(struct http_client_ctx *client, enum http_transaction_status status, const struct http_request_ctx *request_ctx, struct http_response_ctx *response_ctx, void *user_data) { @@ -81,7 +81,7 @@ static int echo_handler(struct http_client_ctx *client, enum http_data_status st enum http_method method = client->method; static size_t processed; - if (status == HTTP_SERVER_DATA_ABORTED) { + if (status == HTTP_SERVER_TRANSACTION_ABORTED) { LOG_DBG("Transaction aborted after %zd bytes.", processed); processed = 0; return 0; @@ -95,7 +95,7 @@ static int echo_handler(struct http_client_ctx *client, enum http_data_status st request_ctx->data_len); LOG_HEXDUMP_DBG(request_ctx->data, request_ctx->data_len, print_str); - if (status == HTTP_SERVER_DATA_FINAL) { + if (status == HTTP_SERVER_REQUEST_DATA_FINAL) { LOG_DBG("All data received (%zd bytes).", processed); processed = 0; } @@ -103,7 +103,7 @@ static int echo_handler(struct http_client_ctx *client, enum http_data_status st /* Echo data back to client */ response_ctx->body = request_ctx->data; response_ctx->body_len = request_ctx->data_len; - response_ctx->final_chunk = (status == HTTP_SERVER_DATA_FINAL); + response_ctx->final_chunk = (status == HTTP_SERVER_REQUEST_DATA_FINAL); return 0; } @@ -117,7 +117,7 @@ static struct http_resource_detail_dynamic echo_resource_detail = { .user_data = NULL, }; -static int uptime_handler(struct http_client_ctx *client, enum http_data_status status, +static int uptime_handler(struct http_client_ctx *client, enum http_transaction_status status, const struct http_request_ctx *request_ctx, struct http_response_ctx *response_ctx, void *user_data) { @@ -129,7 +129,7 @@ static int uptime_handler(struct http_client_ctx *client, enum http_data_status /* A payload is not expected with the GET request. Ignore any data and wait until * final callback before sending response */ - if (status == HTTP_SERVER_DATA_FINAL) { + if (status == HTTP_SERVER_REQUEST_DATA_FINAL) { ret = snprintf(uptime_buf, sizeof(uptime_buf), "%" PRId64, k_uptime_get()); if (ret < 0) { LOG_ERR("Failed to snprintf uptime, err %d", ret); @@ -176,7 +176,7 @@ static void parse_led_post(uint8_t *buf, size_t len) } } -static int led_handler(struct http_client_ctx *client, enum http_data_status status, +static int led_handler(struct http_client_ctx *client, enum http_transaction_status status, const struct http_request_ctx *request_ctx, struct http_response_ctx *response_ctx, void *user_data) { @@ -185,7 +185,7 @@ static int led_handler(struct http_client_ctx *client, enum http_data_status sta LOG_DBG("LED handler status %d, size %zu", status, request_ctx->data_len); - if (status == HTTP_SERVER_DATA_ABORTED) { + if (status == HTTP_SERVER_TRANSACTION_ABORTED) { cursor = 0; return 0; } @@ -202,7 +202,7 @@ static int led_handler(struct http_client_ctx *client, enum http_data_status sta memcpy(post_payload_buf + cursor, request_ctx->data, request_ctx->data_len); cursor += request_ctx->data_len; - if (status == HTTP_SERVER_DATA_FINAL) { + if (status == HTTP_SERVER_REQUEST_DATA_FINAL) { parse_led_post(post_payload_buf, cursor); cursor = 0; } diff --git a/subsys/net/lib/http/headers/server_internal.h b/subsys/net/lib/http/headers/server_internal.h index 1cbd04b0d387..0bc80eff71c7 100644 --- a/subsys/net/lib/http/headers/server_internal.h +++ b/subsys/net/lib/http/headers/server_internal.h @@ -53,7 +53,7 @@ void http_server_get_content_type_from_extension(char *url, char *content_type, int http_server_find_file(char *fname, size_t fname_size, size_t *file_size, uint8_t supported_compression, enum http_compression *chosen_compression); void http_client_timer_restart(struct http_client_ctx *client); -bool http_response_is_final(struct http_response_ctx *rsp, enum http_data_status status); +bool http_response_is_final(struct http_response_ctx *rsp, enum http_transaction_status status); bool http_response_is_provided(struct http_response_ctx *rsp); /* TODO Could be static, but currently used in tests. */ diff --git a/subsys/net/lib/http/http_server_core.c b/subsys/net/lib/http/http_server_core.c index de8c22d22c45..2c96c2643c85 100644 --- a/subsys/net/lib/http/http_server_core.c +++ b/subsys/net/lib/http/http_server_core.c @@ -344,7 +344,7 @@ static void client_release_resources(struct http_client_ctx *client) populate_request_ctx(&request_ctx, NULL, 0, NULL); - dynamic_detail->cb(client, HTTP_SERVER_DATA_ABORTED, &request_ctx, + dynamic_detail->cb(client, HTTP_SERVER_TRANSACTION_ABORTED, &request_ctx, &response_ctx, dynamic_detail->user_data); } } @@ -909,9 +909,9 @@ int http_server_sendall(struct http_client_ctx *client, const void *buf, size_t return 0; } -bool http_response_is_final(struct http_response_ctx *rsp, enum http_data_status status) +bool http_response_is_final(struct http_response_ctx *rsp, enum http_transaction_status status) { - if (status != HTTP_SERVER_DATA_FINAL) { + if (status != HTTP_SERVER_REQUEST_DATA_FINAL) { return false; } diff --git a/subsys/net/lib/http/http_server_http1.c b/subsys/net/lib/http/http_server_http1.c index f958eb9f121c..938df36408cb 100644 --- a/subsys/net/lib/http/http_server_http1.c +++ b/subsys/net/lib/http/http_server_http1.c @@ -407,14 +407,14 @@ static int dynamic_get_del_req(struct http_resource_detail_dynamic *dynamic_deta { int ret, len; char *ptr; - enum http_data_status status; + enum http_transaction_status status; struct http_request_ctx request_ctx; struct http_response_ctx response_ctx; /* Start of GET params */ ptr = &client->url_buffer[dynamic_detail->common.path_len]; len = strlen(ptr); - status = HTTP_SERVER_DATA_FINAL; + status = HTTP_SERVER_REQUEST_DATA_FINAL; do { memset(&response_ctx, 0, sizeof(response_ctx)); @@ -453,7 +453,7 @@ static int dynamic_post_put_req(struct http_resource_detail_dynamic *dynamic_det { int ret; char *ptr = client->cursor; - enum http_data_status status; + enum http_transaction_status status; struct http_request_ctx request_ctx; struct http_response_ctx response_ctx; @@ -462,9 +462,9 @@ static int dynamic_post_put_req(struct http_resource_detail_dynamic *dynamic_det } if (client->parser_state == HTTP1_MESSAGE_COMPLETE_STATE) { - status = HTTP_SERVER_DATA_FINAL; + status = HTTP_SERVER_REQUEST_DATA_FINAL; } else { - status = HTTP_SERVER_DATA_MORE; + status = HTTP_SERVER_REQUEST_DATA_MORE; } memset(&response_ctx, 0, sizeof(response_ctx)); @@ -492,7 +492,8 @@ static int dynamic_post_put_req(struct http_resource_detail_dynamic *dynamic_det } /* Once all data is transferred to application, repeat cb until response is complete */ - while (!http_response_is_final(&response_ctx, status) && status == HTTP_SERVER_DATA_FINAL) { + while (!http_response_is_final(&response_ctx, status) && + status == HTTP_SERVER_REQUEST_DATA_FINAL) { memset(&response_ctx, 0, sizeof(response_ctx)); populate_request_ctx(&request_ctx, ptr, 0, &client->header_capture_ctx); diff --git a/subsys/net/lib/http/http_server_http2.c b/subsys/net/lib/http/http_server_http2.c index 771ada1e7419..41593005ac7a 100644 --- a/subsys/net/lib/http/http_server_http2.c +++ b/subsys/net/lib/http/http_server_http2.c @@ -557,12 +557,13 @@ static int handle_http2_static_fs_resource(struct http_resource_detail_static_fs #endif /* CONFIG_FILE_SYSTEM */ static int http2_dynamic_response(struct http_client_ctx *client, struct http2_frame *frame, - struct http_response_ctx *rsp, enum http_data_status data_status, + struct http_response_ctx *rsp, + enum http_transaction_status status, struct http_resource_detail_dynamic *dynamic_detail) { int ret; uint8_t flags = 0; - bool final_response = http_response_is_final(rsp, data_status); + bool final_response = http_response_is_final(rsp, status); if (client->current_stream->headers_sent && (rsp->header_count > 0 || rsp->status != 0)) { LOG_WRN("Already sent headers, dropping new headers and/or response code"); @@ -622,7 +623,7 @@ static int dynamic_get_del_req_v2(struct http_resource_detail_dynamic *dynamic_d int ret, len; char *ptr; struct http2_frame *frame = &client->current_frame; - enum http_data_status status; + enum http_transaction_status status; struct http_request_ctx request_ctx; struct http_response_ctx response_ctx; @@ -633,7 +634,7 @@ static int dynamic_get_del_req_v2(struct http_resource_detail_dynamic *dynamic_d /* Start of GET params */ ptr = &client->url_buffer[dynamic_detail->common.path_len]; len = strlen(ptr); - status = HTTP_SERVER_DATA_FINAL; + status = HTTP_SERVER_REQUEST_DATA_FINAL; do { memset(&response_ctx, 0, sizeof(response_ctx)); @@ -674,7 +675,7 @@ static int dynamic_post_put_req_v2(struct http_resource_detail_dynamic *dynamic_ int ret = 0; char *ptr = client->cursor; size_t data_len; - enum http_data_status status; + enum http_transaction_status status; struct http2_frame *frame = &client->current_frame; struct http_request_ctx request_ctx; struct http_response_ctx response_ctx; @@ -700,9 +701,9 @@ static int dynamic_post_put_req_v2(struct http_resource_detail_dynamic *dynamic_ if (frame->length == 0 && is_header_flag_set(frame->flags, HTTP2_FLAG_END_STREAM) && !headers_only) { - status = HTTP_SERVER_DATA_FINAL; + status = HTTP_SERVER_REQUEST_DATA_FINAL; } else { - status = HTTP_SERVER_DATA_MORE; + status = HTTP_SERVER_REQUEST_DATA_MORE; } memset(&response_ctx, 0, sizeof(response_ctx)); @@ -725,7 +726,8 @@ static int dynamic_post_put_req_v2(struct http_resource_detail_dynamic *dynamic_ } /* Once all data is transferred to application, repeat cb until response is complete */ - while (!http_response_is_final(&response_ctx, status) && status == HTTP_SERVER_DATA_FINAL) { + while (!http_response_is_final(&response_ctx, status) && + status == HTTP_SERVER_REQUEST_DATA_FINAL) { memset(&response_ctx, 0, sizeof(response_ctx)); populate_request_ctx(&request_ctx, ptr, 0, request_headers_ctx); @@ -751,7 +753,8 @@ static int dynamic_post_put_req_v2(struct http_resource_detail_dynamic *dynamic_ memset(&response_ctx, 0, sizeof(response_ctx)); response_ctx.final_chunk = true; ret = http2_dynamic_response(client, frame, &response_ctx, - HTTP_SERVER_DATA_FINAL, dynamic_detail); + HTTP_SERVER_REQUEST_DATA_FINAL, + dynamic_detail); } if (ret < 0) { @@ -1492,7 +1495,7 @@ static int handle_http_frame_headers_end_stream(struct http_client_ctx *client) memset(&response_ctx, 0, sizeof(response_ctx)); populate_request_ctx(&request_ctx, NULL, 0, NULL); - ret = dynamic_detail->cb(client, HTTP_SERVER_DATA_FINAL, &request_ctx, + ret = dynamic_detail->cb(client, HTTP_SERVER_REQUEST_DATA_FINAL, &request_ctx, &response_ctx, dynamic_detail->user_data); if (ret < 0) { dynamic_detail->holder = NULL; @@ -1502,8 +1505,8 @@ static int handle_http_frame_headers_end_stream(struct http_client_ctx *client) /* Force end stream */ response_ctx.final_chunk = true; - ret = http2_dynamic_response(client, frame, &response_ctx, HTTP_SERVER_DATA_FINAL, - dynamic_detail); + ret = http2_dynamic_response(client, frame, &response_ctx, + HTTP_SERVER_REQUEST_DATA_FINAL, dynamic_detail); dynamic_detail->holder = NULL; if (ret < 0) { diff --git a/tests/net/lib/http_client/src/main.c b/tests/net/lib/http_client/src/main.c index 251e446c953a..b9662a8a264d 100644 --- a/tests/net/lib/http_client/src/main.c +++ b/tests/net/lib/http_client/src/main.c @@ -32,13 +32,13 @@ HTTP_RESOURCE_DEFINE(static_resource, test_http_service, "/static", static uint8_t dynamic_buf[TEST_BUF_SIZE]; static size_t dynamic_len; -static int dynamic_cb(struct http_client_ctx *client, enum http_data_status status, +static int dynamic_cb(struct http_client_ctx *client, enum http_transaction_status status, const struct http_request_ctx *request_ctx, struct http_response_ctx *response_ctx, void *user_data) { static size_t offset; - if (status == HTTP_SERVER_DATA_ABORTED) { + if (status == HTTP_SERVER_TRANSACTION_ABORTED) { offset = 0; return 0; } @@ -60,7 +60,7 @@ static int dynamic_cb(struct http_client_ctx *client, enum http_data_status stat offset += request_ctx->data_len; } - if (status == HTTP_SERVER_DATA_FINAL) { + if (status == HTTP_SERVER_REQUEST_DATA_FINAL) { /* All data received, reset progress. */ dynamic_len = offset; offset = 0; diff --git a/tests/net/lib/http_server/core/src/main.c b/tests/net/lib/http_server/core/src/main.c index 9abaaa435497..c9074be93ff5 100644 --- a/tests/net/lib/http_server/core/src/main.c +++ b/tests/net/lib/http_server/core/src/main.c @@ -253,13 +253,13 @@ static uint8_t dynamic_payload[32]; static size_t dynamic_payload_len = sizeof(dynamic_payload); static bool dynamic_error; -static int dynamic_cb(struct http_client_ctx *client, enum http_data_status status, +static int dynamic_cb(struct http_client_ctx *client, enum http_transaction_status status, const struct http_request_ctx *request_ctx, struct http_response_ctx *response_ctx, void *user_data) { static size_t offset; - if (status == HTTP_SERVER_DATA_ABORTED) { + if (status == HTTP_SERVER_TRANSACTION_ABORTED) { offset = 0; return 0; } @@ -291,7 +291,7 @@ static int dynamic_cb(struct http_client_ctx *client, enum http_data_status stat offset += request_ctx->data_len; } - if (status == HTTP_SERVER_DATA_FINAL) { + if (status == HTTP_SERVER_REQUEST_DATA_FINAL) { /* All data received, reset progress. */ dynamic_payload_len = offset; offset = 0; @@ -327,7 +327,8 @@ struct test_headers_clone { enum http_header_status status; }; -static int dynamic_request_headers_cb(struct http_client_ctx *client, enum http_data_status status, +static int dynamic_request_headers_cb(struct http_client_ctx *client, + enum http_transaction_status status, const struct http_request_ctx *request_ctx, struct http_response_ctx *response_ctx, void *user_data) { @@ -425,7 +426,8 @@ enum dynamic_response_headers_variant { static uint8_t dynamic_response_headers_variant; static uint8_t dynamic_response_headers_buffer[sizeof(long_payload)]; -static int dynamic_response_headers_cb(struct http_client_ctx *client, enum http_data_status status, +static int dynamic_response_headers_cb(struct http_client_ctx *client, + enum http_transaction_status status, const struct http_request_ctx *request_ctx, struct http_response_ctx *response_ctx, void *user_data) { @@ -440,7 +442,7 @@ static int dynamic_response_headers_cb(struct http_client_ctx *client, enum http {.name = "Content-Type", .value = "application/json"}, }; - if (status != HTTP_SERVER_DATA_FINAL && + if (status != HTTP_SERVER_REQUEST_DATA_FINAL && dynamic_response_headers_variant != DYNAMIC_RESPONSE_HEADERS_VARIANT_BODY_LONG) { /* Long body variant is the only one which needs to take some action before final * data has been received from server @@ -515,7 +517,7 @@ static int dynamic_response_headers_cb(struct http_client_ctx *client, enum http request_ctx->data_len); offset += request_ctx->data_len; - if (status == HTTP_SERVER_DATA_FINAL) { + if (status == HTTP_SERVER_REQUEST_DATA_FINAL) { offset = 0; } } else { From d40c003513ecfe818b4a69c8f36502c1d5aeabb4 Mon Sep 17 00:00:00 2001 From: Tim Pambor Date: Fri, 9 Jan 2026 10:19:55 +0100 Subject: [PATCH 1493/3659] net: http_server: Add transaction complete status When the response has been sent completely to the client, the server reports the new `HTTP_SERVER_TRANSACTION_COMPLETE` status. Together with the existing `HTTP_SERVER_TRANSACTION_ABORTED` status, the application can now also for successful completions of requests clean up any resources allocated for handling the request. This especially allows to dynamically allocate the response buffer passed to the server in the request callback and free it when the request is done. Signed-off-by: Tim Pambor --- .../networking/api/http_server.rst | 14 ++++++--- doc/releases/migration-guide-4.4.rst | 5 ++++ include/zephyr/net/http/server.h | 7 ++++- samples/net/sockets/http_server/src/main.c | 10 +++++-- subsys/net/lib/http/http_server_http1.c | 16 ++++++++-- subsys/net/lib/http/http_server_http2.c | 30 ++++++++++++++++++- tests/net/lib/http_client/src/main.c | 3 +- tests/net/lib/http_server/core/src/main.c | 28 ++++++++++++++++- 8 files changed, 100 insertions(+), 13 deletions(-) diff --git a/doc/connectivity/networking/api/http_server.rst b/doc/connectivity/networking/api/http_server.rst index ba58b18e222f..e7d1b4001d6b 100644 --- a/doc/connectivity/networking/api/http_server.rst +++ b/doc/connectivity/networking/api/http_server.rst @@ -342,8 +342,11 @@ resource handler, which echoes received data back to the client: __ASSERT_NO_MSG(buffer != NULL); - if (status == HTTP_SERVER_TRANSACTION_ABORTED) { - LOG_DBG("Transaction aborted after %zd bytes.", processed); + if (status == HTTP_SERVER_TRANSACTION_ABORTED || + status == HTTP_SERVER_TRANSACTION_COMPLETE) { + if (status == HTTP_SERVER_TRANSACTION_ABORTED) { + LOG_DBG("Transaction aborted after %zd bytes.", processed); + } processed = 0; return 0; } @@ -392,8 +395,11 @@ Once all request payload has been passed to the application, the server reports :c:enumerator:`HTTP_SERVER_REQUEST_DATA_FINAL` status. In case of communication errors during request processing (for example client closed the connection before complete payload has been received), the server reports -:c:enumerator:`HTTP_SERVER_TRANSACTION_ABORTED`. Either of the two events indicate -that the application shall reset any progress recorded for the resource, and await +:c:enumerator:`HTTP_SERVER_TRANSACTION_ABORTED`. +When the response has been sent completely to the client, the server reports +:c:enumerator:`HTTP_SERVER_TRANSACTION_COMPLETE` status. +Either of the two events indicate that the request processing is finished, and +the application shall reset any progress recorded for the resource, and await a new request to come. The server guarantees that the resource can only be accessed by single client at a time. diff --git a/doc/releases/migration-guide-4.4.rst b/doc/releases/migration-guide-4.4.rst index 96945c16b67c..8fbe3e118f89 100644 --- a/doc/releases/migration-guide-4.4.rst +++ b/doc/releases/migration-guide-4.4.rst @@ -519,6 +519,11 @@ Networking and its renamed values. Applications using dynamic HTTP resources must update their handler callbacks to use the new enum and handle the renamed values. +* The HTTP server now reports for dynamic resources the ``HTTP_SERVER_TRANSACTION_COMPLETE`` + status when the response has been sent completely to the client. Applications should now also + handle this status in the handler callback to properly reset resource state after successful + response transmission. + Modem ***** diff --git a/include/zephyr/net/http/server.h b/include/zephyr/net/http/server.h index 903006e37693..2bae320b37a2 100644 --- a/include/zephyr/net/http/server.h +++ b/include/zephyr/net/http/server.h @@ -178,6 +178,8 @@ enum http_transaction_status { HTTP_SERVER_REQUEST_DATA_MORE = 0, /** Final data fragment in current transaction. */ HTTP_SERVER_REQUEST_DATA_FINAL = 1, + /** Transaction completed, response sent completely. */ + HTTP_SERVER_TRANSACTION_COMPLETE = 2, }; /** @brief Status of captured request headers */ @@ -218,7 +220,10 @@ struct http_response_ctx { * can be specified. * * @param client HTTP context information for this client connection. - * @param status HTTP data status, indicate whether more data is expected or not. + * @param status HTTP transaction status, HTTP_SERVER_REQUEST_DATA_MORE and + * HTTP_SERVER_REQUEST_DATA_FINAL describe the request-body delivery progress. + * HTTP_SERVER_TRANSACTION_ABORTED and HTTP_SERVER_TRANSACTION_COMPLETE are + * terminal notifications. * @param request_ctx Request context structure containing HTTP request data that was received. * @param response_ctx Response context structure for application to populate with response data. * @param user_data User specified data. diff --git a/samples/net/sockets/http_server/src/main.c b/samples/net/sockets/http_server/src/main.c index e0a066b3a95c..b0799cc0924d 100644 --- a/samples/net/sockets/http_server/src/main.c +++ b/samples/net/sockets/http_server/src/main.c @@ -81,8 +81,11 @@ static int echo_handler(struct http_client_ctx *client, enum http_transaction_st enum http_method method = client->method; static size_t processed; - if (status == HTTP_SERVER_TRANSACTION_ABORTED) { - LOG_DBG("Transaction aborted after %zd bytes.", processed); + if (status == HTTP_SERVER_TRANSACTION_ABORTED || + status == HTTP_SERVER_TRANSACTION_COMPLETE) { + if (status == HTTP_SERVER_TRANSACTION_ABORTED) { + LOG_DBG("Transaction aborted after %zd bytes.", processed); + } processed = 0; return 0; } @@ -185,7 +188,8 @@ static int led_handler(struct http_client_ctx *client, enum http_transaction_sta LOG_DBG("LED handler status %d, size %zu", status, request_ctx->data_len); - if (status == HTTP_SERVER_TRANSACTION_ABORTED) { + if (status == HTTP_SERVER_TRANSACTION_ABORTED || + status == HTTP_SERVER_TRANSACTION_COMPLETE) { cursor = 0; return 0; } diff --git a/subsys/net/lib/http/http_server_http1.c b/subsys/net/lib/http/http_server_http1.c index 938df36408cb..773031837bd3 100644 --- a/subsys/net/lib/http/http_server_http1.c +++ b/subsys/net/lib/http/http_server_http1.c @@ -435,8 +435,6 @@ static int dynamic_get_del_req(struct http_resource_detail_dynamic *dynamic_deta len = 0; } while (!http_response_is_final(&response_ctx, status)); - dynamic_detail->holder = NULL; - /* Only send the 0\r\n\r\n if the client is NOT HTTP/1.0 */ if (!is_client_http10(client)) { ret = http_server_sendall(client, final_chunk, sizeof(final_chunk) - 1); @@ -445,6 +443,14 @@ static int dynamic_get_del_req(struct http_resource_detail_dynamic *dynamic_deta } } + ret = dynamic_detail->cb(client, HTTP_SERVER_TRANSACTION_COMPLETE, &request_ctx, + &response_ctx, dynamic_detail->user_data); + if (ret < 0) { + return ret; + } + + dynamic_detail->holder = NULL; + return 0; } @@ -528,6 +534,12 @@ static int dynamic_post_put_req(struct http_resource_detail_dynamic *dynamic_det } } + ret = dynamic_detail->cb(client, HTTP_SERVER_TRANSACTION_COMPLETE, &request_ctx, + &response_ctx, dynamic_detail->user_data); + if (ret < 0) { + return ret; + } + dynamic_detail->holder = NULL; } diff --git a/subsys/net/lib/http/http_server_http2.c b/subsys/net/lib/http/http_server_http2.c index 41593005ac7a..295d591e9c0b 100644 --- a/subsys/net/lib/http/http_server_http2.c +++ b/subsys/net/lib/http/http_server_http2.c @@ -661,9 +661,16 @@ static int dynamic_get_del_req_v2(struct http_resource_detail_dynamic *dynamic_d HTTP2_FLAG_END_STREAM); if (ret < 0) { LOG_DBG("Cannot send last frame (%d)", ret); + return ret; } } + ret = dynamic_detail->cb(client, HTTP_SERVER_TRANSACTION_COMPLETE, &request_ctx, + &response_ctx, dynamic_detail->user_data); + if (ret < 0) { + return ret; + } + dynamic_detail->holder = NULL; return ret; @@ -759,10 +766,22 @@ static int dynamic_post_put_req_v2(struct http_resource_detail_dynamic *dynamic_ if (ret < 0) { LOG_DBG("Cannot send last frame (%d)", ret); + return ret; } client->current_stream->end_stream_sent = true; - dynamic_detail->holder = NULL; + + if (http_response_is_final(&response_ctx, status) && + status == HTTP_SERVER_REQUEST_DATA_FINAL) { + ret = dynamic_detail->cb(client, HTTP_SERVER_TRANSACTION_COMPLETE, + &request_ctx, &response_ctx, + dynamic_detail->user_data); + if (ret < 0) { + return ret; + } + + dynamic_detail->holder = NULL; + } } return ret; @@ -1507,6 +1526,15 @@ static int handle_http_frame_headers_end_stream(struct http_client_ctx *client) ret = http2_dynamic_response(client, frame, &response_ctx, HTTP_SERVER_REQUEST_DATA_FINAL, dynamic_detail); + + if (ret < 0) { + dynamic_detail->holder = NULL; + goto out; + } + + ret = dynamic_detail->cb(client, HTTP_SERVER_TRANSACTION_COMPLETE, &request_ctx, + &response_ctx, dynamic_detail->user_data); + dynamic_detail->holder = NULL; if (ret < 0) { diff --git a/tests/net/lib/http_client/src/main.c b/tests/net/lib/http_client/src/main.c index b9662a8a264d..70a146f3dae4 100644 --- a/tests/net/lib/http_client/src/main.c +++ b/tests/net/lib/http_client/src/main.c @@ -38,7 +38,8 @@ static int dynamic_cb(struct http_client_ctx *client, enum http_transaction_stat { static size_t offset; - if (status == HTTP_SERVER_TRANSACTION_ABORTED) { + if (status == HTTP_SERVER_TRANSACTION_ABORTED || + status == HTTP_SERVER_TRANSACTION_COMPLETE) { offset = 0; return 0; } diff --git a/tests/net/lib/http_server/core/src/main.c b/tests/net/lib/http_server/core/src/main.c index c9074be93ff5..c372f6c8b702 100644 --- a/tests/net/lib/http_server/core/src/main.c +++ b/tests/net/lib/http_server/core/src/main.c @@ -252,6 +252,7 @@ HTTP_RESOURCE_DEFINE(static_resource, test_http_service, "/", static uint8_t dynamic_payload[32]; static size_t dynamic_payload_len = sizeof(dynamic_payload); static bool dynamic_error; +static bool dynamic_complete; static int dynamic_cb(struct http_client_ctx *client, enum http_transaction_status status, const struct http_request_ctx *request_ctx, @@ -259,8 +260,14 @@ static int dynamic_cb(struct http_client_ctx *client, enum http_transaction_stat { static size_t offset; - if (status == HTTP_SERVER_TRANSACTION_ABORTED) { + if (status == HTTP_SERVER_TRANSACTION_ABORTED || + status == HTTP_SERVER_TRANSACTION_COMPLETE) { offset = 0; + if (status == HTTP_SERVER_TRANSACTION_COMPLETE) { + zassert_false(dynamic_complete, + "Transaction complete called multiple times"); + dynamic_complete = true; + } return 0; } @@ -337,6 +344,11 @@ static int dynamic_request_headers_cb(struct http_client_ctx *client, struct http_header *hdrs_dst; struct test_headers_clone *clone = (struct test_headers_clone *)user_data; + if (status == HTTP_SERVER_TRANSACTION_ABORTED || + status == HTTP_SERVER_TRANSACTION_COMPLETE) { + return 0; + } + if (request_ctx->header_count != 0) { /* Copy the captured header info to static buffer for later assertions in testcase. * Don't assume that the buffer inside client context remains valid after return @@ -442,6 +454,12 @@ static int dynamic_response_headers_cb(struct http_client_ctx *client, {.name = "Content-Type", .value = "application/json"}, }; + if (status == HTTP_SERVER_TRANSACTION_ABORTED || + status == HTTP_SERVER_TRANSACTION_COMPLETE) { + offset = 0; + return 0; + } + if (status != HTTP_SERVER_REQUEST_DATA_FINAL && dynamic_response_headers_variant != DYNAMIC_RESPONSE_HEADERS_VARIANT_BODY_LONG) { /* Long body variant is the only one which needs to take some action before final @@ -857,6 +875,7 @@ static void common_verify_http2_dynamic_post_request(const uint8_t *request, "Wrong dynamic resource length"); zassert_mem_equal(dynamic_payload, TEST_DYNAMIC_POST_PAYLOAD, dynamic_payload_len, "Wrong dynamic resource data"); + zassert_true(dynamic_complete, "Callback not called with transaction complete status"); } ZTEST(server_function_tests, test_http2_dynamic_post) @@ -911,6 +930,7 @@ static void common_verify_http1_dynamic_upgrade_post(const uint8_t *method) "Wrong dynamic resource length"); zassert_mem_equal(dynamic_payload, TEST_DYNAMIC_POST_PAYLOAD, dynamic_payload_len, "Wrong dynamic resource data"); + zassert_true(dynamic_complete, "Callback not called with transaction complete status"); } ZTEST(server_function_tests, test_http1_dynamic_upgrade_post) @@ -953,6 +973,7 @@ static void common_verify_http1_dynamic_post(const uint8_t *method) "Wrong dynamic resource length"); zassert_mem_equal(dynamic_payload, TEST_DYNAMIC_POST_PAYLOAD, dynamic_payload_len, "Wrong dynamic resource data"); + zassert_true(dynamic_complete, "Callback not called with transaction complete status"); } ZTEST(server_function_tests, test_http1_dynamic_post) @@ -979,6 +1000,7 @@ static void common_verify_http2_dynamic_get_request(const uint8_t *request, expect_http2_headers_frame(&offset, TEST_STREAM_ID_1, HTTP2_FLAG_END_HEADERS, NULL, 0); expect_http2_data_frame(&offset, TEST_STREAM_ID_1, TEST_DYNAMIC_GET_PAYLOAD, strlen(TEST_DYNAMIC_GET_PAYLOAD), HTTP2_FLAG_END_STREAM); + zassert_true(dynamic_complete, "Callback not called with transaction complete status"); } ZTEST(server_function_tests, test_http2_dynamic_get) @@ -1026,6 +1048,7 @@ ZTEST(server_function_tests, test_http1_dynamic_upgrade_get) expect_http2_headers_frame(&offset, UPGRADE_STREAM_ID, HTTP2_FLAG_END_HEADERS, NULL, 0); expect_http2_data_frame(&offset, UPGRADE_STREAM_ID, TEST_DYNAMIC_GET_PAYLOAD, strlen(TEST_DYNAMIC_GET_PAYLOAD), HTTP2_FLAG_END_STREAM); + zassert_true(dynamic_complete, "Callback not called with transaction complete status"); } ZTEST(server_function_tests, test_http1_dynamic_get) @@ -1057,6 +1080,7 @@ ZTEST(server_function_tests, test_http1_dynamic_get) test_read_data(&offset, sizeof(expected_response) - 1); zassert_mem_equal(buf, expected_response, sizeof(expected_response) - 1, "Received data doesn't match expected response"); + zassert_true(dynamic_complete, "Callback not called with transaction complete status"); } ZTEST(server_function_tests, test_http2_dynamic_put) @@ -1369,6 +1393,7 @@ ZTEST(server_function_tests, test_http2_post_trailing_headers) "Wrong dynamic resource length"); zassert_mem_equal(dynamic_payload, TEST_DYNAMIC_POST_PAYLOAD, dynamic_payload_len, "Wrong dynamic resource data"); + zassert_true(dynamic_complete, "Callback not called with transaction complete status"); } ZTEST(server_function_tests, test_http2_get_headers_with_padding) @@ -2799,6 +2824,7 @@ static void http_server_tests_before(void *fixture) memset(&request_headers_clone2, 0, sizeof(request_headers_clone2)); dynamic_payload_len = 0; dynamic_error = false; + dynamic_complete = false; ret = http_server_start(); if (ret < 0) { From d74087f58df06eb1938226ddd463732127957708 Mon Sep 17 00:00:00 2001 From: Anton Puppe Date: Fri, 12 Dec 2025 10:15:33 +0100 Subject: [PATCH 1494/3659] drivers: video: imx335: Add 2x2 binning support Adds support for switching the sensor resolution between all-pixel scan (2592x1944) and 2x2 binning (1296x972). This reduces the bandwidth and processing power requirements for applications that do not need the full resolution. It also paves the way for higher frame rates. Note that while the imx335 driver now supports dynamic resolution changes, some downstream components may not. The binning mode is enabled automatically if the correct format is selected. Signed-off-by: Anton Puppe --- drivers/video/imx335.c | 237 ++++++++++++++++++++++++++++++++++------- 1 file changed, 198 insertions(+), 39 deletions(-) diff --git a/drivers/video/imx335.c b/drivers/video/imx335.c index 1e2a7ef7bbf6..b253b8b0379f 100644 --- a/drivers/video/imx335.c +++ b/drivers/video/imx335.c @@ -21,11 +21,19 @@ LOG_MODULE_REGISTER(video_imx335, CONFIG_VIDEO_LOG_LEVEL); -#define IMX335_WIDTH 2592 -#define IMX335_HEIGHT 1944 +#define IMX335_NATIVE_WIDTH 2592 +#define IMX335_NATIVE_HEIGHT 1944 + +#define IMX335_BIN_2X2_WIDTH 1296 +#define IMX335_BIN_2X2_HEIGHT 972 #define IMX335_PIXEL_RATE 396000000 +enum imx335_res { + IMX335_RES_2592x1944, + IMX335_RES_1296x972, +}; + struct imx335_config { struct i2c_dt_spec i2c; #if DT_ANY_INST_HAS_PROP_STATUS_OKAY(reset_gpios) @@ -43,6 +51,7 @@ struct imx335_ctrls { struct imx335_data { struct imx335_ctrls ctrls; struct video_format fmt; + bool enabled; }; #define IMX335_REG8(addr) ((addr) | VIDEO_REG_ADDR16_DATA8) @@ -60,12 +69,15 @@ struct imx335_data { #define IMX335_HTRIMMING_START IMX335_REG16(0x302c) #define IMX335_HNUM IMX335_REG16(0x302e) #define IMX335_VMAX IMX335_REG24(0x3030) +#define IMX335_HMAX IMX335_REG16(0x3034) #define IMX335_VMAX_DEFAULT 4500 #define IMX335_OPB_SIZE_V IMX335_REG8(0x304c) #define IMX335_ADBIT IMX335_REG8(0x3050) #define IMX335_Y_OUT_SIZE IMX335_REG16(0x3056) #define IMX335_SHR0 IMX335_REG24(0x3058) #define IMX335_SHR0_MIN 9 +#define IMX335_SHR0_MIN_BINNING 17 +#define IMX335_AREA2_WIDTH_1 IMX335_REG16(0x3072) #define IMX335_AREA3_ST_ADR_1 IMX335_REG16(0x3074) #define IMX335_AREA3_WIDTH_1 IMX335_REG16(0x3076) #define IMX335_GAIN IMX335_REG16(0x30e8) @@ -76,17 +88,17 @@ struct imx335_data { #define IMX335_INCKSEL2_PLL_IF_GC IMX335_REG8(0x315a) #define IMX335_INCKSEL3 IMX335_REG8(0x3168) #define IMX335_INCKSEL4 IMX335_REG8(0x316a) +#define IMX335_HADD_VADD IMX335_REG8(0x3199) #define IMX335_MDBIT IMX335_REG8(0x319d) #define IMX335_XVS_XHS_DRV IMX335_REG8(0x31a1) +#define IMX335_TCYCLE IMX335_REG8(0x3300) #define IMX335_ADBIT1 IMX335_REG16(0x341c) #define IMX335_LANEMODE IMX335_REG8(0x3a01) static const struct video_reg imx335_init_params[] = { {IMX335_STANDBY, 0x01}, {IMX335_XMSTA, 0x00}, - {IMX335_WINMODE, 0x04}, {IMX335_HTRIMMING_START, 0x3c}, {IMX335_HNUM, 0x0a20}, - {IMX335_OPB_SIZE_V, 0x00}, {IMX335_Y_OUT_SIZE, 0x0798}, {IMX335_AREA3_ST_ADR_1, 0x00c8}, {IMX335_AREA3_WIDTH_1, 0x0f30}, @@ -164,6 +176,87 @@ static const struct video_reg16 imx335_fixed_regs[] = { {0x3a00, 0x01}, }; +static const struct video_reg imx335_bin_2x2[] = { + {IMX335_WINMODE, 0x01}, + {IMX335_Y_OUT_SIZE, 0x03D8}, + {IMX335_AREA2_WIDTH_1, 0x0030}, + {IMX335_AREA3_ST_ADR_1, 0x00A8}, + {IMX335_AREA3_WIDTH_1, 0x0F60}, + {IMX335_HADD_VADD, 0x30}, + {IMX335_TCYCLE, 0x01}, + /* Fixed regs for 2/2 binning */ + {IMX335_REG8(0x3078), 0x04}, + {IMX335_REG8(0x3079), 0xFD}, + {IMX335_REG8(0x307A), 0x04}, + {IMX335_REG8(0x307B), 0xFE}, + {IMX335_REG8(0x307C), 0x04}, + {IMX335_REG8(0x307D), 0xFB}, + {IMX335_REG8(0x307E), 0x04}, + {IMX335_REG8(0x307F), 0x02}, + {IMX335_REG8(0x3080), 0x04}, + {IMX335_REG8(0x3081), 0xFD}, + {IMX335_REG8(0x3082), 0x04}, + {IMX335_REG8(0x3083), 0xFE}, + {IMX335_REG8(0x3084), 0x04}, + {IMX335_REG8(0x3085), 0xFB}, + {IMX335_REG8(0x3086), 0x04}, + {IMX335_REG8(0x3087), 0x02}, + {IMX335_REG8(0x30A4), 0x77}, + {IMX335_REG8(0x30A8), 0x20}, + {IMX335_REG8(0x30A9), 0x00}, + {IMX335_REG8(0x30AC), 0x08}, + {IMX335_REG8(0x30AD), 0x08}, + {IMX335_REG8(0x30B0), 0x20}, + {IMX335_REG8(0x30B1), 0x00}, + {IMX335_REG8(0x30B4), 0x10}, + {IMX335_REG8(0x30B5), 0x10}, + {IMX335_REG16(0x30B6), 0x0000}, + {IMX335_REG16(0x3112), 0x0010}, + {IMX335_REG16(0x3116), 0x0010}, +}; + +/* Note that this only contains registers that need to be reset when switching away from + * 2x2 binning mode + */ +static const struct video_reg imx335_bin_none[] = { + {IMX335_WINMODE, 0x00}, + {IMX335_Y_OUT_SIZE, 0x07AC}, + {IMX335_AREA2_WIDTH_1, 0x0028}, + {IMX335_AREA3_ST_ADR_1, 0x00B0}, + {IMX335_AREA3_WIDTH_1, 0x0F58}, + {IMX335_HADD_VADD, 0x00}, + {IMX335_TCYCLE, 0x00}, + /* Reset fixed regs from binning to all-pixel scan */ + {IMX335_REG8(0x3078), 0x01}, + {IMX335_REG8(0x3079), 0x02}, + {IMX335_REG8(0x307A), 0xFF}, + {IMX335_REG8(0x307B), 0x02}, + {IMX335_REG8(0x307C), 0x00}, + {IMX335_REG8(0x307D), 0x00}, + {IMX335_REG8(0x307E), 0x00}, + {IMX335_REG8(0x307F), 0x00}, + {IMX335_REG8(0x3080), 0x01}, + {IMX335_REG8(0x3081), 0x02}, + {IMX335_REG8(0x3082), 0xFF}, + {IMX335_REG8(0x3083), 0x02}, + {IMX335_REG8(0x3084), 0x00}, + {IMX335_REG8(0x3085), 0x00}, + {IMX335_REG8(0x3086), 0x00}, + {IMX335_REG8(0x3087), 0x00}, + {IMX335_REG8(0x30A4), 0x33}, + {IMX335_REG8(0x30A8), 0x10}, + {IMX335_REG8(0x30A9), 0x04}, + {IMX335_REG8(0x30AC), 0x00}, + {IMX335_REG8(0x30AD), 0x00}, + {IMX335_REG8(0x30B0), 0x10}, + {IMX335_REG8(0x30B1), 0x08}, + {IMX335_REG8(0x30B4), 0x00}, + {IMX335_REG8(0x30B5), 0x00}, + {IMX335_REG16(0x30B6), 0x0000}, + {IMX335_REG16(0x3112), 0x0008}, + {IMX335_REG16(0x3116), 0x0008}, +}; + static const struct video_reg imx335_mode_2l_10b[] = { {IMX335_ADBIT, 0x00}, {IMX335_MDBIT, 0x00}, @@ -217,34 +310,29 @@ static const struct video_reg imx335_inck_6mhz[] = { }; static const struct video_format_cap imx335_fmts[] = { - { + /* all-pixel scan mode */ + [IMX335_RES_2592x1944] = { .pixelformat = VIDEO_PIX_FMT_SRGGB10P, - .width_min = IMX335_WIDTH, - .width_max = IMX335_WIDTH, - .height_min = IMX335_HEIGHT, - .height_max = IMX335_HEIGHT, + .width_min = IMX335_NATIVE_WIDTH, + .width_max = IMX335_NATIVE_WIDTH, + .height_min = IMX335_NATIVE_HEIGHT, + .height_max = IMX335_NATIVE_HEIGHT, + .width_step = 0, + .height_step = 0, + }, + /* 2x2 binning mode */ + [IMX335_RES_1296x972] = { + .pixelformat = VIDEO_PIX_FMT_SRGGB10P, + .width_min = IMX335_BIN_2X2_WIDTH, + .width_max = IMX335_BIN_2X2_WIDTH, + .height_min = IMX335_BIN_2X2_HEIGHT, + .height_max = IMX335_BIN_2X2_HEIGHT, .width_step = 0, .height_step = 0, }, {0} }; -static int imx335_set_fmt(const struct device *dev, struct video_format *fmt) -{ - /* - * Only support RGGB10 for now and resolution is fixed hence only check - * values here - */ - if (fmt->pixelformat != VIDEO_PIX_FMT_SRGGB10P || - fmt->width != IMX335_WIDTH || - fmt->height != IMX335_HEIGHT) { - LOG_ERR("Unsupported pixel format or resolution"); - return -ENOTSUP; - } - - return 0; -} - static int imx335_get_fmt(const struct device *dev, struct video_format *fmt) { struct imx335_data *drv_data = dev->data; @@ -263,15 +351,18 @@ static int imx335_get_caps(const struct device *dev, struct video_caps *caps) static int imx335_set_stream(const struct device *dev, bool enable, enum video_buf_type type) { const struct imx335_config *cfg = dev->config; + struct imx335_data *drv_data = dev->data; int ret; ret = video_write_cci_reg(&cfg->i2c, IMX335_STANDBY, enable ? IMX335_STANDBY_OPERATING : IMX335_STANDBY_STANDBY); - if (ret) { + if (ret < 0) { LOG_ERR("Failed to set standby register\n"); return ret; } + drv_data->enabled = enable; + k_sleep(K_USEC(20)); return 0; @@ -285,13 +376,13 @@ static int imx335_set_ctrl_gain(const struct device *dev) int ret; ret = video_write_cci_reg(&cfg->i2c, IMX335_REGHOLD, 1); - if (ret) { + if (ret < 0) { return ret; } /* Apply gain upon conversion to gain unit */ ret = video_write_cci_reg(&cfg->i2c, IMX335_GAIN, ctrls->gain.val / IMX335_GAIN_UNIT_MDB); - if (ret) { + if (ret < 0) { return ret; } @@ -306,14 +397,14 @@ static int imx335_set_ctrl_exposure(const struct device *dev) int ret; ret = video_write_cci_reg(&cfg->i2c, IMX335_REGHOLD, 1); - if (ret) { + if (ret < 0) { return ret; } /* Since we never update VMAX, we can use the default value directly */ ret = video_write_cci_reg(&cfg->i2c, IMX335_SHR0, IMX335_VMAX_DEFAULT - ctrls->exposure.val); - if (ret) { + if (ret < 0) { return ret; } @@ -332,6 +423,66 @@ static int imx335_set_ctrl(const struct device *dev, unsigned int cid) } } +static int imx335_set_fmt(const struct device *dev, struct video_format *fmt) +{ + struct imx335_data *drv_data = dev->data; + const struct imx335_config *cfg = dev->config; + struct imx335_ctrls *ctrls = &drv_data->ctrls; + int ret; + size_t fmt_idx; + + if (drv_data->enabled) { + LOG_ERR("Cannot set format while the stream is running"); + return -EBUSY; + } + + ret = video_format_caps_index(imx335_fmts, fmt, &fmt_idx); + if (ret < 0) { + LOG_ERR("Unsupported pixel format or resolution"); + return ret; + } + + if (fmt_idx == IMX335_RES_2592x1944) { + /* Full resolution */ + + ret = video_write_cci_multiregs(&cfg->i2c, imx335_bin_none, + ARRAY_SIZE(imx335_bin_none)); + if (ret < 0) { + LOG_ERR("Failed to disable binning"); + return ret; + } + + ctrls->exposure.range.max = IMX335_VMAX_DEFAULT - IMX335_SHR0_MIN; + ctrls->exposure.range.def = IMX335_VMAX_DEFAULT - IMX335_SHR0_MIN; + } else if (fmt_idx == IMX335_RES_1296x972) { + /* 2x2 binning mode */ + + LOG_DBG("2x2 binning mode active"); + ret = video_write_cci_multiregs(&cfg->i2c, imx335_bin_2x2, + ARRAY_SIZE(imx335_bin_2x2)); + if (ret < 0) { + LOG_ERR("Failed to enable binning"); + return ret; + } + + ctrls->exposure.range.max = IMX335_VMAX_DEFAULT - IMX335_SHR0_MIN_BINNING; + ctrls->exposure.range.def = IMX335_VMAX_DEFAULT - IMX335_SHR0_MIN_BINNING; + + /* update exposure, since the upper limit is lower if binning is active */ + ctrls->exposure.val = MIN(ctrls->exposure.range.max, ctrls->exposure.val); + ret = imx335_set_ctrl_exposure(dev); + if (ret < 0) { + LOG_ERR("Failed to update exposure while enabling binning"); + return ret; + } + } + + drv_data->fmt.width = fmt->width; + drv_data->fmt.height = fmt->height; + + return 0; +} + static int imx335_get_frmival(const struct device *dev, struct video_frmival *frmival) { /* Only 30fps is supported right now */ @@ -413,7 +564,7 @@ static int imx335_init_controls(const struct device *dev) .max = IMX335_GAIN_MAX, .step = IMX335_GAIN_UNIT_MDB, .def = 0}); - if (ret) { + if (ret < 0) { return ret; } @@ -424,7 +575,7 @@ static int imx335_init_controls(const struct device *dev) .max = IMX335_VMAX_DEFAULT - IMX335_SHR0_MIN, .step = 1, .def = IMX335_VMAX_DEFAULT - IMX335_SHR0_MIN}); - if (ret) { + if (ret < 0) { return ret; } @@ -440,6 +591,7 @@ static int imx335_init_controls(const struct device *dev) static int imx335_init(const struct device *dev) { const struct imx335_config *cfg = dev->config; + struct imx335_data *drv_data = dev->data; int ret; if (!device_is_ready(cfg->i2c.bus)) { @@ -457,7 +609,7 @@ static int imx335_init(const struct device *dev) /* Power up sequence */ ret = gpio_pin_configure_dt(&cfg->reset_gpio, GPIO_OUTPUT_ACTIVE); - if (ret) { + if (ret < 0) { return ret; } @@ -472,7 +624,7 @@ static int imx335_init(const struct device *dev) /* Initialize register values */ ret = video_write_cci_multiregs(&cfg->i2c, imx335_init_params, ARRAY_SIZE(imx335_init_params)); - if (ret) { + if (ret < 0) { LOG_ERR("Unable to initialize the sensor"); return ret; } @@ -480,21 +632,27 @@ static int imx335_init(const struct device *dev) /* Apply the fixed value registers */ ret = video_write_cci_multiregs16(&cfg->i2c, imx335_fixed_regs, ARRAY_SIZE(imx335_fixed_regs)); - if (ret) { + if (ret < 0) { LOG_ERR("Unable to initialize the sensor"); return ret; } + ret = imx335_set_fmt(dev, &drv_data->fmt); + if (ret < 0) { + LOG_ERR("Unable to apply format"); + return ret; + } + /* TODO - Only 10bit - 2 data lanes mode is supported for the time being */ ret = video_write_cci_multiregs(&cfg->i2c, imx335_mode_2l_10b, ARRAY_SIZE(imx335_mode_2l_10b)); - if (ret) { + if (ret < 0) { LOG_ERR("Unable to initialize the sensor"); return ret; } ret = imx335_set_input_clk(dev, cfg->input_clk); - if (ret) { + if (ret < 0) { LOG_ERR("Unable to configure INCK"); return ret; } @@ -512,9 +670,10 @@ static int imx335_init(const struct device *dev) static struct imx335_data imx335_data_##n = { \ .fmt = { \ .pixelformat = VIDEO_PIX_FMT_SRGGB10P, \ - .width = IMX335_WIDTH, \ - .height = IMX335_HEIGHT, \ + .width = IMX335_NATIVE_WIDTH, \ + .height = IMX335_NATIVE_HEIGHT, \ }, \ + .enabled = false, \ }; \ static const struct imx335_config imx335_cfg_##n = { \ .i2c = I2C_DT_SPEC_INST_GET(n), \ From 264a01f832220077992b925af4c4bc4f83ce2197 Mon Sep 17 00:00:00 2001 From: Anton Puppe Date: Fri, 12 Dec 2025 11:08:27 +0100 Subject: [PATCH 1495/3659] drivers: video: imx335: Add configurable refresh rate Adds support for video_set_frmival for the IMX335 sensor driver. The available framerates depend on whether the binning mode is enabled. Currently, 25Hz and 30Hz are always available and 50Hz/60Hz only with binning. Signed-off-by: Anton Puppe --- drivers/video/imx335.c | 100 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 93 insertions(+), 7 deletions(-) diff --git a/drivers/video/imx335.c b/drivers/video/imx335.c index b253b8b0379f..e4fe33330914 100644 --- a/drivers/video/imx335.c +++ b/drivers/video/imx335.c @@ -34,6 +34,13 @@ enum imx335_res { IMX335_RES_1296x972, }; +enum imx335_framerate { + IMX335_25_FPS, + IMX335_30_FPS, + IMX335_50_FPS, + IMX335_60_FPS, +}; + struct imx335_config { struct i2c_dt_spec i2c; #if DT_ANY_INST_HAS_PROP_STATUS_OKAY(reset_gpios) @@ -51,6 +58,7 @@ struct imx335_ctrls { struct imx335_data { struct imx335_ctrls ctrls; struct video_format fmt; + uint32_t frame_rate; bool enabled; }; @@ -333,6 +341,13 @@ static const struct video_format_cap imx335_fmts[] = { {0} }; +static const uint32_t imx335_framerates[] = { + [IMX335_25_FPS] = 25, + [IMX335_30_FPS] = 30, + [IMX335_50_FPS] = 50, + [IMX335_60_FPS] = 60, +}; + static int imx335_get_fmt(const struct device *dev, struct video_format *fmt) { struct imx335_data *drv_data = dev->data; @@ -423,6 +438,62 @@ static int imx335_set_ctrl(const struct device *dev, unsigned int cid) } } +static int imx335_set_frmival(const struct device *dev, struct video_frmival *frmival) +{ + const struct imx335_config *cfg = dev->config; + struct imx335_data *drv_data = dev->data; + int ret; + + struct video_frmival_enum match = { + .format = &drv_data->fmt, + .type = VIDEO_FRMIVAL_TYPE_DISCRETE, + .discrete = *frmival, + }; + video_closest_frmival(dev, &match); + + uint16_t hmax; + + switch (match.index) { + case IMX335_25_FPS: + hmax = (drv_data->fmt.width == IMX335_BIN_2X2_WIDTH + && drv_data->fmt.height == IMX335_BIN_2X2_HEIGHT) ? 0x0280 : 0x0294; + break; + case IMX335_30_FPS: + hmax = 0x0226; + break; + case IMX335_50_FPS: + hmax = 0x0140; + break; + case IMX335_60_FPS: + hmax = 0x0113; + break; + default: + CODE_UNREACHABLE; + } + + /* use REGHOLD to ensure that our change is applied consistently */ + ret = video_write_cci_reg(&cfg->i2c, IMX335_REGHOLD, 1); + if (ret < 0) { + return ret; + } + + ret = video_write_cci_reg(&cfg->i2c, IMX335_HMAX, hmax); + if (ret < 0) { + return ret; + } + + ret = video_write_cci_reg(&cfg->i2c, IMX335_REGHOLD, 0); + if (ret < 0) { + return ret; + } + + frmival->numerator = 1; + frmival->denominator = imx335_framerates[match.index]; + drv_data->frame_rate = imx335_framerates[match.index]; + + return 0; +} + static int imx335_set_fmt(const struct device *dev, struct video_format *fmt) { struct imx335_data *drv_data = dev->data; @@ -479,28 +550,43 @@ static int imx335_set_fmt(const struct device *dev, struct video_format *fmt) drv_data->fmt.width = fmt->width; drv_data->fmt.height = fmt->height; + /* update framerate, since the timing and allowed framerates may have changed */ + struct video_frmival frmival = { + .numerator = 1, + .denominator = drv_data->frame_rate, + }; - return 0; + return imx335_set_frmival(dev, &frmival); } static int imx335_get_frmival(const struct device *dev, struct video_frmival *frmival) { - /* Only 30fps is supported right now */ + struct imx335_data *drv_data = dev->data; + frmival->numerator = 1; - frmival->denominator = 30; + frmival->denominator = drv_data->frame_rate; return 0; } static int imx335_enum_frmival(const struct device *dev, struct video_frmival_enum *fie) { - if (fie->index > 0) { + size_t fmt_idx; + int ret; + + ret = video_format_caps_index(imx335_fmts, fie->format, &fmt_idx); + if (ret < 0) { + return ret; + } + + if ((fmt_idx == IMX335_RES_2592x1944 && fie->index > IMX335_30_FPS) + || (fmt_idx == IMX335_RES_1296x972 && fie->index > IMX335_60_FPS)) { return -EINVAL; } fie->type = VIDEO_FRMIVAL_TYPE_DISCRETE; fie->discrete.numerator = 1; - fie->discrete.denominator = 30; + fie->discrete.denominator = imx335_framerates[fie->index]; return 0; } @@ -511,8 +597,7 @@ static DEVICE_API(video, imx335_driver_api) = { .get_caps = imx335_get_caps, .set_stream = imx335_set_stream, .set_ctrl = imx335_set_ctrl, - /* frmival is fixed, hence set/get_frmival both return 30fps */ - .set_frmival = imx335_get_frmival, + .set_frmival = imx335_set_frmival, .get_frmival = imx335_get_frmival, .enum_frmival = imx335_enum_frmival, }; @@ -673,6 +758,7 @@ static int imx335_init(const struct device *dev) .width = IMX335_NATIVE_WIDTH, \ .height = IMX335_NATIVE_HEIGHT, \ }, \ + .frame_rate = 30, \ .enabled = false, \ }; \ static const struct imx335_config imx335_cfg_##n = { \ From 4cd4b75159133b8fee4c2da5712778913d0734c1 Mon Sep 17 00:00:00 2001 From: Anton Puppe Date: Fri, 12 Dec 2025 11:20:59 +0100 Subject: [PATCH 1496/3659] samples: video: capture: Add option to allow shell and capture together Add Kconfig option VIDEO_SHELL_AND_CAPTURE to allow the capture to run even if the video shell is enabled. Also, add delta time between frames to log output. This enables testing of on-the-fly framerate changes. Signed-off-by: Anton Puppe --- samples/drivers/video/capture/Kconfig | 7 +++++++ samples/drivers/video/capture/README.rst | 18 ++++++++++-------- samples/drivers/video/capture/src/main.c | 11 +++++++---- 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/samples/drivers/video/capture/Kconfig b/samples/drivers/video/capture/Kconfig index 362a6037a6cf..1a90f38b3729 100644 --- a/samples/drivers/video/capture/Kconfig +++ b/samples/drivers/video/capture/Kconfig @@ -58,6 +58,13 @@ config VIDEO_CTRL_VFLIP help If set, mirror the video frame vertically +config VIDEO_SHELL_AND_CAPTURE + bool "Capture video even if the video shell is enabled" + depends on VIDEO_SHELL + default n + help + If set, the video capture is enabled even if the video shell is also enabled. + endmenu source "Kconfig.zephyr" diff --git a/samples/drivers/video/capture/README.rst b/samples/drivers/video/capture/README.rst index c8768bc50f68..1d418e8a8dab 100644 --- a/samples/drivers/video/capture/README.rst +++ b/samples/drivers/video/capture/README.rst @@ -153,17 +153,19 @@ Sample Output current_pixel_format = 32, current_orientation = 0 Capture started - Got frame 0! size: 261120; timestamp 249 ms - Got frame 1! size: 261120; timestamp 282 ms - Got frame 2! size: 261120; timestamp 316 ms - Got frame 3! size: 261120; timestamp 350 ms - Got frame 4! size: 261120; timestamp 384 ms - Got frame 5! size: 261120; timestamp 418 ms - Got frame 6! size: 261120; timestamp 451 ms + Got frame 0! size: 261120; timestamp 249 ms (delta 249 ms) + Got frame 1! size: 261120; timestamp 282 ms (delta 33 ms) + Got frame 2! size: 261120; timestamp 316 ms (delta 34 ms) + Got frame 3! size: 261120; timestamp 350 ms (delta 34 ms) + Got frame 4! size: 261120; timestamp 384 ms (delta 34 ms) + Got frame 5! size: 261120; timestamp 418 ms (delta 34 ms) + Got frame 6! size: 261120; timestamp 451 ms (delta 33 ms) -If using the shell, the capture would not start, and instead it is possible to access the shell +If using the shell, the capture will not start unless the Kconfig option +:kconfig:option:`VIDEO_SHELL_AND_CAPTURE` is set. In both cases, the shell can be used to change +parameters on the fly: .. code-block:: console diff --git a/samples/drivers/video/capture/src/main.c b/samples/drivers/video/capture/src/main.c index 3ac10cd424d5..ab68688ad2ca 100644 --- a/samples/drivers/video/capture/src/main.c +++ b/samples/drivers/video/capture/src/main.c @@ -347,8 +347,8 @@ int main(void) unsigned int frame = 0; int ret; - /* When the video shell is enabled, do not run the capture loop */ - if (IS_ENABLED(CONFIG_VIDEO_SHELL)) { + /* When the video shell is enabled, do not run the capture loop unless requested */ + if (IS_ENABLED(CONFIG_VIDEO_SHELL) && !IS_ENABLED(CONFIG_VIDEO_SHELL_AND_CAPTURE)) { LOG_INF("Letting the user control the device with the video shell"); return 0; } @@ -398,6 +398,8 @@ int main(void) LOG_INF("Capture started"); + uint32_t last_ts = 0; + vbuf->type = VIDEO_BUF_TYPE_OUTPUT; while (1) { ret = video_dequeue(video_dev, &vbuf, K_FOREVER); @@ -406,8 +408,9 @@ int main(void) goto err; } - LOG_INF("Got frame %u! size: %u; timestamp %u ms", - frame++, vbuf->bytesused, vbuf->timestamp); + LOG_INF("Got frame %u! size: %u; timestamp %u ms (delta %u ms)", + frame++, vbuf->bytesused, vbuf->timestamp, vbuf->timestamp-last_ts); + last_ts = vbuf->timestamp; if (DT_HAS_CHOSEN(zephyr_display)) { ret = app_display_frame(display_dev, vbuf, &fmt); From 3e7b47f7c45a296addc2a55ea94d1300f21a4e5c Mon Sep 17 00:00:00 2001 From: Anton Puppe Date: Fri, 12 Dec 2025 12:53:03 +0100 Subject: [PATCH 1497/3659] samples: video: capture: Add STM32N6570_DK to sample documentation Add docs (wiring, build etc.) for the stm32n6570_dk board with the st_b_cams_imx_mb1854 camera shield (based on an IMX335). Signed-off-by: Anton Puppe --- samples/drivers/video/capture/README.rst | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/samples/drivers/video/capture/README.rst b/samples/drivers/video/capture/README.rst index 1d418e8a8dab..e505ff2daa18 100644 --- a/samples/drivers/video/capture/README.rst +++ b/samples/drivers/video/capture/README.rst @@ -30,6 +30,9 @@ Supported boards and camera modules include: - :zephyr:board:`stm32h7b3i_dk` with the :ref:`st_b_cams_omv_mb1683` shield and a compatible camera module. +- :zephyr:board:`stm32n6570_dk` + with the :ref:`st_b_cams_imx_mb1854` camera module. + Also :zephyr:board:`arduino_nicla_vision` can be used in this sample as capture device, in that case The user can transfer the captured frames through on board USB. @@ -48,6 +51,10 @@ On :zephyr:board:`stm32h7b3i_dk`, connect the :ref:`st_b_cams_omv_mb1683` shield board on CN7 connector. A USB cable should be connected from a host to the micro USB connector in order to get console output. +On :zephyr:board:`stm32n6570_dk`, connect the :ref:`st_b_cams_imx_mb1854` camera module +to the J4 CSI connector. A USB cable should be connected from a host to both USB-C ports for +power, flashing and console output. + For :zephyr:board:`arduino_nicla_vision` there is no extra wiring required. Building and Running @@ -100,6 +107,16 @@ using the :ref:`st_b_cams_omv_mb1683` shield with a compatible camera module: :goals: build :compact: +For :zephyr:board:`stm32n6570_dk`, build this sample application with the following commands, +using the :ref:`st_b_cams_imx_mb1854` camera module: + +.. zephyr-app-commands:: + :zephyr-app: samples/drivers/video/capture + :board: stm32n6570_dk + :shield: st_b_cams_imx_mb1854 + :goals: build + :compact: + For testing purpose and without the need of any real video capture and/or display hardwares, a video software pattern generator is supported by the above build commands without specifying the shields, and using :ref:`snippet-video-sw-generator`: From 588d22464d130fdcc1b0319adbcc21e7c3347226 Mon Sep 17 00:00:00 2001 From: Andy Lin Date: Wed, 7 Jan 2026 01:59:53 +0800 Subject: [PATCH 1498/3659] soc: raspberrypi: rp235x/hazard3: Add support for ramfunc Add support to run code from SRAM and future PSRAM for RP235x:hazard3. Signed-off-by: Andy Lin --- soc/raspberrypi/rpi_pico/rp2350/Kconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/soc/raspberrypi/rpi_pico/rp2350/Kconfig b/soc/raspberrypi/rpi_pico/rp2350/Kconfig index f843a2f5b6a1..389f8275e9da 100644 --- a/soc/raspberrypi/rpi_pico/rp2350/Kconfig +++ b/soc/raspberrypi/rpi_pico/rp2350/Kconfig @@ -10,6 +10,7 @@ config SOC_SERIES_RP2350 imply XIP config SOC_RP2350A_HAZARD3 + select ARCH_HAS_RAMFUNC_SUPPORT if XIP select HAS_FLASH_LOAD_OFFSET select INCLUDE_RESET_VECTOR select RISCV @@ -34,6 +35,7 @@ config SOC_RP2350A_M33 select ARMV8_M_DSP config SOC_RP2350B_HAZARD3 + select ARCH_HAS_RAMFUNC_SUPPORT if XIP select HAS_FLASH_LOAD_OFFSET select INCLUDE_RESET_VECTOR select RISCV From feadf2e8ef5a9e55a0d08ac65797e351d86edf7b Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Tue, 17 Dec 2024 08:35:12 +0000 Subject: [PATCH 1499/3659] sysbuild: Add optional output merged hex file support Adds support for generated merged hex file output, one hex file per unique board target. This feature can be enabled with SB_CONFIG_MERGED_HEX_FILES Signed-off-by: Jamie McCrae --- .gitignore | 1 + share/sysbuild/build/Kconfig | 7 ++ .../cmake/modules/sysbuild_default.cmake | 1 + .../cmake/modules/sysbuild_merged_hex.cmake | 96 +++++++++++++++++++ 4 files changed, 105 insertions(+) create mode 100644 share/sysbuild/cmake/modules/sysbuild_merged_hex.cmake diff --git a/.gitignore b/.gitignore index da37ed2a238e..5ca55745f066 100644 --- a/.gitignore +++ b/.gitignore @@ -17,6 +17,7 @@ build*/ !doc/build/ !scripts/build +!share/sysbuild/build !tests/drivers/build_all !scripts/pylib/build_helpers cscope.* diff --git a/share/sysbuild/build/Kconfig b/share/sysbuild/build/Kconfig index dfa423cd3e82..789a13a31fb0 100644 --- a/share/sysbuild/build/Kconfig +++ b/share/sysbuild/build/Kconfig @@ -6,3 +6,10 @@ config COMPILER_WARNINGS_AS_ERRORS bool "Treat warnings as errors" help Turn on "warning as error" toolchain flags for all images if set. + +config MERGED_HEX_FILES + bool "Create merged hex files" + help + If this option is enabled, merged hex files will be created, one per unique board + target, that contain all the data of the hex output files merged into a single file, + named ``merged_.hex``. diff --git a/share/sysbuild/cmake/modules/sysbuild_default.cmake b/share/sysbuild/cmake/modules/sysbuild_default.cmake index f3ffa81bb28b..5dcb1c067d78 100644 --- a/share/sysbuild/cmake/modules/sysbuild_default.cmake +++ b/share/sysbuild/cmake/modules/sysbuild_default.cmake @@ -19,3 +19,4 @@ include(sysbuild_snippets) include(sysbuild_kconfig) include(native_simulator_sb_extensions) include(sysbuild_images) +include(sysbuild_merged_hex) diff --git a/share/sysbuild/cmake/modules/sysbuild_merged_hex.cmake b/share/sysbuild/cmake/modules/sysbuild_merged_hex.cmake new file mode 100644 index 000000000000..2638adffeed8 --- /dev/null +++ b/share/sysbuild/cmake/modules/sysbuild_merged_hex.cmake @@ -0,0 +1,96 @@ +# +# Copyright (c) 2024-2026 Nordic Semiconductor +# +# SPDX-License-Identifier: Apache-2.0 +# + +# This module is responsible for creating merged hex files, one per unique board target. Hex +# files are merged using replace overlap mode from the images in ascending flash priority +# order (a later flashed application will overwrite data from previous images if both contain +# data in the same area) +function(create_merged_hex_files) + set(board_targets) + sysbuild_images_order(sorted_flash_images FLASH IMAGES ${IMAGES}) + + # Parse each image to get the board target, normalise it and create a list of every image per + # unique board target + foreach(image ${sorted_flash_images}) + set(board_target) + sysbuild_get(board_target IMAGE ${image} VAR CONFIG_BOARD_TARGET KCONFIG) + string(REPLACE "/" "_" board_target ${board_target}) + string(REPLACE "." "_" board_target ${board_target}) + string(REPLACE "@" "_" board_target ${board_target}) + + if(NOT board_target IN_LIST board_targets) + list(APPEND board_targets ${board_target}) + set(board_merge_images_${board_target}) + endif() + + list(APPEND board_merge_images_${board_target} ${image}) + endforeach() + + foreach(board_target ${board_targets}) + set(depends_list) + set(input_list) + + foreach(image ${board_merge_images_${board_target}}) + # Only process images that create hex files + set(output_hex) + sysbuild_get(output_hex IMAGE ${image} VAR CONFIG_BUILD_OUTPUT_HEX KCONFIG) + + if(output_hex) + # The order of files to use are (starting with highest priority): + # * + # * + # * .hex + # + # This ensures that if the image has a signing script, that the signed image is used, the + # confirmed version should be used if MCUboot is used in directXIP mode so has the most + # priority. If there is no byproduct signed file, then the normal zephyr hex file is used + set(byproduct_signed_confirmed_hex) + set(byproduct_signed_hex) + set(kernel_name) + set(application_image_dir) + sysbuild_get(byproduct_signed_confirmed_hex IMAGE ${image} VAR BYPRODUCT_KERNEL_SIGNED_CONFIRMED_HEX_NAME CACHE) + sysbuild_get(byproduct_signed_hex IMAGE ${image} VAR BYPRODUCT_KERNEL_SIGNED_HEX_NAME CACHE) + sysbuild_get(kernel_name IMAGE ${image} VAR CONFIG_KERNEL_BIN_NAME KCONFIG) + sysbuild_get(application_image_dir IMAGE ${image} VAR APPLICATION_BINARY_DIR CACHE) + list(APPEND depends_list ${image}_extra_byproducts ${application_image_dir}/zephyr/.config) + + if(byproduct_signed_confirmed_hex) + list(APPEND input_list ${byproduct_signed_confirmed_hex}) + elseif(byproduct_signed_hex) + list(APPEND input_list ${byproduct_signed_hex}) + else() + list(APPEND input_list ${application_image_dir}/zephyr/${kernel_name}.hex) + endif() + endif() + endforeach() + + # Use the mergehex python file to merge the hex file in flash-order with replace mode + add_custom_command( + OUTPUT + ${CMAKE_BINARY_DIR}/merged_${board_target}.hex + COMMAND + ${PYTHON_EXECUTABLE} + ${ZEPHYR_BASE}/scripts/build/mergehex.py + -o ${CMAKE_BINARY_DIR}/merged_${board_target}.hex + --overlap replace + ${input_list} + DEPENDS + ${depends_list};${input_list} + WORKING_DIRECTORY + ${CMAKE_BINARY_DIR} + ) + + add_custom_target( + merged_${board_target}_target + ALL DEPENDS + ${CMAKE_BINARY_DIR}/merged_${board_target}.hex + ) + endforeach() +endfunction() + +if(SB_CONFIG_MERGED_HEX_FILES) + create_merged_hex_files() +endif() From a69bf8d419fe87674aad7cff426b74994edf0049 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Wed, 7 Jan 2026 10:16:08 +0000 Subject: [PATCH 1500/3659] tests: cmake: Add sysbuild_merged_hex test Adds a test to ensure proper functioning of the sysbuild merged hex feature Signed-off-by: Jamie McCrae --- .../cmake/sysbuild_merged_hex/CMakeLists.txt | 8 +++ .../sysbuild_merged_hex/compare_output.py | 31 ++++++++ tests/cmake/sysbuild_merged_hex/prj.conf | 1 + tests/cmake/sysbuild_merged_hex/src/main.c | 7 ++ .../cmake/sysbuild_merged_hex/sysbuild.cmake | 72 +++++++++++++++++++ tests/cmake/sysbuild_merged_hex/sysbuild.conf | 2 + tests/cmake/sysbuild_merged_hex/testcase.yaml | 13 ++++ 7 files changed, 134 insertions(+) create mode 100644 tests/cmake/sysbuild_merged_hex/CMakeLists.txt create mode 100644 tests/cmake/sysbuild_merged_hex/compare_output.py create mode 100644 tests/cmake/sysbuild_merged_hex/prj.conf create mode 100644 tests/cmake/sysbuild_merged_hex/src/main.c create mode 100644 tests/cmake/sysbuild_merged_hex/sysbuild.cmake create mode 100644 tests/cmake/sysbuild_merged_hex/sysbuild.conf create mode 100644 tests/cmake/sysbuild_merged_hex/testcase.yaml diff --git a/tests/cmake/sysbuild_merged_hex/CMakeLists.txt b/tests/cmake/sysbuild_merged_hex/CMakeLists.txt new file mode 100644 index 000000000000..80882889622a --- /dev/null +++ b/tests/cmake/sysbuild_merged_hex/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(test_sysbuild_merged_hex) + +target_sources(app PRIVATE src/main.c) diff --git a/tests/cmake/sysbuild_merged_hex/compare_output.py b/tests/cmake/sysbuild_merged_hex/compare_output.py new file mode 100644 index 000000000000..495436585161 --- /dev/null +++ b/tests/cmake/sysbuild_merged_hex/compare_output.py @@ -0,0 +1,31 @@ +# +# Copyright (c) 2026 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 +# + +import hashlib +import sys + +with open("merged_nrf9160dk_0_14_0_nrf9160.hex", "rb") as f: + md5type = hashlib.md5(usedforsecurity=False) + md5type.update(f.read()) + nrf9160 = md5type.hexdigest() +with open("merged_nrf9160dk_0_14_0_nrf52840.hex", "rb") as f: + md5type = hashlib.md5(usedforsecurity=False) + md5type.update(f.read()) + nrf52840 = md5type.hexdigest() +with open("test1.hex", "rb") as f: + md5type = hashlib.md5(usedforsecurity=False) + md5type.update(f.read()) + test1 = md5type.hexdigest() +with open("test2.hex", "rb") as f: + md5type = hashlib.md5(usedforsecurity=False) + md5type.update(f.read()) + test2 = md5type.hexdigest() + +if nrf9160 != test1: + sys.exit("nrf9160 <-> test1 file contents mismatch") + +if nrf52840 != test2: + sys.exit("nrf52840 <-> test2 file contents mismatch") diff --git a/tests/cmake/sysbuild_merged_hex/prj.conf b/tests/cmake/sysbuild_merged_hex/prj.conf new file mode 100644 index 000000000000..b2a4ba591044 --- /dev/null +++ b/tests/cmake/sysbuild_merged_hex/prj.conf @@ -0,0 +1 @@ +# nothing here diff --git a/tests/cmake/sysbuild_merged_hex/src/main.c b/tests/cmake/sysbuild_merged_hex/src/main.c new file mode 100644 index 000000000000..eed3a0cb0032 --- /dev/null +++ b/tests/cmake/sysbuild_merged_hex/src/main.c @@ -0,0 +1,7 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* Empty file */ diff --git a/tests/cmake/sysbuild_merged_hex/sysbuild.cmake b/tests/cmake/sysbuild_merged_hex/sysbuild.cmake new file mode 100644 index 000000000000..00ad75679b2b --- /dev/null +++ b/tests/cmake/sysbuild_merged_hex/sysbuild.cmake @@ -0,0 +1,72 @@ +# +# Copyright (c) 2026 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 +# + +ExternalZephyrProject_Add( + APPLICATION other_hello + SOURCE_DIR ${ZEPHYR_BASE}/samples/hello_world + BOARD nrf9160dk/nrf52840 +) + +add_custom_command( + OUTPUT + ${CMAKE_BINARY_DIR}/test1.hex + COMMAND + ${PYTHON_EXECUTABLE} + ${ZEPHYR_BASE}/scripts/build/mergehex.py + -o ${CMAKE_BINARY_DIR}/test1.hex + --overlap replace + mcuboot/zephyr/zephyr.hex + sysbuild_merged_hex/zephyr/zephyr.signed.hex + DEPENDS + mcuboot_extra_byproducts;sysbuild_merged_hex_extra_byproducts;merged_nrf9160dk_0_14_0_nrf9160_target + WORKING_DIRECTORY + ${CMAKE_BINARY_DIR} +) + +add_custom_target( + test1_target + ALL DEPENDS + ${CMAKE_BINARY_DIR}/test1.hex +) + +add_custom_command( + OUTPUT + ${CMAKE_BINARY_DIR}/test2.hex + COMMAND + ${PYTHON_EXECUTABLE} + ${ZEPHYR_BASE}/scripts/build/mergehex.py + -o ${CMAKE_BINARY_DIR}/test2.hex + --overlap replace + other_hello/zephyr/zephyr.hex + DEPENDS + other_hello_extra_byproducts;merged_nrf9160dk_0_14_0_nrf52840_target + WORKING_DIRECTORY + ${CMAKE_BINARY_DIR} +) + +add_custom_target( + test2_target + ALL DEPENDS + ${CMAKE_BINARY_DIR}/test2.hex +) + +add_custom_command( + OUTPUT + test3_result + COMMAND + ${PYTHON_EXECUTABLE} + ${APP_DIR}/compare_output.py + DEPENDS + test1_target;test2_target;${CMAKE_BINARY_DIR}/test1.hex;${CMAKE_BINARY_DIR}/test2.hex + WORKING_DIRECTORY + ${CMAKE_BINARY_DIR} +) + +add_custom_target( + test3_target + ALL DEPENDS + test3_result +) diff --git a/tests/cmake/sysbuild_merged_hex/sysbuild.conf b/tests/cmake/sysbuild_merged_hex/sysbuild.conf new file mode 100644 index 000000000000..451ffa571a79 --- /dev/null +++ b/tests/cmake/sysbuild_merged_hex/sysbuild.conf @@ -0,0 +1,2 @@ +SB_CONFIG_BOOTLOADER_MCUBOOT=y +SB_CONFIG_MERGED_HEX_FILES=y diff --git a/tests/cmake/sysbuild_merged_hex/testcase.yaml b/tests/cmake/sysbuild_merged_hex/testcase.yaml new file mode 100644 index 000000000000..60de1b697963 --- /dev/null +++ b/tests/cmake/sysbuild_merged_hex/testcase.yaml @@ -0,0 +1,13 @@ +common: + sysbuild: true + build_only: true + tags: + - sysbuild + - pytest + platform_allow: + - nrf9160dk/nrf9160 + integration_platforms: + - nrf9160dk/nrf9160 + +tests: + buildsystem.sysbuild.merged.hex: {} From c6bc55e698238204ee9e0d43937ef1247158899a Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Wed, 7 Jan 2026 08:31:35 +0000 Subject: [PATCH 1501/3659] doc: build: sysbuild: Add merged hex file information Adds details about the newly introduced merged hex file support Signed-off-by: Jamie McCrae --- doc/build/sysbuild/index.rst | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/doc/build/sysbuild/index.rst b/doc/build/sysbuild/index.rst index 42d100c554ea..1d1e0185b882 100644 --- a/doc/build/sysbuild/index.rst +++ b/doc/build/sysbuild/index.rst @@ -805,6 +805,22 @@ As a result, ``my_sample`` will be flashed after ``sample_a`` and ``sample_b`` If ``my_sample`` had been created with ``BUILD_ONLY TRUE``, then the above call to ``sysbuild_add_dependencies()`` would have produced an error. +.. _sysbuild_merged_hex_files: + +Merged hex files +**************** + +Sysbuild supports creating merged hex files, which will be created one per unique board target +in a sysbuild project and can be enabled with :kconfig:option:`SB_CONFIG_MERGED_HEX_FILES`. +The output filename format will be :file:`merged_.hex`. This is ideal +for creating production images for deployment, it requires that all images output hex files. +If a sysbuild project builds multiple images for the same board target but for **different** +devices (e.g. 3 images for 3 different boards as part of a test), then this option should remain +disabled. Hex files will be merged as per the flashing order they have been configured in, any +overlapping data from previous addresses that conflicts with later merged hex files will be +overwritten with the later hex file data - see :ref:`sysbuild_zephyr_application_dependencies` +for how to configure the flashing order of sysbuild images. + Adding non-Zephyr applications to sysbuild ****************************************** From ef9f455db1021e1952552b8cb79946b3d01533a1 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Wed, 7 Jan 2026 08:32:12 +0000 Subject: [PATCH 1502/3659] doc: releases: release-notes: 4.4: Add note on sysbuild merged hex Adds details of the newly introduced merged hex output support for sysbuild Signed-off-by: Jamie McCrae --- doc/releases/release-notes-4.4.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/doc/releases/release-notes-4.4.rst b/doc/releases/release-notes-4.4.rst index 1bdc2a9fe4d9..be546808c5b1 100644 --- a/doc/releases/release-notes-4.4.rst +++ b/doc/releases/release-notes-4.4.rst @@ -138,6 +138,13 @@ New APIs and options * Introduced Alert Notification Service (ANS) :kconfig:option:`CONFIG_BT_ANS` +* Build system + + * Sysbuild + + * Added :kconfig:option:`SB_CONFIG_MERGED_HEX_FILES` which allows generating + :ref:`merged hex files `. + * Ethernet * Driver MAC address configuration with support for NVMEM cell. From c6a0444f500195d0c89209bc6f13b22d9ff2852f Mon Sep 17 00:00:00 2001 From: Francis Roi Manabat Date: Thu, 4 Dec 2025 19:10:25 +0800 Subject: [PATCH 1503/3659] drivers: sensor: add MAX30210 Temperature Sensor Support Add Support for MAX30210, a low-power, high-accuracy digital temperature sensor operating from a 1.7 V to 2.0 V supply. Signed-off-by: Francis Roi Manabat --- drivers/sensor/adi/CMakeLists.txt | 1 + drivers/sensor/adi/Kconfig | 1 + drivers/sensor/adi/max30210/CMakeLists.txt | 8 + drivers/sensor/adi/max30210/Kconfig | 64 ++ drivers/sensor/adi/max30210/max30210.c | 930 ++++++++++++++++++ drivers/sensor/adi/max30210/max30210.h | 271 +++++ .../sensor/adi/max30210/max30210_trigger.c | 311 ++++++ dts/bindings/sensor/adi,max30210.yaml | 122 +++ include/zephyr/drivers/sensor/max30210.h | 51 + 9 files changed, 1759 insertions(+) create mode 100644 drivers/sensor/adi/max30210/CMakeLists.txt create mode 100644 drivers/sensor/adi/max30210/Kconfig create mode 100644 drivers/sensor/adi/max30210/max30210.c create mode 100644 drivers/sensor/adi/max30210/max30210.h create mode 100644 drivers/sensor/adi/max30210/max30210_trigger.c create mode 100644 dts/bindings/sensor/adi,max30210.yaml create mode 100644 include/zephyr/drivers/sensor/max30210.h diff --git a/drivers/sensor/adi/CMakeLists.txt b/drivers/sensor/adi/CMakeLists.txt index e524f38dc5e6..b30a07011562 100644 --- a/drivers/sensor/adi/CMakeLists.txt +++ b/drivers/sensor/adi/CMakeLists.txt @@ -10,5 +10,6 @@ add_subdirectory_ifdef(CONFIG_ADXL345 adxl345) add_subdirectory_ifdef(CONFIG_ADXL362 adxl362) add_subdirectory_ifdef(CONFIG_ADXL367 adxl367) add_subdirectory_ifdef(CONFIG_ADXL372 adxl372) +add_subdirectory_ifdef(CONFIG_MAX30210 max30210) add_subdirectory_ifdef(CONFIG_SENSOR_MAX32664C max32664c) # zephyr-keep-sorted-stop diff --git a/drivers/sensor/adi/Kconfig b/drivers/sensor/adi/Kconfig index d0812de2dcee..7377be4623af 100644 --- a/drivers/sensor/adi/Kconfig +++ b/drivers/sensor/adi/Kconfig @@ -10,5 +10,6 @@ source "drivers/sensor/adi/adxl345/Kconfig" source "drivers/sensor/adi/adxl362/Kconfig" source "drivers/sensor/adi/adxl367/Kconfig" source "drivers/sensor/adi/adxl372/Kconfig" +source "drivers/sensor/adi/max30210/Kconfig" source "drivers/sensor/adi/max32664c/Kconfig" # zephyr-keep-sorted-stop diff --git a/drivers/sensor/adi/max30210/CMakeLists.txt b/drivers/sensor/adi/max30210/CMakeLists.txt new file mode 100644 index 000000000000..c64443810173 --- /dev/null +++ b/drivers/sensor/adi/max30210/CMakeLists.txt @@ -0,0 +1,8 @@ +# Copyright (c) 2025 Analog Devices, Inc. +# +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library() + +zephyr_library_sources(max30210.c) +zephyr_library_sources_ifdef(CONFIG_MAX30210_TRIGGER max30210_trigger.c) diff --git a/drivers/sensor/adi/max30210/Kconfig b/drivers/sensor/adi/max30210/Kconfig new file mode 100644 index 000000000000..abccda1c0f7e --- /dev/null +++ b/drivers/sensor/adi/max30210/Kconfig @@ -0,0 +1,64 @@ +# Copyright (c) 2025 Analog Devices Inc. +# SPDX-License-Identifier: Apache-2.0 +# +# This file contains the binding for MAX30210 sensor + +menuconfig MAX30210 + bool "MAX30210 Temperature Sensor" + default y + depends on DT_HAS_ADI_MAX30210_ENABLED + select I2C + help + Enable driver for the MAX30210 temperature sensor. + +if MAX30210 + +config MAX30210_TRIGGER + bool + +choice MAX30210_TRIGGER_MODE + prompt "Sets trigger mode" + default MAX30210_TRIGGER_NONE + help + Sets thread type for the interrupt handler. + +config MAX30210_TRIGGER_NONE + bool "No trigger" + +config MAX30210_TRIGGER_GLOBAL_THREAD + bool "Use global thread" + depends on $(dt_compat_any_has_prop,$(DT_COMPAT_ADI_MAX30210),interrupt-gpios) + select GPIO + select MAX30210_TRIGGER + help + Use a global thread for the interrupt handler. + +config MAX30210_TRIGGER_OWN_THREAD + bool "Use own thread" + depends on $(dt_compat_any_has_prop,$(DT_COMPAT_ADI_MAX30210),interrupt-gpios) + select GPIO + select MAX30210_TRIGGER + help + Use a separate thread for the interrupt handler. + +endchoice # MAX30210_TRIGGER_MODE + +if MAX30210_TRIGGER_OWN_THREAD + +config MAX30210_THREAD_PRIORITY + int "Thread priority of the interrupt handler" + default 10 + help + Thread priority of the interrupt handler. A higher number implies a + higher priority. The thread is cooperative and will not be interrupted by + another thread until execution is released. + +config MAX30210_THREAD_STACK_SIZE + int "Stack size of the interrupt handler thread" + default 1024 + help + Stack size of the interrupt handler thread. + +endif # MAX30210_TRIGGER_OWN_THREAD + +endif # MAX30210 diff --git a/drivers/sensor/adi/max30210/max30210.c b/drivers/sensor/adi/max30210/max30210.c new file mode 100644 index 000000000000..62309855c67d --- /dev/null +++ b/drivers/sensor/adi/max30210/max30210.c @@ -0,0 +1,930 @@ +/* + * Copyright (c) 2025 Analog Devices Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT adi_max30210 + +#include +#include +#include +#include +#include "max30210.h" +#include +#include +#include + +LOG_MODULE_REGISTER(MAX30210, CONFIG_SENSOR_LOG_LEVEL); + +/** + * @brief Read from MAX30210 register + * + * @param dev Device Pointer + * @param reg_addr Register Address + * @param val Value Pointer + * @param length Number of Bytes to Read + * @return int 0 on success, negative error code on failure + */ +int max30210_reg_read(const struct device *dev, uint8_t reg_addr, uint8_t *val, uint8_t length) +{ + const struct max30210_config *config = dev->config; + + return i2c_burst_read_dt(&config->i2c, reg_addr, val, length); +} + +/** + * @brief Single byte write to MAX30210 register + * + * @param dev Device Pointer + * @param reg_addr Register Address + * @param val Value to Write + * @param length Ignored + * @return int + */ +int max30210_reg_write(const struct device *dev, uint8_t reg_addr, uint8_t val) +{ + const struct max30210_config *config = dev->config; + + return i2c_reg_write_byte_dt(&config->i2c, reg_addr, val); +} + +/** + * @brief Multiple byte write to MAX30210 register + * + * @param dev Device Pointer + * @param reg_addr Register Address + * @param val Value Pointer + * @param length Number of Bytes to Write + * @return int 0 on success, negative error code on failure + */ +int max30210_reg_write_multiple(const struct device *dev, uint8_t reg_addr, uint8_t *val, + uint8_t length) +{ + const struct max30210_config *config = dev->config; + + if (length < 2) { + return -EINVAL; + } + + return i2c_burst_write_dt(&config->i2c, reg_addr, val, length); +} + +/** + * @brief Update specific bits in a MAX30210 register + * + * @param dev Device Pointer + * @param reg_addr Register Address + * @param mask Bit Mask + * @param val Value to Set + * @return int 0 on success, negative error code on failure + */ +int max30210_reg_update(const struct device *dev, uint8_t reg_addr, uint8_t mask, uint8_t val) +{ + uint8_t reg_val = 0; + int ret; + + ret = max30210_reg_read(dev, reg_addr, ®_val, 1); + if (ret < 0) { + return ret; + } + + reg_val &= ~mask; + reg_val |= FIELD_PREP(mask, val); + + return max30210_reg_write(dev, reg_addr, reg_val); +} + +/** + * @brief Convert temperature in millidegrees Celsius to MAX30210 register bytes + * + * @param temp_mc Temperature in millidegrees Celsius + * @param msb Pointer to store Most Significant Byte + * @param lsb Pointer to store Least Significant Byte + */ +static inline void max30210_temp_to_bytes(int32_t temp_mc, uint8_t *msb, uint8_t *lsb) +{ + /* Convert millidegrees Celsius to register value */ + int16_t reg_val = (int16_t)(temp_mc / 5); + uint8_t buf[2]; + + /* Split into two bytes (big-endian: MSB first, LSB second) */ + sys_put_be16(reg_val, buf); + *msb = buf[0]; + *lsb = buf[1]; +} + +/** + * @brief Set Continuous Conversion Mode for MAX30210 + * + * @param dev Device Pointer + * @return int 0 on success, negative error code on failure + */ +static int max30210_attr_set_continuous_conversion_mode(const struct device *dev) +{ + int ret; + + ret = max30210_reg_write(dev, TEMP_CONVERT, 0X03); + if (ret < 0) { + LOG_ERR("Failed to set CONTINUOUS CONVERSION MODE: %d\n", ret); + return ret; + } + return 0; +} + +/** + * @brief Validate whole part for MAX30210 temperature thresholds + * + * @param val Sensor Value Pointer + * @return int 0 on success, negative error code on failure + */ +static int max30210_validate_whole_part(const struct sensor_value *val) +{ + if (val->val1 < 0 || val->val1 > MAX30210_TEMP_MAX_C) { + LOG_ERR("Invalid whole part for THRESH\n"); + return -EINVAL; + } + return 0; +} + +/** + * @brief Validate fractional parts for MAX30210 temperature thresholds + * + * @param val Sensor Value Pointer + * @return int 0 on success, negative error code on failure + */ +static int max30210_validate_fractional_parts(const struct sensor_value *val) +{ + if (val->val2 < 0 || val->val2 > MAX30210_TEMP_FRAC_MAX_UC || + val->val2 % MAX30210_TEMP_FRAC_STEP_UC != 0) { + LOG_ERR("Invalid fractional part for THRESH\n"); + return -EINVAL; + } + return 0; +} + +/** + * @brief Set Temperature Threshold for MAX30210 + * + * @param dev Device Pointer + * @param val Sensor Value Pointer + * @param upper Boolean indicating if setting upper threshold + * @return int 0 on success, negative error code on failure + */ +static int max30210_attr_set_threshold(const struct device *dev, const struct sensor_value *val, + bool upper) +{ + int ret; + struct max30210_data *temp_data = dev->data; + uint16_t whole_numbers_data; + uint16_t fractional_data; + + ret = max30210_validate_whole_part(val); + if (ret < 0) { + LOG_ERR("Failed to validate whole part for THRESH: %d\n", ret); + return ret; + } + + ret = max30210_validate_fractional_parts(val); + if (ret < 0) { + LOG_ERR("Failed to validate fractional part for THRESH: %d\n", ret); + return ret; + } + + whole_numbers_data = (val->val1) * MAX30210_TEMP_COUNTS_PER_C; + fractional_data = (val->val2 * MAX30210_TEMP_COUNTS_PER_C) / MAX30210_TEMP_FRAC_MAX_UC; + uint16_t thresh = whole_numbers_data + fractional_data; + uint8_t thresh_data[2]; + + sys_put_be16(thresh, thresh_data); + if (upper) { + temp_data->temp_alarm_high_setup = thresh; + ret = max30210_reg_write_multiple(dev, TEMP_ALARM_HIGH_MSB, thresh_data, 2); + } else { + temp_data->temp_alarm_low_setup = thresh; + ret = max30210_reg_write_multiple(dev, TEMP_ALARM_LOW_MSB, thresh_data, 2); + } + if (ret < 0) { + LOG_ERR("Failed to set THRESH: %d\n", ret); + return ret; + } + return 0; +} + +/** + * @brief Set Sampling Frequency for MAX30210 + * + * @param dev Device Pointer + * @param val Sensor Value Pointer + * @return int 0 on success, negative error code on failure + */ +static int max30210_attr_set_sampling_frequency(const struct device *dev, + const struct sensor_value *val) +{ + int ret; + + if (val->val1 < 0 || val->val1 > 8) { + LOG_ERR("Invalid whole part for SAMPLING FREQUENCY\n"); + return -EINVAL; + } + uint8_t sampling_rate = 0; + + if (val->val1 == 0) { + switch ((val->val2)) { + case (15625): + sampling_rate = SENSOR_SAMPLING_RATE_MAX30210_0_015625; + break; + + case (31250): + sampling_rate = SENSOR_SAMPLING_RATE_MAX30210_0_03125; + break; + + case (62500): + sampling_rate = SENSOR_SAMPLING_RATE_MAX30210_0_0625; + break; + + case (125000): + sampling_rate = SENSOR_SAMPLING_RATE_MAX30210_0_125; + break; + + case (250000): + sampling_rate = SENSOR_SAMPLING_RATE_MAX30210_0_25; + break; + + case (500000): + sampling_rate = SENSOR_SAMPLING_RATE_MAX30210_0_5; + break; + + default: + LOG_ERR("Invalid SAMPLING FREQUENCY\n"); + return -EINVAL; + } + + } else { + switch ((val->val1)) { + case (1): + sampling_rate = SENSOR_SAMPLING_RATE_MAX30210_1; + break; + + case (2): + sampling_rate = SENSOR_SAMPLING_RATE_MAX30210_2; + break; + + case (4): + sampling_rate = SENSOR_SAMPLING_RATE_MAX30210_4; + break; + + case (8): + sampling_rate = SENSOR_SAMPLING_RATE_MAX30210_8; + break; + + default: + LOG_ERR("Invalid SAMPLING FREQUENCY\n"); + return -EINVAL; + } + } + + ret = max30210_reg_update(dev, TEMP_CONFIG_2, TEMP_PERIOD_MASK, sampling_rate); + if (ret < 0) { + LOG_ERR("Failed to set SAMPLING FREQUENCY: %d\n", ret); + return ret; + } + return 0; +} + +/** + * @brief Validate whole part for MAX30210 FAST THRESH + * + * @param val Sensor Value Pointer + * @return int 0 on success, negative error code on failure + */ +static int max30210_validate_fast_thresh_whole_part(const struct sensor_value *val) +{ + if (val->val1 < 0 || val->val1 > 1) { + LOG_ERR("Invalid whole part for INC/DEC FAST THRESH\n"); + return -EINVAL; + } + return 0; +} + +/** + * @brief Set Temperature Sample-to-Sample increment Threshold for MAX30210 + * + * @param dev Device Pointer + * @param val Sensor Value Pointer + * @return int 0 on success, negative error code on failure + */ +static int max30210_attr_set_temp_inc_fast_thresh(const struct device *dev, + const struct sensor_value *val) +{ + int ret; + struct max30210_data *temp_data = dev->data; + uint16_t whole_numbers_data; + uint16_t fractional_data; + + whole_numbers_data = (val->val1) * MAX30210_TEMP_COUNTS_PER_C; + fractional_data = ((val->val2) / MAX30210_TEMP_FRAC_MAX_UC) * MAX30210_TEMP_COUNTS_PER_C; + uint8_t inc_fast_thresh = whole_numbers_data + fractional_data; + + temp_data->temp_inc_fast_thresh = inc_fast_thresh; + + if (inc_fast_thresh > MAX30210_TEMP_SLOPE_MAX_REG_VALUE) { + LOG_ERR("INC FAST THRESH exceeds maximum value\n"); + return -EINVAL; + } + + ret = max30210_reg_write(dev, TEMP_INC_FAST_THRESH, inc_fast_thresh); + if (ret < 0) { + LOG_ERR("Failed to set INC FAST THRESH: %d\n", ret); + return ret; + } + return 0; +} + +/** + * @brief Set Temperature Sample-to-Sample decrement Threshold for MAX30210 + * + * @param dev Device Pointer + * @param val Sensor Value Pointer + * @return int 0 on success, negative error code on failure + */ +static int max30210_attr_set_temp_dec_fast_thresh(const struct device *dev, + const struct sensor_value *val) +{ + int ret; + struct max30210_data *temp_data = dev->data; + uint16_t whole_numbers_data; + uint16_t fractional_data; + + /* Highest possible whole number is 1 degrees celsius */ + ret = max30210_validate_fast_thresh_whole_part(val); + if (ret < 0) { + LOG_ERR("Invalid whole part for DEC FAST THRESH\n"); + return -EINVAL; + } + + /* Validate value is non-negative, <= 1 degree, and a multiple of 0.005 degrees */ + ret = max30210_validate_fractional_parts(val); + if (ret < 0) { + LOG_ERR("Invalid fractional part for DEC FAST THRESH\n"); + return -EINVAL; + } + + whole_numbers_data = (val->val1) * MAX30210_TEMP_COUNTS_PER_C; + fractional_data = ((val->val2) / MAX30210_TEMP_FRAC_MAX_UC) * MAX30210_TEMP_COUNTS_PER_C; + uint8_t dec_fast_thresh = whole_numbers_data + fractional_data; + + temp_data->temp_dec_fast_thresh = dec_fast_thresh; + + if (dec_fast_thresh > MAX30210_TEMP_SLOPE_MAX_REG_VALUE) { + LOG_ERR("DEC FAST THRESH exceeds maximum value\n"); + return -EINVAL; + } + + ret = max30210_reg_write(dev, TEMP_DEC_FAST_THRESH, dec_fast_thresh); + if (ret < 0) { + LOG_ERR("Failed to set DEC FAST THRESH: %d\n", ret); + return ret; + } + return 0; +} + +/** + * @brief Perform Software Reset for MAX30210 + * + * @param dev Device Pointer + * @return int 0 on success, negative error code on failure + */ +static int max30210_attr_set_soft_reset(const struct device *dev) +{ + int ret; + + ret = max30210_reg_write(dev, SYS_CONFIG, RESET_MASK); + if (ret < 0) { + LOG_ERR("Failed to perform software reset: %d\n", ret); + return ret; + } + k_sleep(K_MSEC(10)); + return 0; +} + +/** + * @brief Set Rate Change Filter for MAX30210 + * + * @param dev Device Pointer + * @param val Sensor Value Pointer + * @return int 0 on success, negative error code on failure + */ +static int max30210_attr_set_rate_chg_filter(const struct device *dev, + const struct sensor_value *val) +{ + int ret; + + /*Check validity of Rate CHG Filter*/ + if (val->val1 < 0 || val->val1 > 7) { + LOG_ERR("Invalid value for rate change filter\n"); + return -EINVAL; + } + ret = max30210_reg_update(dev, TEMP_CONFIG_1, RATE_CHRG_FILTER_MASK, val->val1); + if (ret < 0) { + LOG_ERR("Failed to set rate change filter: %d\n", ret); + return ret; + } + return 0; +} + +/** + * @brief Validate value for Reset or Mode settings + * + * @param val Sensor Value Pointer + * @return int 0 on success, negative error code on failure + */ +static int validate_mode_reset_value(const struct sensor_value *val) +{ + if (val->val1 < 0 || val->val1 > 1) { + LOG_ERR("Invalid value for Reset or Mode\n"); + return -EINVAL; + } + return 0; +} + +/** + * @brief Set High Non-Consecutive Mode for MAX30210 + * + * @param dev Device Pointer + * @param val Sensor Value Pointer + * @return int 0 on success, negative error code on failure + */ +static int max30210_attr_set_hi_non_consecutive_mode(const struct device *dev, + const struct sensor_value *val) +{ + int ret; + + ret = validate_mode_reset_value(val); + if (ret < 0) { + LOG_ERR("Invalid value for high consecutive mode\n"); + return -EINVAL; + } + + ret = max30210_reg_update(dev, TEMP_ALARM_HIGH_SETUP, TEMP_HI_ALARM_TRIP_MASK, val->val1); + if (ret < 0) { + LOG_ERR("Failed to set high consecutive mode: %d\n", ret); + return ret; + } + return 0; +} + +/** + * @brief Set Low Non-Consecutive Mode for MAX30210 + * + * @param dev Device Pointer + * @param val Sensor Value Pointer + * @return int 0 on success, negative error code on failure + */ +static int max30210_attr_set_lo_non_consecutive_mode(const struct device *dev, + const struct sensor_value *val) +{ + int ret; + + ret = validate_mode_reset_value(val); + if (ret < 0) { + LOG_ERR("Invalid value for low consecutive mode\n"); + return -EINVAL; + } + + ret = max30210_reg_update(dev, TEMP_ALARM_LOW_SETUP, TEMP_LO_ALARM_TRIP_MASK, val->val1); + if (ret < 0) { + LOG_ERR("Failed to set low consecutive mode: %d\n", ret); + return ret; + } + return 0; +} + +static int validate_trip_count_value(const struct sensor_value *val) +{ + if (val->val1 < 1 || val->val1 > 4) { + LOG_ERR("Invalid value for trip count\n"); + return -EINVAL; + } + return 0; +} + +/** + * @brief Set High Trip Count for MAX30210 + * + * @param dev Device Pointer + * @param val Sensor Value Pointer + * @return int 0 on success, negative error code on failure + */ +static int max30210_attr_set_hi_trip_count(const struct device *dev, const struct sensor_value *val) +{ + int ret; + + ret = validate_trip_count_value(val); + if (ret < 0) { + LOG_ERR("Invalid value for high trip count\n"); + return -EINVAL; + } + + ret = max30210_reg_update(dev, TEMP_ALARM_HIGH_SETUP, TEMP_HI_TRIP_COUNTER_MASK, + (val->val1) - 1); + if (ret < 0) { + LOG_ERR("Failed to set high trip count: %d\n", ret); + return ret; + } + return 0; +} + +/** + * @brief Set Low Trip Count for MAX30210 + * + * @param dev Device Pointer + * @param val Sensor Value Pointer + * @return int 0 on success, negative error code on failure + */ +static int max30210_attr_set_lo_trip_count(const struct device *dev, const struct sensor_value *val) +{ + int ret; + + ret = validate_trip_count_value(val); + if (ret < 0) { + LOG_ERR("Invalid value for low trip count\n"); + return -EINVAL; + } + + ret = max30210_reg_update(dev, TEMP_ALARM_LOW_SETUP, TEMP_LO_TRIP_COUNTER_MASK, + (val->val1) - 1); + if (ret < 0) { + LOG_ERR("Failed to set low trip count: %d\n", ret); + return ret; + } + return 0; +} + +/** + * @brief Set High Trip Count Reset for MAX30210 + * + * @param dev Device Pointer + * @param val Sensor Value Pointer + * @return int 0 on success, negative error code on failure + */ +static int max30210_attr_set_hi_trip_count_reset(const struct device *dev, + const struct sensor_value *val) +{ + int ret; + + ret = validate_mode_reset_value(val); + if (ret < 0) { + LOG_ERR("Invalid value for high trip count reset\n"); + return -EINVAL; + } + + ret = max30210_reg_update(dev, TEMP_ALARM_HIGH_SETUP, TEMP_RST_HI_COUNTER, val->val1); + if (ret < 0) { + LOG_ERR("Failed to set high trip count reset: %d\n", ret); + return ret; + } + return 0; +} + +/** + * @brief Set Low Trip Count Reset for MAX30210 + * + * @param dev Device Pointer + * @param val Sensor Value Pointer + * @return int 0 on success, negative error code on failure + */ +static int max30210_attr_set_lo_trip_count_reset(const struct device *dev, + const struct sensor_value *val) +{ + int ret; + + ret = validate_mode_reset_value(val); + if (ret < 0) { + LOG_ERR("Invalid value for low trip count reset\n"); + return -EINVAL; + } + + ret = max30210_reg_update(dev, TEMP_ALARM_LOW_SETUP, TEMP_RST_LO_COUNTER, val->val1); + if (ret < 0) { + LOG_ERR("Failed to set low trip count reset: %d\n", ret); + return ret; + } + return 0; +} + +/** + * @brief Set Alert Mode for MAX30210 + * + * @param dev Device Pointer + * @param val Sensor Value Pointer + * @return int 0 on success, negative error code on failure + */ +static int max30210_attr_set_alert_mode(const struct device *dev, const struct sensor_value *val) +{ + int ret; + + /*Check validity of Alert Mode*/ + ret = validate_mode_reset_value(val); + if (ret < 0) { + LOG_ERR("Invalid value for alert mode\n"); + return -EINVAL; + } + + ret = max30210_reg_update(dev, TEMP_CONFIG_2, ALERT_MODE_MASK, val->val1); + if (ret < 0) { + LOG_ERR("Failed to set alert mode: %d\n", ret); + return ret; + } + return 0; +} + +/** + * @brief Set sensor attributes for MAX30210 + * + * @param dev Device Pointer + * @param chan Sensor Channel + * @param attr Sensor Attribute + * @param val Value Pointer + * @return int 0 on success, negative error code on failure + */ +static int max30210_attr_set(const struct device *dev, enum sensor_channel chan, + enum sensor_attribute attr, const struct sensor_value *val) +{ + switch ((int)attr) { + case SENSOR_ATTR_MAX30210_CONTINUOUS_CONVERSION_MODE: + return max30210_attr_set_continuous_conversion_mode(dev); + case SENSOR_ATTR_LOWER_THRESH: + return max30210_attr_set_threshold(dev, val, false); + case SENSOR_ATTR_UPPER_THRESH: + return max30210_attr_set_threshold(dev, val, true); + case SENSOR_ATTR_SAMPLING_FREQUENCY: + return max30210_attr_set_sampling_frequency(dev, val); + case SENSOR_ATTR_MAX30210_TEMP_INC_FAST_THRESH: + return max30210_attr_set_temp_inc_fast_thresh(dev, val); + case SENSOR_ATTR_MAX30210_TEMP_DEC_FAST_THRESH: + return max30210_attr_set_temp_dec_fast_thresh(dev, val); + case SENSOR_ATTR_MAX30210_SOFTWARE_RESET: + return max30210_attr_set_soft_reset(dev); + case SENSOR_ATTR_MAX30210_RATE_CHG_FILTER: + return max30210_attr_set_rate_chg_filter(dev, val); + case SENSOR_ATTR_MAX30210_HI_NON_CONSECUTIVE_MODE: + return max30210_attr_set_hi_non_consecutive_mode(dev, val); + case SENSOR_ATTR_MAX30210_LO_NON_CONSECUTIVE_MODE: + return max30210_attr_set_lo_non_consecutive_mode(dev, val); + case SENSOR_ATTR_MAX30210_HI_TRIP_COUNT: + return max30210_attr_set_hi_trip_count(dev, val); + case SENSOR_ATTR_MAX30210_LO_TRIP_COUNT: + return max30210_attr_set_lo_trip_count(dev, val); + case SENSOR_ATTR_MAX30210_HI_TRIP_COUNT_RESET: + return max30210_attr_set_hi_trip_count_reset(dev, val); + case SENSOR_ATTR_MAX30210_LO_TRIP_COUNT_RESET: + return max30210_attr_set_lo_trip_count_reset(dev, val); + case SENSOR_ATTR_MAX30210_ALERT_MODE: + return max30210_attr_set_alert_mode(dev, val); + default: + LOG_ERR("Unsupported attribute: %d", attr); + return -ENOTSUP; + } + + return 0; +} + +/** + * @brief Fetch sample data from MAX30210 + * + * @param dev Device Pointer + * @param chan Sensor Channel + * @return int 0 on success, negative error code on failure + */ +static int max30210_sample_fetch(const struct device *dev, enum sensor_channel chan) +{ + struct max30210_data *data = dev->data; + uint8_t temp_data[2]; + int ret; + + if (chan != SENSOR_CHAN_ALL && chan != SENSOR_CHAN_AMBIENT_TEMP) { + LOG_ERR("Unsupported channel: %d", chan); + return -ENOTSUP; + } + + ret = max30210_reg_read(dev, TEMP_DATA_MSB, temp_data, 2); + if (ret < 0) { + LOG_ERR("Failed to read TEMP_DATA_MSB: %d", ret); + return ret; + } + + data->temp_data = (temp_data[0] << 8) | temp_data[1]; + + return 0; +} + +/** + * @brief Get sensor channel data from MAX30210 + * + * @param dev Device Pointer + * @param chan Sensor Channel + * @param val Value Pointer + * @return int 0 on success, negative error code on failure + */ +static int max30210_channel_get(const struct device *dev, enum sensor_channel chan, + struct sensor_value *val) +{ + struct max30210_data *data = dev->data; + + if (chan != SENSOR_CHAN_AMBIENT_TEMP) { + LOG_ERR("Unsupported channel: %d", chan); + return -ENOTSUP; + } + /** 0.005/LSB*/ + int32_t value = sign_extend(data->temp_data, 15) * 5000; + + return sensor_value_from_micro(val, value); +} + +/** + * @brief Probe and configure MAX30210 device + * + * @param dev Device Pointer + * @return int 0 on success, negative error code on failure + */ +static int max30210_probe(const struct device *dev) +{ + const struct max30210_config *config = dev->config; + int ret = 0; + /* Set Alarm High Setup */ + + uint8_t alarm_setup[2]; + + max30210_temp_to_bytes(config->alarm_high_setup, &alarm_setup[0], &alarm_setup[1]); + + ret = max30210_reg_write_multiple(dev, TEMP_ALARM_HIGH_MSB, alarm_setup, 2); + if (ret < 0) { + LOG_ERR("Failed to set Alarm High Setup: %d\n", ret); + return ret; + } + + /* Set Alarm Low Setup */ + + max30210_temp_to_bytes(config->alarm_low_setup, &alarm_setup[0], &alarm_setup[1]); + ret = max30210_reg_write_multiple(dev, TEMP_ALARM_LOW_MSB, alarm_setup, 2); + if (ret < 0) { + LOG_ERR("Failed to set Alarm Low Setup: %d\n", ret); + return ret; + } + + /* Set Increment Fast Threshold */ + ret = max30210_reg_write(dev, TEMP_INC_FAST_THRESH, config->inc_fast_thresh); + if (ret < 0) { + return ret; + } + + /* Set Decrement Fast Threshold */ + ret = max30210_reg_write(dev, TEMP_DEC_FAST_THRESH, config->dec_fast_thresh); + if (ret < 0) { + LOG_ERR("Failed to set Decrement Fast Threshold: %d\n", ret); + return ret; + } + + /* Set Sampling Rate */ + ret = max30210_reg_update(dev, TEMP_CONFIG_2, TEMP_PERIOD_MASK, config->sampling_rate); + if (ret < 0) { + LOG_ERR("Failed to set Sampling Rate: %d\n", ret); + return ret; + } + + /* Set High Trip Count */ + ret = max30210_reg_update(dev, TEMP_ALARM_HIGH_SETUP, TEMP_HI_TRIP_COUNTER_MASK, + (config->hi_trip_count) - 1); + if (ret < 0) { + LOG_ERR("Failed to set High Trip Count: %d\n", ret); + return ret; + } + + /* Set High Non-Consecutive Mode */ + ret = max30210_reg_update(dev, TEMP_ALARM_HIGH_SETUP, TEMP_HI_ALARM_TRIP_MASK, + config->hi_trip_non_consecutive); + if (ret < 0) { + LOG_ERR("Failed to set High Non-Consecutive Mode: %d\n", ret); + return ret; + } + + /* Set Low Trip Count */ + ret = max30210_reg_update(dev, TEMP_ALARM_LOW_SETUP, TEMP_LO_TRIP_COUNTER_MASK, + (config->lo_trip_count) - 1); + if (ret < 0) { + LOG_ERR("Failed to set Low Trip Count: %d\n", ret); + return ret; + } + + /* Set Low Non-Consecutive Mode */ + ret = max30210_reg_update(dev, TEMP_ALARM_LOW_SETUP, TEMP_LO_ALARM_TRIP_MASK, + config->lo_trip_non_consecutive); + if (ret < 0) { + LOG_ERR("Failed to set Low Non-Consecutive Mode: %d\n", ret); + return ret; + } + + ret = max30210_reg_update(dev, TEMP_CONFIG_1, CHG_DET_EN_MASK, 1); + if (ret < 0) { + LOG_ERR("Failed to enable Change Detection: %d\n", ret); + return ret; + } + if (config->init_start) { + return max30210_attr_set_continuous_conversion_mode(dev); + } + return 0; +} + +/** + * @brief Initialize MAX30210 device + * + * @param dev Device Pointer + * @return int 0 on success, negative error code on failure + */ +static int max30210_init(const struct device *dev) +{ + const struct max30210_config *config = dev->config; + uint8_t part_id; + uint8_t status; + + if (!i2c_is_ready_dt(&config->i2c)) { + return -ENODEV; + } + /* Check PART_ID */ + int ret = max30210_reg_read(dev, PART_ID, &part_id, 1); + + if (ret < 0) { + LOG_ERR("Failed to read PART_ID: %d\n", ret); + return ret; + } + + if (part_id != MAX30210_PART_ID) { + LOG_ERR("Invalid PART_ID: 0x%02X\n", part_id); + return -ENODEV; + } + /* Perform Software Reset */ + ret = max30210_reg_write(dev, SYS_CONFIG, RESET_MASK); + if (ret < 0) { + LOG_ERR("Failed to perform software reset: %d\n", ret); + return ret; + } + + ret = max30210_reg_read(dev, STATUS, &status, 1); + if (ret < 0) { + LOG_ERR("Failed to read STATUS register: %d\n", ret); + return ret; + } + + ret = max30210_probe(dev); + if (ret < 0) { + LOG_ERR("Failed to probe MAX30210: %d\n", ret); + return ret; + } + +#ifdef CONFIG_MAX30210_TRIGGER + if (max30210_init_interrupt(dev)) { + LOG_ERR("Failed to initialize interrupts\n"); + return -EIO; + } +#endif + + LOG_DBG("MAX30210 device initialized successfully with Part ID: 0x%02X\n", part_id); + return 0; +} + +#define MAX30210_CONFIG(inst) \ + .sampling_rate = DT_INST_PROP_OR(inst, sampling_rate, 0), \ + .hi_trip_count = DT_INST_PROP(inst, hi_trip_count), \ + .lo_trip_count = DT_INST_PROP(inst, lo_trip_count), \ + .hi_trip_non_consecutive = DT_INST_PROP(inst, hi_trip_non_consecutive), \ + .lo_trip_non_consecutive = DT_INST_PROP(inst, lo_trip_non_consecutive), \ + .alarm_high_setup = DT_INST_PROP_OR(inst, alarm_high_setup, INT16_MAX), \ + .alarm_low_setup = DT_INST_PROP_OR(inst, alarm_low_setup, INT16_MIN), \ + .inc_fast_thresh = DT_INST_PROP_OR(inst, inc_fast_thresh, 0), \ + .dec_fast_thresh = DT_INST_PROP_OR(inst, dec_fast_thresh, 0), \ + .init_start = DT_INST_PROP(inst, start_continuous_conversion) + +static DEVICE_API(sensor, max30210_driver_api) = { + .attr_set = max30210_attr_set, + .sample_fetch = max30210_sample_fetch, + .channel_get = max30210_channel_get, +#ifdef CONFIG_MAX30210_TRIGGER + .trigger_set = max30210_trigger_set, +#endif +}; + +#define MAX30210_DEFINE(inst) \ + static struct max30210_data max30210_prv_data_##inst; \ + static const struct max30210_config max30210_config_##inst = { \ + .i2c = I2C_DT_SPEC_INST_GET(inst), \ + MAX30210_CONFIG(inst), \ + IF_ENABLED(CONFIG_MAX30210_TRIGGER,\ + (.interrupt_gpio = \ + GPIO_DT_SPEC_INST_GET_OR( \ + inst, interrupt_gpios, {0}),)) }; \ + SENSOR_DEVICE_DT_INST_DEFINE(inst, &max30210_init, NULL, &max30210_prv_data_##inst, \ + &max30210_config_##inst, POST_KERNEL, \ + CONFIG_SENSOR_INIT_PRIORITY, &max30210_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(MAX30210_DEFINE) diff --git a/drivers/sensor/adi/max30210/max30210.h b/drivers/sensor/adi/max30210/max30210.h new file mode 100644 index 000000000000..32f95436eb62 --- /dev/null +++ b/drivers/sensor/adi/max30210/max30210.h @@ -0,0 +1,271 @@ +/* + * Copyright (c) 2025 Analog Devices, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_SENSOR_MAX30210_MAX30210_H_ +#define ZEPHYR_DRIVERS_SENSOR_MAX30210_MAX30210_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** Register addresses */ +#define STATUS 0x00u +#define INTERRUPT_ENABLE 0x02u +#define FIFO_WR_PTR 0x04u +#define FIFO_RD_PTR 0x05u +#define FIFO_COUNTER_1 0x06u +#define FIFO_COUNTER_2 0x07u +#define FIFO_DATA 0x08u +#define FIFO_CONFIG_1 0x09u +#define FIFO_CONFIG_2 0x0Au +#define SYS_CONFIG 0x11u +#define PIN_CONFIG 0x12u +#define TEMP_ALARM_HIGH_SETUP 0x20u +#define TEMP_ALARM_LOW_SETUP 0x21u +#define TEMP_ALARM_HIGH_MSB 0x22u +#define TEMP_ALARM_HIGH_LSB 0x23u +#define TEMP_ALARM_LOW_MSB 0x24u +#define TEMP_ALARM_LOW_LSB 0x25u +#define TEMP_INC_FAST_THRESH 0x26u +#define TEMP_DEC_FAST_THRESH 0x27u +#define TEMP_CONFIG_1 0x28u +#define TEMP_CONFIG_2 0x29u +#define TEMP_CONVERT 0x2Au +#define TEMP_DATA_MSB 0x2Bu +#define TEMP_DATA_LSB 0x2Cu +#define TEMP_SLOPE_MSB 0x2Du +#define TEMP_SLOPE_LSB 0x2Eu +#define UNIQUE_ID1 0x30u +#define UNIQUE_ID2 0x31u +#define UNIQUE_ID3 0x32u +#define UNIQUE_ID4 0x33u +#define UNIQUE_ID5 0x34u +#define UNIQUE_ID6 0x35u +#define PART_ID 0xFFu + +/** Status Register Masks */ +#define PWR_RDY_MASK BIT(0) +#define TEMP_HI_MASK BIT(2) +#define TEMP_LO_MASK BIT(3) +#define TEMP_INC_FAST_MASK BIT(4) +#define TEMP_DEC_FAST_MASK BIT(5) +#define TEMP_RDY_MASK BIT(6) +#define FIFO_FULL_MASK BIT(7) + +/** Interrupt Enable Register Masks */ +#define TEMP_HI_EN_MASK BIT(2) +#define TEMP_LO_EN_MASK BIT(3) +#define TEMP_INC_FAST_EN_MASK BIT(4) +#define TEMP_DEC_FAST_EN_MASK BIT(5) +#define TEMP_RDY_EN_MASK BIT(6) +#define FIFO_FULL_EN_MASK BIT(7) + +/** FIFO Write Pointer Masks */ +#define WRITE_PTR_MASK GENMASK(5, 0) + +/** FIFO Read Pointer Masks */ +#define READ_PTR_MASK GENMASK(5, 0) + +/** FIFO Counter 1 Register Masks */ +#define FIFO_OVERFLOW_COUNTER_MASK GENMASK(5, 0) + +/** FIFO Counter 2 Register Masks */ +#define FIFO_DATA_COUNT_MSB_MASK GENMASK(5, 0) + +/** FIFO Data Masks */ +#define FIFO_DATA_MASK GENMASK(7, 0) + +/** FIFO Config 1 Register Masks */ +#define FIFO_A_FULL_MASK GENMASK(5, 0) + +/** FIFO Config 2 Register Masks */ +#define FLUSH_FIFO_MASK BIT(4) +#define FIFO_STAT_CLEAR_MASK BIT(3) +#define FIFO_FULL_TYPE_MASK BIT(2) +#define FIFO_ROLL_OVER_MASK BIT(1) /* Ignored when in Auto Mode */ + +/** System Configuration Register Masks */ +#define RESET_MASK BIT(0) + +/** Pin Configuration Register Masks */ +#define EXT_CVT_EN_MASK BIT(7) +#define EXT_CVT_ICFG_MASK BIT(6) +#define INT_FCFG_MASK GENMASK(3, 2) +#define INT_OCFG_MASK GENMASK(1, 0) + +/** Temperature Alarm High Setup Register Masks */ +#define TEMP_HI_DET_COUNTER_MASK GENMASK(7, 5) +#define TEMP_HI_ALARM_TRIP_MASK BIT(3) +#define TEMP_HI_TRIP_COUNTER_MASK GENMASK(2, 1) +#define TEMP_RST_HI_COUNTER BIT(0) + +/** Temperature Alarm Low Setup Register Masks */ +#define TEMP_LO_DET_COUNTER_MASK GENMASK(7, 5) +#define TEMP_LO_ALARM_TRIP_MASK BIT(3) +#define TEMP_LO_TRIP_COUNTER_MASK GENMASK(2, 1) +#define TEMP_RST_LO_COUNTER BIT(0) + +/** Temperature Alarm High MSB Register Masks */ +#define TEMP_HI_MSB_MASK GENMASK(7, 0) + +/** Temperature Alarm High LSB Register Masks */ +#define TEMP_HI_LSB_MASK GENMASK(7, 0) + +/** Temperature Alarm Low MSB Register Masks */ +#define TEMP_LO_MSB_MASK GENMASK(7, 0) + +/** Temperature Alarm Low LSB Register Masks */ +#define TEMP_LO_LSB_MASK GENMASK(7, 0) + +/** Temperature Increment Fast Threshold Register Masks */ +#define TEMP_INC_FAST_THRESH_MASK GENMASK(7, 0) + +/** Temperature Decrement Fast Threshold Register Masks */ +#define TEMP_DEC_FAST_THRESH_MASK GENMASK(7, 0) + +/** Temperature Configuration 1 Register Masks */ +#define CHG_DET_EN_MASK BIT(3) +#define RATE_CHRG_FILTER_MASK GENMASK(2, 0) + +/** Temperature Configuration 2 Register Masks */ +#define ALERT_MODE_MASK BIT(7) +#define TEMP_PERIOD_MASK GENMASK(3, 0) + +/** Temperature Convert Register Masks */ +#define AUTO_MODE_MASK BIT(1) +#define CONVERT_T_MASK BIT(0) + +/** Temperature Data MSB Register Masks */ +#define TEMP_DATA_MSB_MASK GENMASK(7, 0) + +/** Temperature Data LSB Register Masks */ +#define TEMP_DATA_LSB_MASK GENMASK(7, 0) + +/** Temperature Slope MSB Register Masks */ +#define TEMP_SLOPE_MSB_MASK BIT(0) + +/** Temperature Slope LSB Register Masks */ +#define TEMP_SLOPE_LSB_MASK GENMASK(7, 0) + +/** Unique ID 1 Register Masks */ +#define UNIQUE_ID_1_MASK GENMASK(7, 0) + +/** Unique ID 2 Register Masks */ +#define UNIQUE_ID_2_MASK GENMASK(7, 0) + +/** Unique ID 3 Register Masks */ +#define UNIQUE_ID_3_MASK GENMASK(7, 0) + +/** Unique ID 4 Register Masks */ +#define UNIQUE_ID_4_MASK GENMASK(7, 0) + +/** Unique ID 5 Register Masks */ +#define UNIQUE_ID_5_MASK GENMASK(7, 0) + +/** Unique ID 6 Register Masks */ +#define UNIQUE_ID_6_MASK GENMASK(7, 0) + +/** Part ID Register Masks */ +#define PART_ID_MASK GENMASK(7, 0) + +#define MAX30210_PART_ID 0x45 + +#define MAX30210_BYTES_PER_SAMPLE 3 /* 2 bytes for temperature data, 1 byte for status */ + +#define MAX30210_FIFO_DEPTH 64 + +#define MAX30210_TEMP_MAX_C 164 +#define MAX30210_TEMP_FRAC_MAX_UC 1000000 +#define MAX30210_TEMP_FRAC_STEP_UC 5000 +#define MAX30210_TEMP_COUNTS_PER_C 200 +#define MAX30210_TEMP_REG_BYTES 2 +#define MAX30210_TEMP_SLOPE_MAX_REG_VALUE 255 + +struct max30210_config { + struct i2c_dt_spec i2c; + +#if defined(CONFIG_MAX30210_TRIGGER) + struct gpio_dt_spec interrupt_gpio; /* GPIO for interrupt */ +#endif + int32_t alarm_high_setup; + int32_t alarm_low_setup; + uint8_t inc_fast_thresh; + uint8_t dec_fast_thresh; + uint8_t sampling_rate; + uint8_t hi_trip_count; + uint8_t lo_trip_count; + bool hi_trip_non_consecutive; + bool lo_trip_non_consecutive; + bool init_start; +}; + +struct max30210_data { + uint16_t temp_data; + uint16_t temp_slope; + uint8_t int_status; + uint8_t fifo_data; + uint8_t ovf_counter; + + /** Temperature Configuration */ + uint16_t temp_alarm_high_setup; + uint16_t temp_alarm_low_setup; + uint8_t temp_inc_fast_thresh; + uint8_t temp_dec_fast_thresh; + uint8_t temp_config_1; + uint8_t temp_config_2; + +#ifdef CONFIG_MAX30210_TRIGGER + const struct device *dev; + struct gpio_callback gpio_cb; + + sensor_trigger_handler_t a_fifo_full_handler; + sensor_trigger_handler_t temp_hi_handler; + sensor_trigger_handler_t temp_lo_handler; + sensor_trigger_handler_t temp_inc_fast_handler; + sensor_trigger_handler_t temp_dec_fast_handler; + sensor_trigger_handler_t temp_rdy_handler; + + const struct sensor_trigger *a_fifo_full_trigger; + const struct sensor_trigger *temp_hi_trigger; + const struct sensor_trigger *temp_lo_trigger; + const struct sensor_trigger *temp_inc_fast_trigger; + const struct sensor_trigger *temp_dec_fast_trigger; + const struct sensor_trigger *temp_rdy_trigger; + +#if defined(CONFIG_MAX30210_TRIGGER_OWN_THREAD) + struct k_thread thread; + + K_KERNEL_STACK_MEMBER(thread_stack, CONFIG_MAX30210_THREAD_STACK_SIZE); + struct k_sem gpio_sem; +#elif defined(CONFIG_MAX30210_TRIGGER_GLOBAL_THREAD) + struct k_work work; +#endif /* CONFIG_MAX30210_TRIGGER_OWN_THREAD || CONFIG_MAX30210_TRIGGER_GLOBAL_THREAD*/ + +#endif /* CONFIG_MAX30210_TRIGGER */ +}; + +#ifdef CONFIG_MAX30210_TRIGGER +int max30210_trigger_set(const struct device *dev, const struct sensor_trigger *trig, + sensor_trigger_handler_t handler); + +int max30210_init_interrupt(const struct device *dev); +#endif + +int max30210_reg_read(const struct device *dev, uint8_t reg_addr, uint8_t *val, uint8_t length); + +int max30210_reg_write(const struct device *dev, uint8_t reg_addr, uint8_t val); + +int max30210_reg_write_multiple(const struct device *dev, uint8_t reg_addr, uint8_t *val, + uint8_t length); + +int max30210_reg_update(const struct device *dev, uint8_t reg_addr, uint8_t mask, uint8_t val); +#endif /* ZEPHYR_DRIVERS_SENSOR_MAX30210_MAX30210_H_ */ diff --git a/drivers/sensor/adi/max30210/max30210_trigger.c b/drivers/sensor/adi/max30210/max30210_trigger.c new file mode 100644 index 000000000000..3252ba8a34fd --- /dev/null +++ b/drivers/sensor/adi/max30210/max30210_trigger.c @@ -0,0 +1,311 @@ +/* + * Copyright (c) 2025 Analog Devices Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "max30210.h" +#include + +LOG_MODULE_DECLARE(MAX30210, CONFIG_SENSOR_LOG_LEVEL); +#if defined(CONFIG_MAX30210_TRIGGER_OWN_THREAD) || defined(CONFIG_MAX30210_TRIGGER_GLOBAL_THREAD) +/** + * @brief MAX30210 interrupt handling thread callback + * + * @param dev Device Pointer + */ +static int max30210_thread_cb(const struct device *dev) +{ + const struct max30210_config *config = dev->config; + struct max30210_data *data = dev->data; + int ret; + uint8_t status; + + /*Clear the Status*/ + ret = max30210_reg_read(dev, STATUS, &status, 1); + if (ret < 0) { + LOG_ERR("Failed to read STATUS register: %d\n", ret); + return -EFAULT; + } + + if (data->temp_hi_handler && (status & TEMP_HI_MASK)) { + data->temp_hi_handler(dev, data->temp_hi_trigger); + } + if (data->temp_lo_handler && (status & TEMP_LO_MASK)) { + data->temp_lo_handler(dev, data->temp_lo_trigger); + } + if (data->temp_inc_fast_handler && (status & TEMP_INC_FAST_MASK)) { + data->temp_inc_fast_handler(dev, data->temp_inc_fast_trigger); + } + if (data->temp_dec_fast_handler && (status & TEMP_DEC_FAST_MASK)) { + data->temp_dec_fast_handler(dev, data->temp_dec_fast_trigger); + } + if (data->temp_rdy_handler && (status & TEMP_RDY_MASK)) { + data->temp_rdy_handler(dev, data->temp_rdy_trigger); + } + if (data->a_fifo_full_handler && (status & FIFO_FULL_MASK)) { + data->a_fifo_full_handler(dev, data->a_fifo_full_trigger); + } + + ret = gpio_pin_interrupt_configure_dt(&config->interrupt_gpio, GPIO_INT_EDGE_FALLING); + if (ret < 0) { + LOG_ERR("Failed to reconfigure GPIO interrupt: %d\n", ret); + return -EFAULT; + } + return 0; +} + +#endif /* CONFIG_MAX30210_TRIGGER_OWN_THREAD || CONFIG_MAX30210_TRIGGER_GLOBAL_THREAD */ + +/** + * @brief MAX30210 GPIO interrupt callback + * + * @param dev Device Pointer + * @param cb GPIO Callback Pointer + * @param pins Pin Mask + */ +static void max30210_gpio_callback(const struct device *dev, struct gpio_callback *cb, + uint32_t pins) +{ + struct max30210_data *data = CONTAINER_OF(cb, struct max30210_data, gpio_cb); + const struct max30210_config *config = data->dev->config; + + gpio_pin_interrupt_configure_dt(&config->interrupt_gpio, GPIO_INT_DISABLE); + +#if defined(CONFIG_MAX30210_TRIGGER_OWN_THREAD) + k_sem_give(&data->gpio_sem); +#elif defined(CONFIG_MAX30210_TRIGGER_GLOBAL_THREAD) + k_work_submit(&data->work); +#endif +} + +#if defined(CONFIG_MAX30210_TRIGGER_OWN_THREAD) +static void max30210_thread(void *p1, void *p2, void *p3) +{ + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + struct max30210_data *data = p1; + const struct device *dev = data->dev; + int ret; + + while (1) { + k_sem_take(&data->gpio_sem, K_FOREVER); + ret = max30210_thread_cb(dev); + if (ret < 0) { + LOG_ERR("Error in interrupt handling thread: %d\n", ret); + } + } +} +#elif defined(CONFIG_MAX30210_TRIGGER_GLOBAL_THREAD) +static void max30210_work_cb(struct k_work *work) +{ + struct max30210_data *data = CONTAINER_OF(work, struct max30210_data, work); + const struct device *dev = data->dev; + int ret; + + ret = max30210_thread_cb(dev); + if (ret < 0) { + LOG_ERR("Error in interrupt handling work: %d\n", ret); + } +} +#endif + +/** + * @brief Set MAX30210 sensor trigger + * + * @param dev Device Pointer + * @param trig Trigger Pointer + * @param handler Trigger Handler + * @return int 0 on success, negative error code on failure + */ +int max30210_trigger_set(const struct device *dev, const struct sensor_trigger *trig, + sensor_trigger_handler_t handler) +{ + const struct max30210_config *config = dev->config; + struct max30210_data *data = dev->data; + int ret = 0; + uint8_t int_mask = 0, int_en; + uint8_t status; + + if (!config->interrupt_gpio.port) { + LOG_ERR("Interrupt GPIO not configured\n"); + return -ENODEV; + } + + ret = gpio_pin_interrupt_configure_dt(&config->interrupt_gpio, GPIO_INT_DISABLE); + if (ret < 0) { + LOG_ERR("Failed to disable GPIO interrupt: %d\n", ret); + return ret; + } + + switch ((int)trig->type) { + case SENSOR_TRIG_THRESHOLD: + uint8_t temp_hi_setup[2]; + + max30210_reg_read(dev, TEMP_ALARM_HIGH_MSB, temp_hi_setup, 2); + data->temp_alarm_high_setup = (temp_hi_setup[0] << 8) | temp_hi_setup[1]; + + if (data->temp_alarm_high_setup >= 0x7FFF) { + LOG_ERR("Temperature high threshold not set\n"); + } + + else { + data->temp_hi_handler = handler; + data->temp_hi_trigger = trig; + int_mask |= TEMP_HI_MASK; + } + + uint8_t temp_lo_setup[2]; + + max30210_reg_read(dev, TEMP_ALARM_LOW_MSB, temp_lo_setup, 2); + data->temp_alarm_low_setup = (temp_lo_setup[0] << 8) | temp_lo_setup[1]; + if (data->temp_alarm_low_setup == 0x8000) { + LOG_ERR("Temperature low threshold not set\n"); + } + + else { + data->temp_lo_handler = handler; + data->temp_lo_trigger = trig; + int_mask |= TEMP_LO_MASK; + } + break; + + case SENSOR_TRIG_TEMP_INC_FAST: + uint8_t temp_inc_fast_thresh; + + ret = max30210_reg_read(dev, TEMP_INC_FAST_THRESH, &temp_inc_fast_thresh, 1); + if (ret < 0) { + LOG_ERR("Failed to read TEMP_INC_FAST_THRESH: %d\n", ret); + return ret; + } + data->temp_inc_fast_thresh = temp_inc_fast_thresh; + if (data->temp_inc_fast_thresh == 0) { + LOG_ERR("Temperature increase fast threshold not set\n"); + return -EINVAL; + } + + else { + data->temp_inc_fast_handler = handler; + data->temp_inc_fast_trigger = trig; + int_mask |= TEMP_INC_FAST_MASK; + } + break; + + case SENSOR_TRIG_TEMP_DEC_FAST: + uint8_t temp_dec_fast_thresh; + + ret = max30210_reg_read(dev, TEMP_DEC_FAST_THRESH, &temp_dec_fast_thresh, 1); + if (ret < 0) { + LOG_ERR("Failed to read TEMP_DEC_FAST_THRESH: %d\n", ret); + return ret; + } + data->temp_dec_fast_thresh = temp_dec_fast_thresh; + if (data->temp_dec_fast_thresh == 0) { + LOG_ERR("Temperature decrease fast threshold not set\n"); + return -EINVAL; + } + + else { + data->temp_dec_fast_handler = handler; + data->temp_dec_fast_trigger = trig; + int_mask |= TEMP_DEC_FAST_MASK; + } + break; + + case SENSOR_TRIG_DATA_READY: + data->temp_rdy_handler = handler; + data->temp_rdy_trigger = trig; + int_mask |= TEMP_RDY_MASK; + break; + + case SENSOR_TRIG_FIFO_FULL: + data->a_fifo_full_handler = handler; + data->a_fifo_full_trigger = trig; + int_mask |= FIFO_FULL_MASK; + break; + default: + LOG_ERR("Unsupported trigger type: %d\n", trig->type); + return -ENOTSUP; + } + if (handler) { + int_en = 1; + } else { + int_en = 0; + } + + if (sys_count_bits(&int_mask, sizeof(int_mask)) > 1) { + int_en = 0x3; + } + + ret = max30210_reg_update(dev, INTERRUPT_ENABLE, int_mask, int_en); + if (ret < 0) { + LOG_ERR("Failed to update interrupt enable register: %d\n", ret); + return ret; + } + /* Clear Status */ + ret = max30210_reg_read(dev, STATUS, &status, 1); + if (ret < 0) { + LOG_ERR("Failed to read STATUS register: %d\n", ret); + return ret; + } + ret = gpio_pin_interrupt_configure_dt(&config->interrupt_gpio, GPIO_INT_EDGE_FALLING); + if (ret < 0) { + LOG_ERR("Failed to configure GPIO interrupt: %d\n", ret); + return ret; + } + + return 0; +} + +/** + * @brief Initialize MAX30210 interrupt + * + * @param dev Device Pointer + * @return int 0 on success, negative error code on failure + */ +int max30210_init_interrupt(const struct device *dev) +{ + struct max30210_data *data = dev->data; + const struct max30210_config *config = dev->config; + int ret; + + if (!gpio_is_ready_dt(&config->interrupt_gpio)) { + LOG_ERR("Interrupt GPIO not ready\n"); + return -ENODEV; + } + + ret = gpio_pin_configure_dt(&config->interrupt_gpio, GPIO_INPUT); + if (ret < 0) { + LOG_ERR("Failed to configure interrupt GPIO: %d\n", ret); + return ret; + } + + gpio_init_callback(&data->gpio_cb, max30210_gpio_callback, BIT(config->interrupt_gpio.pin)); + + ret = gpio_add_callback(config->interrupt_gpio.port, &data->gpio_cb); + if (ret < 0) { + LOG_ERR("Failed to add GPIO callback: %d\n", ret); + return ret; + } + + ret = gpio_pin_interrupt_configure_dt(&config->interrupt_gpio, GPIO_INT_EDGE_FALLING); + if (ret < 0) { + LOG_ERR("Failed to configure GPIO interrupt: %d\n", ret); + return ret; + } + data->dev = dev; + +#if defined(CONFIG_MAX30210_TRIGGER_OWN_THREAD) + k_sem_init(&data->gpio_sem, 0, K_SEM_MAX_LIMIT); + + k_thread_create(&data->thread, data->thread_stack, CONFIG_MAX30210_THREAD_STACK_SIZE, + (k_thread_entry_t)max30210_thread, data, NULL, NULL, + K_PRIO_COOP(CONFIG_MAX30210_THREAD_PRIORITY), 0, K_NO_WAIT); + + k_thread_name_set(&data->thread, dev->name); +#elif defined(CONFIG_MAX30210_TRIGGER_GLOBAL_THREAD) + data->work.handler = max30210_work_cb; +#endif + return 0; +} diff --git a/dts/bindings/sensor/adi,max30210.yaml b/dts/bindings/sensor/adi,max30210.yaml new file mode 100644 index 000000000000..4c97f7e9789a --- /dev/null +++ b/dts/bindings/sensor/adi,max30210.yaml @@ -0,0 +1,122 @@ +# Copyright (c) 2025 Analog Devices Inc. +# SPDX-License-Identifier: Apache-2.0 +# + +description: MAX30210, a high-accuracy digital temperature sensor from Analog Devices. + +compatible: "adi,max30210" + +include: [sensor-device.yaml, i2c-device.yaml] + +properties: + reg: + required: true + + interrupt-gpios: + type: phandle-array + description: | + The INT1 pin defaults to active low when produced by the sensor. The property value should + ensure the flags properly describe the signal that is presented to the driver. + + sampling-rate: + type: int + description: | + The sampling rate of the sensor in Hz. This value is used to configure the sensor's internal + sampling rate. If not specified, the driver will use a default value of 0.015625 Hz + which is also the reset value. + default: 0x00 + enum: + - 0x0 # 0.015625 Hz + - 0x1 # 0.03125 Hz + - 0x2 # 0.0625 Hz + - 0x3 # 0.125 Hz + - 0x4 # 0.25 Hz + - 0x5 # 0.5 Hz + - 0x6 # 1 Hz + - 0x7 # 2 Hz + - 0x8 # 4 Hz + - 0x9 # 8 Hz + + alarm-high-setup: + type: int + description: | + The high temperature threshold for the sensor in degrees Celsius. When the temperature + exceeds this threshold, the INT1 pin will be asserted. The value is represented as a + signed 16-bit integer in two's complement format, with a resolution of 0.005 degrees Celsius. + Usage: input a temperature in millidegrees Celsius (e.g., 25000 for 25.000°C), and the driver + will convert it to the appropriate register value. Default value is equivalent is 163.835°C + which is equivalent to the reset value (0x7FFF) for ALARM_HI register. + default: 163835 # 163.835°C + + alarm-low-setup: + type: int + description: | + The low temperature threshold for the sensor in degrees Celsius. When the temperature + falls below this threshold, the INT1 pin will be asserted. The value is represented as a + signed 16-bit integer in two's complement format, with a resolution of 0.005 degrees Celsius. + Usage: input a temperature in millidegrees Celsius (e.g., 25000 for 25.000°C), and the driver + will convert it to the appropriate register value. Default value is equivalent is -163.840°C + which is equivalent to the reset value (0x8000) for ALARM_LO register. + default: -163840 # -163.840°C + + inc-fast-thresh: + type: int + description: | + The increment threshold between samples. If the temperature increments + by more than N x 5 m°C between samples, the INT1 pin will be asserted + when interrupts are enabled. The default value is 0, which represents 0 m°C + and corresponds to the device register reset value. + default: 0 + + dec-fast-thresh: + type: int + description: | + The decrement threshold between samples. If the temperature decrements + by more than N x 5 m°C between samples, the INT1 pin will be asserted + when interrupts are enabled. The default value is 0, which represents 0 m°C + and corresponds to the device register reset value. + default: 0 + + hi-trip-count: + type: int + description: | + The number of trip counts exceeding the high temperature threshold that must occur + to assert required to assert the TEMP_HI alarm on the INT1 pin. Default value is 1 + which equates to a single sample exceeding the high temperature threshold and corresponds + to the device register reset value. + default: 1 + enum: + - 1 + - 2 + - 3 + - 4 + + lo-trip-count: + type: int + description: | + The number of trip counts below the low temperature threshold that must occur + to assert required to assert the TEMP_LO alarm on the INT1 pin. Default value is 1 + which equates to a single sample below the low temperature threshold and corresponds + to the device register reset value. + default: 1 + enum: + - 1 + - 2 + - 3 + - 4 + + hi-trip-non-consecutive: + type: boolean + description: | + If true, the high temperature threshold trip count is non-consecutive. + + lo-trip-non-consecutive: + type: boolean + description: | + If true, the low temperature threshold trip count is non-consecutive. + + start-continuous-conversion: + type: boolean + description: | + If true, the sensor will start temperature conversions immediately after initialization. + If false, the sensor will remain in standby mode until explicitly started by the driver. diff --git a/include/zephyr/drivers/sensor/max30210.h b/include/zephyr/drivers/sensor/max30210.h new file mode 100644 index 000000000000..c6fe4962f818 --- /dev/null +++ b/include/zephyr/drivers/sensor/max30210.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2025 Analog Devices Inc. + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_SENSOR_MAX30210_H_ +#define ZEPHYR_INCLUDE_DRIVERS_SENSOR_MAX30210_H_ + +#include + +enum sensor_attribute_max30210 { + SENSOR_ATTR_MAX30210_INTERRUPT_POLARITY = SENSOR_ATTR_PRIV_START, + SENSOR_ATTR_MAX30210_CONTINUOUS_CONVERSION_MODE, + SENSOR_ATTR_MAX30210_TEMP_INC_FAST_THRESH, + SENSOR_ATTR_MAX30210_TEMP_DEC_FAST_THRESH, + SENSOR_ATTR_MAX30210_RATE_CHG_FILTER, + SENSOR_ATTR_MAX30210_HI_TRIP_COUNT, + SENSOR_ATTR_MAX30210_LO_TRIP_COUNT, + SENSOR_ATTR_MAX30210_HI_TRIP_COUNT_RESET, + SENSOR_ATTR_MAX30210_LO_TRIP_COUNT_RESET, + SENSOR_ATTR_MAX30210_HI_NON_CONSECUTIVE_MODE, + SENSOR_ATTR_MAX30210_LO_NON_CONSECUTIVE_MODE, + SENSOR_ATTR_MAX30210_UPPER_THRESH, + SENSOR_ATTR_MAX30210_ALERT_MODE, + SENSOR_ATTR_MAX30210_SOFTWARE_RESET, + SENSOR_ATTR_MAX30210_TEMP_CONVERT, + SENSOR_ATTR_MAX30210_AUTO_MODE +}; + +enum sensor_sampling_rate_max30210 { + SENSOR_SAMPLING_RATE_MAX30210_0_015625 = 0, + SENSOR_SAMPLING_RATE_MAX30210_0_03125, + SENSOR_SAMPLING_RATE_MAX30210_0_0625, + SENSOR_SAMPLING_RATE_MAX30210_0_125, + SENSOR_SAMPLING_RATE_MAX30210_0_25, + SENSOR_SAMPLING_RATE_MAX30210_0_5, + SENSOR_SAMPLING_RATE_MAX30210_1, + SENSOR_SAMPLING_RATE_MAX30210_2, + SENSOR_SAMPLING_RATE_MAX30210_4, + SENSOR_SAMPLING_RATE_MAX30210_8, +}; + +enum sensor_trigger_type_max30210 { + /** Trigger fires on temperature increase beyond threshold */ + SENSOR_TRIG_TEMP_INC_FAST = SENSOR_TRIG_PRIV_START, + /** Trigger fires on temperature decrease beyond threshold */ + SENSOR_TRIG_TEMP_DEC_FAST + /** Trigger fires on temperature configuration change */ +}; + +#endif /* ZEPHYR_INCLUDE_DRIVERS_SENSOR_MAX30210_H_ */ From 0a5d3e44f226e507e2538f8a8a84ebf47f290436 Mon Sep 17 00:00:00 2001 From: Francis Roi Manabat Date: Wed, 17 Dec 2025 13:27:15 +0800 Subject: [PATCH 1504/3659] tests: drivers: build_all: Add build test for MAX30210 Add max30210 sensor to build test. Signed-off-by: Francis Roi Manabat --- tests/drivers/build_all/sensor/i2c.dtsi | 6 ++++++ tests/drivers/build_all/sensor/sensors_trigger_global.conf | 1 + tests/drivers/build_all/sensor/sensors_trigger_none.conf | 1 + tests/drivers/build_all/sensor/sensors_trigger_own.conf | 1 + 4 files changed, 9 insertions(+) diff --git a/tests/drivers/build_all/sensor/i2c.dtsi b/tests/drivers/build_all/sensor/i2c.dtsi index 86d7836d931b..818b05711e0f 100644 --- a/tests/drivers/build_all/sensor/i2c.dtsi +++ b/tests/drivers/build_all/sensor/i2c.dtsi @@ -1482,3 +1482,9 @@ test_i2c_opt3004: opt3004@c4 { compatible = "ti,opt3004"; reg = <0xc4>; }; + +test_i2c_max30210: max30210@c5 { + compatible = "adi,max30210"; + reg = <0xc5>; + interrupt-gpios = <&test_gpio 0 0>; +}; diff --git a/tests/drivers/build_all/sensor/sensors_trigger_global.conf b/tests/drivers/build_all/sensor/sensors_trigger_global.conf index a8a6c0e628f6..d5d0def2d611 100644 --- a/tests/drivers/build_all/sensor/sensors_trigger_global.conf +++ b/tests/drivers/build_all/sensor/sensors_trigger_global.conf @@ -53,6 +53,7 @@ CONFIG_LSM6DSL_TRIGGER_GLOBAL_THREAD=y CONFIG_LSM6DSO16IS_TRIGGER_GLOBAL_THREAD=y CONFIG_LSM6DSO_TRIGGER_GLOBAL_THREAD=y CONFIG_LSM6DSV16X_TRIGGER_GLOBAL_THREAD=y +CONFIG_MAX30210_TRIGGER_GLOBAL_THREAD=y CONFIG_MPU6050_TRIGGER_GLOBAL_THREAD=y CONFIG_MPU9250_TRIGGER_GLOBAL_THREAD=y CONFIG_OPT300X_TRIGGER_GLOBAL_THREAD=y diff --git a/tests/drivers/build_all/sensor/sensors_trigger_none.conf b/tests/drivers/build_all/sensor/sensors_trigger_none.conf index 9ede26b646bb..9e062dc76aed 100644 --- a/tests/drivers/build_all/sensor/sensors_trigger_none.conf +++ b/tests/drivers/build_all/sensor/sensors_trigger_none.conf @@ -54,6 +54,7 @@ CONFIG_LSM6DSL_TRIGGER_NONE=y CONFIG_LSM6DSO16IS_TRIGGER_NONE=y CONFIG_LSM6DSO_TRIGGER_NONE=y CONFIG_LSM6DSV16X_TRIGGER_NONE=y +CONFIG_MAX30210_TRIGGER_NONE=y CONFIG_MC3419_TRIGGER_NONE=y CONFIG_MPU6050_TRIGGER_NONE=y CONFIG_MPU9250_TRIGGER_NONE=y diff --git a/tests/drivers/build_all/sensor/sensors_trigger_own.conf b/tests/drivers/build_all/sensor/sensors_trigger_own.conf index b3bf3f986b85..853ff0e92464 100644 --- a/tests/drivers/build_all/sensor/sensors_trigger_own.conf +++ b/tests/drivers/build_all/sensor/sensors_trigger_own.conf @@ -51,6 +51,7 @@ CONFIG_LSM6DSL_TRIGGER_OWN_THREAD=y CONFIG_LSM6DSO16IS_TRIGGER_OWN_THREAD=y CONFIG_LSM6DSO_TRIGGER_OWN_THREAD=y CONFIG_LSM6DSV16X_TRIGGER_OWN_THREAD=y +CONFIG_MAX30210_TRIGGER_OWN_THREAD=y CONFIG_MC3419_TRIGGER_OWN_THREAD=y CONFIG_MPU6050_TRIGGER_OWN_THREAD=y CONFIG_MPU9250_TRIGGER_OWN_THREAD=y From 1cb9ebaad2e671b25692a7ce0d8ad4ff322873f0 Mon Sep 17 00:00:00 2001 From: Phuc Pham Date: Thu, 4 Dec 2025 17:24:34 +0700 Subject: [PATCH 1505/3659] drivers: timer: Fix incorrect data type use - Fix incorrect data type that caused the timer to malfunction after running for a period of time Signed-off-by: Phuc Pham Signed-off-by: Tien Nguyen --- drivers/timer/renesas_rza2m_os_timer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/timer/renesas_rza2m_os_timer.c b/drivers/timer/renesas_rza2m_os_timer.c index 5109c3f38eea..71942a77877e 100644 --- a/drivers/timer/renesas_rza2m_os_timer.c +++ b/drivers/timer/renesas_rza2m_os_timer.c @@ -89,8 +89,8 @@ static uint32_t cyc_per_tick; #define CYC_PER_TICK cyc_per_tick static struct k_spinlock lock; -static uint64_t last_cycle; -static uint64_t last_tick; +static uint32_t last_cycle; +static uint32_t last_tick; static uint32_t last_elapsed; extern unsigned int z_clock_hw_cycles_per_sec; From 1eec5dae9fde5b354ab18f4672cf86ded9c0405a Mon Sep 17 00:00:00 2001 From: Phuc Pham Date: Thu, 4 Dec 2025 17:30:11 +0700 Subject: [PATCH 1506/3659] drivers: adc: Add ADC support for Renesas RZ/A2M Add ADC driver support for Renesas RZ/A2M Signed-off-by: Phuc Pham Signed-off-by: Tien Nguyen --- drivers/adc/CMakeLists.txt | 1 + drivers/adc/Kconfig.renesas_rz | 8 + drivers/adc/adc_renesas_rza2m.c | 553 ++++++++++++++++++++++++ dts/bindings/adc/renesas,rza2m-adc.yaml | 50 +++ 4 files changed, 612 insertions(+) create mode 100644 drivers/adc/adc_renesas_rza2m.c create mode 100644 dts/bindings/adc/renesas,rza2m-adc.yaml diff --git a/drivers/adc/CMakeLists.txt b/drivers/adc/CMakeLists.txt index 30e40c25b20d..847cffd5514a 100644 --- a/drivers/adc/CMakeLists.txt +++ b/drivers/adc/CMakeLists.txt @@ -61,6 +61,7 @@ zephyr_library_sources_ifdef(CONFIG_ADC_REALTEK_RTS5912 adc_realtek_rts5912.c) zephyr_library_sources_ifdef(CONFIG_ADC_RENESAS_RA adc_renesas_ra.c) zephyr_library_sources_ifdef(CONFIG_ADC_RENESAS_RX adc_renesas_rx.c) zephyr_library_sources_ifdef(CONFIG_ADC_RENESAS_RZ adc_renesas_rz.c) +zephyr_library_sources_ifdef(CONFIG_ADC_RENESAS_RZA2M adc_renesas_rza2m.c) zephyr_library_sources_ifdef(CONFIG_ADC_RENESAS_RZ_ADC_C adc_renesas_rz.c) zephyr_library_sources_ifdef(CONFIG_ADC_RPI_PICO adc_rpi_pico.c) zephyr_library_sources_ifdef(CONFIG_ADC_SAM adc_sam.c) diff --git a/drivers/adc/Kconfig.renesas_rz b/drivers/adc/Kconfig.renesas_rz index a2840ca7d6e2..269d5a32e8e2 100644 --- a/drivers/adc/Kconfig.renesas_rz +++ b/drivers/adc/Kconfig.renesas_rz @@ -18,3 +18,11 @@ config ADC_RENESAS_RZ_ADC_C select USE_RZ_FSP_ADC help Enable the RZ ADC-C driver. + +config ADC_RENESAS_RZA2M + bool "Renesas A2M ADC Driver" + default y + depends on DT_HAS_RENESAS_RZA2M_ADC_ENABLED + select PINCTRL + help + Enable Renesas ADC Driver. diff --git a/drivers/adc/adc_renesas_rza2m.c b/drivers/adc/adc_renesas_rza2m.c new file mode 100644 index 000000000000..93c4cdfeb101 --- /dev/null +++ b/drivers/adc/adc_renesas_rza2m.c @@ -0,0 +1,553 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT renesas_rza2m_adc + +#include +#include +#include +#include +#include +#include + +#define ADC_CONTEXT_USES_KERNEL_TIMER +#include "adc_context.h" + +LOG_MODULE_REGISTER(adc_renesas_rz, CONFIG_ADC_LOG_LEVEL); + +struct adc_reg { + uint8_t offset, size; +}; + +enum { + RZA2M_ADCSR, /* Control Register */ + RZA2M_ADANSA0, /* Channel Select Register A0 */ + RZA2M_ADADS0, /* Addition/Average Mode Select Register 0 */ + RZA2M_ADADC, /* Addition/Average Count Select Register */ + RZA2M_ADCER, /* Control Extended Register */ + RZA2M_ADSTRGR, /* Start Trigger Select Register */ + RZA2M_ADANSB0, /* Channel Select Register B0 */ + RZA2M_ADDBLDR, /* Data Duplication Register */ + RZA2M_ADRD, /* Self-Diagnosis Data Register */ + RZA2M_ADDR0, /* Data Register 0 */ + RZA2M_ADDR1, /* Data Register 1 */ + RZA2M_ADDR2, /* Data Register 2 */ + RZA2M_ADDR3, /* Data Register 3 */ + RZA2M_ADDR4, /* Data Register 4 */ + RZA2M_ADDR5, /* Data Register 5 */ + RZA2M_ADDR6, /* Data Register 6 */ + RZA2M_ADDR7, /* Data Register 7 */ + RZA2M_ADDISCR, /* Disconnection Detection Control Register */ + RZA2M_ADGSPCR, /* Group Scan Priority Control Register */ + RZA2M_ADDBLDRA, /* Data Duplication Register A */ + RZA2M_ADDBLDRB, /* Data Duplication Register B */ + RZA2M_ADWINMON, /* Compare Function AB Status Monitor Register */ + RZA2M_ADCMPCR, /* Compare Control Register */ + RZA2M_ADCMPANSR0, /* Compare Function Window-A Channel Selection Register 0 */ + RZA2M_ADCMPLR0, /* Compare Function Window-A Comparison Condition Setting Register 0 */ + RZA2M_ADCMPDR0, /* Compare Function Window-A Lower Level Setting Register */ + RZA2M_ADCMPDR1, /* Compare Function Window-A Upper Level Setting Register */ + RZA2M_ADCMPSR0, /* Compare Function Window-A Channel Status Register 0 */ + RZA2M_ADCMPBNSR, /* Compare Function Window-B Channel Selection Register */ + RZA2M_ADWINLLB, /* Compare Function Window-B Lower Level Setting Register */ + RZA2M_ADWINULB, /* Compare Function Window-B Upper Level Setting Register */ + RZA2M_ADCMPBSR, /* Compare Function Window-B Status Register */ + RZA2M_ADANSC0, /* Channel Select Register C0 */ + RZA2M_ADGCTRGR, /* Group C Trigger Select Register */ + RZA2M_ADSSTR0, /* Sampling State Register 0 */ + RZA2M_ADSSTR1, /* Sampling State Register 1 */ + RZA2M_ADSSTR2, /* Sampling State Register 2 */ + RZA2M_ADSSTR3, /* Sampling State Register 3 */ + RZA2M_ADSSTR4, /* Sampling State Register 4 */ + RZA2M_ADSSTR5, /* Sampling State Register 5 */ + RZA2M_ADSSTR6, /* Sampling State Register 6 */ + RZA2M_ADSSTR7, /* Sampling State Register 7 */ + + RZA2M_ADC_NR_REGS, /* Total number of registers */ +}; + +struct adc_rza2m_config { + DEVICE_MMIO_ROM; /* Must be first */ + const struct device *clock_dev; + clock_control_subsys_t clock_subsys; + /* Pinctrl configs */ + const struct pinctrl_dev_config *pcfg; + /* Structure that stores register offset and size information */ + const struct adc_reg *regs; + /* Mask for channels existed in each board */ + uint32_t channel_available_mask; +}; + +struct adc_rza2m_data { + DEVICE_MMIO_RAM; /* Must be first */ + /* Structure that handle state of ongoing read operation */ + struct adc_context ctx; + /* Pointer to RZ ADC own device structure */ + const struct device *dev; + /* Pointer to memory where next sample will be written */ + uint16_t *buf; + /* Mask with channels that will be sampled */ + uint32_t channels; + /* Mask of channels that have been configured via setup API */ + uint32_t configured_channels; + /* Buffer id */ + uint16_t buf_id; +}; + +#define ADC_RZA2M_DEFAULT_ACQ_TIME 11 + +/* ADCSR (Control Register) */ +#define ADCSR_ADST BIT(15) /* A/D Conversion Start */ +#define ADCSR_ADCS_MASK GENMASK(14, 13) /* Scan Mode Select */ +#define ADCSR_ADIE BIT(12) /* Scan End Interrupt Enable */ +#define ADCSR_TRGE BIT(9) /* Trigger Start Enable */ +#define ADCSR_EXTRG BIT(8) /* Trigger Select */ +#define ADCSR_DBLE BIT(7) /* Double Trigger Mode Select */ +#define ADCSR_GBADIE BIT(6) /* Group B Scan End Interrupt Enable */ +#define ADCSR_DBLANS_MASK GENMASK(4, 0) /* Double Trigger Channel Select */ + +/* ADANSA0 (Channel Select Register A0) */ +#define ADANSA0_ANSA0_MASK GENMASK(7, 0) /* A/D Conversion Channel Select */ + +/* ADADS0 (Addition/Average Mode Select Register 0) */ +#define ADADS0_ADS0_MASK GENMASK(7, 0) /* A/D Addition/Average Channel Select */ + +/* ADADC (Addition/Average Count Select Register) */ +#define ADADC_ADC_MASK GENMASK(2, 0) /* Addition Count Select */ +#define ADADC_AVEE BIT(7) /* Average Mode Enable */ + +/* ADCER (Control Extended Register) */ +#define ADCER_ADRFMT BIT(15) /* Data Register Format Select */ +#define ADCER_DIAGM BIT(11) /* Self-Diagnosis Enable */ +#define ADCER_DIAGLD BIT(10) /* Self-Diagnosis Mode Select */ +#define ADCER_DIAGVAL_MASK GENMASK(9, 8) /* Self-Diagnosis Conversion Voltage Select */ +#define ADCER_ACE BIT(5) /* Data Register Automatic Clearing Enable */ +#define ADCER_ADPRC_MASK GENMASK(2, 1) /* Conversion Accuracy */ + +/* clang-format off */ +/* Registers */ +static const struct adc_reg rza2m_regs[RZA2M_ADC_NR_REGS] = { + [RZA2M_ADCSR] = {0x00, 16}, + [RZA2M_ADANSA0] = {0x04, 16}, + [RZA2M_ADADS0] = {0x08, 16}, + [RZA2M_ADADC] = {0x0C, 8}, + [RZA2M_ADCER] = {0x0E, 16}, + [RZA2M_ADSTRGR] = {0x10, 16}, + [RZA2M_ADANSB0] = {0x14, 16}, + [RZA2M_ADDBLDR] = {0x18, 16}, + [RZA2M_ADRD] = {0x1E, 16}, + [RZA2M_ADDR0] = {0x20, 16}, + [RZA2M_ADDR1] = {0x22, 16}, + [RZA2M_ADDR2] = {0x24, 16}, + [RZA2M_ADDR3] = {0x26, 16}, + [RZA2M_ADDR4] = {0x28, 16}, + [RZA2M_ADDR5] = {0x2A, 16}, + [RZA2M_ADDR6] = {0x2C, 16}, + [RZA2M_ADDR7] = {0x2E, 16}, + [RZA2M_ADDISCR] = {0x7A, 8}, + [RZA2M_ADGSPCR] = {0x80, 16}, + [RZA2M_ADDBLDRA] = {0x84, 16}, + [RZA2M_ADDBLDRB] = {0x86, 16}, + [RZA2M_ADWINMON] = {0x8C, 8}, + [RZA2M_ADCMPCR] = {0x90, 16}, + [RZA2M_ADCMPANSR0] = {0x94, 16}, + [RZA2M_ADCMPLR0] = {0x98, 16}, + [RZA2M_ADCMPDR0] = {0x9C, 16}, + [RZA2M_ADCMPDR1] = {0x9E, 16}, + [RZA2M_ADCMPSR0] = {0xA0, 16}, + [RZA2M_ADCMPBNSR] = {0xA6, 8}, + [RZA2M_ADWINLLB] = {0xA8, 16}, + [RZA2M_ADWINULB] = {0xAA, 16}, + [RZA2M_ADCMPBSR] = {0xAC, 8}, + [RZA2M_ADANSC0] = {0xD4, 16}, + [RZA2M_ADGCTRGR] = {0xD9, 8}, + [RZA2M_ADSSTR0] = {0xE0, 8}, + [RZA2M_ADSSTR1] = {0xE1, 8}, + [RZA2M_ADSSTR2] = {0xE2, 8}, + [RZA2M_ADSSTR3] = {0xE3, 8}, + [RZA2M_ADSSTR4] = {0xE4, 8}, + [RZA2M_ADSSTR5] = {0xE5, 8}, + [RZA2M_ADSSTR6] = {0xE6, 8}, + [RZA2M_ADSSTR7] = {0xE7, 8}, +}; +/* clang-format on */ + +static __maybe_unused uint8_t adc_rza2m_read_8(const struct device *dev, uint32_t offs) +{ + const struct adc_rza2m_config *config = dev->config; + uint32_t offset = config->regs[offs].offset; + + return sys_read8(DEVICE_MMIO_GET(dev) + offset); +} + +static void adc_rza2m_write_8(const struct device *dev, uint32_t offs, uint8_t value) +{ + const struct adc_rza2m_config *config = dev->config; + uint32_t offset = config->regs[offs].offset; + + sys_write8(value, DEVICE_MMIO_GET(dev) + offset); +} + +static uint16_t adc_rza2m_read_16(const struct device *dev, uint32_t offs) +{ + const struct adc_rza2m_config *config = dev->config; + uint32_t offset = config->regs[offs].offset; + + return sys_read16(DEVICE_MMIO_GET(dev) + offset); +} + +static void adc_rza2m_write_16(const struct device *dev, uint32_t offs, uint16_t value) +{ + const struct adc_rza2m_config *config = dev->config; + uint32_t offset = config->regs[offs].offset; + + sys_write16(value, DEVICE_MMIO_GET(dev) + offset); +} + +/** + * @brief Interrupt handler + */ +static void adc_rza2m_isr(const struct device *dev) +{ + struct adc_rza2m_data *data = dev->data; + int16_t *sample_buffer = (int16_t *)data->buf; + uint32_t channels = data->channels; + uint8_t channel_id = 0; + /* Read ADC results for all enabled channels in the current sequence mask */ + while (channels != 0U) { + if ((channels & 0x01U) != 0U) { + sample_buffer[data->buf_id] = + adc_rza2m_read_16(dev, RZA2M_ADDR0 + channel_id); + data->buf_id = data->buf_id + 1; + } + channels >>= 1; + channel_id++; + } + adc_context_on_sampling_done(&data->ctx, dev); +} + +/** + * @brief Setup channels before starting to scan ADC + */ +static int adc_rza2m_channel_setup(const struct device *dev, + const struct adc_channel_cfg *channel_cfg) +{ + struct adc_rza2m_data *data = dev->data; + const struct adc_rza2m_config *config = dev->config; + uint8_t acq_time = 0; + + if (!((config->channel_available_mask & BIT(channel_cfg->channel_id)) != 0)) { + LOG_ERR("Unsupported channel id '%d'", channel_cfg->channel_id); + return -ENOTSUP; + } + + if (channel_cfg->acquisition_time == ADC_ACQ_TIME_DEFAULT) { + acq_time = ADC_RZA2M_DEFAULT_ACQ_TIME; + + } else { + if (ADC_ACQ_TIME_UNIT(channel_cfg->acquisition_time) != ADC_ACQ_TIME_TICKS) { + LOG_ERR("Acquisition time only support ADC_ACQ_TIME_TICKS unit"); + return -ENOTSUP; + } + + if (!IN_RANGE(ADC_ACQ_TIME_VALUE(channel_cfg->acquisition_time), 5, 255)) { + LOG_ERR("Acquisition time value %d is out of range (5~255 ticks)", + channel_cfg->acquisition_time); + return -ENOTSUP; + } + acq_time = ADC_ACQ_TIME_VALUE(channel_cfg->acquisition_time); + } + + if (channel_cfg->differential) { + LOG_ERR("Differential channels are not supported"); + return -ENOTSUP; + } + + if (channel_cfg->gain != ADC_GAIN_1) { + LOG_ERR("Unsupported channel gain %d", channel_cfg->gain); + return -EINVAL; + } + + if (channel_cfg->reference != ADC_REF_INTERNAL) { + LOG_ERR("Unsupported channel reference"); + return -EINVAL; + } + + data->configured_channels |= (1U << channel_cfg->channel_id); + + /* Set acquisition time for each channel */ + adc_rza2m_write_8(dev, RZA2M_ADSSTR0 + channel_cfg->channel_id, acq_time); + + return 0; +} + +/** + * @brief Check if buffer in @p sequence is big enough to hold all ADC samples + */ +static int adc_rza2m_check_buffer_size(const struct device *dev, + const struct adc_sequence *sequence) +{ + uint8_t channels = 0; + size_t needed; + + channels = POPCOUNT(sequence->channels); + + if (sequence->resolution == 8) { + needed = channels * sizeof(uint8_t); + } else { + needed = channels * sizeof(uint16_t); + } + + if (sequence->options) { + needed *= (1 + sequence->options->extra_samplings); + } + + if (sequence->buffer_size < needed) { + return -ENOMEM; + } + + return 0; +} + +/** + * @brief Start processing read request + */ +static int adc_rza2m_start_read(const struct device *dev, const struct adc_sequence *sequence) +{ + const struct adc_rza2m_config *config = dev->config; + struct adc_rza2m_data *data = dev->data; + uint8_t adadc = 0; + uint16_t adcer; + int err; + + if (sequence->channels == 0) { + LOG_ERR("No channel to read"); + return -EINVAL; + } + + switch (sequence->resolution) { + case 8: + adcer = adc_rza2m_read_16(dev, RZA2M_ADCER); + adcer &= ~ADCER_ADPRC_MASK; + adcer |= FIELD_PREP(ADCER_ADPRC_MASK, 0x02); + break; + case 10: + adcer = adc_rza2m_read_16(dev, RZA2M_ADCER); + adcer &= ~ADCER_ADPRC_MASK; + adcer |= FIELD_PREP(ADCER_ADPRC_MASK, 0x01); + break; + case 12: + adcer = adc_rza2m_read_16(dev, RZA2M_ADCER); + adcer &= ~ADCER_ADPRC_MASK; + adcer |= FIELD_PREP(ADCER_ADPRC_MASK, 0x00); + break; + default: + LOG_ERR("Invalid resolution value %d, (valid value: 8, 10, 12)", + sequence->resolution); + return -EINVAL; + } + + switch (sequence->oversampling) { + case 0: + adadc = 0; + break; + case 1: + adadc |= FIELD_PREP(ADADC_ADC_MASK, 0x01) | ADADC_AVEE; + break; + case 2: + adadc |= FIELD_PREP(ADADC_ADC_MASK, 0x03) | ADADC_AVEE; + break; + default: + LOG_ERR("Invalid oversampling value %d (valid value: 0, 1, 2)", + sequence->oversampling); + return -EINVAL; + } + + if ((sequence->channels & ~config->channel_available_mask) != 0) { + LOG_ERR("Unsupported channels in mask: 0x%08x", sequence->channels); + return -ENOTSUP; + } + + /* Check if channels have been configured via channel_setup */ + if ((sequence->channels & ~data->configured_channels) != 0) { + LOG_ERR("Attempted to read from unconfigured channels in mask: 0x%08x", + sequence->channels); + return -EINVAL; + } + + err = adc_rza2m_check_buffer_size(dev, sequence); + + if (err) { + LOG_ERR("Buffer size too small"); + return err; + } + + /* Select input channels for this sequence */ + adc_rza2m_write_16(dev, RZA2M_ADANSA0, sequence->channels); + /* Set oversampling */ + adc_rza2m_write_16(dev, RZA2M_ADADS0, sequence->channels); + adc_rza2m_write_8(dev, RZA2M_ADADC, adadc); + /* Set resolution */ + adc_rza2m_write_16(dev, RZA2M_ADCER, adcer); + + data->buf_id = 0; + data->buf = sequence->buffer; + adc_context_start_read(&data->ctx, sequence); + adc_context_wait_for_completion(&data->ctx); + + return 0; +} + +/** + * @brief Start processing read request asynchronously + */ +static int adc_rza2m_read_async(const struct device *dev, const struct adc_sequence *sequence, + struct k_poll_signal *async) +{ + struct adc_rza2m_data *data = dev->data; + int err; + + adc_context_lock(&data->ctx, async ? true : false, async); + err = adc_rza2m_start_read(dev, sequence); + adc_context_release(&data->ctx, err); + + return err; +} + +/** + * @brief Start processing read request synchronously + */ +static int adc_rza2m_read(const struct device *dev, const struct adc_sequence *sequence) +{ + return adc_rza2m_read_async(dev, sequence, NULL); +} + +static void adc_context_start_sampling(struct adc_context *ctx) +{ + struct adc_rza2m_data *data = CONTAINER_OF(ctx, struct adc_rza2m_data, ctx); + const struct device *dev = data->dev; + uint16_t reg_16; + + data->channels = ctx->sequence.channels; + /* Start conversion */ + reg_16 = adc_rza2m_read_16(dev, RZA2M_ADCSR); + reg_16 |= ADCSR_ADST; + adc_rza2m_write_16(dev, RZA2M_ADCSR, reg_16); +} + +static void adc_context_update_buffer_pointer(struct adc_context *ctx, bool repeat_sampling) +{ + struct adc_rza2m_data *data = CONTAINER_OF(ctx, struct adc_rza2m_data, ctx); + + if (repeat_sampling) { + data->buf_id = 0; + } +} + +/** + * @brief Set the operational mode common to all channels + */ +static void adc_rza2m_configure(const struct device *dev) +{ + uint16_t adcsr = 0, adcer = 0; + + /* ADCSR: + * Single scan mode, scan end interrupt enable + */ + adcsr |= ADCSR_ADIE; + adc_rza2m_write_16(dev, RZA2M_ADCSR, adcsr); + + /* ADCER: + * Resolution 12-bit, automatic clearing after read, right alignment data format + */ + adcer |= ADCER_ACE; + adc_rza2m_write_16(dev, RZA2M_ADCER, adcer); + + /* Set default values for acquisition time */ + for (int i = 0; i < 8; i++) { + adc_rza2m_write_8(dev, RZA2M_ADSSTR0 + i, ADC_RZA2M_DEFAULT_ACQ_TIME); + } +} + +/** + * @brief Function called on init for each RZA2M ADC device + */ +static int adc_rza2m_init(const struct device *dev) +{ + const struct adc_rza2m_config *config = dev->config; + struct adc_rza2m_data *data = dev->data; + int ret; + + /* Configure dt provided device signals when available */ + ret = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT); + if (ret < 0) { + return ret; + } + + if (!device_is_ready(config->clock_dev)) { + return -ENODEV; + } + + ret = clock_control_on(config->clock_dev, (clock_control_subsys_t)config->clock_subsys); + if (ret < 0) { + return ret; + } + + DEVICE_MMIO_MAP(dev, K_MEM_CACHE_NONE); + + adc_rza2m_configure(dev); + + /* Release context unconditionally */ + adc_context_unlock_unconditionally(&data->ctx); + + return 0; +} + +/** + * ************************* DRIVER REGISTER SECTION *************************** + */ +#define ADC_RZA2M_IRQ_CONNECT(idx, irq_name, isr) \ + do { \ + IRQ_CONNECT(DT_INST_IRQ_BY_NAME(idx, irq_name, irq) - GIC_SPI_INT_BASE, \ + DT_INST_IRQ_BY_NAME(idx, irq_name, priority), isr, \ + DEVICE_DT_INST_GET(idx), DT_INST_IRQ_BY_NAME(idx, irq_name, flags)); \ + irq_enable(DT_INST_IRQ_BY_NAME(idx, irq_name, irq) - GIC_SPI_INT_BASE); \ + } while (0) + +#define ADC_RZA2M_CONFIG_FUNC(idx) ADC_RZA2M_IRQ_CONNECT(idx, scanend, adc_rza2m_isr); + +#define ADC_RZA2M_INIT(idx) \ + PINCTRL_DT_INST_DEFINE(idx); \ + uint32_t clock_subsys##n = DT_INST_CLOCKS_CELL(idx, clk_id); \ + static DEVICE_API(adc, adc_rza2m_api_##idx) = { \ + .channel_setup = adc_rza2m_channel_setup, \ + .read = adc_rza2m_read, \ + .ref_internal = DT_INST_PROP(idx, vref_mv), \ + IF_ENABLED(CONFIG_ADC_ASYNC, \ + (.read_async = adc_rza2m_read_async))}; \ + static struct adc_rza2m_config adc_rza2m_config_##idx = { \ + DEVICE_MMIO_ROM_INIT(DT_DRV_INST(idx)), \ + .clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(idx)), \ + .clock_subsys = (clock_control_subsys_t)(&clock_subsys##n), \ + .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(idx), \ + .regs = rza2m_regs, \ + .channel_available_mask = DT_INST_PROP(idx, channel_available_mask), \ + }; \ + static struct adc_rza2m_data adc_rza2m_data_##idx = { \ + ADC_CONTEXT_INIT_TIMER(adc_rza2m_data_##idx, ctx), \ + ADC_CONTEXT_INIT_LOCK(adc_rza2m_data_##idx, ctx), \ + ADC_CONTEXT_INIT_SYNC(adc_rza2m_data_##idx, ctx), \ + .dev = DEVICE_DT_INST_GET(idx), \ + }; \ + static int adc_rza2m_init_##idx(const struct device *dev) \ + { \ + ADC_RZA2M_CONFIG_FUNC(idx) \ + return adc_rza2m_init(dev); \ + } \ + DEVICE_DT_INST_DEFINE(idx, adc_rza2m_init_##idx, NULL, &adc_rza2m_data_##idx, \ + &adc_rza2m_config_##idx, POST_KERNEL, CONFIG_ADC_INIT_PRIORITY, \ + &adc_rza2m_api_##idx) + +DT_INST_FOREACH_STATUS_OKAY(ADC_RZA2M_INIT); diff --git a/dts/bindings/adc/renesas,rza2m-adc.yaml b/dts/bindings/adc/renesas,rza2m-adc.yaml new file mode 100644 index 000000000000..8c717ba29b50 --- /dev/null +++ b/dts/bindings/adc/renesas,rza2m-adc.yaml @@ -0,0 +1,50 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +description: "Renesas RZ/A2M ADC driver" + +compatible: "renesas,rza2m-adc" + +include: [adc-controller.yaml, pinctrl-device.yaml] + +properties: + reg: + required: true + + interrupts: + required: true + + vref-mv: + type: int + required: true + description: Indicates the reference voltage of the ADC in mV. + + channel-available-mask: + type: int + required: true + description: Mask for ADC channels existed in each board + + clocks: + required: true + + "#io-channel-cells": + const: 1 + +io-channel-cells: + - input + +child-binding: + properties: + zephyr,acquisition-time: + description: | + Acquisition time for ADC sampling in ADCLK cycles (ticks). + Only the ADC_ACQ_TIME_TICKS unit is supported on this device. + The acquisition time value (in ticks) must be between 5 and 255. + When ADC_ACQ_TIME_DEFAULT is specified, the hardware uses 11 ticks as the default + acquisition time. + zephyr,oversampling: + description: | + Oversampling setting to be used for the channel. + When specified, each sample is averaged from 2^N conversion results + (where N is the provided value). + On this device, N = 0, 1, 2. From 2ef755cd81416a5dc073d6a690b749a4ede752ac Mon Sep 17 00:00:00 2001 From: Phuc Pham Date: Thu, 4 Dec 2025 17:31:46 +0700 Subject: [PATCH 1507/3659] dts: renesas: Add ADC support for Renesas RZ/A2M Add ADC nodes for Renesas RZ/A2M Signed-off-by: Phuc Pham Signed-off-by: Tien Nguyen --- dts/arm/renesas/rz/rza/r7s9210.dtsi | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/dts/arm/renesas/rz/rza/r7s9210.dtsi b/dts/arm/renesas/rz/rza/r7s9210.dtsi index 16b0399a0b90..efa3e8f751a9 100644 --- a/dts/arm/renesas/rz/rza/r7s9210.dtsi +++ b/dts/arm/renesas/rz/rza/r7s9210.dtsi @@ -7,6 +7,7 @@ #include #include #include +#include / { compatible = "renesas,r7s9210"; @@ -319,6 +320,18 @@ }; }; + adc: adc@e8005800 { + compatible = "renesas,rza2m-adc"; + reg = <0xe8005800 0xe8>; + interrupts = ; + interrupt-names = "scanend"; + #io-channel-cells = <1>; + vref-mv = <3300>; + channel-available-mask = <0xFF>; + clocks = <&cpg RZA2M_CLOCK(RZA2M_MODULE_ADC, RZA2M_CLK_P1C)>; + status = "disabled"; + }; + scif0: serial@e8007000 { compatible = "renesas,rza2m-scif-uart"; channel = <0>; From d641a2847c1156c8eba31c538b2f6afab379c90d Mon Sep 17 00:00:00 2001 From: Phuc Pham Date: Thu, 4 Dec 2025 17:34:41 +0700 Subject: [PATCH 1508/3659] boards: renesas: Add ADC support for Renesas RZ/A2M Add ADC support for board Renesas RZ/A2M-EVK Signed-off-by: Phuc Pham Signed-off-by: Tien Nguyen --- boards/renesas/rza2m_evk/rza2m_evk-pinctrl.dtsi | 6 ++++++ boards/renesas/rza2m_evk/rza2m_evk.dts | 6 ++++++ boards/renesas/rza2m_evk/rza2m_evk.yaml | 1 + 3 files changed, 13 insertions(+) diff --git a/boards/renesas/rza2m_evk/rza2m_evk-pinctrl.dtsi b/boards/renesas/rza2m_evk/rza2m_evk-pinctrl.dtsi index 8d076ece20e3..8f8f45a4fda5 100644 --- a/boards/renesas/rza2m_evk/rza2m_evk-pinctrl.dtsi +++ b/boards/renesas/rza2m_evk/rza2m_evk-pinctrl.dtsi @@ -13,4 +13,10 @@ ; /* RXD */ }; }; + + /omit-if-no-ref/ adc_default: adc_default { + adc-pinmux { + pinmux = ; /* AN006 */ + }; + }; }; diff --git a/boards/renesas/rza2m_evk/rza2m_evk.dts b/boards/renesas/rza2m_evk/rza2m_evk.dts index cb38dae33c10..3db33997c522 100644 --- a/boards/renesas/rza2m_evk/rza2m_evk.dts +++ b/boards/renesas/rza2m_evk/rza2m_evk.dts @@ -88,3 +88,9 @@ current-speed = <115200>; status = "okay"; }; + +&adc { + pinctrl-0 = <&adc_default>; + pinctrl-names = "default"; + status = "okay"; +}; diff --git a/boards/renesas/rza2m_evk/rza2m_evk.yaml b/boards/renesas/rza2m_evk/rza2m_evk.yaml index 402c81a73ef5..ef0f7e55ddb9 100644 --- a/boards/renesas/rza2m_evk/rza2m_evk.yaml +++ b/boards/renesas/rza2m_evk/rza2m_evk.yaml @@ -6,6 +6,7 @@ toolchain: - zephyr - gnuarmemb supported: + - adc - uart - gpio vendor: renesas From d6d3a1df23051d000537cb75a0d3ca0886f524f1 Mon Sep 17 00:00:00 2001 From: Phuc Pham Date: Thu, 4 Dec 2025 17:37:25 +0700 Subject: [PATCH 1509/3659] tests: drivers: adc: Add ADC support for Renesas RZ/A2M Add ADC tests support for board RZ/A2M-EVK Signed-off-by: Phuc Pham Signed-off-by: Tien Nguyen --- .../adc/adc_api/boards/rza2m_evk.overlay | 26 +++++++++++++++++++ .../adc_error_cases/boards/rza2m_evk.overlay | 17 ++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 tests/drivers/adc/adc_api/boards/rza2m_evk.overlay create mode 100644 tests/drivers/adc/adc_error_cases/boards/rza2m_evk.overlay diff --git a/tests/drivers/adc/adc_api/boards/rza2m_evk.overlay b/tests/drivers/adc/adc_api/boards/rza2m_evk.overlay new file mode 100644 index 000000000000..0dd094025689 --- /dev/null +++ b/tests/drivers/adc/adc_api/boards/rza2m_evk.overlay @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + zephyr,user { + io-channels = <&adc 6>; + }; +}; + +&adc { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + + channel@6 { + reg = <6>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,resolution = <12>; + zephyr,acquisition-time = ; + zephyr,vref-mv = <3300>; + }; +}; diff --git a/tests/drivers/adc/adc_error_cases/boards/rza2m_evk.overlay b/tests/drivers/adc/adc_error_cases/boards/rza2m_evk.overlay new file mode 100644 index 000000000000..60a751d96a56 --- /dev/null +++ b/tests/drivers/adc/adc_error_cases/boards/rza2m_evk.overlay @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + adc = &adc; + }; +}; + +&adc { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; +}; From 8a50020b7a896badba60034c1883732c2ae41a50 Mon Sep 17 00:00:00 2001 From: Phuc Pham Date: Thu, 4 Dec 2025 17:39:13 +0700 Subject: [PATCH 1510/3659] samples: drivers: adc: Add ADC support for Renesas RZ/A2M Add ADC samples support for board RZ/A2M-EVK Signed-off-by: Phuc Pham Signed-off-by: Tien Nguyen --- .../adc/adc_dt/boards/rza2m_evk.overlay | 27 +++++++++++++++++++ .../adc/adc_sequence/boards/rza2m_evk.conf | 1 + .../adc/adc_sequence/boards/rza2m_evk.overlay | 26 ++++++++++++++++++ 3 files changed, 54 insertions(+) create mode 100644 samples/drivers/adc/adc_dt/boards/rza2m_evk.overlay create mode 100644 samples/drivers/adc/adc_sequence/boards/rza2m_evk.conf create mode 100644 samples/drivers/adc/adc_sequence/boards/rza2m_evk.overlay diff --git a/samples/drivers/adc/adc_dt/boards/rza2m_evk.overlay b/samples/drivers/adc/adc_dt/boards/rza2m_evk.overlay new file mode 100644 index 000000000000..5bccb0b17e07 --- /dev/null +++ b/samples/drivers/adc/adc_dt/boards/rza2m_evk.overlay @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + zephyr,user { + io-channels = <&adc 6>; + }; +}; + +&adc { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + + channel@6 { + reg = <6>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,resolution = <10>; + zephyr,acquisition-time = ; + zephyr,vref-mv = <3300>; + zephyr,oversampling = <2>; + }; +}; diff --git a/samples/drivers/adc/adc_sequence/boards/rza2m_evk.conf b/samples/drivers/adc/adc_sequence/boards/rza2m_evk.conf new file mode 100644 index 000000000000..65f176fd23b9 --- /dev/null +++ b/samples/drivers/adc/adc_sequence/boards/rza2m_evk.conf @@ -0,0 +1 @@ +CONFIG_SEQUENCE_RESOLUTION=12 diff --git a/samples/drivers/adc/adc_sequence/boards/rza2m_evk.overlay b/samples/drivers/adc/adc_sequence/boards/rza2m_evk.overlay new file mode 100644 index 000000000000..61138e7b2f47 --- /dev/null +++ b/samples/drivers/adc/adc_sequence/boards/rza2m_evk.overlay @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + adc0 = &adc; + }; +}; + +&adc { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + + channel@6 { + reg = <6>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,resolution = <12>; + zephyr,acquisition-time = ; + zephyr,vref-mv = <3300>; + }; +}; From 06503ceb0207acb0feedc323c8d73504d28bc4ba Mon Sep 17 00:00:00 2001 From: Alexandre Bailon Date: Fri, 12 Dec 2025 10:28:28 +0100 Subject: [PATCH 1511/3659] ieee802154: cc13xx_cc26xx: Improve channel selection When using OpenThread, set_channel operation may be called often with the same channel number. Everytime, even if the channel has not changed, the driver stop all the radio operations, restart the synthesizer and then restart RX operations. This behavior prevents OpenThread joiner to work correcly. This updates the driver to only stop radio operations if this is really required. Signed-off-by: Alexandre Bailon --- drivers/ieee802154/ieee802154_cc13xx_cc26xx.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/drivers/ieee802154/ieee802154_cc13xx_cc26xx.c b/drivers/ieee802154/ieee802154_cc13xx_cc26xx.c index 2ddc73432bd7..472400315fe0 100644 --- a/drivers/ieee802154/ieee802154_cc13xx_cc26xx.c +++ b/drivers/ieee802154/ieee802154_cc13xx_cc26xx.c @@ -172,8 +172,8 @@ static inline int ieee802154_cc13xx_cc26xx_channel_to_frequency( } } -static int ieee802154_cc13xx_cc26xx_set_channel(const struct device *dev, - uint16_t channel) +static int ieee802154_cc13xx_cc26xx_do_set_channel(const struct device *dev, + uint16_t channel, bool force) { int ret; RF_CmdHandle cmd_handle; @@ -181,6 +181,11 @@ static int ieee802154_cc13xx_cc26xx_set_channel(const struct device *dev, uint16_t freq, fract; struct ieee802154_cc13xx_cc26xx_data *drv_data = dev->data; + /* Only stop radio operations and setup RX operations if really needed */ + if (channel == drv_data->cmd_ieee_rx.channel && !force) { + return 0; + } + ret = ieee802154_cc13xx_cc26xx_channel_to_frequency(channel, &freq, &fract); if (ret < 0) { return ret; @@ -226,6 +231,12 @@ static int ieee802154_cc13xx_cc26xx_set_channel(const struct device *dev, return ret; } +static int ieee802154_cc13xx_cc26xx_set_channel(const struct device *dev, + uint16_t channel) +{ + return ieee802154_cc13xx_cc26xx_do_set_channel(dev, channel, false); +} + /* TODO remove when rf driver bugfix is pulled in */ static int ieee802154_cc13xx_cc26xx_reset_channel( const struct device *dev) @@ -240,7 +251,7 @@ static int ieee802154_cc13xx_cc26xx_reset_channel( LOG_DBG("re-setting channel to %u", channel); - return ieee802154_cc13xx_cc26xx_set_channel(dev, channel); + return ieee802154_cc13xx_cc26xx_do_set_channel(dev, channel, true); } static int From 3d11f60b583a7728c87a37c66c5670eadda467b8 Mon Sep 17 00:00:00 2001 From: Alexandre Bailon Date: Fri, 12 Dec 2025 10:40:13 +0100 Subject: [PATCH 1512/3659] ieee802154: cc13xx_cc26xx: Make filter more reliable The radio driver updates the filters but never submit the new ones to the radio core. The filters was only applied later thanks, probably during a channel selection that was happening often. Update the driver stop RX operation and restart it using the new filters. Signed-off-by: Alexandre Bailon --- drivers/ieee802154/ieee802154_cc13xx_cc26xx.c | 20 +++++++++++++++++-- drivers/ieee802154/ieee802154_cc13xx_cc26xx.h | 1 + 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/drivers/ieee802154/ieee802154_cc13xx_cc26xx.c b/drivers/ieee802154/ieee802154_cc13xx_cc26xx.c index 472400315fe0..b75b8c1715a1 100644 --- a/drivers/ieee802154/ieee802154_cc13xx_cc26xx.c +++ b/drivers/ieee802154/ieee802154_cc13xx_cc26xx.c @@ -223,6 +223,7 @@ static int ieee802154_cc13xx_cc26xx_do_set_channel(const struct device *dev, ret = -EIO; goto out; } + drv_data->rx_handle = cmd_handle; ret = 0; @@ -260,11 +261,15 @@ ieee802154_cc13xx_cc26xx_filter(const struct device *dev, bool set, const struct ieee802154_filter *filter) { struct ieee802154_cc13xx_cc26xx_data *drv_data = dev->data; + RF_CmdHandle cmd_handle; + int ret = 0; if (!set) { return -ENOTSUP; } + RF_cancelCmd(drv_data->rf_handle, drv_data->rx_handle, 0); + if (type == IEEE802154_FILTER_TYPE_IEEE_ADDR) { memcpy((uint8_t *)&drv_data->cmd_ieee_rx.localExtAddr, filter->ieee_addr, @@ -274,10 +279,21 @@ ieee802154_cc13xx_cc26xx_filter(const struct device *dev, bool set, } else if (type == IEEE802154_FILTER_TYPE_PAN_ID) { drv_data->cmd_ieee_rx.localPanID = filter->pan_id; } else { - return -ENOTSUP; + ret = -ENOTSUP; } - return 0; + /* Run BG receive process with requested filter updated */ + drv_data->cmd_ieee_rx.status = IDLE; + cmd_handle = RF_scheduleCmd(drv_data->rf_handle, + (RF_Op *)&drv_data->cmd_ieee_rx, RF_PriorityNormal, + cmd_ieee_rx_callback, RF_EventRxEntryDone); + if (cmd_handle < 0) { + LOG_ERR("Failed to post RX command (%d)", cmd_handle); + return -EIO; + } + drv_data->rx_handle = cmd_handle; + + return ret; } static int ieee802154_cc13xx_cc26xx_set_txpower(const struct device *dev, diff --git a/drivers/ieee802154/ieee802154_cc13xx_cc26xx.h b/drivers/ieee802154/ieee802154_cc13xx_cc26xx.h index 507478a1716f..2947fdbbab0f 100644 --- a/drivers/ieee802154/ieee802154_cc13xx_cc26xx.h +++ b/drivers/ieee802154/ieee802154_cc13xx_cc26xx.h @@ -93,6 +93,7 @@ struct ieee802154_cc13xx_cc26xx_data { #endif /* CONFIG_SOC_CCxx52x */ volatile int16_t saved_cmdhandle; + volatile RF_CmdHandle rx_handle; }; #endif /* ZEPHYR_DRIVERS_IEEE802154_IEEE802154_CC13XX_CC26XX_H_ */ From 76e862cd1390372b0acc45ad940f6dee28bae5bc Mon Sep 17 00:00:00 2001 From: Muhammed Asif Date: Wed, 3 Dec 2025 16:55:19 +0530 Subject: [PATCH 1513/3659] dts: arm: microchip: same5xd5x: Add watchdog node in devicetree - Adds devicetree node of watchdog in same5xd5x family - Adds the binding yaml for g1 driver of watchdog Signed-off-by: Muhammed Asif --- .../sam/sam_d5x_e5x/common/samd5xe5x.dtsi | 20 ++++++- dts/bindings/watchdog/microchip,wdt-g1.yaml | 58 +++++++++++++++++++ 2 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 dts/bindings/watchdog/microchip,wdt-g1.yaml diff --git a/dts/arm/microchip/sam/sam_d5x_e5x/common/samd5xe5x.dtsi b/dts/arm/microchip/sam/sam_d5x_e5x/common/samd5xe5x.dtsi index 85afd619591b..9c3830c91ac5 100644 --- a/dts/arm/microchip/sam/sam_d5x_e5x/common/samd5xe5x.dtsi +++ b/dts/arm/microchip/sam/sam_d5x_e5x/common/samd5xe5x.dtsi @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025 Microchip Technology Inc. + * Copyright (c) 2025-2026 Microchip Technology Inc. * * SPDX-License-Identifier: Apache-2.0 */ @@ -10,6 +10,10 @@ #include / { + aliases { + watchdog0 = &wdt; + }; + cpus { #address-cells = <1>; #size-cells = <0>; @@ -98,6 +102,20 @@ reg = <0x40000c00 0x400>; }; + wdt: watchdog@40002000 { + compatible = "microchip,wdt-g1"; + reg = <0x40002000 13>; + interrupts = <10 0>; + interrupt-names = "wdt-ew"; + clocks = <&mclkperiph CLOCK_MCHP_MCLKPERIPH_ID_APBA_WDT>; + clock-names = "mclk"; + max-installable-timeout-count = <1>; + max-timeout-window = <0x4000>; /* 16384 milliseconds */ + max-timeout-window-mode = <0x8000>;/* 32768 milliseconds */ + min-window-limit = <0x8>;/* 8 milliseconds */ + status = "disabled"; + }; + rtc: rtc@40002400 { compatible = "microchip,rtc-g1"; reg = <0x40002400 0x400>; diff --git a/dts/bindings/watchdog/microchip,wdt-g1.yaml b/dts/bindings/watchdog/microchip,wdt-g1.yaml new file mode 100644 index 000000000000..a52a97d8dffa --- /dev/null +++ b/dts/bindings/watchdog/microchip,wdt-g1.yaml @@ -0,0 +1,58 @@ +# Copyright (c) 2025-2026 Microchip Technologies Inc. +# SPDX-License-Identifier: Apache-2.0 + +title: Microchip Watchdog g1 driver + +description: | + Microchip Watchdog driver bindings. + + Group g1 Watchdog driver supports following hardware peripherals: + - module name="WDT" id="U2251" version="1.1.0" + +compatible: "microchip,wdt-g1" + +include: base.yaml + +properties: + reg: + required: true + description: | + Specifies the base address and size of the register block for the watchdog + timer. + + clocks: + required: true + description: | + Defines the clock sources used by the watchdog timer peripheral. + + clock-names: + required: true + description: | + Names of the clocks referenced in the "clocks" property, used to identify + the clock sources + + max-installable-timeout-count: + type: int + required: true + description: | + Specifies the maximum number of timeout counts that can be configured for + the watchdog timer. + + max-timeout-window: + type: int + required: true + description: | + Defines the maximum timeout window period for the watchdog timer. + + max-timeout-window-mode: + type: int + required: true + description: | + Indicates the maximum timeout period in window mode for the watchdog + timer. + + min-window-limit: + type: int + required: true + description: | + Indicates the minimum window limit for the watchdog timer in window mode From e452c05026eadd4ee8646a19b83bf63f54389690 Mon Sep 17 00:00:00 2001 From: Muhammed Asif Date: Wed, 3 Dec 2025 16:59:21 +0530 Subject: [PATCH 1514/3659] drivers: watchdog: microchip: watchdog g1 driver - Adds watchdog g1 driver for microchip devices Signed-off-by: Muhammed Asif --- drivers/watchdog/CMakeLists.txt | 1 + drivers/watchdog/Kconfig | 1 + drivers/watchdog/Kconfig.mchp | 10 + drivers/watchdog/wdt_mchp_g1.c | 572 ++++++++++++++++++++++++++++++++ 4 files changed, 584 insertions(+) create mode 100644 drivers/watchdog/Kconfig.mchp create mode 100644 drivers/watchdog/wdt_mchp_g1.c diff --git a/drivers/watchdog/CMakeLists.txt b/drivers/watchdog/CMakeLists.txt index 7cefe1cc1f20..f8fe5d2f08c2 100644 --- a/drivers/watchdog/CMakeLists.txt +++ b/drivers/watchdog/CMakeLists.txt @@ -27,6 +27,7 @@ zephyr_library_sources_ifdef(CONFIG_WDT_ITE_IT8XXX2 wdt_ite_it8xxx2.c) zephyr_library_sources_ifdef(CONFIG_WDT_IWDG_WCH wdt_iwdg_wch.c) zephyr_library_sources_ifdef(CONFIG_WDT_LITEX wdt_litex.c) zephyr_library_sources_ifdef(CONFIG_WDT_MAX32 wdt_max32.c) +zephyr_library_sources_ifdef(CONFIG_WDT_MCHP_G1 wdt_mchp_g1.c) zephyr_library_sources_ifdef(CONFIG_WDT_MCUX_COP wdt_mcux_cop.c) zephyr_library_sources_ifdef(CONFIG_WDT_MCUX_IMX_WDOG wdt_mcux_imx_wdog.c) zephyr_library_sources_ifdef(CONFIG_WDT_MCUX_RTWDOG wdt_mcux_rtwdog.c) diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index df2ca0029bfa..b0eab2b86a9a 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -83,6 +83,7 @@ source "drivers/watchdog/Kconfig.it51xxx" source "drivers/watchdog/Kconfig.it8xxx2" source "drivers/watchdog/Kconfig.litex" source "drivers/watchdog/Kconfig.max32" +source "drivers/watchdog/Kconfig.mchp" source "drivers/watchdog/Kconfig.mcux" source "drivers/watchdog/Kconfig.mcux_imx" source "drivers/watchdog/Kconfig.npcx" diff --git a/drivers/watchdog/Kconfig.mchp b/drivers/watchdog/Kconfig.mchp new file mode 100644 index 000000000000..13e570b14f0c --- /dev/null +++ b/drivers/watchdog/Kconfig.mchp @@ -0,0 +1,10 @@ +# Copyright (c) 2025-2026 Microchip Technology Inc. +# SPDX-License-Identifier: Apache-2.0 + +config WDT_MCHP_G1 + bool "Microchip G1 Watchdog (WDT) Driver" + default y + depends on DT_HAS_MICROCHIP_WDT_G1_ENABLED + select HAS_WDT_DISABLE_AT_BOOT + help + Enable WDT driver for Microchip G1 IPs. diff --git a/drivers/watchdog/wdt_mchp_g1.c b/drivers/watchdog/wdt_mchp_g1.c new file mode 100644 index 000000000000..3749883fc72a --- /dev/null +++ b/drivers/watchdog/wdt_mchp_g1.c @@ -0,0 +1,572 @@ +/* + * Copyright (c) 2025-2026 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include + +#define DT_DRV_COMPAT microchip_wdt_g1 + +LOG_MODULE_REGISTER(wdt_mchp_g1, CONFIG_WDT_LOG_LEVEL); + +#define WDT_LOCK_TIMEOUT K_MSEC(10) +#define MAX_INSTALLABLE_TIMEOUT_COUNT (DT_PROP(DT_NODELABEL(wdt), max_installable_timeout_count)) +#define MAX_TIMEOUT_WINDOW (DT_PROP(DT_NODELABEL(wdt), max_timeout_window)) +#define MAX_TIMEOUT_WINDOW_MODE (DT_PROP(DT_NODELABEL(wdt), max_timeout_window_mode)) +#define MIN_WINDOW_LIMIT (DT_PROP(DT_NODELABEL(wdt), min_window_limit)) +#define WDT_FLAG_ONLY_ONE_TIMEOUT_VALUE_SUPPORTED \ + (DT_PROP(DT_NODELABEL(wdog), only_one_timeout_val_supported_flag)) + +/* Either of these bits will be set in case watchdog is turned on */ +#define WDT_ENABLED_BITS_POS (WDT_CTRLA_ENABLE(1) | WDT_CTRLA_ALWAYSON(1)) +#define UINT32_WIDTH 32U +#define TIMER_FREQ_HZ 1024U +#define MS_PER_SEC 1000U + +/* This macro takes an integer input `n` and calculates the period value by + * left-shifting the number 8 by `n` positions. The result of this macro is 8 * 2^n. + */ +#define PERIOD_VALUE(n) (8 << n) +#define TIMEOUT_VALUE_US 1000 +#define DELAY_US 2 + +typedef enum { + NORMAL_MODE = 0, + WINDOW_MODE = 1, +} wdt_mode_t; + +struct wdt_mchp_clock { + const struct device *clock_dev; + clock_control_subsys_t mclk_sys; +}; + +struct wdt_mchp_channel_data { + struct wdt_window window; +}; + +struct wdt_mchp_dev_data { + wdt_callback_t callback; + bool interrupt_enabled; + bool window_mode; + uint8_t installed_timeout_cnt; + struct wdt_mchp_channel_data channel_data[MAX_INSTALLABLE_TIMEOUT_COUNT]; + struct k_mutex lock; +}; + +struct wdt_mchp_dev_cfg { + wdt_registers_t *regs; + void (*irq_config_func)(const struct device *dev); + struct wdt_mchp_clock wdt_clock; +}; + +static inline bool wdt_is_enabled(const wdt_registers_t *regs) +{ + /* the significance of WDT_ENABLED_BITS_POS is that it + * denotes the always on bit and the enable bit + */ + return ((regs->WDT_CTRLA & WDT_ENABLED_BITS_POS) != 0) ? true : false; +} + +/* + * Function to wait for the watchdog timer synchronization. + * + * This function waits until the synchronization busy bit in the watchdog timer + * control register is cleared, indicating that the synchronization is complete. + */ +static void wdt_sync_wait(const wdt_registers_t *regs) +{ + if (WAIT_FOR((regs->WDT_SYNCBUSY == 0), TIMEOUT_VALUE_US, k_busy_wait(DELAY_US)) == false) { + LOG_ERR("Timeout waiting for WDT_SYNCBUSY to clear"); + } +} +/* + * Function to enable or disable watchdog peripheral + * + * It won't be able to disable if the always on bit is turned on + */ + +static int wdt_enable(wdt_registers_t *regs, bool enable) +{ + int ret = 0; + + if (enable != 0) { + regs->WDT_CTRLA |= WDT_CTRLA_ENABLE(1); + } else { + /* check always on bit here */ + if (0 == (regs->WDT_CTRLA & WDT_CTRLA_ALWAYSON(1))) { + regs->WDT_CTRLA &= ~WDT_CTRLA_ENABLE(1); + } else { + LOG_ERR("watchdog disable not supported when always on bit is enabled"); + ret = -ENOTSUP; + } + } + wdt_sync_wait(regs); + LOG_DBG("ctrl reg = 0x%x\n", regs->WDT_CTRLA); + + return ret; +} + +/* + * Function to get the period index for a given timeout value. + * + * This function calculates the number of clock cycles required for the given + * timeout value in milliseconds. It then determines the appropriate period + * index based on the number of clock cycles. The function returns the period + * index. + */ +static uint32_t wdt_get_period_idx(uint32_t timeout_ms) +{ + uint32_t next_period; + uint32_t cycles; + + /* Calculate number of clock cycles @ TIMER_FREQ_HZ input clock */ + cycles = (timeout_ms * TIMER_FREQ_HZ) / MS_PER_SEC; + + /* Minimum wdt period is 8 clock cycles (register value 0) */ + if (cycles <= MIN_WINDOW_LIMIT) { + return 0; + } + + /* Round up to next period and calculate the register value + * This produces a value that is the smallest power of two + * greater than or equal to cycles + */ + next_period = BIT64(UINT32_WIDTH) >> __builtin_clz(cycles - 1); + + return find_msb_set(next_period >> 4); +} + +/* + * Function to get the watchdog timer timeout values. + * + * This function calculates the minimum and maximum timeout values for the + * watchdog timer based on the input parameters. It calculates the appropriate + * period indices for the window closed time and the maximum timeout value. The + * function returns the calculated timeout values. + */ +static struct wdt_mchp_channel_data wdt_get_timeout_val(uint32_t window_closed_time, + uint32_t timeout_max) +{ + struct wdt_mchp_channel_data new_timeout = {0}; + uint8_t window_index = wdt_get_period_idx(window_closed_time); + uint8_t per_index = wdt_get_period_idx(timeout_max - window_closed_time); + + new_timeout.window.min = (window_closed_time ? PERIOD_VALUE(window_index) : 0); + new_timeout.window.max = + (window_closed_time ? (PERIOD_VALUE(per_index) + PERIOD_VALUE(window_index)) + : PERIOD_VALUE(per_index)); + + return new_timeout; +} + +static int wdt_reset_type_set(uint8_t flag) +{ + int ret_val = 0; + + switch (flag) { + case WDT_FLAG_RESET_NONE: + ret_val = -ENOTSUP; + break; + + case WDT_FLAG_RESET_CPU_CORE: + case WDT_FLAG_RESET_SOC: + break; + + default: + ret_val = -EINVAL; + break; + } + + return ret_val; +} + +/* + * Function to validate the watchdog timer window configuration. + * + * This function checks the validity of the minimum and maximum timeout values + * for the watchdog timer window mode. It performs various checks to ensure that + * the timeout values are within the allowed range and that the window + * configuration is valid. If any of the checks fail, the function returns + * failure. + */ +static int wdt_validate_window(uint32_t timeout_min, uint32_t timeout_max) +{ + /* Check whether the timeout max is greater + * than the maximum possible value in window mode + */ + if ((timeout_max >= MAX_TIMEOUT_WINDOW_MODE) && (timeout_min != 0)) { + LOG_ERR("invalid timeout values"); + return -EINVAL; + } + + /* check whether the timeout max given is zero */ + if (timeout_max == 0) { + LOG_ERR("invalid timeout values %d", __LINE__); + return -EINVAL; + } + + /* Check whether the timeout min is not + * less than the minimum possible window + */ + if ((timeout_min < PERIOD_VALUE(0)) && (timeout_min != 0)) { + LOG_ERR("invalid timeout values %d", __LINE__); + return -EINVAL; + } + + /* Ensure that a window is available) */ + if (timeout_min > (timeout_max >> 1)) { + LOG_ERR("invalid timeout values %d", __LINE__); + return -EINVAL; + } + + /* this will ensure that the timeout range is within + * the limit for both normal mode and window mode + */ + if ((timeout_max - timeout_min) > MAX_TIMEOUT_WINDOW) { + LOG_ERR("invalid timeout values %d", __LINE__); + return -EINVAL; + } + + return 0; +} + +static inline int wdt_interrupt_enable(wdt_registers_t *regs) +{ + ARG_UNUSED(regs); + return -ENOTSUP; +} + +static inline int wdt_interrupt_flag_clear(wdt_registers_t *regs) +{ + ARG_UNUSED(regs); + return -ENOTSUP; +} + +static void wdt_window_enable(wdt_registers_t *regs, bool enable) +{ + if (enable != 0) { + regs->WDT_CTRLA |= WDT_CTRLA_WEN(1); + } else { + regs->WDT_CTRLA &= ~WDT_CTRLA_WEN(1); + } + wdt_sync_wait(regs); +} + +static struct wdt_mchp_channel_data +wdt_set_timeout(wdt_registers_t *regs, uint32_t window_closed_time, uint32_t timeout_max) +{ + struct wdt_mchp_channel_data set_timeout = {0}; + uint8_t window = wdt_get_period_idx(window_closed_time); + + /* The difference is taken as the total time of WDT + * defined by the CONFIG.window + CONFIG.per register value + */ + uint8_t per = wdt_get_period_idx(timeout_max - window_closed_time); + + LOG_DBG("window = %d : 0x%x per = %d : 0x%x\n\r", window, WDT_CONFIG_WINDOW(window), per, + WDT_CONFIG_PER(per)); + set_timeout.window.min = window_closed_time ? PERIOD_VALUE(window) : 0; + + /* Based on the mode the window mode or normal mode, timeout max is returned */ + set_timeout.window.max = (window_closed_time ? (PERIOD_VALUE(per) + PERIOD_VALUE(window)) + : PERIOD_VALUE(per)); + regs->WDT_CONFIG = WDT_CONFIG_WINDOW(window) | WDT_CONFIG_PER(per); + wdt_sync_wait(regs); + LOG_DBG("wdt_config = 0x%x\n\r", regs->WDT_CONFIG); + + return set_timeout; +} + +static int wdt_apply_options(wdt_registers_t *regs, uint8_t options) +{ + /* WDT_OPT_PAUSE_HALTED_BY_DBG is supported by default by the peripheral */ + if ((options & WDT_OPT_PAUSE_IN_SLEEP) != 0) { + LOG_ERR("unsupported option selected %s", __func__); + return -ENOTSUP; + } + + return 0; +} + +static void wdt_mchp_isr(const struct device *wdt_dev) +{ + struct wdt_mchp_dev_data *mchp_wdt_data = wdt_dev->data; + const struct wdt_mchp_dev_cfg *const mchp_wdt_cfg = wdt_dev->config; + + wdt_interrupt_flag_clear(mchp_wdt_cfg->regs); + if (mchp_wdt_data->callback != NULL) { + mchp_wdt_data->callback(wdt_dev, 0); + } +} + +static int wdt_mchp_setup(const struct device *wdt_dev, uint8_t options) +{ + struct wdt_mchp_dev_data *mchp_wdt_data = wdt_dev->data; + const struct wdt_mchp_dev_cfg *const mchp_wdt_cfg = wdt_dev->config; + wdt_registers_t *regs = mchp_wdt_cfg->regs; + int ret; + + k_mutex_lock(&mchp_wdt_data->lock, WDT_LOCK_TIMEOUT); + if (wdt_is_enabled(regs) == true) { + k_mutex_unlock(&mchp_wdt_data->lock); + LOG_ERR("Watchdog already setup"); + return -EBUSY; + } + + if (mchp_wdt_data->installed_timeout_cnt == 0) { + k_mutex_unlock(&mchp_wdt_data->lock); + LOG_ERR("No valid timeout installed"); + return -EINVAL; + } + ret = wdt_apply_options(regs, options); + if (ret < 0) { + k_mutex_unlock(&mchp_wdt_data->lock); + LOG_ERR("ret val apply = %d", ret); + return ret; + } + ret = wdt_enable(regs, true); + if (ret < 0) { + k_mutex_unlock(&mchp_wdt_data->lock); + LOG_ERR("wdt_enable failed %d", ret); + return ret; + } + LOG_DBG("watchdog enabled : 0x%x\n\r", wdt_is_enabled(regs)); + k_mutex_unlock(&mchp_wdt_data->lock); + + return 0; +} + +static int wdt_mchp_disable(const struct device *wdt_dev) +{ + struct wdt_mchp_dev_data *mchp_wdt_data = wdt_dev->data; + const struct wdt_mchp_dev_cfg *const mchp_wdt_cfg = wdt_dev->config; + wdt_registers_t *regs = mchp_wdt_cfg->regs; + int ret; + uint32_t irq_key; + + irq_key = irq_lock(); + mchp_wdt_data->installed_timeout_cnt = 0; + + /* if watchdog is not enabled, then return fault */ + if (wdt_is_enabled(regs) == false) { + irq_unlock(irq_key); + LOG_ERR("wdg is already disabled"); + return -EFAULT; + } + ret = wdt_enable(regs, false); + if (ret < 0) { + irq_unlock(irq_key); + LOG_ERR("wdg was not disabled = %d", ret); + return -EPERM; + } + irq_unlock(irq_key); + + return 0; +} + +static int wdt_mchp_install_timeout(const struct device *wdt_dev, const struct wdt_timeout_cfg *cfg) +{ + struct wdt_mchp_dev_data *mchp_wdt_data = wdt_dev->data; + const struct wdt_mchp_dev_cfg *const mchp_wdt_cfg = wdt_dev->config; + wdt_registers_t *regs = mchp_wdt_cfg->regs; + struct wdt_mchp_channel_data *channel_data = mchp_wdt_data->channel_data; + struct wdt_mchp_channel_data actual_set_timeout = {0}; + int ret = 0; + uint32_t irq_key = 0; + + k_mutex_lock(&mchp_wdt_data->lock, WDT_LOCK_TIMEOUT); + mchp_wdt_data->callback = cfg->callback; + mchp_wdt_data->window_mode = (((cfg->window.min) > 0) ? true : false); + mchp_wdt_data->interrupt_enabled = ((mchp_wdt_data->callback != NULL) ? true : false); + + /* CONFIG is enable protected, error out if already enabled */ + if (wdt_is_enabled(regs) != 0) { + k_mutex_unlock(&mchp_wdt_data->lock); + LOG_ERR("Watchdog already setup"); + return -EBUSY; + } + +#if defined(WDT_FLAG_ONLY_ONE_TIMEOUT_VALUE_SUPPORTED) + struct wdt_mchp_channel_data new_set_timeout = {0}; + + /* Check whether the new timeout is different from the already existing timeout */ + if (mchp_wdt_data->installed_timeout_cnt != 0) { + new_set_timeout = wdt_get_timeout_val(cfg->window.min, cfg->window.max); + if ((new_set_timeout.window.min != channel_data[0].window.min) || + (new_set_timeout.window.max != channel_data[0].window.max)) { + k_mutex_unlock(&mchp_wdt_data->lock); + LOG_ERR("invalid timeout val"); + return -EINVAL; + } + } +#endif /* WDT_FLAG_ONLY_ONE_TIMEOUT_VALUE_SUPPORTED */ + + /* if more installable timeouts are not available the count will be + * MAX_INSTALLABLE_TIMEOUT_COUNT + */ + if (mchp_wdt_data->installed_timeout_cnt == MAX_INSTALLABLE_TIMEOUT_COUNT) { + k_mutex_unlock(&mchp_wdt_data->lock); + LOG_ERR("No more timeouts available"); + return -ENOMEM; + } + + /* Set the behaviour of the watchdog peripheral based on the flags supplied */ + ret = wdt_reset_type_set(cfg->flags); + if (ret < 0) { + k_mutex_unlock(&mchp_wdt_data->lock); + LOG_ERR("error in setting reset type %d", ret); + return ret; + } + + /* validate the timeout window to be in the range available for the peripheral */ + ret = wdt_validate_window(cfg->window.min, cfg->window.max); + if (ret < 0) { + k_mutex_unlock(&mchp_wdt_data->lock); + LOG_ERR("timeout out of range"); + return -EINVAL; + } + + /* register the provided callback and enable the interrupt */ + if (mchp_wdt_data->interrupt_enabled != 0) { + mchp_wdt_data->callback = cfg->callback; + ret = wdt_interrupt_enable(regs); + if (ret < 0) { + k_mutex_unlock(&mchp_wdt_data->lock); + LOG_ERR("Interrupt is not supported for this peripeheral"); + return -ENOTSUP; + } + } + + if (mchp_wdt_data->window_mode == WINDOW_MODE) { + wdt_window_enable(regs, true); + } else { /* Normal Mode */ + wdt_window_enable(regs, false); + } + actual_set_timeout = wdt_set_timeout(regs, cfg->window.min, cfg->window.max); + + /* Update the channel_data structure with the window parameters of each channel */ + channel_data[mchp_wdt_data->installed_timeout_cnt].window.max = + actual_set_timeout.window.max; + channel_data[mchp_wdt_data->installed_timeout_cnt].window.min = + actual_set_timeout.window.min; + + LOG_ERR("Rounded off timeout min to %d\nRounded off timeout max to %d", + actual_set_timeout.window.min, actual_set_timeout.window.max); + + /* this will return the channel id and then increment the + * count which will then be used for the next channel. + */ + irq_key = irq_lock(); + ret = (mchp_wdt_data->installed_timeout_cnt)++; + irq_unlock(irq_key); + k_mutex_unlock(&mchp_wdt_data->lock); + + return ret; +} + +static int wdt_mchp_feed(const struct device *wdt_dev, int channel_id) +{ + struct wdt_mchp_dev_data *mchp_wdt_data = wdt_dev->data; + const struct wdt_mchp_dev_cfg *const mchp_wdt_cfg = wdt_dev->config; + wdt_registers_t *regs = mchp_wdt_cfg->regs; + + if (wdt_is_enabled(regs) == false) { + LOG_ERR("Watchdog not setup"); + return -EINVAL; + } + if ((channel_id < 0) || (channel_id >= (mchp_wdt_data->installed_timeout_cnt))) { + LOG_ERR("Invalid channel selected"); + return -EINVAL; + } + if (mchp_wdt_data->installed_timeout_cnt == 0) { + LOG_ERR("No valid timeout installed"); + return -EINVAL; + } + + /* Lock mutex only if feed called from a thread */ + if (false == k_is_in_isr()) { + k_mutex_lock(&mchp_wdt_data->lock, WDT_LOCK_TIMEOUT); + } + regs->WDT_CLEAR = WDT_CLEAR_CLEAR_KEY_Val; + + if (false == k_is_in_isr()) { + k_mutex_unlock(&mchp_wdt_data->lock); + } + + return 0; +} + +static int wdt_mchp_init(const struct device *wdt_dev) +{ + struct wdt_mchp_dev_data *mchp_wdt_data = wdt_dev->data; + const struct wdt_mchp_dev_cfg *const mchp_wdt_cfg = wdt_dev->config; + int ret_val = 0; + + k_mutex_init(&mchp_wdt_data->lock); + +#if defined(CONFIG_WDT_DISABLE_AT_BOOT) + ret_val = wdt_mchp_disable(wdt_dev); + if (ret_val < 0) { + LOG_ERR("Watchdog could not be disabled on startup"); + return -EPERM; + } +#endif /* CONFIG_WDT_DISABLE_AT_BOOT */ + + ret_val = clock_control_on(mchp_wdt_cfg->wdt_clock.clock_dev, + mchp_wdt_cfg->wdt_clock.mclk_sys); + if ((ret_val < 0) && (ret_val != -EALREADY)) { + LOG_ERR("Clock control on failed for MCLK %d", ret_val); + return ret_val; + } + + mchp_wdt_data->installed_timeout_cnt = 0; + mchp_wdt_cfg->irq_config_func(wdt_dev); + + return 0; +} + +static DEVICE_API(wdt, wdt_mchp_api) = { + .setup = wdt_mchp_setup, + .disable = wdt_mchp_disable, + .install_timeout = wdt_mchp_install_timeout, + .feed = wdt_mchp_feed, +}; + +#define WDT_MCHP_IRQ_HANDLER(n) \ + static void wdt_mchp_irq_config_##n(const struct device *wdt_dev) \ + { \ + MCHP_WDT_IRQ_CONNECT(n, 0); \ + } + +#define MCHP_WDT_IRQ_CONNECT(n, m) \ + do { \ + IRQ_CONNECT(DT_INST_IRQ_BY_IDX(n, m, irq), DT_INST_IRQ_BY_IDX(n, m, priority), \ + wdt_mchp_isr, DEVICE_DT_INST_GET(n), 0); \ + irq_enable(DT_INST_IRQ_BY_IDX(n, m, irq)); \ + } while (false); + +#define WDT_MCHP_IRQ_HANDLER_DECL(n) \ + static void wdt_mchp_irq_config_##n(const struct device *wdt_dev) + +#define WDT_MCHP_CONFIG_DEFN(n) \ + static const struct wdt_mchp_dev_cfg wdt_mchp_config_##n = { \ + .regs = (wdt_registers_t *)DT_INST_REG_ADDR(n), \ + .irq_config_func = wdt_mchp_irq_config_##n, \ + .wdt_clock.clock_dev = DEVICE_DT_GET(DT_NODELABEL(clock)), \ + .wdt_clock.mclk_sys = (void *)(DT_INST_CLOCKS_CELL_BY_NAME(n, mclk, subsystem))} + +#define WDT_MCHP_DEVICE_INIT(n) \ + WDT_MCHP_IRQ_HANDLER_DECL(n); \ + WDT_MCHP_CONFIG_DEFN(n); \ + static struct wdt_mchp_dev_data wdt_mchp_data_##n; \ + DEVICE_DT_INST_DEFINE(n, wdt_mchp_init, NULL, &wdt_mchp_data_##n, &wdt_mchp_config_##n, \ + PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &wdt_mchp_api); \ + WDT_MCHP_IRQ_HANDLER(n) + +DT_INST_FOREACH_STATUS_OKAY(WDT_MCHP_DEVICE_INIT) From f2234392350079254a024b8963f586f63458a41e Mon Sep 17 00:00:00 2001 From: Muhammed Asif Date: Wed, 3 Dec 2025 17:01:52 +0530 Subject: [PATCH 1515/3659] boards: microchip: sam_e54_xpro: Updates watchdog to board yaml - Updates the board yaml file with watchdog entry for enabling CI to include watchdog for testing Signed-off-by: Muhammed Asif --- boards/microchip/sam/sam_e54_xpro/sam_e54_xpro.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/boards/microchip/sam/sam_e54_xpro/sam_e54_xpro.yaml b/boards/microchip/sam/sam_e54_xpro/sam_e54_xpro.yaml index e7b65fadb305..7e6ac68cbfb6 100644 --- a/boards/microchip/sam/sam_e54_xpro/sam_e54_xpro.yaml +++ b/boards/microchip/sam/sam_e54_xpro/sam_e54_xpro.yaml @@ -27,4 +27,5 @@ supported: - rtc - shell - uart + - watchdog vendor: microchip From 4fb07b6be0bf6aaa49d2551b86d519fce4cd538c Mon Sep 17 00:00:00 2001 From: farsin NASAR V A Date: Thu, 10 Apr 2025 11:49:28 +0530 Subject: [PATCH 1516/3659] tests: drivers: watchdog: Adds sam_e54 test support files - Adds sam_e54_xpro.overlay files for wdt test projects. - Adds sam_e54_xpro platform allow in testcase.yaml. - Adds wdt board specific configuration in main.c Signed-off-by: farsin NASAR V A --- .../watchdog/wdt_basic_api/boards/sam_e54_xpro.overlay | 9 +++++++++ .../watchdog/wdt_error_cases/boards/sam_e54_xpro.overlay | 9 +++++++++ tests/drivers/watchdog/wdt_error_cases/src/main.c | 9 +++++++++ tests/drivers/watchdog/wdt_error_cases/testcase.yaml | 1 + 4 files changed, 28 insertions(+) create mode 100644 tests/drivers/watchdog/wdt_basic_api/boards/sam_e54_xpro.overlay create mode 100644 tests/drivers/watchdog/wdt_error_cases/boards/sam_e54_xpro.overlay diff --git a/tests/drivers/watchdog/wdt_basic_api/boards/sam_e54_xpro.overlay b/tests/drivers/watchdog/wdt_basic_api/boards/sam_e54_xpro.overlay new file mode 100644 index 000000000000..5686e7fff17c --- /dev/null +++ b/tests/drivers/watchdog/wdt_basic_api/boards/sam_e54_xpro.overlay @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2025-2026 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&wdt { + status = "okay"; +}; diff --git a/tests/drivers/watchdog/wdt_error_cases/boards/sam_e54_xpro.overlay b/tests/drivers/watchdog/wdt_error_cases/boards/sam_e54_xpro.overlay new file mode 100644 index 000000000000..5686e7fff17c --- /dev/null +++ b/tests/drivers/watchdog/wdt_error_cases/boards/sam_e54_xpro.overlay @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2025-2026 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&wdt { + status = "okay"; +}; diff --git a/tests/drivers/watchdog/wdt_error_cases/src/main.c b/tests/drivers/watchdog/wdt_error_cases/src/main.c index c1c62f7d41cf..468118ae4e55 100644 --- a/tests/drivers/watchdog/wdt_error_cases/src/main.c +++ b/tests/drivers/watchdog/wdt_error_cases/src/main.c @@ -69,6 +69,15 @@ #define MAX_INSTALLABLE_TIMEOUTS (1) #define WDT_WINDOW_MAX_ALLOWED (0x40001U) #define DEFAULT_OPTIONS (WDT_OPT_PAUSE_IN_SLEEP | WDT_OPT_PAUSE_HALTED_BY_DBG) +#elif defined(CONFIG_SOC_FAMILY_MICROCHIP_SAM_D5X_E5X) +#define WDT_TEST_FLAGS \ + (WDT_DISABLE_SUPPORTED | WDT_FLAG_RESET_SOC_SUPPORTED | \ + WDT_FLAG_RESET_CPU_CORE_SUPPORTED | WDT_FLAG_ONLY_ONE_TIMEOUT_VALUE_SUPPORTED | \ + WDT_OPT_PAUSE_HALTED_BY_DBG_SUPPORTED) +#define DEFAULT_FLAGS (WDT_FLAG_RESET_SOC) +#define MAX_INSTALLABLE_TIMEOUTS (1) +#define WDT_WINDOW_MAX_ALLOWED (0x4000) +#define DEFAULT_OPTIONS (0) #else /* By default run most of the error checks. * See Readme.txt on how to align test scope for the specific target. diff --git a/tests/drivers/watchdog/wdt_error_cases/testcase.yaml b/tests/drivers/watchdog/wdt_error_cases/testcase.yaml index c48dc0b08bb1..c4e8329cf657 100644 --- a/tests/drivers/watchdog/wdt_error_cases/testcase.yaml +++ b/tests/drivers/watchdog/wdt_error_cases/testcase.yaml @@ -19,6 +19,7 @@ tests: - xg24_rb4187c - xg27_dk2602a - raytac_an54lq_db_15/nrf54l15/cpuapp + - sam_e54_xpro integration_platforms: - nrf54l15dk/nrf54l15/cpuapp - ophelia4ev/nrf54l15/cpuapp From e92fe156f933f8f0b2c1fdd4b0327cc7e17166bf Mon Sep 17 00:00:00 2001 From: Muhammed Asif Date: Tue, 9 Dec 2025 17:03:49 +0530 Subject: [PATCH 1517/3659] samples: watchdog: sam_e54_xpro: Adds the overlay for the board - Adds the overlay for sam_e54_xpro board in the sample for watchdog. Signed-off-by: Muhammed Asif --- samples/drivers/watchdog/boards/sam_e54_xpro.overlay | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 samples/drivers/watchdog/boards/sam_e54_xpro.overlay diff --git a/samples/drivers/watchdog/boards/sam_e54_xpro.overlay b/samples/drivers/watchdog/boards/sam_e54_xpro.overlay new file mode 100644 index 000000000000..5686e7fff17c --- /dev/null +++ b/samples/drivers/watchdog/boards/sam_e54_xpro.overlay @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2025-2026 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&wdt { + status = "okay"; +}; From 290384b8cb833f6f2226dbbe5b9fc66ed6bab214 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Fri, 19 Dec 2025 13:33:39 +0200 Subject: [PATCH 1518/3659] net: dns: Add missing documentation for struct dns_addrinfo The documentation of various fields in "struct dns_addrinfo" were missing. Signed-off-by: Jukka Rissanen --- include/zephyr/net/dns_resolve.h | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/include/zephyr/net/dns_resolve.h b/include/zephyr/net/dns_resolve.h index a8426895b6dd..eeaa1adf2db8 100644 --- a/include/zephyr/net/dns_resolve.h +++ b/include/zephyr/net/dns_resolve.h @@ -284,21 +284,30 @@ int dns_dispatcher_unregister(struct dns_socket_dispatcher *ctx); * Enumerate the extensions that are available in the address info */ enum dns_resolve_extension { - DNS_RESOLVE_NONE = 0, - DNS_RESOLVE_TXT, - DNS_RESOLVE_SRV, + DNS_RESOLVE_NONE = 0, /*<< No extension in use */ + DNS_RESOLVE_TXT, /*<< TXT field is returned */ + DNS_RESOLVE_SRV, /*<< SRV field is returned */ }; +/** TXT record information */ struct dns_resolve_txt { + /** Length of the text field */ size_t textlen; + /** Text field (NULL terminated)*/ char text[DNS_MAX_TEXT_SIZE + 1]; }; +/** SRV record information */ struct dns_resolve_srv { + /** Priority of the server order, lower value means higher priority */ uint16_t priority; + /** Weight of the server for load balancing */ uint16_t weight; + /** Port number of the service */ uint16_t port; + /** Length of the target field */ size_t targetlen; + /** Target field (NULL terminated) */ char target[DNS_MAX_NAME_SIZE + 1]; }; @@ -310,23 +319,27 @@ struct dns_addrinfo { uint8_t ai_family; union { + /** A or AAAA records */ struct { /** Length of the ai_addr field or ai_canonname */ net_socklen_t ai_addrlen; - /* NET_AF_INET or NET_AF_INET6 address info */ + /** NET_AF_INET or NET_AF_INET6 address info */ struct net_sockaddr ai_addr; - /** AF_LOCAL Canonical name of the address */ + /** NET_AF_LOCAL Canonical name of the address */ char ai_canonname[DNS_MAX_NAME_SIZE + 1]; }; - /* AF_UNSPEC extensions */ + /** SRV or TXT records (NET_AF_UNSPEC extension) */ struct { + /** What kind of extension is returned */ enum dns_resolve_extension ai_extension; union { + /** TXT record info */ struct dns_resolve_txt ai_txt; + /** SRV record info */ struct dns_resolve_srv ai_srv; }; }; From 5f0483a8aa0fa8ee1958d00ef9084426e8058856 Mon Sep 17 00:00:00 2001 From: Devika Raju Date: Fri, 19 Dec 2025 09:26:19 +0530 Subject: [PATCH 1519/3659] drivers: wifi: siwx91x: Fix multicast filtering on IGMP leave Device continued receiving multicast data after leaving IGMP group because the driver did not configure the SiWx917 firmware to stop filtering for the multicast MAC address. Register a Zephyr multicast monitor callback (net_if_mcast_mon_register) that calls sl_wifi_configure_multicast_filter() to add or remove multicast MAC filters in the firmware when groups are joined or left. Signed-off-by: Devika Raju --- drivers/wifi/siwx91x/siwx91x_wifi.c | 52 +++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/drivers/wifi/siwx91x/siwx91x_wifi.c b/drivers/wifi/siwx91x/siwx91x_wifi.c index 40778ef8d090..57a5d6a49f01 100644 --- a/drivers/wifi/siwx91x/siwx91x_wifi.c +++ b/drivers/wifi/siwx91x/siwx91x_wifi.c @@ -301,6 +301,56 @@ sl_status_t sl_si91x_host_process_data_frame(sl_wifi_interface_t interface, return SL_STATUS_FAIL; } +static enum ethernet_hw_caps siwx91x_get_capabilities(const struct device *dev) +{ + ARG_UNUSED(dev); + + return ETHERNET_HW_FILTERING; +} + +static int siwx91x_set_config(const struct device *dev, + enum ethernet_config_type type, + const struct ethernet_config *config) +{ + sl_wifi_multicast_filter_info_t filter_info = {}; + sl_status_t status; + + ARG_UNUSED(dev); + + switch (type) { + case ETHERNET_CONFIG_TYPE_FILTER: + memcpy(filter_info.mac_address.octet, config->filter.mac_address.addr, + sizeof(config->filter.mac_address.addr)); + + if (config->filter.set) { + filter_info.command_type = SL_WIFI_MULTICAST_MAC_ADD_BIT; + } else { + filter_info.command_type = SL_WIFI_MULTICAST_MAC_CLEAR_BIT; + } + + status = sl_wifi_configure_multicast_filter(&filter_info); + if (status != SL_STATUS_OK) { + LOG_ERR("Failed to %s multicast filter: 0x%x", + config->filter.set ? "add" : "remove", status); + return -EIO; + } + + LOG_DBG("Multicast filter %s for %02x:%02x:%02x:%02x:%02x:%02x", + config->filter.set ? "added" : "removed", + config->filter.mac_address.addr[0], + config->filter.mac_address.addr[1], + config->filter.mac_address.addr[2], + config->filter.mac_address.addr[3], + config->filter.mac_address.addr[4], + config->filter.mac_address.addr[5]); + return 0; + default: + break; + } + + return -ENOTSUP; +} + #endif static void siwx91x_ethernet_init(struct net_if *iface) @@ -592,6 +642,8 @@ static const struct net_wifi_mgmt_offload siwx91x_api = { .wifi_iface.iface_api.init = siwx91x_iface_init, #ifdef CONFIG_WIFI_SILABS_SIWX91X_NET_STACK_NATIVE .wifi_iface.send = siwx91x_send, + .wifi_iface.get_capabilities = siwx91x_get_capabilities, + .wifi_iface.set_config = siwx91x_set_config, #else .wifi_iface.get_type = siwx91x_get_type, #endif From bd7da95049c19405458d437b6c143ab44d6aec33 Mon Sep 17 00:00:00 2001 From: Lyle Zhu Date: Wed, 24 Dec 2025 14:27:49 +0800 Subject: [PATCH 1520/3659] Bluetooth: Classic: L2CAP: Fix sending buffer reference counting There is a corner case that the ACL_Data_Packet_Length is less than the MPS of the L2CAP BR channel connection. Then the partial data will be sent and the remaining data will be sent in sequence in the function `l2cap_br_data_pull()`. The issue occurs when sending the continuing fragment HCI ACL packet, due to the reference counting of sending buffer is 0. Therefore, the application will be asserted in the function `send_buf()`. Fix the issue by managing the reference count of the sending buffer. Use the function `net_buf_ref()` to increment the reference count of the sending buffer. If the sending buffer is the last fragment, use `net_buf_unref()` to decrement the reference count of the sending buffer to ensure that the send buffer can be properly released when the data is sent out. Signed-off-by: Lyle Zhu --- subsys/bluetooth/host/classic/l2cap_br.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/subsys/bluetooth/host/classic/l2cap_br.c b/subsys/bluetooth/host/classic/l2cap_br.c index 012429eedae0..b290ee6a4c94 100644 --- a/subsys/bluetooth/host/classic/l2cap_br.c +++ b/subsys/bluetooth/host/classic/l2cap_br.c @@ -2,6 +2,7 @@ /* * Copyright (c) 2016 Intel Corporation + * Copyright 2024-2025 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -1565,11 +1566,12 @@ static struct net_buf *l2cap_br_ret_fc_data_pull(struct bt_conn *conn, size_t am struct net_buf *buf; - buf = br_chan->_pdu_buf; + buf = net_buf_ref(br_chan->_pdu_buf); if (br_chan->_pdu_remaining > amount) { br_chan->_pdu_remaining -= amount; } else { + net_buf_unref(br_chan->_pdu_buf); br_chan->_pdu_buf = NULL; br_chan->_pdu_remaining = 0; if (pdu && !pdu->len) { From aba81d54e7f0d71d829a28709cbb0438137f1d61 Mon Sep 17 00:00:00 2001 From: Pisit Sawangvonganan Date: Mon, 5 Jan 2026 01:56:33 +0700 Subject: [PATCH 1521/3659] drivers: spi: avoid duplicating tx/rx length selection logic For clarity and compactness, use `spi_context_max_continuous_chunk()` instead of open-coding the same tx/rx length selection logic. Signed-off-by: Pisit Sawangvonganan --- drivers/spi/spi_renesas_ra_sci_b.c | 8 +------- drivers/spi/spi_renesas_rz_rspi.c | 8 +------- drivers/spi/spi_stm32.c | 8 +------- drivers/spi/spi_xmc4xxx.c | 8 +------- 4 files changed, 4 insertions(+), 28 deletions(-) diff --git a/drivers/spi/spi_renesas_ra_sci_b.c b/drivers/spi/spi_renesas_ra_sci_b.c index 85e56fa3b1b2..be03b5ae9feb 100644 --- a/drivers/spi/spi_renesas_ra_sci_b.c +++ b/drivers/spi/spi_renesas_ra_sci_b.c @@ -156,13 +156,7 @@ static void spi_renesas_ra_sci_b_retransmit(struct spi_renesas_ra_sci_b_data *da { fsp_err_t fsp_err; - if (data->ctx.rx_len == 0) { - data->data_len = data->ctx.tx_len; - } else if (data->ctx.tx_len == 0) { - data->data_len = data->ctx.rx_len; - } else { - data->data_len = MIN(data->ctx.tx_len, data->ctx.rx_len); - } + data->data_len = spi_context_max_continuous_chunk(&data->ctx); if (data->ctx.rx_buf == NULL) { fsp_err = R_SCI_B_SPI_Write(&data->fsp_ctrl, data->ctx.tx_buf, data->data_len, diff --git a/drivers/spi/spi_renesas_rz_rspi.c b/drivers/spi/spi_renesas_rz_rspi.c index c8f1709610f8..eafbce99b4ac 100644 --- a/drivers/spi/spi_renesas_rz_rspi.c +++ b/drivers/spi/spi_renesas_rz_rspi.c @@ -76,13 +76,7 @@ static void spi_rz_rspi_retransmit(const struct device *dev) struct spi_rz_rspi_data *data = dev->data; const struct spi_rz_rspi_config *config = dev->config; - if (data->ctx.rx_len == 0) { - data->data_len = data->ctx.tx_len; - } else if (data->ctx.tx_len == 0) { - data->data_len = data->ctx.rx_len; - } else { - data->data_len = MIN(data->ctx.tx_len, data->ctx.rx_len); - } + data->data_len = spi_context_max_continuous_chunk(&data->ctx); if (data->ctx.tx_buf == NULL) { /* If there is only the rx buffer */ config->fsp_api->read(data->fsp_ctrl, data->ctx.rx_buf, data->data_len, diff --git a/drivers/spi/spi_stm32.c b/drivers/spi/spi_stm32.c index 0a24f3133907..60b897dae5fe 100644 --- a/drivers/spi/spi_stm32.c +++ b/drivers/spi/spi_stm32.c @@ -1498,13 +1498,7 @@ static int transceive_dma(const struct device *dev, data->status_flags = 0; if (transfer_dir == LL_SPI_FULL_DUPLEX) { - if (data->ctx.rx_len == 0) { - dma_len = data->ctx.tx_len; - } else if (data->ctx.tx_len == 0) { - dma_len = data->ctx.rx_len; - } else { - dma_len = MIN(data->ctx.tx_len, data->ctx.rx_len); - } + dma_len = spi_context_max_continuous_chunk(&data->ctx); ret = spi_dma_move_buffers(dev, dma_len); } else if (transfer_dir == LL_SPI_HALF_DUPLEX_TX) { diff --git a/drivers/spi/spi_xmc4xxx.c b/drivers/spi/spi_xmc4xxx.c index ff87a2e98b19..fc4cf86f60a5 100644 --- a/drivers/spi/spi_xmc4xxx.c +++ b/drivers/spi/spi_xmc4xxx.c @@ -400,13 +400,7 @@ static int spi_xmc4xxx_transceive_dma(const struct device *dev, const struct spi XMC_USIC_CH_TBUF_STATUS_BUSY) { }; - if (data->ctx.rx_len == 0) { - dma_len = data->ctx.tx_len; - } else if (data->ctx.tx_len == 0) { - dma_len = data->ctx.rx_len; - } else { - dma_len = MIN(data->ctx.tx_len, data->ctx.rx_len); - } + dma_len = spi_context_max_continuous_chunk(&data->ctx); if (ctx->rx_buf) { From d6cb39852d6b1f87914b9acf5c29dedc60b42715 Mon Sep 17 00:00:00 2001 From: Ian Morris Date: Tue, 6 Jan 2026 19:31:11 -0800 Subject: [PATCH 1522/3659] boards: renesas: ek_ra6m4: add PWM LED alias Added pwm-led0 alias so that basic/blinky_pwm and basic/fade_led samples can be built/run on the ek_ra6m4. Signed-off-by: Ian Morris --- boards/renesas/ek_ra6m4/ek_ra6m4.dts | 10 ++++++++++ boards/renesas/ek_ra6m4/ek_ra6m4.yaml | 1 + 2 files changed, 11 insertions(+) diff --git a/boards/renesas/ek_ra6m4/ek_ra6m4.dts b/boards/renesas/ek_ra6m4/ek_ra6m4.dts index bf49ef63b040..5b664eee0021 100644 --- a/boards/renesas/ek_ra6m4/ek_ra6m4.dts +++ b/boards/renesas/ek_ra6m4/ek_ra6m4.dts @@ -10,6 +10,7 @@ #include #include #include +#include #include "ek_ra6m4-pinctrl.dtsi" @@ -46,6 +47,14 @@ }; }; + pwmleds { + compatible = "pwm-leds"; + + pwm_led1: pwm_led1 { + pwms = <&pwm0 0 PWM_MSEC(20) PWM_POLARITY_NORMAL>; + }; + }; + mikrobus_header: mikrobus-connector { compatible = "mikro-bus"; #gpio-cells = <2>; @@ -146,6 +155,7 @@ aliases { led0 = &led1; + pwm-led0 = &pwm_led1; sw0 = &button0; sw1 = &button1; watchdog0 = &wdt; diff --git a/boards/renesas/ek_ra6m4/ek_ra6m4.yaml b/boards/renesas/ek_ra6m4/ek_ra6m4.yaml index 85317151ba31..d7893d9d92dc 100644 --- a/boards/renesas/ek_ra6m4/ek_ra6m4.yaml +++ b/boards/renesas/ek_ra6m4/ek_ra6m4.yaml @@ -12,4 +12,5 @@ supported: - usbd - watchdog - counter + - pwm vendor: renesas From a4da8962117da7fb9e00665e4da0137274d4cdb6 Mon Sep 17 00:00:00 2001 From: Ian Morris Date: Wed, 7 Jan 2026 20:08:07 -0800 Subject: [PATCH 1523/3659] boards: renesas: ek_ra2l1: add LEDs and alias Added additional LEDs and an alias so that examples such basic/threads will build/run on this board. Signed-off-by: Ian Morris --- boards/renesas/ek_ra2l1/ek_ra2l1.dts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/boards/renesas/ek_ra2l1/ek_ra2l1.dts b/boards/renesas/ek_ra2l1/ek_ra2l1.dts index acb99dd23778..f4aa98c7aaf2 100644 --- a/boards/renesas/ek_ra2l1/ek_ra2l1.dts +++ b/boards/renesas/ek_ra2l1/ek_ra2l1.dts @@ -39,6 +39,16 @@ gpios = <&ioport5 3 GPIO_ACTIVE_HIGH>; label = "LED1"; }; + + led2: led2 { + gpios = <&ioport5 4 GPIO_ACTIVE_HIGH>; + label = "LED2"; + }; + + led3: led3 { + gpios = <&ioport5 5 GPIO_ACTIVE_HIGH>; + label = "LED3"; + }; }; buttons { @@ -59,6 +69,7 @@ aliases { led0 = &led1; + led1 = &led2; sw0 = &button0; sw1 = &button1; watchdog0 = &wdt; From 0b5477cd38eb825ab4967ac7148526a5b5370176 Mon Sep 17 00:00:00 2001 From: Mathieu Choplain Date: Thu, 8 Jan 2026 10:48:18 +0100 Subject: [PATCH 1524/3659] doc: arch: arm_cortex_m: CM0/CM1 can't program custom fault priorities The documentation currently indicates that Cortex-M0 and Cortex-M1 have programmable fault priorities which is not true. Fix this error. Signed-off-by: Mathieu Choplain --- doc/hardware/arch/arm_cortex_m.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/hardware/arch/arm_cortex_m.rst b/doc/hardware/arch/arm_cortex_m.rst index 139f00429d84..4e25ce319bd9 100644 --- a/doc/hardware/arch/arm_cortex_m.rst +++ b/doc/hardware/arch/arm_cortex_m.rst @@ -27,7 +27,7 @@ Arm Cortex-M implementation variants. | **OS Features** | | | | +---------------------------------+-----------------------------------+-----------------+---------+--------+-----------+--------+---------+------------+------------+------------+ | Programmable fault | | | | | | | | | | | -| IRQ priorities | | Y | N | Y | Y | Y | N | Y | Y | Y | +| IRQ priorities | | N | N | Y | Y | Y | N | Y | Y | Y | +---------------------------------+-----------------------------------+-----------------+---------+--------+-----------+--------+---------+------------+------------+------------+ | Single-thread kernel support | | Y | Y | Y | Y | Y | Y | Y | Y | Y | +---------------------------------+-----------------------------------+-----------------+---------+--------+-----------+--------+---------+------------+------------+------------+ From 37f8685ab29adb46f1995249ea57a6a45e3305d6 Mon Sep 17 00:00:00 2001 From: Mathieu Choplain Date: Thu, 8 Jan 2026 11:19:43 +0100 Subject: [PATCH 1525/3659] doc: arch: arm_cortex_m: cleanup zephyr,memory-attr example Remove unnecessary parentheses and switch to the plain variant of the RAM_NOCACHE "attribute". Signed-off-by: Mathieu Choplain --- doc/hardware/arch/arm_cortex_m.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/hardware/arch/arm_cortex_m.rst b/doc/hardware/arch/arm_cortex_m.rst index 4e25ce319bd9..c05c8001e371 100644 --- a/doc/hardware/arch/arm_cortex_m.rst +++ b/doc/hardware/arch/arm_cortex_m.rst @@ -521,7 +521,7 @@ For example, to define a new non-cacheable memory region in devicetree: compatible = "zephyr,memory-region", "mmio-sram"; reg = <0x20300000 0x100000>; zephyr,memory-region = "SRAM_NO_CACHE"; - zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_RAM_NOCACHE) )>; + zephyr,memory-attr = ; }; This will automatically create a new MPU entry in with the correct name, base, From 8f5a5bb7cd87fd154c2a6754907e6d134fc2118b Mon Sep 17 00:00:00 2001 From: Mathieu Choplain Date: Thu, 8 Jan 2026 11:23:24 +0100 Subject: [PATCH 1526/3659] doc: services: mem_mgmt: cleanup zephyr,memory-attr examples Remove whitespace between parentheses and value. This seems to be the only place in tree where such a pattern is found, and it violates the rules of the Devicetree linter executed by CI. Replace ARM-specific MPU attributes with their plain variant, also removing the unnecessary parentheses in the process. Signed-off-by: Mathieu Choplain --- doc/services/mem_mgmt/index.rst | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/doc/services/mem_mgmt/index.rst b/doc/services/mem_mgmt/index.rst index bcdef9fc3cb4..262786ab3cd0 100644 --- a/doc/services/mem_mgmt/index.rst +++ b/doc/services/mem_mgmt/index.rst @@ -19,7 +19,7 @@ out-of-order: mem: memory@10000000 { compatible = "mmio-sram"; reg = <0x10000000 0x1000>; - zephyr,memory-attr = <( DT_MEM_NON_VOLATILE | DT_MEM_CACHEABLE | DT_MEM_OOO )>; + zephyr,memory-attr = <(DT_MEM_NON_VOLATILE | DT_MEM_CACHEABLE | DT_MEM_OOO)>; }; .. note:: @@ -41,7 +41,7 @@ regions out of devicetree defined memory regions, for example: compatible = "mmio-sram"; reg = <0x10000000 0x1000>; zephyr,memory-region = "NOCACHE_REGION"; - zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_RAM_NOCACHE) )>; + zephyr,memory-attr = ; }; See :zephyr_file:`include/zephyr/dt-bindings/memory-attr/memory-attr-arm.h` and @@ -82,12 +82,12 @@ one by renaming the property and changing its value according to the following l .. code-block:: none - "RAM" -> <( DT_ARM_MPU(ATTR_MPU_RAM) )> - "RAM_NOCACHE" -> <( DT_ARM_MPU(ATTR_MPU_RAM_NOCACHE) )> - "FLASH" -> <( DT_ARM_MPU(ATTR_MPU_FLASH) )> - "PPB" -> <( DT_ARM_MPU(ATTR_MPU_PPB) )> - "IO" -> <( DT_ARM_MPU(ATTR_MPU_IO) )> - "EXTMEM" -> <( DT_ARM_MPU(ATTR_MPU_EXTMEM) )> + "RAM" -> + "RAM_NOCACHE" -> + "FLASH" -> + "PPB" -> + "IO" -> + "EXTMEM" -> Memory Attributes Heap Allocator ******************************** @@ -119,26 +119,26 @@ allocate memory from those regions: mem_cacheable: memory@10000000 { compatible = "mmio-sram"; reg = <0x10000000 0x1000>; - zephyr,memory-attr = <( DT_MEM_CACHEABLE | DT_MEM_SW_ALLOC_CACHE )>; + zephyr,memory-attr = <(DT_MEM_CACHEABLE | DT_MEM_SW_ALLOC_CACHE)>; }; mem_non_cacheable: memory@20000000 { compatible = "mmio-sram"; reg = <0x20000000 0x1000>; - zephyr,memory-attr = <( DT_MEM_NON_CACHEABLE | ATTR_SW_ALLOC_NON_CACHE )>; + zephyr,memory-attr = <(DT_MEM_NON_CACHEABLE | ATTR_SW_ALLOC_NON_CACHE)>; }; mem_cacheable_big: memory@30000000 { compatible = "mmio-sram"; reg = <0x30000000 0x10000>; - zephyr,memory-attr = <( DT_MEM_CACHEABLE | DT_MEM_OOO | DT_MEM_SW_ALLOC_CACHE )>; + zephyr,memory-attr = <(DT_MEM_CACHEABLE | DT_MEM_OOO | DT_MEM_SW_ALLOC_CACHE)>; }; mem_cacheable_dma: memory@40000000 { compatible = "mmio-sram"; reg = <0x40000000 0x10000>; - zephyr,memory-attr = <( DT_MEM_CACHEABLE | DT_MEM_DMA | - DT_MEM_SW_ALLOC_CACHE | DT_MEM_SW_ALLOC_DMA )>; + zephyr,memory-attr = <(DT_MEM_CACHEABLE | DT_MEM_DMA | + DT_MEM_SW_ALLOC_CACHE | DT_MEM_SW_ALLOC_DMA)>; }; The user can then dynamically carve memory out of those regions using the From 76dd50833fabb56a8de65f01629f205de6c4f155 Mon Sep 17 00:00:00 2001 From: Camille BAUD Date: Sun, 11 Jan 2026 22:56:11 +0100 Subject: [PATCH 1527/3659] boards: bflb: Add pre_dt_board.cmake to all Add -Wno-unique_unit_address_if_enabled for all boards, as bflb SoCs contains a lot of overlapping peripheral nodes. Signed-off-by: Camille BAUD --- boards/aithinker/ai_m61_32s_kit/pre_dt_board.cmake | 4 ++++ boards/aithinker/ai_m62_12f_kit/pre_dt_board.cmake | 4 ++++ boards/aithinker/ai_wb2_12f_kit/pre_dt_board.cmake | 4 ++++ boards/bflb/bl60x/bl604e_iot_dvk/pre_dt_board.cmake | 4 ++++ boards/doiting/dt_bl10_devkit/pre_dt_board.cmake | 4 ++++ boards/doiting/dt_xt_zb1_devkit/pre_dt_board.cmake | 4 ++++ boards/sipeed/maix_m0s_dock/pre_dt_board.cmake | 4 ++++ 7 files changed, 28 insertions(+) create mode 100644 boards/aithinker/ai_m61_32s_kit/pre_dt_board.cmake create mode 100644 boards/aithinker/ai_m62_12f_kit/pre_dt_board.cmake create mode 100644 boards/aithinker/ai_wb2_12f_kit/pre_dt_board.cmake create mode 100644 boards/bflb/bl60x/bl604e_iot_dvk/pre_dt_board.cmake create mode 100644 boards/doiting/dt_bl10_devkit/pre_dt_board.cmake create mode 100644 boards/doiting/dt_xt_zb1_devkit/pre_dt_board.cmake create mode 100644 boards/sipeed/maix_m0s_dock/pre_dt_board.cmake diff --git a/boards/aithinker/ai_m61_32s_kit/pre_dt_board.cmake b/boards/aithinker/ai_m61_32s_kit/pre_dt_board.cmake new file mode 100644 index 000000000000..c3a69b990ff0 --- /dev/null +++ b/boards/aithinker/ai_m61_32s_kit/pre_dt_board.cmake @@ -0,0 +1,4 @@ +# Copyright The Zephyr Project Contributors +# SPDX-License-Identifier: Apache-2.0 + +list(APPEND EXTRA_DTC_FLAGS "-Wno-unique_unit_address_if_enabled") diff --git a/boards/aithinker/ai_m62_12f_kit/pre_dt_board.cmake b/boards/aithinker/ai_m62_12f_kit/pre_dt_board.cmake new file mode 100644 index 000000000000..c3a69b990ff0 --- /dev/null +++ b/boards/aithinker/ai_m62_12f_kit/pre_dt_board.cmake @@ -0,0 +1,4 @@ +# Copyright The Zephyr Project Contributors +# SPDX-License-Identifier: Apache-2.0 + +list(APPEND EXTRA_DTC_FLAGS "-Wno-unique_unit_address_if_enabled") diff --git a/boards/aithinker/ai_wb2_12f_kit/pre_dt_board.cmake b/boards/aithinker/ai_wb2_12f_kit/pre_dt_board.cmake new file mode 100644 index 000000000000..c3a69b990ff0 --- /dev/null +++ b/boards/aithinker/ai_wb2_12f_kit/pre_dt_board.cmake @@ -0,0 +1,4 @@ +# Copyright The Zephyr Project Contributors +# SPDX-License-Identifier: Apache-2.0 + +list(APPEND EXTRA_DTC_FLAGS "-Wno-unique_unit_address_if_enabled") diff --git a/boards/bflb/bl60x/bl604e_iot_dvk/pre_dt_board.cmake b/boards/bflb/bl60x/bl604e_iot_dvk/pre_dt_board.cmake new file mode 100644 index 000000000000..c3a69b990ff0 --- /dev/null +++ b/boards/bflb/bl60x/bl604e_iot_dvk/pre_dt_board.cmake @@ -0,0 +1,4 @@ +# Copyright The Zephyr Project Contributors +# SPDX-License-Identifier: Apache-2.0 + +list(APPEND EXTRA_DTC_FLAGS "-Wno-unique_unit_address_if_enabled") diff --git a/boards/doiting/dt_bl10_devkit/pre_dt_board.cmake b/boards/doiting/dt_bl10_devkit/pre_dt_board.cmake new file mode 100644 index 000000000000..c3a69b990ff0 --- /dev/null +++ b/boards/doiting/dt_bl10_devkit/pre_dt_board.cmake @@ -0,0 +1,4 @@ +# Copyright The Zephyr Project Contributors +# SPDX-License-Identifier: Apache-2.0 + +list(APPEND EXTRA_DTC_FLAGS "-Wno-unique_unit_address_if_enabled") diff --git a/boards/doiting/dt_xt_zb1_devkit/pre_dt_board.cmake b/boards/doiting/dt_xt_zb1_devkit/pre_dt_board.cmake new file mode 100644 index 000000000000..c3a69b990ff0 --- /dev/null +++ b/boards/doiting/dt_xt_zb1_devkit/pre_dt_board.cmake @@ -0,0 +1,4 @@ +# Copyright The Zephyr Project Contributors +# SPDX-License-Identifier: Apache-2.0 + +list(APPEND EXTRA_DTC_FLAGS "-Wno-unique_unit_address_if_enabled") diff --git a/boards/sipeed/maix_m0s_dock/pre_dt_board.cmake b/boards/sipeed/maix_m0s_dock/pre_dt_board.cmake new file mode 100644 index 000000000000..c3a69b990ff0 --- /dev/null +++ b/boards/sipeed/maix_m0s_dock/pre_dt_board.cmake @@ -0,0 +1,4 @@ +# Copyright The Zephyr Project Contributors +# SPDX-License-Identifier: Apache-2.0 + +list(APPEND EXTRA_DTC_FLAGS "-Wno-unique_unit_address_if_enabled") From 0949f8a52ae981c7422b877e4fdce912b0666e3b Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Mon, 12 Jan 2026 15:38:40 +0100 Subject: [PATCH 1528/3659] drivers: sensor: adi: max30210: Fix build with Clang/LLVM drivers/sensor/adi/max30210/max30210_trigger.c:144:3: error: label followed by a declaration is a C23 extension [-Werror,-Wc23-extensions] 144 | uint8_t temp_hi_setup[2]; | ^ drivers/sensor/adi/max30210/max30210_trigger.c:175:3: error: label followed by a declaration is a C23 extension [-Werror,-Wc23-extensions] 175 | uint8_t temp_inc_fast_thresh; | ^ drivers/sensor/adi/max30210/max30210_trigger.c:196:3: error: label followed by a declaration is a C23 extension [-Werror,-Wc23-extensions] 196 | uint8_t temp_dec_fast_thresh; | ^ Signed-off-by: Henrik Brix Andersen --- drivers/sensor/adi/max30210/max30210_trigger.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/sensor/adi/max30210/max30210_trigger.c b/drivers/sensor/adi/max30210/max30210_trigger.c index 3252ba8a34fd..f3d1d92dd8e4 100644 --- a/drivers/sensor/adi/max30210/max30210_trigger.c +++ b/drivers/sensor/adi/max30210/max30210_trigger.c @@ -140,7 +140,7 @@ int max30210_trigger_set(const struct device *dev, const struct sensor_trigger * } switch ((int)trig->type) { - case SENSOR_TRIG_THRESHOLD: + case SENSOR_TRIG_THRESHOLD: { uint8_t temp_hi_setup[2]; max30210_reg_read(dev, TEMP_ALARM_HIGH_MSB, temp_hi_setup, 2); @@ -170,8 +170,9 @@ int max30210_trigger_set(const struct device *dev, const struct sensor_trigger * int_mask |= TEMP_LO_MASK; } break; + } - case SENSOR_TRIG_TEMP_INC_FAST: + case SENSOR_TRIG_TEMP_INC_FAST: { uint8_t temp_inc_fast_thresh; ret = max30210_reg_read(dev, TEMP_INC_FAST_THRESH, &temp_inc_fast_thresh, 1); @@ -191,8 +192,9 @@ int max30210_trigger_set(const struct device *dev, const struct sensor_trigger * int_mask |= TEMP_INC_FAST_MASK; } break; + } - case SENSOR_TRIG_TEMP_DEC_FAST: + case SENSOR_TRIG_TEMP_DEC_FAST: { uint8_t temp_dec_fast_thresh; ret = max30210_reg_read(dev, TEMP_DEC_FAST_THRESH, &temp_dec_fast_thresh, 1); @@ -212,6 +214,7 @@ int max30210_trigger_set(const struct device *dev, const struct sensor_trigger * int_mask |= TEMP_DEC_FAST_MASK; } break; + } case SENSOR_TRIG_DATA_READY: data->temp_rdy_handler = handler; From 5372b419795a3e93450b3729ce6766283a140428 Mon Sep 17 00:00:00 2001 From: Armando Visconti Date: Tue, 27 May 2025 15:12:32 +0200 Subject: [PATCH 1529/3659] sensor/lsm6dsvxxx: change DT common prop names The Device Tree property names that are common to lsm6dsv16x and lsm6dsv32x drivers are now prefixed with LSM6DSVXXX_ (and not LSM6DSV16X_) just for the sake of clarity. Signed-off-by: Armando Visconti --- drivers/sensor/st/lsm6dsv16x/lsm6dsv16x.c | 4 +- .../sensor/st/lsm6dsv16x/lsm6dsv16x_decoder.c | 66 ++--- .../st/lsm6dsv16x/lsm6dsv16x_rtio_stream.c | 48 ++-- dts/bindings/sensor/st,lsm6dsv16x-common.yaml | 32 +++ dts/bindings/sensor/st,lsm6dsv32x-common.yaml | 32 +++ dts/bindings/sensor/st,lsm6dsvxxx-common.yaml | 252 ++++++++---------- .../zephyr/dt-bindings/sensor/lsm6dsv16x.h | 116 +------- .../zephyr/dt-bindings/sensor/lsm6dsv32x.h | 25 ++ .../zephyr/dt-bindings/sensor/lsm6dsvxxx.h | 98 +++++++ .../stream_fifo/boards/nucleo_f401re.overlay | 10 +- .../stream_fifo/boards/nucleo_h503rb.overlay | 14 +- .../boards/sensortile_box_pro.overlay | 14 +- tests/drivers/build_all/sensor/i2c.dtsi | 5 +- tests/drivers/build_all/sensor/i3c.dtsi | 10 +- 14 files changed, 395 insertions(+), 331 deletions(-) create mode 100644 include/zephyr/dt-bindings/sensor/lsm6dsv32x.h create mode 100644 include/zephyr/dt-bindings/sensor/lsm6dsvxxx.h diff --git a/drivers/sensor/st/lsm6dsv16x/lsm6dsv16x.c b/drivers/sensor/st/lsm6dsv16x/lsm6dsv16x.c index f5fece20cbe7..805e06ec7f7e 100644 --- a/drivers/sensor/st/lsm6dsv16x/lsm6dsv16x.c +++ b/drivers/sensor/st/lsm6dsv16x/lsm6dsv16x.c @@ -1232,11 +1232,11 @@ static int lsm6dsv16x_pm_action(const struct device *dev, enum pm_device_action } break; case PM_DEVICE_ACTION_SUSPEND: - if (lsm6dsv16x_xl_data_rate_set(ctx, LSM6DSV16X_DT_ODR_OFF) < 0) { + if (lsm6dsv16x_xl_data_rate_set(ctx, LSM6DSVXXX_DT_ODR_OFF) < 0) { LOG_ERR("failed to disable accelerometer"); ret = -EIO; } - if (lsm6dsv16x_gy_data_rate_set(ctx, LSM6DSV16X_DT_ODR_OFF) < 0) { + if (lsm6dsv16x_gy_data_rate_set(ctx, LSM6DSVXXX_DT_ODR_OFF) < 0) { LOG_ERR("failed to disable gyroscope"); ret = -EIO; } diff --git a/drivers/sensor/st/lsm6dsv16x/lsm6dsv16x_decoder.c b/drivers/sensor/st/lsm6dsv16x/lsm6dsv16x_decoder.c index 6eac7856e637..9859708b609a 100644 --- a/drivers/sensor/st/lsm6dsv16x/lsm6dsv16x_decoder.c +++ b/drivers/sensor/st/lsm6dsv16x/lsm6dsv16x_decoder.c @@ -15,50 +15,50 @@ LOG_MODULE_REGISTER(LSM6DSV16X_DECODER, CONFIG_SENSOR_LOG_LEVEL); #ifdef CONFIG_LSM6DSV16X_STREAM static const uint32_t accel_period_ns[] = { - [LSM6DSV16X_XL_BATCHED_AT_1Hz875] = UINT32_C(1000000000000) / 1875, - [LSM6DSV16X_XL_BATCHED_AT_7Hz5] = UINT32_C(1000000000000) / 7500, - [LSM6DSV16X_XL_BATCHED_AT_15Hz] = UINT32_C(1000000000) / 15, - [LSM6DSV16X_XL_BATCHED_AT_30Hz] = UINT32_C(1000000000) / 30, - [LSM6DSV16X_XL_BATCHED_AT_60Hz] = UINT32_C(1000000000) / 60, - [LSM6DSV16X_XL_BATCHED_AT_120Hz] = UINT32_C(1000000000) / 120, - [LSM6DSV16X_XL_BATCHED_AT_240Hz] = UINT32_C(1000000000) / 240, - [LSM6DSV16X_XL_BATCHED_AT_480Hz] = UINT32_C(1000000000) / 480, - [LSM6DSV16X_XL_BATCHED_AT_960Hz] = UINT32_C(1000000000) / 960, - [LSM6DSV16X_XL_BATCHED_AT_1920Hz] = UINT32_C(1000000000) / 1920, - [LSM6DSV16X_XL_BATCHED_AT_3840Hz] = UINT32_C(1000000000) / 3840, - [LSM6DSV16X_XL_BATCHED_AT_7680Hz] = UINT32_C(1000000000) / 7680, + [LSM6DSVXXX_DT_XL_BATCHED_AT_1Hz875] = UINT32_C(1000000000000) / 1875, + [LSM6DSVXXX_DT_XL_BATCHED_AT_7Hz5] = UINT32_C(1000000000000) / 7500, + [LSM6DSVXXX_DT_XL_BATCHED_AT_15Hz] = UINT32_C(1000000000) / 15, + [LSM6DSVXXX_DT_XL_BATCHED_AT_30Hz] = UINT32_C(1000000000) / 30, + [LSM6DSVXXX_DT_XL_BATCHED_AT_60Hz] = UINT32_C(1000000000) / 60, + [LSM6DSVXXX_DT_XL_BATCHED_AT_120Hz] = UINT32_C(1000000000) / 120, + [LSM6DSVXXX_DT_XL_BATCHED_AT_240Hz] = UINT32_C(1000000000) / 240, + [LSM6DSVXXX_DT_XL_BATCHED_AT_480Hz] = UINT32_C(1000000000) / 480, + [LSM6DSVXXX_DT_XL_BATCHED_AT_960Hz] = UINT32_C(1000000000) / 960, + [LSM6DSVXXX_DT_XL_BATCHED_AT_1920Hz] = UINT32_C(1000000000) / 1920, + [LSM6DSVXXX_DT_XL_BATCHED_AT_3840Hz] = UINT32_C(1000000000) / 3840, + [LSM6DSVXXX_DT_XL_BATCHED_AT_7680Hz] = UINT32_C(1000000000) / 7680, }; static const uint32_t gyro_period_ns[] = { - [LSM6DSV16X_GY_BATCHED_AT_1Hz875] = UINT32_C(1000000000000) / 1875, - [LSM6DSV16X_GY_BATCHED_AT_7Hz5] = UINT32_C(1000000000000) / 7500, - [LSM6DSV16X_GY_BATCHED_AT_15Hz] = UINT32_C(1000000000) / 15, - [LSM6DSV16X_GY_BATCHED_AT_30Hz] = UINT32_C(1000000000) / 30, - [LSM6DSV16X_GY_BATCHED_AT_60Hz] = UINT32_C(1000000000) / 60, - [LSM6DSV16X_GY_BATCHED_AT_120Hz] = UINT32_C(1000000000) / 120, - [LSM6DSV16X_GY_BATCHED_AT_240Hz] = UINT32_C(1000000000) / 240, - [LSM6DSV16X_GY_BATCHED_AT_480Hz] = UINT32_C(1000000000) / 480, - [LSM6DSV16X_GY_BATCHED_AT_960Hz] = UINT32_C(1000000000) / 960, - [LSM6DSV16X_GY_BATCHED_AT_1920Hz] = UINT32_C(1000000000) / 1920, - [LSM6DSV16X_GY_BATCHED_AT_3840Hz] = UINT32_C(1000000000) / 3840, - [LSM6DSV16X_GY_BATCHED_AT_7680Hz] = UINT32_C(1000000000) / 7680, + [LSM6DSVXXX_DT_GY_BATCHED_AT_1Hz875] = UINT32_C(1000000000000) / 1875, + [LSM6DSVXXX_DT_GY_BATCHED_AT_7Hz5] = UINT32_C(1000000000000) / 7500, + [LSM6DSVXXX_DT_GY_BATCHED_AT_15Hz] = UINT32_C(1000000000) / 15, + [LSM6DSVXXX_DT_GY_BATCHED_AT_30Hz] = UINT32_C(1000000000) / 30, + [LSM6DSVXXX_DT_GY_BATCHED_AT_60Hz] = UINT32_C(1000000000) / 60, + [LSM6DSVXXX_DT_GY_BATCHED_AT_120Hz] = UINT32_C(1000000000) / 120, + [LSM6DSVXXX_DT_GY_BATCHED_AT_240Hz] = UINT32_C(1000000000) / 240, + [LSM6DSVXXX_DT_GY_BATCHED_AT_480Hz] = UINT32_C(1000000000) / 480, + [LSM6DSVXXX_DT_GY_BATCHED_AT_960Hz] = UINT32_C(1000000000) / 960, + [LSM6DSVXXX_DT_GY_BATCHED_AT_1920Hz] = UINT32_C(1000000000) / 1920, + [LSM6DSVXXX_DT_GY_BATCHED_AT_3840Hz] = UINT32_C(1000000000) / 3840, + [LSM6DSVXXX_DT_GY_BATCHED_AT_7680Hz] = UINT32_C(1000000000) / 7680, }; #if defined(CONFIG_LSM6DSV16X_ENABLE_TEMP) static const uint32_t temp_period_ns[] = { - [LSM6DSV16X_TEMP_BATCHED_AT_1Hz875] = UINT32_C(1000000000000) / 1875, - [LSM6DSV16X_TEMP_BATCHED_AT_15Hz] = UINT32_C(1000000000) / 15, - [LSM6DSV16X_TEMP_BATCHED_AT_60Hz] = UINT32_C(1000000000) / 60, + [LSM6DSVXXX_DT_TEMP_BATCHED_AT_1Hz875] = UINT32_C(1000000000000) / 1875, + [LSM6DSVXXX_DT_TEMP_BATCHED_AT_15Hz] = UINT32_C(1000000000) / 15, + [LSM6DSVXXX_DT_TEMP_BATCHED_AT_60Hz] = UINT32_C(1000000000) / 60, }; #endif static const uint32_t sflp_period_ns[] = { - [LSM6DSV16X_DT_SFLP_ODR_AT_15Hz] = UINT32_C(1000000000) / 15, - [LSM6DSV16X_DT_SFLP_ODR_AT_30Hz] = UINT32_C(1000000000) / 30, - [LSM6DSV16X_DT_SFLP_ODR_AT_60Hz] = UINT32_C(1000000000) / 60, - [LSM6DSV16X_DT_SFLP_ODR_AT_120Hz] = UINT32_C(1000000000) / 120, - [LSM6DSV16X_DT_SFLP_ODR_AT_240Hz] = UINT32_C(1000000000) / 240, - [LSM6DSV16X_DT_SFLP_ODR_AT_480Hz] = UINT32_C(1000000000) / 480, + [LSM6DSVXXX_DT_SFLP_ODR_AT_15Hz] = UINT32_C(1000000000) / 15, + [LSM6DSVXXX_DT_SFLP_ODR_AT_30Hz] = UINT32_C(1000000000) / 30, + [LSM6DSVXXX_DT_SFLP_ODR_AT_60Hz] = UINT32_C(1000000000) / 60, + [LSM6DSVXXX_DT_SFLP_ODR_AT_120Hz] = UINT32_C(1000000000) / 120, + [LSM6DSVXXX_DT_SFLP_ODR_AT_240Hz] = UINT32_C(1000000000) / 240, + [LSM6DSVXXX_DT_SFLP_ODR_AT_480Hz] = UINT32_C(1000000000) / 480, }; #endif /* CONFIG_LSM6DSV16X_STREAM */ diff --git a/drivers/sensor/st/lsm6dsv16x/lsm6dsv16x_rtio_stream.c b/drivers/sensor/st/lsm6dsv16x/lsm6dsv16x_rtio_stream.c index 013c6a60675f..7013baec684b 100644 --- a/drivers/sensor/st/lsm6dsv16x/lsm6dsv16x_rtio_stream.c +++ b/drivers/sensor/st/lsm6dsv16x/lsm6dsv16x_rtio_stream.c @@ -82,9 +82,9 @@ static void lsm6dsv16x_config_fifo(const struct device *dev, struct trigger_conf stmdev_ctx_t *ctx = (stmdev_ctx_t *)&config->ctx; uint8_t fifo_wtm = 0; lsm6dsv16x_pin_int_route_t pin_int = { 0 }; - lsm6dsv16x_fifo_xl_batch_t xl_batch = LSM6DSV16X_DT_XL_NOT_BATCHED; - lsm6dsv16x_fifo_gy_batch_t gy_batch = LSM6DSV16X_DT_GY_NOT_BATCHED; - lsm6dsv16x_fifo_temp_batch_t temp_batch = LSM6DSV16X_DT_TEMP_NOT_BATCHED; + lsm6dsv16x_fifo_xl_batch_t xl_batch = LSM6DSVXXX_DT_XL_NOT_BATCHED; + lsm6dsv16x_fifo_gy_batch_t gy_batch = LSM6DSVXXX_DT_GY_NOT_BATCHED; + lsm6dsv16x_fifo_temp_batch_t temp_batch = LSM6DSVXXX_DT_TEMP_NOT_BATCHED; lsm6dsv16x_fifo_mode_t fifo_mode = LSM6DSV16X_BYPASS_MODE; lsm6dsv16x_sflp_data_rate_t sflp_odr = LSM6DSV16X_SFLP_120Hz; lsm6dsv16x_fifo_sflp_raw_t sflp_fifo = { 0 }; @@ -107,15 +107,15 @@ static void lsm6dsv16x_config_fifo(const struct device *dev, struct trigger_conf fifo_mode = LSM6DSV16X_STREAM_MODE; fifo_wtm = config->fifo_wtm; - if (config->sflp_fifo_en & LSM6DSV16X_DT_SFLP_FIFO_GAME_ROTATION) { + if (config->sflp_fifo_en & LSM6DSVXXX_DT_SFLP_FIFO_GAME_ROTATION) { sflp_fifo.game_rotation = 1; } - if (config->sflp_fifo_en & LSM6DSV16X_DT_SFLP_FIFO_GRAVITY) { + if (config->sflp_fifo_en & LSM6DSVXXX_DT_SFLP_FIFO_GRAVITY) { sflp_fifo.gravity = 1; } - if (config->sflp_fifo_en & LSM6DSV16X_DT_SFLP_FIFO_GBIAS) { + if (config->sflp_fifo_en & LSM6DSVXXX_DT_SFLP_FIFO_GBIAS) { sflp_fifo.gbias = 1; } @@ -151,34 +151,34 @@ static void lsm6dsv16x_config_fifo(const struct device *dev, struct trigger_conf * make the SFLP gbias setting effective. Then restore it to saved values. */ switch (sflp_odr) { - case LSM6DSV16X_DT_SFLP_ODR_AT_480Hz: - lsm6dsv16x_accel_set_odr_raw(dev, LSM6DSV16X_DT_ODR_AT_480Hz); - lsm6dsv16x_gyro_set_odr_raw(dev, LSM6DSV16X_DT_ODR_AT_480Hz); + case LSM6DSVXXX_DT_SFLP_ODR_AT_480Hz: + lsm6dsv16x_accel_set_odr_raw(dev, LSM6DSVXXX_DT_ODR_AT_480Hz); + lsm6dsv16x_gyro_set_odr_raw(dev, LSM6DSVXXX_DT_ODR_AT_480Hz); break; - case LSM6DSV16X_DT_SFLP_ODR_AT_240Hz: - lsm6dsv16x_accel_set_odr_raw(dev, LSM6DSV16X_DT_ODR_AT_240Hz); - lsm6dsv16x_gyro_set_odr_raw(dev, LSM6DSV16X_DT_ODR_AT_240Hz); + case LSM6DSVXXX_DT_SFLP_ODR_AT_240Hz: + lsm6dsv16x_accel_set_odr_raw(dev, LSM6DSVXXX_DT_ODR_AT_240Hz); + lsm6dsv16x_gyro_set_odr_raw(dev, LSM6DSVXXX_DT_ODR_AT_240Hz); break; - case LSM6DSV16X_DT_SFLP_ODR_AT_120Hz: - lsm6dsv16x_accel_set_odr_raw(dev, LSM6DSV16X_DT_ODR_AT_120Hz); - lsm6dsv16x_gyro_set_odr_raw(dev, LSM6DSV16X_DT_ODR_AT_120Hz); + case LSM6DSVXXX_DT_SFLP_ODR_AT_120Hz: + lsm6dsv16x_accel_set_odr_raw(dev, LSM6DSVXXX_DT_ODR_AT_120Hz); + lsm6dsv16x_gyro_set_odr_raw(dev, LSM6DSVXXX_DT_ODR_AT_120Hz); break; - case LSM6DSV16X_DT_SFLP_ODR_AT_60Hz: - lsm6dsv16x_accel_set_odr_raw(dev, LSM6DSV16X_DT_ODR_AT_60Hz); - lsm6dsv16x_gyro_set_odr_raw(dev, LSM6DSV16X_DT_ODR_AT_60Hz); + case LSM6DSVXXX_DT_SFLP_ODR_AT_60Hz: + lsm6dsv16x_accel_set_odr_raw(dev, LSM6DSVXXX_DT_ODR_AT_60Hz); + lsm6dsv16x_gyro_set_odr_raw(dev, LSM6DSVXXX_DT_ODR_AT_60Hz); break; - case LSM6DSV16X_DT_SFLP_ODR_AT_30Hz: - lsm6dsv16x_accel_set_odr_raw(dev, LSM6DSV16X_DT_ODR_AT_30Hz); - lsm6dsv16x_gyro_set_odr_raw(dev, LSM6DSV16X_DT_ODR_AT_30Hz); + case LSM6DSVXXX_DT_SFLP_ODR_AT_30Hz: + lsm6dsv16x_accel_set_odr_raw(dev, LSM6DSVXXX_DT_ODR_AT_30Hz); + lsm6dsv16x_gyro_set_odr_raw(dev, LSM6DSVXXX_DT_ODR_AT_30Hz); break; - case LSM6DSV16X_DT_SFLP_ODR_AT_15Hz: - lsm6dsv16x_accel_set_odr_raw(dev, LSM6DSV16X_DT_ODR_AT_15Hz); - lsm6dsv16x_gyro_set_odr_raw(dev, LSM6DSV16X_DT_ODR_AT_15Hz); + case LSM6DSVXXX_DT_SFLP_ODR_AT_15Hz: + lsm6dsv16x_accel_set_odr_raw(dev, LSM6DSVXXX_DT_ODR_AT_15Hz); + lsm6dsv16x_gyro_set_odr_raw(dev, LSM6DSVXXX_DT_ODR_AT_15Hz); break; } diff --git a/dts/bindings/sensor/st,lsm6dsv16x-common.yaml b/dts/bindings/sensor/st,lsm6dsv16x-common.yaml index b382aa101a05..55d84bf7973d 100644 --- a/dts/bindings/sensor/st,lsm6dsv16x-common.yaml +++ b/dts/bindings/sensor/st,lsm6dsv16x-common.yaml @@ -1,6 +1,23 @@ # Copyright (c) 2023 STMicroelectronics # SPDX-License-Identifier: Apache-2.0 +description: | + When setting the accel-range, accel-odr, gyro-range, gyro-odr properties in + a .dts or .dtsi file you may include lsm6dsv16x.h and use the macros + defined there. + + Example: + #include + + lsm6dsv16x: lsm6dsv16x@0 { + ... + + accel-range = ; + accel-odr = ; + gyro-range = ; + gyro-odr = ; + }; + include: st,lsm6dsvxxx-common.yaml properties: @@ -16,3 +33,18 @@ properties: - 16 # LSM6DSV16X_DT_FS_16G (0.488 mg/LSB) enum: [2, 4, 8, 16] + + gyro-range: + type: int + default: 0 + description: | + Range in dps. Default is power-up configuration. + + - 0x0 # LSM6DSV16X_DT_FS_125DPS (4.375 mdps/LSB) + - 0x1 # LSM6DSV16X_DT_FS_250DPS (8.75 mdps/LSB) + - 0x2 # LSM6DSV16X_DT_FS_500DPS (17.50 mdps/LSB) + - 0x3 # LSM6DSV16X_DT_FS_1000DPS (35 mdps/LSB) + - 0x4 # LSM6DSV16X_DT_FS_2000DPS (70 mdps/LSB) + - 0xc # LSM6DSV16X_DT_FS_4000DPS (140 mdps/LSB) + + enum: [0x0, 0x1, 0x2, 0x3, 0x4, 0xc] diff --git a/dts/bindings/sensor/st,lsm6dsv32x-common.yaml b/dts/bindings/sensor/st,lsm6dsv32x-common.yaml index cad3f67e69c5..2e0b598eca60 100644 --- a/dts/bindings/sensor/st,lsm6dsv32x-common.yaml +++ b/dts/bindings/sensor/st,lsm6dsv32x-common.yaml @@ -1,6 +1,23 @@ # Copyright (c) 2025 Meta Platforms # SPDX-License-Identifier: Apache-2.0 +description: | + When setting the accel-range, accel-odr, gyro-range, gyro-odr properties in + a .dts or .dtsi file you may include lsm6dsv32x.h and use the macros + defined there. + + Example: + #include + + lsm6dsv32x: lsm6dsv32x@0 { + ... + + accel-range = ; + accel-odr = ; + gyro-range = ; + gyro-odr = ; + }; + include: st,lsm6dsvxxx-common.yaml properties: @@ -16,3 +33,18 @@ properties: - 32 # LSM6DSV32X_DT_FS_32G (0.976 mg/LSB) enum: [4, 8, 16, 32] + + gyro-range: + type: int + default: 0 + description: | + Range in dps. Default is power-up configuration. + + - 0x0 # LSM6DSV32X_DT_FS_125DPS (4.375 mdps/LSB) + - 0x1 # LSM6DSV32X_DT_FS_250DPS (8.75 mdps/LSB) + - 0x2 # LSM6DSV32X_DT_FS_500DPS (17.50 mdps/LSB) + - 0x3 # LSM6DSV32X_DT_FS_1000DPS (35 mdps/LSB) + - 0x4 # LSM6DSV32X_DT_FS_2000DPS (70 mdps/LSB) + - 0xc # LSM6DSV32X_DT_FS_4000DPS (140 mdps/LSB) + + enum: [0x0, 0x1, 0x2, 0x3, 0x4, 0xc] diff --git a/dts/bindings/sensor/st,lsm6dsvxxx-common.yaml b/dts/bindings/sensor/st,lsm6dsvxxx-common.yaml index 44b897343f74..133860e1a90f 100644 --- a/dts/bindings/sensor/st,lsm6dsvxxx-common.yaml +++ b/dts/bindings/sensor/st,lsm6dsvxxx-common.yaml @@ -1,23 +1,6 @@ # Copyright (c) 2023 STMicroelectronics # SPDX-License-Identifier: Apache-2.0 -description: | - When setting the accel-range, accel-odr, gyro-range, gyro-odr properties in - a .dts or .dtsi file you may include lsm6dsv16x.h and use the macros - defined there. - - Example: - #include - - lsm6dsv16x: lsm6dsv16x@0 { - ... - - accel-range = ; - accel-odr = ; - gyro-range = ; - gyro-odr = ; - }; - include: sensor-device.yaml properties: @@ -63,59 +46,44 @@ properties: High Performance (device default) Default is power-up configuration. - - 0x00 # LSM6DSV16X_DT_ODR_OFF - - 0x01 # LSM6DSV16X_DT_ODR_AT_1Hz875 - - 0x02 # LSM6DSV16X_DT_ODR_AT_7Hz5 - - 0x03 # LSM6DSV16X_DT_ODR_AT_15Hz - - 0x04 # LSM6DSV16X_DT_ODR_AT_30Hz - - 0x05 # LSM6DSV16X_DT_ODR_AT_60Hz - - 0x06 # LSM6DSV16X_DT_ODR_AT_120Hz - - 0x07 # LSM6DSV16X_DT_ODR_AT_240Hz - - 0x08 # LSM6DSV16X_DT_ODR_AT_480Hz - - 0x09 # LSM6DSV16X_DT_ODR_AT_960Hz - - 0x0a # LSM6DSV16X_DT_ODR_AT_1920Hz - - 0x0b # LSM6DSV16X_DT_ODR_AT_3840Hz - - 0x0c # LSM6DSV16X_DT_ODR_AT_7680Hz - - 0x13 # LSM6DSV16X_DT_ODR_HA01_AT_15Hz625 - - 0x14 # LSM6DSV16X_DT_ODR_HA01_AT_31Hz25 - - 0x15 # LSM6DSV16X_DT_ODR_HA01_AT_62Hz5 - - 0x16 # LSM6DSV16X_DT_ODR_HA01_AT_125Hz - - 0x17 # LSM6DSV16X_DT_ODR_HA01_AT_250Hz - - 0x18 # LSM6DSV16X_DT_ODR_HA01_AT_500Hz - - 0x19 # LSM6DSV16X_DT_ODR_HA01_AT_1000Hz - - 0x1a # LSM6DSV16X_DT_ODR_HA01_AT_2000Hz - - 0x1b # LSM6DSV16X_DT_ODR_HA01_AT_4000Hz - - 0x1c # LSM6DSV16X_DT_ODR_HA01_AT_8000Hz - - 0x23 # LSM6DSV16X_DT_ODR_HA02_AT_12Hz5 - - 0x24 # LSM6DSV16X_DT_ODR_HA02_AT_25Hz - - 0x25 # LSM6DSV16X_DT_ODR_HA02_AT_50Hz - - 0x26 # LSM6DSV16X_DT_ODR_HA02_AT_100Hz - - 0x27 # LSM6DSV16X_DT_ODR_HA02_AT_200Hz - - 0x28 # LSM6DSV16X_DT_ODR_HA02_AT_400Hz - - 0x29 # LSM6DSV16X_DT_ODR_HA02_AT_800Hz - - 0x2a # LSM6DSV16X_DT_ODR_HA02_AT_1600Hz - - 0x2b # LSM6DSV16X_DT_ODR_HA02_AT_3200Hz - - 0x2c # LSM6DSV16X_DT_ODR_HA02_AT_6400Hz + - 0x00 # LSM6DSVXXX_DT_ODR_OFF + - 0x01 # LSM6DSVXXX_DT_ODR_AT_1Hz875 + - 0x02 # LSM6DSVXXX_DT_ODR_AT_7Hz5 + - 0x03 # LSM6DSVXXX_DT_ODR_AT_15Hz + - 0x04 # LSM6DSVXXX_DT_ODR_AT_30Hz + - 0x05 # LSM6DSVXXX_DT_ODR_AT_60Hz + - 0x06 # LSM6DSVXXX_DT_ODR_AT_120Hz + - 0x07 # LSM6DSVXXX_DT_ODR_AT_240Hz + - 0x08 # LSM6DSVXXX_DT_ODR_AT_480Hz + - 0x09 # LSM6DSVXXX_DT_ODR_AT_960Hz + - 0x0a # LSM6DSVXXX_DT_ODR_AT_1920Hz + - 0x0b # LSM6DSVXXX_DT_ODR_AT_3840Hz + - 0x0c # LSM6DSVXXX_DT_ODR_AT_7680Hz + - 0x13 # LSM6DSVXXX_DT_ODR_HA01_AT_15Hz625 + - 0x14 # LSM6DSVXXX_DT_ODR_HA01_AT_31Hz25 + - 0x15 # LSM6DSVXXX_DT_ODR_HA01_AT_62Hz5 + - 0x16 # LSM6DSVXXX_DT_ODR_HA01_AT_125Hz + - 0x17 # LSM6DSVXXX_DT_ODR_HA01_AT_250Hz + - 0x18 # LSM6DSVXXX_DT_ODR_HA01_AT_500Hz + - 0x19 # LSM6DSVXXX_DT_ODR_HA01_AT_1000Hz + - 0x1a # LSM6DSVXXX_DT_ODR_HA01_AT_2000Hz + - 0x1b # LSM6DSVXXX_DT_ODR_HA01_AT_4000Hz + - 0x1c # LSM6DSVXXX_DT_ODR_HA01_AT_8000Hz + - 0x23 # LSM6DSVXXX_DT_ODR_HA02_AT_12Hz5 + - 0x24 # LSM6DSVXXX_DT_ODR_HA02_AT_25Hz + - 0x25 # LSM6DSVXXX_DT_ODR_HA02_AT_50Hz + - 0x26 # LSM6DSVXXX_DT_ODR_HA02_AT_100Hz + - 0x27 # LSM6DSVXXX_DT_ODR_HA02_AT_200Hz + - 0x28 # LSM6DSVXXX_DT_ODR_HA02_AT_400Hz + - 0x29 # LSM6DSVXXX_DT_ODR_HA02_AT_800Hz + - 0x2a # LSM6DSVXXX_DT_ODR_HA02_AT_1600Hz + - 0x2b # LSM6DSVXXX_DT_ODR_HA02_AT_3200Hz + - 0x2c # LSM6DSVXXX_DT_ODR_HA02_AT_6400Hz enum: [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c] - gyro-range: - type: int - default: 0 - description: | - Range in dps. Default is power-up configuration. - - - 0x0 # LSM6DSV16X_DT_FS_125DPS (4.375 mdps/LSB) - - 0x1 # LSM6DSV16X_DT_FS_250DPS (8.75 mdps/LSB) - - 0x2 # LSM6DSV16X_DT_FS_500DPS (17.50 mdps/LSB) - - 0x3 # LSM6DSV16X_DT_FS_1000DPS (35 mdps/LSB) - - 0x4 # LSM6DSV16X_DT_FS_2000DPS (70 mdps/LSB) - - 0xc # LSM6DSV16X_DT_FS_4000DPS (140 mdps/LSB) - - enum: [0x0, 0x1, 0x2, 0x3, 0x4, 0xc] - gyro-odr: type: int default: 0x0 @@ -128,39 +96,39 @@ properties: SENSOR_ATTR_SAMPLING_FREQUENCY. Default is power-up configuration. - - 0x00 # LSM6DSV16X_DT_ODR_OFF - - 0x01 # LSM6DSV16X_DT_ODR_AT_1Hz875 - - 0x02 # LSM6DSV16X_DT_ODR_AT_7Hz5 - - 0x03 # LSM6DSV16X_DT_ODR_AT_15Hz - - 0x04 # LSM6DSV16X_DT_ODR_AT_30Hz - - 0x05 # LSM6DSV16X_DT_ODR_AT_60Hz - - 0x06 # LSM6DSV16X_DT_ODR_AT_120Hz - - 0x07 # LSM6DSV16X_DT_ODR_AT_240Hz - - 0x08 # LSM6DSV16X_DT_ODR_AT_480Hz - - 0x09 # LSM6DSV16X_DT_ODR_AT_960Hz - - 0x0a # LSM6DSV16X_DT_ODR_AT_1920Hz - - 0x0b # LSM6DSV16X_DT_ODR_AT_3840Hz - - 0x0c # LSM6DSV16X_DT_ODR_AT_7680Hz - - 0x13 # LSM6DSV16X_DT_ODR_HA01_AT_15Hz625 - - 0x14 # LSM6DSV16X_DT_ODR_HA01_AT_31Hz25 - - 0x15 # LSM6DSV16X_DT_ODR_HA01_AT_62Hz5 - - 0x16 # LSM6DSV16X_DT_ODR_HA01_AT_125Hz - - 0x17 # LSM6DSV16X_DT_ODR_HA01_AT_250Hz - - 0x18 # LSM6DSV16X_DT_ODR_HA01_AT_500Hz - - 0x19 # LSM6DSV16X_DT_ODR_HA01_AT_1000Hz - - 0x1a # LSM6DSV16X_DT_ODR_HA01_AT_2000Hz - - 0x1b # LSM6DSV16X_DT_ODR_HA01_AT_4000Hz - - 0x1c # LSM6DSV16X_DT_ODR_HA01_AT_8000Hz - - 0x23 # LSM6DSV16X_DT_ODR_HA02_AT_12Hz5 - - 0x24 # LSM6DSV16X_DT_ODR_HA02_AT_25Hz - - 0x25 # LSM6DSV16X_DT_ODR_HA02_AT_50Hz - - 0x26 # LSM6DSV16X_DT_ODR_HA02_AT_100Hz - - 0x27 # LSM6DSV16X_DT_ODR_HA02_AT_200Hz - - 0x28 # LSM6DSV16X_DT_ODR_HA02_AT_400Hz - - 0x29 # LSM6DSV16X_DT_ODR_HA02_AT_800Hz - - 0x2a # LSM6DSV16X_DT_ODR_HA02_AT_1600Hz - - 0x2b # LSM6DSV16X_DT_ODR_HA02_AT_3200Hz - - 0x2c # LSM6DSV16X_DT_ODR_HA02_AT_6400Hz + - 0x00 # LSM6DSVXXX_DT_ODR_OFF + - 0x01 # LSM6DSVXXX_DT_ODR_AT_1Hz875 + - 0x02 # LSM6DSVXXX_DT_ODR_AT_7Hz5 + - 0x03 # LSM6DSVXXX_DT_ODR_AT_15Hz + - 0x04 # LSM6DSVXXX_DT_ODR_AT_30Hz + - 0x05 # LSM6DSVXXX_DT_ODR_AT_60Hz + - 0x06 # LSM6DSVXXX_DT_ODR_AT_120Hz + - 0x07 # LSM6DSVXXX_DT_ODR_AT_240Hz + - 0x08 # LSM6DSVXXX_DT_ODR_AT_480Hz + - 0x09 # LSM6DSVXXX_DT_ODR_AT_960Hz + - 0x0a # LSM6DSVXXX_DT_ODR_AT_1920Hz + - 0x0b # LSM6DSVXXX_DT_ODR_AT_3840Hz + - 0x0c # LSM6DSVXXX_DT_ODR_AT_7680Hz + - 0x13 # LSM6DSVXXX_DT_ODR_HA01_AT_15Hz625 + - 0x14 # LSM6DSVXXX_DT_ODR_HA01_AT_31Hz25 + - 0x15 # LSM6DSVXXX_DT_ODR_HA01_AT_62Hz5 + - 0x16 # LSM6DSVXXX_DT_ODR_HA01_AT_125Hz + - 0x17 # LSM6DSVXXX_DT_ODR_HA01_AT_250Hz + - 0x18 # LSM6DSVXXX_DT_ODR_HA01_AT_500Hz + - 0x19 # LSM6DSVXXX_DT_ODR_HA01_AT_1000Hz + - 0x1a # LSM6DSVXXX_DT_ODR_HA01_AT_2000Hz + - 0x1b # LSM6DSVXXX_DT_ODR_HA01_AT_4000Hz + - 0x1c # LSM6DSVXXX_DT_ODR_HA01_AT_8000Hz + - 0x23 # LSM6DSVXXX_DT_ODR_HA02_AT_12Hz5 + - 0x24 # LSM6DSVXXX_DT_ODR_HA02_AT_25Hz + - 0x25 # LSM6DSVXXX_DT_ODR_HA02_AT_50Hz + - 0x26 # LSM6DSVXXX_DT_ODR_HA02_AT_100Hz + - 0x27 # LSM6DSVXXX_DT_ODR_HA02_AT_200Hz + - 0x28 # LSM6DSVXXX_DT_ODR_HA02_AT_400Hz + - 0x29 # LSM6DSVXXX_DT_ODR_HA02_AT_800Hz + - 0x2a # LSM6DSVXXX_DT_ODR_HA02_AT_1600Hz + - 0x2b # LSM6DSVXXX_DT_ODR_HA02_AT_3200Hz + - 0x2c # LSM6DSVXXX_DT_ODR_HA02_AT_6400Hz enum: [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, @@ -189,19 +157,19 @@ properties: module. Default is power-up configuration. - - 0x0 # LSM6DSV16X_DT_XL_NOT_BATCHED - - 0x1 # LSM6DSV16X_DT_XL_BATCHED_AT_1Hz875 - - 0x2 # LSM6DSV16X_DT_XL_BATCHED_AT_7Hz5 - - 0x3 # LSM6DSV16X_DT_XL_BATCHED_AT_15Hz - - 0x4 # LSM6DSV16X_DT_XL_BATCHED_AT_30Hz - - 0x5 # LSM6DSV16X_DT_XL_BATCHED_AT_60Hz - - 0x6 # LSM6DSV16X_DT_XL_BATCHED_AT_120Hz - - 0x7 # LSM6DSV16X_DT_XL_BATCHED_AT_240Hz - - 0x8 # LSM6DSV16X_DT_XL_BATCHED_AT_480Hz - - 0x9 # LSM6DSV16X_DT_XL_BATCHED_AT_960Hz - - 0xa # LSM6DSV16X_DT_XL_BATCHED_AT_1920Hz - - 0xb # LSM6DSV16X_DT_XL_BATCHED_AT_3840Hz - - 0xc # LSM6DSV16X_DT_XL_BATCHED_AT_7680Hz + - 0x0 # LSM6DSVXXX_DT_XL_NOT_BATCHED + - 0x1 # LSM6DSVXXX_DT_XL_BATCHED_AT_1Hz875 + - 0x2 # LSM6DSVXXX_DT_XL_BATCHED_AT_7Hz5 + - 0x3 # LSM6DSVXXX_DT_XL_BATCHED_AT_15Hz + - 0x4 # LSM6DSVXXX_DT_XL_BATCHED_AT_30Hz + - 0x5 # LSM6DSVXXX_DT_XL_BATCHED_AT_60Hz + - 0x6 # LSM6DSVXXX_DT_XL_BATCHED_AT_120Hz + - 0x7 # LSM6DSVXXX_DT_XL_BATCHED_AT_240Hz + - 0x8 # LSM6DSVXXX_DT_XL_BATCHED_AT_480Hz + - 0x9 # LSM6DSVXXX_DT_XL_BATCHED_AT_960Hz + - 0xa # LSM6DSVXXX_DT_XL_BATCHED_AT_1920Hz + - 0xb # LSM6DSVXXX_DT_XL_BATCHED_AT_3840Hz + - 0xc # LSM6DSVXXX_DT_XL_BATCHED_AT_7680Hz enum: [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c] @@ -214,19 +182,19 @@ properties: module. Default is power-up configuration. - - 0x0 # LSM6DSV16X_DT_GY_NOT_BATCHED - - 0x1 # LSM6DSV16X_DT_GY_BATCHED_AT_1Hz875 - - 0x2 # LSM6DSV16X_DT_GY_BATCHED_AT_7Hz5 - - 0x3 # LSM6DSV16X_DT_GY_BATCHED_AT_15Hz - - 0x4 # LSM6DSV16X_DT_GY_BATCHED_AT_30Hz - - 0x5 # LSM6DSV16X_DT_GY_BATCHED_AT_60Hz - - 0x6 # LSM6DSV16X_DT_GY_BATCHED_AT_120Hz - - 0x7 # LSM6DSV16X_DT_GY_BATCHED_AT_240Hz - - 0x8 # LSM6DSV16X_DT_GY_BATCHED_AT_480Hz - - 0x9 # LSM6DSV16X_DT_GY_BATCHED_AT_960Hz - - 0xa # LSM6DSV16X_DT_GY_BATCHED_AT_1920Hz - - 0xb # LSM6DSV16X_DT_GY_BATCHED_AT_3840Hz - - 0xc # LSM6DSV16X_DT_GY_BATCHED_AT_7680Hz + - 0x0 # LSM6DSVXXX_DT_GY_NOT_BATCHED + - 0x1 # LSM6DSVXXX_DT_GY_BATCHED_AT_1Hz875 + - 0x2 # LSM6DSVXXX_DT_GY_BATCHED_AT_7Hz5 + - 0x3 # LSM6DSVXXX_DT_GY_BATCHED_AT_15Hz + - 0x4 # LSM6DSVXXX_DT_GY_BATCHED_AT_30Hz + - 0x5 # LSM6DSVXXX_DT_GY_BATCHED_AT_60Hz + - 0x6 # LSM6DSVXXX_DT_GY_BATCHED_AT_120Hz + - 0x7 # LSM6DSVXXX_DT_GY_BATCHED_AT_240Hz + - 0x8 # LSM6DSVXXX_DT_GY_BATCHED_AT_480Hz + - 0x9 # LSM6DSVXXX_DT_GY_BATCHED_AT_960Hz + - 0xa # LSM6DSVXXX_DT_GY_BATCHED_AT_1920Hz + - 0xb # LSM6DSVXXX_DT_GY_BATCHED_AT_3840Hz + - 0xc # LSM6DSVXXX_DT_GY_BATCHED_AT_7680Hz enum: [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c] @@ -239,10 +207,10 @@ properties: module. Default is power-up configuration. - - 0x0 # LSM6DSV16X_DT_TEMP_NOT_BATCHED - - 0x1 # LSM6DSV16X_DT_TEMP_BATCHED_AT_1Hz875 - - 0x2 # LSM6DSV16X_DT_TEMP_BATCHED_AT_15Hz - - 0x3 # LSM6DSV16X_DT_TEMP_BATCHED_AT_60Hz + - 0x0 # LSM6DSVXXX_DT_TEMP_NOT_BATCHED + - 0x1 # LSM6DSVXXX_DT_TEMP_BATCHED_AT_1Hz875 + - 0x2 # LSM6DSVXXX_DT_TEMP_BATCHED_AT_15Hz + - 0x3 # LSM6DSVXXX_DT_TEMP_BATCHED_AT_60Hz enum: [0x00, 0x01, 0x02, 0x03] @@ -255,12 +223,12 @@ properties: module. Default is power-up configuration. - - 0x0 # LSM6DSV16X_DT_SFLP_ODR_AT_15Hz - - 0x1 # LSM6DSV16X_DT_SFLP_ODR_AT_30Hz - - 0x2 # LSM6DSV16X_DT_SFLP_ODR_AT_60Hz - - 0x3 # LSM6DSV16X_DT_SFLP_ODR_AT_120Hz - - 0x4 # LSM6DSV16X_DT_SFLP_ODR_AT_240Hz - - 0x5 # LSM6DSV16X_DT_SFLP_ODR_AT_480Hz + - 0x0 # LSM6DSVXXX_DT_SFLP_ODR_AT_15Hz + - 0x1 # LSM6DSVXXX_DT_SFLP_ODR_AT_30Hz + - 0x2 # LSM6DSVXXX_DT_SFLP_ODR_AT_60Hz + - 0x3 # LSM6DSVXXX_DT_SFLP_ODR_AT_120Hz + - 0x4 # LSM6DSVXXX_DT_SFLP_ODR_AT_240Hz + - 0x5 # LSM6DSVXXX_DT_SFLP_ODR_AT_480Hz enum: [0x00, 0x01, 0x02, 0x03, 0x04, 0x05] @@ -273,13 +241,13 @@ properties: module. Default is power-up configuration. - - 0x0 # LSM6DSV16X_DT_SFLP_FIFO_OFF - - 0x1 # LSM6DSV16X_DT_SFLP_FIFO_GAME_ROTATION - - 0x2 # LSM6DSV16X_DT_SFLP_FIFO_GRAVITY - - 0x3 # LSM6DSV16X_DT_SFLP_FIFO_GAME_ROTATION_GRAVITY - - 0x4 # LSM6DSV16X_DT_SFLP_FIFO_GBIAS - - 0x5 # LSM6DSV16X_DT_SFLP_FIFO_GAME_ROTATION_GBIAS - - 0x6 # LSM6DSV16X_DT_SFLP_FIFO_GRAVITY_GBIAS - - 0x7 # LSM6DSV16X_DT_SFLP_FIFO_GAME_ROTATION_GRAVITY_GBIAS + - 0x0 # LSM6DSVXXX_DT_SFLP_FIFO_OFF + - 0x1 # LSM6DSVXXX_DT_SFLP_FIFO_GAME_ROTATION + - 0x2 # LSM6DSVXXX_DT_SFLP_FIFO_GRAVITY + - 0x3 # LSM6DSVXXX_DT_SFLP_FIFO_GAME_ROTATION_GRAVITY + - 0x4 # LSM6DSVXXX_DT_SFLP_FIFO_GBIAS + - 0x5 # LSM6DSVXXX_DT_SFLP_FIFO_GAME_ROTATION_GBIAS + - 0x6 # LSM6DSVXXX_DT_SFLP_FIFO_GRAVITY_GBIAS + - 0x7 # LSM6DSVXXX_DT_SFLP_FIFO_GAME_ROTATION_GRAVITY_GBIAS enum: [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07] diff --git a/include/zephyr/dt-bindings/sensor/lsm6dsv16x.h b/include/zephyr/dt-bindings/sensor/lsm6dsv16x.h index 9f3b5afda2dc..a7cccf03a902 100644 --- a/include/zephyr/dt-bindings/sensor/lsm6dsv16x.h +++ b/include/zephyr/dt-bindings/sensor/lsm6dsv16x.h @@ -6,112 +6,20 @@ #ifndef ZEPHYR_INCLUDE_DT_BINDINGS_ST_LSM6DSV16X_H_ #define ZEPHYR_INCLUDE_DT_BINDINGS_ST_LSM6DSV16X_H_ +#include "lsm6dsvxxx.h" + /* Accel range */ -#define LSM6DSV16X_DT_FS_2G 2 -#define LSM6DSV16X_DT_FS_4G 4 -#define LSM6DSV16X_DT_FS_8G 8 -#define LSM6DSV16X_DT_FS_16G 16 -#define LSM6DSV32X_DT_FS_4G 4 -#define LSM6DSV32X_DT_FS_8G 8 -#define LSM6DSV32X_DT_FS_16G 16 -#define LSM6DSV32X_DT_FS_32G 32 +#define LSM6DSV16X_DT_FS_2G 2 +#define LSM6DSV16X_DT_FS_4G 4 +#define LSM6DSV16X_DT_FS_8G 8 +#define LSM6DSV16X_DT_FS_16G 16 /* Gyro range */ -#define LSM6DSV16X_DT_FS_125DPS 0x0 -#define LSM6DSV16X_DT_FS_250DPS 0x1 -#define LSM6DSV16X_DT_FS_500DPS 0x2 -#define LSM6DSV16X_DT_FS_1000DPS 0x3 -#define LSM6DSV16X_DT_FS_2000DPS 0x4 -#define LSM6DSV16X_DT_FS_4000DPS 0xc - -/* Accel and Gyro Data rates */ -#define LSM6DSV16X_DT_ODR_OFF 0x0 -#define LSM6DSV16X_DT_ODR_AT_1Hz875 0x1 -#define LSM6DSV16X_DT_ODR_AT_7Hz5 0x2 -#define LSM6DSV16X_DT_ODR_AT_15Hz 0x3 -#define LSM6DSV16X_DT_ODR_AT_30Hz 0x4 -#define LSM6DSV16X_DT_ODR_AT_60Hz 0x5 -#define LSM6DSV16X_DT_ODR_AT_120Hz 0x6 -#define LSM6DSV16X_DT_ODR_AT_240Hz 0x7 -#define LSM6DSV16X_DT_ODR_AT_480Hz 0x8 -#define LSM6DSV16X_DT_ODR_AT_960Hz 0x9 -#define LSM6DSV16X_DT_ODR_AT_1920Hz 0xA -#define LSM6DSV16X_DT_ODR_AT_3840Hz 0xB -#define LSM6DSV16X_DT_ODR_AT_7680Hz 0xC -#define LSM6DSV16X_DT_ODR_HA01_AT_15Hz625 0x13 -#define LSM6DSV16X_DT_ODR_HA01_AT_31Hz25 0x14 -#define LSM6DSV16X_DT_ODR_HA01_AT_62Hz5 0x15 -#define LSM6DSV16X_DT_ODR_HA01_AT_125Hz 0x16 -#define LSM6DSV16X_DT_ODR_HA01_AT_250Hz 0x17 -#define LSM6DSV16X_DT_ODR_HA01_AT_500Hz 0x18 -#define LSM6DSV16X_DT_ODR_HA01_AT_1000Hz 0x19 -#define LSM6DSV16X_DT_ODR_HA01_AT_2000Hz 0x1A -#define LSM6DSV16X_DT_ODR_HA01_AT_4000Hz 0x1B -#define LSM6DSV16X_DT_ODR_HA01_AT_8000Hz 0x1C -#define LSM6DSV16X_DT_ODR_HA02_AT_12Hz5 0x23 -#define LSM6DSV16X_DT_ODR_HA02_AT_25Hz 0x24 -#define LSM6DSV16X_DT_ODR_HA02_AT_50Hz 0x25 -#define LSM6DSV16X_DT_ODR_HA02_AT_100Hz 0x26 -#define LSM6DSV16X_DT_ODR_HA02_AT_200Hz 0x27 -#define LSM6DSV16X_DT_ODR_HA02_AT_400Hz 0x28 -#define LSM6DSV16X_DT_ODR_HA02_AT_800Hz 0x29 -#define LSM6DSV16X_DT_ODR_HA02_AT_1600Hz 0x2A -#define LSM6DSV16X_DT_ODR_HA02_AT_3200Hz 0x2B -#define LSM6DSV16X_DT_ODR_HA02_AT_6400Hz 0x2C - -/* Accelerometer batching rates */ -#define LSM6DSV16X_DT_XL_NOT_BATCHED 0x0 -#define LSM6DSV16X_DT_XL_BATCHED_AT_1Hz875 0x1 -#define LSM6DSV16X_DT_XL_BATCHED_AT_7Hz5 0x2 -#define LSM6DSV16X_DT_XL_BATCHED_AT_15Hz 0x3 -#define LSM6DSV16X_DT_XL_BATCHED_AT_30Hz 0x4 -#define LSM6DSV16X_DT_XL_BATCHED_AT_60Hz 0x5 -#define LSM6DSV16X_DT_XL_BATCHED_AT_120Hz 0x6 -#define LSM6DSV16X_DT_XL_BATCHED_AT_240Hz 0x7 -#define LSM6DSV16X_DT_XL_BATCHED_AT_480Hz 0x8 -#define LSM6DSV16X_DT_XL_BATCHED_AT_960Hz 0x9 -#define LSM6DSV16X_DT_XL_BATCHED_AT_1920Hz 0xa -#define LSM6DSV16X_DT_XL_BATCHED_AT_3840Hz 0xb -#define LSM6DSV16X_DT_XL_BATCHED_AT_7680Hz 0xc - -/* Gyroscope batching rates */ -#define LSM6DSV16X_DT_GY_NOT_BATCHED 0x0 -#define LSM6DSV16X_DT_GY_BATCHED_AT_1Hz875 0x1 -#define LSM6DSV16X_DT_GY_BATCHED_AT_7Hz5 0x2 -#define LSM6DSV16X_DT_GY_BATCHED_AT_15Hz 0x3 -#define LSM6DSV16X_DT_GY_BATCHED_AT_30Hz 0x4 -#define LSM6DSV16X_DT_GY_BATCHED_AT_60Hz 0x5 -#define LSM6DSV16X_DT_GY_BATCHED_AT_120Hz 0x6 -#define LSM6DSV16X_DT_GY_BATCHED_AT_240Hz 0x7 -#define LSM6DSV16X_DT_GY_BATCHED_AT_480Hz 0x8 -#define LSM6DSV16X_DT_GY_BATCHED_AT_960Hz 0x9 -#define LSM6DSV16X_DT_GY_BATCHED_AT_1920Hz 0xa -#define LSM6DSV16X_DT_GY_BATCHED_AT_3840Hz 0xb -#define LSM6DSV16X_DT_GY_BATCHED_AT_7680Hz 0xc - -/* Temperature sensor batching rates */ -#define LSM6DSV16X_DT_TEMP_NOT_BATCHED 0x0 -#define LSM6DSV16X_DT_TEMP_BATCHED_AT_1Hz875 0x1 -#define LSM6DSV16X_DT_TEMP_BATCHED_AT_15Hz 0x2 -#define LSM6DSV16X_DT_TEMP_BATCHED_AT_60Hz 0x3 - -/* Sensor Fusion Low Power Data rates */ -#define LSM6DSV16X_DT_SFLP_ODR_AT_15Hz 0x0 -#define LSM6DSV16X_DT_SFLP_ODR_AT_30Hz 0x1 -#define LSM6DSV16X_DT_SFLP_ODR_AT_60Hz 0x2 -#define LSM6DSV16X_DT_SFLP_ODR_AT_120Hz 0x3 -#define LSM6DSV16X_DT_SFLP_ODR_AT_240Hz 0x4 -#define LSM6DSV16X_DT_SFLP_ODR_AT_480Hz 0x5 - -/* Sensor Fusion Low Power FIFO enable defs */ -#define LSM6DSV16X_DT_SFLP_FIFO_OFF 0x0 -#define LSM6DSV16X_DT_SFLP_FIFO_GAME_ROTATION 0x1 -#define LSM6DSV16X_DT_SFLP_FIFO_GRAVITY 0x2 -#define LSM6DSV16X_DT_SFLP_FIFO_GAME_ROTATION_GRAVITY 0x3 -#define LSM6DSV16X_DT_SFLP_FIFO_GBIAS 0x4 -#define LSM6DSV16X_DT_SFLP_FIFO_GAME_ROTATION_GBIAS 0x5 -#define LSM6DSV16X_DT_SFLP_FIFO_GRAVITY_GBIAS 0x6 -#define LSM6DSV16X_DT_SFLP_FIFO_GAME_ROTATION_GRAVITY_GBIAS 0x7 - +#define LSM6DSV16X_DT_FS_125DPS 0x0 +#define LSM6DSV16X_DT_FS_250DPS 0x1 +#define LSM6DSV16X_DT_FS_500DPS 0x2 +#define LSM6DSV16X_DT_FS_1000DPS 0x3 +#define LSM6DSV16X_DT_FS_2000DPS 0x4 +#define LSM6DSV16X_DT_FS_4000DPS 0xc #endif /* ZEPHYR_INCLUDE_DT_BINDINGS_ST_LSM6DSV16X_H_ */ diff --git a/include/zephyr/dt-bindings/sensor/lsm6dsv32x.h b/include/zephyr/dt-bindings/sensor/lsm6dsv32x.h new file mode 100644 index 000000000000..c326343b1f70 --- /dev/null +++ b/include/zephyr/dt-bindings/sensor/lsm6dsv32x.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2023 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_ST_LSM6DSV32X_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_ST_LSM6DSV32X_H_ + +#include "lsm6dsvxxx.h" + +/* Accel range */ +#define LSM6DSV32X_DT_FS_4G 4 +#define LSM6DSV32X_DT_FS_8G 8 +#define LSM6DSV32X_DT_FS_16G 16 +#define LSM6DSV32X_DT_FS_32G 32 + +/* Gyro range */ +#define LSM6DSV32X_DT_FS_125DPS 0x0 +#define LSM6DSV32X_DT_FS_250DPS 0x1 +#define LSM6DSV32X_DT_FS_500DPS 0x2 +#define LSM6DSV32X_DT_FS_1000DPS 0x3 +#define LSM6DSV32X_DT_FS_2000DPS 0x4 +#define LSM6DSV32X_DT_FS_4000DPS 0xc + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_ST_LSM6DSV32X_H_ */ diff --git a/include/zephyr/dt-bindings/sensor/lsm6dsvxxx.h b/include/zephyr/dt-bindings/sensor/lsm6dsvxxx.h new file mode 100644 index 000000000000..ac8db9fa612d --- /dev/null +++ b/include/zephyr/dt-bindings/sensor/lsm6dsvxxx.h @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2025 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_ST_LSM6DSVXXX_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_ST_LSM6DSVXXX_H_ + +/* Accel and Gyro Data rates */ +#define LSM6DSVXXX_DT_ODR_OFF 0x0 +#define LSM6DSVXXX_DT_ODR_AT_1Hz875 0x1 +#define LSM6DSVXXX_DT_ODR_AT_7Hz5 0x2 +#define LSM6DSVXXX_DT_ODR_AT_15Hz 0x3 +#define LSM6DSVXXX_DT_ODR_AT_30Hz 0x4 +#define LSM6DSVXXX_DT_ODR_AT_60Hz 0x5 +#define LSM6DSVXXX_DT_ODR_AT_120Hz 0x6 +#define LSM6DSVXXX_DT_ODR_AT_240Hz 0x7 +#define LSM6DSVXXX_DT_ODR_AT_480Hz 0x8 +#define LSM6DSVXXX_DT_ODR_AT_960Hz 0x9 +#define LSM6DSVXXX_DT_ODR_AT_1920Hz 0xA +#define LSM6DSVXXX_DT_ODR_AT_3840Hz 0xB +#define LSM6DSVXXX_DT_ODR_AT_7680Hz 0xC +#define LSM6DSVXXX_DT_ODR_HA01_AT_15Hz625 0x13 +#define LSM6DSVXXX_DT_ODR_HA01_AT_31Hz25 0x14 +#define LSM6DSVXXX_DT_ODR_HA01_AT_62Hz5 0x15 +#define LSM6DSVXXX_DT_ODR_HA01_AT_125Hz 0x16 +#define LSM6DSVXXX_DT_ODR_HA01_AT_250Hz 0x17 +#define LSM6DSVXXX_DT_ODR_HA01_AT_500Hz 0x18 +#define LSM6DSVXXX_DT_ODR_HA01_AT_1000Hz 0x19 +#define LSM6DSVXXX_DT_ODR_HA01_AT_2000Hz 0x1A +#define LSM6DSVXXX_DT_ODR_HA01_AT_4000Hz 0x1B +#define LSM6DSVXXX_DT_ODR_HA01_AT_8000Hz 0x1C +#define LSM6DSVXXX_DT_ODR_HA02_AT_12Hz5 0x23 +#define LSM6DSVXXX_DT_ODR_HA02_AT_25Hz 0x24 +#define LSM6DSVXXX_DT_ODR_HA02_AT_50Hz 0x25 +#define LSM6DSVXXX_DT_ODR_HA02_AT_100Hz 0x26 +#define LSM6DSVXXX_DT_ODR_HA02_AT_200Hz 0x27 +#define LSM6DSVXXX_DT_ODR_HA02_AT_400Hz 0x28 +#define LSM6DSVXXX_DT_ODR_HA02_AT_800Hz 0x29 +#define LSM6DSVXXX_DT_ODR_HA02_AT_1600Hz 0x2A +#define LSM6DSVXXX_DT_ODR_HA02_AT_3200Hz 0x2B +#define LSM6DSVXXX_DT_ODR_HA02_AT_6400Hz 0x2C + +/* Accelerometer batching rates */ +#define LSM6DSVXXX_DT_XL_NOT_BATCHED 0x0 +#define LSM6DSVXXX_DT_XL_BATCHED_AT_1Hz875 0x1 +#define LSM6DSVXXX_DT_XL_BATCHED_AT_7Hz5 0x2 +#define LSM6DSVXXX_DT_XL_BATCHED_AT_15Hz 0x3 +#define LSM6DSVXXX_DT_XL_BATCHED_AT_30Hz 0x4 +#define LSM6DSVXXX_DT_XL_BATCHED_AT_60Hz 0x5 +#define LSM6DSVXXX_DT_XL_BATCHED_AT_120Hz 0x6 +#define LSM6DSVXXX_DT_XL_BATCHED_AT_240Hz 0x7 +#define LSM6DSVXXX_DT_XL_BATCHED_AT_480Hz 0x8 +#define LSM6DSVXXX_DT_XL_BATCHED_AT_960Hz 0x9 +#define LSM6DSVXXX_DT_XL_BATCHED_AT_1920Hz 0xa +#define LSM6DSVXXX_DT_XL_BATCHED_AT_3840Hz 0xb +#define LSM6DSVXXX_DT_XL_BATCHED_AT_7680Hz 0xc + +/* Gyroscope batching rates */ +#define LSM6DSVXXX_DT_GY_NOT_BATCHED 0x0 +#define LSM6DSVXXX_DT_GY_BATCHED_AT_1Hz875 0x1 +#define LSM6DSVXXX_DT_GY_BATCHED_AT_7Hz5 0x2 +#define LSM6DSVXXX_DT_GY_BATCHED_AT_15Hz 0x3 +#define LSM6DSVXXX_DT_GY_BATCHED_AT_30Hz 0x4 +#define LSM6DSVXXX_DT_GY_BATCHED_AT_60Hz 0x5 +#define LSM6DSVXXX_DT_GY_BATCHED_AT_120Hz 0x6 +#define LSM6DSVXXX_DT_GY_BATCHED_AT_240Hz 0x7 +#define LSM6DSVXXX_DT_GY_BATCHED_AT_480Hz 0x8 +#define LSM6DSVXXX_DT_GY_BATCHED_AT_960Hz 0x9 +#define LSM6DSVXXX_DT_GY_BATCHED_AT_1920Hz 0xa +#define LSM6DSVXXX_DT_GY_BATCHED_AT_3840Hz 0xb +#define LSM6DSVXXX_DT_GY_BATCHED_AT_7680Hz 0xc + +/* Temperature sensor batching rates */ +#define LSM6DSVXXX_DT_TEMP_NOT_BATCHED 0x0 +#define LSM6DSVXXX_DT_TEMP_BATCHED_AT_1Hz875 0x1 +#define LSM6DSVXXX_DT_TEMP_BATCHED_AT_15Hz 0x2 +#define LSM6DSVXXX_DT_TEMP_BATCHED_AT_60Hz 0x3 + +/* Sensor Fusion Low Power Data rates */ +#define LSM6DSVXXX_DT_SFLP_ODR_AT_15Hz 0x0 +#define LSM6DSVXXX_DT_SFLP_ODR_AT_30Hz 0x1 +#define LSM6DSVXXX_DT_SFLP_ODR_AT_60Hz 0x2 +#define LSM6DSVXXX_DT_SFLP_ODR_AT_120Hz 0x3 +#define LSM6DSVXXX_DT_SFLP_ODR_AT_240Hz 0x4 +#define LSM6DSVXXX_DT_SFLP_ODR_AT_480Hz 0x5 + +/* Sensor Fusion Low Power FIFO enable defs */ +#define LSM6DSVXXX_DT_SFLP_FIFO_OFF 0x0 +#define LSM6DSVXXX_DT_SFLP_FIFO_GAME_ROTATION 0x1 +#define LSM6DSVXXX_DT_SFLP_FIFO_GRAVITY 0x2 +#define LSM6DSVXXX_DT_SFLP_FIFO_GAME_ROTATION_GRAVITY 0x3 +#define LSM6DSVXXX_DT_SFLP_FIFO_GBIAS 0x4 +#define LSM6DSVXXX_DT_SFLP_FIFO_GAME_ROTATION_GBIAS 0x5 +#define LSM6DSVXXX_DT_SFLP_FIFO_GRAVITY_GBIAS 0x6 +#define LSM6DSVXXX_DT_SFLP_FIFO_GAME_ROTATION_GRAVITY_GBIAS 0x7 + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_ST_LSM6DSVXXX_H_ */ diff --git a/samples/sensor/stream_fifo/boards/nucleo_f401re.overlay b/samples/sensor/stream_fifo/boards/nucleo_f401re.overlay index 4387131a0494..51ad4c985995 100644 --- a/samples/sensor/stream_fifo/boards/nucleo_f401re.overlay +++ b/samples/sensor/stream_fifo/boards/nucleo_f401re.overlay @@ -22,14 +22,14 @@ lsm6dsv16x_6b_x_nucleo_iks4a1: lsm6dsv16x@6b { compatible = "st,lsm6dsv16x"; reg = <0x6b>; - accel-odr = ; + accel-odr = ; accel-range = ; - gyro-odr = ; + gyro-odr = ; gyro-range = ; fifo-watermark = <64>; - accel-fifo-batch-rate = ; - gyro-fifo-batch-rate = ; - temp-fifo-batch-rate = ; + accel-fifo-batch-rate = ; + gyro-fifo-batch-rate = ; + temp-fifo-batch-rate = ; int2-gpios = <&arduino_header 10 GPIO_ACTIVE_HIGH>; /* D4 (PB5) */ drdy-pin = <2>; drdy-pulsed; diff --git a/samples/sensor/stream_fifo/boards/nucleo_h503rb.overlay b/samples/sensor/stream_fifo/boards/nucleo_h503rb.overlay index 28fbe5d791de..685b8ac09a82 100644 --- a/samples/sensor/stream_fifo/boards/nucleo_h503rb.overlay +++ b/samples/sensor/stream_fifo/boards/nucleo_h503rb.overlay @@ -22,17 +22,17 @@ lsm6dsv16x_6b_x_nucleo_iks4a1: lsm6dsv16x@6b { compatible = "st,lsm6dsv16x"; reg = <0x6b>; - accel-odr = ; + accel-odr = ; accel-range = ; - gyro-odr = ; + gyro-odr = ; gyro-range = ; fifo-watermark = <64>; - accel-fifo-batch-rate = ; - gyro-fifo-batch-rate = ; - temp-fifo-batch-rate = ; + accel-fifo-batch-rate = ; + gyro-fifo-batch-rate = ; + temp-fifo-batch-rate = ; - sflp-odr = ; - sflp-fifo-enable = ; + sflp-odr = ; + sflp-fifo-enable = ; int2-gpios = <&arduino_header 10 GPIO_ACTIVE_HIGH>; /* D4 (PB5) */ drdy-pin = <2>; drdy-pulsed; diff --git a/samples/sensor/stream_fifo/boards/sensortile_box_pro.overlay b/samples/sensor/stream_fifo/boards/sensortile_box_pro.overlay index 5f5864e6ca3e..8d702222233f 100644 --- a/samples/sensor/stream_fifo/boards/sensortile_box_pro.overlay +++ b/samples/sensor/stream_fifo/boards/sensortile_box_pro.overlay @@ -20,16 +20,16 @@ lsm6dsv16x_0: lsm6dsv16x@0 { compatible = "st,lsm6dsv16x"; - accel-odr = ; + accel-odr = ; accel-range = ; - gyro-odr = ; + gyro-odr = ; gyro-range = ; fifo-watermark = <64>; - accel-fifo-batch-rate = ; - gyro-fifo-batch-rate = ; - temp-fifo-batch-rate = ; + accel-fifo-batch-rate = ; + gyro-fifo-batch-rate = ; + temp-fifo-batch-rate = ; - sflp-odr = ; - sflp-fifo-enable = ; + sflp-odr = ; + sflp-fifo-enable = ; }; }; diff --git a/tests/drivers/build_all/sensor/i2c.dtsi b/tests/drivers/build_all/sensor/i2c.dtsi index 818b05711e0f..c8f108c29254 100644 --- a/tests/drivers/build_all/sensor/i2c.dtsi +++ b/tests/drivers/build_all/sensor/i2c.dtsi @@ -7,6 +7,7 @@ */ #include +#include #include #include #include @@ -756,9 +757,9 @@ test_i2c_lsm6dsv16x: lsm6dsv16x@69 { int1-gpios = <&test_gpio 0 0>; int2-gpios = <&test_gpio 0 0>; accel-range = ; - accel-odr = ; + accel-odr = ; gyro-range = ; - gyro-odr = ; + gyro-odr = ; }; test_i2c_mcp9600: mcp9600@6a { diff --git a/tests/drivers/build_all/sensor/i3c.dtsi b/tests/drivers/build_all/sensor/i3c.dtsi index 97de324de86e..7118f1d4b717 100644 --- a/tests/drivers/build_all/sensor/i3c.dtsi +++ b/tests/drivers/build_all/sensor/i3c.dtsi @@ -45,9 +45,9 @@ test_i3c_lsm6dsv16x: lsm6dsv16x@500000803E0000004 { int1-gpios = <&test_gpio 0 0>; int2-gpios = <&test_gpio 0 0>; accel-range = ; - accel-odr = ; + accel-odr = ; gyro-range = ; - gyro-odr = ; + gyro-odr = ; }; test_i3c_lsm6dsv32x: lsm6dsv32x@600000803E0000004 { @@ -57,9 +57,9 @@ test_i3c_lsm6dsv32x: lsm6dsv32x@600000803E0000004 { int1-gpios = <&test_gpio 0 0>; int2-gpios = <&test_gpio 0 0>; accel-range = ; - accel-odr = ; - gyro-range = ; - gyro-odr = ; + accel-odr = ; + gyro-range = ; + gyro-odr = ; }; test_i3c_icm45686: icm45686@700000803E0000004 { From d6eaae4d531a7afd6244d14f29827f79395c3d37 Mon Sep 17 00:00:00 2001 From: Armando Visconti Date: Wed, 28 May 2025 17:33:27 +0200 Subject: [PATCH 1530/3659] drivers/sensor/st: add support to LSM6DSVXXX IMU family This driver is currently only supporting the polling-mode read_and_decode APIs (both blocking and non-blocking). The driver implements a chip_api structure which has to be used to provide device specific callbacks. The only lsm6dsvxxx family device currently supported is lsm6dsv320x. More information about LSM6DSV16X: https://www.st.com/resource/en/datasheet/lsm6dsv320x.pdf Signed-off-by: Armando Visconti --- drivers/sensor/st/CMakeLists.txt | 1 + drivers/sensor/st/Kconfig | 1 + drivers/sensor/st/lsm6dsvxxx/CMakeLists.txt | 13 + drivers/sensor/st/lsm6dsvxxx/Kconfig | 27 + drivers/sensor/st/lsm6dsvxxx/lsm6dsv320x.c | 648 ++++++++++++++++++ drivers/sensor/st/lsm6dsvxxx/lsm6dsv320x.h | 23 + drivers/sensor/st/lsm6dsvxxx/lsm6dsvxxx.c | 502 ++++++++++++++ drivers/sensor/st/lsm6dsvxxx/lsm6dsvxxx.h | 209 ++++++ .../sensor/st/lsm6dsvxxx/lsm6dsvxxx_decoder.c | 215 ++++++ .../sensor/st/lsm6dsvxxx/lsm6dsvxxx_rtio.h | 22 + .../sensor/st,lsm6dsv320x-common.yaml | 76 ++ dts/bindings/sensor/st,lsm6dsv320x-i2c.yaml | 10 + dts/bindings/sensor/st,lsm6dsv320x-i3c.yaml | 24 + dts/bindings/sensor/st,lsm6dsv320x-spi.yaml | 10 + .../zephyr/dt-bindings/sensor/lsm6dsv320x.h | 37 + modules/hal_st/Kconfig | 3 + tests/drivers/build_all/sensor/i2c.dtsi | 12 + 17 files changed, 1833 insertions(+) create mode 100644 drivers/sensor/st/lsm6dsvxxx/CMakeLists.txt create mode 100644 drivers/sensor/st/lsm6dsvxxx/Kconfig create mode 100644 drivers/sensor/st/lsm6dsvxxx/lsm6dsv320x.c create mode 100644 drivers/sensor/st/lsm6dsvxxx/lsm6dsv320x.h create mode 100644 drivers/sensor/st/lsm6dsvxxx/lsm6dsvxxx.c create mode 100644 drivers/sensor/st/lsm6dsvxxx/lsm6dsvxxx.h create mode 100644 drivers/sensor/st/lsm6dsvxxx/lsm6dsvxxx_decoder.c create mode 100644 drivers/sensor/st/lsm6dsvxxx/lsm6dsvxxx_rtio.h create mode 100644 dts/bindings/sensor/st,lsm6dsv320x-common.yaml create mode 100644 dts/bindings/sensor/st,lsm6dsv320x-i2c.yaml create mode 100644 dts/bindings/sensor/st,lsm6dsv320x-i3c.yaml create mode 100644 dts/bindings/sensor/st,lsm6dsv320x-spi.yaml create mode 100644 include/zephyr/dt-bindings/sensor/lsm6dsv320x.h diff --git a/drivers/sensor/st/CMakeLists.txt b/drivers/sensor/st/CMakeLists.txt index 979d67d96ae2..ab62b3e978c0 100644 --- a/drivers/sensor/st/CMakeLists.txt +++ b/drivers/sensor/st/CMakeLists.txt @@ -31,6 +31,7 @@ add_subdirectory_ifdef(CONFIG_LSM6DSL lsm6dsl) add_subdirectory_ifdef(CONFIG_LSM6DSO lsm6dso) add_subdirectory_ifdef(CONFIG_LSM6DSO16IS lsm6dso16is) add_subdirectory_ifdef(CONFIG_LSM6DSV16X lsm6dsv16x) +add_subdirectory_ifdef(CONFIG_LSM6DSVXXX lsm6dsvxxx) add_subdirectory_ifdef(CONFIG_LSM9DS0_GYRO lsm9ds0_gyro) add_subdirectory_ifdef(CONFIG_LSM9DS0_MFD lsm9ds0_mfd) add_subdirectory_ifdef(CONFIG_LSM9DS1 lsm9ds1) diff --git a/drivers/sensor/st/Kconfig b/drivers/sensor/st/Kconfig index 4daaba9d7cc8..88bd18aea15a 100644 --- a/drivers/sensor/st/Kconfig +++ b/drivers/sensor/st/Kconfig @@ -30,6 +30,7 @@ source "drivers/sensor/st/lsm6dsl/Kconfig" source "drivers/sensor/st/lsm6dso/Kconfig" source "drivers/sensor/st/lsm6dso16is/Kconfig" source "drivers/sensor/st/lsm6dsv16x/Kconfig" +source "drivers/sensor/st/lsm6dsvxxx/Kconfig" source "drivers/sensor/st/lsm9ds0_gyro/Kconfig" source "drivers/sensor/st/lsm9ds0_mfd/Kconfig" source "drivers/sensor/st/lsm9ds1/Kconfig" diff --git a/drivers/sensor/st/lsm6dsvxxx/CMakeLists.txt b/drivers/sensor/st/lsm6dsvxxx/CMakeLists.txt new file mode 100644 index 000000000000..5734502cf778 --- /dev/null +++ b/drivers/sensor/st/lsm6dsvxxx/CMakeLists.txt @@ -0,0 +1,13 @@ +# ST Microelectronics LSM6DSVXXX accelerometer sensor +# +# Copyright (c) 2025 STMicroelectronics +# +# SPDX-License-Identifier: Apache-2.0 +# +zephyr_library() + +zephyr_library_sources(lsm6dsvxxx.c) +zephyr_library_sources_ifdef(CONFIG_DT_HAS_ST_LSM6DSV320X_ENABLED lsm6dsv320x.c) +zephyr_library_sources_ifdef(CONFIG_SENSOR_ASYNC_API lsm6dsvxxx_decoder.c) + +zephyr_library_include_directories(../stmemsc) diff --git a/drivers/sensor/st/lsm6dsvxxx/Kconfig b/drivers/sensor/st/lsm6dsvxxx/Kconfig new file mode 100644 index 000000000000..17931fe1a4bf --- /dev/null +++ b/drivers/sensor/st/lsm6dsvxxx/Kconfig @@ -0,0 +1,27 @@ +# ST Microelectronics LSM6DSVXXX accelerometer sensor + +# Copyright (c) 2025 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +menuconfig LSM6DSVXXX + bool "LSM6DSVXXX IMU sensor" + default y + depends on DT_HAS_ST_LSM6DSV320X_ENABLED + depends on ZEPHYR_HAL_ST_MODULE + select I2C if $(dt_compat_on_bus,$(DT_COMPAT_ST_LSM6DSV320X),i2c) + select I3C if $(dt_compat_on_bus,$(DT_COMPAT_ST_LSM6DSV320X),i3c) + select SPI if $(dt_compat_on_bus,$(DT_COMPAT_ST_LSM6DSV320X),spi) + select HAS_STMEMSC + select USE_STDC_LSM6DSV320X if DT_HAS_ST_LSM6DSV320X_ENABLED + help + Enable driver for LSM6DSVXXX family IMU sensors. + +if LSM6DSVXXX + +config LSM6DSVXXX_ENABLE_TEMP + bool "Temperature" + help + Enable/disable temperature sensor + + +endif # LSM6DSVXXX diff --git a/drivers/sensor/st/lsm6dsvxxx/lsm6dsv320x.c b/drivers/sensor/st/lsm6dsvxxx/lsm6dsv320x.c new file mode 100644 index 000000000000..8648df54a4b6 --- /dev/null +++ b/drivers/sensor/st/lsm6dsvxxx/lsm6dsv320x.c @@ -0,0 +1,648 @@ +/* ST Microelectronics LSM6DSVXXX family IMU sensor + * + * Copyright (c) 2025 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + * + * Datasheet: + * https://www.st.com/resource/en/datasheet/lsm6dsv320x.pdf + */ + +#include "lsm6dsv320x.h" +#include + +LOG_MODULE_DECLARE(LSM6DSVXXX, CONFIG_SENSOR_LOG_LEVEL); + +/* + * XL configuration + */ + +static uint16_t lsm6dsv320x_accel_gain_ug(uint8_t fs) +{ + if (fs == 8) { + /* range is 320g */ + return 10417; + } + + return (61 * (1 << fs)); +} + +/* The first nibble of fs tells if it is High-G or not */ +static int lsm6dsv320x_accel_range_to_fs_val(const struct device *dev, + int32_t range, + uint8_t *fs) +{ + switch (range) { + case LSM6DSV320X_DT_FS_2G: + *fs = 0; + break; + + case LSM6DSV320X_DT_FS_4G: + *fs = 1; + break; + + case LSM6DSV320X_DT_FS_8G: + *fs = 2; + break; + + case LSM6DSV320X_DT_FS_16G: + *fs = 3; + break; + + case LSM6DSV320X_DT_FS_32G: + *fs = 4; + break; + + case LSM6DSV320X_DT_FS_64G: + *fs = 5; + break; + + case LSM6DSV320X_DT_FS_128G: + *fs = 6; + break; + + case LSM6DSV320X_DT_FS_256G: + *fs = 7; + break; + + case LSM6DSV320X_DT_FS_320G: + *fs = 8; + break; + + default: + return -EINVAL; + } + + return 0; +} + +static int lsm6dsv320x_accel_set_fs_raw(const struct device *dev, uint8_t fs) +{ + const struct lsm6dsvxxx_config *cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + struct lsm6dsvxxx_data *data = dev->data; + + if (fs < 4) { /* 2g/4g/8g/16g */ + lsm6dsv320x_xl_full_scale_t val = fs; + + if (lsm6dsv320x_xl_full_scale_set(ctx, val) < 0) { + return -EIO; + } + + data->out_xl = LSM6DSV320X_OUTX_L_A; + } else if (fs <= 8) { /* 32g/64g/128g/256g/320g */ + lsm6dsv320x_hg_xl_full_scale_t val = (fs - 4); + + if (lsm6dsv320x_hg_xl_full_scale_set(ctx, val) < 0) { + return -EIO; + } + + data->out_xl = LSM6DSV320X_UI_OUTX_L_A_OIS_HG; + } else { + return -EINVAL; + } + + data->accel_fs = fs; + data->acc_gain = lsm6dsv320x_accel_gain_ug(fs); + + return 0; +} + +static int lsm6dsv320x_accel_set_fs(const struct device *dev, int32_t range) +{ + uint8_t fs; + int ret; + + ret = lsm6dsv320x_accel_range_to_fs_val(dev, range, &fs); + if (ret < 0) { + return ret; + } + + ret = lsm6dsv320x_accel_set_fs_raw(dev, fs); + if (ret < 0) { + return ret; + } + + return 0; +} + +static int lsm6dsv320x_accel_set_odr_raw(const struct device *dev, uint8_t odr) +{ + const struct lsm6dsvxxx_config *cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + struct lsm6dsvxxx_data *data = dev->data; + + if (cfg->accel_hg_odr != LSM6DSV320X_HG_XL_ODR_OFF) { + + if (lsm6dsv320x_hg_xl_data_rate_set(ctx, cfg->accel_hg_odr, 1) < 0) { + return -EIO; + } + } else { + if (lsm6dsv320x_xl_data_rate_set(ctx, odr) < 0) { + return -EIO; + } + } + + data->accel_freq = odr; + + return 0; +} + +/* + * values taken from lsm6dsv320x_data_rate_t in hal/st module. The mode/accuracy + * should be selected through accel-odr property in DT + */ +static const float lsm6dsv320x_odr_map[3][13] = { + /* High Accuracy off */ + {0.0f, 1.875f, 7.5f, 15.0f, 30.0f, 60.0f, + 120.0f, 240.0f, 480.0f, 960.0f, 1920.0f, + 3840.0f, 7680.0f}, + + /* High Accuracy 1 */ + {0.0f, 1.875f, 7.5f, 15.625f, 31.25f, 62.5f, + 125.0f, 250.0f, 500.0f, 1000.0f, 2000.0f, + 4000.0f, 8000.0f}, + + /* High Accuracy 2 */ + {0.0f, 1.875f, 7.5f, 12.5f, 25.0f, 50.0f, + 100.0f, 200.0f, 400.0f, 800.0f, 1600.0f, + 3200.0f, 6400.0f}, + }; + +static uint8_t lsm6dsv320x_freq_to_odr_val(const struct device *dev, int32_t freq) +{ + const struct lsm6dsvxxx_config *cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + lsm6dsv320x_data_rate_t odr; + int8_t mode; + size_t i; + + if (lsm6dsv320x_xl_data_rate_get(ctx, &odr) < 0) { + return -EINVAL; + } + + mode = (odr >> 4) & 0xf; + + for (i = 0; i < ARRAY_SIZE(lsm6dsv320x_odr_map[mode]); i++) { + if (freq <= lsm6dsv320x_odr_map[mode][i]) { + LOG_DBG("mode: %d - odr: %d", mode, i); + return i | (mode << 4); + } + } + + return 0xFF; +} + +static int lsm6dsv320x_accel_set_odr(const struct device *dev, int32_t freq) +{ + uint8_t odr; + + odr = lsm6dsv320x_freq_to_odr_val(dev, freq); + if (odr == 0xFF) { + return -EINVAL; + } + + if (lsm6dsv320x_accel_set_odr_raw(dev, odr) < 0) { + LOG_DBG("failed to set accelerometer sampling rate"); + return -EIO; + } + + return 0; +} + +static int32_t lsm6dsv320x_accel_set_mode(const struct device *dev, int32_t mode) +{ + const struct lsm6dsvxxx_config *cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + + switch (mode) { + case 0: /* High Performance */ + mode = LSM6DSV320X_XL_HIGH_PERFORMANCE_MD; + break; + case 1: /* High Accuracy */ + mode = LSM6DSV320X_XL_HIGH_ACCURACY_ODR_MD; + break; + case 3: /* ODR triggered */ + mode = LSM6DSV320X_XL_ODR_TRIGGERED_MD; + break; + case 4: /* Low Power 2 */ + mode = LSM6DSV320X_XL_LOW_POWER_2_AVG_MD; + break; + case 5: /* Low Power 4 */ + mode = LSM6DSV320X_XL_LOW_POWER_4_AVG_MD; + break; + case 6: /* Low Power 8 */ + mode = LSM6DSV320X_XL_LOW_POWER_8_AVG_MD; + break; + case 7: /* Normal */ + mode = LSM6DSV320X_XL_NORMAL_MD; + break; + default: + return -EIO; + } + + return lsm6dsv320x_xl_mode_set(ctx, mode); +} + +static int32_t lsm6dsv320x_accel_get_fs(const struct device *dev, int32_t *range) +{ + return -ENOTSUP; +} + +static int32_t lsm6dsv320x_accel_get_odr(const struct device *dev, int32_t *freq) +{ + return -ENOTSUP; +} + +static int32_t lsm6dsv320x_accel_get_mode(const struct device *dev, int32_t *mode) +{ + const struct lsm6dsvxxx_config *cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + lsm6dsv320x_xl_mode_t md; + + lsm6dsv320x_xl_mode_get(ctx, &md); + + switch (md) { + case LSM6DSV320X_XL_HIGH_PERFORMANCE_MD: + *mode = 0; + break; + case LSM6DSV320X_XL_HIGH_ACCURACY_ODR_MD: + *mode = 1; + break; + case LSM6DSV320X_XL_ODR_TRIGGERED_MD: + *mode = 3; + break; + case LSM6DSV320X_XL_LOW_POWER_2_AVG_MD: + *mode = 4; + break; + case LSM6DSV320X_XL_LOW_POWER_4_AVG_MD: + *mode = 5; + break; + case LSM6DSV320X_XL_LOW_POWER_8_AVG_MD: + *mode = 6; + break; + case LSM6DSV320X_XL_NORMAL_MD: + *mode = 7; + break; + default: + return -EIO; + } + + return 0; +} + +/* + * GY configuration + */ + +static int lsm6dsv320x_gyro_range_to_fs_val(const struct device *dev, + int32_t range, + uint8_t *fs) +{ + switch (range) { + case 0: + *fs = 0; + break; + + case 250: + *fs = LSM6DSV320X_DT_FS_250DPS; + break; + + case 500: + *fs = LSM6DSV320X_DT_FS_500DPS; + break; + + case 1000: + *fs = LSM6DSV320X_DT_FS_1000DPS; + break; + + case 2000: + *fs = LSM6DSV320X_DT_FS_2000DPS; + break; + + case 4000: + *fs = LSM6DSV320X_DT_FS_4000DPS; + break; + + default: + return -EINVAL; + } + + return 0; +} + +static uint32_t lsm6dsv320x_gyro_gain_udps(uint8_t fs) +{ + return (4375 * (1 << fs)); +} + +static int lsm6dsv320x_gyro_set_fs_raw(const struct device *dev, uint8_t fs) +{ + const struct lsm6dsvxxx_config *cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + struct lsm6dsvxxx_data *data = dev->data; + + if (fs == 0) { + /* skip power-up value */ + return 0; + } + + if (lsm6dsv320x_gy_full_scale_set(ctx, fs) < 0) { + return -EIO; + } + + data->gyro_fs = fs; + data->gyro_gain = lsm6dsv320x_gyro_gain_udps(fs); + return 0; +} + +static int lsm6dsv320x_gyro_set_fs(const struct device *dev, int32_t range) +{ + uint8_t fs; + int ret; + + ret = lsm6dsv320x_gyro_range_to_fs_val(dev, range, &fs); + if (ret < 0) { + return ret; + } + + if (lsm6dsv320x_gyro_set_fs_raw(dev, fs) < 0) { + return -EIO; + } + + return 0; +} + +static int lsm6dsv320x_gyro_set_odr_raw(const struct device *dev, uint8_t odr) +{ + const struct lsm6dsvxxx_config *cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + struct lsm6dsvxxx_data *data = dev->data; + + if (lsm6dsv320x_gy_data_rate_set(ctx, odr) < 0) { + return -EIO; + } + + data->gyro_freq = odr; + return 0; +} + +static int lsm6dsv320x_gyro_set_odr(const struct device *dev, int32_t freq) +{ + uint8_t odr; + + odr = lsm6dsv320x_freq_to_odr_val(dev, freq); + if (odr == 0xFF) { + return -EINVAL; + } + + if (lsm6dsv320x_gyro_set_odr_raw(dev, odr) < 0) { + LOG_DBG("failed to set gyroscope sampling rate"); + return -EIO; + } + + return 0; +} + +static int32_t lsm6dsv320x_gyro_set_mode(const struct device *dev, int32_t mode) +{ + const struct lsm6dsvxxx_config *cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + + switch (mode) { + case 0: /* High Performance */ + mode = LSM6DSV320X_GY_HIGH_PERFORMANCE_MD; + break; + case 1: /* High Accuracy */ + mode = LSM6DSV320X_GY_HIGH_ACCURACY_ODR_MD; + break; + case 4: /* Sleep */ + mode = LSM6DSV320X_GY_SLEEP_MD; + break; + case 5: /* Low Power */ + mode = LSM6DSV320X_GY_LOW_POWER_MD; + break; + default: + return -EIO; + } + + return lsm6dsv320x_gy_mode_set(ctx, mode); +} + +static int32_t lsm6dsv320x_gyro_get_fs(const struct device *dev, int32_t *range) +{ + return -ENOTSUP; +} + +static int32_t lsm6dsv320x_gyro_get_odr(const struct device *dev, int32_t *freq) +{ + return -ENOTSUP; +} + +static int32_t lsm6dsv320x_gyro_get_mode(const struct device *dev, int32_t *mode) +{ + const struct lsm6dsvxxx_config *cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + lsm6dsv320x_gy_mode_t md; + + lsm6dsv320x_gy_mode_get(ctx, &md); + + switch (md) { + case LSM6DSV320X_GY_HIGH_PERFORMANCE_MD: + *mode = 0; + break; + case LSM6DSV320X_GY_HIGH_ACCURACY_ODR_MD: + *mode = 1; + break; + case LSM6DSV320X_GY_SLEEP_MD: + *mode = 4; + break; + case LSM6DSV320X_GY_LOW_POWER_MD: + *mode = 5; + break; + default: + return -EIO; + } + + return 0; +} + +static int lsm6dsv320x_init_chip(const struct device *dev) +{ + const struct lsm6dsvxxx_config *cfg = dev->config; + struct lsm6dsvxxx_data *data = dev->data; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + uint8_t chip_id; + uint8_t odr, fs; + +#if LSM6DSVXXX_ANY_INST_ON_BUS_STATUS_OKAY(i3c) + if (cfg->i3c.bus != NULL) { + /* + * Need to grab the pointer to the I3C device descriptor + * before we can talk to the sensor. + */ + lsm6dsvxxx->i3c_dev = i3c_device_find(cfg->i3c.bus, &cfg->i3c.dev_id); + if (lsm6dsvxxx->i3c_dev == NULL) { + LOG_ERR("Cannot find I3C device descriptor"); + return -ENODEV; + } + } +#endif + + /* All registers except 0x01 are different between banks, including the WHO_AM_I + * register and the register used for a SW reset. If the lsm6dsvxxx wasn't on the user + * bank when it reset, then both the chip id check and the sw reset will fail unless we + * set the bank now. + */ + if (lsm6dsv320x_mem_bank_set(ctx, LSM6DSV320X_MAIN_MEM_BANK) < 0) { + LOG_DBG("Failed to set user bank"); + return -EIO; + } + + if (lsm6dsv320x_device_id_get(ctx, &chip_id) < 0) { + LOG_DBG("Failed reading chip id"); + return -EIO; + } + + LOG_INF("chip id 0x%x", chip_id); + + if (chip_id != LSM6DSV320X_ID) { + LOG_DBG("Invalid chip id 0x%x", chip_id); + return -EIO; + } + + /* Resetting the whole device while using I3C will also reset the DA, therefore perform + * only a software reset if the bus is I3C. It should be assumed that the device was + * already fully reset by the I3C CCC RSTACT (whole chip) done as apart of the I3C Bus + * initialization. + */ + if (ON_I3C_BUS(cfg)) { + /* Restore default configuration */ + lsm6dsv320x_reboot(ctx); + + /* wait 150us as reported in AN5763 */ + k_sleep(K_USEC(150)); + } else { + /* reset device (sw_por) */ + if (lsm6dsv320x_sw_por(ctx) < 0) { + return -EIO; + } + + /* wait 30ms as reported in AN5763 */ + k_sleep(K_MSEC(30)); + } + + data->out_xl = LSM6DSV320X_OUTX_L_A; + data->out_tp = LSM6DSV320X_OUT_TEMP_L; + + fs = cfg->accel_range; + LOG_DBG("accel range is %d", fs); + if (lsm6dsv320x_accel_set_fs_raw(dev, fs) < 0) { + LOG_ERR("failed to set accelerometer range %d", fs); + return -EIO; + } + + odr = cfg->accel_odr; + LOG_DBG("accel odr is %d", odr); + if (lsm6dsv320x_accel_set_odr_raw(dev, odr) < 0) { + LOG_ERR("failed to set accelerometer odr %d", odr); + return -EIO; + } + + fs = cfg->gyro_range; + LOG_DBG("gyro range is %d", fs); + if (lsm6dsv320x_gyro_set_fs_raw(dev, fs) < 0) { + LOG_ERR("failed to set gyroscope range %d", fs); + return -EIO; + } + + odr = cfg->gyro_odr; + LOG_DBG("gyro odr is %d", odr); + if (lsm6dsv320x_gyro_set_odr_raw(dev, odr) < 0) { + LOG_ERR("failed to set gyroscope odr %d", odr); + return -EIO; + } + +#if LSM6DSVXXX_ANY_INST_ON_BUS_STATUS_OKAY(i3c) + if (IS_ENABLED(CONFIG_LSM6DSVXXX_STREAM) && (ON_I3C_BUS(cfg))) { + /* + * Set MRL to the Max Size of the FIFO so the entire FIFO can be read + * out at once + */ + struct i3c_ccc_mrl setmrl = { + .len = 0x0700, + .ibi_len = lsm6dsvxxx->i3c_dev->data_length.max_ibi, + }; + if (i3c_ccc_do_setmrl(lsm6dsvxxx->i3c_dev, &setmrl) < 0) { + LOG_ERR("failed to set mrl"); + return -EIO; + } + } +#endif + + if (lsm6dsv320x_block_data_update_set(ctx, 1) < 0) { + LOG_DBG("failed to set BDU mode"); + return -EIO; + } + + return 0; +} + +#if defined(CONFIG_PM_DEVICE) +static int lsm6dsv320x_pm_action(const struct device *dev, enum pm_device_action action) +{ + struct lsm6dsvxxx_data *data = dev->data; + const struct lsm6dsvxxx_config *cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + int ret = 0; + + LOG_DBG("PM action: %d", (int)action); + + switch (action) { + case PM_DEVICE_ACTION_RESUME: + if (lsm6dsv320x_xl_data_rate_set(ctx, data->accel_freq) < 0) { + LOG_ERR("failed to set accelerometer odr %d", (int)data->accel_freq); + ret = -EIO; + } + if (lsm6dsv320x_gy_data_rate_set(ctx, data->gyro_freq) < 0) { + LOG_ERR("failed to set gyroscope odr %d", (int)data->gyro_freq); + ret = -EIO; + } + break; + case PM_DEVICE_ACTION_SUSPEND: + if (lsm6dsv320x_xl_data_rate_set(ctx, LSM6DSVXXX_DT_ODR_OFF) < 0) { + LOG_ERR("failed to disable accelerometer"); + ret = -EIO; + } + if (lsm6dsv320x_gy_data_rate_set(ctx, LSM6DSVXXX_DT_ODR_OFF) < 0) { + LOG_ERR("failed to disable gyroscope"); + ret = -EIO; + } + break; + default: + ret = -ENOTSUP; + break; + } + + return ret; +} +#endif /* CONFIG_PM_DEVICE */ + +const struct lsm6dsvxxx_chip_api st_lsm6dsv320x_chip_api = { + .init_chip = lsm6dsv320x_init_chip, +#if defined(CONFIG_PM_DEVICE) + .pm_action = lsm6dsv320x_pm_action, +#endif /* CONFIG_PM_DEVICE */ + .accel_fs_set = lsm6dsv320x_accel_set_fs, + .accel_odr_set = lsm6dsv320x_accel_set_odr, + .accel_mode_set = lsm6dsv320x_accel_set_mode, + .accel_fs_get = lsm6dsv320x_accel_get_fs, + .accel_odr_get = lsm6dsv320x_accel_get_odr, + .accel_mode_get = lsm6dsv320x_accel_get_mode, + .gyro_fs_set = lsm6dsv320x_gyro_set_fs, + .gyro_odr_set = lsm6dsv320x_gyro_set_odr, + .gyro_mode_set = lsm6dsv320x_gyro_set_mode, + .gyro_fs_get = lsm6dsv320x_gyro_get_fs, + .gyro_odr_get = lsm6dsv320x_gyro_get_odr, + .gyro_mode_get = lsm6dsv320x_gyro_get_mode, +}; diff --git a/drivers/sensor/st/lsm6dsvxxx/lsm6dsv320x.h b/drivers/sensor/st/lsm6dsvxxx/lsm6dsv320x.h new file mode 100644 index 000000000000..2959bda8ddc2 --- /dev/null +++ b/drivers/sensor/st/lsm6dsvxxx/lsm6dsv320x.h @@ -0,0 +1,23 @@ +/* ST Microelectronics LSM6DSVXXX family IMU sensor + * + * Copyright (c) 2025 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + * + * Datasheet: + * https://www.st.com/resource/en/datasheet/lsm6dsv320x.pdf + */ +#ifndef ZEPHYR_DRIVERS_SENSOR_LSM6DSV320X_H_ +#define ZEPHYR_DRIVERS_SENSOR_LSM6DSV320X_H_ + +#include +#include + +#include "lsm6dsvxxx.h" +#include "lsm6dsv320x_reg.h" + +#include + +extern const struct lsm6dsvxxx_chip_api st_lsm6dsv320x_chip_api; + +#endif /* ZEPHYR_DRIVERS_SENSOR_LSM6DSV320X_H_ */ diff --git a/drivers/sensor/st/lsm6dsvxxx/lsm6dsvxxx.c b/drivers/sensor/st/lsm6dsvxxx/lsm6dsvxxx.c new file mode 100644 index 000000000000..880eb9f7d02c --- /dev/null +++ b/drivers/sensor/st/lsm6dsvxxx/lsm6dsvxxx.c @@ -0,0 +1,502 @@ +/* ST Microelectronics LSM6DSVXXX family IMU sensor + * + * Copyright (c) 2025 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + * + * Datasheet: + * https://www.st.com/resource/en/datasheet/lsm6dsv320x.pdf + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "lsm6dsvxxx.h" +#include "lsm6dsvxxx_rtio.h" + +#if DT_HAS_COMPAT_STATUS_OKAY(st_lsm6dsv320x) +#include "lsm6dsv320x.h" +#endif + +LOG_MODULE_REGISTER(LSM6DSVXXX, CONFIG_SENSOR_LOG_LEVEL); + +static int lsm6dsvxxx_accel_config(const struct device *dev, + enum sensor_channel chan, + enum sensor_attribute attr, + const struct sensor_value *val) +{ + const struct lsm6dsvxxx_config *cfg = dev->config; + + switch (attr) { + case SENSOR_ATTR_FULL_SCALE: + return cfg->chip_api->accel_fs_set(dev, sensor_ms2_to_g(val)); + case SENSOR_ATTR_SAMPLING_FREQUENCY: + return cfg->chip_api->accel_odr_set(dev, val->val1); + case SENSOR_ATTR_CONFIGURATION: + return cfg->chip_api->accel_mode_set(dev, val->val1); + default: + LOG_DBG("Accel attribute not supported."); + return -ENOTSUP; + } + + return 0; +} + +static int lsm6dsvxxx_gyro_config(const struct device *dev, + enum sensor_channel chan, + enum sensor_attribute attr, + const struct sensor_value *val) +{ + const struct lsm6dsvxxx_config *cfg = dev->config; + + switch (attr) { + case SENSOR_ATTR_FULL_SCALE: + return cfg->chip_api->gyro_fs_set(dev, sensor_rad_to_degrees(val)); + case SENSOR_ATTR_SAMPLING_FREQUENCY: + return cfg->chip_api->gyro_odr_set(dev, val->val1); + case SENSOR_ATTR_CONFIGURATION: + return cfg->chip_api->gyro_mode_set(dev, val->val1); + default: + LOG_DBG("Gyro attribute not supported."); + return -ENOTSUP; + } + + return 0; +} + +static int lsm6dsvxxx_attr_set(const struct device *dev, + enum sensor_channel chan, + enum sensor_attribute attr, + const struct sensor_value *val) +{ + switch (chan) { + case SENSOR_CHAN_ACCEL_XYZ: + return lsm6dsvxxx_accel_config(dev, chan, attr, val); + case SENSOR_CHAN_GYRO_XYZ: + return lsm6dsvxxx_gyro_config(dev, chan, attr, val); +#ifdef CONFIG_LSM6DSVXXX_STREAM + case SENSOR_CHAN_GBIAS_XYZ: + return lsm6dsvxxx_gbias_config(dev, chan, attr, val); +#endif /* CONFIG_LSM6DSVXXX_STREAM */ + default: + LOG_WRN("attr_set() not supported on this channel."); + return -ENOTSUP; + } + + return 0; +} + +static int lsm6dsvxxx_accel_get_config(const struct device *dev, + enum sensor_channel chan, + enum sensor_attribute attr, + struct sensor_value *val) +{ + const struct lsm6dsvxxx_config *cfg = dev->config; + + switch (attr) { + case SENSOR_ATTR_CONFIGURATION: + return cfg->chip_api->accel_mode_get(dev, &val->val1); + default: + LOG_DBG("Accel attribute not supported."); + return -ENOTSUP; + } + + return 0; +} + +static int lsm6dsvxxx_gyro_get_config(const struct device *dev, + enum sensor_channel chan, + enum sensor_attribute attr, + struct sensor_value *val) +{ + const struct lsm6dsvxxx_config *cfg = dev->config; + + switch (attr) { + case SENSOR_ATTR_CONFIGURATION: + return cfg->chip_api->gyro_mode_get(dev, &val->val1); + default: + LOG_DBG("Gyro attribute not supported."); + return -ENOTSUP; + } + + return 0; +} + +static int lsm6dsvxxx_attr_get(const struct device *dev, enum sensor_channel chan, + enum sensor_attribute attr, struct sensor_value *val) +{ + switch (chan) { + case SENSOR_CHAN_ACCEL_XYZ: + return lsm6dsvxxx_accel_get_config(dev, chan, attr, val); + case SENSOR_CHAN_GYRO_XYZ: + return lsm6dsvxxx_gyro_get_config(dev, chan, attr, val); +#ifdef CONFIG_LSM6DSVXXX_STREAM + case SENSOR_CHAN_GBIAS_XYZ: + return lsm6dsvxxx_gbias_get_config(dev, chan, attr, val); +#endif /* CONFIG_LSM6DSVXXX_STREAM */ + default: + LOG_WRN("attr_get() not supported on this channel."); + return -ENOTSUP; + } + + return 0; +} + +static void lsm6dsvxxx_one_shot_complete_cb(struct rtio *ctx, const struct rtio_sqe *sqe, + int result, void *arg) +{ + ARG_UNUSED(result); + + struct rtio_iodev_sqe *iodev_sqe = (struct rtio_iodev_sqe *)sqe->userdata; + int err = 0; + + err = rtio_flush_completion_queue(ctx); + + if (err) { + rtio_iodev_sqe_err(iodev_sqe, err); + } else { + rtio_iodev_sqe_ok(iodev_sqe, 0); + } +} + +static void lsm6dsvxxx_submit_one_shot(const struct device *dev, struct rtio_iodev_sqe *iodev_sqe) +{ + 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; + uint32_t min_buf_len = sizeof(struct lsm6dsvxxx_rtio_data); + uint64_t cycles; + int rc = 0; + uint8_t *buf; + uint32_t buf_len; + struct lsm6dsvxxx_rtio_data *edata; + struct lsm6dsvxxx_data *data = dev->data; + + /* Get the buffer for the frame, it may be allocated dynamically by the rtio context */ + 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); + return; + } + + edata = (struct lsm6dsvxxx_rtio_data *)buf; + + edata->has_accel = 0; + edata->has_temp = 0; + + rc = sensor_clock_get_cycles(&cycles); + if (rc != 0) { + LOG_ERR("Failed to get sensor clock cycles"); + rtio_iodev_sqe_err(iodev_sqe, rc); + return; + } + + edata->header.is_fifo = false; + edata->header.range = data->accel_fs; + edata->header.timestamp = sensor_clock_cycles_to_ns(cycles); + + for (int i = 0; i < num_channels; i++) { + switch (channels[i].chan_type) { + case SENSOR_CHAN_ACCEL_X: + case SENSOR_CHAN_ACCEL_Y: + case SENSOR_CHAN_ACCEL_Z: + case SENSOR_CHAN_ACCEL_XYZ: + edata->has_accel = 1; + + uint8_t xl_addr = lsm6dsvxxx_bus_reg(data->bus_type, data->out_xl); + struct rtio_regs outx_regs; + struct rtio_regs_list xl_regs_list[] = { + { + xl_addr, + (uint8_t *)edata->accel, + 6, + }, + }; + + outx_regs.rtio_regs_list = xl_regs_list; + outx_regs.rtio_regs_num = ARRAY_SIZE(xl_regs_list); + + /* + * Prepare rtio enabled bus to read LSM6DSVXXX_OUTX_L_A register + * where accelerometer data is available. + * Then lsm6dsvxxx_one_shot_complete_cb callback will be invoked. + * + * STMEMSC API equivalent code: + * + * uint8_t accel_raw[6]; + * + * lsm6dsvxxx_acceleration_raw_get(&dev_ctx, accel_raw); + */ + rtio_read_regs_async(data->rtio_ctx, data->iodev, data->bus_type, + &outx_regs, iodev_sqe, dev, + lsm6dsvxxx_one_shot_complete_cb); + break; + +#if defined(CONFIG_LSM6DSVXXX_ENABLE_TEMP) + case SENSOR_CHAN_DIE_TEMP: + edata->has_temp = 1; + + uint8_t t_addr = lsm6dsvxxx_bus_reg(data->bus_type, data->out_tp); + struct rtio_regs outt_regs; + struct rtio_regs_list t_regs_list[] = { + { + t_addr, + (uint8_t *)&edata->temp, + 2, + }, + }; + + outt_regs.rtio_regs_list = t_regs_list; + outt_regs.rtio_regs_num = ARRAY_SIZE(t_regs_list); + + /* + * Prepare rtio enabled bus to read LSM6DSVXX0X_OUT_TEMP_L register + * where temperature data is available. + * Then lsm6dsvxxx_one_shot_complete_cb callback will be invoked. + * + * STMEMSC API equivalent code: + * + * int16_t val; + * + * lsm6dsvxxx_temperature_raw_get(&dev_ctx, &val); + */ + rtio_read_regs_async(data->rtio_ctx, data->iodev, data->bus_type, + &outt_regs, iodev_sqe, dev, + lsm6dsvxxx_one_shot_complete_cb); + break; +#endif + + default: + continue; + } + } + + if (edata->has_accel == 0) { + rtio_iodev_sqe_err(iodev_sqe, -EIO); + } +} + +void lsm6dsvxxx_submit(const struct device *dev, struct rtio_iodev_sqe *iodev_sqe) +{ + const struct sensor_read_config *cfg = iodev_sqe->sqe.iodev->data; + + if (!cfg->is_streaming) { + lsm6dsvxxx_submit_one_shot(dev, iodev_sqe); + } else { + rtio_iodev_sqe_err(iodev_sqe, -ENOTSUP); + } +} + +static DEVICE_API(sensor, lsm6dsvxxx_driver_api) = { + .attr_set = lsm6dsvxxx_attr_set, + .attr_get = lsm6dsvxxx_attr_get, +#ifdef CONFIG_SENSOR_ASYNC_API + .get_decoder = lsm6dsvxxx_get_decoder, + .submit = lsm6dsvxxx_submit, +#endif +}; + +static int lsm6dsvxxx_init(const struct device *dev) +{ + const struct lsm6dsvxxx_config *cfg = dev->config; + struct lsm6dsvxxx_data *data = dev->data; + + LOG_INF("Initialize device %s", dev->name); + data->dev = dev; + + if (cfg->chip_api->init_chip(dev) < 0) { + LOG_DBG("failed to initialize chip"); + return -EIO; + } + +#ifdef CONFIG_LSM6DSVXXX_TRIGGER + if (cfg->trig_enabled && (lsm6dsvxxx_init_interrupt(dev) < 0)) { + LOG_ERR("Failed to initialize interrupt."); + return -EIO; + } +#endif + + return 0; +} + +#if defined(CONFIG_PM_DEVICE) +static int lsm6dsvxxx_pm_action(const struct device *dev, enum pm_device_action action) +{ + const struct lsm6dsvxxx_config *cfg = dev->config; + + return cfg->chip_api->pm_action(dev, action); +} +#endif /* CONFIG_PM_DEVICE */ + +/* + * Device creation macro, shared by LSM6DSVXXX_DEFINE_SPI() and + * LSM6DSVXXX_DEFINE_I2C(). + */ + +/* clang-format off */ + +#define LSM6DSVXXX_DEVICE_INIT(inst, prefix) \ + PM_DEVICE_DT_INST_DEFINE(inst, lsm6dsvxxx_pm_action); \ + SENSOR_DEVICE_DT_INST_DEFINE(inst, lsm6dsvxxx_init, PM_DEVICE_DT_INST_GET(inst), \ + &prefix##_data_##inst, &prefix##_config_##inst, \ + POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY, \ + &lsm6dsvxxx_driver_api); + +#ifdef CONFIG_LSM6DSVXXX_TRIGGER +#define LSM6DSVXXX_CFG_IRQ(inst) \ + .trig_enabled = true, \ + .int1_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, int1_gpios, { 0 }), \ + .int2_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, int2_gpios, { 0 }), \ + .drdy_pulsed = DT_INST_PROP(inst, drdy_pulsed), \ + .drdy_pin = DT_INST_PROP(inst, drdy_pin) +#else +#define LSM6DSVXXX_CFG_IRQ(inst) +#endif /* CONFIG_LSM6DSVXXX_TRIGGER */ + +#define LSM6DSVXXX_CONFIG_COMMON(inst, prefix) \ + .chip_api = &prefix##_chip_api, \ + .accel_odr = DT_INST_PROP(inst, accel_odr), \ + IF_ENABLED(DT_INST_NODE_HAS_PROP(inst, accel_hg_odr), \ + (.accel_hg_odr = DT_INST_PROP(inst, accel_hg_odr),)) \ + .accel_range = DT_INST_ENUM_IDX(inst, accel_range), \ + .gyro_odr = DT_INST_PROP(inst, gyro_odr), \ + .gyro_range = DT_INST_PROP(inst, gyro_range), \ + IF_ENABLED(CONFIG_LSM6DSVXXX_STREAM, \ + (.fifo_wtm = DT_INST_PROP(inst, fifo_watermark), \ + .accel_batch = DT_INST_PROP(inst, accel_fifo_batch_rate), \ + .gyro_batch = DT_INST_PROP(inst, gyro_fifo_batch_rate), \ + .sflp_odr = DT_INST_PROP(inst, sflp_odr), \ + .sflp_fifo_en = DT_INST_PROP(inst, sflp_fifo_enable), \ + .temp_batch = DT_INST_PROP(inst, temp_fifo_batch_rate),)) \ + IF_ENABLED(UTIL_OR(DT_INST_NODE_HAS_PROP(inst, int1_gpios), \ + DT_INST_NODE_HAS_PROP(inst, int2_gpios)), \ + (LSM6DSVXXX_CFG_IRQ(inst))) + +/* + * Instantiation macros used when a device is on a SPI bus. + */ + +#define LSM6DSVXXX_SPI_OP (SPI_WORD_SET(8) | \ + SPI_OP_MODE_MASTER | \ + SPI_MODE_CPOL | \ + SPI_MODE_CPHA) \ + +#define LSM6DSVXXX_SPI_RTIO_DEFINE(inst, prefix) \ + SPI_DT_IODEV_DEFINE(prefix##_iodev_##inst, \ + DT_DRV_INST(inst), LSM6DSVXXX_SPI_OP, 0U); \ + RTIO_DEFINE(prefix##_rtio_ctx_##inst, 8, 8); + +#define LSM6DSVXXX_CONFIG_SPI(inst, prefix) \ + { \ + STMEMSC_CTX_SPI(&prefix##_config_##inst.stmemsc_cfg), \ + .stmemsc_cfg = { \ + .spi = SPI_DT_SPEC_INST_GET(inst, \ + LSM6DSVXXX_SPI_OP, \ + 0), \ + }, \ + LSM6DSVXXX_CONFIG_COMMON(inst, prefix) \ + } + +#define LSM6DSVXXX_DEFINE_SPI(inst, prefix) \ + IF_ENABLED(CONFIG_SPI_RTIO, \ + (LSM6DSVXXX_SPI_RTIO_DEFINE(inst, prefix))); \ + static struct lsm6dsvxxx_data prefix##_data_##inst = { \ + IF_ENABLED(CONFIG_SPI_RTIO, \ + (.rtio_ctx = &prefix##_rtio_ctx_##inst, \ + .iodev = &prefix##_iodev_##inst, \ + .bus_type = RTIO_BUS_SPI,)) \ + }; \ + static const struct lsm6dsvxxx_config prefix##_config_##inst = \ + LSM6DSVXXX_CONFIG_SPI(inst, prefix); + +/* + * Instantiation macros used when a device is on an I2C bus. + */ + +#define LSM6DSVXXX_I2C_RTIO_DEFINE(inst, prefix) \ + I2C_DT_IODEV_DEFINE(prefix##_iodev_##inst, DT_DRV_INST(inst)); \ + RTIO_DEFINE(prefix##_rtio_ctx_##inst, 8, 8); + +#define LSM6DSVXXX_CONFIG_I2C(inst, prefix) \ + { \ + STMEMSC_CTX_I2C(&prefix##_config_##inst.stmemsc_cfg), \ + .stmemsc_cfg = { \ + .i2c = I2C_DT_SPEC_INST_GET(inst), \ + }, \ + LSM6DSVXXX_CONFIG_COMMON(inst, prefix) \ + } + +#define LSM6DSVXXX_DEFINE_I2C(inst, prefix) \ + IF_ENABLED(CONFIG_I2C_RTIO, \ + (LSM6DSVXXX_I2C_RTIO_DEFINE(inst, prefix))); \ + static struct lsm6dsvxxx_data prefix##_data_##inst = { \ + IF_ENABLED(CONFIG_I2C_RTIO, \ + (.rtio_ctx = &prefix##_rtio_ctx_##inst, \ + .iodev = &prefix##_iodev_##inst, \ + .bus_type = RTIO_BUS_I2C,)) \ + }; \ + static const struct lsm6dsvxxx_config prefix##_config_##inst = \ + LSM6DSVXXX_CONFIG_I2C(inst, prefix); + +/* + * Instantiation macros used when a device is on an I3C bus. + */ + +#define LSM6DSVXXX_I3C_RTIO_DEFINE(inst, prefix) \ + I3C_DT_IODEV_DEFINE(prefix##_i3c_iodev_##inst, DT_DRV_INST(inst)); \ + RTIO_DEFINE(prefix##_rtio_ctx_##inst, 8, 8); + +#define LSM6DSVXXX_CONFIG_I3C(inst, prefix) \ + { \ + STMEMSC_CTX_I3C(&prefix##_config_##inst.stmemsc_cfg), \ + .stmemsc_cfg = { \ + .i3c = &prefix##_data_##inst.i3c_dev, \ + }, \ + .i3c.bus = DEVICE_DT_GET(DT_INST_BUS(inst)), \ + .i3c.dev_id = I3C_DEVICE_ID_DT_INST(inst), \ + IF_ENABLED(CONFIG_LSM6DSVXXX_TRIGGER, \ + (.int_en_i3c = DT_INST_PROP(inst, int_en_i3c), \ + .bus_act_sel = DT_INST_ENUM_IDX(inst, bus_act_sel_us),)) \ + LSM6DSVXXX_CONFIG_COMMON(inst, prefix) \ + } + +#define LSM6DSVXXX_DEFINE_I3C(inst, prefix) \ + IF_ENABLED(CONFIG_I3C_RTIO, \ + (LSM6DSVXXX_I3C_RTIO_DEFINE(inst, prefix))); \ + static struct lsm6dsvxxx_data prefix##_data_##inst = { \ + IF_ENABLED(CONFIG_I3C_RTIO, \ + (.rtio_ctx = &prefix##_rtio_ctx_##inst, \ + .iodev = &prefix##_i3c_iodev_##inst, \ + .bus_type = RTIO_BUS_I3C,)) \ + }; \ + static const struct lsm6dsvxxx_config prefix##_config_##inst = \ + LSM6DSVXXX_CONFIG_I3C(inst, prefix); + +#define LSM6DSVXXX_DEFINE_I3C_OR_I2C(inst, prefix) \ + COND_CODE_0(DT_INST_PROP_BY_IDX(inst, reg, 1), \ + (LSM6DSVXXX_DEFINE_I2C(inst, prefix)), \ + (LSM6DSVXXX_DEFINE_I3C(inst, prefix))) + +/* + * Main instantiation macro. Use of COND_CODE_1() selects the right + * bus-specific macro at preprocessor time. + */ + +#define LSM6DSVXXX_DEFINE(inst, prefix) \ + COND_CODE_1(DT_INST_ON_BUS(inst, spi), \ + (LSM6DSVXXX_DEFINE_SPI(inst, prefix)), \ + (COND_CODE_1(DT_INST_ON_BUS(inst, i3c), \ + (LSM6DSVXXX_DEFINE_I3C_OR_I2C(inst, prefix)), \ + (LSM6DSVXXX_DEFINE_I2C(inst, prefix))))); \ + LSM6DSVXXX_DEVICE_INIT(inst, prefix) + +/* clang-format on */ + +#define DT_DRV_COMPAT st_lsm6dsv320x +DT_INST_FOREACH_STATUS_OKAY_VARGS(LSM6DSVXXX_DEFINE, DT_DRV_COMPAT) +#undef DT_DRV_COMPAT diff --git a/drivers/sensor/st/lsm6dsvxxx/lsm6dsvxxx.h b/drivers/sensor/st/lsm6dsvxxx/lsm6dsvxxx.h new file mode 100644 index 000000000000..a4590cd18e73 --- /dev/null +++ b/drivers/sensor/st/lsm6dsvxxx/lsm6dsvxxx.h @@ -0,0 +1,209 @@ +/* ST Microelectronics LSM6DSVXXX family IMU sensor + * + * Copyright (c) 2025 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + * + * Datasheet: + * https://www.st.com/resource/en/datasheet/lsm6dsv320x.pdf + */ + +#ifndef ZEPHYR_DRIVERS_SENSOR_LSM6DSVXXX_LSM6DSVXXX_H_ +#define ZEPHYR_DRIVERS_SENSOR_LSM6DSVXXX_LSM6DSVXXX_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define LSM6DSVXXX_ANY_INST_ON_BUS_STATUS_OKAY(bus) \ + (DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_lsm6dsv320x, bus)) + +#if DT_HAS_COMPAT_STATUS_OKAY(st_lsm6dsv320x) +#include "lsm6dsv320x_reg.h" +#include +#endif + +#if LSM6DSVXXX_ANY_INST_ON_BUS_STATUS_OKAY(spi) +#include +#endif /* LSM6DSVXXX_ANY_INST_ON_BUS_STATUS_OKAY(spi) */ + +#if LSM6DSVXXX_ANY_INST_ON_BUS_STATUS_OKAY(i2c) +#include +#endif /* LSM6DSVXXX_ANY_INST_ON_BUS_STATUS_OKAY(i2c) */ + +#if LSM6DSVXXX_ANY_INST_ON_BUS_STATUS_OKAY(i3c) +#include +#endif /* LSM6DSVXXX_ANY_INST_ON_BUS_STATUS_OKAY(i3c) */ + +#if (LSM6DSVXXX_ANY_INST_ON_BUS_STATUS_OKAY(i3c)) + #define ON_I3C_BUS(cfg) (cfg->i3c.bus != NULL) +#else + #define ON_I3C_BUS(cfg) (false) +#endif + +typedef int32_t (*api_lsm6dsvxxx_init_chip)(const struct device *dev); +#if defined(CONFIG_PM_DEVICE) +typedef int32_t (*api_lsm6dsvxxx_pm_action)(const struct device *dev, enum pm_device_action action); +#endif /* CONFIG_PM_DEVICE */ +typedef int32_t (*api_lsm6dsvxxx_accel_set_fs)(const struct device *dev, int32_t range); +typedef int32_t (*api_lsm6dsvxxx_accel_set_odr)(const struct device *dev, int32_t freq); +typedef int32_t (*api_lsm6dsvxxx_accel_set_mode)(const struct device *dev, int32_t mode); +typedef int32_t (*api_lsm6dsvxxx_accel_get_fs)(const struct device *dev, int32_t *range); +typedef int32_t (*api_lsm6dsvxxx_accel_get_odr)(const struct device *dev, int32_t *freq); +typedef int32_t (*api_lsm6dsvxxx_accel_get_mode)(const struct device *dev, int32_t *mode); +typedef int32_t (*api_lsm6dsvxxx_gyro_set_fs)(const struct device *dev, int32_t range); +typedef int32_t (*api_lsm6dsvxxx_gyro_set_odr)(const struct device *dev, int32_t freq); +typedef int32_t (*api_lsm6dsvxxx_gyro_set_mode)(const struct device *dev, int32_t mode); +typedef int32_t (*api_lsm6dsvxxx_gyro_get_fs)(const struct device *dev, int32_t *range); +typedef int32_t (*api_lsm6dsvxxx_gyro_get_odr)(const struct device *dev, int32_t *freq); +typedef int32_t (*api_lsm6dsvxxx_gyro_get_mode)(const struct device *dev, int32_t *mode); + +struct lsm6dsvxxx_chip_api { + api_lsm6dsvxxx_init_chip init_chip; +#if defined(CONFIG_PM_DEVICE) + api_lsm6dsvxxx_pm_action pm_action; +#endif /* CONFIG_PM_DEVICE */ + api_lsm6dsvxxx_accel_set_fs accel_fs_set; + api_lsm6dsvxxx_accel_set_odr accel_odr_set; + api_lsm6dsvxxx_accel_set_mode accel_mode_set; + api_lsm6dsvxxx_accel_get_fs accel_fs_get; + api_lsm6dsvxxx_accel_get_odr accel_odr_get; + api_lsm6dsvxxx_accel_get_mode accel_mode_get; + api_lsm6dsvxxx_gyro_set_fs gyro_fs_set; + api_lsm6dsvxxx_gyro_set_odr gyro_odr_set; + api_lsm6dsvxxx_gyro_set_mode gyro_mode_set; + api_lsm6dsvxxx_gyro_get_fs gyro_fs_get; + api_lsm6dsvxxx_gyro_get_odr gyro_odr_get; + api_lsm6dsvxxx_gyro_get_mode gyro_mode_get; +}; + +struct lsm6dsvxxx_config { + stmdev_ctx_t ctx; + union { +#if LSM6DSVXXX_ANY_INST_ON_BUS_STATUS_OKAY(i2c) + const struct i2c_dt_spec i2c; +#endif +#if LSM6DSVXXX_ANY_INST_ON_BUS_STATUS_OKAY(spi) + const struct spi_dt_spec spi; +#endif +#if LSM6DSVXXX_ANY_INST_ON_BUS_STATUS_OKAY(i3c) + struct i3c_device_desc **i3c; +#endif + } stmemsc_cfg; + uint8_t accel_pm; + uint8_t accel_odr; + uint8_t accel_hg_odr; + uint8_t accel_range; + uint8_t gyro_pm; + uint8_t gyro_odr; + uint8_t gyro_range; + uint8_t drdy_pulsed; + +#if LSM6DSVXXX_ANY_INST_ON_BUS_STATUS_OKAY(i3c) + struct { + const struct device *bus; + const struct i3c_device_id dev_id; + } i3c; +#endif + const struct lsm6dsvxxx_chip_api *chip_api; +}; + +struct lsm6dsvxxx_ibi_payload { + uint8_t mdb; + uint8_t fifo_status1; + uint8_t fifo_status2; + uint8_t all_int_src; + uint8_t status_reg; + uint8_t status_reg_ois; + uint8_t status_master_main; + uint8_t emb_func_status; + uint8_t fsm_status; + uint8_t mlc_status; +} __packed; + +struct lsm6dsvxxx_data { + const struct device *dev; + int16_t acc[3]; + uint32_t acc_gain; + int16_t gyro[3]; + uint32_t gyro_gain; +#if defined(CONFIG_LSM6DSV16X_ENABLE_TEMP) + int16_t temp_sample; +#endif + + uint8_t accel_freq; + uint8_t accel_fs; + uint8_t gyro_freq; + uint8_t gyro_fs; + uint8_t out_xl; + uint8_t out_tp; + + struct rtio_iodev_sqe *streaming_sqe; + struct rtio *rtio_ctx; + struct rtio_iodev *iodev; + + rtio_bus_type bus_type; /* I2C is 0, SPI is 1, I3C is 2 */ + +#if LSM6DSVXXX_ANY_INST_ON_BUS_STATUS_OKAY(i3c) + struct i3c_device_desc *i3c_dev; + struct lsm6dsvxxx_ibi_payload ibi_payload; +#endif +}; + +static inline uint8_t lsm6dsvxxx_bus_reg(rtio_bus_type bus, uint8_t addr) +{ + return (rtio_is_spi(bus)) ? addr | 0x80 : addr; +} + +int lsm6dsvxxx_spi_init(const struct device *dev); + +/* decoder */ +struct lsm6dsvxxx_decoder_header { + uint64_t timestamp; + uint8_t is_fifo: 1; + uint8_t range: 4; + uint8_t reserved: 3; + uint8_t int_status; +} __attribute__((__packed__)); + +struct lsm6dsvxxx_fifo_data { + struct lsm6dsvxxx_decoder_header header; + uint32_t accel_odr: 4; + uint32_t fifo_mode_sel: 2; + uint32_t fifo_count: 7; + uint32_t reserved_1: 5; + uint32_t accel_batch_odr: 3; + uint32_t ts_batch_odr: 2; + uint32_t reserved: 9; +} __attribute__((__packed__)); + +struct lsm6dsvxxx_rtio_data { + struct lsm6dsvxxx_decoder_header header; + struct { + uint8_t has_accel: 1; /* set if accel channel has data */ + uint8_t has_temp: 1; /* set if temp channel has data */ + uint8_t reserved: 6; + } __attribute__((__packed__)); + int16_t accel[3]; + int16_t temp; +}; + +int lsm6dsvxxx_encode(const struct device *dev, const struct sensor_chan_spec *const channels, + const size_t num_channels, uint8_t *buf); + +int lsm6dsvxxx_get_decoder(const struct device *dev, const struct sensor_decoder_api **decoder); + +void lsm6dsvxxx_rtio_rd_transaction(const struct device *dev, + uint8_t *regs, uint8_t regs_num, + struct spi_buf *buf, + struct rtio_iodev_sqe *iodev_sqe, + rtio_callback_t complete_op_cb); +#endif /* ZEPHYR_DRIVERS_SENSOR_LSM6DSVXXX_LSM6DSVXXX_H_ */ diff --git a/drivers/sensor/st/lsm6dsvxxx/lsm6dsvxxx_decoder.c b/drivers/sensor/st/lsm6dsvxxx/lsm6dsvxxx_decoder.c new file mode 100644 index 000000000000..bde794feadeb --- /dev/null +++ b/drivers/sensor/st/lsm6dsvxxx/lsm6dsvxxx_decoder.c @@ -0,0 +1,215 @@ +/* ST Microelectronics LSM6DSVXXX family IMU sensor + * + * Copyright (c) 2025 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + * + * Datasheet: + * https://www.st.com/resource/en/datasheet/lsm6dsv320x.pdf + */ + +#include "lsm6dsvxxx.h" + +#include +LOG_MODULE_REGISTER(LSM6DSVXXX_DECODER, CONFIG_SENSOR_LOG_LEVEL); + +/* + * Expand val to q31_t according to its range; this is achieved multiplying by 2^31/2^range. + */ +#define Q31_SHIFT_VAL(val, range) \ + (q31_t) (roundf((val) * ((int64_t)1 << (31 - (range))))) + +/* + * Expand micro_val (a generic micro unit) to q31_t according to its range; this is achieved + * multiplying by 2^31/2^range. Then transform it to val. + */ +#define Q31_SHIFT_MICROVAL(micro_val, range) \ + (q31_t) ((int64_t)(micro_val) * ((int64_t)1 << (31 - (range))) / 1000000LL) + +/* bit range for Accelerometer for a given range value */ +static const int8_t accel_range[] = { + 5, /* FS_2G */ + 6, /* FS_4G */ + 7, /* FS_8G */ + 8, /* FS_16G */ + 9, /* FS_32G */ + 10, /* FS_64G */ + 11, /* FS_128G */ + 12, /* FS_256G */ + 13, /* FS_320G */ +}; + +#if defined(CONFIG_LSM6DSVXXX_ENABLE_TEMP) +/* bit range for Temperature sensor */ +static const int8_t temp_range = 9; + +/* transform temperature LSB into micro-Celsius */ +#define SENSOR_TEMP_UCELSIUS(t_lsb) \ + (int64_t) (25000000LL + (((int64_t)(t_lsb) * 1000000LL) / 355LL)) + +#endif + +/* Calculate scaling factor to transform micro-g/LSB unit into micro-ms2/LSB */ +#define SENSOR_SCALE_UG_TO_UMS2(ug_lsb) \ + (int32_t)((ug_lsb) * SENSOR_G / 1000000LL) + +/* + * Accelerometer scaling factors table for a given range value + * GAIN_UNIT_XL is expressed in ug/LSB. + */ +static const int32_t accel_scaler[] = { + SENSOR_SCALE_UG_TO_UMS2(61), /* FS_2G */ + SENSOR_SCALE_UG_TO_UMS2(122), /* FS_4G */ + SENSOR_SCALE_UG_TO_UMS2(244), /* FS_8G */ + SENSOR_SCALE_UG_TO_UMS2(488), /* FS_16G */ + SENSOR_SCALE_UG_TO_UMS2(976), /* FS_32G */ + SENSOR_SCALE_UG_TO_UMS2(1952), /* FS_64G */ + SENSOR_SCALE_UG_TO_UMS2(2904), /* FS_128G */ + SENSOR_SCALE_UG_TO_UMS2(7808), /* FS_256G */ + SENSOR_SCALE_UG_TO_UMS2(10417), /* FS_320G */ +}; + +/* Calculate scaling factor to transform micro-dps/LSB unit into micro-rads/LSB */ +#define SENSOR_SCALE_UDPS_TO_URADS(udps_lsb) \ + (int32_t)(((udps_lsb) * SENSOR_PI / 180LL) / 1000000LL) + +static int lsm6dsvxxx_decoder_get_frame_count(const uint8_t *buffer, + struct sensor_chan_spec chan_spec, + uint16_t *frame_count) +{ + const struct lsm6dsvxxx_fifo_data *data = (const struct lsm6dsvxxx_fifo_data *)buffer; + const struct lsm6dsvxxx_rtio_data *rdata = (const struct lsm6dsvxxx_rtio_data *)buffer; + const struct lsm6dsvxxx_decoder_header *header = &data->header; + + if (chan_spec.chan_idx != 0) { + return -ENOTSUP; + } + + if (!header->is_fifo) { + switch (chan_spec.chan_type) { + case SENSOR_CHAN_ACCEL_X: + case SENSOR_CHAN_ACCEL_Y: + case SENSOR_CHAN_ACCEL_Z: + case SENSOR_CHAN_ACCEL_XYZ: + *frame_count = rdata->has_accel ? 1 : 0; + return 0; + + case SENSOR_CHAN_DIE_TEMP: + *frame_count = rdata->has_temp ? 1 : 0; + return 0; + + default: + *frame_count = 0; + return -ENOTSUP; + } + + return 0; + } + + return 0; +} + +static int lsm6dsvxxx_decode_sample(const uint8_t *buffer, struct sensor_chan_spec chan_spec, + uint32_t *fit, uint16_t max_count, void *data_out) +{ + const struct lsm6dsvxxx_rtio_data *edata = (const struct lsm6dsvxxx_rtio_data *)buffer; + const struct lsm6dsvxxx_decoder_header *header = &edata->header; + + if (*fit != 0) { + return 0; + } + if (max_count == 0 || chan_spec.chan_idx != 0) { + return -EINVAL; + } + + switch (chan_spec.chan_type) { + case SENSOR_CHAN_ACCEL_X: + case SENSOR_CHAN_ACCEL_Y: + case SENSOR_CHAN_ACCEL_Z: + case SENSOR_CHAN_ACCEL_XYZ: { + const int32_t scale = accel_scaler[header->range]; + + if (edata->has_accel == 0) { + return -ENODATA; + } + + struct sensor_three_axis_data *out = data_out; + + out->header.base_timestamp_ns = edata->header.timestamp; + out->header.reading_count = 1; + + out->shift = accel_range[header->range]; + + out->readings[0].x = Q31_SHIFT_MICROVAL(scale * edata->accel[0], out->shift); + out->readings[0].y = Q31_SHIFT_MICROVAL(scale * edata->accel[1], out->shift); + out->readings[0].z = Q31_SHIFT_MICROVAL(scale * edata->accel[2], out->shift); + *fit = 1; + return 1; + } +#if defined(CONFIG_LSM6DSVXXX_ENABLE_TEMP) + case SENSOR_CHAN_DIE_TEMP: { + int64_t t_uC; + + if (edata->has_temp == 0) { + return -ENODATA; + } + + struct sensor_q31_data *out = data_out; + + out->header.base_timestamp_ns = edata->header.timestamp; + out->header.reading_count = 1; + + out->shift = temp_range; + + /* transform temperature LSB into micro-Celsius */ + t_uC = SENSOR_TEMP_UCELSIUS(edata->temp); + + out->readings[0].temperature = Q31_SHIFT_MICROVAL(t_uC, out->shift); + *fit = 1; + return 1; + } +#endif + default: + return -EINVAL; + } +} + +static int lsm6dsvxxx_decoder_decode(const uint8_t *buffer, struct sensor_chan_spec chan_spec, + uint32_t *fit, uint16_t max_count, void *data_out) +{ + return lsm6dsvxxx_decode_sample(buffer, chan_spec, fit, max_count, data_out); +} + +static int lsm6dsvxxx_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_ACCEL_X: + case SENSOR_CHAN_ACCEL_Y: + case SENSOR_CHAN_ACCEL_Z: + case SENSOR_CHAN_ACCEL_XYZ: + *base_size = sizeof(struct sensor_three_axis_data); + *frame_size = sizeof(struct sensor_three_axis_sample_data); + return 0; + case SENSOR_CHAN_DIE_TEMP: + *base_size = sizeof(struct sensor_q31_data); + *frame_size = sizeof(struct sensor_q31_sample_data); + return 0; + default: + return -ENOTSUP; + } +} + +SENSOR_DECODER_API_DT_DEFINE() = { + .get_frame_count = lsm6dsvxxx_decoder_get_frame_count, + .get_size_info = lsm6dsvxxx_decoder_get_size_info, + .decode = lsm6dsvxxx_decoder_decode, +}; + +int lsm6dsvxxx_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/st/lsm6dsvxxx/lsm6dsvxxx_rtio.h b/drivers/sensor/st/lsm6dsvxxx/lsm6dsvxxx_rtio.h new file mode 100644 index 000000000000..14596a7e8c9f --- /dev/null +++ b/drivers/sensor/st/lsm6dsvxxx/lsm6dsvxxx_rtio.h @@ -0,0 +1,22 @@ +/* ST Microelectronics LSM6DSVXXX family IMU sensor + * + * Copyright (c) 2025 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + * + * Datasheet: + * https://www.st.com/resource/en/datasheet/lsm6dsv320x.pdf + */ + +#ifndef ZEPHYR_DRIVERS_SENSOR_LSM6DSVXXX_RTIO_H_ +#define ZEPHYR_DRIVERS_SENSOR_LSM6DSVXXX_RTIO_H_ + +#include +#include +#include + +void lsm6dsvxxx_submit(const struct device *sensor, struct rtio_iodev_sqe *iodev_sqe); +void lsm6dsvxxx_submit_stream(const struct device *sensor, struct rtio_iodev_sqe *iodev_sqe); +void lsm6dsvxxx_stream_irq_handler(const struct device *dev); + +#endif /* ZEPHYR_DRIVERS_SENSOR_LSM6DSVXXX_RTIO_H_ */ diff --git a/dts/bindings/sensor/st,lsm6dsv320x-common.yaml b/dts/bindings/sensor/st,lsm6dsv320x-common.yaml new file mode 100644 index 000000000000..ad22c8999812 --- /dev/null +++ b/dts/bindings/sensor/st,lsm6dsv320x-common.yaml @@ -0,0 +1,76 @@ +# Copyright (c) 2025 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +description: | + When setting the accel-range, accel-odr, gyro-range, gyro-odr properties in + a .dts or .dtsi file you may include lsm6dsv320x.h and use the macros + defined there. + + Example: + #include + + lsm6dsv320x: lsm6dsv320x@0 { + ... + + accel-range = ; + accel-odr = ; + gyro-range = ; + gyro-odr = ; + }; + +include: st,lsm6dsvxxx-common.yaml + +properties: + accel-hg-odr: + type: int + default: 0x0 + description: | + Specify the default accelerometer High-g output data rate expressed in samples per + second (Hz). + The values are taken in accordance to lsm6dsv320x_hg_xl_data_rate_t enumerative in hal/st + module. Please note that this values will not change the operating mode, which will remain + High Performance (device default) + Default is power-up configuration. + + - 0x0 # LSM6DSV320X_HG_XL_ODR_OFF + - 0x3 # LSM6DSV320X_HG_XL_ODR_AT_480Hz + - 0x4 # LSM6DSV320X_HG_XL_ODR_AT_960Hz + - 0x5 # LSM6DSV320X_HG_XL_ODR_AT_1920Hz + - 0x6 # LSM6DSV320X_HG_XL_ODR_AT_3840Hz + - 0x7 # LSM6DSV320X_HG_XL_ODR_AT_7680Hz + + enum: [0x0, 0x3, 0x4, 0x5, 0x6, 0x7] + + accel-range: + type: int + default: 2 + description: | + Range in g. Default is power-up configuration. + Ranges from 32g and above requires the High-g sensor to be turned on (see accel-hg-odr). + + - 2 # LSM6DSV320X_DT_FS_2G (0.061 mg/LSB) + - 4 # LSM6DSV320X_DT_FS_4G (0.122 mg/LSB) + - 8 # LSM6DSV320X_DT_FS_8G (0.244 mg/LSB) + - 16 # LSM6DSV320X_DT_FS_16G (0.488 mg/LSB) + - 32 # LSM6DSV320X_DT_FS_32G (0.976 mg/LSB) + - 64 # LSM6DSV320X_DT_FS_64G (1.952 mg/LSB) + - 128 # LSM6DSV320X_DT_FS_128G (3.904 mg/LSB) + - 256 # LSM6DSV320X_DT_FS_256G (7.808 mg/LSB) + - 320 # LSM6DSV320X_DT_FS_320G (10.417 mg/LSB) + + enum: [2, 4, 8, 16, 32, 64, 128, 256, 320] + + gyro-range: + type: int + default: 0 + description: | + Range in dps. Default is power-up configuration. + + - 0x0 # power-up configuration + - 0x1 # LSM6DSV320X_DT_FS_250DPS (8.75 mdps/LSB) + - 0x2 # LSM6DSV320X_DT_FS_500DPS (17.50 mdps/LSB) + - 0x3 # LSM6DSV320X_DT_FS_1000DPS (35 mdps/LSB) + - 0x4 # LSM6DSV320X_DT_FS_2000DPS (70 mdps/LSB) + - 0x5 # LSM6DSV320X_DT_FS_4000DPS (140 mdps/LSB) + + enum: [0x0, 0x1, 0x2, 0x3, 0x4, 0x5] diff --git a/dts/bindings/sensor/st,lsm6dsv320x-i2c.yaml b/dts/bindings/sensor/st,lsm6dsv320x-i2c.yaml new file mode 100644 index 000000000000..9c01599e8210 --- /dev/null +++ b/dts/bindings/sensor/st,lsm6dsv320x-i2c.yaml @@ -0,0 +1,10 @@ +# Copyright (c) 2025 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +description: | + STMicroelectronics LSM6DSV320X 6-axis IMU (Inertial Measurement Unit) sensor + accessed through I2C bus + +compatible: "st,lsm6dsv320x" + +include: ["i2c-device.yaml", "st,lsm6dsv320x-common.yaml"] diff --git a/dts/bindings/sensor/st,lsm6dsv320x-i3c.yaml b/dts/bindings/sensor/st,lsm6dsv320x-i3c.yaml new file mode 100644 index 000000000000..07f9320fd905 --- /dev/null +++ b/dts/bindings/sensor/st,lsm6dsv320x-i3c.yaml @@ -0,0 +1,24 @@ +# Copyright (c) 2025 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +description: | + STMicroelectronics LSM6DSV320X 6-axis IMU (Inertial Measurement Unit) sensor + accessed through I3C bus + +compatible: "st,lsm6dsv320x" + +include: ["i3c-device.yaml", "st,lsm6dsv320x-common.yaml"] + +properties: + int-en-i3c: + type: boolean + description: | + Enables INT pin when I3C is enabled + + bus-act-sel-us: + type: int + default: 50 + description: | + Bus available time for I3C IBI in microseconds + + enum: [50, 2, 1000, 25000] diff --git a/dts/bindings/sensor/st,lsm6dsv320x-spi.yaml b/dts/bindings/sensor/st,lsm6dsv320x-spi.yaml new file mode 100644 index 000000000000..8a3a9230a3c8 --- /dev/null +++ b/dts/bindings/sensor/st,lsm6dsv320x-spi.yaml @@ -0,0 +1,10 @@ +# Copyright (c) 2025 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +description: | + STMicroelectronics LSM6DSV320X 6-axis IMU (Inertial Measurement Unit) sensor + accessed through SPI bus + +compatible: "st,lsm6dsv320x" + +include: ["spi-device.yaml", "st,lsm6dsv320x-common.yaml"] diff --git a/include/zephyr/dt-bindings/sensor/lsm6dsv320x.h b/include/zephyr/dt-bindings/sensor/lsm6dsv320x.h new file mode 100644 index 000000000000..720b623958d6 --- /dev/null +++ b/include/zephyr/dt-bindings/sensor/lsm6dsv320x.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2025 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_ST_LSM6DSV320X_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_ST_LSM6DSV320X_H_ + +#include "lsm6dsvxxx.h" + +/* Accel High-g odr */ +#define LSM6DSV320X_HG_XL_ODR_OFF 0x0 +#define LSM6DSV320X_HG_XL_ODR_AT_480Hz 0x3 +#define LSM6DSV320X_HG_XL_ODR_AT_960Hz 0x4 +#define LSM6DSV320X_HG_XL_ODR_AT_1920Hz 0x5 +#define LSM6DSV320X_HG_XL_ODR_AT_3840Hz 0x6 +#define LSM6DSV320X_HG_XL_ODR_AT_7680Hz 0x7 + +/* Accel range */ +#define LSM6DSV320X_DT_FS_2G 2 +#define LSM6DSV320X_DT_FS_4G 4 +#define LSM6DSV320X_DT_FS_8G 8 +#define LSM6DSV320X_DT_FS_16G 16 +#define LSM6DSV320X_DT_FS_32G 32 +#define LSM6DSV320X_DT_FS_64G 64 +#define LSM6DSV320X_DT_FS_128G 128 +#define LSM6DSV320X_DT_FS_256G 256 +#define LSM6DSV320X_DT_FS_320G 320 + +/* Gyro range */ +#define LSM6DSV320X_DT_FS_250DPS 0x1 +#define LSM6DSV320X_DT_FS_500DPS 0x2 +#define LSM6DSV320X_DT_FS_1000DPS 0x3 +#define LSM6DSV320X_DT_FS_2000DPS 0x4 +#define LSM6DSV320X_DT_FS_4000DPS 0x5 + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_ST_LSM6DSV320X_H_ */ diff --git a/modules/hal_st/Kconfig b/modules/hal_st/Kconfig index eec37ff95247..6d32938ba587 100644 --- a/modules/hal_st/Kconfig +++ b/modules/hal_st/Kconfig @@ -192,6 +192,9 @@ config USE_STDC_LSM6DSRX config USE_STDC_LSM6DSV16X bool +config USE_STDC_LSM6DSV320X + bool + config USE_STDC_LSM9DS1 bool diff --git a/tests/drivers/build_all/sensor/i2c.dtsi b/tests/drivers/build_all/sensor/i2c.dtsi index c8f108c29254..b7eaa9bf7250 100644 --- a/tests/drivers/build_all/sensor/i2c.dtsi +++ b/tests/drivers/build_all/sensor/i2c.dtsi @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -1489,3 +1490,14 @@ test_i2c_max30210: max30210@c5 { reg = <0xc5>; interrupt-gpios = <&test_gpio 0 0>; }; + +test_i2c_lsm6dsv320x: lsm6dsv320x@c6 { + compatible = "st,lsm6dsv320x"; + reg = <0xc6>; + int1-gpios = <&test_gpio 0 0>; + int2-gpios = <&test_gpio 0 0>; + accel-range = ; + accel-odr = ; + gyro-range = ; + gyro-odr = ; +}; From 3c16d599b1b892938a7319ac45c2000ba5ba5223 Mon Sep 17 00:00:00 2001 From: Armando Visconti Date: Thu, 5 Jun 2025 18:37:33 +0200 Subject: [PATCH 1531/3659] drivers/sensor: lsm6dsvxxx: add streaming capabality Add read_and_decode streaming APIs support. Triggers supported: - SENSOR_TRIG_FIFO_WATERMARK - SENSOR_TRIG_FIFO_FULL - SENSOR_TRIG_DATA_READY Signed-off-by: Armando Visconti --- drivers/sensor/st/lsm6dsvxxx/CMakeLists.txt | 5 +- drivers/sensor/st/lsm6dsvxxx/Kconfig | 12 + drivers/sensor/st/lsm6dsvxxx/lsm6dsv320x.c | 249 ++++++- drivers/sensor/st/lsm6dsvxxx/lsm6dsv320x.h | 2 + drivers/sensor/st/lsm6dsvxxx/lsm6dsvxxx.c | 16 +- drivers/sensor/st/lsm6dsvxxx/lsm6dsvxxx.h | 115 +++- .../sensor/st/lsm6dsvxxx/lsm6dsvxxx_decoder.c | 557 +++++++++++++++- .../sensor/st/lsm6dsvxxx/lsm6dsvxxx_rtio.h | 5 + .../sensor/st/lsm6dsvxxx/lsm6dsvxxx_stream.c | 628 ++++++++++++++++++ .../sensor/st/lsm6dsvxxx/lsm6dsvxxx_trigger.c | 72 ++ .../zephyr/dt-bindings/sensor/lsm6dsvxxx.h | 41 ++ 11 files changed, 1626 insertions(+), 76 deletions(-) create mode 100644 drivers/sensor/st/lsm6dsvxxx/lsm6dsvxxx_stream.c create mode 100644 drivers/sensor/st/lsm6dsvxxx/lsm6dsvxxx_trigger.c diff --git a/drivers/sensor/st/lsm6dsvxxx/CMakeLists.txt b/drivers/sensor/st/lsm6dsvxxx/CMakeLists.txt index 5734502cf778..8904293e74d7 100644 --- a/drivers/sensor/st/lsm6dsvxxx/CMakeLists.txt +++ b/drivers/sensor/st/lsm6dsvxxx/CMakeLists.txt @@ -7,7 +7,10 @@ zephyr_library() zephyr_library_sources(lsm6dsvxxx.c) -zephyr_library_sources_ifdef(CONFIG_DT_HAS_ST_LSM6DSV320X_ENABLED lsm6dsv320x.c) zephyr_library_sources_ifdef(CONFIG_SENSOR_ASYNC_API lsm6dsvxxx_decoder.c) +zephyr_library_sources_ifdef(CONFIG_LSM6DSVXXX_STREAM lsm6dsvxxx_stream.c) +zephyr_library_sources_ifdef(CONFIG_LSM6DSVXXX_TRIGGER lsm6dsvxxx_trigger.c) + +zephyr_library_sources_ifdef(CONFIG_DT_HAS_ST_LSM6DSV320X_ENABLED lsm6dsv320x.c) zephyr_library_include_directories(../stmemsc) diff --git a/drivers/sensor/st/lsm6dsvxxx/Kconfig b/drivers/sensor/st/lsm6dsvxxx/Kconfig index 17931fe1a4bf..c1074291de3c 100644 --- a/drivers/sensor/st/lsm6dsvxxx/Kconfig +++ b/drivers/sensor/st/lsm6dsvxxx/Kconfig @@ -18,6 +18,18 @@ menuconfig LSM6DSVXXX if LSM6DSVXXX +config LSM6DSVXXX_STREAM + bool "LSM6DSVXXX data streaming" + select LSM6DSVXXX_TRIGGER + default y + depends on SPI_RTIO || I2C_RTIO || I3C_RTIO + depends on SENSOR_ASYNC_API + help + Use this config option to enable streaming sensor data via RTIO subsystem. + +config LSM6DSVXXX_TRIGGER + bool + config LSM6DSVXXX_ENABLE_TEMP bool "Temperature" help diff --git a/drivers/sensor/st/lsm6dsvxxx/lsm6dsv320x.c b/drivers/sensor/st/lsm6dsvxxx/lsm6dsv320x.c index 8648df54a4b6..33f22806e972 100644 --- a/drivers/sensor/st/lsm6dsvxxx/lsm6dsv320x.c +++ b/drivers/sensor/st/lsm6dsvxxx/lsm6dsv320x.c @@ -13,6 +13,16 @@ LOG_MODULE_DECLARE(LSM6DSVXXX, CONFIG_SENSOR_LOG_LEVEL); +static bool lsm6dsv320x_is_std_fs(uint8_t fs) +{ + return (fs < 4); /* 2g/4g/8g/16g */ +} + +static bool lsm6dsv320x_is_hg_fs(uint8_t fs) +{ + return (fs >= 4 && fs <= 8); /* 32g/64g/128g/256g/320g */ +} + /* * XL configuration */ @@ -28,9 +38,7 @@ static uint16_t lsm6dsv320x_accel_gain_ug(uint8_t fs) } /* The first nibble of fs tells if it is High-G or not */ -static int lsm6dsv320x_accel_range_to_fs_val(const struct device *dev, - int32_t range, - uint8_t *fs) +static int lsm6dsv320x_accel_range_to_fs_val(const struct device *dev, int32_t range, uint8_t *fs) { switch (range) { case LSM6DSV320X_DT_FS_2G: @@ -82,7 +90,7 @@ static int lsm6dsv320x_accel_set_fs_raw(const struct device *dev, uint8_t fs) stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; struct lsm6dsvxxx_data *data = dev->data; - if (fs < 4) { /* 2g/4g/8g/16g */ + if (lsm6dsv320x_is_std_fs(fs)) { /* 2g/4g/8g/16g */ lsm6dsv320x_xl_full_scale_t val = fs; if (lsm6dsv320x_xl_full_scale_set(ctx, val) < 0) { @@ -90,7 +98,7 @@ static int lsm6dsv320x_accel_set_fs_raw(const struct device *dev, uint8_t fs) } data->out_xl = LSM6DSV320X_OUTX_L_A; - } else if (fs <= 8) { /* 32g/64g/128g/256g/320g */ + } else if (lsm6dsv320x_is_hg_fs(fs)) { /* 32g/64g/128g/256g/320g */ lsm6dsv320x_hg_xl_full_scale_t val = (fs - 4); if (lsm6dsv320x_hg_xl_full_scale_set(ctx, val) < 0) { @@ -153,21 +161,18 @@ static int lsm6dsv320x_accel_set_odr_raw(const struct device *dev, uint8_t odr) * should be selected through accel-odr property in DT */ static const float lsm6dsv320x_odr_map[3][13] = { - /* High Accuracy off */ - {0.0f, 1.875f, 7.5f, 15.0f, 30.0f, 60.0f, - 120.0f, 240.0f, 480.0f, 960.0f, 1920.0f, - 3840.0f, 7680.0f}, - - /* High Accuracy 1 */ - {0.0f, 1.875f, 7.5f, 15.625f, 31.25f, 62.5f, - 125.0f, 250.0f, 500.0f, 1000.0f, 2000.0f, - 4000.0f, 8000.0f}, - - /* High Accuracy 2 */ - {0.0f, 1.875f, 7.5f, 12.5f, 25.0f, 50.0f, - 100.0f, 200.0f, 400.0f, 800.0f, 1600.0f, - 3200.0f, 6400.0f}, - }; + /* High Accuracy off */ + {0.0f, 1.875f, 7.5f, 15.0f, 30.0f, 60.0f, 120.0f, 240.0f, 480.0f, 960.0f, 1920.0f, 3840.0f, + 7680.0f}, + + /* High Accuracy 1 */ + {0.0f, 1.875f, 7.5f, 15.625f, 31.25f, 62.5f, 125.0f, 250.0f, 500.0f, 1000.0f, 2000.0f, + 4000.0f, 8000.0f}, + + /* High Accuracy 2 */ + {0.0f, 1.875f, 7.5f, 12.5f, 25.0f, 50.0f, 100.0f, 200.0f, 400.0f, 800.0f, 1600.0f, 3200.0f, + 6400.0f}, +}; static uint8_t lsm6dsv320x_freq_to_odr_val(const struct device *dev, int32_t freq) { @@ -295,9 +300,7 @@ static int32_t lsm6dsv320x_accel_get_mode(const struct device *dev, int32_t *mod * GY configuration */ -static int lsm6dsv320x_gyro_range_to_fs_val(const struct device *dev, - int32_t range, - uint8_t *fs) +static int lsm6dsv320x_gyro_range_to_fs_val(const struct device *dev, int32_t range, uint8_t *fs) { switch (range) { case 0: @@ -467,6 +470,24 @@ static int32_t lsm6dsv320x_gyro_get_mode(const struct device *dev, int32_t *mode return 0; } +#if defined(CONFIG_LSM6DSVXXX_TRIGGER) +int32_t lsm6dsv320x_drdy_mode_set(const struct device *dev) +{ + const struct lsm6dsvxxx_config *config = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&config->ctx; + + /* enable drdy on int1/int2 in pulse mode */ + lsm6dsv320x_data_ready_mode_t drdy = + (config->drdy_pulsed) ? LSM6DSV320X_DRDY_PULSED : LSM6DSV320X_DRDY_LATCHED; + if (lsm6dsv320x_data_ready_mode_set(ctx, drdy)) { + return -EIO; + } + + return 0; +} +#endif /* CONFIG_LSM6DSVXXX_TRIGGER */ + +/* init routine */ static int lsm6dsv320x_init_chip(const struct device *dev) { const struct lsm6dsvxxx_config *cfg = dev->config; @@ -628,8 +649,155 @@ static int lsm6dsv320x_pm_action(const struct device *dev, enum pm_device_action } #endif /* CONFIG_PM_DEVICE */ +#if defined(CONFIG_LSM6DSVXXX_STREAM) +static void lsm6dsv320x_config_fifo(const struct device *dev, struct trigger_config trig_cfg) +{ + struct lsm6dsvxxx_data *data = dev->data; + const struct lsm6dsvxxx_config *config = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&config->ctx; + uint8_t fifo_wtm = 0; + lsm6dsv320x_pin_int_route_t pin_int = {0}; + lsm6dsv320x_fifo_xl_batch_t xl_batch = LSM6DSVXXX_DT_XL_NOT_BATCHED; + lsm6dsv320x_fifo_gy_batch_t gy_batch = LSM6DSVXXX_DT_GY_NOT_BATCHED; + lsm6dsv320x_fifo_temp_batch_t temp_batch = LSM6DSVXXX_DT_TEMP_NOT_BATCHED; + lsm6dsv320x_fifo_mode_t fifo_mode = LSM6DSV320X_BYPASS_MODE; + lsm6dsv320x_sflp_data_rate_t sflp_odr = LSM6DSV320X_SFLP_120Hz; + lsm6dsv320x_fifo_sflp_raw_t sflp_fifo = {0}; + lsm6dsv320x_sflp_gbias_t gbias; + + /* disable FIFO as first thing */ + lsm6dsv320x_fifo_mode_set(ctx, LSM6DSV320X_BYPASS_MODE); + + pin_int.fifo_th = PROPERTY_DISABLE; + pin_int.fifo_full = PROPERTY_DISABLE; + + if (trig_cfg.int_fifo_th || trig_cfg.int_fifo_full) { + pin_int.fifo_th = (trig_cfg.int_fifo_th) ? PROPERTY_ENABLE : PROPERTY_DISABLE; + pin_int.fifo_full = (trig_cfg.int_fifo_full) ? PROPERTY_ENABLE : PROPERTY_DISABLE; + + xl_batch = config->accel_batch; + gy_batch = config->gyro_batch; + temp_batch = config->temp_batch; + + fifo_mode = LSM6DSV320X_STREAM_MODE; + fifo_wtm = config->fifo_wtm; + + if (config->sflp_fifo_en & LSM6DSVXXX_DT_SFLP_FIFO_GAME_ROTATION) { + sflp_fifo.game_rotation = 1; + } + + if (config->sflp_fifo_en & LSM6DSVXXX_DT_SFLP_FIFO_GRAVITY) { + sflp_fifo.gravity = 1; + } + + if (config->sflp_fifo_en & LSM6DSVXXX_DT_SFLP_FIFO_GBIAS) { + sflp_fifo.gbias = 1; + } + + sflp_odr = config->sflp_odr; + } + + /* + * Set FIFO watermark (number of unread sensor data TAG + 6 bytes + * stored in FIFO) to FIFO_WATERMARK samples + */ + lsm6dsv320x_fifo_watermark_set(ctx, config->fifo_wtm); + + /* Turn on/off FIFO */ + lsm6dsv320x_fifo_mode_set(ctx, fifo_mode); + + /* Set FIFO batch rates */ + lsm6dsv320x_fifo_xl_batch_set(ctx, xl_batch); + data->accel_batch_odr = xl_batch; + lsm6dsv320x_fifo_gy_batch_set(ctx, gy_batch); + data->gyro_batch_odr = gy_batch; +#if defined(CONFIG_LSM6DSVXXX_ENABLE_TEMP) + lsm6dsv320x_fifo_temp_batch_set(ctx, temp_batch); + data->temp_batch_odr = temp_batch; +#endif + + lsm6dsv320x_sflp_data_rate_set(ctx, sflp_odr); + data->sflp_batch_odr = sflp_odr; + lsm6dsv320x_fifo_sflp_batch_set(ctx, sflp_fifo); + lsm6dsv320x_sflp_game_rotation_set(ctx, PROPERTY_ENABLE); + + /* + * Temporarly set Accel and gyro odr same as sensor fusion LP in order to + * make the SFLP gbias setting effective. Then restore it to saved values. + */ + switch (sflp_odr) { + case LSM6DSVXXX_DT_SFLP_ODR_AT_480Hz: + lsm6dsv320x_accel_set_odr_raw(dev, LSM6DSVXXX_DT_ODR_AT_480Hz); + lsm6dsv320x_gyro_set_odr_raw(dev, LSM6DSVXXX_DT_ODR_AT_480Hz); + break; + + case LSM6DSVXXX_DT_SFLP_ODR_AT_240Hz: + lsm6dsv320x_accel_set_odr_raw(dev, LSM6DSVXXX_DT_ODR_AT_240Hz); + lsm6dsv320x_gyro_set_odr_raw(dev, LSM6DSVXXX_DT_ODR_AT_240Hz); + break; + + case LSM6DSVXXX_DT_SFLP_ODR_AT_120Hz: + lsm6dsv320x_accel_set_odr_raw(dev, LSM6DSVXXX_DT_ODR_AT_120Hz); + lsm6dsv320x_gyro_set_odr_raw(dev, LSM6DSVXXX_DT_ODR_AT_120Hz); + break; + + case LSM6DSVXXX_DT_SFLP_ODR_AT_60Hz: + lsm6dsv320x_accel_set_odr_raw(dev, LSM6DSVXXX_DT_ODR_AT_60Hz); + lsm6dsv320x_gyro_set_odr_raw(dev, LSM6DSVXXX_DT_ODR_AT_60Hz); + break; + + case LSM6DSVXXX_DT_SFLP_ODR_AT_30Hz: + lsm6dsv320x_accel_set_odr_raw(dev, LSM6DSVXXX_DT_ODR_AT_30Hz); + lsm6dsv320x_gyro_set_odr_raw(dev, LSM6DSVXXX_DT_ODR_AT_30Hz); + break; + + case LSM6DSVXXX_DT_SFLP_ODR_AT_15Hz: + default: + lsm6dsv320x_accel_set_odr_raw(dev, LSM6DSVXXX_DT_ODR_AT_15Hz); + lsm6dsv320x_gyro_set_odr_raw(dev, LSM6DSVXXX_DT_ODR_AT_15Hz); + break; + } + + /* set sflp gbias */ + gbias.gbias_x = (float)data->gbias_x_udps / 1000000; + gbias.gbias_y = (float)data->gbias_y_udps / 1000000; + gbias.gbias_z = (float)data->gbias_z_udps / 1000000; + lsm6dsv320x_sflp_game_gbias_set(ctx, &gbias); + + /* restore accel/gyro odr to saved values */ + lsm6dsv320x_accel_set_odr_raw(dev, data->accel_freq); + lsm6dsv320x_gyro_set_odr_raw(dev, data->gyro_freq); + + /* Set pin interrupt (fifo_th could be on or off) */ + if ((config->drdy_pin == 1) || (ON_I3C_BUS(config) && (!I3C_INT_PIN(config)))) { + lsm6dsv320x_pin_int1_route_set(ctx, &pin_int); + } else { + lsm6dsv320x_pin_int2_route_set(ctx, &pin_int); + } +} + +static void lsm6dsv320x_config_drdy(const struct device *dev, struct trigger_config trig_cfg) +{ + const struct lsm6dsvxxx_config *config = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&config->ctx; + lsm6dsv320x_pin_int_route_t pin_int = {0}; + + pin_int.drdy_xl = (trig_cfg.int_drdy) ? PROPERTY_ENABLE : PROPERTY_DISABLE; + + /* Set pin interrupt (fifo_th could be on or off) */ + if ((config->drdy_pin == 1) || (ON_I3C_BUS(config) && (!I3C_INT_PIN(config)))) { + lsm6dsv320x_pin_int1_route_set(ctx, &pin_int); + } else { + lsm6dsv320x_pin_int2_route_set(ctx, &pin_int); + } +} +#endif /* CONFIG_LSM6DSVXXX_STREAM */ + const struct lsm6dsvxxx_chip_api st_lsm6dsv320x_chip_api = { .init_chip = lsm6dsv320x_init_chip, +#if defined(CONFIG_LSM6DSVXXX_TRIGGER) + .drdy_mode_set = lsm6dsv320x_drdy_mode_set, +#endif /* CONFIG_LSM6DSVXXX_TRIGGER */ #if defined(CONFIG_PM_DEVICE) .pm_action = lsm6dsv320x_pm_action, #endif /* CONFIG_PM_DEVICE */ @@ -645,4 +813,39 @@ const struct lsm6dsvxxx_chip_api st_lsm6dsv320x_chip_api = { .gyro_fs_get = lsm6dsv320x_gyro_get_fs, .gyro_odr_get = lsm6dsv320x_gyro_get_odr, .gyro_mode_get = lsm6dsv320x_gyro_get_mode, +#if defined(CONFIG_LSM6DSVXXX_STREAM) + .config_fifo = lsm6dsv320x_config_fifo, + .config_drdy = lsm6dsv320x_config_drdy, + .from_f16_to_f32 = lsm6dsv320x_from_f16_to_f32, + .from_sflp_to_mg = lsm6dsv320x_from_sflp_to_mg, +#endif /* CONFIG_LSM6DSVXXX_STREAM */ +}; + +/* bit shift for Accelerometer for a given range value */ +const int8_t st_lsm6dsv320x_accel_bit_shift[] = { + 5, /* FS_2G */ + 6, /* FS_4G */ + 7, /* FS_8G */ + 8, /* FS_16G */ + 9, /* FS_32G */ + 10, /* FS_64G */ + 11, /* FS_128G */ + 12, /* FS_256G */ + 13, /* FS_320G */ +}; + +/* + * Accelerometer scaling factors table for a given range value + * GAIN_UNIT_XL is expressed in ug/LSB. + */ +const int32_t st_lsm6dsv320x_accel_scaler[] = { + SENSOR_SCALE_UG_TO_UMS2(61), /* FS_2G */ + SENSOR_SCALE_UG_TO_UMS2(122), /* FS_4G */ + SENSOR_SCALE_UG_TO_UMS2(244), /* FS_8G */ + SENSOR_SCALE_UG_TO_UMS2(488), /* FS_16G */ + SENSOR_SCALE_UG_TO_UMS2(976), /* FS_32G */ + SENSOR_SCALE_UG_TO_UMS2(1952), /* FS_64G */ + SENSOR_SCALE_UG_TO_UMS2(2904), /* FS_128G */ + SENSOR_SCALE_UG_TO_UMS2(7808), /* FS_256G */ + SENSOR_SCALE_UG_TO_UMS2(10417), /* FS_320G */ }; diff --git a/drivers/sensor/st/lsm6dsvxxx/lsm6dsv320x.h b/drivers/sensor/st/lsm6dsvxxx/lsm6dsv320x.h index 2959bda8ddc2..eca48fce5af9 100644 --- a/drivers/sensor/st/lsm6dsvxxx/lsm6dsv320x.h +++ b/drivers/sensor/st/lsm6dsvxxx/lsm6dsv320x.h @@ -19,5 +19,7 @@ #include extern const struct lsm6dsvxxx_chip_api st_lsm6dsv320x_chip_api; +extern const int8_t st_lsm6dsv320x_accel_bit_shift[]; +extern const int32_t st_lsm6dsv320x_accel_scaler[]; #endif /* ZEPHYR_DRIVERS_SENSOR_LSM6DSV320X_H_ */ diff --git a/drivers/sensor/st/lsm6dsvxxx/lsm6dsvxxx.c b/drivers/sensor/st/lsm6dsvxxx/lsm6dsvxxx.c index 880eb9f7d02c..677e44e4adc0 100644 --- a/drivers/sensor/st/lsm6dsvxxx/lsm6dsvxxx.c +++ b/drivers/sensor/st/lsm6dsvxxx/lsm6dsvxxx.c @@ -166,6 +166,7 @@ static void lsm6dsvxxx_one_shot_complete_cb(struct rtio *ctx, const struct rtio_ static void lsm6dsvxxx_submit_one_shot(const struct device *dev, struct rtio_iodev_sqe *iodev_sqe) { + const struct lsm6dsvxxx_config *config = dev->config; 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; @@ -196,8 +197,9 @@ static void lsm6dsvxxx_submit_one_shot(const struct device *dev, struct rtio_iod return; } + edata->header.cfg = config; edata->header.is_fifo = false; - edata->header.range = data->accel_fs; + edata->header.accel_fs = data->accel_fs; edata->header.timestamp = sensor_clock_cycles_to_ns(cycles); for (int i = 0; i < num_channels; i++) { @@ -287,6 +289,8 @@ void lsm6dsvxxx_submit(const struct device *dev, struct rtio_iodev_sqe *iodev_sq if (!cfg->is_streaming) { lsm6dsvxxx_submit_one_shot(dev, iodev_sqe); + } else if (IS_ENABLED(CONFIG_LSM6DSVXXX_STREAM)) { + lsm6dsvxxx_submit_stream(dev, iodev_sqe); } else { rtio_iodev_sqe_err(iodev_sqe, -ENOTSUP); } @@ -360,12 +364,15 @@ static int lsm6dsvxxx_pm_action(const struct device *dev, enum pm_device_action #define LSM6DSVXXX_CONFIG_COMMON(inst, prefix) \ .chip_api = &prefix##_chip_api, \ + .accel_bit_shift = prefix##_accel_bit_shift, \ + .accel_scaler = prefix##_accel_scaler, \ .accel_odr = DT_INST_PROP(inst, accel_odr), \ IF_ENABLED(DT_INST_NODE_HAS_PROP(inst, accel_hg_odr), \ (.accel_hg_odr = DT_INST_PROP(inst, accel_hg_odr),)) \ .accel_range = DT_INST_ENUM_IDX(inst, accel_range), \ .gyro_odr = DT_INST_PROP(inst, gyro_odr), \ .gyro_range = DT_INST_PROP(inst, gyro_range), \ + \ IF_ENABLED(CONFIG_LSM6DSVXXX_STREAM, \ (.fifo_wtm = DT_INST_PROP(inst, fifo_watermark), \ .accel_batch = DT_INST_PROP(inst, accel_fifo_batch_rate), \ @@ -373,6 +380,7 @@ static int lsm6dsvxxx_pm_action(const struct device *dev, enum pm_device_action .sflp_odr = DT_INST_PROP(inst, sflp_odr), \ .sflp_fifo_en = DT_INST_PROP(inst, sflp_fifo_enable), \ .temp_batch = DT_INST_PROP(inst, temp_fifo_batch_rate),)) \ + \ IF_ENABLED(UTIL_OR(DT_INST_NODE_HAS_PROP(inst, int1_gpios), \ DT_INST_NODE_HAS_PROP(inst, int2_gpios)), \ (LSM6DSVXXX_CFG_IRQ(inst))) @@ -388,7 +396,7 @@ static int lsm6dsvxxx_pm_action(const struct device *dev, enum pm_device_action #define LSM6DSVXXX_SPI_RTIO_DEFINE(inst, prefix) \ SPI_DT_IODEV_DEFINE(prefix##_iodev_##inst, \ - DT_DRV_INST(inst), LSM6DSVXXX_SPI_OP, 0U); \ + DT_DRV_INST(inst), LSM6DSVXXX_SPI_OP); \ RTIO_DEFINE(prefix##_rtio_ctx_##inst, 8, 8); #define LSM6DSVXXX_CONFIG_SPI(inst, prefix) \ @@ -396,9 +404,9 @@ static int lsm6dsvxxx_pm_action(const struct device *dev, enum pm_device_action STMEMSC_CTX_SPI(&prefix##_config_##inst.stmemsc_cfg), \ .stmemsc_cfg = { \ .spi = SPI_DT_SPEC_INST_GET(inst, \ - LSM6DSVXXX_SPI_OP, \ - 0), \ + LSM6DSVXXX_SPI_OP), \ }, \ + \ LSM6DSVXXX_CONFIG_COMMON(inst, prefix) \ } diff --git a/drivers/sensor/st/lsm6dsvxxx/lsm6dsvxxx.h b/drivers/sensor/st/lsm6dsvxxx/lsm6dsvxxx.h index a4590cd18e73..019381b43fde 100644 --- a/drivers/sensor/st/lsm6dsvxxx/lsm6dsvxxx.h +++ b/drivers/sensor/st/lsm6dsvxxx/lsm6dsvxxx.h @@ -44,12 +44,23 @@ #endif /* LSM6DSVXXX_ANY_INST_ON_BUS_STATUS_OKAY(i3c) */ #if (LSM6DSVXXX_ANY_INST_ON_BUS_STATUS_OKAY(i3c)) - #define ON_I3C_BUS(cfg) (cfg->i3c.bus != NULL) +#define ON_I3C_BUS(cfg) (cfg->i3c.bus != NULL) +#define I3C_INT_PIN(cfg) (cfg->int_en_i3c) #else - #define ON_I3C_BUS(cfg) (false) +#define ON_I3C_BUS(cfg) (false) +#define I3C_INT_PIN(cfg) (false) #endif +struct trigger_config { + uint8_t int_fifo_th : 1; + uint8_t int_fifo_full : 1; + uint8_t int_drdy : 1; +}; + typedef int32_t (*api_lsm6dsvxxx_init_chip)(const struct device *dev); +#if defined(CONFIG_LSM6DSVXXX_TRIGGER) +typedef int32_t (*api_lsm6dsvxxx_drdy_mode_set)(const struct device *dev); +#endif /* CONFIG_LSM6DSVXXX_TRIGGER */ #if defined(CONFIG_PM_DEVICE) typedef int32_t (*api_lsm6dsvxxx_pm_action)(const struct device *dev, enum pm_device_action action); #endif /* CONFIG_PM_DEVICE */ @@ -65,9 +76,20 @@ typedef int32_t (*api_lsm6dsvxxx_gyro_set_mode)(const struct device *dev, int32_ typedef int32_t (*api_lsm6dsvxxx_gyro_get_fs)(const struct device *dev, int32_t *range); typedef int32_t (*api_lsm6dsvxxx_gyro_get_odr)(const struct device *dev, int32_t *freq); typedef int32_t (*api_lsm6dsvxxx_gyro_get_mode)(const struct device *dev, int32_t *mode); +#if defined(CONFIG_LSM6DSVXXX_STREAM) +typedef void (*api_lsm6dsvxxx_config_fifo)(const struct device *dev, + struct trigger_config trig_cfg); +typedef void (*api_lsm6dsvxxx_config_drdy)(const struct device *dev, + struct trigger_config trig_cfg); +typedef uint32_t (*api_lsm6dsvxxx_from_f16_to_f32)(uint16_t val); +typedef float (*api_lsm6dsvxxx_from_sflp_to_mg)(int16_t lsb); +#endif /* CONFIG_LSM6DSVXXX_STREAM */ struct lsm6dsvxxx_chip_api { api_lsm6dsvxxx_init_chip init_chip; +#if defined(CONFIG_LSM6DSVXXX_TRIGGER) + api_lsm6dsvxxx_drdy_mode_set drdy_mode_set; +#endif /* CONFIG_LSM6DSVXXX_TRIGGER */ #if defined(CONFIG_PM_DEVICE) api_lsm6dsvxxx_pm_action pm_action; #endif /* CONFIG_PM_DEVICE */ @@ -83,6 +105,12 @@ struct lsm6dsvxxx_chip_api { api_lsm6dsvxxx_gyro_get_fs gyro_fs_get; api_lsm6dsvxxx_gyro_get_odr gyro_odr_get; api_lsm6dsvxxx_gyro_get_mode gyro_mode_get; +#if defined(CONFIG_LSM6DSVXXX_STREAM) + api_lsm6dsvxxx_config_fifo config_fifo; + api_lsm6dsvxxx_config_drdy config_drdy; + api_lsm6dsvxxx_from_f16_to_f32 from_f16_to_f32; + api_lsm6dsvxxx_from_sflp_to_mg from_sflp_to_mg; +#endif /* CONFIG_LSM6DSVXXX_STREAM */ }; struct lsm6dsvxxx_config { @@ -106,6 +134,27 @@ struct lsm6dsvxxx_config { uint8_t gyro_odr; uint8_t gyro_range; uint8_t drdy_pulsed; + const int8_t *accel_bit_shift; + const int32_t *accel_scaler; + +#ifdef CONFIG_LSM6DSVXXX_STREAM + uint8_t fifo_wtm; + uint8_t accel_batch : 4; + uint8_t gyro_batch : 4; + uint8_t temp_batch : 2; + uint8_t sflp_odr : 3; + uint8_t sflp_fifo_en : 3; +#endif +#ifdef CONFIG_LSM6DSVXXX_TRIGGER + const struct gpio_dt_spec int1_gpio; + const struct gpio_dt_spec int2_gpio; + uint8_t drdy_pin; + bool trig_enabled; +#if LSM6DSVXXX_ANY_INST_ON_BUS_STATUS_OKAY(i3c) + bool int_en_i3c; + lsm6dsvxxx_i3c_ibi_time_t bus_act_sel; +#endif /* LSM6DSVXXX_ANY_INST_ON_BUS_STATUS_OKAY(i3c) */ +#endif /* CONFIG_LSM6DSVXXX_TRIGGER */ #if LSM6DSVXXX_ANY_INST_ON_BUS_STATUS_OKAY(i3c) struct { @@ -135,7 +184,7 @@ struct lsm6dsvxxx_data { uint32_t acc_gain; int16_t gyro[3]; uint32_t gyro_gain; -#if defined(CONFIG_LSM6DSV16X_ENABLE_TEMP) +#if defined(CONFIG_LSM6DSVXXX_ENABLE_TEMP) int16_t temp_sample; #endif @@ -152,6 +201,26 @@ struct lsm6dsvxxx_data { rtio_bus_type bus_type; /* I2C is 0, SPI is 1, I3C is 2 */ +#ifdef CONFIG_LSM6DSVXXX_STREAM + uint64_t timestamp; + uint8_t status; + uint8_t fifo_status[2]; + uint16_t fifo_count; + struct trigger_config trig_cfg; + uint8_t accel_batch_odr : 4; + uint8_t gyro_batch_odr : 4; + uint8_t temp_batch_odr : 2; + uint8_t sflp_batch_odr : 3; + uint8_t reserved : 3; + int32_t gbias_x_udps; + int32_t gbias_y_udps; + int32_t gbias_z_udps; +#endif +#ifdef CONFIG_LSM6DSVXXX_TRIGGER + const struct gpio_dt_spec *drdy_gpio; + struct gpio_callback gpio_cb; +#endif /* CONFIG_LSM6DSVXXX_TRIGGER */ + #if LSM6DSVXXX_ANY_INST_ON_BUS_STATUS_OKAY(i3c) struct i3c_device_desc *i3c_dev; struct lsm6dsvxxx_ibi_payload ibi_payload; @@ -165,24 +234,29 @@ static inline uint8_t lsm6dsvxxx_bus_reg(rtio_bus_type bus, uint8_t addr) int lsm6dsvxxx_spi_init(const struct device *dev); +#define LSM6DSVXXX_ACCEL_FS_VAL_TO_FS_IDX(x) (__builtin_clz(x) - 1) + /* decoder */ struct lsm6dsvxxx_decoder_header { + const struct lsm6dsvxxx_config *cfg; uint64_t timestamp; uint8_t is_fifo: 1; - uint8_t range: 4; - uint8_t reserved: 3; + uint8_t accel_fs: 4; + uint8_t gyro_fs: 3; uint8_t int_status; } __attribute__((__packed__)); struct lsm6dsvxxx_fifo_data { struct lsm6dsvxxx_decoder_header header; - uint32_t accel_odr: 4; - uint32_t fifo_mode_sel: 2; - uint32_t fifo_count: 7; - uint32_t reserved_1: 5; - uint32_t accel_batch_odr: 3; - uint32_t ts_batch_odr: 2; - uint32_t reserved: 9; + uint8_t gyro_odr: 4; + uint8_t accel_odr: 4; + uint16_t fifo_count: 11; + uint16_t reserved_1: 5; + uint16_t gyro_batch_odr: 4; + uint16_t accel_batch_odr: 4; + uint16_t temp_batch_odr: 4; + uint16_t sflp_batch_odr: 3; + uint16_t reserved_2: 1; } __attribute__((__packed__)); struct lsm6dsvxxx_rtio_data { @@ -196,6 +270,19 @@ struct lsm6dsvxxx_rtio_data { int16_t temp; }; +/* Calculate scaling factor to transform micro-g/LSB unit into micro-ms2/LSB */ +#define SENSOR_SCALE_UG_TO_UMS2(ug_lsb) \ + (int32_t)((ug_lsb) * SENSOR_G / 1000000LL) + +/* Calculate scaling factor to transform micro-dps/LSB unit into micro-rads/LSB */ +#define SENSOR_SCALE_UDPS_TO_URADS(udps_lsb) \ + (int32_t)(((udps_lsb) * SENSOR_PI / 180LL) / 1000000LL) + +#ifdef CONFIG_LSM6DSVXXX_STREAM +#define LSM6DSVXXX_FIFO_ITEM_LEN 7 +#define LSM6DSVXXX_FIFO_SIZE(x) (x * LSM6DSVXXX_FIFO_ITEM_LEN) +#endif + int lsm6dsvxxx_encode(const struct device *dev, const struct sensor_chan_spec *const channels, const size_t num_channels, uint8_t *buf); @@ -206,4 +293,8 @@ void lsm6dsvxxx_rtio_rd_transaction(const struct device *dev, struct spi_buf *buf, struct rtio_iodev_sqe *iodev_sqe, rtio_callback_t complete_op_cb); +#ifdef CONFIG_LSM6DSVXXX_TRIGGER +int lsm6dsvxxx_init_interrupt(const struct device *dev); +#endif /* CONFIG_LSM6DSVXXX_TRIGGER */ + #endif /* ZEPHYR_DRIVERS_SENSOR_LSM6DSVXXX_LSM6DSVXXX_H_ */ diff --git a/drivers/sensor/st/lsm6dsvxxx/lsm6dsvxxx_decoder.c b/drivers/sensor/st/lsm6dsvxxx/lsm6dsvxxx_decoder.c index bde794feadeb..63842048ecf3 100644 --- a/drivers/sensor/st/lsm6dsvxxx/lsm6dsvxxx_decoder.c +++ b/drivers/sensor/st/lsm6dsvxxx/lsm6dsvxxx_decoder.c @@ -9,10 +9,60 @@ */ #include "lsm6dsvxxx.h" +#include #include LOG_MODULE_REGISTER(LSM6DSVXXX_DECODER, CONFIG_SENSOR_LOG_LEVEL); +#ifdef CONFIG_LSM6DSVXXX_STREAM +static const uint32_t accel_period_ns[] = { + [LSM6DSVXXX_DT_XL_BATCHED_AT_1Hz875] = UINT32_C(1000000000000) / 1875, + [LSM6DSVXXX_DT_XL_BATCHED_AT_7Hz5] = UINT32_C(1000000000000) / 7500, + [LSM6DSVXXX_DT_XL_BATCHED_AT_15Hz] = UINT32_C(1000000000) / 15, + [LSM6DSVXXX_DT_XL_BATCHED_AT_30Hz] = UINT32_C(1000000000) / 30, + [LSM6DSVXXX_DT_XL_BATCHED_AT_60Hz] = UINT32_C(1000000000) / 60, + [LSM6DSVXXX_DT_XL_BATCHED_AT_120Hz] = UINT32_C(1000000000) / 120, + [LSM6DSVXXX_DT_XL_BATCHED_AT_240Hz] = UINT32_C(1000000000) / 240, + [LSM6DSVXXX_DT_XL_BATCHED_AT_480Hz] = UINT32_C(1000000000) / 480, + [LSM6DSVXXX_DT_XL_BATCHED_AT_960Hz] = UINT32_C(1000000000) / 960, + [LSM6DSVXXX_DT_XL_BATCHED_AT_1920Hz] = UINT32_C(1000000000) / 1920, + [LSM6DSVXXX_DT_XL_BATCHED_AT_3840Hz] = UINT32_C(1000000000) / 3840, + [LSM6DSVXXX_DT_XL_BATCHED_AT_7680Hz] = UINT32_C(1000000000) / 7680, +}; + +static const uint32_t gyro_period_ns[] = { + [LSM6DSVXXX_DT_GY_BATCHED_AT_1Hz875] = UINT32_C(1000000000000) / 1875, + [LSM6DSVXXX_DT_GY_BATCHED_AT_7Hz5] = UINT32_C(1000000000000) / 7500, + [LSM6DSVXXX_DT_GY_BATCHED_AT_15Hz] = UINT32_C(1000000000) / 15, + [LSM6DSVXXX_DT_GY_BATCHED_AT_30Hz] = UINT32_C(1000000000) / 30, + [LSM6DSVXXX_DT_GY_BATCHED_AT_60Hz] = UINT32_C(1000000000) / 60, + [LSM6DSVXXX_DT_GY_BATCHED_AT_120Hz] = UINT32_C(1000000000) / 120, + [LSM6DSVXXX_DT_GY_BATCHED_AT_240Hz] = UINT32_C(1000000000) / 240, + [LSM6DSVXXX_DT_GY_BATCHED_AT_480Hz] = UINT32_C(1000000000) / 480, + [LSM6DSVXXX_DT_GY_BATCHED_AT_960Hz] = UINT32_C(1000000000) / 960, + [LSM6DSVXXX_DT_GY_BATCHED_AT_1920Hz] = UINT32_C(1000000000) / 1920, + [LSM6DSVXXX_DT_GY_BATCHED_AT_3840Hz] = UINT32_C(1000000000) / 3840, + [LSM6DSVXXX_DT_GY_BATCHED_AT_7680Hz] = UINT32_C(1000000000) / 7680, +}; + +#if defined(CONFIG_LSM6DSVXXX_ENABLE_TEMP) +static const uint32_t temp_period_ns[] = { + [LSM6DSVXXX_DT_TEMP_BATCHED_AT_1Hz875] = UINT32_C(1000000000000) / 1875, + [LSM6DSVXXX_DT_TEMP_BATCHED_AT_15Hz] = UINT32_C(1000000000) / 15, + [LSM6DSVXXX_DT_TEMP_BATCHED_AT_60Hz] = UINT32_C(1000000000) / 60, +}; +#endif + +static const uint32_t sflp_period_ns[] = { + [LSM6DSVXXX_DT_SFLP_ODR_AT_15Hz] = UINT32_C(1000000000) / 15, + [LSM6DSVXXX_DT_SFLP_ODR_AT_30Hz] = UINT32_C(1000000000) / 30, + [LSM6DSVXXX_DT_SFLP_ODR_AT_60Hz] = UINT32_C(1000000000) / 60, + [LSM6DSVXXX_DT_SFLP_ODR_AT_120Hz] = UINT32_C(1000000000) / 120, + [LSM6DSVXXX_DT_SFLP_ODR_AT_240Hz] = UINT32_C(1000000000) / 240, + [LSM6DSVXXX_DT_SFLP_ODR_AT_480Hz] = UINT32_C(1000000000) / 480, +}; +#endif /* CONFIG_LSM6DSVXXX_STREAM */ + /* * Expand val to q31_t according to its range; this is achieved multiplying by 2^31/2^range. */ @@ -26,22 +76,19 @@ LOG_MODULE_REGISTER(LSM6DSVXXX_DECODER, CONFIG_SENSOR_LOG_LEVEL); #define Q31_SHIFT_MICROVAL(micro_val, range) \ (q31_t) ((int64_t)(micro_val) * ((int64_t)1 << (31 - (range))) / 1000000LL) -/* bit range for Accelerometer for a given range value */ -static const int8_t accel_range[] = { - 5, /* FS_2G */ - 6, /* FS_4G */ - 7, /* FS_8G */ - 8, /* FS_16G */ - 9, /* FS_32G */ - 10, /* FS_64G */ - 11, /* FS_128G */ - 12, /* FS_256G */ - 13, /* FS_320G */ +/* bit shift for Gyroscope for a given fs */ +static const int8_t gyro_bit_shift[] = { + 2, /* 125 dps */ + 3, /* 250 dps */ + 4, /* 500 dps */ + 5, /* 1000 dps */ + 6, /* 2000 dps */ + 7, /* 4000 dps */ }; #if defined(CONFIG_LSM6DSVXXX_ENABLE_TEMP) -/* bit range for Temperature sensor */ -static const int8_t temp_range = 9; +/* bit shift for Temperature sensor */ +static const int8_t temp_bit_shift = 9; /* transform temperature LSB into micro-Celsius */ #define SENSOR_TEMP_UCELSIUS(t_lsb) \ @@ -49,30 +96,19 @@ static const int8_t temp_range = 9; #endif -/* Calculate scaling factor to transform micro-g/LSB unit into micro-ms2/LSB */ -#define SENSOR_SCALE_UG_TO_UMS2(ug_lsb) \ - (int32_t)((ug_lsb) * SENSOR_G / 1000000LL) - /* - * Accelerometer scaling factors table for a given range value - * GAIN_UNIT_XL is expressed in ug/LSB. + * Accelerometer scaling factors table (indexed by full scale) + * GAIN_UNIT_G is expressed in udps/LSB. */ -static const int32_t accel_scaler[] = { - SENSOR_SCALE_UG_TO_UMS2(61), /* FS_2G */ - SENSOR_SCALE_UG_TO_UMS2(122), /* FS_4G */ - SENSOR_SCALE_UG_TO_UMS2(244), /* FS_8G */ - SENSOR_SCALE_UG_TO_UMS2(488), /* FS_16G */ - SENSOR_SCALE_UG_TO_UMS2(976), /* FS_32G */ - SENSOR_SCALE_UG_TO_UMS2(1952), /* FS_64G */ - SENSOR_SCALE_UG_TO_UMS2(2904), /* FS_128G */ - SENSOR_SCALE_UG_TO_UMS2(7808), /* FS_256G */ - SENSOR_SCALE_UG_TO_UMS2(10417), /* FS_320G */ +static const int32_t gyro_scaler[] = { + SENSOR_SCALE_UDPS_TO_URADS(4375), /* 125 dps */ + SENSOR_SCALE_UDPS_TO_URADS(8750), /* 250 dps */ + SENSOR_SCALE_UDPS_TO_URADS(17500), /* 500 dps */ + SENSOR_SCALE_UDPS_TO_URADS(35000), /* 1000 dps */ + SENSOR_SCALE_UDPS_TO_URADS(70000), /* 2000 dps */ + SENSOR_SCALE_UDPS_TO_URADS(140000), /* 4000 dps */ }; -/* Calculate scaling factor to transform micro-dps/LSB unit into micro-rads/LSB */ -#define SENSOR_SCALE_UDPS_TO_URADS(udps_lsb) \ - (int32_t)(((udps_lsb) * SENSOR_PI / 180LL) / 1000000LL) - static int lsm6dsvxxx_decoder_get_frame_count(const uint8_t *buffer, struct sensor_chan_spec chan_spec, uint16_t *frame_count) @@ -106,14 +142,447 @@ static int lsm6dsvxxx_decoder_get_frame_count(const uint8_t *buffer, return 0; } +#ifdef CONFIG_LSM6DSVXXX_STREAM + const struct lsm6dsvxxx_fifo_data *edata = (const struct lsm6dsvxxx_fifo_data *)buffer; + const uint8_t *buffer_end; + uint8_t fifo_tag; + uint8_t tot_accel_fifo_words = 0, tot_gyro_fifo_words = 0; + uint8_t tot_sflp_gbias = 0, tot_sflp_gravity = 0, tot_sflp_game_rotation = 0; + +#if defined(CONFIG_LSM6DSVXXX_ENABLE_TEMP) + uint8_t tot_temp_fifo_words = 0; +#endif + + buffer += sizeof(struct lsm6dsvxxx_fifo_data); + buffer_end = buffer + LSM6DSVXXX_FIFO_SIZE(edata->fifo_count); + + /* count total FIFO word for each tag */ + while (buffer < buffer_end) { + fifo_tag = (buffer[0] >> 3); + + switch (fifo_tag) { + case LSM6DSVXXX_XL_NC_TAG: + tot_accel_fifo_words++; + break; + case LSM6DSVXXX_GY_NC_TAG: + tot_gyro_fifo_words++; + break; +#if defined(CONFIG_LSM6DSVXXX_ENABLE_TEMP) + case LSM6DSVXXX_TEMPERATURE_TAG: + tot_temp_fifo_words++; + break; +#endif + case LSM6DSVXXX_SFLP_GYROSCOPE_BIAS_TAG: + tot_sflp_gbias++; + break; + case LSM6DSVXXX_SFLP_GRAVITY_VECTOR_TAG: + tot_sflp_gravity++; + break; + case LSM6DSVXXX_SFLP_GAME_ROTATION_VECTOR_TAG: + tot_sflp_game_rotation++; + break; + default: + break; + } + + buffer += LSM6DSVXXX_FIFO_ITEM_LEN; + } + + switch (chan_spec.chan_type) { + case SENSOR_CHAN_ACCEL_X: + case SENSOR_CHAN_ACCEL_Y: + case SENSOR_CHAN_ACCEL_Z: + case SENSOR_CHAN_ACCEL_XYZ: + *frame_count = tot_accel_fifo_words; + break; + + case SENSOR_CHAN_GYRO_X: + case SENSOR_CHAN_GYRO_Y: + case SENSOR_CHAN_GYRO_Z: + case SENSOR_CHAN_GYRO_XYZ: + *frame_count = tot_gyro_fifo_words; + break; + +#if defined(CONFIG_LSM6DSVXXX_ENABLE_TEMP) + case SENSOR_CHAN_DIE_TEMP: + *frame_count = tot_temp_fifo_words; + break; +#endif + case SENSOR_CHAN_GAME_ROTATION_VECTOR: + *frame_count = tot_sflp_game_rotation; + break; + case SENSOR_CHAN_GRAVITY_VECTOR: + *frame_count = tot_sflp_gravity; + break; + case SENSOR_CHAN_GBIAS_XYZ: + *frame_count = tot_sflp_gbias; + break; + default: + *frame_count = 0; + break; + } +#endif + + return 0; +} + +#ifdef CONFIG_LSM6DSVXXX_STREAM +static float32_t calculate_quat_w(float32_t *x, float32_t *y, float32_t *z) +{ + float32_t sumsq; + + sumsq = powf(*x, 2) + powf(*y, 2) + powf(*z, 2); + + /* + * Theoretically sumsq should never be greater than 1, but due to + * lack of precision it might happen. So, add a software correction + * which consists in normalizing the (x, y, z) vector. + */ + if (sumsq > 1.0f) { + float32_t n = sqrtf(sumsq); + + *x /= n; + *y /= n; + *z /= n; + sumsq = 1.0f; + } + + /* unity vector quaternions */ + return sqrtf(1.0f - sumsq); +} + +static int generate_accel_output(const uint8_t *buffer, int count, uint16_t xl_count, + struct sensor_chan_spec chan_spec, + const struct lsm6dsvxxx_decoder_header *header, + void *data_out) +{ + struct sensor_three_axis_data *out = data_out; + const struct lsm6dsvxxx_fifo_data *edata = (const struct lsm6dsvxxx_fifo_data *)buffer; + int16_t x, y, z; + const struct lsm6dsvxxx_config *cfg = header->cfg; + const int32_t scale = cfg->accel_scaler[header->accel_fs]; + + if (!SENSOR_CHANNEL_IS_ACCEL(chan_spec.chan_type)) { + return 1; + } + + out->readings[count].timestamp_delta = + (xl_count - 1) * accel_period_ns[edata->accel_batch_odr]; + + x = *(const int16_t *)&buffer[1]; + y = *(const int16_t *)&buffer[3]; + z = *(const int16_t *)&buffer[5]; + + out->shift = cfg->accel_bit_shift[header->accel_fs]; + + out->readings[count].x = Q31_SHIFT_MICROVAL(scale * x, out->shift); + out->readings[count].y = Q31_SHIFT_MICROVAL(scale * y, out->shift); + out->readings[count].z = Q31_SHIFT_MICROVAL(scale * z, out->shift); + return 0; } +static int generate_gyro_output(const uint8_t *buffer, int count, uint16_t gy_count, + struct sensor_chan_spec chan_spec, + const struct lsm6dsvxxx_decoder_header *header, + void *data_out) +{ + struct sensor_three_axis_data *out = data_out; + const struct lsm6dsvxxx_fifo_data *edata = (const struct lsm6dsvxxx_fifo_data *)buffer; + int16_t x, y, z; + const int32_t scale = gyro_scaler[header->gyro_fs]; + + if (!SENSOR_CHANNEL_IS_GYRO(chan_spec.chan_type)) { + return 1; + } + + out->readings[count].timestamp_delta = + (gy_count - 1) * gyro_period_ns[edata->gyro_batch_odr]; + + x = *(const int16_t *)&buffer[1]; + y = *(const int16_t *)&buffer[3]; + z = *(const int16_t *)&buffer[5]; + + out->shift = gyro_bit_shift[header->gyro_fs]; + + out->readings[count].x = Q31_SHIFT_MICROVAL(scale * x, out->shift); + out->readings[count].y = Q31_SHIFT_MICROVAL(scale * y, out->shift); + out->readings[count].z = Q31_SHIFT_MICROVAL(scale * z, out->shift); + + return 0; +} + +#if defined(CONFIG_LSM6DSVXXX_ENABLE_TEMP) +static int generate_temp_output(const uint8_t *buffer, int count, uint16_t temp_count, + struct sensor_chan_spec chan_spec, + const struct lsm6dsvxxx_decoder_header *header, + void *data_out) +{ + struct sensor_q31_data *out = data_out; + const struct lsm6dsvxxx_fifo_data *edata = (const struct lsm6dsvxxx_fifo_data *)buffer; + int16_t t; + int64_t t_uC; + + if (chan_spec.chan_type != SENSOR_CHAN_DIE_TEMP) { + return 1; + } + + out->readings[count].timestamp_delta = + (temp_count - 1) * temp_period_ns[edata->temp_batch_odr]; + + t = *(const int16_t *)&buffer[1]; + t_uC = SENSOR_TEMP_UCELSIUS(t); + + out->shift = temp_bit_shift; + + out->readings[count].temperature = Q31_SHIFT_MICROVAL(t_uC, out->shift); + + return 0; +} +#endif + +static int generate_game_rot_output(const uint8_t *buffer, int count, uint16_t game_rot_count, + struct sensor_chan_spec chan_spec, + const struct lsm6dsvxxx_decoder_header *header, + void *data_out) +{ + struct sensor_game_rotation_vector_data *out = data_out; + const struct lsm6dsvxxx_fifo_data *edata = (const struct lsm6dsvxxx_fifo_data *)buffer; + const struct lsm6dsvxxx_config *cfg = header->cfg; + union { float32_t f; uint32_t i; } x, y, z; + float32_t w; + + if (chan_spec.chan_type != SENSOR_CHAN_GAME_ROTATION_VECTOR) { + return 1; + } + + out->readings[count].timestamp_delta = + (game_rot_count - 1) * sflp_period_ns[edata->sflp_batch_odr]; + + x.i = cfg->chip_api->from_f16_to_f32(buffer[1] | (buffer[2] << 8)); + y.i = cfg->chip_api->from_f16_to_f32(buffer[3] | (buffer[4] << 8)); + z.i = cfg->chip_api->from_f16_to_f32(buffer[5] | (buffer[6] << 8)); + + /* unity vector quaternion */ + w = calculate_quat_w(&x.f, &y.f, &z.f); + + /* + * Quaternions are numbers between -1 and 1. So let's select the signed + * Q0.31 format (m = 0, n (fractional bits) == 31) + */ + out->shift = 0; + + out->readings[count].x = Q31_SHIFT_VAL(x.f, out->shift); + out->readings[count].y = Q31_SHIFT_VAL(y.f, out->shift); + out->readings[count].z = Q31_SHIFT_VAL(z.f, out->shift); + out->readings[count].w = Q31_SHIFT_VAL(w, out->shift); + + return 0; +} + +static int generate_gbias_output(const uint8_t *buffer, int count, uint16_t gbias_count, + struct sensor_chan_spec chan_spec, + const struct lsm6dsvxxx_decoder_header *header, + void *data_out) +{ + struct sensor_three_axis_data *out = data_out; + const struct lsm6dsvxxx_fifo_data *edata = (const struct lsm6dsvxxx_fifo_data *)buffer; + int16_t x, y, z; + const int32_t scale = gyro_scaler[0]; /* 125 dpds */ + + if (chan_spec.chan_type != SENSOR_CHAN_GBIAS_XYZ) { + return 1; + } + + out->readings[count].timestamp_delta = + (gbias_count - 1) * sflp_period_ns[edata->sflp_batch_odr]; + + x = buffer[1] | (buffer[2] << 8); + y = buffer[3] | (buffer[4] << 8); + z = buffer[5] | (buffer[6] << 8); + + out->shift = gyro_bit_shift[0]; /* 125 dpds */ + + out->readings[count].x = Q31_SHIFT_MICROVAL(scale * x, out->shift); + out->readings[count].y = Q31_SHIFT_MICROVAL(scale * y, out->shift); + out->readings[count].z = Q31_SHIFT_MICROVAL(scale * z, out->shift); + + return 0; +} + +static int generate_gravity_output(const uint8_t *buffer, int count, uint16_t gravity_count, + struct sensor_chan_spec chan_spec, + const struct lsm6dsvxxx_decoder_header *header, + void *data_out) +{ + struct sensor_three_axis_data *out = data_out; + const struct lsm6dsvxxx_fifo_data *edata = (const struct lsm6dsvxxx_fifo_data *)buffer; + const struct lsm6dsvxxx_config *cfg = header->cfg; + float32_t x, y, z; + + if (chan_spec.chan_type != SENSOR_CHAN_GRAVITY_VECTOR) { + return 1; + } + + out->readings[count].timestamp_delta = + (gravity_count - 1) * sflp_period_ns[edata->sflp_batch_odr]; + + x = cfg->chip_api->from_sflp_to_mg(buffer[1] | (buffer[2] << 8)); + y = cfg->chip_api->from_sflp_to_mg(buffer[3] | (buffer[4] << 8)); + z = cfg->chip_api->from_sflp_to_mg(buffer[5] | (buffer[6] << 8)); + + out->shift = 12; + + out->readings[count].x = Q31_SHIFT_VAL(x, out->shift); + out->readings[count].y = Q31_SHIFT_VAL(y, out->shift); + out->readings[count].z = Q31_SHIFT_VAL(z, out->shift); + + return 0; +} + +static int lsm6dsvxxx_decode_fifo(const uint8_t *buffer, struct sensor_chan_spec chan_spec, + uint32_t *fit, uint16_t max_count, void *data_out) +{ + const struct lsm6dsvxxx_fifo_data *edata = (const struct lsm6dsvxxx_fifo_data *)buffer; + const uint8_t *buffer_end; + const struct lsm6dsvxxx_decoder_header *header = &edata->header; + int count = 0; + uint8_t fifo_tag; + uint16_t xl_count = 0, gy_count = 0; + uint16_t tot_chan_fifo_words = 0; + +#if defined(CONFIG_LSM6DSVXXX_ENABLE_TEMP) + uint16_t temp_count = 0; +#endif + uint16_t game_rot_count = 0, gravity_count = 0, gbias_count = 0; + int ret; + + /* count total FIFO word for each tag */ + ret = lsm6dsvxxx_decoder_get_frame_count(buffer, chan_spec, &tot_chan_fifo_words); + if (ret < 0) { + return 0; + } + + buffer += sizeof(struct lsm6dsvxxx_fifo_data); + buffer_end = buffer + LSM6DSVXXX_FIFO_SIZE(edata->fifo_count); + + /* + * Timestamp in header is set when FIFO threshold is reached, so + * set time baseline going back in past according to total number + * of FIFO word for each type. + */ + switch (chan_spec.chan_type) { + case SENSOR_CHAN_ACCEL_X: + case SENSOR_CHAN_ACCEL_Y: + case SENSOR_CHAN_ACCEL_Z: + case SENSOR_CHAN_ACCEL_XYZ: + ((struct sensor_data_header *)data_out)->base_timestamp_ns = + edata->header.timestamp - + (tot_chan_fifo_words - 1) * accel_period_ns[edata->accel_batch_odr]; + break; + case SENSOR_CHAN_GYRO_X: + case SENSOR_CHAN_GYRO_Y: + case SENSOR_CHAN_GYRO_Z: + case SENSOR_CHAN_GYRO_XYZ: + ((struct sensor_data_header *)data_out)->base_timestamp_ns = + edata->header.timestamp - + (tot_chan_fifo_words - 1) * gyro_period_ns[edata->gyro_batch_odr]; + break; +#if defined(CONFIG_LSM6DSVXXX_ENABLE_TEMP) + case SENSOR_CHAN_DIE_TEMP: + ((struct sensor_data_header *)data_out)->base_timestamp_ns = + edata->header.timestamp - + (tot_chan_fifo_words - 1) * temp_period_ns[edata->temp_batch_odr]; + break; +#endif + case SENSOR_CHAN_GAME_ROTATION_VECTOR: + case SENSOR_CHAN_GRAVITY_VECTOR: + case SENSOR_CHAN_GBIAS_XYZ: + ((struct sensor_data_header *)data_out)->base_timestamp_ns = + edata->header.timestamp - + (tot_chan_fifo_words - 1) * sflp_period_ns[edata->sflp_batch_odr]; + break; + default: + /* unhandled FIFO tag */ + ((struct sensor_data_header *)data_out)->base_timestamp_ns = 0; + } + + while (count < max_count && buffer < buffer_end) { + const uint8_t *frame_end = buffer; + uint8_t skip = 0; + + frame_end += LSM6DSVXXX_FIFO_ITEM_LEN; + + if ((uintptr_t)buffer < *fit) { + /* This frame was already decoded, move on to the next frame */ + buffer = frame_end; + continue; + } + + fifo_tag = (buffer[0] >> 3); + + switch (fifo_tag) { + case LSM6DSVXXX_XL_NC_TAG: + xl_count++; + skip = generate_accel_output(buffer, count, xl_count, + chan_spec, header, data_out); + break; + + case LSM6DSVXXX_GY_NC_TAG: + gy_count++; + skip = generate_gyro_output(buffer, count, gy_count, + chan_spec, header, data_out); + break; + +#if defined(CONFIG_LSM6DSVXXX_ENABLE_TEMP) + case LSM6DSVXXX_TEMPERATURE_TAG: + temp_count++; + skip = generate_temp_output(buffer, count, temp_count, + chan_spec, header, data_out); + break; +#endif + case LSM6DSVXXX_SFLP_GAME_ROTATION_VECTOR_TAG: + game_rot_count++; + skip = generate_game_rot_output(buffer, count, game_rot_count, + chan_spec, header, data_out); + break; + + case LSM6DSVXXX_SFLP_GYROSCOPE_BIAS_TAG: + gbias_count++; + skip = generate_gbias_output(buffer, count, gbias_count, + chan_spec, header, data_out); + break; + + case LSM6DSVXXX_SFLP_GRAVITY_VECTOR_TAG: + gravity_count++; + skip = generate_gravity_output(buffer, count, gravity_count, + chan_spec, header, data_out); + break; + + default: + /* skip unhandled FIFO tag */ + buffer = frame_end; + LOG_DBG("unknown FIFO tag %02x", fifo_tag); + continue; + } + + buffer = frame_end; + if (!skip) { + *fit = (uintptr_t)frame_end; + count++; + } + } + + return count; +} +#endif /* CONFIG_LSM6DSVXXX_STREAM */ + static int lsm6dsvxxx_decode_sample(const uint8_t *buffer, struct sensor_chan_spec chan_spec, uint32_t *fit, uint16_t max_count, void *data_out) { const struct lsm6dsvxxx_rtio_data *edata = (const struct lsm6dsvxxx_rtio_data *)buffer; const struct lsm6dsvxxx_decoder_header *header = &edata->header; + const struct lsm6dsvxxx_config *cfg = header->cfg; if (*fit != 0) { return 0; @@ -127,7 +596,7 @@ static int lsm6dsvxxx_decode_sample(const uint8_t *buffer, struct sensor_chan_sp case SENSOR_CHAN_ACCEL_Y: case SENSOR_CHAN_ACCEL_Z: case SENSOR_CHAN_ACCEL_XYZ: { - const int32_t scale = accel_scaler[header->range]; + const int32_t scale = cfg->accel_scaler[header->accel_fs]; if (edata->has_accel == 0) { return -ENODATA; @@ -138,7 +607,7 @@ static int lsm6dsvxxx_decode_sample(const uint8_t *buffer, struct sensor_chan_sp out->header.base_timestamp_ns = edata->header.timestamp; out->header.reading_count = 1; - out->shift = accel_range[header->range]; + out->shift = cfg->accel_bit_shift[header->accel_fs]; out->readings[0].x = Q31_SHIFT_MICROVAL(scale * edata->accel[0], out->shift); out->readings[0].y = Q31_SHIFT_MICROVAL(scale * edata->accel[1], out->shift); @@ -159,7 +628,7 @@ static int lsm6dsvxxx_decode_sample(const uint8_t *buffer, struct sensor_chan_sp out->header.base_timestamp_ns = edata->header.timestamp; out->header.reading_count = 1; - out->shift = temp_range; + out->shift = temp_bit_shift; /* transform temperature LSB into micro-Celsius */ t_uC = SENSOR_TEMP_UCELSIUS(edata->temp); @@ -177,6 +646,17 @@ static int lsm6dsvxxx_decode_sample(const uint8_t *buffer, struct sensor_chan_sp static int lsm6dsvxxx_decoder_decode(const uint8_t *buffer, struct sensor_chan_spec chan_spec, uint32_t *fit, uint16_t max_count, void *data_out) { +#ifdef CONFIG_LSM6DSVXXX_STREAM + const struct lsm6dsvxxx_decoder_header *header = + (const struct lsm6dsvxxx_decoder_header *)buffer; + + if (header->is_fifo) { + return lsm6dsvxxx_decode_fifo(buffer, chan_spec, fit, max_count, data_out); + } else { + return lsm6dsvxxx_decode_sample(buffer, chan_spec, fit, max_count, data_out); + } +#endif + return lsm6dsvxxx_decode_sample(buffer, chan_spec, fit, max_count, data_out); } @@ -199,11 +679,16 @@ static int lsm6dsvxxx_decoder_get_size_info(struct sensor_chan_spec chan_spec, s return -ENOTSUP; } } +static bool lsm6dsvxxx_decoder_has_trigger(const uint8_t *buffer, enum sensor_trigger_type trigger) +{ + return false; +} SENSOR_DECODER_API_DT_DEFINE() = { .get_frame_count = lsm6dsvxxx_decoder_get_frame_count, .get_size_info = lsm6dsvxxx_decoder_get_size_info, .decode = lsm6dsvxxx_decoder_decode, + .has_trigger = lsm6dsvxxx_decoder_has_trigger, }; int lsm6dsvxxx_get_decoder(const struct device *dev, const struct sensor_decoder_api **decoder) diff --git a/drivers/sensor/st/lsm6dsvxxx/lsm6dsvxxx_rtio.h b/drivers/sensor/st/lsm6dsvxxx/lsm6dsvxxx_rtio.h index 14596a7e8c9f..865cae12be55 100644 --- a/drivers/sensor/st/lsm6dsvxxx/lsm6dsvxxx_rtio.h +++ b/drivers/sensor/st/lsm6dsvxxx/lsm6dsvxxx_rtio.h @@ -19,4 +19,9 @@ void lsm6dsvxxx_submit(const struct device *sensor, struct rtio_iodev_sqe *iodev void lsm6dsvxxx_submit_stream(const struct device *sensor, struct rtio_iodev_sqe *iodev_sqe); void lsm6dsvxxx_stream_irq_handler(const struct device *dev); +int lsm6dsvxxx_gbias_config(const struct device *dev, enum sensor_channel chan, + enum sensor_attribute attr, + const struct sensor_value *val); +int lsm6dsvxxx_gbias_get_config(const struct device *dev, enum sensor_channel chan, + enum sensor_attribute attr, struct sensor_value *val); #endif /* ZEPHYR_DRIVERS_SENSOR_LSM6DSVXXX_RTIO_H_ */ diff --git a/drivers/sensor/st/lsm6dsvxxx/lsm6dsvxxx_stream.c b/drivers/sensor/st/lsm6dsvxxx/lsm6dsvxxx_stream.c new file mode 100644 index 000000000000..533e645da34c --- /dev/null +++ b/drivers/sensor/st/lsm6dsvxxx/lsm6dsvxxx_stream.c @@ -0,0 +1,628 @@ +/* ST Microelectronics LSM6DSVXXX family IMU sensor + * + * Copyright (c) 2025 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + * + * Datasheet: + * https://www.st.com/resource/en/datasheet/lsm6dsv320x.pdf + */ + +#include "lsm6dsvxxx.h" + +#include +LOG_MODULE_DECLARE(LSM6DSVXXX, CONFIG_SENSOR_LOG_LEVEL); + +void lsm6dsvxxx_gpio_pin_enable(const struct lsm6dsvxxx_config *config, + const struct gpio_dt_spec *irq_gpio) +{ + if (!ON_I3C_BUS(config) || (I3C_INT_PIN(config))) { + gpio_pin_interrupt_configure_dt(irq_gpio, GPIO_INT_EDGE_TO_ACTIVE); + } +} + +void lsm6dsvxxx_gpio_pin_disable(const struct lsm6dsvxxx_config *config, + const struct gpio_dt_spec *irq_gpio) +{ + if (!ON_I3C_BUS(config) || (I3C_INT_PIN(config))) { + gpio_pin_interrupt_configure_dt(irq_gpio, GPIO_INT_DISABLE); + } +} + +int lsm6dsvxxx_gbias_config(const struct device *dev, enum sensor_channel chan, + enum sensor_attribute attr, + const struct sensor_value *val) +{ + struct lsm6dsvxxx_data *lsm6dsvxxx = dev->data; + + switch (attr) { + case SENSOR_ATTR_OFFSET: + lsm6dsvxxx->gbias_x_udps = 10 * sensor_rad_to_10udegrees(&val[0]); + lsm6dsvxxx->gbias_y_udps = 10 * sensor_rad_to_10udegrees(&val[1]); + lsm6dsvxxx->gbias_z_udps = 10 * sensor_rad_to_10udegrees(&val[2]); + break; + default: + LOG_DBG("Accel attribute not supported."); + return -ENOTSUP; + } + + return 0; +} + +int lsm6dsvxxx_gbias_get_config(const struct device *dev, enum sensor_channel chan, + enum sensor_attribute attr, struct sensor_value *val) +{ + struct lsm6dsvxxx_data *lsm6dsvxxx = dev->data; + + switch (attr) { + case SENSOR_ATTR_OFFSET: + sensor_10udegrees_to_rad(lsm6dsvxxx->gbias_x_udps / 10, &val[0]); + sensor_10udegrees_to_rad(lsm6dsvxxx->gbias_y_udps / 10, &val[1]); + sensor_10udegrees_to_rad(lsm6dsvxxx->gbias_z_udps / 10, &val[2]); + break; + default: + LOG_DBG("Accel attribute not supported."); + return -ENOTSUP; + } + + return 0; +} + +void lsm6dsvxxx_submit_stream(const struct device *dev, struct rtio_iodev_sqe *iodev_sqe) +{ + struct lsm6dsvxxx_data *data = dev->data; + const struct lsm6dsvxxx_config *config = dev->config; + const struct sensor_read_config *cfg = iodev_sqe->sqe.iodev->data; + struct trigger_config trig_cfg = { 0 }; + + lsm6dsvxxx_gpio_pin_disable(config, data->drdy_gpio); + + for (size_t i = 0; i < cfg->count; i++) { + switch (cfg->triggers[i].trigger) { + case SENSOR_TRIG_FIFO_WATERMARK: + trig_cfg.int_fifo_th = 1; + break; + case SENSOR_TRIG_FIFO_FULL: + trig_cfg.int_fifo_full = 1; + break; + case SENSOR_TRIG_DATA_READY: + trig_cfg.int_drdy = 1; + break; + default: + break; + } + } + + /* if any change in trig_cfg for FIFO triggers */ + if (trig_cfg.int_fifo_th != data->trig_cfg.int_fifo_th || + trig_cfg.int_fifo_full != data->trig_cfg.int_fifo_full) { + data->trig_cfg.int_fifo_th = trig_cfg.int_fifo_th; + data->trig_cfg.int_fifo_full = trig_cfg.int_fifo_full; + + /* enable/disable the FIFO */ + config->chip_api->config_fifo(dev, data->trig_cfg); + } + + /* if any change in trig_cfg for DRDY triggers */ + if (trig_cfg.int_drdy != data->trig_cfg.int_drdy) { + data->trig_cfg.int_drdy = trig_cfg.int_drdy; + + /* enable/disable drdy events */ + config->chip_api->config_drdy(dev, data->trig_cfg); + } + + data->streaming_sqe = iodev_sqe; + + lsm6dsvxxx_gpio_pin_enable(config, data->drdy_gpio); +} + +/* + * Called by bus driver to complete the sqe. + */ +static void lsm6dsvxxx_complete_op_cb(struct rtio *r, const struct rtio_sqe *sqe, + int result, void *arg) +{ + ARG_UNUSED(result); + + const struct device *dev = arg; + struct lsm6dsvxxx_data *data = dev->data; + + /* + * Mark operation completed + */ + data->streaming_sqe = NULL; + rtio_iodev_sqe_ok(sqe->userdata, 0); + lsm6dsvxxx_gpio_pin_enable(dev->config, data->drdy_gpio); +} + +/* + * Called by bus driver to complete the LSM6DSVXXX_FIFO_STATUS read op (2 bytes). + * If FIFO threshold or FIFO full events are active it reads all FIFO entries. + */ +static void lsm6dsvxxx_read_fifo_cb(struct rtio *r, const struct rtio_sqe *sqe, + int result, void *arg) +{ + ARG_UNUSED(result); + + const struct device *dev = arg; + const struct lsm6dsvxxx_config *cfg = dev->config; + struct lsm6dsvxxx_data *data = dev->data; + struct rtio *rtio = data->rtio_ctx; + const struct gpio_dt_spec *irq_gpio = data->drdy_gpio; + struct rtio_iodev *iodev = data->iodev; + struct sensor_read_config *read_config; + uint8_t fifo_th = 0, fifo_full = 0; + uint16_t fifo_count; + + /* At this point, no sqe request is queued should be considered as a bug */ + __ASSERT_NO_MSG(data->streaming_sqe != NULL); + + read_config = (struct sensor_read_config *)data->streaming_sqe->sqe.iodev->data; + __ASSERT_NO_MSG(read_config != NULL); + __ASSERT_NO_MSG(read_config->is_streaming == true); + + /* parse the configuration in search for any configured trigger */ + struct sensor_stream_trigger *fifo_ths_cfg = NULL; + struct sensor_stream_trigger *fifo_full_cfg = NULL; + + for (int i = 0; i < read_config->count; ++i) { + if (read_config->triggers[i].trigger == SENSOR_TRIG_FIFO_WATERMARK) { + fifo_ths_cfg = &read_config->triggers[i]; + continue; + } + + if (read_config->triggers[i].trigger == SENSOR_TRIG_FIFO_FULL) { + fifo_full_cfg = &read_config->triggers[i]; + continue; + } + } + + /* fill fifo h/w status */ + fifo_th = (data->fifo_status[1] & 0x80) ? 1 : 0; + fifo_full = (data->fifo_status[1] & 0x20) ? 1 : 0; + fifo_count = (uint16_t)data->fifo_status[1] & 0x1U; + fifo_count = (fifo_count << 8) | data->fifo_status[0]; + data->fifo_count = fifo_count; + + bool has_fifo_ths_trig = fifo_ths_cfg != NULL && fifo_th == 1; + bool has_fifo_full_trig = fifo_full_cfg != NULL && fifo_full == 1; + + /* check if no theshold/full fifo interrupt or spurious interrupts */ + if (!has_fifo_ths_trig && !has_fifo_full_trig) { + /* complete operation with no error */ + rtio_iodev_sqe_ok(sqe->userdata, 0); + + data->streaming_sqe = NULL; + lsm6dsvxxx_gpio_pin_enable(cfg, irq_gpio); + return; + } + + /* flush completion */ + int res = 0; + + res = rtio_flush_completion_queue(rtio); + + /* Bail/cancel attempt to read sensor on any error */ + if (res != 0) { + rtio_iodev_sqe_err(data->streaming_sqe, res); + data->streaming_sqe = NULL; + return; + } + + enum sensor_stream_data_opt data_opt; + + if (has_fifo_ths_trig && !has_fifo_full_trig) { + /* Only care about fifo threshold */ + data_opt = fifo_ths_cfg->opt; + } else if (!has_fifo_ths_trig && has_fifo_full_trig) { + /* Only care about fifo full */ + data_opt = fifo_full_cfg->opt; + } else { + /* Both fifo threshold and full */ + data_opt = MIN(fifo_ths_cfg->opt, fifo_full_cfg->opt); + } + + if (data_opt == SENSOR_STREAM_DATA_NOP || data_opt == SENSOR_STREAM_DATA_DROP) { + uint8_t *buf; + uint32_t buf_len; + + /* Clear streaming_sqe since we're done with the call */ + if (rtio_sqe_rx_buf(data->streaming_sqe, sizeof(struct lsm6dsvxxx_fifo_data), + sizeof(struct lsm6dsvxxx_fifo_data), &buf, &buf_len) != 0) { + rtio_iodev_sqe_err(data->streaming_sqe, -ENOMEM); + data->streaming_sqe = NULL; + lsm6dsvxxx_gpio_pin_enable(cfg, irq_gpio); + return; + } + + struct lsm6dsvxxx_fifo_data *rx_data = (struct lsm6dsvxxx_fifo_data *)buf; + + memset(buf, 0, buf_len); + rx_data->header.cfg = cfg; + rx_data->header.is_fifo = 1; + rx_data->header.timestamp = data->timestamp; + rx_data->header.int_status = data->fifo_status[1]; + rx_data->fifo_count = 0; + + /* complete request with ok */ + rtio_iodev_sqe_ok(data->streaming_sqe, 0); + data->streaming_sqe = NULL; + lsm6dsvxxx_gpio_pin_enable(cfg, irq_gpio); + + if (data_opt == SENSOR_STREAM_DATA_DROP) { + + /* + * Flush the FIFO by setting the mode to LSM6DSVXXX_BYPASS_MODE + * + * STMEMSC API equivalent code: + * + * lsm6dsvxxx_fifo_mode_set(ctx, LSM6DSVXXX_BYPASS_MODE); + */ + struct rtio_sqe *write_fifo_mode = rtio_sqe_acquire(rtio); + uint8_t lsm6dsvxxx_fifo_mode_set[] = { + LSM6DSVXXX_FIFO_CTRL4, + LSM6DSVXXX_BYPASS_MODE, + }; + + write_fifo_mode->flags |= RTIO_SQE_NO_RESPONSE; + rtio_sqe_prep_tiny_write(write_fifo_mode, iodev, + RTIO_PRIO_NORM, lsm6dsvxxx_fifo_mode_set, + ARRAY_SIZE(lsm6dsvxxx_fifo_mode_set), NULL); + + rtio_submit(rtio, 0); + } + + return; + } + + uint8_t *buf, *read_buf; + uint32_t buf_len, buf_avail; + uint32_t req_len = LSM6DSVXXX_FIFO_SIZE(fifo_count) + sizeof(struct lsm6dsvxxx_fifo_data); + + if (rtio_sqe_rx_buf(data->streaming_sqe, req_len, req_len, &buf, &buf_len) != 0) { + LOG_ERR("Failed to get buffer"); + rtio_iodev_sqe_err(data->streaming_sqe, -ENOMEM); + data->streaming_sqe = NULL; + lsm6dsvxxx_gpio_pin_enable(cfg, irq_gpio); + return; + } + + /* clang-format off */ + struct lsm6dsvxxx_fifo_data hdr = { + .header = { + .cfg = cfg, + .is_fifo = true, + .accel_fs = data->accel_fs, + .gyro_fs = data->gyro_fs, + .timestamp = data->timestamp, + }, + .fifo_count = fifo_count, + .accel_batch_odr = data->accel_batch_odr, + .gyro_batch_odr = data->gyro_batch_odr, +#if defined(CONFIG_LSM6DSVXXX_ENABLE_TEMP) + .temp_batch_odr = data->temp_batch_odr, +#endif + .sflp_batch_odr = data->sflp_batch_odr, + }; + /* clang-format on */ + + memcpy(buf, &hdr, sizeof(hdr)); + read_buf = buf + sizeof(hdr); + buf_avail = buf_len - sizeof(hdr); + + uint8_t reg_addr = lsm6dsvxxx_bus_reg(data->bus_type, LSM6DSVXXX_FIFO_DATA_OUT_TAG); + struct rtio_regs fifo_regs; + struct rtio_regs_list regs_list[] = { + { + reg_addr, + read_buf, + buf_avail, + }, + }; + + fifo_regs.rtio_regs_list = regs_list; + fifo_regs.rtio_regs_num = ARRAY_SIZE(regs_list); + + /* + * Prepare rtio enabled bus to read all fifo_count entries from + * LSM6DSVXXX_FIFO_DATA_OUT_TAG. Then lsm6dsvxxx_complete_op_cb + * callback will be invoked. + * + * STMEMSC API equivalent code: + * + * num = fifo_status.fifo_level; + * + * while (num--) { + * lsm6dsvxxx_fifo_out_raw_t f_data; + * + * lsm6dsvxxx_fifo_out_raw_get(&dev_ctx, &f_data); + * } + */ + rtio_read_regs_async(data->rtio_ctx, data->iodev, data->bus_type, + &fifo_regs, data->streaming_sqe, dev, lsm6dsvxxx_complete_op_cb); +} + +/* + * Called by bus driver to complete the LSM6DSVXXX_STATUS_REG read op. + * If drdy_xl is active it reads XL data (6 bytes) from LSM6DSVXXX_OUTX_L_A reg. + */ +static void lsm6dsvxxx_read_status_cb(struct rtio *r, const struct rtio_sqe *sqe, + int result, void *arg) +{ + ARG_UNUSED(result); + + const struct device *dev = arg; + const struct lsm6dsvxxx_config *config = dev->config; + struct lsm6dsvxxx_data *data = dev->data; + struct rtio *rtio = data->rtio_ctx; + const struct gpio_dt_spec *irq_gpio = data->drdy_gpio; + struct sensor_read_config *read_config; + + /* At this point, no sqe request is queued should be considered as a bug */ + __ASSERT_NO_MSG(data->streaming_sqe != NULL); + + read_config = (struct sensor_read_config *)data->streaming_sqe->sqe.iodev->data; + __ASSERT_NO_MSG(read_config != NULL); + __ASSERT_NO_MSG(read_config->is_streaming == true); + + /* parse the configuration in search for any configured trigger */ + struct sensor_stream_trigger *data_ready = NULL; + + for (int i = 0; i < read_config->count; ++i) { + if (read_config->triggers[i].trigger == SENSOR_TRIG_DATA_READY) { + data_ready = &read_config->triggers[i]; + break; + } + } + + /* flush completion */ + int res = 0; + + res = rtio_flush_completion_queue(rtio); + + if (res != 0) { + rtio_iodev_sqe_err(data->streaming_sqe, res); + data->streaming_sqe = NULL; + return; + } + + if (data_ready != NULL && + (data_ready->opt == SENSOR_STREAM_DATA_NOP || + data_ready->opt == SENSOR_STREAM_DATA_DROP)) { + uint8_t *buf; + uint32_t buf_len; + + /* Clear streaming_sqe since we're done with the call */ + if (rtio_sqe_rx_buf(data->streaming_sqe, sizeof(struct lsm6dsvxxx_fifo_data), + sizeof(struct lsm6dsvxxx_fifo_data), &buf, &buf_len) != 0) { + rtio_iodev_sqe_err(data->streaming_sqe, -ENOMEM); + data->streaming_sqe = NULL; + lsm6dsvxxx_gpio_pin_enable(config, irq_gpio); + return; + } + + struct lsm6dsvxxx_fifo_data *rx_data = (struct lsm6dsvxxx_fifo_data *)buf; + + memset(buf, 0, buf_len); + rx_data->header.cfg = config; + rx_data->header.is_fifo = 1; + rx_data->header.timestamp = data->timestamp; + rx_data->header.int_status = data->fifo_status[1]; + rx_data->fifo_count = 0; + + /* complete request with ok */ + rtio_iodev_sqe_ok(data->streaming_sqe, 0); + data->streaming_sqe = NULL; + lsm6dsvxxx_gpio_pin_enable(config, irq_gpio); + + if (data_ready->opt == SENSOR_STREAM_DATA_DROP) { + + /* + * Flush the FIFO by setting the mode to LSM6DSVXXX_BYPASS_MODE + * + * STMEMSC API equivalent code: + * + * lsm6dsvxxx_fifo_mode_set(ctx, LSM6DSVXXX_BYPASS_MODE); + */ + struct rtio_sqe *write_fifo_mode = rtio_sqe_acquire(rtio); + uint8_t lsm6dsvxxx_fifo_mode_set[] = { + LSM6DSVXXX_FIFO_CTRL4, + LSM6DSVXXX_BYPASS_MODE, + }; + + write_fifo_mode->flags |= RTIO_SQE_NO_RESPONSE; + rtio_sqe_prep_tiny_write(write_fifo_mode, data->iodev, + RTIO_PRIO_NORM, lsm6dsvxxx_fifo_mode_set, + ARRAY_SIZE(lsm6dsvxxx_fifo_mode_set), NULL); + + rtio_submit(rtio, 0); + } + + return; + } + + /* + * Read XL data + * + * STMEMSC API equivalent code: + * + * lsm6dsvxxx_data_ready_t drdy; + * if (drdy.drdy_xl) { + */ + if (data->status & 0x1) { + uint8_t *buf, *read_buf; + uint32_t buf_len; + uint32_t req_len = 6 + sizeof(struct lsm6dsvxxx_rtio_data); + + if (rtio_sqe_rx_buf(data->streaming_sqe, + req_len, req_len, &buf, &buf_len) != 0) { + LOG_ERR("Failed to get buffer"); + rtio_iodev_sqe_err(data->streaming_sqe, -ENOMEM); + data->streaming_sqe = NULL; + lsm6dsvxxx_gpio_pin_enable(config, irq_gpio); + return; + } + + struct lsm6dsvxxx_rtio_data hdr = { + .header = { + .cfg = config, + .is_fifo = false, + .accel_fs = data->accel_fs, + .gyro_fs = data->gyro_fs, + .timestamp = data->timestamp, + }, + .has_accel = 1, + .has_temp = 0, + }; + + memcpy(buf, &hdr, sizeof(hdr)); + read_buf = (uint8_t *)&((struct lsm6dsvxxx_rtio_data *)buf)->accel[0]; + + uint8_t reg_addr = lsm6dsvxxx_bus_reg(data->bus_type, data->out_xl); + struct rtio_regs drdy_regs; + struct rtio_regs_list regs_list[] = { + { + reg_addr, + read_buf, + 6, + }, + }; + + drdy_regs.rtio_regs_list = regs_list; + drdy_regs.rtio_regs_num = ARRAY_SIZE(regs_list); + + /* + * Prepare rtio enabled bus to read LSM6DSVXXX_OUTX_L_A register + * where accelerometer data is available. + * Then lsm6dsvxxx_complete_op_cb callback will be invoked. + * + * STMEMSC API equivalent code: + * + * uint8_t accel_raw[6]; + * + * lsm6dsvxxx_acceleration_raw_get(&dev_ctx, accel_raw); + */ + rtio_read_regs_async(data->rtio_ctx, data->iodev, data->bus_type, + &drdy_regs, data->streaming_sqe, dev, + lsm6dsvxxx_complete_op_cb); + } +} + +/* + * Called when one of the following trigger is active: + * + * - int_fifo_th (SENSOR_TRIG_FIFO_WATERMARK) + * - int_fifo_full (SENSOR_TRIG_FIFO_FULL) + * - int_drdy (SENSOR_TRIG_DATA_READY) + */ +void lsm6dsvxxx_stream_irq_handler(const struct device *dev) +{ + struct lsm6dsvxxx_data *data = dev->data; + uint64_t cycles; + int rc; + + if (data->streaming_sqe == NULL) { + return; + } + + rc = sensor_clock_get_cycles(&cycles); + if (rc != 0) { + LOG_ERR("Failed to get sensor clock cycles"); + rtio_iodev_sqe_err(data->streaming_sqe, rc); + return; + } + + /* get timestamp as soon as the irq is served */ + data->timestamp = sensor_clock_cycles_to_ns(cycles); + + /* handle FIFO triggers */ + if (data->trig_cfg.int_fifo_th || data->trig_cfg.int_fifo_full) { +#if LSM6DSVXXX_ANY_INST_ON_BUS_STATUS_OKAY(i3c) + if (ON_I3C_BUS(config) && (!I3C_INT_PIN(config))) { + /* + * If we are on an I3C bus, then it should be expected that the fifo status + * was already received in the IBI payload and we don't need to read it + * again. + */ + data->fifo_status[0] = data->ibi_payload.fifo_status1; + data->fifo_status[1] = data->ibi_payload.fifo_status2; + + struct rtio_sqe *check_fifo_status_reg = rtio_sqe_acquire(rtio); + + rtio_sqe_prep_callback_no_cqe(check_fifo_status_reg, + data_read_fifo_cb, (void *)dev, NULL); + rtio_submit(rtio, 0); + } else { +#endif + data->fifo_status[0] = data->fifo_status[1] = 0; + + uint8_t reg_addr = + lsm6dsvxxx_bus_reg(data->bus_type, LSM6DSVXXX_FIFO_STATUS1); + struct rtio_regs fifo_regs; + struct rtio_regs_list regs_list[] = { + { + reg_addr, + data->fifo_status, + 2, + }, + }; + + fifo_regs.rtio_regs_list = regs_list; + fifo_regs.rtio_regs_num = ARRAY_SIZE(regs_list); + + /* + * Prepare rtio enabled bus to read LSM6DSVXXX_FIFO_STATUS1 and + * LSM6DSVXXX_FIFO_STATUS2 registers where FIFO threshold condition and + * count are reported. Then lsm6dsvxxx_read_fifo_cb callback will be + * invoked. + * + * STMEMSC API equivalent code: + * + * lsm6dsvxxx_fifo_status_t fifo_status; + * + * lsm6dsvxxx_fifo_status_get(&dev_ctx, &fifo_status); + */ + rtio_read_regs_async(data->rtio_ctx, data->iodev, + data->bus_type, &fifo_regs, + data->streaming_sqe, dev, + lsm6dsvxxx_read_fifo_cb); +#if LSM6DSVXXX_ANY_INST_ON_BUS_STATUS_OKAY(i3c) + } +#endif + } + + /* handle drdy trigger */ + if (data->trig_cfg.int_drdy) { + data->status = 0; + + uint8_t reg_addr = + lsm6dsvxxx_bus_reg(data->bus_type, LSM6DSVXXX_STATUS_REG); + struct rtio_regs drdy_regs; + struct rtio_regs_list regs_list[] = { + { + reg_addr, + &data->status, + 1, + }, + }; + + drdy_regs.rtio_regs_list = regs_list; + drdy_regs.rtio_regs_num = ARRAY_SIZE(regs_list); + + /* + * Prepare rtio enabled bus to read LSM6DSVXXX_STATUS_REG register + * where accelerometer and gyroscope data ready status is available. + * Then data_read_status_cb callback will be invoked. + * + * STMEMSC API equivalent code: + * + * uint8_t val; + * + * data_xl_flag_data_ready_get(&dev_ctx, &val); + */ + rtio_read_regs_async(data->rtio_ctx, data->iodev, + data->bus_type, &drdy_regs, + data->streaming_sqe, dev, + lsm6dsvxxx_read_status_cb); + } +} diff --git a/drivers/sensor/st/lsm6dsvxxx/lsm6dsvxxx_trigger.c b/drivers/sensor/st/lsm6dsvxxx/lsm6dsvxxx_trigger.c new file mode 100644 index 000000000000..dc0159c19914 --- /dev/null +++ b/drivers/sensor/st/lsm6dsvxxx/lsm6dsvxxx_trigger.c @@ -0,0 +1,72 @@ +/* ST Microelectronics LSM6DSVXXX family IMU sensor + * + * Copyright (c) 2025 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + * + * Datasheet: + * https://www.st.com/resource/en/datasheet/lsm6dsv320x.pdf + */ + +#define DT_DRV_COMPAT st_lsm6dsvxxx + +#include +#include +#include +#include + +#include "lsm6dsvxxx.h" +#include "lsm6dsvxxx_rtio.h" + +LOG_MODULE_DECLARE(LSM6DSVXXX, CONFIG_SENSOR_LOG_LEVEL); + +static void lsm6dsvxxx_gpio_callback(const struct device *dev, struct gpio_callback *cb, + uint32_t pins) +{ + struct lsm6dsvxxx_data *lsm6dsvxxx = CONTAINER_OF(cb, struct lsm6dsvxxx_data, gpio_cb); + + ARG_UNUSED(pins); + + gpio_pin_interrupt_configure_dt(lsm6dsvxxx->drdy_gpio, GPIO_INT_DISABLE); + + if (IS_ENABLED(CONFIG_LSM6DSVXXX_STREAM)) { + lsm6dsvxxx_stream_irq_handler(lsm6dsvxxx->dev); + } +} + +int lsm6dsvxxx_init_interrupt(const struct device *dev) +{ + struct lsm6dsvxxx_data *lsm6dsvxxx = dev->data; + const struct lsm6dsvxxx_config *cfg = dev->config; + int ret; + + lsm6dsvxxx->drdy_gpio = (cfg->drdy_pin == 1) ? (const struct gpio_dt_spec *)&cfg->int1_gpio + : (const struct gpio_dt_spec *)&cfg->int2_gpio; + + /* setup data ready gpio interrupt (INT1 or INT2) */ + if (!gpio_is_ready_dt(lsm6dsvxxx->drdy_gpio)) { + LOG_ERR("Cannot get pointer to drdy_gpio device"); + return -ENODEV; + } + + lsm6dsvxxx->dev = dev; + + ret = gpio_pin_configure_dt(lsm6dsvxxx->drdy_gpio, GPIO_INPUT); + if (ret < 0) { + LOG_ERR("Could not configure gpio"); + return ret; + } + + gpio_init_callback(&lsm6dsvxxx->gpio_cb, lsm6dsvxxx_gpio_callback, + BIT(lsm6dsvxxx->drdy_gpio->pin)); + + if (gpio_add_callback(lsm6dsvxxx->drdy_gpio->port, &lsm6dsvxxx->gpio_cb) < 0) { + LOG_DBG("Could not set gpio callback"); + return -EIO; + } + + /* set drdy mode on int1/int2 */ + cfg->chip_api->drdy_mode_set(dev); + + return gpio_pin_interrupt_configure_dt(lsm6dsvxxx->drdy_gpio, GPIO_INT_EDGE_TO_ACTIVE); +} diff --git a/include/zephyr/dt-bindings/sensor/lsm6dsvxxx.h b/include/zephyr/dt-bindings/sensor/lsm6dsvxxx.h index ac8db9fa612d..0c080a56177e 100644 --- a/include/zephyr/dt-bindings/sensor/lsm6dsvxxx.h +++ b/include/zephyr/dt-bindings/sensor/lsm6dsvxxx.h @@ -95,4 +95,45 @@ #define LSM6DSVXXX_DT_SFLP_FIFO_GRAVITY_GBIAS 0x6 #define LSM6DSVXXX_DT_SFLP_FIFO_GAME_ROTATION_GRAVITY_GBIAS 0x7 +/* FIFO tags */ +#define LSM6DSVXXX_FIFO_EMPTY 0x0 +#define LSM6DSVXXX_GY_NC_TAG 0x1 +#define LSM6DSVXXX_XL_NC_TAG 0x2 +#define LSM6DSVXXX_TEMPERATURE_TAG 0x3 +#define LSM6DSVXXX_TIMESTAMP_TAG 0x4 +#define LSM6DSVXXX_CFG_CHANGE_TAG 0x5 +#define LSM6DSVXXX_XL_NC_T_2_TAG 0x6 +#define LSM6DSVXXX_XL_NC_T_1_TAG 0x7 +#define LSM6DSVXXX_XL_2XC_TAG 0x8 +#define LSM6DSVXXX_XL_3XC_TAG 0x9 +#define LSM6DSVXXX_GY_NC_T_2_TAG 0xA +#define LSM6DSVXXX_GY_NC_T_1_TAG 0xB +#define LSM6DSVXXX_GY_2XC_TAG 0xC +#define LSM6DSVXXX_GY_3XC_TAG 0xD +#define LSM6DSVXXX_SENSORHUB_TARGET0_TAG 0xE +#define LSM6DSVXXX_SENSORHUB_TARGET1_TAG 0xF +#define LSM6DSVXXX_SENSORHUB_TARGET2_TAG 0x10 +#define LSM6DSVXXX_SENSORHUB_TARGET3_TAG 0x11 +#define LSM6DSVXXX_STEP_COUNTER_TAG 0x12 +#define LSM6DSVXXX_SFLP_GAME_ROTATION_VECTOR_TAG 0x13 +#define LSM6DSVXXX_SFLP_GYROSCOPE_BIAS_TAG 0x16 +#define LSM6DSVXXX_SFLP_GRAVITY_VECTOR_TAG 0x17 +#define LSM6DSVXXX_HG_XL_PEAK_TAG 0x18 +#define LSM6DSVXXX_SENSORHUB_NACK_TAG 0x19 +#define LSM6DSVXXX_MLC_RESULT_TAG 0x1A +#define LSM6DSVXXX_MLC_FILTER 0x1B +#define LSM6DSVXXX_MLC_FEATURE 0x1C +#define LSM6DSVXXX_XL_HG_TAG 0x1D +#define LSM6DSVXXX_GY_ENHANCED_EIS 0x1E + +/* status registers */ +#define LSM6DSVXXX_STATUS_REG 0x1EU +#define LSM6DSVXXX_OUTX_L_A 0x28U +#define LSM6DSVXXX_FIFO_STATUS1 0x1BU +#define LSM6DSVXXX_FIFO_DATA_OUT_TAG 0x78U + +/* FIFO settings */ +#define LSM6DSVXXX_BYPASS_MODE 0x00U +#define LSM6DSVXXX_FIFO_CTRL4 0x0AU + #endif /* ZEPHYR_INCLUDE_DT_BINDINGS_ST_LSM6DSVXXX_H_ */ From b66fc31c953c36702ca6e5d4cd181f131b604afa Mon Sep 17 00:00:00 2001 From: Armando Visconti Date: Thu, 23 Oct 2025 16:36:18 +0200 Subject: [PATCH 1532/3659] drivers/sensor: lsm6dsvxxx: add lsm6dsv80x support Add support to lsm6dsv80x sensor variant of LSM6DSVXXX driver. More information: https://www.st.com/resource/en/datasheet/lsm6dsv80x.pdf Signed-off-by: Armando Visconti --- drivers/sensor/st/lsm6dsvxxx/CMakeLists.txt | 1 + drivers/sensor/st/lsm6dsvxxx/Kconfig | 12 +- drivers/sensor/st/lsm6dsvxxx/lsm6dsv80x.c | 834 ++++++++++++++++++ drivers/sensor/st/lsm6dsvxxx/lsm6dsv80x.h | 25 + drivers/sensor/st/lsm6dsvxxx/lsm6dsvxxx.c | 8 + drivers/sensor/st/lsm6dsvxxx/lsm6dsvxxx.h | 8 +- .../sensor/st/lsm6dsvxxx/lsm6dsvxxx_decoder.c | 1 + dts/bindings/sensor/st,lsm6dsv80x-common.yaml | 74 ++ dts/bindings/sensor/st,lsm6dsv80x-i2c.yaml | 10 + dts/bindings/sensor/st,lsm6dsv80x-i3c.yaml | 24 + dts/bindings/sensor/st,lsm6dsv80x-spi.yaml | 10 + .../zephyr/dt-bindings/sensor/lsm6dsv80x.h | 35 + modules/hal_st/Kconfig | 3 + tests/drivers/build_all/sensor/i2c.dtsi | 12 + 14 files changed, 1052 insertions(+), 5 deletions(-) create mode 100644 drivers/sensor/st/lsm6dsvxxx/lsm6dsv80x.c create mode 100644 drivers/sensor/st/lsm6dsvxxx/lsm6dsv80x.h create mode 100644 dts/bindings/sensor/st,lsm6dsv80x-common.yaml create mode 100644 dts/bindings/sensor/st,lsm6dsv80x-i2c.yaml create mode 100644 dts/bindings/sensor/st,lsm6dsv80x-i3c.yaml create mode 100644 dts/bindings/sensor/st,lsm6dsv80x-spi.yaml create mode 100644 include/zephyr/dt-bindings/sensor/lsm6dsv80x.h diff --git a/drivers/sensor/st/lsm6dsvxxx/CMakeLists.txt b/drivers/sensor/st/lsm6dsvxxx/CMakeLists.txt index 8904293e74d7..d36c15466303 100644 --- a/drivers/sensor/st/lsm6dsvxxx/CMakeLists.txt +++ b/drivers/sensor/st/lsm6dsvxxx/CMakeLists.txt @@ -12,5 +12,6 @@ zephyr_library_sources_ifdef(CONFIG_LSM6DSVXXX_STREAM lsm6dsvxxx_stream.c) zephyr_library_sources_ifdef(CONFIG_LSM6DSVXXX_TRIGGER lsm6dsvxxx_trigger.c) zephyr_library_sources_ifdef(CONFIG_DT_HAS_ST_LSM6DSV320X_ENABLED lsm6dsv320x.c) +zephyr_library_sources_ifdef(CONFIG_DT_HAS_ST_LSM6DSV80X_ENABLED lsm6dsv80x.c) zephyr_library_include_directories(../stmemsc) diff --git a/drivers/sensor/st/lsm6dsvxxx/Kconfig b/drivers/sensor/st/lsm6dsvxxx/Kconfig index c1074291de3c..7422321f807c 100644 --- a/drivers/sensor/st/lsm6dsvxxx/Kconfig +++ b/drivers/sensor/st/lsm6dsvxxx/Kconfig @@ -6,13 +6,17 @@ menuconfig LSM6DSVXXX bool "LSM6DSVXXX IMU sensor" default y - depends on DT_HAS_ST_LSM6DSV320X_ENABLED + depends on DT_HAS_ST_LSM6DSV320X_ENABLED || DT_HAS_ST_LSM6DSV80X_ENABLED depends on ZEPHYR_HAL_ST_MODULE - select I2C if $(dt_compat_on_bus,$(DT_COMPAT_ST_LSM6DSV320X),i2c) - select I3C if $(dt_compat_on_bus,$(DT_COMPAT_ST_LSM6DSV320X),i3c) - select SPI if $(dt_compat_on_bus,$(DT_COMPAT_ST_LSM6DSV320X),spi) + select I2C if $(dt_compat_on_bus,$(DT_COMPAT_ST_LSM6DSV320X),i2c) ||\ + $(dt_compat_on_bus,$(DT_COMPAT_ST_LSM6DSV80X),i2c) + select I3C if $(dt_compat_on_bus,$(DT_COMPAT_ST_LSM6DSV320X),i3c) ||\ + $(dt_compat_on_bus,$(DT_COMPAT_ST_LSM6DSV80X),i3c) + select SPI if $(dt_compat_on_bus,$(DT_COMPAT_ST_LSM6DSV320X),spi) ||\ + $(dt_compat_on_bus,$(DT_COMPAT_ST_LSM6DSV80X),spi) select HAS_STMEMSC select USE_STDC_LSM6DSV320X if DT_HAS_ST_LSM6DSV320X_ENABLED + select USE_STDC_LSM6DSV80X if DT_HAS_ST_LSM6DSV80X_ENABLED help Enable driver for LSM6DSVXXX family IMU sensors. diff --git a/drivers/sensor/st/lsm6dsvxxx/lsm6dsv80x.c b/drivers/sensor/st/lsm6dsvxxx/lsm6dsv80x.c new file mode 100644 index 000000000000..581bdfa1a231 --- /dev/null +++ b/drivers/sensor/st/lsm6dsvxxx/lsm6dsv80x.c @@ -0,0 +1,834 @@ +/* ST Microelectronics LSM6DSVXXX family IMU sensor + * + * Copyright (c) 2025 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + * + * Datasheet: + * https://www.st.com/resource/en/datasheet/lsm6dsv80x.pdf + */ + +#include "lsm6dsv80x.h" +#include + +LOG_MODULE_DECLARE(LSM6DSVXXX, CONFIG_SENSOR_LOG_LEVEL); + +static bool lsm6dsv80x_is_std_fs(uint8_t fs) +{ + return (fs < 4); /* 2g/4g/8g/16g */ +} + +static bool lsm6dsv80x_is_hg_fs(uint8_t fs) +{ + return (fs >= 4 && fs <= 6); /* 32g/64g/80g */ +} + +/* + * XL configuration + */ + +static uint16_t lsm6dsv80x_accel_gain_ug(uint8_t fs) +{ + return (61 * (1 << fs)); +} + +/* The first nibble of fs tells if it is High-G or not */ +static int lsm6dsv80x_accel_range_to_fs_val(const struct device *dev, int32_t range, uint8_t *fs) +{ + switch (range) { + case LSM6DSV80X_DT_FS_2G: + *fs = 0; + break; + + case LSM6DSV80X_DT_FS_4G: + *fs = 1; + break; + + case LSM6DSV80X_DT_FS_8G: + *fs = 2; + break; + + case LSM6DSV80X_DT_FS_16G: + *fs = 3; + break; + + case LSM6DSV80X_DT_FS_32G: + *fs = 4; + break; + + case LSM6DSV80X_DT_FS_64G: + *fs = 5; + break; + + case LSM6DSV80X_DT_FS_80G: + *fs = 6; + break; + + default: + return -EINVAL; + } + + return 0; +} + +static int lsm6dsv80x_accel_set_fs_raw(const struct device *dev, uint8_t fs) +{ + const struct lsm6dsvxxx_config *cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + struct lsm6dsvxxx_data *data = dev->data; + + if (lsm6dsv80x_is_std_fs(fs)) { /* 2g/4g/8g/16g */ + lsm6dsv80x_xl_full_scale_t val = fs; + + if (lsm6dsv80x_xl_full_scale_set(ctx, val) < 0) { + return -EIO; + } + + data->out_xl = LSM6DSV80X_OUTX_L_A; + } else if (lsm6dsv80x_is_hg_fs(fs)) { /* 32g/64g/80g */ + lsm6dsv80x_hg_xl_full_scale_t val = (fs - 4); + + if (lsm6dsv80x_hg_xl_full_scale_set(ctx, val) < 0) { + return -EIO; + } + + data->out_xl = LSM6DSV80X_UI_OUTX_L_A_HG; + } else { + return -EINVAL; + } + + data->accel_fs = fs; + data->acc_gain = lsm6dsv80x_accel_gain_ug(fs); + + return 0; +} + +static int lsm6dsv80x_accel_set_fs(const struct device *dev, int32_t range) +{ + uint8_t fs; + int ret; + + ret = lsm6dsv80x_accel_range_to_fs_val(dev, range, &fs); + if (ret < 0) { + return ret; + } + + ret = lsm6dsv80x_accel_set_fs_raw(dev, fs); + if (ret < 0) { + return ret; + } + + return 0; +} + +static int lsm6dsv80x_accel_set_odr_raw(const struct device *dev, uint8_t odr) +{ + const struct lsm6dsvxxx_config *cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + struct lsm6dsvxxx_data *data = dev->data; + + if (cfg->accel_hg_odr != LSM6DSV80X_HG_XL_ODR_OFF) { + + if (lsm6dsv80x_hg_xl_data_rate_set(ctx, cfg->accel_hg_odr, 1) < 0) { + return -EIO; + } + } else { + if (lsm6dsv80x_xl_data_rate_set(ctx, odr) < 0) { + return -EIO; + } + } + + data->accel_freq = odr; + + return 0; +} + +/* + * values taken from lsm6dsv80x_data_rate_t in hal/st module. The mode/accuracy + * should be selected through accel-odr property in DT + */ +static const float lsm6dsv80x_odr_map[3][13] = { + /* High Accuracy off */ + {0.0f, 1.875f, 7.5f, 15.0f, 30.0f, 60.0f, 120.0f, 240.0f, 480.0f, 960.0f, 1920.0f, 3840.0f, + 7680.0f}, + + /* High Accuracy 1 */ + {0.0f, 1.875f, 7.5f, 15.625f, 31.25f, 62.5f, 125.0f, 250.0f, 500.0f, 1000.0f, 2000.0f, + 4000.0f, 8000.0f}, + + /* High Accuracy 2 */ + {0.0f, 1.875f, 7.5f, 12.5f, 25.0f, 50.0f, 100.0f, 200.0f, 400.0f, 800.0f, 1600.0f, 800.0f, + 6400.0f}, +}; + +static uint8_t lsm6dsv80x_freq_to_odr_val(const struct device *dev, int32_t freq) +{ + const struct lsm6dsvxxx_config *cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + lsm6dsv80x_data_rate_t odr; + int8_t mode; + size_t i; + + if (lsm6dsv80x_xl_data_rate_get(ctx, &odr) < 0) { + return -EINVAL; + } + + mode = (odr >> 4) & 0xf; + + for (i = 0; i < ARRAY_SIZE(lsm6dsv80x_odr_map[mode]); i++) { + if (freq <= lsm6dsv80x_odr_map[mode][i]) { + LOG_DBG("mode: %d - odr: %d", mode, i); + return i | (mode << 4); + } + } + + return 0xFF; +} + +static int lsm6dsv80x_accel_set_odr(const struct device *dev, int32_t freq) +{ + uint8_t odr; + + odr = lsm6dsv80x_freq_to_odr_val(dev, freq); + if (odr == 0xFF) { + return -EINVAL; + } + + if (lsm6dsv80x_accel_set_odr_raw(dev, odr) < 0) { + LOG_DBG("failed to set accelerometer sampling rate"); + return -EIO; + } + + return 0; +} + +static int32_t lsm6dsv80x_accel_set_mode(const struct device *dev, int32_t mode) +{ + const struct lsm6dsvxxx_config *cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + + switch (mode) { + case 0: /* High Performance */ + mode = LSM6DSV80X_XL_HIGH_PERFORMANCE_MD; + break; + case 1: /* High Accuracy */ + mode = LSM6DSV80X_XL_HIGH_ACCURACY_ODR_MD; + break; + case 3: /* ODR triggered */ + mode = LSM6DSV80X_XL_ODR_TRIGGERED_MD; + break; + case 4: /* Low Power 2 */ + mode = LSM6DSV80X_XL_LOW_POWER_2_AVG_MD; + break; + case 5: /* Low Power 4 */ + mode = LSM6DSV80X_XL_LOW_POWER_4_AVG_MD; + break; + case 6: /* Low Power 8 */ + mode = LSM6DSV80X_XL_LOW_POWER_8_AVG_MD; + break; + case 7: /* Normal */ + mode = LSM6DSV80X_XL_NORMAL_MD; + break; + default: + return -EIO; + } + + return lsm6dsv80x_xl_mode_set(ctx, mode); +} + +static int32_t lsm6dsv80x_accel_get_fs(const struct device *dev, int32_t *range) +{ + return -ENOTSUP; +} + +static int32_t lsm6dsv80x_accel_get_odr(const struct device *dev, int32_t *freq) +{ + return -ENOTSUP; +} + +static int32_t lsm6dsv80x_accel_get_mode(const struct device *dev, int32_t *mode) +{ + const struct lsm6dsvxxx_config *cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + lsm6dsv80x_xl_mode_t md; + + lsm6dsv80x_xl_mode_get(ctx, &md); + + switch (md) { + case LSM6DSV80X_XL_HIGH_PERFORMANCE_MD: + *mode = 0; + break; + case LSM6DSV80X_XL_HIGH_ACCURACY_ODR_MD: + *mode = 1; + break; + case LSM6DSV80X_XL_ODR_TRIGGERED_MD: + *mode = 3; + break; + case LSM6DSV80X_XL_LOW_POWER_2_AVG_MD: + *mode = 4; + break; + case LSM6DSV80X_XL_LOW_POWER_4_AVG_MD: + *mode = 5; + break; + case LSM6DSV80X_XL_LOW_POWER_8_AVG_MD: + *mode = 6; + break; + case LSM6DSV80X_XL_NORMAL_MD: + *mode = 7; + break; + default: + return -EIO; + } + + return 0; +} + +/* + * GY configuration + */ + +static int lsm6dsv80x_gyro_range_to_fs_val(const struct device *dev, int32_t range, uint8_t *fs) +{ + switch (range) { + case 0: + *fs = 0; + break; + + case 250: + *fs = LSM6DSV80X_DT_FS_250DPS; + break; + + case 500: + *fs = LSM6DSV80X_DT_FS_500DPS; + break; + + case 1000: + *fs = LSM6DSV80X_DT_FS_1000DPS; + break; + + case 2000: + *fs = LSM6DSV80X_DT_FS_2000DPS; + break; + + case 4000: + *fs = LSM6DSV80X_DT_FS_4000DPS; + break; + + default: + return -EINVAL; + } + + return 0; +} + +static uint32_t lsm6dsv80x_gyro_gain_udps(uint8_t fs) +{ + return (4375 * (1 << fs)); +} + +static int lsm6dsv80x_gyro_set_fs_raw(const struct device *dev, uint8_t fs) +{ + const struct lsm6dsvxxx_config *cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + struct lsm6dsvxxx_data *data = dev->data; + + if (fs == 0) { + /* skip power-up value */ + return 0; + } + + if (lsm6dsv80x_gy_full_scale_set(ctx, fs) < 0) { + return -EIO; + } + + data->gyro_fs = fs; + data->gyro_gain = lsm6dsv80x_gyro_gain_udps(fs); + return 0; +} + +static int lsm6dsv80x_gyro_set_fs(const struct device *dev, int32_t range) +{ + uint8_t fs; + int ret; + + ret = lsm6dsv80x_gyro_range_to_fs_val(dev, range, &fs); + if (ret < 0) { + return ret; + } + + if (lsm6dsv80x_gyro_set_fs_raw(dev, fs) < 0) { + return -EIO; + } + + return 0; +} + +static int lsm6dsv80x_gyro_set_odr_raw(const struct device *dev, uint8_t odr) +{ + const struct lsm6dsvxxx_config *cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + struct lsm6dsvxxx_data *data = dev->data; + + if (lsm6dsv80x_gy_data_rate_set(ctx, odr) < 0) { + return -EIO; + } + + data->gyro_freq = odr; + return 0; +} + +static int lsm6dsv80x_gyro_set_odr(const struct device *dev, int32_t freq) +{ + uint8_t odr; + + odr = lsm6dsv80x_freq_to_odr_val(dev, freq); + if (odr == 0xFF) { + return -EINVAL; + } + + if (lsm6dsv80x_gyro_set_odr_raw(dev, odr) < 0) { + LOG_DBG("failed to set gyroscope sampling rate"); + return -EIO; + } + + return 0; +} + +static int32_t lsm6dsv80x_gyro_set_mode(const struct device *dev, int32_t mode) +{ + const struct lsm6dsvxxx_config *cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + + switch (mode) { + case 0: /* High Performance */ + mode = LSM6DSV80X_GY_HIGH_PERFORMANCE_MD; + break; + case 1: /* High Accuracy */ + mode = LSM6DSV80X_GY_HIGH_ACCURACY_ODR_MD; + break; + case 4: /* Sleep */ + mode = LSM6DSV80X_GY_SLEEP_MD; + break; + case 5: /* Low Power */ + mode = LSM6DSV80X_GY_LOW_POWER_MD; + break; + default: + return -EIO; + } + + return lsm6dsv80x_gy_mode_set(ctx, mode); +} + +static int32_t lsm6dsv80x_gyro_get_fs(const struct device *dev, int32_t *range) +{ + return -ENOTSUP; +} + +static int32_t lsm6dsv80x_gyro_get_odr(const struct device *dev, int32_t *freq) +{ + return -ENOTSUP; +} + +static int32_t lsm6dsv80x_gyro_get_mode(const struct device *dev, int32_t *mode) +{ + const struct lsm6dsvxxx_config *cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + lsm6dsv80x_gy_mode_t md; + + lsm6dsv80x_gy_mode_get(ctx, &md); + + switch (md) { + case LSM6DSV80X_GY_HIGH_PERFORMANCE_MD: + *mode = 0; + break; + case LSM6DSV80X_GY_HIGH_ACCURACY_ODR_MD: + *mode = 1; + break; + case LSM6DSV80X_GY_SLEEP_MD: + *mode = 4; + break; + case LSM6DSV80X_GY_LOW_POWER_MD: + *mode = 5; + break; + default: + return -EIO; + } + + return 0; +} + +#if defined(CONFIG_LSM6DSVXXX_TRIGGER) +int32_t lsm6dsv80x_drdy_mode_set(const struct device *dev) +{ + const struct lsm6dsvxxx_config *config = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&config->ctx; + + /* enable drdy on int1/int2 in pulse mode */ + lsm6dsv80x_data_ready_mode_t drdy = + (config->drdy_pulsed) ? LSM6DSV80X_DRDY_PULSED : LSM6DSV80X_DRDY_LATCHED; + if (lsm6dsv80x_data_ready_mode_set(ctx, drdy)) { + return -EIO; + } + + return 0; +} +#endif /* CONFIG_LSM6DSVXXX_TRIGGER */ + +/* init routine */ +static int lsm6dsv80x_init_chip(const struct device *dev) +{ + const struct lsm6dsvxxx_config *cfg = dev->config; + struct lsm6dsvxxx_data *data = dev->data; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + uint8_t chip_id; + uint8_t odr, fs; + +#if LSM6DSVXXX_ANY_INST_ON_BUS_STATUS_OKAY(i3c) + if (cfg->i3c.bus != NULL) { + /* + * Need to grab the pointer to the I3C device descriptor + * before we can talk to the sensor. + */ + lsm6dsvxxx->i3c_dev = i3c_device_find(cfg->i3c.bus, &cfg->i3c.dev_id); + if (lsm6dsvxxx->i3c_dev == NULL) { + LOG_ERR("Cannot find I3C device descriptor"); + return -ENODEV; + } + } +#endif + + /* All registers except 0x01 are different between banks, including the WHO_AM_I + * register and the register used for a SW reset. If the lsm6dsvxxx wasn't on the user + * bank when it reset, then both the chip id check and the sw reset will fail unless we + * set the bank now. + */ + if (lsm6dsv80x_mem_bank_set(ctx, LSM6DSV80X_MAIN_MEM_BANK) < 0) { + LOG_DBG("Failed to set user bank"); + return -EIO; + } + + if (lsm6dsv80x_device_id_get(ctx, &chip_id) < 0) { + LOG_DBG("Failed reading chip id"); + return -EIO; + } + + LOG_INF("chip id 0x%x", chip_id); + + if (chip_id != LSM6DSV80X_ID) { + LOG_DBG("Invalid chip id 0x%x", chip_id); + return -EIO; + } + + /* Resetting the whole device while using I3C will also reset the DA, therefore perform + * only a software reset if the bus is I3C. It should be assumed that the device was + * already fully reset by the I3C CCC RSTACT (whole chip) done as apart of the I3C Bus + * initialization. + */ + if (ON_I3C_BUS(cfg)) { + /* Restore default configuration */ + lsm6dsv80x_reboot(ctx); + + /* wait 150us as reported in AN5763 */ + k_sleep(K_USEC(150)); + } else { + /* reset device (sw_por) */ + if (lsm6dsv80x_sw_por(ctx) < 0) { + return -EIO; + } + + /* wait 30ms as reported in AN5763 */ + k_sleep(K_MSEC(30)); + } + + data->out_xl = LSM6DSV80X_OUTX_L_A; + data->out_tp = LSM6DSV80X_OUT_TEMP_L; + + fs = cfg->accel_range; + LOG_DBG("accel range is %d", fs); + if (lsm6dsv80x_accel_set_fs_raw(dev, fs) < 0) { + LOG_ERR("failed to set accelerometer range %d", fs); + return -EIO; + } + + odr = cfg->accel_odr; + LOG_DBG("accel odr is %d", odr); + if (lsm6dsv80x_accel_set_odr_raw(dev, odr) < 0) { + LOG_ERR("failed to set accelerometer odr %d", odr); + return -EIO; + } + + fs = cfg->gyro_range; + LOG_DBG("gyro range is %d", fs); + if (lsm6dsv80x_gyro_set_fs_raw(dev, fs) < 0) { + LOG_ERR("failed to set gyroscope range %d", fs); + return -EIO; + } + + odr = cfg->gyro_odr; + LOG_DBG("gyro odr is %d", odr); + if (lsm6dsv80x_gyro_set_odr_raw(dev, odr) < 0) { + LOG_ERR("failed to set gyroscope odr %d", odr); + return -EIO; + } + +#if LSM6DSVXXX_ANY_INST_ON_BUS_STATUS_OKAY(i3c) + if (IS_ENABLED(CONFIG_LSM6DSVXXX_STREAM) && (ON_I3C_BUS(cfg))) { + /* + * Set MRL to the Max Size of the FIFO so the entire FIFO can be read + * out at once + */ + struct i3c_ccc_mrl setmrl = { + .len = 0x0700, + .ibi_len = lsm6dsvxxx->i3c_dev->data_length.max_ibi, + }; + if (i3c_ccc_do_setmrl(lsm6dsvxxx->i3c_dev, &setmrl) < 0) { + LOG_ERR("failed to set mrl"); + return -EIO; + } + } +#endif + + if (lsm6dsv80x_block_data_update_set(ctx, 1) < 0) { + LOG_DBG("failed to set BDU mode"); + return -EIO; + } + + return 0; +} + +#if defined(CONFIG_PM_DEVICE) +static int lsm6dsv80x_pm_action(const struct device *dev, enum pm_device_action action) +{ + struct lsm6dsvxxx_data *data = dev->data; + const struct lsm6dsvxxx_config *cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + int ret = 0; + + LOG_DBG("PM action: %d", (int)action); + + switch (action) { + case PM_DEVICE_ACTION_RESUME: + if (lsm6dsv80x_xl_data_rate_set(ctx, data->accel_freq) < 0) { + LOG_ERR("failed to set accelerometer odr %d", (int)data->accel_freq); + ret = -EIO; + } + if (lsm6dsv80x_gy_data_rate_set(ctx, data->gyro_freq) < 0) { + LOG_ERR("failed to set gyroscope odr %d", (int)data->gyro_freq); + ret = -EIO; + } + break; + case PM_DEVICE_ACTION_SUSPEND: + if (lsm6dsv80x_xl_data_rate_set(ctx, LSM6DSVXXX_DT_ODR_OFF) < 0) { + LOG_ERR("failed to disable accelerometer"); + ret = -EIO; + } + if (lsm6dsv80x_gy_data_rate_set(ctx, LSM6DSVXXX_DT_ODR_OFF) < 0) { + LOG_ERR("failed to disable gyroscope"); + ret = -EIO; + } + break; + default: + ret = -ENOTSUP; + break; + } + + return ret; +} +#endif /* CONFIG_PM_DEVICE */ + +#if defined(CONFIG_LSM6DSVXXX_STREAM) +static void lsm6dsv80x_config_fifo(const struct device *dev, struct trigger_config trig_cfg) +{ + struct lsm6dsvxxx_data *data = dev->data; + const struct lsm6dsvxxx_config *config = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&config->ctx; + uint8_t fifo_wtm = 0; + lsm6dsv80x_pin_int_route_t pin_int = {0}; + lsm6dsv80x_fifo_xl_batch_t xl_batch = LSM6DSVXXX_DT_XL_NOT_BATCHED; + lsm6dsv80x_fifo_gy_batch_t gy_batch = LSM6DSVXXX_DT_GY_NOT_BATCHED; + lsm6dsv80x_fifo_temp_batch_t temp_batch = LSM6DSVXXX_DT_TEMP_NOT_BATCHED; + lsm6dsv80x_fifo_mode_t fifo_mode = LSM6DSV80X_BYPASS_MODE; + lsm6dsv80x_sflp_data_rate_t sflp_odr = LSM6DSV80X_SFLP_120Hz; + lsm6dsv80x_fifo_sflp_raw_t sflp_fifo = {0}; + lsm6dsv80x_sflp_gbias_t gbias; + + /* disable FIFO as first thing */ + lsm6dsv80x_fifo_mode_set(ctx, LSM6DSV80X_BYPASS_MODE); + + pin_int.fifo_th = PROPERTY_DISABLE; + pin_int.fifo_full = PROPERTY_DISABLE; + + if (trig_cfg.int_fifo_th || trig_cfg.int_fifo_full) { + pin_int.fifo_th = (trig_cfg.int_fifo_th) ? PROPERTY_ENABLE : PROPERTY_DISABLE; + pin_int.fifo_full = (trig_cfg.int_fifo_full) ? PROPERTY_ENABLE : PROPERTY_DISABLE; + + xl_batch = config->accel_batch; + gy_batch = config->gyro_batch; + temp_batch = config->temp_batch; + + fifo_mode = LSM6DSV80X_STREAM_MODE; + fifo_wtm = config->fifo_wtm; + + if (config->sflp_fifo_en & LSM6DSVXXX_DT_SFLP_FIFO_GAME_ROTATION) { + sflp_fifo.game_rotation = 1; + } + + if (config->sflp_fifo_en & LSM6DSVXXX_DT_SFLP_FIFO_GRAVITY) { + sflp_fifo.gravity = 1; + } + + if (config->sflp_fifo_en & LSM6DSVXXX_DT_SFLP_FIFO_GBIAS) { + sflp_fifo.gbias = 1; + } + + sflp_odr = config->sflp_odr; + } + + /* + * Set FIFO watermark (number of unread sensor data TAG + 6 bytes + * stored in FIFO) to FIFO_WATERMARK samples + */ + lsm6dsv80x_fifo_watermark_set(ctx, config->fifo_wtm); + + /* Turn on/off FIFO */ + lsm6dsv80x_fifo_mode_set(ctx, fifo_mode); + + /* Set FIFO batch rates */ + lsm6dsv80x_fifo_xl_batch_set(ctx, xl_batch); + data->accel_batch_odr = xl_batch; + lsm6dsv80x_fifo_gy_batch_set(ctx, gy_batch); + data->gyro_batch_odr = gy_batch; +#if defined(CONFIG_LSM6DSVXXX_ENABLE_TEMP) + lsm6dsv80x_fifo_temp_batch_set(ctx, temp_batch); + data->temp_batch_odr = temp_batch; +#endif + + lsm6dsv80x_sflp_data_rate_set(ctx, sflp_odr); + data->sflp_batch_odr = sflp_odr; + lsm6dsv80x_fifo_sflp_batch_set(ctx, sflp_fifo); + lsm6dsv80x_sflp_game_rotation_set(ctx, PROPERTY_ENABLE); + + /* + * Temporarly set Accel and gyro odr same as sensor fusion LP in order to + * make the SFLP gbias setting effective. Then restore it to saved values. + */ + switch (sflp_odr) { + case LSM6DSVXXX_DT_SFLP_ODR_AT_480Hz: + lsm6dsv80x_accel_set_odr_raw(dev, LSM6DSVXXX_DT_ODR_AT_480Hz); + lsm6dsv80x_gyro_set_odr_raw(dev, LSM6DSVXXX_DT_ODR_AT_480Hz); + break; + + case LSM6DSVXXX_DT_SFLP_ODR_AT_240Hz: + lsm6dsv80x_accel_set_odr_raw(dev, LSM6DSVXXX_DT_ODR_AT_240Hz); + lsm6dsv80x_gyro_set_odr_raw(dev, LSM6DSVXXX_DT_ODR_AT_240Hz); + break; + + case LSM6DSVXXX_DT_SFLP_ODR_AT_120Hz: + lsm6dsv80x_accel_set_odr_raw(dev, LSM6DSVXXX_DT_ODR_AT_120Hz); + lsm6dsv80x_gyro_set_odr_raw(dev, LSM6DSVXXX_DT_ODR_AT_120Hz); + break; + + case LSM6DSVXXX_DT_SFLP_ODR_AT_60Hz: + lsm6dsv80x_accel_set_odr_raw(dev, LSM6DSVXXX_DT_ODR_AT_60Hz); + lsm6dsv80x_gyro_set_odr_raw(dev, LSM6DSVXXX_DT_ODR_AT_60Hz); + break; + + case LSM6DSVXXX_DT_SFLP_ODR_AT_30Hz: + lsm6dsv80x_accel_set_odr_raw(dev, LSM6DSVXXX_DT_ODR_AT_30Hz); + lsm6dsv80x_gyro_set_odr_raw(dev, LSM6DSVXXX_DT_ODR_AT_30Hz); + break; + + case LSM6DSVXXX_DT_SFLP_ODR_AT_15Hz: + default: + lsm6dsv80x_accel_set_odr_raw(dev, LSM6DSVXXX_DT_ODR_AT_15Hz); + lsm6dsv80x_gyro_set_odr_raw(dev, LSM6DSVXXX_DT_ODR_AT_15Hz); + break; + } + + /* set sflp gbias */ + gbias.gbias_x = (float)data->gbias_x_udps / 1000000; + gbias.gbias_y = (float)data->gbias_y_udps / 1000000; + gbias.gbias_z = (float)data->gbias_z_udps / 1000000; + lsm6dsv80x_sflp_game_gbias_set(ctx, &gbias); + + /* restore accel/gyro odr to saved values */ + lsm6dsv80x_accel_set_odr_raw(dev, data->accel_freq); + lsm6dsv80x_gyro_set_odr_raw(dev, data->gyro_freq); + + /* Set pin interrupt (fifo_th could be on or off) */ + if ((config->drdy_pin == 1) || (ON_I3C_BUS(config) && (!I3C_INT_PIN(config)))) { + lsm6dsv80x_pin_int1_route_set(ctx, &pin_int); + } else { + lsm6dsv80x_pin_int2_route_set(ctx, &pin_int); + } +} + +static void lsm6dsv80x_config_drdy(const struct device *dev, struct trigger_config trig_cfg) +{ + const struct lsm6dsvxxx_config *config = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&config->ctx; + lsm6dsv80x_pin_int_route_t pin_int = {0}; + + pin_int.drdy_xl = (trig_cfg.int_drdy) ? PROPERTY_ENABLE : PROPERTY_DISABLE; + + /* Set pin interrupt (fifo_th could be on or off) */ + if ((config->drdy_pin == 1) || (ON_I3C_BUS(config) && (!I3C_INT_PIN(config)))) { + lsm6dsv80x_pin_int1_route_set(ctx, &pin_int); + } else { + lsm6dsv80x_pin_int2_route_set(ctx, &pin_int); + } +} +#endif /* CONFIG_LSM6DSVXXX_STREAM */ + +const struct lsm6dsvxxx_chip_api st_lsm6dsv80x_chip_api = { + .init_chip = lsm6dsv80x_init_chip, +#if defined(CONFIG_LSM6DSVXXX_TRIGGER) + .drdy_mode_set = lsm6dsv80x_drdy_mode_set, +#endif /* CONFIG_LSM6DSVXXX_TRIGGER */ +#if defined(CONFIG_PM_DEVICE) + .pm_action = lsm6dsv80x_pm_action, +#endif /* CONFIG_PM_DEVICE */ + .accel_fs_set = lsm6dsv80x_accel_set_fs, + .accel_odr_set = lsm6dsv80x_accel_set_odr, + .accel_mode_set = lsm6dsv80x_accel_set_mode, + .accel_fs_get = lsm6dsv80x_accel_get_fs, + .accel_odr_get = lsm6dsv80x_accel_get_odr, + .accel_mode_get = lsm6dsv80x_accel_get_mode, + .gyro_fs_set = lsm6dsv80x_gyro_set_fs, + .gyro_odr_set = lsm6dsv80x_gyro_set_odr, + .gyro_mode_set = lsm6dsv80x_gyro_set_mode, + .gyro_fs_get = lsm6dsv80x_gyro_get_fs, + .gyro_odr_get = lsm6dsv80x_gyro_get_odr, + .gyro_mode_get = lsm6dsv80x_gyro_get_mode, +#if defined(CONFIG_LSM6DSVXXX_STREAM) + .config_fifo = lsm6dsv80x_config_fifo, + .config_drdy = lsm6dsv80x_config_drdy, + .from_f16_to_f32 = lsm6dsv80x_from_f16_to_f32, + .from_sflp_to_mg = lsm6dsv80x_from_sflp_to_mg, +#endif /* CONFIG_LSM6DSVXXX_STREAM */ +}; + +/* bit shift for Accelerometer for a given range value */ +const int8_t st_lsm6dsv80x_accel_bit_shift[] = { + 5, /* FS_2G */ + 6, /* FS_4G */ + 7, /* FS_8G */ + 8, /* FS_16G */ + 9, /* FS_32G */ + 10, /* FS_64G */ + 11, /* FS_80G */ +}; + +/* + * Accelerometer scaling factors table for a given range value + * GAIN_UNIT_XL is expressed in ug/LSB. + */ +const int32_t st_lsm6dsv80x_accel_scaler[] = { + SENSOR_SCALE_UG_TO_UMS2(61), /* FS_2G */ + SENSOR_SCALE_UG_TO_UMS2(122), /* FS_4G */ + SENSOR_SCALE_UG_TO_UMS2(244), /* FS_8G */ + SENSOR_SCALE_UG_TO_UMS2(488), /* FS_16G */ + SENSOR_SCALE_UG_TO_UMS2(976), /* FS_32G */ + SENSOR_SCALE_UG_TO_UMS2(1952), /* FS_64G */ + SENSOR_SCALE_UG_TO_UMS2(3904), /* FS_80G */ +}; diff --git a/drivers/sensor/st/lsm6dsvxxx/lsm6dsv80x.h b/drivers/sensor/st/lsm6dsvxxx/lsm6dsv80x.h new file mode 100644 index 000000000000..49ec42171f02 --- /dev/null +++ b/drivers/sensor/st/lsm6dsvxxx/lsm6dsv80x.h @@ -0,0 +1,25 @@ +/* ST Microelectronics LSM6DSVXXX family IMU sensor + * + * Copyright (c) 2025 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + * + * Datasheet: + * https://www.st.com/resource/en/datasheet/lsm6dsv80x.pdf + */ +#ifndef ZEPHYR_DRIVERS_SENSOR_LSM6DSV80X_H_ +#define ZEPHYR_DRIVERS_SENSOR_LSM6DSV80X_H_ + +#include +#include + +#include "lsm6dsvxxx.h" +#include "lsm6dsv80x_reg.h" + +#include + +extern const struct lsm6dsvxxx_chip_api st_lsm6dsv80x_chip_api; +extern const int8_t st_lsm6dsv80x_accel_bit_shift[]; +extern const int32_t st_lsm6dsv80x_accel_scaler[]; + +#endif /* ZEPHYR_DRIVERS_SENSOR_LSM6DSV80X_H_ */ diff --git a/drivers/sensor/st/lsm6dsvxxx/lsm6dsvxxx.c b/drivers/sensor/st/lsm6dsvxxx/lsm6dsvxxx.c index 677e44e4adc0..afc745033986 100644 --- a/drivers/sensor/st/lsm6dsvxxx/lsm6dsvxxx.c +++ b/drivers/sensor/st/lsm6dsvxxx/lsm6dsvxxx.c @@ -23,6 +23,10 @@ #include "lsm6dsv320x.h" #endif +#if DT_HAS_COMPAT_STATUS_OKAY(st_lsm6dsv80x) +#include "lsm6dsv80x.h" +#endif + LOG_MODULE_REGISTER(LSM6DSVXXX, CONFIG_SENSOR_LOG_LEVEL); static int lsm6dsvxxx_accel_config(const struct device *dev, @@ -508,3 +512,7 @@ static int lsm6dsvxxx_pm_action(const struct device *dev, enum pm_device_action #define DT_DRV_COMPAT st_lsm6dsv320x DT_INST_FOREACH_STATUS_OKAY_VARGS(LSM6DSVXXX_DEFINE, DT_DRV_COMPAT) #undef DT_DRV_COMPAT + +#define DT_DRV_COMPAT st_lsm6dsv80x +DT_INST_FOREACH_STATUS_OKAY_VARGS(LSM6DSVXXX_DEFINE, DT_DRV_COMPAT) +#undef DT_DRV_COMPAT diff --git a/drivers/sensor/st/lsm6dsvxxx/lsm6dsvxxx.h b/drivers/sensor/st/lsm6dsvxxx/lsm6dsvxxx.h index 019381b43fde..0c262346113a 100644 --- a/drivers/sensor/st/lsm6dsvxxx/lsm6dsvxxx.h +++ b/drivers/sensor/st/lsm6dsvxxx/lsm6dsvxxx.h @@ -24,13 +24,19 @@ #include #define LSM6DSVXXX_ANY_INST_ON_BUS_STATUS_OKAY(bus) \ - (DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_lsm6dsv320x, bus)) + (DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_lsm6dsv320x, bus) ||\ + DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_lsm6dsv80x, bus)) #if DT_HAS_COMPAT_STATUS_OKAY(st_lsm6dsv320x) #include "lsm6dsv320x_reg.h" #include #endif +#if DT_HAS_COMPAT_STATUS_OKAY(st_lsm6dsv80x) +#include "lsm6dsv80x_reg.h" +#include +#endif + #if LSM6DSVXXX_ANY_INST_ON_BUS_STATUS_OKAY(spi) #include #endif /* LSM6DSVXXX_ANY_INST_ON_BUS_STATUS_OKAY(spi) */ diff --git a/drivers/sensor/st/lsm6dsvxxx/lsm6dsvxxx_decoder.c b/drivers/sensor/st/lsm6dsvxxx/lsm6dsvxxx_decoder.c index 63842048ecf3..6ce40f740c13 100644 --- a/drivers/sensor/st/lsm6dsvxxx/lsm6dsvxxx_decoder.c +++ b/drivers/sensor/st/lsm6dsvxxx/lsm6dsvxxx_decoder.c @@ -6,6 +6,7 @@ * * Datasheet: * https://www.st.com/resource/en/datasheet/lsm6dsv320x.pdf + * https://www.st.com/resource/en/datasheet/lsm6dsv80x.pdf */ #include "lsm6dsvxxx.h" diff --git a/dts/bindings/sensor/st,lsm6dsv80x-common.yaml b/dts/bindings/sensor/st,lsm6dsv80x-common.yaml new file mode 100644 index 000000000000..439e2cefea2c --- /dev/null +++ b/dts/bindings/sensor/st,lsm6dsv80x-common.yaml @@ -0,0 +1,74 @@ +# Copyright (c) 2025 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +description: | + When setting the accel-range, accel-odr, gyro-range, gyro-odr properties in + a .dts or .dtsi file you may include lsm6dsv80x.h and use the macros + defined there. + + Example: + #include + + lsm6dsv80x: lsm6dsv80x@0 { + ... + + accel-range = ; + accel-odr = ; + gyro-range = ; + gyro-odr = ; + }; + +include: st,lsm6dsvxxx-common.yaml + +properties: + accel-hg-odr: + type: int + default: 0x0 + description: | + Specify the default accelerometer High-g output data rate expressed in samples per + second (Hz). + The values are taken in accordance to lsm6dsv80x_hg_xl_data_rate_t enumerative in hal/st + module. Please note that this values will not change the operating mode, which will remain + High Performance (device default) + Default is power-up configuration. + + - 0x0 # LSM6DSV80X_HG_XL_ODR_OFF + - 0x3 # LSM6DSV80X_HG_XL_ODR_AT_480Hz + - 0x4 # LSM6DSV80X_HG_XL_ODR_AT_960Hz + - 0x5 # LSM6DSV80X_HG_XL_ODR_AT_1920Hz + - 0x6 # LSM6DSV80X_HG_XL_ODR_AT_3840Hz + - 0x7 # LSM6DSV80X_HG_XL_ODR_AT_7680Hz + + enum: [0x0, 0x3, 0x4, 0x5, 0x6, 0x7] + + accel-range: + type: int + default: 2 + description: | + Range in g. Default is power-up configuration. + Ranges from 32g and above requires the High-g sensor to be turned on (see accel-hg-odr). + + - 2 # LSM6DSV80X_DT_FS_2G (0.061 mg/LSB) + - 4 # LSM6DSV80X_DT_FS_4G (0.122 mg/LSB) + - 8 # LSM6DSV80X_DT_FS_8G (0.244 mg/LSB) + - 16 # LSM6DSV80X_DT_FS_16G (0.488 mg/LSB) + - 32 # LSM6DSV80X_DT_FS_32G (0.976 mg/LSB) + - 64 # LSM6DSV80X_DT_FS_64G (1.952 mg/LSB) + - 80 # LSM6DSV80X_DT_FS_80G (3.904 mg/LSB) + + enum: [2, 4, 8, 16, 32, 64, 80] + + gyro-range: + type: int + default: 0 + description: | + Range in dps. Default is power-up configuration. + + - 0x0 # power-up configuration + - 0x1 # LSM6DSV80X_DT_FS_250DPS (8.75 mdps/LSB) + - 0x2 # LSM6DSV80X_DT_FS_500DPS (17.50 mdps/LSB) + - 0x3 # LSM6DSV80X_DT_FS_1000DPS (35 mdps/LSB) + - 0x4 # LSM6DSV80X_DT_FS_2000DPS (70 mdps/LSB) + - 0x5 # LSM6DSV80X_DT_FS_4000DPS (140 mdps/LSB) + + enum: [0x0, 0x1, 0x2, 0x3, 0x4, 0x5] diff --git a/dts/bindings/sensor/st,lsm6dsv80x-i2c.yaml b/dts/bindings/sensor/st,lsm6dsv80x-i2c.yaml new file mode 100644 index 000000000000..ae722724aba1 --- /dev/null +++ b/dts/bindings/sensor/st,lsm6dsv80x-i2c.yaml @@ -0,0 +1,10 @@ +# Copyright (c) 2025 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +description: | + STMicroelectronics LSM6DSV80X 6-axis IMU (Inertial Measurement Unit) sensor + accessed through I2C bus + +compatible: "st,lsm6dsv80x" + +include: ["i2c-device.yaml", "st,lsm6dsv80x-common.yaml"] diff --git a/dts/bindings/sensor/st,lsm6dsv80x-i3c.yaml b/dts/bindings/sensor/st,lsm6dsv80x-i3c.yaml new file mode 100644 index 000000000000..cf05b3289510 --- /dev/null +++ b/dts/bindings/sensor/st,lsm6dsv80x-i3c.yaml @@ -0,0 +1,24 @@ +# Copyright (c) 2025 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +description: | + STMicroelectronics LSM6DSV80X 6-axis IMU (Inertial Measurement Unit) sensor + accessed through I3C bus + +compatible: "st,lsm6dsv80x" + +include: ["i3c-device.yaml", "st,lsm6dsv80x-common.yaml"] + +properties: + int-en-i3c: + type: boolean + description: | + Enables INT pin when I3C is enabled + + bus-act-sel-us: + type: int + default: 50 + description: | + Bus available time for I3C IBI in microseconds + + enum: [50, 2, 1000, 25000] diff --git a/dts/bindings/sensor/st,lsm6dsv80x-spi.yaml b/dts/bindings/sensor/st,lsm6dsv80x-spi.yaml new file mode 100644 index 000000000000..5354160a21cb --- /dev/null +++ b/dts/bindings/sensor/st,lsm6dsv80x-spi.yaml @@ -0,0 +1,10 @@ +# Copyright (c) 2025 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +description: | + STMicroelectronics LSM6DSV80X 6-axis IMU (Inertial Measurement Unit) sensor + accessed through SPI bus + +compatible: "st,lsm6dsv80x" + +include: ["spi-device.yaml", "st,lsm6dsv80x-common.yaml"] diff --git a/include/zephyr/dt-bindings/sensor/lsm6dsv80x.h b/include/zephyr/dt-bindings/sensor/lsm6dsv80x.h new file mode 100644 index 000000000000..3b54032f201e --- /dev/null +++ b/include/zephyr/dt-bindings/sensor/lsm6dsv80x.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2025 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_ST_LSM6DSV80X_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_ST_LSM6DSV80X_H_ + +#include "lsm6dsvxxx.h" + +/* Accel High-g odr */ +#define LSM6DSV80X_HG_XL_ODR_OFF 0x0 +#define LSM6DSV80X_HG_XL_ODR_AT_480Hz 0x3 +#define LSM6DSV80X_HG_XL_ODR_AT_960Hz 0x4 +#define LSM6DSV80X_HG_XL_ODR_AT_1920Hz 0x5 +#define LSM6DSV80X_HG_XL_ODR_AT_3840Hz 0x6 +#define LSM6DSV80X_HG_XL_ODR_AT_7680Hz 0x7 + +/* Accel range */ +#define LSM6DSV80X_DT_FS_2G 2 +#define LSM6DSV80X_DT_FS_4G 4 +#define LSM6DSV80X_DT_FS_8G 8 +#define LSM6DSV80X_DT_FS_16G 16 +#define LSM6DSV80X_DT_FS_32G 32 +#define LSM6DSV80X_DT_FS_64G 64 +#define LSM6DSV80X_DT_FS_80G 80 + +/* Gyro range */ +#define LSM6DSV80X_DT_FS_250DPS 0x1 +#define LSM6DSV80X_DT_FS_500DPS 0x2 +#define LSM6DSV80X_DT_FS_1000DPS 0x3 +#define LSM6DSV80X_DT_FS_2000DPS 0x4 +#define LSM6DSV80X_DT_FS_4000DPS 0x5 + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_ST_LSM6DSV80X_H_ */ diff --git a/modules/hal_st/Kconfig b/modules/hal_st/Kconfig index 6d32938ba587..cece2d4fec93 100644 --- a/modules/hal_st/Kconfig +++ b/modules/hal_st/Kconfig @@ -195,6 +195,9 @@ config USE_STDC_LSM6DSV16X config USE_STDC_LSM6DSV320X bool +config USE_STDC_LSM6DSV80X + bool + config USE_STDC_LSM9DS1 bool diff --git a/tests/drivers/build_all/sensor/i2c.dtsi b/tests/drivers/build_all/sensor/i2c.dtsi index b7eaa9bf7250..2518cdda7a77 100644 --- a/tests/drivers/build_all/sensor/i2c.dtsi +++ b/tests/drivers/build_all/sensor/i2c.dtsi @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -1501,3 +1502,14 @@ test_i2c_lsm6dsv320x: lsm6dsv320x@c6 { gyro-range = ; gyro-odr = ; }; + +test_i2c_lsm6dsv80x: lsm6dsv80x@c7 { + compatible = "st,lsm6dsv80x"; + reg = <0xc7>; + int1-gpios = <&test_gpio 0 0>; + int2-gpios = <&test_gpio 0 0>; + accel-range = ; + accel-odr = ; + gyro-range = ; + gyro-odr = ; +}; From 310457448a95e7dd8ff56806b0493f4f050be3da Mon Sep 17 00:00:00 2001 From: Armando Visconti Date: Wed, 10 Sep 2025 15:22:41 +0200 Subject: [PATCH 1533/3659] drivers/sensor: lsm6dsvxxx: add High-g data support in FIFO Add support for High-g data in FIFO. The HG data wiil be marked in FIFO with LSM6DSV80X_XL_HG_TAG. Signed-off-by: Armando Visconti --- drivers/sensor/st/lsm6dsvxxx/lsm6dsv320x.c | 3 +++ drivers/sensor/st/lsm6dsvxxx/lsm6dsv80x.c | 3 +++ drivers/sensor/st/lsm6dsvxxx/lsm6dsvxxx_decoder.c | 2 ++ 3 files changed, 8 insertions(+) diff --git a/drivers/sensor/st/lsm6dsvxxx/lsm6dsv320x.c b/drivers/sensor/st/lsm6dsvxxx/lsm6dsv320x.c index 33f22806e972..604c4742a8f0 100644 --- a/drivers/sensor/st/lsm6dsvxxx/lsm6dsv320x.c +++ b/drivers/sensor/st/lsm6dsvxxx/lsm6dsv320x.c @@ -664,6 +664,7 @@ static void lsm6dsv320x_config_fifo(const struct device *dev, struct trigger_con lsm6dsv320x_sflp_data_rate_t sflp_odr = LSM6DSV320X_SFLP_120Hz; lsm6dsv320x_fifo_sflp_raw_t sflp_fifo = {0}; lsm6dsv320x_sflp_gbias_t gbias; + uint8_t xl_hg_batch = 0; /* disable FIFO as first thing */ lsm6dsv320x_fifo_mode_set(ctx, LSM6DSV320X_BYPASS_MODE); @@ -678,6 +679,7 @@ static void lsm6dsv320x_config_fifo(const struct device *dev, struct trigger_con xl_batch = config->accel_batch; gy_batch = config->gyro_batch; temp_batch = config->temp_batch; + xl_hg_batch = (lsm6dsv320x_is_hg_fs(config->accel_range)) ? 1 : 0; fifo_mode = LSM6DSV320X_STREAM_MODE; fifo_wtm = config->fifo_wtm; @@ -709,6 +711,7 @@ static void lsm6dsv320x_config_fifo(const struct device *dev, struct trigger_con /* Set FIFO batch rates */ lsm6dsv320x_fifo_xl_batch_set(ctx, xl_batch); data->accel_batch_odr = xl_batch; + lsm6dsv320x_fifo_hg_xl_batch_set(ctx, xl_hg_batch); lsm6dsv320x_fifo_gy_batch_set(ctx, gy_batch); data->gyro_batch_odr = gy_batch; #if defined(CONFIG_LSM6DSVXXX_ENABLE_TEMP) diff --git a/drivers/sensor/st/lsm6dsvxxx/lsm6dsv80x.c b/drivers/sensor/st/lsm6dsvxxx/lsm6dsv80x.c index 581bdfa1a231..69b0f1a1ec67 100644 --- a/drivers/sensor/st/lsm6dsvxxx/lsm6dsv80x.c +++ b/drivers/sensor/st/lsm6dsvxxx/lsm6dsv80x.c @@ -651,6 +651,7 @@ static void lsm6dsv80x_config_fifo(const struct device *dev, struct trigger_conf lsm6dsv80x_sflp_data_rate_t sflp_odr = LSM6DSV80X_SFLP_120Hz; lsm6dsv80x_fifo_sflp_raw_t sflp_fifo = {0}; lsm6dsv80x_sflp_gbias_t gbias; + uint8_t xl_hg_batch = 0; /* disable FIFO as first thing */ lsm6dsv80x_fifo_mode_set(ctx, LSM6DSV80X_BYPASS_MODE); @@ -665,6 +666,7 @@ static void lsm6dsv80x_config_fifo(const struct device *dev, struct trigger_conf xl_batch = config->accel_batch; gy_batch = config->gyro_batch; temp_batch = config->temp_batch; + xl_hg_batch = (lsm6dsv80x_is_hg_fs(config->accel_range)) ? 1 : 0; fifo_mode = LSM6DSV80X_STREAM_MODE; fifo_wtm = config->fifo_wtm; @@ -696,6 +698,7 @@ static void lsm6dsv80x_config_fifo(const struct device *dev, struct trigger_conf /* Set FIFO batch rates */ lsm6dsv80x_fifo_xl_batch_set(ctx, xl_batch); data->accel_batch_odr = xl_batch; + lsm6dsv80x_fifo_hg_xl_batch_set(ctx, xl_hg_batch); lsm6dsv80x_fifo_gy_batch_set(ctx, gy_batch); data->gyro_batch_odr = gy_batch; #if defined(CONFIG_LSM6DSVXXX_ENABLE_TEMP) diff --git a/drivers/sensor/st/lsm6dsvxxx/lsm6dsvxxx_decoder.c b/drivers/sensor/st/lsm6dsvxxx/lsm6dsvxxx_decoder.c index 6ce40f740c13..af1c57374f97 100644 --- a/drivers/sensor/st/lsm6dsvxxx/lsm6dsvxxx_decoder.c +++ b/drivers/sensor/st/lsm6dsvxxx/lsm6dsvxxx_decoder.c @@ -162,6 +162,7 @@ static int lsm6dsvxxx_decoder_get_frame_count(const uint8_t *buffer, fifo_tag = (buffer[0] >> 3); switch (fifo_tag) { + case LSM6DSVXXX_XL_HG_TAG: case LSM6DSVXXX_XL_NC_TAG: tot_accel_fifo_words++; break; @@ -523,6 +524,7 @@ static int lsm6dsvxxx_decode_fifo(const uint8_t *buffer, struct sensor_chan_spec fifo_tag = (buffer[0] >> 3); switch (fifo_tag) { + case LSM6DSVXXX_XL_HG_TAG: case LSM6DSVXXX_XL_NC_TAG: xl_count++; skip = generate_accel_output(buffer, count, xl_count, From 56b85ea61a8cae53135b2aeb7e74222e6df9bdb7 Mon Sep 17 00:00:00 2001 From: Armando Visconti Date: Thu, 23 Oct 2025 16:37:52 +0200 Subject: [PATCH 1534/3659] drivers/sensor: lsm6dsvxxx: add ism6hg256x support Add support to ism6hg256x sensor variant of LSM6DSVXXX driver. More information: https://www.st.com/resource/en/datasheet/ism6hg256x.pdf Signed-off-by: Armando Visconti --- drivers/sensor/st/lsm6dsvxxx/CMakeLists.txt | 1 + drivers/sensor/st/lsm6dsvxxx/Kconfig | 13 +- drivers/sensor/st/lsm6dsvxxx/ism6hg256x.c | 843 ++++++++++++++++++ drivers/sensor/st/lsm6dsvxxx/ism6hg256x.h | 25 + drivers/sensor/st/lsm6dsvxxx/lsm6dsvxxx.c | 8 + drivers/sensor/st/lsm6dsvxxx/lsm6dsvxxx.h | 8 +- dts/bindings/sensor/st,ism6hg256x-common.yaml | 75 ++ dts/bindings/sensor/st,ism6hg256x-i2c.yaml | 10 + dts/bindings/sensor/st,ism6hg256x-i3c.yaml | 24 + dts/bindings/sensor/st,ism6hg256x-spi.yaml | 10 + .../zephyr/dt-bindings/sensor/ism6hg256x.h | 36 + modules/hal_st/Kconfig | 3 + tests/drivers/build_all/sensor/i2c.dtsi | 12 + 13 files changed, 1063 insertions(+), 5 deletions(-) create mode 100644 drivers/sensor/st/lsm6dsvxxx/ism6hg256x.c create mode 100644 drivers/sensor/st/lsm6dsvxxx/ism6hg256x.h create mode 100644 dts/bindings/sensor/st,ism6hg256x-common.yaml create mode 100644 dts/bindings/sensor/st,ism6hg256x-i2c.yaml create mode 100644 dts/bindings/sensor/st,ism6hg256x-i3c.yaml create mode 100644 dts/bindings/sensor/st,ism6hg256x-spi.yaml create mode 100644 include/zephyr/dt-bindings/sensor/ism6hg256x.h diff --git a/drivers/sensor/st/lsm6dsvxxx/CMakeLists.txt b/drivers/sensor/st/lsm6dsvxxx/CMakeLists.txt index d36c15466303..6a574467b760 100644 --- a/drivers/sensor/st/lsm6dsvxxx/CMakeLists.txt +++ b/drivers/sensor/st/lsm6dsvxxx/CMakeLists.txt @@ -13,5 +13,6 @@ zephyr_library_sources_ifdef(CONFIG_LSM6DSVXXX_TRIGGER lsm6dsvxxx_trigger.c) zephyr_library_sources_ifdef(CONFIG_DT_HAS_ST_LSM6DSV320X_ENABLED lsm6dsv320x.c) zephyr_library_sources_ifdef(CONFIG_DT_HAS_ST_LSM6DSV80X_ENABLED lsm6dsv80x.c) +zephyr_library_sources_ifdef(CONFIG_DT_HAS_ST_ISM6HG256X_ENABLED ism6hg256x.c) zephyr_library_include_directories(../stmemsc) diff --git a/drivers/sensor/st/lsm6dsvxxx/Kconfig b/drivers/sensor/st/lsm6dsvxxx/Kconfig index 7422321f807c..2060c2106300 100644 --- a/drivers/sensor/st/lsm6dsvxxx/Kconfig +++ b/drivers/sensor/st/lsm6dsvxxx/Kconfig @@ -6,17 +6,22 @@ menuconfig LSM6DSVXXX bool "LSM6DSVXXX IMU sensor" default y - depends on DT_HAS_ST_LSM6DSV320X_ENABLED || DT_HAS_ST_LSM6DSV80X_ENABLED + depends on DT_HAS_ST_LSM6DSV320X_ENABLED || DT_HAS_ST_LSM6DSV80X_ENABLED ||\ + DT_HAS_ST_ISM6HG256X_ENABLED depends on ZEPHYR_HAL_ST_MODULE select I2C if $(dt_compat_on_bus,$(DT_COMPAT_ST_LSM6DSV320X),i2c) ||\ - $(dt_compat_on_bus,$(DT_COMPAT_ST_LSM6DSV80X),i2c) + $(dt_compat_on_bus,$(DT_COMPAT_ST_LSM6DSV80X),i2c) ||\ + $(dt_compat_on_bus,$(DT_COMPAT_ST_ISM6HG256X),i2c) select I3C if $(dt_compat_on_bus,$(DT_COMPAT_ST_LSM6DSV320X),i3c) ||\ - $(dt_compat_on_bus,$(DT_COMPAT_ST_LSM6DSV80X),i3c) + $(dt_compat_on_bus,$(DT_COMPAT_ST_LSM6DSV80X),i3c) ||\ + $(dt_compat_on_bus,$(DT_COMPAT_ST_ISM6HG256X),i3c) select SPI if $(dt_compat_on_bus,$(DT_COMPAT_ST_LSM6DSV320X),spi) ||\ - $(dt_compat_on_bus,$(DT_COMPAT_ST_LSM6DSV80X),spi) + $(dt_compat_on_bus,$(DT_COMPAT_ST_LSM6DSV80X),spi) ||\ + $(dt_compat_on_bus,$(DT_COMPAT_ST_ISM6HG256X),spi) select HAS_STMEMSC select USE_STDC_LSM6DSV320X if DT_HAS_ST_LSM6DSV320X_ENABLED select USE_STDC_LSM6DSV80X if DT_HAS_ST_LSM6DSV80X_ENABLED + select USE_STDC_ISM6HG256X if DT_HAS_ST_ISM6HG256X_ENABLED help Enable driver for LSM6DSVXXX family IMU sensors. diff --git a/drivers/sensor/st/lsm6dsvxxx/ism6hg256x.c b/drivers/sensor/st/lsm6dsvxxx/ism6hg256x.c new file mode 100644 index 000000000000..b4ddea9ea229 --- /dev/null +++ b/drivers/sensor/st/lsm6dsvxxx/ism6hg256x.c @@ -0,0 +1,843 @@ +/* ST Microelectronics LSM6DSVXXX family IMU sensor + * + * Copyright (c) 2025 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + * + * Datasheet: + * https://www.st.com/resource/en/datasheet/ism6hg256x.pdf + */ + +#include "ism6hg256x.h" +#include + +LOG_MODULE_DECLARE(LSM6DSVXXX, CONFIG_SENSOR_LOG_LEVEL); + +static bool ism6hg256x_is_std_fs(uint8_t fs) +{ + return (fs < 4); /* 2g/4g/8g/16g */ +} + +static bool ism6hg256x_is_hg_fs(uint8_t fs) +{ + return (fs >= 4 && fs <= 7); /* 32g/64g/128g/256g */ +} + +/* + * XL configuration + */ + +static uint16_t ism6hg256x_accel_gain_ug(uint8_t fs) +{ + return (61 * (1 << fs)); +} + +/* The first nibble of fs tells if it is High-G or not */ +static int ism6hg256x_accel_range_to_fs_val(const struct device *dev, int32_t range, uint8_t *fs) +{ + switch (range) { + case ISM6HG256X_DT_FS_2G: + *fs = 0; + break; + + case ISM6HG256X_DT_FS_4G: + *fs = 1; + break; + + case ISM6HG256X_DT_FS_8G: + *fs = 2; + break; + + case ISM6HG256X_DT_FS_16G: + *fs = 3; + break; + + case ISM6HG256X_DT_FS_32G: + *fs = 4; + break; + + case ISM6HG256X_DT_FS_64G: + *fs = 5; + break; + + case ISM6HG256X_DT_FS_128G: + *fs = 6; + break; + + case ISM6HG256X_DT_FS_256G: + *fs = 7; + break; + + default: + return -EINVAL; + } + + return 0; +} + +static int ism6hg256x_accel_set_fs_raw(const struct device *dev, uint8_t fs) +{ + const struct lsm6dsvxxx_config *cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + struct lsm6dsvxxx_data *data = dev->data; + + if (ism6hg256x_is_std_fs(fs)) { /* 2g/4g/8g/16g */ + ism6hg256x_xl_full_scale_t val = fs; + + if (ism6hg256x_xl_full_scale_set(ctx, val) < 0) { + return -EIO; + } + + data->out_xl = ISM6HG256X_OUTX_L_A; + } else if (ism6hg256x_is_hg_fs(fs)) { /* 32g/64g/128g/256g */ + ism6hg256x_hg_xl_full_scale_t val = (fs - 4); + + if (ism6hg256x_hg_xl_full_scale_set(ctx, val) < 0) { + return -EIO; + } + + data->out_xl = ISM6HG256X_UI_OUTX_L_A_OIS_HG; + } else { + return -EINVAL; + } + + data->accel_fs = fs; + data->acc_gain = ism6hg256x_accel_gain_ug(fs); + + return 0; +} + +static int ism6hg256x_accel_set_fs(const struct device *dev, int32_t range) +{ + uint8_t fs; + int ret; + + ret = ism6hg256x_accel_range_to_fs_val(dev, range, &fs); + if (ret < 0) { + return ret; + } + + ret = ism6hg256x_accel_set_fs_raw(dev, fs); + if (ret < 0) { + return ret; + } + + return 0; +} + +static int ism6hg256x_accel_set_odr_raw(const struct device *dev, uint8_t odr) +{ + const struct lsm6dsvxxx_config *cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + struct lsm6dsvxxx_data *data = dev->data; + + if (cfg->accel_hg_odr != ISM6HG256X_HG_XL_ODR_OFF) { + + if (ism6hg256x_hg_xl_data_rate_set(ctx, cfg->accel_hg_odr, 1) < 0) { + return -EIO; + } + } else { + if (ism6hg256x_xl_data_rate_set(ctx, odr) < 0) { + return -EIO; + } + } + + data->accel_freq = odr; + + return 0; +} + +/* + * values taken from ism6hg256x_data_rate_t in hal/st module. The mode/accuracy + * should be selected through accel-odr property in DT + */ +static const float ism6hg256x_odr_map[3][13] = { + /* High Accuracy off */ + {0.0f, 1.875f, 7.5f, 15.0f, 30.0f, 60.0f, 120.0f, 240.0f, 480.0f, 960.0f, 1920.0f, 3840.0f, + 7680.0f}, + + /* High Accuracy 1 */ + {0.0f, 1.875f, 7.5f, 15.625f, 31.25f, 62.5f, 125.0f, 250.0f, 500.0f, 1000.0f, 2000.0f, + 4000.0f, 8000.0f}, + + /* High Accuracy 2 */ + {0.0f, 1.875f, 7.5f, 12.5f, 25.0f, 50.0f, 100.0f, 200.0f, 400.0f, 800.0f, 1600.0f, 3200.0f, + 6400.0f}, +}; + +static uint8_t ism6hg256x_freq_to_odr_val(const struct device *dev, int32_t freq) +{ + const struct lsm6dsvxxx_config *cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + ism6hg256x_data_rate_t odr; + int8_t mode; + size_t i; + + if (ism6hg256x_xl_data_rate_get(ctx, &odr) < 0) { + return -EINVAL; + } + + mode = (odr >> 4) & 0xf; + + for (i = 0; i < ARRAY_SIZE(ism6hg256x_odr_map[mode]); i++) { + if (freq <= ism6hg256x_odr_map[mode][i]) { + LOG_DBG("mode: %d - odr: %d", mode, i); + return i | (mode << 4); + } + } + + return 0xFF; +} + +static int ism6hg256x_accel_set_odr(const struct device *dev, int32_t freq) +{ + uint8_t odr; + + odr = ism6hg256x_freq_to_odr_val(dev, freq); + if (odr == 0xFF) { + return -EINVAL; + } + + if (ism6hg256x_accel_set_odr_raw(dev, odr) < 0) { + LOG_DBG("failed to set accelerometer sampling rate"); + return -EIO; + } + + return 0; +} + +static int32_t ism6hg256x_accel_set_mode(const struct device *dev, int32_t mode) +{ + const struct lsm6dsvxxx_config *cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + + switch (mode) { + case 0: /* High Performance */ + mode = ISM6HG256X_XL_HIGH_PERFORMANCE_MD; + break; + case 1: /* High Accuracy */ + mode = ISM6HG256X_XL_HIGH_ACCURACY_ODR_MD; + break; + case 3: /* ODR triggered */ + mode = ISM6HG256X_XL_ODR_TRIGGERED_MD; + break; + case 4: /* Low Power 2 */ + mode = ISM6HG256X_XL_LOW_POWER_2_AVG_MD; + break; + case 5: /* Low Power 4 */ + mode = ISM6HG256X_XL_LOW_POWER_4_AVG_MD; + break; + case 6: /* Low Power 8 */ + mode = ISM6HG256X_XL_LOW_POWER_8_AVG_MD; + break; + case 7: /* Normal */ + mode = ISM6HG256X_XL_NORMAL_MD; + break; + default: + return -EIO; + } + + return ism6hg256x_xl_mode_set(ctx, mode); +} + +static int32_t ism6hg256x_accel_get_fs(const struct device *dev, int32_t *range) +{ + return -ENOTSUP; +} + +static int32_t ism6hg256x_accel_get_odr(const struct device *dev, int32_t *freq) +{ + return -ENOTSUP; +} + +static int32_t ism6hg256x_accel_get_mode(const struct device *dev, int32_t *mode) +{ + const struct lsm6dsvxxx_config *cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + ism6hg256x_xl_mode_t md; + + ism6hg256x_xl_mode_get(ctx, &md); + + switch (md) { + case ISM6HG256X_XL_HIGH_PERFORMANCE_MD: + *mode = 0; + break; + case ISM6HG256X_XL_HIGH_ACCURACY_ODR_MD: + *mode = 1; + break; + case ISM6HG256X_XL_ODR_TRIGGERED_MD: + *mode = 3; + break; + case ISM6HG256X_XL_LOW_POWER_2_AVG_MD: + *mode = 4; + break; + case ISM6HG256X_XL_LOW_POWER_4_AVG_MD: + *mode = 5; + break; + case ISM6HG256X_XL_LOW_POWER_8_AVG_MD: + *mode = 6; + break; + case ISM6HG256X_XL_NORMAL_MD: + *mode = 7; + break; + default: + return -EIO; + } + + return 0; +} + +/* + * GY configuration + */ + +static int ism6hg256x_gyro_range_to_fs_val(const struct device *dev, int32_t range, uint8_t *fs) +{ + switch (range) { + case 0: + *fs = 0; + break; + + case 250: + *fs = ISM6HG256X_DT_FS_250DPS; + break; + + case 500: + *fs = ISM6HG256X_DT_FS_500DPS; + break; + + case 1000: + *fs = ISM6HG256X_DT_FS_1000DPS; + break; + + case 2000: + *fs = ISM6HG256X_DT_FS_2000DPS; + break; + + case 4000: + *fs = ISM6HG256X_DT_FS_4000DPS; + break; + + default: + return -EINVAL; + } + + return 0; +} + +static uint32_t ism6hg256x_gyro_gain_udps(uint8_t fs) +{ + return (4375 * (1 << fs)); +} + +static int ism6hg256x_gyro_set_fs_raw(const struct device *dev, uint8_t fs) +{ + const struct lsm6dsvxxx_config *cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + struct lsm6dsvxxx_data *data = dev->data; + + if (fs == 0) { + /* skip power-up value */ + return 0; + } + + if (ism6hg256x_gy_full_scale_set(ctx, fs) < 0) { + return -EIO; + } + + data->gyro_fs = fs; + data->gyro_gain = ism6hg256x_gyro_gain_udps(fs); + return 0; +} + +static int ism6hg256x_gyro_set_fs(const struct device *dev, int32_t range) +{ + uint8_t fs; + int ret; + + ret = ism6hg256x_gyro_range_to_fs_val(dev, range, &fs); + if (ret < 0) { + return ret; + } + + if (ism6hg256x_gyro_set_fs_raw(dev, fs) < 0) { + return -EIO; + } + + return 0; +} + +static int ism6hg256x_gyro_set_odr_raw(const struct device *dev, uint8_t odr) +{ + const struct lsm6dsvxxx_config *cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + struct lsm6dsvxxx_data *data = dev->data; + + if (ism6hg256x_gy_data_rate_set(ctx, odr) < 0) { + return -EIO; + } + + data->gyro_freq = odr; + return 0; +} + +static int ism6hg256x_gyro_set_odr(const struct device *dev, int32_t freq) +{ + uint8_t odr; + + odr = ism6hg256x_freq_to_odr_val(dev, freq); + if (odr == 0xFF) { + return -EINVAL; + } + + if (ism6hg256x_gyro_set_odr_raw(dev, odr) < 0) { + LOG_DBG("failed to set gyroscope sampling rate"); + return -EIO; + } + + return 0; +} + +static int32_t ism6hg256x_gyro_set_mode(const struct device *dev, int32_t mode) +{ + const struct lsm6dsvxxx_config *cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + + switch (mode) { + case 0: /* High Performance */ + mode = ISM6HG256X_GY_HIGH_PERFORMANCE_MD; + break; + case 1: /* High Accuracy */ + mode = ISM6HG256X_GY_HIGH_ACCURACY_ODR_MD; + break; + case 4: /* Sleep */ + mode = ISM6HG256X_GY_SLEEP_MD; + break; + case 5: /* Low Power */ + mode = ISM6HG256X_GY_LOW_POWER_MD; + break; + default: + return -EIO; + } + + return ism6hg256x_gy_mode_set(ctx, mode); +} + +static int32_t ism6hg256x_gyro_get_fs(const struct device *dev, int32_t *range) +{ + return -ENOTSUP; +} + +static int32_t ism6hg256x_gyro_get_odr(const struct device *dev, int32_t *freq) +{ + return -ENOTSUP; +} + +static int32_t ism6hg256x_gyro_get_mode(const struct device *dev, int32_t *mode) +{ + const struct lsm6dsvxxx_config *cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + ism6hg256x_gy_mode_t md; + + ism6hg256x_gy_mode_get(ctx, &md); + + switch (md) { + case ISM6HG256X_GY_HIGH_PERFORMANCE_MD: + *mode = 0; + break; + case ISM6HG256X_GY_HIGH_ACCURACY_ODR_MD: + *mode = 1; + break; + case ISM6HG256X_GY_SLEEP_MD: + *mode = 4; + break; + case ISM6HG256X_GY_LOW_POWER_MD: + *mode = 5; + break; + default: + return -EIO; + } + + return 0; +} + +#if defined(CONFIG_LSM6DSVXXX_TRIGGER) +int32_t ism6hg256x_drdy_mode_set(const struct device *dev) +{ + const struct lsm6dsvxxx_config *config = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&config->ctx; + + /* enable drdy on int1/int2 in pulse mode */ + ism6hg256x_data_ready_mode_t drdy = + (config->drdy_pulsed) ? ISM6HG256X_DRDY_PULSED : ISM6HG256X_DRDY_LATCHED; + if (ism6hg256x_data_ready_mode_set(ctx, drdy)) { + return -EIO; + } + + return 0; +} +#endif /* CONFIG_LSM6DSVXXX_TRIGGER */ + +/* init routine */ +static int ism6hg256x_init_chip(const struct device *dev) +{ + const struct lsm6dsvxxx_config *cfg = dev->config; + struct lsm6dsvxxx_data *data = dev->data; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + uint8_t chip_id; + uint8_t odr, fs; + +#if LSM6DSVXXX_ANY_INST_ON_BUS_STATUS_OKAY(i3c) + if (cfg->i3c.bus != NULL) { + /* + * Need to grab the pointer to the I3C device descriptor + * before we can talk to the sensor. + */ + lsm6dsvxxx->i3c_dev = i3c_device_find(cfg->i3c.bus, &cfg->i3c.dev_id); + if (lsm6dsvxxx->i3c_dev == NULL) { + LOG_ERR("Cannot find I3C device descriptor"); + return -ENODEV; + } + } +#endif + + /* All registers except 0x01 are different between banks, including the WHO_AM_I + * register and the register used for a SW reset. If the lsm6dsvxxx wasn't on the user + * bank when it reset, then both the chip id check and the sw reset will fail unless we + * set the bank now. + */ + if (ism6hg256x_mem_bank_set(ctx, ISM6HG256X_MAIN_MEM_BANK) < 0) { + LOG_DBG("Failed to set user bank"); + return -EIO; + } + + if (ism6hg256x_device_id_get(ctx, &chip_id) < 0) { + LOG_DBG("Failed reading chip id"); + return -EIO; + } + + LOG_INF("chip id 0x%x", chip_id); + + if (chip_id != ISM6HG256X_ID) { + LOG_DBG("Invalid chip id 0x%x", chip_id); + return -EIO; + } + + /* Resetting the whole device while using I3C will also reset the DA, therefore perform + * only a software reset if the bus is I3C. It should be assumed that the device was + * already fully reset by the I3C CCC RSTACT (whole chip) done as apart of the I3C Bus + * initialization. + */ + if (ON_I3C_BUS(cfg)) { + /* Restore default configuration */ + ism6hg256x_reboot(ctx); + + /* wait 150us as reported in AN5763 */ + k_sleep(K_USEC(150)); + } else { + /* reset device (sw_por) */ + if (ism6hg256x_sw_por(ctx) < 0) { + return -EIO; + } + + /* wait 30ms as reported in AN5763 */ + k_sleep(K_MSEC(30)); + } + + data->out_xl = ISM6HG256X_OUTX_L_A; + data->out_tp = ISM6HG256X_OUT_TEMP_L; + + fs = cfg->accel_range; + LOG_DBG("accel range is %d", fs); + if (ism6hg256x_accel_set_fs_raw(dev, fs) < 0) { + LOG_ERR("failed to set accelerometer range %d", fs); + return -EIO; + } + + odr = cfg->accel_odr; + LOG_DBG("accel odr is %d", odr); + if (ism6hg256x_accel_set_odr_raw(dev, odr) < 0) { + LOG_ERR("failed to set accelerometer odr %d", odr); + return -EIO; + } + + fs = cfg->gyro_range; + LOG_DBG("gyro range is %d", fs); + if (ism6hg256x_gyro_set_fs_raw(dev, fs) < 0) { + LOG_ERR("failed to set gyroscope range %d", fs); + return -EIO; + } + + odr = cfg->gyro_odr; + LOG_DBG("gyro odr is %d", odr); + if (ism6hg256x_gyro_set_odr_raw(dev, odr) < 0) { + LOG_ERR("failed to set gyroscope odr %d", odr); + return -EIO; + } + +#if LSM6DSVXXX_ANY_INST_ON_BUS_STATUS_OKAY(i3c) + if (IS_ENABLED(CONFIG_LSM6DSVXXX_STREAM) && (ON_I3C_BUS(cfg))) { + /* + * Set MRL to the Max Size of the FIFO so the entire FIFO can be read + * out at once + */ + struct i3c_ccc_mrl setmrl = { + .len = 0x0700, + .ibi_len = lsm6dsvxxx->i3c_dev->data_length.max_ibi, + }; + if (i3c_ccc_do_setmrl(lsm6dsvxxx->i3c_dev, &setmrl) < 0) { + LOG_ERR("failed to set mrl"); + return -EIO; + } + } +#endif + + if (ism6hg256x_block_data_update_set(ctx, 1) < 0) { + LOG_DBG("failed to set BDU mode"); + return -EIO; + } + + return 0; +} + +#if defined(CONFIG_PM_DEVICE) +static int ism6hg256x_pm_action(const struct device *dev, enum pm_device_action action) +{ + struct lsm6dsvxxx_data *data = dev->data; + const struct lsm6dsvxxx_config *cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + int ret = 0; + + LOG_DBG("PM action: %d", (int)action); + + switch (action) { + case PM_DEVICE_ACTION_RESUME: + if (ism6hg256x_xl_data_rate_set(ctx, data->accel_freq) < 0) { + LOG_ERR("failed to set accelerometer odr %d", (int)data->accel_freq); + ret = -EIO; + } + if (ism6hg256x_gy_data_rate_set(ctx, data->gyro_freq) < 0) { + LOG_ERR("failed to set gyroscope odr %d", (int)data->gyro_freq); + ret = -EIO; + } + break; + case PM_DEVICE_ACTION_SUSPEND: + if (ism6hg256x_xl_data_rate_set(ctx, LSM6DSVXXX_DT_ODR_OFF) < 0) { + LOG_ERR("failed to disable accelerometer"); + ret = -EIO; + } + if (ism6hg256x_gy_data_rate_set(ctx, LSM6DSVXXX_DT_ODR_OFF) < 0) { + LOG_ERR("failed to disable gyroscope"); + ret = -EIO; + } + break; + default: + ret = -ENOTSUP; + break; + } + + return ret; +} +#endif /* CONFIG_PM_DEVICE */ + +#if defined(CONFIG_LSM6DSVXXX_STREAM) +static void ism6hg256x_config_fifo(const struct device *dev, struct trigger_config trig_cfg) +{ + struct lsm6dsvxxx_data *data = dev->data; + const struct lsm6dsvxxx_config *config = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&config->ctx; + uint8_t fifo_wtm = 0; + ism6hg256x_pin_int_route_t pin_int = {0}; + ism6hg256x_fifo_xl_batch_t xl_batch = LSM6DSVXXX_DT_XL_NOT_BATCHED; + ism6hg256x_fifo_gy_batch_t gy_batch = LSM6DSVXXX_DT_GY_NOT_BATCHED; + ism6hg256x_fifo_temp_batch_t temp_batch = LSM6DSVXXX_DT_TEMP_NOT_BATCHED; + ism6hg256x_fifo_mode_t fifo_mode = ISM6HG256X_BYPASS_MODE; + ism6hg256x_sflp_data_rate_t sflp_odr = ISM6HG256X_SFLP_120Hz; + ism6hg256x_fifo_sflp_raw_t sflp_fifo = {0}; + ism6hg256x_sflp_gbias_t gbias; + uint8_t xl_hg_batch = 0; + + /* disable FIFO as first thing */ + ism6hg256x_fifo_mode_set(ctx, ISM6HG256X_BYPASS_MODE); + + pin_int.fifo_th = PROPERTY_DISABLE; + pin_int.fifo_full = PROPERTY_DISABLE; + + if (trig_cfg.int_fifo_th || trig_cfg.int_fifo_full) { + pin_int.fifo_th = (trig_cfg.int_fifo_th) ? PROPERTY_ENABLE : PROPERTY_DISABLE; + pin_int.fifo_full = (trig_cfg.int_fifo_full) ? PROPERTY_ENABLE : PROPERTY_DISABLE; + + xl_batch = config->accel_batch; + gy_batch = config->gyro_batch; + temp_batch = config->temp_batch; + xl_hg_batch = (ism6hg256x_is_hg_fs(config->accel_range)) ? 1 : 0; + + fifo_mode = ISM6HG256X_STREAM_MODE; + fifo_wtm = config->fifo_wtm; + + if (config->sflp_fifo_en & LSM6DSVXXX_DT_SFLP_FIFO_GAME_ROTATION) { + sflp_fifo.game_rotation = 1; + } + + if (config->sflp_fifo_en & LSM6DSVXXX_DT_SFLP_FIFO_GRAVITY) { + sflp_fifo.gravity = 1; + } + + if (config->sflp_fifo_en & LSM6DSVXXX_DT_SFLP_FIFO_GBIAS) { + sflp_fifo.gbias = 1; + } + + sflp_odr = config->sflp_odr; + } + + /* + * Set FIFO watermark (number of unread sensor data TAG + 6 bytes + * stored in FIFO) to FIFO_WATERMARK samples + */ + ism6hg256x_fifo_watermark_set(ctx, config->fifo_wtm); + + /* Turn on/off FIFO */ + ism6hg256x_fifo_mode_set(ctx, fifo_mode); + + /* Set FIFO batch rates */ + ism6hg256x_fifo_xl_batch_set(ctx, xl_batch); + data->accel_batch_odr = xl_batch; + ism6hg256x_fifo_hg_xl_batch_set(ctx, xl_hg_batch); + ism6hg256x_fifo_gy_batch_set(ctx, gy_batch); + data->gyro_batch_odr = gy_batch; +#if defined(CONFIG_LSM6DSVXXX_ENABLE_TEMP) + ism6hg256x_fifo_temp_batch_set(ctx, temp_batch); + data->temp_batch_odr = temp_batch; +#endif + + ism6hg256x_sflp_data_rate_set(ctx, sflp_odr); + data->sflp_batch_odr = sflp_odr; + ism6hg256x_fifo_sflp_batch_set(ctx, sflp_fifo); + ism6hg256x_sflp_game_rotation_set(ctx, PROPERTY_ENABLE); + + /* + * Temporarly set Accel and gyro odr same as sensor fusion LP in order to + * make the SFLP gbias setting effective. Then restore it to saved values. + */ + switch (sflp_odr) { + case LSM6DSVXXX_DT_SFLP_ODR_AT_480Hz: + ism6hg256x_accel_set_odr_raw(dev, LSM6DSVXXX_DT_ODR_AT_480Hz); + ism6hg256x_gyro_set_odr_raw(dev, LSM6DSVXXX_DT_ODR_AT_480Hz); + break; + + case LSM6DSVXXX_DT_SFLP_ODR_AT_240Hz: + ism6hg256x_accel_set_odr_raw(dev, LSM6DSVXXX_DT_ODR_AT_240Hz); + ism6hg256x_gyro_set_odr_raw(dev, LSM6DSVXXX_DT_ODR_AT_240Hz); + break; + + case LSM6DSVXXX_DT_SFLP_ODR_AT_120Hz: + ism6hg256x_accel_set_odr_raw(dev, LSM6DSVXXX_DT_ODR_AT_120Hz); + ism6hg256x_gyro_set_odr_raw(dev, LSM6DSVXXX_DT_ODR_AT_120Hz); + break; + + case LSM6DSVXXX_DT_SFLP_ODR_AT_60Hz: + ism6hg256x_accel_set_odr_raw(dev, LSM6DSVXXX_DT_ODR_AT_60Hz); + ism6hg256x_gyro_set_odr_raw(dev, LSM6DSVXXX_DT_ODR_AT_60Hz); + break; + + case LSM6DSVXXX_DT_SFLP_ODR_AT_30Hz: + ism6hg256x_accel_set_odr_raw(dev, LSM6DSVXXX_DT_ODR_AT_30Hz); + ism6hg256x_gyro_set_odr_raw(dev, LSM6DSVXXX_DT_ODR_AT_30Hz); + break; + + case LSM6DSVXXX_DT_SFLP_ODR_AT_15Hz: + default: + ism6hg256x_accel_set_odr_raw(dev, LSM6DSVXXX_DT_ODR_AT_15Hz); + ism6hg256x_gyro_set_odr_raw(dev, LSM6DSVXXX_DT_ODR_AT_15Hz); + break; + } + + /* set sflp gbias */ + gbias.gbias_x = (float)data->gbias_x_udps / 1000000; + gbias.gbias_y = (float)data->gbias_y_udps / 1000000; + gbias.gbias_z = (float)data->gbias_z_udps / 1000000; + ism6hg256x_sflp_game_gbias_set(ctx, &gbias); + + /* restore accel/gyro odr to saved values */ + ism6hg256x_accel_set_odr_raw(dev, data->accel_freq); + ism6hg256x_gyro_set_odr_raw(dev, data->gyro_freq); + + /* Set pin interrupt (fifo_th could be on or off) */ + if ((config->drdy_pin == 1) || (ON_I3C_BUS(config) && (!I3C_INT_PIN(config)))) { + ism6hg256x_pin_int1_route_set(ctx, &pin_int); + } else { + ism6hg256x_pin_int2_route_set(ctx, &pin_int); + } +} + +static void ism6hg256x_config_drdy(const struct device *dev, struct trigger_config trig_cfg) +{ + const struct lsm6dsvxxx_config *config = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&config->ctx; + ism6hg256x_pin_int_route_t pin_int = {0}; + + pin_int.drdy_xl = (trig_cfg.int_drdy) ? PROPERTY_ENABLE : PROPERTY_DISABLE; + + /* Set pin interrupt (fifo_th could be on or off) */ + if ((config->drdy_pin == 1) || (ON_I3C_BUS(config) && (!I3C_INT_PIN(config)))) { + ism6hg256x_pin_int1_route_set(ctx, &pin_int); + } else { + ism6hg256x_pin_int2_route_set(ctx, &pin_int); + } +} +#endif /* CONFIG_LSM6DSVXXX_STREAM */ + +const struct lsm6dsvxxx_chip_api st_ism6hg256x_chip_api = { + .init_chip = ism6hg256x_init_chip, +#if defined(CONFIG_LSM6DSVXXX_TRIGGER) + .drdy_mode_set = ism6hg256x_drdy_mode_set, +#endif /* CONFIG_LSM6DSVXXX_TRIGGER */ +#if defined(CONFIG_PM_DEVICE) + .pm_action = ism6hg256x_pm_action, +#endif /* CONFIG_PM_DEVICE */ + .accel_fs_set = ism6hg256x_accel_set_fs, + .accel_odr_set = ism6hg256x_accel_set_odr, + .accel_mode_set = ism6hg256x_accel_set_mode, + .accel_fs_get = ism6hg256x_accel_get_fs, + .accel_odr_get = ism6hg256x_accel_get_odr, + .accel_mode_get = ism6hg256x_accel_get_mode, + .gyro_fs_set = ism6hg256x_gyro_set_fs, + .gyro_odr_set = ism6hg256x_gyro_set_odr, + .gyro_mode_set = ism6hg256x_gyro_set_mode, + .gyro_fs_get = ism6hg256x_gyro_get_fs, + .gyro_odr_get = ism6hg256x_gyro_get_odr, + .gyro_mode_get = ism6hg256x_gyro_get_mode, +#if defined(CONFIG_LSM6DSVXXX_STREAM) + .config_fifo = ism6hg256x_config_fifo, + .config_drdy = ism6hg256x_config_drdy, + .from_f16_to_f32 = ism6hg256x_from_f16_to_f32, + .from_sflp_to_mg = ism6hg256x_from_sflp_to_mg, +#endif /* CONFIG_LSM6DSVXXX_STREAM */ +}; + +/* bit shift for Accelerometer for a given range value */ +const int8_t st_ism6hg256x_accel_bit_shift[] = { + 5, /* FS_2G */ + 6, /* FS_4G */ + 7, /* FS_8G */ + 8, /* FS_16G */ + 9, /* FS_32G */ + 10, /* FS_64G */ + 11, /* FS_128G */ + 12, /* FS_256G */ +}; + +/* + * Accelerometer scaling factors table for a given range value + * GAIN_UNIT_XL is expressed in ug/LSB. + */ +const int32_t st_ism6hg256x_accel_scaler[] = { + SENSOR_SCALE_UG_TO_UMS2(61), /* FS_2G */ + SENSOR_SCALE_UG_TO_UMS2(122), /* FS_4G */ + SENSOR_SCALE_UG_TO_UMS2(244), /* FS_8G */ + SENSOR_SCALE_UG_TO_UMS2(488), /* FS_16G */ + SENSOR_SCALE_UG_TO_UMS2(976), /* FS_32G */ + SENSOR_SCALE_UG_TO_UMS2(1952), /* FS_64G */ + SENSOR_SCALE_UG_TO_UMS2(2904), /* FS_128G */ + SENSOR_SCALE_UG_TO_UMS2(7808), /* FS_256G */ +}; diff --git a/drivers/sensor/st/lsm6dsvxxx/ism6hg256x.h b/drivers/sensor/st/lsm6dsvxxx/ism6hg256x.h new file mode 100644 index 000000000000..4ec55847a5c3 --- /dev/null +++ b/drivers/sensor/st/lsm6dsvxxx/ism6hg256x.h @@ -0,0 +1,25 @@ +/* ST Microelectronics LSM6DSVXXX family IMU sensor + * + * Copyright (c) 2025 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + * + * Datasheet: + * https://www.st.com/resource/en/datasheet/ism6hg256x.pdf + */ +#ifndef ZEPHYR_DRIVERS_SENSOR_ISM6HG256X_H_ +#define ZEPHYR_DRIVERS_SENSOR_ISM6HG256X_H_ + +#include +#include + +#include "lsm6dsvxxx.h" +#include "ism6hg256x_reg.h" + +#include + +extern const struct lsm6dsvxxx_chip_api st_ism6hg256x_chip_api; +extern const int8_t st_ism6hg256x_accel_bit_shift[]; +extern const int32_t st_ism6hg256x_accel_scaler[]; + +#endif /* ZEPHYR_DRIVERS_SENSOR_ISM6HG256X_H_ */ diff --git a/drivers/sensor/st/lsm6dsvxxx/lsm6dsvxxx.c b/drivers/sensor/st/lsm6dsvxxx/lsm6dsvxxx.c index afc745033986..da168a283d8f 100644 --- a/drivers/sensor/st/lsm6dsvxxx/lsm6dsvxxx.c +++ b/drivers/sensor/st/lsm6dsvxxx/lsm6dsvxxx.c @@ -27,6 +27,10 @@ #include "lsm6dsv80x.h" #endif +#if DT_HAS_COMPAT_STATUS_OKAY(st_ism6hg256x) +#include "ism6hg256x.h" +#endif + LOG_MODULE_REGISTER(LSM6DSVXXX, CONFIG_SENSOR_LOG_LEVEL); static int lsm6dsvxxx_accel_config(const struct device *dev, @@ -516,3 +520,7 @@ DT_INST_FOREACH_STATUS_OKAY_VARGS(LSM6DSVXXX_DEFINE, DT_DRV_COMPAT) #define DT_DRV_COMPAT st_lsm6dsv80x DT_INST_FOREACH_STATUS_OKAY_VARGS(LSM6DSVXXX_DEFINE, DT_DRV_COMPAT) #undef DT_DRV_COMPAT + +#define DT_DRV_COMPAT st_ism6hg256x +DT_INST_FOREACH_STATUS_OKAY_VARGS(LSM6DSVXXX_DEFINE, DT_DRV_COMPAT) +#undef DT_DRV_COMPAT diff --git a/drivers/sensor/st/lsm6dsvxxx/lsm6dsvxxx.h b/drivers/sensor/st/lsm6dsvxxx/lsm6dsvxxx.h index 0c262346113a..1ea4718afa0f 100644 --- a/drivers/sensor/st/lsm6dsvxxx/lsm6dsvxxx.h +++ b/drivers/sensor/st/lsm6dsvxxx/lsm6dsvxxx.h @@ -25,7 +25,8 @@ #define LSM6DSVXXX_ANY_INST_ON_BUS_STATUS_OKAY(bus) \ (DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_lsm6dsv320x, bus) ||\ - DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_lsm6dsv80x, bus)) + DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_lsm6dsv80x, bus) ||\ + DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_ism6hg256x, bus)) #if DT_HAS_COMPAT_STATUS_OKAY(st_lsm6dsv320x) #include "lsm6dsv320x_reg.h" @@ -37,6 +38,11 @@ #include #endif +#if DT_HAS_COMPAT_STATUS_OKAY(st_ism6hg256x) +#include "ism6hg256x_reg.h" +#include +#endif + #if LSM6DSVXXX_ANY_INST_ON_BUS_STATUS_OKAY(spi) #include #endif /* LSM6DSVXXX_ANY_INST_ON_BUS_STATUS_OKAY(spi) */ diff --git a/dts/bindings/sensor/st,ism6hg256x-common.yaml b/dts/bindings/sensor/st,ism6hg256x-common.yaml new file mode 100644 index 000000000000..3688b74cd67f --- /dev/null +++ b/dts/bindings/sensor/st,ism6hg256x-common.yaml @@ -0,0 +1,75 @@ +# Copyright (c) 2025 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +description: | + When setting the accel-range, accel-odr, gyro-range, gyro-odr properties in + a .dts or .dtsi file you may include ism6hg256x.h and use the macros + defined there. + + Example: + #include + + ism6hg256x: ism6hg256x@0 { + ... + + accel-range = ; + accel-odr = ; + gyro-range = ; + gyro-odr = ; + }; + +include: st,lsm6dsvxxx-common.yaml + +properties: + accel-hg-odr: + type: int + default: 0x0 + description: | + Specify the default accelerometer High-g output data rate expressed in samples per + second (Hz). + The values are taken in accordance to ism6hg256x_hg_xl_data_rate_t enumerative in hal/st + module. Please note that this values will not change the operating mode, which will remain + High Performance (device default) + Default is power-up configuration. + + - 0x0 # ISM6HG256X_HG_XL_ODR_OFF + - 0x3 # ISM6HG256X_HG_XL_ODR_AT_480Hz + - 0x4 # ISM6HG256X_HG_XL_ODR_AT_960Hz + - 0x5 # ISM6HG256X_HG_XL_ODR_AT_1920Hz + - 0x6 # ISM6HG256X_HG_XL_ODR_AT_3840Hz + - 0x7 # ISM6HG256X_HG_XL_ODR_AT_7680Hz + + enum: [0x0, 0x3, 0x4, 0x5, 0x6, 0x7] + + accel-range: + type: int + default: 2 + description: | + Range in g. Default is power-up configuration. + Ranges from 32g and above requires the High-g sensor to be turned on (see accel-hg-odr). + + - 2 # ISM6HG256X_DT_FS_2G (0.061 mg/LSB) + - 4 # ISM6HG256X_DT_FS_4G (0.122 mg/LSB) + - 8 # ISM6HG256X_DT_FS_8G (0.244 mg/LSB) + - 16 # ISM6HG256X_DT_FS_16G (0.488 mg/LSB) + - 32 # ISM6HG256X_DT_FS_32G (0.976 mg/LSB) + - 64 # ISM6HG256X_DT_FS_64G (1.952 mg/LSB) + - 128 # ISM6HG256X_DT_FS_128G (3.904 mg/LSB) + - 256 # ISM6HG256X_DT_FS_256G (7.808 mg/LSB) + + enum: [2, 4, 8, 16, 32, 64, 128, 256] + + gyro-range: + type: int + default: 0 + description: | + Range in dps. Default is power-up configuration. + + - 0x0 # power-up configuration + - 0x1 # ISM6HG256X_DT_FS_250DPS (8.75 mdps/LSB) + - 0x2 # ISM6HG256X_DT_FS_500DPS (17.50 mdps/LSB) + - 0x3 # ISM6HG256X_DT_FS_1000DPS (35 mdps/LSB) + - 0x4 # ISM6HG256X_DT_FS_2000DPS (70 mdps/LSB) + - 0x5 # ISM6HG256X_DT_FS_4000DPS (140 mdps/LSB) + + enum: [0x0, 0x1, 0x2, 0x3, 0x4, 0x5] diff --git a/dts/bindings/sensor/st,ism6hg256x-i2c.yaml b/dts/bindings/sensor/st,ism6hg256x-i2c.yaml new file mode 100644 index 000000000000..c4f987d43219 --- /dev/null +++ b/dts/bindings/sensor/st,ism6hg256x-i2c.yaml @@ -0,0 +1,10 @@ +# Copyright (c) 2025 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +description: | + STMicroelectronics ISM6HG256X 6-axis IMU (Inertial Measurement Unit) sensor + accessed through I2C bus + +compatible: "st,ism6hg256x" + +include: ["i2c-device.yaml", "st,ism6hg256x-common.yaml"] diff --git a/dts/bindings/sensor/st,ism6hg256x-i3c.yaml b/dts/bindings/sensor/st,ism6hg256x-i3c.yaml new file mode 100644 index 000000000000..e74db0e909f5 --- /dev/null +++ b/dts/bindings/sensor/st,ism6hg256x-i3c.yaml @@ -0,0 +1,24 @@ +# Copyright (c) 2025 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +description: | + STMicroelectronics ISM6HG256X 6-axis IMU (Inertial Measurement Unit) sensor + accessed through I3C bus + +compatible: "st,ism6hg256x" + +include: ["i3c-device.yaml", "st,ism6hg256x-common.yaml"] + +properties: + int-en-i3c: + type: boolean + description: | + Enables INT pin when I3C is enabled + + bus-act-sel-us: + type: int + default: 50 + description: | + Bus available time for I3C IBI in microseconds + + enum: [50, 2, 1000, 25000] diff --git a/dts/bindings/sensor/st,ism6hg256x-spi.yaml b/dts/bindings/sensor/st,ism6hg256x-spi.yaml new file mode 100644 index 000000000000..338b162be291 --- /dev/null +++ b/dts/bindings/sensor/st,ism6hg256x-spi.yaml @@ -0,0 +1,10 @@ +# Copyright (c) 2025 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +description: | + STMicroelectronics ISM6HG256X 6-axis IMU (Inertial Measurement Unit) sensor + accessed through SPI bus + +compatible: "st,ism6hg256x" + +include: ["spi-device.yaml", "st,ism6hg256x-common.yaml"] diff --git a/include/zephyr/dt-bindings/sensor/ism6hg256x.h b/include/zephyr/dt-bindings/sensor/ism6hg256x.h new file mode 100644 index 000000000000..ed3d946e919b --- /dev/null +++ b/include/zephyr/dt-bindings/sensor/ism6hg256x.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2025 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_ST_ISM6HG256X_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_ST_ISM6HG256X_H_ + +#include "lsm6dsvxxx.h" + +/* Accel High-g odr */ +#define ISM6HG256X_HG_XL_ODR_OFF 0x0 +#define ISM6HG256X_HG_XL_ODR_AT_480Hz 0x3 +#define ISM6HG256X_HG_XL_ODR_AT_960Hz 0x4 +#define ISM6HG256X_HG_XL_ODR_AT_1920Hz 0x5 +#define ISM6HG256X_HG_XL_ODR_AT_3840Hz 0x6 +#define ISM6HG256X_HG_XL_ODR_AT_7680Hz 0x7 + +/* Accel range */ +#define ISM6HG256X_DT_FS_2G 2 +#define ISM6HG256X_DT_FS_4G 4 +#define ISM6HG256X_DT_FS_8G 8 +#define ISM6HG256X_DT_FS_16G 16 +#define ISM6HG256X_DT_FS_32G 32 +#define ISM6HG256X_DT_FS_64G 64 +#define ISM6HG256X_DT_FS_128G 128 +#define ISM6HG256X_DT_FS_256G 256 + +/* Gyro range */ +#define ISM6HG256X_DT_FS_250DPS 0x1 +#define ISM6HG256X_DT_FS_500DPS 0x2 +#define ISM6HG256X_DT_FS_1000DPS 0x3 +#define ISM6HG256X_DT_FS_2000DPS 0x4 +#define ISM6HG256X_DT_FS_4000DPS 0x5 + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_ST_ISM6HG256X_H_ */ diff --git a/modules/hal_st/Kconfig b/modules/hal_st/Kconfig index cece2d4fec93..a014955a0b31 100644 --- a/modules/hal_st/Kconfig +++ b/modules/hal_st/Kconfig @@ -69,6 +69,9 @@ config USE_STDC_ISM330DHCX config USE_STDC_ISM330DLC bool +config USE_STDC_ISM6HG256X + bool + config USE_STDC_L20G20IS bool diff --git a/tests/drivers/build_all/sensor/i2c.dtsi b/tests/drivers/build_all/sensor/i2c.dtsi index 2518cdda7a77..592ffdaf875f 100644 --- a/tests/drivers/build_all/sensor/i2c.dtsi +++ b/tests/drivers/build_all/sensor/i2c.dtsi @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -1513,3 +1514,14 @@ test_i2c_lsm6dsv80x: lsm6dsv80x@c7 { gyro-range = ; gyro-odr = ; }; + +test_i2c_ism6hg256x: ism6hg256x@c8 { + compatible = "st,ism6hg256x"; + reg = <0xc8>; + int1-gpios = <&test_gpio 0 0>; + int2-gpios = <&test_gpio 0 0>; + accel-range = ; + accel-odr = ; + gyro-range = ; + gyro-odr = ; +}; From baf18d9e88c2a12731c05e6e4fac71ee0f82fc18 Mon Sep 17 00:00:00 2001 From: Stephan Linz Date: Mon, 13 Oct 2025 10:02:14 +0200 Subject: [PATCH 1535/3659] boards: shields: add support for MikroE CAN FD 6 Click Add shield definition for the MikroElektronika CAN FD 6 Click shield, an mikroBUS compatible evaluation module for the TI TCAN4x5x CAN controller series. Signed-off-by: Stephan Linz --- .../mikroe_can_fd_6_click/Kconfig.shield | 6 +++ .../doc/canfd6_click.webp | Bin 0 -> 43458 bytes .../mikroe_can_fd_6_click/doc/index.rst | 51 ++++++++++++++++++ .../mikroe_can_fd_6_click.overlay | 37 +++++++++++++ .../shields/mikroe_can_fd_6_click/shield.yml | 10 ++++ 5 files changed, 104 insertions(+) create mode 100644 boards/shields/mikroe_can_fd_6_click/Kconfig.shield create mode 100644 boards/shields/mikroe_can_fd_6_click/doc/canfd6_click.webp create mode 100644 boards/shields/mikroe_can_fd_6_click/doc/index.rst create mode 100644 boards/shields/mikroe_can_fd_6_click/mikroe_can_fd_6_click.overlay create mode 100644 boards/shields/mikroe_can_fd_6_click/shield.yml diff --git a/boards/shields/mikroe_can_fd_6_click/Kconfig.shield b/boards/shields/mikroe_can_fd_6_click/Kconfig.shield new file mode 100644 index 000000000000..ce9664540002 --- /dev/null +++ b/boards/shields/mikroe_can_fd_6_click/Kconfig.shield @@ -0,0 +1,6 @@ +# SPDX-FileCopyrightText: Copyright (c) 2025 Navimatix GmbH +# SPDX-FileCopyrightText: Copyright (c) 2025 TiaC Systems +# SPDX-License-Identifier: Apache-2.0 + +config SHIELD_MIKROE_CAN_FD_6_CLICK + def_bool $(shields_list_contains,mikroe_can_fd_6_click) diff --git a/boards/shields/mikroe_can_fd_6_click/doc/canfd6_click.webp b/boards/shields/mikroe_can_fd_6_click/doc/canfd6_click.webp new file mode 100644 index 0000000000000000000000000000000000000000..55c3c41f126fa908998e228d6beb4fc659bc2967 GIT binary patch literal 43458 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 literal 0 HcmV?d00001 diff --git a/boards/shields/mikroe_can_fd_6_click/doc/index.rst b/boards/shields/mikroe_can_fd_6_click/doc/index.rst new file mode 100644 index 000000000000..774b1ae9b8f6 --- /dev/null +++ b/boards/shields/mikroe_can_fd_6_click/doc/index.rst @@ -0,0 +1,51 @@ +.. _mikroe_can_fd_6_click_shield: + +MikroElektronika CAN FD 6 Click +############################### + +Overview +-------- + +The CAN FD 6 Click shield has a `TI TCAN4550-Q1`_ automotive system +basis chip (SBC) with integrated CAN FD controller via a SPI interface +and a integrated high-speed CAN FD transceiver with up to 5 Mbps. + +More information about the shield can be found at +`Mikroe CAN FD 6 click`_. + +.. figure:: canfd6_click.webp + :align: center + :alt: MikroElektronika CAN FD 6 Click + + MikroElektronika CAN FD 6 Click (Credit: MikroElektronika) + +Requirements +************ + +The shield uses a mikroBUS interface. The target board must define the +``mikrobus_spi`` and ``mikrobus_header`` node labels (see :ref:`shields` +for more details). The target board must also support level triggered +interrupts and SPI clock frequency of up to 18 MHz. + +Programming +*********** + +Set ``--shield mikroe_can_fd_6_click`` when you invoke ``west build``, +for example: + +.. zephyr-app-commands:: + :zephyr-app: samples/drivers/can/counter + :board: mikroe_stm32_m4_clicker + :shield: mikroe_can_fd_6_click + :goals: build flash + +References +********** + +.. target-notes:: + +.. _Mikroe CAN FD 6 click: + https://www.mikroe.com/can-fd-6-click + +.. _TI TCAN4550-Q1: + https://www.ti.com/product/TCAN4550-Q1 diff --git a/boards/shields/mikroe_can_fd_6_click/mikroe_can_fd_6_click.overlay b/boards/shields/mikroe_can_fd_6_click/mikroe_can_fd_6_click.overlay new file mode 100644 index 000000000000..4bafde879a64 --- /dev/null +++ b/boards/shields/mikroe_can_fd_6_click/mikroe_can_fd_6_click.overlay @@ -0,0 +1,37 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2025 Navimatix GmbH + * SPDX-FileCopyrightText: Copyright (c) 2025 TiaC Systems + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&mikrobus_spi { + status = "okay"; + cs-gpios = <&mikrobus_header 2 GPIO_ACTIVE_LOW>; + + tcan4x5x_mikroe_can_fd_6_click: tcan4x5x@0 { + compatible = "ti,tcan4x5x"; + reg = <0>; + spi-max-frequency = <18000000>; + status = "okay"; + + clock-frequency = <40000000>; + device-state-gpios = <&mikrobus_header 0 GPIO_ACTIVE_HIGH>; + device-wake-gpios = <&mikrobus_header 6 GPIO_ACTIVE_HIGH>; + reset-gpios = <&mikrobus_header 1 GPIO_ACTIVE_HIGH>; + int-gpios = <&mikrobus_header 7 GPIO_ACTIVE_LOW>; + bosch,mram-cfg = <0x0 15 15 7 7 0 10 10>; + + can-transceiver { + max-bitrate = <8000000>; + }; + }; +}; + +/ { + chosen { + zephyr,canbus = &tcan4x5x_mikroe_can_fd_6_click; + }; +}; diff --git a/boards/shields/mikroe_can_fd_6_click/shield.yml b/boards/shields/mikroe_can_fd_6_click/shield.yml new file mode 100644 index 000000000000..ed6850e7d4b9 --- /dev/null +++ b/boards/shields/mikroe_can_fd_6_click/shield.yml @@ -0,0 +1,10 @@ +# SPDX-FileCopyrightText: Copyright (c) 2025 Navimatix GmbH +# SPDX-FileCopyrightText: Copyright (c) 2025 TiaC Systems +# SPDX-License-Identifier: Apache-2.0 + +shield: + name: mikroe_can_fd_6_click + full_name: CAN FD 6 Click + vendor: mikroe + supported_features: + - can From 0049bbe202c4cf225aa80b6ef1aed014276cd08f Mon Sep 17 00:00:00 2001 From: Stephan Linz Date: Fri, 17 Oct 2025 07:31:24 +0200 Subject: [PATCH 1536/3659] tests: drivers: build_all: can: add MikroE compile tests for tcan4x5x Add the MikroE compile test for the TI TCAN4x5x series CAN controller driver. Signed-off-by: Stephan Linz --- tests/drivers/build_all/can/testcase.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/drivers/build_all/can/testcase.yaml b/tests/drivers/build_all/can/testcase.yaml index a536ef43ac4f..d4e0ace41f45 100644 --- a/tests/drivers/build_all/can/testcase.yaml +++ b/tests/drivers/build_all/can/testcase.yaml @@ -16,6 +16,9 @@ tests: - arduino_gpio extra_args: SHIELD=tcan4550evm platform_allow: frdm_k64f + drivers.can.build_all.tcan4x5x.mikrobus: + extra_args: SHIELD=mikroe_can_fd_6_click + platform_allow: mikroe_stm32_m4_clicker drivers.can.build_all.mcp251xfd: extra_args: SHIELD=mikroe_mcp2518fd_click platform_allow: lpcxpresso55s28 From adaac81ae811dd481779051ec71d0d26c3eb666d Mon Sep 17 00:00:00 2001 From: Stephan Linz Date: Fri, 17 Oct 2025 06:49:48 +0200 Subject: [PATCH 1537/3659] MAINTAINERS: include CAN FD 6 Click shield in CAN drivers This commit adds the MikroE CAN FD 6 Click shield under the same assignees as other of the CAN driver based shields. Signed-off-by: Stephan Linz --- MAINTAINERS.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index 950a89950ecf..91013e1c10b8 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -1320,6 +1320,7 @@ Documentation Infrastructure: files: - boards/shields/canis_canpico/ - boards/shields/mcp2515/ + - boards/shields/mikroe_can_fd_6_click/ - boards/shields/tcan4550evm/ - doc/connectivity/canbus/ - doc/hardware/peripherals/can/ From e1c68019ccf7a0cc6b9f4c13d2052cc4558bbdc4 Mon Sep 17 00:00:00 2001 From: Marco Casaroli Date: Mon, 24 Nov 2025 18:50:39 +0100 Subject: [PATCH 1538/3659] modules: mbedtls: include option to enable version information Some libraries like libcoap make use of mbedtls_version_get_number which is enabled by MBEDTLS_VERSION_C. We add a config option to be able to selectively enable it. Signed-off-by: Marco Casaroli --- modules/mbedtls/Kconfig.mbedtls | 6 ++++++ modules/mbedtls/configs/config-mbedtls.h | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/modules/mbedtls/Kconfig.mbedtls b/modules/mbedtls/Kconfig.mbedtls index c8065fa758a1..3d1c1dad14a7 100644 --- a/modules/mbedtls/Kconfig.mbedtls +++ b/modules/mbedtls/Kconfig.mbedtls @@ -604,6 +604,12 @@ config MBEDTLS_LMS_C depends on MBEDTLS_SHA256 select PSA_WANT_ALG_SHA_256 +config MBEDTLS_VERSION_C + bool "Support version information" + help + Enable the mbedtls_version_get_number() function to get version + information from Mbed TLS. + if MBEDTLS_PSA_CRYPTO_C config MBEDTLS_PSA_P256M_DRIVER_ENABLED diff --git a/modules/mbedtls/configs/config-mbedtls.h b/modules/mbedtls/configs/config-mbedtls.h index 3c33586c4c1f..d574071885fe 100644 --- a/modules/mbedtls/configs/config-mbedtls.h +++ b/modules/mbedtls/configs/config-mbedtls.h @@ -45,6 +45,10 @@ #define MBEDTLS_LMS_C #endif +#if defined(CONFIG_MBEDTLS_VERSION_C) +#define MBEDTLS_VERSION_C +#endif + #if defined(CONFIG_MBEDTLS_HAVE_TIME_DATE) #define MBEDTLS_HAVE_TIME #define MBEDTLS_HAVE_TIME_DATE From 2988310fe6e59491fdd6e54ff99af59e469c3738 Mon Sep 17 00:00:00 2001 From: Marco Casaroli Date: Sat, 29 Nov 2025 09:59:19 +0100 Subject: [PATCH 1539/3659] doc: releases: add note about CONFIG_MBEDTLS_VERSION in Mbed TLS Updates release notes about the addition of the new configuration. Signed-off-by: Marco Casaroli --- doc/releases/release-notes-4.4.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/releases/release-notes-4.4.rst b/doc/releases/release-notes-4.4.rst index be546808c5b1..76705f4dc8b4 100644 --- a/doc/releases/release-notes-4.4.rst +++ b/doc/releases/release-notes-4.4.rst @@ -279,6 +279,12 @@ Libraries / Subsystems * :c:func:`lora_airtime` +* Mbed TLS + + * Added :kconfig:option:`CONFIG_MBEDTLS_VERSION_C` to simplify the + export of version information from Mbed TLS. If enabled, the + :c:func:`mbedtls_version_get_number()` function will be available. + Other notable changes ********************* From 80474fae1cd8537212e77c11a2edd7fff3309de6 Mon Sep 17 00:00:00 2001 From: Dev Joshi Date: Mon, 24 Nov 2025 13:47:54 -0800 Subject: [PATCH 1540/3659] boards: rpi_pico2: fix I2C misconfiguration bug I2C controller on rpi_pico2 boards were getting misconfigured due to `CONFIG_I2C_DW_CLOCK_SPEED` not getting set properly. This change fixes the value for this Kconfig symbol to the correct clock speed (clk_peri) that is used by I2C controller. Signed-off-by: Dev Joshi --- boards/raspberrypi/rpi_pico2/Kconfig.defconfig | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/boards/raspberrypi/rpi_pico2/Kconfig.defconfig b/boards/raspberrypi/rpi_pico2/Kconfig.defconfig index f0c7c0a89a24..c18d88b8eb4f 100644 --- a/boards/raspberrypi/rpi_pico2/Kconfig.defconfig +++ b/boards/raspberrypi/rpi_pico2/Kconfig.defconfig @@ -17,4 +17,11 @@ config WHD_DISABLE_SDIO_PULLUP_DURING_SPI_SLEEP endif # WIFI_AIROC +if I2C_DW + +config I2C_DW_CLOCK_SPEED + default 150 + +endif # I2C_DW + endif # BOARD_RPI_PICO2 From b85c12049bf1b5364046728388c53d900c74fcae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fin=20Maa=C3=9F?= Date: Mon, 1 Dec 2025 22:10:21 +0100 Subject: [PATCH 1541/3659] drivers: ethernet: w5500: use timeout directly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit use Kconfig timeout directly. Signed-off-by: Fin Maaß --- drivers/ethernet/eth_w5500.c | 6 ++---- drivers/ethernet/eth_w5500_priv.h | 1 - 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/ethernet/eth_w5500.c b/drivers/ethernet/eth_w5500.c index 9a87a0a70c73..f1658e0ecbdc 100644 --- a/drivers/ethernet/eth_w5500.c +++ b/drivers/ethernet/eth_w5500.c @@ -216,7 +216,6 @@ static void w5500_rx(const struct device *dev) struct net_buf *pkt_buf = NULL; struct net_pkt *pkt; struct w5500_runtime *ctx = dev->data; - const struct w5500_config *config = dev->config; w5500_spi_read(dev, W5500_S0_RX_RSR, tmp, 2); rx_buf_len = sys_get_be16(tmp); @@ -231,8 +230,8 @@ static void w5500_rx(const struct device *dev) w5500_readbuf(dev, off, header, 2); rx_len = sys_get_be16(header) - 2; - pkt = net_pkt_rx_alloc_with_buffer(ctx->iface, rx_len, - NET_AF_UNSPEC, 0, K_MSEC(config->timeout)); + pkt = net_pkt_rx_alloc_with_buffer(ctx->iface, rx_len, NET_AF_UNSPEC, 0, + K_MSEC(CONFIG_ETH_W5500_TIMEOUT)); if (!pkt) { eth_stats_update_errors_rx(ctx->iface); return; @@ -623,7 +622,6 @@ static const struct w5500_config w5500_0_config = { .spi = SPI_DT_SPEC_INST_GET(0, SPI_WORD_SET(8)), .interrupt = GPIO_DT_SPEC_INST_GET(0, int_gpios), .reset = GPIO_DT_SPEC_INST_GET_OR(0, reset_gpios, { 0 }), - .timeout = CONFIG_ETH_W5500_TIMEOUT, .mac_cfg = NET_ETH_MAC_DT_INST_CONFIG_INIT(0), }; diff --git a/drivers/ethernet/eth_w5500_priv.h b/drivers/ethernet/eth_w5500_priv.h index 50235481aa64..f58da1794d30 100644 --- a/drivers/ethernet/eth_w5500_priv.h +++ b/drivers/ethernet/eth_w5500_priv.h @@ -83,7 +83,6 @@ struct w5500_config { struct spi_dt_spec spi; struct gpio_dt_spec interrupt; struct gpio_dt_spec reset; - int32_t timeout; struct net_eth_mac_config mac_cfg; }; From 540df685f44ba4891a48ba0bf60bacb7edfb9647 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fin=20Maa=C3=9F?= Date: Tue, 2 Dec 2025 00:51:16 +0100 Subject: [PATCH 1542/3659] drivers: ethernet: w5500: implement get_link MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit implement get_link from the ethernet phy api. Signed-off-by: Fin Maaß --- drivers/ethernet/eth_w5500.c | 60 ++++++++++++++++++++++++++----- drivers/ethernet/eth_w5500_priv.h | 11 +++++- 2 files changed, 62 insertions(+), 9 deletions(-) diff --git a/drivers/ethernet/eth_w5500.c b/drivers/ethernet/eth_w5500.c index f1658e0ecbdc..e06d1444f4fa 100644 --- a/drivers/ethernet/eth_w5500.c +++ b/drivers/ethernet/eth_w5500.c @@ -278,21 +278,38 @@ static void w5500_update_link_status(const struct device *dev) { uint8_t phycfgr; struct w5500_runtime *ctx = dev->data; + enum phy_link_speed speed; if (w5500_spi_read(dev, W5500_PHYCFGR, &phycfgr, 1) < 0) { return; } - if (phycfgr & 0x01) { - if (ctx->link_up != true) { + if (IS_BIT_SET(phycfgr, W5500_PHYCFGR_LNK_BIT)) { + if (ctx->state.is_up != true) { LOG_INF("%s: Link up", dev->name); - ctx->link_up = true; + ctx->state.is_up = true; net_eth_carrier_on(ctx->iface); } + + if (IS_BIT_SET(phycfgr, W5500_PHYCFGR_SPD_BIT)) { + speed = IS_BIT_SET(phycfgr, W5500_PHYCFGR_DPX_BIT) ? LINK_FULL_100BASE + : LINK_HALF_100BASE; + } else { + speed = IS_BIT_SET(phycfgr, W5500_PHYCFGR_DPX_BIT) ? LINK_FULL_10BASE + : LINK_HALF_10BASE; + } + + if (ctx->state.speed != speed) { + ctx->state.speed = speed; + LOG_INF("%s: Link speed %s Mb, %s duplex", dev->name, + PHY_LINK_IS_SPEED_100M(speed) ? "100" : "10", + PHY_LINK_IS_FULL_DUPLEX(speed) ? "full" : "half"); + } } else { - if (ctx->link_up != false) { + if (ctx->state.is_up != false) { LOG_INF("%s: Link down", dev->name); - ctx->link_up = false; + ctx->state.is_up = false; + ctx->state.speed = 0; net_eth_carrier_off(ctx->iface); } } @@ -314,7 +331,7 @@ static void w5500_thread(void *p1, void *p2, void *p3) if (res == 0) { /* semaphore taken, update link status and receive packets */ - if (ctx->link_up != true) { + if (ctx->state.is_up != true) { w5500_update_link_status(dev); } @@ -458,15 +475,38 @@ static int w5500_hw_stop(const struct device *dev) return 0; } +static const struct device *w5500_get_phy(const struct device *dev) +{ + const struct w5500_config *config = dev->config; + + return config->phy_dev; +} + static const struct ethernet_api w5500_api_funcs = { .iface_api.init = w5500_iface_init, .get_capabilities = w5500_get_capabilities, .set_config = w5500_set_config, .start = w5500_hw_start, .stop = w5500_hw_stop, + .get_phy = w5500_get_phy, .send = w5500_tx, }; +static int w5500_get_link_state(const struct device *dev, + struct phy_link_state *state) +{ + struct w5500_runtime *const data = dev->data; + + state->speed = data->state.speed; + state->is_up = data->state.is_up; + + return 0; +} + +static DEVICE_API(ethphy, w5500_phy_driver_api) = { + .get_link = w5500_get_link_state, +}; + static int w5500_soft_reset(const struct device *dev) { int ret; @@ -526,8 +566,6 @@ static int w5500_init(const struct device *dev) const struct w5500_config *config = dev->config; struct w5500_runtime *ctx = dev->data; - ctx->link_up = false; - if (!spi_is_ready_dt(&config->spi)) { LOG_ERR("SPI master port %s not ready", config->spi.bus->name); return -EINVAL; @@ -611,6 +649,8 @@ static int w5500_init(const struct device *dev) return 0; } +DEVICE_DECLARE(eth_w5500_phy_0); + static struct w5500_runtime w5500_0_runtime = { .tx_sem = Z_SEM_INITIALIZER(w5500_0_runtime.tx_sem, 1, UINT_MAX), @@ -623,9 +663,13 @@ static const struct w5500_config w5500_0_config = { .interrupt = GPIO_DT_SPEC_INST_GET(0, int_gpios), .reset = GPIO_DT_SPEC_INST_GET_OR(0, reset_gpios, { 0 }), .mac_cfg = NET_ETH_MAC_DT_INST_CONFIG_INIT(0), + .phy_dev = DEVICE_GET(eth_w5500_phy_0), }; ETH_NET_DEVICE_DT_INST_DEFINE(0, w5500_init, NULL, &w5500_0_runtime, &w5500_0_config, CONFIG_ETH_INIT_PRIORITY, &w5500_api_funcs, NET_ETH_MTU); + +DEVICE_DEFINE(eth_w5500_phy_0, DEVICE_DT_NAME(DT_DRV_INST(0)) "_phy", NULL, NULL, &w5500_0_runtime, + &w5500_0_config, POST_KERNEL, CONFIG_ETH_INIT_PRIORITY, &w5500_phy_driver_api); diff --git a/drivers/ethernet/eth_w5500_priv.h b/drivers/ethernet/eth_w5500_priv.h index f58da1794d30..40cdcefba829 100644 --- a/drivers/ethernet/eth_w5500_priv.h +++ b/drivers/ethernet/eth_w5500_priv.h @@ -8,6 +8,7 @@ #include #include +#include #ifndef _W5500_ #define _W5500_ @@ -27,6 +28,13 @@ #define W5500_COMMON_REGS_LEN 0x0040 #define W5500_PHYCFGR 0x002E /* PHY Configuration register */ +#define W5500_PHYCFGR_LNK_BIT 0 /* Link status */ +#define W5500_PHYCFGR_SPD_BIT 1 /* Speed status */ +#define W5500_PHYCFGR_DPX_BIT 2 /* Duplex status */ +#define W5500_PHYCFGR_LNK BIT(W5500_PHYCFGR_LNK_BIT) /* Link status */ +#define W5500_PHYCFGR_SPD BIT(W5500_PHYCFGR_SPD_BIT) /* Speed status */ +#define W5500_PHYCFGR_DPX BIT(W5500_PHYCFGR_DPX_BIT) /* Duplex status */ + #define W5500_Sn_MR 0x0000 /* Sn Mode Register */ #define W5500_Sn_CR 0x0001 /* Sn Command Register */ #define W5500_Sn_IR 0x0002 /* Sn Interrupt Register */ @@ -84,6 +92,7 @@ struct w5500_config { struct gpio_dt_spec interrupt; struct gpio_dt_spec reset; struct net_eth_mac_config mac_cfg; + const struct device *phy_dev; }; struct w5500_runtime { @@ -96,7 +105,7 @@ struct w5500_runtime { struct gpio_callback gpio_cb; struct k_sem tx_sem; struct k_sem int_sem; - bool link_up; + struct phy_link_state state; uint8_t buf[NET_ETH_MAX_FRAME_SIZE]; }; From b42b10f89e334799764b66b0923a0c2fd76c9039 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Fri, 12 Dec 2025 10:35:07 +0100 Subject: [PATCH 1543/3659] west.yml: update hal_stm32 module on H7RS/L4/L5/N6 stm32cube releases stm32h7rsxx bumps to STM32CubeH7RS version 1.3.0. stm32l4xx bumps to STM32CubeL4 version 1.18.2. stm32l5xx bumps to STM32CubeL5 version 1.6.0. stm32n6xx bumps to STM32CubeN6 version 1.3.0. Update dma_stm32.h to sync with HAL new function prototype for LL_DMA_IsActiveFlag_HT*() functions that now expect a const pointer on STM32L4X series. While at it, also update the STM32MP13X series that expects the same prototypes. Signed-off-by: Etienne Carriere --- drivers/dma/dma_stm32.h | 2 ++ west.yml | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/dma/dma_stm32.h b/drivers/dma/dma_stm32.h index dcb41a6b2eae..6602b13e734f 100644 --- a/drivers/dma/dma_stm32.h +++ b/drivers/dma/dma_stm32.h @@ -58,6 +58,8 @@ typedef void (*dma_stm32_clear_flag_func)(DMA_TypeDef *DMAx); #if !defined(CONFIG_SOC_SERIES_STM32C0X) && \ !defined(CONFIG_SOC_SERIES_STM32G0X) && \ !defined(CONFIG_SOC_SERIES_STM32H7X) && \ + !defined(CONFIG_SOC_SERIES_STM32L4X) && \ + !defined(CONFIG_SOC_SERIES_STM32MP13X) && \ !defined(CONFIG_SOC_SERIES_STM32U0X) typedef uint32_t (*dma_stm32_check_flag_func)(DMA_TypeDef *DMAx); #else diff --git a/west.yml b/west.yml index b563d0f75b7d..3919bf664119 100644 --- a/west.yml +++ b/west.yml @@ -255,7 +255,7 @@ manifest: groups: - hal - name: hal_stm32 - revision: 9325b43737ffca79ffe1af6300c90ffde98919da + revision: ec0fe4a09a5bbf0e482ab1f4bd42d66131c64369 path: modules/hal/stm32 groups: - hal From cd528e3b25d18989da40ba04e9797a984a205326 Mon Sep 17 00:00:00 2001 From: Qingsong Gou Date: Sun, 14 Dec 2025 11:38:10 +0800 Subject: [PATCH 1544/3659] drivers: rtc: sf32lb: fix y2k bug Fix 1999 to 2000 year bug Signed-off-by: Qingsong Gou --- drivers/rtc/rtc_sf32lb.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/rtc/rtc_sf32lb.c b/drivers/rtc/rtc_sf32lb.c index e4b5deb3ab14..04995ff92c05 100644 --- a/drivers/rtc/rtc_sf32lb.c +++ b/drivers/rtc/rtc_sf32lb.c @@ -175,7 +175,17 @@ static int rtc_sf32lb_get_time(const struct device *dev, struct rtc_time *timept reg = sys_read32(config->cfg + SYS_CFG_RTC_DR); if (reg & RTC_DR_CB) { /* 20th century */ - timeptr->tm_year = bcd2bin(FIELD_GET(RTC_DR_YT_Msk | RTC_DR_YU_Msk, reg)); + uint8_t year = bcd2bin(FIELD_GET(RTC_DR_YT_Msk | RTC_DR_YU_Msk, reg)); + + if (year < 70) { + /* Year is 00-69, which should be 2000-2069. Clear CB bit */ + sys_clear_bit(config->base + RTC_DATER, RTC_DR_CB_Pos); + + timeptr->tm_year = year + 100; + } else { + /* Year is 70-99, which is 1970-1999. Keep CB bit set */ + timeptr->tm_year = year; + } } else { timeptr->tm_year = bcd2bin(FIELD_GET(RTC_DR_YT_Msk | RTC_DR_YU_Msk, reg)) + 100; } From 0a0ab9888cc8cf37999a05569dc6ad5709d40ad9 Mon Sep 17 00:00:00 2001 From: Qingsong Gou Date: Thu, 18 Dec 2025 18:51:32 +0800 Subject: [PATCH 1545/3659] boards: sifli: sf32lb52_devkit_lcd: enable rtc build Enable rtc build on sf32lb52_devkit_lcd board Signed-off-by: Qingsong Gou --- boards/sifli/sf32lb52_devkit_lcd/sf32lb52_devkit_lcd.yaml | 1 + tests/drivers/build_all/rtc/testcase.yaml | 3 +++ 2 files changed, 4 insertions(+) diff --git a/boards/sifli/sf32lb52_devkit_lcd/sf32lb52_devkit_lcd.yaml b/boards/sifli/sf32lb52_devkit_lcd/sf32lb52_devkit_lcd.yaml index e3882be98bab..d48dfa7177dc 100644 --- a/boards/sifli/sf32lb52_devkit_lcd/sf32lb52_devkit_lcd.yaml +++ b/boards/sifli/sf32lb52_devkit_lcd/sf32lb52_devkit_lcd.yaml @@ -15,4 +15,5 @@ supported: - watchdog - bluetooth - audio + - rtc vendor: sifli diff --git a/tests/drivers/build_all/rtc/testcase.yaml b/tests/drivers/build_all/rtc/testcase.yaml index ba357ce35b3b..606cac0af56c 100644 --- a/tests/drivers/build_all/rtc/testcase.yaml +++ b/tests/drivers/build_all/rtc/testcase.yaml @@ -4,6 +4,9 @@ common: - drivers - rtc tests: + drivers.rtc.build.sf32lb: + platform_allow: + - sf32lb52_devkit_lcd drivers.rtc.build.pcf8523: depends_on: - arduino_spi From 0ee36a6f50cd19180a9d70c48a735d6541f68106 Mon Sep 17 00:00:00 2001 From: Qingsong Gou Date: Thu, 18 Dec 2025 22:05:48 +0800 Subject: [PATCH 1546/3659] drivers: rtc: sf32lb: fix compile warnings Fix compile warnings for sf32lb Signed-off-by: Qingsong Gou --- drivers/rtc/rtc_sf32lb.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/rtc/rtc_sf32lb.c b/drivers/rtc/rtc_sf32lb.c index 04995ff92c05..2a0ecdffae4c 100644 --- a/drivers/rtc/rtc_sf32lb.c +++ b/drivers/rtc/rtc_sf32lb.c @@ -73,6 +73,7 @@ struct rtc_sf32lb_config { #endif }; +#ifdef CONFIG_RTC_ALARM static void rtc_irq_handler(const struct device *dev) { const struct rtc_sf32lb_config *config = dev->config; @@ -82,15 +83,14 @@ static void rtc_irq_handler(const struct device *dev) if (isr & RTC_ISR_ALRMF) { sys_clear_bit(config->base + RTC_ISR, RTC_ISR_ALRMF_Pos); -#ifdef CONFIG_RTC_ALARM - atomic_set_bit(&data->is_pending, 0); + atomic_set_bit(data->is_pending, 0); if (data->alarm_cb.cb) { data->alarm_cb.cb(dev, 0, data->alarm_cb.user_data); } -#endif } } +#endif static inline int rtc_sf32lb_enter_init_mode(const struct device *dev) { @@ -329,7 +329,7 @@ static int rtc_sf32lb_alarm_is_pending(const struct device *dev, uint16_t id) return -EINVAL; } - return (int)atomic_test_and_clear_bit(&data->is_pending, 0); + return (int)atomic_test_and_clear_bit(data->is_pending, 0); } static int rtc_sf32lb_alarm_set_callback(const struct device *dev, uint16_t id, @@ -388,7 +388,8 @@ static int rtc_sf32lb_init(const struct device *dev) } #define RTC_SF32LB_DEFINE(n) \ - static void rtc_sf32lb_irq_config_func_##n(void); \ + IF_ENABLED(CONFIG_RTC_ALARM, ( \ + static void rtc_sf32lb_irq_config_func_##n(void);)) \ static const struct rtc_sf32lb_config rtc_sf32lb_config_##n = { \ .base = DT_INST_REG_ADDR(n), \ .cfg = DT_REG_ADDR(DT_INST_PHANDLE(n, sifli_cfg)), \ From cef6b4a760ee4b079fc38cdc0a240368de1a14a6 Mon Sep 17 00:00:00 2001 From: Karun Kumar Eagalapati Date: Mon, 15 Dec 2025 15:03:03 +0530 Subject: [PATCH 1547/3659] manifest: Update nrf_wifi with latest rpu bins 1. Fixes an issue in UMAC where valid P2P devices were filtered during a connect scan due to strict SSID length matching. 2. P2P NOA Bug Fix. 3. Linker issue fix in Raw modes. 4. LMAC BIMG offset change. 5. RPU Version update from 1.2.14.6 to 1.2.14.7. 6. Display scan fix for WPA3 HNP and H2E. Signed-off-by: Karun Kumar Eagalapati --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 3919bf664119..aaa91fb01966 100644 --- a/west.yml +++ b/west.yml @@ -347,7 +347,7 @@ manifest: revision: 0f0c43748111c65800c6920f1c0690676423a351 path: modules/bsim_hw_models/nrf_hw_models - name: nrf_wifi - revision: 9f09f0785f9fc716514d8956a2a446021697400c + revision: eaf223da0c3f987caa1156cbed54b513bee4ba37 path: modules/lib/nrf_wifi - name: open-amp revision: 5efe7974f9546582e99f5a842a816ea4b65f5227 From 16c97c51703cbf8497fbe2e16c0adde6dd0c5ca3 Mon Sep 17 00:00:00 2001 From: Kapil Bhatt Date: Tue, 16 Dec 2025 11:25:45 +0000 Subject: [PATCH 1548/3659] manifest: Update hostap revision for p2p fixes Listen for probe request in GO mode Reducing a delay in p2p connection. Signed-off-by: Kapil Bhatt --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index aaa91fb01966..fc0e681a3b30 100644 --- a/west.yml +++ b/west.yml @@ -291,7 +291,7 @@ manifest: - hal - name: hostap path: modules/lib/hostap - revision: 5af8b179632c602b8a05c34c74a50dda3d546eaa + revision: 1a2fbb7910f23822a785294eab9f4922c6119711 - name: liblc3 revision: 48bbd3eacd36e99a57317a0a4867002e0b09e183 path: modules/lib/liblc3 From 78853034222da461f978d2a4d9e0336ad255ff89 Mon Sep 17 00:00:00 2001 From: Kapil Bhatt Date: Wed, 7 Jan 2026 13:11:28 +0000 Subject: [PATCH 1549/3659] driver: nrf_wifi: Add config option for No-ACK policy in Tx packets Build time configuration option to set No-ACK policy for Tx packets with a specific TID. Signed-off-by: Kapil Bhatt --- drivers/wifi/nrf_wifi/Kconfig.nrfwifi | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/drivers/wifi/nrf_wifi/Kconfig.nrfwifi b/drivers/wifi/nrf_wifi/Kconfig.nrfwifi index a4603cf96a9b..a3e4c2d1fd60 100644 --- a/drivers/wifi/nrf_wifi/Kconfig.nrfwifi +++ b/drivers/wifi/nrf_wifi/Kconfig.nrfwifi @@ -808,6 +808,32 @@ config NRF_WIFI_FEAT_WMM help This option controls disable/enable of the WMM (Wireless Multi-Media) feature. +config NRF_WIFI_QOS_NOACK_POLICY + bool "QoS No-ACK policy for Tx packets" + help + Enable this option to set No-ACK policy for Tx packets with a specific TID. + When enabled, all Tx frames for the configured TID will be marked with + the No-ACK policy flag, indicating that the receiver should not send + ACK frames for these packets. + Use with caution: + Enabling No-ACK for BE (Best Effort) or BK (Background) can cause link + issues (ARP/IP failures due to no retries). + + Recommended usage: + Ideally for VI (Video) or VO (Voice) access category. + The application must correctly encode TID via TOS to activate this feature. + +if NRF_WIFI_QOS_NOACK_POLICY +config NRF_WIFI_QOS_NOACK_POLICY_TID + int "TID (Traffic Identifier) for No-ACK policy" + range 0 7 + default 0 + help + Specify the TID (Traffic Identifier) for which No-ACK policy should be applied. + TID values range from 0 to 7, corresponding to different QoS priority levels. + All Tx frames with this TID will be marked with the No-ACK policy flag. +endif # NRF_WIFI_QOS_NOACK_POLICY + choice NRF_WIFI_PS_DATA_RETRIEVAL_MECHANISM prompt "Power save data retrieval mechanism" default NRF_WIFI_PS_POLL_BASED_RETRIEVAL From 2b2ac80eea911a7191cec2f02b14a157e9f3f1df Mon Sep 17 00:00:00 2001 From: Kapil Bhatt Date: Thu, 8 Jan 2026 07:15:36 +0000 Subject: [PATCH 1550/3659] drivers: wifi: Change WPA3 to WPA3_HNP and WPA3_H2E Change WPA3 into WPA3-HNP, WPA3-H2E for Display scan fix. Signed-off-by: Kapil Bhatt --- drivers/wifi/nrf_wifi/src/wifi_mgmt_scan.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/wifi/nrf_wifi/src/wifi_mgmt_scan.c b/drivers/wifi/nrf_wifi/src/wifi_mgmt_scan.c index 07560376987b..aec7610cc6b3 100644 --- a/drivers/wifi/nrf_wifi/src/wifi_mgmt_scan.c +++ b/drivers/wifi/nrf_wifi/src/wifi_mgmt_scan.c @@ -290,8 +290,10 @@ static inline enum wifi_security_type drv_to_wifi_mgmt(int drv_security_type) return WIFI_SECURITY_TYPE_PSK; case NRF_WIFI_WPA2_256: return WIFI_SECURITY_TYPE_PSK_SHA256; - case NRF_WIFI_WPA3: + case NRF_WIFI_WPA3_HNP: return WIFI_SECURITY_TYPE_SAE; + case NRF_WIFI_WPA3_H2E: + return WIFI_SECURITY_TYPE_SAE_H2E; case NRF_WIFI_WAPI: return WIFI_SECURITY_TYPE_WAPI; case NRF_WIFI_EAP: From 7695aefce1a6d1787915c3fe6459238ce19ef3e3 Mon Sep 17 00:00:00 2001 From: Sylvio Alves Date: Fri, 19 Dec 2025 11:26:59 -0300 Subject: [PATCH 1551/3659] boards: esp32: remove --no-init from openocd args Remove the --no-init flag to fix west debugserver on boards with built-in USB JTAG (ESP32-C6, ESP32-H2). Signed-off-by: Sylvio Alves --- boards/common/esp32.board.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boards/common/esp32.board.cmake b/boards/common/esp32.board.cmake index 4669c2e620be..d0f83434c144 100644 --- a/boards/common/esp32.board.cmake +++ b/boards/common/esp32.board.cmake @@ -3,7 +3,7 @@ board_set_flasher_ifnset(esp32) board_set_debugger_ifnset(openocd) -board_runner_args(openocd --no-init --no-halt --no-targets --no-load) +board_runner_args(openocd --no-halt --no-targets --no-load) board_runner_args(openocd --gdb-init "set remote hardware-watchpoint-limit 2") board_runner_args(openocd --gdb-init "maintenance flush register-cache") From aaec098e0e4a7d6309a123fae9c0e5b99e97dd02 Mon Sep 17 00:00:00 2001 From: Sylvio Alves Date: Fri, 19 Dec 2025 14:04:22 -0300 Subject: [PATCH 1552/3659] boards: esp32: enable Zephyr RTOS in openocd config Change ESP_RTOS from none to Zephyr in all ESP32 board openocd.cfg files to enable thread awareness during debug. Signed-off-by: Sylvio Alves --- boards/01space/esp32c3_042_oled/support/openocd.cfg | 2 +- boards/adafruit/feather_esp32s2/support/openocd.cfg | 4 ++-- boards/adafruit/feather_esp32s3/support/openocd.cfg | 4 ++-- boards/adafruit/feather_esp32s3_tft/support/openocd.cfg | 4 ++-- .../feather_esp32s3_tft_reverse/support/openocd.cfg | 4 ++-- boards/adafruit/qt_py_esp32s3/support/openocd.cfg | 4 ++-- boards/aithinker/esp32_cam/support/openocd.cfg | 4 ++-- boards/alientek/dnesp32s3b/support/openocd.cfg | 4 ++-- boards/dptechnics/walter/support/openocd.cfg | 4 ++-- boards/espressif/esp32_devkitc/support/openocd.cfg | 4 ++-- boards/espressif/esp32_ethernet_kit/support/openocd.cfg | 4 ++-- boards/espressif/esp32c3_devkitc/support/openocd.cfg | 2 +- boards/espressif/esp32c3_devkitm/support/openocd.cfg | 2 +- boards/espressif/esp32c3_rust/support/openocd.cfg | 2 +- boards/espressif/esp32c6_devkitc/support/openocd.cfg | 2 +- boards/espressif/esp32h2_devkitm/support/openocd.cfg | 2 +- boards/espressif/esp32s2_devkitc/support/openocd.cfg | 2 +- boards/espressif/esp32s2_saola/support/openocd.cfg | 2 +- boards/espressif/esp32s3_devkitc/support/openocd.cfg | 6 ++---- boards/espressif/esp32s3_eye/support/openocd.cfg | 6 ++---- boards/espressif/esp8684_devkitm/support/openocd.cfg | 2 +- boards/espressif/esp_wrover_kit/support/openocd.cfg | 4 ++-- boards/franzininho/esp32s2_franzininho/support/openocd.cfg | 2 +- .../heltec_wireless_stick_lite_v3/support/openocd.cfg | 4 ++-- boards/heltec/heltec_wireless_tracker/support/openocd.cfg | 4 ++-- boards/kincony/kincony_kc868_a32/support/openocd.cfg | 4 ++-- boards/lilygo/tdongle_s3/support/openocd.cfg | 4 ++-- boards/lilygo/ttgo_lora32/support/openocd.cfg | 4 ++-- boards/lilygo/ttgo_t7v1_5/support/openocd.cfg | 3 ++- boards/lilygo/ttgo_t8c3/support/openocd.cfg | 2 +- boards/lilygo/ttgo_t8s3/support/openocd.cfg | 4 ++-- boards/lilygo/ttgo_tbeam/support/openocd.cfg | 4 ++-- boards/lilygo/ttgo_toiplus/support/openocd.cfg | 2 +- boards/lilygo/twatch_s3/support/openocd.cfg | 4 ++-- boards/luatos/esp32c3_luatos_core/support/openocd.cfg | 2 +- boards/luatos/esp32s3_luatos_core/support/openocd.cfg | 4 ++-- boards/m5stack/m5stack_core2/support/openocd.cfg | 4 ++-- boards/m5stack/m5stack_cores3/support/openocd.cfg | 4 ++-- boards/m5stack/m5stack_fire/support/openocd.cfg | 4 ++-- boards/m5stack/m5stack_nanoc6/support/openocd.cfg | 2 +- boards/m5stack/m5stickc_plus/support/openocd.cfg | 4 ++-- boards/m5stack/stamp_c3/support/openocd.cfg | 2 +- boards/olimex/olimex_esp32_evb/support/openocd.cfg | 4 ++-- boards/others/doit_esp32_devkit_v1/support/openocd.cfg | 4 ++-- boards/others/esp32c3_lckfb/support/openocd.cfg | 2 +- boards/others/esp32c3_supermini/support/openocd.cfg | 2 +- boards/others/icev_wireless/support/openocd.cfg | 2 +- boards/pcbcupid/glyph_c6/support/openocd.cfg | 2 +- boards/rakwireless/rak3112/support/openocd.cfg | 4 ++-- boards/seeed/xiao_esp32c3/support/openocd.cfg | 2 +- boards/seeed/xiao_esp32c6/support/openocd.cfg | 2 +- boards/seeed/xiao_esp32s3/support/openocd.cfg | 4 ++-- boards/vcc-gnd/yd_esp32/support/openocd.cfg | 4 ++-- boards/waveshare/esp32s3_geek/support/openocd.cfg | 4 ++-- boards/waveshare/esp32s3_matrix/support/openocd.cfg | 4 ++-- boards/waveshare/esp32s3_touch_lcd_1_28/support/openocd.cfg | 4 ++-- boards/we/orthosie1ev/support/openocd.cfg | 2 +- boards/weact/esp32c3_mini/support/openocd.cfg | 2 +- boards/weact/esp32c6_mini/support/openocd.cfg | 2 +- boards/weact/esp32s3_mini/support/openocd.cfg | 4 ++-- boards/weact/weact_esp32s3_b/support/openocd.cfg | 4 ++-- boards/wemos/esp32s2_lolin_mini/support/openocd.cfg | 2 +- boards/wemos/lolin32_lite/support/openocd.cfg | 4 ++-- 63 files changed, 101 insertions(+), 104 deletions(-) diff --git a/boards/01space/esp32c3_042_oled/support/openocd.cfg b/boards/01space/esp32c3_042_oled/support/openocd.cfg index 7421637880c7..cf1bc91bbf9f 100644 --- a/boards/01space/esp32c3_042_oled/support/openocd.cfg +++ b/boards/01space/esp32c3_042_oled/support/openocd.cfg @@ -1,4 +1,4 @@ -set ESP_RTOS none +set ESP_RTOS Zephyr source [find interface/esp_usb_jtag.cfg] diff --git a/boards/adafruit/feather_esp32s2/support/openocd.cfg b/boards/adafruit/feather_esp32s2/support/openocd.cfg index 2f740b4a36ab..b45e13c53d01 100644 --- a/boards/adafruit/feather_esp32s2/support/openocd.cfg +++ b/boards/adafruit/feather_esp32s2/support/openocd.cfg @@ -1,5 +1,5 @@ -set ESP_RTOS none -set ESP32_ONLYCPU 1 +set ESP_RTOS Zephyr +set ESP_ONLYCPU 1 # Source the JTAG interface configuration file source [find interface/esp_usb_jtag.cfg] diff --git a/boards/adafruit/feather_esp32s3/support/openocd.cfg b/boards/adafruit/feather_esp32s3/support/openocd.cfg index 2f740b4a36ab..b45e13c53d01 100644 --- a/boards/adafruit/feather_esp32s3/support/openocd.cfg +++ b/boards/adafruit/feather_esp32s3/support/openocd.cfg @@ -1,5 +1,5 @@ -set ESP_RTOS none -set ESP32_ONLYCPU 1 +set ESP_RTOS Zephyr +set ESP_ONLYCPU 1 # Source the JTAG interface configuration file source [find interface/esp_usb_jtag.cfg] diff --git a/boards/adafruit/feather_esp32s3_tft/support/openocd.cfg b/boards/adafruit/feather_esp32s3_tft/support/openocd.cfg index 2f740b4a36ab..b45e13c53d01 100644 --- a/boards/adafruit/feather_esp32s3_tft/support/openocd.cfg +++ b/boards/adafruit/feather_esp32s3_tft/support/openocd.cfg @@ -1,5 +1,5 @@ -set ESP_RTOS none -set ESP32_ONLYCPU 1 +set ESP_RTOS Zephyr +set ESP_ONLYCPU 1 # Source the JTAG interface configuration file source [find interface/esp_usb_jtag.cfg] diff --git a/boards/adafruit/feather_esp32s3_tft_reverse/support/openocd.cfg b/boards/adafruit/feather_esp32s3_tft_reverse/support/openocd.cfg index 2f740b4a36ab..b45e13c53d01 100644 --- a/boards/adafruit/feather_esp32s3_tft_reverse/support/openocd.cfg +++ b/boards/adafruit/feather_esp32s3_tft_reverse/support/openocd.cfg @@ -1,5 +1,5 @@ -set ESP_RTOS none -set ESP32_ONLYCPU 1 +set ESP_RTOS Zephyr +set ESP_ONLYCPU 1 # Source the JTAG interface configuration file source [find interface/esp_usb_jtag.cfg] diff --git a/boards/adafruit/qt_py_esp32s3/support/openocd.cfg b/boards/adafruit/qt_py_esp32s3/support/openocd.cfg index 2f740b4a36ab..b45e13c53d01 100644 --- a/boards/adafruit/qt_py_esp32s3/support/openocd.cfg +++ b/boards/adafruit/qt_py_esp32s3/support/openocd.cfg @@ -1,5 +1,5 @@ -set ESP_RTOS none -set ESP32_ONLYCPU 1 +set ESP_RTOS Zephyr +set ESP_ONLYCPU 1 # Source the JTAG interface configuration file source [find interface/esp_usb_jtag.cfg] diff --git a/boards/aithinker/esp32_cam/support/openocd.cfg b/boards/aithinker/esp32_cam/support/openocd.cfg index 338e6e4e6eae..41411e37140e 100644 --- a/boards/aithinker/esp32_cam/support/openocd.cfg +++ b/boards/aithinker/esp32_cam/support/openocd.cfg @@ -1,5 +1,5 @@ -set ESP_RTOS none -set ESP32_ONLYCPU 1 +set ESP_RTOS Zephyr +set ESP_ONLYCPU 1 source [find interface/ftdi/esp32_devkitj_v1.cfg] source [find target/esp32.cfg] diff --git a/boards/alientek/dnesp32s3b/support/openocd.cfg b/boards/alientek/dnesp32s3b/support/openocd.cfg index 625341a5aa87..7b2d51e21ad0 100644 --- a/boards/alientek/dnesp32s3b/support/openocd.cfg +++ b/boards/alientek/dnesp32s3b/support/openocd.cfg @@ -1,8 +1,8 @@ # Copyright (c) 2024 Joel Guittet # SPDX-License-Identifier: Apache-2.0 -set ESP_RTOS none -set ESP32_ONLYCPU 1 +set ESP_RTOS Zephyr +set ESP_ONLYCPU 1 # Source the JTAG interface configuration file source [find interface/esp_usb_jtag.cfg] diff --git a/boards/dptechnics/walter/support/openocd.cfg b/boards/dptechnics/walter/support/openocd.cfg index 2f740b4a36ab..b45e13c53d01 100644 --- a/boards/dptechnics/walter/support/openocd.cfg +++ b/boards/dptechnics/walter/support/openocd.cfg @@ -1,5 +1,5 @@ -set ESP_RTOS none -set ESP32_ONLYCPU 1 +set ESP_RTOS Zephyr +set ESP_ONLYCPU 1 # Source the JTAG interface configuration file source [find interface/esp_usb_jtag.cfg] diff --git a/boards/espressif/esp32_devkitc/support/openocd.cfg b/boards/espressif/esp32_devkitc/support/openocd.cfg index 338e6e4e6eae..41411e37140e 100644 --- a/boards/espressif/esp32_devkitc/support/openocd.cfg +++ b/boards/espressif/esp32_devkitc/support/openocd.cfg @@ -1,5 +1,5 @@ -set ESP_RTOS none -set ESP32_ONLYCPU 1 +set ESP_RTOS Zephyr +set ESP_ONLYCPU 1 source [find interface/ftdi/esp32_devkitj_v1.cfg] source [find target/esp32.cfg] diff --git a/boards/espressif/esp32_ethernet_kit/support/openocd.cfg b/boards/espressif/esp32_ethernet_kit/support/openocd.cfg index 338e6e4e6eae..41411e37140e 100644 --- a/boards/espressif/esp32_ethernet_kit/support/openocd.cfg +++ b/boards/espressif/esp32_ethernet_kit/support/openocd.cfg @@ -1,5 +1,5 @@ -set ESP_RTOS none -set ESP32_ONLYCPU 1 +set ESP_RTOS Zephyr +set ESP_ONLYCPU 1 source [find interface/ftdi/esp32_devkitj_v1.cfg] source [find target/esp32.cfg] diff --git a/boards/espressif/esp32c3_devkitc/support/openocd.cfg b/boards/espressif/esp32c3_devkitc/support/openocd.cfg index 92a792fecb8e..6aed93913348 100644 --- a/boards/espressif/esp32c3_devkitc/support/openocd.cfg +++ b/boards/espressif/esp32c3_devkitc/support/openocd.cfg @@ -1,4 +1,4 @@ -set ESP_RTOS none +set ESP_RTOS Zephyr # ESP32C3 has built-in JTAG interface over USB port in pins GPIO18/GPIO19 (D-/D+). # Uncomment the line below to enable USB debugging. diff --git a/boards/espressif/esp32c3_devkitm/support/openocd.cfg b/boards/espressif/esp32c3_devkitm/support/openocd.cfg index 92a792fecb8e..6aed93913348 100644 --- a/boards/espressif/esp32c3_devkitm/support/openocd.cfg +++ b/boards/espressif/esp32c3_devkitm/support/openocd.cfg @@ -1,4 +1,4 @@ -set ESP_RTOS none +set ESP_RTOS Zephyr # ESP32C3 has built-in JTAG interface over USB port in pins GPIO18/GPIO19 (D-/D+). # Uncomment the line below to enable USB debugging. diff --git a/boards/espressif/esp32c3_rust/support/openocd.cfg b/boards/espressif/esp32c3_rust/support/openocd.cfg index e846c967fb1c..f5fa2c4906b3 100644 --- a/boards/espressif/esp32c3_rust/support/openocd.cfg +++ b/boards/espressif/esp32c3_rust/support/openocd.cfg @@ -1,4 +1,4 @@ -set ESP_RTOS none +set ESP_RTOS Zephyr # ESP32C3 has built-in JTAG interface over USB port in pins GPIO18/GPIO19 (D-/D+). # Uncomment the line below to enable USB debugging. diff --git a/boards/espressif/esp32c6_devkitc/support/openocd.cfg b/boards/espressif/esp32c6_devkitc/support/openocd.cfg index d86a5517a4ca..29d5fac25c5a 100644 --- a/boards/espressif/esp32c6_devkitc/support/openocd.cfg +++ b/boards/espressif/esp32c6_devkitc/support/openocd.cfg @@ -1,4 +1,4 @@ # ESP32C6 has built-in JTAG interface over USB port in pins GPIO13/GPIO12 (D-/D+). -set ESP_RTOS none +set ESP_RTOS Zephyr source [find board/esp32c6-builtin.cfg] diff --git a/boards/espressif/esp32h2_devkitm/support/openocd.cfg b/boards/espressif/esp32h2_devkitm/support/openocd.cfg index 5dac2bad03f9..19c9b79ef7e6 100644 --- a/boards/espressif/esp32h2_devkitm/support/openocd.cfg +++ b/boards/espressif/esp32h2_devkitm/support/openocd.cfg @@ -1,4 +1,4 @@ # ESP32H2 has built-in JTAG interface over USB port in pins GPIO26/GPIO27 (D-/D+). -set ESP_RTOS none +set ESP_RTOS Zephyr source [find board/esp32h2-builtin.cfg] diff --git a/boards/espressif/esp32s2_devkitc/support/openocd.cfg b/boards/espressif/esp32s2_devkitc/support/openocd.cfg index f75d53b0b34c..6b71dc41b12f 100644 --- a/boards/espressif/esp32s2_devkitc/support/openocd.cfg +++ b/boards/espressif/esp32s2_devkitc/support/openocd.cfg @@ -1,4 +1,4 @@ -set ESP_RTOS none +set ESP_RTOS Zephyr source [find interface/ftdi/esp32s2_kaluga_v1.cfg] source [find target/esp32s2.cfg] diff --git a/boards/espressif/esp32s2_saola/support/openocd.cfg b/boards/espressif/esp32s2_saola/support/openocd.cfg index f75d53b0b34c..6b71dc41b12f 100644 --- a/boards/espressif/esp32s2_saola/support/openocd.cfg +++ b/boards/espressif/esp32s2_saola/support/openocd.cfg @@ -1,4 +1,4 @@ -set ESP_RTOS none +set ESP_RTOS Zephyr source [find interface/ftdi/esp32s2_kaluga_v1.cfg] source [find target/esp32s2.cfg] diff --git a/boards/espressif/esp32s3_devkitc/support/openocd.cfg b/boards/espressif/esp32s3_devkitc/support/openocd.cfg index 2f740b4a36ab..421b173cbd4e 100644 --- a/boards/espressif/esp32s3_devkitc/support/openocd.cfg +++ b/boards/espressif/esp32s3_devkitc/support/openocd.cfg @@ -1,7 +1,5 @@ -set ESP_RTOS none -set ESP32_ONLYCPU 1 +set ESP_RTOS Zephyr +set ESP_ONLYCPU 1 -# Source the JTAG interface configuration file source [find interface/esp_usb_jtag.cfg] -# Source the ESP32-S3 configuration file source [find target/esp32s3.cfg] diff --git a/boards/espressif/esp32s3_eye/support/openocd.cfg b/boards/espressif/esp32s3_eye/support/openocd.cfg index 2f740b4a36ab..421b173cbd4e 100644 --- a/boards/espressif/esp32s3_eye/support/openocd.cfg +++ b/boards/espressif/esp32s3_eye/support/openocd.cfg @@ -1,7 +1,5 @@ -set ESP_RTOS none -set ESP32_ONLYCPU 1 +set ESP_RTOS Zephyr +set ESP_ONLYCPU 1 -# Source the JTAG interface configuration file source [find interface/esp_usb_jtag.cfg] -# Source the ESP32-S3 configuration file source [find target/esp32s3.cfg] diff --git a/boards/espressif/esp8684_devkitm/support/openocd.cfg b/boards/espressif/esp8684_devkitm/support/openocd.cfg index 93209701b692..a024cf396087 100644 --- a/boards/espressif/esp8684_devkitm/support/openocd.cfg +++ b/boards/espressif/esp8684_devkitm/support/openocd.cfg @@ -1,4 +1,4 @@ -set ESP_RTOS none +set ESP_RTOS Zephyr # Use external JTAG interface, such as ESP-Prog source [find interface/ftdi/esp32_devkitj_v1.cfg] diff --git a/boards/espressif/esp_wrover_kit/support/openocd.cfg b/boards/espressif/esp_wrover_kit/support/openocd.cfg index 338e6e4e6eae..41411e37140e 100644 --- a/boards/espressif/esp_wrover_kit/support/openocd.cfg +++ b/boards/espressif/esp_wrover_kit/support/openocd.cfg @@ -1,5 +1,5 @@ -set ESP_RTOS none -set ESP32_ONLYCPU 1 +set ESP_RTOS Zephyr +set ESP_ONLYCPU 1 source [find interface/ftdi/esp32_devkitj_v1.cfg] source [find target/esp32.cfg] diff --git a/boards/franzininho/esp32s2_franzininho/support/openocd.cfg b/boards/franzininho/esp32s2_franzininho/support/openocd.cfg index f75d53b0b34c..6b71dc41b12f 100644 --- a/boards/franzininho/esp32s2_franzininho/support/openocd.cfg +++ b/boards/franzininho/esp32s2_franzininho/support/openocd.cfg @@ -1,4 +1,4 @@ -set ESP_RTOS none +set ESP_RTOS Zephyr source [find interface/ftdi/esp32s2_kaluga_v1.cfg] source [find target/esp32s2.cfg] diff --git a/boards/heltec/heltec_wireless_stick_lite_v3/support/openocd.cfg b/boards/heltec/heltec_wireless_stick_lite_v3/support/openocd.cfg index 2f740b4a36ab..b45e13c53d01 100644 --- a/boards/heltec/heltec_wireless_stick_lite_v3/support/openocd.cfg +++ b/boards/heltec/heltec_wireless_stick_lite_v3/support/openocd.cfg @@ -1,5 +1,5 @@ -set ESP_RTOS none -set ESP32_ONLYCPU 1 +set ESP_RTOS Zephyr +set ESP_ONLYCPU 1 # Source the JTAG interface configuration file source [find interface/esp_usb_jtag.cfg] diff --git a/boards/heltec/heltec_wireless_tracker/support/openocd.cfg b/boards/heltec/heltec_wireless_tracker/support/openocd.cfg index 2f740b4a36ab..b45e13c53d01 100644 --- a/boards/heltec/heltec_wireless_tracker/support/openocd.cfg +++ b/boards/heltec/heltec_wireless_tracker/support/openocd.cfg @@ -1,5 +1,5 @@ -set ESP_RTOS none -set ESP32_ONLYCPU 1 +set ESP_RTOS Zephyr +set ESP_ONLYCPU 1 # Source the JTAG interface configuration file source [find interface/esp_usb_jtag.cfg] diff --git a/boards/kincony/kincony_kc868_a32/support/openocd.cfg b/boards/kincony/kincony_kc868_a32/support/openocd.cfg index 338e6e4e6eae..41411e37140e 100644 --- a/boards/kincony/kincony_kc868_a32/support/openocd.cfg +++ b/boards/kincony/kincony_kc868_a32/support/openocd.cfg @@ -1,5 +1,5 @@ -set ESP_RTOS none -set ESP32_ONLYCPU 1 +set ESP_RTOS Zephyr +set ESP_ONLYCPU 1 source [find interface/ftdi/esp32_devkitj_v1.cfg] source [find target/esp32.cfg] diff --git a/boards/lilygo/tdongle_s3/support/openocd.cfg b/boards/lilygo/tdongle_s3/support/openocd.cfg index 0b2c4909fe0e..dc401fe1b974 100644 --- a/boards/lilygo/tdongle_s3/support/openocd.cfg +++ b/boards/lilygo/tdongle_s3/support/openocd.cfg @@ -1,5 +1,5 @@ -set ESP_RTOS none -set ESP32_ONLYCPU 1 +set ESP_RTOS Zephyr +set ESP_ONLYCPU 1 source [find interface/esp_usb_jtag.cfg] diff --git a/boards/lilygo/ttgo_lora32/support/openocd.cfg b/boards/lilygo/ttgo_lora32/support/openocd.cfg index 338e6e4e6eae..41411e37140e 100644 --- a/boards/lilygo/ttgo_lora32/support/openocd.cfg +++ b/boards/lilygo/ttgo_lora32/support/openocd.cfg @@ -1,5 +1,5 @@ -set ESP_RTOS none -set ESP32_ONLYCPU 1 +set ESP_RTOS Zephyr +set ESP_ONLYCPU 1 source [find interface/ftdi/esp32_devkitj_v1.cfg] source [find target/esp32.cfg] diff --git a/boards/lilygo/ttgo_t7v1_5/support/openocd.cfg b/boards/lilygo/ttgo_t7v1_5/support/openocd.cfg index 756e960dd203..2d704722bbc7 100644 --- a/boards/lilygo/ttgo_t7v1_5/support/openocd.cfg +++ b/boards/lilygo/ttgo_t7v1_5/support/openocd.cfg @@ -1,4 +1,5 @@ -set ESP_RTOS none +set ESP_RTOS Zephyr +set ESP_ONLYCPU 1 source [find interface/esp_usb_jtag.cfg] diff --git a/boards/lilygo/ttgo_t8c3/support/openocd.cfg b/boards/lilygo/ttgo_t8c3/support/openocd.cfg index 02754ff2a73c..e896e7e7f8db 100644 --- a/boards/lilygo/ttgo_t8c3/support/openocd.cfg +++ b/boards/lilygo/ttgo_t8c3/support/openocd.cfg @@ -1,4 +1,4 @@ -set ESP_RTOS none +set ESP_RTOS Zephyr source [find interface/esp_usb_jtag.cfg] diff --git a/boards/lilygo/ttgo_t8s3/support/openocd.cfg b/boards/lilygo/ttgo_t8s3/support/openocd.cfg index 0b2c4909fe0e..dc401fe1b974 100644 --- a/boards/lilygo/ttgo_t8s3/support/openocd.cfg +++ b/boards/lilygo/ttgo_t8s3/support/openocd.cfg @@ -1,5 +1,5 @@ -set ESP_RTOS none -set ESP32_ONLYCPU 1 +set ESP_RTOS Zephyr +set ESP_ONLYCPU 1 source [find interface/esp_usb_jtag.cfg] diff --git a/boards/lilygo/ttgo_tbeam/support/openocd.cfg b/boards/lilygo/ttgo_tbeam/support/openocd.cfg index 338e6e4e6eae..41411e37140e 100644 --- a/boards/lilygo/ttgo_tbeam/support/openocd.cfg +++ b/boards/lilygo/ttgo_tbeam/support/openocd.cfg @@ -1,5 +1,5 @@ -set ESP_RTOS none -set ESP32_ONLYCPU 1 +set ESP_RTOS Zephyr +set ESP_ONLYCPU 1 source [find interface/ftdi/esp32_devkitj_v1.cfg] source [find target/esp32.cfg] diff --git a/boards/lilygo/ttgo_toiplus/support/openocd.cfg b/boards/lilygo/ttgo_toiplus/support/openocd.cfg index 02754ff2a73c..e896e7e7f8db 100644 --- a/boards/lilygo/ttgo_toiplus/support/openocd.cfg +++ b/boards/lilygo/ttgo_toiplus/support/openocd.cfg @@ -1,4 +1,4 @@ -set ESP_RTOS none +set ESP_RTOS Zephyr source [find interface/esp_usb_jtag.cfg] diff --git a/boards/lilygo/twatch_s3/support/openocd.cfg b/boards/lilygo/twatch_s3/support/openocd.cfg index 0b2c4909fe0e..dc401fe1b974 100644 --- a/boards/lilygo/twatch_s3/support/openocd.cfg +++ b/boards/lilygo/twatch_s3/support/openocd.cfg @@ -1,5 +1,5 @@ -set ESP_RTOS none -set ESP32_ONLYCPU 1 +set ESP_RTOS Zephyr +set ESP_ONLYCPU 1 source [find interface/esp_usb_jtag.cfg] diff --git a/boards/luatos/esp32c3_luatos_core/support/openocd.cfg b/boards/luatos/esp32c3_luatos_core/support/openocd.cfg index 12065b5e6304..c758eb8203e4 100644 --- a/boards/luatos/esp32c3_luatos_core/support/openocd.cfg +++ b/boards/luatos/esp32c3_luatos_core/support/openocd.cfg @@ -1,5 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -set ESP_RTOS none +set ESP_RTOS Zephyr # ESP32C3 has built-in JTAG interface over USB port in pins GPIO18/GPIO19 (D-/D+). # Uncomment the line below to enable USB debugging. diff --git a/boards/luatos/esp32s3_luatos_core/support/openocd.cfg b/boards/luatos/esp32s3_luatos_core/support/openocd.cfg index 2f740b4a36ab..b45e13c53d01 100644 --- a/boards/luatos/esp32s3_luatos_core/support/openocd.cfg +++ b/boards/luatos/esp32s3_luatos_core/support/openocd.cfg @@ -1,5 +1,5 @@ -set ESP_RTOS none -set ESP32_ONLYCPU 1 +set ESP_RTOS Zephyr +set ESP_ONLYCPU 1 # Source the JTAG interface configuration file source [find interface/esp_usb_jtag.cfg] diff --git a/boards/m5stack/m5stack_core2/support/openocd.cfg b/boards/m5stack/m5stack_core2/support/openocd.cfg index 338e6e4e6eae..41411e37140e 100644 --- a/boards/m5stack/m5stack_core2/support/openocd.cfg +++ b/boards/m5stack/m5stack_core2/support/openocd.cfg @@ -1,5 +1,5 @@ -set ESP_RTOS none -set ESP32_ONLYCPU 1 +set ESP_RTOS Zephyr +set ESP_ONLYCPU 1 source [find interface/ftdi/esp32_devkitj_v1.cfg] source [find target/esp32.cfg] diff --git a/boards/m5stack/m5stack_cores3/support/openocd.cfg b/boards/m5stack/m5stack_cores3/support/openocd.cfg index 2f740b4a36ab..b45e13c53d01 100644 --- a/boards/m5stack/m5stack_cores3/support/openocd.cfg +++ b/boards/m5stack/m5stack_cores3/support/openocd.cfg @@ -1,5 +1,5 @@ -set ESP_RTOS none -set ESP32_ONLYCPU 1 +set ESP_RTOS Zephyr +set ESP_ONLYCPU 1 # Source the JTAG interface configuration file source [find interface/esp_usb_jtag.cfg] diff --git a/boards/m5stack/m5stack_fire/support/openocd.cfg b/boards/m5stack/m5stack_fire/support/openocd.cfg index 338e6e4e6eae..41411e37140e 100644 --- a/boards/m5stack/m5stack_fire/support/openocd.cfg +++ b/boards/m5stack/m5stack_fire/support/openocd.cfg @@ -1,5 +1,5 @@ -set ESP_RTOS none -set ESP32_ONLYCPU 1 +set ESP_RTOS Zephyr +set ESP_ONLYCPU 1 source [find interface/ftdi/esp32_devkitj_v1.cfg] source [find target/esp32.cfg] diff --git a/boards/m5stack/m5stack_nanoc6/support/openocd.cfg b/boards/m5stack/m5stack_nanoc6/support/openocd.cfg index d86a5517a4ca..29d5fac25c5a 100644 --- a/boards/m5stack/m5stack_nanoc6/support/openocd.cfg +++ b/boards/m5stack/m5stack_nanoc6/support/openocd.cfg @@ -1,4 +1,4 @@ # ESP32C6 has built-in JTAG interface over USB port in pins GPIO13/GPIO12 (D-/D+). -set ESP_RTOS none +set ESP_RTOS Zephyr source [find board/esp32c6-builtin.cfg] diff --git a/boards/m5stack/m5stickc_plus/support/openocd.cfg b/boards/m5stack/m5stickc_plus/support/openocd.cfg index 338e6e4e6eae..41411e37140e 100644 --- a/boards/m5stack/m5stickc_plus/support/openocd.cfg +++ b/boards/m5stack/m5stickc_plus/support/openocd.cfg @@ -1,5 +1,5 @@ -set ESP_RTOS none -set ESP32_ONLYCPU 1 +set ESP_RTOS Zephyr +set ESP_ONLYCPU 1 source [find interface/ftdi/esp32_devkitj_v1.cfg] source [find target/esp32.cfg] diff --git a/boards/m5stack/stamp_c3/support/openocd.cfg b/boards/m5stack/stamp_c3/support/openocd.cfg index 92e47fabefb3..8890eee15b25 100644 --- a/boards/m5stack/stamp_c3/support/openocd.cfg +++ b/boards/m5stack/stamp_c3/support/openocd.cfg @@ -1,7 +1,7 @@ # Copyright (c) 2022 TOKITA Hiroshi # SPDX-License-Identifier: Apache-2.0 -set ESP_RTOS none +set ESP_RTOS Zephyr source [find interface/esp_usb_jtag.cfg] diff --git a/boards/olimex/olimex_esp32_evb/support/openocd.cfg b/boards/olimex/olimex_esp32_evb/support/openocd.cfg index 338e6e4e6eae..41411e37140e 100644 --- a/boards/olimex/olimex_esp32_evb/support/openocd.cfg +++ b/boards/olimex/olimex_esp32_evb/support/openocd.cfg @@ -1,5 +1,5 @@ -set ESP_RTOS none -set ESP32_ONLYCPU 1 +set ESP_RTOS Zephyr +set ESP_ONLYCPU 1 source [find interface/ftdi/esp32_devkitj_v1.cfg] source [find target/esp32.cfg] diff --git a/boards/others/doit_esp32_devkit_v1/support/openocd.cfg b/boards/others/doit_esp32_devkit_v1/support/openocd.cfg index 338e6e4e6eae..41411e37140e 100644 --- a/boards/others/doit_esp32_devkit_v1/support/openocd.cfg +++ b/boards/others/doit_esp32_devkit_v1/support/openocd.cfg @@ -1,5 +1,5 @@ -set ESP_RTOS none -set ESP32_ONLYCPU 1 +set ESP_RTOS Zephyr +set ESP_ONLYCPU 1 source [find interface/ftdi/esp32_devkitj_v1.cfg] source [find target/esp32.cfg] diff --git a/boards/others/esp32c3_lckfb/support/openocd.cfg b/boards/others/esp32c3_lckfb/support/openocd.cfg index 92a792fecb8e..6aed93913348 100644 --- a/boards/others/esp32c3_lckfb/support/openocd.cfg +++ b/boards/others/esp32c3_lckfb/support/openocd.cfg @@ -1,4 +1,4 @@ -set ESP_RTOS none +set ESP_RTOS Zephyr # ESP32C3 has built-in JTAG interface over USB port in pins GPIO18/GPIO19 (D-/D+). # Uncomment the line below to enable USB debugging. diff --git a/boards/others/esp32c3_supermini/support/openocd.cfg b/boards/others/esp32c3_supermini/support/openocd.cfg index 7fa9d1362475..540169f08ba5 100644 --- a/boards/others/esp32c3_supermini/support/openocd.cfg +++ b/boards/others/esp32c3_supermini/support/openocd.cfg @@ -1,7 +1,7 @@ # Copyright (c) 2024 Arrel Neumiller # SPDX-License-Identifier: Apache-2.0 -set ESP_RTOS none +set ESP_RTOS Zephyr # ESP32C3 has built-in JTAG interface over USB port in pins GPIO18/GPIO19 (D-/D+). # Uncomment the line below to enable USB debugging. diff --git a/boards/others/icev_wireless/support/openocd.cfg b/boards/others/icev_wireless/support/openocd.cfg index 7421637880c7..cf1bc91bbf9f 100644 --- a/boards/others/icev_wireless/support/openocd.cfg +++ b/boards/others/icev_wireless/support/openocd.cfg @@ -1,4 +1,4 @@ -set ESP_RTOS none +set ESP_RTOS Zephyr source [find interface/esp_usb_jtag.cfg] diff --git a/boards/pcbcupid/glyph_c6/support/openocd.cfg b/boards/pcbcupid/glyph_c6/support/openocd.cfg index d86a5517a4ca..29d5fac25c5a 100644 --- a/boards/pcbcupid/glyph_c6/support/openocd.cfg +++ b/boards/pcbcupid/glyph_c6/support/openocd.cfg @@ -1,4 +1,4 @@ # ESP32C6 has built-in JTAG interface over USB port in pins GPIO13/GPIO12 (D-/D+). -set ESP_RTOS none +set ESP_RTOS Zephyr source [find board/esp32c6-builtin.cfg] diff --git a/boards/rakwireless/rak3112/support/openocd.cfg b/boards/rakwireless/rak3112/support/openocd.cfg index 2f740b4a36ab..b45e13c53d01 100644 --- a/boards/rakwireless/rak3112/support/openocd.cfg +++ b/boards/rakwireless/rak3112/support/openocd.cfg @@ -1,5 +1,5 @@ -set ESP_RTOS none -set ESP32_ONLYCPU 1 +set ESP_RTOS Zephyr +set ESP_ONLYCPU 1 # Source the JTAG interface configuration file source [find interface/esp_usb_jtag.cfg] diff --git a/boards/seeed/xiao_esp32c3/support/openocd.cfg b/boards/seeed/xiao_esp32c3/support/openocd.cfg index 7421637880c7..cf1bc91bbf9f 100644 --- a/boards/seeed/xiao_esp32c3/support/openocd.cfg +++ b/boards/seeed/xiao_esp32c3/support/openocd.cfg @@ -1,4 +1,4 @@ -set ESP_RTOS none +set ESP_RTOS Zephyr source [find interface/esp_usb_jtag.cfg] diff --git a/boards/seeed/xiao_esp32c6/support/openocd.cfg b/boards/seeed/xiao_esp32c6/support/openocd.cfg index d86a5517a4ca..29d5fac25c5a 100644 --- a/boards/seeed/xiao_esp32c6/support/openocd.cfg +++ b/boards/seeed/xiao_esp32c6/support/openocd.cfg @@ -1,4 +1,4 @@ # ESP32C6 has built-in JTAG interface over USB port in pins GPIO13/GPIO12 (D-/D+). -set ESP_RTOS none +set ESP_RTOS Zephyr source [find board/esp32c6-builtin.cfg] diff --git a/boards/seeed/xiao_esp32s3/support/openocd.cfg b/boards/seeed/xiao_esp32s3/support/openocd.cfg index 2f740b4a36ab..b45e13c53d01 100644 --- a/boards/seeed/xiao_esp32s3/support/openocd.cfg +++ b/boards/seeed/xiao_esp32s3/support/openocd.cfg @@ -1,5 +1,5 @@ -set ESP_RTOS none -set ESP32_ONLYCPU 1 +set ESP_RTOS Zephyr +set ESP_ONLYCPU 1 # Source the JTAG interface configuration file source [find interface/esp_usb_jtag.cfg] diff --git a/boards/vcc-gnd/yd_esp32/support/openocd.cfg b/boards/vcc-gnd/yd_esp32/support/openocd.cfg index 338e6e4e6eae..41411e37140e 100644 --- a/boards/vcc-gnd/yd_esp32/support/openocd.cfg +++ b/boards/vcc-gnd/yd_esp32/support/openocd.cfg @@ -1,5 +1,5 @@ -set ESP_RTOS none -set ESP32_ONLYCPU 1 +set ESP_RTOS Zephyr +set ESP_ONLYCPU 1 source [find interface/ftdi/esp32_devkitj_v1.cfg] source [find target/esp32.cfg] diff --git a/boards/waveshare/esp32s3_geek/support/openocd.cfg b/boards/waveshare/esp32s3_geek/support/openocd.cfg index 625341a5aa87..7b2d51e21ad0 100644 --- a/boards/waveshare/esp32s3_geek/support/openocd.cfg +++ b/boards/waveshare/esp32s3_geek/support/openocd.cfg @@ -1,8 +1,8 @@ # Copyright (c) 2024 Joel Guittet # SPDX-License-Identifier: Apache-2.0 -set ESP_RTOS none -set ESP32_ONLYCPU 1 +set ESP_RTOS Zephyr +set ESP_ONLYCPU 1 # Source the JTAG interface configuration file source [find interface/esp_usb_jtag.cfg] diff --git a/boards/waveshare/esp32s3_matrix/support/openocd.cfg b/boards/waveshare/esp32s3_matrix/support/openocd.cfg index 625341a5aa87..7b2d51e21ad0 100644 --- a/boards/waveshare/esp32s3_matrix/support/openocd.cfg +++ b/boards/waveshare/esp32s3_matrix/support/openocd.cfg @@ -1,8 +1,8 @@ # Copyright (c) 2024 Joel Guittet # SPDX-License-Identifier: Apache-2.0 -set ESP_RTOS none -set ESP32_ONLYCPU 1 +set ESP_RTOS Zephyr +set ESP_ONLYCPU 1 # Source the JTAG interface configuration file source [find interface/esp_usb_jtag.cfg] diff --git a/boards/waveshare/esp32s3_touch_lcd_1_28/support/openocd.cfg b/boards/waveshare/esp32s3_touch_lcd_1_28/support/openocd.cfg index 625341a5aa87..7b2d51e21ad0 100644 --- a/boards/waveshare/esp32s3_touch_lcd_1_28/support/openocd.cfg +++ b/boards/waveshare/esp32s3_touch_lcd_1_28/support/openocd.cfg @@ -1,8 +1,8 @@ # Copyright (c) 2024 Joel Guittet # SPDX-License-Identifier: Apache-2.0 -set ESP_RTOS none -set ESP32_ONLYCPU 1 +set ESP_RTOS Zephyr +set ESP_ONLYCPU 1 # Source the JTAG interface configuration file source [find interface/esp_usb_jtag.cfg] diff --git a/boards/we/orthosie1ev/support/openocd.cfg b/boards/we/orthosie1ev/support/openocd.cfg index 92a792fecb8e..6aed93913348 100644 --- a/boards/we/orthosie1ev/support/openocd.cfg +++ b/boards/we/orthosie1ev/support/openocd.cfg @@ -1,4 +1,4 @@ -set ESP_RTOS none +set ESP_RTOS Zephyr # ESP32C3 has built-in JTAG interface over USB port in pins GPIO18/GPIO19 (D-/D+). # Uncomment the line below to enable USB debugging. diff --git a/boards/weact/esp32c3_mini/support/openocd.cfg b/boards/weact/esp32c3_mini/support/openocd.cfg index 0ad11b02ae91..66073e4e28ba 100644 --- a/boards/weact/esp32c3_mini/support/openocd.cfg +++ b/boards/weact/esp32c3_mini/support/openocd.cfg @@ -1,4 +1,4 @@ -set ESP_RTOS none +set ESP_RTOS Zephyr # ESP32C3 has built-in JTAG interface over USB port in pins GPIO18/GPIO19 (D-/D+). # Uncomment the line below to enable USB debugging. diff --git a/boards/weact/esp32c6_mini/support/openocd.cfg b/boards/weact/esp32c6_mini/support/openocd.cfg index d86a5517a4ca..29d5fac25c5a 100644 --- a/boards/weact/esp32c6_mini/support/openocd.cfg +++ b/boards/weact/esp32c6_mini/support/openocd.cfg @@ -1,4 +1,4 @@ # ESP32C6 has built-in JTAG interface over USB port in pins GPIO13/GPIO12 (D-/D+). -set ESP_RTOS none +set ESP_RTOS Zephyr source [find board/esp32c6-builtin.cfg] diff --git a/boards/weact/esp32s3_mini/support/openocd.cfg b/boards/weact/esp32s3_mini/support/openocd.cfg index 2f740b4a36ab..b45e13c53d01 100644 --- a/boards/weact/esp32s3_mini/support/openocd.cfg +++ b/boards/weact/esp32s3_mini/support/openocd.cfg @@ -1,5 +1,5 @@ -set ESP_RTOS none -set ESP32_ONLYCPU 1 +set ESP_RTOS Zephyr +set ESP_ONLYCPU 1 # Source the JTAG interface configuration file source [find interface/esp_usb_jtag.cfg] diff --git a/boards/weact/weact_esp32s3_b/support/openocd.cfg b/boards/weact/weact_esp32s3_b/support/openocd.cfg index 2f740b4a36ab..b45e13c53d01 100644 --- a/boards/weact/weact_esp32s3_b/support/openocd.cfg +++ b/boards/weact/weact_esp32s3_b/support/openocd.cfg @@ -1,5 +1,5 @@ -set ESP_RTOS none -set ESP32_ONLYCPU 1 +set ESP_RTOS Zephyr +set ESP_ONLYCPU 1 # Source the JTAG interface configuration file source [find interface/esp_usb_jtag.cfg] diff --git a/boards/wemos/esp32s2_lolin_mini/support/openocd.cfg b/boards/wemos/esp32s2_lolin_mini/support/openocd.cfg index f75d53b0b34c..6b71dc41b12f 100644 --- a/boards/wemos/esp32s2_lolin_mini/support/openocd.cfg +++ b/boards/wemos/esp32s2_lolin_mini/support/openocd.cfg @@ -1,4 +1,4 @@ -set ESP_RTOS none +set ESP_RTOS Zephyr source [find interface/ftdi/esp32s2_kaluga_v1.cfg] source [find target/esp32s2.cfg] diff --git a/boards/wemos/lolin32_lite/support/openocd.cfg b/boards/wemos/lolin32_lite/support/openocd.cfg index 338e6e4e6eae..41411e37140e 100644 --- a/boards/wemos/lolin32_lite/support/openocd.cfg +++ b/boards/wemos/lolin32_lite/support/openocd.cfg @@ -1,5 +1,5 @@ -set ESP_RTOS none -set ESP32_ONLYCPU 1 +set ESP_RTOS Zephyr +set ESP_ONLYCPU 1 source [find interface/ftdi/esp32_devkitj_v1.cfg] source [find target/esp32.cfg] From f9e81d6ded980450539f875810bddec49067a9f6 Mon Sep 17 00:00:00 2001 From: Sylvio Alves Date: Fri, 19 Dec 2025 14:03:56 -0300 Subject: [PATCH 1553/3659] boards: esp32: set openocd target handle for RTOS support ESP32 OpenOCD uses $_TARGETNAME_0 instead of $_TARGETNAME. Set the correct target handle to enable RTOS awareness. Signed-off-by: Sylvio Alves --- boards/common/esp32.board.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boards/common/esp32.board.cmake b/boards/common/esp32.board.cmake index d0f83434c144..7c9587bea8e9 100644 --- a/boards/common/esp32.board.cmake +++ b/boards/common/esp32.board.cmake @@ -3,7 +3,7 @@ board_set_flasher_ifnset(esp32) board_set_debugger_ifnset(openocd) -board_runner_args(openocd --no-halt --no-targets --no-load) +board_runner_args(openocd --no-halt --no-targets --no-load --target-handle _TARGETNAME_0) board_runner_args(openocd --gdb-init "set remote hardware-watchpoint-limit 2") board_runner_args(openocd --gdb-init "maintenance flush register-cache") From b6e6a4c0c4039e6d7e82bbace1dc49026dc64358 Mon Sep 17 00:00:00 2001 From: Sylvio Alves Date: Fri, 19 Dec 2025 15:00:22 -0300 Subject: [PATCH 1554/3659] doc: esp32: document openocd thread awareness Document the OpenOCD version required for Zephyr thread awareness and how to use CONFIG_DEBUG_THREAD_INFO. Signed-off-by: Sylvio Alves --- boards/espressif/common/openocd-debugging.rst | 42 +++++++++++++------ 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/boards/espressif/common/openocd-debugging.rst b/boards/espressif/common/openocd-debugging.rst index 71d75389eb79..7ec60739908d 100644 --- a/boards/espressif/common/openocd-debugging.rst +++ b/boards/espressif/common/openocd-debugging.rst @@ -2,34 +2,50 @@ .. espressif-openocd-debugging -OpenOCD -======= +OpenOCD Debugging +================= -As with much custom hardware, the ESP32 modules require patches to -OpenOCD that are not upstreamed yet. Espressif maintains their own fork of -the project. The custom OpenOCD can be obtained at `OpenOCD for ESP32`_. +Espressif chips require a custom OpenOCD build with ESP32-specific patches. +Download the latest release from `OpenOCD for ESP32`_. -The Zephyr SDK uses a bundled version of OpenOCD by default. You can overwrite that behavior by adding the -``-DOPENOCD= -DOPENOCD_DEFAULT_PATH=`` -parameter when building. +For detailed JTAG setup instructions, see `JTAG debugging for ESP32`_. -Further documentation can be obtained from the SoC vendor in `JTAG debugging for ESP32`_. +Zephyr Thread Awareness +----------------------- -Here is an example for building the :zephyr:code-sample:`hello_world` application. +OpenOCD supports Zephyr RTOS thread awareness, allowing GDB to: + +- List all threads with ``info threads`` +- Display thread names, priorities, and states +- Switch between thread contexts +- Show backtraces for any thread + +**Requirements:** + +- `OpenOCD ESP32 v0.12.0-esp32-20251215`_ or later +- Build with ``CONFIG_DEBUG_THREAD_INFO=y`` + +**Example:** .. zephyr-app-commands:: :zephyr-app: samples/hello_world :board: - :goals: build flash - :gen-args: -DOPENOCD= -DOPENOCD_DEFAULT_PATH= + :goals: debug + :gen-args: -DCONFIG_DEBUG_THREAD_INFO=y -DOPENOCD= -DOPENOCD_DEFAULT_PATH= + +Using a Custom OpenOCD +---------------------- -You can debug an application in the usual way. Here is an example for the :zephyr:code-sample:`hello_world` application. +The Zephyr SDK includes a bundled OpenOCD, but it may not have ESP32 support. +To use the Espressif OpenOCD, specify the path when building: .. zephyr-app-commands:: :zephyr-app: samples/hello_world :board: :goals: debug + :gen-args: -DOPENOCD=/path/to/openocd -DOPENOCD_DEFAULT_PATH=/path/to/openocd/scripts .. _`OpenOCD for ESP32`: https://github.com/espressif/openocd-esp32/releases +.. _`OpenOCD ESP32 v0.12.0-esp32-20251215`: https://github.com/espressif/openocd-esp32/releases/tag/v0.12.0-esp32-20251215 .. _`JTAG debugging for ESP32`: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/jtag-debugging/index.html From 45dd7fa9ad9069377237de829d6eebf306f2527c Mon Sep 17 00:00:00 2001 From: Marek Matej Date: Fri, 14 Nov 2025 21:45:05 +0000 Subject: [PATCH 1555/3659] xtensa: debug: enable xtensa thread awareness Enable stack offset switching for Xtensa targets if arch_switch is used. Signed-off-by: Marek Matej --- subsys/debug/thread_info.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/subsys/debug/thread_info.c b/subsys/debug/thread_info.c index 78be9940f7bf..704f43d33394 100644 --- a/subsys/debug/thread_info.c +++ b/subsys/debug/thread_info.c @@ -86,12 +86,16 @@ const size_t _kernel_thread_info_offsets[] = { [THREAD_INFO_OFFSET_T_STACK_PTR] = offsetof(struct k_thread, callee_saved.thread_status), #elif defined(CONFIG_XTENSA) - /* Xtensa does not store stack pointers inside thread objects. - * The registers are saved in thread stack where there is - * no fixed location for this to work. So mark this as - * unimplemented to avoid the #warning below. - */ +/* Xtensa does not store stack pointers inside thread objects. + * The registers are saved in thread stack where there is + * no fixed location for this to work. It needs arch_switch in + * order to work on Xtensa. + */ +#ifdef CONFIG_USE_SWITCH + [THREAD_INFO_OFFSET_T_STACK_PTR] = offsetof(struct k_thread, switch_handle), +#else [THREAD_INFO_OFFSET_T_STACK_PTR] = THREAD_INFO_UNIMPLEMENTED, +#endif #elif defined(CONFIG_RX) /* RX doesn't store *anything* inside thread objects yet */ [THREAD_INFO_OFFSET_T_STACK_PTR] = THREAD_INFO_UNIMPLEMENTED, From eb2da4f4c674c63088f8c0c35fc76a9358f76578 Mon Sep 17 00:00:00 2001 From: Om Srivastava Date: Sat, 20 Dec 2025 00:15:37 +0530 Subject: [PATCH 1556/3659] bluetooth: shell: fix AD length validation Fix validation of AD length handling in the Bluetooth shell. Reject zero-length AD fields before subtracting the AD type size. The previous implementation compared an unsigned length against zero after subtraction, making the error path unreachable. Signed-off-by: Om Srivastava --- subsys/bluetooth/host/shell/bt.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/subsys/bluetooth/host/shell/bt.c b/subsys/bluetooth/host/shell/bt.c index 21302647bdf7..fc3e4100599d 100644 --- a/subsys/bluetooth/host/shell/bt.c +++ b/subsys/bluetooth/host/shell/bt.c @@ -5176,11 +5176,14 @@ int ead_update_ad(void) while (idx < bt_shell_ead_data_size && ad_structs_idx < BT_SHELL_EAD_MAX_AD) { ad = &ad_structs[ad_structs_idx]; - /* the data_len from bt_data struct doesn't include the size of the type */ - ad->data_len = bt_shell_ead_data[idx] - 1; - - if (ad->data_len < 0) { - /* if the len is less than 0 that mean there is not even a type field */ + /* bt_shell_ead_data[idx] points to the start of an encrypted advertising + * tuple, so bt_shell_ead_data[idx] is the length field, bt_shell_ead_data[idx + 1] + * is the type field and bt_shell_ead_data[idx + 2] is the start of the value + */ + if (bt_shell_ead_data[idx] > 0) { + ad->data_len = bt_shell_ead_data[idx] - 1; + } else { + /* Zero length means the AD field does not even contain a type */ bt_shell_error("Failed to update AD due to malformed AD."); return -ENOEXEC; } From 0d1863c4096165c4660561840f64197d83078200 Mon Sep 17 00:00:00 2001 From: Igor Knippenberg Date: Fri, 19 Dec 2025 22:32:30 +0100 Subject: [PATCH 1557/3659] drivers: can: stm32: fdcan: enable hardware RX timestamping Enables hardware RX timestamping for the STM32 FDCAN driver by leveraging the M_CAN timestamping interface. Introduces a new `timestamp-counter` property in the device tree binding. If `CONFIG_CAN_RX_TIMESTAMP` is enabled and this property is defined, the driver configures the M_CAN Timestamp Select to use the external timestamp counter value. This allows linking a Zephyr Counter device to the FDCAN instance to provide precise packet timing. Signed-off-by: Igor Knippenberg --- drivers/can/can_stm32_fdcan.c | 32 +++++++++++++++++++++++++++- dts/bindings/can/st,stm32-fdcan.yaml | 12 +++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/drivers/can/can_stm32_fdcan.c b/drivers/can/can_stm32_fdcan.c index 8a5021cf2953..1ffe75ac4a83 100644 --- a/drivers/can/can_stm32_fdcan.c +++ b/drivers/can/can_stm32_fdcan.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -173,6 +174,9 @@ struct can_stm32fd_config { void (*config_irq)(void); const struct pinctrl_dev_config *pcfg; uint8_t clock_divider; +#ifdef CONFIG_CAN_RX_TIMESTAMP + const struct device *external_timestamp_counter_dev; +#endif }; static inline uint16_t can_stm32fd_remap_reg(uint16_t reg) @@ -520,6 +524,29 @@ static int can_stm32fd_init(const struct device *dev) return ret; } + +#ifdef CONFIG_CAN_RX_TIMESTAMP + if (stm32fd_cfg->external_timestamp_counter_dev != NULL) { + if (!device_is_ready(stm32fd_cfg->external_timestamp_counter_dev)) { + LOG_ERR("Timestamp counter device not ready"); + return -ENODEV; + } + + ret = counter_start(stm32fd_cfg->external_timestamp_counter_dev); + if (ret < 0) { + LOG_ERR("Failed to start timestamp counter (%d)", ret); + return ret; + } + + /* Use External Timestamp counter (TSS=2) */ + ret = can_mcan_write_reg(dev, CAN_MCAN_TSCC, FIELD_PREP(CAN_MCAN_TSCC_TSS, 0x2)); + if (ret != 0) { + LOG_ERR("Failed to write TSCC register"); + return ret; + } + } +#endif /* CONFIG_CAN_RX_TIMESTAMP */ + stm32fd_cfg->config_irq(); return ret; @@ -609,7 +636,10 @@ static const struct can_mcan_ops can_stm32fd_ops = { .pclk_len = DT_INST_NUM_CLOCKS(inst), \ .config_irq = config_can_##inst##_irq, \ .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(inst), \ - .clock_divider = DT_INST_PROP_OR(inst, clk_divider, 0) \ + .clock_divider = DT_INST_PROP_OR(inst, clk_divider, 0), \ + IF_ENABLED(CONFIG_CAN_RX_TIMESTAMP, \ + (.external_timestamp_counter_dev = DEVICE_DT_GET_OR_NULL( \ + DT_INST_PHANDLE(inst, external_timestamp_counter)),)) \ }; \ \ static const struct can_mcan_config can_mcan_cfg_##inst = \ diff --git a/dts/bindings/can/st,stm32-fdcan.yaml b/dts/bindings/can/st,stm32-fdcan.yaml index 7df1123ace95..8cd2cb51e159 100644 --- a/dts/bindings/can/st,stm32-fdcan.yaml +++ b/dts/bindings/can/st,stm32-fdcan.yaml @@ -43,3 +43,15 @@ properties: Note that the divisor is common to all 'st,stm32-fdcan' instances. Divide by 1 is the peripherals reset value and remains set unless this property is configured. + + external-timestamp-counter: + type: phandle + description: | + Phandle to the counter device to be used as the external RX timestamp source. + + When this property is defined, the driver configures the FDCAN Timestamp + Counter Configuration (TSCC) to use the External Timestamp (TSS=0x2). + + Hardware Constraint: The selected timer must be physically routed to the + fdcan_ts input in the SoC interconnect. (e.g. TIM3 on STM32G4). The exact timer + connected to the fdcan_ts input can be found in the reference manual of the specific SoC. From 52c712d4d13efbeadd53f6c6bd61dbe370fd088f Mon Sep 17 00:00:00 2001 From: Yongxu Wang Date: Mon, 22 Dec 2025 14:17:37 +0800 Subject: [PATCH 1558/3659] firmware: scmi: add mutex protection to polling mode Protect scmi_send_message_polling() with channel mutex to prevent concurrent access with interrupt-driven transfers. Without this fix, PM subsystem could send polling-mode messages while an interrupt-mode transfer was in progress, corrupting the shared channel state. Fixes hang on i.MX943 during I2C initialization when PM attempted to send power state notifications concurrently. Signed-off-by: Yongxu Wang --- drivers/firmware/scmi/core.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/firmware/scmi/core.c b/drivers/firmware/scmi/core.c index 547ee92f43e5..a18069d32444 100644 --- a/drivers/firmware/scmi/core.c +++ b/drivers/firmware/scmi/core.c @@ -115,6 +115,13 @@ static int scmi_send_message_polling(struct scmi_protocol *proto, int ret; int status; + /* wait for channel to be free */ + ret = k_mutex_lock(&proto->tx->lock, K_NO_WAIT); + if (ret < 0) { + LOG_ERR("failed to acquire chan lock"); + return -EBUSY; + } + /* * SCMI communication interrupt is enabled by default during setup_chan * to support interrupt-driven communication. When using polling mode @@ -152,6 +159,8 @@ static int scmi_send_message_polling(struct scmi_protocol *proto, scmi_interrupt_enable(proto->tx, true); } + k_mutex_unlock(&proto->tx->lock); + return ret; } From c1722f5eda7883a9061363d3ea3d493af603e783 Mon Sep 17 00:00:00 2001 From: Maximilian Werner Date: Tue, 23 Dec 2025 12:32:55 +0100 Subject: [PATCH 1559/3659] drivers: i2c: mcux: add support for target mode Add i2c target support to the i2c_mcux driver. Add the frdm_mcxc242 board to i2c_target_api tests. Signed-off-by: Maximilian Werner --- drivers/i2c/i2c_mcux.c | 176 ++++++++++++++++++ .../boards/frdm_mcxc242.overlay | 57 ++++++ .../drivers/i2c/i2c_target_api/testcase.yaml | 1 + 3 files changed, 234 insertions(+) create mode 100644 tests/drivers/i2c/i2c_target_api/boards/frdm_mcxc242.overlay diff --git a/drivers/i2c/i2c_mcux.c b/drivers/i2c/i2c_mcux.c index 1ef10cc40206..348dabcf3b3a 100644 --- a/drivers/i2c/i2c_mcux.c +++ b/drivers/i2c/i2c_mcux.c @@ -46,6 +46,14 @@ struct i2c_mcux_data { i2c_callback_t cb; void *userdata; #endif /* CONFIG_I2C_CALLBACK */ +#ifdef CONFIG_I2C_TARGET + i2c_slave_handle_t target_handle; + struct i2c_target_config *target_cfg; + uint8_t target_buffer; + bool target_attached; + bool target_receiving; + bool target_first_rxtx; +#endif }; static int i2c_mcux_configure(const struct device *dev, @@ -299,12 +307,176 @@ static int i2c_mcux_transfer_cb(const struct device *dev, struct i2c_msg *msgs, #endif /* CONFIG_I2C_CALLBACK */ +#ifdef CONFIG_I2C_TARGET +static void i2c_mcux_target_transfer_cb(I2C_Type *base, i2c_slave_transfer_t *transfer, + void *userData) +{ + const struct device *dev = (const struct device *)userData; + struct i2c_mcux_data *data = dev->data; + const struct i2c_target_callbacks *target_cb = data->target_cfg->callbacks; + int ret = 0; + + ARG_UNUSED(base); + + switch (transfer->event) { + case kI2C_SlaveStartEvent: + /* start or repeated start of a transfer */ + transfer->dataSize = 0; + data->target_first_rxtx = true; + + if (data->target_receiving) { + /* In case of a repeated start after a kI2C_SlaveReceiveEvent, + * the kI2C_SlaveCompletionEvent is not fired. We need to fetch the last + * byte here. + */ + data->target_receiving = false; + if (target_cb->write_received) { + target_cb->write_received(data->target_cfg, data->target_buffer); + } + } + break; + + case kI2C_SlaveReceiveEvent: + /* request to provide a buffer in which to place received data */ + data->target_receiving = true; + + transfer->data = &data->target_buffer; + transfer->dataSize = 1; + + if (data->target_first_rxtx) { + data->target_first_rxtx = false; + if (target_cb->write_requested) { + ret = target_cb->write_requested(data->target_cfg); + } + } else { + if (target_cb->write_received) { + ret = target_cb->write_received(data->target_cfg, + data->target_buffer); + } + } + break; + + case kI2C_SlaveTransmitEvent: + /* request to provide data to transmit */ + transfer->data = &data->target_buffer; + transfer->dataSize = 1; + + if (data->target_first_rxtx) { + data->target_first_rxtx = false; + if (target_cb->read_requested) { + ret = target_cb->read_requested(data->target_cfg, + &data->target_buffer); + } + } else { + if (target_cb->read_processed) { + ret = target_cb->read_processed(data->target_cfg, + &data->target_buffer); + } + } + break; + + case kI2C_SlaveCompletionEvent: + /* transfer finished */ + data->target_first_rxtx = false; + + if (data->target_receiving) { + /* fetch last received byte */ + data->target_receiving = false; + if (target_cb->write_received) { + target_cb->write_received(data->target_cfg, data->target_buffer); + } + } + + if (target_cb->stop) { + target_cb->stop(data->target_cfg); + } + break; + + default: + LOG_INF("Unhandled event: %d", transfer->event); + break; + } + + if (ret < 0) { + /* abort communication by not providing a buffer in case of an error */ + transfer->dataSize = 0; + } +} + +static int i2c_mcux_target_register(const struct device *dev, + struct i2c_target_config *target_config) +{ + I2C_Type *base = DEV_BASE(dev); + const struct i2c_mcux_config *config = dev->config; + struct i2c_mcux_data *data = dev->data; + i2c_slave_config_t slave_config; + uint32_t clock_freq; + + if (!target_config || !target_config->callbacks) { + return -EINVAL; + } + + if (data->target_attached) { + return -EBUSY; + } + + I2C_MasterDeinit(base); + + data->target_attached = true; + data->target_cfg = target_config; + data->target_first_rxtx = true; + data->target_receiving = false; + + I2C_SlaveGetDefaultConfig(&slave_config); + slave_config.slaveAddress = target_config->address; + + clock_freq = CLOCK_GetFreq(config->clock_source); + + I2C_SlaveInit(base, &slave_config, clock_freq); + I2C_SlaveClearStatusFlags(base, kClearFlags); + I2C_SlaveTransferCreateHandle(base, &data->target_handle, i2c_mcux_target_transfer_cb, + (void *)dev); + I2C_SlaveTransferNonBlocking(base, &data->target_handle, + kI2C_SlaveStartEvent | kI2C_SlaveCompletionEvent); + + return 0; +} + +static int i2c_mcux_target_unregister(const struct device *dev, + struct i2c_target_config *target_config) +{ + I2C_Type *base = DEV_BASE(dev); + struct i2c_mcux_data *data = dev->data; + + ARG_UNUSED(target_config); + + if (!data->target_attached) { + return -EINVAL; + } + + I2C_SlaveDeinit(base); + + data->target_cfg = NULL; + data->target_attached = false; + + return 0; +} +#endif /* CONFIG_I2C_TARGET */ + static void i2c_mcux_isr(const struct device *dev) { I2C_Type *base = DEV_BASE(dev); struct i2c_mcux_data *data = dev->data; +#ifdef CONFIG_I2C_TARGET + if (data->target_attached) { + I2C_SlaveTransferHandleIRQ(base, &data->target_handle); + } else { + I2C_MasterTransferHandleIRQ(base, &data->handle); + } +#else I2C_MasterTransferHandleIRQ(base, &data->handle); +#endif /* CONFIG_I2C_TARGET */ } static int i2c_mcux_init(const struct device *dev) @@ -351,6 +523,10 @@ static DEVICE_API(i2c, i2c_mcux_driver_api) = { #ifdef CONFIG_I2C_RTIO .iodev_submit = i2c_iodev_submit_fallback, #endif +#ifdef CONFIG_I2C_TARGET + .target_register = i2c_mcux_target_register, + .target_unregister = i2c_mcux_target_unregister, +#endif }; #define I2C_DEVICE_INIT_MCUX(n) \ diff --git a/tests/drivers/i2c/i2c_target_api/boards/frdm_mcxc242.overlay b/tests/drivers/i2c/i2c_target_api/boards/frdm_mcxc242.overlay new file mode 100644 index 000000000000..b2ad3e879e17 --- /dev/null +++ b/tests/drivers/i2c/i2c_target_api/boards/frdm_mcxc242.overlay @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2025 Maximilian Werner + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&pinctrl { + pinmux_i2c0: pinmux_i2c0 { + group0 { + pinmux = , + ; + drive-strength = "low"; + drive-open-drain; + slew-rate = "fast"; + }; + }; + + pinmux_i2c1: pinmux_i2c1 { + group0 { + pinmux = , + ; + drive-strength = "low"; + drive-open-drain; + slew-rate = "fast"; + }; + }; +}; + +/* To test this sample, connect + * I2C0 SCL(J4-12, PTB0) --> I2C1 SCL(J2-20, PTD7) + * I2C0 SDA(J4-10, PTB1) --> I2C1 SDA(J2-18, PTD6) + */ +&i2c0 { + pinctrl-0 = <&pinmux_i2c0>; + pinctrl-names = "default"; + status = "okay"; + + eeprom0: eeprom@54 { + compatible = "zephyr,i2c-target-eeprom"; + reg = <0x54>; + size = <256>; + }; +}; + +&i2c1 { + pinctrl-0 = <&pinmux_i2c1>; + pinctrl-names = "default"; + status = "okay"; + + eeprom1: eeprom@56 { + compatible = "zephyr,i2c-target-eeprom"; + reg = <0x56>; + size = <256>; + }; +}; diff --git a/tests/drivers/i2c/i2c_target_api/testcase.yaml b/tests/drivers/i2c/i2c_target_api/testcase.yaml index 58a78df2ff27..bbf6cb2ae104 100644 --- a/tests/drivers/i2c/i2c_target_api/testcase.yaml +++ b/tests/drivers/i2c/i2c_target_api/testcase.yaml @@ -58,6 +58,7 @@ tests: - frdm_mcxa346 - frdm_mcxa266 - frdm_mcxa366 + - frdm_mcxc242 - max32655evkit/max32655/m4 - max32662evkit - max32666evkit/max32666/cpu0 From 1602f3cff1d06f1c2c81e45d4f4f6ef56882b305 Mon Sep 17 00:00:00 2001 From: Maximilian Werner Date: Tue, 6 Jan 2026 12:03:52 +0100 Subject: [PATCH 1560/3659] drivers: i2c: mcux: refactor target event handler The target event handler i2c_mcux_target_transfer_cb() had a too high cognitive complexity. Create a function for each event type to reduce the complexity score. Signed-off-by: Maximilian Werner --- drivers/i2c/i2c_mcux.c | 158 ++++++++++++++++++++++++++--------------- 1 file changed, 99 insertions(+), 59 deletions(-) diff --git a/drivers/i2c/i2c_mcux.c b/drivers/i2c/i2c_mcux.c index 348dabcf3b3a..97eee6c0bc08 100644 --- a/drivers/i2c/i2c_mcux.c +++ b/drivers/i2c/i2c_mcux.c @@ -308,92 +308,132 @@ static int i2c_mcux_transfer_cb(const struct device *dev, struct i2c_msg *msgs, #endif /* CONFIG_I2C_CALLBACK */ #ifdef CONFIG_I2C_TARGET +static int i2c_mcux_target_start_handler(struct i2c_mcux_data *data, i2c_slave_transfer_t *transfer) +{ + const struct i2c_target_callbacks *target_cb = data->target_cfg->callbacks; + int ret = 0; + + transfer->dataSize = 0; + data->target_first_rxtx = true; + + if (data->target_receiving) { + /* In case of a repeated start after a kI2C_SlaveReceiveEvent, + * the kI2C_SlaveCompletionEvent is not fired. We need to fetch the last + * byte here. + */ + data->target_receiving = false; + if (target_cb->write_received) { + ret = target_cb->write_received(data->target_cfg, data->target_buffer); + } + } + + return ret; +} + +static int i2c_mcux_target_receive_handler(struct i2c_mcux_data *data, + i2c_slave_transfer_t *transfer) +{ + const struct i2c_target_callbacks *target_cb = data->target_cfg->callbacks; + int ret = 0; + + data->target_receiving = true; + + transfer->data = &data->target_buffer; + transfer->dataSize = 1; + + if (data->target_first_rxtx) { + data->target_first_rxtx = false; + if (target_cb->write_requested) { + ret = target_cb->write_requested(data->target_cfg); + } + } else { + if (target_cb->write_received) { + ret = target_cb->write_received(data->target_cfg, data->target_buffer); + } + } + + return ret; +} + +static int i2c_mcux_target_transmit_handler(struct i2c_mcux_data *data, + i2c_slave_transfer_t *transfer) +{ + const struct i2c_target_callbacks *target_cb = data->target_cfg->callbacks; + int ret = 0; + + transfer->data = &data->target_buffer; + transfer->dataSize = 1; + + if (data->target_first_rxtx) { + data->target_first_rxtx = false; + if (target_cb->read_requested) { + ret = target_cb->read_requested(data->target_cfg, &data->target_buffer); + } + } else { + if (target_cb->read_processed) { + ret = target_cb->read_processed(data->target_cfg, &data->target_buffer); + } + } + + return ret; +} + +static int i2c_mcux_target_completion_handler(struct i2c_mcux_data *data, + i2c_slave_transfer_t *transfer) +{ + const struct i2c_target_callbacks *target_cb = data->target_cfg->callbacks; + int ret = 0; + + data->target_first_rxtx = false; + + if (data->target_receiving) { + /* fetch last received byte */ + data->target_receiving = false; + if (target_cb->write_received) { + ret = target_cb->write_received(data->target_cfg, data->target_buffer); + } + } + + if (target_cb->stop) { + ret = target_cb->stop(data->target_cfg); + } + + return ret; +} + static void i2c_mcux_target_transfer_cb(I2C_Type *base, i2c_slave_transfer_t *transfer, void *userData) { const struct device *dev = (const struct device *)userData; struct i2c_mcux_data *data = dev->data; - const struct i2c_target_callbacks *target_cb = data->target_cfg->callbacks; - int ret = 0; + int ret; ARG_UNUSED(base); switch (transfer->event) { case kI2C_SlaveStartEvent: /* start or repeated start of a transfer */ - transfer->dataSize = 0; - data->target_first_rxtx = true; - - if (data->target_receiving) { - /* In case of a repeated start after a kI2C_SlaveReceiveEvent, - * the kI2C_SlaveCompletionEvent is not fired. We need to fetch the last - * byte here. - */ - data->target_receiving = false; - if (target_cb->write_received) { - target_cb->write_received(data->target_cfg, data->target_buffer); - } - } + ret = i2c_mcux_target_start_handler(data, transfer); break; case kI2C_SlaveReceiveEvent: /* request to provide a buffer in which to place received data */ - data->target_receiving = true; - - transfer->data = &data->target_buffer; - transfer->dataSize = 1; - - if (data->target_first_rxtx) { - data->target_first_rxtx = false; - if (target_cb->write_requested) { - ret = target_cb->write_requested(data->target_cfg); - } - } else { - if (target_cb->write_received) { - ret = target_cb->write_received(data->target_cfg, - data->target_buffer); - } - } + ret = i2c_mcux_target_receive_handler(data, transfer); break; case kI2C_SlaveTransmitEvent: /* request to provide data to transmit */ - transfer->data = &data->target_buffer; - transfer->dataSize = 1; - - if (data->target_first_rxtx) { - data->target_first_rxtx = false; - if (target_cb->read_requested) { - ret = target_cb->read_requested(data->target_cfg, - &data->target_buffer); - } - } else { - if (target_cb->read_processed) { - ret = target_cb->read_processed(data->target_cfg, - &data->target_buffer); - } - } + ret = i2c_mcux_target_transmit_handler(data, transfer); break; case kI2C_SlaveCompletionEvent: /* transfer finished */ - data->target_first_rxtx = false; - - if (data->target_receiving) { - /* fetch last received byte */ - data->target_receiving = false; - if (target_cb->write_received) { - target_cb->write_received(data->target_cfg, data->target_buffer); - } - } - - if (target_cb->stop) { - target_cb->stop(data->target_cfg); - } + ret = i2c_mcux_target_completion_handler(data, transfer); break; default: LOG_INF("Unhandled event: %d", transfer->event); + ret = -EINVAL; break; } From 6511eb4edf9ff550b83703a9eba8755a75b86407 Mon Sep 17 00:00:00 2001 From: Sylvio Alves Date: Tue, 23 Dec 2025 17:49:18 -0300 Subject: [PATCH 1561/3659] bluetooth: hci: add Espressif VS platform/variant definitions Add Espressif platform and variant IDs to hci_vs.h for ESP32 family SoCs (ESP32, ESP32-S3, ESP32-C2, ESP32-C3, ESP32-C6, ESP32-H2). Add Espressif Systems to vs_hw_platform() and vs_hw_variant() functions in hci_core.c for proper vendor identification. Use CONFIG_SOC_FAMILY guards in vs_hw_variant() to reduce flash usage by only compiling variant strings for the active SoC family. Signed-off-by: Sylvio Alves --- doc/connectivity/bluetooth/api/hci.txt | 1 + include/zephyr/bluetooth/hci_vs.h | 8 ++++++++ subsys/bluetooth/host/hci_core.c | 20 +++++++++++++++----- 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/doc/connectivity/bluetooth/api/hci.txt b/doc/connectivity/bluetooth/api/hci.txt index a23b24e6ad0e..dead83220a4e 100644 --- a/doc/connectivity/bluetooth/api/hci.txt +++ b/doc/connectivity/bluetooth/api/hci.txt @@ -111,6 +111,7 @@ manufacturer. | 0x0001 | Intel Corporation | | 0x0002 | Nordic Semiconductor | | 0x0003 | NXP Semiconductors | + | 0x0004 | Espressif Systems | | All other values | Reserved for future use | +--------------------+--------------------------------------+ diff --git a/include/zephyr/bluetooth/hci_vs.h b/include/zephyr/bluetooth/hci_vs.h index 904bcbdb2d5d..51e7b19cdddb 100644 --- a/include/zephyr/bluetooth/hci_vs.h +++ b/include/zephyr/bluetooth/hci_vs.h @@ -46,6 +46,7 @@ extern "C" { #define BT_HCI_VS_HW_PLAT_INTEL 0x0001 #define BT_HCI_VS_HW_PLAT_NORDIC 0x0002 #define BT_HCI_VS_HW_PLAT_NXP 0x0003 +#define BT_HCI_VS_HW_PLAT_ESPRESSIF 0x0004 #define BT_HCI_VS_HW_VAR_NORDIC_NRF51X 0x0001 #define BT_HCI_VS_HW_VAR_NORDIC_NRF52X 0x0002 @@ -53,6 +54,13 @@ extern "C" { #define BT_HCI_VS_HW_VAR_NORDIC_NRF54HX 0x0004 #define BT_HCI_VS_HW_VAR_NORDIC_NRF54LX 0x0005 +#define BT_HCI_VS_HW_VAR_ESP32 0x0001 +#define BT_HCI_VS_HW_VAR_ESP32S3 0x0002 +#define BT_HCI_VS_HW_VAR_ESP32C2 0x0003 +#define BT_HCI_VS_HW_VAR_ESP32C3 0x0004 +#define BT_HCI_VS_HW_VAR_ESP32C6 0x0005 +#define BT_HCI_VS_HW_VAR_ESP32H2 0x0006 + #define BT_HCI_VS_FW_VAR_STANDARD_CTLR 0x0001 #define BT_HCI_VS_FW_VAR_VS_CTLR 0x0002 #define BT_HCI_VS_FW_VAR_FW_LOADER 0x0003 diff --git a/subsys/bluetooth/host/hci_core.c b/subsys/bluetooth/host/hci_core.c index 8704ab57d575..82c429aef9d6 100644 --- a/subsys/bluetooth/host/hci_core.c +++ b/subsys/bluetooth/host/hci_core.c @@ -4119,7 +4119,8 @@ static const char *vs_hw_platform(uint16_t platform) { static const char * const plat_str[] = { "reserved", "Intel Corporation", "Nordic Semiconductor", - "NXP Semiconductors" }; + "NXP Semiconductors", "Espressif Systems" + }; if (platform < ARRAY_SIZE(plat_str)) { return plat_str[platform]; @@ -4130,17 +4131,26 @@ static const char *vs_hw_platform(uint16_t platform) static const char *vs_hw_variant(uint16_t platform, uint16_t variant) { +#if defined(CONFIG_SOC_FAMILY_NORDIC_NRF) static const char * const nordic_str[] = { "reserved", "nRF51x", "nRF52x", "nRF53x", "nRF54Hx", "nRF54Lx" }; - if (platform != BT_HCI_VS_HW_PLAT_NORDIC) { - return "unknown"; + if (platform == BT_HCI_VS_HW_PLAT_NORDIC && variant < ARRAY_SIZE(nordic_str)) { + return nordic_str[variant]; } +#endif +#if defined(CONFIG_SOC_FAMILY_ESPRESSIF_ESP32) + static const char * const esp32_str[] = { + "reserved", "ESP32", "ESP32-S3", "ESP32-C2", "ESP32-C3", "ESP32-C6", "ESP32-H2" + }; - if (variant < ARRAY_SIZE(nordic_str)) { - return nordic_str[variant]; + if (platform == BT_HCI_VS_HW_PLAT_ESPRESSIF && variant < ARRAY_SIZE(esp32_str)) { + return esp32_str[variant]; } +#endif + ARG_UNUSED(platform); + ARG_UNUSED(variant); return "unknown"; } From 06890c3f92523a575c1e13784e64308ed6e47004 Mon Sep 17 00:00:00 2001 From: Sylvio Alves Date: Tue, 23 Dec 2025 17:51:53 -0300 Subject: [PATCH 1562/3659] drivers: bluetooth: esp32: add vendor-specific HCI commands Implement VS HCI commands for ESP32 BLE controllers: - Read/Write TX power level with per-handle support - Read version info (platform, variant, firmware version) - Read supported commands and features - Read static addresses from eFuse (C2/C6/H2) - Read build info (controller version string) For original ESP32, use the legacy esp_ble_tx_power_set/get API. For newer variants (ESP32-S3, ESP32-C2, ESP32-C3, ESP32-C6, ESP32-H2), use the enhanced API that supports per-connection power control. Signed-off-by: Sylvio Alves --- drivers/bluetooth/hci/Kconfig | 1 + drivers/bluetooth/hci/hci_esp32.c | 521 +++++++++++++++++++++++++++++- 2 files changed, 509 insertions(+), 13 deletions(-) diff --git a/drivers/bluetooth/hci/Kconfig b/drivers/bluetooth/hci/Kconfig index 88ce87d8e8ad..8e650f93eb69 100644 --- a/drivers/bluetooth/hci/Kconfig +++ b/drivers/bluetooth/hci/Kconfig @@ -173,6 +173,7 @@ config BT_ESP32 select BT_CTLR_PRIVACY_SUPPORT select BT_CTLR_EXT_SCAN_FP_SUPPORT select BT_CTLR_DATA_LEN_UPDATE_SUPPORT + select BT_CTLR_CONN_RSSI_SUPPORT select BT_CTLR_ADV_EXT_SUPPORT if !SOC_SERIES_ESP32 select BT_CTLR_PHY_UPDATE_SUPPORT if !SOC_SERIES_ESP32 select BT_CTLR_EXT_REJ_IND_SUPPORT if !SOC_SERIES_ESP32 diff --git a/drivers/bluetooth/hci/hci_esp32.c b/drivers/bluetooth/hci/hci_esp32.c index efb4ca0c9b66..201e16473e0d 100644 --- a/drivers/bluetooth/hci/hci_esp32.c +++ b/drivers/bluetooth/hci/hci_esp32.c @@ -5,18 +5,159 @@ */ #include +#include #include #include +#include #include #include +#include #define LOG_LEVEL CONFIG_BT_HCI_DRIVER_LOG_LEVEL #include LOG_MODULE_REGISTER(bt_hci_driver_esp32); +#if defined(CONFIG_SOC_SERIES_ESP32) || defined(CONFIG_SOC_SERIES_ESP32S3) || \ + defined(CONFIG_SOC_SERIES_ESP32C3) +extern const char *btdm_controller_get_compile_version(void); +#define esp32_get_controller_version() btdm_controller_get_compile_version() +#else +extern char *ble_controller_get_compile_version(void); +#define esp32_get_controller_version() ble_controller_get_compile_version() +#endif + +#if defined(CONFIG_SOC_SERIES_ESP32) +#define ESP32_HAS_ENHANCED_TX_POWER_API 0 +#else +#define ESP32_HAS_ENHANCED_TX_POWER_API 1 +#endif + + +static esp_power_level_t dbm_to_esp_power_level(int8_t dbm) +{ +#if ESP32_HAS_ENHANCED_TX_POWER_API + if (dbm >= 20) { + return ESP_PWR_LVL_P20; + } else if (dbm >= 18) { + return ESP_PWR_LVL_P18; + } else if (dbm >= 15) { + return ESP_PWR_LVL_P15; + } else if (dbm >= 12) { + return ESP_PWR_LVL_P12; + } else if (dbm >= 9) { + return ESP_PWR_LVL_P9; + } else if (dbm >= 6) { + return ESP_PWR_LVL_P6; + } else if (dbm >= 3) { + return ESP_PWR_LVL_P3; + } else if (dbm >= 0) { + return ESP_PWR_LVL_N0; + } else if (dbm >= -3) { + return ESP_PWR_LVL_N3; + } else if (dbm >= -6) { + return ESP_PWR_LVL_N6; + } else if (dbm >= -9) { + return ESP_PWR_LVL_N9; + } else if (dbm >= -12) { + return ESP_PWR_LVL_N12; + } else { + return ESP_PWR_LVL_N15; + } +#else + if (dbm >= 9) { + return ESP_PWR_LVL_P9; + } else if (dbm >= 6) { + return ESP_PWR_LVL_P6; + } else if (dbm >= 3) { + return ESP_PWR_LVL_P3; + } else if (dbm >= 0) { + return ESP_PWR_LVL_N0; + } else if (dbm >= -3) { + return ESP_PWR_LVL_N3; + } else if (dbm >= -6) { + return ESP_PWR_LVL_N6; + } else if (dbm >= -9) { + return ESP_PWR_LVL_N9; + } else { + return ESP_PWR_LVL_N12; + } +#endif +} + +static int8_t esp_power_level_to_dbm(esp_power_level_t level) +{ + switch (level) { +#if ESP32_HAS_ENHANCED_TX_POWER_API + case ESP_PWR_LVL_N15: + return -15; +#endif + case ESP_PWR_LVL_N12: + return -12; + case ESP_PWR_LVL_N9: + return -9; + case ESP_PWR_LVL_N6: + return -6; + case ESP_PWR_LVL_N3: + return -3; + case ESP_PWR_LVL_N0: + return 0; + case ESP_PWR_LVL_P3: + return 3; + case ESP_PWR_LVL_P6: + return 6; + case ESP_PWR_LVL_P9: + return 9; +#if ESP32_HAS_ENHANCED_TX_POWER_API + case ESP_PWR_LVL_P12: + return 12; + case ESP_PWR_LVL_P15: + return 15; + case ESP_PWR_LVL_P18: + return 18; + case ESP_PWR_LVL_P20: + return 20; +#endif + default: + return 0; + } +} + +#if ESP32_HAS_ENHANCED_TX_POWER_API +static esp_ble_enhanced_power_type_t handle_type_to_esp_enhanced_type(uint8_t handle_type) +{ + switch (handle_type) { + case BT_HCI_VS_LL_HANDLE_TYPE_ADV: + return ESP_BLE_ENHANCED_PWR_TYPE_ADV; + case BT_HCI_VS_LL_HANDLE_TYPE_SCAN: + return ESP_BLE_ENHANCED_PWR_TYPE_SCAN; + case BT_HCI_VS_LL_HANDLE_TYPE_CONN: + return ESP_BLE_ENHANCED_PWR_TYPE_CONN; + default: + return ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT; + } +} +#else +static esp_ble_power_type_t handle_to_esp_power_type(uint8_t handle_type, uint16_t handle) +{ + switch (handle_type) { + case BT_HCI_VS_LL_HANDLE_TYPE_ADV: + return ESP_BLE_PWR_TYPE_ADV; + case BT_HCI_VS_LL_HANDLE_TYPE_SCAN: + return ESP_BLE_PWR_TYPE_SCAN; + case BT_HCI_VS_LL_HANDLE_TYPE_CONN: + if (handle <= 8) { + return (esp_ble_power_type_t)(ESP_BLE_PWR_TYPE_CONN_HDL0 + handle); + } + return ESP_BLE_PWR_TYPE_DEFAULT; + default: + return ESP_BLE_PWR_TYPE_DEFAULT; + } +} +#endif + #define DT_DRV_COMPAT espressif_esp32_bt_hci #define HCI_BT_ESP32_TIMEOUT K_MSEC(2000) @@ -25,9 +166,357 @@ struct bt_esp32_data { bt_hci_recv_t recv; }; -/* VHCI notifies when exactly one more HCI packet can be sent */ static K_SEM_DEFINE(hci_send_sem, 0, 1); +static int bt_esp32_vs_send_cmd_complete(const struct device *dev, uint16_t opcode, const void *rsp, + size_t rsp_len) +{ + struct bt_esp32_data *hci = dev->data; + struct net_buf *buf; + struct bt_hci_evt_hdr *evt_hdr; + struct bt_hci_evt_cmd_complete *cmd_complete; + + buf = bt_buf_get_evt(BT_HCI_EVT_CMD_COMPLETE, false, K_NO_WAIT); + if (!buf) { + LOG_ERR("No available event buffers for VS cmd complete"); + return -ENOMEM; + } + + evt_hdr = net_buf_add(buf, sizeof(*evt_hdr)); + evt_hdr->evt = BT_HCI_EVT_CMD_COMPLETE; + evt_hdr->len = sizeof(*cmd_complete) + rsp_len; + + cmd_complete = net_buf_add(buf, sizeof(*cmd_complete)); + cmd_complete->ncmd = 1; + cmd_complete->opcode = sys_cpu_to_le16(opcode); + + if (rsp && rsp_len > 0) { + net_buf_add_mem(buf, rsp, rsp_len); + } + + LOG_DBG("VS cmd complete: opcode 0x%04x, rsp_len %zu", opcode, rsp_len); + + hci->recv(dev, buf); + + return 0; +} + +static int bt_esp32_vs_write_tx_power(const struct device *dev, struct net_buf *buf) +{ + struct bt_hci_cp_vs_write_tx_power_level *cp; + struct bt_hci_rp_vs_write_tx_power_level rp; + esp_power_level_t esp_level; + esp_err_t err; + int8_t requested_dbm; + uint16_t handle; + + if (buf->len < sizeof(*cp)) { + LOG_ERR("VS Write TX Power: invalid param length"); + rp.status = BT_HCI_ERR_INVALID_PARAM; + rp.handle_type = 0; + rp.handle = 0; + rp.selected_tx_power = 0; + return bt_esp32_vs_send_cmd_complete(dev, BT_HCI_OP_VS_WRITE_TX_POWER_LEVEL, &rp, + sizeof(rp)); + } + + cp = (struct bt_hci_cp_vs_write_tx_power_level *)buf->data; + requested_dbm = cp->tx_power_level; + handle = sys_le16_to_cpu(cp->handle); + + LOG_DBG("VS Write TX Power: type=%u handle=%u power=%d dBm", cp->handle_type, handle, + requested_dbm); + + esp_level = dbm_to_esp_power_level(requested_dbm); + +#if ESP32_HAS_ENHANCED_TX_POWER_API + esp_ble_enhanced_power_type_t esp_type; + + esp_type = handle_type_to_esp_enhanced_type(cp->handle_type); + err = esp_ble_tx_power_set_enhanced(esp_type, handle, esp_level); + if (err != ESP_OK) { + LOG_WRN("esp_ble_tx_power_set_enhanced failed: %d", err); + rp.status = BT_HCI_ERR_INVALID_PARAM; + } else { + rp.status = BT_HCI_ERR_SUCCESS; + } +#else + esp_ble_power_type_t esp_type; + + esp_type = handle_to_esp_power_type(cp->handle_type, handle); + err = esp_ble_tx_power_set(esp_type, esp_level); + if (err != ESP_OK) { + LOG_WRN("esp_ble_tx_power_set failed: %d", err); + rp.status = BT_HCI_ERR_INVALID_PARAM; + } else { + rp.status = BT_HCI_ERR_SUCCESS; + } +#endif + + rp.handle_type = cp->handle_type; + rp.handle = cp->handle; + rp.selected_tx_power = esp_power_level_to_dbm(esp_level); + + LOG_DBG("VS Write TX Power response: status=%u selected=%d dBm", rp.status, + rp.selected_tx_power); + + return bt_esp32_vs_send_cmd_complete(dev, BT_HCI_OP_VS_WRITE_TX_POWER_LEVEL, &rp, + sizeof(rp)); +} + +static int bt_esp32_vs_read_tx_power(const struct device *dev, struct net_buf *buf) +{ + struct bt_hci_cp_vs_read_tx_power_level *cp; + struct bt_hci_rp_vs_read_tx_power_level rp; + esp_power_level_t esp_level; + uint16_t handle; + + if (buf->len < sizeof(*cp)) { + LOG_ERR("VS Read TX Power: invalid param length"); + rp.status = BT_HCI_ERR_INVALID_PARAM; + rp.handle_type = 0; + rp.handle = 0; + rp.tx_power_level = 0; + return bt_esp32_vs_send_cmd_complete(dev, BT_HCI_OP_VS_READ_TX_POWER_LEVEL, &rp, + sizeof(rp)); + } + + cp = (struct bt_hci_cp_vs_read_tx_power_level *)buf->data; + handle = sys_le16_to_cpu(cp->handle); + + LOG_DBG("VS Read TX Power: type=%u handle=%u", cp->handle_type, handle); + +#if ESP32_HAS_ENHANCED_TX_POWER_API + esp_ble_enhanced_power_type_t esp_type; + + esp_type = handle_type_to_esp_enhanced_type(cp->handle_type); + esp_level = esp_ble_tx_power_get_enhanced(esp_type, handle); + + if (esp_level == ESP_PWR_LVL_INVALID) { + LOG_WRN("esp_ble_tx_power_get_enhanced returned invalid"); + rp.status = BT_HCI_ERR_INVALID_PARAM; + rp.tx_power_level = 0; + } else { + rp.status = BT_HCI_ERR_SUCCESS; + rp.tx_power_level = esp_power_level_to_dbm(esp_level); + } +#else + esp_ble_power_type_t esp_type; + + esp_type = handle_to_esp_power_type(cp->handle_type, handle); + esp_level = esp_ble_tx_power_get(esp_type); + + rp.status = BT_HCI_ERR_SUCCESS; + rp.tx_power_level = esp_power_level_to_dbm(esp_level); +#endif + + rp.handle_type = cp->handle_type; + rp.handle = cp->handle; + + LOG_DBG("VS Read TX Power response: status=%u power=%d dBm", rp.status, rp.tx_power_level); + + return bt_esp32_vs_send_cmd_complete(dev, BT_HCI_OP_VS_READ_TX_POWER_LEVEL, &rp, + sizeof(rp)); +} + +static int bt_esp32_vs_read_static_addrs(const struct device *dev) +{ + struct { + struct bt_hci_rp_vs_read_static_addrs hdr; + struct bt_hci_vs_static_addr addr; + } __packed rp; + uint8_t mac[6]; + esp_err_t err; + + memset(&rp, 0, sizeof(rp)); + + err = esp_read_mac(mac, ESP_MAC_BT); + if (err != ESP_OK) { + LOG_DBG("Failed to read BT MAC from eFuse"); + rp.hdr.status = BT_HCI_ERR_SUCCESS; + rp.hdr.num_addrs = 0; + return bt_esp32_vs_send_cmd_complete(dev, BT_HCI_OP_VS_READ_STATIC_ADDRS, &rp.hdr, + sizeof(rp.hdr)); + } + + /* Copy MAC and set static random address bits [47:46] = 0b11 */ + memcpy(rp.addr.bdaddr.val, mac, sizeof(rp.addr.bdaddr.val)); + BT_ADDR_SET_STATIC(&rp.addr.bdaddr); + + rp.hdr.status = BT_HCI_ERR_SUCCESS; + rp.hdr.num_addrs = 1; + + LOG_DBG("VS Read Static Addrs: %02x:%02x:%02x:%02x:%02x:%02x", rp.addr.bdaddr.val[5], + rp.addr.bdaddr.val[4], rp.addr.bdaddr.val[3], rp.addr.bdaddr.val[2], + rp.addr.bdaddr.val[1], rp.addr.bdaddr.val[0]); + + return bt_esp32_vs_send_cmd_complete(dev, BT_HCI_OP_VS_READ_STATIC_ADDRS, &rp, sizeof(rp)); +} + +static int bt_esp32_vs_read_build_info(const struct device *dev) +{ + const char *version; + size_t version_len; + struct net_buf *buf; + struct bt_hci_evt_hdr *evt_hdr; + struct bt_hci_evt_cmd_complete *cmd_complete; + struct bt_hci_rp_vs_read_build_info *rp; + struct bt_esp32_data *hci = dev->data; + + version = esp32_get_controller_version(); + if (version == NULL) { + version = "unknown"; + } + version_len = strlen(version) + 1; + + buf = bt_buf_get_evt(BT_HCI_EVT_CMD_COMPLETE, false, K_NO_WAIT); + if (!buf) { + LOG_ERR("No available event buffers for VS read build info"); + return -ENOMEM; + } + + evt_hdr = net_buf_add(buf, sizeof(*evt_hdr)); + evt_hdr->evt = BT_HCI_EVT_CMD_COMPLETE; + evt_hdr->len = sizeof(*cmd_complete) + sizeof(*rp) + version_len; + + cmd_complete = net_buf_add(buf, sizeof(*cmd_complete)); + cmd_complete->ncmd = 1; + cmd_complete->opcode = sys_cpu_to_le16(BT_HCI_OP_VS_READ_BUILD_INFO); + + rp = net_buf_add(buf, sizeof(*rp)); + rp->status = BT_HCI_ERR_SUCCESS; + + net_buf_add_mem(buf, version, version_len); + + LOG_DBG("VS Read Build Info: %s", version); + + hci->recv(dev, buf); + + return 0; +} + +static uint16_t bt_esp32_get_hw_variant(void) +{ +#if defined(CONFIG_SOC_SERIES_ESP32) + return BT_HCI_VS_HW_VAR_ESP32; +#elif defined(CONFIG_SOC_SERIES_ESP32S3) + return BT_HCI_VS_HW_VAR_ESP32S3; +#elif defined(CONFIG_SOC_SERIES_ESP32C2) + return BT_HCI_VS_HW_VAR_ESP32C2; +#elif defined(CONFIG_SOC_SERIES_ESP32C3) + return BT_HCI_VS_HW_VAR_ESP32C3; +#elif defined(CONFIG_SOC_SERIES_ESP32C6) + return BT_HCI_VS_HW_VAR_ESP32C6; +#elif defined(CONFIG_SOC_SERIES_ESP32H2) + return BT_HCI_VS_HW_VAR_ESP32H2; +#else + return 0x0000; +#endif +} + +static int bt_esp32_vs_read_version_info(const struct device *dev) +{ + struct bt_hci_rp_vs_read_version_info rp; + + memset(&rp, 0, sizeof(rp)); + + rp.status = BT_HCI_ERR_SUCCESS; + rp.hw_platform = sys_cpu_to_le16(BT_HCI_VS_HW_PLAT_ESPRESSIF); + rp.hw_variant = sys_cpu_to_le16(bt_esp32_get_hw_variant()); + rp.fw_variant = 0; + rp.fw_version = KERNEL_VERSION_MAJOR & 0xff; + rp.fw_revision = sys_cpu_to_le16(KERNEL_VERSION_MINOR); + rp.fw_build = sys_cpu_to_le32(KERNEL_PATCHLEVEL & 0xffff); + + LOG_DBG("VS Read Version Info: plat=0x%04x var=0x%04x fw=%u.%u.%u", + BT_HCI_VS_HW_PLAT_ESPRESSIF, bt_esp32_get_hw_variant(), KERNEL_VERSION_MAJOR, + KERNEL_VERSION_MINOR, KERNEL_PATCHLEVEL); + + return bt_esp32_vs_send_cmd_complete(dev, BT_HCI_OP_VS_READ_VERSION_INFO, &rp, sizeof(rp)); +} + +static int bt_esp32_vs_read_supported_commands(const struct device *dev) +{ + struct bt_hci_rp_vs_read_supported_commands rp; + + memset(&rp, 0, sizeof(rp)); + rp.status = BT_HCI_ERR_SUCCESS; + + rp.commands[0] |= BIT(0); + rp.commands[0] |= BIT(1); + rp.commands[0] |= BIT(2); + rp.commands[0] |= BIT(7); + rp.commands[1] |= BIT(0); + rp.commands[1] |= BIT(5); + rp.commands[1] |= BIT(6); + + LOG_DBG("VS Read Supported Commands"); + + return bt_esp32_vs_send_cmd_complete(dev, BT_HCI_OP_VS_READ_SUPPORTED_COMMANDS, &rp, + sizeof(rp)); +} + +static int bt_esp32_vs_read_supported_features(const struct device *dev) +{ + struct bt_hci_rp_vs_read_supported_features rp; + + memset(&rp, 0, sizeof(rp)); + rp.status = BT_HCI_ERR_SUCCESS; + + rp.features[0] |= BIT(0); + + LOG_DBG("VS Read Supported Features"); + + return bt_esp32_vs_send_cmd_complete(dev, BT_HCI_OP_VS_READ_SUPPORTED_FEATURES, &rp, + sizeof(rp)); +} + +static uint16_t bt_esp32_get_vs_opcode(struct net_buf *buf) +{ + struct bt_hci_cmd_hdr *hdr; + + if (buf->len < sizeof(*hdr)) { + return 0; + } + + if (buf->data[0] != BT_HCI_H4_CMD) { + return 0; + } + + hdr = (struct bt_hci_cmd_hdr *)(buf->data + 1); + return sys_le16_to_cpu(hdr->opcode); +} + +static int bt_esp32_handle_vs_cmd(const struct device *dev, struct net_buf *buf) +{ + uint16_t opcode; + struct net_buf cmd_buf; + + opcode = bt_esp32_get_vs_opcode(buf); + + cmd_buf.data = buf->data + 1 + sizeof(struct bt_hci_cmd_hdr); + cmd_buf.len = buf->len - 1 - sizeof(struct bt_hci_cmd_hdr); + + switch (opcode) { + case BT_HCI_OP_VS_READ_VERSION_INFO: + return bt_esp32_vs_read_version_info(dev); + case BT_HCI_OP_VS_READ_SUPPORTED_COMMANDS: + return bt_esp32_vs_read_supported_commands(dev); + case BT_HCI_OP_VS_READ_SUPPORTED_FEATURES: + return bt_esp32_vs_read_supported_features(dev); + case BT_HCI_OP_VS_READ_BUILD_INFO: + return bt_esp32_vs_read_build_info(dev); + case BT_HCI_OP_VS_READ_STATIC_ADDRS: + return bt_esp32_vs_read_static_addrs(dev); + case BT_HCI_OP_VS_WRITE_TX_POWER_LEVEL: + return bt_esp32_vs_write_tx_power(dev, &cmd_buf); + case BT_HCI_OP_VS_READ_TX_POWER_LEVEL: + return bt_esp32_vs_read_tx_power(dev, &cmd_buf); + default: + return -ENOTSUP; + } +} + static bool is_hci_event_discardable(uint8_t evt_code, const uint8_t *payload, size_t plen) { switch (evt_code) { @@ -235,7 +724,7 @@ static void hci_esp_controller_rcv_pkt_ready(void) static esp_vhci_host_callback_t vhci_host_cb = { hci_esp_controller_rcv_pkt_ready, - hci_esp_host_rcv_pkt + hci_esp_host_rcv_pkt, }; static int bt_esp32_send(const struct device *dev, struct net_buf *buf) @@ -246,7 +735,16 @@ static int bt_esp32_send(const struct device *dev, struct net_buf *buf) LOG_HEXDUMP_DBG(buf->data, buf->len, "Final HCI buffer:"); - /* Wait for controller credit (callback gives the semaphore) */ + err = bt_esp32_handle_vs_cmd(dev, buf); + if (err == 0) { + net_buf_unref(buf); + return 0; + } else if (err != -ENOTSUP) { + return err; + } + + err = 0; + if (k_sem_take(&hci_send_sem, HCI_BT_ESP32_TIMEOUT) != 0) { LOG_ERR("Send packet timeout error"); err = -ETIMEDOUT; @@ -261,7 +759,6 @@ static int bt_esp32_send(const struct device *dev, struct net_buf *buf) net_buf_unref(buf); } - return err; } @@ -357,16 +854,14 @@ static int bt_esp32_close(const struct device *dev) } static DEVICE_API(bt_hci, drv) = { - .open = bt_esp32_open, - .send = bt_esp32_send, - .close = bt_esp32_close, + .open = bt_esp32_open, + .send = bt_esp32_send, + .close = bt_esp32_close, }; -#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) +#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) -/* Only one instance supported */ BT_ESP32_DEVICE_INIT(0) From c94930c6c9b8f830268cc50e65d2d88a7f43f036 Mon Sep 17 00:00:00 2001 From: Sylvio Alves Date: Tue, 23 Dec 2025 17:52:08 -0300 Subject: [PATCH 1563/3659] soc: espressif: set BLE HCI buffer defaults Set default values for BLE HCI buffer configuration that match the ESP32 controller requirements: - BT_BUF_ACL_RX_COUNT=24: Match controller's ACL buffer count - BT_BUF_EVT_RX_COUNT=30: Match controller's event buffer count Enable BT HCI node in device tree for all ESP32 SoCs that support BLE. Signed-off-by: Sylvio Alves --- .../espressif/esp32c2/esp32c2_common.dtsi | 1 + .../espressif/esp32c3/esp32c3_common.dtsi | 1 + .../espressif/esp32c6/esp32c6_common.dtsi | 1 + .../espressif/esp32h2/esp32h2_common.dtsi | 1 + dts/xtensa/espressif/esp32/esp32_common.dtsi | 1 + .../espressif/esp32s3/esp32s3_common.dtsi | 2 ++ soc/espressif/common/Kconfig.defconfig | 20 +++++++++++++++++++ 7 files changed, 27 insertions(+) diff --git a/dts/riscv/espressif/esp32c2/esp32c2_common.dtsi b/dts/riscv/espressif/esp32c2/esp32c2_common.dtsi index fccb5da0a7ee..b85de18fa025 100644 --- a/dts/riscv/espressif/esp32c2/esp32c2_common.dtsi +++ b/dts/riscv/espressif/esp32c2/esp32c2_common.dtsi @@ -53,6 +53,7 @@ esp32_bt_hci: esp32_bt_hci { compatible = "espressif,esp32-bt-hci"; + bt-hci-vs-ext; status = "disabled"; }; diff --git a/dts/riscv/espressif/esp32c3/esp32c3_common.dtsi b/dts/riscv/espressif/esp32c3/esp32c3_common.dtsi index 788724aad9c3..d60b3837c74c 100644 --- a/dts/riscv/espressif/esp32c3/esp32c3_common.dtsi +++ b/dts/riscv/espressif/esp32c3/esp32c3_common.dtsi @@ -71,6 +71,7 @@ esp32_bt_hci: esp32_bt_hci { compatible = "espressif,esp32-bt-hci"; + bt-hci-vs-ext; status = "disabled"; }; diff --git a/dts/riscv/espressif/esp32c6/esp32c6_common.dtsi b/dts/riscv/espressif/esp32c6/esp32c6_common.dtsi index 0a7cadea2d79..0316228f6a32 100644 --- a/dts/riscv/espressif/esp32c6/esp32c6_common.dtsi +++ b/dts/riscv/espressif/esp32c6/esp32c6_common.dtsi @@ -66,6 +66,7 @@ esp32_bt_hci: esp32_bt_hci { compatible = "espressif,esp32-bt-hci"; + bt-hci-vs-ext; status = "disabled"; }; diff --git a/dts/riscv/espressif/esp32h2/esp32h2_common.dtsi b/dts/riscv/espressif/esp32h2/esp32h2_common.dtsi index a1b017f167e5..5c88040baecf 100644 --- a/dts/riscv/espressif/esp32h2/esp32h2_common.dtsi +++ b/dts/riscv/espressif/esp32h2/esp32h2_common.dtsi @@ -74,6 +74,7 @@ esp32_bt_hci: esp32_bt_hci { compatible = "espressif,esp32-bt-hci"; + bt-hci-vs-ext; status = "disabled"; }; diff --git a/dts/xtensa/espressif/esp32/esp32_common.dtsi b/dts/xtensa/espressif/esp32/esp32_common.dtsi index 94c6437aa4f9..0d44c6aa396d 100644 --- a/dts/xtensa/espressif/esp32/esp32_common.dtsi +++ b/dts/xtensa/espressif/esp32/esp32_common.dtsi @@ -70,6 +70,7 @@ esp32_bt_hci: esp32_bt_hci { compatible = "espressif,esp32-bt-hci"; + bt-hci-vs-ext; status = "disabled"; }; diff --git a/dts/xtensa/espressif/esp32s3/esp32s3_common.dtsi b/dts/xtensa/espressif/esp32s3/esp32s3_common.dtsi index 8e98c722993d..2b9f09fb5885 100644 --- a/dts/xtensa/espressif/esp32s3/esp32s3_common.dtsi +++ b/dts/xtensa/espressif/esp32s3/esp32s3_common.dtsi @@ -22,6 +22,7 @@ zephyr,canbus = &twai; zephyr,entropy = &trng0; zephyr,flash-controller = &flash; + zephyr,bt-hci = &esp32_bt_hci; }; cpus { @@ -71,6 +72,7 @@ esp32_bt_hci: esp32_bt_hci { compatible = "espressif,esp32-bt-hci"; + bt-hci-vs-ext; status = "disabled"; }; diff --git a/soc/espressif/common/Kconfig.defconfig b/soc/espressif/common/Kconfig.defconfig index 337895ded15d..0ce3ba63ad24 100644 --- a/soc/espressif/common/Kconfig.defconfig +++ b/soc/espressif/common/Kconfig.defconfig @@ -52,6 +52,16 @@ config ROM_START_OFFSET endif # BOOTLOADER_MCUBOOT +if BT_ESP32 + +config BT_BUF_ACL_TX_COUNT + default 10 + +config BT_BUF_EVT_RX_COUNT + default 20 + +endif # BT_ESP32 + endif # SOC_SERIES_ESP32C2 || SOC_SERIES_ESP32C3 || SOC_SERIES_ESP32C6 || SOC_SERIES_ESP32H2 if SOC_SERIES_ESP32 || SOC_SERIES_ESP32S2 || SOC_SERIES_ESP32S3 @@ -94,4 +104,14 @@ config ROM_START_OFFSET endif # BOOTLOADER_MCUBOOT +if BT_ESP32 + +config BT_BUF_ACL_TX_COUNT + default 10 + +config BT_BUF_EVT_RX_COUNT + default 20 + +endif # BT_ESP32 + endif # SOC_SERIES_ESP32 || SOC_SERIES_ESP32S2 || SOC_SERIES_ESP32S3 From 3ff8115439839bc1c16c00ec6ee8f54867846376 Mon Sep 17 00:00:00 2001 From: Sylvio Alves Date: Tue, 23 Dec 2025 17:52:16 -0300 Subject: [PATCH 1564/3659] samples: bluetooth: hci_pwr_ctrl: remove unnecessary config Remove CONFIG_BT_CTLR_ADVANCED_FEATURES from prj.conf. This option only controls visibility of advanced features in menuconfig and is not required by the sample. It also depends on BT_LL_SW_SPLIT which is not available on all platforms (e.g., ESP32 uses a closed-source controller blob). Signed-off-by: Sylvio Alves --- samples/bluetooth/hci_pwr_ctrl/prj.conf | 1 - 1 file changed, 1 deletion(-) diff --git a/samples/bluetooth/hci_pwr_ctrl/prj.conf b/samples/bluetooth/hci_pwr_ctrl/prj.conf index 8d76025b3ab1..517ae4221b15 100644 --- a/samples/bluetooth/hci_pwr_ctrl/prj.conf +++ b/samples/bluetooth/hci_pwr_ctrl/prj.conf @@ -4,6 +4,5 @@ CONFIG_BT_PERIPHERAL=y CONFIG_BT_HRS=y CONFIG_BT_DEVICE_APPEARANCE=833 CONFIG_BT_DEVICE_NAME="Dynamic test beacon" -CONFIG_BT_CTLR_ADVANCED_FEATURES=y CONFIG_BT_CTLR_CONN_RSSI=y CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL=y From e4bfc1d2a481d4fa75d10217f3a716e6cd2e4de4 Mon Sep 17 00:00:00 2001 From: Eoin Jordan Date: Fri, 9 Jan 2026 11:25:07 +0000 Subject: [PATCH 1565/3659] doc: add Edge Impulse SDK external module documentation Add documentation for the Edge Impulse SDK Zephyr module to the external modules section, including: - Module overview describing the Edge Impulse ML development platform - Integration instructions with west.yml manifest configuration - West extension commands (ei-build, ei-deploy) for model deployment - License information (BSD-3-Clause-Clear) - References to official Edge Impulse documentation and tutorials The Edge Impulse SDK module enables machine learning inference on Zephyr devices by packaging the Edge Impulse SDK as a reusable Zephyr module with west integration for streamlined ML model deployment workflows. Signed-off-by: Eoin Jordan --- .../manifest/external/edge-impulse.rst | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 doc/develop/manifest/external/edge-impulse.rst diff --git a/doc/develop/manifest/external/edge-impulse.rst b/doc/develop/manifest/external/edge-impulse.rst new file mode 100644 index 000000000000..bf9f646b6427 --- /dev/null +++ b/doc/develop/manifest/external/edge-impulse.rst @@ -0,0 +1,64 @@ +.. _external_module_edge_impulse: + +Edge Impulse SDK for Zephyr +############################ + +Overview +************ + +Edge Impulse is a leading edge AI design and development platform for deploying machine learning +to edge devices. The Edge Impulse SDK for Zephyr packages the Edge Impulse inferencing SDK as a +Zephyr module, enabling easy integration with Zephyr's build system. Sign up for a free account +`here `_. + +The module packages the Edge Impulse inferencing SDK as a Zephyr module, enabling easy +integration with Zephyr's build system. It can also provide west extension commands to build (on +the Edge Impulse platform) and download model deployment artifacts into your workspace for +integration into a Zephyr application. + +The Edge Impulse SDK is provided under the `BSD-3-Clause-Clear license +`_. +Note that Edge Impulse cloud services require at least a free tier account or api-key to a +public project; see the `Edge Impulse website `_ for pricing and terms +of service. + +Adding the Module to Your Project +********************************** + +To use the module, add the following entry (replace ``v1.82.3`` with the desired version): + +.. code-block:: yaml + + manifest: + projects: + - name: edge-impulse-sdk-zephyr + url: https://github.com/edgeimpulse/edge-impulse-sdk-zephyr + revision: v1.82.3 + path: modules/edge-impulse-sdk-zephyr + west-commands: west/west-commands.yml + +to a Zephyr submanifest and run ``west update``, or add it to your project's ``west.yml`` manifest. + +Usage With Zephyr +****************** + +Building and deploying Edge Impulse models can be done using the provided west extension commands, +or manually. See `Edge Impulse Zephyr Module Deployment`_ for detailed instructions. + +**West Extension Commands:** + +- ``west ei-build``: Triggers Studio build with optional parameters (``-e tflite-eon``, + ``-t int8``, ``-i 1``) +- ``west ei-deploy``: Downloads pre-built deployment artifacts +- Both require ``-k`` (API key) and ``-p`` (project ID) options + +For step-by-step tutorials and guides on integrating Edge Impulse with Zephyr, see the +`Edge Impulse Zephyr Module Deployment`_. + +References +********** + +.. target-notes:: + +.. _Edge Impulse Zephyr Module Deployment: + https://docs.edgeimpulse.com/hardware/deployments/run-zephyr-module From 1cf21e55cac3564f9d1061eeaebde3372b08f8e5 Mon Sep 17 00:00:00 2001 From: Lyle Zhu Date: Tue, 30 Dec 2025 14:37:35 +0800 Subject: [PATCH 1566/3659] bluetooth: Classic: hfp_hf: make at_get_raw_string() return const char * Change at_get_raw_string() return type from 'char *' to 'const char *' to match at_get_string() and improve const-correctness. This function returns read-only AT command response data that should not be modified. - Update at_get_raw_string() signature in at.h and at.c - Update return statement cast from 'char *' to 'const char *' - Update local variables in hfp_hf.c to use 'const char *': * bvra_handle: 'id' variable * chld_handle: 'value' variable * cnum_handle: 'alpha' and 'speed' variables - Mark unused 'alpha' and 'speed' in cnum_handle with __maybe_unused - Change NULL check style from '!id' to 'id == NULL' for consistency This completes the const-correctness improvements started in the previous commit for HFP HF AT command string handling. Signed-off-by: Lyle Zhu --- subsys/bluetooth/host/classic/at.c | 4 ++-- subsys/bluetooth/host/classic/at.h | 2 +- subsys/bluetooth/host/classic/hfp_hf.c | 12 ++++++------ 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/subsys/bluetooth/host/classic/at.c b/subsys/bluetooth/host/classic/at.c index 098d78170dd9..f1c26c11434a 100644 --- a/subsys/bluetooth/host/classic/at.c +++ b/subsys/bluetooth/host/classic/at.c @@ -778,7 +778,7 @@ static bool at_get_raw_string_cb(uint8_t *c, void *data) return true; } -char *at_get_raw_string(struct at_client *at, size_t *string_len) +const char *at_get_raw_string(struct at_client *at, size_t *string_len) { struct get_raw_string_data data; @@ -800,5 +800,5 @@ char *at_get_raw_string(struct at_client *at, size_t *string_len) skip_space(at); next_list(at); - return (char *)data.start; + return (const char *)data.start; } diff --git a/subsys/bluetooth/host/classic/at.h b/subsys/bluetooth/host/classic/at.h index f535b251a901..2323071ceae2 100644 --- a/subsys/bluetooth/host/classic/at.h +++ b/subsys/bluetooth/host/classic/at.h @@ -115,4 +115,4 @@ int at_close_list(struct at_client *at); int at_open_list(struct at_client *at); bool at_has_next_list(struct at_client *at); const char *at_get_string(struct at_client *at); -char *at_get_raw_string(struct at_client *at, size_t *string_len); +const char *at_get_raw_string(struct at_client *at, size_t *string_len); diff --git a/subsys/bluetooth/host/classic/hfp_hf.c b/subsys/bluetooth/host/classic/hfp_hf.c index eca4a11903c6..8749e4a642e7 100644 --- a/subsys/bluetooth/host/classic/hfp_hf.c +++ b/subsys/bluetooth/host/classic/hfp_hf.c @@ -905,7 +905,7 @@ static int bvra_handle(struct at_client *hf_at) int err; uint32_t activate; uint32_t state; - char *id; + const char *id; char text_id[BT_HFP_BVRA_TEXT_ID_MAX_LEN + 1]; size_t id_len; uint32_t type; @@ -946,7 +946,7 @@ static int bvra_handle(struct at_client *hf_at) #if defined(CONFIG_BT_HFP_HF_VOICE_RECG_TEXT) id = at_get_raw_string(hf_at, &id_len); - if (!id) { + if (id == NULL) { LOG_INF("Error getting text ID"); return 0; } @@ -1726,7 +1726,7 @@ static int get_chld_feature(const char *name) int chld_handle(struct at_client *hf_at) { struct bt_hfp_hf *hf = CONTAINER_OF(hf_at, struct bt_hfp_hf, at); - char *value; + const char *value; uint32_t chld_features = 0; int err; @@ -1738,7 +1738,7 @@ int chld_handle(struct at_client *hf_at) while (at_has_next_list(hf_at)) { value = at_get_raw_string(hf_at, NULL); - if (!value) { + if (value == NULL) { LOG_ERR("Could not get value"); goto error; } @@ -1780,10 +1780,10 @@ static int cnum_handle(struct at_client *hf_at) { struct bt_hfp_hf *hf = CONTAINER_OF(hf_at, struct bt_hfp_hf, at); int err; - char *alpha; + __maybe_unused const char *alpha; const char *number; uint32_t type; - char *speed; + __maybe_unused const char *speed; uint32_t service = 4; alpha = at_get_raw_string(hf_at, NULL); From f017f4cb918ee77166c667cf44e8b029266b907b Mon Sep 17 00:00:00 2001 From: Gaetan Perrot Date: Tue, 6 Jan 2026 08:40:13 +0900 Subject: [PATCH 1567/3659] drivers: crypto: intel_sha: make set_ctl_enable void intel_sha_set_ctl_enable() never reports errors and always returns 0. The error check at the call site is therefore dead code. Make the function void and drop the unused error handling. Signed-off-by: Gaetan Perrot --- drivers/crypto/crypto_intel_sha.c | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/drivers/crypto/crypto_intel_sha.c b/drivers/crypto/crypto_intel_sha.c index 54934f5949a4..8e5065e41a70 100644 --- a/drivers/crypto/crypto_intel_sha.c +++ b/drivers/crypto/crypto_intel_sha.c @@ -29,7 +29,7 @@ static int intel_sha_get_unused_session_idx(void) return -1; } -static int intel_sha_set_ctl_enable(struct sha_container *sha, int status) +static void intel_sha_set_ctl_enable(struct sha_container *sha, int status) { /* wait until not busy when turning off */ if (status == 0 && sha->dfsha->shactl.part.en == 1) { @@ -38,7 +38,6 @@ static int intel_sha_set_ctl_enable(struct sha_container *sha, int status) } sha->dfsha->shactl.part.en = status; - return 0; } static int intel_sha_set_resume_length_dw0(struct sha_container *sha, uint32_t lower_length) @@ -87,10 +86,7 @@ static int intel_sha_device_run(const struct device *dev, const void *buf_in, si /* align to OWORD */ const size_t aligned_buff_size = ROUND_UP(buf_in_size, 0x10); - err = intel_sha_set_ctl_enable(self, 0); - if (err) { - return err; - } + intel_sha_set_ctl_enable(self, 0); /* set processing element disable */ self->dfsha->pibcs.part.peen = 0; @@ -142,14 +138,11 @@ static int intel_sha_device_run(const struct device *dev, const void *buf_in, si /* increment pointer */ self->dfsha->pibfpi.full = buf_in_size; - err = intel_sha_set_ctl_enable(self, 1); - if (err) { - return err; - } + intel_sha_set_ctl_enable(self, 1); - err = intel_sha_set_ctl_enable(self, 0); + intel_sha_set_ctl_enable(self, 0); - return err; + return 0; } static int intel_sha_copy_hash(struct sha_container *const self, void *dst, size_t len) From bca0b43be9ea7a08cd3510d21dd8754c32549948 Mon Sep 17 00:00:00 2001 From: Gaetan Perrot Date: Tue, 6 Jan 2026 08:50:54 +0900 Subject: [PATCH 1568/3659] drivers: crypto: intel_sha: make set_resume_length_dw1 void intel_sha_set_resume_length_dw1() never reports errors and always returns 0. The error check at the call site is therefore dead code. Make the function void and drop the unused error handling. Signed-off-by: Gaetan Perrot --- drivers/crypto/crypto_intel_sha.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/crypto/crypto_intel_sha.c b/drivers/crypto/crypto_intel_sha.c index 8e5065e41a70..ef99fafd0f38 100644 --- a/drivers/crypto/crypto_intel_sha.c +++ b/drivers/crypto/crypto_intel_sha.c @@ -52,10 +52,9 @@ static int intel_sha_set_resume_length_dw0(struct sha_container *sha, uint32_t l return err; } -static int intel_sha_set_resume_length_dw1(struct sha_container *sha, uint32_t upper_length) +static void intel_sha_set_resume_length_dw1(struct sha_container *sha, uint32_t upper_length) { sha->dfsha->sharldw1.full = upper_length; - return 0; } static int intel_sha_regs_cpy(void *dst, const void *src, size_t len) @@ -116,10 +115,8 @@ static int intel_sha_device_run(const struct device *dev, const void *buf_in, si if (err) { return err; } - err = intel_sha_set_resume_length_dw1(self, self->dfsha->shaaldw1.full); - if (err) { - return err; - } + intel_sha_set_resume_length_dw1(self, self->dfsha->shaaldw1.full); + err = intel_sha_regs_cpy((void *)self->dfsha->initial_vector, (void *)self->dfsha->sha_result, sizeof(self->dfsha->initial_vector)); From 5b92b6a66f2f7aed4b4597f995e24e2afcd6be8c Mon Sep 17 00:00:00 2001 From: Liam Ogletree Date: Fri, 31 Oct 2025 15:21:08 -0500 Subject: [PATCH 1569/3659] boards: crd40l50: Add support for CRD40L50 demonstration board Add support for the Cirrus Logic CRD40L50 demonstration board, which features a CS40L5x haptics driver, AT25 SPI flash memory, status LEDs, and a push button. Signed-off-by: Liam Ogletree Co-authored-by: Ricardo Rivera-Matos --- boards/cirrus/crd40l50/Kconfig.crd40l50 | 10 + boards/cirrus/crd40l50/Kconfig.defconfig | 12 ++ boards/cirrus/crd40l50/board.cmake | 9 + boards/cirrus/crd40l50/board.yml | 6 + boards/cirrus/crd40l50/crd40l50.dts | 199 ++++++++++++++++++ boards/cirrus/crd40l50/crd40l50.yaml | 14 ++ boards/cirrus/crd40l50/crd40l50_defconfig | 11 + .../crd40l50/doc/img/cirrus_crd40l50.webp | Bin 0 -> 10588 bytes boards/cirrus/crd40l50/doc/index.rst | 99 +++++++++ boards/cirrus/index.rst | 10 + 10 files changed, 370 insertions(+) create mode 100644 boards/cirrus/crd40l50/Kconfig.crd40l50 create mode 100644 boards/cirrus/crd40l50/Kconfig.defconfig create mode 100644 boards/cirrus/crd40l50/board.cmake create mode 100644 boards/cirrus/crd40l50/board.yml create mode 100644 boards/cirrus/crd40l50/crd40l50.dts create mode 100644 boards/cirrus/crd40l50/crd40l50.yaml create mode 100644 boards/cirrus/crd40l50/crd40l50_defconfig create mode 100644 boards/cirrus/crd40l50/doc/img/cirrus_crd40l50.webp create mode 100644 boards/cirrus/crd40l50/doc/index.rst create mode 100644 boards/cirrus/index.rst diff --git a/boards/cirrus/crd40l50/Kconfig.crd40l50 b/boards/cirrus/crd40l50/Kconfig.crd40l50 new file mode 100644 index 000000000000..c21d3d8c5a19 --- /dev/null +++ b/boards/cirrus/crd40l50/Kconfig.crd40l50 @@ -0,0 +1,10 @@ +# Copyright (c) 2026 Cirrus Logic, Inc. +# SPDX-License-Identifier: Apache-2.0 + +# Required to select STM32F401XE instead of STM32F401XD because the STM32 HAL +# does not provide a #define for STM32F401xD variants. Because STM32F401xD and +# STM32F401xE microcontrollers are identical apart from the size of embedded +# flash memory, we select SOC_STM32F401XE. + +config BOARD_CRD40L50 + select SOC_STM32F401XE diff --git a/boards/cirrus/crd40l50/Kconfig.defconfig b/boards/cirrus/crd40l50/Kconfig.defconfig new file mode 100644 index 000000000000..50a2f9bf9a5a --- /dev/null +++ b/boards/cirrus/crd40l50/Kconfig.defconfig @@ -0,0 +1,12 @@ +# Cirrus CRD40L50 Blackstar board configuration + +# Copyright (c) 2026 Cirrus Logic, Inc. +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_CRD40L50 + +config SPI_STM32_INTERRUPT + default y + depends on SPI + +endif # BOARD_CRD40L50 diff --git a/boards/cirrus/crd40l50/board.cmake b/boards/cirrus/crd40l50/board.cmake new file mode 100644 index 000000000000..10a33a180c40 --- /dev/null +++ b/boards/cirrus/crd40l50/board.cmake @@ -0,0 +1,9 @@ +# Copyright (c) 2026 Cirrus Logic, Inc. +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(stm32cubeprogrammer "--port=swd" "--reset-mode=hw") +board_runner_args(jlink "--device=STM32F401CD" "--speed=4000") + +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/cirrus/crd40l50/board.yml b/boards/cirrus/crd40l50/board.yml new file mode 100644 index 000000000000..ae27fb9cf9e0 --- /dev/null +++ b/boards/cirrus/crd40l50/board.yml @@ -0,0 +1,6 @@ +board: + name: crd40l50 + full_name: CRD40L50-POC-Q + vendor: cirrus + socs: + - name: stm32f401xd diff --git a/boards/cirrus/crd40l50/crd40l50.dts b/boards/cirrus/crd40l50/crd40l50.dts new file mode 100644 index 000000000000..0d807b1990eb --- /dev/null +++ b/boards/cirrus/crd40l50/crd40l50.dts @@ -0,0 +1,199 @@ +/* + * Copyright (c) 2026 Cirrus Logic, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include +#include + +/ { + model = "Cirrus Logic CRD40L50-POC-Q"; + compatible = "cirrus,crd40l50"; + + aliases { + flash1 = &flash_1; + haptic0 = &haptic_0; + led0 = &green_led_1; + led1 = &red_led_1; + led2 = &yellow_led_1; + led3 = &yellow_led_2; + led4 = &yellow_led_3; + sw0 = &user_button; + }; + + buttons { + compatible = "gpio-keys"; + + user_button: button { + label = "User"; + gpios = <&gpioa 2 GPIO_ACTIVE_LOW>; + zephyr,code = ; + }; + }; + + chosen { + zephyr,code-partition = &slot0_partition; + zephyr,console = &rtt0; + zephyr,flash = &flash0; + zephyr,shell-uart = &usart1; + zephyr,sram = &sram0; + }; + + leds { + compatible = "gpio-leds"; + + green_led_1: led_1 { + gpios = <&gpiob 5 GPIO_ACTIVE_HIGH>; + label = "LED PASS"; + }; + + red_led_1: led_2 { + gpios = <&gpiob 8 GPIO_ACTIVE_HIGH>; + label = "LED FAIL"; + }; + + yellow_led_1: led_3 { + gpios = <&gpiob 9 GPIO_ACTIVE_HIGH>; + label = "SEL LED 1"; + }; + + yellow_led_2: led_4 { + gpios = <&gpioc 13 GPIO_ACTIVE_HIGH>; + label = "SEL LED 2"; + }; + + yellow_led_3: led_5 { + gpios = <&gpioa 3 GPIO_ACTIVE_HIGH>; + label = "SEL LED 3"; + }; + }; + + rtt0: rtt_chan0 { + compatible = "segger,rtt-uart"; + status = "okay"; + }; +}; + +&clk_lse { + status = "okay"; +}; + +&clk_hsi { + status = "okay"; +}; + +&pll { + status = "okay"; + + clocks = <&clk_hsi>; + + div-m = <16>; + mul-n = <336>; + div-p = <4>; + div-q = <7>; +}; + +&rcc { + clocks = <&pll>; + clock-frequency = ; + + ahb-prescaler = <1>; + apb1-prescaler = <2>; + apb2-prescaler = <1>; +}; + +&i2c1 { + status = "okay"; + + clock-frequency = ; + + pinctrl-0 = <&i2c1_scl_pb6 &i2c1_sda_pb7>; + pinctrl-1 = <&analog_pb6 &analog_pb7>; + pinctrl-names = "default", "sleep"; + + haptic_0: haptic@30 { + compatible = "cirrus,cs40l5x"; + reg = <0x30>; + + reset-gpios = <&gpiob 4 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + int-gpios = <&gpioh 0 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + + trigger-mapping = <11 12 13>; + trigger-gpios = <&gpioa 8 GPIO_PULL_UP>, + <&gpioa 9 GPIO_PULL_UP>, + <&gpiob 10 GPIO_PULL_UP>; + + flash-storage = <&flash_1>; + flash-offset = <0x0>; + + status = "okay"; + }; +}; + +&spi2 { + status = "okay"; + + cs-gpios = <&gpiob 12 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + + pinctrl-0 = <&spi2_sck_pb13 &spi2_miso_pb14 &spi2_mosi_pb15>; + pinctrl-1 = <&analog_pb13 &analog_pb14 &analog_pb15>; + pinctrl-names = "default", "sleep"; + + flash_1: flash@0 { + compatible = "atmel,at25xv021a"; + reg = <0>; + spi-max-frequency = <25000000>; + + size = ; + page-size = <256>; + timeout = <10>; + timeout-erase = <4000>; + + wp-gpios = <&gpiob 2 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + + status = "okay"; + }; +}; + +&flash0 { + partitions { + compatible = "fixed-partitions"; + + #address-cells = <1>; + #size-cells = <1>; + + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 DT_SIZE_K(64)>; + read-only; + }; + + /* + * The flash starting at offset 0x10000 and ending at + * offset 0x1ffff is reserved for use by the application. + */ + + slot0_partition: partition@20000 { + label = "image-0"; + reg = <0x00020000 DT_SIZE_K(64)>; + }; + + slot1_partition: partition@30000 { + label = "image-1"; + reg = <0x00030000 DT_SIZE_K(64)>; + }; + + scratch_partition: partition@40000 { + label = "image-scratch"; + reg = <0x00040000 DT_SIZE_K(64)>; + }; + + storage_partition: partition@50000 { + label = "storage"; + reg = <0x00050000 DT_SIZE_K(64)>; + }; + }; +}; diff --git a/boards/cirrus/crd40l50/crd40l50.yaml b/boards/cirrus/crd40l50/crd40l50.yaml new file mode 100644 index 000000000000..229f5f9bbbc0 --- /dev/null +++ b/boards/cirrus/crd40l50/crd40l50.yaml @@ -0,0 +1,14 @@ +identifier: crd40l50 +name: CRD40L50-POC-Q +type: mcu +arch: arm +toolchain: + - zephyr +supported: + - gpio + - i2c + - spi + - rtc +ram: 96 +flash: 384 +vendor: cirrus diff --git a/boards/cirrus/crd40l50/crd40l50_defconfig b/boards/cirrus/crd40l50/crd40l50_defconfig new file mode 100644 index 000000000000..54a56a4734c4 --- /dev/null +++ b/boards/cirrus/crd40l50/crd40l50_defconfig @@ -0,0 +1,11 @@ +# Copyright (c) 2026 Cirrus Logic, Inc. +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_GPIO=y + +# Required to flash and debug with the SEGGER J-Link +CONFIG_SERIAL=y +CONFIG_CONSOLE=y +CONFIG_RTT_CONSOLE=y +CONFIG_UART_RTT=y +CONFIG_USE_SEGGER_RTT=y diff --git a/boards/cirrus/crd40l50/doc/img/cirrus_crd40l50.webp b/boards/cirrus/crd40l50/doc/img/cirrus_crd40l50.webp new file mode 100644 index 0000000000000000000000000000000000000000..b05ccbb5f80ad8d6933858064e45c20a07754df9 GIT binary patch literal 10588 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 Date: Tue, 6 Jan 2026 14:28:47 -0600 Subject: [PATCH 1570/3659] samples: cs40l5x: Support CRD40L50 demonstration board Add CRD40L50 board support to the CS40L5x sample application and update documentation accordingly. Signed-off-by: Liam Ogletree --- samples/drivers/haptics/cs40l5x/README.rst | 12 ++++++++++-- samples/drivers/haptics/cs40l5x/boards/crd40l50.conf | 2 ++ samples/drivers/haptics/cs40l5x/sample.yaml | 1 + 3 files changed, 13 insertions(+), 2 deletions(-) create mode 100644 samples/drivers/haptics/cs40l5x/boards/crd40l50.conf diff --git a/samples/drivers/haptics/cs40l5x/README.rst b/samples/drivers/haptics/cs40l5x/README.rst index 3e897d6ace40..8fb4c8b0412a 100644 --- a/samples/drivers/haptics/cs40l5x/README.rst +++ b/samples/drivers/haptics/cs40l5x/README.rst @@ -28,8 +28,16 @@ edge-triggered effects. :goals: build :compact: -For flashing the application, refer to the Flashing section of the :zephyr:board:`nucleo_f401re` board -documentation. +Alternatively, build the application for the :zephyr:board:`crd40l50` demonstration board. + +.. zephyr-app-commands:: + :zephyr-app: samples/drivers/haptics/cs40l5x + :board: crd40l50 + :goals: build + :compact: + +For flashing the application, refer to the Flashing sections of the :zephyr:board:`nucleo_f401re` or +:zephyr:board:`crd40l50` board documentation. .. code-block:: none diff --git a/samples/drivers/haptics/cs40l5x/boards/crd40l50.conf b/samples/drivers/haptics/cs40l5x/boards/crd40l50.conf new file mode 100644 index 000000000000..33249afd215c --- /dev/null +++ b/samples/drivers/haptics/cs40l5x/boards/crd40l50.conf @@ -0,0 +1,2 @@ +# Required to use shell interface with the SEGGER J-Link +CONFIG_SHELL_BACKEND_RTT=y diff --git a/samples/drivers/haptics/cs40l5x/sample.yaml b/samples/drivers/haptics/cs40l5x/sample.yaml index 9ba767255cd7..8b7a92dc9088 100644 --- a/samples/drivers/haptics/cs40l5x/sample.yaml +++ b/samples/drivers/haptics/cs40l5x/sample.yaml @@ -6,3 +6,4 @@ tests: tags: haptics platform_allow: - nucleo_f401re + - crd40l50 From 1753bdb0f6e54f3f2147ff89fb5b5cf7441f2867 Mon Sep 17 00:00:00 2001 From: Zackery Backman Date: Tue, 6 Jan 2026 14:59:54 -0700 Subject: [PATCH 1571/3659] doc: develop: manifests: external: add wolfMQTT Add documentation to external module section for adding wolfMQTT to Zephyr Signed-off-by: Zackery Backman --- doc/develop/manifest/external/wolfmqtt.rst | 88 ++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 doc/develop/manifest/external/wolfmqtt.rst diff --git a/doc/develop/manifest/external/wolfmqtt.rst b/doc/develop/manifest/external/wolfmqtt.rst new file mode 100644 index 000000000000..3fdcb1a34768 --- /dev/null +++ b/doc/develop/manifest/external/wolfmqtt.rst @@ -0,0 +1,88 @@ +.. _external_module_wolfmqtt: + +wolfMQTT +######## + +Introduction +************ + +wolfMQTT is a lightweight, portable MQTT client library optimized for +embedded systems, RTOS environments, and resource-constrained devices. +It provides a client implementation of the MQTT protocol with support +for MQTT v3.1.1 and v5.0. The library offers features such as QoS +levels 0-2, Last Will and Testament (LWT), and compatibility with +various MQTT brokers. Its support for multiple build configurations +makes it suitable for a wide range of IoT applications and hardware +platforms that are utilizing the Zephyr RTOS. + +wolfMQTT has support for the Zephyr networking stack so applications +can use the wolfMQTT API to establish MQTT connections with brokers and +other devices or services over the network. + +wolfMQTT is dual licensed under GPLv3 and commercial licenses. + +GitHub Repository: `wolfMQTT Repository`_ + +Requirements +************ + +* :ref:`external_module_wolfssl` for secure communication (TLS support) + +Usage with Zephyr +***************** + +Add wolfMQTT as a project to your west.yml: + +.. code-block:: yaml + + manifest: + remotes: + # + - name: wolfmqtt + url-base: https://github.com/wolfssl + projects: + # + - name: wolfmqtt + path: modules/lib/wolfmqtt + revision: v1.21.0 + remote: wolfmqtt + +.. note:: + + The revision shown above is an example. Check the `wolfMQTT Repository`_ + releases page for the latest release tag to ensure you are using the desired + version. + +Update west's modules: + +.. code-block:: bash + + west update + +Now west recognizes ``wolfmqtt`` as a module, and will include its +Kconfig and CMakeLists.txt in the build system. + +For more regarding the usage of wolfMQTT with Zephyr, please refer to +the `wolfMQTT Zephyr Example Usage`_. + +For application code examples in Zephyr, please refer to the +`wolfSSL NXP AppCodeHub`_. + +For wolfMQTT API documentation, please refer to the `wolfMQTT Documentation`_. + +Reference +********* + +.. target-notes:: + +.. _wolfMQTT Repository: + https://github.com/wolfSSL/wolfMQTT + +.. _wolfMQTT Zephyr Example Usage: + https://github.com/wolfSSL/wolfMQTT/tree/master/zephyr + +.. _wolfSSL NXP AppCodeHub: + https://github.com/wolfSSL/nxp-appcodehub + +.. _wolfMQTT Documentation: + https://www.wolfssl.com/documentation/manuals/wolfmqtt/ From 6defef2519127ebf0ea12d74000bfd5894726117 Mon Sep 17 00:00:00 2001 From: Zackery Backman Date: Tue, 6 Jan 2026 15:00:41 -0700 Subject: [PATCH 1572/3659] doc: develop: manifests: external: add wolfTPM Add documentation to external module section for adding wolfTPM to Zephyr Signed-off-by: Zackery Backman --- doc/develop/manifest/external/wolftpm.rst | 118 ++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 doc/develop/manifest/external/wolftpm.rst diff --git a/doc/develop/manifest/external/wolftpm.rst b/doc/develop/manifest/external/wolftpm.rst new file mode 100644 index 000000000000..9bd73618c2eb --- /dev/null +++ b/doc/develop/manifest/external/wolftpm.rst @@ -0,0 +1,118 @@ +.. _external_module_wolftpm: + +wolfTPM +####### + +Introduction +************ + +wolfTPM is a lightweight, portable TPM 2.0 library optimized for +embedded systems, RTOS environments, and resource-constrained devices. +It provides a full TPM 2.0 implementation including support for +cryptographic operations, key generation, secure storage, and +attestation. + +wolfTPM has been integrated as a Zephyr module with CMake and Kconfig +support, making it simple to include TPM functionality in any +Zephyr-based project. The module supports device tree integration for +I2C communication with TPM devices - you can configure the I2C bus by +setting ``WOLFTPM_ZEPHYR_I2C_BUS`` in ``user_settings.h`` to the node +describing the I2C bus on your device. I2C speed can be configured with +``WOLFTPM_ZEPHYR_I2C_SPEED``. + +wolfTPM is dual licensed under GPLv3 and commercial licenses. + +GitHub Repository: `wolfTPM Repository`_ + +Requirements +************ + +* :ref:`external_module_wolfssl` for cryptographic operations + +Usage with Zephyr +***************** + +Add wolfTPM as a project to your west.yml: + +.. code-block:: yaml + + manifest: + remotes: + # + - name: wolftpm + url-base: https://github.com/wolfssl + projects: + # + - name: wolftpm + path: modules/crypto/wolftpm + revision: v3.10.0 + remote: wolftpm + +.. note:: + + The revision shown above is an example. Check the `wolfTPM Repository`_ + releases page for the latest release tag to ensure you are using the desired + version. + +Update west's modules: + +.. code-block:: bash + + west update + +Now west recognizes ``wolftpm`` as a module, and will include its +Kconfig and CMakeLists.txt in the build system. + +Sample Applications +******************* + +wolfTPM includes two sample applications for Zephyr: + +* **wolftpm_wrap_test** - tests core TPM wrapper functionality +* **wolftpm_wrap_caps** - displays TPM capabilities + +Both examples build and run successfully on qemu_x86, providing a solid +foundation for development. + +Configuration +************* + +The module uses a ``user_settings.h`` configuration file that can be +customized to match project-specific requirements. For I2C communication +with TPM devices, configure: + +* ``WOLFTPM_ZEPHYR_I2C_BUS`` - set to the device tree node describing + your I2C bus +* ``WOLFTPM_ZEPHYR_I2C_SPEED`` - set the I2C line speed + +Additional Resources +******************** + +For more regarding the usage of wolfTPM with Zephyr, please refer to +the `wolfTPM Zephyr Example Usage`_ and the `wolfTPM Zephyr +Announcement`_. + +For application code examples in Zephyr, please refer to the +`wolfSSL NXP AppCodeHub`_. + +For wolfTPM API documentation, please refer to the `wolfTPM Documentation`_. + +Reference +********* + +.. target-notes:: + +.. _wolfTPM Repository: + https://github.com/wolfSSL/wolfTPM + +.. _wolfTPM Zephyr Example Usage: + https://github.com/wolfSSL/wolfTPM/blob/master/zephyr/README.md + +.. _wolfSSL NXP AppCodeHub: + https://github.com/wolfSSL/nxp-appcodehub + +.. _wolfTPM Documentation: + https://www.wolfssl.com/documentation/manuals/wolftpm/ + +.. _wolfTPM Zephyr Announcement: + https://www.wolfssl.com/wolftpm-support-for-zephyr-rtos/ From 8aec838debd5c5a9dae337b59ef996f1331f66b9 Mon Sep 17 00:00:00 2001 From: Eric Mechin Date: Wed, 7 Jan 2026 14:48:35 +0100 Subject: [PATCH 1573/3659] drivers: stm32wb: ipm_stm32wb: Add extended advertising support Set extended advertising setting in ipm_stm32wb.c with stm32wb_set_stack_options function call for the BLE stack Options flags initialization according to the zephyr Kconfig options. Signed-off-by: Eric Mechin --- drivers/bluetooth/hci/ipm_stm32wb.c | 95 +++++++++++++++++++++++++++-- 1 file changed, 90 insertions(+), 5 deletions(-) diff --git a/drivers/bluetooth/hci/ipm_stm32wb.c b/drivers/bluetooth/hci/ipm_stm32wb.c index 0f61f7c36f78..c093bd6ad538 100644 --- a/drivers/bluetooth/hci/ipm_stm32wb.c +++ b/drivers/bluetooth/hci/ipm_stm32wb.c @@ -84,12 +84,80 @@ static struct k_thread ipm_rx_thread_data; static bool c2_started_flag; +static void stm32wb_set_stack_options(SHCI_C2_Ble_Init_Cmd_Packet_t *ble_init_cmd_packet) +{ + ble_init_cmd_packet->Param.Options = + SHCI_C2_BLE_INIT_OPTIONS_LL_HOST | + SHCI_C2_BLE_INIT_OPTIONS_WITH_SVC_CHANGE_DESC | + SHCI_C2_BLE_INIT_OPTIONS_FULL_GATTDB_NVM | + SHCI_C2_BLE_INIT_OPTIONS_POWER_CLASS_2_3; + ble_init_cmd_packet->Param.Options_extension = 0; + +#if !defined(CONFIG_BT_DEVICE_NAME_GATT_WRITABLE) + ble_init_cmd_packet->Param.Options |= + SHCI_C2_BLE_INIT_OPTIONS_DEVICE_NAME_RO; +#endif + +#if defined(CONFIG_BT_EXT_ADV) + ble_init_cmd_packet->Param.Options |= + SHCI_C2_BLE_INIT_OPTIONS_EXT_ADV | + SHCI_C2_BLE_INIT_OPTIONS_CS_ALGO2; +#endif + +#if defined(CONFIG_BT_GATT_CACHING) + ble_init_cmd_packet->Param.Options |= + SHCI_C2_BLE_INIT_OPTIONS_GATT_CACHING_USED; +#endif + +#if defined(CONFIG_BT_DEVICE_APPEARANCE_GATT_WRITABLE) + ble_init_cmd_packet->Param.Options_extension |= + SHCI_C2_BLE_INIT_OPTIONS_APPEARANCE_WRITABLE; +#endif + +#if defined(CONFIG_BT_EATT) + ble_init_cmd_packet->Param.Options_extension |= + SHCI_C2_BLE_INIT_OPTIONS_ENHANCED_ATT_SUPPORTED; +#endif + +#if defined(CONFIG_BT_EXT_ADV_MAX_ADV_SET) +#if (CONFIG_BT_EXT_ADV_MAX_ADV_SET > 8) + ble_init_cmd_packet->Param.max_adv_set_nbr = 1; +#else + ble_init_cmd_packet->Param.max_adv_set_nbr = CONFIG_BT_EXT_ADV_MAX_ADV_SET; +#endif +#else + ble_init_cmd_packet->Param.max_adv_set_nbr = 1; +#endif + + if (ble_init_cmd_packet->Param.max_adv_set_nbr < 4) { + ble_init_cmd_packet->Param.max_adv_data_len = 1650; + } else if (ble_init_cmd_packet->Param.max_adv_set_nbr == 4) { + ble_init_cmd_packet->Param.max_adv_data_len = 1035; + } else if (ble_init_cmd_packet->Param.max_adv_set_nbr == 5) { + ble_init_cmd_packet->Param.max_adv_data_len = 621; + } else if (ble_init_cmd_packet->Param.max_adv_set_nbr == 6) { + ble_init_cmd_packet->Param.max_adv_data_len = 414; + } else { + ble_init_cmd_packet->Param.max_adv_data_len = 207; + } + +#if defined(CONFIG_BT_EATT_MAX) +#if (CONFIG_BT_EATT_MAX > 4) + ble_init_cmd_packet->Param.MaxAddEattBearers = 4; +#else + ble_init_cmd_packet->Param.MaxAddEattBearers = CONFIG_BT_EATT_MAX; +#endif +#else + ble_init_cmd_packet->Param.MaxAddEattBearers = 4; +#endif +} + static void stm32wb_start_ble(uint32_t rf_clock) { SHCI_C2_Ble_Init_Cmd_Packet_t ble_init_cmd_packet = { - { { 0, 0, 0 } }, /**< Header unused */ - { 0, /** pBleBufferAddress not used */ - 0, /** BleBufferSize not used */ + { { 0, 0, 0 } }, /**< Header unused */ + { 0, /** pBleBufferAddress not used */ + 0, /** BleBufferSize not used */ CFG_BLE_NUM_GATT_ATTRIBUTES, CFG_BLE_NUM_GATT_SERVICES, CFG_BLE_ATT_VALUE_ARRAY_SIZE, @@ -105,9 +173,26 @@ static void stm32wb_start_ble(uint32_t rf_clock) CFG_BLE_HSE_STARTUP_TIME, CFG_BLE_VITERBI_MODE, CFG_BLE_OPTIONS, - 0 } + 0, + CFG_BLE_MAX_COC_INITIATOR_NBR, + CFG_BLE_MIN_TX_POWER, + CFG_BLE_MAX_TX_POWER, + CFG_BLE_RX_MODEL_CONFIG, + CFG_BLE_MAX_ADV_SET_NBR, + CFG_BLE_MAX_ADV_DATA_LEN, + CFG_BLE_TX_PATH_COMPENS, + CFG_BLE_RX_PATH_COMPENS, + CFG_BLE_CORE_VERSION, + CFG_BLE_OPTIONS_EXT, + CFG_BLE_MAX_ADD_EATT_BEARERS } }; + /** + * Set BLE Options, Options_extension, max_adv_set_nbr, + * max_adv_data_len and MaxAddEattBearers according zephyr KConfig + */ + stm32wb_set_stack_options(&ble_init_cmd_packet); + /** * Starts the BLE Stack on CPU2 */ @@ -473,7 +558,7 @@ static int bt_ipm_ble_init(void) } param = net_buf_add(buf, sizeof(*param)); param->cmd = 0x0F; - param->value[0] = 0x18; + param->value[0] = CFG_TX_POWER; /* app_conf.h define: 0x18 => -0.15dBm */ param->value[1] = 0x01; err = bt_hci_cmd_send_sync(ACI_WRITE_SET_TX_POWER_LEVEL, buf, NULL); From e6bd2151daa37e44f239e38840cee8e2fbbfc898 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fin=20Maa=C3=9F?= Date: Thu, 8 Jan 2026 11:27:12 +0100 Subject: [PATCH 1574/3659] drivers: ethernet: nxp: fix set_config case MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit the enum ethernet_config_type for the multicast filter is ETHERNET_CONFIG_TYPE_FILTER. ETHERNET_HW_FILTERING is only the according ethernet_hw_caps. Signed-off-by: Fin Maaß --- drivers/ethernet/eth_nxp_s32_gmac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ethernet/eth_nxp_s32_gmac.c b/drivers/ethernet/eth_nxp_s32_gmac.c index e3b43b2a869f..2552e593f5d7 100644 --- a/drivers/ethernet/eth_nxp_s32_gmac.c +++ b/drivers/ethernet/eth_nxp_s32_gmac.c @@ -537,7 +537,7 @@ static int eth_nxp_s32_set_config(const struct device *dev, break; #endif #if defined(CONFIG_ETH_NXP_S32_MULTICAST_FILTER) - case ETHERNET_HW_FILTERING: + case ETHERNET_CONFIG_TYPE_FILTER: if (config->filter.set) { Gmac_Ip_AddDstAddrToHashFilter(cfg->instance, config->filter.mac_address.addr); From eaca1fcf7f4bec36a1e494cc41d0ae12aba7f699 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fin=20Maa=C3=9F?= Date: Thu, 8 Jan 2026 11:34:47 +0100 Subject: [PATCH 1575/3659] drivers: ethernet: nxp: netc: fix ethernet_hw_caps MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ETHERNET_CONFIG_TYPE_FILTER is not supported in the set_config, therefore remove ETHERNET_HW_FILTERING from the ethernet_hw_caps of this driver. Signed-off-by: Fin Maaß --- drivers/ethernet/nxp_imx_netc/eth_nxp_imx_netc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ethernet/nxp_imx_netc/eth_nxp_imx_netc.c b/drivers/ethernet/nxp_imx_netc/eth_nxp_imx_netc.c index 56e5aa919f05..9106e17fcd7a 100644 --- a/drivers/ethernet/nxp_imx_netc/eth_nxp_imx_netc.c +++ b/drivers/ethernet/nxp_imx_netc/eth_nxp_imx_netc.c @@ -575,7 +575,7 @@ enum ethernet_hw_caps netc_eth_get_capabilities(const struct device *dev) uint32_t caps; caps = (ETHERNET_LINK_10BASE | ETHERNET_LINK_100BASE | ETHERNET_LINK_1000BASE | - ETHERNET_HW_RX_CHKSUM_OFFLOAD | ETHERNET_HW_FILTERING + ETHERNET_HW_RX_CHKSUM_OFFLOAD #if defined(CONFIG_NET_VLAN) | ETHERNET_HW_VLAN #endif From 311769564c6cc546d80765f38bfac2234cc81963 Mon Sep 17 00:00:00 2001 From: Gaetan Perrot Date: Thu, 8 Jan 2026 20:46:34 +0900 Subject: [PATCH 1576/3659] samples: sensor: soc_voltage: fix error propagation print_voltage() always returned success even when sensor operations failed, making the error check in main() dead code. Return the actual error codes so failures are correctly propagated to the caller. Signed-off-by: Gaetan Perrot --- samples/sensor/soc_voltage/src/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/samples/sensor/soc_voltage/src/main.c b/samples/sensor/soc_voltage/src/main.c index 19ac0ca3fe15..260e4b12b0ba 100644 --- a/samples/sensor/soc_voltage/src/main.c +++ b/samples/sensor/soc_voltage/src/main.c @@ -25,13 +25,13 @@ static int print_voltage(const struct device *dev) rc = sensor_sample_fetch(dev); if (rc) { printk("Failed to fetch sample (%d)\n", rc); - return 0; + return rc; } rc = sensor_channel_get(dev, SENSOR_CHAN_VOLTAGE, &val); if (rc) { printk("Failed to get data (%d)\n", rc); - return 0; + return rc; } printk("Sensor voltage[%s]: %.2f V\n", dev->name, sensor_value_to_double(&val)); From e0da5fa899af50aa2034523aae7a7788296e62d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fin=20Maa=C3=9F?= Date: Thu, 8 Jan 2026 14:31:49 +0100 Subject: [PATCH 1577/3659] MAINTAINERS.yml: add maass-hamburg to i2c colaborators MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit add me to the i2c collaborators, that we are going to have at least 2 reviewers for that area. I wrote the drivers/i2c/i2c_litex_litei2c.c driver and the acording i2c core https://github.com/litex-hub/litei2c Signed-off-by: Fin Maaß --- MAINTAINERS.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index 91013e1c10b8..aea295559274 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -1833,6 +1833,8 @@ Documentation Infrastructure: status: maintained maintainers: - teburd + collaborators: + - maass-hamburg files: - drivers/i2c/ - include/zephyr/drivers/i2c/ From ca26f143f0fb646fbfce85520d8a0b2a3374f885 Mon Sep 17 00:00:00 2001 From: Grzegorz Chwierut Date: Thu, 8 Jan 2026 14:33:02 +0100 Subject: [PATCH 1578/3659] samples: sysbuild: hello_world: Skip test if no second UART If a second UART was not configured in the hardware map, then skip the testcase instead of failing. Signed-off-by: Grzegorz Chwierut --- samples/sysbuild/hello_world/pytest/test_both_uart.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/samples/sysbuild/hello_world/pytest/test_both_uart.py b/samples/sysbuild/hello_world/pytest/test_both_uart.py index ad920034d31f..c81542ecd4fd 100644 --- a/samples/sysbuild/hello_world/pytest/test_both_uart.py +++ b/samples/sysbuild/hello_world/pytest/test_both_uart.py @@ -3,6 +3,7 @@ # # SPDX-License-Identifier: Apache-2.0 # +import pytest from twister_harness import DeviceAdapter timeout = 5 @@ -16,4 +17,7 @@ def test_uart_in_app(dut: DeviceAdapter): def test_uart_in_second_core(dut: DeviceAdapter): """Verify logs from uart in second core""" + if len(dut.connections) < 2: + pytest.skip("Only one UART connection configured for this device") + dut.readlines_until(connection_index=1, regex=regex, print_output=True, timeout=timeout) From 9ae3b77359fb5cb04f39f22cd39c60740d3424b9 Mon Sep 17 00:00:00 2001 From: Stefan Gloor Date: Thu, 8 Jan 2026 14:42:08 +0100 Subject: [PATCH 1579/3659] net: net_if: remove obsolete documentation about buffer lifetime The net_linkaddr struct used to use pointers instead of copying the data. Thankfully this was fixed in https://github.com/zephyrproject-rtos/zephyr/pull/87027. Remove the old comment to reflect the current state. Signed-off-by: Stefan Gloor --- include/zephyr/net/net_if.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/zephyr/net/net_if.h b/include/zephyr/net/net_if.h index 6ea94ad7f60f..d6b4abc6df1e 100644 --- a/include/zephyr/net/net_if.h +++ b/include/zephyr/net/net_if.h @@ -1348,7 +1348,6 @@ extern struct net_if_addr *net_if_addr_ref(struct net_if *iface, * * @param iface Pointer to a network interface structure * @param addr A pointer to a uint8_t buffer representing the address. - * The buffer must remain valid throughout interface lifetime. * @param len length of the address buffer * @param type network bearer type of this link address * From d6f9a4808f2ea86ab786a681b85166628f7ffba8 Mon Sep 17 00:00:00 2001 From: Ian Morris Date: Wed, 31 Dec 2025 16:35:22 -0800 Subject: [PATCH 1580/3659] boards: renesas: ek_ra4l1: added arduino node labels Added arduino_serial and arduino_header node labels to EK-RA4L1 device tree board definition, allowing compatible shield boards to be used. Signed-off-by: Ian Morris --- boards/renesas/ek_ra4l1/ek_ra4l1.dts | 33 ++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/boards/renesas/ek_ra4l1/ek_ra4l1.dts b/boards/renesas/ek_ra4l1/ek_ra4l1.dts index 41f6eec77277..19f8bc593c1c 100644 --- a/boards/renesas/ek_ra4l1/ek_ra4l1.dts +++ b/boards/renesas/ek_ra4l1/ek_ra4l1.dts @@ -9,6 +9,8 @@ #include #include #include +#include + #include "ek_ra4l1-pinctrl.dtsi" / { @@ -67,6 +69,35 @@ /* GND */ }; + arduino_header: arduino-connector { + compatible = "arduino-header-r3"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; + }; + buttons { compatible = "gpio-keys"; @@ -272,3 +303,5 @@ }; mikrobus_serial: &uart1 {}; + +arduino_serial: &uart1 {}; From f16c568c9924eedf245688dab1ffbaaef77aa5e7 Mon Sep 17 00:00:00 2001 From: Piotr Kosycarz Date: Mon, 12 Jan 2026 09:20:52 +0100 Subject: [PATCH 1581/3659] samples: boards: nordic: coresight_stm: enable uart at rtt config Enable uart logging as it is required for testing. Can be used at the same time with RTT. Signed-off-by: Piotr Kosycarz --- samples/boards/nordic/coresight_stm/sample.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/samples/boards/nordic/coresight_stm/sample.yaml b/samples/boards/nordic/coresight_stm/sample.yaml index 10f1d153855a..1be8b6384733 100644 --- a/samples/boards/nordic/coresight_stm/sample.yaml +++ b/samples/boards/nordic/coresight_stm/sample.yaml @@ -46,7 +46,6 @@ tests: - nordic-log-stm extra_configs: - CONFIG_DEBUG_NRF_ETR_BACKEND_RTT=y - - CONFIG_DEBUG_NRF_ETR_BACKEND_UART=n - CONFIG_SEGGER_RTT_BUFFER_SIZE_UP=8192 extra_args: - SB_CONFIG_APP_CPUPPR_RUN=y From 918bc5876168f56fe5182710976876df9b130e64 Mon Sep 17 00:00:00 2001 From: Camille BAUD Date: Tue, 11 Nov 2025 10:54:32 +0100 Subject: [PATCH 1582/3659] dts: bflb: add PWM nodes Adds nodes for BFLB pwm Signed-off-by: Camille BAUD --- dts/bindings/pwm/bflb,pwm-1.yaml | 21 +++++++++++++++++++++ dts/bindings/pwm/bflb,pwm-2.yaml | 22 ++++++++++++++++++++++ dts/riscv/bflb/bl60x.dtsi | 11 +++++++++++ dts/riscv/bflb/bl61x.dtsi | 11 +++++++++++ dts/riscv/bflb/bl70x.dtsi | 11 +++++++++++ 5 files changed, 76 insertions(+) create mode 100644 dts/bindings/pwm/bflb,pwm-1.yaml create mode 100644 dts/bindings/pwm/bflb,pwm-2.yaml diff --git a/dts/bindings/pwm/bflb,pwm-1.yaml b/dts/bindings/pwm/bflb,pwm-1.yaml new file mode 100644 index 000000000000..2afc107d469c --- /dev/null +++ b/dts/bindings/pwm/bflb,pwm-1.yaml @@ -0,0 +1,21 @@ +# Copyright (c) 2025 MASSDRIVER EI (massdriver.space) +# SPDX-License-Identifier: Apache-2.0 + +description: | + Bouffalolab PWM 1 + +compatible: "bflb,pwm-1" + +include: [pwm-controller.yaml, pinctrl-device.yaml, base.yaml] + +properties: + reg: + required: true + + "#pwm-cells": + const: 3 + +pwm-cells: + - channel + - period + - flags diff --git a/dts/bindings/pwm/bflb,pwm-2.yaml b/dts/bindings/pwm/bflb,pwm-2.yaml new file mode 100644 index 000000000000..ee9f9de53dc3 --- /dev/null +++ b/dts/bindings/pwm/bflb,pwm-2.yaml @@ -0,0 +1,22 @@ +# Copyright (c) 2025 MASSDRIVER EI (massdriver.space) +# SPDX-License-Identifier: Apache-2.0 + +description: | + Bouffalolab PWM 2. + The period is common to all channels on this PWM! + +compatible: "bflb,pwm-2" + +include: [pwm-controller.yaml, pinctrl-device.yaml, base.yaml] + +properties: + reg: + required: true + + "#pwm-cells": + const: 3 + +pwm-cells: + - channel + - period + - flags diff --git a/dts/riscv/bflb/bl60x.dtsi b/dts/riscv/bflb/bl60x.dtsi index 69c172e47e27..d6f8429c7987 100644 --- a/dts/riscv/bflb/bl60x.dtsi +++ b/dts/riscv/bflb/bl60x.dtsi @@ -14,6 +14,7 @@ #include #include #include +#include / { #address-cells = <1>; @@ -195,6 +196,16 @@ interrupt-parent = <&clic>; }; + pwm0: pwm@4000a400 { + compatible = "bflb,pwm-1"; + reg = <0x4000a400 0x100>; + #pwm-cells = <3>; + status = "disabled"; + + interrupts = <50 0>; + interrupt-parent = <&clic>; + }; + irx: irx@4000a600 { compatible = "bflb,irx"; reg = <0x4000a600 0x100>; diff --git a/dts/riscv/bflb/bl61x.dtsi b/dts/riscv/bflb/bl61x.dtsi index dc4910a2a73b..be944d11a907 100644 --- a/dts/riscv/bflb/bl61x.dtsi +++ b/dts/riscv/bflb/bl61x.dtsi @@ -13,6 +13,7 @@ #include #include #include +#include / { #address-cells = <1>; @@ -230,6 +231,16 @@ interrupt-parent = <&clic>; }; + pwm0: pwm@2000a400 { + compatible = "bflb,pwm-2"; + reg = <0x2000a400 0x100>; + #pwm-cells = <3>; + status = "disabled"; + + interrupts = <49 1>; + interrupt-parent = <&clic>; + }; + flashctrl: flash-controller@2000b000 { compatible = "bflb,flash-controller"; reg = <0x2000b000 0x1000>; diff --git a/dts/riscv/bflb/bl70x.dtsi b/dts/riscv/bflb/bl70x.dtsi index 87224b47a28a..4956750ea14a 100644 --- a/dts/riscv/bflb/bl70x.dtsi +++ b/dts/riscv/bflb/bl70x.dtsi @@ -13,6 +13,7 @@ #include #include #include +#include / { #address-cells = <1>; @@ -200,6 +201,16 @@ interrupt-parent = <&clic>; }; + pwm0: pwm@4000a400 { + compatible = "bflb,pwm-1"; + reg = <0x4000a400 0x100>; + #pwm-cells = <3>; + status = "disabled"; + + interrupts = <50 0>; + interrupt-parent = <&clic>; + }; + irx: irx@4000a600 { compatible = "bflb,irx"; reg = <0x4000a600 0x100>; From f4bcc3cd55fcb84f6aa053040d7a3918fed19170 Mon Sep 17 00:00:00 2001 From: Camille BAUD Date: Tue, 11 Nov 2025 10:55:27 +0100 Subject: [PATCH 1583/3659] drivers: clock_control: bflb: add PWM elements Adds clock side elements for PWM Signed-off-by: Camille BAUD --- drivers/clock_control/clock_control_bl60x.c | 2 ++ drivers/clock_control/clock_control_bl61x.c | 2 ++ drivers/clock_control/clock_control_bl70x.c | 2 ++ 3 files changed, 6 insertions(+) diff --git a/drivers/clock_control/clock_control_bl60x.c b/drivers/clock_control/clock_control_bl60x.c index d6d53f725a87..4d353e37d94c 100644 --- a/drivers/clock_control/clock_control_bl60x.c +++ b/drivers/clock_control/clock_control_bl60x.c @@ -658,6 +658,8 @@ static void clock_control_bl60x_peripheral_clock_init(void) regval |= (1 << 19); /* enable SPI0 clock routing */ regval |= (1 << 18); + /* enable PWM clock routing */ + regval |= (1 << 20); /* enable DMA clock routing */ regval |= (1 << 12); /* enable IR clock routing */ diff --git a/drivers/clock_control/clock_control_bl61x.c b/drivers/clock_control/clock_control_bl61x.c index 2efd7b5c03ad..07e9ef6af92d 100644 --- a/drivers/clock_control/clock_control_bl61x.c +++ b/drivers/clock_control/clock_control_bl61x.c @@ -1039,6 +1039,8 @@ static void clock_control_bl61x_peripheral_clock_init(void) regval |= (1 << 18); /* enable I2C0 clock routing */ regval |= (1 << 19); + /* enable PWM clock routing */ + regval |= (1 << 20); /* enable I2C1 clock routing */ regval |= (1 << 25); /* enable USB clock routing */ diff --git a/drivers/clock_control/clock_control_bl70x.c b/drivers/clock_control/clock_control_bl70x.c index 40214b422334..3c464c78261f 100644 --- a/drivers/clock_control/clock_control_bl70x.c +++ b/drivers/clock_control/clock_control_bl70x.c @@ -538,6 +538,8 @@ static void clock_control_bl70x_peripheral_clock_init(void) regval |= (1 << 18); /* enable I2C0 clock routing */ regval |= (1 << 19); + /* enable PWM clock routing */ + regval |= (1 << 20); /* enable DMA clock routing */ regval |= (1 << 12); /* enable IR clock routing */ From 396249fdd4ae0a1662f11b5397f54d9c4869953f Mon Sep 17 00:00:00 2001 From: Camille BAUD Date: Tue, 11 Nov 2025 10:56:29 +0100 Subject: [PATCH 1584/3659] drivers: pwm: Add BFLB PWM 1 and 2 Adds BFLB PWMs Signed-off-by: Camille BAUD --- drivers/pwm/CMakeLists.txt | 2 + drivers/pwm/Kconfig | 1 + drivers/pwm/Kconfig.bflb | 16 +++ drivers/pwm/pwm_bflb_1.c | 192 ++++++++++++++++++++++++++++++++++ drivers/pwm/pwm_bflb_2.c | 204 +++++++++++++++++++++++++++++++++++++ 5 files changed, 415 insertions(+) create mode 100644 drivers/pwm/Kconfig.bflb create mode 100644 drivers/pwm/pwm_bflb_1.c create mode 100644 drivers/pwm/pwm_bflb_2.c diff --git a/drivers/pwm/CMakeLists.txt b/drivers/pwm/CMakeLists.txt index b8d59336afd5..6a9038f97e6f 100644 --- a/drivers/pwm/CMakeLists.txt +++ b/drivers/pwm/CMakeLists.txt @@ -13,6 +13,8 @@ zephyr_library_sources_ifdef(CONFIG_MCPWM_ESP32 pwm_mc_esp32.c) zephyr_library_sources_ifdef(CONFIG_PWM_AMBIQ_CTIMER pwm_ambiq_ctimer.c) zephyr_library_sources_ifdef(CONFIG_PWM_AMBIQ_TIMER pwm_ambiq_timer.c) zephyr_library_sources_ifdef(CONFIG_PWM_BBLED_XEC pwm_mchp_xec_bbled.c) +zephyr_library_sources_ifdef(CONFIG_PWM_BFLB_1 pwm_bflb_1.c) +zephyr_library_sources_ifdef(CONFIG_PWM_BFLB_2 pwm_bflb_2.c) zephyr_library_sources_ifdef(CONFIG_PWM_CC13XX_CC26XX_TIMER pwm_cc13xx_cc26xx_timer.c) zephyr_library_sources_ifdef(CONFIG_PWM_CC23X0_TIMER pwm_cc23x0_timer.c) zephyr_library_sources_ifdef(CONFIG_PWM_ENE_KB106X pwm_ene_kb106x.c) diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig index 15d557c1c39f..cf52629e1601 100644 --- a/drivers/pwm/Kconfig +++ b/drivers/pwm/Kconfig @@ -42,6 +42,7 @@ config PWM_EVENT # zephyr-keep-sorted-start source "drivers/pwm/Kconfig.ambiq_timer" source "drivers/pwm/Kconfig.b91" +source "drivers/pwm/Kconfig.bflb" source "drivers/pwm/Kconfig.cc13xx_cc26xx_timer" source "drivers/pwm/Kconfig.cc23x0_timer" source "drivers/pwm/Kconfig.ene" diff --git a/drivers/pwm/Kconfig.bflb b/drivers/pwm/Kconfig.bflb new file mode 100644 index 000000000000..51ddb4400c6f --- /dev/null +++ b/drivers/pwm/Kconfig.bflb @@ -0,0 +1,16 @@ +# Copyright (c) 2025 MASSDRIVER EI (massdriver.space) +# SPDX-License-Identifier: Apache-2.0 + +config PWM_BFLB_1 + bool "BFLB PWM 1 (BL60x, BL70x)" + default y + depends on DT_HAS_BFLB_PWM_1_ENABLED + help + This option enables the PWM driver for Bouffalolab BL60x and BL70x + +config PWM_BFLB_2 + bool "BFLB PWM 2 (BL61x)" + default y + depends on DT_HAS_BFLB_PWM_2_ENABLED + help + This option enables the PWM driver for Bouffalolab BL61x diff --git a/drivers/pwm/pwm_bflb_1.c b/drivers/pwm/pwm_bflb_1.c new file mode 100644 index 000000000000..c3138bb6ec82 --- /dev/null +++ b/drivers/pwm/pwm_bflb_1.c @@ -0,0 +1,192 @@ +/* + * Copyright (c) 2025 MASSDRIVER EI (massdriver.space) + * + * SPDX-License-Identifier: Apache-2.0 + */ +#define DT_DRV_COMPAT bflb_pwm_1 + +#include +#include +#include +#include +#include +#include +LOG_MODULE_REGISTER(pwm_bflb, CONFIG_PWM_LOG_LEVEL); + +#include +#include +#include +#include +#include +#include + +#define PWM_WAIT_TIMEOUT_MS 100 +#define PWM_CH_OFFSET_MUL 0x20 +#define CHANNELS 5 + +struct pwm_bflb_config { + uintptr_t base; + const struct pinctrl_dev_config *pcfg; +}; + +struct pwm_bflb_data { + uint16_t period_cycles[CHANNELS]; +}; + +static int pwm_bflb_get_cycles_per_sec(const struct device *dev, uint32_t ch, uint64_t *cycles) +{ + const struct device *clock_ctrl = DEVICE_DT_GET_ANY(bflb_clock_controller); + uint32_t clk; + int ret; + + ret = clock_control_get_rate(clock_ctrl, (void *)BFLB_CLKID_CLK_BCLK, &clk); + + *cycles = clk; + + LOG_DBG("cycles: %u", clk); + + return ret; +} + +static int pwm_bflb_detrigger(const struct device *dev, uint32_t ch) +{ + const struct pwm_bflb_config *cfg = dev->config; + volatile uint32_t tmp; + + tmp = sys_read32(cfg->base + PWM0_CONFIG_OFFSET + ch * PWM_CH_OFFSET_MUL); + tmp |= PWM_STOP_EN; + sys_write32(tmp, cfg->base + PWM0_CONFIG_OFFSET + ch * PWM_CH_OFFSET_MUL); + + return 0; +} + + +static int pwm_bflb_trigger(const struct device *dev, uint32_t ch) +{ + const struct pwm_bflb_config *cfg = dev->config; + volatile uint32_t tmp; + + tmp = sys_read32(cfg->base + PWM0_CONFIG_OFFSET + ch * PWM_CH_OFFSET_MUL); + tmp &= ~PWM_STOP_EN; + sys_write32(tmp, cfg->base + PWM0_CONFIG_OFFSET + ch * PWM_CH_OFFSET_MUL); + + return 0; +} + +static int pwm_bflb_set_cycles(const struct device *dev, uint32_t ch, uint32_t period_cycles, + uint32_t pulse_cycles, pwm_flags_t flags) +{ + const struct pwm_bflb_config *cfg = dev->config; + struct pwm_bflb_data *data = dev->data; + k_timepoint_t end_timeout = + sys_timepoint_calc(K_MSEC(PWM_WAIT_TIMEOUT_MS)); + volatile uint32_t tmp; + uint32_t pulse, divider; + uint16_t period; + + if (ch >= CHANNELS) { + return -EINVAL; + } + + divider = period_cycles / UINT16_MAX + 1; + + if (divider > UINT16_MAX) { + divider = UINT16_MAX; + } + + period = period_cycles / divider; + + if (data->period_cycles[ch] != period_cycles) { + pwm_bflb_detrigger(dev, ch); + + do { + tmp = sys_read32(cfg->base + PWM0_CONFIG_OFFSET + ch * PWM_CH_OFFSET_MUL); + } while (!(tmp & PWM_STS_TOP) && !sys_timepoint_expired(end_timeout)); + if (sys_timepoint_expired(end_timeout)) { + return -ETIMEDOUT; + } + + tmp = sys_read32(cfg->base + PWM0_CLKDIV_OFFSET + ch * PWM_CH_OFFSET_MUL); + tmp &= ~PWM_CLK_DIV_MASK; + tmp |= divider << PWM_CLK_DIV_SHIFT; + sys_write32(tmp, cfg->base + PWM0_CLKDIV_OFFSET + ch * PWM_CH_OFFSET_MUL); + + tmp = sys_read32(cfg->base + PWM0_PERIOD_OFFSET + ch * PWM_CH_OFFSET_MUL); + tmp &= ~PWM_PERIOD_MASK; + tmp |= (uint32_t)period << PWM_PERIOD_SHIFT; + sys_write32(tmp, cfg->base + PWM0_PERIOD_OFFSET + ch * PWM_CH_OFFSET_MUL); + } + + pulse = pulse_cycles / divider; + + LOG_DBG("divider: %u period: %u pulse: %u", divider, period, pulse); + + tmp = sys_read32(cfg->base + PWM0_THRE1_OFFSET + ch * PWM_CH_OFFSET_MUL); + tmp &= ~PWM_THRE1_MASK; + sys_write32(tmp, cfg->base + PWM0_THRE1_OFFSET + ch * PWM_CH_OFFSET_MUL); + + tmp = sys_read32(cfg->base + PWM0_THRE2_OFFSET + ch * PWM_CH_OFFSET_MUL); + tmp &= ~PWM_THRE2_MASK; + tmp |= pulse; + sys_write32(tmp, cfg->base + PWM0_THRE2_OFFSET + ch * PWM_CH_OFFSET_MUL); + + tmp = sys_read32(cfg->base + PWM0_CONFIG_OFFSET + ch * PWM_CH_OFFSET_MUL); + if (flags & PWM_POLARITY_INVERTED) { + tmp |= PWM_OUT_INV; + } else { + tmp &= ~PWM_OUT_INV; + } + /* Dont wait for period end */ + tmp &= ~PWM_STOP_MODE; + tmp &= ~PWM_REG_CLK_SEL_MASK; + /* Use BCLK */ + tmp |= 1U << PWM_REG_CLK_SEL_SHIFT; + sys_write32(tmp, cfg->base + PWM0_CONFIG_OFFSET + ch * PWM_CH_OFFSET_MUL); + + if (data->period_cycles[ch] != period_cycles) { + pwm_bflb_trigger(dev, ch); + + do { + tmp = sys_read32(cfg->base + PWM0_CONFIG_OFFSET + ch * PWM_CH_OFFSET_MUL); + } while (tmp & PWM_STS_TOP && !sys_timepoint_expired(end_timeout)); + if (sys_timepoint_expired(end_timeout)) { + return -ETIMEDOUT; + } + data->period_cycles[ch] = period_cycles; + } + return 0; +} + +static DEVICE_API(pwm, pwm_bflb_driver_api) = { + .get_cycles_per_sec = pwm_bflb_get_cycles_per_sec, + .set_cycles = pwm_bflb_set_cycles, +}; + +static int pwm_bflb_init(const struct device *dev) +{ + const struct pwm_bflb_config *cfg = dev->config; + int err; + + err = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT); + if (err) { + LOG_ERR("Failed to configure pins for PWM. err=%d", err); + return err; + } + + return 0; +} + +#define PWM_BFLB_INIT(idx) \ + \ + PINCTRL_DT_INST_DEFINE(idx); \ + static const struct pwm_bflb_config pwm_bflb_config_##idx = { \ + .base = DT_INST_REG_ADDR(idx), \ + .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(idx), \ + }; \ + static struct pwm_bflb_data pwm_bflb_data_##idx = { 0 }; \ + \ + DEVICE_DT_INST_DEFINE(idx, pwm_bflb_init, NULL, \ + &pwm_bflb_data_##idx, &pwm_bflb_config_##idx, POST_KERNEL, \ + CONFIG_PWM_INIT_PRIORITY, &pwm_bflb_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(PWM_BFLB_INIT); diff --git a/drivers/pwm/pwm_bflb_2.c b/drivers/pwm/pwm_bflb_2.c new file mode 100644 index 000000000000..c3d95ea2a555 --- /dev/null +++ b/drivers/pwm/pwm_bflb_2.c @@ -0,0 +1,204 @@ +/* + * Copyright (c) 2025 MASSDRIVER EI (massdriver.space) + * + * SPDX-License-Identifier: Apache-2.0 + */ +#define DT_DRV_COMPAT bflb_pwm_2 + +#include +#include +#include +#include +#include +#include +LOG_MODULE_REGISTER(pwm_bflb, CONFIG_PWM_LOG_LEVEL); + +#include +#include +#include +#include +#include +#include + +#define PWM_WAIT_TIMEOUT_MS 100 +#define PWM_CH_OFFSET_MUL 4 +#define PWM_CH_SHIFT_MUL 4 +#define PWM_CH_POLARITY_MUL 2 +#define CHANNELS 4 + +struct pwm_bflb_config { + uintptr_t base; + const struct pinctrl_dev_config *pcfg; +}; + +struct pwm_bflb_data { + uint32_t period_cycles; +}; + +static int pwm_bflb_get_cycles_per_sec(const struct device *dev, uint32_t ch, uint64_t *cycles) +{ + const struct device *clock_ctrl = DEVICE_DT_GET_ANY(bflb_clock_controller); + uint32_t clk; + int ret; + + ret = clock_control_get_rate(clock_ctrl, (void *)BFLB_CLKID_CLK_BCLK, &clk); + + *cycles = clk / 2; + + LOG_DBG("cycles: %u", clk); + + return ret; +} + +static int pwm_bflb_detrigger(const struct device *dev) +{ + const struct pwm_bflb_config *cfg = dev->config; + volatile uint32_t tmp; + + tmp = sys_read32(cfg->base + PWM_MC0_CONFIG0_OFFSET); + tmp |= PWM_STOP_EN; + sys_write32(tmp, cfg->base + PWM_MC0_CONFIG0_OFFSET); + + return 0; +} + + +static int pwm_bflb_trigger(const struct device *dev) +{ + const struct pwm_bflb_config *cfg = dev->config; + volatile uint32_t tmp; + + tmp = sys_read32(cfg->base + PWM_MC0_CONFIG0_OFFSET); + tmp &= ~PWM_STOP_EN; + sys_write32(tmp, cfg->base + PWM_MC0_CONFIG0_OFFSET); + + return 0; +} + +static int pwm_bflb_set_cycles(const struct device *dev, uint32_t ch, uint32_t period_cycles, + uint32_t pulse_cycles, pwm_flags_t flags) +{ + const struct pwm_bflb_config *cfg = dev->config; + struct pwm_bflb_data *data = dev->data; + k_timepoint_t end_timeout = + sys_timepoint_calc(K_MSEC(PWM_WAIT_TIMEOUT_MS)); + volatile uint32_t tmp; + uint32_t pulse, divider; + uint16_t period; + + if (ch >= CHANNELS) { + return -EINVAL; + } + + divider = period_cycles / UINT16_MAX + 1; + + if (divider > UINT16_MAX) { + divider = UINT16_MAX; + } + + period = period_cycles / divider; + + if (period_cycles != data->period_cycles) { + LOG_INF("Changing global period!"); + pwm_bflb_detrigger(dev); + + do { + tmp = sys_read32(cfg->base + PWM_MC0_CONFIG0_OFFSET); + } while (!(tmp & PWM_STS_STOP) && !sys_timepoint_expired(end_timeout)); + if (sys_timepoint_expired(end_timeout)) { + return -ETIMEDOUT; + } + + tmp = sys_read32(cfg->base + PWM_MC0_CONFIG0_OFFSET); + tmp &= ~PWM_CLK_DIV_MASK; + tmp |= (uint32_t)divider << PWM_CLK_DIV_SHIFT; + sys_write32(tmp, cfg->base + PWM_MC0_CONFIG0_OFFSET); + + tmp = sys_read32(cfg->base + PWM_MC0_PERIOD_OFFSET); + tmp &= ~PWM_PERIOD_MASK; + tmp |= (uint32_t)period << PWM_PERIOD_SHIFT; + sys_write32(tmp, cfg->base + PWM_MC0_PERIOD_OFFSET); + } + + pulse = pulse_cycles / divider; + + LOG_DBG("divider: %d period: %d pulse: %d", divider, period, pulse); + + tmp = pulse << PWM_CH0_THREH_SHIFT; + sys_write32(tmp, cfg->base + PWM_MC0_CH0_THRE_OFFSET + ch * PWM_CH_OFFSET_MUL); + + tmp = sys_read32(cfg->base + PWM_MC0_CONFIG1_OFFSET); + tmp |= PWM_CH0_PEN << (PWM_CH_SHIFT_MUL * ch); + tmp |= PWM_CH0_NEN << (PWM_CH_SHIFT_MUL * ch); + if (flags & PWM_POLARITY_INVERTED) { + tmp &= ~(PWM_CH0_PPL << (PWM_CH_POLARITY_MUL * ch)); + tmp &= ~(PWM_CH0_NPL << (PWM_CH_POLARITY_MUL * ch)); + } else { + tmp |= PWM_CH0_PPL << (PWM_CH_POLARITY_MUL * ch); + tmp |= PWM_CH0_NPL << (PWM_CH_POLARITY_MUL * ch); + } + sys_write32(tmp, cfg->base + PWM_MC0_CONFIG1_OFFSET); + + if (period_cycles != data->period_cycles) { + pwm_bflb_trigger(dev); + + do { + tmp = sys_read32(cfg->base + PWM_MC0_CONFIG0_OFFSET); + } while (tmp & PWM_STS_STOP && !sys_timepoint_expired(end_timeout)); + if (sys_timepoint_expired(end_timeout)) { + return -ETIMEDOUT; + } + data->period_cycles = period_cycles; + } + + return 0; +} + +static DEVICE_API(pwm, pwm_bflb_driver_api) = { + .get_cycles_per_sec = pwm_bflb_get_cycles_per_sec, + .set_cycles = pwm_bflb_set_cycles, +}; + +static int pwm_bflb_init(const struct device *dev) +{ + const struct pwm_bflb_config *cfg = dev->config; + int err; + volatile uint32_t tmp; + + err = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT); + if (err) { + LOG_ERR("Failed to configure pins for PWM. err=%d", err); + return err; + } + + tmp = sys_read32(GLB_BASE + GLB_PWM_CFG0_OFFSET); + tmp &= GLB_REG_PWM1_IO_SEL_UMSK; + sys_write32(tmp, GLB_BASE + GLB_PWM_CFG0_OFFSET); + + tmp = sys_read32(cfg->base + PWM_MC0_CONFIG0_OFFSET); + tmp &= ~PWM_REG_CLK_SEL_MASK; + /* Use BCLK */ + tmp |= 1U << PWM_REG_CLK_SEL_SHIFT; + /* Dont wait for period end */ + tmp &= ~PWM_STOP_MODE; + sys_write32(tmp, cfg->base + PWM_MC0_CONFIG0_OFFSET); + + return 0; +} + +#define PWM_BFLB_INIT(idx) \ + \ + PINCTRL_DT_INST_DEFINE(idx); \ + static const struct pwm_bflb_config pwm_bflb_config_##idx = { \ + .base = DT_INST_REG_ADDR(idx), \ + .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(idx), \ + }; \ + static struct pwm_bflb_data pwm_bflb_data_##idx = { \ + .period_cycles = 0, \ + }; \ + \ + DEVICE_DT_INST_DEFINE(idx, pwm_bflb_init, NULL, \ + &pwm_bflb_data_##idx, &pwm_bflb_config_##idx, POST_KERNEL, \ + CONFIG_PWM_INIT_PRIORITY, &pwm_bflb_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(PWM_BFLB_INIT); From cafc6a9c73e25811336f1f5ca12e591a29de0d83 Mon Sep 17 00:00:00 2001 From: Camille BAUD Date: Tue, 11 Nov 2025 10:59:31 +0100 Subject: [PATCH 1585/3659] boards: bflb: update ai_m62_12f for PWM Adds PWM nodes and samples Signed-off-by: Camille BAUD --- .../ai_m62_12f_kit-pinctrl.dtsi | 9 ++++++ .../ai_m62_12f_kit/ai_m62_12f_kit.dts | 31 +++++++++++++++++++ .../ai_m62_12f_kit/ai_m62_12f_kit.yaml | 1 + .../blinky_pwm/boards/ai_m62_12f_kit.overlay | 21 +++++++++++++ .../fade_led/boards/ai_m62_12f_kit.overlay | 21 +++++++++++++ 5 files changed, 83 insertions(+) create mode 100644 samples/basic/blinky_pwm/boards/ai_m62_12f_kit.overlay create mode 100644 samples/basic/fade_led/boards/ai_m62_12f_kit.overlay diff --git a/boards/aithinker/ai_m62_12f_kit/ai_m62_12f_kit-pinctrl.dtsi b/boards/aithinker/ai_m62_12f_kit/ai_m62_12f_kit-pinctrl.dtsi index 285589db170f..2ff265f2e2c5 100644 --- a/boards/aithinker/ai_m62_12f_kit/ai_m62_12f_kit-pinctrl.dtsi +++ b/boards/aithinker/ai_m62_12f_kit/ai_m62_12f_kit-pinctrl.dtsi @@ -23,4 +23,13 @@ input-schmitt-enable; }; }; + + white_pwm_pinctrl: white_pwm_pinctrl { + group1 { + pinmux = ; + bias-pull-up; + input-schmitt-enable; + drive-strength = <1>; + }; + }; }; diff --git a/boards/aithinker/ai_m62_12f_kit/ai_m62_12f_kit.dts b/boards/aithinker/ai_m62_12f_kit/ai_m62_12f_kit.dts index 88f17e14053f..fc3a1c707233 100644 --- a/boards/aithinker/ai_m62_12f_kit/ai_m62_12f_kit.dts +++ b/boards/aithinker/ai_m62_12f_kit/ai_m62_12f_kit.dts @@ -14,6 +14,7 @@ aliases { led0 = &blue_led; + pwm-led0 = &white_pwm_led; sw0 = &button_0; }; @@ -46,6 +47,36 @@ }; }; + pwmleds: pwmleds { + compatible = "pwm-leds"; + status = "disabled"; + + blue_pwm_led: led_pwm_0 { + pwms = <&pwm0 0 PWM_MSEC(1) PWM_POLARITY_NORMAL>; + label = "Blue - LED0 PWM"; + }; + + green_pwm_led: led_pwm_1 { + pwms = <&pwm0 2 PWM_MSEC(1) PWM_POLARITY_NORMAL>; + label = "Green - LED1 PWM"; + }; + + red_pwm_led: led_pwm_2 { + pwms = <&pwm0 1 PWM_MSEC(1) PWM_POLARITY_NORMAL>; + label = "Red - LED2 PWM"; + }; + + white_pwm_led: led_pwm_3 { + pwms = <&pwm0 1 PWM_MSEC(1) PWM_POLARITY_NORMAL>; + label = "White - LED3 PWM"; + }; + + warmwhite_pwm_led: led_pwm_4 { + pwms = <&pwm0 3 PWM_MSEC(1) PWM_POLARITY_NORMAL>; + label = "Warm White - LED4 PWM"; + }; + }; + buttons { compatible = "gpio-keys"; diff --git a/boards/aithinker/ai_m62_12f_kit/ai_m62_12f_kit.yaml b/boards/aithinker/ai_m62_12f_kit/ai_m62_12f_kit.yaml index 1af3071bc36d..9735f959fd14 100644 --- a/boards/aithinker/ai_m62_12f_kit/ai_m62_12f_kit.yaml +++ b/boards/aithinker/ai_m62_12f_kit/ai_m62_12f_kit.yaml @@ -22,4 +22,5 @@ supported: - spi - flash - input + - pwm vendor: bflb diff --git a/samples/basic/blinky_pwm/boards/ai_m62_12f_kit.overlay b/samples/basic/blinky_pwm/boards/ai_m62_12f_kit.overlay new file mode 100644 index 000000000000..811d1d37834a --- /dev/null +++ b/samples/basic/blinky_pwm/boards/ai_m62_12f_kit.overlay @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2025 MASSDRIVER EI (massdriver.space) + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + leds { + status = "disabled"; + }; +}; + +&pwmleds { + status = "okay"; +}; + +&pwm0 { + status = "okay"; + pinctrl-0 = <&white_pwm_pinctrl>; + pinctrl-names = "default"; +}; diff --git a/samples/basic/fade_led/boards/ai_m62_12f_kit.overlay b/samples/basic/fade_led/boards/ai_m62_12f_kit.overlay new file mode 100644 index 000000000000..811d1d37834a --- /dev/null +++ b/samples/basic/fade_led/boards/ai_m62_12f_kit.overlay @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2025 MASSDRIVER EI (massdriver.space) + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + leds { + status = "disabled"; + }; +}; + +&pwmleds { + status = "okay"; +}; + +&pwm0 { + status = "okay"; + pinctrl-0 = <&white_pwm_pinctrl>; + pinctrl-names = "default"; +}; From 12aa44edbdbbe1af84403e08caf22e004bd82b2e Mon Sep 17 00:00:00 2001 From: Camille BAUD Date: Tue, 11 Nov 2025 10:59:55 +0100 Subject: [PATCH 1586/3659] boards: bflb: update ai_wb2_12f for PWM Adds PWM nodes and samples Signed-off-by: Camille BAUD --- .../ai_wb2_12f_kit-pinctrl.dtsi | 9 ++++++++ .../ai_wb2_12f_kit/ai_wb2_12f_kit.dts | 21 +++++++++++++++++++ .../ai_wb2_12f_kit/ai_wb2_12f_kit.yaml | 1 + .../blinky_pwm/boards/ai_wb2_12f_kit.overlay | 21 +++++++++++++++++++ .../fade_led/boards/ai_wb2_12f_kit.overlay | 21 +++++++++++++++++++ 5 files changed, 73 insertions(+) create mode 100644 samples/basic/blinky_pwm/boards/ai_wb2_12f_kit.overlay create mode 100644 samples/basic/fade_led/boards/ai_wb2_12f_kit.overlay diff --git a/boards/aithinker/ai_wb2_12f_kit/ai_wb2_12f_kit-pinctrl.dtsi b/boards/aithinker/ai_wb2_12f_kit/ai_wb2_12f_kit-pinctrl.dtsi index a60c6948db4f..acf2c447b815 100644 --- a/boards/aithinker/ai_wb2_12f_kit/ai_wb2_12f_kit-pinctrl.dtsi +++ b/boards/aithinker/ai_wb2_12f_kit/ai_wb2_12f_kit-pinctrl.dtsi @@ -23,4 +23,13 @@ input-schmitt-enable; }; }; + + blue_pwm_pinctrl: blue_pwm_pinctrl { + group1 { + pinmux = ; + bias-pull-up; + input-schmitt-enable; + drive-strength = <1>; + }; + }; }; diff --git a/boards/aithinker/ai_wb2_12f_kit/ai_wb2_12f_kit.dts b/boards/aithinker/ai_wb2_12f_kit/ai_wb2_12f_kit.dts index 8c41dca95807..51ee647a2f4d 100644 --- a/boards/aithinker/ai_wb2_12f_kit/ai_wb2_12f_kit.dts +++ b/boards/aithinker/ai_wb2_12f_kit/ai_wb2_12f_kit.dts @@ -14,6 +14,7 @@ aliases { led0 = &blue_led; + pwm-led0 = &blue_pwm_led; sw0 = &button_0; }; @@ -36,6 +37,26 @@ }; }; + pwmleds: pwmleds { + compatible = "pwm-leds"; + status = "disabled"; + + blue_pwm_led: led_pwm_0 { + pwms = <&pwm0 3 PWM_MSEC(1) PWM_POLARITY_NORMAL>; + label = "Blue - LED0 PWM"; + }; + + green_pwm_led: led_pwm_1 { + pwms = <&pwm0 2 PWM_MSEC(1) PWM_POLARITY_NORMAL>; + label = "Green - LED1 PWM"; + }; + + red_pwm_led: led_pwm_2 { + pwms = <&pwm0 4 PWM_MSEC(1) PWM_POLARITY_NORMAL>; + label = "Red - LED2 PWM"; + }; + }; + buttons { compatible = "gpio-keys"; diff --git a/boards/aithinker/ai_wb2_12f_kit/ai_wb2_12f_kit.yaml b/boards/aithinker/ai_wb2_12f_kit/ai_wb2_12f_kit.yaml index 337bffb02e02..77cf6f189871 100644 --- a/boards/aithinker/ai_wb2_12f_kit/ai_wb2_12f_kit.yaml +++ b/boards/aithinker/ai_wb2_12f_kit/ai_wb2_12f_kit.yaml @@ -22,4 +22,5 @@ supported: - spi - flash - input + - pwm vendor: bflb diff --git a/samples/basic/blinky_pwm/boards/ai_wb2_12f_kit.overlay b/samples/basic/blinky_pwm/boards/ai_wb2_12f_kit.overlay new file mode 100644 index 000000000000..d04faf4f4ed3 --- /dev/null +++ b/samples/basic/blinky_pwm/boards/ai_wb2_12f_kit.overlay @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2025 MASSDRIVER EI (massdriver.space) + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + leds { + status = "disabled"; + }; +}; + +&pwmleds { + status = "okay"; +}; + +&pwm0 { + status = "okay"; + pinctrl-0 = <&blue_pwm_pinctrl>; + pinctrl-names = "default"; +}; diff --git a/samples/basic/fade_led/boards/ai_wb2_12f_kit.overlay b/samples/basic/fade_led/boards/ai_wb2_12f_kit.overlay new file mode 100644 index 000000000000..d04faf4f4ed3 --- /dev/null +++ b/samples/basic/fade_led/boards/ai_wb2_12f_kit.overlay @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2025 MASSDRIVER EI (massdriver.space) + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + leds { + status = "disabled"; + }; +}; + +&pwmleds { + status = "okay"; +}; + +&pwm0 { + status = "okay"; + pinctrl-0 = <&blue_pwm_pinctrl>; + pinctrl-names = "default"; +}; From de939ab796ab9fcecb0dd140092066fe083b8dbf Mon Sep 17 00:00:00 2001 From: Camille BAUD Date: Mon, 12 Jan 2026 12:33:51 +0100 Subject: [PATCH 1587/3659] boards: bflb: update ai_m61_32s for PWM Adds PWM nodes and samples Signed-off-by: Camille BAUD --- .../ai_m61_32s_kit-pinctrl.dtsi | 11 ++++++- .../ai_m61_32s_kit/ai_m61_32s_kit.dts | 31 +++++++++++++++++++ .../ai_m61_32s_kit/ai_m61_32s_kit.yaml | 1 + .../fade_led/boards/ai_m61_32s_kit.overlay | 21 +++++++++++++ 4 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 samples/basic/fade_led/boards/ai_m61_32s_kit.overlay diff --git a/boards/aithinker/ai_m61_32s_kit/ai_m61_32s_kit-pinctrl.dtsi b/boards/aithinker/ai_m61_32s_kit/ai_m61_32s_kit-pinctrl.dtsi index cfcf3670ef47..f9e75267840c 100644 --- a/boards/aithinker/ai_m61_32s_kit/ai_m61_32s_kit-pinctrl.dtsi +++ b/boards/aithinker/ai_m61_32s_kit/ai_m61_32s_kit-pinctrl.dtsi @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025 MASSDRIVER EI (massdriver.space) + * Copyright (c) 2025-2026 MASSDRIVER EI (massdriver.space) * * SPDX-License-Identifier: Apache-2.0 */ @@ -23,4 +23,13 @@ input-schmitt-enable; }; }; + + blue_pwm_pinctrl: pwm_pinctrl { + group1 { + pinmux = ; + bias-pull-up; + input-schmitt-enable; + drive-strength = <1>; + }; + }; }; diff --git a/boards/aithinker/ai_m61_32s_kit/ai_m61_32s_kit.dts b/boards/aithinker/ai_m61_32s_kit/ai_m61_32s_kit.dts index 7a3af709ba5f..080f7ec40f88 100644 --- a/boards/aithinker/ai_m61_32s_kit/ai_m61_32s_kit.dts +++ b/boards/aithinker/ai_m61_32s_kit/ai_m61_32s_kit.dts @@ -15,6 +15,7 @@ aliases { led0 = &blue_led; sw0 = &button_0; + pwm-led0 = &blue_pwm_led; }; leds { @@ -46,6 +47,36 @@ }; }; + pwmleds: pwmleds { + compatible = "pwm-leds"; + status = "disabled"; + + blue_pwm_led: led_pwm_0 { + pwms = <&pwm0 3 PWM_MSEC(1) PWM_POLARITY_NORMAL>; + label = "Blue - LED0 PWM"; + }; + + green_pwm_led: led_pwm_1 { + pwms = <&pwm0 2 PWM_MSEC(1) PWM_POLARITY_NORMAL>; + label = "Green - LED1 PWM"; + }; + + red_pwm_led: led_pwm_2 { + pwms = <&pwm0 0 PWM_MSEC(1) PWM_POLARITY_NORMAL>; + label = "Red - LED2 PWM"; + }; + + white_pwm_led: led_pwm_3 { + pwms = <&pwm0 1 PWM_MSEC(1) PWM_POLARITY_NORMAL>; + label = "White - LED3 PWM"; + }; + + warmwhite_pwm_led: led_pwm_4 { + pwms = <&pwm0 3 PWM_MSEC(1) PWM_POLARITY_NORMAL>; + label = "Warm White - LED4 PWM"; + }; + }; + buttons { compatible = "gpio-keys"; diff --git a/boards/aithinker/ai_m61_32s_kit/ai_m61_32s_kit.yaml b/boards/aithinker/ai_m61_32s_kit/ai_m61_32s_kit.yaml index a8214e0cfbdb..cb93dc1b3e1e 100644 --- a/boards/aithinker/ai_m61_32s_kit/ai_m61_32s_kit.yaml +++ b/boards/aithinker/ai_m61_32s_kit/ai_m61_32s_kit.yaml @@ -21,4 +21,5 @@ supported: - i2c - spi - flash + - pwm vendor: bflb diff --git a/samples/basic/fade_led/boards/ai_m61_32s_kit.overlay b/samples/basic/fade_led/boards/ai_m61_32s_kit.overlay new file mode 100644 index 000000000000..345b037a873f --- /dev/null +++ b/samples/basic/fade_led/boards/ai_m61_32s_kit.overlay @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2026 MASSDRIVER EI (massdriver.space) + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + leds { + status = "disabled"; + }; +}; + +&pwmleds { + status = "okay"; +}; + +&pwm0 { + status = "okay"; + pinctrl-0 = <&blue_pwm_pinctrl>; + pinctrl-names = "default"; +}; From 94f08de684a498c54f1da3ebd18091e7d38a9704 Mon Sep 17 00:00:00 2001 From: Hau Ho Date: Tue, 25 Nov 2025 13:33:27 +0700 Subject: [PATCH 1588/3659] dts: renesas: Add GPIO interrupt for RX261 SoC Add GPIO interrupt for RX261 SoC Signed-off-by: Hau Ho --- dts/rx/renesas/rx261-common.dtsi | 144 +++++++++++++++++++++++++++++++ 1 file changed, 144 insertions(+) diff --git a/dts/rx/renesas/rx261-common.dtsi b/dts/rx/renesas/rx261-common.dtsi index 91c14addf9f2..e7e95e019d46 100644 --- a/dts/rx/renesas/rx261-common.dtsi +++ b/dts/rx/renesas/rx261-common.dtsi @@ -167,6 +167,86 @@ status = "okay"; }; + port_irq0: external-interrupt@87500 { + compatible = "renesas,rx-external-interrupt"; + reg = <0x00087500 0x1>; + interrupts = <64 12>; + channel = <0>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq1: external-interrupt@87501 { + compatible = "renesas,rx-external-interrupt"; + reg = <0x00087501 0x1>; + interrupts = <65 12>; + channel = <1>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq2: external-interrupt@87502 { + compatible = "renesas,rx-external-interrupt"; + reg = <0x00087502 0x1>; + interrupts = <66 12>; + channel = <2>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq3: external-interrupt@87503 { + compatible = "renesas,rx-external-interrupt"; + reg = <0x00087503 0x1>; + interrupts = <67 12>; + channel = <3>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq4: external-interrupt@87504 { + compatible = "renesas,rx-external-interrupt"; + reg = <0x00087504 0x1>; + interrupts = <68 12>; + channel = <4>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq5: external-interrupt@87505 { + compatible = "renesas,rx-external-interrupt"; + reg = <0x00087505 0x1>; + interrupts = <69 12>; + channel = <5>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq6: external-interrupt@87506 { + compatible = "renesas,rx-external-interrupt"; + reg = <0x00087506 0x1>; + interrupts = <70 12>; + channel = <6>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + + port_irq7: external-interrupt@87507 { + compatible = "renesas,rx-external-interrupt"; + reg = <0x00087507 0x1>; + interrupts = <71 12>; + channel = <7>; + renesas,sample-clock-div = <64>; + #port-irq-cells = <0>; + status = "disabled"; + }; + ioport0: gpio@8c000 { compatible = "renesas,rx-gpio"; gpio-controller; @@ -198,6 +278,20 @@ <0x0008C0C1 0x01>; reg-names = "PDR", "PODR", "PIDR", "PMR", "ODR0", "ODR1", "PCR"; pinmux = <&pinmux1>; + port-irqs = <&port_irq2 &port_irq3 &port_irq4 + &port_irq5 &port_irq6 &port_irq7>; + port-irq-names = "port-irq2", + "port-irq3", + "port-irq4", + "port-irq5", + "port-irq6", + "port-irq7"; + port-irq2-pins = <2>; + port-irq3-pins = <3>; + port-irq4-pins = <4>; + port-irq5-pins = <5>; + port-irq6-pins = <6>; + port-irq7-pins = <7>; status = "disabled"; }; @@ -234,6 +328,17 @@ <0x0008C0C3 0x01>; reg-names = "PDR", "PODR", "PIDR", "PMR", "ODR0", "ODR1", "PCR"; pinmux = <&pinmux3>; + port-irqs = <&port_irq0 &port_irq1 &port_irq2 &port_irq3 &port_irq4>; + port-irq-names = "port-irq0", + "port-irq1", + "port-irq2", + "port-irq3", + "port-irq4"; + port-irq0-pins = <0>; + port-irq1-pins = <1>; + port-irq2-pins = <2>; + port-irq3-pins = <3>; + port-irq4-pins = <4>; status = "disabled"; }; @@ -286,6 +391,11 @@ <0x0008C0CA 0x01>; reg-names = "PDR", "PODR", "PIDR", "PMR", "ODR0", "ODR1", "PCR"; pinmux = <&pinmuxa>; + port-irqs = <&port_irq5 &port_irq6>; + port-irq-names = "port-irq5", + "port-irq6"; + port-irq5-pins = <4>; + port-irq6-pins = <3>; status = "disabled"; }; @@ -304,6 +414,9 @@ <0x0008C0CB 0x01>; reg-names = "PDR", "PODR", "PIDR", "PMR", "ODR0", "ODR1", "PCR"; pinmux = <&pinmuxb>; + port-irqs = <&port_irq4>; + port-irq-names = "port-irq4"; + port-irq4-pins = <1>; status = "disabled"; }; @@ -339,6 +452,25 @@ <0x0008C0CD 0x01>; reg-names = "PDR", "PODR", "PIDR", "PMR", "ODR0", "PCR"; pinmux = <&pinmuxd>; + port-irqs = <&port_irq0 &port_irq1 &port_irq2 + &port_irq3 &port_irq4 &port_irq5 + &port_irq6 &port_irq7>; + port-irq-names = "port-irq0", + "port-irq1", + "port-irq2", + "port-irq3", + "port-irq4", + "port-irq5", + "port-irq6", + "port-irq7"; + port-irq0-pins = <0>; + port-irq1-pins = <1>; + port-irq2-pins = <2>; + port-irq3-pins = <3>; + port-irq4-pins = <4>; + port-irq5-pins = <5>; + port-irq6-pins = <6>; + port-irq7-pins = <7>; status = "okay"; }; @@ -356,6 +488,13 @@ <0x0008C0CE 0x01>; reg-names = "PDR", "PODR", "PIDR", "PMR", "ODR0", "PCR"; pinmux = <&pinmuxe>; + port-irqs = <&port_irq5 &port_irq6 &port_irq7>; + port-irq-names = "port-irq5", + "port-irq6", + "port-irq7"; + port-irq5-pins = <5>; + port-irq6-pins = <6>; + port-irq7-pins = <2 7>; status = "disabled"; }; @@ -372,6 +511,11 @@ <0x0008C0D1 0x01>; reg-names = "PDR", "PODR", "PIDR", "PMR", "PCR"; pinmux = <&pinmuxh>; + port-irqs = <&port_irq0 &port_irq1>; + port-irq-names = "port-irq0", + "port-irq1"; + port-irq0-pins = <1>; + port-irq1-pins = <2>; status = "disabled"; }; From 33bfffc07ae4625bf2bd597db06cfcda511466e7 Mon Sep 17 00:00:00 2001 From: Hau Ho Date: Tue, 25 Nov 2025 13:43:08 +0700 Subject: [PATCH 1589/3659] boards: renesas: Add GPIO interrupt support for EK-RX261 board Add GPIO interrupt support for EK-RX261 board Signed-off-by: Hau Ho --- boards/renesas/ek_rx261/ek_rx261.dts | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/boards/renesas/ek_rx261/ek_rx261.dts b/boards/renesas/ek_rx261/ek_rx261.dts index 6905aed82746..e7841dd2dfc3 100644 --- a/boards/renesas/ek_rx261/ek_rx261.dts +++ b/boards/renesas/ek_rx261/ek_rx261.dts @@ -10,6 +10,7 @@ #include #include "ek_rx261-pinctrl.dtsi" #include +#include / { model = "Renesas EK-RX261 KIT"; @@ -42,10 +43,29 @@ }; }; + buttons { + compatible = "gpio-keys"; + + sw1: button1 { + label = "Key"; + gpios = <&ioportd 0 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + zephyr,code = ; + }; + + sw2: button2 { + label = "Key"; + gpios = <&ioport3 2 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + zephyr,code = ; + }; + }; + aliases { led0 = &led1; led1 = &led2; led2 = &led3; + + sw0 = &sw1; + sw1 = &sw2; }; }; @@ -130,3 +150,11 @@ pinctrl-names = "default"; status = "okay"; }; + +&port_irq0 { + status = "okay"; +}; + +&port_irq1 { + status = "okay"; +}; From 44c64b007c9fb99c5911769bc113a7e345fc1eba Mon Sep 17 00:00:00 2001 From: Hau Ho Date: Tue, 25 Nov 2025 13:43:33 +0700 Subject: [PATCH 1590/3659] boards: renesas: Add GPIO interrupt support for FPB-RX261 board Add GPIO interrupt support for EK-RX261 board Signed-off-by: Hau Ho --- boards/renesas/fpb_rx261/fpb_rx261.dts | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/boards/renesas/fpb_rx261/fpb_rx261.dts b/boards/renesas/fpb_rx261/fpb_rx261.dts index 76e5d9c936de..d735a73f4585 100644 --- a/boards/renesas/fpb_rx261/fpb_rx261.dts +++ b/boards/renesas/fpb_rx261/fpb_rx261.dts @@ -38,9 +38,21 @@ }; }; + buttons { + compatible = "gpio-keys"; + + sw1: button1 { + label = "Key"; + gpios = <&ioport3 2 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + zephyr,code = ; + }; + }; + aliases { led0 = &led1; led1 = &led2; + + sw0 = &sw1; }; }; @@ -120,3 +132,11 @@ pinctrl-names = "default"; status = "okay"; }; + +&port_irq1 { + status = "okay"; +}; + +&port_irq2 { + status = "okay"; +}; From 5c0bf4ee7af7ae43f2d9019d9c07ef81eb022c16 Mon Sep 17 00:00:00 2001 From: Hau Ho Date: Tue, 25 Nov 2025 13:45:20 +0700 Subject: [PATCH 1591/3659] tests: drivers: gpio: Add overlay and config file for gpio tests Add overlay and config file for EK-RX261 and FPB-RX261 Signed-off-by: Hau Ho --- .../gpio/gpio_basic_api/boards/ek_rx261.conf | 1 + .../gpio_basic_api/boards/ek_rx261.overlay | 22 +++++++++++++++++++ .../gpio/gpio_basic_api/boards/fpb_rx261.conf | 1 + .../gpio_basic_api/boards/fpb_rx261.overlay | 22 +++++++++++++++++++ 4 files changed, 46 insertions(+) create mode 100644 tests/drivers/gpio/gpio_basic_api/boards/ek_rx261.conf create mode 100644 tests/drivers/gpio/gpio_basic_api/boards/ek_rx261.overlay create mode 100644 tests/drivers/gpio/gpio_basic_api/boards/fpb_rx261.conf create mode 100644 tests/drivers/gpio/gpio_basic_api/boards/fpb_rx261.overlay diff --git a/tests/drivers/gpio/gpio_basic_api/boards/ek_rx261.conf b/tests/drivers/gpio/gpio_basic_api/boards/ek_rx261.conf new file mode 100644 index 000000000000..15e08fba7938 --- /dev/null +++ b/tests/drivers/gpio/gpio_basic_api/boards/ek_rx261.conf @@ -0,0 +1 @@ +CONFIG_READ_DELAY=10 diff --git a/tests/drivers/gpio/gpio_basic_api/boards/ek_rx261.overlay b/tests/drivers/gpio/gpio_basic_api/boards/ek_rx261.overlay new file mode 100644 index 000000000000..84afdff59313 --- /dev/null +++ b/tests/drivers/gpio/gpio_basic_api/boards/ek_rx261.overlay @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + resources { + compatible = "test-gpio-basic-api"; + out-gpios = <&ioportd 1 0>; /* PD1 */ + in-gpios = <&ioportd 2 0>; /* PD2 */ + }; +}; + +&port_irq2 { + status = "okay"; + renesas,digital-filtering; +}; + +&ioportd { + status = "okay"; +}; diff --git a/tests/drivers/gpio/gpio_basic_api/boards/fpb_rx261.conf b/tests/drivers/gpio/gpio_basic_api/boards/fpb_rx261.conf new file mode 100644 index 000000000000..15e08fba7938 --- /dev/null +++ b/tests/drivers/gpio/gpio_basic_api/boards/fpb_rx261.conf @@ -0,0 +1 @@ +CONFIG_READ_DELAY=10 diff --git a/tests/drivers/gpio/gpio_basic_api/boards/fpb_rx261.overlay b/tests/drivers/gpio/gpio_basic_api/boards/fpb_rx261.overlay new file mode 100644 index 000000000000..84afdff59313 --- /dev/null +++ b/tests/drivers/gpio/gpio_basic_api/boards/fpb_rx261.overlay @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + resources { + compatible = "test-gpio-basic-api"; + out-gpios = <&ioportd 1 0>; /* PD1 */ + in-gpios = <&ioportd 2 0>; /* PD2 */ + }; +}; + +&port_irq2 { + status = "okay"; + renesas,digital-filtering; +}; + +&ioportd { + status = "okay"; +}; From 490fe49856789dfbf6b94b6a6aa1685f4e87e687 Mon Sep 17 00:00:00 2001 From: Johann Fischer Date: Thu, 27 Nov 2025 18:05:58 +0100 Subject: [PATCH 1592/3659] include: drivers: add SWD driver user API Although the DAP subsystem is the only user in the tree, yet, we may have other subsystems, libraries, or simple samples that could use this API in the future. Signed-off-by: Johann Fischer --- include/zephyr/drivers/swdp.h | 188 ++++++++++++++++++++++++++++++++++ 1 file changed, 188 insertions(+) diff --git a/include/zephyr/drivers/swdp.h b/include/zephyr/drivers/swdp.h index e16819a1909c..e9ae7cb5d372 100644 --- a/include/zephyr/drivers/swdp.h +++ b/include/zephyr/drivers/swdp.h @@ -194,10 +194,198 @@ struct swdp_api { int (*swdp_port_off)(const struct device *dev); }; +/** + * @brief Write count bits to SWDIO from data LSB first + * + * Typically used for line reset sequence or switching JTAG<->SWD operation. + * + * @param dev SWDP device + * @param count Number of bits to write + * @param data Bits to write + * @return 0 on success, or error code + */ +__syscall int swdp_output_sequence(const struct device *dev, + const uint32_t count, + const uint8_t *const data); + +static inline int z_impl_swdp_output_sequence(const struct device *dev, + const uint32_t count, + const uint8_t *const data) +{ + const struct swdp_api *api = dev->api; + + return api->swdp_output_sequence(dev, count, data); +} + +/** + * @brief Read count bits from SWDIO into data LSB first + * + * @param dev SWDP device + * @param count Number of bits to read + * @param buf Buffer to store bits read + * @return 0 on success, or error code + */ +__syscall int swdp_input_sequence(const struct device *dev, + const uint32_t count, + uint8_t *const buf); + +static inline int z_impl_swdp_input_sequence(const struct device *dev, + const uint32_t count, + uint8_t *const buf) +{ + const struct swdp_api *api = dev->api; + + return api->swdp_input_sequence(dev, count, buf); +} + +/** + * @brief Perform SWDP transfer and store response + * + * Request must be in the form APnDP | RnW | A[2:3], without start, stop, or parity bits. + * The driver may ignore idle_cycles when the SWDCLK is always clocked. + * + * @param dev SWDP device + * @param request SWDP request bits + * @param data Data to be transferred with request + * @param idle_cycles Idle cycles between request and response + * @param response Buffer to store response (ACK/WAIT/FAULT) + * @return 0 on success, or error code + */ +__syscall int swdp_transfer(const struct device *dev, + const uint8_t request, + uint32_t *const data, + const uint8_t idle_cycles, + uint8_t *const response); + +static inline int z_impl_swdp_transfer(const struct device *dev, + const uint8_t request, + uint32_t *const data, + const uint8_t idle_cycles, + uint8_t *const response) +{ + const struct swdp_api *api = dev->api; + + return api->swdp_transfer(dev, request, data, idle_cycles, response); +} + +/** + * @brief Set SWCLK, SWDPIO, and nRESET pins state + * @note The bit positions are defined by the SWDP_*_PIN macros. + * + * @param dev SWDP device + * @param pins Bitmask of pins to set + * @param value Value to set pins to + * @return 0 on success, or error code + */ +__syscall int swdp_set_pins(const struct device *dev, + const uint8_t pins, + const uint8_t value); + +static inline int z_impl_swdp_set_pins(const struct device *dev, + const uint8_t pins, + const uint8_t value) +{ + const struct swdp_api *api = dev->api; + + return api->swdp_set_pins(dev, pins, value); +} + +/** + * @brief Get SWCLK, SWDPIO, and nRESET pins state + * @note The bit positions are defined by the SWDP_*_PIN macros. + * + * @param dev SWDP device + * @param state Place to store pins state + * @return 0 on success, or error code + */ +__syscall int swdp_get_pins(const struct device *dev, + uint8_t *const state); + +static inline int z_impl_swdp_get_pins(const struct device *dev, + uint8_t *const state) +{ + const struct swdp_api *api = dev->api; + + return api->swdp_get_pins(dev, state); +} + +/** + * @brief Set SWDP clock frequency + * + * @param dev SWDP device + * @param clock Clock frequency in Hz + * @return 0 on success, or error code + */ +__syscall int swdp_set_clock(const struct device *dev, + const uint32_t clock); + +static inline int z_impl_swdp_set_clock(const struct device *dev, + const uint32_t clock) +{ + const struct swdp_api *api = dev->api; + + return api->swdp_set_clock(dev, clock); +} + +/** + * @brief Enable interface, set pins to default state + * + * @note SWDPIO is set to output mode, SWCLK and nRESET are set to high level. + * + * @param dev SWDP device + * @return 0 on success, or error code + */ +__syscall int swdp_port_on(const struct device *dev); + +static inline int z_impl_swdp_port_on(const struct device *dev) +{ + const struct swdp_api *api = dev->api; + + return api->swdp_port_on(dev); +} + +/** + * @brief Disable interface, set pins to High-Z mode + * + * @param dev SWDP device + * @return 0 on success, or error code + */ +__syscall int swdp_port_off(const struct device *dev); + +static inline int z_impl_swdp_port_off(const struct device *dev) +{ + const struct swdp_api *api = dev->api; + + return api->swdp_port_off(dev); +} + +/** + * @brief Configure SWDP interface + * + * @param dev SWDP device + * @param turnaround Line turnaround cycles + * @param data_phase Always generate Data Phase (also on WAIT/FAULT) + * @return 0 on success, or error code + */ +__syscall int swdp_configure(const struct device *dev, + const uint8_t turnaround, + const bool data_phase); + +static inline int z_impl_swdp_configure(const struct device *dev, + const uint8_t turnaround, + const bool data_phase) +{ + const struct swdp_api *api = dev->api; + + return api->swdp_configure(dev, turnaround, data_phase); +} + #ifdef __cplusplus } #endif /** @} */ +#include + #endif /* ZEPHYR_INCLUDE_SWDP_H_ */ From 4b9f4106e26c8b55c180f9ea8eb7d5ad6be5ffa6 Mon Sep 17 00:00:00 2001 From: Johann Fischer Date: Thu, 27 Nov 2025 18:38:38 +0100 Subject: [PATCH 1593/3659] dap: cmsis_dap: use SWD driver user API Use SWD driver user API. Signed-off-by: Johann Fischer --- subsys/dap/cmsis_dap.c | 41 ++++++++++++++++------------------------- 1 file changed, 16 insertions(+), 25 deletions(-) diff --git a/subsys/dap/cmsis_dap.c b/subsys/dap/cmsis_dap.c index cd68f634a567..cbed72d1f108 100644 --- a/subsys/dap/cmsis_dap.c +++ b/subsys/dap/cmsis_dap.c @@ -194,7 +194,6 @@ static uint16_t dap_connect(struct dap_context *const ctx, const uint8_t *const request, uint8_t *const response) { - const struct swdp_api *api = ctx->swdp_dev->api; uint8_t port; if (request[0] == DAP_PORT_AUTODETECT) { @@ -214,7 +213,7 @@ static uint16_t dap_connect(struct dap_context *const ctx, break; } - api->swdp_port_on(ctx->swdp_dev); + (void)swdp_port_on(ctx->swdp_dev); break; case DAP_PORT_JTAG: LOG_ERR("port unsupported"); @@ -234,14 +233,13 @@ static uint16_t dap_connect(struct dap_context *const ctx, static uint16_t dap_disconnect(struct dap_context *const ctx, uint8_t *const response) { - const struct swdp_api *api = ctx->swdp_dev->api; LOG_DBG(""); ctx->debug_port = DAP_PORT_DISABLED; if (atomic_test_bit(&ctx->state, DAP_STATE_CONNECTED)) { - api->swdp_port_off(ctx->swdp_dev); + (void)swdp_port_off(ctx->swdp_dev); } else { LOG_WRN("DAP device is not connected"); } @@ -283,7 +281,6 @@ static uint16_t dap_swj_pins(struct dap_context *const ctx, const uint8_t *const request, uint8_t *const response) { - const struct swdp_api *api = ctx->swdp_dev->api; uint8_t value = request[0]; uint8_t select = request[1]; uint32_t wait = sys_get_le32(&request[2]); @@ -298,11 +295,11 @@ static uint16_t dap_swj_pins(struct dap_context *const ctx, /* Skip if nothing selected. */ if (select) { - api->swdp_set_pins(ctx->swdp_dev, select, value); + (void)swdp_set_pins(ctx->swdp_dev, select, value); } do { - api->swdp_get_pins(ctx->swdp_dev, &state); + (void)swdp_get_pins(ctx->swdp_dev, &state); LOG_INF("select 0x%02x, value 0x%02x, wait %u, state 0x%02x", select, value, wait, state); if ((value & select) == (state & select)) { @@ -321,14 +318,13 @@ static uint16_t dap_swj_clock(struct dap_context *const ctx, const uint8_t *const request, uint8_t *const response) { - const struct swdp_api *api = ctx->swdp_dev->api; uint32_t clk = sys_get_le32(&request[0]); LOG_DBG("clock %d", clk); if (atomic_test_bit(&ctx->state, DAP_STATE_CONNECTED)) { if (clk) { - api->swdp_set_clock(ctx->swdp_dev, clk); + (void)swdp_set_clock(ctx->swdp_dev, clk); response[0] = DAP_OK; } else { response[0] = DAP_ERROR; @@ -346,7 +342,6 @@ static uint16_t dap_swj_sequence(struct dap_context *const ctx, const uint8_t *const request, uint8_t *const response) { - const struct swdp_api *api = ctx->swdp_dev->api; uint16_t count = request[0]; LOG_DBG("count %u", count); @@ -361,7 +356,7 @@ static uint16_t dap_swj_sequence(struct dap_context *const ctx, return 1U; } - api->swdp_output_sequence(ctx->swdp_dev, count, &request[1]); + (void)swdp_output_sequence(ctx->swdp_dev, count, &request[1]); response[0] = DAP_OK; return 1U; @@ -372,7 +367,6 @@ static uint16_t dap_swdp_configure(struct dap_context *const ctx, const uint8_t *const request, uint8_t *const response) { - const struct swdp_api *api = ctx->swdp_dev->api; uint8_t turnaround = (request[0] & 0x03U) + 1U; bool data_phase = (request[0] & 0x04U) ? true : false; @@ -382,7 +376,7 @@ static uint16_t dap_swdp_configure(struct dap_context *const ctx, return 1U; } - api->swdp_configure(ctx->swdp_dev, turnaround, data_phase); + (void)swdp_configure(ctx->swdp_dev, turnaround, data_phase); response[0] = DAP_OK; return 1U; @@ -410,16 +404,15 @@ static inline uint8_t do_swdp_transfer(struct dap_context *const ctx, const uint8_t req_val, uint32_t *data) { - const struct swdp_api *api = ctx->swdp_dev->api; uint32_t retry = ctx->transfer.retry_count; uint8_t rspns_val; do { - api->swdp_transfer(ctx->swdp_dev, - req_val, - data, - ctx->transfer.idle_cycles, - &rspns_val); + (void)swdp_transfer(ctx->swdp_dev, + req_val, + data, + ctx->transfer.idle_cycles, + &rspns_val); } while ((rspns_val == SWDP_ACK_WAIT) && retry--); return rspns_val; @@ -642,7 +635,6 @@ static uint16_t dap_swdp_sequence(struct dap_context *const ctx, const uint8_t *const request, uint8_t *const response) { - const struct swdp_api *api = ctx->swdp_dev->api; const uint8_t *request_data = request + 1; uint8_t *response_data = response + 1; uint8_t count = request[0]; @@ -673,10 +665,10 @@ static uint16_t dap_swdp_sequence(struct dap_context *const ctx, request_data += 1; if (input) { - api->swdp_input_sequence(ctx->swdp_dev, num_cycles, response_data); + (void)swdp_input_sequence(ctx->swdp_dev, num_cycles, response_data); response_data += num_bytes; } else { - api->swdp_output_sequence(ctx->swdp_dev, num_cycles, request_data); + (void)swdp_output_sequence(ctx->swdp_dev, num_cycles, request_data); request_data += num_bytes; } } @@ -809,13 +801,12 @@ static uint16_t dap_swdp_writeabort(struct dap_context *const ctx, const uint8_t *const request, uint8_t *const response) { - const struct swdp_api *api = ctx->swdp_dev->api; /* Load data (Ignore DAP index in request[0]) */ uint32_t data = sys_get_le32(&request[1]); /* Write Abort register */ - api->swdp_transfer(ctx->swdp_dev, DP_ABORT, &data, - ctx->transfer.idle_cycles, NULL); + (void)swdp_transfer(ctx->swdp_dev, DP_ABORT, &data, + ctx->transfer.idle_cycles, NULL); response[0] = DAP_OK; return 1U; From 2c254285cb167df8aeda5a233ba7a91d901f39db Mon Sep 17 00:00:00 2001 From: Johann Fischer Date: Fri, 28 Nov 2025 00:33:06 +0100 Subject: [PATCH 1594/3659] drivers: dp: add common header for SWD drivers Move the LUT to convert from simplified format to request packet expected by the target, and the helper to calculate parity bits to common header, so that they could be used by other drivers. Signed-off-by: Johann Fischer --- drivers/dp/swdp_bitbang.c | 34 ++++------------------- drivers/dp/swdp_common.h | 58 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 29 deletions(-) create mode 100644 drivers/dp/swdp_common.h diff --git a/drivers/dp/swdp_bitbang.c b/drivers/dp/swdp_bitbang.c index ceee3e58887b..2647828b19d7 100644 --- a/drivers/dp/swdp_bitbang.c +++ b/drivers/dp/swdp_bitbang.c @@ -17,6 +17,8 @@ #define DT_DRV_COMPAT zephyr_swdp_gpio +#include "swdp_common.h" + #include #include #include @@ -60,32 +62,6 @@ struct sw_cfg_data { bool fast_clock; }; -/* - * Move A[2:3], RnW, APnDP bits to their position, - * add start bit, stop bit(6), park bit and parity bit. - * For example, reading IDCODE would be APnDP=0, RnW=1, A2=0, A3=0. - * The request would be 0xa5, which is 10100101 in binary. - * - * For more information, see: - * - CMSIS-DAP Command Specification, DAP_Transfer - * - ARM Debug Interface v5 Architecture Specification - */ -const static uint8_t sw_request_lut[16] = { - 0x81, 0xa3, 0xa5, 0x87, 0xa9, 0x8b, 0x8d, 0xaf, - 0xb1, 0x93, 0x95, 0xb7, 0x99, 0xbb, 0xbd, 0x9f -}; - -static ALWAYS_INLINE uint32_t sw_get32bit_parity(uint32_t data) -{ - data ^= data >> 16; - data ^= data >> 8; - data ^= data >> 4; - data ^= data >> 2; - data ^= data >> 1; - - return data & 1U; -} - /* Set SWCLK DAP hardware output pin to high level */ static ALWAYS_INLINE void pin_swclk_set(const struct device *dev) { @@ -335,12 +311,12 @@ static int sw_transfer(const struct device *dev, LOG_DBG("request 0x%02x idle %u", request, idle_cycles); if (!(request & SWDP_REQUEST_RnW)) { LOG_DBG("write data 0x%08x", *data); - parity = sw_get32bit_parity(*data); + parity = swd_get32bit_parity(*data); } key = irq_lock(); - val = sw_request_lut[request & 0xFU]; + val = SWD_REQUEST_FROM_LUT(request); for (n = 8U; n; n--) { SW_WRITE_BIT(dev, val, sw_data->clock_delay); val >>= 1; @@ -374,7 +350,7 @@ static int sw_transfer(const struct device *dev, sw_cycle_turnaround(dev); pin_swdio_out_enable(dev); - if ((sw_get32bit_parity(val) ^ bit) & 1U) { + if ((swd_get32bit_parity(val) ^ bit) & 1U) { ack = SWDP_TRANSFER_ERROR; } diff --git a/drivers/dp/swdp_common.h b/drivers/dp/swdp_common.h new file mode 100644 index 000000000000..4f28765dc606 --- /dev/null +++ b/drivers/dp/swdp_common.h @@ -0,0 +1,58 @@ +/* + * SPDX-FileCopyrightText: Copyright The Zephyr Project Contributors + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Private API for SWDP controller drivers + */ + +#ifndef ZEPHYR_DRIVERS_DP_SWDP_COMMON_H +#define ZEPHYR_DRIVERS_DP_SWDP_COMMON_H + +#include +#include + +/* + * LUT to convert request value from the simplified format + * APnDP | RnW | A[2:3] + * to the request packet expected by the target + * Start | APnDP | RnW | A[2:3] | Parity | Stop | Park + */ +const static uint8_t swd_request_lut[16] = { + 0x81, 0xa3, 0xa5, 0x87, 0xa9, 0x8b, 0x8d, 0xaf, + 0xb1, 0x93, 0x95, 0xb7, 0x99, 0xbb, 0xbd, 0x9f +}; + +/** + * @brief Convert request from simplified format to format expected by the target + * + * @param[in] request value in simplified format APnDP | RnW | A[2:3] + * + * @return request packet expected by the target + */ +#define SWD_REQUEST_FROM_LUT(r) (swd_request_lut[(r) & 0x0F]) + +/** + * @brief Get parity of 32 bits data + * + * @param[in] data Transceived or received data + * + * @return Parity bit placed in LSB. + */ +static inline uint32_t swd_get32bit_parity(const uint32_t data) +{ + uint32_t parity = data; + + parity ^= parity >> 16; + parity ^= parity >> 8; + parity ^= parity >> 4; + parity ^= parity >> 2; + parity ^= parity >> 1; + + return parity & 1U; +} + +#endif /* ZEPHYR_DRIVERS_DP_SWDP_COMMON_H */ From cfd748fff172c67b643fb4959cf0033f978e6f02 Mon Sep 17 00:00:00 2001 From: Johann Fischer Date: Fri, 28 Nov 2025 23:11:50 +0100 Subject: [PATCH 1595/3659] dap: add header and macro to instantiate DAP context Although we have the three layers, SWDP driver API, DAP stack, and USB backend, to implement a debug probe, there is no way for the user to instantiate the DAP context, which would allow it to be used with different backends or to change the configuration at runtime. The Debug Access Port (DAP) is an implementation of the ARM Debug Interface (ADI) that is typically integrated into SoC. With all three layers, we implement a link to the DAP on the SoC. Let's call it Zephyr DAP Link and use the dap_link prefix. There is also a MBED DAPLink project that implements similar functionality, but using a different name would likely cause more confusion. Signed-off-by: Johann Fischer --- include/zephyr/dap/dap_link.h | 113 ++++++++++++++++++++++++++++++ samples/subsys/dap/src/main.c | 14 ++-- subsys/dap/cmsis_dap.c | 126 ++++++++++++++-------------------- subsys/dap/cmsis_dap.h | 9 ++- subsys/dap/dap_backend_usb.c | 28 +++++++- 5 files changed, 205 insertions(+), 85 deletions(-) create mode 100644 include/zephyr/dap/dap_link.h diff --git a/include/zephyr/dap/dap_link.h b/include/zephyr/dap/dap_link.h new file mode 100644 index 000000000000..db1f1c3767e6 --- /dev/null +++ b/include/zephyr/dap/dap_link.h @@ -0,0 +1,113 @@ +/* + * SPDX-FileCopyrightText: Copyright The Zephyr Project Contributors + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Main header file for DAP Link API. + */ + +#ifndef ZEPHYR_INCLUDE_DAP_DAP_LINK_H +#define ZEPHYR_INCLUDE_DAP_DAP_LINK_H + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Zephyr DAP Link API + * @defgroup DAP API + * @ingroup io_interfaces + * @since 4.4 + * @version 0.1.0 + * @{ + */ + +/** + * @cond INTERNAL_HIDDEN + * Degug Access Port (DAP) Link runtime context + * + */ +struct dap_link_context { + /* Pointer to SWD or JTAG device. Only SWD is supported yet. */ + const struct device *dev; + atomic_t state; + /* Runtime debug port type */ + uint8_t debug_port; + /* Debug port capabilities */ + uint8_t capabilities; + /* Packet size used by a backend */ + uint16_t pkt_size; + struct { + /* Idle cycles after transfer */ + uint8_t idle_cycles; + /* Number of retries after WAIT response */ + uint16_t retry_count; + /* Number of retries if read value does not match */ + uint16_t match_retry; + /* Match Mask */ + uint32_t match_mask; + } transfer; +}; + +/** @endcond */ + +/** + * @brief Define Zephyr DAP Link context structure + * + * Example of use: + * + * @code{.c} + * DAP_LINK_CONTEXT_DEFINE(sample_link_ctx, + * DEVICE_DT_GET_ONE(zephyr_swdp_gpio)); + * @endcode + * + * @param ctx_name DAP Link context name + * @param ctx_dev Pointer to SWDP device + */ +#define DAP_LINK_CONTEXT_DEFINE(ctx_name, ctx_dev) \ + static struct dap_link_context ctx_name = { \ + .dev = ctx_dev, \ + } + +/** + * @brief Initialize DAP Link + * + * @param[in] dap_link_ctx Pointer to DAP Link context + * + * @return 0 on success, or error code + */ +int dap_link_init(struct dap_link_context *const dap_link_ctx); + +/** + * @brief Set packet size used by a DAP Link backend + * + * @param[in] dap_link_ctx Pointer to DAP Link context + * @param[in] pkt_size Packet size + * + */ +void dap_link_set_pkt_size(struct dap_link_context *const dap_link_ctx, + const uint16_t pkt_size); + +/** + * @brief Initialize DAP Link USB backend + * + * @param[in] dap_link_ctx Pointer to DAP Link context + * + * @return 0 on success, or error code + */ +int dap_link_backend_usb_init(struct dap_link_context *const dap_link_ctx); + +#ifdef __cplusplus +} +#endif + +/** @} */ + +#endif /* ZEPHYR_INCLUDE_DAP_DAP_LINK_H */ diff --git a/samples/subsys/dap/src/main.c b/samples/subsys/dap/src/main.c index 55288af1eff1..3b6559b671d1 100644 --- a/samples/subsys/dap/src/main.c +++ b/samples/subsys/dap/src/main.c @@ -12,8 +12,7 @@ #include #include #include - -#include +#include #include LOG_MODULE_REGISTER(dap_sample, LOG_LEVEL_INF); @@ -21,18 +20,25 @@ LOG_MODULE_REGISTER(dap_sample, LOG_LEVEL_INF); #include "webusb.h" #include "msosv2.h" +DAP_LINK_CONTEXT_DEFINE(sample_dap_ctx, DEVICE_DT_GET_ONE(zephyr_swdp_gpio)); + int main(void) { - const struct device *const swd_dev = DEVICE_DT_GET_ONE(zephyr_swdp_gpio); struct usbd_context *sample_usbd; int ret; - ret = dap_setup(swd_dev); + ret = dap_link_init(&sample_dap_ctx); if (ret) { LOG_ERR("Failed to initialize DAP controller, %d", ret); return ret; } + ret = dap_link_backend_usb_init(&sample_dap_ctx); + if (ret) { + LOG_ERR("Failed to initialize DAP Link USB backend, %d", ret); + return ret; + } + sample_usbd = sample_usbd_setup_device(NULL); if (sample_usbd == NULL) { LOG_ERR("Failed to setup USB device"); diff --git a/subsys/dap/cmsis_dap.c b/subsys/dap/cmsis_dap.c index cbed72d1f108..ce26e8a30f33 100644 --- a/subsys/dap/cmsis_dap.c +++ b/subsys/dap/cmsis_dap.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -27,26 +28,6 @@ LOG_MODULE_REGISTER(dap, CONFIG_DAP_LOG_LEVEL); #define DAP_STATE_CONNECTED 0 -struct dap_context { - struct device *swdp_dev; - atomic_t state; - uint8_t debug_port; - uint8_t capabilities; - uint16_t pkt_size; - struct { - /* Idle cycles after transfer */ - uint8_t idle_cycles; - /* Number of retries after WAIT response */ - uint16_t retry_count; - /* Number of retries if read value does not match */ - uint16_t match_retry; - /* Match Mask */ - uint32_t match_mask; - } transfer; -}; - -static struct dap_context dap_ctx[1]; - #define CMSIS_DAP_PACKET_MIN_SIZE 64 BUILD_ASSERT(sizeof(CONFIG_CMSIS_DAP_PROBE_VENDOR) <= @@ -69,7 +50,7 @@ BUILD_ASSERT(sizeof(CONFIG_CMSIS_DAP_DEVICE_NAME) <= "DEVICE_NAME string is too long."); /* Get DAP Information */ -static uint16_t dap_info(struct dap_context *const ctx, +static uint16_t dap_info(struct dap_link_context *const ctx, const uint8_t *const request, uint8_t *const response) { @@ -165,7 +146,7 @@ static uint16_t dap_info(struct dap_context *const ctx, } /* Process Host Status command and prepare response */ -static uint16_t dap_host_status(struct dap_context *const ctx, +static uint16_t dap_host_status(struct dap_link_context *const ctx, const uint8_t *const request, uint8_t *const response) { @@ -190,7 +171,7 @@ static uint16_t dap_host_status(struct dap_context *const ctx, } /* Process Connect command and prepare response */ -static uint16_t dap_connect(struct dap_context *const ctx, +static uint16_t dap_connect(struct dap_link_context *const ctx, const uint8_t *const request, uint8_t *const response) { @@ -213,7 +194,7 @@ static uint16_t dap_connect(struct dap_context *const ctx, break; } - (void)swdp_port_on(ctx->swdp_dev); + (void)swdp_port_on(ctx->dev); break; case DAP_PORT_JTAG: LOG_ERR("port unsupported"); @@ -230,7 +211,7 @@ static uint16_t dap_connect(struct dap_context *const ctx, } /* Process Disconnect command and prepare response */ -static uint16_t dap_disconnect(struct dap_context *const ctx, +static uint16_t dap_disconnect(struct dap_link_context *const ctx, uint8_t *const response) { @@ -239,7 +220,7 @@ static uint16_t dap_disconnect(struct dap_context *const ctx, ctx->debug_port = DAP_PORT_DISABLED; if (atomic_test_bit(&ctx->state, DAP_STATE_CONNECTED)) { - (void)swdp_port_off(ctx->swdp_dev); + (void)swdp_port_off(ctx->dev); } else { LOG_WRN("DAP device is not connected"); } @@ -251,7 +232,7 @@ static uint16_t dap_disconnect(struct dap_context *const ctx, } /* Process Delay command and prepare response */ -static uint16_t dap_delay(struct dap_context *const ctx, +static uint16_t dap_delay(struct dap_link_context *const ctx, const uint8_t *const request, uint8_t *const response) { @@ -266,7 +247,7 @@ static uint16_t dap_delay(struct dap_context *const ctx, } /* Process Reset Target command and prepare response */ -static uint16_t dap_reset_target(struct dap_context *const ctx, +static uint16_t dap_reset_target(struct dap_link_context *const ctx, uint8_t *const response) { response[0] = DAP_OK; @@ -277,7 +258,7 @@ static uint16_t dap_reset_target(struct dap_context *const ctx, } /* Process SWJ Pins command and prepare response */ -static uint16_t dap_swj_pins(struct dap_context *const ctx, +static uint16_t dap_swj_pins(struct dap_link_context *const ctx, const uint8_t *const request, uint8_t *const response) { @@ -295,11 +276,11 @@ static uint16_t dap_swj_pins(struct dap_context *const ctx, /* Skip if nothing selected. */ if (select) { - (void)swdp_set_pins(ctx->swdp_dev, select, value); + (void)swdp_set_pins(ctx->dev, select, value); } do { - (void)swdp_get_pins(ctx->swdp_dev, &state); + (void)swdp_get_pins(ctx->dev, &state); LOG_INF("select 0x%02x, value 0x%02x, wait %u, state 0x%02x", select, value, wait, state); if ((value & select) == (state & select)) { @@ -314,7 +295,7 @@ static uint16_t dap_swj_pins(struct dap_context *const ctx, } /* Process SWJ Clock command and prepare response */ -static uint16_t dap_swj_clock(struct dap_context *const ctx, +static uint16_t dap_swj_clock(struct dap_link_context *const ctx, const uint8_t *const request, uint8_t *const response) { @@ -324,7 +305,7 @@ static uint16_t dap_swj_clock(struct dap_context *const ctx, if (atomic_test_bit(&ctx->state, DAP_STATE_CONNECTED)) { if (clk) { - (void)swdp_set_clock(ctx->swdp_dev, clk); + (void)swdp_set_clock(ctx->dev, clk); response[0] = DAP_OK; } else { response[0] = DAP_ERROR; @@ -338,7 +319,7 @@ static uint16_t dap_swj_clock(struct dap_context *const ctx, } /* Process SWJ Sequence command and prepare response */ -static uint16_t dap_swj_sequence(struct dap_context *const ctx, +static uint16_t dap_swj_sequence(struct dap_link_context *const ctx, const uint8_t *const request, uint8_t *const response) { @@ -356,14 +337,14 @@ static uint16_t dap_swj_sequence(struct dap_context *const ctx, return 1U; } - (void)swdp_output_sequence(ctx->swdp_dev, count, &request[1]); + (void)swdp_output_sequence(ctx->dev, count, &request[1]); response[0] = DAP_OK; return 1U; } /* Process SWD Configure command and prepare response */ -static uint16_t dap_swdp_configure(struct dap_context *const ctx, +static uint16_t dap_swdp_configure(struct dap_link_context *const ctx, const uint8_t *const request, uint8_t *const response) { @@ -376,14 +357,14 @@ static uint16_t dap_swdp_configure(struct dap_context *const ctx, return 1U; } - (void)swdp_configure(ctx->swdp_dev, turnaround, data_phase); + (void)swdp_configure(ctx->dev, turnaround, data_phase); response[0] = DAP_OK; return 1U; } /* Process Transfer Configure command and prepare response */ -static uint16_t dap_transfer_cfg(struct dap_context *const ctx, +static uint16_t dap_transfer_cfg(struct dap_link_context *const ctx, const uint8_t *const request, uint8_t *const response) { @@ -400,7 +381,7 @@ static uint16_t dap_transfer_cfg(struct dap_context *const ctx, return 1U; } -static inline uint8_t do_swdp_transfer(struct dap_context *const ctx, +static inline uint8_t do_swdp_transfer(struct dap_link_context *const ctx, const uint8_t req_val, uint32_t *data) { @@ -408,7 +389,7 @@ static inline uint8_t do_swdp_transfer(struct dap_context *const ctx, uint8_t rspns_val; do { - (void)swdp_transfer(ctx->swdp_dev, + (void)swdp_transfer(ctx->dev, req_val, data, ctx->transfer.idle_cycles, @@ -418,7 +399,7 @@ static inline uint8_t do_swdp_transfer(struct dap_context *const ctx, return rspns_val; } -static uint8_t swdp_transfer_match(struct dap_context *const ctx, +static uint8_t swdp_transfer_match(struct dap_link_context *const ctx, const uint8_t req_val, const uint32_t match_val) { @@ -463,7 +444,7 @@ static uint8_t swdp_transfer_match(struct dap_context *const ctx, * one byte request (register) * four byte data (for write request only) */ -static uint16_t dap_swdp_transfer(struct dap_context *const ctx, +static uint16_t dap_swdp_transfer(struct dap_link_context *const ctx, const uint8_t *const request, uint8_t *const response) { @@ -605,7 +586,7 @@ static uint16_t dap_swdp_transfer(struct dap_context *const ctx, } /* Delegate DAP Transfer command */ -static uint16_t dap_transfer(struct dap_context *const ctx, +static uint16_t dap_transfer(struct dap_link_context *const ctx, const uint8_t *const request, uint8_t *const response) { @@ -631,7 +612,7 @@ static uint16_t dap_transfer(struct dap_context *const ctx, return retval; } -static uint16_t dap_swdp_sequence(struct dap_context *const ctx, +static uint16_t dap_swdp_sequence(struct dap_link_context *const ctx, const uint8_t *const request, uint8_t *const response) { @@ -665,10 +646,10 @@ static uint16_t dap_swdp_sequence(struct dap_context *const ctx, request_data += 1; if (input) { - (void)swdp_input_sequence(ctx->swdp_dev, num_cycles, response_data); + (void)swdp_input_sequence(ctx->dev, num_cycles, response_data); response_data += num_bytes; } else { - (void)swdp_output_sequence(ctx->swdp_dev, num_cycles, request_data); + (void)swdp_output_sequence(ctx->dev, num_cycles, request_data); request_data += num_bytes; } } @@ -684,7 +665,7 @@ static uint16_t dap_swdp_sequence(struct dap_context *const ctx, * one byte block_request (register) * data[transfer_count * sizeof(uint32_t)] */ -static uint16_t dap_swdp_transferblock(struct dap_context *const ctx, +static uint16_t dap_swdp_transferblock(struct dap_link_context *const ctx, const uint8_t *const request, uint8_t *const response) { @@ -764,7 +745,7 @@ static uint16_t dap_swdp_transferblock(struct dap_context *const ctx, } /* Delegate Transfer Block command */ -static uint16_t dap_transferblock(struct dap_context *const ctx, +static uint16_t dap_transferblock(struct dap_link_context *const ctx, const uint8_t *const request, uint8_t *const response) { @@ -797,7 +778,7 @@ static uint16_t dap_transferblock(struct dap_context *const ctx, } /* Process SWD Write ABORT command and prepare response */ -static uint16_t dap_swdp_writeabort(struct dap_context *const ctx, +static uint16_t dap_swdp_writeabort(struct dap_link_context *const ctx, const uint8_t *const request, uint8_t *const response) { @@ -805,7 +786,7 @@ static uint16_t dap_swdp_writeabort(struct dap_context *const ctx, uint32_t data = sys_get_le32(&request[1]); /* Write Abort register */ - (void)swdp_transfer(ctx->swdp_dev, DP_ABORT, &data, + (void)swdp_transfer(ctx->dev, DP_ABORT, &data, ctx->transfer.idle_cycles, NULL); response[0] = DAP_OK; @@ -813,7 +794,7 @@ static uint16_t dap_swdp_writeabort(struct dap_context *const ctx, } /* Delegate DAP Write ABORT command */ -static uint16_t dap_writeabort(struct dap_context *const ctx, +static uint16_t dap_writeabort(struct dap_link_context *const ctx, const uint8_t *const request, uint8_t *const response) { @@ -839,7 +820,7 @@ static uint16_t dap_writeabort(struct dap_context *const ctx, } /* Process DAP Vendor command request */ -static uint16_t dap_process_vendor_cmd(struct dap_context *const ctx, +static uint16_t dap_process_vendor_cmd(struct dap_link_context *const ctx, const uint8_t *const request, uint8_t *const response) { @@ -856,7 +837,7 @@ static uint16_t dap_process_vendor_cmd(struct dap_context *const ctx, * All the subsequent command functions have the same parameter * and return value structure. */ -static uint16_t dap_process_cmd(struct dap_context *const ctx, +static uint16_t dap_process_cmd(struct dap_link_context *const ctx, const uint8_t *request, uint8_t *response) { @@ -1002,8 +983,8 @@ static uint16_t dap_process_cmd(struct dap_context *const ctx, * response: pointer to response data * return: number of bytes in response */ -uint32_t dap_execute_cmd(const uint8_t *request, - uint8_t *response) +uint32_t dap_link_execute_cmd(struct dap_link_context *const dap_link_ctx, + const uint8_t *request, uint8_t *response) { uint32_t retval; uint16_t n; @@ -1019,7 +1000,7 @@ uint32_t dap_execute_cmd(const uint8_t *request, retval = sizeof(count) + 1U; LOG_WRN("(untested) ID DAP EXECUTE_COMMANDS count %u", count); while (count--) { - n = dap_process_cmd(&dap_ctx[0], request, response); + n = dap_process_cmd(dap_link_ctx, request, response); retval += n; request += n; response += n; @@ -1027,33 +1008,32 @@ uint32_t dap_execute_cmd(const uint8_t *request, return retval; } - return dap_process_cmd(&dap_ctx[0], request, response); + return dap_process_cmd(dap_link_ctx, request, response); } -void dap_update_pkt_size(const uint16_t pkt_size) +void dap_link_set_pkt_size(struct dap_link_context *const dap_link_ctx, + const uint16_t pkt_size) { - dap_ctx[0].pkt_size = pkt_size; - LOG_INF("New packet size %u", dap_ctx[0].pkt_size); + dap_link_ctx->pkt_size = pkt_size; + LOG_INF("New packet size %u", dap_link_ctx->pkt_size); } -int dap_setup(const struct device *const dev) +int dap_link_init(struct dap_link_context *const dap_link_ctx) { - dap_ctx[0].swdp_dev = (void *)dev; - - if (!device_is_ready(dap_ctx[0].swdp_dev)) { - LOG_ERR("SWD driver not ready"); + if (!device_is_ready(dap_link_ctx->dev)) { + LOG_ERR("SWD driver %s not ready", dap_link_ctx->dev->name); return -ENODEV; } /* Default settings */ - dap_ctx[0].pkt_size = CMSIS_DAP_PACKET_MIN_SIZE; - dap_ctx[0].debug_port = 0U; - dap_ctx[0].transfer.idle_cycles = 0U; - dap_ctx[0].transfer.retry_count = 100U; - dap_ctx[0].transfer.match_retry = 0U; - dap_ctx[0].transfer.match_mask = 0U; - dap_ctx[0].capabilities = DAP_SUPPORTS_ATOMIC_COMMANDS | - DAP_DP_SUPPORTS_SWD; + dap_link_ctx->pkt_size = CMSIS_DAP_PACKET_MIN_SIZE; + dap_link_ctx->debug_port = 0U; + dap_link_ctx->transfer.idle_cycles = 0U; + dap_link_ctx->transfer.retry_count = 100U; + dap_link_ctx->transfer.match_retry = 0U; + dap_link_ctx->transfer.match_mask = 0U; + dap_link_ctx->capabilities = DAP_SUPPORTS_ATOMIC_COMMANDS | + DAP_DP_SUPPORTS_SWD; return 0; } diff --git a/subsys/dap/cmsis_dap.h b/subsys/dap/cmsis_dap.h index 947435828759..29267d32579e 100644 --- a/subsys/dap/cmsis_dap.h +++ b/subsys/dap/cmsis_dap.h @@ -19,7 +19,8 @@ #ifndef ZEPHYR_INCLUDE_CMSIS_DAP_H_ #define ZEPHYR_INCLUDE_CMSIS_DAP_H_ -#include +#include +#include /* Firmware Version */ #define DAP_FW_VER "2.1.0" @@ -129,9 +130,7 @@ #define DAP_MBMSG_FROM_IFACE 0x1U #define DAP_MBMSG_FROM_CONTROLLER 0x2U -/* Keep it internal until an other interface has been implemented. */ -int dap_setup(const struct device *const dev); -uint32_t dap_execute_cmd(const uint8_t *request, uint8_t *response); -void dap_update_pkt_size(const uint16_t pkt_size); +uint32_t dap_link_execute_cmd(struct dap_link_context *const dap_link_ctx, + const uint8_t *request, uint8_t *response); #endif /* ZEPHYR_INCLUDE_CMSIS_DAP_H_ */ diff --git a/subsys/dap/dap_backend_usb.c b/subsys/dap/dap_backend_usb.c index 5986e3a1e2cd..91a074e3fb16 100644 --- a/subsys/dap/dap_backend_usb.c +++ b/subsys/dap/dap_backend_usb.c @@ -7,6 +7,7 @@ #include #include #include +#include #include "cmsis_dap.h" @@ -41,6 +42,7 @@ struct dap_func_data { const struct usb_desc_header **const hs_desc; struct usbd_desc_node *const iface_str_desc_nd; atomic_t state; + struct dap_link_context *dap_link_ctx; }; static uint8_t dap_func_get_bulk_out(struct usbd_class_data *const c_data) @@ -91,7 +93,8 @@ static int dap_func_request_handler(struct usbd_class_data *c_data, } else { bi->ep = dap_func_get_bulk_in(c_data); - len = dap_execute_cmd(buf->data, response_buf); + len = dap_link_execute_cmd(data->dap_link_ctx, + buf->data, response_buf); net_buf_reset(buf); LOG_DBG("response length %u, starting with [0x%02X, 0x%02X]", len, response_buf[0], response_buf[1]); @@ -159,9 +162,9 @@ static void dap_func_enable(struct usbd_class_data *const c_data) if (!atomic_test_and_set_bit(&data->state, SAMPLE_FUNCTION_ENABLED)) { if (usbd_bus_speed(uds_ctx) == USBD_SPEED_HS) { - dap_update_pkt_size(512); + dap_link_set_pkt_size(data->dap_link_ctx, 512); } else { - dap_update_pkt_size(64); + dap_link_set_pkt_size(data->dap_link_ctx, 64); } buf = dap_func_buf_alloc(c_data, dap_func_get_bulk_out(c_data)); @@ -191,6 +194,11 @@ static int dap_func_init(struct usbd_class_data *c_data) struct dap_func_data *data = usbd_class_get_private(c_data); struct dap_func_desc *desc = data->desc; + if (data->dap_link_ctx == NULL) { + LOG_ERR("No DAP Link context provided"); + return -EIO; + } + LOG_DBG("Init class instance %p", (void *)c_data); if (usbd_add_descriptor(uds_ctx, data->iface_str_desc_nd)) { @@ -303,3 +311,17 @@ const static struct usb_desc_header *dap_func_hs_desc_##n[] = { \ LISTIFY(1, DAP_FUNC_DESCRIPTOR_DEFINE, ()) LISTIFY(1, DAP_FUNC_FUNCTION_DATA_DEFINE, ()) + +int dap_link_backend_usb_init(struct dap_link_context *const dap_link_ctx) +{ + struct usbd_class_data *const c_data = &dap_func_0; + struct dap_func_data *data = usbd_class_get_private(c_data); + + if (atomic_test_bit(&data->state, SAMPLE_FUNCTION_ENABLED)) { + return -EALREADY; + } + + data->dap_link_ctx = dap_link_ctx; + + return 0; +} From 730880e2662fdf14fa986fabe62a54b83dd57ba4 Mon Sep 17 00:00:00 2001 From: Johann Fischer Date: Wed, 3 Dec 2025 00:16:59 +0100 Subject: [PATCH 1596/3659] doc: migration: add note about DAP subsystem changes Add note about DAP subsystem changes. Keep it general, as there will be more changes. Signed-off-by: Johann Fischer --- doc/releases/migration-guide-4.4.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/releases/migration-guide-4.4.rst b/doc/releases/migration-guide-4.4.rst index 8fbe3e118f89..4ea6622aa085 100644 --- a/doc/releases/migration-guide-4.4.rst +++ b/doc/releases/migration-guide-4.4.rst @@ -545,6 +545,8 @@ Modem HL78XX Other subsystems **************** +* The DAP subsystem initialization and configuration has changed. Please take a look at + :zephyr:code-sample:`cmsis-dap` sample on how to initialize Zephyr DAP Link with USB backend. * Cache From b98fc2740a1fc47775b8713fd5351df1d8aa82bd Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Wed, 17 Dec 2025 16:29:43 -0800 Subject: [PATCH 1597/3659] soc: intel_adsp/ace40: disable spin validation on simulator xt-clang seems to generate some memory access patterns which result in the simulator accessing incorrect memory and/or messing with cached TLB entries when spinlock validation is enabled. Not exactly sure what's going on here due to the core of the simulator is built on top of pre-built binaries provided by the toolchain without any sources so debugging would be nearly impossible. But at least we have an easy workaround by disabling spin lock validation. Fixes #100885 Signed-off-by: Daniel Leung --- soc/intel/intel_adsp/ace/Kconfig.defconfig.ace40 | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/soc/intel/intel_adsp/ace/Kconfig.defconfig.ace40 b/soc/intel/intel_adsp/ace/Kconfig.defconfig.ace40 index 42e584fea695..682b0870b684 100644 --- a/soc/intel/intel_adsp/ace/Kconfig.defconfig.ace40 +++ b/soc/intel/intel_adsp/ace/Kconfig.defconfig.ace40 @@ -35,4 +35,11 @@ config XTENSA_MMU_NUM_L2_TABLES config XTENSA_MMU_USE_DEFAULT_MAPPINGS default n +# xt-clang seems to generate some memory access patterns which +# result in the simulator accessing incorrect memory or +# messing with cached TLB entries when spinlock validation +# is enabled. So disable this to avoid this issue. +config SPIN_VALIDATE + default n if INTEL_ADSP_SIM + endif From 008904d63e868a134c1bcd6b92f8bcaf6215bd41 Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Mon, 22 Dec 2025 16:08:31 +0000 Subject: [PATCH 1598/3659] drivers: can: shell: add can dump subcommand Add "can dump " subcommand for dumping all CAN RX frames of a given CAN controller. Signed-off-by: Henrik Brix Andersen --- drivers/can/can_shell.c | 100 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) diff --git a/drivers/can/can_shell.c b/drivers/can/can_shell.c index 982a790c6ce2..38a98ca65120 100644 --- a/drivers/can/can_shell.c +++ b/drivers/can/can_shell.c @@ -25,6 +25,12 @@ struct can_shell_rx_event { const struct device *dev; }; +struct can_shell_dump_context { + int filter_id_std; + int filter_id_ext; + bool started; +}; + struct can_shell_mode_mapping { const char *name; can_mode_t mode; @@ -64,6 +70,8 @@ static struct k_poll_event can_shell_rx_msgq_events[] = { &can_shell_rx_msgq, 0) }; +static struct can_shell_dump_context can_shell_dump_ctx; + /* Forward declarations */ static void can_shell_tx_msgq_triggered_work_handler(struct k_work *work); static void can_shell_rx_msgq_triggered_work_handler(struct k_work *work); @@ -434,6 +442,94 @@ static int cmd_can_show(const struct shell *sh, size_t argc, char **argv) return 0; } +#define ASCII_CTRL_C 0x03 + +static void can_shell_dump_bypass_cb(const struct shell *sh, uint8_t *data, size_t len, + void *user_data) +{ + const struct device *dev = user_data; + int err; + + for (size_t i = 0; i < len; i++) { + if (data[i] == ASCII_CTRL_C) { + if (can_shell_dump_ctx.started) { + err = can_stop(dev); + if (err != 0) { + shell_error(sh, "failed to stop CAN controller (err %d)", + err); + } + } + + if (can_shell_dump_ctx.filter_id_std >= 0) { + can_remove_rx_filter(dev, can_shell_dump_ctx.filter_id_std); + } + + + if (can_shell_dump_ctx.filter_id_ext >= 0) { + can_remove_rx_filter(dev, can_shell_dump_ctx.filter_id_ext); + } + + shell_set_bypass(sh, NULL, NULL); + return; + } + } +} + +static int cmd_can_dump(const struct shell *sh, size_t argc, char **argv) +{ + const struct device *dev = shell_device_get_binding(argv[1]); + const struct can_filter std_filter = { + .flags = 0U, + .id = 0U, + .mask = 0U + }; + const struct can_filter ext_filter = { + .flags = CAN_FILTER_IDE, + .id = 0U, + .mask = 0U + }; + int err; + + if (!can_device_check(dev)) { + shell_error(sh, "device %s not ready", argv[1]); + return -ENODEV; + } + + err = can_add_rx_filter(dev, can_shell_rx_callback, NULL, &std_filter); + if (err < 0) { + shell_warn(sh, "failed to add standard (11-bit) filter (err %d)", err); + } + can_shell_dump_ctx.filter_id_std = err; + + err = can_add_rx_filter(dev, can_shell_rx_callback, NULL, &ext_filter); + if (err < 0) { + shell_warn(sh, "failed to add extended (29-bit) filter (err %d)", err); + } + can_shell_dump_ctx.filter_id_ext = err; + + err = can_shell_rx_msgq_poll_submit(sh); + if (err != 0) { + shell_error(sh, "failed to start CAN RX message queue polling (err %d)", err); + return err; + } + + can_shell_dump_ctx.started = true; + + err = can_start(dev); + if (err == -EALREADY) { + can_shell_dump_ctx.started = false; + } else if (err != 0) { + shell_error(sh, "failed to start CAN controller (err %d)", err); + return err; + } + + shell_set_bypass(sh, can_shell_dump_bypass_cb, (void *)dev); + + shell_print(sh, "dumping CAN RX frames on device %s, press Ctrl+C to exit", dev->name); + + return 0; +} + static int cmd_can_bitrate_set(const struct shell *sh, size_t argc, char **argv) { const struct device *dev = shell_device_get_binding(argv[1]); @@ -1108,6 +1204,10 @@ SHELL_STATIC_SUBCMD_SET_CREATE(sub_can_cmds, "Manually recover CAN controller from bus-off state\n" "Usage: can recover [timeout ms]", cmd_can_recover, 2, 1), + SHELL_CMD_ARG(dump, &dsub_can_device_name, + "Dump all CAN controller RX frames\n" + "Usage: can dump ", + cmd_can_dump, 2, 0), SHELL_SUBCMD_SET_END ); From b947de920ea68eb727f139ccec29fddb432e9185 Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Sun, 28 Dec 2025 16:00:51 +0000 Subject: [PATCH 1599/3659] doc: hardware: peripherals: can: shell: document can dump subcommand Document the "can dump" subcommand of the CAN shell module. Signed-off-by: Henrik Brix Andersen --- doc/hardware/peripherals/can/shell.rst | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/doc/hardware/peripherals/can/shell.rst b/doc/hardware/peripherals/can/shell.rst index 863a65eaadfb..f9acd293b77d 100644 --- a/doc/hardware/peripherals/can/shell.rst +++ b/doc/hardware/peripherals/can/shell.rst @@ -239,6 +239,18 @@ below). uart:~$ can filter remove can@0 0 removing filter with ID 0 +Another option is to use the ``can dump`` subcommand, which adds standard (11-bit) and extended +(29-bit) CAN filters matching any RX frame, starts the CAN controller, and prints all received CAN +frames to the shell: + +.. code-block:: console + + uart:~$ can dump can@0 + dumping CAN RX frames on device can@0, press Ctrl+C to exit + +After exiting the ``can dump`` subcommand by pressing Ctrl+C, the added filters are automatically +removed and the CAN controller stopped again. + Sending ******* From a2e902b3076e135a6ba9b3b735544f7305ce9046 Mon Sep 17 00:00:00 2001 From: Holt Sun Date: Tue, 30 Dec 2025 21:10:28 +0800 Subject: [PATCH 1600/3659] drivers: counter: mcux_gpt: add devicetree run-mode property Add a "run-mode" devicetree property to the NXP i.MX GPT counter driver to control counter behavior on compare events. The property supports two modes: - "restart": Counter resets to 0 when reaching Compare Channel 1 value - "free-run": Counter continues counting without reset This change makes the GPT run mode configurable per device instance instead of being hardcoded. The driver now derives the enableFreeRun setting from devicetree, defaulting to "restart" mode. This update aligns the GPT driver configuration approach with the NXP LPTMR counter driver, which also uses devicetree properties for runtime behavior configuration. This provides consistency across NXP counter drivers in how hardware behavior is controlled through devicetree. Signed-off-by: Holt Sun --- drivers/counter/counter_mcux_gpt.c | 6 ++++-- dts/bindings/counter/nxp,imx-gpt.yaml | 17 +++++++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/drivers/counter/counter_mcux_gpt.c b/drivers/counter/counter_mcux_gpt.c index 222f9615c9ce..934aca21657b 100644 --- a/drivers/counter/counter_mcux_gpt.c +++ b/drivers/counter/counter_mcux_gpt.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2019, Linaro Limited. - * Copyright 2024 NXP + * Copyright 2024-2025 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -27,6 +27,7 @@ struct mcux_gpt_config { const struct device *clock_dev; clock_control_subsys_t clock_subsys; + bool enable_free_run; void (*irq_config_func)(void); }; @@ -204,7 +205,7 @@ static int mcux_gpt_init(const struct device *dev) } GPT_GetDefaultConfig(&gptConfig); - gptConfig.enableFreeRun = true; /* Do not reset on compare */ + gptConfig.enableFreeRun = config->enable_free_run; gptConfig.clockSource = kGPT_ClockSource_Periph; gptConfig.divider = clock_freq / config->info.freq; base = get_base(dev); @@ -235,6 +236,7 @@ static DEVICE_API(counter, mcux_gpt_driver_api) = { .clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(n)), \ .clock_subsys = \ (clock_control_subsys_t)DT_INST_CLOCKS_CELL(n, name),\ + .enable_free_run = (DT_INST_ENUM_IDX_OR(n, run_mode, 0) == 1),\ .info = { \ .max_top_value = UINT32_MAX, \ .freq = DT_INST_PROP(n, gptfreq), \ diff --git a/dts/bindings/counter/nxp,imx-gpt.yaml b/dts/bindings/counter/nxp,imx-gpt.yaml index 4d1aac49c14a..07afd874576c 100644 --- a/dts/bindings/counter/nxp,imx-gpt.yaml +++ b/dts/bindings/counter/nxp,imx-gpt.yaml @@ -1,4 +1,5 @@ # Copyright (c) 2018 Nordic Semiconductor ASA +# Copyright 2025 NXP # SPDX-License-Identifier: Apache-2.0 description: NXP MCUX General-Purpose Timer (GPT) @@ -18,3 +19,19 @@ properties: type: int required: true description: gpt frequencies + + run-mode: + type: string + description: | + Selects how the GPT counter behaves on compare events. + - restart(default): When the counter reaches the Compare Channel 1 value, + the counter resets to 0x00000000 and starts counting again. + - free-run: Compare events do not reset the counter. + Notes: + - This driver uses Compare Channel 1 for the Zephyr counter alarm. + - With restart, using alarms may cause the counter to reset at the + alarm compare point. + enum: + - restart + - free-run + default: restart From 6623fbcb6f0563bd95aaac4da64f68a82a63f9e7 Mon Sep 17 00:00:00 2001 From: Holt Sun Date: Thu, 1 Jan 2026 11:13:31 +0800 Subject: [PATCH 1601/3659] doc: releases: migration-guide-4.4: add GPT counter run-mode change Document the breaking change in the NXP i.MX GPT counter driver that introduces a devicetree "run-mode" property and changes the default from hardcoded free-run to restart mode. Out-of-tree boards must add `run-mode = "free-run";` to their GPT devicetree nodes to preserve previous behavior. This change aligns GPT configuration with the LPTMR driver, providing consistency across NXP counter drivers in using devicetree properties for hardware behavior control. Signed-off-by: Holt Sun --- doc/releases/migration-guide-4.4.rst | 38 ++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/doc/releases/migration-guide-4.4.rst b/doc/releases/migration-guide-4.4.rst index 4ea6622aa085..8ecfa9e17943 100644 --- a/doc/releases/migration-guide-4.4.rst +++ b/doc/releases/migration-guide-4.4.rst @@ -237,6 +237,44 @@ Counter resolution = <16>; }; +* The NXP i.MX GPT counter driver (:dtcompatible:`nxp,imx-gpt`) now + defaults to ``run-mode = "restart"`` instead of the previous hardcoded free-run behavior. + + * **Previous behavior** (Zephyr ≤ 4.3): GPT counter always ran in free-run mode + (``enableFreeRun = true``). The counter continued counting without reset on compare events. + + * **New behavior** (Zephyr ≥ 4.4): GPT counter defaults to restart mode unless explicitly + configured. A new ``run-mode`` devicetree property controls the behavior: + + * ``"restart"`` (default): Counter resets to 0 when reaching Compare Channel 1 value + * ``"free-run"``: Counter continues counting without reset (previous behavior) + + **Migration Required**: Out-of-tree boards and applications using GPT counters must add + ``run-mode = "free-run";`` to their devicetree nodes to preserve the previous behavior. + + .. code-block:: devicetree + + /* Out-of-tree boards: add this to preserve previous behavior */ + gpt2: gpt@400f0000 { + compatible = "nxp,imx-gpt"; + /* Explicitly restore Zephyr ≤4.3 behavior */ + run-mode = "free-run"; + /* ... other properties ... */ + }; + + .. warning:: + + The driver uses Compare Channel 1 for Zephyr counter alarm functionality. When using + ``run-mode = "restart"``, setting alarms will cause the counter to reset at the alarm + compare point. If your application relies on alarms and continuous counting, you must + use ``run-mode = "free-run"``. + + .. note:: + + This change standardizes NXP counter driver run mode configuration. + GPT now uses explicit devicetree properties rather than hardcoded values, allowing + per-instance customization. + EEPROM ====== From ba24cc36e5148564262843992ef671ab7b97f17b Mon Sep 17 00:00:00 2001 From: Lucien Zhao Date: Tue, 6 Jan 2026 18:08:12 +0800 Subject: [PATCH 1602/3659] dts: arm: nxp_mcxe24x_common.dtsi: update clk-source - Update clk-source to 1 for all flexcan instances because we need to use sysclk as PE clock source and reduce customer's confused when configuring flexcan clock If user use a fast external osc and want to choose another choice, user can change it in overlay files Signed-off-by: Lucien Zhao --- dts/arm/nxp/nxp_mcxe24x_common.dtsi | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dts/arm/nxp/nxp_mcxe24x_common.dtsi b/dts/arm/nxp/nxp_mcxe24x_common.dtsi index 9f01ee385ef3..35a2b1a1e0e4 100644 --- a/dts/arm/nxp/nxp_mcxe24x_common.dtsi +++ b/dts/arm/nxp/nxp_mcxe24x_common.dtsi @@ -291,7 +291,7 @@ "mb-0-15", "mb-16-31"; clocks = <&scg KINETIS_SCG_CORESYS_CLK>; - clk-source = <0>; + clk-source = <1>; status = "disabled"; }; @@ -301,7 +301,7 @@ interrupts = <85 0>, <86 0>, <88 0>, <89 0>; interrupt-names = "ored-warning-bus-off", "error", "mb-0-15", "mb-16-31"; clocks = <&scg KINETIS_SCG_CORESYS_CLK>; - clk-source = <0>; + clk-source = <1>; status = "disabled"; }; @@ -311,7 +311,7 @@ interrupts = <92 0>, <93 0>, <95 0>, <96 0>; interrupt-names = "ored-warning-bus-off", "error", "mb-0-15", "mb-16-31"; clocks = <&scg KINETIS_SCG_CORESYS_CLK>; - clk-source = <0>; + clk-source = <1>; status = "disabled"; }; From f2653dc523d96aba71df244b0402e8d8bbddc936 Mon Sep 17 00:00:00 2001 From: Lucien Zhao Date: Mon, 5 Jan 2026 16:11:40 +0800 Subject: [PATCH 1603/3659] boards: nxp: frdm_mcxe247: add flexcan0 support - config flexcan0 pinmux - enable flexcan0 instance - add three flexcan clock enablement code Signed-off-by: Lucien Zhao --- boards/nxp/frdm_mcxe247/board.c | 9 +++++++++ boards/nxp/frdm_mcxe247/doc/index.rst | 4 ++++ boards/nxp/frdm_mcxe247/frdm_mcxe247-pinctrl.dtsi | 10 ++++++++++ boards/nxp/frdm_mcxe247/frdm_mcxe247.dts | 6 ++++++ boards/nxp/frdm_mcxe247/frdm_mcxe247.yaml | 1 + 5 files changed, 30 insertions(+) diff --git a/boards/nxp/frdm_mcxe247/board.c b/boards/nxp/frdm_mcxe247/board.c index a0cb98d6f7d6..939fa2b8e24c 100644 --- a/boards/nxp/frdm_mcxe247/board.c +++ b/boards/nxp/frdm_mcxe247/board.c @@ -181,6 +181,15 @@ __weak void clock_init(void) CLOCK_GetCurSysClkConfig(¤t); } while (current.src != scg_sys_clk_config.src); +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(flexcan0)) + CLOCK_EnableClock(kCLOCK_Can0); +#endif +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(flexcan1)) + CLOCK_EnableClock(kCLOCK_Can1); +#endif +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(flexcan2)) + CLOCK_EnableClock(kCLOCK_Can2); +#endif #if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(lpuart0)) CLOCK_SetIpSrc(kCLOCK_Lpuart0, DT_CLOCKS_CELL(DT_NODELABEL(lpuart0), ip_source)); diff --git a/boards/nxp/frdm_mcxe247/doc/index.rst b/boards/nxp/frdm_mcxe247/doc/index.rst index 0103adc7dfca..ad140b730f6d 100644 --- a/boards/nxp/frdm_mcxe247/doc/index.rst +++ b/boards/nxp/frdm_mcxe247/doc/index.rst @@ -76,6 +76,10 @@ PORTB/GPIOB, PORTC/GPIOC, PORTD/GPIOD, and PORTE/GPIOE). +-------+-------------+---------------------------+ | PTA0 | CMP0 | CMP0 IN 0 | +-------+-------------+---------------------------+ +| PTE5 | FLEXCAN0 | CAN0 TX | ++-------+-------------+---------------------------+ +| PTE4 | FLEXCAN0 | CAN0 RX | ++-------+-------------+---------------------------+ System Clock ============ diff --git a/boards/nxp/frdm_mcxe247/frdm_mcxe247-pinctrl.dtsi b/boards/nxp/frdm_mcxe247/frdm_mcxe247-pinctrl.dtsi index c183221437fb..42aa5471decb 100644 --- a/boards/nxp/frdm_mcxe247/frdm_mcxe247-pinctrl.dtsi +++ b/boards/nxp/frdm_mcxe247/frdm_mcxe247-pinctrl.dtsi @@ -74,4 +74,14 @@ slew-rate = "fast"; }; }; + + pinmux_flexcan0: pinmux_flexcan0 { + group0 { + pinmux = , + ; + slew-rate = "fast"; + drive-strength = "low"; + input-enable; + }; + }; }; diff --git a/boards/nxp/frdm_mcxe247/frdm_mcxe247.dts b/boards/nxp/frdm_mcxe247/frdm_mcxe247.dts index 9207f2088820..c499e331ba1d 100644 --- a/boards/nxp/frdm_mcxe247/frdm_mcxe247.dts +++ b/boards/nxp/frdm_mcxe247/frdm_mcxe247.dts @@ -160,6 +160,12 @@ clock-div = <1>; }; +&flexcan0 { + pinctrl-0 = <&pinmux_flexcan0>; + pinctrl-names = "default"; + status = "okay"; +}; + &soscdiv2_clk { clock-div = <1>; }; diff --git a/boards/nxp/frdm_mcxe247/frdm_mcxe247.yaml b/boards/nxp/frdm_mcxe247/frdm_mcxe247.yaml index effc11e7ac87..bae8bf5bfedf 100644 --- a/boards/nxp/frdm_mcxe247/frdm_mcxe247.yaml +++ b/boards/nxp/frdm_mcxe247/frdm_mcxe247.yaml @@ -15,6 +15,7 @@ toolchain: - gnuarmemb supported: - adc + - can - uart - i2c - spi From 2669090ce34ddd1212cfd403eaf9e39cc2c227a2 Mon Sep 17 00:00:00 2001 From: Lucien Zhao Date: Mon, 5 Jan 2026 16:12:59 +0800 Subject: [PATCH 1604/3659] test: drivers: can: support can cases on frdm-mcxe247 - Support can test case: api/shell/timing - Tese passed for three cases on my local Signed-off-by: Lucien Zhao --- tests/drivers/can/timing/boards/frdm_mcxe247.conf | 1 + 1 file changed, 1 insertion(+) create mode 100644 tests/drivers/can/timing/boards/frdm_mcxe247.conf diff --git a/tests/drivers/can/timing/boards/frdm_mcxe247.conf b/tests/drivers/can/timing/boards/frdm_mcxe247.conf new file mode 100644 index 000000000000..7b071f3a54f5 --- /dev/null +++ b/tests/drivers/can/timing/boards/frdm_mcxe247.conf @@ -0,0 +1 @@ +CONFIG_TEST_ALL_BITRATES=y From 0d8c876448276fd7e9bdbc85cb44bb70789222a1 Mon Sep 17 00:00:00 2001 From: Muhammad Waleed Badar Date: Thu, 8 Jan 2026 15:20:34 +0500 Subject: [PATCH 1605/3659] doc: releases: v4.4: add pl011 uart poll_in changes Add changes for pl011 uart poll_in function Signed-off-by: Muhammad Waleed Badar --- doc/releases/migration-guide-4.4.rst | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/doc/releases/migration-guide-4.4.rst b/doc/releases/migration-guide-4.4.rst index 8ecfa9e17943..aec21a8c759f 100644 --- a/doc/releases/migration-guide-4.4.rst +++ b/doc/releases/migration-guide-4.4.rst @@ -612,6 +612,14 @@ Tracing With this change, existing CTF traces with 8-bit IDs won't be compatible. +Serial +======== + +* pl011 UART driver: Remove Read Status Register (RSR) error handling + from :c:func:`pl011_poll_in`. RSR handling is already implemented in + :c:func:`pl011_err_check`, which is the appropriate place to detect, + and report receive error conditions. (:github:`101715`) + Settings ======== From c97ccba142d3e9f5a243f916582f64e0998df850 Mon Sep 17 00:00:00 2001 From: Tom Burdick Date: Thu, 8 Jan 2026 12:19:35 -0600 Subject: [PATCH 1606/3659] twister: Support kitprog when generating hw map Hardware map file generation should at least get you part way now with Infineon boards with the Cypress derived KitProg3. Signed-off-by: Tom Burdick --- scripts/pylib/twister/twisterlib/hardwaremap.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/pylib/twister/twisterlib/hardwaremap.py b/scripts/pylib/twister/twisterlib/hardwaremap.py index 4f83daf26dec..6bbf22099c32 100644 --- a/scripts/pylib/twister/twisterlib/hardwaremap.py +++ b/scripts/pylib/twister/twisterlib/hardwaremap.py @@ -148,6 +148,7 @@ class HardwareMap: 'Nuvoton', 'Espressif', 'SecuringHardware.com', + 'Cypress Semiconductor' ] runner_mapping = { @@ -160,7 +161,7 @@ class HardwareMap: 'J-Link OB' ], 'openocd': [ - 'STM32 STLink', '^XDS110.*', 'STLINK-V3', '^Tigard.*' + 'STM32 STLink', '^XDS110.*', 'STLINK-V3', '^Tigard.*', 'KitProg3' ], 'dediprog': [ 'TTL232R-3V3', From 769ac1b112e16408ac2244e3b4af747d11761f6b Mon Sep 17 00:00:00 2001 From: Tom Burdick Date: Thu, 8 Jan 2026 13:58:51 -0600 Subject: [PATCH 1607/3659] ci: Drop preemptible||preemptable spellcheck Preemptable and preemptible are both commonly used spellings. Infineon had chosen preemptable as the spelling and lead to CI failures when using struct members in the PDL. Removing the check in Zephyr allows for flexibility in spellings of this word. Signed-off-by: Tom Burdick --- scripts/spelling.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/spelling.txt b/scripts/spelling.txt index 9302fd19ade4..9bccbde010d0 100644 --- a/scripts/spelling.txt +++ b/scripts/spelling.txt @@ -1194,7 +1194,6 @@ preceeding||preceding preceed||precede precendence||precedence precission||precision -preemptable||preemptible prefered||preferred prefferably||preferably prefitler||prefilter From b14f7e9e9f6d40db73b3b8d16619890e88400ac2 Mon Sep 17 00:00:00 2001 From: Gaetan Perrot Date: Fri, 9 Jan 2026 02:08:02 +0900 Subject: [PATCH 1608/3659] drivers: rtc: ds3231: drop impossible negative id check rtc_ds3231_alarm_set_callback() takes an unsigned alarm id, making the negative value check impossible. The id < 0 condition is therefore dead code and can never be true. Remove it and keep only the upper bound check. No functional change intended. Signed-off-by: Gaetan Perrot --- drivers/rtc/rtc_ds3231.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/rtc/rtc_ds3231.c b/drivers/rtc/rtc_ds3231.c index 45beac1fbab2..d24bddf9c424 100644 --- a/drivers/rtc/rtc_ds3231.c +++ b/drivers/rtc/rtc_ds3231.c @@ -608,7 +608,7 @@ static int rtc_ds3231_get_alarm_states(const struct device *dev, bool *states) static int rtc_ds3231_alarm_set_callback(const struct device *dev, uint16_t id, rtc_alarm_callback cb, void *user_data) { - if (id < 0 || id >= ALARM_COUNT) { + if (id >= ALARM_COUNT) { return -EINVAL; } From 4655fa18d43c2063018121a2011fe774ef49bf72 Mon Sep 17 00:00:00 2001 From: Gaetan Perrot Date: Fri, 9 Jan 2026 09:04:35 +0900 Subject: [PATCH 1609/3659] drivers: video: ov7725: fix uninitialized struct Fix uninitialized struct fmt to fix Coverity issue. CID: 524756 Signed-off-by: Gaetan Perrot --- drivers/video/ov7725.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/video/ov7725.c b/drivers/video/ov7725.c index eff4b21519fc..2b8d4d882ed6 100644 --- a/drivers/video/ov7725.c +++ b/drivers/video/ov7725.c @@ -549,7 +549,11 @@ static DEVICE_API(video, ov7725_driver_api) = { static int ov7725_init(const struct device *dev) { const struct ov7725_config *cfg = dev->config; - struct video_format fmt; + struct video_format fmt = { + .pixelformat = VIDEO_PIX_FMT_RGB565, + .width = 640, + .height = 480, + }; uint8_t pid, ver; int ret; @@ -588,10 +592,6 @@ static int ov7725_init(const struct device *dev) k_sleep(K_MSEC(2)); - /* set default/init format VGA RGB565 */ - fmt.pixelformat = VIDEO_PIX_FMT_RGB565; - fmt.width = 640; - fmt.height = 480; ret = ov7725_set_fmt(dev, &fmt); if (ret) { LOG_ERR("Unable to configure default format"); From a0c17db18e257be32db5c21d77b3690be4b277a1 Mon Sep 17 00:00:00 2001 From: Gaetan Perrot Date: Fri, 9 Jan 2026 15:58:09 +0900 Subject: [PATCH 1610/3659] drivers: video: remove redundant rad_val initialization Remove the unused initialization without changing behavior. Signed-off-by: Gaetan Perrot --- drivers/video/ov5640.c | 3 +-- drivers/video/ov5642.c | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/video/ov5640.c b/drivers/video/ov5640.c index 6da406d40660..f7e3b080b799 100644 --- a/drivers/video/ov5640.c +++ b/drivers/video/ov5640.c @@ -892,14 +892,13 @@ static int ov5640_set_ctrl_hue(const struct device *dev, int value) const struct ov5640_config *cfg = dev->config; int cos_coef, sin_coef, sign = 0; - double rad_val = value; + double rad_val = value * PI / 180.0; int ret = video_modify_cci_reg(&cfg->i2c, OV5640_REG8(SDE_CTRL0_REG), BIT(0), BIT(0)); if (ret) { return ret; } - rad_val = value * PI / 180.0; cos_coef = round(cos(rad_val) * 128); sin_coef = round(sin(rad_val) * 128); diff --git a/drivers/video/ov5642.c b/drivers/video/ov5642.c index 57d668cb85ec..95ab5a53be76 100644 --- a/drivers/video/ov5642.c +++ b/drivers/video/ov5642.c @@ -606,7 +606,7 @@ static int ov5642_set_ctrl_hue(const struct device *dev, int value) { const struct ov5642_config *cfg = dev->config; int cos_coef, sin_coef, sign = 0; - double rad_val = value; + double rad_val = value * PI / 180.0; int ret; ret = video_modify_cci_reg(&cfg->i2c, SDE_CTRL0_CCI, BIT(0), BIT(0)); @@ -614,7 +614,6 @@ static int ov5642_set_ctrl_hue(const struct device *dev, int value) return ret; } - rad_val = value * PI / 180.0; cos_coef = round(cos(rad_val) * 128); sin_coef = round(sin(rad_val) * 128); From f241ecedec03c5656c6661353bacbf382e81f921 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Thu, 8 Jan 2026 14:34:27 +0100 Subject: [PATCH 1611/3659] boards: nordic: nrf54h20dk: rm hfxo/lfxo from common dtsi The hfxo and lfxo should only be enabled for the cpuapp and cpurad as these cores are the only ones which have access to the clock. Leaving it enabled will break cpuppr and cpuflpr builds if CONFIG_CLOCK_CONTROL is enabled as the drivers are not compatible. Signed-off-by: Bjarki Arge Andreasen --- boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20-common.dtsi | 5 ----- boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts | 8 ++++++++ boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpurad.dts | 8 ++++++++ 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20-common.dtsi b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20-common.dtsi index b0cb997de947..72d78b9c739c 100644 --- a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20-common.dtsi +++ b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20-common.dtsi @@ -9,13 +9,8 @@ #include "nrf54h20dk_nrf54h20-pinctrl.dtsi" &hfxo { - status = "okay"; accuracy-ppm = <30>; }; -&lfxo { - status = "okay"; -}; - /* Get a node label for wi-fi spi to use in shield files */ wifi_spi: &spi130 {}; diff --git a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts index 901ed2939111..c534e1bd91c8 100644 --- a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts +++ b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts @@ -323,6 +323,14 @@ zephyr_udc0: &usbhs { pinctrl-names = "default"; }; +&hfxo { + status = "okay"; +}; + +&lfxo { + status = "okay"; +}; + &pwm130 { status = "okay"; pinctrl-0 = <&pwm130_default>; diff --git a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpurad.dts b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpurad.dts index ef5698d139ef..2bdf0cda9a10 100644 --- a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpurad.dts +++ b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpurad.dts @@ -95,6 +95,14 @@ slot1_partition: &cpurad_slot1_partition { status = "okay"; }; +&hfxo { + status = "okay"; +}; + +&lfxo { + status = "okay"; +}; + &uart135 { status = "okay"; memory-regions = <&cpurad_dma_region>; From 4c0b2622a60dac127b8ec134b672a48e246c5057 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Thu, 8 Jan 2026 15:18:18 +0100 Subject: [PATCH 1612/3659] drivers: can: can_nrf: add missing soc.h include The can_nrf driver uses defines from soc.h which happened to be included by some other header when building for cpuapp, but not when building for cpuflpr. Include soc.h explicitly. Signed-off-by: Bjarki Arge Andreasen --- drivers/can/can_nrf.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/can/can_nrf.c b/drivers/can/can_nrf.c index fa287b301ed1..4e427dcbd129 100644 --- a/drivers/can/can_nrf.c +++ b/drivers/can/can_nrf.c @@ -16,6 +16,7 @@ #include #include #include +#include /* nRF CAN wrapper offsets */ #define CAN_TASKS_START offsetof(NRF_CAN_Type, TASKS_START) From a7cea5d58aca570a57410a867d18ff272f95fc5c Mon Sep 17 00:00:00 2001 From: Nakul Chauhan Date: Mon, 12 Jan 2026 14:38:15 +0530 Subject: [PATCH 1613/3659] native_simulator: Get latest from upstream Align with native_simulator's upstream main 215ee859eee5e49dc09eda8f17a956ee7318caf2 Which includes: 215ee85: native timer_model: Fix printf format specifier warnings w debug logs Signed-off-by: Nakul Chauhan Signed-off-by: Alberto Escolar Piedras --- scripts/native_simulator/native/src/timer_model.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/scripts/native_simulator/native/src/timer_model.c b/scripts/native_simulator/native/src/timer_model.c index ebe5498dfb1a..bbf457bc683d 100644 --- a/scripts/native_simulator/native/src/timer_model.c +++ b/scripts/native_simulator/native/src/timer_model.c @@ -15,6 +15,7 @@ */ #include +#include #include #include #include @@ -190,8 +191,8 @@ static void hwtimer_tick_timer_reached(void) us_time_to_str(es, expected_rt - boot_time); us_time_to_str(rs, real_time - boot_time); - printf("tick @%5llims: diff = expected_rt - real_time = " - "%5lli = %s - %s\n", + printf("tick @%5"PRIu64"ms: diff = expected_rt - real_time = " + "%5"PRIi64" = %s - %s\n", hw_timer_tick_timer/1000U, diff, es, rs); #endif @@ -325,7 +326,7 @@ void hwtimer_adjust_rt_ratio(double ratio_correction) last_drift_offset += r_drift; us_time_to_str(ct, current_stime); - printf("%s(): @%s, s_diff= %llius after last adjust\n" + printf("%s(): @%s, s_diff= %"PRIi64"us after last adjust\n" " during which we drifted %.3fms\n" " total acc drift (last_drift_offset) = %.3fms\n" " last_radj_rtime = %.3fms (+%.3fms )\n" From 65f43b919e5c9a9a32daab0729e40baf318a2166 Mon Sep 17 00:00:00 2001 From: Gaetan Perrot Date: Sat, 10 Jan 2026 02:38:39 +0900 Subject: [PATCH 1614/3659] drivers: videos: ov767x: fix typos in comments Fix typos in comments in ov767x_init_regtbl. No functional change. Signed-off-by: Gaetan Perrot --- drivers/video/ov767x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/video/ov767x.c b/drivers/video/ov767x.c index b92c1765a09b..4aeed182aff6 100644 --- a/drivers/video/ov767x.c +++ b/drivers/video/ov767x.c @@ -256,7 +256,7 @@ static const struct video_reg8 ov767x_init_regtbl[] = { {OV767X_COM13, 0x80}, /* Common Control 13 */ {OV767X_MANU, 0x11}, /* Manual U Value */ {OV767X_MANV, 0xFF}, /* Manual V Value */ - /* config the output window data, this can be configed later */ + /* config the output window data, this can be configured later */ {OV767X_HSTART, 0x15}, /* HSTART */ {OV767X_HSTOP, 0x03}, /* HSTOP */ {OV767X_VSTRT, 0x02}, /* VSTRT */ From d9015cf5d02796081f77828e8d81252c58852ce5 Mon Sep 17 00:00:00 2001 From: Ravi Dondaputi Date: Mon, 8 Sep 2025 18:42:08 +0530 Subject: [PATCH 1615/3659] drivers: wifi: nrf_wifi: Set SSID for P2P discovery Use `ssids` instead of `filter_ssids` to set the SSID in probe requests. `filter_ssids` are to filter scan results to include only the specified SSIDs. Signed-off-by: Ravi Dondaputi --- drivers/wifi/nrf_wifi/src/wpa_supp_if.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/wifi/nrf_wifi/src/wpa_supp_if.c b/drivers/wifi/nrf_wifi/src/wpa_supp_if.c index f913558ffea5..1421062cb230 100644 --- a/drivers/wifi/nrf_wifi/src/wpa_supp_if.c +++ b/drivers/wifi/nrf_wifi/src/wpa_supp_if.c @@ -545,16 +545,16 @@ int nrf_wifi_wpa_supp_scan2(void *if_priv, struct wpa_driver_scan_params *params scan_info->scan_params.num_scan_channels = indx; } - if (params->filter_ssids) { - scan_info->scan_params.num_scan_ssids = params->num_filter_ssids; + if (params->num_ssids) { + scan_info->scan_params.num_scan_ssids = params->num_ssids; - for (indx = 0; indx < params->num_filter_ssids; indx++) { + for (indx = 0; indx < params->num_ssids; indx++) { memcpy(scan_info->scan_params.scan_ssids[indx].nrf_wifi_ssid, - params->filter_ssids[indx].ssid, - params->filter_ssids[indx].ssid_len); + params->ssids[indx].ssid, + params->ssids[indx].ssid_len); scan_info->scan_params.scan_ssids[indx].nrf_wifi_ssid_len = - params->filter_ssids[indx].ssid_len; + params->ssids[indx].ssid_len; } } From 3ac9a46aba295f24077a2968123093ddc6ccc593 Mon Sep 17 00:00:00 2001 From: Ravi Dondaputi Date: Tue, 14 Oct 2025 12:09:51 +0530 Subject: [PATCH 1616/3659] drivers: wifi: nrf_wifi: Set P2P capability In P2P mode, inform supplicant that the driver is P2P capable. Signed-off-by: Ravi Dondaputi --- drivers/wifi/nrf_wifi/src/wpa_supp_if.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/wifi/nrf_wifi/src/wpa_supp_if.c b/drivers/wifi/nrf_wifi/src/wpa_supp_if.c index 1421062cb230..da63be115cdd 100644 --- a/drivers/wifi/nrf_wifi/src/wpa_supp_if.c +++ b/drivers/wifi/nrf_wifi/src/wpa_supp_if.c @@ -1798,6 +1798,9 @@ int nrf_wifi_supp_get_capa(void *if_priv, struct wpa_driver_capa *capa) if (IS_ENABLED(CONFIG_NRF70_AP_MODE)) { capa->flags |= WPA_DRIVER_FLAGS_AP; } + if (IS_ENABLED(CONFIG_NRF70_P2P_MODE)) { + capa->flags |= WPA_DRIVER_FLAGS_P2P_CAPABLE; + } capa->enc |= WPA_DRIVER_CAPA_ENC_WEP40 | WPA_DRIVER_CAPA_ENC_WEP104 | From 84db77c46b1d18b3c226d501fbf2709f9773634f Mon Sep 17 00:00:00 2001 From: Kapil Bhatt Date: Thu, 9 Oct 2025 17:16:51 +0000 Subject: [PATCH 1617/3659] net: wifi: Add Wi-Fi direct P2P discovery API support Add supplicant api and mgmt ops support for P2P discovery. Signed-off-by: Kapil Bhatt --- include/zephyr/net/wifi_mgmt.h | 126 ++++++++++++++- modules/hostap/src/supp_api.c | 254 +++++++++++++++++++++++++++++++ modules/hostap/src/supp_api.h | 12 ++ modules/hostap/src/supp_events.c | 54 ++++++- modules/hostap/src/supp_events.h | 7 + modules/hostap/src/supp_main.c | 9 ++ subsys/net/l2/wifi/Kconfig | 9 ++ subsys/net/l2/wifi/wifi_mgmt.c | 29 ++++ 8 files changed, 497 insertions(+), 3 deletions(-) diff --git a/include/zephyr/net/wifi_mgmt.h b/include/zephyr/net/wifi_mgmt.h index 817a4fcd6fb6..ef0a6bac27cf 100644 --- a/include/zephyr/net/wifi_mgmt.h +++ b/include/zephyr/net/wifi_mgmt.h @@ -139,6 +139,8 @@ enum net_request_wifi_cmd { NET_REQUEST_WIFI_CMD_BSS_MAX_IDLE_PERIOD, /** Configure background scanning */ NET_REQUEST_WIFI_CMD_BGSCAN, + /** Wi-Fi Direct (P2P) operations*/ + NET_REQUEST_WIFI_CMD_P2P_OPER, /** @cond INTERNAL_HIDDEN */ NET_REQUEST_WIFI_CMD_MAX /** @endcond */ @@ -339,6 +341,11 @@ NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_WIFI_BSS_MAX_IDLE_PERIOD); NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_WIFI_BGSCAN); +#define NET_REQUEST_WIFI_P2P_OPER \ + (NET_WIFI_BASE | NET_REQUEST_WIFI_CMD_P2P_OPER) + +NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_WIFI_P2P_OPER); + /** @cond INTERNAL_HIDDEN */ enum { @@ -359,7 +366,7 @@ enum { NET_EVENT_WIFI_CMD_AP_STA_CONNECTED_VAL, NET_EVENT_WIFI_CMD_AP_STA_DISCONNECTED_VAL, NET_EVENT_WIFI_CMD_SUPPLICANT_VAL, - + NET_EVENT_WIFI_CMD_P2P_DEVICE_FOUND_VAL, NET_EVENT_WIFI_CMD_MAX, }; @@ -406,6 +413,8 @@ enum net_event_wifi_cmd { NET_MGMT_CMD(NET_EVENT_WIFI_CMD_AP_STA_DISCONNECTED), /** Supplicant specific event */ NET_MGMT_CMD(NET_EVENT_WIFI_CMD_SUPPLICANT), + /** P2P device found */ + NET_MGMT_CMD(NET_EVENT_WIFI_CMD_P2P_DEVICE_FOUND), }; /** Event emitted for Wi-Fi scan result */ @@ -468,6 +477,51 @@ enum net_event_wifi_cmd { #define NET_EVENT_WIFI_AP_STA_DISCONNECTED \ (NET_WIFI_EVENT | NET_EVENT_WIFI_CMD_AP_STA_DISCONNECTED) +/** Event emitted for P2P device found event */ +#define NET_EVENT_WIFI_P2P_DEVICE_FOUND \ + (NET_WIFI_EVENT | NET_EVENT_WIFI_CMD_P2P_DEVICE_FOUND) + +#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P +/** Maximum length for P2P device name */ +#define WIFI_P2P_DEVICE_NAME_MAX_LEN 32 +/** Size of P2P primary device type (8 bytes) */ +#define WIFI_P2P_PRI_DEV_TYPE_SIZE 8 +/** Maximum length for P2P primary device type string */ +#define WIFI_P2P_PRI_DEV_TYPE_STR_MAX_LEN 32 +/** Maximum length for P2P WPS configuration methods string */ +#define WIFI_P2P_CONFIG_METHODS_STR_MAX_LEN 16 +/** Maximum length for P2P manufacturer name */ +#define WIFI_P2P_MANUFACTURER_MAX_LEN 64 +/** Maximum length for P2P model name */ +#define WIFI_P2P_MODEL_NAME_MAX_LEN 32 + +/** @brief Wi-Fi P2P device info */ +struct wifi_p2p_device_info { + /** Device MAC address */ + uint8_t mac[WIFI_MAC_ADDR_LEN]; + /** Device name (max 32 chars + null terminator) */ + char device_name[WIFI_P2P_DEVICE_NAME_MAX_LEN + 1]; + /** Primary device type */ + uint8_t pri_dev_type[WIFI_P2P_PRI_DEV_TYPE_SIZE]; + /** Primary device type string */ + char pri_dev_type_str[WIFI_P2P_PRI_DEV_TYPE_STR_MAX_LEN]; + /** Signal strength (RSSI) */ + int8_t rssi; + /** WPS configuration methods supported */ + uint16_t config_methods; + /** WPS configuration methods string */ + char config_methods_str[WIFI_P2P_CONFIG_METHODS_STR_MAX_LEN]; + /** Device capability */ + uint8_t dev_capab; + /** Group capability */ + uint8_t group_capab; + /** Manufacturer (max 64 chars + null terminator) */ + char manufacturer[WIFI_P2P_MANUFACTURER_MAX_LEN + 1]; + /** Model name (max 32 chars + null terminator) */ + char model_name[WIFI_P2P_MODEL_NAME_MAX_LEN + 1]; +}; +#endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P */ + /** @brief Wi-Fi version */ struct wifi_version { /** Driver version */ @@ -1114,6 +1168,9 @@ union wifi_mgmt_events { #endif /* CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS */ struct wifi_twt_params twt_params; struct wifi_ap_sta_info ap_sta_info; +#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P + struct wifi_p2p_device_info p2p_device_info; +#endif }; /** @endcond */ @@ -1397,6 +1454,51 @@ struct wifi_wps_config_params { char pin[WIFI_WPS_PIN_MAX_LEN + 1]; }; +#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P +/** Wi-Fi P2P operation */ +enum wifi_p2p_op { + /** P2P find/discovery */ + WIFI_P2P_FIND = 0, + /** P2P stop find/discovery */ + WIFI_P2P_STOP_FIND, + /** P2P query peer info use broadcast MAC (ff:ff:ff:ff:ff:ff) to list all peers, + * or specific MAC address to query a single peer + */ + WIFI_P2P_PEER, +}; + +/** Wi-Fi P2P discovery type */ +enum wifi_p2p_discovery_type { + /** Start with full scan, then only social channels */ + WIFI_P2P_FIND_START_WITH_FULL = 0, + /** Only social channels (1, 6, 11) */ + WIFI_P2P_FIND_ONLY_SOCIAL, + /** Progressive - scan through all channels one at a time */ + WIFI_P2P_FIND_PROGRESSIVE, +}; + +/** Maximum number of P2P peers that can be returned in a single query */ +#define WIFI_P2P_MAX_PEERS CONFIG_WIFI_P2P_MAX_PEERS + +/** Wi-Fi P2P parameters */ +struct wifi_p2p_params { + /** P2P operation */ + enum wifi_p2p_op oper; + /** Discovery type (for find operation) */ + enum wifi_p2p_discovery_type discovery_type; + /** Timeout in seconds (0 = no timeout, run until stopped) */ + uint16_t timeout; + /** Peer device address (for peer operation) */ + uint8_t peer_addr[WIFI_MAC_ADDR_LEN]; + /** Flag to list only discovered peers (for peers operation) */ + bool discovered_only; + /** Pointer to array for peer info results */ + struct wifi_p2p_device_info *peers; + /** Actual number of peers returned */ + uint16_t peer_count; +}; +#endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P */ + /** Wi-Fi AP status */ enum wifi_sap_iface_state { @@ -1785,6 +1887,17 @@ struct wifi_mgmt_ops { */ int (*set_bgscan)(const struct device *dev, struct wifi_bgscan_params *params); #endif +#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P + /** Wi-Fi Direct (P2P) operations for device discovery + * + * @param dev Pointer to the device structure for the driver instance. + * @param params P2P operation parameters including operation type, discovery settings, + * timeout values and peer information retrieval options + * + * @return 0 if ok, < 0 if error + */ + int (*p2p_oper)(const struct device *dev, struct wifi_p2p_params *params); +#endif }; /** Wi-Fi management offload API */ @@ -1916,6 +2029,17 @@ void wifi_mgmt_raise_ap_sta_connected_event(struct net_if *iface, void wifi_mgmt_raise_ap_sta_disconnected_event(struct net_if *iface, struct wifi_ap_sta_info *sta_info); +#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P +/** + * @brief Raise P2P device found event + * + * @param iface Network interface + * @param device_info P2P device information + */ +void wifi_mgmt_raise_p2p_device_found_event(struct net_if *iface, + struct wifi_p2p_device_info *peer_info); +#endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P */ + /** * @} */ diff --git a/modules/hostap/src/supp_api.c b/modules/hostap/src/supp_api.c index 6880e94981ac..2cb3c7697fe7 100644 --- a/modules/hostap/src/supp_api.c +++ b/modules/hostap/src/supp_api.c @@ -61,6 +61,14 @@ enum status_thread_state { static struct wifi_enterprise_creds_params enterprise_creds; #endif +#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P +#define P2P_CMD_BUF_SIZE 128 +#define P2P_RESP_BUF_SIZE 64 +#define P2P_PEER_INFO_SIZE 512 +#define P2P_ADDR_SIZE 32 +#define P2P_CMD_SIZE 64 +#endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P */ + K_MUTEX_DEFINE(wpa_supplicant_mutex); extern struct k_work_q *get_workq(void); @@ -2607,3 +2615,249 @@ int supplicant_config_params(const struct device *dev, struct wifi_config_params k_mutex_unlock(&wpa_supplicant_mutex); return ret; } + +#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P +static inline void extract_value(const char *src, char *dest, size_t dest_size) +{ + size_t i = 0; + + while (src[i] != '\0' && src[i] != '\n' && i < dest_size - 1) { + dest[i] = src[i]; + i++; + } + dest[i] = '\0'; +} + +static void parse_peer_info_line(const char *line, struct wifi_p2p_device_info *info) +{ + const char *pos; + + if (strncmp(line, "device_name=", 12) == 0) { + extract_value(line + 12, info->device_name, sizeof(info->device_name)); + } else if (strncmp(line, "pri_dev_type=", 13) == 0) { + extract_value(line + 13, info->pri_dev_type_str, sizeof(info->pri_dev_type_str)); + } else if (strncmp(line, "level=", 6) == 0) { + char *endptr; + long val; + + pos = line + 6; + val = strtol(pos, &endptr, 10); + if (endptr != pos && val >= INT8_MIN && val <= INT8_MAX) { + info->rssi = (int8_t)val; + } + } else if (strncmp(line, "config_methods=", 15) == 0) { + char *endptr; + long val; + + pos = line + 15; + extract_value(pos, info->config_methods_str, sizeof(info->config_methods_str)); + + if (pos[0] == '0' && (pos[1] == 'x' || pos[1] == 'X')) { + val = strtol(pos, &endptr, 16); + } else { + val = strtol(pos, &endptr, 10); + } + if (endptr != pos && val >= 0 && val <= UINT16_MAX) { + info->config_methods = (uint16_t)val; + } + } else if (strncmp(line, "manufacturer=", 13) == 0) { + extract_value(line + 13, info->manufacturer, sizeof(info->manufacturer)); + } else if (strncmp(line, "model_name=", 11) == 0) { + extract_value(line + 11, info->model_name, sizeof(info->model_name)); + } +} + +static void parse_peer_info_response(const char *resp, const uint8_t *mac, + struct wifi_p2p_device_info *info) +{ + const char *line = resp; + const char *next_line; + + memset(info, 0, sizeof(*info)); + + if (mac != NULL) { + memcpy(info->mac, mac, WIFI_MAC_ADDR_LEN); + } + + while (line != NULL && *line != '\0') { + if (*line == '\n') { + line++; + continue; + } + next_line = strchr(line, '\n'); + parse_peer_info_line(line, info); + if (next_line != NULL) { + line = next_line + 1; + } else { + break; + } + } +} + +int supplicant_p2p_oper(const struct device *dev, struct wifi_p2p_params *params) +{ + struct wpa_supplicant *wpa_s = get_wpa_s_handle(dev); + char cmd_buf[P2P_CMD_BUF_SIZE]; + char resp_buf[P2P_RESP_BUF_SIZE]; + int ret = -1; + const char *discovery_type_str = ""; + + if (wpa_s == NULL || wpa_s->ctrl_conn == NULL) { + wpa_printf(MSG_ERROR, "wpa_supplicant control interface not initialized"); + return -ENOTSUP; + } + + switch (params->oper) { + case WIFI_P2P_FIND: + switch (params->discovery_type) { + case WIFI_P2P_FIND_ONLY_SOCIAL: + discovery_type_str = "type=social"; + break; + case WIFI_P2P_FIND_PROGRESSIVE: + discovery_type_str = "type=progressive"; + break; + case WIFI_P2P_FIND_START_WITH_FULL: + default: + discovery_type_str = ""; + break; + } + + if (params->timeout > 0) { + if (strlen(discovery_type_str) > 0) { + snprintk(cmd_buf, sizeof(cmd_buf), "P2P_FIND %u %s", + params->timeout, discovery_type_str); + } else { + snprintk(cmd_buf, sizeof(cmd_buf), "P2P_FIND %u", + params->timeout); + } + } else { + if (strlen(discovery_type_str) > 0) { + snprintk(cmd_buf, sizeof(cmd_buf), "P2P_FIND %s", + discovery_type_str); + } else { + snprintk(cmd_buf, sizeof(cmd_buf), "P2P_FIND"); + } + } + ret = zephyr_wpa_cli_cmd_resp_noprint(wpa_s->ctrl_conn, cmd_buf, resp_buf); + if (ret < 0) { + wpa_printf(MSG_ERROR, "P2P_FIND command failed: %d", ret); + return -EIO; + } + ret = 0; + break; + + case WIFI_P2P_STOP_FIND: + snprintk(cmd_buf, sizeof(cmd_buf), "P2P_STOP_FIND"); + ret = zephyr_wpa_cli_cmd_resp_noprint(wpa_s->ctrl_conn, cmd_buf, resp_buf); + if (ret < 0) { + wpa_printf(MSG_ERROR, "P2P_STOP_FIND command failed: %d", ret); + return -EIO; + } + ret = 0; + break; + + case WIFI_P2P_PEER: { + char addr[P2P_ADDR_SIZE]; + char cmd[P2P_CMD_SIZE]; + char peer_info[P2P_PEER_INFO_SIZE]; + char *pos; + size_t len; + uint16_t peer_idx = 0; + uint8_t mac[WIFI_MAC_ADDR_LEN]; + struct net_eth_addr peer_mac; + bool query_all_peers; + + if (params->peers == NULL) { + wpa_printf(MSG_ERROR, "Peer info array not provided"); + return -EINVAL; + } + + memcpy(&peer_mac, params->peer_addr, WIFI_MAC_ADDR_LEN); + query_all_peers = net_eth_is_addr_broadcast(&peer_mac); + + if (query_all_peers == true) { + snprintk(cmd_buf, sizeof(cmd_buf), "P2P_PEER FIRST"); + + while (peer_idx < params->peer_count) { + ret = zephyr_wpa_cli_cmd_resp_noprint(wpa_s->ctrl_conn, + cmd_buf, resp_buf); + + if (ret < 0 || resp_buf[0] == '\0' || + strncmp(resp_buf, "FAIL", 4) == 0) { + if (peer_idx == 0) { + wpa_printf(MSG_DEBUG, "No P2P peers found"); + } + break; + } + + len = 0; + pos = resp_buf; + while (*pos != '\0' && *pos != '\n' && len < sizeof(addr) - 1) { + addr[len++] = *pos++; + } + addr[len] = '\0'; + + if (strncmp(addr, "00:00:00:00:00:00", 17) != 0 && + sscanf(addr, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", + &mac[0], &mac[1], &mac[2], + &mac[3], &mac[4], &mac[5]) == + WIFI_MAC_ADDR_LEN) { + + snprintk(cmd, sizeof(cmd), "P2P_PEER %s", addr); + ret = zephyr_wpa_cli_cmd_resp_noprint( + wpa_s->ctrl_conn, cmd, peer_info); + + if (ret >= 0 && + (!params->discovered_only || + strstr(peer_info, + "[PROBE_REQ_ONLY]") == NULL)) { + parse_peer_info_response(peer_info, + mac, + ¶ms->peers[peer_idx]); + peer_idx++; + } + } + snprintk(cmd_buf, sizeof(cmd_buf), "P2P_PEER NEXT-%s", addr); + } + params->peer_count = peer_idx; + } else { + char addr_str[18]; + + if (params->peer_count < 1) { + wpa_printf(MSG_ERROR, "Peer count must be at least 1"); + return -EINVAL; + } + + snprintk(addr_str, sizeof(addr_str), "%02x:%02x:%02x:%02x:%02x:%02x", + params->peer_addr[0], params->peer_addr[1], params->peer_addr[2], + params->peer_addr[3], params->peer_addr[4], params->peer_addr[5]); + snprintk(cmd_buf, sizeof(cmd_buf), "P2P_PEER %s", addr_str); + + /* Use peer_info buffer for single peer query to avoid large resp_buf */ + ret = zephyr_wpa_cli_cmd_resp_noprint(wpa_s->ctrl_conn, + cmd_buf, peer_info); + if (ret < 0) { + wpa_printf(MSG_ERROR, "P2P_PEER command failed: %d", ret); + return -EIO; + } + if (strncmp(peer_info, "FAIL", 4) == 0) { + wpa_printf(MSG_ERROR, "Peer %s not found", addr_str); + return -ENODEV; + } + parse_peer_info_response(peer_info, params->peer_addr, + ¶ms->peers[0]); + params->peer_count = 1; + } + ret = 0; + break; + } + + default: + wpa_printf(MSG_ERROR, "Unknown P2P operation: %d", params->oper); + ret = -EINVAL; + break; + } + + return ret; +} +#endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P */ diff --git a/modules/hostap/src/supp_api.h b/modules/hostap/src/supp_api.h index 8ab49f177e70..692db61bf277 100644 --- a/modules/hostap/src/supp_api.h +++ b/modules/hostap/src/supp_api.h @@ -386,4 +386,16 @@ int supplicant_dpp_dispatch(const struct device *dev, struct wifi_dpp_params *pa * @return 0 for OK; -1 for ERROR */ int supplicant_config_params(const struct device *dev, struct wifi_config_params *params); + +#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P +/** + * @brief P2P operation + * + * @param dev Wi-Fi interface handle to use + * @param params P2P parameters + * @return 0 for OK; -1 for ERROR + */ +int supplicant_p2p_oper(const struct device *dev, struct wifi_p2p_params *params); +#endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P */ + #endif /* ZEPHYR_SUPP_MGMT_H */ diff --git a/modules/hostap/src/supp_events.c b/modules/hostap/src/supp_events.c index c4175a416bea..ee6a05a568ec 100644 --- a/modules/hostap/src/supp_events.c +++ b/modules/hostap/src/supp_events.c @@ -43,6 +43,9 @@ static const struct wpa_supp_event_info { { "CTRL-EVENT-NETWORK-REMOVED", SUPPLICANT_EVENT_NETWORK_REMOVED }, { "CTRL-EVENT-DSCP-POLICY", SUPPLICANT_EVENT_DSCP_POLICY }, { "CTRL-EVENT-REGDOM-CHANGE", SUPPLICANT_EVENT_REGDOM_CHANGE }, +#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P + { "P2P-DEVICE-FOUND", SUPPLICANT_EVENT_P2P_DEVICE_FOUND }, +#endif }; static void copy_mac_addr(const unsigned int *src, uint8_t *dst) @@ -174,6 +177,43 @@ static int supplicant_process_status(struct supplicant_int_event_data *event_dat event_data->data_len = sizeof(data->bss_removed); copy_mac_addr(tmp_mac_addr, data->bss_removed.bssid); break; +#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P + case SUPPLICANT_EVENT_P2P_DEVICE_FOUND: + { + char *ptr, *name_start, *name_end; + unsigned int config_methods = 0; + + memset(&data->p2p_device_found, 0, sizeof(data->p2p_device_found)); + ret = sscanf(event_no_prefix, MACSTR, MACADDR2STR(tmp_mac_addr)); + if (ret > 0) { + copy_mac_addr(tmp_mac_addr, data->p2p_device_found.mac); + } + name_start = strstr(event_no_prefix, "name='"); + if (name_start) { + name_start += 6; + name_end = strchr(name_start, '\''); + if (name_end) { + size_t name_len = name_end - name_start; + + if (name_len >= sizeof(data->p2p_device_found.device_name)) { + name_len = sizeof(data->p2p_device_found.device_name) - 1; + } + memcpy(data->p2p_device_found.device_name, name_start, name_len); + data->p2p_device_found.device_name[name_len] = '\0'; + } + } + ptr = strstr(event_no_prefix, "config_methods="); + if (ptr) { + ret = sscanf(ptr, "config_methods=%x", &config_methods); + if (ret > 0) { + data->p2p_device_found.config_methods = config_methods; + } + } + event_data->data_len = sizeof(data->p2p_device_found); + ret = 1; + break; + } +#endif case SUPPLICANT_EVENT_TERMINATING: case SUPPLICANT_EVENT_SCAN_STARTED: case SUPPLICANT_EVENT_SCAN_RESULTS: @@ -386,8 +426,18 @@ int supplicant_send_wifi_mgmt_event(const char *ifname, enum net_event_wifi_cmd case NET_EVENT_WIFI_CMD_SUPPLICANT: event_data.data = &data; if (supplicant_process_status(&event_data, (char *)supplicant_status) > 0) { - net_mgmt_event_notify_with_info(NET_EVENT_SUPPLICANT_INT_EVENT, - iface, &event_data, sizeof(event_data)); +#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P + /* Handle P2P events directly */ + if (event_data.event == SUPPLICANT_EVENT_P2P_DEVICE_FOUND) { + wifi_mgmt_raise_p2p_device_found_event(iface, + &data.p2p_device_found); + } else { +#endif + net_mgmt_event_notify_with_info(NET_EVENT_SUPPLICANT_INT_EVENT, + iface, &event_data, sizeof(event_data)); +#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P + } +#endif } break; default: diff --git a/modules/hostap/src/supp_events.h b/modules/hostap/src/supp_events.h index 1c74af528492..6ff8812c2fb8 100644 --- a/modules/hostap/src/supp_events.h +++ b/modules/hostap/src/supp_events.h @@ -137,6 +137,10 @@ union supplicant_event_data { unsigned int id; } network_removed; +#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P + struct wifi_p2p_device_info p2p_device_found; +#endif + char supplicant_event_str[NM_WIFI_EVENT_STR_LEN]; }; @@ -158,6 +162,9 @@ enum supplicant_event_num { SUPPLICANT_EVENT_NETWORK_REMOVED, SUPPLICANT_EVENT_DSCP_POLICY, SUPPLICANT_EVENT_REGDOM_CHANGE, +#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P + SUPPLICANT_EVENT_P2P_DEVICE_FOUND, +#endif }; struct supplicant_int_event_data { diff --git a/modules/hostap/src/supp_main.c b/modules/hostap/src/supp_main.c index 37c4128a2bcc..c56e9b134271 100644 --- a/modules/hostap/src/supp_main.c +++ b/modules/hostap/src/supp_main.c @@ -100,6 +100,9 @@ static const struct wifi_mgmt_ops mgmt_ops = { .enterprise_creds = supplicant_add_enterprise_creds, #endif .config_params = supplicant_config_params, +#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P + .p2p_oper = supplicant_p2p_oper, +#endif }; DEFINE_WIFI_NM_INSTANCE(wifi_supplicant, &mgmt_ops); @@ -244,6 +247,12 @@ static void zephyr_wpa_supplicant_msg(void *ctx, const char *txt, size_t len) supplicant_send_wifi_mgmt_event(wpa_s->ifname, NET_EVENT_WIFI_CMD_NEIGHBOR_REP_RECEIVED, (void *)txt, len); +#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P + } else if (strncmp(txt, "P2P-", 4) == 0) { + supplicant_send_wifi_mgmt_event(wpa_s->ifname, + NET_EVENT_WIFI_CMD_SUPPLICANT, + (void *)txt, len); +#endif } } diff --git a/subsys/net/l2/wifi/Kconfig b/subsys/net/l2/wifi/Kconfig index 63680dba9b30..eddfb7d4c30a 100644 --- a/subsys/net/l2/wifi/Kconfig +++ b/subsys/net/l2/wifi/Kconfig @@ -72,6 +72,15 @@ config WIFI_SHELL_MAX_AP_STA This option defines the maximum number of APs and STAs that can be managed in Wi-Fi shell. +config WIFI_P2P_MAX_PEERS + int "Maximum number of P2P peers that can be returned in a single query" + depends on WIFI_NM_WPA_SUPPLICANT_P2P + default 32 + range 1 256 + help + This option defines the maximum number of P2P peers that can be returned + in a single query operation. + config WIFI_NM bool "Wi-Fi Network manager support" help diff --git a/subsys/net/l2/wifi/wifi_mgmt.c b/subsys/net/l2/wifi/wifi_mgmt.c index b20e5d6674d2..7e13b1b5622f 100644 --- a/subsys/net/l2/wifi/wifi_mgmt.c +++ b/subsys/net/l2/wifi/wifi_mgmt.c @@ -1474,6 +1474,35 @@ static int wifi_set_bgscan(uint64_t mgmt_request, struct net_if *iface, void *da NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_BGSCAN, wifi_set_bgscan); #endif +#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P +static int wifi_p2p_oper(uint64_t mgmt_request, struct net_if *iface, + void *data, size_t len) +{ + const struct device *dev = net_if_get_device(iface); + const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface); + struct wifi_p2p_params *params = data; + + if (wifi_mgmt_api == NULL || wifi_mgmt_api->p2p_oper == NULL) { + return -ENOTSUP; + } + + if (data == NULL || len != sizeof(*params)) { + return -EINVAL; + } + + return wifi_mgmt_api->p2p_oper(dev, params); +} + +NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_P2P_OPER, wifi_p2p_oper); + +void wifi_mgmt_raise_p2p_device_found_event(struct net_if *iface, + struct wifi_p2p_device_info *peer_info) +{ + net_mgmt_event_notify_with_info(NET_EVENT_WIFI_P2P_DEVICE_FOUND, + iface, peer_info, + sizeof(*peer_info)); +} +#endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P */ #ifdef CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS void wifi_mgmt_raise_raw_scan_result_event(struct net_if *iface, From 2805347dfa74cc2233096cf86786ec52031b4df8 Mon Sep 17 00:00:00 2001 From: Kapil Bhatt Date: Wed, 29 Oct 2025 13:08:44 +0000 Subject: [PATCH 1618/3659] net: wifi: Add Wi-Fi direct P2P discovery shell command support Add shell command support for P2P discovery. Signed-off-by: Kapil Bhatt --- subsys/net/l2/wifi/wifi_shell.c | 234 +++++++++++++++++++++++++++++++- 1 file changed, 233 insertions(+), 1 deletion(-) diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 429e1042800e..a644b4f6cc43 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -45,7 +45,8 @@ LOG_MODULE_REGISTER(net_wifi_shell, LOG_LEVEL_INF); NET_EVENT_WIFI_AP_STA_CONNECTED |\ NET_EVENT_WIFI_AP_STA_DISCONNECTED|\ NET_EVENT_WIFI_SIGNAL_CHANGE |\ - NET_EVENT_WIFI_NEIGHBOR_REP_COMP) + NET_EVENT_WIFI_NEIGHBOR_REP_COMP |\ + NET_EVENT_WIFI_P2P_DEVICE_FOUND) #ifdef CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS_ONLY #define WIFI_SHELL_SCAN_EVENTS ( \ @@ -518,6 +519,26 @@ static void handle_wifi_neighbor_rep_complete(struct net_mgmt_event_callback *cb } #endif +#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P +static void handle_wifi_p2p_device_found(struct net_mgmt_event_callback *cb) +{ + const struct wifi_p2p_device_info *peer_info = + (const struct wifi_p2p_device_info *)cb->info; + const struct shell *sh = context.sh; + + if (!peer_info || peer_info->device_name[0] == '\0') { + return; + } + + PR("Device Name: %-20s MAC Address: %02x:%02x:%02x:%02x:%02x:%02x " + "Config Methods: 0x%x\n", + peer_info->device_name, + peer_info->mac[0], peer_info->mac[1], peer_info->mac[2], + peer_info->mac[3], peer_info->mac[4], peer_info->mac[5], + peer_info->config_methods); +} +#endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P */ + static void wifi_mgmt_event_handler(struct net_mgmt_event_callback *cb, uint64_t mgmt_event, struct net_if *iface) { @@ -551,6 +572,11 @@ static void wifi_mgmt_event_handler(struct net_mgmt_event_callback *cb, handle_wifi_neighbor_rep_complete(cb, iface); break; #endif +#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P + case NET_EVENT_WIFI_P2P_DEVICE_FOUND: + handle_wifi_p2p_device_found(cb); + break; +#endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P */ default: break; } @@ -3524,6 +3550,180 @@ static int cmd_wifi_dpp_reconfig(const struct shell *sh, size_t argc, char *argv } #endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_DPP */ + +#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P +static void print_peer_info(const struct shell *sh, int index, + const struct wifi_p2p_device_info *peer) +{ + uint8_t mac_string_buf[sizeof("xx:xx:xx:xx:xx:xx")]; + const char *device_name; + const char *device_type; + const char *config_methods; + + device_name = (peer->device_name[0] != '\0') ? + peer->device_name : ""; + device_type = (peer->pri_dev_type_str[0] != '\0') ? + peer->pri_dev_type_str : "-"; + config_methods = (peer->config_methods_str[0] != '\0') ? + peer->config_methods_str : "-"; + + PR("%-4d | %-32s | %-17s | %-4d | %-20s | %s\n", + index, + device_name, + net_sprint_ll_addr_buf(peer->mac, WIFI_MAC_ADDR_LEN, + mac_string_buf, + sizeof(mac_string_buf)), + peer->rssi, + device_type, + config_methods); +} + +static int cmd_wifi_p2p_peer(const struct shell *sh, size_t argc, char *argv[]) +{ + struct net_if *iface = get_iface(IFACE_TYPE_STA, argc, argv); + struct wifi_p2p_params params = {0}; + uint8_t mac_addr[WIFI_MAC_ADDR_LEN]; + static struct wifi_p2p_device_info peers[WIFI_P2P_MAX_PEERS]; + int ret; + int max_peers = (argc < 2) ? WIFI_P2P_MAX_PEERS : 1; + + context.sh = sh; + + memset(peers, 0, sizeof(peers)); + + params.peers = peers; + params.oper = WIFI_P2P_PEER; + params.peer_count = max_peers; + + if (argc >= 2) { + if (sscanf(argv[1], "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", + &mac_addr[0], &mac_addr[1], &mac_addr[2], + &mac_addr[3], &mac_addr[4], &mac_addr[5]) != WIFI_MAC_ADDR_LEN) { + PR_ERROR("Invalid MAC address format. Use: XX:XX:XX:XX:XX:XX\n"); + return -EINVAL; + } + memcpy(params.peer_addr, mac_addr, WIFI_MAC_ADDR_LEN); + params.peer_count = 1; + } else { + /* Use broadcast MAC to query all peers */ + memset(params.peer_addr, 0xFF, WIFI_MAC_ADDR_LEN); + } + + ret = net_mgmt(NET_REQUEST_WIFI_P2P_OPER, iface, ¶ms, sizeof(params)); + if (ret) { + PR_WARNING("P2P peer info request failed\n"); + return -ENOEXEC; + } + + if (params.peer_count > 0) { + PR("\n%-4s | %-32s | %-17s | %-4s | %-20s | %s\n", + "Num", "Device Name", "MAC Address", "RSSI", "Device Type", "Config Methods"); + for (int i = 0; i < params.peer_count; i++) { + print_peer_info(sh, i + 1, &peers[i]); + } + } else { + if (argc >= 2) { + shell_print(sh, "No information available for peer %s", argv[1]); + } else { + shell_print(sh, "No P2P peers found"); + } + } + + return 0; +} + + +static int cmd_wifi_p2p_find(const struct shell *sh, size_t argc, char *argv[]) +{ + struct net_if *iface = get_iface(IFACE_TYPE_STA, argc, argv); + struct wifi_p2p_params params = {0}; + + context.sh = sh; + + params.oper = WIFI_P2P_FIND; + params.discovery_type = WIFI_P2P_FIND_START_WITH_FULL; + params.timeout = 10; /* Default 10 second timeout */ + + if (argc > 1) { + int opt; + int opt_index = 0; + struct sys_getopt_state *state; + static const struct sys_getopt_option long_options[] = { + {"timeout", sys_getopt_required_argument, 0, 't'}, + {"type", sys_getopt_required_argument, 0, 'T'}, + {"iface", sys_getopt_required_argument, 0, 'i'}, + {"help", sys_getopt_no_argument, 0, 'h'}, + {0, 0, 0, 0} + }; + long val; + + while ((opt = sys_getopt_long(argc, argv, "t:T:i:h", + long_options, &opt_index)) != -1) { + state = sys_getopt_state_get(); + switch (opt) { + case 't': + if (!parse_number(sh, &val, state->optarg, "timeout", 0, 65535)) { + return -EINVAL; + } + params.timeout = (uint16_t)val; + break; + case 'T': + if (!parse_number(sh, &val, state->optarg, "type", 0, 2)) { + return -EINVAL; + } + switch (val) { + case 0: + params.discovery_type = WIFI_P2P_FIND_ONLY_SOCIAL; + break; + case 1: + params.discovery_type = WIFI_P2P_FIND_PROGRESSIVE; + break; + case 2: + params.discovery_type = WIFI_P2P_FIND_START_WITH_FULL; + break; + default: + return -EINVAL; + } + break; + case 'i': + /* Unused, but parsing to avoid unknown option error */ + break; + case 'h': + shell_help(sh); + return -ENOEXEC; + default: + PR_ERROR("Invalid option %c\n", state->optopt); + return -EINVAL; + } + } + } + + if (net_mgmt(NET_REQUEST_WIFI_P2P_OPER, iface, ¶ms, sizeof(params))) { + PR_WARNING("P2P find request failed\n"); + return -ENOEXEC; + } + PR("P2P find started\n"); + return 0; +} + +static int cmd_wifi_p2p_stop_find(const struct shell *sh, size_t argc, char *argv[]) +{ + struct net_if *iface = get_iface(IFACE_TYPE_STA, argc, argv); + struct wifi_p2p_params params = {0}; + + context.sh = sh; + + params.oper = WIFI_P2P_STOP_FIND; + + if (net_mgmt(NET_REQUEST_WIFI_P2P_OPER, iface, ¶ms, sizeof(params))) { + PR_WARNING("P2P stop find request failed\n"); + return -ENOEXEC; + } + PR("P2P find stopped\n"); + return 0; +} +#endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P */ + static int cmd_wifi_pmksa_flush(const struct shell *sh, size_t argc, char *argv[]) { struct net_if *iface = get_iface(IFACE_TYPE_STA, argc, argv); @@ -4229,6 +4429,38 @@ SHELL_SUBCMD_ADD((wifi), bgscan, NULL, 2, 6); #endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_BGSCAN */ +#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P +SHELL_STATIC_SUBCMD_SET_CREATE( + wifi_cmd_p2p, + SHELL_CMD_ARG(find, NULL, + "Start P2P device discovery\n" + "[-t, --timeout=]: Discovery timeout\n" + "[-T, --type=<0|1|2>]: Discovery type\n" + " 0: Social channels only (1, 6, 11)\n" + " 1: Progressive scan (all channels)\n" + " 2: Full scan first, then social (default)\n" + "[-i, --iface=]: Interface index\n" + "[-h, --help]: Show help\n", + cmd_wifi_p2p_find, 1, 6), + SHELL_CMD_ARG(stop_find, NULL, + "Stop P2P device discovery\n" + "[-i, --iface=]: Interface index\n", + cmd_wifi_p2p_stop_find, 1, 2), + SHELL_CMD_ARG(peer, NULL, + "Show information about P2P peers\n" + "Usage: peer []\n" + ": Show detailed info for specific peer (format: XX:XX:XX:XX:XX:XX)\n" + "[-i, --iface=]: Interface index\n", + cmd_wifi_p2p_peer, 1, 3), + SHELL_SUBCMD_SET_END +); + +SHELL_SUBCMD_ADD((wifi), p2p, &wifi_cmd_p2p, + "Wi-Fi Direct (P2P) commands.", + NULL, + 0, 0); +#endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P */ + SHELL_SUBCMD_ADD((wifi), config, NULL, "Configure STA parameters.\n" "-o, --okc=<0/1>: Opportunistic Key Caching. 0: disable, 1: enable\n" From a9176ad7cb0339a8bd459a09079cbb5965fdff95 Mon Sep 17 00:00:00 2001 From: Ravi Dondaputi Date: Thu, 30 Oct 2025 19:48:21 +0530 Subject: [PATCH 1619/3659] drivers: wifi: nrf_wifi: Add RoC support Add ops for remain-on-channel and cancelling remain-on-channel. Signed-off-by: Ravi Dondaputi --- drivers/wifi/nrf_wifi/inc/wpa_supp_if.h | 8 ++ drivers/wifi/nrf_wifi/src/fmac_main.c | 4 + drivers/wifi/nrf_wifi/src/wpa_supp_if.c | 141 ++++++++++++++++++++++++ 3 files changed, 153 insertions(+) diff --git a/drivers/wifi/nrf_wifi/inc/wpa_supp_if.h b/drivers/wifi/nrf_wifi/inc/wpa_supp_if.h index c543644e3128..28aadae28ebd 100644 --- a/drivers/wifi/nrf_wifi/inc/wpa_supp_if.h +++ b/drivers/wifi/nrf_wifi/inc/wpa_supp_if.h @@ -123,8 +123,16 @@ int nrf_wifi_supp_get_conn_info(void *if_priv, struct wpa_conn_info *info); void nrf_wifi_supp_event_proc_get_conn_info(void *os_vif_ctx, struct nrf_wifi_umac_event_conn_info *info, unsigned int event_len); +void nrf_wifi_supp_event_remain_on_channel(void *os_vif_ctx, + struct nrf_wifi_event_remain_on_channel *info, + unsigned int event_len); +void nrf_wifi_supp_event_roc_cancel_complete(void *os_vif_ctx, + struct nrf_wifi_event_remain_on_channel *info, + unsigned int event_len); int nrf_wifi_supp_set_country(void *if_priv, const char *alpha2); int nrf_wifi_supp_get_country(void *if_priv, char *alpha2); +int nrf_wifi_supp_remain_on_channel(void *if_priv, unsigned int freq, unsigned int duration); +int nrf_wifi_supp_cancel_remain_on_channel(void *if_priv); #endif /* CONFIG_NRF70_STA_MODE */ #ifdef CONFIG_NRF70_AP_MODE diff --git a/drivers/wifi/nrf_wifi/src/fmac_main.c b/drivers/wifi/nrf_wifi/src/fmac_main.c index e8e04f12d0cc..bd40cb74d67d 100644 --- a/drivers/wifi/nrf_wifi/src/fmac_main.c +++ b/drivers/wifi/nrf_wifi/src/fmac_main.c @@ -830,6 +830,8 @@ static int nrf_wifi_drv_main_zep(const struct device *dev) callbk_fns.event_get_wiphy = nrf_wifi_wpa_supp_event_get_wiphy; callbk_fns.mgmt_rx_callbk_fn = nrf_wifi_wpa_supp_event_mgmt_rx_callbk_fn; callbk_fns.get_conn_info_callbk_fn = nrf_wifi_supp_event_proc_get_conn_info; + callbk_fns.roc_callbk_fn = nrf_wifi_supp_event_remain_on_channel; + callbk_fns.roc_cancel_callbk_fn = nrf_wifi_supp_event_roc_cancel_complete; #endif /* CONFIG_NRF70_STA_MODE */ /* The OSAL layer needs to be initialized before any other initialization @@ -950,6 +952,8 @@ static const struct zep_wpa_supp_dev_ops wpa_supp_ops = { .get_conn_info = nrf_wifi_supp_get_conn_info, .set_country = nrf_wifi_supp_set_country, .get_country = nrf_wifi_supp_get_country, + .remain_on_channel = nrf_wifi_supp_remain_on_channel, + .cancel_remain_on_channel = nrf_wifi_supp_cancel_remain_on_channel, #ifdef CONFIG_NRF70_AP_MODE .init_ap = nrf_wifi_wpa_supp_init_ap, .start_ap = nrf_wifi_wpa_supp_start_ap, diff --git a/drivers/wifi/nrf_wifi/src/wpa_supp_if.c b/drivers/wifi/nrf_wifi/src/wpa_supp_if.c index da63be115cdd..283c752887b1 100644 --- a/drivers/wifi/nrf_wifi/src/wpa_supp_if.c +++ b/drivers/wifi/nrf_wifi/src/wpa_supp_if.c @@ -1986,6 +1986,147 @@ void nrf_wifi_supp_event_proc_get_conn_info(void *if_priv, k_sem_give(&wait_for_event_sem); } +void nrf_wifi_supp_event_remain_on_channel(void *if_priv, + struct nrf_wifi_event_remain_on_channel *roc_complete, + unsigned int event_len) +{ + struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL; + + if (if_priv == NULL) { + LOG_ERR("%s: Missing interface context", __func__); + return; + } + + vif_ctx_zep = if_priv; + + if (roc_complete == NULL) { + LOG_ERR("%s: Missing ROC complete event data", __func__); + return; + } + + LOG_DBG("%s: ROC complete on freq %d, dur %d, vif_idx %d", + __func__, roc_complete->frequency, + roc_complete->dur, vif_ctx_zep->vif_idx); + + if (vif_ctx_zep->supp_drv_if_ctx && vif_ctx_zep->supp_callbk_fns.roc_complete) { + vif_ctx_zep->supp_callbk_fns.roc_complete(vif_ctx_zep->supp_drv_if_ctx, + roc_complete->frequency, + roc_complete->dur); + } +} + +void nrf_wifi_supp_event_roc_cancel_complete(void *if_priv, + struct nrf_wifi_event_remain_on_channel + *roc_cancel_complete, + unsigned int event_len) +{ + struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL; + + if (if_priv == NULL) { + LOG_ERR("%s: Missing interface context", __func__); + return; + } + + vif_ctx_zep = if_priv; + + if (roc_cancel_complete == NULL) { + LOG_ERR("%s: Missing ROC cancel complete event data", __func__); + return; + } + + LOG_DBG("%s: ROC cancel complete on freq %d, vif_idx %d", + __func__, roc_cancel_complete->frequency, + vif_ctx_zep->vif_idx); + + if (vif_ctx_zep->supp_drv_if_ctx && vif_ctx_zep->supp_callbk_fns.roc_cancel_complete) { + vif_ctx_zep->supp_callbk_fns.roc_cancel_complete(vif_ctx_zep->supp_drv_if_ctx, + roc_cancel_complete->frequency); + } +} + +int nrf_wifi_supp_remain_on_channel(void *if_priv, unsigned int freq, + unsigned int duration) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; +#ifdef NRF70_P2P_MODE + struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL; + struct nrf_wifi_ctx_zep *rpu_ctx_zep = NULL; + struct remain_on_channel_info roc_info; + + if (if_priv == NULL) { + LOG_ERR("%s: Invalid params", __func__); + return -1; + } + + vif_ctx_zep = if_priv; + rpu_ctx_zep = vif_ctx_zep->rpu_ctx_zep; + if (rpu_ctx_zep == NULL) { + LOG_ERR("%s: rpu_ctx_zep is NULL", __func__); + return -1; + } + + k_mutex_lock(&vif_ctx_zep->vif_lock, K_FOREVER); + if (rpu_ctx_zep->rpu_ctx == NULL) { + LOG_DBG("%s: RPU context not initialized", __func__); + goto out; + } + + memset(&roc_info, 0, sizeof(roc_info)); + roc_info.nrf_wifi_freq_params.frequency = freq; + roc_info.nrf_wifi_freq_params.channel_width = NRF_WIFI_CHAN_WIDTH_20; + roc_info.nrf_wifi_freq_params.center_frequency1 = freq; + roc_info.nrf_wifi_freq_params.center_frequency2 = 0; + roc_info.nrf_wifi_freq_params.channel_type = NRF_WIFI_CHAN_HT20; + roc_info.dur = duration; + + status = nrf_wifi_sys_fmac_p2p_roc_start(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx, + &roc_info); + if (status != NRF_WIFI_STATUS_SUCCESS) { + LOG_ERR("%s: nrf_wifi_fmac_remain_on_channel failed", __func__); + goto out; + } +out: + k_mutex_unlock(&vif_ctx_zep->vif_lock); +#endif /* NRF70_P2P_MODE */ + return status; +} + +int nrf_wifi_supp_cancel_remain_on_channel(void *if_priv) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; +#ifdef NRF70_P2P_MODE + struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL; + struct nrf_wifi_ctx_zep *rpu_ctx_zep = NULL; + + if (if_priv == NULL) { + LOG_ERR("%s: Invalid params", __func__); + return -1; + } + + vif_ctx_zep = if_priv; + rpu_ctx_zep = vif_ctx_zep->rpu_ctx_zep; + if (rpu_ctx_zep == NULL) { + LOG_ERR("%s: rpu_ctx_zep is NULL", __func__); + return -1; + } + + k_mutex_lock(&vif_ctx_zep->vif_lock, K_FOREVER); + if (rpu_ctx_zep->rpu_ctx == NULL) { + LOG_DBG("%s: RPU context not initialized", __func__); + goto out; + } + + status = nrf_wifi_sys_fmac_p2p_roc_stop(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx, 0); + if (status != NRF_WIFI_STATUS_SUCCESS) { + LOG_ERR("%s: nrf_wifi_fmac_cancel_remain_on_channel failed", __func__); + goto out; + } +out: + k_mutex_unlock(&vif_ctx_zep->vif_lock); +#endif /* NRF70_P2P_MODE */ + return status; +} + #ifdef CONFIG_NRF70_AP_MODE static int nrf_wifi_vif_state_change(struct nrf_wifi_vif_ctx_zep *vif_ctx_zep, enum nrf_wifi_fmac_if_op_state state) From ed56b9b97c2d40593cb3bc28163d012888cad726 Mon Sep 17 00:00:00 2001 From: Ravi Dondaputi Date: Thu, 30 Oct 2025 19:51:45 +0530 Subject: [PATCH 1620/3659] drivers: wifi: nrf_wifi: Allow off channel TX for probe responses For frames sent down by supplicant in station mode, inform RPU to allow off-channel transmission. This is needed for sending P2P probe responses. Signed-off-by: Ravi Dondaputi --- drivers/wifi/nrf_wifi/src/wpa_supp_if.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/wifi/nrf_wifi/src/wpa_supp_if.c b/drivers/wifi/nrf_wifi/src/wpa_supp_if.c index 283c752887b1..1a03bff0940e 100644 --- a/drivers/wifi/nrf_wifi/src/wpa_supp_if.c +++ b/drivers/wifi/nrf_wifi/src/wpa_supp_if.c @@ -1435,6 +1435,10 @@ int nrf_wifi_nl80211_send_mlme(void *if_priv, const u8 *data, goto out; } + if (vif_ctx_zep->if_type == NRF_WIFI_IFTYPE_STATION) { + offchanok = 1; + } + if (offchanok) { mgmt_tx_info->nrf_wifi_flags |= NRF_WIFI_CMD_FRAME_OFFCHANNEL_TX_OK; } From 041766d9cba46a4abc89579fef294da903309c9e Mon Sep 17 00:00:00 2001 From: Ravi Dondaputi Date: Thu, 30 Oct 2025 20:04:00 +0530 Subject: [PATCH 1621/3659] drivers: wifi: nrf_wifi: Register frame without match For frames like Probe Requests, there is no match criterion. Re-arrange the checks to support registering of frames without providing any matching info. Signed-off-by: Ravi Dondaputi --- drivers/wifi/nrf_wifi/src/wpa_supp_if.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/wifi/nrf_wifi/src/wpa_supp_if.c b/drivers/wifi/nrf_wifi/src/wpa_supp_if.c index 1a03bff0940e..05cb5b87dc97 100644 --- a/drivers/wifi/nrf_wifi/src/wpa_supp_if.c +++ b/drivers/wifi/nrf_wifi/src/wpa_supp_if.c @@ -1702,7 +1702,7 @@ int nrf_wifi_supp_register_frame(void *if_priv, struct nrf_wifi_ctx_zep *rpu_ctx_zep = NULL; struct nrf_wifi_umac_mgmt_frame_info frame_info; - if (!if_priv || !match || !match_len) { + if (if_priv == NULL) { LOG_ERR("%s: Invalid parameters", __func__); return -1; } @@ -1723,8 +1723,14 @@ int nrf_wifi_supp_register_frame(void *if_priv, memset(&frame_info, 0, sizeof(frame_info)); frame_info.frame_type = type; - frame_info.frame_match.frame_match_len = match_len; - memcpy(frame_info.frame_match.frame_match, match, match_len); + if (match_len > 0) { + if (match == NULL) { + LOG_ERR("%s: Invalid match parameters", __func__); + goto out; + } + frame_info.frame_match.frame_match_len = match_len; + memcpy(frame_info.frame_match.frame_match, match, match_len); + } status = nrf_wifi_sys_fmac_register_frame(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx, &frame_info); From 000e41b2e8eb3540042516bf38418df427b87a09 Mon Sep 17 00:00:00 2001 From: Ravi Dondaputi Date: Thu, 30 Oct 2025 20:15:39 +0530 Subject: [PATCH 1622/3659] modules: hostap: Define heap and stack for P2P support Increase required heap and stack size for P2P. More stack was required during WPS negotiation. Signed-off-by: Ravi Dondaputi --- modules/hostap/Kconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/hostap/Kconfig b/modules/hostap/Kconfig index d64208eaa668..4ec31c21e199 100644 --- a/modules/hostap/Kconfig +++ b/modules/hostap/Kconfig @@ -53,6 +53,7 @@ config HEAP_MEM_POOL_ADD_SIZE_HOSTAP def_int 60000 if WIFI_USAGE_MODE_STA_AP def_int 55000 if WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE && WIFI_CREDENTIALS def_int 48000 if WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE + def_int 80000 if WIFI_NM_WPA_SUPPLICANT_P2P def_int 41808 if WIFI_NM_WPA_SUPPLICANT_AP # 30K is mandatory, but might need more for long duration use cases def_int 30000 @@ -61,6 +62,7 @@ endif # WIFI_NM_WPA_SUPPLICANT_GLOBAL_HEAP config WIFI_NM_WPA_SUPPLICANT_THREAD_STACK_SIZE int "Stack size for wpa_supplicant thread" + default 7300 if WIFI_NM_WPA_SUPPLICANT_P2P # TODO: Providing higher stack size for Enterprise mode to fix stack # overflow issues. Need to identify the cause for higher stack usage. default 8192 if WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE || WIFI_USAGE_MODE_STA_AP From ca9e1eba5d2b19854c1afb31844160c4067e9c29 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Fri, 31 Oct 2025 04:07:05 +0530 Subject: [PATCH 1623/3659] modules: hostap: Remove obsolete conditional We now support a single MbedTLS shim for hostap, so, this extra check is not needed, we can always use DH5 groups from Mbedtls. Signed-off-by: Chaitanya Tata --- modules/hostap/CMakeLists.txt | 8 -------- 1 file changed, 8 deletions(-) diff --git a/modules/hostap/CMakeLists.txt b/modules/hostap/CMakeLists.txt index 94ceca36ae29..e10804081c4f 100644 --- a/modules/hostap/CMakeLists.txt +++ b/modules/hostap/CMakeLists.txt @@ -385,14 +385,6 @@ zephyr_library_sources_ifdef(CONFIG_WIFI_NM_WPA_SUPPLICANT_WPS ${HOSTAP_SRC_BASE}/crypto/dh_groups.c ) -if(NOT CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ALT) -# dh_group5 is only needed if we are not using mbedtls, as mbedtls provides -# its own definition -zephyr_library_sources_ifdef(CONFIG_WIFI_NM_WPA_SUPPLICANT_WPS - ${HOSTAP_SRC_BASE}/crypto/dh_group5.c -) -endif() - zephyr_library_compile_definitions_ifdef(CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P CONFIG_P2P CONFIG_GAS From c2649b5887ce1c8af4d42785ce2a3b872438da3d Mon Sep 17 00:00:00 2001 From: Kapil Bhatt Date: Fri, 31 Oct 2025 07:30:40 +0000 Subject: [PATCH 1624/3659] net: wifi: Add Wi-Fi direct P2P connect API support Add structures and API support for P2P connect. Signed-off-by: Kapil Bhatt --- include/zephyr/net/wifi_mgmt.h | 28 +++++++++++ modules/hostap/src/supp_api.c | 89 ++++++++++++++++++++++++++++++++++ 2 files changed, 117 insertions(+) diff --git a/include/zephyr/net/wifi_mgmt.h b/include/zephyr/net/wifi_mgmt.h index ef0a6bac27cf..0b0643b3b1c7 100644 --- a/include/zephyr/net/wifi_mgmt.h +++ b/include/zephyr/net/wifi_mgmt.h @@ -1465,6 +1465,8 @@ enum wifi_p2p_op { * or specific MAC address to query a single peer */ WIFI_P2P_PEER, + /** P2P connect to peer */ + WIFI_P2P_CONNECT, }; /** Wi-Fi P2P discovery type */ @@ -1477,6 +1479,16 @@ enum wifi_p2p_discovery_type { WIFI_P2P_FIND_PROGRESSIVE, }; +/** Wi-Fi P2P connection method */ +enum wifi_p2p_connection_method { + /** Push Button Configuration */ + WIFI_P2P_METHOD_PBC = 0, + /** Display PIN (device displays PIN for peer to enter) */ + WIFI_P2P_METHOD_DISPLAY, + /** Keypad PIN (user enters PIN on device) */ + WIFI_P2P_METHOD_KEYPAD, +}; + /** Maximum number of P2P peers that can be returned in a single query */ #define WIFI_P2P_MAX_PEERS CONFIG_WIFI_P2P_MAX_PEERS @@ -1496,6 +1508,22 @@ struct wifi_p2p_params { struct wifi_p2p_device_info *peers; /** Actual number of peers returned */ uint16_t peer_count; + /** Connect specific parameters */ + struct { + /** Connection method */ + enum wifi_p2p_connection_method method; + /** PIN for display/keypad methods (8 digits) + * - For DISPLAY: Leave empty, PIN will be generated and returned + * - For KEYPAD: Provide the PIN to use for connection + */ + char pin[WIFI_WPS_PIN_MAX_LEN + 1]; + /** GO intent (0-15, higher values indicate higher willingness to be GO) */ + uint8_t go_intent; + /** Frequency in MHz (0 = not specified, use default) */ + unsigned int freq; + /** Join an existing group (as a client) instead of starting GO negotiation */ + bool join; + } connect; }; #endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P */ diff --git a/modules/hostap/src/supp_api.c b/modules/hostap/src/supp_api.c index 2cb3c7697fe7..4e4beb1f0bcf 100644 --- a/modules/hostap/src/supp_api.c +++ b/modules/hostap/src/supp_api.c @@ -2852,6 +2852,95 @@ int supplicant_p2p_oper(const struct device *dev, struct wifi_p2p_params *params break; } + case WIFI_P2P_CONNECT: { + char addr_str[18]; + const char *method_str = ""; + char freq_str[32] = ""; + const char *join_str = ""; + + if (params == NULL) { + wpa_printf(MSG_ERROR, "P2P connect params are NULL"); + return -EINVAL; + } + + snprintk(addr_str, sizeof(addr_str), "%02x:%02x:%02x:%02x:%02x:%02x", + params->peer_addr[0], params->peer_addr[1], params->peer_addr[2], + params->peer_addr[3], params->peer_addr[4], params->peer_addr[5]); + + /* Add frequency parameter if specified */ + if (params->connect.freq > 0) { + snprintk(freq_str, sizeof(freq_str), " freq=%u", params->connect.freq); + } + + /* Add join parameter if specified */ + if (params->connect.join) { + join_str = " join"; + } + + switch (params->connect.method) { + case WIFI_P2P_METHOD_PBC: + method_str = "pbc"; + snprintk(cmd_buf, sizeof(cmd_buf), "P2P_CONNECT %s %s go_intent=%d%s%s", + addr_str, method_str, params->connect.go_intent, freq_str, + join_str); + break; + case WIFI_P2P_METHOD_DISPLAY: + method_str = "pin"; + snprintk(cmd_buf, sizeof(cmd_buf), "P2P_CONNECT %s %s go_intent=%d%s%s", + addr_str, method_str, params->connect.go_intent, freq_str, + join_str); + break; + case WIFI_P2P_METHOD_KEYPAD: + method_str = "keypad"; + if (params->connect.pin[0] == '\0') { + wpa_printf(MSG_ERROR, "PIN required for keypad method"); + return -EINVAL; + } + snprintk(cmd_buf, sizeof(cmd_buf), "P2P_CONNECT %s %s %s go_intent=%d%s%s", + addr_str, method_str, params->connect.pin, + params->connect.go_intent, freq_str, join_str); + break; + default: + wpa_printf(MSG_ERROR, "Unknown P2P connection method: %d", + params->connect.method); + return -EINVAL; + } + + ret = zephyr_wpa_cli_cmd_resp_noprint(wpa_s->ctrl_conn, cmd_buf, resp_buf); + if (ret < 0) { + wpa_printf(MSG_ERROR, "P2P_CONNECT command failed: %d", ret); + return -EIO; + } + if (strncmp(resp_buf, "FAIL", 4) == 0) { + wpa_printf(MSG_ERROR, "P2P connect failed: %s", resp_buf); + return -ENODEV; + } + + /* For DISPLAY method, capture the generated PIN from response */ + if (params->connect.method == WIFI_P2P_METHOD_DISPLAY) { + size_t len = 0; + char *pos = resp_buf; + + while (*pos == ' ' || *pos == '\t' || *pos == '\n') { + pos++; + } + + while (*pos != '\0' && *pos != '\n' && *pos != ' ' && + len < WIFI_WPS_PIN_MAX_LEN) { + params->connect.pin[len++] = *pos++; + } + params->connect.pin[len] = '\0'; + + if (params->connect.pin[0] == '\0') { + wpa_printf(MSG_ERROR, "P2P connect: No PIN returned"); + return -ENODEV; + } + } + + ret = 0; + break; + } + default: wpa_printf(MSG_ERROR, "Unknown P2P operation: %d", params->oper); ret = -EINVAL; From 9428fe090f30b17e7a115519174332e51b8cea1d Mon Sep 17 00:00:00 2001 From: Kapil Bhatt Date: Wed, 12 Nov 2025 09:53:18 +0000 Subject: [PATCH 1625/3659] net: wifi: Add Wi-Fi direct P2P connect shell command support Add shell command support for P2P connect. Signed-off-by: Kapil Bhatt --- subsys/net/l2/wifi/wifi_shell.c | 125 ++++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index a644b4f6cc43..538efe65d880 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -3722,6 +3722,112 @@ static int cmd_wifi_p2p_stop_find(const struct shell *sh, size_t argc, char *arg PR("P2P find stopped\n"); return 0; } + +static int cmd_wifi_p2p_connect(const struct shell *sh, size_t argc, char *argv[]) +{ + struct net_if *iface = get_iface(IFACE_TYPE_STA, argc, argv); + struct wifi_p2p_params params = {0}; + uint8_t mac_addr[WIFI_MAC_ADDR_LEN]; + const char *method_arg = NULL; + int opt; + int opt_index = 0; + struct sys_getopt_state *state; + static const struct sys_getopt_option long_options[] = { + {"go-intent", sys_getopt_required_argument, 0, 'g'}, + {"freq", sys_getopt_required_argument, 0, 'f'}, + {"join", sys_getopt_no_argument, 0, 'j'}, + {"iface", sys_getopt_required_argument, 0, 'i'}, + {"help", sys_getopt_no_argument, 0, 'h'}, + {0, 0, 0, 0} + }; + long val; + + context.sh = sh; + + if (argc < 3) { + PR_ERROR("Usage: wifi p2p connect [PIN] " + "[--go-intent=<0-15>] [--freq=] [--join]\n"); + return -EINVAL; + } + + /* Parse MAC address */ + if (sscanf(argv[1], "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", + &mac_addr[0], &mac_addr[1], &mac_addr[2], + &mac_addr[3], &mac_addr[4], &mac_addr[5]) != WIFI_MAC_ADDR_LEN) { + PR_ERROR("Invalid MAC address format. Use: XX:XX:XX:XX:XX:XX\n"); + return -EINVAL; + } + memcpy(params.peer_addr, mac_addr, WIFI_MAC_ADDR_LEN); + + method_arg = argv[2]; + if (strcmp(method_arg, "pbc") == 0) { + params.connect.method = WIFI_P2P_METHOD_PBC; + } else if (strcmp(method_arg, "pin") == 0) { + if (argc > 3 && argv[3][0] != '-') { + params.connect.method = WIFI_P2P_METHOD_KEYPAD; + strncpy(params.connect.pin, argv[3], WIFI_WPS_PIN_MAX_LEN); + params.connect.pin[WIFI_WPS_PIN_MAX_LEN] = '\0'; + } else { + params.connect.method = WIFI_P2P_METHOD_DISPLAY; + params.connect.pin[0] = '\0'; + } + } else { + PR_ERROR("Invalid connection method. Use: pbc or pin\n"); + return -EINVAL; + } + + /* Set default GO intent */ + params.connect.go_intent = 0; + /* Set default frequency to 2462 MHz (channel 11, 2.4 GHz) */ + params.connect.freq = 2462; + /* Set default join to false */ + params.connect.join = false; + + while ((opt = sys_getopt_long(argc, argv, "g:f:ji:h", long_options, &opt_index)) != -1) { + state = sys_getopt_state_get(); + switch (opt) { + case 'g': + if (!parse_number(sh, &val, state->optarg, "go-intent", 0, 15)) { + return -EINVAL; + } + params.connect.go_intent = (uint8_t)val; + break; + case 'f': + if (!parse_number(sh, &val, state->optarg, "freq", 0, 6000)) { + return -EINVAL; + } + params.connect.freq = (unsigned int)val; + break; + case 'j': + params.connect.join = true; + break; + case 'i': + /* Unused, but parsing to avoid unknown option error */ + break; + case 'h': + shell_help(sh); + return -ENOEXEC; + default: + PR_ERROR("Invalid option %c\n", state->optopt); + return -EINVAL; + } + } + + params.oper = WIFI_P2P_CONNECT; + + if (net_mgmt(NET_REQUEST_WIFI_P2P_OPER, iface, ¶ms, sizeof(params))) { + PR_WARNING("P2P connect request failed\n"); + return -ENOEXEC; + } + + /* Display the generated PIN for DISPLAY method */ + if (params.connect.method == WIFI_P2P_METHOD_DISPLAY && params.connect.pin[0] != '\0') { + PR("%s\n", params.connect.pin); + } else { + PR("P2P connection initiated\n"); + } + return 0; +} #endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P */ static int cmd_wifi_pmksa_flush(const struct shell *sh, size_t argc, char *argv[]) @@ -4452,6 +4558,25 @@ SHELL_STATIC_SUBCMD_SET_CREATE( ": Show detailed info for specific peer (format: XX:XX:XX:XX:XX:XX)\n" "[-i, --iface=]: Interface index\n", cmd_wifi_p2p_peer, 1, 3), + SHELL_CMD_ARG(connect, NULL, + "Connect to a P2P peer\n" + "Usage: connect [PIN] [options]\n" + ": Peer device MAC address (format: XX:XX:XX:XX:XX:XX)\n" + ": Use Push Button Configuration\n" + ": Use PIN method\n" + " - Without PIN: Device displays generated PIN for peer to enter\n" + " - With PIN: Device uses provided PIN to connect\n" + "[PIN]: 8-digit PIN (optional, generates if omitted)\n" + "[-g, --go-intent=<0-15>]: GO intent (0=client, 15=GO, default: 0)\n" + "[-f, --freq=]: Frequency in MHz (default: 2462)\n" + "[-j, --join]: Join an existing group (as a client) instead of starting GO negotiation\n" + "[-i, --iface=]: Interface index\n" + "[-h, --help]: Show help\n" + "Examples:\n" + " wifi p2p connect 9c:b1:50:e3:81:96 pin -g 0 (displays PIN)\n" + " wifi p2p connect 9c:b1:50:e3:81:96 pin 12345670 -g 0 (uses PIN)\n" + " wifi p2p connect f4:ce:36:01:00:38 pbc --join (join existing group)\n", + cmd_wifi_p2p_connect, 3, 6), SHELL_SUBCMD_SET_END ); From 04a9692a9173e5836b77c0a8956039aaae887a7a Mon Sep 17 00:00:00 2001 From: Kapil Bhatt Date: Fri, 7 Nov 2025 08:33:54 +0000 Subject: [PATCH 1626/3659] drivers: nrf_wifi: Add default value to p2p mode Kconfig The Kconfig NRF70_P2P_MODE should be enabled when WIFI_NM_WPA_SUPPLICANT_P2P is enabled. Signed-off-by: Kapil Bhatt --- drivers/wifi/nrf_wifi/Kconfig.nrfwifi | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/wifi/nrf_wifi/Kconfig.nrfwifi b/drivers/wifi/nrf_wifi/Kconfig.nrfwifi index a3e4c2d1fd60..5786f8cef145 100644 --- a/drivers/wifi/nrf_wifi/Kconfig.nrfwifi +++ b/drivers/wifi/nrf_wifi/Kconfig.nrfwifi @@ -119,6 +119,7 @@ config NRF70_ENABLE_DUAL_VIF config NRF70_P2P_MODE bool "P2P support in driver" + default y if WIFI_NM_WPA_SUPPLICANT_P2P config NRF70_SYSTEM_WITH_RAW_MODES bool "nRF70 system mode with raw modes" From aff682032fff2de822ee0fa6c9d9cd6cedf78a3d Mon Sep 17 00:00:00 2001 From: Kapil Bhatt Date: Fri, 7 Nov 2025 09:08:30 +0000 Subject: [PATCH 1627/3659] doc: networking: Add Wi-Fi P2P info Add Wi-Fi P2P mode build command and info. Signed-off-by: Kapil Bhatt --- doc/connectivity/networking/api/wifi.rst | 14 ++++++++++++++ doc/releases/release-notes-4.4.rst | 6 ++++++ 2 files changed, 20 insertions(+) diff --git a/doc/connectivity/networking/api/wifi.rst b/doc/connectivity/networking/api/wifi.rst index e0be44835443..e50a1f9fc74b 100644 --- a/doc/connectivity/networking/api/wifi.rst +++ b/doc/connectivity/networking/api/wifi.rst @@ -10,6 +10,7 @@ The Wi-Fi management API is used to manage Wi-Fi networks. It supports below mod * IEEE802.11 Station (STA) * IEEE802.11 Access Point (AP) +* IEEE802.11 P2P (Wi-Fi Direct) Only personal mode security is supported with below types: @@ -215,6 +216,19 @@ The test certificates in ``samples/net/wifi/test_certs/rsa2k`` are generated usi .. note:: These certificates are for testing only and should not be used in production. +Wi-Fi P2P (Wi-Fi Direct) +************************ + +Wi-Fi P2P or Wi-Fi Direct enables devices to communicate directly with each other without requiring +a traditional access point. This feature is particularly useful for device-to-device communication +scenarios. + +To enable and build with Wi-Fi P2P support: + +.. code-block:: bash + + $ west build -p -b samples/net/wifi/shell -- -DCONFIG_WIFI_NM_WPA_SUPPLICANT_P2P=y + API Reference ************* diff --git a/doc/releases/release-notes-4.4.rst b/doc/releases/release-notes-4.4.rst index 76705f4dc8b4..6176bfb717e9 100644 --- a/doc/releases/release-notes-4.4.rst +++ b/doc/releases/release-notes-4.4.rst @@ -183,6 +183,12 @@ New APIs and options * :kconfig:option:`CONFIG_NVMEM_FLASH` * :kconfig:option:`CONFIG_NVMEM_FLASH_WRITE` +* Networking + + * Wi-Fi + + * Add support for Wi-Fi Direct (P2P) mode. + * PWM * Extended API with PWM events From 7b6930b7466fb5bbb704d21128e0c03c1e7511b5 Mon Sep 17 00:00:00 2001 From: Ravi Dondaputi Date: Wed, 12 Nov 2025 12:32:52 +0530 Subject: [PATCH 1628/3659] modules: hostap: Add support for P2P GO mode ops Enable build time configs required for supporting P2P GO mode. Signed-off-by: Ravi Dondaputi --- modules/hostap/CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modules/hostap/CMakeLists.txt b/modules/hostap/CMakeLists.txt index e10804081c4f..52ede512bdd2 100644 --- a/modules/hostap/CMakeLists.txt +++ b/modules/hostap/CMakeLists.txt @@ -383,6 +383,9 @@ zephyr_library_sources_ifdef(CONFIG_WIFI_NM_WPA_SUPPLICANT_WPS ${HOSTAP_SRC_BASE}/wps/wps_enrollee.c ${HOSTAP_SRC_BASE}/wps/wps_registrar.c ${HOSTAP_SRC_BASE}/crypto/dh_groups.c + ${HOSTAP_SRC_BASE}/eap_server/eap_server_wsc.c + ${HOSTAP_SRC_BASE}/eap_server/eap_server.c + ${HOSTAP_SRC_BASE}/eap_server/eap_server_methods.c ) zephyr_library_compile_definitions_ifdef(CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P @@ -394,6 +397,7 @@ zephyr_library_compile_definitions_ifdef(CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P zephyr_library_compile_definitions_ifdef(CONFIG_WIFI_NM_WPA_SUPPLICANT_WPS CONFIG_WPS EAP_WSC + EAP_SERVER_WSC ) zephyr_library_sources_ifdef(CONFIG_WIFI_NM_HOSTAPD_WPS From 1da38b7d0af2d3a0c29057ae348155cdde043b02 Mon Sep 17 00:00:00 2001 From: Ravi Dondaputi Date: Wed, 12 Nov 2025 13:00:08 +0530 Subject: [PATCH 1629/3659] drivers: wifi: nrf_wifi: Add per-peer authorized flag Add per-peer authorized parameter. Port authorization command from supplicant will set this flag and will be used by driver to allow or nor allow data traffic. Signed-off-by: Ravi Dondaputi --- drivers/wifi/nrf_wifi/inc/fmac_main.h | 4 ++- drivers/wifi/nrf_wifi/src/fmac_main.c | 17 +++++++++ drivers/wifi/nrf_wifi/src/net_if.c | 39 ++++++++++++++++----- drivers/wifi/nrf_wifi/src/wifi_mgmt.c | 32 +++++++++++++---- drivers/wifi/nrf_wifi/src/wpa_supp_if.c | 46 +++++++++++++++++++++++-- 5 files changed, 119 insertions(+), 19 deletions(-) diff --git a/drivers/wifi/nrf_wifi/inc/fmac_main.h b/drivers/wifi/nrf_wifi/inc/fmac_main.h index 799beff1fbaf..857205eeebbc 100644 --- a/drivers/wifi/nrf_wifi/inc/fmac_main.h +++ b/drivers/wifi/nrf_wifi/inc/fmac_main.h @@ -75,7 +75,7 @@ struct nrf_wifi_vif_ctx_zep { #endif /* CONFIG_NET_STATISTICS_ETHERNET_VENDOR */ struct net_stats_eth eth_stats; #endif /* CONFIG_NET_STATISTICS_ETHERNET */ -#if defined(CONFIG_NRF70_STA_MODE) || defined(CONFIG_NRF70_RAW_DATA_RX) +#if defined(CONFIG_NRF70_STA_MODE) || defined(CONFIG_NRF70_RAW_DATA_TX) bool authorized; #endif #ifdef CONFIG_NRF70_STA_MODE @@ -154,6 +154,8 @@ void configure_tx_pwr_settings(struct nrf_wifi_tx_pwr_ctrl_params *tx_pwr_ctrl_p void configure_board_dep_params(struct nrf_wifi_board_params *board_params); void set_tx_pwr_ceil_default(struct nrf_wifi_tx_pwr_ceil_params *pwr_ceil_params); const char *nrf_wifi_get_drv_version(void); +char *nrf_wifi_sprint_ll_addr_buf(const uint8_t *ll, uint8_t ll_len, + char *buf, int buflen); enum nrf_wifi_status nrf_wifi_fmac_dev_add_zep(struct nrf_wifi_drv_priv_zep *drv_priv_zep); enum nrf_wifi_status nrf_wifi_fmac_dev_rem_zep(struct nrf_wifi_drv_priv_zep *drv_priv_zep); struct nrf_wifi_vif_ctx_zep *nrf_wifi_get_vif_ctx(struct net_if *iface); diff --git a/drivers/wifi/nrf_wifi/src/fmac_main.c b/drivers/wifi/nrf_wifi/src/fmac_main.c index bd40cb74d67d..96390f8e5fd2 100644 --- a/drivers/wifi/nrf_wifi/src/fmac_main.c +++ b/drivers/wifi/nrf_wifi/src/fmac_main.c @@ -47,6 +47,7 @@ LOG_MODULE_DECLARE(wifi_nrf, CONFIG_WIFI_NRF70_LOG_LEVEL); struct nrf_wifi_drv_priv_zep rpu_drv_priv_zep; extern const struct nrf_wifi_osal_ops nrf_wifi_os_zep_ops; +extern char *net_sprint_ll_addr_buf(const uint8_t *ll, uint8_t ll_len, char *buf, int buflen); /* 3 bytes for addreess, 3 bytes for length */ #define MAX_PKT_RAM_TX_ALIGN_OVERHEAD 6 @@ -101,6 +102,22 @@ static const unsigned int rx3_buf_sz = CONFIG_NRF70_RX_MAX_DATA_SIZE; struct nrf_wifi_drv_priv_zep rpu_drv_priv_zep; static K_MUTEX_DEFINE(reg_lock); +/** + * @brief Format a link layer address to a string buffer. + * + * @param ll Pointer to the link layer address bytes. + * @param ll_len Length of the link layer address (typically 6 for MAC). + * @param buf Buffer to store the formatted string. + * @param buflen Size of the buffer. + * + * @return Pointer to the buffer on success, NULL on failure. + */ +char *nrf_wifi_sprint_ll_addr_buf(const uint8_t *ll, uint8_t ll_len, + char *buf, int buflen) +{ + return net_sprint_ll_addr_buf(ll, NET_ETH_ADDR_LEN, buf, buflen); +} + const char *nrf_wifi_get_drv_version(void) { return NRF70_DRIVER_VERSION; diff --git a/drivers/wifi/nrf_wifi/src/net_if.c b/drivers/wifi/nrf_wifi/src/net_if.c index 9a9d7d670267..cafe8dd7e321 100644 --- a/drivers/wifi/nrf_wifi/src/net_if.c +++ b/drivers/wifi/nrf_wifi/src/net_if.c @@ -25,14 +25,12 @@ LOG_MODULE_DECLARE(wifi_nrf, CONFIG_WIFI_NRF70_LOG_LEVEL); #include "util.h" #include "common/fmac_util.h" +#include "system/fmac_peer.h" #include "shim.h" #include "fmac_main.h" #include "wpa_supp_if.h" #include "net_if.h" -extern char *net_sprint_ll_addr_buf(const uint8_t *ll, uint8_t ll_len, - char *buf, int buflen); - #ifdef CONFIG_NRF70_STA_MODE static struct net_if_mcast_monitor mcast_monitor; #endif /* CONFIG_NRF70_STA_MODE */ @@ -388,6 +386,9 @@ int nrf_wifi_if_send(const struct device *dev, struct rpu_host_stats *host_stats = NULL; void *nbuf = NULL; bool locked = false; + unsigned char *ra = NULL; + int peer_id = -1; + bool authorized; if (!dev || !pkt) { LOG_ERR("%s: vif_ctx_zep is NULL", __func__); @@ -436,12 +437,30 @@ int nrf_wifi_if_send(const struct device *dev, nbuf); } else { #endif /* CONFIG_NRF70_RAW_DATA_TX */ + + ra = nrf_wifi_util_get_ra(sys_dev_ctx->vif_ctx[vif_ctx_zep->vif_idx], nbuf); + peer_id = nrf_wifi_fmac_peer_get_id(rpu_ctx_zep->rpu_ctx, ra); + if (peer_id == -1) { + char ra_buf[18] = {0}; + + LOG_ERR("%s: Got packet for unknown PEER: %s", __func__, + nrf_wifi_sprint_ll_addr_buf(ra, 6, ra_buf, + sizeof(ra_buf))); + goto drop; + } + + /* VIF or per-peer depending on RA */ + if (peer_id == MAX_PEERS) { + authorized = vif_ctx_zep->authorized; + } else { + authorized = sys_dev_ctx->tx_config.peers[peer_id].authorized; + } + if ((vif_ctx_zep->if_carr_state != NRF_WIFI_FMAC_IF_CARR_STATE_ON) || - (!vif_ctx_zep->authorized && !is_eapol(pkt))) { + (!authorized && !is_eapol(pkt))) { ret = -EPERM; goto drop; } - ret = nrf_wifi_fmac_start_xmit(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx, nbuf); @@ -484,7 +503,6 @@ static void ip_maddr_event_handler(struct net_if *iface, struct net_eth_addr mac_addr; struct nrf_wifi_umac_mcast_cfg *mcast_info = NULL; enum nrf_wifi_status status; - uint8_t mac_string_buf[sizeof("xx:xx:xx:xx:xx:xx")]; struct nrf_wifi_ctx_zep *rpu_ctx_zep = NULL; int ret; @@ -540,12 +558,15 @@ static void ip_maddr_event_handler(struct net_if *iface, vif_ctx_zep->vif_idx, mcast_info); if (status == NRF_WIFI_STATUS_FAIL) { + char mac_string_buf[sizeof("xx:xx:xx:xx:xx:xx")]; + LOG_ERR("%s: nrf_wifi_fmac_set_multicast failed for" " mac addr=%s", __func__, - net_sprint_ll_addr_buf(mac_addr.addr, - WIFI_MAC_ADDR_LEN, mac_string_buf, - sizeof(mac_string_buf))); + nrf_wifi_sprint_ll_addr_buf(mac_addr.addr, + WIFI_MAC_ADDR_LEN, + mac_string_buf, + sizeof(mac_string_buf))); } unlock: nrf_wifi_osal_mem_free(mcast_info); diff --git a/drivers/wifi/nrf_wifi/src/wifi_mgmt.c b/drivers/wifi/nrf_wifi/src/wifi_mgmt.c index 6bb31241b295..4c98ef0d8aa0 100644 --- a/drivers/wifi/nrf_wifi/src/wifi_mgmt.c +++ b/drivers/wifi/nrf_wifi/src/wifi_mgmt.c @@ -18,6 +18,7 @@ #include "system/fmac_api.h" #include "system/fmac_tx.h" #include "common/fmac_util.h" +#include "common/fmac_structs_common.h" #include "fmac_main.h" #include "wifi_mgmt.h" @@ -757,6 +758,8 @@ int nrf_wifi_mode(const struct device *dev, struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL; struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL; struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL; + struct peers_info *peer = NULL; + int i = 0; int ret = -1; if (!dev || !mode) { @@ -798,10 +801,16 @@ int nrf_wifi_mode(const struct device *dev, goto out; } - if (vif_ctx_zep->authorized && (mode->mode == NRF_WIFI_MONITOR_MODE)) { - LOG_ERR("%s: Cannot set monitor mode when station is connected", - __func__); - goto out; + for (i = 0; i < MAX_PEERS; i++) { + peer = &sys_dev_ctx->tx_config.peers[i]; + if (peer->peer_id == -1) { + continue; + } + if (peer->authorized && (mode->mode == NRF_WIFI_MONITOR_MODE)) { + LOG_ERR("%s: Cannot set monitor mode when station is connected", + __func__); + goto out; + } } /** @@ -851,6 +860,8 @@ int nrf_wifi_channel(const struct device *dev, struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL; struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL; struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL; + struct peers_info *peer = NULL; + int i = 0; int ret = -1; if (!dev || !channel) { @@ -864,9 +875,16 @@ int nrf_wifi_channel(const struct device *dev, return ret; } - if (vif_ctx_zep->authorized) { - LOG_ERR("%s: Cannot change channel when in station connected mode", __func__); - return ret; + for (i = 0; i < MAX_PEERS; i++) { + peer = &sys_dev_ctx->tx_config.peers[i]; + if (peer->peer_id == -1) { + continue; + } + if (peer->authorized) { + LOG_ERR("%s: Cannot change channel when in station connected mode", + __func__); + return ret; + } } rpu_ctx_zep = vif_ctx_zep->rpu_ctx_zep; diff --git a/drivers/wifi/nrf_wifi/src/wpa_supp_if.c b/drivers/wifi/nrf_wifi/src/wpa_supp_if.c index 05cb5b87dc97..12b8fdcfca58 100644 --- a/drivers/wifi/nrf_wifi/src/wpa_supp_if.c +++ b/drivers/wifi/nrf_wifi/src/wpa_supp_if.c @@ -17,6 +17,7 @@ #include "common/fmac_util.h" #include "wifi_mgmt.h" #include "wpa_supp_if.h" +#include LOG_MODULE_DECLARE(wifi_nrf, CONFIG_WIFI_NRF70_LOG_LEVEL); @@ -1103,6 +1104,7 @@ int nrf_wifi_wpa_set_supp_port(void *if_priv, int authorized, char *bssid) struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL; struct nrf_wifi_umac_chg_sta_info chg_sta_info; struct nrf_wifi_ctx_zep *rpu_ctx_zep = NULL; + struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx; enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; int ret = -1; @@ -1124,6 +1126,12 @@ int nrf_wifi_wpa_set_supp_port(void *if_priv, int authorized, char *bssid) goto out; } + sys_dev_ctx = wifi_dev_priv(rpu_ctx_zep->rpu_ctx); + if (!sys_dev_ctx) { + LOG_ERR("%s: sys_dev_ctx is NULL", __func__); + goto out; + } + if (vif_ctx_zep->if_op_state != NRF_WIFI_FMAC_IF_OP_STATE_UP) { LOG_DBG("%s: Interface not UP, ignoring", __func__); ret = 0; @@ -1135,7 +1143,6 @@ int nrf_wifi_wpa_set_supp_port(void *if_priv, int authorized, char *bssid) memcpy(chg_sta_info.mac_addr, bssid, ETH_ALEN); vif_ctx_zep->authorized = authorized; - if (authorized) { /* BIT(NL80211_STA_FLAG_AUTHORIZED) */ chg_sta_info.sta_flags2.nrf_wifi_mask = 1 << 1; @@ -1153,6 +1160,10 @@ int nrf_wifi_wpa_set_supp_port(void *if_priv, int authorized, char *bssid) goto out; } + if (vif_ctx_zep->if_type == NRF_WIFI_IFTYPE_STATION) { + sys_dev_ctx->tx_config.peers[0].authorized = authorized; + } + ret = 0; out: k_mutex_unlock(&vif_ctx_zep->vif_lock); @@ -2952,8 +2963,11 @@ int nrf_wifi_wpa_supp_sta_set_flags(void *if_priv, const u8 *addr, struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL; struct nrf_wifi_umac_chg_sta_info chg_sta = {0}; struct nrf_wifi_ctx_zep *rpu_ctx_zep = NULL; + struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL; enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + int peer_id = -1; int ret = -1; + char buf[18] = {0}; if (!if_priv || !addr) { LOG_ERR("%s: Invalid params", __func__); @@ -2975,18 +2989,46 @@ int nrf_wifi_wpa_supp_sta_set_flags(void *if_priv, const u8 *addr, memcpy(chg_sta.mac_addr, addr, sizeof(chg_sta.mac_addr)); + if (!net_eth_is_addr_valid((struct net_eth_addr *)&chg_sta.mac_addr)) { + LOG_ERR("%s: Invalid peer MAC address: %s", __func__, + nrf_wifi_sprint_ll_addr_buf(chg_sta.mac_addr, 6, buf, + sizeof(buf))); + goto out; + } + + peer_id = nrf_wifi_fmac_peer_get_id(rpu_ctx_zep->rpu_ctx, chg_sta.mac_addr); + if (peer_id == -1) { + LOG_ERR("%s: Unknown PEER: %s", __func__, + nrf_wifi_sprint_ll_addr_buf(chg_sta.mac_addr, 6, buf, + sizeof(buf))); + goto out; + } + + if (peer_id == MAX_PEERS) { + LOG_ERR("%s: Invalid PEER (group): %s", __func__, + nrf_wifi_sprint_ll_addr_buf(chg_sta.mac_addr, 6, buf, + sizeof(buf))); + goto out; + } + chg_sta.sta_flags2.nrf_wifi_mask = nrf_wifi_sta_flags_to_nrf(flags_or | ~flags_and); chg_sta.sta_flags2.nrf_wifi_set = nrf_wifi_sta_flags_to_nrf(flags_or); LOG_DBG("%s %x, %x", __func__, chg_sta.sta_flags2.nrf_wifi_set, chg_sta.sta_flags2.nrf_wifi_mask); - status = nrf_wifi_sys_fmac_chg_sta(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx, &chg_sta); + status = nrf_wifi_sys_fmac_chg_sta(rpu_ctx_zep->rpu_ctx, + vif_ctx_zep->vif_idx, &chg_sta); if (status != NRF_WIFI_STATUS_SUCCESS) { LOG_ERR("%s: nrf_wifi_sys_fmac_chg_sta failed", __func__); goto out; } + sys_dev_ctx = wifi_dev_priv(rpu_ctx_zep->rpu_ctx); + + sys_dev_ctx->tx_config.peers[peer_id].authorized = + !!(chg_sta.sta_flags2.nrf_wifi_set & NRF_WIFI_STA_FLAG_AUTHORIZED); + ret = 0; out: From 4e5783f39a9a76a543ee7b4c54bb8d7cf4479dcb Mon Sep 17 00:00:00 2001 From: Kapil Bhatt Date: Thu, 13 Nov 2025 09:09:07 +0000 Subject: [PATCH 1630/3659] net: wifi: Add API support for P2P GO mode Add structures and API support for P2P Go mode. Signed-off-by: Kapil Bhatt --- include/zephyr/net/wifi_mgmt.h | 50 ++++++++++++ modules/hostap/src/supp_api.c | 141 +++++++++++++++++++++++++++++++++ 2 files changed, 191 insertions(+) diff --git a/include/zephyr/net/wifi_mgmt.h b/include/zephyr/net/wifi_mgmt.h index 0b0643b3b1c7..89965859fdb2 100644 --- a/include/zephyr/net/wifi_mgmt.h +++ b/include/zephyr/net/wifi_mgmt.h @@ -1467,6 +1467,12 @@ enum wifi_p2p_op { WIFI_P2P_PEER, /** P2P connect to peer */ WIFI_P2P_CONNECT, + /** P2P group add */ + WIFI_P2P_GROUP_ADD, + /** P2P group remove */ + WIFI_P2P_GROUP_REMOVE, + /** P2P invite */ + WIFI_P2P_INVITE, }; /** Wi-Fi P2P discovery type */ @@ -1524,6 +1530,50 @@ struct wifi_p2p_params { /** Join an existing group (as a client) instead of starting GO negotiation */ bool join; } connect; + /** Group add specific parameters */ + struct { + /** Frequency in MHz (0 = auto) */ + int freq; + /** Persistent group ID (-1 = not persistent) */ + int persistent; + /** Enable HT40 */ + bool ht40; + /** Enable VHT */ + bool vht; + /** Enable HE */ + bool he; + /** Enable EDMG */ + bool edmg; + /** GO BSSID (NULL = auto) */ + uint8_t go_bssid[WIFI_MAC_ADDR_LEN]; + /** GO BSSID length */ + uint8_t go_bssid_length; + } group_add; + /** Group remove specific parameters */ + struct { + /** Interface name (e.g., "wlan0") */ + char ifname[CONFIG_NET_INTERFACE_NAME_LEN + 1]; + } group_remove; + /** Invite specific parameters */ + struct { + /** Invite type: persistent or group */ + enum { + WIFI_P2P_INVITE_PERSISTENT = 0, + WIFI_P2P_INVITE_GROUP, + } type; + /** Persistent group ID (for persistent type) */ + int persistent_id; + /** Group interface name (for group type) */ + char group_ifname[CONFIG_NET_INTERFACE_NAME_LEN + 1]; + /** Peer MAC address */ + uint8_t peer_addr[WIFI_MAC_ADDR_LEN]; + /** Frequency in MHz (0 = auto) */ + int freq; + /** GO device address (for group type, NULL = auto) */ + uint8_t go_dev_addr[WIFI_MAC_ADDR_LEN]; + /** GO device address length */ + uint8_t go_dev_addr_length; + } invite; }; #endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P */ diff --git a/modules/hostap/src/supp_api.c b/modules/hostap/src/supp_api.c index 4e4beb1f0bcf..0fa5dee095e7 100644 --- a/modules/hostap/src/supp_api.c +++ b/modules/hostap/src/supp_api.c @@ -2941,6 +2941,147 @@ int supplicant_p2p_oper(const struct device *dev, struct wifi_p2p_params *params break; } + case WIFI_P2P_GROUP_ADD: { + int len = 0; + + if (params == NULL) { + wpa_printf(MSG_ERROR, "P2P group add params are NULL"); + return -EINVAL; + } + + len = snprintk(cmd_buf, sizeof(cmd_buf), "P2P_GROUP_ADD"); + + if (params->group_add.freq > 0) { + len += snprintk(cmd_buf + len, sizeof(cmd_buf) - len, " freq=%d", + params->group_add.freq); + } + + if (params->group_add.persistent >= 0) { + len += snprintk(cmd_buf + len, sizeof(cmd_buf) - len, " persistent=%d", + params->group_add.persistent); + } + + if (params->group_add.ht40 != 0) { + len += snprintk(cmd_buf + len, sizeof(cmd_buf) - len, " ht40"); + } + + if (params->group_add.vht != 0) { + len += snprintk(cmd_buf + len, sizeof(cmd_buf) - len, " vht"); + } + + if (params->group_add.he != 0) { + len += snprintk(cmd_buf + len, sizeof(cmd_buf) - len, " he"); + } + + if (params->group_add.edmg != 0) { + len += snprintk(cmd_buf + len, sizeof(cmd_buf) - len, " edmg"); + } + + if (params->group_add.go_bssid_length == WIFI_MAC_ADDR_LEN) { + len += snprintk(cmd_buf + len, sizeof(cmd_buf) - len, + " go_bssid=%02x:%02x:%02x:%02x:%02x:%02x", + params->group_add.go_bssid[0], + params->group_add.go_bssid[1], + params->group_add.go_bssid[2], + params->group_add.go_bssid[3], + params->group_add.go_bssid[4], + params->group_add.go_bssid[5]); + } + + ret = zephyr_wpa_cli_cmd_resp_noprint(wpa_s->ctrl_conn, cmd_buf, resp_buf); + if (ret < 0) { + wpa_printf(MSG_ERROR, "P2P_GROUP_ADD command failed: %d", ret); + return -EIO; + } + ret = 0; + break; + } + + case WIFI_P2P_GROUP_REMOVE: + if (params == NULL) { + wpa_printf(MSG_ERROR, "P2P group remove params are NULL"); + return -EINVAL; + } + + if (params->group_remove.ifname[0] == '\0') { + wpa_printf(MSG_ERROR, "Interface name required for P2P_GROUP_REMOVE"); + return -EINVAL; + } + + snprintk(cmd_buf, sizeof(cmd_buf), "P2P_GROUP_REMOVE %s", + params->group_remove.ifname); + + ret = zephyr_wpa_cli_cmd_resp_noprint(wpa_s->ctrl_conn, cmd_buf, resp_buf); + if (ret < 0) { + wpa_printf(MSG_ERROR, "P2P_GROUP_REMOVE command failed: %d", ret); + return -EIO; + } + ret = 0; + break; + + case WIFI_P2P_INVITE: { + char addr_str[18]; + int len = 0; + + if (params == NULL) { + wpa_printf(MSG_ERROR, "P2P invite params are NULL"); + return -EINVAL; + } + + snprintk(addr_str, sizeof(addr_str), "%02x:%02x:%02x:%02x:%02x:%02x", + params->invite.peer_addr[0], params->invite.peer_addr[1], + params->invite.peer_addr[2], params->invite.peer_addr[3], + params->invite.peer_addr[4], params->invite.peer_addr[5]); + + if (params->invite.type == WIFI_P2P_INVITE_PERSISTENT) { + if (params->invite.persistent_id < 0) { + wpa_printf(MSG_ERROR, "Persistent group ID required"); + return -EINVAL; + } + len = snprintk(cmd_buf, sizeof(cmd_buf), "P2P_INVITE persistent=%d peer=%s", + params->invite.persistent_id, addr_str); + + if (params->invite.freq > 0) { + len += snprintk(cmd_buf + len, sizeof(cmd_buf) - len, " freq=%d", + params->invite.freq); + } + } else if (params->invite.type == WIFI_P2P_INVITE_GROUP) { + if (params->invite.group_ifname[0] == '\0') { + wpa_printf(MSG_ERROR, "Group interface name required"); + return -EINVAL; + } + len = snprintk(cmd_buf, sizeof(cmd_buf), "P2P_INVITE group=%s peer=%s", + params->invite.group_ifname, addr_str); + + if (params->invite.freq > 0) { + len += snprintk(cmd_buf + len, sizeof(cmd_buf) - len, " freq=%d", + params->invite.freq); + } + + if (params->invite.go_dev_addr_length == WIFI_MAC_ADDR_LEN) { + len += snprintk(cmd_buf + len, sizeof(cmd_buf) - len, + " go_dev_addr=%02x:%02x:%02x:%02x:%02x:%02x", + params->invite.go_dev_addr[0], + params->invite.go_dev_addr[1], + params->invite.go_dev_addr[2], + params->invite.go_dev_addr[3], + params->invite.go_dev_addr[4], + params->invite.go_dev_addr[5]); + } + } else { + wpa_printf(MSG_ERROR, "Invalid invite type: %d", params->invite.type); + return -EINVAL; + } + + ret = zephyr_wpa_cli_cmd_resp_noprint(wpa_s->ctrl_conn, cmd_buf, resp_buf); + if (ret < 0) { + wpa_printf(MSG_ERROR, "P2P_INVITE command failed: %d", ret); + return -EIO; + } + ret = 0; + break; + } + default: wpa_printf(MSG_ERROR, "Unknown P2P operation: %d", params->oper); ret = -EINVAL; From bd1aec4ffcd553d5a3b62a5c4a22e5a3d0cd99fe Mon Sep 17 00:00:00 2001 From: Kapil Bhatt Date: Thu, 13 Nov 2025 09:10:42 +0000 Subject: [PATCH 1631/3659] net: wifi: Add Wi-Fi direct P2P GO mode shell command Add shell commands support for P2P GO mode. Signed-off-by: Kapil Bhatt --- subsys/net/l2/wifi/wifi_shell.c | 279 ++++++++++++++++++++++++++++++++ 1 file changed, 279 insertions(+) diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 538efe65d880..d5bb9e77a0b8 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -3828,6 +3828,256 @@ static int cmd_wifi_p2p_connect(const struct shell *sh, size_t argc, char *argv[ } return 0; } + +static int cmd_wifi_p2p_group_add(const struct shell *sh, size_t argc, char *argv[]) +{ + struct net_if *iface = get_iface(IFACE_TYPE_STA, argc, argv); + struct wifi_p2p_params params = {0}; + int opt; + int opt_index = 0; + struct sys_getopt_state *state; + static const struct sys_getopt_option long_options[] = { + {"freq", sys_getopt_required_argument, 0, 'f'}, + {"persistent", sys_getopt_required_argument, 0, 'p'}, + {"ht40", sys_getopt_no_argument, 0, 'h'}, + {"vht", sys_getopt_no_argument, 0, 'v'}, + {"he", sys_getopt_no_argument, 0, 'H'}, + {"edmg", sys_getopt_no_argument, 0, 'e'}, + {"go-bssid", sys_getopt_required_argument, 0, 'b'}, + {"iface", sys_getopt_required_argument, 0, 'i'}, + {"help", sys_getopt_no_argument, 0, '?'}, + {0, 0, 0, 0} + }; + long val; + uint8_t mac_addr[WIFI_MAC_ADDR_LEN]; + + context.sh = sh; + + params.oper = WIFI_P2P_GROUP_ADD; + params.group_add.freq = 0; + params.group_add.persistent = -1; + params.group_add.ht40 = false; + params.group_add.vht = false; + params.group_add.he = false; + params.group_add.edmg = false; + params.group_add.go_bssid_length = 0; + + while ((opt = sys_getopt_long(argc, argv, "f:p:hvHeb:i:?", long_options, + &opt_index)) != -1) { + state = sys_getopt_state_get(); + switch (opt) { + case 'f': + if (!parse_number(sh, &val, state->optarg, "freq", 0, 6000)) { + return -EINVAL; + } + params.group_add.freq = (int)val; + break; + case 'p': + if (!parse_number(sh, &val, state->optarg, "persistent", -1, 255)) { + return -EINVAL; + } + params.group_add.persistent = (int)val; + break; + case 'h': + params.group_add.ht40 = true; + break; + case 'v': + params.group_add.vht = true; + params.group_add.ht40 = true; + break; + case 'H': + params.group_add.he = true; + break; + case 'e': + params.group_add.edmg = true; + break; + case 'b': + if (sscanf(state->optarg, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", + &mac_addr[0], &mac_addr[1], &mac_addr[2], &mac_addr[3], + &mac_addr[4], &mac_addr[5]) != WIFI_MAC_ADDR_LEN) { + PR_ERROR("Invalid GO BSSID format. Use: XX:XX:XX:XX:XX:XX\n"); + return -EINVAL; + } + memcpy(params.group_add.go_bssid, mac_addr, WIFI_MAC_ADDR_LEN); + params.group_add.go_bssid_length = WIFI_MAC_ADDR_LEN; + break; + case 'i': + /* Unused, but parsing to avoid unknown option error */ + break; + case '?': + shell_help(sh); + return -ENOEXEC; + default: + PR_ERROR("Invalid option %c\n", state->optopt); + return -EINVAL; + } + } + + if (net_mgmt(NET_REQUEST_WIFI_P2P_OPER, iface, ¶ms, sizeof(params))) { + PR_WARNING("P2P group add request failed\n"); + return -ENOEXEC; + } + PR("P2P group add initiated\n"); + return 0; +} + +static int cmd_wifi_p2p_group_remove(const struct shell *sh, size_t argc, char *argv[]) +{ + struct net_if *iface = get_iface(IFACE_TYPE_STA, argc, argv); + struct wifi_p2p_params params = {0}; + + context.sh = sh; + + if (argc < 2) { + PR_ERROR("Interface name required. Usage: wifi p2p group_remove \n"); + return -EINVAL; + } + + params.oper = WIFI_P2P_GROUP_REMOVE; + strncpy(params.group_remove.ifname, argv[1], + CONFIG_NET_INTERFACE_NAME_LEN); + params.group_remove.ifname[CONFIG_NET_INTERFACE_NAME_LEN] = '\0'; + + if (net_mgmt(NET_REQUEST_WIFI_P2P_OPER, iface, ¶ms, sizeof(params))) { + PR_WARNING("P2P group remove request failed\n"); + return -ENOEXEC; + } + PR("P2P group remove initiated\n"); + return 0; +} + +static int cmd_wifi_p2p_invite(const struct shell *sh, size_t argc, char *argv[]) +{ + struct net_if *iface = get_iface(IFACE_TYPE_STA, argc, argv); + struct wifi_p2p_params params = {0}; + uint8_t mac_addr[WIFI_MAC_ADDR_LEN]; + int opt; + int opt_index = 0; + struct sys_getopt_state *state; + static const struct sys_getopt_option long_options[] = { + {"persistent", sys_getopt_required_argument, 0, 'p'}, + {"group", sys_getopt_required_argument, 0, 'g'}, + {"peer", sys_getopt_required_argument, 0, 'P'}, + {"freq", sys_getopt_required_argument, 0, 'f'}, + {"go-dev-addr", sys_getopt_required_argument, 0, 'd'}, + {"iface", sys_getopt_required_argument, 0, 'i'}, + {"help", sys_getopt_no_argument, 0, 'h'}, + {0, 0, 0, 0} + }; + long val; + + context.sh = sh; + + params.oper = WIFI_P2P_INVITE; + params.invite.type = WIFI_P2P_INVITE_PERSISTENT; + params.invite.persistent_id = -1; + params.invite.group_ifname[0] = '\0'; + params.invite.freq = 0; + params.invite.go_dev_addr_length = 0; + memset(params.invite.peer_addr, 0, WIFI_MAC_ADDR_LEN); + + if (argc < 2) { + PR_ERROR("Usage: wifi p2p invite --persistent= OR " + "wifi p2p invite --group= --peer= [options]\n"); + return -EINVAL; + } + + while ((opt = sys_getopt_long(argc, argv, "p:g:P:f:d:i:h", long_options, + &opt_index)) != -1) { + state = sys_getopt_state_get(); + switch (opt) { + case 'p': + if (!parse_number(sh, &val, state->optarg, "persistent", 0, 255)) { + return -EINVAL; + } + params.invite.type = WIFI_P2P_INVITE_PERSISTENT; + params.invite.persistent_id = (int)val; + break; + case 'g': + params.invite.type = WIFI_P2P_INVITE_GROUP; + strncpy(params.invite.group_ifname, state->optarg, + CONFIG_NET_INTERFACE_NAME_LEN); + params.invite.group_ifname[CONFIG_NET_INTERFACE_NAME_LEN] = '\0'; + break; + case 'P': + if (sscanf(state->optarg, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", + &mac_addr[0], &mac_addr[1], &mac_addr[2], &mac_addr[3], + &mac_addr[4], &mac_addr[5]) != WIFI_MAC_ADDR_LEN) { + PR_ERROR("Invalid peer MAC address format\n"); + return -EINVAL; + } + memcpy(params.invite.peer_addr, mac_addr, WIFI_MAC_ADDR_LEN); + break; + case 'f': + if (!parse_number(sh, &val, state->optarg, "freq", 0, 6000)) { + return -EINVAL; + } + params.invite.freq = (int)val; + break; + case 'd': + if (sscanf(state->optarg, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", + &mac_addr[0], &mac_addr[1], &mac_addr[2], &mac_addr[3], + &mac_addr[4], &mac_addr[5]) != WIFI_MAC_ADDR_LEN) { + PR_ERROR("Invalid GO device address format\n"); + return -EINVAL; + } + memcpy(params.invite.go_dev_addr, mac_addr, WIFI_MAC_ADDR_LEN); + params.invite.go_dev_addr_length = WIFI_MAC_ADDR_LEN; + break; + case 'i': + /* Unused, but parsing to avoid unknown option error */ + break; + case 'h': + shell_help(sh); + return -ENOEXEC; + default: + PR_ERROR("Invalid option %c\n", state->optopt); + return -EINVAL; + } + } + + state = sys_getopt_state_get(); + + if (params.invite.type == WIFI_P2P_INVITE_PERSISTENT && + params.invite.persistent_id >= 0 && + params.invite.peer_addr[0] == 0 && params.invite.peer_addr[1] == 0 && + argc > state->optind && argv[state->optind][0] != '-') { + if (sscanf(argv[state->optind], "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", + &mac_addr[0], &mac_addr[1], &mac_addr[2], &mac_addr[3], + &mac_addr[4], &mac_addr[5]) != WIFI_MAC_ADDR_LEN) { + PR_ERROR("Invalid peer MAC address format\n"); + return -EINVAL; + } + memcpy(params.invite.peer_addr, mac_addr, WIFI_MAC_ADDR_LEN); + } + + if (params.invite.type == WIFI_P2P_INVITE_PERSISTENT) { + if (params.invite.persistent_id < 0) { + PR_ERROR("Persistent group ID required. Use --persistent=\n"); + return -EINVAL; + } + if (params.invite.peer_addr[0] == 0 && params.invite.peer_addr[1] == 0) { + PR_ERROR("Peer MAC address required\n"); + return -EINVAL; + } + } else if (params.invite.type == WIFI_P2P_INVITE_GROUP) { + if (params.invite.group_ifname[0] == '\0') { + PR_ERROR("Group interface name required. Use --group=\n"); + return -EINVAL; + } + if (params.invite.peer_addr[0] == 0 && params.invite.peer_addr[1] == 0) { + PR_ERROR("Peer MAC address required. Use --peer=\n"); + return -EINVAL; + } + } + + if (net_mgmt(NET_REQUEST_WIFI_P2P_OPER, iface, ¶ms, sizeof(params))) { + PR_WARNING("P2P invite request failed\n"); + return -ENOEXEC; + } + PR("P2P invite initiated\n"); + return 0; +} #endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P */ static int cmd_wifi_pmksa_flush(const struct shell *sh, size_t argc, char *argv[]) @@ -4577,6 +4827,35 @@ SHELL_STATIC_SUBCMD_SET_CREATE( " wifi p2p connect 9c:b1:50:e3:81:96 pin 12345670 -g 0 (uses PIN)\n" " wifi p2p connect f4:ce:36:01:00:38 pbc --join (join existing group)\n", cmd_wifi_p2p_connect, 3, 6), + SHELL_CMD_ARG(group_add, NULL, + "Add a P2P group (start as GO)\n" + "Usage: group_add [options]\n" + "[-f, --freq=]: Frequency in MHz (0 = auto)\n" + "[-p, --persistent=]: Persistent group ID (-1 = not persistent)\n" + "[-h, --ht40]: Enable HT40\n" + "[-v, --vht]: Enable VHT (also enables HT40)\n" + "[-H, --he]: Enable HE\n" + "[-e, --edmg]: Enable EDMG\n" + "[-b, --go-bssid=]: GO BSSID (format: XX:XX:XX:XX:XX:XX)\n" + "[-i, --iface=]: Interface index\n", + cmd_wifi_p2p_group_add, 1, 10), + SHELL_CMD_ARG(group_remove, NULL, + "Remove a P2P group\n" + "Usage: group_remove \n" + ": Interface name (e.g., wlan0)\n" + "[-i, --iface=]: Interface index\n", + cmd_wifi_p2p_group_remove, 2, 3), + SHELL_CMD_ARG(invite, NULL, + "Invite a peer to a P2P group\n" + "Usage: invite --persistent= OR\n" + " invite --group= --peer= [options]\n" + "[-p, --persistent=]: Persistent group ID\n" + "[-g, --group=]: Group interface name\n" + "[-P, --peer=]: Peer MAC address (format: XX:XX:XX:XX:XX:XX)\n" + "[-f, --freq=]: Frequency in MHz (0 = auto)\n" + "[-d, --go-dev-addr=]: GO device address (for group type)\n" + "[-i, --iface=]: Interface index\n", + cmd_wifi_p2p_invite, 2, 8), SHELL_SUBCMD_SET_END ); From fbc0429906e04a7cdca7c56c91a1d37f02826eca Mon Sep 17 00:00:00 2001 From: Ravi Dondaputi Date: Mon, 17 Nov 2025 23:32:15 +0530 Subject: [PATCH 1632/3659] drivers: wifi: nrf_wifi: Add P2P powersave support Add ops to handle P2P powersave configuration. Signed-off-by: Ravi Dondaputi --- drivers/wifi/nrf_wifi/inc/wpa_supp_if.h | 1 + drivers/wifi/nrf_wifi/src/fmac_main.c | 1 + drivers/wifi/nrf_wifi/src/wpa_supp_if.c | 45 +++++++++++++++++++++++++ 3 files changed, 47 insertions(+) diff --git a/drivers/wifi/nrf_wifi/inc/wpa_supp_if.h b/drivers/wifi/nrf_wifi/inc/wpa_supp_if.h index 28aadae28ebd..b4ec7545be49 100644 --- a/drivers/wifi/nrf_wifi/inc/wpa_supp_if.h +++ b/drivers/wifi/nrf_wifi/inc/wpa_supp_if.h @@ -133,6 +133,7 @@ int nrf_wifi_supp_set_country(void *if_priv, const char *alpha2); int nrf_wifi_supp_get_country(void *if_priv, char *alpha2); int nrf_wifi_supp_remain_on_channel(void *if_priv, unsigned int freq, unsigned int duration); int nrf_wifi_supp_cancel_remain_on_channel(void *if_priv); +int nrf_wifi_supp_set_p2p_powersave(void *if_priv, int legacy_ps, int opp_ps, int ctwindow); #endif /* CONFIG_NRF70_STA_MODE */ #ifdef CONFIG_NRF70_AP_MODE diff --git a/drivers/wifi/nrf_wifi/src/fmac_main.c b/drivers/wifi/nrf_wifi/src/fmac_main.c index 96390f8e5fd2..d0deb0d4656d 100644 --- a/drivers/wifi/nrf_wifi/src/fmac_main.c +++ b/drivers/wifi/nrf_wifi/src/fmac_main.c @@ -971,6 +971,7 @@ static const struct zep_wpa_supp_dev_ops wpa_supp_ops = { .get_country = nrf_wifi_supp_get_country, .remain_on_channel = nrf_wifi_supp_remain_on_channel, .cancel_remain_on_channel = nrf_wifi_supp_cancel_remain_on_channel, + .set_p2p_powersave = nrf_wifi_supp_set_p2p_powersave, #ifdef CONFIG_NRF70_AP_MODE .init_ap = nrf_wifi_wpa_supp_init_ap, .start_ap = nrf_wifi_wpa_supp_start_ap, diff --git a/drivers/wifi/nrf_wifi/src/wpa_supp_if.c b/drivers/wifi/nrf_wifi/src/wpa_supp_if.c index 12b8fdcfca58..dfcb0c57cea0 100644 --- a/drivers/wifi/nrf_wifi/src/wpa_supp_if.c +++ b/drivers/wifi/nrf_wifi/src/wpa_supp_if.c @@ -2148,6 +2148,51 @@ int nrf_wifi_supp_cancel_remain_on_channel(void *if_priv) return status; } +int nrf_wifi_supp_set_p2p_powersave(void *if_priv, int legacy_ps, int opp_ps, int ctwindow) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; +#ifdef NRF70_P2P_MODE + struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL; + struct nrf_wifi_ctx_zep *rpu_ctx_zep = NULL; + + if (if_priv == NULL) { + LOG_ERR("%s: Invalid params", __func__); + return -1; + } + vif_ctx_zep = if_priv; + rpu_ctx_zep = vif_ctx_zep->rpu_ctx_zep; + if (rpu_ctx_zep == NULL) { + LOG_ERR("%s: rpu_ctx_zep is NULL", __func__); + return -1; + } + k_mutex_lock(&vif_ctx_zep->vif_lock, K_FOREVER); + if (rpu_ctx_zep->rpu_ctx == NULL) { + LOG_DBG("%s: RPU context not initialized", __func__); + goto out; + } + + if (legacy_ps == -1) { + status = 0; + goto out; + } + + if (legacy_ps != 0 && legacy_ps != 1) { + LOG_ERR("%s: Invalid legacy_ps value: %d", __func__, legacy_ps); + goto out; + } + + status = nrf_wifi_sys_fmac_set_power_save(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx, + legacy_ps); + if (status != NRF_WIFI_STATUS_SUCCESS) { + LOG_ERR("%s: nrf_wifi_fmac_set_p2p_powersave failed", __func__); + goto out; + } +out: + k_mutex_unlock(&vif_ctx_zep->vif_lock); +#endif /* NRF70_P2P_MODE */ + return status; +} + #ifdef CONFIG_NRF70_AP_MODE static int nrf_wifi_vif_state_change(struct nrf_wifi_vif_ctx_zep *vif_ctx_zep, enum nrf_wifi_fmac_if_op_state state) From 8a5b39fd2777af3c9e6e8d60f94432ba37178e49 Mon Sep 17 00:00:00 2001 From: Ravi Dondaputi Date: Mon, 17 Nov 2025 23:33:01 +0530 Subject: [PATCH 1633/3659] drivers: wifi: nrf_wifi: Add cookie handling support Add cookie event callbacks to track RoC and cancel-RoC requests and its responses from firmware. Signed-off-by: Ravi Dondaputi --- drivers/wifi/nrf_wifi/inc/wpa_supp_if.h | 5 +++-- drivers/wifi/nrf_wifi/src/fmac_main.c | 5 +++++ drivers/wifi/nrf_wifi/src/wpa_supp_if.c | 11 ++++++----- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/drivers/wifi/nrf_wifi/inc/wpa_supp_if.h b/drivers/wifi/nrf_wifi/inc/wpa_supp_if.h index b4ec7545be49..321705308d1a 100644 --- a/drivers/wifi/nrf_wifi/inc/wpa_supp_if.h +++ b/drivers/wifi/nrf_wifi/inc/wpa_supp_if.h @@ -131,8 +131,9 @@ void nrf_wifi_supp_event_roc_cancel_complete(void *os_vif_ctx, unsigned int event_len); int nrf_wifi_supp_set_country(void *if_priv, const char *alpha2); int nrf_wifi_supp_get_country(void *if_priv, char *alpha2); -int nrf_wifi_supp_remain_on_channel(void *if_priv, unsigned int freq, unsigned int duration); -int nrf_wifi_supp_cancel_remain_on_channel(void *if_priv); +int nrf_wifi_supp_remain_on_channel(void *if_priv, unsigned int freq, + unsigned int duration, u64 host_cookie); +int nrf_wifi_supp_cancel_remain_on_channel(void *if_priv, u64 rpu_cookie); int nrf_wifi_supp_set_p2p_powersave(void *if_priv, int legacy_ps, int opp_ps, int ctwindow); #endif /* CONFIG_NRF70_STA_MODE */ diff --git a/drivers/wifi/nrf_wifi/src/fmac_main.c b/drivers/wifi/nrf_wifi/src/fmac_main.c index d0deb0d4656d..5ddf11a14254 100644 --- a/drivers/wifi/nrf_wifi/src/fmac_main.c +++ b/drivers/wifi/nrf_wifi/src/fmac_main.c @@ -456,6 +456,11 @@ void nrf_wifi_event_proc_cookie_rsp(void *vif_ctx, /* TODO: When supp_callbk_fns.mgmt_tx_status is implemented, add logic * here to use the cookie and host_cookie to map requests to responses. */ + if (vif_ctx_zep->supp_drv_if_ctx && + vif_ctx_zep->supp_callbk_fns.cookie_event) { + vif_ctx_zep->supp_callbk_fns.cookie_event(vif_ctx_zep->supp_drv_if_ctx, + cookie_rsp_event->host_cookie, cookie_rsp_event->cookie); + } } #endif /* CONFIG_NRF70_STA_MODE */ diff --git a/drivers/wifi/nrf_wifi/src/wpa_supp_if.c b/drivers/wifi/nrf_wifi/src/wpa_supp_if.c index dfcb0c57cea0..0b65efe11c49 100644 --- a/drivers/wifi/nrf_wifi/src/wpa_supp_if.c +++ b/drivers/wifi/nrf_wifi/src/wpa_supp_if.c @@ -2032,7 +2032,7 @@ void nrf_wifi_supp_event_remain_on_channel(void *if_priv, if (vif_ctx_zep->supp_drv_if_ctx && vif_ctx_zep->supp_callbk_fns.roc_complete) { vif_ctx_zep->supp_callbk_fns.roc_complete(vif_ctx_zep->supp_drv_if_ctx, roc_complete->frequency, - roc_complete->dur); + roc_complete->dur, roc_complete->cookie); } } @@ -2061,12 +2061,12 @@ void nrf_wifi_supp_event_roc_cancel_complete(void *if_priv, if (vif_ctx_zep->supp_drv_if_ctx && vif_ctx_zep->supp_callbk_fns.roc_cancel_complete) { vif_ctx_zep->supp_callbk_fns.roc_cancel_complete(vif_ctx_zep->supp_drv_if_ctx, - roc_cancel_complete->frequency); + roc_cancel_complete->frequency, roc_cancel_complete->cookie); } } int nrf_wifi_supp_remain_on_channel(void *if_priv, unsigned int freq, - unsigned int duration) + unsigned int duration, u64 host_cookie) { enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; #ifdef NRF70_P2P_MODE @@ -2099,6 +2099,7 @@ int nrf_wifi_supp_remain_on_channel(void *if_priv, unsigned int freq, roc_info.nrf_wifi_freq_params.center_frequency2 = 0; roc_info.nrf_wifi_freq_params.channel_type = NRF_WIFI_CHAN_HT20; roc_info.dur = duration; + roc_info.host_cookie = host_cookie; status = nrf_wifi_sys_fmac_p2p_roc_start(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx, &roc_info); @@ -2112,7 +2113,7 @@ int nrf_wifi_supp_remain_on_channel(void *if_priv, unsigned int freq, return status; } -int nrf_wifi_supp_cancel_remain_on_channel(void *if_priv) +int nrf_wifi_supp_cancel_remain_on_channel(void *if_priv, u64 cookie) { enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; #ifdef NRF70_P2P_MODE @@ -2137,7 +2138,7 @@ int nrf_wifi_supp_cancel_remain_on_channel(void *if_priv) goto out; } - status = nrf_wifi_sys_fmac_p2p_roc_stop(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx, 0); + status = nrf_wifi_sys_fmac_p2p_roc_stop(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx, cookie); if (status != NRF_WIFI_STATUS_SUCCESS) { LOG_ERR("%s: nrf_wifi_fmac_cancel_remain_on_channel failed", __func__); goto out; From 094d30cc0537bf2845795fbb9c32ff38f644652a Mon Sep 17 00:00:00 2001 From: Kapil Bhatt Date: Tue, 18 Nov 2025 12:39:11 +0000 Subject: [PATCH 1634/3659] net: wifi: Add API support for P2P power save Add API support for P2P power save. Signed-off-by: Kapil Bhatt --- include/zephyr/net/wifi_mgmt.h | 4 ++++ modules/hostap/src/supp_api.c | 14 ++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/include/zephyr/net/wifi_mgmt.h b/include/zephyr/net/wifi_mgmt.h index 89965859fdb2..a04b352737e1 100644 --- a/include/zephyr/net/wifi_mgmt.h +++ b/include/zephyr/net/wifi_mgmt.h @@ -1473,6 +1473,8 @@ enum wifi_p2p_op { WIFI_P2P_GROUP_REMOVE, /** P2P invite */ WIFI_P2P_INVITE, + /** P2P power save */ + WIFI_P2P_POWER_SAVE, }; /** Wi-Fi P2P discovery type */ @@ -1514,6 +1516,8 @@ struct wifi_p2p_params { struct wifi_p2p_device_info *peers; /** Actual number of peers returned */ uint16_t peer_count; + /** Power save enabled (for power save operation) */ + bool power_save; /** Connect specific parameters */ struct { /** Connection method */ diff --git a/modules/hostap/src/supp_api.c b/modules/hostap/src/supp_api.c index 0fa5dee095e7..0dced93f4bed 100644 --- a/modules/hostap/src/supp_api.c +++ b/modules/hostap/src/supp_api.c @@ -3082,6 +3082,20 @@ int supplicant_p2p_oper(const struct device *dev, struct wifi_p2p_params *params break; } + case WIFI_P2P_POWER_SAVE: + snprintk(cmd_buf, sizeof(cmd_buf), "p2p_set ps %d", params->power_save ? 1 : 0); + ret = zephyr_wpa_cli_cmd_resp_noprint(wpa_s->ctrl_conn, cmd_buf, resp_buf); + if (ret < 0) { + wpa_printf(MSG_ERROR, "p2p_set ps command failed: %d", ret); + return -EIO; + } + if (strncmp(resp_buf, "FAIL", 4) == 0) { + wpa_printf(MSG_ERROR, "p2p_set ps command returned FAIL"); + return -EIO; + } + ret = 0; + break; + default: wpa_printf(MSG_ERROR, "Unknown P2P operation: %d", params->oper); ret = -EINVAL; From 85b8e880aab20ae5b321b1069290543ff711ae49 Mon Sep 17 00:00:00 2001 From: Kapil Bhatt Date: Tue, 18 Nov 2025 12:40:59 +0000 Subject: [PATCH 1635/3659] net: wifi: Add P2P power save shell command support Add shell command support for P2P power save. Signed-off-by: Kapil Bhatt --- subsys/net/l2/wifi/wifi_shell.c | 41 +++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index d5bb9e77a0b8..ff14bdccfd07 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -4078,6 +4078,40 @@ static int cmd_wifi_p2p_invite(const struct shell *sh, size_t argc, char *argv[] PR("P2P invite initiated\n"); return 0; } + +static int cmd_wifi_p2p_power_save(const struct shell *sh, size_t argc, char *argv[]) +{ + struct net_if *iface = get_iface(IFACE_TYPE_STA, argc, argv); + struct wifi_p2p_params params = {0}; + bool power_save_enable = false; + + context.sh = sh; + + if (argc < 2) { + PR_ERROR("Usage: wifi p2p power_save \n"); + return -EINVAL; + } + + if (strcmp(argv[1], "on") == 0) { + power_save_enable = true; + } else if (strcmp(argv[1], "off") == 0) { + power_save_enable = false; + } else { + PR_ERROR("Invalid argument. Use 'on' or 'off'\n"); + return -EINVAL; + } + + params.oper = WIFI_P2P_POWER_SAVE; + params.power_save = power_save_enable; + + if (net_mgmt(NET_REQUEST_WIFI_P2P_OPER, iface, ¶ms, sizeof(params))) { + PR_WARNING("P2P power save request failed\n"); + return -ENOEXEC; + } + + PR("P2P power save %s\n", power_save_enable ? "enabled" : "disabled"); + return 0; +} #endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_P2P */ static int cmd_wifi_pmksa_flush(const struct shell *sh, size_t argc, char *argv[]) @@ -4856,6 +4890,13 @@ SHELL_STATIC_SUBCMD_SET_CREATE( "[-d, --go-dev-addr=]: GO device address (for group type)\n" "[-i, --iface=]: Interface index\n", cmd_wifi_p2p_invite, 2, 8), + SHELL_CMD_ARG(power_save, NULL, + "Set P2P power save mode\n" + "Usage: power_save \n" + ": Enable P2P power save\n" + ": Disable P2P power save\n" + "[-i, --iface=]: Interface index\n", + cmd_wifi_p2p_power_save, 2, 3), SHELL_SUBCMD_SET_END ); From 02756ea9daf354b257487173df9a27b7983a6bba Mon Sep 17 00:00:00 2001 From: Ravi Dondaputi Date: Mon, 24 Nov 2025 19:26:58 +0530 Subject: [PATCH 1636/3659] drivers: wifi: nrf_wifi: Suppress 11b rates in P2P scan Add an identifier to P2P scan request. RPU can use this to differentiate it from regular scan requests and suppress 11b rates. Signed-off-by: Ravi Dondaputi --- drivers/wifi/nrf_wifi/src/wpa_supp_if.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/wifi/nrf_wifi/src/wpa_supp_if.c b/drivers/wifi/nrf_wifi/src/wpa_supp_if.c index 0b65efe11c49..d2aebfbb54ca 100644 --- a/drivers/wifi/nrf_wifi/src/wpa_supp_if.c +++ b/drivers/wifi/nrf_wifi/src/wpa_supp_if.c @@ -559,6 +559,10 @@ int nrf_wifi_wpa_supp_scan2(void *if_priv, struct wpa_driver_scan_params *params } } + if (params->p2p_probe) { + scan_info->scan_params.no_cck = 1; + } + scan_info->scan_reason = SCAN_CONNECT; /* Copy extra_ies */ From f71d52c4ddf565bb0c4db20af085a2fd0c3247b6 Mon Sep 17 00:00:00 2001 From: Triveni Danda Date: Fri, 28 Nov 2025 14:33:47 +0530 Subject: [PATCH 1637/3659] drivers: wifi: nrf_wifi: Fix invalid pointer access Fix pointer dereferencing by accessing the pointer only after initialization, preventing fault exceptions. Signed-off-by: Triveni Danda --- drivers/wifi/nrf_wifi/src/wifi_mgmt.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/wifi/nrf_wifi/src/wifi_mgmt.c b/drivers/wifi/nrf_wifi/src/wifi_mgmt.c index 4c98ef0d8aa0..1fae3d2cf2a4 100644 --- a/drivers/wifi/nrf_wifi/src/wifi_mgmt.c +++ b/drivers/wifi/nrf_wifi/src/wifi_mgmt.c @@ -875,18 +875,6 @@ int nrf_wifi_channel(const struct device *dev, return ret; } - for (i = 0; i < MAX_PEERS; i++) { - peer = &sys_dev_ctx->tx_config.peers[i]; - if (peer->peer_id == -1) { - continue; - } - if (peer->authorized) { - LOG_ERR("%s: Cannot change channel when in station connected mode", - __func__); - return ret; - } - } - rpu_ctx_zep = vif_ctx_zep->rpu_ctx_zep; if (!rpu_ctx_zep) { LOG_ERR("%s: rpu_ctx_zep is NULL", __func__); @@ -902,6 +890,18 @@ int nrf_wifi_channel(const struct device *dev, fmac_dev_ctx = rpu_ctx_zep->rpu_ctx; sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + for (i = 0; i < MAX_PEERS; i++) { + peer = &sys_dev_ctx->tx_config.peers[i]; + if (peer->peer_id == -1) { + continue; + } + if (peer->authorized) { + LOG_ERR("%s: Cannot change channel when in station connected mode", + __func__); + return ret; + } + } + if (channel->oper == WIFI_MGMT_SET) { /** * Send the driver vif_idx instead of upper layer sent if_index. From 797a87c29c2a9d25d2ae923b15c8838873b0d30a Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Sun, 30 Nov 2025 21:27:34 +0530 Subject: [PATCH 1638/3659] modules: hostap: Fix SoF in softap mode Due to recent changes, the stack usage is increased, fix the SoF. Signed-off-by: Chaitanya Tata --- modules/hostap/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/hostap/Kconfig b/modules/hostap/Kconfig index 4ec31c21e199..fa47d6c1da9a 100644 --- a/modules/hostap/Kconfig +++ b/modules/hostap/Kconfig @@ -67,7 +67,7 @@ config WIFI_NM_WPA_SUPPLICANT_THREAD_STACK_SIZE # overflow issues. Need to identify the cause for higher stack usage. default 8192 if WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE || WIFI_USAGE_MODE_STA_AP # This is needed to handle stack overflow issues on nRF Wi-Fi drivers. - default 5900 if WIFI_NM_WPA_SUPPLICANT_AP + default 6144 if WIFI_NM_WPA_SUPPLICANT_AP default 5800 config WIFI_NM_WPA_SUPPLICANT_WQ_STACK_SIZE From ce937488b3947c26ed20621e9502c3fc2e36f368 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Mon, 1 Dec 2025 17:15:00 +0530 Subject: [PATCH 1639/3659] drivers: nrf_wifi: Workaround for failing tests Test automation framework fails if there are any error prints, and we had seen issues with networking that sends packets to the driver before the assocation is up (either not checking dormant status or in a window where dormant status is being updated). Add a workaround to suppress the print till the issue root cause is fixed. Signed-off-by: Chaitanya Tata --- drivers/wifi/nrf_wifi/src/net_if.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/wifi/nrf_wifi/src/net_if.c b/drivers/wifi/nrf_wifi/src/net_if.c index cafe8dd7e321..5d3187d0bdc3 100644 --- a/drivers/wifi/nrf_wifi/src/net_if.c +++ b/drivers/wifi/nrf_wifi/src/net_if.c @@ -441,11 +441,16 @@ int nrf_wifi_if_send(const struct device *dev, ra = nrf_wifi_util_get_ra(sys_dev_ctx->vif_ctx[vif_ctx_zep->vif_idx], nbuf); peer_id = nrf_wifi_fmac_peer_get_id(rpu_ctx_zep->rpu_ctx, ra); if (peer_id == -1) { + /* TODO: Make this an error once we fix ping_work sending packets despite + * the interface being dormant + */ +#if CONFIG_WIFI_NRF70_LOG_LEVEL >= LOG_LEVEL_DBG char ra_buf[18] = {0}; - LOG_ERR("%s: Got packet for unknown PEER: %s", __func__, + LOG_DBG("%s: Got packet for unknown PEER: %s", __func__, nrf_wifi_sprint_ll_addr_buf(ra, 6, ra_buf, sizeof(ra_buf))); +#endif goto drop; } From 3905d7a939ea011b06de6ada7c08b2290bc3e6fe Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Fri, 19 Dec 2025 01:44:34 +0530 Subject: [PATCH 1640/3659] drivers: nrf_wifi: Set VIF type for non-STA This is used in SoftAP/P2P GO modes. Signed-off-by: Chaitanya Tata --- drivers/wifi/nrf_wifi/src/wpa_supp_if.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/wifi/nrf_wifi/src/wpa_supp_if.c b/drivers/wifi/nrf_wifi/src/wpa_supp_if.c index d2aebfbb54ca..1afea6ab38be 100644 --- a/drivers/wifi/nrf_wifi/src/wpa_supp_if.c +++ b/drivers/wifi/nrf_wifi/src/wpa_supp_if.c @@ -2312,6 +2312,7 @@ static int nrf_wifi_iftype_change(struct nrf_wifi_vif_ctx_zep *vif_ctx_zep, int goto out; } + vif_ctx_zep->if_type = iftype; ret = nrf_wifi_vif_state_change(vif_ctx_zep, NRF_WIFI_FMAC_IF_OP_STATE_UP); if (ret) { LOG_ERR("%s: Failed to set interface up", __func__); From 45029ab469bfe5d1cef8f27c3cceeed981660f60 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Fri, 19 Dec 2025 01:42:32 +0530 Subject: [PATCH 1641/3659] drivers: nrf_wifi: Fix the port authorization logic For non-STA mode the vif level authorized flag is unused, simply allow all group traffic and for unicast traffic check respective peer status. Signed-off-by: Chaitanya Tata --- drivers/wifi/nrf_wifi/src/net_if.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/wifi/nrf_wifi/src/net_if.c b/drivers/wifi/nrf_wifi/src/net_if.c index 5d3187d0bdc3..0d8669f94a10 100644 --- a/drivers/wifi/nrf_wifi/src/net_if.c +++ b/drivers/wifi/nrf_wifi/src/net_if.c @@ -454,15 +454,20 @@ int nrf_wifi_if_send(const struct device *dev, goto drop; } - /* VIF or per-peer depending on RA */ - if (peer_id == MAX_PEERS) { + /* Use authorized from vif_ctx_zep for STA mode, or per-peer for AP/GO */ + if (vif_ctx_zep->if_type == NRF_WIFI_IFTYPE_STATION) { authorized = vif_ctx_zep->authorized; - } else { + } else if (peer_id != MAX_PEERS) { authorized = sys_dev_ctx->tx_config.peers[peer_id].authorized; + } else { + /* non-STA modes always allow group frames */ + authorized = true; } if ((vif_ctx_zep->if_carr_state != NRF_WIFI_FMAC_IF_CARR_STATE_ON) || (!authorized && !is_eapol(pkt))) { + LOG_DBG("%s: carrier state: %d, authorized: %d, is_eapol: %d", + __func__, vif_ctx_zep->if_carr_state, authorized, is_eapol(pkt)); ret = -EPERM; goto drop; } From baef40786cb49c09898374153ea258b2f6cb72a6 Mon Sep 17 00:00:00 2001 From: Ravi Dondaputi Date: Fri, 19 Dec 2025 23:19:01 +0530 Subject: [PATCH 1642/3659] drivers: wifi: nrf_wifi: Use filter_ssid for connect scan Modify the scan logic to use filter_ssids for connect scan and use ssids for other cases. Signed-off-by: Ravi Dondaputi --- drivers/wifi/nrf_wifi/src/wpa_supp_if.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/wifi/nrf_wifi/src/wpa_supp_if.c b/drivers/wifi/nrf_wifi/src/wpa_supp_if.c index 1afea6ab38be..d11d46c79e3a 100644 --- a/drivers/wifi/nrf_wifi/src/wpa_supp_if.c +++ b/drivers/wifi/nrf_wifi/src/wpa_supp_if.c @@ -546,7 +546,17 @@ int nrf_wifi_wpa_supp_scan2(void *if_priv, struct wpa_driver_scan_params *params scan_info->scan_params.num_scan_channels = indx; } - if (params->num_ssids) { + if (params->filter_ssids) { + scan_info->scan_params.num_scan_ssids = params->num_filter_ssids; + for (indx = 0; indx < params->num_filter_ssids; indx++) { + memcpy(scan_info->scan_params.scan_ssids[indx].nrf_wifi_ssid, + params->filter_ssids[indx].ssid, + params->filter_ssids[indx].ssid_len); + + scan_info->scan_params.scan_ssids[indx].nrf_wifi_ssid_len = + params->filter_ssids[indx].ssid_len; + } + } else if (params->num_ssids) { scan_info->scan_params.num_scan_ssids = params->num_ssids; for (indx = 0; indx < params->num_ssids; indx++) { From c1a4c78c5cf2626e4f6fd2dfd66fa0c53c461699 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 20 Oct 2025 15:21:18 +0100 Subject: [PATCH 1643/3659] scripts: snippets: Add support for board revisions Allows snippets to specify additional files for specific revisions of boards Signed-off-by: Jamie McCrae --- scripts/schemas/snippet-schema.yaml | 23 +++++++++++++++++++++++ scripts/snippets.py | 27 +++++++++++++++++++++++---- 2 files changed, 46 insertions(+), 4 deletions(-) diff --git a/scripts/schemas/snippet-schema.yaml b/scripts/schemas/snippet-schema.yaml index 360ff2caf0f1..b069a05e5a4f 100644 --- a/scripts/schemas/snippet-schema.yaml +++ b/scripts/schemas/snippet-schema.yaml @@ -17,6 +17,19 @@ # append: # EXTRA_DTC_OVERLAY_FILE: m3.overlay +# 'revisions' can also be used to include additional file(s) specific to a board revision: +# name: foo +# boards: +# nrf9160dk/nrf9160: +# append: +# # Base file will be applied first +# EXTRA_DTC_OVERLAY_FILE: first.overlay +# revisions: +# "0.7.0": +# append: +# # Will be applied on top of common board file +# EXTRA_DTC_OVERLAY_FILE: extra_0_7_0.overlay + $schema: "https://json-schema.org/draft/2020-12/schema" $id: "https://zephyrproject.org/schemas/zephyr/snippet" title: Zephyr snippet Schema @@ -51,6 +64,16 @@ properties: properties: append: $ref: "#/$defs/append-schema" + revisions: + type: object + patternProperties: + "(.*)": + type: object + properties: + append: + include: append-schema + additionalProperties: false + additionalProperties: false additionalProperties: false required: - name diff --git a/scripts/snippets.py b/scripts/snippets.py index 0662d0a3b4eb..e439c9af38b8 100644 --- a/scripts/snippets.py +++ b/scripts/snippets.py @@ -31,12 +31,13 @@ # Marker type for an 'append:' configuration. Maps variables # to the list of values to append to them. Appends = Dict[str, List[str]] +BoardRevisionAppends = Dict[str, Dict[str, List[str]]] def _new_append(): return defaultdict(list) def _new_board2appends(): - return defaultdict(_new_append) + return defaultdict(lambda: defaultdict(_new_append)) @dataclass class Snippet: @@ -45,7 +46,7 @@ class Snippet: name: str appends: Appends = field(default_factory=_new_append) - board2appends: Dict[str, Appends] = field(default_factory=_new_board2appends) + board2appends: Dict[str, BoardRevisionAppends] = field(default_factory=_new_board2appends) def process_data(self, pathobj: Path, snippet_data: dict, sysbuild: bool): '''Process the data in a snippet.yml file, after it is loaded into a @@ -68,10 +69,16 @@ def append_value(variable, value): if board.startswith('/') and not board.endswith('/'): _err(f"snippet file {pathobj}: board {board} starts with '/', so " "it must end with '/' to use a regular expression") + for revision, appenddata in settings.get('revisions', {}).items(): + for variable, value in appenddata.get('append', {}).items(): + if (sysbuild is True and variable[0:3] == 'SB_') or \ + (sysbuild is False and variable[0:3] != 'SB_'): + self.board2appends[board][revision][variable].append( + append_value(variable, value)) for variable, value in settings.get('append', {}).items(): if (sysbuild is True and variable[0:3] == 'SB_') or \ (sysbuild is False and variable[0:3] != 'SB_'): - self.board2appends[board][variable].append( + self.board2appends[board][""][variable].append( append_value(variable, value)) class Snippets(UserDict): @@ -173,7 +180,19 @@ def output_appends_for_board(self, board: str, appends: Appends): # Appends for board '{board}' if("${{BOARD}}${{BOARD_QUALIFIERS}}" STREQUAL "{board}") ''' - output += self.output_appends(appends, 1) + + # Output board variables first then board revision variables + output += self.output_appends(appends[""], 1) + + for revision in appends: + if revision != "": + output += f'''\ + # Appends for revision '{revision}' + if("${{BOARD_REVISION}}" STREQUAL "{revision}") +''' + output += self.output_appends(appends[revision], 2) + output += ' endif()\n' + output += 'endif()\n' return output From f1772b94f1546f815d394a41390dc64010b9a0b1 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Tue, 21 Oct 2025 12:14:51 +0100 Subject: [PATCH 1644/3659] tests: cmake: snippets: Add board revision check Adds a check that snippets are correctly applied to named boards with the correct board revision Signed-off-by: Jamie McCrae --- tests/cmake/snippets/Kconfig | 21 +++++++ .../snippets/snippets/ver_check/snippet.yml | 9 +++ .../snippets/ver_check/ver_check.conf | 2 + .../snippets/ver_check/ver_check_0_7_0.conf | 1 + tests/cmake/snippets/src/main.c | 17 ++++++ tests/cmake/snippets/testcase.yaml | 61 ++++++++++++++++--- 6 files changed, 104 insertions(+), 7 deletions(-) create mode 100644 tests/cmake/snippets/snippets/ver_check/snippet.yml create mode 100644 tests/cmake/snippets/snippets/ver_check/ver_check.conf create mode 100644 tests/cmake/snippets/snippets/ver_check/ver_check_0_7_0.conf diff --git a/tests/cmake/snippets/Kconfig b/tests/cmake/snippets/Kconfig index 7506a377d2d9..b56985d877dd 100644 --- a/tests/cmake/snippets/Kconfig +++ b/tests/cmake/snippets/Kconfig @@ -37,6 +37,16 @@ config TEST_TYPE_BAR_FOO help Test the snippet processing order (1. bar, 2. foo) +config TEST_TYPE_VER_CHECK + bool "Test Type: Version check" + help + Test board version snippet application + +config TEST_TYPE_VER_CHECK_SPECIFIC + bool "Test Type: Version check specific" + help + Test board version snippet application with specific board version + endchoice # Test values set by the snippet config overlays and tested by the test logic @@ -57,3 +67,14 @@ config TEST_COMMON_VAL help This option's value should be overridden by the snippet config overlays. + +# Used for testing board version snippets +config TEST_VER_CHECK_APPLIED + bool "Test version check snippet applied" + help + This option's value should be set by the ver_check snippet. + +config TEST_VER_CHECK_SPECIFIC_VERSION_APPLIED + bool "Test version check with board version snippet applied" + help + This option's value should be set by the ver_check snippet. diff --git a/tests/cmake/snippets/snippets/ver_check/snippet.yml b/tests/cmake/snippets/snippets/ver_check/snippet.yml new file mode 100644 index 000000000000..d4d958b3933c --- /dev/null +++ b/tests/cmake/snippets/snippets/ver_check/snippet.yml @@ -0,0 +1,9 @@ +name: ver_check +boards: + nrf9160dk/nrf9160: + revisions: + "0.7.0": + append: + EXTRA_CONF_FILE: ver_check_0_7_0.conf + append: + EXTRA_CONF_FILE: ver_check.conf diff --git a/tests/cmake/snippets/snippets/ver_check/ver_check.conf b/tests/cmake/snippets/snippets/ver_check/ver_check.conf new file mode 100644 index 000000000000..4b735bdeb2c8 --- /dev/null +++ b/tests/cmake/snippets/snippets/ver_check/ver_check.conf @@ -0,0 +1,2 @@ +CONFIG_TEST_VER_CHECK_APPLIED=y +CONFIG_TEST_VER_CHECK_SPECIFIC_VERSION_APPLIED=n diff --git a/tests/cmake/snippets/snippets/ver_check/ver_check_0_7_0.conf b/tests/cmake/snippets/snippets/ver_check/ver_check_0_7_0.conf new file mode 100644 index 000000000000..48d65309180c --- /dev/null +++ b/tests/cmake/snippets/snippets/ver_check/ver_check_0_7_0.conf @@ -0,0 +1 @@ +CONFIG_TEST_VER_CHECK_SPECIFIC_VERSION_APPLIED=y diff --git a/tests/cmake/snippets/src/main.c b/tests/cmake/snippets/src/main.c index c7ff97821427..6eb860c7eb74 100644 --- a/tests/cmake/snippets/src/main.c +++ b/tests/cmake/snippets/src/main.c @@ -19,6 +19,23 @@ #define TEST_BAR_VAL_BAR (964183) #define TEST_COMMON_VAL_BAR (109234) +/* Check board-specific snippet files */ +#if defined(CONFIG_TEST_TYPE_VER_CHECK) +#if !defined(CONFIG_TEST_VER_CHECK_APPLIED) +#error "Base ver_check snippet has not been applied" +#endif +#if defined(CONFIG_TEST_VER_CHECK_SPECIFIC_VERSION_APPLIED) +#error "Board specific ver_check snippet has wrongly been applied" +#endif +#elif defined(CONFIG_TEST_TYPE_VER_CHECK_SPECIFIC) +#if !defined(CONFIG_TEST_VER_CHECK_APPLIED) +#error "Base ver_check snippet has not been applied" +#endif +#if !defined(CONFIG_TEST_VER_CHECK_SPECIFIC_VERSION_APPLIED) +#error "Board specific ver_check snippet has not been applied" +#endif +#endif + ZTEST_SUITE(snippet_tests, NULL, NULL, NULL, NULL, NULL); ZTEST(snippet_tests, test_overlay_config) diff --git a/tests/cmake/snippets/testcase.yaml b/tests/cmake/snippets/testcase.yaml index 8de8be1c71ed..0cd821ab1e4b 100644 --- a/tests/cmake/snippets/testcase.yaml +++ b/tests/cmake/snippets/testcase.yaml @@ -1,12 +1,5 @@ common: tags: snippets - platform_allow: - - native_sim - - qemu_x86 - - qemu_x86_64 - - qemu_cortex_m3 - integration_platforms: - - native_sim sysbuild: false tests: @@ -14,23 +7,77 @@ tests: buildsystem.snippets.none: extra_configs: - CONFIG_TEST_TYPE_NONE=y + platform_allow: + - native_sim + - qemu_x86 + - qemu_x86_64 + - qemu_cortex_m3 + integration_platforms: + - native_sim # Test the `foo` snippet from the default application snippet root buildsystem.snippets.foo: extra_args: SNIPPET="foo" extra_configs: - CONFIG_TEST_TYPE_FOO=y + platform_allow: + - native_sim + - qemu_x86 + - qemu_x86_64 + - qemu_cortex_m3 + integration_platforms: + - native_sim # Test the `bar` snippet from an extra snippet root buildsystem.snippets.bar: extra_args: SNIPPET="bar" extra_configs: - CONFIG_TEST_TYPE_BAR=y + platform_allow: + - native_sim + - qemu_x86 + - qemu_x86_64 + - qemu_cortex_m3 + integration_platforms: + - native_sim # Test the snippet processing order (1. foo, 2. bar) buildsystem.snippets.foo_bar: extra_args: SNIPPET="foo;bar" extra_configs: - CONFIG_TEST_TYPE_FOO_BAR=y + platform_allow: + - native_sim + - qemu_x86 + - qemu_x86_64 + - qemu_cortex_m3 + integration_platforms: + - native_sim # Test the snippet processing order (1. bar, 2. foo) buildsystem.snippets.bar_foo: extra_args: SNIPPET="bar;foo" extra_configs: - CONFIG_TEST_TYPE_BAR_FOO=y + platform_allow: + - native_sim + - qemu_x86 + - qemu_x86_64 + - qemu_cortex_m3 + integration_platforms: + - native_sim + # Test the snippet board version processing + buildsystem.snippets.version_exclude: + extra_args: SNIPPET="ver_check" + extra_configs: + - CONFIG_TEST_TYPE_VER_CHECK=y + platform_allow: + - nrf9160dk@0.14.0/nrf9160 + integration_platforms: + - nrf9160dk@0.14.0/nrf9160 + build_only: true + buildsystem.snippets.version_include: + extra_args: SNIPPET="ver_check" + extra_configs: + - CONFIG_TEST_TYPE_VER_CHECK_SPECIFIC=y + platform_allow: + - nrf9160dk@0.7.0/nrf9160 + integration_platforms: + - nrf9160dk@0.7.0/nrf9160 + build_only: true From e31140859de17eb26017d36d9c3dd85a1661c13d Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Tue, 30 Dec 2025 13:46:58 +0000 Subject: [PATCH 1645/3659] doc: build: snippets: writing: Add details on board revision support Adds details of how to use the newly added board revision support in snippets Signed-off-by: Jamie McCrae --- doc/build/snippets/writing.rst | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/doc/build/snippets/writing.rst b/doc/build/snippets/writing.rst index 7f0fb4a04716..46aa9d647066 100644 --- a/doc/build/snippets/writing.rst +++ b/doc/build/snippets/writing.rst @@ -245,3 +245,27 @@ The above example uses devicetree overlay :file:`my_vendor.overlay` when building for either board ``my_vendor_board1`` or ``my_vendor_board2``. It would not use the overlay when building for either ``another_vendor_board`` or ``x_my_vendor_board``. + +Board revisions +=============== + +Specific configuration for revisions of boards is also supported which will be applied after the +common files: + +.. code-block:: yaml + + name: foo + boards: + bar: + append: + # Base file will be applied first + EXTRA_DTC_OVERLAY_FILE: first.overlay + revisions: + "0.7.0": + append: + # Will be applied on top of common board file + EXTRA_DTC_OVERLAY_FILE: extra_0_7_0.overlay + +The above example will use :file:`first.overlay` for all revisions of the ``bar`` board, and will +also include :file:`extra_0_7_0.overlay` when building for revision ``0.7.0`` of the ``bar`` +board (``bar@0.7.0``). From 239fab93bcc2a62e5757f98207cd36e4c244c3ca Mon Sep 17 00:00:00 2001 From: Mathieu Choplain Date: Fri, 28 Nov 2025 14:10:57 +0100 Subject: [PATCH 1646/3659] kconfig: treewide: use auto-generated Kconfig compatible macro variables Replace some manually-defined DT_COMPAT_<> Kconfig macro variables with their automatically generated counterparts. In most cases, this is straightforward as the manually defined macro is named identically to the one generated by the build system. Signed-off-by: Mathieu Choplain --- drivers/debug/Kconfig.nrf | 2 -- drivers/ethernet/dwc_xgmac/Kconfig | 2 -- drivers/i3c/Kconfig.nxp | 2 -- drivers/usb/uhc/Kconfig.max3421e | 2 -- modules/hal_nordic/nrfx/Kconfig | 4 ---- modules/nrf_wifi/bus/Kconfig | 7 +------ soc/nxp/common/Kconfig.flexspi_xip | 3 +-- soc/nxp/common/Kconfig.xspi_xip | 3 +-- subsys/fs/Kconfig.fatfs | 1 - subsys/fs/ext2/Kconfig | 1 - 10 files changed, 3 insertions(+), 24 deletions(-) diff --git a/drivers/debug/Kconfig.nrf b/drivers/debug/Kconfig.nrf index 266f44efc923..d04b145b4110 100644 --- a/drivers/debug/Kconfig.nrf +++ b/drivers/debug/Kconfig.nrf @@ -1,8 +1,6 @@ # Copyright (c) 2024 Nordic Semiconductor ASA # SPDX-License-Identifier: Apache-2.0 -DT_COMPAT_NORDIC_NRF_TBM := nordic,nrf-tbm - config DEBUG_NRF_ETR bool "Coresight ETR handler (with Nordic TBM)" depends on $(dt_compat_enabled,$(DT_COMPAT_NORDIC_NRF_TBM)) diff --git a/drivers/ethernet/dwc_xgmac/Kconfig b/drivers/ethernet/dwc_xgmac/Kconfig index 31d20606dc02..e4a29c327363 100644 --- a/drivers/ethernet/dwc_xgmac/Kconfig +++ b/drivers/ethernet/dwc_xgmac/Kconfig @@ -5,8 +5,6 @@ # SPDX-License-Identifier: Apache-2.0 # -DT_COMPAT_DWC_XGMAC := snps,dwcxgmac - menu "DWC XGMAC configuration" config ETH_DWC_XGMAC diff --git a/drivers/i3c/Kconfig.nxp b/drivers/i3c/Kconfig.nxp index fc66f6882832..0603ea279310 100644 --- a/drivers/i3c/Kconfig.nxp +++ b/drivers/i3c/Kconfig.nxp @@ -2,8 +2,6 @@ # # SPDX-License-Identifier: Apache-2.0 -DT_COMPAT_NXP_MCUX_I3C := nxp,mcux-i3c - module = I3C_MCUX module-str = i3c-mcux source "subsys/logging/Kconfig.template.log_config" diff --git a/drivers/usb/uhc/Kconfig.max3421e b/drivers/usb/uhc/Kconfig.max3421e index 61b461b27a6a..d879064cbf5b 100644 --- a/drivers/usb/uhc/Kconfig.max3421e +++ b/drivers/usb/uhc/Kconfig.max3421e @@ -1,8 +1,6 @@ # Copyright (c) 2022 Nordic Semiconductor ASA # SPDX-License-Identifier: Apache-2.0 -DT_COMPAT_UHC_MAX3421E := maxim,max3421e-spi - config UHC_MAX3421E bool "MAX3421E driver" default y diff --git a/modules/hal_nordic/nrfx/Kconfig b/modules/hal_nordic/nrfx/Kconfig index 50b9c4a932a6..9561e5e28d20 100644 --- a/modules/hal_nordic/nrfx/Kconfig +++ b/modules/hal_nordic/nrfx/Kconfig @@ -277,14 +277,10 @@ config NRFX_SPI2 depends on $(dt_nodelabel_exists,spi2) && SOC_SERIES_NRF52X select NRFX_SPI -DT_COMPAT_NORDIC_NRF_SPIM := nordic,nrf-spim - config NRFX_SPIM bool "SPIM driver" depends on $(dt_has_compat,$(DT_COMPAT_NORDIC_NRF_SPIM)) -DT_COMPAT_NORDIC_NRF_SPIS := nordic,nrf-spis - config NRFX_SPIS bool "SPIS driver" depends on $(dt_has_compat,$(DT_COMPAT_NORDIC_NRF_SPIS)) diff --git a/modules/nrf_wifi/bus/Kconfig b/modules/nrf_wifi/bus/Kconfig index 91b198cb3cb0..d9ef9553078c 100644 --- a/modules/nrf_wifi/bus/Kconfig +++ b/modules/nrf_wifi/bus/Kconfig @@ -4,12 +4,7 @@ # SPDX-License-Identifier: Apache-2.0 # -DT_COMPAT_NORDIC_NRF7002_QSPI := nordic,nrf7002-qspi -DT_COMPAT_NORDIC_NRF7002_SPI := nordic,nrf7002-spi -DT_COMPAT_NORDIC_NRF7001_QSPI := nordic,nrf7001-qspi -DT_COMPAT_NORDIC_NRF7001_SPI := nordic,nrf7001-spi -DT_COMPAT_NORDIC_NRF7000_QSPI := nordic,nrf7000-qspi -DT_COMPAT_NORDIC_NRF7000_SPI := nordic,nrf7000-spi +# TODO: Use DTS generated Kconfig once the board support is added DT_COMPAT_NORDIC_WIFI71 := nordic,nrf7120 menuconfig NRF70_BUSLIB diff --git a/soc/nxp/common/Kconfig.flexspi_xip b/soc/nxp/common/Kconfig.flexspi_xip index f804c563933e..ec44c6379833 100644 --- a/soc/nxp/common/Kconfig.flexspi_xip +++ b/soc/nxp/common/Kconfig.flexspi_xip @@ -2,12 +2,11 @@ # SPDX-License-Identifier: Apache-2.0 DT_CHOSEN_Z_FLASH := zephyr,flash -DT_COMPAT_FLEXSPI := nxp,imx-flexspi DT_CHOSEN_FLASH_NODE := $(dt_chosen_path,$(DT_CHOSEN_Z_FLASH)) DT_CHOSEN_FLASH_PARENT := $(dt_node_parent,$(DT_CHOSEN_FLASH_NODE)) -DT_FLASH_PARENT_IS_FLEXSPI := $(dt_node_has_compat,$(DT_CHOSEN_FLASH_PARENT),$(DT_COMPAT_FLEXSPI)) +DT_FLASH_PARENT_IS_FLEXSPI := $(dt_node_has_compat,$(DT_CHOSEN_FLASH_PARENT),$(DT_COMPAT_NXP_IMX_FLEXSPI)) DT_FLASH_HAS_SIZE_PROP := $(dt_node_has_prop,$(DT_CHOSEN_FLASH_NODE),size) config FLASH_BASE_ADDRESS diff --git a/soc/nxp/common/Kconfig.xspi_xip b/soc/nxp/common/Kconfig.xspi_xip index a2ad8724871d..2d2a73eb2b64 100644 --- a/soc/nxp/common/Kconfig.xspi_xip +++ b/soc/nxp/common/Kconfig.xspi_xip @@ -2,13 +2,12 @@ # SPDX-License-Identifier: Apache-2.0 DT_CHOSEN_Z_FLASH := zephyr,flash -DT_COMPAT_XSPI := nxp,xspi DT_CHOSEN_FLASH_NODE := $(dt_chosen_path,$(DT_CHOSEN_Z_FLASH)) DT_CHOSEN_FLASH_CTRL := $(dt_node_parent,$(DT_CHOSEN_FLASH_NODE)) DT_CHOSEN_FLASH_CTRL_PARENT := $(dt_node_parent,$(DT_CHOSEN_FLASH_CTRL)) -DT_FLASH_CTRL_PARENT_IS_XSPI := $(dt_node_has_compat,$(DT_CHOSEN_FLASH_CTRL_PARENT),$(DT_COMPAT_XSPI)) +DT_FLASH_CTRL_PARENT_IS_XSPI := $(dt_node_has_compat,$(DT_CHOSEN_FLASH_CTRL_PARENT),$(DT_COMPAT_NXP_XSPI)) DT_FLASH_CTRL_HAS_SIZE_PROP := $(dt_node_has_prop,$(DT_CHOSEN_FLASH_CTRL),size) config FLASH_BASE_ADDRESS diff --git a/subsys/fs/Kconfig.fatfs b/subsys/fs/Kconfig.fatfs index ee0ec6ab4f20..41dce9e9ec32 100644 --- a/subsys/fs/Kconfig.fatfs +++ b/subsys/fs/Kconfig.fatfs @@ -299,7 +299,6 @@ config FS_FATFS_CUSTOM_MOUNT_POINTS be used for mounting fatfs filesystems anymore. depends on FS_FATFS_CUSTOM_MOUNT_POINT_COUNT > 0 -DT_COMPAT_ZEPHYR_FSTAB_FATFS := zephyr,fstab,fatfs config FS_FATFS_FSTAB_AUTOMOUNT bool "Support for fstab auto-mounting" depends on $(dt_compat_enabled,$(DT_COMPAT_ZEPHYR_FSTAB_FATFS)) diff --git a/subsys/fs/ext2/Kconfig b/subsys/fs/ext2/Kconfig index 02c42f666f10..48f82980b9bd 100644 --- a/subsys/fs/ext2/Kconfig +++ b/subsys/fs/ext2/Kconfig @@ -53,7 +53,6 @@ config EXT2_SUPERBLOCK_ALIGNMENT this value if they require alignment. This represents the alignment of struct ext2_disk_superblock in bytes. -DT_COMPAT_ZEPHYR_FSTAB_EXT2 := zephyr,fstab,ext2 config EXT2_FSTAB_AUTOMOUNT bool "Support for fstab auto-mounting" depends on $(dt_compat_enabled,$(DT_COMPAT_ZEPHYR_FSTAB_EXT2)) From ae275eb4a13322d986d51854e1be9bf8d3dba159 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Mon, 8 Dec 2025 11:05:56 +0100 Subject: [PATCH 1647/3659] boards: nordic: nrf54h20dk: cpurad: enable lfclk The lfclk is required for bluetooth, so enable it by default for the radio core. Applications are only affected if they enable CLOCK_CONTROL, in which case either only the lfclk or all clocks are enabled, so enabling lfclk alone is the lowest common denominator. Signed-off-by: Bjarki Arge Andreasen --- boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpurad.dts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpurad.dts b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpurad.dts index 2bdf0cda9a10..cf88e536d43c 100644 --- a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpurad.dts +++ b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpurad.dts @@ -148,3 +148,7 @@ zephyr_udc0: &usbhs { &gpiote130 { owned-channels = <7>; }; + +&lfclk { + status = "okay"; +}; From a437d3057a75802f405ceb34fcd31529dfbe67f6 Mon Sep 17 00:00:00 2001 From: Hieu Nguyen Date: Thu, 11 Dec 2025 10:25:33 +0700 Subject: [PATCH 1648/3659] drivers: pwm: Initial support for RZ/A2M Add PWM driver support for Renesas RZ/A2M Signed-off-by: Hieu Nguyen Signed-off-by: Tien Nguyen --- drivers/pwm/CMakeLists.txt | 1 + drivers/pwm/Kconfig.renesas_rz | 7 + drivers/pwm/pwm_renesas_rza2m_gpt.c | 754 ++++++++++++++++++++ dts/bindings/pwm/renesas,rza2m-gpt-pwm.yaml | 17 + dts/bindings/timer/renesas,rza2m-gpt.yaml | 31 + 5 files changed, 810 insertions(+) create mode 100644 drivers/pwm/pwm_renesas_rza2m_gpt.c create mode 100644 dts/bindings/pwm/renesas,rza2m-gpt-pwm.yaml create mode 100644 dts/bindings/timer/renesas,rza2m-gpt.yaml diff --git a/drivers/pwm/CMakeLists.txt b/drivers/pwm/CMakeLists.txt index 6a9038f97e6f..859cee6780a1 100644 --- a/drivers/pwm/CMakeLists.txt +++ b/drivers/pwm/CMakeLists.txt @@ -54,6 +54,7 @@ zephyr_library_sources_ifdef(CONFIG_PWM_RCAR pwm_rcar.c) zephyr_library_sources_ifdef(CONFIG_PWM_REALTEK_RTS5912 pwm_realtek_rts5912.c) zephyr_library_sources_ifdef(CONFIG_PWM_RENESAS_RA pwm_renesas_ra.c) zephyr_library_sources_ifdef(CONFIG_PWM_RENESAS_RX_MTU pwm_renesas_rx_mtu.c) +zephyr_library_sources_ifdef(CONFIG_PWM_RENESAS_RZA2M_GPT pwm_renesas_rza2m_gpt.c) zephyr_library_sources_ifdef(CONFIG_PWM_RENESAS_RZ_GPT pwm_renesas_rz_gpt.c) zephyr_library_sources_ifdef(CONFIG_PWM_RENESAS_RZ_MTU pwm_renesas_rz_mtu.c) zephyr_library_sources_ifdef(CONFIG_PWM_RPI_PICO pwm_rpi_pico.c) diff --git a/drivers/pwm/Kconfig.renesas_rz b/drivers/pwm/Kconfig.renesas_rz index c5955f952a7d..40da6d24b50f 100644 --- a/drivers/pwm/Kconfig.renesas_rz +++ b/drivers/pwm/Kconfig.renesas_rz @@ -9,6 +9,13 @@ config PWM_RENESAS_RZ_GPT help Enable the PWM driver for the Renesas RZ General PWM Timer (GPT). +config PWM_RENESAS_RZA2M_GPT + bool "Renesas RZA2M General PWM Timer (GPT) PWM driver" + default y + depends on DT_HAS_RENESAS_RZA2M_GPT_PWM_ENABLED + help + Enable the PWM driver for the Renesas RZ/A2M General PWM Timer (GPT). + config PWM_RENESAS_RZ_MTU bool "Renesas RZ Multi-Function Timer Pulse (MTU) PWM driver" default y diff --git a/drivers/pwm/pwm_renesas_rza2m_gpt.c b/drivers/pwm/pwm_renesas_rza2m_gpt.c new file mode 100644 index 000000000000..c0349a618020 --- /dev/null +++ b/drivers/pwm/pwm_renesas_rza2m_gpt.c @@ -0,0 +1,754 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(pwm_renesas_rza2m_gpt, CONFIG_PWM_LOG_LEVEL); + +#define DT_DRV_COMPAT renesas_rza2m_gpt_pwm + +#define RZA2M_CAPTURE_BOTH_FIRST_EVENT_IS_PULSE_CAPTURE 1 +#define RZA2M_CAPTURE_BOTH_SECOND_EVENT_IS_PERIOD_CAPTURE 2 + +/* Enable action on the rising edge of GTIOCA input when GTIOCB input is 0 */ +#define RZA2M_GT_ARBL BIT(8) +/* Enable action on the rising edge of GTIOCA input when GTIOCB input is 1 */ +#define RZA2M_GT_ARBH BIT(9) +#define RZA2M_GT_AR (RZA2M_GT_ARBL | RZA2M_GT_ARBH) +/* Enable action on the falling edge of GTIOCA input when GTIOCB input is 0 */ +#define RZA2M_GT_AFBL BIT(10) +/* Enable action on the falling edge of GTIOCA input when GTIOCB input is 1 */ +#define RZA2M_GT_AFBH BIT(11) +#define RZA2M_GT_AF (RZA2M_GT_AFBL | RZA2M_GT_AFBH) +/* Enable action on the rising edge of GTIOCB input when GTIOCA input is 0 */ +#define RZA2M_GT_BRAL BIT(12) +/* Enable action on the rising edge of GTIOCB input when GTIOCA input is 1 */ +#define RZA2M_GT_BRAH BIT(13) +#define RZA2M_GT_BR (RZA2M_GT_BRAL | RZA2M_GT_BRAH) +/* Enable action on the falling edge of GTIOCB input when GTIOCA input is 0 */ +#define RZA2M_GT_BFAL BIT(14) +/* Enable action on the falling edge of GTIOCB input when GTIOCA input is 1 */ +#define RZA2M_GT_BFAH BIT(15) +#define RZA2M_GT_BF (RZA2M_GT_BFAL | RZA2M_GT_BFAH) + +#define RZA2M_GTSSR_OFFSET 0x10 /* Start Source Select Register */ +#define RZA2M_GTPSR_OFFSET 0x14 /* Stop Source Select Register */ +#define RZA2M_GTCSR_OFFSET 0x18 /* Clear Source Select Register */ + +#define RZA2M_GTICASR_OFFSET 0x24 /* Input Capture Source Select Register A */ +#define RZA2M_GTICBSR_OFFSET 0x28 /* Input Capture Source Select Register B */ + +#define RZA2M_GTCR_OFFSET 0x2c /* General PWM Timer Control Register */ +#define RZA2M_GTCR_TPCS_SHIFT 24 /* Timer Prescaler Select */ +#define RZA2M_GTCR_TPCS_MASK 0x7 +#define RZA2M_GTCR_TPCS_MAX_VAL 5U +#define RZA2M_GTCR_GET_TPCS(reg) ((reg >> RZA2M_GTCR_TPCS_SHIFT) & RZA2M_GTCR_TPCS_MASK) +#define RZA2M_GTCR_SET_TPCS(reg, tpcs) \ + ((reg & ~(RZA2M_GTCR_TPCS_MASK << RZA2M_GTCR_TPCS_SHIFT)) | \ + ((tpcs & RZA2M_GTCR_TPCS_MASK) << RZA2M_GTCR_TPCS_SHIFT)) +#define RZA2M_GTCR_MD_SHIFT 16 +#define RZA2M_GTCR_MD_MASK 0x3 +#define RZA2M_GTCR_SET_MD(reg, md) \ + ((reg & ~(RZA2M_GTCR_MD_MASK << RZA2M_GTCR_MD_SHIFT)) | \ + ((md & RZA2M_GTCR_MD_MASK) << RZA2M_GTCR_MD_SHIFT)) +#define RZA2M_GTCR_MD_PWM_SAW_WAVE 0 +#define RZA2M_GTCR_START_CNT BIT(0) + +#define RZA2M_GTUDDTYC_OFFSET 0x30 /* Count Direction and Duty Setting Register */ +#define RZA2M_GTUDDTYC_UD BIT(0) /* Count Direction Setting: counts up on GTCNT */ + +#define RZA2M_GTUDDTYC_OADTY_MASK (BIT(17) | BIT(16)) +#define RZA2M_GTUDDTYC_OADTY_0 BIT(17) +#define RZA2M_GTUDDTYC_OADTY_100 (BIT(17) | BIT(16)) + +#define RZA2M_GTUDDTYC_OBDTY_MASK (BIT(25) | BIT(24)) +#define RZA2M_GTUDDTYC_OBDTY_0 BIT(25) +#define RZA2M_GTUDDTYC_OBDTY_100 (BIT(25) | BIT(24)) + +#define RZA2M_GTIOR_OFFSET 0x34 /* I/O Control Register */ + +/* Levels of out on compare match A */ +#define RZA2M_GTIOR_GTIOA_OUT_CYC_CMP_LOW BIT(0) +#define RZA2M_GTIOR_GTIOA_OUT_CYC_CMP_HIGH BIT(1) + +/* Levels of out on end of the cycle A */ +#define RZA2M_GTIOR_GTIOA_OUT_CYC_END_LOW BIT(2) +#define RZA2M_GTIOR_GTIOA_OUT_CYC_END_HIGH BIT(3) + +/* Levels of out on compare match B */ +#define RZA2M_GTIOR_GTIOB_OUT_CYC_CMP_LOW BIT(16) +#define RZA2M_GTIOR_GTIOB_OUT_CYC_CMP_HIGH BIT(17) + +/* Levels of out on end of the cycle B */ +#define RZA2M_GTIOR_GTIOB_OUT_CYC_END_LOW BIT(18) +#define RZA2M_GTIOR_GTIOB_OUT_CYC_END_HIGH BIT(19) + +#define RZA2M_GTIOR_OAE BIT(8) /* GTIOCA Pin Output Enable */ +#define RZA2M_GTIOR_OBE BIT(24) /* GTIOCB Pin Output Enable */ + +#define RZA2M_GTINTAD_OFFSET 0x38 /* Interrupt Output Setting Register */ +#define RZA2M_GTINTAD_GTINTA BIT(0) /* GTCCRA Compare Match/InputCapture Interrupt Enable */ +#define RZA2M_GTINTAD_GTINTB BIT(1) /* GTCCRB Compare Match/InputCapture Interrupt Enable */ +#define RZA2M_GTINTAD_GTINTPR BIT(6) /* Overflow Interrupt Enable */ + +#define RZA2M_GTST_OFFSET 0x3C /* Status Register */ +#define RZA2M_GTST_TCFA BIT(0) /* Input capture/compare match of GTCCRA occurred */ +#define RZA2M_GTST_TCFB BIT(1) /* Input capture/compare match of GTCCRB occurred */ +#define RZA2M_GTST_TCFPO BIT(6) /* Overflow (crest) occurred */ + +#define RZA2M_GTBER_OFFSET 0x40 /* Buffer Enable Register */ +#define RZA2M_GTBER_CCRA_1_BUF (BIT(16)) /* Single buffer operation for GTCCRA */ +#define RZA2M_GTBER_CCRB_1_BUF (BIT(18)) /* Single buffer operation for GTCCRB */ +#define RZA2M_GTBER_PR_1_BUF (BIT(20)) /* Single buffer operation for GTPR */ + +#define RZA2M_GTBER_ADTTA_CREST (BIT(24)) +#define RZA2M_GTBER_ADTTB_CREST (BIT(28)) + +#define RZA2M_GTBER_CCRA_1_BUF_EN (RZA2M_GTBER_CCRA_1_BUF | RZA2M_GTBER_ADTTA_CREST) +#define RZA2M_GTBER_CCRB_1_BUF_EN (RZA2M_GTBER_CCRB_1_BUF | RZA2M_GTBER_ADTTB_CREST) + +/* Interrupt and A/D Converter Start Request Skipping Setting Register */ +#define RZA2M_GTITC_OFFSET 0x44 + +#define RZA2M_GTCNT_OFFSET 0x48 /* Counter */ + +#define RZA2M_GTCCRA_OFFSET 0x4C /* Compare Capture Register A */ +#define RZA2M_GTCCRB_OFFSET 0x50 /* Compare Capture Register B */ +#define RZA2M_GTCCRC_OFFSET 0x54 /* Compare Capture Register C */ +#define RZA2M_GTCCRE_OFFSET 0x58 /* Compare Capture Register E */ + +#define RZA2M_GTPR_OFFSET 0x64 /* Cycle Setting Register */ +#define RZA2M_GTPBR_OFFSET 0x68 /* Cycle Setting Buffer Register */ + +enum rza2m_gpt_event { + RZA2M_GPT_EVENT_CYCLE_END, /* Requested timer delay has expired */ + RZA2M_GPT_EVENT_CAPTURE_A, /* A capture has occurred on signal A */ + RZA2M_GPT_EVENT_CAPTURE_B, /* A capture has occurred on signal B */ +}; + +struct pwm_rza2m_config { + DEVICE_MMIO_ROM; /* Must be first */ + uint32_t channel_id; + uint32_t divider; + + const struct device *clock_dev; + clock_control_subsys_t clock_subsys; + + const struct pinctrl_dev_config *pincfg; + + uint32_t ccmpa_irq; + uint32_t ccmpb_irq; + uint32_t cycle_end_irq; +}; + +struct pwm_rza2m_gpt_capture_data { + pwm_capture_callback_handler_t callback; + void *user_data; + uint64_t period; + uint64_t pulse; + bool inverted; + uint16_t type_flag; + bool is_busy; + uint32_t overflows; + bool continuous; + uint32_t capture_both_event_count; + uint32_t capture_channel; + + uint32_t start_source; + uint32_t stop_source; + uint32_t capture_source; + uint32_t clear_source; +}; + +struct pwm_rza2m_data { + DEVICE_MMIO_RAM; /* Must be first */ + uint32_t clk_rate; +#ifdef CONFIG_PWM_CAPTURE + struct pwm_rza2m_gpt_capture_data capture; +#endif +}; + +static uint32_t renesas_rza2m_pwm_read_32(const struct device *dev, uint32_t offset) +{ + return sys_read32(DEVICE_MMIO_GET(dev) + offset); +} + +static void renesas_rza2m_pwm_write_32(const struct device *dev, uint32_t offset, uint32_t value) +{ + sys_write32(value, DEVICE_MMIO_GET(dev) + offset); +} + +static inline void rza2m_pwm_set_duty_setting(const struct device *dev, uint32_t period_cycles, + uint32_t pulse_cycles, bool is_channel_b, + bool is_inverted) +{ + uint32_t reg; + uint32_t new_reg; + uint32_t mask; + uint32_t duty_0; + uint32_t duty_100; + + reg = renesas_rza2m_pwm_read_32(dev, RZA2M_GTUDDTYC_OFFSET); + + /* Select mask and values based on channel */ + if (is_channel_b) { + mask = RZA2M_GTUDDTYC_OBDTY_MASK; + duty_0 = RZA2M_GTUDDTYC_OBDTY_0; + duty_100 = RZA2M_GTUDDTYC_OBDTY_100; + } else { + mask = RZA2M_GTUDDTYC_OADTY_MASK; + duty_0 = RZA2M_GTUDDTYC_OADTY_0; + duty_100 = RZA2M_GTUDDTYC_OADTY_100; + } + + new_reg = reg & ~mask; + + /* Set duty based on period/pulse ratio and polarity */ + if (period_cycles == pulse_cycles) { + /* 100% duty cycle */ + new_reg |= is_inverted ? duty_0 : duty_100; + } else if (pulse_cycles == 0) { + /* 0% duty cycle */ + new_reg |= is_inverted ? duty_100 : duty_0; + } else { + /* Do nothing */ + } + + if (new_reg != reg) { + renesas_rza2m_pwm_write_32(dev, RZA2M_GTUDDTYC_OFFSET, new_reg); + } +} + +#define RZA2M_CH_A_IO_FLAGS_NORMAL \ + (RZA2M_GTIOR_OAE | RZA2M_GTIOR_GTIOA_OUT_CYC_END_HIGH | RZA2M_GTIOR_GTIOA_OUT_CYC_CMP_LOW) +#define RZA2M_CH_A_IO_FLAGS_INV \ + (RZA2M_GTIOR_OAE | RZA2M_GTIOR_GTIOA_OUT_CYC_END_LOW | RZA2M_GTIOR_GTIOA_OUT_CYC_CMP_HIGH) +#define RZA2M_CH_B_IO_FLAGS_NORMAL \ + (RZA2M_GTIOR_OBE | RZA2M_GTIOR_GTIOB_OUT_CYC_END_HIGH | RZA2M_GTIOR_GTIOB_OUT_CYC_CMP_LOW) +#define RZA2M_CH_B_IO_FLAGS_INV \ + (RZA2M_GTIOR_OBE | RZA2M_GTIOR_GTIOB_OUT_CYC_END_LOW | RZA2M_GTIOR_GTIOB_OUT_CYC_CMP_HIGH) + +static void rza2m_pwm_cfg_io(const struct device *dev, bool is_channel_b, bool is_inv) +{ + uint32_t gtior; + + if (is_channel_b) { + if (is_inv) { + gtior = RZA2M_CH_B_IO_FLAGS_INV; + } else { + gtior = RZA2M_CH_B_IO_FLAGS_NORMAL; + } + } else { + if (is_inv) { + gtior = RZA2M_CH_A_IO_FLAGS_INV; + } else { + gtior = RZA2M_CH_A_IO_FLAGS_NORMAL; + } + } + renesas_rza2m_pwm_write_32(dev, RZA2M_GTIOR_OFFSET, gtior); +} + +static int pwm_rza2m_gpt_set_cycles(const struct device *dev, uint32_t channel, uint32_t period_cyc, + uint32_t pulse_cyc, pwm_flags_t flags) +{ + uint32_t reg; + bool is_channel_b; + bool is_inv; + + if (!(channel == RZ_PWM_GPT_IO_A || channel == RZ_PWM_GPT_IO_B)) { + LOG_ERR("Valid only for RZ_PWM_GPT_IO_A and RZ_PWM_GPT_IO_B pins"); + return -EINVAL; + } + + if (period_cyc == 0) { + LOG_ERR("%s: period is equal to zero", dev->name); + return -EINVAL; + } + + if (period_cyc < pulse_cyc) { + LOG_ERR("%s: period duration less than pulse duration", dev->name); + return -EINVAL; + } + + is_channel_b = (channel == RZ_PWM_GPT_IO_B); + is_inv = ((flags & PWM_POLARITY_INVERTED) == PWM_POLARITY_INVERTED); + + /* Stop counter operation */ + reg = renesas_rza2m_pwm_read_32(dev, RZA2M_GTCR_OFFSET); + renesas_rza2m_pwm_write_32(dev, RZA2M_GTCR_OFFSET, reg & ~RZA2M_GTCR_START_CNT); + + /* Counter goes up */ + reg = renesas_rza2m_pwm_read_32(dev, RZA2M_GTUDDTYC_OFFSET); + renesas_rza2m_pwm_write_32(dev, RZA2M_GTUDDTYC_OFFSET, reg | RZA2M_GTUDDTYC_UD); + + rza2m_pwm_set_duty_setting(dev, period_cyc, pulse_cyc, is_channel_b, is_inv); + + /* Timer counter starts from zero */ + renesas_rza2m_pwm_write_32(dev, RZA2M_GTCNT_OFFSET, 0); + + if (is_channel_b) { + renesas_rza2m_pwm_write_32(dev, RZA2M_GTCCRE_OFFSET, pulse_cyc); + renesas_rza2m_pwm_write_32(dev, RZA2M_GTCCRB_OFFSET, pulse_cyc); + } else { + renesas_rza2m_pwm_write_32(dev, RZA2M_GTCCRC_OFFSET, pulse_cyc); + renesas_rza2m_pwm_write_32(dev, RZA2M_GTCCRA_OFFSET, pulse_cyc); + } + + renesas_rza2m_pwm_write_32(dev, RZA2M_GTPR_OFFSET, period_cyc - 1); + renesas_rza2m_pwm_write_32(dev, RZA2M_GTPBR_OFFSET, period_cyc - 1); + + /* Enable bufferization for registers GTCCRA, GTCCRB and GTPR */ + if (is_channel_b) { + renesas_rza2m_pwm_write_32(dev, RZA2M_GTBER_OFFSET, + RZA2M_GTBER_CCRB_1_BUF_EN | RZA2M_GTBER_PR_1_BUF); + } else { + renesas_rza2m_pwm_write_32(dev, RZA2M_GTBER_OFFSET, + RZA2M_GTBER_CCRA_1_BUF_EN | RZA2M_GTBER_PR_1_BUF); + } + + rza2m_pwm_cfg_io(dev, is_channel_b, is_inv); + + /* Start counter operation */ + reg = renesas_rza2m_pwm_read_32(dev, RZA2M_GTCR_OFFSET); + renesas_rza2m_pwm_write_32(dev, RZA2M_GTCR_OFFSET, reg | RZA2M_GTCR_START_CNT); + + return 0; +}; + +static int pwm_rza2m_gpt_get_cycles_per_sec(const struct device *dev, uint32_t channel, + uint64_t *cycles) +{ + struct pwm_rza2m_data *data = dev->data; + uint32_t clk_divisor; + + /* We have the same clk_divisor for all in/out */ + clk_divisor = renesas_rza2m_pwm_read_32(dev, RZA2M_GTCR_OFFSET); + clk_divisor = RZA2M_GTCR_GET_TPCS(clk_divisor); + + if (clk_divisor > RZA2M_GTCR_TPCS_MAX_VAL) { + LOG_ERR("%s: clock clk_divisor hasn't be bigger than %u", dev->name, + RZA2M_GTCR_TPCS_MAX_VAL); + return -EINVAL; + } + + clk_divisor <<= 1; + *cycles = data->clk_rate >> clk_divisor; + + return 0; +}; + +#ifdef CONFIG_PWM_CAPTURE +static int renesas_rza2m_pwm_configure_capture_flow(struct pwm_rza2m_gpt_capture_data *capture) +{ + uint32_t rising_edge; + uint32_t falling_edge; + + /* Select channel-specific edge detection constants */ + if (capture->capture_channel == RZ_PWM_GPT_IO_B) { + rising_edge = RZA2M_GT_BR; + falling_edge = RZA2M_GT_BF; + } else { + rising_edge = RZA2M_GT_AR; + falling_edge = RZA2M_GT_AF; + } + + /* Configure start and capture sources based on type and polarity */ + capture->start_source = capture->inverted ? falling_edge : rising_edge; + + if (capture->type_flag == PWM_CAPTURE_TYPE_PERIOD) { + capture->capture_source = capture->start_source; + } else if (capture->type_flag == PWM_CAPTURE_TYPE_PULSE) { + capture->capture_source = capture->inverted ? rising_edge : falling_edge; + } else if (capture->type_flag == PWM_CAPTURE_TYPE_BOTH) { + capture->capture_source = rising_edge | falling_edge; + } else { + return -EINVAL; + } + + /* Configure continuous mode sources */ + capture->stop_source = 0; + capture->clear_source = 0; + + if (capture->continuous) { + if (capture->type_flag == PWM_CAPTURE_TYPE_BOTH) { + capture->stop_source = 0; + } else { + capture->stop_source = capture->capture_source; + } + capture->clear_source = capture->start_source; + } + + return 0; +} + +static int pwm_rza2m_gpt_configure_capture(const struct device *dev, uint32_t channel, + pwm_flags_t flags, pwm_capture_callback_handler_t cb, + void *user_data) +{ + struct pwm_rza2m_data *data = dev->data; + struct pwm_rza2m_gpt_capture_data *capture = &data->capture; + uint32_t reg; + int err; + + if (!(channel == RZ_PWM_GPT_IO_A || channel == RZ_PWM_GPT_IO_B)) { + LOG_ERR("Valid only for RZ_PWM_GPT_IO_A and RZ_PWM_GPT_IO_B pins"); + return -EINVAL; + } + + if (capture->is_busy) { + LOG_ERR("%s: capture started, pls, stop before reconfigutration", dev->name); + return -EBUSY; + } + + /* Stop counter operation */ + reg = renesas_rza2m_pwm_read_32(dev, RZA2M_GTCR_OFFSET); + renesas_rza2m_pwm_write_32(dev, RZA2M_GTCR_OFFSET, reg & ~RZA2M_GTCR_START_CNT); + + /* Counter goes up */ + reg = renesas_rza2m_pwm_read_32(dev, RZA2M_GTUDDTYC_OFFSET); + renesas_rza2m_pwm_write_32(dev, RZA2M_GTUDDTYC_OFFSET, reg | RZA2M_GTUDDTYC_UD); + + /* Set maximum number cycles to 2^32 */ + renesas_rza2m_pwm_write_32(dev, RZA2M_GTPR_OFFSET, UINT32_MAX); + + /* Disable interrupt skipping function */ + renesas_rza2m_pwm_write_32(dev, RZA2M_GTITC_OFFSET, 0); + + capture->capture_channel = channel; + capture->inverted = ((flags & PWM_POLARITY_INVERTED) == PWM_POLARITY_INVERTED); + capture->type_flag = flags & PWM_CAPTURE_TYPE_MASK; + capture->continuous = flags & PWM_CAPTURE_MODE_CONTINUOUS; + + if (capture->capture_channel == RZ_PWM_GPT_IO_B) { + renesas_rza2m_pwm_write_32(dev, RZA2M_GTBER_OFFSET, RZA2M_GTBER_CCRB_1_BUF); + } else { + renesas_rza2m_pwm_write_32(dev, RZA2M_GTBER_OFFSET, RZA2M_GTBER_CCRA_1_BUF); + } + + err = renesas_rza2m_pwm_configure_capture_flow(capture); + if (err < 0) { + return err; + } + + capture->callback = cb; + capture->user_data = user_data; + + return err; +} + +static int pwm_rza2m_gpt_enable_capture(const struct device *dev, uint32_t channel) +{ + const struct pwm_rza2m_config *config = dev->config; + struct pwm_rza2m_data *data = dev->data; + struct pwm_rza2m_gpt_capture_data *capture = &data->capture; + uint32_t intad, st, ssr; + + if (!(channel == RZ_PWM_GPT_IO_A || channel == RZ_PWM_GPT_IO_B)) { + LOG_ERR("Valid only for RZ_PWM_GPT_IO_A and RZ_PWM_GPT_IO_B pins"); + return -EINVAL; + } + + if (!capture->callback) { + LOG_ERR("PWM capture not configured"); + return -EINVAL; + } + + if (capture->is_busy) { + LOG_ERR("Capture already active on this pin"); + return -EBUSY; + } + + capture->capture_channel = channel; + capture->is_busy = true; + capture->overflows = 0; + capture->capture_both_event_count = 0; + + renesas_rza2m_pwm_write_32(dev, RZA2M_GTCNT_OFFSET, 0); + + /* Unmask IRQ on capture for INT A/B */ + intad = renesas_rza2m_pwm_read_32(dev, RZA2M_GTINTAD_OFFSET); + st = renesas_rza2m_pwm_read_32(dev, RZA2M_GTST_OFFSET); + ssr = renesas_rza2m_pwm_read_32(dev, RZA2M_GTSSR_OFFSET); + + if (capture->capture_channel == RZ_PWM_GPT_IO_B) { + renesas_rza2m_pwm_write_32(dev, RZA2M_GTCCRB_OFFSET, 0); + renesas_rza2m_pwm_write_32(dev, RZA2M_GTCCRE_OFFSET, 0); + + intad |= RZA2M_GTINTAD_GTINTB; + st &= ~RZA2M_GTST_TCFB; + ssr &= ~(RZA2M_GT_BF | RZA2M_GT_BR); + } else { + renesas_rza2m_pwm_write_32(dev, RZA2M_GTCCRA_OFFSET, 0); + renesas_rza2m_pwm_write_32(dev, RZA2M_GTCCRC_OFFSET, 0); + + intad |= RZA2M_GTINTAD_GTINTA; + st &= ~RZA2M_GTST_TCFA; + ssr &= ~(RZA2M_GT_AF | RZA2M_GT_AR); + } + + renesas_rza2m_pwm_write_32(dev, RZA2M_GTSSR_OFFSET, capture->start_source | ssr); + renesas_rza2m_pwm_write_32(dev, RZA2M_GTPSR_OFFSET, capture->stop_source); + renesas_rza2m_pwm_write_32(dev, RZA2M_GTCSR_OFFSET, capture->clear_source); + + intad |= RZA2M_GTINTAD_GTINTPR; + renesas_rza2m_pwm_write_32(dev, RZA2M_GTINTAD_OFFSET, intad); + st &= ~RZA2M_GTST_TCFPO; + renesas_rza2m_pwm_write_32(dev, RZA2M_GTST_OFFSET, st); + + if (capture->capture_channel == RZ_PWM_GPT_IO_B) { + renesas_rza2m_pwm_write_32(dev, RZA2M_GTICBSR_OFFSET, capture->capture_source); + irq_enable(config->ccmpb_irq); + } else { + renesas_rza2m_pwm_write_32(dev, RZA2M_GTICASR_OFFSET, capture->capture_source); + irq_enable(config->ccmpa_irq); + } + irq_enable(config->cycle_end_irq); + + return 0; +} + +static int pwm_rza2m_gpt_disable_capture(const struct device *dev, uint32_t channel) +{ + const struct pwm_rza2m_config *config = dev->config; + struct pwm_rza2m_data *data = dev->data; + struct pwm_rza2m_gpt_capture_data *capture = &data->capture; + uint32_t reg, st; + + if (!(channel == RZ_PWM_GPT_IO_A || channel == RZ_PWM_GPT_IO_B)) { + LOG_ERR("Valid only for RZ_PWM_GPT_IO_A and RZ_PWM_GPT_IO_B pins"); + return -EINVAL; + } + + capture->capture_channel = channel; + capture->is_busy = false; + + /* Disable auto start of cnt on input edges */ + reg = renesas_rza2m_pwm_read_32(dev, RZA2M_GTSSR_OFFSET); + if (capture->capture_channel == RZ_PWM_GPT_IO_B) { + renesas_rza2m_pwm_write_32(dev, RZA2M_GTSSR_OFFSET, + reg & ~(RZA2M_GT_BR | RZA2M_GT_BF)); + } else { + renesas_rza2m_pwm_write_32(dev, RZA2M_GTSSR_OFFSET, + reg & ~(RZA2M_GT_AR | RZA2M_GT_AF)); + } + + /* Stop counter operation */ + reg = renesas_rza2m_pwm_read_32(dev, RZA2M_GTCR_OFFSET); + renesas_rza2m_pwm_write_32(dev, RZA2M_GTCR_OFFSET, reg & ~RZA2M_GTCR_START_CNT); + + reg = renesas_rza2m_pwm_read_32(dev, RZA2M_GTINTAD_OFFSET); + st = renesas_rza2m_pwm_read_32(dev, RZA2M_GTST_OFFSET); + if (capture->capture_channel == RZ_PWM_GPT_IO_B) { + reg &= ~RZA2M_GTINTAD_GTINTB; + st &= ~RZA2M_GTST_TCFB; + } else { + reg &= ~RZA2M_GTINTAD_GTINTA; + st &= ~RZA2M_GTST_TCFA; + } + + reg &= ~RZA2M_GTINTAD_GTINTPR; + st &= ~RZA2M_GTST_TCFPO; + + renesas_rza2m_pwm_write_32(dev, RZA2M_GTINTAD_OFFSET, reg); + renesas_rza2m_pwm_write_32(dev, RZA2M_GTST_OFFSET, st); + renesas_rza2m_pwm_write_32(dev, RZA2M_GTPSR_OFFSET, 0); + + irq_disable(config->cycle_end_irq); + if (capture->capture_channel == RZ_PWM_GPT_IO_B) { + irq_disable(config->ccmpb_irq); + } else { + irq_disable(config->ccmpa_irq); + } + + return 0; +} +#endif /* CONFIG_PWM_CAPTURE */ + +static DEVICE_API(pwm, pwm_rza2m_gpt_driver_api) = { + .get_cycles_per_sec = pwm_rza2m_gpt_get_cycles_per_sec, + .set_cycles = pwm_rza2m_gpt_set_cycles, +#ifdef CONFIG_PWM_CAPTURE + .configure_capture = pwm_rza2m_gpt_configure_capture, + .enable_capture = pwm_rza2m_gpt_enable_capture, + .disable_capture = pwm_rza2m_gpt_disable_capture, +#endif /* CONFIG_PWM_CAPTURE */ +}; + +static int pwm_rza2m_gpt_init(const struct device *dev) +{ + const struct pwm_rza2m_config *config = dev->config; + struct pwm_rza2m_data *data = dev->data; + int err; + uint32_t tpcs; + uint32_t reg; + + if (!device_is_ready(config->clock_dev)) { + return -ENODEV; + } + + err = pinctrl_apply_state(config->pincfg, PINCTRL_STATE_DEFAULT); + if (err < 0) { + LOG_ERR("Failed to configure pins for PWM (%d)", err); + return err; + } + + err = clock_control_on(config->clock_dev, (clock_control_subsys_t)config->clock_subsys); + if (err < 0) { + return err; + } + + err = clock_control_get_rate(config->clock_dev, + (clock_control_subsys_t)config->clock_subsys, &data->clk_rate); + if (err < 0) { + return err; + } + + DEVICE_MMIO_MAP(dev, K_MEM_CACHE_NONE); + + /* Stop counter operation */ + reg = renesas_rza2m_pwm_read_32(dev, RZA2M_GTCR_OFFSET); + renesas_rza2m_pwm_write_32(dev, RZA2M_GTCR_OFFSET, reg & ~RZA2M_GTCR_START_CNT); + + /* Set saw-wave mode */ + reg = RZA2M_GTCR_SET_MD(reg, RZA2M_GTCR_MD_PWM_SAW_WAVE); + + /* Set divider */ + tpcs = find_lsb_set(config->divider) >> 1; + reg = RZA2M_GTCR_SET_TPCS(reg, tpcs); + renesas_rza2m_pwm_write_32(dev, RZA2M_GTCR_OFFSET, reg); + + return 0; +} + +#define RZA2M_GPT(idx) DT_INST_PARENT(idx) + +#ifdef CONFIG_PWM_CAPTURE +static void renesas_rza2m_pwm_ccmp_handler(const struct device *dev, enum rza2m_gpt_event event) +{ + struct pwm_rza2m_data *data = dev->data; + struct pwm_rza2m_gpt_capture_data *capture = &data->capture; + uint32_t reg; + uint32_t gtccr_offset; + uint64_t period_cyc; + + period_cyc = renesas_rza2m_pwm_read_32(dev, RZA2M_GTPR_OFFSET) + 1; + + if (event == RZA2M_GPT_EVENT_CAPTURE_A) { + gtccr_offset = RZA2M_GTCCRA_OFFSET; + } else { + gtccr_offset = RZA2M_GTCCRB_OFFSET; + } + + reg = renesas_rza2m_pwm_read_32(dev, gtccr_offset); + if (reg == 0) { + return; + } + + if (capture->type_flag == PWM_CAPTURE_TYPE_BOTH) { + capture->capture_both_event_count++; + if (capture->capture_both_event_count == + RZA2M_CAPTURE_BOTH_FIRST_EVENT_IS_PULSE_CAPTURE) { + capture->pulse = (capture->overflows * period_cyc) + reg; + + return; + } + if (capture->capture_both_event_count == + RZA2M_CAPTURE_BOTH_SECOND_EVENT_IS_PERIOD_CAPTURE) { + capture->capture_both_event_count = 0; + capture->period = (capture->overflows * period_cyc) + reg; + capture->callback(dev, capture->capture_channel, capture->period, + capture->pulse, 0, capture->user_data); + } + } else if (capture->type_flag == PWM_CAPTURE_TYPE_PULSE) { + capture->pulse = (capture->overflows * period_cyc) + reg; + capture->callback(dev, capture->capture_channel, 0, capture->pulse, 0, + capture->user_data); + } else { + capture->period = (capture->overflows * period_cyc) + reg; + capture->callback(dev, capture->capture_channel, capture->period, 0, 0, + capture->user_data); + } + + capture->overflows = 0; + + if (!capture->continuous) { + pwm_rza2m_gpt_disable_capture(dev, capture->capture_channel); + } +} + +static void pwm_rza2m_gpt_ccmpa_isr(const struct device *dev) +{ + renesas_rza2m_pwm_ccmp_handler(dev, RZA2M_GPT_EVENT_CAPTURE_A); +} + +static void pwm_rza2m_gpt_ccmpb_isr(const struct device *dev) +{ + renesas_rza2m_pwm_ccmp_handler(dev, RZA2M_GPT_EVENT_CAPTURE_B); +} + +static void pwm_rza2m_gpt_ovf_isr(const struct device *dev) +{ + struct pwm_rza2m_data *data = dev->data; + + data->capture.overflows++; +} + +#define GPT_GET_IRQ_FLAGS(idx, irq_name) DT_IRQ_BY_NAME(RZA2M_GPT(idx), irq_name, flags) + +#define PWM_RZA2M_IRQ_CONFIG_INIT(inst) \ + do { \ + IRQ_CONNECT(DT_IRQ_BY_NAME(RZA2M_GPT(inst), ccmpa, irq) - GIC_SPI_INT_BASE, \ + DT_IRQ_BY_NAME(RZA2M_GPT(inst), ccmpa, priority), \ + pwm_rza2m_gpt_ccmpa_isr, DEVICE_DT_INST_GET(inst), \ + GPT_GET_IRQ_FLAGS(inst, ccmpa)); \ + IRQ_CONNECT(DT_IRQ_BY_NAME(RZA2M_GPT(inst), ccmpb, irq) - GIC_SPI_INT_BASE, \ + DT_IRQ_BY_NAME(RZA2M_GPT(inst), ccmpb, priority), \ + pwm_rza2m_gpt_ccmpb_isr, DEVICE_DT_INST_GET(inst), \ + GPT_GET_IRQ_FLAGS(inst, ccmpb)); \ + IRQ_CONNECT(DT_IRQ_BY_NAME(RZA2M_GPT(inst), ovf, irq) - GIC_SPI_INT_BASE, \ + DT_IRQ_BY_NAME(RZA2M_GPT(inst), ovf, priority), pwm_rza2m_gpt_ovf_isr, \ + DEVICE_DT_INST_GET(inst), GPT_GET_IRQ_FLAGS(inst, ovf)); \ + } while (0) +#endif /* CONFIG_PWM_CAPTURE */ + +#define PWM_RZA2M_INIT(inst) \ + PINCTRL_DT_INST_DEFINE(inst); \ + uint32_t pwm_clock_subsys##inst = DT_CLOCKS_CELL(RZA2M_GPT(inst), clk_id); \ + static const struct pwm_rza2m_config pwm_rza2m_gpt_config_##inst = { \ + DEVICE_MMIO_ROM_INIT(DT_PARENT(DT_DRV_INST(inst))), \ + .channel_id = DT_PROP(RZA2M_GPT(inst), channel), \ + .divider = DT_PROP(RZA2M_GPT(inst), prescaler), \ + .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(inst), \ + .clock_dev = DEVICE_DT_GET(DT_CLOCKS_CTLR(RZA2M_GPT(inst))), \ + .clock_subsys = (clock_control_subsys_t)(&pwm_clock_subsys##inst), \ + .ccmpa_irq = DT_IRQ_BY_NAME(RZA2M_GPT(inst), ccmpa, irq) - GIC_SPI_INT_BASE, \ + .ccmpb_irq = DT_IRQ_BY_NAME(RZA2M_GPT(inst), ccmpb, irq) - GIC_SPI_INT_BASE, \ + .cycle_end_irq = DT_IRQ_BY_NAME(RZA2M_GPT(inst), ovf, irq) - GIC_SPI_INT_BASE, \ + }; \ + static struct pwm_rza2m_data pwm_rza2m_data_##inst = {}; \ + static int pwm_rza2m_gpt_init_##inst(const struct device *dev) \ + { \ + IF_ENABLED(CONFIG_PWM_CAPTURE, \ + (PWM_RZA2M_IRQ_CONFIG_INIT(inst);)) \ + int err = pwm_rza2m_gpt_init(dev); \ + if (err < 0) { \ + return err; \ + } \ + return 0; \ + } \ + DEVICE_DT_INST_DEFINE(inst, pwm_rza2m_gpt_init_##inst, NULL, &pwm_rza2m_data_##inst, \ + &pwm_rza2m_gpt_config_##inst, POST_KERNEL, CONFIG_PWM_INIT_PRIORITY, \ + &pwm_rza2m_gpt_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(PWM_RZA2M_INIT); diff --git a/dts/bindings/pwm/renesas,rza2m-gpt-pwm.yaml b/dts/bindings/pwm/renesas,rza2m-gpt-pwm.yaml new file mode 100644 index 000000000000..fada0a3004c2 --- /dev/null +++ b/dts/bindings/pwm/renesas,rza2m-gpt-pwm.yaml @@ -0,0 +1,17 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +description: Renesas RZA2M GPT PWM + +compatible: "renesas,rza2m-gpt-pwm" + +include: [pwm-controller.yaml, base.yaml, pinctrl-device.yaml] + +properties: + "#pwm-cells": + const: 3 + +pwm-cells: + - channel + - period + - flags diff --git a/dts/bindings/timer/renesas,rza2m-gpt.yaml b/dts/bindings/timer/renesas,rza2m-gpt.yaml new file mode 100644 index 000000000000..9b1912432e79 --- /dev/null +++ b/dts/bindings/timer/renesas,rza2m-gpt.yaml @@ -0,0 +1,31 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +description: Renesas RZA2M GPT + +compatible: "renesas,rza2m-gpt" + +include: [base.yaml] + +properties: + prescaler: + type: int + required: true + enum: + - 1 + - 4 + - 16 + - 64 + - 256 + - 1024 + description: Input clock prescaler. + + channel: + type: int + required: true + + interrupts: + required: true + + interrupt-names: + required: true From e58a100bbf82369f31facd4023f1dc4350e50149 Mon Sep 17 00:00:00 2001 From: Hieu Nguyen Date: Thu, 11 Dec 2025 10:27:03 +0700 Subject: [PATCH 1649/3659] dts: renesas: Add PWM support for RZ/A2M Add GPT nodes and PWM child nodes to RZ/A2M devicetree Signed-off-by: Hieu Nguyen Signed-off-by: Tien Nguyen --- dts/arm/renesas/rz/rza/r7s9210.dtsi | 224 ++++++++++++++++++++++++++++ 1 file changed, 224 insertions(+) diff --git a/dts/arm/renesas/rz/rza/r7s9210.dtsi b/dts/arm/renesas/rz/rza/r7s9210.dtsi index efa3e8f751a9..5e6f1bc9b6ae 100644 --- a/dts/arm/renesas/rz/rza/r7s9210.dtsi +++ b/dts/arm/renesas/rz/rza/r7s9210.dtsi @@ -332,6 +332,230 @@ status = "disabled"; }; + gpt32e0: gpt32e@e8043000 { + compatible = "renesas,rza2m-gpt"; + channel = <0>; + reg = <0xe8043000 0xa4>; + interrupt-parent = <&gic>; + interrupts = , + , + , + , + , + , + , + , + , + ; + interrupt-names = "ccmpa", "ccmpb", "cmpc", "cmpd", "cmpe", + "cmpf", "adtrga", "adtrgb", "ovf", "unf"; + prescaler = <1>; + clocks = <&cpg RZA2M_CLOCK(RZA2M_MODULE_GPT, RZA2M_CLK_P1C)>; + status = "disabled"; + + pwm { + compatible = "renesas,rza2m-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt32e1: gpt32e@e8043100 { + compatible = "renesas,rza2m-gpt"; + channel = <1>; + reg = <0xe8043100 0xa4>; + interrupt-parent = <&gic>; + interrupts = , + , + , + , + , + , + , + , + , + ; + interrupt-names = "ccmpa", "ccmpb", "cmpc", "cmpd", "cmpe", + "cmpf", "adtrga", "adtrgb", "ovf", "unf"; + prescaler = <1>; + clocks = <&cpg RZA2M_CLOCK(RZA2M_MODULE_GPT, RZA2M_CLK_P1C)>; + status = "disabled"; + + pwm { + compatible = "renesas,rza2m-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt32e2: gpt32e@e8043200 { + compatible = "renesas,rza2m-gpt"; + channel = <2>; + reg = <0xe8043200 0xa4>; + interrupt-parent = <&gic>; + interrupts = , + , + , + , + , + , + , + , + , + ; + interrupt-names = "ccmpa", "ccmpb", "cmpc", "cmpd", "cmpe", + "cmpf", "adtrga", "adtrgb", "ovf", "unf"; + prescaler = <1>; + clocks = <&cpg RZA2M_CLOCK(RZA2M_MODULE_GPT, RZA2M_CLK_P1C)>; + status = "disabled"; + + pwm { + compatible = "renesas,rza2m-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt32e3: gpt32e@e8043300 { + compatible = "renesas,rza2m-gpt"; + channel = <3>; + reg = <0xe8043300 0xa4>; + interrupt-parent = <&gic>; + interrupts = , + , + , + , + , + , + , + , + , + ; + interrupt-names = "ccmpa", "ccmpb", "cmpc", "cmpd", "cmpe", + "cmpf", "adtrga", "adtrgb", "ovf", "unf"; + prescaler = <1>; + clocks = <&cpg RZA2M_CLOCK(RZA2M_MODULE_GPT, RZA2M_CLK_P1C)>; + status = "disabled"; + + pwm { + compatible = "renesas,rza2m-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt32e4: gpt32e@e8043400 { + compatible = "renesas,rza2m-gpt"; + channel = <4>; + reg = <0xe8043400 0xa4>; + interrupt-parent = <&gic>; + interrupts = , + , + , + , + , + , + , + , + , + ; + interrupt-names = "ccmpa", "ccmpb", "cmpc", "cmpd", "cmpe", + "cmpf", "adtrga", "adtrgb", "ovf", "unf"; + prescaler = <1>; + clocks = <&cpg RZA2M_CLOCK(RZA2M_MODULE_GPT, RZA2M_CLK_P1C)>; + status = "disabled"; + + pwm { + compatible = "renesas,rza2m-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt32e5: gpt32e@e8043500 { + compatible = "renesas,rza2m-gpt"; + channel = <5>; + reg = <0xe8043500 0xa4>; + interrupt-parent = <&gic>; + interrupts = , + , + , + , + , + , + , + , + , + ; + interrupt-names = "ccmpa", "ccmpb", "cmpc", "cmpd", "cmpe", + "cmpf", "adtrga", "adtrgb", "ovf", "unf"; + prescaler = <1>; + clocks = <&cpg RZA2M_CLOCK(RZA2M_MODULE_GPT, RZA2M_CLK_P1C)>; + status = "disabled"; + + pwm { + compatible = "renesas,rza2m-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt32e6: gpt32e@e8043600 { + compatible = "renesas,rza2m-gpt"; + channel = <6>; + reg = <0xe8043600 0xa4>; + interrupt-parent = <&gic>; + interrupts = , + , + , + , + , + , + , + , + , + ; + interrupt-names = "ccmpa", "ccmpb", "cmpc", "cmpd", "cmpe", + "cmpf", "adtrga", "adtrgb", "ovf", "unf"; + prescaler = <1>; + clocks = <&cpg RZA2M_CLOCK(RZA2M_MODULE_GPT, RZA2M_CLK_P1C)>; + status = "disabled"; + + pwm { + compatible = "renesas,rza2m-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt32e7: gpt32e@e8043700 { + compatible = "renesas,rza2m-gpt"; + channel = <7>; + reg = <0xe8043700 0xa4>; + interrupt-parent = <&gic>; + interrupts = , + , + , + , + , + , + , + , + , + ; + interrupt-names = "ccmpa", "ccmpb", "cmpc", "cmpd", "cmpe", + "cmpf", "adtrga", "adtrgb", "ovf", "unf"; + prescaler = <1>; + clocks = <&cpg RZA2M_CLOCK(RZA2M_MODULE_GPT, RZA2M_CLK_P1C)>; + status = "disabled"; + + pwm { + compatible = "renesas,rza2m-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + scif0: serial@e8007000 { compatible = "renesas,rza2m-scif-uart"; channel = <0>; From d88dc4e751d1d55111814a2dd08700a921708202 Mon Sep 17 00:00:00 2001 From: Hieu Nguyen Date: Thu, 11 Dec 2025 10:28:47 +0700 Subject: [PATCH 1650/3659] boards: renesas: rza2m_evk: Add PWM support Add PWM support for board RZ/A2M-EVK Signed-off-by: Hieu Nguyen Signed-off-by: Tien Nguyen --- boards/renesas/rza2m_evk/rza2m_evk-pinctrl.dtsi | 14 ++++++++++++++ boards/renesas/rza2m_evk/rza2m_evk.yaml | 1 + 2 files changed, 15 insertions(+) diff --git a/boards/renesas/rza2m_evk/rza2m_evk-pinctrl.dtsi b/boards/renesas/rza2m_evk/rza2m_evk-pinctrl.dtsi index 8f8f45a4fda5..d91755e166d6 100644 --- a/boards/renesas/rza2m_evk/rza2m_evk-pinctrl.dtsi +++ b/boards/renesas/rza2m_evk/rza2m_evk-pinctrl.dtsi @@ -19,4 +19,18 @@ pinmux = ; /* AN006 */ }; }; + + /omit-if-no-ref/ gpt3_pins: gpt3 { + gpt3-pinmux { + pinmux = , /* GTIOCA */ + ; /* GTIOCB */ + }; + }; + + /omit-if-no-ref/ gpt5_pins: gpt5 { + gpt5-pinmux { + pinmux = , /* GTIOCA */ + ; /* GTIOCB */ + }; + }; }; diff --git a/boards/renesas/rza2m_evk/rza2m_evk.yaml b/boards/renesas/rza2m_evk/rza2m_evk.yaml index ef0f7e55ddb9..ebc9249bd225 100644 --- a/boards/renesas/rza2m_evk/rza2m_evk.yaml +++ b/boards/renesas/rza2m_evk/rza2m_evk.yaml @@ -9,4 +9,5 @@ supported: - adc - uart - gpio + - pwm vendor: renesas From 6b266684c5252baf0bd93e17bf830240ac49129b Mon Sep 17 00:00:00 2001 From: Hieu Nguyen Date: Thu, 11 Dec 2025 10:29:59 +0700 Subject: [PATCH 1651/3659] tests: drivers: pwm: Add support for RZ/A2M-EVK Add test support for PWM driver of RZ/A2M-EVK Signed-off-by: Hieu Nguyen Signed-off-by: Tien Nguyen --- .../pwm/pwm_api/boards/rza2m_evk.overlay | 21 +++++++++++ .../pwm/pwm_loopback/boards/rza2m_evk.overlay | 36 +++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 tests/drivers/pwm/pwm_api/boards/rza2m_evk.overlay create mode 100644 tests/drivers/pwm/pwm_loopback/boards/rza2m_evk.overlay diff --git a/tests/drivers/pwm/pwm_api/boards/rza2m_evk.overlay b/tests/drivers/pwm/pwm_api/boards/rza2m_evk.overlay new file mode 100644 index 000000000000..5d1326d089ec --- /dev/null +++ b/tests/drivers/pwm/pwm_api/boards/rza2m_evk.overlay @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + pwm-test = &pwm3; + }; +}; + +&gpt32e3 { + status = "okay"; + + pwm3: pwm { + status = "okay"; + pinctrl-0 = <&gpt3_pins>; + pinctrl-names = "default"; + }; +}; diff --git a/tests/drivers/pwm/pwm_loopback/boards/rza2m_evk.overlay b/tests/drivers/pwm/pwm_loopback/boards/rza2m_evk.overlay new file mode 100644 index 000000000000..7e284fff1ed7 --- /dev/null +++ b/tests/drivers/pwm/pwm_loopback/boards/rza2m_evk.overlay @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + pwm_loopback_0 { + compatible = "test-pwm-loopback"; + pwms = <&pwm3 RZ_PWM_GPT_IO_A 0 PWM_POLARITY_NORMAL>, + <&pwm5 RZ_PWM_GPT_IO_A 0 PWM_POLARITY_NORMAL>; + }; +}; + +&gpt32e3 { + status = "okay"; + + pwm3: pwm { + status = "okay"; + pinctrl-0 = <&gpt3_pins>; + pinctrl-names = "default"; + }; +}; + +&gpt32e5 { + status = "okay"; + + pwm5: pwm { + status = "okay"; + pinctrl-0 = <&gpt5_pins>; + pinctrl-names = "default"; + }; +}; From 419b6d665839f06571f59cd092890da3c278dd71 Mon Sep 17 00:00:00 2001 From: Farsin Nasar V A Date: Fri, 5 Dec 2025 15:00:44 +0530 Subject: [PATCH 1652/3659] dts: arm: microchip: Add HWINFO node - Added hwinfo node in the pic32cx_sg.dtsi file Signed-off-by: Farsin Nasar V A --- .../microchip/pic32c/pic32cx_sg/common/pic32cx_sg.dtsi | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/dts/arm/microchip/pic32c/pic32cx_sg/common/pic32cx_sg.dtsi b/dts/arm/microchip/pic32c/pic32cx_sg/common/pic32cx_sg.dtsi index bc7d944c59b4..6b7c83681a69 100644 --- a/dts/arm/microchip/pic32c/pic32cx_sg/common/pic32cx_sg.dtsi +++ b/dts/arm/microchip/pic32c/pic32cx_sg/common/pic32cx_sg.dtsi @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025 Microchip Technology Inc. + * Copyright (c) 2025-2026 Microchip Technology Inc. * * SPDX-License-Identifier: Apache-2.0 */ @@ -29,6 +29,14 @@ }; soc { + hwinfo: device_id@8061fc { + compatible = "microchip,hwinfo-g1"; + reg = <0x008061fc 0x4>, + <0x00806010 0x4>, + <0x00806014 0x4>, + <0x00806018 0x4>; + }; + sram0: memory@20000000 { compatible = "mmio-sram"; reg = <0x20000000 DT_SIZE_K(256)>; From 31dbbf6aad205e32e874c45bb2fc93f536a0f352 Mon Sep 17 00:00:00 2001 From: Farsin Nasar V A Date: Fri, 5 Dec 2025 15:03:45 +0530 Subject: [PATCH 1653/3659] boards: microchip: pic32cx_sg41_cult: add hwinfo to supported list - Update pic32cx_sg41_cult.yaml to reflect G1 hwinfo support on the board. Signed-off-by: Farsin Nasar V A --- .../microchip/pic32c/pic32cx_sg41_cult/pic32cx_sg41_cult.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/boards/microchip/pic32c/pic32cx_sg41_cult/pic32cx_sg41_cult.yaml b/boards/microchip/pic32c/pic32cx_sg41_cult/pic32cx_sg41_cult.yaml index fd56cabeb1e6..937aaa1b226d 100644 --- a/boards/microchip/pic32c/pic32cx_sg41_cult/pic32cx_sg41_cult.yaml +++ b/boards/microchip/pic32c/pic32cx_sg41_cult/pic32cx_sg41_cult.yaml @@ -1,4 +1,4 @@ -# Copyright (c) 2025 Microchip Technology Inc. +# Copyright (c) 2025-2026 Microchip Technology Inc. # SPDX-License-Identifier: Apache-2.0 identifier: pic32cx_sg41_cult @@ -14,6 +14,7 @@ supported: - dma - flash - gpio + - hwinfo - i2c - pinctrl - pwm From 72b2a51f3ed1758de20e82c51b5e3db127e93e26 Mon Sep 17 00:00:00 2001 From: Farsin Nasar V A Date: Fri, 5 Dec 2025 15:05:43 +0530 Subject: [PATCH 1654/3659] boards: microchip: pic32cx_sg61_cult: add hwinfo to supported list - Update pic32cx_sg61_cult.yaml to reflect G1 hwinfo support on the board. Signed-off-by: Farsin Nasar V A --- .../microchip/pic32c/pic32cx_sg61_cult/pic32cx_sg61_cult.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/boards/microchip/pic32c/pic32cx_sg61_cult/pic32cx_sg61_cult.yaml b/boards/microchip/pic32c/pic32cx_sg61_cult/pic32cx_sg61_cult.yaml index b9cd766d1e8b..6fb96788eea3 100644 --- a/boards/microchip/pic32c/pic32cx_sg61_cult/pic32cx_sg61_cult.yaml +++ b/boards/microchip/pic32c/pic32cx_sg61_cult/pic32cx_sg61_cult.yaml @@ -1,4 +1,4 @@ -# Copyright (c) 2025 Microchip Technology Inc. +# Copyright (c) 2025-2026 Microchip Technology Inc. # SPDX-License-Identifier: Apache-2.0 identifier: pic32cx_sg61_cult @@ -14,6 +14,7 @@ supported: - dma - flash - gpio + - hwinfo - i2c - pinctrl - pwm From cf318bb1f25e2781955680b822908d78a524c03a Mon Sep 17 00:00:00 2001 From: Kai Vehmanen Date: Tue, 16 Dec 2025 18:11:23 +0200 Subject: [PATCH 1655/3659] drivers: dai: fix optional use of dai_get_properties_copy() Handle the case if driver is not implementing get_properties_copy(). Document the behaviour and add a note that the method is optional and users need to be handle the case that not all drivers will have this method defined. Also add documentation on error codes. Drivers should use -ENOENT if no properties are defined for the device. This matches behaviour of dai_get_properties() returning NULL if there are no properties. Signed-off-by: Kai Vehmanen --- include/zephyr/drivers/dai.h | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/include/zephyr/drivers/dai.h b/include/zephyr/drivers/dai.h index 606a2f325668..cf37982725fa 100644 --- a/include/zephyr/drivers/dai.h +++ b/include/zephyr/drivers/dai.h @@ -463,12 +463,17 @@ static inline const struct dai_properties *dai_get_properties(const struct devic /** * @brief Fetch properties of a DAI driver * + * Optional method. + * * @param dev Pointer to the device structure for the driver instance * @param dir Stream direction: RX or TX as defined by DAI_DIR_* * @param stream_id Stream id: some drivers may have stream specific * properties, this id specifies the stream. * @param dst address where to write properties to - * @retval Zero on success + * @retval 0 if success + * @retval -EINVAL if arguments are incorrect + * @retval -ENOENT if there are no properties for the device + * @retval -ENOSYS if method not implemented by the driver */ __syscall int dai_get_properties_copy(const struct device *dev, enum dai_dir dir, @@ -482,6 +487,10 @@ static inline int z_impl_dai_get_properties_copy(const struct device *dev, { const struct dai_driver_api *api = (const struct dai_driver_api *)dev->api; + if (!api->get_properties_copy) { + return -ENOSYS; + } + return api->get_properties_copy(dev, dir, stream_id, dst); } From a64a4325e7ab1e352e54d4c90bd1446de6c047a0 Mon Sep 17 00:00:00 2001 From: Kai Vehmanen Date: Tue, 16 Dec 2025 18:16:46 +0200 Subject: [PATCH 1656/3659] drivers: dai: intel: ssp: fix indentation for dai_ssp_get_properties_copy Fix function indentation to match coding style. Signed-off-by: Kai Vehmanen --- drivers/dai/intel/ssp/ssp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/dai/intel/ssp/ssp.c b/drivers/dai/intel/ssp/ssp.c index 653f1d481687..fba24ee2cafb 100644 --- a/drivers/dai/intel/ssp/ssp.c +++ b/drivers/dai/intel/ssp/ssp.c @@ -2549,7 +2549,8 @@ static const struct dai_properties *dai_ssp_get_properties(const struct device * } static int dai_ssp_get_properties_copy(const struct device *dev, - enum dai_dir dir, int stream_id, struct dai_properties *prop) + enum dai_dir dir, int stream_id, + struct dai_properties *prop) { const struct dai_properties *kernel_prop = dai_ssp_get_properties(dev, dir, stream_id); From 8fb3da57f351682c8df7ae099feea3016c5b47f8 Mon Sep 17 00:00:00 2001 From: Kai Vehmanen Date: Tue, 16 Dec 2025 18:17:37 +0200 Subject: [PATCH 1657/3659] drivers: dai: intel: ssp: handle no properties case for properties_copy() dai_ssp_get_properties() can return NULL if there are no properties defined for the device. Handle this case correctly in ssp driver's dai_ssp_get_properties_copy() by returning -ENOENT in this case. Signed-off-by: Kai Vehmanen --- drivers/dai/intel/ssp/ssp.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/dai/intel/ssp/ssp.c b/drivers/dai/intel/ssp/ssp.c index fba24ee2cafb..a2395a611ac0 100644 --- a/drivers/dai/intel/ssp/ssp.c +++ b/drivers/dai/intel/ssp/ssp.c @@ -2558,6 +2558,10 @@ static int dai_ssp_get_properties_copy(const struct device *dev, return -EINVAL; } + if (!kernel_prop) { + return -ENOENT; + } + memcpy(prop, kernel_prop, sizeof(*kernel_prop)); return 0; From 6110b9728fbad57c8add9048f1db0d45d6c881b3 Mon Sep 17 00:00:00 2001 From: Kai Vehmanen Date: Tue, 16 Dec 2025 19:57:08 +0200 Subject: [PATCH 1658/3659] drivers: dai: fix dai_config_set() syscall validation Make a in-kernel copy of 'cfg' parameter before passing the struct to kernel z_impl_dai_config_set() implementation. This ensures user-space will not have access to the object when kernel part of the syscall is running. Also add separate handling for the case where bespoke configuration object is NULL. While no current driver works without a bespoke configuration, this is not forbidden in the API and the generic syscall handler should not assume a bespoke object is passed. Signed-off-by: Kai Vehmanen --- drivers/dai/dai_handlers.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/dai/dai_handlers.c b/drivers/dai/dai_handlers.c index 28283e25a66b..0f4388c94f57 100644 --- a/drivers/dai/dai_handlers.c +++ b/drivers/dai/dai_handlers.c @@ -36,15 +36,21 @@ static inline int z_vrfy_dai_config_set(const struct device *dev, size_t size) { uint8_t bespoke_cfg_kernel[DAI_MAX_BESPOKE_CFG_SIZE]; + struct dai_config cfg_kernel; if (size > DAI_MAX_BESPOKE_CFG_SIZE) { return -EINVAL; } K_OOPS(K_SYSCALL_DRIVER_DAI(dev, config_set)); - K_OOPS(k_usermode_from_copy(bespoke_cfg_kernel, bespoke_cfg, size)); + K_OOPS(k_usermode_from_copy(&cfg_kernel, cfg, sizeof(cfg_kernel))); - return z_impl_dai_config_set(dev, cfg, bespoke_cfg_kernel, size); + if (bespoke_cfg) { + K_OOPS(k_usermode_from_copy(bespoke_cfg_kernel, bespoke_cfg, size)); + } + + return z_impl_dai_config_set(dev, &cfg_kernel, + bespoke_cfg ? bespoke_cfg_kernel : NULL, size); } #include @@ -133,7 +139,7 @@ static inline int z_vrfy_dai_config_update(const struct device *dev, { uint8_t bespoke_cfg_kernel[DAI_MAX_BESPOKE_CFG_SIZE]; - if (size > DAI_MAX_BESPOKE_CFG_SIZE) { + if (!bespoke_cfg || size > DAI_MAX_BESPOKE_CFG_SIZE) { return -EINVAL; } From 82f28ff77457dba17ef7d715992704982eb1f162 Mon Sep 17 00:00:00 2001 From: Kai Vehmanen Date: Tue, 16 Dec 2025 20:16:17 +0200 Subject: [PATCH 1659/3659] drivers: dai: intel: alh: implement get_properties_copy Implement get_properties_copy(). This allows the driver to be used from user-space threads. Signed-off-by: Kai Vehmanen --- drivers/dai/intel/alh/alh.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/drivers/dai/intel/alh/alh.c b/drivers/dai/intel/alh/alh.c index 7d8dd0dd14c5..230da39a1ecf 100644 --- a/drivers/dai/intel/alh/alh.c +++ b/drivers/dai/intel/alh/alh.c @@ -158,6 +158,25 @@ static const struct dai_properties *dai_alh_get_properties(const struct device * return prop; } +static int dai_alh_get_properties_copy(const struct device *dev, + enum dai_dir dir, int stream_id, + struct dai_properties *prop) +{ + const struct dai_properties *kernel_prop = dai_alh_get_properties(dev, dir, stream_id); + + if (!prop) { + return -EINVAL; + } + + if (!kernel_prop) { + return -ENOENT; + } + + memcpy(prop, kernel_prop, sizeof(*kernel_prop)); + + return 0; +} + static int dai_alh_probe(const struct device *dev) { k_spinlock_key_t key; @@ -201,6 +220,7 @@ static DEVICE_API(dai, dai_intel_alh_api_funcs) = { .config_get = dai_alh_config_get, .trigger = dai_alh_trigger, .get_properties = dai_alh_get_properties, + .get_properties_copy = dai_alh_get_properties_copy, }; #define DAI_INTEL_ALH_DEVICE_INIT(n) \ From 43e45a2b502572e140051a824b9d39b99ce9d1b8 Mon Sep 17 00:00:00 2001 From: Kai Vehmanen Date: Tue, 16 Dec 2025 20:18:40 +0200 Subject: [PATCH 1660/3659] drivers: dai: intel: dmic: implement get_properties_copy Implement get_properties_copy(). This allows the driver to be used from user-space threads. Signed-off-by: Kai Vehmanen --- drivers/dai/intel/dmic/dmic.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/drivers/dai/intel/dmic/dmic.c b/drivers/dai/intel/dmic/dmic.c index a55a74728ce0..79b71e5d66f8 100644 --- a/drivers/dai/intel/dmic/dmic.c +++ b/drivers/dai/intel/dmic/dmic.c @@ -686,6 +686,25 @@ const struct dai_properties *dai_dmic_get_properties(const struct device *dev, return prop; } +static int dai_dmic_get_properties_copy(const struct device *dev, + enum dai_dir dir, int stream_id, + struct dai_properties *prop) +{ + const struct dai_properties *kernel_prop = dai_dmic_get_properties(dev, dir, stream_id); + + if (!prop) { + return -EINVAL; + } + + if (!kernel_prop) { + return -ENOENT; + } + + memcpy(prop, kernel_prop, sizeof(*kernel_prop)); + + return 0; +} + static int dai_dmic_trigger(const struct device *dev, enum dai_dir dir, enum dai_trigger_cmd cmd) { @@ -857,6 +876,7 @@ DEVICE_API(dai, dai_dmic_ops) = { .config_set = dai_dmic_set_config, .config_get = dai_dmic_get_config, .get_properties = dai_dmic_get_properties, + .get_properties_copy = dai_dmic_get_properties_copy, .trigger = dai_dmic_trigger, .ts_config = dai_dmic_timestamp_config, .ts_start = dai_timestamp_dmic_start, From 72d06609af0aaf7518ceed084635b45f7d9dce48 Mon Sep 17 00:00:00 2001 From: Kai Vehmanen Date: Tue, 16 Dec 2025 20:21:14 +0200 Subject: [PATCH 1661/3659] drivers: dai: intel: hda: implement get_properties_copy Implement get_properties_copy(). This allows the driver to be used from user-space threads. Signed-off-by: Kai Vehmanen --- drivers/dai/intel/hda/hda.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/drivers/dai/intel/hda/hda.c b/drivers/dai/intel/hda/hda.c index c901b20600b0..535fd625d970 100644 --- a/drivers/dai/intel/hda/hda.c +++ b/drivers/dai/intel/hda/hda.c @@ -92,6 +92,25 @@ static const struct dai_properties *dai_hda_get_properties(const struct device * return prop; } +static int dai_hda_get_properties_copy(const struct device *dev, + enum dai_dir dir, int stream_id, + struct dai_properties *prop) +{ + const struct dai_properties *kernel_prop = dai_hda_get_properties(dev, dir, stream_id); + + if (!prop) { + return -EINVAL; + } + + if (!kernel_prop) { + return -ENOENT; + } + + memcpy(prop, kernel_prop, sizeof(*kernel_prop)); + + return 0; +} + static int dai_hda_probe(const struct device *dev) { LOG_DBG("%s", __func__); @@ -139,6 +158,7 @@ static DEVICE_API(dai, dai_intel_hda_api_funcs) = { .config_get = dai_hda_config_get, .trigger = dai_hda_trigger, .get_properties = dai_hda_get_properties, + .get_properties_copy = dai_hda_get_properties_copy, }; #define DAI_INTEL_HDA_DEVICE_INIT(n) \ From 399a3766ee522e410d71ebd558c8b42341525ba3 Mon Sep 17 00:00:00 2001 From: Maochen Wang Date: Mon, 22 Dec 2025 12:30:49 +0800 Subject: [PATCH 1662/3659] manifest: update hal_nxp FW for RW61x/IW612/IW610/IW416 Remove unused IW612 part. update IW610 FW version to 5.p86 update RW612 FW version to 6.p50 update IW61x FW version to p27.8 update IW416 FW version to p153.8 Signed-off-by: Maochen Wang --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index fc0e681a3b30..914191df257a 100644 --- a/west.yml +++ b/west.yml @@ -210,7 +210,7 @@ manifest: groups: - hal - name: hal_nxp - revision: 1fecd5a189a8231a4ba54fad68acb75e428d1c87 + revision: 05702fcda8247876970f198669b72e3a8c99f6e5 path: modules/hal/nxp groups: - hal From 8ba115c2c5a9125c9352a4ae5a8d4ea4b0a8141c Mon Sep 17 00:00:00 2001 From: Sam Friedman Date: Fri, 2 Jan 2026 13:36:22 -0500 Subject: [PATCH 1663/3659] net: coap_client: remove unused parameter in static function 75ef6392 removed the only call to coap_client_init_request() where reconstruct==true. All remaining calls have reconstruct==false. This commit removes the parameter. Signed-off-by: Sam Friedman --- subsys/net/lib/coap/coap_client.c | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/subsys/net/lib/coap/coap_client.c b/subsys/net/lib/coap/coap_client.c index 8a5ee85416ee..9ed507e7536a 100644 --- a/subsys/net/lib/coap/coap_client.c +++ b/subsys/net/lib/coap/coap_client.c @@ -197,10 +197,8 @@ static enum coap_block_size coap_client_default_block_size(void) return COAP_BLOCK_256; } -static int coap_client_init_request(struct coap_client *client, - struct coap_client_request *req, - struct coap_client_internal_request *internal_req, - bool reconstruct) +static int coap_client_init_request(struct coap_client *client, struct coap_client_request *req, + struct coap_client_internal_request *internal_req) { int ret = 0; int i; @@ -208,13 +206,11 @@ static int coap_client_init_request(struct coap_client *client, memset(internal_req->send_buf, 0, sizeof(internal_req->send_buf)); - if (!reconstruct) { - uint8_t *token = coap_next_token(); + uint8_t *token = coap_next_token(); - internal_req->last_id = coap_next_id(); - internal_req->request_tkl = COAP_TOKEN_MAX_LEN & 0xf; - memcpy(internal_req->request_token, token, internal_req->request_tkl); - } + internal_req->last_id = coap_next_id(); + internal_req->request_tkl = COAP_TOKEN_MAX_LEN & 0xf; + memcpy(internal_req->request_token, token, internal_req->request_tkl); ret = coap_packet_init(&internal_req->request, internal_req->send_buf, MAX_COAP_MSG_LEN, 1, req->confirmable ? COAP_TYPE_CON : COAP_TYPE_NON_CON, @@ -469,7 +465,7 @@ int coap_client_req(struct coap_client *client, int sock, const struct net_socka reset_internal_request(internal_req); - ret = coap_client_init_request(client, req, internal_req, false); + ret = coap_client_init_request(client, req, internal_req); if (ret < 0) { LOG_ERR("Failed to initialize coap request"); goto release; @@ -897,7 +893,7 @@ static int handle_response(struct coap_client *client, const struct coap_packet /* Resend request with echo option */ if (response_code == COAP_RESPONSE_CODE_UNAUTHORIZED) { ret = coap_client_init_request(client, &internal_req->coap_request, - internal_req, false); + internal_req); if (ret < 0) { LOG_ERR("Error creating a CoAP request"); @@ -1052,8 +1048,7 @@ static int handle_response(struct coap_client *client, const struct coap_packet /* If this wasn't last block, send the next request */ if (blockwise_transfer && !last_block) { - ret = coap_client_init_request(client, &internal_req->coap_request, internal_req, - false); + ret = coap_client_init_request(client, &internal_req->coap_request, internal_req); if (ret < 0) { LOG_ERR("Error creating a CoAP request"); From 913fae5169425550f2364655298fceb79b320066 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Thu, 8 Jan 2026 12:54:12 +0100 Subject: [PATCH 1664/3659] net: tcp: Make sure TCP context is dereferenced only once on network down In case network interface goes down, all underlying TCP contexts are being dereferenced, however they are not released until application dereferences them as well (i.e. closed the socket). If the application does not do so however timely, and network interface goes down again, the TCP context would still be present on the active contexts list and could've been dereferenced for the second time. Fix this by checking the context state before dereferencing it on the stack behalf. Non-listening TCP context are being set to CLOSED state upon dereferencing. For the listening contexts, the TCP context has only one ref from the application side, so use the `accept_cb` pointer value as an indicator that the accept callback, indicating an error, has already been called for the context. Additionally, add a mutex lock when releasing listening context on network down even, to avoid potential races with yet unprocessed incoming packets. Signed-off-by: Robert Lubos --- subsys/net/ip/tcp.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/subsys/net/ip/tcp.c b/subsys/net/ip/tcp.c index d7ddae22828b..668181760fd3 100644 --- a/subsys/net/ip/tcp.c +++ b/subsys/net/ip/tcp.c @@ -4759,10 +4759,16 @@ static void close_tcp_conn(struct tcp *conn, void *user_data) return; } + if (conn->state == TCP_CLOSED) { + return; + } + /* net_tcp_put() will handle decrementing refcount on stack's behalf */ if (net_context_get_state(context) != NET_CONTEXT_LISTENING) { net_tcp_put(context, true); } else { + k_mutex_lock(&conn->lock, K_FOREVER); + if (context->conn_handler) { net_conn_unregister(context->conn_handler); context->conn_handler = NULL; @@ -4770,7 +4776,10 @@ static void close_tcp_conn(struct tcp *conn, void *user_data) if (conn->accept_cb != NULL) { conn->accept_cb(conn->context, NULL, 0, -ENETDOWN, context->user_data); + conn->accept_cb = NULL; } + + k_mutex_unlock(&conn->lock); } } From 1a2d9f7b8fff74729042e22fca264d8a07e0ae40 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Thu, 8 Jan 2026 13:48:49 +0100 Subject: [PATCH 1665/3659] net: sockets: Report an unrelying errors from accept() If the underlying listening TCP context reported an error, it's no longer usable, therefore accept() call for such a socket should report an error as well, otherwise it may block indefinitely. Signed-off-by: Robert Lubos --- subsys/net/lib/sockets/sockets_inet.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/subsys/net/lib/sockets/sockets_inet.c b/subsys/net/lib/sockets/sockets_inet.c index ae47f2aba8a7..7f1be17cebe1 100644 --- a/subsys/net/lib/sockets/sockets_inet.c +++ b/subsys/net/lib/sockets/sockets_inet.c @@ -491,6 +491,11 @@ int zsock_accept_ctx(struct net_context *parent, struct net_sockaddr *addr, return -1; } + if (sock_is_error(parent)) { + errno = POINTER_TO_INT(parent->user_data); + return -1; + } + if (!sock_is_nonblock(parent)) { k_timeout_t timeout = K_FOREVER; From 735f16f12feb05a33978d464d028aa7a23f49a0b Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Thu, 8 Jan 2026 15:42:01 +0100 Subject: [PATCH 1666/3659] samples: net: mdns_responder: Verify accept() result in echo server The mdns_responder sample has a simple TCP echo server running, however the accept() function errors were ignored, making the server defunct in case server socket started to report errors (for example when network went down). Update the sample to restart the echo server in case of accept() errors to make the sample more reliable. Signed-off-by: Robert Lubos --- samples/net/mdns_responder/src/service.c | 148 ++++++++++++++--------- 1 file changed, 90 insertions(+), 58 deletions(-) diff --git a/samples/net/mdns_responder/src/service.c b/samples/net/mdns_responder/src/service.c index 74e61aad950d..a6fb77212fd5 100644 --- a/samples/net/mdns_responder/src/service.c +++ b/samples/net/mdns_responder/src/service.c @@ -29,11 +29,7 @@ static int welcome(int fd) return send(fd, msg, sizeof(msg), 0); } -/* This is mainly here to bind to a port to get service advertisement - * to work.. but since we're already here we might as well do something - * useful. - */ -void service(void) +static int echo_service(const struct sockaddr *server_addr) { int r; int server_fd; @@ -41,74 +37,53 @@ void service(void) socklen_t len; void *addrp; uint16_t *portp; - struct sockaddr client_addr; + struct sockaddr_storage client_addr; char addrstr[INET6_ADDRSTRLEN]; uint8_t line[64]; - static struct sockaddr server_addr; - -#if DEFAULT_PORT == 0 - /* The advanced use case: ephemeral port */ -#if defined(CONFIG_NET_IPV6) - DNS_SD_REGISTER_SERVICE(zephyr, CONFIG_NET_HOSTNAME, - "_zephyr", "_tcp", "local", DNS_SD_EMPTY_TXT, - &((struct sockaddr_in6 *)&server_addr)->sin6_port); -#elif defined(CONFIG_NET_IPV4) - DNS_SD_REGISTER_SERVICE(zephyr, CONFIG_NET_HOSTNAME, - "_zephyr", "_tcp", "local", DNS_SD_EMPTY_TXT, - &((struct sockaddr_in *)&server_addr)->sin_port); -#endif -#else - /* The simple use case: fixed port */ - DNS_SD_REGISTER_TCP_SERVICE(zephyr, CONFIG_NET_HOSTNAME, - "_zephyr", "local", DNS_SD_EMPTY_TXT, DEFAULT_PORT); -#endif - - if (IS_ENABLED(CONFIG_NET_IPV6)) { - net_sin6(&server_addr)->sin6_family = AF_INET6; - net_sin6(&server_addr)->sin6_addr = in6addr_any; - net_sin6(&server_addr)->sin6_port = sys_cpu_to_be16(DEFAULT_PORT); - } else if (IS_ENABLED(CONFIG_NET_IPV4)) { - net_sin(&server_addr)->sin_family = AF_INET; - net_sin(&server_addr)->sin_addr.s_addr = htonl(INADDR_ANY); - net_sin(&server_addr)->sin_port = sys_cpu_to_be16(DEFAULT_PORT); - } else { - __ASSERT(false, "Neither IPv6 nor IPv4 are enabled"); - } - - r = socket(server_addr.sa_family, SOCK_STREAM, 0); + r = socket(server_addr->sa_family, SOCK_STREAM, 0); if (r == -1) { - NET_DBG("socket() failed (%d)", errno); - return; + r = -errno; + NET_DBG("socket() failed (%d)", r); + return r; } server_fd = r; NET_DBG("server_fd is %d", server_fd); - r = bind(server_fd, &server_addr, sizeof(server_addr)); + r = setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &(int){1}, sizeof(int)); if (r == -1) { - NET_DBG("bind() failed (%d)", errno); + r = -errno; + LOG_ERR("setsockopt() failed (%d)", r); close(server_fd); - return; + return r; } - if (server_addr.sa_family == AF_INET6) { - addrp = &net_sin6(&server_addr)->sin6_addr; - portp = &net_sin6(&server_addr)->sin6_port; + r = bind(server_fd, server_addr, sizeof(*server_addr)); + if (r == -1) { + r = -errno; + NET_DBG("bind() failed (%d)", r); + close(server_fd); + return r; + } + + if (server_addr->sa_family == AF_INET6) { + addrp = &net_sin6((server_addr))->sin6_addr; + portp = &net_sin6(server_addr)->sin6_port; } else { - addrp = &net_sin(&server_addr)->sin_addr; - portp = &net_sin(&server_addr)->sin_port; + addrp = &net_sin(server_addr)->sin_addr; + portp = &net_sin(server_addr)->sin_port; } - inet_ntop(server_addr.sa_family, addrp, addrstr, sizeof(addrstr)); - NET_DBG("bound to [%s]:%u", - addrstr, ntohs(*portp)); + inet_ntop(server_addr->sa_family, addrp, addrstr, sizeof(addrstr)); + NET_DBG("bound to [%s]:%u", addrstr, ntohs(*portp)); r = listen(server_fd, 1); if (r == -1) { - NET_DBG("listen() failed (%d)", errno); + r = -errno; + NET_DBG("listen() failed (%d)", r); close(server_fd); - return; + return r; } for (;;) { @@ -116,21 +91,20 @@ void service(void) r = accept(server_fd, (struct sockaddr *)&client_addr, &len); if (r == -1) { NET_DBG("accept() failed (%d)", errno); - continue; + break; } client_fd = r; - inet_ntop(server_addr.sa_family, addrp, addrstr, sizeof(addrstr)); - NET_DBG("accepted connection from [%s]:%u", - addrstr, ntohs(*portp)); + inet_ntop(server_addr->sa_family, addrp, addrstr, sizeof(addrstr)); + NET_DBG("accepted connection from [%s]:%u", addrstr, ntohs(*portp)); /* send a banner */ r = welcome(client_fd); if (r == -1) { NET_DBG("send() failed (%d)", errno); close(client_fd); - return; + continue; } for (;;) { @@ -141,6 +115,13 @@ void service(void) close(client_fd); break; } + + if (r == 0) { + NET_DBG("connection closed by peer"); + close(client_fd); + break; + } + len = r; r = send(client_fd, line, len, 0); @@ -151,4 +132,55 @@ void service(void) } } } + + close(server_fd); + + return 0; +} + +/* This is mainly here to bind to a port to get service advertisement + * to work.. but since we're already here we might as well do something + * useful. + */ +void service(void) +{ + int r = 0; + + static struct sockaddr_storage server_addr; + +#if DEFAULT_PORT == 0 + /* The advanced use case: ephemeral port */ +#if defined(CONFIG_NET_IPV6) + DNS_SD_REGISTER_SERVICE(zephyr, CONFIG_NET_HOSTNAME, + "_zephyr", "_tcp", "local", DNS_SD_EMPTY_TXT, + &((struct sockaddr_in6 *)&server_addr)->sin6_port); +#elif defined(CONFIG_NET_IPV4) + DNS_SD_REGISTER_SERVICE(zephyr, CONFIG_NET_HOSTNAME, + "_zephyr", "_tcp", "local", DNS_SD_EMPTY_TXT, + &((struct sockaddr_in *)&server_addr)->sin_port); +#endif +#else + /* The simple use case: fixed port */ + DNS_SD_REGISTER_TCP_SERVICE(zephyr, CONFIG_NET_HOSTNAME, + "_zephyr", "local", DNS_SD_EMPTY_TXT, DEFAULT_PORT); +#endif + + if (IS_ENABLED(CONFIG_NET_IPV6)) { + net_sin6(net_sad(&server_addr))->sin6_family = AF_INET6; + net_sin6(net_sad(&server_addr))->sin6_addr = in6addr_any; + net_sin6(net_sad(&server_addr))->sin6_port = sys_cpu_to_be16(DEFAULT_PORT); + } else if (IS_ENABLED(CONFIG_NET_IPV4)) { + net_sin(net_sad(&server_addr))->sin_family = AF_INET; + net_sin(net_sad(&server_addr))->sin_addr.s_addr = htonl(INADDR_ANY); + net_sin(net_sad(&server_addr))->sin_port = sys_cpu_to_be16(DEFAULT_PORT); + } else { + __ASSERT(false, "Neither IPv6 nor IPv4 are enabled"); + } + + while (r == 0) { + r = echo_service((struct sockaddr *)&server_addr); + if (r < 0) { + NET_ERR("Fatal echo server error, %d", r); + } + } } From dd0dd16a818274204b5002617929f0ea71d6eaaf Mon Sep 17 00:00:00 2001 From: Joel Key Date: Thu, 8 Jan 2026 13:23:16 -0500 Subject: [PATCH 1667/3659] MAINTAINER: Add jkey-eng as Safety Collaborator Add myself as a Safety Collaborator Signed-off-by: Joel Key --- MAINTAINERS.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index aea295559274..b1bd5d04f7af 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -4685,6 +4685,8 @@ Safety: maintainers: - tobiaskaestner - parphane + collaborators: + - jkey-eng files: - doc/safety/ labels: From ec85cddd151a43889073a6d0ca2e872c53c6efe7 Mon Sep 17 00:00:00 2001 From: Gaetan Perrot Date: Fri, 9 Jan 2026 02:23:11 +0900 Subject: [PATCH 1668/3659] samples: fs: fs_sample: fix typo in board overlay files Fix a typo in several filesystem sample board overlay files where 'parition' was used instead of 'partition'. This is a spelling-only change with no functional impact. Signed-off-by: Gaetan Perrot --- .../fs/fs_sample/boards/bl54l15_dvk_nrf54l15_cpuapp.overlay | 2 +- .../fs/fs_sample/boards/bl54l15u_dvk_nrf54l15_cpuapp.overlay | 2 +- .../fs/fs_sample/boards/nrf54l15dk_nrf54l15_cpuapp.overlay | 2 +- .../fs/fs_sample/boards/ophelia4ev_nrf54l15_cpuapp.overlay | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/samples/subsys/fs/fs_sample/boards/bl54l15_dvk_nrf54l15_cpuapp.overlay b/samples/subsys/fs/fs_sample/boards/bl54l15_dvk_nrf54l15_cpuapp.overlay index a23dec3dd55a..6aac8a3b983d 100644 --- a/samples/subsys/fs/fs_sample/boards/bl54l15_dvk_nrf54l15_cpuapp.overlay +++ b/samples/subsys/fs/fs_sample/boards/bl54l15_dvk_nrf54l15_cpuapp.overlay @@ -19,7 +19,7 @@ #address-cells = <1>; #size-cells = <1>; - slot0_partition: parition@10000 { + slot0_partition: partition@10000 { reg = <0x00010000 DT_SIZE_K(300)>; }; diff --git a/samples/subsys/fs/fs_sample/boards/bl54l15u_dvk_nrf54l15_cpuapp.overlay b/samples/subsys/fs/fs_sample/boards/bl54l15u_dvk_nrf54l15_cpuapp.overlay index a23dec3dd55a..6aac8a3b983d 100644 --- a/samples/subsys/fs/fs_sample/boards/bl54l15u_dvk_nrf54l15_cpuapp.overlay +++ b/samples/subsys/fs/fs_sample/boards/bl54l15u_dvk_nrf54l15_cpuapp.overlay @@ -19,7 +19,7 @@ #address-cells = <1>; #size-cells = <1>; - slot0_partition: parition@10000 { + slot0_partition: partition@10000 { reg = <0x00010000 DT_SIZE_K(300)>; }; diff --git a/samples/subsys/fs/fs_sample/boards/nrf54l15dk_nrf54l15_cpuapp.overlay b/samples/subsys/fs/fs_sample/boards/nrf54l15dk_nrf54l15_cpuapp.overlay index ceead62cb6f8..b44427b19b9d 100644 --- a/samples/subsys/fs/fs_sample/boards/nrf54l15dk_nrf54l15_cpuapp.overlay +++ b/samples/subsys/fs/fs_sample/boards/nrf54l15dk_nrf54l15_cpuapp.overlay @@ -18,7 +18,7 @@ #address-cells = <1>; #size-cells = <1>; - slot0_partition: parition@10000 { + slot0_partition: partition@10000 { reg = <0x00010000 DT_SIZE_K(300)>; }; diff --git a/samples/subsys/fs/fs_sample/boards/ophelia4ev_nrf54l15_cpuapp.overlay b/samples/subsys/fs/fs_sample/boards/ophelia4ev_nrf54l15_cpuapp.overlay index 339c971683a1..1afd8bf74b46 100644 --- a/samples/subsys/fs/fs_sample/boards/ophelia4ev_nrf54l15_cpuapp.overlay +++ b/samples/subsys/fs/fs_sample/boards/ophelia4ev_nrf54l15_cpuapp.overlay @@ -19,7 +19,7 @@ #address-cells = <1>; #size-cells = <1>; - slot0_partition: parition@10000 { + slot0_partition: partition@10000 { reg = <0x00010000 DT_SIZE_K(300)>; }; From ad40aa7f2bb5a5c81f3d46c3363c2eaa88586f1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrzej=20G=C5=82=C4=85bek?= Date: Fri, 9 Jan 2026 10:43:19 +0100 Subject: [PATCH 1669/3659] MAINTAINERS: remove anangl as I2S maintainer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I can no longer act as a maintainer in this area. Degrade my role to collaborator. Signed-off-by: Andrzej Głąbek --- MAINTAINERS.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index b1bd5d04f7af..4cd97634fa1c 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -1852,11 +1852,10 @@ Documentation Infrastructure: - drivers.i2c "Drivers: I2S": - status: maintained - maintainers: - - anangl + status: odd fixes collaborators: - TomasBarakNXP + - anangl files: - doc/hardware/peripherals/audio/i2s.rst - drivers/i2s/ From 427f872a561c287f300fdebbc18d4e16e8eba242 Mon Sep 17 00:00:00 2001 From: Tim Pambor Date: Fri, 9 Jan 2026 11:40:25 +0100 Subject: [PATCH 1670/3659] samples: net: sockets: http_server: fix buffer undeclared error Fix regression introduced in commit ddaeb13 which removed the 'buffer' function parameter from the dynamic endpoint callback function signature but did not update the http_server sample accordingly. Signed-off-by: Tim Pambor --- doc/connectivity/networking/api/http_server.rst | 2 +- samples/net/sockets/http_server/src/main.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/connectivity/networking/api/http_server.rst b/doc/connectivity/networking/api/http_server.rst index e7d1b4001d6b..a9d76bba89a0 100644 --- a/doc/connectivity/networking/api/http_server.rst +++ b/doc/connectivity/networking/api/http_server.rst @@ -340,7 +340,7 @@ resource handler, which echoes received data back to the client: enum http_method method = client->method; static size_t processed; - __ASSERT_NO_MSG(buffer != NULL); + __ASSERT_NO_MSG(request_ctx->data != NULL); if (status == HTTP_SERVER_TRANSACTION_ABORTED || status == HTTP_SERVER_TRANSACTION_COMPLETE) { diff --git a/samples/net/sockets/http_server/src/main.c b/samples/net/sockets/http_server/src/main.c index b0799cc0924d..efe9f8bd4fcf 100644 --- a/samples/net/sockets/http_server/src/main.c +++ b/samples/net/sockets/http_server/src/main.c @@ -90,7 +90,7 @@ static int echo_handler(struct http_client_ctx *client, enum http_transaction_st return 0; } - __ASSERT_NO_MSG(buffer != NULL); + __ASSERT_NO_MSG(request_ctx->data != NULL); processed += request_ctx->data_len; From 6fc1cd52af44719cfa03a27ad4ce0e1045bf5e4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mo=C5=84?= Date: Fri, 9 Jan 2026 11:36:52 +0100 Subject: [PATCH 1671/3659] nrf_usbd_common: use NRF_ERRATA_DYNAMIC_CHECK macros MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Upcoming MDK will make nrf52 errata check functions exist only for nRF52 and therefore the code will no longer compile for nRF5340. Replace nrf52 errata checks with new NRF_ERRATA_DYNAMIC_CHECK(). Signed-off-by: Tomasz Moń --- .../common/nrf_usbd_common/nrf_usbd_common_errata.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/usb/common/nrf_usbd_common/nrf_usbd_common_errata.h b/drivers/usb/common/nrf_usbd_common/nrf_usbd_common_errata.h index 338818d4999b..7552174daaf6 100644 --- a/drivers/usb/common/nrf_usbd_common/nrf_usbd_common_errata.h +++ b/drivers/usb/common/nrf_usbd_common/nrf_usbd_common_errata.h @@ -25,37 +25,37 @@ /* Errata: ISO double buffering not functional. **/ static inline bool nrf_usbd_common_errata_166(void) { - return NRF_USBD_COMMON_ERRATA_ENABLE && nrf52_errata_166(); + return NRF_USBD_COMMON_ERRATA_ENABLE && NRF_ERRATA_DYNAMIC_CHECK(52, 166); } /* Errata: USBD might not reach its active state. **/ static inline bool nrf_usbd_common_errata_171(void) { - return NRF_USBD_COMMON_ERRATA_ENABLE && nrf52_errata_171(); + return NRF_USBD_COMMON_ERRATA_ENABLE && NRF_ERRATA_DYNAMIC_CHECK(52, 171); } /* Errata: USB cannot be enabled. **/ static inline bool nrf_usbd_common_errata_187(void) { - return NRF_USBD_COMMON_ERRATA_ENABLE && nrf52_errata_187(); + return NRF_USBD_COMMON_ERRATA_ENABLE && NRF_ERRATA_DYNAMIC_CHECK(52, 187); } /* Errata: USBD cannot receive tasks during DMA. **/ static inline bool nrf_usbd_common_errata_199(void) { - return NRF_USBD_COMMON_ERRATA_ENABLE && nrf52_errata_199(); + return NRF_USBD_COMMON_ERRATA_ENABLE && NRF_ERRATA_DYNAMIC_CHECK(52, 199); } /* Errata: Device remains in SUSPEND too long. */ static inline bool nrf_usbd_common_errata_211(void) { - return NRF_USBD_COMMON_ERRATA_ENABLE && nrf52_errata_211(); + return NRF_USBD_COMMON_ERRATA_ENABLE && NRF_ERRATA_DYNAMIC_CHECK(52, 211); } /* Errata: Unexpected behavior after reset. **/ static inline bool nrf_usbd_common_errata_223(void) { - return NRF_USBD_COMMON_ERRATA_ENABLE && nrf52_errata_223(); + return NRF_USBD_COMMON_ERRATA_ENABLE && NRF_ERRATA_DYNAMIC_CHECK(52, 223); } #endif /* NRF_USBD_COMMON_ERRATA_H__ */ From a1ccb9647fbdf3ff8d95c8cac7bd80c83848b10a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Stasiak?= Date: Fri, 9 Jan 2026 12:52:55 +0100 Subject: [PATCH 1672/3659] drivers: nrf: use NRF_ERRATA_DYNAMIC_CHECK macros MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It is now the proper way of checking whether an anomaly workaround should be performed. Signed-off-by: Michał Stasiak --- drivers/clock_control/clock_control_nrf.c | 2 +- drivers/flash/nrf_qspi_nor.c | 6 +++--- drivers/flash/soc_flash_nrf.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/clock_control/clock_control_nrf.c b/drivers/clock_control/clock_control_nrf.c index cfdba9b00839..004643456b4d 100644 --- a/drivers/clock_control/clock_control_nrf.c +++ b/drivers/clock_control/clock_control_nrf.c @@ -252,7 +252,7 @@ static void clkstarted_handle(const struct device *dev, enum clock_control_nrf_type type) { #if CONFIG_CLOCK_CONTROL_NRF_HFINT_CALIBRATION - if (nrf54l_errata_30() && (type == CLOCK_CONTROL_NRF_TYPE_HFCLK)) { + if (NRF_ERRATA_DYNAMIC_CHECK(54L, 30) && (type == CLOCK_CONTROL_NRF_TYPE_HFCLK)) { nrf54l_errata_30_workaround(); } #endif diff --git a/drivers/flash/nrf_qspi_nor.c b/drivers/flash/nrf_qspi_nor.c index 446216dd29ff..a1ef25e23827 100644 --- a/drivers/flash/nrf_qspi_nor.c +++ b/drivers/flash/nrf_qspi_nor.c @@ -261,7 +261,7 @@ static inline void qspi_clock_div_change(const struct device *dev) #if NRF53_ERRATA_159_ENABLE_WORKAROUND struct qspi_nor_data *dev_data = dev->data; - if (nrf53_errata_159()) { + if (NRF_ERRATA_DYNAMIC_CHECK(53, 159)) { /* Save current hfclk configuration */ dev_data->prev_hclk_div = nrf_clock_hfclk_div_get(NRF_CLOCK); nrf_clock_hfclk_div_set(NRF_CLOCK, NRF_CLOCK_HFCLK_DIV_2); @@ -285,7 +285,7 @@ static inline void qspi_clock_div_restore(const struct device *dev) #if NRF53_ERRATA_159_ENABLE_WORKAROUND struct qspi_nor_data *dev_data = dev->data; - if (nrf53_errata_159()) { + if (NRF_ERRATA_DYNAMIC_CHECK(53, 159)) { /* Restore previous hfclk configuration */ nrf_clock_hfclk_div_set(NRF_CLOCK, dev_data->prev_hclk_div); } @@ -1054,7 +1054,7 @@ static int qspi_init(const struct device *dev) } #if DT_INST_NODE_HAS_PROP(0, rx_delay) - if (!nrf53_errata_121()) { + if (!NRF_ERRATA_DYNAMIC_CHECK(53, 121)) { nrf_qspi_iftiming_set(NRF_QSPI, DT_INST_PROP(0, rx_delay)); } #endif diff --git a/drivers/flash/soc_flash_nrf.c b/drivers/flash/soc_flash_nrf.c index 95e67dccfcc5..f6b8a6f5eef3 100644 --- a/drivers/flash/soc_flash_nrf.c +++ b/drivers/flash/soc_flash_nrf.c @@ -555,7 +555,7 @@ static bool pofcon_enabled; static int suspend_pofwarn(void) { - if (!nrf52_errata_242()) { + if (!NRF_ERRATA_DYNAMIC_CHECK(52, 242)) { return 0; } From 06d257d41bad68ff8761db492483e3a58321e93f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fin=20Maa=C3=9F?= Date: Fri, 9 Jan 2026 13:24:36 +0100 Subject: [PATCH 1673/3659] net: shell: follow rule 78 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Follow coding guidelines rule 78: A full expression containing an increment (++) or decrement (–) operator should have no other potential side effects other than that caused by the increment or decrement operator Signed-off-by: Fin Maaß --- subsys/net/lib/shell/tcp.c | 19 ++++++++----------- subsys/net/lib/shell/vlan.c | 20 +++++++++----------- 2 files changed, 17 insertions(+), 22 deletions(-) diff --git a/subsys/net/lib/shell/tcp.c b/subsys/net/lib/shell/tcp.c index 664684c75d9d..9129f8092f8e 100644 --- a/subsys/net/lib/shell/tcp.c +++ b/subsys/net/lib/shell/tcp.c @@ -258,8 +258,6 @@ static void tcp_recv_cb(struct net_context *context, struct net_pkt *pkt, static int cmd_net_tcp_connect(const struct shell *sh, size_t argc, char *argv[]) { #if defined(CONFIG_NET_TCP) && defined(CONFIG_NET_NATIVE_TCP) - int arg = 0; - /* tcp connect port */ char *endptr; char *ip; @@ -271,21 +269,21 @@ static int cmd_net_tcp_connect(const struct shell *sh, size_t argc, char *argv[] return -ENOEXEC; } - if (!argv[++arg]) { + if (!argv[1]) { PR_WARNING("Peer IP address missing.\n"); return -ENOEXEC; } - ip = argv[arg]; + ip = argv[1]; - if (!argv[++arg]) { + if (!argv[2]) { PR_WARNING("Peer port missing.\n"); return -ENOEXEC; } - port = strtol(argv[arg], &endptr, 10); + port = strtol(argv[2], &endptr, 10); if (*endptr != '\0') { - PR_WARNING("Invalid port %s\n", argv[arg]); + PR_WARNING("Invalid port %s\n", argv[2]); return -ENOEXEC; } @@ -301,7 +299,6 @@ static int cmd_net_tcp_connect(const struct shell *sh, size_t argc, char *argv[] static int cmd_net_tcp_send(const struct shell *sh, size_t argc, char *argv[]) { #if defined(CONFIG_NET_TCP) && defined(CONFIG_NET_NATIVE_TCP) - int arg = 0; int ret; struct net_shell_user_data user_data; @@ -311,15 +308,15 @@ static int cmd_net_tcp_send(const struct shell *sh, size_t argc, char *argv[]) return -ENOEXEC; } - if (!argv[++arg]) { + if (!argv[1]) { PR_WARNING("No data to send.\n"); return -ENOEXEC; } user_data.sh = sh; - ret = net_context_send(tcp_ctx, (uint8_t *)argv[arg], - strlen(argv[arg]), tcp_sent_cb, + ret = net_context_send(tcp_ctx, (uint8_t *)argv[1], + strlen(argv[1]), tcp_sent_cb, TCP_TIMEOUT, &user_data); if (ret < 0) { PR_WARNING("Cannot send msg (%d)\n", ret); diff --git a/subsys/net/lib/shell/vlan.c b/subsys/net/lib/shell/vlan.c index a39dc8f51d54..1bb9577731c7 100644 --- a/subsys/net/lib/shell/vlan.c +++ b/subsys/net/lib/shell/vlan.c @@ -95,7 +95,6 @@ static int cmd_net_vlan(const struct shell *sh, size_t argc, char *argv[]) static int cmd_net_vlan_add(const struct shell *sh, size_t argc, char *argv[]) { #if defined(CONFIG_NET_VLAN) - int arg = 0; int ret; uint16_t tag; struct net_if *iface; @@ -103,25 +102,25 @@ static int cmd_net_vlan_add(const struct shell *sh, size_t argc, char *argv[]) uint32_t iface_idx; /* vlan add */ - if (!argv[++arg]) { + if (!argv[1]) { PR_WARNING("VLAN tag missing.\n"); goto usage; } - tag = strtol(argv[arg], &endptr, 10); + tag = strtol(argv[1], &endptr, 10); if (*endptr != '\0') { - PR_WARNING("Invalid tag %s\n", argv[arg]); + PR_WARNING("Invalid tag %s\n", argv[1]); return -ENOEXEC; } - if (!argv[++arg]) { + if (!argv[2]) { PR_WARNING("Network interface index missing.\n"); goto usage; } - iface_idx = strtol(argv[arg], &endptr, 10); + iface_idx = strtol(argv[2], &endptr, 10); if (*endptr != '\0') { - PR_WARNING("Invalid index %s\n", argv[arg]); + PR_WARNING("Invalid index %s\n", argv[2]); goto usage; } @@ -169,20 +168,19 @@ static int cmd_net_vlan_add(const struct shell *sh, size_t argc, char *argv[]) static int cmd_net_vlan_del(const struct shell *sh, size_t argc, char *argv[]) { #if defined(CONFIG_NET_VLAN) - int arg = 0; struct net_shell_user_data user_data; char *endptr; uint16_t tag; /* vlan del */ - if (!argv[++arg]) { + if (!argv[1]) { PR_WARNING("VLAN tag missing.\n"); goto usage; } - tag = strtol(argv[arg], &endptr, 10); + tag = strtol(argv[1], &endptr, 10); if (*endptr != '\0') { - PR_WARNING("Invalid tag %s\n", argv[arg]); + PR_WARNING("Invalid tag %s\n", argv[1]); return -ENOEXEC; } From 67c6ec66b57bacccae6bd4484c7087563c26897c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fin=20Maa=C3=9F?= Date: Mon, 12 Jan 2026 18:08:59 +0100 Subject: [PATCH 1674/3659] net: shell: set constant array index directly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit set constant array index directly. Signed-off-by: Fin Maaß --- subsys/net/lib/shell/arp.c | 3 +-- subsys/net/lib/shell/gptp.c | 7 +++---- subsys/net/lib/shell/pmtu.c | 3 +-- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/subsys/net/lib/shell/arp.c b/subsys/net/lib/shell/arp.c index 58889f27d5c5..16db0418bb9e 100644 --- a/subsys/net/lib/shell/arp.c +++ b/subsys/net/lib/shell/arp.c @@ -47,13 +47,12 @@ static int cmd_net_arp(const struct shell *sh, size_t argc, char *argv[]) { #if defined(CONFIG_NET_ARP) struct net_shell_user_data user_data; - int arg = 1; #endif ARG_UNUSED(argc); #if defined(CONFIG_NET_ARP) - if (!argv[arg]) { + if (!argv[1]) { /* ARP cache content */ int count = 0; diff --git a/subsys/net/lib/shell/gptp.c b/subsys/net/lib/shell/gptp.c index 0de653e26cd1..431700a42383 100644 --- a/subsys/net/lib/shell/gptp.c +++ b/subsys/net/lib/shell/gptp.c @@ -550,23 +550,22 @@ static void gptp_print_port_info(const struct shell *sh, int port) static int cmd_net_gptp_port(const struct shell *sh, size_t argc, char *argv[]) { #if defined(CONFIG_NET_GPTP) - int arg = 1; char *endptr; int port; #endif #if defined(CONFIG_NET_GPTP) - if (!argv[arg]) { + if (!argv[1]) { PR_WARNING("Port number must be given.\n"); return -ENOEXEC; } - port = strtol(argv[arg], &endptr, 10); + port = strtol(argv[1], &endptr, 10); if (*endptr == '\0') { gptp_print_port_info(sh, port); } else { - PR_WARNING("Not a valid gPTP port number: %s\n", argv[arg]); + PR_WARNING("Not a valid gPTP port number: %s\n", argv[1]); } #else ARG_UNUSED(argc); diff --git a/subsys/net/lib/shell/pmtu.c b/subsys/net/lib/shell/pmtu.c index bf8eca403ce8..d97e98c4810a 100644 --- a/subsys/net/lib/shell/pmtu.c +++ b/subsys/net/lib/shell/pmtu.c @@ -59,13 +59,12 @@ static int cmd_net_pmtu(const struct shell *sh, size_t argc, char *argv[]) { #if defined(CONFIG_NET_PMTU) struct net_shell_user_data user_data; - int arg = 1; #endif ARG_UNUSED(argc); #if defined(CONFIG_NET_PMTU) - if (!argv[arg]) { + if (!argv[1]) { /* PMTU destination cache content */ int count = 0; From 2b6e2874c412b588a681b8eae1b8be4f545b288b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fin=20Maa=C3=9F?= Date: Mon, 12 Jan 2026 18:14:32 +0100 Subject: [PATCH 1675/3659] net: shell: explicitly check for NULL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit explicitly check for NULL Signed-off-by: Fin Maaß --- subsys/net/lib/shell/arp.c | 2 +- subsys/net/lib/shell/events.c | 2 +- subsys/net/lib/shell/gptp.c | 2 +- subsys/net/lib/shell/nbr.c | 2 +- subsys/net/lib/shell/pmtu.c | 2 +- subsys/net/lib/shell/stats.c | 2 +- subsys/net/lib/shell/tcp.c | 6 +++--- subsys/net/lib/shell/vlan.c | 6 +++--- 8 files changed, 12 insertions(+), 12 deletions(-) diff --git a/subsys/net/lib/shell/arp.c b/subsys/net/lib/shell/arp.c index 16db0418bb9e..68fd0d24757a 100644 --- a/subsys/net/lib/shell/arp.c +++ b/subsys/net/lib/shell/arp.c @@ -52,7 +52,7 @@ static int cmd_net_arp(const struct shell *sh, size_t argc, char *argv[]) ARG_UNUSED(argc); #if defined(CONFIG_NET_ARP) - if (!argv[1]) { + if (argv[1] == NULL) { /* ARP cache content */ int count = 0; diff --git a/subsys/net/lib/shell/events.c b/subsys/net/lib/shell/events.c index 53d849924846..848f574e0098 100644 --- a/subsys/net/lib/shell/events.c +++ b/subsys/net/lib/shell/events.c @@ -663,7 +663,7 @@ static int cmd_net_events(const struct shell *sh, size_t argc, char *argv[]) PR("Network event monitoring is %s.\n", net_event_monitoring ? "enabled" : "disabled"); - if (!argv[1]) { + if (argv[1] == NULL) { PR_INFO("Give 'on' to enable event monitoring and " "'off' to disable it.\n"); } diff --git a/subsys/net/lib/shell/gptp.c b/subsys/net/lib/shell/gptp.c index 431700a42383..7f1c94132b72 100644 --- a/subsys/net/lib/shell/gptp.c +++ b/subsys/net/lib/shell/gptp.c @@ -555,7 +555,7 @@ static int cmd_net_gptp_port(const struct shell *sh, size_t argc, char *argv[]) #endif #if defined(CONFIG_NET_GPTP) - if (!argv[1]) { + if (argv[1] == NULL) { PR_WARNING("Port number must be given.\n"); return -ENOEXEC; } diff --git a/subsys/net/lib/shell/nbr.c b/subsys/net/lib/shell/nbr.c index 55fc9afb8aec..a6cdaa4c0e2c 100644 --- a/subsys/net/lib/shell/nbr.c +++ b/subsys/net/lib/shell/nbr.c @@ -16,7 +16,7 @@ static int cmd_net_nbr_rm(const struct shell *sh, size_t argc, char *argv[]) struct net_in6_addr addr; int ret; - if (!argv[1]) { + if (argv[1] == NULL) { PR_WARNING("Neighbor IPv6 address missing.\n"); return -ENOEXEC; } diff --git a/subsys/net/lib/shell/pmtu.c b/subsys/net/lib/shell/pmtu.c index d97e98c4810a..55cde38a073d 100644 --- a/subsys/net/lib/shell/pmtu.c +++ b/subsys/net/lib/shell/pmtu.c @@ -64,7 +64,7 @@ static int cmd_net_pmtu(const struct shell *sh, size_t argc, char *argv[]) ARG_UNUSED(argc); #if defined(CONFIG_NET_PMTU) - if (!argv[1]) { + if (argv[1] == NULL) { /* PMTU destination cache content */ int count = 0; diff --git a/subsys/net/lib/shell/stats.c b/subsys/net/lib/shell/stats.c index 76a985f285fd..2b2712c45a5a 100644 --- a/subsys/net/lib/shell/stats.c +++ b/subsys/net/lib/shell/stats.c @@ -799,7 +799,7 @@ int cmd_net_stats_iface(const struct shell *sh, size_t argc, char *argv[]) static int cmd_net_stats(const struct shell *sh, size_t argc, char *argv[]) { #if defined(CONFIG_NET_STATISTICS) - if (!argv[1]) { + if (argv[1] == NULL) { cmd_net_stats_all(sh, argc, argv); return 0; } diff --git a/subsys/net/lib/shell/tcp.c b/subsys/net/lib/shell/tcp.c index 9129f8092f8e..097cadc27f5a 100644 --- a/subsys/net/lib/shell/tcp.c +++ b/subsys/net/lib/shell/tcp.c @@ -269,14 +269,14 @@ static int cmd_net_tcp_connect(const struct shell *sh, size_t argc, char *argv[] return -ENOEXEC; } - if (!argv[1]) { + if (argv[1] == NULL) { PR_WARNING("Peer IP address missing.\n"); return -ENOEXEC; } ip = argv[1]; - if (!argv[2]) { + if (argv[2] == NULL) { PR_WARNING("Peer port missing.\n"); return -ENOEXEC; } @@ -308,7 +308,7 @@ static int cmd_net_tcp_send(const struct shell *sh, size_t argc, char *argv[]) return -ENOEXEC; } - if (!argv[1]) { + if (argv[1] == NULL) { PR_WARNING("No data to send.\n"); return -ENOEXEC; } diff --git a/subsys/net/lib/shell/vlan.c b/subsys/net/lib/shell/vlan.c index 1bb9577731c7..97d13598f604 100644 --- a/subsys/net/lib/shell/vlan.c +++ b/subsys/net/lib/shell/vlan.c @@ -102,7 +102,7 @@ static int cmd_net_vlan_add(const struct shell *sh, size_t argc, char *argv[]) uint32_t iface_idx; /* vlan add */ - if (!argv[1]) { + if (argv[1] == NULL) { PR_WARNING("VLAN tag missing.\n"); goto usage; } @@ -113,7 +113,7 @@ static int cmd_net_vlan_add(const struct shell *sh, size_t argc, char *argv[]) return -ENOEXEC; } - if (!argv[2]) { + if (argv[2] == NULL) { PR_WARNING("Network interface index missing.\n"); goto usage; } @@ -173,7 +173,7 @@ static int cmd_net_vlan_del(const struct shell *sh, size_t argc, char *argv[]) uint16_t tag; /* vlan del */ - if (!argv[1]) { + if (argv[1] == NULL) { PR_WARNING("VLAN tag missing.\n"); goto usage; } From 9adc5bda078fb8015bfa1755d9e4073283daae51 Mon Sep 17 00:00:00 2001 From: Pieter De Gendt Date: Wed, 26 Nov 2025 17:46:17 +0100 Subject: [PATCH 1676/3659] doc: releases: migration-guide-4.4: Ethernet MAC config compatibles Replace file references with compatibles, for users to refer to the migration guide if it has any impact on out-of-tree boards. Signed-off-by: Pieter De Gendt --- doc/releases/migration-guide-4.4.rst | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/doc/releases/migration-guide-4.4.rst b/doc/releases/migration-guide-4.4.rst index aec21a8c759f..2f0353b660db 100644 --- a/doc/releases/migration-guide-4.4.rst +++ b/doc/releases/migration-guide-4.4.rst @@ -307,15 +307,14 @@ Ethernet * Driver MAC address configuration support using :c:struct:`net_eth_mac_config` has been introduced for the following drivers: - * :zephyr_file:`drivers/ethernet/eth_test.c` (:github:`96598`) + * :dtcompatible:`vnd,ethernet` (:github:`96598`) - * :zephyr_file:`drivers/ethernet/eth_sam_gmac.c` (:github:`96598`) + * :dtcompatible:`atmel,sam-gmac` and :dtcompatible:`atmel,sam0-gmac` (:github:`96598`) * Removed ``CONFIG_ETH_SAM_GMAC_MAC_I2C_EEPROM`` * Removed ``CONFIG_ETH_SAM_GMAC_MAC_I2C_INT_ADDRESS`` * Removed ``CONFIG_ETH_SAM_GMAC_MAC_I2C_INT_ADDRESS_SIZE`` - * Removed ``mac-eeprom`` property from :dtcompatible:`atmel,sam-gmac` and - :dtcompatible:`atmel,sam0-gmac` + * Removed ``mac-eeprom`` property * The ``fixed-link`` property has been removed from :dtcompatible:`ethernet-phy`. Use the new :dtcompatible:`ethernet-phy-fixed-link` compatible instead, if that functionality From 96a4d92c52dc1ffb2efe1660cd3ca2b4663e9d69 Mon Sep 17 00:00:00 2001 From: Pieter De Gendt Date: Wed, 26 Nov 2025 17:50:00 +0100 Subject: [PATCH 1677/3659] doc: releases: migration-guide-4.4: Add compatibles with MAC config support Add ethernet driver compatibles to the migration guide that have support for MAC address configuration. Signed-off-by: Pieter De Gendt --- doc/releases/migration-guide-4.4.rst | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/doc/releases/migration-guide-4.4.rst b/doc/releases/migration-guide-4.4.rst index 2f0353b660db..aaea2b3acf65 100644 --- a/doc/releases/migration-guide-4.4.rst +++ b/doc/releases/migration-guide-4.4.rst @@ -307,8 +307,6 @@ Ethernet * Driver MAC address configuration support using :c:struct:`net_eth_mac_config` has been introduced for the following drivers: - * :dtcompatible:`vnd,ethernet` (:github:`96598`) - * :dtcompatible:`atmel,sam-gmac` and :dtcompatible:`atmel,sam0-gmac` (:github:`96598`) * Removed ``CONFIG_ETH_SAM_GMAC_MAC_I2C_EEPROM`` @@ -316,6 +314,14 @@ Ethernet * Removed ``CONFIG_ETH_SAM_GMAC_MAC_I2C_INT_ADDRESS_SIZE`` * Removed ``mac-eeprom`` property + * :dtcompatible:`litex,liteeth` (:github:`100620`) + * :dtcompatible:`microchip,lan865x` (:github:`100318`) + * :dtcompatible:`microchip,lan9250` (:github:`99127`) + * :dtcompatible:`sensry,sy1xx-mac` (:github:`100619`) + * :dtcompatible:`virtio,net` (:github:`100106`) + * :dtcompatible:`vnd,ethernet` (:github:`96598`) + * :dtcompatible:`wiznet,w5500` (:github:`100919`) + * The ``fixed-link`` property has been removed from :dtcompatible:`ethernet-phy`. Use the new :dtcompatible:`ethernet-phy-fixed-link` compatible instead, if that functionality is needed. There you need to specify the fixed link parameters using the ``default-speeds`` From c2a3803b0f6ca9c327fc14eb08440398889d50e7 Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Tue, 16 Dec 2025 10:35:27 +0100 Subject: [PATCH 1678/3659] net: samples: zperf: Add configuration for T1S - nucleo_g474re This patch provides configuration to run T1S (OA_TC6) driver with zperf test program. Signed-off-by: Lukasz Majewski --- samples/net/zperf/boards/nucleo_g474re.conf | 40 +++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 samples/net/zperf/boards/nucleo_g474re.conf diff --git a/samples/net/zperf/boards/nucleo_g474re.conf b/samples/net/zperf/boards/nucleo_g474re.conf new file mode 100644 index 000000000000..88df9be0a447 --- /dev/null +++ b/samples/net/zperf/boards/nucleo_g474re.conf @@ -0,0 +1,40 @@ +# +# Copyright (c) 2026, Łukasz Majewski +# +# SPDX-License-Identifier: Apache-2.0 +# + +# Generic +CONFIG_CACHE_MANAGEMENT=n + +# Generic networking options +CONFIG_NET_CONNECTION_MANAGER=y + +# Kernel options +CONFIG_HEAP_MEM_POOL_SIZE=512 +CONFIG_ISR_STACK_SIZE=1024 +CONFIG_MAIN_STACK_SIZE=3584 + +# Network buffers +CONFIG_NET_PKT_RX_COUNT=8 +CONFIG_NET_PKT_TX_COUNT=16 +CONFIG_NET_BUF_RX_COUNT=64 +CONFIG_NET_BUF_TX_COUNT=128 +CONFIG_NET_CONTEXT_NET_PKT_POOL=y + +# Shell +CONFIG_SHELL=y +CONFIG_SHELL_ARGC_MAX=8 +CONFIG_SHELL_HISTORY_BUFFER=128 + +# LAN865x T1S driver specific +CONFIG_ETH_LAN865X=y +CONFIG_NET_BUF_DATA_SIZE=128 + +# Debugging +CONFIG_DEBUG_OPTIMIZATIONS=y +CONFIG_DEBUG_THREAD_INFO=y + +CONFIG_NET_DEBUG_NET_PKT_ALLOC=y +CONFIG_NET_BUF_POOL_USAGE=y +CONFIG_NET_ICMPV4_LOG_LEVEL_INF=y From 65e4958f1078f0dc492a71c8538883590384c245 Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Tue, 16 Dec 2025 13:06:51 +0100 Subject: [PATCH 1679/3659] net: samples: echo_server: Add configuration for T1S - nucleo_g474re This patch provides configuration to run T1S (OA_TC6) driver with echo_server test program. Signed-off-by: Lukasz Majewski --- .../echo_server/boards/nucleo_g474re.conf | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 samples/net/sockets/echo_server/boards/nucleo_g474re.conf diff --git a/samples/net/sockets/echo_server/boards/nucleo_g474re.conf b/samples/net/sockets/echo_server/boards/nucleo_g474re.conf new file mode 100644 index 000000000000..9797fd7f1bcd --- /dev/null +++ b/samples/net/sockets/echo_server/boards/nucleo_g474re.conf @@ -0,0 +1,53 @@ +# +# Copyright (c) 2026, Łukasz Majewski +# +# SPDX-License-Identifier: Apache-2.0 +# + +# Generic networking options +CONFIG_NET_TCP=n +CONFIG_POSIX_SYSCONF_IMPL_MACRO=y + +# Kernel options - adjustments +CONFIG_HEAP_MEM_POOL_SIZE=2048 +CONFIG_ISR_STACK_SIZE=1024 +CONFIG_MAIN_STACK_SIZE=3584 + +# Network buffers +CONFIG_NET_PKT_RX_COUNT=6 +CONFIG_NET_PKT_TX_COUNT=20 +CONFIG_NET_BUF_RX_COUNT=64 +CONFIG_NET_BUF_TX_COUNT=64 + +# Shell +CONFIG_SHELL_ARGC_MAX=5 +CONFIG_SHELL_HISTORY_BUFFER=128 + +# IP address options +CONFIG_NET_IF_UNICAST_IPV6_ADDR_COUNT=3 +CONFIG_NET_IF_MCAST_IPV6_ADDR_COUNT=4 +# For bigger networks aka stacked version (default is 8) +CONFIG_NET_IPV6_MAX_NEIGHBORS=16 + +# LAN865x T1S driver specific +CONFIG_NET_L2_ETHERNET=y +CONFIG_ETH_LAN865X=y +CONFIG_NET_BUF_DATA_SIZE=128 + +# Log +CONFIG_LOG_BUFFER_SIZE=4096 + +# Debugging +CONFIG_DEBUG_OPTIMIZATIONS=y +CONFIG_DEBUG_THREAD_INFO=y + +CONFIG_NET_DEBUG_NET_PKT_ALLOC=y +CONFIG_NET_BUF_POOL_USAGE=y +CONFIG_NET_ICMPV4_LOG_LEVEL_INF=y +CONFIG_NET_ICMPV6_LOG_LEVEL_INF=y + +# Use UDPPERF stress test program +# As it is an external Zephyr 'module' +CONFIG_CPP=y +CONFIG_STD_CPP17=y +CONFIG_REQUIRES_FULL_LIBCPP=y From b86999a7b01980eb1b1f14375385e8710d6aa904 Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Tue, 16 Dec 2025 12:56:53 +0100 Subject: [PATCH 1680/3659] net: samples: dts: spi: Enable LAN8651 (SPI) for T1S (zperf) This commit provides device tree description of the LAN8651 T1S device to work with zperf performance test program. Signed-off-by: Lukasz Majewski --- .../net/zperf/boards/nucleo_g474re.overlay | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 samples/net/zperf/boards/nucleo_g474re.overlay diff --git a/samples/net/zperf/boards/nucleo_g474re.overlay b/samples/net/zperf/boards/nucleo_g474re.overlay new file mode 100644 index 000000000000..428bc272126f --- /dev/null +++ b/samples/net/zperf/boards/nucleo_g474re.overlay @@ -0,0 +1,47 @@ +/* + * Copyright 2025 Łukasz Majewski + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&spi1 { + status = "okay"; + pinctrl-0 = <&spi1_sck_pa5 &spi1_miso_pa6 &spi1_mosi_pa7>; + pinctrl-names = "default"; + cs-gpios = <&gpiob 6 GPIO_ACTIVE_LOW>; + + spe: lan865x@0 { + compatible = "microchip,lan865x"; + reg = <0>; + + /* pa9 -> D8 label on nucleo */ + rst-gpios = <&gpioa 9 GPIO_ACTIVE_LOW>; + /* pa8 -> D7 label on nucleo */ + int-gpios = <&gpioa 8 GPIO_ACTIVE_LOW>; + + local-mac-address = [00 19 05 00 00 01]; + + spi-max-frequency = <25000000>; + + lan865x_mdio: lan865x_mdio { + compatible = "microchip,lan865x-mdio"; + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + + ethernet-phy@0 { + compatible = "microchip,t1s-phy"; + reg = <0x0>; + plca-enable; + plca-node-id = <1>; + plca-node-count = <8>; + plca-burst-count = <0>; + plca-burst-timer = <0x80>; + plca-to-timer = <0x20>; + status = "okay"; + }; + }; + + status = "okay"; + }; +}; From fbeb78fe6b52a2709e251ca8c76a84b180e844ff Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Tue, 16 Dec 2025 12:56:59 +0100 Subject: [PATCH 1681/3659] net: samples: dts: spi: Enable LAN8651 (SPI) for T1S (echo_server) This commit provides device tree description of the LAN8651 T1S device to work with echo_server sample program. Signed-off-by: Lukasz Majewski --- .../echo_server/boards/nucleo_g474re.overlay | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 samples/net/sockets/echo_server/boards/nucleo_g474re.overlay diff --git a/samples/net/sockets/echo_server/boards/nucleo_g474re.overlay b/samples/net/sockets/echo_server/boards/nucleo_g474re.overlay new file mode 100644 index 000000000000..428bc272126f --- /dev/null +++ b/samples/net/sockets/echo_server/boards/nucleo_g474re.overlay @@ -0,0 +1,47 @@ +/* + * Copyright 2025 Łukasz Majewski + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&spi1 { + status = "okay"; + pinctrl-0 = <&spi1_sck_pa5 &spi1_miso_pa6 &spi1_mosi_pa7>; + pinctrl-names = "default"; + cs-gpios = <&gpiob 6 GPIO_ACTIVE_LOW>; + + spe: lan865x@0 { + compatible = "microchip,lan865x"; + reg = <0>; + + /* pa9 -> D8 label on nucleo */ + rst-gpios = <&gpioa 9 GPIO_ACTIVE_LOW>; + /* pa8 -> D7 label on nucleo */ + int-gpios = <&gpioa 8 GPIO_ACTIVE_LOW>; + + local-mac-address = [00 19 05 00 00 01]; + + spi-max-frequency = <25000000>; + + lan865x_mdio: lan865x_mdio { + compatible = "microchip,lan865x-mdio"; + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + + ethernet-phy@0 { + compatible = "microchip,t1s-phy"; + reg = <0x0>; + plca-enable; + plca-node-id = <1>; + plca-node-count = <8>; + plca-burst-count = <0>; + plca-burst-timer = <0x80>; + plca-to-timer = <0x20>; + status = "okay"; + }; + }; + + status = "okay"; + }; +}; From 6628f16231bb826887e56b6ad07e1bbc733fa473 Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Fri, 27 Oct 2023 16:08:20 +0200 Subject: [PATCH 1682/3659] samples: net: doc: Add information to build and test the T1S driver This commit provides information regarding building and executing stress tests for LAN8651 based 10BASE T1S ethernet connection. The LAN8651 is connected to nucleo_g474re board. Signed-off-by: Lukasz Majewski --- samples/net/ethernet/t1s/README.rst | 177 ++++++++++++++++++++++++++++ 1 file changed, 177 insertions(+) create mode 100644 samples/net/ethernet/t1s/README.rst diff --git a/samples/net/ethernet/t1s/README.rst b/samples/net/ethernet/t1s/README.rst new file mode 100644 index 000000000000..0742e8f0f1ee --- /dev/null +++ b/samples/net/ethernet/t1s/README.rst @@ -0,0 +1,177 @@ +.. zephyr:code-sample:: t1s + :name: 10BASE-T1S tests (OA_TC6) + + Setup tests to examine long term stability of 10BASE-T1S communication + + +10BASE-T1S Network (OA_TC6) Tests +################################# + +Overview +******** + +This test setup checks if long term stability and operation of the +T1S communication is preserved. + +Prerequisites +************* + +HW prerequisites: +================= + +* `Raspberry PI4 `_ with Debian 11.9 (v.6.1 kernel) and + `LAN8670-USB dongle `_ setup as 10 BASE T1S master (HOST) +* Nucleo (:zephyr:board:`nucleo_g474re`) connected to `LAN8651 "micro BUS" module from + microe.com `_ (one or more) (DUTs) + +.. note:: + + The lan867x-linux-driver-2v2/linux-v6.1.21-support IPv6 is not working on + PC's Debian 12. Hence, the move to RPI4 is recommended. + +Connections and IOs +=================== + ++-------------------------------------------------------+ +| :zephyr:board:`nucleo_g474re` | `microe-lan8651`_ | ++================================+======================+ +| 3V3 (CN 6) | 3V3 | ++--------------------------------+----------------------+ +| GND (CN 6) | GND | ++--------------------------------+----------------------+ +| SCK/D13 (CN 5) | SCK | ++--------------------------------+----------------------+ +| MISO/D12 (CN 5) | SDO | ++--------------------------------+----------------------+ +| PWM/MOSI/D11 (CN 5) | SDI | ++--------------------------------+----------------------+ +| PWM/CS/D10 (CN 5) | CS | ++--------------------------------+----------------------+ +| D8 (CN 5) | RST | ++--------------------------------+----------------------+ +| D7 (CN 9) | IRQ | ++--------------------------------+----------------------+ + + +Software prerequisites: +======================= + +* Compile `udp-perf`_ program (both for HOST and DUTs) + +* `The udp-perf Zephyr sources `_ should be cloned to: + ``modules/udp-perf/zephyr`` + +* Extend ``west.yml``: + +.. code-block:: shell + + - name: udp-perf + path: modules/udp-perf + +* Enable config :code:`UDPPERF` in the config file for :code:`echo_server` + or :code:`zperf` + +* Extend ``boards/nucleo_g474re.conf`` for per setup IP configuration: + +.. code-block:: shell + + CONFIG_NET_CONFIG_MY_IPV4_ADDR="192.0.2.1" + CONFIG_NET_CONFIG_PEER_IPV4_ADDR="192.0.2.3" + CONFIG_NET_CONFIG_MY_IPV6_ADDR="2001:db8::1" + CONFIG_NET_CONFIG_PEER_IPV6_ADDR="2001:db8::3" + + +Testing and validation: +*********************** + +:zephyr:code-sample:`sockets-echo-server` with `udp-perf`_: +=========================================================== + +* Build for the :zephyr:board:`nucleo_g474re` board + +.. code-block:: shell + + west build -p always -b nucleo_g474re samples/net/sockets/echo_server/ + +Default configuration: + +.. code-block:: console + + Nucleo ip: 192.0.2.1 RPI4: 192.0.2.3 + Nucleo ipv6 2001:db8::1 RPI4: 2001:db8::3 + + +* Use RPI4 to connect the USB <-> T1S dongle (connect to USB 2.0): + +.. code-block:: shell + + uname -a # Linux raspberrypi 6.1.21 + cd ~/work/Zephyr/lan867x-linux-driver-2v2/linux-v6.1.21-support + ./load.sh + +Add default route to Nucleo (on RPI4): + +.. code-block:: shell + + ip -6 route add 2001:db8::1 dev eth0 + +* Run test programs (on RPI4) - log via SSH to have separate consoles for each ``while``: + +.. code-block:: shell + + cd ~/work/Zephyr/net-tools $ + while :; do ./echo-client -r -i eth1 192.0.2.1; sleep 1; ping -c 3 192.0.2.1; done + while :; do ./echo-client -r -i eth1 2001:db8::1; sleep 1; ping -6 -c 3 2001:db8::1; done + cd ~/work/Zephyr/udp-perf $ + while :; do ./target/armv7-unknown-linux-gnueabihf/release/udp-perf client --ip 192.0.2.1 --packets 100 --mode reduced --runs 5; [ $? -ne 0 ] && echo "Error!"; done + + +:zephyr:code-sample:`zperf`: +============================ + +* Build for the :zephyr:board:`nucleo_g474re` board + +.. code-block:: shell + + west build -p always -b nucleo_g474re samples/net/zperf/ + +* Zephyr module (nucleo board) as CLIENT + +.. code-block:: shell + + zperf udp upload 192.0.2.3 5001 10 1460 10M # -> nucleo shell + iperf -s -l 1460 -u -B 192.0.2.3 -i 1 # -> RPI4 + +* Zephyr module (nucleo board) as SERVER + +.. code-block:: shell + + zperf udp download 5001 # -> nucleo shell + iperf -l 1460 -u -c 192.0.2.1 -i 1 -b 10M -p 5001 # -> RPI4 + + +Running more device instances: +****************************** + +It is possible to run more than one instance of DUTs: + +* Adjust IP addresses in ``nucleo_g474re.conf`` + +* In ``boards/nucleo_g474re.overlay`` adjust :code:`local-mac-address` and + :code:`plca-node-id` properties. + + +.. _microe-lan8651: + https://www.mikroe.com/two-wire-eth-click?srsltid=AfmBOoouUPjUzmLu19iA8wRez6GyJp5Mf_mMjckgRcvtqrBA9INjaKQe + +.. _evb-lan8670: + https://www.microchip.com/en-us/development-tool/ev08l38a + +.. _rpi4-spec: + https://www.raspberrypi.com/products/raspberry-pi-4-model-b/specifications/ + +.. _udp-perf: + https://gitlab.com/network851614/udp-perf/-/tree/main/zephyr?ref_type=heads + +.. _udp-perf-zephyr: + https://gitlab.com/network851614/udp-perf/-/tree/main/zephyr?ref_type=heads From 12cd3703ebcb284eb0d56502d0be317586b2e5d2 Mon Sep 17 00:00:00 2001 From: Benedek Kupper Date: Mon, 5 Jan 2026 14:49:27 +0100 Subject: [PATCH 1683/3659] drivers: adc: stm32: only set CR2/DMA bit once on STM32F1 As reported in #101190, running adc_sequence sample on stm32f103c8 with 8 ADC channels causes all subsequent conversions after the first to be one channel shifted. This is because writing to CR2 with ADON=1 and no other changes triggers a conversion (which is why the bug happens on all but the first sequence). Adding this check will ensure that CR2 is only written when the DMA bit changes. Signed-off-by: Benedek Kupper --- drivers/adc/adc_stm32.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/adc/adc_stm32.c b/drivers/adc/adc_stm32.c index 8df0aec6336b..dbffd9b27c6e 100644 --- a/drivers/adc/adc_stm32.c +++ b/drivers/adc/adc_stm32.c @@ -240,7 +240,12 @@ static void adc_stm32_enable_dma_support(ADC_TypeDef *adc) { /* Allow ADC to create DMA request and set to one-shot mode as implemented in HAL drivers */ #if DT_HAS_COMPAT_STATUS_OKAY(st_stm32f1_adc) - LL_ADC_REG_SetDMATransfer(adc, LL_ADC_REG_DMA_TRANSFER_UNLIMITED); + /* Only modify CR2 register if DMA bit is not already set, otherwise + * when ADON=1 a conversion is triggered + */ + if (LL_ADC_REG_GetDMATransfer(adc) != LL_ADC_REG_DMA_TRANSFER_UNLIMITED) { + LL_ADC_REG_SetDMATransfer(adc, LL_ADC_REG_DMA_TRANSFER_UNLIMITED); + } #elif defined(CONFIG_SOC_SERIES_STM32H7X) || \ defined(CONFIG_SOC_SERIES_STM32N6X) || \ defined(CONFIG_SOC_SERIES_STM32U3X) || \ From 7440bca13d73f61b2b96d091c1b2e020ec5a05e7 Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Wed, 26 Mar 2025 13:16:11 +0100 Subject: [PATCH 1684/3659] drivers: pwm: shell: add command for getting cycles per second Add PWM shell command for getting the number of cycles per second for a given PWM controller/channel. Signed-off-by: Henrik Brix Andersen --- drivers/pwm/pwm_shell.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/drivers/pwm/pwm_shell.c b/drivers/pwm/pwm_shell.c index c28e44632fed..2a4f21b90550 100644 --- a/drivers/pwm/pwm_shell.c +++ b/drivers/pwm/pwm_shell.c @@ -29,6 +29,32 @@ static const struct args_index args_indx = { .flags = 5, }; +static int cmd_frequency(const struct shell *sh, size_t argc, char **argv) +{ + const struct device *dev; + uint32_t channel; + uint64_t cycles; + int err; + + dev = shell_device_get_binding(argv[args_indx.device]); + if (dev == NULL) { + shell_error(sh, "PWM device not found"); + return -EINVAL; + } + + channel = strtoul(argv[args_indx.channel], NULL, 0); + + err = pwm_get_cycles_per_sec(dev, channel, &cycles); + if (err != 0) { + shell_error(sh, "failed to get PWM cycles per second (err %d)", err); + return err; + } + + shell_print(sh, "Frequency: %" PRIu64 " Hz", cycles); + + return 0; +} + static int cmd_cycles(const struct shell *sh, size_t argc, char **argv) { pwm_flags_t flags = 0; @@ -144,6 +170,10 @@ static void device_name_get(size_t idx, struct shell_static_entry *entry) SHELL_DYNAMIC_CMD_CREATE(dsub_device_name, device_name_get); SHELL_STATIC_SUBCMD_SET_CREATE(pwm_cmds, + SHELL_CMD_ARG(frequency, &dsub_device_name, + SHELL_HELP("Get PWM counter frequency in Hz.", + " "), + cmd_frequency, 3, 0), SHELL_CMD_ARG( cycles, &dsub_device_name, SHELL_HELP("Set PWM period and pulse width in cycles.", From 6bb7a1b54ba789172d86b37f71e7d38b54df8bba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gu=C3=B0ni=20M=C3=A1r=20Gilbert?= Date: Sat, 10 Jan 2026 16:02:13 +0000 Subject: [PATCH 1685/3659] scripts: twister: Add full_name to board.yml MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes regression introduced by e45ac11aeb9b874038a2925c2588b94100aa28cc Signed-off-by: Guðni Már Gilbert --- .../tests/twister/test_data/boards/1_level/2_level/board.yml | 3 +++ scripts/tests/twister/test_platform.py | 5 +++++ .../test_data/boards/others/dummy_board/board.yml | 1 + 3 files changed, 9 insertions(+) diff --git a/scripts/tests/twister/test_data/boards/1_level/2_level/board.yml b/scripts/tests/twister/test_data/boards/1_level/2_level/board.yml index 863e42047b65..90a1b447fda9 100644 --- a/scripts/tests/twister/test_data/boards/1_level/2_level/board.yml +++ b/scripts/tests/twister/test_data/boards/1_level/2_level/board.yml @@ -1,14 +1,17 @@ boards: - name: demo_board_1 + full_name: Demo Board 1 vendor: zephyr socs: - name: unit_testing - name: demo_board_2 + full_name: Demo Board 2 vendor: zephyr socs: - name: unit_testing - name: demo_board_3 + full_name: Demo Board 3 vendor: zephyr socs: - name: unit_testing diff --git a/scripts/tests/twister/test_platform.py b/scripts/tests/twister/test_platform.py index 7cc20e7e23c1..bef49ca861f4 100644 --- a/scripts/tests/twister/test_platform.py +++ b/scripts/tests/twister/test_platform.py @@ -191,10 +191,12 @@ def test_generate_platforms( 'm0/boards/zephyr/p1/board.yml': """\ boards: - name: p1e1 + full_name: p1e1 vendor: zephyr socs: - name: s1 - name: p1e2 + full_name: p1e2 vendor: zephyr socs: - name: s1 @@ -211,6 +213,7 @@ def test_generate_platforms( 'm0/boards/zephyr/p2/board.yml': """\ boards: - name: p2 + full_name: p2 vendor: zephyr socs: - name: s1 @@ -226,6 +229,7 @@ def test_generate_platforms( 'm0/boards/arm/p3/board.yml': """\ board: name: p3 + full_name: p3 vendor: arm revision: format: letter @@ -296,6 +300,7 @@ def test_generate_platforms( boards: - extend: p3 - name: p4 + full_name: p4 vendor: misc socs: - name: s1 diff --git a/scripts/tests/twister_blackbox/test_data/boards/others/dummy_board/board.yml b/scripts/tests/twister_blackbox/test_data/boards/others/dummy_board/board.yml index a139d44b95fc..fdf204c9f35b 100644 --- a/scripts/tests/twister_blackbox/test_data/boards/others/dummy_board/board.yml +++ b/scripts/tests/twister_blackbox/test_data/boards/others/dummy_board/board.yml @@ -1,5 +1,6 @@ board: name: dummy + full_name: dummy vendor: others socs: - name: unit_testing From 6f9e5bed93b5cc276cc6effe43dda7fabc45b2d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fin=20Maa=C3=9F?= Date: Fri, 22 Aug 2025 15:05:02 +0200 Subject: [PATCH 1686/3659] devicetree: add DT_ANY/ALL_INST for reg names MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit add DT_ANY_INST_REG_HAS_NAME_STATUS_OKAY and DT_ALL_INST_REG_HAS_NAME_STATUS_OKAY to check if any instance has a register with a specific name. Signed-off-by: Fin Maaß --- include/zephyr/devicetree.h | 49 +++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/include/zephyr/devicetree.h b/include/zephyr/devicetree.h index 6fca2c19e463..497822f6cfc6 100644 --- a/include/zephyr/devicetree.h +++ b/include/zephyr/devicetree.h @@ -5216,6 +5216,25 @@ #define DT_ALL_INST_HAS_BOOL_STATUS_OKAY(prop) \ IS_EMPTY(DT_INST_FOREACH_STATUS_OKAY_VARGS(DT_ALL_INST_HAS_BOOL_STATUS_OKAY_, prop)) +/** + * @brief Check if any `DT_DRV_COMPAT` node with status `okay` has a given + * register name. + * + * @param name lowercase-and-underscores register name + */ +#define DT_ANY_INST_REG_HAS_NAME_STATUS_OKAY(name) \ + UTIL_NOT(IS_EMPTY( \ + DT_INST_FOREACH_STATUS_OKAY_VARGS(DT_ANY_INST_REG_HAS_NAME_STATUS_OKAY_, name))) + +/** + * @brief Check if all `DT_DRV_COMPAT` node with status `okay` has a given + * register name. If all nodes are disabled, this will return 1. + * + * @param name lowercase-and-underscores register name + */ +#define DT_ALL_INST_REG_HAS_NAME_STATUS_OKAY(name) \ + IS_EMPTY(DT_INST_FOREACH_STATUS_OKAY_VARGS(DT_ALL_INST_REG_HAS_NAME_STATUS_OKAY_, name)) + /** * @brief Call @p fn on all nodes with compatible `DT_DRV_COMPAT` * and status `okay` @@ -5514,6 +5533,21 @@ #define DT_ANY_INST_HAS_BOOL_STATUS_OKAY_(inst, prop) \ IF_ENABLED(DT_INST_PROP(inst, prop), (1,)) +/** @brief Helper for DT_ANY_INST_REG_HAS_NAME_STATUS_OKAY + * + * This macro generates token "1," for instance of a device, + * identified by index @p inst, if instance has named register + * @p name. + * + * @param inst instance number + * @param name register name to check for + * + * @return Macro evaluates to `1,` if instance register name exists, + * otherwise it evaluates to literal nothing. + */ +#define DT_ANY_INST_REG_HAS_NAME_STATUS_OKAY_(inst, name) \ + IF_ENABLED(DT_INST_REG_HAS_NAME(inst, name), (1,)) + /** @brief Helper for DT_ALL_INST_HAS_PROP_STATUS_OKAY * * This macro generates token "1," for instance of a device, @@ -5543,6 +5577,21 @@ #define DT_ALL_INST_HAS_BOOL_STATUS_OKAY_(inst, prop) \ IF_DISABLED(DT_INST_PROP(inst, prop), (1,)) +/** @brief Helper for DT_ALL_INST_REG_HAS_NAME_STATUS_OKAY + * + * This macro generates token "1," for instance of a device, + * identified by index @p inst, if instance has no named register + * @p name. + * + * @param inst instance number + * @param name register name to check for + * + * @return Macro evaluates to `1,` if instance register name exists, + * otherwise it evaluates to literal nothing. + */ +#define DT_ALL_INST_REG_HAS_NAME_STATUS_OKAY_(inst, name) \ + IF_DISABLED(DT_INST_REG_HAS_NAME(inst, name), (1,)) + #define DT_PATH_INTERNAL(...) \ UTIL_CAT(DT_ROOT, MACRO_MAP_CAT(DT_S_PREFIX, __VA_ARGS__)) /** @brief DT_PATH_INTERNAL() helper: prepends _S_ to a node name From 1ad13962eebce538a2a4fbd416dc33d851038870 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fin=20Maa=C3=9F?= Date: Wed, 3 Dec 2025 17:08:45 +0100 Subject: [PATCH 1687/3659] tests: dts: add for DT_ANY/ALL_INST_REG_HAS_NAME_STATUS_OKAY MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit add test for DT_ANY_INST_REG_HAS_NAME_STATUS_OKAY and DT_ALL_INST_REG_HAS_NAME_STATUS_OKAY macros. Signed-off-by: Fin Maaß --- dts/bindings/test/vnd,reg-holder-2.yaml | 15 +++++++++ tests/lib/devicetree/api/app.overlay | 21 ++++++++++++ tests/lib/devicetree/api/src/main.c | 44 +++++++++++++++++++++++++ 3 files changed, 80 insertions(+) create mode 100644 dts/bindings/test/vnd,reg-holder-2.yaml diff --git a/dts/bindings/test/vnd,reg-holder-2.yaml b/dts/bindings/test/vnd,reg-holder-2.yaml new file mode 100644 index 000000000000..0189b107e8ce --- /dev/null +++ b/dts/bindings/test/vnd,reg-holder-2.yaml @@ -0,0 +1,15 @@ +# Copyright (c) 2020 Linaro Ltd. +# SPDX-License-Identifier: Apache-2.0 + +description: Test register property container + +compatible: "vnd,reg-holder-2" + +include: [base.yaml] + +properties: + reg: + required: true + + reg-names: + required: true diff --git a/tests/lib/devicetree/api/app.overlay b/tests/lib/devicetree/api/app.overlay index 05889318e38e..ae6e4e316a1c 100644 --- a/tests/lib/devicetree/api/app.overlay +++ b/tests/lib/devicetree/api/app.overlay @@ -435,6 +435,27 @@ misc-prop = <1234>; }; + test_reg_0: reg-holder-0@9999baaa { + compatible = "vnd,reg-holder-2"; + reg = <0x9999baaa 0x1000 0xbbbbcccc 0x3f>; + status = "okay"; + reg-names = "foo", "bar"; + }; + + test_reg_1: reg-holder-1@9999caaa { + compatible = "vnd,reg-holder-2"; + reg = <0x9999caaa 0x1000>; + status = "okay"; + reg-names = "foo"; + }; + + test_reg_2: reg-holder-2@9999daaa { + compatible = "vnd,reg-holder-2"; + reg = <0x9999daaa 0x1000>; + status = "disabled"; + reg-names = "baz"; + }; + test_vendor: vendor { compatible = "vnd,model1", "gpio", "zephyr,model2"; status = "okay"; diff --git a/tests/lib/devicetree/api/src/main.c b/tests/lib/devicetree/api/src/main.c index 81085adb91d4..fd8bd88085ff 100644 --- a/tests/lib/devicetree/api/src/main.c +++ b/tests/lib/devicetree/api/src/main.c @@ -205,6 +205,50 @@ ZTEST(devicetree_api, test_inst_props) "vnd,gpio-device"), ""); } +#undef DT_DRV_COMPAT +#define DT_DRV_COMPAT vnd_reg_holder_2 +ZTEST(devicetree_api, test_any_inst_reg_names) +{ + zassert_equal(DT_ANY_INST_REG_HAS_NAME_STATUS_OKAY(foo), 1, ""); + zassert_equal(DT_ANY_INST_REG_HAS_NAME_STATUS_OKAY(bar), 1, ""); + zassert_equal(DT_ANY_INST_REG_HAS_NAME_STATUS_OKAY(baz), 0, ""); + zassert_equal(DT_ANY_INST_REG_HAS_NAME_STATUS_OKAY(does_not_exist), 0, ""); + + zassert_equal(COND_CODE_1(DT_ANY_INST_REG_HAS_NAME_STATUS_OKAY(foo), + (5), (6)), 5, ""); + zassert_equal(COND_CODE_0(DT_ANY_INST_REG_HAS_NAME_STATUS_OKAY(foo), + (5), (6)), 6, ""); + zassert_equal(COND_CODE_1(DT_ANY_INST_REG_HAS_NAME_STATUS_OKAY(baz), + (5), (6)), 6, ""); + zassert_equal(COND_CODE_0(DT_ANY_INST_REG_HAS_NAME_STATUS_OKAY(baz), + (5), (6)), 5, ""); + zassert_true(IS_ENABLED(DT_ANY_INST_REG_HAS_NAME_STATUS_OKAY(foo)), ""); + zassert_true(!IS_ENABLED(DT_ANY_INST_REG_HAS_NAME_STATUS_OKAY(baz)), ""); + zassert_equal(IF_ENABLED(DT_ANY_INST_REG_HAS_NAME_STATUS_OKAY(foo), (1)) + 1, 2, ""); + zassert_equal(IF_ENABLED(DT_ANY_INST_REG_HAS_NAME_STATUS_OKAY(baz), (1)) + 1, 1, ""); +} + +ZTEST(devicetree_api, test_all_inst_reg_names) +{ + zassert_equal(DT_ALL_INST_REG_HAS_NAME_STATUS_OKAY(foo), 1, ""); + zassert_equal(DT_ALL_INST_REG_HAS_NAME_STATUS_OKAY(bar), 0, ""); + zassert_equal(DT_ALL_INST_REG_HAS_NAME_STATUS_OKAY(baz), 0, ""); + zassert_equal(DT_ALL_INST_REG_HAS_NAME_STATUS_OKAY(does_not_exist), 0, ""); + + zassert_equal(COND_CODE_1(DT_ALL_INST_REG_HAS_NAME_STATUS_OKAY(foo), + (5), (6)), 5, ""); + zassert_equal(COND_CODE_0(DT_ALL_INST_REG_HAS_NAME_STATUS_OKAY(foo), + (5), (6)), 6, ""); + zassert_equal(COND_CODE_1(DT_ALL_INST_REG_HAS_NAME_STATUS_OKAY(baz), + (5), (6)), 6, ""); + zassert_equal(COND_CODE_0(DT_ALL_INST_REG_HAS_NAME_STATUS_OKAY(baz), + (5), (6)), 5, ""); + zassert_true(IS_ENABLED(DT_ALL_INST_REG_HAS_NAME_STATUS_OKAY(foo)), ""); + zassert_true(!IS_ENABLED(DT_ALL_INST_REG_HAS_NAME_STATUS_OKAY(baz)), ""); + zassert_equal(IF_ENABLED(DT_ALL_INST_REG_HAS_NAME_STATUS_OKAY(foo), (1)) + 1, 2, ""); + zassert_equal(IF_ENABLED(DT_ALL_INST_REG_HAS_NAME_STATUS_OKAY(baz), (1)) + 1, 1, ""); +} + #undef DT_DRV_COMPAT #define DT_DRV_COMPAT vnd_device_with_props ZTEST(devicetree_api, test_any_inst_prop) From 075f2e73617fd999ada473cb22e740646f6ea82e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fin=20Maa=C3=9F?= Date: Thu, 13 Nov 2025 17:51:45 +0100 Subject: [PATCH 1688/3659] drivers: gpio: litex: rework litex gpio driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit rework litex gpio driver. It is now also supported to change direction. now uses the reg names to detect if what modes the gpio controller supports. use the reg names directly from litex. Signed-off-by: Fin Maaß --- .../litex_vexriscv/litex_vexriscv.dts | 13 +- drivers/gpio/gpio_litex.c | 336 ++++++++++-------- dts/bindings/gpio/litex,gpio.yaml | 4 - 3 files changed, 186 insertions(+), 167 deletions(-) diff --git a/boards/enjoydigital/litex_vexriscv/litex_vexriscv.dts b/boards/enjoydigital/litex_vexriscv/litex_vexriscv.dts index 4d20ff909e0e..8cc07204745d 100644 --- a/boards/enjoydigital/litex_vexriscv/litex_vexriscv.dts +++ b/boards/enjoydigital/litex_vexriscv/litex_vexriscv.dts @@ -297,9 +297,8 @@ gpio_out: gpio@e0005800 { compatible = "litex,gpio"; reg = <0xe0005800 0x4>; - reg-names = "control"; + reg-names = "out"; ngpios = <4>; - port-is-output; status = "okay"; gpio-controller; #gpio-cells = <2>; @@ -314,11 +313,11 @@ <0xe0006014 0x4>; interrupt-parent = <&intc0>; interrupts = <4 2>; - reg-names = "base", - "irq_mode", - "irq_edge", - "irq_pend", - "irq_en"; + reg-names = "in", + "mode", + "edge", + "ev_pending", + "ev_enable"; ngpios = <4>; status = "okay"; gpio-controller; diff --git a/drivers/gpio/gpio_litex.c b/drivers/gpio/gpio_litex.c index 3d7d9a1744d0..325e003f5446 100644 --- a/drivers/gpio/gpio_litex.c +++ b/drivers/gpio/gpio_litex.c @@ -1,6 +1,7 @@ /* * Copyright (c) 2019-2021 Antmicro * Copyright (c) 2021 Raptor Engineering, LLC + * SPDX-FileCopyrightText: Copyright The Zephyr Project Contributors * * SPDX-License-Identifier: Apache-2.0 */ @@ -18,6 +19,27 @@ #include +BUILD_ASSERT(CONFIG_LITEX_CSR_DATA_WIDTH == 32, "CONFIG_LITEX_CSR_DATA_WIDTH must be 32 bits"); + +#define GPIO_LITEX_ALL_HAS_IRQ DT_ALL_INST_HAS_PROP_STATUS_OKAY(interrupts) +#define GPIO_LITEX_ANY_HAS_IRQ DT_ANY_INST_HAS_PROP_STATUS_OKAY(interrupts) + +#define GPIO_LITEX_ALL_HAS_OE DT_ALL_INST_REG_HAS_NAME_STATUS_OKAY(oe) +#define GPIO_LITEX_ANY_HAS_OE DT_ANY_INST_REG_HAS_NAME_STATUS_OKAY(oe) + +#define GPIO_LITEX_ALL_HAS_OUT DT_ALL_INST_REG_HAS_NAME_STATUS_OKAY(out) +#define GPIO_LITEX_ANY_HAS_OUT DT_ANY_INST_REG_HAS_NAME_STATUS_OKAY(out) + +#define GPIO_LITEX_ALL_HAS_IN DT_ALL_INST_REG_HAS_NAME_STATUS_OKAY(in) +#define GPIO_LITEX_ANY_HAS_IN DT_ANY_INST_REG_HAS_NAME_STATUS_OKAY(in) + +#define GPIO_LITEX_HAS_OE(cfg) \ + (GPIO_LITEX_ANY_HAS_OE && (GPIO_LITEX_ALL_HAS_OE || ((cfg)->oe_addr != 0))) +#define GPIO_LITEX_HAS_OUT(cfg) \ + (GPIO_LITEX_ANY_HAS_OUT && (GPIO_LITEX_ALL_HAS_OUT || ((cfg)->out_addr != 0))) +#define GPIO_LITEX_HAS_IN(cfg) \ + (GPIO_LITEX_ANY_HAS_IN && (GPIO_LITEX_ALL_HAS_IN || ((cfg)->in_addr != 0))) + #include #define SUPPORTED_FLAGS (GPIO_INPUT | GPIO_OUTPUT | \ @@ -30,20 +52,15 @@ #define LOG_LEVEL CONFIG_GPIO_LOG_LEVEL LOG_MODULE_REGISTER(gpio_litex); -static const char *LITEX_LOG_REG_SIZE_NGPIOS_MISMATCH = - "Cannot handle all of the gpios with the register of given size\n"; -static const char *LITEX_LOG_CANNOT_CHANGE_DIR = - "Cannot change port direction selected in device tree\n"; - struct gpio_litex_cfg { - uint32_t reg_addr; - int reg_size; - uint32_t ev_pending_addr; - uint32_t ev_enable_addr; - uint32_t ev_mode_addr; - uint32_t ev_edge_addr; - int nr_gpios; - bool port_is_output; + struct gpio_driver_config common; + mem_addr_t oe_addr; + mem_addr_t in_addr; + mem_addr_t out_addr; + mem_addr_t ev_pending_addr; + mem_addr_t ev_enable_addr; + mem_addr_t ev_mode_addr; + mem_addr_t ev_edge_addr; }; struct gpio_litex_data { @@ -59,39 +76,37 @@ struct gpio_litex_data { /* Helper functions for bit / port access */ -static inline void set_bit(const struct gpio_litex_cfg *config, - uint32_t bit, bool val) +static inline void set_bit(mem_addr_t reg_addr, uint32_t bit, bool val) { - int regv, new_regv; + uint32_t reg = litex_read32(reg_addr); - regv = litex_read(config->reg_addr, config->reg_size); - new_regv = (regv & ~BIT(bit)) | (val << bit); - litex_write(config->reg_addr, config->reg_size, new_regv); + WRITE_BIT(reg, bit, val); + + litex_write32(reg, reg_addr); } -static inline uint32_t get_bit(const struct gpio_litex_cfg *config, uint32_t bit) +static inline uint32_t get_bit(mem_addr_t reg_addr, int reg_size, uint32_t bit) { - int regv = litex_read(config->reg_addr, config->reg_size); + uint32_t reg = litex_read32(reg_addr); - return !!(regv & BIT(bit)); + return IS_BIT_SET(reg, bit); } -static inline void set_port(const struct gpio_litex_cfg *config, uint32_t value) +static inline uint32_t get_port_out(const struct gpio_litex_cfg *gpio_config) { - litex_write(config->reg_addr, config->reg_size, value); + return (litex_read32(gpio_config->out_addr) & gpio_config->common.port_pin_mask); } -static inline uint32_t get_port(const struct gpio_litex_cfg *config) +static inline void set_oe(const struct gpio_litex_cfg *gpio_config, gpio_pin_t pin, bool val) { - int regv = litex_read(config->reg_addr, config->reg_size); - - return (regv & BIT_MASK(config->nr_gpios)); + if (GPIO_LITEX_HAS_OE(gpio_config)) { + set_bit(gpio_config->oe_addr, pin, 1); + } } /* Driver functions */ -static int gpio_litex_configure(const struct device *dev, - gpio_pin_t pin, gpio_flags_t flags) +static int gpio_litex_configure(const struct device *dev, gpio_pin_t pin, gpio_flags_t flags) { const struct gpio_litex_cfg *gpio_config = DEV_GPIO_CFG(dev); @@ -99,41 +114,42 @@ static int gpio_litex_configure(const struct device *dev, return -ENOTSUP; } - if ((flags & GPIO_OUTPUT) && (flags & GPIO_INPUT)) { - /* Pin cannot be configured as input and output */ - return -ENOTSUP; - } else if (!(flags & (GPIO_INPUT | GPIO_OUTPUT))) { - /* Pin has to be configured as input or output */ - return -ENOTSUP; - } - - if (flags & GPIO_OUTPUT) { - if (!gpio_config->port_is_output) { - LOG_ERR("%s", LITEX_LOG_CANNOT_CHANGE_DIR); + switch (flags & GPIO_DIR_MASK) { + case GPIO_OUTPUT: + if (!GPIO_LITEX_HAS_OUT(gpio_config)) { return -EINVAL; } - if (flags & GPIO_OUTPUT_INIT_HIGH) { - set_bit(gpio_config, pin, GPIO_HIGH); - } else if (flags & GPIO_OUTPUT_INIT_LOW) { - set_bit(gpio_config, pin, GPIO_LOW); + set_oe(gpio_config, pin, true); + + if (flags & (GPIO_OUTPUT_INIT_HIGH | GPIO_OUTPUT_INIT_LOW)) { + set_bit(gpio_config->out_addr, pin, (flags & GPIO_OUTPUT_INIT_HIGH) != 0); } - } else { - if (gpio_config->port_is_output) { - LOG_ERR("%s", LITEX_LOG_CANNOT_CHANGE_DIR); + + break; + case GPIO_INPUT: + if (!GPIO_LITEX_HAS_IN(gpio_config)) { return -EINVAL; } + + set_oe(gpio_config, pin, false); + + break; + default: + return -ENOTSUP; } return 0; } -static int gpio_litex_port_get_raw(const struct device *dev, - gpio_port_value_t *value) +static int gpio_litex_port_get_raw(const struct device *dev, gpio_port_value_t *value) { const struct gpio_litex_cfg *gpio_config = DEV_GPIO_CFG(dev); - *value = get_port(gpio_config); + *value = GPIO_LITEX_HAS_IN(gpio_config) + ? (litex_read32(gpio_config->in_addr) & gpio_config->common.port_pin_mask) + : 0; + return 0; } @@ -144,9 +160,11 @@ static int gpio_litex_port_set_masked_raw(const struct device *dev, const struct gpio_litex_cfg *gpio_config = DEV_GPIO_CFG(dev); uint32_t port_val; - port_val = get_port(gpio_config); - port_val = (port_val & ~mask) | (value & mask); - set_port(gpio_config, port_val); + if (GPIO_LITEX_HAS_OUT(gpio_config)) { + port_val = get_port_out(gpio_config); + port_val = (port_val & ~mask) | (value & mask); + litex_write32(port_val, gpio_config->out_addr); + } return 0; } @@ -157,9 +175,11 @@ static int gpio_litex_port_set_bits_raw(const struct device *dev, const struct gpio_litex_cfg *gpio_config = DEV_GPIO_CFG(dev); uint32_t port_val; - port_val = get_port(gpio_config); - port_val |= pins; - set_port(gpio_config, port_val); + if (GPIO_LITEX_HAS_OUT(gpio_config)) { + port_val = get_port_out(gpio_config); + port_val |= pins; + litex_write32(port_val, gpio_config->out_addr); + } return 0; } @@ -170,10 +190,11 @@ static int gpio_litex_port_clear_bits_raw(const struct device *dev, const struct gpio_litex_cfg *gpio_config = DEV_GPIO_CFG(dev); uint32_t port_val; - port_val = get_port(gpio_config); - port_val &= ~pins; - set_port(gpio_config, port_val); - + if (GPIO_LITEX_HAS_OUT(gpio_config)) { + port_val = get_port_out(gpio_config); + port_val &= ~pins; + litex_write32(port_val, gpio_config->out_addr); + } return 0; } @@ -183,26 +204,26 @@ static int gpio_litex_port_toggle_bits(const struct device *dev, const struct gpio_litex_cfg *gpio_config = DEV_GPIO_CFG(dev); uint32_t port_val; - port_val = get_port(gpio_config); - port_val ^= pins; - set_port(gpio_config, port_val); + if (GPIO_LITEX_HAS_OUT(gpio_config)) { + port_val = get_port_out(gpio_config); + port_val ^= pins; + litex_write32(port_val, gpio_config->out_addr); + } return 0; } +#if GPIO_LITEX_ANY_HAS_IRQ static void gpio_litex_irq_handler(const struct device *dev) { const struct gpio_litex_cfg *gpio_config = DEV_GPIO_CFG(dev); struct gpio_litex_data *data = dev->data; - uint8_t int_status = - litex_read(gpio_config->ev_pending_addr, gpio_config->reg_size); - uint8_t ev_enabled = - litex_read(gpio_config->ev_enable_addr, gpio_config->reg_size); + uint32_t int_status = litex_read32(gpio_config->ev_pending_addr); + uint32_t ev_enabled = litex_read32(gpio_config->ev_enable_addr); /* clear events */ - litex_write(gpio_config->ev_pending_addr, gpio_config->reg_size, - int_status); + litex_write32(int_status, gpio_config->ev_pending_addr); gpio_fire_callbacks(&data->cb, dev, int_status & ev_enabled); } @@ -221,67 +242,75 @@ static int gpio_litex_pin_interrupt_configure(const struct device *dev, enum gpio_int_trig trig) { const struct gpio_litex_cfg *gpio_config = DEV_GPIO_CFG(dev); + uint32_t ev_enabled, ev_mode, ev_edge; - if (gpio_config->port_is_output == true) { + if (!GPIO_LITEX_HAS_IN(gpio_config) || + !(GPIO_LITEX_ALL_HAS_IRQ || gpio_config->ev_enable_addr != 0)) { return -ENOTSUP; } + if (GPIO_LITEX_HAS_OE(gpio_config) && + IS_BIT_SET(litex_read32(gpio_config->oe_addr), pin)) { + return -EINVAL; + } + + ev_enabled = litex_read32(gpio_config->ev_enable_addr); + if (mode == GPIO_INT_MODE_EDGE) { - uint8_t ev_enabled = litex_read(gpio_config->ev_enable_addr, - gpio_config->reg_size); - uint8_t ev_mode = litex_read(gpio_config->ev_mode_addr, - gpio_config->reg_size); - uint8_t ev_edge = litex_read(gpio_config->ev_edge_addr, - gpio_config->reg_size); - - litex_write(gpio_config->ev_enable_addr, gpio_config->reg_size, - ev_enabled | BIT(pin)); - - if (trig == GPIO_INT_TRIG_HIGH) { - /* Change mode to 'edge' and edge to 'rising' */ - litex_write(gpio_config->ev_mode_addr, gpio_config->reg_size, - ev_mode & ~BIT(pin)); - litex_write(gpio_config->ev_edge_addr, gpio_config->reg_size, - ev_edge & ~BIT(pin)); - } else if (trig == GPIO_INT_TRIG_LOW) { - /* Change mode to 'edge' and edge to 'falling' */ - litex_write(gpio_config->ev_mode_addr, gpio_config->reg_size, - ev_mode & ~BIT(pin)); - litex_write(gpio_config->ev_edge_addr, gpio_config->reg_size, - ev_edge | BIT(pin)); - } else if (trig == GPIO_INT_TRIG_BOTH) { - /* Change mode to 'change' */ - litex_write(gpio_config->ev_mode_addr, gpio_config->reg_size, - ev_mode | BIT(pin)); + ev_mode = litex_read32(gpio_config->ev_mode_addr); + ev_edge = litex_read32(gpio_config->ev_edge_addr); + + litex_write32(ev_enabled | BIT(pin), gpio_config->ev_enable_addr); + + WRITE_BIT(ev_mode, pin, (trig == GPIO_INT_TRIG_BOTH)); + + litex_write32(ev_mode, gpio_config->ev_mode_addr); + + switch (trig & GPIO_INT_TRIG_BOTH) { + case GPIO_INT_TRIG_HIGH: + /* Rising edge */ + litex_write32(ev_edge & ~BIT(pin), gpio_config->ev_edge_addr); + break; + case GPIO_INT_TRIG_LOW: + /* Falling edge */ + litex_write32(ev_edge | BIT(pin), gpio_config->ev_edge_addr); + break; + default: + break; } return 0; } if (mode == GPIO_INT_DISABLE) { - uint8_t ev_enabled = litex_read(gpio_config->ev_enable_addr, - gpio_config->reg_size); - litex_write(gpio_config->ev_enable_addr, gpio_config->reg_size, - ev_enabled & ~BIT(pin)); + litex_write32(ev_enabled & ~BIT(pin), gpio_config->ev_enable_addr); return 0; } return -ENOTSUP; } +#endif /* GPIO_LITEX_ANY_HAS_IRQ */ #ifdef CONFIG_GPIO_GET_DIRECTION static int gpio_litex_port_get_direction(const struct device *dev, gpio_port_pins_t map, gpio_port_pins_t *inputs, gpio_port_pins_t *outputs) { const struct gpio_litex_cfg *gpio_config = DEV_GPIO_CFG(dev); + uint32_t oe_reg; - map &= gpio_config->port_pin_mask; + map &= gpio_config->common.port_pin_mask; + + if (!GPIO_LITEX_HAS_OE(gpio_config)) { + oe_reg = GPIO_LITEX_HAS_OUT(gpio_config) ? UINT32_MAX : 0; + } else { + oe_reg = litex_read32(gpio_config->oe_addr); + } if (inputs != NULL) { - *inputs = map & (!gpio_config->port_is_output); + *inputs = map & ~oe_reg; } if (outputs != NULL) { - *outputs = map & (gpio_config->port_is_output); + *outputs = map & oe_reg; } return 0; @@ -295,66 +324,61 @@ static DEVICE_API(gpio, gpio_litex_driver_api) = { .port_set_bits_raw = gpio_litex_port_set_bits_raw, .port_clear_bits_raw = gpio_litex_port_clear_bits_raw, .port_toggle_bits = gpio_litex_port_toggle_bits, +#if GPIO_LITEX_ANY_HAS_IRQ .pin_interrupt_configure = gpio_litex_pin_interrupt_configure, .manage_callback = gpio_litex_manage_callback, +#endif /* GPIO_LITEX_ANY_HAS_IRQ */ #ifdef CONFIG_GPIO_GET_DIRECTION .port_get_direction = gpio_litex_port_get_direction, #endif /* CONFIG_GPIO_GET_DIRECTION */ }; /* Device Instantiation */ -#define GPIO_LITEX_IRQ_INIT(n) \ - do { \ - IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority), \ - gpio_litex_irq_handler, \ - DEVICE_DT_INST_GET(n), 0); \ -\ - irq_enable(DT_INST_IRQN(n)); \ - } while (false) - -#define GPIO_LITEX_INIT(n) \ - static int gpio_litex_port_init_##n(const struct device *dev); \ -\ - static const struct gpio_litex_cfg gpio_litex_cfg_##n = { \ - .reg_addr = DT_INST_REG_ADDR(n), \ - .reg_size = DT_INST_REG_SIZE(n), \ - .nr_gpios = DT_INST_PROP(n, ngpios), \ - IF_ENABLED(DT_INST_IRQ_HAS_IDX(n, 0), ( \ - .ev_mode_addr = DT_INST_REG_ADDR_BY_NAME(n, irq_mode), \ - .ev_edge_addr = DT_INST_REG_ADDR_BY_NAME(n, irq_edge), \ - .ev_pending_addr = DT_INST_REG_ADDR_BY_NAME(n, irq_pend), \ - .ev_enable_addr = DT_INST_REG_ADDR_BY_NAME(n, irq_en), \ - )) \ - .port_is_output = DT_INST_PROP(n, port_is_output), \ - }; \ - static struct gpio_litex_data gpio_litex_data_##n; \ -\ - DEVICE_DT_INST_DEFINE(n, \ - gpio_litex_port_init_##n, \ - NULL, \ - &gpio_litex_data_##n, \ - &gpio_litex_cfg_##n, \ - POST_KERNEL, \ - CONFIG_GPIO_INIT_PRIORITY, \ - &gpio_litex_driver_api \ - ); \ -\ - static int gpio_litex_port_init_##n(const struct device *dev) \ - { \ - const struct gpio_litex_cfg *gpio_config = DEV_GPIO_CFG(dev); \ -\ - /* Check if gpios fit in declared register space */ \ - /* Number of subregisters times size in bits */ \ - const int max_gpios_can_fit = DT_INST_REG_SIZE(n) / 4 \ - * CONFIG_LITEX_CSR_DATA_WIDTH; \ - if (gpio_config->nr_gpios > max_gpios_can_fit) { \ - LOG_ERR("%s", LITEX_LOG_REG_SIZE_NGPIOS_MISMATCH); \ - return -EINVAL; \ - } \ -\ - IF_ENABLED(DT_INST_IRQ_HAS_IDX(n, 0), \ - (GPIO_LITEX_IRQ_INIT(n);)) \ - return 0; \ +#define GPIO_LITEX_IRQ(n) \ + BUILD_ASSERT(DT_INST_REG_HAS_NAME(n, mode) && \ + DT_INST_REG_HAS_NAME(n, edge) && \ + DT_INST_REG_HAS_NAME(n, ev_pending) && \ + DT_INST_REG_HAS_NAME(n, ev_enable), \ + "registers for interrupts missing"); \ + \ + static int gpio_litex_port_init_##n(const struct device *dev) \ + { \ + IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority), gpio_litex_irq_handler, \ + DEVICE_DT_INST_GET(n), 0); \ + \ + irq_enable(DT_INST_IRQN(n)); \ + \ + return 0; \ } +#define GPIO_LITEX_INIT(n) \ + IF_ENABLED(DT_INST_IRQ_HAS_IDX(n, 0), (GPIO_LITEX_IRQ(n))) \ + \ + BUILD_ASSERT(DT_INST_REG_HAS_NAME(n, in) || DT_INST_REG_HAS_NAME(n, out), \ + "Either 'in' or 'out' register must be defined"); \ + BUILD_ASSERT((DT_INST_REG_HAS_NAME(n, in) && DT_INST_REG_HAS_NAME(n, out)) == \ + DT_INST_REG_HAS_NAME(n, oe), \ + "oe' register is needed, if both 'in' and 'out' registers are defined"); \ + BUILD_ASSERT(DT_INST_PROP(n, ngpios) <= 32, \ + "Number of gpios exceeds what can be handled"); \ + \ + static const struct gpio_litex_cfg gpio_litex_cfg_##n = { \ + .common = { .port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(n) }, \ + .oe_addr = DT_INST_REG_ADDR_BY_NAME_OR(n, oe, 0), \ + .in_addr = DT_INST_REG_ADDR_BY_NAME_OR(n, in, 0), \ + .out_addr = DT_INST_REG_ADDR_BY_NAME_OR(n, out, 0), \ + IF_ENABLED(DT_INST_IRQ_HAS_IDX(n, 0), ( \ + .ev_mode_addr = DT_INST_REG_ADDR_BY_NAME(n, mode), \ + .ev_edge_addr = DT_INST_REG_ADDR_BY_NAME(n, edge), \ + .ev_pending_addr = DT_INST_REG_ADDR_BY_NAME(n, ev_pending), \ + .ev_enable_addr = DT_INST_REG_ADDR_BY_NAME(n, ev_enable), \ + )) }; \ + \ + static struct gpio_litex_data gpio_litex_data_##n; \ + \ + DEVICE_DT_INST_DEFINE(n, COND_CODE_1(DT_INST_IRQ_HAS_IDX(n, 0), \ + (gpio_litex_port_init_##n), (NULL)), NULL, &gpio_litex_data_##n, \ + &gpio_litex_cfg_##n, POST_KERNEL, CONFIG_GPIO_INIT_PRIORITY, \ + &gpio_litex_driver_api); + DT_INST_FOREACH_STATUS_OKAY(GPIO_LITEX_INIT) diff --git a/dts/bindings/gpio/litex,gpio.yaml b/dts/bindings/gpio/litex,gpio.yaml index ad5a85e420b0..13ff6052eef7 100644 --- a/dts/bindings/gpio/litex,gpio.yaml +++ b/dts/bindings/gpio/litex,gpio.yaml @@ -11,10 +11,6 @@ compatible: "litex,gpio" include: [gpio-controller.yaml, base.yaml] properties: - port-is-output: - type: boolean - description: Indicates if the port is an output port - reg: required: true From 35f2cd63539547805e8781b7aba8428a6c2fb39d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fin=20Maa=C3=9F?= Date: Thu, 13 Nov 2025 18:16:04 +0100 Subject: [PATCH 1689/3659] doc: migration-guide: 4.4: mention litex,gpio change MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit mention litex,gpio change. Signed-off-by: Fin Maaß --- doc/releases/migration-guide-4.4.rst | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/doc/releases/migration-guide-4.4.rst b/doc/releases/migration-guide-4.4.rst index aaea2b3acf65..86583acbff39 100644 --- a/doc/releases/migration-guide-4.4.rst +++ b/doc/releases/migration-guide-4.4.rst @@ -331,6 +331,14 @@ Ethernet reworked to be used as active low, you may have to set the pin as ``GPIO_ACTIVE_LOW`` in devicetree (:github:`100751`). +GPIO +==== + +* The LiteX GPIO driver :dtcompatible:`litex,gpio` has been reworked to support changing direction. + The driver now uses the reg-names property to detect supported modes of the GPIO controller. + The Devicetree property ``port-is-output`` has been removed. + The reg-names are now taken directly from LiteX. (:github:`99329`) + Infineon ======== From 00bf0915d6e4fbc1da2a9da1aff632ad82de008c Mon Sep 17 00:00:00 2001 From: Ibrahim Abdalkader Date: Fri, 12 Dec 2025 15:49:36 +0100 Subject: [PATCH 1690/3659] llext: Skip MPU region alignment if userspace is disabled. llext aligns and rounds up memory regions to satisfy MPU requirements, which can waste significant memory by relocating read-only regions, with power-of-two alignment on some architectures. However, these MPU-aligned regions are never actually used by the MPU unless userspace (CONFIG_USERSPACE) is enabled. Signed-off-by: Ibrahim Abdalkader --- subsys/llext/llext_mem.c | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/subsys/llext/llext_mem.c b/subsys/llext/llext_mem.c index 84220a90a7c7..496397683337 100644 --- a/subsys/llext/llext_mem.c +++ b/subsys/llext/llext_mem.c @@ -96,25 +96,28 @@ static int llext_copy_region(struct llext_loader *ldr, struct llext *ext, * program-accessible data (not to string tables, for example). */ if (region->sh_flags & SHF_ALLOC) { - if (IS_ENABLED(CONFIG_MPU_REQUIRES_POWER_OF_TWO_ALIGNMENT)) { - /* Some MPU architectures (ARMv7-M, older ARC) require regions - * to be sized and aligned to the same power of two. - */ - uintptr_t block_sz = MAX(MAX(region_alloc, region_align), LLEXT_PAGE_SIZE); - - block_sz = 1 << LOG2CEIL(block_sz); /* align to next power of two */ - region_alloc = block_sz; - region_align = block_sz; - } else if (IS_ENABLED(CONFIG_ARM_MPU) || IS_ENABLED(CONFIG_ARC_MPU)) { - /* ARMv8-M and newer ARC MPUs use 32-byte alignment. */ - region_alloc = ROUND_UP(region_alloc, LLEXT_PAGE_SIZE); - region_align = MAX(region_align, LLEXT_PAGE_SIZE); - } else if (IS_ENABLED(CONFIG_MMU)) { + if (IS_ENABLED(CONFIG_MMU)) { /* MMU targets map memory in page-sized chunks. Round * the region to multiples of those. */ region_alloc = ROUND_UP(region_alloc, LLEXT_PAGE_SIZE); region_align = MAX(region_align, LLEXT_PAGE_SIZE); + } else if (IS_ENABLED(CONFIG_USERSPACE)) { + if (IS_ENABLED(CONFIG_MPU_REQUIRES_POWER_OF_TWO_ALIGNMENT)) { + /* Some MPU architectures (ARMv7-M, older ARC) require regions + * to be sized and aligned to the same power of two. + */ + uintptr_t block_sz = + MAX(MAX(region_alloc, region_align), LLEXT_PAGE_SIZE); + + block_sz = 1 << LOG2CEIL(block_sz); /* align to next power of two */ + region_alloc = block_sz; + region_align = block_sz; + } else if (IS_ENABLED(CONFIG_ARM_MPU) || IS_ENABLED(CONFIG_ARC_MPU)) { + /* ARMv8-M and newer ARC MPUs use 32-byte alignment. */ + region_alloc = ROUND_UP(region_alloc, LLEXT_PAGE_SIZE); + region_align = MAX(region_align, LLEXT_PAGE_SIZE); + } } } From b05332abee29c9460ffdd9d5d1c260985c2f63b6 Mon Sep 17 00:00:00 2001 From: Sylvio Alves Date: Fri, 12 Dec 2025 14:10:17 -0300 Subject: [PATCH 1691/3659] arch: riscv: pmp: add SoC-specific region support Add infrastructure for SoCs to define additional PMP regions that need protection beyond the standard ROM region. This uses iterable sections to collect region definitions at link time. The PMP_SOC_REGION_DEFINE macro allows SoCs to register memory regions with specific permissions. These regions become global PMP entries shared between M-mode and U-mode. Signed-off-by: Sylvio Alves --- arch/riscv/core/CMakeLists.txt | 1 + arch/riscv/core/pmp.c | 13 +++++++++++ arch/riscv/core/pmp.ld | 9 ++++++++ arch/riscv/include/pmp.h | 1 + include/zephyr/arch/riscv/pmp.h | 40 +++++++++++++++++++++++++++++++++ 5 files changed, 64 insertions(+) create mode 100644 arch/riscv/core/pmp.ld diff --git a/arch/riscv/core/CMakeLists.txt b/arch/riscv/core/CMakeLists.txt index dafbe63ff0b9..f42b156e0e27 100644 --- a/arch/riscv/core/CMakeLists.txt +++ b/arch/riscv/core/CMakeLists.txt @@ -28,6 +28,7 @@ zephyr_library_sources_ifdef(CONFIG_DEBUG_COREDUMP coredump.c) zephyr_library_sources_ifdef(CONFIG_IRQ_OFFLOAD irq_offload.c) zephyr_library_sources_ifdef(CONFIG_USE_ISR_WRAPPER isr.S) zephyr_library_sources_ifdef(CONFIG_RISCV_PMP pmp.c pmp.S) +zephyr_linker_sources_ifdef(CONFIG_RISCV_PMP ROM_SECTIONS pmp.ld) zephyr_library_sources_ifdef(CONFIG_THREAD_LOCAL_STORAGE tls.c) zephyr_library_sources_ifdef(CONFIG_USERSPACE userspace.S) zephyr_library_sources_ifdef(CONFIG_SEMIHOST semihost.c) diff --git a/arch/riscv/core/pmp.c b/arch/riscv/core/pmp.c index db5fd2b7e746..5e20970b0a55 100644 --- a/arch/riscv/core/pmp.c +++ b/arch/riscv/core/pmp.c @@ -617,6 +617,19 @@ void z_riscv_pmp_init(void) (size_t)__rom_region_size, pmp_addr, pmp_cfg, ARRAY_SIZE(pmp_addr)); + /* SoC-specific PMP regions defined via iterable sections */ + STRUCT_SECTION_FOREACH(pmp_soc_region, region) { + uintptr_t start = (uintptr_t)region->start; + size_t size = (uintptr_t)region->end - start; + + if (size > 0) { + set_pmp_entry(&index, region->perm | COND_CODE_1(CONFIG_PMP_NO_LOCK_GLOBAL, + (0x0), (PMP_L)), start, + size, pmp_addr, pmp_cfg, + ARRAY_SIZE(pmp_addr)); + } + } + #ifdef CONFIG_PMP_STACK_GUARD #ifdef CONFIG_MULTITHREADING /* diff --git a/arch/riscv/core/pmp.ld b/arch/riscv/core/pmp.ld new file mode 100644 index 000000000000..344091df78bf --- /dev/null +++ b/arch/riscv/core/pmp.ld @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2025 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +ITERABLE_SECTION_ROM(pmp_soc_region, Z_LINK_ITERABLE_SUBALIGN) diff --git a/arch/riscv/include/pmp.h b/arch/riscv/include/pmp.h index 8367342bb9bb..d541730ef103 100644 --- a/arch/riscv/include/pmp.h +++ b/arch/riscv/include/pmp.h @@ -7,6 +7,7 @@ #ifndef PMP_H_ #define PMP_H_ +#include #include #define PMPCFG_STRIDE (__riscv_xlen / 8) diff --git a/include/zephyr/arch/riscv/pmp.h b/include/zephyr/arch/riscv/pmp.h index df8debf8c109..8ced716b0b8d 100644 --- a/include/zephyr/arch/riscv/pmp.h +++ b/include/zephyr/arch/riscv/pmp.h @@ -8,6 +8,46 @@ #define ZEPHYR_INCLUDE_RISCV_PMP_H_ #include +#include + +/** + * @brief SoC-specific PMP region descriptor. + * + * SoCs can define additional memory regions that need PMP protection + * using the PMP_SOC_REGION_DEFINE macro. + * These regions are automatically collected via iterable sections and + * programmed into the PMP during initialization. + * + * Note: Uses start/end pointers instead of start/size to support regions + * defined by linker symbols where the size is not a compile-time constant. + */ +struct pmp_soc_region { + /** Start address of the region (must be aligned to PMP granularity) */ + const void *start; + /** End address of the region (exclusive) */ + const void *end; + /** PMP permission flags (PMP_R, PMP_W, PMP_X combinations) */ + uint8_t perm; +}; + +/** + * @brief Define a SoC-specific PMP region. + * + * This macro allows SoCs to register memory regions that require PMP + * protection. The regions are collected at link time and programmed + * during PMP initialization. + * + * @param name Unique identifier for this region + * @param _start Start address of the region (pointer or linker symbol) + * @param _end End address of the region (pointer or linker symbol, exclusive) + * @param _perm PMP permission flags (PMP_R | PMP_W | PMP_X) + */ +#define PMP_SOC_REGION_DEFINE(name, _start, _end, _perm) \ + static const STRUCT_SECTION_ITERABLE(pmp_soc_region, name) = { \ + .start = (const void *)(_start), \ + .end = (const void *)(_end), \ + .perm = (_perm), \ + } /** * @brief Change the memory protection (R/W/X) permissions for a defined region. From 78fddf083a68baccd67253b6940a13342c7e569a Mon Sep 17 00:00:00 2001 From: Sylvio Alves Date: Fri, 12 Dec 2025 14:11:39 -0300 Subject: [PATCH 1692/3659] dts: esp32c6: add SoC ROM memory region Add device tree node for ESP32-C6 SoC ROM at 0x40000000. This 320KB ROM contains libc and utility functions used by the application. PMP protection is configured separately via PMP_SOC_REGION_DEFINE in pmp_regions.c. Signed-off-by: Sylvio Alves --- dts/riscv/espressif/esp32c6/esp32c6_common.dtsi | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/dts/riscv/espressif/esp32c6/esp32c6_common.dtsi b/dts/riscv/espressif/esp32c6/esp32c6_common.dtsi index 0316228f6a32..727f712820c5 100644 --- a/dts/riscv/espressif/esp32c6/esp32c6_common.dtsi +++ b/dts/riscv/espressif/esp32c6/esp32c6_common.dtsi @@ -11,6 +11,7 @@ #include #include #include +#include / { #address-cells = <1>; @@ -94,6 +95,17 @@ compatible = "simple-bus"; ranges; + /* + * ESP32-C6 ROM region containing libc functions. + * PMP protection for this region is configured via + * PMP_SOC_REGION_DEFINE in pmp_regions.c + */ + soc_rom: memory@40000000 { + compatible = "zephyr,memory-region"; + reg = <0x40000000 DT_SIZE_K(320)>; + zephyr,memory-region = "SOC_ROM"; + }; + sramhp: memory@40800000 { compatible = "zephyr,memory-region", "mmio-sram"; reg = <0x40800000 DT_SIZE_K(512)>; From 52c9bd85caa49f93f8e8402da96d04992b5f822c Mon Sep 17 00:00:00 2001 From: Sylvio Alves Date: Fri, 12 Dec 2025 14:11:16 -0300 Subject: [PATCH 1693/3659] soc: esp32c6: add userspace linker support Add linker script support for CONFIG_USERSPACE: - MPU alignment macros for PMP granularity - User stacks section in noinit area - Application shared memory partitions - Kernel object sections (text, rom, data, priv-stacks) - ROM region size symbol for PMP configuration Signed-off-by: Sylvio Alves --- soc/espressif/esp32c6/default.ld | 51 +++++++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/soc/espressif/esp32c6/default.ld b/soc/espressif/esp32c6/default.ld index 6785a0c7ef0c..00cd6578d38f 100644 --- a/soc/espressif/esp32c6/default.ld +++ b/soc/espressif/esp32c6/default.ld @@ -31,6 +31,22 @@ user_sram_size = (user_sram_end - user_sram_org); #define RAMABLE_REGION sram0_0_seg #define ROMABLE_REGION FLASH +#ifdef CONFIG_RISCV_PMP + #define MPU_MIN_SIZE CONFIG_PMP_GRANULARITY + #define MPU_MIN_SIZE_ALIGN . = ALIGN(MPU_MIN_SIZE); + #if defined(CONFIG_MPU_REQUIRES_POWER_OF_TWO_ALIGNMENT) + #define MPU_ALIGN(region_size) \ + . = ALIGN(MPU_MIN_SIZE); \ + . = ALIGN(1 << LOG2CEIL(region_size)) + #else + #define MPU_ALIGN(region_size) \ + . = ALIGN(MPU_MIN_SIZE) + #endif +#else + #define MPU_MIN_SIZE_ALIGN + #define MPU_ALIGN(region_size) . = ALIGN(4) +#endif + #undef GROUP_DATA_LINK_IN #define GROUP_DATA_LINK_IN(vregion, lregion) > vregion AT > lregion @@ -695,6 +711,24 @@ SECTIONS #include #pragma pop_macro("GROUP_ROM_LINK_IN") + /* + * Userspace sections (app_smem, kobject_data) must be placed before .dram0.end + * so they are included in the DRAM segment that MCUboot loads to RAM. + * The MCUboot load header uses .dram0.end to calculate DRAM size. + */ +#if defined(CONFIG_USERSPACE) +#define APP_SHARED_ALIGN MPU_MIN_SIZE_ALIGN +#define SMEM_PARTITION_ALIGN MPU_ALIGN + +#include + + _app_smem_size = _app_smem_end - _app_smem_start; + _app_smem_rom_start = LOADADDR(_APP_SMEM_SECTION_NAME); +#endif /* CONFIG_USERSPACE */ + +#include +#include + .dram0.end : { . = ALIGN(4); @@ -707,12 +741,18 @@ SECTIONS . = ALIGN(4); *(.noinit) *(.noinit.*) +#ifdef CONFIG_USERSPACE + z_user_stacks_start = .; + *(.user_stacks*) + z_user_stacks_end = .; +#endif /* CONFIG_USERSPACE */ . = ALIGN(4); } GROUP_LINK_IN(RAMABLE_REGION) /* Shared RAM */ .dram0.bss (NOLOAD) : { + MPU_MIN_SIZE_ALIGN . = ALIGN (8); __bss_start = ABSOLUTE(.); _bss_start = ABSOLUTE(.); @@ -750,6 +790,9 @@ SECTIONS /* Provide total SRAM usage, including IRAM and DRAM */ _image_ram_start = _iram_start; + +#define LAST_RAM_ALIGN MPU_MIN_SIZE_ALIGN + #include ASSERT(((_end - ORIGIN(sram0_0_seg)) <= LENGTH(sram0_0_seg)), "SRAM code/data does not fit.") @@ -792,6 +835,7 @@ SECTIONS *(.literal .text .literal.* .text.*) *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) *(.irom0.text) /* catch stray ICACHE_RODATA_ATTR */ +#include *(.fini.literal) *(.fini) @@ -809,7 +853,10 @@ SECTIONS _text_end = ABSOLUTE(.); _instruction_reserved_end = ABSOLUTE(.); __text_region_end = ABSOLUTE(.); + /* Align for PMP granularity requirements */ + MPU_MIN_SIZE_ALIGN __rom_region_end = ABSOLUTE(.); + __rom_region_size = __rom_region_end - __rom_region_start; _etext = .; } GROUP_DATA_LINK_IN(FLASH_CODE_REGION, ROMABLE_REGION) @@ -864,7 +911,6 @@ SECTIONS *(.xt_except_desc_end) *(.dynamic) *(.gnu.version_d) - __rodata_region_end = .; _rodata_end = ABSOLUTE(.); /* Literals are also RO data. */ _lit4_start = ABSOLUTE(.); @@ -879,7 +925,9 @@ SECTIONS *(.rodata.*) *(.rodata_wlog) *(.rodata_wlog*) +#include . = ALIGN(4); + __rodata_region_end = .; } GROUP_DATA_LINK_IN(RODATA_REGION, ROMABLE_REGION) #include @@ -890,6 +938,7 @@ SECTIONS #include #include #include + #include #include #include From b75d67fb1f54104cfc9db57cd98fac50cc1c3192 Mon Sep 17 00:00:00 2001 From: Sylvio Alves Date: Fri, 12 Dec 2025 14:10:50 -0300 Subject: [PATCH 1694/3659] soc: esp32c6: enable PMP and define SoC regions Enable RISC-V PMP for ESP32-C6 and configure appropriate defaults: - 16 PMP slots available on hardware - Unlocked global entries for XIP flash execution - MEM_ATTR subsystem for device tree memory regions Define SoC-specific PMP regions: - SoC ROM (0x40000000): libc functions, R+X - IRAM text: interrupt handlers and critical code, R+X Signed-off-by: Sylvio Alves --- soc/espressif/common/Kconfig.flash | 5 +++- soc/espressif/esp32c6/CMakeLists.txt | 1 + soc/espressif/esp32c6/Kconfig | 1 + soc/espressif/esp32c6/Kconfig.defconfig | 10 +++++++ soc/espressif/esp32c6/pmp_regions.c | 39 +++++++++++++++++++++++++ 5 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 soc/espressif/esp32c6/pmp_regions.c diff --git a/soc/espressif/common/Kconfig.flash b/soc/espressif/common/Kconfig.flash index 0042d2844ac5..b4fb8b58a105 100644 --- a/soc/espressif/common/Kconfig.flash +++ b/soc/espressif/common/Kconfig.flash @@ -113,12 +113,15 @@ endchoice config BOOTLOADER_REGION_PROTECTION_ENABLE bool "Protect unmapped memory regions from unintended accesses" - default y + default y if !RISCV_PMP && !MCUBOOT help Protects the unmapped memory regions of the entire address space from unintended accesses. This will ensure that an exception will be triggered whenever the CPU performs a memory operation on unmapped regions of the address space. + Automatically disabled when RISCV_PMP is enabled since Zephyr manages PMP directly. + Also disabled for MCUboot builds since the bootloader handles its own region protection. + config SPI_FLASH_HPM_ENABLE bool depends on SOC_SERIES_ESP32S3 diff --git a/soc/espressif/esp32c6/CMakeLists.txt b/soc/espressif/esp32c6/CMakeLists.txt index 9101292b406a..90a58f083ad9 100644 --- a/soc/espressif/esp32c6/CMakeLists.txt +++ b/soc/espressif/esp32c6/CMakeLists.txt @@ -21,4 +21,5 @@ if(CONFIG_SOC_ESP32C6_HPCORE) zephyr_library_sources_ifdef(CONFIG_PM power.c) zephyr_library_sources_ifdef(CONFIG_POWEROFF poweroff.c) zephyr_sources_ifdef(CONFIG_ULP_COPROC_ENABLED hpcore_init_ulp.c) + zephyr_sources_ifdef(CONFIG_RISCV_PMP pmp_regions.c) endif() diff --git a/soc/espressif/esp32c6/Kconfig b/soc/espressif/esp32c6/Kconfig index 706bbc86ac9c..bb1b4a752392 100644 --- a/soc/espressif/esp32c6/Kconfig +++ b/soc/espressif/esp32c6/Kconfig @@ -4,6 +4,7 @@ config SOC_SERIES_ESP32C6 select RISCV select RISCV_SOC_HAS_GP_RELATIVE_ADDRESSING + select RISCV_PMP if SOC_ESP32C6_HPCORE && !MCUBOOT select DYNAMIC_INTERRUPTS if SOC_ESP32C6_HPCORE select CLOCK_CONTROL if SOC_ESP32C6_HPCORE select PINCTRL if SOC_ESP32C6_HPCORE diff --git a/soc/espressif/esp32c6/Kconfig.defconfig b/soc/espressif/esp32c6/Kconfig.defconfig index 35db1929818e..0d90f12e29d6 100644 --- a/soc/espressif/esp32c6/Kconfig.defconfig +++ b/soc/espressif/esp32c6/Kconfig.defconfig @@ -6,6 +6,16 @@ if SOC_SERIES_ESP32C6 config NUM_IRQS default 32 +config PMP_SLOTS + default 16 + +# ESP32-C6 uses MMU to map flash to virtual addresses for code execution. +# The PMP init code runs from IRAM while the main rom region is in flash. +# Locked PMP entries would block IRAM execution before proper coverage is set. +# Use unlocked entries with MPRV-based enforcement instead. +config PMP_NO_LOCK_GLOBAL + default y + config FLASH_SIZE default $(dt_node_reg_size_int,/soc/flash-controller@60002000/flash@0,0) diff --git a/soc/espressif/esp32c6/pmp_regions.c b/soc/espressif/esp32c6/pmp_regions.c new file mode 100644 index 000000000000..3bf554ffab37 --- /dev/null +++ b/soc/espressif/esp32c6/pmp_regions.c @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2025 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +/* + * ESP32-C6 SoC ROM region. + * + * The ESP32-C6 has a ROM at 0x40000000 containing libc and other utility + * functions. This region needs to be accessible (R+X) from both kernel + * and user mode for proper operation. + */ +#define SOC_ROM_NODE DT_NODELABEL(soc_rom) + +PMP_SOC_REGION_DEFINE(esp32c6_soc_rom, DT_REG_ADDR(SOC_ROM_NODE), + DT_REG_ADDR(SOC_ROM_NODE) + DT_REG_SIZE(SOC_ROM_NODE), PMP_R | PMP_X); + +/* + * ESP32-C6 IRAM text region. + * + * On ESP32-C6, IRAM and DRAM share the same 512KB physical memory space + * (0x40800000-0x40880000). The split between code (IRAM) and data (DRAM) + * is determined at link time. Only the IRAM text portion should be + * executable to maintain security - making the entire region executable + * would allow code execution from the data area. + * + * The linker symbols _iram_text_start and _iram_text_end define the + * actual IRAM text boundaries. + */ +extern char _iram_text_start[]; +extern char _iram_text_end[]; + +PMP_SOC_REGION_DEFINE(esp32c6_iram_text, _iram_text_start, _iram_text_end, PMP_R | PMP_X); From 8805de47b432a84e04c8f7b19f49fa60edf468f6 Mon Sep 17 00:00:00 2001 From: Sylvio Alves Date: Wed, 24 Dec 2025 10:11:15 -0300 Subject: [PATCH 1695/3659] tests: arch: riscv: add PMP SoC regions test Add test for PMP_SOC_REGION_DEFINE macro that allows SoCs to define custom PMP regions via iterable sections. The test verifies: - Regions defined with PMP_SOC_REGION_DEFINE are programmed into PMP registers during z_riscv_pmp_init() - SoC regions are placed in global PMP slots (first half of entries) - STRUCT_SECTION_FOREACH correctly iterates over defined regions Signed-off-by: Sylvio Alves --- .../pmp/pmp-custom-regions/CMakeLists.txt | 13 ++ .../riscv/pmp/pmp-custom-regions/prj.conf | 2 + .../riscv/pmp/pmp-custom-regions/src/main.c | 163 ++++++++++++++++++ .../pmp/pmp-custom-regions/testcase.yaml | 10 ++ 4 files changed, 188 insertions(+) create mode 100644 tests/arch/riscv/pmp/pmp-custom-regions/CMakeLists.txt create mode 100644 tests/arch/riscv/pmp/pmp-custom-regions/prj.conf create mode 100644 tests/arch/riscv/pmp/pmp-custom-regions/src/main.c create mode 100644 tests/arch/riscv/pmp/pmp-custom-regions/testcase.yaml diff --git a/tests/arch/riscv/pmp/pmp-custom-regions/CMakeLists.txt b/tests/arch/riscv/pmp/pmp-custom-regions/CMakeLists.txt new file mode 100644 index 000000000000..eab6b4afd8dc --- /dev/null +++ b/tests/arch/riscv/pmp/pmp-custom-regions/CMakeLists.txt @@ -0,0 +1,13 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(pmp_soc_regions) + +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources}) + +target_include_directories(app PRIVATE + ${ZEPHYR_BASE}/kernel/include + ${ZEPHYR_BASE}/arch/${ARCH}/include + ) diff --git a/tests/arch/riscv/pmp/pmp-custom-regions/prj.conf b/tests/arch/riscv/pmp/pmp-custom-regions/prj.conf new file mode 100644 index 000000000000..193ae25c5162 --- /dev/null +++ b/tests/arch/riscv/pmp/pmp-custom-regions/prj.conf @@ -0,0 +1,2 @@ +CONFIG_ZTEST=y +CONFIG_RISCV_PMP=y diff --git a/tests/arch/riscv/pmp/pmp-custom-regions/src/main.c b/tests/arch/riscv/pmp/pmp-custom-regions/src/main.c new file mode 100644 index 000000000000..26096c099172 --- /dev/null +++ b/tests/arch/riscv/pmp/pmp-custom-regions/src/main.c @@ -0,0 +1,163 @@ +/* + * Copyright (c) 2025 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +/* + * Test regions defined using PMP_SOC_REGION_DEFINE macro. + * These will be collected via iterable sections and programmed + * into PMP during z_riscv_pmp_init(). + * + * Use addresses from QEMU flash region (0x20000000-0x24000000) + */ +#define TEST_REGION1_ADDR 0x20010000UL +#define TEST_REGION1_SIZE 0x1000UL +#define TEST_REGION1_PERM (PMP_R | PMP_X) + +#define TEST_REGION2_ADDR 0x20020000UL +#define TEST_REGION2_SIZE 0x2000UL +#define TEST_REGION2_PERM (PMP_R | PMP_W) + +PMP_SOC_REGION_DEFINE(test_region1, TEST_REGION1_ADDR, TEST_REGION1_ADDR + TEST_REGION1_SIZE, + TEST_REGION1_PERM); + +PMP_SOC_REGION_DEFINE(test_region2, TEST_REGION2_ADDR, TEST_REGION2_ADDR + TEST_REGION2_SIZE, + TEST_REGION2_PERM); + +struct expected_region { + uintptr_t base; + size_t size; + uint8_t perm; + bool found; +}; + +static struct expected_region expected_regions[] = { + { + .base = TEST_REGION1_ADDR, + .size = TEST_REGION1_SIZE, + .perm = TEST_REGION1_PERM, + .found = false, + }, + { + .base = TEST_REGION2_ADDR, + .size = TEST_REGION2_SIZE, + .perm = TEST_REGION2_PERM, + .found = false, + }, +}; + +ZTEST(riscv_pmp_soc_regions, test_soc_regions_configured) +{ + const size_t num_pmpcfg_regs = CONFIG_PMP_SLOTS / sizeof(unsigned long); + const size_t num_pmpaddr_regs = CONFIG_PMP_SLOTS; + + unsigned long current_pmpcfg_regs[num_pmpcfg_regs]; + unsigned long current_pmpaddr_regs[num_pmpaddr_regs]; + + z_riscv_pmp_read_config(current_pmpcfg_regs, num_pmpcfg_regs); + z_riscv_pmp_read_addr(current_pmpaddr_regs, num_pmpaddr_regs); + + const uint8_t *const cfg_entries = (const uint8_t *)current_pmpcfg_regs; + + for (size_t i = 0; i < ARRAY_SIZE(expected_regions); ++i) { + expected_regions[i].found = false; + } + + for (unsigned int index = 0; index < CONFIG_PMP_SLOTS; ++index) { + unsigned long start, end; + uint8_t cfg_byte = cfg_entries[index]; + + if ((cfg_byte & PMP_A) == 0) { + continue; + } + + pmp_decode_region(cfg_byte, current_pmpaddr_regs, index, &start, &end); + + for (size_t i = 0; i < ARRAY_SIZE(expected_regions); ++i) { + if ((start == expected_regions[i].base) && + (end == expected_regions[i].base + expected_regions[i].size - 1) && + ((cfg_byte & 0x07) == expected_regions[i].perm)) { + expected_regions[i].found = true; + break; + } + } + } + + for (size_t i = 0; i < ARRAY_SIZE(expected_regions); i++) { + zassert_true(expected_regions[i].found, + "SoC region %zu (base 0x%lx, size 0x%zx, perm 0x%x) " + "not found in PMP registers", + i, expected_regions[i].base, expected_regions[i].size, + expected_regions[i].perm); + } +} + +ZTEST(riscv_pmp_soc_regions, test_soc_regions_are_global) +{ + const size_t num_pmpcfg_regs = CONFIG_PMP_SLOTS / sizeof(unsigned long); + const size_t num_pmpaddr_regs = CONFIG_PMP_SLOTS; + + unsigned long current_pmpcfg_regs[num_pmpcfg_regs]; + unsigned long current_pmpaddr_regs[num_pmpaddr_regs]; + + z_riscv_pmp_read_config(current_pmpcfg_regs, num_pmpcfg_regs); + z_riscv_pmp_read_addr(current_pmpaddr_regs, num_pmpaddr_regs); + + const uint8_t *const cfg_entries = (const uint8_t *)current_pmpcfg_regs; + + unsigned int region1_index = CONFIG_PMP_SLOTS; + + for (unsigned int index = 0; index < CONFIG_PMP_SLOTS; ++index) { + unsigned long start, end; + uint8_t cfg_byte = cfg_entries[index]; + + if ((cfg_byte & PMP_A) == 0) { + continue; + } + + pmp_decode_region(cfg_byte, current_pmpaddr_regs, index, &start, &end); + + if (start == TEST_REGION1_ADDR) { + region1_index = index; + break; + } + } + + zassert_true(region1_index < CONFIG_PMP_SLOTS, "Test region 1 not found in PMP entries"); + + zassert_true(region1_index < CONFIG_PMP_SLOTS / 2, + "SoC region appears too late in PMP entries (index %u), " + "may not be a global entry", + region1_index); +} + +ZTEST(riscv_pmp_soc_regions, test_iterable_section) +{ + size_t count; + const struct pmp_soc_region *region; + + STRUCT_SECTION_COUNT(pmp_soc_region, &count); + zassert_true(count >= 2, "Expected at least 2 regions, found %zu", count); + + STRUCT_SECTION_GET(pmp_soc_region, 0, ®ion); + zassert_equal((uintptr_t)region->start, TEST_REGION1_ADDR, + "Region1 start address mismatch"); + zassert_equal((uintptr_t)region->end, TEST_REGION1_ADDR + TEST_REGION1_SIZE, + "Region1 end address mismatch"); + zassert_equal(region->perm, TEST_REGION1_PERM, "Region1 permission mismatch"); + + STRUCT_SECTION_GET(pmp_soc_region, 1, ®ion); + zassert_equal((uintptr_t)region->start, TEST_REGION2_ADDR, + "Region2 start address mismatch"); + zassert_equal((uintptr_t)region->end, TEST_REGION2_ADDR + TEST_REGION2_SIZE, + "Region2 end address mismatch"); + zassert_equal(region->perm, TEST_REGION2_PERM, "Region2 permission mismatch"); +} + +ZTEST_SUITE(riscv_pmp_soc_regions, NULL, NULL, NULL, NULL, NULL); diff --git a/tests/arch/riscv/pmp/pmp-custom-regions/testcase.yaml b/tests/arch/riscv/pmp/pmp-custom-regions/testcase.yaml new file mode 100644 index 000000000000..10b26f4d8f06 --- /dev/null +++ b/tests/arch/riscv/pmp/pmp-custom-regions/testcase.yaml @@ -0,0 +1,10 @@ +common: + platform_allow: + - qemu_riscv32 + - qemu_riscv64 + filter: CONFIG_RISCV_PMP + tags: pmp + +tests: + arch.riscv.pmp.soc_regions: + harness: ztest From 1c6d0c0c2e197519d5a23bdb977cf74c3769eab4 Mon Sep 17 00:00:00 2001 From: Ajay Neeli Date: Thu, 1 Jan 2026 17:04:08 +0530 Subject: [PATCH 1696/3659] MAINTAINERS: add neeliajay as Xilinx collaborator Add neeliajay (Ajay Neeli) as a collaborator for "Xilinx Platforms" Signed-off-by: Ajay Neeli --- MAINTAINERS.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index 4cd97634fa1c..b3fd9ab2748d 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -6363,6 +6363,7 @@ Xilinx Platforms: - henrikbrixandersen - ibirnbaum - kedareswararao + - neeliajay files: - boards/amd/ - drivers/*/*xilinx* From 517cd3e5c6233fb0ef92e5c94a65d13fed40cf00 Mon Sep 17 00:00:00 2001 From: Mathieu Choplain Date: Fri, 9 Jan 2026 15:13:46 +0100 Subject: [PATCH 1697/3659] dts: arm: st: n6: fix reg property of NPU The reg property on the NPU node indicated a base address of 0x580C0000 and size of 4 KiB, neither of which are correct (in fact, this base address is the one of the OTGPHYC2). Set the reg property to the correct values: the NPU instance is mapped at 0x580E0000 and occupies 128 KiB of address space. Signed-off-by: Mathieu Choplain --- dts/arm/st/n6/stm32n6.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dts/arm/st/n6/stm32n6.dtsi b/dts/arm/st/n6/stm32n6.dtsi index cc1c95c229e0..a35feffa0e93 100644 --- a/dts/arm/st/n6/stm32n6.dtsi +++ b/dts/arm/st/n6/stm32n6.dtsi @@ -1335,9 +1335,9 @@ status = "disabled"; }; - npu: npu@580c0000 { + npu: npu@580e0000 { compatible = "st,stm32-npu"; - reg = <0x580c0000 0x1000>; + reg = <0x580e0000 DT_SIZE_K(128)>; clocks = <&rcc STM32_CLOCK(AHB5, 31)>, <&rcc STM32_CLOCK(AHB5, 30)>; clock-names = "npu", "cacheaxi"; From f3deb7bed79671ff4a468aa4ccfea10fbf8b43cf Mon Sep 17 00:00:00 2001 From: Sylvio Alves Date: Fri, 9 Jan 2026 11:33:47 -0300 Subject: [PATCH 1698/3659] kernel: nothread: fix build when CONFIG_SYS_CLOCK_EXISTS=n The k_timer API requires CONFIG_SYS_CLOCK_EXISTS to be enabled, as timer.c is only compiled when this config is set. Guard the timer-based k_sleep() implementation and fall back to the previous busy-wait approach when no system clock exists. Signed-off-by: Sylvio Alves --- kernel/nothread.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/kernel/nothread.c b/kernel/nothread.c index 02876c69f2b8..a01d42d77094 100644 --- a/kernel/nothread.c +++ b/kernel/nothread.c @@ -14,7 +14,9 @@ bool k_is_in_isr(void) return arch_is_in_isr(); } +#ifdef CONFIG_SYS_CLOCK_EXISTS static K_TIMER_DEFINE(sleep_timer, NULL, NULL); +#endif /* This is a fallback implementation of k_sleep() for when multi-threading is * disabled. The main implementation is in sched.c. @@ -34,6 +36,7 @@ int32_t z_impl_k_sleep(k_timeout_t timeout) return (int32_t) K_TICKS_FOREVER; } +#ifdef CONFIG_SYS_CLOCK_EXISTS k_timer_start(&sleep_timer, timeout, K_NO_WAIT); /* When multithreading is disabled, this will enter a low power state @@ -48,4 +51,33 @@ int32_t z_impl_k_sleep(k_timeout_t timeout) * sleep for the entire timeout duration (no thread to awake). */ return 0; +#else + /* Fallback to busy-wait when no system clock is available */ + k_ticks_t ticks; + uint32_t ticks_to_wait; + + ticks = timeout.ticks; + if (Z_IS_TIMEOUT_RELATIVE(timeout)) { + /* ticks is delta timeout */ + ticks_to_wait = ticks; + } else { + /* ticks is absolute timeout expiration */ + uint32_t curr_ticks = sys_clock_tick_get_32(); + + if (Z_TICK_ABS(ticks) > curr_ticks) { + ticks_to_wait = Z_TICK_ABS(ticks) - curr_ticks; + } else { + ticks_to_wait = 0; + } + } + + /* busy wait to be time coherent since subsystems may depend on it */ + z_impl_k_busy_wait(k_ticks_to_us_ceil32(ticks_to_wait)); + + int32_t ret = k_ticks_to_ms_ceil64(0); + + SYS_PORT_TRACING_FUNC_EXIT(k_thread, sleep, timeout, ret); + + return ret; +#endif } From bb9616c0cd9246c9ed40b743856e8f5afeb0d96d Mon Sep 17 00:00:00 2001 From: Andreas Huber Date: Fri, 9 Jan 2026 16:27:47 +0100 Subject: [PATCH 1699/3659] net: arp: Choose IP corresponding to the same network If we have more than one IP on an interface we should choose the IP corresponding to the same network as the target IP. Signed-off-by: Andreas Huber --- subsys/net/l2/ethernet/arp.c | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/subsys/net/l2/ethernet/arp.c b/subsys/net/l2/ethernet/arp.c index 304994f2e7b5..fb810f0ea30b 100644 --- a/subsys/net/l2/ethernet/arp.c +++ b/subsys/net/l2/ethernet/arp.c @@ -228,10 +228,19 @@ static void arp_request_timeout(struct k_work *work) k_mutex_unlock(&arp_mutex); } +static inline bool is_same_subnet(uint32_t addr1, + uint32_t addr2, + uint32_t netmask) +{ + return ((addr1 & netmask) == (addr2 & netmask)); +} + static inline struct net_in_addr *if_get_addr(struct net_if *iface, - const uint8_t *addr) + const uint8_t *own_addr, + const struct net_in_addr *dst_addr) { struct net_if_ipv4 *ipv4 = iface->config.ip.ipv4; + struct net_in_addr *fall_back = NULL; if (!ipv4) { return NULL; @@ -241,14 +250,23 @@ static inline struct net_in_addr *if_get_addr(struct net_if *iface, if (ipv4->unicast[i].ipv4.is_used && ipv4->unicast[i].ipv4.address.family == NET_AF_INET && ipv4->unicast[i].ipv4.addr_state == NET_ADDR_PREFERRED && - (!addr || + ((own_addr == NULL) || net_ipv4_addr_cmp_raw( - addr, ipv4->unicast[i].ipv4.address.in_addr.s4_addr))) { - return &ipv4->unicast[i].ipv4.address.in_addr; + own_addr, ipv4->unicast[i].ipv4.address.in_addr.s4_addr))) { + if ((dst_addr == NULL) || + is_same_subnet(dst_addr->s_addr, + ipv4->unicast[i].ipv4.address.in_addr.s_addr, + ipv4->unicast[i].netmask.s_addr)) { + /* Use preferred address on the same subnet as destination */ + return &ipv4->unicast[i].ipv4.address.in_addr; + } else if (fall_back == NULL) { + /* Use address as fallback, if no match for subnet is found */ + fall_back = &ipv4->unicast[i].ipv4.address.in_addr; + } } } - return NULL; + return fall_back; } static inline struct net_pkt *arp_prepare(struct net_if *iface, @@ -339,7 +357,7 @@ static inline struct net_pkt *arp_prepare(struct net_if *iface, } else if (!entry) { my_addr = (struct net_in_addr *)NET_IPV4_HDR(pending)->src; } else { - my_addr = if_get_addr(entry->iface, (const uint8_t *)current_ip); + my_addr = if_get_addr(entry->iface, (const uint8_t *)current_ip, next_addr); } if (my_addr) { @@ -852,7 +870,7 @@ enum net_verdict net_arp_input(struct net_pkt *pkt, } /* Someone wants to know our ll address */ - addr = if_get_addr(net_pkt_iface(pkt), arp_hdr->dst_ipaddr); + addr = if_get_addr(net_pkt_iface(pkt), arp_hdr->dst_ipaddr, NULL); if (!addr) { /* Not for us so drop the packet silently */ return NET_DROP; From f331614bacf709296af4d6b884bc271378ecbb49 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Fri, 9 Jan 2026 16:51:27 +0100 Subject: [PATCH 1700/3659] net: lib: websocket: remove usage of legacy Mbed TLS crypto Remove optional use of legacy Mbed TLS crypto in favor of the already existing PSA Crypto API alternative. This is required in order to jump to the next version of Mbed TLS (i.e. 4.0) where all this legacy crypto support is no more available. Signed-off-by: Valerio Setti --- subsys/net/lib/websocket/Kconfig | 4 +-- subsys/net/lib/websocket/websocket.c | 25 ------------------- subsys/net/lib/websocket/websocket_internal.h | 3 ++- 3 files changed, 4 insertions(+), 28 deletions(-) diff --git a/subsys/net/lib/websocket/Kconfig b/subsys/net/lib/websocket/Kconfig index 457cbc0c42b5..9502ce0f2dc4 100644 --- a/subsys/net/lib/websocket/Kconfig +++ b/subsys/net/lib/websocket/Kconfig @@ -7,9 +7,9 @@ config WEBSOCKET_CLIENT select HTTP_PARSER select HTTP_PARSER_URL select HTTP_CLIENT - select MBEDTLS select BASE64 - select MBEDTLS_SHA1 if MBEDTLS_BUILTIN + select PSA_CRYPTO + select PSA_WANT_ALG_SHA_256 select EXPERIMENTAL help Enable Websocket client library. diff --git a/subsys/net/lib/websocket/websocket.c b/subsys/net/lib/websocket/websocket.c index fdcd9fe2c85a..ca5ed2f00dbd 100644 --- a/subsys/net/lib/websocket/websocket.c +++ b/subsys/net/lib/websocket/websocket.c @@ -30,11 +30,7 @@ LOG_MODULE_REGISTER(net_websocket, CONFIG_NET_WEBSOCKET_LOG_LEVEL); #include #include -#ifdef CONFIG_MBEDTLS_PSA_CRYPTO_CLIENT #include -#else -#include -#endif /* CONFIG_MBEDTLS_PSA_CRYPTO_CLIENT */ #include "net_private.h" #include "sockets_internal.h" @@ -253,10 +249,8 @@ int websocket_connect(int sock, struct websocket_request *wreq, "Sec-WebSocket-Version: 13\r\n", NULL }; -#ifdef CONFIG_MBEDTLS_PSA_CRYPTO_CLIENT psa_status_t psa_status; size_t hash_length; -#endif /* CONFIG_MBEDTLS_PSA_CRYPTO_CLIENT */ fd = -1; @@ -284,7 +278,6 @@ int websocket_connect(int sock, struct websocket_request *wreq, ctx->http_cb = wreq->http_cb; ctx->is_client = 1; -#ifdef CONFIG_MBEDTLS_PSA_CRYPTO_CLIENT psa_status = psa_hash_compute(PSA_ALG_SHA_1, (const uint8_t *)&rnd_value, sizeof(rnd_value), sec_accept_key, sizeof(sec_accept_key), &hash_length); if (psa_status != PSA_SUCCESS) { @@ -292,15 +285,6 @@ int websocket_connect(int sock, struct websocket_request *wreq, ret = -EPROTO; goto out; } -#else - ret = mbedtls_sha1((const unsigned char *)&rnd_value, sizeof(rnd_value), sec_accept_key); - if (ret != 0) { - NET_DBG("[%p] Cannot calculate sha1 (%d)", ctx, ret); - ret = -EPROTO; - goto out; - } -#endif /* CONFIG_MBEDTLS_PSA_CRYPTO_CLIENT */ - ret = base64_encode(sec_ws_key + sizeof("Sec-Websocket-Key: ") - 1, sizeof(sec_ws_key) - @@ -363,7 +347,6 @@ int websocket_connect(int sock, struct websocket_request *wreq, memcpy(key_accept + key_len, WS_MAGIC, olen); /* This SHA-1 value is then checked when we receive the response */ -#ifdef CONFIG_MBEDTLS_PSA_CRYPTO_CLIENT psa_status = psa_hash_compute(PSA_ALG_SHA_1, (const uint8_t *)key_accept, olen + key_len, sec_accept_key, sizeof(sec_accept_key), &hash_length); if (psa_status != PSA_SUCCESS) { @@ -371,14 +354,6 @@ int websocket_connect(int sock, struct websocket_request *wreq, ret = -EPROTO; goto out; } -#else - ret = mbedtls_sha1(key_accept, olen + key_len, sec_accept_key); - if (ret != 0) { - NET_DBG("[%p] Cannot calculate sha1 (%d)", ctx, ret); - ret = -EPROTO; - goto out; - } -#endif /* CONFIG_MBEDTLS_PSA_CRYPTO_CLIENT */ ret = http_client_req(sock, &req, timeout, ctx); if (ret < 0) { diff --git a/subsys/net/lib/websocket/websocket_internal.h b/subsys/net/lib/websocket/websocket_internal.h index 50f2fee37973..09a48d569592 100644 --- a/subsys/net/lib/websocket/websocket_internal.h +++ b/subsys/net/lib/websocket/websocket_internal.h @@ -11,8 +11,9 @@ */ #include +#include -#define WS_SHA1_OUTPUT_LEN 20 +#define WS_SHA1_OUTPUT_LEN PSA_HASH_LENGTH(PSA_ALG_SHA_1) /* Min Websocket header length */ #define MIN_HEADER_LEN 2 From 63cfa56bbb4764d72225441b76df6c76f660ad33 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Fri, 9 Jan 2026 17:21:30 +0100 Subject: [PATCH 1701/3659] net: lib: http: http_server: replace usage of legacy Mbed TLS crypto Use PSA Crypto API for SHA-1 computation instead of legacy Mbed TLS crypto. The latter is going to be removed soon. Signed-off-by: Valerio Setti --- subsys/net/lib/http/http_server_ws.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/subsys/net/lib/http/http_server_ws.c b/subsys/net/lib/http/http_server_ws.c index 6d6c2f702a9f..d87599d876fb 100644 --- a/subsys/net/lib/http/http_server_ws.c +++ b/subsys/net/lib/http/http_server_ws.c @@ -17,6 +17,7 @@ #include #include #include +#include LOG_MODULE_DECLARE(net_http_server, CONFIG_NET_HTTP_SERVER_LOG_LEVEL); @@ -40,6 +41,7 @@ int handle_http1_to_websocket_upgrade(struct http_client_ctx *client) "Sec-WebSocket-Accept: "; char key_accept[HTTP_SERVER_WS_MAX_SEC_KEY_LEN + sizeof(WS_MAGIC)]; char accept[20]; + size_t accept_len; char tmp[64]; size_t key_len; size_t olen; @@ -52,7 +54,8 @@ int handle_http1_to_websocket_upgrade(struct http_client_ctx *client) olen = MIN(sizeof(key_accept) - 1 - key_len, sizeof(WS_MAGIC) - 1); memcpy(key_accept + key_len, WS_MAGIC, olen); - mbedtls_sha1(key_accept, olen + key_len, accept); + psa_hash_compute(PSA_ALG_SHA_1, key_accept, olen + key_len, + accept, sizeof(accept), &accept_len); ret = base64_encode(tmp, sizeof(tmp) - 1, &olen, accept, sizeof(accept)); if (ret) { From c5dd4c7a0bf0213e2ab633f4049928a337e394be Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Mon, 12 Jan 2026 10:14:48 +0100 Subject: [PATCH 1702/3659] net: lib: shell: make header file inclusion conditional Include "websocket/websocket_internal.h" only when CONFIG_WEBSOCKET_CLIENT is also enabled. Signed-off-by: Valerio Setti --- subsys/net/lib/shell/websocket.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/subsys/net/lib/shell/websocket.c b/subsys/net/lib/shell/websocket.c index 61458c0a2296..771ad199f39c 100644 --- a/subsys/net/lib/shell/websocket.c +++ b/subsys/net/lib/shell/websocket.c @@ -14,11 +14,12 @@ LOG_MODULE_DECLARE(net_shell); #include "net_shell_private.h" -#include "websocket/websocket_internal.h" - #include #if defined(CONFIG_WEBSOCKET_CLIENT) + +#include "websocket/websocket_internal.h" + static void websocket_context_cb(struct websocket_context *context, void *user_data) { From 90abc8083deb58db52079dd6fe903bd8f08af439 Mon Sep 17 00:00:00 2001 From: Andrei Smirnou Date: Thu, 28 Nov 2024 16:46:46 +0000 Subject: [PATCH 1703/3659] board: adi: eval_adin2111d1z - Add ADIN2111D1Z board support - Added documentation for eval_adin2111d1z - Added regulator for the bypass relay Co-authored-by: Andrei Smirnou Co-authored-by: Jules Rouillard Signed-off-by: Andrei Smirnou --- .../Kconfig.adi_eval_adin2111d1z | 7 + boards/adi/eval_adin2111d1z/Kconfig.defconfig | 30 +++ .../adi_eval_adin2111d1z_max32690_m4.dts | 193 ++++++++++++++++ .../adi_eval_adin2111d1z_max32690_m4.yaml | 15 ++ ...adi_eval_adin2111d1z_max32690_m4_defconfig | 21 ++ boards/adi/eval_adin2111d1z/board.cmake | 8 + boards/adi/eval_adin2111d1z/board.yml | 9 + .../doc/img/adi_eval_adin2111d1z.webp | Bin 0 -> 100680 bytes boards/adi/eval_adin2111d1z/doc/index.rst | 218 ++++++++++++++++++ 9 files changed, 501 insertions(+) create mode 100644 boards/adi/eval_adin2111d1z/Kconfig.adi_eval_adin2111d1z create mode 100644 boards/adi/eval_adin2111d1z/Kconfig.defconfig create mode 100644 boards/adi/eval_adin2111d1z/adi_eval_adin2111d1z_max32690_m4.dts create mode 100644 boards/adi/eval_adin2111d1z/adi_eval_adin2111d1z_max32690_m4.yaml create mode 100644 boards/adi/eval_adin2111d1z/adi_eval_adin2111d1z_max32690_m4_defconfig create mode 100644 boards/adi/eval_adin2111d1z/board.cmake create mode 100644 boards/adi/eval_adin2111d1z/board.yml create mode 100644 boards/adi/eval_adin2111d1z/doc/img/adi_eval_adin2111d1z.webp create mode 100644 boards/adi/eval_adin2111d1z/doc/index.rst diff --git a/boards/adi/eval_adin2111d1z/Kconfig.adi_eval_adin2111d1z b/boards/adi/eval_adin2111d1z/Kconfig.adi_eval_adin2111d1z new file mode 100644 index 000000000000..4a46363ecb72 --- /dev/null +++ b/boards/adi/eval_adin2111d1z/Kconfig.adi_eval_adin2111d1z @@ -0,0 +1,7 @@ +# EVAL ADIN2111D1Z board configuration + +# Copyright (c) 2023-2024 Analog Devices, Inc. +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_ADI_EVAL_ADIN2111D1Z + select SOC_MAX32690_M4 diff --git a/boards/adi/eval_adin2111d1z/Kconfig.defconfig b/boards/adi/eval_adin2111d1z/Kconfig.defconfig new file mode 100644 index 000000000000..576d056d30f9 --- /dev/null +++ b/boards/adi/eval_adin2111d1z/Kconfig.defconfig @@ -0,0 +1,30 @@ +# ADI EVAL-ADIN2111D1Z board configuration + +# Copyright (c) 2024 BayLibre +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_ADI_EVAL_ADIN2111D1Z + +config MDIO_INIT_PRIORITY + default 81 + depends on MDIO + +config PHY_INIT_PRIORITY + default 82 + depends on NET_L2_ETHERNET && ETH_DRIVER + +if NETWORKING + +config NET_L2_ETHERNET + default y + +if ETH_ADIN2111 + +config NET_IF_MAX_IPV4_COUNT + default 2 + +endif # ETH_ADIN2111 + +endif # NETWORKING + +endif # BOARD_ADI_EVAL_ADIN2111D1Z diff --git a/boards/adi/eval_adin2111d1z/adi_eval_adin2111d1z_max32690_m4.dts b/boards/adi/eval_adin2111d1z/adi_eval_adin2111d1z_max32690_m4.dts new file mode 100644 index 000000000000..61dbacef9b55 --- /dev/null +++ b/boards/adi/eval_adin2111d1z/adi_eval_adin2111d1z_max32690_m4.dts @@ -0,0 +1,193 @@ +/* + * Copyright (c) 2023-2024 Analog Devices, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include +#include +#include + +/ { + model = "Analog Devices EVAL_ADIN2111D1Z"; + compatible = "adi,eval-adin2111d1z"; + + chosen { + zephyr,console = &uart0; + zephyr,shell-uart = &uart0; + zephyr,sram = &sram0; + zephyr,flash = &flash0; + zephyr,code-partition = &code_partition; + }; + + bypass_relay: bypass_relay_uc { + compatible = "regulator-fixed"; + regulator-name = "bypass_relay"; + enable-gpios = <&gpio0 23 GPIO_ACTIVE_HIGH>; + regulator-boot-on; + }; + + leds { + compatible = "gpio-leds"; + + orange_led: led_0 { + gpios = <&gpio0 14 GPIO_ACTIVE_LOW>; + label = "LED0"; + }; + + green_led: led_1 { + gpios = <&gpio2 22 GPIO_ACTIVE_LOW>; + label = "LED1"; + }; + + red_led: led_2 { + gpios = <&gpio2 23 GPIO_ACTIVE_LOW>; + label = "LED2"; + }; + }; + + buttons { + compatible = "gpio-keys"; + + pb0: pb0 { + gpios = <&gpio4 0 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "SW2"; + zephyr,code = ; + }; + }; + + aliases { + bypassuc = &bypass_relay; + led0 = &orange_led; + led1 = &green_led; + led2 = &red_led; + sw0 = &pb0; + }; +}; + +&clk_ipo { + status = "okay"; +}; + +&clk_ibro { + status = "okay"; +}; + +&gpio0 { + status = "okay"; +}; + +&gpio1 { + status = "okay"; +}; + +&gpio2 { + status = "okay"; +}; + +&gpio3 { + status = "okay"; +}; + +&gpio4 { + status = "okay"; +}; + +&i2c0 { + pinctrl-0 = <&i2c0a_sda_p2_7 &i2c0a_scl_p2_8>; + pinctrl-names = "default"; + status = "okay"; +}; + +&uart0 { /*USB-C P4*/ + clock-source = ; + pinctrl-0 = <&uart0a_tx_p2_12 &uart0a_rx_p2_11>; + pinctrl-names = "default"; + current-speed = <115200>; + data-bits = <8>; + parity = "none"; + status = "okay"; +}; + +&spi0b_miso_p2_27 { + power-source = ; +}; + +&spi0b_mosi_p2_28 { + power-source = ; +}; + +&spi0b_sck_p2_29 { + power-source = ; +}; + +&spi0b_ss1_p2_26 { + power-source = ; +}; + +&spi0 { + pinctrl-0 = <&spi0b_miso_p2_27 &spi0b_mosi_p2_28 &spi0b_sck_p2_29>; + pinctrl-names = "default"; + cs-gpios = <&gpio2 26 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + status = "okay"; + + adin2111: adin2111@0 { + compatible = "adi,adin2111"; + reg = <0x0>; + spi-max-frequency = ; + int-gpios = <&gpio2 25 (GPIO_ACTIVE_LOW | MAX32_GPIO_VSEL_VDDIOH)>; + status = "okay"; + spi-oa; + spi-oa-protection; + + port1 { + local-mac-address = [00 aa 22 fe da c8]; + status = "okay"; + }; + + port2 { + local-mac-address = [00 aa 22 fe da c8]; + status = "okay"; + }; + + mdio { + compatible = "adi,adin2111-mdio"; + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + ethernet-phy@1 { + reg = <0x1>; + compatible = "adi,adin2111-phy"; + status = "okay"; + }; + + ethernet-phy@2 { + reg = <0x2>; + compatible = "adi,adin2111-phy"; + status = "okay"; + }; + }; + }; +}; + +&flash0 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + code_partition: partition@0 { + label = "image"; + reg = <0x0 DT_SIZE_M(1)>; + }; + + storage_partition: partition@100000 { + label = "storage_partition"; + reg = <0x100000 DT_SIZE_K(256)>; + }; + }; +}; diff --git a/boards/adi/eval_adin2111d1z/adi_eval_adin2111d1z_max32690_m4.yaml b/boards/adi/eval_adin2111d1z/adi_eval_adin2111d1z_max32690_m4.yaml new file mode 100644 index 000000000000..9a5440723614 --- /dev/null +++ b/boards/adi/eval_adin2111d1z/adi_eval_adin2111d1z_max32690_m4.yaml @@ -0,0 +1,15 @@ +identifier: adi_eval_adin2111d1z/max32690/m4 +name: ADI EVAL-ADIN2111D1Z evaulation board +type: mcu +arch: arm +vendor: adi +toolchain: + - zephyr + - gnuarmemb +supported: + - gpio + - serial + - spi + - i2c +ram: 1024 +flash: 3072 diff --git a/boards/adi/eval_adin2111d1z/adi_eval_adin2111d1z_max32690_m4_defconfig b/boards/adi/eval_adin2111d1z/adi_eval_adin2111d1z_max32690_m4_defconfig new file mode 100644 index 000000000000..d8802ba24c00 --- /dev/null +++ b/boards/adi/eval_adin2111d1z/adi_eval_adin2111d1z_max32690_m4_defconfig @@ -0,0 +1,21 @@ +# Copyright (c) 2023-2024 Analog Devices, Inc. +# SPDX-License-Identifier: Apache-2.0 + +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable GPIO +CONFIG_GPIO=y + +# Console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# Enable UART +CONFIG_SERIAL=y +CONFIG_UART_INTERRUPT_DRIVEN=y + +# Enable regulators +CONFIG_REGULATOR=y + +CONFIG_USE_DT_CODE_PARTITION=y diff --git a/boards/adi/eval_adin2111d1z/board.cmake b/boards/adi/eval_adin2111d1z/board.cmake new file mode 100644 index 000000000000..43b3efb7b59f --- /dev/null +++ b/boards/adi/eval_adin2111d1z/board.cmake @@ -0,0 +1,8 @@ +# Copyright (c) 2023-2024 Analog Devices, Inc. +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(jlink "--device=MAX32690" "--reset-after-load") + +include(${ZEPHYR_BASE}/boards/common/openocd-adi-max32.boards.cmake) +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/adi/eval_adin2111d1z/board.yml b/boards/adi/eval_adin2111d1z/board.yml new file mode 100644 index 000000000000..c7c1ceb5cb5d --- /dev/null +++ b/boards/adi/eval_adin2111d1z/board.yml @@ -0,0 +1,9 @@ +# Copyright (c) 2023-2024 Analog Devices, Inc. +# SPDX-License-Identifier: Apache-2.0 + +board: + name: adi_eval_adin2111d1z + full_name: EVAL-ADIN2111D1Z + vendor: adi + socs: + - name: max32690 diff --git a/boards/adi/eval_adin2111d1z/doc/img/adi_eval_adin2111d1z.webp b/boards/adi/eval_adin2111d1z/doc/img/adi_eval_adin2111d1z.webp new file mode 100644 index 0000000000000000000000000000000000000000..6812065532a369bdb70f8313ae1c731fd0eadb14 GIT binary patch literal 100680 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 Qzv3v~7lKZGnt(t5*{#&aSO5S3 literal 0 HcmV?d00001 diff --git a/boards/adi/eval_adin2111d1z/doc/index.rst b/boards/adi/eval_adin2111d1z/doc/index.rst new file mode 100644 index 000000000000..60be2dca4f67 --- /dev/null +++ b/boards/adi/eval_adin2111d1z/doc/index.rst @@ -0,0 +1,218 @@ +.. zephyr:board:: adi_eval_adin2111d1z + +Overview +******** + +Board EVAL-ADIN2111D1Z is a small 4.5x6.5 cm board with ADIN2111 and MAX32690 +microcontroller. The board provides two 10BASE-T1L ports and acts as an +evaluation node in a daisy-chain configuration for both power and data. A +sensor can be connected to the board, analog or digital. In case of power loss, +data is forwarded to another node/board in the chain. The purpose is not to +create a power node, but to demonstrate the daisy-chaining and bypassing data +an on-board relay. + +Use-Cases +********* + +- Daisy-chained sensors (temperature, pressure, light, proximity, ....) using + 10BASE-T1L; in a room / building +- Daisy-chained power over a number (?) of boards +- Daisy-chain data over a number (?) of boards +- Read data from on-board temperature sensor ADT75 +- Demonstrate 10BASE-T1L communication over more nodes +- Use MAX32690 to control ADIN2111 over SPI interface + +Hardware +******** + ++---------------------------------------+----------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Component | Function | Description | ++=======================================+==============================================+==================================================================================================================================================================================+ +| ADIN2111 | 2x 10BASE-T1L switch | Two port industrial ethernet switch with integrated 10BASE-T1L PHYs. Ultra-low power, various routing configurations. SPI communication to uC. | ++---------------------------------------+----------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| MAX32690 (68 TQFN-EP) | ARM M4 Microcontroller (uC) | Widely used across ADI, 120 MHz clock speed, 3 MB flash, 1 MB SRAM, 12-bit ADC, Bluetooth LE 5.2; security options; bootloader. Interfaces: 2x I2C; I2S; SPI; 2x UART; OWM; USB. | ++---------------------------------------+----------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| MAX17640 | DC/DC converter to 3.3V | Input +4.5V to +70V; output 400mA @3.3V. Temperature range -40°C to +150°C | ++---------------------------------------+----------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| MAX77324 | DC/DC converter to 1.8V | Input from MAX17640, output 1500mA @1.8V. VDDIO for ADIN2111 and uC, supply for other parts. | ++---------------------------------------+----------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| MAX77324 | DC/DC converter to 1.1V | Input from MAX17640, output 1500mA @1.1V. Supplies the uC and ADIN2111. | ++---------------------------------------+----------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| EEPROM Microchip AT24C64D | EEPROM memory I2C to uC | 64-Kbit (8192 x 8), 400 KHz Fast mode | ++---------------------------------------+----------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Polarity correction (Bourns CD-HD201) | Bridge rectifier | VRRM 100V, IFSM 50A; IF(AV) 2A; VF(MAX) 0.85A. | ++---------------------------------------+----------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Relay (TE IM21GR) | Bypasses data when power lost | VCOIL 3VDC, RCOIL 180 Ω; PCOIL 50 mW; Ultra highly sensitive. VSWITCH(MAX) 220VDC, ASWITCH(MAX) 2A. | ++---------------------------------------+----------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Transformers (TDK ICI70CGI) | Ensures high impedance in power loss | LR 2.2 mH. Data and signal line chokes, without central tap. | ++---------------------------------------+----------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Power inductors (Coilcraft MSD7342) | Power daisy-chain | L 47 μH; DCR(MAX) 0.42 Ω; SRF 9.5 MHz; ISAT(20% drop) 1.3 A; IRMS(both/one) = 0.61 / 0.86 A. | ++---------------------------------------+----------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| USB-C / JTAG | User / developer interfaces | | ++---------------------------------------+----------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| FTDI chip (FT230XQ-R) | Allows terminal connection to uC | USB to serial UART interface. | ++---------------------------------------+----------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| ADT75 temp. sensor | Temperature sensor | Range −25°C to +100°C, ±2°C. Power consumption 79 μW @3.3V | ++---------------------------------------+----------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| PMOD | UART/SPI/I2C connection for external sensor | 12-pin female connector. | +| | OWM (1-wire) and one ADC input | Shares pins for ADC_0 and ADC_TRIG; OWM (1-wire) | ++---------------------------------------+----------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| 6 pin header | SPI pins for ADIN2111 | Only for testing | ++---------------------------------------+----------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| BLE antenna (Kyocera M310220) | 2.4 GHz on-board antenna | Freq. range 2400 –2485 MHz; G(PEAK) 1.7 dBi; linearly polarized. | ++---------------------------------------+----------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Port 1/2 | 10BASE-T1L ports + DC power | 3-pin 2x Phoenix plug-in screw-terminal connectors | ++---------------------------------------+----------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Ext. power | External power (not injected to T1L lines) | 2-pin Phoenix plug-in screw-terminal connector | ++---------------------------------------+----------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + +Supported Features +================== + +.. zephyr:board-supported-hw:: + +Why MAX32690? +============= + +Microcontroller ADI MAX32690 is an ARM Cortex-M4 device. It is ultra-efficient +and very low power, suitable for battery-powered devices. This microcontroller +(uC) is currently widely used across ADI. The uC has internal 3 MB flash +memory, which is necessary and enough for hosting a webpage and storing MAC and +IP addresses. Other uCs from the 326xx family have significantly less flash +memory (32670/1 has 384 KB; 32672 has 1 MB) and do not support external flash +memory. Other reasons for choosing MAX32690 are more GPIO pins, ability to +flash its firmware using USB interface and USB com port (not implemented yet at +the moment - planned), more security options; and also support for Bluetooth. + +Also, this evaluation board has a representative value showing off our uC, +ADIN2111 PHY, ADT75 temp. sensor, MAX17640 and MAX77324 DC/DC converters; all +connected on one board. + +Connectivity +============ + +- 2x 3 pin (+ - EARTH) Phoenix (P1, P2): Communication amplitude is 1V and 2.4V + as well. +- USB-C connector (P4) uses FTDI chip to talk to the uC. A terminal app UART + communication can be open to read/write to the uC. Also flashing a new + firmware for the uC might be done using UCB-C port and bootloader. +- JTAG/SWD (P5) exposed single wire debug interface of the uC to the connector. + A MAX32625PICO board can be used to download/debug the uC during firmware + development. +- Bluetooth: A Bluetooth connectivity is provided by the uC MAX32690 and an + integrated chip antenna on board. + +Sensors +======= + ++---------+-------+---------------+---------------------------------------------------------------------+ +| Analog | Type | Connector | Note | ++=========+=======+===============+=====================================================================+ +| Digital | I2C | PMOD (P6) | All share one PMOD connector. Only one protocol can be used at once | ++---------+-------+---------------+ | +| | SPI | PMOD (P6) | | ++---------+-------+---------------+ | +| | UART | PMOD (P6) | | ++---------+-------+---------------+---------------------------------------------------------------------+ +| | ADT75 | on-board (U5) | | ++---------+-------+---------------+---------------------------------------------------------------------+ +| | OWM | PMOD (P6) | | ++---------+-------+---------------+---------------------------------------------------------------------+ +| Analog | ADC | PMOD (P6) | 12-bit SAR. PMOD only ADC trigger and ADC_0 input. | ++---------+ +---------------+---------------------------------------------------------------------+ +| | | ADC_1 / ADC_4 | These pins available on the board (solder pins) for future use | ++---------+-------+---------------+---------------------------------------------------------------------+ + + +Power +===== + +There are three options to provide power to the board: USB-C, Ext. 2-pin +connector, 10BASE-T1L 3-pin connectors. + +The goal of the board is not to act as a power node, hence power provided from +different connectors will act differently. + +- USB-C (P4) + + - Only for board - NOT injected to PORT1/2 + - Powers up DC/DC → all circuitry with 3V3, 1V8 and 1V1 + +- Ext. 2 pin connector (P3) + + - 5V-58VDC + - Only for board - NOT injected to PORT1/2 + - Powers up DC/DC → all circuitry with 3V3, 1V8 and 1V1 + +- PORT 1 + + - IN/OUT power + - 7V-58VDC (voltage drop caused by bridge rectifier) + - Power for the board + - Powers up DC/DC → all circuitry with 3V3, 1V8 and 1V1 + - Forwarded to PORT 2 to daisy-chain power + +- PORT 2 + + - IN/OUT power + - 7V-58VDC (voltage drop caused by bridge rectifier) + - Power for the board + - Powers up DC/DC → all circuitry with 3V3, 1V8 and 1V1 + - Forwarded to PORT 1 to daisy-chain power + +Data/Power Bypass +================= + +- Power to PORT 1 + + - Board has power + - Relay connects PORT 1 and PORT 2 to ADIN2111 + - Power is also forwarded to PORT 2 + +- Power to PORT 1 is lost + + - Board does not have power + - Relay disconnects PORT 1 and PORT 2 from ADIN2111 + - Relay connects PORT 1 and PORT 2 together allowing daisy-chaining → data + goes to another node in the chain + - Power is NOT forwarded to PORT 2 + +- Data to PORT 1 + + - Board does not have power UNLESS power provided from Ext. or USB-C + - Relay connects PORT 1 and PORT 2 to ADIN2111 - Data from both ports goes + to ADIN2111 + - Transformers ensure ADIN2111 is disconnected from the lines, resistance + of lines connected to the transformers converges to infinite. + +- Data to PORT 1 and power is lost + + - Relay connects PORT 1 and PORT 2 together to daisy-chain data + - Relay connects PORT 1 and PORT 2 to ADIN2111 + - Power is NOT daisy-chained + - Data is processed by ADIN2111 + - Board does not have power and power is NOT provided from Ext. or USB-C + - Board does not have power, but power IS provided from Ext. or USB-C + +Relay Functionality +=================== + +- Relay is controlled by uC GPIO pin (pin 13 / P0.23) connected to N-FET + transistor + + - When configured correctly: + - if uC has power → relay has power → PORT 1 and PORT 2 connected to + ADIN2111 + - if uC hasn't got power → relay hasn't got power → PORT 1 and PORT 2 not + connected to ADIN2111 instead connected together to allow daisy-chain data + +- Inserting R41 will bypass uC controlling the relay => if board has power -> + relay has power -> PORT 1 and PORT 2 connected to ADIN2111 + + - This option is used in the first stage of testing HW and developing the + board's SW. + +Programming and Debugging +************************* + +.. zephyr:board-supported-runners:: From 6e227712d8e7f222fffb67e5dd27b9e63525c575 Mon Sep 17 00:00:00 2001 From: Ryan McClelland Date: Mon, 10 Nov 2025 16:55:14 -0800 Subject: [PATCH 1704/3659] drivers: i3c: cdns: make idle timeout a kconfig Rather than having a hardcoded timeout for entering idle, make it a KConfig. Signed-off-by: Ryan McClelland --- drivers/i3c/Kconfig.cdns | 15 +++++++++++++++ drivers/i3c/i3c_cdns.c | 3 ++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/drivers/i3c/Kconfig.cdns b/drivers/i3c/Kconfig.cdns index 9b13a1bb8915..e8d35c3c2f74 100644 --- a/drivers/i3c/Kconfig.cdns +++ b/drivers/i3c/Kconfig.cdns @@ -13,3 +13,18 @@ config I3C_CADENCE default y help Enable Cadence I3C driver. + +if I3C_CADENCE + +config I3C_CADENCE_IDLE_TIMEOUT_US + int "I3C Idle Timeout (us)" + default 250 + help + The timeout value waiting for to entry I3C idle state. + This is due to the odd state machine of the I3C peripheral, + where it can be not in an idle state for a while after a transfer + is complete, and it does another transfer before it goes to idle. + It needs to wait for it to be back in the idle state before it can + start another transfer. + +endif # I3C_CADENCE diff --git a/drivers/i3c/i3c_cdns.c b/drivers/i3c/i3c_cdns.c index faf304f6d105..e54cc3e22973 100644 --- a/drivers/i3c/i3c_cdns.c +++ b/drivers/i3c/i3c_cdns.c @@ -466,7 +466,7 @@ #define I3C_MAX_IDLE_CANCEL_WAIT_RETRIES 50 #define I3C_PRESCL_REG_SCALE (4) #define I2C_PRESCL_REG_SCALE (5) -#define I3C_WAIT_FOR_IDLE_STATE_US 100 +#define I3C_WAIT_FOR_IDLE_STATE_US CONFIG_I3C_CADENCE_IDLE_TIMEOUT_US #define I3C_IDLE_TIMEOUT_CYC \ (I3C_WAIT_FOR_IDLE_STATE_US * (sys_clock_hw_cycles_per_sec() / USEC_PER_SEC)) @@ -935,6 +935,7 @@ static inline int cdns_i3c_wait_for_idle(const struct device *dev) */ while (!(sys_read32(config->base + MST_STATUS0) & MST_STATUS0_IDLE)) { if (k_cycle_get_32() - start_time > I3C_IDLE_TIMEOUT_CYC) { + LOG_ERR("%s: Timeout waiting for idle", dev->name); return -EAGAIN; } } From 27c518ee6c746ff421e57374087fde56c0d09e00 Mon Sep 17 00:00:00 2001 From: Qingsong Gou Date: Tue, 23 Dec 2025 19:31:18 +0800 Subject: [PATCH 1705/3659] dts: bindings: display: add sifli,sf32lb-lcdc Add sifli,sf32lb-lcdc for sf32lb platform Signed-off-by: Qingsong Gou --- dts/bindings/display/sifli,sf32lb-lcdc.yaml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 dts/bindings/display/sifli,sf32lb-lcdc.yaml diff --git a/dts/bindings/display/sifli,sf32lb-lcdc.yaml b/dts/bindings/display/sifli,sf32lb-lcdc.yaml new file mode 100644 index 000000000000..10931dbdaf5d --- /dev/null +++ b/dts/bindings/display/sifli,sf32lb-lcdc.yaml @@ -0,0 +1,15 @@ +# Copyright (c) 2025, Qingsong Gou +# SPDX-License-Identifier: Apache-2.0 + +description: Sifli SF32LB LCDC display controller + +compatible: "sifli,sf32lb-lcdc" + +include: base.yaml + +properties: + reg: + required: true + + clocks: + required: true From 0d4640e71ad4bd3a3447489751891ca2baaa08f7 Mon Sep 17 00:00:00 2001 From: Qingsong Gou Date: Sat, 15 Nov 2025 19:50:44 +0800 Subject: [PATCH 1706/3659] dts: bindings: mipi-dbi: sf32lb: add sifli,sf32lb-lcdc-mipi-dbi Add mipi-dbi device bingding for sf32lb platform Signed-off-by: Qingsong Gou --- .../mipi-dbi/sifli,sf32lb-lcdc-mipi-dbi.yaml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 dts/bindings/mipi-dbi/sifli,sf32lb-lcdc-mipi-dbi.yaml diff --git a/dts/bindings/mipi-dbi/sifli,sf32lb-lcdc-mipi-dbi.yaml b/dts/bindings/mipi-dbi/sifli,sf32lb-lcdc-mipi-dbi.yaml new file mode 100644 index 000000000000..dda1f48a0de4 --- /dev/null +++ b/dts/bindings/mipi-dbi/sifli,sf32lb-lcdc-mipi-dbi.yaml @@ -0,0 +1,15 @@ +# Copyright (c) 2025, Qingsong Gou +# SPDX-License-Identifier: Apache-2.0 + +description: SF32LB LCDC MIPI DBI controller + +compatible: "sifli,sf32lb-lcdc-mipi-dbi" + +include: [mipi-dbi-controller.yaml, pinctrl-device.yaml] + +properties: + pinctrl-0: + required: true + + pinctrl-names: + required: true From ec60b59eae7dbc52798e9df4635ab94c7101de65 Mon Sep 17 00:00:00 2001 From: Qingsong Gou Date: Sat, 15 Nov 2025 19:52:36 +0800 Subject: [PATCH 1707/3659] dts: arm: sfili: sf32lb52x: add lcdc and mipi-dbi node Add lcdc and mipi-dbi device for sf32lb platform Signed-off-by: Qingsong Gou --- dts/arm/sifli/sf32lb52x.dtsi | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/dts/arm/sifli/sf32lb52x.dtsi b/dts/arm/sifli/sf32lb52x.dtsi index 44251630953a..8122fd7216f9 100644 --- a/dts/arm/sifli/sf32lb52x.dtsi +++ b/dts/arm/sifli/sf32lb52x.dtsi @@ -120,6 +120,18 @@ }; }; + lcdc: lcdc@50008000 { + compatible = "sifli,sf32lb-lcdc"; + reg = <0x50008000 0x1000>; + clocks = <&rcc_clk SF32LB52X_CLOCK_LCDC1>; + status = "disabled"; + + mipi-dbi { + compatible = "sifli,sf32lb-lcdc-mipi-dbi"; + status = "disabled"; + }; + }; + trng: trng@5000f000 { compatible = "sifli,sf32lb-trng"; reg = <0x5000f000 0x1000>; From 60943ec6847f72e431077b640f885cb077c7f766 Mon Sep 17 00:00:00 2001 From: Qingsong Gou Date: Sat, 15 Nov 2025 19:55:56 +0800 Subject: [PATCH 1708/3659] drivers: mipi_dbi: add lcdc mipi-dbi driver for sf32lb Add lcdc mipi-dbi driver for sf32lb platform Signed-off-by: Qingsong Gou --- drivers/mipi_dbi/CMakeLists.txt | 1 + drivers/mipi_dbi/Kconfig | 1 + drivers/mipi_dbi/Kconfig.sf32lb_lcdc | 9 + drivers/mipi_dbi/mipi_dbi_sf32lb.c | 539 +++++++++++++++++++++++++++ 4 files changed, 550 insertions(+) create mode 100644 drivers/mipi_dbi/Kconfig.sf32lb_lcdc create mode 100644 drivers/mipi_dbi/mipi_dbi_sf32lb.c diff --git a/drivers/mipi_dbi/CMakeLists.txt b/drivers/mipi_dbi/CMakeLists.txt index 5508f7dd3a84..98069c8ad51f 100644 --- a/drivers/mipi_dbi/CMakeLists.txt +++ b/drivers/mipi_dbi/CMakeLists.txt @@ -21,6 +21,7 @@ zephyr_sources_ifdef(CONFIG_MIPI_DBI_ESP32 mipi_dbi_esp32.c) zephyr_sources_ifdef(CONFIG_MIPI_DBI_NXP_DCNANO_LCDIF mipi_dbi_nxp_dcnano_lcdif.c) zephyr_sources_ifdef(CONFIG_MIPI_DBI_NXP_FLEXIO_LCDIF mipi_dbi_nxp_flexio_lcdif.c) zephyr_sources_ifdef(CONFIG_MIPI_DBI_NXP_LCDIC mipi_dbi_nxp_lcdic.c) +zephyr_sources_ifdef(CONFIG_MIPI_DBI_SF32LB mipi_dbi_sf32lb.c) zephyr_sources_ifdef(CONFIG_MIPI_DBI_SMARTBOND mipi_dbi_smartbond.c) zephyr_sources_ifdef(CONFIG_MIPI_DBI_SPI mipi_dbi_spi.c) zephyr_sources_ifdef(CONFIG_MIPI_DBI_STM32_FMC mipi_dbi_stm32_fmc.c) diff --git a/drivers/mipi_dbi/Kconfig b/drivers/mipi_dbi/Kconfig index 5490a1cf36ba..277d3f5d1669 100644 --- a/drivers/mipi_dbi/Kconfig +++ b/drivers/mipi_dbi/Kconfig @@ -28,6 +28,7 @@ source "drivers/mipi_dbi/Kconfig.esp32" source "drivers/mipi_dbi/Kconfig.nxp_dcnano_lcdif" source "drivers/mipi_dbi/Kconfig.nxp_flexio_lcdif" source "drivers/mipi_dbi/Kconfig.nxp_lcdic" +source "drivers/mipi_dbi/Kconfig.sf32lb_lcdc" source "drivers/mipi_dbi/Kconfig.smartbond" source "drivers/mipi_dbi/Kconfig.spi" source "drivers/mipi_dbi/Kconfig.stm32_fmc" diff --git a/drivers/mipi_dbi/Kconfig.sf32lb_lcdc b/drivers/mipi_dbi/Kconfig.sf32lb_lcdc new file mode 100644 index 000000000000..cbf5a58c51b2 --- /dev/null +++ b/drivers/mipi_dbi/Kconfig.sf32lb_lcdc @@ -0,0 +1,9 @@ +# Copyright (c) 2025, Qingsong Gou +# SPDX-License-Identifier: Apache-2.0 + +config MIPI_DBI_SF32LB + bool "SF32LB MIPI DBI driver" + default y + depends on DT_HAS_SIFLI_SF32LB_LCDC_MIPI_DBI_ENABLED + help + Enable driver for SF32LB MIPI DBI controller. diff --git a/drivers/mipi_dbi/mipi_dbi_sf32lb.c b/drivers/mipi_dbi/mipi_dbi_sf32lb.c new file mode 100644 index 000000000000..c50ddad9a2be --- /dev/null +++ b/drivers/mipi_dbi/mipi_dbi_sf32lb.c @@ -0,0 +1,539 @@ +/* + * Copyright (c) 2025, Qingsong Gou + * SPDX-License-Identifier: Apache-2.0 + */ +#define DT_DRV_COMPAT sifli_sf32lb_lcdc_mipi_dbi + +#include +#include +#include +#include +#include +#include + +#include + +LOG_MODULE_REGISTER(mipi_dbi_sf32lb, CONFIG_MIPI_DBI_LOG_LEVEL); + +#define LCDC_SETTING offsetof(LCD_IF_TypeDef, SETTING) +#define LCD_CONF offsetof(LCD_IF_TypeDef, LCD_CONF) +#define LCD_IF_CONF offsetof(LCD_IF_TypeDef, LCD_IF_CONF) +#define TE_CONF offsetof(LCD_IF_TypeDef, TE_CONF) +#define TE_CONF2 offsetof(LCD_IF_TypeDef, TE_CONF2) +#define LCD_WR offsetof(LCD_IF_TypeDef, LCD_WR) +#define LCD_RD offsetof(LCD_IF_TypeDef, LCD_RD) +#define LCD_SINGLE offsetof(LCD_IF_TypeDef, LCD_SINGLE) +#define LCD_SPI_IF_CONF offsetof(LCD_IF_TypeDef, SPI_IF_CONF) +#define LCD_STATUS offsetof(LCD_IF_TypeDef, STATUS) + +#define LCD_INTF_SEL_DBI_TYPEB (0U) +#define LCD_INTF_SEL_SPI (1U) +#define LCD_INTF_SEL_JDI (4U) +#define LCD_INTF_SEL_DBI_TYPEA (6U) + +struct dbi_sf32lb_config { + uintptr_t base; + const struct pinctrl_dev_config *pincfg; + struct sf32lb_clock_dt_spec clock; +}; + +struct dbi_sf32lb_data { + const struct mipi_dbi_config *active_config; +}; + +static inline void wait_busy(const struct device *dev) +{ + const struct dbi_sf32lb_config *config = dev->config; + + while (sys_test_bit(config->base + LCD_SINGLE, LCD_IF_LCD_SINGLE_LCD_BUSY_Pos) || + sys_test_bit(config->base + LCD_STATUS, LCD_IF_STATUS_LCD_BUSY_Pos)) { + } +} + +static void mipi_dbi_sf32lb_spi_sequence(const struct device *dev, bool end) +{ + const struct dbi_sf32lb_config *config = dev->config; + + wait_busy(dev); + + if (end) { + sys_set_bit(config->base + LCD_SPI_IF_CONF, LCD_IF_SPI_IF_CONF_SPI_CS_AUTO_DIS_Pos); + } else { + sys_clear_bit(config->base + LCD_SPI_IF_CONF, + LCD_IF_SPI_IF_CONF_SPI_CS_AUTO_DIS_Pos); + } +} + +static void mipi_dbi_sf32lb_send_single_cmd(const struct device *dev, uint32_t addr, + uint32_t addr_len) +{ + const struct dbi_sf32lb_config *config = dev->config; + uint32_t spi_if_conf; + + wait_busy(dev); + + spi_if_conf = sys_read32(config->base + LCD_SPI_IF_CONF); + spi_if_conf &= ~(LCD_IF_SPI_IF_CONF_RD_LEN_Msk | LCD_IF_SPI_IF_CONF_SPI_RD_MODE_Msk | + LCD_IF_SPI_IF_CONF_WR_LEN_Msk); + + if ((addr_len > 0) && (addr_len <= 4)) { + spi_if_conf |= FIELD_PREP(LCD_IF_SPI_IF_CONF_WR_LEN_Msk, addr_len - 1); + + sys_write32(spi_if_conf, config->base + LCD_SPI_IF_CONF); + sys_write32(addr, config->base + LCD_WR); + sys_write32(LCD_IF_LCD_SINGLE_WR_TRIG | LCD_IF_LCD_SINGLE_TYPE, + config->base + LCD_SINGLE); + } +} + +static void mipi_dbi_sf32lb_recv_single_data(const struct device *dev, uint8_t *buf, uint32_t len) +{ + const struct dbi_sf32lb_config *config = dev->config; + uint32_t spi_if_conf; + uint32_t data; + + wait_busy(dev); + + spi_if_conf = sys_read32(config->base + LCD_SPI_IF_CONF); + spi_if_conf &= ~(LCD_IF_SPI_IF_CONF_RD_LEN_Msk | LCD_IF_SPI_IF_CONF_SPI_RD_MODE_Msk | + LCD_IF_SPI_IF_CONF_WR_LEN_Msk); + + spi_if_conf |= FIELD_PREP(LCD_IF_SPI_IF_CONF_RD_LEN_Msk, len - 1U) | + FIELD_PREP(LCD_IF_SPI_IF_CONF_SPI_RD_MODE_Msk, 1U); + + sys_write32(spi_if_conf, config->base + LCD_SPI_IF_CONF); + sys_write32(LCD_IF_LCD_SINGLE_RD_TRIG, config->base + LCD_SINGLE); + + wait_busy(dev); + + data = sys_read32(config->base + LCD_RD); + + sys_put_le32(data, buf); +} + +static void mipi_dbi_sf32lb_read_bytes(const struct device *dev, uint32_t addr, uint32_t addr_len, + uint8_t *buf, uint16_t len) +{ + wait_busy(dev); + mipi_dbi_sf32lb_spi_sequence(dev, false); + mipi_dbi_sf32lb_send_single_cmd(dev, addr, addr_len); + + mipi_dbi_sf32lb_recv_single_data(dev, buf, len); + mipi_dbi_sf32lb_spi_sequence(dev, true); +} + +static inline void wait_lcdc_single_busy(const struct device *dev) +{ + const struct dbi_sf32lb_config *config = dev->config; + + while (sys_test_bit(config->base + LCD_SINGLE, LCD_IF_LCD_SINGLE_LCD_BUSY_Pos)) { + } +} + +static void mipi_dbi_sf32lb_write_bytes(const struct device *dev, uint32_t addr, uint16_t addr_len, + const uint8_t *buf, uint16_t len) +{ + const struct dbi_sf32lb_config *config = dev->config; + uint32_t spi_if_conf; + + wait_busy(dev); + + mipi_dbi_sf32lb_spi_sequence(dev, 0U == len); + + spi_if_conf = sys_read32(config->base + LCD_SPI_IF_CONF); + spi_if_conf &= ~(LCD_IF_SPI_IF_CONF_RD_LEN_Msk | LCD_IF_SPI_IF_CONF_SPI_RD_MODE_Msk | + LCD_IF_SPI_IF_CONF_WR_LEN_Msk); + + spi_if_conf |= FIELD_PREP(LCD_IF_SPI_IF_CONF_WR_LEN_Msk, addr_len - 1U); + + sys_write32(spi_if_conf, config->base + LCD_SPI_IF_CONF); + sys_write32(addr, config->base + LCD_WR); + sys_write32(LCD_IF_LCD_SINGLE_WR_TRIG | LCD_IF_LCD_SINGLE_TYPE, config->base + LCD_SINGLE); + + uint32_t data_len = len; + uint32_t total_len = len; + + while (data_len > 0) { + uint32_t v, l; + + /* Convert 0xAA,0xBB,0xCC -> 0x00AABBCC */ + for (v = 0, l = 0; l < 4; l++) { + v = (v << 8) | (*buf); + data_len--; + buf++; + } + + wait_lcdc_single_busy(dev); + + total_len -= l; + mipi_dbi_sf32lb_spi_sequence(dev, (0 == total_len)); + + spi_if_conf = sys_read32(config->base + LCD_SPI_IF_CONF); + spi_if_conf &= ~(LCD_IF_SPI_IF_CONF_WR_LEN_Msk); + spi_if_conf |= FIELD_PREP(LCD_IF_SPI_IF_CONF_WR_LEN_Msk, l - 1U); + + sys_write32(spi_if_conf, config->base + LCD_SPI_IF_CONF); + sys_write32(v, config->base + LCD_WR); + sys_write32(LCD_IF_LCD_SINGLE_WR_TRIG | LCD_IF_LCD_SINGLE_TYPE, + config->base + LCD_SINGLE); + } +} + +static int mipi_dbi_sf32lb_freq_config(const struct device *dev, + const struct mipi_dbi_config *dbi_config) +{ + const struct dbi_sf32lb_config *config = dev->config; + uint32_t freq = dbi_config->config.frequency; + uint32_t lcdc_clk; + uint32_t pw, pwl, pwh; + uint32_t lcd_if_conf; + int ret; + + ret = sf32lb_clock_control_get_rate_dt(&config->clock, &lcdc_clk); + if (ret < 0) { + LOG_ERR("Failed to get LCDC clock rate"); + return ret; + } + + pw = (lcdc_clk + (freq - 1)) / freq; + pwl = pw / 2; + pwh = pw - pwl; + + if (pwl < 1) { + pwl = 1; + } + if (pwl > FIELD_GET(LCD_IF_LCD_IF_CONF_PWL_Msk, LCD_IF_LCD_IF_CONF_PWL_Msk)) { + pwl = FIELD_GET(LCD_IF_LCD_IF_CONF_PWL_Msk, LCD_IF_LCD_IF_CONF_PWL_Msk); + } + + if (pwh < 1) { + pwh = 1; + } + if (pwh > FIELD_GET(LCD_IF_LCD_IF_CONF_PWH_Msk, LCD_IF_LCD_IF_CONF_PWH_Msk)) { + pwh = FIELD_GET(LCD_IF_LCD_IF_CONF_PWH_Msk, LCD_IF_LCD_IF_CONF_PWH_Msk); + } + + lcd_if_conf = sys_read32(config->base + LCD_IF_CONF); + lcd_if_conf &= ~(LCD_IF_LCD_IF_CONF_PWL_Msk | LCD_IF_LCD_IF_CONF_PWH_Msk); + lcd_if_conf |= FIELD_PREP(LCD_IF_LCD_IF_CONF_PWL_Msk, pwl) | + FIELD_PREP(LCD_IF_LCD_IF_CONF_PWH_Msk, pwh); + sys_write32(lcd_if_conf, config->base + LCD_IF_CONF); + + return ret; +} + +static int mipi_dbi_sf32lb_spi_config(const struct device *dev, + const struct mipi_dbi_config *dbi_config) +{ + const struct dbi_sf32lb_config *config = dev->config; + const struct spi_config *spi_config = &dbi_config->config; + uint8_t bus_type = dbi_config->mode & 0xFU; + uint8_t color_format = dbi_config->mode & 0xF0U; + uint32_t spi_if_conf = 0; + uint32_t clk_div; + uint32_t lcdc_clk; + uint32_t freq = dbi_config->config.frequency; + uint32_t lcd_conf = sys_read32(config->base + LCD_CONF); + + sys_clear_bits(config->base + LCD_SPI_IF_CONF, LCD_IF_SPI_IF_CONF_CLK_DIV); + + ret = sf32lb_clock_control_get_rate_dt(&config->clock, &lcdc_clk); + if (ret < 0) { + return ret; + }; + + spi_if_conf = LCD_IF_SPI_IF_CONF_SPI_CS_AUTO_DIS | LCD_IF_SPI_IF_CONF_SPI_CLK_AUTO_DIS | + LCD_IF_SPI_IF_CONF_SPI_CS_NO_IDLE; + + if (bus_type == MIPI_DBI_MODE_SPI_4WIRE) { + spi_if_conf |= LCD_IF_SPI_IF_CONF_4LINE_4_DATA_LINE; + } else if (bus_type == MIPI_DBI_MODE_SPI_3WIRE) { + spi_if_conf |= LCD_IF_SPI_IF_CONF_3LINE; + } else { + return -EINVAL; + } + + if (spi_config->operation & SPI_MODE_CPOL) { + spi_if_conf &= ~LCD_IF_SPI_IF_CONF_SPI_CLK_INIT; + } else { + spi_if_conf |= LCD_IF_SPI_IF_CONF_SPI_CLK_INIT; + } + + if (spi_config->operation & SPI_MODE_CPHA) { + spi_if_conf |= LCD_IF_SPI_IF_CONF_SPI_CLK_POL; + } + + clk_div = (lcdc_clk + (freq - 1)) / freq; + if (clk_div < 2) { /* HW NOT support divider 1 */ + clk_div = 2; + } + if (clk_div > 0xFF) { + clk_div = 0xFF; + } + + spi_if_conf |= FIELD_PREP(LCD_IF_SPI_IF_CONF_CLK_DIV_Msk, clk_div); + sys_write32(spi_if_conf, config->base + LCD_SPI_IF_CONF); + + return 0; +} + +static int mipi_dbi_sf32lb_configure(const struct device *dev, + const struct mipi_dbi_config *dbi_config) +{ + const struct dbi_sf32lb_config *config = dev->config; + struct dbi_sf32lb_data *data = dev->data; + uint8_t bus_type = dbi_config->mode & 0xFU; + uint32_t lcd_conf; + uint32_t lcd_if_conf; + + if (dbi_config == data->active_config) { + return 0; + } + + lcd_conf = sys_read32(config->base + LCD_CONF); + lcd_conf &= ~(LCD_IF_LCD_CONF_LCD_INTF_SEL_Msk | LCD_IF_LCD_CONF_TARGET_LCD_Msk); + + switch (bus_type) { + case MIPI_DBI_MODE_8080_BUS_16_BIT: + case MIPI_DBI_MODE_8080_BUS_9_BIT: + case MIPI_DBI_MODE_8080_BUS_8_BIT: + lcd_conf |= FIELD_PREP(LCD_IF_LCD_CONF_LCD_INTF_SEL_Msk, LCD_INTF_SEL_DBI_TYPEB); + lcd_conf |= FIELD_PREP(LCD_IF_LCD_CONF_TARGET_LCD_Msk, 0U); + lcd_if_conf = sys_read32(config->base + LCD_IF_CONF); + lcd_if_conf &= ~(LCD_IF_LCD_IF_CONF_TAS_Msk | LCD_IF_LCD_IF_CONF_TAH_Msk); + lcd_if_conf |= FIELD_PREP(LCD_IF_LCD_IF_CONF_TAS_Msk, 1U) | + FIELD_PREP(LCD_IF_LCD_IF_CONF_TAH_Msk, 1U); + sys_write32(lcd_if_conf, config->base + LCD_IF_CONF); + mipi_dbi_sf32lb_freq_config(dev, dbi_config); + break; + + case MIPI_DBI_MODE_SPI_3WIRE: + case MIPI_DBI_MODE_SPI_4WIRE: + lcd_conf |= FIELD_PREP(LCD_IF_LCD_CONF_LCD_INTF_SEL_Msk, LCD_INTF_SEL_SPI); + lcd_conf |= FIELD_PREP(LCD_IF_LCD_CONF_TARGET_LCD_Msk, 1U); + ret = mipi_dbi_sf32lb_spi_config(dev, dbi_config); + if (ret < 0) { + return ret; + } + break; + + default: + return -EINVAL; + } + + sys_write32(lcd_conf, config->base + LCD_CONF); + data->active_config = dbi_config; + + return 0; +} + +static int mipi_dbi_reset_sf32lb(const struct device *dev, k_timeout_t delay) +{ + const struct dbi_sf32lb_config *config = dev->config; + uint32_t delay_ms = k_ticks_to_ms_ceil32(delay.ticks); + + sys_clear_bit(config->base + LCD_IF_CONF, LCD_IF_LCD_IF_CONF_LCD_RSTB_Pos); + k_msleep(delay_ms); + sys_set_bit(config->base + LCD_IF_CONF, LCD_IF_LCD_IF_CONF_LCD_RSTB_Pos); + + return 0; +} + +static int mipi_dbi_sf32lb_8080_cmd_write_bytes(const struct device *dev, uint8_t cmd, + const uint8_t *data, size_t data_len) +{ + const struct dbi_sf32lb_config *config = dev->config; + + wait_busy(dev); + sys_write32(cmd, config->base + LCD_WR); + sys_write32(LCD_IF_LCD_SINGLE_WR_TRIG, config->base + LCD_SINGLE); + + while (data_len > 0) { + uint8_t v = *data; + + wait_busy(dev); + sys_write32(v, config->base + LCD_WR); + sys_write32(LCD_IF_LCD_SINGLE_WR_TRIG | LCD_IF_LCD_SINGLE_TYPE, + config->base + LCD_SINGLE); + + data_len--; + data++; + } + + return 0; +} + +static int mipi_dbi_command_write_sf32lb(const struct device *dev, + const struct mipi_dbi_config *dbi_config, uint8_t cmd, + const uint8_t *data, size_t len) +{ + uint32_t addr; + uint8_t bus_type = dbi_config->mode & 0xFU; + + mipi_dbi_sf32lb_configure(dev, dbi_config); + + switch (bus_type) { + case MIPI_DBI_MODE_8080_BUS_8_BIT: + return mipi_dbi_sf32lb_8080_cmd_write_bytes(dev, cmd, data, len); + case MIPI_DBI_MODE_SPI_3WIRE: + case MIPI_DBI_MODE_SPI_4WIRE: + mipi_dbi_sf32lb_write_bytes(dev, addr, sizeof(addr), data, len); + break; + default: + return -EINVAL; + } + + return 0; +} + +static int mipi_dbi_write_display_sf32lb(const struct device *dev, + const struct mipi_dbi_config *dbi_config, + const uint8_t *framebuf, + struct display_buffer_descriptor *desc, + enum display_pixel_format pixfmt) +{ + ARG_UNUSED(pixfmt); + const struct dbi_sf32lb_config *config = dev->config; + int data_len = desc->buf_size; + const uint8_t *buf = framebuf; + uint32_t spi_if_conf; + uint8_t bus_type = dbi_config->mode & 0xFU; + + if (data_len < 0) { + return 0; + } + + if (bus_type == MIPI_DBI_MODE_8080_BUS_16_BIT || bus_type == MIPI_DBI_MODE_8080_BUS_9_BIT || + bus_type == MIPI_DBI_MODE_8080_BUS_8_BIT) { + while (data_len > 0) { + wait_busy(dev); + + if (bus_type == MIPI_DBI_MODE_8080_BUS_16_BIT && data_len >= 2) { + uint16_t v = sys_get_le16(buf); + + sys_write32(v, config->base + LCD_WR); + sys_write32(LCD_IF_LCD_SINGLE_WR_TRIG | LCD_IF_LCD_SINGLE_TYPE, + config->base + LCD_SINGLE); + buf += 2; + data_len -= 2; + } else { + sys_write32(*buf, config->base + LCD_WR); + sys_write32(LCD_IF_LCD_SINGLE_WR_TRIG | LCD_IF_LCD_SINGLE_TYPE, + config->base + LCD_SINGLE); + buf++; + data_len--; + } + } + } else if (bus_type == MIPI_DBI_MODE_SPI_3WIRE || bus_type == MIPI_DBI_MODE_SPI_4WIRE) { + uint32_t total_len = data_len; + + mipi_dbi_sf32lb_configure(dev, dbi_config); + + while (data_len > 0) { + uint32_t v, l; + + /* Convert 0xAA,0xBB,0xCC -> 0x00AABBCC */ + for (v = 0, l = 0; l < 4; l++) { + v = (v << 8) | (*buf); + data_len--; + buf++; + } + + wait_lcdc_single_busy(dev); + + total_len -= l; + mipi_dbi_sf32lb_spi_sequence(dev, (0 == total_len)); + + spi_if_conf = sys_read32(config->base + LCD_SPI_IF_CONF); + spi_if_conf &= ~(LCD_IF_SPI_IF_CONF_WR_LEN_Msk); + spi_if_conf |= FIELD_PREP(LCD_IF_SPI_IF_CONF_WR_LEN_Msk, l - 1U); + + sys_write32(spi_if_conf, config->base + LCD_SPI_IF_CONF); + sys_write32(v, config->base + LCD_WR); + sys_write32(LCD_IF_LCD_SINGLE_WR_TRIG | LCD_IF_LCD_SINGLE_TYPE, + config->base + LCD_SINGLE); + } + } else { + return -EINVAL; + } + + return 0; +} + +static int mipi_dbi_configure_te_sf32lb(const struct device *dev, uint8_t edge, k_timeout_t delay) +{ + const struct dbi_sf32lb_config *config = dev->config; + uint32_t delay_us = k_ticks_to_us_ceil32(delay.ticks); + uint32_t te_conf; + + te_conf = sys_read32(config->base + TE_CONF); + + te_conf &= ~LCD_IF_TE_CONF_FMARK_MODE_Msk; + + if (edge == MIPI_DBI_TE_RISING_EDGE) { + te_conf |= FIELD_PREP(LCD_IF_TE_CONF_FMARK_POL_Msk, 0); + } else if (edge == MIPI_DBI_TE_FALLING_EDGE) { + te_conf |= FIELD_PREP(LCD_IF_TE_CONF_FMARK_POL_Msk, 1); + } else { + return -EINVAL; + } + + te_conf |= FIELD_PREP(LCD_IF_TE_CONF_FMARK_MODE_Msk, 1) | + FIELD_PREP(LCD_IF_TE_CONF_ENABLE_Msk, 1); + + sys_write32(delay_us, config->base + TE_CONF2); + sys_write32(te_conf, config->base + TE_CONF); + + return 0; +} + +static DEVICE_API(mipi_dbi, dbi_sf32lb_api) = { + .reset = mipi_dbi_reset_sf32lb, + .command_write = mipi_dbi_command_write_sf32lb, + .write_display = mipi_dbi_write_display_sf32lb, + .configure_te = mipi_dbi_configure_te_sf32lb, +}; + +static int mipi_dbi_init_sf32lb(const struct device *dev) +{ + const struct dbi_sf32lb_config *config = dev->config; + int err; + + if (!sf32lb_clock_is_ready_dt(&config->clock)) { + return -ENODEV; + } + + err = sf32lb_clock_control_on_dt(&config->clock); + if (err < 0) { + return err; + } + + err = pinctrl_apply_state(config->pincfg, PINCTRL_STATE_DEFAULT); + if (err < 0) { + LOG_ERR("Failed to apply pinctrl state: %d", err); + return err; + } + + sys_set_bit(config->base + LCDC_SETTING, LCD_IF_SETTING_AUTO_GATE_EN_Pos); + sys_set_bit(config->base + LCD_IF_CONF, LCD_IF_LCD_IF_CONF_LCD_RSTB_Pos); + + return err; +} + +#define DBI_SF32LB_DEFINE(n) \ + PINCTRL_DT_INST_DEFINE(n); \ + static struct dbi_sf32lb_data dbi_sf32lb_data_##n; \ + \ + static const struct dbi_sf32lb_config dbi_sf32lb_config_##n = { \ + .base = DT_REG_ADDR(DT_INST_PARENT(n)), \ + .clock = SF32LB_CLOCK_DT_INST_PARENT_SPEC_GET(n), \ + .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ + }; \ + \ + DEVICE_DT_INST_DEFINE(n, mipi_dbi_init_sf32lb, NULL, &dbi_sf32lb_data_##n, \ + &dbi_sf32lb_config_##n, POST_KERNEL, CONFIG_MIPI_DBI_INIT_PRIORITY, \ + &dbi_sf32lb_api); \ + BUILD_ASSERT((DT_CHILD_NUM_STATUS_OKAY(DT_INST_PARENT(n)) == 1), \ + "LCDC only supports one operating mode"); + +DT_INST_FOREACH_STATUS_OKAY(DBI_SF32LB_DEFINE) From 2917cc90bc765604adddc14d9ab12bab70ffbe90 Mon Sep 17 00:00:00 2001 From: Qingsong Gou Date: Fri, 19 Dec 2025 09:57:24 +0800 Subject: [PATCH 1709/3659] tests: drivers: build_all: add SF32LB dbi test Add a SF32LB DBI test Signed-off-by: Qingsong Gou --- .../boards/sf32lb52_devkit_lcd.overlay | 37 +++++++++++++++++++ tests/drivers/build_all/display/testcase.yaml | 4 ++ 2 files changed, 41 insertions(+) create mode 100644 tests/drivers/build_all/display/boards/sf32lb52_devkit_lcd.overlay diff --git a/tests/drivers/build_all/display/boards/sf32lb52_devkit_lcd.overlay b/tests/drivers/build_all/display/boards/sf32lb52_devkit_lcd.overlay new file mode 100644 index 000000000000..1c085883e63f --- /dev/null +++ b/tests/drivers/build_all/display/boards/sf32lb52_devkit_lcd.overlay @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2025, Qingsong Gou + * SPDX-License-Identifier: Apache-2.0 + */ + +&pinctrl { + lcdc_8080_default: lcdc_8080_default { + group1 { + pinmux = , + , + , + , + , + , + , + , + , + , + , + , + ; + input-enable; + }; + }; +}; + +&lcdc { + status = "okay"; + + mipi_dbi: mipi-dbi { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + pinctrl-0 = <&lcdc_8080_default>; + pinctrl-names = "default"; + }; +}; diff --git a/tests/drivers/build_all/display/testcase.yaml b/tests/drivers/build_all/display/testcase.yaml index d4764e6337db..6ece8757c239 100644 --- a/tests/drivers/build_all/display/testcase.yaml +++ b/tests/drivers/build_all/display/testcase.yaml @@ -14,3 +14,7 @@ tests: drivers.display.build.bflb_dbi: platform_allow: - ai_m62_12f_kit + + drivers.display.build.sf32lb_dbi: + platform_allow: + - sf32lb52_devkit_lcd From 952ee6a68187a2e57275e8415ea85dba5cfb1196 Mon Sep 17 00:00:00 2001 From: Mark Wang Date: Fri, 19 Dec 2025 11:19:14 +0800 Subject: [PATCH 1710/3659] MAINTAINERS: bluetooth: add sbc.h and sbc.c to libsbc maintainer entry Add include/zephyr/bluetooth/sbc.h and subsys/bluetooth/lib/sbc.c to the libsbc module maintainer entry to ensure proper coverage of SBC codec related files. Signed-off-by: Mark Wang --- MAINTAINERS.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index b3fd9ab2748d..066895f3fdc2 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -584,6 +584,7 @@ Bluetooth Host: - include/zephyr/bluetooth/iso.h - include/zephyr/bluetooth/controller.h - include/zephyr/bluetooth/mesh.h + - include/zephyr/bluetooth/sbc.h - doc/connectivity/bluetooth/bluetooth-ctlr-arch.rst - doc/connectivity/bluetooth/autopts/ - doc/connectivity/bluetooth/img/ctlr* @@ -606,6 +607,7 @@ Bluetooth Host: - subsys/bluetooth/host/iso.c - subsys/bluetooth/host/iso_internal.h - subsys/bluetooth/host/shell/iso.c + - subsys/bluetooth/lib/sbc.c - tests/bluetooth/audio/ - tests/bluetooth/classic/ - tests/bluetooth/controller/ @@ -6024,6 +6026,8 @@ West: - MarkWangChinese files: - modules/libsbc/ + - include/zephyr/bluetooth/sbc.h + - subsys/bluetooth/lib/sbc.c labels: - "area: Audio" From 0aadb3f0c8837cd67ecb69055cb0b296881f6a80 Mon Sep 17 00:00:00 2001 From: Thomas Stranger Date: Fri, 26 Dec 2025 19:27:42 +0100 Subject: [PATCH 1711/3659] doc: develop: getting_started: fedora dnf5 group installation The group display names don't work with dnf5. As displaynames can depend on the locale and are not unique dnf5 only supports the group identifiers. Distributions with dnf4 like RHEL<=10, Fedora<41, and CentOS stream shouldn't have any issues with the group id, but have not been tested. Alternatives considered: use the @-sytax for groups introduced in dnf5, but using the group command makes it more clear that package groups are installed. Signed-off-by: Thomas Stranger --- doc/develop/getting_started/installation_linux.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/develop/getting_started/installation_linux.rst b/doc/develop/getting_started/installation_linux.rst index 80aefcd302fe..c5858545f368 100644 --- a/doc/develop/getting_started/installation_linux.rst +++ b/doc/develop/getting_started/installation_linux.rst @@ -85,7 +85,7 @@ need one. .. code-block:: console - sudo dnf group install "Development Tools" "C Development Tools and Libraries" + sudo dnf group install development-tools c-development sudo dnf install cmake ninja-build gperf dfu-util dtc wget which \ python3-pip python3-tkinter xz file python3-devel SDL2-devel From da7d8d5c4b9391436369950005ad84ae2def5a48 Mon Sep 17 00:00:00 2001 From: Dhruv Menon Date: Wed, 31 Dec 2025 23:27:15 +0530 Subject: [PATCH 1712/3659] boards: vicharak: shrike_lite: Add initial board config Add initial board configuration and device tree files for the Vicharak Shrike Lite board. Signed-off-by: Dhruv Menon --- boards/vicharak/index.rst | 10 ++ boards/vicharak/shrike_lite/Kconfig | 5 + boards/vicharak/shrike_lite/Kconfig.defconfig | 19 +++ .../vicharak/shrike_lite/Kconfig.shrike_lite | 5 + boards/vicharak/shrike_lite/board.cmake | 29 ++++ boards/vicharak/shrike_lite/board.yml | 5 + .../shrike_lite/doc/img/shrike_lite.webp | Bin 0 -> 55846 bytes boards/vicharak/shrike_lite/doc/index.rst | 126 ++++++++++++++++++ .../shrike_lite/shrike_lite-pinctrl.dtsi | 67 ++++++++++ boards/vicharak/shrike_lite/shrike_lite.dts | 122 +++++++++++++++++ boards/vicharak/shrike_lite/shrike_lite.yaml | 24 ++++ .../shrike_lite/shrike_lite_defconfig | 15 +++ dts/bindings/vendor-prefixes.txt | 1 + 13 files changed, 428 insertions(+) create mode 100644 boards/vicharak/index.rst create mode 100644 boards/vicharak/shrike_lite/Kconfig create mode 100644 boards/vicharak/shrike_lite/Kconfig.defconfig create mode 100644 boards/vicharak/shrike_lite/Kconfig.shrike_lite create mode 100644 boards/vicharak/shrike_lite/board.cmake create mode 100644 boards/vicharak/shrike_lite/board.yml create mode 100644 boards/vicharak/shrike_lite/doc/img/shrike_lite.webp create mode 100644 boards/vicharak/shrike_lite/doc/index.rst create mode 100644 boards/vicharak/shrike_lite/shrike_lite-pinctrl.dtsi create mode 100644 boards/vicharak/shrike_lite/shrike_lite.dts create mode 100644 boards/vicharak/shrike_lite/shrike_lite.yaml create mode 100644 boards/vicharak/shrike_lite/shrike_lite_defconfig diff --git a/boards/vicharak/index.rst b/boards/vicharak/index.rst new file mode 100644 index 000000000000..5ff82723ade6 --- /dev/null +++ b/boards/vicharak/index.rst @@ -0,0 +1,10 @@ +.. _boards-vicharak: + +Vicharak +######## + +.. toctree:: + :maxdepth: 1 + :glob: + + **/* diff --git a/boards/vicharak/shrike_lite/Kconfig b/boards/vicharak/shrike_lite/Kconfig new file mode 100644 index 000000000000..75d49ff5367d --- /dev/null +++ b/boards/vicharak/shrike_lite/Kconfig @@ -0,0 +1,5 @@ +# Copyright (C) 2025 Dhruv Menon +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_SHRIKE_LITE + select RP2_FLASH_W25Q080 diff --git a/boards/vicharak/shrike_lite/Kconfig.defconfig b/boards/vicharak/shrike_lite/Kconfig.defconfig new file mode 100644 index 000000000000..3e2eb4ce8d63 --- /dev/null +++ b/boards/vicharak/shrike_lite/Kconfig.defconfig @@ -0,0 +1,19 @@ +# Shrike Lite board configuration +# +# Copyright (c) 2026 Dhruv Menon +# +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_SHRIKE_LITE + +if I2C_DW + +config I2C_DW_CLOCK_SPEED + default 125 + +endif # I2C_DW + +config USB_SELF_POWERED + default n + +endif # BOARD_SHRIKE_LITE diff --git a/boards/vicharak/shrike_lite/Kconfig.shrike_lite b/boards/vicharak/shrike_lite/Kconfig.shrike_lite new file mode 100644 index 000000000000..e8b29d52d72a --- /dev/null +++ b/boards/vicharak/shrike_lite/Kconfig.shrike_lite @@ -0,0 +1,5 @@ +# Copyright (C) 2025 Dhruv Menon +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_SHRIKE_LITE + select SOC_RP2040 diff --git a/boards/vicharak/shrike_lite/board.cmake b/boards/vicharak/shrike_lite/board.cmake new file mode 100644 index 000000000000..c050a08520ab --- /dev/null +++ b/boards/vicharak/shrike_lite/board.cmake @@ -0,0 +1,29 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright (C) 2025 Dhruv Menon + +# This configuration allows selecting what debug adapter to use for debugging +# the Vicharak Shrike Lite by a command-line argument. +# It is mainly intended to support both the 'picoprobe' and 'raspberrypi-swd' +# adapter described in "Getting started with Raspberry Pi Pico". + +# Set DRPI_PICO_DEBUG_ADAPTER to select debug adapter by command-line arguments. +# e.g.) west build -b shrike_lite -- -DRPI_PICO_DEBUG_ADAPTER=raspberrypi-swd +# The value is treated as a part of an interface file name that +# the debugger's configuration file. + +if("${RPI_PICO_DEBUG_ADAPTER}" STREQUAL "") + set(RPI_PICO_DEBUG_ADAPTER "cmsis-dap") +endif() + +board_runner_args(openocd --cmd-pre-init "source [find interface/${RPI_PICO_DEBUG_ADAPTER}.cfg]") +board_runner_args(openocd --cmd-pre-init "transport select swd") +board_runner_args(openocd --cmd-pre-init "source [find target/rp2040.cfg]") + +# The adapter speed is expected to be set by interface configuration. +# But if not so, set 2000 to adapter speed. +board_runner_args(openocd --cmd-pre-init "set_adapter_speed_if_not_set 2000") + +board_runner_args(uf2 "--board-id=RPI-RP2") + +include(${ZEPHYR_BASE}/boards/common/uf2.board.cmake) +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) \ No newline at end of file diff --git a/boards/vicharak/shrike_lite/board.yml b/boards/vicharak/shrike_lite/board.yml new file mode 100644 index 000000000000..b8f09702a6ba --- /dev/null +++ b/boards/vicharak/shrike_lite/board.yml @@ -0,0 +1,5 @@ +board: + name: shrike_lite + vendor: vicharak + socs: + - name: rp2040 diff --git a/boards/vicharak/shrike_lite/doc/img/shrike_lite.webp b/boards/vicharak/shrike_lite/doc/img/shrike_lite.webp new file mode 100644 index 0000000000000000000000000000000000000000..31927677f066f79adbf2efadf1751a81d5a36f7a GIT binary patch literal 55846 zcmd41QZ5!v?eg55}PxtOVw|idAn>j{C+cP=Jis-qrZc%#9b*iOYk<@tJ~d0@gQ@uHUC-P)>?hN zuR-GBPb_M-5`>6MTx7j!0xBZK8N%s@yI{NwZ`$P9xr{8D9 zTk{M3Ir~1lftTSo_FMO(wDP;tx9Ye23iy-rUG&q|fcNRm(POm+{gL)gx2fk2|HSwH zTmS3#*>LOjT=%^D$+zqc>BshS{Ok0^_R;4jXT{g^`}=+8=L&8=pm2nDgaLt0$sP0+ zL;wsb7Vj5tjIUq*0RI3J4D$z9;71@nAh2khZ=4Z?x&+<#xRGn({n zE;}Lc@kn2&DEj$wZw_2;N$My9&IT6V(6Vjh9*a2;t1yD$VJxIau$2{YN$??)4hrrN z!vjh9_l_h=b`6Q zH>r|H2yg&n6ya_J9BAe)vXeg&ooAB&U9|q+L<^3u4@Y9-Hb;avHki#*yG0wcGm9{R z=(BUjupB{#skcv6o*9pUSBBWe8F&plfK(u7+BH%Q)eGk(66kD7lsQ=rqFmdRFs71t z{PL-12>LFxb8zXitW*NlAZS^6(WrkBU5SxTy+Mcjg&)wS{! zKdEHpm{aw}6*bIyOFxH@e%&y8!yhn7-UiUT8FgG{3HMkKOHWc!*rGF;CXSJAySB{= zqy+?3N%`;r$|2Y-HuvWYLThcshh*>D2PERL{rmamb*jy{0D@d7Cjw45i-$h10 zyA6hjbt1W*(QE~MFrI@=uG7BUK1tTOg?Ykar|~?pYaMBt*UUgc5g;bg)n`DOi}FAJ z*&`Gmk~{p3IGO! z57^7G($Op^<_>`1jQ;daN-0X6hSwWfA%GLv--s?upihAC96e%D!y#EXyc90`o7WhQ zaPbe5vBxFfpYnp7;=GZ_n0cMuEHVfTr+oLQ5tat)3jeWK;osN*v3#cQ4o!RvuVxPx zhI#k*%c&iL1!i8;YpxC5b07(2Q&NQ5DXs7-CXeeG-4VMT_wD-WZ7*CU-CeRwJ|Px< zfbJaQdK|w|o?5=7{yA}&>4^DO{E4V7M725nZPGDj^4)3$u^8vCQHPy(vD21XsHVz5 zWqu~Kd?d4cYgM$HZ8v+)jxJc!v^Bg8d1bo~xk=r9EUKPZVI+E$TnKQO0=NV(w=MR# zfaXvVcBf{uSpZ?Jx(Ttz@V-fQnZ8MZacogS4*O3s^LRU>WT}vnHlNB7+iOvs&LtP2 zM$9uv6z$lgFX;U-*#4#=Xcq0Jt|EK^Tb4Kr4VB=)Fx9kff=8UJ(ZtpL1zS@i^O#%4 zQSv-YsE?5t2|;~9VPc0fjXxGulX#j>VCOR`e`yD_yTV*SSK7}?h1{+Q%l);8;O$uM zUqeMjCH#It@>$%Hk@msWwQ>IaS{kuHG>lw8BDvHgCSSZ^F_9X|(wX0`7&=hjWJku_ z*l{SG6ED7JL2r(|qt_Kr$&A85SI9o=r)gUpxf0^D)AYFxpo_u~bgItj8-qYlkTa`>oKS=9b2*Wsrw8AoT+yH#BNna}bCOcWhH zq*Ugzy?SV@PySWH0UW?;vk7?O+|LD_TWt_p&di1}yqdoDIA+@6;E$gWT45yBW|#U~ zbBo`ECoFikRElV}%F7p|1F8HDUNMSTNns>g*6M43`9hZxuX~BFlZ)q%1Zp)VIBsI~ z%_>J5dDhC(*U1{qX1-Oc;|Hdu4W^BRuLY=B)Kyk@)zGW1ufToXv{^v>aBEQz=f$|9iOl zKeHo39B28PaPEn@Xtu@IGwls&xBwTf1{xy6kL0)@5pQ_F+upG5@d>`wFU@LN&vYLu z8?)0KQxuUIwDu#vVqnX1+sEx{;BbNMa45bZyu!I+dGqSikk+c-kc`fxK**B7L|exI zI{k8-nz!HN_G0tm7g6>q4`!AzZO-K?h-p`}+Y6{=EVqj4?Y^ILKO9dt2P5JLL$TBN zPvDde8jg$m=8!I*6e}|10geuC*WVMkZ0fq#fnm-*1Cxp|T&rMWy$3~qHvkD4n}>wI1lS_jp4(#4?`elCIw+V$_uj48y&LNpgm2a!Blz;y z$owcs2wB;V<`dSF^EVmlbERp@`dpEebaSW+$sy+o^v(eaOw=YP7!KxyGTY8Z<(Qhm ziGHbE%cnmOgeNR_0&Gi=>rc=RnN$(xx{X9$7wfVU0~oIGxTz2F&8lAC+GsaAryh>_ zcSUuSN0Z3ihm5yFrd{$+`f!|yc4 zXP(OuGe4A`(yOcTfAe4dy)NzF)>-5YA=foh`KFQvveQ#omULyx>qL%8h@2b8o&F%hgHt*QJi`25TY_E#FcH5Tul@ifDQ))54*Nwsk{h!iC1nI9fAMHR!xY4GJco5jV@hA8wjlH>8zhJPdu+^oE?cCH&xKd2 zVo`#|qOnj?ezO1kcbAQT8?GdnmDY_EkpTL*>OAWe)q?~9G_VW^Gs(ax6v*8EHw7MRzc`B$*%e|K4i~RZv0<{Qy}qgy#mjs zv9D|NI`}&H@Rujmno(a%lr}HG9YhcJWeX26uXIo%+fg$af8MKJ)Y;~5^?i&Mkrv5SAPN6KEKb#*IF<3syqL;Ev zE3Rrg?h$B`nGm85dl>Etk>zce;(`Kuv%`e3@=u7r&ZY17ZbG&uo*t{Hx9W{FhehP4 z$sL37x6;T2H>dK!3C63BUQ9=ls%dmccJvRM{&obR0)xg~ND5QVz(iyv&zchK7isH; z?yxj*%>Xe~U2!oYtF|L-Xne~9kQy`rI->d+S2u=}e*6k+jQG(z|7tFrxmJ$op@=-I zt?GGfUfkL-$Y|X0FILdZXw4NTWtU{@aRcDs16|g~1moUep!P3>VnotpkJ%fs5ibJY z!2!xpQlyFOZJGoo8uyG=O{WW_J?w_(63ihFWDR&g!Up?oNT(hf&(+Ry;vA2K0x0g# zEjWa?G%Cb&xy=*i-!ln`-hnf8py<(IgjUbqXUUF^qgLR?Z1JIfI_@V_BhqN!r`JId z&%Y%631fK7dNQ%Rqy5cb*2xBQCvYE4h0ptW(4`kb>O1&I0tkh~eo6o|DB>%?&Ah_q z_(Y!exJ@G_Mfe6aeVijP^Fia}Q~MXHBcn4oJO^e}ymhCS-u}(A;eF34CR!{Ys~^|Y zry(|{lHxJ1csR%GyArxyeZvSM(r4TYMM?_xuMnPR&Kf79?22}TEcFZQ>FY-m%{T%@zuwR&>8ATQ3!wW;o;j0SE=-Eh&^qA2 zHtEYFnlUboK-BVB$Sf(sCclY#xTY{}=86yseRqqaym;M%k?(X?S(NS^?x6@S%hQ4X zv1p?nVw16y{eI~INmHOrkC((?NiQF^q{uY+IqfQ}h>uDo-6Dv)u|f9=!M@<=4)kkw zV#qNDkQBfZVQ9h4!Eg-is=Ik4M!5Dbdkgu4pG-GC?JPHp*ZUXznf0Qu2GT?@FD7WP zSL4Ym$Iahs+VY+8WoCDW-r(~=>(c!y$2o5R%7}Fj6PXcwGT}KIV^AoX%Pc$ccVVi~ zCnwBH-_vEYXwCRdgd76twV)G~S4XY~uOc4W?C~$0f z@v1Tzrb0u?ZBxf#y5HSTLQv^AxFzbKG-@$Yo*EHUZV;^A-X^{_XM7D_Q!7@%xDwMV z9aab@E(N)VWtm+{O0R~2_ys2MGLD)ZukWKS&Kv)mu#Wvyvu@T? zhhme-xgk*Cf5zv-30LYYj(V*I%xKGa+QtcpBh15;ppsz;waR`qGs3KHbpTT(7iYGf z*jX4@#g;cL%V7v@yewi>u(Aarg7Fl(?KdrKq`NBr8>`rRHWB6{=@U!EdX9Sg^)4QX zx+g^-9=rgmW&FEs0@+oc-R#?0cKm7lV=lAI=;byFaAVn5tqYt#3Hpr3NKhz{Uei-0 z2gJYyo}6_M(Ak7A2-D*{A+DX6gViM6`S}jVlIFc@n0Gem@oCxy)iFqW=Lq^BvR>|l zF^Hjl1OlWOq$wJc$MpKUX``Mo6SmsohI-PPM*!M(RKlTl#rK31hY7+dJrOKY1f^;^ z=*eKa8}M|^e)(sHr)4TqmMKDKs+^S*ldZ2w%wzB~0sffS19OEbTvc5KBw&L)V;&7| z8NE{bN|GAMw>jInnf=lpVK8yWqk?Y$*3yhZ^M7YS5bSSMM>z8%igQ3B@g4UtTne@X zNQVUp(UE>y&bx+9A>iJLuy*ff$1Q~n41|7J9XtSyc2iB5&QGGZ1m7n`g6k*)qyXe1WbpCsl!t^ z2C%aBn8!@{pG5{sbQPNPO@1Z~l5lX_LP;5wby5!pUfW#Oyk9?jyTPMdQ5au42 zZK)kulemNR0+426@UefWB&ixS0Dt_M#n`PnE1Ecy2(v9ChXYegCX(+t&$+zR26?2iu(_R zhqsTS^wC{#XTL6gK7x^V|9(enUe-I~JS)6NDQ~3zUw!?OmIVM08)u+3^^&m<*wf?ZDLo9EYl14hT7?L8_$ZcGaCpv`~gK&ZC7IdRbdIk?~e<)OA0^#LAqUPB4(>hY|1P# z5Ckl}_)yz&T9LJ@ob!~FPPr9u6#CQ98kQP{P`_elHwMh#;6;p9DBz#t@ETSPR=c^9 z%1{7?{6Ud>3tppApQ1+*$}V6?ndLa(%G2)A_n!eHNegreL+tZSC`hIF?_VVPOwcRH z<Z)aYt5(Y~3A zUf>QKPFd!Mt%Yo=R&iEogz-u<&OkB&Kbnu0sTd_0ehKyLdMn)1p0@4jnOzHHpO9z4 z^h?TyxMI`yQ{BEEqwH&EV{{csw=cm+3K3-Ff?5QvbJc%u=l-3QI*%=9S6l6Z@Zt9k zD9zanb)1BMhG{e6An6G@sg%-|6}h;s!h=U`i1fy__G3Qo3lv`s6=TOT1eK|sDMBxb zX`k~*M|K-|wG3Mt9I4Ky5Kjk|XO3u1x0=d3hamjP_7_>>S>6siz#Xf+;^ow6R50xM z1v>d!pFSL(VN@KEQ6Q*cgNQ_Hq#qMA5P_(d3V;js&UL|k%$lZL`j^%IkAkt9eH$xT zL_yUyj{+@=eAgaf)_9l*>3Rp}Zr z3Y~NTBt7Jf%8HD)v@tNBhr)3|WQLkF(7<7IxV~bQ3 z)t^hgQ(21G)oE|O!b2oA9y4b2(`2u3id^0q95~-G&i@sd{cjX*V6}iw*KLlbw2<6T z3`E}}XuNHD2oAR3bK{$jD#i|)(!sVdaSMejjn@(o${m;DD23S~3fjMbu@Ow2VZAds z7rzM-$M)aB_7K;^jvk0#U-EU%jnRM?uY-W`SL)W>qHfkW#%CX|(oAt1+0?Q$jzF4mpabfRZi04|5VDes3Bcph(PntEvS0i@hU`!dD>kXHKa#ezz6 zsdGgsB7@&c-ysUKWs|ZprZmd#%(%? zJtx!^?KR2iy+!48BO{vKh@tfLC$Gf%m7+?|81L*N*=|{JSZ9Nz;}LCd%7Eo0=JUC- zcNR>HM^DyfiDQ8rTA0pHjHvG0UKH)ZZPvr}N3A&}{iJX$Dbc+_NoSuf9s%%?0LSgJ zT7VjM$V&H0gC33T(teDB9wZ?2u*8gz0-?tUf{}Bg(S5I@`ZhaOiTCFUu%GF(@KdN%5gaT#mk%w3DFB( zEcTP(h{?ZxHX4leVxxuJ#2=gs#(&BFoV|0CSie`3RlZ~&D02|=H4@dQoc)#0s9A^4 z+`eqxbfStnJOrpP$b{Kkbq}`j?kDNz{EBQ$%GyQQPaeDO(jV1LiK7H&`)REaKujky zeBZT?#BJYO!J+q37aWKz2>rt@i{6W2kv#eYO|vBntgiQG&MDBHFCmwrO>zWW%dUTB z=*!F)&i(%F#d)Twi2aQQvis>HgZ)W*qkmgV{XsYiYCog^*7AYr~PsuF0q?#O1m+`H3Fb+G4;s`^tU$ur| zv3u{5DFm-C_!L~bjf+hJvdA0GP32S`R-m)6J&#jflPk&_eZag4;nB1-erlq(<|Y*L znVSbn+XQqANdRxtW5o7iDd79+M0wc_PVM)wX&DiY0br+3b5H7u$qm2`7F|#qMs=CGn{$%kwp572M@r?Q#BL%|(W*}X1O{~vLp;7PdXrg7CU zi4`^0auYcCGhUsj{O)@Z?~Tu)4H%`!;b#jcYtxX}R{FK&T{t@BA!0x}`d^-iMU61p zXGvoLN6b5EJ@XqiRMOEHVJc;*|GMDEZi&%gu-td_dI72=rZ0O(|)`0&Eg%b z{`HA_$_Go9J`V<`wb9e84B(#2tY*m!;r}CbAC-8NZnT}V97!!yZkmYsuqE-@(kh3C zWXYKiUjW4ma1N7qTQHF)rr%k|s)DU)v-7S=Z|()c;< z1YL8`hCr?Yi$@39yDuB}l})L6wXp-W9^-I*>_8$dyJ>top?O3R8#gedwCm!4qvNq( zmh`3m!a1pL!p)V<_H2{xKI^jo9GRRcd>R(~&I#Wgv%L!Y=jE{ivXrW^!+AK2=<=0`4vj!Gwr zAiJ5NuWKVz`)@On8;GX%5=>D1wi1U&d+x+`|E}nI<2M=ivz~Gq$_h#0I6%!p0}}^7 z0||uGccz`)Cx5fE@?9RsYsxY=!qqGo7~{l*&)0hSa}K)%AED9OA(`pnQ|)zOF>RYU zg-o&N4xEAb{#!N9v3l3EnZ5^KE99KA^hKmWoy)ph+eethc@`ls9|07KV?(Q>#4&Fg z^+fG!Ji|7hzCh7bHz~>m7e@_)&!F9SioVs~MAF=FX2B#&OW{X}?(g{Y9zbCvD_;vd zUtZCXQCi&W4m(Y4aN=1z=E_41#pt=R2Dd)<&q7yGp4K~F*wC3-MA7ND+vE>C6*_ySUWZk$E*e6` zM6;VfZ=!Ze=Kj%o{UDOR(i7ql{WXNA+H!8-Zl;YCX#L7ST<2{g`oen-DFmPncGI9{ zKKD#(7!#xBn+bh+w$Qy;#lTj+9hSqk8t1^=C=?O$0ryeDR83=;a)inHx$|H9kh%IgEn?}Lp`V<#^9|70%amDXbIMMi{tjwC3p0>@+{ILPT$9EnG*7ACsYv4kGNqAb-& zyc_&G$@A0ZYCgdOKumB?YKZa~^3%y;RprH|`$jkzEK;c-n@K(>d1=WFZr&bjb~G2I zCp8>ySGoO}xYDX1ju{bxFvyh+b{%}~{yJ%3gO1kr!ABkxx+$V97z%I6R#2!2Sd<`0 zr2)uyJclf|Sk^TrH@KZgryGN?i02tD(7|o&iR<0rYWS_+vop5}wN#v>?XHnaL@YK5 zmsh16P;iEsmSbr{UFJvruB>lP%*v^Xj76EZ*aI?z(Fk%wPn=#zgO?5Ig$D2NDc zIqPO+PaR@<_t9I4eQ{r^;KEBjAn8mUyY>%kLJ%U}Ej*S@x_ zsl+gqL zZ8OVT>}5qQa)?{Q@5M%e19eG;5O=L)KR7=_B|LZSmN~>M&c5J0*}vFflhaX78&hcc zXXy|XlwQ(g?Hs$}{U>ykzd8gn1ZY51<)0XIx)Y^gwyKUm3_D_srTVC?pV_6}TM=w= zcrjD+HF^iQ_ppB*0euy)1?TL4`h&>su;|B7gB|NZ1* zjG&=8tQ?#r6nN9*h|FEOaKX+RPzstJ)-olSu}<}0Fv7K7Jd0bi5SWPm*!F>H!|%`z z|Dclj$fSoVo!`2e#~L9mPh&f>~~7c_D=QSvX)ykyL=}66y_l@d?Qi7O304R z&EL&Z4ZkZlVjKz|;tJ|#>c#vOK!m}Tm_0JGlB&D{jH7A_>Jf1^9BY=3!A>sdt|*mG zg(^*9f#53x+(DS{e``~4`$q#SjJOi)iiAN~+5fWRyy?-AM9nD0O;86O9X+cD%1GR0 z6ay@M#YaxACW^&(aw220J9AAV>`MRJfi^qE>#{sg`jNWHGK<#r0f!yN{6^joBFJ=>(2IZGO6=^nJ-!I33${!sKx;G+T+T~zUoqFf z%EK98L$7=a8WK;H4F6e|}|)t3L1$9Z#L2!%I_b zJUNww5x*C&VZs$#b-0+WVXRi4SS4v#F`JsX z<+$D;;3#o%tq_!r3b>Vc25Sh%O%zG?UfJ*N23W(Oe`JqYAsDn>guk4d1gq0@~fHvxYFMzJ=@ z-W7uoChYUq0ZY1inC(m4O@V+L0#tmWKuE$O;>s9vG;-Ds!{2kE3&^ZSuVX+44G2?9 zb|>{QzBJ1>VQHx52L-X4JdgFocB(6lx|K;x8L_$<^@h)>Y>oAUa~qfH33pDuL1k7h zWzah+vPaifc{I*tS3&qDX|Kx;NRP51*Mygv(*VhjaTrC9>>(GQbdOoIxEGIdp_PUp zLv!What1z)tGo7jYI!FBP=7G;oe~s#;j@R(FrqSq21l`7ie&OiatA!7d|TLC?Jjr{ z9Q07i0SJ%84<#UP(wj4p^PsU@217a~$VzGX4fpA!Qd>(YSB`SLUr}r)8Ca-v+c9Nc z-Tb~M7;s^<6wrmKNM>&}pgdX0PqhR3we@`)swF~vgP_4GYrMCMT7Uu#xUsz`h1q3x zUEE{S!bY3m-cWAT_k8kj&LE=9K;OeJ$!ct*bHVHKVD~^NVk1oPD}$KOpVV)lAsJ@D=r%0zW5%gjg8Y-h0WGR-}WjSS! z>kHtK@|`ZD@dd@#eqMbaaWWS%5*@`dX(@8;Lurq!ToB46>-&ST8&@{_M9k^8!1S1M zpYQWI?W&EUWFcO(qJcZr$N?PfKnkhVg~#Ox#_*QnMBJKQa$u`t$WBpcQb}cFuD8G z?J0!Gm|bV#no+0h^9I*3dO(nr7Mt61z9Bnn@UvBjp$_m_#4G-h>4hz9i%672DaQ6q zr(8eT=}&LdaBOayVgkq(iWgg^*N6B6hCH;W z7B#Q7laZqLgk@I}*OZXdsda$Jgn78^-OAh48Bp>S5&bF6H5smT=6cAK20Z(B10^US zW@NncSpBaItmB+hl(OxF*-#=$3ft)PFyevV(iztj#seL0^wUH}fobsAN%&A6_V9RI zr75-{WH>75NEDe>anbWZ2%fNMp?}17E>5lzq5J8AGgl)@3&7b1y8)28;4fXmd8j3k z0mr1x%s_f<6-r`jX>XsxK&J{|n&36{#Ez__{30q0N@6C1% zTS-TrX0%}6w0;uw314E``D!Uo+z&cYRUR2cf%bM}<$hc>a^*eJq@~xZ&}bDcIzqwi zM9>R(^clM-Faq>|t?m@YjoFgoE|tQ)W6pN*0}bX`Zmpe+y1G(W!n|SJaYeh@aM8tRV?*Bo}V5n{j?^1~>fbPZc}(ftj-eG2uOUvs7E zf?t)P8AF)m*UBDLLV5ecx0Wv}PKgo(Ye5dMWa?zFUTySh*U%7ONQkN&A+$D&V602N zjUWsO;YHu#IBiiRg@Bx3k&ierXUuR3iXX%5;ptIl-G=&TW*Wy_B{+Xx9Q$MJr)h5j z<$Hfi!23z+`v{aEY~AJac~*^7Qj*!pO5=9b{SE6}xsTUrPu`T;gwk)+b5yU^oiv+) z;()m73P3J}UrQg4-}qEJ;{WS| zBCw1E8IjPv-CP`1OZDZQRn;4iK3rJ7+uuI}#?yZ%G^cVT+X)dr3$t2#KDgnL?u^A_ z7;!oJ2_EG6sZ-!Vw~~zgMP?*VGjh84iU_5GReF;ID%ZjwtEhU;Vr5KbQ}j5AnCY-B zuj&7~GK8$CT)m^`xOj>@E-B6k=;P4w`t$x>U3cvMEB*C0Qdv{xBbEv(%1cl6ITZkL z;S-uuk2^dO#Cj&Ha!n{IGl!{aIt&p!l#6PtyrJnOLQM%02#LneU(%ROS&(iYga9Wi z{~rIj5rUv#>+lAbYfFoyhtA#qGB;GtshL%#_ZY6Vx^u4BM5ZQuFPG5})$jWNY({6a z_knyg)mvw*l+0X6K_uKz6xyFn{`tARvL=Zm396b5`z(w986qP zxlp!v*hhgG*vo7I+a$%Idie?HEnDE|1Wif)eKIc-&)7Gq^{QNj563q!RHV{o$w}B^IM`~GGlA+7=+Ri+ zEYc>S_xnfoG9X`;o4KVdFNZV)yhsKMo56nQio&#qW}Kf`M3tzIeRxh9vbTEm>V6gW z@DY0r$tQ1swaEzI5?nf&!h0|;j4168KGqo?Xi2EVUz9a6PJ`!yf2G)A&aoc;OAAPY zCcjU!1cifRY&IooDLGqTXa?{Avd#w9gTV>7wQvAbVBD)DH%%PInD-gsj94#tI(OZK zFKZy;9y>pk-;I^}aGkW>L+Ve}l@BI|wLJk)(1!?^U_5)^*`!6jiPXdU&v?yRr;S=~`Ce4{gN(K`o%2!ZuHL*TJ>nKJ$Pj*0uOh3&X|n-S~s zPZ19bE4{=3tD_QXk7%zF*?rSmWmC~#L3t@w?N#BpGpZJW&<8PmVd^bwa-Z~fl7JEO zzun7v_=Y1hbH>A~e#U@GJd16>(TeMi_CP236xR5+&VjLy7F**&m8v<7-o&9Yp z`T^*#1C$yIo@;|WXcgz%5^czoBAe#i=BNe78isPCL*e?w5HkadfJE#0h7CCA{p_f;*Joza@0MrOVlU_0($r zB}>&NrO>Yq40k25bzrdrwq^z?;^w!1%4mz#6dutB$46WWA5hc$Y&tF_RAQE}19<8U zDod9d^Y0j8y7xPDm8?E2s7`l%T4t5*vE~vDxbr0}fWD63 zW|aq&LY&cQi&t!_{X+mPLtEUiCiiG(i&(FAsn==m6jySU=)A77$at8fnrw!3JJEQ$ zh1ACi{2A;JjMV=pbnB{wbLRe!Q~<@EBc$l@;^n%Kb9;DTx%-?l!B1A1S^3@BtR;33(0K z_I4lq=k9>DViHJfF3mcqfCi(p?SVIwuIfRy_w%!4>J_mv$$KR8zAr^T4}3f%pE(

    2^CG8xj>EPdY4iDEUi*InBK{E|zHDUg^y8fo1>@nbD9I zmgn=TF~q-NC{h|P_?XlA@_K}95byu9#_}CHX4H&cJwnI`u)a6 z8NL}!;hFmlv@(b0yEqj9ZffxBi47&A)c5-`g8ZLL%y#CKB$Y<1#Smlr2@tvmzpmXr z$}10=FJpGv@FTOc)fuwnQzto5Z9_1;x!Nhrw9E{tBcVpz;7;)Ro$u)FhoF1%(1Z}X z5M2Uc){HJ*!qdDYW!rLg^0ouO*L{Rs=EAn1KYynBP>d(ByBFlpJpU2|Olb|SEVM!j z-3i! z5EWqJiBJFOL28W7KA5z>sIFlyn8~X1#X*w;9JOma`FYtnq=iXPJPOBdd(|snKnxBq z7S+48EuHCwQc{ESaZk2U*<6r18BB1I=1b_hbtj-`yD%ioSQiJ7xTfQ)y%3w!Gx|OU zui_KEm=TEG^XW1#P=tR;#M`SP>nZSwq(-kG-@%FSk!T9y zh%W_kc!??cp(^RL{;<&-xd6LDCroJRSOV*IexESt8==7`tslNfR#aBfxk*?$5{F#& zy2Td?TVrEo^`>l;c^Q&TafEWr0>Qm;Cv{{Y?wa>w$N^$U+-Glcis{xoJInF%be_`eI?m0`%;+5oj6NT=*m|PNH?7&@;%c17FH{!Wb_02L1`hEyY9Ya4$RNA zTWJ>BJRNS-`Fqhhm~tPq2d{fDih`ON@q-KpV)$i$Gb`|Q5HfBkZKH!!NvS_NpW4;R`uK9}EmZ z6vD~-zS(t|)$DK_EKkNS4X(f81o%e5VMPlrk|m*LH1C-hIN(eY{IgdFy&RwvdHL=z z?z!V4eDp2AHI-}-7ciUm0g(>-jzwH|Y;}M3iDd?j=@fV=P|#fkBqDGY-uwGus#Z4h zS5GF+QcyJPdE>20o#?LmH|i_=`#R+hoa_04#Z;gxJ)6AUN5l~ii-toe;b#O3&Z}L$ z!*0L0i-Jb?@iP7je2wXdO0e+r78HV2-;lkY`|QyHd&rQ@I)!ID(P#U-UW-z zF9tcLyb1?zhEd0Eem~4)=DiGZnrGS{@&OPkNwOBR?Y}`oX)X06{@eH=pfXD^wPZ3p zMdE^bKC9tfP`nELXThuCD?_|;lA|siOHNx`I}EET?Kc-Fc`PR6>**pp%=Y&ajzw6n zQ(9U!KP>~0QmIw*=N<)KGuJ4 zhqmruDgJvj#s(>>=!zEMCW2^mu|RDHa>X|`HShd`e-&-bb7Wh4JHVERKG`u)&0ZMD z6=@7_h*n>Au&C~}1SSf_4bcd7W>uCR_n*GRNLNk|Jfunw%EiV*nEM{#bKtPB26a>Q zIT#XI=_?mSSER8UEOrujdtU-y#76#)MKrvmO*=arH*Ia*OgsRZqETzL!rm}6w_`{Jz1Ob)gm`! zbner$)PsX6^AxxNiwB6G>n6p@mleAWlqOznEd$m4 ze^vA)J+|ED`9loYw$G=)^L~vNVB2_(uJ9$x2wR5BKMg`{&MzC%AMT`827x}oz}|Tb z@~#w=cdM~oOj4$Ns2VPhPTFu}RI zwkzpD*IB7D*H9^(M$#}ws2b{C^IEgv`04#PDvo%Mhaj4=c=v+3Q+8hGdO9QRx*iq< z*M>yI2Qiq6m?opF#;O5zc=m6muBNa*uxVTZMq8i2DxEOEbFZdLml$k`$qeE@d7LF6 zi2+E{_l|;vqCW!0CEBu_$8)*{#hmxy!+Wb!cO5uFg2Wka*F(3hw zRggPWpfcYD(t#iw90*Nodj0|(WoXl?t>p8oYsV?k9%t&vhn)tm7ZnJbOWpw`O!wGvhbDB zg-8)G#z|k7D_6d`Z$iy3&OjR9m*LpcGUVz91ymM`aRwlya%%a83SUem&p>sfTW_)P zaO2MWx}O^w4t5wOvXoXz>AN7OK&-f)&IELh8cC(18j%{}HGOwO6Fimo&E{wo$$+;< zx)gUrQ4do45&U*+&8?6-!mQ-JliDxKCdc!D=av(uW2I{1tDOVvXOVZ8Sp?CrkamU! ze>4-02&PHGza*Js>xo?}hFkA8TR%F4ze*J!^wKrR%F20fjD4dTLH_`3oG_wk!kq2cP27jz%mRCR8Rh+$sxEYFZC&Z~Mlp7|imAY)-2MmTfL z&~XPl^px1{DFwypS;WaaOo_3rAnsFmd!#QNni=~$59#0aDj*F#+2(M>=)G!x9*7i~zBvhD z+I*Rdutjw4M1Bck7c_K_Trvk=6w*>t|kt>ojYwC`zs3#huu=OMBWCplUPr5GTH0hEfTFt0>Cz_hk3d_8 zq{+vcd}2S-TP+SJL{7e7i!sE!y+})^%&twdU)NzJ23vPhIj={+*_S;v^$Qy*HrsSh zniY=bAO1#JoQ(=^HGSl#O%iL-%Mpg%e~QSHH&%sv(oh!I8}ymVvNig`#wloo$d-`G zzxF_jq@D%)xggn#`7drcDP5;F31d#93!e1fXq*<|h+HDw^e9|(FP32gnmRG*1|f$U z8IAha(zvgaBGQ!@>9DEdMKp9W>q3hH08~p=wb_N==c39RPk}4kq*b<)-$MU0?Uz1_ zROUcQ+x1NBOo5{M!@BLaEA!2F#ZW|=9WH3StZL~Vq-8_p2b&&IE^}VDK+a1xLF)b* zcXM#+dpz@XX4P)xS}O5ouElotc;j%Pa7Zto*f>A>{{SIC-oFVv|Bdflg(WvBguFEa z|LX%o=1Q&aDjw$7@gDO7r-o|N{ynuHN>|-nAG|+CFomV*Xw&f4G+QViyPPT)&1c+WEe?WDKw8MND0J+CfoCD6&9 zexh7YdO9ux$a+jUYB1X5)aBdp}w1Ls=5;c|o>3?7iv{^jG<#advtm6WwL zv^#Vw=mTH;1*QY-bh~au%zQ*He$kgQ=-za5a>M1Zc|)AJa`r%QNiuFUXCc7pHNjo6 z8@CXaH@c&;g;QN@+RYlA?CukoP*~rOFnDTy@&?U$(9JZARego?_{g&VkMGm24kM9v zcNCN9Xi=a|wbA1n-e-exGVo05mpjJX7`}OE{RMF@G*P z0-xB4Qd>;8;sgcqC6**PR<%X)qE7x#tyrqD(!&%GY!}>AaEPmU^Kn?pYcOpg-EsO+ zfa!_~hgJYvtU|W2H|w|Yt}eoQsurBPyB%QPjP+#Dd-49|VD-+Zv?0!hN7xoZrJ=G{ zBH!G4z~=A``~*7S>;(Z6ASkD@trYBHpHBfAjvE?bxye8i{p&Ofe^RJETR<`s*?-lP zON-Wv54bLXPnH|VfKGyu{bURud(zeXA9`kXU8nJ|%S3flH$}nM$wJS^v#c881%y@Hf6I-&am)QpD-GHckpWUJ};@;M*mHd&Gf>taQ!`8uc24J zd%_c=-fq%SlDJr=1kqr^v7qtH$LfMO41eCJ_K~|68oJ-z+!&PiX}%^;@)nobg#1CF z)(Xp4S+rCHoL_#7*ya0^MGc(U-{SNUS6DSzzjEP`l(!v(#`Tf76?E7DN1 zoGO9DIS&jzDie*&krPu74pLDUapt3)45Gf3YHH6%s$Lf+ir7yP@V`JDS_US@HP_BX z&Zy8TiP9D>>yW}-BPiS;2jgrCev3J4d(2QJGI1*=2p$ zM}NR`w%yqD(7A=e5MUH?z;rB|OkyZ#pKIdHhw%XyD21fsT#*%w*C>zw#2TvWk6jIx z!|U!v?|QzKJ~PdL>Q1(f984uc&=M@Z;q|$3wNLjg(UQ=p8N&1)w67=@F!wMfUgJDr z28S@iZDfovdB?A%xH-OEHp%qpKQ8NBmwIz^O66 zQ)p}lc^Nd`T$zb;W%#V3uWmE46@g>$Wo=0tT{rYf19tkrPVij*7y(9V!V7sq>oF$U zq-m0}!f*C?rsG~OBy>8+REIK6ruz9jD~7>;`8sZ;PjakS{MnE~CY)+=|5-hrgC0aa zhwZngY_wed+2Lyq2+eE?r{^QwqVI_lF}ombUMQAon+m~6)-Tk2Qy?B7ZtE*R`M1?` z7c_!1*`?zPgVled1;7 z8s6hN_7}>TahLcIsS6`gGI;&p60|lgyHW4oDP<+TV3GIy#{#yQ<{7`jmYkpif}EqY zVOM%U>kIYLILZk#uJ@ItX;E4`yw;#_a}+MgNg*-9b9=R+ih7vOCB~} zRGb&Ykt|d2K-Q+v%l8})Qxgh<8GY(chHo)3jz)P}mXi~=Jl>zU|*$*9Ow?SDX_sQ;$! z^`c`_2`&rWPFmYc*D$6cMA>HYK90l|6ioR(X!Z?KN><#ctyw|t3hS4XD;jUkO@2Hb zzsZ0Og?snwnH?>v*!1vTvlCa9bF8oU zYN<2o=h-Vuu;~4R?aL2p`T_>>z1~E!)^Ygx8N?q|ZwfZ4(5Oamr zOx@oQ7C4Gp2g}wz#rJbZm}mOZj)A5(PnjoK<&T&5W{cknq=sevFos~ZgdLVB5#tIg-ZsP z2T!N=XU7h$q*szYG8t%G|?h>5X;7+{k9kkpo^uKLh!B_4v5IY_~GL@)sob~l{T3?7I)E#8lzspB-%D)JQq zu=2Y@Y?5LHo+sZq*7FvgvBD$$YqkBtW+*8!KcBF(MXYiS6(s0KuB$r^h#1eHJ0I=` zF$XGmAp!hg2s&cSgh8l%?7C^P@KymlPZW17^_!&7wD!h%X#~M^!HLwGcF82w)aTz| zTSLDGMUc(rK{N**IP>3kmU+8Iq#0&t6QkW~%#Rw*b6psg48e4N%B+B>-_hico)l#~ zZ2tL{Zdk`^UPAPG0w|4?5#e<{z7W61&)aMhUi|VV#eaqJX3R-(KDOr1aUJ~7GoZsu#ZxfUz)J2 z(q=EP3*cLQT#f54APIMTw-|Q$^V91*99w&X2_)3=lxy{ZdUfF^;b3`&ubb-o*72)t zZXPp*P$z^~?h&Bx^UW(iWV?dQ-~fnDkJd~9^9v91e&frNme|b8FJG)6Y|kq1ChGW~ z=MI=F`05ouc$hgUe=McLeVk;|wXsk;p;hK66iH}pUK9dKKzgIgfV874$1_~M@5Efw zm5MgfQ@*{Sr_K+(H$>TEZoA1V z?F$Bx9-Mk}mBDC5HrsuXnb*QkYIt9E^P4|u1z{Zh#eWSIdqr{@T(}k`yXo(^HV9tR zli^&S#~@eH+LO!auvNn#nMka9>$aD3t3L^4C@5XXzaI{E49|twyIm0Zo(Tjr@|qcc zyg=v^F79ui-tOE(wS1`a&Dw#TEF24vo2r5yOh~C;$29G)U(HF*Cd9PydBFn<_A$W! zyg2TAIlbxe>Hkr+4z$1j7aqLv{xU=SI;$;z3YD0Pu+Jr=Ls8+Z!#jFYQhNaCn5V*| zy6MXdOY+Jw;d2><44n7+ylj|ix1@Pq<>PSff#{$q+dSi@&j1QQW{OqU;#8GNk`16I zg7pZYk6_XMVC8Z*B9Vz6;y}WRUF)5PAC;w=0|Tr#TqcprxS&9d@1X2yhlPU7=+`h0r0N*2Srejg zbr^k&TZ4(U_nvqZ?8

    E(%6cQl-Z7>0_v(klS)a!+G4j!BD6HBTl#thixeU+DN_r zM8@XKJkLt8!I@N2KBP9RQoxOhm@&u6ExEf1=gPT8au5Hk_KM|huS_v-sHhsuKjZr( zOevS(ZjMBi9%*+SHhjzA&5-*l(O;Q4J0oJ2ANw-n!NAFFtE8a+Jh3fj!?o!EoB_lR)f8^riC60hW zaANSleTVKkC!Eq7tbBA4u3?G!Fk)_YKFEf~=7s;6-+R+h_6Q`~F?cEM3DdpU8{0=Z zU&7T#Wc{n+rF`#Avj1Btv0D3oUHs&Is0u4fC>qvw^&l0;@cOYjLOG00QfIHUm_?Z; z1?4larkAD9YZ_$rOV*HnCr^Mfvl~ACoh2LSMY8~2Ud5=XF=La)g#+NY2Tgb^QinPL zM-A2T74O&FlmWIf9o`UA5cdLyJ1RSI$IMJh z`T%S~^SA=x2GP)auJJCneAY0!C#S)`;M1R85&8po66v#dtD!=4BG`5Aea{AM|qQ(eEJgWE1vR)i`8QMu;p^-LuLe(bg!FFxZA1Q1 zmZ2f^?Sa7ehfL!KGyPsirKJ&a20CuMPSj#l_9ZU5-@@p<`pQ3p5|8%gc6ybUT^c7t zvjP@t;2b&*pI!R9ylqWX%R$zjE0>0OW%azCVtBI3DRoTa&7&%Wn@DZfW1KOmI6t>; z1^R}JqcS_{tmn|v-$u1;1oG%_G{#meFu~Qa4geqYi(#TU9ibcX<(*ay)LXP6MT*t1 zdf=8)giA&Hrpr;tykc0cV0d>m31pd6aX+gUN-mbD14bJw)56 zcacbGIxoO;4zyd__@Hn&evfHOm`pcD3ZgQ|nCw>s*_rcu7MWv)@}z4oJgHFR6U$NM z3|Hx;uP392T4goWFXu%j=%(07F?d$Iu^Z8Yf;afTh2Gze(W_xjD|mb-i-)Ar8ipUC z9+jxZDG9xo=l_-B@=CiykrKOJ&3W!HPbFPd%)+X^?XQRf3COZWiL?Q`=sB77BGi_@ zD_q6C^;2#$3sCpnZ8GNxj?1BB6IXX!X0aX;QAXz>F7-{=XIf!JG9O4E^I=xulYPUn zGivIOxbK>$UDe4$Lp_y#F(gTT)vf*R!|Jy1;ipZX6@wm8cqZ;=@(xKY4ON>a6iqcr)c+MP-PJWYK!GW46;sW*Ra06Jc# z05XdhOTTSw-&@J{J3v>;I<6L=ArU395FtRXyLC@~1{Qz+;Ika`#?vA@7|Z9BPoYg2 zxjaljJEiMB)l7aDgIUqfT7#n#gW?RLC9AG)LtiOj545V^+P`Tb6!K#2AUN+8Bg8$u z9F*>`ux6wVU8a;oOcIer`3(I1(hvGu;kd|_)*o(Y+Rn1f^o#@l$~c5}ske6IpS6{A zN^O2M9Ura?+D*JNx6^YzF458ff*L}n#}4ilHG1}VP457DXc}PFYJV3V(+_2p!w3wY zcyZlN=q9*9Cym^Aq2k`3#QjNVV0-;}=xYwcQp&E&8PHafBv6P-ge_Y=0P^I<_tKPT zE|bw=%9b<4>_#!#0C-`b#=lvj9ApVAw>r);202uq5ht7j^5k;K`ct?(0tT+Y$H6@U zntDus0`OU8Wu|^~@S?`#;JYuwVd^ffOL(A|1GBD05a>%Q%0h2nUEMHu2HXi-0e7xK zj-ObReIZA{W5^mASSp`=m%k&h`*C(Rn?4`|@8Im`U=H1IxgkR_H)7?c+{&NLDJh!> z;$Hd@@^f>ECr=Nc)n8k<1-h5vP3PV!kiF)USgQuop*e?O#=!^k@Fo#vcPcB?8ARZa z7>L9s4w75Ld}?t7J3Gc1VKr&#&`)*{CfZj99<$k3tV;wD@cBh@?Zwkp>sh?wvOAg3 zkT$a5O6YSlSU5bGP6EIN{i>k&*kSWwDPVG|<`^O8->eVj?MU6*F$ zzK~4AHRA$h2pWRKj_WG+-&`M}%s*q4lvB-=)jar3tG5G{LnO4sojrC_`bN^~4ki@t zy5t`YuWgr&)6ciB~BihT4MduM-ct%T{TQaRvvKZ5q8ON>lld~N1=qHcFVTR zKO(|Yv{blndr)VXdP8ajp2MjH_qz5j^*4=V2$>oJ%Qs0BHmaJ(wc%*Efn?B2Rdo|r z-!)=W|MDcJf5>;KpxLH#1sBEfMsnnY1;U}cQZ;1l+XS|lQRS>__OFJK^o?*?+cD<*+-`xxYTaC{VxM{h);I)yKXF*($7h|r()F>aFtRQ&h}XerQ~=}J+wJX4He4+w`B)g4pr=!;t^WNubdtfI>igx z@4!AVCxS=xAdXT%0f?7>s4ufY{IhF?IHekpm0~?#$$eLd3Ul}tPVn2@EHj={Nt}2Z z0w#aN>@2?ChvDAPh5?TDaeRaZ_7w{6($_YxVQ?4z(Za# zba_UJBh)Q=;OoWMo(kH)0YV+cNW+E?a*1AvhsHH+D%UwW)3}c5!vDtd-}(D{vcDf~RzXJbilEd7Bbm&+MW38pa>^D|vsc|6#;b8WOV4wa{Q5 zrKZFF7(D3L&NTfG7-uNpT9Tcqb6eEInE!)aHwn*J>jNpmA6s(OsHjc~U;XP8-V3-+ zQI>7-Ck}Z#9$H{?stO03(-@TEXj?eP%t{GmXJ*poPe)`_GVZw;84XL9a@IW5tj=ZN z2hM-nvC7?o=0NMY#!xg0{7LI>+r>r zZOP{7&bcP7DsJ7LaA{ll+5v%0l^u+~1P~J@Ta|)OM>28!8x9j#>P!1`WXCyR%-L-% zE;?H`iAX~`HIymIqDGJFp6IEX@gY(Q&m0s`SN&;|S;sYt(it6^3;M{RJygl?+wzJN z;iVNdB#7i70P?=+JcEXvx}>lQq^h@CxBhMVz81;{crFXF!VvL>PcSVE*FJ`t!rj~i zmijRzeG*soX|T_vlYH=*eo-E`TS(aRz!~O*CL!(Yo4>yK zd#wvvc-(`;A&EUsdK$-D27_HvsNB;<^=Rt3=E}U@OK3D2!U5J?_2!<_TV?1EyvP}7 zheOgzI>p?z?|MIBEZFuv?ejp)o-iB#^5s=#hf)e-$=K!H+I$w=6ILvdwZRph&}NmN zL11SX=ymHEZj~Qom$jN1L5-b6ySNH3LxIH&nz07$R5`qImXU_o1cO|Wgl8c2zhO@# z!~Q?UR#eQb$;aO>de#a2MPMF3vVe4O6Gi|F8SFm=_}-Ox|0)?qxYEXnOxiFy?3p~w zMI^=Q+W&N-ZE=QUIks~D?G0_PuCpE6f0-J^P@TNtn3n&Ja8Ai<_kQSuKOETOns<|) zjOE`{ODS}ZE|`+G)rs?Mk%R35IA&s#*b(}y!>n*-+_Y(`p4H<~VuS+oa!`|Q*oyD$F&svHC9B<_=})A#EGz)?ILPE&+J(C!1!a(O zQKsCbILItszu!=#)Vw6?cmIAMed^12j940NGlDzr3%Ev%(WI7=5m*szPoWCAuul#J z0)`EQ8H#^?znkQpx}0B25!>e+ut~K^*w|V#$wn>$0gz_(dgL!o67+?A$}wT+hFwtr z!q9LAz8P^2}4(I4slGvP=tc#g>FOZlDzRrQ505WK`;dA2&5121H2G6X1x5p?bmpzLtx9 z$!a)MpK+mLFB!5UD9|nhd?GLpEWHW`vXCFu*ikBmI#8)40u10jrc0FH!iTm)3lK^r zptTZr5AjL4ITVkL#b1*IG^Veh35TUp@UN#` za?hzJ{KGGd37G%&E(yvQuAgUzhkeR!P{*kX4*J#|*Ke$;mu@Wt-Z` ztrBBX&Ku-cTAA$%%2bnS*!N^VLskkepDG@$TqQBB1)kg$gJ6RePg`4VESW#CDjZE` zHXjYmLD&xUZE|rlNXgp&G!o8)_vDzKn>=xBqc{a0db@lwsrskMT8v(;3_z!Y%LGt5|Agxz;o&k$DJt$Z5n+WeItx- zHIFxg-2ROlaM%d8$47-=wMh8!tTzHjEXAVmy8O809KWiS6niik-XG)1(sEt78XYah zH&F}(Jz~j~e{U9|rsrqLKEzg5j&hA;pv8Uf*r`DMbvYUlC4geD+E+m|%v`{n4XQvZ zw3CF`{RjsKe>hhvit!B-5)&hzHnI<4{|X}k+HuGr@Lc_?4`wbjS_VizlUrRIr;i3{ z!3TV@5QATjtDUrbSBux`jAs!rP>1PT)OJVBpXX{F@GW7m{xj;zE@p78fyO_Dz&t^W z!Llu#5A-nXykSy;-(sONJ`O`|H=W!qT>4A)Fh5l+;Iop8ABuCJQ&c&CId~eMQ-vA+ zBJNJ|W0A7eO8l2OHw)_s;VMAe{4M&EWd^jlR@z~FPDB9f8awZ$A+@$dTEQJ`L%`IT zw781&`)9@ey9(I=ijhmA>E&GGqSE?#9~8uRp+hrexO2%0UJ~hX zj%Dh)D88ibI)Neo0P*%pY$+-9e zcxk{hm;1$JM)pd|MqNZuEuGU|}%}H3t(WS<}A&ffKwO zUf!0%yUh{R90oM-Ez?%F_P(+6 z$SRI$5%X}o4rGiS1ORJqv*P}xd2w>ssa}h>n4yrGqa9yPKB(*ef~&h`8lOOa$ucfo zB^iR&*5qToyijDcI+dQ$PFn8KuX4h>;-sXl6ddYW{<=WFJ+~UJ63vxtezh*lsZ|BC?HI1z=A$V{uBFeovmXUShGkNj$oG*SJZPZ#W-kPw{yno~I99>& z+O5-@5n@qaVHZVnyRHFeY$FIz$Gg>ZgaF6sVNj=a2(<| z=Dt4^k3llc^?bv_#{VoaOgju@*82{{?F-#MIa%^6>#Ps9#cnLpSGaN$l1-YqI7YfO z#TKGG0-cE-eG?OCTtDj%muv0Yb5LyavWHN&Lbh6>e&W@)zW4qN-~VARYx8k(mAiae zVsL(zvg*=KThV6nQl>}*yUFd8L$OL~1k)#uZTL|7!JQ7fRxJv`5Mv1XPyPqJafEa( zy#<%4x&hbf^?`t@yOEc6oZ2O>Ak(SD$Zi7KSuCLUL^-O8;H-Wf!lJ5i3CfuV<@u_& zrR{wu&_pz{6@i2vg(`jC=$Oms2If*Xfov@6J@}x)FlIdym6`F{JJsBig>*RuzOt<| zm@Sas7UkffnDi{>A0e4Qt!z^64{qxc1v3@1=>S-za|%L|gd>|C*ZlL>A+`M5AXY!s zC~-+BqROI6!H8mZy*Tr2>q}K!#uGhbe^B8{1d8`)hM<>(zmo%F zoTy_+YjTvSVzc+^CBJHVft1_yVFQ&kwWnzAW~{H-H|;7i*TEr6Lu_DdVtjQd$VM*j z^C~$(48F{9oj^Cb2+t?^2&o#^1K4JLvcrQJUP7BzARq7 z7Z}=p_^SNzS}W{pqD=iXW5t4z=>AB1+FK!3!r`7cnQpI1`6`$$P*xiw&N46V(Y^Db zXN2OeqisC^P;l@9k5rmP6KZ1j#5Vja38|73YTCS9UyjJ8NLSGUK3VC z>2`f zxy%J;@upkD0AYPT$k_=7Cg#6H!O`w?3hyp(F=f3*C0;3JyqN8zTBpc32l&(j3jfF) zy_1I10>q!Jw7!gpu{F{`(@One>Ua@= zW$)zB_bZVPGM#4NY;+Gp4mHo06w{63bKLm|4-OfCU6Y(y=wZ^W4eR%z2vC(NnepU7 ztx`)(d~1ZsqqN8hmXf%Q3$-NOJ*7e{RlghwgWRZ{x#wlJ*^_9D_ysSoZBMGaVjRvD z;nSC|iTc4B*$n#Ju&tuJWSz#{y<ENKqGKy#b9MY?YW*F=k&bM6A;fcyi z@8vNGpxIT4!a@CEraqBh!8yvhDl@R-g9i043^hU#!=fVr&YWk>Co#H0w!ylW)W zNd4GE%yNOm&SiCF2q0cG^U63W$TF}yMF~uq2Yx>mAhAofays?AF)93Hki5+4IkaO9 z?b-^)-+`>s{cfLiI%;B&=)-6_u1+UC92`}*Em)l>~Y&!<5iS9^Gg z0x5n(-0O+udy31by&makT&@c-(7nV1+OC6speKc0RPjw@Yaq^^2R+8l(PUY1I0r^b z@QHqzwqx_`pW>GTn+Og!GevJpjAQ4EXiWky$EqIx?4?1O8sJ$I5oK<%ZHMSz4R0QE ztQ5w-o^?2eu2h!B>u;$-o*3R<{#&HL!=#dOmxfO(@AozbddbhJI$nBjAtYyh61;kQ z0VT4HM{HSq8#zX02N+r561#`tLiDt zGn@ZOxN_W(hb_x;B?`s*xPXZHAOmLa9MAOX#DW1@Hztv83S#vy73|nz8&AznK4!K4Lm`jd&bhv*HrFz6_r4m`0P1=3&hW{rN&;Yb@-+uDmvzQMfHGin-ln~;jA|2H#!o!g(o%OP)NL|t4XYwN8z$e@Flj4e1 zWBqCeiO#_Q?Ajr_B#AcARiO_ux)9>MD1WY$ngIW@!DbTlPLSpUX{;wGzD0_q_4)GF zmQ?6$q_F#Kd4$Y6b56pWpZmS40qCcydQ{GV=`b_I?1Jyf)ED z{NCStwjh}Y+bdo4c8Y_#LomV=Xh{nlUKTUR(8Q9xRu^KNU6vx_) zgP5pJ&jCP74v>NAdgp#os`_#c;HHHfAYj0M`Dm*99hn;FNb|u4KYwWK*UXVXNhF>C z_;&jA72@!s$*VMb_RL*j{kb|u=CArcKZeOgRu298D9~lxbVyATDBrZtM%?ZhK2vz) zz>>2nwM5o#k&miK(CBGdxV_~GT~4k(W%D_H#K1LasPsqm9Lo2O z^7-DS3n+$%2Wb=;!@XuXRCSr4zv`biWE&Zg+*0+vT@vAeaDABqs1hoit#wly)s(CV z9f-;D9tF6H_Sl7#yxT;pKTRG1USlB*1lkFY(cz)=Zsdht6GIe;am9sVkT+A!L>B@2 zajL3_Mw&kv#3maph2yfN{>+t?>CgfbIm8Wx^ZvDsI(+YFHYQ&}lYAg~9x_O=e$B|o zaXr$$6zMQQ&~gzPK}2QcobP4G_d$B<;j_00K`w8nMZ#6m%NwP>{Wpq}qBtx9<~$78gfM#A5N>4f7cBAZ$DrWn_4eqC?MjdN5)HMZ4E9PhpgKDCBIBFm`2) z5_VnsXz(|kJ0X3yJ#2t8KqTjaWqe@NY)`cNVKx5>1Yg7Aww`B7jt}{M5O6CU2>a;T zr>tcj&lKnVzx9!=%IvxkvLL+}*R-g(;l$l@X97wXI(wGkf3DtT$_0WvYiYs>!T&pNIp0=RcUjj#tkqdwC}g-I~!0gMyZ;-E_8vF6SY@IMd6a6T0weOfDE+ z-2a~oxjxTAY#b*FTTu&yyh>tn5UnPgCj=!>8LAXqxDZZf+fSFwsR%(ZkQFkGIOX`Z ztmWUeju=5dFcf~wN+o)eIeP;Glj!U}lr!a39N*15!#^S(khZ_~@r=g@{*9vf>1ZQI zjOw^fKxK$%()iUJGx=T0ku+bw15zh1*3S|<5YdID0_?lE>sUPM>?O{_*Y_iFsoQf3F*Zk{~Po;%MW;Z8GLk#cev)E2bVl> zBZN`2IAZ$%MYv_5?u|-V)}lcVqRR2z=gz5tc*t=n$kQ{qub|H(c-6|YRY+R(@lSG6 z@?+&s!QcQj=1f#^R0Q>HVyfTBFe)^KqbOSaS!QorWQu|5h5F-h#r|k+`u^%3R`P1D zqTgo%SRiZJ&iUeLtxjG4qDY!osmg!49A~Z|4k&slZa#Gru0VPM-ptX9kWgSb<8Sv7 z%q10)tu!@L-79@uIPbqW;^cnP))P>BJtbIZ->g=}?e+v`Np6vnV!^mYph+02+m7W$ zW5wJlbtD(KN-4Cf5cNI1&y|o-{x{O}LD_tuH`*^lP3Eycw;Ons9D|W79g2zJ_##MA z-FWTVr_X4?=&KOlCn1j#6U4Jl!Kw;S_Dyv!xWw0So zL3-?t>=Na@&jnlq za$wwBIG#(Nsv4PwZ{YMsLjvlBsPoz6AHX1z-w1-RP(cW?1H?|N-udPv{oauz?~Y#P zvNH5!bB0qGW%xju;ipo53l6fSbQ&OB$7CC%tSAQZ^+bkbY(C*Jng2CST4@^T-l;$U zD;RbNEl-vk^QrFcxCn^(moX$dN^ps*0ZIggWmoS}nQtTer8L4=cd#HZ@T0*Z^35$h z1=hvX4|sn-QHwR@iF#t@Ti60Z(mhf2kGP@+eE?B=C{QG>M-bp4O zkoh?N4a6uO=Cp2k$EgAf3U-+ej8yD(1hcZh8DINzN{58#R))y}ySji3h0X5`UaQC~gW>6c36X=Y!k8!GGZrKdf1H|3;%^#3?w@qPp{S4T_-?2bU!EXI zY+A2zWjj56s6oW1!ep+# zuP5IX^0%aacW~#OXFq6X<9<32!-WMb!Jq+cbOBwhHZ$fY`$3E71YOKrE1phlrJ1u- zkDSzF>X%>m=i@8Z__+;zU~QdMFIH2W_NK#V>_4@X66#uEeq;C+v`NK8q$6TJCRR$E zF%mIRDM3u6e!c$O&MydcB>_V@17gq;IY>=tvSdMW!9eWH>#%R|P_b28C-bDbAl^J= zfjtN>qKh=qc0ybk-t|E&WJe`usnmL*_i<2U!wws5l8^|);sotHxvPz{73V~>F68h#-Hlb&pjLfm0<5F3d{ zfdZU9RM)~I;awVq!fjdj8>Mf&p(>@E5D)JV9rtVQ8{vc0L9od3^vjr#5D@*RIigrm z>wA8pQzcn>-7)H#79_?7;4pD&J6cX(jfd1VvUxHNrJI1Z!cAOPD17oh&k&OCT}*f%n#;|3ZpN{U)#}MGNKYHxGe8k`l$p@8FRf zUO>y+h8B!5FmAy$QD_vm8U4`Byr*)KvQvkao!(F_Wb^DPrJ$-CaTazO<;n^p(Pv|H zqmT(WS3r36awISE3t4d4{rZRGMblN*N!Jj8)zmk*%Gr@T26Ze_MUfltD5?R9j|i>gRiY9kN4 z1RGx-0V>0M8x$-*271wLbXImWc(T?5GCru%aWyS{1uCBfgrm~Eiho;Ml|UH$2he7} z=?_694d}O=5@^Wj*;wZl%3`_`4eG8!jCbmf%KXb9Br=Ur^<)Gw^KyQ-4G;wC!uIEP zKRjGJ3VW9`?;mO(1L~BJ`un=X3`*7?VHZK_#wZdQl%C4;-gWtsV$3oOpJ9lYtH+V~K}1 z-Ng$ybmEAHnQY0DAvbVnmHbLfk3j|A`emj}`!^fCG~Z{Idp=J#n3tHqVV#m0Cr@ag zT4nqA9~v(?9Nu*zt=|gt+AW_$eXC9Ab;hnqZj#(^xpM3xKBp_fakqzqN~UW;f?Wa; zZfa!6rewAhE7stMPhd<}&L#&Z(phYEK)3|}@e8IWL=Xj(A?OVTP_l|+$(=)aEg<%3)RFu8qzdrgvE+3q4G`dUz~z_qG1 zx=X&(j+0~HJzrm^g2X|uu1RY>`qlB|Wb$&ojDyec{5JCSC=!8CCPt3fpYVlow>~O6 z+IKEhIaL~Wy@=7i9r})XFwnj@m#P`p$q7GOgJ%wAFkkNiLP!;Fcx%NL^4=v;T0XOe zj~+vkIh=TR-RRLBh;!kvfER@QxE;NwV|wbP=CQ?y-eN`UZ#q%q32fYU2ww;}JTc*s zgAI`9tn0N9>Se6j<>2|*2%UhU!|Q|u_>p?Sya-&Ci)M zD<&9aWLJdhCd#+jm}!{pJlVxGyy?|#Krb}Td}dr)BsB6E9?=0FA_A!J^l+5J79O@! zA)j+06M+_!AJB!l@ls(CYc_|q5JTV=a`Nc64~2=MS#CwiB4)2hTfgcKlB)?4C3L{6 zxD=*NURtlx$c^$ZO(8G=%D5d+8EiJ0?K9Q`P9(QnMwB;pnOX~>3ONluN)i~tt1y2dwXzr;(zpn<ZkqMv%koSQJuq09c4axHd1JT?X9U0DsNNZX z8r=Scy)L+ala+BKlQq)^uNsqV1qKvd4$Zc8`y0m5MDV15@=1TofPxwLoCxl8mnhJp zu*|9^vFd$P&TnbcDDN?a3DK2Kr$>>`Z z$Gqr`H0mh#If+rz^CIF@&*|Gc(A`K(r^!f6gE6Dai#Y+3)u~J3tPEy>Q?u!Z^L&dX z4sqdn)%rvV3DO$8)X&+5sK4E+?+><)CMnJ|npG*Pa-Wi5*iBdxuxS0rpq~K*30^^= zrq80K8A@cM!><37v73B>#1r7F?|2Dw#Od2eA+P&a5cb~1WuwYawmO-DJbm>J2}QV_Uv&; zXe#3+k4HSV*F5D5ZR_e{2y}&8Yuwy#hF+=ts{jxu(`ny=bqbsw$q$%?B&EAL9@fFl z(ln=GkGqo&nIkh8b{Izb7f@<1stl>y6M`xhThbXvvJu%8hk2E2-EA$2q+N0xcAKrF zzwj!`Z{VNdLwd~u!cBgDT6c9WeNxn|NWLkQ)P=y2)#l;o(l>CEsW}4WR12 zXNdo44WSjMs_(vgDkh@AVM6JMFt?nPshf$k~A6`O@Q% z^e$o%wc!tR%Y>rDMMLbb21Dg#Q4}u#LqNR0eb&F44YAQG)_T+W;!-~u9^;gD+#z9G z+fG05Pl5-k|6OMk^-J3#+$=W+r-;p6G<h(I@HmohwZL>O|j-;&B$+-|mj7v1oqO zD`aK2;6*dXi)8rK#%9_g96g+iuQ!JU3_XbKa+jfOT#<0@+0|J>YKI`{pC|7vtXDwJ z;}DW8lTtPE)POF2klTU3zKz5v-If5~gbCC=6HWS+A0K2)s4m>fp+mSS6HI_nA8x zAIIax-$jxcg_;qQ0yPqqXIF(j1^kQ@0i~5-LG9Ud*;As{j?~z|xmkvIcwu8p(JCzJ zn7yM5ESo~K%b;kP8kq^O*7|-9nJj5b51>7$cbWSDHQ-8U+dNp5*#Q&_JJykwNOXJlPyxSJL#xt>Zp zN?tu4dN_nt4!%$+kbcG7n~X!yd0ZtbuP1Yi{5CB!vja2mfDQo;pyYkA4* zV*I8syYYV^1*|8!kc9hnCS_jzYI~C~5wmxcmTWTAweJ`WM8qU1|D;_*7RdXvJlpEu zGu2IH)E>fEs>E75E!tbq0W);@8D7`yf98pU*>0qYcEuJS`Ejq3ezke_FzuDH8UIM8 z@rBZkXvGhf>(>+2Rp`SqOt>)8mCKf&Hj%Cy=&NS{=ecO~SisXO`*))4P~=><8ik#` z{T?8Lb;uVkmP*Uc)?dKAQN-uKyH{_xR%@l;mb5>(D1V9%WFrBTHq!8k8b#&hAZ0hh zb9U5^>=J$}vgQU=(aksko1m%ozUF@;;CP1$ek1c4W~C!hRIz7P?b2^&{3u;1r{n3z zOmH%J^}?W~WI-eXGbmUKAfB7`+%8k8&kZwJWVRyU>Z{w(PSh1>FcI6C;0;TAU!{6k zx?=>ZTBP0R{J(oCt61Wn#Z!M=`TBrj3y+kI}Y(`h0O`dKPLsQVH;9%dHw*jaPAJd17#muB&{7{Cw0uX)`vdM z&Vz0sTCCnE>1oTb9!)JIm2?FB^4e@wHMcgp1Iab;dh^_=g!iozUdam4Z zv>SUFz0gp&1+vG0XC`+BH9*(#PPEu~1^iEU*UTFJb5B?;EiLL)yQko8|I~d{lvA9? z_wo-c4m-9?L>gZBX#YK&)K9Wy2E)e< zk{{RDO#F;>%v3*T70uok6>;CP*-;pnl~-YtE!CVXrUju+vfeS{QntRCMy*l_R^BQG z+VpKHv?#cv29)&mzyV3GvXmP71}Het2`;dG4Jxz3B;E^OAoPcQdpEb!f}BqVyoN>W z3$iYDN;{xT^;b9p$xGyaTKSy@K}{1#?Q?@c98z?9=sLjy&uy*i@_0$VWtw*-Dz^Z+ z3fJF|Y6AEpRQi9j>-l8p##HcchYmj+QX3s(_VciE$ny7v;&$=HnJ|6Ae-X?15|{@x zk=6y7t6h$avLMDNqI$W;U%a`nFP>vL9fyk{pl?v%LRSS!Ti0a%(PL1Nw5)jD6`z12 zYhlMQA<#1xm1QXhi>F+B&-T$sD7j|8{TsIFvck7zZ( z@NblzxNSrCbOn&lZfh{JOeNM~{0spR4_w_bx(XfmR6i!%+BKxGF7*9(>#igvKQi;% zKZMp7-R;)2i^8_-y@dKNkoWhsQEK6r;hyko({_n@fEJh+e?{DoOi&*|(;^l|0%Ty% z@cO3P6pN^I)D@;v@Bn#}DHmPa{rywOjri?WY?7&CHRJEa5V91GuZ?MVa{a|PRQTH) z5xi?CzXY-CDViKrkJ>F2x*KnZhFtGr>xW^&=a^oSk9x9r7NZx)ntGsit1l%mt3D0D zxtn92fEdEi1$yU%M^YPJws}`n*E{&#rT_ePGPec&)i8U@nR?!u*gDA8=B_s_!bm{= z;#=^GJ>(&jCjOx;=KI91Jr=y!YNP~iu%Vx!LRw3tS0dAs(rIi?Tr^-pXa47;!=Y&9 zn=3Op_fC2_8)eHa*WDi@DlFB7*+_3C#=Zf}RM5f-SzzV*PbNexy+J;mz>&V?@3Kmf zZyDupNSE$gf4rX=2XuU}7N$0y^QpMDBe`o}{vty+WC6igMFMETY(>#M)s?0gNMAK) zap)irBb|Bl@TnUm|9XMR)VXeKi*4g7rOd1dtJ10Q`aZJu7En(+0cJa7%$~i|O!H=H zA!;RfUKy>#nC0}meAghxG5yNLT^!TE^kG8;nx ze2pLq#GO~B*?vn?Vzw}bz6UBOf9o{qpa@^;$8a9Gm_n9i1ZfBWFQ(>N7)W% z$uZdJX0apWtMLEel4h(cA(UARrTVQ;&w2%I4Qzx-m<;g|G?bk((?PhW!`C3X0Baqy z#e-m$fYt2Vwo=ki5*?Bwz^skr@Id8OImd-2o8{szkOW+_5Z=|Xk9Rssp&{}E1+RAw zjOh!dP!mXpozter&3v3a0Zhy|3C^%PsP>3Ifdcn?9%3k3I&TdTb)Kl7(tA5U00cnD zpn#?;N5JoUi5eWO^?PD^2zvVzSKfFaqG)@bFON;TFe5Q2P|ixXTlsAXFd#w*zj;c` z_SfVox>zEmyYLTI;u+|W%!0!krs2KcJ@E9DVjKcom?l`C#-gXlG?^cQc8Qyo;gSAd zwLu;;?%d}(-Z|K!2K6_xaqcX{Kk&zuq+NQ(qAksFx-#vzTp{&`hN-#MUQ-cToQ;~8 zvIQ9J)&KIjsH<<|%)>S=oz{7<`r_~+iG>)|e!rKtot{|BKP8SlIj!H0Mz!tBt@f0e z=WYB>Fy?M6F{okWk%XAJe!4`BT{7pIBy z(7ME1r+eSq=Wh8Vk=+?}lTKN%gg;Cq$HlBFk33Cjp1?N6(e7zGb19h8g@5IjuLwD` zmVc5I-V!f4RqQsJq=VJxk}`k6go~EX$gsNpl5XEN^ZH+n6f&%$t@uOS6{yC<9O@bI z1xe~ncs@sm6Y>tXunX|%GPb$(2+rPMYjaUVd1m;2yQ7$&>I%WOM^o1;dg?#XpNaz0 zSFs>Obqe}|FOcTqH&Ph>vV+>5qm8s)%40LJu%`+q{Jv5MRQw}w{^Mi0^xdcxI<2(0 ztfc_w{0XYsKvwA{c2M_hC@b6xlB7A+%{8mNn+U6OhsbIKMRv~ATDe0rO z=6q2U0Oss_1R33UEKMH*a>6x)hl%o*Os<;)rNZ_Wk+c+j9^rw^yZ&wX8f^^t*@)U9Na2>ualQN8A|+uq^i(HjXG)x5lI2be`C_R+3k#3f~lJe?Gd ziu^`r0jx50x(gq{@<_DPaQ_62uHM%o@wi{;1gt+CBlaQaHP4pn*9xY3-t4CUZ@}L# zac#U5G&8fSr~S!m@ueA#2pHO$j8wnRoR1D(bS<#&WE`)^#6*0M+m9o}sK6~{U$;LE z1)Z`gQ$@I11Po#sG@IiGN<^{$PN{&43#sAemSI5+ zfQf&|kXzOp?h}5%P5>3-efP@54_Qsg34XM~_HT2AHhp^to8)^SOVq4jvM&f}7cOZ< zUVgt@@0+Nj5dc zl;#8gZAU)!O*AAQcP|pCxUvO~qEg7gsdI;^8_HGbR{OM+WjX_^m=BKx5|($2fV+w_ zf?8l#Z{xcJ$Lt!Fi(R{HO53`gG`MR%5AL_3G^s3hVdZ%`{^1VM`e-a`vO@K zeKsXGTIbF(HRy4c#jehy!Wk_<4@phBa1qve-vi5ld&FcVA(5v*I^%{+%*9#Jf>d*W zov1-%w(gFNXN!O=6!Y#pVw2$a{wDRw?a;~4QSNn6n6jz7h*edWn$*QZ_ffPLym^R) zK-S)=4SST)J@Ii2+;8Yqq5UeXt{1`rJ-M@x4=vKq{_dla?<J ztgjB6j0Lcv!)}f;46OmQuVQ4t?P&OagN@#$Am=z#o)heP@j&Gn=lF1dlq7j#lD2BY zK9{XIO0vc^hU#h}?r0PuTY?-7AN=Rv2|zqn3xPxWjZ#Ml20-c$Tz0@)S~y~E}CLJwKhKi z^sUd*woA(~s0VES%1Vd43IHF&aWd)^8}?NCd`7OXDv9K=t<>9R3e!ck!@Zzdgw)XK z1q=OM^36KkPz{ZJgL=>#uncfe3VN$YcK+S!3RE)hm4nSBc3vsmC=nEWtuT#)BT_nl z7Qp;^M-6G~z>R7ibKwOBMnAP?_enk|w|WFNMe|>sR;Z*v%Xq}uQ3M#r3WZ-^tn-v2b#D;?m<10I}}?Q;LK6f@!}onmb&d1Q)hEw0iW)ujuj)`H%y{Z9SW zIZpmR=7@-!bL_NcbrFuPt@CLkrZJhKe8`*lYmRfgivHMKlqK z3in?ms}%?`)cwE??v6otwV{PkpGua1x8ck8t+($NFSlXLiN1IF1xu8F^nZ4eu)yq( z^^Ig}zvzF%BWd0#!aDS1Id`mAMTh@K@-~=@7h$-=kgSRP#AR9qcqB(5mj!nYAE&*@ zhgzeSoTP(8W#cO1H=Cs90ijYb@l^M5DuQ>5DOtGw3?A3zPoqobJl21kCO>bcw->7oiyH2q`iRIQ|GcQFH0+L-P$Htcn-c zy+`_Za(hZ$z7@TSDT&x^sF+#B699IIj`=t(c5<;4dxHD;Bz)DQz@>(`M0wcMDuR5r z6ai_jr!*=Z3Ai5vh^jU}l8f4@C9vWIpx#+h95dwIGC;rG=#s^(cCA^`q1c|ZTQ27@wxlR!H&Xo61u8^N3E;s}5O=%%QxANNXR+JaeB z_U(|Gu8{r-X1^;Lvi)_cvQE5zfwPi93-OtFPiI?Qu5N%kihl}tpNBIK; ziC=h45jja~E+n%WbY+ik;EfY)T>lStO7mB*G!U722PQ_KNgV2LG znrP?(^P5|RoSM_|ddoMs4{DE_xTaC^t_#0kA6PsdJdn9~??(bdj(FE5pMs;AT zusm}cXOfn(fVe479`t=8R~d^U4)-@%Ub1BqR|e0Wx7AZ^stcc`M3Lvu=>!^3Dxk)G|@JPx()6XVYgqb zGl@f14*(02rREMNn+EAX`9Vw3ihKYeQTX46EgVpNGxh1wTL>0XV3m zqin{REY6CzRu8?D*)4AdA2UIHmq+-fpRa6L>svUVISRS#O-%Tl|0f#*YQU|L5?v81 zUMHC$K5KgTdob=CTSas7bqC_;xNFh>vF1#aZ_5ZROvlte*t%T<yXu3`z-ix=yZkPZP5h%>agtJ#mkZ=ap4w)xi>J~txY+(KpZA}n9L59=?rJyW z_d!2djfjl+l#kgO;yzET;A5zr_Xa=k0X%x*g2y?PXg+4#D8B9r5W%@iS0Z90czm`R zjzFC8F4{!B0+=z(VCh+YIhXMkRZWh~*&|xlugz$<#nYXC+ewV3))s%wGOu+zWq0EO zxwN1LBOkBlb;w*=8+h}`^Z>Sx8=k@{-h)Q|3syyRyAgJ3K(b~e3bb}?3N;}#tZ{&& zB;$$tFyVK5fX=zO4T4m19jf%Zdf;Ce&m9qP z2Cb5$H2xbHoZ&YxUgwOo`+#Xm1_mi_@ZVJ+Dy(qeKMq6m;Ag*98X`Q9E-dtEA0?r1 z3Y7%Csb}jSC|k^3^nOWs^T0TQ4G+5Wn%G12!BxAGF!{FMfx`iu*#v+!9QTM;Xl~Te zk8Xz;^z4-U5u@>o2aK=4dT{%R+~5JS|6%d>qvKY*y>wX=cFm4<{H5ozE<84fUZ&Tr zx(vgHVlc3teWR5`r@;0s4|yFm$Q4<{bx9m_H4BXNS)!Yl@0aM>>F#&?f&a03g#_C- zJv+|=Q%y5|X&O~<=<03L-B`n?M8CWIKCjLg4PyR|0RqXwyUi*s_x5i7hp^SjTgaZr ztl5Z)3qaXM9eaz&&W3^*cMGrvbF)r2#l9rx1`$Pipp8yT<=)SAf3xU8kWsU!hma=1 zqLDoL5F#vC=KDS&ZOKGiszfsuVH^xa-oJ#z4D0-}m5{ATL&vAQT-Uc$M@|tp&Pu-#(Kdpg{CE6_`Wib<8qeiWlO3C?JFUT&xXsE1#w zuD`U5fQ>kE0XsO!!-t_Q%-152!jv|o%)W=X1WCkr>vx^ytNA{Fgxbvx6nafx*I0Dd ziQ;>WN?-%Cjj0N}wCx9;SYF%dUFY_0h2|64M3qddmL4pa>|9rlHH5m-+$}>!NT_l> zhr@ao=G>1dQ(XIw0wCZw;m-#CazuM`<&Rj=vstbS_HL)0rlI&qR|H$JdDCfJU>@i} zPXPx{9J3XmCbknrPJK^w&CG_{11vfEw>qJ;gvhl2Vku6UU_a;|{q*tZkcRbX%k&W* zU_-0??y6aZfU@xy@DmLX1Bq*%cjw&IjPmzbc$0_aPQUip&IViVHhYfz&QQbu_QHl( zH`T?~96AU-TvoGsx6m3nZ|70lYt<-h(4pAGV#z{x!r%c=pdcdEsf>%zaVU8*W*KyPV!4VR%|lTqOSCM!8ct9{ zrE}ML^f!Z>C!zGVMHY0i)9wK zdZE11(81ZjT-N&)AYc%ruPZ6iM$7hy5fY;6$aiSPx`{{LjJcj}E?Sys+7BMb6XoeU z+YV4CnyhM`9mN#ABZE^#C|1ep6t^ldv)ZmJztxP0yd}WCfOk1l8E+GH(cDDHEriiw zmG{k8yuuqqCl=axL#1Ox8K2nyam5NK_i_Jl^nA%>Kbdrdqk2~fU3jM24E(?QP&XrvT#h2q z+XPF*!BRH40dY=YCGSN@Fl>%g=Cia^ZT!e?*T!xrw(HZibf-(+J#j!)vk;U}ZoWut z8PDYB)ZgD|Xt9-#N7G3Z&QgsrLrR=qq1WHV=OD+SYfsOuasc`~2>I9^w>LALlXwmh zY60MdUu4?3xBz!x0+=7N2e(Ixr^)5xVR@HqQD>mo>YW_8ToQtUQCGV=UdTf5L#Wi| zifYv)v#i5S=65YZGW<;}btwAP9YvBOGB_ad>533iufE_!nn&v}j+zRWuaZgfmgy5C zGmp}$?zkK~q+cZu*~iCXyk$pIK&db7KiIo9Ifa(nWpO?Cj5b(5vWS0awRD7ZiUr|k z(ktKSgc8?rda1tY;gt+@x4bbS^KE->PcE;eq5Q`6Y=LhQ>g9#ru zwdJMI#`oWUcR9$e;#8TYWW>Rmz2MvLZZ%wObQuNw+#6d0X`Xe79HBlL9DO#ttfUa#b>EF@KVZOyAb-8;_+ns6=39m(vr5d-a8eZ!{6l)#F zOn?ZsC`jou6PIt+Z_$YNgYu{+&*jWX3$AiFA=T8itPcO^2$mdrnud-fsrjjOd1Zucp7WoPTc|0ZqJ~RjiAxeJaCv!`;BGn*{#EsV#4phk ziS{J+?o(0u#?+rkOW$W(`*N*$%{bfP7s@?xhUo7t7z;&I6$3Bpa|W7h--+)})FSnT zV6Rb6aj*xwGiU~&!$NJy&k5xdcgew-UeWurtqsq6XMKJTUI?B-^@`*oJM^_^RC6%@ z;+&TWJp9B!BcrgB2*vw`29AWP*jq3Vos7hjUA(2lz+8Ojyw948NJ5v;>*-bEbR-W;=Q4aPtjN;X(A? zyipE6&?K^91`(7i8P{cC85i|qr8!bSV+x6|L)IZg?|8Eo2%Wg*Abd5nn;ioxRhK)+ zmm0gZ-Mw;)@6WGiTG1V@c`odB6VP!?m#=q;E0#enbgFR(yKdpW#XcOvQzb~U)@eES z!};i0o6Z5S?O#TkuO5!sxty#%$NhB<@hfJV_YTBztpFKG@OFO`{Jv55r};pAl{Q*^ zW&bTe(7V|?UlEvD4v84zCApuIC}`cn4H4Hvgfl*OfM|9)|0jgHoJ@%;=e~OSOQE}d z4bZq1bqadhKmWO%^CnlV=dP4D?rL)kZ%E?PKO~H->`FWaFZ1l8%^iF&KiN$Y=8Ad( zZoI+Z4cPt>2POra-J$CdeZVl3@1m*mJ;~(%hKx6Z1AtAasv=gD}hpKH49*{hH^~R3;99ZXu z0R3Lti$}~Z>8SC1ihrXjJ{`^Gzyba!4-Cve%k9iU zCePD1PGSBl*5oeLf9Z1ht7{L(kRP%{n8j01Uiyraexvk6OYD{Y1LDK@sw4}?-Aj26R&IRDdfU*f>TuVYF=)E%Nk|#XnZrCe z`;F#+skFnGzM*TD!k=D|mbUAkk@sdM_h%kf$;uPzBd~I#+GPLNI+V;y34IacC{{~S zg@j4kLn!sdUD)qPr}Pfgd&^RJLP$8WP`T zR)J!@PP_g_f+j_j@A5n^kW~Jo?Beu-ezC>BQWNsG$WTyx5XruHtc-~_NEifI=RsJ> z+1{69YA`B3pK6(qtwnB8)5(;SZ&;es1)RMLV0$#*QEmv>B_&4me219mW@HI0i?NIW z?GxD&K|IIx%uD*CaCkFd9v?GHcs6h3O3jZZBlYB)#@WcUzqa)LbBJqm5(2@-f{9at zh^i(G91+BKTzuh}>)RIxUVP0`Mb~qq=B=>liz^O1t46Q8{AhI!R~?;Ws<+Eu5#~_* zd{zB>>|~p+#yjLKf8oX)9Lol<;r=Y`x`yyYSaV%!Z`X!3p_d+w9e@FWNBnK`^hBER z+@u8~s9%Vj7mB{@FFoE|owT01lfhSqrc(t=NV1F6##sz{KuZqB&<3rw zf+DB6JGiSSR4SSv&vh(WyOG4{v|e>iEGII>m|@z-7<>|4^tGruv^-iq3Dl8 zR?w_Hv>WSWW~80D*l@G-KaT??^|ENGJgys}@t_e>mYFAG?q^;UFLE=gC!3?;B^0Qn z@i8NO5{g^#iUy*Ut?tyQTt3D&+)}W03RY)A;W$=b!pO+ss7cIN=C=*_9vGn%y2?VP zqN95Ekw~f-b$L2TcX-2rb-?<6u*_iOk{kx4&|DE~S zrjbTR^Mp+l@K{2R)K!OI5(wYPGJI_lSW4t$W5UJ8g`;5IMDq_>x_Tl7hzF`BFcA`+ z_fT)8tmWodNG?pmQ@{1$2U(Sdw!=TL40jagI|X$A{gA%Kx7n=56)tf>I)V&PfRpT0 zunU%vfowI9n|VG+z{a~RQ;KjT&>!Pr zWGvmoKszubcoNz)I=fwGlqC+{YI3UqWD|1Yge|#HRF844i6{i$$E8y~NNoN<0U&i8 z0NWGd(6uuDSZnE3s|aF~@%>kCg$X#!2+FwXImv9zBWd=07H z2tN6@SApiWRj5&q$|o`nT9$>EU7InwDPUVXMTcDjXQ@61}`4-Mlx%9~0%eFcAc>UR5Ut&Qm z&}wBa@WfVF=?M|Tx!T)s`(e^uZp-NA=Z(CpY|txXqxxZxJ4*Yvaam=`mZ0=hk1P3A zIegl@>b80XcqIjWN1WM65(1ilgyPJ5 z-1;&esrBrzwPb?W%11e)e~aH^x2*^2<7HUM#@CpO8>{E8e;8i{dOE%u1i_)x;H3TI zy{9Yh|9Ef3TufL%xikmS(Vqw<8*n>=zoh0lqs2n%#HGR?Jb_%pBUI|bs*M9LJ8`? zi+CUuY|+Qn-0gB{{a?#GYHL&;k5rd-qU4`^7Z%?5ziU*1b`r_ir_rkq0u9t14ZT2e z_sG+YtCbPNXWlW6erSz-iSNZGQqUwMOko@xgCK~l9}yPN(usayxA;He|9&Tq)0TsI zG?M>xMy0$+4KB(&IvreEsCO?0-{Q~r;=WU;WIpG*$kq{y*Sd>q#QTf zwB^!!9fP?K&WoeeM6FEGD!|X)x^CFT&$p zBqWkWR&Kwdt2NMJo1Xh%)%X45 z0ch16c9b5jobfNz=+~|DR1`oKq!OM||Diji8T{Yz5)hVa{(iua+#J$OULa}-j^_fU?T&Rf|WO?f5wwJZZJ(%QzCyT`(8OAlL|uH#H{30u0~Ytz!m{ zvtLNr@KgHS|E%_8+0c$d^DMW8HtNC^Mamp(18fg@zrxyRxQKW~2Rl7>v5<|U0#RMS z$<|o+9`^ul$OFL;?6afg@q9ootup8gTnW8WiCe*5U0ZfbC}v58s{-nDEbjH!YKlxnYKNGXJ+{lg{h$dzDCz$+NnRHtbGhUs!uk=Va&GBH4 zWh#svk~saF?`i*Vu*?j_k1>+Q3(miZ^X98v>(42*wV|#ObpYV~7Nx#L<*UcT~puN@fLj57-*x!)2$7rU_b3Pr6Np4RvKADoQKsQ8>pdl_K< zuDWAn5FYLRrr7vGk1AFBO(~|4b(c$pYW`R2VpZFG%>om)On5HI)H@$FS4YUkCtifT zNDCkH!%@nk0m@_C_gV7E70b1b>n$g)B6|ggQOmCSAzj>z%B;0Cc*} zMFh@6o|WmOE~FMnTCnjNll`m~89D>?dHD^-J%uet!h1WWTf1e=SvnlxA3|QZ=a<5$ zBLT^a{k~VaTBp8@AO>Mchr8YROD-cb)GKGPit)8KhgYmv;NuvKOvY_@0z)(vZqi_Skl_n#GB5KgAEu>RtG#G|#Uj{t4euom) z1!(^^msrQ-SOYPM)ILG1RM~%Vmq@d;KMzvMe|xL1g|AG(8-8Xd3QP7V!?#Ys`I!wjn0& zIvHI~pr%QN?=lLLfd(LW-jdk6A}hrsd6HYWd@o=>6jG3Fu~#(2)?3(8onpSApP>_4 z@0>$>zwxAc^0%?l&I4D^r#-K`YrT*FDbA6&`@(awx?r)yAYzDkM6O@_6JVq$fA_&C zu_r8`iSQ5KV^lvRfv~pc)st!%sL4P1A8NSSbWw7G(GbwMDVbMspC}Sg0oLGa0K+tR z3UBWBeFDN}Qm+z)CUnX7-_v=F)Q*kuP`2M0*iEs-fK}-jj@$OVm@6@!%MIR6+kbzR zS|u^GRE<8>|t5!!S8FQXvw@j*(OF*j-@ zbcj^gAo(ljwg|h-DiaWJ=n2=sK8Ft+m2g{>)GZpL%Vb1d5VfB1n#Tu6a&dytXgL$3 zq|QY0$IJ56e=Kk6B*ZHV1@TG}C#XhO#MKBn)bvuH#W7*oMMDCTr#S>q(ZLKfHfOWBV`03tcW z0>(8MSjc*=5!A%~tQRww*kpLv*>AGv`w~$!dB4`+4L6`r)j4j< zV(=e?7-?m<0HgJa_6Y@}JE$oQP3jeE`j2Eu<{PM2r^003pM4#R~;D^}LD zXfZI{29z=y1#}#UnQg#!&~p&b%xE)%6~708J0S=cRK+`o0GJ~tgl%dL9boYzS;P70 z$57laad$Z{!T!-f5znSDa($QAVIp(s#iRBu@8XX2E?-f|pQI2??0hai`E-do78Yx5 ztBLFsrw}l|E^x$eS2U?zJIjz5w!?goGaj~iJu<@wwNvALHN5u;f$uCqyJ#hXOzvjh z#35|>GA}oQj`EV>7qKypD51p&6t>AP9U}F;{3BdBZxbOulS?ie(;jU~?~vpm5H;U2 zb{@^DCuG|^V>Kk+-S)5w^yO^NemT3O@2I|?K+-i*^SfG*iwcQ-3+nr=-GK<`1&V*E zAmwo_A1dw*Slr^nYlML9uvJKK~EE$Wd3hMzB@V9YE88ddz+p2kXWUv5`pX!od`!rc_`?wE$vN$EqP;rD8MXB9g??DH+?ig;b? z{;oGV{2VddXB^II8}95uwKW>{=~8N%kc{%3RJo2hdGPnhdDQOhH}<=PjuL(%6aW>p z2`@Qpk}Mv;&4@Lq`Liy6!Z$tsGEFA!J<3zYn93RM6Y-F;Z;5t0oAx&}22w6YGVfTr z_yqv-va@_dQwoQLON^^)Bysp*IQ|}neHaah}k(%|rH2>V5^y zC-TOnD}AwiJ?8HPqI|0*TdhtvMf?b}mGj>KiGaE?qk5eoG4w*2 zFgH_tMSKjo3uxh5;l?!9C=a(J7^n+caKXUo+9_|1Anc!G&z-@6Va))Qy_Ur=}r{rq=UB2Sjw=&MEy`4bFpaBnJ|hwHAtf0fbKl;E@_vmQX-i7rGRD$dbyO zPVsbZQl~G20X*qWk2%%dS6Z)!^uHy~>hspz%QT@(4O{-|6DM@txYSJK>b&`j`lNtN zseC;78=D`7-B0KGT?Njq_ftY$f?>^79P70w6%^&YVK@? z6WLQFCv;v}sDgl5U=#y=PzMUcImkPFg;(h9_thwz3zE@^^e;m_UCikWWMt32ZN&zE6PopbTEJRzq-cMnmCbB z1o9*Zjs9d7t!G_6a!Q`?LVOf`A57;R!#{t-bW+^`=)NlSgD9S_A2xxH z7_m*oSLa?I5DYGlP4X?vN>TJEO!(&43N_HbJpIjT^)1E7y`%KVdx%f(MEW6UtOn5~ zH5Axe6nLV{$Oi2GNUz&R-CYT5JLwZPBfZHf4B$&e%*qbBctOzQuI>7EGZ#t2@TktZ zDoJ+D%p&U1+;>#exVI7`vS8tKjqH~(GsG3>=(>o# z>LYh9ax*h2d~`5#o21Bz4_>H_1l;DbWoy0BTZT1IZ+j zukWc+Vq_E+TC;BxJxcuV!AiNM@1iamKWkoY(S6-{AzdCd!he@ZLXW^}?)3zUo^74H zL$y%)w}9b>;1+)tmbb-D0W{Ust{l>_hsp8*k-qo!Y6Mn*%!Vfw#_=KezQ%(8WaBgG zsbXy^m)7O3P48*J^k<%34cI8(-4N!QNAE-f97`ft^AhoU;|4Em)JBHxA-r#Ts$vFR zkp$%wE+bQAFBs)0zqsm5AT!LB{hTBja^=*AwXm zxmp}41|7n+J~p04*w;ja05xPv`0?TWqSLC_ANG=SSoHgBmA95C zB5QR}^cJL9&OOso;j4Eu550#>o)86@KJ=w=(anp5d#20Z3>;W+z_xCg%4);mNfWSh zUbk*qVNR8&0KvyS7>*qEAP8AbmA!LuNpl7AJz^-L_P99-O#v*-FE%>)7>;;;XPQhM zdF}~G+&7#x$6?8}mHGP5;UDcq-r|P)dPf~yDXOxii}b0;P9Zo+2bd@4xMVPsPwEsW zfr`xyqrffhY)etO9w?TO1qPdT>q{Yp$tv>!psmsNn>PN#D+udD5AWi6Eu?F*vWjBg zJD7B3YPk%`{68#tZ*xn6#nelj=@O5D?LhIkk;p19RH>6lMnpwviAB#F3PB^XTwPFl z)tG~9@nDd}BDTuTb5DARDSk*h78-7GszI2aS_hV)vMU0b#e)az4M;r6Xi3G@7pQVq zbu=Ptc5{em-~7Srn!jBZfDOvijQ%LGY=FUw5Bh_E(%^+`QH*UvZ5KzNt*&S6p>rm+ zspihvcKXk%kau|*f!qcoZA3T#0001f-$_Eepy+j-Qm1s)Hy-kLx8KWSQ+p=P#_r@4 z6~WZ7{ykz%j2y*47iT>AnsgD-PkNhbg0hn%vU+-d{OFZY^Y1gj!4ka1^0a;rbjE-w z>#su&1os#z6B`soju`#HEh7Ai$sC%}q;iwdz^L!4vy6#yL?%i>JAw&b>NYPcpL)EP z7usR$+&x!QUkT3??3jZt&#~5?mGn+r+qgb$h|b-wup`{4O6`UAFN$dSgaxKR8#v5m zit9glw~rt>l2OxfyXDVQYpUx3} zIlUtk{nbH}>l%8XaA##hxBuY*DGM3Ht~v+Y6F_7(JqPPH!4(Ms9PaIF zCw+rR13Z0%VF&@a8A$By7tqO?pya{cto^6?jRc{bOzil%#g9mz9$K^F$|W0S`gM-5dqjvGp)iX)5=IorCd}iPhAaSU-SIIHlBbO%X zRr?jG8!e()8A57WlV;9aCZ{WjamJcYqU^dNm6w;Er<0p43H<6o#NMFl8BKw)4z&vC zSEQQr>{N9fl~p+Kc##>wTq0h%v4tay20v8dUs>g4M|UCD*)D*8%1T35&uSi9nhsXcvh z9|=Oif)e0s4$jcpuI;}gEfUuEdXF86Nw9FeZkS=TF0}||ao$jOABiByPG^0#0?Jmw z{m>89D*l?ynW&+p9LKbCb|t_^bnGGkRp(C3hw$xU_SluJ-b$xRfRjn*p`|G>P(cE7 zWe(&ge#eS*xv)lSB(45mJtYvjnUfLINSXeCf-=hHSEZvjL}>3Bv=feNIagXos&~K3 z0Cv|LOs4`Z8uNi5;5n({P`joH@qQ_33CvrP=k&P6$I*2dQWSKR!(`2xM}O}d4|`7< z!^Sl)i5;@w-%z>Fk^nU=>WJ7u>nR3rD*E@{Qddb{NZFuuoVSbZEwOoU%XaZ~K_4>Z zg%jursgrAKaaKH6n!oFb`Xrt4&A(2?Ci)B)D`1L=^J~J#4A?5e5h-#ov!^A*1)N{F zxwzl|$;Mz;>(U2wY+!TiGA*^suUdY^aRUjnm^|Yk6Gz(?i?G|%Ge^VplA$XHP%)ZV z{rNBK6L<|jx=Vg}6Gs};=&SC7vZV={CCNirQzt4-$KnoTSyiz2J?{92*)fRW*_*LGy8Vj6=I;;h^ndA{nf60kA;juT9>dsK$2b;y?BUZ6qSG-BA zAW$K$=(Pnt3ILOB4=jJT)>_#JkGp+8<2L<)-g&O<(g-6ry#nE7#D3@^==p-b1|tJ7 zC_L-P!H~FwqoIn@iPzRftr?|B_`@27g)x+xe_>-XblN>7IIjfcLGy9y4zZKLTe1~Y z@sd!X&)Id>6=2H{%1jIU@wdFKM?^@CovR^~T96l}srh^&ZlpSsQ$(bL!EzPi16+(G z`&hD5Y)+(1CJ9gj8%45n7lG+Re`>LX#&6PCpy=+GcPMK@-3t*KT6tuQ37fPDoHX3A z&VA&Is~TVmHrZ74Vb8v!`zT)!__WvoS$o3_k3_dF#!0M}QIf)4iofCX-;%Qdbry>0 z*|9|*I-eAriOLU)Y``JBWPEqUzQ;Fk`Nc&AC{rrCEG%GG%X?b{;WnR`Gd0l5ivL0- zT|H70l3%%(;m^&C3Eaio7IGCdVSzvZ010GP1T_E|y^G76KA>(F+S|rof%#g%M}4tl zC<0o*?x&$G@#jtB7aL2-ADDyjE|jVaMa`8LWAWC)W<(k9COShZ{oBKe(>B;)tZ z`-Hmw=tT)L|MEZtV3FwDbfWhH`S)b97s@;rsf=`r3fo;#euD@aH{ju^czZV}87pe{ zI=l@OMe7jwvY==Qfp`=Vi`7FL`mVSZq~N65Eq-cE=6SanKTz%a1I4qtA=5B5$EwH7 z+d0FhJ_x2QYLh`b?yB=Qp_)3yq_6_XtWwwP724y$XGV3ImX$--_^mN85$YUo-4&UD zpE|we_u+JOH0TvH>D(MA&1muFNQE_|vEZ0m_j#f^uJAMv$&`qYS9n1dT7UTZL3V+m zcn*+3xEZ`0Krj8_$0^DVoqLKHw|>ewjwg)3l^)4tbuPJm$7p#z5e?(he>9pXm>2~$ zZ5m%``9b)}7J-0t(iZo9rW4_N-ZXawn$>%f61_riN8ei|&HO}-$m#K|`VXz!?`Iu0 zw=BL_awkNT*QM=%0C;kii*z}-8NrgPoCzZRv%aIdfkMw4$kdz^bzWsV^RoP>|Ioa* zlR~z}1LcV4(JFVjYJDX2g)9nG zT!R;wUd<{4upbsepf~9a!FzyfzmqtvTy&!7OF&&`UKD!IqPZ^bxA+7&Z(vCzm}0MP2lQ zPQs5Hi&UDjcz#RSK+8UOl+AXw(#wI0$baU%1>Np592jqDacm8xOmn(1W{kMiG zO=!?lEJ8q$k(JrSPCU2(J4`vW# znlQ6~000003PH=5Rv2t)lcJ?;TXYSryfI1&10soLV0+kW_=8LmGmq?}gTA3SE^P02 z$g>0UZ-gyY{EwPq82m>dDb#@?t_(}74mU8KOr}}yBAHo2uyvOd(_SVtF@W35;mz@@ zwZo~@Exi7*Z`NyXI~k=;&!D~WZ2Zq!!v$eRkVnA;J8DWX(ZFY`S7gH!VfIF@)Wh8deDoX7?;Ku!jFJ>P zn}ZjyO@^j&Li`+BiU>v!PNg?xeDcBNvn>}U<6?Pv-Odo|yHaeo%~H|S2QD+=_*w7% zeFIjW+%7w+E^Lxkb%VAY>Wt>tYvaxFxFTS)P+#oVbu6Ua&|VI)7;uAk>{dpn37k9x z?H=5*AS1Y7x4cc|56?9S1+;OBp6d+c<5{8gcb$eX9)qIqg9X_dYipxY7)XtJxEH}v3Y}2^0CEbGFb>r__zQ;>~o#kKlE`fLAmO?7xUNi^8>)Der=uQU5y$3ej-N$=iJ@ zQtf^|UaWvBuTOo~cpr%o^xm@&gZBlbBz_MG2g;R)lI8NW&8S^j3zzbt0wrv%`LlMy z?Gea+3?gPet0Nseb1Z(9xAKVYOJqSJrEy?)=)C6$NQO=Qw;Hy_EOQxC;aRV3B4~Zu zhe4OKo0M^%J}y(T5Bo;lmSA^F84{$vFwBl|F2}|FN{pg3df^PnvsMEOnKkS9YaSk@ ztw&3ueL_*3p=z<25sy0-d{}clD&ZO3rSqbB_G9oRhaKgOmcJ*rR}p z@c;)l{24ZNGSy4Kqa>!4FnMimeSTl`6%}MX52DOmd+wFm1{tCAB zvOK&<hwZKk7wbatDG&u7A-eTx4@Q9J1c&W4z$p6u z-~1M!n5F)`32fB$Fe(-sWPh(K2T?MaGup2MaRqTZHob}lYRSps>Is;w=j&DzGj5&; z2(YN31GiSxh3Zi!uYw4$j}3$xo&7ATpT%L^oRC$EK9p1}Sm}*FvTj42G6ZU9>c4@I z=c0UF^nMum-)ZGhI05ys8tyfF5{|i|VPi`)&H!jN?MPK|%=H1O9be#XGR1yL>vMnr z0000cak`6RfiZgjgi=&RQsFg=nILst9OnoB-e+{7rY%(@aOJN%AlNN7_^f1c5NkAXwfTGHCHpq zdE8l8R8aq(D5(8aw#^E48nGG#n}(SN!D(@il{`w+uY-~=&x_(x!78H+I}wx>CsCry z^tAzNGupq{92CMX;5sV=-mTn&a7VXzJ2k7Cpuyi^I#?UA%C7OGl1Sq*X)=&&#BQ?+txg31$ zD;%j!L0w_r)0J+O+VjkQjY!Y?SkSJ!+hOi!58qL!hQ>a`+@&}m@9jG?$up!zv0vF4H$60*i~qi zslaFJl6G^nntnOJxD9(|v$M`m1dF7i-3gtlIHUF^vEhQPm?6##1I*ExTW#(lZe+PK zX4)PLy%4fiMh1rMO7DQ;->N-RqY)k8|2Mw6`ZAf-bX+m-Q_=|Xj6Q6J*8#St7;P`w z>fcG_bSPC3&uO)^0|6!4LK)64Q8~GD;E12wB{gQS>~R^wy#^6l?HHf8X|J%oex!h- z(U}$BrITf0A2Xh9_?6p>c1e2Rfpye8JV7+vm3I>9~& z6Mdp<8fF$yTs7RFUKbN{9@*oo1p_|fm=3?b%*$bMJeSq_X0KNH>n6kqAuw(PkhGm% z4T7V2F3H9F<*iUr*BBjb!qAY97C}PHd<#1|tkLj2PQv`^MC5jqC7`s;yS=%9i-M4h zlS6C66F;i1JW885ZOg5LOXy6viE9b?V32HvG^qAvGc zZ_!Y^{ctQ^5z|Mf85?l5raFY0uY=Gm3rg(-lu(nBeMRocKEEm_l}jFC_bJs`BNonR z&2CvPlHRRyhr)}K(eXM_6l~$!OJ>?~^v?gvl|iEwgdm`bLkenk!OQPWgEP+iOwHt^ ze;vkXWBD8^B6{3vd)v?(L+aFn#6Gq63>O3chW@(ITFaJBbilIS{cb49bldF*BrZQ=$sJ@I|0f@S^aIsmGjmDISu}nHNqx) z?K14PS=`Nl=rrrUMgT;F|9wCpv4EG{X3K~Y*%Ptwqc)D%4RtW5@p{RX6gc=Kt>WAw zUk~*t10YY&kHTfF;wQGTws^JM)gSlE3N0oHJ=O%bksgRs+*tlm3v44XQvE!4#THVi zqJM;(miBLxzD_ac0l1e0HG;xfS;xjY)ntf5RKbe^Ht;gAqR1wZPyy8RG~%zc@aA4JNrL(!SI4ZrZ@#kjC}7gE#j2Zgei(Mr%UNAvBB%*VtdqPFo9@?0$2uKj=~ur zMxCyGFFGI>S=4qh%^=duFKsYCY67S)tjb2J6&<|Z-#)Ti^xZ;?b$tyK6)LS@tsrS| z@b^`jr!eWpR2D-6ft&n^3H>e~n|w+zE8_d^=gYOJR`BK1*RGVoQ@O)*>S6Wb#er^m zeGR)%lfLOxv^tfDShBobRfe zj(rvy*I8VPSs<0M9}tGC$^0F3h#|ctZ%;B|9p4bfQ>yfPuZ+6)7>Dhiy0OD`Jcxp6 z{;hl4O`b^_561`PFQAQ8S`TgGFRi9qB-MB%MPcz`*-7pJYpVD#b8 zHRO{uF4=s3<&LE@>b6?t`A!U^O}h_0*uD`dZ|q-wD|VgJSY#8bkwc^D|Dnzb6PKGU zlzI+H^6>Rk#;YblZ5i%t9sBu}cnn319yH4!JkBj0rj^!R3g57nCoh>kk1X-po~s-M z>vQIAvfN8T-9?^hBIu21VBE@>0BFg2RB$jt_x!A$8ErXdI|VHf<3kL#>YxIoGr-y! zxxf)^Js)A0kHtU$00001mtcyXtFRN?u-7zUqI*9pFie&Vru{?aMXOe ztP`TO106hqkTW%hJB95G|KxS&OJ#Y&`|*B@zjM}<8w;-KoK%CHi)m4Ns`9) zFQ*;DTYBAEn0MM)BY=I|27rk7Vd8Mn8xM=qVWjS2T5*b3!*;5&2mHp zB!8YMsQ;ziIDywrv*V6=#}i8rns!i7UzHi zV7o5j*J&8fFNym?0@uX-Y#J=MOg)D|yzs=JPe!Y6wtX!5fE3D&tNhbdFIO*;ob(hEe6x(*(6gkc0&sE!-#XEz(X7+lO$Biq*xu}v4SiNbUqk= zih3BggD`=@KmY&$000qnRby@Dl4ZZo+1IhYWt1K2zVd_-8 z6`U-;F=RsIV(uK64xJN7CGn~C${zJPHS|2?&N7sx$bh1Y>?~^{BsZ1fc>^$Q`WuMFy!R=7 zKJzM=CY)*C;}ob@GN8@Y5!HtD0KI6_&&t$VKjKF!K>mk8rc&AxR7Yk6Gx(lM6X2tp zZ|wy#&hKtdM#tFoAJJiHmQ0ZM47$QnyQe}y7uKLKH4#gq5T6)>P|8bPD-O{{Q^V7j z2sh^>{z;TM3bq#j00000000`d;d>#-)aQ~Az%Fn8+KfsDuFV;z2fig!mPbAQ=W3{P z{r`_92?$`kj1}E29Z17hl(=n%qa{8+GHqa2+TP@HAM`=(XN_)wOQfb7PJh zGS;iXiocOv%j|zdPN&f7dk5E6m91cM_S`=7#(&0lRy;PgS7$Unf^7w@L}a?u&ohW7 z>@F=fh;9M8LJ(NPl)PeqVAAsEq}LLKZk!74e;tWKfS`L@P~0X&2lP`b{sd|`&Cf;z z?29{N)!q{y&bbNS&6tHK@%e(kit0SzC$etr$D*QW`cDU)Fi2GTtOjAA+CL};3Cs(s z@Dfx8DMW!yc6cCEqG0DgZk5X)k@ypG1~&*00000008G_|>&Q6t6y}ytumxP`F?~~E z63R7UD!*a2IPQ3$MR7_OWd~%HXgs3Z5FTS6=`OzSe3PG>1A+)<29@6?cd4plk8s;a!iO{f$U-Wk0zd!&00000 g000000000000000000000000000000000000RHBwQ~&?~ literal 0 HcmV?d00001 diff --git a/boards/vicharak/shrike_lite/doc/index.rst b/boards/vicharak/shrike_lite/doc/index.rst new file mode 100644 index 000000000000..d61dafb50316 --- /dev/null +++ b/boards/vicharak/shrike_lite/doc/index.rst @@ -0,0 +1,126 @@ +.. zephyr:board:: shrike_lite + +Overview +******** + +`Shrike-lite`_ is a low-cost, open-source microcontroller + FPGA development board +combining an `RP2040`_ MCU and a 1120 LUT FPGA. It features a PMOD connector, +breadboard-compatible layout, integrated FPGA–MCU IO interface, QSPI flash, +dual user LEDs, and USB Type-C for power/programming. +Ideal for learners, hobbyists, and hardware/software co-design prototyping. + + +Hardware +******** + +- Microcontroller `RP2040`_, with a max frequency of 133 MHz +- Dual ARM Cortex M0+ cores +- 264 kByte SRAM +- 4 Mbyte QSPI flash +- GPIO +- ADC +- I2C +- SPI +- UART +- USB Type-C connector +- Dual user LEDs +- Debug Connector +- Reset and boot buttons +- 1120 LUT SLG47910 Low-Power FPGA +- Blue LED + + +Supported Features +================== + +.. zephyr:board-supported-hw:: + + +Programming +*********** + +The ``shrike_lite`` board is supported by the following runners: + +.. zephyr:board-supported-runners:: + +There are multiple ways to program and debug the `Shrike-lite`_ board. +All methods are standard to the way of programming and debugging for the `Raspberry Pi Pico`_. + +The supported format for pico series (UF2) is located at :file:`build/zephyr/zephyr.uf2` file. + +To build the application using USB Type-C connector, you can use the following command: + +.. zephyr-app-commands:: + :zephyr-app: samples/basic/blinky + :board: shrike_lite + :goals: build + +To build the application using `Raspberry Pi Debug Probe`_, you can use the following command: + +.. zephyr-app-commands:: + :zephyr-app: samples/basic/blinky + :board: shrike_lite + :goals: build + :gen-args: -DRPI_PICO_DEBUG_ADAPTER=cmsis-dap + + +Flashing the board +================== + +To flash the board, you can use the following methods: + +- USB Type-C connector (default) + +Press and hold the boot button while plugging in the USB Type-C connector +to enter the bootloader mode and show the mass storage volume named "RP1-RP2" in the file manager. + +You can either: + +Drag and drop the :file:`build/zephyr/zephyr.uf2` file to the mass storage volume to program the board. +You can also use the following command to program the board: + +.. zephyr-app-commands:: + :zephyr-app: samples/basic/blinky + :board: shrike_lite + :goals: flash + :flash-args: --runner uf2 + +Or use the following command to program the board to try another runner: + +.. zephyr-app-commands:: + :zephyr-app: samples/basic/blinky + :board: shrike_lite + :goals: flash + :flash-args: --openocd /usr/local/bin/openocd + + +Debugging the board +=================== + +To debug the board, + +Press and hold the boot button while the `Raspberry Pi Debug Probe`_ is connected +to enter the debug mode and show the mass storage volume named "RP1-RP2" in the file manager. + +.. zephyr-app-commands:: + :zephyr-app: samples/basic/blinky + :board: shrike_lite + :goals: debug + :debug-args: --openocd /usr/local/bin/openocd + +.. target-notes:: + +.. _Shrike-lite: + https://vicharak-in.github.io/shrike/introduction.html + +.. _Shrike-lite Source Repository: + https://github.com/vicharak-in/shrike + +.. _RP2040: + https://datasheets.raspberrypi.com/rp2040/rp2040-datasheet.pdf + +.. _Raspberry Pi Debug Probe: + https://www.raspberrypi.com/documentation/microcontrollers/debug-probe.html + +.. _Raspberry Pi Pico: + https://www.raspberrypi.com/products/raspberry-pi-pico/ diff --git a/boards/vicharak/shrike_lite/shrike_lite-pinctrl.dtsi b/boards/vicharak/shrike_lite/shrike_lite-pinctrl.dtsi new file mode 100644 index 000000000000..2246d203dff1 --- /dev/null +++ b/boards/vicharak/shrike_lite/shrike_lite-pinctrl.dtsi @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2025 Dhruv Menon + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&pinctrl { + fpga_pwr_default: fpga_pwr_default { + group1 { + pinmux = ; + }; + }; + + fpga_en_default: fpga_en_default { + group1 { + pinmux = ; + }; + }; + + fpga_flash_default: fpga_flash_default { + group1 { + pinmux = , , ; + }; + + group2 { + pinmux = ; + input-enable; + }; + }; + + /* I2C1 on pins 14 (SDA) and 15 (SCL): Connected to both pinout and FPGA */ + i2c1_default: i2c1_default { + group1 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + + group2 { + pinmux = ; + input-enable; + input-schmitt-enable; + }; + }; + + uart1_default: uart1_default { + group1 { + pinmux = ; + }; + + group2 { + pinmux = ; + input-enable; + }; + }; + + adc_default: adc_default { + group1 { + pinmux = , + , + , + ; + input-enable; + }; + }; +}; diff --git a/boards/vicharak/shrike_lite/shrike_lite.dts b/boards/vicharak/shrike_lite/shrike_lite.dts new file mode 100644 index 000000000000..a101565e4bb5 --- /dev/null +++ b/boards/vicharak/shrike_lite/shrike_lite.dts @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2025 Dhruv Menon + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include +#include "shrike_lite-pinctrl.dtsi" +#include + +/ { + chosen { + zephyr,sram = &sram0; + zephyr,flash = &flash0; + zephyr,flash-controller = &ssi; + zephyr,console = &uart1; + zephyr,shell-uart = &uart1; + zephyr,code-partition = &code_partition; + }; + + aliases { + /* I2C1 on pins 14/15, connected to both pinout and FPGA */ + fpga-i2c1 = &i2c1; + watchdog0 = &wdt0; + led0 = &blue_led; + }; + + zephyr,user { + io-channels = <&adc 0>, <&adc 1>, <&adc 2>, <&adc 3>; + }; + + leds: leds { + compatible = "gpio-leds"; + + blue_led: blue_led { + gpios = <&gpio0 4 GPIO_ACTIVE_HIGH>; + label = "Blue LED"; + }; + }; +}; + +&flash0 { + /* 4MB (32Mb) flash - W25Q32JV minus the 0x100 used for + * the second stage bootloader + */ + reg = <0x10000000 DT_SIZE_M(4)>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + /* Reserved memory for the second stage bootloader */ + second_stage_bootloader: partition@0 { + label = "second_stage_bootloader"; + reg = <0x00000000 0x100>; + read-only; + }; + + /* + * Usable flash. Starts at 0x100, after the bootloader. The partition + * size is 4MB minus the 0x100 bytes taken by the bootloader. + */ + code_partition: partition@100 { + label = "code-partition"; + reg = <0x100 (DT_SIZE_M(4) - 0x100)>; + read-only; + }; + }; +}; + +&gpio0 { + status = "okay"; +}; + +&uart1 { + current-speed = <115200>; + status = "okay"; + pinctrl-0 = <&uart1_default>; + pinctrl-names = "default"; +}; + +&i2c1 { + clock-frequency = ; + status = "okay"; + pinctrl-0 = <&i2c1_default>; + pinctrl-names = "default"; +}; + +&adc { + status = "okay"; + pinctrl-0 = <&adc_default>; + pinctrl-names = "default"; +}; + +&timer { + status = "okay"; +}; + +&wdt0 { + status = "okay"; +}; + +&rtc { + clocks = <&clocks RPI_PICO_CLKID_CLK_RTC>; + status = "okay"; +}; + +zephyr_udc0: &usbd { + status = "okay"; +}; + +&vreg { + regulator-always-on; + regulator-allowed-modes = ; +}; + +&xosc { + startup-delay-multiplier = <64>; +}; diff --git a/boards/vicharak/shrike_lite/shrike_lite.yaml b/boards/vicharak/shrike_lite/shrike_lite.yaml new file mode 100644 index 000000000000..7f78952418bb --- /dev/null +++ b/boards/vicharak/shrike_lite/shrike_lite.yaml @@ -0,0 +1,24 @@ +identifier: shrike_lite +name: Vicharak Shrike Lite +vendor: Vicharak +type: mcu +arch: arm +flash: 4096 +ram: 264 +toolchain: + - zephyr + - gnuarmemb +supported: + - uart + - gpio + - adc + - i2c + - spi + - hwinfo + - watchdog + - pwm + - flash + - dma + - counter + - clock + - pio diff --git a/boards/vicharak/shrike_lite/shrike_lite_defconfig b/boards/vicharak/shrike_lite/shrike_lite_defconfig new file mode 100644 index 000000000000..597b2afa9554 --- /dev/null +++ b/boards/vicharak/shrike_lite/shrike_lite_defconfig @@ -0,0 +1,15 @@ +# Shrike Lite board configuration +# +# Copyright (c) 2026 Dhruv Menon +# +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SERIAL=y +CONFIG_UART_INTERRUPT_DRIVEN=y +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_GPIO=y +CONFIG_RESET=y +CONFIG_CLOCK_CONTROL=y +CONFIG_USE_DT_CODE_PARTITION=y +CONFIG_BUILD_OUTPUT_UF2=y diff --git a/dts/bindings/vendor-prefixes.txt b/dts/bindings/vendor-prefixes.txt index bc3af74bedcb..09dd15e40af7 100644 --- a/dts/bindings/vendor-prefixes.txt +++ b/dts/bindings/vendor-prefixes.txt @@ -740,6 +740,7 @@ variscite Variscite Ltd. vcc-gnd VCC-GND Studio vdl Van der Laan b.v. via VIA Technologies, Inc. +vicharak Vicharak videostrong Videostrong Technology Co., Ltd. virtio Virtual I/O Device Specification, developed by the OASIS consortium virtual Used for virtual device without specific vendor. From 995a77ae3ed93833f2efdae413c9518ade213ca1 Mon Sep 17 00:00:00 2001 From: Jonas Berg Date: Mon, 5 Jan 2026 23:11:24 +0100 Subject: [PATCH 1713/3659] boards: Add Grove headers for Cytron Maker Uno RP2040 Added the six Grove headers (and the Stemma QT header) to a separate devicetree include file. Signed-off-by: Jonas Berg --- .../maker_uno_rp2040/grove_connectors.dtsi | 70 +++++++++++++++++++ .../maker_uno_rp2040/maker_uno_rp2040.dts | 10 +-- 2 files changed, 71 insertions(+), 9 deletions(-) create mode 100644 boards/cytron/maker_uno_rp2040/grove_connectors.dtsi diff --git a/boards/cytron/maker_uno_rp2040/grove_connectors.dtsi b/boards/cytron/maker_uno_rp2040/grove_connectors.dtsi new file mode 100644 index 000000000000..6b2302851486 --- /dev/null +++ b/boards/cytron/maker_uno_rp2040/grove_connectors.dtsi @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2026 Jonas Berg + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + grove_header1: grove_header1 { + compatible = "grove-header"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <0 0 &gpio0 1 0>, /* RX */ + <1 0 &gpio0 0 0>; /* TX */ + }; + + grove_header2: grove_header2 { + compatible = "grove-header"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <0 0 &gpio0 5 0>, + <1 0 &gpio0 4 0>; + }; + + grove_header3: grove_header3 { + compatible = "grove-header"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <0 0 &gpio0 26 0>, /* ADC0 */ + <1 0 &gpio0 6 0>; + }; + + grove_header4: grove_header4 { + compatible = "grove-header"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <0 0 &gpio0 27 0>, /* ADC1 */ + <1 0 &gpio0 7 0>; + }; + + grove_header5: grove_header5 { + compatible = "grove-header"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <0 0 &gpio0 29 0>, /* ADC3 */ + <1 0 &gpio0 28 0>; /* ADC2 */ + }; + + grove_header6: grove_header6 { + compatible = "grove-header"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <0 0 &gpio0 21 0>, /* SCL */ + <1 0 &gpio0 20 0>; /* SDA */ + }; + + stemma_connector: stemma_connector { + compatible = "stemma-qt-connector"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <0 0 &gpio0 21 0>, /* SCL */ + <1 0 &gpio0 20 0>; /* SDA */ + }; +}; diff --git a/boards/cytron/maker_uno_rp2040/maker_uno_rp2040.dts b/boards/cytron/maker_uno_rp2040/maker_uno_rp2040.dts index b527184ffd70..8b466b973532 100644 --- a/boards/cytron/maker_uno_rp2040/maker_uno_rp2040.dts +++ b/boards/cytron/maker_uno_rp2040/maker_uno_rp2040.dts @@ -13,6 +13,7 @@ #include #include #include "arduino_r3_connector.dtsi" +#include "grove_connectors.dtsi" #include "maker_uno_rp2040-pinctrl.dtsi" / { @@ -57,15 +58,6 @@ label = "LED GP3"; }; }; - - stemma_connector: stemma_connector { - compatible = "stemma-qt-connector"; - #gpio-cells = <2>; - gpio-map-mask = <0xffffffff 0xffffffc0>; - gpio-map-pass-thru = <0 0x3f>; - gpio-map = <0 0 &gpio0 21 0>, /* SCL */ - <1 0 &gpio0 20 0>; /* SDA */ - }; }; &flash0 { From 03eab92f89fd72aa45719369f4a9139f2ebeb203 Mon Sep 17 00:00:00 2001 From: Camille BAUD Date: Fri, 9 Jan 2026 16:35:55 +0100 Subject: [PATCH 1714/3659] drivers: i2c: Fix BFLB I2C again again Maybe the last time? associated issue outlines details Signed-off-by: Camille BAUD --- drivers/i2c/i2c_bflb.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/i2c/i2c_bflb.c b/drivers/i2c/i2c_bflb.c index 6ebb9df39e9e..5e4829f9fa86 100644 --- a/drivers/i2c/i2c_bflb.c +++ b/drivers/i2c/i2c_bflb.c @@ -408,7 +408,7 @@ static inline bool i2c_bflb_errored(const struct device *dev) return (tmp & I2C_ARB_INT) != 0 || (tmp & I2C_FER_INT) != 0; } -static inline int i2c_bflb_write(const struct device *dev, uint8_t *buf, uint8_t len) +__no_optimization static int i2c_bflb_write(const struct device *dev, uint8_t *buf, uint8_t len) { const struct i2c_bflb_cfg *config = dev->config; uint32_t tmp; @@ -445,7 +445,7 @@ static inline int i2c_bflb_write(const struct device *dev, uint8_t *buf, uint8_t return 0; } -static inline int i2c_bflb_read(const struct device *dev, uint8_t *buf, uint8_t len) +__no_optimization static int i2c_bflb_read(const struct device *dev, uint8_t *buf, uint8_t len) { const struct i2c_bflb_cfg *config = dev->config; uint32_t tmp; @@ -480,7 +480,7 @@ static inline int i2c_bflb_read(const struct device *dev, uint8_t *buf, uint8_t return 0; } -static inline int i2c_bflb_prepare_transfer(const struct device *dev, +__no_optimization static int i2c_bflb_prepare_transfer(const struct device *dev, struct i2c_msg *msgs, uint8_t num_msgs) { struct i2c_bflb_data *data = dev->data; @@ -526,7 +526,6 @@ static inline int i2c_bflb_prepare_transfer(const struct device *dev, return i; } -/* GCC somehow keeps mangling that function into nonfunctionality. Nuke optimization. */ __no_optimization static int i2c_bflb_transfer(const struct device *dev, struct i2c_msg *msgs, uint8_t num_msgs, From 24db35949ec4e55913870cb285d31e59c031576f Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Fri, 9 Jan 2026 17:28:18 +0100 Subject: [PATCH 1715/3659] tests: benchmark: mbedtls: remove legacy crypto Kconfig This is a leftover from the past that is no more required and that should be removed in order to prepare for the next Mbed TLS release. Signed-off-by: Valerio Setti --- tests/benchmarks/mbedtls/prj.conf | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/benchmarks/mbedtls/prj.conf b/tests/benchmarks/mbedtls/prj.conf index 11c51832785c..ba24d6663924 100644 --- a/tests/benchmarks/mbedtls/prj.conf +++ b/tests/benchmarks/mbedtls/prj.conf @@ -1,7 +1,6 @@ CONFIG_TEST=y CONFIG_PRINTK=y -CONFIG_MBEDTLS_SHA256=y CONFIG_MBEDTLS=y CONFIG_MBEDTLS_PSA_CRYPTO_C=y From cc29ac78719bda0f928ba55596bdd67f5f66831c Mon Sep 17 00:00:00 2001 From: Charles Hardin Date: Fri, 9 Jan 2026 08:59:40 -0800 Subject: [PATCH 1716/3659] drivers: ethernet: lan9250: remove/simplifiy the runtime structure Remove the unused variable tid_int and lock. Also, match the other drivers by dropping the back reference to the device structure and just pass in the dev for the thread and dereference the context from there. Signed-off-by: Charles Hardin --- drivers/ethernet/eth_lan9250.c | 24 ++++++++++++------------ drivers/ethernet/eth_lan9250_priv.h | 6 ++---- 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/drivers/ethernet/eth_lan9250.c b/drivers/ethernet/eth_lan9250.c index 6821079fdd72..69d11db82ef9 100644 --- a/drivers/ethernet/eth_lan9250.c +++ b/drivers/ethernet/eth_lan9250.c @@ -575,7 +575,8 @@ static void lan9250_thread(void *p1, void *p2, void *p3) ARG_UNUSED(p2); ARG_UNUSED(p3); - struct lan9250_runtime *context = p1; + const struct device *dev = p1; + struct lan9250_runtime *context = dev->data; uint32_t int_sts; uint16_t tmp; uint32_t ier; @@ -584,18 +585,18 @@ static void lan9250_thread(void *p1, void *p2, void *p3) k_sem_take(&context->int_sem, K_FOREVER); /* Save interrupt enable register value */ - lan9250_read_sys_reg(context->dev, LAN9250_INT_EN, &ier); + lan9250_read_sys_reg(dev, LAN9250_INT_EN, &ier); /* Disable interrupts to release the interrupt line */ - lan9250_write_sys_reg(context->dev, LAN9250_INT_EN, 0); + lan9250_write_sys_reg(dev, LAN9250_INT_EN, 0); /* Read interrupt status register */ - lan9250_read_sys_reg(context->dev, LAN9250_INT_STS, &int_sts); + lan9250_read_sys_reg(dev, LAN9250_INT_STS, &int_sts); if ((int_sts & LAN9250_INT_STS_PHY_INT) != 0) { /* Read PHY interrupt source register */ - lan9250_read_phy_reg(context->dev, LAN9250_PHY_INTERRUPT_SOURCE, &tmp); + lan9250_read_phy_reg(dev, LAN9250_PHY_INTERRUPT_SOURCE, &tmp); if (tmp & LAN9250_PHY_INTERRUPT_SOURCE_LINK_UP) { LOG_DBG("LINK UP"); net_eth_carrier_on(context->iface); @@ -606,12 +607,12 @@ static void lan9250_thread(void *p1, void *p2, void *p3) } if ((int_sts & LAN9250_INT_STS_RSFL) != 0) { - lan9250_write_sys_reg(context->dev, LAN9250_INT_STS, LAN9250_INT_STS_RSFL); - lan9250_rx(context->dev); + lan9250_write_sys_reg(dev, LAN9250_INT_STS, LAN9250_INT_STS_RSFL); + lan9250_rx(dev); } /* Re-enable interrupts */ - lan9250_write_sys_reg(context->dev, LAN9250_INT_EN, ier); + lan9250_write_sys_reg(dev, LAN9250_INT_EN, ier); } } @@ -663,8 +664,6 @@ static int lan9250_init(const struct device *dev) const struct lan9250_config *config = dev->config; struct lan9250_runtime *context = dev->data; - context->dev = dev; - /* SPI config */ if (!spi_is_ready_dt(&config->spi)) { LOG_ERR("SPI master port %s not ready", config->spi.bus->name); @@ -733,8 +732,9 @@ static int lan9250_init(const struct device *dev) lan9250_set_macaddr(dev); k_thread_create(&context->thread, context->thread_stack, - CONFIG_ETH_LAN9250_RX_THREAD_STACK_SIZE, lan9250_thread, context, NULL, - NULL, K_PRIO_COOP(CONFIG_ETH_LAN9250_RX_THREAD_PRIO), 0, K_NO_WAIT); + CONFIG_ETH_LAN9250_RX_THREAD_STACK_SIZE, + lan9250_thread, (void *)dev, NULL, NULL, + K_PRIO_COOP(CONFIG_ETH_LAN9250_RX_THREAD_PRIO), 0, K_NO_WAIT); LOG_INF("LAN9250 Initialized"); diff --git a/drivers/ethernet/eth_lan9250_priv.h b/drivers/ethernet/eth_lan9250_priv.h index 4c80c1e8173f..86b5f9ffeeb4 100644 --- a/drivers/ethernet/eth_lan9250_priv.h +++ b/drivers/ethernet/eth_lan9250_priv.h @@ -316,10 +316,9 @@ struct lan9250_config { struct lan9250_runtime { struct net_if *iface; - const struct device *dev; - K_KERNEL_STACK_MEMBER(thread_stack, CONFIG_ETH_LAN9250_RX_THREAD_STACK_SIZE); - k_tid_t tid_int; + K_KERNEL_STACK_MEMBER(thread_stack, + CONFIG_ETH_LAN9250_RX_THREAD_STACK_SIZE); struct k_thread thread; uint8_t mac_address[6]; @@ -327,7 +326,6 @@ struct lan9250_runtime { struct k_sem tx_rx_sem; struct k_sem int_sem; uint8_t buf[NET_ETH_MAX_FRAME_SIZE]; - struct k_mutex lock; }; #endif /*_LAN9250_*/ From 9035b77251ddc3038b20b88a036221284d16710e Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Tue, 13 Jan 2026 14:06:27 +0000 Subject: [PATCH 1717/3659] github: hello_world_multiplatform: trim the sdk list further Trim the sdk list down to arm and riscv64, should be good enough for testing the buildsystem and saves some disk space. Signed-off-by: Fabio Baltieri --- .github/workflows/hello_world_multiplatform.yaml | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/.github/workflows/hello_world_multiplatform.yaml b/.github/workflows/hello_world_multiplatform.yaml index 6d4e5cf369bc..00b22b9b875b 100644 --- a/.github/workflows/hello_world_multiplatform.yaml +++ b/.github/workflows/hello_world_multiplatform.yaml @@ -62,7 +62,7 @@ jobs: uses: zephyrproject-rtos/action-zephyr-setup@c125c5ebeeadbd727fa740b407f862734af1e52a # v1.0.9 with: app-path: zephyr - toolchains: aarch64-zephyr-elf:arc-zephyr-elf:arc64-zephyr-elf:arm-zephyr-eabi:mips-zephyr-elf:riscv64-zephyr-elf:sparc-zephyr-elf:x86_64-zephyr-elf:xtensa-dc233c_zephyr-elf:xtensa-sample_controller32_zephyr-elf:rx-zephyr-elf + toolchains: arm-zephyr-eabi:riscv64-zephyr-elf ccache-cache-key: hw-${{ matrix.os }} - name: Build firmware @@ -76,7 +76,15 @@ jobs: elif [ "${{ runner.os }}-${{ runner.arch }}" == "Linux-ARM64" ]; then EXTRA_TWISTER_FLAGS="--exclude-platform native_sim/native" fi - west twister --runtime-artifact-cleanup --force-color --inline-logs -T samples/hello_world -T samples/cpp/hello_world -v $EXTRA_TWISTER_FLAGS + west twister \ + -p native_sim -p qemu_cortex_m0 -p qemu_riscv32 -p qemu_riscv64 \ + --runtime-artifact-cleanup \ + --force-color \ + --inline-logs \ + -T samples/hello_world \ + -T samples/cpp/hello_world \ + -v \ + $EXTRA_TWISTER_FLAGS - name: Upload artifacts if: failure() From 3dfdfad2def10761fb120bfd8c14dde91134899a Mon Sep 17 00:00:00 2001 From: Gaetan Perrot Date: Tue, 13 Jan 2026 23:24:41 +0900 Subject: [PATCH 1718/3659] tests: drivers: eeprom: api: assert EEPROM size Verify that the EEPROM is large enough to hold the test write buffer before executing the test. This makes the test assumptions explicit and avoids unused variable in API test. Signed-off-by: Gaetan Perrot --- tests/drivers/eeprom/api/src/main.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/drivers/eeprom/api/src/main.c b/tests/drivers/eeprom/api/src/main.c index 5d311b7567d1..6f26c33120db 100644 --- a/tests/drivers/eeprom/api/src/main.c +++ b/tests/drivers/eeprom/api/src/main.c @@ -85,6 +85,8 @@ ZTEST_USER(eeprom, test_write_at_fixed_address) size = eeprom_get_size(eeprom); + zassert_true(size >= sizeof(wr_buf1), "EEPROM too small: %zu < %zu", size, sizeof(wr_buf1)); + for (int i = 0; i < 16; i++) { rc = eeprom_write(eeprom, address, wr_buf1, sizeof(wr_buf1)); zassert_equal(0, rc, "Unexpected error code (%d)", rc); From 417a37b20d274bccf300f8947d8b5e1057857989 Mon Sep 17 00:00:00 2001 From: Matin Lotfaliei Date: Tue, 13 Jan 2026 15:19:47 -0800 Subject: [PATCH 1719/3659] boards: vicharak: shrike_lite: Add full name to the board.yml boards: vicharak: shrike_lite: Add full name to the board.yml Add the missing `full_name` field for the shrike_lite board added in 3f3b528997a815d84a13fbc4a0b686129fc38b91 Signed-off-by: Matin Lotfaliei --- boards/vicharak/shrike_lite/board.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/boards/vicharak/shrike_lite/board.yml b/boards/vicharak/shrike_lite/board.yml index b8f09702a6ba..4992713b34d2 100644 --- a/boards/vicharak/shrike_lite/board.yml +++ b/boards/vicharak/shrike_lite/board.yml @@ -1,5 +1,6 @@ board: name: shrike_lite + full_name: Shrike-lite vendor: vicharak socs: - name: rp2040 From 6725a9a39b289920154a52ba764a1af8998a6240 Mon Sep 17 00:00:00 2001 From: Manojkumar Konisetty Date: Wed, 10 Dec 2025 20:53:58 +0530 Subject: [PATCH 1720/3659] drivers: i2c: update Infineon PDL I2C driver Implement I2C configure() handling in the driver to apply speed settings and default hardware options. Signed-off-by: Manojkumar Konisetty Signed-off-by: Sayooj K Karun --- drivers/i2c/i2c_infineon_pdl.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/i2c/i2c_infineon_pdl.c b/drivers/i2c/i2c_infineon_pdl.c index 8bb6956c4da5..050261e567dc 100644 --- a/drivers/i2c/i2c_infineon_pdl.c +++ b/drivers/i2c/i2c_infineon_pdl.c @@ -370,7 +370,11 @@ static int ifx_cat1_i2c_configure(const struct device *dev, uint32_t dev_config) #endif +#if defined(CONFIG_SOC_FAMILY_INFINEON_PSOC4) + Cy_SCB_I2C_Enable(config->base, &data->context); +#else Cy_SCB_I2C_Enable(config->base); +#endif irq_enable(config->irq_num); /* Register an I2C event callback handler */ @@ -575,7 +579,7 @@ static int ifx_cat1_i2c_init(const struct device *dev) config->irq_config_func(dev); - return 0; + return ifx_cat1_i2c_configure(dev, I2C_MODE_CONTROLLER | I2C_SPEED_SET(I2C_SPEED_STANDARD)); } void _i2c_free(const struct device *dev) From 78a4516cd9898a6daa85b54f8e0ec5c870e0b6c7 Mon Sep 17 00:00:00 2001 From: Manojkumar Konisetty Date: Wed, 10 Dec 2025 20:54:02 +0530 Subject: [PATCH 1721/3659] dts: infineon: add I2C pins for PSoC4100TP Include package-level I/O mapping for I2C pins in psoc4100tp.64-tqfp.dtsi Signed-off-by: Manojkumar Konisetty Signed-off-by: Sayooj K Karun --- .../psoc4/psoc4100tp/psoc4100tp.64-tqfp.dtsi | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/dts/arm/infineon/psoc4/psoc4100tp/psoc4100tp.64-tqfp.dtsi b/dts/arm/infineon/psoc4/psoc4100tp/psoc4100tp.64-tqfp.dtsi index 88a8d3fce22c..2059bc35353a 100644 --- a/dts/arm/infineon/psoc4/psoc4100tp/psoc4100tp.64-tqfp.dtsi +++ b/dts/arm/infineon/psoc4/psoc4100tp/psoc4100tp.64-tqfp.dtsi @@ -12,6 +12,72 @@ / { soc { pinctrl: pinctrl@40020000 { + /* scb_i2c_scl */ + /omit-if-no-ref/ p0_0_scb0_i2c_scl: p0_0_scb0_i2c_scl { + pinmux = ; + }; + + /omit-if-no-ref/ p1_4_scb1_i2c_scl: p1_4_scb1_i2c_scl { + pinmux = ; + }; + + /omit-if-no-ref/ p2_0_scb0_i2c_scl: p2_0_scb0_i2c_scl { + pinmux = ; + }; + + /omit-if-no-ref/ p3_3_scb0_i2c_scl: p3_3_scb0_i2c_scl { + pinmux = ; + }; + + /omit-if-no-ref/ p4_0_scb1_i2c_scl: p4_0_scb1_i2c_scl { + pinmux = ; + }; + + /omit-if-no-ref/ p5_1_scb1_i2c_scl: p5_1_scb1_i2c_scl { + pinmux = ; + }; + + /omit-if-no-ref/ p6_0_scb0_i2c_scl: p6_0_scb0_i2c_scl { + pinmux = ; + }; + + /omit-if-no-ref/ p6_3_scb1_i2c_scl: p6_3_scb1_i2c_scl { + pinmux = ; + }; + + /* scb_i2c_sda */ + /omit-if-no-ref/ p0_1_scb0_i2c_sda: p0_1_scb0_i2c_sda { + pinmux = ; + }; + + /omit-if-no-ref/ p1_5_scb1_i2c_sda: p1_5_scb1_i2c_sda { + pinmux = ; + }; + + /omit-if-no-ref/ p2_1_scb0_i2c_sda: p2_1_scb0_i2c_sda { + pinmux = ; + }; + + /omit-if-no-ref/ p3_2_scb0_i2c_sda: p3_2_scb0_i2c_sda { + pinmux = ; + }; + + /omit-if-no-ref/ p4_1_scb1_i2c_sda: p4_1_scb1_i2c_sda { + pinmux = ; + }; + + /omit-if-no-ref/ p5_2_scb1_i2c_sda: p5_2_scb1_i2c_sda { + pinmux = ; + }; + + /omit-if-no-ref/ p6_1_scb0_i2c_sda: p6_1_scb0_i2c_sda { + pinmux = ; + }; + + /omit-if-no-ref/ p6_4_scb1_i2c_sda: p6_4_scb1_i2c_sda { + pinmux = ; + }; + /* scb_uart_cts */ /omit-if-no-ref/ p0_2_scb0_uart_cts: p0_2_scb0_uart_cts { pinmux = ; From 1cf68612d4e2c39b501de32d3d8af6fffbd7feb2 Mon Sep 17 00:00:00 2001 From: Manojkumar Konisetty Date: Wed, 10 Dec 2025 20:54:04 +0530 Subject: [PATCH 1722/3659] boards: cy8cproto_041tp: enable I2C - Add pin control definitions with proper open-drain drive mode for SCL/SDA in cy8cproto_041tp-pinctrl.dtsi. - Add I2C node and clock configuration to cy8cproto_041tp.dts. Signed-off-by: Manojkumar Konisetty Signed-off-by: Sayooj K Karun --- .../cy8cproto_041tp/cy8cproto_041tp-pinctrl.dtsi | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/boards/infineon/cy8cproto_041tp/cy8cproto_041tp-pinctrl.dtsi b/boards/infineon/cy8cproto_041tp/cy8cproto_041tp-pinctrl.dtsi index 69a0a2db88ec..3a3fdd13c7be 100644 --- a/boards/infineon/cy8cproto_041tp/cy8cproto_041tp-pinctrl.dtsi +++ b/boards/infineon/cy8cproto_041tp/cy8cproto_041tp-pinctrl.dtsi @@ -13,3 +13,13 @@ &p5_1_scb0_uart_rx { input-enable; }; + +&p6_3_scb1_i2c_scl { + drive-open-drain; + input-enable; +}; + +&p6_4_scb1_i2c_sda { + drive-open-drain; + input-enable; +}; From efce139fcd4e973d9a57bdc2528f9d4cda09df2f Mon Sep 17 00:00:00 2001 From: Manojkumar Konisetty Date: Thu, 27 Nov 2025 18:49:51 +0530 Subject: [PATCH 1723/3659] drivers: I2C: Add Infineon PSOC4 I2C slave support De-initialize the SCB when switching between I2C master and slave modes Signed-off-by: Manojkumar Konisetty Signed-off-by: Sayooj K Karun --- drivers/i2c/i2c_infineon_pdl.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/drivers/i2c/i2c_infineon_pdl.c b/drivers/i2c/i2c_infineon_pdl.c index 050261e567dc..c5c07de0209a 100644 --- a/drivers/i2c/i2c_infineon_pdl.c +++ b/drivers/i2c/i2c_infineon_pdl.c @@ -163,6 +163,10 @@ static void ifx_master_event_handler(void *callback_arg, uint32_t event) k_sem_give(&data->transfer_sem); } + if (data->p_target_config == NULL) { + return; + } + if (0 != (CY_SCB_I2C_SLAVE_READ_EVENT & event)) { if (data->p_target_config->callbacks->read_requested) { data->p_target_config->callbacks->read_requested(data->p_target_config, @@ -318,6 +322,7 @@ static int ifx_cat1_i2c_configure(const struct device *dev, uint32_t dev_config) const struct ifx_cat1_i2c_config *config = dev->config; cy_en_scb_i2c_status_t rslt; int ret; + bool is_target_mode = false; if (dev_config != 0) { switch (I2C_SPEED_GET(dev_config)) { @@ -343,9 +348,13 @@ static int ifx_cat1_i2c_configure(const struct device *dev, uint32_t dev_config) if (dev_config & I2C_MODE_CONTROLLER) { _i2c_default_config.i2cMode = CY_SCB_I2C_MASTER; + is_target_mode = false; } else { _i2c_default_config.i2cMode = CY_SCB_I2C_SLAVE; + is_target_mode = true; } + } else { + is_target_mode = (_i2c_default_config.i2cMode == CY_SCB_I2C_SLAVE); } /* Acquire semaphore (block I2C operation for another thread) */ @@ -356,7 +365,16 @@ static int ifx_cat1_i2c_configure(const struct device *dev, uint32_t dev_config) _i2c_default_config.slaveAddress = data->slave_address; - /* Configure the I2C resource to be master */ + if (is_target_mode) { + _i2c_default_config.slaveAddressMask = 0; + _i2c_default_config.ackGeneralAddr = false; + } + + /* De-initialize SCB before re-configuring (required when switching modes) */ + Cy_SCB_I2C_Disable(config->base, &data->context); + Cy_SCB_I2C_DeInit(config->base); + + /* Configure the I2C resource */ rslt = Cy_SCB_I2C_Init(config->base, &_i2c_default_config, &data->context); if (rslt != CY_SCB_I2C_SUCCESS) { LOG_ERR("I2C configure failed with err 0x%x", rslt); @@ -367,7 +385,6 @@ static int ifx_cat1_i2c_configure(const struct device *dev, uint32_t dev_config) #ifdef USE_I2C_SET_PERI_DIVIDER _i2c_set_peri_divider(dev, CAT1_I2C_SPEED_STANDARD_HZ, (_i2c_default_config.i2cMode == CY_SCB_I2C_SLAVE)); - #endif #if defined(CONFIG_SOC_FAMILY_INFINEON_PSOC4) From ad1b0416086a8d3be327a93f2b254d967bf6627d Mon Sep 17 00:00:00 2001 From: Manojkumar Konisetty Date: Fri, 28 Nov 2025 20:27:56 +0530 Subject: [PATCH 1724/3659] samples: sensor: bme280: boards: Add overlay file - Add an overlay to enable bme280 sensor sample. - Contains configurations for I2C bus and Clock Signed-off-by: Manojkumar Konisetty Signed-off-by: Sayooj K Karun --- .../bme280/boards/cy8cproto_041tp.overlay | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 samples/sensor/bme280/boards/cy8cproto_041tp.overlay diff --git a/samples/sensor/bme280/boards/cy8cproto_041tp.overlay b/samples/sensor/bme280/boards/cy8cproto_041tp.overlay new file mode 100644 index 000000000000..d337cd3d1e07 --- /dev/null +++ b/samples/sensor/bme280/boards/cy8cproto_041tp.overlay @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +i2c1: &scb1 { + status = "okay"; + compatible = "infineon,i2c"; + clocks = <&peri_clk_div2>; + pinctrl-0 = <&p6_3_scb1_i2c_scl &p6_4_scb1_i2c_sda>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + + bme280@76 { + status = "okay"; + compatible = "bosch,bme280"; + reg = <0x76>; + label = "BME280_I2C"; + }; +}; From cc7c11f6d2cd4f839c1ed8e24981e0b7ba6e38d9 Mon Sep 17 00:00:00 2001 From: Manojkumar Konisetty Date: Fri, 9 Jan 2026 19:27:51 +0530 Subject: [PATCH 1725/3659] samples: sensor: mpu6050: boards: Add overlay file - Add an overlay to enable mpu6050 sensor sample. - Contains configurations for I2C bus and Clock Signed-off-by: Manojkumar Konisetty Signed-off-by: Sayooj K Karun --- .../mpu6050/boards/cy8cproto_041tp.overlay | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 samples/sensor/mpu6050/boards/cy8cproto_041tp.overlay diff --git a/samples/sensor/mpu6050/boards/cy8cproto_041tp.overlay b/samples/sensor/mpu6050/boards/cy8cproto_041tp.overlay new file mode 100644 index 000000000000..44bfa98cf5ec --- /dev/null +++ b/samples/sensor/mpu6050/boards/cy8cproto_041tp.overlay @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +i2c1: &scb1 { + status = "okay"; + compatible = "infineon,i2c"; + clocks = <&peri_clk_div2>; + pinctrl-0 = <&p6_3_scb1_i2c_scl &p6_4_scb1_i2c_sda>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + + mpu6050@68 { + compatible = "invensense,mpu6050"; + reg = <0x68>; + status = "okay"; + smplrt-div = <249>; + }; +}; From e0ee5cd6e91f87ee962019c4ab88a9957d9d9baa Mon Sep 17 00:00:00 2001 From: Gaetan Perrot Date: Thu, 1 Jan 2026 15:04:27 +0900 Subject: [PATCH 1726/3659] drivers: i3c: i3c_npcx: fix redundant NULL check npcx_i3c_do_ccc() dereferences the device pointer before checking it against NULL, making the defensive check ineffective. Remove the redundant check. Signed-off-by: Gaetan Perrot --- drivers/i3c/i3c_npcx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/i3c/i3c_npcx.c b/drivers/i3c/i3c_npcx.c index 071828c4d8e7..12108ed80d5b 100644 --- a/drivers/i3c/i3c_npcx.c +++ b/drivers/i3c/i3c_npcx.c @@ -1514,7 +1514,7 @@ static int npcx_i3c_do_ccc(const struct device *dev, struct i3c_ccc_payload *pay uint32_t intmask; int xfered_len; - if (dev == NULL || payload == NULL) { + if (payload == NULL) { return -EINVAL; } From c9d5d2f62fc8b93d8ac7790fb29a7d4f491af880 Mon Sep 17 00:00:00 2001 From: Jonas Berg Date: Sun, 4 Jan 2026 10:28:09 +0100 Subject: [PATCH 1727/3659] boards: shield: Add Adafruit MAX17048 fuel gauge shield Compile testing of the overlay file is done via the fuel-gauge sample. Product photo from https://learn.adafruit.com/assets/123027 with the license CC BY-SA 3.0 Signed-off-by: Jonas Berg --- .../shields/adafruit_max17048/Kconfig.shield | 5 ++ .../adafruit_max17048.overlay | 21 ++++++ .../doc/adafruit_max17048.webp | Bin 0 -> 46474 bytes .../shields/adafruit_max17048/doc/index.rst | 63 ++++++++++++++++++ boards/shields/adafruit_max17048/shield.yml | 10 +++ samples/drivers/fuel_gauge/sample.yaml | 5 ++ 6 files changed, 104 insertions(+) create mode 100644 boards/shields/adafruit_max17048/Kconfig.shield create mode 100644 boards/shields/adafruit_max17048/adafruit_max17048.overlay create mode 100644 boards/shields/adafruit_max17048/doc/adafruit_max17048.webp create mode 100644 boards/shields/adafruit_max17048/doc/index.rst create mode 100644 boards/shields/adafruit_max17048/shield.yml diff --git a/boards/shields/adafruit_max17048/Kconfig.shield b/boards/shields/adafruit_max17048/Kconfig.shield new file mode 100644 index 000000000000..66940330fa57 --- /dev/null +++ b/boards/shields/adafruit_max17048/Kconfig.shield @@ -0,0 +1,5 @@ +# Copyright (c) 2026 Jonas Berg +# SPDX-License-Identifier: Apache-2.0 + +config SHIELD_ADAFRUIT_MAX17048 + def_bool $(shields_list_contains,adafruit_max17048) diff --git a/boards/shields/adafruit_max17048/adafruit_max17048.overlay b/boards/shields/adafruit_max17048/adafruit_max17048.overlay new file mode 100644 index 000000000000..a90cb7e6b0ef --- /dev/null +++ b/boards/shields/adafruit_max17048/adafruit_max17048.overlay @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2026 Jonas Berg + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + fuel-gauge0 = &adafruit_max17048; + }; +}; + +&zephyr_i2c { + status = "okay"; + + adafruit_max17048: max17048@36 { + status = "okay"; + compatible = "maxim,max17048"; + reg = <0x36>; + }; +}; diff --git a/boards/shields/adafruit_max17048/doc/adafruit_max17048.webp b/boards/shields/adafruit_max17048/doc/adafruit_max17048.webp new file mode 100644 index 0000000000000000000000000000000000000000..4fdf824af8048cabdeea8ebcda4ae892e266fd7e GIT binary patch literal 46474 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

    &F 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 G0001z!P=w% literal 0 HcmV?d00001 diff --git a/boards/shields/adafruit_max17048/doc/index.rst b/boards/shields/adafruit_max17048/doc/index.rst new file mode 100644 index 000000000000..48f2203d2afd --- /dev/null +++ b/boards/shields/adafruit_max17048/doc/index.rst @@ -0,0 +1,63 @@ +.. _adafruit_max17048: + +Adafruit MAX17048 Shield +######################## + + +Overview +******** + +The `Adafruit MAX17048 Fuel Gauge Shield`_ features +an `Analog Devices MAX17048 Fuel Gauge`_ and two STEMMA QT connectors. +It measures voltage and state-of-charge of a lithium ion or lithium polymer cell. + +.. figure:: adafruit_max17048.webp + :align: center + :alt: Adafruit MAX17048 Shield + + Adafruit MAX17048 Shield (Credit: Adafruit) + + +Requirements +************ + +This shield can be used with boards which provide an I2C connector, for example STEMMA QT +or Qwiic connectors. The target board must define a ``zephyr_i2c`` node label. +See :ref:`shields` for more details. + + +Pin Assignments +=============== + ++--------------+-------------------------------+ +| Shield Pin | Function | ++==============+===============================+ +| SCL | I2C SCL | ++--------------+-------------------------------+ +| SDA | I2C SDA | ++--------------+-------------------------------+ +| INT | Interrupt output | ++--------------+-------------------------------+ +| QStart | Quick-start reset input | ++--------------+-------------------------------+ + +See :dtcompatible:`maxim,max17048` for documentation on how to adjust the devicetree file. + + +Programming +*********** + +Set ``--shield adafruit_max17048`` when you invoke ``west build``. For example when running +the :zephyr:code-sample:`fuel_gauge` sample: + +.. zephyr-app-commands:: + :zephyr-app: samples/drivers/fuel_gauge + :board: adafruit_feather_canbus_rp2040 + :shield: adafruit_max17048 + :goals: build flash + +.. _Adafruit MAX17048 Fuel Gauge Shield: + https://learn.adafruit.com/adafruit-max17048-lipoly-liion-fuel-gauge-and-battery-monitor + +.. _Analog Devices MAX17048 Fuel Gauge: + https://www.analog.com/en/products/max17048.html diff --git a/boards/shields/adafruit_max17048/shield.yml b/boards/shields/adafruit_max17048/shield.yml new file mode 100644 index 000000000000..143e6a907ae5 --- /dev/null +++ b/boards/shields/adafruit_max17048/shield.yml @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# Copyright (c) 2026, Jonas Berg + +shield: + name: adafruit_max17048 + full_name: Adafruit MAX17048 Fuel Gauge Shield + vendor: adafruit + supported_features: + - fuel-gauge diff --git a/samples/drivers/fuel_gauge/sample.yaml b/samples/drivers/fuel_gauge/sample.yaml index 04a89b8954fb..8f2da27a84b3 100644 --- a/samples/drivers/fuel_gauge/sample.yaml +++ b/samples/drivers/fuel_gauge/sample.yaml @@ -18,3 +18,8 @@ tests: - adafruit_feather_esp32s2_tft_reverse/esp32s2 - adafruit_feather_esp32s3/esp32s3/procpu tags: fuel_gauge + sample.sensor.fuel_gauge.shields: + platform_allow: + - adafruit_feather_canbus_rp2040/rp2040 + extra_args: + - platform:adafruit_feather_canbus_rp2040/rp2040:SHIELD="adafruit_max17048" From 4c23ce63418f13a8293f811bf67fdb6b9fd0304a Mon Sep 17 00:00:00 2001 From: Peter Hoddie Date: Tue, 6 Jan 2026 15:11:12 -0800 Subject: [PATCH 1728/3659] boards: adafruit: correct gpio1 pins for feather_esp32s3_tft This DTS uses absolute GPIO numbers for pins on gpio1 rather than relative pin numbers. This causes an abort on boot when led1, neopixel_pwr, or mipi_dbi is enabled. Signed-off-by: Peter Hoddie --- .../adafruit_feather_esp32s3_tft_procpu.dts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/boards/adafruit/feather_esp32s3_tft/adafruit_feather_esp32s3_tft_procpu.dts b/boards/adafruit/feather_esp32s3_tft/adafruit_feather_esp32s3_tft_procpu.dts index 9670e66b26fa..3f7971fce669 100644 --- a/boards/adafruit/feather_esp32s3_tft/adafruit_feather_esp32s3_tft_procpu.dts +++ b/boards/adafruit/feather_esp32s3_tft/adafruit_feather_esp32s3_tft_procpu.dts @@ -58,7 +58,7 @@ }; led1: led_1 { - gpios = <&gpio1 45 GPIO_ACTIVE_HIGH>; + gpios = <&gpio1 13 GPIO_ACTIVE_HIGH>; }; }; @@ -69,7 +69,7 @@ neopixel_pwr: neopixel_pwr { compatible = "power-domain-gpio"; #power-domain-cells = <0>; - enable-gpios = <&gpio1 34 GPIO_ACTIVE_HIGH>; + enable-gpios = <&gpio1 2 GPIO_ACTIVE_HIGH>; }; /* @@ -85,8 +85,8 @@ mipi_dbi { compatible = "zephyr,mipi-dbi-spi"; spi-dev = <&spi2>; - dc-gpios = <&gpio1 39 GPIO_ACTIVE_HIGH>; - reset-gpios = <&gpio1 40 GPIO_ACTIVE_LOW>; + dc-gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>; + reset-gpios = <&gpio1 8 GPIO_ACTIVE_LOW>; write-only; #address-cells = <1>; #size-cells = <0>; From 08df06727c14894f437202628587c61c8e961e7d Mon Sep 17 00:00:00 2001 From: Albort Xue Date: Thu, 8 Jan 2026 12:46:14 +0800 Subject: [PATCH 1729/3659] drivers: clock_control: Consolidate NXP Kconfig files Multiple individual Kconfig files for NXP clock control drivers are consolidated into a single Kconfig.nxp file. This improves maintainability by grouping all NXP-related clock control configurations in one location. Signed-off-by: Albort Xue --- drivers/clock_control/Kconfig | 10 +-- drivers/clock_control/Kconfig.mcux_ccm | 11 --- drivers/clock_control/Kconfig.mcux_ccm_rev2 | 11 --- drivers/clock_control/Kconfig.mcux_mcg | 11 --- drivers/clock_control/Kconfig.mcux_pcc | 11 --- drivers/clock_control/Kconfig.mcux_scg | 19 ----- drivers/clock_control/Kconfig.mcux_sim | 11 --- drivers/clock_control/Kconfig.mcux_syscon | 12 --- drivers/clock_control/Kconfig.nxp | 84 +++++++++++++++++++++ drivers/clock_control/Kconfig.nxp_mc_cgm | 9 --- drivers/clock_control/Kconfig.nxp_s32 | 20 ----- 11 files changed, 85 insertions(+), 124 deletions(-) delete mode 100644 drivers/clock_control/Kconfig.mcux_ccm delete mode 100644 drivers/clock_control/Kconfig.mcux_ccm_rev2 delete mode 100644 drivers/clock_control/Kconfig.mcux_mcg delete mode 100644 drivers/clock_control/Kconfig.mcux_pcc delete mode 100644 drivers/clock_control/Kconfig.mcux_scg delete mode 100644 drivers/clock_control/Kconfig.mcux_sim delete mode 100644 drivers/clock_control/Kconfig.mcux_syscon create mode 100644 drivers/clock_control/Kconfig.nxp delete mode 100644 drivers/clock_control/Kconfig.nxp_mc_cgm delete mode 100644 drivers/clock_control/Kconfig.nxp_s32 diff --git a/drivers/clock_control/Kconfig b/drivers/clock_control/Kconfig index 7afb982a7abc..9443ec0eb2cf 100644 --- a/drivers/clock_control/Kconfig +++ b/drivers/clock_control/Kconfig @@ -44,20 +44,12 @@ source "drivers/clock_control/Kconfig.litex" source "drivers/clock_control/Kconfig.lpc11u6x" source "drivers/clock_control/Kconfig.max32" source "drivers/clock_control/Kconfig.mchp" -source "drivers/clock_control/Kconfig.mcux_ccm" -source "drivers/clock_control/Kconfig.mcux_ccm_rev2" -source "drivers/clock_control/Kconfig.mcux_mcg" -source "drivers/clock_control/Kconfig.mcux_pcc" -source "drivers/clock_control/Kconfig.mcux_scg" -source "drivers/clock_control/Kconfig.mcux_sim" -source "drivers/clock_control/Kconfig.mcux_syscon" source "drivers/clock_control/Kconfig.mspm0" source "drivers/clock_control/Kconfig.npcm" source "drivers/clock_control/Kconfig.npcx" source "drivers/clock_control/Kconfig.nrf" source "drivers/clock_control/Kconfig.numaker" -source "drivers/clock_control/Kconfig.nxp_mc_cgm" -source "drivers/clock_control/Kconfig.nxp_s32" +source "drivers/clock_control/Kconfig.nxp" source "drivers/clock_control/Kconfig.pwm" source "drivers/clock_control/Kconfig.rcar" source "drivers/clock_control/Kconfig.renesas_ra_cgc" diff --git a/drivers/clock_control/Kconfig.mcux_ccm b/drivers/clock_control/Kconfig.mcux_ccm deleted file mode 100644 index 0071ff273a98..000000000000 --- a/drivers/clock_control/Kconfig.mcux_ccm +++ /dev/null @@ -1,11 +0,0 @@ -# MCUXpresso SDK CCM - -# Copyright (c) 2017, NXP -# SPDX-License-Identifier: Apache-2.0 - -config CLOCK_CONTROL_MCUX_CCM - bool "MCUX CCM driver" - default y - depends on DT_HAS_NXP_IMX_CCM_ENABLED - help - Enable support for mcux ccm driver. diff --git a/drivers/clock_control/Kconfig.mcux_ccm_rev2 b/drivers/clock_control/Kconfig.mcux_ccm_rev2 deleted file mode 100644 index 6647259d85cc..000000000000 --- a/drivers/clock_control/Kconfig.mcux_ccm_rev2 +++ /dev/null @@ -1,11 +0,0 @@ -# MCUXpresso SDK CCM - -# Copyright (c) 2021, NXP -# SPDX-License-Identifier: Apache-2.0 - -config CLOCK_CONTROL_MCUX_CCM_REV2 - bool "MCUX CCM Rev 2 driver" - default y - depends on DT_HAS_NXP_IMX_CCM_REV2_ENABLED - help - Enable support for mcux ccm rev 2 driver. diff --git a/drivers/clock_control/Kconfig.mcux_mcg b/drivers/clock_control/Kconfig.mcux_mcg deleted file mode 100644 index 7e81d1d2d82c..000000000000 --- a/drivers/clock_control/Kconfig.mcux_mcg +++ /dev/null @@ -1,11 +0,0 @@ -# MCUXpresso SDK MCG - -# Copyright (c) 2019 Vestas Wind Systems A/S -# SPDX-License-Identifier: Apache-2.0 - -config CLOCK_CONTROL_MCUX_MCG - bool "MCUX MCG driver" - default y - depends on DT_HAS_NXP_KINETIS_MCG_ENABLED - help - Enable support for mcux mcg driver. diff --git a/drivers/clock_control/Kconfig.mcux_pcc b/drivers/clock_control/Kconfig.mcux_pcc deleted file mode 100644 index c085cbc7dafd..000000000000 --- a/drivers/clock_control/Kconfig.mcux_pcc +++ /dev/null @@ -1,11 +0,0 @@ -# MCUXpresso SDK PCC - -# Copyright (c) 2019 Vestas Wind Systems A/S -# SPDX-License-Identifier: Apache-2.0 - -config CLOCK_CONTROL_MCUX_PCC - bool "MCUX PCC driver" - default y - depends on DT_HAS_NXP_KINETIS_PCC_ENABLED - help - Enable support for MCUX PCC driver. diff --git a/drivers/clock_control/Kconfig.mcux_scg b/drivers/clock_control/Kconfig.mcux_scg deleted file mode 100644 index 1096154be60e..000000000000 --- a/drivers/clock_control/Kconfig.mcux_scg +++ /dev/null @@ -1,19 +0,0 @@ -# MCUXpresso SDK SCG - -# Copyright (c) 2019 Vestas Wind Systems A/S -# Copyright 2023 NXP -# SPDX-License-Identifier: Apache-2.0 - -config CLOCK_CONTROL_MCUX_SCG - bool "MCUX SCG driver" - default y - depends on DT_HAS_NXP_KINETIS_SCG_ENABLED - help - Enable support for mcux scg driver. - -config CLOCK_CONTROL_MCUX_SCG_K4 - bool "MCUX driver for K4 Generation SCG" - default y - depends on DT_HAS_NXP_SCG_K4_ENABLED - help - Enable support for SCG K4 driver diff --git a/drivers/clock_control/Kconfig.mcux_sim b/drivers/clock_control/Kconfig.mcux_sim deleted file mode 100644 index c4bef67678bf..000000000000 --- a/drivers/clock_control/Kconfig.mcux_sim +++ /dev/null @@ -1,11 +0,0 @@ -# MCUXpresso SDK SIM - -# Copyright (c) 2017, NXP -# SPDX-License-Identifier: Apache-2.0 - -config CLOCK_CONTROL_MCUX_SIM - bool "MCUX SIM driver" - default y - depends on DT_HAS_NXP_KINETIS_SIM_ENABLED - help - Enable support for mcux sim driver. diff --git a/drivers/clock_control/Kconfig.mcux_syscon b/drivers/clock_control/Kconfig.mcux_syscon deleted file mode 100644 index 48730fd20505..000000000000 --- a/drivers/clock_control/Kconfig.mcux_syscon +++ /dev/null @@ -1,12 +0,0 @@ -# MCUXpresso SDK SYSCON - -# Copyright (c) 2020, NXP -# SPDX-License-Identifier: Apache-2.0 - -config CLOCK_CONTROL_MCUX_SYSCON - bool "MCUX LPC clock driver" - default y - depends on DT_HAS_NXP_LPC_SYSCON_ENABLED - select PINCTRL - help - Enable support for mcux clock driver. diff --git a/drivers/clock_control/Kconfig.nxp b/drivers/clock_control/Kconfig.nxp new file mode 100644 index 000000000000..7d71f1b1685a --- /dev/null +++ b/drivers/clock_control/Kconfig.nxp @@ -0,0 +1,84 @@ +# Copyright 2026 NXP +# SPDX-License-Identifier: Apache-2.0 + +config CLOCK_CONTROL_MCUX_CCM + bool "MCUX CCM driver" + default y + depends on DT_HAS_NXP_IMX_CCM_ENABLED + help + Enable support for mcux ccm driver. + +config CLOCK_CONTROL_MCUX_CCM_REV2 + bool "MCUX CCM Rev 2 driver" + default y + depends on DT_HAS_NXP_IMX_CCM_REV2_ENABLED + help + Enable support for mcux ccm rev 2 driver. + +config CLOCK_CONTROL_MCUX_MCG + bool "MCUX MCG driver" + default y + depends on DT_HAS_NXP_KINETIS_MCG_ENABLED + help + Enable support for mcux mcg driver. + +config CLOCK_CONTROL_MCUX_PCC + bool "MCUX PCC driver" + default y + depends on DT_HAS_NXP_KINETIS_PCC_ENABLED + help + Enable support for MCUX PCC driver. + +config CLOCK_CONTROL_MCUX_SCG + bool "MCUX SCG driver" + default y + depends on DT_HAS_NXP_KINETIS_SCG_ENABLED + help + Enable support for mcux scg driver. + +config CLOCK_CONTROL_MCUX_SCG_K4 + bool "MCUX driver for K4 Generation SCG" + default y + depends on DT_HAS_NXP_SCG_K4_ENABLED + help + Enable support for SCG K4 driver + +config CLOCK_CONTROL_MCUX_SIM + bool "MCUX SIM driver" + default y + depends on DT_HAS_NXP_KINETIS_SIM_ENABLED + help + Enable support for mcux sim driver. + +config CLOCK_CONTROL_MCUX_SYSCON + bool "MCUX LPC clock driver" + default y + depends on DT_HAS_NXP_LPC_SYSCON_ENABLED + select PINCTRL + help + Enable support for mcux clock driver. + +config CLOCK_CONTROL_NXP_MC_CGM + bool "NXP MC_CGM clock driver" + default y + depends on DT_HAS_NXP_MC_CGM_ENABLED + help + Enable support for NXP MC_CGM clock driver. + +config CLOCK_CONTROL_NXP_S32 + bool "NXP S32 clock control driver" + default y + depends on DT_HAS_NXP_S32_CLOCK_ENABLED + help + Enable support for NXP S32 clock control driver. + +if CLOCK_CONTROL_NXP_S32 + +config CLOCK_CONTROL_NXP_S32_CLOCK_CONFIG_IDX + int + default 0 + help + This option specifies the zero-based index of the clock configuration + used to initialize the SoC clocks. + +endif # CLOCK_CONTROL_NXP_S32 diff --git a/drivers/clock_control/Kconfig.nxp_mc_cgm b/drivers/clock_control/Kconfig.nxp_mc_cgm deleted file mode 100644 index aba3c9b54d9a..000000000000 --- a/drivers/clock_control/Kconfig.nxp_mc_cgm +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright 2025 NXP -# SPDX-License-Identifier: Apache-2.0 - -config CLOCK_CONTROL_NXP_MC_CGM - bool "NXP MC_CGM clock driver" - default y - depends on DT_HAS_NXP_MC_CGM_ENABLED - help - Enable support for NXP MC_CGM clock driver. diff --git a/drivers/clock_control/Kconfig.nxp_s32 b/drivers/clock_control/Kconfig.nxp_s32 deleted file mode 100644 index c987a561664f..000000000000 --- a/drivers/clock_control/Kconfig.nxp_s32 +++ /dev/null @@ -1,20 +0,0 @@ -# Copyright 2023 NXP -# SPDX-License-Identifier: Apache-2.0 - -config CLOCK_CONTROL_NXP_S32 - bool "NXP S32 clock control driver" - default y - depends on DT_HAS_NXP_S32_CLOCK_ENABLED - help - Enable support for NXP S32 clock control driver. - -if CLOCK_CONTROL_NXP_S32 - -config CLOCK_CONTROL_NXP_S32_CLOCK_CONFIG_IDX - int - default 0 - help - This option specifies the zero-based index of the clock configuration - used to initialize the SoC clocks. - -endif # CLOCK_CONTROL_NXP_S32 From 084adcd4237db190904187c3ade2c4cd56a245b3 Mon Sep 17 00:00:00 2001 From: Siratul Islam Date: Fri, 9 Jan 2026 10:46:52 +0600 Subject: [PATCH 1730/3659] boards: arm: fix weact_stm32wb55_core led and button pins LED: PB2 -> PE4 BUTTON: PE4 -> PH3 Signed-off-by: Siratul Islam --- boards/weact/stm32wb55_core/weact_stm32wb55_core.dts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/boards/weact/stm32wb55_core/weact_stm32wb55_core.dts b/boards/weact/stm32wb55_core/weact_stm32wb55_core.dts index 56ba3ef7d015..0df22e25a86b 100644 --- a/boards/weact/stm32wb55_core/weact_stm32wb55_core.dts +++ b/boards/weact/stm32wb55_core/weact_stm32wb55_core.dts @@ -27,7 +27,7 @@ compatible = "gpio-leds"; blue_led: led_0 { - gpios = <&gpiob 2 GPIO_ACTIVE_HIGH>; + gpios = <&gpioe 4 GPIO_ACTIVE_HIGH>; label = "User LED"; }; }; @@ -37,7 +37,7 @@ boot_button: button_0 { label = "BOOT"; - gpios = <&gpioe 4 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + gpios = <&gpioh 3 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>; zephyr,code = ; }; }; From a309b3c1279e6d5b9de3433351eeb663d9cef6c4 Mon Sep 17 00:00:00 2001 From: Carlo Caione Date: Fri, 9 Jan 2026 16:31:10 +0100 Subject: [PATCH 1731/3659] drivers: lora: rename loramac_node directory to loramac-node Rename drivers/lora/loramac_node to drivers/lora/loramac-node to align with the module naming convention (modules/loramac-node). Signed-off-by: Carlo Caione --- drivers/lora/CMakeLists.txt | 2 +- drivers/lora/{loramac_node => loramac-node}/CMakeLists.txt | 0 drivers/lora/{loramac_node => loramac-node}/hal_common.c | 0 drivers/lora/{loramac_node => loramac-node}/sx126x.c | 0 drivers/lora/{loramac_node => loramac-node}/sx126x_common.h | 0 drivers/lora/{loramac_node => loramac-node}/sx126x_standalone.c | 0 drivers/lora/{loramac_node => loramac-node}/sx126x_stm32wl.c | 0 drivers/lora/{loramac_node => loramac-node}/sx127x.c | 0 drivers/lora/{loramac_node => loramac-node}/sx12xx_common.c | 0 drivers/lora/{loramac_node => loramac-node}/sx12xx_common.h | 0 10 files changed, 1 insertion(+), 1 deletion(-) rename drivers/lora/{loramac_node => loramac-node}/CMakeLists.txt (100%) rename drivers/lora/{loramac_node => loramac-node}/hal_common.c (100%) rename drivers/lora/{loramac_node => loramac-node}/sx126x.c (100%) rename drivers/lora/{loramac_node => loramac-node}/sx126x_common.h (100%) rename drivers/lora/{loramac_node => loramac-node}/sx126x_standalone.c (100%) rename drivers/lora/{loramac_node => loramac-node}/sx126x_stm32wl.c (100%) rename drivers/lora/{loramac_node => loramac-node}/sx127x.c (100%) rename drivers/lora/{loramac_node => loramac-node}/sx12xx_common.c (100%) rename drivers/lora/{loramac_node => loramac-node}/sx12xx_common.h (100%) diff --git a/drivers/lora/CMakeLists.txt b/drivers/lora/CMakeLists.txt index fc8e0d588e7f..f497ab47f56c 100644 --- a/drivers/lora/CMakeLists.txt +++ b/drivers/lora/CMakeLists.txt @@ -3,6 +3,6 @@ zephyr_sources_ifdef(CONFIG_LORA_SHELL shell.c) # zephyr-keep-sorted-start -add_subdirectory_ifdef(CONFIG_LORA_MODULE_BACKEND_LORAMAC_NODE loramac_node) +add_subdirectory_ifdef(CONFIG_LORA_MODULE_BACKEND_LORAMAC_NODE loramac-node) add_subdirectory_ifdef(CONFIG_LORA_MODULE_BACKEND_LORA_BASICS_MODEM lora_basics_modem) # zephyr-keep-sorted-stop diff --git a/drivers/lora/loramac_node/CMakeLists.txt b/drivers/lora/loramac-node/CMakeLists.txt similarity index 100% rename from drivers/lora/loramac_node/CMakeLists.txt rename to drivers/lora/loramac-node/CMakeLists.txt diff --git a/drivers/lora/loramac_node/hal_common.c b/drivers/lora/loramac-node/hal_common.c similarity index 100% rename from drivers/lora/loramac_node/hal_common.c rename to drivers/lora/loramac-node/hal_common.c diff --git a/drivers/lora/loramac_node/sx126x.c b/drivers/lora/loramac-node/sx126x.c similarity index 100% rename from drivers/lora/loramac_node/sx126x.c rename to drivers/lora/loramac-node/sx126x.c diff --git a/drivers/lora/loramac_node/sx126x_common.h b/drivers/lora/loramac-node/sx126x_common.h similarity index 100% rename from drivers/lora/loramac_node/sx126x_common.h rename to drivers/lora/loramac-node/sx126x_common.h diff --git a/drivers/lora/loramac_node/sx126x_standalone.c b/drivers/lora/loramac-node/sx126x_standalone.c similarity index 100% rename from drivers/lora/loramac_node/sx126x_standalone.c rename to drivers/lora/loramac-node/sx126x_standalone.c diff --git a/drivers/lora/loramac_node/sx126x_stm32wl.c b/drivers/lora/loramac-node/sx126x_stm32wl.c similarity index 100% rename from drivers/lora/loramac_node/sx126x_stm32wl.c rename to drivers/lora/loramac-node/sx126x_stm32wl.c diff --git a/drivers/lora/loramac_node/sx127x.c b/drivers/lora/loramac-node/sx127x.c similarity index 100% rename from drivers/lora/loramac_node/sx127x.c rename to drivers/lora/loramac-node/sx127x.c diff --git a/drivers/lora/loramac_node/sx12xx_common.c b/drivers/lora/loramac-node/sx12xx_common.c similarity index 100% rename from drivers/lora/loramac_node/sx12xx_common.c rename to drivers/lora/loramac-node/sx12xx_common.c diff --git a/drivers/lora/loramac_node/sx12xx_common.h b/drivers/lora/loramac-node/sx12xx_common.h similarity index 100% rename from drivers/lora/loramac_node/sx12xx_common.h rename to drivers/lora/loramac-node/sx12xx_common.h From 5e35f14b1e598b4aaa9067c4ece5f9f345b99c25 Mon Sep 17 00:00:00 2001 From: Carlo Caione Date: Sun, 11 Jan 2026 14:38:14 +0100 Subject: [PATCH 1732/3659] drivers: lora: rename lora_basics_modem directory to lora-basics-modem Rename the lora_basics_modem backend directory to lora-basics-modem for consistency with the module naming convention. Signed-off-by: Carlo Caione --- drivers/lora/CMakeLists.txt | 2 +- drivers/lora/Kconfig | 2 +- .../CMakeLists.txt | 8 ++++---- .../lora/{lora_basics_modem => lora-basics-modem}/Kconfig | 0 .../{lora_basics_modem => lora-basics-modem}/lbm_common.c | 0 .../{lora_basics_modem => lora-basics-modem}/lbm_common.h | 0 .../{lora_basics_modem => lora-basics-modem}/lbm_sx126x.c | 0 .../{lora_basics_modem => lora-basics-modem}/lbm_sx127x.c | 0 modules/lora-basics-modem/CMakeLists.txt | 6 +++--- 9 files changed, 9 insertions(+), 9 deletions(-) rename drivers/lora/{lora_basics_modem => lora-basics-modem}/CMakeLists.txt (79%) rename drivers/lora/{lora_basics_modem => lora-basics-modem}/Kconfig (100%) rename drivers/lora/{lora_basics_modem => lora-basics-modem}/lbm_common.c (100%) rename drivers/lora/{lora_basics_modem => lora-basics-modem}/lbm_common.h (100%) rename drivers/lora/{lora_basics_modem => lora-basics-modem}/lbm_sx126x.c (100%) rename drivers/lora/{lora_basics_modem => lora-basics-modem}/lbm_sx127x.c (100%) diff --git a/drivers/lora/CMakeLists.txt b/drivers/lora/CMakeLists.txt index f497ab47f56c..ffe19e77846e 100644 --- a/drivers/lora/CMakeLists.txt +++ b/drivers/lora/CMakeLists.txt @@ -4,5 +4,5 @@ zephyr_sources_ifdef(CONFIG_LORA_SHELL shell.c) # zephyr-keep-sorted-start add_subdirectory_ifdef(CONFIG_LORA_MODULE_BACKEND_LORAMAC_NODE loramac-node) -add_subdirectory_ifdef(CONFIG_LORA_MODULE_BACKEND_LORA_BASICS_MODEM lora_basics_modem) +add_subdirectory_ifdef(CONFIG_LORA_MODULE_BACKEND_LORA_BASICS_MODEM lora-basics-modem) # zephyr-keep-sorted-stop diff --git a/drivers/lora/Kconfig b/drivers/lora/Kconfig index 380d2d39728f..d322ebd3b042 100644 --- a/drivers/lora/Kconfig +++ b/drivers/lora/Kconfig @@ -54,6 +54,6 @@ config LORA_INIT_PRIORITY rsource "Kconfig.sx12xx" rsource "Kconfig.rylrxxx" -rsource "lora_basics_modem/Kconfig" +rsource "lora-basics-modem/Kconfig" endif # LORA diff --git a/drivers/lora/lora_basics_modem/CMakeLists.txt b/drivers/lora/lora-basics-modem/CMakeLists.txt similarity index 79% rename from drivers/lora/lora_basics_modem/CMakeLists.txt rename to drivers/lora/lora-basics-modem/CMakeLists.txt index be3f52fde9ee..ee7991afefe0 100644 --- a/drivers/lora/lora_basics_modem/CMakeLists.txt +++ b/drivers/lora/lora-basics-modem/CMakeLists.txt @@ -1,12 +1,12 @@ # SPDX-License-Identifier: Apache-2.0 -# LoRa drivers depend on the include directories exposed by the lora_basics_modem +# LoRa drivers depend on the include directories exposed by the lora-basics-modem # library. Hence, if it exists then the source files are added to that otherwise # a library with same name is created. -if(TARGET lora_basics_modem) - set(ZEPHYR_CURRENT_LIBRARY lora_basics_modem) +if(TARGET lora-basics-modem) + set(ZEPHYR_CURRENT_LIBRARY lora-basics-modem) else() - zephyr_library_named(lora_basics_modem) + zephyr_library_named(lora-basics-modem) endif() zephyr_library_sources(lbm_common.c) diff --git a/drivers/lora/lora_basics_modem/Kconfig b/drivers/lora/lora-basics-modem/Kconfig similarity index 100% rename from drivers/lora/lora_basics_modem/Kconfig rename to drivers/lora/lora-basics-modem/Kconfig diff --git a/drivers/lora/lora_basics_modem/lbm_common.c b/drivers/lora/lora-basics-modem/lbm_common.c similarity index 100% rename from drivers/lora/lora_basics_modem/lbm_common.c rename to drivers/lora/lora-basics-modem/lbm_common.c diff --git a/drivers/lora/lora_basics_modem/lbm_common.h b/drivers/lora/lora-basics-modem/lbm_common.h similarity index 100% rename from drivers/lora/lora_basics_modem/lbm_common.h rename to drivers/lora/lora-basics-modem/lbm_common.h diff --git a/drivers/lora/lora_basics_modem/lbm_sx126x.c b/drivers/lora/lora-basics-modem/lbm_sx126x.c similarity index 100% rename from drivers/lora/lora_basics_modem/lbm_sx126x.c rename to drivers/lora/lora-basics-modem/lbm_sx126x.c diff --git a/drivers/lora/lora_basics_modem/lbm_sx127x.c b/drivers/lora/lora-basics-modem/lbm_sx127x.c similarity index 100% rename from drivers/lora/lora_basics_modem/lbm_sx127x.c rename to drivers/lora/lora-basics-modem/lbm_sx127x.c diff --git a/modules/lora-basics-modem/CMakeLists.txt b/modules/lora-basics-modem/CMakeLists.txt index 0e9cab498dd5..ffdfc792e1ff 100644 --- a/modules/lora-basics-modem/CMakeLists.txt +++ b/modules/lora-basics-modem/CMakeLists.txt @@ -8,10 +8,10 @@ if(CONFIG_USE_LORA_BASICS_MODEM_DRIVERS) set(LBM_SMTC_MODEM_CORE_DIR ${LBM_LIB_DIR}/smtc_modem_core) set(LBM_RADIO_DRIVERS_DIR ${LBM_LIB_DIR}/smtc_modem_core/radio_drivers) - if(TARGET lora_basics_modem) - set(ZEPHYR_CURRENT_LIBRARY lora_basics_modem) + if(TARGET lora-basics-modem) + set(ZEPHYR_CURRENT_LIBRARY lora-basics-modem) else() - zephyr_library_named(lora_basics_modem) + zephyr_library_named(lora-basics-modem) endif() zephyr_library_include_directories(${LBM_SMTC_MODEM_CORE_DIR}/smtc_ral/src) From 3755392579d3fa2657ee3c4c5b0f6e977652438a Mon Sep 17 00:00:00 2001 From: Gaetan Perrot Date: Sat, 10 Jan 2026 02:32:43 +0900 Subject: [PATCH 1733/3659] sensing: sensor_mgmt: fix potential NULL dereferences Ensure pointers are validated before dereferencing them in set_arbitrate_interval() and set_interval(). This avoids accessing sensor or connection fields prior to validation and makes the code safe even when assertions are disabled. No functional change intended. Signed-off-by: Gaetan Perrot --- subsys/sensing/sensor_mgmt.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/subsys/sensing/sensor_mgmt.c b/subsys/sensing/sensor_mgmt.c index a3ce834c6498..c8437f9eb592 100644 --- a/subsys/sensing/sensor_mgmt.c +++ b/subsys/sensing/sensor_mgmt.c @@ -75,12 +75,14 @@ static uint32_t arbitrate_interval(struct sensing_sensor *sensor) static int set_arbitrate_interval(struct sensing_sensor *sensor, uint32_t interval) { - struct sensing_submit_config *config = sensor->iodev->data; + struct sensing_submit_config *config; struct sensor_value odr = {0}; int ret; __ASSERT(sensor && sensor->dev, "set arbitrate interval, sensor or sensor device is NULL"); + config = sensor->iodev->data; + LOG_INF("set arbitrate interval:%d, sensor:%s, is_streaming:%d", interval, sensor->dev->name, config->is_streaming); @@ -409,10 +411,10 @@ int sensing_register_callback(struct sensing_connection *conn, int set_interval(struct sensing_connection *conn, uint32_t interval) { - LOG_INF("set interval, sensor:%s, interval:%u(us)", conn->source->dev->name, interval); - __ASSERT(conn && conn->source, "set interval, connection or reporter not be NULL"); + LOG_INF("set interval, sensor:%s, interval:%u(us)", conn->source->dev->name, interval); + if (interval > 0 && interval < conn->source->info->minimal_interval) { LOG_ERR("interval:%d(us) should no less than min interval:%d(us)", interval, conn->source->info->minimal_interval); From 842d31c69142f6d1ac14fd419c57f80c110f10f7 Mon Sep 17 00:00:00 2001 From: Jay Vasanth Date: Fri, 9 Jan 2026 15:01:23 -0500 Subject: [PATCH 1734/3659] MAINTAINERS.YML: Add maintainer for Microchip MEC Adding additional maintainer - Scott Worley for Microchip MEC Platforms Signed-off-by: Jay Vasanth --- MAINTAINERS.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index 066895f3fdc2..8c8ebddfcdc8 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -3375,6 +3375,7 @@ Microchip MEC Platforms: status: maintained maintainers: - jvasanth1 + - scottwcpg collaborators: - VenkatKotakonda - albertofloyd From ec758c9d1cf2b1ea4e8831ac64d097d0489551d8 Mon Sep 17 00:00:00 2001 From: Muhammad Waleed Badar Date: Sat, 10 Jan 2026 00:59:46 +0500 Subject: [PATCH 1735/3659] drivers: wifi: esp32: use macro for mac address len Replace magic number used for mac address lenght with WIFI_MAC_ADDR_LEN macro Signed-off-by: Muhammad Waleed Badar --- drivers/wifi/esp32/src/esp_wifi_drv.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/wifi/esp32/src/esp_wifi_drv.c b/drivers/wifi/esp32/src/esp_wifi_drv.c index 07adfdb46d28..40633c15c167 100644 --- a/drivers/wifi/esp32/src/esp_wifi_drv.c +++ b/drivers/wifi/esp32/src/esp_wifi_drv.c @@ -66,7 +66,7 @@ struct esp32_wifi_status { }; struct esp32_wifi_runtime { - uint8_t mac_addr[6]; + uint8_t mac_addr[WIFI_MAC_ADDR_LEN]; uint8_t frame_buf[NET_ETH_MAX_FRAME_SIZE]; #if defined(CONFIG_NET_STATISTICS_WIFI) struct net_stats_wifi stats; @@ -376,7 +376,7 @@ static void esp_wifi_handle_ap_connect_event(void *event_data) for (int i = 0; i < sta_list.num; i++) { wifi_sta_info_t *sta = &sta_list.sta[i]; - if (memcmp(event->mac, sta->mac, 6) == 0) { + if (memcmp(event->mac, sta->mac, WIFI_MAC_ADDR_LEN) == 0) { if (sta->phy_11n) { sta_info.link_mode = WIFI_4; } else if (sta->phy_11g) { @@ -885,7 +885,7 @@ static void esp32_wifi_init(struct net_if *iface) #endif /* Assign link local address. */ - net_if_set_link_addr(iface, dev_data->mac_addr, 6, NET_LINK_ETHERNET); + net_if_set_link_addr(iface, dev_data->mac_addr, WIFI_MAC_ADDR_LEN, NET_LINK_ETHERNET); ethernet_init(iface); net_if_carrier_off(iface); @@ -909,7 +909,7 @@ static void esp32_wifi_init_ap(struct net_if *iface) wifi_nm_register_mgd_type_iface(nm, WIFI_TYPE_SAP, esp32_wifi_iface_ap); /* Assign link local address. */ - net_if_set_link_addr(iface, dev_data->mac_addr, 6, NET_LINK_ETHERNET); + net_if_set_link_addr(iface, dev_data->mac_addr, WIFI_MAC_ADDR_LEN, NET_LINK_ETHERNET); ethernet_init(iface); net_if_carrier_off(iface); From 4ff523d0fcc3e0068a0f416335b6012272d0063b Mon Sep 17 00:00:00 2001 From: Tom Burdick Date: Fri, 9 Jan 2026 16:33:09 -0600 Subject: [PATCH 1736/3659] boards: kit_pse84_eval: Add ram property Some tests depend on the ram board property to determine whether or not to run, like LLEXT tests. Set the ram property for this board. Signed-off-by: Tom Burdick --- boards/infineon/kit_pse84_eval/kit_pse84_eval_m33.yaml | 1 + boards/infineon/kit_pse84_eval/kit_pse84_eval_m55.yaml | 1 + 2 files changed, 2 insertions(+) diff --git a/boards/infineon/kit_pse84_eval/kit_pse84_eval_m33.yaml b/boards/infineon/kit_pse84_eval/kit_pse84_eval_m33.yaml index d91137ec41bc..29daa46ec3f2 100644 --- a/boards/infineon/kit_pse84_eval/kit_pse84_eval_m33.yaml +++ b/boards/infineon/kit_pse84_eval/kit_pse84_eval_m33.yaml @@ -8,6 +8,7 @@ name: PSOC Edge84 Evaluation Kit (M33_S) type: mcu arch: arm sysbuild: true +ram: 5120 toolchain: - zephyr supported: diff --git a/boards/infineon/kit_pse84_eval/kit_pse84_eval_m55.yaml b/boards/infineon/kit_pse84_eval/kit_pse84_eval_m55.yaml index 85a0bf3f10ca..9ed20693cc0d 100644 --- a/boards/infineon/kit_pse84_eval/kit_pse84_eval_m55.yaml +++ b/boards/infineon/kit_pse84_eval/kit_pse84_eval_m55.yaml @@ -7,6 +7,7 @@ identifier: kit_pse84_eval/pse846gps2dbzc4a/m55 name: PSOC Edge84 Evaluation Kit (M55) type: mcu arch: arm +ram: 5120 sysbuild: true toolchain: - zephyr From 1c1376189886e494ba66a6a13d95ce7e94cf8d39 Mon Sep 17 00:00:00 2001 From: Tom Burdick Date: Fri, 9 Jan 2026 16:35:55 -0600 Subject: [PATCH 1737/3659] boards: kit_pse84_ai: Add ram property Some tests depend on the ram board property to determine whether or not to run, like LLEXT tests. Set the ram property for this board. Signed-off-by: Tom Burdick --- boards/infineon/kit_pse84_ai/kit_pse84_ai_m33.yaml | 1 + boards/infineon/kit_pse84_ai/kit_pse84_ai_m55.yaml | 1 + 2 files changed, 2 insertions(+) diff --git a/boards/infineon/kit_pse84_ai/kit_pse84_ai_m33.yaml b/boards/infineon/kit_pse84_ai/kit_pse84_ai_m33.yaml index 2bab72aed7ac..ca3e4c9f1b2d 100644 --- a/boards/infineon/kit_pse84_ai/kit_pse84_ai_m33.yaml +++ b/boards/infineon/kit_pse84_ai/kit_pse84_ai_m33.yaml @@ -7,6 +7,7 @@ identifier: kit_pse84_ai/pse846gps2dbzc4a/m33 name: PSOC Edge84 AI Kit (M33_S) type: mcu arch: arm +ram: 5120 sysbuild: true toolchain: - zephyr diff --git a/boards/infineon/kit_pse84_ai/kit_pse84_ai_m55.yaml b/boards/infineon/kit_pse84_ai/kit_pse84_ai_m55.yaml index df37cbff7085..bc8cd3dc9471 100644 --- a/boards/infineon/kit_pse84_ai/kit_pse84_ai_m55.yaml +++ b/boards/infineon/kit_pse84_ai/kit_pse84_ai_m55.yaml @@ -7,6 +7,7 @@ identifier: kit_pse84_ai/pse846gps2dbzc4a/m55 name: PSOC Edge84 AI Kit (M55) type: mcu arch: arm +ram: 5120 sysbuild: true toolchain: - zephyr From 6834cd5dae0bf4406f8facd4929f91ad80aabeb3 Mon Sep 17 00:00:00 2001 From: Firas Sammoura Date: Fri, 9 Jan 2026 23:27:22 +0000 Subject: [PATCH 1738/3659] mem_mgmt: add mem_attr_get_region_index_by_name() Add a new API to look up a memory region's index using its DeviceTree node name. This allows callers to identify specific regions within the internal regions array. Includes unit tests for successful lookups and error handling for non-existent names. Signed-off-by: Firas Sammoura --- include/zephyr/mem_mgmt/mem_attr.h | 10 ++++++++++ subsys/mem_mgmt/mem_attr.c | 19 +++++++++++++++++++ tests/subsys/mem_mgmt/mem_attr/src/main.c | 22 ++++++++++++++++++++++ 3 files changed, 51 insertions(+) diff --git a/include/zephyr/mem_mgmt/mem_attr.h b/include/zephyr/mem_mgmt/mem_attr.h index 6e54c1cf40a0..b3d16cb91347 100644 --- a/include/zephyr/mem_mgmt/mem_attr.h +++ b/include/zephyr/mem_mgmt/mem_attr.h @@ -105,6 +105,16 @@ size_t mem_attr_get_regions(const struct mem_attr_region_t **region); */ int mem_attr_check_buf(void *addr, size_t size, uint32_t attr); +/** + * @brief Find the index of a memory region by its node name. + * + * @param target_name The memory node full name to search for. + * + * @return The index of the memory region in the regions array. + * @retval -ENOENT The region was not found. + */ +int mem_attr_get_region_index_by_name(const char *target_name); + #ifdef __cplusplus } #endif diff --git a/subsys/mem_mgmt/mem_attr.c b/subsys/mem_mgmt/mem_attr.c index c70a515dd817..8630307ba380 100644 --- a/subsys/mem_mgmt/mem_attr.c +++ b/subsys/mem_mgmt/mem_attr.c @@ -7,6 +7,8 @@ #include #include +#include + #define _BUILD_MEM_ATTR_REGION(node_id) \ { \ .dt_name = DT_NODE_FULL_NAME(node_id), \ @@ -59,3 +61,20 @@ int mem_attr_check_buf(void *v_addr, size_t size, uint32_t attr) } return -ENOBUFS; } + +int mem_attr_get_region_index_by_name(const char *target_name) +{ + const struct mem_attr_region_t *regions; + size_t num_regions; + + num_regions = mem_attr_get_regions(®ions); + + for (int i = 0; i < num_regions; ++i) { + if (regions[i].dt_name != NULL && + strcmp(regions[i].dt_name, target_name) == 0) { + return i; + } + } + + return -ENOENT; +} diff --git a/tests/subsys/mem_mgmt/mem_attr/src/main.c b/tests/subsys/mem_mgmt/mem_attr/src/main.c index 160c3d51801c..2f6253ec2736 100644 --- a/tests/subsys/mem_mgmt/mem_attr/src/main.c +++ b/tests/subsys/mem_mgmt/mem_attr/src/main.c @@ -84,4 +84,26 @@ ZTEST(mem_attr, test_mem_attr) -ENOBUFS, "Unexpected return value"); } +ZTEST(mem_attr, test_get_index_by_name_success) +{ + int index; + + /* Check first region */ + index = mem_attr_get_region_index_by_name("memory@10000000"); + zassert_equal(index, 0, "Index for 'memory@10000000 should be 0"); + + /* Check second region */ + index = mem_attr_get_region_index_by_name("memory@20000000"); + zassert_equal(index, 1, "Index for 'memory@20000000 should be 1"); +} + +ZTEST(mem_attr, test_get_index_by_name_not_found) +{ + int index; + + /* Search for a non-existent memory node name */ + index = mem_attr_get_region_index_by_name("memory@30000000"); + zassert_equal(index, -ENOENT, "Should return -ENOENT for unknown names"); +} + ZTEST_SUITE(mem_attr, NULL, NULL, NULL, NULL, NULL); From 646e93d29478467a686f4e5d5d256cef846dcc72 Mon Sep 17 00:00:00 2001 From: Gaetan Perrot Date: Sat, 10 Jan 2026 09:08:52 +0900 Subject: [PATCH 1739/3659] net: coap: coap_client: fix request validation order in coap_client_req Avoid accessing request fields before validating input arguments in coap_client_req(). The request path length is now checked only after validating the request pointer, preventing a potential NULL pointer dereference. No functional change intended. Signed-off-by: Gaetan Perrot --- subsys/net/lib/coap/coap_client.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/subsys/net/lib/coap/coap_client.c b/subsys/net/lib/coap/coap_client.c index 9ed507e7536a..1a75f9da2244 100644 --- a/subsys/net/lib/coap/coap_client.c +++ b/subsys/net/lib/coap/coap_client.c @@ -415,10 +415,15 @@ int coap_client_req(struct coap_client *client, int sock, const struct net_socka { int ret; struct coap_client_internal_request *internal_req; - size_t pathlen = strnlen(req->path, MAX_PATH_SIZE); + size_t pathlen; - if (client == NULL || sock < 0 || req == NULL || pathlen == 0 || - pathlen == MAX_PATH_SIZE || req->num_options > MAX_EXTRA_OPTIONS) { + if (client == NULL || sock < 0 || req == NULL || req->num_options > MAX_EXTRA_OPTIONS) { + return -EINVAL; + } + + pathlen = strnlen(req->path, MAX_PATH_SIZE); + + if (pathlen == 0 || pathlen == MAX_PATH_SIZE) { return -EINVAL; } From 8dbaca4131baf76822a38779330d193119de8e82 Mon Sep 17 00:00:00 2001 From: Matin Lotfaliei Date: Sun, 11 Jan 2026 18:22:43 -0800 Subject: [PATCH 1740/3659] drivers: sensor: bosch: bma4xx: Update RTIO callbacks with result arg drivers: sensor: bosch: bma4xx: Update RTIO callbacks with result argument Commit bc8d66d538931e650dd2855fabe768720dcb4b02 introduced a result argument to some RTIO callback handlers. Update for the BMA4XX sensor. Signed-off-by: Matin Lotfaliei --- drivers/sensor/bosch/bma4xx/bma4xx_rtio_stream.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/sensor/bosch/bma4xx/bma4xx_rtio_stream.c b/drivers/sensor/bosch/bma4xx/bma4xx_rtio_stream.c index 563c0f3cd816..dfb7bbc439ab 100644 --- a/drivers/sensor/bosch/bma4xx/bma4xx_rtio_stream.c +++ b/drivers/sensor/bosch/bma4xx/bma4xx_rtio_stream.c @@ -85,8 +85,9 @@ bma4xx_get_read_config_trigger(const struct sensor_read_config *cfg, enum sensor return NULL; } -static void bma4xx_complete_cb(struct rtio *r, const struct rtio_sqe *sqe, void *arg) +static void bma4xx_complete_cb(struct rtio *r, const struct rtio_sqe *sqe, int result, void *arg) { + ARG_UNUSED(result); const struct device *dev = arg; struct bma4xx_data *drv_data = dev->data; const struct bma4xx_config *drv_cfg = dev->config; @@ -97,8 +98,9 @@ static void bma4xx_complete_cb(struct rtio *r, const struct rtio_sqe *sqe, void gpio_pin_interrupt_configure_dt(&drv_cfg->gpio_interrupt, GPIO_INT_EDGE_TO_ACTIVE); } -static void bma4xx_fifo_count_cb(struct rtio *r, const struct rtio_sqe *sqe, void *arg) +static void bma4xx_fifo_count_cb(struct rtio *r, const struct rtio_sqe *sqe, int result, void *arg) { + ARG_UNUSED(result); const struct device *dev = arg; struct bma4xx_data *drv_data = dev->data; const struct bma4xx_config *drv_cfg = dev->config; @@ -192,8 +194,9 @@ static void bma4xx_fifo_count_cb(struct rtio *r, const struct rtio_sqe *sqe, voi rtio_submit(r, 0); } -static void bma4xx_int_status_cb(struct rtio *r, const struct rtio_sqe *sqr, void *arg) +static void bma4xx_int_status_cb(struct rtio *r, const struct rtio_sqe *sqr, int result, void *arg) { + ARG_UNUSED(result); const struct device *dev = arg; struct bma4xx_data *drv_data = dev->data; const struct bma4xx_config *drv_cfg = dev->config; From b1edb1903349c27a9767ecb9edf51bd3456dedd7 Mon Sep 17 00:00:00 2001 From: Abhinav Kulkarni Date: Mon, 12 Jan 2026 07:18:30 +0000 Subject: [PATCH 1741/3659] drivers: wifi: nxp: Added WLS support Added configuration to enable wifi location services. Signed-off-by: Abhinav Kulkarni --- drivers/wifi/nxp/Kconfig.nxp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/wifi/nxp/Kconfig.nxp b/drivers/wifi/nxp/Kconfig.nxp index eb10ac59a2ef..c6c5e5764022 100644 --- a/drivers/wifi/nxp/Kconfig.nxp +++ b/drivers/wifi/nxp/Kconfig.nxp @@ -843,6 +843,13 @@ config NXP_WIFI_CSI_AMI help This option enable/disable channel state information to calculate ambient motion index feature. +config NXP_WIFI_WLS + bool "Wireless Location Service" + select FPU + depends on NXP_WIFI_CSI + help + Enable/Disable Wireless Location Service(WLS) feature. + config NXP_WIFI_RESET bool "Wi-Fi reset" default y From 8dca624355c13ed28aad547bbdd602a0a209b5d3 Mon Sep 17 00:00:00 2001 From: Lyle Zhu Date: Mon, 12 Jan 2026 14:22:47 +0800 Subject: [PATCH 1742/3659] doc: bluetooth: reorganize Classic API documentation into subdirectory Reorganize Bluetooth Classic API documentation by moving existing files (SDP, RFCOMM, A2DP, HFP) into a new `classic/` subdirectory and adding new documentation files for L2CAP BR/EDR, AVRCP, GOEP, and BIP. Changes include: - Move existing Classic API docs to subdirectory `classic/` - Add new L2CAP BR/EDR documentation - Add AVRCP, GOEP, and BIP API reference documentation - Update HFP documentation to include both HFP Unit and HFP-AG sections - Update index.rst to reflect new directory structure - Add Doxygen group documentation to AVRCP header - Update AVRCP Cover Art to be a subgroup of AVRCP - Fix L2CAP BR/EDR Doxygen group name and description Signed-off-by: Lyle Zhu --- doc/_scripts/redirects.py | 4 + .../bluetooth/api/{ => classic}/a2dp.rst | 0 .../bluetooth/api/classic/avrcp.rst | 10 ++ .../bluetooth/api/classic/bip.rst | 10 ++ .../bluetooth/api/classic/goep.rst | 19 +++ .../bluetooth/api/classic/hfp.rst | 19 +++ .../bluetooth/api/classic/l2cap_br.rst | 123 ++++++++++++++++++ .../bluetooth/api/{ => classic}/rfcomm.rst | 0 .../bluetooth/api/{ => classic}/sdp.rst | 0 doc/connectivity/bluetooth/api/hfp.rst | 10 -- doc/connectivity/bluetooth/api/index.rst | 12 +- include/zephyr/bluetooth/classic/avrcp.h | 12 ++ .../bluetooth/classic/avrcp_cover_art.h | 4 +- include/zephyr/bluetooth/classic/l2cap_br.h | 4 +- .../bluetooth/classic/handsfree_ag/README.rst | 2 +- 15 files changed, 210 insertions(+), 19 deletions(-) rename doc/connectivity/bluetooth/api/{ => classic}/a2dp.rst (100%) create mode 100644 doc/connectivity/bluetooth/api/classic/avrcp.rst create mode 100644 doc/connectivity/bluetooth/api/classic/bip.rst create mode 100644 doc/connectivity/bluetooth/api/classic/goep.rst create mode 100644 doc/connectivity/bluetooth/api/classic/hfp.rst create mode 100644 doc/connectivity/bluetooth/api/classic/l2cap_br.rst rename doc/connectivity/bluetooth/api/{ => classic}/rfcomm.rst (100%) rename doc/connectivity/bluetooth/api/{ => classic}/sdp.rst (100%) delete mode 100644 doc/connectivity/bluetooth/api/hfp.rst diff --git a/doc/_scripts/redirects.py b/doc/_scripts/redirects.py index f9fafdee979a..72d34f9b4325 100644 --- a/doc/_scripts/redirects.py +++ b/doc/_scripts/redirects.py @@ -33,6 +33,7 @@ ('boards/x86/intel_rpl/doc/index', 'boards/intel/rpl/doc/index'), ('boards/x86/rpl_crb/doc/index', 'boards/x86/intel_rpl/doc/index'), + ('connectivity/bluetooth/api/a2dp', 'connectivity/bluetooth/api/classic/a2dp'), ('connectivity/bluetooth/api/audio/shell/bap', 'connectivity/bluetooth/shell/audio/bap'), ('connectivity/bluetooth/api/audio/shell/bap_broadcast_assistant', 'connectivity/bluetooth/shell/audio/bap_broadcast_assistant'), ('connectivity/bluetooth/api/audio/shell/bap_scan_delegator', 'connectivity/bluetooth/shell/audio/bap_scan_delegator'), @@ -43,6 +44,9 @@ ('connectivity/bluetooth/api/audio/shell/mcp', 'connectivity/bluetooth/shell/audio/mcp'), ('connectivity/bluetooth/api/audio/shell/pbp', 'connectivity/bluetooth/shell/audio/pbp'), ('connectivity/bluetooth/api/audio/shell/tmap', 'connectivity/bluetooth/shell/audio/tmap'), + ('connectivity/bluetooth/api/hfp', 'connectivity/bluetooth/api/classic/hfp'), + ('connectivity/bluetooth/api/rfcomm', 'connectivity/bluetooth/api/classic/rfcomm'), + ('connectivity/bluetooth/api/sdp', 'connectivity/bluetooth/api/classic/sdp'), ('connectivity/bluetooth/api/shell/iso', 'connectivity/bluetooth/shell/host/iso'), ('connectivity/bluetooth/audio', 'connectivity/bluetooth/api/audio/audio'), ('connectivity/bluetooth/bap', 'connectivity/bluetooth/api/audio/bap'), diff --git a/doc/connectivity/bluetooth/api/a2dp.rst b/doc/connectivity/bluetooth/api/classic/a2dp.rst similarity index 100% rename from doc/connectivity/bluetooth/api/a2dp.rst rename to doc/connectivity/bluetooth/api/classic/a2dp.rst diff --git a/doc/connectivity/bluetooth/api/classic/avrcp.rst b/doc/connectivity/bluetooth/api/classic/avrcp.rst new file mode 100644 index 000000000000..96795fdbd698 --- /dev/null +++ b/doc/connectivity/bluetooth/api/classic/avrcp.rst @@ -0,0 +1,10 @@ +.. _bt_avrcp: + +Audio Video Remote Control Profile (AVRCP) +########################################## + + +API Reference +************* + +.. doxygengroup:: bt_avrcp diff --git a/doc/connectivity/bluetooth/api/classic/bip.rst b/doc/connectivity/bluetooth/api/classic/bip.rst new file mode 100644 index 000000000000..ddd9d5d46182 --- /dev/null +++ b/doc/connectivity/bluetooth/api/classic/bip.rst @@ -0,0 +1,10 @@ +.. _bt_bip: + +Basic Imaging Profile (BIP) +########################### + + +API Reference +************* + +.. doxygengroup:: bt_bip diff --git a/doc/connectivity/bluetooth/api/classic/goep.rst b/doc/connectivity/bluetooth/api/classic/goep.rst new file mode 100644 index 000000000000..6b0995bc3a0d --- /dev/null +++ b/doc/connectivity/bluetooth/api/classic/goep.rst @@ -0,0 +1,19 @@ +.. _bt_goep: + +Generic Object Exchange Profile (GOEP) +###################################### + + +API Reference +************* + +Generic Object Exchange Profile (GOEP) +====================================== + +.. doxygengroup:: bt_goep + + +IrDA Object Exchange Protocol (OBEX) +==================================== + +.. doxygengroup:: bt_obex diff --git a/doc/connectivity/bluetooth/api/classic/hfp.rst b/doc/connectivity/bluetooth/api/classic/hfp.rst new file mode 100644 index 000000000000..ad5237b7d3dc --- /dev/null +++ b/doc/connectivity/bluetooth/api/classic/hfp.rst @@ -0,0 +1,19 @@ +.. _bt_hfp: + +Hands Free Profile (HFP) +######################## + + +API Reference +************* + +Hands Free Profile (HFP) Unit +============================= + +.. doxygengroup:: bt_hfp + + +Hands Free Profile - Audio Gateway (HFP-AG) +=========================================== + +.. doxygengroup:: bt_hfp_ag diff --git a/doc/connectivity/bluetooth/api/classic/l2cap_br.rst b/doc/connectivity/bluetooth/api/classic/l2cap_br.rst new file mode 100644 index 000000000000..49c76cec08b2 --- /dev/null +++ b/doc/connectivity/bluetooth/api/classic/l2cap_br.rst @@ -0,0 +1,123 @@ +.. _bt_l2cap_br: + +Bluetooth Logical Link Control and Adaptation Protocol (L2CAP) for BR/EDR +######################################################################### + +L2CAP BR/EDR provides support for Bluetooth Classic L2CAP (Logical Link Control and Adaptation +Protocol) features including ECHO request/response and connectionless data channels. + +ECHO Request/Response +********************* + +The L2CAP ECHO feature allows testing the connection by sending ECHO requests and receiving ECHO +responses. +Applications can register callbacks to monitor ECHO packets and send ECHO data. +The feature is enabled through the configuration option: :kconfig:option:`CONFIG_BT_CLASSIC`. + +Registering ECHO Callbacks +========================== + +To monitor ECHO request/response packets, register a :c:struct:`bt_l2cap_br_echo_cb` callback +structure: + +.. code-block:: c + + static void echo_req_cb(struct bt_conn *conn, uint8_t identifier, struct net_buf *buf) + { + /* Handle ECHO request */ + } + + static void echo_rsp_cb(struct bt_conn *conn, struct net_buf *buf) + { + /* Handle ECHO response */ + } + + static struct bt_l2cap_br_echo_cb echo_cb = { + .req = echo_req_cb, + .rsp = echo_rsp_cb, + }; + + bt_l2cap_br_echo_cb_register(&echo_cb); + +Sending ECHO Request +==================== + +To send an ECHO request, allocate a buffer with :c:macro:`BT_L2CAP_BR_ECHO_REQ_RESERVE` +bytes reserved for the L2CAP header: + +.. code-block:: c + + struct net_buf *buf; + + buf = net_buf_alloc(&pool, K_FOREVER); + net_buf_reserve(buf, BT_L2CAP_BR_ECHO_REQ_RESERVE); + net_buf_add_mem(buf, data, data_len); + + bt_l2cap_br_echo_req(conn, buf); + +Sending ECHO Response +===================== + +To send an ECHO response (typically in response to a received ECHO request), allocate a buffer with +:c:macro:`BT_L2CAP_BR_ECHO_RSP_RESERVE` bytes reserved for the L2CAP header: + +.. code-block:: c + + struct net_buf *buf; + + buf = net_buf_alloc(&pool, K_FOREVER); + net_buf_reserve(buf, BT_L2CAP_BR_ECHO_RSP_RESERVE); + net_buf_add_mem(buf, data, data_len); + + bt_l2cap_br_echo_rsp(conn, buf); + +The identifier parameter must match the identifier from the received ECHO request to properly +correlate the response with the request. + +Connectionless Data Channel +*************************** + +The connectionless data channel allows sending and receiving data to/from a specific PSM +(Protocol/Service Multiplexer) without establishing a connection-oriented L2CAP channel. +The feature is enabled through the configuration option: :kconfig:option:`CONFIG_BT_L2CAP_CONNLESS`. + +Registering Connectionless Callbacks +==================================== + +To receive connectionless data, register a :c:struct:`bt_l2cap_br_connless_cb` callback structure: + +.. code-block:: c + + static void connless_recv_cb(struct bt_conn *conn, uint16_t psm, struct net_buf *buf) + { + /* Handle received connectionless data */ + } + + static struct bt_l2cap_br_connless_cb connless_cb = { + .psm = MY_PSM, /* Or 0 to receive all */ + .sec_level = BT_SECURITY_L1, + .recv = connless_recv_cb, + }; + + bt_l2cap_br_connless_register(&connless_cb); + +Sending Connectionless Data +=========================== + +To send connectionless data, allocate a buffer with :c:macro:`BT_L2CAP_CONNLESS_RESERVE` +bytes reserved: + +.. code-block:: c + + struct net_buf *buf; + + buf = net_buf_alloc(&pool, K_FOREVER); + net_buf_reserve(buf, BT_L2CAP_CONNLESS_RESERVE); + net_buf_add_mem(buf, data, data_len); + + bt_l2cap_br_connless_send(conn, psm, buf); + +API Reference +************* + +.. doxygengroup:: bt_l2cap_br diff --git a/doc/connectivity/bluetooth/api/rfcomm.rst b/doc/connectivity/bluetooth/api/classic/rfcomm.rst similarity index 100% rename from doc/connectivity/bluetooth/api/rfcomm.rst rename to doc/connectivity/bluetooth/api/classic/rfcomm.rst diff --git a/doc/connectivity/bluetooth/api/sdp.rst b/doc/connectivity/bluetooth/api/classic/sdp.rst similarity index 100% rename from doc/connectivity/bluetooth/api/sdp.rst rename to doc/connectivity/bluetooth/api/classic/sdp.rst diff --git a/doc/connectivity/bluetooth/api/hfp.rst b/doc/connectivity/bluetooth/api/hfp.rst deleted file mode 100644 index ba504be78d8a..000000000000 --- a/doc/connectivity/bluetooth/api/hfp.rst +++ /dev/null @@ -1,10 +0,0 @@ -.. _bt_hfp: - -Hands Free Profile (HFP) -######################## - - -API Reference -************* - -.. doxygengroup:: bt_hfp diff --git a/doc/connectivity/bluetooth/api/index.rst b/doc/connectivity/bluetooth/api/index.rst index dc7a856cfb92..6e6c59ea9c8f 100644 --- a/doc/connectivity/bluetooth/api/index.rst +++ b/doc/connectivity/bluetooth/api/index.rst @@ -9,10 +9,14 @@ Bluetooth Classic Host and profiles .. toctree:: :maxdepth: 1 - hfp.rst - rfcomm.rst - sdp.rst - a2dp.rst + classic/sdp.rst + classic/l2cap_br.rst + classic/rfcomm.rst + classic/hfp.rst + classic/a2dp.rst + classic/avrcp.rst + classic/goep.rst + classic/bip.rst Bluetooth LE Audio ================== diff --git a/include/zephyr/bluetooth/classic/avrcp.h b/include/zephyr/bluetooth/classic/avrcp.h index ccef651c7614..4d15f51c8a99 100644 --- a/include/zephyr/bluetooth/classic/avrcp.h +++ b/include/zephyr/bluetooth/classic/avrcp.h @@ -5,6 +5,7 @@ /* * Copyright (c) 2015-2016 Intel Corporation * Copyright (C) 2024 Xiaomi Corporation + * Copyright 2025-2026 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -12,6 +13,13 @@ #ifndef ZEPHYR_INCLUDE_BLUETOOTH_AVRCP_H_ #define ZEPHYR_INCLUDE_BLUETOOTH_AVRCP_H_ +/** + * @brief Audio Video Remote Control Profile (AVRCP) + * @defgroup bt_avrcp Audio Video Remote Control Profile (AVRCP) + * @ingroup bluetooth + * @{ + */ + #ifdef __cplusplus extern "C" { #endif @@ -2422,4 +2430,8 @@ int bt_avrcp_tg_browsing_general_reject(struct bt_avrcp_tg *tg, uint8_t tid, uin } #endif +/** + * @} + */ + #endif /* ZEPHYR_INCLUDE_BLUETOOTH_AVRCP_H_ */ diff --git a/include/zephyr/bluetooth/classic/avrcp_cover_art.h b/include/zephyr/bluetooth/classic/avrcp_cover_art.h index 8e86ae5c9304..d0315f02451e 100644 --- a/include/zephyr/bluetooth/classic/avrcp_cover_art.h +++ b/include/zephyr/bluetooth/classic/avrcp_cover_art.h @@ -3,7 +3,7 @@ */ /* - * Copyright 2025 NXP + * Copyright 2025-2026 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -14,7 +14,7 @@ /** * @brief Audio Video Remote Control Cover Art Profile (AVRCP-CA) * @defgroup bt_avrcp_cover_art Audio Video Remote Control Cover Art Profile - * @ingroup bluetooth + * @ingroup bt_avrcp * @{ */ diff --git a/include/zephyr/bluetooth/classic/l2cap_br.h b/include/zephyr/bluetooth/classic/l2cap_br.h index 3d10d8218e9b..a508d3feabf0 100644 --- a/include/zephyr/bluetooth/classic/l2cap_br.h +++ b/include/zephyr/bluetooth/classic/l2cap_br.h @@ -11,8 +11,8 @@ #define ZEPHYR_INCLUDE_BLUETOOTH_L2CAP_BR_H_ /** - * @brief L2CAP - * @defgroup bt_l2cap L2CAP + * @brief Bluetooth Logical Link Control and Adaptation Protocol (L2CAP) for BR/EDR + * @defgroup bt_l2cap_br Bluetooth Logical Link Control and Adaptation Protocol (L2CAP) for BR/EDR * @ingroup bluetooth * @{ */ diff --git a/samples/bluetooth/classic/handsfree_ag/README.rst b/samples/bluetooth/classic/handsfree_ag/README.rst index 31b24bab35ed..e36b6a973ab1 100644 --- a/samples/bluetooth/classic/handsfree_ag/README.rst +++ b/samples/bluetooth/classic/handsfree_ag/README.rst @@ -1,6 +1,6 @@ .. zephyr:code-sample:: bluetooth_handsfree_ag :name: Hands-free Audio Gateway (AG) - :relevant-api: bt_hfp bluetooth + :relevant-api: bt_hfp_ag bluetooth Use the Hands-Free Profile Audio Gateway (AG) APIs. From dd76aa4402d5eaad4e47bcd715f99d39679e9348 Mon Sep 17 00:00:00 2001 From: Lyle Zhu Date: Tue, 13 Jan 2026 10:20:33 +0800 Subject: [PATCH 1743/3659] doc: maintainers: update Bluetooth Classic file patterns Update MAINTAINERS.yml to reflect the reorganization of Bluetooth Classic documentation into subdirectories. Replace specific file references with directory paths to cover all files within the classic/ subdirectories for both shell and API documentation. Changes include: - Replace specific a2dp.rst file reference with classic/ directory in Bluetooth Classic section - Add doc/connectivity/bluetooth/api/classic/ to Bluetooth Classic - Add doc/connectivity/bluetooth/api/classic/ to Bluetooth Host - Replace specific a2dp.rst with classic/ directory in Bluetooth Host Signed-off-by: Lyle Zhu --- MAINTAINERS.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index 8c8ebddfcdc8..64cd45e94c9b 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -486,7 +486,8 @@ Bluetooth Classic: - makeshi - chengkai15 files: - - doc/connectivity/bluetooth/shell/classic/a2dp.rst + - doc/connectivity/bluetooth/shell/classic/ + - doc/connectivity/bluetooth/api/classic/ - subsys/bluetooth/common/ - subsys/bluetooth/host/classic/ - include/zephyr/bluetooth/classic/ @@ -589,9 +590,10 @@ Bluetooth Host: - doc/connectivity/bluetooth/autopts/ - doc/connectivity/bluetooth/img/ctlr* - doc/connectivity/bluetooth/api/audio/ + - doc/connectivity/bluetooth/api/classic/ - doc/connectivity/bluetooth/api/mesh/ - doc/connectivity/bluetooth/api/controller.rst - - doc/connectivity/bluetooth/shell/classic/a2dp.rst + - doc/connectivity/bluetooth/shell/classic/ - doc/connectivity/bluetooth/shell/host/iso.rst - doc/connectivity/bluetooth/shell/audio/ - samples/bluetooth/bap*/ From a10d932c17d5c25ea7164479f468346766f9ee57 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Wed, 14 Jan 2026 11:30:21 +0000 Subject: [PATCH 1744/3659] workflows: manually update action-zephyr-setup Current version as a fix for something that is currently causing problems in CI and dependabot is failing too, update this one manually for now. Signed-off-by: Fabio Baltieri --- .github/workflows/doc-build.yml | 2 +- .github/workflows/errno.yml | 2 +- .github/workflows/hello_world_multiplatform.yaml | 2 +- .github/workflows/twister.yaml | 2 +- .github/workflows/twister_tests_blackbox.yml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/doc-build.yml b/.github/workflows/doc-build.yml index 5eb9c5534b7c..054fee42472e 100644 --- a/.github/workflows/doc-build.yml +++ b/.github/workflows/doc-build.yml @@ -230,7 +230,7 @@ jobs: echo "/opt/doxygen-${DOXYGEN_VERSION}/bin" >> $GITHUB_PATH - name: Setup Zephyr project - uses: zephyrproject-rtos/action-zephyr-setup@c125c5ebeeadbd727fa740b407f862734af1e52a # v1.0.9 + uses: zephyrproject-rtos/action-zephyr-setup@cefbf9086ce2da7d70e7ad9589af8aa1e4bda265 # v1.0.11 with: app-path: zephyr toolchains: 'arm-zephyr-eabi' diff --git a/.github/workflows/errno.yml b/.github/workflows/errno.yml index f717e62c68d7..906435200c02 100644 --- a/.github/workflows/errno.yml +++ b/.github/workflows/errno.yml @@ -20,7 +20,7 @@ jobs: path: zephyr - name: Setup Zephyr project - uses: zephyrproject-rtos/action-zephyr-setup@c125c5ebeeadbd727fa740b407f862734af1e52a # v1.0.9 + uses: zephyrproject-rtos/action-zephyr-setup@cefbf9086ce2da7d70e7ad9589af8aa1e4bda265 # v1.0.11 with: app-path: zephyr toolchains: 'arm-zephyr-eabi' diff --git a/.github/workflows/hello_world_multiplatform.yaml b/.github/workflows/hello_world_multiplatform.yaml index 00b22b9b875b..81f1ed60bd0d 100644 --- a/.github/workflows/hello_world_multiplatform.yaml +++ b/.github/workflows/hello_world_multiplatform.yaml @@ -59,7 +59,7 @@ jobs: python-version: 3.12 - name: Setup Zephyr project - uses: zephyrproject-rtos/action-zephyr-setup@c125c5ebeeadbd727fa740b407f862734af1e52a # v1.0.9 + uses: zephyrproject-rtos/action-zephyr-setup@cefbf9086ce2da7d70e7ad9589af8aa1e4bda265 # v1.0.11 with: app-path: zephyr toolchains: arm-zephyr-eabi:riscv64-zephyr-elf diff --git a/.github/workflows/twister.yaml b/.github/workflows/twister.yaml index 186373b15c5f..480003ffe56d 100644 --- a/.github/workflows/twister.yaml +++ b/.github/workflows/twister.yaml @@ -65,7 +65,7 @@ jobs: - name: Setup Zephyr project if: github.event_name == 'pull_request' - uses: zephyrproject-rtos/action-zephyr-setup@c125c5ebeeadbd727fa740b407f862734af1e52a # v1.0.9 + uses: zephyrproject-rtos/action-zephyr-setup@cefbf9086ce2da7d70e7ad9589af8aa1e4bda265 # v1.0.11 with: app-path: zephyr enable-ccache: false diff --git a/.github/workflows/twister_tests_blackbox.yml b/.github/workflows/twister_tests_blackbox.yml index 279a68f672be..58c010faf3a8 100644 --- a/.github/workflows/twister_tests_blackbox.yml +++ b/.github/workflows/twister_tests_blackbox.yml @@ -45,7 +45,7 @@ jobs: cache-dependency-path: scripts/requirements-actions.txt - name: Setup Zephyr project - uses: zephyrproject-rtos/action-zephyr-setup@c125c5ebeeadbd727fa740b407f862734af1e52a # v1.0.9 + uses: zephyrproject-rtos/action-zephyr-setup@cefbf9086ce2da7d70e7ad9589af8aa1e4bda265 # v1.0.11 with: app-path: zephyr toolchains: all From 1da7503904e63d0699b29b947d8d4c497ff3ce5a Mon Sep 17 00:00:00 2001 From: Alain Volmat Date: Mon, 10 Nov 2025 12:50:41 +0100 Subject: [PATCH 1745/3659] drivers: video: stm32-dcmi: correct set_frmival handling Correct set_frmival in order to avoid having un-optimized frmival selection due to rounded values. Computation has been done in usec, leading to incorrect frmival selection due to value being rounded internally. As an example, code was selecting 1/60 from sensor then 4 time frame drop by DCMI instead of selecting directly 1/15 from sensor. Use msec instead to hide those rounding issue and avoid as well 64bit variables. This also put the first video_frmival_nsec outside of the loop to avoid having to do the processing everytime. Signed-off-by: Alain Volmat --- drivers/video/video_stm32_dcmi.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/drivers/video/video_stm32_dcmi.c b/drivers/video/video_stm32_dcmi.c index 9d34344c902f..99ce615aa8e8 100644 --- a/drivers/video/video_stm32_dcmi.c +++ b/drivers/video/video_stm32_dcmi.c @@ -374,10 +374,12 @@ static int video_stm32_dcmi_set_frmival(const struct device *dev, struct video_f .format = &data->fmt, }; struct video_frmival best_sensor_frmival; - uint64_t best_diff_nsec = INT32_MAX; - uint64_t diff_nsec = 0, a, b; + uint32_t best_diff_us = INT32_MAX; + uint32_t diff_us = 0, a, b; int best_capture_rate = 1; + a = video_frmival_nsec(frmival) / USEC_PER_MSEC; + /* * Try to figure out a frameinterval setting allow to reach as close as * possible to the request. At first without relying on DCMI frame control, @@ -391,16 +393,15 @@ static int video_stm32_dcmi_set_frmival(const struct device *dev, struct video_f fie.discrete.numerator = frmival->numerator; fie.discrete.denominator = frmival->denominator * capture_rate; - a = video_frmival_nsec(&fie.discrete); video_closest_frmival(config->sensor_dev, &fie); - b = video_frmival_nsec(&fie.discrete); - diff_nsec = a > b ? a - b : b - a; - if (diff_nsec < best_diff_nsec) { - best_diff_nsec = diff_nsec; + b = video_frmival_nsec(&fie.discrete) * capture_rate / USEC_PER_MSEC; + diff_us = a > b ? a - b : b - a; + if (diff_us < best_diff_us) { + best_diff_us = diff_us; best_sensor_frmival = fie.discrete; best_capture_rate = capture_rate; } - if (diff_nsec == 0) { + if (diff_us == 0) { break; } } From 34757ac269fce11002f00e299cad23cdc786e83b Mon Sep 17 00:00:00 2001 From: Marek Matej Date: Tue, 16 Dec 2025 21:55:16 +0000 Subject: [PATCH 1746/3659] samples,tests: remove obsolete overlays Remove wifi enabling overlays that became obsolete. Signed-off-by: Marek Matej --- samples/net/wifi/shell/socs/esp32s2.overlay | 3 --- samples/net/wifi/shell/socs/esp32s3_procpu.overlay | 3 --- tests/boards/espressif/wifi/socs/esp32_procpu.overlay | 9 --------- tests/boards/espressif/wifi/socs/esp32c2.overlay | 9 --------- tests/boards/espressif/wifi/socs/esp32c3.overlay | 9 --------- tests/boards/espressif/wifi/socs/esp32c3_usb.overlay | 9 --------- tests/boards/espressif/wifi/socs/esp32c6_hpcore.overlay | 9 --------- tests/boards/espressif/wifi/socs/esp32s2.overlay | 9 --------- tests/boards/espressif/wifi/socs/esp32s3_procpu.overlay | 9 --------- 9 files changed, 69 deletions(-) delete mode 100644 samples/net/wifi/shell/socs/esp32s2.overlay delete mode 100644 samples/net/wifi/shell/socs/esp32s3_procpu.overlay delete mode 100644 tests/boards/espressif/wifi/socs/esp32_procpu.overlay delete mode 100644 tests/boards/espressif/wifi/socs/esp32c2.overlay delete mode 100644 tests/boards/espressif/wifi/socs/esp32c3.overlay delete mode 100644 tests/boards/espressif/wifi/socs/esp32c3_usb.overlay delete mode 100644 tests/boards/espressif/wifi/socs/esp32c6_hpcore.overlay delete mode 100644 tests/boards/espressif/wifi/socs/esp32s2.overlay delete mode 100644 tests/boards/espressif/wifi/socs/esp32s3_procpu.overlay diff --git a/samples/net/wifi/shell/socs/esp32s2.overlay b/samples/net/wifi/shell/socs/esp32s2.overlay deleted file mode 100644 index d342be1381c4..000000000000 --- a/samples/net/wifi/shell/socs/esp32s2.overlay +++ /dev/null @@ -1,3 +0,0 @@ -&wifi { - status = "okay"; -}; diff --git a/samples/net/wifi/shell/socs/esp32s3_procpu.overlay b/samples/net/wifi/shell/socs/esp32s3_procpu.overlay deleted file mode 100644 index d342be1381c4..000000000000 --- a/samples/net/wifi/shell/socs/esp32s3_procpu.overlay +++ /dev/null @@ -1,3 +0,0 @@ -&wifi { - status = "okay"; -}; diff --git a/tests/boards/espressif/wifi/socs/esp32_procpu.overlay b/tests/boards/espressif/wifi/socs/esp32_procpu.overlay deleted file mode 100644 index 872f2dfe2eab..000000000000 --- a/tests/boards/espressif/wifi/socs/esp32_procpu.overlay +++ /dev/null @@ -1,9 +0,0 @@ -/* - * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -&wifi { - status = "okay"; -}; diff --git a/tests/boards/espressif/wifi/socs/esp32c2.overlay b/tests/boards/espressif/wifi/socs/esp32c2.overlay deleted file mode 100644 index 872f2dfe2eab..000000000000 --- a/tests/boards/espressif/wifi/socs/esp32c2.overlay +++ /dev/null @@ -1,9 +0,0 @@ -/* - * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -&wifi { - status = "okay"; -}; diff --git a/tests/boards/espressif/wifi/socs/esp32c3.overlay b/tests/boards/espressif/wifi/socs/esp32c3.overlay deleted file mode 100644 index 872f2dfe2eab..000000000000 --- a/tests/boards/espressif/wifi/socs/esp32c3.overlay +++ /dev/null @@ -1,9 +0,0 @@ -/* - * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -&wifi { - status = "okay"; -}; diff --git a/tests/boards/espressif/wifi/socs/esp32c3_usb.overlay b/tests/boards/espressif/wifi/socs/esp32c3_usb.overlay deleted file mode 100644 index 872f2dfe2eab..000000000000 --- a/tests/boards/espressif/wifi/socs/esp32c3_usb.overlay +++ /dev/null @@ -1,9 +0,0 @@ -/* - * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -&wifi { - status = "okay"; -}; diff --git a/tests/boards/espressif/wifi/socs/esp32c6_hpcore.overlay b/tests/boards/espressif/wifi/socs/esp32c6_hpcore.overlay deleted file mode 100644 index 872f2dfe2eab..000000000000 --- a/tests/boards/espressif/wifi/socs/esp32c6_hpcore.overlay +++ /dev/null @@ -1,9 +0,0 @@ -/* - * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -&wifi { - status = "okay"; -}; diff --git a/tests/boards/espressif/wifi/socs/esp32s2.overlay b/tests/boards/espressif/wifi/socs/esp32s2.overlay deleted file mode 100644 index 872f2dfe2eab..000000000000 --- a/tests/boards/espressif/wifi/socs/esp32s2.overlay +++ /dev/null @@ -1,9 +0,0 @@ -/* - * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -&wifi { - status = "okay"; -}; diff --git a/tests/boards/espressif/wifi/socs/esp32s3_procpu.overlay b/tests/boards/espressif/wifi/socs/esp32s3_procpu.overlay deleted file mode 100644 index 872f2dfe2eab..000000000000 --- a/tests/boards/espressif/wifi/socs/esp32s3_procpu.overlay +++ /dev/null @@ -1,9 +0,0 @@ -/* - * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -&wifi { - status = "okay"; -}; From 742c23a352ab7767c8eb352d3a5bd6bc53cf2323 Mon Sep 17 00:00:00 2001 From: Gaetan Perrot Date: Sun, 28 Dec 2025 15:45:59 +0900 Subject: [PATCH 1747/3659] tests: drivers: flash: split mixed error conditions in negative tests Some flash negative tests were validating multiple error conditions in a single API call, such as combining unaligned offsets with oversized operations. This makes it unclear which condition is actually being tested and can lead to fragile tests if drivers change the order of validation. Split these cases so that each call checks a single expected error condition, improving test clarity and robustness. Signed-off-by: Gaetan Perrot --- tests/drivers/flash/negative_tests/src/main.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/tests/drivers/flash/negative_tests/src/main.c b/tests/drivers/flash/negative_tests/src/main.c index 890f4c0b3a1e..cc6c08df21c8 100644 --- a/tests/drivers/flash/negative_tests/src/main.c +++ b/tests/drivers/flash/negative_tests/src/main.c @@ -96,8 +96,12 @@ ZTEST(flash_driver_negative, test_negative_flash_erase) rc = flash_erase(flash_dev, (TEST_FLASH_START + TEST_FLASH_SIZE), page_info.size); zassert_true(rc < 0, "Invalid use of flash_erase returned %d", rc); - /* Check error returned when erasing unaligned memory or too large chunk of memory */ - rc = flash_erase(flash_dev, (TEST_AREA_OFFSET + 1), (TEST_FLASH_SIZE + 1)); + /* Check error returned when erasing unaligned memory */ + rc = flash_erase(flash_dev, (TEST_AREA_OFFSET + 1), page_info.size); + zassert_true(rc < 0, "Invalid use of flash_erase returned %d", rc); + + /* Check error returned when erasing too large chunk of memory */ + rc = flash_erase(flash_dev, TEST_AREA_OFFSET, (TEST_FLASH_SIZE + 1)); zassert_true(rc < 0, "Invalid use of flash_erase returned %d", rc); /* Erasing 0 bytes shall succeed */ @@ -230,8 +234,12 @@ ZTEST(flash_driver_negative, test_negative_flash_write) rc = flash_write(flash_dev, (TEST_FLASH_START + TEST_FLASH_SIZE), expected, page_info.size); zassert_true(rc < 0, "Invalid use of flash_write returned %d", rc); - /* Check error returned when writing at unaligned memory or too large chunk of memory */ - rc = flash_write(flash_dev, (TEST_AREA_OFFSET + 1), expected, (TEST_FLASH_SIZE + 1)); + /* Check error returned when writing at unaligned memory */ + rc = flash_write(flash_dev, (TEST_AREA_OFFSET + 1), expected, page_info.size); + zassert_true(rc < 0, "Invalid use of flash_write returned %d", rc); + + /* Check error returned when writing too large chunk of memory */ + rc = flash_write(flash_dev, TEST_AREA_OFFSET, expected, (TEST_FLASH_SIZE + 1)); zassert_true(rc < 0, "Invalid use of flash_write returned %d", rc); /* Writing 0 bytes shall succeed */ From bbf0187913fe712010ae2bd45637211058cf8920 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrzej=20G=C5=82=C4=85bek?= Date: Fri, 2 Jan 2026 11:58:36 +0100 Subject: [PATCH 1748/3659] drivers: mspi_dw: Remove needless `packet` parameter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit FIFO handling functions in the driver are supplied with a `packet` parameter that is in fact not used anymore. Remove it to simplify matters. Signed-off-by: Andrzej Głąbek --- drivers/mspi/mspi_dw.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/drivers/mspi/mspi_dw.c b/drivers/mspi/mspi_dw.c index df33d5f88208..ca783114d627 100644 --- a/drivers/mspi/mspi_dw.c +++ b/drivers/mspi/mspi_dw.c @@ -256,8 +256,7 @@ static void async_packet_work_handler(struct k_work *work) } #endif /* defined(CONFIG_MULTITHREADING) */ -static void tx_data(const struct device *dev, - const struct mspi_xfer_packet *packet) +static void tx_data(const struct device *dev) { struct mspi_dw_data *dev_data = dev->data; const struct mspi_dw_config *dev_config = dev->config; @@ -365,14 +364,13 @@ static bool tx_dummy_bytes(const struct device *dev, bool *repeat) return true; } -static bool read_rx_fifo(const struct device *dev, - const struct mspi_xfer_packet *packet) +static bool read_rx_fifo(const struct device *dev) { struct mspi_dw_data *dev_data = dev->data; const struct mspi_dw_config *dev_config = dev->config; uint8_t bytes_to_discard = dev_data->bytes_to_discard; uint8_t *buf_pos = dev_data->buf_pos; - const uint8_t *buf_end = &packet->data_buf[packet->num_bytes]; + const uint8_t *buf_end = dev_data->buf_end; uint8_t bytes_per_frame_exp = dev_data->bytes_per_frame_exp; uint32_t remaining_frames; uint32_t in_fifo = FIELD_GET(RXFLR_RXTFL_MASK, read_rxflr(dev)); @@ -456,7 +454,7 @@ static void handle_fifos(const struct device *dev) if (packet->dir == MSPI_TX) { if (dev_data->buf_pos < dev_data->buf_end) { - tx_data(dev, packet); + tx_data(dev); } else { /* It may happen that at this point the controller is * still shifting out the last frame (the last interrupt @@ -489,7 +487,7 @@ static void handle_fifos(const struct device *dev) * has no chance to get new entries, hence no further * interrupts are generated and the transfer gets stuck. */ - if (read_rx_fifo(dev, packet)) { + if (read_rx_fifo(dev)) { finished = true; break; } @@ -1366,7 +1364,7 @@ static int start_next_packet(const struct device *dev) if (dev_data->dummy_bytes && tx_dummy_bytes(dev, NULL)) { imr = IMR_RXFIM_BIT; } else if (packet->dir == MSPI_TX && packet->num_bytes) { - tx_data(dev, packet); + tx_data(dev); } /* Enable interrupts now and wait until the packet is done unless async. */ From 8a190d77fb4d4fc7cd5887908788fbaa05987a28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrzej=20G=C5=82=C4=85bek?= Date: Fri, 2 Jan 2026 12:03:49 +0100 Subject: [PATCH 1749/3659] drivers: mspi_dw: Add support for data only packets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The SSI core requires special handling of packets that are supposed to contain only data (no instruction and data phases): - for TX packets, the first data frame needs to be sent as the address (the instruction and address cannot be both set to zero length for TX, otherwise the transfer will not be performed correctly) - for RX packets, a dummy write to the data register (DR) is needed to start the transfer. Implement the above in the function that starts a packet transfer. Rename also the `packet_frames` variable there to `data_frames` to avoid confusion. Signed-off-by: Andrzej Głąbek --- drivers/mspi/mspi_dw.c | 59 ++++++++++++++++++++++++++++++------------ 1 file changed, 42 insertions(+), 17 deletions(-) diff --git a/drivers/mspi/mspi_dw.c b/drivers/mspi/mspi_dw.c index ca783114d627..d26a537e8af9 100644 --- a/drivers/mspi/mspi_dw.c +++ b/drivers/mspi/mspi_dw.c @@ -1086,17 +1086,18 @@ static int start_next_packet(const struct device *dev) struct mspi_dw_data *dev_data = dev->data; const struct mspi_xfer_packet *packet = &dev_data->xfer.packets[dev_data->packets_done]; + bool data_only_packet = dev_data->xfer.cmd_length == 0 && + dev_data->xfer.addr_length == 0; bool xip_enabled = COND_CODE_1(CONFIG_MSPI_XIP, (dev_data->xip_enabled != 0), (false)); unsigned int key; - uint32_t packet_frames; + uint32_t data_frames; uint32_t imr = 0; int rc = 0; - if (packet->num_bytes == 0 && - dev_data->xfer.cmd_length == 0 && - dev_data->xfer.addr_length == 0) { + + if (data_only_packet && packet->num_bytes == 0) { return 0; } @@ -1109,9 +1110,7 @@ static int start_next_packet(const struct device *dev) dev_data->spi_ctrlr0 &= ~SPI_CTRLR0_WAIT_CYCLES_MASK; - if (dev_data->standard_spi && - (dev_data->xfer.cmd_length != 0 || - dev_data->xfer.addr_length != 0)) { + if (dev_data->standard_spi && !data_only_packet) { dev_data->bytes_per_frame_exp = 0; dev_data->ctrlr0 |= FIELD_PREP(CTRLR0_DFS_MASK, 7); dev_data->ctrlr0 |= FIELD_PREP(CTRLR0_DFS32_MASK, 7); @@ -1131,9 +1130,28 @@ static int start_next_packet(const struct device *dev) } } - packet_frames = packet->num_bytes >> dev_data->bytes_per_frame_exp; + data_frames = packet->num_bytes >> dev_data->bytes_per_frame_exp; + + if (data_only_packet) { + uint32_t addr_length = dev_data->xfer.addr_length; + + /* For TX transfers, the command and address cannot be both + * empty, so treat the first data frame as the address. + */ + if (packet->dir == MSPI_TX) { + addr_length = 1UL << dev_data->bytes_per_frame_exp; + + --data_frames; + } + + dev_data->spi_ctrlr0 &= ~SPI_CTRLR0_ADDR_L_MASK; - if (packet_frames > UINT16_MAX + 1) { + if (!apply_addr_length(dev_data, addr_length)) { + return -EINVAL; + } + } + + if (data_frames > UINT16_MAX + 1) { LOG_ERR("Packet length (%u) exceeds supported maximum", packet->num_bytes); return -EINVAL; @@ -1177,9 +1195,7 @@ static int start_next_packet(const struct device *dev) * clock cycles for the RX part are provided (the controller * does not do it automatically in the TX/RX mode). */ - if (dev_data->standard_spi && - (dev_data->xfer.cmd_length != 0 || - dev_data->xfer.addr_length != 0)) { + if (dev_data->standard_spi && !data_only_packet) { uint32_t rx_total_bytes; uint32_t dummy_cycles = dev_data->xfer.rx_dummy; @@ -1200,7 +1216,7 @@ static int start_next_packet(const struct device *dev) } else { imr = IMR_RXFIM_BIT; tmod = CTRLR0_TMOD_RX; - rx_fifo_threshold = MIN(packet_frames - 1, + rx_fifo_threshold = MIN(data_frames - 1, dev_config->rx_fifo_threshold); dev_data->spi_ctrlr0 |= @@ -1232,8 +1248,8 @@ static int start_next_packet(const struct device *dev) * to prevent potential XIP transfers during that period. */ write_ctrlr0(dev, dev_data->ctrlr0); - write_ctrlr1(dev, packet_frames > 0 - ? FIELD_PREP(CTRLR1_NDF_MASK, packet_frames - 1) + write_ctrlr1(dev, data_frames > 0 + ? FIELD_PREP(CTRLR1_NDF_MASK, data_frames - 1) : 0); write_spi_ctrlr0(dev, dev_data->spi_ctrlr0); write_baudr(dev, dev_data->baudr); @@ -1363,8 +1379,17 @@ static int start_next_packet(const struct device *dev) /* Prefill TX FIFO with any data we can */ if (dev_data->dummy_bytes && tx_dummy_bytes(dev, NULL)) { imr = IMR_RXFIM_BIT; - } else if (packet->dir == MSPI_TX && packet->num_bytes) { - tx_data(dev); + } else if (packet->dir == MSPI_TX) { + if (data_frames) { + tx_data(dev); + } + } else { /* packet->dir == MSPI_RX */ + if (data_only_packet) { + /* For an RX data-only packet, a dummy DR write + * is needed to start the transfer. + */ + write_dr(dev, 0); + } } /* Enable interrupts now and wait until the packet is done unless async. */ From d3868911f81c065d235cd0bd70b45f82303eb68c Mon Sep 17 00:00:00 2001 From: Gaetan Perrot Date: Sat, 3 Jan 2026 03:46:05 +0900 Subject: [PATCH 1750/3659] drivers: flash: spi_nor: fix typo in an error log message Fix a typo in an error log message in mxicy_configure. No functional change. Signed-off-by: Gaetan Perrot --- drivers/flash/spi_nor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/flash/spi_nor.c b/drivers/flash/spi_nor.c index c5ade5e07dd3..91ece3e10cdf 100644 --- a/drivers/flash/spi_nor.c +++ b/drivers/flash/spi_nor.c @@ -848,7 +848,7 @@ static int mxicy_configure(const struct device *dev, const uint8_t *jedec_id) } if (ret < 0) { - LOG_ERR("Enable high performace mode failed: %d", ret); + LOG_ERR("Enable high performance mode failed: %d", ret); } release_device(dev); From 0fbbba2dc0126f1a8df7e510e9a3d03e4d88ba01 Mon Sep 17 00:00:00 2001 From: Samuel Kleiser Date: Tue, 6 Jan 2026 19:24:47 +0100 Subject: [PATCH 1751/3659] mcumgr: fs_mgmt: forward return values from fs_close A new error code FS_MGMT_ERR_FILE_CLOSE_FAILED is returned when closing a file fails. This is done on write or close operations - read operations remain unchecked. Signed-off-by: Samuel Kleiser --- .../zephyr/mgmt/mcumgr/grp/fs_mgmt/fs_mgmt.h | 3 + subsys/mgmt/mcumgr/grp/fs_mgmt/src/fs_mgmt.c | 72 +++++++++++++------ 2 files changed, 53 insertions(+), 22 deletions(-) diff --git a/include/zephyr/mgmt/mcumgr/grp/fs_mgmt/fs_mgmt.h b/include/zephyr/mgmt/mcumgr/grp/fs_mgmt/fs_mgmt.h index 911e938af24b..f98e98ff838e 100644 --- a/include/zephyr/mgmt/mcumgr/grp/fs_mgmt/fs_mgmt.h +++ b/include/zephyr/mgmt/mcumgr/grp/fs_mgmt/fs_mgmt.h @@ -93,6 +93,9 @@ enum fs_mgmt_err_code_t { /** The operation cannot be performed because the file is empty with no contents. */ FS_MGMT_ERR_FILE_EMPTY, + + /** Error occurred whilst attempting to close a file. */ + FS_MGMT_ERR_FILE_CLOSE_FAILED, }; #ifdef __cplusplus diff --git a/subsys/mgmt/mcumgr/grp/fs_mgmt/src/fs_mgmt.c b/subsys/mgmt/mcumgr/grp/fs_mgmt/src/fs_mgmt.c index 7d491e93e6e8..44926c7eff0e 100644 --- a/subsys/mgmt/mcumgr/grp/fs_mgmt/src/fs_mgmt.c +++ b/subsys/mgmt/mcumgr/grp/fs_mgmt/src/fs_mgmt.c @@ -119,16 +119,20 @@ struct fs_mgmt_hash_checksum_iterator_info { #endif /* Clean up open file state */ -static void fs_mgmt_cleanup(void) +static int fs_mgmt_cleanup(void) { + int rc = 0; + if (fs_mgmt_ctxt.state != STATE_NO_UPLOAD_OR_DOWNLOAD) { fs_mgmt_ctxt.state = STATE_NO_UPLOAD_OR_DOWNLOAD; fs_mgmt_ctxt.off = 0; fs_mgmt_ctxt.len = 0; memset(fs_mgmt_ctxt.path, 0, sizeof(fs_mgmt_ctxt.path)); - fs_close(&fs_mgmt_ctxt.file); + rc = fs_close(&fs_mgmt_ctxt.file); fs_mgmt_ctxt.transport = NULL; } + + return rc < 0 ? FS_MGMT_ERR_FILE_CLOSE_FAILED : FS_MGMT_ERR_OK; } static void file_close_work_handler(struct k_work *work) @@ -139,7 +143,7 @@ static void file_close_work_handler(struct k_work *work) return; } - fs_mgmt_cleanup(); + (void)fs_mgmt_cleanup(); k_sem_give(&fs_mgmt_ctxt.lock_sem); } @@ -186,9 +190,12 @@ static bool fs_mgmt_file_rsp(zcbor_state_t *zse, int rc, uint64_t off) /** * Cleans up open file handle and state when upload is finished. + * Returns FS_MGMT_ERR_FILE_CLOSE_FAILED if file close fails, FS_MGMT_ERR_OK otherwise. */ -static void fs_mgmt_upload_download_finish_check(void) +static int fs_mgmt_upload_download_finish_check(void) { + int rc = FS_MGMT_ERR_OK; + if (fs_mgmt_ctxt.len > 0 && fs_mgmt_ctxt.off >= fs_mgmt_ctxt.len) { #if defined(CONFIG_MCUMGR_GRP_FS_FILE_ACCESS_HOOK) char path[CONFIG_MCUMGR_GRP_FS_PATH_LEN + 1]; @@ -216,7 +223,7 @@ static void fs_mgmt_upload_download_finish_check(void) /* File upload/download has finished, clean up */ k_work_cancel_delayable(&fs_mgmt_ctxt.file_close_work); - fs_mgmt_cleanup(); + rc = fs_mgmt_cleanup(); #if defined(CONFIG_MCUMGR_GRP_FS_FILE_ACCESS_HOOK) /* Warn application that file download/upload is done. */ @@ -226,6 +233,8 @@ static void fs_mgmt_upload_download_finish_check(void) } else { k_work_reschedule(&fs_mgmt_ctxt.file_close_work, FILE_CLOSE_IDLE_TIME); } + + return rc; } /** @@ -294,7 +303,7 @@ static int fs_mgmt_file_download(struct smp_streamer *ctxt) } #endif - fs_mgmt_cleanup(); + (void)fs_mgmt_cleanup(); } /* Open new file */ @@ -335,7 +344,7 @@ static int fs_mgmt_file_download(struct smp_streamer *ctxt) if (rc != 0) { ok = smp_add_cmd_err(zse, MGMT_GROUP_ID_FS, FS_MGMT_ERR_FILE_SEEK_FAILED); - fs_mgmt_cleanup(); + (void)fs_mgmt_cleanup(); goto end; } @@ -351,7 +360,7 @@ static int fs_mgmt_file_download(struct smp_streamer *ctxt) if (bytes_read < 0) { ok = smp_add_cmd_err(zse, MGMT_GROUP_ID_FS, FS_MGMT_ERR_FILE_READ_FAILED); - fs_mgmt_cleanup(); + (void)fs_mgmt_cleanup(); goto end; } @@ -365,7 +374,8 @@ static int fs_mgmt_file_download(struct smp_streamer *ctxt) ((off != 0) || (zcbor_tstr_put_lit(zse, "len") && zcbor_uint64_put(zse, fs_mgmt_ctxt.len))); - fs_mgmt_upload_download_finish_check(); + /* Closing errors can be ignored on downloads */ + (void)fs_mgmt_upload_download_finish_check(); end: rc = (ok ? MGMT_ERR_EOK : MGMT_ERR_EMSGSIZE); @@ -390,6 +400,7 @@ static int fs_mgmt_file_upload(struct smp_streamer *ctxt) struct zcbor_string file_data = { 0 }; size_t decoded = 0; ssize_t existing_file_size = 0; + size_t ctxt_off; struct zcbor_map_decode_key_val fs_upload_decode[] = { ZCBOR_MAP_DECODE_KEY_DECODER("off", zcbor_uint64_decode, &off), @@ -444,7 +455,7 @@ static int fs_mgmt_file_upload(struct smp_streamer *ctxt) } #endif - fs_mgmt_cleanup(); + (void)fs_mgmt_cleanup(); } /* Open new file */ @@ -484,7 +495,7 @@ static int fs_mgmt_file_upload(struct smp_streamer *ctxt) if (rc != 0) { ok = smp_add_cmd_err(zse, MGMT_GROUP_ID_FS, rc); - fs_mgmt_cleanup(); + (void)fs_mgmt_cleanup(); goto end; } } else if (fs_mgmt_ctxt.off == 0) { @@ -492,7 +503,7 @@ static int fs_mgmt_file_upload(struct smp_streamer *ctxt) if (rc != 0) { ok = smp_add_cmd_err(zse, MGMT_GROUP_ID_FS, rc); - fs_mgmt_cleanup(); + (void)fs_mgmt_cleanup(); goto end; } } @@ -508,7 +519,7 @@ static int fs_mgmt_file_upload(struct smp_streamer *ctxt) * again, clean everything up and release the file handle so it can be used * elsewhere (if needed). */ - fs_mgmt_cleanup(); + (void)fs_mgmt_cleanup(); goto end; } @@ -523,7 +534,7 @@ static int fs_mgmt_file_upload(struct smp_streamer *ctxt) if (rc != 0) { ok = smp_add_cmd_err(zse, MGMT_GROUP_ID_FS, FS_MGMT_ERR_FILE_SEEK_FAILED); - fs_mgmt_cleanup(); + (void)fs_mgmt_cleanup(); goto end; } @@ -539,7 +550,7 @@ static int fs_mgmt_file_upload(struct smp_streamer *ctxt) if (rc < 0 && rc != -ENOENT) { ok = smp_add_cmd_err(zse, MGMT_GROUP_ID_FS, FS_MGMT_ERR_FILE_DELETE_FAILED); - fs_mgmt_cleanup(); + (void)fs_mgmt_cleanup(); goto end; } @@ -551,7 +562,7 @@ static int fs_mgmt_file_upload(struct smp_streamer *ctxt) /* Failed to truncate file */ ok = smp_add_cmd_err(zse, MGMT_GROUP_ID_FS, FS_MGMT_ERR_FILE_TRUNCATE_FAILED); - fs_mgmt_cleanup(); + (void)fs_mgmt_cleanup(); goto end; } } else if (fs_tell(&fs_mgmt_ctxt.file) != off) { @@ -564,7 +575,7 @@ static int fs_mgmt_file_upload(struct smp_streamer *ctxt) /* Failed to seek in file */ ok = smp_add_cmd_err(zse, MGMT_GROUP_ID_FS, FS_MGMT_ERR_FILE_SEEK_FAILED); - fs_mgmt_cleanup(); + (void)fs_mgmt_cleanup(); goto end; } } @@ -574,16 +585,25 @@ static int fs_mgmt_file_upload(struct smp_streamer *ctxt) if (rc < 0) { ok = smp_add_cmd_err(zse, MGMT_GROUP_ID_FS, FS_MGMT_ERR_FILE_WRITE_FAILED); - fs_mgmt_cleanup(); + (void)fs_mgmt_cleanup(); goto end; } fs_mgmt_ctxt.off += file_data.len; } + /* Store offset since fs_mgmt_upload_download_finish_check invalidates it */ + ctxt_off = fs_mgmt_ctxt.off; + + /* Check for file close errors after upload completion */ + rc = fs_mgmt_upload_download_finish_check(); + if (rc != FS_MGMT_ERR_OK) { + ok = smp_add_cmd_err(zse, MGMT_GROUP_ID_FS, rc); + goto end; + } + /* Send the response. */ - ok = fs_mgmt_file_rsp(zse, MGMT_ERR_EOK, fs_mgmt_ctxt.off); - fs_mgmt_upload_download_finish_check(); + ok = fs_mgmt_file_rsp(zse, MGMT_ERR_EOK, ctxt_off); end: rc = (ok ? MGMT_ERR_EOK : MGMT_ERR_EMSGSIZE); @@ -922,15 +942,22 @@ fs_mgmt_supported_hash_checksum(struct smp_streamer *ctxt) */ static int fs_mgmt_close_opened_file(struct smp_streamer *ctxt) { + zcbor_state_t *zse = ctxt->writer->zs; + bool ok = true; + int rc; + if (k_sem_take(&fs_mgmt_ctxt.lock_sem, FILE_SEMAPHORE_MAX_TAKE_TIME)) { return MGMT_ERR_EBUSY; } - fs_mgmt_cleanup(); + rc = fs_mgmt_cleanup(); + if (rc != FS_MGMT_ERR_OK) { + ok = smp_add_cmd_err(zse, MGMT_GROUP_ID_FS, rc); + } k_sem_give(&fs_mgmt_ctxt.lock_sem); - return MGMT_ERR_EOK; + return rc == FS_MGMT_ERR_OK ? MGMT_ERR_EOK : MGMT_ERR_EMSGSIZE; } #ifdef CONFIG_MCUMGR_SMP_SUPPORT_ORIGINAL_PROTOCOL @@ -953,6 +980,7 @@ static int fs_mgmt_translate_error_code(uint16_t err) case FS_MGMT_ERR_FILE_NOT_FOUND: case FS_MGMT_ERR_MOUNT_POINT_NOT_FOUND: + case FS_MGMT_ERR_FILE_CLOSE_FAILED: rc = MGMT_ERR_ENOENT; break; From 471060a354b4b25de6fc4f130ec5725b67ac1af4 Mon Sep 17 00:00:00 2001 From: Tim Knodel Date: Tue, 6 Jan 2026 11:30:31 -0800 Subject: [PATCH 1752/3659] logging: formatting: Add support for domain names The domain name was always set to NULL. This adds a Kconfig that will enable setting the domain name and sets the domain name if the config is enabled. Signed-off-by: Tim Knodel --- subsys/logging/Kconfig.formatting | 5 +++++ subsys/logging/log_output.c | 4 +++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/subsys/logging/Kconfig.formatting b/subsys/logging/Kconfig.formatting index 58c3423e7e47..d52b07679766 100644 --- a/subsys/logging/Kconfig.formatting +++ b/subsys/logging/Kconfig.formatting @@ -109,6 +109,11 @@ config LOG_DICTIONARY_SUPPORT This should be selected by the backend automatically. +config LOG_DOMAIN_NAME_PREFIX + bool "Domain name prefix" + help + Enable support for prefixing the log source with the domain name. + config LOG_THREAD_ID_PREFIX bool "Thread ID prefix" help diff --git a/subsys/logging/log_output.c b/subsys/logging/log_output.c index a775d9726788..34e029f24bae 100644 --- a/subsys/logging/log_output.c +++ b/subsys/logging/log_output.c @@ -698,12 +698,14 @@ void log_output_msg_process(const struct log_output *output, uint8_t domain_id = log_msg_get_domain(msg); int16_t source_id = log_msg_get_source_id(msg); + const char *dname = IS_ENABLED(CONFIG_LOG_DOMAIN_NAME_PREFIX) ? + log_domain_name_get(domain_id) : NULL; const char *sname = source_id >= 0 ? log_source_name_get(domain_id, source_id) : NULL; size_t plen, dlen; uint8_t *package = log_msg_get_package(msg, &plen); uint8_t *data = log_msg_get_data(msg, &dlen); - log_output_process(output, timestamp, NULL, sname, (k_tid_t)log_msg_get_tid(msg), level, + log_output_process(output, timestamp, dname, sname, (k_tid_t)log_msg_get_tid(msg), level, plen > 0 ? package : NULL, data, dlen, flags); } From 05dde46c4d4607a8ffbe128574991609249fbdfa Mon Sep 17 00:00:00 2001 From: Wilfried Chauveau Date: Fri, 12 Dec 2025 00:13:06 +0000 Subject: [PATCH 1753/3659] build: cmake: print the board's qualifiers in the elf postbuild phase When building for several cores of the same system it can be hard to identify which build is currently running. This addition helps disambiguate the logs. Signed-off-by: Wilfried Chauveau --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f3def10be37a..7d7f1a7bca78 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2286,7 +2286,7 @@ endif() add_custom_command( TARGET ${logical_target_for_zephyr_elf} POST_BUILD - COMMAND ${CMAKE_COMMAND} -E echo "Generating files from ${PROJECT_BINARY_DIR}/${KERNEL_ELF_NAME} for board: ${BOARD}" + COMMAND ${CMAKE_COMMAND} -E echo "Generating files from ${PROJECT_BINARY_DIR}/${KERNEL_ELF_NAME} for board: ${BOARD}${BOARD_QUALIFIERS}" ${post_build_commands} BYPRODUCTS ${post_build_byproducts} From d9b7fe379a9b7697a58256d4d58bca7dbe145b2d Mon Sep 17 00:00:00 2001 From: Tomi Fontanilles Date: Mon, 12 Jan 2026 13:46:30 +0200 Subject: [PATCH 1754/3659] modules: mbedtls: PKCS5: depend on, do not select MD To avoid dependency loops. Signed-off-by: Tomi Fontanilles --- drivers/wifi/esp32/Kconfig.esp32 | 1 + modules/hostap/Kconfig | 1 + modules/mbedtls/Kconfig.mbedtls | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/wifi/esp32/Kconfig.esp32 b/drivers/wifi/esp32/Kconfig.esp32 index a32b3b347f9e..029b69ced5ac 100644 --- a/drivers/wifi/esp32/Kconfig.esp32 +++ b/drivers/wifi/esp32/Kconfig.esp32 @@ -371,6 +371,7 @@ config ESP32_WIFI_MBEDTLS_CRYPTO select MBEDTLS_ECDH_C select MBEDTLS_ECDSA_C select MBEDTLS_PKCS5_C + select MBEDTLS_MD_C select MBEDTLS_PK_WRITE_C select MBEDTLS_CIPHER_MODE_CTR_ENABLED select MBEDTLS_CMAC diff --git a/modules/hostap/Kconfig b/modules/hostap/Kconfig index fa47d6c1da9a..101c344804f3 100644 --- a/modules/hostap/Kconfig +++ b/modules/hostap/Kconfig @@ -186,6 +186,7 @@ config WIFI_NM_WPA_SUPPLICANT_CRYPTO_ALT select MBEDTLS_ECP_ALL_ENABLED select MBEDTLS_CMAC select MBEDTLS_PKCS5_C + select MBEDTLS_MD_C select MBEDTLS_PK_WRITE_C select MBEDTLS_ECDH_C select MBEDTLS_ECDSA_C diff --git a/modules/mbedtls/Kconfig.mbedtls b/modules/mbedtls/Kconfig.mbedtls index 3d1c1dad14a7..7c66b58f768f 100644 --- a/modules/mbedtls/Kconfig.mbedtls +++ b/modules/mbedtls/Kconfig.mbedtls @@ -496,7 +496,7 @@ config MBEDTLS_HAVE_TIME_DATE config MBEDTLS_PKCS5_C bool "Password-based encryption functions" - select MBEDTLS_MD_C + depends on MBEDTLS_MD_C help Enable PKCS5 functions From 74931644b5d4d239d7db6e0f730fe19cf4d0d639 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Mon, 12 Jan 2026 15:40:39 +0200 Subject: [PATCH 1755/3659] net: tcp: Add NULL check when receiving SYN Make sure that if the connection is closed but we still received a SYN packet, we do not try to access already closed connection. Signed-off-by: Jukka Rissanen --- subsys/net/ip/tcp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/net/ip/tcp.c b/subsys/net/ip/tcp.c index 668181760fd3..d67a13e33e44 100644 --- a/subsys/net/ip/tcp.c +++ b/subsys/net/ip/tcp.c @@ -2315,7 +2315,7 @@ static enum net_verdict tcp_recv(struct net_conn *net_conn, if (th_flags(th) & SYN && !(th_flags(th) & ACK)) { struct tcp *conn_old = ((struct net_context *)user_data)->tcp; - if (tcp_backlog_is_full(conn_old)) { + if (conn_old == NULL || tcp_backlog_is_full(conn_old)) { /* If the connection backlog is full, ignore the SYN * packet (same behavior as on Linux). Retransmitted SYN * attempts may be successful later. From 23efdfe30996a01134c8e9a15b49d543bd97455c Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Mon, 12 Jan 2026 19:52:27 +0530 Subject: [PATCH 1756/3659] drivers: nrf_wifi: Implement key installation for nRF71 For nRF71 series keys should be installed via PSA-APIs (KMU). Signed-off-by: Chaitanya Tata --- drivers/wifi/nrf_wifi/src/wpa_supp_if.c | 131 +++++++++++++++++++++++- 1 file changed, 130 insertions(+), 1 deletion(-) diff --git a/drivers/wifi/nrf_wifi/src/wpa_supp_if.c b/drivers/wifi/nrf_wifi/src/wpa_supp_if.c index d11d46c79e3a..25b69b94801c 100644 --- a/drivers/wifi/nrf_wifi/src/wpa_supp_if.c +++ b/drivers/wifi/nrf_wifi/src/wpa_supp_if.c @@ -19,6 +19,11 @@ #include "wpa_supp_if.h" #include +#ifdef CONFIG_NRF71_ON_IPC +#include +#include "wifi_keys.h" +#endif + LOG_MODULE_DECLARE(wifi_nrf, CONFIG_WIFI_NRF70_LOG_LEVEL); K_SEM_DEFINE(wait_for_event_sem, 0, 1); @@ -974,6 +979,113 @@ int nrf_wifi_wpa_supp_associate(void *if_priv, struct wpa_driver_associate_param return ret; } +#ifdef CONFIG_NRF71_ON_IPC +static bool is_mic_cipher_suite(unsigned int suite) +{ + return (suite == RSN_CIPHER_SUITE_AES_128_CMAC || + suite == RSN_CIPHER_SUITE_BIP_GMAC_128 || + suite == RSN_CIPHER_SUITE_BIP_GMAC_256 || + suite == RSN_CIPHER_SUITE_BIP_CMAC_256); +} + +/* Maximum number of keys we can track (unicast + group keys) */ +#define WIFI_CRYPTO_MAX_KEYS 8 + +/* Track installed keys: key_idx -> key_type mapping */ +static struct { + bool valid; + wifi_keys_key_type_t type; + uint32_t db_id; +} installed_keys[WIFI_CRYPTO_MAX_KEYS]; + +static int wifi_import_key_to_crypto(unsigned int suite, const unsigned char *key, size_t key_len, + const unsigned char *addr, int key_idx, uint32_t db_id) +{ + wifi_keys_key_type_t type; + psa_key_attributes_t attr; + psa_key_id_t key_id; + psa_status_t status; + uint32_t key_index; + bool is_broadcast = false; + + /* Determine if this is a broadcast/group key or unicast/pairwise key */ + if (addr && is_broadcast_ether_addr(addr)) { + is_broadcast = true; + } + + /* Determine key type based on cipher suite and address */ + if (is_mic_cipher_suite(suite)) { + type = is_broadcast ? PEER_BCST_MIC : PEER_UCST_MIC; + } else { + type = is_broadcast ? PEER_BCST_ENC : PEER_UCST_ENC; + } + + /* Convert key_idx to uint32_t, ensure it's within valid range */ + key_index = (key_idx < 0) ? 0 : (uint32_t)key_idx; + + /* Initialize PSA key attributes */ + attr = wifi_keys_key_attributes_init(type, db_id, key_index); + + LOG_DBG("%s: Importing key to PSA (suite: 0x%08x, type: %d, idx: %u, len: %zu)", + __func__, suite, type, key_index, key_len); + + /* Import key to PSA */ + status = psa_import_key(&attr, key, key_len, &key_id); + if (status != PSA_SUCCESS) { + LOG_ERR("%s: Failed to import key to PSA: %d", __func__, status); + return -EIO; + } + + /* Track installed key for later destruction */ + if (key_index < WIFI_CRYPTO_MAX_KEYS) { + installed_keys[key_index].valid = true; + installed_keys[key_index].type = type; + installed_keys[key_index].db_id = db_id; + } + + LOG_DBG("%s: Key imported successfully (type: %d, idx: %u)", __func__, type, key_index); + + return 0; +} + +static int wifi_destroy_key_from_crypto(int key_idx, uint32_t db_id) +{ + psa_key_attributes_t attr; + psa_key_id_t key_id; + psa_status_t status; + uint32_t key_index; + + /* Convert key_idx to uint32_t */ + key_index = (key_idx < 0) ? 0 : (uint32_t)key_idx; + + if (key_index >= WIFI_CRYPTO_MAX_KEYS || !installed_keys[key_index].valid) { + LOG_WRN("%s: No tracked key at index %u", __func__, key_index); + /* During init supplicant deletes all keys, so, suppress error */ + return 0; + } + + /* Get the key type that was used during import */ + attr = wifi_keys_key_attributes_init(installed_keys[key_index].type, + installed_keys[key_index].db_id, key_index); + key_id = psa_get_key_id(&attr); + + LOG_DBG("%s: Destroying key (type: %d, idx: %u, key_id: 0x%08x)", + __func__, installed_keys[key_index].type, key_index, key_id); + + status = psa_destroy_key(key_id); + if (status != PSA_SUCCESS) { + LOG_ERR("%s: Failed to destroy key: %d", __func__, status); + return -EIO; + } + + /* Clear tracking entry */ + installed_keys[key_index].valid = false; + + LOG_DBG("%s: Key destroyed successfully", __func__); + return 0; +} +#endif + int nrf_wifi_wpa_supp_set_key(void *if_priv, const unsigned char *ifname, enum wpa_alg alg, const unsigned char *addr, int key_idx, int set_tx, const unsigned char *seq, size_t seq_len, const unsigned char *key, @@ -982,7 +1094,7 @@ int nrf_wifi_wpa_supp_set_key(void *if_priv, const unsigned char *ifname, enum w enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL; struct nrf_wifi_ctx_zep *rpu_ctx_zep = NULL; - struct nrf_wifi_umac_key_info key_info; + struct nrf_wifi_umac_key_info key_info = {0}; const unsigned char *mac_addr = NULL; unsigned int suite; int ret = -1; @@ -1022,7 +1134,15 @@ int nrf_wifi_wpa_supp_set_key(void *if_priv, const unsigned char *ifname, enum w goto out; } +#ifdef CONFIG_NRF71_ON_IPC + ret = wifi_import_key_to_crypto(suite, key, key_len, addr, key_idx, 0); + if (ret) { + LOG_ERR("%s: Failed to import key to crypto: %d", __func__, ret); + goto out; + } +#else memcpy(key_info.key.nrf_wifi_key, key, key_len); +#endif key_info.key.nrf_wifi_key_len = key_len; key_info.cipher_suite = suite; @@ -1060,7 +1180,16 @@ int nrf_wifi_wpa_supp_set_key(void *if_priv, const unsigned char *ifname, enum w if (status != NRF_WIFI_STATUS_SUCCESS) { LOG_ERR("%s: nrf_wifi_sys_fmac_del_key failed", __func__); } else { +#ifdef CONFIG_NRF71_ON_IPC + /* Destroy PSA key after successful del_key */ + ret = wifi_destroy_key_from_crypto(key_idx, 0); + if (ret) { + LOG_ERR("%s: Failed to destroy key from crypto: %d", + __func__, ret); + } +#else ret = 0; +#endif } } else { status = nrf_wifi_sys_fmac_add_key(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx, From c611a16ecd7ff48e2d3ac2bbfe28ff613ad9fce8 Mon Sep 17 00:00:00 2001 From: Andreas Huber Date: Mon, 12 Jan 2026 15:37:33 +0100 Subject: [PATCH 1757/3659] net: ipv4: Add missing broadcast check in address conflict detection As described in RFC5227 ch. 2.1.1 ARP Probes are broadcasted. ARP requests not being broadcasted should not be detected as ARP Probes. Signed-off-by: Andreas Huber --- subsys/net/ip/ipv4_acd.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/subsys/net/ip/ipv4_acd.c b/subsys/net/ip/ipv4_acd.c index 8d094671355b..f121f2c0ad98 100644 --- a/subsys/net/ip/ipv4_acd.c +++ b/subsys/net/ip/ipv4_acd.c @@ -267,6 +267,7 @@ enum net_verdict net_ipv4_acd_input(struct net_if *iface, struct net_pkt *pkt) sys_snode_t *current, *next; struct net_arp_hdr *arp_hdr; struct net_if_ipv4 *ipv4; + struct net_linkaddr *dst_lladdr; if (net_pkt_get_len(pkt) < sizeof(struct net_arp_hdr)) { NET_DBG("Invalid ARP header (len %zu, min %zu bytes)", @@ -274,6 +275,13 @@ enum net_verdict net_ipv4_acd_input(struct net_if *iface, struct net_pkt *pkt) return NET_DROP; } + dst_lladdr = net_pkt_lladdr_dst(pkt); + if ((dst_lladdr->type != NET_LINK_ETHERNET) || + (dst_lladdr->len != sizeof(struct net_eth_addr))) { + NET_ERR("Invalid LinkLayer in ARP"); + return NET_DROP; + } + arp_hdr = NET_ARP_HDR(pkt); k_mutex_lock(&lock, K_FOREVER); @@ -298,15 +306,16 @@ enum net_verdict net_ipv4_acd_input(struct net_if *iface, struct net_pkt *pkt) * - ARP Request/Reply with Sender IP address match OR, * - ARP Probe where Target IP address match with different sender HW address, * indicate a conflict. - * ARP Probe has an all-zero sender IP address + * ARP Probe has an all-zero sender IP address and is broadcasted */ if (net_ipv4_addr_cmp_raw(arp_hdr->src_ipaddr, (uint8_t *)&ifaddr->address.in_addr) || (net_ipv4_addr_cmp_raw(arp_hdr->dst_ipaddr, - (uint8_t *)&ifaddr->address.in_addr) && - (memcmp(&arp_hdr->src_hwaddr, ll_addr->addr, ll_addr->len) != 0) && - (net_ipv4_addr_cmp_raw(arp_hdr->src_ipaddr, - (uint8_t *)&(struct net_in_addr)NET_INADDR_ANY_INIT)))) { + (uint8_t *)&ifaddr->address.in_addr) && + (memcmp(&arp_hdr->src_hwaddr, ll_addr->addr, ll_addr->len) != 0) && + (net_ipv4_addr_cmp_raw(arp_hdr->src_ipaddr, + (uint8_t *)&(struct net_in_addr)NET_INADDR_ANY_INIT)) && + net_eth_is_addr_broadcast((struct net_eth_addr *)dst_lladdr->addr))) { NET_DBG("Conflict detected from %s for %s", net_sprint_ll_addr((uint8_t *)&arp_hdr->src_hwaddr, arp_hdr->hwlen), From c75ee62562f54905a9beb7b58d4b41d7442edf75 Mon Sep 17 00:00:00 2001 From: Mohamed Moawad Date: Thu, 13 Nov 2025 15:31:22 +0200 Subject: [PATCH 1758/3659] soc: arc_iot: add configurable custom CPU idle for UART retention The ARC IoT SoC (used on iotdk board) has a hardware limitation where entering CPU sleep mode causes some peripherals (e.g., UART) to lose power, preventing the board from waking up via peripheral interrupts. Add a configurable custom CPU idle option (CONFIG_ARC_IOT_CUSTOM_CPU_IDLE) that enables interrupts without executing the sleep instruction. This allows the system to remain responsive while keeping peripherals powered. The option defaults to disabled (n) to preserve normal CPU sleep behavior for most use cases. Tests that require continuous UART operation during idle (pytest/shell harnesses) can enable it via platform-specific extra_configs. This approach allows timer-based idle to work correctly by default while providing a workaround for tests that need UART retention. Signed-off-by: Mohamed Moawad --- samples/sensor/sensor_shell/sample.yaml | 1 + samples/subsys/shell/shell_module/sample.yaml | 1 + samples/subsys/smf/hsm_psicc2/sample.yaml | 2 ++ .../testsuite/pytest/shell/testcase.yaml | 1 + soc/snps/arc_iot/CMakeLists.txt | 2 ++ soc/snps/arc_iot/Kconfig | 13 ++++++++ soc/snps/arc_iot/soc_idle.c | 30 +++++++++++++++++++ 7 files changed, 50 insertions(+) create mode 100644 soc/snps/arc_iot/soc_idle.c diff --git a/samples/sensor/sensor_shell/sample.yaml b/samples/sensor/sensor_shell/sample.yaml index 1a0a681307f7..5e4b5216e6d2 100644 --- a/samples/sensor/sensor_shell/sample.yaml +++ b/samples/sensor/sensor_shell/sample.yaml @@ -23,6 +23,7 @@ tests: timeout: 180 extra_configs: - arch:posix:CONFIG_UART_NATIVE_PTY_0_ON_STDINOUT=y + - platform:iotdk/arc_iot:CONFIG_ARC_IOT_CUSTOM_CPU_IDLE=y extra_args: DTC_OVERLAY_FILE=fake_sensor.overlay integration_platforms: - native_sim diff --git a/samples/subsys/shell/shell_module/sample.yaml b/samples/subsys/shell/shell_module/sample.yaml index ca5e9c1fd065..389689ab5846 100644 --- a/samples/subsys/shell/shell_module/sample.yaml +++ b/samples/subsys/shell/shell_module/sample.yaml @@ -13,6 +13,7 @@ tests: - native_sim extra_configs: - arch:posix:CONFIG_UART_NATIVE_PTY_0_ON_STDINOUT=y + - platform:iotdk/arc_iot:CONFIG_ARC_IOT_CUSTOM_CPU_IDLE=y sample.shell.shell_module.usb: depends_on: usbd tags: diff --git a/samples/subsys/smf/hsm_psicc2/sample.yaml b/samples/subsys/smf/hsm_psicc2/sample.yaml index ae32b7594af9..f9a0bf05e88a 100644 --- a/samples/subsys/smf/hsm_psicc2/sample.yaml +++ b/samples/subsys/smf/hsm_psicc2/sample.yaml @@ -15,5 +15,7 @@ common: - ".* hsm_psicc2_thread: s2_entry.*" - ".* hsm_psicc2_thread: s21_entry.*" - ".* hsm_psicc2_thread: s211_entry.*" + extra_configs: + - platform:iotdk/arc_iot:CONFIG_ARC_IOT_CUSTOM_CPU_IDLE=y tests: sample.smf.hsm_psicc2: {} diff --git a/samples/subsys/testsuite/pytest/shell/testcase.yaml b/samples/subsys/testsuite/pytest/shell/testcase.yaml index 60b80817620d..89f43b5ab5ce 100644 --- a/samples/subsys/testsuite/pytest/shell/testcase.yaml +++ b/samples/subsys/testsuite/pytest/shell/testcase.yaml @@ -7,6 +7,7 @@ common: filter: CONFIG_SERIAL and not CONFIG_SMP and dt_chosen_enabled("zephyr,shell-uart") extra_configs: - arch:posix:CONFIG_UART_NATIVE_PTY_0_ON_STDINOUT=y + - platform:iotdk/arc_iot:CONFIG_ARC_IOT_CUSTOM_CPU_IDLE=y min_ram: 40 integration_platforms: - native_sim diff --git a/soc/snps/arc_iot/CMakeLists.txt b/soc/snps/arc_iot/CMakeLists.txt index 5a28fe228d88..b383ca4cf9d2 100644 --- a/soc/snps/arc_iot/CMakeLists.txt +++ b/soc/snps/arc_iot/CMakeLists.txt @@ -7,4 +7,6 @@ zephyr_sources( sysconf.c ) +zephyr_sources_ifdef(CONFIG_ARC_IOT_CUSTOM_CPU_IDLE soc_idle.c) + set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld CACHE INTERNAL "") diff --git a/soc/snps/arc_iot/Kconfig b/soc/snps/arc_iot/Kconfig index 0ea361d2325a..d7ad5f588fb9 100644 --- a/soc/snps/arc_iot/Kconfig +++ b/soc/snps/arc_iot/Kconfig @@ -7,3 +7,16 @@ config SOC_ARC_IOT select CPU_HAS_MPU select CPU_HAS_FPU select SOC_EARLY_INIT_HOOK + +config ARC_IOT_CUSTOM_CPU_IDLE + bool "Use custom CPU idle that skips sleep" + default n + depends on SOC_ARC_IOT + select ARCH_HAS_CUSTOM_CPU_IDLE + select ARCH_HAS_CUSTOM_CPU_ATOMIC_IDLE + help + The ARC IoT SoC has a hardware limitation where entering sleep mode + causes peripherals (e.g., UART) to lose power, preventing wake-up + from peripheral interrupts. Enable this option to use a custom idle + implementation that skips sleep, keeping peripherals powered. + Enable for tests that require continuous UART operation during idle. diff --git a/soc/snps/arc_iot/soc_idle.c b/soc/snps/arc_iot/soc_idle.c new file mode 100644 index 000000000000..84e192090a4e --- /dev/null +++ b/soc/snps/arc_iot/soc_idle.c @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2026 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Custom CPU idle implementation for ARC IoT SoC + * + * The ARC IoT SoC has a hardware limitation where entering sleep mode + * causes peripherals (e.g., UART) to lose power. This prevents wake-up + * from peripheral interrupts. These custom implementations skip the sleep + * instruction and only enable interrupts. + */ + +#include +#include + +void arch_cpu_idle(void) +{ + sys_trace_idle(); + irq_unlock(0); +} + +void arch_cpu_atomic_idle(unsigned int key) +{ + sys_trace_idle(); + irq_unlock(key); +} From 7fb39e806cfb95b6ff395c9fe5fcf928860aeab8 Mon Sep 17 00:00:00 2001 From: Mohamed Moawad Date: Mon, 5 Jan 2026 15:21:45 +0200 Subject: [PATCH 1759/3659] twister: Add board-level flash_before support for pytest/shell harnesses Add support for boards to specify flash_before in their board YAML files, which is then used by pytest and shell harnesses. This is needed for Synopsys ARC development boards (hsdk, hsdk/arc_hsdk/2cores, hsdk4xd and iotdk) where the USB serial port disconnects during flashing. Signed-off-by: Mohamed Moawad --- boards/snps/hsdk/hsdk.yaml | 1 + boards/snps/hsdk/hsdk_arc_hsdk_2cores.yaml | 1 + boards/snps/hsdk4xd/hsdk4xd.yaml | 1 + boards/snps/iotdk/iotdk.yaml | 1 + doc/develop/test/twister.rst | 5 +++++ scripts/pylib/twister/twisterlib/harness.py | 7 +++++-- scripts/pylib/twister/twisterlib/platform.py | 3 +++ scripts/schemas/twister/platform-schema.yaml | 3 +++ 8 files changed, 20 insertions(+), 2 deletions(-) diff --git a/boards/snps/hsdk/hsdk.yaml b/boards/snps/hsdk/hsdk.yaml index 7a63a47ee679..b1c8312ec299 100644 --- a/boards/snps/hsdk/hsdk.yaml +++ b/boards/snps/hsdk/hsdk.yaml @@ -9,6 +9,7 @@ toolchain: supported: - smp testing: + flash_before: true ignore_tags: - net - bluetooth diff --git a/boards/snps/hsdk/hsdk_arc_hsdk_2cores.yaml b/boards/snps/hsdk/hsdk_arc_hsdk_2cores.yaml index b4bd8f19f5d3..95f5cf198067 100644 --- a/boards/snps/hsdk/hsdk_arc_hsdk_2cores.yaml +++ b/boards/snps/hsdk/hsdk_arc_hsdk_2cores.yaml @@ -9,6 +9,7 @@ toolchain: supported: - smp testing: + flash_before: true ignore_tags: - net - bluetooth diff --git a/boards/snps/hsdk4xd/hsdk4xd.yaml b/boards/snps/hsdk4xd/hsdk4xd.yaml index 8cc50a8db6b6..ef526a72a61b 100644 --- a/boards/snps/hsdk4xd/hsdk4xd.yaml +++ b/boards/snps/hsdk4xd/hsdk4xd.yaml @@ -9,6 +9,7 @@ toolchain: supported: - smp testing: + flash_before: true ignore_tags: - net - bluetooth diff --git a/boards/snps/iotdk/iotdk.yaml b/boards/snps/iotdk/iotdk.yaml index 9de77e5c1a71..39c78792df4d 100644 --- a/boards/snps/iotdk/iotdk.yaml +++ b/boards/snps/iotdk/iotdk.yaml @@ -7,6 +7,7 @@ toolchain: - cross-compile ram: 128 testing: + flash_before: true ignore_tags: - net - bluetooth diff --git a/doc/develop/test/twister.rst b/doc/develop/test/twister.rst index 57209962c4ff..f0644f5f0cc0 100644 --- a/doc/develop/test/twister.rst +++ b/doc/develop/test/twister.rst @@ -223,6 +223,11 @@ testing: power-efficient but slow CPU or simulation platform which can perform instruction accurate simulation but does it slowly. + flash_before: [True|False] (default False) + For pytest/shell harness hardware testing, flash the device before opening the serial port. + This prevents serial port disconnection issues during flashing on some boards (e.g., those + with USB CDC that reset during flash operations). + env: A list of environment variables. Twister will check if all these environment variables are set, and otherwise skip this platform. This allows the user to define a platform which should be diff --git a/scripts/pylib/twister/twisterlib/harness.py b/scripts/pylib/twister/twisterlib/harness.py index f3eb9c391cdf..9a06e059feca 100644 --- a/scripts/pylib/twister/twisterlib/harness.py +++ b/scripts/pylib/twister/twisterlib/harness.py @@ -500,8 +500,11 @@ def _generate_parameters_for_hardware(self, handler: Handler): if hardware.post_script: command.append(f'--post-script={hardware.post_script}') - if hardware.flash_before: - command.append(f'--flash-before={hardware.flash_before}') + # Check flash_before from both hardware map and platform (board YAML) + # Platform flash_before is intended for boards with USB reset issues during flashing + flash_before = hardware.flash_before or self.instance.platform.flash_before + if flash_before: + command.append(f'--flash-before={flash_before}') for fixture in hardware.fixtures: command.append(f'--twister-fixture={fixture}') diff --git a/scripts/pylib/twister/twisterlib/platform.py b/scripts/pylib/twister/twisterlib/platform.py index 779a3e29bb74..6fd98b83b2cc 100644 --- a/scripts/pylib/twister/twisterlib/platform.py +++ b/scripts/pylib/twister/twisterlib/platform.py @@ -72,6 +72,7 @@ def __init__(self): self.ignore_tags = [] self.only_tags = [] self.default = False + self.flash_before = False # if no flash size is specified by the board, take a default of 512K self.flash = 512 self.supported = set() @@ -116,6 +117,7 @@ def load(self, board, target, aliases, data, variant_data): self.default = testing.get("default", self.default) self.binaries = testing.get("binaries", []) self.timeout_multiplier = testing.get("timeout_multiplier", self.timeout_multiplier) + self.flash_before = testing.get("flash_before", self.flash_before) # testing data for variant testing_var = variant_data.get("testing", data.get("testing", {})) @@ -124,6 +126,7 @@ def load(self, board, target, aliases, data, variant_data): self.only_tags = testing_var.get("only_tags", self.only_tags) self.default = testing_var.get("default", self.default) self.binaries = testing_var.get("binaries", self.binaries) + self.flash_before = testing_var.get("flash_before", self.flash_before) renode = testing.get("renode", {}) self.uart = renode.get("uart", "") self.resc = renode.get("resc", "") diff --git a/scripts/schemas/twister/platform-schema.yaml b/scripts/schemas/twister/platform-schema.yaml index a4c0f673e46c..7ceebfe491c4 100644 --- a/scripts/schemas/twister/platform-schema.yaml +++ b/scripts/schemas/twister/platform-schema.yaml @@ -104,6 +104,9 @@ schema;platform-schema: required: false "default": type: bool + "flash_before": + type: bool + required: false "binaries": type: seq seq: From cdb53ec8aaa9df099c946e3a01ef5de492c48c5b Mon Sep 17 00:00:00 2001 From: Qiang Zhang Date: Tue, 2 Dec 2025 14:30:07 +0800 Subject: [PATCH 1760/3659] drivers: dma: mcux_edma: Remove DMA_MCUX_EDMA_V5 configuration The DMA_MCUX_EDMA_V5 configuration option has been removed and replaced with DMA_MCUX_EDMA_V4, as both versions share the same register layout and can use the same driver implementation. Key changes: - Remove CONFIG_DMA_MCUX_EDMA_V5 Kconfig option - Replace DMA_MCUX_EDMA_V5 conditionals with DMA_MCUX_EDMA_V4 - Remove DMAx_Type typedef, use DMA_Type directly - Update EDMA_HW_TCD macros for V4 to use HAL-provided accessor macros - Add DMA_MCUX_EDMA_DMAMUX Kconfig option to control DMAMUX support based on device tree property - Update device tree binding to add has-dmamux property - Update HAL driver selection to use DMA_MCUX_EDMA_DMAMUX instead of DMA_MCUX_EDMA for DMAMUX component - Add SOC_SERIES_MCXE31X to DMA_MCUX_TEST_SLOT_START configuration - Calculate DMA_TCD_ALIGN_SIZE from edma_tcd_t structure size Signed-off-by: Qiang Zhang --- drivers/dma/CMakeLists.txt | 1 - drivers/dma/Kconfig.mcux_edma | 32 +++++---- drivers/dma/dma_mcux_edma.c | 67 ++++++++++--------- dts/bindings/dma/nxp,mcux-edma.yaml | 6 ++ .../mcux/mcux-sdk-ng/drivers/drivers.cmake | 3 +- 5 files changed, 61 insertions(+), 48 deletions(-) diff --git a/drivers/dma/CMakeLists.txt b/drivers/dma/CMakeLists.txt index 6da1031f7bfa..6759b4af9155 100644 --- a/drivers/dma/CMakeLists.txt +++ b/drivers/dma/CMakeLists.txt @@ -30,7 +30,6 @@ zephyr_library_sources_ifdef(CONFIG_DMA_MCHP_XEC dma_mchp_xec.c) zephyr_library_sources_ifdef(CONFIG_DMA_MCUX_EDMA dma_mcux_edma.c) zephyr_library_sources_ifdef(CONFIG_DMA_MCUX_EDMA_V3 dma_mcux_edma.c) zephyr_library_sources_ifdef(CONFIG_DMA_MCUX_EDMA_V4 dma_mcux_edma.c) -zephyr_library_sources_ifdef(CONFIG_DMA_MCUX_EDMA_V5 dma_mcux_edma.c) zephyr_library_sources_ifdef(CONFIG_DMA_MCUX_LPC dma_mcux_lpc.c) zephyr_library_sources_ifdef(CONFIG_DMA_MCUX_SMARTDMA dma_mcux_smartdma.c) zephyr_library_sources_ifdef(CONFIG_DMA_NIOS2_MSGDMA dma_nios2_msgdma.c) diff --git a/drivers/dma/Kconfig.mcux_edma b/drivers/dma/Kconfig.mcux_edma index bbf98e599dcd..b40244bc89e7 100644 --- a/drivers/dma/Kconfig.mcux_edma +++ b/drivers/dma/Kconfig.mcux_edma @@ -5,6 +5,7 @@ EDMA_COMPAT := $(DT_COMPAT_NXP_MCUX_EDMA) REV_PROP := nxp,version +DMAMUX_PROP:= has-dmamux config DMA_MCUX_EDMA bool "MCUX DMA driver" @@ -12,35 +13,40 @@ config DMA_MCUX_EDMA depends on $(dt_compat_any_has_prop,$(EDMA_COMPAT),$(REV_PROP),2) imply NOCACHE_MEMORY if CPU_HAS_DCACHE help - DMA driver for MCUX series SoCs. + DMA version 2 driver for MCUX series SoCs with EDMA IP. config DMA_MCUX_EDMA_V3 bool "MCUX DMA v3 driver" default y depends on $(dt_compat_any_has_prop,$(EDMA_COMPAT),$(REV_PROP),3) help - DMA version 3 driver for MCUX series SoCs. + DMA version 3 driver for MCUX series SoCs with DMA3 IP. config DMA_MCUX_EDMA_V4 - bool "MCUX DMA v4 driver" + bool "MCUX DMA UNIFIED driver" default y - depends on $(dt_compat_any_has_prop,$(EDMA_COMPAT),$(REV_PROP),4) + depends on $(dt_compat_any_has_prop,$(EDMA_COMPAT),$(REV_PROP),4) || \ + $(dt_compat_any_has_prop,$(EDMA_COMPAT),$(REV_PROP),5) help - DMA version 4 driver for MCUX series SoCs. + DMA version 4 driver for MCUX Series SoCs Equipped + with Multiple EDMA IPs(EDMA, DMA3, EDMA4, EDMA5). + For the EDMA4 driver, it is compatible with different EDMA IPs + and allows different EDMA IPs to be used within a single project. + However, it required provide additional support in the SDK + device header. Therefore, only new SoCs could use it. -config DMA_MCUX_EDMA_V5 - bool "MCUX DMA v5 driver" - default y - depends on $(dt_compat_any_has_prop,$(EDMA_COMPAT),$(REV_PROP),5) +config DMA_MCUX_EDMA_DMAMUX + bool + default (DMA_MCUX_EDMA || $(dt_compat_any_has_prop,$(EDMA_COMPAT),$(DMAMUX_PROP),True)) help - DMA version 5 driver for MCUX series SoCs. + Automatically enabled when EDMA device tree node has has-dmamux property. config DMA_MCUX_MAX_DATA_SIZE int - default 64 if DMA_MCUX_EDMA_V5 || DMA_MCUX_EDMA_V4 || DMA_MCUX_EDMA_V3 + default 64 if DMA_MCUX_EDMA_V4 || DMA_MCUX_EDMA_V3 default 32 -if DMA_MCUX_EDMA || DMA_MCUX_EDMA_V3 || DMA_MCUX_EDMA_V4 || DMA_MCUX_EDMA_V5 +if DMA_MCUX_EDMA || DMA_MCUX_EDMA_V3 || DMA_MCUX_EDMA_V4 config DMA_TCD_QUEUE_SIZE int "number of TCD in a queue for SG mode" @@ -69,4 +75,4 @@ config DMA_MCUX_USE_DTCM_FOR_DMA_DESCRIPTORS When this option is activated, the descriptors for DMA transfer are located in the DTCM (Data Tightly Coupled Memory). -endif # DMA_MCUX_EDMA || DMA_MCUX_EDMA_V3 || DMA_MCUX_EDMA_V4 || DMA_MCUX_EDMA_V5 +endif # DMA_MCUX_EDMA || DMA_MCUX_EDMA_V3 || DMA_MCUX_EDMA_V4 diff --git a/drivers/dma/dma_mcux_edma.c b/drivers/dma/dma_mcux_edma.c index 4ff72ec14c45..60963afc2956 100644 --- a/drivers/dma/dma_mcux_edma.c +++ b/drivers/dma/dma_mcux_edma.c @@ -40,12 +40,6 @@ LOG_MODULE_REGISTER(dma_mcux_edma, CONFIG_DMA_LOG_LEVEL); #define HAS_CHANNEL_GAP(n) DT_INST_NODE_HAS_PROP(n, channel_gap) || #define DMA_MCUX_HAS_CHANNEL_GAP (DT_INST_FOREACH_STATUS_OKAY(HAS_CHANNEL_GAP) 0) -#if defined(CONFIG_DMA_MCUX_EDMA_V5) -typedef DMA5_Type DMAx_Type; -#else -typedef DMA_Type DMAx_Type; -#endif - struct dma_mcux_edma_config { DEVICE_MMIO_NAMED_ROM(edma_mmio); #if defined(FSL_FEATURE_SOC_DMAMUX_COUNT) && FSL_FEATURE_SOC_DMAMUX_COUNT @@ -100,7 +94,7 @@ struct dma_mcux_edma_data { #define DEV_CFG(dev) \ ((const struct dma_mcux_edma_config *const)dev->config) #define DEV_DATA(dev) ((struct dma_mcux_edma_data *)dev->data) -#define DEV_BASE(dev) ((DMAx_Type *)DEVICE_MMIO_NAMED_GET(dev, edma_mmio)) +#define DEV_BASE(dev) ((DMA_Type *)DEVICE_MMIO_NAMED_GET(dev, edma_mmio)) #define DEV_CHANNEL_DATA(dev, ch) \ ((struct call_back *)(&(DEV_DATA(dev)->data_cb[ch]))) @@ -130,24 +124,39 @@ struct dma_mcux_edma_data { #else #define EDMA_HW_TCD_CH_ACTIVE_MASK (DMA_CSR_ACTIVE_MASK) #endif /* CONFIG_DMA_MCUX_EDMA_V3 */ -#elif defined(CONFIG_DMA_MCUX_EDMA_V4) || defined(CONFIG_DMA_MCUX_EDMA_V5) +#elif defined(CONFIG_DMA_MCUX_EDMA_V4) /* Above macros have been defined in fsl_edma_core.h */ #define EDMA_HW_TCD_CH_ACTIVE_MASK (DMA_CH_CSR_ACTIVE_MASK) #endif /* Definations for HW TCD fields */ -#if defined(CONFIG_DMA_MCUX_EDMA) || defined(CONFIG_DMA_MCUX_EDMA_V5) +#if defined(CONFIG_DMA_MCUX_EDMA) #define EDMA_HW_TCD_SADDR(dev, ch) (DEV_BASE(dev)->TCD[ch].SADDR) #define EDMA_HW_TCD_DADDR(dev, ch) (DEV_BASE(dev)->TCD[ch].DADDR) #define EDMA_HW_TCD_BITER(dev, ch) (DEV_BASE(dev)->TCD[ch].BITER_ELINKNO) #define EDMA_HW_TCD_CITER(dev, ch) (DEV_BASE(dev)->TCD[ch].CITER_ELINKNO) #define EDMA_HW_TCD_CSR(dev, ch) (DEV_BASE(dev)->TCD[ch].CSR) -#elif defined(CONFIG_DMA_MCUX_EDMA_V3) || defined(CONFIG_DMA_MCUX_EDMA_V4) +#elif defined(CONFIG_DMA_MCUX_EDMA_V3) #define EDMA_HW_TCD_SADDR(dev, ch) (DEV_BASE(dev)->CH[ch].TCD_SADDR) #define EDMA_HW_TCD_DADDR(dev, ch) (DEV_BASE(dev)->CH[ch].TCD_DADDR) #define EDMA_HW_TCD_BITER(dev, ch) (DEV_BASE(dev)->CH[ch].TCD_BITER_ELINKNO) #define EDMA_HW_TCD_CITER(dev, ch) (DEV_BASE(dev)->CH[ch].TCD_CITER_ELINKNO) #define EDMA_HW_TCD_CSR(dev, ch) (DEV_BASE(dev)->CH[ch].TCD_CSR) +#elif defined(CONFIG_DMA_MCUX_EDMA_V4) +/* + * For different EDMA IPs, the register read methods vary. Therefore, for devices + * incorporating multiple EDMA types, hardware access must be abstracted and unified. + */ +#define EDMA_HW_TCD_SADDR(dev, ch) EDMA_TCD_SADDR(EDMA_TCD_BASE((void *)DEV_BASE(dev), ch), \ + EDMA_TCD_TYPE((void *)DEV_BASE(dev))) +#define EDMA_HW_TCD_DADDR(dev, ch) EDMA_TCD_DADDR(EDMA_TCD_BASE((void *)DEV_BASE(dev), ch), \ + EDMA_TCD_TYPE((void *)DEV_BASE(dev))) +#define EDMA_HW_TCD_BITER(dev, ch) EDMA_TCD_BITER(EDMA_TCD_BASE((void *)DEV_BASE(dev), ch), \ + EDMA_TCD_TYPE((void *)DEV_BASE(dev))) +#define EDMA_HW_TCD_CITER(dev, ch) EDMA_TCD_CITER(EDMA_TCD_BASE((void *)DEV_BASE(dev), ch), \ + EDMA_TCD_TYPE((void *)DEV_BASE(dev))) +#define EDMA_HW_TCD_CSR(dev, ch) EDMA_TCD_CSR(EDMA_TCD_BASE((void *)DEV_BASE(dev), ch), \ + EDMA_TCD_TYPE((void *)DEV_BASE(dev))) #endif #if defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET @@ -302,7 +311,6 @@ static void edma_configure_dmamux(const struct device *dev, uint32_t channel, DMAMUX_SetSource(DEV_DMAMUX_BASE(dev, dmamux_idx), dmamux_channel, slot); #endif /* nxp_a_on */ - /* dam_imx_rt_set_channel_priority(dev, channel, config); */ DMAMUX_EnableChannel(DEV_DMAMUX_BASE(dev, dmamux_idx), dmamux_channel); } @@ -358,7 +366,7 @@ static int dma_mcux_edma_configure_sg_loop(const struct device *dev, /* Init all TCDs with the para in transfer config and link them. */ for (int i = 0; i < CONFIG_DMA_TCD_QUEUE_SIZE; i++) { -#if defined(CONFIG_DMA_MCUX_EDMA_V5) +#if defined(CONFIG_DMA_MCUX_EDMA_V4) EDMA_TcdSetTransferConfigExt(DEV_BASE(dev), &DEV_CFG(dev)->tcdpool[channel][i], &data->transferConfig, &DEV_CFG(dev)->tcdpool[channel][(i + 1) % @@ -464,7 +472,7 @@ static int dma_mcux_edma_configure_basic(const struct device *dev, struct call_back *data = DEV_CHANNEL_DATA(dev, channel); struct dma_mcux_channel_transfer_edma_settings *xfer_settings = &data->transfer_settings; struct dma_block_config *block_config = config->head_block; - uint32_t hw_channel; + uint32_t hw_channel = dma_mcux_edma_add_channel_gap(dev, channel); int ret = 0; /* block_count shall be 1 */ @@ -691,8 +699,7 @@ static int dma_mcux_edma_start(const struct device *dev, uint32_t channel) edma_log_dmamux(dev, channel); -#if !defined(CONFIG_DMA_MCUX_EDMA_V3) && !defined(CONFIG_DMA_MCUX_EDMA_V4) \ - && !defined(CONFIG_DMA_MCUX_EDMA_V5) +#if !defined(CONFIG_DMA_MCUX_EDMA_V3) && !defined(CONFIG_DMA_MCUX_EDMA_V4) LOG_DBG("DMA CR 0x%x", DEV_BASE(dev)->CR); #endif data->busy = true; @@ -856,7 +863,7 @@ static int edma_reload_loop(const struct device *dev, uint32_t channel, */ EDMA_ClearChannelStatusFlags(DEV_BASE(dev), channel, kEDMA_DoneFlag); EDMA_HW_TCD_CSR(dev, channel) |= DMA_CSR_ESG_MASK; -#elif (CONFIG_DMA_MCUX_EDMA_V3 || CONFIG_DMA_MCUX_EDMA_V4 || CONFIG_DMA_MCUX_EDMA_V5) +#elif (CONFIG_DMA_MCUX_EDMA_V3 || CONFIG_DMA_MCUX_EDMA_V4) /*We have not verified if this issue exist on V3/V4 HW, jut place a holder here. */ #endif /* TCDs are configured. Resume DMA */ @@ -951,7 +958,7 @@ static int dma_mcux_edma_get_status(const struct device *dev, uint32_t channel, edma_log_dmamux(dev, channel); -#if defined(CONFIG_DMA_MCUX_EDMA_V3) || defined(CONFIG_DMA_MCUX_EDMA_V4) +#if defined(CONFIG_DMA_MCUX_EDMA_V3) LOG_DBG("DMA MP_CSR 0x%x", DEV_BASE(dev)->MP_CSR); LOG_DBG("DMA MP_ES 0x%x", DEV_BASE(dev)->MP_ES); LOG_DBG("DMA CHx_ES 0x%x", DEV_BASE(dev)->CH[hw_channel].CH_ES); @@ -959,16 +966,16 @@ static int dma_mcux_edma_get_status(const struct device *dev, uint32_t channel, LOG_DBG("DMA CHx_ES 0x%x", DEV_BASE(dev)->CH[hw_channel].CH_ES); LOG_DBG("DMA CHx_INT 0x%x", DEV_BASE(dev)->CH[hw_channel].CH_INT); LOG_DBG("DMA TCD_CSR 0x%x", DEV_BASE(dev)->CH[hw_channel].TCD_CSR); -#elif defined(CONFIG_DMA_MCUX_EDMA_V5) - LOG_DBG("DMA MP_CSR 0x%x", DEV_BASE(dev)->MP_CSR); - LOG_DBG("DMA MP_ES 0x%x", DEV_BASE(dev)->MP_ES); - LOG_DBG("DMA CHx_ES 0x%x", DEV_BASE(dev)->TCD[hw_channel].CH_ES); - LOG_DBG("DMA CHx_CSR 0x%x", DEV_BASE(dev)->TCD[hw_channel].CH_CSR); - LOG_DBG("DMA CHx_ES 0x%x", DEV_BASE(dev)->TCD[hw_channel].CH_ES); - LOG_DBG("DMA CHx_INT 0x%x", DEV_BASE(dev)->TCD[hw_channel].CH_INT); - LOG_DBG("DMA TCD_CSR 0x%x", DEV_BASE(dev)->TCD[hw_channel].CSR); - LOG_DBG("DMA TCD_SADDR 0x%x", DEV_BASE(dev)->TCD[hw_channel].SADDR); - LOG_DBG("DMA TCD_DADDR 0x%x", DEV_BASE(dev)->TCD[hw_channel].DADDR); +#elif defined(CONFIG_DMA_MCUX_EDMA_V4) + LOG_DBG("DMA MP_CSR 0x%x", EDMA_MP_BASE(DEV_BASE(dev))->MP_CSR); + LOG_DBG("DMA MP_ES 0x%x", EDMA_MP_BASE(DEV_BASE(dev))->MP_ES); + LOG_DBG("DMA CHx_ES 0x%x", EDMA_CHANNEL_BASE(DEV_BASE(dev), hw_channel)->CH_ES); + LOG_DBG("DMA CHx_CSR 0x%x", EDMA_CHANNEL_BASE(DEV_BASE(dev), hw_channel)->CH_CSR); + LOG_DBG("DMA CHx_ES 0x%x", EDMA_CHANNEL_BASE(DEV_BASE(dev), hw_channel)->CH_ES); + LOG_DBG("DMA CHx_INT 0x%x", EDMA_CHANNEL_BASE(DEV_BASE(dev), hw_channel)->CH_INT); + LOG_DBG("DMA TCD_CSR 0x%x", EDMA_HW_TCD_CSR(dev, hw_channel)); + LOG_DBG("DMA TCD_SADDR 0x%x", EDMA_HW_TCD_SADDR(dev, hw_channel)); + LOG_DBG("DMA TCD_DADDR 0x%x", EDMA_HW_TCD_DADDR(dev, hw_channel)); #else LOG_DBG("DMA CR 0x%x", DEV_BASE(dev)->CR); LOG_DBG("DMA INT 0x%x", DEV_BASE(dev)->INT); @@ -1126,11 +1133,7 @@ static int dma_mcux_edma_init(const struct device *dev) #define CHANNELS_PER_MUX(n) #endif -#if defined(CONFIG_DMA_MCUX_EDMA_V5) -#define DMA_TCD_ALIGN_SIZE 64 -#else -#define DMA_TCD_ALIGN_SIZE 32 -#endif +#define DMA_TCD_ALIGN_SIZE sizeof(edma_tcd_t) /* * Note: the TCD pool *must* be in non cacheable memory. All of the NXP SOCs diff --git a/dts/bindings/dma/nxp,mcux-edma.yaml b/dts/bindings/dma/nxp,mcux-edma.yaml index d6e0d0c4f42c..8f9f2e616b7d 100644 --- a/dts/bindings/dma/nxp,mcux-edma.yaml +++ b/dts/bindings/dma/nxp,mcux-edma.yaml @@ -31,6 +31,12 @@ properties: DMAMUX. This value is used to validate the request source index provided in the DMA specifier. + has-dmamux: + type: boolean + description: | + Indicates whether the DMA controller has an integrated DMAMUX. + If present, the controller includes DMAMUX functionality. + dmamux-reg-offset: type: int default: 0 diff --git a/modules/hal_nxp/mcux/mcux-sdk-ng/drivers/drivers.cmake b/modules/hal_nxp/mcux/mcux-sdk-ng/drivers/drivers.cmake index 3b209071ffd9..c47f9bdb1d99 100644 --- a/modules/hal_nxp/mcux/mcux-sdk-ng/drivers/drivers.cmake +++ b/modules/hal_nxp/mcux/mcux-sdk-ng/drivers/drivers.cmake @@ -57,12 +57,11 @@ set_variable_ifdef(CONFIG_COUNTER_MCUX_RTC_JDP CONFIG_MCUX_COMPONENT_driver.rtc set_variable_ifdef(CONFIG_DAC_MCUX_DAC CONFIG_MCUX_COMPONENT_driver.dac) set_variable_ifdef(CONFIG_DAC_MCUX_DAC12 CONFIG_MCUX_COMPONENT_driver.dac12) set_variable_ifdef(CONFIG_DAC_MCUX_DAC32 CONFIG_MCUX_COMPONENT_driver.dac32) -set_variable_ifdef(CONFIG_DMA_MCUX_EDMA CONFIG_MCUX_COMPONENT_driver.dmamux) set_variable_ifdef(CONFIG_DMA_MCUX_EDMA CONFIG_MCUX_COMPONENT_driver.edma) set_variable_ifdef(CONFIG_DMA_MCUX_EDMA_V3 CONFIG_MCUX_COMPONENT_driver.dma3) set_variable_ifdef(CONFIG_DMA_MCUX_EDMA_V4 CONFIG_MCUX_COMPONENT_driver.edma4) +set_variable_ifdef(CONFIG_DMA_MCUX_EDMA_DMAMUX CONFIG_MCUX_COMPONENT_driver.dmamux) set_variable_ifdef(CONFIG_DMA_NXP_EDMA CONFIG_MCUX_COMPONENT_driver.edma_rev2) -set_variable_ifdef(CONFIG_DMA_MCUX_EDMA_V5 CONFIG_MCUX_COMPONENT_driver.edma4) set_variable_ifdef(CONFIG_EDAC_NXP_EIM CONFIG_MCUX_COMPONENT_driver.eim) set_variable_ifdef(CONFIG_EDAC_NXP_ERM CONFIG_MCUX_COMPONENT_driver.erm) set_variable_ifdef(CONFIG_ENTROPY_MCUX_RNGA CONFIG_MCUX_COMPONENT_driver.rnga) From 33e71b448bfd16c03a963b33a45e813413338514 Mon Sep 17 00:00:00 2001 From: Qiang Zhang Date: Tue, 2 Dec 2025 14:33:58 +0800 Subject: [PATCH 1761/3659] dts: arm: nxp: Update EDMA device tree configurations Update EDMA device tree nodes for NXP MCXE31B platforms to align with the unified EDMA driver implementation. Signed-off-by: Qiang Zhang --- boards/nxp/frdm_mcxe31b/frdm_mcxe31b.dts | 4 ++++ boards/nxp/frdm_mcxe31b/frdm_mcxe31b.yaml | 1 + drivers/dma/Kconfig.mcux_edma | 5 +++-- dts/arm/nxp/nxp_mcxe31x_common.dtsi | 8 ++++++-- 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/boards/nxp/frdm_mcxe31b/frdm_mcxe31b.dts b/boards/nxp/frdm_mcxe31b/frdm_mcxe31b.dts index d0c8ef2d7272..fed4b33c9b53 100644 --- a/boards/nxp/frdm_mcxe31b/frdm_mcxe31b.dts +++ b/boards/nxp/frdm_mcxe31b/frdm_mcxe31b.dts @@ -100,6 +100,10 @@ clock-frequency = ; }; +&edma { + status = "okay"; +}; + &erm0 { status = "okay"; }; diff --git a/boards/nxp/frdm_mcxe31b/frdm_mcxe31b.yaml b/boards/nxp/frdm_mcxe31b/frdm_mcxe31b.yaml index 0d46a01922ab..e2a69046a790 100644 --- a/boards/nxp/frdm_mcxe31b/frdm_mcxe31b.yaml +++ b/boards/nxp/frdm_mcxe31b/frdm_mcxe31b.yaml @@ -15,6 +15,7 @@ supported: - can - gpio - rtc + - dma - watchdog - adc vendor: nxp diff --git a/drivers/dma/Kconfig.mcux_edma b/drivers/dma/Kconfig.mcux_edma index b40244bc89e7..56160be6f0cc 100644 --- a/drivers/dma/Kconfig.mcux_edma +++ b/drivers/dma/Kconfig.mcux_edma @@ -57,11 +57,12 @@ config DMA_TCD_QUEUE_SIZE config DMA_MCUX_TEST_SLOT_START int "test slot start num" depends on (SOC_SERIES_KINETIS_K6X || SOC_SERIES_KINETIS_KE1XF \ - || SOC_SERIES_S32K3 || SOC_SERIES_S32ZE || SOC_SERIES_KE1XZ || SOC_SERIES_MCXE24X) + || SOC_SERIES_S32K3 || SOC_SERIES_S32ZE || SOC_SERIES_KE1XZ || SOC_SERIES_MCXE24X \ + || SOC_SERIES_MCXE31X) default 58 if SOC_SERIES_KINETIS_K6X default 60 if SOC_SERIES_KINETIS_KE1XF default 60 if SOC_SERIES_KE1XZ - default 62 if SOC_SERIES_S32K3 || SOC_SERIES_S32ZE || SOC_SERIES_MCXE24X + default 62 if SOC_SERIES_S32K3 || SOC_SERIES_S32ZE || SOC_SERIES_MCXE24X || SOC_SERIES_MCXE31X help test slot start num diff --git a/dts/arm/nxp/nxp_mcxe31x_common.dtsi b/dts/arm/nxp/nxp_mcxe31x_common.dtsi index c3bea2f8d21e..b259980b58a0 100644 --- a/dts/arm/nxp/nxp_mcxe31x_common.dtsi +++ b/dts/arm/nxp/nxp_mcxe31x_common.dtsi @@ -149,9 +149,13 @@ edma: edma@20c000 { #dma-cells = <2>; compatible = "nxp,mcux-edma"; - reg = <0x20c000 0x19c>; + reg = <0x20c000 0x3000>, <0x280000 0x4000>, <0x284000 0x4000>; + nxp,version = <4>; dma-channels = <32>; - dma-requests = <128>; + dma-requests = <64>; + has-dmamux; + nxp,mem2mem; + no-error-irq; interrupts = <4 0>, <5 0>, <6 0>, <7 0>, <8 0>, <9 0>, <10 0>, <11 0>, <12 0>, <13 0>, <14 0>, <15 0>, From 3a5cdd0be97223a161926bf9a4f55da019b95ba3 Mon Sep 17 00:00:00 2001 From: Qiang Zhang Date: Thu, 18 Dec 2025 10:41:21 +0800 Subject: [PATCH 1762/3659] dts: nxp: frdm_mcxe31b: Add LPUART2 DMA support Add pinctrl configuration and DMA channel assignments for LPUART2 on the FRDM-MCXE31B board. Signed-off-by: Qiang Zhang --- boards/nxp/frdm_mcxe31b/frdm_mcxe31b-pinctrl.dtsi | 12 ++++++++++++ boards/nxp/frdm_mcxe31b/frdm_mcxe31b.dts | 10 ++++++++++ 2 files changed, 22 insertions(+) diff --git a/boards/nxp/frdm_mcxe31b/frdm_mcxe31b-pinctrl.dtsi b/boards/nxp/frdm_mcxe31b/frdm_mcxe31b-pinctrl.dtsi index af1515c094bd..454c816d3ced 100644 --- a/boards/nxp/frdm_mcxe31b/frdm_mcxe31b-pinctrl.dtsi +++ b/boards/nxp/frdm_mcxe31b/frdm_mcxe31b-pinctrl.dtsi @@ -13,6 +13,18 @@ }; }; + pinmux_lpuart_2: pinmux_lpuart_2 { + group1 { + pinmux = ; + output-enable; + }; + + group2 { + pinmux = ; + input-enable; + }; + }; + pinmux_lpuart_5: pinmux_lpuart_5 { group1 { pinmux = ; diff --git a/boards/nxp/frdm_mcxe31b/frdm_mcxe31b.dts b/boards/nxp/frdm_mcxe31b/frdm_mcxe31b.dts index fed4b33c9b53..65781a660edb 100644 --- a/boards/nxp/frdm_mcxe31b/frdm_mcxe31b.dts +++ b/boards/nxp/frdm_mcxe31b/frdm_mcxe31b.dts @@ -124,6 +124,13 @@ status = "okay"; }; +&lpuart_2 { + pinctrl-0 = <&pinmux_lpuart_2>; + pinctrl-names = "default"; + dmas = <&edma 16 38>, <&edma 17 39>; + dma-names = "tx", "rx"; +}; + &lpuart_5 { status = "okay"; current-speed = <115200>; @@ -219,3 +226,6 @@ &adc_0 { status = "okay"; }; + +/* Add lpuart2 label to lpuart_2. */ +lpuart2: &lpuart_2 {}; From be3e51d444e93ef6ccb4c49731a4de4f26470dbc Mon Sep 17 00:00:00 2001 From: Qiang Zhang Date: Tue, 2 Dec 2025 14:53:22 +0800 Subject: [PATCH 1763/3659] tests: drivers/dma: Add support for frdm_mcxe31b Add board-specific configuration and overlay files to enable DMA testing on the FRDM-MCXE31B board. Signed-off-by: Qiang Zhang --- .../dma/chan_blen_transfer/boards/frdm_mcxe31b.overlay | 8 ++++++++ .../dma/chan_link_transfer/boards/frdm_mcxe31b.overlay | 8 ++++++++ tests/drivers/dma/chan_link_transfer/testcase.yaml | 1 + .../drivers/dma/loop_transfer/boards/frdm_mcxe31b.overlay | 8 ++++++++ tests/drivers/dma/scatter_gather/boards/frdm_mcxe31b.conf | 1 + .../dma/scatter_gather/boards/frdm_mcxe31b.overlay | 8 ++++++++ tests/drivers/dma/scatter_gather/testcase.yaml | 1 + 7 files changed, 35 insertions(+) create mode 100644 tests/drivers/dma/chan_blen_transfer/boards/frdm_mcxe31b.overlay create mode 100644 tests/drivers/dma/chan_link_transfer/boards/frdm_mcxe31b.overlay create mode 100644 tests/drivers/dma/loop_transfer/boards/frdm_mcxe31b.overlay create mode 100644 tests/drivers/dma/scatter_gather/boards/frdm_mcxe31b.conf create mode 100644 tests/drivers/dma/scatter_gather/boards/frdm_mcxe31b.overlay diff --git a/tests/drivers/dma/chan_blen_transfer/boards/frdm_mcxe31b.overlay b/tests/drivers/dma/chan_blen_transfer/boards/frdm_mcxe31b.overlay new file mode 100644 index 000000000000..bdf204b0536e --- /dev/null +++ b/tests/drivers/dma/chan_blen_transfer/boards/frdm_mcxe31b.overlay @@ -0,0 +1,8 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* Add test label to edma node */ +tst_dma0: &edma {}; diff --git a/tests/drivers/dma/chan_link_transfer/boards/frdm_mcxe31b.overlay b/tests/drivers/dma/chan_link_transfer/boards/frdm_mcxe31b.overlay new file mode 100644 index 000000000000..bdf204b0536e --- /dev/null +++ b/tests/drivers/dma/chan_link_transfer/boards/frdm_mcxe31b.overlay @@ -0,0 +1,8 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* Add test label to edma node */ +tst_dma0: &edma {}; diff --git a/tests/drivers/dma/chan_link_transfer/testcase.yaml b/tests/drivers/dma/chan_link_transfer/testcase.yaml index c3865d0c5620..ea037b1d75b0 100644 --- a/tests/drivers/dma/chan_link_transfer/testcase.yaml +++ b/tests/drivers/dma/chan_link_transfer/testcase.yaml @@ -8,6 +8,7 @@ tests: platform_allow: - frdm_k64f - frdm_mcxe247 + - frdm_mcxe31b - mimxrt595_evk/mimxrt595s/cm33 - mimxrt1010_evk - mimxrt1050_evk/mimxrt1052/hyperflash diff --git a/tests/drivers/dma/loop_transfer/boards/frdm_mcxe31b.overlay b/tests/drivers/dma/loop_transfer/boards/frdm_mcxe31b.overlay new file mode 100644 index 000000000000..bdf204b0536e --- /dev/null +++ b/tests/drivers/dma/loop_transfer/boards/frdm_mcxe31b.overlay @@ -0,0 +1,8 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* Add test label to edma node */ +tst_dma0: &edma {}; diff --git a/tests/drivers/dma/scatter_gather/boards/frdm_mcxe31b.conf b/tests/drivers/dma/scatter_gather/boards/frdm_mcxe31b.conf new file mode 100644 index 000000000000..61f2d18ca3c7 --- /dev/null +++ b/tests/drivers/dma/scatter_gather/boards/frdm_mcxe31b.conf @@ -0,0 +1 @@ +CONFIG_DMA_TCD_QUEUE_SIZE=4 diff --git a/tests/drivers/dma/scatter_gather/boards/frdm_mcxe31b.overlay b/tests/drivers/dma/scatter_gather/boards/frdm_mcxe31b.overlay new file mode 100644 index 000000000000..bdf204b0536e --- /dev/null +++ b/tests/drivers/dma/scatter_gather/boards/frdm_mcxe31b.overlay @@ -0,0 +1,8 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* Add test label to edma node */ +tst_dma0: &edma {}; diff --git a/tests/drivers/dma/scatter_gather/testcase.yaml b/tests/drivers/dma/scatter_gather/testcase.yaml index bb8191b5eeeb..1b4339ba0cd7 100644 --- a/tests/drivers/dma/scatter_gather/testcase.yaml +++ b/tests/drivers/dma/scatter_gather/testcase.yaml @@ -8,6 +8,7 @@ tests: - intel_adsp/cavs25 - frdm_k64f - frdm_mcxe247 + - frdm_mcxe31b - mimxrt1010_evk - mimxrt685_evk/mimxrt685s/cm33 - mimxrt1060_evk/mimxrt1062/qspi From a96905a60166c60fc69f0e0553d9a1f355c0555a Mon Sep 17 00:00:00 2001 From: Qiang Zhang Date: Thu, 18 Dec 2025 10:44:41 +0800 Subject: [PATCH 1764/3659] tests: drivers/uart: Add async API support for frdm_mcxe31b Add board-specific overlay file to enable UART async API testing on the FRDM-MCXE31B board. Signed-off-by: Qiang Zhang --- tests/drivers/uart/uart_async_api/testcase.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/drivers/uart/uart_async_api/testcase.yaml b/tests/drivers/uart/uart_async_api/testcase.yaml index 2134301f268e..cf29a6618aba 100644 --- a/tests/drivers/uart/uart_async_api/testcase.yaml +++ b/tests/drivers/uart/uart_async_api/testcase.yaml @@ -113,6 +113,7 @@ tests: - platform:mimxrt1060_evk@B/mimxrt1062/qspi:"DTC_OVERLAY_FILE=nxp/dut_lpuart3_loopback.overlay" - platform:mimxrt1060_evk@C/mimxrt1062/qspi:"DTC_OVERLAY_FILE=nxp/dut_lpuart3_loopback.overlay" - platform:mimxrt1064_evk/mimxrt1064:"DTC_OVERLAY_FILE=nxp/dut_lpuart3_loopback.overlay" + - platform:frdm_mcxe31b/mcxe31b:"DTC_OVERLAY_FILE=nxp/dut_lpuart2_loopback.overlay" drivers.uart.async_api.sam0: filter: CONFIG_SERIAL_SUPPORT_ASYNC and CONFIG_SOC_FAMILY_ATMEL_SAM0 platform_allow: From 22e754c77e36f73c2d9890bf240cb5ab758a9e94 Mon Sep 17 00:00:00 2001 From: Qiang Zhang Date: Tue, 30 Dec 2025 17:12:41 +0800 Subject: [PATCH 1765/3659] doc: migration-guide-4.4: Document DMA_MCUX_EDMA_V5 removal Add migration guide entry for the removal of CONFIG_DMA_MCUX_EDMA_V5 configuration option. Signed-off-by: Qiang Zhang --- doc/releases/migration-guide-4.4.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/doc/releases/migration-guide-4.4.rst b/doc/releases/migration-guide-4.4.rst index 86583acbff39..032380264318 100644 --- a/doc/releases/migration-guide-4.4.rst +++ b/doc/releases/migration-guide-4.4.rst @@ -275,6 +275,13 @@ Counter GPT now uses explicit devicetree properties rather than hardcoded values, allowing per-instance customization. +DMA +=== + +* Removed the :kconfig:option:`CONFIG_DMA_MCUX_EDMA_V5` (:github:`100341`). This macro previously distinguished between + nxp,version(5) and nxp,version(4). It now supports unified maintenance for both versions. + Users can modify ``DMA_MCUX_EDMA_V5`` to ``DMA_MCUX_EDMA_V4``. + EEPROM ====== From 307c13ad7a915c8fb6a305172a37c7254ad2bd99 Mon Sep 17 00:00:00 2001 From: Albort Xue Date: Mon, 15 Dec 2025 16:17:55 +0800 Subject: [PATCH 1766/3659] drivers: flash: flexspi_nor: Add RDSR2 command to quad enable LUT When qer is S2B1v1 or S2B1v4, reading Status Register 1 and Status Register 2 requires different opcodes, and writing Status Register 1/2 requires two bytes in a single write. Add the Read Status Register 2 command sequence to the LUT used by the quad-enable function, and ensure the write operation sends two bytes (SR1|SR2) when setting the QE bit. Signed-off-by: Albort Xue --- drivers/flash/flash_mcux_flexspi_nor.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/flash/flash_mcux_flexspi_nor.c b/drivers/flash/flash_mcux_flexspi_nor.c index 13be9f367866..e24d104cd287 100644 --- a/drivers/flash/flash_mcux_flexspi_nor.c +++ b/drivers/flash/flash_mcux_flexspi_nor.c @@ -592,6 +592,15 @@ static int flash_flexspi_nor_quad_enable(struct flash_flexspi_nor_data *data, flexspi_lut[SCRATCH_CMD][0] = FLEXSPI_LUT_SEQ( kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, SPI_NOR_CMD_RDSR, kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x1); + flexspi_lut[SCRATCH_CMD][1] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_JUMP_ON_CS, kFLEXSPI_1PAD, 0x2, + kFLEXSPI_Command_JUMP_ON_CS, kFLEXSPI_1PAD, 0x2); + flexspi_lut[SCRATCH_CMD][2] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, SPI_NOR_CMD_RDSR2, + kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x1); + flexspi_lut[SCRATCH_CMD][3] = FLEXSPI_LUT_SEQ( + kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0x0, + kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0x0); flexspi_lut[SCRATCH_CMD2][0] = FLEXSPI_LUT_SEQ( kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, SPI_NOR_CMD_WRSR, kFLEXSPI_Command_WRITE_SDR, kFLEXSPI_1PAD, 0x1); From 077e23482c03c7a0355e3bcc9b26b35a1acd5a9b Mon Sep 17 00:00:00 2001 From: James Roy Date: Mon, 12 Jan 2026 22:42:22 +0800 Subject: [PATCH 1767/3659] doc: scripts: Add a language parameter to the to_code_block() Introduce a `language` parameter in `to_code_block()` for syntax highlighting support (default: None). Signed-off-by: James Roy --- doc/_scripts/gen_devicetree_rest.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/_scripts/gen_devicetree_rest.py b/doc/_scripts/gen_devicetree_rest.py index 82c18b085ee0..766f1dc5b9af 100644 --- a/doc/_scripts/gen_devicetree_rest.py +++ b/doc/_scripts/gen_devicetree_rest.py @@ -819,13 +819,13 @@ def print_block(block, string_io): print(textwrap.dedent(block), file=string_io) -def to_code_block(s, indent=0): +def to_code_block(s, indent=0, language='none'): # Converts 's', a string, to an indented rst .. code-block::. The # 'indent' argument is a leading indent for each line in the code # block, in spaces. indent = indent * ' ' - return ('.. code-block:: none\n\n' + - textwrap.indent(s, indent + ' ') + '\n') + return (f".. code-block:: {language}\n\n" + f"{textwrap.indent(s, f'{indent} ')}\n") def compatible_vnd(compatible): # Get the vendor prefix for a compatible string 'compatible'. From 4c8cb73198809e25e48d599ddc405fbf15e89869 Mon Sep 17 00:00:00 2001 From: James Roy Date: Wed, 14 Jan 2026 22:14:03 +0800 Subject: [PATCH 1768/3659] doc: Generate documentation for the binding examples Generate an rst document with an `Examples` section from the sample nodes written in the examples of the binding. Signed-off-by: James Roy --- doc/_scripts/gen_devicetree_rest.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/doc/_scripts/gen_devicetree_rest.py b/doc/_scripts/gen_devicetree_rest.py index 766f1dc5b9af..f66114583d62 100644 --- a/doc/_scripts/gen_devicetree_rest.py +++ b/doc/_scripts/gen_devicetree_rest.py @@ -596,6 +596,16 @@ def print_binding_page(binding, base_names, vnd_lookup, driver_sources,dup_compa description = binding.description.strip() print(to_code_block(description), file=string_io) + # Examples + if binding.examples: + print_block('''\ + Examples + ******** + ''', string_io) + blocks = [to_code_block(example, language='dts') + for example in binding.examples] + print("\n----\n".join(blocks), file=string_io) + # Properties. print_block('''\ Properties From 212a8fe8c9307cb75725feed2e0bd321cf4d70ed Mon Sep 17 00:00:00 2001 From: Robert Robinson Date: Wed, 10 Dec 2025 15:06:45 +0000 Subject: [PATCH 1769/3659] dts: arm: nordic: Add support for nRF7120 Add dts files for nRF7120 SoC. Signed-off-by: Robert Robinson --- MAINTAINERS.yml | 1 + drivers/entropy/Kconfig.nrf_cracen | 6 +- drivers/wifi/nrf_wifi/Kconfig.nrfwifi | 7 +- dts/arm/nordic/nrf7120_enga_cpuapp.dtsi | 150 +++ dts/bindings/arm/nordic,nrf-pwr-antswc.yaml | 20 + dts/bindings/clock/nordic,nrf71-lfxo.yaml | 56 + dts/bindings/wifi/nordic,nrf71-wifi.yaml | 12 + dts/riscv/nordic/nrf7120_enga_cpuflpr.dtsi | 74 ++ .../nordic/nrf7120_cpuapp_ns_partition.dtsi | 62 ++ .../nordic/nrf7120_cpuapp_partition.dtsi | 40 + dts/vendor/nordic/nrf7120_enga.dtsi | 960 ++++++++++++++++++ .../nrf7120_enga_secure_peripherals.dtsi | 50 + modules/nrf_wifi/bus/Kconfig | 5 +- 13 files changed, 1431 insertions(+), 12 deletions(-) create mode 100644 dts/arm/nordic/nrf7120_enga_cpuapp.dtsi create mode 100644 dts/bindings/arm/nordic,nrf-pwr-antswc.yaml create mode 100644 dts/bindings/clock/nordic,nrf71-lfxo.yaml create mode 100644 dts/bindings/wifi/nordic,nrf71-wifi.yaml create mode 100644 dts/riscv/nordic/nrf7120_enga_cpuflpr.dtsi create mode 100644 dts/vendor/nordic/nrf7120_cpuapp_ns_partition.dtsi create mode 100644 dts/vendor/nordic/nrf7120_cpuapp_partition.dtsi create mode 100644 dts/vendor/nordic/nrf7120_enga.dtsi create mode 100644 dts/vendor/nordic/nrf7120_enga_secure_peripherals.dtsi diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index 64cd45e94c9b..848b34d3a264 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -2634,6 +2634,7 @@ Documentation Infrastructure: - dts/bindings/wifi/nordic,nrf7000-spi.yaml - dts/bindings/wifi/nordic,nrf7001-qspi.yaml - dts/bindings/wifi/nordic,nrf7001-spi.yaml + - dts/bindings/wifi/nordic,nrf71-wifi.yaml - boards/shields/nrf7002ek/ labels: - "area: Wi-Fi" diff --git a/drivers/entropy/Kconfig.nrf_cracen b/drivers/entropy/Kconfig.nrf_cracen index 8941096a126f..903a304c6808 100644 --- a/drivers/entropy/Kconfig.nrf_cracen +++ b/drivers/entropy/Kconfig.nrf_cracen @@ -5,13 +5,13 @@ config ENTROPY_NRF_CRACEN_CTR_DRBG bool "nRF entropy driver based on the CRACEN CTR_DRBG driver" default y depends on DT_HAS_NORDIC_NRF_CRACEN_CTRDRBG_ENABLED - depends on SOC_COMPATIBLE_NRF54LX + depends on SOC_COMPATIBLE_NRF54LX || SOC_COMPATIBLE_NRF7120_ENGA select ENTROPY_HAS_DRIVER select NRFX_CRACEN help - This option enables the 54L CRACEN based entropy driver, based on the nrfx CRACEN CTR_DRBG + This option enables the 54L/7120 CRACEN based entropy driver, based on the nrfx CRACEN CTR_DRBG random driver. - Notes: This driver is only compatible with 54L devices, and may only be used from one processor + Notes: This driver is only compatible with 54L and 7120 devices, and may only be used from one processor core. This driver cannot be used in conjunction with the nRF security PSA solution, as both would attempt to use the CRACEN HW exclusively; When that is enabled, the PSA crypto entropy driver should be selected instead. diff --git a/drivers/wifi/nrf_wifi/Kconfig.nrfwifi b/drivers/wifi/nrf_wifi/Kconfig.nrfwifi index 5786f8cef145..c168d9596087 100644 --- a/drivers/wifi/nrf_wifi/Kconfig.nrfwifi +++ b/drivers/wifi/nrf_wifi/Kconfig.nrfwifi @@ -5,9 +5,6 @@ # SPDX-License-Identifier: Apache-2.0 # -# TODO: Use DTS generated Kconfig once the board support is added -DT_COMPAT_NORDIC_WIFI71 := nordic,nrf7120 - menuconfig WIFI_NRF70 bool "nRF70 driver" select NET_L2_WIFI_MGMT if NETWORKING @@ -20,7 +17,7 @@ menuconfig WIFI_NRF70 DT_HAS_NORDIC_NRF7002_SPI_ENABLED || DT_HAS_NORDIC_NRF7002_QSPI_ENABLED || \ DT_HAS_NORDIC_NRF7001_SPI_ENABLED || DT_HAS_NORDIC_NRF7001_QSPI_ENABLED || \ DT_HAS_NORDIC_NRF7000_SPI_ENABLED || DT_HAS_NORDIC_NRF7000_QSPI_ENABLED || \ - $(dt_compat_enabled,$(DT_COMPAT_NORDIC_WIFI71)) + $(dt_compat_enabled,$(DT_COMPAT_NORDIC_NRF71_WIFI)) help Nordic Wi-Fi Driver @@ -28,7 +25,7 @@ if WIFI_NRF70 # Hidden symbols for internal use config WIFI_NRF7002 bool - default y if DT_HAS_NORDIC_NRF7002_SPI_ENABLED || DT_HAS_NORDIC_NRF7002_QSPI_ENABLED || $(dt_compat_enabled,$(DT_COMPAT_NORDIC_WIFI71)) + default y if DT_HAS_NORDIC_NRF7002_SPI_ENABLED || DT_HAS_NORDIC_NRF7002_QSPI_ENABLED || $(dt_compat_enabled,$(DT_COMPAT_NORDIC_NRF71_WIFI)) config WIFI_NRF7001 bool diff --git a/dts/arm/nordic/nrf7120_enga_cpuapp.dtsi b/dts/arm/nordic/nrf7120_enga_cpuapp.dtsi new file mode 100644 index 000000000000..829836660cad --- /dev/null +++ b/dts/arm/nordic/nrf7120_enga_cpuapp.dtsi @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +cpu: &cpuapp {}; + +systick: &cpuapp_systick {}; + +nvic: &cpuapp_nvic {}; + +/delete-node/ &cpuflpr; +/delete-node/ &cpuflpr_clic; + +/ { + chosen { + zephyr,entropy = &psa_rng; + }; + + soc { + compatible = "simple-bus"; + interrupt-parent = <&cpuapp_nvic>; + ranges; + }; + + rng: rng { + status = "okay"; + compatible = "nordic,nrf-cracen-ctrdrbg"; + }; + + psa_rng: psa-rng { + compatible = "zephyr,psa-crypto-rng"; + status = "disabled"; + }; +}; + +&cpuflpr_vpr { + cpuapp_vevif_rx: mailbox@1 { + compatible = "nordic,nrf-vevif-event-rx"; + reg = <0x0 0x1000>; + status = "disabled"; + interrupts = <76 NRF_DEFAULT_IRQ_PRIORITY>; + #mbox-cells = <1>; + nordic,events = <1>; + nordic,events-mask = <0x00100000>; + }; + + cpuapp_vevif_tx: mailbox@0 { + compatible = "nordic,nrf-vevif-task-tx"; + reg = <0x0 0x1000>; + #mbox-cells = <1>; + nordic,tasks = <7>; + nordic,tasks-mask = <0x007f0000>; + status = "disabled"; + }; +}; + +&cpuapp_ppb { + compatible = "simple-bus"; + ranges; +}; + +&grtc { +#ifdef USE_NON_SECURE_ADDRESS_MAP + interrupts = <227 NRF_DEFAULT_IRQ_PRIORITY>, +#else + interrupts = <228 NRF_DEFAULT_IRQ_PRIORITY>, +#endif + /* Reserved for Zero Latency IRQs */ + <229 NRF_DEFAULT_IRQ_PRIORITY>; +}; + +&gpiote20 { +#ifdef USE_NON_SECURE_ADDRESS_MAP + interrupts = <218 NRF_DEFAULT_IRQ_PRIORITY>; +#else + interrupts = <219 NRF_DEFAULT_IRQ_PRIORITY>; +#endif +}; + +&gpiote30 { +#ifdef USE_NON_SECURE_ADDRESS_MAP + interrupts = <268 NRF_DEFAULT_IRQ_PRIORITY>; +#else + interrupts = <269 NRF_DEFAULT_IRQ_PRIORITY>; +#endif +}; + +&dppic00 { + status = "okay"; +}; + +&dppic10 { + status = "okay"; +}; + +&dppic20 { + status = "okay"; +}; + +&dppic30 { + status = "okay"; +}; + +&ppib00 { + status = "okay"; +}; + +&ppib01 { + status = "okay"; +}; + +&ppib10 { + status = "okay"; +}; + +&ppib11 { + status = "okay"; +}; + +&ppib20 { + status = "okay"; +}; + +&ppib21 { + status = "okay"; +}; + +&ppib22 { + status = "okay"; +}; + +&ppib30 { + status = "okay"; +}; + +&wifi_bellboard { + compatible = "nordic,nrf-bellboard-tx"; +}; + +&cpuapp_bellboard { + compatible = "nordic,nrf-bellboard-rx"; + interrupts = <120 NRF_DEFAULT_IRQ_PRIORITY>, + <121 NRF_DEFAULT_IRQ_PRIORITY>; + interrupt-names = "irq0", "irq1"; + nordic,interrupt-mapping = <0x0000000f 0>, <0x0000000f 1>; +}; diff --git a/dts/bindings/arm/nordic,nrf-pwr-antswc.yaml b/dts/bindings/arm/nordic,nrf-pwr-antswc.yaml new file mode 100644 index 000000000000..c861b0f62a40 --- /dev/null +++ b/dts/bindings/arm/nordic,nrf-pwr-antswc.yaml @@ -0,0 +1,20 @@ +# Copyright (c) 2025 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +description: | + + Nordic nRF family pwr-antswc (Powering Antenna Switch) + + Uses pwr-gpios to control the 1.8V supply for the antenna switch. This + pin is SoC specific and cannot be modified at a board level. + Relevant configuration is implemented in soc_early_init_hook(). + +compatible: "nordic,nrf-pwr-antswc" + +include: base.yaml + +properties: + pwr-gpios: + type: phandle-array + description: | + GPIO specifier that controls power to the antenna switch controller. diff --git a/dts/bindings/clock/nordic,nrf71-lfxo.yaml b/dts/bindings/clock/nordic,nrf71-lfxo.yaml new file mode 100644 index 000000000000..94a7814f29c8 --- /dev/null +++ b/dts/bindings/clock/nordic,nrf71-lfxo.yaml @@ -0,0 +1,56 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +description: Nordic nRF low-frequency crystal oscillator (nRF71 series) + +compatible: "nordic,nrf71-lfxo" + +include: fixed-clock.yaml + +properties: + clock-frequency: + const: 32768 + + load-capacitors: + type: string + enum: + - "internal" + - "external" + description: | + Type of load capacitors connected to the crystal. If not specified, + adjustments may still happen when the device trimming happens during + system initialization. + + load-capacitance-femtofarad: + type: int + enum: + - 0 + - 1000 + - 2000 + - 3000 + - 4000 + - 5000 + - 6000 + - 7000 + - 8000 + - 9000 + - 10000 + - 11000 + - 12000 + - 13000 + - 14000 + - 15000 + - 16000 + - 17000 + - 18000 + - 19000 + - 20000 + - 21000 + - 22000 + - 23000 + - 24000 + - 25000 + + description: | + Load capacitance in femtofarads. This property is only used when + load-capacitors is set to "internal". diff --git a/dts/bindings/wifi/nordic,nrf71-wifi.yaml b/dts/bindings/wifi/nordic,nrf71-wifi.yaml new file mode 100644 index 000000000000..41f5acd86d08 --- /dev/null +++ b/dts/bindings/wifi/nordic,nrf71-wifi.yaml @@ -0,0 +1,12 @@ +# Copyright (c) 2025 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +description: > + This is a representation of the Wi-Fi parts of the nRF71 Series Wi-Fi and + Bluetooth chip SoC. + +compatible: "nordic,nrf71-wifi" + +include: + - "wifi-tx-power-2g.yaml" + - "wifi-tx-power-5g.yaml" diff --git a/dts/riscv/nordic/nrf7120_enga_cpuflpr.dtsi b/dts/riscv/nordic/nrf7120_enga_cpuflpr.dtsi new file mode 100644 index 000000000000..2aec31f3a282 --- /dev/null +++ b/dts/riscv/nordic/nrf7120_enga_cpuflpr.dtsi @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +cpu: &cpuflpr {}; + +clic: &cpuflpr_clic {}; + +/delete-node/ &cpuapp; +/delete-node/ &cpuapp_ppb; +/delete-node/ &cpuapp_sram; +/delete-node/ &cpuapp_mram; + +&mram_controller { + cpuflpr_mram: mram@3e0000 { + compatible = "soc-nv-flash"; + reg = <0x3e0000 DT_SIZE_K(116)>; + erase-block-size = <4096>; + write-block-size = <4>; + }; +}; + +/ { + soc { + compatible = "simple-bus"; + interrupt-parent = <&cpuflpr_clic>; + ranges; + }; +}; + +&cpuflpr_vpr { + cpuflpr_vevif_tx: mailbox { + compatible = "nordic,nrf-vevif-event-tx"; + #mbox-cells = <1>; + nordic,events = <1>; + nordic,events-mask = <0x00100000>; + status = "disabled"; + }; +}; + +&cpuflpr_clic { + status = "okay"; +}; + +&wifi_bellboard { + compatible = "nordic,nrf-bellboard-rx"; + interrupts = <116 NRF_DEFAULT_IRQ_PRIORITY>, + <117 NRF_DEFAULT_IRQ_PRIORITY>, + <118 NRF_DEFAULT_IRQ_PRIORITY>, + <119 NRF_DEFAULT_IRQ_PRIORITY>; + interrupt-names = "irq0", "irq1", "irq2", "irq3"; + nordic,interrupt-mapping = <0x0000000f 0>, <0x0000000f 1>, + <0x0000000f 2>, <0x0000000f 3>; +}; + +&cpuapp_bellboard { + compatible = "nordic,nrf-bellboard-tx"; +}; + +&grtc { + interrupts = <226 NRF_DEFAULT_IRQ_PRIORITY>; +}; + +&gpiote20 { + interrupts = <218 NRF_DEFAULT_IRQ_PRIORITY>; +}; + +&gpiote30 { + interrupts = <268 NRF_DEFAULT_IRQ_PRIORITY>; +}; diff --git a/dts/vendor/nordic/nrf7120_cpuapp_ns_partition.dtsi b/dts/vendor/nordic/nrf7120_cpuapp_ns_partition.dtsi new file mode 100644 index 000000000000..f2bf6feec045 --- /dev/null +++ b/dts/vendor/nordic/nrf7120_cpuapp_ns_partition.dtsi @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + * + * Default memory partitioning for nRF7120 application CPU. + */ + +&cpuapp_mram { + /* + * Default NVM layout on NRF7120 Application MCU without BL2: + * This layout matches (by necessity) that in the TF-M repository: + * + * 0x0000_0000 Secure image primary (512 KB) + * 0x0008_0000 Protected Storage Area (16 KB) + * 0x0008_4000 Internal Trusted Storage Area (16 KB) + * 0x0008_8000 OTP / NV counters area (8 KB) + * 0x0008_A000 Non-secure image primary (844 KB) + * 0x0015_D000 Non-secure storage, used when built with NRF_NS_STORAGE=ON, + * otherwise unused (32 KB) + */ + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + /* This static layout needs to be the same with the upstream TF-M layout in the + * header flash_layout.h of the relevant platform. Any updates in the layout + * needs to happen both in the flash_layout.h and in this file at the same time. + */ + + slot0_partition: partition@0 { + label = "image-0"; + reg = <0x0000000 DT_SIZE_K(512)>; + }; + + tfm_ps_partition: partition@80000 { + label = "tfm-ps"; + reg = <0x00080000 DT_SIZE_K(16)>; + }; + + tfm_its_partition: partition@84000 { + label = "tfm-its"; + reg = <0x00084000 DT_SIZE_K(16)>; + }; + + tfm_otp_partition: partition@88000 { + label = "tfm-otp"; + reg = <0x00088000 DT_SIZE_K(8)>; + }; + + slot0_ns_partition: partition@8A000 { + label = "image-0-nonsecure"; + reg = <0x0008A000 DT_SIZE_K(844)>; + }; + + storage_partition: partition@15D000 { + label = "storage"; + reg = <0x00015D000 DT_SIZE_K(32)>; + }; + }; +}; diff --git a/dts/vendor/nordic/nrf7120_cpuapp_partition.dtsi b/dts/vendor/nordic/nrf7120_cpuapp_partition.dtsi new file mode 100644 index 000000000000..a508d3760381 --- /dev/null +++ b/dts/vendor/nordic/nrf7120_cpuapp_partition.dtsi @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + * + * Default memory partitioning for nRF7120 application CPU. + */ + +&cpuapp_mram { + reg = <0x0 DT_SIZE_K(4084)>; +}; + +/* These partition sizes assume no FLPR area in MRAM */ +&cpuapp_mram { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 DT_SIZE_K(64)>; + }; + + slot0_partition: partition@10000 { + label = "image-0"; + reg = <0x00010000 DT_SIZE_K(1992)>; + }; + + slot1_partition: partition@202000 { + label = "image-1"; + reg = <0x00202000 DT_SIZE_K(1992)>; + }; + + storage_partition: partition@3f4000 { + label = "storage"; + reg = <0x003f4000 DT_SIZE_K(36)>; + }; + }; +}; diff --git a/dts/vendor/nordic/nrf7120_enga.dtsi b/dts/vendor/nordic/nrf7120_enga.dtsi new file mode 100644 index 000000000000..9f310aa00619 --- /dev/null +++ b/dts/vendor/nordic/nrf7120_enga.dtsi @@ -0,0 +1,960 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +/delete-node/ &sw_pwm; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpuapp: cpu@0 { + compatible = "arm,cortex-m33f"; + reg = <0>; + device_type = "cpu"; + clock-frequency = ; + #address-cells = <1>; + #size-cells = <1>; + + itm: itm@e0000000 { + compatible = "arm,armv8m-itm"; + reg = <0xe0000000 0x1000>; + swo-ref-frequency = ; + }; + }; + + cpuflpr: cpu@1 { + compatible = "nordic,vpr"; + reg = <1>; + device_type = "cpu"; + clock-frequency = ; + riscv,isa = "rv32emc"; + nordic,bus-width = <32>; + }; + }; + + clocks { + pclk: pclk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = ; + }; + + pclk32m: pclk32m { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = ; + }; + + lfxo: lfxo { + compatible = "nordic,nrf71-lfxo"; + #clock-cells = <0>; + clock-frequency = <32768>; + }; + + hfxo64m: hfxo64m { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = ; + }; + + hfpll: hfpll { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = ; + }; + }; + + reserved-memory { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + nordic_reserved: memory@200fe000 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "mmio-sram"; + reg = <0x200fe000 0x1000>; + ranges = <0x0 0x200fe000 0x1000>; + }; + + nrf_kmu_cracen_exchange_area: memory@200ff000 { + #address-cells = <1>; + #size-cells = <1>; + reg = <0x200ff000 0x1000>; + compatible = "zephyr,memory-region", "mmio-sram"; + zephyr,memory-region = "NRF_KMU_CRACEN_EXCHANGE"; + }; + + nrf_mpc_region: memory@50041000 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "nordic,nrf-mpc"; + reg = <0x50041000 0x1000>; + override-num = <14>; + override-granularity = <4096>; + }; + }; + + pwr_antswc: pwr_antswc { + compatible = "nordic,nrf-pwr-antswc"; + /* + * Hardwired to P0.09 in nRF7120. If pwr_antswc is enabled, ensure + * P0.09 is available and not used by other enabled peripherals. + */ + pwr-gpios = <&gpio0 9 GPIO_ACTIVE_HIGH>; + status = "disabled"; + }; + + soc { + #address-cells = <1>; + #size-cells = <1>; + + ficr: ficr@ffc000 { + compatible = "nordic,nrf-ficr"; + reg = <0xffc000 0x1000>; + #nordic,ficr-cells = <1>; + }; + +#ifdef USE_NON_SECURE_ADDRESS_MAP + /* Intentionally empty because uicr is hardware fixed to Secure */ +#else + uicr: uicr@ffd000 { + compatible = "nordic,nrf-uicr"; + reg = <0xffd000 0x1000>; + status = "disabled"; + }; +#endif + + cpuapp_sram: memory@20000000 { + compatible = "mmio-sram"; + reg = <0x20000000 DT_SIZE_K(512)>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x20000000 0x80000>; + }; + + ram01_sram: memory@20080000 { + compatible = "mmio-sram"; + reg = <0x20080000 DT_SIZE_K(256)>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x20080000 0x40000>; + }; + + ram02_sram: memory@200c0000 { + compatible = "mmio-sram"; + reg = <0x200c0000 DT_SIZE_K(128)>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x200c0000 0x20000>; + }; + + ram03_sram: memory@200e0000 { + compatible = "mmio-sram"; + reg = <0x200e0000 DT_SIZE_K(120)>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x200e0000 0x1e000>; + }; + +#ifdef USE_NON_SECURE_ADDRESS_MAP + global_peripherals: peripheral@40000000 { + reg = <0x40000000 0x10000000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x40000000 0x10000000>; +#else + global_peripherals: peripheral@50000000 { + reg = <0x50000000 0x10000000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x50000000 0x10000000>; + #include "nrf7120_enga_secure_peripherals.dtsi" +#endif + + dppic00: dppic@42000 { + compatible = "nordic,nrf-dppic"; + reg = <0x42000 0x1000>; + status = "disabled"; + }; + + ppib00: ppib@44000 { + compatible = "nordic,nrf-ppib"; + reg = <0x44000 0x1000>; + status = "disabled"; + }; + + ppib01: ppib@45000 { + compatible = "nordic,nrf-ppib"; + reg = <0x45000 0x1000>; + status = "disabled"; + }; + + ccm00: ccm@4a000 { + compatible = "nordic,nrf-ccm"; + reg = <0x4a000 0x1000>; + interrupts = <74 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; + }; + + ecb00: ecb@4b000 { + compatible = "nordic,nrf-ecb"; + reg = <0x4b000 0x1000>; + interrupts = <75 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; + }; + + cpuflpr_vpr: vpr@4c000 { + compatible = "nordic,nrf-vpr-coprocessor"; + reg = <0x4c000 0x1000>; + ranges = <0x0 0x4c000 0x1000>; + #address-cells = <1>; + #size-cells = <1>; + status = "disabled"; + enable-secure; + enable-dma-secure; + + cpuflpr_clic: interrupt-controller@f0000000 { + compatible = "nordic,nrf-clic"; + reg = <0xf0000000 0x1780>; + interrupt-controller; + #interrupt-cells = <2>; + #address-cells = <1>; + status = "disabled"; + }; + }; + + spi00: spi@4d000 { + compatible = "nordic,nrf-spim"; + reg = <0x4d000 0x1000>; + interrupts = <77 NRF_DEFAULT_IRQ_PRIORITY>; + #address-cells = <1>; + #size-cells = <0>; + max-frequency = ; + easydma-maxcnt-bits = <16>; + rx-delay-supported; + rx-delay = <1>; + status = "disabled"; + }; + + uart00: uart@4d000 { + compatible = "nordic,nrf-uarte"; + reg = <0x4d000 0x1000>; + interrupts = <77 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; + endtx-stoptx-supported; + frame-timeout-supported; + }; + + gpio2: gpio@50400 { + compatible = "nordic,nrf-gpio"; + reg = <0x50400 0x200>; + gpio-controller; + #gpio-cells = <2>; + port = <2>; + ngpios = <12>; + status = "disabled"; + }; + + ctrlap: ctrlap@52000 { + compatible = "nordic,nrf-ctrlapperi"; + reg = <0x52000 0x1000>; + interrupts = <82 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; + }; + + timer00: timer@55000 { + compatible = "nordic,nrf-timer"; + reg = <0x55000 0x1000>; + interrupts = <85 NRF_DEFAULT_IRQ_PRIORITY>; + clocks = <&hfpll>; + cc-num = <6>; + max-bit-width = <32>; + prescaler = <0>; + status = "disabled"; + }; + + egu00: egu@58000 { + compatible = "nordic,nrf-egu"; + reg = <0x58000 0x1000>; + interrupts = <88 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; + }; + + qspi00: qspi@5b000 { + compatible = "nordic,nrf-qspi-v2", "snps,designware-ssi"; + interrupts = <91 NRF_DEFAULT_IRQ_PRIORITY>; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x5b000 0x900 0x5b900 0x700>; + reg-names = "wrapper", "core"; + clock-frequency = ; + fifo-depth = <16>; + packet-data-limit = <65536>; + dma-transmit-data-level = <8>; + dma-receive-data-level = <8>; + status = "disabled"; + }; + + qspi01: qspi@5c000 { + compatible = "nordic,nrf-qspi-v2", "snps,designware-ssi"; + interrupts = <92 NRF_DEFAULT_IRQ_PRIORITY>; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x5c000 0x900 0x5c900 0x700>; + reg-names = "wrapper", "core"; + clock-frequency = ; + fifo-depth = <16>; + packet-data-limit = <65536>; + dma-transmit-data-level = <8>; + dma-receive-data-level = <8>; + status = "disabled"; + }; + + spi01: spi@5d000 { + compatible = "nordic,nrf-spim"; + reg = <0x5d000 0x1000>; + interrupts = <93 NRF_DEFAULT_IRQ_PRIORITY>; + #address-cells = <1>; + #size-cells = <0>; + max-frequency = ; + easydma-maxcnt-bits = <16>; + rx-delay-supported; + rx-delay = <1>; + status = "disabled"; + }; + + dppic10: dppic@82000 { + compatible = "nordic,nrf-dppic"; + reg = <0x82000 0x1000>; + status = "disabled"; + }; + + ppib10: ppib@83000 { + compatible = "nordic,nrf-ppib"; + reg = <0x83000 0x1000>; + status = "disabled"; + }; + + ppib11: ppib@84000 { + compatible = "nordic,nrf-ppib"; + reg = <0x84000 0x1000>; + status = "disabled"; + }; + + timer10: timer@85000 { + compatible = "nordic,nrf-timer"; + reg = <0x85000 0x1000>; + interrupts = <133 NRF_DEFAULT_IRQ_PRIORITY>; + clocks = <&pclk32m>; + cc-num = <8>; + max-bit-width = <32>; + prescaler = <0>; + status = "disabled"; + }; + + egu10: egu@87000 { + compatible = "nordic,nrf-egu"; + reg = <0x87000 0x1000>; + interrupts = <135 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; + }; + + radio: radio@8a000 { + compatible = "nordic,nrf-radio"; + reg = <0x8a000 0x2000>; + interrupts = <138 NRF_DEFAULT_IRQ_PRIORITY>; + dfe-supported; + ieee802154-supported; + ble-2mbps-supported; + ble-coded-phy-supported; + status = "disabled"; + + ieee802154: ieee802154 { + compatible = "nordic,nrf-ieee802154"; + status = "disabled"; + }; + + bt_hci_sdc: bt_hci_sdc { + compatible = "nordic,bt-hci-sdc"; + status = "disabled"; + }; + + bt_hci_controller: bt_hci_controller { + compatible = "zephyr,bt-hci-ll-sw-split"; + status = "disabled"; + }; + }; + + ipct10: ipct@8d000 { + compatible = "nordic,nrf-ipct-global"; + reg = <0x8d000 0x1000>; + interrupts = <141 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; + }; + + dppic20: dppic@c2000 { + compatible = "nordic,nrf-dppic"; + reg = <0xc2000 0x1000>; + status = "disabled"; + }; + + ppib20: ppib@c3000 { + compatible = "nordic,nrf-ppib"; + reg = <0xc3000 0x1000>; + status = "disabled"; + }; + + ppib21: ppib@c4000 { + compatible = "nordic,nrf-ppib"; + reg = <0xc4000 0x1000>; + status = "disabled"; + }; + + ppib22: ppib@c5000 { + compatible = "nordic,nrf-ppib"; + reg = <0xc5000 0x1000>; + status = "disabled"; + }; + + spi20: spi@c6000 { + compatible = "nordic,nrf-spim"; + reg = <0xc6000 0x1000>; + interrupts = <198 NRF_DEFAULT_IRQ_PRIORITY>; + #address-cells = <1>; + #size-cells = <0>; + max-frequency = ; + easydma-maxcnt-bits = <16>; + rx-delay-supported; + rx-delay = <1>; + status = "disabled"; + }; + + i2c20: i2c@c6000 { + compatible = "nordic,nrf-twim"; + reg = <0xc6000 0x1000>; + interrupts = <198 NRF_DEFAULT_IRQ_PRIORITY>; + #address-cells = <1>; + #size-cells = <0>; + clock-frequency = ; + easydma-maxcnt-bits = <16>; + status = "disabled"; + }; + + uart20: uart@c6000 { + compatible = "nordic,nrf-uarte"; + reg = <0xc6000 0x1000>; + interrupts = <198 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; + endtx-stoptx-supported; + frame-timeout-supported; + }; + + spi21: spi@c7000 { + compatible = "nordic,nrf-spim"; + reg = <0xc7000 0x1000>; + interrupts = <199 NRF_DEFAULT_IRQ_PRIORITY>; + #address-cells = <1>; + #size-cells = <0>; + max-frequency = ; + easydma-maxcnt-bits = <16>; + rx-delay-supported; + rx-delay = <1>; + status = "disabled"; + }; + + i2c21: i2c@c7000 { + compatible = "nordic,nrf-twim"; + reg = <0xc7000 0x1000>; + interrupts = <199 NRF_DEFAULT_IRQ_PRIORITY>; + #address-cells = <1>; + #size-cells = <0>; + clock-frequency = ; + easydma-maxcnt-bits = <16>; + status = "disabled"; + }; + + uart21: uart@c7000 { + compatible = "nordic,nrf-uarte"; + reg = <0xc7000 0x1000>; + interrupts = <199 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; + endtx-stoptx-supported; + frame-timeout-supported; + }; + + spi22: spi@c8000 { + compatible = "nordic,nrf-spim"; + reg = <0xc8000 0x1000>; + interrupts = <200 NRF_DEFAULT_IRQ_PRIORITY>; + #address-cells = <1>; + #size-cells = <0>; + max-frequency = ; + easydma-maxcnt-bits = <16>; + rx-delay-supported; + rx-delay = <1>; + status = "disabled"; + }; + + i2c22: i2c@c8000 { + compatible = "nordic,nrf-twim"; + reg = <0xc8000 0x1000>; + interrupts = <200 NRF_DEFAULT_IRQ_PRIORITY>; + #address-cells = <1>; + #size-cells = <0>; + clock-frequency = ; + easydma-maxcnt-bits = <16>; + status = "disabled"; + }; + + uart22: uart@c8000 { + compatible = "nordic,nrf-uarte"; + reg = <0xc8000 0x1000>; + interrupts = <200 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; + endtx-stoptx-supported; + frame-timeout-supported; + }; + + egu20: egu@c9000 { + compatible = "nordic,nrf-egu"; + reg = <0xc9000 0x1000>; + interrupts = <201 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; + }; + + timer20: timer@ca000 { + compatible = "nordic,nrf-timer"; + reg = <0xca000 0x1000>; + interrupts = <202 NRF_DEFAULT_IRQ_PRIORITY>; + cc-num = <6>; + max-bit-width = <32>; + prescaler = <0>; + status = "disabled"; + }; + + timer21: timer@cb000 { + compatible = "nordic,nrf-timer"; + reg = <0xcb000 0x1000>; + interrupts = <203 NRF_DEFAULT_IRQ_PRIORITY>; + cc-num = <6>; + max-bit-width = <32>; + prescaler = <0>; + status = "disabled"; + }; + + timer22: timer@cc000 { + compatible = "nordic,nrf-timer"; + reg = <0xcc000 0x1000>; + interrupts = <204 NRF_DEFAULT_IRQ_PRIORITY>; + cc-num = <6>; + max-bit-width = <32>; + prescaler = <0>; + status = "disabled"; + }; + + timer23: timer@cd000 { + compatible = "nordic,nrf-timer"; + reg = <0xcd000 0x1000>; + interrupts = <205 NRF_DEFAULT_IRQ_PRIORITY>; + cc-num = <6>; + max-bit-width = <32>; + prescaler = <0>; + status = "disabled"; + }; + + timer24: timer@ce000 { + compatible = "nordic,nrf-timer"; + reg = <0xce000 0x1000>; + interrupts = <206 NRF_DEFAULT_IRQ_PRIORITY>; + cc-num = <6>; + max-bit-width = <32>; + prescaler = <0>; + status = "disabled"; + }; + + pdm20: pdm@d0000 { + compatible = "nordic,nrf-pdm"; + reg = <0xd0000 0x1000>; + interrupts = <208 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; + }; + + pdm21: pdm@d1000 { + compatible = "nordic,nrf-pdm"; + reg = <0xd1000 0x1000>; + interrupts = <209 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; + }; + + pwm20: pwm@d2000 { + compatible = "nordic,nrf-pwm"; + reg = <0xd2000 0x1000>; + interrupts = <210 NRF_DEFAULT_IRQ_PRIORITY>; + #pwm-cells = <3>; + status = "disabled"; + idleout-supported; + }; + + pwm21: pwm@d3000 { + compatible = "nordic,nrf-pwm"; + reg = <0xd3000 0x1000>; + interrupts = <211 NRF_DEFAULT_IRQ_PRIORITY>; + #pwm-cells = <3>; + status = "disabled"; + idleout-supported; + }; + + pwm22: pwm@d4000 { + compatible = "nordic,nrf-pwm"; + reg = <0xd4000 0x1000>; + interrupts = <212 NRF_DEFAULT_IRQ_PRIORITY>; + #pwm-cells = <3>; + status = "disabled"; + idleout-supported; + }; + + adc: adc@d5000 { + compatible = "nordic,nrf-saadc"; + reg = <0xd5000 0x1000>; + interrupts = <213 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; + #io-channel-cells = <1>; + }; + + nfct: nfct@d6000 { + compatible = "nordic,nrf-nfct"; + reg = <0xd6000 0x1000>; + interrupts = <214 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; + }; + + temp: temp@d7000 { + compatible = "nordic,nrf-temp"; + reg = <0xd7000 0x1000>; + interrupts = <215 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; + }; + + gpio1: gpio@d8200 { + compatible = "nordic,nrf-gpio"; + reg = <0xd8200 0x200>; + gpio-controller; + #gpio-cells = <2>; + port = <1>; + ngpios = <16>; + gpiote-instance = <&gpiote20>; + status = "disabled"; + }; + + gpio3: gpio@d8600 { + compatible = "nordic,nrf-gpio"; + reg = <0xd8600 0x200>; + gpio-controller; + #gpio-cells = <2>; + port = <3>; + ngpios = <12>; + gpiote-instance = <&gpiote20>; + status = "disabled"; + }; + + gpio4: gpio@d8800 { + compatible = "nordic,nrf-gpio"; + reg = <0xd8800 0x200>; + gpio-controller; + #gpio-cells = <2>; + port = <4>; + ngpios = <12>; + status = "disabled"; + }; + + gpiote20: gpiote@da000 { + compatible = "nordic,nrf-gpiote"; + reg = <0xda000 0x1000>; + instance = <20>; + status = "disabled"; + }; + + qdec20: qdec@e0000 { + compatible = "nordic,nrf-qdec"; + reg = <0xe0000 0x1000>; + interrupts = <224 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; + }; + + qdec21: qdec@e1000 { + compatible = "nordic,nrf-qdec"; + reg = <0xe1000 0x1000>; + interrupts = <225 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; + }; + + grtc: grtc@e2000 { + compatible = "nordic,nrf-grtc"; + reg = <0xe2000 0x1000>; + cc-num = <16>; + clocks = <&lfxo>, <&pclk>; + clock-names = "lfclock", "hfclock"; + status = "disabled"; + }; + + tdm: tdm@e8000 { + compatible = "nordic,nrf-tdm"; + easydma-maxcnt-bits = <15>; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xe8000 0x1000>; + interrupts = <232 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; + clocks = <&pclk32m>; + }; + + spi23: spi@ed000 { + compatible = "nordic,nrf-spim"; + reg = <0xed000 0x1000>; + interrupts = <237 NRF_DEFAULT_IRQ_PRIORITY>; + #address-cells = <1>; + #size-cells = <0>; + max-frequency = ; + easydma-maxcnt-bits = <16>; + rx-delay-supported; + rx-delay = <1>; + status = "disabled"; + }; + + i2c23: i2c@ed000 { + compatible = "nordic,nrf-twim"; + reg = <0xed000 0x1000>; + interrupts = <237 NRF_DEFAULT_IRQ_PRIORITY>; + #address-cells = <1>; + #size-cells = <0>; + clock-frequency = ; + easydma-maxcnt-bits = <16>; + status = "disabled"; + }; + + uart23: uart@ed000 { + compatible = "nordic,nrf-uarte"; + reg = <0xed000 0x1000>; + interrupts = <237 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; + endtx-stoptx-supported; + frame-timeout-supported; + }; + + spi24: spi@ee000 { + compatible = "nordic,nrf-spim"; + reg = <0xee000 0x1000>; + interrupts = <238 NRF_DEFAULT_IRQ_PRIORITY>; + #address-cells = <1>; + #size-cells = <0>; + max-frequency = ; + easydma-maxcnt-bits = <16>; + rx-delay-supported; + rx-delay = <1>; + status = "disabled"; + }; + + i2c24: i2c@ee000 { + compatible = "nordic,nrf-twim"; + reg = <0xee000 0x1000>; + interrupts = <238 NRF_DEFAULT_IRQ_PRIORITY>; + #address-cells = <1>; + #size-cells = <0>; + clock-frequency = ; + easydma-maxcnt-bits = <16>; + status = "disabled"; + }; + + uart24: uart@ee000 { + compatible = "nordic,nrf-uarte"; + reg = <0xee000 0x1000>; + interrupts = <238 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; + endtx-stoptx-supported; + frame-timeout-supported; + }; + + dppic30: dppic@102000 { + compatible = "nordic,nrf-dppic"; + reg = <0x102000 0x1000>; + status = "disabled"; + }; + + ppib30: ppib@103000 { + compatible = "nordic,nrf-ppib"; + reg = <0x103000 0x1000>; + status = "disabled"; + }; + + spi30: spi@104000 { + compatible = "nordic,nrf-spim"; + reg = <0x104000 0x1000>; + interrupts = <260 NRF_DEFAULT_IRQ_PRIORITY>; + #address-cells = <1>; + #size-cells = <0>; + max-frequency = ; + easydma-maxcnt-bits = <16>; + rx-delay-supported; + rx-delay = <1>; + status = "disabled"; + }; + + i2c30: i2c@104000 { + compatible = "nordic,nrf-twim"; + reg = <0x104000 0x1000>; + interrupts = <260 NRF_DEFAULT_IRQ_PRIORITY>; + #address-cells = <1>; + #size-cells = <0>; + clock-frequency = ; + easydma-maxcnt-bits = <16>; + status = "disabled"; + }; + + uart30: uart@104000 { + compatible = "nordic,nrf-uarte"; + reg = <0x104000 0x1000>; + interrupts = <260 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; + endtx-stoptx-supported; + frame-timeout-supported; + }; + + comp: comp@106000 { + compatible = "nordic,nrf-comp"; + reg = <0x106000 0x1000>; + interrupts = <262 NRF_DEFAULT_IRQ_PRIORITY>; + #io-channels-cells = <1>; + status = "disabled"; + }; + + wdt31: wdt@109000 { + compatible = "nordic,nrf-wdt"; + reg = <0x109000 0x1000>; + interrupts = <265 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; + }; + + gpio0: gpio@10a000 { + compatible = "nordic,nrf-gpio"; + reg = <0x10a000 0x200>; + gpio-controller; + #gpio-cells = <2>; + port = <0>; + ngpios = <13>; + gpiote-instance = <&gpiote30>; + status = "disabled"; + }; + + gpiote30: gpiote@10c000 { + compatible = "nordic,nrf-gpiote"; + reg = <0x10c000 0x1000>; + instance = <30>; + status = "disabled"; + }; + + clock: clock@10e000 { + compatible = "nordic,nrf-clock"; + reg = <0x10e000 0x1000>; + interrupts = <270 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; + }; + + audio_auxpll: auxpll@130000 { + compatible = "nordic,nrf-auxpll"; + reg = <0x130000 0x1000>; + interrupts = <304 NRF_DEFAULT_IRQ_PRIORITY>; + clocks = <&pclk32m>; + #clock-cells = <0>; + /* + * Temporarily reading FICR addr 0 as FICR offsets + * not defined yet + */ + nordic,ficrs = <&ficr 0>; + nordic,out-div = ; + nordic,out-drive = <0>; + nordic,current-tune = <9>; + nordic,sdm-disable; + nordic,range = "mid"; + status = "disabled"; + }; + + cpuapp_ppb: cpuapp-ppb-bus { + #address-cells = <1>; + #size-cells = <1>; + + cpuapp_systick: timer@e000e010 { + compatible = "arm,armv8m-systick"; + reg = <0xe000e010 0x10>; + status = "disabled"; + }; + + cpuapp_nvic: interrupt-controller@e000e100 { + #address-cells = <1>; + compatible = "arm,v8m-nvic"; + reg = <0xe000e100 0xc00>; + arm,num-irq-priority-bits = <3>; + interrupt-controller; + #interrupt-cells = <2>; + }; + }; + }; + + wifi_bellboard: mailbox@40074000 { + reg = <0x40074000 0x1000>; + status = "disabled"; + #mbox-cells = <1>; + }; + + cpuapp_bellboard: mailbox@40078000 { + reg = <0x40078000 0x1000>; + status = "disabled"; + #mbox-cells = <1>; + }; + + mram_controller: mram-controller@5004e000 { + compatible = "nordic,nrf-mramc"; + reg = <0x5004e000 0x1000>; + #address-cells = <1>; + #size-cells = <1>; + interrupts = <78 NRF_DEFAULT_IRQ_PRIORITY>; + + cpuapp_mram: mram@0 { + compatible = "soc-nv-flash"; + reg = <0 DT_SIZE_K(4084)>; + erase-block-size = <4096>; + write-block-size = <4>; + }; + }; + }; + + wifi: wifi { + compatible = "nordic,nrf7120-wifi"; + status = "disabled"; + + wifi-max-tx-pwr-2g-dsss = <21>; + wifi-max-tx-pwr-2g-mcs0 = <16>; + wifi-max-tx-pwr-2g-mcs7 = <16>; + wifi-max-tx-pwr-5g-low-mcs0 = <13>; + wifi-max-tx-pwr-5g-low-mcs7 = <13>; + wifi-max-tx-pwr-5g-mid-mcs0 = <13>; + wifi-max-tx-pwr-5g-mid-mcs7 = <13>; + wifi-max-tx-pwr-5g-high-mcs0 = <12>; + wifi-max-tx-pwr-5g-high-mcs7 = <12>; + + wlan0: wlan0 { + compatible = "nordic,wlan"; + }; + }; +}; diff --git a/dts/vendor/nordic/nrf7120_enga_secure_peripherals.dtsi b/dts/vendor/nordic/nrf7120_enga_secure_peripherals.dtsi new file mode 100644 index 000000000000..58c6abe21099 --- /dev/null +++ b/dts/vendor/nordic/nrf7120_enga_secure_peripherals.dtsi @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * This file contains peripherals that are secure only in nRF7120 + */ + +spu00: spu@40000 { + compatible = "nordic,nrf-spu"; + reg = <0x40000 0x1000>; + interrupts = <64 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; +}; + +kmu: kmu@49000 { + compatible = "nordic,nrf-kmu"; + reg = <0x49000 0x1000>; + status = "disabled"; +}; + +spu10: spu@80000 { + compatible = "nordic,nrf-spu"; + reg = <0x80000 0x1000>; + interrupts = <128 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; +}; + +spu20: spu@c0000 { + compatible = "nordic,nrf-spu"; + reg = <0xc0000 0x1000>; + interrupts = <192 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; +}; + +spu30: spu@100000 { + compatible = "nordic,nrf-spu"; + reg = <0x100000 0x1000>; + interrupts = <256 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; +}; + +wdt30: wdt@108000 { + compatible = "nordic,nrf-wdt"; + reg = <0x108000 0x1000>; + interrupts = <264 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; +}; diff --git a/modules/nrf_wifi/bus/Kconfig b/modules/nrf_wifi/bus/Kconfig index d9ef9553078c..1fab99da46ff 100644 --- a/modules/nrf_wifi/bus/Kconfig +++ b/modules/nrf_wifi/bus/Kconfig @@ -4,9 +4,6 @@ # SPDX-License-Identifier: Apache-2.0 # -# TODO: Use DTS generated Kconfig once the board support is added -DT_COMPAT_NORDIC_WIFI71 := nordic,nrf7120 - menuconfig NRF70_BUSLIB bool "NRF70 Bus Library" help @@ -27,7 +24,7 @@ config NRF70_ON_SPI select SPI config NRF71_ON_IPC - def_bool $(dt_compat_enabled,$(DT_COMPAT_NORDIC_WIFI71)) + def_bool $(dt_compat_enabled,$(DT_COMPAT_NORDIC_NRF71_WIFI)) select MBOX select IPC_SERVICE select SPSC_PBUF From a0ac5b0e2238b316460b11558065b77c529da51d Mon Sep 17 00:00:00 2001 From: Robert Robinson Date: Wed, 10 Dec 2025 15:05:19 +0000 Subject: [PATCH 1770/3659] boards: Add Nordic nrf7120dk_nrf7120 board support Add all board files for nRF7120dk Signed-off-by: Robert Robinson --- boards/nordic/nrf7120dk/Kconfig.defconfig | 36 ++++ boards/nordic/nrf7120dk/Kconfig.nrf7120dk | 7 + boards/nordic/nrf7120dk/board.cmake | 20 ++ boards/nordic/nrf7120dk/board.yml | 11 ++ boards/nordic/nrf7120dk/doc/index.rst | 87 +++++++++ .../nrf7120dk/nrf7120_cpuapp_common.dtsi | 174 ++++++++++++++++++ .../nrf7120dk/nrf7120dk_nrf7120-common.dtsi | 126 +++++++++++++ .../nrf7120dk/nrf7120dk_nrf7120-pinctrl.dtsi | 129 +++++++++++++ .../nrf7120dk/nrf7120dk_nrf7120_cpuapp.dts | 21 +++ .../nrf7120dk/nrf7120dk_nrf7120_cpuapp.yaml | 24 +++ .../nrf7120dk_nrf7120_cpuapp_defconfig | 25 +++ .../nrf7120dk/nrf7120dk_nrf7120_cpuapp_ns.dts | 28 +++ .../nrf7120dk_nrf7120_cpuapp_ns.yaml | 22 +++ .../nrf7120dk_nrf7120_cpuapp_ns_defconfig | 37 ++++ .../nrf7120dk/nrf7120dk_nrf7120_cpuflpr.dts | 80 ++++++++ .../nrf7120dk/nrf7120dk_nrf7120_cpuflpr.yaml | 17 ++ .../nrf7120dk_nrf7120_cpuflpr_defconfig | 17 ++ .../nrf7120dk_nrf7120_cpuflpr_xip.dts | 7 + .../nrf7120dk_nrf7120_cpuflpr_xip.yaml | 17 ++ .../nrf7120dk_nrf7120_cpuflpr_xip_defconfig | 15 ++ 20 files changed, 900 insertions(+) create mode 100644 boards/nordic/nrf7120dk/Kconfig.defconfig create mode 100644 boards/nordic/nrf7120dk/Kconfig.nrf7120dk create mode 100644 boards/nordic/nrf7120dk/board.cmake create mode 100644 boards/nordic/nrf7120dk/board.yml create mode 100644 boards/nordic/nrf7120dk/doc/index.rst create mode 100644 boards/nordic/nrf7120dk/nrf7120_cpuapp_common.dtsi create mode 100644 boards/nordic/nrf7120dk/nrf7120dk_nrf7120-common.dtsi create mode 100644 boards/nordic/nrf7120dk/nrf7120dk_nrf7120-pinctrl.dtsi create mode 100644 boards/nordic/nrf7120dk/nrf7120dk_nrf7120_cpuapp.dts create mode 100644 boards/nordic/nrf7120dk/nrf7120dk_nrf7120_cpuapp.yaml create mode 100644 boards/nordic/nrf7120dk/nrf7120dk_nrf7120_cpuapp_defconfig create mode 100644 boards/nordic/nrf7120dk/nrf7120dk_nrf7120_cpuapp_ns.dts create mode 100644 boards/nordic/nrf7120dk/nrf7120dk_nrf7120_cpuapp_ns.yaml create mode 100644 boards/nordic/nrf7120dk/nrf7120dk_nrf7120_cpuapp_ns_defconfig create mode 100644 boards/nordic/nrf7120dk/nrf7120dk_nrf7120_cpuflpr.dts create mode 100644 boards/nordic/nrf7120dk/nrf7120dk_nrf7120_cpuflpr.yaml create mode 100644 boards/nordic/nrf7120dk/nrf7120dk_nrf7120_cpuflpr_defconfig create mode 100644 boards/nordic/nrf7120dk/nrf7120dk_nrf7120_cpuflpr_xip.dts create mode 100644 boards/nordic/nrf7120dk/nrf7120dk_nrf7120_cpuflpr_xip.yaml create mode 100644 boards/nordic/nrf7120dk/nrf7120dk_nrf7120_cpuflpr_xip_defconfig diff --git a/boards/nordic/nrf7120dk/Kconfig.defconfig b/boards/nordic/nrf7120dk/Kconfig.defconfig new file mode 100644 index 000000000000..cfd142f10b5e --- /dev/null +++ b/boards/nordic/nrf7120dk/Kconfig.defconfig @@ -0,0 +1,36 @@ +# Copyright (c) 2025 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config HW_STACK_PROTECTION + default ARCH_HAS_STACK_PROTECTION + +if BOARD_NRF7120DK_NRF7120_CPUAPP + +config HAS_BT_CTLR + default BT + +config ROM_START_OFFSET + default 0x800 if BOOTLOADER_MCUBOOT + +endif # BOARD_NRF7120DK_NRF7120_CPUAPP + +if BOARD_NRF7120DK_NRF7120_CPUAPP_NS + +config BOARD_NRF7120DK + select USE_DT_CODE_PARTITION + +config HAS_BT_CTLR + default BT + +# By default, if we build for a Non-Secure version of the board, +# enable building with TF-M as the Secure Execution Environment. +config BUILD_WITH_TFM + default y + +# By default, if we build with TF-M, instruct build system to +# flash the combined TF-M (Secure) & Zephyr (Non Secure) image +config TFM_FLASH_MERGED_BINARY + default y + depends on BUILD_WITH_TFM + +endif # BOARD_NRF7120DK_NRF7120_CPUAPP_NS diff --git a/boards/nordic/nrf7120dk/Kconfig.nrf7120dk b/boards/nordic/nrf7120dk/Kconfig.nrf7120dk new file mode 100644 index 000000000000..37223f60bcd4 --- /dev/null +++ b/boards/nordic/nrf7120dk/Kconfig.nrf7120dk @@ -0,0 +1,7 @@ +# Copyright (c) 2025 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 +config BOARD_NRF7120DK + select SOC_NRF7120_ENGA_CPUAPP if BOARD_NRF7120DK_NRF7120_CPUAPP || \ + BOARD_NRF7120DK_NRF7120_CPUAPP_NS + select SOC_NRF7120_ENGA_CPUFLPR if BOARD_NRF7120DK_NRF7120_CPUFLPR || \ + BOARD_NRF7120DK_NRF7120_CPUFLPR_XIP diff --git a/boards/nordic/nrf7120dk/board.cmake b/boards/nordic/nrf7120dk/board.cmake new file mode 100644 index 000000000000..5756f8c462ac --- /dev/null +++ b/boards/nordic/nrf7120dk/board.cmake @@ -0,0 +1,20 @@ +# Copyright (c) 2025 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if(CONFIG_SOC_NRF7120_ENGA_CPUAPP) + board_runner_args(jlink "--device=cortex-m33" "--speed=4000") +elseif(CONFIG_SOC_NRF7120_ENGA_CPUFLPR) + board_runner_args(jlink "--speed=4000") +endif() + +if(CONFIG_SOC_SERIES_NRF71 AND CONFIG_TRUSTED_EXECUTION_NONSECURE) + set(TFM_PUBLIC_KEY_FORMAT "full") +endif() + +if(CONFIG_TFM_FLASH_MERGED_BINARY) + set_property(TARGET runners_yaml_props_target PROPERTY hex_file tfm_merged.hex) +endif() + +include(${ZEPHYR_BASE}/boards/common/nrfutil.board.cmake) +include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/nordic/nrf7120dk/board.yml b/boards/nordic/nrf7120dk/board.yml new file mode 100644 index 000000000000..c6c5d74623df --- /dev/null +++ b/boards/nordic/nrf7120dk/board.yml @@ -0,0 +1,11 @@ +board: + name: nrf7120dk + full_name: nRF7120 DK + vendor: nordic + socs: + - name: nrf7120 + variants: + - name: xip + cpucluster: cpuflpr + - name: ns + cpucluster: cpuapp diff --git a/boards/nordic/nrf7120dk/doc/index.rst b/boards/nordic/nrf7120dk/doc/index.rst new file mode 100644 index 000000000000..c84f502e5d45 --- /dev/null +++ b/boards/nordic/nrf7120dk/doc/index.rst @@ -0,0 +1,87 @@ +.. zephyr:board:: nrf7120dk + +Overview +******** + +The nRF7120 Development Kit hardware provides support for the Nordic Semiconductor +nRF7120 Arm Cortex-M33 CPU. + +Hardware +******** + +nRF7120 DK has two crystal oscillators: + +* High-frequency 64 MHz crystal oscillator (HFXO) +* Low-frequency 32.768 kHz crystal oscillator (LFXO) + +The crystal oscillators can be configured to use either +internal or external capacitors. + +Supported Features +================== + +.. zephyr:board-supported-hw:: + +Programming and Debugging +************************* + +.. zephyr:board-supported-runners:: + +Applications for the ``nrf7120dk/nrf7120/cpuapp`` board target can be +built, flashed, and debugged in the usual way. See +:ref:`build_an_application` and :ref:`application_run` for more details on +building and running. + +Applications for the ``nrf7120dk/nrf7120/cpuflpr`` board target need +to be built using sysbuild to include the ``vpr_launcher`` image for the application core. + +Enter the following command to compile ``hello_world`` for the FLPR core: + +.. code-block:: console + + west build -p -b nrf7120dk/nrf7120/cpuflpr --sysbuild + + +Flashing +======== + +As an example, this section shows how to build and flash the :zephyr:code-sample:`hello_world` +application. + +.. warning:: + + When programming the device, you might get an error similar to the following message:: + + ERROR: The operation attempted is unavailable due to readback protection in + ERROR: your device. Please use --recover to unlock the device. + + This error occurs when readback protection is enabled. + To disable the readback protection, you must *recover* your device. + + Enter the following command to recover the core:: + + west flash --recover + + The ``--recover`` command erases the flash memory and then writes a small binary into + the recovered flash memory. + This binary prevents the readback protection from enabling itself again after a pin + reset or power cycle. + +Follow the instructions in the :ref:`nordic_segger` page to install +and configure all the necessary software. Further information can be +found in :ref:`nordic_segger_flashing`. + +To build and program the sample to the nRF7120 DK, complete the following steps: + +First, connect the nRF7120 DK to you computer using the IMCU USB port on the DK. +Next, build the sample by running the following command: + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: nrf7120dk/nrf7120/cpuapp + :goals: build flash + +Testing the LEDs and buttons in the nRF7120 DK +************************************************ + +Test the nRF7120 DK with a :zephyr:code-sample:`blinky` sample. diff --git a/boards/nordic/nrf7120dk/nrf7120_cpuapp_common.dtsi b/boards/nordic/nrf7120dk/nrf7120_cpuapp_common.dtsi new file mode 100644 index 000000000000..41c76e48433b --- /dev/null +++ b/boards/nordic/nrf7120dk/nrf7120_cpuapp_common.dtsi @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* This file is common to the secure and non-secure domain */ + +#include +#include "nrf7120dk_nrf7120-common.dtsi" + +/ { + chosen { + zephyr,console = &uart20; + zephyr,shell-uart = &uart20; + zephyr,uart-mcumgr = &uart20; + zephyr,bt-mon-uart = &uart20; + zephyr,bt-c2h-uart = &uart20; + zephyr,flash = &cpuapp_mram; + zephyr,ieee802154 = &ieee802154; + zephyr,wifi = &wlan0; + }; + + /* TODO: Fine tune the sizes */ + reserved-memory { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + ipc_shm_area_cpuapp_cpuuma: memory@200C0000 { + compatible = "mmio-sram"; + reg = <0x200C0000 0x2000>; + ranges = <0x0 0x200C0000 0x2000>; + #address-cells = <1>; + #size-cells = <1>; + status = "okay"; + + ipc_shm_cpuapp_cpuuma_0: memory@0 { + reg = <0x0 DT_SIZE_K(2)>; + }; + + ipc_shm_cpuuma_cpuapp_0: memory@800 { + reg = <0x800 DT_SIZE_K(2)>; + }; + + ipc_shm_cpuapp_cpuuma_1: memory@1000 { + reg = <0x1000 DT_SIZE_K(2)>; + }; + + ipc_shm_cpuuma_cpuapp_1: memory@1800 { + reg = <0x1800 DT_SIZE_K(2)>; + }; + }; + }; + + ipc { + ipc0: ipc0 { + compatible = "zephyr,ipc-icmsg"; + tx-region = <&ipc_shm_cpuapp_cpuuma_0>; + rx-region = <&ipc_shm_cpuuma_cpuapp_0>; + mboxes = <&wifi_bellboard 2>, + <&cpuapp_bellboard 0>; + mbox-names = "tx", "rx"; + status = "okay"; + }; + + ipc1: ipc1 { + compatible = "zephyr,ipc-icmsg"; + tx-region = <&ipc_shm_cpuapp_cpuuma_1>; + rx-region = <&ipc_shm_cpuuma_cpuapp_1>; + mboxes = <&wifi_bellboard 3>, + <&cpuapp_bellboard 1>; + mbox-names = "tx", "rx"; + status = "okay"; + }; + }; +}; + +&cpuapp_sram { + status = "okay"; +}; + +&grtc { + owned-channels = <0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15>; + /* Channels 7-11 reserved for Zero Latency IRQs, 3-4 for FLPR */ + child-owned-channels = <3 4 7 8 9 10 11>; + status = "okay"; +}; + +&uart20 { + status = "okay"; +}; + +&gpio0 { + status = "okay"; +}; + +&gpio1 { + status = "okay"; +}; + +&gpio2 { + status = "okay"; +}; + +&gpio3 { + status = "okay"; +}; + +&gpio4 { + status = "okay"; +}; + +&gpiote20 { + status = "okay"; +}; + +&gpiote30 { + status = "okay"; +}; + +&radio { + status = "okay"; +}; + +&ieee802154 { + status = "okay"; +}; + +&temp { + status = "okay"; +}; + +&clock { + status = "okay"; +}; + +&spi00 { + status = "okay"; + cs-gpios = <&gpio2 5 GPIO_ACTIVE_LOW>; + pinctrl-0 = <&spi00_default>; + pinctrl-1 = <&spi00_sleep>; + pinctrl-names = "default", "sleep"; +}; + +&adc { + status = "okay"; +}; + +&pwr_antswc { + status = "okay"; +}; + +&wifi { + status = "okay"; +}; + +&audio_auxpll { + nordic,frequency = ; + status = "okay"; +}; + +&cpuapp_bellboard { + status = "okay"; +}; + +&wifi_bellboard { + status = "okay"; +}; + +&qspi00 { + status = "okay"; + op-mode = "MSPI_OP_MODE_CONTROLLER"; +}; diff --git a/boards/nordic/nrf7120dk/nrf7120dk_nrf7120-common.dtsi b/boards/nordic/nrf7120dk/nrf7120dk_nrf7120-common.dtsi new file mode 100644 index 000000000000..50a219c56a0d --- /dev/null +++ b/boards/nordic/nrf7120dk/nrf7120dk_nrf7120-common.dtsi @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "nrf7120dk_nrf7120-pinctrl.dtsi" + +/ { + leds { + compatible = "gpio-leds"; + + led0: led_0 { + gpios = <&gpio2 9 GPIO_ACTIVE_HIGH>; + label = "Green LED 0"; + }; + + led1: led_1 { + gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>; + label = "Green LED 1"; + }; + + led2: led_2 { + gpios = <&gpio2 7 GPIO_ACTIVE_HIGH>; + label = "Green LED 2"; + }; + + led3: led_3 { + gpios = <&gpio1 14 GPIO_ACTIVE_HIGH>; + label = "Green LED 3"; + }; + }; + + 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 { + gpios = <&gpio1 13 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button 0"; + zephyr,code = ; + }; + + button1: button_1 { + gpios = <&gpio1 9 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button 1"; + zephyr,code = ; + }; + + button2: button_2 { + gpios = <&gpio1 8 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button 2"; + zephyr,code = ; + }; + + button3: button_3 { + gpios = <&gpio0 4 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button 3"; + zephyr,code = ; + }; + }; + + aliases { + led0 = &led0; + led1 = &led1; + led2 = &led2; + led3 = &led3; + pwm-led0 = &pwm_led1; + sw0 = &button0; + sw1 = &button1; + sw2 = &button2; + sw3 = &button3; + watchdog0 = &wdt31; + }; +}; + +&uart00 { + current-speed = <115200>; + pinctrl-0 = <&uart00_default>; + pinctrl-1 = <&uart00_sleep>; + pinctrl-names = "default", "sleep"; +}; + +&uart20 { + current-speed = <115200>; + pinctrl-0 = <&uart20_default>; + pinctrl-1 = <&uart20_sleep>; + pinctrl-names = "default", "sleep"; +}; + +&uart30 { + current-speed = <115200>; + pinctrl-0 = <&uart30_default>; + pinctrl-1 = <&uart30_sleep>; + pinctrl-names = "default", "sleep"; +}; + +&pwm20 { + status = "okay"; + pinctrl-0 = <&pwm20_default>; + pinctrl-1 = <&pwm20_sleep>; + pinctrl-names = "default", "sleep"; +}; + +&nfct { + status = "okay"; +}; + +&qspi00 { + pinctrl-0 = <&qspi00_default>; + pinctrl-1 = <&qspi00_sleep>; + pinctrl-names = "default", "sleep"; +}; diff --git a/boards/nordic/nrf7120dk/nrf7120dk_nrf7120-pinctrl.dtsi b/boards/nordic/nrf7120dk/nrf7120dk_nrf7120-pinctrl.dtsi new file mode 100644 index 000000000000..6538af10f840 --- /dev/null +++ b/boards/nordic/nrf7120dk/nrf7120dk_nrf7120-pinctrl.dtsi @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor + * SPDX-License-Identifier: Apache-2.0 + */ + +&pinctrl { + /omit-if-no-ref/ uart20_default: uart20_default { + group1 { + psels = , + ; + }; + + group2 { + psels = , + ; + bias-pull-up; + }; + }; + + /omit-if-no-ref/ uart20_sleep: uart20_sleep { + group1 { + psels = , + , + , + ; + low-power-enable; + }; + }; + + /omit-if-no-ref/ uart30_default: uart30_default { + group1 { + psels = , + ; + }; + + group2 { + psels = , + ; + bias-pull-up; + }; + }; + + /omit-if-no-ref/ uart30_sleep: uart30_sleep { + group1 { + psels = , + , + , + ; + low-power-enable; + }; + }; + + /omit-if-no-ref/ spi00_default: spi00_default { + group1 { + psels = , + , + ; + }; + }; + + /omit-if-no-ref/ spi00_sleep: spi00_sleep { + group1 { + psels = , + , + ; + low-power-enable; + }; + }; + + /omit-if-no-ref/ pwm20_default: pwm20_default { + group1 { + psels = ; + }; + }; + + /omit-if-no-ref/ pwm20_sleep: pwm20_sleep { + group1 { + psels = ; + low-power-enable; + }; + }; + + /omit-if-no-ref/ uart00_default: uart00_default { + group1 { + psels = , + ; + }; + + group2 { + psels = , + ; + bias-pull-up; + }; + }; + + /omit-if-no-ref/ uart00_sleep: uart00_sleep { + group1 { + psels = , + , + , + ; + low-power-enable; + }; + }; + + /omit-if-no-ref/ qspi00_default: qspi00_default { + group1 { + psels = , + , + , + , + , + ; + nordic,drive-mode = ; + }; + }; + + /omit-if-no-ref/ qspi00_sleep: qspi00_sleep { + group1 { + low-power-enable; + psels = , + , + , + , + , + ; + }; + }; +}; diff --git a/boards/nordic/nrf7120dk/nrf7120dk_nrf7120_cpuapp.dts b/boards/nordic/nrf7120dk/nrf7120dk_nrf7120_cpuapp.dts new file mode 100644 index 000000000000..3e0ef75f6bed --- /dev/null +++ b/boards/nordic/nrf7120dk/nrf7120dk_nrf7120_cpuapp.dts @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include "nrf7120_cpuapp_common.dtsi" + +/ { + compatible = "nordic,nrf7120dk_nrf7120-cpuapp"; + model = "Nordic nRF7120 DK nRF7120 Application MCU"; + + chosen { + zephyr,code-partition = &slot0_partition; + zephyr,sram = &cpuapp_sram; + }; +}; + +#include diff --git a/boards/nordic/nrf7120dk/nrf7120dk_nrf7120_cpuapp.yaml b/boards/nordic/nrf7120dk/nrf7120dk_nrf7120_cpuapp.yaml new file mode 100644 index 000000000000..7d746d495b12 --- /dev/null +++ b/boards/nordic/nrf7120dk/nrf7120dk_nrf7120_cpuapp.yaml @@ -0,0 +1,24 @@ +# Copyright (c) 2025 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +identifier: nrf7120dk/nrf7120/cpuapp +name: nRF7120-DK-nRF7120-Application +type: mcu +arch: arm +toolchain: + - gnuarmemb + - xtools + - zephyr +sysbuild: true +ram: 512 +flash: 1992 +supported: + - adc + - counter + - gpio + - i2c + - pwm + - spi + - watchdog + - i2s + - wifi diff --git a/boards/nordic/nrf7120dk/nrf7120dk_nrf7120_cpuapp_defconfig b/boards/nordic/nrf7120dk/nrf7120dk_nrf7120_cpuapp_defconfig new file mode 100644 index 000000000000..8ff96446de24 --- /dev/null +++ b/boards/nordic/nrf7120dk/nrf7120dk_nrf7120_cpuapp_defconfig @@ -0,0 +1,25 @@ +# Copyright (c) 2025 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +# Enable UART driver +CONFIG_SERIAL=y + +# Enable console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# Enable GPIO +CONFIG_GPIO=y + +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable hardware stack protection +CONFIG_HW_STACK_PROTECTION=y + +# MPU-based null-pointer dereferencing detection cannot +# be applied as the (0x0 - 0x400) is unmapped for this target. +CONFIG_NULL_POINTER_EXCEPTION_DETECTION_NONE=y + +# Start SYSCOUNTER on driver init +CONFIG_NRF_GRTC_START_SYSCOUNTER=y diff --git a/boards/nordic/nrf7120dk/nrf7120dk_nrf7120_cpuapp_ns.dts b/boards/nordic/nrf7120dk/nrf7120dk_nrf7120_cpuapp_ns.dts new file mode 100644 index 000000000000..56f2104393d4 --- /dev/null +++ b/boards/nordic/nrf7120dk/nrf7120dk_nrf7120_cpuapp_ns.dts @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#define USE_NON_SECURE_ADDRESS_MAP 1 + +#include "nrf7120_cpuapp_common.dtsi" + +/ { + compatible = "nordic,nrf7120dk_nrf7120-cpuapp"; + model = "Nordic nRF7120 DK nRF7120 Application MCU"; + + chosen { + zephyr,code-partition = &slot0_ns_partition; + zephyr,sram = &cpuapp_sram; + }; +}; + +&uart30 { + /* Disable so that TF-M can use this UART */ + status = "disabled"; +}; + +#include diff --git a/boards/nordic/nrf7120dk/nrf7120dk_nrf7120_cpuapp_ns.yaml b/boards/nordic/nrf7120dk/nrf7120dk_nrf7120_cpuapp_ns.yaml new file mode 100644 index 000000000000..3891b38e52a0 --- /dev/null +++ b/boards/nordic/nrf7120dk/nrf7120dk_nrf7120_cpuapp_ns.yaml @@ -0,0 +1,22 @@ +# Copyright (c) 2025 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +identifier: nrf7120dk/nrf7120/cpuapp/ns +name: nRF7120-DK-nRF7120-Application-Non-Secure +type: mcu +arch: arm +toolchain: + - gnuarmemb + - xtools + - zephyr +ram: 896 +flash: 512 +supported: + - adc + - gpio + - i2c + - spi + - counter + - watchdog + - adc + - i2s diff --git a/boards/nordic/nrf7120dk/nrf7120dk_nrf7120_cpuapp_ns_defconfig b/boards/nordic/nrf7120dk/nrf7120dk_nrf7120_cpuapp_ns_defconfig new file mode 100644 index 000000000000..771440c64940 --- /dev/null +++ b/boards/nordic/nrf7120dk/nrf7120dk_nrf7120_cpuapp_ns_defconfig @@ -0,0 +1,37 @@ +# Copyright (c) 2025 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable hardware stack protection +CONFIG_HW_STACK_PROTECTION=y + +CONFIG_NULL_POINTER_EXCEPTION_DETECTION_NONE=y + +# Enable TrustZone-M +CONFIG_ARM_TRUSTZONE_M=y + +# This Board implies building Non-Secure firmware +CONFIG_TRUSTED_EXECUTION_NONSECURE=y + +# Use devicetree code partition for TF-M +CONFIG_USE_DT_CODE_PARTITION=y + +# Don't enable the cache in the non-secure image as it is a +# secure-only peripheral on 71x series +CONFIG_CACHE_MANAGEMENT=n +CONFIG_EXTERNAL_CACHE=n + +CONFIG_UART_CONSOLE=y +CONFIG_CONSOLE=y +CONFIG_SERIAL=y + +# Enable GPIO +CONFIG_GPIO=y + +# Start SYSCOUNTER on driver init +CONFIG_NRF_GRTC_START_SYSCOUNTER=y + +# Disable TFM BL2 since it is not supported +CONFIG_TFM_BL2=n diff --git a/boards/nordic/nrf7120dk/nrf7120dk_nrf7120_cpuflpr.dts b/boards/nordic/nrf7120dk/nrf7120dk_nrf7120_cpuflpr.dts new file mode 100644 index 000000000000..87e7f03dc79e --- /dev/null +++ b/boards/nordic/nrf7120dk/nrf7120dk_nrf7120_cpuflpr.dts @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include "nrf7120dk_nrf7120-common.dtsi" + +/ { + model = "Nordic nRF7120 DK nRF7120 FLPR MCU"; + compatible = "nordic,nrf7120dk_nrf7120-cpuflpr"; + + chosen { + zephyr,console = &uart00; + zephyr,shell-uart = &uart00; + zephyr,code-partition = &cpuflpr_code_partition; + zephyr,flash = &cpuflpr_mram; + zephyr,sram = &ram03_sram; + }; +}; + +/* RAM03 is single cycle access for FLPR core while RAM01 is 2 cycle access */ +&ram03_sram { + status = "okay"; + reg = <0x200e0000 DT_SIZE_K(120)>; + ranges = <0x0 0x200e0000 0x1e000>; +}; + +&cpuflpr_mram { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + cpuflpr_code_partition: partition@0 { + label = "image-0"; + reg = <0 DT_SIZE_K(116)>; + }; + }; +}; + +&grtc { + owned-channels = <3 4>; + status = "okay"; +}; + +&uart00 { + status = "okay"; +}; + +&gpio0 { + status = "okay"; +}; + +&gpio1 { + status = "okay"; +}; + +&gpio2 { + status = "okay"; +}; + +&gpio3 { + status = "okay"; +}; + +&gpio4 { + status = "okay"; +}; + +&gpiote20 { + status = "okay"; +}; + +&gpiote30 { + status = "okay"; +}; diff --git a/boards/nordic/nrf7120dk/nrf7120dk_nrf7120_cpuflpr.yaml b/boards/nordic/nrf7120dk/nrf7120dk_nrf7120_cpuflpr.yaml new file mode 100644 index 000000000000..e04eb2653f35 --- /dev/null +++ b/boards/nordic/nrf7120dk/nrf7120dk_nrf7120_cpuflpr.yaml @@ -0,0 +1,17 @@ +# Copyright (c) 2025 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +identifier: nrf7120dk/nrf7120/cpuflpr +name: nRF7120-DK-nRF7120-Fast-Lightweight-Peripheral-Processor +type: mcu +arch: riscv +toolchain: + - zephyr +sysbuild: true +ram: 124 +flash: 116 +supported: + - counter + - gpio + - i2c + - spi diff --git a/boards/nordic/nrf7120dk/nrf7120dk_nrf7120_cpuflpr_defconfig b/boards/nordic/nrf7120dk/nrf7120dk_nrf7120_cpuflpr_defconfig new file mode 100644 index 000000000000..90cf13bdee5e --- /dev/null +++ b/boards/nordic/nrf7120dk/nrf7120dk_nrf7120_cpuflpr_defconfig @@ -0,0 +1,17 @@ +# Copyright (c) 2025 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +# Enable UART driver +CONFIG_SERIAL=y + +# Enable console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# Enable GPIO +CONFIG_GPIO=y + +CONFIG_USE_DT_CODE_PARTITION=y + +# Execute from SRAM +CONFIG_XIP=n diff --git a/boards/nordic/nrf7120dk/nrf7120dk_nrf7120_cpuflpr_xip.dts b/boards/nordic/nrf7120dk/nrf7120dk_nrf7120_cpuflpr_xip.dts new file mode 100644 index 000000000000..8c0b6285416e --- /dev/null +++ b/boards/nordic/nrf7120dk/nrf7120dk_nrf7120_cpuflpr_xip.dts @@ -0,0 +1,7 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "nrf7120dk_nrf7120_cpuflpr.dts" diff --git a/boards/nordic/nrf7120dk/nrf7120dk_nrf7120_cpuflpr_xip.yaml b/boards/nordic/nrf7120dk/nrf7120dk_nrf7120_cpuflpr_xip.yaml new file mode 100644 index 000000000000..a08c578b03c6 --- /dev/null +++ b/boards/nordic/nrf7120dk/nrf7120dk_nrf7120_cpuflpr_xip.yaml @@ -0,0 +1,17 @@ +# Copyright (c) 2025 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +identifier: nrf7120dk/nrf7120/cpuflpr/xip +name: nRF7120-DK-nRF7120-Fast-Lightweight-Peripheral-Processor (MRAM XIP) +type: mcu +arch: riscv +toolchain: + - zephyr +sysbuild: true +ram: 124 +flash: 116 +supported: + - counter + - gpio + - i2c + - spi diff --git a/boards/nordic/nrf7120dk/nrf7120dk_nrf7120_cpuflpr_xip_defconfig b/boards/nordic/nrf7120dk/nrf7120dk_nrf7120_cpuflpr_xip_defconfig new file mode 100644 index 000000000000..f0b4a7dc2802 --- /dev/null +++ b/boards/nordic/nrf7120dk/nrf7120dk_nrf7120_cpuflpr_xip_defconfig @@ -0,0 +1,15 @@ +# Copyright (c) 2025 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +# Enable UART driver +CONFIG_SERIAL=y + +# Enable console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# Enable GPIO +CONFIG_GPIO=y + +# Execute from MRAM +CONFIG_XIP=y From eb647dbf64cabab8c42f6aa2fdc2fef748156d83 Mon Sep 17 00:00:00 2001 From: Robert Robinson Date: Wed, 10 Dec 2025 15:08:18 +0000 Subject: [PATCH 1771/3659] soc: nordic: Add initial support for nRF7120 SoC Add SoC files for nrf7120. Signed-off-by: Robert Robinson --- modules/hal_nordic/nrfx/CMakeLists.txt | 24 +- modules/hal_nordic/nrfx/nrfx_kconfig.h | 10 + soc/nordic/Kconfig | 6 + soc/nordic/Kconfig.soc | 7 + soc/nordic/nrf71/CMakeLists.txt | 10 + soc/nordic/nrf71/Kconfig | 27 +++ soc/nordic/nrf71/Kconfig.defconfig | 45 ++++ .../Kconfig.defconfig.nrf7120_enga_cpuapp | 11 + .../Kconfig.defconfig.nrf7120_enga_cpuflpr | 15 ++ soc/nordic/nrf71/Kconfig.soc | 31 +++ soc/nordic/nrf71/align.ld | 10 + soc/nordic/nrf71/soc.c | 212 ++++++++++++++++++ soc/nordic/nrf71/soc.h | 30 +++ soc/nordic/soc.yml | 10 + 14 files changed, 444 insertions(+), 4 deletions(-) create mode 100644 soc/nordic/nrf71/CMakeLists.txt create mode 100644 soc/nordic/nrf71/Kconfig create mode 100644 soc/nordic/nrf71/Kconfig.defconfig create mode 100644 soc/nordic/nrf71/Kconfig.defconfig.nrf7120_enga_cpuapp create mode 100644 soc/nordic/nrf71/Kconfig.defconfig.nrf7120_enga_cpuflpr create mode 100644 soc/nordic/nrf71/Kconfig.soc create mode 100644 soc/nordic/nrf71/align.ld create mode 100644 soc/nordic/nrf71/soc.c create mode 100644 soc/nordic/nrf71/soc.h diff --git a/modules/hal_nordic/nrfx/CMakeLists.txt b/modules/hal_nordic/nrfx/CMakeLists.txt index 00e5db07006b..df079455b506 100644 --- a/modules/hal_nordic/nrfx/CMakeLists.txt +++ b/modules/hal_nordic/nrfx/CMakeLists.txt @@ -73,6 +73,11 @@ zephyr_compile_definitions_ifdef(CONFIG_SOC_NRF54LM20A_ENGA_CPUAPP NRF_APPLICATI zephyr_compile_definitions_ifdef(CONFIG_SOC_NRF54LM20A_ENGA_CPUFLPR NRF_FLPR) zephyr_compile_definitions_ifdef(CONFIG_SOC_COMPATIBLE_NRF54LM20A NRF54LM20A_ENGA_XXAA) zephyr_compile_definitions_ifdef(CONFIG_SOC_COMPATIBLE_NRF54LM20A_CPUAPP NRF_APPLICATION) +zephyr_compile_definitions_ifdef(CONFIG_SOC_NRF7120_ENGA NRF7120_ENGA_XXAA) +zephyr_compile_definitions_ifdef(CONFIG_SOC_NRF7120_ENGA_CPUAPP NRF_APPLICATION) +zephyr_compile_definitions_ifdef(CONFIG_SOC_NRF7120_ENGA_CPUFLPR NRF_FLPR) +zephyr_compile_definitions_ifdef(CONFIG_SOC_COMPATIBLE_NRF7120_ENGA NRF7120_ENGA_XXAA) +zephyr_compile_definitions_ifdef(CONFIG_SOC_COMPATIBLE_NRF7120_ENGA_CPUAPP NRF_APPLICATION) zephyr_compile_definitions_ifdef(CONFIG_SOC_NRF9120 NRF9120_XXAA) zephyr_compile_definitions_ifdef(CONFIG_SOC_NRF9160 NRF9160_XXAA) @@ -120,8 +125,9 @@ zephyr_library_sources_ifdef(CONFIG_SOC_SERIES_NRF54HX ${MDK_DIR}/system_nrf54h. if(CONFIG_SOC_SERIES_NRF54LX OR CONFIG_SOC_SERIES_BSIM_NRF54LX) zephyr_library_sources(${MDK_DIR}/system_nrf54l.c) endif() -zephyr_library_sources_ifdef(CONFIG_SOC_SERIES_NRF91X ${MDK_DIR}/system_nrf91.c) -zephyr_library_sources_ifdef(CONFIG_SOC_SERIES_NRF92X ${MDK_DIR}/system_nrf92.c) +zephyr_library_sources_ifdef(CONFIG_SOC_SERIES_NRF71 ${MDK_DIR}/system_nrf7120_enga.c) +zephyr_library_sources_ifdef(CONFIG_SOC_SERIES_NRF91X ${MDK_DIR}/system_nrf91.c) +zephyr_library_sources_ifdef(CONFIG_SOC_SERIES_NRF92X ${MDK_DIR}/system_nrf92.c) zephyr_library_sources(nrfx_glue.c) zephyr_library_sources(${HELPERS_DIR}/nrfx_flag32_allocator.c) @@ -129,10 +135,12 @@ zephyr_library_sources_ifdef(CONFIG_HAS_NORDIC_RAM_CTRL ${HELPERS_DIR}/nrf if(CONFIG_NRFX_GPPI AND NOT CONFIG_NRFX_GPPI_V1) zephyr_library_sources_ifdef(CONFIG_HAS_HW_NRF_PPI ${HELPERS_DIR}/nrfx_gppi_ppi.c) - if(CONFIG_SOC_SERIES_NRF54LX OR CONFIG_HAS_HW_NRF_DPPIC) + if(CONFIG_SOC_SERIES_NRF54LX OR CONFIG_SOC_SERIES_NRF71 OR CONFIG_HAS_HW_NRF_DPPIC) zephyr_library_sources(${HELPERS_DIR}/nrfx_gppi_dppi.c) endif() - zephyr_library_sources_ifdef(CONFIG_SOC_COMPATIBLE_NRF54LX ${BSP_DIR}/soc/interconnect/nrfx_gppi_lumos.c) + if(CONFIG_SOC_COMPATIBLE_NRF54LX OR CONFIG_SOC_SERIES_NRF71) + zephyr_library_sources(${BSP_DIR}/soc/interconnect/nrfx_gppi_lumos.c) + endif() endif() zephyr_library_sources_ifdef(CONFIG_NRFX_PRS ${SRC_DIR}/prs/nrfx_prs.c) @@ -225,6 +233,12 @@ if(CONFIG_SOC_NRF54L_CPUAPP_COMMON) zephyr_compile_definitions("NRF_CONFIG_CPU_FREQ_MHZ=${clock_frequency_mhz}") endif() +if(CONFIG_SOC_NRF7120_ENGA_CPUAPP) + dt_prop(clock_frequency PATH "/cpus/cpu@0" PROPERTY "clock-frequency") + math(EXPR clock_frequency_mhz "${clock_frequency} / 1000000") + zephyr_compile_definitions("NRF_CONFIG_CPU_FREQ_MHZ=${clock_frequency_mhz}") +endif() + zephyr_compile_definitions_ifdef(CONFIG_NRF_SKIP_CLOCK_CONFIG NRF_SKIP_CLOCK_CONFIGURATION) zephyr_compile_definitions_ifdef(CONFIG_SOC_NRF54LX_DISABLE_FICR_TRIMCNF NRF_DISABLE_FICR_TRIMCNF) zephyr_compile_definitions_ifdef(CONFIG_SOC_NRF54LX_SKIP_GLITCHDETECTOR_DISABLE NRF_SKIP_GLITCHDETECTOR_DISABLE) @@ -264,6 +278,8 @@ mdk_svd_ifdef(CONFIG_SOC_NRF54L15_CPUAPP nrf54l15_application.svd) mdk_svd_ifdef(CONFIG_SOC_NRF54L15_CPUFLPR nrf54l15_flpr.svd) mdk_svd_ifdef(CONFIG_SOC_NRF54LM20A_ENGA_CPUAPP nrf54lm20a_enga_application.svd) mdk_svd_ifdef(CONFIG_SOC_NRF54LM20A_ENGA_CPUFLPR nrf54lm20a_enga_flpr.svd) +mdk_svd_ifdef(CONFIG_SOC_NRF7120_ENGA_CPUAPP nrf7120_enga_application.svd) +mdk_svd_ifdef(CONFIG_SOC_NRF7120_ENGA_CPUFLPR nrf7120_enga_flpr.svd) mdk_svd_ifdef(CONFIG_SOC_NRF9120 nrf9120.svd) mdk_svd_ifdef(CONFIG_SOC_NRF9160 nrf9160.svd) mdk_svd_ifdef(CONFIG_SOC_NRF9230_ENGB_CPUAPP nrf9230_engb_application.svd) diff --git a/modules/hal_nordic/nrfx/nrfx_kconfig.h b/modules/hal_nordic/nrfx/nrfx_kconfig.h index 5118dd29944e..833fc6f23c75 100644 --- a/modules/hal_nordic/nrfx/nrfx_kconfig.h +++ b/modules/hal_nordic/nrfx/nrfx_kconfig.h @@ -14,6 +14,16 @@ * supported by nrfx (see the corresponding nrfx_config_*.h files). */ +#if defined(CONFIG_SOC_COMPATIBLE_NRF7120_ENGA) && !defined(NRF7120_ENGA_XXAA) +#define NRF7120_ENGA_XXAA +#endif +#if defined(CONFIG_SOC_COMPATIBLE_NRF7120_ENGA_CPUAPP) && !defined(NRF_APPLICATION) +#define NRF_APPLICATION +#endif +#if defined(CONFIG_SOC_NRF7120_ENGA_CPUFLPR) && !defined(NRF_FLPR) +#define NRF_FLPR +#endif + #ifdef CONFIG_NRFX_ADC #define NRFX_ADC_ENABLED 1 #endif diff --git a/soc/nordic/Kconfig b/soc/nordic/Kconfig index df4bba2e1ce1..ef66efea38a6 100644 --- a/soc/nordic/Kconfig +++ b/soc/nordic/Kconfig @@ -43,6 +43,12 @@ config SOC_COMPATIBLE_NRF54LM20A config SOC_COMPATIBLE_NRF54LM20A_CPUAPP bool +config SOC_COMPATIBLE_NRF7120_ENGA + bool + +config SOC_COMPATIBLE_NRF7120_ENGA_CPUAPP + bool + config SOC_FAMILY_NORDIC_NRF select SOC_COMPATIBLE_NRF select SOC_RESET_HOOK diff --git a/soc/nordic/Kconfig.soc b/soc/nordic/Kconfig.soc index 6851c25becf1..15913e12dce0 100644 --- a/soc/nordic/Kconfig.soc +++ b/soc/nordic/Kconfig.soc @@ -13,6 +13,7 @@ config SOC_SERIES default "nrf53" if SOC_SERIES_NRF53X default "nrf54h" if SOC_SERIES_NRF54HX default "nrf54l" if SOC_SERIES_NRF54LX + default "nrf71" if SOC_SERIES_NRF71 default "nrf91" if SOC_SERIES_NRF91X default "nrf92" if SOC_SERIES_NRF92X @@ -51,6 +52,12 @@ config SOC_SERIES_NRF54LX help Nordic Semiconductor nRF54L series MCU +config SOC_SERIES_NRF71 + bool + select SOC_FAMILY_NORDIC_NRF + help + Nordic Semiconductor nRF71 series MCU + config SOC_SERIES_NRF91X bool select SOC_FAMILY_NORDIC_NRF diff --git a/soc/nordic/nrf71/CMakeLists.txt b/soc/nordic/nrf71/CMakeLists.txt new file mode 100644 index 000000000000..b7e66a6ff30f --- /dev/null +++ b/soc/nordic/nrf71/CMakeLists.txt @@ -0,0 +1,10 @@ +# Copyright (c) 2025 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library_sources(soc.c) + +zephyr_include_directories(.) + +# Ensure that image size aligns with 16 bytes so that MRAMC finalizes all writes +# for the image correctly +zephyr_linker_sources(SECTIONS SORT_KEY zzz_place_align_at_end align.ld) diff --git a/soc/nordic/nrf71/Kconfig b/soc/nordic/nrf71/Kconfig new file mode 100644 index 000000000000..12f8fe77a695 --- /dev/null +++ b/soc/nordic/nrf71/Kconfig @@ -0,0 +1,27 @@ +# Nordic Semiconductor nRF71 MCU line + +# Copyright (c) 2025 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_NRF71 + select HAS_NRFX + select HAS_NORDIC_DRIVERS + select HAS_SEGGER_RTT if ZEPHYR_SEGGER_MODULE + select SOC_EARLY_INIT_HOOK + select SOC_RESET_HOOK + select NRF_PLATFORM_LUMOS + +config SOC_NRF7120_ENGA_CPUAPP + select ARM + select ARMV8_M_DSP + select CPU_CORTEX_M33 + select CPU_HAS_ARM_MPU + select CPU_HAS_ICACHE + select CPU_HAS_ARM_SAU + select CPU_HAS_FPU + select HAS_HW_NRF_RADIO_IEEE802154 + select HAS_POWEROFF + select HAS_SWO + +config SOC_NRF7120_ENGA_CPUFLPR + select RISCV_CORE_NORDIC_VPR diff --git a/soc/nordic/nrf71/Kconfig.defconfig b/soc/nordic/nrf71/Kconfig.defconfig new file mode 100644 index 000000000000..ff602e08751b --- /dev/null +++ b/soc/nordic/nrf71/Kconfig.defconfig @@ -0,0 +1,45 @@ +# Nordic Semiconductor nRF71 MCU line + +# Copyright (c) 2025 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if SOC_SERIES_NRF71 + +rsource "Kconfig.defconfig.nrf71*" + +if ARM + +config CORTEX_M_SYSTICK + default !NRF_GRTC_TIMER + +config CACHE_NRF_CACHE + default y + +config CACHE_MANAGEMENT + default y + +choice CACHE_TYPE + default EXTERNAL_CACHE +endchoice + +endif # ARM + +if RISCV + +DT_CHOSEN_Z_SRAM = zephyr,sram +DT_CHOSEN_Z_CODE = zephyr,code-partition + +config BUILD_OUTPUT_ADJUST_LMA + depends on !XIP + default "$(dt_chosen_partition_addr_hex,$(DT_CHOSEN_Z_CODE)) - \ + $(dt_chosen_reg_addr_hex,$(DT_CHOSEN_Z_SRAM))" + +endif # RISCV + +config SYS_CLOCK_HW_CYCLES_PER_SEC + default $(dt_nodelabel_int_prop,grtc,clock-frequency) if NRF_GRTC_TIMER + +config MSPI_DW_DDR + default n + +endif # SOC_SERIES_NRF71 diff --git a/soc/nordic/nrf71/Kconfig.defconfig.nrf7120_enga_cpuapp b/soc/nordic/nrf71/Kconfig.defconfig.nrf7120_enga_cpuapp new file mode 100644 index 000000000000..05babc6a10b3 --- /dev/null +++ b/soc/nordic/nrf71/Kconfig.defconfig.nrf7120_enga_cpuapp @@ -0,0 +1,11 @@ +# Nordic Semiconductor nRF7120 MCU + +# Copyright (c) 2025 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if SOC_NRF7120_ENGA_CPUAPP + +config NUM_IRQS + default 304 + +endif # SOC_NRF7120_ENGA_CPUAPP diff --git a/soc/nordic/nrf71/Kconfig.defconfig.nrf7120_enga_cpuflpr b/soc/nordic/nrf71/Kconfig.defconfig.nrf7120_enga_cpuflpr new file mode 100644 index 000000000000..8dbae72d3ccb --- /dev/null +++ b/soc/nordic/nrf71/Kconfig.defconfig.nrf7120_enga_cpuflpr @@ -0,0 +1,15 @@ +# Nordic Semiconductor nRF7120 MCU + +# Copyright (c) 2025 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if SOC_NRF7120_ENGA_CPUFLPR + +config NUM_IRQS + default 304 + +# As FLPR has limited memory most of tests does not fit with asserts enabled. +config ASSERT + default n + +endif # SOC_NRF7120_ENGA_CPUFLPR diff --git a/soc/nordic/nrf71/Kconfig.soc b/soc/nordic/nrf71/Kconfig.soc new file mode 100644 index 000000000000..93521c98caa0 --- /dev/null +++ b/soc/nordic/nrf71/Kconfig.soc @@ -0,0 +1,31 @@ +# Nordic Semiconductor nRF71 MCU line + +# Copyright (c) 2025 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config SOC_NRF7120 + bool + select SOC_SERIES_NRF71 + help + NRF7120 + +config SOC_NRF7120_ENGA + bool + select SOC_NRF7120 + help + NRF7120 ENGA + +config SOC_NRF7120_ENGA_CPUAPP + bool + select SOC_NRF7120_ENGA + help + NRF7120 ENGA CPUAPP + +config SOC_NRF7120_ENGA_CPUFLPR + bool + select SOC_NRF7120_ENGA + help + NRF7120 ENGA CPUFLPR + +config SOC + default "nrf7120" if SOC_NRF7120 diff --git a/soc/nordic/nrf71/align.ld b/soc/nordic/nrf71/align.ld new file mode 100644 index 000000000000..4fa606c1d658 --- /dev/null +++ b/soc/nordic/nrf71/align.ld @@ -0,0 +1,10 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA. + * SPDX-License-Identifier: Apache-2.0 + */ + +SECTION_PROLOGUE(.align16,,) +{ + . = (ALIGN(16) > 0 ? ALIGN(16) : 16) - 1; + BYTE(0); +} GROUP_LINK_IN(ROMABLE_REGION) diff --git a/soc/nordic/nrf71/soc.c b/soc/nordic/nrf71/soc.c new file mode 100644 index 000000000000..a71cd26367e1 --- /dev/null +++ b/soc/nordic/nrf71/soc.c @@ -0,0 +1,212 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief System/hardware module for Nordic Semiconductor nRF71 family processor + * + * This module provides routines to initialize and support board-level hardware + * for the Nordic Semiconductor nRF71 family processor. + */ + +#ifdef __NRF_TFM__ +#include +#endif + +#include +#include +#include +#include + +#ifndef __NRF_TFM__ +#include +#endif + +#if defined(NRF_APPLICATION) +#include +#include +#endif + +#include +#include + +#include +#include +#include + +LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); + +#define LFXO_NODE DT_NODELABEL(lfxo) + +#if !defined(CONFIG_TRUSTED_EXECUTION_NONSECURE) +/* Copied from TF-M native driver */ +struct mpc_region_override { + nrf_mpc_override_config_t config; + nrf_owner_t owner_id; + uintptr_t start_address; + uintptr_t endaddr; + uint32_t perm; + uint32_t permmask; + size_t index; +}; + +static void mpc_configure_override(NRF_MPC_Type *mpc, struct mpc_region_override *override) +{ + nrf_mpc_override_startaddr_set(mpc, override->index, override->start_address); + nrf_mpc_override_endaddr_set(mpc, override->index, override->endaddr); + nrf_mpc_override_perm_set(mpc, override->index, override->perm); + nrf_mpc_override_permmask_set(mpc, override->index, override->permmask); +#if defined(NRF_MPC_HAS_OVERRIDE_OWNERID) && NRF_MPC_HAS_OVERRIDE_OWNERID + nrf_mpc_override_ownerid_set(mpc, override->index, override->owner_id); +#endif + nrf_mpc_override_config_set(mpc, override->index, &override->config); +} + +/* + * Configure the override struct with reasonable defaults. This includes: + * + * Use a slave number of 0 to avoid redirecting bus transactions from + * one slave to another. + * + * Lock the override to prevent the code that follows from tampering + * with the configuration. + * + * Enable the override so it takes effect. + * + * Indicate that secdom is not enabled as this driver is not used on + * platforms with secdom. + */ +static void init_mpc_region_override(struct mpc_region_override *override) +{ + *override = (struct mpc_region_override){ + .config = + (nrf_mpc_override_config_t){ + .slave_number = 0, + .lock = true, + .enable = true, + .secdom_enable = false, + .secure_mask = false, + }, + /* 0-NS R,W,X =1 */ + .perm = 0x7, + .permmask = 0xF, + .owner_id = 0, + }; +} + +/** + * Return the SPU instance that can be used to configure the + * peripheral at the given base address. + */ +static inline NRF_SPU_Type *spu_instance_from_peripheral_addr(uint32_t peripheral_addr) +{ + /* See the SPU chapter in the IPS for how this is calculated */ + + uint32_t apb_bus_number = peripheral_addr & 0x00FC0000; + + return (NRF_SPU_Type *)(0x50000000 | apb_bus_number); +} + +/* End of TF-M native driver */ + +static void wifi_mpc_configuration(void) +{ + struct mpc_region_override override; + uint32_t index = 0; + + /* Make RAM_00/01/02 (AMBIX00 + AMBIX03) accessible to the Wi-Fi domain*/ + init_mpc_region_override(&override); + override.start_address = 0x20000000; + override.endaddr = 0x200E0000; + override.index = index++; + mpc_configure_override(NRF_MPC00, &override); + + /* MRAM MPC overrides for wifi */ + init_mpc_region_override(&override); + override.start_address = 0x00000000; + override.endaddr = 0x01000000; + override.index = index++; + mpc_configure_override(NRF_MPC00, &override); + + /* Make RAM_02 (AMBIX03) accessible to the Wi-Fi domain for IPC */ + init_mpc_region_override(&override); + override.start_address = 0x200C0000; + override.endaddr = 0x200E0000; + override.index = 0; + mpc_configure_override(NRF_MPC03, &override); +} + +static void grtc_configuration(void) +{ + /* Split security configuration to let Wi-Fi access GRTC */ + nrf_spu_feature_secattr_set(NRF_SPU20, NRF_SPU_FEATURE_GRTC_CC, 15, 0, 0); + nrf_spu_feature_secattr_set(NRF_SPU20, NRF_SPU_FEATURE_GRTC_CC, 14, 0, 0); + nrf_spu_feature_secattr_set(NRF_SPU20, NRF_SPU_FEATURE_GRTC_INTERRUPT, 4, 0, 0); + nrf_spu_feature_secattr_set(NRF_SPU20, NRF_SPU_FEATURE_GRTC_INTERRUPT, 5, 0, 0); + nrf_spu_feature_secattr_set(NRF_SPU20, NRF_SPU_FEATURE_GRTC_SYSCOUNTER, 0, 0, 0); +} +#endif /* CONFIG_TRUSTED_EXECUTION_NONSECURE */ + +#if !defined(CONFIG_TRUSTED_EXECUTION_NONSECURE) || defined(__NRF_TFM__) +static void wifi_setup(void) +{ +#if !defined(CONFIG_TRUSTED_EXECUTION_NONSECURE) + /* Skip for tf-m, configuration exist in target_cfg_71.c */ + wifi_mpc_configuration(); + + grtc_configuration(); + +#endif + + /* Kickstart the LMAC processor */ + NRF_WIFICORE_LRCCONF_LRC0->POWERON = + (LRCCONF_POWERON_MAIN_AlwaysOn << LRCCONF_POWERON_MAIN_Pos); + NRF_WIFICORE_LMAC_VPR->INITPC = NRF_WICR->RESERVED[0]; + NRF_WIFICORE_LMAC_VPR->CPURUN = (VPR_CPURUN_EN_Running << VPR_CPURUN_EN_Pos); +} +#endif + +void soc_early_init_hook(void) +{ +#if DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_pwr_antswc) + *(volatile uint32_t *)PWR_ANTSWC_REG |= PWR_ANTSWC_ENABLE; +#endif + /* Update the SystemCoreClock global variable with current core clock + * retrieved from hardware state. + */ +#if !defined(CONFIG_TRUSTED_EXECUTION_NONSECURE) || defined(__NRF_TFM__) + /* Currently not supported for non-secure */ + SystemCoreClockUpdate(); + wifi_setup(); + + /* Configure LFXO capacitive load if internal load capacitors are used */ +#if DT_ENUM_HAS_VALUE(LFXO_NODE, load_capacitors, internal) + nrf_lfxo_cload_set(NRF_LFXO, + (uint8_t)(DT_PROP(LFXO_NODE, load_capacitance_femtofarad) / 1000)); +#endif +#endif + +#ifdef __NRF_TFM__ + /* TF-M enables the instruction cache from target_cfg_71.c, so we + * don't need to enable it here. + */ +#else + /* Enable ICACHE */ + sys_cache_instr_enable(); +#endif +} + +void arch_busy_wait(uint32_t time_us) +{ + nrfx_coredep_delay_us(time_us); +} + +#ifdef CONFIG_SOC_RESET_HOOK +void soc_reset_hook(void) +{ + SystemInit(); +} +#endif diff --git a/soc/nordic/nrf71/soc.h b/soc/nordic/nrf71/soc.h new file mode 100644 index 000000000000..28ff81c8265e --- /dev/null +++ b/soc/nordic/nrf71/soc.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file SoC configuration macros for the Nordic Semiconductor NRF71 family processors. + */ + +#ifndef _NORDICSEMI_NRF71_SOC_H_ +#define _NORDICSEMI_NRF71_SOC_H_ + +#include + +#define FLASH_PAGE_ERASE_MAX_TIME_US 42000UL +#define FLASH_PAGE_MAX_CNT 381UL + +#if DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_pwr_antswc) + +#if defined(CONFIG_TRUSTED_EXECUTION_NONSECURE) +#define PWR_ANTSWC_REG (0x4010F780UL) +#else /* CONFIG_TRUSTED_EXECUTION_NONSECURE */ +#define PWR_ANTSWC_REG (0x5010F780UL) +#endif /* CONFIG_TRUSTED_EXECUTION_NONSECURE */ + +#define PWR_ANTSWC_ENABLE (0x3UL) +#endif /* DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_pwr_antswc) */ + +#endif /* _NORDICSEMI_NRF71_SOC_H_ */ diff --git a/soc/nordic/soc.yml b/soc/nordic/soc.yml index c6f33f5866b0..aab70b717b11 100644 --- a/soc/nordic/soc.yml +++ b/soc/nordic/soc.yml @@ -45,6 +45,12 @@ family: - name: cpurad - name: cpuppr - name: cpuflpr + - name: nrf71 + socs: + - name: nrf7120 + cpuclusters: + - name: cpuapp + - name: cpuflpr - name: nrf91 socs: - name: nrf9131 @@ -248,6 +254,10 @@ runners: - nrf54h20/cpurad - nrf54h20/cpuppr - nrf54h20/cpuflpr + - qualifiers: + - nrf7120/cpuapp + - nrf7120/cpuapp/ns + - nrf7120/cpuflpr - qualifiers: - nrf9280/cpuapp - nrf9280/cpurad From 5445a6ac0f7fbb3c49bb8e721abbc8ca36a25862 Mon Sep 17 00:00:00 2001 From: Robert Robinson Date: Fri, 19 Dec 2025 13:09:12 +0000 Subject: [PATCH 1772/3659] manifest: Update TF-M for nRF7120DK to align with upstream zephyr Rename nRF7120PDK to nRF7120DK to align with upstream zephyr Align to nrf4.0 Add tfm_platform_user_memory_ranges.h files Signed-off-by: Robert Robinson --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 914191df257a..ecb086954aca 100644 --- a/west.yml +++ b/west.yml @@ -386,7 +386,7 @@ manifest: groups: - tee - name: trusted-firmware-m - revision: e9ea674ed02e8ee00548f1bb994d52df23c8068d + revision: 8b3158f4d4023fef9efa5648e6236875a2f058e5 path: modules/tee/tf-m/trusted-firmware-m groups: - tee From cf6e4178e9ed4027213b049a04415a103aa8c044 Mon Sep 17 00:00:00 2001 From: Robert Robinson Date: Fri, 19 Dec 2025 13:00:25 +0000 Subject: [PATCH 1773/3659] modules: tf-m: nordic: Add support for nRF7120 TF-M This commit adds initial support for non secure nRF7120 targets in zephyr. There are important limitations, such as: - The hardware Crypto accelerator is not supported and thus the non secure target is NOT secure for production applications in upstream Zephyr. - The BL2 is not supported, so no DFU is supported with this support Signed-off-by: Robert Robinson --- drivers/flash/Kconfig.nrf_mramc | 1 + modules/trusted-firmware-m/Kconfig.tfm | 1 + .../nordic/include/tfm_peripherals_config.h | 2 ++ .../nordic/nrf7120_cpuapp/CMakeLists.txt | 22 +++++++++++++++++++ .../nordic/nrf7120_cpuapp/config.cmake | 9 ++++++++ .../nordic/nrf7120_cpuapp/cpuarch.cmake | 9 ++++++++ .../nordic/nrf7120_cpuapp/ns/cpuarch_ns.cmake | 10 +++++++++ 7 files changed, 54 insertions(+) create mode 100644 modules/trusted-firmware-m/nordic/nrf7120_cpuapp/CMakeLists.txt create mode 100644 modules/trusted-firmware-m/nordic/nrf7120_cpuapp/config.cmake create mode 100644 modules/trusted-firmware-m/nordic/nrf7120_cpuapp/cpuarch.cmake create mode 100644 modules/trusted-firmware-m/nordic/nrf7120_cpuapp/ns/cpuarch_ns.cmake diff --git a/drivers/flash/Kconfig.nrf_mramc b/drivers/flash/Kconfig.nrf_mramc index 1637baec8969..d968b869c499 100644 --- a/drivers/flash/Kconfig.nrf_mramc +++ b/drivers/flash/Kconfig.nrf_mramc @@ -7,6 +7,7 @@ config SOC_FLASH_NRF_MRAMC bool "Nordic Semiconductor flash driver for MRAM using MRAM Controller" default y + depends on !BUILD_WITH_TFM depends on DT_HAS_NORDIC_NRF_MRAMC_ENABLED select NRFX_MRAMC select FLASH_HAS_DRIVER_ENABLED diff --git a/modules/trusted-firmware-m/Kconfig.tfm b/modules/trusted-firmware-m/Kconfig.tfm index e28c087736e8..a62ef049d2d8 100644 --- a/modules/trusted-firmware-m/Kconfig.tfm +++ b/modules/trusted-firmware-m/Kconfig.tfm @@ -35,6 +35,7 @@ config TFM_BOARD default "$(ZEPHYR_BASE)/modules/trusted-firmware-m/nordic/nrf54l15_cpuapp" if SOC_NRF54L15_CPUAPP default "$(ZEPHYR_BASE)/modules/trusted-firmware-m/nordic/nrf54l10_cpuapp" if SOC_NRF54L10_CPUAPP default "$(ZEPHYR_BASE)/modules/trusted-firmware-m/nordic/nrf54lm20a_cpuapp" if SOC_NRF54LM20A_ENGA_CPUAPP + default "$(ZEPHYR_BASE)/modules/trusted-firmware-m/nordic/nrf7120_cpuapp" if SOC_NRF7120_ENGA_CPUAPP help The board name used for building TFM. Building with TFM requires that TFM has been ported to the given board/SoC. diff --git a/modules/trusted-firmware-m/nordic/include/tfm_peripherals_config.h b/modules/trusted-firmware-m/nordic/include/tfm_peripherals_config.h index 2b50abc57ae1..4e74f537c7d6 100644 --- a/modules/trusted-firmware-m/nordic/include/tfm_peripherals_config.h +++ b/modules/trusted-firmware-m/nordic/include/tfm_peripherals_config.h @@ -37,6 +37,8 @@ extern "C" { #include #elif defined(NRF54L_SERIES) #include +#elif defined(NRF71_SERIES) + #include #else #error "Unknown device." #endif diff --git a/modules/trusted-firmware-m/nordic/nrf7120_cpuapp/CMakeLists.txt b/modules/trusted-firmware-m/nordic/nrf7120_cpuapp/CMakeLists.txt new file mode 100644 index 000000000000..89d36e5a4c73 --- /dev/null +++ b/modules/trusted-firmware-m/nordic/nrf7120_cpuapp/CMakeLists.txt @@ -0,0 +1,22 @@ +# +# Copyright (c) 2025, Nordic Semiconductor ASA. +# +# SPDX-License-Identifier: Apache-2.0 +# + +set(NRF_BOARD_SELECTED True) + +add_subdirectory(${Trusted\ Firmware\ M_SOURCE_DIR}/platform/ext/target/nordic_nrf/common/nrf7120 nrf7120) + +add_subdirectory(.. common) + +install(FILES ${CMAKE_CURRENT_LIST_DIR}/ns/cpuarch_ns.cmake + DESTINATION ${INSTALL_PLATFORM_NS_DIR} + RENAME cpuarch.cmake) + +install(FILES config.cmake + DESTINATION ${INSTALL_PLATFORM_NS_DIR}) + +install(DIRECTORY ${Trusted\ Firmware\ M_SOURCE_DIR}/platform/ext/target/nordic_nrf/nrf7120dk_nrf7120_cpuapp/tests + DESTINATION ${INSTALL_PLATFORM_NS_DIR} +) diff --git a/modules/trusted-firmware-m/nordic/nrf7120_cpuapp/config.cmake b/modules/trusted-firmware-m/nordic/nrf7120_cpuapp/config.cmake new file mode 100644 index 000000000000..c325c6d65391 --- /dev/null +++ b/modules/trusted-firmware-m/nordic/nrf7120_cpuapp/config.cmake @@ -0,0 +1,9 @@ +# +# Copyright (c) 2025, Nordic Semiconductor ASA. +# +# SPDX-License-Identifier: Apache-2.0 +# + +set(NRF_SOC_VARIANT nrf7120 CACHE STRING "nRF SoC Variant") + +include(${PLATFORM_PATH}/common/nrf7120/config.cmake) diff --git a/modules/trusted-firmware-m/nordic/nrf7120_cpuapp/cpuarch.cmake b/modules/trusted-firmware-m/nordic/nrf7120_cpuapp/cpuarch.cmake new file mode 100644 index 000000000000..53be5a39816b --- /dev/null +++ b/modules/trusted-firmware-m/nordic/nrf7120_cpuapp/cpuarch.cmake @@ -0,0 +1,9 @@ +# +# Copyright (c) 2025, Nordic Semiconductor ASA. +# +# SPDX-License-Identifier: Apache-2.0 +# + +set(PLATFORM_PATH platform/ext/target/nordic_nrf) + +include(${PLATFORM_PATH}/common/nrf7120/cpuarch.cmake) diff --git a/modules/trusted-firmware-m/nordic/nrf7120_cpuapp/ns/cpuarch_ns.cmake b/modules/trusted-firmware-m/nordic/nrf7120_cpuapp/ns/cpuarch_ns.cmake new file mode 100644 index 000000000000..54810b354ebe --- /dev/null +++ b/modules/trusted-firmware-m/nordic/nrf7120_cpuapp/ns/cpuarch_ns.cmake @@ -0,0 +1,10 @@ +# +# Copyright (c) 2025, Nordic Semiconductor ASA. +# +# SPDX-License-Identifier: Apache-2.0 +# + +set(PLATFORM_DIR ${CMAKE_CURRENT_LIST_DIR}) +set(PLATFORM_PATH ${CMAKE_CURRENT_LIST_DIR}) + +include(${CMAKE_CURRENT_LIST_DIR}/common/nrf7120/cpuarch.cmake) From bb042f0be8f3f8aceac65988a0a17bc986134a52 Mon Sep 17 00:00:00 2001 From: Robert Robinson Date: Tue, 23 Dec 2025 11:40:47 +0000 Subject: [PATCH 1774/3659] tests: Add support for nRF7120 to CI tests Initial porting of nRF7120 to zephyr requires support for a number of tests that are run as part of the CI. This commit adds the support. Signed-off-by: Robert Robinson --- .../watchdog/boards/nrf7120dk_nrf7120_cpuapp.overlay | 8 ++++++++ samples/drivers/watchdog/sample.yaml | 1 + .../arm/arm_irq_vector_table/src/arm_irq_vector_table.c | 4 ++-- tests/arch/common/gen_isr_table/src/main.c | 5 +++++ tests/arch/common/interrupt/src/nested_irq.c | 6 ++++++ .../boards/nrf7120dk_nrf7120_cpuapp.overlay | 9 +++++++++ .../boards/nrf7120dk_nrf7120_cpuapp_ns.overlay | 7 +++++++ .../boards/nrf7120dk_nrf7120_cpuapp.overlay | 9 +++++++++ tests/drivers/watchdog/wdt_error_cases/src/main.c | 3 ++- tests/drivers/watchdog/wdt_error_cases/testcase.yaml | 1 + tests/lib/cpp/cxx/testcase.yaml | 5 +++-- 11 files changed, 53 insertions(+), 5 deletions(-) create mode 100644 samples/drivers/watchdog/boards/nrf7120dk_nrf7120_cpuapp.overlay create mode 100644 tests/drivers/watchdog/wdt_basic_api/boards/nrf7120dk_nrf7120_cpuapp.overlay create mode 100644 tests/drivers/watchdog/wdt_basic_api/boards/nrf7120dk_nrf7120_cpuapp_ns.overlay create mode 100644 tests/drivers/watchdog/wdt_error_cases/boards/nrf7120dk_nrf7120_cpuapp.overlay diff --git a/samples/drivers/watchdog/boards/nrf7120dk_nrf7120_cpuapp.overlay b/samples/drivers/watchdog/boards/nrf7120dk_nrf7120_cpuapp.overlay new file mode 100644 index 000000000000..cfb41e09b99e --- /dev/null +++ b/samples/drivers/watchdog/boards/nrf7120dk_nrf7120_cpuapp.overlay @@ -0,0 +1,8 @@ +/* + * Copyright 2025 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +&wdt31 { + status = "okay"; +}; diff --git a/samples/drivers/watchdog/sample.yaml b/samples/drivers/watchdog/sample.yaml index 6e3bc1571168..c7fffc99001a 100644 --- a/samples/drivers/watchdog/sample.yaml +++ b/samples/drivers/watchdog/sample.yaml @@ -29,6 +29,7 @@ tests: - nrf54lm20dk/nrf54lm20a/cpuapp/ns - nrf54l15dk/nrf54l15/cpuapp/ns - nrf54l15dk/nrf54l10/cpuapp/ns + - nrf7120dk/nrf7120/cpuapp/ns - bl54l15_dvk/nrf54l10/cpuapp/ns - bl54l15_dvk/nrf54l15/cpuapp/ns - bl54l15u_dvk/nrf54l15/cpuapp/ns diff --git a/tests/arch/arm/arm_irq_vector_table/src/arm_irq_vector_table.c b/tests/arch/arm/arm_irq_vector_table/src/arm_irq_vector_table.c index a6ba3d85d8b8..c971f5c1268c 100644 --- a/tests/arch/arm/arm_irq_vector_table/src/arm_irq_vector_table.c +++ b/tests/arch/arm/arm_irq_vector_table/src/arm_irq_vector_table.c @@ -24,7 +24,7 @@ * the TIMER0 IRQ line, which is used by the system timer. */ #define _ISR_OFFSET (TIMER0_IRQn + 1) -#elif defined(CONFIG_SOC_SERIES_NRF54LX) +#elif defined(CONFIG_SOC_SERIES_NRF54LX) || defined(CONFIG_SOC_SERIES_NRF71) /* For nRF54L Series, use SWI00-02 interrupt lines. */ #define _ISR_OFFSET SWI00_IRQn #elif defined(CONFIG_SOC_SERIES_NRF54HX) || defined(CONFIG_SOC_SERIES_NRF92X) @@ -157,7 +157,7 @@ void timer0_nrf_isr(void); #define TIMER_IRQ_HANDLER timer0_nrf_isr #define TIMER_IRQ_NUM TIMER0_IRQn #elif defined(CONFIG_SOC_SERIES_NRF54LX) || defined(CONFIG_SOC_SERIES_NRF54HX) || \ - defined(CONFIG_SOC_SERIES_NRF92X) + defined(CONFIG_SOC_SERIES_NRF71) || defined(CONFIG_SOC_SERIES_NRF92X) void nrfx_grtc_irq_handler(void); #define TIMER_IRQ_HANDLER nrfx_grtc_irq_handler #define TIMER_IRQ_NUM DT_IRQN(DT_NODELABEL(grtc)) diff --git a/tests/arch/common/gen_isr_table/src/main.c b/tests/arch/common/gen_isr_table/src/main.c index 94efb5b0e436..c280de89d863 100644 --- a/tests/arch/common/gen_isr_table/src/main.c +++ b/tests/arch/common/gen_isr_table/src/main.c @@ -42,6 +42,11 @@ extern const uintptr_t _irq_vector_table[]; #define ISR3_OFFSET 15 #define ISR5_OFFSET 16 #define TRIG_CHECK_SIZE 17 +#elif defined(CONFIG_SOC_SERIES_NRF71) && defined(CONFIG_RISCV_CORE_NORDIC_VPR) +#define ISR1_OFFSET 16 +#define ISR3_OFFSET 21 +#define ISR5_OFFSET 22 +#define TRIG_CHECK_SIZE 23 #elif defined(CONFIG_SOC_NRF9280_CPUPPR) #define ISR1_OFFSET 14 #define ISR3_OFFSET 15 diff --git a/tests/arch/common/interrupt/src/nested_irq.c b/tests/arch/common/interrupt/src/nested_irq.c index ca4cebe98788..87f26e8693a6 100644 --- a/tests/arch/common/interrupt/src/nested_irq.c +++ b/tests/arch/common/interrupt/src/nested_irq.c @@ -73,6 +73,12 @@ #define IRQ0_LINE 14 #define IRQ1_LINE 15 +#define IRQ0_PRIO 1 +#define IRQ1_PRIO 2 +#elif defined(CONFIG_SOC_SERIES_NRF71) && defined(CONFIG_RISCV_CORE_NORDIC_VPR) +#define IRQ0_LINE 19 +#define IRQ1_LINE 20 + #define IRQ0_PRIO 1 #define IRQ1_PRIO 2 #elif defined(CONFIG_SOC_NRF9280_CPUPPR) diff --git a/tests/drivers/watchdog/wdt_basic_api/boards/nrf7120dk_nrf7120_cpuapp.overlay b/tests/drivers/watchdog/wdt_basic_api/boards/nrf7120dk_nrf7120_cpuapp.overlay new file mode 100644 index 000000000000..dc1ea1a9ddc9 --- /dev/null +++ b/tests/drivers/watchdog/wdt_basic_api/boards/nrf7120dk_nrf7120_cpuapp.overlay @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&wdt31 { + status = "okay"; +}; diff --git a/tests/drivers/watchdog/wdt_basic_api/boards/nrf7120dk_nrf7120_cpuapp_ns.overlay b/tests/drivers/watchdog/wdt_basic_api/boards/nrf7120dk_nrf7120_cpuapp_ns.overlay new file mode 100644 index 000000000000..a9bb00b00e2d --- /dev/null +++ b/tests/drivers/watchdog/wdt_basic_api/boards/nrf7120dk_nrf7120_cpuapp_ns.overlay @@ -0,0 +1,7 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "nrf7120dk_nrf7120_cpuapp.overlay" diff --git a/tests/drivers/watchdog/wdt_error_cases/boards/nrf7120dk_nrf7120_cpuapp.overlay b/tests/drivers/watchdog/wdt_error_cases/boards/nrf7120dk_nrf7120_cpuapp.overlay new file mode 100644 index 000000000000..8d3dce3b3800 --- /dev/null +++ b/tests/drivers/watchdog/wdt_error_cases/boards/nrf7120dk_nrf7120_cpuapp.overlay @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&wdt31 { + status = "okay"; +}; diff --git a/tests/drivers/watchdog/wdt_error_cases/src/main.c b/tests/drivers/watchdog/wdt_error_cases/src/main.c index 468118ae4e55..b5b78d94af66 100644 --- a/tests/drivers/watchdog/wdt_error_cases/src/main.c +++ b/tests/drivers/watchdog/wdt_error_cases/src/main.c @@ -45,7 +45,8 @@ /* Align tests to the specific target: */ #if defined(CONFIG_SOC_SERIES_NRF53X) || defined(CONFIG_SOC_SERIES_NRF54LX) || \ - defined(CONFIG_SOC_NRF54H20) || defined(CONFIG_SOC_NRF9280) + defined(CONFIG_SOC_SERIES_NRF71) || defined(CONFIG_SOC_NRF54H20) || \ + defined(CONFIG_SOC_NRF9280) #define WDT_TEST_FLAGS \ (WDT_DISABLE_SUPPORTED | WDT_FLAG_RESET_SOC_SUPPORTED | \ WDT_FLAG_ONLY_ONE_TIMEOUT_VALUE_SUPPORTED | WDT_OPT_PAUSE_IN_SLEEP_SUPPORTED | \ diff --git a/tests/drivers/watchdog/wdt_error_cases/testcase.yaml b/tests/drivers/watchdog/wdt_error_cases/testcase.yaml index c4e8329cf657..dd3ba54adc4c 100644 --- a/tests/drivers/watchdog/wdt_error_cases/testcase.yaml +++ b/tests/drivers/watchdog/wdt_error_cases/testcase.yaml @@ -13,6 +13,7 @@ tests: - nrf54h20dk/nrf54h20/cpurad - nrf54l15dk/nrf54l15/cpuapp - nrf54lm20dk/nrf54lm20a/cpuapp + - nrf7120dk/nrf7120/cpuapp - nrf9280pdk/nrf9280/cpuapp - nrf9280pdk/nrf9280/cpurad - ophelia4ev/nrf54l15/cpuapp diff --git a/tests/lib/cpp/cxx/testcase.yaml b/tests/lib/cpp/cxx/testcase.yaml index 87386b36aa5d..cf32b2b46b4c 100644 --- a/tests/lib/cpp/cxx/testcase.yaml +++ b/tests/lib/cpp/cxx/testcase.yaml @@ -34,7 +34,7 @@ tests: # -std=c++98) cpp.main.cpp98: arch_exclude: posix - # Exclude ARM cores from nRF54H, nRF92n and RF54L series as Nordic HAL is not + # Exclude ARM cores from nRF54H, nRF92n, nRF54L and nRF71 series as Nordic HAL is not # compatible with C++98. # Exclude CONFIG_HAS_RENESAS_RA_FSP and CONFIG_HAS_RENESAS_RZ_FSP as Renesas HALs are not # compatible with C++98. @@ -43,7 +43,8 @@ tests: filter: not CONFIG_HAS_RENESAS_RA_FSP and not CONFIG_HAS_RENESAS_RZ_FSP and not CONFIG_HAS_SILABS_WISECONNECT and not CONFIG_SOC_FAMILY_AMBIQ and - not (CONFIG_CPU_CORTEX_M and (CONFIG_NRF_PLATFORM_HALTIUM or CONFIG_SOC_SERIES_NRF54LX)) + not (CONFIG_CPU_CORTEX_M and (CONFIG_NRF_PLATFORM_HALTIUM or + CONFIG_SOC_SERIES_NRF54LX or CONFIG_SOC_SERIES_NRF71)) build_only: true extra_configs: - CONFIG_STD_CPP98=y From b432178303b1a86ae1193e5ff7a6b657e6b25c41 Mon Sep 17 00:00:00 2001 From: Jacob Schloss Date: Thu, 18 Dec 2025 22:06:26 -0800 Subject: [PATCH 1775/3659] dts: arm: st: h7: Add cryp to STM32H753/H755 Add cryp block to STM32H753, as in STM32H755. Signed-off-by: Jacob Schloss --- dts/arm/st/h7/stm32h753.dtsi | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/dts/arm/st/h7/stm32h753.dtsi b/dts/arm/st/h7/stm32h753.dtsi index f3061e843fa1..3bba3a40134b 100644 --- a/dts/arm/st/h7/stm32h753.dtsi +++ b/dts/arm/st/h7/stm32h753.dtsi @@ -9,5 +9,14 @@ / { soc { compatible = "st,stm32h753", "st,stm32h7", "simple-bus"; + + cryp: cryp@48021000 { + compatible = "st,stm32-cryp"; + reg = <0x48021000 0x400>; + clocks = <&rcc STM32_CLOCK(AHB2, 4)>; + resets = <&rctl STM32_RESET(AHB2, 4)>; + interrupts = <79 0>; + status = "disabled"; + }; }; }; From da0e264c9d47795960089a67cf6b20e02402c968 Mon Sep 17 00:00:00 2001 From: Jacob Schloss Date: Thu, 18 Dec 2025 23:57:52 -0800 Subject: [PATCH 1776/3659] dts: arm: st: h7: Add missing cryp reset controllers Add missing reset to h755 / h757 cryp block. Signed-off-by: Jacob Schloss --- dts/arm/st/h7/stm32h755.dtsi | 1 + dts/arm/st/h7/stm32h757.dtsi | 1 + 2 files changed, 2 insertions(+) diff --git a/dts/arm/st/h7/stm32h755.dtsi b/dts/arm/st/h7/stm32h755.dtsi index e1269ed5565b..6df371513e45 100644 --- a/dts/arm/st/h7/stm32h755.dtsi +++ b/dts/arm/st/h7/stm32h755.dtsi @@ -15,6 +15,7 @@ compatible = "st,stm32-cryp"; reg = <0x48021000 0x400>; clocks = <&rcc STM32_CLOCK(AHB2, 4)>; + resets = <&rctl STM32_RESET(AHB2, 4)>; interrupts = <79 0>; status = "disabled"; }; diff --git a/dts/arm/st/h7/stm32h757.dtsi b/dts/arm/st/h7/stm32h757.dtsi index 2d02e456de44..7b13c7a55b15 100644 --- a/dts/arm/st/h7/stm32h757.dtsi +++ b/dts/arm/st/h7/stm32h757.dtsi @@ -14,6 +14,7 @@ compatible = "st,stm32-cryp"; reg = <0x48021000 0x400>; clocks = <&rcc STM32_CLOCK(AHB2, 4)>; + resets = <&rctl STM32_RESET(AHB2, 4)>; interrupts = <79 0>; status = "disabled"; }; From 4342789ee4287540365853edd5486386004456f8 Mon Sep 17 00:00:00 2001 From: Jacob Schloss Date: Fri, 19 Dec 2025 00:12:48 -0800 Subject: [PATCH 1777/3659] boards: st: nucleo_h753zi: enable cryp node Enable cryp on board nucleo_h753zi. Signed-off-by: Jacob Schloss --- boards/st/nucleo_h753zi/nucleo_h753zi.dts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/boards/st/nucleo_h753zi/nucleo_h753zi.dts b/boards/st/nucleo_h753zi/nucleo_h753zi.dts index f69890628496..cfeab4123f89 100644 --- a/boards/st/nucleo_h753zi/nucleo_h753zi.dts +++ b/boards/st/nucleo_h753zi/nucleo_h753zi.dts @@ -275,3 +275,7 @@ zephyr_udc0: &usbotg_fs { &iwdg1 { status = "okay"; }; + +&cryp { + status = "okay"; +}; From f51e2aaf393fb5cc2fd9ac68534345945e3c76b2 Mon Sep 17 00:00:00 2001 From: Jacob Schloss Date: Tue, 13 Jan 2026 10:37:10 -0800 Subject: [PATCH 1778/3659] tests: crypto: crypto_aes: enable nucleo_h753zi platform Enable nucleo_h753zi platform for crypto_aes tests. Signed-off-by: Jacob Schloss --- tests/crypto/crypto_aes/src/main.c | 2 ++ tests/crypto/crypto_aes/testcase.yaml | 1 + 2 files changed, 3 insertions(+) diff --git a/tests/crypto/crypto_aes/src/main.c b/tests/crypto/crypto_aes/src/main.c index 3da74aa964af..f64d63f68ecf 100644 --- a/tests/crypto/crypto_aes/src/main.c +++ b/tests/crypto/crypto_aes/src/main.c @@ -14,6 +14,8 @@ #define CRYPTO_DRV_NAME CONFIG_CRYPTO_MBEDTLS_SHIM_DRV_NAME #elif CONFIG_CRYPTO_ESP32_AES #define CRYPTO_DEV_COMPAT espressif_esp32_aes +#elif CONFIG_CRYPTO_STM32 +#define CRYPTO_DEV_COMPAT st_stm32_cryp #else #error "You need to enable one crypto device" #endif diff --git a/tests/crypto/crypto_aes/testcase.yaml b/tests/crypto/crypto_aes/testcase.yaml index 64d488453258..6dff578bec79 100644 --- a/tests/crypto/crypto_aes/testcase.yaml +++ b/tests/crypto/crypto_aes/testcase.yaml @@ -14,4 +14,5 @@ tests: - esp32c3_devkitc - esp32c6_devkitc/esp32c6/hpcore - esp32h2_devkitm + - nucleo_h753zi tags: crypto From 9d5731d0d0a9ba9095e33322a299984493254aa9 Mon Sep 17 00:00:00 2001 From: Gerson Fernando Budke Date: Sat, 20 Dec 2025 13:33:50 +0100 Subject: [PATCH 1779/3659] west.yml: Replace native_posix by native_sim in tests Repalce the native_posix by native_sim in tests and reformat platform list to allow twister to correct recognize the platforms. Fixes #101300 Signed-off-by: Gerson Fernando Budke --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index ecb086954aca..a11238717de4 100644 --- a/west.yml +++ b/west.yml @@ -394,7 +394,7 @@ manifest: revision: ac80c3bf2b88deec86d129654fbde09761582342 path: modules/lib/uoscore-uedhoc - name: zcbor - revision: 9b07780aca6fb21f82a241ba386ad9b379809337 + revision: 9164bd18dcd88ff9d9ef98279501fc1093571017 path: modules/lib/zcbor # zephyr-keep-sorted-stop From 18d6e8c8b15e8ac25d424e69705875f85a57ffa2 Mon Sep 17 00:00:00 2001 From: Lyle Zhu Date: Mon, 5 Jan 2026 19:18:54 +0800 Subject: [PATCH 1780/3659] drivers: bluetooth: hci: nxp: enable calibration data by default Enable HCI_NXP_SET_CAL_DATA and HCI_NXP_SET_CAL_DATA_ANNEX100 by default for NW612 and IW416 modules to ensure proper calibration during HCI initialization. Signed-off-by: Lyle Zhu --- drivers/bluetooth/hci/Kconfig.nxp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/bluetooth/hci/Kconfig.nxp b/drivers/bluetooth/hci/Kconfig.nxp index f16760c69826..4db2c08cd83c 100644 --- a/drivers/bluetooth/hci/Kconfig.nxp +++ b/drivers/bluetooth/hci/Kconfig.nxp @@ -14,11 +14,13 @@ config HCI_NXP_ENABLE_AUTO_SLEEP config HCI_NXP_SET_CAL_DATA bool "Bluetooth Controller calibration data" + default y if BT_NXP_NW612 || BT_NXP_IW416 help If enabled, the Host will send calibration data to the Bluetooth Controller during HCI init. config HCI_NXP_SET_CAL_DATA_ANNEX100 bool "Bluetooth Controller calibration data annex 100" + default y if BT_NXP_NW612 || BT_NXP_IW416 help If enabled, the Host will send calibration data annex 100 to the Bluetooth Controller during HCI init. From 2ba21af69dc8074a62205ca08e690afa0fdf33f8 Mon Sep 17 00:00:00 2001 From: Sylvio Alves Date: Wed, 7 Jan 2026 10:56:14 -0300 Subject: [PATCH 1781/3659] runners: openocd: add BIN file flash support Add --use-bin and --flash-address arguments to allow flashing BIN files at a specific address. This is needed for targets like ESP32 where HEX files contain virtual addresses (due to MMU mapping) rather than physical flash addresses. The new do_flash_bin() method uses the load command with the BIN file path and flash address, similar to how ELF flashing works. Signed-off-by: Sylvio Alves --- scripts/west_commands/runners/openocd.py | 85 +++++++++++++++++++++--- 1 file changed, 75 insertions(+), 10 deletions(-) diff --git a/scripts/west_commands/runners/openocd.py b/scripts/west_commands/runners/openocd.py index 31be09bb3fe2..cf22b8ad9362 100644 --- a/scripts/west_commands/runners/openocd.py +++ b/scripts/west_commands/runners/openocd.py @@ -51,8 +51,8 @@ class OpenOcdBinaryRunner(ZephyrBinaryRunner): def __init__(self, cfg, pre_init=None, reset_halt_cmd=DEFAULT_OPENOCD_RESET_HALT_CMD, pre_load=None, erase_cmd=None, load_cmd=None, verify_cmd=None, post_verify=None, do_verify=False, do_verify_only=False, do_erase=False, - tui=None, config=None, serial=None, use_elf=None, - no_halt=False, no_init=False, no_targets=False, + tui=None, config=None, serial=None, image_type=None, + flash_address=None, no_halt=False, no_init=False, no_targets=False, tcl_port=DEFAULT_OPENOCD_TCL_PORT, telnet_port=DEFAULT_OPENOCD_TELNET_PORT, gdb_port=DEFAULT_OPENOCD_GDB_PORT, @@ -116,7 +116,8 @@ def __init__(self, cfg, pre_init=None, reset_halt_cmd=DEFAULT_OPENOCD_RESET_HALT self.init_arg = [] if no_init else ['-c init'] self.targets_arg = [] if no_targets else ['-c targets'] self.serial = ['-c set _ZEPHYR_BOARD_SERIAL ' + serial] if serial else [] - self.use_elf = use_elf + self.image_type = image_type + self.flash_address = flash_address self.gdb_init = gdb_init self.load_arg = ['-ex', 'load'] if load else [] self.target_handle = target_handle @@ -140,8 +141,18 @@ def do_add_parser(cls, parser): parser.add_argument('--serial', default="", help='''if given, selects FTDI instance by its serial number, defaults to empty''') - parser.add_argument('--use-elf', default=False, action='store_true', - help='if given, Elf file will be used for loading instead of HEX image') + # Multiple flags share the same dest; last one wins. + parser.add_argument('--use-hex', action='store_const', + dest='image_type', const='hex', + help='use HEX file for loading (default)') + parser.add_argument('--use-elf', action='store_const', + dest='image_type', const='elf', + help='use ELF file for loading instead of HEX') + parser.add_argument('--use-bin', action='store_const', + dest='image_type', const='bin', + help='use BIN file for loading instead of HEX') + parser.add_argument('--flash-address', default=None, + help='flash address to use when flashing BIN file') # Options for flashing: parser.add_argument('--cmd-pre-init', action='append', help='''Command to run before calling init; @@ -209,7 +220,8 @@ def do_create(cls, cfg, args): verify_cmd=args.cmd_verify, post_verify=args.cmd_post_verify, do_verify=args.verify, do_verify_only=args.verify_only, do_erase=args.erase, tui=args.tui, config=args.config, serial=args.serial, - use_elf=args.use_elf, no_halt=args.no_halt, no_init=args.no_init, + image_type=args.image_type, + flash_address=args.flash_address, no_halt=args.no_halt, no_init=args.no_init, no_targets=args.no_targets, tcl_port=args.tcl_port, telnet_port=args.telnet_port, gdb_port=args.gdb_port, gdb_client_port=args.gdb_client_port, gdb_init=args.gdb_init, @@ -259,10 +271,13 @@ def do_run(self, command, **kwargs): self.cfg_cmd.append('-f') self.cfg_cmd.append(i) - if command == 'flash' and self.use_elf: - self.do_flash_elf(**kwargs) - elif command == 'flash': - self.do_flash(**kwargs) + if command == 'flash': + if self.image_type == 'elf': + self.do_flash_elf(**kwargs) + elif self.image_type == 'bin': + self.do_flash_bin(**kwargs) + else: + self.do_flash(**kwargs) elif command in ('attach', 'debug', 'rtt'): self.do_attach_debug_rtt(command, **kwargs) elif command == 'load': @@ -329,6 +344,56 @@ def do_flash(self, **kwargs): '-c', 'shutdown']) self.check_call(cmd) + def do_flash_bin(self, **kwargs): + self.ensure_output('bin') + if self.load_cmd is None: + raise ValueError('Cannot flash; load command is missing') + if self.flash_address is None: + raise ValueError('Cannot flash BIN; flash address is missing (use --flash-address)') + + bin_name = Path(self.cfg.bin_file).as_posix() + + self.logger.info(f'Flashing file: {bin_name}') + + pre_init_cmd = [] + pre_load_cmd = [] + post_verify_cmd = [] + for i in self.pre_init: + pre_init_cmd.append("-c") + pre_init_cmd.append(i) + + for i in self.pre_load: + pre_load_cmd.append("-c") + pre_load_cmd.append(i) + + for i in self.post_verify: + post_verify_cmd.append("-c") + post_verify_cmd.append(i) + + load_image = [] + if not self.do_verify_only: + load_image = ['-c', self.reset_halt_cmd] + if self.do_erase and self.erase_cmd is None: + self.logger.error('--erase not supported for target without --cmd-erase') + return + if self.do_erase: + load_image += [x for cmd in self.erase_cmd for x in ("-c", cmd)] + load_image += ['-c', f'{self.load_cmd} {bin_name} {self.flash_address}'] + + verify_image = [] + if (self.do_verify or self.do_verify_only) and self.verify_cmd: + verify_image = ['-c', self.reset_halt_cmd, + '-c', f'{self.verify_cmd} {bin_name} {self.flash_address}'] + + cmd = (self.openocd_cmd + self.serial + self.cfg_cmd + + pre_init_cmd + self.init_arg + self.targets_arg + + pre_load_cmd + load_image + + verify_image + + post_verify_cmd + + ['-c', 'reset run', + '-c', 'shutdown']) + self.check_call(cmd) + def do_flash_elf(self, **kwargs): if self.elf_name is None: raise ValueError('Cannot debug; no .elf specified') From cb196db575dca3f3d983f389b3517ab982bc7b00 Mon Sep 17 00:00:00 2001 From: Sylvio Alves Date: Tue, 13 Jan 2026 22:34:34 -0300 Subject: [PATCH 1782/3659] boards: esp32: add openocd flash support Configure ESP32 boards to use OpenOCD for flashing with BIN files. The --flash-address argument is combined with its value to avoid YAML parsing issues where hex values like 0x0 are parsed as integers. Signed-off-by: Sylvio Alves --- boards/common/esp32.board.cmake | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/boards/common/esp32.board.cmake b/boards/common/esp32.board.cmake index 7c9587bea8e9..ca97aa20c3f5 100644 --- a/boards/common/esp32.board.cmake +++ b/boards/common/esp32.board.cmake @@ -7,9 +7,15 @@ board_runner_args(openocd --no-halt --no-targets --no-load --target-handle _TAR board_runner_args(openocd --gdb-init "set remote hardware-watchpoint-limit 2") board_runner_args(openocd --gdb-init "maintenance flush register-cache") +board_runner_args(openocd --gdb-init "mon esp appimage_offset ${CONFIG_FLASH_LOAD_OFFSET}") board_runner_args(openocd --gdb-init "mon reset halt") board_runner_args(openocd --gdb-init "thb main") +board_runner_args(openocd --use-bin) +board_runner_args(openocd "--flash-address=${CONFIG_FLASH_LOAD_OFFSET}") +board_runner_args(openocd --cmd-load "program_esp") +board_runner_args(openocd --cmd-verify "esp verify_bank_hash 0") + set(ESP_IDF_PATH ${ZEPHYR_HAL_ESPRESSIF_MODULE_DIR}) assert(ESP_IDF_PATH "ESP_IDF_PATH is not set") From 85e1ea0259152f24d677a71c5086e61368c69b3a Mon Sep 17 00:00:00 2001 From: Sylvio Alves Date: Tue, 13 Jan 2026 22:35:22 -0300 Subject: [PATCH 1783/3659] runners: openocd: refactor flash methods into single do_flash Add _openocd_cmd() helper method to reduce code duplication when building openocd command lists. Consolidate do_flash, do_flash_elf, and do_flash_bin into a single do_flash method using match statement on image_type parameter. Signed-off-by: Sylvio Alves --- scripts/west_commands/runners/openocd.py | 228 ++++++++--------------- 1 file changed, 80 insertions(+), 148 deletions(-) diff --git a/scripts/west_commands/runners/openocd.py b/scripts/west_commands/runners/openocd.py index cf22b8ad9362..e78c235e4038 100644 --- a/scripts/west_commands/runners/openocd.py +++ b/scripts/west_commands/runners/openocd.py @@ -272,12 +272,7 @@ def do_run(self, command, **kwargs): self.cfg_cmd.append(i) if command == 'flash': - if self.image_type == 'elf': - self.do_flash_elf(**kwargs) - elif self.image_type == 'bin': - self.do_flash_bin(**kwargs) - else: - self.do_flash(**kwargs) + self.do_flash(**kwargs) elif command in ('attach', 'debug', 'rtt'): self.do_attach_debug_rtt(command, **kwargs) elif command == 'load': @@ -285,155 +280,92 @@ def do_run(self, command, **kwargs): else: self.do_debugserver(**kwargs) - def do_flash(self, **kwargs): - self.ensure_output('hex') - if self.load_cmd is None: - raise ValueError('Cannot flash; load command is missing') - if self.verify_cmd is None: - raise ValueError('Cannot flash; verify command is missing') - - # openocd doesn't cope with Windows path names, so convert - # them to POSIX style just to be sure. - hex_name = Path(self.cfg.hex_file).as_posix() - - self.logger.info(f'Flashing file: {hex_name}') - - pre_init_cmd = [] - pre_load_cmd = [] - post_verify_cmd = [] - for i in self.pre_init: - pre_init_cmd.append("-c") - pre_init_cmd.append(i) + def _openocd_cmd(self, cmd_list): + """Convert a list of commands to openocd -c arguments.""" + return [x for cmd in cmd_list for x in ("-c", cmd)] - for i in self.pre_load: - pre_load_cmd.append("-c") - pre_load_cmd.append(i) - - for i in self.post_verify: - post_verify_cmd.append("-c") - post_verify_cmd.append(i) - - load_image = [] - if not self.do_verify_only: - # Halt target - load_image = ['-c', self.reset_halt_cmd] - # Perform any erase operations - if self.do_erase: - if self.erase_cmd is None: - self.logger.error('--erase not supported for target without --cmd-erase') - return - for erase_cmd in self.erase_cmd: - load_image += ["-c", erase_cmd] - # Trim the "erase" from "flash write_image erase" since a mass erase is already done - if self.load_cmd.endswith(' erase'): - self.load_cmd = self.load_cmd[:-6] - # Load image - load_image +=['-c', self.load_cmd + ' ' + hex_name] - - verify_image = [] - if self.do_verify or self.do_verify_only: - verify_image = ['-c', self.reset_halt_cmd, - '-c', self.verify_cmd + ' ' + hex_name] - - cmd = (self.openocd_cmd + self.serial + self.cfg_cmd + - pre_init_cmd + self.init_arg + self.targets_arg + - pre_load_cmd + load_image + - verify_image + - post_verify_cmd + - ['-c', 'reset run', - '-c', 'shutdown']) - self.check_call(cmd) - - def do_flash_bin(self, **kwargs): - self.ensure_output('bin') - if self.load_cmd is None: - raise ValueError('Cannot flash; load command is missing') - if self.flash_address is None: - raise ValueError('Cannot flash BIN; flash address is missing (use --flash-address)') - - bin_name = Path(self.cfg.bin_file).as_posix() - - self.logger.info(f'Flashing file: {bin_name}') - - pre_init_cmd = [] - pre_load_cmd = [] - post_verify_cmd = [] - for i in self.pre_init: - pre_init_cmd.append("-c") - pre_init_cmd.append(i) + def do_flash(self, **kwargs): + match self.image_type: + case 'elf': + if self.elf_name is None: + raise ValueError('Cannot flash; no .elf specified') + image_file = self.elf_name + with open(image_file, 'rb') as f: + ep_addr = f"0x{ELFFile(f).header['e_entry']:016x}" + + case 'bin': + self.ensure_output('bin') + if self.load_cmd is None: + raise ValueError('Cannot flash; load command is missing') + if self.flash_address is None: + raise ValueError('Cannot flash; flash address is missing') + image_file = Path(self.cfg.bin_file).as_posix() + + case _: # 'hex' or None (default) + self.ensure_output('hex') + if self.load_cmd is None: + raise ValueError('Cannot flash; load command is missing') + if self.verify_cmd is None: + raise ValueError('Cannot flash; verify command is missing') + image_file = Path(self.cfg.hex_file).as_posix() + + self.logger.info(f'Flashing file: {image_file}') + + pre_init_cmd = self._openocd_cmd(self.pre_init) + + if self.image_type == 'elf': + pre_load_cmd = [] + load_image = [] + if not self.do_verify_only: + pre_load_cmd = self._openocd_cmd(self.pre_load) + load_image = ['-c', self.reset_halt_cmd, + '-c', 'load_image ' + image_file] + + verify_image = [] + post_verify_cmd = [] + if self.do_verify or self.do_verify_only: + verify_image = ['-c', 'verify_image ' + image_file] + post_verify_cmd = self._openocd_cmd(self.post_verify) + + epilogue = ['-c', 'resume ' + ep_addr, '-c', 'shutdown'] - for i in self.pre_load: - pre_load_cmd.append("-c") - pre_load_cmd.append(i) - - for i in self.post_verify: - post_verify_cmd.append("-c") - post_verify_cmd.append(i) - - load_image = [] - if not self.do_verify_only: - load_image = ['-c', self.reset_halt_cmd] - if self.do_erase and self.erase_cmd is None: - self.logger.error('--erase not supported for target without --cmd-erase') - return - if self.do_erase: - load_image += [x for cmd in self.erase_cmd for x in ("-c", cmd)] - load_image += ['-c', f'{self.load_cmd} {bin_name} {self.flash_address}'] - - verify_image = [] - if (self.do_verify or self.do_verify_only) and self.verify_cmd: - verify_image = ['-c', self.reset_halt_cmd, - '-c', f'{self.verify_cmd} {bin_name} {self.flash_address}'] + else: + pre_load_cmd = self._openocd_cmd(self.pre_load) + post_verify_cmd = self._openocd_cmd(self.post_verify) + + load_image = [] + if not self.do_verify_only: + load_image = ['-c', self.reset_halt_cmd] + if self.do_erase: + if self.erase_cmd is None: + self.logger.error('--erase not supported for target without --cmd-erase') + return + load_image += self._openocd_cmd(self.erase_cmd) + if self.image_type != 'bin' and self.load_cmd.endswith(' erase'): + self.load_cmd = self.load_cmd[:-6] + + if self.image_type == 'bin': + load_image += ['-c', f'{self.load_cmd} {image_file} {self.flash_address}'] + else: + load_image += ['-c', f'{self.load_cmd} {image_file}'] + + verify_image = [] + if self.do_verify or self.do_verify_only: + if self.image_type == 'bin': + if self.verify_cmd: + verify_cmd = f'{self.verify_cmd} {image_file} {self.flash_address}' + verify_image = ['-c', self.reset_halt_cmd, '-c', verify_cmd] + else: + verify_image = ['-c', self.reset_halt_cmd, + '-c', f'{self.verify_cmd} {image_file}'] + + epilogue = ['-c', 'reset run', '-c', 'shutdown'] cmd = (self.openocd_cmd + self.serial + self.cfg_cmd + pre_init_cmd + self.init_arg + self.targets_arg + pre_load_cmd + load_image + - verify_image + - post_verify_cmd + - ['-c', 'reset run', - '-c', 'shutdown']) - self.check_call(cmd) - - def do_flash_elf(self, **kwargs): - if self.elf_name is None: - raise ValueError('Cannot debug; no .elf specified') - - # Extract entry point address from Elf to use it later with - # "resume" command of OpenOCD. - with open(self.elf_name, 'rb') as f: - ep_addr = f"0x{ELFFile(f).header['e_entry']:016x}" - - pre_init_cmd = [] - for i in self.pre_init: - pre_init_cmd.append("-c") - pre_init_cmd.append(i) - - pre_load_cmd = [] - load_image = [] - if not self.do_verify_only: - for i in self.pre_load: - pre_load_cmd.append("-c") - pre_load_cmd.append(i) - load_image = ['-c', 'load_image ' + self.elf_name] - - verify_image = [] - post_verify_cmd = [] - if self.do_verify or self.do_verify_only: - verify_image = ['-c', 'verify_image ' + self.elf_name] - for i in self.post_verify: - post_verify_cmd.append("-c") - post_verify_cmd.append(i) - - prologue = ['-c', 'resume ' + ep_addr, - '-c', 'shutdown'] - - cmd = (self.openocd_cmd + self.serial + self.cfg_cmd + - pre_init_cmd + self.init_arg + self.targets_arg + - pre_load_cmd + ['-c', self.reset_halt_cmd] + - load_image + verify_image + post_verify_cmd + - prologue) - + epilogue) self.check_call(cmd) def do_attach_debug_rtt(self, command, **kwargs): From 6d5140780350c1551ebd1a6b1ce9b9e49cb67f8e Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Mon, 12 Jan 2026 16:31:36 +0100 Subject: [PATCH 1784/3659] net: tcp: Fix possible assertion when peer advertises zero window If peer lowered its receive window and advertised zero-window length, TCP stack would pause the retransmission timer until non-empty window is advertised again. This however could trigger an assertion, that verified that the retransmission timer is running whenever there is data to transmit. Add an exception to the assertion for the zero-window case. Signed-off-by: Robert Lubos --- subsys/net/ip/tcp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/net/ip/tcp.c b/subsys/net/ip/tcp.c index d67a13e33e44..529f1ec559ca 100644 --- a/subsys/net/ip/tcp.c +++ b/subsys/net/ip/tcp.c @@ -3289,7 +3289,7 @@ static enum net_verdict tcp_in(struct tcp *conn, struct net_pkt *pkt) } } #endif - NET_ASSERT((conn->send_data_total == 0) || + NET_ASSERT((conn->send_data_total == 0) || (conn->send_win == 0) || k_work_delayable_is_pending(&conn->send_data_timer), "conn: %p, Missing a subscription " "of the send_data queue timer", conn); From 93c0172d4d631b3872ccd9f23a789b8605704ce0 Mon Sep 17 00:00:00 2001 From: Fabrice DJIATSA Date: Fri, 9 Jan 2026 17:10:07 +0100 Subject: [PATCH 1785/3659] boards: st: add netif:eth twister support for f207zg The Twister netif:eth was missing on the STM32F207ZG board, and hence it was not built against net tests/samples Additionally,sort the supported peripherals in alphabetical order. Signed-off-by: Fabrice DJIATSA --- boards/st/nucleo_f207zg/nucleo_f207zg.yaml | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/boards/st/nucleo_f207zg/nucleo_f207zg.yaml b/boards/st/nucleo_f207zg/nucleo_f207zg.yaml index 3c441c4311bb..81b6bb365468 100644 --- a/boards/st/nucleo_f207zg/nucleo_f207zg.yaml +++ b/boards/st/nucleo_f207zg/nucleo_f207zg.yaml @@ -8,22 +8,23 @@ toolchain: - zephyr - gnuarmemb supported: + - adc - arduino_gpio - arduino_i2c - arduino_spi - - i2c - - spi - - gpio + - backup_sram - can - - usb_device - - watchdog - counter - - adc - dac - - backup_sram + - dma + - gpio + - i2c + - netif:eth - pwm - rng - - dma - rtc + - spi + - usb_device - usbd + - watchdog vendor: st From 59206e41322e0f35efa40081a4efe1e8a43ae67c Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 14 Jan 2026 13:03:16 +0100 Subject: [PATCH 1786/3659] doc: net: http_server: Update header capture code snippet Update outdated code snippet for the header capture feature in HTTP server docs. Signed-off-by: Robert Lubos --- doc/connectivity/networking/api/http_server.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/connectivity/networking/api/http_server.rst b/doc/connectivity/networking/api/http_server.rst index a9d76bba89a0..fc32dae39a42 100644 --- a/doc/connectivity/networking/api/http_server.rst +++ b/doc/connectivity/networking/api/http_server.rst @@ -495,7 +495,8 @@ from within the dynamic resource callback: HTTP_SERVER_REGISTER_HEADER_CAPTURE(capture_user_agent, "User-Agent"); static int dyn_handler(struct http_client_ctx *client, enum http_transaction_status status, - uint8_t *buffer, size_t len, void *user_data) + const struct http_request_ctx *request_ctx, + struct http_response_ctx *response_ctx, void *user_data) { size_t header_count = client->header_capture_ctx.count; const struct http_header *headers = client->header_capture_ctx.headers; From caa8079a5362cd0437ec4d74c888077857df1a9c Mon Sep 17 00:00:00 2001 From: Sylvio Alves Date: Wed, 14 Jan 2026 09:46:10 -0300 Subject: [PATCH 1787/3659] tests: debug: coredump: use k_panic() for Espressif SoCs Espressif RISC-V chips (ESP32-C3, ESP32-C6, etc.) with PMP enabled use dynamic PMP mode (CONFIG_PMP_NO_LOCK_GLOBAL). In this mode, null pointer dereference to address 0 causes a bus hang instead of generating a clean exception, since address 0 is outside any valid memory region and there's no PMP entry protecting it. Use k_panic() instead, which reliably triggers the coredump path on all Espressif chips. Signed-off-by: Sylvio Alves --- tests/subsys/debug/coredump/src/main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/subsys/debug/coredump/src/main.c b/tests/subsys/debug/coredump/src/main.c index 4903261bc862..191bc2287fa7 100644 --- a/tests/subsys/debug/coredump/src/main.c +++ b/tests/subsys/debug/coredump/src/main.c @@ -43,6 +43,7 @@ __no_optimization void func_3(uint32_t *addr) defined(CONFIG_BOARD_RISCV32_VIRTUAL) || \ defined(CONFIG_SOC_FAMILY_INTEL_ISH) || \ defined(CONFIG_SOC_FAMILY_INTEL_ADSP) || \ + defined(CONFIG_SOC_FAMILY_ESPRESSIF_ESP32) || \ defined(CONFIG_SOC_FAMILY_OPENHWGROUP_CVA6) /* clang-format on */ ARG_UNUSED(addr); From 8e4a55cedb09f01e47b47eed705be283a47eabc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Thu, 8 Jan 2026 22:14:05 +0100 Subject: [PATCH 1788/3659] doc: contribute: add Doxygen guidelines MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add Doxygen guidelines to help maintain code documentation consistency across the project in particular for constructs or commands that are Zephyr specific, such as properly documenting API symbols that are gated by Kconfig. Signed-off-by: Benjamin Cabé --- doc/contribute/documentation/guidelines.rst | 3 + doc/contribute/style/doxygen.rst | 357 ++++++++++++++++++++ doc/contribute/style/index.rst | 1 + doc/develop/api/design_guidelines.rst | 8 +- 4 files changed, 366 insertions(+), 3 deletions(-) create mode 100644 doc/contribute/style/doxygen.rst diff --git a/doc/contribute/documentation/guidelines.rst b/doc/contribute/documentation/guidelines.rst index 7a36deb8fa85..c07049d0717f 100644 --- a/doc/contribute/documentation/guidelines.rst +++ b/doc/contribute/documentation/guidelines.rst @@ -30,6 +30,9 @@ This document provides a quick reference for commonly used reST and Sphinx-defined directives and roles used to create the documentation you're reading. +For instructions regarding writing good C API documentation, see +:ref:`doxygen_style`. + Content Structure ***************** diff --git a/doc/contribute/style/doxygen.rst b/doc/contribute/style/doxygen.rst new file mode 100644 index 000000000000..eafc038e425c --- /dev/null +++ b/doc/contribute/style/doxygen.rst @@ -0,0 +1,357 @@ +.. _doxygen_style: + +Doxygen Style Guidelines +######################## + +The Zephyr Project uses `Doxygen`_ to generate API documentation from source code comments. This +guide defines the conventions for documenting Zephyr public APIs consistently. + +All the `Doxygen commands`_ are available for use even if they don't explicitly appear in this +document. + +.. _Doxygen: https://www.doxygen.nl/ +.. _Doxygen commands: https://www.doxygen.nl/manual/commands.html + +To build and preview Zephyr's Doxygen documentation locally, refer to :ref:`zephyr_doc`. + +General Rules +************* + +All :term:`public header files and their public API symbols ` (functions, structs, +enums, unions, typedefs, macros, and global variables): + +- Must be fully documented (see :ref:`doxygen_internals` for exceptions) +- Must belong to at least one Doxygen group (see :ref:`doxygen_groups`) + +You must use the following syntax when documenting public APIs: + +- Use ``/**`` to start a block comment and ``*/`` to end it. +- Use ``/**<`` for trailing comments on the same line as a symbol. +- Use ``@`` (not ``\``) for Doxygen commands (e.g., ``@param`` not ``\param``). +- The ``@brief`` command is optional. If not used, the first sentence (ending with a period) is + treated as the brief description. + +Constructs meant only for internal use must be hidden from the public documentation, as described +in :ref:`doxygen_internals`. + +What to document +================ + +For any API element that accepts, returns, or stores a value (function parameters, return values, +struct/union members, enum values, typedefs, and macros), their documentation must describe the +following items when applicable: + +Semantics + What this element represents and how callers/users should interpret it. Don't restate the + identifier or the C type. + + Example: + + - Avoid: ``@param timeout Timeout value in ms.`` + - Prefer: ``@param timeout Maximum time to wait before returning, in milliseconds.`` + +Valid values + What values are accepted, and how they are interpreted. Specify one or more of the following: + + - Range: minimum/maximum values (for example, the type is ``uint8_t`` but only 0–100 are valid). + - Discrete set: permitted values, when only a subset is allowed. + - Enum: whether the value must be a valid member of a given enum (and whether all enumerators are + allowed or only a subset). + - Flags/bitmasks: which bits are valid and whether combinations are allowed. + - Nullability: whether ``NULL`` is allowed for pointer values, and what it means. + +Units + When the value represents a quantity, specify the unit and reference (for example, milliseconds vs + ticks, Hertz, bytes). Use SI unit symbols when applicable, and write a space between the number + and the unit symbol (for example, ``10 ms``). + +Representation + Any non-obvious encoding or scaling (for example, fixed-point scale, Q format, split integer and + fractional fields, endianness requirements). + +Ownership and lifetime + For pointers/buffers, state who allocates/frees and how long the memory must remain valid. Note + required size/alignment when relevant. + +Writing style +============= + +Brief descriptions should use the imperative mood (a verb phrase) rather than third-person prose. +This keeps API summaries consistent and scannable. + +- Avoid: "Transmits data through a pipe.", "This function gets the device state.". +- Prefer: "Transmit data through a pipe.", "Get the device state.", "Initialize the subsystem.". + +Parameter and member descriptions may be sentence fragments, but they should remain descriptive and +avoid repeating the parameter/member name. + + +.. _doxygen_groups: + +Groups +****** + +Groups organize related symbols into a hierarchy that helps users navigate the API. + +- Define each group once with ``@defgroup``. + + - The provided title should be a short, descriptive name for the group. + As groups inherently collapse various interfaces/API together, do *not* use "API" or "Interface" + (or any other variant of these) terms in the title, as this would be redundant. + - The brief description of the group should not paraphrase its title. + +- Group names use `snake_case `_. +- Use ``@ingroup`` to specify the parent group(s) a group belongs to. + +Example: + +.. code-block:: c + :emphasize-lines: 2,3 + + /** + * @defgroup mqtt_socket MQTT Client library + * @ingroup networking + * @since 1.14 + * @version 0.8.0 + * @{ + */ + + /* documented contents of the MQTT header file */ + + /** @} */ + +.. note:: + + A group may belong to multiple parent groups, so you may have multiple ``@ingroup`` commands. + For example, device driver emulators typically appear both in "Emulator Interfaces" and "Device + drivers" groups. See :c:group:`i2c_emul_interface` for an example. + +.. _doxygen_api_versioning: + +API Versioning +============== + +Use ``@since`` and ``@version`` on group definitions (``@defgroup``) to document API history +and maturity: + +- ``@since`` indicates the Zephyr release when the API was introduced (e.g., ``@since 3.7``) +- ``@version`` indicates the current API version, following semantic versioning + +The version number reflects the API's maturity as defined in :ref:`api_overview`. + +Example: + +.. code-block:: c + :caption: Example for an API introduced in Zephyr 1.14, with current version 0.8.0 (unstable). + :emphasize-lines: 4,5 + + /** + * @defgroup mqtt_socket MQTT Client library + * @ingroup networking + * @since 1.14 + * @version 0.8.0 + * @{ + */ + + /* documented contents of the MQTT header file */ + + /** @} */ + +Files +***** + +Each public header file must have an ``@file`` block at the top, appearing after the SPDX license +and copyright notice. + +The ``@file`` block must also belong to a Doxygen group, typically the one defined in the same +header file. This allows users browsing by file to easily navigate to the associated group. + +.. code-block:: c + :emphasize-lines: 2,4 + + /** + * @file + * @brief Public API for the GPIO driver. + * @ingroup gpio_interface + */ + +Type Definitions +**************** + +Document ``struct``, ``enum``, ``union``, and ``typedef`` definitions with a brief description. + +Document each member (struct field, enum value, etc.) as well. It is recommended to use ``/**<`` +trailing comments style when only a brief description is provided and it can fit on a single line. + +.. code-block:: c + :caption: Examples of fully documented enum, struct, and typedef. + + /** @brief Parity modes */ + enum uart_config_parity { + UART_CFG_PARITY_NONE, /**< No parity */ + UART_CFG_PARITY_ODD, /**< Odd parity */ + UART_CFG_PARITY_EVEN, /**< Even parity */ + UART_CFG_PARITY_MARK, /**< Mark parity */ + UART_CFG_PARITY_SPACE, /**< Space parity */ + }; + + /** + * GPIO pin configuration. + * + * Specifies direction, pull resistor, and interrupt settings. + */ + struct gpio_config { + uint32_t flags; /**< Pin configuration flags. */ + gpio_pin_t pin; /**< Pin number within the port. */ + }; + + /** + * @brief Identifies a set of pins associated with a port. + * + * The pin with index n is present in the set if and only if the bit + * identified by (1U << n) is set. + */ + typedef uint32_t gpio_port_pins_t; + +Functions +********* + +Parameters +========== + +- Document parameters with ``@param`` in declaration order +- Use ``@param[out]`` for pointers the function writes to. +- Use ``@param[in,out]`` for pointers the function both reads and writes. +- You may omit direction specifiers for const pointers and scalars (implicitly input-only). + +Return Values +============= + +- Use ``@return `` for general descriptions (e.g., boolean or computed values). +- Use ``@retval `` for specific, discrete return values (typically error + codes), starting with the success case (when applicable). The ```` must be provided as the + first word, followed by the description (e.g., ``@retval -EINVAL Invalid arguments``, not + ``@retval -EINVAL if invalid arguments``). + + .. note:: + + Since there might be multiple reasons for the same discrete value to be returned, it is + allowed to use the same value in multiple ``@retval`` statements. + +Example: + +.. code-block:: c + :caption: Examples of fully documented functions. + + /** + * @brief Transmit data through a pipe + * + * @param[in] pipe Pipe to transmit through + * @param buf Data to transmit + * @param size Number of bytes to transmit + * + * @return Number of bytes placed in @p pipe + * @retval -EPERM Pipe is closed + * @retval -errno Negative error code on error + */ + int modem_pipe_transmit(struct modem_pipe *pipe, const uint8_t *buf, size_t size); + + /** + * @brief Helper function for converting struct sensor_value to float. + * + * @param val A pointer to a sensor_value struct. + * @return The converted value. + */ + static inline float sensor_value_to_float(const struct sensor_value *val) + { + return (float)val->val1 + (float)val->val2 / 1000000; + } + + +Macros +****** + +For function-like macros, document parameters like you would for functions. + +.. code-block:: c + :caption: Example of a fully documented function-like macro. + + /** + * @brief Get a node's (only) register block size + * + * Equivalent to DT_REG_SIZE_BY_IDX(node_id, 0). + * + * @param node_id node identifier + * @return node's only register block's size + */ + #define DT_REG_SIZE(node_id) DT_REG_SIZE_BY_IDX(node_id, 0) + +.. _doxygen_internals: + +Hiding internal details +*********************** + +Use ``@cond INTERNAL_HIDDEN`` / ``@endcond`` to hide internal details from generated documentation. + +You may still optionally document these internal symbols to provide a useful reference to internal +users. + +.. code-block:: c + :emphasize-lines: 8,12 + + /** Timer structure. + * + * Opaque type for a timer object. All the fields in this structure are internal and should not + * be accessed outside of kernel code. + */ + struct k_timer { + /** @cond INTERNAL_HIDDEN */ + + /* ... internal members ... */ + + /** @endcond */ + }; + +.. _doxygen_conditional_code: + +Conditional code +**************** + +To ensure conditionally-compiled code appears in documentation, use either of the following +approaches: + +1. Add the Kconfig macro (``CONFIG_...``) that is gating the code to the ``PREDEFINED`` list in + :zephyr_file:`doc/zephyr.doxyfile.in`. This makes the code visible to Doxygen during + documentation generation. + +#. Alternatively, you can rely on the ``__DOXYGEN__`` macro being set to make the conditional code + visible to Doxygen, as this macro is automatically defined by Doxygen. + +.. code-block:: c + :emphasize-lines: 4,10 + + struct coap_packet { + uint8_t *data; /**< User allocated buffer. */ + #if defined(CONFIG_COAP_KEEP_USER_DATA) || defined(__DOXYGEN__) + /** + * Application-specific user data. + * @kconfig_dep{CONFIG_COAP_KEEP_USER_DATA} + */ + void *user_data; + #endif + }; + +.. _doxygen_kconfig_dep: + +Kconfig Dependencies +==================== + +The ``@kconfig_dep`` command can be used to document the Kconfig option(s) that are required in +order for an API symbol to be available to the user. The command can be used with one, two or three +Kconfig options. + +For example, adding ``@kconfig_dep{CONFIG_PM,CONFIG_SMP}`` to the Doxygen documentation of an API +symbol will cause the generated documentation to include a note reading: "Available only when the +following Kconfig options are enabled: ``CONFIG_PM``, ``CONFIG_SMP``.". + +You can see an example of ``@kconfig_dep`` usage in the documentation of :c:struct:`coap_packet`. diff --git a/doc/contribute/style/index.rst b/doc/contribute/style/index.rst index 668cfcb84bce..b77487926483 100644 --- a/doc/contribute/style/index.rst +++ b/doc/contribute/style/index.rst @@ -9,6 +9,7 @@ Coding Style Guidelines naming.rst code.rst + doxygen.rst cmake.rst devicetree.rst kconfig.rst diff --git a/doc/develop/api/design_guidelines.rst b/doc/develop/api/design_guidelines.rst index 1dfeda4c45fc..0b5dc1a452bd 100644 --- a/doc/develop/api/design_guidelines.rst +++ b/doc/develop/api/design_guidelines.rst @@ -7,6 +7,8 @@ Zephyr development and evolution is a group effort, and to simplify maintenance and enhancements there are some general policies that should be followed when developing a new capability or interface. +All public API must be documented using Doxygen. See :ref:`doxygen_style` for details. + Using Callbacks *************** @@ -99,9 +101,9 @@ practices should be followed. other content the feature-specific code should be conditionally processed using ``#ifdef CONFIG_MYFEATURE``. -The Kconfig flag used to enable the feature should be added to the -``PREDEFINED`` variable in :file:`doc/zephyr.doxyfile.in` to ensure the -conditional API and functions appear in generated documentation. +See :ref:`doxygen_conditional_code` for details on +how to ensure conditional code is visible to Doxygen and included in the +public API documentation. Return Codes ************ From 9b2593b8c549c87f948a2f43340798a02cf58a60 Mon Sep 17 00:00:00 2001 From: Nicolas Moreno Date: Wed, 12 Nov 2025 11:50:36 -0400 Subject: [PATCH 1789/3659] drivers: display: issue with configuration on ILI9341 ILI9341 is not deploying correctly the display sample. The screen looks mirrored vertically and the color doesn't match with the sequence expected. To fix it, change the Memory Access Control configuration data. Signed-off-by: Nicolas Moreno --- drivers/display/display_ili9xxx.c | 11 +++++++---- drivers/display/display_ili9xxx.h | 2 +- dts/bindings/display/ilitek,ili9xxx-common.yaml | 1 + include/zephyr/dt-bindings/display/ili9xxx.h | 1 + 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/drivers/display/display_ili9xxx.c b/drivers/display/display_ili9xxx.c index ef258cfed892..1f86d3cd85ea 100644 --- a/drivers/display/display_ili9xxx.c +++ b/drivers/display/display_ili9xxx.c @@ -295,7 +295,7 @@ ili9xxx_set_pixel_format(const struct device *dev, uint8_t tx_data; uint8_t bytes_per_pixel; - if (pixel_format == PIXEL_FORMAT_RGB_565) { + if (pixel_format == PIXEL_FORMAT_RGB_565 || pixel_format == PIXEL_FORMAT_BGR_565) { bytes_per_pixel = 2U; tx_data = ILI9XXX_PIXSET_MCU_16_BIT | ILI9XXX_PIXSET_RGB_16_BIT; } else if (pixel_format == PIXEL_FORMAT_RGB_888) { @@ -324,7 +324,8 @@ static int ili9xxx_set_orientation(const struct device *dev, struct ili9xxx_data *data = dev->data; int r; - uint8_t tx_data = ILI9XXX_MADCTL_BGR; + uint8_t tx_data = config->pixel_format == PIXEL_FORMAT_BGR_565 + ? ILI9XXX_MADCTL_BGR : 0; if (config->quirks->cmd_set == CMD_SET_1) { if (orientation == DISPLAY_ORIENTATION_NORMAL) { tx_data |= ILI9XXX_MADCTL_MX; @@ -368,7 +369,7 @@ static void ili9xxx_get_capabilities(const struct device *dev, memset(capabilities, 0, sizeof(struct display_capabilities)); capabilities->supported_pixel_formats = - PIXEL_FORMAT_RGB_565 | PIXEL_FORMAT_RGB_888; + PIXEL_FORMAT_RGB_565 | PIXEL_FORMAT_RGB_888 | PIXEL_FORMAT_BGR_565; capabilities->current_pixel_format = data->pixel_format; if (data->orientation == DISPLAY_ORIENTATION_NORMAL || @@ -394,6 +395,8 @@ static int ili9xxx_configure(const struct device *dev) /* pixel format */ if (config->pixel_format == ILI9XXX_PIXEL_FORMAT_RGB565) { pixel_format = PIXEL_FORMAT_RGB_565; + } else if (config->pixel_format == ILI9XXX_PIXEL_FORMAT_BGR565) { + pixel_format = PIXEL_FORMAT_BGR_565; } else { pixel_format = PIXEL_FORMAT_RGB_888; } @@ -511,7 +514,7 @@ static const struct ili9xxx_quirks ili9340_quirks = { #ifdef CONFIG_ILI9341 static const struct ili9xxx_quirks ili9341_quirks = { - .cmd_set = CMD_SET_1, + .cmd_set = CMD_SET_2, }; #endif diff --git a/drivers/display/display_ili9xxx.h b/drivers/display/display_ili9xxx.h index cb3774246c72..b8491902df4c 100644 --- a/drivers/display/display_ili9xxx.h +++ b/drivers/display/display_ili9xxx.h @@ -59,7 +59,7 @@ enum madctl_cmd_set { CMD_SET_1, /* Default for most of ILI9xxx display controllers */ - CMD_SET_2, /* Used by ILI9342c */ + CMD_SET_2, /* Used by ILI9342c & ILI9341 */ }; struct ili9xxx_quirks { diff --git a/dts/bindings/display/ilitek,ili9xxx-common.yaml b/dts/bindings/display/ilitek,ili9xxx-common.yaml index 7ce2f5eaa9c5..8498f05ea9fa 100644 --- a/dts/bindings/display/ilitek,ili9xxx-common.yaml +++ b/dts/bindings/display/ilitek,ili9xxx-common.yaml @@ -20,6 +20,7 @@ properties: enum: - 0 # RGB565 - 1 # RGB888 + - 2 # BGR565 description: Display pixel format. Note that when RGB888 pixel format is selected only 6 color bits are actually used being in practice equivalent to diff --git a/include/zephyr/dt-bindings/display/ili9xxx.h b/include/zephyr/dt-bindings/display/ili9xxx.h index 8035600fb90e..c59ff149ad58 100644 --- a/include/zephyr/dt-bindings/display/ili9xxx.h +++ b/include/zephyr/dt-bindings/display/ili9xxx.h @@ -9,5 +9,6 @@ /* Pixel formats */ #define ILI9XXX_PIXEL_FORMAT_RGB565 0U #define ILI9XXX_PIXEL_FORMAT_RGB888 1U +#define ILI9XXX_PIXEL_FORMAT_BGR565 2U #endif /* ZEPHYR_INCLUDE_DT_BINDINGS_DISPLAY_ILI9XXX_H_ */ From 69e353904cb0ef11b5527348112a59c93bbbef82 Mon Sep 17 00:00:00 2001 From: Nicolas Moreno Date: Thu, 13 Nov 2025 20:51:20 -0400 Subject: [PATCH 1790/3659] drivers: display: features for ILI9341 driver Replaced display-controller.yaml with lcd-controller.yaml Deleted pixel format property, replacing it with the property on lcd-controller.yaml. Replace ILI9XXX RGB macro with PANEL RGB macro. Also, added condition to verify pixel format is RGB565, BRG565 or RGB888, otherwise it will show error Replaced with and ILI9XXX_PIXEL with PANEL_PIXEL in some Devicetrees and files that contained both elements. Fixed some script sintax. Deleted drivers/display/display_ili9xxx.c Signed-off-by: Nicolas Moreno --- .../bl5340_dvk_nrf5340_cpuapp_common.dtsi | 2 ++ .../m5stack/m5stack_core2/m5stack_core2_procpu.dts | 4 ++-- .../m5stack_cores3_procpu_common.dtsi | 4 ++-- .../m5stack/m5stack_fire/m5stack_fire_procpu.dts | 4 ++-- .../dts/da14695_dk_usb_mipi_dbi.overlay | 4 ++-- .../dts/da1469x_dk_pro_mipi_dbi.overlay | 4 ++-- boards/seeed/wio_terminal/wio_terminal.dts | 4 ++-- .../boards/rd_rw612_bga.overlay | 3 ++- .../dts/adafruit_2_8_tft_touch_v2.dtsi | 4 ++-- .../buydisplay_2_8_tft_touch_arduino.overlay | 4 ++-- .../buydisplay_3_5_tft_touch_arduino.overlay | 4 ++-- .../x_nucleo_gfx01m2/x_nucleo_gfx01m2.overlay | 4 ++-- .../st/st25dv_mb1283_disco/st25dv_mb1283_disco.dts | 4 ++-- boards/st/stm32f429i_disc1/stm32f429i_disc1.dts | 4 ++-- drivers/display/display_ili9xxx.c | 14 ++++++++------ dts/bindings/display/ilitek,ili9xxx-common.yaml | 14 +------------- include/zephyr/dt-bindings/display/ili9xxx.h | 14 -------------- .../adafruit_2_8_tft_touch_rgb565.overlay | 4 ++-- 18 files changed, 39 insertions(+), 60 deletions(-) delete mode 100644 include/zephyr/dt-bindings/display/ili9xxx.h diff --git a/boards/ezurio/bl5340_dvk/bl5340_dvk_nrf5340_cpuapp_common.dtsi b/boards/ezurio/bl5340_dvk/bl5340_dvk_nrf5340_cpuapp_common.dtsi index 21cecb635565..6af62971ef80 100644 --- a/boards/ezurio/bl5340_dvk/bl5340_dvk_nrf5340_cpuapp_common.dtsi +++ b/boards/ezurio/bl5340_dvk/bl5340_dvk_nrf5340_cpuapp_common.dtsi @@ -6,6 +6,7 @@ */ #include "bl5340_dvk_nrf5340_cpuapp_common-pinctrl.dtsi" #include +#include / { chosen { @@ -122,6 +123,7 @@ rotation = <270>; width = <320>; height = <240>; + pixel-format = ; }; }; }; diff --git a/boards/m5stack/m5stack_core2/m5stack_core2_procpu.dts b/boards/m5stack/m5stack_core2/m5stack_core2_procpu.dts index 42ea3d033ec0..a6949838bbec 100644 --- a/boards/m5stack/m5stack_core2/m5stack_core2_procpu.dts +++ b/boards/m5stack/m5stack_core2/m5stack_core2_procpu.dts @@ -9,7 +9,7 @@ #include "m5stack_core2-pinctrl.dtsi" #include "grove_connectors.dtsi" #include "m5stack_mbus_connectors.dtsi" -#include +#include #include #include @@ -62,7 +62,7 @@ mipi-max-frequency = <30000000>; reg = <0>; vin-supply = <&lcd_bg>; - pixel-format = ; + pixel-format = ; display-inversion; width = <320>; height = <240>; diff --git a/boards/m5stack/m5stack_cores3/m5stack_cores3_procpu_common.dtsi b/boards/m5stack/m5stack_cores3/m5stack_cores3_procpu_common.dtsi index 25ed72da9938..4c8042425889 100644 --- a/boards/m5stack/m5stack_cores3/m5stack_cores3_procpu_common.dtsi +++ b/boards/m5stack/m5stack_cores3/m5stack_cores3_procpu_common.dtsi @@ -6,7 +6,7 @@ #include #include -#include +#include #include "m5stack_cores3-pinctrl.dtsi" #include "m5stack_mbus_connectors.dtsi" #include "grove_connectors.dtsi" @@ -51,7 +51,7 @@ mipi-max-frequency = <30000000>; reg = <0>; vin-supply = <&vcc_bl>; - pixel-format = ; + pixel-format = ; display-inversion; width = <320>; height = <240>; diff --git a/boards/m5stack/m5stack_fire/m5stack_fire_procpu.dts b/boards/m5stack/m5stack_fire/m5stack_fire_procpu.dts index 884c9d24d1a2..4ab712a34a9e 100644 --- a/boards/m5stack/m5stack_fire/m5stack_fire_procpu.dts +++ b/boards/m5stack/m5stack_fire/m5stack_fire_procpu.dts @@ -10,7 +10,7 @@ #include "m5stack_fire-pinctrl.dtsi" #include "grove_connectors.dtsi" #include "m5stack_mbus_connectors.dtsi" -#include +#include #include #include @@ -95,7 +95,7 @@ compatible = "ilitek,ili9342c"; mipi-max-frequency = <30000000>; reg = <0>; - pixel-format = ; + pixel-format = ; display-inversion; width = <320>; height = <240>; diff --git a/boards/renesas/da14695_dk_usb/dts/da14695_dk_usb_mipi_dbi.overlay b/boards/renesas/da14695_dk_usb/dts/da14695_dk_usb_mipi_dbi.overlay index acc98c5f2a94..3a7e41c8c96b 100644 --- a/boards/renesas/da14695_dk_usb/dts/da14695_dk_usb_mipi_dbi.overlay +++ b/boards/renesas/da14695_dk_usb/dts/da14695_dk_usb_mipi_dbi.overlay @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include #include / { @@ -52,7 +52,7 @@ reg = <0>; width = <240>; height = <320>; - pixel-format = ; + pixel-format = ; rotation = <0>; }; }; diff --git a/boards/renesas/da1469x_dk_pro/dts/da1469x_dk_pro_mipi_dbi.overlay b/boards/renesas/da1469x_dk_pro/dts/da1469x_dk_pro_mipi_dbi.overlay index acc98c5f2a94..bd8b6cef95f6 100644 --- a/boards/renesas/da1469x_dk_pro/dts/da1469x_dk_pro_mipi_dbi.overlay +++ b/boards/renesas/da1469x_dk_pro/dts/da1469x_dk_pro_mipi_dbi.overlay @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include #include / { @@ -52,7 +52,7 @@ reg = <0>; width = <240>; height = <320>; - pixel-format = ; + pixel-format = ; rotation = <0>; }; }; diff --git a/boards/seeed/wio_terminal/wio_terminal.dts b/boards/seeed/wio_terminal/wio_terminal.dts index d50411aee2ad..62ce11f0aaef 100644 --- a/boards/seeed/wio_terminal/wio_terminal.dts +++ b/boards/seeed/wio_terminal/wio_terminal.dts @@ -8,7 +8,7 @@ #include "wio_terminal-pinctrl.dtsi" #include "grove_connectors.dtsi" #include "raspberrypi_40pins_connector.dtsi" -#include +#include #include / { @@ -148,7 +148,7 @@ compatible = "ilitek,ili9341"; mipi-max-frequency = <24000000>; reg = <0>; - pixel-format = ; + pixel-format = ; rotation = <270>; width = <320>; height = <240>; 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 9a6ed1d8541d..95de85a08658 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 @@ -5,6 +5,7 @@ */ #include +#include / { chosen { @@ -44,7 +45,7 @@ reg = <0>; width = <320>; height = <240>; - pixel-format = ; + pixel-format = ; rotation = <90>; frmctr1 = [00 18]; pwctrl1 = [23 00]; 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 7eca206f6a02..5868c02118df 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 @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include #include / { @@ -27,7 +27,7 @@ reg = <0>; width = <320>; height = <240>; - pixel-format = ; + pixel-format = ; rotation = <90>; frmctr1 = [00 18]; pwctrl1 = [23 00]; diff --git a/boards/shields/buydisplay_2_8_tft_touch_arduino/buydisplay_2_8_tft_touch_arduino.overlay b/boards/shields/buydisplay_2_8_tft_touch_arduino/buydisplay_2_8_tft_touch_arduino.overlay index cbb1b2b93885..a49cf610ae2c 100644 --- a/boards/shields/buydisplay_2_8_tft_touch_arduino/buydisplay_2_8_tft_touch_arduino.overlay +++ b/boards/shields/buydisplay_2_8_tft_touch_arduino/buydisplay_2_8_tft_touch_arduino.overlay @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include #include / { @@ -28,7 +28,7 @@ reg = <0>; width = <240>; height = <320>; - pixel-format = ; + pixel-format = ; rotation = <0>; frmctr1 = [00 18]; pwctrl1 = [23 00]; diff --git a/boards/shields/buydisplay_3_5_tft_touch_arduino/buydisplay_3_5_tft_touch_arduino.overlay b/boards/shields/buydisplay_3_5_tft_touch_arduino/buydisplay_3_5_tft_touch_arduino.overlay index 5d7bde3e3a55..238233dcae08 100644 --- a/boards/shields/buydisplay_3_5_tft_touch_arduino/buydisplay_3_5_tft_touch_arduino.overlay +++ b/boards/shields/buydisplay_3_5_tft_touch_arduino/buydisplay_3_5_tft_touch_arduino.overlay @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include #include / { @@ -26,7 +26,7 @@ compatible = "ilitek,ili9488"; mipi-max-frequency = <25000000>; reg = <0>; - pixel-format = ; + pixel-format = ; width = <320>; height = <480>; rotation = <0>; diff --git a/boards/shields/x_nucleo_gfx01m2/x_nucleo_gfx01m2.overlay b/boards/shields/x_nucleo_gfx01m2/x_nucleo_gfx01m2.overlay index 9a302a2c0e46..812fa68422d9 100644 --- a/boards/shields/x_nucleo_gfx01m2/x_nucleo_gfx01m2.overlay +++ b/boards/shields/x_nucleo_gfx01m2/x_nucleo_gfx01m2.overlay @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include #include #include #include @@ -74,7 +74,7 @@ width = <240>; height = <320>; rotation = <180>; - pixel-format = ; + pixel-format = ; frmctr1 = [00 1f]; /* 60Hz frame rate */ }; }; diff --git a/boards/st/st25dv_mb1283_disco/st25dv_mb1283_disco.dts b/boards/st/st25dv_mb1283_disco/st25dv_mb1283_disco.dts index 4e0db2a00a32..74c79bcf8858 100644 --- a/boards/st/st25dv_mb1283_disco/st25dv_mb1283_disco.dts +++ b/boards/st/st25dv_mb1283_disco/st25dv_mb1283_disco.dts @@ -8,7 +8,7 @@ #include "st/f4/stm32f405Xg.dtsi" #include "st/f4/stm32f405vgtx-pinctrl.dtsi" #include -#include +#include / { model = "ST ST25DV Discovery Kit with MB1283"; @@ -87,7 +87,7 @@ compatible = "ilitek,ili9341"; mipi-max-frequency = ; reg = <0>; - pixel-format = ; + pixel-format = ; rotation = <0>; width = <240>; height = <320>; diff --git a/boards/st/stm32f429i_disc1/stm32f429i_disc1.dts b/boards/st/stm32f429i_disc1/stm32f429i_disc1.dts index 79596438f7fa..5ed576dea0bf 100644 --- a/boards/st/stm32f429i_disc1/stm32f429i_disc1.dts +++ b/boards/st/stm32f429i_disc1/stm32f429i_disc1.dts @@ -8,7 +8,7 @@ /dts-v1/; #include #include -#include +#include #include / { @@ -76,7 +76,7 @@ width = <240>; height = <320>; rotation = <180>; - pixel-format = ; + pixel-format = ; pwctrla = [39 2c 00 34 02]; pwctrlb = [00 c1 30]; timctrla = [85 00 78]; diff --git a/drivers/display/display_ili9xxx.c b/drivers/display/display_ili9xxx.c index 1f86d3cd85ea..f44af0956601 100644 --- a/drivers/display/display_ili9xxx.c +++ b/drivers/display/display_ili9xxx.c @@ -7,8 +7,7 @@ */ #include "display_ili9xxx.h" - -#include +#include #include #include @@ -324,7 +323,7 @@ static int ili9xxx_set_orientation(const struct device *dev, struct ili9xxx_data *data = dev->data; int r; - uint8_t tx_data = config->pixel_format == PIXEL_FORMAT_BGR_565 + uint8_t tx_data = data->pixel_format == PIXEL_FORMAT_BGR_565 ? ILI9XXX_MADCTL_BGR : 0; if (config->quirks->cmd_set == CMD_SET_1) { if (orientation == DISPLAY_ORIENTATION_NORMAL) { @@ -393,12 +392,15 @@ static int ili9xxx_configure(const struct device *dev) enum display_orientation orientation; /* pixel format */ - if (config->pixel_format == ILI9XXX_PIXEL_FORMAT_RGB565) { + if (config->pixel_format == PANEL_PIXEL_FORMAT_RGB_565) { pixel_format = PIXEL_FORMAT_RGB_565; - } else if (config->pixel_format == ILI9XXX_PIXEL_FORMAT_BGR565) { + } else if (config->pixel_format == PANEL_PIXEL_FORMAT_BGR_565) { pixel_format = PIXEL_FORMAT_BGR_565; - } else { + } else if (config->pixel_format == PANEL_PIXEL_FORMAT_RGB_888) { pixel_format = PIXEL_FORMAT_RGB_888; + } else { + LOG_ERR("Unsupported pixel format in DT"); + return -ENOTSUP; } r = ili9xxx_set_pixel_format(dev, pixel_format); diff --git a/dts/bindings/display/ilitek,ili9xxx-common.yaml b/dts/bindings/display/ilitek,ili9xxx-common.yaml index 8498f05ea9fa..bcd32e0bcc07 100644 --- a/dts/bindings/display/ilitek,ili9xxx-common.yaml +++ b/dts/bindings/display/ilitek,ili9xxx-common.yaml @@ -8,24 +8,12 @@ description: | Ilitek ILI9XXX is a color TFT-LCD controller series. include: - - display-controller.yaml + - lcd-controller.yaml - name: mipi-dbi-spi-device.yaml property-blocklist: - te-delay properties: - pixel-format: - type: int - default: 0 - enum: - - 0 # RGB565 - - 1 # RGB888 - - 2 # BGR565 - description: - Display pixel format. Note that when RGB888 pixel format is selected - only 6 color bits are actually used being in practice equivalent to - RGB666. - rotation: type: int default: 0 diff --git a/include/zephyr/dt-bindings/display/ili9xxx.h b/include/zephyr/dt-bindings/display/ili9xxx.h deleted file mode 100644 index c59ff149ad58..000000000000 --- a/include/zephyr/dt-bindings/display/ili9xxx.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright (c) 2020 Teslabs Engineering S.L. - * - * SPDX-License-Identifier: Apache-2.0 - */ -#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_DISPLAY_ILI9XXX_H_ -#define ZEPHYR_INCLUDE_DT_BINDINGS_DISPLAY_ILI9XXX_H_ - -/* Pixel formats */ -#define ILI9XXX_PIXEL_FORMAT_RGB565 0U -#define ILI9XXX_PIXEL_FORMAT_RGB888 1U -#define ILI9XXX_PIXEL_FORMAT_BGR565 2U - -#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_DISPLAY_ILI9XXX_H_ */ diff --git a/tests/drivers/display/display_read_write/adafruit_2_8_tft_touch_rgb565.overlay b/tests/drivers/display/display_read_write/adafruit_2_8_tft_touch_rgb565.overlay index 5465b3c5c410..6b87853e4269 100644 --- a/tests/drivers/display/display_read_write/adafruit_2_8_tft_touch_rgb565.overlay +++ b/tests/drivers/display/display_read_write/adafruit_2_8_tft_touch_rgb565.overlay @@ -4,10 +4,10 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include &adafruit_2_8_tft_touch_v2_ili9340 { - pixel-format = ; + pixel-format = ; }; &adafruit_2_8_tft_touch_v2_mipi_dbi { From d6899161869beb1fd854126913265c999d90bceb Mon Sep 17 00:00:00 2001 From: Nicolas Moreno Date: Fri, 12 Dec 2025 10:56:16 -0400 Subject: [PATCH 1791/3659] doc: releases: add ili9xxx fixes to 4.4 releases notes & migration guide Added documentation for doc/releases/migration-guide-4.4.rst in reference with the changes on ili9xxx and ili9341 controllers Signed-off-by: Nicolas Moreno --- doc/releases/migration-guide-4.4.rst | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/doc/releases/migration-guide-4.4.rst b/doc/releases/migration-guide-4.4.rst index 032380264318..7dcbc912c9cf 100644 --- a/doc/releases/migration-guide-4.4.rst +++ b/doc/releases/migration-guide-4.4.rst @@ -275,6 +275,16 @@ Counter GPT now uses explicit devicetree properties rather than hardcoded values, allowing per-instance customization. +Display +======= + +* For ILI9XXX controllers, the usage of ``ILI9XXX_PIXEL_FORMAT_x`` in devicetrees for panel color + format selection has been updated to ``PANEL_PIXEL_FORMAT_x``. Out-of-tree boards and shields + should be updated accordingly. (:github:`99267`). + +* For ILI9341 controller, display mirroring configuration has been updated to conform with + the described behavior of the sample ``samples/drivers/display``. (:github:`99267`). + DMA === From 51fa798260a70e6a2b5d1c2ffbb3b457c4510bf9 Mon Sep 17 00:00:00 2001 From: Francis Roi Manabat Date: Mon, 22 Dec 2025 20:47:54 +0800 Subject: [PATCH 1792/3659] drivers: rtc: add MAX31331 RTC Support Add MAX31331 RTC driver, an ultra-low-power real-time clock (RTC) that provides timekeeping with extremely low current consumption (65 nA). Signed-off-by: Francis Roi Manabat --- drivers/rtc/CMakeLists.txt | 1 + drivers/rtc/Kconfig | 1 + drivers/rtc/Kconfig.max31331 | 63 ++ drivers/rtc/rtc_max31331.c | 1138 +++++++++++++++++++++ drivers/rtc/rtc_max31331.h | 442 ++++++++ dts/bindings/rtc/adi,max31331.yaml | 46 + include/zephyr/drivers/rtc/rtc_max31331.h | 49 + 7 files changed, 1740 insertions(+) create mode 100644 drivers/rtc/Kconfig.max31331 create mode 100644 drivers/rtc/rtc_max31331.c create mode 100644 drivers/rtc/rtc_max31331.h create mode 100644 dts/bindings/rtc/adi,max31331.yaml create mode 100644 include/zephyr/drivers/rtc/rtc_max31331.h diff --git a/drivers/rtc/CMakeLists.txt b/drivers/rtc/CMakeLists.txt index e73d2f46047e..2ea429f81151 100644 --- a/drivers/rtc/CMakeLists.txt +++ b/drivers/rtc/CMakeLists.txt @@ -22,6 +22,7 @@ zephyr_library_sources_ifdef(CONFIG_RTC_DS3231 rtc_ds3231.c) zephyr_library_sources_ifdef(CONFIG_RTC_EMUL rtc_emul.c) zephyr_library_sources_ifdef(CONFIG_RTC_FAKE rtc_fake.c) zephyr_library_sources_ifdef(CONFIG_RTC_INFINEON_CAT1 rtc_infineon.c) +zephyr_library_sources_ifdef(CONFIG_RTC_MAX31331 rtc_max31331.c) zephyr_library_sources_ifdef(CONFIG_RTC_MCHP_G1 rtc_mchp_g1.c) zephyr_library_sources_ifdef(CONFIG_RTC_MOTOROLA_MC146818 rtc_mc146818.c) zephyr_library_sources_ifdef(CONFIG_RTC_NUMAKER rtc_numaker.c) diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 3e07ad09cea9..b61917338fa6 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -52,6 +52,7 @@ source "drivers/rtc/Kconfig.ds3231" source "drivers/rtc/Kconfig.emul" source "drivers/rtc/Kconfig.fake" source "drivers/rtc/Kconfig.infineon" +source "drivers/rtc/Kconfig.max31331" source "drivers/rtc/Kconfig.mc146818" source "drivers/rtc/Kconfig.mchp" source "drivers/rtc/Kconfig.numaker" diff --git a/drivers/rtc/Kconfig.max31331 b/drivers/rtc/Kconfig.max31331 new file mode 100644 index 000000000000..4a57d6e45328 --- /dev/null +++ b/drivers/rtc/Kconfig.max31331 @@ -0,0 +1,63 @@ +# Copyright 2025 Analog Devices Inc. +# SPDX-License-Identifier: Apache-2.0 + +config RTC_MAX31331 + bool "MAX31331 ultra low-power RTC" + default y + depends on DT_HAS_ADI_MAX31331_ENABLED + select I2C + help + Enable the Analog Devices MAX31331 RTC multi-function device driver + +config RTC_MAX31331_TIMESTAMPING + bool "Timestamping support (TS0–TS3)" + depends on DT_HAS_ADI_MAX31331_ENABLED + help + Enable support for timestamping functionality using the TS0 - TS3 registers + +config RTC_MAX31331_INTERRUPT + bool "Interrupt support" + +choice RTC_MAX31331_INTERRUPT_MODE + prompt "Set option of Interrupt handling" + default RTC_MAX31331_INTERRUPT_GLOBAL_THREAD + depends on DT_HAS_ADI_MAX31331_ENABLED + help + Choose how the interrupt handling for the MAX31331 RTC driver should be implemented. + This allows selecting between different interrupt handling mechanisms based + on the application requirements. + +config RTC_MAX31331_INTERRUPT_GLOBAL_THREAD + bool "Use global thread" + depends on $(dt_compat_any_has_prop,$(DT_COMPAT_ADI_MAX31331),interrupt-gpios) + select GPIO + select RTC_MAX31331_INTERRUPT + help + Use global thread for the interrupt handler + +config RTC_MAX31331_INTERRUPT_OWN_THREAD + bool "Use own thread" + depends on $(dt_compat_any_has_prop,$(DT_COMPAT_ADI_MAX31331),interrupt-gpios) + select GPIO + select RTC_MAX31331_INTERRUPT + help + Use own thread for the interrupt handler + +endchoice # RTC_MAX31331_INTERRUPT_MODE + +config RTC_MAX31331_THREAD_PRIORITY + int "Thread Priority" + depends on RTC_MAX31331_INTERRUPT_OWN_THREAD + default 10 + help + Set the priority of the thread used for handling interrupts when "Use own thread" + is selected. A lower value indicates a higher priority. + +config RTC_MAX31331_THREAD_STACK_SIZE + int "Thread Stack Size" + depends on RTC_MAX31331_INTERRUPT_OWN_THREAD + default 1024 + help + Specify the stack size (in bytes) for the thread used to handle interrupts when + "Use own thread" is selected. Ensure the stack size is sufficient for the interrupt + handling logic to avoid stack overflows. diff --git a/drivers/rtc/rtc_max31331.c b/drivers/rtc/rtc_max31331.c new file mode 100644 index 000000000000..25f6dd7bd203 --- /dev/null +++ b/drivers/rtc/rtc_max31331.c @@ -0,0 +1,1138 @@ +/* + * Copyright (c) 2025 Analog Devices Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include "rtc_max31331.h" +#include "rtc_utils.h" +#ifdef CONFIG_RTC_MAX31331_TIMESTAMPING +#include +#endif + +#define DT_DRV_COMPAT adi_max31331 + +LOG_MODULE_REGISTER(rtc_max31331, CONFIG_RTC_LOG_LEVEL); + +#ifdef CONFIG_RTC_ALARM +struct rtc_max31331_alarm { + rtc_alarm_callback callback; + void *user_data; +}; +#endif +struct rtc_max31331_data { +#ifdef CONFIG_RTC_ALARM + struct rtc_max31331_alarm alarms[ALARM_COUNT]; +#endif + +#ifdef CONFIG_RTC_MAX31331_TIMESTAMPING + struct rtc_time timestamp_buffer[4]; + rtc_max31331_timestamp_callback ts_callback; + void *ts_user_data; +#endif + struct gpio_callback int_callback; +#if defined(CONFIG_RTC_MAX31331_INTERRUPT_GLOBAL_THREAD) + struct k_work work; +#elif defined(CONFIG_RTC_MAX31331_INTERRUPT_OWN_THREAD) + K_KERNEL_STACK_MEMBER(thread_stack, CONFIG_RTC_MAX31331_THREAD_STACK_SIZE); + struct k_thread thread; + struct k_sem sem; +#endif + const struct device *dev; +}; + +struct rtc_max31331_config { + struct i2c_dt_spec i2c; + struct gpio_dt_spec inta_gpios; + bool ts_enable; + bool ts_vbat_enable; + bool ts_din; + bool ts_overwrite; + bool ts_power_supply_switch; + bool din_polarity; + bool din_en_io; +}; + +/** + * @brief Generic register access function for MAX31331 + * + * @param dev Device Descriptor + * @param addr_reg Register Address + * @param data Data buffer pointer + * @param read Read (true) or Write (false) operation + * @param length Number of bytes to read/write + * @return int 0 on success, negative error code on failure + */ +static int max31331_reg_access(const struct device *dev, uint8_t addr_reg, uint8_t *data, bool read, + uint8_t length) +{ + + const struct rtc_max31331_config *config = dev->config; + + if (read) { + return i2c_burst_read_dt(&config->i2c, addr_reg, data, length); + } else { + return i2c_burst_write_dt(&config->i2c, addr_reg, data, length); + } +} + +/** + * @brief Read register(s) from MAX31331 + * + * @param dev Device Descriptor + * @param reg_addr Register Address + * @param val Data buffer pointer + * @param length Number of bytes to read + * @return int 0 on success, negative error code on failure + */ +static int max31331_reg_read(const struct device *dev, uint8_t reg_addr, uint8_t *val, + uint8_t length) +{ + return max31331_reg_access(dev, reg_addr, val, true, length); +} + +/** + * @brief Single Byte write to MAX31331 register + * + * @param dev Device Descriptor + * @param reg_addr Register Address + * @param val Value to write + * @return int 0 on success, negative error code on failure + */ +static int max31331_reg_write(const struct device *dev, uint8_t reg_addr, uint8_t val) +{ + return max31331_reg_access(dev, reg_addr, &val, false, 1); +} + +/** + * @brief Multiple Byte write to MAX31331 register + * + * @param dev Device Descriptor + * @param reg_addr Register Address + * @param val Data buffer pointer + * @param length Number of bytes to write + * @return int 0 on success, negative error code on failure + */ +static int max31331_reg_write_multiple(const struct device *dev, uint8_t reg_addr, uint8_t *val, + uint8_t length) +{ + if (length < 2) { + return -EINVAL; + } + return max31331_reg_access(dev, reg_addr, val, false, length); +} + +/** + * @brief Update specific bits in a MAX31331 register + * + * @param dev Device Descriptor + * @param reg_addr Register Address + * @param mask Bit mask to update + * @param val New value for the specified bits + * @return int 0 on success, negative error code on failure + */ +static int max31331_reg_update(const struct device *dev, uint8_t reg_addr, uint8_t mask, + uint8_t val) +{ + uint8_t reg_val = 0; + int ret; + + ret = max31331_reg_read(dev, reg_addr, ®_val, 1); + if (ret < 0) { + return ret; + } + + reg_val &= ~mask; + reg_val |= FIELD_PREP(mask, val); + + return max31331_reg_write(dev, reg_addr, reg_val); +} + +/** + * @brief Get the current time from MAX31331 RTC + * + * @param dev Device Descriptor + * @param timeptr Pointer to rtc_time structure to store the retrieved time + * @return int 0 on success, negative error code on failure + */ +static int rtc_max31331_get_time(const struct device *dev, struct rtc_time *timeptr) +{ + int ret; + uint8_t raw_time[7]; + + ret = max31331_reg_read(dev, MAX31331_SECONDS, raw_time, ARRAY_SIZE(raw_time)); + if (ret) { + LOG_ERR("Unable to get time. Err: %i", ret); + return ret; + } + + timeptr->tm_sec = bcd2bin(raw_time[0] & SECONDS_FIELD_MASK); + timeptr->tm_min = bcd2bin(raw_time[1] & MINUTES_FIELD_MASK); + timeptr->tm_hour = bcd2bin(raw_time[2] & HOURS_FIELD_MASK); + timeptr->tm_wday = bcd2bin(raw_time[3] & DAY_FIELD_MASK) + MAX31331_DAY_OFFSET; + timeptr->tm_mday = bcd2bin(raw_time[4] & DATE_FIELD_MASK); + timeptr->tm_mon = bcd2bin(raw_time[5] & MONTH_FIELD_MASK) - 1; + if (raw_time[5] & CENTURY_MASK) { + timeptr->tm_year = bcd2bin(raw_time[6] & YEAR_FIELD_MASK) + MAX31331_YEAR_2100; + } else { + timeptr->tm_year = bcd2bin(raw_time[6] & YEAR_FIELD_MASK); + } + + LOG_DBG("Get time: year: %d, month: %d, month day: %d, week day: %d, hour: %d, " + "minute: %d, second: %d", + timeptr->tm_year + 1900, timeptr->tm_mon, timeptr->tm_mday, timeptr->tm_wday, + timeptr->tm_hour, timeptr->tm_min, timeptr->tm_sec); + + return 0; +} + +/** + * @brief Set the current time on MAX31331 RTC + * + * @param dev Device Descriptor + * @param timeptr Pointer to rtc_time structure containing the time to set + * @return int 0 on success, negative error code on failure + */ +static int rtc_max31331_set_time(const struct device *dev, const struct rtc_time *timeptr) +{ + int ret; + uint8_t raw_time[7]; + + if ((timeptr == NULL) || !rtc_utils_validate_rtc_time(timeptr, MAX31331_RTC_TIME_MASK)) { + LOG_ERR("invalid time"); + return -EINVAL; + } + + raw_time[0] = bin2bcd(timeptr->tm_sec) & SECONDS_FIELD_MASK; + raw_time[1] = bin2bcd(timeptr->tm_min) & MINUTES_FIELD_MASK; + raw_time[2] = bin2bcd(timeptr->tm_hour) & HOURS_FIELD_MASK; + raw_time[3] = bin2bcd(timeptr->tm_wday - MAX31331_DAY_OFFSET) & DAY_FIELD_MASK; + raw_time[4] = bin2bcd(timeptr->tm_mday) & DATE_FIELD_MASK; + raw_time[5] = bin2bcd(timeptr->tm_mon + 1) & MONTH_FIELD_MASK; + + if (timeptr->tm_year >= MAX31331_YEAR_2100) { + raw_time[5] |= BIT(7); + raw_time[6] = bin2bcd(timeptr->tm_year % 100) & YEAR_FIELD_MASK; + } else { + raw_time[5] &= ~BIT(7); + raw_time[6] = bin2bcd(timeptr->tm_year % 100) & YEAR_FIELD_MASK; + } + + ret = max31331_reg_write_multiple(dev, MAX31331_SECONDS, raw_time, ARRAY_SIZE(raw_time)); + if (ret) { + LOG_ERR("Error when setting time: %i", ret); + return ret; + } + return 0; +} + +#ifdef CONFIG_RTC_ALARM + +static inline int validate_alarm_1_time_mask(uint16_t mask) +{ + if (mask & RTC_ALARM_TIME_MASK_YEARDAY) { + LOG_ERR("Alarm 1 does not support yearday field"); + return -EINVAL; + } + + if (mask == 0) { + LOG_ERR("Alarm 1 time mask not set"); + return -EINVAL; + } + return 0; +} + +/** + * @brief Helper to Write time for Alarm 1 + * + * @param dev Device Pointer + * @param mask RTC Alarm Time Mask + * @param timeptr Pointer to rtc_time structure + * @return int 0 on success, negative error code on failure + */ +static int set_alarm_time_1(const struct device *dev, uint16_t mask, const struct rtc_time *timeptr) +{ + int ret; + uint8_t raw_time[6]; + + ret = validate_alarm_1_time_mask(mask); + if (ret) { + LOG_ERR("Invalid alarm 1 time mask: %i", ret); + return ret; + } + + raw_time[0] = (mask & RTC_ALARM_TIME_MASK_SECOND) + ? (bin2bcd(timeptr->tm_sec) & ALARM_1_SECONDS_FIELD_MASK) & + ~ALARM_1_SECONDS_ENABLE_MASK + : (bin2bcd(timeptr->tm_sec) & ALARM_1_SECONDS_FIELD_MASK) | + ALARM_1_SECONDS_ENABLE_MASK; + raw_time[1] = (mask & RTC_ALARM_TIME_MASK_MINUTE) + ? (bin2bcd(timeptr->tm_min) & ALARM_1_MINUTES_FIELD_MASK) & + ~ALARM_1_MINUTES_ENABLE_MASK + : (bin2bcd(timeptr->tm_min) & ALARM_1_MINUTES_FIELD_MASK) | + ALARM_1_MINUTES_ENABLE_MASK; + raw_time[2] = (mask & RTC_ALARM_TIME_MASK_HOUR) + ? (bin2bcd(timeptr->tm_hour) & ALARM_1_HOURS_FIELD_MASK) & + ~ALARM_1_HOURS_ENABLE_MASK + : (bin2bcd(timeptr->tm_hour) & ALARM_1_HOURS_FIELD_MASK) | + ALARM_1_HOURS_ENABLE_MASK; + + if ((mask & RTC_ALARM_TIME_MASK_WEEKDAY) && + (timeptr->tm_wday >= 0 && timeptr->tm_wday <= 6)) { + + raw_time[3] = + ((bin2bcd(timeptr->tm_wday + 1) & ALARM_1_DAY_DATE_MASK) | + ALARM_1_DAY_DATE_OP_MASK | + ((mask & RTC_ALARM_TIME_MASK_WEEKDAY) ? 0 : ALARM_1_DAY_DATE_ENABLE_MASK)); + + } else if ((mask & RTC_ALARM_TIME_MASK_MONTHDAY) && + (timeptr->tm_mday >= 1 && timeptr->tm_mday <= 31)) { + + raw_time[3] = + (((bin2bcd(timeptr->tm_mday) & ALARM_1_DAY_DATE_FIELD_MASK) & + ~ALARM_1_DAY_DATE_OP_MASK) | + ((mask & RTC_ALARM_TIME_MASK_MONTHDAY) ? 0 + : ALARM_1_DAY_DATE_ENABLE_MASK)); + + } else { + /* Disable day/date alarm if neither field is valid */ + raw_time[3] = 0x80; + } + raw_time[4] = (mask & RTC_ALARM_TIME_MASK_MONTH) + ? ((bin2bcd(timeptr->tm_mon + 1) & ALARM_1_MONTH_FIELD_MASK) & + ~ALARM_1_MONTH_ENABLE_MASK) + : ((bin2bcd(timeptr->tm_mon + 1) & ALARM_1_MONTH_FIELD_MASK) | + ALARM_1_MONTH_ENABLE_MASK); + + if (mask & RTC_ALARM_TIME_MASK_YEAR) { + raw_time[5] = (bin2bcd(timeptr->tm_year % 100) & ALARM_1_YEAR_FIELD_MASK); + } else { + raw_time[4] |= ALARM_1_YEAR_ENABLE_MASK; + raw_time[5] = (bin2bcd(timeptr->tm_year % 100) & ALARM_1_YEAR_FIELD_MASK); + } + ret = max31331_reg_write_multiple(dev, MAX31331_ALARM_1_SECONDS, raw_time, + ARRAY_SIZE(raw_time)); + if (ret) { + LOG_ERR("Error when setting alarm: %i", ret); + return ret; + } + return 0; +} + +/** + * @brief Helper to validate Alarm 2 time mask + * + * @param mask RTC Alarm Time Mask + * @return int 0 on success, negative error code on failure + */ +static inline int validate_alarm_2_time_mask(uint16_t mask) +{ + if (mask == 0) { + LOG_ERR("Alarm 2 time mask not set"); + return -EINVAL; + } + + if (mask & RTC_ALARM_TIME_MASK_SECOND) { + LOG_ERR("Alarm 2 does not support seconds field"); + return -EINVAL; + } + + if (mask & RTC_ALARM_TIME_MASK_YEAR) { + LOG_ERR("Alarm 2 does not support year field"); + return -EINVAL; + } + + if (mask & RTC_ALARM_TIME_MASK_MONTH) { + LOG_ERR("Alarm 2 does not support month field"); + return -EINVAL; + } + + return 0; +} + +/** + * @brief Helper to Write time for Alarm 2 + * + * @param dev Device Pointer + * @param mask RTC Alarm Time Mask + * @param timeptr Pointer to rtc_time structure + * @return int 0 on success, negative error code on failure + */ +static int set_alarm_time_2(const struct device *dev, uint16_t mask, const struct rtc_time *timeptr) +{ + int ret; + uint8_t raw_time[3]; + + ret = validate_alarm_2_time_mask(mask); + if (ret) { + LOG_ERR("Invalid alarm 2 time mask: %i", ret); + return ret; + } + + raw_time[0] = (mask & RTC_ALARM_TIME_MASK_MINUTE) + ? (bin2bcd(timeptr->tm_min) & ALARM_2_MINUTES_FIELD_MASK) & + ~ALARM_2_MINUTES_ENABLE_MASK + : (bin2bcd(timeptr->tm_min) & ALARM_2_MINUTES_FIELD_MASK) | + ALARM_2_MINUTES_ENABLE_MASK; + raw_time[1] = (mask & RTC_ALARM_TIME_MASK_HOUR) + ? (bin2bcd(timeptr->tm_hour) & ALARM_2_HOURS_FIELD_MASK) & + ~ALARM_2_HOURS_ENABLE_MASK + : (bin2bcd(timeptr->tm_hour) & ALARM_2_HOURS_FIELD_MASK) | + ALARM_2_HOURS_ENABLE_MASK; + + if (timeptr->tm_wday >= 0 && timeptr->tm_wday <= 6) { + /* Alarm based on weekday */ + if (mask & RTC_ALARM_TIME_MASK_WEEKDAY) { + raw_time[2] = ((bin2bcd(timeptr->tm_wday + 1) & ALARM_2_DAY_DATE_MASK) | + ALARM_2_DAY_DATE_OP_MASK) & + ~ALARM_2_DAY_DATE_ENABLE_MASK; + } else { + raw_time[2] = ((bin2bcd(timeptr->tm_wday + 1) & ALARM_2_DAY_DATE_MASK) | + ALARM_2_DAY_DATE_OP_MASK | ALARM_2_DAY_DATE_ENABLE_MASK); + } + } else if (timeptr->tm_mday >= 1 && timeptr->tm_mday <= 31) { + /* Alarm based on day of month */ + if (mask & RTC_ALARM_TIME_MASK_MONTHDAY) { + raw_time[2] = ((bin2bcd(timeptr->tm_mday) & + (ALARM_2_DAY_DATE_FIELD_MASK & ~ALARM_2_DAY_DATE_OP_MASK)) & + ~ALARM_2_DAY_DATE_ENABLE_MASK); + } else { + raw_time[2] = ((bin2bcd(timeptr->tm_mday) & + (ALARM_2_DAY_DATE_FIELD_MASK & ~ALARM_2_DAY_DATE_OP_MASK)) | + ALARM_2_DAY_DATE_ENABLE_MASK); + } + } else { + raw_time[2] = 0x80; + } + + ret = max31331_reg_write_multiple(dev, MAX31331_ALARM_2_MINUTES, raw_time, + ARRAY_SIZE(raw_time)); + if (ret) { + LOG_ERR("Error when setting alarm: %i", ret); + return ret; + } + return 0; +} + +/** + * @brief Enable or disable alarm interrupt on MAX31331 RTC + * + * @param dev Device Pointer + * @param id Alarm ID + * @param mask RTC Alarm Time Mask + * @return int 0 on success, negative error code on failure + */ +static int enable_alarm_interrupt(const struct device *dev, uint16_t id, uint16_t mask) +{ + int ret; + bool enable; + + if (mask != 0) { + enable = 1; + } else { + enable = 0; + } + + if (id == 1) { + ret = max31331_reg_update(dev, MAX31331_INTERRUPT_ENABLE, + ALARM_1_INTERRUPT_ENABLE_MASK, enable); + if (ret) { + LOG_ERR("Error setting alarm interrupt: %i", ret); + return ret; + } + } else if (id == 2) { + ret = max31331_reg_update(dev, MAX31331_INTERRUPT_ENABLE, + ALARM_2_INTERRUPT_ENABLE_MASK, enable); + if (ret) { + LOG_ERR("Error setting alarm interrupt: %i", ret); + return ret; + } + } else { + LOG_ERR("Invalid Alarm ID: %d", id); + return -EINVAL; + } + return 0; +} + +/** + * @brief Set alarm time helper for MAX31331 RTC + * + * @param dev Device Pointer + * @param mask RTC Alarm Time Mask + * @param timeptr Pointer to rtc_time structure + * @param id Alarm ID + * @return int 0 on success, negative error code on failure + */ +static int set_alarm_time(const struct device *dev, uint16_t mask, const struct rtc_time *timeptr, + uint16_t id) +{ + int ret; + + if (id == 1) { + ret = set_alarm_time_1(dev, mask, timeptr); + if (ret) { + return ret; + } + } else if (id == 2) { + ret = set_alarm_time_2(dev, mask, timeptr); + if (ret) { + return ret; + } + + } else { + LOG_ERR("Invalid Alarm ID: %d", id); + return -EINVAL; + } + return 0; +} +static int validate_mask_month_week_day(uint16_t mask) +{ + if ((mask & RTC_ALARM_TIME_MASK_MONTHDAY) && (mask & RTC_ALARM_TIME_MASK_WEEKDAY)) { + LOG_ERR("Both day and date are set. Not Supported"); + return -EINVAL; + } + return 0; +} +/** + * @brief Set alarm time on MAX31331 RTC + * + * @param dev Device Descriptor + * @param id Alarm ID + * @param mask Alarm time fields mask + * @param timeptr Pointer to rtc_time structure containing the alarm time to set + * @return int 0 on success, negative error code on failure + */ +static int rtc_max31331_alarm_set_time(const struct device *dev, uint16_t id, uint16_t mask, + const struct rtc_time *timeptr) +{ + int ret = 0; + + ret = validate_mask_month_week_day(mask); + if (ret) { + return ret; + } + + if ((timeptr == NULL) || !rtc_utils_validate_rtc_time(timeptr, mask)) { + LOG_ERR("invalid alarm time"); + return -EINVAL; + } + ret = set_alarm_time(dev, mask, timeptr, id); + if (ret) { + LOG_ERR("Error when setting alarm time: %i", ret); + return ret; + } + ret = enable_alarm_interrupt(dev, id, mask); + if (ret) { + LOG_ERR("Error when enabling alarm interrupt: %i", ret); + return ret; + } + return 0; +} + +static void process_mask_alarm_1(uint16_t *mask, const uint8_t *raw_time) +{ + *mask = 0; + if (!(raw_time[0] & ALARM_1_SECONDS_ENABLE_MASK)) { + *mask |= RTC_ALARM_TIME_MASK_SECOND; + } + if (!(raw_time[1] & ALARM_1_MINUTES_ENABLE_MASK)) { + *mask |= RTC_ALARM_TIME_MASK_MINUTE; + } + if (!(raw_time[2] & ALARM_1_HOURS_ENABLE_MASK)) { + *mask |= RTC_ALARM_TIME_MASK_HOUR; + } + if (!(raw_time[3] & ALARM_1_DAY_DATE_ENABLE_MASK)) { + if (raw_time[3] & ALARM_1_DAY_DATE_OP_MASK) { + *mask |= RTC_ALARM_TIME_MASK_WEEKDAY; + } else { + *mask |= RTC_ALARM_TIME_MASK_MONTHDAY; + } + } + if (!(raw_time[4] & ALARM_1_MONTH_ENABLE_MASK)) { + *mask |= RTC_ALARM_TIME_MASK_MONTH; + } + if (!(raw_time[4] & ALARM_1_YEAR_ENABLE_MASK)) { + *mask |= RTC_ALARM_TIME_MASK_YEAR; + } +} + +static void process_mask_alarm_2(uint16_t *mask, const uint8_t *raw_time) +{ + *mask = 0; + if (!(raw_time[0] & ALARM_2_MINUTES_ENABLE_MASK)) { + *mask |= RTC_ALARM_TIME_MASK_MINUTE; + } + if (!(raw_time[1] & ALARM_2_HOURS_ENABLE_MASK)) { + *mask |= RTC_ALARM_TIME_MASK_HOUR; + } + if (!(raw_time[2] & ALARM_2_DAY_DATE_ENABLE_MASK)) { + if (raw_time[2] & ALARM_2_DAY_DATE_OP_MASK) { + *mask |= RTC_ALARM_TIME_MASK_WEEKDAY; + } else { + *mask |= RTC_ALARM_TIME_MASK_MONTHDAY; + } + } +} + +/** + * @brief Get alarm time from MAX31331 RTC + * + * @param dev Device Descriptor + * @param id Alarm ID + * @param mask Alarm time fields mask + * @param timeptr Pointer to rtc_time structure to store the retrieved alarm time + * @return int 0 on success, negative error code on failure + */ +static int rtc_max31331_alarm_get_time(const struct device *dev, uint16_t id, uint16_t *mask, + struct rtc_time *timeptr) +{ + int ret; + uint8_t raw_time[6]; + + switch (id) { + case 1: + ret = max31331_reg_read(dev, MAX31331_ALARM_1_SECONDS, raw_time, + ARRAY_SIZE(raw_time)); + if (ret) { + LOG_ERR("Error when getting alarm time: %i", ret); + return ret; + } + *mask = 0; + process_mask_alarm_1(mask, raw_time); + return 0; + case 2: + ret = max31331_reg_read(dev, MAX31331_ALARM_2_MINUTES, raw_time, 3); + if (ret) { + LOG_ERR("Error when getting alarm time: %i", ret); + return ret; + } + *mask = 0; + process_mask_alarm_2(mask, raw_time); + return 0; + default: + LOG_ERR("Invalid Alarm ID: %d", id); + return -EINVAL; + } +} + +/** + * @brief Set alarm callback for MAX31331 RTC + * + * @param dev Device Descriptor + * @param id Alarm ID + * @param callback Alarm callback function + * @param user_data User data pointer to be passed to the callback + * @return int 0 on success, negative error code on failure + */ +static int rtc_max31331_alarm_set_callback(const struct device *dev, uint16_t id, + rtc_alarm_callback callback, void *user_data) +{ + struct rtc_max31331_data *data = dev->data; + + if (id <= 0 || id > 2) { + LOG_ERR("invalid ID %d", id); + return -EINVAL; + } + data->alarms[id - 1].callback = callback; + data->alarms[id - 1].user_data = user_data; + return 0; +} + +/** + * @brief Get supported alarm time fields for MAX31331 RTC + * + * @param dev Device Descriptor + * @param id Alarm ID + * @param mask Pointer to store the supported alarm time fields mask + * @return int 0 on success, negative error code on failure + */ +static int rtc_max31331_alarm_get_supported_fields(const struct device *dev, uint16_t id, + uint16_t *mask) +{ + *mask = RTC_ALARM_TIME_MASK_MONTHDAY | RTC_ALARM_TIME_MASK_WEEKDAY | + RTC_ALARM_TIME_MASK_HOUR | RTC_ALARM_TIME_MASK_MINUTE; + + switch (id) { + case 1: + *mask |= RTC_ALARM_TIME_MASK_SECOND | RTC_ALARM_TIME_MASK_MONTH | + RTC_ALARM_TIME_MASK_YEAR; + break; + case 2: + break; + default: + return -EINVAL; + } + + return 0; +} + +/** + * @brief Check if an alarm is pending on MAX31331 RTC + * + * @param dev Device Descriptor + * @param id Alarm ID + * @return int 1 if alarm is pending, 0 if not, negative error code on failure + */ +static int rtc_max31331_alarm_is_pending(const struct device *dev, uint16_t id) +{ + int ret; + uint8_t int_status; + + if (id <= 0 || id > 2) { + LOG_ERR("invalid ID %d", id); + return -EINVAL; + } + + ret = max31331_reg_read(dev, MAX31331_STATUS_REG, &int_status, 1); + if (ret) { + LOG_ERR("Failed to read interrupt status"); + return ret; + } + + if (id == 1) { + return (int_status & ALARM_1_FLAG_MASK) ? 1 : 0; + } else if (id == 2) { + return (int_status & ALARM_2_FLAG_MASK) ? 1 : 0; + } + + return 0; +} + +/** + * @brief Initialize alarm structures for MAX31331 RTC + * + * @param dev Device Descriptor + * @return int 0 on success, negative error code on failure + */ +static int rtc_max31331_init_alarms(const struct device *dev) +{ + struct rtc_max31331_data *data = dev->data; + + for (int i = 0; i < ALARM_COUNT; i++) { + data->alarms[i].callback = NULL; + data->alarms[i].user_data = NULL; + } + return 0; +} + +/** + * @brief Main callback function for handling MAX31331 RTC interrupts + * + * @param dev Device Descriptor + */ +static void rtc_max31331_main_cb(const struct device *dev) +{ + const struct rtc_max31331_config *config = dev->config; + struct rtc_max31331_data *data = dev->data; + + int ret = 0; + uint8_t int_status; + + /* Read Status and Clear Flags */ + ret = max31331_reg_read(dev, MAX31331_STATUS_REG, &int_status, 1); + if (ret) { + LOG_ERR("Failed to read interrupt status"); + return; + } + + if ((int_status & ALARM_1_FLAG_MASK) && data->alarms[0].callback) { + data->alarms[0].callback(dev, 1, data->alarms[0].user_data); + } + + if ((int_status & ALARM_2_FLAG_MASK) && data->alarms[1].callback) { + data->alarms[1].callback(dev, 2, data->alarms[1].user_data); + } + +#if defined(CONFIG_RTC_MAX31331_TIMESTAMPING) + if ((int_status & (DIGITAL_INTERRUPT_MASK | VBATLOW_MASK)) && data->ts_callback) { + data->ts_callback(dev, data->ts_user_data); + } +#endif + + ret = gpio_pin_interrupt_configure_dt(&config->inta_gpios, GPIO_INT_EDGE_FALLING); + if (ret) { + LOG_ERR("Failed to enable INT GPIO interrupt"); + return; + } + __ASSERT(ret == 0, "Interrupt Configuration Failed"); +} + +/** + * @brief GPIO callback function for MAX31331 RTC interrupt + * + * @param dev Device Descriptor + * @param cb GPIO callback structure + * @param pins Pin mask that triggered the interrupt + */ +static void rtc_max31331_gpio_callback(const struct device *dev, struct gpio_callback *cb, + uint32_t pins) +{ + struct rtc_max31331_data *data = CONTAINER_OF(cb, struct rtc_max31331_data, int_callback); + const struct rtc_max31331_config *config = data->dev->config; + int ret = 0; + + ret = gpio_pin_interrupt_configure_dt(&config->inta_gpios, GPIO_INT_DISABLE); + if (ret) { + LOG_ERR("Failed to disable INT GPIO interrupt"); + return; + } +#if defined(CONFIG_RTC_MAX31331_INTERRUPT_GLOBAL_THREAD) + k_work_submit(&data->work); +#elif defined(CONFIG_RTC_MAX31331_INTERRUPT_OWN_THREAD) + k_sem_give(&data->sem); +#endif +} + +#if defined(CONFIG_RTC_MAX31331_INTERRUPT_OWN_THREAD) +/** + * @brief Thread function for handling MAX31331 RTC interrupts + * + * @param p1 Pointer to rtc_max31331_data structure + * @param p2 Unused + * @param p3 Unused + */ +static void max31331_thread(void *p1, void *p2, void *p3) +{ + ARG_UNUSED(p2); + ARG_UNUSED(p3); + struct rtc_max31331_data *data = p1; + const struct device *dev = data->dev; + + while (1) { + k_sem_take(&data->sem, K_FOREVER); + rtc_max31331_main_cb(dev); + } +} +#elif defined(CONFIG_RTC_MAX31331_INTERRUPT_GLOBAL_THREAD) +/** + * @brief Work callback function for handling MAX31331 RTC interrupts + * + * @param work Pointer to k_work structure + */ +static void max31331_work_cb(struct k_work *work) +{ + struct rtc_max31331_data *data = CONTAINER_OF(work, struct rtc_max31331_data, work); + const struct device *dev = data->dev; + + rtc_max31331_main_cb(dev); +} +#endif +/** + * @brief Initialize alarm functionality for MAX31331 RTC + * + * @param dev Device Descriptor + * @return int 0 on success, negative error code on failure + */ +static int rtc_max31331_alarm_init(const struct device *dev) +{ + const struct rtc_max31331_config *config = dev->config; + struct rtc_max31331_data *data = dev->data; + int ret = 0; + + if (!gpio_is_ready_dt(&config->inta_gpios)) { + LOG_ERR("INT GPIO not ready"); + return -ENODEV; + } + + ret = rtc_max31331_init_alarms(dev); + if (ret) { + LOG_ERR("Failed to initialize alarms"); + return ret; + } + + ret = gpio_pin_configure_dt(&config->inta_gpios, GPIO_INPUT); + if (ret) { + LOG_ERR("Failed to configure INT GPIO"); + return ret; + } + + ret = gpio_pin_interrupt_configure_dt(&config->inta_gpios, GPIO_INT_EDGE_FALLING); + if (ret) { + LOG_ERR("Failed to configure INT GPIO interrupt"); + return ret; + } + + gpio_init_callback(&data->int_callback, rtc_max31331_gpio_callback, + BIT(config->inta_gpios.pin)); + ret = gpio_add_callback(config->inta_gpios.port, &data->int_callback); + if (ret) { + LOG_ERR("Failed to add INT GPIO callback"); + return ret; + } + + data->dev = dev; +#if defined(CONFIG_RTC_MAX31331_INTERRUPT_GLOBAL_THREAD) + k_work_init(&data->work, max31331_work_cb); +#elif defined(CONFIG_RTC_MAX31331_INTERRUPT_OWN_THREAD) + k_sem_init(&data->sem, 0, K_SEM_MAX_LIMIT); + + k_thread_create(&data->thread, data->thread_stack, CONFIG_RTC_MAX31331_THREAD_STACK_SIZE, + (k_thread_entry_t)max31331_thread, data, NULL, NULL, + K_PRIO_COOP(CONFIG_RTC_MAX31331_THREAD_PRIORITY), 0, K_NO_WAIT); + k_thread_name_set(&data->thread, dev->name); +#endif + + return 0; +} + +#endif + +#ifdef CONFIG_RTC_MAX31331_TIMESTAMPING + +/** + * @brief Initialize timestamp callback for MAX31331 RTC + * + * @param dev Device Descriptor + * @return int 0 on success, negative error code on failure + */ +static int rtc_max31331_timestamp_callback_init(const struct device *dev) +{ + struct rtc_max31331_data *data = dev->data; + + data->ts_callback = NULL; + data->ts_user_data = NULL; + return 0; +} + +/** + * @brief Initialize timestamping functionality for MAX31331 RTC + * + * @param dev Device Descriptor + * @return int 0 on success, negative error code on failure + */ +static int rtc_max31331_timestamping_init(const struct device *dev) +{ + const struct rtc_max31331_config *config = dev->config; + struct rtc_max31331_data *data = dev->data; + int ret = 0; + + memset(data->timestamp_buffer, 0, sizeof(data->timestamp_buffer)); + + ret = max31331_reg_write( + dev, MAX31331_TIMESTAMP_CONFIG, + (config->ts_enable ? TS_ENABLE_MASK : 0) | + (config->ts_vbat_enable ? TS_VBAT_LOW_EN_MASK : 0) | + (config->ts_din ? TS_DIN_MASK : 0) | + (config->ts_overwrite ? TS_OVERWRITE_MASK : 0) | + (config->ts_power_supply_switch ? TS_POWER_SUPPLY_SWITCH_MASK : 0)); + + if (ret) { + LOG_ERR("Failed to configure timestamping"); + return ret; + } + + ret = max31331_reg_update(dev, MAX31331_RTC_CONFIG1, EN_IOUTPUT_MASK, config->din_en_io); + if (ret) { + LOG_ERR("Failed to configure timestamping I/O"); + return ret; + } + + ret = max31331_reg_update(dev, MAX31331_RTC_CONFIG1, DIGITAL_INPUT_POLARITY_MASK, + config->din_polarity); + if (ret) { + LOG_ERR("Failed to configure timestamping DIN polarity"); + return ret; + } + + ret = rtc_max31331_timestamp_callback_init(dev); + if (ret) { + LOG_ERR("Failed to initialize timestamp callback"); + return ret; + } + + return 0; +} + +/** + * @brief Set timestamp callback for MAX31331 RTC + * + * @param dev Device Descriptor + * @param cb Timestamp callback function + * @param user_data User data pointer to be passed to the callback + * @return int 0 on success, negative error code on failure + */ +int rtc_max31331_set_timestamp_callback(const struct device *dev, + rtc_max31331_timestamp_callback cb, void *user_data) +{ + int ret; + struct rtc_max31331_data *data = dev->data; + + data->ts_callback = cb; + data->ts_user_data = user_data; + + ret = max31331_reg_update(dev, MAX31331_INTERRUPT_ENABLE, DIGITAL_INTERRUPT_ENABLE_MASK, + (cb != NULL) ? 1 : 0); + if (ret) { + LOG_ERR("Failed to %s timestamp interrupt", (cb != NULL) ? "enable" : "disable"); + return ret; + } + return 0; +} + +/** + * @brief Get timestamp from MAX31331 RTC + * + * @param dev Device Descriptor + * @param timeptr Pointer to rtc_time structure to store the retrieved timestamp + * @param index Timestamp index (0-3) + * @param flags Pointer to store timestamp flags + * @return int 0 on success, negative error code on failure + */ +int rtc_max31331_get_timestamps(const struct device *dev, struct rtc_time *timeptr, uint8_t index, + uint8_t *flags) +{ + int ret = 0; + uint8_t start_addr = 0; + uint8_t reg_buf[7]; + + switch (index) { + case 0: + start_addr = MAX31331_TS0_SEC; + break; + case 1: + start_addr = MAX31331_TS1_SEC; + break; + case 2: + start_addr = MAX31331_TS2_SEC; + break; + case 3: + start_addr = MAX31331_TS3_SEC; + break; + default: + LOG_ERR("Invalid timestamp index"); + return -EINVAL; + } + + ret = max31331_reg_read(dev, start_addr, reg_buf, ARRAY_SIZE(reg_buf)); + if (ret) { + LOG_ERR("Failed to read timestamp count"); + return ret; + } + + timeptr->tm_sec = bcd2bin(reg_buf[0] & SECONDS_FIELD_MASK); + timeptr->tm_min = bcd2bin(reg_buf[1] & MINUTES_FIELD_MASK); + timeptr->tm_hour = bcd2bin(reg_buf[2] & HOURS_FIELD_MASK); + timeptr->tm_mday = bcd2bin(reg_buf[3] & DATE_FIELD_MASK); + timeptr->tm_mon = bcd2bin(reg_buf[4] & MONTH_FIELD_MASK) - 1; + if (reg_buf[4] & CENTURY_MASK) { + timeptr->tm_year = bcd2bin(reg_buf[5] & YEAR_FIELD_MASK) + MAX31331_YEAR_2100; + } else { + timeptr->tm_year = bcd2bin(reg_buf[5] & YEAR_FIELD_MASK); + } + + *flags = reg_buf[6]; + + return 0; +} + +#endif + +/** + * @brief Initialize MAX31331 RTC device + * + * @param dev Device Descriptor + * @return int 0 on success, negative error code on failure + */ +static int rtc_max31331_init(const struct device *dev) +{ + const struct rtc_max31331_config *config = dev->config; + int ret; + + if (!i2c_is_ready_dt(&config->i2c)) { + return -ENODEV; + } + + ret = max31331_reg_write(dev, MAX31331_RTC_RESET, SW_RESET_MASK); + if (ret) { + LOG_ERR("Failed to reset the device"); + return ret; + } + + ret = max31331_reg_write(dev, MAX31331_RTC_RESET, 0); + if (ret) { + LOG_ERR("Failed to reset the device"); + return ret; + } + + ret = max31331_reg_update(dev, MAX31331_RTC_CONFIG2, CLKOUT_ENABLE_MASK, 1); + + if (ret) { + LOG_ERR("Failed to enable CLKOUT"); + return ret; + } + + ret = max31331_reg_update(dev, MAX31331_TIMESTAMP_CONFIG, TS_REG_RESET_MASK, 1); + if (ret) { + LOG_ERR("Failed to reset timestamp registers"); + return ret; + } + +#if defined(CONFIG_RTC_MAX31331_TIMESTAMPING) + ret = rtc_max31331_timestamping_init(dev); + if (ret) { + LOG_ERR("Failed to initialize timestamping"); + return ret; + } +#endif + +#ifdef CONFIG_RTC_ALARM + if (config->inta_gpios.port) { + ret = rtc_max31331_alarm_init(dev); + if (ret) { + LOG_ERR("Failed to initialize alarms"); + return ret; + } + } +#endif + + ret = max31331_reg_update(dev, MAX31331_RTC_CONFIG1, ENABLE_OSCILLATOR_MASK, 1); + if (ret) { + LOG_ERR("Failed to enable oscillator"); + return ret; + } + + return 0; +} + +static DEVICE_API(rtc, rtc_max31331) = { + .set_time = rtc_max31331_set_time, + .get_time = rtc_max31331_get_time, +#ifdef CONFIG_RTC_ALARM + .alarm_set_time = rtc_max31331_alarm_set_time, + .alarm_get_time = rtc_max31331_alarm_get_time, + .alarm_is_pending = rtc_max31331_alarm_is_pending, + .alarm_set_callback = rtc_max31331_alarm_set_callback, + .alarm_get_supported_fields = rtc_max31331_alarm_get_supported_fields, +#endif +}; + +#define RTC_MAX31331_CONFIG(inst) \ + .ts_enable = DT_INST_PROP(inst, ts_enable), \ + .ts_vbat_enable = DT_INST_PROP(inst, ts_vbat_enable), \ + .ts_din = DT_INST_PROP(inst, ts_din), .ts_overwrite = DT_INST_PROP(inst, ts_overwrite), \ + .ts_power_supply_switch = DT_INST_PROP(inst, ts_power_supply_switch), \ + .din_en_io = DT_INST_PROP(inst, din_en_io), \ + .din_polarity = DT_INST_PROP(inst, din_polarity) + +#define RTC_MAX31331_DEFINE(inst) \ + static struct rtc_max31331_data rtc_max31331_prv_data_##inst; \ + static const struct rtc_max31331_config rtc_max31331_config##inst = { \ + .i2c = I2C_DT_SPEC_INST_GET(inst), \ + RTC_MAX31331_CONFIG(inst), \ + IF_ENABLED(CONFIG_RTC_ALARM, \ + (.inta_gpios = \ + GPIO_DT_SPEC_INST_GET_OR(inst, interrupt_gpios, \ + {0}))) }; \ + \ + DEVICE_DT_INST_DEFINE(inst, rtc_max31331_init, NULL, &rtc_max31331_prv_data_##inst, \ + &rtc_max31331_config##inst, POST_KERNEL, CONFIG_RTC_INIT_PRIORITY, \ + &rtc_max31331); + +DT_INST_FOREACH_STATUS_OKAY(RTC_MAX31331_DEFINE) diff --git a/drivers/rtc/rtc_max31331.h b/drivers/rtc/rtc_max31331.h new file mode 100644 index 000000000000..354ef904ff36 --- /dev/null +++ b/drivers/rtc/rtc_max31331.h @@ -0,0 +1,442 @@ +/* + * Copyright (c) 2025 Analog Devices Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_RTC_RTC_MAX31331_H +#define ZEPHYR_DRIVERS_RTC_RTC_MAX31331_H +#include +#include +#include +#include +#ifdef CONFIG_RTC_MAX31331_TIMESTAMPING +#include +#endif + +#define MAX31331_STATUS_REG 0x00u +#define MAX31331_INTERRUPT_ENABLE 0x01u +#define MAX31331_RTC_RESET 0x02u +#define MAX31331_RTC_CONFIG1 0x03u +#define MAX31331_RTC_CONFIG2 0x04u +#define MAX31331_TIMESTAMP_CONFIG 0x05u +#define MAX31331_TIMER_CONFIG 0x06u +#define MAX31331_SECONDS_1_128 0x07u +#define MAX31331_SECONDS 0x08u +#define MAX31331_MINUTES 0x09u +#define MAX31331_HOURS 0x0Au +#define MAX31331_DAY 0x0Bu +#define MAX31331_DATE 0x0Cu +#define MAX31331_MONTH 0x0Du +#define MAX31331_YEAR 0x0Eu +#define MAX31331_ALARM_1_SECONDS 0x0Fu +#define MAX31331_ALARM_1_MINUTES 0x10u +#define MAX31331_ALARM_1_HOURS 0x11u +#define MAX31331_ALARM_1_DAY_DATE 0x12u +#define MAX31331_ALARM_1_MONTH 0x13u +#define MAX31331_ALARM_1_YEAR 0x14u +#define MAX31331_ALARM_2_MINUTES 0x15u +#define MAX31331_ALARM_2_HOURS 0x16u +#define MAX31331_ALARM_2_DAY_DATE 0x17u +#define MAX31331_TIMER_COUNT 0x18u +#define MAX31331_TIMER_INIT 0x19u +#define MAX31331_POWER_MANAGEMENT 0x1Au +#define MAX31331_TRICKLE_REG 0x1Bu +#define MAX31331_OFFSET_HIGH 0x1Du +#define MAX31331_OFFSET_LOW 0x1Eu + +/** TS RAM REGISTERS */ +#define MAX31331_TS0_SEC_1_128 0x20u +#define MAX31331_TS0_SEC 0x21u +#define MAX31331_TS0_MIN 0x22u +#define MAX31331_TS0_HOUR 0x23u +#define MAX31331_TS0_DATE 0x24u +#define MAX31331_TS0_MONTH 0x25u +#define MAX31331_TS0_YEAR 0x26u +#define MAX31331_TS0_FLAGS 0x27u +#define MAX31331_TS1_SEC_1_128 0x28u +#define MAX31331_TS1_SEC 0x29u +#define MAX31331_TS1_MIN 0x2Au +#define MAX31331_TS1_HOUR 0x2Bu +#define MAX31331_TS1_DATE 0x2Cu +#define MAX31331_TS1_MONTH 0x2Du +#define MAX31331_TS1_YEAR 0x2Eu +#define MAX31331_TS1_FLAGS 0x2Fu +#define MAX31331_TS2_SEC_1_128 0x30u +#define MAX31331_TS2_SEC 0x31u +#define MAX31331_TS2_MIN 0x32u +#define MAX31331_TS2_HOUR 0x33u +#define MAX31331_TS2_DATE 0x34u +#define MAX31331_TS2_MONTH 0x35u +#define MAX31331_TS2_YEAR 0x36u +#define MAX31331_TS2_FLAGS 0x37u +#define MAX31331_TS3_SEC_1_128 0x38u +#define MAX31331_TS3_SEC 0x39u +#define MAX31331_TS3_MIN 0x3Au +#define MAX31331_TS3_HOUR 0x3Bu +#define MAX31331_TS3_DATE 0x3Cu +#define MAX31331_TS3_MONTH 0x3Du +#define MAX31331_TS3_YEAR 0x3Eu +#define MAX31331_TS3_FLAGS 0x3Fu + +/** REGISTER MASKS */ + +/** STATUS REGISTERS MASKS*/ +#define POWER_SOURCE_MASK BIT(7) +#define OSCILLATOR_STOP_FLAG_MASK BIT(6) +#define POWER_FAIL_MASK BIT(5) +#define VBATLOW_MASK BIT(4) +#define DIGITAL_INTERRUPT_MASK BIT(3) +#define TIMER_FLAG_MASK BIT(2) +#define ALARM_2_FLAG_MASK BIT(1) +#define ALARM_1_FLAG_MASK BIT(0) + +/** INTERRUPT ENABLE MASKS */ +#define DISABLE_OSCILLATOR_FLAG_MASK BIT(6) +#define POWER_FAIL_INTERRUPT_ENABLE_MASK BIT(5) +#define VBATLOW_INTERRUPT_ENABLE_MASK BIT(4) +#define DIGITAL_INTERRUPT_ENABLE_MASK BIT(3) +#define TIMER_INTERRUPT_ENABLE_MASK BIT(2) +#define ALARM_2_INTERRUPT_ENABLE_MASK BIT(1) +#define ALARM_1_INTERRUPT_ENABLE_MASK BIT(0) + +/** RTC RESET MASKS */ +#define SW_RESET_MASK BIT(0) + +/** RTC CONFIG1 MASKS */ +#define EN_IOUTPUT_MASK BIT(6) +#define ALARM1_AUTO_CLEAR_MASK GENMASK(5, 4) +#define DIGITAL_INPUT_POLARITY_MASK BIT(3) +#define ENABLE_I2C_TIMEOUT_MASK BIT(1) +#define ENABLE_OSCILLATOR_MASK BIT(0) + +/** RTC CONFIG2 MASKS */ +#define CLKOUT_ENABLE_MASK BIT(2) +#define CLKO_HZ_MASK GENMASK(1, 0) + +/** RTC TIMESTAMP CONFIG MASKS */ +#define TS_VBAT_LOW_EN_MASK BIT(5) +#define TS_POWER_SUPPLY_SWITCH_MASK BIT(4) +#define TS_DIN_MASK BIT(3) +#define TS_OVERWRITE_MASK BIT(2) +#define TS_REG_RESET_MASK BIT(1) +#define TS_ENABLE_MASK BIT(0) + +/** RTC TIMER CONFIG MASKS */ +#define TIMER_ENABLE_MASK BIT(4) +#define TIMER_PAUSE_MASK BIT(3) +#define TIMER_REPEAT_MODE_MASK BIT(2) +#define TIMER_FREQUENCY_SELECTION GENMASK(1, 0) + +/** RTC SECONDS 1_128 MASKS */ +#define SECONDS_1_2_MASK BIT(6) +#define SECONDS_1_4_MASK BIT(5) +#define SECONDS_1_8_MASK BIT(4) +#define SECONDS_1_16_MASK BIT(3) +#define SECONDS_1_32_MASK BIT(2) +#define SECONDS_1_64_MASK BIT(1) +#define SECONDS_1_128_MASK BIT(0) + +/** RTC SECONDS MASKS */ +#define SECONDS_10_MASK GENMASK(6, 4) +#define SECONDS_MASK GENMASK(3, 0) +#define SECONDS_FIELD_MASK (SECONDS_10_MASK | SECONDS_MASK) + +/** RTC MINUTES MASKS */ +#define MINUTES_10_MASK GENMASK(6, 4) +#define MINUTES_MASK GENMASK(3, 0) +#define MINUTES_FIELD_MASK (MINUTES_10_MASK | MINUTES_MASK) + +/** RTC HOURS MASKS */ +#define F24_12_MASK BIT(6) +#define HOUR_20_AM_PM_MASK BIT(5) +#define HOURS_10_MASK BIT(4) +#define HOURS_MASK GENMASK(3, 0) +#define HOURS_FIELD_MASK (HOUR_20_AM_PM_MASK | HOURS_10_MASK | HOURS_MASK) + +/** RTC DAY MASKS */ +#define DAY_FIELD_MASK GENMASK(2, 0) +#define MAX31331_DAY_OFFSET -1 + +/** RTC DATE MASKS */ +#define DATE_10_MASK GENMASK(5, 4) +#define DATE_MASK GENMASK(3, 0) +#define DATE_FIELD_MASK (DATE_10_MASK | DATE_MASK) + +/** RTC MONTH MASKS */ +#define MONTH_10_MASK BIT(4) +#define MONTH_MASK GENMASK(3, 0) +#define MONTH_FIELD_MASK (MONTH_10_MASK | MONTH_MASK) + +/** RTC YEAR MASKS */ +#define YEAR_10_MASK GENMASK(7, 4) +#define YEAR_MASK GENMASK(3, 0) +#define YEAR_FIELD_MASK (YEAR_10_MASK | YEAR_MASK) + +/** CENTURY DETERMINANT*/ +#define MAX31331_YEAR_2100 (2100 - 2000) + +/** ALARM 1 MASKS */ + +/** ALARM 1 SECONDS MASKS */ +#define ALARM_1_SECONDS_ENABLE_MASK BIT(7) +#define ALARM_1_SECONDS_10_MASK GENMASK(6, 4) +#define ALARM_1_SECONDS_MASK GENMASK(3, 0) +#define ALARM_1_SECONDS_FIELD_MASK (ALARM_1_SECONDS_10_MASK | ALARM_1_SECONDS_MASK) + +/** ALARM 1 MINUTES MASKS */ +#define ALARM_1_MINUTES_ENABLE_MASK BIT(7) +#define ALARM_1_MINUTES_10_MASK GENMASK(6, 4) +#define ALARM_1_MINUTES_MASK GENMASK(3, 0) +#define ALARM_1_MINUTES_FIELD_MASK (ALARM_1_MINUTES_10_MASK | ALARM_1_MINUTES_MASK) + +/** ALARM 1 HOURS MASKS */ +#define ALARM_1_HOURS_ENABLE_MASK BIT(7) +#define ALARM_1_HR_20_AM_PM_MASK BIT(5) +#define ALARM_1_HOURS_10_MASK BIT(4) +#define ALARM_1_HOURS_MASK GENMASK(3, 0) +#define ALARM_1_HOURS_FIELD_MASK \ + (ALARM_1_HOURS_10_MASK | ALARM_1_HOURS_MASK | ALARM_1_HR_20_AM_PM_MASK) + +/** ALARM 1 DAY/DATE MASKS */ +#define ALARM_1_DAY_DATE_ENABLE_MASK BIT(7) +#define ALARM_1_DAY_DATE_OP_MASK BIT(6) +#define ALARM_1_DATE_10_MASK GENMASK(5, 4) +#define ALARM_1_DAY_DATE_MASK GENMASK(3, 0) +#define ALARM_1_DAY_DATE_FIELD_MASK (ALARM_1_DATE_10_MASK | ALARM_1_DAY_DATE_MASK) + +/** ALARM 1 MONTH MASKS */ +#define ALARM_1_MONTH_ENABLE_MASK BIT(7) +#define ALARM_1_YEAR_ENABLE_MASK BIT(6) +#define ALARM_1_MONTH_10_MASK BIT(4) +#define ALARM_1_MONTH_MASK GENMASK(3, 0) +#define ALARM_1_MONTH_FIELD_MASK (ALARM_1_MONTH_10_MASK | ALARM_1_MONTH_MASK) + +/** ALARM 1 YEAR MASKS */ +#define ALARM_1_YEAR_10_MASK GENMASK(7, 4) +#define ALARM_1_YEAR_MASK GENMASK(3, 0) +#define ALARM_1_YEAR_FIELD_MASK (ALARM_1_YEAR_10_MASK | ALARM_1_YEAR_MASK) +/** ALARM 2 MASKS */ + +/** ALARM 2 MINUTES MASKS */ +#define ALARM_2_MINUTES_ENABLE_MASK BIT(7) +#define ALARM_2_MINUTES_10_MASK GENMASK(6, 4) +#define ALARM_2_MINUTES_MASK GENMASK(3, 0) +#define ALARM_2_MINUTES_FIELD_MASK (ALARM_2_MINUTES_10_MASK | ALARM_2_MINUTES_MASK) + +/** ALARM 2 HOURS MASKS */ +#define ALARM_2_HOURS_ENABLE_MASK BIT(7) +#define ALARM_2_HR_20_AM_PM_MASK BIT(5) +#define ALARM_2_HOURS_10_MASK BIT(4) +#define ALARM_2_HOURS_MASK GENMASK(3, 0) +#define ALARM_2_HOURS_FIELD_MASK \ + (ALARM_2_HOURS_10_MASK | ALARM_2_HOURS_MASK | ALARM_2_HR_20_AM_PM_MASK) + +/** ALARM 2 DAY/DATE MASKS */ +#define ALARM_2_DAY_DATE_ENABLE_MASK BIT(7) +#define ALARM_2_DAY_DATE_OP_MASK BIT(6) +#define ALARM_2_DATE_10_MASK GENMASK(5, 4) +#define ALARM_2_DAY_DATE_MASK GENMASK(3, 0) +#define ALARM_2_DAY_DATE_FIELD_MASK (ALARM_2_DATE_10_MASK | ALARM_2_DAY_DATE_MASK) + +/** TIMER COUNT MASKS */ +#define TIMER_COUNT_MASK GENMASK(7, 0) + +/** TIMER INITIAL MASKS */ +#define TIMER_INIT_MASK GENMASK(7, 0) + +/** POWER MANAGEMENT MASKS */ +#define BACKUP_BATTERY_SELECT_MASK BIT(1) +#define MANUAL_SEL_MASK BIT(0) + +/** TRICKLE REG MASKS */ +#define TRICKLE_MASKS GENMASK(3, 1) +#define TRICKLE_ENABLE_MASK BIT(0) + +/** OFFSET HIGH */ +#define COMPWORD_MSB_MASK GENMASK(7, 0) + +/** OFFSET LOW */ +#define COMPWORD_LSB_MASK GENMASK(7, 0) + +/** TIMESTAMP 0 MASKS */ + +/** TIMESTAMP 0 SECONDS 1_128 MASKS */ +#define TS0_SECONDS_1_2_MASK BIT(6) +#define TS0_SECONDS_1_4_MASK BIT(5) +#define TS0_SECONDS_1_8_MASK BIT(4) +#define TS0_SECONDS_1_16_MASK BIT(3) +#define TS0_SECONDS_1_32_MASK BIT(2) +#define TS0_SECONDS_1_64_MASK BIT(1) +#define TS0_SECONDS_1_128_MASK BIT(0) + +/** TIMESTAMP 0 SECONDS MASKS */ +#define TS0_SECONDS_10_MASK GENMASK(6, 4) +#define TS0_SECONDS_MASK GENMASK(3, 0) + +/** TIMESTAMP 0 MINUTES MASKS */ +#define TS0_MINUTES_10_MASK GENMASK(6, 4) +#define TS0_MINUTES_MASK GENMASK(3, 0) + +/** TIMESTAMP 0 HOURS MASKS */ +#define TS0_F24_12_MASK BIT(6) +#define TS0_HOUR_20_AM_PM_MASK BIT(5) +#define TS0_HOURS_10_MASK BIT(4) +#define TS0_HOURS_MASK GENMASK(3, 0) + +/** TIMESTAMP 0 DATE MASKS */ +#define TS0_DATE_10_MASK GENMASK(5, 4) +#define TS0_DATE_MASK GENMASK(3, 0) + +/** TIMESTAMP 0 MONTH MASKS */ +#define CENTURY_MASK BIT(7) +#define TS0_MONTH_10_MASK BIT(4) +#define TS0_MONTH_MASK GENMASK(3, 0) + +/** TIMESTAMP 0 YEAR MASKS */ +#define TS0_YEAR_10_MASK GENMASK(7, 4) +#define TS0_YEAR_MASK GENMASK(3, 0) + +/** TIMESTAMP 0 FLAGS MASKS */ +#define TS0_V_LOW_MASK BIT(3) +#define TS0_V_BAT_TO_VCC_SWITCH_MASK BIT(2) +#define TS0_VCC_TO_V_BAT_SWITCH_MASK BIT(1) +#define TS0_DIN_MASK BIT(0) + +/** TIMESTAMP 1 MASKS */ + +/** TIMESTAMP 1 SECONDS 1_128 MASKS */ +#define TS1_SECONDS_1_2_MASK BIT(6) +#define TS1_SECONDS_1_4_MASK BIT(5) +#define TS1_SECONDS_1_8_MASK BIT(4) +#define TS1_SECONDS_1_16_MASK BIT(3) +#define TS1_SECONDS_1_32_MASK BIT(2) +#define TS1_SECONDS_1_64_MASK BIT(1) +#define TS1_SECONDS_1_128_MASK BIT(0) + +/** TIMESTAMP 1 SECONDS MASKS */ +#define TS1_SECONDS_10_MASK GENMASK(6, 4) +#define TS1_SECONDS_MASK GENMASK(3, 0) + +/** TIMESTAMP 1 MINUTES MASKS */ +#define TS1_MINUTES_10_MASK GENMASK(6, 4) +#define TS1_MINUTES_MASK GENMASK(3, 0) + +/** TIMESTAMP 1 HOURS MASKS */ +#define TS1_F24_12_MASK BIT(6) +#define TS1_HOUR_20_AM_PM_MASK BIT(5) +#define TS1_HOURS_10_MASK BIT(4) +#define TS1_HOURS_MASK GENMASK(3, 0) + +/** TIMESTAMP 1 DATE MASKS */ +#define TS1_DATE_10_MASK GENMASK(5, 4) +#define TS1_DATE_MASK GENMASK(3, 0) + +/** TIMESTAMP 1 MONTH MASKS */ +#define TS1_CENTURY_MASK BIT(7) +#define TS1_MONTH_10_MASK BIT(4) +#define TS1_MONTH_MASK GENMASK(3, 0) + +/** TIMESTAMP 1 YEAR MASKS */ +#define TS1_YEAR_10_MASK GENMASK(7, 4) +#define TS1_YEAR_MASK GENMASK(3, 0) + +/** TIMESTAMP 1 FLAGS MASKS */ +#define TS1_V_LOW_MASK BIT(3) +#define TS1_V_BAT_TO_VCC_SWITCH_MASK BIT(2) +#define TS1_VCC_TO_V_BAT_SWITCH_MASK BIT(1) +#define TS1_DIN_MASK BIT(0) + +/** TIMESTAMP 2 MASKS */ +/** TIMESTAMP 2 SECONDS 1_128 MASKS */ +#define TS2_SECONDS_1_2_MASK BIT(6) +#define TS2_SECONDS_1_4_MASK BIT(5) +#define TS2_SECONDS_1_8_MASK BIT(4) +#define TS2_SECONDS_1_16_MASK BIT(3) +#define TS2_SECONDS_1_32_MASK BIT(2) +#define TS2_SECONDS_1_64_MASK BIT(1) +#define TS2_SECONDS_1_128_MASK BIT(0) + +/** TIMESTAMP 2 SECONDS MASKS */ +#define TS2_SECONDS_10_MASK GENMASK(6, 4) +#define TS2_SECONDS_MASK GENMASK(3, 0) + +/** TIMESTAMP 2 MINUTES MASKS */ +#define TS2_MINUTES_10_MASK GENMASK(6, 4) +#define TS2_MINUTES_MASK GENMASK(3, 0) + +/** TIMESTAMP 2 HOURS MASKS */ +#define TS2_F24_12_MASK BIT(6) +#define TS2_HOUR_20_AM_PM_MASK BIT(5) +#define TS2_HOURS_10_MASK BIT(4) +#define TS2_HOURS_MASK GENMASK(3, 0) + +/** TIMESTAMP 2 DATE MASKS */ +#define TS2_DATE_10_MASK GENMASK(5, 4) +#define TS2_DATE_MASK GENMASK(3, 0) + +/** TIMESTAMP 2 MONTH MASKS */ +#define TS2_CENTURY_MASK BIT(7) +#define TS2_MONTH_10_MASK BIT(4) +#define TS2_MONTH_MASK GENMASK(3, 0) + +/** TIMESTAMP 2 YEAR MASKS */ +#define TS2_YEAR_10_MASK GENMASK(7, 4) +#define TS2_YEAR_MASK GENMASK(3, 0) + +/** TIMESTAMP 2 FLAGS MASKS */ +#define TS2_V_LOW_MASK BIT(3) +#define TS2_V_BAT_TO_VCC_SWITCH_MASK BIT(2) +#define TS2_VCC_TO_V_BAT_SWITCH_MASK BIT(1) +#define TS2_DIN_MASK BIT(0) + +/** TIMESTAMP 3 MASKS */ +/** TIMESTAMP 3 SECONDS 1_128 MASKS */ +#define TS3_SECONDS_1_2_MASK BIT(6) +#define TS3_SECONDS_1_4_MASK BIT(5) +#define TS3_SECONDS_1_8_MASK BIT(4) +#define TS3_SECONDS_1_16_MASK BIT(3) +#define TS3_SECONDS_1_32_MASK BIT(2) +#define TS3_SECONDS_1_64_MASK BIT(1) +#define TS3_SECONDS_1_128_MASK BIT(0) + +/** TIMESTAMP 3 SECONDS MASKS */ +#define TS3_SECONDS_10_MASK GENMASK(6, 4) +#define TS3_SECONDS_MASK GENMASK(3, 0) + +/** TIMESTAMP 3 MINUTES MASKS */ +#define TS3_MINUTES_10_MASK GENMASK(6, 4) +#define TS3_MINUTES_MASK GENMASK(3, 0) + +/** TIMESTAMP 3 HOURS MASKS */ +#define TS3_F24_12_MASK BIT(6) +#define TS3_HOUR_20_AM_PM_MASK BIT(5) +#define TS3_HOURS_10_MASK BIT(4) +#define TS3_HOURS_MASK GENMASK(3, 0) + +/** TIMESTAMP 3 DATE MASKS */ +#define TS3_DATE_10_MASK GENMASK(5, 4) +#define TS3_DATE_MASK GENMASK(3, 0) + +/** TIMESTAMP 3 MONTH MASKS */ +#define TS3_CENTURY_MASK BIT(7) +#define TS3_MONTH_10_MASK BIT(4) +#define TS3_MONTH_MASK GENMASK(3, 0) + +/** TIMESTAMP 3 YEAR MASKS */ +#define TS3_YEAR_10_MASK GENMASK(7, 4) +#define TS3_YEAR_MASK GENMASK(3, 0) + +/** TIMESTAMP 3 FLAGS MASKS */ +#define TS3_V_LOW_MASK BIT(3) +#define TS3_V_BAT_TO_VCC_SWITCH_MASK BIT(2) +#define TS3_VCC_TO_V_BAT_SWITCH_MASK BIT(1) +#define TS3_DIN_MASK BIT(0) + +#define MAX31331_RTC_TIME_MASK \ + (RTC_ALARM_TIME_MASK_SECOND | RTC_ALARM_TIME_MASK_MINUTE | RTC_ALARM_TIME_MASK_HOUR | \ + RTC_ALARM_TIME_MASK_MONTH | RTC_ALARM_TIME_MASK_MONTHDAY | RTC_ALARM_TIME_MASK_YEAR | \ + RTC_ALARM_TIME_MASK_WEEKDAY) + +#define ALARM_COUNT 2 +#endif /* ZEPHYR_DRIVERS_RTC_RTC_MAX31331_H */ diff --git a/dts/bindings/rtc/adi,max31331.yaml b/dts/bindings/rtc/adi,max31331.yaml new file mode 100644 index 000000000000..8f98f868c639 --- /dev/null +++ b/dts/bindings/rtc/adi,max31331.yaml @@ -0,0 +1,46 @@ +# Copyright (c) 2025 Analog Devices Inc. +# SPDX-License-Identifier: Apache-2.0 +# +# This file contains the binding for MAX31331 RTC from Analog Devices. + +description: MAX31331, an Ultra-Low-Power, I2C Real-Time Clock. + +compatible: "adi,max31331" + +include: [rtc-device.yaml, i2c-device.yaml] + +properties: + reg: + required: true + + interrupt-gpios: + description: "GPIO connected to the INT pin of the MAX31331." + type: phandle-array + + ts-enable: + description: "Enable the timestamping feature of the MAX31331." + type: boolean + + ts-vbat-enable: + description: "Enable timestamping in VBAT mode." + type: boolean + + ts-din: + description: "Data input for timestamping." + type: boolean + + ts-overwrite: + description: "Enable overwriting of the timestamp register." + type: boolean + + ts-power-supply-switch: + description: "Enable power supply switch for timestamping." + type: boolean + + din-polarity: + description: "Polarity of the data input for timestamping." + type: boolean + + din-en-io: + description: "Enable data input as IO." + type: boolean diff --git a/include/zephyr/drivers/rtc/rtc_max31331.h b/include/zephyr/drivers/rtc/rtc_max31331.h new file mode 100644 index 000000000000..578d55dce439 --- /dev/null +++ b/include/zephyr/drivers/rtc/rtc_max31331.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2025 Analog Devices Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef ZEPHYR_INCLUDE_RTC_RTC_MAX31331_H +#define ZEPHYR_INCLUDE_RTC_RTC_MAX31331_H + +#include +#include +#include +#include + +/** + * @brief MAX31331 timestamp callback type + * + * @param dev Pointer to the RTC device. + * @param user_data Pointer to user context. + */ +typedef void (*rtc_max31331_timestamp_callback)(const struct device *dev, void *user_data); + +/** + * @brief Read a stored timestamp from the MAX31331. + * + * @param dev Pointer to the RTC device. + * @param timeptr Pointer to struct rtc_time to store result. + * @param index Timestamp index (0–3). + * @param flags Pointer to variable receiving timestamp flags. + * + * @retval 0 If successful. + * @retval negative errno code otherwise. + */ +int rtc_max31331_get_timestamps(const struct device *dev, struct rtc_time *timeptr, uint8_t index, + uint8_t *flags); + +/** + * @brief Register a timestamp event callback. + * + * @param dev Pointer to the RTC device. + * @param cb Callback function pointer. + * @param user_data Application-provided context. + * + * @retval 0 If successful. + * @retval negative errno code otherwise. + */ +int rtc_max31331_set_timestamp_callback(const struct device *dev, + rtc_max31331_timestamp_callback cb, void *user_data); + +#endif /* ZEPHYR_DRIVERS_RTC_RTC_MAX31331_H */ From 6ca6fb82331766d24b799628737cd880359b7f80 Mon Sep 17 00:00:00 2001 From: Francis Roi Manabat Date: Mon, 22 Dec 2025 21:05:13 +0800 Subject: [PATCH 1793/3659] tests: rtc: include adi,max31331 in build_all test suite Add the MAX31331 RTC device to the build_all RTC test suite. This ensures it compiles on all supported platforms without requiring actual hardware. Signed-off-by: Francis Roi Manabat --- tests/drivers/build_all/rtc/i2c_devices.overlay | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/drivers/build_all/rtc/i2c_devices.overlay b/tests/drivers/build_all/rtc/i2c_devices.overlay index f0cd27c33e87..4c5b075e2756 100644 --- a/tests/drivers/build_all/rtc/i2c_devices.overlay +++ b/tests/drivers/build_all/rtc/i2c_devices.overlay @@ -121,6 +121,12 @@ status = "okay"; }; }; + + test_max31331: max31331@d { + compatible = "adi,max31331"; + reg = <0xd>; + interrupt-gpios = <&test_gpio 0 0>; + }; }; }; }; From 8ca34066c619071ca83c448e65ab35cbf27cee3d Mon Sep 17 00:00:00 2001 From: Lyle Zhu Date: Mon, 22 Dec 2025 14:28:56 +0800 Subject: [PATCH 1794/3659] sample: Bluetooth: HFP_AG: Support voice transmission and playback Add PCM and CODEC support for voice streaming in the HFP AG sample. Implement PCM interface to handle voice data transmission between the Bluetooth controller and the application using I2S driver. Implement CODEC interface to handle voice playback and capture using I2S and audio codec drivers. Add bidirectional voice streaming: capture voice from CODEC and transmit through PCM when SCO connection is established, and receive voice from PCM and playback through CODEC. Initialize PCM and CODEC interfaces based on the SCO air mode (CVSD or mSBC) when SCO connection is established. Add codec negotiation callbacks to support codec selection. Enable codec negotiation and mSBC codec support for mimxrt1170_evk board. Add configuration options for audio transfer interval, buffer counts, and thread priorities for both PCM and CODEC RX threads. Update documentation with voice streaming topology diagram and running instructions. Signed-off-by: Lyle Zhu --- .../bluetooth/classic/handsfree_ag/Kconfig | 45 ++- .../bluetooth/classic/handsfree_ag/README.rst | 76 +++++ .../mimxrt1170_evk_mimxrt1176_cm7_B.conf | 10 + .../mimxrt1170_evk_mimxrt1176_cm7_B.overlay | 18 +- .../classic/handsfree_ag/src/codec.c | 314 ++++++++++++++++++ .../classic/handsfree_ag/src/codec.h | 21 ++ .../bluetooth/classic/handsfree_ag/src/main.c | 107 +++++- .../bluetooth/classic/handsfree_ag/src/pcm.c | 275 +++++++++++++++ .../bluetooth/classic/handsfree_ag/src/pcm.h | 21 ++ 9 files changed, 883 insertions(+), 4 deletions(-) create mode 100644 samples/bluetooth/classic/handsfree_ag/src/codec.c create mode 100644 samples/bluetooth/classic/handsfree_ag/src/codec.h create mode 100644 samples/bluetooth/classic/handsfree_ag/src/pcm.c create mode 100644 samples/bluetooth/classic/handsfree_ag/src/pcm.h diff --git a/samples/bluetooth/classic/handsfree_ag/Kconfig b/samples/bluetooth/classic/handsfree_ag/Kconfig index f3a1edbcdc9b..7ce7229353cf 100644 --- a/samples/bluetooth/classic/handsfree_ag/Kconfig +++ b/samples/bluetooth/classic/handsfree_ag/Kconfig @@ -1,5 +1,5 @@ # -# Copyright 2024 NXP +# Copyright 2024-2025 NXP # # SPDX-License-Identifier: Apache-2.0 # @@ -22,3 +22,46 @@ config BT_HFP_AG_START_CALL_DELAY_TIME call. The unit is ms. source "Kconfig.zephyr" + +config AUDIO_TRANSFER_INTERVAL + int "Audio transfer interval" + default 10 + range 1 100 + help + Controls the audio transfer interval. + +config PCM_BUFFERS + int "PCM Buffer Count" + default 4 + help + Controls the initial count of audio data blocks. + +config PCM_RX_THREAD_STACK_SIZE + int "PCM RX thread stack size" + default 1024 + help + Controls the PCM RX thread stack size in bytes. + +config PCM_RX_THREAD_PRIO + int "PCM RX thread priority" + default 4 + help + Controls the PCM RX thread priority. + +config CODEC_BUFFERS + int "CODEC Buffer Count" + default PCM_BUFFERS + help + Controls the initial count of audio data blocks. + +config CODEC_RX_THREAD_STACK_SIZE + int "CODEC RX thread stack size" + default 1024 + help + Controls the CODEC RX thread stack size in bytes. + +config CODEC_RX_THREAD_PRIO + int "CODEC RX thread priority" + default 4 + help + Controls the CODEC RX thread priority. diff --git a/samples/bluetooth/classic/handsfree_ag/README.rst b/samples/bluetooth/classic/handsfree_ag/README.rst index e36b6a973ab1..5a8cf86a12a9 100644 --- a/samples/bluetooth/classic/handsfree_ag/README.rst +++ b/samples/bluetooth/classic/handsfree_ag/README.rst @@ -19,3 +19,79 @@ Building and Running ******************** See :zephyr:code-sample-category:`bluetooth` samples for details. + +Running +******* + +The application works as a Hands-Free Audio Gateway. After the Bluetooth Host stack is initialized, +the GAP discovery procedure will be started automatically. The target device is Hands-Free Unit +(The major of COD is 0x04 (:c:macro:`BT_COD_MAJOR_AUDIO_VIDEO`), the minor of the COD is 0x02 +(:c:macro:`BT_COD_MAJOR_AUDIO_VIDEO_MINOR_HANDS_FREE`)). When the target device is discovered, +the AG will connect to the device. + +After the ACL connection is established, the AG will initiate the Service Discovery Protocol (SDP) +to discover the Hands-Free Unit's supported features. Once the HFP connection is established, the +AG will be ready to handle incoming calls and audio streaming requests from the connected HFP unit. + +The application will remain in a standby state, waiting for the outgoing call request from the +Hands-Free Unit. If there are no incoming or outgoing calls within the duration specified by +:kconfig:option:`CONFIG_BT_HFP_AG_START_CALL_DELAY_TIME`, the AG will start a simulation call. The +direction of the call is determined by :kconfig:option:`CONFIG_BT_HFP_AG_CALL_OUTGOING`. + +Once a call is initiated, the AG will establish an SCO (Synchronous Connection-Oriented) link for +audio transmission. + +When the SCO connect is established, the application will initialize the codec and pcm interface +for voice streaming if the codec and pcm configurations are available. + +The HFP application requires the following optional configuration options: +The codec depends on the devicetree alias named ``i2s-codec-rx`` and ``i2s-codec-tx``. +The PCM interface depends on the devicetree alias named ``pcm-rxtx``, or ``pcm-tx`` and ``pcm-rx``. + +After the call is active, the AG will start a delay-able worker with the 10 seconds timeout to +disconnect the ACL connection directly. + +This sample has been tested on :zephyr:board:`mimxrt1170_evk@B/mimxrt1176/cm7 `. + + +.. graphviz:: + :caption: Bluetooth Hands-Free Audio Gateway voice streaming topology + + + digraph bluetooth_hfp_ag { + rankdir=LR; + node [shape=box, style=rounded]; + edge [fontname=Courier, fontsize=9]; + init [shape=point]; + + subgraph cluster_hf { + label="Hands-Free Unit"; + style=filled; + HF [label="HFP HF"]; + } + + subgraph cluster_ag { + label="Zephyr Hands-Free AG"; + style=filled; + + BT_HOST [label="Host Stack"]; + BT_CTRL [label="Controller"]; + HFP_AG_APP [label="HFP AG Application"]; + CODEC [label="Audio Subsystem"]; + SPK [label="Speaker"]; + MIC [label="Microphone"]; + } + + HF -> BT_CTRL [label="SCO Link\n(BR/EDR)"]; + BT_CTRL -> HF [label="SCO Link\n(BR/EDR)"]; + BT_HOST -> BT_CTRL [label="HCI"]; + BT_CTRL -> BT_HOST [label="HCI"]; + BT_HOST -> HFP_AG_APP [label="AG Callbacks"]; + HFP_AG_APP -> BT_HOST [label="AG APIs"]; + HFP_AG_APP -> CODEC [label="Peer voice"]; + CODEC -> HFP_AG_APP [label="Local voice"]; + HFP_AG_APP -> BT_CTRL [label="Local voice\nPCM output"]; + BT_CTRL -> HFP_AG_APP [label="Peer voice\nPCM input"]; + CODEC -> SPK [label="Audio output"] + MIC -> CODEC [label="Audio input"] + } diff --git a/samples/bluetooth/classic/handsfree_ag/boards/mimxrt1170_evk_mimxrt1176_cm7_B.conf b/samples/bluetooth/classic/handsfree_ag/boards/mimxrt1170_evk_mimxrt1176_cm7_B.conf index 9e8851c73af1..6f0d43fde429 100644 --- a/samples/bluetooth/classic/handsfree_ag/boards/mimxrt1170_evk_mimxrt1176_cm7_B.conf +++ b/samples/bluetooth/classic/handsfree_ag/boards/mimxrt1170_evk_mimxrt1176_cm7_B.conf @@ -1,2 +1,12 @@ #select NXP NW612 Chipset CONFIG_BT_NXP_NW612=y + +CONFIG_I2S=y +CONFIG_DMA_TCD_QUEUE_SIZE=4 +CONFIG_AUDIO=y +CONFIG_AUDIO_CODEC=y + +CONFIG_BT_HFP_AG_CODEC_NEG=y +CONFIG_BT_HFP_AG_CODEC_MSBC=y + +CONFIG_DMA_MCUX_USE_DTCM_FOR_DMA_DESCRIPTORS=n diff --git a/samples/bluetooth/classic/handsfree_ag/boards/mimxrt1170_evk_mimxrt1176_cm7_B.overlay b/samples/bluetooth/classic/handsfree_ag/boards/mimxrt1170_evk_mimxrt1176_cm7_B.overlay index 96ef63ad60b2..16aa9ae4a521 100644 --- a/samples/bluetooth/classic/handsfree_ag/boards/mimxrt1170_evk_mimxrt1176_cm7_B.overlay +++ b/samples/bluetooth/classic/handsfree_ag/boards/mimxrt1170_evk_mimxrt1176_cm7_B.overlay @@ -1,5 +1,5 @@ /* - * Copyright 2024 NXP + * Copyright 2024-2025 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -8,4 +8,20 @@ chosen { zephyr,sram = &dtcm; }; + + aliases { + i2s-codec-rx = &sai1; + pcm-rxtx = &sai3; + }; +}; + +&sai1 { + status = "okay"; + mclk-output; + nxp,rx-sync-mode; +}; + +&sai3 { + status = "okay"; + nxp,rx-sync-mode; }; diff --git a/samples/bluetooth/classic/handsfree_ag/src/codec.c b/samples/bluetooth/classic/handsfree_ag/src/codec.c new file mode 100644 index 000000000000..e23dbeb94e2c --- /dev/null +++ b/samples/bluetooth/classic/handsfree_ag/src/codec.c @@ -0,0 +1,314 @@ +/* codec.c - CODEC implementation for Bluetooth Hands-Free Profile */ + +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +#include + +#include "codec.h" + +#if DT_HAS_ALIAS(i2s_codec_tx) && DT_HAS_ALIAS(i2s_codec_rx) +#define I2S_CODEC_TX DT_ALIAS(i2s_codec_tx) +#define I2S_CODEC_RX DT_ALIAS(i2s_codec_rx) +#define I2C_CODEC DT_NODELABEL(audio_codec) + +#define MAX_SAMPLE_FREQ 16000 +#define MAX_SAMPLE_BIT_WIDTH 16 +#define MAX_CHANNELS 2 + +#define SAMPLES_PER_BLOCK ((MAX_SAMPLE_FREQ * CONFIG_AUDIO_TRANSFER_INTERVAL / 1000) * MAX_CHANNELS) + +#define BLOCK_SIZE (MAX_SAMPLE_BIT_WIDTH * SAMPLES_PER_BLOCK / 8) +#define RX_BLOCK_COUNT (CONFIG_CODEC_BUFFERS) +#define TX_BLOCK_COUNT (CONFIG_CODEC_BUFFERS) +#define TIMEOUT (2 * 1000 / CONFIG_AUDIO_TRANSFER_INTERVAL) + +static const struct device *i2s_codec_tx = DEVICE_DT_GET(I2S_CODEC_TX); +static const struct device *i2s_codec_rx = DEVICE_DT_GET(I2S_CODEC_RX); +static const struct device *i2c_codec = DEVICE_DT_GET(I2C_CODEC); + +K_MEM_SLAB_DEFINE_IN_SECT_STATIC(tx_mem_slab, __nocache, BLOCK_SIZE, TX_BLOCK_COUNT, 4); +K_MEM_SLAB_DEFINE_IN_SECT_STATIC(rx_mem_slab, __nocache, BLOCK_SIZE, RX_BLOCK_COUNT, 4); + +static int configure_codec_streams(const struct device *i2s_codec_rx, + const struct device *i2s_codec_tx, struct i2s_config *config) +{ + int err; + + config->mem_slab = &rx_mem_slab; + err = i2s_configure(i2s_codec_rx, I2S_DIR_RX, config); + if (err < 0) { + printk("Failed to configure CODEC RX stream: %d\n", err); + return err; + } + + config->mem_slab = &tx_mem_slab; + err = i2s_configure(i2s_codec_tx, I2S_DIR_TX, config); + if (err < 0) { + printk("Failed to configure CODEC TX stream: %d\n", err); + return err; + } + + return 0; +} + +static struct k_sem codec_rx_thread_notify; +static codec_rx_cb_t codec_rx_cb; + +#define CODEC_RX_FLAG_STOPPED 0 +#define CODEC_RX_FLAG_STARTED 1 +#define CODEC_RX_FLAG_STOPPING 2 + +static atomic_t codec_rx_flag[1]; + +static void codec_rx_task(void *p1, void *p2, void *p3) +{ + int err; + void *mem_block; + uint32_t block_size; + + while (true) { + err = k_sem_take(&codec_rx_thread_notify, K_FOREVER); + if (err < 0) { + continue; + } + + if (atomic_test_and_clear_bit(codec_rx_flag, CODEC_RX_FLAG_STOPPING)) { + err = i2s_trigger(i2s_codec_rx, I2S_DIR_RX, I2S_TRIGGER_STOP); + if (err < 0) { + printk("Failed to stop CODEC RX %d\n", err); + } + atomic_clear_bit(codec_rx_flag, CODEC_RX_FLAG_STARTED); + atomic_set_bit(codec_rx_flag, CODEC_RX_FLAG_STOPPED); + } + + if (!atomic_test_bit(codec_rx_flag, CODEC_RX_FLAG_STARTED)) { + continue; + } else { + k_sem_give(&codec_rx_thread_notify); + } + + err = i2s_read(i2s_codec_rx, &mem_block, &block_size); + if (err < 0) { + continue; + } + + if (codec_rx_cb != NULL) { + codec_rx_cb(mem_block, block_size); + } + k_mem_slab_free(&rx_mem_slab, (void *)mem_block); + } +} + +static K_KERNEL_STACK_MEMBER(codec_rx_thread_stack, CONFIG_CODEC_RX_THREAD_STACK_SIZE); + +int codec_init(uint8_t air_mode) +{ + struct i2s_config config; + struct audio_codec_cfg audio_cfg; + int err; + uint8_t word_size; + uint8_t channels; + uint32_t sample_rate; + + static bool is_initiated; + static struct k_thread codec_rx_thread; + static k_tid_t codec_rx_thread_id; + + if (is_initiated) { + return 0; + } + + if (!device_is_ready(i2s_codec_rx)) { + printk("%s is not ready\n", i2s_codec_rx->name); + return -EINVAL; + } + + if (i2s_codec_rx != i2s_codec_tx && !device_is_ready(i2s_codec_tx)) { + printk("%s is not ready\n", i2s_codec_tx->name); + return -EINVAL; + } + + if (!device_is_ready(i2c_codec)) { + printk("%s is not ready\n", i2c_codec->name); + return -EINVAL; + } + + switch (air_mode) { + case BT_HCI_CODING_FORMAT_CVSD: + word_size = 16; + channels = 2; + sample_rate = 8000; + break; + case BT_HCI_CODING_FORMAT_TRANSPARENT: + word_size = 16; + channels = 2; + sample_rate = 16000; + break; + case BT_HCI_CODING_FORMAT_ULAW_LOG: + case BT_HCI_CODING_FORMAT_ALAW_LOG: + case BT_HCI_CODING_FORMAT_LINEAR_PCM: + case BT_HCI_CODING_FORMAT_MSBC: + case BT_HCI_CODING_FORMAT_LC3: + case BT_HCI_CODING_FORMAT_G729A: + case BT_HCI_CODING_FORMAT_VS: + default: + printk("Unsupported air mode: %d\n", air_mode); + return -ENOTSUP; + } + + audio_cfg.dai_route = AUDIO_ROUTE_PLAYBACK_CAPTURE; + audio_cfg.dai_type = AUDIO_DAI_TYPE_I2S; + audio_cfg.dai_cfg.i2s.word_size = word_size; + audio_cfg.dai_cfg.i2s.channels = channels; + audio_cfg.dai_cfg.i2s.format = I2S_FMT_DATA_FORMAT_I2S; + audio_cfg.dai_cfg.i2s.options = I2S_OPT_FRAME_CLK_SLAVE | I2S_OPT_BIT_CLK_SLAVE; + audio_cfg.dai_cfg.i2s.frame_clk_freq = sample_rate; + audio_cfg.dai_cfg.i2s.mem_slab = &rx_mem_slab; + audio_cfg.dai_cfg.i2s.block_size = BLOCK_SIZE; + err = audio_codec_configure(i2c_codec, &audio_cfg); + if (err != 0) { + printk("Failed to configure audio codec: %d\n", err); + return err; + } + + config.word_size = word_size; + config.channels = channels; + config.format = I2S_FMT_DATA_FORMAT_I2S; + config.options = I2S_OPT_FRAME_CLK_MASTER | I2S_OPT_BIT_CLK_MASTER; + config.frame_clk_freq = sample_rate; + config.block_size = BLOCK_SIZE; + config.timeout = TIMEOUT; + + err = configure_codec_streams(i2s_codec_rx, i2s_codec_tx, &config); + if (err < 0) { + return err; + } + + if (codec_rx_thread_id == NULL) { + k_sem_init(&codec_rx_thread_notify, 0, 1); + codec_rx_thread_id = k_thread_create(&codec_rx_thread, codec_rx_thread_stack, + K_KERNEL_STACK_SIZEOF(codec_rx_thread_stack), + codec_rx_task, NULL, NULL, NULL, + K_PRIO_COOP(CONFIG_CODEC_RX_THREAD_PRIO), 0, + K_NO_WAIT); + k_thread_name_set(codec_rx_thread_id, "HFP CODEC RX"); + } + + atomic_set_bit(codec_rx_flag, CODEC_RX_FLAG_STOPPED); + is_initiated = true; + + return 0; +} + +int codec_rx_start(codec_rx_cb_t cb) +{ + int err; + + if (!atomic_test_bit(codec_rx_flag, CODEC_RX_FLAG_STOPPED)) { + printk("CODEC RX is not idle\n"); + return -EBUSY; + } + + codec_rx_cb = cb; + + err = i2s_trigger(i2s_codec_rx, I2S_DIR_RX, I2S_TRIGGER_START); + if (err < 0) { + printk("Failed to trigger start on RX: %d\n", err); + return err; + } + + atomic_clear_bit(codec_rx_flag, CODEC_RX_FLAG_STOPPED); + atomic_set_bit(codec_rx_flag, CODEC_RX_FLAG_STARTED); + k_sem_give(&codec_rx_thread_notify); + + return 0; +} + +int codec_rx_stop(void) +{ + if (!atomic_test_bit(codec_rx_flag, CODEC_RX_FLAG_STARTED)) { + return 0; + } + + atomic_set_bit(codec_rx_flag, CODEC_RX_FLAG_STOPPING); + k_sem_give(&codec_rx_thread_notify); + + return 0; +} + +int codec_tx(const uint8_t *data, uint32_t len) +{ + int err; + void *mem_block; + + if (len * 2 != BLOCK_SIZE) { + printk("Invalid data len %u != %u\n", len, BLOCK_SIZE / 2); + return -EINVAL; + } + + err = k_mem_slab_alloc(&tx_mem_slab, &mem_block, K_NO_WAIT); + if (err < 0) { + printk("Failed to allocate TX block: %d\n", err); + return err; + } + + for (uint32_t i = 0; i < len; i += 2) { + uint32_t *dst; + uint16_t *src; + + dst = (uint32_t *)&((uint8_t *)mem_block)[i * 2]; + src = (uint16_t *)&data[i]; + + *dst = (*src) | ((*src) << 16); + } + + err = i2s_write(i2s_codec_tx, mem_block, BLOCK_SIZE); + if (err < 0) { + k_mem_slab_free(&tx_mem_slab, mem_block); + printk("Failed to write block: %d\n", err); + return err; + } + + /* Try to trigger TX start each time, because TX may have stopped if there is no more + * data in pending. + * Ignore the error. + */ + (void)i2s_trigger(i2s_codec_tx, I2S_DIR_TX, I2S_TRIGGER_START); + + return 0; +} + +#else + +int codec_init(uint8_t air_mode) +{ + printk("Codec is unsupported\n"); + return 0; +} + +int codec_tx(const uint8_t *data, uint32_t len) +{ + return 0; +} + +int codec_rx_start(codec_rx_cb_t cb) +{ + return 0; +} + +int codec_rx_stop(void) +{ + return 0; +} + +#endif /* DT_HAS_ALIAS(i2s_codec_tx) && DT_HAS_ALIAS(i2s_codec_rx) */ diff --git a/samples/bluetooth/classic/handsfree_ag/src/codec.h b/samples/bluetooth/classic/handsfree_ag/src/codec.h new file mode 100644 index 000000000000..e43bb4624681 --- /dev/null +++ b/samples/bluetooth/classic/handsfree_ag/src/codec.h @@ -0,0 +1,21 @@ +/* codec.h - CODEC implementation for Bluetooth Hands-Free Profile */ + +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _ZEPHYR_SAMPLES_CLASSIC_HANDSFREE_CODEC_H_ +#define _ZEPHYR_SAMPLES_CLASSIC_HANDSFREE_CODEC_H_ + +#include + +typedef void (*codec_rx_cb_t)(const uint8_t *data, uint32_t len); + +int codec_init(uint8_t air_mode); +int codec_tx(const uint8_t *data, uint32_t len); +int codec_rx_start(codec_rx_cb_t cb); +int codec_rx_stop(void); + +#endif /* _ZEPHYR_SAMPLES_CLASSIC_HANDSFREE_CODEC_H_ */ diff --git a/samples/bluetooth/classic/handsfree_ag/src/main.c b/samples/bluetooth/classic/handsfree_ag/src/main.c index 8d2237b0a213..6766c9239406 100644 --- a/samples/bluetooth/classic/handsfree_ag/src/main.c +++ b/samples/bluetooth/classic/handsfree_ag/src/main.c @@ -1,7 +1,7 @@ /* main.c - Application main entry point */ /* - * Copyright 2024 NXP + * Copyright 2024-2025 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -23,8 +23,12 @@ #include #include +#include "pcm.h" +#include "codec.h" + static struct bt_conn *default_conn; struct bt_hfp_ag *hfp_ag; +static struct bt_conn *active_sco_conn; struct bt_hfp_ag_call *hfp_ag_call; static struct bt_br_discovery_param br_discover; @@ -58,13 +62,96 @@ static void ag_disconnected(struct bt_hfp_ag *ag) printk("HFP AG disconnected!\n"); } +static void pcm_rx_cb(const uint8_t *data, uint32_t len) +{ + int err; + + if (active_sco_conn == NULL) { + return; + } + + err = codec_tx(data, len); + if (err != 0) { + printk("Failed to transmit PCM data: %d\n", err); + } +} + +static void codec_rx_cb(const uint8_t *data, uint32_t len) +{ + int err; + + if (active_sco_conn == NULL) { + return; + } + + err = pcm_tx(data, len); + if (err != 0) { + printk("Failed to transmit Codec data: %d\n", err); + } +} + static void ag_sco_connected(struct bt_hfp_ag *ag, struct bt_conn *sco_conn) { - printk("HFP AG SCO connected!\n"); + struct bt_conn_info info; + int err; + + printk("AG SCO connected\n"); + active_sco_conn = bt_conn_ref(sco_conn); + + err = bt_conn_get_info(sco_conn, &info); + if (err != 0) { + printk("Failed to get sco conn %p info\n", sco_conn); + return; + } + + printk("SCO air mode %u\n", info.sco.air_mode); + + err = pcm_init(info.sco.air_mode); + if (err != 0) { + printk("Failed to initialize PCM for air mode %u\n", info.sco.air_mode); + return; + } + + err = codec_init(info.sco.air_mode); + if (err != 0) { + printk("Failed to initialize CODEC for air mode %u\n", info.sco.air_mode); + return; + } + + err = pcm_rx_start(pcm_rx_cb); + if (err != 0) { + printk("Failed to start PCM\n"); + return; + } + + err = codec_rx_start(codec_rx_cb); + if (err != 0) { + printk("Failed to start CODEC\n"); + return; + } } static void ag_sco_disconnected(struct bt_conn *sco_conn, uint8_t reason) { + int err; + + if (active_sco_conn != sco_conn) { + return; + } + + bt_conn_unref(active_sco_conn); + active_sco_conn = NULL; + + err = pcm_rx_stop(); + if (err != 0) { + printk("Failed to stop PCM\n"); + } + + err = codec_rx_stop(); + if (err != 0) { + printk("Failed to stop CODEC\n"); + } + printk("HFP AG SCO disconnected %u!\n", reason); } @@ -106,6 +193,18 @@ static void ag_incoming(struct bt_hfp_ag *ag, struct bt_hfp_ag_call *call, const k_work_cancel_delayable(&call_connect_work); } +#if defined(CONFIG_BT_HFP_AG_CODEC_NEG) +static void ag_codec(struct bt_hfp_ag *ag, uint32_t ids) +{ + printk("AG received codec id bit map %x\n", ids); +} + +static void ag_codec_negotiate(struct bt_hfp_ag *ag, int err) +{ + printk("AG codec negotiation result %d\n", err); +} +#endif /* CONFIG_BT_HFP_AG_CODEC_NEG */ + static struct bt_hfp_ag_cb ag_cb = { .connected = ag_connected, .disconnected = ag_disconnected, @@ -117,6 +216,10 @@ static struct bt_hfp_ag_cb ag_cb = { .accept = ag_accept, .reject = ag_reject, .terminate = ag_terminate, +#if defined(CONFIG_BT_HFP_AG_CODEC_NEG) + .codec = ag_codec, + .codec_negotiate = ag_codec_negotiate, +#endif /* CONFIG_BT_HFP_AG_CODEC_NEG */ }; static uint8_t sdp_discover_cb(struct bt_conn *conn, struct bt_sdp_client_result *result, diff --git a/samples/bluetooth/classic/handsfree_ag/src/pcm.c b/samples/bluetooth/classic/handsfree_ag/src/pcm.c new file mode 100644 index 000000000000..59673d7d4ba6 --- /dev/null +++ b/samples/bluetooth/classic/handsfree_ag/src/pcm.c @@ -0,0 +1,275 @@ +/* pcm.c - PCM implementation for Bluetooth Hands-Free Profile */ + +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +#include + +#include "pcm.h" + +#if DT_HAS_ALIAS(pcm_rxtx) || (DT_HAS_ALIAS(pcm_rx) && DT_HAS_ALIAS(pcm_tx)) +#if DT_NODE_EXISTS(DT_ALIAS(pcm_rxtx)) +#define PCM_RX DT_ALIAS(pcm_rxtx) +#define PCM_TX DT_ALIAS(pcm_rxtx) +#else +#define PCM_RX DT_ALIAS(pcm_rx) +#define PCM_TX DT_ALIAS(pcm_tx) +#endif + +#define MAX_SAMPLE_FREQ 16000 +#define MAX_SAMPLE_BIT_WIDTH 16 +#define MAX_CHANNELS 1 + +#define SAMPLES_PER_BLOCK ((MAX_SAMPLE_FREQ * CONFIG_AUDIO_TRANSFER_INTERVAL / 1000) * MAX_CHANNELS) + +#define BLOCK_SIZE (MAX_SAMPLE_BIT_WIDTH * SAMPLES_PER_BLOCK / 8) +#define RX_BLOCK_COUNT (CONFIG_PCM_BUFFERS) +#define TX_BLOCK_COUNT (CONFIG_PCM_BUFFERS) +#define TIMEOUT (2 * 1000 / CONFIG_AUDIO_TRANSFER_INTERVAL) + +static const struct device *pcm_rx_dev = DEVICE_DT_GET(PCM_RX); +static const struct device *pcm_tx_dev = DEVICE_DT_GET(PCM_TX); + +K_MEM_SLAB_DEFINE_IN_SECT_STATIC(rx_mem_slab, __nocache, BLOCK_SIZE, RX_BLOCK_COUNT, 4); +K_MEM_SLAB_DEFINE_IN_SECT_STATIC(tx_mem_slab, __nocache, BLOCK_SIZE, TX_BLOCK_COUNT, 4); + +static int configure_pcm_streams(const struct device *pcm_rx_dev, const struct device *pcm_tx_dev, + struct i2s_config *config) +{ + int err; + + config->mem_slab = &rx_mem_slab; + err = i2s_configure(pcm_rx_dev, I2S_DIR_RX, config); + if (err < 0) { + printk("Failed to configure PCM RX stream: %d\n", err); + return err; + } + + config->mem_slab = &tx_mem_slab; + err = i2s_configure(pcm_tx_dev, I2S_DIR_TX, config); + if (err < 0) { + printk("Failed to configure PCM TX stream: %d\n", err); + return err; + } + + return 0; +} + +static struct k_sem pcm_rx_thread_notify; +static pcm_rx_cb_t pcm_rx_cb; + +#define PCM_RX_FLAG_STOPPED 0 +#define PCM_RX_FLAG_STARTED 1 + +static atomic_t pcm_rx_flag[1]; + +static void pcm_rx_task(void *p1, void *p2, void *p3) +{ + int err; + void *mem_block; + uint32_t block_size; + + while (true) { + err = k_sem_take(&pcm_rx_thread_notify, K_FOREVER); + if (err < 0) { + continue; + } + + if (!atomic_test_bit(pcm_rx_flag, PCM_RX_FLAG_STARTED)) { + continue; + } else { + k_sem_give(&pcm_rx_thread_notify); + } + + err = i2s_read(pcm_rx_dev, &mem_block, &block_size); + if (err < 0) { + continue; + } + + if (pcm_rx_cb != NULL) { + pcm_rx_cb((const uint8_t *)mem_block, block_size); + } + k_mem_slab_free(&rx_mem_slab, (void *)mem_block); + } +} + +static K_KERNEL_STACK_MEMBER(pcm_rx_thread_stack, CONFIG_PCM_RX_THREAD_STACK_SIZE); + +int pcm_init(uint8_t air_mode) +{ + struct i2s_config config; + int err; + uint8_t word_size; + uint8_t channels; + uint32_t sample_rate; + + static bool is_initiated; + static struct k_thread pcm_rx_thread; + static k_tid_t pcm_rx_thread_id; + + if (is_initiated) { + return 0; + } + + if (!device_is_ready(pcm_rx_dev)) { + printk("%s is not ready\n", pcm_rx_dev->name); + return -EINVAL; + } + + if (pcm_rx_dev != pcm_tx_dev && !device_is_ready(pcm_tx_dev)) { + printk("%s is not ready\n", pcm_tx_dev->name); + return -EINVAL; + } + + switch (air_mode) { + case BT_HCI_CODING_FORMAT_CVSD: + word_size = 16; + channels = 1; + sample_rate = 8000; + break; + case BT_HCI_CODING_FORMAT_TRANSPARENT: + word_size = 16; + channels = 1; + sample_rate = 16000; + break; + case BT_HCI_CODING_FORMAT_ULAW_LOG: + case BT_HCI_CODING_FORMAT_ALAW_LOG: + case BT_HCI_CODING_FORMAT_LINEAR_PCM: + case BT_HCI_CODING_FORMAT_MSBC: + case BT_HCI_CODING_FORMAT_LC3: + case BT_HCI_CODING_FORMAT_G729A: + case BT_HCI_CODING_FORMAT_VS: + default: + printk("Unsupported air mode: %d\n", air_mode); + return -ENOTSUP; + } + + config.word_size = word_size; + config.channels = channels; + config.format = I2S_FMT_DATA_FORMAT_PCM_SHORT; + config.options = I2S_OPT_BIT_CLK_SLAVE | I2S_OPT_FRAME_CLK_SLAVE; + config.frame_clk_freq = sample_rate; + config.block_size = BLOCK_SIZE; + config.timeout = TIMEOUT; + + err = configure_pcm_streams(pcm_rx_dev, pcm_tx_dev, &config); + if (err < 0) { + return err; + } + + if (pcm_rx_thread_id == NULL) { + k_sem_init(&pcm_rx_thread_notify, 0, 1); + pcm_rx_thread_id = k_thread_create(&pcm_rx_thread, pcm_rx_thread_stack, + K_KERNEL_STACK_SIZEOF(pcm_rx_thread_stack), + pcm_rx_task, NULL, NULL, NULL, + K_PRIO_COOP(CONFIG_PCM_RX_THREAD_PRIO), 0, + K_NO_WAIT); + k_thread_name_set(pcm_rx_thread_id, "HFP PCM RX"); + } + + atomic_set_bit(pcm_rx_flag, PCM_RX_FLAG_STOPPED); + is_initiated = true; + + return 0; +} + +int pcm_rx_start(pcm_rx_cb_t cb) +{ + int err; + + if (!atomic_test_bit(pcm_rx_flag, PCM_RX_FLAG_STOPPED)) { + return 0; + } + + pcm_rx_cb = cb; + + err = i2s_trigger(pcm_rx_dev, I2S_DIR_RX, I2S_TRIGGER_START); + if (err < 0) { + printk("Failed to trigger start on RX: %d\n", err); + return err; + } + + atomic_clear_bit(pcm_rx_flag, PCM_RX_FLAG_STOPPED); + atomic_set_bit(pcm_rx_flag, PCM_RX_FLAG_STARTED); + k_sem_give(&pcm_rx_thread_notify); + + return 0; +} + +int pcm_rx_stop(void) +{ + /* TODO: Stop I2S RX. */ + return 0; +} + +int pcm_tx(const uint8_t *data, uint32_t len) +{ + int err; + void *mem_block; + + if (len != (BLOCK_SIZE * 2)) { + printk("Invalid data len %u != %u\n", len, BLOCK_SIZE * 2); + return -EINVAL; + } + + err = k_mem_slab_alloc(&tx_mem_slab, &mem_block, K_NO_WAIT); + if (err < 0) { + printk("Failed to allocate TX block: %d\n", err); + return err; + } + + for (uint32_t i = 0; i < BLOCK_SIZE; i += 2) { + uint16_t *dst; + const uint16_t *src; + + dst = (uint16_t *)&((uint8_t *)mem_block)[i]; + src = (const uint16_t *)&data[i * 2 + 2]; + + *dst = *src; + } + + err = i2s_write(pcm_tx_dev, mem_block, BLOCK_SIZE); + if (err < 0) { + k_mem_slab_free(&tx_mem_slab, mem_block); + printk("Failed to write block: %d\n", err); + return err; + } + + /* Try to trigger TX start each time, because TX may have stopped if there is no more + * data in pending. + * Ignore the error. + */ + (void)i2s_trigger(pcm_tx_dev, I2S_DIR_TX, I2S_TRIGGER_START); + + return 0; +} +#else +int pcm_init(uint8_t air_mode) +{ + printk("PCM is unsupported\n"); + return 0; +} + +int pcm_tx(const uint8_t *data, uint32_t len) +{ + return 0; +} + +int pcm_rx_start(pcm_rx_cb_t cb) +{ + return 0; +} + +int pcm_rx_stop(void) +{ + return 0; +} +#endif /* DT_HAS_ALIAS(pcm_rxtx) || (DT_HAS_ALIAS(pcm_rx) && DT_HAS_ALIAS(pcm_tx)) */ diff --git a/samples/bluetooth/classic/handsfree_ag/src/pcm.h b/samples/bluetooth/classic/handsfree_ag/src/pcm.h new file mode 100644 index 000000000000..5f9536003b8d --- /dev/null +++ b/samples/bluetooth/classic/handsfree_ag/src/pcm.h @@ -0,0 +1,21 @@ +/* pcm.h - PCM implementation for Bluetooth Hands-Free Profile */ + +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _ZEPHYR_SAMPLES_CLASSIC_HANDSFREE_PCM_H_ +#define _ZEPHYR_SAMPLES_CLASSIC_HANDSFREE_PCM_H_ + +#include + +typedef void (*pcm_rx_cb_t)(const uint8_t *data, uint32_t len); + +int pcm_init(uint8_t air_mode); +int pcm_tx(const uint8_t *data, uint32_t len); +int pcm_rx_start(pcm_rx_cb_t cb); +int pcm_rx_stop(void); + +#endif /* _ZEPHYR_SAMPLES_CLASSIC_HANDSFREE_PCM_H_ */ From 6531d415b67619c5d7f4d6ad50f7a9532e4be0b8 Mon Sep 17 00:00:00 2001 From: Lyle Zhu Date: Wed, 14 Jan 2026 16:54:52 +0800 Subject: [PATCH 1795/3659] sample: Bluetooth: HFP_AG: Make global variables `static` Make global variables static in the HFP AG sample to improve encapsulation and avoid potential symbol conflicts. Change the following variables from global to static scope: - hfp_ag - hfp_ag_call - discover_work - call_connect_work - call_disconnect_work - call_remote_ringing_work - call_remote_accept_work These variables are only used within main.c and do not need to be externally visible. Signed-off-by: Lyle Zhu --- .../bluetooth/classic/handsfree_ag/src/main.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/samples/bluetooth/classic/handsfree_ag/src/main.c b/samples/bluetooth/classic/handsfree_ag/src/main.c index 6766c9239406..66c2f78daf57 100644 --- a/samples/bluetooth/classic/handsfree_ag/src/main.c +++ b/samples/bluetooth/classic/handsfree_ag/src/main.c @@ -1,7 +1,7 @@ /* main.c - Application main entry point */ /* - * Copyright 2024-2025 NXP + * Copyright 2024-2026 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -27,19 +27,19 @@ #include "codec.h" static struct bt_conn *default_conn; -struct bt_hfp_ag *hfp_ag; +static struct bt_hfp_ag *hfp_ag; static struct bt_conn *active_sco_conn; -struct bt_hfp_ag_call *hfp_ag_call; +static struct bt_hfp_ag_call *hfp_ag_call; static struct bt_br_discovery_param br_discover; static struct bt_br_discovery_result scan_result[CONFIG_BT_HFP_AG_DISCOVER_RESULT_COUNT]; -struct k_work discover_work; -struct k_work_delayable call_connect_work; -struct k_work_delayable call_disconnect_work; +static struct k_work discover_work; +static struct k_work_delayable call_connect_work; +static struct k_work_delayable call_disconnect_work; -struct k_work_delayable call_remote_ringing_work; -struct k_work_delayable call_remote_accept_work; +static struct k_work_delayable call_remote_ringing_work; +static struct k_work_delayable call_remote_accept_work; NET_BUF_POOL_DEFINE(sdp_discover_pool, 10, BT_L2CAP_BUF_SIZE(CONFIG_BT_L2CAP_TX_MTU), CONFIG_BT_CONN_TX_USER_DATA_SIZE, NULL); From f8cf0d38037a6196d9e030cf46b4287270108f13 Mon Sep 17 00:00:00 2001 From: Aleksandr Senin Date: Sun, 28 Dec 2025 20:23:20 +0300 Subject: [PATCH 1796/3659] drivers: entropy: add GD32F4xx TRNG driver Add entropy driver for the GD32F4xx TRNG. Implement get_entropy_isr() semantics and bounded DRDY wait. Add DT binding and SoC TRNG node; hook driver Kconfig. Signed-off-by: Aleksandr Senin --- drivers/entropy/CMakeLists.txt | 1 + drivers/entropy/Kconfig | 1 + drivers/entropy/Kconfig.gd32 | 15 ++ drivers/entropy/entropy_gd32.c | 221 +++++++++++++++++++++++++++++ dts/arm/gd/gd32f4xx/gd32f4xx.dtsi | 10 +- dts/bindings/rng/gd,gd32-trng.yaml | 20 +++ 6 files changed, 267 insertions(+), 1 deletion(-) create mode 100644 drivers/entropy/Kconfig.gd32 create mode 100644 drivers/entropy/entropy_gd32.c create mode 100644 dts/bindings/rng/gd,gd32-trng.yaml diff --git a/drivers/entropy/CMakeLists.txt b/drivers/entropy/CMakeLists.txt index cfdf054ac5ba..469e45b52481 100644 --- a/drivers/entropy/CMakeLists.txt +++ b/drivers/entropy/CMakeLists.txt @@ -17,6 +17,7 @@ zephyr_library_sources_ifdef(CONFIG_ENTROPY_BRCM_IPROC_RNG200 entropy_iproc_rng2 zephyr_library_sources_ifdef(CONFIG_ENTROPY_BT_HCI entropy_bt_hci.c) zephyr_library_sources_ifdef(CONFIG_ENTROPY_CC13XX_CC26XX_RNG entropy_cc13xx_cc26xx.c) zephyr_library_sources_ifdef(CONFIG_ENTROPY_ESP32_RNG entropy_esp32.c) +zephyr_library_sources_ifdef(CONFIG_ENTROPY_GD32_TRNG entropy_gd32.c) zephyr_library_sources_ifdef(CONFIG_ENTROPY_GECKO_SE entropy_gecko_se.c) zephyr_library_sources_ifdef(CONFIG_ENTROPY_GECKO_TRNG entropy_gecko_trng.c) zephyr_library_sources_ifdef(CONFIG_ENTROPY_LITEX_RNG entropy_litex.c) diff --git a/drivers/entropy/Kconfig b/drivers/entropy/Kconfig index 8b4a6e9b4fc3..acf066087244 100644 --- a/drivers/entropy/Kconfig +++ b/drivers/entropy/Kconfig @@ -26,6 +26,7 @@ source "drivers/entropy/Kconfig.b91" source "drivers/entropy/Kconfig.bt_hci" source "drivers/entropy/Kconfig.cc13xx_cc26xx" source "drivers/entropy/Kconfig.esp32" +source "drivers/entropy/Kconfig.gd32" source "drivers/entropy/Kconfig.gecko" source "drivers/entropy/Kconfig.iproc" source "drivers/entropy/Kconfig.litex" diff --git a/drivers/entropy/Kconfig.gd32 b/drivers/entropy/Kconfig.gd32 new file mode 100644 index 000000000000..1cdd1973bb48 --- /dev/null +++ b/drivers/entropy/Kconfig.gd32 @@ -0,0 +1,15 @@ +# GD32 TRNG configuration + +# Copyright (c) 2025 Aleksandr Senin +# SPDX-License-Identifier: Apache-2.0 + +config ENTROPY_GD32_TRNG + bool "GigaDevice GD32F4xx TRNG driver" + default y + depends on DT_HAS_GD_GD32_TRNG_ENABLED + select ENTROPY_HAS_DRIVER + select USE_GD32_TRNG + help + Enable True Random Number Generator (TRNG) driver for GigaDevice + GD32F4xx series. This driver uses the GD32 HAL and operates in + polling mode. diff --git a/drivers/entropy/entropy_gd32.c b/drivers/entropy/entropy_gd32.c new file mode 100644 index 000000000000..8fe159e721f1 --- /dev/null +++ b/drivers/entropy/entropy_gd32.c @@ -0,0 +1,221 @@ +/* + * Copyright (c) 2025 Aleksandr Senin + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT gd_gd32_trng + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* GD32 HAL headers */ +#include +#include + +LOG_MODULE_REGISTER(entropy_gd32, CONFIG_ENTROPY_LOG_LEVEL); + +/* Prevent infinite wait in case TRNG never asserts DRDY */ +#define GD32_TRNG_DRDY_TIMEOUT_MS 100U + +struct entropy_gd32_config { + uint16_t clkid; +}; + +static inline void entropy_gd32_clear_int_flags(void) +{ + trng_interrupt_flag_clear(TRNG_INT_FLAG_CEIF); + trng_interrupt_flag_clear(TRNG_INT_FLAG_SEIF); +} + +static bool entropy_gd32_ck48m_ready(void) +{ + /* + * CK48M domain is used by TRNG (and also SDIO/USBFS/USBHS). + * + * - If CK48MSEL=1 => CK48M = IRC48M, require IRC48MSTB. + * - If CK48MSEL=0 => CK48M = PLL48M (PLLQ or PLLSAIP), require the + * selected PLL block to be stable. This does not guarantee 48MHz, but + * indicates the clock path is at least running. + */ + if ((RCU_ADDCTL & RCU_ADDCTL_CK48MSEL) != 0U) { + return (RCU_ADDCTL & RCU_ADDCTL_IRC48MSTB) != 0U; + } + + if ((RCU_ADDCTL & RCU_ADDCTL_PLL48MSEL) != 0U) { + /* PLLSAIP selected */ + return (RCU_CTL & RCU_CTL_PLLSAISTB) != 0U; + } + + /* PLLQ selected */ + return (RCU_CTL & RCU_CTL_PLLSTB) != 0U; +} + +static entropy_gd32_recover(void) +{ + /* + * For GD32F4xx TRNG the HAL exposes status bits (CECS/SECS) but provides + * only interrupt-flag clearing (CEIF/SEIF). To reliably recover from seed + * errors, do a peripheral reset (trng_deinit()) and re-enable. + */ + trng_disable(); + trng_deinit(); + entropy_gd32_clear_int_flags(); + trng_enable(); + + return 0; +} + +static int entropy_gd32_wait_drdy(void) +{ + uint32_t start = k_cycle_get_32(); + uint32_t timeout_cycles = (uint32_t)((uint64_t)CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC * + (uint64_t)GD32_TRNG_DRDY_TIMEOUT_MS / 1000ULL); + + while (SET != trng_flag_get(TRNG_FLAG_DRDY)) { + if (SET == trng_flag_get(TRNG_FLAG_CECS)) { + /* Clock error: indicates a misconfigured/too-slow TRNG clock */ + return -EIO; + } + + if (SET == trng_flag_get(TRNG_FLAG_SECS)) { + entropy_gd32_recover(); + } + + if ((k_cycle_get_32() - start) > timeout_cycles) { + return -ETIMEDOUT; + } + + /* Never yield/sleep in ISR paths */ + if (!k_is_in_isr() && !k_is_pre_kernel()) { + k_yield(); + } + } + + return 0; +} + +static int entropy_gd32_init(const struct device *dev) +{ + const struct entropy_gd32_config *cfg = dev->config; + + /* Ensure bus clock gate is enabled via Zephyr clock controller */ + int ret = clock_control_on(GD32_CLOCK_CONTROLLER, (clock_control_subsys_t)&cfg->clkid); + + if (ret < 0) { + return ret; + } + + rcu_periph_clock_enable(RCU_TRNG); + trng_deinit(); + entropy_gd32_clear_int_flags(); + trng_enable(); + + if (!entropy_gd32_ck48m_ready()) { + LOG_ERR("CK48M is not configured/running; configure gd,ck48m-source in DT " + "(gd,gd32-rcu) for TRNG"); + return -EIO; + } + + /* + * If CECS is set here, TRNG domain clock is misconfigured and random data + * may never become ready. We don't hard-fail init, but runtime calls will + * report -EIO. + */ + + return 0; +} + +static int entropy_gd32_fetch_busywait(uint8_t *dst, uint16_t len) +{ + while (len > 0U) { + int ret = entropy_gd32_wait_drdy(); + + if (ret < 0) { + return ret; + } + + uint32_t word = trng_get_true_random_data(); + + if (len >= sizeof(word)) { + memcpy(dst, &word, sizeof(word)); + dst += sizeof(word); + len -= sizeof(word); + } else { + memcpy(dst, &word, len); + len = 0U; + } + } + + return 0; +} + +static int entropy_gd32_get_entropy(const struct device *dev, uint8_t *buffer, uint16_t length) +{ + ARG_UNUSED(dev); + if ((buffer == NULL) || (length == 0U)) { + return -EINVAL; + } + + return entropy_gd32_fetch_busywait(buffer, length); +} + +static int entropy_gd32_get_entropy_isr(const struct device *dev, uint8_t *buffer, uint16_t length, + uint32_t flags) +{ + ARG_UNUSED(dev); + + if ((buffer == NULL) || (length == 0U)) { + return -EINVAL; + } + + if (SET == trng_flag_get(TRNG_FLAG_CECS)) { + return -EIO; + } + if (SET == trng_flag_get(TRNG_FLAG_SECS)) { + entropy_gd32_recover(); + return -EIO; + } + + if ((flags & ENTROPY_BUSYWAIT) == 0U) { + uint16_t written = 0U; + + while ((written < length) && (SET == trng_flag_get(TRNG_FLAG_DRDY))) { + uint32_t word = trng_get_true_random_data(); + uint16_t chunk = MIN((uint16_t)sizeof(word), (uint16_t)(length - written)); + + memcpy(&buffer[written], &word, chunk); + written += chunk; + } + + return written; + } + + /* Busy-wait (ISR-safe): fill the whole buffer, return bytes written */ + int ret = entropy_gd32_fetch_busywait(buffer, length); + + if (ret < 0) { + return ret; + } + + return length; +} + +static DEVICE_API(entropy, entropy_gd32_api) = { + .get_entropy = entropy_gd32_get_entropy, + .get_entropy_isr = entropy_gd32_get_entropy_isr, +}; + +static const struct entropy_gd32_config entropy_gd32_cfg = { + .clkid = DT_INST_CLOCKS_CELL(0, id), +}; + +DEVICE_DT_INST_DEFINE(0, entropy_gd32_init, NULL, NULL, &entropy_gd32_cfg, PRE_KERNEL_1, + CONFIG_ENTROPY_INIT_PRIORITY, &entropy_gd32_api); diff --git a/dts/arm/gd/gd32f4xx/gd32f4xx.dtsi b/dts/arm/gd/gd32f4xx/gd32f4xx.dtsi index 260115cb8a67..3900edf648c8 100644 --- a/dts/arm/gd/gd32f4xx/gd32f4xx.dtsi +++ b/dts/arm/gd/gd32f4xx/gd32f4xx.dtsi @@ -1,6 +1,6 @@ /* * Copyright (c) 2021, Teslabs Engineering S.L. - * + * Copyright (c) 2025 Aleksandr Senin * SPDX-License-Identifier: Apache-2.0 */ @@ -68,6 +68,14 @@ }; }; + trng0: trng@50060800 { + compatible = "gd,gd32-trng"; + reg = <0x50060800 0x400>; + clocks = <&cctl GD32_CLOCK_TRNG>; + resets = <&rctl GD32_RESET_TRNG>; + status = "disabled"; + }; + usart0: usart@40011000 { compatible = "gd,gd32-usart"; reg = <0x40011000 0x400>; diff --git a/dts/bindings/rng/gd,gd32-trng.yaml b/dts/bindings/rng/gd,gd32-trng.yaml new file mode 100644 index 000000000000..f57759749785 --- /dev/null +++ b/dts/bindings/rng/gd,gd32-trng.yaml @@ -0,0 +1,20 @@ +# Copyright (c) 2025 Aleksandr Senin +# +# SPDX-License-Identifier: Apache-2.0 + +description: GigaDevice GD32 TRNG (True Random Number Generator) + +compatible: "gd,gd32-trng" + +include: base.yaml + +properties: + reg: + required: true + + clocks: + required: true + + resets: + type: phandle-array + description: Optional reset line for the TRNG peripheral. From 57993e7d8ec33ad139c6f83cae5597a821e5757b Mon Sep 17 00:00:00 2001 From: Aleksandr Senin Date: Sun, 28 Dec 2025 20:23:20 +0300 Subject: [PATCH 1797/3659] soc: gd32: gd32f4xx: init CK48M from devicetree Add DT properties to select CK48M source for GD32 RCU. Apply CK48M source selection during early SoC init. Signed-off-by: Aleksandr Senin --- dts/bindings/mfd/gd,gd32-rcu.yaml | 27 ++++++++++++++ soc/gd/gd32/gd32f4xx/soc.c | 58 +++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+) diff --git a/dts/bindings/mfd/gd,gd32-rcu.yaml b/dts/bindings/mfd/gd,gd32-rcu.yaml index 92bb3b83616c..8964ba47f8c9 100644 --- a/dts/bindings/mfd/gd,gd32-rcu.yaml +++ b/dts/bindings/mfd/gd,gd32-rcu.yaml @@ -1,4 +1,7 @@ # Copyright (c) 2022, Teslabs Engineering S.L. +# Copyright (c) 2025 Meshium +# Aleksandr Senin +# # SPDX-License-Identifier: Apache-2.0 title: Gigadevice RCU (Reset and Clock Unit) @@ -15,3 +18,27 @@ include: base.yaml properties: reg: required: true + + gd,ck48m-source: + type: string + enum: + - "irc48m" + - "pll48m" + description: | + Select the CK48M clock source. CK48M is used by TRNG/SDIO/USBFS/USBHS. + When set to "irc48m", the SoC initialization code enables the IRC48M + oscillator and selects it as CK48M source. + When set to "pll48m", the SoC initialization code selects PLL48M as CK48M + source (see gd,pll48m-source). + + gd,pll48m-source: + type: string + enum: + - "pllq" + - "pllsaip" + default: "pllq" + description: | + Select the PLL48M source (CK_PLLQ or CK_PLLSAIP) when gd,ck48m-source is + set to "pll48m". This does not configure PLL/PLLSAI parameters; board + clock configuration must ensure the selected source provides a valid + 48MHz clock domain. diff --git a/soc/gd/gd32/gd32f4xx/soc.c b/soc/gd/gd32/gd32f4xx/soc.c index 136edfc6ae2f..03e63a5c026c 100644 --- a/soc/gd/gd32/gd32f4xx/soc.c +++ b/soc/gd/gd32/gd32f4xx/soc.c @@ -1,13 +1,71 @@ /* * Copyright (c) 2021, Teslabs Engineering S.L. + * Copyright (c) 2025 Aleksandr Senin + * * SPDX-License-Identifier: Apache-2.0 */ #include +#include #include #include +/* GD32 HAL RCU helpers */ +#include + +static void gd32f4xx_ck48m_init(void) +{ +#define RCU_NODE DT_NODELABEL(rcu) + + /* enum indexes follow the order in dts/bindings/mfd/gd,gd32-rcu.yaml */ + enum { + CK48M_SRC_IRC48M = 0, + CK48M_SRC_PLL48M = 1, + }; + + enum { + PLL48M_SRC_PLLQ = 0, + PLL48M_SRC_PLLSAIP = 1, + }; + + int ck48m_src = COND_CODE_1(DT_NODE_HAS_PROP(RCU_NODE, gd_ck48m_source), + (DT_ENUM_IDX(RCU_NODE, gd_ck48m_source)), + (-1)); + + int pll48m_src = COND_CODE_1(DT_NODE_HAS_PROP(RCU_NODE, gd_pll48m_source), + (DT_ENUM_IDX(RCU_NODE, gd_pll48m_source)), + (PLL48M_SRC_PLLQ)); + + if (ck48m_src < 0) { + return; + } + + switch (ck48m_src) { + case CK48M_SRC_IRC48M: + /* Enable internal 48MHz oscillator and select it as CK48M */ + rcu_osci_on(RCU_IRC48M); + (void)rcu_osci_stab_wait(RCU_IRC48M); + rcu_ck48m_clock_config(RCU_CK48MSRC_IRC48M); + break; + + case CK48M_SRC_PLL48M: + /* Select PLL48M source (PLLQ or PLLSAIP) and route it to CK48M */ + if (pll48m_src == PLL48M_SRC_PLLSAIP) { + rcu_pll48m_clock_config(RCU_PLL48MSRC_PLLSAIP); + } else { + rcu_pll48m_clock_config(RCU_PLL48MSRC_PLLQ); + } + + rcu_ck48m_clock_config(RCU_CK48MSRC_PLL48M); + break; + + default: + break; + } +} + void soc_early_init_hook(void) { SystemInit(); + gd32f4xx_ck48m_init(); } From 13286c2ddf0675e473a33da34ecce8da34ae240d Mon Sep 17 00:00:00 2001 From: Aleksandr Senin Date: Sun, 28 Dec 2025 20:23:21 +0300 Subject: [PATCH 1798/3659] tests: drivers: entropy: enable GD32 TRNG on gd32f450i_eval Enable TRNG node and select it as zephyr,entropy for the API test. Configure CK48M source via RCU DT properties. Signed-off-by: Aleksandr Senin --- .../entropy/api/boards/gd32f450i_eval.overlay | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 tests/drivers/entropy/api/boards/gd32f450i_eval.overlay diff --git a/tests/drivers/entropy/api/boards/gd32f450i_eval.overlay b/tests/drivers/entropy/api/boards/gd32f450i_eval.overlay new file mode 100644 index 000000000000..b10bc15a5af6 --- /dev/null +++ b/tests/drivers/entropy/api/boards/gd32f450i_eval.overlay @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2025 Aleksandr Senin + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + chosen { + zephyr,entropy = &trng0; + }; +}; + +&rcu { + gd,ck48m-source = "irc48m"; +}; + +&trng0 { + status = "okay"; +}; From c15bd8daa5aacc16be2d77096ea084711474ec13 Mon Sep 17 00:00:00 2001 From: Lin Yu-Cheng Date: Mon, 29 Dec 2025 14:21:35 +0800 Subject: [PATCH 1799/3659] drivers: spi: use transfer config to set spi frequency use transfer config to set spi frequency Signed-off-by: Lin Yu-Cheng --- drivers/spi/spi_rts5912_spi.c | 37 +++++++++++++++++++++++++-------- dts/arm/realtek/ec/rts5912.dtsi | 1 + 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/drivers/spi/spi_rts5912_spi.c b/drivers/spi/spi_rts5912_spi.c index 1b6f5aae396c..ccdcbfbfa7ee 100644 --- a/drivers/spi/spi_rts5912_spi.c +++ b/drivers/spi/spi_rts5912_spi.c @@ -12,6 +12,9 @@ #include #include #include +#include +#include +#include #include "reg/reg_spi.h" #define RTS5912_SPI_TIMEOUT_ROUND 100 @@ -21,7 +24,6 @@ #define RTS5912_SPI_FREQUENCY_REGISTER_MAXIMUM 0xFFFFFFFF #define RTS5912_SPI_FREQUENCY_BUS_MAXIMUM (50000000ul) #define RTS5912_SPI_FREQUENCY_BUS_MINIMUM (15000ul) -#define RTS5912_PLL_DIV2_FREQUENCY (50000000ul) #define RTS5912_SPI_ADDR_ONLY_MODE 0 #define RTS5912_SPI_ADDR_AND_DATA_MODE 2 @@ -31,13 +33,15 @@ LOG_MODULE_REGISTER(spi_rts5912_spi, CONFIG_SPI_LOG_LEVEL); struct spi_rts5912_config { volatile struct spi_reg *const spi_reg_base; const struct pinctrl_dev_config *pcfg; - const uint32_t frequency; + const struct device *clk_dev; + struct rts5912_sccon_subsys sccon_cfg; }; struct spi_rts5912_data { struct spi_context ctx; size_t transfer_len; size_t receive_len; + uint32_t spi_input_clock_rate; }; static int spi_rts5912_configure(const struct device *dev, const struct spi_config *spi_cfg) @@ -89,6 +93,11 @@ static int spi_rts5912_configure(const struct device *dev, const struct spi_conf return -EINVAL; } + if (spi_cfg->frequency < RTS5912_SPI_FREQUENCY_BUS_MINIMUM) { + LOG_ERR("Can't support frequency %d", spi_cfg->frequency); + return -EINVAL; + } + ctx->config = spi_cfg; spi->CTRL |= RTS5912_SPI_CTRL_RST_MASK; @@ -99,11 +108,10 @@ static int spi_rts5912_configure(const struct device *dev, const struct spi_conf spi->CMDN = RTS5912_SPI_ADDR_NUM; /* 7+1bit = 1Byte CMD */ spi->ADDR = 0x0; spi->ADDRN = RTS5912_SPI_ADDR_NUM; - if ((spi_config->frequency < RTS5912_SPI_FREQUENCY_BUS_MAXIMUM) && - (spi_config->frequency > RTS5912_SPI_FREQUENCY_BUS_MINIMUM)) { - spi->CKDV = (RTS5912_PLL_DIV2_FREQUENCY / spi_config->frequency) - 1; + if (spi_cfg->frequency < RTS5912_SPI_FREQUENCY_BUS_MAXIMUM) { + spi->CKDV = ((data->spi_input_clock_rate / 2) / spi_cfg->frequency) - 1; } else { - spi->CKDV = RTS5912_SPI_FREQUENCY_DEFAULT; + spi->CKDV = 0; } spi->CTRL |= RTS5912_SPI_CTRL_RST_MASK; @@ -233,6 +241,7 @@ static int spi_rts5912_spi_init(const struct device *dev) { const struct spi_rts5912_config *cfg = dev->config; struct spi_rts5912_data *data = dev->data; + uint32_t pll_clock_rate = 0; int ret; ret = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT); @@ -246,7 +255,15 @@ static int spi_rts5912_spi_init(const struct device *dev) return ret; } + ret = clock_control_get_rate(cfg->clk_dev, (clock_control_subsys_t)&cfg->sccon_cfg, + &pll_clock_rate); + if (ret) { + return ret; + } + + data->spi_input_clock_rate = pll_clock_rate; spi_context_unlock_unconditionally(&data->ctx); + return 0; } @@ -260,9 +277,11 @@ static DEVICE_API(spi, spi_rts5912_driver_api) = { static const struct spi_rts5912_config spi_rts5912_cfg_##n = { \ .spi_reg_base = (volatile struct spi_reg *const)DT_INST_REG_ADDR(n), \ .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ - .frequency = \ - DT_PROP_OR(n, clock_frequency, RTS5912_SPI_FREQUENCY_REGISTER_MAXIMUM), \ - }; \ + .clk_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(n)), \ + .sccon_cfg = { \ + .clk_grp = DT_INST_CLOCKS_CELL(n, clk_grp), \ + .clk_idx = DT_INST_CLOCKS_CELL(n, clk_idx), \ + }}; \ \ static struct spi_rts5912_data spi_rts5912_data_##n = { \ SPI_CONTEXT_INIT_LOCK(spi_rts5912_data_##n, ctx), \ diff --git a/dts/arm/realtek/ec/rts5912.dtsi b/dts/arm/realtek/ec/rts5912.dtsi index 69c577110754..bd1c32bf75e2 100644 --- a/dts/arm/realtek/ec/rts5912.dtsi +++ b/dts/arm/realtek/ec/rts5912.dtsi @@ -276,6 +276,7 @@ #address-cells = <1>; #size-cells = <0>; compatible = "realtek,rts5912-spi"; + clocks = <&sccon RTS5912_SCCON_SYS 0>; reg = <0x40010400 0x3C>; status = "disabled"; }; From 01e3a54f207cfb84136e860487ea18e6f65db60e Mon Sep 17 00:00:00 2001 From: Gaetan Perrot Date: Fri, 2 Jan 2026 11:59:32 +0900 Subject: [PATCH 1800/3659] Bluetooth: MICP: avoid NULL dereference Avoid calling micp_mic_ctlr_discover_complete() with a NULL controller pointer when lookup fails during AICS discovery. The micp_mic_ctlr_discover_complete() helper dereferences the controller unconditionally, which could otherwise lead to a NULL pointer dereference. Fix by returning early if the controller lookup fails. Signed-off-by: Gaetan Perrot --- subsys/bluetooth/audio/micp_mic_ctlr.c | 1 - 1 file changed, 1 deletion(-) diff --git a/subsys/bluetooth/audio/micp_mic_ctlr.c b/subsys/bluetooth/audio/micp_mic_ctlr.c index 165bb6920df3..f9f30429aa94 100644 --- a/subsys/bluetooth/audio/micp_mic_ctlr.c +++ b/subsys/bluetooth/audio/micp_mic_ctlr.c @@ -242,7 +242,6 @@ static void micp_mic_ctlr_aics_discover_cb(struct bt_aics *inst, int err) if (mic_ctlr == NULL) { LOG_ERR("Could not lookup mic_ctlr from aics"); - micp_mic_ctlr_discover_complete(mic_ctlr, BT_GATT_ERR(BT_ATT_ERR_UNLIKELY)); return; } From 9217ce54c61bf02f0b0e781492f96c21e95dd524 Mon Sep 17 00:00:00 2001 From: Gaetan Perrot Date: Fri, 2 Jan 2026 12:02:26 +0900 Subject: [PATCH 1801/3659] Bluetooth: VCP: avoid NULL dereference Avoid calling vcp_vol_ctlr_discover_complete() with a NULL controller pointer when lookup fails during AICS discovery. The vcp_vol_ctlr_discover_complete() helper dereferences the controller unconditionally, which could otherwise lead to a NULL pointer dereference. Fix by returning early if the controller lookup fails. Signed-off-by: Gaetan Perrot --- subsys/bluetooth/audio/vcp_vol_ctlr.c | 1 - 1 file changed, 1 deletion(-) diff --git a/subsys/bluetooth/audio/vcp_vol_ctlr.c b/subsys/bluetooth/audio/vcp_vol_ctlr.c index 416240cd254a..5fa1839158aa 100644 --- a/subsys/bluetooth/audio/vcp_vol_ctlr.c +++ b/subsys/bluetooth/audio/vcp_vol_ctlr.c @@ -674,7 +674,6 @@ static void vcp_vol_ctlr_aics_discover_cb(struct bt_aics *inst, int err) if (vol_ctlr == NULL) { LOG_ERR("Could not lookup vol_ctlr from aics"); - vcp_vol_ctlr_discover_complete(vol_ctlr, BT_GATT_ERR(BT_ATT_ERR_UNLIKELY)); return; } From a0918b6ed2ad0185424bf95f61056e64d84f4081 Mon Sep 17 00:00:00 2001 From: Sara Touqan Date: Thu, 8 Jan 2026 10:40:30 +0200 Subject: [PATCH 1802/3659] samples: mspi_flash: add clock-frequency in STM32 DTS files Add clock-frequency property under some overlay files. Signed-off-by: Sara Touqan --- samples/drivers/mspi/mspi_flash/boards/b_u585i_iot02a.overlay | 1 + samples/drivers/mspi/mspi_flash/boards/stm32h573i_dk.overlay | 2 +- samples/drivers/mspi/mspi_flash/boards/stm32h735g_disco.overlay | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/samples/drivers/mspi/mspi_flash/boards/b_u585i_iot02a.overlay b/samples/drivers/mspi/mspi_flash/boards/b_u585i_iot02a.overlay index 73748e08c622..eeb536a00f37 100644 --- a/samples/drivers/mspi/mspi_flash/boards/b_u585i_iot02a.overlay +++ b/samples/drivers/mspi/mspi_flash/boards/b_u585i_iot02a.overlay @@ -22,6 +22,7 @@ clocks = <&rcc STM32_CLOCK(AHB2_2, 8)>, <&rcc STM32_SRC_SYSCLK OCTOSPI_SEL(0)>, <&rcc STM32_CLOCK(AHB2, 21)>; + clock-frequency = ; #address-cells = <1>; #size-cells = <0>; op-mode = "MSPI_OP_MODE_CONTROLLER"; diff --git a/samples/drivers/mspi/mspi_flash/boards/stm32h573i_dk.overlay b/samples/drivers/mspi/mspi_flash/boards/stm32h573i_dk.overlay index 240221760c4e..cd37ec69d24c 100644 --- a/samples/drivers/mspi/mspi_flash/boards/stm32h573i_dk.overlay +++ b/samples/drivers/mspi/mspi_flash/boards/stm32h573i_dk.overlay @@ -21,9 +21,9 @@ clock-names = "xspix", "xspi-ker"; clocks = <&rcc STM32_CLOCK(AHB4, 20U)>, <&rcc STM32_SRC_PLL1_Q OCTOSPI1_SEL(1)>; + clock-frequency = ; #address-cells = <1>; #size-cells = <0>; - clock-frequency = <0x17d7840>; op-mode = "MSPI_OP_MODE_CONTROLLER"; status = "okay"; pinctrl-0 = <&octospi1_io0_pb1 &octospi1_io1_pd12 diff --git a/samples/drivers/mspi/mspi_flash/boards/stm32h735g_disco.overlay b/samples/drivers/mspi/mspi_flash/boards/stm32h735g_disco.overlay index c678e82a4270..5f4ad6c0d6ce 100644 --- a/samples/drivers/mspi/mspi_flash/boards/stm32h735g_disco.overlay +++ b/samples/drivers/mspi/mspi_flash/boards/stm32h735g_disco.overlay @@ -20,6 +20,7 @@ clock-names = "ospix", "ospi-ker"; clocks = <&rcc STM32_CLOCK(AHB3, 14)>, <&rcc STM32_SRC_PLL1_Q OSPI_SEL(1)>; + clock-frequency = ; #address-cells = <1>; #size-cells = <0>; op-mode = "MSPI_OP_MODE_CONTROLLER"; From 0651092295baed08f58dd4f2c93e15cd099a8084 Mon Sep 17 00:00:00 2001 From: Sara Touqan Date: Mon, 12 Jan 2026 10:30:52 +0200 Subject: [PATCH 1803/3659] drivers: mspi: stm32: refactor frequency handling to rely on devicetree Remove max frequency Kconfig and uses clock-frequency property instead Signed-off-by: Sara Touqan --- drivers/mspi/Kconfig.stm32 | 10 ---------- drivers/mspi/mspi_stm32.h | 2 -- drivers/mspi/mspi_stm32_ospi.c | 10 +++++----- drivers/mspi/mspi_stm32_qspi.c | 16 +++++++++------- drivers/mspi/mspi_stm32_xspi.c | 14 +++++++------- 5 files changed, 21 insertions(+), 31 deletions(-) diff --git a/drivers/mspi/Kconfig.stm32 b/drivers/mspi/Kconfig.stm32 index 9bc9eee26091..89ed686479ff 100644 --- a/drivers/mspi/Kconfig.stm32 +++ b/drivers/mspi/Kconfig.stm32 @@ -25,16 +25,6 @@ config MSPI_STM32_BUFFER_ALIGNMENT in order for DMA to work correctly. This represents the alignment of buffers required in bytes. -config MSPI_STM32_MAX_FREQ - int "MSPI max frequency" - default 250000000 if SOC_SERIES_STM32H5X - default 280000000 if SOC_SERIES_STM32H7X - default 160000000 if SOC_SERIES_STM32U5X - default 120000000 if SOC_SERIES_STM32L4X - default 110000000 if SOC_SERIES_STM32L5X - default 96000000 if SOC_SERIES_STM32U3X - default 250000000 - config MSPI_STM32_OSPI bool "STM32 OSPI Controller driver" depends on DT_HAS_ST_STM32_OSPI_CONTROLLER_ENABLED diff --git a/drivers/mspi/mspi_stm32.h b/drivers/mspi/mspi_stm32.h index 26b3441a06c8..89f2f5d0c5e6 100644 --- a/drivers/mspi/mspi_stm32.h +++ b/drivers/mspi/mspi_stm32.h @@ -17,7 +17,6 @@ #include "mspi_nor.h" #define MSPI_STM32_FIFO_THRESHOLD 4U -#define MSPI_MAX_FREQ CONFIG_MSPI_STM32_MAX_FREQ #define MSPI_MAX_DEVICE 1 #if defined(CONFIG_SOC_SERIES_STM32U5X) @@ -33,7 +32,6 @@ #endif #define MSPI_STM32_WRITE_REG_MAX_TIME 40U -#define MSPI_STM32_MAX_FREQ 48000000 typedef void (*irq_config_func_t)(void); diff --git a/drivers/mspi/mspi_stm32_ospi.c b/drivers/mspi/mspi_stm32_ospi.c index 0bbfdea802b5..3d246bfa82ac 100644 --- a/drivers/mspi/mspi_stm32_ospi.c +++ b/drivers/mspi/mspi_stm32_ospi.c @@ -934,7 +934,7 @@ static int mspi_stm32_ospi_dev_cfg_save(const struct device *controller, } if ((param_mask & MSPI_DEVICE_CONFIG_FREQUENCY) != 0) { - if (dev_cfg->freq > MSPI_MAX_FREQ) { + if (dev_cfg->freq > cfg->mspicfg.max_freq) { LOG_ERR("%u, freq is too large.", __LINE__); return -ENOTSUP; } @@ -1393,7 +1393,7 @@ static __maybe_unused void mspi_stm32_ospi_dma_callback(const struct device *dev } #endif /* CONFIG_MSPI_DMA && !HAL_MDMA_MODULE_ENABLED */ -static int mspi_stm32_ospi_conf_validate(const struct mspi_cfg *config) +static int mspi_stm32_ospi_conf_validate(const struct mspi_cfg *config, uint32_t max_frequency) { /* Only Controller mode is supported */ if (config->op_mode != MSPI_OP_MODE_CONTROLLER) { @@ -1402,7 +1402,7 @@ static int mspi_stm32_ospi_conf_validate(const struct mspi_cfg *config) } /* Check the max possible freq. */ - if (config->max_freq > MSPI_STM32_MAX_FREQ) { + if (config->max_freq > max_frequency) { LOG_ERR("Max_freq %d too large.", config->max_freq); return -ENOTSUP; } @@ -1521,7 +1521,7 @@ static int mspi_stm32_ospi_config(const struct mspi_dt_spec *spec) struct mspi_stm32_data *dev_data = spec->bus->data; int ret = 0; - ret = mspi_stm32_ospi_conf_validate(config); + ret = mspi_stm32_ospi_conf_validate(config, dev_cfg->mspicfg.max_freq); if (ret != 0) { return ret; } @@ -1764,7 +1764,7 @@ static int mspi_stm32_ospi_pm_action(const struct device *dev, enum pm_device_ac .channel_num = 0, \ .op_mode = DT_INST_ENUM_IDX_OR(index, op_mode, MSPI_OP_MODE_CONTROLLER), \ .duplex = DT_INST_ENUM_IDX_OR(index, duplex, MSPI_HALF_DUPLEX), \ - .max_freq = DT_INST_PROP_OR(index, mspi_max_frequency, MSPI_STM32_MAX_FREQ), \ + .max_freq = DT_INST_PROP(index, clock_frequency), \ .dqs_support = DT_INST_PROP(index, dqs_support), \ .num_periph = DT_INST_CHILD_NUM(index), \ .sw_multi_periph = DT_INST_PROP(index, software_multiperipheral), \ diff --git a/drivers/mspi/mspi_stm32_qspi.c b/drivers/mspi/mspi_stm32_qspi.c index a56d4a3f53f8..5091d3be3168 100644 --- a/drivers/mspi/mspi_stm32_qspi.c +++ b/drivers/mspi/mspi_stm32_qspi.c @@ -538,7 +538,7 @@ static int mspi_stm32_qspi_access(const struct device *dev, const struct mspi_xf * @param config Pointer to MSPI configuration * @return 0 on success, negative errno on failure */ -static int mspi_stm32_qspi_conf_validate(const struct mspi_cfg *config) +static int mspi_stm32_qspi_conf_validate(const struct mspi_cfg *config, uint32_t max_frequency) { /* Only Controller mode is supported */ if (config->op_mode != MSPI_OP_MODE_CONTROLLER) { @@ -547,7 +547,7 @@ static int mspi_stm32_qspi_conf_validate(const struct mspi_cfg *config) } /* Check the max possible freq. */ - if (config->max_freq > MSPI_MAX_FREQ) { + if (config->max_freq > max_frequency) { LOG_ERR("Max_freq %d too large.", config->max_freq); return -ENOTSUP; } @@ -657,7 +657,7 @@ static int mspi_stm32_qspi_config(const struct mspi_dt_spec *spec) LOG_DBG("Configuring QSPI controller"); - ret = mspi_stm32_qspi_conf_validate(config); + ret = mspi_stm32_qspi_conf_validate(config, cfg->mspicfg.max_freq); if (ret != 0) { return ret; } @@ -722,9 +722,10 @@ static int mspi_stm32_qspi_config(const struct mspi_dt_spec *spec) /** * Validate and set frequency configuration. */ -static int mspi_stm32_qspi_validate_and_set_freq(struct mspi_stm32_data *data, uint32_t freq) +static int mspi_stm32_qspi_validate_and_set_freq(struct mspi_stm32_data *data, uint32_t freq, + uint32_t max_frequency) { - if (freq > MSPI_MAX_FREQ) { + if (freq > max_frequency) { LOG_ERR("%u, freq is too large", __LINE__); return -ENOTSUP; } @@ -886,7 +887,8 @@ static int mspi_stm32_qspi_dev_cfg_save(const struct device *controller, } if ((param_mask & MSPI_DEVICE_CONFIG_FREQUENCY) != 0) { - ret = mspi_stm32_qspi_validate_and_set_freq(data, dev_cfg->freq); + ret = mspi_stm32_qspi_validate_and_set_freq(data, dev_cfg->freq, + cfg->mspicfg.max_freq); if (ret != 0) { return ret; } @@ -1306,7 +1308,7 @@ static DEVICE_API(mspi, mspi_stm32_qspi_driver_api) = { .channel_num = 0, \ .op_mode = DT_INST_ENUM_IDX_OR(index, op_mode, MSPI_OP_MODE_CONTROLLER), \ .duplex = DT_INST_ENUM_IDX_OR(index, duplex, MSPI_HALF_DUPLEX), \ - .max_freq = DT_INST_PROP_OR(index, clock_frequency, MSPI_MAX_FREQ), \ + .max_freq = DT_INST_PROP(index, clock_frequency), \ .dqs_support = false, /* QSPI typically doesn't support DQS */ \ .num_periph = DT_INST_CHILD_NUM(index), \ .sw_multi_periph = DT_INST_PROP(index, software_multiperipheral), \ diff --git a/drivers/mspi/mspi_stm32_xspi.c b/drivers/mspi/mspi_stm32_xspi.c index bea651afc631..e9392ad900e8 100644 --- a/drivers/mspi/mspi_stm32_xspi.c +++ b/drivers/mspi/mspi_stm32_xspi.c @@ -944,9 +944,9 @@ static __maybe_unused void mspi_stm32_xspi_dma_callback(const struct device *dev } #endif -static int mspi_stm32_xspi_validate_freq(uint32_t freq) +static int mspi_stm32_xspi_validate_freq(uint32_t freq, uint32_t max_freq) { - if (freq > MSPI_MAX_FREQ) { + if (freq > max_freq) { LOG_ERR("%u, freq is too large", __LINE__); return -ENOTSUP; } @@ -1094,7 +1094,7 @@ static int mspi_stm32_xspi_dev_cfg_save(const struct device *controller, } if ((param_mask & MSPI_DEVICE_CONFIG_FREQUENCY) != 0) { - ret = mspi_stm32_xspi_validate_freq(dev_cfg->freq); + ret = mspi_stm32_xspi_validate_freq(dev_cfg->freq, cfg->mspicfg.max_freq); if (ret != 0) { goto end; } @@ -1427,14 +1427,14 @@ static int mspi_stm32_xspi_dma_init(DMA_HandleTypeDef *hdma, struct stm32_stream return 0; } -static int mspi_validate_config(const struct mspi_cfg *config) +static int mspi_validate_config(const struct mspi_cfg *config, uint32_t max_frequency) { if (config->op_mode != MSPI_OP_MODE_CONTROLLER) { LOG_ERR("Only support MSPI controller mode"); return -ENOTSUP; } - if (config->max_freq > MSPI_STM32_MAX_FREQ) { + if (config->max_freq > max_frequency) { LOG_ERR("Max_freq %d too large", config->max_freq); return -ENOTSUP; } @@ -1552,7 +1552,7 @@ static int mspi_stm32_xspi_config(const struct mspi_dt_spec *spec) struct mspi_stm32_data *dev_data = spec->bus->data; uint32_t ahb_clock_freq; - ret = mspi_validate_config(config); + ret = mspi_validate_config(config, dev_cfg->mspicfg.max_freq); if (ret != 0) { return ret; } @@ -1746,7 +1746,7 @@ static int mspi_stm32_xspi_pm_action(const struct device *dev, enum pm_device_ac .channel_num = 0, \ .op_mode = DT_INST_ENUM_IDX_OR(index, op_mode, MSPI_OP_MODE_CONTROLLER), \ .duplex = DT_INST_ENUM_IDX_OR(index, duplex, MSPI_HALF_DUPLEX), \ - .max_freq = DT_INST_PROP_OR(index, mspi_max_frequency, MSPI_STM32_MAX_FREQ), \ + .max_freq = DT_INST_PROP(index, clock_frequency), \ .dqs_support = DT_INST_PROP(index, dqs_support), \ .num_periph = DT_INST_CHILD_NUM(index), \ .sw_multi_periph = DT_INST_PROP(index, software_multiperipheral), \ From da5f20c5ad5d86921b96664be81afa387c7effeb Mon Sep 17 00:00:00 2001 From: Sara Touqan Date: Tue, 13 Jan 2026 09:25:30 +0200 Subject: [PATCH 1804/3659] dts: bindings: mspi: stm32: Make clock-frequency a required property Add clock-frequency property as required for MSPI/OSPI/QSPI binding files. Signed-off-by: Sara Touqan --- dts/bindings/mspi/st,stm32-ospi-controller.yaml | 3 +++ dts/bindings/mspi/st,stm32-qspi-controller.yaml | 3 +++ dts/bindings/mspi/st,stm32-xspi-controller.yaml | 3 +++ 3 files changed, 9 insertions(+) diff --git a/dts/bindings/mspi/st,stm32-ospi-controller.yaml b/dts/bindings/mspi/st,stm32-ospi-controller.yaml index f06dcecb2052..05a5942f90ff 100644 --- a/dts/bindings/mspi/st,stm32-ospi-controller.yaml +++ b/dts/bindings/mspi/st,stm32-ospi-controller.yaml @@ -133,3 +133,6 @@ properties: Note: You might need to enable the OCTOSPI I/O manager clock to use the property. Please refer to Reference Manual. The clock can be enabled in the devicetree. + + clock-frequency: + required: true diff --git a/dts/bindings/mspi/st,stm32-qspi-controller.yaml b/dts/bindings/mspi/st,stm32-qspi-controller.yaml index 5a9b3ec03507..5807e722ebf0 100644 --- a/dts/bindings/mspi/st,stm32-qspi-controller.yaml +++ b/dts/bindings/mspi/st,stm32-qspi-controller.yaml @@ -47,3 +47,6 @@ properties: Enables Sample Shifting half-cycle. It is recommended to be enabled in STR mode and disabled in DTR mode. + + clock-frequency: + required: true diff --git a/dts/bindings/mspi/st,stm32-xspi-controller.yaml b/dts/bindings/mspi/st,stm32-xspi-controller.yaml index bc6265fd1e0b..9a8059a772b1 100644 --- a/dts/bindings/mspi/st,stm32-xspi-controller.yaml +++ b/dts/bindings/mspi/st,stm32-xspi-controller.yaml @@ -39,3 +39,6 @@ properties: Enables Sample Shifting half-cycle. It is recommended to be enabled in STR mode and disabled in DTR mode. + + clock-frequency: + required: true From 772bfccd68f859d3c939c4a1d071f002815c3b63 Mon Sep 17 00:00:00 2001 From: Sara Touqan Date: Mon, 12 Jan 2026 10:33:28 +0200 Subject: [PATCH 1805/3659] drivers: mspi: stm32: remove unused mspi_stm32_ospi_verify_device function Remove unused function in OSPI driver. Signed-off-by: Sara Touqan --- drivers/mspi/mspi_stm32_ospi.c | 38 ---------------------------------- 1 file changed, 38 deletions(-) diff --git a/drivers/mspi/mspi_stm32_ospi.c b/drivers/mspi/mspi_stm32_ospi.c index 3d246bfa82ac..ad04a7bee9bf 100644 --- a/drivers/mspi/mspi_stm32_ospi.c +++ b/drivers/mspi/mspi_stm32_ospi.c @@ -994,44 +994,6 @@ static int mspi_stm32_ospi_dev_cfg_save(const struct device *controller, return 0; } -/** - * Verify if the device with dev_id is on this MSPI bus. - * - * @param controller Pointer to the device structure for the driver instance. - * @param dev_id Pointer to the device ID structure from a device. - * @return 0 The device is on this MSPI bus. - * @return -ENODEV The device is not on this MSPI bus. - */ -static int mspi_stm32_ospi_verify_device(const struct device *controller, - const struct mspi_dev_id *dev_id) -{ - const struct mspi_stm32_conf *cfg = controller->config; - int device_index = cfg->mspicfg.num_periph; - - if (cfg->mspicfg.num_ce_gpios != 0) { - for (int i = 0; i < cfg->mspicfg.num_periph; i++) { - if (dev_id->ce.port == cfg->mspicfg.ce_group[i].port && - dev_id->ce.pin == cfg->mspicfg.ce_group[i].pin && - dev_id->ce.dt_flags == cfg->mspicfg.ce_group[i].dt_flags) { - device_index = i; - break; - } - } - - if (device_index >= cfg->mspicfg.num_periph || device_index != dev_id->dev_idx) { - LOG_ERR("%u, invalid device ID.", __LINE__); - return -ENODEV; - } - } else { - if (dev_id->dev_idx >= cfg->mspicfg.num_periph) { - LOG_ERR("%u, invalid device ID.", __LINE__); - return -ENODEV; - } - } - - return 0; -} - /** * API implementation of mspi_dev_config : controller device specific configuration * From f6060eb31f48d7bcda542b77998d37a9838a669e Mon Sep 17 00:00:00 2001 From: Gaetan Perrot Date: Tue, 6 Jan 2026 22:19:52 +0900 Subject: [PATCH 1806/3659] drivers: usb: usb_dc_numaker: make usbd_ep_fifo_copy_from_user void numaker_usbd_ep_fifo_copy_from_user() never reports errors and always returns 0. The error check at the call site is therefore dead code. Make the function void and drop the unused error handling. Signed-off-by: Gaetan Perrot --- drivers/usb/device/usb_dc_numaker.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/drivers/usb/device/usb_dc_numaker.c b/drivers/usb/device/usb_dc_numaker.c index 0f52b165a134..87a69cf13c54 100644 --- a/drivers/usb/device/usb_dc_numaker.c +++ b/drivers/usb/device/usb_dc_numaker.c @@ -536,7 +536,7 @@ static int numaker_usbd_ep_fifo_copy_to_user(struct numaker_usbd_ep *ep_cur, uin * * size_p holds size to copy/copied on input/output */ -static int numaker_usbd_ep_fifo_copy_from_user(struct numaker_usbd_ep *ep_cur, +static void numaker_usbd_ep_fifo_copy_from_user(struct numaker_usbd_ep *ep_cur, const uint8_t *usrbuf, uint32_t *size_p) { const struct device *dev = ep_cur->dev; @@ -562,8 +562,6 @@ static int numaker_usbd_ep_fifo_copy_from_user(struct numaker_usbd_ep *ep_cur, if (ep_cur->write_fifo_free == 0) { ep_cur->write_fifo_pos = ep_cur->dmabuf_base; } - - return 0; } /* Update EP read/write FIFO on DATA OUT/IN completed */ @@ -1701,11 +1699,7 @@ int usb_dc_ep_write(const uint8_t ep, const uint8_t *const data_buf, const uint3 /* NOTE: Null data or zero data length are valid, used for ZLP */ if (data_buf && data_len) { data_len_act = data_len; - rc = numaker_usbd_ep_fifo_copy_from_user(ep_cur, data_buf, &data_len_act); - if (rc < 0) { - LOG_ERR("Copy to FIFO from user buffer"); - goto cleanup; - } + numaker_usbd_ep_fifo_copy_from_user(ep_cur, data_buf, &data_len_act); } else { data_len_act = 0; } From 21c1417f31af72f169977e76397d80dd68f8be28 Mon Sep 17 00:00:00 2001 From: Gaetan Perrot Date: Tue, 13 Jan 2026 19:10:52 +0900 Subject: [PATCH 1807/3659] drivers: usb: usb_dc_numaker: make usbd_ep_fifo_copy_to_user void numaker_usbd_ep_fifo_copy_to_user() never reports errors and always returns 0. The error check at the call site is therefore dead code. Make the function void and drop the unused error handling. Signed-off-by: Gaetan Perrot --- drivers/usb/device/usb_dc_numaker.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/drivers/usb/device/usb_dc_numaker.c b/drivers/usb/device/usb_dc_numaker.c index 87a69cf13c54..b40092dfc762 100644 --- a/drivers/usb/device/usb_dc_numaker.c +++ b/drivers/usb/device/usb_dc_numaker.c @@ -506,7 +506,7 @@ static void numaker_usbd_setup_fifo_copy_to_user(const struct device *dev, uint8 * * size_p holds size to copy/copied on input/output */ -static int numaker_usbd_ep_fifo_copy_to_user(struct numaker_usbd_ep *ep_cur, uint8_t *usrbuf, +static void numaker_usbd_ep_fifo_copy_to_user(struct numaker_usbd_ep *ep_cur, uint8_t *usrbuf, uint32_t *size_p) { const struct device *dev = ep_cur->dev; @@ -528,8 +528,6 @@ static int numaker_usbd_ep_fifo_copy_to_user(struct numaker_usbd_ep *ep_cur, uin if (ep_cur->read_fifo_used == 0) { ep_cur->read_fifo_pos = ep_cur->dmabuf_base; } - - return 0; } /* Copy data from user buffer to EP FIFO @@ -1807,12 +1805,7 @@ int usb_dc_ep_read_wait(uint8_t ep, uint8_t *data_buf, uint32_t max_data_len, ui */ if (data_buf) { data_len_act = max_data_len; - rc = numaker_usbd_ep_fifo_copy_to_user(ep_cur, data_buf, &data_len_act); - if (rc < 0) { - LOG_ERR("Copy from FIFO to user buffer"); - goto cleanup; - } - + numaker_usbd_ep_fifo_copy_to_user(ep_cur, data_buf, &data_len_act); if (read_bytes) { *read_bytes = data_len_act; } From 8049f25a08db5b44b6761b1582f969424e4b28ec Mon Sep 17 00:00:00 2001 From: Camille BAUD Date: Wed, 7 Jan 2026 12:36:37 +0100 Subject: [PATCH 1808/3659] boards: add weact rp2350b_core add weact rp2350b board Signed-off-by: Camille BAUD --- boards/weact/rp2350b_core/Kconfig.defconfig | 11 ++ .../weact/rp2350b_core/Kconfig.rp2350b_core | 6 + boards/weact/rp2350b_core/board.cmake | 27 ++++ boards/weact/rp2350b_core/board.yml | 6 + .../rp2350b_core/doc/img/rp2350b_core.webp | Bin 0 -> 46480 bytes boards/weact/rp2350b_core/doc/index.rst | 56 +++++++ .../rp2350b_core/rp2350b_core-pinctrl.dtsi | 52 +++++++ boards/weact/rp2350b_core/rp2350b_core.dtsi | 147 ++++++++++++++++++ .../rp2350b_core_rp2350b_hazard3.dts | 18 +++ .../rp2350b_core_rp2350b_hazard3.yaml | 20 +++ .../rp2350b_core_rp2350b_hazard3_defconfig | 13 ++ .../rp2350b_core/rp2350b_core_rp2350b_m33.dts | 18 +++ .../rp2350b_core_rp2350b_m33.yaml | 23 +++ .../rp2350b_core_rp2350b_m33_defconfig | 13 ++ boards/weact/rp2350b_core/support/openocd.cfg | 11 ++ 15 files changed, 421 insertions(+) create mode 100644 boards/weact/rp2350b_core/Kconfig.defconfig create mode 100644 boards/weact/rp2350b_core/Kconfig.rp2350b_core create mode 100644 boards/weact/rp2350b_core/board.cmake create mode 100644 boards/weact/rp2350b_core/board.yml create mode 100644 boards/weact/rp2350b_core/doc/img/rp2350b_core.webp create mode 100644 boards/weact/rp2350b_core/doc/index.rst create mode 100644 boards/weact/rp2350b_core/rp2350b_core-pinctrl.dtsi create mode 100644 boards/weact/rp2350b_core/rp2350b_core.dtsi create mode 100644 boards/weact/rp2350b_core/rp2350b_core_rp2350b_hazard3.dts create mode 100644 boards/weact/rp2350b_core/rp2350b_core_rp2350b_hazard3.yaml create mode 100644 boards/weact/rp2350b_core/rp2350b_core_rp2350b_hazard3_defconfig create mode 100644 boards/weact/rp2350b_core/rp2350b_core_rp2350b_m33.dts create mode 100644 boards/weact/rp2350b_core/rp2350b_core_rp2350b_m33.yaml create mode 100644 boards/weact/rp2350b_core/rp2350b_core_rp2350b_m33_defconfig create mode 100644 boards/weact/rp2350b_core/support/openocd.cfg diff --git a/boards/weact/rp2350b_core/Kconfig.defconfig b/boards/weact/rp2350b_core/Kconfig.defconfig new file mode 100644 index 000000000000..91630cd53b8b --- /dev/null +++ b/boards/weact/rp2350b_core/Kconfig.defconfig @@ -0,0 +1,11 @@ +# Copyright (c) 2026 MASSDRIVER EI (massdriver.space +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_RP2350B_CORE + +config USB_SELF_POWERED + default n + +source "boards/common/usb/Kconfig.cdc_acm_serial.defconfig" + +endif # BOARD_RP2350B_CORE diff --git a/boards/weact/rp2350b_core/Kconfig.rp2350b_core b/boards/weact/rp2350b_core/Kconfig.rp2350b_core new file mode 100644 index 000000000000..e17c2f776a40 --- /dev/null +++ b/boards/weact/rp2350b_core/Kconfig.rp2350b_core @@ -0,0 +1,6 @@ +# Copyright (c) 2026 MASSDRIVER EI (massdriver.space) +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_RP2350B_CORE + select SOC_RP2350B_HAZARD3 if BOARD_RP2350B_CORE_RP2350B_HAZARD3 + select SOC_RP2350B_M33 if BOARD_RP2350B_CORE_RP2350B_M33 diff --git a/boards/weact/rp2350b_core/board.cmake b/boards/weact/rp2350b_core/board.cmake new file mode 100644 index 000000000000..cc5d6283091b --- /dev/null +++ b/boards/weact/rp2350b_core/board.cmake @@ -0,0 +1,27 @@ +# SPDX-License-Identifier: Apache-2.0 + +if("${RPI_PICO_DEBUG_ADAPTER}" STREQUAL "") + set(RPI_PICO_DEBUG_ADAPTER "cmsis-dap") +endif() + +board_runner_args(openocd --cmd-pre-init "source [find interface/${RPI_PICO_DEBUG_ADAPTER}.cfg]") +if(CONFIG_ARM) + board_runner_args(openocd --cmd-pre-init "source [find target/rp2350.cfg]") +else() + board_runner_args(openocd --cmd-pre-init "source [find target/rp2350-riscv.cfg]") +endif() + +# The adapter speed is expected to be set by interface configuration. +# The Raspberry Pi's OpenOCD fork doesn't, so match their documentation at +# https://www.raspberrypi.com/documentation/microcontrollers/debug-probe.html#debugging-with-swd +board_runner_args(openocd --cmd-pre-init "set_adapter_speed_if_not_set 1000") + +board_runner_args(probe-rs "--chip=RP235x") + +board_runner_args(jlink "--device=RP2350_M33_0") +board_runner_args(uf2 "--board-id=RP2350") + +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) +include(${ZEPHYR_BASE}/boards/common/probe-rs.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) +include(${ZEPHYR_BASE}/boards/common/uf2.board.cmake) diff --git a/boards/weact/rp2350b_core/board.yml b/boards/weact/rp2350b_core/board.yml new file mode 100644 index 000000000000..bc0b26e6af54 --- /dev/null +++ b/boards/weact/rp2350b_core/board.yml @@ -0,0 +1,6 @@ +board: + name: rp2350b_core + full_name: WeAct RP2350B Core + vendor: weact + socs: + - name: rp2350b diff --git a/boards/weact/rp2350b_core/doc/img/rp2350b_core.webp b/boards/weact/rp2350b_core/doc/img/rp2350b_core.webp new file mode 100644 index 0000000000000000000000000000000000000000..eea99eb07bb3a41794bdb33d92709b031d8cc77c GIT binary patch literal 46480 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 + +&pinctrl { + uart0_default: uart0_default { + group1 { + pinmux = ; + }; + + group2 { + pinmux = ; + input-enable; + }; + }; + + i2c0_default: i2c0_default { + group1 { + pinmux = , ; + input-enable; + input-schmitt-enable; + }; + }; + + i2c1_default: i2c1_default { + group1 { + pinmux = , ; + input-enable; + input-schmitt-enable; + }; + }; + + spi0_default: spi0_default { + group1 { + pinmux = , , ; + }; + + group2 { + pinmux = ; + input-enable; + }; + }; + + pwm_ch4b_default: pwm_ch4b_default { + group1 { + pinmux = ; + }; + }; +}; diff --git a/boards/weact/rp2350b_core/rp2350b_core.dtsi b/boards/weact/rp2350b_core/rp2350b_core.dtsi new file mode 100644 index 000000000000..80448a5cfede --- /dev/null +++ b/boards/weact/rp2350b_core/rp2350b_core.dtsi @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2026 MASSDRIVER EI (massdriver.space) + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include +#include +#include + +#include "rp2350b_core-pinctrl.dtsi" + +/ { + chosen { + zephyr,sram = &sram0; + zephyr,flash = &flash0; + zephyr,flash-controller = &qmi; + zephyr,code-partition = &slot0_partition; + uart,passthrough = &uart0; + }; + + aliases { + watchdog0 = &wdt0; + }; + + leds { + compatible = "gpio-leds"; + + led0: led_0 { + gpios = <&gpio0 25 GPIO_ACTIVE_HIGH>; + label = "LED"; + }; + }; + + pwm_leds { + compatible = "pwm-leds"; + status = "disabled"; + + pwm_led0: pwm_led_0 { + pwms = <&pwm 9 PWM_MSEC(20) PWM_POLARITY_NORMAL>; + label = "PWM_LED"; + }; + }; + + buttons { + compatible = "gpio-keys"; + + button_0: sw0 { + gpios = <&gpio0 23 GPIO_ACTIVE_LOW>; + zephyr,code = ; + }; + }; + + aliases { + led0 = &led0; + pwm-led0 = &pwm_led0; + sw0 = &button_0; + }; +}; + +&flash0 { + reg = <0x10000000 DT_SIZE_M(16)>; + status = "okay"; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <0x1>; + #size-cells = <0x1>; + + slot0_partition: partition@0 { + label = "image-0"; + reg = <0x0 0x400000>; + }; + + slot1_partition: partition@400000 { + label = "image-1"; + reg = <0x400000 0x400000>; + }; + + storage_partition: partition@800000 { + label = "storage"; + reg = <0x800000 0x800000>; + }; + }; +}; + +&uart0 { + current-speed = <115200>; + status = "okay"; + pinctrl-0 = <&uart0_default>; + pinctrl-names = "default"; +}; + +gpio0_lo: &gpio0 { + status = "okay"; +}; + +gpio1: &gpio0_hi { + status = "okay"; +}; + +&spi0 { + clock-frequency = ; + pinctrl-0 = <&spi0_default>; + pinctrl-names = "default"; + status = "okay"; +}; + +&i2c0 { + clock-frequency = ; + pinctrl-0 = <&i2c0_default>; + pinctrl-names = "default"; + status = "okay"; +}; + +&i2c1 { + clock-frequency = ; + pinctrl-0 = <&i2c1_default>; + pinctrl-names = "default"; + status = "okay"; +}; + +&pwm { + pinctrl-0 = <&pwm_ch4b_default>; + pinctrl-names = "default"; + divider-int-0 = <255>; +}; + +&timer0 { + status = "okay"; +}; + +&wdt0 { + status = "okay"; +}; + +&rng { + status = "okay"; +}; + +zephyr_udc0: &usbd { + status = "okay"; +}; + +#include <../boards/common/usb/cdc_acm_serial.dtsi> diff --git a/boards/weact/rp2350b_core/rp2350b_core_rp2350b_hazard3.dts b/boards/weact/rp2350b_core/rp2350b_core_rp2350b_hazard3.dts new file mode 100644 index 000000000000..3ac75fb6a16c --- /dev/null +++ b/boards/weact/rp2350b_core/rp2350b_core_rp2350b_hazard3.dts @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2025 Andrew Featherstone + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +/* The build system assumes that there's a cpucluster-specific file. + * + * This file provides composition of the device tree: + * 1. The common features of the SoC + * 2. Core-specific configuration. + * 3. Board-specific configuration. + */ +#include +#include +#include "rp2350b_core.dtsi" diff --git a/boards/weact/rp2350b_core/rp2350b_core_rp2350b_hazard3.yaml b/boards/weact/rp2350b_core/rp2350b_core_rp2350b_hazard3.yaml new file mode 100644 index 000000000000..f01945a1627f --- /dev/null +++ b/boards/weact/rp2350b_core/rp2350b_core_rp2350b_hazard3.yaml @@ -0,0 +1,20 @@ +identifier: rp2350b_core/rp2350b/hazard3 +name: WeAct RP2350B Core (Hazard3) +type: mcu +arch: riscv +flash: 4096 +ram: 520 +toolchain: + - zephyr +supported: + - clock + - counter + - dma + - gpio + - hwinfo + - i2c + - pwm + - spi + - uart + - usbd + - watchdog diff --git a/boards/weact/rp2350b_core/rp2350b_core_rp2350b_hazard3_defconfig b/boards/weact/rp2350b_core/rp2350b_core_rp2350b_hazard3_defconfig new file mode 100644 index 000000000000..4da77bdb95c2 --- /dev/null +++ b/boards/weact/rp2350b_core/rp2350b_core_rp2350b_hazard3_defconfig @@ -0,0 +1,13 @@ +# This configuration is orthogonal to whether the Cortex-M33 or Hazard3 cores +# are in use, but Zephyr does not support providing a qualifier-agnostic +# _defconfig file. +CONFIG_BUILD_OUTPUT_HEX=y +CONFIG_BUILD_OUTPUT_UF2=y +CONFIG_CLOCK_CONTROL=y +CONFIG_CONSOLE=y +CONFIG_GPIO=y +CONFIG_RESET=y +CONFIG_SERIAL=y +CONFIG_UART_CONSOLE=y +CONFIG_UART_INTERRUPT_DRIVEN=y +CONFIG_USE_DT_CODE_PARTITION=y diff --git a/boards/weact/rp2350b_core/rp2350b_core_rp2350b_m33.dts b/boards/weact/rp2350b_core/rp2350b_core_rp2350b_m33.dts new file mode 100644 index 000000000000..8b21486ee002 --- /dev/null +++ b/boards/weact/rp2350b_core/rp2350b_core_rp2350b_m33.dts @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2024 Andrew Featherstone + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +/* The build system assumes that there's a cpucluster-specific file. + * + * This file provides composition of the device tree: + * 1. The common features of the SoC + * 2. Core-specific configuration. + * 3. Board-specific configuration. + */ +#include +#include +#include "rp2350b_core.dtsi" diff --git a/boards/weact/rp2350b_core/rp2350b_core_rp2350b_m33.yaml b/boards/weact/rp2350b_core/rp2350b_core_rp2350b_m33.yaml new file mode 100644 index 000000000000..cb8796560e3d --- /dev/null +++ b/boards/weact/rp2350b_core/rp2350b_core_rp2350b_m33.yaml @@ -0,0 +1,23 @@ +identifier: rp2350b_core/rp2350b/m33 +name: WeAct RP2350B Core (Cortex-M33) +type: mcu +arch: arm +flash: 4096 +ram: 520 +toolchain: + - zephyr + - gnuarmemb +supported: + - clock + - counter + - crypto + - dma + - entropy + - gpio + - hwinfo + - i2c + - pwm + - spi + - uart + - usbd + - watchdog diff --git a/boards/weact/rp2350b_core/rp2350b_core_rp2350b_m33_defconfig b/boards/weact/rp2350b_core/rp2350b_core_rp2350b_m33_defconfig new file mode 100644 index 000000000000..4da77bdb95c2 --- /dev/null +++ b/boards/weact/rp2350b_core/rp2350b_core_rp2350b_m33_defconfig @@ -0,0 +1,13 @@ +# This configuration is orthogonal to whether the Cortex-M33 or Hazard3 cores +# are in use, but Zephyr does not support providing a qualifier-agnostic +# _defconfig file. +CONFIG_BUILD_OUTPUT_HEX=y +CONFIG_BUILD_OUTPUT_UF2=y +CONFIG_CLOCK_CONTROL=y +CONFIG_CONSOLE=y +CONFIG_GPIO=y +CONFIG_RESET=y +CONFIG_SERIAL=y +CONFIG_UART_CONSOLE=y +CONFIG_UART_INTERRUPT_DRIVEN=y +CONFIG_USE_DT_CODE_PARTITION=y diff --git a/boards/weact/rp2350b_core/support/openocd.cfg b/boards/weact/rp2350b_core/support/openocd.cfg new file mode 100644 index 000000000000..82666bb53314 --- /dev/null +++ b/boards/weact/rp2350b_core/support/openocd.cfg @@ -0,0 +1,11 @@ +# Copyright (c) 2024 TOKITA Hiroshi +# SPDX-License-Identifier: Apache-2.0 + +# Checking and set 'adapter speed'. +# Set the adaptor speed, if unset, and given as an argument. +proc set_adapter_speed_if_not_set { speed } { + puts "checking adapter speed..." + if { [catch {adapter speed} ret] } { + adapter speed $speed + } +} From cab3ad6137916e0ffb6509dcc8d7a5bace3b8f08 Mon Sep 17 00:00:00 2001 From: Khoa Nguyen Date: Wed, 24 Dec 2025 15:49:59 +0700 Subject: [PATCH 1809/3659] manifest: Update latest hal_renesas revision Update latest hal_renesas revision Signed-off-by: Khoa Nguyen --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index a11238717de4..e047e218c1b9 100644 --- a/west.yml +++ b/west.yml @@ -231,7 +231,7 @@ manifest: - hal - name: hal_renesas path: modules/hal/renesas - revision: 6894582f2d7ff750caa60d60dd5ccac7927b72e4 + revision: 56c35ce22bac062a9d6b1fc87f145b5d48571efb groups: - hal - name: hal_rpi_pico From 448d3c04f7da7f70cbc6ad3689d739b1f4ba8fb2 Mon Sep 17 00:00:00 2001 From: Khoa Nguyen Date: Mon, 12 Jan 2026 03:54:52 +0000 Subject: [PATCH 1810/3659] modules: Update Kconfig USE_RA_FSP for RA I2C controller Since the latest hal_renesas has updated the I2C Controller config to build the IIC Controller source. Without this update, many current PRs on mainstream which has the update for hal_renesas revision will fail. Signed-off-by: Khoa Nguyen --- drivers/i2c/Kconfig.renesas_ra | 6 +++--- modules/Kconfig.renesas | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/i2c/Kconfig.renesas_ra b/drivers/i2c/Kconfig.renesas_ra index 726d900bf5ed..45f3e5154884 100644 --- a/drivers/i2c/Kconfig.renesas_ra +++ b/drivers/i2c/Kconfig.renesas_ra @@ -4,13 +4,13 @@ # SPDX-License-Identifier: Apache-2.0 config I2C_RENESAS_RA_IIC - bool "Renesas RA I2C IIC Master" + bool "Renesas RA I2C IIC Controller" default y depends on DT_HAS_RENESAS_RA_IIC_ENABLED - select USE_RA_FSP_I2C_IIC + select USE_RA_FSP_I2C_IIC_CONTROLLER select PINCTRL help - Enable Renesas RA I2C IIC Driver. + Enable Renesas RA I2C IIC Controller Driver. config I2C_RENESAS_RA_SCI bool "Renesas RA SCI I2C" diff --git a/modules/Kconfig.renesas b/modules/Kconfig.renesas index 8434c47091f9..25870af170e0 100644 --- a/modules/Kconfig.renesas +++ b/modules/Kconfig.renesas @@ -40,10 +40,10 @@ config USE_RA_FSP_DTC help Enable RA FSP DTC driver -config USE_RA_FSP_I2C_IIC +config USE_RA_FSP_I2C_IIC_CONTROLLER bool help - Enable Renesas RA I2C IIC Master driver + Enable Renesas RA I2C IIC Controller driver config USE_RA_FSP_SCI_I2C bool From 6cab38312bdf4e49c6d68a54989dabca7e9a1eee Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Mon, 12 Jan 2026 12:13:14 -0800 Subject: [PATCH 1811/3659] soc: intel_adsp: add GDB stub register list for ACE 4.0 This adds the register list for GDB stub that is suitable for ACE 4.0. Fixes #102084 Signed-off-by: Daniel Leung --- soc/intel/intel_adsp/ace/CMakeLists.txt | 10 +- soc/intel/intel_adsp/ace/gdbstub_ace40.c | 914 ++++++++++++++++++ .../intel_adsp/common/gdbstub_backend_sram.c | 3 +- 3 files changed, 923 insertions(+), 4 deletions(-) create mode 100644 soc/intel/intel_adsp/ace/gdbstub_ace40.c diff --git a/soc/intel/intel_adsp/ace/CMakeLists.txt b/soc/intel/intel_adsp/ace/CMakeLists.txt index 46c8d6c0a866..80225ab23de4 100644 --- a/soc/intel/intel_adsp/ace/CMakeLists.txt +++ b/soc/intel/intel_adsp/ace/CMakeLists.txt @@ -14,9 +14,13 @@ zephyr_library_sources( timestamp.c ) -zephyr_library_sources_ifdef(CONFIG_GDBSTUB - gdbstub.c - ) +if(CONFIG_GDBSTUB) + if(CONFIG_SOC_INTEL_ACE40) + zephyr_library_sources(gdbstub_ace40.c) + else() + zephyr_library_sources(gdbstub.c) + endif() +endif() zephyr_include_directories(include) zephyr_include_directories(include/${CONFIG_SOC}) diff --git a/soc/intel/intel_adsp/ace/gdbstub_ace40.c b/soc/intel/intel_adsp/ace/gdbstub_ace40.c new file mode 100644 index 000000000000..a5cf9b641e0e --- /dev/null +++ b/soc/intel/intel_adsp/ace/gdbstub_ace40.c @@ -0,0 +1,914 @@ +/* + * Copyright (c) 2026 Intel Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include + +static struct xtensa_register gdb_reg_list[] = { + { + /* PC */ + .idx = 0, + .regno = 0x20, + .byte_size = 4, + .gpkt_offset = 0, + .stack_offset = ___xtensa_irq_bsa_t_pc_OFFSET, + }, + { + /* AR0 */ + .idx = 1, + .regno = 0x100, + .byte_size = 4, + .gpkt_offset = 4, + }, + { + /* AR1 */ + .idx = 2, + .regno = 0x101, + .byte_size = 4, + .gpkt_offset = 8, + }, + { + /* AR2 */ + .idx = 3, + .regno = 0x102, + .byte_size = 4, + .gpkt_offset = 12, + }, + { + /* AR3 */ + .idx = 4, + .regno = 0x103, + .byte_size = 4, + .gpkt_offset = 16, + }, + { + /* AR4 */ + .idx = 5, + .regno = 0x104, + .byte_size = 4, + .gpkt_offset = 20, + }, + { + /* AR5 */ + .idx = 6, + .regno = 0x105, + .byte_size = 4, + .gpkt_offset = 24, + }, + { + /* AR6 */ + .idx = 7, + .regno = 0x106, + .byte_size = 4, + .gpkt_offset = 28, + }, + { + /* AR7 */ + .idx = 8, + .regno = 0x107, + .byte_size = 4, + .gpkt_offset = 32, + }, + { + /* AR8 */ + .idx = 9, + .regno = 0x108, + .byte_size = 4, + .gpkt_offset = 36, + }, + { + /* AR9 */ + .idx = 10, + .regno = 0x109, + .byte_size = 4, + .gpkt_offset = 40, + }, + { + /* AR10 */ + .idx = 11, + .regno = 0x10a, + .byte_size = 4, + .gpkt_offset = 44, + }, + { + /* AR11 */ + .idx = 12, + .regno = 0x10b, + .byte_size = 4, + .gpkt_offset = 48, + }, + { + /* AR12 */ + .idx = 13, + .regno = 0x10c, + .byte_size = 4, + .gpkt_offset = 52, + }, + { + /* AR13 */ + .idx = 14, + .regno = 0x10d, + .byte_size = 4, + .gpkt_offset = 56, + }, + { + /* AR14 */ + .idx = 15, + .regno = 0x10e, + .byte_size = 4, + .gpkt_offset = 60, + }, + { + /* AR15 */ + .idx = 16, + .regno = 0x10f, + .byte_size = 4, + .gpkt_offset = 64, + }, + { + /* AR16 */ + .idx = 17, + .regno = 0x110, + .byte_size = 4, + .gpkt_offset = 68, + }, + { + /* AR17 */ + .idx = 18, + .regno = 0x111, + .byte_size = 4, + .gpkt_offset = 72, + }, + { + /* AR18 */ + .idx = 19, + .regno = 0x112, + .byte_size = 4, + .gpkt_offset = 76, + }, + { + /* AR19 */ + .idx = 20, + .regno = 0x113, + .byte_size = 4, + .gpkt_offset = 80, + }, + { + /* AR20 */ + .idx = 21, + .regno = 0x114, + .byte_size = 4, + .gpkt_offset = 84, + }, + { + /* AR21 */ + .idx = 22, + .regno = 0x115, + .byte_size = 4, + .gpkt_offset = 88, + }, + { + /* AR22 */ + .idx = 23, + .regno = 0x116, + .byte_size = 4, + .gpkt_offset = 92, + }, + { + /* AR23 */ + .idx = 24, + .regno = 0x117, + .byte_size = 4, + .gpkt_offset = 96, + }, + { + /* AR24 */ + .idx = 25, + .regno = 0x118, + .byte_size = 4, + .gpkt_offset = 100, + }, + { + /* AR25 */ + .idx = 26, + .regno = 0x119, + .byte_size = 4, + .gpkt_offset = 104, + }, + { + /* AR26 */ + .idx = 27, + .regno = 0x11a, + .byte_size = 4, + .gpkt_offset = 108, + }, + { + /* AR27 */ + .idx = 28, + .regno = 0x11b, + .byte_size = 4, + .gpkt_offset = 112, + }, + { + /* AR28 */ + .idx = 29, + .regno = 0x11c, + .byte_size = 4, + .gpkt_offset = 116, + }, + { + /* AR29 */ + .idx = 30, + .regno = 0x11d, + .byte_size = 4, + .gpkt_offset = 120, + }, + { + /* AR30 */ + .idx = 31, + .regno = 0x11e, + .byte_size = 4, + .gpkt_offset = 124, + }, + { + /* AR31 */ + .idx = 32, + .regno = 0x11f, + .byte_size = 4, + .gpkt_offset = 128, + }, + { + /* AR32 */ + .idx = 33, + .regno = 0x120, + .byte_size = 4, + .gpkt_offset = 132, + }, + { + /* AR33 */ + .idx = 34, + .regno = 0x121, + .byte_size = 4, + .gpkt_offset = 136, + }, + { + /* AR34 */ + .idx = 35, + .regno = 0x122, + .byte_size = 4, + .gpkt_offset = 140, + }, + { + /* AR35 */ + .idx = 36, + .regno = 0x123, + .byte_size = 4, + .gpkt_offset = 144, + }, + { + /* AR36 */ + .idx = 37, + .regno = 0x124, + .byte_size = 4, + .gpkt_offset = 148, + }, + { + /* AR37 */ + .idx = 38, + .regno = 0x125, + .byte_size = 4, + .gpkt_offset = 152, + }, + { + /* AR38 */ + .idx = 39, + .regno = 0x126, + .byte_size = 4, + .gpkt_offset = 156, + }, + { + /* AR39 */ + .idx = 40, + .regno = 0x127, + .byte_size = 4, + .gpkt_offset = 160, + }, + { + /* AR40 */ + .idx = 41, + .regno = 0x128, + .byte_size = 4, + .gpkt_offset = 164, + }, + { + /* AR41 */ + .idx = 42, + .regno = 0x129, + .byte_size = 4, + .gpkt_offset = 168, + }, + { + /* AR42 */ + .idx = 43, + .regno = 0x12a, + .byte_size = 4, + .gpkt_offset = 172, + }, + { + /* AR43 */ + .idx = 44, + .regno = 0x12b, + .byte_size = 4, + .gpkt_offset = 176, + }, + { + /* AR44 */ + .idx = 45, + .regno = 0x12c, + .byte_size = 4, + .gpkt_offset = 180, + }, + { + /* AR45 */ + .idx = 46, + .regno = 0x12d, + .byte_size = 4, + .gpkt_offset = 184, + }, + { + /* AR46 */ + .idx = 47, + .regno = 0x12e, + .byte_size = 4, + .gpkt_offset = 188, + }, + { + /* AR47 */ + .idx = 48, + .regno = 0x12f, + .byte_size = 4, + .gpkt_offset = 192, + }, + { + /* AR48 */ + .idx = 49, + .regno = 0x130, + .byte_size = 4, + .gpkt_offset = 196, + }, + { + /* AR49 */ + .idx = 50, + .regno = 0x131, + .byte_size = 4, + .gpkt_offset = 200, + }, + { + /* AR50 */ + .idx = 51, + .regno = 0x132, + .byte_size = 4, + .gpkt_offset = 204, + }, + { + /* AR51 */ + .idx = 52, + .regno = 0x133, + .byte_size = 4, + .gpkt_offset = 208, + }, + { + /* AR52 */ + .idx = 53, + .regno = 0x134, + .byte_size = 4, + .gpkt_offset = 212, + }, + { + /* AR53 */ + .idx = 54, + .regno = 0x135, + .byte_size = 4, + .gpkt_offset = 216, + }, + { + /* AR54 */ + .idx = 55, + .regno = 0x136, + .byte_size = 4, + .gpkt_offset = 220, + }, + { + /* AR55 */ + .idx = 56, + .regno = 0x137, + .byte_size = 4, + .gpkt_offset = 224, + }, + { + /* AR56 */ + .idx = 57, + .regno = 0x138, + .byte_size = 4, + .gpkt_offset = 228, + }, + { + /* AR57 */ + .idx = 58, + .regno = 0x139, + .byte_size = 4, + .gpkt_offset = 232, + }, + { + /* AR58 */ + .idx = 59, + .regno = 0x13a, + .byte_size = 4, + .gpkt_offset = 236, + }, + { + /* AR59 */ + .idx = 60, + .regno = 0x13b, + .byte_size = 4, + .gpkt_offset = 240, + }, + { + /* AR60 */ + .idx = 61, + .regno = 0x13c, + .byte_size = 4, + .gpkt_offset = 244, + }, + { + /* AR61 */ + .idx = 62, + .regno = 0x13d, + .byte_size = 4, + .gpkt_offset = 248, + }, + { + /* AR62 */ + .idx = 63, + .regno = 0x13e, + .byte_size = 4, + .gpkt_offset = 252, + }, + { + /* AR63 */ + .idx = 64, + .regno = 0x13f, + .byte_size = 4, + .gpkt_offset = 256, + }, + { + /* LBEG */ + .idx = 65, + .regno = 0x200, + .byte_size = 4, + .gpkt_offset = 260, + .stack_offset = ___xtensa_irq_bsa_t_lbeg_OFFSET, + }, + { + /* LEND */ + .idx = 66, + .regno = 0x201, + .byte_size = 4, + .gpkt_offset = 264, + .stack_offset = ___xtensa_irq_bsa_t_lend_OFFSET, + }, + { + /* LCOUNT */ + .idx = 67, + .regno = 0x202, + .byte_size = 4, + .gpkt_offset = 268, + .stack_offset = ___xtensa_irq_bsa_t_lcount_OFFSET, + }, + { + /* SAR */ + .idx = 68, + .regno = 0x203, + .byte_size = 4, + .gpkt_offset = 272, + .stack_offset = ___xtensa_irq_bsa_t_sar_OFFSET, + }, + { + /* PREFCTL */ + .idx = 69, + .regno = 0x228, + .byte_size = 4, + .gpkt_offset = 276, + .is_read_only = 1, + }, + { + /* WINDOWBASE */ + .idx = 70, + .regno = 0x248, + .byte_size = 4, + .gpkt_offset = 280, + .is_read_only = 1, + }, + { + /* WINDOWSTART */ + .idx = 71, + .regno = 0x249, + .byte_size = 4, + .gpkt_offset = 284, + .is_read_only = 1, + }, + { + /* PS */ + .idx = 74, + .regno = 0x2e6, + .byte_size = 4, + .gpkt_offset = 296, + .stack_offset = ___xtensa_irq_bsa_t_ps_OFFSET, + }, + { + /* THREADPTR */ + .idx = 75, + .regno = 0x3e7, + .byte_size = 4, + .gpkt_offset = 300, + IF_ENABLED(CONFIG_THREAD_LOCAL_STORAGE, + (.stack_offset = ___xtensa_irq_bsa_t_threadptr_OFFSET,)) + }, + { + /* BR */ + .idx = 76, + .regno = 0x204, + .byte_size = 4, + .gpkt_offset = 304, + }, + { + /* SCOMPARE1 */ + .idx = 77, + .regno = 0x20c, + .byte_size = 4, + .gpkt_offset = 308, + .stack_offset = ___xtensa_irq_bsa_t_scompare1_OFFSET, + }, + { + /* PTEVADDR */ + .idx = 130, + .regno = 0x253, + .byte_size = 4, + .gpkt_offset = 684, + }, + { + /* VADDRSTATUS */ + .idx = 131, + .regno = 0x254, + .byte_size = 4, + .gpkt_offset = 688, + }, + { + /* VADDR0 */ + .idx = 132, + .regno = 0x255, + .byte_size = 4, + .gpkt_offset = 692, + }, + { + /* VADDR1 */ + .idx = 133, + .regno = 0x256, + .byte_size = 4, + .gpkt_offset = 696, + }, + { + /* RASID */ + .idx = 135, + .regno = 0x25a, + .byte_size = 4, + .gpkt_offset = 704, + }, + { + /* MEMCTL */ + .idx = 140, + .regno = 0x261, + .byte_size = 4, + .gpkt_offset = 724, + }, + { + /* ATOMCTL */ + .idx = 141, + .regno = 0x263, + .byte_size = 4, + .gpkt_offset = 728, + }, + { + /* EPC1 */ + .idx = 149, + .regno = 0x2b1, + .byte_size = 4, + .gpkt_offset = 760, + }, + { + /* EPC2 */ + .idx = 150, + .regno = 0x2b2, + .byte_size = 4, + .gpkt_offset = 764, + }, + { + /* EPC3 */ + .idx = 151, + .regno = 0x2b3, + .byte_size = 4, + .gpkt_offset = 768, + }, + { + /* EPC4 */ + .idx = 152, + .regno = 0x2b4, + .byte_size = 4, + .gpkt_offset = 772, + }, + { + /* EPC5 */ + .idx = 153, + .regno = 0x2b5, + .byte_size = 4, + .gpkt_offset = 776, + }, + { + /* DEPC */ + .idx = 154, + .regno = 0x2c0, + .byte_size = 4, + .gpkt_offset = 780, + }, + { + /* EPS2 */ + .idx = 155, + .regno = 0x2c2, + .byte_size = 4, + .gpkt_offset = 784, + }, + { + /* EPS3 */ + .idx = 156, + .regno = 0x2c3, + .byte_size = 4, + .gpkt_offset = 788, + }, + { + /* EPS4 */ + .idx = 157, + .regno = 0x2c4, + .byte_size = 4, + .gpkt_offset = 792, + }, + { + /* EPS5 */ + .idx = 158, + .regno = 0x2c5, + .byte_size = 4, + .gpkt_offset = 796, + }, + { + /* EXCSAVE1 */ + .idx = 159, + .regno = 0x2d1, + .byte_size = 4, + .gpkt_offset = 800, + }, + { + /* EXCSAVE2 */ + .idx = 160, + .regno = 0x2d2, + .byte_size = 4, + .gpkt_offset = 804, + }, + { + /* EXCSAVE3 */ + .idx = 161, + .regno = 0x2d3, + .byte_size = 4, + .gpkt_offset = 808, + }, + { + /* EXCSAVE4 */ + .idx = 162, + .regno = 0x2d4, + .byte_size = 4, + .gpkt_offset = 812, + }, + { + /* EXCSAVE5 */ + .idx = 163, + .regno = 0x2d5, + .byte_size = 4, + .gpkt_offset = 816, + }, + { + /* INTERRUPT */ + .idx = 165, + .regno = 0x2e2, + .byte_size = 4, + .gpkt_offset = 824, + }, + { + /* INTSET */ + .idx = 166, + .regno = 0x2e2, + .byte_size = 4, + .gpkt_offset = 828, + }, + { + /* INTCLEAR */ + .idx = 167, + .regno = 0x2e3, + .byte_size = 4, + .gpkt_offset = 832, + }, + { + /* INTENABLE */ + .idx = 168, + .regno = 0x2e4, + .byte_size = 4, + .gpkt_offset = 836, + }, + { + /* VECBASE */ + .idx = 169, + .regno = 0x2e7, + .byte_size = 4, + .gpkt_offset = 840, + }, + { + /* EXCCAUSE */ + .idx = 170, + .regno = 0x2e8, + .byte_size = 4, + .gpkt_offset = 844, + .stack_offset = ___xtensa_irq_bsa_t_exccause_OFFSET, + }, + { + /* DEBUGCAUSE */ + .idx = 171, + .regno = 0x2e9, + .byte_size = 4, + .gpkt_offset = 848, + }, + { + /* EXCVADDR */ + .idx = 176, + .regno = 0x2ee, + .byte_size = 4, + .gpkt_offset = 868, + }, + { + /* MISC0 */ + .idx = 179, + .regno = 0x2f4, + .byte_size = 4, + .gpkt_offset = 880, + }, + { + /* MISC1 */ + .idx = 180, + .regno = 0x2f5, + .byte_size = 4, + .gpkt_offset = 884, + }, + { + /* A0 */ + .idx = 203, + .regno = 0x00, + .byte_size = 4, + .gpkt_offset = 976, + .stack_offset = ___xtensa_irq_bsa_t_a0_OFFSET, + }, + { + /* A1 */ + .idx = 204, + .regno = 0x01, + .byte_size = 4, + .gpkt_offset = 980, + }, + { + /* A2 */ + .idx = 205, + .regno = 0x02, + .byte_size = 4, + .gpkt_offset = 984, + .stack_offset = ___xtensa_irq_bsa_t_a2_OFFSET, + }, + { + /* A3 */ + .idx = 206, + .regno = 0x03, + .byte_size = 4, + .gpkt_offset = 988, + .stack_offset = ___xtensa_irq_bsa_t_a3_OFFSET, + }, + { + /* A4 */ + .idx = 207, + .regno = 0x04, + .byte_size = 4, + .gpkt_offset = 992, + .stack_offset = -16, + }, + { + /* A5 */ + .idx = 208, + .regno = 0x05, + .byte_size = 4, + .gpkt_offset = 996, + .stack_offset = -12, + }, + { + /* A6 */ + .idx = 209, + .regno = 0x06, + .byte_size = 4, + .gpkt_offset = 1000, + .stack_offset = -8, + }, + { + /* A7 */ + .idx = 210, + .regno = 0x07, + .byte_size = 4, + .gpkt_offset = 1004, + .stack_offset = -4, + }, + { + /* A8 */ + .idx = 211, + .regno = 0x08, + .byte_size = 4, + .gpkt_offset = 1008, + .stack_offset = -32, + }, + { + /* A9 */ + .idx = 212, + .regno = 0x09, + .byte_size = 4, + .gpkt_offset = 1012, + .stack_offset = -28, + }, + { + /* A10 */ + .idx = 213, + .regno = 0x0a, + .byte_size = 4, + .gpkt_offset = 1016, + .stack_offset = -24, + }, + { + /* A11 */ + .idx = 214, + .regno = 0x0b, + .byte_size = 4, + .gpkt_offset = 1020, + .stack_offset = -20, + }, + { + /* A12 */ + .idx = 215, + .regno = 0x0c, + .byte_size = 4, + .gpkt_offset = 1024, + .stack_offset = -48, + }, + { + /* A13 */ + .idx = 216, + .regno = 0x0d, + .byte_size = 4, + .gpkt_offset = 1028, + .stack_offset = -44, + }, + { + /* A14 */ + .idx = 217, + .regno = 0x0e, + .byte_size = 4, + .gpkt_offset = 1032, + .stack_offset = -40, + }, + { + /* A15 */ + .idx = 218, + .regno = 0x0f, + .byte_size = 4, + .gpkt_offset = 1036, + .stack_offset = -36, + }, +}; + +struct gdb_ctx xtensa_gdb_ctx = { + .regs = gdb_reg_list, + .num_regs = ARRAY_SIZE(gdb_reg_list), +}; diff --git a/soc/intel/intel_adsp/common/gdbstub_backend_sram.c b/soc/intel/intel_adsp/common/gdbstub_backend_sram.c index 4a0f908fc8a7..93a9dfe5b751 100644 --- a/soc/intel/intel_adsp/common/gdbstub_backend_sram.c +++ b/soc/intel/intel_adsp/common/gdbstub_backend_sram.c @@ -21,7 +21,8 @@ #define RING_SIZE 512 #if CONFIG_SOC_INTEL_CAVS_V25 #define SOF_GDB_WINDOW_OFFSET 1024 -#elif CONFIG_SOC_INTEL_ACE15_MTPM || CONFIG_SOC_INTEL_ACE20_LNL || CONFIG_SOC_INTEL_ACE30 +#elif CONFIG_SOC_INTEL_ACE15_MTPM || CONFIG_SOC_INTEL_ACE20_LNL || CONFIG_SOC_INTEL_ACE30 || \ + CONFIG_SOC_INTEL_ACE40 /* * MTL has 2 usable slots in debug window, which is more than 1 slot on TGL, but * still slot 0 is always used for logging, slot 1 is assigned to shell From 12d68dc49659e0740d723f9a4176fa5319f5c8c3 Mon Sep 17 00:00:00 2001 From: Bill Waters Date: Mon, 12 Jan 2026 15:42:56 -0800 Subject: [PATCH 1812/3659] samples: drivers: counter: alarm: kit_psc3m5_evk Updating overlay file for the kit_psc3m5_evk board to work with device tree updates. Signed-off-by: Bill Waters --- .../alarm/boards/kit_psc3m5_evk.overlay | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/samples/drivers/counter/alarm/boards/kit_psc3m5_evk.overlay b/samples/drivers/counter/alarm/boards/kit_psc3m5_evk.overlay index ba09ff6a650f..88ad1d0f1825 100644 --- a/samples/drivers/counter/alarm/boards/kit_psc3m5_evk.overlay +++ b/samples/drivers/counter/alarm/boards/kit_psc3m5_evk.overlay @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025 Infineon Technologies AG, + * Copyright (c) 2026 Infineon Technologies AG, * or an affiliate of Infineon Technologies AG. * * SPDX-License-Identifier: Apache-2.0 @@ -7,21 +7,19 @@ #include -&tcpwm0_0 { +&tcpwm0_1 { status = "okay"; - divider-type = ; - divider-sel = <0>; - divider-val = <2399>; - counter0_0 { + counter0_1 { status = "okay"; - clocks = <&peri0_group4_16bit_0>; - clock-frequency = <20000>; + clocks = <&peri0_group5_16bit_0>; }; }; -&peri0_group4_16bit_0 { +&peri0_group5_16bit_0 { status = "okay"; - scb-block = <0>; - div-value = <109>; + resource-type = ; + resource-instance = <0>; + resource-channel = <1>; + clock-div = <2400>; }; From c1b8c14995e028707fd172673cad59b9542775ac Mon Sep 17 00:00:00 2001 From: Tom Hughes Date: Mon, 12 Jan 2026 16:28:17 -0800 Subject: [PATCH 1813/3659] tests: net: Use ARG_UNUSED instead of self assignment When building with clang it warns about self-assignment in these tests: * net.icmpv6 * net.shell * net.arp * net.tcp * net.ip_addr * net.6lo * net.icmpv4 * net.udp Example: error: explicitly assigning value of variable of type 'struct net_udp_context *' to itself [-Werror,-Wself-assign] Signed-off-by: Tom Hughes --- tests/net/6lo/src/main.c | 4 +--- tests/net/arp/src/main.c | 4 +--- tests/net/icmpv4/src/main.c | 4 +--- tests/net/icmpv6/src/main.c | 4 +--- tests/net/ip-addr/src/main.c | 4 +--- tests/net/shell/src/main.c | 4 +--- tests/net/tcp/src/main.c | 4 +--- tests/net/udp/src/main.c | 4 +--- 8 files changed, 8 insertions(+), 24 deletions(-) diff --git a/tests/net/6lo/src/main.c b/tests/net/6lo/src/main.c index e297c183bae9..9beb57736a48 100644 --- a/tests/net/6lo/src/main.c +++ b/tests/net/6lo/src/main.c @@ -253,9 +253,7 @@ struct net_6lo_data { int net_6lo_dev_init(const struct device *dev) { - struct net_6lo_context *net_6lo_context = dev->data; - - net_6lo_context = net_6lo_context; + ARG_UNUSED(dev); return 0; } diff --git a/tests/net/arp/src/main.c b/tests/net/arp/src/main.c index 3009f17f050b..8b364677eee2 100644 --- a/tests/net/arp/src/main.c +++ b/tests/net/arp/src/main.c @@ -52,9 +52,7 @@ struct net_arp_context { int net_arp_dev_init(const struct device *dev) { - struct net_arp_context *net_arp_context = dev->data; - - net_arp_context = net_arp_context; + ARG_UNUSED(dev); return 0; } diff --git a/tests/net/icmpv4/src/main.c b/tests/net/icmpv4/src/main.c index ece264a83245..f908ada59558 100644 --- a/tests/net/icmpv4/src/main.c +++ b/tests/net/icmpv4/src/main.c @@ -141,9 +141,7 @@ struct net_icmpv4_context { static int net_icmpv4_dev_init(const struct device *dev) { - struct net_icmpv4_context *net_icmpv4_context = dev->data; - - net_icmpv4_context = net_icmpv4_context; + ARG_UNUSED(dev); return 0; } diff --git a/tests/net/icmpv6/src/main.c b/tests/net/icmpv6/src/main.c index 4fad0a5b9574..d5a58e29bfb0 100644 --- a/tests/net/icmpv6/src/main.c +++ b/tests/net/icmpv6/src/main.c @@ -73,9 +73,7 @@ static struct net_icmpv6_context net_icmpv6_context_data; static int net_icmpv6_dev_init(const struct device *dev) { - struct net_icmpv6_context *net_icmpv6_context = dev->data; - - net_icmpv6_context = net_icmpv6_context; + ARG_UNUSED(dev); return 0; } diff --git a/tests/net/ip-addr/src/main.c b/tests/net/ip-addr/src/main.c index a1958a04ebce..b2b7fb136c0f 100644 --- a/tests/net/ip-addr/src/main.c +++ b/tests/net/ip-addr/src/main.c @@ -115,9 +115,7 @@ struct net_test_context { int net_test_init(const struct device *dev) { - struct net_test_context *net_test_context = dev->data; - - net_test_context = net_test_context; + ARG_UNUSED(dev); return 0; } diff --git a/tests/net/shell/src/main.c b/tests/net/shell/src/main.c index ebf1dad3b34f..5df1cfb5eb05 100644 --- a/tests/net/shell/src/main.c +++ b/tests/net/shell/src/main.c @@ -59,9 +59,7 @@ struct net_udp_context { int net_udp_dev_init(const struct device *dev) { - struct net_udp_context *net_udp_context = dev->data; - - net_udp_context = net_udp_context; + ARG_UNUSED(dev); return 0; } diff --git a/tests/net/tcp/src/main.c b/tests/net/tcp/src/main.c index c294a5ee94cd..ff7a1285ab74 100644 --- a/tests/net/tcp/src/main.c +++ b/tests/net/tcp/src/main.c @@ -164,9 +164,7 @@ struct net_tcp_context { static int net_tcp_dev_init(const struct device *dev) { - struct net_tcp_context *net_tcp_context = dev->data; - - net_tcp_context = net_tcp_context; + ARG_UNUSED(dev); return 0; } diff --git a/tests/net/udp/src/main.c b/tests/net/udp/src/main.c index b855e6fcd3d2..c4ad2596dcbf 100644 --- a/tests/net/udp/src/main.c +++ b/tests/net/udp/src/main.c @@ -61,9 +61,7 @@ struct net_udp_context { int net_udp_dev_init(const struct device *dev) { - struct net_udp_context *net_udp_context = dev->data; - - net_udp_context = net_udp_context; + ARG_UNUSED(dev); return 0; } From 32b63c63edc82324c4d10b18e79858ad8fa8e56d Mon Sep 17 00:00:00 2001 From: Tom Hughes Date: Mon, 12 Jan 2026 16:42:17 -0800 Subject: [PATCH 1814/3659] tests: bluetooth: classic: Remove self assignment When building with clang it warns about self-assignment in the bluetooth.classic.sdp_s test: tests/bluetooth/classic/sdp_s/src/sdp_server.c:258:5: error: explicitly assigning value of variable of type 'const struct shell *' to itself [-Werror,-Wself-assign] 258 | sh = sh; | ~~ ^ ~~ tests/bluetooth/classic/sdp_s/src/sdp_server.c:277:5: error: explicitly assigning value of variable of type 'const struct shell *' to itself [-Werror,-Wself-assign] 277 | sh = sh; | ~~ ^ ~~ tests/bluetooth/classic/sdp_s/src/sdp_server.c:290:5: error: explicitly assigning value of variable of type 'const struct shell *' to itself [-Werror,-Wself-assign] 290 | sh = sh; | ~~ ^ ~~ tests/bluetooth/classic/sdp_s/src/sdp_server.c:368:5: error: explicitly assigning value of variable of type 'const struct shell *' to itself [-Werror,-Wself-assign] 368 | sh = sh; | ~~ ^ ~~ 4 errors generated. The "sh" variable is used later in the functions. Signed-off-by: Tom Hughes --- tests/bluetooth/classic/sdp_s/src/sdp_server.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/tests/bluetooth/classic/sdp_s/src/sdp_server.c b/tests/bluetooth/classic/sdp_s/src/sdp_server.c index 749e37679f35..e11dc5f40bd1 100644 --- a/tests/bluetooth/classic/sdp_s/src/sdp_server.c +++ b/tests/bluetooth/classic/sdp_s/src/sdp_server.c @@ -255,8 +255,6 @@ static int cmd_register_sdp_all(const struct shell *sh, size_t argc, char *argv[ { int err; - sh = sh; - for (size_t i = 0; i < ARRAY_SIZE(spp_rec); i++) { if (!sdp_rec_reg[i]) { err = bt_sdp_register_service(&spp_rec[i]); @@ -274,8 +272,6 @@ static int cmd_register_sdp_large(const struct shell *sh, size_t argc, char *arg { int err; - sh = sh; - err = bt_sdp_register_service(&spp_rec_large); if (err) { shell_error(sh, "Register SDP large record failed (err %d)", err); @@ -287,8 +283,6 @@ static int cmd_register_sdp_large_valid(const struct shell *sh, size_t argc, cha { int err; - sh = sh; - err = bt_sdp_register_service(&spp_rec_large_valid); if (err) { shell_error(sh, "Register SDP large record failed (err %d)", err); @@ -365,8 +359,6 @@ static int cmd_register_sdp_uuid128(const struct shell *sh, size_t argc, char *a { int err; - sh = sh; - err = bt_sdp_register_service(&spp_rec_uuid128); if (err) { shell_error(sh, "Register SDP uuid128 failed (err %d)", err); From a3f95c886a11b480071f50ff901a9b2aa3e23804 Mon Sep 17 00:00:00 2001 From: Zhaoxiang Jin Date: Tue, 13 Jan 2026 14:46:32 +0800 Subject: [PATCH 1815/3659] drivers: ipm: ipm_mbox: fix qualifier warning in callback mbox_msg::data is a const pointer, but ipm_callback_t expects a volatile void * payload. Passing the mailbox payload through the IPM callback was triggering compiler warnings about discarded qualifiers. Convert the mailbox payload pointer to the IPM callback payload type via a uintptr_t round-trip to avoid -Wdiscarded-qualifiers or -Wcast-qual noise without changing the runtime behavior. fix:https://github.com/zephyrproject-rtos/zephyr/issues/102057 Signed-off-by: Zhaoxiang Jin --- drivers/ipm/ipm_mbox.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/ipm/ipm_mbox.c b/drivers/ipm/ipm_mbox.c index cdd70bb6b116..03a835613516 100644 --- a/drivers/ipm/ipm_mbox.c +++ b/drivers/ipm/ipm_mbox.c @@ -48,7 +48,7 @@ static void ipm_mbox_callback(const struct device *mboxdev, { const struct device *ipmdev = user_data; struct ipm_mbox_data *ipm_mbox_data = ipmdev->data; - void *payload = NULL; + volatile void *payload = NULL; if (!ipm_mbox_data || !ipm_mbox_data->callback) { return; @@ -56,7 +56,7 @@ static void ipm_mbox_callback(const struct device *mboxdev, /* Only use the payload if the mailbox provides a non-empty buffer */ if (data && data->data && data->size > 0) { - payload = data->data; + payload = (volatile void *)(uintptr_t)data->data; } ipm_mbox_data->callback(ipmdev, From 203c92980dea5242f5ae3b55bb43cd0a4aa97eaf Mon Sep 17 00:00:00 2001 From: Qiang Zhao Date: Tue, 13 Jan 2026 14:00:12 +0530 Subject: [PATCH 1816/3659] net: shell: fix qbv command documentation and help text Fix inconsistencies in the QBV (IEEE 802.1Qbv Time-Aware Shaper) shell command documentation and help messages: 1. Add missing "net qbv" command documentation to net_shell.rst 2. Correct command examples in help text - add missing "net" prefix to "qbv set_gc" commands 3. Fix command usage descriptions for set_config and set_gc to match actual command names This ensures users see correct command syntax in both documentation and interactive help. Signed-off-by: Qiang Zhao --- doc/connectivity/networking/api/net_shell.rst | 2 ++ subsys/net/lib/shell/qbv_shell.c | 8 ++++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/doc/connectivity/networking/api/net_shell.rst b/doc/connectivity/networking/api/net_shell.rst index a6ab2ccd4821..0f3518fdc366 100644 --- a/doc/connectivity/networking/api/net_shell.rst +++ b/doc/connectivity/networking/api/net_shell.rst @@ -38,6 +38,8 @@ The following net-shell commands are implemented: "net nbr", "Print neighbor information. Only available if :kconfig:option:`CONFIG_NET_IPV6` is set." "net ping", "Ping a network host." + "net qbv", "Show and configure IEEE 802.1Qbv Time-Aware Shaper (TAS) information. + Only available if :kconfig:option:`CONFIG_NET_QBV` is set." "net route", "Show IPv6 network routes. Only available if :kconfig:option:`CONFIG_NET_ROUTE` is set." "net sockets", "Show network socket information and statistics. Only available if diff --git a/subsys/net/lib/shell/qbv_shell.c b/subsys/net/lib/shell/qbv_shell.c index 7f74b50e5398..69d600c9c97e 100644 --- a/subsys/net/lib/shell/qbv_shell.c +++ b/subsys/net/lib/shell/qbv_shell.c @@ -52,8 +52,8 @@ static int cmd_net_qbv(const struct shell *sh, size_t argc, char **argv) shell_print(sh, "For example:"); shell_print(sh, " 1. net qbv enable 1 on"); shell_print(sh, " 2. net qbv set_config 1 200 0 0 10000000 0 2"); - shell_print(sh, " 3. qbv set_gc 1 0 0x1 5000000"); - shell_print(sh, " 4. qbv set_gc 1 0 0x2 5000000"); + shell_print(sh, " 3. net qbv set_gc 1 0 0x1 5000000"); + shell_print(sh, " 4. net qbv set_gc 1 0 0x2 5000000"); #else shell_print(sh, "Set %s to enable %s support.\n", "CONFIG_NET_QBV", "qbv"); shell_print(sh, "Set %s to enable %s support.\n", "CONFIG_NET_L2_ETHERNET_MGMT", @@ -321,10 +321,10 @@ SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_qbv, "Enable: enable ", cmd_qbv_enable, 3, 0), SHELL_CMD_ARG(set_config, NULL, - "Set config: set ", + "Set config: set_config ", cmd_qbv_set_config, 8, 0), SHELL_CMD_ARG(set_gc, NULL, - "Set gate control: set ", + "Set gate control: set_gc ", cmd_qbv_set_gc, 5, 0), SHELL_CMD_ARG(get_info, NULL, "Get info: get_info ", From 16c2444d7afb07ca2317ea2391133eada6c0ba0d Mon Sep 17 00:00:00 2001 From: Jordan Yates Date: Tue, 13 Jan 2026 19:24:15 +1000 Subject: [PATCH 1817/3659] net: nsos_sockets: update heap size check The final system heap size is now stored in `K_HEAP_MEM_POOL_SIZE`, not `CONFIG_HEAP_MEM_POOL_SIZE`. Signed-off-by: Jordan Yates --- drivers/net/nsos_sockets.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/nsos_sockets.c b/drivers/net/nsos_sockets.c index ad77fe22349a..b822ea05b2d2 100644 --- a/drivers/net/nsos_sockets.c +++ b/drivers/net/nsos_sockets.c @@ -36,7 +36,7 @@ LOG_MODULE_REGISTER(nsos_sockets); #include "nsi_host_trampolines.h" -BUILD_ASSERT(CONFIG_HEAP_MEM_POOL_SIZE > 0); +BUILD_ASSERT(K_HEAP_MEM_POOL_SIZE > 0); #define NSOS_IRQ_FLAGS (0) #define NSOS_IRQ_PRIORITY (2) From 3feb7ca4256028b95eeff95f73b36ec5acbc8612 Mon Sep 17 00:00:00 2001 From: Jordan Yates Date: Tue, 13 Jan 2026 19:25:00 +1000 Subject: [PATCH 1818/3659] net: heap default for NSOS DNS results DNS queries using native posix can return multiple results. Add a relatively large default to pre-empt failures due to the query being too successful. Extra RAM usage can be ignored since NSOS sockets can only exist on native posix, which has essentially infinite RAM. Signed-off-by: Jordan Yates --- drivers/net/Kconfig | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index c9672be5f77d..59c4f188c1ea 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -282,6 +282,13 @@ config NET_NATIVE_OFFLOADED_SOCKETS_CONNECTIVITY_SIM_AUTO_CONNECT network interface has been brought up. This option sets the default value, the option has a corresponding flag that can be set at run time by calling conn_mgr_if_set_flag(). +config HEAP_MEM_POOL_ADD_SIZE_NET_NATIVE_SOCKETS_GETADDRINFO + # Defaults to heap memory required for 8 zsock_addrinfo_wrap structures. + # Single queries have been observed to return 6 results. + # Excessive memory consumption is not a concern for native sockets. + int + default 2304 + endif # NET_NATIVE_OFFLOADED_SOCKETS endif # NET_DRIVERS From 7e3c5ab2bb2a9f4bf1b0afd43c872e6f19461777 Mon Sep 17 00:00:00 2001 From: Jordan Yates Date: Tue, 13 Jan 2026 19:27:15 +1000 Subject: [PATCH 1819/3659] samples: net: nsos: remove `CONFIG_HEAP_MEM_POOL_SIZE` Remove the explicit setting of `CONFIG_HEAP_MEM_POOL_SIZE` from NSOS samples, letting the build system construct the heap size from Kconfig options. Signed-off-by: Jordan Yates --- samples/net/sockets/echo_server/overlay-nsos.conf | 1 - samples/net/sockets/http_get/overlay-nsos.conf | 1 - samples/net/sockets/sntp_client/overlay-nsos.conf | 1 - 3 files changed, 3 deletions(-) diff --git a/samples/net/sockets/echo_server/overlay-nsos.conf b/samples/net/sockets/echo_server/overlay-nsos.conf index b6e0ca5a02ba..85bc57f1c493 100644 --- a/samples/net/sockets/echo_server/overlay-nsos.conf +++ b/samples/net/sockets/echo_server/overlay-nsos.conf @@ -3,7 +3,6 @@ CONFIG_NET_DRIVERS=y CONFIG_NET_SOCKETS=y CONFIG_NET_SOCKETS_OFFLOAD=y CONFIG_NET_NATIVE_OFFLOADED_SOCKETS=y -CONFIG_HEAP_MEM_POOL_SIZE=1024 # IPv6 DAD requires lower level network interface access, below exposed socket-level access CONFIG_NET_IPV6_DAD=n diff --git a/samples/net/sockets/http_get/overlay-nsos.conf b/samples/net/sockets/http_get/overlay-nsos.conf index dfe7324e0f99..a12e6e4d61ad 100644 --- a/samples/net/sockets/http_get/overlay-nsos.conf +++ b/samples/net/sockets/http_get/overlay-nsos.conf @@ -3,4 +3,3 @@ CONFIG_NET_DRIVERS=y CONFIG_NET_SOCKETS=y CONFIG_NET_SOCKETS_OFFLOAD=y CONFIG_NET_NATIVE_OFFLOADED_SOCKETS=y -CONFIG_HEAP_MEM_POOL_SIZE=1024 diff --git a/samples/net/sockets/sntp_client/overlay-nsos.conf b/samples/net/sockets/sntp_client/overlay-nsos.conf index dec4079422e8..4cb8f3a014ed 100644 --- a/samples/net/sockets/sntp_client/overlay-nsos.conf +++ b/samples/net/sockets/sntp_client/overlay-nsos.conf @@ -5,7 +5,6 @@ CONFIG_NET_DRIVERS=y CONFIG_NET_SOCKETS=y CONFIG_NET_SOCKETS_OFFLOAD=y CONFIG_NET_NATIVE_OFFLOADED_SOCKETS=y -CONFIG_HEAP_MEM_POOL_SIZE=4096 # IPv6 DAD requires lower level network interface access, below exposed socket-level access CONFIG_NET_IPV6_DAD=n From 8c729eec2f48b99a2db4d9a01031bc53b9abbd80 Mon Sep 17 00:00:00 2001 From: Guillaume Gautier Date: Mon, 3 Nov 2025 14:10:28 +0100 Subject: [PATCH 1820/3659] dts: bindings: rng: stm32: add noise source control property Some STM32 series need to configure the RNG source noise control register for NIST SP800-90B compliance. Signed-off-by: Guillaume Gautier --- dts/bindings/rng/st,stm32-rng.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/dts/bindings/rng/st,stm32-rng.yaml b/dts/bindings/rng/st,stm32-rng.yaml index c0e6d5e2ec3f..477c06d37d46 100644 --- a/dts/bindings/rng/st,stm32-rng.yaml +++ b/dts/bindings/rng/st,stm32-rng.yaml @@ -45,3 +45,9 @@ properties: description: | Heath Test Configuration, necessary to have proper RNG behavior, when available. + + noise-source-control: + type: int + description: | + This property is used to configure the RNG_NSCR register for the NIST + certification. From 40df5225e2423186125f0c6e9ebe72290af131d3 Mon Sep 17 00:00:00 2001 From: Guillaume Gautier Date: Mon, 3 Nov 2025 14:13:11 +0100 Subject: [PATCH 1821/3659] drivers: entropy: stm32: remove STM32L4 specific code STM32L4 was using different LL functions from the other series. With the latest HAL update, the usual functions are now defined, so the L4-specific code can now be removed. Signed-off-by: Guillaume Gautier --- drivers/entropy/entropy_stm32.c | 23 +++++------------------ 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/drivers/entropy/entropy_stm32.c b/drivers/entropy/entropy_stm32.c index e40105c12c47..dae71e28e70d 100644 --- a/drivers/entropy/entropy_stm32.c +++ b/drivers/entropy/entropy_stm32.c @@ -247,22 +247,18 @@ static void configure_rng(void) #if DT_INST_NODE_HAS_PROP(0, health_test_config) #if DT_INST_NODE_HAS_PROP(0, health_test_magic) + /* On certain series, a magic value must be written first as + * health configuration before the actual configuration value. + */ LL_RNG_SetHealthConfig(rng, DT_INST_PROP(0, health_test_magic)); #endif /* health_test_magic */ LL_RNG_SetHealthConfig(rng, desired_htcr); #endif /* health_test_config */ -#if defined(CONFIG_SOC_SERIES_STM32L4X) - LL_RNG_ResetConditioningResetBit(rng); - /* Wait for conditioning reset process to be completed */ - while (LL_RNG_IsResetConditioningBitSet(rng) == 1) { - } -#else LL_RNG_DisableCondReset(rng); /* Wait for conditioning reset process to be completed */ while (LL_RNG_IsEnabledCondReset(rng) == 1) { } -#endif /* CONFIG_SOC_SERIES_STM32L4X */ } #endif /* STM32_CONDRST_SUPPORT */ @@ -312,23 +308,14 @@ static int recover_seed_error(RNG_TypeDef *rng) { uint32_t count_timeout = 0; -#if defined(CONFIG_SOC_SERIES_STM32L4X) - LL_RNG_SetConditioningResetBit(rng); - LL_RNG_ResetConditioningResetBit(rng); -#else - LL_RNG_EnableCondReset(rng); - LL_RNG_DisableCondReset(rng); -#endif /* CONFIG_SOC_SERIES_STM32L4X */ + LL_RNG_EnableCondReset(rng); + LL_RNG_DisableCondReset(rng); /* When reset process is done cond reset bit is read 0 * This typically takes: 2 AHB clock cycles + 2 RNG clock cycles. */ -#if defined(CONFIG_SOC_SERIES_STM32L4X) - while (LL_RNG_IsResetConditioningBitSet(rng) || -#else while (LL_RNG_IsEnabledCondReset(rng) || -#endif /* CONFIG_SOC_SERIES_STM32L4X */ ll_rng_is_active_seis(rng) || ll_rng_is_active_secs(rng)) { count_timeout++; From ffa1c2fad47863b7c1fa35ec8c24a8e3971b20e8 Mon Sep 17 00:00:00 2001 From: Guillaume Gautier Date: Thu, 13 Nov 2025 16:23:32 +0100 Subject: [PATCH 1822/3659] drivers: entropy: stm32: add noise source control support Set the content of the noise source control register if the corresponding property is set in device tree. Signed-off-by: Guillaume Gautier --- drivers/entropy/entropy_stm32.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/entropy/entropy_stm32.c b/drivers/entropy/entropy_stm32.c index dae71e28e70d..01fb26bf6e13 100644 --- a/drivers/entropy/entropy_stm32.c +++ b/drivers/entropy/entropy_stm32.c @@ -218,8 +218,10 @@ static void configure_rng(void) #ifdef STM32_CONDRST_SUPPORT uint32_t desired_nist_cfg = DT_INST_PROP_OR(0, nist_config, 0U); uint32_t desired_htcr = DT_INST_PROP_OR(0, health_test_config, 0U); + uint32_t desired_nscr = DT_INST_PROP_OR(0, noise_source_control, 0U); uint32_t cur_nist_cfg = 0U; uint32_t cur_htcr = 0U; + uint32_t cur_nscr = 0U; #if DT_INST_NODE_HAS_PROP(0, nist_config) /* @@ -242,7 +244,12 @@ static void configure_rng(void) cur_htcr = LL_RNG_GetHealthConfig(rng); #endif /* health_test_config */ - if (cur_nist_cfg != desired_nist_cfg || cur_htcr != desired_htcr) { +#if DT_INST_NODE_HAS_PROP(0, noise_source_control) + cur_nscr = LL_RNG_GetNoiseConfig(rng); +#endif /* noise_source_control */ + + if (cur_nist_cfg != desired_nist_cfg || cur_htcr != desired_htcr || + cur_nscr != desired_nscr) { stm32_reg_modify_bits(&rng->CR, cur_nist_cfg, desired_nist_cfg | RNG_CR_CONDRST); #if DT_INST_NODE_HAS_PROP(0, health_test_config) @@ -255,6 +262,10 @@ static void configure_rng(void) LL_RNG_SetHealthConfig(rng, desired_htcr); #endif /* health_test_config */ +#if DT_INST_NODE_HAS_PROP(0, noise_source_control) + LL_RNG_SetNoiseConfig(rng, DT_INST_PROP(0, noise_source_control)); +#endif /* noise_source_control */ + LL_RNG_DisableCondReset(rng); /* Wait for conditioning reset process to be completed */ while (LL_RNG_IsEnabledCondReset(rng) == 1) { From 5688afaf0d44f6c300d1ae64b7b91e44b135094f Mon Sep 17 00:00:00 2001 From: Guillaume Gautier Date: Mon, 3 Nov 2025 14:23:18 +0100 Subject: [PATCH 1823/3659] dts: arm: st: fix rng nist compliant configs In order to comply to NIST SP800-90B, the STM32 RNG should set its registers as documented in Application Note AN4230 (Rev12, Table 3) [1]. To that effect, some values have been modified to match the table, and some have been added. For STM32H7R/S and WBA, configure the RNG as per configuration C of the Reference Manual since the NSCR register is not available yet (internal issues 221082 and 221083). [1]: https://www.st.com/resource/en/application_note/dm00073853.pdf Signed-off-by: Guillaume Gautier --- dts/arm/st/h5/stm32h562.dtsi | 6 ++++++ dts/arm/st/h7/stm32h723.dtsi | 1 + dts/arm/st/h7rs/stm32h7rs.dtsi | 2 ++ dts/arm/st/l4/stm32l4p5.dtsi | 6 ++++++ dts/arm/st/l4/stm32l4r5.dtsi | 7 +++++++ dts/arm/st/n6/stm32n6.dtsi | 2 ++ dts/arm/st/u0/stm32u0.dtsi | 2 ++ dts/arm/st/u3/stm32u3.dtsi | 2 ++ dts/arm/st/u5/stm32u5.dtsi | 2 -- dts/arm/st/u5/stm32u535.dtsi | 6 ++++++ dts/arm/st/u5/stm32u575.dtsi | 6 ++++++ dts/arm/st/u5/stm32u595.dtsi | 6 ++++++ dts/arm/st/u5/stm32u5f9.dtsi | 6 ++++++ dts/arm/st/wba/stm32wba.dtsi | 2 +- dts/arm/st/wba/stm32wba65.dtsi | 4 ++++ dts/arm/st/wl/stm32wl.dtsi | 1 + 16 files changed, 58 insertions(+), 3 deletions(-) diff --git a/dts/arm/st/h5/stm32h562.dtsi b/dts/arm/st/h5/stm32h562.dtsi index 5f2b20585d90..00c912053229 100644 --- a/dts/arm/st/h5/stm32h562.dtsi +++ b/dts/arm/st/h5/stm32h562.dtsi @@ -525,6 +525,12 @@ status = "disabled"; }; + rng: rng@420c0800 { + nist-config = <0xf00e00>; + health-test-config = <0x6a91>; + noise-source-control = <0x3af66>; + }; + sdmmc1: sdmmc@46008000 { compatible = "st,stm32-sdmmc"; reg = <0x46008000 0x400>; diff --git a/dts/arm/st/h7/stm32h723.dtsi b/dts/arm/st/h7/stm32h723.dtsi index 6703f035983e..4f4255c9a81f 100644 --- a/dts/arm/st/h7/stm32h723.dtsi +++ b/dts/arm/st/h7/stm32h723.dtsi @@ -62,6 +62,7 @@ }; rng: rng@48021800 { + nist-config = <0xf00d00>; health-test-magic = <0x17590abc>; health-test-config = <0xaa74>; }; diff --git a/dts/arm/st/h7rs/stm32h7rs.dtsi b/dts/arm/st/h7rs/stm32h7rs.dtsi index 9be44419bb92..ffbd2d0f9ff7 100644 --- a/dts/arm/st/h7rs/stm32h7rs.dtsi +++ b/dts/arm/st/h7rs/stm32h7rs.dtsi @@ -917,6 +917,8 @@ reg = <0x48020000 0x400>; clocks = <&rcc STM32_CLOCK(AHB3, 0)>; interrupts = <37 0>; + nist-config = <0xf00d00>; + health-test-config = <0xaac7>; status = "disabled"; }; diff --git a/dts/arm/st/l4/stm32l4p5.dtsi b/dts/arm/st/l4/stm32l4p5.dtsi index 5f93f9d9c3b7..09f7ca96ecff 100644 --- a/dts/arm/st/l4/stm32l4p5.dtsi +++ b/dts/arm/st/l4/stm32l4p5.dtsi @@ -454,6 +454,12 @@ #size-cells = <0>; status = "disabled"; }; + + rng: rng@50060800 { + nist-config = <0xf00d00>; + health-test-magic = <0x17590abc>; + health-test-config = <0xaa74>; + }; }; otgfs_phy: otgfs_phy { diff --git a/dts/arm/st/l4/stm32l4r5.dtsi b/dts/arm/st/l4/stm32l4r5.dtsi index edb1be954e23..4f9a0cb4dfa3 100644 --- a/dts/arm/st/l4/stm32l4r5.dtsi +++ b/dts/arm/st/l4/stm32l4r5.dtsi @@ -41,5 +41,12 @@ STM32_DMA_MEM_INC | STM32_DMA_PERIPH_8BITS | STM32_DMA_MEM_32BITS | STM32_DMA_PRIORITY_HIGH) STM32_DMA_FIFO_1_4>; }; + + rng: rng@50060800 { + /* L4R/S RNG differs from L4P/Q; these properties are not available */ + /delete-property/ nist-config; + /delete-property/ health-test-magic; + /delete-property/ health-test-config; + }; }; }; diff --git a/dts/arm/st/n6/stm32n6.dtsi b/dts/arm/st/n6/stm32n6.dtsi index a35feffa0e93..fb0fc21847bb 100644 --- a/dts/arm/st/n6/stm32n6.dtsi +++ b/dts/arm/st/n6/stm32n6.dtsi @@ -1288,6 +1288,8 @@ reg = <0x54020000 0x400>; interrupts = <40 0>; clocks = <&rcc STM32_CLOCK(AHB3, 0)>; + nist-config = <0xf00d00>; + health-test-config = <0xaac7>; status = "disabled"; }; diff --git a/dts/arm/st/u0/stm32u0.dtsi b/dts/arm/st/u0/stm32u0.dtsi index 35c9a00d4830..a15b69e686a5 100644 --- a/dts/arm/st/u0/stm32u0.dtsi +++ b/dts/arm/st/u0/stm32u0.dtsi @@ -402,6 +402,8 @@ clocks = <&rcc STM32_CLOCK(AHB1, 18)>, <&rcc STM32_SRC_CK48 NO_SEL>; interrupts = <31 0>; + nist-config = <0xf00d00>; + health-test-config = <0xaac7>; status = "disabled"; }; diff --git a/dts/arm/st/u3/stm32u3.dtsi b/dts/arm/st/u3/stm32u3.dtsi index b2887ab15894..662a7936e919 100644 --- a/dts/arm/st/u3/stm32u3.dtsi +++ b/dts/arm/st/u3/stm32u3.dtsi @@ -335,6 +335,8 @@ reg = <0x420c0800 0x400>; clocks = <&rcc STM32_CLOCK(AHB2, 18)>; interrupts = <94 0>; + nist-config = <0xf00d00>; + health-test-config = <0xaac7>; status = "disabled"; }; diff --git a/dts/arm/st/u5/stm32u5.dtsi b/dts/arm/st/u5/stm32u5.dtsi index ed57e389bc34..b55354d520dc 100644 --- a/dts/arm/st/u5/stm32u5.dtsi +++ b/dts/arm/st/u5/stm32u5.dtsi @@ -816,8 +816,6 @@ reg = <0x420c0800 0x400>; clocks = <&rcc STM32_CLOCK(AHB2, 18)>; interrupts = <94 0>; - nist-config = <0xf60d00>; - health-test-config = <0x9aae>; status = "disabled"; }; diff --git a/dts/arm/st/u5/stm32u535.dtsi b/dts/arm/st/u5/stm32u535.dtsi index b2ae9ebbf430..f6f2d1d270ab 100644 --- a/dts/arm/st/u5/stm32u535.dtsi +++ b/dts/arm/st/u5/stm32u535.dtsi @@ -19,5 +19,11 @@ soc { compatible = "st,stm32u535", "st,stm32u5", "simple-bus"; + + rng: rng@420c0800 { + nist-config = <0xf10f00>; + health-test-config = <0x76b3>; + noise-source-control = <0x24c2>; + }; }; }; diff --git a/dts/arm/st/u5/stm32u575.dtsi b/dts/arm/st/u5/stm32u575.dtsi index 1db3c8325e10..901ac9fe31af 100644 --- a/dts/arm/st/u5/stm32u575.dtsi +++ b/dts/arm/st/u5/stm32u575.dtsi @@ -21,5 +21,11 @@ soc { compatible = "st,stm32u575", "st,stm32u5", "simple-bus"; + + rng: rng@420c0800 { + nist-config = <0xf00d00>; + health-test-config = <0xa2b0>; + noise-source-control = <0x17cbb>; + }; }; }; diff --git a/dts/arm/st/u5/stm32u595.dtsi b/dts/arm/st/u5/stm32u595.dtsi index fb496bc156c2..7225d5599e49 100644 --- a/dts/arm/st/u5/stm32u595.dtsi +++ b/dts/arm/st/u5/stm32u595.dtsi @@ -114,6 +114,12 @@ st,adc-has-differential-support; status = "disabled"; }; + + rng: rng@420c0800 { + nist-config = <0xf10f00>; + health-test-config = <0x92f3>; + noise-source-control = <0x1609>; + }; }; smbus5: smbus5 { diff --git a/dts/arm/st/u5/stm32u5f9.dtsi b/dts/arm/st/u5/stm32u5f9.dtsi index 786fd9a9d4a8..38cbf9e23926 100644 --- a/dts/arm/st/u5/stm32u5f9.dtsi +++ b/dts/arm/st/u5/stm32u5f9.dtsi @@ -9,6 +9,12 @@ / { soc { compatible = "st,stm32u5f9", "st,stm32u5", "simple-bus"; + + rng: rng@420c0800 { + nist-config = <0xf10f00>; + health-test-config = <0xa715>; + noise-source-control = <0x9049>; + }; }; }; diff --git a/dts/arm/st/wba/stm32wba.dtsi b/dts/arm/st/wba/stm32wba.dtsi index 44473ebb271f..e6ec7f722efd 100644 --- a/dts/arm/st/wba/stm32wba.dtsi +++ b/dts/arm/st/wba/stm32wba.dtsi @@ -540,7 +540,7 @@ interrupts = <59 0>; clocks = <&rcc STM32_CLOCK(AHB2, 18)>, <&rcc STM32_SRC_HSI16 RNG_SEL(2)>; - nist-config = <0xf00d>; + nist-config = <0xf00d00>; health-test-config = <0xaac7>; status = "disabled"; }; diff --git a/dts/arm/st/wba/stm32wba65.dtsi b/dts/arm/st/wba/stm32wba65.dtsi index 860851f0f3f2..a5b40e972d36 100644 --- a/dts/arm/st/wba/stm32wba65.dtsi +++ b/dts/arm/st/wba/stm32wba65.dtsi @@ -69,6 +69,10 @@ status = "disabled"; }; + rng: rng@420c0800 { + nist-config = <0x8200f00>; + }; + spi2: spi@40003800 { compatible = "st,stm32h7-spi", "st,stm32-spi-fifo", "st,stm32-spi"; #address-cells = <1>; diff --git a/dts/arm/st/wl/stm32wl.dtsi b/dts/arm/st/wl/stm32wl.dtsi index 75b95f30c918..22a440a6d0cb 100644 --- a/dts/arm/st/wl/stm32wl.dtsi +++ b/dts/arm/st/wl/stm32wl.dtsi @@ -486,6 +486,7 @@ reg = <0x58001000 0x400>; interrupts = <52 0>; clocks = <&rcc STM32_CLOCK(AHB3, 18)>; + nist-config = <0xf00d00>; health-test-magic = <0x17590abc>; health-test-config = <0xaa74>; status = "disabled"; From b43382c68590f9b54a243367c3b2ebb612561925 Mon Sep 17 00:00:00 2001 From: Tarang Patel Date: Wed, 12 Nov 2025 11:47:15 +0000 Subject: [PATCH 1824/3659] boards: u-blox: ubx_evk_iris_w1_rw612: fix flash config correct flash_config.c file for different flash varient fix spelling error across board files update boards/deprecated.cmake to help older release support Signed-off-by: Tarang Patel --- boards/deprecated.cmake | 3 +++ boards/u-blox/ubx_evk_iris_w1/CMakeLists.txt | 4 +-- boards/u-blox/ubx_evk_iris_w1/board.yml | 4 +-- boards/u-blox/ubx_evk_iris_w1/doc/index.rst | 4 +-- ..._flash_config.c => fidelix_flash_config.c} | 2 ++ .../ubx_evk_iris_w1/macronix_flash_config.c | 25 ++++++------------- boards/u-blox/ubx_evk_iris_w1/revision.cmake | 8 +++--- ...config => ubx_evk_iris_w1_rw612_defconfig} | 0 .../ubx_evk_iris_w1_rw612_macronix_defconfig | 12 --------- 9 files changed, 23 insertions(+), 39 deletions(-) rename boards/u-blox/ubx_evk_iris_w1/{fidelex_flash_config.c => fidelix_flash_config.c} (98%) rename boards/u-blox/ubx_evk_iris_w1/{ubx_evk_iris_w1_rw612_fidelex_defconfig => ubx_evk_iris_w1_rw612_defconfig} (100%) delete mode 100644 boards/u-blox/ubx_evk_iris_w1/ubx_evk_iris_w1_rw612_macronix_defconfig diff --git a/boards/deprecated.cmake b/boards/deprecated.cmake index 270e0acf63f8..8a884009de24 100644 --- a/boards/deprecated.cmake +++ b/boards/deprecated.cmake @@ -64,3 +64,6 @@ set(esp32s3_devkitm/esp32s3/procpu_DEPRECATED set(esp32s3_devkitm/esp32s3/appcpu_DEPRECATED esp32s3_devkitc/esp32s3/appcpu ) +set(ubx_evk_iris_w1_fidelex/rw612_DEPRECATED + ubx_evk_iris_w1@fidelix/rw612 +) diff --git a/boards/u-blox/ubx_evk_iris_w1/CMakeLists.txt b/boards/u-blox/ubx_evk_iris_w1/CMakeLists.txt index 9e592dca1174..027825b98536 100644 --- a/boards/u-blox/ubx_evk_iris_w1/CMakeLists.txt +++ b/boards/u-blox/ubx_evk_iris_w1/CMakeLists.txt @@ -11,8 +11,8 @@ if(CONFIG_NXP_RW6XX_BOOT_HEADER) if(BOARD_REVISION STREQUAL "macronix") zephyr_library_sources(macronix_flash_config.c) - elseif(BOARD_REVISION STREQUAL "fidelex") - zephyr_library_sources(fidelex_flash_config.c) + elseif(BOARD_REVISION STREQUAL "fidelix") + zephyr_library_sources(fidelix_flash_config.c) else() message(FATAL_ERROR "Unsupported board revision: ${BOARD_REVISION}") endif() diff --git a/boards/u-blox/ubx_evk_iris_w1/board.yml b/boards/u-blox/ubx_evk_iris_w1/board.yml index 2b3b54823f5d..a09e18c0698c 100644 --- a/boards/u-blox/ubx_evk_iris_w1/board.yml +++ b/boards/u-blox/ubx_evk_iris_w1/board.yml @@ -4,9 +4,9 @@ board: vendor: u-blox revision: format: custom - default: fidelex + default: fidelix revisions: - name: "macronix" - - name: "fidelex" + - name: "fidelix" socs: - name: rw612 diff --git a/boards/u-blox/ubx_evk_iris_w1/doc/index.rst b/boards/u-blox/ubx_evk_iris_w1/doc/index.rst index 0b56718451d9..b6cb9e2205c6 100644 --- a/boards/u-blox/ubx_evk_iris_w1/doc/index.rst +++ b/boards/u-blox/ubx_evk_iris_w1/doc/index.rst @@ -39,14 +39,14 @@ Flash Memory Configuration The IRIS-W1 board uses different flash vendors depending on revision: - ``@macronix``: Module build up to 2023 week 45 -- ``@fidelex``: Module build 2023 week 46 (2346) onward +- ``@fidelix``: Module build 2023 week 46 (2346) onward To build for a specific flash version: .. code-block:: bash west build -b ubx_evk_iris_w1@macronix - west build -b ubx_evk_iris_w1@fidelex + west build -b ubx_evk_iris_w1@fidelix Supported Features ================== diff --git a/boards/u-blox/ubx_evk_iris_w1/fidelex_flash_config.c b/boards/u-blox/ubx_evk_iris_w1/fidelix_flash_config.c similarity index 98% rename from boards/u-blox/ubx_evk_iris_w1/fidelex_flash_config.c rename to boards/u-blox/ubx_evk_iris_w1/fidelix_flash_config.c index c605e295bac0..c2642cebe2c4 100644 --- a/boards/u-blox/ubx_evk_iris_w1/fidelex_flash_config.c +++ b/boards/u-blox/ubx_evk_iris_w1/fidelix_flash_config.c @@ -1,6 +1,8 @@ /* * Copyright (c) 2021-2024 NXP * + * Copyright (c) 2025 u-blox AG + * * SPDX-License-Identifier: Apache-2.0 */ diff --git a/boards/u-blox/ubx_evk_iris_w1/macronix_flash_config.c b/boards/u-blox/ubx_evk_iris_w1/macronix_flash_config.c index 44e11b5e2c16..4074fc97027e 100644 --- a/boards/u-blox/ubx_evk_iris_w1/macronix_flash_config.c +++ b/boards/u-blox/ubx_evk_iris_w1/macronix_flash_config.c @@ -1,6 +1,7 @@ /* - * Copyright 2021-2024 NXP - * All rights reserved. + * Copyright (c) 2021-2024 NXP + * + * Copyright (c) 2025 u-blox AG * * SPDX-License-Identifier: Apache-2.0 */ @@ -20,7 +21,7 @@ const fc_flexspi_nor_config_t flexspi_config = { .seqNum = 1, .seqId = 2, }, - .deviceModeArg = 0x0200, + .deviceModeArg = 0xC740, .configCmdEnable = 0, .deviceType = 0x1, .sflashPadType = kSerialFlash_4Pads, @@ -37,14 +38,9 @@ const fc_flexspi_nor_config_t flexspi_config = { FC_FLEXSPI_4PAD, 0x18), [1] = FC_FLEXSPI_LUT_SEQ( FC_MODE8_SDR, - FC_FLEXSPI_4PAD, 0x00, + FC_FLEXSPI_4PAD, 0x0A, FC_DUMMY_SDR, FC_FLEXSPI_4PAD, 0x04), - [2] = FC_FLEXSPI_LUT_SEQ( - FC_READ_SDR, - FC_FLEXSPI_4PAD, 0x04, - FC_STOP_EXE, - FC_FLEXSPI_1PAD, 0x00), /* Read Status */ [4 * 1 + 0] = FC_FLEXSPI_LUT_SEQ( @@ -62,14 +58,6 @@ const fc_flexspi_nor_config_t flexspi_config = { FC_FLEXSPI_1PAD, 0x02), - /* Write Enable */ - [4 * 3 + 0] = FC_FLEXSPI_LUT_SEQ( - FC_CMD_SDR, - FC_FLEXSPI_1PAD, - 0x06, FC_STOP_EXE, - FC_FLEXSPI_1PAD, - 0x00), - /* Sector erase */ [4 * 5 + 0] = FC_FLEXSPI_LUT_SEQ( FC_CMD_SDR, @@ -93,6 +81,7 @@ const fc_flexspi_nor_config_t flexspi_config = { 0x02, FC_RADDR_SDR, FC_FLEXSPI_1PAD, 0x18), + [4 * 9 + 1] = FC_FLEXSPI_LUT_SEQ( FC_WRITE_SDR, FC_FLEXSPI_1PAD, @@ -114,5 +103,5 @@ const fc_flexspi_nor_config_t flexspi_config = { .sectorSize = 0x1000, .ipcmdSerialClkFreq = 0, .blockSize = 0x8000, - .fcb_fill = 0xFFFFFFFFU, + .fcb_fill[0] = 0xFFFFFFFFU, }; diff --git a/boards/u-blox/ubx_evk_iris_w1/revision.cmake b/boards/u-blox/ubx_evk_iris_w1/revision.cmake index 1fa646cfa173..8b7783e50c0c 100644 --- a/boards/u-blox/ubx_evk_iris_w1/revision.cmake +++ b/boards/u-blox/ubx_evk_iris_w1/revision.cmake @@ -1,14 +1,16 @@ # Copyright (c) 2025 u-blox AG # SPDX-License-Identifier: Apache-2.0 +set(BOARD_REVISIONS "macronix" "fidelix") + if(NOT BOARD_REVISION) - set(BOARD_REVISION fidelex CACHE STRING "Board revision") + set(BOARD_REVISION "fidelix") endif() # Validate revision -if(NOT BOARD_REVISION STREQUAL "macronix" AND NOT BOARD_REVISION STREQUAL "fidelex") +if(NOT BOARD_REVISION STREQUAL "macronix" AND NOT BOARD_REVISION STREQUAL "fidelix") message(FATAL_ERROR "Invalid BOARD_REVISION: ${BOARD_REVISION}\n" - "Must be one of: macronix, fidelex" + "Must be one of: macronix, fidelix" ) endif() diff --git a/boards/u-blox/ubx_evk_iris_w1/ubx_evk_iris_w1_rw612_fidelex_defconfig b/boards/u-blox/ubx_evk_iris_w1/ubx_evk_iris_w1_rw612_defconfig similarity index 100% rename from boards/u-blox/ubx_evk_iris_w1/ubx_evk_iris_w1_rw612_fidelex_defconfig rename to boards/u-blox/ubx_evk_iris_w1/ubx_evk_iris_w1_rw612_defconfig diff --git a/boards/u-blox/ubx_evk_iris_w1/ubx_evk_iris_w1_rw612_macronix_defconfig b/boards/u-blox/ubx_evk_iris_w1/ubx_evk_iris_w1_rw612_macronix_defconfig deleted file mode 100644 index dab38c62f8fc..000000000000 --- a/boards/u-blox/ubx_evk_iris_w1/ubx_evk_iris_w1_rw612_macronix_defconfig +++ /dev/null @@ -1,12 +0,0 @@ -# -# Copyright (c) 2025 u-blox AG -# SPDX-License-Identifier: Apache-2.0 -# -CONFIG_CONSOLE=y -CONFIG_UART_CONSOLE=y -CONFIG_SERIAL=y -CONFIG_UART_INTERRUPT_DRIVEN=y -CONFIG_GPIO=y -CONFIG_ARM_MPU=y -CONFIG_HW_STACK_PROTECTION=y -CONFIG_TRUSTED_EXECUTION_SECURE=y From f0a528bbb2fe14c7b99d887a0aa6753717da4790 Mon Sep 17 00:00:00 2001 From: Lucien Zhao Date: Wed, 3 Dec 2025 15:18:24 +0800 Subject: [PATCH 1825/3659] drivers: clock_control_nxp_mc_cgm.c: update clock driver - Update switch usage for mc_cgm_clock_control_on function - add pit clock on/get rate feature Signed-off-by: Lucien Zhao --- .../clock_control/clock_control_nxp_mc_cgm.c | 47 +++++++++++-------- include/zephyr/dt-bindings/clock/nxp_mc_cgm.h | 3 +- 2 files changed, 30 insertions(+), 20 deletions(-) diff --git a/drivers/clock_control/clock_control_nxp_mc_cgm.c b/drivers/clock_control/clock_control_nxp_mc_cgm.c index ea4f4b8f89da..cdfea309d47e 100644 --- a/drivers/clock_control/clock_control_nxp_mc_cgm.c +++ b/drivers/clock_control/clock_control_nxp_mc_cgm.c @@ -42,8 +42,10 @@ const clock_pcfs_config_t pcfs_config = {.maxAllowableIDDchange = NXP_PLL_MAXIDO static int mc_cgm_clock_control_on(const struct device *dev, clock_control_subsys_t sub_system) { + uint32_t clock_name = (uint32_t)sub_system; + + switch (clock_name) { #if defined(CONFIG_CAN_MCUX_FLEXCAN) - switch ((uint32_t)sub_system) { case MCUX_FLEXCAN0_CLK: CLOCK_EnableClock(kCLOCK_Flexcan0); break; @@ -62,13 +64,9 @@ static int mc_cgm_clock_control_on(const struct device *dev, clock_control_subsy case MCUX_FLEXCAN5_CLK: CLOCK_EnableClock(kCLOCK_Flexcan5); break; - default: - break; - } #endif /* defined(CONFIG_CAN_MCUX_MCAN) */ #if defined(CONFIG_UART_MCUX_LPUART) - switch ((uint32_t)sub_system) { case MCUX_LPUART0_CLK: CLOCK_EnableClock(kCLOCK_Lpuart0); break; @@ -117,13 +115,9 @@ static int mc_cgm_clock_control_on(const struct device *dev, clock_control_subsy case MCUX_LPUART15_CLK: CLOCK_EnableClock(kCLOCK_Lpuart15); break; - default: - break; - } #endif /* defined(CONFIG_UART_MCUX_LPUART) */ #if defined(CONFIG_SPI_NXP_LPSPI) - switch ((uint32_t)sub_system) { case MCUX_LPSPI0_CLK: CLOCK_EnableClock(kCLOCK_Lpspi0); break; @@ -142,36 +136,40 @@ static int mc_cgm_clock_control_on(const struct device *dev, clock_control_subsy case MCUX_LPSPI5_CLK: CLOCK_EnableClock(kCLOCK_Lpspi5); break; - default: - break; - } #endif /* defined(CONFIG_SPI_NXP_LPSPI) */ #if defined(CONFIG_I2C_MCUX_LPI2C) - switch ((uint32_t)sub_system) { case MCUX_LPI2C0_CLK: CLOCK_EnableClock(kCLOCK_Lpi2c0); break; case MCUX_LPI2C1_CLK: CLOCK_EnableClock(kCLOCK_Lpi2c1); break; - default: - break; - } #endif /* defined(CONFIG_I2C_MCUX_LPI2C) */ #if defined(CONFIG_COUNTER_MCUX_STM) - switch ((uint32_t)sub_system) { case MCUX_STM0_CLK: CLOCK_EnableClock(kCLOCK_Stm0); break; case MCUX_STM1_CLK: CLOCK_EnableClock(kCLOCK_Stm1); break; - default: +#endif /* defined(CONFIG_COUNTER_MCUX_STM) */ + +#ifdef CONFIG_COUNTER_NXP_PIT + case MCUX_PIT0_CLK: + CLOCK_EnableClock(kCLOCK_Pit0Clk); + break; + case MCUX_PIT1_CLK: + CLOCK_EnableClock(kCLOCK_Pit1Clk); + break; + case MCUX_PIT2_CLK: + CLOCK_EnableClock(kCLOCK_Pit2Clk); break; +#endif + default: + return -ENOTSUP; } -#endif /* defined(CONFIG_COUNTER_MCUX_STM) */ #if defined(CONFIG_COMPARATOR_NXP_LPCMP) switch ((uint32_t)sub_system) { @@ -309,6 +307,17 @@ static int mc_cgm_get_subsys_rate(const struct device *dev, clock_control_subsys break; #endif /* CONFIG_ADC_NXP_SAR_ADC */ + +#if defined(CONFIG_COUNTER_NXP_PIT) + case MCUX_PIT0_CLK: + case MCUX_PIT1_CLK: + case MCUX_PIT2_CLK: + *rate = CLOCK_GetAipsSlowClkFreq(); + break; +#endif /* defined(CONFIG_COUNTER_NXP_PIT) */ + + default: + return -ENOTSUP; } return 0; diff --git a/include/zephyr/dt-bindings/clock/nxp_mc_cgm.h b/include/zephyr/dt-bindings/clock/nxp_mc_cgm.h index cf4698081cf2..160e56fb786f 100644 --- a/include/zephyr/dt-bindings/clock/nxp_mc_cgm.h +++ b/include/zephyr/dt-bindings/clock/nxp_mc_cgm.h @@ -24,7 +24,8 @@ /* Note- clock identifiers in this file must be unique, * as the driver uses them in a switch case */ - +#define MCUX_MC_CGM_PERIPHERAL_MASK 0xFF00UL +#define MCUX_MC_CGM_INSTANCE_MASK 0xFFUL #define MCUX_MC_CGM_CLK_ID(high, low) ((high << 8) | (low)) /* These IDs are used within SOC macros, and thus cannot be defined From 2f6a4191a7552e5c6ac488294fdf3ec31093e8ff Mon Sep 17 00:00:00 2001 From: Lucien Zhao Date: Tue, 9 Dec 2025 23:00:05 +0800 Subject: [PATCH 1826/3659] =?UTF-8?q?boards=EF=BC=9A=20nxp:=20frdm=5Fmcxe3?= =?UTF-8?q?1b:=20add=20pit=20support?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - add some necessary static parameter for pit instances - Enable counter_basic_api case by using pit0 instance - Test counter_basic_api passed Signed-off-by: Lucien Zhao --- boards/nxp/frdm_mcxe31b/frdm_mcxe31b.dts | 4 + dts/arm/nxp/nxp_mcxe31x_common.dtsi | 78 +++++++++++++++++++ .../boards/frdm_mcxe31b.overlay | 21 +++++ 3 files changed, 103 insertions(+) create mode 100644 tests/drivers/counter/counter_basic_api/boards/frdm_mcxe31b.overlay diff --git a/boards/nxp/frdm_mcxe31b/frdm_mcxe31b.dts b/boards/nxp/frdm_mcxe31b/frdm_mcxe31b.dts index 65781a660edb..c5ef02d6a123 100644 --- a/boards/nxp/frdm_mcxe31b/frdm_mcxe31b.dts +++ b/boards/nxp/frdm_mcxe31b/frdm_mcxe31b.dts @@ -177,6 +177,10 @@ overdrive = <12>; }; +&pit_0 { + status = "okay"; +}; + &pll { status = "okay"; workmode = "Integer"; diff --git a/dts/arm/nxp/nxp_mcxe31x_common.dtsi b/dts/arm/nxp/nxp_mcxe31x_common.dtsi index b259980b58a0..5c25e06113ef 100644 --- a/dts/arm/nxp/nxp_mcxe31x_common.dtsi +++ b/dts/arm/nxp/nxp_mcxe31x_common.dtsi @@ -727,6 +727,32 @@ clocks = <&mc_cgm MCUX_PIT0_CLK>; max-load-value = <0xffffffff>; status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + + pit_0_channel0: pit_0_channel@0 { + compatible = "nxp,pit-channel"; + reg = <0>; + status = "disabled"; + }; + + pit_0_channel1: pit_0_channel@1 { + compatible = "nxp,pit-channel"; + reg = <1>; + status = "disabled"; + }; + + pit_0_channel2: pit_0_channel@2 { + compatible = "nxp,pit-channel"; + reg = <2>; + status = "disabled"; + }; + + pit_0_channel3: pit_0_channel@3 { + compatible = "nxp,pit-channel"; + reg = <3>; + status = "disabled"; + }; }; pit_1: pit@b4000 { @@ -736,6 +762,32 @@ clocks = <&mc_cgm MCUX_PIT1_CLK>; max-load-value = <0xffffffff>; status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + + pit_1_channel0: pit_1_channel@0 { + compatible = "nxp,pit-channel"; + reg = <0>; + status = "disabled"; + }; + + pit_1_channel1: pit_1_channel@1 { + compatible = "nxp,pit-channel"; + reg = <1>; + status = "disabled"; + }; + + pit_1_channel2: pit_1_channel@2 { + compatible = "nxp,pit-channel"; + reg = <2>; + status = "disabled"; + }; + + pit_1_channel3: pit_1_channel@3 { + compatible = "nxp,pit-channel"; + reg = <3>; + status = "disabled"; + }; }; pit_2: pit@2fc000 { @@ -745,6 +797,32 @@ clocks = <&mc_cgm MCUX_PIT2_CLK>; max-load-value = <0xffffffff>; status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + + pit_2_channel0: pit_2_channel@0 { + compatible = "nxp,pit-channel"; + reg = <0>; + status = "disabled"; + }; + + pit_2_channel1: pit_2_channel@1 { + compatible = "nxp,pit-channel"; + reg = <1>; + status = "disabled"; + }; + + pit_2_channel2: pit_2_channel@2 { + compatible = "nxp,pit-channel"; + reg = <2>; + status = "disabled"; + }; + + pit_2_channel3: pit_2_channel@3 { + compatible = "nxp,pit-channel"; + reg = <3>; + status = "disabled"; + }; }; pll: plldig@402e0000 { diff --git a/tests/drivers/counter/counter_basic_api/boards/frdm_mcxe31b.overlay b/tests/drivers/counter/counter_basic_api/boards/frdm_mcxe31b.overlay new file mode 100644 index 000000000000..693d95f77fc9 --- /dev/null +++ b/tests/drivers/counter/counter_basic_api/boards/frdm_mcxe31b.overlay @@ -0,0 +1,21 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&pit_0_channel0 { + status = "okay"; +}; + +&pit_0_channel1 { + status = "okay"; +}; + +&pit_0_channel2 { + status = "okay"; +}; + +&pit_0_channel3 { + status = "okay"; +}; From 837eac94e07413a3b99f2ed41251f967db3d490c Mon Sep 17 00:00:00 2001 From: Dat Nguyen Duy Date: Fri, 26 Dec 2025 10:32:09 +0700 Subject: [PATCH 1827/3659] dts: nxp: add pwm (ftm) devicetree nodes for s32k566 Add PWM (FTM) devicetree nodes for s32k566 Signed-off-by: Dat Nguyen Duy --- dts/arm/nxp/nxp_s32k566.dtsi | 9 +++++++++ dts/arm/nxp/nxp_s32k566_m7.dtsi | 4 ++++ dts/arm/nxp/nxp_s32k566_r52.dtsi | 4 ++++ 3 files changed, 17 insertions(+) diff --git a/dts/arm/nxp/nxp_s32k566.dtsi b/dts/arm/nxp/nxp_s32k566.dtsi index ea06872f5084..9cc51920429a 100644 --- a/dts/arm/nxp/nxp_s32k566.dtsi +++ b/dts/arm/nxp/nxp_s32k566.dtsi @@ -789,6 +789,15 @@ status = "disabled"; }; + lpe_ftm: ftm@42158000 { + compatible = "nxp,ftm-pwm"; + reg = <0x42158000 0x4000>; + clocks = <&clock NXP_S32_LPE_FTM_IPG_CLK>; + prescaler = <1>; + #pwm-cells = <3>; + status = "disabled"; + }; + sar_adc0: adc@40698000 { compatible = "nxp,s32-adc-sar"; reg = <0x40698000 0x4000>; diff --git a/dts/arm/nxp/nxp_s32k566_m7.dtsi b/dts/arm/nxp/nxp_s32k566_m7.dtsi index 06a833b146f0..55cc97bb85eb 100644 --- a/dts/arm/nxp/nxp_s32k566_m7.dtsi +++ b/dts/arm/nxp/nxp_s32k566_m7.dtsi @@ -457,3 +457,7 @@ &lpi2c3 { interrupts = <146 0>; }; + +&lpe_ftm { + interrupts = <223 0>; +}; diff --git a/dts/arm/nxp/nxp_s32k566_r52.dtsi b/dts/arm/nxp/nxp_s32k566_r52.dtsi index 5622742f13fd..d37db24bdc52 100644 --- a/dts/arm/nxp/nxp_s32k566_r52.dtsi +++ b/dts/arm/nxp/nxp_s32k566_r52.dtsi @@ -407,3 +407,7 @@ &lpi2c3 { interrupts = ; }; + +&lpe_ftm { + interrupts = ; +}; From af3d6a25c7fb5ab4f1890709fc5ab7838e862018 Mon Sep 17 00:00:00 2001 From: Dat Nguyen Duy Date: Fri, 26 Dec 2025 10:35:49 +0700 Subject: [PATCH 1828/3659] tests: drivers: pwm_ftm: enable tests for s32k5xxcvb Enable PWM (FTM) tests for s32k5xxcvb. The board supports eMIOS and FTM for PWM Signed-off-by: Dat Nguyen Duy --- .../boards/s32k5xxcvb_s32k566_ftm.overlay | 30 +++++++++++++++ .../boards/s32k5xxcvb_s32k566_m7.overlay | 2 +- tests/drivers/pwm/pwm_api/testcase.yaml | 10 +++++ .../boards/s32k5xxcvb_s32k566_ftm.overlay | 37 +++++++++++++++++++ tests/drivers/pwm/pwm_loopback/testcase.yaml | 14 +++++++ 5 files changed, 92 insertions(+), 1 deletion(-) create mode 100644 tests/drivers/pwm/pwm_api/boards/s32k5xxcvb_s32k566_ftm.overlay create mode 100644 tests/drivers/pwm/pwm_loopback/boards/s32k5xxcvb_s32k566_ftm.overlay diff --git a/tests/drivers/pwm/pwm_api/boards/s32k5xxcvb_s32k566_ftm.overlay b/tests/drivers/pwm/pwm_api/boards/s32k5xxcvb_s32k566_ftm.overlay new file mode 100644 index 000000000000..26046719bb60 --- /dev/null +++ b/tests/drivers/pwm/pwm_api/boards/s32k5xxcvb_s32k566_ftm.overlay @@ -0,0 +1,30 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/ { + aliases { + pwm-test = &lpe_ftm; + }; +}; + +&pinctrl { + lpe_ftm_default: lpe_ftm_default { + group0 { + pinmux = ; /* GPIO173 - J318 - P4*/ + output-enable; + }; + }; +}; + +&lpe_ftm { + pinctrl-0 = <&lpe_ftm_default>; + pinctrl-names = "default"; + clock-source = "system"; + prescaler = <32>; + status = "okay"; +}; diff --git a/tests/drivers/pwm/pwm_api/boards/s32k5xxcvb_s32k566_m7.overlay b/tests/drivers/pwm/pwm_api/boards/s32k5xxcvb_s32k566_m7.overlay index 042fb50589fa..b9e64537079a 100644 --- a/tests/drivers/pwm/pwm_api/boards/s32k5xxcvb_s32k566_m7.overlay +++ b/tests/drivers/pwm/pwm_api/boards/s32k5xxcvb_s32k566_m7.overlay @@ -8,7 +8,7 @@ / { aliases { - pwm-0 = &emios0_pwm; + pwm-test = &emios0_pwm; }; }; diff --git a/tests/drivers/pwm/pwm_api/testcase.yaml b/tests/drivers/pwm/pwm_api/testcase.yaml index deeb338f94b6..6a3a07856eb9 100644 --- a/tests/drivers/pwm/pwm_api/testcase.yaml +++ b/tests/drivers/pwm/pwm_api/testcase.yaml @@ -146,3 +146,13 @@ tests: platform_allow: - sam_e54_xpro filter: dt_alias_exists("pwm-test") + drivers.pwm.s32k5xxcvb_s32k566_ftm: + tags: + - drivers + - pwm + - userspace + extra_args: DTC_OVERLAY_FILE="boards/s32k5xxcvb_s32k566_ftm.overlay" + platform_allow: + - s32k5xxcvb/s32k566/m7 + - s32k5xxcvb/s32k566/r52 + depends_on: pwm diff --git a/tests/drivers/pwm/pwm_loopback/boards/s32k5xxcvb_s32k566_ftm.overlay b/tests/drivers/pwm/pwm_loopback/boards/s32k5xxcvb_s32k566_ftm.overlay new file mode 100644 index 000000000000..f05022258f3c --- /dev/null +++ b/tests/drivers/pwm/pwm_loopback/boards/s32k5xxcvb_s32k566_ftm.overlay @@ -0,0 +1,37 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/ { + pwm_loopback_0 { + compatible = "test-pwm-loopback"; + pwms = <&lpe_ftm 0 0 PWM_POLARITY_NORMAL>, + <&lpe_ftm 4 0 PWM_POLARITY_NORMAL>; + }; +}; + +&pinctrl { + lpe_ftm_default: lpe_ftm_default { + group0 { + pinmux = ; /* GPIO173 - J318 - P4*/ + output-enable; + }; + + group1 { + pinmux = ; /* GPIO167 - J405 - D1 */ + input-enable; + }; + }; +}; + +&lpe_ftm { + pinctrl-0 = <&lpe_ftm_default>; + pinctrl-names = "default"; + clock-source = "system"; + prescaler = <128>; + status = "okay"; +}; diff --git a/tests/drivers/pwm/pwm_loopback/testcase.yaml b/tests/drivers/pwm/pwm_loopback/testcase.yaml index 66df7c5fef2f..377f0d16c704 100644 --- a/tests/drivers/pwm/pwm_loopback/testcase.yaml +++ b/tests/drivers/pwm/pwm_loopback/testcase.yaml @@ -9,3 +9,17 @@ tests: harness: ztest harness_config: fixture: pwm_loopback + drivers.pwm.s32k5xxcvb_s32k566_ftm.loopback: + tags: + - pwm + - drivers + - userspace + extra_args: DTC_OVERLAY_FILE="boards/s32k5xxcvb_s32k566_ftm.overlay" + platform_allow: + - s32k5xxcvb/s32k566/m7 + - s32k5xxcvb/s32k566/r52 + depends_on: pwm + filter: dt_compat_enabled("test-pwm-loopback") + harness: ztest + harness_config: + fixture: pwm_loopback From 31fb05d9b25870b9c7d6d0aa632cc23c8a11e239 Mon Sep 17 00:00:00 2001 From: Ha Duong Quang Date: Fri, 21 Nov 2025 09:00:56 +0700 Subject: [PATCH 1829/3659] boards: nxp: s32k5xxcvb: add pwm support Add support PWM (FTM) for S32K5XXCVB Signed-off-by: Ha Duong Quang Co-authored-by: Dat Nguyen Duy Signed-off-by: Dat Nguyen Duy --- boards/nxp/s32k5xxcvb/s32k5xxcvb_s32k566_m7.yaml | 1 + boards/nxp/s32k5xxcvb/s32k5xxcvb_s32k566_r52.yaml | 1 + 2 files changed, 2 insertions(+) diff --git a/boards/nxp/s32k5xxcvb/s32k5xxcvb_s32k566_m7.yaml b/boards/nxp/s32k5xxcvb/s32k5xxcvb_s32k566_m7.yaml index 057ba3b3ad45..35be8009dad9 100644 --- a/boards/nxp/s32k5xxcvb/s32k5xxcvb_s32k566_m7.yaml +++ b/boards/nxp/s32k5xxcvb/s32k5xxcvb_s32k566_m7.yaml @@ -13,6 +13,7 @@ supported: - adc - can - gpio + - pwm - counter - i2c vendor: nxp diff --git a/boards/nxp/s32k5xxcvb/s32k5xxcvb_s32k566_r52.yaml b/boards/nxp/s32k5xxcvb/s32k5xxcvb_s32k566_r52.yaml index c7874c8f1524..41d218e21581 100644 --- a/boards/nxp/s32k5xxcvb/s32k5xxcvb_s32k566_r52.yaml +++ b/boards/nxp/s32k5xxcvb/s32k5xxcvb_s32k566_r52.yaml @@ -13,6 +13,7 @@ supported: - adc - can - gpio + - pwm - counter - i2c vendor: nxp From 9e9eb8e3caa4406d62903108645dd1df1ecd7651 Mon Sep 17 00:00:00 2001 From: Karol Werner Date: Sun, 11 Jan 2026 20:13:09 +0100 Subject: [PATCH 1830/3659] doc: rp2040_zero: Update pin mapping to match pinctrl The pin mapping documented for I2C0 and I2C1 did not match actual pinctrl definitions. Update the documentation to reflect correct pins and add missing SPI and RGB LED mappings. Signed-off-by: Karol Werner --- boards/waveshare/rp2040_zero/doc/index.rst | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/boards/waveshare/rp2040_zero/doc/index.rst b/boards/waveshare/rp2040_zero/doc/index.rst index a469e2f502f8..ebafe54373ab 100644 --- a/boards/waveshare/rp2040_zero/doc/index.rst +++ b/boards/waveshare/rp2040_zero/doc/index.rst @@ -39,14 +39,18 @@ Default Zephyr Peripheral Mapping: - UART0_TX : P0 - UART0_RX : P1 -- I2C0_SDA : P4 -- I2C0_SCL : P5 -- I2C1_SDA : P6 -- I2C1_SCL : P7 +- I2C0_SDA : P24 +- I2C0_SCL : P25 +- I2C1_SDA : P22 +- I2C1_SCL : P23 +- SPI0_TX : P3 +- SPI0_RX : P4 +- SPI0_SCK : P6 - ADC_CH0 : P26 - ADC_CH1 : P27 - ADC_CH2 : P28 - ADC_CH3 : P29 +- RGB LED (WS2812): P16 Programming and Debugging ************************* From a28ee312b07ca670719fa14a1e2f98f821999bed Mon Sep 17 00:00:00 2001 From: Farsin Nasar V A Date: Thu, 8 Jan 2026 12:41:55 +0530 Subject: [PATCH 1831/3659] dts: arm: microchip: add RSTC node Add the device tree node for microchip RSTC G1 IP. Signed-off-by: Farsin Nasar V A --- dts/arm/microchip/pic32c/pic32cm_jh/common/pic32cm_jh.dtsi | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/dts/arm/microchip/pic32c/pic32cm_jh/common/pic32cm_jh.dtsi b/dts/arm/microchip/pic32c/pic32cm_jh/common/pic32cm_jh.dtsi index 9191d4d19400..ad24848b4187 100644 --- a/dts/arm/microchip/pic32c/pic32cm_jh/common/pic32cm_jh.dtsi +++ b/dts/arm/microchip/pic32c/pic32cm_jh/common/pic32cm_jh.dtsi @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025 Microchip Technology Inc. + * Copyright (c) 2025-2026 Microchip Technology Inc. * * SPDX-License-Identifier: Apache-2.0 */ @@ -91,6 +91,11 @@ }; }; + rstc: rstc@40000c00 { + compatible = "microchip,rstc-g1-reset"; + reg = <0x40000c00 0x400>; + }; + pinctrl: pinctrl@41000000 { compatible = "microchip,port-g1-pinctrl"; #address-cells = <1>; From 9d156cc98b6fad8feca5a8fd425c1a8262bf2225 Mon Sep 17 00:00:00 2001 From: Farsin Nasar V A Date: Thu, 8 Jan 2026 12:44:02 +0530 Subject: [PATCH 1832/3659] drivers: reset: microchip: update RSTC G1 driver for PIC32CM JH Update the reset driver to add support for the PIC32CM JH family Signed-off-by: Farsin Nasar V A --- drivers/reset/reset_mchp_rstc_g1.c | 14 ++++---------- include/zephyr/drivers/reset/mchp_rstc_g1.h | 11 ++++++++++- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/drivers/reset/reset_mchp_rstc_g1.c b/drivers/reset/reset_mchp_rstc_g1.c index 33d141aaff34..4fc7426f325f 100644 --- a/drivers/reset/reset_mchp_rstc_g1.c +++ b/drivers/reset/reset_mchp_rstc_g1.c @@ -1,22 +1,14 @@ /* - * Copyright (c) 2025 Microchip Technology Inc. + * Copyright (c) 2025-2026 Microchip Technology Inc. * * SPDX-License-Identifier: Apache-2.0 */ -/** - * @file reset_mchp_rstc_g1.c - * @brief Zephyr reset driver for Microchip G1 peripherals - * - * This file implements the driver for the Microchip RSTC g1 reset controller, - * providing APIs to assert, deassert, toggle, and query the status of reset lines. - * - */ - #include #include #include #include +#include #define DT_DRV_COMPAT microchip_rstc_g1_reset @@ -46,6 +38,8 @@ static int reset_mchp_status(const struct device *dev, uint32_t id, uint8_t *sta if (id >= MCHP_RST_LINE_MAX) { ret = -EINVAL; + } else if ((BIT(id) & RSTC_UNSUPPORTED_RCAUSE) != 0U) { + ret = -ENOTSUP; } else { rcause = (((const struct reset_mchp_config *)((dev)->config))->regs)->RSTC_RCAUSE; *status = (rcause & BIT(id)) ? 1 : 0; diff --git a/include/zephyr/drivers/reset/mchp_rstc_g1.h b/include/zephyr/drivers/reset/mchp_rstc_g1.h index 174fca359c92..f488cc7c604c 100644 --- a/include/zephyr/drivers/reset/mchp_rstc_g1.h +++ b/include/zephyr/drivers/reset/mchp_rstc_g1.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025 Microchip Technology Inc. + * Copyright (c) 2025-2026 Microchip Technology Inc. * * SPDX-License-Identifier: Apache-2.0 */ @@ -32,4 +32,13 @@ enum rstc_g1_rcause { RSTC_G1_RCAUSE_BACKUP = 7 /* Backup Reset */ }; +#ifdef CONFIG_SOC_FAMILY_MICROCHIP_PIC32CM_JH +/* Reserved reset-cause bits on PIC32CM JH */ +#define RSTC_RESERVED_BIT_3 BIT(3) +#define RSTC_RESERVED_BIT_7 BIT(7) +#define RSTC_UNSUPPORTED_RCAUSE ((RSTC_RESERVED_BIT_3) | (RSTC_RESERVED_BIT_7)) +#else +#define RSTC_UNSUPPORTED_RCAUSE 0U +#endif /* CONFIG_SOC_FAMILY_MICROCHIP_PIC32CM_JH */ + #endif /* INCLUDE_ZEPHYR_DRIVERS_RESET_MCHP_RSTC_G1_H_ */ From 752c1d97c6c5a6db9e4e15a3a48fbb1651cda512 Mon Sep 17 00:00:00 2001 From: Farsin Nasar V A Date: Thu, 8 Jan 2026 12:50:14 +0530 Subject: [PATCH 1833/3659] boards: microchip: pic32cm_jh01_cpro: add RESET to supported list Update pic32cm_jh01_cpro.yaml to include RESET in the supported modules list. Signed-off-by: Farsin Nasar V A --- .../microchip/pic32c/pic32cm_jh01_cpro/pic32cm_jh01_cpro.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/boards/microchip/pic32c/pic32cm_jh01_cpro/pic32cm_jh01_cpro.yaml b/boards/microchip/pic32c/pic32cm_jh01_cpro/pic32cm_jh01_cpro.yaml index 3a26590f8ce7..1eccd96ff03d 100644 --- a/boards/microchip/pic32c/pic32cm_jh01_cpro/pic32cm_jh01_cpro.yaml +++ b/boards/microchip/pic32c/pic32cm_jh01_cpro/pic32cm_jh01_cpro.yaml @@ -1,4 +1,4 @@ -# Copyright (c) 2025 Microchip Technology Inc. +# Copyright (c) 2025-2026 Microchip Technology Inc. # SPDX-License-Identifier: Apache-2.0 identifier: pic32cm_jh01_cpro @@ -13,5 +13,6 @@ supported: - clock_control - gpio - pinctrl + - reset - uart vendor: microchip From a3df33722c8f0969fe6579031d6bb1a62944c035 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Tue, 13 Jan 2026 11:55:25 +0100 Subject: [PATCH 1834/3659] manifest: update hal_nordic to get cache hal fix Update hal_nordic to get a fix in the definition of nrf_cache_data_unit_validity_check() Signed-off-by: Alberto Escolar Piedras --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index e047e218c1b9..275fbbf60f6a 100644 --- a/west.yml +++ b/west.yml @@ -200,7 +200,7 @@ manifest: groups: - hal - name: hal_nordic - revision: 248eadcacf976bbd27f1c0bc0dd3f11d8ec8657e + revision: a83db66acbeca0bfef157a0c3482c07ddbb82555 path: modules/hal/nordic groups: - hal From f0c26dfb85b8e6903ff8bedcca8fd16f03ced895 Mon Sep 17 00:00:00 2001 From: Ivan Iushkov Date: Tue, 13 Jan 2026 13:14:11 +0100 Subject: [PATCH 1835/3659] Bluetooth: fix potential unaligned access in CS HCI fields This commit fixes an issue reported by LLVM Clang compiler when building with -Wunaligned-access: ``` bluetooth/hci_types.h:4044:2: error: field within 'struct bt_hci_le_cs_step_data_mode_1' is less aligned than 'union bt_hci_le_cs_step_data_mode_1:: (include/zephyr/bluetooth/hci_types.h:4044:2)' and is usually due to 'struct bt_hci_le_cs_step_data_mode_1' being packed, which can lead to unaligned accesses [-Werror,-Wunaligned-access] ``` and similar issues for other CS-specific types containing unions Signed-off-by: Ivan Iushkov --- include/zephyr/bluetooth/hci_types.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/zephyr/bluetooth/hci_types.h b/include/zephyr/bluetooth/hci_types.h index 71fb29c828aa..ce2aa428fa5a 100644 --- a/include/zephyr/bluetooth/hci_types.h +++ b/include/zephyr/bluetooth/hci_types.h @@ -4044,7 +4044,7 @@ struct bt_hci_le_cs_step_data_mode_1 { union { int16_t toa_tod_initiator; int16_t tod_toa_reflector; - }; + } __packed; uint8_t packet_antenna; } __packed; @@ -4062,7 +4062,7 @@ struct bt_hci_le_cs_step_data_mode_1_ss_rtt { union { int16_t toa_tod_initiator; int16_t tod_toa_reflector; - }; + } __packed; uint8_t packet_antenna; uint8_t packet_pct1[4]; uint8_t packet_pct2[4]; @@ -4101,7 +4101,7 @@ struct bt_hci_le_cs_step_data_mode_3 { union { int16_t toa_tod_initiator; int16_t tod_toa_reflector; - }; + } __packed; uint8_t packet_antenna; uint8_t antenna_permutation_index; struct bt_hci_le_cs_step_data_tone_info tone_info[]; @@ -4121,7 +4121,7 @@ struct bt_hci_le_cs_step_data_mode_3_ss_rtt { union { int16_t toa_tod_initiator; int16_t tod_toa_reflector; - }; + } __packed; uint8_t packet_antenna; uint8_t packet_pct1[4]; uint8_t packet_pct2[4]; From 69f318ab1605f3da0cc8b8ceb8f688e6a27b7f3a Mon Sep 17 00:00:00 2001 From: Gaetan Perrot Date: Tue, 13 Jan 2026 19:28:06 +0900 Subject: [PATCH 1836/3659] tests: net: lwm2m: interop: client: make lwm2m_setup void lwm2m_setup() never reports errors and always returns 0. The error check at the call site is therefore dead code. Make the function void and drop the unused error handling. Signed-off-by: Gaetan Perrot --- tests/net/lib/lwm2m/interop/src/lwm2m-client.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/tests/net/lib/lwm2m/interop/src/lwm2m-client.c b/tests/net/lib/lwm2m/interop/src/lwm2m-client.c index fcc89b9b3171..1ff3b72bd640 100644 --- a/tests/net/lib/lwm2m/interop/src/lwm2m-client.c +++ b/tests/net/lib/lwm2m/interop/src/lwm2m-client.c @@ -100,7 +100,7 @@ static int create_appdata(uint16_t obj_inst_id) return 0; } -static int lwm2m_setup(void) +static void lwm2m_setup(void) { /* setup DEVICE object */ @@ -131,8 +131,6 @@ static int lwm2m_setup(void) lwm2m_set_res_buf(&LWM2M_OBJ(3, 0, 8, 1), &usb_ma, sizeof(usb_ma), sizeof(usb_ma), 0); lwm2m_register_create_callback(19, create_appdata); - - return 0; } static void rd_client_event(struct lwm2m_ctx *client, @@ -236,13 +234,7 @@ static void observe_cb(enum lwm2m_observe_event event, int main(void) { - int ret; - - ret = lwm2m_setup(); - if (ret < 0) { - LOG_ERR("Cannot setup LWM2M fields (%d)", ret); - return 0; - } + lwm2m_setup(); client.tls_tag = 1; client.set_socketoptions = set_socketoptions; From a793acaff008f03886859a83359aba94243c76fc Mon Sep 17 00:00:00 2001 From: Tim Pambor Date: Tue, 13 Jan 2026 14:29:45 +0100 Subject: [PATCH 1837/3659] drivers: flash: shell: increase max repeat limit for speed tests Increase the maximum allowed repeat count for flash speed tests from 10 to 10000. This allows for more accurate measurements over longer test durations. Signed-off-by: Tim Pambor --- drivers/flash/flash_shell.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/flash/flash_shell.c b/drivers/flash/flash_shell.c index b5d3da86baec..77fb7af3a785 100644 --- a/drivers/flash/flash_shell.c +++ b/drivers/flash/flash_shell.c @@ -21,6 +21,8 @@ #include #endif +#define SPEED_TEST_MAX_REPETITIONS 10000 + /* Buffer is only needed for bytes that follow command and offset */ #define BUF_ARRAY_CNT (CONFIG_SHELL_ARGC_MAX - 2) @@ -350,8 +352,8 @@ static int read_write_erase_validate(const struct shell *sh, size_t argc, char * return -EINVAL; } - if (*repeat == 0 || *repeat > 10) { - shell_error(sh, " must be between 1 and 10."); + if (*repeat == 0 || *repeat > SPEED_TEST_MAX_REPETITIONS) { + shell_error(sh, " must be between 1 and %d.", SPEED_TEST_MAX_REPETITIONS); return -EINVAL; } From 60f97b4c7c49d67f31b254f163af3df6a4225cf9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Wed, 14 Jan 2026 23:06:39 +0100 Subject: [PATCH 1838/3659] cmake: modules: boards: fix typo in "outcome" target name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The module sets a target named "boards", not "board". Signed-off-by: Benjamin Cabé --- cmake/modules/boards.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/modules/boards.cmake b/cmake/modules/boards.cmake index 9a21574595ba..44fa8d5a753a 100644 --- a/cmake/modules/boards.cmake +++ b/cmake/modules/boards.cmake @@ -31,7 +31,7 @@ # - BOARD_ROOT: BOARD_ROOT with ZEPHYR_BASE appended # # The following targets will be defined when this CMake module completes: -# - board: when invoked, a list of valid boards will be printed +# - boards: when invoked, a list of valid boards will be printed # # Required variables: # - BOARD: Board name, including any optional revision field, for example: `foo` or `foo@1.0.0` From 9c3b2f06489f05251461c2b979e1d12db06fd38d Mon Sep 17 00:00:00 2001 From: Sergei Ovchinnikov Date: Mon, 14 Jul 2025 10:18:02 +0200 Subject: [PATCH 1839/3659] drivers: regulators: regulator_gpio: remove gpio_pin_get_dt call Since input buffer may not always be connected when a GPIO is configured as an OUTPUT, setting its state based on what is returned by gpio_pin_get_dt can lead to faulty behavior. Remove this check as redundant. Fixes #93012 Signed-off-by: Sergei Ovchinnikov --- drivers/regulator/regulator_gpio.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/drivers/regulator/regulator_gpio.c b/drivers/regulator/regulator_gpio.c index dd9a4a19822d..eb4056da60b6 100644 --- a/drivers/regulator/regulator_gpio.c +++ b/drivers/regulator/regulator_gpio.c @@ -38,19 +38,11 @@ static int regulator_gpio_apply_state(const struct device *dev, uint32_t state) int ret; int new_state_of_gpio = (state >> gpio_idx) & 0x1; - ret = gpio_pin_get_dt(&cfg->gpios[gpio_idx]); + ret = gpio_pin_set_dt(&cfg->gpios[gpio_idx], new_state_of_gpio); if (ret < 0) { - LOG_ERR("%s: can't get pin state", dev->name); + LOG_ERR("%s: can't set pin state", dev->name); return ret; } - - if (ret != new_state_of_gpio) { - ret = gpio_pin_set_dt(&cfg->gpios[gpio_idx], new_state_of_gpio); - if (ret < 0) { - LOG_ERR("%s: can't set pin state", dev->name); - return ret; - } - } } return 0; From e572a6f7c6ff724948344b8caf6d446eb03baae3 Mon Sep 17 00:00:00 2001 From: Sergei Ovchinnikov Date: Mon, 14 Jul 2025 10:41:01 +0200 Subject: [PATCH 1840/3659] drivers: regulators: regulator_fixed, regulator_gpio: change init Change init procedure of regulator_fixed and regulator_gpio to not rely on reading the state of the enable pin as it might not be available. Initialize the enable pin to the appropriate state based on the REGULATOR_INIT_ENABLED flag. Signed-off-by: Sergei Ovchinnikov --- drivers/regulator/regulator_fixed.c | 16 +++++----------- drivers/regulator/regulator_gpio.c | 6 ++++-- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/drivers/regulator/regulator_fixed.c b/drivers/regulator/regulator_fixed.c index 7e024b608872..0e64fd1f274f 100644 --- a/drivers/regulator/regulator_fixed.c +++ b/drivers/regulator/regulator_fixed.c @@ -90,7 +90,8 @@ static DEVICE_API(regulator, regulator_fixed_api) = { static int regulator_fixed_init(const struct device *dev) { const struct regulator_fixed_config *cfg = dev->config; - bool is_enabled = false; + const bool should_enable = cfg->common.flags & REGULATOR_INIT_ENABLED; + int ret; regulator_common_data_init(dev); @@ -100,22 +101,15 @@ static int regulator_fixed_init(const struct device *dev) return -ENODEV; } - int ret = gpio_pin_configure_dt(&cfg->enable, GPIO_OUTPUT); + ret = gpio_pin_configure_dt(&cfg->enable, should_enable ? GPIO_OUTPUT_ACTIVE + : GPIO_OUTPUT_INACTIVE); if (ret < 0) { return ret; } - - ret = gpio_pin_get_dt(&cfg->enable); - - if (ret < 0) { - return ret; - } - - is_enabled = ret; } - return regulator_common_init(dev, is_enabled); + return regulator_common_init(dev, should_enable); } #define REGULATOR_FIXED_DEFINE(inst) \ diff --git a/drivers/regulator/regulator_gpio.c b/drivers/regulator/regulator_gpio.c index eb4056da60b6..a54995914ae4 100644 --- a/drivers/regulator/regulator_gpio.c +++ b/drivers/regulator/regulator_gpio.c @@ -154,6 +154,7 @@ static DEVICE_API(regulator, regulator_gpio_api) = { static int regulator_gpio_init(const struct device *dev) { const struct regulator_gpio_config *cfg = dev->config; + const bool should_enable = cfg->common.flags & REGULATOR_INIT_ENABLED; int ret; regulator_common_data_init(dev); @@ -180,7 +181,8 @@ static int regulator_gpio_init(const struct device *dev) return -ENODEV; } - ret = gpio_pin_configure_dt(&cfg->enable, GPIO_OUTPUT | GPIO_OUTPUT_INIT_LOW); + ret = gpio_pin_configure_dt(&cfg->enable, should_enable ? GPIO_OUTPUT_ACTIVE + : GPIO_OUTPUT_INACTIVE); if (ret < 0) { LOG_ERR("%s: can't configure enable pin (%d) as output", dev->name, cfg->enable.pin); @@ -188,7 +190,7 @@ static int regulator_gpio_init(const struct device *dev) } } - return regulator_common_init(dev, false); + return regulator_common_init(dev, should_enable); } #define REG_GPIO_CONTEXT_GPIOS_SPEC_ELEM(_node_id, _prop, _idx) \ From 234aa30a8f074bf7db39d3af25e5c6210ce5d75b Mon Sep 17 00:00:00 2001 From: Mark Inderhees Date: Mon, 29 Sep 2025 16:08:11 -0700 Subject: [PATCH 1841/3659] build: Dependency handling for syscall gen for changed API Fix issue where changing an existing syscall API does not result in regeneration of syscalls. This causes a build break on incremental builds. The issue comes from an incorrect assumption that file modifications result in updates to folder timestamps on Linux. The fix is to use the same mechanism Windows is using to track file changes, making explicit deps on header files that have syscalls. Signed-off-by: Mark Inderhees --- CMakeLists.txt | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7d7f1a7bca78..7dfdaebe1e34 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -818,12 +818,12 @@ set(struct_tags_json ${CMAKE_CURRENT_BINARY_DIR}/misc/generated/struct_tags.json # The syscalls subdirs txt file is constructed by python containing a list of folders to use for # dependency handling, including empty folders. # Windows: The list is used to specify DIRECTORY list with CMAKE_CONFIGURE_DEPENDS attribute. -# Other OS: The list will update whenever a file is added/removed/modified and ensure a re-build. +# Other OS: The list file is updated whenever a directory is added or removed. set(syscalls_subdirs_txt ${CMAKE_CURRENT_BINARY_DIR}/misc/generated/syscalls_subdirs.txt) -# As syscalls_subdirs_txt is updated whenever a file is modified, this file can not be used for -# monitoring of added / removed folders. A trigger file is thus used for correct dependency -# handling. The trigger file will update when a folder is added / removed. +# As syscalls_subdirs_txt is updated only on directory add or remove, this file can not be used for +# monitoring of syscall changes. A trigger file is thus used for correct dependency handling. The +# trigger file will update when syscalls change. set(syscalls_subdirs_trigger ${CMAKE_CURRENT_BINARY_DIR}/misc/generated/syscalls_subdirs.trigger) if(NOT (${CMAKE_HOST_SYSTEM_NAME} STREQUAL Windows)) @@ -842,14 +842,13 @@ execute_process( ) file(STRINGS ${syscalls_subdirs_txt} PARSE_SYSCALLS_PATHS_DEPENDS ENCODING UTF-8) +# Each header file must be monitored as file modifications are not reflected on directory level. +file(GLOB_RECURSE PARSE_SYSCALLS_HEADER_DEPENDS ${ZEPHYR_BASE}/include/*.h) + if(${CMAKE_HOST_SYSTEM_NAME} STREQUAL Windows) # On windows only adding/removing files or folders will be reflected in depends. # Hence adding a file requires CMake to re-run to add this file to the file list. set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${PARSE_SYSCALLS_PATHS_DEPENDS}) - - # Also On Windows each header file must be monitored as file modifications are not reflected - # on directory level. - file(GLOB_RECURSE PARSE_SYSCALLS_HEADER_DEPENDS ${ZEPHYR_BASE}/include/*.h) else() # The syscall parsing depends on the folders in order to detect add/removed/modified files. # When a folder is removed, CMake will try to find a target that creates that dependency. @@ -880,10 +879,10 @@ else() file(WRITE ${syscalls_subdirs_txt} "") endif() - # On other OS'es, modifying a file is reflected on the folder timestamp and hence detected + # On other OS'es, using git checkout is reflected on the folder timestamp and hence detected # when using depend on directory level. # Thus CMake only needs to re-run when sub-directories are added / removed, which is indicated - # using a trigger file. + # by syscalls_subdirs_txt being updated. set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${syscalls_subdirs_txt}) endif() From dca4136f5e07dafefb2f116d529bebb502e678cd Mon Sep 17 00:00:00 2001 From: Ibrahim Abdalkader Date: Tue, 9 Dec 2025 13:07:01 +0100 Subject: [PATCH 1842/3659] llext: Keep constant data in flash. This patch adds a new Kconfig option that allows read-only data sections without relocations to be mapped directly (remain in flash) instead of being copied to RAM during extension loading. This helps extensions that have large constant data, such as certificates, lookup tables etc.. to save saving significant RAM, especially with MPU is enabled. This feature requires the extension to place rodata sections without relocations in LLEXT_RODATA_NO_RELOC section. Note that we chose to disable this optimization when MMU or USERSPACE is enabled because the NO_RELOC section may not be aligned to the MPU/MMU requirements on some architectures. If we leave it in place, llext will attempt to create an MPU region for it using a misaligned address, and if we allow it to be copied to RAM, it defeats the purpose of this feature. Signed-off-by: Ibrahim Abdalkader --- include/zephyr/llext/llext.h | 19 +++++++++++++++++++ subsys/llext/Kconfig | 14 ++++++++++++++ subsys/llext/llext_load.c | 11 +++++++++++ 3 files changed, 44 insertions(+) diff --git a/include/zephyr/llext/llext.h b/include/zephyr/llext/llext.h index 4a5272568329..9e601ebf8dd1 100644 --- a/include/zephyr/llext/llext.h +++ b/include/zephyr/llext/llext.h @@ -53,6 +53,9 @@ enum llext_mem { LLEXT_MEM_PREINIT, /**< Array of early setup functions */ LLEXT_MEM_INIT, /**< Array of setup functions */ LLEXT_MEM_FINI, /**< Array of cleanup functions */ +#ifdef CONFIG_LLEXT_RODATA_NO_RELOC + LLEXT_MEM_RODATA_NO_RELOC, /**< Read-only data without relocations (kept in flash) */ +#endif LLEXT_MEM_COUNT, /**< Number of regions managed by LLEXT */ }; @@ -62,6 +65,22 @@ enum llext_mem { /* Number of memory partitions used by LLEXT */ #define LLEXT_MEM_PARTITIONS (LLEXT_MEM_BSS+1) +#ifdef CONFIG_LLEXT_RODATA_NO_RELOC +/* Section name for read-only data kept in flash */ +#define LLEXT_SECT_RODATA_NO_RELOC llext.rodata.noreloc + +/* Full section name as string for comparisons */ +#define LLEXT_SECTION_RODATA_NO_RELOC ("." STRINGIFY(LLEXT_SECT_RODATA_NO_RELOC)) + +/** + * Use this attribute on read-only data that should remain in flash + * instead of being copied to RAM. + */ +#define LLEXT_RODATA_NO_RELOC Z_GENERIC_DOT_SECTION(LLEXT_SECT_RODATA_NO_RELOC) +#else +#define LLEXT_RODATA_NO_RELOC +#endif + struct llext_loader; /** @endcond */ diff --git a/subsys/llext/Kconfig b/subsys/llext/Kconfig index b742f16f2add..c7c11ba6497a 100644 --- a/subsys/llext/Kconfig +++ b/subsys/llext/Kconfig @@ -108,6 +108,20 @@ config LLEXT_STORAGE_WRITABLE Select if LLEXT storage is writable, i.e. if extensions are stored in RAM and can be modified in place +config LLEXT_RODATA_NO_RELOC + bool "Keep read-only data without relocations in flash" + depends on !MMU && !USERSPACE + help + When enabled, read-only data sections (.rodata) that do not have + any relocations are kept in their original location (typically flash) + instead of being copied to RAM. + + This is useful for large constant data like certificates, lookup + tables, or string literals that don't contain any pointers. + + This feature requires the extension to manually tag that data with + the LLEXT_RODATA_NO_RELOC macro. + config LLEXT_EXPORT_DEVICES bool "Export all DT devices to llexts" select LLEXT_EXPORT_SYMBOL_GROUP_DEVICE diff --git a/subsys/llext/llext_load.c b/subsys/llext/llext_load.c index f317a8da3237..131825df360d 100644 --- a/subsys/llext/llext_load.c +++ b/subsys/llext/llext_load.c @@ -262,6 +262,10 @@ static int llext_map_sections(struct llext_loader *ldr, struct llext *ext, mem_idx = LLEXT_MEM_TEXT; } else if (shdr->sh_flags & SHF_WRITE) { mem_idx = LLEXT_MEM_DATA; +#ifdef CONFIG_LLEXT_RODATA_NO_RELOC + } else if (strcmp(name, LLEXT_SECTION_RODATA_NO_RELOC) == 0) { + mem_idx = LLEXT_MEM_RODATA_NO_RELOC; +#endif } else { mem_idx = LLEXT_MEM_RODATA; } @@ -534,6 +538,13 @@ static int llext_map_sections(struct llext_loader *ldr, struct llext *ext, } } +#ifdef CONFIG_LLEXT_RODATA_NO_RELOC + if (ldr->sects[LLEXT_MEM_RODATA_NO_RELOC].sh_flags & SHF_LLEXT_HAS_RELOCS) { + LOG_ERR("%s has relocations", LLEXT_SECTION_RODATA_NO_RELOC); + return -ENOEXEC; + } +#endif + return 0; } From d320921cd1873c04cea0a8fa51d9e04b2b72715d Mon Sep 17 00:00:00 2001 From: Ibrahim Abdalkader Date: Tue, 9 Dec 2025 20:29:53 +0100 Subject: [PATCH 1843/3659] tests: subsys: llext: Add test for LLEXT_RODATA_NO_RELOC. Test extension for CONFIG_LLEXT_RODATA_NO_RELOC feature. Signed-off-by: Ibrahim Abdalkader --- tests/subsys/llext/CMakeLists.txt | 4 ++ tests/subsys/llext/src/rodata_no_reloc_ext.c | 51 ++++++++++++++++++++ tests/subsys/llext/src/test_llext.c | 11 +++++ tests/subsys/llext/testcase.yaml | 2 + 4 files changed, 68 insertions(+) create mode 100644 tests/subsys/llext/src/rodata_no_reloc_ext.c diff --git a/tests/subsys/llext/CMakeLists.txt b/tests/subsys/llext/CMakeLists.txt index 4b746e48f925..ed4ca1fb4186 100644 --- a/tests/subsys/llext/CMakeLists.txt +++ b/tests/subsys/llext/CMakeLists.txt @@ -47,6 +47,10 @@ if(NOT CONFIG_LLEXT_TYPE_ELF_SHAREDLIB) list(APPEND ext_names init_fini) endif() +if(CONFIG_LLEXT_RODATA_NO_RELOC) + list(APPEND ext_names rodata_no_reloc) +endif() + # generate extension targets for each extension in 'ext_names' foreach(ext_name ${ext_names}) set(ext_src ${PROJECT_SOURCE_DIR}/src/${ext_name}_ext.c) diff --git a/tests/subsys/llext/src/rodata_no_reloc_ext.c b/tests/subsys/llext/src/rodata_no_reloc_ext.c new file mode 100644 index 000000000000..66c4f2c97e06 --- /dev/null +++ b/tests/subsys/llext/src/rodata_no_reloc_ext.c @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2025 Arduino SA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * Test extension for CONFIG_LLEXT_RODATA_NO_RELOC feature. + */ + +#include +#include +#include +#include +#include + +/* Exported by the main test to provide ELF buffer location */ +extern const void *rodata_no_reloc_ext_ptr; +extern const size_t rodata_no_reloc_ext_size; + +/* rodata with a relocation - forces .rodata to be relocated */ +Z_GENERIC_SECTION(.rodata) +static const void *relocated_data = &printk; + +/* rodata with no relocation - should stay in place */ +LLEXT_RODATA_NO_RELOC +static const uint32_t noreloc_data = 0x12345678; + +void test_entry(void) +{ + uintptr_t elf_start = (uintptr_t)rodata_no_reloc_ext_ptr; + uintptr_t elf_end = elf_start + rodata_no_reloc_ext_size; + uintptr_t noreloc_addr = (uintptr_t)&noreloc_data; + uintptr_t relocated_addr = (uintptr_t)&relocated_data; + + printk("noreloc at %p, relocated at %p, ELF: %p - %p\n", + (void *)noreloc_addr, (void *)relocated_addr, + (void *)elf_start, (void *)elf_end); + + /* Verify data is correct */ + zassert_equal(noreloc_data, 0x12345678, "noreloc_data value mismatch"); + + /* noreloc_data should stay in original ELF buffer */ + zassert_true(noreloc_addr >= elf_start && noreloc_addr < elf_end, + "noreloc_data should remain in ELF buffer"); + + /* relocated_data should be outside ELF buffer */ + zassert_true(relocated_addr < elf_start || relocated_addr >= elf_end, + "relocated_data should be outside ELF buffer"); +} +EXPORT_SYMBOL(test_entry); diff --git a/tests/subsys/llext/src/test_llext.c b/tests/subsys/llext/src/test_llext.c index 1ae98167d599..a7cf0032059f 100644 --- a/tests/subsys/llext/src/test_llext.c +++ b/tests/subsys/llext/src/test_llext.c @@ -332,6 +332,17 @@ static LLEXT_CONST uint8_t inspect_ext[] LLEXT_SECT ELF_ALIGN = { #include "inspect.inc" }; +#if defined(CONFIG_LLEXT_RODATA_NO_RELOC) +static LLEXT_CONST uint8_t rodata_no_reloc_ext[] ELF_ALIGN = { + #include "rodata_no_reloc.inc" +}; +const void *rodata_no_reloc_ext_ptr = rodata_no_reloc_ext; +EXPORT_SYMBOL(rodata_no_reloc_ext_ptr); +const size_t rodata_no_reloc_ext_size = sizeof(rodata_no_reloc_ext); +EXPORT_SYMBOL(rodata_no_reloc_ext_size); +LLEXT_LOAD_UNLOAD(rodata_no_reloc) +#endif + void do_inspect_checks(struct llext_loader *ldr, struct llext *ext, enum llext_mem reg_idx, const char *sect_name, const char *sym_name) { diff --git a/tests/subsys/llext/testcase.yaml b/tests/subsys/llext/testcase.yaml index 9377650e8f2f..3c6c939d19ff 100644 --- a/tests/subsys/llext/testcase.yaml +++ b/tests/subsys/llext/testcase.yaml @@ -44,6 +44,7 @@ tests: extra_conf_files: ['no_mem_protection.conf'] extra_configs: - CONFIG_LLEXT_STORAGE_WRITABLE=n + - CONFIG_LLEXT_RODATA_NO_RELOC=y llext.readonly_mpu: arch_allow: - arm # Xtensa needs writable storage, currently not supported on RISC-V @@ -64,6 +65,7 @@ tests: extra_configs: - CONFIG_LLEXT_HEAP_SIZE=128 # qemu_cortex_a9 requires larger heap - CONFIG_LLEXT_STORAGE_WRITABLE=n + - CONFIG_LLEXT_RODATA_NO_RELOC=y llext.writable: arch_allow: - arm From dbc30c5e2fbfca8365de436241b386206a5435bb Mon Sep 17 00:00:00 2001 From: Nikita Divakov Date: Thu, 11 Dec 2025 14:30:20 +0300 Subject: [PATCH 1844/3659] toolchain: gcc: iar: add ___in_section_unique() Macros __in_section_unique() and __in_section_unique_named() use ___in_section with __FILE__ argument to create a unique section name. Since __FILE__ is a string, calling Z_STRINGIFY(__FILE__) in ___in_section() causes double quotes in __FILE__ value to be masked. This prevents ld from matching section names output by this script. For example, when using CONFIG_CODE_DATA_RELOCATION to relocate a noinit section, __in_section_unique() generates the following section name: KEEP(*file.c.obj(.noinit."WEST_TOPDIR/path/file.c".symbol)) Besides, __FILE__ is used to create unique sections in two macros, so why not unify this approach. This fix adds ___in_section_unique() macro, which substitutes __FILE__ string into section name without additional stringification. Thus, resulting section is correctly matched by ld. Signed-off-by: Nikita Divakov --- include/zephyr/toolchain/gcc.h | 10 +++++++--- include/zephyr/toolchain/iar/iccarm.h | 10 +++++++--- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/include/zephyr/toolchain/gcc.h b/include/zephyr/toolchain/gcc.h index 899e245ed37f..044a8e52b784 100644 --- a/include/zephyr/toolchain/gcc.h +++ b/include/zephyr/toolchain/gcc.h @@ -200,13 +200,17 @@ do { \ "." Z_STRINGIFY(c)))) #define __in_section(a, b, c) ___in_section(a, b, c) +#define ___in_section_unique(a, b) \ + __attribute__((section("." Z_STRINGIFY(a) \ + "." __FILE__ \ + "." Z_STRINGIFY(b)))) + #ifndef __in_section_unique -#define __in_section_unique(seg) ___in_section(seg, __FILE__, __COUNTER__) +#define __in_section_unique(seg) ___in_section_unique(seg, __COUNTER__) #endif #ifndef __in_section_unique_named -#define __in_section_unique_named(seg, name) \ - ___in_section(seg, __FILE__, name) +#define __in_section_unique_named(seg, name) ___in_section_unique(seg, name) #endif /* When using XIP, using '__ramfunc' places a function into RAM instead diff --git a/include/zephyr/toolchain/iar/iccarm.h b/include/zephyr/toolchain/iar/iccarm.h index 8d197ddf04b5..3e117b1128e9 100644 --- a/include/zephyr/toolchain/iar/iccarm.h +++ b/include/zephyr/toolchain/iar/iccarm.h @@ -121,10 +121,14 @@ do { \ "." Z_STRINGIFY(c)))) #define __in_section(a, b, c) ___in_section(a, b, c) -#define __in_section_unique(seg) ___in_section(seg, __FILE__, __COUNTER__) +#define ___in_section_unique(a, b) \ + __attribute__((section("." Z_STRINGIFY(a) \ + "." __FILE__ \ + "." Z_STRINGIFY(b)))) -#define __in_section_unique_named(seg, name) \ - ___in_section(seg, __FILE__, name) +#define __in_section_unique(seg) ___in_section_unique(seg, __COUNTER__) + +#define __in_section_unique_named(seg, name) ___in_section_unique(seg, name) /* When using XIP, using '__ramfunc' places a function into RAM instead * of FLASH. Make sure '__ramfunc' is defined only when From b807da4f56ec3283474a1cc8219e13b2bb0fc0d2 Mon Sep 17 00:00:00 2001 From: Nikita Divakov Date: Thu, 11 Dec 2025 17:24:01 +0300 Subject: [PATCH 1845/3659] scripts: gen_relocate_app.py: add quotes around section names in templates Section names may contain paths to files with special characters. For example, a valid file path might contain '@'. Then using CONFIG_CODE_DATA_RELOCATION to relocate section, macro __in_section_unique() will generate section name like this: KEEP(*file.c.obj(.noinit.WEST_TOPDIR/path_with@char/file.c.0)) Such section names cannot be processed by ld because '@' is a special character for ld. This fix wraps section names in double quotes to escape special characters for ld. Signed-off-by: Nikita Divakov --- scripts/build/gen_relocate_app.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/build/gen_relocate_app.py b/scripts/build/gen_relocate_app.py index c1d26cf24050..e547af3449aa 100755 --- a/scripts/build/gen_relocate_app.py +++ b/scripts/build/gen_relocate_app.py @@ -101,11 +101,11 @@ class OutputSection(NamedTuple): PRINT_TEMPLATE = """ - KEEP(*{obj_file_name}({section_name})) + KEEP(*{obj_file_name}("{section_name}")) """ PRINT_TEMPLATE_NOKEEP = """ - *{obj_file_name}({section_name}) + *{obj_file_name}("{section_name}") """ SECTION_LOAD_MEMORY_SEQ = """ From d8b9b7ff33fbe0f0158a7e08503495b037aff21e Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Mon, 29 Dec 2025 14:46:03 +0000 Subject: [PATCH 1846/3659] samples: copy the button example into drivers/gpio/button_interrupt Make space for reworking the one in basic in the next commit. Signed-off-by: Fabio Baltieri --- .../gpio/button_interrupt/CMakeLists.txt | 7 ++ .../drivers/gpio/button_interrupt/README.rst | 110 ++++++++++++++++++ .../boards/bg27_rb4110b.overlay | 12 ++ .../boards/bg27_rb4111b.overlay | 12 ++ .../button_interrupt/boards/rd_rw612_bga.conf | 6 + .../boards/rd_rw612_bga.overlay | 9 ++ .../rzg3s_smarc_r9a08g045s33gbg_cm33.overlay | 12 ++ .../boards/slwrb4311a.overlay | 12 ++ .../boards/xgm240_rb4316a.overlay | 12 ++ .../boards/xgm240_rb4317a.overlay | 12 ++ .../drivers/gpio/button_interrupt/prj.conf | 1 + .../drivers/gpio/button_interrupt/sample.yaml | 12 ++ .../drivers/gpio/button_interrupt/src/main.c | 99 ++++++++++++++++ samples/drivers/gpio/index.rst | 5 + 14 files changed, 321 insertions(+) create mode 100644 samples/drivers/gpio/button_interrupt/CMakeLists.txt create mode 100644 samples/drivers/gpio/button_interrupt/README.rst create mode 100644 samples/drivers/gpio/button_interrupt/boards/bg27_rb4110b.overlay create mode 100644 samples/drivers/gpio/button_interrupt/boards/bg27_rb4111b.overlay create mode 100644 samples/drivers/gpio/button_interrupt/boards/rd_rw612_bga.conf create mode 100644 samples/drivers/gpio/button_interrupt/boards/rd_rw612_bga.overlay create mode 100644 samples/drivers/gpio/button_interrupt/boards/rzg3s_smarc_r9a08g045s33gbg_cm33.overlay create mode 100644 samples/drivers/gpio/button_interrupt/boards/slwrb4311a.overlay create mode 100644 samples/drivers/gpio/button_interrupt/boards/xgm240_rb4316a.overlay create mode 100644 samples/drivers/gpio/button_interrupt/boards/xgm240_rb4317a.overlay create mode 100644 samples/drivers/gpio/button_interrupt/prj.conf create mode 100644 samples/drivers/gpio/button_interrupt/sample.yaml create mode 100644 samples/drivers/gpio/button_interrupt/src/main.c create mode 100644 samples/drivers/gpio/index.rst diff --git a/samples/drivers/gpio/button_interrupt/CMakeLists.txt b/samples/drivers/gpio/button_interrupt/CMakeLists.txt new file mode 100644 index 000000000000..ed4d1f69e640 --- /dev/null +++ b/samples/drivers/gpio/button_interrupt/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(button_interrupt) + +target_sources(app PRIVATE src/main.c) diff --git a/samples/drivers/gpio/button_interrupt/README.rst b/samples/drivers/gpio/button_interrupt/README.rst new file mode 100644 index 000000000000..81d0da5579b6 --- /dev/null +++ b/samples/drivers/gpio/button_interrupt/README.rst @@ -0,0 +1,110 @@ +.. zephyr:code-sample:: button_interrupt + :name: Button interrupt + :relevant-api: gpio_interface + + Handle GPIO inputs with interrupts. + +Overview +******** + +A simple button demo showcasing the use of GPIO input with interrupts. +The sample prints a message to the console each time a button is pressed. + +Requirements +************ + +The board hardware must have a push button connected via a GPIO pin. These are +called "User buttons" on many of Zephyr's :ref:`boards`. + +The button must be configured using the ``sw0`` :ref:`devicetree ` +alias, usually in the :ref:`BOARD.dts file `. You will +see this error if you try to build this sample for an unsupported board: + +.. code-block:: none + + Unsupported board: sw0 devicetree alias is not defined + +You may see additional build errors if the ``sw0`` alias exists, but is not +properly defined. + +The sample additionally supports an optional ``led0`` devicetree alias. This is +the same alias used by the :zephyr:code-sample:`blinky` sample. If this is provided, the LED +will be turned on when the button is pressed, and turned off when it is +released. + +Devicetree details +================== + +This section provides more details on devicetree configuration. + +Here is a minimal devicetree fragment which supports this sample. This only +includes a ``sw0`` alias; the optional ``led0`` alias is left out for +simplicity. + +.. code-block:: devicetree + + / { + aliases { + sw0 = &button0; + }; + + soc { + gpio0: gpio@0 { + status = "okay"; + gpio-controller; + #gpio-cells = <2>; + /* ... */ + }; + }; + + buttons { + compatible = "gpio-keys"; + button0: button_0 { + gpios = < &gpio0 PIN FLAGS >; + label = "User button"; + }; + /* ... other buttons ... */ + }; + }; + +As shown, the ``sw0`` devicetree alias must point to a child node of a node +with a "gpio-keys" :ref:`compatible `. + +The above situation is for the common case where: + +- ``gpio0`` is an example node label referring to a GPIO controller +- ``PIN`` should be a pin number, like ``8`` or ``0`` +- ``FLAGS`` should be a logical OR of :ref:`GPIO configuration flags ` + meant to apply to the button, such as ``(GPIO_PULL_UP | GPIO_ACTIVE_LOW)`` + +This assumes the common case, where ``#gpio-cells = <2>`` in the ``gpio0`` +node, and that the GPIO controller's devicetree binding names those two cells +"pin" and "flags" like so: + +.. code-block:: yaml + + gpio-cells: + - pin + - flags + +This sample requires a ``pin`` cell in the ``gpios`` property. The ``flags`` +cell is optional, however, and the sample still works if the GPIO cells +do not contain ``flags``. + +Building and Running +******************** + +This sample can be built for multiple boards, in this example we will build it +for the nucleo_f103rb board: + +.. zephyr-app-commands:: + :zephyr-app: samples/drivers/gpio/button_interrupt + :board: nucleo_f103rb + :goals: build + :compact: + +After startup, the program looks up a predefined GPIO device, and configures the +pin in input mode, enabling interrupt generation on falling edge. During each +iteration of the main loop, the state of GPIO line is monitored and printed to +the serial console. When the input button gets pressed, the interrupt handler +will print an information about this event along with its timestamp. diff --git a/samples/drivers/gpio/button_interrupt/boards/bg27_rb4110b.overlay b/samples/drivers/gpio/button_interrupt/boards/bg27_rb4110b.overlay new file mode 100644 index 000000000000..58c02cf373ec --- /dev/null +++ b/samples/drivers/gpio/button_interrupt/boards/bg27_rb4110b.overlay @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2025 Silicon Laboratories Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + /* led0 interferes with sw0 since it uses the same pin */ + /delete-property/ led0; + }; +}; diff --git a/samples/drivers/gpio/button_interrupt/boards/bg27_rb4111b.overlay b/samples/drivers/gpio/button_interrupt/boards/bg27_rb4111b.overlay new file mode 100644 index 000000000000..58c02cf373ec --- /dev/null +++ b/samples/drivers/gpio/button_interrupt/boards/bg27_rb4111b.overlay @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2025 Silicon Laboratories Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + /* led0 interferes with sw0 since it uses the same pin */ + /delete-property/ led0; + }; +}; diff --git a/samples/drivers/gpio/button_interrupt/boards/rd_rw612_bga.conf b/samples/drivers/gpio/button_interrupt/boards/rd_rw612_bga.conf new file mode 100644 index 000000000000..b0995a93b88d --- /dev/null +++ b/samples/drivers/gpio/button_interrupt/boards/rd_rw612_bga.conf @@ -0,0 +1,6 @@ +# +# Copyright 2025 NXP +# +# SPDX-License-Identifier: Apache-2.0 +# +CONFIG_PM=y diff --git a/samples/drivers/gpio/button_interrupt/boards/rd_rw612_bga.overlay b/samples/drivers/gpio/button_interrupt/boards/rd_rw612_bga.overlay new file mode 100644 index 000000000000..65821c8b3eb5 --- /dev/null +++ b/samples/drivers/gpio/button_interrupt/boards/rd_rw612_bga.overlay @@ -0,0 +1,9 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&standby { + status = "okay"; +}; diff --git a/samples/drivers/gpio/button_interrupt/boards/rzg3s_smarc_r9a08g045s33gbg_cm33.overlay b/samples/drivers/gpio/button_interrupt/boards/rzg3s_smarc_r9a08g045s33gbg_cm33.overlay new file mode 100644 index 000000000000..89a6820cb9fc --- /dev/null +++ b/samples/drivers/gpio/button_interrupt/boards/rzg3s_smarc_r9a08g045s33gbg_cm33.overlay @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2024 Renesas Electronics Corporation + * SPDX-License-Identifier: Apache-2.0 + */ + +&gpio { + status = "okay"; +}; + +&gpio18 { + irqs = <0 16>; +}; diff --git a/samples/drivers/gpio/button_interrupt/boards/slwrb4311a.overlay b/samples/drivers/gpio/button_interrupt/boards/slwrb4311a.overlay new file mode 100644 index 000000000000..58c02cf373ec --- /dev/null +++ b/samples/drivers/gpio/button_interrupt/boards/slwrb4311a.overlay @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2025 Silicon Laboratories Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + /* led0 interferes with sw0 since it uses the same pin */ + /delete-property/ led0; + }; +}; diff --git a/samples/drivers/gpio/button_interrupt/boards/xgm240_rb4316a.overlay b/samples/drivers/gpio/button_interrupt/boards/xgm240_rb4316a.overlay new file mode 100644 index 000000000000..58c02cf373ec --- /dev/null +++ b/samples/drivers/gpio/button_interrupt/boards/xgm240_rb4316a.overlay @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2025 Silicon Laboratories Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + /* led0 interferes with sw0 since it uses the same pin */ + /delete-property/ led0; + }; +}; diff --git a/samples/drivers/gpio/button_interrupt/boards/xgm240_rb4317a.overlay b/samples/drivers/gpio/button_interrupt/boards/xgm240_rb4317a.overlay new file mode 100644 index 000000000000..58c02cf373ec --- /dev/null +++ b/samples/drivers/gpio/button_interrupt/boards/xgm240_rb4317a.overlay @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2025 Silicon Laboratories Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + /* led0 interferes with sw0 since it uses the same pin */ + /delete-property/ led0; + }; +}; diff --git a/samples/drivers/gpio/button_interrupt/prj.conf b/samples/drivers/gpio/button_interrupt/prj.conf new file mode 100644 index 000000000000..91c3c15b37d1 --- /dev/null +++ b/samples/drivers/gpio/button_interrupt/prj.conf @@ -0,0 +1 @@ +CONFIG_GPIO=y diff --git a/samples/drivers/gpio/button_interrupt/sample.yaml b/samples/drivers/gpio/button_interrupt/sample.yaml new file mode 100644 index 000000000000..df5840c1cb59 --- /dev/null +++ b/samples/drivers/gpio/button_interrupt/sample.yaml @@ -0,0 +1,12 @@ +sample: + name: Button interrupt sample +tests: + sample.gpio.button_interrupt: + tags: + - button + - gpio + filter: dt_enabled_alias_with_parent_compat("sw0", "gpio-keys") + integration_platforms: + - nrf52833dk/nrf52820 + depends_on: gpio + harness: button diff --git a/samples/drivers/gpio/button_interrupt/src/main.c b/samples/drivers/gpio/button_interrupt/src/main.c new file mode 100644 index 000000000000..a86407a65c25 --- /dev/null +++ b/samples/drivers/gpio/button_interrupt/src/main.c @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2016 Open-RnD Sp. z o.o. + * Copyright (c) 2020 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include + +#define SLEEP_TIME_MS 1 + +/* + * Get button configuration from the devicetree sw0 alias. This is mandatory. + */ +#define SW0_NODE DT_ALIAS(sw0) +#if !DT_NODE_HAS_STATUS_OKAY(SW0_NODE) +#error "Unsupported board: sw0 devicetree alias is not defined" +#endif +static const struct gpio_dt_spec button = GPIO_DT_SPEC_GET_OR(SW0_NODE, gpios, + {0}); +static struct gpio_callback button_cb_data; + +/* + * The led0 devicetree alias is optional. If present, we'll use it + * to turn on the LED whenever the button is pressed. + */ +static struct gpio_dt_spec led = GPIO_DT_SPEC_GET_OR(DT_ALIAS(led0), gpios, + {0}); + +void button_pressed(const struct device *dev, struct gpio_callback *cb, + uint32_t pins) +{ + printk("Button pressed at %" PRIu32 "\n", k_cycle_get_32()); +} + +int main(void) +{ + int ret; + + if (!gpio_is_ready_dt(&button)) { + printk("Error: button device %s is not ready\n", + button.port->name); + return 0; + } + + ret = gpio_pin_configure_dt(&button, GPIO_INPUT); + if (ret != 0) { + printk("Error %d: failed to configure %s pin %d\n", + ret, button.port->name, button.pin); + return 0; + } + + ret = gpio_pin_interrupt_configure_dt(&button, + GPIO_INT_EDGE_TO_ACTIVE); + if (ret != 0) { + printk("Error %d: failed to configure interrupt on %s pin %d\n", + ret, button.port->name, button.pin); + return 0; + } + + gpio_init_callback(&button_cb_data, button_pressed, BIT(button.pin)); + gpio_add_callback(button.port, &button_cb_data); + printk("Set up button at %s pin %d\n", button.port->name, button.pin); + + if (led.port && !gpio_is_ready_dt(&led)) { + printk("Error %d: LED device %s is not ready; ignoring it\n", + ret, led.port->name); + led.port = NULL; + } + if (led.port) { + ret = gpio_pin_configure_dt(&led, GPIO_OUTPUT); + if (ret != 0) { + printk("Error %d: failed to configure LED device %s pin %d\n", + ret, led.port->name, led.pin); + led.port = NULL; + } else { + printk("Set up LED at %s pin %d\n", led.port->name, led.pin); + } + } + + printk("Press the button\n"); + if (led.port) { + while (1) { + /* If we have an LED, match its state to the button's. */ + int val = gpio_pin_get_dt(&button); + + if (val >= 0) { + gpio_pin_set_dt(&led, val); + } + k_msleep(SLEEP_TIME_MS); + } + } + return 0; +} diff --git a/samples/drivers/gpio/index.rst b/samples/drivers/gpio/index.rst new file mode 100644 index 000000000000..f258ca9c0f91 --- /dev/null +++ b/samples/drivers/gpio/index.rst @@ -0,0 +1,5 @@ +.. zephyr:code-sample-category:: gpio + :name: General Purpose I/O (GPIO) + :show-listing: + + These samples demonstrate how to use the :ref:`GPIO ` driver API. From 68999e6fcf2e3a3389dd7361a0348e4aae20508c Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Mon, 29 Dec 2025 15:13:29 +0000 Subject: [PATCH 1847/3659] samples: button: rework to use the input and leds subsystem Rework the button sample to use the input subsystem for the button and LED subsystem for the LED. This is a better representation of how a button and LED should be controlled in Zephyr. Signed-off-by: Fabio Baltieri --- samples/basic/button/README.rst | 99 +++-------------------------- samples/basic/button/prj.conf | 2 + samples/basic/button/sample.yaml | 7 +-- samples/basic/button/src/main.c | 104 ++++++------------------------- 4 files changed, 33 insertions(+), 179 deletions(-) diff --git a/samples/basic/button/README.rst b/samples/basic/button/README.rst index 9e3cddca1bea..54eb1e72bf4e 100644 --- a/samples/basic/button/README.rst +++ b/samples/basic/button/README.rst @@ -1,99 +1,26 @@ .. zephyr:code-sample:: button :name: Button - :relevant-api: gpio_interface + :relevant-api: input_interface - Handle GPIO inputs with interrupts. + Handle GPIO button inputs using the input subsystem. Overview ******** -A simple button demo showcasing the use of GPIO input with interrupts. +A simple button demo showcasing the use of buttons with the :ref:`input` APIs. The sample prints a message to the console each time a button is pressed. -.. NOTE:: If you are looking into an implementation of button events with - debouncing, check out :ref:`input` and :zephyr:code-sample:`input-dump` - instead. - Requirements ************ -The board hardware must have a push button connected via a GPIO pin. These are -called "User buttons" on many of Zephyr's :ref:`boards`. - -The button must be configured using the ``sw0`` :ref:`devicetree ` -alias, usually in the :ref:`BOARD.dts file `. You will -see this error if you try to build this sample for an unsupported board: - -.. code-block:: none - - Unsupported board: sw0 devicetree alias is not defined - -You may see additional build errors if the ``sw0`` alias exists, but is not -properly defined. - -The sample additionally supports an optional ``led0`` devicetree alias. This is -the same alias used by the :zephyr:code-sample:`blinky` sample. If this is provided, the LED -will be turned on when the button is pressed, and turned off off when it is -released. - -Devicetree details -================== - -This section provides more details on devicetree configuration. - -Here is a minimal devicetree fragment which supports this sample. This only -includes a ``sw0`` alias; the optional ``led0`` alias is left out for -simplicity. - -.. code-block:: devicetree +The board hardware must have a device node capable of generating input KEY +events, typically a push button connected via a GPIO pin and defined in a +"gpio-keys" node. These are called "User buttons" on many of Zephyr's +:ref:`boards`. - / { - aliases { - sw0 = &button0; - }; - - soc { - gpio0: gpio@0 { - status = "okay"; - gpio-controller; - #gpio-cells = <2>; - /* ... */ - }; - }; - - buttons { - compatible = "gpio-keys"; - button0: button_0 { - gpios = < &gpio0 PIN FLAGS >; - label = "User button"; - }; - /* ... other buttons ... */ - }; - }; - -As shown, the ``sw0`` devicetree alias must point to a child node of a node -with a "gpio-keys" :ref:`compatible `. - -The above situation is for the common case where: - -- ``gpio0`` is an example node label referring to a GPIO controller -- ``PIN`` should be a pin number, like ``8`` or ``0`` -- ``FLAGS`` should be a logical OR of :ref:`GPIO configuration flags ` - meant to apply to the button, such as ``(GPIO_PULL_UP | GPIO_ACTIVE_LOW)`` - -This assumes the common case, where ``#gpio-cells = <2>`` in the ``gpio0`` -node, and that the GPIO controller's devicetree binding names those two cells -"pin" and "flags" like so: - -.. code-block:: yaml - - gpio-cells: - - pin - - flags - -This sample requires a ``pin`` cell in the ``gpios`` property. The ``flags`` -cell is optional, however, and the sample still works if the GPIO cells -do not contain ``flags``. +The sample additionally supports an optional ``led0`` devicetree alias. If this +is provided, the LED will be turned on when the button is pressed, and turned +off when it is released. Building and Running ******************** @@ -106,9 +33,3 @@ for the nucleo_f103rb board: :board: nucleo_f103rb :goals: build :compact: - -After startup, the program looks up a predefined GPIO device, and configures the -pin in input mode, enabling interrupt generation on falling edge. During each -iteration of the main loop, the state of GPIO line is monitored and printed to -the serial console. When the input button gets pressed, the interrupt handler -will print an information about this event along with its timestamp. diff --git a/samples/basic/button/prj.conf b/samples/basic/button/prj.conf index 91c3c15b37d1..bb33231dc3dd 100644 --- a/samples/basic/button/prj.conf +++ b/samples/basic/button/prj.conf @@ -1 +1,3 @@ CONFIG_GPIO=y +CONFIG_INPUT=y +CONFIG_LED=y diff --git a/samples/basic/button/sample.yaml b/samples/basic/button/sample.yaml index b2d76330fcf5..64fdf05055b4 100644 --- a/samples/basic/button/sample.yaml +++ b/samples/basic/button/sample.yaml @@ -2,11 +2,6 @@ sample: name: Button Sample tests: sample.basic.button: - tags: - - button - - gpio - filter: dt_enabled_alias_with_parent_compat("sw0", "gpio-keys") integration_platforms: - nrf52833dk/nrf52820 - depends_on: gpio - harness: button + build_only: true diff --git a/samples/basic/button/src/main.c b/samples/basic/button/src/main.c index 7c6ab66faa14..09be2d6fe7d0 100644 --- a/samples/basic/button/src/main.c +++ b/samples/basic/button/src/main.c @@ -1,103 +1,39 @@ /* - * Copyright (c) 2016 Open-RnD Sp. z o.o. - * Copyright (c) 2020 Nordic Semiconductor ASA - * + * SPDX-FileCopyrightText: Copyright The Zephyr Project Contributors * SPDX-License-Identifier: Apache-2.0 - * - * NOTE: If you are looking into an implementation of button events with - * debouncing, check out `input` subsystem and `samples/subsys/input/input_dump` - * example instead. */ +#include +#include +#include #include -#include -#include -#include #include -#include - -#define SLEEP_TIME_MS 1 - -/* - * Get button configuration from the devicetree sw0 alias. This is mandatory. - */ -#define SW0_NODE DT_ALIAS(sw0) -#if !DT_NODE_HAS_STATUS_OKAY(SW0_NODE) -#error "Unsupported board: sw0 devicetree alias is not defined" -#endif -static const struct gpio_dt_spec button = GPIO_DT_SPEC_GET_OR(SW0_NODE, gpios, - {0}); -static struct gpio_callback button_cb_data; -/* - * The led0 devicetree alias is optional. If present, we'll use it - * to turn on the LED whenever the button is pressed. - */ -static struct gpio_dt_spec led = GPIO_DT_SPEC_GET_OR(DT_ALIAS(led0), gpios, - {0}); - -void button_pressed(const struct device *dev, struct gpio_callback *cb, - uint32_t pins) -{ - printk("Button pressed at %" PRIu32 "\n", k_cycle_get_32()); -} +static const struct led_dt_spec led0 = LED_DT_SPEC_GET_OR(DT_ALIAS(led0), {0}); -int main(void) +static void button_input_cb(struct input_event *evt, void *user_data) { - int ret; - - if (!gpio_is_ready_dt(&button)) { - printk("Error: button device %s is not ready\n", - button.port->name); - return 0; + if (evt->sync == 0) { + return; } - ret = gpio_pin_configure_dt(&button, GPIO_INPUT); - if (ret != 0) { - printk("Error %d: failed to configure %s pin %d\n", - ret, button.port->name, button.pin); - return 0; - } + printk("Button %d %s at %" PRIu32 "\n", + evt->code, + evt->value ? "pressed" : "released", + k_cycle_get_32()); - ret = gpio_pin_interrupt_configure_dt(&button, - GPIO_INT_EDGE_TO_ACTIVE); - if (ret != 0) { - printk("Error %d: failed to configure interrupt on %s pin %d\n", - ret, button.port->name, button.pin); - return 0; + if (led0.dev != NULL) { + led_set_brightness_dt(&led0, evt->value ? 100 : 0); } +} - gpio_init_callback(&button_cb_data, button_pressed, BIT(button.pin)); - gpio_add_callback(button.port, &button_cb_data); - printk("Set up button at %s pin %d\n", button.port->name, button.pin); - - if (led.port && !gpio_is_ready_dt(&led)) { - printk("Error %d: LED device %s is not ready; ignoring it\n", - ret, led.port->name); - led.port = NULL; - } - if (led.port) { - ret = gpio_pin_configure_dt(&led, GPIO_OUTPUT); - if (ret != 0) { - printk("Error %d: failed to configure LED device %s pin %d\n", - ret, led.port->name, led.pin); - led.port = NULL; - } else { - printk("Set up LED at %s pin %d\n", led.port->name, led.pin); - } - } +INPUT_CALLBACK_DEFINE(NULL, button_input_cb, NULL); +int main(void) +{ printk("Press the button\n"); - if (led.port) { - while (1) { - /* If we have an LED, match its state to the button's. */ - int val = gpio_pin_get_dt(&button); - if (val >= 0) { - gpio_pin_set_dt(&led, val); - } - k_msleep(SLEEP_TIME_MS); - } - } + k_sleep(K_FOREVER); + return 0; } From 68cf4b7b506ac1a075ff0f9609758b213acd93f5 Mon Sep 17 00:00:00 2001 From: Axel Le Bourhis Date: Fri, 9 Jan 2026 14:43:53 +0100 Subject: [PATCH 1848/3659] hal_nxp: move connectivity_framework to mcux-sdk-ng integration Move the connectivity framework to the new mcux-sdk-ng integration from hal_nxp, instead of using the legacy integration method. This will allow for easier integration of future releases. Signed-off-by: Axel Le Bourhis --- .../middleware/connectivity_framework.cmake | 60 +++++++++++++++++++ .../mcux-sdk-ng/middleware/middleware.cmake | 2 + west.yml | 2 +- 3 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 modules/hal_nxp/mcux/mcux-sdk-ng/middleware/connectivity_framework.cmake diff --git a/modules/hal_nxp/mcux/mcux-sdk-ng/middleware/connectivity_framework.cmake b/modules/hal_nxp/mcux/mcux-sdk-ng/middleware/connectivity_framework.cmake new file mode 100644 index 000000000000..adbb584397d4 --- /dev/null +++ b/modules/hal_nxp/mcux/mcux-sdk-ng/middleware/connectivity_framework.cmake @@ -0,0 +1,60 @@ +if(CONFIG_SOC_SERIES_RW6XX) + if(CONFIG_NET_L2_OPENTHREAD OR CONFIG_NXP_NBU) + set(CONFIG_MCUX_COMPONENT_middleware.wireless.framework ON) + set(CONFIG_MCUX_COMPONENT_middleware.wireless.framework.platform ON) + set(CONFIG_MCUX_COMPONENT_middleware.wireless.framework.platform.ble ON) + set(CONFIG_MCUX_COMPONENT_middleware.wireless.framework.platform.ot ON) + set(CONFIG_MCUX_COMPONENT_middleware.wireless.framework.platform.hdlc ON) + set(CONFIG_MCUX_COMPONENT_middleware.wireless.framework.platform.coex ON) + set(CONFIG_MCUX_COMPONENT_middleware.wireless.framework.platform.rw61x ON) + + zephyr_compile_definitions(gPlatformDisableVendorSpecificInit=1U) + + if(CONFIG_NXP_MONOLITHIC_WIFI OR CONFIG_NXP_MONOLITHIC_NBU) + zephyr_compile_definitions( + gPlatformMonolithicApp_d=1U + fw_cpu2_ble=fw_cpu2 + fw_cpu2_combo=fw_cpu2 + ) + + zephyr_compile_definitions_ifndef(CONFIG_NXP_MONOLITHIC_NBU + BLE_FW_ADDRESS=0U + COMBO_FW_ADDRESS=0U) + + zephyr_compile_definitions_ifndef(CONFIG_NXP_MONOLITHIC_WIFI + WIFI_FW_ADDRESS=0U) + endif() + endif() +endif() + +if(CONFIG_SOC_SERIES_MCXW7XX) + if(CONFIG_NET_L2_OPENTHREAD OR CONFIG_NXP_NBU) + set(CONFIG_MCUX_COMPONENT_driver.spc ON) + set(CONFIG_USE_component_osa_zephyr ON) + set(CONFIG_MCUX_COMPONENT_middleware.wireless.framework ON) + set(CONFIG_MCUX_COMPONENT_middleware.wireless.framework.platform ON) + set(CONFIG_MCUX_COMPONENT_middleware.wireless.framework.function_lib ON) + set(CONFIG_MCUX_COMPONENT_middleware.wireless.framework.function_lib.use_toolchain_mem_function ON) + set(CONFIG_MCUX_COMPONENT_middleware.wireless.framework.platform.ics ON) + set(CONFIG_MCUX_COMPONENT_middleware.wireless.framework.platform.ble ON) + set(CONFIG_MCUX_COMPONENT_middleware.wireless.framework.platform.ot ON) + set_variable_ifdef(CONFIG_SOC_MCXW727C_CPU0 CONFIG_MCUX_COMPONENT_middleware.wireless.framework.platform.kw47_mcxw72) + set_variable_ifdef(CONFIG_SOC_MCXW716C CONFIG_MCUX_COMPONENT_middleware.wireless.framework.platform.kw45_k32w1_mcxw71) + endif() +endif() + +if(CONFIG_SOC_SERIES_MCXW2XX) + if(CONFIG_BT) + set(CONFIG_MCUX_COMPONENT_middleware.wireless.framework ON) + set(CONFIG_MCUX_COMPONENT_middleware.wireless.framework.platform ON) + set(CONFIG_MCUX_COMPONENT_middleware.wireless.framework.platform.mcxw23 ON) + set(CONFIG_MCUX_COMPONENT_middleware.wireless.framework.platform.ble ON) + endif() +endif() + +if(CONFIG_MCUX_COMPONENT_middleware.wireless.framework) + message(STATUS "connectivity_framework middleware is included.") + add_subdirectory(${MCUX_SDK_NG_DIR}/middleware/mcuxsdk-middleware-connectivity-framework + ${CMAKE_CURRENT_BINARY_DIR}/mcuxsdk-middleware-connectivity-framework + ) +endif() diff --git a/modules/hal_nxp/mcux/mcux-sdk-ng/middleware/middleware.cmake b/modules/hal_nxp/mcux/mcux-sdk-ng/middleware/middleware.cmake index 2bf1bfa84f86..f0ee5e0b233a 100644 --- a/modules/hal_nxp/mcux/mcux-sdk-ng/middleware/middleware.cmake +++ b/modules/hal_nxp/mcux/mcux-sdk-ng/middleware/middleware.cmake @@ -55,3 +55,5 @@ endif() add_subdirectory(${MCUX_SDK_NG_DIR}/middleware/usb ${CMAKE_CURRENT_BINARY_DIR}/usb ) + +include(${CMAKE_CURRENT_LIST_DIR}/connectivity_framework.cmake) diff --git a/west.yml b/west.yml index 275fbbf60f6a..ca5999498921 100644 --- a/west.yml +++ b/west.yml @@ -210,7 +210,7 @@ manifest: groups: - hal - name: hal_nxp - revision: 05702fcda8247876970f198669b72e3a8c99f6e5 + revision: 9424596b87f119f5e4049855e9a73eb16efd2c80 path: modules/hal/nxp groups: - hal From f6adcad1a6cb308e9c725b2129129561b40c9596 Mon Sep 17 00:00:00 2001 From: Sylvio Alves Date: Mon, 12 Jan 2026 13:16:10 -0300 Subject: [PATCH 1849/3659] drivers: wifi: esp32: fix AP mode MAC address mismatch When ESP32 operates in AP-only mode the network interface is initialized with the STA MAC address, but the Wi-Fi hardware operates with the AP MAC address (typically STA MAC + 1). Some Wi-Fi clients correctly address frames to the AP MAC, causing them to be dropped by the ethernet L2 layer with "Dropping frame, not for me" because the interface link address doesn't match. Fix this by updating the interface link address to the AP MAC when enabling AP mode, and restoring the STA MAC when disabling AP mode. Signed-off-by: Sylvio Alves --- drivers/wifi/esp32/src/esp_wifi_drv.c | 31 +++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/drivers/wifi/esp32/src/esp_wifi_drv.c b/drivers/wifi/esp32/src/esp_wifi_drv.c index 40633c15c167..10436e207150 100644 --- a/drivers/wifi/esp32/src/esp_wifi_drv.c +++ b/drivers/wifi/esp32/src/esp_wifi_drv.c @@ -667,6 +667,7 @@ static int esp32_wifi_ap_enable(const struct device *dev, struct wifi_connect_req_params *params) { struct esp32_wifi_runtime *data = dev->data; + struct net_if *iface = net_if_lookup_by_dev(dev); esp_err_t err = 0; /* Build Wi-Fi configuration for AP mode */ @@ -729,11 +730,32 @@ static int esp32_wifi_ap_enable(const struct device *dev, return -EAGAIN; } + /* + * Update interface link address to AP MAC. + * In AP-only mode (without CONFIG_ESP32_WIFI_AP_STA_MODE), the interface + * is initialized with STA MAC but operates with AP MAC. Some clients + * correctly address frames to AP MAC, which would be dropped without + * this update. See: https://github.com/zephyrproject-rtos/zephyr/issues/101761 + */ +#if !defined(CONFIG_ESP32_WIFI_AP_STA_MODE) + esp_read_mac(data->mac_addr, ESP_MAC_WIFI_SOFTAP); + net_if_carrier_off(iface); + net_if_set_link_addr(iface, data->mac_addr, NET_ETH_ADDR_LEN, + NET_LINK_ETHERNET); + net_if_carrier_on(iface); +#else + ARG_UNUSED(iface); +#endif + return 0; }; static int esp32_wifi_ap_disable(const struct device *dev) { +#if !defined(CONFIG_ESP32_WIFI_AP_STA_MODE) + struct esp32_wifi_runtime *data = dev->data; + struct net_if *iface = net_if_lookup_by_dev(dev); +#endif int err = 0; wifi_mode_t mode; @@ -749,6 +771,15 @@ static int esp32_wifi_ap_disable(const struct device *dev) return -EAGAIN; } + /* Restore interface link address to STA MAC when AP mode is disabled */ +#if !defined(CONFIG_ESP32_WIFI_AP_STA_MODE) + esp_read_mac(data->mac_addr, ESP_MAC_WIFI_STA); + net_if_carrier_off(iface); + net_if_set_link_addr(iface, data->mac_addr, NET_ETH_ADDR_LEN, + NET_LINK_ETHERNET); + net_if_carrier_on(iface); +#endif + return 0; }; From 060682fb8dadcf30e75989968fb7164987972cd1 Mon Sep 17 00:00:00 2001 From: Marcin Niestroj Date: Tue, 16 Dec 2025 09:18:15 +0100 Subject: [PATCH 1850/3659] drivers: nsos: release socket lock while polling So far using recvfrom() and send() from two different threads was not possible, since thread attempting send() was blocked by the thread executing recvfrom(). All other APIs were also blocking each other, while it was not necessary. One example use case in Zephyr tree is MCUMGR SMP over UDP implementation, which resuled in communication timeouts. Release socket lock while actively polling, so other APIs executed from other threads can safely progress. Do this using k_condvar_wait() API with socket mutex, so that mutex is safely released and reaquired during wait. Signed-off-by: Marcin Niestroj --- drivers/net/nsos_sockets.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/drivers/net/nsos_sockets.c b/drivers/net/nsos_sockets.c index b822ea05b2d2..4233ecce8496 100644 --- a/drivers/net/nsos_sockets.c +++ b/drivers/net/nsos_sockets.c @@ -46,6 +46,7 @@ struct nsos_socket; struct nsos_socket_poll { struct nsos_mid_pollfd mid; struct k_poll_signal signal; + struct k_condvar *cond; sys_dnode_t node; }; @@ -287,6 +288,10 @@ static void pollcb(struct nsos_mid_pollfd *mid) struct nsos_socket_poll *poll = CONTAINER_OF(mid, struct nsos_socket_poll, mid); k_poll_signal_raise(&poll->signal, poll->mid.revents); + + if (poll->cond) { + k_condvar_signal(poll->cond); + } } static int nsos_poll_prepare(struct nsos_socket *sock, struct zsock_pollfd *pfd, @@ -568,9 +573,22 @@ static int nsos_wait_for_poll(struct nsos_socket *sock, int 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 = {}; + struct k_mutex *lock = NULL; + struct k_condvar cond; + struct nsos_socket_poll socket_poll = { + .cond = &cond, + }; + bool lock_acquired; int ret; + lock_acquired = zvfs_get_obj_lock_and_cond(sock, + &nsos_socket_fd_op_vtable.fd_vtable, + &lock, NULL); + __ASSERT(lock_acquired, "zvfs_get_obj_lock_and_cond() failed"); + __ASSERT_NO_MSG(lock != NULL); + + k_condvar_init(&cond); + ret = nsos_adapt_dup(sock->poll.mid.fd); if (ret < 0) { goto return_ret; @@ -586,7 +604,7 @@ static int nsos_wait_for_poll(struct nsos_socket *sock, int events, goto close_dup; } - ret = k_poll(poll_events, ARRAY_SIZE(poll_events), timeout); + ret = k_condvar_wait(&cond, lock, timeout); if (ret != 0 && ret != -EAGAIN && ret != -EINTR) { goto poll_update; } From 32823f39fbf2663fa1bbb75e60e5743cd6d91579 Mon Sep 17 00:00:00 2001 From: Andrej Butok Date: Tue, 13 Jan 2026 16:17:48 +0100 Subject: [PATCH 1851/3659] boards: mikroe: move the hexiwear board - The vendor of the hexiwear board is mikroe (not nxp) https://www.mikroe.com/hexiwear. - Move the board files from 'nxp' to 'mikroe'. - Delete hexiwear from the nxp maintained board list. - Update paths in the documentation. Signed-off-by: Andrej Butok --- MAINTAINERS.yml | 1 - boards/{nxp => mikroe}/hexiwear/Kconfig.defconfig | 0 boards/{nxp => mikroe}/hexiwear/Kconfig.hexiwear | 0 boards/{nxp => mikroe}/hexiwear/board.cmake | 0 boards/{nxp => mikroe}/hexiwear/board.yml | 2 +- .../{nxp => mikroe}/hexiwear/doc/hexiwear_k64.jpg | Bin boards/{nxp => mikroe}/hexiwear/doc/index.rst | 6 ++---- .../hexiwear/hexiwear_mk64f12-pinctrl.dtsi | 0 .../{nxp => mikroe}/hexiwear/hexiwear_mk64f12.dts | 2 +- .../{nxp => mikroe}/hexiwear/hexiwear_mk64f12.yaml | 2 +- .../hexiwear/hexiwear_mk64f12_defconfig | 0 .../hexiwear/hexiwear_mkw40z4-pinctrl.dtsi | 0 .../{nxp => mikroe}/hexiwear/hexiwear_mkw40z4.dts | 0 .../{nxp => mikroe}/hexiwear/hexiwear_mkw40z4.yaml | 2 +- .../hexiwear/hexiwear_mkw40z4_defconfig | 0 doc/_scripts/redirects.py | 1 + doc/hardware/porting/board_porting.rst | 2 +- samples/basic/rgb_led/README.rst | 2 +- 18 files changed, 9 insertions(+), 11 deletions(-) rename boards/{nxp => mikroe}/hexiwear/Kconfig.defconfig (100%) rename boards/{nxp => mikroe}/hexiwear/Kconfig.hexiwear (100%) rename boards/{nxp => mikroe}/hexiwear/board.cmake (100%) rename boards/{nxp => mikroe}/hexiwear/board.yml (84%) rename boards/{nxp => mikroe}/hexiwear/doc/hexiwear_k64.jpg (100%) rename boards/{nxp => mikroe}/hexiwear/doc/index.rst (99%) rename boards/{nxp => mikroe}/hexiwear/hexiwear_mk64f12-pinctrl.dtsi (100%) rename boards/{nxp => mikroe}/hexiwear/hexiwear_mk64f12.dts (98%) rename boards/{nxp => mikroe}/hexiwear/hexiwear_mk64f12.yaml (92%) rename boards/{nxp => mikroe}/hexiwear/hexiwear_mk64f12_defconfig (100%) rename boards/{nxp => mikroe}/hexiwear/hexiwear_mkw40z4-pinctrl.dtsi (100%) rename boards/{nxp => mikroe}/hexiwear/hexiwear_mkw40z4.dts (100%) rename boards/{nxp => mikroe}/hexiwear/hexiwear_mkw40z4.yaml (91%) rename boards/{nxp => mikroe}/hexiwear/hexiwear_mkw40z4_defconfig (100%) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index 848b34d3a264..2d8c0ee1ee8f 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -3610,7 +3610,6 @@ NXP Platforms (MCU): - boards/nxp/lpcxpress*/ - boards/nxp/twr_*/ - boards/nxp/*rw*/ - - boards/nxp/hexiwear/ - boards/nxp/common/ - boards/nxp/* - soc/nxp/common/ diff --git a/boards/nxp/hexiwear/Kconfig.defconfig b/boards/mikroe/hexiwear/Kconfig.defconfig similarity index 100% rename from boards/nxp/hexiwear/Kconfig.defconfig rename to boards/mikroe/hexiwear/Kconfig.defconfig diff --git a/boards/nxp/hexiwear/Kconfig.hexiwear b/boards/mikroe/hexiwear/Kconfig.hexiwear similarity index 100% rename from boards/nxp/hexiwear/Kconfig.hexiwear rename to boards/mikroe/hexiwear/Kconfig.hexiwear diff --git a/boards/nxp/hexiwear/board.cmake b/boards/mikroe/hexiwear/board.cmake similarity index 100% rename from boards/nxp/hexiwear/board.cmake rename to boards/mikroe/hexiwear/board.cmake diff --git a/boards/nxp/hexiwear/board.yml b/boards/mikroe/hexiwear/board.yml similarity index 84% rename from boards/nxp/hexiwear/board.yml rename to boards/mikroe/hexiwear/board.yml index 63a0e80de9ad..9ae1a49cc20c 100644 --- a/boards/nxp/hexiwear/board.yml +++ b/boards/mikroe/hexiwear/board.yml @@ -1,7 +1,7 @@ board: name: hexiwear full_name: Hexiwear - vendor: nxp + vendor: mikroe socs: - name: mk64f12 - name: mkw40z4 diff --git a/boards/nxp/hexiwear/doc/hexiwear_k64.jpg b/boards/mikroe/hexiwear/doc/hexiwear_k64.jpg similarity index 100% rename from boards/nxp/hexiwear/doc/hexiwear_k64.jpg rename to boards/mikroe/hexiwear/doc/hexiwear_k64.jpg diff --git a/boards/nxp/hexiwear/doc/index.rst b/boards/mikroe/hexiwear/doc/index.rst similarity index 99% rename from boards/nxp/hexiwear/doc/index.rst rename to boards/mikroe/hexiwear/doc/index.rst index bb77f1ce0fa2..ad17c98f294a 100644 --- a/boards/nxp/hexiwear/doc/index.rst +++ b/boards/mikroe/hexiwear/doc/index.rst @@ -94,7 +94,7 @@ The hexiwear/mk64f12 board variant supports the following hardware features: The default configuration can be found in the defconfig file: - :zephyr_file:`boards/nxp/hexiwear/hexiwear_mk64f12_defconfig` + :zephyr_file:`boards/mikroe/hexiwear/hexiwear_mk64f12_defconfig` Other hardware features are not currently supported by the port. @@ -381,7 +381,7 @@ The hexiwear/mkw40z4 board variant supports the following hardware features: The default configuration can be found in the defconfig file: - :zephyr_file:`boards/nxp/hexiwear/hexiwear_mkw40z4_defconfig` + :zephyr_file:`boards/mikroe/hexiwear/hexiwear_mkw40z4_defconfig` Other hardware features are not currently supported by the port. @@ -501,8 +501,6 @@ you should see the following message in the terminal: ***** Booting Zephyr OS v1.14.0-rc1 ***** Hello World! hexiwear -.. include:: ../../common/board-footer.rst.inc - .. _KW40Z Website: https://www.nxp.com/products/processors-and-microcontrollers/arm-based-processors-and-mcus/kinetis-cortex-m-mcus/w-serieswireless-conn.m0-plus-m4/kinetis-kw40z-2.4-ghz-dual-mode-ble-and-802.15.4-wireless-radio-microcontroller-mcu-based-on-arm-cortex-m0-plus-core:KW40Z diff --git a/boards/nxp/hexiwear/hexiwear_mk64f12-pinctrl.dtsi b/boards/mikroe/hexiwear/hexiwear_mk64f12-pinctrl.dtsi similarity index 100% rename from boards/nxp/hexiwear/hexiwear_mk64f12-pinctrl.dtsi rename to boards/mikroe/hexiwear/hexiwear_mk64f12-pinctrl.dtsi diff --git a/boards/nxp/hexiwear/hexiwear_mk64f12.dts b/boards/mikroe/hexiwear/hexiwear_mk64f12.dts similarity index 98% rename from boards/nxp/hexiwear/hexiwear_mk64f12.dts rename to boards/mikroe/hexiwear/hexiwear_mk64f12.dts index 6ac4661aebd0..fd55fb0a89a3 100644 --- a/boards/nxp/hexiwear/hexiwear_mk64f12.dts +++ b/boards/mikroe/hexiwear/hexiwear_mk64f12.dts @@ -13,7 +13,7 @@ / { model = "Hexiwear K64 board"; - compatible = "nxp,hexiwear", "nxp,k64f", "nxp,k6x"; + compatible = "mikroe,hexiwear", "nxp,k64f", "nxp,k6x"; aliases { led0 = &green_led; diff --git a/boards/nxp/hexiwear/hexiwear_mk64f12.yaml b/boards/mikroe/hexiwear/hexiwear_mk64f12.yaml similarity index 92% rename from boards/nxp/hexiwear/hexiwear_mk64f12.yaml rename to boards/mikroe/hexiwear/hexiwear_mk64f12.yaml index f545c591d96f..171032e915a7 100644 --- a/boards/nxp/hexiwear/hexiwear_mk64f12.yaml +++ b/boards/mikroe/hexiwear/hexiwear_mk64f12.yaml @@ -13,4 +13,4 @@ supported: - i2c - pwm - watchdog -vendor: nxp +vendor: mikroe diff --git a/boards/nxp/hexiwear/hexiwear_mk64f12_defconfig b/boards/mikroe/hexiwear/hexiwear_mk64f12_defconfig similarity index 100% rename from boards/nxp/hexiwear/hexiwear_mk64f12_defconfig rename to boards/mikroe/hexiwear/hexiwear_mk64f12_defconfig diff --git a/boards/nxp/hexiwear/hexiwear_mkw40z4-pinctrl.dtsi b/boards/mikroe/hexiwear/hexiwear_mkw40z4-pinctrl.dtsi similarity index 100% rename from boards/nxp/hexiwear/hexiwear_mkw40z4-pinctrl.dtsi rename to boards/mikroe/hexiwear/hexiwear_mkw40z4-pinctrl.dtsi diff --git a/boards/nxp/hexiwear/hexiwear_mkw40z4.dts b/boards/mikroe/hexiwear/hexiwear_mkw40z4.dts similarity index 100% rename from boards/nxp/hexiwear/hexiwear_mkw40z4.dts rename to boards/mikroe/hexiwear/hexiwear_mkw40z4.dts diff --git a/boards/nxp/hexiwear/hexiwear_mkw40z4.yaml b/boards/mikroe/hexiwear/hexiwear_mkw40z4.yaml similarity index 91% rename from boards/nxp/hexiwear/hexiwear_mkw40z4.yaml rename to boards/mikroe/hexiwear/hexiwear_mkw40z4.yaml index e0e49ea82e99..f7cea0894c0a 100644 --- a/boards/nxp/hexiwear/hexiwear_mkw40z4.yaml +++ b/boards/mikroe/hexiwear/hexiwear_mkw40z4.yaml @@ -10,4 +10,4 @@ toolchain: testing: ignore_tags: - net -vendor: nxp +vendor: mikroe diff --git a/boards/nxp/hexiwear/hexiwear_mkw40z4_defconfig b/boards/mikroe/hexiwear/hexiwear_mkw40z4_defconfig similarity index 100% rename from boards/nxp/hexiwear/hexiwear_mkw40z4_defconfig rename to boards/mikroe/hexiwear/hexiwear_mkw40z4_defconfig diff --git a/doc/_scripts/redirects.py b/doc/_scripts/redirects.py index 72d34f9b4325..bee8ac631129 100644 --- a/doc/_scripts/redirects.py +++ b/doc/_scripts/redirects.py @@ -20,6 +20,7 @@ ('boards/arm/fvp_baser_aemv8r/doc/aarch64', 'boards/arm/fvp_baser_aemv8r/doc/index'), ('boards/arm/fvp_baser_aemv8r/doc/debug-with-arm-ds', 'boards/arm/fvp_baser_aemv8r/doc/index'), ('boards/nordic/nrf54l20pdk/doc/index', 'boards/nordic/nrf54lm20dk/doc/index'), + ('boards/nxp/hexiwear/doc/index', 'boards/mikroe/hexiwear/doc/index'), ('boards/panasonic/panb511evb/doc/index', 'boards/panasonic/panb611evb/doc/index'), ('boards/phytec/mimx8mm_phyboard_polis/doc/index', 'boards/phytec/phyboard_polis/doc/index'), ('boards/phytec/mimx8mp_phyboard_pollux/doc/index', 'boards/phytec/phyboard_pollux/doc/index'), diff --git a/doc/hardware/porting/board_porting.rst b/doc/hardware/porting/board_porting.rst index bdc11cc5e6c1..f5f05cb32a5d 100644 --- a/doc/hardware/porting/board_porting.rst +++ b/doc/hardware/porting/board_porting.rst @@ -443,7 +443,7 @@ devicetree. The FRDM-K64F and Hexiwear K64 board devicetrees are defined in :zephyr_file:`frdm_k64fs.dts ` and -:zephyr_file:`hexiwear_k64.dts ` +:zephyr_file:`hexiwear_k64.dts ` respectively. Both boards have NXP SoCs from the same Kinetis SoC family, the K6X. diff --git a/samples/basic/rgb_led/README.rst b/samples/basic/rgb_led/README.rst index b3dca648d570..2613d098d520 100644 --- a/samples/basic/rgb_led/README.rst +++ b/samples/basic/rgb_led/README.rst @@ -39,7 +39,7 @@ an unsupported board: Unsupported board: green-pwm-led devicetree alias is not defined Unsupported board: blue-pwm-led devicetree alias is not defined -See :zephyr_file:`boards/nxp/hexiwear/hexiwear_mk64f12.dts` for an example +See :zephyr_file:`boards/mikroe/hexiwear/hexiwear_mk64f12.dts` for an example :file:`BOARD.dts` file which supports this sample. Wiring From 678adcd77b1951fb72f37a232bbabd1a8ad92d1a Mon Sep 17 00:00:00 2001 From: Yves Wang Date: Wed, 14 Jan 2026 12:29:42 +0800 Subject: [PATCH 1852/3659] MAINTAINER: Add yvesll as Watchdog Collaborator Add yvesll as Watchdog Collaborator Signed-off-by: Yves Wang --- MAINTAINERS.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index 2d8c0ee1ee8f..49e74a6ee84d 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -2586,6 +2586,7 @@ Documentation Infrastructure: collaborators: - katsuster - martinjaeger + - yvesll files: - doc/hardware/peripherals/watchdog.rst - drivers/watchdog/ From 9541db5f9c2249062381ddf57e68101d55d52972 Mon Sep 17 00:00:00 2001 From: Laura Carlesso Date: Tue, 13 Jan 2026 15:12:55 -0800 Subject: [PATCH 1853/3659] tests: drivers: gpio: gpio_basic_api: Updated pins for cy8cproto_063_ble Updated pins for the gpio basic tests for cy8cproto_063_ble to pins not used by other tests so that a single board can be wired for all tests without overlaps. Signed-off-by: Laura Carlesso --- .../gpio/gpio_basic_api/boards/cy8cproto_063_ble.overlay | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/drivers/gpio/gpio_basic_api/boards/cy8cproto_063_ble.overlay b/tests/drivers/gpio/gpio_basic_api/boards/cy8cproto_063_ble.overlay index a01e0d692c5b..76350810c2b6 100644 --- a/tests/drivers/gpio/gpio_basic_api/boards/cy8cproto_063_ble.overlay +++ b/tests/drivers/gpio/gpio_basic_api/boards/cy8cproto_063_ble.overlay @@ -8,8 +8,8 @@ / { resources { compatible = "test-gpio-basic-api"; - out-gpios = <&gpio_prt9 4 0>; - in-gpios = <&gpio_prt9 2 0>; + out-gpios = <&gpio_prt12 6 0>; + in-gpios = <&gpio_prt12 7 0>; }; }; From f69cb628686158c3cc8fe549780447646558d048 Mon Sep 17 00:00:00 2001 From: Derek Snell Date: Tue, 13 Jan 2026 17:26:54 -0500 Subject: [PATCH 1854/3659] maintainers: add DerekSnell as collaborator to NXP Platforms (MCU) Signed-off-by: Derek Snell --- MAINTAINERS.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index 49e74a6ee84d..5e942ab46f30 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -3604,6 +3604,7 @@ NXP Platforms (MCU): - mmahadevan108 collaborators: - butok + - DerekSnell files: - boards/nxp/mimxrt*/ - boards/nxp/frdm*/ From 6d7b8b6b2d9951f5797a5de2f60c14143e87cc6d Mon Sep 17 00:00:00 2001 From: Tom Hughes Date: Tue, 13 Jan 2026 11:32:15 -0800 Subject: [PATCH 1855/3659] drivers: gpio: max14906: Fix initialization Found when building with clang with -Winitializer-overrides: drivers/gpio/gpio_max14906.c:495:29: error: initializer overrides prior initialization of this subobject [-Werror,-Winitializer-overrides] 495 | DT_INST_FOREACH_STATUS_OKAY(GPIO_MAX14906_DEVICE) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~ Signed-off-by: Tom Hughes --- drivers/gpio/gpio_max14906.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpio/gpio_max14906.c b/drivers/gpio/gpio_max14906.c index 0753e2a459e5..8f3f8f8947b5 100644 --- a/drivers/gpio/gpio_max14906.c +++ b/drivers/gpio/gpio_max14906.c @@ -471,9 +471,9 @@ static DEVICE_API(gpio, gpio_max14906_api) = { .OW_OFF_EN3 = DT_INST_PROP_BY_IDX(id, ow_en, 2), \ .OW_OFF_EN4 = DT_INST_PROP_BY_IDX(id, ow_en, 3), \ .GDRV_EN1 = DT_INST_PROP_BY_IDX(id, gdrv_en, 0), \ - .GDRV_EN1 = DT_INST_PROP_BY_IDX(id, gdrv_en, 1), \ - .GDRV_EN2 = DT_INST_PROP_BY_IDX(id, gdrv_en, 2), \ - .GDRV_EN3 = DT_INST_PROP_BY_IDX(id, gdrv_en, 3), \ + .GDRV_EN2 = DT_INST_PROP_BY_IDX(id, gdrv_en, 1), \ + .GDRV_EN3 = DT_INST_PROP_BY_IDX(id, gdrv_en, 2), \ + .GDRV_EN4 = DT_INST_PROP_BY_IDX(id, gdrv_en, 3), \ }, \ .chan_en.sht_vdd_en.reg_bits = \ { \ From a893e1dccfc59e4daa4f4a2dbbec70cae0e2cce9 Mon Sep 17 00:00:00 2001 From: Christopher Hofmeister Date: Tue, 13 Jan 2026 13:37:08 -0600 Subject: [PATCH 1856/3659] boards: silabs: siwx917_dk2605a: fix LED polarity Fix incorrect LED polarity definitions for the SiWx917 DK. The user LEDs on the SiWx917 DK are wired as active-low according to the board schematic, but were previously defined as GPIO_ACTIVE_HIGH. Update the devicetree LED gpio definitions to GPIO_ACTIVE_LOW so LED behavior matches the hardware and sample applications behave as expected. Signed-off-by: Christopher Hofmeister --- boards/silabs/dev_kits/siwx917_dk2605a/siwx917_dk2605a.dts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/boards/silabs/dev_kits/siwx917_dk2605a/siwx917_dk2605a.dts b/boards/silabs/dev_kits/siwx917_dk2605a/siwx917_dk2605a.dts index f1e0e5fffccf..32e3365cb2b9 100644 --- a/boards/silabs/dev_kits/siwx917_dk2605a/siwx917_dk2605a.dts +++ b/boards/silabs/dev_kits/siwx917_dk2605a/siwx917_dk2605a.dts @@ -39,17 +39,17 @@ compatible = "gpio-leds"; led0: led_0 { - gpios = <&gpioa 15 GPIO_ACTIVE_HIGH>; + gpios = <&gpioa 15 GPIO_ACTIVE_LOW>; label = "LED0"; }; led1: led_1 { - gpios = <&gpiod 2 GPIO_ACTIVE_HIGH>; + gpios = <&gpiod 2 GPIO_ACTIVE_LOW>; label = "LED1"; }; led2: led_2 { - gpios = <&gpiod 3 GPIO_ACTIVE_HIGH>; + gpios = <&gpiod 3 GPIO_ACTIVE_LOW>; label = "LED2"; }; }; From 1c353a3924375408edb5e4f25e52a8434673c057 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Thu, 15 Jan 2026 12:15:03 +0000 Subject: [PATCH 1857/3659] ci: twister_tests_blackbox: filter the toolchain list Only install arm, riscv and x86 toolchains for the twister blackbox workflow, save some space. Signed-off-by: Fabio Baltieri --- .github/workflows/twister_tests_blackbox.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/twister_tests_blackbox.yml b/.github/workflows/twister_tests_blackbox.yml index 58c010faf3a8..4cd8f3531215 100644 --- a/.github/workflows/twister_tests_blackbox.yml +++ b/.github/workflows/twister_tests_blackbox.yml @@ -48,7 +48,7 @@ jobs: uses: zephyrproject-rtos/action-zephyr-setup@cefbf9086ce2da7d70e7ad9589af8aa1e4bda265 # v1.0.11 with: app-path: zephyr - toolchains: all + toolchains: 'arm-zephyr-eabi:riscv64-zephyr-elf:x86_64-zephyr-elf' enable-ccache: false west-group-filter: -tools,-bootloader,-babblesim,-hal west-project-filter: -nrf_hw_models,+cmsis,+hal_xtensa,+cmsis_6 From 13eeffbc4bc51766fdcd53a15635263f71829301 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Tue, 13 Jan 2026 17:11:36 +0000 Subject: [PATCH 1858/3659] samples: mgmt: mcumgr: smp_svr: Document/rename UDP DTLS file Renames the UDP DTLS Kconfig fragment file, due to wrongly using an underscore instead of a dash like the other Kconfig fragments, and also documents how to use it in the readme Signed-off-by: Jamie McCrae --- samples/subsys/mgmt/mcumgr/smp_svr/README.rst | 11 +++++++++++ samples/subsys/mgmt/mcumgr/smp_svr/sample.yaml | 4 ++-- .../mcumgr/smp_svr/{udp_dtls.conf => udp-dtls.conf} | 0 3 files changed, 13 insertions(+), 2 deletions(-) rename samples/subsys/mgmt/mcumgr/smp_svr/{udp_dtls.conf => udp-dtls.conf} (100%) diff --git a/samples/subsys/mgmt/mcumgr/smp_svr/README.rst b/samples/subsys/mgmt/mcumgr/smp_svr/README.rst index 2314ff87fa42..9e4972aee23e 100644 --- a/samples/subsys/mgmt/mcumgr/smp_svr/README.rst +++ b/samples/subsys/mgmt/mcumgr/smp_svr/README.rst @@ -145,6 +145,17 @@ included. The ``smp_svr`` sample comes in different flavours. :gen-args: -DEXTRA_CONF_FILE="overlay-udp.conf;802154-subg.conf" :compact: + To build the UDP with DTLS sample: + + .. zephyr-app-commands:: + :tool: west + :zephyr-app: samples/subsys/mgmt/mcumgr/smp_svr + :board: bl5340_dvk/nrf5340/cpuapp + :goals: build + :west-args: --sysbuild + :gen-args: -DEXTRA_CONF_FILE="udp-dtls.conf" + :compact: + Flashing the sample image ************************* diff --git a/samples/subsys/mgmt/mcumgr/smp_svr/sample.yaml b/samples/subsys/mgmt/mcumgr/smp_svr/sample.yaml index 6be485e0e5ce..2632530fc2b4 100644 --- a/samples/subsys/mgmt/mcumgr/smp_svr/sample.yaml +++ b/samples/subsys/mgmt/mcumgr/smp_svr/sample.yaml @@ -37,9 +37,9 @@ tests: - frdm_k64f integration_platforms: - frdm_k64f - sample.mcumgr.smp_svr.udp_dtls: + sample.mcumgr.smp_svr.udp-dtls: extra_args: - - EXTRA_CONF_FILE="udp_dtls.conf" + - EXTRA_CONF_FILE="udp-dtls.conf" - CONFIG_IMG_MANAGER=n - SB_CONFIG_BOOTLOADER_NONE=y platform_allow: diff --git a/samples/subsys/mgmt/mcumgr/smp_svr/udp_dtls.conf b/samples/subsys/mgmt/mcumgr/smp_svr/udp-dtls.conf similarity index 100% rename from samples/subsys/mgmt/mcumgr/smp_svr/udp_dtls.conf rename to samples/subsys/mgmt/mcumgr/smp_svr/udp-dtls.conf From a159d0ee0351a6a43a188b15d06f88ac00527735 Mon Sep 17 00:00:00 2001 From: Andrew Davis Date: Thu, 18 Dec 2025 11:47:42 -0600 Subject: [PATCH 1859/3659] soc: ti: k3: Add support for AM62L The TI AM62L is a low-power ARM Cortex-A53 based SoC with display for IOT, HMI and general purpose applications. More information here: https://www.ti.com/product/AM62L Add initial SoC and DTS support here. Signed-off-by: Andrew Davis --- dts/arm64/ti/am62l3_a53.dtsi | 173 +++++++++++++++++++ dts/vendor/ti/am62l-main.dtsi | 283 ++++++++++++++++++++++++++++++++ dts/vendor/ti/am62l-wakeup.dtsi | 56 +++++++ soc/ti/k3/am6x/CMakeLists.txt | 2 +- soc/ti/k3/am6x/Kconfig | 1 + soc/ti/k3/am6x/Kconfig.soc | 5 + soc/ti/k3/soc.yml | 3 + 7 files changed, 522 insertions(+), 1 deletion(-) create mode 100644 dts/arm64/ti/am62l3_a53.dtsi create mode 100644 dts/vendor/ti/am62l-main.dtsi create mode 100644 dts/vendor/ti/am62l-wakeup.dtsi diff --git a/dts/arm64/ti/am62l3_a53.dtsi b/dts/arm64/ti/am62l3_a53.dtsi new file mode 100644 index 000000000000..fa450878fc87 --- /dev/null +++ b/dts/arm64/ti/am62l3_a53.dtsi @@ -0,0 +1,173 @@ +/* + * Copyright (C) 2025 Texas Instruments Incorporated - https://www.ti.com/ + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/ { + #address-cells = <1>; + #size-cells = <1>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a53"; + reg = <0>; + }; + + cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a53"; + reg = <1>; + }; + }; + + firmware { + psci: psci { + compatible = "arm,psci-1.1"; + method = "smc"; + }; + + scmi { + compatible = "arm,scmi-smc"; + arm,smc-id = <0x82004000>; + shmem = <&scmi_shmem>; + + #address-cells = <1>; + #size-cells = <0>; + + scmi_pds: protocol@11 { + compatible = "arm,scmi-power"; + reg = <0x11>; + #power-domain-cells = <1>; + }; + + scmi_clk: protocol@14 { + compatible = "arm,scmi-clock"; + reg = <0x14>; + #clock-cells = <1>; + }; + }; + }; + + oc_sram: sram@70800000 { + compatible = "mmio-sram"; + reg = <0x70800000 DT_SIZE_K(64)>; + ranges = <0x0 0x70800000 0x10000>; + #address-cells = <1>; + #size-cells = <1>; + + scmi_shmem: sram@0 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0x100>; + }; + }; + + arch_timer: timer { + compatible = "arm,armv8-timer"; + interrupts = , + , + , + ; + interrupt-parent = <&gic>; + }; + + gic: interrupt-controller@1800000 { + compatible = "arm,gic-v3", "arm,gic"; + reg = <0x01800000 0x10000>, /* GICD */ + <0x01840000 0xc0000>; /* GICR */ + interrupt-controller; + #interrupt-cells = <4>; + #address-cells = <1>; + #size-cells = <1>; + status = "okay"; + + its: msi-controller@1820000 { + compatible = "arm,gic-v3-its"; + reg = <0x01820000 0x10000>; + status = "okay"; + }; + }; +}; + +&wkup_timer0 { + interrupts = ; + interrupt-parent = <&gic>; +}; + +&wkup_timer1 { + interrupts = ; + interrupt-parent = <&gic>; +}; + +&wkup_i2c0 { + interrupts = ; + interrupt-parent = <&gic>; +}; + +&main_uart0 { + interrupts = ; + interrupt-parent = <&gic>; +}; + +&main_uart1 { + interrupts = ; + interrupt-parent = <&gic>; +}; + +&main_uart2 { + interrupts = ; + interrupt-parent = <&gic>; +}; + +&main_uart3 { + interrupts = ; + interrupt-parent = <&gic>; +}; + +&main_uart4 { + interrupts = ; + interrupt-parent = <&gic>; +}; + +&main_uart5 { + interrupts = ; + interrupt-parent = <&gic>; +}; + +&main_uart6 { + interrupts = ; + interrupt-parent = <&gic>; +}; + +&main_i2c0 { + interrupts = ; + interrupt-parent = <&gic>; +}; + +&main_i2c1 { + interrupts = ; + interrupt-parent = <&gic>; +}; + +&main_i2c2 { + interrupts = ; + interrupt-parent = <&gic>; +}; + +&main_i2c3 { + interrupts = ; + interrupt-parent = <&gic>; +}; diff --git a/dts/vendor/ti/am62l-main.dtsi b/dts/vendor/ti/am62l-main.dtsi new file mode 100644 index 000000000000..c1e42304a49f --- /dev/null +++ b/dts/vendor/ti/am62l-main.dtsi @@ -0,0 +1,283 @@ +/* + * Device Tree Source for AM62L SoC Family Main Domain peripherals + * + * Copyright (C) 2025 Texas Instruments Incorporated - https://www.ti.com/ + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + main_uart0: serial@2800000 { + compatible = "ns16550"; + reg = <0x02800000 0x100>; + clock-frequency = <48000000>; + current-speed = <115200>; + reg-shift = <2>; + status = "disabled"; + }; + + main_uart1: serial@2810000 { + compatible = "ns16550"; + reg = <0x02810000 0x100>; + clock-frequency = <48000000>; + current-speed = <115200>; + reg-shift = <2>; + status = "disabled"; + }; + + main_uart2: serial@2820000 { + compatible = "ns16550"; + reg = <0x02820000 0x100>; + clock-frequency = <48000000>; + current-speed = <115200>; + reg-shift = <2>; + status = "disabled"; + }; + + main_uart3: serial@2830000 { + compatible = "ns16550"; + reg = <0x02830000 0x100>; + clock-frequency = <48000000>; + current-speed = <115200>; + reg-shift = <2>; + status = "disabled"; + }; + + main_uart4: serial@2840000 { + compatible = "ns16550"; + reg = <0x02840000 0x100>; + clock-frequency = <48000000>; + current-speed = <115200>; + reg-shift = <2>; + status = "disabled"; + }; + + main_uart5: serial@2850000 { + compatible = "ns16550"; + reg = <0x02850000 0x100>; + clock-frequency = <48000000>; + current-speed = <115200>; + reg-shift = <2>; + status = "disabled"; + }; + + main_uart6: serial@2860000 { + compatible = "ns16550"; + reg = <0x02860000 0x100>; + clock-frequency = <48000000>; + current-speed = <115200>; + reg-shift = <2>; + status = "disabled"; + }; + + main_i2c0: i2c@20000000 { + compatible = "ti,omap-i2c"; + reg = <0x20000000 0x100>; + clock-frequency = <100000>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + main_i2c1: i2c@20010000 { + compatible = "ti,omap-i2c"; + reg = <0x20010000 0x100>; + clock-frequency = <100000>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + main_i2c2: i2c@20020000 { + compatible = "ti,omap-i2c"; + reg = <0x20020000 0x100>; + clock-frequency = <100000>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + main_i2c3: i2c@20030000 { + compatible = "ti,omap-i2c"; + reg = <0x20030000 0x100>; + clock-frequency = <100000>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + main_gpio0: main-gpio0 { + #gpio-cells = <2>; + gpio-map = <0 0 &main_gpio0_0 0 0>, <1 0 &main_gpio0_0 1 0>, + <2 0 &main_gpio0_0 2 0>, <3 0 &main_gpio0_0 3 0>, + <4 0 &main_gpio0_0 4 0>, <5 0 &main_gpio0_0 5 0>, + <6 0 &main_gpio0_0 6 0>, <7 0 &main_gpio0_0 7 0>, + <8 0 &main_gpio0_0 8 0>, <9 0 &main_gpio0_0 9 0>, + <10 0 &main_gpio0_0 10 0>, <11 0 &main_gpio0_0 11 0>, + <12 0 &main_gpio0_0 12 0>, <13 0 &main_gpio0_0 13 0>, + <14 0 &main_gpio0_0 14 0>, <15 0 &main_gpio0_0 15 0>, + <16 0 &main_gpio0_0 16 0>, <17 0 &main_gpio0_0 17 0>, + <18 0 &main_gpio0_0 18 0>, <19 0 &main_gpio0_0 19 0>, + <20 0 &main_gpio0_0 20 0>, <21 0 &main_gpio0_0 21 0>, + <22 0 &main_gpio0_0 22 0>, <23 0 &main_gpio0_0 23 0>, + <24 0 &main_gpio0_0 24 0>, <25 0 &main_gpio0_0 25 0>, + <26 0 &main_gpio0_0 26 0>, <27 0 &main_gpio0_0 27 0>, + <28 0 &main_gpio0_0 28 0>, <29 0 &main_gpio0_0 29 0>, + <30 0 &main_gpio0_0 30 0>, <31 0 &main_gpio0_0 31 0>, + <32 0 &main_gpio0_1 0 0>, <33 0 &main_gpio0_1 1 0>, + <34 0 &main_gpio0_1 2 0>, <35 0 &main_gpio0_1 3 0>, + <36 0 &main_gpio0_1 4 0>, <37 0 &main_gpio0_1 5 0>, + <38 0 &main_gpio0_1 6 0>, <39 0 &main_gpio0_1 7 0>, + <40 0 &main_gpio0_1 8 0>, <41 0 &main_gpio0_1 9 0>, + <42 0 &main_gpio0_1 10 0>, <43 0 &main_gpio0_1 11 0>, + <44 0 &main_gpio0_1 12 0>, <45 0 &main_gpio0_1 13 0>, + <46 0 &main_gpio0_1 14 0>, <47 0 &main_gpio0_1 15 0>, + <48 0 &main_gpio0_1 16 0>, <49 0 &main_gpio0_1 17 0>, + <50 0 &main_gpio0_1 18 0>, <51 0 &main_gpio0_1 19 0>, + <52 0 &main_gpio0_1 20 0>, <53 0 &main_gpio0_1 21 0>, + <54 0 &main_gpio0_1 22 0>, <55 0 &main_gpio0_1 23 0>, + <56 0 &main_gpio0_1 24 0>, <57 0 &main_gpio0_1 25 0>, + <58 0 &main_gpio0_1 26 0>, <59 0 &main_gpio0_1 27 0>, + <60 0 &main_gpio0_1 28 0>, <61 0 &main_gpio0_1 29 0>, + <62 0 &main_gpio0_1 30 0>, <63 0 &main_gpio0_1 31 0>, + <64 0 &main_gpio0_2 0 0>, <65 0 &main_gpio0_2 1 0>, + <66 0 &main_gpio0_2 2 0>, <67 0 &main_gpio0_2 3 0>, + <68 0 &main_gpio0_2 4 0>, <69 0 &main_gpio0_2 5 0>, + <70 0 &main_gpio0_2 6 0>, <71 0 &main_gpio0_2 7 0>, + <72 0 &main_gpio0_2 8 0>, <73 0 &main_gpio0_2 9 0>, + <74 0 &main_gpio0_2 10 0>, <75 0 &main_gpio0_2 11 0>, + <76 0 &main_gpio0_2 12 0>, <77 0 &main_gpio0_2 13 0>, + <78 0 &main_gpio0_2 14 0>, <79 0 &main_gpio0_2 15 0>, + <80 0 &main_gpio0_2 16 0>, <81 0 &main_gpio0_2 17 0>, + <82 0 &main_gpio0_2 18 0>, <83 0 &main_gpio0_2 17 0>, + <84 0 &main_gpio0_2 20 0>, <85 0 &main_gpio0_2 21 0>, + <86 0 &main_gpio0_2 22 0>, <87 0 &main_gpio0_2 23 0>, + <88 0 &main_gpio0_2 24 0>, <89 0 &main_gpio0_2 25 0>, + <90 0 &main_gpio0_2 26 0>, <91 0 &main_gpio0_2 27 0>, + <92 0 &main_gpio0_2 28 0>, <93 0 &main_gpio0_2 29 0>, + <94 0 &main_gpio0_2 30 0>, <95 0 &main_gpio0_2 31 0>, + <96 0 &main_gpio0_3 0 0>, <97 0 &main_gpio0_3 1 0>, + <98 0 &main_gpio0_3 2 0>, <99 0 &main_gpio0_3 3 0>, + <100 0 &main_gpio0_3 4 0>, <101 0 &main_gpio0_3 5 0>, + <102 0 &main_gpio0_3 6 0>, <103 0 &main_gpio0_3 7 0>, + <104 0 &main_gpio0_3 8 0>, <105 0 &main_gpio0_3 9 0>, + <106 0 &main_gpio0_3 10 0>, <107 0 &main_gpio0_3 11 0>, + <108 0 &main_gpio0_3 12 0>, <109 0 &main_gpio0_3 13 0>, + <110 0 &main_gpio0_3 14 0>, <111 0 &main_gpio0_3 15 0>, + <112 0 &main_gpio0_3 16 0>, <113 0 &main_gpio0_3 17 0>, + <114 0 &main_gpio0_3 18 0>, <115 0 &main_gpio0_3 17 0>, + <116 0 &main_gpio0_3 20 0>, <117 0 &main_gpio0_3 21 0>, + <118 0 &main_gpio0_3 22 0>, <119 0 &main_gpio0_3 23 0>, + <120 0 &main_gpio0_3 24 0>, <121 0 &main_gpio0_3 25 0>, + <122 0 &main_gpio0_3 26 0>, <123 0 &main_gpio0_3 27 0>, + <124 0 &main_gpio0_3 28 0>, <125 0 &main_gpio0_3 29 0>; + gpio-map-mask = <0xffff 0x0>; + gpio-map-pass-thru = <0x0 0x1>; + }; + + main_gpio0_0: gpio@600010 { + compatible = "ti,davinci-gpio"; + reg = <0x00600010 0x28>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <32>; + status = "disabled"; + }; + + main_gpio0_1: gpio@600038 { + compatible = "ti,davinci-gpio"; + reg = <0x00600038 0x28>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <32>; + status = "disabled"; + }; + + main_gpio0_2: gpio@600060 { + compatible = "ti,davinci-gpio"; + reg = <0x00600060 0x28>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <32>; + status = "disabled"; + }; + + main_gpio0_3: gpio@600088 { + compatible = "ti,davinci-gpio"; + reg = <0x00600088 0x28>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <30>; + status = "disabled"; + }; + + main_rti0: watchdog@e000000 { + compatible = "ti,j7-rti-wdt"; + reg = <0x0e000000 0x100>; + clock-frequency = ; + status = "disabled"; + }; + + main_rti1: watchdog@e010000 { + compatible = "ti,j7-rti-wdt"; + reg = <0x0e010000 0x100>; + clock-frequency = ; + status = "disabled"; + }; + + main_spi0: spi@20100000 { + compatible = "ti,omap-mcspi"; + reg = <0x20100000 0x400>; + interrupts = ; + interrupt-parent = <&gic>; + #address-cells = <1>; + #size-cells = <0>; + power-domains = <&scmi_pds 72>; + clock-frequency = ; + clocks = <&scmi_clk 299>; + ti,spi-num-cs = <4>; + status = "disabled"; + }; + + main_spi1: spi@20110000 { + compatible = "ti,omap-mcspi"; + reg = <0x20110000 0x400>; + interrupts = ; + interrupt-parent = <&gic>; + #address-cells = <1>; + #size-cells = <0>; + power-domains = <&scmi_pds 73>; + clock-frequency = ; + clocks = <&scmi_clk 302>; + ti,spi-num-cs = <4>; + status = "disabled"; + }; + + main_spi2: spi@20120000 { + compatible = "ti,omap-mcspi"; + reg = <0x20120000 0x400>; + interrupts = ; + interrupt-parent = <&gic>; + #address-cells = <1>; + #size-cells = <0>; + power-domains = <&scmi_pds 74>; + clock-frequency = ; + clocks = <&scmi_clk 305>; + ti,spi-num-cs = <4>; + status = "disabled"; + }; + + main_spi3: spi@20130000 { + compatible = "ti,omap-mcspi"; + reg = <0x20130000 0x400>; + interrupts = ; + interrupt-parent = <&gic>; + #address-cells = <1>; + #size-cells = <0>; + power-domains = <&scmi_pds 75>; + clock-frequency = ; + clocks = <&scmi_clk 308>; + ti,spi-num-cs = <4>; + status = "disabled"; + }; +}; diff --git a/dts/vendor/ti/am62l-wakeup.dtsi b/dts/vendor/ti/am62l-wakeup.dtsi new file mode 100644 index 000000000000..b583b6522056 --- /dev/null +++ b/dts/vendor/ti/am62l-wakeup.dtsi @@ -0,0 +1,56 @@ +/* + * Device Tree Source for AM62L SoC Family Wakeup Domain peripherals + * + * Copyright (C) 2025 Texas Instruments Incorporated - https://www.ti.com/ + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + wkup_pinctrl: pinctrl@4084000 { + compatible = "ti,k3-pinctrl"; + reg = <0x04084000 0x24c>; + status = "disabled"; + }; + + wkup_gpio0: gpio@4201010 { + compatible = "ti,davinci-gpio"; + reg = <0x04201010 0x28>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <7>; + power-domains = <&scmi_pds 36>; + clocks = <&scmi_clk 146>; + clock-names = "gpio"; + status = "disabled"; + }; + + wkup_timer0: timer@2b100000 { + compatible = "ti,am654-timer"; + reg = <0x2b100000 DT_SIZE_K(1)>; + clocks = <&scmi_clk 93>; + clock-names = "fck"; + power-domains = <&scmi_pds 19>; + status = "disabled"; + }; + + wkup_timer1: timer@2b110000 { + compatible = "ti,am654-timer"; + reg = <0x2b110000 DT_SIZE_K(1)>; + clocks = <&scmi_clk 98>; + clock-names = "fck"; + power-domains = <&scmi_pds 20>; + status = "disabled"; + }; + + wkup_i2c0: i2c@2b200000 { + compatible = "ti,omap-i2c"; + reg = <0x2b200000 0x100>; + #address-cells = <1>; + #size-cells = <0>; + power-domains = <&scmi_pds 57>; + clocks = <&scmi_clk 262>; + clock-names = "fck"; + status = "disabled"; + }; +}; diff --git a/soc/ti/k3/am6x/CMakeLists.txt b/soc/ti/k3/am6x/CMakeLists.txt index c20bed681437..206e041f725c 100644 --- a/soc/ti/k3/am6x/CMakeLists.txt +++ b/soc/ti/k3/am6x/CMakeLists.txt @@ -4,7 +4,7 @@ zephyr_include_directories(.) zephyr_sources(common/ctrl_partitions.c) -if(CONFIG_SOC_AM6234_A53 OR CONFIG_SOC_AM6232_A53 OR CONFIG_SOC_AM6254_A53) +if(CONFIG_SOC_AM6234_A53 OR CONFIG_SOC_AM6232_A53 OR CONFIG_SOC_AM6254_A53 OR CONFIG_SOC_AM62L3_A53) zephyr_sources_ifdef(CONFIG_ARM_MMU a53/mmu_regions.c) set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm64/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/ti/k3/am6x/Kconfig b/soc/ti/k3/am6x/Kconfig index 2950d7cdfa71..be4796dcca98 100644 --- a/soc/ti/k3/am6x/Kconfig +++ b/soc/ti/k3/am6x/Kconfig @@ -39,6 +39,7 @@ config SOC_PART_NUMBER default "AM6234" if SOC_AM6234_A53 default "AM6234" if SOC_AM6234_M4 default "AM6254" if SOC_AM6254_M4 || SOC_AM6254_A53 + default "AM62L3" if SOC_AM62L3_A53 default "AM6442" if SOC_AM6442_M4 default "AM6442" if SOC_AM6442_R5F0_0 default "AM6442" if SOC_AM6442_R5F0_1 diff --git a/soc/ti/k3/am6x/Kconfig.soc b/soc/ti/k3/am6x/Kconfig.soc index dae5216d5531..054215d6e513 100644 --- a/soc/ti/k3/am6x/Kconfig.soc +++ b/soc/ti/k3/am6x/Kconfig.soc @@ -47,6 +47,10 @@ config SOC_AM6232_M4 bool select SOC_SERIES_AM6X_M4 +config SOC_AM62L3_A53 + bool + select SOC_SERIES_AM6X_A53 + config SOC_AM6442_M4 bool select SOC_SERIES_AM6X_M4 @@ -95,6 +99,7 @@ config SOC default "am6232" if SOC_AM6232_M4 || SOC_AM6232_A53 default "am6234" if SOC_AM6234_M4 || SOC_AM6234_A53 default "am6254" if SOC_AM6254_M4 || SOC_AM6254_A53 + default "am62l3" if SOC_AM62L3_A53 default "am6442" if SOC_AM6442_M4 default "am6442" if SOC_AM6442_R5F0_0 default "am6442" if SOC_AM6442_R5F0_1 diff --git a/soc/ti/k3/soc.yml b/soc/ti/k3/soc.yml index 7234dacefa01..3f2cb22e156d 100644 --- a/soc/ti/k3/soc.yml +++ b/soc/ti/k3/soc.yml @@ -15,6 +15,9 @@ family: cpuclusters: - name: m4 - name: a53 + - name: am62l3 + cpuclusters: + - name: a53 - name: am6442 cpuclusters: - name: m4 From 9c3343d00fa208f495a3723f8bf84ec76990dd8c Mon Sep 17 00:00:00 2001 From: Andrew Davis Date: Tue, 23 Dec 2025 15:16:21 -0600 Subject: [PATCH 1860/3659] boards: ti: Add support for the AM62L EVM The AM62L evaluation module (TMDS62LEVM) is designed for low-cost and performance optimized AM62L family of application processors. More information here: https://www.ti.com/tool/TMDS62LEVM Add base board support here. Signed-off-by: Andrew Davis --- boards/ti/am62l_evm/Kconfig.am62l_evm | 8 ++ .../am62l_evm_am62l3_a53-pinctrl.dtsi | 17 +++ boards/ti/am62l_evm/am62l_evm_am62l3_a53.dts | 43 +++++++ boards/ti/am62l_evm/am62l_evm_am62l3_a53.yaml | 15 +++ .../am62l_evm/am62l_evm_am62l3_a53_defconfig | 32 +++++ boards/ti/am62l_evm/board.yml | 6 + boards/ti/am62l_evm/doc/img/am62l_evm.webp | Bin 0 -> 20988 bytes boards/ti/am62l_evm/doc/index.rst | 109 ++++++++++++++++++ 8 files changed, 230 insertions(+) create mode 100644 boards/ti/am62l_evm/Kconfig.am62l_evm create mode 100644 boards/ti/am62l_evm/am62l_evm_am62l3_a53-pinctrl.dtsi create mode 100644 boards/ti/am62l_evm/am62l_evm_am62l3_a53.dts create mode 100644 boards/ti/am62l_evm/am62l_evm_am62l3_a53.yaml create mode 100644 boards/ti/am62l_evm/am62l_evm_am62l3_a53_defconfig create mode 100644 boards/ti/am62l_evm/board.yml create mode 100644 boards/ti/am62l_evm/doc/img/am62l_evm.webp create mode 100644 boards/ti/am62l_evm/doc/index.rst diff --git a/boards/ti/am62l_evm/Kconfig.am62l_evm b/boards/ti/am62l_evm/Kconfig.am62l_evm new file mode 100644 index 000000000000..05a9d9425ab4 --- /dev/null +++ b/boards/ti/am62l_evm/Kconfig.am62l_evm @@ -0,0 +1,8 @@ +# Texas Instruments Sitara AM62L EVM +# +# Copyright (c) 2025 Texas Instruments Incorporated +# +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_AM62L_EVM + select SOC_AM62L3_A53 diff --git a/boards/ti/am62l_evm/am62l_evm_am62l3_a53-pinctrl.dtsi b/boards/ti/am62l_evm/am62l_evm_am62l3_a53-pinctrl.dtsi new file mode 100644 index 000000000000..16a3351009fb --- /dev/null +++ b/boards/ti/am62l_evm/am62l_evm_am62l3_a53-pinctrl.dtsi @@ -0,0 +1,17 @@ +/* + * Copyright (C) 2025 Texas Instruments Incorporated - https://www.ti.com/ + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&wkup_pinctrl { + status = "okay"; + + uart0_rx_default: uart0_rx_default { + pinmux = ; /* (D13) UART0_RXD */ + }; + + uart0_tx_default: uart0_tx_default { + pinmux = ; /* (C13) UART0_TXD */ + }; +}; diff --git a/boards/ti/am62l_evm/am62l_evm_am62l3_a53.dts b/boards/ti/am62l_evm/am62l_evm_am62l3_a53.dts new file mode 100644 index 000000000000..3c9170c6c30a --- /dev/null +++ b/boards/ti/am62l_evm/am62l_evm_am62l3_a53.dts @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2025 Texas Instruments Incorporated - https://www.ti.com/ + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include "am62l_evm_am62l3_a53-pinctrl.dtsi" + +/ { + model = "TI AM62L EVALUATION MODULE (EVM)"; + compatible = "ti,am62l_evm"; + + chosen { + zephyr,console = &main_uart0; + zephyr,shell-uart = &main_uart0; + zephyr,sram = &ddr0; + }; + + cpus { + cpu@0 { + status = "okay"; + }; + + cpu@1 { + status = "okay"; + }; + }; + + ddr0: memory@82000000 { + reg = <0x82000000 (DT_SIZE_G(2) - DT_SIZE_M(32))>; + }; +}; + +&main_uart0 { + current-speed = <115200>; + pinctrl-0 = <&uart0_rx_default>, + <&uart0_tx_default>; + pinctrl-names = "default"; + status = "okay"; +}; diff --git a/boards/ti/am62l_evm/am62l_evm_am62l3_a53.yaml b/boards/ti/am62l_evm/am62l_evm_am62l3_a53.yaml new file mode 100644 index 000000000000..6d469560df03 --- /dev/null +++ b/boards/ti/am62l_evm/am62l_evm_am62l3_a53.yaml @@ -0,0 +1,15 @@ +identifier: am62l_evm/am62l3/a53 +name: TI AM62L Evaluation Module (EVM) +type: mcu +arch: arm64 +toolchain: + - zephyr + - cross-compile +ram: 2048 +supported: + - uart +testing: + ignore_tags: + - net + - bluetooth +vendor: ti diff --git a/boards/ti/am62l_evm/am62l_evm_am62l3_a53_defconfig b/boards/ti/am62l_evm/am62l_evm_am62l3_a53_defconfig new file mode 100644 index 000000000000..fb49deec39fc --- /dev/null +++ b/boards/ti/am62l_evm/am62l_evm_am62l3_a53_defconfig @@ -0,0 +1,32 @@ +# Texas Instruments Sitara AM62L EVM +# +# Copyright (c) 2025 Texas Instruments Incorporated +# +# SPDX-License-Identifier: Apache-2.0 + +# Zephyr Kernel Configuration +CONFIG_XIP=n + +# Serial Driver +CONFIG_SERIAL=y + +# Enable Console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_UART_INTERRUPT_DRIVEN=y + +# ARM Options +CONFIG_AARCH64_IMAGE_HEADER=y +CONFIG_ARMV8_A_NS=y +CONFIG_ARM64_VA_BITS_36=y +CONFIG_ARM64_PA_BITS_36=y + +# Cache Options +CONFIG_CACHE_MANAGEMENT=y +CONFIG_DCACHE_LINE_SIZE_DETECT=y +CONFIG_ICACHE_LINE_SIZE_DETECT=y + +# Multicore Support +CONFIG_SMP=y +CONFIG_PM_CPU_OPS=y +CONFIG_MP_MAX_NUM_CPUS=2 diff --git a/boards/ti/am62l_evm/board.yml b/boards/ti/am62l_evm/board.yml new file mode 100644 index 000000000000..c42a8cc6ed73 --- /dev/null +++ b/boards/ti/am62l_evm/board.yml @@ -0,0 +1,6 @@ +board: + name: am62l_evm + full_name: AM62L TMDS62LEVM evaluation module (EVM) + vendor: ti + socs: + - name: am62l3 diff --git a/boards/ti/am62l_evm/doc/img/am62l_evm.webp b/boards/ti/am62l_evm/doc/img/am62l_evm.webp new file mode 100644 index 0000000000000000000000000000000000000000..d9245a843127911b5dae674fc2b05c7a97cdacc8 GIT binary patch literal 20988 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 c%aNzR000000000007oV2&;S4c literal 0 HcmV?d00001 diff --git a/boards/ti/am62l_evm/doc/index.rst b/boards/ti/am62l_evm/doc/index.rst new file mode 100644 index 000000000000..211843dc20c2 --- /dev/null +++ b/boards/ti/am62l_evm/doc/index.rst @@ -0,0 +1,109 @@ +.. zephyr:board:: am62l_evm + +Overview +******** + +The AM62L EVM board configuration is used by Zephyr applications that run on +the TI AM62L platform. The board configuration provides support for: + +- ARM Cortex-A53 core and the following features: + + - General Interrupt Controller (GIC) + - ARM Generic Timer (arch_timer) + - On-chip SRAM (oc_sram) + - UART interfaces (uart0 to uart6) + +The board configuration also enables support for the semihosting debugging console. + +See the `TI AM62L Product Page`_ for details. + +Hardware +******** +The AM62L EVM features the AM62L SoC, which is composed of a dual Cortex-A53 +cluster. The following listed hardware specifications are used: + +- High-performance ARM Cortex-A53 +- Memory + + - 160KB of SRAM + - 2GB of DDR4 + +- Debug + + - XDS110 based JTAG + +Supported Features +================== + +.. zephyr:board-supported-hw:: + +Devices +======== +System Clock +------------ + +This board configuration uses a system clock frequency of 1250 MHz. + +DDR RAM +------- + +The board has 2GB of DDR RAM available. + +Serial Port +----------- + +This board configuration uses a single serial communication channel with the +MAIN domain UART (main_uart0). + +SD Card +******* + +Download TI's official `WIC`_ and flash the WIC file with an etching software +onto an SD-card. + +Copy the compiled ``zephyr.bin`` to the first FAT partition of the SD card and +plug the SD card into the board. Power it up and stop the u-boot execution at +prompt. + +Use U-Boot to load and start zephyr.bin: + +.. code-block:: console + + fatload mmc 1:1 0x82000000 zephyr.bin; dcache flush; icache flush; dcache off; icache off; go 0x82000000 + +The Zephyr application should start running on the A53 core. + +Debugging +********* + +The board is equipped with an XDS110 JTAG debugger. To debug a binary, utilize the ``debug`` build target: + +.. zephyr-app-commands:: + :app: + :board: am62l_evm/am62l3/a53 + :maybe-skip-config: + :goals: debug + +.. hint:: + To utilize this feature, you'll need OpenOCD version 0.12 or higher. Due to the possibility of + older versions being available in package feeds, it's advisable to `build OpenOCD from source`_. + +References +********** + +https://www.ti.com/tool/TMDS62LEVM + +.. _AM62L EVM TRM: + https://www.ti.com/lit/pdf/SPRUJG8 + +.. _TI AM62L Product Page: + https://www.ti.com/product/AM62L + +.. _WIC: + https://dr-download.ti.com/software-development/software-development-kit-sdk/MD-PvdSyIiioq/10.01.10.04/tisdk-default-image-am62xx-evm-10.01.10.04.rootfs.wic.xz + +.. _EVM User's Guide: + https://www.ti.com/lit/pdf/SPRUJG8 + +.. _build OpenOCD from source: + https://docs.u-boot.org/en/latest/board/ti/k3.html#building-openocd-from-source From 636e104b232b7ff3db8d352e5174b928a60ce51c Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Tue, 13 Jan 2026 11:03:05 +0100 Subject: [PATCH 1861/3659] util: Use CONCAT() instead of internal _CONCAT_\d() in tree The explicit, and internal, _CONCAT_\d macros are used in a few files instead of the public CONCAT() macro which automatically expands to the correct _CONCAT_\d macro based on number of args passed to it. Update files to use CONCAT(). Signed-off-by: Bjarki Arge Andreasen --- drivers/comparator/comparator_mcux_acmp.c | 2 +- drivers/i2c/i2c_nrfx_twim_rtio.c | 2 +- drivers/i2c/i2c_nrfx_twis.c | 2 +- drivers/modem/modem_cellular.c | 2 +- drivers/power_domain/power_domain_nrfs_gdpwr.c | 2 +- include/zephyr/drivers/gnss.h | 4 ++-- include/zephyr/gnss/rtk/rtk.h | 2 +- include/zephyr/modem/pipelink.h | 2 +- include/zephyr/pm/state.h | 2 +- 9 files changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/comparator/comparator_mcux_acmp.c b/drivers/comparator/comparator_mcux_acmp.c index 45af2a672d91..c8eab2e09b6c 100644 --- a/drivers/comparator/comparator_mcux_acmp.c +++ b/drivers/comparator/comparator_mcux_acmp.c @@ -77,7 +77,7 @@ LOG_MODULE_REGISTER(nxp_kinetis_acmp, CONFIG_COMPARATOR_LOG_LEVEL); #endif #define MCUX_ACMP_ENUM(name, value) \ - _CONCAT_4(COMP_MCUX_ACMP_, name, _, value) + CONCAT(COMP_MCUX_ACMP_, name, _, value) #define MCUX_ACMP_DT_INST_ENUM(inst, name, prop) \ MCUX_ACMP_ENUM(name, DT_INST_STRING_TOKEN(inst, prop)) diff --git a/drivers/i2c/i2c_nrfx_twim_rtio.c b/drivers/i2c/i2c_nrfx_twim_rtio.c index a14ebf9afd29..cae5acef6a52 100644 --- a/drivers/i2c/i2c_nrfx_twim_rtio.c +++ b/drivers/i2c/i2c_nrfx_twim_rtio.c @@ -237,7 +237,7 @@ static int i2c_nrfx_twim_rtio_deinit(const struct device *dev) ) #define MSG_BUF_SYM(inst) \ - _CONCAT_3(twim_, inst, _msg_buf) + CONCAT(twim_, inst, _msg_buf) #define MSG_BUF_DEFINE(inst) \ static uint8_t MSG_BUF_SYM(inst)[MSG_BUF_SIZE(inst)] MSG_BUF_ATTR(inst) diff --git a/drivers/i2c/i2c_nrfx_twis.c b/drivers/i2c/i2c_nrfx_twis.c index b17d5fd887c4..302a0e5950c5 100644 --- a/drivers/i2c/i2c_nrfx_twis.c +++ b/drivers/i2c/i2c_nrfx_twis.c @@ -307,7 +307,7 @@ static int shim_nrf_twis_deinit(const struct device *dev) #endif #define SHIM_NRF_TWIS_NAME(id, name) \ - _CONCAT_4(shim_nrf_twis_, name, _, id) + CONCAT(shim_nrf_twis_, name, _, id) #define SHIM_NRF_TWIS_DEVICE_DEFINE(id) \ static struct shim_nrf_twis_data SHIM_NRF_TWIS_NAME(id, data); \ diff --git a/drivers/modem/modem_cellular.c b/drivers/modem/modem_cellular.c index 28b698241219..2f3a3be329be 100644 --- a/drivers/modem/modem_cellular.c +++ b/drivers/modem/modem_cellular.c @@ -3031,7 +3031,7 @@ MODEM_CHAT_SCRIPT_DEFINE(sqn_gm02s_periodic_chat_script, #endif #define MODEM_CELLULAR_INST_NAME(name, inst) \ - _CONCAT_4(name, _, DT_DRV_COMPAT, inst) + CONCAT(name, _, DT_DRV_COMPAT, inst) #define MODEM_CELLULAR_DEFINE_USER_PIPE_DATA(inst, name, size) \ MODEM_PIPELINK_DT_INST_DEFINE(inst, name); \ diff --git a/drivers/power_domain/power_domain_nrfs_gdpwr.c b/drivers/power_domain/power_domain_nrfs_gdpwr.c index 16343293be58..9b7e76247ae8 100644 --- a/drivers/power_domain/power_domain_nrfs_gdpwr.c +++ b/drivers/power_domain/power_domain_nrfs_gdpwr.c @@ -255,7 +255,7 @@ static int domain_init(const struct device *dev) } #define DOMAIN_NODE_SYMNAME(node, sym) \ - _CONCAT_4(domain, _, sym, DT_NODE_CHILD_IDX(node)) + CONCAT(domain, _, sym, DT_NODE_CHILD_IDX(node)) #define DOMAIN_NODE_TO_GDPWR_ENUM(node) \ _CONCAT(GDPWR_GD_, DT_NODE_FULL_NAME_UPPER_TOKEN(node)) diff --git a/include/zephyr/drivers/gnss.h b/include/zephyr/drivers/gnss.h index aa034438b6da..9d1454de2be5 100644 --- a/include/zephyr/drivers/gnss.h +++ b/include/zephyr/drivers/gnss.h @@ -434,7 +434,7 @@ static inline int z_impl_gnss_get_latest_timepulse(const struct device *dev, #define GNSS_DT_DATA_CALLBACK_DEFINE(_node_id, _callback) \ static const STRUCT_SECTION_ITERABLE( \ gnss_data_callback, \ - _CONCAT_4(_gnss_data_callback_, DT_DEP_ORD(_node_id), _, _callback)) = { \ + CONCAT(_gnss_data_callback_, DT_DEP_ORD(_node_id), _, _callback)) = { \ .dev = DEVICE_DT_GET(_node_id), \ .callback = _callback, \ } @@ -460,7 +460,7 @@ static inline int z_impl_gnss_get_latest_timepulse(const struct device *dev, #define GNSS_DT_SATELLITES_CALLBACK_DEFINE(_node_id, _callback) \ static const STRUCT_SECTION_ITERABLE( \ gnss_satellites_callback, \ - _CONCAT_4(_gnss_satellites_callback_, DT_DEP_ORD(_node_id), _, _callback)) = { \ + CONCAT(_gnss_satellites_callback_, DT_DEP_ORD(_node_id), _, _callback)) = { \ .dev = DEVICE_DT_GET(_node_id), \ .callback = _callback, \ } diff --git a/include/zephyr/gnss/rtk/rtk.h b/include/zephyr/gnss/rtk/rtk.h index 937e3640c4c5..0a710d9cc465 100644 --- a/include/zephyr/gnss/rtk/rtk.h +++ b/include/zephyr/gnss/rtk/rtk.h @@ -40,7 +40,7 @@ struct gnss_rtk_data_callback { #define GNSS_DT_RTK_DATA_CALLBACK_DEFINE(_node_id, _callback) \ static const STRUCT_SECTION_ITERABLE( \ gnss_rtk_data_callback, \ - _CONCAT_4(_gnss_rtk_data_callback_, DT_DEP_ORD(_node_id), _, _callback)) = { \ + CONCAT(_gnss_rtk_data_callback_, DT_DEP_ORD(_node_id), _, _callback)) = { \ .dev = DEVICE_DT_GET(_node_id), \ .callback = _callback, \ } diff --git a/include/zephyr/modem/pipelink.h b/include/zephyr/modem/pipelink.h index e8e5edd200ac..f0ecca7d4c8b 100644 --- a/include/zephyr/modem/pipelink.h +++ b/include/zephyr/modem/pipelink.h @@ -115,7 +115,7 @@ void modem_pipelink_notify_disconnected(struct modem_pipelink *link); * @param name Pipelink name */ #define MODEM_PIPELINK_DT_SYM(node_id, name) \ - _CONCAT_4(__modem_pipelink_, DT_DEP_ORD(node_id), _, name) + CONCAT(__modem_pipelink_, DT_DEP_ORD(node_id), _, name) /** @endcond */ diff --git a/include/zephyr/pm/state.h b/include/zephyr/pm/state.h index 69d0cae8863a..9679c26919a8 100644 --- a/include/zephyr/pm/state.h +++ b/include/zephyr/pm/state.h @@ -385,7 +385,7 @@ struct pm_state_constraints { PM_STATE_CONSTRAINT_INIT(DT_PHANDLE_BY_IDX(node_id, phandle, idx)) #define Z_PM_STATE_CONSTRAINTS_LIST_NAME(node_id, phandles) \ - _CONCAT_4(node_id, _, phandles, _constraints) + CONCAT(node_id, _, phandles, _constraints) /** * @brief Define a list of power state constraints from devicetree. From 547d0ffe2544f04294575ec593bc13bcb5868f00 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Mon, 12 Jan 2026 15:28:31 +0100 Subject: [PATCH 1862/3659] scripts: checkpatch: extend has_arg_concat to include CONCAT() The has_arg_concat check checks for ## and UTIL_CAT, but is missing the CONCAT macro. This is causing spurious occurances of MACRO_WITH_FLOW_CONTROL warnings for functions defined with macros if they use the CONCAT() macro (its like UTIL_CAT but supports up to 10 concatenations). Signed-off-by: Bjarki Arge Andreasen --- scripts/checkpatch.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 8ce62f93ca67..cf810d081b18 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -5300,7 +5300,7 @@ sub process { #print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n"; $has_flow_statement = 1 if ($ctx =~ /\b(goto|return)\b/); - $has_arg_concat = 1 if (($ctx =~ /\#\#/ || $ctx =~ /UTIL_CAT/) && $ctx !~ /\#\#\s*(?:__VA_ARGS__|args)\b/); + $has_arg_concat = 1 if (($ctx =~ /\#\#/ || $ctx =~ /UTIL_CAT/ || $ctx =~ /CONCAT/) && $ctx !~ /\#\#\s*(?:__VA_ARGS__|args)\b/); $dstat =~ s/^.\s*\#\s*define\s+$Ident(\([^\)]*\))?\s*//; my $define_args = $1; From bb214df802f96fdc69bc90f56e721ce18b11fe33 Mon Sep 17 00:00:00 2001 From: Gaetan Perrot Date: Sat, 10 Jan 2026 13:43:38 +0900 Subject: [PATCH 1863/3659] ipc: ipc_service: ipc_static_vrings: make vq_teardown void vq_teardown() never reports errors and always returns 0. The error check at the call site is therefore dead code. Make the function void and drop the unused error handling. Signed-off-by: Gaetan Perrot --- subsys/ipc/ipc_service/lib/ipc_static_vrings.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/subsys/ipc/ipc_service/lib/ipc_static_vrings.c b/subsys/ipc/ipc_service/lib/ipc_static_vrings.c index f07ffd45dcb2..3ca0fa18edf2 100644 --- a/subsys/ipc/ipc_service/lib/ipc_static_vrings.c +++ b/subsys/ipc/ipc_service/lib/ipc_static_vrings.c @@ -103,7 +103,7 @@ static int vq_setup(struct ipc_static_vrings *vr, unsigned int role) return 0; } -static int vq_teardown(struct ipc_static_vrings *vr, unsigned int role) +static void vq_teardown(struct ipc_static_vrings *vr, unsigned int role) { memset(&vr->vdev, 0, sizeof(struct virtio_device)); @@ -112,8 +112,6 @@ static int vq_teardown(struct ipc_static_vrings *vr, unsigned int role) virtqueue_free(vr->vq[RPMSG_VQ_1]); virtqueue_free(vr->vq[RPMSG_VQ_0]); - - return 0; } int ipc_static_vrings_init(struct ipc_static_vrings *vr, unsigned int role) @@ -140,12 +138,8 @@ int ipc_static_vrings_init(struct ipc_static_vrings *vr, unsigned int role) int ipc_static_vrings_deinit(struct ipc_static_vrings *vr, unsigned int role) { - int err; - err = vq_teardown(vr, role); - if (err != 0) { - return err; - } + vq_teardown(vr, role); metal_io_finish(&vr->shm_io); From 2e20e8310922b3c7713c8274201acd0aca8b2e6f Mon Sep 17 00:00:00 2001 From: Fabrice DJIATSA Date: Mon, 12 Jan 2026 09:30:51 +0100 Subject: [PATCH 1864/3659] tests: boot: with_mcumgr: exclude stm32h573i_dk from running ble scenario add stm32h573i_dk to the list of excluded platforms for test_upgrade_ble scenario since it's not supported. Signed-off-by: Fabrice DJIATSA --- tests/boot/with_mcumgr/testcase.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/boot/with_mcumgr/testcase.yaml b/tests/boot/with_mcumgr/testcase.yaml index 5be708303262..ec1bb28d8617 100644 --- a/tests/boot/with_mcumgr/testcase.yaml +++ b/tests/boot/with_mcumgr/testcase.yaml @@ -50,6 +50,7 @@ tests: - nucleo_wba65ri - nucleo_wl55jc - stm32f3_disco + - stm32h573i_dk - stm32l562e_dk - stm32u083c_dk - stm32wba65i_dk1 From d30ed270491b03f0f06ff47997e5f706b8e8518f Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Fri, 9 Jan 2026 14:49:51 +0100 Subject: [PATCH 1865/3659] Bluetooth: Tester: Remove empty file hci_ipc.conf The file is unused and the use of it has been removed from autopts. Signed-off-by: Emil Gydesen --- tests/bluetooth/tester/hci_ipc.conf | 1 - 1 file changed, 1 deletion(-) delete mode 100644 tests/bluetooth/tester/hci_ipc.conf diff --git a/tests/bluetooth/tester/hci_ipc.conf b/tests/bluetooth/tester/hci_ipc.conf deleted file mode 100644 index e88b3fb67452..000000000000 --- a/tests/bluetooth/tester/hci_ipc.conf +++ /dev/null @@ -1 +0,0 @@ -# left empty until autopts has been updated to stop using it From b1aa1a394acceefd9244b16adca29857d06cd1f5 Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Sun, 11 Jan 2026 13:26:09 +0000 Subject: [PATCH 1866/3659] dts: bindings: can: nxp: flexcan: make clk-source property optional Make the clk-source property of the NXP FlexCAN devicetree nodes optional as not all FlexCAN instances have an internal clock multiplexer. Remove the clk-source property from the SoCs where the internal clock multiplexer is not present, limit the values this property can be assigned, and default the clock selection bit to 0 in the driver. Signed-off-by: Henrik Brix Andersen --- drivers/can/can_mcux_flexcan.c | 6 +++--- dts/arm/nxp/nxp_mcxa156.dtsi | 1 - dts/arm/nxp/nxp_mcxa344.dtsi | 1 - dts/arm/nxp/nxp_mcxa5x_common.dtsi | 2 -- dts/arm/nxp/nxp_mcxe31x_common.dtsi | 6 ------ dts/arm/nxp/nxp_mcxn23x_common.dtsi | 2 -- dts/arm/nxp/nxp_mcxn94x_common.dtsi | 1 - dts/arm/nxp/nxp_mcxnx4x_common.dtsi | 1 - dts/arm/nxp/nxp_mcxw7x_common.dtsi | 1 - dts/arm/nxp/nxp_rt10xx.dtsi | 3 --- dts/arm/nxp/nxp_s32k344_m7.dtsi | 6 ------ dts/arm/nxp/nxp_s32k566.dtsi | 18 ------------------ dts/arm/nxp/nxp_s32z27x_r52.dtsi | 24 ------------------------ dts/bindings/can/nxp,flexcan.yaml | 6 ++++-- 14 files changed, 7 insertions(+), 71 deletions(-) diff --git a/drivers/can/can_mcux_flexcan.c b/drivers/can/can_mcux_flexcan.c index ad97b64997f3..bcc3dfa2a44d 100644 --- a/drivers/can/can_mcux_flexcan.c +++ b/drivers/can/can_mcux_flexcan.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Vestas Wind Systems A/S + * Copyright (c) 2019-2026 Vestas Wind Systems A/S * Copyright 2025 NXP * * SPDX-License-Identifier: Apache-2.0 @@ -64,7 +64,7 @@ struct mcux_flexcan_config { const struct device *clock_dev; clock_control_subsys_t clock_subsys; - int clk_source; + uint32_t clk_source; uint32_t number_of_mb; uint32_t rx_mb; uint32_t tx_mb; @@ -1521,7 +1521,7 @@ static DEVICE_API(can, mcux_flexcan_fd_driver_api) = { .clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(id)), \ .clock_subsys = (clock_control_subsys_t) \ DT_INST_CLOCKS_CELL(id, name), \ - .clk_source = DT_INST_PROP(id, clk_source), \ + .clk_source = DT_INST_PROP_OR(id, clk_source, 0U), \ .number_of_mb = FLEXCAN_INST_NUMBER_OF_MB(id), \ .rx_mb = FLEXCAN_INST_RX_MB(id), \ .tx_mb = FLEXCAN_INST_TX_MB(id), \ diff --git a/dts/arm/nxp/nxp_mcxa156.dtsi b/dts/arm/nxp/nxp_mcxa156.dtsi index 3cfb77e5fa2f..4b4bf059c01b 100644 --- a/dts/arm/nxp/nxp_mcxa156.dtsi +++ b/dts/arm/nxp/nxp_mcxa156.dtsi @@ -293,7 +293,6 @@ interrupts = <19 0>; interrupt-names = "common"; clocks = <&syscon MCUX_FLEXCAN0_CLK>; - clk-source = <0>; number-of-mb = <32>; status = "disabled"; }; diff --git a/dts/arm/nxp/nxp_mcxa344.dtsi b/dts/arm/nxp/nxp_mcxa344.dtsi index 3392f68aaa44..36a845afcfd6 100644 --- a/dts/arm/nxp/nxp_mcxa344.dtsi +++ b/dts/arm/nxp/nxp_mcxa344.dtsi @@ -288,7 +288,6 @@ interrupts = <19 0>; interrupt-names = "common"; clocks = <&syscon MCUX_FLEXCAN0_CLK>; - clk-source = <0>; number-of-mb = <32>; status = "disabled"; }; diff --git a/dts/arm/nxp/nxp_mcxa5x_common.dtsi b/dts/arm/nxp/nxp_mcxa5x_common.dtsi index a16261903df7..df5e3b37d354 100644 --- a/dts/arm/nxp/nxp_mcxa5x_common.dtsi +++ b/dts/arm/nxp/nxp_mcxa5x_common.dtsi @@ -487,7 +487,6 @@ interrupts = <19 0>; interrupt-names = "common"; clocks = <&syscon MCUX_FLEXCAN0_CLK>; - clk-source = <0>; number-of-mb = <32>; status = "disabled"; }; @@ -498,7 +497,6 @@ interrupts = <20 0>; interrupt-names = "common"; clocks = <&syscon MCUX_FLEXCAN1_CLK>; - clk-source = <0>; number-of-mb = <32>; status = "disabled"; }; diff --git a/dts/arm/nxp/nxp_mcxe31x_common.dtsi b/dts/arm/nxp/nxp_mcxe31x_common.dtsi index 5c25e06113ef..473b313e87e0 100644 --- a/dts/arm/nxp/nxp_mcxe31x_common.dtsi +++ b/dts/arm/nxp/nxp_mcxe31x_common.dtsi @@ -328,7 +328,6 @@ interrupts = <109 0>, <110 0>, <111 0>, <112 0>; interrupt-names = "flexcan0-0", "flexcan0-1", "flexcan0-2", "flexcan0-3"; clocks = <&mc_cgm MCUX_FLEXCAN0_CLK>; - clk-source = <0>; status = "disabled"; }; @@ -338,7 +337,6 @@ interrupts = <113 0>, <114 0>, <115 0>; interrupt-names = "flexcan1-0", "flexcan1-1", "flexcan1-2"; clocks = <&mc_cgm MCUX_FLEXCAN1_CLK>; - clk-source = <0>; status = "disabled"; }; @@ -348,7 +346,6 @@ interrupts = <116 0>, <117 0>, <118 0>; interrupt-names = "flexcan2-0", "flexcan2-1", "flexcan2-2"; clocks = <&mc_cgm MCUX_FLEXCAN2_CLK>; - clk-source = <0>; status = "disabled"; }; @@ -358,7 +355,6 @@ interrupts = <119 0>, <120 0>; interrupt-names = "flexcan3-0", "flexcan3-1"; clocks = <&mc_cgm MCUX_FLEXCAN3_CLK>; - clk-source = <0>; status = "disabled"; }; @@ -368,7 +364,6 @@ interrupts = <121 0>, <122 0>; interrupt-names = "flexcan4-0", "flexcan4-1"; clocks = <&mc_cgm MCUX_FLEXCAN4_CLK>; - clk-source = <0>; status = "disabled"; }; @@ -378,7 +373,6 @@ interrupts = <123 0>, <124 0>; interrupt-names = "flexcan5-0", "flexcan5-1"; clocks = <&mc_cgm MCUX_FLEXCAN5_CLK>; - clk-source = <0>; status = "disabled"; }; diff --git a/dts/arm/nxp/nxp_mcxn23x_common.dtsi b/dts/arm/nxp/nxp_mcxn23x_common.dtsi index 648ef517208a..8179afe26253 100644 --- a/dts/arm/nxp/nxp_mcxn23x_common.dtsi +++ b/dts/arm/nxp/nxp_mcxn23x_common.dtsi @@ -923,7 +923,6 @@ interrupts = <62 0>; interrupt-names = "common"; clocks = <&syscon MCUX_FLEXCAN0_CLK>; - clk-source = <0>; number-of-mb = <32>; number-of-mb-fd = <7>; status = "disabled"; @@ -935,7 +934,6 @@ interrupts = <63 0>; interrupt-names = "common"; clocks = <&syscon MCUX_FLEXCAN1_CLK>; - clk-source = <0>; number-of-mb = <32>; number-of-mb-fd = <7>; status = "disabled"; diff --git a/dts/arm/nxp/nxp_mcxn94x_common.dtsi b/dts/arm/nxp/nxp_mcxn94x_common.dtsi index f8871eaf02c6..48106779602a 100644 --- a/dts/arm/nxp/nxp_mcxn94x_common.dtsi +++ b/dts/arm/nxp/nxp_mcxn94x_common.dtsi @@ -117,7 +117,6 @@ interrupts = <63 0>; interrupt-names = "common"; clocks = <&syscon MCUX_FLEXCAN1_CLK>; - clk-source = <0>; number-of-mb = <32>; number-of-mb-fd = <7>; status = "disabled"; diff --git a/dts/arm/nxp/nxp_mcxnx4x_common.dtsi b/dts/arm/nxp/nxp_mcxnx4x_common.dtsi index b9c338563ce8..1b60685609c1 100644 --- a/dts/arm/nxp/nxp_mcxnx4x_common.dtsi +++ b/dts/arm/nxp/nxp_mcxnx4x_common.dtsi @@ -1105,7 +1105,6 @@ interrupts = <62 0>; interrupt-names = "common"; clocks = <&syscon MCUX_FLEXCAN0_CLK>; - clk-source = <0>; number-of-mb = <32>; number-of-mb-fd = <7>; status = "disabled"; diff --git a/dts/arm/nxp/nxp_mcxw7x_common.dtsi b/dts/arm/nxp/nxp_mcxw7x_common.dtsi index fb4300bd4364..f52f2200e593 100644 --- a/dts/arm/nxp/nxp_mcxw7x_common.dtsi +++ b/dts/arm/nxp/nxp_mcxw7x_common.dtsi @@ -376,7 +376,6 @@ interrupts = <47 0>; interrupt-names = "common"; clocks = <&scg SCG_K4_FIRC_CLK 0xec>; - clk-source = <2>; number-of-mb = <32>; status = "disabled"; }; diff --git a/dts/arm/nxp/nxp_rt10xx.dtsi b/dts/arm/nxp/nxp_rt10xx.dtsi index 914819a0293a..5a14b50017a2 100644 --- a/dts/arm/nxp/nxp_rt10xx.dtsi +++ b/dts/arm/nxp/nxp_rt10xx.dtsi @@ -969,7 +969,6 @@ interrupts = <36 0>; interrupt-names = "common"; clocks = <&ccm IMX_CCM_CAN_CLK 0x68 14>; - clk-source = <2>; number-of-mb = <64>; status = "disabled"; }; @@ -980,7 +979,6 @@ interrupts = <37 0>; interrupt-names = "common"; clocks = <&ccm IMX_CCM_CAN_CLK 0x68 18>; - clk-source = <2>; number-of-mb = <64>; status = "disabled"; }; @@ -991,7 +989,6 @@ interrupts = <154 0>; interrupt-names = "common"; clocks = <&ccm IMX_CCM_CAN_CLK 0x84 6>; - clk-source = <2>; number-of-mb = <64>; number-of-mb-fd = <14>; status = "disabled"; diff --git a/dts/arm/nxp/nxp_s32k344_m7.dtsi b/dts/arm/nxp/nxp_s32k344_m7.dtsi index 443436455b36..1f7e6cdd6664 100644 --- a/dts/arm/nxp/nxp_s32k344_m7.dtsi +++ b/dts/arm/nxp/nxp_s32k344_m7.dtsi @@ -475,7 +475,6 @@ compatible = "nxp,flexcan-fd", "nxp,flexcan"; reg = <0x40304000 0x4000>; clocks = <&clock NXP_S32_FLEXCANA_CLK>; - clk-source = <0>; interrupts = <109 0>, <110 0>, <111 0>, <112 0>; interrupt-names = "ored", "ored_0_31_mb", "ored_32_63_mb", "ored_64_95_mb"; @@ -488,7 +487,6 @@ compatible = "nxp,flexcan-fd", "nxp,flexcan"; reg = <0x40308000 0x4000>; clocks = <&clock NXP_S32_FLEXCANA_CLK>; - clk-source = <0>; interrupts = <113 0>, <114 0>, <115 0>; interrupt-names = "ored", "ored_0_31_mb", "ored_32_63_mb"; number-of-mb = <64>; @@ -500,7 +498,6 @@ compatible = "nxp,flexcan-fd", "nxp,flexcan"; reg = <0x4030c000 0x4000>; clocks = <&clock NXP_S32_FLEXCANA_CLK>; - clk-source = <0>; interrupts = <116 0>, <117 0>, <118 0>; interrupt-names = "ored", "ored_0_31_mb", "ored_32_63_mb"; number-of-mb = <64>; @@ -512,7 +509,6 @@ compatible = "nxp,flexcan-fd", "nxp,flexcan"; reg = <0x40310000 0x4000>; clocks = <&clock NXP_S32_FLEXCANB_CLK>; - clk-source = <0>; interrupts = <119 0>, <120 0>; interrupt-names = "ored", "ored_0_31_mb"; number-of-mb = <32>; @@ -524,7 +520,6 @@ compatible = "nxp,flexcan-fd", "nxp,flexcan"; reg = <0x40314000 0x4000>; clocks = <&clock NXP_S32_FLEXCANB_CLK>; - clk-source = <0>; interrupts = <121 0>, <122 0>; interrupt-names = "ored", "ored_0_31_mb"; number-of-mb = <32>; @@ -536,7 +531,6 @@ compatible = "nxp,flexcan-fd", "nxp,flexcan"; reg = <0x40318000 0x4000>; clocks = <&clock NXP_S32_FLEXCANB_CLK>; - clk-source = <0>; interrupts = <123 0>, <124 0>; interrupt-names = "ored", "ored_0_31_mb"; number-of-mb = <32>; diff --git a/dts/arm/nxp/nxp_s32k566.dtsi b/dts/arm/nxp/nxp_s32k566.dtsi index 9cc51920429a..a50f189da15d 100644 --- a/dts/arm/nxp/nxp_s32k566.dtsi +++ b/dts/arm/nxp/nxp_s32k566.dtsi @@ -551,7 +551,6 @@ compatible = "nxp,flexcan-fd", "nxp,flexcan"; reg = <0x42174000 0x4000>; clocks = <&clock NXP_S32_LPE_FLEXCAN_PE_CLK>; - clk-source = <0>; number-of-mb = <96>; number-of-mb-fd = <21>; interrupt-names = "ored", "ored_0_96_mb"; @@ -562,7 +561,6 @@ compatible = "nxp,flexcan-fd", "nxp,flexcan"; reg = <0x40290000 0x4000>; clocks = <&clock NXP_S32_FLEXCAN0_PE_NOGATE_CLK>; - clk-source = <0>; number-of-mb = <96>; number-of-mb-fd = <21>; interrupt-names = "ored", "ored_0_96_mb"; @@ -573,7 +571,6 @@ compatible = "nxp,flexcan-fd", "nxp,flexcan"; reg = <0x40294000 0x4000>; clocks = <&clock NXP_S32_FLEXCAN1_PE_NOGATE_CLK>; - clk-source = <0>; number-of-mb = <96>; number-of-mb-fd = <21>; interrupt-names = "ored", "ored_0_96_mb"; @@ -584,7 +581,6 @@ compatible = "nxp,flexcan-fd", "nxp,flexcan"; reg = <0x40298000 0x4000>; clocks = <&clock NXP_S32_FLEXCAN2_PE_NOGATE_CLK>; - clk-source = <0>; number-of-mb = <96>; number-of-mb-fd = <21>; interrupt-names = "ored", "ored_0_96_mb"; @@ -595,7 +591,6 @@ compatible = "nxp,flexcan-fd", "nxp,flexcan"; reg = <0x4029c000 0x4000>; clocks = <&clock NXP_S32_FLEXCAN3_PE_NOGATE_CLK>; - clk-source = <0>; number-of-mb = <96>; number-of-mb-fd = <21>; interrupt-names = "ored", "ored_0_96_mb"; @@ -606,7 +601,6 @@ compatible = "nxp,flexcan-fd", "nxp,flexcan"; reg = <0x402a0000 0x4000>; clocks = <&clock NXP_S32_FLEXCAN4_PE_NOGATE_CLK>; - clk-source = <0>; number-of-mb = <96>; number-of-mb-fd = <21>; interrupt-names = "ored", "ored_0_96_mb"; @@ -617,7 +611,6 @@ compatible = "nxp,flexcan-fd", "nxp,flexcan"; reg = <0x402a4000 0x4000>; clocks = <&clock NXP_S32_FLEXCAN5_PE_NOGATE_CLK>; - clk-source = <0>; number-of-mb = <96>; number-of-mb-fd = <21>; interrupt-names = "ored", "ored_0_96_mb"; @@ -628,7 +621,6 @@ compatible = "nxp,flexcan-fd", "nxp,flexcan"; reg = <0x402a8000 0x4000>; clocks = <&clock NXP_S32_FLEXCAN6_PE_NOGATE_CLK>; - clk-source = <0>; number-of-mb = <96>; number-of-mb-fd = <21>; interrupt-names = "ored", "ored_0_96_mb"; @@ -639,7 +631,6 @@ compatible = "nxp,flexcan-fd", "nxp,flexcan"; reg = <0x402ac000 0x4000>; clocks = <&clock NXP_S32_FLEXCAN7_PE_NOGATE_CLK>; - clk-source = <0>; number-of-mb = <96>; number-of-mb-fd = <21>; interrupt-names = "ored", "ored_0_96_mb"; @@ -650,7 +641,6 @@ compatible = "nxp,flexcan-fd", "nxp,flexcan"; reg = <0x406b0000 0x4000>; clocks = <&clock NXP_S32_FLEXCAN8_PE_NOGATE_CLK>; - clk-source = <0>; number-of-mb = <96>; number-of-mb-fd = <21>; interrupt-names = "ored", "ored_0_96_mb"; @@ -661,7 +651,6 @@ compatible = "nxp,flexcan-fd", "nxp,flexcan"; reg = <0x406b4000 0x4000>; clocks = <&clock NXP_S32_FLEXCAN9_PE_NOGATE_CLK>; - clk-source = <0>; number-of-mb = <96>; number-of-mb-fd = <21>; interrupt-names = "ored", "ored_0_96_mb"; @@ -672,7 +661,6 @@ compatible = "nxp,flexcan-fd", "nxp,flexcan"; reg = <0x406ac000 0x4000>; clocks = <&clock NXP_S32_FLEXCAN10_PE_NOGATE_CLK>; - clk-source = <0>; number-of-mb = <96>; number-of-mb-fd = <21>; interrupt-names = "ored", "ored_0_96_mb"; @@ -683,7 +671,6 @@ compatible = "nxp,flexcan-fd", "nxp,flexcan"; reg = <0x4089c000 0x4000>; clocks = <&clock NXP_S32_FLEXCAN11_PE_NOGATE_CLK>; - clk-source = <0>; number-of-mb = <96>; number-of-mb-fd = <21>; interrupt-names = "ored", "ored_0_96_mb"; @@ -694,7 +681,6 @@ compatible = "nxp,flexcan-fd", "nxp,flexcan"; reg = <0x408a0000 0x4000>; clocks = <&clock NXP_S32_FLEXCAN12_PE_NOGATE_CLK>; - clk-source = <0>; number-of-mb = <96>; number-of-mb-fd = <21>; interrupt-names = "ored", "ored_0_96_mb"; @@ -705,7 +691,6 @@ compatible = "nxp,flexcan-fd", "nxp,flexcan"; reg = <0x408a4000 0x4000>; clocks = <&clock NXP_S32_FLEXCAN13_PE_NOGATE_CLK>; - clk-source = <0>; number-of-mb = <96>; number-of-mb-fd = <21>; interrupt-names = "ored", "ored_0_96_mb"; @@ -716,7 +701,6 @@ compatible = "nxp,flexcan-fd", "nxp,flexcan"; reg = <0x408a8000 0x4000>; clocks = <&clock NXP_S32_FLEXCAN14_PE_NOGATE_CLK>; - clk-source = <0>; number-of-mb = <96>; number-of-mb-fd = <21>; interrupt-names = "ored", "ored_0_96_mb"; @@ -727,7 +711,6 @@ compatible = "nxp,flexcan-fd", "nxp,flexcan"; reg = <0x408ac000 0x4000>; clocks = <&clock NXP_S32_FLEXCAN15_PE_NOGATE_CLK>; - clk-source = <0>; number-of-mb = <96>; number-of-mb-fd = <21>; interrupt-names = "ored", "ored_0_96_mb"; @@ -738,7 +721,6 @@ compatible = "nxp,flexcan-fd", "nxp,flexcan"; reg = <0x408b0000 0x4000>; clocks = <&clock NXP_S32_FLEXCAN16_PE_NOGATE_CLK>; - clk-source = <0>; number-of-mb = <96>; number-of-mb-fd = <21>; interrupt-names = "ored", "ored_0_96_mb"; diff --git a/dts/arm/nxp/nxp_s32z27x_r52.dtsi b/dts/arm/nxp/nxp_s32z27x_r52.dtsi index e11eb9eab475..8a4634610418 100644 --- a/dts/arm/nxp/nxp_s32z27x_r52.dtsi +++ b/dts/arm/nxp/nxp_s32z27x_r52.dtsi @@ -747,7 +747,6 @@ flexcan0: can@449a0000 { compatible = "nxp,flexcan-fd", "nxp,flexcan"; reg = <0x449a0000 0x4000>; - clk-source = <0>; interrupts = , , , @@ -764,7 +763,6 @@ flexcan1: can@449b0000 { compatible = "nxp,flexcan-fd", "nxp,flexcan"; reg = <0x449b0000 0x4000>; - clk-source = <0>; interrupts = , , , @@ -780,7 +778,6 @@ flexcan2: can@449c0000 { compatible = "nxp,flexcan-fd", "nxp,flexcan"; - clk-source = <0>; reg = <0x449c0000 0x4000>; interrupts = , , @@ -797,7 +794,6 @@ flexcan3: can@449d0000 { compatible = "nxp,flexcan-fd", "nxp,flexcan"; - clk-source = <0>; reg = <0x449d0000 0x4000>; interrupts = , , @@ -814,7 +810,6 @@ flexcan4: can@449e0000 { compatible = "nxp,flexcan-fd", "nxp,flexcan"; - clk-source = <0>; reg = <0x449e0000 0x4000>; interrupts = , , @@ -831,7 +826,6 @@ flexcan5: can@449f0000 { compatible = "nxp,flexcan-fd", "nxp,flexcan"; - clk-source = <0>; reg = <0x449f0000 0x4000>; interrupts = , , @@ -848,7 +842,6 @@ flexcan6: can@44ba0000 { compatible = "nxp,flexcan-fd", "nxp,flexcan"; - clk-source = <0>; reg = <0x44ba0000 0x4000>; interrupts = , , @@ -865,7 +858,6 @@ flexcan7: can@44bb0000 { compatible = "nxp,flexcan-fd", "nxp,flexcan"; - clk-source = <0>; reg = <0x44bb0000 0x4000>; interrupts = , , @@ -882,7 +874,6 @@ flexcan8: can@44bc0000 { compatible = "nxp,flexcan-fd", "nxp,flexcan"; - clk-source = <0>; reg = <0x44bc0000 0x4000>; interrupts = , , @@ -899,7 +890,6 @@ flexcan9: can@44bd0000 { compatible = "nxp,flexcan-fd", "nxp,flexcan"; - clk-source = <0>; reg = <0x44bd0000 0x4000>; interrupts = , , @@ -916,7 +906,6 @@ flexcan10: can@44be0000 { compatible = "nxp,flexcan-fd", "nxp,flexcan"; - clk-source = <0>; reg = <0x44be0000 0x4000>; interrupts = , , @@ -933,7 +922,6 @@ flexcan11: can@44bf0000 { compatible = "nxp,flexcan-fd", "nxp,flexcan"; - clk-source = <0>; reg = <0x44bf0000 0x4000>; interrupts = , , @@ -950,7 +938,6 @@ flexcan12: can@44da0000 { compatible = "nxp,flexcan-fd", "nxp,flexcan"; - clk-source = <0>; reg = <0x44da0000 0x4000>; interrupts = , , @@ -967,7 +954,6 @@ flexcan13: can@44db0000 { compatible = "nxp,flexcan-fd", "nxp,flexcan"; - clk-source = <0>; reg = <0x44db0000 0x4000>; interrupts = , , @@ -984,7 +970,6 @@ flexcan14: can@44dc0000 { compatible = "nxp,flexcan-fd", "nxp,flexcan"; - clk-source = <0>; reg = <0x44dc0000 0x4000>; interrupts = , , @@ -1001,7 +986,6 @@ flexcan15: can@44dd0000 { compatible = "nxp,flexcan-fd", "nxp,flexcan"; - clk-source = <0>; reg = <0x44dd0000 0x4000>; interrupts = , , @@ -1018,7 +1002,6 @@ flexcan16: can@44de0000 { compatible = "nxp,flexcan-fd", "nxp,flexcan"; - clk-source = <0>; reg = <0x44de0000 0x4000>; interrupts = , , @@ -1035,7 +1018,6 @@ flexcan17: can@44df0000 { compatible = "nxp,flexcan-fd", "nxp,flexcan"; - clk-source = <0>; reg = <0x44df0000 0x4000>; interrupts = , , @@ -1052,7 +1034,6 @@ flexcan18: can@44fa0000 { compatible = "nxp,flexcan-fd", "nxp,flexcan"; - clk-source = <0>; reg = <0x44fa0000 0x4000>; interrupts = , , @@ -1069,7 +1050,6 @@ flexcan19: can@44fb0000 { compatible = "nxp,flexcan-fd", "nxp,flexcan"; - clk-source = <0>; reg = <0x44fb0000 0x4000>; interrupts = , , @@ -1086,7 +1066,6 @@ flexcan20: can@44fc0000 { compatible = "nxp,flexcan-fd", "nxp,flexcan"; - clk-source = <0>; reg = <0x44fc0000 0x4000>; interrupts = , , @@ -1103,7 +1082,6 @@ flexcan21: can@44fd0000 { compatible = "nxp,flexcan-fd", "nxp,flexcan"; - clk-source = <0>; reg = <0x44fd0000 0x4000>; interrupts = , , @@ -1120,7 +1098,6 @@ flexcan22: can@44fe0000 { compatible = "nxp,flexcan-fd", "nxp,flexcan"; - clk-source = <0>; reg = <0x44fe0000 0x4000>; interrupts = , , @@ -1137,7 +1114,6 @@ flexcan23: can@44ff0000 { compatible = "nxp,flexcan-fd", "nxp,flexcan"; - clk-source = <0>; reg = <0x44ff0000 0x4000>; interrupts = , , diff --git a/dts/bindings/can/nxp,flexcan.yaml b/dts/bindings/can/nxp,flexcan.yaml index 562d8d4322bf..1e53452d3434 100644 --- a/dts/bindings/can/nxp,flexcan.yaml +++ b/dts/bindings/can/nxp,flexcan.yaml @@ -1,4 +1,4 @@ -# Copyright (c) 2019 Vestas Wind Systems A/S +# Copyright (c) 2019-2026 Vestas Wind Systems A/S # SPDX-License-Identifier: Apache-2.0 description: | @@ -38,7 +38,9 @@ properties: clk-source: type: int - required: true + enum: + - 0 + - 1 description: CAN engine clock source number-of-mb: From b359f9037d542a45139786d7a86104cda1d04d6f Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Sun, 11 Jan 2026 15:22:25 +0000 Subject: [PATCH 1867/3659] drivers: can: nxp: mcux: flexcan: add proper support for clock multiplexer Add proper support for the 1-bit CAN protocol engine clock multiplexer present in some NXP FlexCAN instances. Both possible input clocks are now represented as named clocks in the devicetree nodes ("clksrc0" and "clksrc1") and the existing devicetree property "clk-source" now selects the correct clock in addition to setting the multiplexer bit (CLKSRC) in the FlexCAN CTRL1 register. Fixes: #94517 Signed-off-by: Henrik Brix Andersen --- drivers/can/can_mcux_flexcan.c | 30 +++++++++++++++++++++++++---- dts/arm/nxp/nxp_k66.dtsi | 4 +++- dts/arm/nxp/nxp_k6x.dtsi | 4 +++- dts/arm/nxp/nxp_ke1xf.dtsi | 14 +++++++------- dts/arm/nxp/nxp_mcxe24x_common.dtsi | 13 +++++++++---- dts/arm/nxp/nxp_rt118x.dtsi | 3 +++ dts/arm/nxp/nxp_rt11xx.dtsi | 3 +++ dts/arm/nxp/nxp_s32k146.dtsi | 4 ++++ dts/arm/nxp/nxp_s32k148.dtsi | 4 ++++ dts/arm/nxp/nxp_s32k1xx.dtsi | 3 +-- dts/arm64/nxp/nxp_mimx8mp_a53.dtsi | 2 ++ dts/arm64/nxp/nxp_mimx93_a55.dtsi | 2 ++ dts/bindings/can/nxp,flexcan.yaml | 15 ++++++++++++++- 13 files changed, 81 insertions(+), 20 deletions(-) diff --git a/drivers/can/can_mcux_flexcan.c b/drivers/can/can_mcux_flexcan.c index bcc3dfa2a44d..3dd214743406 100644 --- a/drivers/can/can_mcux_flexcan.c +++ b/drivers/can/can_mcux_flexcan.c @@ -1488,6 +1488,30 @@ static DEVICE_API(can, mcux_flexcan_fd_driver_api) = { #define FLEXCAN_INST_RX_MB(id) (CONFIG_CAN_MCUX_FLEXCAN_MAX_FILTERS + RX_START_IDX) #define FLEXCAN_INST_TX_MB(id) (FLEXCAN_INST_NUMBER_OF_MB(id) - FLEXCAN_INST_RX_MB(id)) +#define FLEXCAN_CLK_SOURCE(id) DT_INST_PROP(id, clk_source) +#define FLEXCAN_CLK_SOURCE_NAME(id) CONCAT(clksrc, FLEXCAN_CLK_SOURCE(id)) + +#define FLEXCAN_INST_CLOCKS_FROM_CLK_SOURCE(id) \ + .clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR_BY_NAME(id, FLEXCAN_CLK_SOURCE_NAME(id))), \ + .clock_subsys = (clock_control_subsys_t) \ + DT_INST_CLOCKS_CELL_BY_NAME(id, FLEXCAN_CLK_SOURCE_NAME(id), name), \ + .clk_source = FLEXCAN_CLK_SOURCE(id) + +#define FLEXCAN_INST_CLOCKS_NO_CLK_SOURCE(id) \ + .clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(id)), \ + .clock_subsys = (clock_control_subsys_t)DT_INST_CLOCKS_CELL(id, name), \ + .clk_source = 0U + +#define FLEXCAN_INST_CLOCKS(id) \ + COND_CODE_1(DT_INST_NODE_HAS_PROP(id, clk_source), \ + (FLEXCAN_INST_CLOCKS_FROM_CLK_SOURCE(id)), \ + (FLEXCAN_INST_CLOCKS_NO_CLK_SOURCE(id))) + +#define FLEXCAN_CHECK_CLK_SOURCE(id) \ + IF_ENABLED(DT_INST_NODE_HAS_PROP(id, clk_source), \ + (BUILD_ASSERT(DT_INST_CLOCKS_HAS_NAME(id, FLEXCAN_CLK_SOURCE_NAME(id)), \ + "FlexCAN instance " STRINGIFY(id) " clk-source without named clock"))) + #define FLEXCAN_CHECK_MAX_FILTER(id) \ BUILD_ASSERT(CONFIG_CAN_MCUX_FLEXCAN_MAX_FILTERS > 0, \ "Maximum number of RX filters should greater than 0"); \ @@ -1499,6 +1523,7 @@ static DEVICE_API(can, mcux_flexcan_fd_driver_api) = { #define FLEXCAN_DEVICE_INIT_MCUX(id) \ PINCTRL_DT_INST_DEFINE(id); \ + FLEXCAN_CHECK_CLK_SOURCE(id); \ FLEXCAN_CHECK_MAX_FILTER(id); \ \ static void mcux_flexcan_irq_config_##id(const struct device *dev); \ @@ -1518,10 +1543,7 @@ static DEVICE_API(can, mcux_flexcan_fd_driver_api) = { static const struct mcux_flexcan_config mcux_flexcan_config_##id = { \ DEVICE_MMIO_NAMED_ROM_INIT(flexcan_mmio, DT_DRV_INST(id)), \ .common = CAN_DT_DRIVER_CONFIG_INST_GET(id, 0, FLEXCAN_MAX_BITRATE(id)), \ - .clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(id)), \ - .clock_subsys = (clock_control_subsys_t) \ - DT_INST_CLOCKS_CELL(id, name), \ - .clk_source = DT_INST_PROP_OR(id, clk_source, 0U), \ + FLEXCAN_INST_CLOCKS(id), \ .number_of_mb = FLEXCAN_INST_NUMBER_OF_MB(id), \ .rx_mb = FLEXCAN_INST_RX_MB(id), \ .tx_mb = FLEXCAN_INST_TX_MB(id), \ diff --git a/dts/arm/nxp/nxp_k66.dtsi b/dts/arm/nxp/nxp_k66.dtsi index 0bc7e8497475..81889bb5948f 100644 --- a/dts/arm/nxp/nxp_k66.dtsi +++ b/dts/arm/nxp/nxp_k66.dtsi @@ -30,7 +30,9 @@ interrupts = <94 0>, <95 0>, <96 0>, <97 0>, <98 0>, <99 0>; interrupt-names = "mb-0-15", "bus-off", "error", "tx-warning", "rx-warning", "wake-up"; - clocks = <&sim KINETIS_SIM_BUS_CLK 0x1030 4>; + clocks = <&sim KINETIS_SIM_OSCERCLK 0x1030 4>, + <&sim KINETIS_SIM_BUS_CLK 0x1030 4>; + clock-names = "clksrc0", "clksrc1"; clk-source = <1>; number-of-mb = <16>; status = "disabled"; diff --git a/dts/arm/nxp/nxp_k6x.dtsi b/dts/arm/nxp/nxp_k6x.dtsi index 18f4e169c2bf..bd8a859aebb1 100644 --- a/dts/arm/nxp/nxp_k6x.dtsi +++ b/dts/arm/nxp/nxp_k6x.dtsi @@ -521,7 +521,9 @@ interrupts = <75 0>, <76 0>, <77 0>, <78 0>, <79 0>, <80 0>; interrupt-names = "mb-0-15", "bus-off", "error", "tx-warning", "rx-warning", "wake-up"; - clocks = <&sim KINETIS_SIM_BUS_CLK 0x103C 4>; + clocks = <&sim KINETIS_SIM_OSCERCLK 0x103C 4>, + <&sim KINETIS_SIM_BUS_CLK 0x103C 4>; + clock-names = "clksrc0", "clksrc1"; clk-source = <1>; number-of-mb = <16>; status = "disabled"; diff --git a/dts/arm/nxp/nxp_ke1xf.dtsi b/dts/arm/nxp/nxp_ke1xf.dtsi index f2784e37b9c5..421e00c04b24 100644 --- a/dts/arm/nxp/nxp_ke1xf.dtsi +++ b/dts/arm/nxp/nxp_ke1xf.dtsi @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2021 Vestas Wind Systems A/S + * Copyright (c) 2019-2026 Vestas Wind Systems A/S * * SPDX-License-Identifier: Apache-2.0 */ @@ -407,9 +407,9 @@ compatible = "nxp,flexcan"; reg = <0x40024000 0x1000>; interrupts = <78 0>, <79 0>, <80 0>, <81 0>; - interrupt-names = "warning", "error", "wake-up", - "mb-0-15"; - clocks = <&scg KINETIS_SCG_BUS_CLK>; + interrupt-names = "warning", "error", "wake-up", "mb-0-15"; + clocks = <&scg KINETIS_SCG_SOSC_ASYNC_DIV2_CLK>, <&scg KINETIS_SCG_BUS_CLK>; + clock-names = "clksrc0", "clksrc1"; clk-source = <1>; number-of-mb = <16>; status = "disabled"; @@ -419,9 +419,9 @@ compatible = "nxp,flexcan"; reg = <0x40025000 0x1000>; interrupts = <85 0>, <86 0>, <87 0>, <88 0>; - interrupt-names = "warning", "error", "wake-up", - "mb-0-15"; - clocks = <&scg KINETIS_SCG_BUS_CLK>; + interrupt-names = "warning", "error", "wake-up", "mb-0-15"; + clocks = <&scg KINETIS_SCG_SOSC_ASYNC_DIV2_CLK>, <&scg KINETIS_SCG_BUS_CLK>; + clock-names = "clksrc0", "clksrc1"; clk-source = <1>; number-of-mb = <16>; status = "disabled"; diff --git a/dts/arm/nxp/nxp_mcxe24x_common.dtsi b/dts/arm/nxp/nxp_mcxe24x_common.dtsi index 35a2b1a1e0e4..69278670bb77 100644 --- a/dts/arm/nxp/nxp_mcxe24x_common.dtsi +++ b/dts/arm/nxp/nxp_mcxe24x_common.dtsi @@ -289,8 +289,9 @@ interrupts = <78 0>, <79 0>, <80 0>, <81 0>, <82 0>; interrupt-names = "ored-warning-bus-off", "error", "wake-up", "mb-0-15", "mb-16-31"; - - clocks = <&scg KINETIS_SCG_CORESYS_CLK>; + clocks = <&scg KINETIS_SCG_SOSC_ASYNC_DIV2_CLK>, + <&scg KINETIS_SCG_CORESYS_CLK>; + clock-names = "clksrc0", "clksrc1"; clk-source = <1>; status = "disabled"; }; @@ -300,7 +301,9 @@ reg = <0x40025000 0x1000>; interrupts = <85 0>, <86 0>, <88 0>, <89 0>; interrupt-names = "ored-warning-bus-off", "error", "mb-0-15", "mb-16-31"; - clocks = <&scg KINETIS_SCG_CORESYS_CLK>; + clocks = <&scg KINETIS_SCG_SOSC_ASYNC_DIV2_CLK>, + <&scg KINETIS_SCG_CORESYS_CLK>; + clock-names = "clksrc0", "clksrc1"; clk-source = <1>; status = "disabled"; }; @@ -310,7 +313,9 @@ reg = <0x4002b000 0x1000>; interrupts = <92 0>, <93 0>, <95 0>, <96 0>; interrupt-names = "ored-warning-bus-off", "error", "mb-0-15", "mb-16-31"; - clocks = <&scg KINETIS_SCG_CORESYS_CLK>; + clocks = <&scg KINETIS_SCG_SOSC_ASYNC_DIV2_CLK>, + <&scg KINETIS_SCG_CORESYS_CLK>; + clock-names = "clksrc0", "clksrc1"; clk-source = <1>; status = "disabled"; }; diff --git a/dts/arm/nxp/nxp_rt118x.dtsi b/dts/arm/nxp/nxp_rt118x.dtsi index 9cb31c1b7871..6abc73028713 100644 --- a/dts/arm/nxp/nxp_rt118x.dtsi +++ b/dts/arm/nxp/nxp_rt118x.dtsi @@ -785,6 +785,7 @@ interrupts = <8 0>, <9 0>; interrupt-names = "common", "error"; clocks = <&ccm IMX_CCM_CAN1_CLK 0x68 14>; + clock-names = "clksrc0"; clk-source = <0>; number-of-mb = <96>; number-of-mb-fd = <21>; @@ -797,6 +798,7 @@ interrupts = <51 0>, <52 0>; interrupt-names = "common", "error"; clocks = <&ccm IMX_CCM_CAN2_CLK 0x68 18>; + clock-names = "clksrc0"; clk-source = <0>; number-of-mb = <96>; number-of-mb-fd = <21>; @@ -809,6 +811,7 @@ interrupts = <191 0>, <192 0>; interrupt-names = "common", "error"; clocks = <&ccm IMX_CCM_CAN3_CLK 0x84 6>; + clock-names = "clksrc0"; clk-source = <0>; number-of-mb = <96>; number-of-mb-fd = <21>; diff --git a/dts/arm/nxp/nxp_rt11xx.dtsi b/dts/arm/nxp/nxp_rt11xx.dtsi index 7d39dfebdf13..9a05c425eabb 100644 --- a/dts/arm/nxp/nxp_rt11xx.dtsi +++ b/dts/arm/nxp/nxp_rt11xx.dtsi @@ -916,6 +916,7 @@ interrupts = <44 0>, <45 0>; interrupt-names = "common", "error"; clocks = <&ccm IMX_CCM_CAN1_CLK 0x68 14>; + clock-names = "clksrc0"; clk-source = <0>; number-of-mb = <64>; number-of-mb-fd = <14>; @@ -928,6 +929,7 @@ interrupts = <46 0>, <47 0>; interrupt-names = "common", "error"; clocks = <&ccm IMX_CCM_CAN2_CLK 0x68 18>; + clock-names = "clksrc0"; clk-source = <0>; number-of-mb = <64>; number-of-mb-fd = <14>; @@ -940,6 +942,7 @@ interrupts = <48 0>, <49 0>; interrupt-names = "common", "error"; clocks = <&ccm IMX_CCM_CAN3_CLK 0x84 6>; + clock-names = "clksrc0"; clk-source = <0>; number-of-mb = <64>; number-of-mb-fd = <14>; diff --git a/dts/arm/nxp/nxp_s32k146.dtsi b/dts/arm/nxp/nxp_s32k146.dtsi index bf25cde02f75..411d9c13552a 100644 --- a/dts/arm/nxp/nxp_s32k146.dtsi +++ b/dts/arm/nxp/nxp_s32k146.dtsi @@ -73,6 +73,8 @@ interrupts = <85 0>, <86 0>, <88 0>, <89 0>; interrupt-names = "warning", "error", "mb-0-15", "mb-16-31"; clocks = <&clock NXP_S32_FLEXCAN1_CLK>; + clock-names = "clksrc1"; + clk-source = <1>; number-of-mb = <32>; number-of-mb-fd = <7>; }; @@ -82,5 +84,7 @@ interrupts = <92 0>, <93 0>, <95 0>; interrupt-names = "warning", "error", "mb-0-15"; clocks = <&clock NXP_S32_FLEXCAN2_CLK>; + clock-names = "clksrc1"; + clk-source = <1>; number-of-mb = <16>; }; diff --git a/dts/arm/nxp/nxp_s32k148.dtsi b/dts/arm/nxp/nxp_s32k148.dtsi index a19d046999db..32de725ef2d5 100644 --- a/dts/arm/nxp/nxp_s32k148.dtsi +++ b/dts/arm/nxp/nxp_s32k148.dtsi @@ -96,6 +96,8 @@ interrupts = <85 0>, <86 0>, <88 0>, <89 0>; interrupt-names = "warning", "error", "mb-0-15", "mb-16-31"; clocks = <&clock NXP_S32_FLEXCAN1_CLK>; + clock-names = "clksrc1"; + clk-source = <1>; number-of-mb = <32>; number-of-mb-fd = <7>; }; @@ -104,6 +106,8 @@ interrupts = <92 0>, <93 0>, <95 0>, <96 0>; interrupt-names = "warning", "error", "mb-0-15", "mb-16-31"; clocks = <&clock NXP_S32_FLEXCAN2_CLK>; + clock-names = "clksrc1"; + clk-source = <1>; number-of-mb = <32>; number-of-mb-fd = <7>; }; diff --git a/dts/arm/nxp/nxp_s32k1xx.dtsi b/dts/arm/nxp/nxp_s32k1xx.dtsi index e2f0e87add55..72fb1b70747c 100644 --- a/dts/arm/nxp/nxp_s32k1xx.dtsi +++ b/dts/arm/nxp/nxp_s32k1xx.dtsi @@ -53,6 +53,7 @@ compatible = "nxp,flexcan-fd", "nxp,flexcan"; reg = <0x40024000 0x1000>; clocks = <&clock NXP_S32_FLEXCAN0_CLK>; + clock-names = "clksrc1"; clk-source = <1>; status = "disabled"; }; @@ -60,14 +61,12 @@ flexcan1: can@40025000 { compatible = "nxp,flexcan-fd", "nxp,flexcan"; reg = <0x40025000 0x1000>; - clk-source = <1>; status = "disabled"; }; flexcan2: can@4002b000 { compatible = "nxp,flexcan-fd", "nxp,flexcan"; reg = <0x4002b000 0x1000>; - clk-source = <1>; status = "disabled"; }; diff --git a/dts/arm64/nxp/nxp_mimx8mp_a53.dtsi b/dts/arm64/nxp/nxp_mimx8mp_a53.dtsi index 33fedafc7fc5..f16388707582 100644 --- a/dts/arm64/nxp/nxp_mimx8mp_a53.dtsi +++ b/dts/arm64/nxp/nxp_mimx8mp_a53.dtsi @@ -197,6 +197,7 @@ ; interrupt-names = "common", "error"; clocks = <&ccm IMX_CCM_CAN1_CLK 0x68 14>; + clock-names = "clksrc0"; clk-source = <0>; number-of-mb = <64>; number-of-mb-fd = <14>; @@ -213,6 +214,7 @@ ; interrupt-names = "common", "error"; clocks = <&ccm IMX_CCM_CAN2_CLK 0x68 14>; + clock-names = "clksrc0"; clk-source = <0>; number-of-mb = <64>; number-of-mb-fd = <14>; diff --git a/dts/arm64/nxp/nxp_mimx93_a55.dtsi b/dts/arm64/nxp/nxp_mimx93_a55.dtsi index 712a29f6663c..6ffb3e0a9187 100644 --- a/dts/arm64/nxp/nxp_mimx93_a55.dtsi +++ b/dts/arm64/nxp/nxp_mimx93_a55.dtsi @@ -419,6 +419,7 @@ ; interrupt-names = "common", "error"; clocks = <&ccm IMX_CCM_CAN1_CLK 0x68 14>; + clock-names = "clksrc0"; clk-source = <0>; number-of-mb = <96>; number-of-mb-fd = <21>; @@ -433,6 +434,7 @@ ; interrupt-names = "common", "error"; clocks = <&ccm IMX_CCM_CAN2_CLK 0x68 14>; + clock-names = "clksrc0"; clk-source = <0>; number-of-mb = <96>; number-of-mb-fd = <21>; diff --git a/dts/bindings/can/nxp,flexcan.yaml b/dts/bindings/can/nxp,flexcan.yaml index 1e53452d3434..2f6581effd24 100644 --- a/dts/bindings/can/nxp,flexcan.yaml +++ b/dts/bindings/can/nxp,flexcan.yaml @@ -36,12 +36,25 @@ properties: clocks: required: true + clock-names: + description: | + Required if the "clk-source" property is present. + clk-source: type: int enum: - 0 - 1 - description: CAN engine clock source + description: | + CAN engine clock source. The value of this property, if present, selects the corresponding + named clock from the "clocks" property. A value of "0" selects "clksrc0" whereas a value of + "1" selects "clksrc1". + + The value of this property is written to the CLKSRC bit of the FlexCAN CTRL1 register for + controlling the 1-bit, internal clock multiplexer. + + Omit this property for FlexCAN instances that do not have a 1-bit, internal multiplexer + (FlexCAN CTRL1 register bit 13 is marked as "reserved"). number-of-mb: type: int From b5980bcc75134f97e5134787d4e4f7e29bc82c76 Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Sun, 11 Jan 2026 19:17:17 +0000 Subject: [PATCH 1868/3659] doc: releases: migration-guide: 4.4: mention change to FlexCAN DT clock Mention that the NXP FlexCAN devicetree property "clk-source" now automatically selects between named input clocks. Signed-off-by: Henrik Brix Andersen --- doc/releases/migration-guide-4.4.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/releases/migration-guide-4.4.rst b/doc/releases/migration-guide-4.4.rst index 7dcbc912c9cf..ba954b018f5a 100644 --- a/doc/releases/migration-guide-4.4.rst +++ b/doc/releases/migration-guide-4.4.rst @@ -104,6 +104,10 @@ Controller Area Network (CAN) :dtcompatible:`nxp,flexcan-fd` with per-instance ``number-of-mb`` and ``number-of-mb-fd`` devicetree properties (:github:`99483`). +* The :dtcompatible:`nxp,flexcan` ``clk-source`` devicetree property, if present, now automatically + selects between the named input clocks ``clksrc0`` and ``clksrc1`` for use as the CAN protocol + engine clock. + Counter ======= From c6a959dcc3dd15287b054724d308b361689ed797 Mon Sep 17 00:00:00 2001 From: Scott Worley Date: Wed, 3 Dec 2025 15:08:54 -0500 Subject: [PATCH 1869/3659] drivers: serial: microchip: mec: Common UART driver We modified the Microchip MEC UART driver to be HAL independent and be usuable on all MEC SoCs. The only hardware difference is an extra register in the MEC174x/5x family providing TX FIFO full and current byte count. Signed-off-by: Scott Worley --- drivers/serial/CMakeLists.txt | 1 - drivers/serial/Kconfig | 1 - drivers/serial/Kconfig.mec5 | 28 - drivers/serial/uart_mchp_mec5.c | 662 ------------- drivers/serial/uart_mchp_xec.c | 893 ++++++++---------- dts/bindings/serial/microchip,mec5-uart.yaml | 55 -- dts/bindings/serial/microchip,xec-uart.yaml | 17 +- .../zephyr/dt-bindings/clock/mchp_xec_pcr.h | 29 +- soc/microchip/mec/common/CMakeLists.txt | 2 +- soc/microchip/mec/common/reg/mec_uart.h | 296 +++--- soc/microchip/mec/common/soc_mmcr.h | 25 + soc/microchip/mec/common/soc_pcr.c | 25 + soc/microchip/mec/common/soc_pcr.h | 87 +- soc/microchip/mec/mec15xx/soc.h | 2 +- soc/microchip/mec/mec165xb/soc.h | 18 +- soc/microchip/mec/mec174x/soc.h | 5 +- soc/microchip/mec/mec175x/soc.h | 4 +- 17 files changed, 713 insertions(+), 1437 deletions(-) delete mode 100644 drivers/serial/Kconfig.mec5 delete mode 100644 drivers/serial/uart_mchp_mec5.c delete mode 100644 dts/bindings/serial/microchip,mec5-uart.yaml create mode 100644 soc/microchip/mec/common/soc_pcr.c diff --git a/drivers/serial/CMakeLists.txt b/drivers/serial/CMakeLists.txt index 66387f5b2cad..3090a33b5ffc 100644 --- a/drivers/serial/CMakeLists.txt +++ b/drivers/serial/CMakeLists.txt @@ -50,7 +50,6 @@ zephyr_library_sources_ifdef(CONFIG_UART_ITE_IT8XXX2 uart_ite_it8xxx2.c) zephyr_library_sources_ifdef(CONFIG_UART_LITEX uart_litex.c) zephyr_library_sources_ifdef(CONFIG_UART_LPC11U6X uart_lpc11u6x.c) zephyr_library_sources_ifdef(CONFIG_UART_MAX32 uart_max32.c) -zephyr_library_sources_ifdef(CONFIG_UART_MCHP_MEC5 uart_mchp_mec5.c) zephyr_library_sources_ifdef(CONFIG_UART_MCHP_SERCOM_G1 uart_mchp_sercom_g1.c) zephyr_library_sources_ifdef(CONFIG_UART_MCUX uart_mcux.c) zephyr_library_sources_ifdef(CONFIG_UART_MCUX_FLEXCOMM uart_mcux_flexcomm.c) diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index f9837c53bbaa..ce7ea1c12a65 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -197,7 +197,6 @@ rsource "Kconfig.mcux_flexcomm" rsource "Kconfig.mcux_iuart" rsource "Kconfig.mcux_lpsci" rsource "Kconfig.mcux_lpuart" -rsource "Kconfig.mec5" rsource "Kconfig.miv" rsource "Kconfig.msp432p4xx" rsource "Kconfig.mspm0" diff --git a/drivers/serial/Kconfig.mec5 b/drivers/serial/Kconfig.mec5 deleted file mode 100644 index d02392a06234..000000000000 --- a/drivers/serial/Kconfig.mec5 +++ /dev/null @@ -1,28 +0,0 @@ -# Microchip MEC5 UART - -# Copyright (c) 2024 Microchip Technology Inc. -# SPDX-License-Identifier: Apache-2.0 - -config UART_MCHP_MEC5 - bool "Microchip MEC5 family ns16550 compatible UART driver" - default y - depends on DT_HAS_MICROCHIP_MEC5_UART_ENABLED - select PINCTRL - select SERIAL_HAS_DRIVER - select SERIAL_SUPPORT_INTERRUPT - help - This option enables the UART driver for Microchip MEC5 - family processors. - -if UART_MCHP_MEC5 - -config UART_MCHP_MEC5_LINE_CTRL - bool "Serial Line Control for Apps" - depends on UART_LINE_CTRL - help - This enables the API for apps to control the serial line, - such as CTS and RTS. - - Says n if not sure. - -endif # UART_MCHP_MEC5 diff --git a/drivers/serial/uart_mchp_mec5.c b/drivers/serial/uart_mchp_mec5.c deleted file mode 100644 index 61f0a010e839..000000000000 --- a/drivers/serial/uart_mchp_mec5.c +++ /dev/null @@ -1,662 +0,0 @@ -/* - * Copyright (c) 2024 Microchip Technology Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @brief Microchip MEC5 ns16550 compatible UART Serial Driver - */ - -#define DT_DRV_COMPAT microchip_mec5_uart - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -LOG_MODULE_REGISTER(uart_mec5, CONFIG_UART_LOG_LEVEL); - -/* MEC5 HAL */ -#include -#include -#include - -#define UART_MEC_DFLT_CLK_FREQ 1843200u -#define UART_MEC_DEVCFG_FLAG_RX_FIFO_TRIG_POS 0 -#define UART_MEC_DEVCFG_FLAG_RX_FIFO_TRIG_MSK 0x3u -#define UART_MEC_DEVCFG_FLAG_FIFO_DIS_POS 4 -#define UART_MEC_DEVCFG_FLAG_USE_EXTCLK_POS 5 - -struct uart_mec5_devcfg { - struct mec_uart_regs *regs; - const struct pinctrl_dev_config *pcfg; - uint32_t clock_freq; - uint32_t flags; -#ifdef CONFIG_UART_INTERRUPT_DRIVEN - void (*irq_config_func)(const struct device *dev); -#endif -}; - -struct uart_mec5_dev_data { - const struct device *dev; - struct uart_config current_config; - struct uart_config ucfg; - struct k_spinlock lock; - enum mec_uart_ipend ipend; -#ifdef CONFIG_UART_INTERRUPT_DRIVEN - uart_irq_callback_user_data_t cb; /* Callback function pointer */ - void *cb_data; /* Callback function arg */ - uint32_t flags; - uint8_t rx_enabled; - uint8_t tx_enabled; -#endif -}; - -static const uint8_t mec5_xlat_word_len[4] = { - MEC_UART_WORD_LEN_5, - MEC_UART_WORD_LEN_6, - MEC_UART_WORD_LEN_7, - MEC_UART_WORD_LEN_8, -}; - -static const uint8_t mec5_xlat_stop_bits[4] = { - MEC_UART_STOP_BITS_1, - MEC_UART_STOP_BITS_1, - MEC_UART_STOP_BITS_2, - MEC_UART_STOP_BITS_2, -}; - -static const uint8_t mec5_xlat_parity[5] = { - (uint8_t)(MEC5_UART_CFG_PARITY_NONE >> MEC5_UART_CFG_PARITY_POS), - (uint8_t)(MEC5_UART_CFG_PARITY_ODD >> MEC5_UART_CFG_PARITY_POS), - (uint8_t)(MEC5_UART_CFG_PARITY_EVEN >> MEC5_UART_CFG_PARITY_POS), - (uint8_t)(MEC5_UART_CFG_PARITY_MARK >> MEC5_UART_CFG_PARITY_POS), - (uint8_t)(MEC5_UART_CFG_PARITY_SPACE >> MEC5_UART_CFG_PARITY_POS), -}; - -static int uart_mec5_xlat_cfg(const struct uart_config *cfg, uint32_t *cfg_word) -{ - uint32_t temp; - - if (!cfg || !cfg_word) { - return -EINVAL; - } - - *cfg_word = 0u; - - if (cfg->data_bits > UART_CFG_DATA_BITS_8) { - return -EINVAL; - } - temp = mec5_xlat_word_len[cfg->data_bits]; - *cfg_word |= ((temp << MEC5_UART_CFG_WORD_LEN_POS) & MEC5_UART_CFG_WORD_LEN_MSK); - - if (cfg->stop_bits > UART_CFG_STOP_BITS_2) { - return -EINVAL; - } - temp = mec5_xlat_stop_bits[cfg->stop_bits]; - *cfg_word |= ((temp << MEC5_UART_CFG_STOP_BITS_POS) & MEC5_UART_CFG_STOP_BITS_MSK); - - if (cfg->parity > UART_CFG_PARITY_SPACE) { - return -EINVAL; - } - temp = mec5_xlat_parity[cfg->parity]; - *cfg_word |= ((temp << MEC5_UART_CFG_PARITY_POS) & MEC5_UART_CFG_PARITY_MSK); - - return 0; -} - -/* Configure UART TX and RX FIFOs based on device tree. - * Both FIFOs are fixed 16-byte. - * RX FIFO has a configurable interrupt trigger level of 1, 4, 8, or 14 bytes. - */ -static uint32_t uart_mec5_fifo_config(uint32_t mcfg, uint32_t cfg_flags) -{ - uint32_t new_mcfg = mcfg; - uint32_t temp = 0; - - if (!(cfg_flags & BIT(UART_MEC_DEVCFG_FLAG_FIFO_DIS_POS))) { - new_mcfg |= BIT(MEC5_UART_CFG_FIFO_EN_POS); - temp = (cfg_flags & UART_MEC_DEVCFG_FLAG_RX_FIFO_TRIG_MSK) >> - UART_MEC_DEVCFG_FLAG_RX_FIFO_TRIG_POS; - switch (temp) { - case 0: - new_mcfg |= MEC5_UART_CFG_RX_FIFO_TRIG_LVL_1; - break; - case 1: - new_mcfg |= MEC5_UART_CFG_RX_FIFO_TRIG_LVL_4; - break; - case 2: - new_mcfg |= MEC5_UART_CFG_RX_FIFO_TRIG_LVL_8; - break; - default: - new_mcfg |= MEC5_UART_CFG_RX_FIFO_TRIG_LVL_14; - break; - } - } - - return new_mcfg; -} - -static int config_mec5_uart(const struct device *dev, const struct uart_config *cfg) -{ - const struct uart_mec5_devcfg *devcfg = dev->config; - struct mec_uart_regs *const regs = devcfg->regs; - struct uart_mec5_dev_data *const data = dev->data; - int ret = 0; - uint32_t mcfg = 0, extclk = 0; - - data->ipend = MEC_UART_IPEND_NONE; - - ret = uart_mec5_xlat_cfg(cfg, &mcfg); - if (ret) { - return ret; - } - - mcfg = uart_mec5_fifo_config(mcfg, devcfg->flags); - mcfg |= BIT(MEC5_UART_CFG_GIRQ_EN_POS); - - if (devcfg->flags & BIT(UART_MEC_DEVCFG_FLAG_USE_EXTCLK_POS)) { - extclk = devcfg->clock_freq; - } - - ret = mec_hal_uart_init(regs, cfg->baudrate, mcfg, extclk); - if (ret != MEC_RET_OK) { - return -EIO; - } - - memcpy(&data->ucfg, cfg, sizeof(struct uart_config)); - - return ret; -}; - -#ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE -/* run-time driver configuration API */ -static int uart_mec5_configure(const struct device *dev, const struct uart_config *cfg) -{ - const struct uart_mec5_devcfg *devcfg = dev->config; - struct uart_mec5_dev_data *const data = dev->data; - int ret = 0; - k_spinlock_key_t key = k_spin_lock(&data->lock); - - ret = pinctrl_apply_state(devcfg->pcfg, PINCTRL_STATE_DEFAULT); - if (ret) { - LOG_ERR("MEC5 UART pinctrl error (%d)", ret); - } - - ret = config_mec5_uart(dev, cfg); - if (ret) { - LOG_ERR("MEC5 UART config error (%d)", ret); - return ret; - } - - data->current_config = *cfg; - - k_spin_unlock(&data->lock, key); - - return ret; -} - -static int uart_mec5_config_get(const struct device *dev, struct uart_config *cfg) -{ - struct uart_mec5_dev_data *const data = dev->data; - - if (!cfg) { - return -EINVAL; - } - - k_spinlock_key_t key = k_spin_lock(&data->lock); - - *cfg = data->current_config; - - k_spin_unlock(&data->lock, key); - - return 0; -} -#endif /* CONFIG_UART_USE_RUNTIME_CONFIGURE */ - -/* Called by kernel during driver initialization phase */ -static int uart_mec5_init(const struct device *dev) -{ - const struct uart_mec5_devcfg *devcfg = dev->config; - struct uart_mec5_dev_data *data = dev->data; - int ret = 0; - - ret = pinctrl_apply_state(devcfg->pcfg, PINCTRL_STATE_DEFAULT); - if (ret) { - LOG_ERR("MEC5 UART init pinctrl error (%d)", ret); - return ret; - } - - ret = config_mec5_uart(dev, &data->ucfg); - if (ret != 0) { - return -EIO; - } - - return ret; -} - -/* - * Poll the UART for input. - * return 0 is a byte arrived else -1 if no data. - */ -static int uart_mec5_poll_in(const struct device *dev, unsigned char *cptr) -{ - const struct uart_mec5_devcfg *devcfg = dev->config; - struct mec_uart_regs *const regs = devcfg->regs; - struct uart_mec5_dev_data *data = dev->data; - k_spinlock_key_t key = k_spin_lock(&data->lock); - int ret = 0; - - ret = mec_hal_uart_rx_byte(regs, (uint8_t *)cptr); - if (ret == MEC_RET_ERR_NO_DATA) { - k_spin_unlock(&data->lock, key); - return -1; - } - - k_spin_unlock(&data->lock, key); - - return 0; -} - -/* Block until UART can accept data byte. */ -static void uart_mec5_poll_out(const struct device *dev, unsigned char out_data) -{ - const struct uart_mec5_devcfg *devcfg = dev->config; - struct mec_uart_regs *const regs = devcfg->regs; - struct uart_mec5_dev_data *data = dev->data; - k_spinlock_key_t key = k_spin_lock(&data->lock); - int ret = 0; - - do { - ret = mec_hal_uart_tx_byte(regs, (uint8_t)out_data); - } while (ret == MEC_RET_ERR_BUSY); - - k_spin_unlock(&data->lock, key); -} - -#ifdef CONFIG_UART_INTERRUPT_DRIVEN -static inline void irq_tx_enable(const struct device *dev) -{ - const struct uart_mec5_devcfg *devcfg = dev->config; - struct mec_uart_regs *const regs = devcfg->regs; - struct uart_mec5_dev_data *data = dev->data; - k_spinlock_key_t key = k_spin_lock(&data->lock); - - mec_hal_uart_intr_mask(regs, MEC_UART_IEN_FLAG_ETHREI, MEC_UART_IEN_FLAG_ETHREI); - - k_spin_unlock(&data->lock, key); -} - -static inline void irq_tx_disable(const struct device *dev) -{ - const struct uart_mec5_devcfg *devcfg = dev->config; - struct uart_mec5_dev_data *data = dev->data; - struct mec_uart_regs *const regs = devcfg->regs; - k_spinlock_key_t key = k_spin_lock(&data->lock); - - mec_hal_uart_intr_mask(regs, MEC_UART_IEN_FLAG_ETHREI, 0); - - k_spin_unlock(&data->lock, key); -} - -static inline void irq_rx_enable(const struct device *dev) -{ - const struct uart_mec5_devcfg *const devcfg = dev->config; - struct uart_mec5_dev_data *data = dev->data; - struct mec_uart_regs *const regs = devcfg->regs; - k_spinlock_key_t key = k_spin_lock(&data->lock); - - mec_hal_uart_intr_mask(regs, MEC_UART_IEN_FLAG_ERDAI, MEC_UART_IEN_FLAG_ERDAI); - - k_spin_unlock(&data->lock, key); -} - -static inline void irq_rx_disable(const struct device *dev) -{ - const struct uart_mec5_devcfg *const devcfg = dev->config; - struct uart_mec5_dev_data *data = dev->data; - struct mec_uart_regs *const regs = devcfg->regs; - k_spinlock_key_t key = k_spin_lock(&data->lock); - - mec_hal_uart_intr_mask(regs, MEC_UART_IEN_FLAG_ERDAI, 0); - - k_spin_unlock(&data->lock, key); -} - -static int uart_mec5_fifo_fill(const struct device *dev, const uint8_t *tx_data, int len) -{ - const struct uart_mec5_devcfg *const devcfg = dev->config; - struct uart_mec5_dev_data *data = dev->data; - struct mec_uart_regs *const regs = devcfg->regs; - int num_tx = 0, ret = 0; - - if (len < 0) { - return 0; - } - - k_spinlock_key_t key = k_spin_lock(&data->lock); - - while (num_tx < len) { - ret = mec_hal_uart_tx_byte(regs, tx_data[num_tx]); - if (ret == MEC_RET_ERR_BUSY) { - break; - } - num_tx++; - } - - if (data->tx_enabled) { - irq_tx_enable(dev); - } - - k_spin_unlock(&data->lock, key); - - return num_tx; -} - -static int uart_mec5_fifo_read(const struct device *dev, uint8_t *rx_data, const int size) -{ - const struct uart_mec5_devcfg *const devcfg = dev->config; - struct uart_mec5_dev_data *data = dev->data; - struct mec_uart_regs *const regs = devcfg->regs; - int num_rx = 0, ret = 0; - - if (size < 0) { - return 0; - } - - k_spinlock_key_t key = k_spin_lock(&data->lock); - uint8_t *pdata = rx_data; - - while (num_rx < size) { - ret = mec_hal_uart_rx_byte(regs, pdata); - if (ret != MEC_RET_OK) { - break; - } - pdata++; - num_rx++; - } - - if (data->rx_enabled) { - irq_rx_enable(dev); - } - - k_spin_unlock(&data->lock, key); - - return num_rx; -} - -static void uart_mec5_irq_tx_enable(const struct device *dev) -{ - struct uart_mec5_dev_data *data = dev->data; - k_spinlock_key_t key = k_spin_lock(&data->lock); - - data->tx_enabled = 1; - irq_tx_enable(dev); - - k_spin_unlock(&data->lock, key); -} - -static void uart_mec5_irq_tx_disable(const struct device *dev) -{ - struct uart_mec5_dev_data *data = dev->data; - k_spinlock_key_t key = k_spin_lock(&data->lock); - - irq_tx_disable(dev); - data->tx_enabled = 0; - - k_spin_unlock(&data->lock, key); -} - -static int uart_mec5_irq_tx_ready(const struct device *dev) -{ - struct uart_mec5_dev_data *data = dev->data; - k_spinlock_key_t key = k_spin_lock(&data->lock); - int ret = 0; - - if (data->ipend == MEC_UART_IPEND_TX) { - ret = 1; - } - - k_spin_unlock(&data->lock, key); - - return ret; -} - -static void uart_mec5_irq_rx_enable(const struct device *dev) -{ - struct uart_mec5_dev_data *data = dev->data; - k_spinlock_key_t key = k_spin_lock(&data->lock); - - data->rx_enabled = 1; - irq_rx_enable(dev); - - k_spin_unlock(&data->lock, key); -} - -static void uart_mec5_irq_rx_disable(const struct device *dev) -{ - struct uart_mec5_dev_data *data = dev->data; - k_spinlock_key_t key = k_spin_lock(&data->lock); - - irq_rx_disable(dev); - data->rx_enabled = 0; - - k_spin_unlock(&data->lock, key); -} - -/* check if UART TX shift register is empty. Empty TX shift register indicates - * the UART does not need clocks and can be put into a low power state. - * return 1 nothing remains to be transmitted, 0 otherwise. - */ -static int uart_mec5_irq_tx_complete(const struct device *dev) -{ - const struct uart_mec5_devcfg *const devcfg = dev->config; - struct mec_uart_regs *const regs = devcfg->regs; - struct uart_mec5_dev_data *data = dev->data; - k_spinlock_key_t key = k_spin_lock(&data->lock); - int ret = mec_hal_uart_is_tx_empty(regs); - - k_spin_unlock(&data->lock, key); - - return ret; -} - -static int uart_mec5_irq_rx_ready(const struct device *dev) -{ - struct uart_mec5_dev_data *data = dev->data; - int ret = 0; - k_spinlock_key_t key = k_spin_lock(&data->lock); - - if (data->ipend == MEC_UART_IPEND_RX_DATA) { - ret = 1; - } - - k_spin_unlock(&data->lock, key); - - return ret; -} - -static void irq_error_enable(const struct device *dev, uint8_t enable) -{ - const struct uart_mec5_devcfg *const devcfg = dev->config; - struct mec_uart_regs *const regs = devcfg->regs; - uint8_t msk = 0; - - if (enable) { - msk = MEC_UART_IEN_FLAG_ELSI; - } - - mec_hal_uart_intr_mask(regs, MEC_UART_IEN_FLAG_ELSI, msk); -} - -/* - * Enable received line status interrupt active when one or more of the following errors - * occur: overrun, parity, framing, or break. - */ -static void uart_mec5_irq_err_enable(const struct device *dev) -{ - struct uart_mec5_dev_data *data = dev->data; - k_spinlock_key_t key = k_spin_lock(&data->lock); - - irq_error_enable(dev, 1u); - - k_spin_unlock(&data->lock, key); -} - -static void uart_mec5_irq_err_disable(const struct device *dev) -{ - struct uart_mec5_dev_data *data = dev->data; - k_spinlock_key_t key = k_spin_lock(&data->lock); - - irq_error_enable(dev, 0); - - k_spin_unlock(&data->lock, key); -} - -static int uart_mec5_irq_is_pending(const struct device *dev) -{ - struct uart_mec5_dev_data *data = dev->data; - k_spinlock_key_t key = k_spin_lock(&data->lock); - int ret = 0; - - if (data->ipend != MEC_UART_IPEND_NONE) { - ret = 1; - } - - k_spin_unlock(&data->lock, key); - - return ret; -} - -static int uart_mec5_irq_update(const struct device *dev) -{ - const struct uart_mec5_devcfg *const devcfg = dev->config; - struct mec_uart_regs *const regs = devcfg->regs; - struct uart_mec5_dev_data *data = dev->data; - k_spinlock_key_t key = k_spin_lock(&data->lock); - - data->ipend = MEC_UART_IPEND_NONE; - mec_hal_uart_pending_status(regs, &data->ipend); - - switch (data->ipend) { - case MEC_UART_IPEND_NONE: - break; - case MEC_UART_IPEND_TX: - irq_tx_disable(dev); - break; - case MEC_UART_IPEND_RX_DATA: - irq_rx_disable(dev); - break; - case MEC_UART_IPEND_RX_ERR: - irq_error_enable(dev, 0); - break; - case MEC_UART_IPEND_MODEM: - __fallthrough; /* fall through */ - default: - k_panic(); - break; - } - - k_spin_unlock(&data->lock, key); - - return 1; -} - -static void uart_mec5_irq_callback_set(const struct device *dev, uart_irq_callback_user_data_t cb, - void *cb_data) -{ - struct uart_mec5_dev_data *data = dev->data; - k_spinlock_key_t key = k_spin_lock(&data->lock); - - data->cb = cb; - data->cb_data = cb_data; - - k_spin_unlock(&data->lock, key); -} - -static void uart_mec5_isr(const struct device *dev) -{ - struct uart_mec5_dev_data *data = dev->data; - - if (data->cb) { - data->cb(dev, data->cb_data); - } -} -#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ - -static DEVICE_API(uart, uart_mec5_driver_api) = { - .poll_in = uart_mec5_poll_in, - .poll_out = uart_mec5_poll_out, -#ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE - .configure = uart_mec5_configure, - .config_get = uart_mec5_config_get, -#endif -#ifdef CONFIG_UART_INTERRUPT_DRIVEN - .fifo_fill = uart_mec5_fifo_fill, - .fifo_read = uart_mec5_fifo_read, - .irq_tx_enable = uart_mec5_irq_tx_enable, - .irq_tx_disable = uart_mec5_irq_tx_disable, - .irq_tx_ready = uart_mec5_irq_tx_ready, - .irq_rx_enable = uart_mec5_irq_rx_enable, - .irq_rx_disable = uart_mec5_irq_rx_disable, - .irq_tx_complete = uart_mec5_irq_tx_complete, - .irq_rx_ready = uart_mec5_irq_rx_ready, - .irq_err_enable = uart_mec5_irq_err_enable, - .irq_err_disable = uart_mec5_irq_err_disable, - .irq_is_pending = uart_mec5_irq_is_pending, - .irq_update = uart_mec5_irq_update, - .irq_callback_set = uart_mec5_irq_callback_set, -#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ -}; - -#ifdef CONFIG_UART_INTERRUPT_DRIVEN -#define UART_MEC5_CONFIGURE(n) \ - do { \ - IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority), uart_mec5_isr, \ - DEVICE_DT_INST_GET(n), 0); \ - \ - irq_enable(DT_INST_IRQN(n)); \ - } while (0) -#else -#define UART_MEC5_CONFIGURE(n) -#endif - -#define UART_MEC5_DCFG_FLAGS(i) \ - ((DT_INST_ENUM_IDX_OR(i, rx_fifo_trig, 2) & 0x3u) | \ - ((DT_INST_PROP_OR(i, fifo_mode_disable, 0) & 0x1u) << 4) | \ - ((DT_INST_PROP_OR(i, use_extclk, 0) & 0x1u) << 5)) - -#define DEV_DATA_FLOW_CTRL(n) DT_INST_PROP_OR(n, hw_flow_control, UART_CFG_FLOW_CTRL_NONE) - -#define UART_MEC5_DEVICE(i) \ - PINCTRL_DT_INST_DEFINE(i); \ - static const struct uart_mec5_devcfg uart_mec5_##i##_devcfg = { \ - .regs = (struct mec_uart_regs *)DT_INST_REG_ADDR(i), \ - .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(i), \ - .clock_freq = DT_INST_PROP_OR(i, clock_frequency, UART_MEC_DFLT_CLK_FREQ), \ - .flags = UART_MEC5_DCFG_FLAGS(i), \ - }; \ - static struct uart_mec5_dev_data uart_mec5_##i##_dev_data = { \ - .ucfg.baudrate = DT_INST_PROP_OR(i, current_speed, 0), \ - .ucfg.parity = UART_CFG_PARITY_NONE, \ - .ucfg.stop_bits = UART_CFG_STOP_BITS_1, \ - .ucfg.data_bits = UART_CFG_DATA_BITS_8, \ - .ucfg.flow_ctrl = DEV_DATA_FLOW_CTRL(i), \ - }; \ - static int uart_mec5_##i##_init(const struct device *dev) \ - { \ - UART_MEC5_CONFIGURE(i); \ - return uart_mec5_init(dev); \ - } \ - DEVICE_DT_INST_DEFINE(i, uart_mec5_##i##_init, NULL, &uart_mec5_##i##_dev_data, \ - &uart_mec5_##i##_devcfg, PRE_KERNEL_1, CONFIG_SERIAL_INIT_PRIORITY, \ - &uart_mec5_driver_api); - -DT_INST_FOREACH_STATUS_OKAY(UART_MEC5_DEVICE) diff --git a/drivers/serial/uart_mchp_xec.c b/drivers/serial/uart_mchp_xec.c index 61310ebe015d..92a7f0477f5c 100644 --- a/drivers/serial/uart_mchp_xec.c +++ b/drivers/serial/uart_mchp_xec.c @@ -9,168 +9,39 @@ /** * @brief Microchip XEC UART Serial Driver * - * This is the driver for the Microchip XEC MCU UART. It is NS16550 compatible. + * This is the driver for the Microchip XEC MCU UART. It is mostly NS16550 compatible. * */ #define DT_DRV_COMPAT microchip_xec_uart -#include -#include -#include -#include #include - -#include -#include -#include -#ifdef CONFIG_SOC_SERIES_MEC172X -#include -#include -#endif +#include +#include #include #include -#include -#include -#include +#include +#include #include #include #include +#include #include LOG_MODULE_REGISTER(uart_xec, CONFIG_UART_LOG_LEVEL); -/* Clock source is 1.8432 MHz derived from PLL 48 MHz */ -#define XEC_UART_CLK_SRC_1P8M 0 -/* Clock source is PLL 48 MHz output */ -#define XEC_UART_CLK_SRC_48M 1 -/* Clock source is the UART_CLK alternate pin function. */ -#define XEC_UART_CLK_SRC_EXT_PIN 2 - -/* register definitions */ - -#define REG_THR 0x00 /* Transmitter holding reg. */ -#define REG_RDR 0x00 /* Receiver data reg. */ -#define REG_BRDL 0x00 /* Baud rate divisor (LSB) */ -#define REG_BRDH 0x01 /* Baud rate divisor (MSB) */ -#define REG_IER 0x01 /* Interrupt enable reg. */ -#define REG_IIR 0x02 /* Interrupt ID reg. */ -#define REG_FCR 0x02 /* FIFO control reg. */ -#define REG_LCR 0x03 /* Line control reg. */ -#define REG_MDC 0x04 /* Modem control reg. */ -#define REG_LSR 0x05 /* Line status reg. */ -#define REG_MSR 0x06 /* Modem status reg. */ -#define REG_SCR 0x07 /* scratch register */ -#define REG_LD_ACTV 0x330 /* Logical Device activate */ -#define REG_LD_CFG 0x3f0 /* Logical Device configuration */ - -/* equates for interrupt enable register */ - -#define IER_RXRDY 0x01 /* receiver data ready */ -#define IER_TBE 0x02 /* transmit bit enable */ -#define IER_LSR 0x04 /* line status interrupts */ -#define IER_MSI 0x08 /* modem status interrupts */ - -/* equates for interrupt identification register */ - -#define IIR_MSTAT 0x00 /* modem status interrupt */ -#define IIR_NIP 0x01 /* no interrupt pending */ -#define IIR_THRE 0x02 /* transmit holding register empty interrupt */ -#define IIR_RBRF 0x04 /* receiver buffer register full interrupt */ -#define IIR_LS 0x06 /* receiver line status interrupt */ -#define IIR_MASK 0x07 /* interrupt id bits mask */ -#define IIR_ID 0x06 /* interrupt ID mask without NIP */ - -/* equates for FIFO control register */ - -#define FCR_FIFO 0x01 /* enable XMIT and RCVR FIFO */ -#define FCR_RCVRCLR 0x02 /* clear RCVR FIFO */ -#define FCR_XMITCLR 0x04 /* clear XMIT FIFO */ - -/* - * Per PC16550D (Literature Number: SNLS378B): - * - * RXRDY, Mode 0: When in the 16450 Mode (FCR0 = 0) or in - * the FIFO Mode (FCR0 = 1, FCR3 = 0) and there is at least 1 - * character in the RCVR FIFO or RCVR holding register, the - * RXRDY pin (29) will be low active. Once it is activated the - * RXRDY pin will go inactive when there are no more charac- - * ters in the FIFO or holding register. - * - * RXRDY, Mode 1: In the FIFO Mode (FCR0 = 1) when the - * FCR3 = 1 and the trigger level or the timeout has been - * reached, the RXRDY pin will go low active. Once it is acti- - * vated it will go inactive when there are no more characters - * in the FIFO or holding register. - * - * TXRDY, Mode 0: In the 16450 Mode (FCR0 = 0) or in the - * FIFO Mode (FCR0 = 1, FCR3 = 0) and there are no charac- - * ters in the XMIT FIFO or XMIT holding register, the TXRDY - * pin (24) will be low active. Once it is activated the TXRDY - * pin will go inactive after the first character is loaded into the - * XMIT FIFO or holding register. - * - * TXRDY, Mode 1: In the FIFO Mode (FCR0 = 1) when - * FCR3 = 1 and there are no characters in the XMIT FIFO, the - * TXRDY pin will go low active. This pin will become inactive - * when the XMIT FIFO is completely full. - */ -#define FCR_MODE0 0x00 /* set receiver in mode 0 */ -#define FCR_MODE1 0x08 /* set receiver in mode 1 */ - -/* RCVR FIFO interrupt levels: trigger interrupt with this bytes in FIFO */ -#define FCR_FIFO_1 0x00 /* 1 byte in RCVR FIFO */ -#define FCR_FIFO_4 0x40 /* 4 bytes in RCVR FIFO */ -#define FCR_FIFO_8 0x80 /* 8 bytes in RCVR FIFO */ -#define FCR_FIFO_14 0xC0 /* 14 bytes in RCVR FIFO */ - -/* constants for line control register */ - -#define LCR_CS5 0x00 /* 5 bits data size */ -#define LCR_CS6 0x01 /* 6 bits data size */ -#define LCR_CS7 0x02 /* 7 bits data size */ -#define LCR_CS8 0x03 /* 8 bits data size */ -#define LCR_2_STB 0x04 /* 2 stop bits */ -#define LCR_1_STB 0x00 /* 1 stop bit */ -#define LCR_PEN 0x08 /* parity enable */ -#define LCR_PDIS 0x00 /* parity disable */ -#define LCR_EPS 0x10 /* even parity select */ -#define LCR_SP 0x20 /* stick parity select */ -#define LCR_SBRK 0x40 /* break control bit */ -#define LCR_DLAB 0x80 /* divisor latch access enable */ - -/* constants for the modem control register */ - -#define MCR_DTR 0x01 /* dtr output */ -#define MCR_RTS 0x02 /* rts output */ -#define MCR_OUT1 0x04 /* output #1 */ -#define MCR_OUT2 0x08 /* output #2 */ -#define MCR_LOOP 0x10 /* loop back */ -#define MCR_AFCE 0x20 /* auto flow control enable */ - -/* constants for line status register */ - -#define LSR_RXRDY 0x01 /* receiver data available */ -#define LSR_OE 0x02 /* overrun error */ -#define LSR_PE 0x04 /* parity error */ -#define LSR_FE 0x08 /* framing error */ -#define LSR_BI 0x10 /* break interrupt */ -#define LSR_EOB_MASK 0x1E /* Error or Break mask */ -#define LSR_THRE 0x20 /* transmit holding register empty */ -#define LSR_TEMT 0x40 /* transmitter empty */ - -/* constants for modem status register */ - -#define MSR_DCTS 0x01 /* cts change */ -#define MSR_DDSR 0x02 /* dsr change */ -#define MSR_DRI 0x04 /* ring change */ -#define MSR_DDCD 0x08 /* data carrier change */ -#define MSR_CTS 0x10 /* complement of cts */ -#define MSR_DSR 0x20 /* complement of dsr */ -#define MSR_RI 0x40 /* complement of ring signal */ -#define MSR_DCD 0x80 /* complement of dcd */ - -#define IIRC(dev) (((struct uart_xec_dev_data *)(dev)->data)->iir_cache) +#define XEC_UART_FIN_HZ 1843200u +#define XEC_UART_FIN_HS_HZ 48000000u +#define XEC_UART_BRG_ROUNDING_MULT 16u +#define XEC_UART_BRG_ROUNDING_MSK 0xfu +#define XEC_UART_BRG_ROUNDING_UP 8u +#define XEC_UART_FIN_HZ_RM (XEC_UART_FIN_HZ * XEC_UART_BRG_ROUNDING_MULT) +#define XEC_UART_FIN_HS_HZ_RM (XEC_UART_FIN_HS_HZ * XEC_UART_BRG_ROUNDING_MULT) +#define XEC_UART_BRG_HW_MULT 16u +#define XEC_UART_MAX_BAUD 115200u +#define XEC_UART_MAX_HS_BAUD 3000000u +#define XEC_UART_BRG_DIV_MSK 0x7fffu +#define XEC_UART_BRD_DIV_HS_POS 15 enum uart_xec_pm_policy_state_flag { UART_XEC_PM_POLICY_STATE_TX_FLAG, @@ -180,15 +51,14 @@ enum uart_xec_pm_policy_state_flag { /* device config */ struct uart_xec_device_config { - struct uart_regs *regs; + mm_reg_t uart_base; uint32_t sys_clk_freq; uint8_t girq_id; uint8_t girq_pos; - uint8_t pcr_idx; - uint8_t pcr_bitpos; + uint8_t enc_pcr; const struct pinctrl_dev_config *pcfg; #if defined(CONFIG_UART_INTERRUPT_DRIVEN) || defined(CONFIG_UART_ASYNC_API) - uart_irq_config_func_t irq_config_func; + uart_irq_config_func_t irq_config_func; #endif #ifdef CONFIG_PM_DEVICE struct gpio_dt_spec wakerx_gpio; @@ -201,20 +71,21 @@ struct uart_xec_dev_data { struct uart_config uart_config; struct k_spinlock lock; - uint8_t fcr_cache; /**< cache of FCR write only register */ - uint8_t iir_cache; /**< cache of IIR since it clears when read */ + uint8_t fcr_cache; /**< cache of FCR write only register */ + uint8_t iir_cache; /**< cache of IIR since it clears when read */ + volatile uint8_t data_byte; #ifdef CONFIG_UART_INTERRUPT_DRIVEN - uart_irq_callback_user_data_t cb; /**< Callback function pointer */ - void *cb_data; /**< Callback function arg */ + uart_irq_callback_user_data_t cb; /**< Callback function pointer */ + void *cb_data; /**< Callback function arg */ #endif }; #ifdef CONFIG_PM_DEVICE - ATOMIC_DEFINE(pm_policy_state_flag, UART_XEC_PM_POLICY_STATE_FLAG_COUNT); +ATOMIC_DEFINE(pm_policy_state_flag, UART_XEC_PM_POLICY_STATE_FLAG_COUNT); #endif #if defined(CONFIG_PM_DEVICE) && defined(CONFIG_UART_CONSOLE_INPUT_EXPIRED) - struct k_work_delayable rx_refresh_timeout_work; +struct k_work_delayable rx_refresh_timeout_work; #endif static DEVICE_API(uart, uart_xec_driver_api); @@ -235,81 +106,58 @@ static void uart_xec_pm_policy_state_lock_put(enum uart_xec_pm_policy_state_flag } #endif -#ifdef CONFIG_SOC_SERIES_MEC172X - -static void uart_clr_slp_en(const struct device *dev) -{ - struct uart_xec_device_config const *dev_cfg = dev->config; - - z_mchp_xec_pcr_periph_sleep(dev_cfg->pcr_idx, dev_cfg->pcr_bitpos, 0); -} - -static inline void uart_xec_girq_clr(const struct device *dev) -{ - struct uart_xec_device_config const *dev_cfg = dev->config; - - mchp_soc_ecia_girq_src_clr(dev_cfg->girq_id, dev_cfg->girq_pos); -} - -static inline void uart_xec_girq_en(uint8_t girq_idx, uint8_t girq_posn) +/* Calculate the baud clock divisor given the desired BAUD rate. + * Hardware design is divisor = Fin / (16 * baud_rate) + * Fin is selectable as 1.8432 MHz (divisor b[15]=0) or 48 MHz (divisor b[15]=1) + * We multiply Fin by 16 and look at the lower 4 bits to implement rounding. + */ +static uint32_t calc_baud_clock_divisor(uint32_t baud_rate) { - mchp_xec_ecia_girq_src_en(girq_idx, girq_posn); -} - -#else + uint32_t fin = XEC_UART_FIN_HZ_RM; + uint32_t bdiv = 0, d = 0; -static void uart_clr_slp_en(const struct device *dev) -{ - struct uart_xec_device_config const *dev_cfg = dev->config; + if (baud_rate > XEC_UART_MAX_BAUD) { + fin = XEC_UART_FIN_HS_HZ_RM; + if (baud_rate > XEC_UART_MAX_HS_BAUD) { + baud_rate = XEC_UART_MAX_HS_BAUD; + } + } - if (dev_cfg->pcr_bitpos == MCHP_PCR2_UART0_POS) { - mchp_pcr_periph_slp_ctrl(PCR_UART0, 0); - } else if (dev_cfg->pcr_bitpos == MCHP_PCR2_UART1_POS) { - mchp_pcr_periph_slp_ctrl(PCR_UART1, 0); - } else { - mchp_pcr_periph_slp_ctrl(PCR_UART2, 0); + d = fin / (XEC_UART_BRG_HW_MULT * baud_rate); + bdiv = d / XEC_UART_BRG_ROUNDING_MULT; + if ((d & XEC_UART_BRG_ROUNDING_MSK) >= XEC_UART_BRG_ROUNDING_UP) { + bdiv++; } -} -static inline void uart_xec_girq_clr(const struct device *dev) -{ - struct uart_xec_device_config const *dev_cfg = dev->config; + bdiv &= XEC_UART_BRG_DIV_MSK; - MCHP_GIRQ_SRC(dev_cfg->girq_id) = BIT(dev_cfg->girq_pos); -} + if (baud_rate > XEC_UART_MAX_BAUD) { + bdiv |= BIT(XEC_UART_BRD_DIV_HS_POS); + } -static inline void uart_xec_girq_en(uint8_t girq_idx, uint8_t girq_posn) -{ - MCHP_GIRQ_ENSET(girq_idx) = BIT(girq_posn); + return bdiv; } -#endif - static void set_baud_rate(const struct device *dev, uint32_t baud_rate) { - const struct uart_xec_device_config * const dev_cfg = dev->config; - struct uart_xec_dev_data * const dev_data = dev->data; - struct uart_regs *regs = dev_cfg->regs; + const struct uart_xec_device_config *const dev_cfg = dev->config; + struct uart_xec_dev_data *const dev_data = dev->data; + mm_reg_t ub = dev_cfg->uart_base; uint32_t divisor; /* baud rate divisor */ uint8_t lcr_cache; if ((baud_rate != 0U) && (dev_cfg->sys_clk_freq != 0U)) { - /* - * calculate baud rate divisor. a variant of - * (uint32_t)(dev_cfg->sys_clk_freq / (16.0 * baud_rate) + 0.5) - */ - divisor = ((dev_cfg->sys_clk_freq + (baud_rate << 3)) - / baud_rate) >> 4; + divisor = calc_baud_clock_divisor(baud_rate); /* set the DLAB to access the baud rate divisor registers */ - lcr_cache = regs->LCR; - regs->LCR = LCR_DLAB | lcr_cache; - regs->RTXB = (unsigned char)(divisor & 0xff); - /* bit[7]=0 1.8MHz clock source, =1 48MHz clock source */ - regs->IER = (unsigned char)((divisor >> 8) & 0x7f); + lcr_cache = sys_read8(ub + XEC_UART_LCR_OFS); + sys_write8(XEC_UART_LCR_DLAB_EN | lcr_cache, ub + XEC_UART_LCR_OFS); + + sys_write8((uint8_t)(divisor & 0xffu), ub + XEC_UART_BRGD_LSB_OFS); + sys_write8((uint8_t)((divisor >> 8) & 0xffu), ub + XEC_UART_BRGD_MSB_OFS); /* restore the DLAB to access the baud rate divisor registers */ - regs->LCR = lcr_cache; + sys_write8(lcr_cache, ub + XEC_UART_LCR_OFS); dev_data->uart_config.baudrate = baud_rate; } @@ -321,47 +169,41 @@ static void set_baud_rate(const struct device *dev, uint32_t baud_rate) * We must change the UART reset signal to XEC VTR_PWRGD. Make sure UART * clock source is an internal clock and UART pins are not inverted. */ -static int uart_xec_configure(const struct device *dev, - const struct uart_config *cfg) +static int uart_xec_configure(const struct device *dev, const struct uart_config *cfg) { - struct uart_xec_dev_data * const dev_data = dev->data; - const struct uart_xec_device_config * const dev_cfg = dev->config; - struct uart_regs *regs = dev_cfg->regs; - uint8_t lcr_cache; - - /* temp for return value if error occurs in this locked region */ + struct uart_xec_dev_data *const dev_data = dev->data; + const struct uart_xec_device_config *const dev_cfg = dev->config; + mm_reg_t ub = dev_cfg->uart_base; int ret = 0; + uint8_t lcr = 0, temp8 = 0; k_spinlock_key_t key = k_spin_lock(&dev_data->lock); - ARG_UNUSED(dev_data); - dev_data->fcr_cache = 0U; dev_data->iir_cache = 0U; /* XEC UART specific configuration and enable */ - regs->CFG_SEL &= ~(MCHP_UART_LD_CFG_RESET_VCC | - MCHP_UART_LD_CFG_EXTCLK | MCHP_UART_LD_CFG_INVERT); + temp8 = sys_read8(ub + XEC_UART_LD_CFG_OFS); + temp8 &= ~(XEC_UART_LD_CFG_RESET_VCC | XEC_UART_LD_CFG_EXTCLK | XEC_UART_LD_CFG_INVERT); + sys_write8(temp8, ub + XEC_UART_LD_CFG_OFS); + /* set activate to enable clocks */ - regs->ACTV |= MCHP_UART_LD_ACTIVATE; + soc_set_bit8(ub + XEC_UART_LD_ACT_OFS, XEC_UART_LD_ACTIVATE_POS); set_baud_rate(dev, cfg->baudrate); - /* Local structure to hold temporary values */ - struct uart_config uart_cfg; - switch (cfg->data_bits) { case UART_CFG_DATA_BITS_5: - uart_cfg.data_bits = LCR_CS5; + lcr |= XEC_UART_LCR_WORD_LEN_SET(XEC_UART_LCR_WORD_LEN_5); break; case UART_CFG_DATA_BITS_6: - uart_cfg.data_bits = LCR_CS6; + lcr |= XEC_UART_LCR_WORD_LEN_SET(XEC_UART_LCR_WORD_LEN_6); break; case UART_CFG_DATA_BITS_7: - uart_cfg.data_bits = LCR_CS7; + lcr |= XEC_UART_LCR_WORD_LEN_SET(XEC_UART_LCR_WORD_LEN_7); break; case UART_CFG_DATA_BITS_8: - uart_cfg.data_bits = LCR_CS8; + lcr |= XEC_UART_LCR_WORD_LEN_SET(XEC_UART_LCR_WORD_LEN_8); break; default: ret = -ENOTSUP; @@ -370,10 +212,10 @@ static int uart_xec_configure(const struct device *dev, switch (cfg->stop_bits) { case UART_CFG_STOP_BITS_1: - uart_cfg.stop_bits = LCR_1_STB; + lcr |= XEC_UART_LCR_STOP_BIT_1; break; case UART_CFG_STOP_BITS_2: - uart_cfg.stop_bits = LCR_2_STB; + lcr |= XEC_UART_LCR_STOP_BIT_2; break; default: ret = -ENOTSUP; @@ -382,10 +224,19 @@ static int uart_xec_configure(const struct device *dev, switch (cfg->parity) { case UART_CFG_PARITY_NONE: - uart_cfg.parity = LCR_PDIS; + lcr |= XEC_UART_LCR_PARITY_SET(XEC_UART_LCR_PARITY_NONE); + break; + case UART_CFG_PARITY_ODD: + lcr |= XEC_UART_LCR_PARITY_SET(XEC_UART_LCR_PARITY_ODD); break; case UART_CFG_PARITY_EVEN: - uart_cfg.parity = LCR_EPS; + lcr |= XEC_UART_LCR_PARITY_SET(XEC_UART_LCR_PARITY_EVEN); + break; + case UART_CFG_PARITY_MARK: + lcr |= XEC_UART_LCR_PARITY_SET(XEC_UART_LCR_PARITY_MARK); + break; + case UART_CFG_PARITY_SPACE: + lcr |= XEC_UART_LCR_PARITY_SET(XEC_UART_LCR_PARITY_SPACE); break; default: ret = -ENOTSUP; @@ -395,36 +246,38 @@ static int uart_xec_configure(const struct device *dev, dev_data->uart_config = *cfg; /* data bits, stop bits, parity, clear DLAB */ - regs->LCR = uart_cfg.data_bits | uart_cfg.stop_bits | uart_cfg.parity; + sys_write8(lcr, ub + XEC_UART_LCR_OFS); - regs->MCR = MCR_OUT2 | MCR_RTS | MCR_DTR; + /* modem control */ + temp8 = (XEC_UART_MCR_OUT2 | XEC_UART_MCR_RTSn | XEC_UART_MCR_DTRn); + sys_write8(temp8, ub + XEC_UART_MCR_OFS); /* * Program FIFO: enabled, mode 0 * generate the interrupt at 8th byte * Clear TX and RX FIFO */ - dev_data->fcr_cache = FCR_FIFO | FCR_MODE0 | FCR_FIFO_8 | FCR_RCVRCLR | - FCR_XMITCLR; - regs->IIR_FCR = dev_data->fcr_cache; + dev_data->fcr_cache = (XEC_UART_FCR_EXRF | XEC_UART_FCR_RX_FIFO_LVL_8 | + XEC_UART_FCR_CLR_RX_FIFO | XEC_UART_FCR_CLR_TX_FIFO); + + sys_write8(dev_data->fcr_cache, ub + XEC_UART_FCR_OFS); /* clear the port */ - lcr_cache = regs->LCR; - regs->LCR = LCR_DLAB | lcr_cache; - regs->SCR = regs->RTXB; - regs->LCR = lcr_cache; + if (soc_test_bit8(ub + XEC_UART_LSR_OFS, XEC_UART_LSR_DATA_RDY_POS) != 0) { + dev_data->data_byte = sys_read8(ub + XEC_UART_RTXB_OFS); + } /* disable interrupts */ - regs->IER = 0; + sys_write8(0, ub + XEC_UART_IER_OFS); out: k_spin_unlock(&dev_data->lock, key); + return ret; }; #ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE -static int uart_xec_config_get(const struct device *dev, - struct uart_config *cfg) +static int uart_xec_config_get(const struct device *dev, struct uart_config *cfg) { struct uart_xec_dev_data *data = dev->data; @@ -441,11 +294,10 @@ static int uart_xec_config_get(const struct device *dev, #ifdef CONFIG_PM_DEVICE static void uart_xec_wake_handler(const struct device *gpio, struct gpio_callback *cb, - uint32_t pins) + uint32_t pins) { /* Disable interrupts on UART RX pin to avoid repeated interrupts. */ - (void)gpio_pin_interrupt_configure(gpio, (find_msb_set(pins) - 1), - GPIO_INT_DISABLE); + (void)gpio_pin_interrupt_configure(gpio, (find_msb_set(pins) - 1), GPIO_INT_DISABLE); /* Refresh console expired time */ #ifdef CONFIG_UART_CONSOLE_INPUT_EXPIRED k_timeout_t delay = K_MSEC(CONFIG_UART_CONSOLE_INPUT_EXPIRED_TIMEOUT); @@ -455,23 +307,22 @@ static void uart_xec_wake_handler(const struct device *gpio, struct gpio_callbac #endif } -static int uart_xec_pm_action(const struct device *dev, - enum pm_device_action action) +static int uart_xec_pm_action(const struct device *dev, enum pm_device_action action) { - const struct uart_xec_device_config * const dev_cfg = dev->config; - struct uart_regs *regs = dev_cfg->regs; + const struct uart_xec_device_config *const dev_cfg = dev->config; + mm_reg_t ub = dev_cfg->uart_base; int ret = 0; switch (action) { case PM_DEVICE_ACTION_RESUME: - regs->ACTV = MCHP_UART_LD_ACTIVATE; + soc_set_bit8(ub + XEC_UART_LD_ACT_OFS, XEC_UART_LD_ACTIVATE_POS); break; case PM_DEVICE_ACTION_SUSPEND: /* Enable UART wake interrupt */ - regs->ACTV = 0; + soc_clear_bit8(ub + XEC_UART_LD_ACT_OFS, XEC_UART_LD_ACTIVATE_POS); if ((dev_cfg->wakeup_source) && (dev_cfg->wakerx_gpio.port != NULL)) { - ret = gpio_pin_interrupt_configure_dt(&dev_cfg->wakerx_gpio, - GPIO_INT_MODE_EDGE | GPIO_INT_TRIG_LOW); + ret = gpio_pin_interrupt_configure_dt( + &dev_cfg->wakerx_gpio, GPIO_INT_MODE_EDGE | GPIO_INT_TRIG_LOW); if (ret < 0) { LOG_ERR("Failed to configure UART wake interrupt (ret %d)", ret); return ret; @@ -495,22 +346,18 @@ static void uart_xec_rx_refresh_timeout(struct k_work *work) #endif #endif /* CONFIG_PM_DEVICE */ -/** - * @brief Initialize individual UART port - * +/* Initialize individual UART port + * params: dev UART device struct + * return: 0 if successful, failed otherwise * This routine is called to reset the chip in a quiescent state. - * - * @param dev UART device struct - * - * @return 0 if successful, failed otherwise */ static int uart_xec_init(const struct device *dev) { - const struct uart_xec_device_config * const dev_cfg = dev->config; + const struct uart_xec_device_config *const dev_cfg = dev->config; struct uart_xec_dev_data *dev_data = dev->data; int ret; - uart_clr_slp_en(dev); + soc_xec_pcr_sleep_en_clear(dev_cfg->enc_pcr); ret = pinctrl_apply_state(dev_cfg->pcfg, PINCTRL_STATE_DEFAULT); if (ret != 0) { @@ -528,7 +375,7 @@ static int uart_xec_init(const struct device *dev) #ifdef CONFIG_PM_DEVICE #ifdef CONFIG_UART_CONSOLE_INPUT_EXPIRED - k_work_init_delayable(&rx_refresh_timeout_work, uart_xec_rx_refresh_timeout); + k_work_init_delayable(&rx_refresh_timeout_work, uart_xec_rx_refresh_timeout); #endif if ((dev_cfg->wakeup_source) && (dev_cfg->wakerx_gpio.port != NULL)) { static struct gpio_callback uart_xec_wake_cb; @@ -547,25 +394,22 @@ static int uart_xec_init(const struct device *dev) return 0; } -/** - * @brief Poll the device for input. - * - * @param dev UART device struct - * @param c Pointer to character - * - * @return 0 if a character arrived, -1 if the input buffer if empty. +/* Poll the device for input. + * params: + * dev UART device struct + * c Pointer to character + * return: 0 if a character arrived, -1 if the input buffer if empty. */ static int uart_xec_poll_in(const struct device *dev, unsigned char *c) { - const struct uart_xec_device_config * const dev_cfg = dev->config; + const struct uart_xec_device_config *const dev_cfg = dev->config; struct uart_xec_dev_data *dev_data = dev->data; - struct uart_regs *regs = dev_cfg->regs; + mm_reg_t ub = dev_cfg->uart_base; int ret = -1; k_spinlock_key_t key = k_spin_lock(&dev_data->lock); - if ((regs->LSR & LSR_RXRDY) != 0) { - /* got a character */ - *c = regs->RTXB; + if ((soc_test_bit8(ub + XEC_UART_LSR_OFS, XEC_UART_LSR_DATA_RDY_POS)) != 0) { + *c = (unsigned char)sys_read8(ub + XEC_UART_RTXB_OFS); ret = 0; } @@ -574,80 +418,113 @@ static int uart_xec_poll_in(const struct device *dev, unsigned char *c) return ret; } -/** - * @brief Output a character in polled mode. - * +/* Output a character in polled mode. + * params: + * dev a pointer to UART device structure + * c unsigned character to be written to HW + * return: None * Checks if the transmitter is empty. If empty, a character is written to * the data register. - * * If the hardware flow control is enabled then the handshake signal CTS has to * be asserted in order to send a character. - * - * @param dev UART device struct - * @param c Character to send */ static void uart_xec_poll_out(const struct device *dev, unsigned char c) { - const struct uart_xec_device_config * const dev_cfg = dev->config; + const struct uart_xec_device_config *const dev_cfg = dev->config; struct uart_xec_dev_data *dev_data = dev->data; - struct uart_regs *regs = dev_cfg->regs; + mm_reg_t ub = dev_cfg->uart_base; k_spinlock_key_t key = k_spin_lock(&dev_data->lock); - while ((regs->LSR & LSR_THRE) == 0) { - ; +#ifdef XEC_HAS_UART_LSR2 + if ((sys_read8(ub + XEC_UART_IIR_OFS) & XEC_UART_IIR_FIFO_EN_MASK) != 0) { + /* When the FIFO is disabled this bit is always 0 */ + while (soc_test_bit8(ub + XEC_UART_LSR2_OFS, XEC_UART_LSR2_TX_FIFO_FULL_POS) != 0) { + } + } else { + while (soc_test_bit8(ub + XEC_UART_LSR_OFS, XEC_UART_LSR_THRE_POS) == 0) { + } } +#else + while (soc_test_bit8(ub + XEC_UART_LSR_OFS, XEC_UART_LSR_THRE_POS) == 0) { + } +#endif - regs->RTXB = c; + sys_write8(c, ub + XEC_UART_RTXB_OFS); k_spin_unlock(&dev_data->lock, key); } -/** - * @brief Check if an error was received - * - * @param dev UART device struct - * - * @return one of UART_ERROR_OVERRUN, UART_ERROR_PARITY, UART_ERROR_FRAMING, +/* Check if an error was received + * params: dev UART device struct + * return: one of UART_ERROR_OVERRUN, UART_ERROR_PARITY, UART_ERROR_FRAMING, * UART_BREAK if an error was detected, 0 otherwise. */ static int uart_xec_err_check(const struct device *dev) { - const struct uart_xec_device_config * const dev_cfg = dev->config; + const struct uart_xec_device_config *const dev_cfg = dev->config; struct uart_xec_dev_data *dev_data = dev->data; - struct uart_regs *regs = dev_cfg->regs; + mm_reg_t ub = dev_cfg->uart_base; + uint32_t lsr = 0; k_spinlock_key_t key = k_spin_lock(&dev_data->lock); - int check = regs->LSR & LSR_EOB_MASK; + + lsr = (uint32_t)sys_read8(ub + XEC_UART_LSR_OFS) & XEC_UART_LSR_ANY_ERR; k_spin_unlock(&dev_data->lock, key); - return check >> 1; + return (int)((lsr & XEC_UART_LSR_ANY_ERR) >> 1); } #if CONFIG_UART_INTERRUPT_DRIVEN -/** - * @brief Fill FIFO with data - * - * @param dev UART device struct - * @param tx_data Data to transmit - * @param size Number of bytes to send - * - * @return Number of bytes sent +static bool uart_xec_ready_to_xmit(mm_reg_t base, bool fifo_enabled) +{ +#ifdef XEC_HAS_UART_LSR2 + if (fifo_enabled == true) { + if (soc_test_bit8(base + XEC_UART_LSR2_OFS, XEC_UART_LSR2_TX_FIFO_FULL_POS) == 0) { + return true; + } else { + return false; + } + } +#endif + if (soc_test_bit8(base + XEC_UART_LSR_OFS, XEC_UART_LSR_THRE_POS) != 0) { + return true; + } + + return false; +} + +/* Fill FIFO with data + * params: + * dev UART device struct + * tx_data Data to transmit + * size Number of bytes to send + * return: Number of bytes sent + * Do NOT block. If TX FIFO is full return 0. */ -static int uart_xec_fifo_fill(const struct device *dev, const uint8_t *tx_data, - int size) +static int uart_xec_fifo_fill(const struct device *dev, const uint8_t *tx_data, int size) { - const struct uart_xec_device_config * const dev_cfg = dev->config; + const struct uart_xec_device_config *const dev_cfg = dev->config; struct uart_xec_dev_data *dev_data = dev->data; - struct uart_regs *regs = dev_cfg->regs; - int i; + mm_reg_t ub = dev_cfg->uart_base; + int i = 0; + bool fifo_enabled = false; k_spinlock_key_t key = k_spin_lock(&dev_data->lock); - for (i = 0; (i < size) && (regs->LSR & LSR_THRE) != 0; i++) { + if ((sys_read8(ub + XEC_UART_IIR_OFS) & XEC_UART_IIR_FIFO_EN_MASK) != 0) { + fifo_enabled = true; + } + + while (i < size) { + if (uart_xec_ready_to_xmit(ub, fifo_enabled) == true) { #if defined(CONFIG_PM_DEVICE) && defined(CONFIG_UART_CONSOLE_INPUT_EXPIRED) - uart_xec_pm_policy_state_lock_get(UART_XEC_PM_POLICY_STATE_TX_FLAG); + uart_xec_pm_policy_state_lock_get(UART_XEC_PM_POLICY_STATE_TX_FLAG); #endif - regs->RTXB = tx_data[i]; + sys_write8(tx_data[i], ub + XEC_UART_RTXB_OFS); + i++; + } else { + break; + } } k_spin_unlock(&dev_data->lock, key); @@ -655,26 +532,29 @@ static int uart_xec_fifo_fill(const struct device *dev, const uint8_t *tx_data, return i; } -/** - * @brief Read data from FIFO - * - * @param dev UART device struct - * @param rxData Data container - * @param size Container size - * - * @return Number of bytes read +/* Read data from FIFO + * params: + * dev UART device struct + * rxData Data container + * size Container size + * return: Number of bytes read + * Do NOT block. If no data ready return 0 */ -static int uart_xec_fifo_read(const struct device *dev, uint8_t *rx_data, - const int size) +static int uart_xec_fifo_read(const struct device *dev, uint8_t *rx_data, const int size) { - const struct uart_xec_device_config * const dev_cfg = dev->config; + const struct uart_xec_device_config *const dev_cfg = dev->config; struct uart_xec_dev_data *dev_data = dev->data; - struct uart_regs *regs = dev_cfg->regs; - int i; + mm_reg_t ub = dev_cfg->uart_base; + int i = 0; k_spinlock_key_t key = k_spin_lock(&dev_data->lock); - for (i = 0; (i < size) && (regs->LSR & LSR_RXRDY) != 0; i++) { - rx_data[i] = regs->RTXB; + while (i < size) { + if (soc_test_bit8(ub + XEC_UART_LSR_OFS, XEC_UART_LSR_DATA_RDY_POS) != 0) { + rx_data[i] = sys_read8(ub + XEC_UART_RTXB_OFS); + i++; + } else { + break; + } } k_spin_unlock(&dev_data->lock, key); @@ -682,76 +562,77 @@ static int uart_xec_fifo_read(const struct device *dev, uint8_t *rx_data, return i; } -/** - * @brief Enable TX interrupt in IER - * - * @param dev UART device struct +/* Enable TX interrupt in IER + * params: dev UART device struct */ static void uart_xec_irq_tx_enable(const struct device *dev) { - const struct uart_xec_device_config * const dev_cfg = dev->config; + const struct uart_xec_device_config *const dev_cfg = dev->config; struct uart_xec_dev_data *dev_data = dev->data; - struct uart_regs *regs = dev_cfg->regs; + mm_reg_t ub = dev_cfg->uart_base; k_spinlock_key_t key = k_spin_lock(&dev_data->lock); - regs->IER |= IER_TBE; + soc_set_bit8(ub + XEC_UART_IER_OFS, XEC_UART_IER_ETHREI_POS); k_spin_unlock(&dev_data->lock, key); } -/** - * @brief Disable TX interrupt in IER - * - * @param dev UART device struct +/* Disable TX interrupt in IER + * params: dev UART device struct */ static void uart_xec_irq_tx_disable(const struct device *dev) { - const struct uart_xec_device_config * const dev_cfg = dev->config; + const struct uart_xec_device_config *const dev_cfg = dev->config; struct uart_xec_dev_data *dev_data = dev->data; - struct uart_regs *regs = dev_cfg->regs; + mm_reg_t ub = dev_cfg->uart_base; k_spinlock_key_t key = k_spin_lock(&dev_data->lock); - regs->IER &= ~(IER_TBE); + soc_clear_bit8(ub + XEC_UART_IER_OFS, XEC_UART_IER_ETHREI_POS); k_spin_unlock(&dev_data->lock, key); } -/** - * @brief Check if Tx IRQ has been raised - * - * @param dev UART device struct - * - * @return 1 if an IRQ is ready, 0 otherwise +/* Check if Tx IRQ has been raised + * params: dev UART device struct + * return: 1 if an IRQ is ready, 0 otherwise */ static int uart_xec_irq_tx_ready(const struct device *dev) { struct uart_xec_dev_data *dev_data = dev->data; k_spinlock_key_t key = k_spin_lock(&dev_data->lock); + int ret = 0; + uint8_t iid = XEC_UART_IIR_INTID_GET(dev_data->iir_cache); - int ret = ((IIRC(dev) & IIR_ID) == IIR_THRE) ? 1 : 0; + if (iid == XEC_UART_IIR_INTID_THRE) { + ret = 1; + } k_spin_unlock(&dev_data->lock, key); return ret; } -/** - * @brief Check if nothing remains to be transmitted - * - * @param dev UART device struct - * - * @return 1 if nothing remains to be transmitted, 0 otherwise +/* Check if nothing remains to be transmitted + * params: dev UART device struct + * return: 1 if nothing remains to be transmitted, 0 otherwise */ static int uart_xec_irq_tx_complete(const struct device *dev) { - const struct uart_xec_device_config * const dev_cfg = dev->config; + const struct uart_xec_device_config *const dev_cfg = dev->config; struct uart_xec_dev_data *dev_data = dev->data; - struct uart_regs *regs = dev_cfg->regs; - int ret; + mm_reg_t ub = dev_cfg->uart_base; + int ret = 0; + uint8_t ier = 0, lsr = 0; + uint8_t lsr_msk = (XEC_UART_LSR_THRE | XEC_UART_LSR_TEMT); k_spinlock_key_t key = k_spin_lock(&dev_data->lock); - if ((regs->IER & IER_TBE) || - ((regs->LSR & (LSR_TEMT | LSR_THRE)) != (LSR_TEMT | LSR_THRE))) { + ier = sys_read8(ub + XEC_UART_IER_OFS); + lsr = sys_read8(ub + XEC_UART_LSR_OFS); + + /* TX FIFO holding register empty interrupt enabled OR + * both TX holding and shift registers are empty. + */ + if (((ier & XEC_UART_IER_ETHREI) != 0) || ((lsr & lsr_msk) == lsr_msk)) { ret = 0; } else { ret = 1; @@ -762,146 +643,144 @@ static int uart_xec_irq_tx_complete(const struct device *dev) return ret; } -/** - * @brief Enable RX interrupt in IER - * - * @param dev UART device struct +/* Enable RX interrupt in IER + * params: dev UART device struct */ static void uart_xec_irq_rx_enable(const struct device *dev) { - const struct uart_xec_device_config * const dev_cfg = dev->config; + const struct uart_xec_device_config *const dev_cfg = dev->config; struct uart_xec_dev_data *dev_data = dev->data; - struct uart_regs *regs = dev_cfg->regs; + mm_reg_t ub = dev_cfg->uart_base; k_spinlock_key_t key = k_spin_lock(&dev_data->lock); - regs->IER |= IER_RXRDY; + soc_set_bit8(ub + XEC_UART_IER_OFS, XEC_UART_IER_ERDAI_POS); k_spin_unlock(&dev_data->lock, key); } -/** - * @brief Disable RX interrupt in IER - * - * @param dev UART device struct +/* Disable RX interrupt in IER + * params: dev UART device struct */ static void uart_xec_irq_rx_disable(const struct device *dev) { - const struct uart_xec_device_config * const dev_cfg = dev->config; + const struct uart_xec_device_config *const dev_cfg = dev->config; struct uart_xec_dev_data *dev_data = dev->data; - struct uart_regs *regs = dev_cfg->regs; + mm_reg_t ub = dev_cfg->uart_base; k_spinlock_key_t key = k_spin_lock(&dev_data->lock); - regs->IER &= ~(IER_RXRDY); + soc_clear_bit8(ub + XEC_UART_IER_OFS, XEC_UART_IER_ERDAI_POS); k_spin_unlock(&dev_data->lock, key); } -/** - * @brief Check if Rx IRQ has been raised - * - * @param dev UART device struct - * - * @return 1 if an IRQ is ready, 0 otherwise +/* + * Check if Rx IRQ has been raised + * params: + * dev UART device struct + * return: + * 0 No RX IRQ has been raised + * 1 RX IRQ has been raised + * -ENOSYS function not implemented + * -ENOTSUP if API is not enabled + * Notes: + * MEC UART is NS16550 compatible and has two possible RX events signalling + * an interrupt. RX data is available and RX data is available but no bytes + * have been removed from the RX FIFO during the last frames. In both cases + * reading the RX buffer will clear the status. */ static int uart_xec_irq_rx_ready(const struct device *dev) { struct uart_xec_dev_data *dev_data = dev->data; k_spinlock_key_t key = k_spin_lock(&dev_data->lock); + int ret = 0; + uint8_t iid = XEC_UART_IIR_INTID_GET(dev_data->iir_cache); - int ret = ((IIRC(dev) & IIR_ID) == IIR_RBRF) ? 1 : 0; + if ((iid == XEC_UART_IIR_INTID_RXD) || (iid == XEC_UART_IIR_INTID_RXTM)) { + ret = 1; + } k_spin_unlock(&dev_data->lock, key); return ret; } -/** - * @brief Enable error interrupt in IER - * - * @param dev UART device struct +/* Enable error interrupt in IER + * params: dev UART device struct */ static void uart_xec_irq_err_enable(const struct device *dev) { - const struct uart_xec_device_config * const dev_cfg = dev->config; + const struct uart_xec_device_config *const dev_cfg = dev->config; struct uart_xec_dev_data *dev_data = dev->data; - struct uart_regs *regs = dev_cfg->regs; + mm_reg_t ub = dev_cfg->uart_base; k_spinlock_key_t key = k_spin_lock(&dev_data->lock); - regs->IER |= IER_LSR; + soc_set_bit8(ub + XEC_UART_IER_OFS, XEC_UART_IER_ELSI_POS); k_spin_unlock(&dev_data->lock, key); } -/** - * @brief Disable error interrupt in IER - * - * @param dev UART device struct - * - * @return 1 if an IRQ is ready, 0 otherwise +/* Disable error interrupt in IER + * params: dev UART device struct */ static void uart_xec_irq_err_disable(const struct device *dev) { - const struct uart_xec_device_config * const dev_cfg = dev->config; + const struct uart_xec_device_config *const dev_cfg = dev->config; struct uart_xec_dev_data *dev_data = dev->data; - struct uart_regs *regs = dev_cfg->regs; + mm_reg_t ub = dev_cfg->uart_base; k_spinlock_key_t key = k_spin_lock(&dev_data->lock); - regs->IER &= ~(IER_LSR); + soc_clear_bit8(ub + XEC_UART_IER_OFS, XEC_UART_IER_ELSI_POS); k_spin_unlock(&dev_data->lock, key); } -/** - * @brief Check if any IRQ is pending - * - * @param dev UART device struct - * - * @return 1 if an IRQ is pending, 0 otherwise +/* Check if any IRQ is pending + * params: dev UART device struct + * return: 1 if an IRQ is pending, 0 otherwise */ static int uart_xec_irq_is_pending(const struct device *dev) { struct uart_xec_dev_data *dev_data = dev->data; k_spinlock_key_t key = k_spin_lock(&dev_data->lock); + int ret = 0; - int ret = (!(IIRC(dev) & IIR_NIP)) ? 1 : 0; + if ((dev_data->iir_cache & BIT(XEC_UART_IIR_NOT_IPEND_POS)) == 0) { + ret = 1; + } k_spin_unlock(&dev_data->lock, key); return ret; } -/** - * @brief Update cached contents of IIR - * - * @param dev UART device struct - * - * @return Always 1 +/* Update cached contents of IIR + * param: dev UART device struct + * return: Always 1 */ static int uart_xec_irq_update(const struct device *dev) { - const struct uart_xec_device_config * const dev_cfg = dev->config; + const struct uart_xec_device_config *const dev_cfg = dev->config; struct uart_xec_dev_data *dev_data = dev->data; - struct uart_regs *regs = dev_cfg->regs; + mm_reg_t ub = dev_cfg->uart_base; k_spinlock_key_t key = k_spin_lock(&dev_data->lock); - IIRC(dev) = regs->IIR_FCR; + dev_data->iir_cache = sys_read8(ub + XEC_UART_IIR_OFS); k_spin_unlock(&dev_data->lock, key); return 1; } -/** - * @brief Set the callback function pointer for IRQ. - * - * @param dev UART device struct - * @param cb Callback function pointer. +/* Set the callback function pointer for IRQ. + * params: + * dev UART device struct + * cb Callback function pointer. + * cb_data pointer to opaque user data */ -static void uart_xec_irq_callback_set(const struct device *dev, - uart_irq_callback_user_data_t cb, +static void uart_xec_irq_callback_set(const struct device *dev, uart_irq_callback_user_data_t cb, void *cb_data) { - struct uart_xec_dev_data * const dev_data = dev->data; + struct uart_xec_dev_data *const dev_data = dev->data; k_spinlock_key_t key = k_spin_lock(&dev_data->lock); dev_data->cb = cb; @@ -910,23 +789,23 @@ static void uart_xec_irq_callback_set(const struct device *dev, k_spin_unlock(&dev_data->lock, key); } -/** - * @brief Interrupt service routine. - * +/* UART interrupt service routine. + * params: dev pointer to UART device structure * This simply calls the callback function, if one exists. - * - * @param arg Argument to ISR. + * If Zephyr PM_DEVICE power management enabled and console input expired + * timeout is enabled in the build we ask the kernel to run a helper function + * in its work queue thread. */ static void uart_xec_isr(const struct device *dev) { - struct uart_xec_dev_data * const dev_data = dev->data; + const struct uart_xec_device_config *const dev_cfg = dev->config; + struct uart_xec_dev_data *const dev_data = dev->data; + #if defined(CONFIG_PM_DEVICE) && defined(CONFIG_UART_CONSOLE_INPUT_EXPIRED) - const struct uart_xec_device_config * const dev_cfg = dev->config; - struct uart_regs *regs = dev_cfg->regs; - int rx_ready = 0; + mm_reg_t ub = dev_cfg->uart_base; + uint8_t lsr = sys_read8(ub + XEC_UART_LSR_OFS); - rx_ready = ((regs->LSR & LSR_RXRDY) == LSR_RXRDY) ? 1 : 0; - if (rx_ready) { + if ((lsr & XEC_UART_LSR_DATA_RDY) != 0) { k_timeout_t delay = K_MSEC(CONFIG_UART_CONSOLE_INPUT_EXPIRED_TIMEOUT); uart_xec_pm_policy_state_lock_get(UART_XEC_PM_POLICY_STATE_RX_FLAG); @@ -934,40 +813,37 @@ static void uart_xec_isr(const struct device *dev) } #endif - if (dev_data->cb) { + if (dev_data->cb != NULL) { dev_data->cb(dev, dev_data->cb_data); } #if defined(CONFIG_PM_DEVICE) && defined(CONFIG_UART_CONSOLE_INPUT_EXPIRED) - if (uart_xec_irq_tx_complete(dev)) { + if (uart_xec_irq_tx_complete(dev) != 0) { uart_xec_pm_policy_state_lock_put(UART_XEC_PM_POLICY_STATE_TX_FLAG); } #endif /* CONFIG_PM */ /* clear ECIA GIRQ R/W1C status bit after UART status cleared */ - uart_xec_girq_clr(dev); + soc_ecia_girq_status_clear(dev_cfg->girq_id, dev_cfg->girq_pos); } #endif /* CONFIG_UART_INTERRUPT_DRIVEN */ #ifdef CONFIG_UART_XEC_LINE_CTRL -/** - * @brief Manipulate line control for UART. - * - * @param dev UART device struct - * @param ctrl The line control to be manipulated - * @param val Value to set the line control - * - * @return 0 if successful, failed otherwise +/* Manipulate line control for UART. + * params: + * dev UART device struct + * ctrl The line control to be manipulated + * val Value to set the line control + * return: 0 if successful, failed otherwise */ -static int uart_xec_line_ctrl_set(const struct device *dev, - uint32_t ctrl, uint32_t val) +static int uart_xec_line_ctrl_set(const struct device *dev, uint32_t ctrl, uint32_t val) { - const struct uart_xec_device_config * const dev_cfg = dev->config; + const struct uart_xec_device_config *const dev_cfg = dev->config; struct uart_xec_dev_data *dev_data = dev->data; - struct uart_regs *regs = dev_cfg->regs; - uint32_t mdc, chg; + mm_reg_t ub = dev_cfg->uart_base; + uint32_t mdc = 0, chg = 0; k_spinlock_key_t key; switch (ctrl) { @@ -978,7 +854,8 @@ static int uart_xec_line_ctrl_set(const struct device *dev, case UART_LINE_CTRL_RTS: case UART_LINE_CTRL_DTR: key = k_spin_lock(&dev_data->lock); - mdc = regs->MCR; + + mdc = (uint32_t)sys_read8(ub + XEC_UART_MCR_OFS); if (ctrl == UART_LINE_CTRL_RTS) { chg = MCR_RTS; @@ -991,9 +868,15 @@ static int uart_xec_line_ctrl_set(const struct device *dev, } else { mdc &= ~(chg); } - regs->MCR = mdc; + + sys_write8(mdc, ub + XEC_UART_MCR_OFS); + k_spin_unlock(&dev_data->lock, key); + return 0; + + default: + break; } return -ENOTSUP; @@ -1033,24 +916,23 @@ static DEVICE_API(uart, uart_xec_driver_api) = { #endif }; -#define DEV_CONFIG_REG_INIT(n) \ - .regs = (struct uart_regs *)(DT_INST_REG_ADDR(n)), +#define DEV_CONFIG_REG_INIT(n) .uart_base = (mm_reg_t)(DT_INST_REG_ADDR(n)), + +#define DEV_CFG_GIRQ(inst) MCHP_XEC_ECIA_GIRQ(DT_INST_PROP_BY_IDX(inst, girqs, 0)) +#define DEV_CFG_GIRQ_POS(inst) MCHP_XEC_ECIA_GIRQ_POS(DT_INST_PROP_BY_IDX(inst, girqs, 0)) #ifdef CONFIG_UART_INTERRUPT_DRIVEN -#define DEV_CONFIG_IRQ_FUNC_INIT(n) \ - .irq_config_func = irq_config_func##n, -#define UART_XEC_IRQ_FUNC_DECLARE(n) \ - static void irq_config_func##n(const struct device *dev); -#define UART_XEC_IRQ_FUNC_DEFINE(n) \ - static void irq_config_func##n(const struct device *dev) \ - { \ - ARG_UNUSED(dev); \ - IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority), \ - uart_xec_isr, DEVICE_DT_INST_GET(n), \ - 0); \ - irq_enable(DT_INST_IRQN(n)); \ - uart_xec_girq_en(DT_INST_PROP_BY_IDX(n, girqs, 0), \ - DT_INST_PROP_BY_IDX(n, girqs, 1)); \ +#define DEV_CONFIG_IRQ_FUNC_INIT(n) .irq_config_func = irq_config_func##n, +#define UART_XEC_IRQ_FUNC_DECLARE(n) static void irq_config_func##n(const struct device *dev); +#define UART_XEC_IRQ_FUNC_DEFINE(n) \ + static void irq_config_func##n(const struct device *dev) \ + { \ + const struct uart_xec_device_config *devcfg = dev->config; \ + \ + IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority), uart_xec_isr, \ + DEVICE_DT_INST_GET(n), 0); \ + irq_enable(DT_INST_IRQN(n)); \ + soc_ecia_girq_ctrl(devcfg->girq_id, devcfg->girq_pos, 1u); \ } #else /* !CONFIG_UART_INTERRUPT_DRIVEN */ @@ -1059,8 +941,7 @@ static DEVICE_API(uart, uart_xec_driver_api) = { #define UART_XEC_IRQ_FUNC_DEFINE(n) #endif /* CONFIG_UART_INTERRUPT_DRIVEN */ -#define DEV_DATA_FLOW_CTRL(n) \ - DT_INST_PROP_OR(n, hw_flow_control, UART_CFG_FLOW_CTRL_NONE) +#define DEV_DATA_FLOW_CTRL(n) DT_INST_PROP_OR(n, hw_flow_control, UART_CFG_FLOW_CTRL_NONE) /* To enable wakeup on the UART, the DTS needs to have two entries defined * in the corresponding UART node in the DTS specifying it as a wake source @@ -1070,45 +951,37 @@ static DEVICE_API(uart, uart_xec_driver_api) = { * wakeup-source; */ #ifdef CONFIG_PM_DEVICE -#define XEC_UART_PM_WAKEUP(n) \ - .wakeup_source = (uint8_t)DT_INST_PROP_OR(n, wakeup_source, 0), \ - .wakerx_gpio = GPIO_DT_SPEC_INST_GET_OR(n, wakerx_gpios, {0}), +#define XEC_UART_PM_WAKEUP(n) \ + .wakeup_source = (uint8_t)DT_INST_PROP_OR(n, wakeup_source, 0), \ + .wakerx_gpio = GPIO_DT_SPEC_INST_GET_OR(n, wakerx_gpios, {0}), #else #define XEC_UART_PM_WAKEUP(index) /* Not used */ #endif -#define UART_XEC_DEVICE_INIT(n) \ - \ - PINCTRL_DT_INST_DEFINE(n); \ - \ - UART_XEC_IRQ_FUNC_DECLARE(n); \ - \ - static const struct uart_xec_device_config uart_xec_dev_cfg_##n = { \ - DEV_CONFIG_REG_INIT(n) \ - .sys_clk_freq = DT_INST_PROP(n, clock_frequency), \ - .girq_id = DT_INST_PROP_BY_IDX(n, girqs, 0), \ - .girq_pos = DT_INST_PROP_BY_IDX(n, girqs, 1), \ - .pcr_idx = DT_INST_PROP_BY_IDX(n, pcrs, 0), \ - .pcr_bitpos = DT_INST_PROP_BY_IDX(n, pcrs, 1), \ - .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ - XEC_UART_PM_WAKEUP(n) \ - DEV_CONFIG_IRQ_FUNC_INIT(n) \ - }; \ - static struct uart_xec_dev_data uart_xec_dev_data_##n = { \ - .uart_config.baudrate = DT_INST_PROP_OR(n, current_speed, 0), \ - .uart_config.parity = UART_CFG_PARITY_NONE, \ - .uart_config.stop_bits = UART_CFG_STOP_BITS_1, \ - .uart_config.data_bits = UART_CFG_DATA_BITS_8, \ - .uart_config.flow_ctrl = DEV_DATA_FLOW_CTRL(n), \ - }; \ - PM_DEVICE_DT_INST_DEFINE(n, uart_xec_pm_action); \ - DEVICE_DT_INST_DEFINE(n, uart_xec_init, \ - PM_DEVICE_DT_INST_GET(n), \ - &uart_xec_dev_data_##n, \ - &uart_xec_dev_cfg_##n, \ - PRE_KERNEL_1, \ - CONFIG_SERIAL_INIT_PRIORITY, \ - &uart_xec_driver_api); \ +#define UART_XEC_DEVICE_INIT(n) \ + \ + PINCTRL_DT_INST_DEFINE(n); \ + \ + UART_XEC_IRQ_FUNC_DECLARE(n); \ + \ + static const struct uart_xec_device_config uart_xec_dev_cfg_##n = { \ + DEV_CONFIG_REG_INIT(n).sys_clk_freq = DT_INST_PROP(n, clock_frequency), \ + .girq_id = DEV_CFG_GIRQ(n), \ + .girq_pos = DEV_CFG_GIRQ_POS(n), \ + .enc_pcr = DT_INST_PROP(n, pcr_scr), \ + .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ + XEC_UART_PM_WAKEUP(n) DEV_CONFIG_IRQ_FUNC_INIT(n)}; \ + static struct uart_xec_dev_data uart_xec_dev_data_##n = { \ + .uart_config.baudrate = DT_INST_PROP_OR(n, current_speed, 0), \ + .uart_config.parity = UART_CFG_PARITY_NONE, \ + .uart_config.stop_bits = UART_CFG_STOP_BITS_1, \ + .uart_config.data_bits = UART_CFG_DATA_BITS_8, \ + .uart_config.flow_ctrl = DEV_DATA_FLOW_CTRL(n), \ + }; \ + PM_DEVICE_DT_INST_DEFINE(n, uart_xec_pm_action); \ + DEVICE_DT_INST_DEFINE(n, uart_xec_init, PM_DEVICE_DT_INST_GET(n), &uart_xec_dev_data_##n, \ + &uart_xec_dev_cfg_##n, PRE_KERNEL_1, CONFIG_SERIAL_INIT_PRIORITY, \ + &uart_xec_driver_api); \ UART_XEC_IRQ_FUNC_DEFINE(n) DT_INST_FOREACH_STATUS_OKAY(UART_XEC_DEVICE_INIT) diff --git a/dts/bindings/serial/microchip,mec5-uart.yaml b/dts/bindings/serial/microchip,mec5-uart.yaml deleted file mode 100644 index 701ec588db5b..000000000000 --- a/dts/bindings/serial/microchip,mec5-uart.yaml +++ /dev/null @@ -1,55 +0,0 @@ -# Copyright (c) 2024 Microchip Technology Inc. -# SPDX-License-Identifier: Apache-2.0 - -description: Microchip MEC5 UART - -compatible: "microchip,mec5-uart" - -include: [uart-controller.yaml, pinctrl-device.yaml, "microchip,dmec-ecia-girq.yaml"] - -properties: - reg: - required: true - - interrupts: - required: true - - pinctrl-0: - required: true - - pinctrl-names: - required: true - - fifo-mode-disable: - type: boolean - description: | - Disable 16550 FIFO mode. Both 16-byte TX and RX FIFOs will be - disabled. UART will revert to a one byte holding register for - TX and RX. - - rx-fifo-trig: - type: string - default: "8" - description: | - RX FIFO byte count trigger limit. When the number of received bytes - reaches this level the UART will signal an interrupt if enabled. - enum: - - "1" - - "4" - - "8" - - "14" - - use-extclk: - type: boolean - description: | - Optional source of an external UART clock. If present the - driver will use this pin as the UART input clock source. - The pin should have a 1.8432 MHz clock waveform for normal - UART BAUD rates or 48 MHz for high speed BAUD rates. - Refer to data sheet for the pin(s) available as external UART - clock input. The pin should be added to the default PINCTRL list. - Example using external 1.8432MHz clock on MEC5 external UART clock pin. - - clock-frequency = <1843200>; - pinctrl-0 = < &uart1_tx_gpio170 &uart1_tx_gpio171 &uart_clk_gpio025>; - pinctrl-names = "default"; diff --git a/dts/bindings/serial/microchip,xec-uart.yaml b/dts/bindings/serial/microchip,xec-uart.yaml index 159ae367be03..1da649ad5694 100644 --- a/dts/bindings/serial/microchip,xec-uart.yaml +++ b/dts/bindings/serial/microchip,xec-uart.yaml @@ -2,7 +2,10 @@ description: Microchip XEC UART compatible: "microchip,xec-uart" -include: [uart-controller.yaml, pinctrl-device.yaml] +include: + - name: uart-controller.yaml + - name: pinctrl-device.yaml + - name: microchip,dmec-ecia-girq.yaml properties: reg: @@ -16,15 +19,11 @@ properties: required: true description: logical device number - girqs: - type: array - required: true - description: UART GIRQ and bit position in EC interrupt aggregator - - pcrs: - type: array + pcr-scr: + type: int required: true - description: UART Power Clock Reset(PCR) register index and bit position + description: | + UART Power Clock Reset(PCR) peripheral index and bit position pinctrl-0: required: true diff --git a/include/zephyr/dt-bindings/clock/mchp_xec_pcr.h b/include/zephyr/dt-bindings/clock/mchp_xec_pcr.h index c52ecab1b21d..c60a5d4fec28 100644 --- a/include/zephyr/dt-bindings/clock/mchp_xec_pcr.h +++ b/include/zephyr/dt-bindings/clock/mchp_xec_pcr.h @@ -8,22 +8,25 @@ #define ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_MCHP_XEC_H_ /* PLL 32KHz clock source VTR rail ON. */ -#define MCHP_XEC_PLL_CLK32K_SRC_SIL_OSC 0U -#define MCHP_XEC_PLL_CLK32K_SRC_XTAL 1U -#define MCHP_XEC_PLL_CLK32K_SRC_PIN 2U +#define MCHP_XEC_PLL_CLK32K_SRC_SIL_OSC 0U +#define MCHP_XEC_PLL_CLK32K_SRC_XTAL 1U +#define MCHP_XEC_PLL_CLK32K_SRC_PIN 2U /* Peripheral 32KHz clock source for VTR rail ON and off(VBAT operation) */ -#define MCHP_XEC_PERIPH_CLK32K_SRC_SO_SO 0U -#define MCHP_XEC_PERIPH_CLK32K_SRC_XTAL_XTAL 1U -#define MCHP_XEC_PERIPH_CLK32K_SRC_PIN_SO 2U -#define MCHP_XEC_PERIPH_CLK32K_SRC_PIN_XTAL 3U +#define MCHP_XEC_PERIPH_CLK32K_SRC_SO_SO 0U +#define MCHP_XEC_PERIPH_CLK32K_SRC_XTAL_XTAL 1U +#define MCHP_XEC_PERIPH_CLK32K_SRC_PIN_SO 2U +#define MCHP_XEC_PERIPH_CLK32K_SRC_PIN_XTAL 3U /* clocks supported by the driver */ -#define MCHP_XEC_PCR_CLK_CORE 0 -#define MCHP_XEC_PCR_CLK_CPU 1 -#define MCHP_XEC_PCR_CLK_BUS 2 -#define MCHP_XEC_PCR_CLK_PERIPH 3 -#define MCHP_XEC_PCR_CLK_PERIPH_FAST 4 -#define MCHP_XEC_PCR_CLK_PERIPH_SLOW 5 +#define MCHP_XEC_PCR_CLK_CORE 0 +#define MCHP_XEC_PCR_CLK_CPU 1 +#define MCHP_XEC_PCR_CLK_BUS 2 +#define MCHP_XEC_PCR_CLK_PERIPH 3 +#define MCHP_XEC_PCR_CLK_PERIPH_FAST 4 +#define MCHP_XEC_PCR_CLK_PERIPH_SLOW 5 + +/* Encode a peripheral's sleep-en/clock-req/reset-en index and bit position */ +#define MCHP_XEC_SCR_ENCODE(idx, bitpos) (((idx) & 0x7) | (((bitpos) & 0x1f) << 3)) #endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_MCHP_XEC_H_ */ diff --git a/soc/microchip/mec/common/CMakeLists.txt b/soc/microchip/mec/common/CMakeLists.txt index 599ec653b0aa..0f19288ae785 100644 --- a/soc/microchip/mec/common/CMakeLists.txt +++ b/soc/microchip/mec/common/CMakeLists.txt @@ -1,7 +1,7 @@ # SPDX-License-Identifier: Apache-2.0 zephyr_include_directories(.) -zephyr_library_sources(soc_ecia.c) +zephyr_library_sources(soc_ecia.c soc_pcr.c) zephyr_library_sources_ifdef(CONFIG_SOC_SERIES_MEC172X soc_i2c.c ) diff --git a/soc/microchip/mec/common/reg/mec_uart.h b/soc/microchip/mec/common/reg/mec_uart.h index 4ae30948bc6a..34212da4cd33 100644 --- a/soc/microchip/mec/common/reg/mec_uart.h +++ b/soc/microchip/mec/common/reg/mec_uart.h @@ -9,172 +9,206 @@ #include #include +#include -#define MCHP_UART_RX_FIFO_MAX_LEN 16u -#define MCHP_UART_TX_FIFO_MAX_LEN 16u +#define XEC_UART_RX_FIFO_MAX_LEN 16u +#define XEC_UART_TX_FIFO_MAX_LEN 16u -#define MCHP_UART_BAUD_RATE_MIN 50u -#define MCHP_UART_BAUD_RATE_MAX 1500000u +#define XEC_UART_BAUD_RATE_MIN 50u +#define XEC_UART_BAUD_RATE_MAX 1500000u -#define MCHP_UART_SPACING 0x400u +#define XEC_UART_SPACING 0x400u /* * LCR DLAB=0 * Transmit buffer(WO), Receive buffer(RO) * LCR DLAB=1, BAUD rate divisor LSB */ -#define MCHP_UART_RTXB_OFS 0u -#define MCHP_UART_BRGD_LSB_OFS 0u +#define XEC_UART_RTXB_OFS 0u +#define XEC_UART_BRGD_LSB_OFS 0u /* * LCR DLAB=0 * Interrupt Enable Register, R/W * LCR DLAB=1, BAUD rate divisor MSB */ -#define MCHP_UART_BRGD_MSB_OFS 1u -#define MCHP_UART_IER_OFS 1u -#define MCHP_UART_IER_MASK 0x0fu -#define MCHP_UART_IER_ERDAI 0x01u /* Received data available and timeouts */ -#define MCHP_UART_IER_ETHREI 0x02u /* TX Holding register empty */ -#define MCHP_UART_IER_ELSI 0x04u /* Errors: Overrun, Parity, Framing, and Break */ -#define MCHP_UART_IER_EMSI 0x08u /* Modem Status */ -#define MCHP_UART_IER_ALL 0x0fu +#define XEC_UART_BRGD_MSB_OFS 1u +#define XEC_UART_IER_OFS 1u +#define XEC_UART_IER_MASK 0x0fu +#define XEC_UART_IER_ERDAI_POS 0 +#define XEC_UART_IER_ETHREI_POS 1 +#define XEC_UART_IER_ELSI_POS 2 +#define XEC_UART_IER_EMSI_POS 3 + +#define XEC_UART_IER_ERDAI 0x01u /* Received data available and timeouts */ +#define XEC_UART_IER_ETHREI 0x02u /* TX Holding register empty */ +#define XEC_UART_IER_ELSI 0x04u /* Errors: Overrun, Parity, Framing, and Break */ +#define XEC_UART_IER_EMSI 0x08u /* Modem Status */ +#define XEC_UART_IER_ALL 0x0fu /* FIFO Control Register, Write-Only */ -#define MCHP_UART_FCR_OFS 2u -#define MCHP_UART_FCR_MASK 0xcfu -#define MCHP_UART_FCR_EXRF 0x01u /* Enable TX & RX FIFO's */ -#define MCHP_UART_FCR_CLR_RX_FIFO 0x02u /* Clear RX FIFO, bit is self-clearing */ -#define MCHP_UART_FCR_CLR_TX_FIFO 0x04u /* Clear TX FIFO, bit is self-clearing */ -#define MCHP_UART_FCR_DMA_EN 0x08u /* DMA Mode Enable. Not implemented */ -#define MCHP_UART_FCR_RX_FIFO_LVL_MASK 0xc0u /* RX FIFO trigger level mask */ -#define MCHP_UART_FCR_RX_FIFO_LVL_1 0x00u -#define MCHP_UART_FCR_RX_FIFO_LVL_4 0x40u -#define MCHP_UART_FCR_RX_FIFO_LVL_8 0x80u -#define MCHP_UART_FCR_RX_FIFO_LVL_14 0xc0u - -/* Interrupt Identification Register, Read-Only */ -#define MCHP_UART_IIR_OFS 2u -#define MCHP_UART_IIR_MASK 0xcfu -#define MCHP_UART_IIR_NOT_IPEND 0x01u -#define MCHP_UART_IIR_INTID_MASK0 0x07u -#define MCHP_UART_IIR_INTID_POS 1u -#define MCHP_UART_IIR_INTID_MASK 0x0eu -#define MCHP_UART_IIR_FIFO_EN_MASK 0xc0u -/* - * interrupt values - * Highest priority: Line status, overrun, framing, or break - * Highest-1. RX data available or RX FIFO trigger level reached - * Highest-2. RX timeout - * Highest-3. TX Holding register empty - * Highest-4. MODEM status +#define XEC_UART_FCR_OFS 2u +#define XEC_UART_FCR_MSK 0xcfu +#define XEC_UART_FCR_EXRF 0x01u /* Enable TX & RX FIFO's */ +#define XEC_UART_FCR_CLR_RX_FIFO 0x02u /* Clear RX FIFO, bit is self-clearing */ +#define XEC_UART_FCR_CLR_TX_FIFO 0x04u /* Clear TX FIFO, bit is self-clearing */ +#define XEC_UART_FCR_DMA_EN 0x08u /* DMA Mode Enable. Not implemented */ +#define XEC_UART_FCR_RX_FIFO_LVL_MSK GENMASK(7, 6) +#define XEC_UART_FCR_RX_FIFO_LVL_1 0 +#define XEC_UART_FCR_RX_FIFO_LVL_4 1u +#define XEC_UART_FCR_RX_FIFO_LVL_8 2u +#define XEC_UART_FCR_RX_FIFO_LVL_14 3u +#define XEC_UART_FCR_RX_FIFO_LVL_SET(f) FIELD_PREP(XEC_UART_FCR_RX_FIFO_LVL_MSK, (f)) +#define XEC_UART_FCR_RX_FIFO_LVL_GET(r) FIELD_GET(XEC_UART_FCR_RX_FIFO_LVL_MSK, (r)) + +/* Interrupt Identification Register, Read-Only + * IIR encodes one interrupt event at a time by event priority. + * It must be read and each interrupt event ID processed until + * bit[0] -> 1 indicating no UART interrupt event is pending. + * 16550 HW event priority and clearing method. + * Highest: Errors: overrun, parity, framing or break. Clear by reading LSR + * Second Highest: RX data available or RX FIFO trigger level reached + * Clear by reading RX data register until below RX FIFO threshold + * Second Highest: RX data timeout. RX character received without error and has not + * been removed from RX buffer/FIFO for 4 character times. Indicates servicing + * FW is not able to keep up. Clear by reading RX data. + * Third Highest: TX Holding Register Empty. Clear by reading IIR or writing next + * byte to transmit into TX holding register or FIFO. + * Lowest: MODEM status CTS, DSR, or RI. Clear by reading MSR. */ -#define MCHP_UART_IIR_INT_NONE 0x01u -#define MCHP_UART_IIR_INT_LS 0x06u -#define MCHP_UART_IIR_INT_RX 0x04u -#define MCHP_UART_IIR_INT_RX_TMOUT 0x0cu -#define MCHP_UART_IIR_INT_THRE 0x02u -#define MCHP_UART_IIR_INT_MS 0x00u +#define XEC_UART_IIR_OFS 2u +#define XEC_UART_IIR_MASK 0xcfu +#define XEC_UART_IIR_NOT_IPEND_POS 0 +#define XEC_UART_IIR_INTID_POS 1u +#define XEC_UART_IIR_INTID_MSK GENMASK(3, 1) +#define XEC_UART_IIR_INTID_MDM 0 +#define XEC_UART_IIR_INTID_THRE 1u +#define XEC_UART_IIR_INTID_RXD 2u +#define XEC_UART_IIR_INTID_LSR 3u +#define XEC_UART_IIR_INTID_RXTM 6u +#define XEC_UART_IIR_INTID_GET(r) FIELD_GET(XEC_UART_IIR_INTID_MSK, (r)) + +#define XEC_UART_IIR_INTID_MASK0 0x0fu +#define XEC_UART_IIR_INTID_MASK 0x0eu +#define XEC_UART_IIR_FIFO_EN_MASK 0xc0u /* Line Control Register R/W */ -#define MCHP_UART_LCR_OFS 3u -#define MCHP_UART_LCR_WORD_LEN_MASK 0x03u -#define MCHP_UART_LCR_WORD_LEN_5 0x00u -#define MCHP_UART_LCR_WORD_LEN_6 0x01u -#define MCHP_UART_LCR_WORD_LEN_7 0x02u -#define MCHP_UART_LCR_WORD_LEN_8 0x03u -#define MCHP_UART_LCR_STOP_BIT_1 0x00u -#define MCHP_UART_LCR_STOP_BIT_2 0x04u -#define MCHP_UART_LCR_PARITY_NONE 0x00u -#define MCHP_UART_LCR_PARITY_EN 0x08u -#define MCHP_UART_LCR_PARITY_ODD 0x00u -#define MCHP_UART_LCR_PARITY_EVEN 0x10u -#define MCHP_UART_LCR_STICK_PARITY 0x20u -#define MCHP_UART_LCR_BREAK_EN 0x40u -#define MCHP_UART_LCR_DLAB_EN 0x80u +#define XEC_UART_LCR_OFS 3u +#define XEC_UART_LCR_WORD_LEN_MSK GENMASK(1, 0) +#define XEC_UART_LCR_WORD_LEN_5 0x00u +#define XEC_UART_LCR_WORD_LEN_6 0x01u +#define XEC_UART_LCR_WORD_LEN_7 0x02u +#define XEC_UART_LCR_WORD_LEN_8 0x03u +#define XEC_UART_LCR_WORD_LEN_SET(l) FIELD_PREP(XEC_UART_LCR_WORD_LEN_MSK, (l)) +#define XEC_UART_LCR_WORD_LEN_GET(r) FIELD_GET(XEC_UART_LCR_WORD_LEN_MSK, (r)) +#define XEC_UART_LCR_STOP_BIT_1 0x00u +#define XEC_UART_LCR_STOP_BIT_2 0x04u +#define XEC_UART_LCR_PARITY_MSK GENMASK(5, 3) +#define XEC_UART_LCR_PARITY_NONE 0 +#define XEC_UART_LCR_PARITY_ODD 0x1u +#define XEC_UART_LCR_PARITY_EVEN 0x3u +#define XEC_UART_LCR_PARITY_MARK 0x5u +#define XEC_UART_LCR_PARITY_SPACE 0x7u +#define XEC_UART_LCR_PARITY_SET(p) FIELD_PREP(XEC_UART_LCR_PARITY_MSK, (p)) +#define XEC_UART_LCR_PARITY_GET(r) FIELD_GET(XEC_UART_LCR_PARITY_MSK, (r)) +#define XEC_UART_LCR_BREAK_EN 0x40u +#define XEC_UART_LCR_DLAB_EN 0x80u /* MODEM Control Register R/W */ -#define MCHP_UART_MCR_OFS 4u -#define MCHP_UART_MCR_MASK 0x1fu -#define MCHP_UART_MCR_DTRn 0x01u -#define MCHP_UART_MCR_RTSn 0x02u -#define MCHP_UART_MCR_OUT1 0x04u -#define MCHP_UART_MCR_OUT2 0x08u -#define MCHP_UART_MCR_LOOPBCK_EN 0x10u +#define XEC_UART_MCR_OFS 4u +#define XEC_UART_MCR_MASK 0x1fu +#define XEC_UART_MCR_DTRn 0x01u +#define XEC_UART_MCR_RTSn 0x02u +#define XEC_UART_MCR_OUT1 0x04u +#define XEC_UART_MCR_OUT2 0x08u +#define XEC_UART_MCR_LOOPBCK_EN 0x10u /* Line Status Register RO */ -#define MCHP_UART_LSR_OFS 5u -#define MCHP_UART_LSR_DATA_RDY 0x01u -#define MCHP_UART_LSR_OVERRUN 0x02u -#define MCHP_UART_LSR_PARITY 0x04u -#define MCHP_UART_LSR_FRAME 0x08u -#define MCHP_UART_LSR_RX_BREAK 0x10u -#define MCHP_UART_LSR_THRE 0x20u -#define MCHP_UART_LSR_TEMT 0x40u -#define MCHP_UART_LSR_FIFO_ERR 0x80u -#define MCHP_UART_LSR_ANY 0xffu +#define XEC_UART_LSR_OFS 5u +#define XEC_UART_LSR_DATA_RDY_POS 0 +#define XEC_UART_LSR_OVERRUN_POS 1 +#define XEC_UART_LSR_PARITY_POS 2 +#define XEC_UART_LSR_FRAME_POS 3 +#define XEC_UART_LSR_RX_BREAK_POS 4 +#define XEC_UART_LSR_THRE_POS 5 +#define XEC_UART_LSR_TEMT_POS 6 +#define XEC_UART_LSR_FIFO_ERR_POS 7 + +#define XEC_UART_LSR_DATA_RDY 0x01u +#define XEC_UART_LSR_OVERRUN 0x02u +#define XEC_UART_LSR_PARITY 0x04u +#define XEC_UART_LSR_FRAME 0x08u +#define XEC_UART_LSR_RX_BREAK 0x10u +#define XEC_UART_LSR_THRE 0x20u +#define XEC_UART_LSR_TEMT 0x40u +#define XEC_UART_LSR_FIFO_ERR 0x80u +#define XEC_UART_LSR_ANY 0xffu +#define XEC_UART_LSR_ANY_ERR 0x1eu /* MODEM Status Register RO */ -#define MCHP_UART_MSR_OFS 6u -#define MCHP_UART_MSR_DCTS 0x01u -#define MCHP_UART_MSR_DDSR 0x02u -#define MCHP_UART_MSR_TERI 0x04u -#define MCHP_UART_MSR_DDCD 0x08u -#define MCHP_UART_MSR_CTS 0x10u -#define MCHP_UART_MSR_DSR 0x20u -#define MCHP_UART_MSR_RI 0x40u -#define MCHP_UART_MSR_DCD 0x80u +#define XEC_UART_MSR_OFS 6u +#define XEC_UART_MSR_DCTS_POS 0 +#define XEC_UART_MSR_DDSR_POS 1 +#define XEC_UART_MSR_TERI_POS 2 +#define XEC_UART_MSR_DDCD_POS 3 +#define XEC_UART_MSR_CTS_POS 4 +#define XEC_UART_MSR_DSR_POS 5 +#define XEC_UART_MSR_RI_POS 6 +#define XEC_UART_MSR_DCD_POS 7 + +#define XEC_UART_MSR_DCTS 0x01u +#define XEC_UART_MSR_DDSR 0x02u +#define XEC_UART_MSR_TERI 0x04u +#define XEC_UART_MSR_DDCD 0x08u +#define XEC_UART_MSR_CTS 0x10u +#define XEC_UART_MSR_DSR 0x20u +#define XEC_UART_MSR_RI 0x40u +#define XEC_UART_MSR_DCD 0x80u /* Scratch Register RO */ -#define MCHP_UART_SCR_OFS 7u +#define XEC_UART_SCR_OFS 7u /* UART Logical Device Activate Register */ -#define MCHP_UART_LD_ACT_OFS 0x330u -#define MCHP_UART_LD_ACTIVATE 0x01u +#define XEC_UART_LD_ACT_OFS 0x330u +#define XEC_UART_LD_ACTIVATE_POS 0 +#define XEC_UART_LD_ACTIVATE 0x01u /* UART Logical Device Config Register */ -#define MCHP_UART_LD_CFG_OFS 0x3f0u -#define MCHP_UART_LD_CFG_INTCLK 0u -#define MCHP_UART_LD_CFG_NO_INVERT 0u -#define MCHP_UART_LD_CFG_RESET_SYS 0u -#define MCHP_UART_LD_CFG_EXTCLK BIT(0) -#define MCHP_UART_LD_CFG_RESET_VCC BIT(1) -#define MCHP_UART_LD_CFG_INVERT BIT(2) +#define XEC_UART_LD_CFG_OFS 0x3f0u +#define XEC_UART_LD_CFG_INTCLK 0u +#define XEC_UART_LD_CFG_NO_INVERT 0u +#define XEC_UART_LD_CFG_RESET_SYS 0u +#define XEC_UART_LD_CFG_EXTCLK BIT(0) +#define XEC_UART_LD_CFG_RESET_VCC BIT(1) +#define XEC_UART_LD_CFG_INVERT BIT(2) + +/* MEC174x and onwards have a new register only visible to the EC at offset 0x8 + * Line State 2 register. It has fields indicating the number of bytes currenly + * in the TX FIFO and if the TX FIFO is full. + */ +#define XEC_UART_LSR2_OFS 8u +#define XEC_UART_LSR2_TX_FIFO_FULL_POS 0 +#define XEC_UART_LSR2_TX_FIFO_CNT_POS 4u +#define XEC_UART_LSR2_TX_FIFO_CNT_MSK 0xf0u /* BAUD rate generator */ -#define MCHP_UART_INT_CLK_24M BIT(15) +#define XEC_UART_INT_CLK_24M BIT(15) /* 1.8MHz internal clock source */ -#define MCHP_UART_1P8M_BAUD_50 2304u -#define MCHP_UART_1P8M_BAUD_110 1536u -#define MCHP_UART_1P8M_BAUD_150 768u -#define MCHP_UART_1P8M_BAUD_300 384u -#define MCHP_UART_1P8M_BAUD_1200 96u -#define MCHP_UART_1P8M_BAUD_2400 48u -#define MCHP_UART_1P8M_BAUD_9600 12u -#define MCHP_UART_1P8M_BAUD_19200 6u -#define MCHP_UART_1P8M_BAUD_38400 3u -#define MCHP_UART_1P8M_BAUD_57600 2u -#define MCHP_UART_1P8M_BAUD_115200 1u +#define XEC_UART_1P8M_BAUD_50 2304u +#define XEC_UART_1P8M_BAUD_110 1536u +#define XEC_UART_1P8M_BAUD_150 768u +#define XEC_UART_1P8M_BAUD_300 384u +#define XEC_UART_1P8M_BAUD_1200 96u +#define XEC_UART_1P8M_BAUD_2400 48u +#define XEC_UART_1P8M_BAUD_9600 12u +#define XEC_UART_1P8M_BAUD_19200 6u +#define XEC_UART_1P8M_BAUD_38400 3u +#define XEC_UART_1P8M_BAUD_57600 2u +#define XEC_UART_1P8M_BAUD_115200 1u /* 24MHz internal clock source. n = 24e6 / (BAUD * 16) = 1500000 / BAUD */ -#define MCHP_UART_24M_BAUD_115200 ((13u) + (MCHP_UART_INT_CLK_24M)) -#define MCHP_UART_24M_BAUD_57600 ((26u) + (MCHP_UART_INT_CLK_24M)) - -/** @brief 16550 compatible UART. Size = 1012(0x3f4) */ -struct uart_regs { - volatile uint8_t RTXB; - volatile uint8_t IER; - volatile uint8_t IIR_FCR; - volatile uint8_t LCR; - volatile uint8_t MCR; - volatile uint8_t LSR; - volatile uint8_t MSR; - volatile uint8_t SCR; - uint8_t RSVDA[0x330 - 0x08]; - volatile uint8_t ACTV; - uint8_t RSVDB[0x3f0 - 0x331]; - volatile uint8_t CFG_SEL; -}; - -#endif /* #ifndef _MEC_MCHP_UART_H */ +#define XEC_UART_24M_BAUD_115200 ((13u) + (XEC_UART_INT_CLK_24M)) +#define XEC_UART_24M_BAUD_57600 ((26u) + (XEC_UART_INT_CLK_24M)) + +#endif /* #ifndef _MEC_UART_H */ diff --git a/soc/microchip/mec/common/soc_mmcr.h b/soc/microchip/mec/common/soc_mmcr.h index 8b0c07cbb65f..11708bf81593 100644 --- a/soc/microchip/mec/common/soc_mmcr.h +++ b/soc/microchip/mec/common/soc_mmcr.h @@ -11,6 +11,7 @@ #ifndef _SOC_MICROCHIP_MEC_COMMON_MMCR_H_ #define _SOC_MICROCHIP_MEC_COMMON_MMCR_H_ +#include #include /* mem_addr_t definition */ /* Zephyr only provides 32-bit version of these routines. We need these for memory @@ -127,4 +128,28 @@ static ALWAYS_INLINE int soc_test_and_clear_bit16(mem_addr_t addr, unsigned int return ret; } +static ALWAYS_INLINE void soc_mmcr_mask_set(mem_addr_t addr, uint32_t val, uint32_t mask) +{ + uint32_t temp = *(volatile uint32_t *)addr; + + temp = (temp & ~mask) | (val & mask); + *(volatile uint32_t *)addr = temp; +} + +static ALWAYS_INLINE void soc_mmcr_mask_set16(mem_addr_t addr, uint16_t val, uint16_t mask) +{ + uint32_t temp = *(volatile uint16_t *)addr; + + temp = (temp & ~mask) | (val & mask); + *(volatile uint16_t *)addr = (uint16_t)temp; +} + +static ALWAYS_INLINE void soc_mmcr_mask_set8(mem_addr_t addr, uint8_t val, uint8_t mask) +{ + uint32_t temp = *(volatile uint8_t *)addr; + + temp = (temp & ~mask) | (val & mask); + *(volatile uint8_t *)addr = (uint8_t)temp; +} + #endif /* SOC_MICROCHIP_MEC_COMMON_MMCR_H_ */ diff --git a/soc/microchip/mec/common/soc_pcr.c b/soc/microchip/mec/common/soc_pcr.c new file mode 100644 index 000000000000..2c17f8427712 --- /dev/null +++ b/soc/microchip/mec/common/soc_pcr.c @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +#include "soc_pcr.h" + +/* Reset a peripheral block */ +void soc_xec_pcr_reset_en(uint16_t enc_pcr_scr) +{ + mem_addr_t raddr = XEC_PCR_RST_EN_BASE + (MCHP_XEC_PCR_SCR_GET_IDX(enc_pcr_scr) * 4u); + unsigned int irq_lock_val = irq_lock(); + + sys_write32(XEC_PCR_RST_EN_UNLOCK_VAL, (mem_addr_t)XEC_PCR_RST_EN_LOCK_BASE); + sys_set_bit(raddr, MCHP_XEC_PCR_SCR_GET_BITPOS(enc_pcr_scr)); + sys_write32(XEC_PCR_RST_EN_LOCK_VAL, XEC_PCR_RST_EN_LOCK_BASE); + irq_unlock(irq_lock_val); +} diff --git a/soc/microchip/mec/common/soc_pcr.h b/soc/microchip/mec/common/soc_pcr.h index ea29f4a56d14..f035a26b94dc 100644 --- a/soc/microchip/mec/common/soc_pcr.h +++ b/soc/microchip/mec/common/soc_pcr.h @@ -11,35 +11,44 @@ extern "C" { #endif -/* slp_idx = [0, 4], bitpos = [0, 31] refer above */ -#define MCHP_XEC_PCR_SCR_ENCODE(slp_idx, bitpos, domain) \ - ((((uint32_t)(domain) & 0xff) << 24) | (((bitpos) & 0x1f) << 3) \ - | ((uint32_t)(slp_idx) & 0x7)) +#include +#include +#include +#include -#define MCHP_XEC_PCR_SCR_GET_IDX(e) ((e) & 0x7u) -#define MCHP_XEC_PCR_SCR_GET_BITPOS(e) (((e) & 0xf8u) >> 3) +/* + * slp_idx must be 0 through 4 + * bitpos must be 0 through 31 + */ +#define MCHP_XEC_ENC_PCR_SCR(slp_idx, bitpos) (((slp_idx) & 0x7u) | (((bitpos) & 0x1fu) << 3)) + +#define MCHP_XEC_PCR_SCR_ENCODE(slp_idx, bitpos, domain) \ + ((((uint32_t)(domain) & 0xff) << 24) | (((bitpos) & 0x1f) << 3) | \ + ((uint32_t)(slp_idx) & 0x7)) + +#define MCHP_XEC_PCR_SCR_GET_IDX(e) ((e) & 0x7u) +#define MCHP_XEC_PCR_SCR_GET_BITPOS(e) (((e) & 0xf8u) >> 3) /* cpu clock divider */ -#define MCHP_XEC_CLK_CPU_MASK GENMASK(7, 0) -#define MCHP_XEC_CLK_CPU_CLK_DIV_1 1u -#define MCHP_XEC_CLK_CPU_CLK_DIV_2 2u -#define MCHP_XEC_CLK_CPU_CLK_DIV_4 4u -#define MCHP_XEC_CLK_CPU_CLK_DIV_8 8u -#define MCHP_XEC_CLK_CPU_CLK_DIV_16 16u -#define MCHP_XEC_CLK_CPU_CLK_DIV_48 48u +#define MCHP_XEC_CLK_CPU_MASK GENMASK(7, 0) +#define MCHP_XEC_CLK_CPU_CLK_DIV_1 1u +#define MCHP_XEC_CLK_CPU_CLK_DIV_2 2u +#define MCHP_XEC_CLK_CPU_CLK_DIV_4 4u +#define MCHP_XEC_CLK_CPU_CLK_DIV_8 8u +#define MCHP_XEC_CLK_CPU_CLK_DIV_16 16u +#define MCHP_XEC_CLK_CPU_CLK_DIV_48 48u /* slow clock divider */ -#define MCHP_XEC_CLK_SLOW_MASK GENMASK(8, 0) -#define MCHP_XEC_CLK_SLOW_CLK_DIV_100K 480u +#define MCHP_XEC_CLK_SLOW_MASK GENMASK(8, 0) +#define MCHP_XEC_CLK_SLOW_CLK_DIV_100K 480u -#define MCHP_XEC_CLK_SRC_POS 24 -#define MCHP_XEC_CLK_SRC_MASK GENMASK(31, 24) +#define MCHP_XEC_CLK_SRC_POS 24 +#define MCHP_XEC_CLK_SRC_MASK GENMASK(31, 24) -#define MCHP_XEC_CLK_SRC_GET(n) \ - (((n) & MCHP_XEC_CLK_SRC_MASK) >> MCHP_XEC_CLK_SRC_POS) +#define MCHP_XEC_CLK_SRC_GET(n) (((n) & MCHP_XEC_CLK_SRC_MASK) >> MCHP_XEC_CLK_SRC_POS) -#define MCHP_XEC_CLK_SRC_SET(v, c) (((v) & ~MCHP_XEC_CLK_SRC_MASK) |\ - (((c) << MCHP_XEC_CLK_SRC_POS) & MCHP_XEC_CLK_SRC_MASK)) +#define MCHP_XEC_CLK_SRC_SET(v, c) \ + (((v) & ~MCHP_XEC_CLK_SRC_MASK) | (((c) << MCHP_XEC_CLK_SRC_POS) & MCHP_XEC_CLK_SRC_MASK)) /* * b[31:24] = clock source @@ -49,6 +58,42 @@ struct mchp_xec_pcr_clk_ctrl { uint32_t pcr_info; }; +/* inline routines */ +#define XEC_PCR_BASE (mem_addr_t)(DT_REG_ADDR_BY_IDX(DT_NODELABEL(pcr), 0)) +#define XEC_PCR_SLP_EN_BASE (XEC_PCR_BASE + 0x30u) +#define XEC_PCR_CLK_REQ_BASE (XEC_PCR_BASE + 0x50u) +#define XEC_PCR_RST_EN_BASE (XEC_PCR_BASE + 0x70u) +#define XEC_PCR_RST_EN_LOCK_BASE (XEC_PCR_BASE + 0x84u) +#define XEC_PCR_RST_EN_LOCK_VAL 0xa6382d4du +#define XEC_PCR_RST_EN_UNLOCK_VAL 0xa6382d4cu +/* PCR sleep enabled, clock required, and reset enable registers are all 32-bit */ +#define XEC_PCR_SCR_REG_SIZE 4u +/* Calculate register offset from encoded zero based index and register size */ +#define XEC_PCR_SCR_REG_OFS(e) (MCHP_XEC_PCR_SCR_GET_IDX(enc_pcr_scr) * XEC_PCR_SCR_REG_SIZE) + +static ALWAYS_INLINE void soc_xec_pcr_sleep_en_set(uint8_t enc_pcr_scr) +{ + mem_addr_t raddr = XEC_PCR_SLP_EN_BASE + XEC_PCR_SCR_REG_OFS(enc_pcr_scr); + + sys_set_bit(raddr, MCHP_XEC_PCR_SCR_GET_BITPOS(enc_pcr_scr)); +} + +static ALWAYS_INLINE void soc_xec_pcr_sleep_en_clear(uint8_t enc_pcr_scr) +{ + mem_addr_t raddr = XEC_PCR_SLP_EN_BASE + XEC_PCR_SCR_REG_OFS(enc_pcr_scr); + + sys_clear_bit(raddr, MCHP_XEC_PCR_SCR_GET_BITPOS(enc_pcr_scr)); +} + +static ALWAYS_INLINE int soc_xec_pcr_clk_req(uint8_t enc_pcr_scr) +{ + mem_addr_t raddr = XEC_PCR_CLK_REQ_BASE + XEC_PCR_SCR_REG_OFS(enc_pcr_scr); + + return sys_test_bit(raddr, MCHP_XEC_PCR_SCR_GET_BITPOS(enc_pcr_scr)); +} + +void soc_xec_pcr_reset_en(uint16_t enc_pcr_scr); + #ifdef __cplusplus } #endif diff --git a/soc/microchip/mec/mec15xx/soc.h b/soc/microchip/mec/mec15xx/soc.h index cc7ab6651337..dc4c852e067a 100644 --- a/soc/microchip/mec/mec15xx/soc.h +++ b/soc/microchip/mec/mec15xx/soc.h @@ -15,8 +15,8 @@ #include "regaccess.h" /* common peripheral register defines */ - #include +#include /* common SoC API */ #include diff --git a/soc/microchip/mec/mec165xb/soc.h b/soc/microchip/mec/mec165xb/soc.h index d36b501cb029..545b8a1d102f 100644 --- a/soc/microchip/mec/mec165xb/soc.h +++ b/soc/microchip/mec/mec165xb/soc.h @@ -11,10 +11,26 @@ #ifndef _ASMLANGUAGE -#include "device_mec5.h" +#define MCHP_HAS_UART_LSR2 + +#include /* common peripheral register defines */ +#include +#include +#include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* common SoC API */ #include diff --git a/soc/microchip/mec/mec174x/soc.h b/soc/microchip/mec/mec174x/soc.h index 1a29328c2c77..cdfc1f228ccd 100644 --- a/soc/microchip/mec/mec174x/soc.h +++ b/soc/microchip/mec/mec174x/soc.h @@ -11,12 +11,15 @@ #ifndef _ASMLANGUAGE +#define MCHP_HAS_UART_LSR2 + #include /* common peripheral register defines */ #include #include #include +#include #include #include #include @@ -28,7 +31,6 @@ #include #include #include -#include /* common SoC API */ #include @@ -39,6 +41,5 @@ #include #include - #endif #endif diff --git a/soc/microchip/mec/mec175x/soc.h b/soc/microchip/mec/mec175x/soc.h index 796c9b84730c..93b1987e033b 100644 --- a/soc/microchip/mec/mec175x/soc.h +++ b/soc/microchip/mec/mec175x/soc.h @@ -11,12 +11,15 @@ #ifndef _ASMLANGUAGE +#define MCHP_HAS_UART_LSR2 + #include /* common peripheral register defines */ #include #include #include +#include #include #include #include @@ -28,7 +31,6 @@ #include #include #include -#include /* common SoC API */ #include From 63b7e57fe9cc3030327fb7e3e6eecced2408f909 Mon Sep 17 00:00:00 2001 From: Scott Worley Date: Wed, 3 Dec 2025 15:12:55 -0500 Subject: [PATCH 1870/3659] dts: arm: microchip: mec: Update UART nodes with new driver properties We updates all the UART hardware nodes for all MEC parts with properties used by the new, common UART driver. Signed-off-by: Scott Worley --- dts/arm/microchip/mec/mec1501hsz.dtsi | 12 ++++++------ dts/arm/microchip/mec/mec172x_common.dtsi | 8 ++++---- dts/arm/microchip/mec/mec5.dtsi | 9 +++++++-- dts/arm/microchip/mec/mec5_mec1653bnsz.dtsi | 4 +++- dts/arm/microchip/mec/mec5_mec1743qlj.dtsi | 8 ++++++-- dts/arm/microchip/mec/mec5_mec1743qsz.dtsi | 4 +++- dts/arm/microchip/mec/mec5_mec1753qlj.dtsi | 8 ++++++-- dts/arm/microchip/mec/mec5_mec1753qsz.dtsi | 4 +++- 8 files changed, 38 insertions(+), 19 deletions(-) diff --git a/dts/arm/microchip/mec/mec1501hsz.dtsi b/dts/arm/microchip/mec/mec1501hsz.dtsi index adac5fca059c..5815a8859e69 100644 --- a/dts/arm/microchip/mec/mec1501hsz.dtsi +++ b/dts/arm/microchip/mec/mec1501hsz.dtsi @@ -190,8 +190,8 @@ interrupts = <40 0>; clock-frequency = <1843200>; current-speed = <38400>; - girqs = <15 0>; - pcrs = <2 1>; + girqs = ; + pcr-scr = ; ldn = <9>; status = "disabled"; }; @@ -202,8 +202,8 @@ interrupts = <41 0>; clock-frequency = <1843200>; current-speed = <38400>; - girqs = <15 1>; - pcrs = <2 2>; + girqs = ; + pcr-scr = ; ldn = <10>; status = "disabled"; }; @@ -214,8 +214,8 @@ interrupts = <44 0>; clock-frequency = <1843200>; current-speed = <38400>; - girqs = <15 4>; - pcrs = <2 28>; + girqs = ; + pcr-scr = ; ldn = <11>; status = "disabled"; }; diff --git a/dts/arm/microchip/mec/mec172x_common.dtsi b/dts/arm/microchip/mec/mec172x_common.dtsi index 52850fb82684..ba87bccd832a 100644 --- a/dts/arm/microchip/mec/mec172x_common.dtsi +++ b/dts/arm/microchip/mec/mec172x_common.dtsi @@ -864,8 +864,8 @@ uart0: uart@400f2400 { interrupts = <40 1>; clock-frequency = <1843200>; current-speed = <38400>; - girqs = <15 0>; - pcrs = <2 1>; + girqs = ; + pcr-scr = ; ldn = <9>; status = "disabled"; }; @@ -876,8 +876,8 @@ uart1: uart@400f2800 { interrupts = <41 1>; clock-frequency = <1843200>; current-speed = <38400>; - girqs = <15 1>; - pcrs = <2 2>; + girqs = ; + pcr-scr = ; ldn = <10>; status = "disabled"; }; diff --git a/dts/arm/microchip/mec/mec5.dtsi b/dts/arm/microchip/mec/mec5.dtsi index 8d4c2e1824ff..60de7b7afa6e 100644 --- a/dts/arm/microchip/mec/mec5.dtsi +++ b/dts/arm/microchip/mec/mec5.dtsi @@ -5,6 +5,7 @@ */ #include +#include #include #include #include @@ -232,14 +233,18 @@ uart0: uart@400f2400 { reg = <0x400f2400 0x400>; interrupts = <40 1>; - girqs = <15 0>; + girqs = ; + pcr-scr = ; + ldn = <9>; status = "disabled"; }; uart1: uart@400f2800 { reg = <0x400f2800 0x400>; interrupts = <41 1>; - girqs = <15 1>; + girqs = ; + pcr-scr = ; + ldn = <10>; status = "disabled"; }; diff --git a/dts/arm/microchip/mec/mec5_mec1653bnsz.dtsi b/dts/arm/microchip/mec/mec5_mec1653bnsz.dtsi index 1c8efca0b15d..aee3d83bd2b2 100644 --- a/dts/arm/microchip/mec/mec5_mec1653bnsz.dtsi +++ b/dts/arm/microchip/mec/mec5_mec1653bnsz.dtsi @@ -42,7 +42,9 @@ uart2: uart@400f2c00 { reg = <0x400f2c00 0x400>; interrupts = <183 2>; - girqs = <15 25>; + girqs = ; + pcr-scr = ; + ldn = <11>; clock-frequency = <1843200>; current-speed = <115200>; status = "disabled"; diff --git a/dts/arm/microchip/mec/mec5_mec1743qlj.dtsi b/dts/arm/microchip/mec/mec5_mec1743qlj.dtsi index bf48b5e43dc7..d85b6aac4b5a 100644 --- a/dts/arm/microchip/mec/mec5_mec1743qlj.dtsi +++ b/dts/arm/microchip/mec/mec5_mec1743qlj.dtsi @@ -51,7 +51,9 @@ uart2: uart@400f2c00 { reg = <0x400f2c00 0x400>; interrupts = <183 2>; - girqs = <15 25>; + girqs = ; + pcr-scr = ; + ldn = <11>; clock-frequency = <1843200>; current-speed = <115200>; status = "disabled"; @@ -60,7 +62,9 @@ uart3: uart@400f3000 { reg = <0x400f3000 0x400>; interrupts = <184 2>; - girqs = <15 26>; + girqs = ; + pcr-scr = ; + ldn = <12>; clock-frequency = <1843200>; current-speed = <115200>; status = "disabled"; diff --git a/dts/arm/microchip/mec/mec5_mec1743qsz.dtsi b/dts/arm/microchip/mec/mec5_mec1743qsz.dtsi index 87e26e6d179c..9968261f315f 100644 --- a/dts/arm/microchip/mec/mec5_mec1743qsz.dtsi +++ b/dts/arm/microchip/mec/mec5_mec1743qsz.dtsi @@ -50,7 +50,9 @@ uart2: uart@400f2c00 { reg = <0x400f2c00 0x400>; interrupts = <183 2>; - girqs = <15 25>; + girqs = ; + pcr-scr = ; + ldn = <11>; clock-frequency = <1843200>; current-speed = <115200>; status = "disabled"; diff --git a/dts/arm/microchip/mec/mec5_mec1753qlj.dtsi b/dts/arm/microchip/mec/mec5_mec1753qlj.dtsi index e9aac4ac794b..4dc36d0e1409 100644 --- a/dts/arm/microchip/mec/mec5_mec1753qlj.dtsi +++ b/dts/arm/microchip/mec/mec5_mec1753qlj.dtsi @@ -51,7 +51,9 @@ uart2: uart@400f2c00 { reg = <0x400f2c00 0x400>; interrupts = <183 2>; - girqs = <15 25>; + girqs = ; + pcr-scr = ; + ldn = <11>; clock-frequency = <1843200>; current-speed = <115200>; status = "disabled"; @@ -60,7 +62,9 @@ uart3: uart@400f3000 { reg = <0x400f3000 0x400>; interrupts = <184 2>; - girqs = <15 26>; + girqs = ; + pcr-scr = ; + ldn = <12>; clock-frequency = <1843200>; current-speed = <115200>; status = "disabled"; diff --git a/dts/arm/microchip/mec/mec5_mec1753qsz.dtsi b/dts/arm/microchip/mec/mec5_mec1753qsz.dtsi index 67d2bce495dc..8639581ddf75 100644 --- a/dts/arm/microchip/mec/mec5_mec1753qsz.dtsi +++ b/dts/arm/microchip/mec/mec5_mec1753qsz.dtsi @@ -51,7 +51,9 @@ uart2: uart@400f2c00 { reg = <0x400f2c00 0x400>; interrupts = <183 2>; - girqs = <15 25>; + girqs = ; + pcr-scr = ; + ldn = <11>; clock-frequency = <1843200>; current-speed = <115200>; status = "disabled"; From dc9d70307d8594241c574d761fcd516164db28a5 Mon Sep 17 00:00:00 2001 From: Scott Worley Date: Wed, 3 Dec 2025 15:14:37 -0500 Subject: [PATCH 1871/3659] boards: microchip: Use new, common UART driver for all MEC boards Modify Microchip mec_assy6941 boards to use the new, common UART driver. We also added chose "zephyr,shell-uart" to all MEC boards allowing building of the "echo_bot" sample application. Signed-off-by: Scott Worley --- .../mec1501modular_assy6885/mec1501modular_assy6885.dts | 1 + .../mec15xxevb_assy6853/mec15xxevb_assy6853.dts | 1 + .../mec172xevb_assy6906/mec172xevb_assy6906.dts | 1 + .../mec172xmodular_assy6930/mec172xmodular_assy6930.dts | 1 + .../microchip/mec_assy6941/mec_assy6941_mec1653b_nsz.dts | 9 ++------- .../microchip/mec_assy6941/mec_assy6941_mec1743_qlj.dts | 3 ++- .../microchip/mec_assy6941/mec_assy6941_mec1743_qsz.dts | 3 ++- .../microchip/mec_assy6941/mec_assy6941_mec1753_qlj.dts | 3 ++- .../microchip/mec_assy6941/mec_assy6941_mec1753_qsz.dts | 3 ++- 9 files changed, 14 insertions(+), 11 deletions(-) diff --git a/boards/microchip/mec1501modular_assy6885/mec1501modular_assy6885.dts b/boards/microchip/mec1501modular_assy6885/mec1501modular_assy6885.dts index bf8348982c9a..4dcebe41a69e 100644 --- a/boards/microchip/mec1501modular_assy6885/mec1501modular_assy6885.dts +++ b/boards/microchip/mec1501modular_assy6885/mec1501modular_assy6885.dts @@ -16,6 +16,7 @@ chosen { zephyr,sram = &sram0; zephyr,console = &uart1; + zephyr,shell-uart = &uart1; zephyr,flash = &flash0; }; diff --git a/boards/microchip/mec15xxevb_assy6853/mec15xxevb_assy6853.dts b/boards/microchip/mec15xxevb_assy6853/mec15xxevb_assy6853.dts index 25c11f98f5cf..ba11a01e3cdd 100644 --- a/boards/microchip/mec15xxevb_assy6853/mec15xxevb_assy6853.dts +++ b/boards/microchip/mec15xxevb_assy6853/mec15xxevb_assy6853.dts @@ -15,6 +15,7 @@ chosen { zephyr,sram = &sram0; zephyr,console = &uart2; + zephyr,shell-uart = &uart2; zephyr,flash = &flash0; }; diff --git a/boards/microchip/mec172xevb_assy6906/mec172xevb_assy6906.dts b/boards/microchip/mec172xevb_assy6906/mec172xevb_assy6906.dts index 9d87268b2a85..17bc7bd62069 100644 --- a/boards/microchip/mec172xevb_assy6906/mec172xevb_assy6906.dts +++ b/boards/microchip/mec172xevb_assy6906/mec172xevb_assy6906.dts @@ -17,6 +17,7 @@ zephyr,sram = &sram0; zephyr,flash = &flash0; zephyr,console = &uart1; + zephyr,shell-uart = &uart1; }; aliases { diff --git a/boards/microchip/mec172xmodular_assy6930/mec172xmodular_assy6930.dts b/boards/microchip/mec172xmodular_assy6930/mec172xmodular_assy6930.dts index 72b3e4f9069b..4acfe7026c8c 100644 --- a/boards/microchip/mec172xmodular_assy6930/mec172xmodular_assy6930.dts +++ b/boards/microchip/mec172xmodular_assy6930/mec172xmodular_assy6930.dts @@ -17,6 +17,7 @@ zephyr,sram = &sram0; zephyr,flash = &flash0; zephyr,console = &uart1; + zephyr,shell-uart = &uart1; }; aliases { diff --git a/boards/microchip/mec_assy6941/mec_assy6941_mec1653b_nsz.dts b/boards/microchip/mec_assy6941/mec_assy6941_mec1653b_nsz.dts index 25de1d57adc3..b78a1a06bdcb 100644 --- a/boards/microchip/mec_assy6941/mec_assy6941_mec1653b_nsz.dts +++ b/boards/microchip/mec_assy6941/mec_assy6941_mec1653b_nsz.dts @@ -17,7 +17,7 @@ zephyr,sram = &sram0; zephyr,flash = &flash0; zephyr,console = &uart1; - rtimer-busy-wait-timer = &timer5; + zephyr,shell-uart = &uart1; }; power-states { @@ -51,13 +51,8 @@ status = "okay"; }; -/* We chose 32-bit basic timer 5 for use by ktimer */ -&timer5 { - status = "okay"; -}; - &uart1 { - compatible = "microchip,mec5-uart"; + compatible = "microchip,xec-uart"; status = "okay"; clock-frequency = <1843200>; current-speed = <115200>; diff --git a/boards/microchip/mec_assy6941/mec_assy6941_mec1743_qlj.dts b/boards/microchip/mec_assy6941/mec_assy6941_mec1743_qlj.dts index 4ce509c096bf..ce22011ec78a 100644 --- a/boards/microchip/mec_assy6941/mec_assy6941_mec1743_qlj.dts +++ b/boards/microchip/mec_assy6941/mec_assy6941_mec1743_qlj.dts @@ -17,6 +17,7 @@ zephyr,sram = &sram0; zephyr,flash = &flash0; zephyr,console = &uart1; + zephyr,shell-uart = &uart1; }; power-states { @@ -51,7 +52,7 @@ }; &uart1 { - compatible = "microchip,mec5-uart"; + compatible = "microchip,xec-uart"; status = "okay"; clock-frequency = <1843200>; current-speed = <115200>; diff --git a/boards/microchip/mec_assy6941/mec_assy6941_mec1743_qsz.dts b/boards/microchip/mec_assy6941/mec_assy6941_mec1743_qsz.dts index 05e09ce8dccc..e473c8eb7995 100644 --- a/boards/microchip/mec_assy6941/mec_assy6941_mec1743_qsz.dts +++ b/boards/microchip/mec_assy6941/mec_assy6941_mec1743_qsz.dts @@ -17,6 +17,7 @@ zephyr,sram = &sram0; zephyr,flash = &flash0; zephyr,console = &uart1; + zephyr,shell-uart = &uart1; }; power-states { @@ -51,7 +52,7 @@ }; &uart1 { - compatible = "microchip,mec5-uart"; + compatible = "microchip,xec-uart"; status = "okay"; clock-frequency = <1843200>; current-speed = <115200>; diff --git a/boards/microchip/mec_assy6941/mec_assy6941_mec1753_qlj.dts b/boards/microchip/mec_assy6941/mec_assy6941_mec1753_qlj.dts index 7f4f5dc0b803..b6ba7905eecb 100644 --- a/boards/microchip/mec_assy6941/mec_assy6941_mec1753_qlj.dts +++ b/boards/microchip/mec_assy6941/mec_assy6941_mec1753_qlj.dts @@ -17,6 +17,7 @@ zephyr,sram = &sram0; zephyr,flash = &flash0; zephyr,console = &uart1; + zephyr,shell-uart = &uart1; }; power-states { @@ -51,7 +52,7 @@ }; &uart1 { - compatible = "microchip,mec5-uart"; + compatible = "microchip,xec-uart"; status = "okay"; clock-frequency = <1843200>; current-speed = <115200>; diff --git a/boards/microchip/mec_assy6941/mec_assy6941_mec1753_qsz.dts b/boards/microchip/mec_assy6941/mec_assy6941_mec1753_qsz.dts index e42c63495001..a4b2af338a2b 100644 --- a/boards/microchip/mec_assy6941/mec_assy6941_mec1753_qsz.dts +++ b/boards/microchip/mec_assy6941/mec_assy6941_mec1753_qsz.dts @@ -17,6 +17,7 @@ zephyr,sram = &sram0; zephyr,flash = &flash0; zephyr,console = &uart1; + zephyr,shell-uart = &uart1; }; power-states { @@ -51,7 +52,7 @@ }; &uart1 { - compatible = "microchip,mec5-uart"; + compatible = "microchip,xec-uart"; status = "okay"; clock-frequency = <1843200>; current-speed = <115200>; From 14a4591ec009cfafb080ea264122b70678416b91 Mon Sep 17 00:00:00 2001 From: Ritesh Kudkelwar Date: Tue, 13 Jan 2026 23:13:55 +0530 Subject: [PATCH 1872/3659] doc: document west sdk under zephyr-specific west commands Move west sdk documentation to the Zephyr-specific west commands page and clarify listing, interactive install behavior, and toolchain selection. Signed-off-by: Ritesh Kudkelwar --- doc/develop/west/zephyr-cmds.rst | 46 ++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/doc/develop/west/zephyr-cmds.rst b/doc/develop/west/zephyr-cmds.rst index df211965ec19..a1448592dda5 100644 --- a/doc/develop/west/zephyr-cmds.rst +++ b/doc/develop/west/zephyr-cmds.rst @@ -445,3 +445,49 @@ each individual commit associated with the given pull request. │ ├── second-commit-from-pr.patch │ └── third-commit-from-pr.patch └── patches.yml + +Working with the Zephyr SDK: ``west sdk`` +***************************************** + +The ``west sdk`` command is a Zephyr-specific west command used to list +and install the Zephyr SDK and its toolchains. + +Listing SDKs and toolchains +--------------------------- + +To list installed Zephyr SDKs as well as available SDK releases and +toolchains, run: + +.. code-block:: console + + west sdk list + +This command shows: + +- Installed SDK versions +- Available SDK releases +- Toolchains included in each SDK + +Installing the Zephyr SDK +------------------------- + +To install the Zephyr SDK, run: + +.. code-block:: console + + west sdk install + +This command may run in interactive mode and prompt for SDK or +toolchain selection. When specific toolchains are provided via +``--toolchains``, the command runs non-interactively, which is +recommended for automation. + +To install specific toolchains only, use the ``--toolchains`` option: + +.. code-block:: console + + west sdk install --toolchains arm-zephyr-eabi riscv64-zephyr-elf + +If you are unsure which toolchains you need, run ``west sdk list`` first +to see the available options and avoid downloading unnecessary +toolchains, which can save gigabytes of disk space and download time. From 429d98f80d8c95bd5aa313df5fdd76b8f701c413 Mon Sep 17 00:00:00 2001 From: Carlo Caione Date: Wed, 7 Jan 2026 19:12:13 +0100 Subject: [PATCH 1873/3659] lorawan: move loramac-node backend to subdirectory Refactor the LoRaWAN subsystem to support multiple backends by moving the loramac-node specific implementation into a dedicated subdirectory. This change prepares the subsystem for adding lora-basics-modem support as an alternative backend. Signed-off-by: Carlo Caione --- subsys/lorawan/CMakeLists.txt | 33 +-------- subsys/lorawan/Kconfig | 58 +-------------- subsys/lorawan/loramac-node/CMakeLists.txt | 32 +++++++++ subsys/lorawan/loramac-node/Kconfig | 70 +++++++++++++++++++ subsys/lorawan/{ => loramac-node}/lorawan.c | 2 +- .../lorawan/{ => loramac-node}/lorawan_emul.c | 0 subsys/lorawan/{ => loramac-node}/lw_priv.c | 0 subsys/lorawan/{ => loramac-node}/lw_priv.h | 0 subsys/lorawan/nvm/CMakeLists.txt | 2 + subsys/lorawan/nvm/Kconfig | 2 + subsys/lorawan/services/CMakeLists.txt | 17 +++-- subsys/lorawan/services/Kconfig | 6 +- subsys/lorawan/services/clock_sync.c | 1 - subsys/lorawan/services/frag_decoder_lowmem.h | 5 +- subsys/lorawan/services/frag_flash.c | 3 +- subsys/lorawan/services/frag_transport.c | 1 - subsys/lorawan/services/multicast.c | 2 +- 17 files changed, 134 insertions(+), 100 deletions(-) create mode 100644 subsys/lorawan/loramac-node/CMakeLists.txt create mode 100644 subsys/lorawan/loramac-node/Kconfig rename subsys/lorawan/{ => loramac-node}/lorawan.c (99%) rename subsys/lorawan/{ => loramac-node}/lorawan_emul.c (100%) rename subsys/lorawan/{ => loramac-node}/lw_priv.c (100%) rename subsys/lorawan/{ => loramac-node}/lw_priv.h (100%) diff --git a/subsys/lorawan/CMakeLists.txt b/subsys/lorawan/CMakeLists.txt index f57500154fe6..0ff86ca32ad1 100644 --- a/subsys/lorawan/CMakeLists.txt +++ b/subsys/lorawan/CMakeLists.txt @@ -1,34 +1,7 @@ # SPDX-License-Identifier: Apache-2.0 -# lorawan.c depends on the include directories exposed by the loramac-node -# library. Hence, if it exists then the source files are added to that otherwise -# a library with same name is created. -if(TARGET loramac-node) - set(ZEPHYR_CURRENT_LIBRARY loramac-node) -else() - zephyr_library_named(loramac-node) -endif() - -zephyr_compile_definitions_ifdef(CONFIG_LORAMAC_REGION_AS923 REGION_AS923) -zephyr_compile_definitions_ifdef(CONFIG_LORAMAC_REGION_AU915 REGION_AU915) -zephyr_compile_definitions_ifdef(CONFIG_LORAMAC_REGION_CN470 REGION_CN470) -zephyr_compile_definitions_ifdef(CONFIG_LORAMAC_REGION_CN779 REGION_CN779) -zephyr_compile_definitions_ifdef(CONFIG_LORAMAC_REGION_EU433 REGION_EU433) -zephyr_compile_definitions_ifdef(CONFIG_LORAMAC_REGION_EU868 REGION_EU868) -zephyr_compile_definitions_ifdef(CONFIG_LORAMAC_REGION_KR920 REGION_KR920) -zephyr_compile_definitions_ifdef(CONFIG_LORAMAC_REGION_IN865 REGION_IN865) -zephyr_compile_definitions_ifdef(CONFIG_LORAMAC_REGION_US915 REGION_US915) -zephyr_compile_definitions_ifdef(CONFIG_LORAMAC_REGION_RU864 REGION_RU864) - if(CONFIG_LORAWAN) - if(CONFIG_LORAWAN_EMUL) - zephyr_library_sources(lorawan_emul.c) - else() - zephyr_library_sources(lorawan.c) - endif() - - zephyr_library_sources(lw_priv.c) + add_subdirectory_ifdef(CONFIG_LORA_MODULE_BACKEND_LORAMAC_NODE loramac-node) + add_subdirectory(services) + add_subdirectory(nvm) endif() - -add_subdirectory(services) -add_subdirectory(nvm) diff --git a/subsys/lorawan/Kconfig b/subsys/lorawan/Kconfig index 6bdd144b4b06..5c236bc289d4 100644 --- a/subsys/lorawan/Kconfig +++ b/subsys/lorawan/Kconfig @@ -1,5 +1,5 @@ # LoRaWAN configuration options - +# # Copyright (c) 2020 Manivannan Sadhasivam # SPDX-License-Identifier: Apache-2.0 @@ -7,8 +7,6 @@ menuconfig LORAWAN bool "LoRaWAN support [EXPERIMENTAL]" depends on LORA select REQUIRES_FULL_LIBC - select HAS_SEMTECH_LORAMAC - imply HAS_SEMTECH_SOFT_SE select EXPERIMENTAL help This option enables LoRaWAN support. @@ -19,59 +17,7 @@ module = LORAWAN module-str = lorawan source "subsys/logging/Kconfig.template.log_config" -config LORAWAN_EMUL - bool "LoRaWAN Emulator" - help - The emulator can be used for unit testing of LoRaWAN services. - It provides interfaces to send arbitrary messages to the LoRaWAN - stack and receive the response through callbacks without using - actual LoRa hardware. - - See include/zephyr/lorawan/emul.h for the emulator API. - -config LORAWAN_SYSTEM_MAX_RX_ERROR - int "LoRaWAN System Max Rx Error" - default 20 - help - System Max Rx timing error value in ms to be used by LoRaWAN stack - for calculating the RX1/RX2 window timing. - -config LORAWAN_PUBLIC_NETWORK - bool "LoRaWAN Public Network" - default y - help - Enable this option to use a public LoRaWAN network. - Disable for private LoRaWAN networks. - -config LORAMAC_REGION_AS923 - bool "Asia 923MHz Frequency band" - -config LORAMAC_REGION_AU915 - bool "Australia 915MHz Frequency band" - -config LORAMAC_REGION_CN470 - bool "China 470MHz Frequency band" - -config LORAMAC_REGION_CN779 - bool "China 779MHz Frequency band" - -config LORAMAC_REGION_EU433 - bool "Europe 433MHz Frequency band" - -config LORAMAC_REGION_EU868 - bool "Europe 868MHz Frequency band" - -config LORAMAC_REGION_KR920 - bool "South Korea 920MHz Frequency band" - -config LORAMAC_REGION_IN865 - bool "India 865MHz Frequency band" - -config LORAMAC_REGION_US915 - bool "North America 915MHz Frequency band" - -config LORAMAC_REGION_RU864 - bool "Russia 864MHz Frequency band" +rsource "loramac-node/Kconfig" rsource "nvm/Kconfig" diff --git a/subsys/lorawan/loramac-node/CMakeLists.txt b/subsys/lorawan/loramac-node/CMakeLists.txt new file mode 100644 index 000000000000..35b098cfafdd --- /dev/null +++ b/subsys/lorawan/loramac-node/CMakeLists.txt @@ -0,0 +1,32 @@ +# SPDX-License-Identifier: Apache-2.0 + +# The loramac-node backend implementation depends on the include directories +# exposed by the loramac-node library. Hence, if it exists then the source +# files are added to that otherwise a library with same name is created. +if(TARGET loramac-node) + set(ZEPHYR_CURRENT_LIBRARY loramac-node) +else() + zephyr_library_named(loramac-node) +endif() + +# Add include path for local headers (lw_priv.h) +zephyr_library_include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +zephyr_compile_definitions_ifdef(CONFIG_LORAMAC_REGION_AS923 REGION_AS923) +zephyr_compile_definitions_ifdef(CONFIG_LORAMAC_REGION_AU915 REGION_AU915) +zephyr_compile_definitions_ifdef(CONFIG_LORAMAC_REGION_CN470 REGION_CN470) +zephyr_compile_definitions_ifdef(CONFIG_LORAMAC_REGION_CN779 REGION_CN779) +zephyr_compile_definitions_ifdef(CONFIG_LORAMAC_REGION_EU433 REGION_EU433) +zephyr_compile_definitions_ifdef(CONFIG_LORAMAC_REGION_EU868 REGION_EU868) +zephyr_compile_definitions_ifdef(CONFIG_LORAMAC_REGION_KR920 REGION_KR920) +zephyr_compile_definitions_ifdef(CONFIG_LORAMAC_REGION_IN865 REGION_IN865) +zephyr_compile_definitions_ifdef(CONFIG_LORAMAC_REGION_US915 REGION_US915) +zephyr_compile_definitions_ifdef(CONFIG_LORAMAC_REGION_RU864 REGION_RU864) + +if(CONFIG_LORAWAN_EMUL) + zephyr_library_sources(lorawan_emul.c) +else() + zephyr_library_sources(lorawan.c) +endif() + +zephyr_library_sources(lw_priv.c) diff --git a/subsys/lorawan/loramac-node/Kconfig b/subsys/lorawan/loramac-node/Kconfig new file mode 100644 index 000000000000..3975c59b4ffc --- /dev/null +++ b/subsys/lorawan/loramac-node/Kconfig @@ -0,0 +1,70 @@ +# LoRaWAN loramac-node backend configuration +# +# Copyright (c) 2020 Manivannan Sadhasivam +# SPDX-License-Identifier: Apache-2.0 + +if LORA_MODULE_BACKEND_LORAMAC_NODE + +config LORAWAN_LORAMAC_NODE + bool + default y + select HAS_SEMTECH_LORAMAC + imply HAS_SEMTECH_SOFT_SE + help + Hidden config to enable loramac-node backend specific options. + +config LORAWAN_EMUL + bool "LoRaWAN Emulator" + help + The emulator can be used for unit testing of LoRaWAN services. + It provides interfaces to send arbitrary messages to the LoRaWAN + stack and receive the response through callbacks without using + actual LoRa hardware. + + See include/zephyr/lorawan/emul.h for the emulator API. + +config LORAWAN_SYSTEM_MAX_RX_ERROR + int "LoRaWAN System Max Rx Error" + default 20 + help + System Max Rx timing error value in ms to be used by LoRaWAN stack + for calculating the RX1/RX2 window timing. + +config LORAWAN_PUBLIC_NETWORK + bool "LoRaWAN Public Network" + default y + help + Enable this option to use a public LoRaWAN network. + Disable for private LoRaWAN networks. + +config LORAMAC_REGION_AS923 + bool "Asia 923MHz Frequency band" + +config LORAMAC_REGION_AU915 + bool "Australia 915MHz Frequency band" + +config LORAMAC_REGION_CN470 + bool "China 470MHz Frequency band" + +config LORAMAC_REGION_CN779 + bool "China 779MHz Frequency band" + +config LORAMAC_REGION_EU433 + bool "Europe 433MHz Frequency band" + +config LORAMAC_REGION_EU868 + bool "Europe 868MHz Frequency band" + +config LORAMAC_REGION_KR920 + bool "South Korea 920MHz Frequency band" + +config LORAMAC_REGION_IN865 + bool "India 865MHz Frequency band" + +config LORAMAC_REGION_US915 + bool "North America 915MHz Frequency band" + +config LORAMAC_REGION_RU864 + bool "Russia 864MHz Frequency band" + +endif # LORA_MODULE_BACKEND_LORAMAC_NODE diff --git a/subsys/lorawan/lorawan.c b/subsys/lorawan/loramac-node/lorawan.c similarity index 99% rename from subsys/lorawan/lorawan.c rename to subsys/lorawan/loramac-node/lorawan.c index 5a55281d0862..a7c677001f6b 100644 --- a/subsys/lorawan/lorawan.c +++ b/subsys/lorawan/loramac-node/lorawan.c @@ -13,7 +13,7 @@ #include #include -#include "nvm/lorawan_nvm.h" +#include "../nvm/lorawan_nvm.h" #ifdef CONFIG_LORAMAC_REGION_AS923 #define DEFAULT_LORAWAN_REGION LORAMAC_REGION_AS923 diff --git a/subsys/lorawan/lorawan_emul.c b/subsys/lorawan/loramac-node/lorawan_emul.c similarity index 100% rename from subsys/lorawan/lorawan_emul.c rename to subsys/lorawan/loramac-node/lorawan_emul.c diff --git a/subsys/lorawan/lw_priv.c b/subsys/lorawan/loramac-node/lw_priv.c similarity index 100% rename from subsys/lorawan/lw_priv.c rename to subsys/lorawan/loramac-node/lw_priv.c diff --git a/subsys/lorawan/lw_priv.h b/subsys/lorawan/loramac-node/lw_priv.h similarity index 100% rename from subsys/lorawan/lw_priv.h rename to subsys/lorawan/loramac-node/lw_priv.h diff --git a/subsys/lorawan/nvm/CMakeLists.txt b/subsys/lorawan/nvm/CMakeLists.txt index 2b7b710690ee..d5c3afddab6c 100644 --- a/subsys/lorawan/nvm/CMakeLists.txt +++ b/subsys/lorawan/nvm/CMakeLists.txt @@ -1,3 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 +# The settings-based NVM implementation is loramac-node specific +set(ZEPHYR_CURRENT_LIBRARY loramac-node) zephyr_library_sources_ifdef(CONFIG_LORAWAN_NVM_SETTINGS lorawan_nvm_settings.c) diff --git a/subsys/lorawan/nvm/Kconfig b/subsys/lorawan/nvm/Kconfig index da847d829f3a..963e2d67b95e 100644 --- a/subsys/lorawan/nvm/Kconfig +++ b/subsys/lorawan/nvm/Kconfig @@ -19,5 +19,7 @@ config LORAWAN_NVM_NONE config LORAWAN_NVM_SETTINGS bool "Settings based NVM" depends on SETTINGS + # The settings-based NVM implementation currently only supports loramac-node + depends on LORA_MODULE_BACKEND_LORAMAC_NODE endchoice diff --git a/subsys/lorawan/services/CMakeLists.txt b/subsys/lorawan/services/CMakeLists.txt index 258cdd51d50b..db7fdcf974ad 100644 --- a/subsys/lorawan/services/CMakeLists.txt +++ b/subsys/lorawan/services/CMakeLists.txt @@ -2,6 +2,8 @@ if(CONFIG_LORAWAN_SERVICES) + zephyr_library() + zephyr_library_sources(lorawan_services.c) zephyr_library_sources_ifdef( @@ -17,12 +19,17 @@ if(CONFIG_LORAWAN_SERVICES) zephyr_library_sources_ifdef( CONFIG_LORAWAN_FRAG_TRANSPORT_DECODER_LOWMEM - frag_decoder_lowmem.c + frag_decoder_lowmem.c ) - zephyr_library_sources_ifdef( - CONFIG_LORAWAN_REMOTE_MULTICAST - multicast.c - ) + if(CONFIG_LORAWAN_FRAG_TRANSPORT_DECODER_SEMTECH) + zephyr_library_include_directories( + ${ZEPHYR_LORAMAC_NODE_MODULE_DIR}/src/apps/LoRaMac/common/LmHandler/packages + ) + endif() endif() + +# The multicast service is loramac-node specific +set(ZEPHYR_CURRENT_LIBRARY loramac-node) +zephyr_library_sources_ifdef(CONFIG_LORAWAN_REMOTE_MULTICAST multicast.c) diff --git a/subsys/lorawan/services/Kconfig b/subsys/lorawan/services/Kconfig index e4f5e9ca9a6f..3401f83b5654 100644 --- a/subsys/lorawan/services/Kconfig +++ b/subsys/lorawan/services/Kconfig @@ -68,10 +68,12 @@ config LORAWAN_FRAG_TRANSPORT choice LORAWAN_FRAG_TRANSPORT_DECODER bool "Fragmented Data Block Transport decoder implementation" depends on LORAWAN_FRAG_TRANSPORT - default LORAWAN_FRAG_TRANSPORT_DECODER_SEMTECH + default LORAWAN_FRAG_TRANSPORT_DECODER_SEMTECH if LORA_MODULE_BACKEND_LORAMAC_NODE + default LORAWAN_FRAG_TRANSPORT_DECODER_LOWMEM config LORAWAN_FRAG_TRANSPORT_DECODER_SEMTECH bool "Semtech" + depends on LORA_MODULE_BACKEND_LORAMAC_NODE help The default decoder implementation from LoRaMAC-node. @@ -159,6 +161,8 @@ config LORAWAN_REMOTE_MULTICAST bool "Remote Multicast Setup" depends on LORAWAN_APP_CLOCK_SYNC depends on !LORAWAN_NVM_NONE + # The multicast service implementation currently only supports loramac-node + depends on LORA_MODULE_BACKEND_LORAMAC_NODE help Enables the LoRaWAN Remote Multicast Setup service according to TS005-1.0.0 as published by the LoRa Alliance. diff --git a/subsys/lorawan/services/clock_sync.c b/subsys/lorawan/services/clock_sync.c index 7334641e0af1..bf77a7b2532c 100644 --- a/subsys/lorawan/services/clock_sync.c +++ b/subsys/lorawan/services/clock_sync.c @@ -11,7 +11,6 @@ #include "lorawan_services.h" -#include #include #include #include diff --git a/subsys/lorawan/services/frag_decoder_lowmem.h b/subsys/lorawan/services/frag_decoder_lowmem.h index 4fc6159a1b7f..42feca7a67a0 100644 --- a/subsys/lorawan/services/frag_decoder_lowmem.h +++ b/subsys/lorawan/services/frag_decoder_lowmem.h @@ -18,8 +18,9 @@ #define FRAG_MAX_NB \ (CONFIG_LORAWAN_FRAG_TRANSPORT_IMAGE_SIZE / CONFIG_LORAWAN_FRAG_TRANSPORT_MIN_FRAG_SIZE + \ 1U) -#define FRAG_MAX_SIZE (CONFIG_LORAWAN_FRAG_TRANSPORT_MAX_FRAG_SIZE) -#define FRAG_TOLERANCE (FRAG_MAX_NB * CONFIG_LORAWAN_FRAG_TRANSPORT_MAX_REDUNDANCY / 100U) +#define FRAG_MAX_SIZE (CONFIG_LORAWAN_FRAG_TRANSPORT_MAX_FRAG_SIZE) +#define FRAG_MAX_REDUNDANCY (FRAG_MAX_NB * CONFIG_LORAWAN_FRAG_TRANSPORT_MAX_REDUNDANCY / 100U) +#define FRAG_TOLERANCE FRAG_MAX_REDUNDANCY #define FRAG_DEC_ONGOING (-1) #define FRAG_DEC_ERR_INVALID_FRAME (-2) diff --git a/subsys/lorawan/services/frag_flash.c b/subsys/lorawan/services/frag_flash.c index 2d5db55a7a8b..71ea4adb9052 100644 --- a/subsys/lorawan/services/frag_flash.c +++ b/subsys/lorawan/services/frag_flash.c @@ -6,8 +6,7 @@ */ #include "frag_flash.h" - -#include +#include "frag_decoder_lowmem.h" #include #include diff --git a/subsys/lorawan/services/frag_transport.c b/subsys/lorawan/services/frag_transport.c index 2ee4c86e40f4..2bda3dc761db 100644 --- a/subsys/lorawan/services/frag_transport.c +++ b/subsys/lorawan/services/frag_transport.c @@ -12,7 +12,6 @@ #include "frag_flash.h" #include "lorawan_services.h" -#include #ifdef CONFIG_LORAWAN_FRAG_TRANSPORT_DECODER_SEMTECH #include #elif defined(CONFIG_LORAWAN_FRAG_TRANSPORT_DECODER_LOWMEM) diff --git a/subsys/lorawan/services/multicast.c b/subsys/lorawan/services/multicast.c index 72f2de0497ea..26e66a1045f1 100644 --- a/subsys/lorawan/services/multicast.c +++ b/subsys/lorawan/services/multicast.c @@ -6,7 +6,7 @@ */ #include "lorawan_services.h" -#include "../lw_priv.h" +#include #include #include From 0a45c8dc7075ad10f97f7e9615df5610af757912 Mon Sep 17 00:00:00 2001 From: Carlo Caione Date: Thu, 8 Jan 2026 09:19:31 +0100 Subject: [PATCH 1874/3659] lorawan: make NVM header documentation backend-agnostic Remove loramac-node specific references (LORAMAC_NVM_NOTIFY_FLAG_*) from the NVM interface documentation, making it suitable for any LoRaWAN backend implementation. Signed-off-by: Carlo Caione --- subsys/lorawan/nvm/lorawan_nvm.h | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/subsys/lorawan/nvm/lorawan_nvm.h b/subsys/lorawan/nvm/lorawan_nvm.h index 92c34d697750..4161d9ad7892 100644 --- a/subsys/lorawan/nvm/lorawan_nvm.h +++ b/subsys/lorawan/nvm/lorawan_nvm.h @@ -10,21 +10,13 @@ #include /** - * @brief Hook function called when an interrupt related to NVM - * is received from the LoRaWAN stack. + * @brief Hook function called when an NVM update event is received from + * the LoRaWAN stack. * - * @note This function should not be called directly by the application + * @note This function should not be called directly by the application. * - * @param flags OR'ed flags received with the interrupt - * - * @see LORAMAC_NVM_NOTIFY_FLAG_NONE - * @see LORAMAC_NVM_NOTIFY_FLAG_CRYPTO - * @see LORAMAC_NVM_NOTIFY_FLAG_MAC_GROUP1 - * @see LORAMAC_NVM_NOTIFY_FLAG_MAC_GROUP2 - * @see LORAMAC_NVM_NOTIFY_FLAG_SECURE_ELEMENT - * @see LORAMAC_NVM_NOTIFY_FLAG_REGION_GROUP1 - * @see LORAMAC_NVM_NOTIFY_FLAG_REGION_GROUP2 - * @see LORAMAC_NVM_NOTIFY_FLAG_CLASS_B + * @param flags OR'ed flags indicating which data sections need to be stored. + * The flag values are backend-specific. */ void lorawan_nvm_data_mgmt_event(uint16_t flags); From 5eab8eb69301f8b437ce639539f2e0f8e1e59917 Mon Sep 17 00:00:00 2001 From: Carlo Caione Date: Fri, 9 Jan 2026 14:17:53 +0100 Subject: [PATCH 1875/3659] lorawan: move emulator to separate backend directory Move the LoRaWAN emulator from the loramac-node backend directory to its own directory because the emulator currently still depends on loramac-node for some types and functions. Once these dependencies are removed in a follow-up, the emulator can become a fully standalone backend. Signed-off-by: Carlo Caione --- subsys/lorawan/CMakeLists.txt | 1 + subsys/lorawan/Kconfig | 2 ++ subsys/lorawan/emul/CMakeLists.txt | 6 ++++++ subsys/lorawan/emul/Kconfig | 18 ++++++++++++++++++ .../{loramac-node => emul}/lorawan_emul.c | 0 subsys/lorawan/loramac-node/CMakeLists.txt | 5 ++--- subsys/lorawan/loramac-node/Kconfig | 10 ---------- 7 files changed, 29 insertions(+), 13 deletions(-) create mode 100644 subsys/lorawan/emul/CMakeLists.txt create mode 100644 subsys/lorawan/emul/Kconfig rename subsys/lorawan/{loramac-node => emul}/lorawan_emul.c (100%) diff --git a/subsys/lorawan/CMakeLists.txt b/subsys/lorawan/CMakeLists.txt index 0ff86ca32ad1..5ac754d5689b 100644 --- a/subsys/lorawan/CMakeLists.txt +++ b/subsys/lorawan/CMakeLists.txt @@ -2,6 +2,7 @@ if(CONFIG_LORAWAN) add_subdirectory_ifdef(CONFIG_LORA_MODULE_BACKEND_LORAMAC_NODE loramac-node) + add_subdirectory(emul) add_subdirectory(services) add_subdirectory(nvm) endif() diff --git a/subsys/lorawan/Kconfig b/subsys/lorawan/Kconfig index 5c236bc289d4..4bea9700b5d4 100644 --- a/subsys/lorawan/Kconfig +++ b/subsys/lorawan/Kconfig @@ -19,6 +19,8 @@ source "subsys/logging/Kconfig.template.log_config" rsource "loramac-node/Kconfig" +rsource "emul/Kconfig" + rsource "nvm/Kconfig" rsource "services/Kconfig" diff --git a/subsys/lorawan/emul/CMakeLists.txt b/subsys/lorawan/emul/CMakeLists.txt new file mode 100644 index 000000000000..28e5ee06e1fa --- /dev/null +++ b/subsys/lorawan/emul/CMakeLists.txt @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: Apache-2.0 + +# The emulator currently depends on loramac-node for some types and functions. +# Once these dependencies are removed, it can become a fully standalone backend. +set(ZEPHYR_CURRENT_LIBRARY loramac-node) +zephyr_library_sources_ifdef(CONFIG_LORAWAN_EMUL lorawan_emul.c) diff --git a/subsys/lorawan/emul/Kconfig b/subsys/lorawan/emul/Kconfig new file mode 100644 index 000000000000..f85b7cdbeeb7 --- /dev/null +++ b/subsys/lorawan/emul/Kconfig @@ -0,0 +1,18 @@ +# LoRaWAN emulator configuration +# +# Copyright (c) 2024 A Labs GmbH +# Copyright (c) 2024 tado GmbH +# SPDX-License-Identifier: Apache-2.0 + +config LORAWAN_EMUL + bool "LoRaWAN Emulator" + # The emulator currently depends on loramac-node for some types and + # functions. Once these dependencies are removed, this can be changed. + depends on LORA_MODULE_BACKEND_LORAMAC_NODE + help + The emulator can be used for unit testing of LoRaWAN services. + It provides interfaces to send arbitrary messages to the LoRaWAN + stack and receive the response through callbacks without using + actual LoRa hardware. + + See include/zephyr/lorawan/emul.h for the emulator API. diff --git a/subsys/lorawan/loramac-node/lorawan_emul.c b/subsys/lorawan/emul/lorawan_emul.c similarity index 100% rename from subsys/lorawan/loramac-node/lorawan_emul.c rename to subsys/lorawan/emul/lorawan_emul.c diff --git a/subsys/lorawan/loramac-node/CMakeLists.txt b/subsys/lorawan/loramac-node/CMakeLists.txt index 35b098cfafdd..a10d8e7a1f24 100644 --- a/subsys/lorawan/loramac-node/CMakeLists.txt +++ b/subsys/lorawan/loramac-node/CMakeLists.txt @@ -23,9 +23,8 @@ zephyr_compile_definitions_ifdef(CONFIG_LORAMAC_REGION_IN865 REGION_IN865) zephyr_compile_definitions_ifdef(CONFIG_LORAMAC_REGION_US915 REGION_US915) zephyr_compile_definitions_ifdef(CONFIG_LORAMAC_REGION_RU864 REGION_RU864) -if(CONFIG_LORAWAN_EMUL) - zephyr_library_sources(lorawan_emul.c) -else() +# Don't build the real implementation when the emulator is used +if(NOT CONFIG_LORAWAN_EMUL) zephyr_library_sources(lorawan.c) endif() diff --git a/subsys/lorawan/loramac-node/Kconfig b/subsys/lorawan/loramac-node/Kconfig index 3975c59b4ffc..2abbf002a044 100644 --- a/subsys/lorawan/loramac-node/Kconfig +++ b/subsys/lorawan/loramac-node/Kconfig @@ -13,16 +13,6 @@ config LORAWAN_LORAMAC_NODE help Hidden config to enable loramac-node backend specific options. -config LORAWAN_EMUL - bool "LoRaWAN Emulator" - help - The emulator can be used for unit testing of LoRaWAN services. - It provides interfaces to send arbitrary messages to the LoRaWAN - stack and receive the response through callbacks without using - actual LoRa hardware. - - See include/zephyr/lorawan/emul.h for the emulator API. - config LORAWAN_SYSTEM_MAX_RX_ERROR int "LoRaWAN System Max Rx Error" default 20 From d6dce1ca51d4de61f3b0e09548b04396cee9928a Mon Sep 17 00:00:00 2001 From: Carlo Caione Date: Sat, 10 Jan 2026 16:48:25 +0100 Subject: [PATCH 1876/3659] lorawan: rename region Kconfig symbols to be backend-agnostic Move and rename the region Kconfig symbols from LORAMAC_REGION_* to LORAWAN_REGION_* to make them backend-agnostic. Signed-off-by: Carlo Caione --- doc/connectivity/lora_lorawan/index.rst | 20 +++++----- doc/releases/migration-guide-4.4.rst | 18 +++++++++ modules/loramac-node/CMakeLists.txt | 20 +++++----- samples/subsys/lorawan/class_a/prj.conf | 2 +- samples/subsys/lorawan/class_a/sample.yaml | 24 +++++------ samples/subsys/lorawan/class_a/src/main.c | 2 +- samples/subsys/lorawan/fuota/prj.conf | 2 +- subsys/lorawan/Kconfig | 34 ++++++++++++++++ subsys/lorawan/loramac-node/CMakeLists.txt | 20 +++++----- subsys/lorawan/loramac-node/Kconfig | 30 -------------- subsys/lorawan/loramac-node/lorawan.c | 40 +++++++++---------- tests/subsys/lorawan/channels_mask/prj.conf | 4 +- tests/subsys/lorawan/clock_sync/prj.conf | 2 +- tests/subsys/lorawan/frag_decoder/prj.conf | 2 +- .../mgmt/mcumgr/transport_lorawan/prj.conf | 2 +- 15 files changed, 122 insertions(+), 100 deletions(-) diff --git a/doc/connectivity/lora_lorawan/index.rst b/doc/connectivity/lora_lorawan/index.rst index 0e67334425f7..e5e10c07ae69 100644 --- a/doc/connectivity/lora_lorawan/index.rst +++ b/doc/connectivity/lora_lorawan/index.rst @@ -69,25 +69,25 @@ Related configuration options can be found under * :kconfig:option:`CONFIG_LORAWAN_SYSTEM_MAX_RX_ERROR` -* :kconfig:option:`CONFIG_LORAMAC_REGION_AS923` +* :kconfig:option:`CONFIG_LORAWAN_REGION_AS923` -* :kconfig:option:`CONFIG_LORAMAC_REGION_AU915` +* :kconfig:option:`CONFIG_LORAWAN_REGION_AU915` -* :kconfig:option:`CONFIG_LORAMAC_REGION_CN470` +* :kconfig:option:`CONFIG_LORAWAN_REGION_CN470` -* :kconfig:option:`CONFIG_LORAMAC_REGION_CN779` +* :kconfig:option:`CONFIG_LORAWAN_REGION_CN779` -* :kconfig:option:`CONFIG_LORAMAC_REGION_EU433` +* :kconfig:option:`CONFIG_LORAWAN_REGION_EU433` -* :kconfig:option:`CONFIG_LORAMAC_REGION_EU868` +* :kconfig:option:`CONFIG_LORAWAN_REGION_EU868` -* :kconfig:option:`CONFIG_LORAMAC_REGION_KR920` +* :kconfig:option:`CONFIG_LORAWAN_REGION_KR920` -* :kconfig:option:`CONFIG_LORAMAC_REGION_IN865` +* :kconfig:option:`CONFIG_LORAWAN_REGION_IN865` -* :kconfig:option:`CONFIG_LORAMAC_REGION_US915` +* :kconfig:option:`CONFIG_LORAWAN_REGION_US915` -* :kconfig:option:`CONFIG_LORAMAC_REGION_RU864` +* :kconfig:option:`CONFIG_LORAWAN_REGION_RU864` API Reference ************* diff --git a/doc/releases/migration-guide-4.4.rst b/doc/releases/migration-guide-4.4.rst index ba954b018f5a..11fab4cdc2f6 100644 --- a/doc/releases/migration-guide-4.4.rst +++ b/doc/releases/migration-guide-4.4.rst @@ -615,6 +615,24 @@ Modem HL78XX Applications depending on the previous defaults must update their configuration. +LoRaWAN +******* + +* The LoRaWAN region Kconfig symbols have been renamed from ``LORAMAC_REGION_*`` to + ``LORAWAN_REGION_*`` to make them backend-agnostic. Applications using any of the following + symbols must update their configuration files: + + * ``CONFIG_LORAMAC_REGION_AS923`` → :kconfig:option:`CONFIG_LORAWAN_REGION_AS923` + * ``CONFIG_LORAMAC_REGION_AU915`` → :kconfig:option:`CONFIG_LORAWAN_REGION_AU915` + * ``CONFIG_LORAMAC_REGION_CN470`` → :kconfig:option:`CONFIG_LORAWAN_REGION_CN470` + * ``CONFIG_LORAMAC_REGION_CN779`` → :kconfig:option:`CONFIG_LORAWAN_REGION_CN779` + * ``CONFIG_LORAMAC_REGION_EU433`` → :kconfig:option:`CONFIG_LORAWAN_REGION_EU433` + * ``CONFIG_LORAMAC_REGION_EU868`` → :kconfig:option:`CONFIG_LORAWAN_REGION_EU868` + * ``CONFIG_LORAMAC_REGION_KR920`` → :kconfig:option:`CONFIG_LORAWAN_REGION_KR920` + * ``CONFIG_LORAMAC_REGION_IN865`` → :kconfig:option:`CONFIG_LORAWAN_REGION_IN865` + * ``CONFIG_LORAMAC_REGION_US915`` → :kconfig:option:`CONFIG_LORAWAN_REGION_US915` + * ``CONFIG_LORAMAC_REGION_RU864`` → :kconfig:option:`CONFIG_LORAWAN_REGION_RU864` + Other subsystems **************** * The DAP subsystem initialization and configuration has changed. Please take a look at diff --git a/modules/loramac-node/CMakeLists.txt b/modules/loramac-node/CMakeLists.txt index a711ab3e5fe9..415c7facd247 100644 --- a/modules/loramac-node/CMakeLists.txt +++ b/modules/loramac-node/CMakeLists.txt @@ -63,27 +63,27 @@ zephyr_library_sources_ifdef(CONFIG_HAS_SEMTECH_LORAMAC ${ZEPHYR_LORAMAC_NODE_MODULE_DIR}/src/mac/region/Region.c ${ZEPHYR_LORAMAC_NODE_MODULE_DIR}/src/mac/region/RegionCommon.c ) -zephyr_library_sources_ifdef(CONFIG_LORAMAC_REGION_EU868 +zephyr_library_sources_ifdef(CONFIG_LORAWAN_REGION_EU868 ${ZEPHYR_LORAMAC_NODE_MODULE_DIR}/src/mac/region/RegionEU868.c ) -zephyr_library_sources_ifdef(CONFIG_LORAMAC_REGION_US915 +zephyr_library_sources_ifdef(CONFIG_LORAWAN_REGION_US915 ${ZEPHYR_LORAMAC_NODE_MODULE_DIR}/src/mac/region/RegionBaseUS.c ${ZEPHYR_LORAMAC_NODE_MODULE_DIR}/src/mac/region/RegionUS915.c ) -zephyr_library_sources_ifdef(CONFIG_LORAMAC_REGION_CN779 +zephyr_library_sources_ifdef(CONFIG_LORAWAN_REGION_CN779 ${ZEPHYR_LORAMAC_NODE_MODULE_DIR}/src/mac/region/RegionCN779.c ) -zephyr_library_sources_ifdef(CONFIG_LORAMAC_REGION_EU433 +zephyr_library_sources_ifdef(CONFIG_LORAWAN_REGION_EU433 ${ZEPHYR_LORAMAC_NODE_MODULE_DIR}/src/mac/region/RegionEU433.c ) -zephyr_library_sources_ifdef(CONFIG_LORAMAC_REGION_AU915 +zephyr_library_sources_ifdef(CONFIG_LORAWAN_REGION_AU915 ${ZEPHYR_LORAMAC_NODE_MODULE_DIR}/src/mac/region/RegionBaseUS.c ${ZEPHYR_LORAMAC_NODE_MODULE_DIR}/src/mac/region/RegionAU915.c ) -zephyr_library_sources_ifdef(CONFIG_LORAMAC_REGION_AS923 +zephyr_library_sources_ifdef(CONFIG_LORAWAN_REGION_AS923 ${ZEPHYR_LORAMAC_NODE_MODULE_DIR}/src/mac/region/RegionAS923.c ) -zephyr_library_sources_ifdef(CONFIG_LORAMAC_REGION_CN470 +zephyr_library_sources_ifdef(CONFIG_LORAWAN_REGION_CN470 ${ZEPHYR_LORAMAC_NODE_MODULE_DIR}/src/mac/region/RegionBaseUS.c ${ZEPHYR_LORAMAC_NODE_MODULE_DIR}/src/mac/region/RegionCN470.c ${ZEPHYR_LORAMAC_NODE_MODULE_DIR}/src/mac/region/RegionCN470A20.c @@ -91,13 +91,13 @@ zephyr_library_sources_ifdef(CONFIG_LORAMAC_REGION_CN470 ${ZEPHYR_LORAMAC_NODE_MODULE_DIR}/src/mac/region/RegionCN470B20.c ${ZEPHYR_LORAMAC_NODE_MODULE_DIR}/src/mac/region/RegionCN470B26.c ) -zephyr_library_sources_ifdef(CONFIG_LORAMAC_REGION_KR920 +zephyr_library_sources_ifdef(CONFIG_LORAWAN_REGION_KR920 ${ZEPHYR_LORAMAC_NODE_MODULE_DIR}/src/mac/region/RegionKR920.c ) -zephyr_library_sources_ifdef(CONFIG_LORAMAC_REGION_IN865 +zephyr_library_sources_ifdef(CONFIG_LORAWAN_REGION_IN865 ${ZEPHYR_LORAMAC_NODE_MODULE_DIR}/src/mac/region/RegionIN865.c ) -zephyr_library_sources_ifdef(CONFIG_LORAMAC_REGION_RU864 +zephyr_library_sources_ifdef(CONFIG_LORAWAN_REGION_RU864 ${ZEPHYR_LORAMAC_NODE_MODULE_DIR}/src/mac/region/RegionRU864.c ) diff --git a/samples/subsys/lorawan/class_a/prj.conf b/samples/subsys/lorawan/class_a/prj.conf index 5421cfcc83cd..38325c0d9632 100644 --- a/samples/subsys/lorawan/class_a/prj.conf +++ b/samples/subsys/lorawan/class_a/prj.conf @@ -1,6 +1,6 @@ CONFIG_LOG=y CONFIG_LORA=y CONFIG_LORAWAN=y -CONFIG_LORAMAC_REGION_IN865=y +CONFIG_LORAWAN_REGION_IN865=y CONFIG_MAIN_STACK_SIZE=2048 CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048 diff --git a/samples/subsys/lorawan/class_a/sample.yaml b/samples/subsys/lorawan/class_a/sample.yaml index c617ec5feb44..0dc967e073ec 100644 --- a/samples/subsys/lorawan/class_a/sample.yaml +++ b/samples/subsys/lorawan/class_a/sample.yaml @@ -12,35 +12,35 @@ sample: tests: sample.lorawan.class_a.as923: extra_configs: - - CONFIG_LORAMAC_REGION_AS923=y + - CONFIG_LORAWAN_REGION_AS923=y sample.lorawan.class_a.au915: extra_configs: - - CONFIG_LORAMAC_REGION_AU915=y + - CONFIG_LORAWAN_REGION_AU915=y sample.lorawan.class_a.cn470: extra_configs: - - CONFIG_LORAMAC_REGION_CN470=y + - CONFIG_LORAWAN_REGION_CN470=y sample.lorawan.class_a.cn779: extra_configs: - - CONFIG_LORAMAC_REGION_CN779=y + - CONFIG_LORAWAN_REGION_CN779=y sample.lorawan.class_a.eu433: extra_configs: - - CONFIG_LORAMAC_REGION_EU433=y + - CONFIG_LORAWAN_REGION_EU433=y sample.lorawan.class_a.eu868: extra_configs: - - CONFIG_LORAMAC_REGION_EU868=y + - CONFIG_LORAWAN_REGION_EU868=y sample.lorawan.class_a.kr920: extra_configs: - - CONFIG_LORAMAC_REGION_KR920=y + - CONFIG_LORAWAN_REGION_KR920=y sample.lorawan.class_a.in865: extra_configs: - - CONFIG_LORAMAC_REGION_IN865=y + - CONFIG_LORAWAN_REGION_IN865=y sample.lorawan.class_a.us915: extra_configs: - - CONFIG_LORAMAC_REGION_US915=y + - CONFIG_LORAWAN_REGION_US915=y sample.lorawan.class_a.ru864: extra_configs: - - CONFIG_LORAMAC_REGION_RU864=y + - CONFIG_LORAWAN_REGION_RU864=y sample.lorawan.class_a.multiregion: extra_configs: - - CONFIG_LORAMAC_REGION_EU868=y - - CONFIG_LORAMAC_REGION_US915=y + - CONFIG_LORAWAN_REGION_EU868=y + - CONFIG_LORAWAN_REGION_US915=y diff --git a/samples/subsys/lorawan/class_a/src/main.c b/samples/subsys/lorawan/class_a/src/main.c index ee48cee6a115..5282fa0055ef 100644 --- a/samples/subsys/lorawan/class_a/src/main.c +++ b/samples/subsys/lorawan/class_a/src/main.c @@ -65,7 +65,7 @@ int main(void) return 0; } -#if defined(CONFIG_LORAMAC_REGION_EU868) +#if defined(CONFIG_LORAWAN_REGION_EU868) /* If more than one region Kconfig is selected, app should set region * before calling lorawan_start() */ diff --git a/samples/subsys/lorawan/fuota/prj.conf b/samples/subsys/lorawan/fuota/prj.conf index 4e606e18b98b..9ebdf9dcfae9 100644 --- a/samples/subsys/lorawan/fuota/prj.conf +++ b/samples/subsys/lorawan/fuota/prj.conf @@ -16,7 +16,7 @@ CONFIG_ENTROPY_GENERATOR=y # LoRaWAN application layer CONFIG_LORAWAN=y -CONFIG_LORAMAC_REGION_EU868=y +CONFIG_LORAWAN_REGION_EU868=y CONFIG_LORAWAN_NVM_SETTINGS=y # LoRaWAN services required for FUOTA diff --git a/subsys/lorawan/Kconfig b/subsys/lorawan/Kconfig index 4bea9700b5d4..a994cc514571 100644 --- a/subsys/lorawan/Kconfig +++ b/subsys/lorawan/Kconfig @@ -17,6 +17,40 @@ module = LORAWAN module-str = lorawan source "subsys/logging/Kconfig.template.log_config" +menu "LoRaWAN Regions" + +config LORAWAN_REGION_AS923 + bool "Asia 923MHz Frequency band" + +config LORAWAN_REGION_AU915 + bool "Australia 915MHz Frequency band" + +config LORAWAN_REGION_CN470 + bool "China 470MHz Frequency band" + +config LORAWAN_REGION_CN779 + bool "China 779MHz Frequency band" + +config LORAWAN_REGION_EU433 + bool "Europe 433MHz Frequency band" + +config LORAWAN_REGION_EU868 + bool "Europe 868MHz Frequency band" + +config LORAWAN_REGION_KR920 + bool "South Korea 920MHz Frequency band" + +config LORAWAN_REGION_IN865 + bool "India 865MHz Frequency band" + +config LORAWAN_REGION_US915 + bool "North America 915MHz Frequency band" + +config LORAWAN_REGION_RU864 + bool "Russia 864MHz Frequency band" + +endmenu + rsource "loramac-node/Kconfig" rsource "emul/Kconfig" diff --git a/subsys/lorawan/loramac-node/CMakeLists.txt b/subsys/lorawan/loramac-node/CMakeLists.txt index a10d8e7a1f24..ef47e0e2393c 100644 --- a/subsys/lorawan/loramac-node/CMakeLists.txt +++ b/subsys/lorawan/loramac-node/CMakeLists.txt @@ -12,16 +12,16 @@ endif() # Add include path for local headers (lw_priv.h) zephyr_library_include_directories(${CMAKE_CURRENT_SOURCE_DIR}) -zephyr_compile_definitions_ifdef(CONFIG_LORAMAC_REGION_AS923 REGION_AS923) -zephyr_compile_definitions_ifdef(CONFIG_LORAMAC_REGION_AU915 REGION_AU915) -zephyr_compile_definitions_ifdef(CONFIG_LORAMAC_REGION_CN470 REGION_CN470) -zephyr_compile_definitions_ifdef(CONFIG_LORAMAC_REGION_CN779 REGION_CN779) -zephyr_compile_definitions_ifdef(CONFIG_LORAMAC_REGION_EU433 REGION_EU433) -zephyr_compile_definitions_ifdef(CONFIG_LORAMAC_REGION_EU868 REGION_EU868) -zephyr_compile_definitions_ifdef(CONFIG_LORAMAC_REGION_KR920 REGION_KR920) -zephyr_compile_definitions_ifdef(CONFIG_LORAMAC_REGION_IN865 REGION_IN865) -zephyr_compile_definitions_ifdef(CONFIG_LORAMAC_REGION_US915 REGION_US915) -zephyr_compile_definitions_ifdef(CONFIG_LORAMAC_REGION_RU864 REGION_RU864) +zephyr_compile_definitions_ifdef(CONFIG_LORAWAN_REGION_AS923 REGION_AS923) +zephyr_compile_definitions_ifdef(CONFIG_LORAWAN_REGION_AU915 REGION_AU915) +zephyr_compile_definitions_ifdef(CONFIG_LORAWAN_REGION_CN470 REGION_CN470) +zephyr_compile_definitions_ifdef(CONFIG_LORAWAN_REGION_CN779 REGION_CN779) +zephyr_compile_definitions_ifdef(CONFIG_LORAWAN_REGION_EU433 REGION_EU433) +zephyr_compile_definitions_ifdef(CONFIG_LORAWAN_REGION_EU868 REGION_EU868) +zephyr_compile_definitions_ifdef(CONFIG_LORAWAN_REGION_KR920 REGION_KR920) +zephyr_compile_definitions_ifdef(CONFIG_LORAWAN_REGION_IN865 REGION_IN865) +zephyr_compile_definitions_ifdef(CONFIG_LORAWAN_REGION_US915 REGION_US915) +zephyr_compile_definitions_ifdef(CONFIG_LORAWAN_REGION_RU864 REGION_RU864) # Don't build the real implementation when the emulator is used if(NOT CONFIG_LORAWAN_EMUL) diff --git a/subsys/lorawan/loramac-node/Kconfig b/subsys/lorawan/loramac-node/Kconfig index 2abbf002a044..97184d8a02d6 100644 --- a/subsys/lorawan/loramac-node/Kconfig +++ b/subsys/lorawan/loramac-node/Kconfig @@ -27,34 +27,4 @@ config LORAWAN_PUBLIC_NETWORK Enable this option to use a public LoRaWAN network. Disable for private LoRaWAN networks. -config LORAMAC_REGION_AS923 - bool "Asia 923MHz Frequency band" - -config LORAMAC_REGION_AU915 - bool "Australia 915MHz Frequency band" - -config LORAMAC_REGION_CN470 - bool "China 470MHz Frequency band" - -config LORAMAC_REGION_CN779 - bool "China 779MHz Frequency band" - -config LORAMAC_REGION_EU433 - bool "Europe 433MHz Frequency band" - -config LORAMAC_REGION_EU868 - bool "Europe 868MHz Frequency band" - -config LORAMAC_REGION_KR920 - bool "South Korea 920MHz Frequency band" - -config LORAMAC_REGION_IN865 - bool "India 865MHz Frequency band" - -config LORAMAC_REGION_US915 - bool "North America 915MHz Frequency band" - -config LORAMAC_REGION_RU864 - bool "Russia 864MHz Frequency band" - endif # LORA_MODULE_BACKEND_LORAMAC_NODE diff --git a/subsys/lorawan/loramac-node/lorawan.c b/subsys/lorawan/loramac-node/lorawan.c index a7c677001f6b..fd2b02b89ef8 100644 --- a/subsys/lorawan/loramac-node/lorawan.c +++ b/subsys/lorawan/loramac-node/lorawan.c @@ -15,34 +15,34 @@ #include #include "../nvm/lorawan_nvm.h" -#ifdef CONFIG_LORAMAC_REGION_AS923 +#ifdef CONFIG_LORAWAN_REGION_AS923 #define DEFAULT_LORAWAN_REGION LORAMAC_REGION_AS923 #define DEFAULT_LORAWAN_CHANNELS_MASK_SIZE LORAWAN_CHANNELS_MASK_SIZE_AS923 -#elif CONFIG_LORAMAC_REGION_AU915 +#elif CONFIG_LORAWAN_REGION_AU915 #define DEFAULT_LORAWAN_REGION LORAMAC_REGION_AU915 #define DEFAULT_LORAWAN_CHANNELS_MASK_SIZE LORAWAN_CHANNELS_MASK_SIZE_AU915 -#elif CONFIG_LORAMAC_REGION_CN470 +#elif CONFIG_LORAWAN_REGION_CN470 #define DEFAULT_LORAWAN_REGION LORAMAC_REGION_CN470 #define DEFAULT_LORAWAN_CHANNELS_MASK_SIZE LORAWAN_CHANNELS_MASK_SIZE_CN470 -#elif CONFIG_LORAMAC_REGION_CN779 +#elif CONFIG_LORAWAN_REGION_CN779 #define DEFAULT_LORAWAN_REGION LORAMAC_REGION_CN779 #define DEFAULT_LORAWAN_CHANNELS_MASK_SIZE LORAWAN_CHANNELS_MASK_SIZE_CN779 -#elif CONFIG_LORAMAC_REGION_EU433 +#elif CONFIG_LORAWAN_REGION_EU433 #define DEFAULT_LORAWAN_REGION LORAMAC_REGION_EU433 #define DEFAULT_LORAWAN_CHANNELS_MASK_SIZE LORAWAN_CHANNELS_MASK_SIZE_EU433 -#elif CONFIG_LORAMAC_REGION_EU868 +#elif CONFIG_LORAWAN_REGION_EU868 #define DEFAULT_LORAWAN_REGION LORAMAC_REGION_EU868 #define DEFAULT_LORAWAN_CHANNELS_MASK_SIZE LORAWAN_CHANNELS_MASK_SIZE_EU868 -#elif CONFIG_LORAMAC_REGION_KR920 +#elif CONFIG_LORAWAN_REGION_KR920 #define DEFAULT_LORAWAN_REGION LORAMAC_REGION_KR920 #define DEFAULT_LORAWAN_CHANNELS_MASK_SIZE LORAWAN_CHANNELS_MASK_SIZE_KR920 -#elif CONFIG_LORAMAC_REGION_IN865 +#elif CONFIG_LORAWAN_REGION_IN865 #define DEFAULT_LORAWAN_REGION LORAMAC_REGION_IN865 #define DEFAULT_LORAWAN_CHANNELS_MASK_SIZE LORAWAN_CHANNELS_MASK_SIZE_IN865 -#elif CONFIG_LORAMAC_REGION_US915 +#elif CONFIG_LORAWAN_REGION_US915 #define DEFAULT_LORAWAN_REGION LORAMAC_REGION_US915 #define DEFAULT_LORAWAN_CHANNELS_MASK_SIZE LORAWAN_CHANNELS_MASK_SIZE_US915 -#elif CONFIG_LORAMAC_REGION_RU864 +#elif CONFIG_LORAWAN_REGION_RU864 #define DEFAULT_LORAWAN_REGION LORAMAC_REGION_RU864 #define DEFAULT_LORAWAN_CHANNELS_MASK_SIZE LORAWAN_CHANNELS_MASK_SIZE_RU864 #else @@ -322,70 +322,70 @@ int lorawan_set_region(enum lorawan_region region) { switch (region) { -#if defined(CONFIG_LORAMAC_REGION_AS923) +#if defined(CONFIG_LORAWAN_REGION_AS923) case LORAWAN_REGION_AS923: selected_region = LORAMAC_REGION_AS923; region_channels_mask_size = LORAWAN_CHANNELS_MASK_SIZE_AS923; break; #endif -#if defined(CONFIG_LORAMAC_REGION_AU915) +#if defined(CONFIG_LORAWAN_REGION_AU915) case LORAWAN_REGION_AU915: selected_region = LORAMAC_REGION_AU915; region_channels_mask_size = LORAWAN_CHANNELS_MASK_SIZE_AU915; break; #endif -#if defined(CONFIG_LORAMAC_REGION_CN470) +#if defined(CONFIG_LORAWAN_REGION_CN470) case LORAWAN_REGION_CN470: selected_region = LORAMAC_REGION_CN470; region_channels_mask_size = LORAWAN_CHANNELS_MASK_SIZE_CN470; break; #endif -#if defined(CONFIG_LORAMAC_REGION_CN779) +#if defined(CONFIG_LORAWAN_REGION_CN779) case LORAWAN_REGION_CN779: selected_region = LORAMAC_REGION_CN779; region_channels_mask_size = LORAWAN_CHANNELS_MASK_SIZE_CN779; break; #endif -#if defined(CONFIG_LORAMAC_REGION_EU433) +#if defined(CONFIG_LORAWAN_REGION_EU433) case LORAWAN_REGION_EU433: selected_region = LORAMAC_REGION_EU433; region_channels_mask_size = LORAWAN_CHANNELS_MASK_SIZE_EU433; break; #endif -#if defined(CONFIG_LORAMAC_REGION_EU868) +#if defined(CONFIG_LORAWAN_REGION_EU868) case LORAWAN_REGION_EU868: selected_region = LORAMAC_REGION_EU868; region_channels_mask_size = LORAWAN_CHANNELS_MASK_SIZE_EU868; break; #endif -#if defined(CONFIG_LORAMAC_REGION_KR920) +#if defined(CONFIG_LORAWAN_REGION_KR920) case LORAWAN_REGION_KR920: selected_region = LORAMAC_REGION_KR920; region_channels_mask_size = LORAWAN_CHANNELS_MASK_SIZE_KR920; break; #endif -#if defined(CONFIG_LORAMAC_REGION_IN865) +#if defined(CONFIG_LORAWAN_REGION_IN865) case LORAWAN_REGION_IN865: selected_region = LORAMAC_REGION_IN865; region_channels_mask_size = LORAWAN_CHANNELS_MASK_SIZE_IN865; break; #endif -#if defined(CONFIG_LORAMAC_REGION_US915) +#if defined(CONFIG_LORAWAN_REGION_US915) case LORAWAN_REGION_US915: selected_region = LORAMAC_REGION_US915; region_channels_mask_size = LORAWAN_CHANNELS_MASK_SIZE_US915; break; #endif -#if defined(CONFIG_LORAMAC_REGION_RU864) +#if defined(CONFIG_LORAWAN_REGION_RU864) case LORAWAN_REGION_RU864: selected_region = LORAMAC_REGION_RU864; region_channels_mask_size = LORAWAN_CHANNELS_MASK_SIZE_RU864; diff --git a/tests/subsys/lorawan/channels_mask/prj.conf b/tests/subsys/lorawan/channels_mask/prj.conf index 52ac900a809b..bc48e1077e4c 100644 --- a/tests/subsys/lorawan/channels_mask/prj.conf +++ b/tests/subsys/lorawan/channels_mask/prj.conf @@ -3,7 +3,7 @@ CONFIG_ZTEST=y CONFIG_ASSERT=y CONFIG_LORA=y CONFIG_LORAWAN=y -CONFIG_LORAMAC_REGION_AS923=y -CONFIG_LORAMAC_REGION_AU915=y +CONFIG_LORAWAN_REGION_AS923=y +CONFIG_LORAWAN_REGION_AU915=y CONFIG_MAIN_STACK_SIZE=2048 CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048 diff --git a/tests/subsys/lorawan/clock_sync/prj.conf b/tests/subsys/lorawan/clock_sync/prj.conf index c1e44024348e..da7f3b29ce1f 100644 --- a/tests/subsys/lorawan/clock_sync/prj.conf +++ b/tests/subsys/lorawan/clock_sync/prj.conf @@ -17,7 +17,7 @@ CONFIG_ENTROPY_GENERATOR=y # LoRaWAN application layer CONFIG_LORAWAN=y CONFIG_LORAWAN_EMUL=y -CONFIG_LORAMAC_REGION_EU868=y +CONFIG_LORAWAN_REGION_EU868=y # LoRaWAN services required for this test CONFIG_LORAWAN_SERVICES=y diff --git a/tests/subsys/lorawan/frag_decoder/prj.conf b/tests/subsys/lorawan/frag_decoder/prj.conf index b355ebd006fc..f12df194dbd7 100644 --- a/tests/subsys/lorawan/frag_decoder/prj.conf +++ b/tests/subsys/lorawan/frag_decoder/prj.conf @@ -17,7 +17,7 @@ CONFIG_ENTROPY_GENERATOR=y # LoRaWAN application layer CONFIG_LORAWAN=y CONFIG_LORAWAN_EMUL=y -CONFIG_LORAMAC_REGION_EU868=y +CONFIG_LORAWAN_REGION_EU868=y # LoRaWAN services required for this test CONFIG_LORAWAN_SERVICES=y diff --git a/tests/subsys/mgmt/mcumgr/transport_lorawan/prj.conf b/tests/subsys/mgmt/mcumgr/transport_lorawan/prj.conf index 7cd639239601..23debb538844 100644 --- a/tests/subsys/mgmt/mcumgr/transport_lorawan/prj.conf +++ b/tests/subsys/mgmt/mcumgr/transport_lorawan/prj.conf @@ -10,7 +10,7 @@ CONFIG_ZCBOR=y CONFIG_MCUMGR=y CONFIG_LORA=y CONFIG_LORAWAN=y -CONFIG_LORAMAC_REGION_EU868=y +CONFIG_LORAWAN_REGION_EU868=y CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=3000 CONFIG_MCUMGR_TRANSPORT_LORAWAN=y CONFIG_MCUMGR_TRANSPORT_LORAWAN_CONFIRMED_UPLINKS=n From ab16cca665d26f76ba6a333db8917af2b9fdc8fd Mon Sep 17 00:00:00 2001 From: Zhaoxiang Jin Date: Thu, 8 Jan 2026 17:54:04 +0800 Subject: [PATCH 1877/3659] drivers: adc: nxp_sar_adc: Add compatibility for SoCs without ADCLKSEL Some NXP SAR ADC variants don't implement the MCR[ADCLKSEL] field. Add conditional compilation guards to define compatibility macros that evaluate to 0 when ADCLKSEL is not available, allowing the driver to compile across different NXP SoCs. Signed-off-by: Zhaoxiang Jin --- drivers/adc/adc_nxp_sar_adc.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/drivers/adc/adc_nxp_sar_adc.c b/drivers/adc/adc_nxp_sar_adc.c index ad1622c8d98a..8b00df66dfa8 100644 --- a/drivers/adc/adc_nxp_sar_adc.c +++ b/drivers/adc/adc_nxp_sar_adc.c @@ -31,6 +31,17 @@ LOG_MODULE_REGISTER(nxp_sar_adc, CONFIG_ADC_LOG_LEVEL); #define NXP_SAR_ADC_HAS_GROUP2_REGS 0 #endif +/* Some NXP SAR ADC variants don't implement MCR[ADCLKSEL]. + * Guard both the mask and the value macro so the driver can compile across SoCs. + */ +#if defined(ADC_MCR_ADCLKSEL_MASK) && defined(ADC_MCR_ADCLKSEL) +#define NXP_SAR_ADC_MCR_ADCLKSEL_MASK ADC_MCR_ADCLKSEL_MASK +#define NXP_SAR_ADC_MCR_ADCLKSEL(x) ADC_MCR_ADCLKSEL(x) +#else +#define NXP_SAR_ADC_MCR_ADCLKSEL_MASK 0U +#define NXP_SAR_ADC_MCR_ADCLKSEL(x) 0U +#endif + struct nxp_sar_adc_config { ADC_Type *base; const struct device *clock_dev; @@ -465,9 +476,9 @@ static int nxp_sar_adc_init(const struct device *dev) } base->MCR = ((base->MCR & ~(ADC_MCR_OWREN_MASK | ADC_MCR_ACKO_MASK | - ADC_MCR_ADCLKSEL_MASK)) | ADC_MCR_OWREN(config->overwrite ? 1U : 0U) | + NXP_SAR_ADC_MCR_ADCLKSEL_MASK)) | ADC_MCR_OWREN(config->overwrite ? 1U : 0U) | ADC_MCR_ACKO(config->auto_clock_off ? 1U : 0U) | - ADC_MCR_ADCLKSEL(config->conv_clk_freq_div_factor)); + NXP_SAR_ADC_MCR_ADCLKSEL(config->conv_clk_freq_div_factor)); /* Disable global and all channels' interrupt. */ base->IMR = 0U; From a03afda472e27dd9f4c02d9f7cf4c320e256ee11 Mon Sep 17 00:00:00 2001 From: Sylvio Alves Date: Wed, 7 Jan 2026 14:01:28 -0300 Subject: [PATCH 1878/3659] boards: espressif: update hw breakpoint limits per soc Fix max number of hardware breakpoints based on SOC. Signed-off-by: Sylvio Alves --- boards/common/esp32.board.cmake | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/boards/common/esp32.board.cmake b/boards/common/esp32.board.cmake index ca97aa20c3f5..74fd8a98ce86 100644 --- a/boards/common/esp32.board.cmake +++ b/boards/common/esp32.board.cmake @@ -4,7 +4,17 @@ board_set_flasher_ifnset(esp32) board_set_debugger_ifnset(openocd) board_runner_args(openocd --no-halt --no-targets --no-load --target-handle _TARGETNAME_0) -board_runner_args(openocd --gdb-init "set remote hardware-watchpoint-limit 2") + +# Set hardware watchpoint limit based on SOC capabilities +if(CONFIG_SOC_SERIES_ESP32C3) + set(ESP_HW_WATCHPOINT_LIMIT 8) +elseif(CONFIG_SOC_SERIES_ESP32C6 OR CONFIG_SOC_SERIES_ESP32H2) + set(ESP_HW_WATCHPOINT_LIMIT 4) +else() + # ESP32, ESP32-S2, ESP32-S3, ESP32-C2 all have 2 watchpoints + set(ESP_HW_WATCHPOINT_LIMIT 2) +endif() +board_runner_args(openocd --gdb-init "set remote hardware-watchpoint-limit ${ESP_HW_WATCHPOINT_LIMIT}") board_runner_args(openocd --gdb-init "maintenance flush register-cache") board_runner_args(openocd --gdb-init "mon esp appimage_offset ${CONFIG_FLASH_LOAD_OFFSET}") From eb7827869c63481e8a5f6de7aa3acc14827a5964 Mon Sep 17 00:00:00 2001 From: Biwen Li Date: Wed, 7 Jan 2026 14:36:00 +0900 Subject: [PATCH 1879/3659] dts: arm: nxp: imx95: m7: disable disp_irqsteer This is a workaround to fix a bug that failed to access registers of display irqsteer when display mix is in power off state. - Display irqsteer is in display mix, need to power on display mix firstly. Signed-off-by: Biwen Li --- dts/arm/nxp/nxp_imx95_m7.dtsi | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/dts/arm/nxp/nxp_imx95_m7.dtsi b/dts/arm/nxp/nxp_imx95_m7.dtsi index 71c7130a7810..d345f8d48042 100644 --- a/dts/arm/nxp/nxp_imx95_m7.dtsi +++ b/dts/arm/nxp/nxp_imx95_m7.dtsi @@ -684,6 +684,7 @@ #address-cells = <1>; nxp,irq-offset = <874>; nxp,num-irqs = <512>; + status = "disabled"; disp_irqsteer_master0: interrupt-controller@0 { compatible = "nxp,irqsteer-master"; @@ -691,6 +692,7 @@ interrupt-controller; #interrupt-cells = <2>; interrupts-extended = <&nvic 214 0>; + status = "disabled"; }; disp_irqsteer_master1: interrupt-controller@1 { @@ -699,6 +701,7 @@ interrupt-controller; #interrupt-cells = <2>; interrupts-extended = <&nvic 215 0>; + status = "disabled"; }; disp_irqsteer_master2: interrupt-controller@2 { @@ -707,6 +710,7 @@ interrupt-controller; #interrupt-cells = <2>; interrupts-extended = <&nvic 216 0>; + status = "disabled"; }; disp_irqsteer_master3: interrupt-controller@3 { @@ -715,6 +719,7 @@ interrupt-controller; #interrupt-cells = <2>; interrupts-extended = <&nvic 217 0>; + status = "disabled"; }; disp_irqsteer_master4: interrupt-controller@4 { @@ -723,6 +728,7 @@ interrupt-controller; #interrupt-cells = <2>; interrupts-extended = <&nvic 218 0>; + status = "disabled"; }; disp_irqsteer_master7: interrupt-controller@7 { @@ -731,6 +737,7 @@ interrupt-controller; #interrupt-cells = <2>; interrupts-extended = <&nvic 219 0>; + status = "disabled"; }; }; From 419752001619f3e01e2e5d6c59b2a1a2ef362fd9 Mon Sep 17 00:00:00 2001 From: Jiafei Pan Date: Tue, 6 Jan 2026 17:05:10 +0800 Subject: [PATCH 1880/3659] dts: arm64: imx943: add watchdog device nodes Added device nodes for WDOG3 and WDOG4 which is used by A55. Signed-off-by: Jiafei Pan --- dts/arm64/nxp/nxp_mimx943_a55.dtsi | 54 +++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/dts/arm64/nxp/nxp_mimx943_a55.dtsi b/dts/arm64/nxp/nxp_mimx943_a55.dtsi index 912d5469a7d4..72a9e103bef8 100644 --- a/dts/arm64/nxp/nxp_mimx943_a55.dtsi +++ b/dts/arm64/nxp/nxp_mimx943_a55.dtsi @@ -1,5 +1,5 @@ /* - * Copyright 2025 NXP + * Copyright 2025-2026 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -418,6 +418,58 @@ status = "disabled"; }; + ext_clk: ext24m { + /* WDOG ext clock: 24MHz */ + compatible = "fixed-clock"; + clock-frequency = <24000000>; + #clock-cells = <0>; + }; + + lpo_clk: lpo32k { + /* WDOG LPO clock: 32KHz */ + compatible = "fixed-clock"; + clock-frequency = <32000>; + #clock-cells = <0>; + }; + + int_clk: int133m { + /* WDOG int clock: 133MHz */ + compatible = "fixed-clock"; + clock-frequency = <133000000>; + #clock-cells = <0>; + }; + + ipg_clk: ipg133m { + /* WDOG ipg clock: 133MHz */ + compatible = "fixed-clock"; + clock-frequency = <133000000>; + #clock-cells = <0>; + }; + + wdog3: watchdog@49220000 { + compatible = "nxp,wdog32"; + reg = <0x49220000 0x1000>; + interrupts = ; + interrupt-parent = <&gic>; + /* clk-source and clocks must aligned: 0-ipg_clk, 1-lpo_clk, 2-int_clk, 3-ext_clk */ + clocks = <&lpo_clk>; + clk-source = <1>; + clk-divider = <256>; + status = "disabled"; + }; + + wdog4: watchdog@49230000 { + compatible = "nxp,wdog32"; + reg = <0x49230000 0x1000>; + interrupts = ; + interrupt-parent = <&gic>; + /* clk-source and clocks must aligned: 0-ipg_clk, 1-lpo_clk, 2-int_clk, 3-ext_clk */ + clocks = <&lpo_clk>; + clk-source = <1>; + clk-divider = <256>; + status = "disabled"; + }; + netc_blk_ctrl: netc-blk-ctrl@4ceb0000 { compatible = "nxp,imx-netc-blk-ctrl"; reg = <0x4ceb0000 0x10000>, From b6866c15d304975dd17b735be117f49468de5fed Mon Sep 17 00:00:00 2001 From: Jiafei Pan Date: Tue, 6 Jan 2026 17:08:28 +0800 Subject: [PATCH 1881/3659] boards: imx943_evk: enable watchdog for Cortex-A55 Enable WDOG4 for A55 on imx943_evk board. It could be verified by building application by: west build -p always -b imx943_evk/mimx94398/a55 samples/drivers/watchdog Signed-off-by: Jiafei Pan --- boards/nxp/imx943_evk/imx943_evk_mimx94398_a55.dts | 10 +++++++++- boards/nxp/imx943_evk/imx943_evk_mimx94398_a55.yaml | 3 ++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/boards/nxp/imx943_evk/imx943_evk_mimx94398_a55.dts b/boards/nxp/imx943_evk/imx943_evk_mimx94398_a55.dts index ae6ab2dee668..31a696846253 100644 --- a/boards/nxp/imx943_evk/imx943_evk_mimx94398_a55.dts +++ b/boards/nxp/imx943_evk/imx943_evk_mimx94398_a55.dts @@ -1,5 +1,5 @@ /* - * Copyright 2025 NXP + * Copyright 2025-2026 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -13,6 +13,10 @@ model = "NXP i.MX943 A55"; compatible = "fsl,mimx943"; + aliases { + watchdog0 = &wdog4; + }; + chosen { zephyr,console = &lpuart1; zephyr,shell-uart = &lpuart1; @@ -133,3 +137,7 @@ zephyr,random-mac-address; status = "disabled"; }; + +&wdog4 { + status = "okay"; +}; diff --git a/boards/nxp/imx943_evk/imx943_evk_mimx94398_a55.yaml b/boards/nxp/imx943_evk/imx943_evk_mimx94398_a55.yaml index fd9927ef343c..1c0d0e8586bf 100644 --- a/boards/nxp/imx943_evk/imx943_evk_mimx94398_a55.yaml +++ b/boards/nxp/imx943_evk/imx943_evk_mimx94398_a55.yaml @@ -1,5 +1,5 @@ # -# Copyright 2025 NXP +# Copyright 2025-2026 NXP # # SPDX-License-Identifier: Apache-2.0 # @@ -17,4 +17,5 @@ supported: - gpio - net - uart + - watchdog vendor: nxp From 69bee427ba74113634280950052f66b27a00ee0d Mon Sep 17 00:00:00 2001 From: TOKITA Hiroshi Date: Sat, 3 Jan 2026 16:23:42 +0900 Subject: [PATCH 1882/3659] drivers: sensor: liteon: Rename ltr329 to ltr55x The LTR329 is a functional subset of the LTR55X series, lacking the proximity sensor functionality. To maintain symbol consistency, we will use LTR55X as the base name. Signed-off-by: TOKITA Hiroshi --- drivers/sensor/liteon/CMakeLists.txt | 2 +- drivers/sensor/liteon/Kconfig | 2 +- .../liteon/{ltr329 => ltr55x}/CMakeLists.txt | 2 +- .../sensor/liteon/{ltr329 => ltr55x}/Kconfig | 2 +- .../{ltr329/ltr329.c => ltr55x/ltr55x.c} | 186 +++++++++--------- 5 files changed, 97 insertions(+), 97 deletions(-) rename drivers/sensor/liteon/{ltr329 => ltr55x}/CMakeLists.txt (63%) rename drivers/sensor/liteon/{ltr329 => ltr55x}/Kconfig (95%) rename drivers/sensor/liteon/{ltr329/ltr329.c => ltr55x/ltr55x.c} (52%) diff --git a/drivers/sensor/liteon/CMakeLists.txt b/drivers/sensor/liteon/CMakeLists.txt index b3d699fd44fc..8a7ee300beb2 100644 --- a/drivers/sensor/liteon/CMakeLists.txt +++ b/drivers/sensor/liteon/CMakeLists.txt @@ -2,6 +2,6 @@ # SPDX-License-Identifier: Apache-2.0 # zephyr-keep-sorted-start -add_subdirectory_ifdef(CONFIG_LTR329 ltr329) +add_subdirectory_ifdef(CONFIG_LTR55X ltr55x) add_subdirectory_ifdef(CONFIG_LTR_F216A ltrf216a) # zephyr-keep-sorted-stop diff --git a/drivers/sensor/liteon/Kconfig b/drivers/sensor/liteon/Kconfig index 802a8c57e87f..988b9fb144a9 100644 --- a/drivers/sensor/liteon/Kconfig +++ b/drivers/sensor/liteon/Kconfig @@ -2,6 +2,6 @@ # SPDX-License-Identifier: Apache-2.0 # zephyr-keep-sorted-start -source "drivers/sensor/liteon/ltr329/Kconfig" +source "drivers/sensor/liteon/ltr55x/Kconfig" source "drivers/sensor/liteon/ltrf216a/Kconfig" # zephyr-keep-sorted-stop diff --git a/drivers/sensor/liteon/ltr329/CMakeLists.txt b/drivers/sensor/liteon/ltr55x/CMakeLists.txt similarity index 63% rename from drivers/sensor/liteon/ltr329/CMakeLists.txt rename to drivers/sensor/liteon/ltr55x/CMakeLists.txt index e1282068ddd1..93ec22975bb6 100644 --- a/drivers/sensor/liteon/ltr329/CMakeLists.txt +++ b/drivers/sensor/liteon/ltr55x/CMakeLists.txt @@ -2,4 +2,4 @@ zephyr_library() -zephyr_library_sources(ltr329.c) +zephyr_library_sources(ltr55x.c) diff --git a/drivers/sensor/liteon/ltr329/Kconfig b/drivers/sensor/liteon/ltr55x/Kconfig similarity index 95% rename from drivers/sensor/liteon/ltr329/Kconfig rename to drivers/sensor/liteon/ltr55x/Kconfig index 3a08aabc5901..fa8a37d7db30 100644 --- a/drivers/sensor/liteon/ltr329/Kconfig +++ b/drivers/sensor/liteon/ltr55x/Kconfig @@ -3,7 +3,7 @@ # Copyright (c) 2025 Konrad Sikora # SPDX-License-Identifier: Apache-2.0 -config LTR329 +config LTR55X bool "LiteOn LTR-329 Ambient light sensor support" default y depends on DT_HAS_LITEON_LTR329_ENABLED diff --git a/drivers/sensor/liteon/ltr329/ltr329.c b/drivers/sensor/liteon/ltr55x/ltr55x.c similarity index 52% rename from drivers/sensor/liteon/ltr329/ltr329.c rename to drivers/sensor/liteon/ltr55x/ltr55x.c index 1ee317af3435..a72c2a008f8a 100644 --- a/drivers/sensor/liteon/ltr329/ltr329.c +++ b/drivers/sensor/liteon/ltr55x/ltr55x.c @@ -13,152 +13,152 @@ #include #include -LOG_MODULE_REGISTER(LTR329, CONFIG_SENSOR_LOG_LEVEL); +LOG_MODULE_REGISTER(LTR55X, CONFIG_SENSOR_LOG_LEVEL); /* Register addresses */ -#define LTR329_ALS_CONTR 0x80 -#define LTR329_MEAS_RATE 0x85 -#define LTR329_PART_ID 0x86 -#define LTR329_MANUFAC_ID 0x87 -#define LTR329_ALS_DATA_CH1_0 0x88 -#define LTR329_ALS_DATA_CH1_1 0x89 -#define LTR329_ALS_DATA_CH0_0 0x8A -#define LTR329_ALS_DATA_CH0_1 0x8B -#define LTR329_ALS_STATUS 0x8C +#define LTR55X_ALS_CONTR 0x80 +#define LTR55X_MEAS_RATE 0x85 +#define LTR55X_PART_ID 0x86 +#define LTR55X_MANUFAC_ID 0x87 +#define LTR55X_ALS_DATA_CH1_0 0x88 +#define LTR55X_ALS_DATA_CH1_1 0x89 +#define LTR55X_ALS_DATA_CH0_0 0x8A +#define LTR55X_ALS_DATA_CH0_1 0x8B +#define LTR55X_ALS_STATUS 0x8C /* Bit masks and shifts for ALS_CONTR register */ -#define LTR329_ALS_CONTR_MODE_MASK BIT(0) -#define LTR329_ALS_CONTR_MODE_SHIFT 0 -#define LTR329_ALS_CONTR_SW_RESET_MASK BIT(1) -#define LTR329_ALS_CONTR_SW_RESET_SHIFT 1 -#define LTR329_ALS_CONTR_GAIN_MASK GENMASK(4, 2) -#define LTR329_ALS_CONTR_GAIN_SHIFT 2 +#define LTR55X_ALS_CONTR_MODE_MASK BIT(0) +#define LTR55X_ALS_CONTR_MODE_SHIFT 0 +#define LTR55X_ALS_CONTR_SW_RESET_MASK BIT(1) +#define LTR55X_ALS_CONTR_SW_RESET_SHIFT 1 +#define LTR55X_ALS_CONTR_GAIN_MASK GENMASK(4, 2) +#define LTR55X_ALS_CONTR_GAIN_SHIFT 2 /* Bit masks and shifts for MEAS_RATE register */ -#define LTR329_MEAS_RATE_REPEAT_MASK GENMASK(2, 0) -#define LTR329_MEAS_RATE_REPEAT_SHIFT 0 -#define LTR329_MEAS_RATE_INT_TIME_MASK GENMASK(5, 3) -#define LTR329_MEAS_RATE_INT_TIME_SHIFT 3 +#define LTR55X_MEAS_RATE_REPEAT_MASK GENMASK(2, 0) +#define LTR55X_MEAS_RATE_REPEAT_SHIFT 0 +#define LTR55X_MEAS_RATE_INT_TIME_MASK GENMASK(5, 3) +#define LTR55X_MEAS_RATE_INT_TIME_SHIFT 3 /* Bit masks and shifts for PART_ID register */ -#define LTR329_PART_ID_REVISION_MASK GENMASK(3, 0) -#define LTR329_PART_ID_REVISION_SHIFT 0 -#define LTR329_PART_ID_NUMBER_MASK GENMASK(7, 4) -#define LTR329_PART_ID_NUMBER_SHIFT 4 +#define LTR55X_PART_ID_REVISION_MASK GENMASK(3, 0) +#define LTR55X_PART_ID_REVISION_SHIFT 0 +#define LTR55X_PART_ID_NUMBER_MASK GENMASK(7, 4) +#define LTR55X_PART_ID_NUMBER_SHIFT 4 /* Bit masks and shifts for MANUFAC_ID register */ -#define LTR329_MANUFAC_ID_IDENTIFICATION_MASK GENMASK(7, 0) -#define LTR329_MANUFAC_ID_IDENTIFICATION_SHIFT 0 +#define LTR55X_MANUFAC_ID_IDENTIFICATION_MASK GENMASK(7, 0) +#define LTR55X_MANUFAC_ID_IDENTIFICATION_SHIFT 0 /* Bit masks and shifts for ALS_STATUS register */ -#define LTR329_ALS_STATUS_DATA_MASK GENMASK(7, 0) -#define LTR329_ALS_STATUS_DATA_SHIFT 0 -#define LTR329_ALS_STATUS_DATA_READY_MASK BIT(2) -#define LTR329_ALS_STATUS_DATA_READY_SHIFT 2 -#define LTR329_ALS_STATUS_DATA_GAIN_MASK GENMASK(6, 4) -#define LTR329_ALS_STATUS_DATA_GAIN_SHIFT 4 -#define LTR329_ALS_STATUS_DATA_VALID_MASK BIT(7) -#define LTR329_ALS_STATUS_DATA_VALID_SHIFT 7 +#define LTR55X_ALS_STATUS_DATA_MASK GENMASK(7, 0) +#define LTR55X_ALS_STATUS_DATA_SHIFT 0 +#define LTR55X_ALS_STATUS_DATA_READY_MASK BIT(2) +#define LTR55X_ALS_STATUS_DATA_READY_SHIFT 2 +#define LTR55X_ALS_STATUS_DATA_GAIN_MASK GENMASK(6, 4) +#define LTR55X_ALS_STATUS_DATA_GAIN_SHIFT 4 +#define LTR55X_ALS_STATUS_DATA_VALID_MASK BIT(7) +#define LTR55X_ALS_STATUS_DATA_VALID_SHIFT 7 /* Expected sensor IDs */ -#define LTR329_PART_ID_VALUE 0xA0 -#define LTR329_MANUFACTURER_ID_VALUE 0x05 +#define LTR55X_PART_ID_VALUE 0xA0 +#define LTR55X_MANUFACTURER_ID_VALUE 0x05 /* Timing definitions - refer to LTR-329ALS-01 datasheet */ -#define LTR329_INIT_STARTUP_MS 100 -#define LTR329_WAKEUP_FROM_STANDBY_MS 10 +#define LTR55X_INIT_STARTUP_MS 100 +#define LTR55X_WAKEUP_FROM_STANDBY_MS 10 /* Macros to set and get register fields */ -#define LTR329_REG_SET(reg, field, value) \ +#define LTR55X_REG_SET(reg, field, value) \ (((value) << reg##_##field##_SHIFT) & reg##_##field##_MASK) -#define LTR329_REG_GET(reg, field, value) \ +#define LTR55X_REG_GET(reg, field, value) \ (((value) & reg##_##field##_MASK) >> reg##_##field##_SHIFT) -struct ltr329_config { +struct ltr55x_config { const struct i2c_dt_spec bus; uint8_t gain; uint8_t integration_time; uint8_t measurement_rate; }; -struct ltr329_data { +struct ltr55x_data { uint16_t ch0; uint16_t ch1; }; -static int ltr329_check_device_id(const struct i2c_dt_spec *bus) +static int ltr55x_check_device_id(const struct i2c_dt_spec *bus) { uint8_t id; int rc; - rc = i2c_reg_read_byte_dt(bus, LTR329_PART_ID, &id); + rc = i2c_reg_read_byte_dt(bus, LTR55X_PART_ID, &id); if (rc < 0) { LOG_ERR("Failed to read PART_ID"); return rc; } - if (id != LTR329_PART_ID_VALUE) { - LOG_ERR("PART_ID mismatch: expected 0x%02X, got 0x%02X", LTR329_PART_ID_VALUE, id); + if (id != LTR55X_PART_ID_VALUE) { + LOG_ERR("PART_ID mismatch: expected 0x%02X, got 0x%02X", LTR55X_PART_ID_VALUE, id); return -ENODEV; } - rc = i2c_reg_read_byte_dt(bus, LTR329_MANUFAC_ID, &id); + rc = i2c_reg_read_byte_dt(bus, LTR55X_MANUFAC_ID, &id); if (rc < 0) { LOG_ERR("Failed to read MANUFAC_ID"); return rc; } - if (id != LTR329_MANUFACTURER_ID_VALUE) { + if (id != LTR55X_MANUFACTURER_ID_VALUE) { LOG_ERR("MANUFAC_ID mismatch: expected 0x%02X, got 0x%02X", - LTR329_MANUFACTURER_ID_VALUE, id); + LTR55X_MANUFACTURER_ID_VALUE, id); return -ENODEV; } return 0; } -static int ltr329_init_registers(const struct i2c_dt_spec *bus, const struct ltr329_config *cfg) +static int ltr55x_init_registers(const struct i2c_dt_spec *bus, const struct ltr55x_config *cfg) { - const uint8_t control_reg = LTR329_REG_SET(LTR329_ALS_CONTR, MODE, 1) | - LTR329_REG_SET(LTR329_ALS_CONTR, GAIN, cfg->gain); - const uint8_t meas_reg = LTR329_REG_SET(LTR329_MEAS_RATE, REPEAT, cfg->measurement_rate) | - LTR329_REG_SET(LTR329_MEAS_RATE, INT_TIME, cfg->integration_time); + const uint8_t control_reg = LTR55X_REG_SET(LTR55X_ALS_CONTR, MODE, 1) | + LTR55X_REG_SET(LTR55X_ALS_CONTR, GAIN, cfg->gain); + const uint8_t meas_reg = LTR55X_REG_SET(LTR55X_MEAS_RATE, REPEAT, cfg->measurement_rate) | + LTR55X_REG_SET(LTR55X_MEAS_RATE, INT_TIME, cfg->integration_time); uint8_t buffer; int rc; - rc = i2c_reg_write_byte_dt(bus, LTR329_ALS_CONTR, control_reg); + rc = i2c_reg_write_byte_dt(bus, LTR55X_ALS_CONTR, control_reg); if (rc < 0) { LOG_ERR("Failed to set ALS_CONTR register"); return rc; } - rc = i2c_reg_write_byte_dt(bus, LTR329_MEAS_RATE, meas_reg); + rc = i2c_reg_write_byte_dt(bus, LTR55X_MEAS_RATE, meas_reg); if (rc < 0) { LOG_ERR("Failed to set MEAS_RATE register"); return rc; } /* Read back the MEAS_RATE register to verify the settings */ - rc = i2c_reg_read_byte_dt(bus, LTR329_MEAS_RATE, &buffer); + rc = i2c_reg_read_byte_dt(bus, LTR55X_MEAS_RATE, &buffer); if (rc < 0) { LOG_ERR("Failed to read back MEAS_RATE register"); return rc; } - if (LTR329_REG_GET(LTR329_MEAS_RATE, REPEAT, buffer) != cfg->measurement_rate) { + if (LTR55X_REG_GET(LTR55X_MEAS_RATE, REPEAT, buffer) != cfg->measurement_rate) { LOG_ERR("Measurement rate mismatch: expected %u, got %u", cfg->measurement_rate, - (uint8_t)LTR329_REG_GET(LTR329_MEAS_RATE, REPEAT, buffer)); + (uint8_t)LTR55X_REG_GET(LTR55X_MEAS_RATE, REPEAT, buffer)); return -ENODEV; } - if (LTR329_REG_GET(LTR329_MEAS_RATE, INT_TIME, buffer) != cfg->integration_time) { + if (LTR55X_REG_GET(LTR55X_MEAS_RATE, INT_TIME, buffer) != cfg->integration_time) { LOG_ERR("Integration time mismatch: expected %u, got %u", cfg->integration_time, - (uint8_t)LTR329_REG_GET(LTR329_MEAS_RATE, INT_TIME, buffer)); + (uint8_t)LTR55X_REG_GET(LTR55X_MEAS_RATE, INT_TIME, buffer)); return -ENODEV; } return 0; } -static int ltr329_init(const struct device *dev) +static int ltr55x_init(const struct device *dev) { - const struct ltr329_config *cfg = dev->config; + const struct ltr55x_config *cfg = dev->config; int rc; if (!i2c_is_ready_dt(&cfg->bus)) { @@ -167,15 +167,15 @@ static int ltr329_init(const struct device *dev) } /* Wait for sensor startup */ - k_sleep(K_MSEC(LTR329_INIT_STARTUP_MS)); + k_sleep(K_MSEC(LTR55X_INIT_STARTUP_MS)); - rc = ltr329_check_device_id(&cfg->bus); + rc = ltr55x_check_device_id(&cfg->bus); if (rc < 0) { return rc; } /* Init register to enable sensor to active mode */ - rc = ltr329_init_registers(&cfg->bus, cfg); + rc = ltr55x_init_registers(&cfg->bus, cfg); if (rc < 0) { return rc; } @@ -183,18 +183,18 @@ static int ltr329_init(const struct device *dev) return 0; } -static int ltr329_check_data_ready(const struct i2c_dt_spec *bus) +static int ltr55x_check_data_ready(const struct i2c_dt_spec *bus) { uint8_t status; int rc; - rc = i2c_reg_read_byte_dt(bus, LTR329_ALS_STATUS, &status); + rc = i2c_reg_read_byte_dt(bus, LTR55X_ALS_STATUS, &status); if (rc < 0) { LOG_ERR("Failed to read ALS_STATUS register"); return rc; } - if (!LTR329_REG_GET(LTR329_ALS_STATUS, DATA_READY, status)) { + if (!LTR55X_REG_GET(LTR55X_ALS_STATUS, DATA_READY, status)) { LOG_WRN("Data not ready"); return -EBUSY; } @@ -202,9 +202,9 @@ static int ltr329_check_data_ready(const struct i2c_dt_spec *bus) return 0; } -static int ltr329_read_als_data(const struct i2c_dt_spec *bus, struct ltr329_data *data) +static int ltr55x_read_als_data(const struct i2c_dt_spec *bus, struct ltr55x_data *data) { - uint8_t reg = LTR329_ALS_DATA_CH1_0; + uint8_t reg = LTR55X_ALS_DATA_CH1_0; uint8_t buff[4]; int rc; @@ -220,22 +220,22 @@ static int ltr329_read_als_data(const struct i2c_dt_spec *bus, struct ltr329_dat return 0; } -static int ltr329_sample_fetch(const struct device *dev, enum sensor_channel chan) +static int ltr55x_sample_fetch(const struct device *dev, enum sensor_channel chan) { - const struct ltr329_config *cfg = dev->config; - struct ltr329_data *data = dev->data; + const struct ltr55x_config *cfg = dev->config; + struct ltr55x_data *data = dev->data; int rc; if ((chan != SENSOR_CHAN_ALL) && (chan != SENSOR_CHAN_LIGHT)) { return -ENOTSUP; } - rc = ltr329_check_data_ready(&cfg->bus); + rc = ltr55x_check_data_ready(&cfg->bus); if (rc < 0) { return rc; } - rc = ltr329_read_als_data(&cfg->bus, data); + rc = ltr55x_read_als_data(&cfg->bus, data); if (rc < 0) { return rc; } @@ -243,7 +243,7 @@ static int ltr329_sample_fetch(const struct device *dev, enum sensor_channel cha return 0; } -static int ltr329_get_mapped_gain(const uint8_t reg_val, uint8_t *const output) +static int ltr55x_get_mapped_gain(const uint8_t reg_val, uint8_t *const output) { /* Map the register value to the gain used in the lux calculation * Indices 4 and 5 are invalid. @@ -259,7 +259,7 @@ static int ltr329_get_mapped_gain(const uint8_t reg_val, uint8_t *const output) return -EINVAL; } -static int ltr329_get_mapped_int_time(const uint8_t reg_val, uint8_t *const output) +static int ltr55x_get_mapped_int_time(const uint8_t reg_val, uint8_t *const output) { /* Map the register value to the integration time used in the lux calculation */ static const uint8_t int_time_lux_calc[] = {10, 5, 20, 40, 15, 25, 30, 35}; @@ -273,11 +273,11 @@ static int ltr329_get_mapped_int_time(const uint8_t reg_val, uint8_t *const outp return -EINVAL; } -static int ltr329_channel_get(const struct device *dev, enum sensor_channel chan, +static int ltr55x_channel_get(const struct device *dev, enum sensor_channel chan, struct sensor_value *val) { - const struct ltr329_data *data = dev->data; - const struct ltr329_config *cfg = dev->config; + const struct ltr55x_data *data = dev->data; + const struct ltr55x_config *cfg = dev->config; uint8_t gain_value; uint8_t integration_time_value; @@ -285,12 +285,12 @@ static int ltr329_channel_get(const struct device *dev, enum sensor_channel chan return -ENOTSUP; } - if (ltr329_get_mapped_gain(cfg->gain, &gain_value) != 0) { + if (ltr55x_get_mapped_gain(cfg->gain, &gain_value) != 0) { LOG_ERR("Invalid gain configuration"); return -EINVAL; } - if (ltr329_get_mapped_int_time(cfg->integration_time, &integration_time_value) != 0) { + if (ltr55x_get_mapped_int_time(cfg->integration_time, &integration_time_value) != 0) { LOG_ERR("Invalid integration time configuration"); return -EINVAL; } @@ -328,21 +328,21 @@ static int ltr329_channel_get(const struct device *dev, enum sensor_channel chan return 0; } -static DEVICE_API(sensor, ltr329_driver_api) = { - .sample_fetch = ltr329_sample_fetch, - .channel_get = ltr329_channel_get, +static DEVICE_API(sensor, ltr55x_driver_api) = { + .sample_fetch = ltr55x_sample_fetch, + .channel_get = ltr55x_channel_get, }; -#define DEFINE_LTR329(_num) \ - static struct ltr329_data ltr329_data_##_num; \ - static const struct ltr329_config ltr329_config_##_num = { \ +#define DEFINE_LTR55X(_num) \ + static struct ltr55x_data ltr55x_data_##_num; \ + static const struct ltr55x_config ltr55x_config_##_num = { \ .bus = I2C_DT_SPEC_INST_GET(_num), \ .gain = DT_INST_PROP(_num, gain), \ .integration_time = DT_INST_PROP(_num, integration_time), \ .measurement_rate = DT_INST_PROP(_num, measurement_rate), \ }; \ - SENSOR_DEVICE_DT_INST_DEFINE(_num, ltr329_init, NULL, <r329_data_##_num, \ - <r329_config_##_num, POST_KERNEL, \ - CONFIG_SENSOR_INIT_PRIORITY, <r329_driver_api); + SENSOR_DEVICE_DT_INST_DEFINE(_num, ltr55x_init, NULL, <r55x_data_##_num, \ + <r55x_config_##_num, POST_KERNEL, \ + CONFIG_SENSOR_INIT_PRIORITY, <r55x_driver_api); -DT_INST_FOREACH_STATUS_OKAY(DEFINE_LTR329) +DT_INST_FOREACH_STATUS_OKAY(DEFINE_LTR55X) From 0f40d36f6bae96bd98bd3a2e89a1ff3150b78d61 Mon Sep 17 00:00:00 2001 From: TOKITA Hiroshi Date: Sun, 4 Jan 2026 10:09:04 +0900 Subject: [PATCH 1883/3659] drivers: sensor: liteon: ltr55x: Split definitions to header ADd ltr55x.h to split definitions from .c file. Signed-off-by: TOKITA Hiroshi --- drivers/sensor/liteon/ltr55x/ltr55x.c | 81 ++---------------------- drivers/sensor/liteon/ltr55x/ltr55x.h | 89 +++++++++++++++++++++++++++ 2 files changed, 93 insertions(+), 77 deletions(-) create mode 100644 drivers/sensor/liteon/ltr55x/ltr55x.h diff --git a/drivers/sensor/liteon/ltr55x/ltr55x.c b/drivers/sensor/liteon/ltr55x/ltr55x.c index a72c2a008f8a..346fcdf40556 100644 --- a/drivers/sensor/liteon/ltr55x/ltr55x.c +++ b/drivers/sensor/liteon/ltr55x/ltr55x.c @@ -6,86 +6,13 @@ #define DT_DRV_COMPAT liteon_ltr329 -#include -#include -#include +#include "ltr55x.h" + #include #include -#include LOG_MODULE_REGISTER(LTR55X, CONFIG_SENSOR_LOG_LEVEL); -/* Register addresses */ -#define LTR55X_ALS_CONTR 0x80 -#define LTR55X_MEAS_RATE 0x85 -#define LTR55X_PART_ID 0x86 -#define LTR55X_MANUFAC_ID 0x87 -#define LTR55X_ALS_DATA_CH1_0 0x88 -#define LTR55X_ALS_DATA_CH1_1 0x89 -#define LTR55X_ALS_DATA_CH0_0 0x8A -#define LTR55X_ALS_DATA_CH0_1 0x8B -#define LTR55X_ALS_STATUS 0x8C - -/* Bit masks and shifts for ALS_CONTR register */ -#define LTR55X_ALS_CONTR_MODE_MASK BIT(0) -#define LTR55X_ALS_CONTR_MODE_SHIFT 0 -#define LTR55X_ALS_CONTR_SW_RESET_MASK BIT(1) -#define LTR55X_ALS_CONTR_SW_RESET_SHIFT 1 -#define LTR55X_ALS_CONTR_GAIN_MASK GENMASK(4, 2) -#define LTR55X_ALS_CONTR_GAIN_SHIFT 2 - -/* Bit masks and shifts for MEAS_RATE register */ -#define LTR55X_MEAS_RATE_REPEAT_MASK GENMASK(2, 0) -#define LTR55X_MEAS_RATE_REPEAT_SHIFT 0 -#define LTR55X_MEAS_RATE_INT_TIME_MASK GENMASK(5, 3) -#define LTR55X_MEAS_RATE_INT_TIME_SHIFT 3 - -/* Bit masks and shifts for PART_ID register */ -#define LTR55X_PART_ID_REVISION_MASK GENMASK(3, 0) -#define LTR55X_PART_ID_REVISION_SHIFT 0 -#define LTR55X_PART_ID_NUMBER_MASK GENMASK(7, 4) -#define LTR55X_PART_ID_NUMBER_SHIFT 4 - -/* Bit masks and shifts for MANUFAC_ID register */ -#define LTR55X_MANUFAC_ID_IDENTIFICATION_MASK GENMASK(7, 0) -#define LTR55X_MANUFAC_ID_IDENTIFICATION_SHIFT 0 - -/* Bit masks and shifts for ALS_STATUS register */ -#define LTR55X_ALS_STATUS_DATA_MASK GENMASK(7, 0) -#define LTR55X_ALS_STATUS_DATA_SHIFT 0 -#define LTR55X_ALS_STATUS_DATA_READY_MASK BIT(2) -#define LTR55X_ALS_STATUS_DATA_READY_SHIFT 2 -#define LTR55X_ALS_STATUS_DATA_GAIN_MASK GENMASK(6, 4) -#define LTR55X_ALS_STATUS_DATA_GAIN_SHIFT 4 -#define LTR55X_ALS_STATUS_DATA_VALID_MASK BIT(7) -#define LTR55X_ALS_STATUS_DATA_VALID_SHIFT 7 - -/* Expected sensor IDs */ -#define LTR55X_PART_ID_VALUE 0xA0 -#define LTR55X_MANUFACTURER_ID_VALUE 0x05 - -/* Timing definitions - refer to LTR-329ALS-01 datasheet */ -#define LTR55X_INIT_STARTUP_MS 100 -#define LTR55X_WAKEUP_FROM_STANDBY_MS 10 - -/* Macros to set and get register fields */ -#define LTR55X_REG_SET(reg, field, value) \ - (((value) << reg##_##field##_SHIFT) & reg##_##field##_MASK) -#define LTR55X_REG_GET(reg, field, value) \ - (((value) & reg##_##field##_MASK) >> reg##_##field##_SHIFT) - -struct ltr55x_config { - const struct i2c_dt_spec bus; - uint8_t gain; - uint8_t integration_time; - uint8_t measurement_rate; -}; - -struct ltr55x_data { - uint16_t ch0; - uint16_t ch1; -}; - static int ltr55x_check_device_id(const struct i2c_dt_spec *bus) { uint8_t id; @@ -96,8 +23,8 @@ static int ltr55x_check_device_id(const struct i2c_dt_spec *bus) LOG_ERR("Failed to read PART_ID"); return rc; } - if (id != LTR55X_PART_ID_VALUE) { - LOG_ERR("PART_ID mismatch: expected 0x%02X, got 0x%02X", LTR55X_PART_ID_VALUE, id); + if (id != LTR329_PART_ID_VALUE) { + LOG_ERR("PART_ID mismatch: expected 0x%02X, got 0x%02X", LTR329_PART_ID_VALUE, id); return -ENODEV; } diff --git a/drivers/sensor/liteon/ltr55x/ltr55x.h b/drivers/sensor/liteon/ltr55x/ltr55x.h new file mode 100644 index 000000000000..e37e020ad5e9 --- /dev/null +++ b/drivers/sensor/liteon/ltr55x/ltr55x.h @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2025 Konrad Sikora + * Copyright (c) 2025 TOKITA Hiroshi + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_SENSOR_LITEON_LTR55X_LTR55X_H_ +#define ZEPHYR_DRIVERS_SENSOR_LITEON_LTR55X_LTR55X_H_ + +#include +#include +#include +#include +#include +#include + +/* Register addresses */ +#define LTR55X_ALS_CONTR 0x80 +#define LTR55X_MEAS_RATE 0x85 +#define LTR55X_PART_ID 0x86 +#define LTR55X_MANUFAC_ID 0x87 +#define LTR55X_ALS_DATA_CH1_0 0x88 +#define LTR55X_ALS_DATA_CH1_1 0x89 +#define LTR55X_ALS_DATA_CH0_0 0x8A +#define LTR55X_ALS_DATA_CH0_1 0x8B +#define LTR55X_ALS_STATUS 0x8C + +/* Bit masks and shifts for ALS_CONTR register */ +#define LTR55X_ALS_CONTR_MODE_MASK BIT(0) +#define LTR55X_ALS_CONTR_MODE_SHIFT 0 +#define LTR55X_ALS_CONTR_SW_RESET_MASK BIT(1) +#define LTR55X_ALS_CONTR_SW_RESET_SHIFT 1 +#define LTR55X_ALS_CONTR_GAIN_MASK GENMASK(4, 2) +#define LTR55X_ALS_CONTR_GAIN_SHIFT 2 + +/* Bit masks and shifts for MEAS_RATE register */ +#define LTR55X_MEAS_RATE_REPEAT_MASK GENMASK(2, 0) +#define LTR55X_MEAS_RATE_REPEAT_SHIFT 0 +#define LTR55X_MEAS_RATE_INT_TIME_MASK GENMASK(5, 3) +#define LTR55X_MEAS_RATE_INT_TIME_SHIFT 3 + +/* Bit masks and shifts for PART_ID register */ +#define LTR55X_PART_ID_REVISION_MASK GENMASK(3, 0) +#define LTR55X_PART_ID_REVISION_SHIFT 0 +#define LTR55X_PART_ID_NUMBER_MASK GENMASK(7, 4) +#define LTR55X_PART_ID_NUMBER_SHIFT 4 + +/* Bit masks and shifts for MANUFAC_ID register */ +#define LTR55X_MANUFAC_ID_IDENTIFICATION_MASK GENMASK(7, 0) +#define LTR55X_MANUFAC_ID_IDENTIFICATION_SHIFT 0 + +/* Bit masks and shifts for ALS_STATUS register */ +#define LTR55X_ALS_STATUS_DATA_MASK GENMASK(7, 0) +#define LTR55X_ALS_STATUS_DATA_SHIFT 0 +#define LTR55X_ALS_STATUS_DATA_READY_MASK BIT(2) +#define LTR55X_ALS_STATUS_DATA_READY_SHIFT 2 +#define LTR55X_ALS_STATUS_DATA_GAIN_MASK GENMASK(6, 4) +#define LTR55X_ALS_STATUS_DATA_GAIN_SHIFT 4 +#define LTR55X_ALS_STATUS_DATA_VALID_MASK BIT(7) +#define LTR55X_ALS_STATUS_DATA_VALID_SHIFT 7 + +/* Expected sensor IDs */ +#define LTR329_PART_ID_VALUE 0xA0 +#define LTR55X_MANUFACTURER_ID_VALUE 0x05 + +/* Timing definitions - refer to LTR-329ALS-01 datasheet */ +#define LTR55X_INIT_STARTUP_MS 100 +#define LTR55X_WAKEUP_FROM_STANDBY_MS 10 + +/* Macros to set and get register fields */ +#define LTR55X_REG_SET(reg, field, value) \ + (((value) << reg##_##field##_SHIFT) & reg##_##field##_MASK) +#define LTR55X_REG_GET(reg, field, value) \ + (((value) & reg##_##field##_MASK) >> reg##_##field##_SHIFT) + +struct ltr55x_config { + const struct i2c_dt_spec bus; + uint8_t gain; + uint8_t integration_time; + uint8_t measurement_rate; +}; + +struct ltr55x_data { + uint16_t ch0; + uint16_t ch1; +}; + +#endif /* ZEPHYR_DRIVERS_SENSOR_LITEON_LTR55X_LTR55X_H_ */ From ab6699c03ab0cc88bc3c7f69475c6173562de90c Mon Sep 17 00:00:00 2001 From: TOKITA Hiroshi Date: Mon, 29 Dec 2025 09:08:04 +0900 Subject: [PATCH 1884/3659] dts: bindings: liteon: ltr329: deprecate legacy ALS props To add support for LTR553, we will migrate device-tree properties to new ones and mark the old ones as deprecated. We will also refactor variable names accordingly. Signed-off-by: TOKITA Hiroshi --- drivers/sensor/liteon/ltr55x/ltr55x.c | 78 +++++++++++++++----------- drivers/sensor/liteon/ltr55x/ltr55x.h | 52 ++++++++++------- dts/bindings/sensor/liteon,ltr329.yaml | 37 +++++++++++- 3 files changed, 112 insertions(+), 55 deletions(-) diff --git a/drivers/sensor/liteon/ltr55x/ltr55x.c b/drivers/sensor/liteon/ltr55x/ltr55x.c index 346fcdf40556..a0398854b091 100644 --- a/drivers/sensor/liteon/ltr55x/ltr55x.c +++ b/drivers/sensor/liteon/ltr55x/ltr55x.c @@ -42,12 +42,13 @@ static int ltr55x_check_device_id(const struct i2c_dt_spec *bus) return 0; } -static int ltr55x_init_registers(const struct i2c_dt_spec *bus, const struct ltr55x_config *cfg) +static int ltr55x_init_als_registers(const struct ltr55x_config *cfg) { - const uint8_t control_reg = LTR55X_REG_SET(LTR55X_ALS_CONTR, MODE, 1) | - LTR55X_REG_SET(LTR55X_ALS_CONTR, GAIN, cfg->gain); - const uint8_t meas_reg = LTR55X_REG_SET(LTR55X_MEAS_RATE, REPEAT, cfg->measurement_rate) | - LTR55X_REG_SET(LTR55X_MEAS_RATE, INT_TIME, cfg->integration_time); + const struct i2c_dt_spec *bus = &cfg->bus; + const uint8_t control_reg = LTR55X_REG_SET(ALS_CONTR, MODE, LTR553_ALS_CONTR_MODE_ACTIVE) | + LTR55X_REG_SET(ALS_CONTR, GAIN, cfg->als_gain); + const uint8_t meas_reg = LTR55X_REG_SET(MEAS_RATE, REPEAT, cfg->als_measurement_rate) | + LTR55X_REG_SET(MEAS_RATE, INT_TIME, cfg->als_integration_time); uint8_t buffer; int rc; @@ -69,14 +70,14 @@ static int ltr55x_init_registers(const struct i2c_dt_spec *bus, const struct ltr LOG_ERR("Failed to read back MEAS_RATE register"); return rc; } - if (LTR55X_REG_GET(LTR55X_MEAS_RATE, REPEAT, buffer) != cfg->measurement_rate) { - LOG_ERR("Measurement rate mismatch: expected %u, got %u", cfg->measurement_rate, - (uint8_t)LTR55X_REG_GET(LTR55X_MEAS_RATE, REPEAT, buffer)); + if (LTR55X_REG_GET(MEAS_RATE, REPEAT, buffer) != cfg->als_measurement_rate) { + LOG_ERR("Measurement rate mismatch: expected %u, got %u", cfg->als_measurement_rate, + (uint8_t)LTR55X_REG_GET(MEAS_RATE, REPEAT, buffer)); return -ENODEV; } - if (LTR55X_REG_GET(LTR55X_MEAS_RATE, INT_TIME, buffer) != cfg->integration_time) { - LOG_ERR("Integration time mismatch: expected %u, got %u", cfg->integration_time, - (uint8_t)LTR55X_REG_GET(LTR55X_MEAS_RATE, INT_TIME, buffer)); + if (LTR55X_REG_GET(MEAS_RATE, INT_TIME, buffer) != cfg->als_integration_time) { + LOG_ERR("Integration time mismatch: expected %u, got %u", cfg->als_integration_time, + (uint8_t)LTR55X_REG_GET(MEAS_RATE, INT_TIME, buffer)); return -ENODEV; } @@ -102,7 +103,7 @@ static int ltr55x_init(const struct device *dev) } /* Init register to enable sensor to active mode */ - rc = ltr55x_init_registers(&cfg->bus, cfg); + rc = ltr55x_init_als_registers(cfg); if (rc < 0) { return rc; } @@ -115,13 +116,13 @@ static int ltr55x_check_data_ready(const struct i2c_dt_spec *bus) uint8_t status; int rc; - rc = i2c_reg_read_byte_dt(bus, LTR55X_ALS_STATUS, &status); + rc = i2c_reg_read_byte_dt(bus, LTR55X_ALS_PS_STATUS, &status); if (rc < 0) { LOG_ERR("Failed to read ALS_STATUS register"); return rc; } - if (!LTR55X_REG_GET(LTR55X_ALS_STATUS, DATA_READY, status)) { + if (!LTR55X_REG_GET(ALS_PS_STATUS, ALS_DATA_STATUS, status)) { LOG_WRN("Data not ready"); return -EBUSY; } @@ -141,8 +142,8 @@ static int ltr55x_read_als_data(const struct i2c_dt_spec *bus, struct ltr55x_dat return rc; } - data->ch1 = sys_get_le16(buff); - data->ch0 = sys_get_le16(buff + 2); + data->als_ch1 = sys_get_le16(buff); + data->als_ch0 = sys_get_le16(buff + 2); return 0; } @@ -212,17 +213,17 @@ static int ltr55x_channel_get(const struct device *dev, enum sensor_channel chan return -ENOTSUP; } - if (ltr55x_get_mapped_gain(cfg->gain, &gain_value) != 0) { + if (ltr55x_get_mapped_gain(cfg->als_gain, &gain_value) != 0) { LOG_ERR("Invalid gain configuration"); return -EINVAL; } - if (ltr55x_get_mapped_int_time(cfg->integration_time, &integration_time_value) != 0) { + if (ltr55x_get_mapped_int_time(cfg->als_integration_time, &integration_time_value) != 0) { LOG_ERR("Invalid integration time configuration"); return -EINVAL; } - if ((data->ch0 == 0) && (data->ch1 == 0)) { + if ((data->als_ch0 == 0) && (data->als_ch1 == 0)) { LOG_WRN("Both channels are zero; cannot compute ratio"); return -EINVAL; } @@ -230,14 +231,15 @@ static int ltr55x_channel_get(const struct device *dev, enum sensor_channel chan /* Calculate lux value according to the appendix A of the datasheet. */ uint64_t lux; /* The calculation is scaled by 1000000 to avoid floating point. */ - uint64_t scaled_ratio = (data->ch1 * UINT64_C(1000000)) / (uint64_t)(data->ch0 + data->ch1); + uint64_t scaled_ratio = + (data->als_ch1 * UINT64_C(1000000)) / (uint64_t)(data->als_ch0 + data->als_ch1); if (scaled_ratio < UINT64_C(450000)) { - lux = (UINT64_C(1774300) * data->ch0 + UINT64_C(1105900) * data->ch1); + lux = (UINT64_C(1774300) * data->als_ch0 + UINT64_C(1105900) * data->als_ch1); } else if (scaled_ratio < UINT64_C(640000)) { - lux = (UINT64_C(4278500) * data->ch0 - UINT64_C(1954800) * data->ch1); + lux = (UINT64_C(4278500) * data->als_ch0 - UINT64_C(1954800) * data->als_ch1); } else if (scaled_ratio < UINT64_C(850000)) { - lux = (UINT64_C(592600) * data->ch0 + UINT64_C(118500) * data->ch1); + lux = (UINT64_C(592600) * data->als_ch0 + UINT64_C(118500) * data->als_ch1); } else { LOG_WRN("Invalid ratio: %llu", scaled_ratio); return -EINVAL; @@ -260,16 +262,26 @@ static DEVICE_API(sensor, ltr55x_driver_api) = { .channel_get = ltr55x_channel_get, }; -#define DEFINE_LTR55X(_num) \ - static struct ltr55x_data ltr55x_data_##_num; \ - static const struct ltr55x_config ltr55x_config_##_num = { \ - .bus = I2C_DT_SPEC_INST_GET(_num), \ - .gain = DT_INST_PROP(_num, gain), \ - .integration_time = DT_INST_PROP(_num, integration_time), \ - .measurement_rate = DT_INST_PROP(_num, measurement_rate), \ - }; \ - SENSOR_DEVICE_DT_INST_DEFINE(_num, ltr55x_init, NULL, <r55x_data_##_num, \ - <r55x_config_##_num, POST_KERNEL, \ +#define LTR55X_ALS_GAIN_REG(n) \ + COND_CODE_1(DT_NODE_HAS_PROP(n, gain), (DT_PROP(n, gain)), \ + (UTIL_CAT(LTR55X_ALS_GAIN_VALUE_, DT_PROP_OR(n, als_gain, 1)))) +#define LTR55X_ALS_INT_TIME_REG(n) \ + COND_CODE_1(DT_NODE_HAS_PROP(n, integration_time), (DT_PROP(n, integration_time)), \ + (DT_ENUM_IDX_OR(n, als_integration_time, 0))) +#define LTR55X_ALS_MEAS_RATE_REG(n) \ + COND_CODE_1(DT_NODE_HAS_PROP(n, measurement_rate), (DT_PROP(n, measurement_rate)), \ + (DT_ENUM_IDX_OR(n, als_measurement_rate, 3))) + +#define DEFINE_LTR55X(_num) \ + static struct ltr55x_data ltr55x_data_##_num; \ + static const struct ltr55x_config ltr55x_config_##_num = { \ + .bus = I2C_DT_SPEC_INST_GET(_num), \ + .als_gain = LTR55X_ALS_GAIN_REG(_num), \ + .als_integration_time = LTR55X_ALS_INT_TIME_REG(_num), \ + .als_measurement_rate = LTR55X_ALS_MEAS_RATE_REG(_num), \ + }; \ + SENSOR_DEVICE_DT_INST_DEFINE(_num, ltr55x_init, NULL, <r55x_data_##_num, \ + <r55x_config_##_num, POST_KERNEL, \ CONFIG_SENSOR_INIT_PRIORITY, <r55x_driver_api); DT_INST_FOREACH_STATUS_OKAY(DEFINE_LTR55X) diff --git a/drivers/sensor/liteon/ltr55x/ltr55x.h b/drivers/sensor/liteon/ltr55x/ltr55x.h index e37e020ad5e9..c97d0403ffd5 100644 --- a/drivers/sensor/liteon/ltr55x/ltr55x.h +++ b/drivers/sensor/liteon/ltr55x/ltr55x.h @@ -24,7 +24,7 @@ #define LTR55X_ALS_DATA_CH1_1 0x89 #define LTR55X_ALS_DATA_CH0_0 0x8A #define LTR55X_ALS_DATA_CH0_1 0x8B -#define LTR55X_ALS_STATUS 0x8C +#define LTR55X_ALS_PS_STATUS 0x8C /* Bit masks and shifts for ALS_CONTR register */ #define LTR55X_ALS_CONTR_MODE_MASK BIT(0) @@ -51,14 +51,20 @@ #define LTR55X_MANUFAC_ID_IDENTIFICATION_SHIFT 0 /* Bit masks and shifts for ALS_STATUS register */ -#define LTR55X_ALS_STATUS_DATA_MASK GENMASK(7, 0) -#define LTR55X_ALS_STATUS_DATA_SHIFT 0 -#define LTR55X_ALS_STATUS_DATA_READY_MASK BIT(2) -#define LTR55X_ALS_STATUS_DATA_READY_SHIFT 2 -#define LTR55X_ALS_STATUS_DATA_GAIN_MASK GENMASK(6, 4) -#define LTR55X_ALS_STATUS_DATA_GAIN_SHIFT 4 -#define LTR55X_ALS_STATUS_DATA_VALID_MASK BIT(7) -#define LTR55X_ALS_STATUS_DATA_VALID_SHIFT 7 +#define LTR55X_ALS_PS_STATUS_PS_DATA_STATUS_MASK BIT(0) +#define LTR55X_ALS_PS_STATUS_PS_DATA_STATUS_SHIFT 0 +#define LTR55X_ALS_PS_STATUS_PS_INTR_STATUS_MASK BIT(1) +#define LTR55X_ALS_PS_STATUS_PS_INTR_STATUS_SHIFT 1 +#define LTR55X_ALS_PS_STATUS_ALS_DATA_STATUS_MASK BIT(2) +#define LTR55X_ALS_PS_STATUS_ALS_DATA_STATUS_SHIFT 2 +#define LTR55X_ALS_PS_STATUS_ALS_INTR_STATUS_MASK BIT(3) +#define LTR55X_ALS_PS_STATUS_ALS_INTR_STATUS_SHIFT 3 +#define LTR55X_ALS_PS_STATUS_ALS_GAIN_MASK GENMASK(6, 4) +#define LTR55X_ALS_PS_STATUS_ALS_GAIN_SHIFT 4 +#define LTR55X_ALS_PS_STATUS_ALS_DATA_VALID_MASK BIT(7) +#define LTR55X_ALS_PS_STATUS_ALS_DATA_VALID_SHIFT 7 + +#define LTR553_ALS_CONTR_MODE_ACTIVE 0x1 /* Expected sensor IDs */ #define LTR329_PART_ID_VALUE 0xA0 @@ -68,22 +74,30 @@ #define LTR55X_INIT_STARTUP_MS 100 #define LTR55X_WAKEUP_FROM_STANDBY_MS 10 +/* Convert als-gain value in device-tree to register values */ +#define LTR55X_ALS_GAIN_VALUE_1 0 +#define LTR55X_ALS_GAIN_VALUE_2 1 +#define LTR55X_ALS_GAIN_VALUE_4 2 +#define LTR55X_ALS_GAIN_VALUE_8 3 +#define LTR55X_ALS_GAIN_VALUE_48 6 +#define LTR55X_ALS_GAIN_VALUE_96 7 + /* Macros to set and get register fields */ -#define LTR55X_REG_SET(reg, field, value) \ - (((value) << reg##_##field##_SHIFT) & reg##_##field##_MASK) -#define LTR55X_REG_GET(reg, field, value) \ - (((value) & reg##_##field##_MASK) >> reg##_##field##_SHIFT) +#define LTR55X_REG_SET(reg, field, value) \ + (((value) << LTR55X_##reg##_##field##_SHIFT) & LTR55X_##reg##_##field##_MASK) +#define LTR55X_REG_GET(reg, field, value) \ + (((value) & LTR55X_##reg##_##field##_MASK) >> LTR55X_##reg##_##field##_SHIFT) struct ltr55x_config { - const struct i2c_dt_spec bus; - uint8_t gain; - uint8_t integration_time; - uint8_t measurement_rate; + const struct i2c_dt_spec bus; + uint8_t als_gain; + uint8_t als_integration_time; + uint8_t als_measurement_rate; }; struct ltr55x_data { - uint16_t ch0; - uint16_t ch1; + uint16_t als_ch0; + uint16_t als_ch1; }; #endif /* ZEPHYR_DRIVERS_SENSOR_LITEON_LTR55X_LTR55X_H_ */ diff --git a/dts/bindings/sensor/liteon,ltr329.yaml b/dts/bindings/sensor/liteon,ltr329.yaml index 66db8bfe9826..f0b829720fcc 100644 --- a/dts/bindings/sensor/liteon,ltr329.yaml +++ b/dts/bindings/sensor/liteon,ltr329.yaml @@ -10,7 +10,7 @@ include: [sensor-device.yaml, i2c-device.yaml] properties: gain: type: int - default: 0 + deprecated: true description: | This parameter adjusts the ADC gain factor, impacting the sensor's light sensitivity range. The default setting, corresponding to the @@ -26,7 +26,7 @@ properties: integration-time: type: int - default: 0 + deprecated: true description: | ALS Integration Time is the measurement time for each ALS cycle. Default value is a register reset value (100ms). @@ -43,7 +43,7 @@ properties: measurement-rate: type: int - default: 3 + deprecated: true description: | ALS Measurement Rate is the rate at which the sensor takes measurements in the active mode. This is the interval @@ -61,3 +61,34 @@ properties: - 4 # 1000ms - 5 # 2000ms enum: [0, 1, 2, 3, 4, 5] + + als-gain: + type: int + default: 1 + enum: [1, 2, 4, 8, 48, 96] + description: | + This parameter adjusts the ADC gain factor, impacting the sensor's + light sensitivity range. The default setting, corresponding to the + register reset value (1X). + + als-integration-time: + type: int + default: 100 + enum: [100, 50, 200, 400, 150, 250, 300, 350] + description: | + ALS Integration Time is the measurement time for each ALS cycle. + Default value is a register reset value (100ms). + + als-measurement-rate: + type: int + default: 500 + enum: [50, 100, 200, 500, 1000, 2000] + description: | + ALS Measurement Rate is the rate at which the sensor + takes measurements in the active mode. This is the interval + between ALS_DATA registers update. ALS Measurement Repeat Rate + must be set to be equal or larger than the Integration Time. + If ALS Measurement Repeat Rate is set to be smaller than + ALS Integration Time, it will automatically be reset to be + equal to ALS Integration Time by the IC internally. Default value + is a register reset value (500ms). From 717bc816b90e928078ced0f53f79d9ba04941916 Mon Sep 17 00:00:00 2001 From: TOKITA Hiroshi Date: Sat, 3 Jan 2026 16:28:52 +0900 Subject: [PATCH 1885/3659] drivers: sensor: liteon: ltr553: Add support for LTR553 Extends the LTR329 driver to support the LTR553. Signed-off-by: TOKITA Hiroshi --- drivers/sensor/liteon/ltr55x/Kconfig | 9 +- drivers/sensor/liteon/ltr55x/ltr55x.c | 240 +++++++++++++++++++++---- drivers/sensor/liteon/ltr55x/ltr55x.h | 100 +++++++++-- dts/bindings/sensor/liteon,ltr553.yaml | 81 +++++++++ 4 files changed, 378 insertions(+), 52 deletions(-) create mode 100644 dts/bindings/sensor/liteon,ltr553.yaml diff --git a/drivers/sensor/liteon/ltr55x/Kconfig b/drivers/sensor/liteon/ltr55x/Kconfig index fa8a37d7db30..161913202f6f 100644 --- a/drivers/sensor/liteon/ltr55x/Kconfig +++ b/drivers/sensor/liteon/ltr55x/Kconfig @@ -1,12 +1,13 @@ -# Lite-On LTR-329 light sensor driver configuration +# Lite-On LTR-329/LTR-553 sensor driver configuration # Copyright (c) 2025 Konrad Sikora # SPDX-License-Identifier: Apache-2.0 config LTR55X - bool "LiteOn LTR-329 Ambient light sensor support" + bool "LiteOn LTR-329/LTR-553 ambient light/proximity sensor support" default y - depends on DT_HAS_LITEON_LTR329_ENABLED + depends on DT_HAS_LITEON_LTR329_ENABLED || DT_HAS_LITEON_LTR553_ENABLED select I2C help - Enable driver for Lite-On LTR-329 ambient light sensor. + Enable driver for Lite-On LTR-329 ambient light sensor and + LTR-55X ambient light plus proximity sensor. diff --git a/drivers/sensor/liteon/ltr55x/ltr55x.c b/drivers/sensor/liteon/ltr55x/ltr55x.c index a0398854b091..f51607c5812d 100644 --- a/drivers/sensor/liteon/ltr55x/ltr55x.c +++ b/drivers/sensor/liteon/ltr55x/ltr55x.c @@ -4,8 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#define DT_DRV_COMPAT liteon_ltr329 - #include "ltr55x.h" #include @@ -13,8 +11,9 @@ LOG_MODULE_REGISTER(LTR55X, CONFIG_SENSOR_LOG_LEVEL); -static int ltr55x_check_device_id(const struct i2c_dt_spec *bus) +static int ltr55x_check_device_id(const struct ltr55x_config *cfg) { + const struct i2c_dt_spec *bus = &cfg->bus; uint8_t id; int rc; @@ -23,8 +22,9 @@ static int ltr55x_check_device_id(const struct i2c_dt_spec *bus) LOG_ERR("Failed to read PART_ID"); return rc; } - if (id != LTR329_PART_ID_VALUE) { - LOG_ERR("PART_ID mismatch: expected 0x%02X, got 0x%02X", LTR329_PART_ID_VALUE, id); + + if (id != cfg->part_id) { + LOG_ERR("PART_ID mismatch: expected 0x%02X, got 0x%02X", cfg->part_id, id); return -ENODEV; } @@ -42,10 +42,55 @@ static int ltr55x_check_device_id(const struct i2c_dt_spec *bus) return 0; } -static int ltr55x_init_als_registers(const struct ltr55x_config *cfg) +static int ltr55x_init_interrupt_registers(const struct device *dev) +{ + const struct ltr55x_config *cfg = dev->config; + const struct i2c_dt_spec *bus = &cfg->bus; + struct ltr55x_data *data = dev->data; + uint8_t buf[6]; + int rc; + + sys_put_le16(data->ps_upper_threshold, &buf[0]); + sys_put_le16(data->ps_lower_threshold, &buf[2]); + sys_put_be16(data->ps_offset, &buf[4]); + + rc = i2c_burst_write_dt(bus, LTR55X_PS_THRES_UP_0, buf, 6); + if (rc < 0) { + LOG_ERR("Failed to set PS threshold/offset: %d", rc); + return rc; + } + + return 0; +} + +static int ltr55x_init_ps_registers(const struct device *dev) +{ + const struct ltr55x_config *cfg = dev->config; + const struct i2c_dt_spec *bus = &cfg->bus; + const uint8_t ps_contr = LTR55X_REG_SET(PS_CONTR, MODE, LTR55X_PS_CONTR_MODE_ACTIVE) | + LTR55X_REG_SET(PS_CONTR, SAT_IND, cfg->ps_saturation_indicator); + const uint8_t ps_led = LTR55X_REG_SET(PS_LED, PULSE_FREQ, cfg->ps_led_pulse_freq) | + LTR55X_REG_SET(PS_LED, DUTY_CYCLE, cfg->ps_led_duty_cycle) | + LTR55X_REG_SET(PS_LED, CURRENT, cfg->ps_led_current); + const uint8_t ps_n_pulses = LTR55X_REG_SET(PS_N_PULSES, COUNT, cfg->ps_n_pulses); + const uint8_t ps_meas_rate = LTR55X_REG_SET(PS_MEAS_RATE, RATE, cfg->ps_measurement_rate); + const uint8_t buf[] = {ps_contr, ps_led, ps_n_pulses, ps_meas_rate}; + int rc; + + rc = i2c_burst_write_dt(bus, LTR55X_PS_CONTR, buf, sizeof(buf)); + if (rc < 0) { + LOG_ERR("Failed to set PS registers"); + return rc; + } + + return 0; +} + +static int ltr55x_init_als_registers(const struct device *dev) { + const struct ltr55x_config *cfg = dev->config; const struct i2c_dt_spec *bus = &cfg->bus; - const uint8_t control_reg = LTR55X_REG_SET(ALS_CONTR, MODE, LTR553_ALS_CONTR_MODE_ACTIVE) | + const uint8_t control_reg = LTR55X_REG_SET(ALS_CONTR, MODE, LTR55X_ALS_CONTR_MODE_ACTIVE) | LTR55X_REG_SET(ALS_CONTR, GAIN, cfg->als_gain); const uint8_t meas_reg = LTR55X_REG_SET(MEAS_RATE, REPEAT, cfg->als_measurement_rate) | LTR55X_REG_SET(MEAS_RATE, INT_TIME, cfg->als_integration_time); @@ -97,13 +142,25 @@ static int ltr55x_init(const struct device *dev) /* Wait for sensor startup */ k_sleep(K_MSEC(LTR55X_INIT_STARTUP_MS)); - rc = ltr55x_check_device_id(&cfg->bus); + rc = ltr55x_check_device_id(cfg); if (rc < 0) { return rc; } + if (cfg->part_id == LTR55X_PART_ID_VALUE) { + rc = ltr55x_init_interrupt_registers(dev); + if (rc < 0) { + return rc; + } + + rc = ltr55x_init_ps_registers(dev); + if (rc < 0) { + return rc; + } + } + /* Init register to enable sensor to active mode */ - rc = ltr55x_init_als_registers(cfg); + rc = ltr55x_init_als_registers(dev); if (rc < 0) { return rc; } @@ -111,8 +168,12 @@ static int ltr55x_init(const struct device *dev) return 0; } -static int ltr55x_check_data_ready(const struct i2c_dt_spec *bus) +static int ltr55x_check_data_ready(const struct ltr55x_config *cfg, enum sensor_channel chan) { + const struct i2c_dt_spec *bus = &cfg->bus; + const bool need_als = (chan == SENSOR_CHAN_ALL) || (chan == SENSOR_CHAN_LIGHT); + const bool need_ps = (cfg->part_id == LTR55X_PART_ID_VALUE) && + ((chan == SENSOR_CHAN_ALL) || (chan == SENSOR_CHAN_PROX)); uint8_t status; int rc; @@ -122,48 +183,78 @@ static int ltr55x_check_data_ready(const struct i2c_dt_spec *bus) return rc; } - if (!LTR55X_REG_GET(ALS_PS_STATUS, ALS_DATA_STATUS, status)) { - LOG_WRN("Data not ready"); + if (need_als && !LTR55X_REG_GET(ALS_PS_STATUS, ALS_DATA_STATUS, status)) { + LOG_WRN("ALS data not ready"); + return -EBUSY; + } + + if (need_ps && !LTR55X_REG_GET(ALS_PS_STATUS, PS_DATA_STATUS, status)) { + LOG_WRN("PS data not ready"); return -EBUSY; } return 0; } -static int ltr55x_read_als_data(const struct i2c_dt_spec *bus, struct ltr55x_data *data) +static int ltr55x_read_data(const struct ltr55x_config *cfg, enum sensor_channel chan, + struct ltr55x_data *data) { + const struct i2c_dt_spec *bus = &cfg->bus; + const bool need_als = (chan == SENSOR_CHAN_ALL) || (chan == SENSOR_CHAN_LIGHT); + const bool need_ps = (cfg->part_id == LTR55X_PART_ID_VALUE) && + ((chan == SENSOR_CHAN_ALL) || (chan == SENSOR_CHAN_PROX)); + const size_t read_als_ps = (LTR55X_PS_DATA1 + 1) - LTR55X_ALS_DATA_CH1_0; + const size_t read_als_only = (LTR55X_ALS_DATA_CH0_1 + 1) - LTR55X_ALS_DATA_CH1_0; + const size_t read_size = + (cfg->part_id == LTR55X_PART_ID_VALUE) ? read_als_ps : read_als_only; uint8_t reg = LTR55X_ALS_DATA_CH1_0; - uint8_t buff[4]; + uint8_t buff[read_als_ps]; int rc; - rc = i2c_write_read_dt(bus, ®, sizeof(reg), buff, sizeof(buff)); + rc = i2c_write_read_dt(bus, ®, sizeof(reg), buff, read_size); if (rc < 0) { LOG_ERR("Failed to read ALS data registers"); return rc; } - data->als_ch1 = sys_get_le16(buff); - data->als_ch0 = sys_get_le16(buff + 2); + if (need_als) { + data->als_ch1 = sys_get_le16(buff); + data->als_ch0 = sys_get_le16(buff + 2); + } + + if (need_ps) { + data->ps_ch0 = sys_get_le16(buff + 5) & LTR55X_PS_DATA_MASK; + } return 0; } +static bool ltr55x_is_channel_supported(const struct ltr55x_config *cfg, enum sensor_channel chan) +{ + if (cfg->part_id == LTR55X_PART_ID_VALUE) { + return (chan == SENSOR_CHAN_ALL) || (chan == SENSOR_CHAN_LIGHT) || + (chan == SENSOR_CHAN_PROX); + } + + return (chan == SENSOR_CHAN_ALL) || (chan == SENSOR_CHAN_LIGHT); +} + static int ltr55x_sample_fetch(const struct device *dev, enum sensor_channel chan) { const struct ltr55x_config *cfg = dev->config; struct ltr55x_data *data = dev->data; int rc; - if ((chan != SENSOR_CHAN_ALL) && (chan != SENSOR_CHAN_LIGHT)) { + if (!ltr55x_is_channel_supported(cfg, chan)) { return -ENOTSUP; } - rc = ltr55x_check_data_ready(&cfg->bus); + rc = ltr55x_check_data_ready(cfg, chan); if (rc < 0) { return rc; } - rc = ltr55x_read_als_data(&cfg->bus, data); + rc = ltr55x_read_data(cfg, chan, data); if (rc < 0) { return rc; } @@ -201,18 +292,13 @@ static int ltr55x_get_mapped_int_time(const uint8_t reg_val, uint8_t *const outp return -EINVAL; } -static int ltr55x_channel_get(const struct device *dev, enum sensor_channel chan, - struct sensor_value *val) +static int ltr55x_channel_light_get(const struct device *dev, struct sensor_value *val) { - const struct ltr55x_data *data = dev->data; const struct ltr55x_config *cfg = dev->config; + struct ltr55x_data *data = dev->data; uint8_t gain_value; uint8_t integration_time_value; - if (chan != SENSOR_CHAN_LIGHT) { - return -ENOTSUP; - } - if (ltr55x_get_mapped_gain(cfg->als_gain, &gain_value) != 0) { LOG_ERR("Invalid gain configuration"); return -EINVAL; @@ -257,6 +343,62 @@ static int ltr55x_channel_get(const struct device *dev, enum sensor_channel chan return 0; } +static int ltr55x_channel_proximity_get(const struct device *dev, struct sensor_value *val) +{ + const struct ltr55x_config *cfg = dev->config; + struct ltr55x_data *data = dev->data; + + if (cfg->part_id != LTR55X_PART_ID_VALUE) { + return -ENOTSUP; + } + + LOG_DBG("proximity: state=%d data: %d L-H: %d - %d", data->proximity_state, data->ps_ch0, + data->ps_lower_threshold, data->ps_upper_threshold); + + if (data->proximity_state) { + if (data->ps_ch0 <= data->ps_lower_threshold) { + data->proximity_state = false; + } + } else { + if (data->ps_ch0 >= data->ps_upper_threshold) { + data->proximity_state = true; + } + } + + val->val1 = data->proximity_state ? 1 : 0; + val->val2 = 0; + + return 0; +} + +static int ltr55x_channel_get(const struct device *dev, enum sensor_channel chan, + struct sensor_value *val) +{ + const struct ltr55x_config *cfg = dev->config; + int ret = -ENOTSUP; + + if (!ltr55x_is_channel_supported(cfg, chan)) { + return -ENOTSUP; + } + + if (chan == SENSOR_CHAN_LIGHT || chan == SENSOR_CHAN_ALL) { + ret = ltr55x_channel_light_get(dev, val); + + if (ret < 0) { + return ret; + } + } + + if (chan == SENSOR_CHAN_PROX || chan == SENSOR_CHAN_ALL) { + ret = ltr55x_channel_proximity_get(dev, val); + if (ret < 0) { + return ret; + } + } + + return ret; +} + static DEVICE_API(sensor, ltr55x_driver_api) = { .sample_fetch = ltr55x_sample_fetch, .channel_get = ltr55x_channel_get, @@ -272,16 +414,38 @@ static DEVICE_API(sensor, ltr55x_driver_api) = { COND_CODE_1(DT_NODE_HAS_PROP(n, measurement_rate), (DT_PROP(n, measurement_rate)), \ (DT_ENUM_IDX_OR(n, als_measurement_rate, 3))) -#define DEFINE_LTR55X(_num) \ - static struct ltr55x_data ltr55x_data_##_num; \ - static const struct ltr55x_config ltr55x_config_##_num = { \ - .bus = I2C_DT_SPEC_INST_GET(_num), \ - .als_gain = LTR55X_ALS_GAIN_REG(_num), \ - .als_integration_time = LTR55X_ALS_INT_TIME_REG(_num), \ - .als_measurement_rate = LTR55X_ALS_MEAS_RATE_REG(_num), \ +#define DEFINE_LTRXXX(node_id, partid) \ + BUILD_ASSERT(DT_PROP_OR(node_id, ps_offset, 0) <= LTR55X_PS_DATA_MAX); \ + BUILD_ASSERT(DT_PROP_OR(node_id, ps_upper_threshold, LTR55X_PS_DATA_MASK) <= \ + LTR55X_PS_DATA_MASK); \ + BUILD_ASSERT(DT_PROP_OR(node_id, ps_lower_threshold, 0) <= LTR55X_PS_DATA_MAX); \ + BUILD_ASSERT(DT_PROP_OR(node_id, ps_lower_threshold, 0) <= \ + DT_PROP_OR(node_id, ps_upper_threshold, LTR55X_PS_DATA_MAX)); \ + static struct ltr55x_data ltr55x_data_##node_id = { \ + .ps_offset = DT_PROP_OR(node_id, ps_offset, 0), \ + .ps_upper_threshold = DT_PROP_OR(node_id, ps_upper_threshold, LTR55X_PS_DATA_MAX), \ + .ps_lower_threshold = DT_PROP_OR(node_id, ps_lower_threshold, 0), \ }; \ - SENSOR_DEVICE_DT_INST_DEFINE(_num, ltr55x_init, NULL, <r55x_data_##_num, \ - <r55x_config_##_num, POST_KERNEL, \ - CONFIG_SENSOR_INIT_PRIORITY, <r55x_driver_api); + static const struct ltr55x_config ltr55x_config_##node_id = { \ + .bus = I2C_DT_SPEC_GET(node_id), \ + .part_id = partid, \ + .als_gain = LTR55X_ALS_GAIN_REG(node_id), \ + .als_integration_time = LTR55X_ALS_INT_TIME_REG(node_id), \ + .als_measurement_rate = LTR55X_ALS_MEAS_RATE_REG(node_id), \ + .ps_led_pulse_freq = DT_ENUM_IDX_OR(node_id, ps_led_pulse_frequency, 3), \ + .ps_led_duty_cycle = DT_ENUM_IDX_OR(node_id, ps_led_duty_cycle, 3), \ + .ps_led_current = DT_ENUM_IDX_OR(node_id, ps_led_current, 4), \ + .ps_n_pulses = DT_PROP_OR(node_id, ps_n_pulses, 1), \ + .ps_measurement_rate = UTIL_CAT(LTR55X_PS_MEASUREMENT_RATE_VALUE_, \ + DT_PROP_OR(node_id, ps_measurement_rate, 100)), \ + .ps_saturation_indicator = DT_PROP_OR(node_id, ps_saturation_indicator, false), \ + }; \ + SENSOR_DEVICE_DT_DEFINE(node_id, ltr55x_init, NULL, <r55x_data_##node_id, \ + <r55x_config_##node_id, POST_KERNEL, \ + CONFIG_SENSOR_INIT_PRIORITY, <r55x_driver_api); + +#define DEFINE_LTR329(node_id) DEFINE_LTRXXX(node_id, LTR329_PART_ID_VALUE) +#define DEFINE_LTR55X(node_id) DEFINE_LTRXXX(node_id, LTR55X_PART_ID_VALUE) -DT_INST_FOREACH_STATUS_OKAY(DEFINE_LTR55X) +DT_FOREACH_STATUS_OKAY(liteon_ltr329, DEFINE_LTR329) +DT_FOREACH_STATUS_OKAY(liteon_ltr553, DEFINE_LTR55X) diff --git a/drivers/sensor/liteon/ltr55x/ltr55x.h b/drivers/sensor/liteon/ltr55x/ltr55x.h index c97d0403ffd5..eb7acb953dc2 100644 --- a/drivers/sensor/liteon/ltr55x/ltr55x.h +++ b/drivers/sensor/liteon/ltr55x/ltr55x.h @@ -16,15 +16,33 @@ #include /* Register addresses */ -#define LTR55X_ALS_CONTR 0x80 -#define LTR55X_MEAS_RATE 0x85 -#define LTR55X_PART_ID 0x86 -#define LTR55X_MANUFAC_ID 0x87 -#define LTR55X_ALS_DATA_CH1_0 0x88 -#define LTR55X_ALS_DATA_CH1_1 0x89 -#define LTR55X_ALS_DATA_CH0_0 0x8A -#define LTR55X_ALS_DATA_CH0_1 0x8B -#define LTR55X_ALS_PS_STATUS 0x8C +#define LTR55X_ALS_CONTR 0x80 +#define LTR55X_PS_CONTR 0x81 +#define LTR55X_PS_LED 0x82 +#define LTR55X_PS_N_PULSES 0x83 +#define LTR55X_PS_MEAS_RATE 0x84 +#define LTR55X_MEAS_RATE 0x85 +#define LTR55X_PART_ID 0x86 +#define LTR55X_MANUFAC_ID 0x87 +#define LTR55X_ALS_DATA_CH1_0 0x88 +#define LTR55X_ALS_DATA_CH1_1 0x89 +#define LTR55X_ALS_DATA_CH0_0 0x8A +#define LTR55X_ALS_DATA_CH0_1 0x8B +#define LTR55X_ALS_PS_STATUS 0x8C +#define LTR55X_PS_DATA0 0x8D +#define LTR55X_PS_DATA1 0x8E +#define LTR55X_INTERRUPT 0x8F +#define LTR55X_PS_THRES_UP_0 0x90 +#define LTR55X_PS_THRES_UP_1 0x91 +#define LTR55X_PS_THRES_LOW_0 0x92 +#define LTR55X_PS_THRES_LOW_1 0x93 +#define LTR55X_PS_OFFSET_1 0x94 +#define LTR55X_PS_OFFSET_0 0x95 +#define LTR55X_ALS_THRES_UP_0 0x97 +#define LTR55X_ALS_THRES_UP_1 0x98 +#define LTR55X_ALS_THRES_LOW_0 0x99 +#define LTR55X_ALS_THRES_LOW_1 0x9A +#define LTR55X_INTERRUPT_PERSIST 0x9E /* Bit masks and shifts for ALS_CONTR register */ #define LTR55X_ALS_CONTR_MODE_MASK BIT(0) @@ -40,6 +58,28 @@ #define LTR55X_MEAS_RATE_INT_TIME_MASK GENMASK(5, 3) #define LTR55X_MEAS_RATE_INT_TIME_SHIFT 3 +/* Bit masks and shift for PS_CONTR register */ +#define LTR55X_PS_CONTR_MODE_MASK GENMASK(1, 0) +#define LTR55X_PS_CONTR_MODE_SHIFT 0 +#define LTR55X_PS_CONTR_SAT_IND_MASK BIT(5) +#define LTR55X_PS_CONTR_SAT_IND_SHIFT 5 + +/* Bit masks and shift for PS_LED register */ +#define LTR55X_PS_LED_PULSE_FREQ_MASK GENMASK(7, 5) +#define LTR55X_PS_LED_PULSE_FREQ_SHIFT 5 +#define LTR55X_PS_LED_DUTY_CYCLE_MASK GENMASK(4, 3) +#define LTR55X_PS_LED_DUTY_CYCLE_SHIFT 3 +#define LTR55X_PS_LED_CURRENT_MASK GENMASK(2, 0) +#define LTR55X_PS_LED_CURRENT_SHIFT 0 + +/* Bit masks and shift for PS_N_PULSES register */ +#define LTR55X_PS_N_PULSES_COUNT_MASK GENMASK(3, 0) +#define LTR55X_PS_N_PULSES_COUNT_SHIFT 0 + +/* Bit masks and shift for PS_MEAS_RATE register */ +#define LTR55X_PS_MEAS_RATE_RATE_MASK GENMASK(3, 0) +#define LTR55X_PS_MEAS_RATE_RATE_SHIFT 0 + /* Bit masks and shifts for PART_ID register */ #define LTR55X_PART_ID_REVISION_MASK GENMASK(3, 0) #define LTR55X_PART_ID_REVISION_SHIFT 0 @@ -64,10 +104,28 @@ #define LTR55X_ALS_PS_STATUS_ALS_DATA_VALID_MASK BIT(7) #define LTR55X_ALS_PS_STATUS_ALS_DATA_VALID_SHIFT 7 -#define LTR553_ALS_CONTR_MODE_ACTIVE 0x1 +/* Bit masks for LTR55X-specific registers */ +#define LTR55X_INTERRUPT_PS_MASK BIT(0) +#define LTR55X_INTERRUPT_PS_SHIFT 0 +#define LTR55X_INTERRUPT_ALS_MASK BIT(1) +#define LTR55X_INTERRUPT_ALS_SHIFT 1 +#define LTR55X_INTERRUPT_POLARITY_MASK BIT(2) +#define LTR55X_INTERRUPT_POLARITY_SHIFT 2 + +#define LTR55X_INTERRUPT_PERSIST_ALS_MASK GENMASK(3, 0) +#define LTR55X_INTERRUPT_PERSIST_ALS_SHIFT 0 +#define LTR55X_INTERRUPT_PERSIST_PS_MASK GENMASK(7, 4) +#define LTR55X_INTERRUPT_PERSIST_PS_SHIFT 4 + +#define LTR55X_PS_DATA_MASK 0x07FF +#define LTR55X_PS_DATA_MAX LTR55X_PS_DATA_MASK + +#define LTR55X_ALS_CONTR_MODE_ACTIVE 0x1 +#define LTR55X_PS_CONTR_MODE_ACTIVE 0x02 /* Expected sensor IDs */ #define LTR329_PART_ID_VALUE 0xA0 +#define LTR55X_PART_ID_VALUE 0x92 #define LTR55X_MANUFACTURER_ID_VALUE 0x05 /* Timing definitions - refer to LTR-329ALS-01 datasheet */ @@ -82,6 +140,16 @@ #define LTR55X_ALS_GAIN_VALUE_48 6 #define LTR55X_ALS_GAIN_VALUE_96 7 +/* Convert ps-measurement value in device-tree to register values */ +#define LTR55X_PS_MEASUREMENT_RATE_VALUE_50 0 +#define LTR55X_PS_MEASUREMENT_RATE_VALUE_70 1 +#define LTR55X_PS_MEASUREMENT_RATE_VALUE_100 2 +#define LTR55X_PS_MEASUREMENT_RATE_VALUE_200 3 +#define LTR55X_PS_MEASUREMENT_RATE_VALUE_500 4 +#define LTR55X_PS_MEASUREMENT_RATE_VALUE_1000 5 +#define LTR55X_PS_MEASUREMENT_RATE_VALUE_2000 6 +#define LTR55X_PS_MEASUREMENT_RATE_VALUE_10 8 + /* Macros to set and get register fields */ #define LTR55X_REG_SET(reg, field, value) \ (((value) << LTR55X_##reg##_##field##_SHIFT) & LTR55X_##reg##_##field##_MASK) @@ -90,14 +158,26 @@ struct ltr55x_config { const struct i2c_dt_spec bus; + uint8_t part_id; uint8_t als_gain; uint8_t als_integration_time; uint8_t als_measurement_rate; + uint8_t ps_led_pulse_freq; + uint8_t ps_led_duty_cycle; + uint8_t ps_led_current; + uint8_t ps_n_pulses; + uint8_t ps_measurement_rate; + bool ps_saturation_indicator; }; struct ltr55x_data { uint16_t als_ch0; uint16_t als_ch1; + uint16_t ps_ch0; + uint16_t ps_offset; + uint16_t ps_upper_threshold; + uint16_t ps_lower_threshold; + bool proximity_state; }; #endif /* ZEPHYR_DRIVERS_SENSOR_LITEON_LTR55X_LTR55X_H_ */ diff --git a/dts/bindings/sensor/liteon,ltr553.yaml b/dts/bindings/sensor/liteon,ltr553.yaml new file mode 100644 index 000000000000..1941e700c610 --- /dev/null +++ b/dts/bindings/sensor/liteon,ltr553.yaml @@ -0,0 +1,81 @@ +# Copyright (c) 2025 Konrad Sikora +# Copyright (c) 2025 TOKITA Hiroshi +# SPDX-License-Identifier: Apache-2.0 + +description: LiteOn LTR-553 Digital Ambient Light and proximity sensor + +compatible: "liteon,ltr553" + +include: [sensor-device.yaml, i2c-device.yaml] + +properties: + als-gain: + type: int + default: 1 + enum: [1, 2, 4, 8, 48, 96] + description: | + This parameter adjusts the ADC gain factor, impacting the sensor's + light sensitivity range. The default setting, corresponding to the + register reset value (1X). + + als-integration-time: + type: int + default: 100 + enum: [100, 50, 200, 400, 150, 250, 300, 350] + description: | + ALS Integration Time is the measurement time for each ALS cycle. + Default value is a register reset value (100ms). + + als-measurement-rate: + type: int + default: 500 + enum: [50, 100, 200, 500, 1000, 2000] + description: | + ALS Measurement Rate is the rate at which the sensor + takes measurements in the active mode. This is the interval + between ALS_DATA registers update. ALS Measurement Repeat Rate + must be set to be equal or larger than the Integration Time. + If ALS Measurement Repeat Rate is set to be smaller than + ALS Integration Time, it will automatically be reset to be + equal to ALS Integration Time by the IC internally. Default value + is a register reset value (500ms). + + ps-saturation-indicator: + type: boolean + description: | + Enable the PS saturation indicator flag in PS_DATA_1. + + ps-led-pulse-frequency: + type: int + default: 60 + enum: [30, 40, 50, 60, 70, 80, 90, 100] + description: | + PS LED pulse modulation frequency. + + ps-led-duty-cycle: + type: int + default: 100 + enum: [25, 50, 75, 100] + description: | + PS LED duty cycle. + + ps-led-current: + type: int + default: 100 + enum: [5, 10, 20, 50, 100] + description: | + PS LED peak current in milliamperes. + + ps-n-pulses: + type: int + default: 1 + enum: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] + description: | + Number of PS LED pulses emitted per measurement. + + ps-measurement-rate: + type: int + default: 100 + enum: [50, 70, 100, 200, 500, 1000, 2000, 10] + description: | + PS Measurement Repeat Rate is the interval between PS_DATA updates. From 0c506c63006da334e3867d3a8f19f177921a6c06 Mon Sep 17 00:00:00 2001 From: TOKITA Hiroshi Date: Sat, 3 Jan 2026 16:48:18 +0900 Subject: [PATCH 1886/3659] boards: m5stack: cores3: Add LTR 553 sensor configuration Adding configuration for enabling LTR553 ambient light and proximity sensor. Signed-off-by: TOKITA Hiroshi --- boards/m5stack/m5stack_cores3/m5stack_cores3_procpu.dts | 8 ++++++++ dts/bindings/sensor/liteon,ltr553.yaml | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/boards/m5stack/m5stack_cores3/m5stack_cores3_procpu.dts b/boards/m5stack/m5stack_cores3/m5stack_cores3_procpu.dts index 6a1b43d1c6eb..8420e314cb04 100644 --- a/boards/m5stack/m5stack_cores3/m5stack_cores3_procpu.dts +++ b/boards/m5stack/m5stack_cores3/m5stack_cores3_procpu.dts @@ -15,6 +15,8 @@ aliases { accel0 = &bmi270; magn0 = &bmm150; + light-sensor = <r553; + prox-sensor0 = <r553; }; }; @@ -29,6 +31,12 @@ status = "okay"; reg = <0x10>; }; + + ltr553: ltr553@23 { + compatible = "liteon,ltr553"; + reg = <0x23>; + status = "okay"; + }; }; ®ulator { diff --git a/dts/bindings/sensor/liteon,ltr553.yaml b/dts/bindings/sensor/liteon,ltr553.yaml index 1941e700c610..965dbbd49bd3 100644 --- a/dts/bindings/sensor/liteon,ltr553.yaml +++ b/dts/bindings/sensor/liteon,ltr553.yaml @@ -35,7 +35,7 @@ properties: takes measurements in the active mode. This is the interval between ALS_DATA registers update. ALS Measurement Repeat Rate must be set to be equal or larger than the Integration Time. - If ALS Measurement Repeat Rate is set to be smaller than + If ALS Measurement Repeat Rate is set to be smaller than ALS Integration Time, it will automatically be reset to be equal to ALS Integration Time by the IC internally. Default value is a register reset value (500ms). From 523941037c8f364f5fbb7e8b34187e98044dc378 Mon Sep 17 00:00:00 2001 From: TOKITA Hiroshi Date: Wed, 7 Jan 2026 05:58:54 +0900 Subject: [PATCH 1887/3659] tests: sensor: Add `liteon,ltr553` to build_all test suite Enable LTR553 driver testing. Signed-off-by: TOKITA Hiroshi --- tests/drivers/build_all/sensor/i2c.dtsi | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/drivers/build_all/sensor/i2c.dtsi b/tests/drivers/build_all/sensor/i2c.dtsi index 592ffdaf875f..5c47fbf01d01 100644 --- a/tests/drivers/build_all/sensor/i2c.dtsi +++ b/tests/drivers/build_all/sensor/i2c.dtsi @@ -1525,3 +1525,8 @@ test_i2c_ism6hg256x: ism6hg256x@c8 { gyro-range = ; gyro-odr = ; }; + +test_i2c_ltr553: ltr553@c9 { + compatible = "liteon,ltr553"; + reg = <0xc9>; +}; From ca0703f9e64a0f6b6ff8f2c393475e88375d086c Mon Sep 17 00:00:00 2001 From: Carlo Caione Date: Tue, 23 Dec 2025 12:57:31 +0100 Subject: [PATCH 1888/3659] modules: lora-basics-modem: Refactor and fix CMake A set of preliminary (but harmless) changes to prepare for adding the HAL implementation. - Rename CMake variables for clarity and consistency, adding an 'LBM_LIB_' prefix when the path is a library / module path. - Change zephyr_library_include_directories to zephyr_include_directories for the RAL/RALF includes, since these headers may be needed outside the library itself. - Make lbm_common.h available to code outside the driver directory. Signed-off-by: Carlo Caione --- drivers/lora/lora-basics-modem/CMakeLists.txt | 2 ++ modules/lora-basics-modem/CMakeLists.txt | 9 +++++---- modules/lora-basics-modem/sx126x.cmake | 6 +++--- modules/lora-basics-modem/sx127x.cmake | 6 +++--- 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/drivers/lora/lora-basics-modem/CMakeLists.txt b/drivers/lora/lora-basics-modem/CMakeLists.txt index ee7991afefe0..0fa573ebb085 100644 --- a/drivers/lora/lora-basics-modem/CMakeLists.txt +++ b/drivers/lora/lora-basics-modem/CMakeLists.txt @@ -9,6 +9,8 @@ else() zephyr_library_named(lora-basics-modem) endif() +zephyr_include_directories(.) + zephyr_library_sources(lbm_common.c) # zephyr-keep-sorted-start diff --git a/modules/lora-basics-modem/CMakeLists.txt b/modules/lora-basics-modem/CMakeLists.txt index ffdfc792e1ff..32a503ba2b27 100644 --- a/modules/lora-basics-modem/CMakeLists.txt +++ b/modules/lora-basics-modem/CMakeLists.txt @@ -4,9 +4,10 @@ if(CONFIG_USE_LORA_BASICS_MODEM_DRIVERS) set(LORA_BASICS_MODEM_DIR ${ZEPHYR_CURRENT_MODULE_DIR}) + set(LBM_LIB_DIR ${LORA_BASICS_MODEM_DIR}/lbm_lib) - set(LBM_SMTC_MODEM_CORE_DIR ${LBM_LIB_DIR}/smtc_modem_core) - set(LBM_RADIO_DRIVERS_DIR ${LBM_LIB_DIR}/smtc_modem_core/radio_drivers) + set(LBM_LIB_SMTC_MODEM_CORE_DIR ${LBM_LIB_DIR}/smtc_modem_core) + set(LBM_LIB_RADIO_DRIVERS_DIR ${LBM_LIB_DIR}/smtc_modem_core/radio_drivers) if(TARGET lora-basics-modem) set(ZEPHYR_CURRENT_LIBRARY lora-basics-modem) @@ -14,8 +15,8 @@ if(CONFIG_USE_LORA_BASICS_MODEM_DRIVERS) zephyr_library_named(lora-basics-modem) endif() - zephyr_library_include_directories(${LBM_SMTC_MODEM_CORE_DIR}/smtc_ral/src) - zephyr_library_include_directories(${LBM_SMTC_MODEM_CORE_DIR}/smtc_ralf/src) + zephyr_include_directories(${LBM_LIB_SMTC_MODEM_CORE_DIR}/smtc_ral/src) + zephyr_include_directories(${LBM_LIB_SMTC_MODEM_CORE_DIR}/smtc_ralf/src) if(CONFIG_LORA_SX126X) include(sx126x.cmake) diff --git a/modules/lora-basics-modem/sx126x.cmake b/modules/lora-basics-modem/sx126x.cmake index 021f047711dc..f719183f3caa 100644 --- a/modules/lora-basics-modem/sx126x.cmake +++ b/modules/lora-basics-modem/sx126x.cmake @@ -8,7 +8,7 @@ zephyr_library_compile_definitions(SX126X_TRANSCEIVER) # Allow modem options set(ALLOW_CSMA_BUILD true) -set(LBM_SX126X_LIB_DIR ${LBM_RADIO_DRIVERS_DIR}/sx126x_driver/src) +set(LBM_SX126X_LIB_DIR ${LBM_LIB_RADIO_DRIVERS_DIR}/sx126x_driver/src) zephyr_include_directories(${LBM_SX126X_LIB_DIR}) #----------------------------------------------------------------------------- @@ -19,6 +19,6 @@ zephyr_library_sources( ${LBM_SX126X_LIB_DIR}/sx126x.c ${LBM_SX126X_LIB_DIR}/sx126x_driver_version.c ${LBM_SX126X_LIB_DIR}/sx126x_lr_fhss.c - ${LBM_SMTC_MODEM_CORE_DIR}/smtc_ral/src/ral_sx126x.c - ${LBM_SMTC_MODEM_CORE_DIR}/smtc_ralf/src/ralf_sx126x.c + ${LBM_LIB_SMTC_MODEM_CORE_DIR}/smtc_ral/src/ral_sx126x.c + ${LBM_LIB_SMTC_MODEM_CORE_DIR}/smtc_ralf/src/ralf_sx126x.c ) diff --git a/modules/lora-basics-modem/sx127x.cmake b/modules/lora-basics-modem/sx127x.cmake index b26c4f824c58..0e498824c5c3 100644 --- a/modules/lora-basics-modem/sx127x.cmake +++ b/modules/lora-basics-modem/sx127x.cmake @@ -15,7 +15,7 @@ endif() # Allow modem options set(ALLOW_CSMA_BUILD true) -set(LBM_SX127X_LIB_DIR ${LBM_RADIO_DRIVERS_DIR}/sx127x_driver/src) +set(LBM_SX127X_LIB_DIR ${LBM_LIB_RADIO_DRIVERS_DIR}/sx127x_driver/src) zephyr_include_directories(${LBM_SX127X_LIB_DIR}) #----------------------------------------------------------------------------- @@ -23,6 +23,6 @@ zephyr_include_directories(${LBM_SX127X_LIB_DIR}) #----------------------------------------------------------------------------- zephyr_library_sources( ${LBM_SX127X_LIB_DIR}/sx127x.c - ${LBM_SMTC_MODEM_CORE_DIR}/smtc_ral/src/ral_sx127x.c - ${LBM_SMTC_MODEM_CORE_DIR}/smtc_ralf/src/ralf_sx127x.c + ${LBM_LIB_SMTC_MODEM_CORE_DIR}/smtc_ral/src/ral_sx127x.c + ${LBM_LIB_SMTC_MODEM_CORE_DIR}/smtc_ralf/src/ralf_sx127x.c ) From a4dbdba2e7b4f57ec42981e99870faa6b486da85 Mon Sep 17 00:00:00 2001 From: Carlo Caione Date: Tue, 23 Dec 2025 12:59:49 +0100 Subject: [PATCH 1889/3659] modules: lora-basics-modem: Add HAL implementation with porting tests Add the initial smtc_modem_hal implementation for Zephyr that provides the hardware abstraction layer required by LoRa Basics Modem. To fully port the LoRa Basic Modem library to Zephyr we need to port and adapt three parts (see [0]): 1. Radio Driver HAL 2. RAL BSP 3. LoRa Basics Modem HAL Right now the Radio Driver HAL and the RAL BSP are correctly implemented by the lbm_sx126x drivers, this patchset is taking care of the initial work of porting and adapting also the LoRa Basics Modem HAL. The LBM library provides a porting tool [1] that (quoting from [2]) "[...] provides a automatic suite of tests that will help user ensures that lora basics modem mcu and radio HAL functions are implemented in a good way (SPI, radio_irq, time, timer, random, radio config, sleep and low power)" This patchset is taking care of making the porting tool a first class test suite for Zephyr implementing the needed HAL functions. [0] https://github.com/Lora-net/SWL2001/blob/master/lbm_lib/PORTING_GUIDE.md [1] https://github.com/Lora-net/SWL2001/blob/master/lbm_examples/main_examples/main_porting_tests.c [2] https://github.com/Lora-net/SWL2001/blob/master/lbm_examples/README.md Signed-off-by: Carlo Caione --- modules/lora-basics-modem/CMakeLists.txt | 10 + modules/lora-basics-modem/Kconfig | 8 + .../smtc_modem_hal/smtc_modem_hal.c | 320 +++++++ .../smtc_modem_hal/smtc_modem_hal_ext.h | 31 + .../porting_tests/CMakeLists.txt | 10 + .../boards/nrf52840dk_nrf52840.overlay | 51 + .../lora-basics-modem/porting_tests/prj.conf | 13 + .../porting_tests/src/main.c | 892 ++++++++++++++++++ .../porting_tests/testcase.yaml | 18 + 9 files changed, 1353 insertions(+) create mode 100644 modules/lora-basics-modem/smtc_modem_hal/smtc_modem_hal.c create mode 100644 modules/lora-basics-modem/smtc_modem_hal/smtc_modem_hal_ext.h create mode 100644 tests/modules/lora-basics-modem/porting_tests/CMakeLists.txt create mode 100644 tests/modules/lora-basics-modem/porting_tests/boards/nrf52840dk_nrf52840.overlay create mode 100644 tests/modules/lora-basics-modem/porting_tests/prj.conf create mode 100644 tests/modules/lora-basics-modem/porting_tests/src/main.c create mode 100644 tests/modules/lora-basics-modem/porting_tests/testcase.yaml diff --git a/modules/lora-basics-modem/CMakeLists.txt b/modules/lora-basics-modem/CMakeLists.txt index 32a503ba2b27..a97d1b918edb 100644 --- a/modules/lora-basics-modem/CMakeLists.txt +++ b/modules/lora-basics-modem/CMakeLists.txt @@ -7,8 +7,11 @@ if(CONFIG_USE_LORA_BASICS_MODEM_DRIVERS) set(LBM_LIB_DIR ${LORA_BASICS_MODEM_DIR}/lbm_lib) set(LBM_LIB_SMTC_MODEM_CORE_DIR ${LBM_LIB_DIR}/smtc_modem_core) + set(LBM_LIB_SMTC_MODEM_HAL_DIR ${LBM_LIB_DIR}/smtc_modem_hal) set(LBM_LIB_RADIO_DRIVERS_DIR ${LBM_LIB_DIR}/smtc_modem_core/radio_drivers) + set(LBM_SMTC_MODEM_HAL_DIR ${CMAKE_CURRENT_LIST_DIR}/smtc_modem_hal) + if(TARGET lora-basics-modem) set(ZEPHYR_CURRENT_LIBRARY lora-basics-modem) else() @@ -17,6 +20,13 @@ if(CONFIG_USE_LORA_BASICS_MODEM_DRIVERS) zephyr_include_directories(${LBM_LIB_SMTC_MODEM_CORE_DIR}/smtc_ral/src) zephyr_include_directories(${LBM_LIB_SMTC_MODEM_CORE_DIR}/smtc_ralf/src) + zephyr_include_directories(${LBM_LIB_SMTC_MODEM_HAL_DIR}) + + zephyr_include_directories(${LBM_SMTC_MODEM_HAL_DIR}) + + if(CONFIG_LORA_BASICS_MODEM_HAL) + zephyr_library_sources(${LBM_SMTC_MODEM_HAL_DIR}/smtc_modem_hal.c) + endif() if(CONFIG_LORA_SX126X) include(sx126x.cmake) diff --git a/modules/lora-basics-modem/Kconfig b/modules/lora-basics-modem/Kconfig index ce4382c247f7..432f85fbab7a 100644 --- a/modules/lora-basics-modem/Kconfig +++ b/modules/lora-basics-modem/Kconfig @@ -9,3 +9,11 @@ config ZEPHYR_LORA_BASICS_MODEM_MODULE config USE_LORA_BASICS_MODEM_DRIVERS bool + +config LORA_BASICS_MODEM_HAL + bool "LoRa Basics Modem HAL implementation" + depends on USE_LORA_BASICS_MODEM_DRIVERS && LORA_SX126X + help + Compile the smtc_modem_hal implementation for LoRa Basics Modem. + This is required for porting tests and full modem functionality. + Currently only supported with SX126x radios. diff --git a/modules/lora-basics-modem/smtc_modem_hal/smtc_modem_hal.c b/modules/lora-basics-modem/smtc_modem_hal/smtc_modem_hal.c new file mode 100644 index 000000000000..327fd683e6f6 --- /dev/null +++ b/modules/lora-basics-modem/smtc_modem_hal/smtc_modem_hal.c @@ -0,0 +1,320 @@ +/* + * Copyright (c) 2025 Carlo Caione + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +LOG_MODULE_REGISTER(smtc_modem_hal, CONFIG_LORA_LOG_LEVEL); + +#define HAL_WORKQ_STACK_SIZE 1024 +#define HAL_WORKQ_PRIORITY (-1) + +typedef void (*callback_t)(void *context); + +struct cb_data_t { + struct gpio_callback cb; + struct k_work work; + callback_t dio_cb; + void *context; +}; + +struct timer_data_t { + callback_t timer_cb; + void *context; +}; + +static struct cb_data_t prv_cb_data; +static struct timer_data_t prv_timer_data; + +static const struct device *prv_transceiver_dev; + +static bool prv_modem_irq_enabled = true; +static bool prv_pending_timer_cb; +static bool prv_pending_dio_cb; + +static K_THREAD_STACK_DEFINE(hal_workq_stack, HAL_WORKQ_STACK_SIZE); +static struct k_work_q hal_workq; + +static void hal_timer_callback(struct k_timer *timer); +static K_TIMER_DEFINE(prv_timer, hal_timer_callback, NULL); + +static void hal_irq_work_handler(struct k_work *work) +{ + struct cb_data_t *data = CONTAINER_OF(work, struct cb_data_t, work); + + if (!prv_modem_irq_enabled) { + prv_pending_dio_cb = true; + return; + } + + if (data->dio_cb != NULL) { + data->dio_cb(data->context); + } +} + +static void hal_irq_callback(const struct device *port, struct gpio_callback *cb, uint32_t pins) +{ + struct cb_data_t *data = CONTAINER_OF(cb, struct cb_data_t, cb); + + k_work_submit_to_queue(&hal_workq, &data->work); +} + +static void hal_timer_callback(struct k_timer *timer) +{ + ARG_UNUSED(timer); + + if (!prv_modem_irq_enabled) { + prv_pending_timer_cb = true; + return; + } + + if (prv_timer_data.timer_cb != NULL) { + prv_timer_data.timer_cb(prv_timer_data.context); + } +} + +void smtc_modem_hal_init(const struct device *transceiver) +{ + __ASSERT(transceiver, "transceiver must be provided"); + __ASSERT(DEVICE_API_IS(lora, transceiver), "transceiver must be a LoRa device"); + + prv_transceiver_dev = transceiver; + + k_work_queue_start(&hal_workq, hal_workq_stack, + K_THREAD_STACK_SIZEOF(hal_workq_stack), + HAL_WORKQ_PRIORITY, NULL); + k_thread_name_set(&hal_workq.thread, "lbm_hal_workq"); + + k_work_init(&prv_cb_data.work, hal_irq_work_handler); +} + +/* -------------------------------------------------------------------------- */ +/* --- TIME MANAGEMENT ------------------------------------------------------ */ +/* -------------------------------------------------------------------------- */ + +/** + * @brief Provide the time since startup in seconds. + * + * @remark Used for scheduling autonomous retransmissions (i.e: NbTrans), + * transmitting MAC answers, basically any delay without accurate time + * constraints. It is also used to measure the time spent inside the + * LoRaWAN process for the integrated failsafe. + * + * @return Current system uptime in seconds + */ +uint32_t smtc_modem_hal_get_time_in_s(void) +{ + return k_uptime_seconds(); +} + +/** + * @brief Provide the time since startup in milliseconds. + * + * The returned value must monotonically increase all the way to 0xFFFFFFFF and + * then overflow to 0x00000000. + * + * @return Current system uptime in milliseconds + */ +uint32_t smtc_modem_hal_get_time_in_ms(void) +{ + return k_uptime_get_32(); +} + +/* -------------------------------------------------------------------------- */ +/* --- TIMER MANAGEMENT ----------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +/** + * @brief Start a timer that will expire at the requested time. + * + * Upon expiration, the provided callback is called with context as its sole + * argument. The callback is executed in an interrupt context, with interrupts + * disabled. + * + * @param [in] milliseconds Timer duration in milliseconds + * @param [in] callback Callback function to be called when the timer expires + * @param [in] context Context to be passed to the callback function + */ +void smtc_modem_hal_start_timer(const uint32_t milliseconds, callback_t callback, void *context) +{ + prv_timer_data.timer_cb = callback; + prv_timer_data.context = context; + + k_timer_start(&prv_timer, K_MSEC(milliseconds), K_NO_WAIT); +} + +/** + * @brief Stop the timer that may have been started with smtc_modem_hal_start_timer. + */ +void smtc_modem_hal_stop_timer(void) +{ + k_timer_stop(&prv_timer); +} + +/* -------------------------------------------------------------------------- */ +/* --- IRQ MANAGEMENT ------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +/** + * @brief Disable the two interrupt sources that execute the LoRa Basics Modem + * code: the timer, and the transceiver DIO interrupt source. + */ +void smtc_modem_hal_disable_modem_irq(void) +{ + prv_modem_irq_enabled = false; +} + +/** + * @brief Enable the two interrupt sources that execute the LoRa Basics Modem + * code: the timer, and the transceiver DIO interrupt source. + */ +void smtc_modem_hal_enable_modem_irq(void) +{ + prv_modem_irq_enabled = true; + + if (prv_pending_timer_cb) { + prv_pending_timer_cb = false; + if (prv_timer_data.timer_cb != NULL) { + prv_timer_data.timer_cb(prv_timer_data.context); + } + } + + if (prv_pending_dio_cb) { + prv_pending_dio_cb = false; + if (prv_cb_data.dio_cb != NULL) { + prv_cb_data.dio_cb(prv_cb_data.context); + } + } +} + +/* -------------------------------------------------------------------------- */ +/* --- RANDOM NUMBER -------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +/** + * @brief Return a uniformly-distributed unsigned random integer from the closed + * interval [val_1, val_2] or [val_2, val_1]. + * + * @param [in] val_1 First boundary value + * @param [in] val_2 Second boundary value + * + * @return Random value in the range [min(val_1,val_2), max(val_1,val_2)] + */ +uint32_t smtc_modem_hal_get_random_nb_in_range(const uint32_t val_1, const uint32_t val_2) +{ + uint32_t min = MIN(val_1, val_2); + uint32_t range = MAX(val_1, val_2) - min; + uint32_t random = sys_rand32_get(); + + if (range == UINT32_MAX) { + return random; + } + + return min + (random % (range + 1)); +} + +/* -------------------------------------------------------------------------- */ +/* --- RADIO ENVIRONMENT ---------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +/** + * @brief Store the callback and context argument that must be executed when a + * radio event occurs. + * + * @param [in] callback Callback that will be called when a radio event occurs + * @param [in] context Context that will be passed to the callback + */ +void smtc_modem_hal_irq_config_radio_irq(callback_t dio_cb, void *context) +{ + int ret; + + __ASSERT(prv_transceiver_dev, "smtc_modem_hal_init must be called first"); + __ASSERT(dio_cb, "DIO1 callback must be provided"); + + if (prv_cb_data.dio_cb != NULL) { + ret = lbm_driver_remove_dio1_gpio_callback(prv_transceiver_dev, &prv_cb_data.cb); + if (ret < 0) { + LOG_ERR("Failed to remove DIO1 GPIO callback: %d", ret); + } + } + + prv_cb_data.dio_cb = dio_cb; + prv_cb_data.context = context; + + ret = lbm_driver_add_dio1_gpio_callback(prv_transceiver_dev, &prv_cb_data.cb, + hal_irq_callback); + if (ret < 0) { + LOG_ERR("Failed to add DIO1 GPIO callback: %d", ret); + } +} + +/** + * @brief Power up the TCXO. + * + * If the TCXO is not controlled by the transceiver, power up the TCXO and then + * busy wait until the TCXO is running with the proper accuracy. If the TCXO is + * controlled by the transceiver or if no TCXO is present, implement an empty + * function. + */ +void smtc_modem_hal_start_radio_tcxo(void) +{ + /* + * We only support TCXO's that are wired to the transceiver. In such cases, + * this function must be empty. See 5.25 of the porting guide. + */ +} + +/** + * @brief Power down the TCXO. + * + * If the TCXO is not controlled by the transceiver, stop the TCXO. If the TCXO + * is controlled by the transceiver or if no TCXO is present, implement an empty + * function. + */ +void smtc_modem_hal_stop_radio_tcxo(void) +{ + /* + * We only support TCXO's that are wired to the transceiver. In such cases, + * this function must be empty. See 5.26 of the porting guide. + */ +} + +/** + * @brief Return the time in milliseconds that the TCXO needs to start up with + * the required accuracy. + * + * This does not implement a delay but is used to perform certain calculations + * so the modem accounts for startup latency when scheduling reception windows. + * Return zero if no TCXO is deployed. + * + * @return TCXO startup delay in milliseconds + */ +uint32_t smtc_modem_hal_get_radio_tcxo_startup_delay_ms(void) +{ + return 0; +} + +/** + * @brief Set antenna switch for Tx operation or not. + * + * If no antenna switch is used then implement an empty command. + * + * @param [in] is_tx_on Set to true for Tx operation, false otherwise + */ +void smtc_modem_hal_set_ant_switch(bool is_tx_on) +{ + /* No antenna switch is used. */ +} diff --git a/modules/lora-basics-modem/smtc_modem_hal/smtc_modem_hal_ext.h b/modules/lora-basics-modem/smtc_modem_hal/smtc_modem_hal_ext.h new file mode 100644 index 000000000000..0d512091cdbd --- /dev/null +++ b/modules/lora-basics-modem/smtc_modem_hal/smtc_modem_hal_ext.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2025 Carlo Caione + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef SMTC_MODEM_HAL_EXT_H +#define SMTC_MODEM_HAL_EXT_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Initialization of the hal implementation. + * + * This must be called before smtc_modem_init + * + * @param[in] transceiver The device pointer of the transceiver instance that will be used. + */ +void smtc_modem_hal_init(const struct device *transceiver); + + +#ifdef __cplusplus +} +#endif + +#endif /* SMTC_MODEM_HAL_EXT_H */ diff --git a/tests/modules/lora-basics-modem/porting_tests/CMakeLists.txt b/tests/modules/lora-basics-modem/porting_tests/CMakeLists.txt new file mode 100644 index 000000000000..edb590934c84 --- /dev/null +++ b/tests/modules/lora-basics-modem/porting_tests/CMakeLists.txt @@ -0,0 +1,10 @@ +# Copyright (c) 2025 Carlo Caione +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.13.1) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) + +project(lbm_porting LANGUAGES C) + +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources}) diff --git a/tests/modules/lora-basics-modem/porting_tests/boards/nrf52840dk_nrf52840.overlay b/tests/modules/lora-basics-modem/porting_tests/boards/nrf52840dk_nrf52840.overlay new file mode 100644 index 000000000000..4c24c9333cf9 --- /dev/null +++ b/tests/modules/lora-basics-modem/porting_tests/boards/nrf52840dk_nrf52840.overlay @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2025 Carlo Caione + * Copyright (c) 2024 Semtech Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + smtc-hal-uart = &uart1; + smtc-watchdog = &wdt; + }; +}; + +&spi1 { + status = "disabled"; +}; + +&qspi { + status = "disabled"; +}; + +&uart1 { + status = "okay"; + + current-speed = <115200>; + + pinctrl-0 = <&uart1_default_alt>; + pinctrl-1 = <&uart1_sleep_alt>; + pinctrl-names = "default", "sleep"; + /delete-property/ hw-flow-control; +}; + +&pinctrl { + uart1_default_alt: uart1_default_alt { + group1 { + psels = , ; + }; + }; + + uart1_sleep_alt: uart1_sleep_alt { + group1 { + psels = , ; + low-power-enable; + }; + }; +}; + +&wdt { + status = "okay"; +}; diff --git a/tests/modules/lora-basics-modem/porting_tests/prj.conf b/tests/modules/lora-basics-modem/porting_tests/prj.conf new file mode 100644 index 000000000000..54b4c6f8d52e --- /dev/null +++ b/tests/modules/lora-basics-modem/porting_tests/prj.conf @@ -0,0 +1,13 @@ +# Copyright (c) 2025 Carlo Caione +# Copyright (c) 2024 Semtech Corporation +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_LOG=y +CONFIG_PRINTK=y +CONFIG_LORA=y +CONFIG_LORA_MODULE_BACKEND_LORA_BASICS_MODEM=y +CONFIG_LORA_BASICS_MODEM_DEFERRED_INIT=y +CONFIG_LORA_BASICS_MODEM_HAL=y +CONFIG_ZTEST=y +CONFIG_ZTEST_THREAD_PRIORITY=0 +CONFIG_ENTROPY_GENERATOR=y diff --git a/tests/modules/lora-basics-modem/porting_tests/src/main.c b/tests/modules/lora-basics-modem/porting_tests/src/main.c new file mode 100644 index 000000000000..7a19722779a7 --- /dev/null +++ b/tests/modules/lora-basics-modem/porting_tests/src/main.c @@ -0,0 +1,892 @@ +/* + * Copyright (c) 2025 Carlo Caione + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include +#include +#include + +#include +#include +#include +#include + +#define NB_LOOP_TEST_SPI 2 +#define NB_LOOP_TEST_CONFIG_RADIO 2 +#define SYNC_WORD_NO_RADIO 0x21 +#define FREQ_NO_RADIO 868300000 +#define MARGIN_GET_TIME_IN_MS 1 +#define MARGIN_TIMER_IRQ_IN_MS 2 +#define MARGIN_TIME_CONFIG_RADIO_IN_MS 8 +#define MARGIN_SLEEP_IN_MS 2 + +/** + * @brief Return test enumeration + */ +enum return_code_test { + RC_PORTING_TEST_OK = 0x00, + RC_PORTING_TEST_NOK = 0x01, + RC_PORTING_TEST_RELAUNCH = 0x02, +}; + +#define DEFAULT_RADIO_NODE DT_ALIAS(lora0) +BUILD_ASSERT(DT_NODE_HAS_STATUS_OKAY(DEFAULT_RADIO_NODE), + "No default LoRa radio specified in DT"); + +struct lbm_porting_fixture { + ralf_t modem_radio; + const struct device *transceiver; + volatile bool radio_irq_raised; + volatile bool irq_rx_timeout_raised; + volatile bool timer_irq_raised; + volatile uint32_t irq_time_ms; + volatile uint32_t irq_time_s; + ralf_params_lora_t rx_lora_param; + ralf_params_lora_t tx_lora_param; +}; + +/* Radio IRQ callback (runs in thread context via HAL work queue) */ +static void radio_rx_irq_callback(void *context) +{ + struct lbm_porting_fixture *fixture = (struct lbm_porting_fixture *)context; + ral_irq_t radio_irq = 0; + + fixture->radio_irq_raised = true; + + /* Record time in thread context */ + fixture->irq_time_ms = smtc_modem_hal_get_time_in_ms(); + + /* Get IRQ status to check for RX timeout */ + ral_get_irq_status(&fixture->modem_radio.ral, &radio_irq); + + if ((radio_irq & RAL_IRQ_RX_TIMEOUT) == RAL_IRQ_RX_TIMEOUT) { + fixture->irq_rx_timeout_raised = true; + } + + /* Clear IRQ status */ + ral_clear_irq_status(&fixture->modem_radio.ral, RAL_IRQ_ALL); + + /* Shut down the TCXO */ + smtc_modem_hal_stop_radio_tcxo(); +} + +/* Radio IRQ callback for time in seconds test (runs in thread context via HAL work queue) */ +static void radio_rx_irq_callback_get_time_in_s(void *context) +{ + struct lbm_porting_fixture *fixture = (struct lbm_porting_fixture *)context; + ral_irq_t radio_irq = 0; + + fixture->radio_irq_raised = true; + + /* Record time in seconds in thread context */ + fixture->irq_time_s = smtc_modem_hal_get_time_in_s(); + + /* Get IRQ status to check for RX timeout */ + ral_get_irq_status(&fixture->modem_radio.ral, &radio_irq); + + if ((radio_irq & RAL_IRQ_RX_TIMEOUT) == RAL_IRQ_RX_TIMEOUT) { + fixture->irq_rx_timeout_raised = true; + } + + /* Clear IRQ status */ + ral_clear_irq_status(&fixture->modem_radio.ral, RAL_IRQ_ALL); + + /* Shut down the TCXO */ + smtc_modem_hal_stop_radio_tcxo(); +} + +/* Timer IRQ callback */ +static void timer_irq_callback(void *context) +{ + struct lbm_porting_fixture *fixture = (struct lbm_porting_fixture *)context; + + fixture->irq_time_ms = smtc_modem_hal_get_time_in_ms(); + fixture->timer_irq_raised = true; +} + +/* Radio TX IRQ callback */ +static void radio_tx_irq_callback(void *context) +{ + struct lbm_porting_fixture *fixture = (struct lbm_porting_fixture *)context; + + fixture->irq_time_ms = smtc_modem_hal_get_time_in_ms(); + fixture->radio_irq_raised = true; + + /* Clear IRQ status */ + ral_clear_irq_status(&fixture->modem_radio.ral, RAL_IRQ_ALL); +} + +/** + * @brief Reset and initialize radio + * + * Test processing: + * - Reset radio + * - Initialize radio + * - Set radio in sleep mode + * + * @param fixture Test fixture containing modem radio + * @return ral_status_t Status of the operation + */ +static ral_status_t reset_init_radio(struct lbm_porting_fixture *fixture) +{ + ral_status_t status; + + /* Reset radio */ + status = ral_reset(&fixture->modem_radio.ral); + if (status != RAL_STATUS_OK) { + return status; + } + + /* Initialize radio */ + status = ral_init(&fixture->modem_radio.ral); + if (status != RAL_STATUS_OK) { + return status; + } + + /* Set radio in sleep mode */ + status = ral_set_sleep(&fixture->modem_radio.ral, true); + smtc_modem_hal_set_ant_switch(false); + if (status != RAL_STATUS_OK) { + return status; + } + + return RAL_STATUS_OK; +} + +static void *lbm_porting_setup(void) +{ + static struct lbm_porting_fixture fixture = { + .modem_radio = RALF_SX126X_INSTANTIATE(NULL), + .transceiver = DEVICE_DT_GET(DEFAULT_RADIO_NODE), + .radio_irq_raised = false, + + /* LoRa RX configurations TO NOT receive */ + .rx_lora_param = { + .rf_freq_in_hz = FREQ_NO_RADIO, + .sync_word = SYNC_WORD_NO_RADIO, + .symb_nb_timeout = 0, + .mod_params = { + .sf = RAL_LORA_SF12, + .bw = RAL_LORA_BW_125_KHZ, + .cr = RAL_LORA_CR_4_5, + .ldro = 0, + }, + .pkt_params = { + .preamble_len_in_symb = 8, + .header_type = RAL_LORA_PKT_EXPLICIT, + .pld_len_in_bytes = 255, + .crc_is_on = false, + .invert_iq_is_on = true, + }, + }, + + /* LoRa TX configurations TO NOT transmit */ + .tx_lora_param = { + .rf_freq_in_hz = FREQ_NO_RADIO, + .sync_word = SYNC_WORD_NO_RADIO, + .output_pwr_in_dbm = 14, + .mod_params = { + .sf = RAL_LORA_SF12, + .bw = RAL_LORA_BW_125_KHZ, + .cr = RAL_LORA_CR_4_5, + .ldro = 0, + }, + .pkt_params = { + .preamble_len_in_symb = 8, + .header_type = RAL_LORA_PKT_EXPLICIT, + .pld_len_in_bytes = 50, + .crc_is_on = true, + .invert_iq_is_on = false, + }, + }, + }; + + fixture.modem_radio.ral.context = fixture.transceiver; + + smtc_modem_hal_init(fixture.transceiver); + + return &fixture; +} + +ZTEST_SUITE(lbm_porting, NULL, lbm_porting_setup, NULL, NULL, NULL); + +/** + * @brief Test SPI communication with radio + * + * Test processing: + * - Reset radio + * - Read radio status through SPI + * - Check if data is coherent and chip mode is valid + */ +ZTEST_F(lbm_porting, test_spi) +{ + ral_status_t ral_status; + uint32_t counter_nok = 0; + + /* Reset radio */ + ral_status = ral_reset(&fixture->modem_radio.ral); + zassert_equal(ral_status, RAL_STATUS_OK, "SPI test failed: ral_reset returned 0x%x", + ral_status); + + /* Read chip status multiple times to verify SPI communication */ + for (int i = 0; i < NB_LOOP_TEST_SPI; i++) { + sx126x_chip_status_t chip_status; + sx126x_status_t status; + + /* Get chip status via SPI */ + status = sx126x_get_status(fixture->transceiver, &chip_status); + + if (status == SX126X_STATUS_OK) { + /* Check chip mode is valid (not UNUSED) */ + if (chip_status.chip_mode == SX126X_CHIP_MODE_UNUSED) { + TC_PRINT("Wrong SX126X chip mode, get SX126X_CHIP_MODE_UNUSED\n"); + counter_nok++; + } + } else { + TC_PRINT("Failed to get SX126X status\n"); + counter_nok++; + } + } + + zassert_equal(counter_nok, 0, "SPI test failed: %u / %u tests failed", + counter_nok, NB_LOOP_TEST_SPI); +} + +/** + * @brief Test radio interrupt functionality + * + * Test processing: + * - Reset and initialize radio + * - Configure radio IRQ callback + * - Configure radio with bad parameters to receive a RX timeout IRQ + * - Configure radio in reception mode with a timeout + * - Wait for timeout to expire + * - Check if RX timeout IRQ was raised + */ +ZTEST_F(lbm_porting, test_radio_irq) +{ + ral_status_t status; + uint32_t rx_timeout_in_ms = 500; + + /* Reset IRQ flag */ + fixture->radio_irq_raised = false; + + /* Reset, init radio and put it in sleep mode */ + status = reset_init_radio(fixture); + zassert_equal(status, RAL_STATUS_OK, "Could not reset/init radio: 0x%x", status); + + /* Setup radio and IRQ */ + smtc_modem_hal_irq_config_radio_irq(radio_rx_irq_callback, fixture); + smtc_modem_hal_start_radio_tcxo(); + smtc_modem_hal_set_ant_switch(false); + + /* Setup LoRa parameters */ + status = ralf_setup_lora(&fixture->modem_radio, &fixture->rx_lora_param); + zassert_equal(status, RAL_STATUS_OK, "ralf_setup_lora failed: 0x%x", status); + + /* Configure IRQ parameters */ + status = ral_set_dio_irq_params(&fixture->modem_radio.ral, + RAL_IRQ_RX_DONE | RAL_IRQ_RX_TIMEOUT | + RAL_IRQ_RX_HDR_ERROR | RAL_IRQ_RX_CRC_ERROR); + zassert_equal(status, RAL_STATUS_OK, "ral_set_dio_irq_params failed: 0x%x", status); + + /* Set radio in RX mode */ + status = ral_set_rx(&fixture->modem_radio.ral, rx_timeout_in_ms); + zassert_equal(status, RAL_STATUS_OK, "ral_set_rx failed: 0x%x", status); + + /* Wait for 2 * timeout */ + k_busy_wait((rx_timeout_in_ms * 2) * 1000); + + /* Check if IRQ was raised */ + zassert_true(fixture->radio_irq_raised, + "Timeout, radio irq not received"); +} + +/** + * @brief Test get time in seconds + * + * Test processing: + * - Reset, init and configure radio + * - Configure radio in reception mode with a timeout + * - Get start time + * - Wait for radio IRQ (get stop time in IRQ callback) + * - Check if time is coherent with the configured timeout + * + * @return enum return_code_test RC_PORTING_TEST_OK, RC_PORTING_TEST_NOK, or + * RC_PORTING_TEST_RELAUNCH + */ +static enum return_code_test test_get_time_in_s(struct lbm_porting_fixture *fixture) +{ + ral_status_t status; + uint32_t rx_timeout_in_ms = 5000; + uint32_t start_time_s; + uint32_t elapsed_time; + + /* Reset flags */ + fixture->radio_irq_raised = false; + fixture->irq_rx_timeout_raised = false; + fixture->rx_lora_param.symb_nb_timeout = 0; + + /* Reset, init radio and put it in sleep mode */ + status = reset_init_radio(fixture); + if (status != RAL_STATUS_OK) { + TC_PRINT("Could not reset/init radio: 0x%x\n", status); + return RC_PORTING_TEST_NOK; + } + + /* Setup radio and IRQ - use callback that records time in seconds */ + smtc_modem_hal_irq_config_radio_irq(radio_rx_irq_callback_get_time_in_s, fixture); + smtc_modem_hal_start_radio_tcxo(); + smtc_modem_hal_set_ant_switch(false); + + /* Setup LoRa parameters */ + status = ralf_setup_lora(&fixture->modem_radio, &fixture->rx_lora_param); + if (status != RAL_STATUS_OK) { + TC_PRINT("ralf_setup_lora failed: 0x%x\n", status); + return RC_PORTING_TEST_NOK; + } + + /* Configure IRQ parameters */ + status = ral_set_dio_irq_params(&fixture->modem_radio.ral, + RAL_IRQ_RX_DONE | RAL_IRQ_RX_TIMEOUT | + RAL_IRQ_RX_HDR_ERROR | RAL_IRQ_RX_CRC_ERROR); + if (status != RAL_STATUS_OK) { + TC_PRINT("ral_set_dio_irq_params failed: 0x%x\n", status); + return RC_PORTING_TEST_NOK; + } + + /* Set radio in RX mode */ + status = ral_set_rx(&fixture->modem_radio.ral, rx_timeout_in_ms); + if (status != RAL_STATUS_OK) { + TC_PRINT("ral_set_rx failed: 0x%x\n", status); + return RC_PORTING_TEST_NOK; + } + + /* Get start time */ + start_time_s = smtc_modem_hal_get_time_in_s(); + + /* Wait for radio IRQ */ + while (fixture->radio_irq_raised == false) { + k_sleep(K_MSEC(10)); + } + + /* Relaunch test if IRQ was not RX timeout */ + if (fixture->irq_rx_timeout_raised == false) { + TC_PRINT("Radio IRQ received but not RX timeout -> relaunch test\n"); + return RC_PORTING_TEST_RELAUNCH; + } + + /* Check elapsed time */ + elapsed_time = fixture->irq_time_s - start_time_s; + if (elapsed_time != rx_timeout_in_ms / 1000) { + TC_PRINT("Time is not coherent: expected %us / got %us\n", + rx_timeout_in_ms / 1000, elapsed_time); + return RC_PORTING_TEST_NOK; + } + + TC_PRINT("Time expected %us / got %us (no margin)\n", + rx_timeout_in_ms / 1000, elapsed_time); + + return RC_PORTING_TEST_OK; +} + +/** + * @brief Test get time in milliseconds + * + * Test processing: + * - Reset, init and configure radio with a timeout symbol number + * - Get start time + * - Configure radio in reception mode + * - Wait for radio IRQ (get stop time in IRQ callback) + * - Check if time is coherent with the configured timeout symbol number + * + * @return enum return_code_test RC_PORTING_TEST_OK, RC_PORTING_TEST_NOK, or + * RC_PORTING_TEST_RELAUNCH + */ +static enum return_code_test test_get_time_in_ms(struct lbm_porting_fixture *fixture) +{ + ral_status_t status; + uint32_t start_time_ms; + uint32_t elapsed_time; + uint32_t symb_time_ms; + uint8_t wait_start_ms = 5; + + /* Reset flags */ + fixture->radio_irq_raised = false; + fixture->irq_rx_timeout_raised = false; + + /* + * Configure symbol timeout. + * To avoid misalignment between symb timeout and real timeout, + * use a number of symbols smaller than 63. + */ + fixture->rx_lora_param.symb_nb_timeout = 62; + fixture->rx_lora_param.mod_params.sf = RAL_LORA_SF12; + fixture->rx_lora_param.mod_params.bw = RAL_LORA_BW_125_KHZ; + + /* Calculate expected symbol time: 2^SF / BW * symb_nb_timeout */ + symb_time_ms = (uint32_t)(fixture->rx_lora_param.symb_nb_timeout * + ((1 << 12) / 125.0)); + + /* Reset, init radio and put it in sleep mode */ + status = reset_init_radio(fixture); + if (status != RAL_STATUS_OK) { + TC_PRINT("Could not reset/init radio: 0x%x\n", status); + return RC_PORTING_TEST_NOK; + } + + /* Setup radio and IRQ */ + smtc_modem_hal_irq_config_radio_irq(radio_rx_irq_callback, fixture); + smtc_modem_hal_start_radio_tcxo(); + smtc_modem_hal_set_ant_switch(false); + + /* Setup LoRa parameters */ + status = ralf_setup_lora(&fixture->modem_radio, &fixture->rx_lora_param); + if (status != RAL_STATUS_OK) { + TC_PRINT("ralf_setup_lora failed: 0x%x\n", status); + return RC_PORTING_TEST_NOK; + } + + /* Configure IRQ parameters */ + status = ral_set_dio_irq_params(&fixture->modem_radio.ral, + RAL_IRQ_RX_DONE | RAL_IRQ_RX_TIMEOUT | + RAL_IRQ_RX_HDR_ERROR | RAL_IRQ_RX_CRC_ERROR); + if (status != RAL_STATUS_OK) { + TC_PRINT("ral_set_dio_irq_params failed: 0x%x\n", status); + return RC_PORTING_TEST_NOK; + } + + /* Wait to align start time */ + start_time_ms = smtc_modem_hal_get_time_in_ms() + wait_start_ms; + while (smtc_modem_hal_get_time_in_ms() < start_time_ms) { + /* Busy wait */ + } + + /* Set radio in RX mode with symbol timeout (timeout_in_ms = 0) */ + status = ral_set_rx(&fixture->modem_radio.ral, 0); + if (status != RAL_STATUS_OK) { + TC_PRINT("ral_set_rx failed: 0x%x\n", status); + return RC_PORTING_TEST_NOK; + } + + /* Wait for radio IRQ */ + while (fixture->radio_irq_raised == false) { + k_sleep(K_MSEC(1)); + } + + /* Relaunch test if IRQ was not RX timeout */ + if (fixture->irq_rx_timeout_raised == false) { + TC_PRINT("Radio IRQ received but not RX timeout -> relaunch test\n"); + return RC_PORTING_TEST_RELAUNCH; + } + + /* Calculate elapsed time, compensating for TCXO startup delay */ + elapsed_time = fixture->irq_time_ms - start_time_ms - + smtc_modem_hal_get_radio_tcxo_startup_delay_ms(); + + /* Check elapsed time within margin */ + if (abs((int)(elapsed_time - symb_time_ms)) > MARGIN_GET_TIME_IN_MS) { + TC_PRINT("Time is not coherent: expected %ums / got %ums (margin +/-%ums)\n", + symb_time_ms, elapsed_time, MARGIN_GET_TIME_IN_MS); + return RC_PORTING_TEST_NOK; + } + + TC_PRINT("Time expected %ums / got %ums (margin +/-%ums)\n", + symb_time_ms, elapsed_time, MARGIN_GET_TIME_IN_MS); + + return RC_PORTING_TEST_OK; +} + +/** + * @brief Test time (Get time in s and in ms) + * + * Test processing: + * - Run test_get_time_in_s (with retry on relaunch) + * - Run test_get_time_in_ms (with retry on relaunch) + */ +ZTEST_F(lbm_porting, test_get_time) +{ + enum return_code_test ret; + + /* Test get time in seconds */ + do { + ret = test_get_time_in_s(fixture); + zassert_not_equal(ret, RC_PORTING_TEST_NOK, "test_get_time_in_s failed"); + } while (ret == RC_PORTING_TEST_RELAUNCH); + + /* Test get time in milliseconds */ + do { + ret = test_get_time_in_ms(fixture); + zassert_not_equal(ret, RC_PORTING_TEST_NOK, "test_get_time_in_ms failed"); + } while (ret == RC_PORTING_TEST_RELAUNCH); +} + +/** + * @brief Test timer IRQ + * + * Test processing: + * - Get start time + * - Configure and start timer + * - Wait timer irq (get stop time in irq callback) + * - Check the time elapsed between timer start and timer IRQ reception + */ +ZTEST_F(lbm_porting, test_timer_irq) +{ + uint32_t timer_ms = 3000; + uint8_t wait_start_ms = 5; + uint16_t timeout_ms = 2000; + uint32_t start_time_ms; + uint32_t elapsed_time; + + fixture->timer_irq_raised = false; + + smtc_modem_hal_stop_timer(); + + /* Wait to align start time */ + start_time_ms = smtc_modem_hal_get_time_in_ms() + wait_start_ms; + while (smtc_modem_hal_get_time_in_ms() < start_time_ms) { + k_sleep(K_MSEC(1)); + } + + smtc_modem_hal_start_timer(timer_ms, timer_irq_callback, fixture); + + /* Wait for timer IRQ with timeout */ + while ((fixture->timer_irq_raised == false) && + ((smtc_modem_hal_get_time_in_ms() - start_time_ms) < (timer_ms + timeout_ms))) { + k_sleep(K_MSEC(1)); + } + + zassert_true(fixture->timer_irq_raised, "Timeout: timer irq not received"); + + elapsed_time = fixture->irq_time_ms - start_time_ms; + + zassert_true((elapsed_time >= timer_ms) && + (elapsed_time <= timer_ms + MARGIN_TIMER_IRQ_IN_MS), + "Timer irq delay is not coherent: expected %ums / got %ums (margin +%ums)", + timer_ms, elapsed_time, MARGIN_TIMER_IRQ_IN_MS); + + TC_PRINT("Timer irq configured with %ums / got %ums (margin +%ums)\n", + timer_ms, elapsed_time, MARGIN_TIMER_IRQ_IN_MS); +} + +/** + * @brief Test stop timer + * + * Test processing: + * - Configure and start timer + * - Wait half of timer duration + * - Stop timer + * - Wait past the end of timer + * - Check if timer IRQ is not received + */ +ZTEST_F(lbm_porting, test_stop_timer) +{ + uint32_t timer_ms = 1000; + uint32_t time; + + fixture->timer_irq_raised = false; + + smtc_modem_hal_start_timer(timer_ms, timer_irq_callback, fixture); + + /* Wait half of timer */ + time = smtc_modem_hal_get_time_in_ms(); + while ((smtc_modem_hal_get_time_in_ms() - time) < (timer_ms / 2)) { + k_sleep(K_MSEC(1)); + } + + smtc_modem_hal_stop_timer(); + + /* Wait past the end of timer */ + time = smtc_modem_hal_get_time_in_ms(); + while ((smtc_modem_hal_get_time_in_ms() - time) < (timer_ms + 500)) { + k_sleep(K_MSEC(1)); + } + + zassert_false(fixture->timer_irq_raised, + "Timer irq raised while timer is stopped"); +} + +/** + * @brief Test enable/disable irq + * + * Test processing: + * - Disable irq + * - Start timer with irq + * - Wait the end of timer + * - Check if timer irq is not raised + * - Enable irq + * - Check if timer irq is raised + */ +ZTEST_F(lbm_porting, test_disable_enable_irq) +{ + uint32_t timer_ms = 3000; + uint32_t time; + + fixture->timer_irq_raised = false; + + smtc_modem_hal_disable_modem_irq(); + + smtc_modem_hal_start_timer(timer_ms, timer_irq_callback, fixture); + + /* Wait past the end of timer */ + time = smtc_modem_hal_get_time_in_ms(); + while ((smtc_modem_hal_get_time_in_ms() - time) < (timer_ms + 1000)) { + k_sleep(K_MSEC(1)); + } + + zassert_false(fixture->timer_irq_raised, + "Timer irq raised while irq is disabled"); + + smtc_modem_hal_enable_modem_irq(); + + zassert_true(fixture->timer_irq_raised, + "Timer irq not received while irq is reenabled"); +} + +/** + * @brief Test get random numbers + * + * Test processing: + * 1) Get 2 random numbers in full range + * - Check if numbers are not equal to 0 and are different + * 2) Get 2 random numbers in a defined range + * - Check if numbers are different and in the defined range + * 3) Get random draw of numbers in a defined range + * - Check if draw of each value is equivalent (uniform distribution) + */ +ZTEST_F(lbm_porting, test_random) +{ + ARG_UNUSED(fixture); + + uint32_t rdom1, rdom2; + uint32_t range_min, range_max; + + /* Test 1: Get random numbers in full range */ + TC_PRINT("Get random nb: "); + rdom1 = smtc_modem_hal_get_random_nb_in_range(0, 0xFFFFFFFF); + rdom2 = smtc_modem_hal_get_random_nb_in_range(0, 0xFFFFFFFF); + + zassert_true((rdom1 != 0) && (rdom2 != 0) && (rdom1 != rdom2), + "Random numbers invalid: random1 = %u, random2 = %u", rdom1, rdom2); + TC_PRINT("OK - random1 = %u, random2 = %u\n", rdom1, rdom2); + + /* Test 2: Get random numbers in defined range */ + TC_PRINT("Get random nb in range: "); + range_min = 1; + range_max = 42; + + rdom1 = smtc_modem_hal_get_random_nb_in_range(range_min, range_max); + rdom2 = smtc_modem_hal_get_random_nb_in_range(range_min, range_max); + + zassert_true((rdom1 >= range_min) && (rdom1 <= range_max), + "random1 = %u out of range [%u;%u]", rdom1, range_min, range_max); + zassert_true((rdom2 >= range_min) && (rdom2 <= range_max), + "random2 = %u out of range [%u;%u]", rdom2, range_min, range_max); + zassert_true(rdom1 != rdom2, + "random1 and random2 are equal: %u", rdom1); + TC_PRINT("OK - random1 = %u, random2 = %u in range [%u;%u]\n", + rdom1, rdom2, range_min, range_max); + + /* Test 3: Get random draw - check uniform distribution */ + TC_PRINT("Get random draw: "); + range_min = 1; + range_max = 10; + + uint32_t tab_counter_random[10] = {0}; + uint32_t nb_draw = 100000; + uint32_t probability_draw = nb_draw / (range_max - range_min + 1); + /* Error margin = 5% of probability_draw */ + int16_t margin = (probability_draw * 5) / 100; + bool distribution_ok = true; + + for (uint32_t i = 0; i < nb_draw; i++) { + rdom1 = smtc_modem_hal_get_random_nb_in_range(range_min, range_max); + tab_counter_random[rdom1 - 1]++; + } + + uint8_t tab_size = sizeof(tab_counter_random) / sizeof(uint32_t); + + for (uint16_t i = 0; i < tab_size; i++) { + if (abs((int)(probability_draw - tab_counter_random[i])) > margin) { + TC_PRINT("Number %u drawn %u times, expected [%u;%u]\n", + (i + 1), tab_counter_random[i], + (probability_draw - margin), + (probability_draw + margin)); + distribution_ok = false; + } + } + + zassert_true(distribution_ok, + "Random distribution error margin > 5%%"); + TC_PRINT("OK - Random draw of %u numbers between [%u;%u] range\n", + nb_draw, range_min, range_max); +} + +/** + * @brief Test time to configure RX radio + * + * Test processing: + * - Reset and init radio + * - Configure radio IRQ + * - In a loop: + * - Get start time + * - Configure RX radio (TCXO, antenna switch, LoRa params, IRQ params) + * - Get stop time + * - Check configuration time is within margin + */ +ZTEST_F(lbm_porting, test_config_rx_radio) +{ + ral_status_t status; + uint16_t counter_nok = 0; + + fixture->radio_irq_raised = false; + + /* Reset, init radio and put it in sleep mode */ + status = reset_init_radio(fixture); + zassert_equal(status, RAL_STATUS_OK, "Could not reset/init radio: 0x%x", status); + + k_msleep(500); + + /* Setup radio IRQ callback */ + smtc_modem_hal_irq_config_radio_irq(radio_rx_irq_callback, fixture); + + for (uint16_t i = 0; i < NB_LOOP_TEST_CONFIG_RADIO; i++) { + uint32_t start_time_ms; + uint32_t elapsed_time; + + fixture->radio_irq_raised = false; + + start_time_ms = smtc_modem_hal_get_time_in_ms(); + + /* Configure radio for RX */ + smtc_modem_hal_start_radio_tcxo(); + smtc_modem_hal_set_ant_switch(false); + + status = ralf_setup_lora(&fixture->modem_radio, &fixture->rx_lora_param); + zassert_equal(status, RAL_STATUS_OK, "ralf_setup_lora failed: 0x%x", status); + + status = ral_set_dio_irq_params(&fixture->modem_radio.ral, + RAL_IRQ_RX_DONE | RAL_IRQ_RX_TIMEOUT | + RAL_IRQ_RX_HDR_ERROR | RAL_IRQ_RX_CRC_ERROR); + zassert_equal(status, RAL_STATUS_OK, "ral_set_dio_irq_params failed: 0x%x", status); + + elapsed_time = smtc_modem_hal_get_time_in_ms() - start_time_ms; + + if (elapsed_time >= MARGIN_TIME_CONFIG_RADIO_IN_MS) { + TC_PRINT("Configuration of RX radio is too long: %ums (margin +%ums)\n", + elapsed_time, MARGIN_TIME_CONFIG_RADIO_IN_MS); + counter_nok++; + } + + smtc_modem_hal_stop_radio_tcxo(); + } + + zassert_equal(counter_nok, 0, "Failed test = %u / %u", + counter_nok, NB_LOOP_TEST_CONFIG_RADIO); +} + +/** + * @brief Test time to configure TX radio + * + * Test processing: + * - Reset and init radio + * - Configure radio IRQ + * - In a loop: + * - Get start time + * - Configure TX radio (TCXO, antenna switch, LoRa params, IRQ params, payload) + * - Get stop time + * - Check configuration time is within margin + */ +ZTEST_F(lbm_porting, test_config_tx_radio) +{ + ral_status_t status; + uint16_t counter_nok = 0; + uint16_t payload_size = 50; + uint8_t payload[50] = {0}; + + fixture->radio_irq_raised = false; + + /* Reset, init radio and put it in sleep mode */ + status = reset_init_radio(fixture); + zassert_equal(status, RAL_STATUS_OK, "Could not reset/init radio: 0x%x", status); + + /* Setup radio IRQ callback */ + smtc_modem_hal_irq_config_radio_irq(radio_tx_irq_callback, fixture); + + for (uint16_t i = 0; i < NB_LOOP_TEST_CONFIG_RADIO; i++) { + uint32_t start_time_ms; + uint32_t elapsed_time; + + fixture->radio_irq_raised = false; + + start_time_ms = smtc_modem_hal_get_time_in_ms(); + + /* Configure radio for TX */ + smtc_modem_hal_start_radio_tcxo(); + smtc_modem_hal_set_ant_switch(true); + + status = ralf_setup_lora(&fixture->modem_radio, &fixture->tx_lora_param); + zassert_equal(status, RAL_STATUS_OK, "ralf_setup_lora failed: 0x%x", status); + + status = ral_set_dio_irq_params(&fixture->modem_radio.ral, RAL_IRQ_TX_DONE); + zassert_equal(status, RAL_STATUS_OK, "ral_set_dio_irq_params failed: 0x%x", status); + + status = ral_set_pkt_payload(&fixture->modem_radio.ral, payload, payload_size); + zassert_equal(status, RAL_STATUS_OK, "ral_set_pkt_payload failed: 0x%x", status); + + elapsed_time = smtc_modem_hal_get_time_in_ms() - start_time_ms; + + if (elapsed_time >= MARGIN_TIME_CONFIG_RADIO_IN_MS) { + TC_PRINT("Configuration of TX radio is too long: %ums (margin +%ums)\n", + elapsed_time, MARGIN_TIME_CONFIG_RADIO_IN_MS); + counter_nok++; + } + + smtc_modem_hal_stop_radio_tcxo(); + } + + zassert_equal(counter_nok, 0, "Failed test = %u / %u", + counter_nok, NB_LOOP_TEST_CONFIG_RADIO); +} + +/** + * @brief Test sleep time + * + * Test processing: + * - Get start time + * - Sleep for a defined duration + * - Get stop time + * - Check sleep time is accurate within margin + */ +ZTEST_F(lbm_porting, test_sleep_ms) +{ + ARG_UNUSED(fixture); + + int32_t sleep_ms = 2000; + uint8_t wait_start_ms = 5; + uint32_t start_time_ms; + uint32_t stop_time_ms; + uint32_t elapsed_time; + + /* Wait to align start time */ + start_time_ms = smtc_modem_hal_get_time_in_ms() + wait_start_ms; + while (smtc_modem_hal_get_time_in_ms() < start_time_ms) { + /* Busy wait */ + } + + k_msleep(sleep_ms); + + stop_time_ms = smtc_modem_hal_get_time_in_ms(); + elapsed_time = stop_time_ms - start_time_ms; + + zassert_true(abs((int)(elapsed_time - sleep_ms)) <= MARGIN_SLEEP_IN_MS, + "Sleep time is not coherent: expected %ums / got %ums (margin +/-%ums)", + sleep_ms, elapsed_time, MARGIN_SLEEP_IN_MS); + + TC_PRINT("Sleep time expected %ums / got %ums (margin +/-%ums)\n", + sleep_ms, elapsed_time, MARGIN_SLEEP_IN_MS); +} diff --git a/tests/modules/lora-basics-modem/porting_tests/testcase.yaml b/tests/modules/lora-basics-modem/porting_tests/testcase.yaml new file mode 100644 index 000000000000..555a6b6f3f80 --- /dev/null +++ b/tests/modules/lora-basics-modem/porting_tests/testcase.yaml @@ -0,0 +1,18 @@ +# Copyright (c) 2025 Carlo Caione +# SPDX-License-Identifier: Apache-2.0 + +common: + tags: + - lora + - lora-basics-modem + harness: ztest + build_only: true + modules: + - lora-basics-modem + +tests: + modules.lora-basics-modem.porting_tests: + platform_allow: nrf52840dk/nrf52840 + extra_args: + - DTC_OVERLAY_FILE=boards/nrf52840dk_nrf52840.overlay + - SHIELD=semtech_sx1261mb2bas From 89b097428da3a7ae533c6403f2f2f0cd038ae236 Mon Sep 17 00:00:00 2001 From: Carlo Caione Date: Tue, 23 Dec 2025 13:01:02 +0100 Subject: [PATCH 1890/3659] modules: lora-basics-modem: Add remaining HAL stub functions Add stub implementations for all remaining smtc_modem_hal functions required by LoRa Basics Modem. These functions are not yet implemented but provide the necessary symbols for linking. Signed-off-by: Carlo Caione --- .../smtc_modem_hal/smtc_modem_hal.c | 418 ++++++++++++++++++ 1 file changed, 418 insertions(+) diff --git a/modules/lora-basics-modem/smtc_modem_hal/smtc_modem_hal.c b/modules/lora-basics-modem/smtc_modem_hal/smtc_modem_hal.c index 327fd683e6f6..83d38009e81e 100644 --- a/modules/lora-basics-modem/smtc_modem_hal/smtc_modem_hal.c +++ b/modules/lora-basics-modem/smtc_modem_hal/smtc_modem_hal.c @@ -318,3 +318,421 @@ void smtc_modem_hal_set_ant_switch(bool is_tx_on) { /* No antenna switch is used. */ } + +/** + * @brief Check if the radio is free. + * + * @remark Except a very specific application, this function should always + * return false. This function is used to check if the radio is used + * by an external stack. + * + * @remark Not implemented yet. + * + * @return false Radio is free (default) + */ +bool smtc_modem_external_stack_currently_use_radio(void) +{ + /* Not implemented yet */ + return false; +} + +/* -------------------------------------------------------------------------- */ +/* --- RESET MANAGEMENT ----------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +/** + * @brief Resets the MCU. + * + * @remark Not implemented yet. + */ +void smtc_modem_hal_reset_mcu(void) +{ + /* Not implemented yet */ +} + +/* -------------------------------------------------------------------------- */ +/* --- WATCHDOG MANAGEMENT -------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +/** + * @brief Reloads watchdog counter. + * + * @remark Application has to call this function periodically. The call period + * must be less than WATCHDOG_RELOAD_PERIOD. + * + * @remark Not implemented yet. + */ +void smtc_modem_hal_reload_wdog(void) +{ + /* Not implemented yet */ +} + +/** + * @brief Set an offset into the RTC counter. + * + * @remark Used for debug purpose such as wrapping issue. + * + * @remark Not implemented yet. + * + * @param [in] offset_to_test_wrapping Offset value to add + */ +void smtc_modem_hal_set_offset_to_test_wrapping(const uint32_t offset_to_test_wrapping) +{ + /* Not implemented yet */ +} + +/* -------------------------------------------------------------------------- */ +/* --- CONTEXT SAVING MANAGEMENT -------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +/** + * @brief Restores the data context. + * + * @remark This function is used to restore Modem data from a non volatile memory. + * + * @remark Not implemented yet. + * + * @param [in] ctx_type Type of modem context that need to be restored + * @param [in] offset Memory offset after ctx_type address + * @param [out] buffer Buffer pointer to write to + * @param [in] size Buffer size to read in bytes + */ +void smtc_modem_hal_context_restore(const modem_context_type_t ctx_type, uint32_t offset, + uint8_t *buffer, const uint32_t size) +{ + /* Not implemented yet */ +} + +/** + * @brief Stores the data context. + * + * @remark This function is used to store Modem data in a non volatile memory. + * + * @remark Not implemented yet. + * + * @param [in] ctx_type Type of modem context that need to be saved + * @param [in] offset Memory offset after ctx_type address + * @param [in] buffer Buffer pointer to write from + * @param [in] size Buffer size to write in bytes + */ +void smtc_modem_hal_context_store(const modem_context_type_t ctx_type, uint32_t offset, + const uint8_t *buffer, const uint32_t size) +{ + /* Not implemented yet */ +} + +/** + * @brief Erase a chosen number of flash pages of a context. + * + * @remark This function is only used with CONTEXT_STORE_AND_FORWARD. + * + * @remark Not implemented yet. + * + * @param [in] ctx_type Type of modem context that need to be erased + * @param [in] offset Memory offset after ctx_type address + * @param [in] nb_page Number of pages to erase + */ +void smtc_modem_hal_context_flash_pages_erase(const modem_context_type_t ctx_type, + uint32_t offset, uint8_t nb_page) +{ + /* Not implemented yet */ +} + +/* -------------------------------------------------------------------------- */ +/* --- PANIC MANAGEMENT ----------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +/** + * @brief Action to be taken in case of modem panic. + * + * @remark In case Device Management is used, it is recommended to perform the + * crashlog storage and status update in this function. + * + * @param [in] func The name of the function where the panic occurs + * @param [in] line The line number where the panic occurs + * @param [in] fmt String format + * @param [in] ... String arguments + */ +void smtc_modem_hal_on_panic(uint8_t *func, uint32_t line, const char *fmt, ...) +{ + LOG_ERR("LBM panic: %s:%u", func, line); + k_panic(); +} + +/* -------------------------------------------------------------------------- */ +/* --- ENVIRONMENT MANAGEMENT ----------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +/** + * @brief Return the battery level. + * + * @remark According to LoRaWAN 1.0.4 spec: + * 0: The end-device is connected to an external power source. + * 1..254: Battery level, where 1 is the minimum and 254 is the maximum. + * 255: The end-device was not able to measure the battery level. + * + * @remark Not implemented yet. + * + * @return Battery level for LoRaWAN stack (255 = not able to measure) + */ +uint8_t smtc_modem_hal_get_battery_level(void) +{ + /* Not implemented yet */ + return 255; +} + +/** + * @brief Return board wake up delay in milliseconds. + * + * @remark Not implemented yet. + * + * @return Board wake up delay in ms (0 = no delay) + */ +int8_t smtc_modem_hal_get_board_delay_ms(void) +{ + /* Not implemented yet */ + return 0; +} + +/* -------------------------------------------------------------------------- */ +/* --- TRACE MANAGEMENT ----------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +/** + * @brief Prints debug trace. + * + * @remark Not implemented yet. + * + * @param [in] fmt String format + * @param [in] ... String arguments + */ +void smtc_modem_hal_print_trace(const char *fmt, ...) +{ + /* Not implemented yet */ +} + +/* -------------------------------------------------------------------------- */ +/* --- FUOTA MANAGEMENT ----------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +/** + * @brief Get hardware version for FUOTA. + * + * @remark Only used if FMP package is activated. + * + * @remark Not implemented yet. + * + * @return Hardware version as defined in FMP Alliance package TS006-1.0.0 + */ +uint32_t smtc_modem_hal_get_hw_version_for_fuota(void) +{ + /* Not implemented yet */ + return 0; +} + +/** + * @brief Get firmware version for FUOTA. + * + * @remark Only used if FMP package is activated. + * + * @remark Not implemented yet. + * + * @return Firmware version as defined in FMP Alliance package TS006-1.0.0 + */ +uint32_t smtc_modem_hal_get_fw_version_for_fuota(void) +{ + /* Not implemented yet */ + return 0; +} + +/** + * @brief Get firmware status available for FUOTA. + * + * @remark Only used if FMP package is activated. + * + * @remark Not implemented yet. + * + * @return Firmware status field as defined in FMP Alliance package TS006-1.0.0 + */ +uint8_t smtc_modem_hal_get_fw_status_available_for_fuota(void) +{ + /* Not implemented yet */ + return 0; +} + +/** + * @brief Get firmware delete status for FUOTA. + * + * @remark Only used if FMP package is activated. + * + * @remark Not implemented yet. + * + * @param [in] fw_to_delete_version Firmware version to delete + * + * @return Firmware status field as defined in FMP Alliance package TS006-1.0.0 + */ +uint8_t smtc_modem_hal_get_fw_delete_status_for_fuota(uint32_t fw_to_delete_version) +{ + /* Not implemented yet */ + return 0; +} + +/** + * @brief Get next firmware version for FUOTA. + * + * @remark Only used if FMP package is activated. + * + * @remark Not implemented yet. + * + * @return Firmware version that will be running once upgrade is installed + */ +uint32_t smtc_modem_hal_get_next_fw_version_for_fuota(void) +{ + /* Not implemented yet */ + return 0; +} + +/* -------------------------------------------------------------------------- */ +/* --- DEVICE MANAGEMENT ---------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +/** + * @brief Return temperature in Celsius. + * + * @remark Not implemented yet. + * + * @return Temperature in Celsius (0 = dummy value) + */ +int8_t smtc_modem_hal_get_temperature(void) +{ + /* Not implemented yet */ + return 0; +} + +/** + * @brief Return MCU voltage in millivolts. + * + * @remark Not implemented yet. + * + * @return MCU voltage in mV (0 = dummy value) + */ +uint16_t smtc_modem_hal_get_voltage_mv(void) +{ + /* Not implemented yet */ + return 0; +} + +/** + * @brief Stores the crashlog. + * + * @remark This function is used to store the Modem crashlog in a non volatile + * memory. + * + * @remark Not implemented yet. + * + * @param [in] crash_string Crashlog string to be stored + * @param [in] crash_string_length Crashlog string length + */ +void smtc_modem_hal_crashlog_store(const uint8_t *crash_string, uint8_t crash_string_length) +{ + /* Not implemented yet */ +} + +/** + * @brief Restores the crashlog. + * + * @remark This function is used to restore the Modem crashlog from a non + * volatile memory. + * + * @remark Not implemented yet. + * + * @param [out] crash_string Crashlog string to be restored + * @param [out] crash_string_length Crashlog string length + */ +void smtc_modem_hal_crashlog_restore(uint8_t *crash_string, uint8_t *crash_string_length) +{ + /* Not implemented yet */ +} + +/** + * @brief Stores the crashlog status. + * + * @remark This function is used to store the Modem crashlog status in a non + * volatile memory. This status will allow the Modem to handle crashlog + * send task if needed after a crash. + * + * @remark Not implemented yet. + * + * @param [in] available True if a crashlog is available, false otherwise + */ +void smtc_modem_hal_crashlog_set_status(bool available) +{ + /* Not implemented yet */ +} + +/** + * @brief Get the previously stored crashlog status. + * + * @remark This function is used to get the Modem crashlog status from a non + * volatile memory. This status will allow the Modem to handle crashlog + * send task if needed after a crash. + * + * @remark Not implemented yet. + * + * @return false No crashlog available (default) + */ +bool smtc_modem_hal_crashlog_get_status(void) +{ + /* Not implemented yet */ + return false; +} + +/* -------------------------------------------------------------------------- */ +/* --- STORE AND FORWARD ---------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +/** + * @brief The number of reserved pages in flash for the Store and Forward service. + * + * @remark The number must be at least 3 pages. + * + * @remark Not implemented yet. + * + * @return Number of flash pages (0 = dummy value) + */ +uint16_t smtc_modem_hal_store_and_forward_get_number_of_pages(void) +{ + /* Not implemented yet */ + return 0; +} + +/** + * @brief Gives the size of a flash page in bytes. + * + * @remark Not implemented yet. + * + * @return Flash page size in bytes (0 = dummy value) + */ +uint16_t smtc_modem_hal_flash_get_page_size(void) +{ + /* Not implemented yet */ + return 0; +} + +/* -------------------------------------------------------------------------- */ +/* --- RTOS COMPATIBILITY --------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +/** + * @brief This function is called by the LBM stack on each LBM interruption + * (radio interrupt or low-power timer interrupt). + * + * @remark It could be convenient in the case of an RTOS implementation to + * notify the thread that manages the LBM stack. + * + * @remark Not implemented yet. + */ +void smtc_modem_hal_user_lbm_irq(void) +{ + /* Not implemented yet */ +} From 7db8328b08fd4cf14b5a5e538e1bce00e9e3bdc3 Mon Sep 17 00:00:00 2001 From: Gatien Chevallier Date: Wed, 15 Oct 2025 15:21:08 +0200 Subject: [PATCH 1891/3659] drivers: Introduce new OTP subsystem Introduce a new OTP subsystem to be able to interact with One Time Programmable(OTP) memory. For now, add basic read()/program() APIs. Program() API is default disabled due to its sensitivity. File drivers/otp.h is inspired by drivers/eeprom.h as the basic features are similar. Signed-off-by: Gatien Chevallier --- doc/hardware/peripherals/index.rst | 1 + doc/hardware/peripherals/otp/api.rst | 23 +++++ doc/hardware/peripherals/otp/index.rst | 17 ++++ drivers/CMakeLists.txt | 1 + drivers/Kconfig | 1 + drivers/otp/CMakeLists.txt | 3 + drivers/otp/Kconfig | 35 ++++++++ include/zephyr/drivers/otp.h | 114 +++++++++++++++++++++++++ 8 files changed, 195 insertions(+) create mode 100644 doc/hardware/peripherals/otp/api.rst create mode 100644 doc/hardware/peripherals/otp/index.rst create mode 100644 drivers/otp/CMakeLists.txt create mode 100644 drivers/otp/Kconfig create mode 100644 include/zephyr/drivers/otp.h diff --git a/doc/hardware/peripherals/index.rst b/doc/hardware/peripherals/index.rst index 7286d88f5b30..3ac3f30f875a 100644 --- a/doc/hardware/peripherals/index.rst +++ b/doc/hardware/peripherals/index.rst @@ -45,6 +45,7 @@ Peripherals mspi.rst mbox.rst opamp.rst + otp/index.rst pcie.rst peci.rst ps2.rst diff --git a/doc/hardware/peripherals/otp/api.rst b/doc/hardware/peripherals/otp/api.rst new file mode 100644 index 000000000000..1c5d5d33e02d --- /dev/null +++ b/doc/hardware/peripherals/otp/api.rst @@ -0,0 +1,23 @@ +.. _otp_api: + +OTP API +####### + +Overview +******** + +The OTP API provides means to provision and read +:abbr:`OTP(One Time Programmable)` memory devices + +API implementation Reference +**************************** +.. doxygengroup:: otp_interface + +Configuration Options +********************* + +OTP related configuration options: + +* :kconfig:option:`CONFIG_OTP` +* :kconfig:option:`CONFIG_OTP_PROGRAM` +* :kconfig:option:`CONFIG_OTP_INIT_PRIORITY` diff --git a/doc/hardware/peripherals/otp/index.rst b/doc/hardware/peripherals/otp/index.rst new file mode 100644 index 000000000000..4f4d8a6b91e6 --- /dev/null +++ b/doc/hardware/peripherals/otp/index.rst @@ -0,0 +1,17 @@ +.. _otp: + +One Time Programmable (OTP) memory devices +########################################## + +Overview +******** + +OTP memory devices handle memory that is expected to be permanent. This memory +is usually provisioned during manufacturing, but there are some use-cases in +which one needs to program the OTP memory at a later lifecycle state (e.g: +monotonic counters, cryptographic keys, etc...). + +.. toctree:: + :maxdepth: 2 + + api.rst diff --git a/drivers/CMakeLists.txt b/drivers/CMakeLists.txt index b3275816f472..8706f7535882 100644 --- a/drivers/CMakeLists.txt +++ b/drivers/CMakeLists.txt @@ -71,6 +71,7 @@ add_subdirectory_ifdef(CONFIG_MODEM modem) add_subdirectory_ifdef(CONFIG_MSPI mspi) add_subdirectory_ifdef(CONFIG_NET_DRIVERS net) add_subdirectory_ifdef(CONFIG_OPAMP opamp) +add_subdirectory_ifdef(CONFIG_OTP otp) add_subdirectory_ifdef(CONFIG_PECI peci) add_subdirectory_ifdef(CONFIG_PINCTRL pinctrl) add_subdirectory_ifdef(CONFIG_PM_CPU_OPS pm_cpu_ops) diff --git a/drivers/Kconfig b/drivers/Kconfig index 4dc5a629677c..7b98396266b5 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -67,6 +67,7 @@ source "drivers/modem/Kconfig" source "drivers/mspi/Kconfig" source "drivers/net/Kconfig" source "drivers/opamp/Kconfig" +source "drivers/otp/Kconfig" source "drivers/pcie/Kconfig" source "drivers/peci/Kconfig" source "drivers/pinctrl/Kconfig" diff --git a/drivers/otp/CMakeLists.txt b/drivers/otp/CMakeLists.txt new file mode 100644 index 000000000000..28a0cecce8ac --- /dev/null +++ b/drivers/otp/CMakeLists.txt @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library() diff --git a/drivers/otp/Kconfig b/drivers/otp/Kconfig new file mode 100644 index 000000000000..d1a1263a202b --- /dev/null +++ b/drivers/otp/Kconfig @@ -0,0 +1,35 @@ +# OTP driver configuration options + +# Copyright (c) 2025 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +menuconfig OTP + bool "One Time Programmable (OTP) drivers [EXPERIMENTAL]" + select EXPERIMENTAL + help + Enable support for hardware OTP. The OTP technology can be anything + from fuses to flash memory option bytes as long as it stays one time + programmable. + +if OTP + +module = OTP +module-str = otp + +source "subsys/logging/Kconfig.template.log_config" + +config OTP_INIT_PRIORITY + int "OTP init priority" + default KERNEL_INIT_PRIORITY_DEVICE + help + OTP device drivers initialization priority. This initialization + priority is used unless the driver implementation has its own + initialization priority. + +config OTP_PROGRAM + bool "Support OTP programming through Zephyr API" + help + Allowing the programming of OTPs may cause irreversible damage + to a platform. Use it very carefully and at your own risk. + +endif # OTP diff --git a/include/zephyr/drivers/otp.h b/include/zephyr/drivers/otp.h new file mode 100644 index 000000000000..f568ecf2b9d6 --- /dev/null +++ b/include/zephyr/drivers/otp.h @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2025 STMicroelectronics + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @ingroup otp_interface + * @brief Main header file for OTP driver API. + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_OTP_H_ +#define ZEPHYR_INCLUDE_DRIVERS_OTP_H_ + +/** + * @brief Interfaces for One Time Programmable (OTP) Memory. + * @defgroup otp_interface One Time Programmable Memory + * @since 4.4 + * @version 0.1.0 + * @ingroup io_interfaces + * @{ + */ + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @cond INTERNAL_HIDDEN + * + * For internal driver use only, skip these in public documentation. + */ + +/** + * @brief Callback API upon reading from the OTP memory. + * See @a otp_read() for argument description + */ +typedef int (*otp_api_read)(const struct device *dev, off_t offset, void *data, size_t len); + +/** + * @brief Callback API upon writing to the OTP memory. + * See @a otp_program() for argument description + */ +typedef int (*otp_api_program)(const struct device *dev, off_t offset, const void *data, + size_t len); + +__subsystem struct otp_driver_api { + otp_api_read read; +#if defined(CONFIG_OTP_PROGRAM) || defined(__DOXYGEN__) + otp_api_program program; +#endif +}; + +/** @endcond */ + +/** + * @brief Read data from OTP memory + * + * @param dev OTP device + * @param offset Address offset to read from. + * @param data Buffer to store read data. + * @param len Number of bytes to read. + * + * @return 0 on success, negative errno code on failure. + */ +__syscall int otp_read(const struct device *dev, off_t offset, void *data, size_t len); + +static inline int z_impl_otp_read(const struct device *dev, off_t offset, void *data, size_t len) +{ + return DEVICE_API_GET(otp, dev)->read(dev, offset, data, len); +} + +#if defined(CONFIG_OTP_PROGRAM) || defined(__DOXYGEN__) +/** + * @brief Program data to the given OTP memory + * + * @param dev OTP device + * @param offset Address offset to program data to. + * @param data Buffer with data to program. + * @param len Number of bytes to program. + * + * @return 0 on success, negative errno code on failure. + */ +__syscall int otp_program(const struct device *dev, off_t offset, const void *data, size_t len); + +static inline int z_impl_otp_program(const struct device *dev, off_t offset, const void *data, + size_t len) +{ + const struct otp_driver_api *api = DEVICE_API_GET(otp, dev); + + if (api->program == NULL) { + return -ENOSYS; + } + + return api->program(dev, offset, data, len); +} +#endif + +#ifdef __cplusplus +} +#endif + +/** + * @} + */ + +#include + +#endif /* ZEPHYR_INCLUDE_DRIVERS_OTP_H_ */ From 624e018a5f7cf040b6fba545b1fb0200c6018384 Mon Sep 17 00:00:00 2001 From: Gatien Chevallier Date: Wed, 22 Oct 2025 10:37:11 +0200 Subject: [PATCH 1892/3659] nvmem: Add OTP API support OTP drivers are the interface to One Time Programmable memory, which is NVMEM. Add the interface with the OTP API to the NVMEM one. Signed-off-by: Gatien Chevallier --- doc/services/storage/nvmem/index.rst | 1 + subsys/nvmem/Kconfig | 9 +++++++++ subsys/nvmem/nvmem.c | 9 +++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/services/storage/nvmem/index.rst b/doc/services/storage/nvmem/index.rst index 91aa2e78824c..5c4cfeff3a16 100644 --- a/doc/services/storage/nvmem/index.rst +++ b/doc/services/storage/nvmem/index.rst @@ -35,6 +35,7 @@ Configuration * :kconfig:option:`CONFIG_NVMEM`: Enables the NVMEM subsystem. * :kconfig:option:`CONFIG_NVMEM_EEPROM`: Enables NVMEM support for EEPROM devices. * :kconfig:option-regex:`CONFIG_NVMEM_FLASH.*`: Configure NVMEM support for flash devices. +* :kconfig:option-regex:`CONFIG_NVMEM_OTP.*`: Configure NVMEM support for OTP devices. Devicetree Bindings ******************* diff --git a/subsys/nvmem/Kconfig b/subsys/nvmem/Kconfig index d05a869f8c23..62f2ffd6c8b8 100644 --- a/subsys/nvmem/Kconfig +++ b/subsys/nvmem/Kconfig @@ -26,6 +26,15 @@ config NVMEM_FLASH_WRITE to write to flash devices requiring out-of-bands erase or taking write-block sizes into account. +config NVMEM_OTP + bool "NVMEM (read) support for OTP memory handling devices" + default y + depends on OTP + +config NVMEM_OTP_WRITE + bool "NVMEM (write) support for OTP memory handling devices" + depends on NVMEM_OTP && OTP_PROGRAM + module = NVMEM module-str = nvmem source "subsys/logging/Kconfig.template.log_config" diff --git a/subsys/nvmem/nvmem.c b/subsys/nvmem/nvmem.c index 97eb6233e0b1..82e09a1802c6 100644 --- a/subsys/nvmem/nvmem.c +++ b/subsys/nvmem/nvmem.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -30,6 +31,10 @@ int nvmem_cell_read(const struct nvmem_cell *cell, void *buf, off_t off, size_t return flash_read(cell->dev, cell->offset + off, buf, len); } + if (IS_ENABLED(CONFIG_NVMEM_OTP) && DEVICE_API_IS(otp, cell->dev)) { + return otp_read(cell->dev, cell->offset + off, buf, len); + } + return -ENXIO; } @@ -57,5 +62,9 @@ int nvmem_cell_write(const struct nvmem_cell *cell, const void *buf, off_t off, return flash_write(cell->dev, cell->offset + off, buf, len); } + if (IS_ENABLED(CONFIG_NVMEM_OTP_WRITE) && DEVICE_API_IS(otp, cell->dev)) { + return otp_program(cell->dev, cell->offset + off, buf, len); + } + return -ENXIO; } From 1d42f375cd38aec744d585928f9db6cf22ae48e8 Mon Sep 17 00:00:00 2001 From: Gatien Chevallier Date: Fri, 12 Dec 2025 11:52:15 +0100 Subject: [PATCH 1893/3659] drivers: otp: add OTP memory emulation driver In order to make some basic tests on the OTP API, add an OTP memory emulator driver. It implements the .program() and .read() APIs. Signed-off-by: Gatien Chevallier --- drivers/otp/CMakeLists.txt | 2 + drivers/otp/Kconfig | 2 + drivers/otp/Kconfig.emu | 11 ++++ drivers/otp/otp_emulator.c | 73 +++++++++++++++++++++++++++ dts/bindings/otp/zephyr,otp-emul.yaml | 14 +++++ 5 files changed, 102 insertions(+) create mode 100644 drivers/otp/Kconfig.emu create mode 100644 drivers/otp/otp_emulator.c create mode 100644 dts/bindings/otp/zephyr,otp-emul.yaml diff --git a/drivers/otp/CMakeLists.txt b/drivers/otp/CMakeLists.txt index 28a0cecce8ac..72b7ec78eb81 100644 --- a/drivers/otp/CMakeLists.txt +++ b/drivers/otp/CMakeLists.txt @@ -1,3 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 zephyr_library() + +zephyr_library_sources_ifdef(CONFIG_OTP_EMULATOR otp_emulator.c) diff --git a/drivers/otp/Kconfig b/drivers/otp/Kconfig index d1a1263a202b..5e587c823af2 100644 --- a/drivers/otp/Kconfig +++ b/drivers/otp/Kconfig @@ -18,6 +18,8 @@ module-str = otp source "subsys/logging/Kconfig.template.log_config" +source "drivers/otp/Kconfig.emu" + config OTP_INIT_PRIORITY int "OTP init priority" default KERNEL_INIT_PRIORITY_DEVICE diff --git a/drivers/otp/Kconfig.emu b/drivers/otp/Kconfig.emu new file mode 100644 index 000000000000..6edea7310f5f --- /dev/null +++ b/drivers/otp/Kconfig.emu @@ -0,0 +1,11 @@ +# Copyright (c) 2025 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +config OTP_EMULATOR + bool "OTP memory emulation driver" + default y + depends on DT_HAS_ZEPHYR_OTP_EMUL_ENABLED + help + Enable OTP emulator driver which can be used for testing purposes. + It will use a static RAM buffer per instance whose size is defined + in the device tree node of the OTP device. diff --git a/drivers/otp/otp_emulator.c b/drivers/otp/otp_emulator.c new file mode 100644 index 000000000000..6a6272411bd9 --- /dev/null +++ b/drivers/otp/otp_emulator.c @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2025 STMicroelectronics + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +#define DT_DRV_COMPAT zephyr_otp_emul + +static K_MUTEX_DEFINE(otp_emul_lock); + +struct otp_emul_config { + size_t size; +}; + +#if defined(CONFIG_OTP_PROGRAM) +static int otp_emul_program(const struct device *dev, off_t offset, const void *buf, size_t len) +{ + const struct otp_emul_config *config = dev->config; + uint8_t *otp_mem = dev->data; + size_t end; + + if (size_add_overflow(offset, len, &end) || end > config->size) { + return -EINVAL; + } + + k_mutex_lock(&otp_emul_lock, K_FOREVER); + memcpy(&otp_mem[offset], buf, len); + k_mutex_unlock(&otp_emul_lock); + + return 0; +} +#endif /* CONFIG_OTP_PROGRAM */ + +static int otp_emul_read(const struct device *dev, off_t offset, void *buf, size_t len) +{ + const struct otp_emul_config *config = dev->config; + uint8_t *otp_mem = dev->data; + size_t end; + + if (size_add_overflow(offset, len, &end) || end > config->size) { + return -EINVAL; + } + + k_mutex_lock(&otp_emul_lock, K_FOREVER); + memcpy(buf, &otp_mem[offset], len); + k_mutex_unlock(&otp_emul_lock); + + return 0; +} + +static DEVICE_API(otp, otp_emul_api) = { +#if defined(CONFIG_OTP_PROGRAM) + .program = otp_emul_program, +#endif + .read = otp_emul_read, +}; + +#define OTP_EMU_INIT(n) \ + static uint8_t otp_emul_mem_##n[DT_INST_PROP_OR(n, size, 0)]; \ + \ + static const struct otp_emul_config otp_emul_##n##_config = { \ + .size = DT_INST_PROP_OR(n, size, 0), \ + }; \ + \ + DEVICE_DT_INST_DEFINE(n, NULL, NULL, &otp_emul_mem_##n, &otp_emul_##n##_config, \ + PRE_KERNEL_1, CONFIG_OTP_INIT_PRIORITY, &otp_emul_api); + +DT_INST_FOREACH_STATUS_OKAY(OTP_EMU_INIT) diff --git a/dts/bindings/otp/zephyr,otp-emul.yaml b/dts/bindings/otp/zephyr,otp-emul.yaml new file mode 100644 index 000000000000..c2211b9560a5 --- /dev/null +++ b/dts/bindings/otp/zephyr,otp-emul.yaml @@ -0,0 +1,14 @@ +# Copyright (c) 2025 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +description: Zephyr OTP memory emulation peripheral + +compatible: "zephyr,otp-emul" + +include: base.yaml + +properties: + size: + type: int + required: true + description: OTP Memory size in bytes From a6953f64279bdc69f592d6e18012dc0f3565aa03 Mon Sep 17 00:00:00 2001 From: Gatien Chevallier Date: Fri, 12 Dec 2025 13:38:42 +0100 Subject: [PATCH 1894/3659] boards: native_sim: add OTP memory emulator node Add an OTP memory emulator node to the board native_sim board device tree file. Additions of a node to the native sim device tree shifts the device index, hence making the check_init_priorities test fail. Update the index in the reference data of the test. Signed-off-by: Gatien Chevallier --- boards/native/native_sim/native_sim.dts | 6 ++++++ .../validate_check_init_priorities_output.py | 6 +++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/boards/native/native_sim/native_sim.dts b/boards/native/native_sim/native_sim.dts index 86f78c133ee4..1d2b1bde46ca 100644 --- a/boards/native/native_sim/native_sim.dts +++ b/boards/native/native_sim/native_sim.dts @@ -109,6 +109,12 @@ size = ; }; + otp0: otp { + compatible = "zephyr,otp-emul"; + size = ; + status = "okay"; + }; + i2c0: i2c@100 { status = "okay"; compatible = "zephyr,i2c-emul-controller"; diff --git a/tests/misc/check_init_priorities/validate_check_init_priorities_output.py b/tests/misc/check_init_priorities/validate_check_init_priorities_output.py index 77bbe5ebd560..4f87384c5542 100755 --- a/tests/misc/check_init_priorities/validate_check_init_priorities_output.py +++ b/tests/misc/check_init_priorities/validate_check_init_priorities_output.py @@ -18,10 +18,10 @@ REFERENCE_OUTPUT_INITLEVELS = [ "EARLY", "PRE_KERNEL_1", - "__init___device_dts_ord_31: init_fn_0(__device_dts_ord_31)", - "__init___device_dts_ord_32: init_fn_1(__device_dts_ord_32)", - "__init___device_dts_ord_33: NULL(__device_dts_ord_33)", + "__init___device_dts_ord_32: init_fn_0(__device_dts_ord_32)", + "__init___device_dts_ord_33: init_fn_1(__device_dts_ord_33)", "__init___device_dts_ord_34: NULL(__device_dts_ord_34)", + "__init___device_dts_ord_35: NULL(__device_dts_ord_35)", "__init_posix_arch_console_init: posix_arch_console_init(NULL)", "PRE_KERNEL_2", "__init_sys_clock_driver_init: sys_clock_driver_init(NULL)", From afab067381eafe02da166bae0ef8656e0385edb8 Mon Sep 17 00:00:00 2001 From: Gatien Chevallier Date: Fri, 12 Dec 2025 11:50:31 +0100 Subject: [PATCH 1895/3659] tests: nvmem: Add OTP testcase Add an overlay/config to test the NVMEM subsystem with an emulated OTP driver. Signed-off-by: Gatien Chevallier --- tests/subsys/nvmem/api/otp.overlay | 35 ++++++++++++++++++++++++++++ tests/subsys/nvmem/api/testcase.yaml | 7 ++++++ 2 files changed, 42 insertions(+) create mode 100644 tests/subsys/nvmem/api/otp.overlay diff --git a/tests/subsys/nvmem/api/otp.overlay b/tests/subsys/nvmem/api/otp.overlay new file mode 100644 index 000000000000..848d5021dbe8 --- /dev/null +++ b/tests/subsys/nvmem/api/otp.overlay @@ -0,0 +1,35 @@ +/** + * Copyright (c) 2025 STMicroelectronics + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + nvmem0 = &otp0; + }; + + test_consumer0: test-consumer0 { + compatible = "vnd,nvmem-consumer"; + nvmem-cells = <&cell0>, <&cell10>; + nvmem-cell-names = "cell0", "cell10"; + }; +}; + +&otp0 { + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + cell0: cell@0 { + reg = <0x0 0x10>; + #nvmem-cell-cells = <0>; + }; + + cell10: cell@10 { + reg = <0x10 0x10>; + read-only; + #nvmem-cell-cells = <0>; + }; + }; +}; diff --git a/tests/subsys/nvmem/api/testcase.yaml b/tests/subsys/nvmem/api/testcase.yaml index f2777be77eb9..1ec2c17c66df 100644 --- a/tests/subsys/nvmem/api/testcase.yaml +++ b/tests/subsys/nvmem/api/testcase.yaml @@ -17,3 +17,10 @@ tests: - CONFIG_NVMEM_FLASH_WRITE=y extra_dtc_overlay_files: - flash.overlay + nvmem.api.otp: + extra_configs: + - CONFIG_OTP=y + - CONFIG_OTP_PROGRAM=y + - CONFIG_NVMEM_OTP_WRITE=y + extra_dtc_overlay_files: + - otp.overlay From 1b988e9014404eea3d7ced2fbd69305d62280f40 Mon Sep 17 00:00:00 2001 From: Gatien Chevallier Date: Mon, 5 Jan 2026 11:10:56 +0100 Subject: [PATCH 1896/3659] MAINTAINERS: Add area for OTP Create a section for the OTP subsystem. NVMEM is referenced in the test category as the OTP subsystem is tested using the NVMEM API. Signed-off-by: Gatien Chevallier --- MAINTAINERS.yml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index 5e942ab46f30..8730fdfbac10 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -4168,6 +4168,22 @@ OSDP: tests: - sample.mgmt.osdp +OTP: + status: odd fixes + collaborators: + - GseoC + - pdgendt + files: + - doc/hardware/peripherals/otp/ + - drivers/otp/ + - dts/bindings/otp/ + - include/zephyr/drivers/otp.h + - tests/subsys/nvmem/api/otp.overlay + labels: + - "area: OTP" + tests: + - nvmem + Octavo Systems Platforms: status: maintained maintainers: From f15e645e35751cc36d868052c08e691c61e433cd Mon Sep 17 00:00:00 2001 From: Gaetan Perrot Date: Mon, 29 Dec 2025 22:38:48 +0900 Subject: [PATCH 1897/3659] drivers: watchdog: nxp_ewm: fix redundant NULL check nxp_ewm_install_timeout() accesses cfg fields before checking for NULL, making the later NULL check ineffective. Remove the redundant check. Signed-off-by: Gaetan Perrot --- drivers/watchdog/wdt_nxp_ewm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/watchdog/wdt_nxp_ewm.c b/drivers/watchdog/wdt_nxp_ewm.c index f70b1d2e2322..f78d56e3a224 100644 --- a/drivers/watchdog/wdt_nxp_ewm.c +++ b/drivers/watchdog/wdt_nxp_ewm.c @@ -88,7 +88,7 @@ static int nxp_ewm_install_timeout(const struct device *dev, return -ENOMEM; } - if (cfg && cfg->window.max <= NXP_EWM_MAX_TIMEOUT_WINDOW && + if (cfg->window.max <= NXP_EWM_MAX_TIMEOUT_WINDOW && cfg->window.min <= cfg->window.max && cfg->window.max > 0 && cfg->window.min >= 0) { From 5dbd980dceb35e00bc79d43c61ea9274e5bb3ff3 Mon Sep 17 00:00:00 2001 From: Richard Mc Sweeney Date: Tue, 16 Dec 2025 11:07:38 -0800 Subject: [PATCH 1898/3659] soc: infineon: add psc3 power management Adds power management support for the Infineon PSC3 device Signed-off-by: Richard Mc Sweeney --- soc/infineon/cat1b/psc3/CMakeLists.txt | 2 + soc/infineon/cat1b/psc3/Kconfig | 1 + soc/infineon/cat1b/psc3/Kconfig.defconfig | 5 +- soc/infineon/cat1b/psc3/power.c | 121 ++++++++++++++++++++++ soc/infineon/cat1b/psc3/power.h | 14 +++ 5 files changed, 142 insertions(+), 1 deletion(-) create mode 100644 soc/infineon/cat1b/psc3/power.c create mode 100644 soc/infineon/cat1b/psc3/power.h diff --git a/soc/infineon/cat1b/psc3/CMakeLists.txt b/soc/infineon/cat1b/psc3/CMakeLists.txt index 0251e3ebc7ec..4b9c756c2120 100644 --- a/soc/infineon/cat1b/psc3/CMakeLists.txt +++ b/soc/infineon/cat1b/psc3/CMakeLists.txt @@ -5,6 +5,8 @@ zephyr_sources(soc.c) zephyr_include_directories(.) zephyr_linker_sources(NOINIT noinit.ld) +zephyr_sources_ifdef(CONFIG_PM power.c) + # CAT1B family defines zephyr_compile_definitions_ifdef(CONFIG_SOC_FAMILY_INFINEON_CAT1 CY_USING_HAL) zephyr_compile_definitions_ifdef(CONFIG_SOC_FAMILY_INFINEON_CAT1B COMPONENT_CAT1B) diff --git a/soc/infineon/cat1b/psc3/Kconfig b/soc/infineon/cat1b/psc3/Kconfig index 8ca1975b8e21..08c6029015b9 100644 --- a/soc/infineon/cat1b/psc3/Kconfig +++ b/soc/infineon/cat1b/psc3/Kconfig @@ -29,3 +29,4 @@ config SOC_SERIES_PSC3 select SOC_EARLY_INIT_HOOK select CPU_CORTEX_M33 select NOINIT_SNIPPET_FIRST + select HAS_PM diff --git a/soc/infineon/cat1b/psc3/Kconfig.defconfig b/soc/infineon/cat1b/psc3/Kconfig.defconfig index c91d28b7eff3..435eb9181007 100644 --- a/soc/infineon/cat1b/psc3/Kconfig.defconfig +++ b/soc/infineon/cat1b/psc3/Kconfig.defconfig @@ -19,8 +19,11 @@ if SOC_SERIES_PSC3 +config INFINEON_CAT1_LP_TIMER_PDL + default n + config CORTEX_M_SYSTICK - default n if INFINEON_LP_TIMER_PDL + default n if INFINEON_CAT1_LP_TIMER_PDL config NUM_IRQS default 140 diff --git a/soc/infineon/cat1b/psc3/power.c b/soc/infineon/cat1b/psc3/power.c new file mode 100644 index 000000000000..80523be9ed0b --- /dev/null +++ b/soc/infineon/cat1b/psc3/power.c @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +LOG_MODULE_REGISTER(soc_power, CONFIG_SOC_LOG_LEVEL); + +uint32_t sleep_attempt_counts; +uint32_t sleep_counts; +uint32_t deepsleep_attempt_counts; +uint32_t deepsleep_counts; +int64_t last_sleep_start; +int64_t last_sleep_duration; + +void get_sleep_info(uint32_t *sleepattempts, uint32_t *sleepcounts, uint32_t *deepsleepattempts, + uint32_t *deepsleepcounts, int64_t *sleeptime) +{ + *sleepattempts = sleep_attempt_counts; + *sleepcounts = sleep_counts; + *deepsleepattempts = deepsleep_attempt_counts; + *deepsleepcounts = deepsleep_counts; + *sleeptime = last_sleep_duration; +} + +/* + * Called from pm_system_suspend(int32_t ticks) in subsys/power.c + * For deep sleep pm_system_suspend has executed all the driver + * power management call backs. + */ +__weak void pm_state_set(enum pm_state state, uint8_t substate_id) +{ + ARG_UNUSED(substate_id); + + /* Switch to using PRIMASK instead of BASEPRI register, since + * we are only able to wake up from standby while using PRIMASK. + */ + /* Set PRIMASK */ + __disable_irq(); + + /* Set BASEPRI to 0 */ + irq_unlock(0); + + switch (state) { + case PM_STATE_SUSPEND_TO_IDLE: + LOG_DBG("Entering PM state suspend to idle"); + sleep_attempt_counts++; + last_sleep_start = k_uptime_ticks(); + if (Cy_SysPm_CpuEnterSleep(CY_SYSPM_WAIT_FOR_INTERRUPT) == CY_RSLT_SUCCESS) { + sleep_counts++; + } + break; + case PM_STATE_SUSPEND_TO_RAM: + LOG_DBG("Entering PM state suspend to RAM"); + deepsleep_attempt_counts++; + last_sleep_start = k_uptime_ticks(); + if (Cy_SysPm_CpuEnterDeepSleep(CY_SYSPM_WAIT_FOR_INTERRUPT) == CY_RSLT_SUCCESS) { + deepsleep_counts++; + } + /* + * The HAL function doesn't clear this bit. It is a problem + * if the Zephyr idle function executes the wfi instruction + * with this bit set. We will always clear it here to avoid + * that situation. + */ + SCB_SCR &= (uint32_t)~SCB_SCR_SLEEPDEEP_Msk; + break; + default: + LOG_DBG("Unsupported power state %u", state); + break; + } +} + +/* + * Zephyr PM code expects us to enabled interrupts at post op exit. Zephyr used + * arch_irq_lock() which sets BASEPRI to a non-zero value masking all interrupts + * preventing wake. MCHP z_power_soc_(deep)_sleep sets PRIMASK=1 and BASEPRI=0 + * allowing wake from any enabled interrupt and prevents the CPU from entering + * an ISR on wake except for faults. We re-enable interrupts by setting PRIMASK + * to 0. + */ +__weak void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) +{ + ARG_UNUSED(substate_id); + + /* Clear PRIMASK */ + __enable_irq(); + + switch (state) { + case PM_STATE_SUSPEND_TO_IDLE: + case PM_STATE_SUSPEND_TO_RAM: + last_sleep_duration = last_sleep_start - k_uptime_ticks(); + break; + + default: + break; + } +} + +static int ifx_pm_init(void) +{ + Cy_SysPm_Init(); + Cy_SysPm_SetDeepSleepMode(CY_SYSPM_MODE_DEEPSLEEP); + + return 0; +} + +SYS_INIT(ifx_pm_init, PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); diff --git a/soc/infineon/cat1b/psc3/power.h b/soc/infineon/cat1b/psc3/power.h new file mode 100644 index 000000000000..3f82aa9d780c --- /dev/null +++ b/soc/infineon/cat1b/psc3/power.h @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __IFX_POWER_H +#define __IFX_POWER_H + +void get_sleep_info(uint32_t *sleepattempts, uint32_t *sleepcounts, uint32_t *deepsleepattempts, + uint32_t *deepsleepcounts, int64_t *sleeptime); + +#endif From 415986b89fb38dd27b4d125759afa4a19c9357c2 Mon Sep 17 00:00:00 2001 From: Richard Mc Sweeney Date: Fri, 19 Dec 2025 09:18:26 -0800 Subject: [PATCH 1899/3659] dts: arm: infineon cat1b psc3 Add power-states to PSC3 Signed-off-by: Richard Mc Sweeney --- .../kit_psc3m5_evk/kit_psc3m5_evk.yaml | 1 + dts/arm/infineon/cat1b/psc3/psc3.cm33.dtsi | 15 +++++++ soc/infineon/cat1b/psc3/Kconfig.defconfig | 5 +-- soc/infineon/cat1b/psc3/power.c | 41 ++----------------- soc/infineon/cat1b/psc3/power.h | 14 ------- 5 files changed, 20 insertions(+), 56 deletions(-) delete mode 100644 soc/infineon/cat1b/psc3/power.h diff --git a/boards/infineon/kit_psc3m5_evk/kit_psc3m5_evk.yaml b/boards/infineon/kit_psc3m5_evk/kit_psc3m5_evk.yaml index c4019cb91b8c..ec7983e4db39 100644 --- a/boards/infineon/kit_psc3m5_evk/kit_psc3m5_evk.yaml +++ b/boards/infineon/kit_psc3m5_evk/kit_psc3m5_evk.yaml @@ -15,6 +15,7 @@ toolchain: supported: - gpio - spi + - timer - uart - dma vendor: infineon diff --git a/dts/arm/infineon/cat1b/psc3/psc3.cm33.dtsi b/dts/arm/infineon/cat1b/psc3/psc3.cm33.dtsi index bd6de75dbf71..a3f6beb2c272 100644 --- a/dts/arm/infineon/cat1b/psc3/psc3.cm33.dtsi +++ b/dts/arm/infineon/cat1b/psc3/psc3.cm33.dtsi @@ -18,6 +18,21 @@ compatible = "arm,cortex-m33"; reg = <0>; clock-frequency = <180000000>; + cpu-power-states = <&sleep &deepsleep>; + }; + + power-states { + sleep: sleep { + compatible = "zephyr,power-state"; + power-state-name = "suspend-to-idle"; + min-residency-us = <1000000>; + }; + + deepsleep: deepsleep { + compatible = "zephyr,power-state"; + power-state-name = "suspend-to-ram"; + min-residency-us = <2000000>; + }; }; }; }; diff --git a/soc/infineon/cat1b/psc3/Kconfig.defconfig b/soc/infineon/cat1b/psc3/Kconfig.defconfig index 435eb9181007..c91d28b7eff3 100644 --- a/soc/infineon/cat1b/psc3/Kconfig.defconfig +++ b/soc/infineon/cat1b/psc3/Kconfig.defconfig @@ -19,11 +19,8 @@ if SOC_SERIES_PSC3 -config INFINEON_CAT1_LP_TIMER_PDL - default n - config CORTEX_M_SYSTICK - default n if INFINEON_CAT1_LP_TIMER_PDL + default n if INFINEON_LP_TIMER_PDL config NUM_IRQS default 140 diff --git a/soc/infineon/cat1b/psc3/power.c b/soc/infineon/cat1b/psc3/power.c index 80523be9ed0b..7e3c8ab019a1 100644 --- a/soc/infineon/cat1b/psc3/power.c +++ b/soc/infineon/cat1b/psc3/power.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025 Infineon Technologies AG, + * Copyright (c) 2026 Infineon Technologies AG, * or an affiliate of Infineon Technologies AG. * * SPDX-License-Identifier: Apache-2.0 @@ -19,23 +19,6 @@ LOG_MODULE_REGISTER(soc_power, CONFIG_SOC_LOG_LEVEL); -uint32_t sleep_attempt_counts; -uint32_t sleep_counts; -uint32_t deepsleep_attempt_counts; -uint32_t deepsleep_counts; -int64_t last_sleep_start; -int64_t last_sleep_duration; - -void get_sleep_info(uint32_t *sleepattempts, uint32_t *sleepcounts, uint32_t *deepsleepattempts, - uint32_t *deepsleepcounts, int64_t *sleeptime) -{ - *sleepattempts = sleep_attempt_counts; - *sleepcounts = sleep_counts; - *deepsleepattempts = deepsleep_attempt_counts; - *deepsleepcounts = deepsleep_counts; - *sleeptime = last_sleep_duration; -} - /* * Called from pm_system_suspend(int32_t ticks) in subsys/power.c * For deep sleep pm_system_suspend has executed all the driver @@ -57,19 +40,11 @@ __weak void pm_state_set(enum pm_state state, uint8_t substate_id) switch (state) { case PM_STATE_SUSPEND_TO_IDLE: LOG_DBG("Entering PM state suspend to idle"); - sleep_attempt_counts++; - last_sleep_start = k_uptime_ticks(); - if (Cy_SysPm_CpuEnterSleep(CY_SYSPM_WAIT_FOR_INTERRUPT) == CY_RSLT_SUCCESS) { - sleep_counts++; - } + Cy_SysPm_CpuEnterSleep(CY_SYSPM_WAIT_FOR_INTERRUPT); break; case PM_STATE_SUSPEND_TO_RAM: LOG_DBG("Entering PM state suspend to RAM"); - deepsleep_attempt_counts++; - last_sleep_start = k_uptime_ticks(); - if (Cy_SysPm_CpuEnterDeepSleep(CY_SYSPM_WAIT_FOR_INTERRUPT) == CY_RSLT_SUCCESS) { - deepsleep_counts++; - } + Cy_SysPm_CpuEnterDeepSleep(CY_SYSPM_WAIT_FOR_INTERRUPT); /* * The HAL function doesn't clear this bit. It is a problem * if the Zephyr idle function executes the wfi instruction @@ -98,16 +73,6 @@ __weak void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) /* Clear PRIMASK */ __enable_irq(); - - switch (state) { - case PM_STATE_SUSPEND_TO_IDLE: - case PM_STATE_SUSPEND_TO_RAM: - last_sleep_duration = last_sleep_start - k_uptime_ticks(); - break; - - default: - break; - } } static int ifx_pm_init(void) diff --git a/soc/infineon/cat1b/psc3/power.h b/soc/infineon/cat1b/psc3/power.h deleted file mode 100644 index 3f82aa9d780c..000000000000 --- a/soc/infineon/cat1b/psc3/power.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright (c) 2025 Infineon Technologies AG, - * or an affiliate of Infineon Technologies AG. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef __IFX_POWER_H -#define __IFX_POWER_H - -void get_sleep_info(uint32_t *sleepattempts, uint32_t *sleepcounts, uint32_t *deepsleepattempts, - uint32_t *deepsleepcounts, int64_t *sleeptime); - -#endif From 213d95358cf242228aba0d71ef6b95b669980b60 Mon Sep 17 00:00:00 2001 From: Richard Mc Sweeney Date: Tue, 13 Jan 2026 11:41:28 -0800 Subject: [PATCH 1900/3659] dts: arm: infineon cat1b mpns Disabled flash controller as it is not yet updated to support PSC3 Signed-off-by: Richard Mc Sweeney --- dts/arm/infineon/cat1b/mpns/psc3m3edabq1_s.dtsi | 1 + dts/arm/infineon/cat1b/mpns/psc3m3edacq1_s.dtsi | 1 + dts/arm/infineon/cat1b/mpns/psc3m3edlgq1_s.dtsi | 1 + dts/arm/infineon/cat1b/mpns/psc3m3edlhq1_s.dtsi | 1 + dts/arm/infineon/cat1b/mpns/psc3m3fds2abq1_s.dtsi | 1 + dts/arm/infineon/cat1b/mpns/psc3m3fds2acq1_s.dtsi | 1 + dts/arm/infineon/cat1b/mpns/psc3m3fds2lgq1_s.dtsi | 1 + dts/arm/infineon/cat1b/mpns/psc3m3fds2lhq1_s.dtsi | 1 + dts/arm/infineon/cat1b/mpns/psc3m5edabq1_s.dtsi | 1 + dts/arm/infineon/cat1b/mpns/psc3m5edacq1_s.dtsi | 1 + dts/arm/infineon/cat1b/mpns/psc3m5edafq1_s.dtsi | 1 + dts/arm/infineon/cat1b/mpns/psc3m5edlgq1_s.dtsi | 1 + dts/arm/infineon/cat1b/mpns/psc3m5edlhq1_s.dtsi | 1 + dts/arm/infineon/cat1b/mpns/psc3m5fds2abq1_s.dtsi | 1 + dts/arm/infineon/cat1b/mpns/psc3m5fds2acq1_s.dtsi | 1 + dts/arm/infineon/cat1b/mpns/psc3m5fds2afq1_s.dtsi | 1 + dts/arm/infineon/cat1b/mpns/psc3m5fds2lgq1_s.dtsi | 1 + dts/arm/infineon/cat1b/mpns/psc3m5fds2lhq1_s.dtsi | 1 + dts/arm/infineon/cat1b/mpns/psc3p2edabq1_s.dtsi | 1 + dts/arm/infineon/cat1b/mpns/psc3p2edacq1_s.dtsi | 1 + dts/arm/infineon/cat1b/mpns/psc3p2edlgq1_s.dtsi | 1 + dts/arm/infineon/cat1b/mpns/psc3p2edlhq1_s.dtsi | 1 + dts/arm/infineon/cat1b/mpns/psc3p2fds2abq1_s.dtsi | 1 + dts/arm/infineon/cat1b/mpns/psc3p2fds2acq1_s.dtsi | 1 + dts/arm/infineon/cat1b/mpns/psc3p2fds2lgq1_s.dtsi | 1 + dts/arm/infineon/cat1b/mpns/psc3p2fds2lhq1_s.dtsi | 1 + dts/arm/infineon/cat1b/mpns/psc3p5edabq1_s.dtsi | 1 + dts/arm/infineon/cat1b/mpns/psc3p5edacq1_s.dtsi | 1 + dts/arm/infineon/cat1b/mpns/psc3p5edlgq1_s.dtsi | 1 + dts/arm/infineon/cat1b/mpns/psc3p5edlhq1_s.dtsi | 1 + dts/arm/infineon/cat1b/mpns/psc3p5fds2abq1_s.dtsi | 1 + dts/arm/infineon/cat1b/mpns/psc3p5fds2acq1_s.dtsi | 1 + dts/arm/infineon/cat1b/mpns/psc3p5fds2lgq1_s.dtsi | 1 + dts/arm/infineon/cat1b/mpns/psc3p5fds2lhq1_s.dtsi | 1 + 34 files changed, 34 insertions(+) diff --git a/dts/arm/infineon/cat1b/mpns/psc3m3edabq1_s.dtsi b/dts/arm/infineon/cat1b/mpns/psc3m3edabq1_s.dtsi index 0fa0a84728a7..edf64c58ef3b 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3m3edabq1_s.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3m3edabq1_s.dtsi @@ -18,6 +18,7 @@ reg = <0x52150000 0x10000>; #address-cells = <1>; #size-cells = <1>; + status = "disabled"; flash0: flash@12000000 { compatible = "soc-nv-flash"; diff --git a/dts/arm/infineon/cat1b/mpns/psc3m3edacq1_s.dtsi b/dts/arm/infineon/cat1b/mpns/psc3m3edacq1_s.dtsi index 1673003ebc62..135734d946aa 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3m3edacq1_s.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3m3edacq1_s.dtsi @@ -18,6 +18,7 @@ reg = <0x52150000 0x10000>; #address-cells = <1>; #size-cells = <1>; + status = "disabled"; flash0: flash@12000000 { compatible = "soc-nv-flash"; diff --git a/dts/arm/infineon/cat1b/mpns/psc3m3edlgq1_s.dtsi b/dts/arm/infineon/cat1b/mpns/psc3m3edlgq1_s.dtsi index 14418ffe62ef..d9a7fd2be0b5 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3m3edlgq1_s.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3m3edlgq1_s.dtsi @@ -18,6 +18,7 @@ reg = <0x52150000 0x10000>; #address-cells = <1>; #size-cells = <1>; + status = "disabled"; flash0: flash@12000000 { compatible = "soc-nv-flash"; diff --git a/dts/arm/infineon/cat1b/mpns/psc3m3edlhq1_s.dtsi b/dts/arm/infineon/cat1b/mpns/psc3m3edlhq1_s.dtsi index 1cf6bafe84f3..466c8f4723de 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3m3edlhq1_s.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3m3edlhq1_s.dtsi @@ -18,6 +18,7 @@ reg = <0x52150000 0x10000>; #address-cells = <1>; #size-cells = <1>; + status = "disabled"; flash0: flash@12000000 { compatible = "soc-nv-flash"; diff --git a/dts/arm/infineon/cat1b/mpns/psc3m3fds2abq1_s.dtsi b/dts/arm/infineon/cat1b/mpns/psc3m3fds2abq1_s.dtsi index 0233102f3588..a309e511cf10 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3m3fds2abq1_s.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3m3fds2abq1_s.dtsi @@ -18,6 +18,7 @@ reg = <0x52150000 0x10000>; #address-cells = <1>; #size-cells = <1>; + status = "disabled"; flash0: flash@12000000 { compatible = "soc-nv-flash"; diff --git a/dts/arm/infineon/cat1b/mpns/psc3m3fds2acq1_s.dtsi b/dts/arm/infineon/cat1b/mpns/psc3m3fds2acq1_s.dtsi index 1e38e0316e4c..7a6b0103d42b 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3m3fds2acq1_s.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3m3fds2acq1_s.dtsi @@ -18,6 +18,7 @@ reg = <0x52150000 0x10000>; #address-cells = <1>; #size-cells = <1>; + status = "disabled"; flash0: flash@12000000 { compatible = "soc-nv-flash"; diff --git a/dts/arm/infineon/cat1b/mpns/psc3m3fds2lgq1_s.dtsi b/dts/arm/infineon/cat1b/mpns/psc3m3fds2lgq1_s.dtsi index 31fa1fa12544..0ceec472eb41 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3m3fds2lgq1_s.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3m3fds2lgq1_s.dtsi @@ -18,6 +18,7 @@ reg = <0x52150000 0x10000>; #address-cells = <1>; #size-cells = <1>; + status = "disabled"; flash0: flash@12000000 { compatible = "soc-nv-flash"; diff --git a/dts/arm/infineon/cat1b/mpns/psc3m3fds2lhq1_s.dtsi b/dts/arm/infineon/cat1b/mpns/psc3m3fds2lhq1_s.dtsi index dbe341f5f20e..db343bb11425 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3m3fds2lhq1_s.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3m3fds2lhq1_s.dtsi @@ -18,6 +18,7 @@ reg = <0x52150000 0x10000>; #address-cells = <1>; #size-cells = <1>; + status = "disabled"; flash0: flash@12000000 { compatible = "soc-nv-flash"; diff --git a/dts/arm/infineon/cat1b/mpns/psc3m5edabq1_s.dtsi b/dts/arm/infineon/cat1b/mpns/psc3m5edabq1_s.dtsi index 4058b054d148..66cc496d6b01 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3m5edabq1_s.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3m5edabq1_s.dtsi @@ -14,6 +14,7 @@ reg = <0x52150000 0x10000>; #address-cells = <1>; #size-cells = <1>; + status = "disabled"; flash0: flash@12000000 { compatible = "soc-nv-flash"; diff --git a/dts/arm/infineon/cat1b/mpns/psc3m5edacq1_s.dtsi b/dts/arm/infineon/cat1b/mpns/psc3m5edacq1_s.dtsi index 3ca533edfc4c..c94ba4f2e904 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3m5edacq1_s.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3m5edacq1_s.dtsi @@ -14,6 +14,7 @@ reg = <0x52150000 0x10000>; #address-cells = <1>; #size-cells = <1>; + status = "disabled"; flash0: flash@12000000 { compatible = "soc-nv-flash"; diff --git a/dts/arm/infineon/cat1b/mpns/psc3m5edafq1_s.dtsi b/dts/arm/infineon/cat1b/mpns/psc3m5edafq1_s.dtsi index 4cb94d93957a..136cd490dbf8 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3m5edafq1_s.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3m5edafq1_s.dtsi @@ -14,6 +14,7 @@ reg = <0x52150000 0x10000>; #address-cells = <1>; #size-cells = <1>; + status = "disabled"; flash0: flash@12000000 { compatible = "soc-nv-flash"; diff --git a/dts/arm/infineon/cat1b/mpns/psc3m5edlgq1_s.dtsi b/dts/arm/infineon/cat1b/mpns/psc3m5edlgq1_s.dtsi index ca986e03dba8..e633a06d3d6a 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3m5edlgq1_s.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3m5edlgq1_s.dtsi @@ -14,6 +14,7 @@ reg = <0x52150000 0x10000>; #address-cells = <1>; #size-cells = <1>; + status = "disabled"; flash0: flash@12000000 { compatible = "soc-nv-flash"; diff --git a/dts/arm/infineon/cat1b/mpns/psc3m5edlhq1_s.dtsi b/dts/arm/infineon/cat1b/mpns/psc3m5edlhq1_s.dtsi index 7bc908ea2b38..9e4866984637 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3m5edlhq1_s.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3m5edlhq1_s.dtsi @@ -14,6 +14,7 @@ reg = <0x52150000 0x10000>; #address-cells = <1>; #size-cells = <1>; + status = "disabled"; flash0: flash@12000000 { compatible = "soc-nv-flash"; diff --git a/dts/arm/infineon/cat1b/mpns/psc3m5fds2abq1_s.dtsi b/dts/arm/infineon/cat1b/mpns/psc3m5fds2abq1_s.dtsi index f38f0c7d95dc..7a2a8a66fb48 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3m5fds2abq1_s.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3m5fds2abq1_s.dtsi @@ -14,6 +14,7 @@ reg = <0x52150000 0x10000>; #address-cells = <1>; #size-cells = <1>; + status = "disabled"; flash0: flash@12000000 { compatible = "soc-nv-flash"; diff --git a/dts/arm/infineon/cat1b/mpns/psc3m5fds2acq1_s.dtsi b/dts/arm/infineon/cat1b/mpns/psc3m5fds2acq1_s.dtsi index dd965b5d93ba..afadb2f2e63e 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3m5fds2acq1_s.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3m5fds2acq1_s.dtsi @@ -14,6 +14,7 @@ reg = <0x52150000 0x10000>; #address-cells = <1>; #size-cells = <1>; + status = "disabled"; flash0: flash@12000000 { compatible = "soc-nv-flash"; diff --git a/dts/arm/infineon/cat1b/mpns/psc3m5fds2afq1_s.dtsi b/dts/arm/infineon/cat1b/mpns/psc3m5fds2afq1_s.dtsi index 11ea1663e6a5..45f4b6e4b999 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3m5fds2afq1_s.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3m5fds2afq1_s.dtsi @@ -14,6 +14,7 @@ reg = <0x52150000 0x10000>; #address-cells = <1>; #size-cells = <1>; + status = "disabled"; flash0: flash@12000000 { compatible = "soc-nv-flash"; diff --git a/dts/arm/infineon/cat1b/mpns/psc3m5fds2lgq1_s.dtsi b/dts/arm/infineon/cat1b/mpns/psc3m5fds2lgq1_s.dtsi index 0c3da22f29e1..f00ce2aedebc 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3m5fds2lgq1_s.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3m5fds2lgq1_s.dtsi @@ -14,6 +14,7 @@ reg = <0x52150000 0x10000>; #address-cells = <1>; #size-cells = <1>; + status = "disabled"; flash0: flash@12000000 { compatible = "soc-nv-flash"; diff --git a/dts/arm/infineon/cat1b/mpns/psc3m5fds2lhq1_s.dtsi b/dts/arm/infineon/cat1b/mpns/psc3m5fds2lhq1_s.dtsi index 90bb53f27f50..bb517fff2870 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3m5fds2lhq1_s.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3m5fds2lhq1_s.dtsi @@ -14,6 +14,7 @@ reg = <0x52150000 0x10000>; #address-cells = <1>; #size-cells = <1>; + status = "disabled"; flash0: flash@12000000 { compatible = "soc-nv-flash"; diff --git a/dts/arm/infineon/cat1b/mpns/psc3p2edabq1_s.dtsi b/dts/arm/infineon/cat1b/mpns/psc3p2edabq1_s.dtsi index 0fa0a84728a7..edf64c58ef3b 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3p2edabq1_s.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3p2edabq1_s.dtsi @@ -18,6 +18,7 @@ reg = <0x52150000 0x10000>; #address-cells = <1>; #size-cells = <1>; + status = "disabled"; flash0: flash@12000000 { compatible = "soc-nv-flash"; diff --git a/dts/arm/infineon/cat1b/mpns/psc3p2edacq1_s.dtsi b/dts/arm/infineon/cat1b/mpns/psc3p2edacq1_s.dtsi index 1673003ebc62..135734d946aa 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3p2edacq1_s.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3p2edacq1_s.dtsi @@ -18,6 +18,7 @@ reg = <0x52150000 0x10000>; #address-cells = <1>; #size-cells = <1>; + status = "disabled"; flash0: flash@12000000 { compatible = "soc-nv-flash"; diff --git a/dts/arm/infineon/cat1b/mpns/psc3p2edlgq1_s.dtsi b/dts/arm/infineon/cat1b/mpns/psc3p2edlgq1_s.dtsi index 14418ffe62ef..d9a7fd2be0b5 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3p2edlgq1_s.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3p2edlgq1_s.dtsi @@ -18,6 +18,7 @@ reg = <0x52150000 0x10000>; #address-cells = <1>; #size-cells = <1>; + status = "disabled"; flash0: flash@12000000 { compatible = "soc-nv-flash"; diff --git a/dts/arm/infineon/cat1b/mpns/psc3p2edlhq1_s.dtsi b/dts/arm/infineon/cat1b/mpns/psc3p2edlhq1_s.dtsi index 1cf6bafe84f3..466c8f4723de 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3p2edlhq1_s.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3p2edlhq1_s.dtsi @@ -18,6 +18,7 @@ reg = <0x52150000 0x10000>; #address-cells = <1>; #size-cells = <1>; + status = "disabled"; flash0: flash@12000000 { compatible = "soc-nv-flash"; diff --git a/dts/arm/infineon/cat1b/mpns/psc3p2fds2abq1_s.dtsi b/dts/arm/infineon/cat1b/mpns/psc3p2fds2abq1_s.dtsi index 0233102f3588..a309e511cf10 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3p2fds2abq1_s.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3p2fds2abq1_s.dtsi @@ -18,6 +18,7 @@ reg = <0x52150000 0x10000>; #address-cells = <1>; #size-cells = <1>; + status = "disabled"; flash0: flash@12000000 { compatible = "soc-nv-flash"; diff --git a/dts/arm/infineon/cat1b/mpns/psc3p2fds2acq1_s.dtsi b/dts/arm/infineon/cat1b/mpns/psc3p2fds2acq1_s.dtsi index 1e38e0316e4c..7a6b0103d42b 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3p2fds2acq1_s.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3p2fds2acq1_s.dtsi @@ -18,6 +18,7 @@ reg = <0x52150000 0x10000>; #address-cells = <1>; #size-cells = <1>; + status = "disabled"; flash0: flash@12000000 { compatible = "soc-nv-flash"; diff --git a/dts/arm/infineon/cat1b/mpns/psc3p2fds2lgq1_s.dtsi b/dts/arm/infineon/cat1b/mpns/psc3p2fds2lgq1_s.dtsi index 31fa1fa12544..0ceec472eb41 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3p2fds2lgq1_s.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3p2fds2lgq1_s.dtsi @@ -18,6 +18,7 @@ reg = <0x52150000 0x10000>; #address-cells = <1>; #size-cells = <1>; + status = "disabled"; flash0: flash@12000000 { compatible = "soc-nv-flash"; diff --git a/dts/arm/infineon/cat1b/mpns/psc3p2fds2lhq1_s.dtsi b/dts/arm/infineon/cat1b/mpns/psc3p2fds2lhq1_s.dtsi index dbe341f5f20e..db343bb11425 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3p2fds2lhq1_s.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3p2fds2lhq1_s.dtsi @@ -18,6 +18,7 @@ reg = <0x52150000 0x10000>; #address-cells = <1>; #size-cells = <1>; + status = "disabled"; flash0: flash@12000000 { compatible = "soc-nv-flash"; diff --git a/dts/arm/infineon/cat1b/mpns/psc3p5edabq1_s.dtsi b/dts/arm/infineon/cat1b/mpns/psc3p5edabq1_s.dtsi index 4058b054d148..66cc496d6b01 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3p5edabq1_s.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3p5edabq1_s.dtsi @@ -14,6 +14,7 @@ reg = <0x52150000 0x10000>; #address-cells = <1>; #size-cells = <1>; + status = "disabled"; flash0: flash@12000000 { compatible = "soc-nv-flash"; diff --git a/dts/arm/infineon/cat1b/mpns/psc3p5edacq1_s.dtsi b/dts/arm/infineon/cat1b/mpns/psc3p5edacq1_s.dtsi index 3ca533edfc4c..c94ba4f2e904 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3p5edacq1_s.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3p5edacq1_s.dtsi @@ -14,6 +14,7 @@ reg = <0x52150000 0x10000>; #address-cells = <1>; #size-cells = <1>; + status = "disabled"; flash0: flash@12000000 { compatible = "soc-nv-flash"; diff --git a/dts/arm/infineon/cat1b/mpns/psc3p5edlgq1_s.dtsi b/dts/arm/infineon/cat1b/mpns/psc3p5edlgq1_s.dtsi index ca986e03dba8..e633a06d3d6a 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3p5edlgq1_s.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3p5edlgq1_s.dtsi @@ -14,6 +14,7 @@ reg = <0x52150000 0x10000>; #address-cells = <1>; #size-cells = <1>; + status = "disabled"; flash0: flash@12000000 { compatible = "soc-nv-flash"; diff --git a/dts/arm/infineon/cat1b/mpns/psc3p5edlhq1_s.dtsi b/dts/arm/infineon/cat1b/mpns/psc3p5edlhq1_s.dtsi index 7bc908ea2b38..9e4866984637 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3p5edlhq1_s.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3p5edlhq1_s.dtsi @@ -14,6 +14,7 @@ reg = <0x52150000 0x10000>; #address-cells = <1>; #size-cells = <1>; + status = "disabled"; flash0: flash@12000000 { compatible = "soc-nv-flash"; diff --git a/dts/arm/infineon/cat1b/mpns/psc3p5fds2abq1_s.dtsi b/dts/arm/infineon/cat1b/mpns/psc3p5fds2abq1_s.dtsi index f38f0c7d95dc..7a2a8a66fb48 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3p5fds2abq1_s.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3p5fds2abq1_s.dtsi @@ -14,6 +14,7 @@ reg = <0x52150000 0x10000>; #address-cells = <1>; #size-cells = <1>; + status = "disabled"; flash0: flash@12000000 { compatible = "soc-nv-flash"; diff --git a/dts/arm/infineon/cat1b/mpns/psc3p5fds2acq1_s.dtsi b/dts/arm/infineon/cat1b/mpns/psc3p5fds2acq1_s.dtsi index dd965b5d93ba..afadb2f2e63e 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3p5fds2acq1_s.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3p5fds2acq1_s.dtsi @@ -14,6 +14,7 @@ reg = <0x52150000 0x10000>; #address-cells = <1>; #size-cells = <1>; + status = "disabled"; flash0: flash@12000000 { compatible = "soc-nv-flash"; diff --git a/dts/arm/infineon/cat1b/mpns/psc3p5fds2lgq1_s.dtsi b/dts/arm/infineon/cat1b/mpns/psc3p5fds2lgq1_s.dtsi index 0c3da22f29e1..f00ce2aedebc 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3p5fds2lgq1_s.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3p5fds2lgq1_s.dtsi @@ -14,6 +14,7 @@ reg = <0x52150000 0x10000>; #address-cells = <1>; #size-cells = <1>; + status = "disabled"; flash0: flash@12000000 { compatible = "soc-nv-flash"; diff --git a/dts/arm/infineon/cat1b/mpns/psc3p5fds2lhq1_s.dtsi b/dts/arm/infineon/cat1b/mpns/psc3p5fds2lhq1_s.dtsi index 90bb53f27f50..bb517fff2870 100644 --- a/dts/arm/infineon/cat1b/mpns/psc3p5fds2lhq1_s.dtsi +++ b/dts/arm/infineon/cat1b/mpns/psc3p5fds2lhq1_s.dtsi @@ -14,6 +14,7 @@ reg = <0x52150000 0x10000>; #address-cells = <1>; #size-cells = <1>; + status = "disabled"; flash0: flash@12000000 { compatible = "soc-nv-flash"; From 6b2f1c19aca3ca5597f5630da3204af542b25445 Mon Sep 17 00:00:00 2001 From: Camille BAUD Date: Sat, 13 Dec 2025 00:49:51 +0100 Subject: [PATCH 1901/3659] drivers: lora: Add missing Bandwidth and Spreading Factor values Add missing values and replace arbitrary BW enum with actual value Signed-off-by: Camille BAUD --- drivers/lora/lora-basics-modem/lbm_common.c | 36 +++++++++++++++++++++ include/zephyr/drivers/lora.h | 33 +++++++++++++------ 2 files changed, 59 insertions(+), 10 deletions(-) diff --git a/drivers/lora/lora-basics-modem/lbm_common.c b/drivers/lora/lora-basics-modem/lbm_common.c index a7fce9dac74b..02a2ef9fde68 100644 --- a/drivers/lora/lora-basics-modem/lbm_common.c +++ b/drivers/lora/lora-basics-modem/lbm_common.c @@ -105,15 +105,51 @@ int lbm_lora_config(const struct device *dev, struct lora_modem_config *lora_con } switch (lora_config->bandwidth) { + case BW_7_KHZ: + params.mod_params.bw = RAL_LORA_BW_007_KHZ; + break; + case BW_10_KHZ: + params.mod_params.bw = RAL_LORA_BW_010_KHZ; + break; + case BW_15_KHZ: + params.mod_params.bw = RAL_LORA_BW_015_KHZ; + break; + case BW_20_KHZ: + params.mod_params.bw = RAL_LORA_BW_020_KHZ; + break; + case BW_31_KHZ: + params.mod_params.bw = RAL_LORA_BW_031_KHZ; + break; + case BW_41_KHZ: + params.mod_params.bw = RAL_LORA_BW_041_KHZ; + break; + case BW_62_KHZ: + params.mod_params.bw = RAL_LORA_BW_062_KHZ; + break; case BW_125_KHZ: params.mod_params.bw = RAL_LORA_BW_125_KHZ; break; + case BW_200_KHZ: + params.mod_params.bw = RAL_LORA_BW_200_KHZ; + break; case BW_250_KHZ: params.mod_params.bw = RAL_LORA_BW_250_KHZ; break; + case BW_400_KHZ: + params.mod_params.bw = RAL_LORA_BW_400_KHZ; + break; case BW_500_KHZ: params.mod_params.bw = RAL_LORA_BW_500_KHZ; break; + case BW_800_KHZ: + params.mod_params.bw = RAL_LORA_BW_800_KHZ; + break; + case BW_1000_KHZ: + params.mod_params.bw = RAL_LORA_BW_1000_KHZ; + break; + case BW_1600_KHZ: + params.mod_params.bw = RAL_LORA_BW_1600_KHZ; + break; default: ret = -EINVAL; goto release; diff --git a/include/zephyr/drivers/lora.h b/include/zephyr/drivers/lora.h index f224b4f05429..b49b950b5d65 100644 --- a/include/zephyr/drivers/lora.h +++ b/include/zephyr/drivers/lora.h @@ -38,9 +38,21 @@ extern "C" { * higher data rates but typically reduce sensitivity and range. */ enum lora_signal_bandwidth { - BW_125_KHZ = 0, /**< 125 kHz */ - BW_250_KHZ, /**< 250 kHz */ - BW_500_KHZ, /**< 500 kHz */ + BW_7_KHZ = 7, /**< 7.81 kHz */ + BW_10_KHZ = 10, /**< 10.42 kHz */ + BW_15_KHZ = 15, /**< 15.63 kHz */ + BW_20_KHZ = 20, /**< 20.83 kHz */ + BW_31_KHZ = 31, /**< 31.25 kHz */ + BW_41_KHZ = 41, /**< 41.67 kHz */ + BW_62_KHZ = 62, /**< 62.5 kHz */ + BW_125_KHZ = 125, /**< 125 kHz */ + BW_200_KHZ = 200, /**< 203 kHz */ + BW_250_KHZ = 250, /**< 250 kHz */ + BW_400_KHZ = 400, /**< 406 kHz */ + BW_500_KHZ = 500, /**< 500 kHz */ + BW_800_KHZ = 800, /**< 812 kHz */ + BW_1000_KHZ = 1000, /**< 1000 kHz */ + BW_1600_KHZ = 1600, /**< 1625 kHz */ }; /** @@ -52,13 +64,14 @@ enum lora_signal_bandwidth { * symbol). Higher values result in lower data rates but increased range and robustness. */ enum lora_datarate { - SF_6 = 6, /**< Spreading factor 6 (fastest, shortest range) */ - SF_7, /**< Spreading factor 7 */ - SF_8, /**< Spreading factor 8 */ - SF_9, /**< Spreading factor 9 */ - SF_10, /**< Spreading factor 10 */ - SF_11, /**< Spreading factor 11 */ - SF_12, /**< Spreading factor 12 (slowest, longest range) */ + SF_5 = 5, /**< Spreading factor 5 (fastest, shortest range) */ + SF_6 = 6, /**< Spreading factor 6 */ + SF_7 = 7, /**< Spreading factor 7 */ + SF_8 = 8, /**< Spreading factor 8 */ + SF_9 = 9, /**< Spreading factor 9 */ + SF_10 = 10, /**< Spreading factor 10 */ + SF_11 = 11, /**< Spreading factor 11 */ + SF_12 = 12, /**< Spreading factor 12 (slowest, longest range) */ }; /** From cd65845ba2fb24a20f30c01b221dddbc17e472fe Mon Sep 17 00:00:00 2001 From: Camille BAUD Date: Sat, 13 Dec 2025 00:51:25 +0100 Subject: [PATCH 1902/3659] drivers: lora: Enable LDRO when symbol time > 16.38ms Enable LDRO when it should be enabled Signed-off-by: Camille BAUD --- drivers/lora/lora-basics-modem/lbm_common.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/lora/lora-basics-modem/lbm_common.c b/drivers/lora/lora-basics-modem/lbm_common.c index 02a2ef9fde68..1bcdf6862fee 100644 --- a/drivers/lora/lora-basics-modem/lbm_common.c +++ b/drivers/lora/lora-basics-modem/lbm_common.c @@ -16,6 +16,14 @@ LOG_MODULE_REGISTER(lbm_driver, CONFIG_LORA_LOG_LEVEL); +/* When Symbol Time exceeds 16.38 ms (6.1.1.4 SX1261/2 datasheet), enable LDRO + * Symbol Rate is bw / (2 ^ sf) so Symbol time is (2 ^ sf) / bw (6.1.1.1 SX1261/2 datasheet) + * Additionally, enable LDRO in additional situations described in Lora Basic Modem lr1mac + * where t < 16 from ral_compute_lora_ldro: Bandwidth less than 41 Khz, and SF9 with BW 41 KHz + */ +#define LORA_LDRO(sf, bw) ((((1 << sf) / bw) >= 16 ? 1 : 0) \ + | (bw < BW_41_KHZ || (bw == BW_41_KHZ && sf == SF_9) ? 1 : 0)) + /** * @brief Attempt to acquire the modem for operations * @@ -73,7 +81,7 @@ int lbm_lora_config(const struct device *dev, struct lora_modem_config *lora_con .mod_params = { .sf = lora_config->datarate, .cr = lora_config->coding_rate, - .ldro = 0, + .ldro = LORA_LDRO(lora_config->datarate, lora_config->bandwidth), }, .pkt_params = { .preamble_len_in_symb = lora_config->preamble_len, From bc07d91ccacd26833afd2793efe41f42e737aa0c Mon Sep 17 00:00:00 2001 From: Camille BAUD Date: Sat, 13 Dec 2025 01:08:12 +0100 Subject: [PATCH 1903/3659] drivers: lora: Add ability to force enable LDRO Allows Enabling LDRO all the time via DTS Signed-off-by: Camille BAUD --- drivers/lora/lora-basics-modem/lbm_common.c | 3 ++- drivers/lora/lora-basics-modem/lbm_common.h | 1 + drivers/lora/lora-basics-modem/lbm_sx126x.c | 1 + drivers/lora/lora-basics-modem/lbm_sx127x.c | 1 + dts/bindings/lora/semtech,sx126x-base.yaml | 6 ++++++ dts/bindings/lora/semtech,sx127x-base.yaml | 6 ++++++ 6 files changed, 17 insertions(+), 1 deletion(-) diff --git a/drivers/lora/lora-basics-modem/lbm_common.c b/drivers/lora/lora-basics-modem/lbm_common.c index 1bcdf6862fee..59402b66a27e 100644 --- a/drivers/lora/lora-basics-modem/lbm_common.c +++ b/drivers/lora/lora-basics-modem/lbm_common.c @@ -81,7 +81,8 @@ int lbm_lora_config(const struct device *dev, struct lora_modem_config *lora_con .mod_params = { .sf = lora_config->datarate, .cr = lora_config->coding_rate, - .ldro = LORA_LDRO(lora_config->datarate, lora_config->bandwidth), + .ldro = config->force_ldro ? 1 : LORA_LDRO(lora_config->datarate, + lora_config->bandwidth), }, .pkt_params = { .preamble_len_in_symb = lora_config->preamble_len, diff --git a/drivers/lora/lora-basics-modem/lbm_common.h b/drivers/lora/lora-basics-modem/lbm_common.h index e78b500a5b87..ad13e58cb4db 100644 --- a/drivers/lora/lora-basics-modem/lbm_common.h +++ b/drivers/lora/lora-basics-modem/lbm_common.h @@ -34,6 +34,7 @@ enum lbm_modem_mode { struct lbm_lora_config_common { /* LBM radio abstration layer structure */ ralf_t ralf; + bool force_ldro; }; /* Common LBM modem data, must be first element of device data */ diff --git a/drivers/lora/lora-basics-modem/lbm_sx126x.c b/drivers/lora/lora-basics-modem/lbm_sx126x.c index ab71e64d16e4..6be78584903b 100644 --- a/drivers/lora/lora-basics-modem/lbm_sx126x.c +++ b/drivers/lora/lora-basics-modem/lbm_sx126x.c @@ -574,6 +574,7 @@ static int sx126x_init(const struct device *dev) #define SX126X_DEFINE(node_id, sx_variant) \ static const struct lbm_sx126x_config config_##node_id = { \ .lbm_common.ralf = RALF_SX126X_INSTANTIATE(DEVICE_DT_GET(node_id)), \ + .lbm_common.force_ldro = DT_PROP(node_id, force_ldro), \ .spi = SPI_DT_SPEC_GET( \ node_id, SPI_WORD_SET(8) | SPI_OP_MODE_MASTER | SPI_TRANSFER_MSB), \ .reset = GPIO_DT_SPEC_GET(node_id, reset_gpios), \ diff --git a/drivers/lora/lora-basics-modem/lbm_sx127x.c b/drivers/lora/lora-basics-modem/lbm_sx127x.c index 7a62c1709ed8..75fc8f72a216 100644 --- a/drivers/lora/lora-basics-modem/lbm_sx127x.c +++ b/drivers/lora/lora-basics-modem/lbm_sx127x.c @@ -467,6 +467,7 @@ static int sx127x_driver_init(const struct device *dev) static struct lbm_sx127x_data data_##node_id; \ static const struct lbm_sx127x_config config_##node_id = { \ .lbm_common.ralf = RALF_SX127X_INSTANTIATE(&data_##node_id.radio), \ + .lbm_common.force_ldro = DT_PROP(node_id, force_ldro), \ .spi = SPI_DT_SPEC_GET( \ node_id, SPI_WORD_SET(8) | SPI_OP_MODE_MASTER | SPI_TRANSFER_MSB), \ .reset = GPIO_DT_SPEC_GET(node_id, reset_gpios), \ diff --git a/dts/bindings/lora/semtech,sx126x-base.yaml b/dts/bindings/lora/semtech,sx126x-base.yaml index 72143f2564f8..2d13d7586950 100644 --- a/dts/bindings/lora/semtech,sx126x-base.yaml +++ b/dts/bindings/lora/semtech,sx126x-base.yaml @@ -70,3 +70,9 @@ properties: type: boolean description: | Use the internal LDO instead of the internal DCDC. Increases power consumption. + + force-ldro: + type: boolean + description: | + Force usage of Low Data Rate Optimization even in cases where the symbol time is shorter than + 16.38ms. Useful for designs using no TCXO or with bad heat dissipation. diff --git a/dts/bindings/lora/semtech,sx127x-base.yaml b/dts/bindings/lora/semtech,sx127x-base.yaml index 6a7b92f4b27d..aca0cb792925 100644 --- a/dts/bindings/lora/semtech,sx127x-base.yaml +++ b/dts/bindings/lora/semtech,sx127x-base.yaml @@ -61,3 +61,9 @@ properties: type: int description: | Delay which has to be applied after enabling TCXO power. + + force-ldro: + type: boolean + description: | + Force usage of Low Data Rate Optimization even in cases where the symbol time is shorter than + 16.38ms. Useful for designs using no TCXO or with bad heat dissipation. From 174f1f71c4ce9c6d6c8637becd8b0d1d89b9d410 Mon Sep 17 00:00:00 2001 From: Zhaoxiang Jin Date: Mon, 22 Dec 2025 18:54:05 +0800 Subject: [PATCH 1904/3659] soc: nxp: scope boot-header compile defs to soc library Create a dedicated Zephyr library for the imxrt11xx and imxrt10xx SoC in CMakeLists.txt and move soc.c into it (zephyr_library() + zephyr_library_sources(soc.c)). Signed-off-by: Zhaoxiang Jin --- soc/nxp/imxrt/imxrt10xx/CMakeLists.txt | 3 ++- soc/nxp/imxrt/imxrt11xx/CMakeLists.txt | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/soc/nxp/imxrt/imxrt10xx/CMakeLists.txt b/soc/nxp/imxrt/imxrt10xx/CMakeLists.txt index 77421318acc2..de77d7715681 100644 --- a/soc/nxp/imxrt/imxrt10xx/CMakeLists.txt +++ b/soc/nxp/imxrt/imxrt10xx/CMakeLists.txt @@ -4,7 +4,8 @@ # SPDX-License-Identifier: Apache-2.0 # -zephyr_sources(soc.c) +zephyr_library() +zephyr_library_sources(soc.c) if(CONFIG_PM) zephyr_sources(power.c) diff --git a/soc/nxp/imxrt/imxrt11xx/CMakeLists.txt b/soc/nxp/imxrt/imxrt11xx/CMakeLists.txt index 960129d5cba7..6ce77d631963 100644 --- a/soc/nxp/imxrt/imxrt11xx/CMakeLists.txt +++ b/soc/nxp/imxrt/imxrt11xx/CMakeLists.txt @@ -4,7 +4,8 @@ # SPDX-License-Identifier: Apache-2.0 # -zephyr_sources(soc.c) +zephyr_library() +zephyr_library_sources(soc.c) zephyr_sources_ifdef(CONFIG_PM power.c) zephyr_include_directories(.) From a86a84afdfe119f3011503a6a396a839ea53b02e Mon Sep 17 00:00:00 2001 From: Zhaoxiang Jin Date: Fri, 26 Dec 2025 15:57:30 +0800 Subject: [PATCH 1905/3659] boards: nxp: remove 'BOARD_FLASH_SIZE' for RTxxx boards Flag 'BOARD_FLASH_SIZE' is not used for RTxxx, so remove it from mimxrt595_evk, mimxrt685_evk, and mimxrt700_evk board CMakeLists.txt files. Normally, 'BOARD_FLASH_SIZE' should not be used elsewhere. If an out-of-tree user uses this flag elsewhere, please define the flag yourself. Signed-off-by: Zhaoxiang Jin --- boards/nxp/mimxrt595_evk/CMakeLists.txt | 2 +- boards/nxp/mimxrt685_evk/CMakeLists.txt | 2 +- boards/nxp/mimxrt700_evk/CMakeLists.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/boards/nxp/mimxrt595_evk/CMakeLists.txt b/boards/nxp/mimxrt595_evk/CMakeLists.txt index 328d2e248185..23332490c805 100644 --- a/boards/nxp/mimxrt595_evk/CMakeLists.txt +++ b/boards/nxp/mimxrt595_evk/CMakeLists.txt @@ -16,11 +16,11 @@ if(CONFIG_NXP_IMXRT_BOOT_HEADER) "the MIMXRT595-EVK, but targeting a custom board. You may need to " "update your flash configuration block data") endif() + # This flash configuration block may need modification if another # flash chip is used on your custom board. See NXP AN13304 for more # information. zephyr_compile_definitions(BOOT_HEADER_ENABLE=1) - zephyr_compile_definitions(BOARD_FLASH_SIZE=CONFIG_FLASH_SIZE*1024) zephyr_library_sources(flash_config/flash_config.c) zephyr_library_include_directories(flash_config) endif() diff --git a/boards/nxp/mimxrt685_evk/CMakeLists.txt b/boards/nxp/mimxrt685_evk/CMakeLists.txt index cfe2c2f07cf8..05924a93ac27 100644 --- a/boards/nxp/mimxrt685_evk/CMakeLists.txt +++ b/boards/nxp/mimxrt685_evk/CMakeLists.txt @@ -18,11 +18,11 @@ if(CONFIG_NXP_IMXRT_BOOT_HEADER) "the MIMXRT685-EVK, but targeting a custom board. You may need to " "update your flash configuration block data") endif() + # This flash configuration block may need modification if another # flash chip is used on your custom board. See NXP AN13386 for more # information. zephyr_compile_definitions(BOOT_HEADER_ENABLE=1) - zephyr_compile_definitions(BOARD_FLASH_SIZE=CONFIG_FLASH_SIZE*1024) zephyr_library_sources(flash_config/flash_config.c) zephyr_library_include_directories(flash_config) endif() diff --git a/boards/nxp/mimxrt700_evk/CMakeLists.txt b/boards/nxp/mimxrt700_evk/CMakeLists.txt index ea4dff764b2d..e2c927aeb22e 100644 --- a/boards/nxp/mimxrt700_evk/CMakeLists.txt +++ b/boards/nxp/mimxrt700_evk/CMakeLists.txt @@ -16,11 +16,11 @@ if(CONFIG_NXP_IMXRT_BOOT_HEADER) "the MIMXRT7xx-EVK, but targeting a custom board. You may need to " "update your flash configuration block data") endif() + # This flash configuration block may need modification if another # flash chip is used on your custom board. See NXP AN13304 for more # information. zephyr_compile_definitions(BOOT_HEADER_ENABLE=1) - zephyr_compile_definitions(BOARD_FLASH_SIZE=CONFIG_FLASH_SIZE*1024) zephyr_library_sources(flash_config/flash_config.c) zephyr_library_include_directories(flash_config) endif() From 7ff326ef56e51dea1f6133b1c948bf07e287a27c Mon Sep 17 00:00:00 2001 From: Zhaoxiang Jin Date: Fri, 26 Dec 2025 15:57:40 +0800 Subject: [PATCH 1906/3659] boards: nxp: move 'BOARD_FLASH_SIZE' to SoC layer cmake For RT10xx and RT11xx, flag 'BOARD_FLASH_SIZE' is only used in hal_nxp fsl_flexspi_nor_boot.h which is included by soc.c, therefore, this flag should be passed in the SoC layer CMake using zephyr_library_compile_definitions() to limit its scope. Normally, 'BOARD_FLASH_SIZE' should not be used elsewhere. If an out-of-tree user uses this flag elsewhere, please define the flag yourself. Signed-off-by: Zhaoxiang Jin --- boards/nxp/mimxrt1010_evk/CMakeLists.txt | 1 - boards/nxp/mimxrt1015_evk/CMakeLists.txt | 1 - boards/nxp/mimxrt1020_evk/CMakeLists.txt | 1 - boards/nxp/mimxrt1024_evk/CMakeLists.txt | 1 - boards/nxp/mimxrt1040_evk/CMakeLists.txt | 1 - boards/nxp/mimxrt1050_evk/CMakeLists.txt | 1 - boards/nxp/mimxrt1060_evk/CMakeLists.txt | 1 - boards/nxp/mimxrt1062_fmurt6/CMakeLists.txt | 1 - boards/nxp/mimxrt1064_evk/CMakeLists.txt | 1 - boards/nxp/mimxrt1160_evk/CMakeLists.txt | 1 - boards/nxp/mimxrt1170_evk/CMakeLists.txt | 1 - boards/nxp/vmu_rt1170/CMakeLists.txt | 1 - soc/nxp/imxrt/imxrt10xx/CMakeLists.txt | 8 +++++++- soc/nxp/imxrt/imxrt11xx/CMakeLists.txt | 5 +++++ 14 files changed, 12 insertions(+), 13 deletions(-) diff --git a/boards/nxp/mimxrt1010_evk/CMakeLists.txt b/boards/nxp/mimxrt1010_evk/CMakeLists.txt index 08fee53a4117..79463e9c0f11 100644 --- a/boards/nxp/mimxrt1010_evk/CMakeLists.txt +++ b/boards/nxp/mimxrt1010_evk/CMakeLists.txt @@ -18,7 +18,6 @@ if(CONFIG_NXP_IMXRT_BOOT_HEADER) # flash chip is used on your custom board. See NXP AN12238 for more # information. zephyr_compile_definitions(XIP_BOOT_HEADER_ENABLE=1) - zephyr_compile_definitions(BOARD_FLASH_SIZE=CONFIG_FLASH_SIZE*1024) zephyr_library_sources(xip/evkmimxrt1010_flexspi_nor_config.c) zephyr_library_include_directories(xip) endif() diff --git a/boards/nxp/mimxrt1015_evk/CMakeLists.txt b/boards/nxp/mimxrt1015_evk/CMakeLists.txt index c4c7adf0e77d..9c62e6eb4575 100644 --- a/boards/nxp/mimxrt1015_evk/CMakeLists.txt +++ b/boards/nxp/mimxrt1015_evk/CMakeLists.txt @@ -17,7 +17,6 @@ if(CONFIG_NXP_IMXRT_BOOT_HEADER) # flash chip is used on your custom board. See NXP AN12238 for more # information. zephyr_compile_definitions(XIP_BOOT_HEADER_ENABLE=1) - zephyr_compile_definitions(BOARD_FLASH_SIZE=CONFIG_FLASH_SIZE*1024) zephyr_library_sources(xip/evkmimxrt1015_flexspi_nor_config.c) zephyr_library_include_directories(xip) endif() diff --git a/boards/nxp/mimxrt1020_evk/CMakeLists.txt b/boards/nxp/mimxrt1020_evk/CMakeLists.txt index 1ae0fae86e2d..d35895a518e1 100644 --- a/boards/nxp/mimxrt1020_evk/CMakeLists.txt +++ b/boards/nxp/mimxrt1020_evk/CMakeLists.txt @@ -17,7 +17,6 @@ if(CONFIG_NXP_IMXRT_BOOT_HEADER) # flash chip is used on your custom board. See NXP AN12238 for more # information. zephyr_compile_definitions(XIP_BOOT_HEADER_ENABLE=1) - zephyr_compile_definitions(BOARD_FLASH_SIZE=CONFIG_FLASH_SIZE*1024) zephyr_library_sources(xip/evkmimxrt1020_flexspi_nor_config.c) zephyr_library_include_directories(xip) endif() diff --git a/boards/nxp/mimxrt1024_evk/CMakeLists.txt b/boards/nxp/mimxrt1024_evk/CMakeLists.txt index 22d2fcdd8ae7..39af29a7f68e 100644 --- a/boards/nxp/mimxrt1024_evk/CMakeLists.txt +++ b/boards/nxp/mimxrt1024_evk/CMakeLists.txt @@ -17,7 +17,6 @@ if(CONFIG_NXP_IMXRT_BOOT_HEADER) # flash chip is used on your custom board. See NXP AN12238 for more # information. zephyr_compile_definitions(XIP_BOOT_HEADER_ENABLE=1) - zephyr_compile_definitions(BOARD_FLASH_SIZE=CONFIG_FLASH_SIZE*1024) zephyr_library_sources(xip/evkmimxrt1024_flexspi_nor_config.c) zephyr_library_include_directories(xip) endif() diff --git a/boards/nxp/mimxrt1040_evk/CMakeLists.txt b/boards/nxp/mimxrt1040_evk/CMakeLists.txt index deea9bbcc9d9..2480a8fcb409 100644 --- a/boards/nxp/mimxrt1040_evk/CMakeLists.txt +++ b/boards/nxp/mimxrt1040_evk/CMakeLists.txt @@ -22,7 +22,6 @@ if(CONFIG_NXP_IMXRT_BOOT_HEADER) # flash chip is used on your custom board. See NXP AN12238 for more # information. zephyr_compile_definitions(XIP_BOOT_HEADER_ENABLE=1) - zephyr_compile_definitions(BOARD_FLASH_SIZE=CONFIG_FLASH_SIZE*1024) zephyr_library_sources(xip/evkmimxrt1040_flexspi_nor_config.c) zephyr_library_include_directories(xip) endif() diff --git a/boards/nxp/mimxrt1050_evk/CMakeLists.txt b/boards/nxp/mimxrt1050_evk/CMakeLists.txt index 3efb8f6f72e8..eac4e1b150e7 100644 --- a/boards/nxp/mimxrt1050_evk/CMakeLists.txt +++ b/boards/nxp/mimxrt1050_evk/CMakeLists.txt @@ -28,7 +28,6 @@ if(CONFIG_NXP_IMXRT_BOOT_HEADER) # flash chip is used on your custom board. See NXP AN12238 for more # information. zephyr_compile_definitions(XIP_BOOT_HEADER_ENABLE=1) - zephyr_compile_definitions(BOARD_FLASH_SIZE=CONFIG_FLASH_SIZE*1024) zephyr_library_sources(xip/${FLASH_CONF}) zephyr_library_include_directories(xip) endif() diff --git a/boards/nxp/mimxrt1060_evk/CMakeLists.txt b/boards/nxp/mimxrt1060_evk/CMakeLists.txt index 4d293e42d6e9..5dd4047f691a 100644 --- a/boards/nxp/mimxrt1060_evk/CMakeLists.txt +++ b/boards/nxp/mimxrt1060_evk/CMakeLists.txt @@ -38,7 +38,6 @@ if(CONFIG_NXP_IMXRT_BOOT_HEADER) # flash chip is used on your custom board. See NXP AN12238 for more # information. zephyr_compile_definitions(XIP_BOOT_HEADER_ENABLE=1) - zephyr_compile_definitions(BOARD_FLASH_SIZE=CONFIG_FLASH_SIZE*1024) zephyr_library_sources(${RT1060_BOARD_DIR}/xip/${FLASH_CONF}) zephyr_library_include_directories(${RT1060_BOARD_DIR}/xip) endif() diff --git a/boards/nxp/mimxrt1062_fmurt6/CMakeLists.txt b/boards/nxp/mimxrt1062_fmurt6/CMakeLists.txt index 2d0bfaecab48..777517718c24 100644 --- a/boards/nxp/mimxrt1062_fmurt6/CMakeLists.txt +++ b/boards/nxp/mimxrt1062_fmurt6/CMakeLists.txt @@ -19,7 +19,6 @@ if(CONFIG_NXP_IMXRT_BOOT_HEADER) # This configuration block may need modification if another flash chip is # used on your custom board. See NXP AN12238 for more information. zephyr_compile_definitions(XIP_BOOT_HEADER_ENABLE=1) - zephyr_compile_definitions(BOARD_FLASH_SIZE=CONFIG_FLASH_SIZE*1024) zephyr_library_sources(${RT1062_BOARD_DIR}/xip/${FLASH_CONF}) zephyr_library_include_directories(${RT1062_BOARD_DIR}/xip) endif() diff --git a/boards/nxp/mimxrt1064_evk/CMakeLists.txt b/boards/nxp/mimxrt1064_evk/CMakeLists.txt index 0b2ef8b7db9d..9981aef406c1 100644 --- a/boards/nxp/mimxrt1064_evk/CMakeLists.txt +++ b/boards/nxp/mimxrt1064_evk/CMakeLists.txt @@ -22,7 +22,6 @@ if(CONFIG_NXP_IMXRT_BOOT_HEADER) # flash chip is used on your custom board. See NXP AN12238 for more # information. zephyr_compile_definitions(XIP_BOOT_HEADER_ENABLE=1) - zephyr_compile_definitions(BOARD_FLASH_SIZE=CONFIG_FLASH_SIZE*1024) zephyr_library_sources(xip/evkmimxrt1064_flexspi_nor_config.c) zephyr_library_include_directories(xip) endif() diff --git a/boards/nxp/mimxrt1160_evk/CMakeLists.txt b/boards/nxp/mimxrt1160_evk/CMakeLists.txt index 9f08c80b8bfe..ada107dbafba 100644 --- a/boards/nxp/mimxrt1160_evk/CMakeLists.txt +++ b/boards/nxp/mimxrt1160_evk/CMakeLists.txt @@ -17,7 +17,6 @@ if(CONFIG_NXP_IMXRT_BOOT_HEADER) # flash chip is used on your custom board. See NXP AN12238 for more # information. zephyr_compile_definitions(XIP_BOOT_HEADER_ENABLE=1) - zephyr_compile_definitions(BOARD_FLASH_SIZE=CONFIG_FLASH_SIZE*1024) zephyr_library_sources(xip/evkmimxrt1160_flexspi_nor_config.c) zephyr_library_include_directories(xip) endif() diff --git a/boards/nxp/mimxrt1170_evk/CMakeLists.txt b/boards/nxp/mimxrt1170_evk/CMakeLists.txt index ae57c284c9d8..da29cacbbb93 100644 --- a/boards/nxp/mimxrt1170_evk/CMakeLists.txt +++ b/boards/nxp/mimxrt1170_evk/CMakeLists.txt @@ -22,7 +22,6 @@ if(CONFIG_NXP_IMXRT_BOOT_HEADER) # flash chip is used on your custom board. See NXP AN12238 for more # information. zephyr_compile_definitions(XIP_BOOT_HEADER_ENABLE=1) - zephyr_compile_definitions(BOARD_FLASH_SIZE=CONFIG_FLASH_SIZE*1024) zephyr_library_sources(xip/${RT1170_BOARD_NAME}_flexspi_nor_config.c) zephyr_library_include_directories(xip) endif() diff --git a/boards/nxp/vmu_rt1170/CMakeLists.txt b/boards/nxp/vmu_rt1170/CMakeLists.txt index db5f2b91259b..39d77a09ee77 100644 --- a/boards/nxp/vmu_rt1170/CMakeLists.txt +++ b/boards/nxp/vmu_rt1170/CMakeLists.txt @@ -11,7 +11,6 @@ if(CONFIG_NXP_IMXRT_BOOT_HEADER) # flash chip is used on your custom board. See NXP AN12238 for more # information. zephyr_compile_definitions(XIP_BOOT_HEADER_ENABLE=1) - zephyr_compile_definitions(BOARD_FLASH_SIZE=CONFIG_FLASH_SIZE*1024) zephyr_library_sources(flexspi_nor_config.c) zephyr_library_include_directories(xip) endif() diff --git a/soc/nxp/imxrt/imxrt10xx/CMakeLists.txt b/soc/nxp/imxrt/imxrt10xx/CMakeLists.txt index de77d7715681..02e149b8d4ca 100644 --- a/soc/nxp/imxrt/imxrt10xx/CMakeLists.txt +++ b/soc/nxp/imxrt/imxrt10xx/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2024 NXP +# Copyright 2024-2025 NXP # # SPDX-License-Identifier: Apache-2.0 # @@ -23,6 +23,12 @@ if(CONFIG_MEMC_MCUX_FLEXSPI) endif() endif() +if(CONFIG_NXP_IMXRT_BOOT_HEADER) + if(CONFIG_BOOT_FLEXSPI_NOR) + zephyr_library_compile_definitions(BOARD_FLASH_SIZE=CONFIG_FLASH_SIZE*1024) + endif() +endif() + zephyr_include_directories(.) set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld CACHE INTERNAL "") diff --git a/soc/nxp/imxrt/imxrt11xx/CMakeLists.txt b/soc/nxp/imxrt/imxrt11xx/CMakeLists.txt index 6ce77d631963..6547dfe35d77 100644 --- a/soc/nxp/imxrt/imxrt11xx/CMakeLists.txt +++ b/soc/nxp/imxrt/imxrt11xx/CMakeLists.txt @@ -22,5 +22,10 @@ if(CONFIG_SECOND_CORE_MCUX_REMOTE_DIR) zephyr_include_directories(${CONFIG_SECOND_CORE_MCUX_REMOTE_DIR}) endif() +if(CONFIG_NXP_IMXRT_BOOT_HEADER) + if(CONFIG_BOOT_FLEXSPI_NOR) + zephyr_library_compile_definitions(BOARD_FLASH_SIZE=CONFIG_FLASH_SIZE*1024) + endif() +endif() set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld CACHE INTERNAL "") From 2849272e6089bde136fcfc84c1d519cdd8014463 Mon Sep 17 00:00:00 2001 From: Zhaoxiang Jin Date: Tue, 23 Dec 2025 13:01:37 +0800 Subject: [PATCH 1907/3659] boards: nxp: convert 'XIP_BOOT_HEADER_ENABLE' to Kconfig options 1. This commit converts the 'XIP_BOOT_HEADER_ENABLE' preprocessor define to Kconfig options across NXP i.MX RTxxxx evaluation boards. The changes enable flexible boot header configuration through the Kconfig build system instead of compile-time defines, improving configurability and maintainability. 2. Now 'XIP_BOOT_HEADER_ENABLE' flag is only used in hal_nxp/rt11xx/fsl_flexspi_nor_boot.h which is included by soc.c, therefore, this flag should be passed in the rt11xx/SoC layer CMake using zephyr_library_compile_definitions(). and can be removed from each board CMakeLists.txt. Note: if out-of-tree files still need to use this flag, please add it in your own CMakeLists.txt. Signed-off-by: Zhaoxiang Jin --- boards/nxp/mimxrt1010_evk/CMakeLists.txt | 1 - .../nxp/mimxrt1010_evk/xip/evkmimxrt1010_flexspi_nor_config.c | 4 ++-- boards/nxp/mimxrt1015_evk/CMakeLists.txt | 1 - .../nxp/mimxrt1015_evk/xip/evkmimxrt1015_flexspi_nor_config.c | 4 ++-- boards/nxp/mimxrt1020_evk/CMakeLists.txt | 1 - boards/nxp/mimxrt1020_evk/dcd/dcd.c | 4 ++-- .../nxp/mimxrt1020_evk/xip/evkmimxrt1020_flexspi_nor_config.c | 4 ++-- boards/nxp/mimxrt1024_evk/CMakeLists.txt | 1 - boards/nxp/mimxrt1024_evk/dcd/dcd.c | 4 ++-- .../nxp/mimxrt1024_evk/xip/evkmimxrt1024_flexspi_nor_config.c | 4 ++-- boards/nxp/mimxrt1040_evk/CMakeLists.txt | 1 - boards/nxp/mimxrt1040_evk/dcd/dcd.c | 4 ++-- .../nxp/mimxrt1040_evk/xip/evkmimxrt1040_flexspi_nor_config.c | 4 ++-- boards/nxp/mimxrt1050_evk/CMakeLists.txt | 1 - boards/nxp/mimxrt1050_evk/dcd/dcd.c | 4 ++-- .../nxp/mimxrt1050_evk/xip/evkbimxrt1050_flexspi_nor_config.c | 4 ++-- .../xip/evkbimxrt1050_flexspi_nor_qspi_config.c | 4 ++-- boards/nxp/mimxrt1060_evk/CMakeLists.txt | 1 - boards/nxp/mimxrt1060_evk/dcd/dcd.c | 4 ++-- .../mimxrt1060_evk/xip/evkbmimxrt1060_flexspi_nor_config.c | 4 ++-- .../nxp/mimxrt1060_evk/xip/evkmimxrt1060_flexspi_nor_config.c | 4 ++-- boards/nxp/mimxrt1062_fmurt6/CMakeLists.txt | 1 - boards/nxp/mimxrt1064_evk/CMakeLists.txt | 1 - boards/nxp/mimxrt1064_evk/dcd/dcd.c | 4 ++-- .../nxp/mimxrt1064_evk/xip/evkmimxrt1064_flexspi_nor_config.c | 4 ++-- boards/nxp/mimxrt1160_evk/CMakeLists.txt | 1 - boards/nxp/mimxrt1160_evk/dcd/dcd.c | 4 ++-- .../nxp/mimxrt1160_evk/xip/evkmimxrt1160_flexspi_nor_config.c | 4 ++-- boards/nxp/mimxrt1170_evk/CMakeLists.txt | 1 - boards/nxp/mimxrt1170_evk/dcd/dcd.c | 4 ++-- .../mimxrt1170_evk/xip/evkbmimxrt1170_flexspi_nor_config.c | 4 ++-- .../nxp/mimxrt1170_evk/xip/evkmimxrt1170_flexspi_nor_config.c | 4 ++-- boards/nxp/mimxrt1170_evk/xmcd/xmcd.c | 4 ++-- boards/nxp/mimxrt1180_evk/CMakeLists.txt | 1 - .../nxp/mimxrt1180_evk/xip/evkmimxrt1180_flexspi_nor_config.c | 4 ++-- boards/nxp/vmu_rt1170/CMakeLists.txt | 1 - boards/nxp/vmu_rt1170/xip/evkmimxrt1170_flexspi_nor_config.c | 4 ++-- soc/nxp/imxrt/imxrt11xx/CMakeLists.txt | 1 + 38 files changed, 49 insertions(+), 61 deletions(-) diff --git a/boards/nxp/mimxrt1010_evk/CMakeLists.txt b/boards/nxp/mimxrt1010_evk/CMakeLists.txt index 79463e9c0f11..0ec99819388c 100644 --- a/boards/nxp/mimxrt1010_evk/CMakeLists.txt +++ b/boards/nxp/mimxrt1010_evk/CMakeLists.txt @@ -17,7 +17,6 @@ if(CONFIG_NXP_IMXRT_BOOT_HEADER) # This flash configuration block may need modification if another # flash chip is used on your custom board. See NXP AN12238 for more # information. - zephyr_compile_definitions(XIP_BOOT_HEADER_ENABLE=1) zephyr_library_sources(xip/evkmimxrt1010_flexspi_nor_config.c) zephyr_library_include_directories(xip) endif() diff --git a/boards/nxp/mimxrt1010_evk/xip/evkmimxrt1010_flexspi_nor_config.c b/boards/nxp/mimxrt1010_evk/xip/evkmimxrt1010_flexspi_nor_config.c index f98b40271b1f..05947cf5fda6 100644 --- a/boards/nxp/mimxrt1010_evk/xip/evkmimxrt1010_flexspi_nor_config.c +++ b/boards/nxp/mimxrt1010_evk/xip/evkmimxrt1010_flexspi_nor_config.c @@ -7,7 +7,7 @@ #include "evkmimxrt1010_flexspi_nor_config.h" -#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) +#if defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_BOOT_FLEXSPI_NOR) __attribute__((section(".boot_hdr.conf"), used)) const flexspi_nor_config_t qspi_flash_config = { @@ -63,4 +63,4 @@ const flexspi_nor_config_t qspi_flash_config = { .is_uniform_block_size = false, }; -#endif /* XIP_BOOT_HEADER_ENABLE */ +#endif /* defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_BOOT_FLEXSPI_NOR) */ diff --git a/boards/nxp/mimxrt1015_evk/CMakeLists.txt b/boards/nxp/mimxrt1015_evk/CMakeLists.txt index 9c62e6eb4575..1c022b96173d 100644 --- a/boards/nxp/mimxrt1015_evk/CMakeLists.txt +++ b/boards/nxp/mimxrt1015_evk/CMakeLists.txt @@ -16,7 +16,6 @@ if(CONFIG_NXP_IMXRT_BOOT_HEADER) # This flash configuration block may need modification if another # flash chip is used on your custom board. See NXP AN12238 for more # information. - zephyr_compile_definitions(XIP_BOOT_HEADER_ENABLE=1) zephyr_library_sources(xip/evkmimxrt1015_flexspi_nor_config.c) zephyr_library_include_directories(xip) endif() diff --git a/boards/nxp/mimxrt1015_evk/xip/evkmimxrt1015_flexspi_nor_config.c b/boards/nxp/mimxrt1015_evk/xip/evkmimxrt1015_flexspi_nor_config.c index 2828312818c9..5582b4754c51 100644 --- a/boards/nxp/mimxrt1015_evk/xip/evkmimxrt1015_flexspi_nor_config.c +++ b/boards/nxp/mimxrt1015_evk/xip/evkmimxrt1015_flexspi_nor_config.c @@ -7,7 +7,7 @@ #include "evkmimxrt1015_flexspi_nor_config.h" -#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) +#if defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_BOOT_FLEXSPI_NOR) __attribute__((section(".boot_hdr.conf"), used)) const flexspi_nor_config_t qspi_flash_config = { @@ -65,4 +65,4 @@ const flexspi_nor_config_t qspi_flash_config = { .is_uniform_block_size = false, }; -#endif /* XIP_BOOT_HEADER_ENABLE */ +#endif /* defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_BOOT_FLEXSPI_NOR) */ diff --git a/boards/nxp/mimxrt1020_evk/CMakeLists.txt b/boards/nxp/mimxrt1020_evk/CMakeLists.txt index d35895a518e1..682a27f1fd20 100644 --- a/boards/nxp/mimxrt1020_evk/CMakeLists.txt +++ b/boards/nxp/mimxrt1020_evk/CMakeLists.txt @@ -16,7 +16,6 @@ if(CONFIG_NXP_IMXRT_BOOT_HEADER) # This flash configuration block may need modification if another # flash chip is used on your custom board. See NXP AN12238 for more # information. - zephyr_compile_definitions(XIP_BOOT_HEADER_ENABLE=1) zephyr_library_sources(xip/evkmimxrt1020_flexspi_nor_config.c) zephyr_library_include_directories(xip) endif() diff --git a/boards/nxp/mimxrt1020_evk/dcd/dcd.c b/boards/nxp/mimxrt1020_evk/dcd/dcd.c index 3b679f893d1a..d6e5e7370145 100644 --- a/boards/nxp/mimxrt1020_evk/dcd/dcd.c +++ b/boards/nxp/mimxrt1020_evk/dcd/dcd.c @@ -7,7 +7,7 @@ #include "dcd.h" -#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) +#if defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_BOOT_FLEXSPI_NOR) #if defined(XIP_BOOT_HEADER_DCD_ENABLE) && (XIP_BOOT_HEADER_DCD_ENABLE == 1) __attribute__((section(".boot_hdr.dcd_data"), used)) @@ -592,4 +592,4 @@ const uint8_t dcd_data[] = { #else const uint8_t dcd_data[] = {0x00}; #endif /* XIP_BOOT_HEADER_DCD_ENABLE */ -#endif /* XIP_BOOT_HEADER_ENABLE */ +#endif /* defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_BOOT_FLEXSPI_NOR) */ diff --git a/boards/nxp/mimxrt1020_evk/xip/evkmimxrt1020_flexspi_nor_config.c b/boards/nxp/mimxrt1020_evk/xip/evkmimxrt1020_flexspi_nor_config.c index fc93d11de5f3..8d9fb1dc8c7e 100644 --- a/boards/nxp/mimxrt1020_evk/xip/evkmimxrt1020_flexspi_nor_config.c +++ b/boards/nxp/mimxrt1020_evk/xip/evkmimxrt1020_flexspi_nor_config.c @@ -7,7 +7,7 @@ #include "evkmimxrt1020_flexspi_nor_config.h" -#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) +#if defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_BOOT_FLEXSPI_NOR) __attribute__((section(".boot_hdr.conf"), used)) #define FLASH_DUMMY_CYCLES 0x08 @@ -85,4 +85,4 @@ const flexspi_nor_config_t qspi_flash_config = { .is_uniform_block_size = false, }; -#endif /* XIP_BOOT_HEADER_ENABLE */ +#endif /* defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_BOOT_FLEXSPI_NOR) */ diff --git a/boards/nxp/mimxrt1024_evk/CMakeLists.txt b/boards/nxp/mimxrt1024_evk/CMakeLists.txt index 39af29a7f68e..aeb72bfe882f 100644 --- a/boards/nxp/mimxrt1024_evk/CMakeLists.txt +++ b/boards/nxp/mimxrt1024_evk/CMakeLists.txt @@ -16,7 +16,6 @@ if(CONFIG_NXP_IMXRT_BOOT_HEADER) # This flash configuration block may need modification if another # flash chip is used on your custom board. See NXP AN12238 for more # information. - zephyr_compile_definitions(XIP_BOOT_HEADER_ENABLE=1) zephyr_library_sources(xip/evkmimxrt1024_flexspi_nor_config.c) zephyr_library_include_directories(xip) endif() diff --git a/boards/nxp/mimxrt1024_evk/dcd/dcd.c b/boards/nxp/mimxrt1024_evk/dcd/dcd.c index e274fbdf84a7..4a6fc611b4c3 100644 --- a/boards/nxp/mimxrt1024_evk/dcd/dcd.c +++ b/boards/nxp/mimxrt1024_evk/dcd/dcd.c @@ -7,7 +7,7 @@ #include "dcd.h" -#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) +#if defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_BOOT_FLEXSPI_NOR) #if defined(XIP_BOOT_HEADER_DCD_ENABLE) && (XIP_BOOT_HEADER_DCD_ENABLE == 1) __attribute__((section(".boot_hdr.dcd_data"), used)) @@ -592,4 +592,4 @@ const uint8_t dcd_data[] = { #else const uint8_t dcd_data[] = {0x00}; #endif /* XIP_BOOT_HEADER_DCD_ENABLE */ -#endif /* XIP_BOOT_HEADER_ENABLE */ +#endif /* defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_BOOT_FLEXSPI_NOR) */ diff --git a/boards/nxp/mimxrt1024_evk/xip/evkmimxrt1024_flexspi_nor_config.c b/boards/nxp/mimxrt1024_evk/xip/evkmimxrt1024_flexspi_nor_config.c index cc9061961842..fb507f74a42a 100644 --- a/boards/nxp/mimxrt1024_evk/xip/evkmimxrt1024_flexspi_nor_config.c +++ b/boards/nxp/mimxrt1024_evk/xip/evkmimxrt1024_flexspi_nor_config.c @@ -7,7 +7,7 @@ #include "evkmimxrt1024_flexspi_nor_config.h" -#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) +#if defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_BOOT_FLEXSPI_NOR) __attribute__((section(".boot_hdr.conf"), used)) const flexspi_nor_config_t qspi_flash_config = { @@ -65,4 +65,4 @@ const flexspi_nor_config_t qspi_flash_config = { .is_uniform_block_size = false, }; -#endif /* XIP_BOOT_HEADER_ENABLE */ +#endif /* defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_BOOT_FLEXSPI_NOR) */ diff --git a/boards/nxp/mimxrt1040_evk/CMakeLists.txt b/boards/nxp/mimxrt1040_evk/CMakeLists.txt index 2480a8fcb409..ab063aaf97bd 100644 --- a/boards/nxp/mimxrt1040_evk/CMakeLists.txt +++ b/boards/nxp/mimxrt1040_evk/CMakeLists.txt @@ -21,7 +21,6 @@ if(CONFIG_NXP_IMXRT_BOOT_HEADER) # This flash configuration block may need modification if another # flash chip is used on your custom board. See NXP AN12238 for more # information. - zephyr_compile_definitions(XIP_BOOT_HEADER_ENABLE=1) zephyr_library_sources(xip/evkmimxrt1040_flexspi_nor_config.c) zephyr_library_include_directories(xip) endif() diff --git a/boards/nxp/mimxrt1040_evk/dcd/dcd.c b/boards/nxp/mimxrt1040_evk/dcd/dcd.c index a58f89a75235..3f54779f56e1 100644 --- a/boards/nxp/mimxrt1040_evk/dcd/dcd.c +++ b/boards/nxp/mimxrt1040_evk/dcd/dcd.c @@ -7,7 +7,7 @@ #include "dcd.h" -#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) +#if defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_BOOT_FLEXSPI_NOR) #if defined(XIP_BOOT_HEADER_DCD_ENABLE) && (XIP_BOOT_HEADER_DCD_ENABLE == 1) __attribute__((section(".boot_hdr.dcd_data"), used)) @@ -616,4 +616,4 @@ const uint8_t dcd_data[] = { #else const uint8_t dcd_data[] = {0x00}; #endif /* XIP_BOOT_HEADER_DCD_ENABLE */ -#endif /* XIP_BOOT_HEADER_ENABLE */ +#endif /* defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_BOOT_FLEXSPI_NOR) */ diff --git a/boards/nxp/mimxrt1040_evk/xip/evkmimxrt1040_flexspi_nor_config.c b/boards/nxp/mimxrt1040_evk/xip/evkmimxrt1040_flexspi_nor_config.c index d18458aed615..d3d0fb1ff896 100644 --- a/boards/nxp/mimxrt1040_evk/xip/evkmimxrt1040_flexspi_nor_config.c +++ b/boards/nxp/mimxrt1040_evk/xip/evkmimxrt1040_flexspi_nor_config.c @@ -7,7 +7,7 @@ #include "evkmimxrt1040_flexspi_nor_config.h" -#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) +#if defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_BOOT_FLEXSPI_NOR) __attribute__((section(".boot_hdr.conf"), used)) const flexspi_nor_config_t qspi_flash_config = { @@ -60,4 +60,4 @@ const flexspi_nor_config_t qspi_flash_config = { .is_uniform_block_size = false, }; -#endif /* XIP_BOOT_HEADER_ENABLE */ +#endif /* defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_BOOT_FLEXSPI_NOR) */ diff --git a/boards/nxp/mimxrt1050_evk/CMakeLists.txt b/boards/nxp/mimxrt1050_evk/CMakeLists.txt index eac4e1b150e7..a0c8f240eb93 100644 --- a/boards/nxp/mimxrt1050_evk/CMakeLists.txt +++ b/boards/nxp/mimxrt1050_evk/CMakeLists.txt @@ -27,7 +27,6 @@ if(CONFIG_NXP_IMXRT_BOOT_HEADER) # This flash configuration block may need modification if another # flash chip is used on your custom board. See NXP AN12238 for more # information. - zephyr_compile_definitions(XIP_BOOT_HEADER_ENABLE=1) zephyr_library_sources(xip/${FLASH_CONF}) zephyr_library_include_directories(xip) endif() diff --git a/boards/nxp/mimxrt1050_evk/dcd/dcd.c b/boards/nxp/mimxrt1050_evk/dcd/dcd.c index 181fa387fb0f..99febb5c3ded 100644 --- a/boards/nxp/mimxrt1050_evk/dcd/dcd.c +++ b/boards/nxp/mimxrt1050_evk/dcd/dcd.c @@ -7,7 +7,7 @@ #include "dcd.h" -#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) +#if defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_BOOT_FLEXSPI_NOR) #if defined(XIP_BOOT_HEADER_DCD_ENABLE) && (XIP_BOOT_HEADER_DCD_ENABLE == 1) __attribute__((section(".boot_hdr.dcd_data"), used)) @@ -616,4 +616,4 @@ const uint8_t dcd_data[] = { #else const uint8_t dcd_data[] = {0x00}; #endif /* XIP_BOOT_HEADER_DCD_ENABLE */ -#endif /* XIP_BOOT_HEADER_ENABLE */ +#endif /* defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_BOOT_FLEXSPI_NOR) */ diff --git a/boards/nxp/mimxrt1050_evk/xip/evkbimxrt1050_flexspi_nor_config.c b/boards/nxp/mimxrt1050_evk/xip/evkbimxrt1050_flexspi_nor_config.c index 07452d6ea3bf..071d25ab50b8 100644 --- a/boards/nxp/mimxrt1050_evk/xip/evkbimxrt1050_flexspi_nor_config.c +++ b/boards/nxp/mimxrt1050_evk/xip/evkbimxrt1050_flexspi_nor_config.c @@ -7,7 +7,7 @@ #include "evkbimxrt1050_flexspi_nor_config.h" -#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) +#if defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_BOOT_FLEXSPI_NOR) __attribute__((section(".boot_hdr.conf"), used)) const flexspi_nor_config_t hyperflash_config = { @@ -224,4 +224,4 @@ const flexspi_nor_config_t hyperflash_config = { .is_uniform_block_size = true, }; -#endif /* XIP_BOOT_HEADER_ENABLE */ +#endif /* defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_BOOT_FLEXSPI_NOR) */ diff --git a/boards/nxp/mimxrt1050_evk/xip/evkbimxrt1050_flexspi_nor_qspi_config.c b/boards/nxp/mimxrt1050_evk/xip/evkbimxrt1050_flexspi_nor_qspi_config.c index a6ffc8774910..750e4e127226 100644 --- a/boards/nxp/mimxrt1050_evk/xip/evkbimxrt1050_flexspi_nor_qspi_config.c +++ b/boards/nxp/mimxrt1050_evk/xip/evkbimxrt1050_flexspi_nor_qspi_config.c @@ -7,7 +7,7 @@ #include "evkbimxrt1050_flexspi_nor_config.h" -#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) +#if defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_BOOT_FLEXSPI_NOR) __attribute__((section(".boot_hdr.conf"), used)) const flexspi_nor_config_t qspi_flash_config = { @@ -34,4 +34,4 @@ const flexspi_nor_config_t qspi_flash_config = { .block_size = 64u * 1024u, .is_uniform_block_size = false, }; -#endif /* XIP_BOOT_HEADER_ENABLE */ +#endif /* defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_BOOT_FLEXSPI_NOR) */ diff --git a/boards/nxp/mimxrt1060_evk/CMakeLists.txt b/boards/nxp/mimxrt1060_evk/CMakeLists.txt index 5dd4047f691a..9ca8c6ddd856 100644 --- a/boards/nxp/mimxrt1060_evk/CMakeLists.txt +++ b/boards/nxp/mimxrt1060_evk/CMakeLists.txt @@ -37,7 +37,6 @@ if(CONFIG_NXP_IMXRT_BOOT_HEADER) # This flash configuration block may need modification if another # flash chip is used on your custom board. See NXP AN12238 for more # information. - zephyr_compile_definitions(XIP_BOOT_HEADER_ENABLE=1) zephyr_library_sources(${RT1060_BOARD_DIR}/xip/${FLASH_CONF}) zephyr_library_include_directories(${RT1060_BOARD_DIR}/xip) endif() diff --git a/boards/nxp/mimxrt1060_evk/dcd/dcd.c b/boards/nxp/mimxrt1060_evk/dcd/dcd.c index f76c1e1d16ce..e6b4f064577e 100644 --- a/boards/nxp/mimxrt1060_evk/dcd/dcd.c +++ b/boards/nxp/mimxrt1060_evk/dcd/dcd.c @@ -7,7 +7,7 @@ #include "dcd.h" -#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) +#if defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_BOOT_FLEXSPI_NOR) #if defined(XIP_BOOT_HEADER_DCD_ENABLE) && (XIP_BOOT_HEADER_DCD_ENABLE == 1) __attribute__((section(".boot_hdr.dcd_data"), used)) @@ -616,4 +616,4 @@ const uint8_t dcd_data[] = { #else const uint8_t dcd_data[] = {0x00}; #endif /* XIP_BOOT_HEADER_DCD_ENABLE */ -#endif /* XIP_BOOT_HEADER_ENABLE */ +#endif /* defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_BOOT_FLEXSPI_NOR) */ diff --git a/boards/nxp/mimxrt1060_evk/xip/evkbmimxrt1060_flexspi_nor_config.c b/boards/nxp/mimxrt1060_evk/xip/evkbmimxrt1060_flexspi_nor_config.c index 26fecbb51aac..bef955817996 100644 --- a/boards/nxp/mimxrt1060_evk/xip/evkbmimxrt1060_flexspi_nor_config.c +++ b/boards/nxp/mimxrt1060_evk/xip/evkbmimxrt1060_flexspi_nor_config.c @@ -7,7 +7,7 @@ #include "evkbmimxrt1060_flexspi_nor_config.h" -#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) +#if defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_BOOT_FLEXSPI_NOR) __attribute__((section(".boot_hdr.conf"), used)) const flexspi_nor_config_t qspi_flash_config = { @@ -65,4 +65,4 @@ const flexspi_nor_config_t qspi_flash_config = { .is_uniform_block_size = false, }; -#endif /* XIP_BOOT_HEADER_ENABLE */ +#endif /* defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_BOOT_FLEXSPI_NOR) */ diff --git a/boards/nxp/mimxrt1060_evk/xip/evkmimxrt1060_flexspi_nor_config.c b/boards/nxp/mimxrt1060_evk/xip/evkmimxrt1060_flexspi_nor_config.c index 2aa0a43fbfc6..fe61574d79cf 100644 --- a/boards/nxp/mimxrt1060_evk/xip/evkmimxrt1060_flexspi_nor_config.c +++ b/boards/nxp/mimxrt1060_evk/xip/evkmimxrt1060_flexspi_nor_config.c @@ -7,7 +7,7 @@ #include "evkmimxrt1060_flexspi_nor_config.h" -#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) +#if defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_BOOT_FLEXSPI_NOR) __attribute__((section(".boot_hdr.conf"), used)) const flexspi_nor_config_t qspi_flash_config = { @@ -65,4 +65,4 @@ const flexspi_nor_config_t qspi_flash_config = { .is_uniform_block_size = false, }; -#endif /* XIP_BOOT_HEADER_ENABLE */ +#endif /* defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_BOOT_FLEXSPI_NOR) */ diff --git a/boards/nxp/mimxrt1062_fmurt6/CMakeLists.txt b/boards/nxp/mimxrt1062_fmurt6/CMakeLists.txt index 777517718c24..4cbb2716a07b 100644 --- a/boards/nxp/mimxrt1062_fmurt6/CMakeLists.txt +++ b/boards/nxp/mimxrt1062_fmurt6/CMakeLists.txt @@ -18,7 +18,6 @@ if(CONFIG_NXP_IMXRT_BOOT_HEADER) # Include flash configuration block for RT1050 EVK from NXP's HAL. # This configuration block may need modification if another flash chip is # used on your custom board. See NXP AN12238 for more information. - zephyr_compile_definitions(XIP_BOOT_HEADER_ENABLE=1) zephyr_library_sources(${RT1062_BOARD_DIR}/xip/${FLASH_CONF}) zephyr_library_include_directories(${RT1062_BOARD_DIR}/xip) endif() diff --git a/boards/nxp/mimxrt1064_evk/CMakeLists.txt b/boards/nxp/mimxrt1064_evk/CMakeLists.txt index 9981aef406c1..28e10c510516 100644 --- a/boards/nxp/mimxrt1064_evk/CMakeLists.txt +++ b/boards/nxp/mimxrt1064_evk/CMakeLists.txt @@ -21,7 +21,6 @@ if(CONFIG_NXP_IMXRT_BOOT_HEADER) # This flash configuration block may need modification if another # flash chip is used on your custom board. See NXP AN12238 for more # information. - zephyr_compile_definitions(XIP_BOOT_HEADER_ENABLE=1) zephyr_library_sources(xip/evkmimxrt1064_flexspi_nor_config.c) zephyr_library_include_directories(xip) endif() diff --git a/boards/nxp/mimxrt1064_evk/dcd/dcd.c b/boards/nxp/mimxrt1064_evk/dcd/dcd.c index bc20b441af10..7ac3330ab47e 100644 --- a/boards/nxp/mimxrt1064_evk/dcd/dcd.c +++ b/boards/nxp/mimxrt1064_evk/dcd/dcd.c @@ -8,7 +8,7 @@ #include "dcd.h" -#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) +#if defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_BOOT_FLEXSPI_NOR) #if defined(XIP_BOOT_HEADER_DCD_ENABLE) && (XIP_BOOT_HEADER_DCD_ENABLE == 1) __attribute__((section(".boot_hdr.dcd_data"), used)) @@ -618,4 +618,4 @@ const uint8_t dcd_data[] = { #else const uint8_t dcd_data[] = {0x00}; #endif /* XIP_BOOT_HEADER_DCD_ENABLE */ -#endif /* XIP_BOOT_HEADER_ENABLE */ +#endif /* defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_BOOT_FLEXSPI_NOR) */ diff --git a/boards/nxp/mimxrt1064_evk/xip/evkmimxrt1064_flexspi_nor_config.c b/boards/nxp/mimxrt1064_evk/xip/evkmimxrt1064_flexspi_nor_config.c index 29fa415bc5b3..ef8b5b00f24d 100644 --- a/boards/nxp/mimxrt1064_evk/xip/evkmimxrt1064_flexspi_nor_config.c +++ b/boards/nxp/mimxrt1064_evk/xip/evkmimxrt1064_flexspi_nor_config.c @@ -7,7 +7,7 @@ #include "evkmimxrt1064_flexspi_nor_config.h" -#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) +#if defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_BOOT_FLEXSPI_NOR) __attribute__((section(".boot_hdr.conf"), used)) const flexspi_nor_config_t qspi_flash_config = { @@ -65,4 +65,4 @@ const flexspi_nor_config_t qspi_flash_config = { .is_uniform_block_size = false, }; -#endif /* XIP_BOOT_HEADER_ENABLE */ +#endif /* defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_BOOT_FLEXSPI_NOR) */ diff --git a/boards/nxp/mimxrt1160_evk/CMakeLists.txt b/boards/nxp/mimxrt1160_evk/CMakeLists.txt index ada107dbafba..5d686055a2ec 100644 --- a/boards/nxp/mimxrt1160_evk/CMakeLists.txt +++ b/boards/nxp/mimxrt1160_evk/CMakeLists.txt @@ -16,7 +16,6 @@ if(CONFIG_NXP_IMXRT_BOOT_HEADER) # This flash configuration block may need modification if another # flash chip is used on your custom board. See NXP AN12238 for more # information. - zephyr_compile_definitions(XIP_BOOT_HEADER_ENABLE=1) zephyr_library_sources(xip/evkmimxrt1160_flexspi_nor_config.c) zephyr_library_include_directories(xip) endif() diff --git a/boards/nxp/mimxrt1160_evk/dcd/dcd.c b/boards/nxp/mimxrt1160_evk/dcd/dcd.c index 4d906f3d7d67..028894e1e3fe 100644 --- a/boards/nxp/mimxrt1160_evk/dcd/dcd.c +++ b/boards/nxp/mimxrt1160_evk/dcd/dcd.c @@ -7,7 +7,7 @@ #include "dcd.h" -#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) +#if defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_BOOT_FLEXSPI_NOR) #if defined(XIP_BOOT_HEADER_DCD_ENABLE) && (XIP_BOOT_HEADER_DCD_ENABLE == 1) __attribute__((section(".boot_hdr.dcd_data"), used)) @@ -746,4 +746,4 @@ const uint8_t dcd_data[] = { #else const uint8_t dcd_data[] = {0x00}; #endif /* XIP_BOOT_HEADER_DCD_ENABLE */ -#endif /* XIP_BOOT_HEADER_ENABLE */ +#endif /* defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_BOOT_FLEXSPI_NOR) */ diff --git a/boards/nxp/mimxrt1160_evk/xip/evkmimxrt1160_flexspi_nor_config.c b/boards/nxp/mimxrt1160_evk/xip/evkmimxrt1160_flexspi_nor_config.c index b16ebfcff253..22fc88c7b6c2 100644 --- a/boards/nxp/mimxrt1160_evk/xip/evkmimxrt1160_flexspi_nor_config.c +++ b/boards/nxp/mimxrt1160_evk/xip/evkmimxrt1160_flexspi_nor_config.c @@ -7,7 +7,7 @@ #include "evkmimxrt1160_flexspi_nor_config.h" -#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) +#if defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_BOOT_FLEXSPI_NOR) __attribute__((section(".boot_hdr.conf"), used)) #define FLASH_DUMMY_CYCLES 0x09 @@ -89,4 +89,4 @@ const flexspi_nor_config_t qspi_flash_config = { .is_uniform_block_size = false, }; -#endif /* XIP_BOOT_HEADER_ENABLE */ +#endif /* defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_BOOT_FLEXSPI_NOR) */ diff --git a/boards/nxp/mimxrt1170_evk/CMakeLists.txt b/boards/nxp/mimxrt1170_evk/CMakeLists.txt index da29cacbbb93..9c64a98be757 100644 --- a/boards/nxp/mimxrt1170_evk/CMakeLists.txt +++ b/boards/nxp/mimxrt1170_evk/CMakeLists.txt @@ -21,7 +21,6 @@ if(CONFIG_NXP_IMXRT_BOOT_HEADER) # This flash configuration block may need modification if another # flash chip is used on your custom board. See NXP AN12238 for more # information. - zephyr_compile_definitions(XIP_BOOT_HEADER_ENABLE=1) zephyr_library_sources(xip/${RT1170_BOARD_NAME}_flexspi_nor_config.c) zephyr_library_include_directories(xip) endif() diff --git a/boards/nxp/mimxrt1170_evk/dcd/dcd.c b/boards/nxp/mimxrt1170_evk/dcd/dcd.c index 81a1ec826ec5..b68306858cd8 100644 --- a/boards/nxp/mimxrt1170_evk/dcd/dcd.c +++ b/boards/nxp/mimxrt1170_evk/dcd/dcd.c @@ -7,7 +7,7 @@ #include "dcd.h" -#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) +#if defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_BOOT_FLEXSPI_NOR) #if defined(XIP_BOOT_HEADER_DCD_ENABLE) && (XIP_BOOT_HEADER_DCD_ENABLE == 1) __attribute__((section(".boot_hdr.dcd_data"), used)) @@ -884,4 +884,4 @@ const uint8_t dcd_data[] = { #else const uint8_t dcd_data[] = {0x00}; #endif /* XIP_BOOT_HEADER_DCD_ENABLE */ -#endif /* XIP_BOOT_HEADER_ENABLE */ +#endif /* defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_BOOT_FLEXSPI_NOR) */ diff --git a/boards/nxp/mimxrt1170_evk/xip/evkbmimxrt1170_flexspi_nor_config.c b/boards/nxp/mimxrt1170_evk/xip/evkbmimxrt1170_flexspi_nor_config.c index 890e8cc1b56b..4bd28d273bea 100644 --- a/boards/nxp/mimxrt1170_evk/xip/evkbmimxrt1170_flexspi_nor_config.c +++ b/boards/nxp/mimxrt1170_evk/xip/evkbmimxrt1170_flexspi_nor_config.c @@ -7,7 +7,7 @@ #include "evkbmimxrt1170_flexspi_nor_config.h" -#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) +#if defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_BOOT_FLEXSPI_NOR) __attribute__((section(".boot_hdr.conf"), used)) #define FLASH_DUMMY_CYCLES 0x08 @@ -88,4 +88,4 @@ const flexspi_nor_config_t qspi_flash_config = { .is_uniform_block_size = false, }; -#endif /* XIP_BOOT_HEADER_ENABLE */ +#endif /* defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_BOOT_FLEXSPI_NOR) */ diff --git a/boards/nxp/mimxrt1170_evk/xip/evkmimxrt1170_flexspi_nor_config.c b/boards/nxp/mimxrt1170_evk/xip/evkmimxrt1170_flexspi_nor_config.c index 5b46ac3c9fc4..9dfae4d92511 100644 --- a/boards/nxp/mimxrt1170_evk/xip/evkmimxrt1170_flexspi_nor_config.c +++ b/boards/nxp/mimxrt1170_evk/xip/evkmimxrt1170_flexspi_nor_config.c @@ -7,7 +7,7 @@ #include "evkmimxrt1170_flexspi_nor_config.h" -#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) +#if defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_BOOT_FLEXSPI_NOR) __attribute__((section(".boot_hdr.conf"), used)) #define FLASH_DUMMY_CYCLES 0x09 @@ -86,4 +86,4 @@ const flexspi_nor_config_t qspi_flash_config = { .is_uniform_block_size = false, }; -#endif /* XIP_BOOT_HEADER_ENABLE */ +#endif /* defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_BOOT_FLEXSPI_NOR) */ diff --git a/boards/nxp/mimxrt1170_evk/xmcd/xmcd.c b/boards/nxp/mimxrt1170_evk/xmcd/xmcd.c index 3c2e848afda7..317db623859f 100644 --- a/boards/nxp/mimxrt1170_evk/xmcd/xmcd.c +++ b/boards/nxp/mimxrt1170_evk/xmcd/xmcd.c @@ -7,7 +7,7 @@ #include "xmcd.h" -#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) +#if defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_BOOT_FLEXSPI_NOR) #if defined(XIP_BOOT_HEADER_XMCD_ENABLE) && (XIP_BOOT_HEADER_XMCD_ENABLE == 1) __attribute__((section(".boot_hdr.xmcd_data"), used)) @@ -31,4 +31,4 @@ const uint32_t xmcd_data[] = { 0x02}; #endif /* XIP_BOOT_HEADER_XMCD_ENABLE */ -#endif /* XIP_BOOT_HEADER_ENABLE */ +#endif /* defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_BOOT_FLEXSPI_NOR) */ diff --git a/boards/nxp/mimxrt1180_evk/CMakeLists.txt b/boards/nxp/mimxrt1180_evk/CMakeLists.txt index 2c8b8e81479e..63e75a83b28d 100644 --- a/boards/nxp/mimxrt1180_evk/CMakeLists.txt +++ b/boards/nxp/mimxrt1180_evk/CMakeLists.txt @@ -29,7 +29,6 @@ if(CONFIG_NXP_IMXRT_BOOT_HEADER) # This flash configuration block may need modification if another # flash chip is used on your custom board. zephyr_library_compile_definitions(XIP_EXTERNAL_FLASH=1) - zephyr_compile_definitions(XIP_BOOT_HEADER_ENABLE=1) zephyr_library_sources(xip/evkmimxrt1180_flexspi_nor_config.c) zephyr_library_include_directories(xip) endif() diff --git a/boards/nxp/mimxrt1180_evk/xip/evkmimxrt1180_flexspi_nor_config.c b/boards/nxp/mimxrt1180_evk/xip/evkmimxrt1180_flexspi_nor_config.c index 72b1328e0103..613f859278ca 100644 --- a/boards/nxp/mimxrt1180_evk/xip/evkmimxrt1180_flexspi_nor_config.c +++ b/boards/nxp/mimxrt1180_evk/xip/evkmimxrt1180_flexspi_nor_config.c @@ -8,8 +8,8 @@ #include "evkmimxrt1180_flexspi_nor_config.h" /* clang-format off */ -#if defined(XIP_EXTERNAL_FLASH) && (XIP_EXTERNAL_FLASH == 1) && \ - defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) +#if defined(XIP_EXTERNAL_FLASH) && (XIP_EXTERNAL_FLASH == 1) && \ + defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_BOOT_FLEXSPI_NOR) /* clang-format on */ #if defined(USE_HYPERRAM) diff --git a/boards/nxp/vmu_rt1170/CMakeLists.txt b/boards/nxp/vmu_rt1170/CMakeLists.txt index 39d77a09ee77..0758d8ca0a4c 100644 --- a/boards/nxp/vmu_rt1170/CMakeLists.txt +++ b/boards/nxp/vmu_rt1170/CMakeLists.txt @@ -10,7 +10,6 @@ if(CONFIG_NXP_IMXRT_BOOT_HEADER) # This flash configuration block may need modification if another # flash chip is used on your custom board. See NXP AN12238 for more # information. - zephyr_compile_definitions(XIP_BOOT_HEADER_ENABLE=1) zephyr_library_sources(flexspi_nor_config.c) zephyr_library_include_directories(xip) endif() diff --git a/boards/nxp/vmu_rt1170/xip/evkmimxrt1170_flexspi_nor_config.c b/boards/nxp/vmu_rt1170/xip/evkmimxrt1170_flexspi_nor_config.c index 1b3cffd78e29..3b668f34aa9e 100644 --- a/boards/nxp/vmu_rt1170/xip/evkmimxrt1170_flexspi_nor_config.c +++ b/boards/nxp/vmu_rt1170/xip/evkmimxrt1170_flexspi_nor_config.c @@ -7,7 +7,7 @@ #include "evkmimxrt1170_flexspi_nor_config.h" -#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) +#if defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_BOOT_FLEXSPI_NOR) __attribute__((section(".boot_hdr.conf"), used)) #define FLASH_DUMMY_CYCLES 0x09 @@ -86,4 +86,4 @@ const flexspi_nor_config_t qspi_flash_config = { .block_size = 64u * 1024u, .is_uniform_block_size = false, }; -#endif /* XIP_BOOT_HEADER_ENABLE */ +#endif /* defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_BOOT_FLEXSPI_NOR) */ diff --git a/soc/nxp/imxrt/imxrt11xx/CMakeLists.txt b/soc/nxp/imxrt/imxrt11xx/CMakeLists.txt index 6547dfe35d77..fae98bb50b83 100644 --- a/soc/nxp/imxrt/imxrt11xx/CMakeLists.txt +++ b/soc/nxp/imxrt/imxrt11xx/CMakeLists.txt @@ -25,6 +25,7 @@ endif() if(CONFIG_NXP_IMXRT_BOOT_HEADER) if(CONFIG_BOOT_FLEXSPI_NOR) zephyr_library_compile_definitions(BOARD_FLASH_SIZE=CONFIG_FLASH_SIZE*1024) + zephyr_library_compile_definitions(XIP_BOOT_HEADER_ENABLE=1) endif() endif() From c323ac7f7e7e6181e8d6cd5a1c8502e9bced5875 Mon Sep 17 00:00:00 2001 From: Zhaoxiang Jin Date: Tue, 23 Dec 2025 12:56:41 +0800 Subject: [PATCH 1908/3659] boards: nxp: convert 'BOOT_HEADER_ENABLE' to Kconfig options 1. This commit converts the 'BOOT_HEADER_ENABLE' preprocessor define to Kconfig options across NXP i.MX RTxxx evaluation boards. The changes enable flexible boot header configuration through the Kconfig build system instead of compile-time defines, improving configurability and maintainability. 2. Now this flag is not used in Zephyr tree, so removed 'zephyr_compile_definitions(BOOT_HEADER_ENABLE=1)' from the CMakeLists.txt files of the following boards: - mimxrt595_evk - mimxrt685_evk - mimxrt700_evk Note: for out-of-tree projects that still require this flag, users can define it in their own CMakeLists.txt or prj.conf files. Signed-off-by: Zhaoxiang Jin --- boards/nxp/mimxrt595_evk/CMakeLists.txt | 2 -- boards/nxp/mimxrt595_evk/flash_config/flash_config.c | 4 ++-- boards/nxp/mimxrt685_evk/CMakeLists.txt | 1 - boards/nxp/mimxrt685_evk/flash_config/flash_config.c | 4 ++-- boards/nxp/mimxrt700_evk/CMakeLists.txt | 1 - boards/nxp/mimxrt700_evk/flash_config/flash_config.c | 4 ++-- 6 files changed, 6 insertions(+), 10 deletions(-) diff --git a/boards/nxp/mimxrt595_evk/CMakeLists.txt b/boards/nxp/mimxrt595_evk/CMakeLists.txt index 23332490c805..598380da19df 100644 --- a/boards/nxp/mimxrt595_evk/CMakeLists.txt +++ b/boards/nxp/mimxrt595_evk/CMakeLists.txt @@ -20,11 +20,9 @@ if(CONFIG_NXP_IMXRT_BOOT_HEADER) # This flash configuration block may need modification if another # flash chip is used on your custom board. See NXP AN13304 for more # information. - zephyr_compile_definitions(BOOT_HEADER_ENABLE=1) zephyr_library_sources(flash_config/flash_config.c) zephyr_library_include_directories(flash_config) endif() - # Add custom linker section to relocate framebuffers to PSRAM zephyr_linker_sources_ifdef(CONFIG_LV_Z_VDB_CUSTOM_SECTION SECTIONS dc_ram.ld) diff --git a/boards/nxp/mimxrt595_evk/flash_config/flash_config.c b/boards/nxp/mimxrt595_evk/flash_config/flash_config.c index a0c7a7392e06..b2660f47f869 100644 --- a/boards/nxp/mimxrt595_evk/flash_config/flash_config.c +++ b/boards/nxp/mimxrt595_evk/flash_config/flash_config.c @@ -6,7 +6,7 @@ */ #include "flash_config.h" -#if defined(BOOT_HEADER_ENABLE) && (BOOT_HEADER_ENABLE == 1) +#if defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && (CONFIG_NXP_IMXRT_BOOT_HEADER == 1) __attribute__((section(".flash_conf"), used)) const flexspi_nor_config_t flash_config = { @@ -105,4 +105,4 @@ const flexspi_nor_config_t flash_config = { .flashStateCtx = 0x07008200u, }; -#endif /* BOOT_HEADER_ENABLE */ +#endif /* defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && (CONFIG_NXP_IMXRT_BOOT_HEADER == 1) */ diff --git a/boards/nxp/mimxrt685_evk/CMakeLists.txt b/boards/nxp/mimxrt685_evk/CMakeLists.txt index 05924a93ac27..af3af08eedaf 100644 --- a/boards/nxp/mimxrt685_evk/CMakeLists.txt +++ b/boards/nxp/mimxrt685_evk/CMakeLists.txt @@ -22,7 +22,6 @@ if(CONFIG_NXP_IMXRT_BOOT_HEADER) # This flash configuration block may need modification if another # flash chip is used on your custom board. See NXP AN13386 for more # information. - zephyr_compile_definitions(BOOT_HEADER_ENABLE=1) zephyr_library_sources(flash_config/flash_config.c) zephyr_library_include_directories(flash_config) endif() diff --git a/boards/nxp/mimxrt685_evk/flash_config/flash_config.c b/boards/nxp/mimxrt685_evk/flash_config/flash_config.c index f7e7453a53e0..8a8098c2409c 100644 --- a/boards/nxp/mimxrt685_evk/flash_config/flash_config.c +++ b/boards/nxp/mimxrt685_evk/flash_config/flash_config.c @@ -6,7 +6,7 @@ */ #include "flash_config.h" -#if defined(BOOT_HEADER_ENABLE) && (BOOT_HEADER_ENABLE == 1) +#if defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && (CONFIG_NXP_IMXRT_BOOT_HEADER == 1) __attribute__((section(".flash_conf"), used)) const flexspi_nor_config_t flexspi_config = { @@ -135,4 +135,4 @@ const flexspi_nor_config_t flexspi_config = { .flash_state_ctx = 0x07008100u, }; -#endif /* BOOT_HEADER_ENABLE */ +#endif /* defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && (CONFIG_NXP_IMXRT_BOOT_HEADER == 1) */ diff --git a/boards/nxp/mimxrt700_evk/CMakeLists.txt b/boards/nxp/mimxrt700_evk/CMakeLists.txt index e2c927aeb22e..98f67d466db2 100644 --- a/boards/nxp/mimxrt700_evk/CMakeLists.txt +++ b/boards/nxp/mimxrt700_evk/CMakeLists.txt @@ -20,7 +20,6 @@ if(CONFIG_NXP_IMXRT_BOOT_HEADER) # This flash configuration block may need modification if another # flash chip is used on your custom board. See NXP AN13304 for more # information. - zephyr_compile_definitions(BOOT_HEADER_ENABLE=1) zephyr_library_sources(flash_config/flash_config.c) zephyr_library_include_directories(flash_config) endif() diff --git a/boards/nxp/mimxrt700_evk/flash_config/flash_config.c b/boards/nxp/mimxrt700_evk/flash_config/flash_config.c index ea5d6d3c9de6..2bdc1cc03616 100644 --- a/boards/nxp/mimxrt700_evk/flash_config/flash_config.c +++ b/boards/nxp/mimxrt700_evk/flash_config/flash_config.c @@ -5,7 +5,7 @@ */ #include "flash_config.h" -#if defined(BOOT_HEADER_ENABLE) && (BOOT_HEADER_ENABLE == 1) +#if defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && (CONFIG_NXP_IMXRT_BOOT_HEADER == 1) __attribute__((section(".flash_conf"), used)) const fc_static_platform_config_t flash_config = { @@ -139,4 +139,4 @@ const fc_static_platform_config_t flash_config = { #endif }; -#endif /* BOOT_HEADER_ENABLE */ +#endif /* defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && (CONFIG_NXP_IMXRT_BOOT_HEADER == 1) */ From 3eb60a97922fe99c1705aea92154a1b273767114 Mon Sep 17 00:00:00 2001 From: Zhaoxiang Jin Date: Tue, 2 Dec 2025 11:23:03 +0800 Subject: [PATCH 1909/3659] boards: nxp: convert 'XIP_BOOT_HEADER_DCD_ENABLE' to Kconfig options 1. This commit converts the 'XIP_BOOT_HEADER_DCD_ENABLE' preprocessor define to Kconfig options across NXP i.MX RTxxxx evaluation boards. The changes enable flexible boot header configuration through the Kconfig build system instead of compile-time defines, improving configurability and maintainability. 2. Now 'XIP_BOOT_HEADER_DCD_ENABLE' flag is only used in hal_nxp/rtxxxx/fsl_flexspi_nor_boot.h which is included by soc.c, therefore, this flag should be passed in the rtxxxx/SoC layer CMake using zephyr_library_compile_definitions(). and can be removed from each board CMakeLists.txt. Note: if out-of-tree files still need to use this flag, please add it in your own CMakeLists.txt. Signed-off-by: Zhaoxiang Jin --- boards/nxp/mimxrt1020_evk/CMakeLists.txt | 1 - boards/nxp/mimxrt1020_evk/dcd/dcd.c | 4 ++-- boards/nxp/mimxrt1024_evk/CMakeLists.txt | 1 - boards/nxp/mimxrt1024_evk/dcd/dcd.c | 4 ++-- boards/nxp/mimxrt1040_evk/CMakeLists.txt | 1 - boards/nxp/mimxrt1040_evk/dcd/dcd.c | 4 ++-- boards/nxp/mimxrt1050_evk/CMakeLists.txt | 1 - boards/nxp/mimxrt1050_evk/dcd/dcd.c | 4 ++-- boards/nxp/mimxrt1060_evk/CMakeLists.txt | 1 - boards/nxp/mimxrt1060_evk/dcd/dcd.c | 4 ++-- boards/nxp/mimxrt1062_fmurt6/CMakeLists.txt | 1 - boards/nxp/mimxrt1064_evk/CMakeLists.txt | 1 - boards/nxp/mimxrt1064_evk/dcd/dcd.c | 4 ++-- boards/nxp/mimxrt1160_evk/CMakeLists.txt | 1 - boards/nxp/mimxrt1160_evk/dcd/dcd.c | 4 ++-- boards/nxp/mimxrt1170_evk/dcd/dcd.c | 4 ++-- soc/nxp/imxrt/imxrt10xx/CMakeLists.txt | 4 ++++ soc/nxp/imxrt/imxrt11xx/CMakeLists.txt | 4 ++++ 18 files changed, 24 insertions(+), 24 deletions(-) diff --git a/boards/nxp/mimxrt1020_evk/CMakeLists.txt b/boards/nxp/mimxrt1020_evk/CMakeLists.txt index 682a27f1fd20..fc7a8481d7c1 100644 --- a/boards/nxp/mimxrt1020_evk/CMakeLists.txt +++ b/boards/nxp/mimxrt1020_evk/CMakeLists.txt @@ -22,7 +22,6 @@ if(CONFIG_NXP_IMXRT_BOOT_HEADER) if(CONFIG_DEVICE_CONFIGURATION_DATA) # This device configuration block may need modification if another # SDRAM chip is used on your custom board. - zephyr_compile_definitions(XIP_BOOT_HEADER_DCD_ENABLE=1) zephyr_library_sources(dcd/dcd.c) else() if(CONFIG_SRAM_BASE_ADDRESS EQUAL 0x80000000) diff --git a/boards/nxp/mimxrt1020_evk/dcd/dcd.c b/boards/nxp/mimxrt1020_evk/dcd/dcd.c index d6e5e7370145..87913fa6a878 100644 --- a/boards/nxp/mimxrt1020_evk/dcd/dcd.c +++ b/boards/nxp/mimxrt1020_evk/dcd/dcd.c @@ -8,7 +8,7 @@ #include "dcd.h" #if defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_BOOT_FLEXSPI_NOR) -#if defined(XIP_BOOT_HEADER_DCD_ENABLE) && (XIP_BOOT_HEADER_DCD_ENABLE == 1) +#if defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_DEVICE_CONFIGURATION_DATA) __attribute__((section(".boot_hdr.dcd_data"), used)) const uint8_t dcd_data[] = { @@ -591,5 +591,5 @@ const uint8_t dcd_data[] = { #else const uint8_t dcd_data[] = {0x00}; -#endif /* XIP_BOOT_HEADER_DCD_ENABLE */ +#endif /* defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_DEVICE_CONFIGURATION_DATA) */ #endif /* defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_BOOT_FLEXSPI_NOR) */ diff --git a/boards/nxp/mimxrt1024_evk/CMakeLists.txt b/boards/nxp/mimxrt1024_evk/CMakeLists.txt index aeb72bfe882f..bbca78b36d8f 100644 --- a/boards/nxp/mimxrt1024_evk/CMakeLists.txt +++ b/boards/nxp/mimxrt1024_evk/CMakeLists.txt @@ -22,7 +22,6 @@ if(CONFIG_NXP_IMXRT_BOOT_HEADER) if(CONFIG_DEVICE_CONFIGURATION_DATA) # This device configuration block may need modification if another # SDRAM chip is used on your custom board. - zephyr_compile_definitions(XIP_BOOT_HEADER_DCD_ENABLE=1) zephyr_library_sources(dcd/dcd.c) else() if(CONFIG_SRAM_BASE_ADDRESS EQUAL 0x80000000) diff --git a/boards/nxp/mimxrt1024_evk/dcd/dcd.c b/boards/nxp/mimxrt1024_evk/dcd/dcd.c index 4a6fc611b4c3..3d42bdcf3ff7 100644 --- a/boards/nxp/mimxrt1024_evk/dcd/dcd.c +++ b/boards/nxp/mimxrt1024_evk/dcd/dcd.c @@ -8,7 +8,7 @@ #include "dcd.h" #if defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_BOOT_FLEXSPI_NOR) -#if defined(XIP_BOOT_HEADER_DCD_ENABLE) && (XIP_BOOT_HEADER_DCD_ENABLE == 1) +#if defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_DEVICE_CONFIGURATION_DATA) __attribute__((section(".boot_hdr.dcd_data"), used)) const uint8_t dcd_data[] = { @@ -591,5 +591,5 @@ const uint8_t dcd_data[] = { #else const uint8_t dcd_data[] = {0x00}; -#endif /* XIP_BOOT_HEADER_DCD_ENABLE */ +#endif /* defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_DEVICE_CONFIGURATION_DATA) */ #endif /* defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_BOOT_FLEXSPI_NOR) */ diff --git a/boards/nxp/mimxrt1040_evk/CMakeLists.txt b/boards/nxp/mimxrt1040_evk/CMakeLists.txt index ab063aaf97bd..776655ecdea1 100644 --- a/boards/nxp/mimxrt1040_evk/CMakeLists.txt +++ b/boards/nxp/mimxrt1040_evk/CMakeLists.txt @@ -27,7 +27,6 @@ if(CONFIG_NXP_IMXRT_BOOT_HEADER) if(CONFIG_DEVICE_CONFIGURATION_DATA) # This device configuration block may need modification if another # SDRAM chip is used on your custom board. - zephyr_compile_definitions(XIP_BOOT_HEADER_DCD_ENABLE=1) zephyr_library_sources(dcd/dcd.c) else() if(CONFIG_SRAM_BASE_ADDRESS EQUAL 0x80000000) diff --git a/boards/nxp/mimxrt1040_evk/dcd/dcd.c b/boards/nxp/mimxrt1040_evk/dcd/dcd.c index 3f54779f56e1..685a155c30b7 100644 --- a/boards/nxp/mimxrt1040_evk/dcd/dcd.c +++ b/boards/nxp/mimxrt1040_evk/dcd/dcd.c @@ -8,7 +8,7 @@ #include "dcd.h" #if defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_BOOT_FLEXSPI_NOR) -#if defined(XIP_BOOT_HEADER_DCD_ENABLE) && (XIP_BOOT_HEADER_DCD_ENABLE == 1) +#if defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_DEVICE_CONFIGURATION_DATA) __attribute__((section(".boot_hdr.dcd_data"), used)) const uint8_t dcd_data[] = { @@ -615,5 +615,5 @@ const uint8_t dcd_data[] = { #else const uint8_t dcd_data[] = {0x00}; -#endif /* XIP_BOOT_HEADER_DCD_ENABLE */ +#endif /* defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_DEVICE_CONFIGURATION_DATA) */ #endif /* defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_BOOT_FLEXSPI_NOR) */ diff --git a/boards/nxp/mimxrt1050_evk/CMakeLists.txt b/boards/nxp/mimxrt1050_evk/CMakeLists.txt index a0c8f240eb93..e1d74f9e584e 100644 --- a/boards/nxp/mimxrt1050_evk/CMakeLists.txt +++ b/boards/nxp/mimxrt1050_evk/CMakeLists.txt @@ -33,7 +33,6 @@ if(CONFIG_NXP_IMXRT_BOOT_HEADER) if(CONFIG_DEVICE_CONFIGURATION_DATA) # This device configuration block may need modification if another # SDRAM chip is used on your custom board. - zephyr_compile_definitions(XIP_BOOT_HEADER_DCD_ENABLE=1) zephyr_library_sources(dcd/dcd.c) else() if(CONFIG_SRAM_BASE_ADDRESS EQUAL 0x80000000) diff --git a/boards/nxp/mimxrt1050_evk/dcd/dcd.c b/boards/nxp/mimxrt1050_evk/dcd/dcd.c index 99febb5c3ded..65b10524db08 100644 --- a/boards/nxp/mimxrt1050_evk/dcd/dcd.c +++ b/boards/nxp/mimxrt1050_evk/dcd/dcd.c @@ -8,7 +8,7 @@ #include "dcd.h" #if defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_BOOT_FLEXSPI_NOR) -#if defined(XIP_BOOT_HEADER_DCD_ENABLE) && (XIP_BOOT_HEADER_DCD_ENABLE == 1) +#if defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_DEVICE_CONFIGURATION_DATA) __attribute__((section(".boot_hdr.dcd_data"), used)) const uint8_t dcd_data[] = { @@ -615,5 +615,5 @@ const uint8_t dcd_data[] = { #else const uint8_t dcd_data[] = {0x00}; -#endif /* XIP_BOOT_HEADER_DCD_ENABLE */ +#endif /* defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_DEVICE_CONFIGURATION_DATA) */ #endif /* defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_BOOT_FLEXSPI_NOR) */ diff --git a/boards/nxp/mimxrt1060_evk/CMakeLists.txt b/boards/nxp/mimxrt1060_evk/CMakeLists.txt index 9ca8c6ddd856..b8b001960bcb 100644 --- a/boards/nxp/mimxrt1060_evk/CMakeLists.txt +++ b/boards/nxp/mimxrt1060_evk/CMakeLists.txt @@ -43,7 +43,6 @@ if(CONFIG_NXP_IMXRT_BOOT_HEADER) if(CONFIG_DEVICE_CONFIGURATION_DATA) # This device configuration data block may need modification if another # SDRAM chip is used on your custom board. - zephyr_compile_definitions(XIP_BOOT_HEADER_DCD_ENABLE=1) zephyr_library_sources(${RT1060_BOARD_DIR}/dcd/dcd.c) else() if(CONFIG_SRAM_BASE_ADDRESS EQUAL 0x80000000) diff --git a/boards/nxp/mimxrt1060_evk/dcd/dcd.c b/boards/nxp/mimxrt1060_evk/dcd/dcd.c index e6b4f064577e..c6271de1a848 100644 --- a/boards/nxp/mimxrt1060_evk/dcd/dcd.c +++ b/boards/nxp/mimxrt1060_evk/dcd/dcd.c @@ -8,7 +8,7 @@ #include "dcd.h" #if defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_BOOT_FLEXSPI_NOR) -#if defined(XIP_BOOT_HEADER_DCD_ENABLE) && (XIP_BOOT_HEADER_DCD_ENABLE == 1) +#if defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_DEVICE_CONFIGURATION_DATA) __attribute__((section(".boot_hdr.dcd_data"), used)) const uint8_t dcd_data[] = { @@ -615,5 +615,5 @@ const uint8_t dcd_data[] = { #else const uint8_t dcd_data[] = {0x00}; -#endif /* XIP_BOOT_HEADER_DCD_ENABLE */ +#endif /* defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_DEVICE_CONFIGURATION_DATA) */ #endif /* defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_BOOT_FLEXSPI_NOR) */ diff --git a/boards/nxp/mimxrt1062_fmurt6/CMakeLists.txt b/boards/nxp/mimxrt1062_fmurt6/CMakeLists.txt index 4cbb2716a07b..53801bc95061 100644 --- a/boards/nxp/mimxrt1062_fmurt6/CMakeLists.txt +++ b/boards/nxp/mimxrt1062_fmurt6/CMakeLists.txt @@ -25,7 +25,6 @@ if(CONFIG_NXP_IMXRT_BOOT_HEADER) # Include device configuration data block for RT1050 EVK from NXP's HAL. # This configuration block may need modification if another SDRAM chip # is used on your custom board. - zephyr_compile_definitions(XIP_BOOT_HEADER_DCD_ENABLE=1) zephyr_library_sources(${RT1062_BOARD_DIR}/dcd/dcd.c) endif() endif() diff --git a/boards/nxp/mimxrt1064_evk/CMakeLists.txt b/boards/nxp/mimxrt1064_evk/CMakeLists.txt index 28e10c510516..6068fd2d2e64 100644 --- a/boards/nxp/mimxrt1064_evk/CMakeLists.txt +++ b/boards/nxp/mimxrt1064_evk/CMakeLists.txt @@ -27,7 +27,6 @@ if(CONFIG_NXP_IMXRT_BOOT_HEADER) if(CONFIG_DEVICE_CONFIGURATION_DATA) # This device configuration block may need modification if another # SDRAM chip is used on your custom board. - zephyr_compile_definitions(XIP_BOOT_HEADER_DCD_ENABLE=1) zephyr_library_sources(dcd/dcd.c) else() if(CONFIG_SRAM_BASE_ADDRESS EQUAL 0x80000000) diff --git a/boards/nxp/mimxrt1064_evk/dcd/dcd.c b/boards/nxp/mimxrt1064_evk/dcd/dcd.c index 7ac3330ab47e..1811934e9374 100644 --- a/boards/nxp/mimxrt1064_evk/dcd/dcd.c +++ b/boards/nxp/mimxrt1064_evk/dcd/dcd.c @@ -9,7 +9,7 @@ #include "dcd.h" #if defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_BOOT_FLEXSPI_NOR) -#if defined(XIP_BOOT_HEADER_DCD_ENABLE) && (XIP_BOOT_HEADER_DCD_ENABLE == 1) +#if defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_DEVICE_CONFIGURATION_DATA) __attribute__((section(".boot_hdr.dcd_data"), used)) /* COMMENTS BELOW ARE USED AS SETTINGS FOR DCD DATA */ @@ -617,5 +617,5 @@ const uint8_t dcd_data[] = { #else const uint8_t dcd_data[] = {0x00}; -#endif /* XIP_BOOT_HEADER_DCD_ENABLE */ +#endif /* defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_DEVICE_CONFIGURATION_DATA) */ #endif /* defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_BOOT_FLEXSPI_NOR) */ diff --git a/boards/nxp/mimxrt1160_evk/CMakeLists.txt b/boards/nxp/mimxrt1160_evk/CMakeLists.txt index 5d686055a2ec..a4662e7fdee2 100644 --- a/boards/nxp/mimxrt1160_evk/CMakeLists.txt +++ b/boards/nxp/mimxrt1160_evk/CMakeLists.txt @@ -22,7 +22,6 @@ if(CONFIG_NXP_IMXRT_BOOT_HEADER) if(CONFIG_DEVICE_CONFIGURATION_DATA) # This device configuration block may need modification if another # SDRAM chip is used on your custom board. - zephyr_compile_definitions(XIP_BOOT_HEADER_DCD_ENABLE=1) zephyr_library_sources(dcd/dcd.c) else() if(CONFIG_SRAM_BASE_ADDRESS EQUAL 0x80000000) diff --git a/boards/nxp/mimxrt1160_evk/dcd/dcd.c b/boards/nxp/mimxrt1160_evk/dcd/dcd.c index 028894e1e3fe..34b3f80dd400 100644 --- a/boards/nxp/mimxrt1160_evk/dcd/dcd.c +++ b/boards/nxp/mimxrt1160_evk/dcd/dcd.c @@ -8,7 +8,7 @@ #include "dcd.h" #if defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_BOOT_FLEXSPI_NOR) -#if defined(XIP_BOOT_HEADER_DCD_ENABLE) && (XIP_BOOT_HEADER_DCD_ENABLE == 1) +#if defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_DEVICE_CONFIGURATION_DATA) __attribute__((section(".boot_hdr.dcd_data"), used)) const uint8_t dcd_data[] = { @@ -745,5 +745,5 @@ const uint8_t dcd_data[] = { #else const uint8_t dcd_data[] = {0x00}; -#endif /* XIP_BOOT_HEADER_DCD_ENABLE */ +#endif /* defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_DEVICE_CONFIGURATION_DATA) */ #endif /* defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_BOOT_FLEXSPI_NOR) */ diff --git a/boards/nxp/mimxrt1170_evk/dcd/dcd.c b/boards/nxp/mimxrt1170_evk/dcd/dcd.c index b68306858cd8..c8b675eb9a5b 100644 --- a/boards/nxp/mimxrt1170_evk/dcd/dcd.c +++ b/boards/nxp/mimxrt1170_evk/dcd/dcd.c @@ -8,7 +8,7 @@ #include "dcd.h" #if defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_BOOT_FLEXSPI_NOR) -#if defined(XIP_BOOT_HEADER_DCD_ENABLE) && (XIP_BOOT_HEADER_DCD_ENABLE == 1) +#if defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_DEVICE_CONFIGURATION_DATA) __attribute__((section(".boot_hdr.dcd_data"), used)) const uint8_t dcd_data[] = { @@ -883,5 +883,5 @@ const uint8_t dcd_data[] = { #else const uint8_t dcd_data[] = {0x00}; -#endif /* XIP_BOOT_HEADER_DCD_ENABLE */ +#endif /* defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_DEVICE_CONFIGURATION_DATA) */ #endif /* defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_BOOT_FLEXSPI_NOR) */ diff --git a/soc/nxp/imxrt/imxrt10xx/CMakeLists.txt b/soc/nxp/imxrt/imxrt10xx/CMakeLists.txt index 02e149b8d4ca..322fb4dc01a2 100644 --- a/soc/nxp/imxrt/imxrt10xx/CMakeLists.txt +++ b/soc/nxp/imxrt/imxrt10xx/CMakeLists.txt @@ -27,6 +27,10 @@ if(CONFIG_NXP_IMXRT_BOOT_HEADER) if(CONFIG_BOOT_FLEXSPI_NOR) zephyr_library_compile_definitions(BOARD_FLASH_SIZE=CONFIG_FLASH_SIZE*1024) endif() + + if(CONFIG_DEVICE_CONFIGURATION_DATA) + zephyr_library_compile_definitions(XIP_BOOT_HEADER_DCD_ENABLE=1) + endif() endif() zephyr_include_directories(.) diff --git a/soc/nxp/imxrt/imxrt11xx/CMakeLists.txt b/soc/nxp/imxrt/imxrt11xx/CMakeLists.txt index fae98bb50b83..c3f6d05588f2 100644 --- a/soc/nxp/imxrt/imxrt11xx/CMakeLists.txt +++ b/soc/nxp/imxrt/imxrt11xx/CMakeLists.txt @@ -27,6 +27,10 @@ if(CONFIG_NXP_IMXRT_BOOT_HEADER) zephyr_library_compile_definitions(BOARD_FLASH_SIZE=CONFIG_FLASH_SIZE*1024) zephyr_library_compile_definitions(XIP_BOOT_HEADER_ENABLE=1) endif() + + if(CONFIG_DEVICE_CONFIGURATION_DATA) + zephyr_library_compile_definitions(XIP_BOOT_HEADER_DCD_ENABLE=1) + endif() endif() set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld CACHE INTERNAL "") From a4b8d3ed7c29a0ba1fe8515a711e9731b496486f Mon Sep 17 00:00:00 2001 From: Zhaoxiang Jin Date: Tue, 23 Dec 2025 14:02:28 +0800 Subject: [PATCH 1910/3659] boards: nxp: rd_rw612_bga: remove unused build flag 'BOOT_HEADER_ENABLE' is not used in RW61x build tree, so should remove it from RW61x board CMakeLists.txt. Note: if out-of-tree files still need to use this flag, please add it in your own CMakeLists.txt. Signed-off-by: Zhaoxiang Jin --- boards/nxp/rd_rw612_bga/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/boards/nxp/rd_rw612_bga/CMakeLists.txt b/boards/nxp/rd_rw612_bga/CMakeLists.txt index f58318a19891..1d59012a81f9 100644 --- a/boards/nxp/rd_rw612_bga/CMakeLists.txt +++ b/boards/nxp/rd_rw612_bga/CMakeLists.txt @@ -15,7 +15,6 @@ if(CONFIG_NXP_RW6XX_BOOT_HEADER) "the RD_RW612_BGA, but targeting a custom board. You may need to " "update your flash configuration block data") endif() - zephyr_compile_definitions(BOOT_HEADER_ENABLE=1) zephyr_library_sources(MX25U51245GZ4I00_FCB.c) endif() From e790de88c6bc07cb77741449f9949f0d9c5acea0 Mon Sep 17 00:00:00 2001 From: Zhaoxiang Jin Date: Fri, 19 Dec 2025 16:04:48 +0800 Subject: [PATCH 1911/3659] doc: releases: add migration guide for NXP compile flag scope changes Document the scope changes for NXP compile flags that were moved from global to local scope in PR #100252. Applications that depended on these flags being globally available may need to be updated. The following flags have been moved to use zephyr_library_compile_definitions(): - BOARD_FLASH_SIZE: moved to SoC layer CMake for RT10xx and RT11xx - XIP_BOOT_HEADER_ENABLE: scoped to boards CMake or SoC layer as needed - BOOT_HEADER_ENABLE: scoped to boards CMake, removed from RW61x boards - XIP_BOOT_HEADER_DCD_ENABLE: scoped to boards CMake or SoC layer as needed Signed-off-by: Zhaoxiang Jin --- doc/releases/migration-guide-4.4.rst | 37 ++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/doc/releases/migration-guide-4.4.rst b/doc/releases/migration-guide-4.4.rst index 11fab4cdc2f6..f45f88b12d3f 100644 --- a/doc/releases/migration-guide-4.4.rst +++ b/doc/releases/migration-guide-4.4.rst @@ -46,6 +46,43 @@ Boards in the respective board CMakeLists.txt files. Applications that depended on these definitions being globally available may need to be updated. (:github:`101322`) +* NXP has changed the scope of some in-tree compile flags to limit their visibility to only where + they are needed. Out-of-tree applications or boards that depended on these flags being globally + available may need to add them to their own CMakeLists.txt files to ensure they continue to build + correctly. (:github:`100252`) + The affected flags are listed below: + + * For the RT10xx and RT11xx families, the compile flag ``BOARD_FLASH_SIZE``, originally defined in + ``boards/nxp/mimxrt10xx_evk/CMakeLists.txt`` and ``boards/nxp/mimxrt11xx_evk/CMakeLists.txt``, is + used only by the HAL header ``fsl_flexspi_nor_boot.h``, which is included by + :zephyr_file:`soc/nxp/imxrt/imxrt10xx/soc.c` and :zephyr_file:`soc/nxp/imxrt/imxrt11xx/soc.c`. + To avoid potential collisions with other global flags, the macro is now defined at the SoC layer + using ``zephyr_library_compile_definitions()`` in :zephyr_file:`soc/nxp/imxrt/imxrt10xx/CMakeLists.txt` + and :zephyr_file:`soc/nxp/imxrt/imxrt11xx/CMakeLists.txt`. This change has been applied to all + RTxxxx boards. + + * For the RTxxx family, the compile flag ``BOARD_FLASH_SIZE``, originally defined in + ``boards/nxp/mimxrtxxx_evk/CMakeLists.txt``, is not used in the Zephyr tree and has + therefore been removed from all RTxxx board CMakeLists.txt files. + + * For the RTxxx family, the compile flag ``BOOT_HEADER_ENABLE``, previously defined in + ``boards/nxp/mimxrtxxx_evk/CMakeLists.txt`` and used in ``boards/nxp/rtxxx/.c``, + has been replaced by a Kconfig option. Consequently, the line + ``zephyr_compile_definitions(BOOT_HEADER_ENABLE=1)`` has been removed from the RTxxx board + CMakeLists.txt files. + + * Removed compile flag ``BOOT_HEADER_ENABLE`` definition from :zephyr_file:`boards/nxp/rd_rw612_bga/CMakeLists.txt`, + as it is not used in the Zephyr tree. + + * Originally, the compile flags ``XIP_BOOT_HEADER_ENABLE`` and ``XIP_BOOT_HEADER_DCD_ENABLE`` were + used in ``boards/nxp/rt1xxx/.c``. These flags have been converted to Kconfig options + across NXP RTxxxx evaluation boards, allowing boot-header configuration via the Kconfig build system + instead of compile-time defines. Consequently, we removed ``zephyr_compile_definitions(XIP_BOOT_HEADER_ENABLE=1)`` + and ``zephyr_compile_definitions(XIP_BOOT_HEADER_DCD_ENABLE=1)`` from the RTxxxx board-level CMakeLists.txt files. + Because these macros are also required by ``hal_nxp/rt10xx/fsl_flexspi_nor_boot.h`` and + ``hal_nxp/rt11xx/fsl_flexspi_nor_boot.h``, they were added to the corresponding SoC-layer CMakeLists.txt files + using ``zephyr_library_compile_definitions()`` to limit their scope. + Device Drivers and Devicetree ***************************** From d087bf9a25f889bfb54377e1923b73e0a7c3cf48 Mon Sep 17 00:00:00 2001 From: Kate Wang Date: Mon, 15 Dec 2025 16:38:25 +0800 Subject: [PATCH 1912/3659] MAINTAINERS: Add Kate Wang as collaborator for MIPI DBI/DSI Add myslef as a collaborator for the MIPI DBI and MIPI DSI subsystems. I have been actively contributing to MIPI DBI/DSI implementations and will continue developing and reviewing patches. Signed-off-by: Kate Wang --- MAINTAINERS.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index 8730fdfbac10..e314e4d6eb06 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -2023,6 +2023,7 @@ Documentation Infrastructure: collaborators: - JarmouniA - VynDragon + - KATE-WANG-NXP files: - drivers/mipi_dbi/ - include/zephyr/drivers/mipi_dbi.h @@ -2035,6 +2036,7 @@ Documentation Infrastructure: status: odd fixes collaborators: - JarmouniA + - KATE-WANG-NXP files: - drivers/mipi_dsi/ - include/zephyr/drivers/mipi_dsi.h From a600317285ff82884055c2135a2ec39af7d42191 Mon Sep 17 00:00:00 2001 From: Kate Wang Date: Mon, 15 Dec 2025 16:39:15 +0800 Subject: [PATCH 1913/3659] MAINTAINERS: Add Kate Wang as collaborator for Display drivers Add myself as a collaborator for the Display drivers subsystem. I have been actively contributing to display driver implementations and will continue developing and reviewing patches. Signed-off-by: Kate Wang --- MAINTAINERS.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index e314e4d6eb06..a2a345dbae11 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -1184,6 +1184,7 @@ Display drivers: - jfischer-no - danieldegrasse - VynDragon + - KATE-WANG-NXP files: - drivers/display/ - dts/bindings/display/ From a52ff9a7bb64524acbe3ec1326cb2333acb2bcf5 Mon Sep 17 00:00:00 2001 From: Neil Chen Date: Fri, 17 Oct 2025 17:49:18 +0800 Subject: [PATCH 1914/3659] drivers: syscon: update syscon driver to support mcxa flexcan clock Add mcxa flexcan clock support Signed-off-by: Neil Chen --- drivers/clock_control/clock_control_mcux_syscon.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/clock_control/clock_control_mcux_syscon.c b/drivers/clock_control/clock_control_mcux_syscon.c index b7d98e0cad5a..2f64bb55e112 100644 --- a/drivers/clock_control/clock_control_mcux_syscon.c +++ b/drivers/clock_control/clock_control_mcux_syscon.c @@ -98,6 +98,11 @@ static int mcux_lpc_syscon_clock_control_on(const struct device *dev, case MCUX_FLEXCAN0_CLK: CLOCK_EnableClock(kCLOCK_GateFLEXCAN0); break; +#if (defined(FSL_FEATURE_SOC_FLEXCAN_COUNT) && (FSL_FEATURE_SOC_FLEXCAN_COUNT > 1)) + case MCUX_FLEXCAN1_CLK: + CLOCK_EnableClock(kCLOCK_GateFLEXCAN1); + break; +#endif /* defined(FSL_FEATURE_SOC_FLEXCAN_COUNT) */ #else case MCUX_FLEXCAN0_CLK: CLOCK_EnableClock(kCLOCK_Flexcan0); @@ -604,7 +609,8 @@ static int mcux_lpc_syscon_clock_control_get_subsys_rate(const struct device *de #endif /* CONFIG_ADC_MCUX_LPADC */ #if defined(CONFIG_CAN_MCUX_FLEXCAN) -#if defined(CONFIG_SOC_FAMILY_MCXA) +#if (defined(FSL_FEATURE_SOC_FLEXCAN_COUNT) && (FSL_FEATURE_SOC_FLEXCAN_COUNT == 1) && \ + !defined(CONFIG_SOC_MCXA346)) case MCUX_FLEXCAN0_CLK: *rate = CLOCK_GetFlexcanClkFreq(); break; @@ -615,7 +621,7 @@ static int mcux_lpc_syscon_clock_control_get_subsys_rate(const struct device *de case MCUX_FLEXCAN1_CLK: *rate = CLOCK_GetFlexcanClkFreq(1); break; -#endif /* defined(CONFIG_SOC_FAMILY_MCXA) */ +#endif /* defined(FSL_FEATURE_SOC_FLEXCAN_COUNT) */ #endif /* defined(CONFIG_CAN_MCUX_FLEXCAN) */ #if defined(CONFIG_MCUX_FLEXIO) From 6b5489b8504d03b710ee96f87d3e026e554f49f4 Mon Sep 17 00:00:00 2001 From: Neil Chen Date: Thu, 15 Jan 2026 16:11:20 +0800 Subject: [PATCH 1915/3659] dts: arm/nxp: Add Flexcan nodes to NXP mcxaxx6 dtsi file Add Flexcan0,Flexcan1 node to NXP MCXA366,MCXA266 dtsi file Add Flexcan0 node to NXP MCXA346 dtsi file Signed-off-by: Neil Chen --- dts/arm/nxp/nxp_mcxa346.dtsi | 1 + dts/arm/nxp/nxp_mcxaxx6_common.dtsi | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/dts/arm/nxp/nxp_mcxa346.dtsi b/dts/arm/nxp/nxp_mcxa346.dtsi index f0e7781715eb..4dad454c63db 100644 --- a/dts/arm/nxp/nxp_mcxa346.dtsi +++ b/dts/arm/nxp/nxp_mcxa346.dtsi @@ -9,3 +9,4 @@ /delete-node/ &i3c0; /delete-node/ &flexio0; /delete-node/ &trng; +/delete-node/ &flexcan1; diff --git a/dts/arm/nxp/nxp_mcxaxx6_common.dtsi b/dts/arm/nxp/nxp_mcxaxx6_common.dtsi index 63d753d72b0f..d6fee9ce9dca 100644 --- a/dts/arm/nxp/nxp_mcxaxx6_common.dtsi +++ b/dts/arm/nxp/nxp_mcxaxx6_common.dtsi @@ -554,6 +554,28 @@ compatible = "nxp,vbat"; reg = <0x40093000 0x1000>; }; + + flexcan0: can@400cc000 { + compatible = "nxp,flexcan-fd", "nxp,flexcan"; + reg = <0x400cc000 0x1000>; + interrupts = <19 0>; + interrupt-names = "common"; + clocks = <&syscon MCUX_FLEXCAN0_CLK>; + number-of-mb = <32>; + number-of-mb-fd = <7>; + status = "disabled"; + }; + + flexcan1: can@400d0000 { + compatible = "nxp,flexcan-fd", "nxp,flexcan"; + reg = <0x400d0000 0x1000>; + interrupts = <20 0>; + interrupt-names = "common"; + clocks = <&syscon MCUX_FLEXCAN1_CLK>; + number-of-mb = <32>; + number-of-mb-fd = <7>; + status = "disabled"; + }; }; }; From 393d8807e3080654422cfc39739f86584bf616cf Mon Sep 17 00:00:00 2001 From: Neil Chen Date: Thu, 15 Jan 2026 16:12:39 +0800 Subject: [PATCH 1916/3659] boards: nxp/frdm_mcxaxx6: Support Flexcan for NXP frdm_mcxaxx6 board Support Flexcan for NXP frdm_mcxa366,frdm_mcxa346,frdm_mcxa266 board Signed-off-by: Neil Chen --- boards/nxp/frdm_mcxaxx6/board.c | 6 ++++++ boards/nxp/frdm_mcxaxx6/board_common.dtsi | 7 +++++++ boards/nxp/frdm_mcxaxx6/frdm_mcxa266-pinctrl.dtsi | 10 ++++++++++ boards/nxp/frdm_mcxaxx6/frdm_mcxa266.yaml | 1 + boards/nxp/frdm_mcxaxx6/frdm_mcxa346-pinctrl.dtsi | 10 ++++++++++ boards/nxp/frdm_mcxaxx6/frdm_mcxa346.yaml | 1 + boards/nxp/frdm_mcxaxx6/frdm_mcxa366-pinctrl.dtsi | 10 ++++++++++ boards/nxp/frdm_mcxaxx6/frdm_mcxa366.yaml | 1 + 8 files changed, 46 insertions(+) diff --git a/boards/nxp/frdm_mcxaxx6/board.c b/boards/nxp/frdm_mcxaxx6/board.c index 6e36191b1c5f..42f93aee5a0d 100644 --- a/boards/nxp/frdm_mcxaxx6/board.c +++ b/boards/nxp/frdm_mcxaxx6/board.c @@ -309,6 +309,12 @@ void board_early_init_hook(void) RESET_ReleasePeripheralReset(kTRNG0_RST_SHIFT_RSTn); #endif +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(flexcan0)) + CLOCK_SetClockDiv(kCLOCK_DivFLEXCAN0, 1U); + CLOCK_SetClockDiv(kCLOCK_DivFRO_HF, 1U); + CLOCK_AttachClk(kFRO_HF_DIV_to_FLEXCAN0); +#endif + /* Set SystemCoreClock variable. */ SystemCoreClock = CLOCK_INIT_CORE_CLOCK; } diff --git a/boards/nxp/frdm_mcxaxx6/board_common.dtsi b/boards/nxp/frdm_mcxaxx6/board_common.dtsi index 9cc7c2d6c416..7d8e1ab20bed 100644 --- a/boards/nxp/frdm_mcxaxx6/board_common.dtsi +++ b/boards/nxp/frdm_mcxaxx6/board_common.dtsi @@ -27,6 +27,7 @@ zephyr,console = &lpuart2; zephyr,shell-uart = &lpuart2; zephyr,cortex-m-idle-timer = &lptmr0; + zephyr,canbus = &flexcan0; }; leds { @@ -202,3 +203,9 @@ &lptmr0 { status = "okay"; }; + +&flexcan0 { + status = "okay"; + pinctrl-0 = <&pinmux_flexcan0>; + pinctrl-names = "default"; +}; diff --git a/boards/nxp/frdm_mcxaxx6/frdm_mcxa266-pinctrl.dtsi b/boards/nxp/frdm_mcxaxx6/frdm_mcxa266-pinctrl.dtsi index ac4fe928a054..b849c2c2d1a2 100644 --- a/boards/nxp/frdm_mcxaxx6/frdm_mcxa266-pinctrl.dtsi +++ b/boards/nxp/frdm_mcxaxx6/frdm_mcxa266-pinctrl.dtsi @@ -126,4 +126,14 @@ slew-rate = "fast"; }; }; + + pinmux_flexcan0: pinmux_flexcan0 { + group0 { + pinmux = , + ; + slew-rate = "fast"; + drive-strength = "low"; + input-enable; + }; + }; }; diff --git a/boards/nxp/frdm_mcxaxx6/frdm_mcxa266.yaml b/boards/nxp/frdm_mcxaxx6/frdm_mcxa266.yaml index 67b32fd9efe0..fee2ae158e8f 100644 --- a/boards/nxp/frdm_mcxaxx6/frdm_mcxa266.yaml +++ b/boards/nxp/frdm_mcxaxx6/frdm_mcxa266.yaml @@ -25,4 +25,5 @@ supported: - dma - i3c - entropy + - can vendor: nxp diff --git a/boards/nxp/frdm_mcxaxx6/frdm_mcxa346-pinctrl.dtsi b/boards/nxp/frdm_mcxaxx6/frdm_mcxa346-pinctrl.dtsi index cffd3bdf85c8..792d36eda497 100644 --- a/boards/nxp/frdm_mcxaxx6/frdm_mcxa346-pinctrl.dtsi +++ b/boards/nxp/frdm_mcxaxx6/frdm_mcxa346-pinctrl.dtsi @@ -118,4 +118,14 @@ slew-rate = "fast"; }; }; + + pinmux_flexcan0: pinmux_flexcan0 { + group0 { + pinmux = , + ; + slew-rate = "fast"; + drive-strength = "low"; + input-enable; + }; + }; }; diff --git a/boards/nxp/frdm_mcxaxx6/frdm_mcxa346.yaml b/boards/nxp/frdm_mcxaxx6/frdm_mcxa346.yaml index 24c6ef2d11da..3214271167e2 100644 --- a/boards/nxp/frdm_mcxaxx6/frdm_mcxa346.yaml +++ b/boards/nxp/frdm_mcxaxx6/frdm_mcxa346.yaml @@ -24,4 +24,5 @@ supported: - counter - dma - opamp + - can vendor: nxp diff --git a/boards/nxp/frdm_mcxaxx6/frdm_mcxa366-pinctrl.dtsi b/boards/nxp/frdm_mcxaxx6/frdm_mcxa366-pinctrl.dtsi index 965b6f3e84c6..3877abf0528e 100644 --- a/boards/nxp/frdm_mcxaxx6/frdm_mcxa366-pinctrl.dtsi +++ b/boards/nxp/frdm_mcxaxx6/frdm_mcxa366-pinctrl.dtsi @@ -136,4 +136,14 @@ slew-rate = "fast"; }; }; + + pinmux_flexcan0: pinmux_flexcan0 { + group0 { + pinmux = , + ; + slew-rate = "fast"; + drive-strength = "low"; + input-enable; + }; + }; }; diff --git a/boards/nxp/frdm_mcxaxx6/frdm_mcxa366.yaml b/boards/nxp/frdm_mcxaxx6/frdm_mcxa366.yaml index a18599ffef3c..a242e3880163 100644 --- a/boards/nxp/frdm_mcxaxx6/frdm_mcxa366.yaml +++ b/boards/nxp/frdm_mcxaxx6/frdm_mcxa366.yaml @@ -26,4 +26,5 @@ supported: - i3c - opamp - entropy + - can vendor: nxp From 1d2fe6ef0f807dba5d6e8162622791a4a61dcb18 Mon Sep 17 00:00:00 2001 From: Neil Chen Date: Tue, 30 Dec 2025 15:15:57 +0800 Subject: [PATCH 1917/3659] tests: drivers: can: timing: enable full timing test Enable the full range of CAN timing tests on the NXP FRDM-MCXA366, FRDM-MCXA346 and FRDM-MCXA266 boards. Signed-off-by: Neil Chen --- tests/drivers/can/timing/boards/frdm_mcxa266.conf | 1 + tests/drivers/can/timing/boards/frdm_mcxa346.conf | 1 + tests/drivers/can/timing/boards/frdm_mcxa366.conf | 1 + 3 files changed, 3 insertions(+) create mode 100644 tests/drivers/can/timing/boards/frdm_mcxa266.conf create mode 100644 tests/drivers/can/timing/boards/frdm_mcxa346.conf create mode 100644 tests/drivers/can/timing/boards/frdm_mcxa366.conf diff --git a/tests/drivers/can/timing/boards/frdm_mcxa266.conf b/tests/drivers/can/timing/boards/frdm_mcxa266.conf new file mode 100644 index 000000000000..7b071f3a54f5 --- /dev/null +++ b/tests/drivers/can/timing/boards/frdm_mcxa266.conf @@ -0,0 +1 @@ +CONFIG_TEST_ALL_BITRATES=y diff --git a/tests/drivers/can/timing/boards/frdm_mcxa346.conf b/tests/drivers/can/timing/boards/frdm_mcxa346.conf new file mode 100644 index 000000000000..7b071f3a54f5 --- /dev/null +++ b/tests/drivers/can/timing/boards/frdm_mcxa346.conf @@ -0,0 +1 @@ +CONFIG_TEST_ALL_BITRATES=y diff --git a/tests/drivers/can/timing/boards/frdm_mcxa366.conf b/tests/drivers/can/timing/boards/frdm_mcxa366.conf new file mode 100644 index 000000000000..7b071f3a54f5 --- /dev/null +++ b/tests/drivers/can/timing/boards/frdm_mcxa366.conf @@ -0,0 +1 @@ +CONFIG_TEST_ALL_BITRATES=y From 47db2c65224de01eb9fde2a0ef6390c7dad86fd6 Mon Sep 17 00:00:00 2001 From: Thorsten Klein Date: Wed, 24 Dec 2025 09:48:23 +0100 Subject: [PATCH 1918/3659] scripts: west_commands: build: remove shadowed function argument Remove _run_cmake argument 'cmake_opts' which is never used and shadowed by a local variable. Signed-off-by: Thorsten Klein --- scripts/west_commands/build.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/west_commands/build.py b/scripts/west_commands/build.py index fc030bc2d157..da10e23d42f1 100644 --- a/scripts/west_commands/build.py +++ b/scripts/west_commands/build.py @@ -263,7 +263,7 @@ def do_run(self, args, remainder): else: self.die("test item path does not exist") - self._run_cmake(board, origin, self.args.cmake_opts) + self._run_cmake(board, origin) if args.cmake_only: return @@ -625,7 +625,7 @@ def _sanity_check(self): self.source_dir = self._find_source_dir() self._sanity_check_source_dir() - def _run_cmake(self, board, origin, cmake_opts): + def _run_cmake(self, board, origin): if board is None and config_getboolean('board_warn', True): self.wrn('This looks like a fresh build and BOARD is unknown;', "so it probably won't work. To fix, use", From fe13def7a5c6edbeaf743a1b4437709d5c64f711 Mon Sep 17 00:00:00 2001 From: Thorsten Klein Date: Tue, 23 Dec 2025 09:22:35 +0100 Subject: [PATCH 1919/3659] scripts: west_commands: build: support cmake arguments via --cmake-opt Support cmake options specified via argument --cmake-opt, in order to avoid `--` in alias commands. Signed-off-by: Thorsten Klein --- scripts/west_commands/build.py | 23 ++++++++++++----------- scripts/west_commands/tests/test_build.py | 8 ++++---- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/scripts/west_commands/build.py b/scripts/west_commands/build.py index da10e23d42f1..4672ec46667e 100644 --- a/scripts/west_commands/build.py +++ b/scripts/west_commands/build.py @@ -30,7 +30,7 @@ west build [-h] [-b BOARD[@REV]]] [-d BUILD_DIR] [-S SNIPPET] [--shield SHIELD] [-t TARGET] [-p {auto, always, never}] [-c] [--cmake-only] - [-n] [-o BUILD_OPT] [-f] + [--cmake-opt CMAKE_OPT] [-n] [-o BUILD_OPT] [-f] [--sysbuild | --no-sysbuild] [--domain DOMAIN] [--extra-conf FILE.conf] [--extra-dtc-overlay FILE.overlay] @@ -120,6 +120,13 @@ def do_add_parser(self, parser_adder): group = parser.add_argument_group('cmake and build tool') group.add_argument('-c', '--cmake', action='store_true', help='force a cmake run') + group.add_argument('--cmake-opt', action='append', + dest="cmake_opts", default=[], + help='''same as using '-- cmake_opt' but avoid the + end-of-options marker '--' (e.g. in alias commands); + those options are passed to cmake first, so they can + be overridden via '-- cmake_opt'; + may be given multiple times.''') group.add_argument('--cmake-only', action='store_true', help="just run cmake; don't build (implies -c)") group.add_argument('--domain', action='append', @@ -294,7 +301,7 @@ def _find_board(self): def _parse_remainder(self, remainder): self.args.source_dir = None - self.args.cmake_opts = None + self.args.cmake_opts = getattr(self.args, 'cmake_opts', []) try: # Only one source_dir is allowed, as the first positional arg @@ -306,7 +313,7 @@ def _parse_remainder(self, remainder): if remainder[0] == _ARG_SEPARATOR: remainder = remainder[1:] if remainder: - self.args.cmake_opts = remainder + self.args.cmake_opts.extend(remainder) except IndexError: pass @@ -408,10 +415,7 @@ def _parse_test_item(self, test_item, board): required_snippets.extend(arg_list) continue - if self.args.cmake_opts: - self.args.cmake_opts.extend(args) - else: - self.args.cmake_opts = args + self.args.cmake_opts.extend(args) self.args.sysbuild = sysbuild @@ -432,10 +436,7 @@ def _parse_test_item(self, test_item, board): # Build the final argument list args_expanded = ["-D{}".format(a.replace('"', '')) for a in args] - if self.args.cmake_opts: - self.args.cmake_opts.extend(args_expanded) - else: - self.args.cmake_opts = args_expanded + self.args.cmake_opts.extend(args_expanded) return found_test_metadata diff --git a/scripts/west_commands/tests/test_build.py b/scripts/west_commands/tests/test_build.py index 3acb47c8fc85..f6208e2dd1f5 100644 --- a/scripts/west_commands/tests/test_build.py +++ b/scripts/west_commands/tests/test_build.py @@ -13,11 +13,11 @@ TEST_CASES = [ {'r': [], - 's': None, 'c': None}, + 's': None, 'c': []}, {'r': ['source_dir'], - 's': 'source_dir', 'c': None}, + 's': 'source_dir', 'c': []}, {'r': ['source_dir', '--'], - 's': 'source_dir', 'c': None}, + 's': 'source_dir', 'c': []}, {'r': ['source_dir', '--', 'cmake_opt'], 's': 'source_dir', 'c': ['cmake_opt']}, {'r': ['source_dir', '--', 'cmake_opt', 'cmake_opt2'], @@ -27,7 +27,7 @@ {'r': ['thing_one', 'thing_two', 'thing_three'], 's': 'thing_one', 'c': ['thing_two', 'thing_three']}, {'r': ['--'], - 's': None, 'c': None}, + 's': None, 'c': []}, {'r': ['--', '--'], 's': None, 'c': ['--']}, {'r': ['--', 'cmake_opt'], From de18a52a20090f57ea5a9438563a70a5876dc17c Mon Sep 17 00:00:00 2001 From: Thorsten Klein Date: Wed, 24 Dec 2025 22:44:16 +0100 Subject: [PATCH 1920/3659] scripts: west_commands: tests: test_build: add tests for west build args Add tests to ensure 'west build' arguments are correctly forwarded to CMake in the correct order. Signed-off-by: Thorsten Klein --- scripts/west_commands/tests/test_build.py | 118 +++++++++++++++++++++- 1 file changed, 117 insertions(+), 1 deletion(-) diff --git a/scripts/west_commands/tests/test_build.py b/scripts/west_commands/tests/test_build.py index f6208e2dd1f5..d52cdeb1c66b 100644 --- a/scripts/west_commands/tests/test_build.py +++ b/scripts/west_commands/tests/test_build.py @@ -4,9 +4,10 @@ from argparse import Namespace -from build import Build +from build import Build, SYSBUILD_PROJ_DIR from build_helpers import DEFAULT_BUILD_DIR from pathlib import Path +import argparse import configparser import os import pytest @@ -61,6 +62,121 @@ def test_parse_remainder(test_case): assert b.args.cmake_opts == test_case['c'] +TEST_CASES_CMAKE_ARGS = [ + # check that given args (a) lead to expected cmake arguments (e) in correct oder + # cmake_opts + {'a': ['--cmake-opt=-Da=1', '--cmake-opt=-Db=2'], + 'e': ['-Da=1', '-Db=2']}, + {'a': ['--cmake-opt=-Da=1', '--', '-Db=2'], + 'e': ['-Da=1', '-Db=2']}, + # build_dir + {'a': ['-d', 'test_dir'], + 'e': ['-Btest_dir']}, + {'a': ['--build-dir=test_dir'], + 'e': ['-Btest_dir']}, + # source_dir + {'a': ['-s', 'test_dir'], + 'e': ['-Stest_dir']}, + {'a': ['--source-dir=test_dir'], + 'e': ['-Stest_dir']}, + # snippets + {'a': ['-S', 'first', '-Ssecond', '-S=third', '--snippet=fourth', '--snippet', 'fifth'], + 'e': ['-DSNIPPET=first;second;third;fourth;fifth']}, + {'a': ['--cmake-opt=-DSNIPPET=cmake_opt', '-S=arg'], + 'e': ['-DSNIPPET=cmake_opt', '-DSNIPPET=arg']}, + # shields + {'a': ['--shield', 'first', '--shield=second'], + 'e': ['-DSHIELD=first;second']}, + {'a': ['--cmake-opt=-DSHIELD=cmake_opt', '--shield=arg'], + 'e': ['-DSHIELD=cmake_opt', '-DSHIELD=arg']}, + # extra_conf_files + {'a': ['--extra-conf', 'first', '--extra-conf=second'], + 'e': ['-DEXTRA_CONF_FILE=first;second']}, + {'a': ['--cmake-opt=-DEXTRA_CONF_FILE=cmake', '--extra-conf=arg'], + 'e': ['-DEXTRA_CONF_FILE=cmake', '-DEXTRA_CONF_FILE=arg']}, + # extra_dtc_overlay_files + {'a': ['--extra-dtc-overlay', 'first', '--extra-dtc-overlay=second'], + 'e': ['-DEXTRA_DTC_OVERLAY_FILE=first;second']}, + {'a': ['--cmake-opt=-DEXTRA_DTC_OVERLAY_FILE=cmake', '--extra-dtc-overlay=arg'], + 'e': ['-DEXTRA_DTC_OVERLAY_FILE=cmake', '-DEXTRA_DTC_OVERLAY_FILE=arg']}, + # sysbuild + {'a': ['--sysbuild'], + 'e': [f'-S{SYSBUILD_PROJ_DIR}']}, + {'a': ['--no-sysbuild', '--source-dir=test_dir'], + 'e': ['-Stest_dir']}, + # combination of multiple arguments (in correct order) + {'a': [ + '--cmake-opt=-Dx', + '--build-dir=x', + '--source-dir=x', + '--snippet=x', + '--shield=x', + '--extra-conf=x', + '--extra-dtc-overlay=x', + '--', + '-Dy', + '-Dz', + ], + 'e': [ + '-Bx', + '-Dx', + '-Dy', + '-Dz', + '-DSNIPPET=x', + '-DSHIELD=x', + '-DEXTRA_CONF_FILE=x', + '-DEXTRA_DTC_OVERLAY_FILE=x', + '-Sx', + ]}, +] + +@pytest.mark.parametrize('test_case', TEST_CASES_CMAKE_ARGS) +def test_cmake_args(monkeypatch, test_case): + """ + Test that 'west build' arguments are correctly forwarded to CMake. + """ + args = test_case['a'] + expected = test_case['e'] + + b = Build() + + # --- Setup argument parser --- + parser = argparse.ArgumentParser(allow_abbrev=False) + subparser = parser.add_subparsers() + command_parser = b.do_add_parser(subparser) + + # Parse known args + b.args, remainder = command_parser.parse_known_args(args) + + # Set some class variables for the test + b.run_cmake = True + b.source_dir = b.args.source_dir + b.build_dir = b.args.build_dir + + # Parse remainder + b._parse_remainder(remainder) + + # --- Monkeypatch run_cmake --- + def run_cmake_mock(final_cmake_args, dry_run, env): + """ + Check that all expected arguments occur in correct order. + """ + previous_position = -1 + for arg in expected: + assert arg in final_cmake_args, f"{arg} not found in {final_cmake_args}" + current_position = final_cmake_args.index(arg) + assert current_position > previous_position, ( + f"{arg} is out of order in {final_cmake_args}" + ) + previous_position = current_position + + monkeypatch.setattr('build.run_cmake', run_cmake_mock) + monkeypatch.setattr(b, '_banner', lambda _: True) + + # --- Trigger CMake run --- + b._run_cmake(board='any', origin=None) + + cwd = Path(os.getcwd()) DEFAULT_ARGS = Namespace( From cd530875a56bcf2eefb6ba08459962e5a4d8f3ce Mon Sep 17 00:00:00 2001 From: Andrej Butok Date: Thu, 8 Jan 2026 14:08:24 +0100 Subject: [PATCH 1921/3659] boards: nxp: Fix NXP FRDM names in yaml - Fixes NXP FRDM names in yaml files. - The '-' was missed for some NXP FRDM boards. - It caused an inconsistent board list in MCUx-VSCode extension. Signed-off-by: Andrej Butok --- boards/nxp/frdm_mcxa153/frdm_mcxa153.yaml | 2 +- boards/nxp/frdm_mcxa156/frdm_mcxa156.yaml | 2 +- boards/nxp/frdm_mcxa344/frdm_mcxa344.yaml | 2 +- boards/nxp/frdm_mcxa577/frdm_mcxa577.yaml | 2 +- boards/nxp/frdm_mcxaxx6/frdm_mcxa266.yaml | 2 +- boards/nxp/frdm_mcxaxx6/frdm_mcxa346.yaml | 2 +- boards/nxp/frdm_mcxaxx6/frdm_mcxa366.yaml | 2 +- boards/nxp/frdm_mcxe31b/frdm_mcxe31b.yaml | 2 +- boards/nxp/frdm_mcxn236/frdm_mcxn236.yaml | 2 +- boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0.yaml | 2 +- boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_ns.yaml | 2 +- boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_qspi.yaml | 2 +- boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu1.yaml | 2 +- boards/nxp/frdm_mcxw71/frdm_mcxw71.yaml | 2 +- boards/nxp/frdm_mcxw72/frdm_mcxw72_mcxw727c_cpu0.yaml | 2 +- boards/nxp/frdm_rw612/board.yml | 2 +- boards/nxp/frdm_rw612/frdm_rw612.yaml | 2 +- 17 files changed, 17 insertions(+), 17 deletions(-) diff --git a/boards/nxp/frdm_mcxa153/frdm_mcxa153.yaml b/boards/nxp/frdm_mcxa153/frdm_mcxa153.yaml index 252b7233cc6f..96915a6de2c0 100644 --- a/boards/nxp/frdm_mcxa153/frdm_mcxa153.yaml +++ b/boards/nxp/frdm_mcxa153/frdm_mcxa153.yaml @@ -5,7 +5,7 @@ # identifier: frdm_mcxa153 -name: NXP FRDM MCXA153 +name: NXP FRDM-MCXA153 type: mcu arch: arm ram: 24 diff --git a/boards/nxp/frdm_mcxa156/frdm_mcxa156.yaml b/boards/nxp/frdm_mcxa156/frdm_mcxa156.yaml index af20bcd7445b..c9be3adf3b5f 100644 --- a/boards/nxp/frdm_mcxa156/frdm_mcxa156.yaml +++ b/boards/nxp/frdm_mcxa156/frdm_mcxa156.yaml @@ -5,7 +5,7 @@ # identifier: frdm_mcxa156 -name: NXP FRDM MCXA156 +name: NXP FRDM-MCXA156 type: mcu arch: arm ram: 128 diff --git a/boards/nxp/frdm_mcxa344/frdm_mcxa344.yaml b/boards/nxp/frdm_mcxa344/frdm_mcxa344.yaml index d0bacc5f75b7..d458aaa7dff1 100644 --- a/boards/nxp/frdm_mcxa344/frdm_mcxa344.yaml +++ b/boards/nxp/frdm_mcxa344/frdm_mcxa344.yaml @@ -5,7 +5,7 @@ # identifier: frdm_mcxa344 -name: NXP FRDM MCXA344 +name: NXP FRDM-MCXA344 type: mcu arch: arm ram: 48 diff --git a/boards/nxp/frdm_mcxa577/frdm_mcxa577.yaml b/boards/nxp/frdm_mcxa577/frdm_mcxa577.yaml index 8fb1dcea4493..dfb7f1e2bff6 100644 --- a/boards/nxp/frdm_mcxa577/frdm_mcxa577.yaml +++ b/boards/nxp/frdm_mcxa577/frdm_mcxa577.yaml @@ -5,7 +5,7 @@ # identifier: frdm_mcxa577 -name: NXP FRDM MCXA577 +name: NXP FRDM-MCXA577 type: mcu arch: arm ram: 640 diff --git a/boards/nxp/frdm_mcxaxx6/frdm_mcxa266.yaml b/boards/nxp/frdm_mcxaxx6/frdm_mcxa266.yaml index fee2ae158e8f..54bdd53c9213 100644 --- a/boards/nxp/frdm_mcxaxx6/frdm_mcxa266.yaml +++ b/boards/nxp/frdm_mcxaxx6/frdm_mcxa266.yaml @@ -5,7 +5,7 @@ # identifier: frdm_mcxa266 -name: NXP FRDM MCXA266 +name: NXP FRDM-MCXA266 type: mcu arch: arm ram: 240 diff --git a/boards/nxp/frdm_mcxaxx6/frdm_mcxa346.yaml b/boards/nxp/frdm_mcxaxx6/frdm_mcxa346.yaml index 3214271167e2..cad201d90bc2 100644 --- a/boards/nxp/frdm_mcxaxx6/frdm_mcxa346.yaml +++ b/boards/nxp/frdm_mcxaxx6/frdm_mcxa346.yaml @@ -5,7 +5,7 @@ # identifier: frdm_mcxa346 -name: NXP FRDM MCXA346 +name: NXP FRDM-MCXA346 type: mcu arch: arm ram: 240 diff --git a/boards/nxp/frdm_mcxaxx6/frdm_mcxa366.yaml b/boards/nxp/frdm_mcxaxx6/frdm_mcxa366.yaml index a242e3880163..031c6aa9de7e 100644 --- a/boards/nxp/frdm_mcxaxx6/frdm_mcxa366.yaml +++ b/boards/nxp/frdm_mcxaxx6/frdm_mcxa366.yaml @@ -5,7 +5,7 @@ # identifier: frdm_mcxa366 -name: NXP FRDM MCXA366 +name: NXP FRDM-MCXA366 type: mcu arch: arm ram: 240 diff --git a/boards/nxp/frdm_mcxe31b/frdm_mcxe31b.yaml b/boards/nxp/frdm_mcxe31b/frdm_mcxe31b.yaml index e2a69046a790..adc7728fc3f3 100644 --- a/boards/nxp/frdm_mcxe31b/frdm_mcxe31b.yaml +++ b/boards/nxp/frdm_mcxe31b/frdm_mcxe31b.yaml @@ -2,7 +2,7 @@ # SPDX-License-Identifier: Apache-2.0 identifier: frdm_mcxe31b -name: NXP FRDM MCXE31B +name: NXP FRDM-MCXE31B type: mcu arch: arm ram: 288 diff --git a/boards/nxp/frdm_mcxn236/frdm_mcxn236.yaml b/boards/nxp/frdm_mcxn236/frdm_mcxn236.yaml index d366a7c74b53..24c031088172 100644 --- a/boards/nxp/frdm_mcxn236/frdm_mcxn236.yaml +++ b/boards/nxp/frdm_mcxn236/frdm_mcxn236.yaml @@ -5,7 +5,7 @@ # identifier: frdm_mcxn236 -name: NXP FRDM MCXN236 +name: NXP FRDM-MCXN236 type: mcu arch: arm ram: 256 diff --git a/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0.yaml b/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0.yaml index 08de31683cfe..b25b6235a90a 100644 --- a/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0.yaml +++ b/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0.yaml @@ -5,7 +5,7 @@ # identifier: frdm_mcxn947/mcxn947/cpu0 -name: NXP FRDM MCXN947 (CPU0) +name: NXP FRDM-MCXN947 (CPU0) type: mcu arch: arm ram: 320 diff --git a/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_ns.yaml b/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_ns.yaml index 1c9ffac1c989..cf4043936abe 100644 --- a/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_ns.yaml +++ b/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_ns.yaml @@ -5,7 +5,7 @@ # identifier: frdm_mcxn947/mcxn947/cpu0/ns -name: NXP FRDM MCXN947 (CPU0) (Non-Secure) +name: NXP FRDM-MCXN947 (CPU0) (Non-Secure) type: mcu arch: arm ram: 128 diff --git a/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_qspi.yaml b/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_qspi.yaml index 711d9d771fff..50fdca7748b5 100644 --- a/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_qspi.yaml +++ b/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_qspi.yaml @@ -5,7 +5,7 @@ # identifier: frdm_mcxn947/mcxn947/cpu0/qspi -name: NXP FRDM MCXN947 QSPI (CPU0) +name: NXP FRDM-MCXN947 QSPI (CPU0) type: mcu arch: arm ram: 320 diff --git a/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu1.yaml b/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu1.yaml index 62335a40f84a..92264551d8c2 100644 --- a/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu1.yaml +++ b/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu1.yaml @@ -5,7 +5,7 @@ # identifier: frdm_mcxn947/mcxn947/cpu1 -name: NXP FRDM MCXN947 (CPU1) +name: NXP FRDM-MCXN947 (CPU1) type: mcu arch: arm ram: 64 diff --git a/boards/nxp/frdm_mcxw71/frdm_mcxw71.yaml b/boards/nxp/frdm_mcxw71/frdm_mcxw71.yaml index 08f7b29929a4..2648f6c21ebb 100644 --- a/boards/nxp/frdm_mcxw71/frdm_mcxw71.yaml +++ b/boards/nxp/frdm_mcxw71/frdm_mcxw71.yaml @@ -5,7 +5,7 @@ # identifier: frdm_mcxw71 -name: NXP FRDM_MCXW71 +name: NXP FRDM-MCXW71 type: mcu arch: arm ram: 64 diff --git a/boards/nxp/frdm_mcxw72/frdm_mcxw72_mcxw727c_cpu0.yaml b/boards/nxp/frdm_mcxw72/frdm_mcxw72_mcxw727c_cpu0.yaml index 010a6973f410..27fdbc9c0976 100644 --- a/boards/nxp/frdm_mcxw72/frdm_mcxw72_mcxw727c_cpu0.yaml +++ b/boards/nxp/frdm_mcxw72/frdm_mcxw72_mcxw727c_cpu0.yaml @@ -1,5 +1,5 @@ identifier: frdm_mcxw72/mcxw727c/cpu0 -name: NXP FRDM_MCXW72 +name: NXP FRDM-MCXW72 type: mcu arch: arm ram: 264 diff --git a/boards/nxp/frdm_rw612/board.yml b/boards/nxp/frdm_rw612/board.yml index 17ec6bda8298..2415eb687dc2 100644 --- a/boards/nxp/frdm_rw612/board.yml +++ b/boards/nxp/frdm_rw612/board.yml @@ -1,6 +1,6 @@ board: name: frdm_rw612 - full_name: FRDM_RW612 + full_name: FRDM-RW612 vendor: nxp socs: - name: rw612 diff --git a/boards/nxp/frdm_rw612/frdm_rw612.yaml b/boards/nxp/frdm_rw612/frdm_rw612.yaml index 29401a9c3fca..c12572f90136 100644 --- a/boards/nxp/frdm_rw612/frdm_rw612.yaml +++ b/boards/nxp/frdm_rw612/frdm_rw612.yaml @@ -5,7 +5,7 @@ # identifier: frdm_rw612 -name: NXP FRDM_RW612 +name: NXP FRDM-RW612 type: mcu arch: arm toolchain: From 46a5734ece38f40851f825fbfebc531d7f2bf2d8 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 9 Jan 2026 09:17:58 +0100 Subject: [PATCH 1922/3659] soc: nordic: common: Introduce NRF_DT_(INST)_IRQ_ utility macros Introduce the NRF_DT_IRQ_DIRECT_DEFINE and NRF_DT_IRQ_CONNECT macros which reduce provide a common way for nordic drivers to adapt to the presence of the SW ISR table which is commonly excluded as it is not required for nordic socs. Also adds device driver inst variants of the macros. Signed-off-by: Bjarki Arge Andreasen --- soc/nordic/common/soc_nrf_common.h | 58 ++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/soc/nordic/common/soc_nrf_common.h b/soc/nordic/common/soc_nrf_common.h index c963b6512188..1a2584ce3641 100644 --- a/soc/nordic/common/soc_nrf_common.h +++ b/soc/nordic/common/soc_nrf_common.h @@ -324,6 +324,64 @@ (0) \ ) +/** + * @brief Utility macro to declare and define direct IRQ if required + * + * @param node_id Devicetree node identifier + * @param handler IRQ handler + * @param param Parameter passed to IRQ handler + */ +#define NRF_DT_IRQ_DIRECT_DEFINE(node_id, handler, param) \ + COND_CODE_1( \ + CONFIG_GEN_SW_ISR_TABLE, \ + (), \ + ( \ + ISR_DIRECT_DECLARE(CONCAT(handler, _, DT_DEP_ORD(node_id))) \ + { \ + handler(param); \ + ISR_DIRECT_PM(); \ + return 1; \ + } \ + ) \ + ) + +/** Device driver instance variant of NRF_DT_IRQ_DIRECT_DEFINE() */ +#define NRF_DT_INST_IRQ_DIRECT_DEFINE(inst, handler, param) \ + NRF_DT_IRQ_DIRECT_DEFINE(DT_DRV_INST(inst), handler, param) + +/** + * @brief Utility macro to connect IRQ handler + * + * @param node_id Devicetree node identifier + * @param handler IRQ handler + * @param param Parameter passed to IRQ handler + */ +#define NRF_DT_IRQ_CONNECT(node_id, handler, param) \ + COND_CODE_1( \ + CONFIG_GEN_SW_ISR_TABLE, \ + ( \ + IRQ_CONNECT( \ + DT_IRQN(node_id), \ + DT_IRQ(node_id, priority), \ + handler, \ + param, \ + 0 \ + ) \ + ), \ + ( \ + IRQ_DIRECT_CONNECT( \ + DT_IRQN(node_id), \ + DT_IRQ(node_id, priority), \ + CONCAT(handler, _, DT_DEP_ORD(node_id)), \ + 0 \ + ) \ + ) \ + ) + +/** Device driver instance variant of NRF_DT_IRQ_DIRECT_DEFINE() */ +#define NRF_DT_INST_IRQ_CONNECT(inst, handler, param) \ + NRF_DT_IRQ_CONNECT(DT_DRV_INST(inst), handler, param) + #endif /* !_ASMLANGUAGE */ #endif From 2e9586b33b60b3c2e998c347e6697852149cc067 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 9 Jan 2026 08:45:37 +0100 Subject: [PATCH 1923/3659] drivers: spi: nrfx_spim: Use NRF_DT_INST_IRQ macros Use NRF_DT_INST_IRQ_ macros which support building with and without SW ISR table for all nordic socs. Signed-off-by: Bjarki Arge Andreasen --- drivers/spi/spi_nrfx_spim.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/spi/spi_nrfx_spim.c b/drivers/spi/spi_nrfx_spim.c index d92b8049ac16..8703eaac9ea9 100644 --- a/drivers/spi/spi_nrfx_spim.c +++ b/drivers/spi/spi_nrfx_spim.c @@ -624,10 +624,18 @@ static int spi_nrfx_deinit(const struct device *dev) .dev = DEVICE_DT_GET(DT_DRV_INST(inst)), \ .busy = false, \ }; \ + NRF_DT_INST_IRQ_DIRECT_DEFINE( \ + inst, \ + nrfx_spim_irq_handler, \ + &CONCAT(spi_, inst, _data.spim) \ + ) \ static void irq_connect##inst(void) \ { \ - IRQ_CONNECT(DT_INST_IRQN(inst), DT_INST_IRQ(inst, priority), \ - nrfx_spim_irq_handler, &spi_##inst##_data.spim, 0); \ + NRF_DT_INST_IRQ_CONNECT( \ + inst, \ + nrfx_spim_irq_handler, \ + &CONCAT(spi_, inst, _data.spim) \ + ); \ } \ PINCTRL_DT_INST_DEFINE(inst); \ static const struct spi_nrfx_config spi_##inst##z_config = { \ From 7f685ca60a80dea1a45697c5ccb1282bb9d680fb Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 9 Jan 2026 10:35:03 +0100 Subject: [PATCH 1924/3659] drivers: gpio: nrfx_gpio: Use NRF_DT_INST_IRQ macros Use NRF_DT_INST_IRQ_ macros which support building with and without SW ISR table for all nordic socs. Signed-off-by: Bjarki Arge Andreasen --- drivers/gpio/gpio_nrfx.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/drivers/gpio/gpio_nrfx.c b/drivers/gpio/gpio_nrfx.c index 5661aeafe2f1..244c492b4afe 100644 --- a/drivers/gpio/gpio_nrfx.c +++ b/drivers/gpio/gpio_nrfx.c @@ -14,6 +14,7 @@ #include #include #include +#include #include @@ -594,12 +595,23 @@ void gpio_nrfx_gpiote_irq_handler(void const *param) } #endif -#define GPIOTE_IRQ_HANDLER_CONNECT(node_id) \ - IRQ_CONNECT(DT_IRQN(node_id), \ - DT_IRQ(node_id, priority), \ - gpio_nrfx_gpiote_irq_handler, \ - &GPIOTE_NRFX_INST_BY_NODE(node_id), \ - 0); +#define GPIOTE_IRQ_HANDLER_CONNECT(node_id) \ + NRF_DT_IRQ_CONNECT( \ + node_id, \ + gpio_nrfx_gpiote_irq_handler, \ + &GPIOTE_NRFX_INST_BY_NODE(node_id) \ + ) + +#define GPIOTE_IRQ_DIRECT_DEFINE(node_id) \ + NRF_DT_IRQ_DIRECT_DEFINE( \ + node_id, \ + gpio_nrfx_gpiote_irq_handler, \ + &GPIOTE_NRFX_INST_BY_NODE(node_id) \ + ) + +#ifdef CONFIG_GPIO_NRFX_INTERRUPT + DT_FOREACH_STATUS_OKAY(nordic_nrf_gpiote, GPIOTE_IRQ_DIRECT_DEFINE); +#endif /* CONFIG_GPIO_NRFX_INTERRUPT */ static int gpio_nrfx_pm_hook(const struct device *port, enum pm_device_action action) { From e0481a1f3011fcd2bcefbe609373a89c26e40550 Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 9 Jan 2026 11:53:44 +0100 Subject: [PATCH 1925/3659] drivers: i2c: i2c_nrfx: Use NRF_DT_INST_IRQ macros Use NRF_DT_INST_IRQ_ macros which support building with and without SW ISR table for all nordic socs. Signed-off-by: Bjarki Arge Andreasen --- drivers/i2c/i2c_nrfx_twim.c | 12 ++++++++++-- drivers/i2c/i2c_nrfx_twim_rtio.c | 12 ++++++++++-- drivers/i2c/i2c_nrfx_twis.c | 14 ++++++++++++-- 3 files changed, 32 insertions(+), 6 deletions(-) diff --git a/drivers/i2c/i2c_nrfx_twim.c b/drivers/i2c/i2c_nrfx_twim.c index 7f9369cce0b8..89642f27d07b 100644 --- a/drivers/i2c/i2c_nrfx_twim.c +++ b/drivers/i2c/i2c_nrfx_twim.c @@ -281,12 +281,20 @@ static DEVICE_API(i2c, i2c_nrfx_twim_driver_api) = { "Wrong I2C " #inst " frequency setting in dts"); \ static struct i2c_nrfx_twim_data twim_##inst##_data; \ static struct i2c_nrfx_twim_common_config twim_##inst##z_config; \ + NRF_DT_INST_IRQ_DIRECT_DEFINE( \ + inst, \ + nrfx_twim_irq_handler, \ + &CONCAT(twim_, inst, _data.twim) \ + ) \ static void pre_init##inst(void) \ { \ twim_##inst##z_config.twim = &twim_##inst##_data.twim; \ twim_##inst##_data.twim.p_twim = (NRF_TWIM_Type *)DT_INST_REG_ADDR(inst); \ - IRQ_CONNECT(DT_INST_IRQN(inst), DT_INST_IRQ(inst, priority), \ - nrfx_twim_irq_handler, &twim_##inst##_data.twim, 0); \ + NRF_DT_INST_IRQ_CONNECT( \ + inst, \ + nrfx_twim_irq_handler, \ + &CONCAT(twim_, inst, _data.twim) \ + ) \ } \ IF_ENABLED(USES_MSG_BUF(inst), \ (static uint8_t twim_##inst##_msg_buf[MSG_BUF_SIZE(inst)] \ diff --git a/drivers/i2c/i2c_nrfx_twim_rtio.c b/drivers/i2c/i2c_nrfx_twim_rtio.c index cae5acef6a52..84fcc314ba5d 100644 --- a/drivers/i2c/i2c_nrfx_twim_rtio.c +++ b/drivers/i2c/i2c_nrfx_twim_rtio.c @@ -253,11 +253,19 @@ static int i2c_nrfx_twim_rtio_deinit(const struct device *dev) .p_twim = (NRF_TWIM_Type *)DT_INST_REG_ADDR(inst), \ }, \ }; \ + NRF_DT_INST_IRQ_DIRECT_DEFINE( \ + inst, \ + nrfx_twim_irq_handler, \ + &CONCAT(twim_, inst, z_data.twim) \ + ) \ static void pre_init##inst(void) \ { \ twim_##inst##z_data.twim.p_twim = (NRF_TWIM_Type *)DT_INST_REG_ADDR(inst); \ - IRQ_CONNECT(DT_INST_IRQN(inst), DT_INST_IRQ(inst, priority), \ - nrfx_twim_irq_handler, &twim_##inst##z_data.twim, 0); \ + NRF_DT_INST_IRQ_CONNECT( \ + inst, \ + nrfx_twim_irq_handler, \ + &CONCAT(twim_, inst, z_data.twim) \ + ) \ } \ IF_ENABLED(USES_MSG_BUF(inst), (MSG_BUF_DEFINE(inst);)) \ I2C_RTIO_DEFINE(_i2c##inst##_twim_rtio, \ diff --git a/drivers/i2c/i2c_nrfx_twis.c b/drivers/i2c/i2c_nrfx_twis.c index 302a0e5950c5..f4fe395452b5 100644 --- a/drivers/i2c/i2c_nrfx_twis.c +++ b/drivers/i2c/i2c_nrfx_twis.c @@ -312,11 +312,21 @@ static int shim_nrf_twis_deinit(const struct device *dev) #define SHIM_NRF_TWIS_DEVICE_DEFINE(id) \ static struct shim_nrf_twis_data SHIM_NRF_TWIS_NAME(id, data); \ NRF_DT_CHECK_NODE_HAS_REQUIRED_MEMORY_REGIONS(DT_DRV_INST(id)); \ + \ + NRF_DT_INST_IRQ_DIRECT_DEFINE( \ + id, \ + nrfx_twis_irq_handler, \ + &SHIM_NRF_TWIS_NAME(id, data).twis \ + ) \ + \ static void SHIM_NRF_TWIS_NAME(id, pre_init)(void) \ { \ SHIM_NRF_TWIS_NAME(id, data).twis.p_reg = (NRF_TWIS_Type *)DT_INST_REG_ADDR(id); \ - IRQ_CONNECT(DT_INST_IRQN(id), DT_INST_IRQ(id, priority), nrfx_twis_irq_handler, \ - &SHIM_NRF_TWIS_NAME(id, data).twis, 0); \ + NRF_DT_INST_IRQ_CONNECT( \ + id, \ + nrfx_twis_irq_handler, \ + &SHIM_NRF_TWIS_NAME(id, data).twis \ + ) \ } \ \ static void SHIM_NRF_TWIS_NAME(id, event_handler)(nrfx_twis_event_t const *event) \ From 46e1c2a52e12cf4174f9da07d58c61bee56f64ca Mon Sep 17 00:00:00 2001 From: Andrej Butok Date: Fri, 9 Jan 2026 14:14:12 +0100 Subject: [PATCH 1926/3659] boards: nxp: mimxrt1170_evk: unify the documentation title Removed revision from the MIMXRT1170-EVK documentation title, to be consistent with all other MIMXRT boards. Signed-off-by: Andrej Butok --- boards/nxp/mimxrt1170_evk/board.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boards/nxp/mimxrt1170_evk/board.yml b/boards/nxp/mimxrt1170_evk/board.yml index fce50aef20b3..a4e836fd3182 100644 --- a/boards/nxp/mimxrt1170_evk/board.yml +++ b/boards/nxp/mimxrt1170_evk/board.yml @@ -1,6 +1,6 @@ board: name: mimxrt1170_evk - full_name: MIMXRT1170-EVK/EVKB + full_name: MIMXRT1170-EVK vendor: nxp socs: - name: mimxrt1176 From 9066af6a70db0a315ef3f76fecf97535e18af7cf Mon Sep 17 00:00:00 2001 From: Tim Pambor Date: Mon, 12 Jan 2026 09:01:00 +0100 Subject: [PATCH 1927/3659] soc: st: stm32: {h5, l5, u5, wbax}: Correct cache line size STM32H5, STM32L5, STM32U5, and STM32WBAX series MCUs have external ICACHE/DCACHE with a cache line size of 16 bytes. The previous configuration incorrectly set the cache line size to 32 bytes (the default cache line size for Cortex-M cores). Signed-off-by: Tim Pambor --- soc/st/stm32/stm32h5x/Kconfig.defconfig | 6 ++++++ soc/st/stm32/stm32l5x/Kconfig.defconfig | 3 +++ soc/st/stm32/stm32u5x/Kconfig.defconfig | 9 +++++++++ soc/st/stm32/stm32wbax/Kconfig.defconfig | 3 +++ 4 files changed, 21 insertions(+) diff --git a/soc/st/stm32/stm32h5x/Kconfig.defconfig b/soc/st/stm32/stm32h5x/Kconfig.defconfig index d3eb43e42860..fa31c45314d3 100644 --- a/soc/st/stm32/stm32h5x/Kconfig.defconfig +++ b/soc/st/stm32/stm32h5x/Kconfig.defconfig @@ -10,9 +10,15 @@ rsource "Kconfig.defconfig.stm32h5*" config ICACHE default y +config ICACHE_LINE_SIZE + default 16 + config DCACHE default y if !SOC_STM32H503XX +config DCACHE_LINE_SIZE + default 16 + config CACHE_MANAGEMENT default y diff --git a/soc/st/stm32/stm32l5x/Kconfig.defconfig b/soc/st/stm32/stm32l5x/Kconfig.defconfig index 77ba04cece93..ee27620682b9 100644 --- a/soc/st/stm32/stm32l5x/Kconfig.defconfig +++ b/soc/st/stm32/stm32l5x/Kconfig.defconfig @@ -10,6 +10,9 @@ rsource "Kconfig.defconfig.stm32l5*" config ICACHE default y +config ICACHE_LINE_SIZE + default 16 + config CACHE_MANAGEMENT default y diff --git a/soc/st/stm32/stm32u5x/Kconfig.defconfig b/soc/st/stm32/stm32u5x/Kconfig.defconfig index 55a18e69ad0f..e7a4986efb8c 100644 --- a/soc/st/stm32/stm32u5x/Kconfig.defconfig +++ b/soc/st/stm32/stm32u5x/Kconfig.defconfig @@ -13,9 +13,18 @@ config ROM_START_OFFSET config ICACHE default y +config ICACHE_LINE_SIZE + default 16 + config DCACHE default y +config DCACHE_LINE_SIZE + default 32 if (SOC_STM32U595XX || SOC_STM32U599XX || \ + SOC_STM32U5A5XX || SOC_STM32U5A9XX || \ + SOC_STM32U5F9XX || SOC_STM32U5G9XX) + default 16 + config CACHE_MANAGEMENT default y diff --git a/soc/st/stm32/stm32wbax/Kconfig.defconfig b/soc/st/stm32/stm32wbax/Kconfig.defconfig index 2a6c438180b2..dd0b65d71553 100644 --- a/soc/st/stm32/stm32wbax/Kconfig.defconfig +++ b/soc/st/stm32/stm32wbax/Kconfig.defconfig @@ -10,6 +10,9 @@ rsource "Kconfig.defconfig.stm32wba*" config ICACHE default y +config ICACHE_LINE_SIZE + default 16 + config CACHE_MANAGEMENT default y From e0d6d425bd70bbc3466f8bbc8a0171f58540e985 Mon Sep 17 00:00:00 2001 From: Mathieu Choplain Date: Tue, 13 Jan 2026 18:00:20 +0100 Subject: [PATCH 1928/3659] drivers: disk: sdmmc_stm32: error out when no domain clock is provided If CONFIG_SDMMC_STM32_CLOCK_CHECK=y but the SDMMC node lacked domain clock, the driver would perform an out-of-bounds access to priv->pclken[1] and provide garbage as the "subsystem" in the call to clock_control_get_rate(). Detect this situation and error out with an explicit message instead to prevent UB and help users. Signed-off-by: Mathieu Choplain --- drivers/disk/sdmmc_stm32.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/disk/sdmmc_stm32.c b/drivers/disk/sdmmc_stm32.c index bde5a8fa555a..65599aa94dca 100644 --- a/drivers/disk/sdmmc_stm32.c +++ b/drivers/disk/sdmmc_stm32.c @@ -187,6 +187,11 @@ static int stm32_sdmmc_clock_enable(struct stm32_sdmmc_priv *priv) if (IS_ENABLED(CONFIG_SDMMC_STM32_CLOCK_CHECK)) { uint32_t sdmmc_clock_rate; + if (DT_INST_NUM_CLOCKS(0) <= 1) { + LOG_ERR("No domain clock provided on SDMMC DT node!"); + return -ENOTSUP; + } + if (clock_control_get_rate(clock, (clock_control_subsys_t)&priv->pclken[1], &sdmmc_clock_rate) != 0) { From 602b91039a8b8f10a602274e8d3415a95e9d3199 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 14 Jan 2026 15:57:16 +0100 Subject: [PATCH 1929/3659] net: core: Queue loopback packets instead of processing directly Instead of processing loopback packets from the TX thread directly, queue them for further processing by RX thread (if possible), just as regular packets. It's now possible as the information regarding the packet is a loopback one or not is stored directly in the net_pkt structure. This allows to avoid unexpected stack consumption increases if packets are sent for loopback destinations. Signed-off-by: Robert Lubos --- subsys/net/ip/net_core.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/subsys/net/ip/net_core.c b/subsys/net/ip/net_core.c index 058477ee37b2..698e755e44e7 100644 --- a/subsys/net/ip/net_core.c +++ b/subsys/net/ip/net_core.c @@ -365,6 +365,8 @@ static inline bool process_multicast(struct net_pkt *pkt) } #endif +static void net_queue_rx(struct net_if *iface, struct net_pkt *pkt); + int net_try_send_data(struct net_pkt *pkt, k_timeout_t timeout) { struct net_if *iface; @@ -413,7 +415,7 @@ int net_try_send_data(struct net_pkt *pkt, k_timeout_t timeout) NET_DBG("Loopback pkt %p back to us", pkt); net_pkt_set_loopback(pkt, true); net_pkt_set_l2_processed(pkt, true); - processing_data(pkt); + net_queue_rx(net_pkt_iface(pkt), pkt); ret = 0; goto err; } From 16ffda989b3c33b43922fa2ee68b81b6b9884fd0 Mon Sep 17 00:00:00 2001 From: Malon Tian Date: Thu, 15 Jan 2026 17:35:26 +0800 Subject: [PATCH 1930/3659] scripts: west: fix typos and formatting in sdk help message Specific fixes include: - Add missing space after period in the disk space warning. - Fix mismatched quotes in the --install-base example (usage of `...'). - Removed a typo double quote in the installation description. This addresses the CLI help message issues reported. Fixes #95609 Signed-off-by: Malon Tian --- scripts/west_commands/sdk.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/west_commands/sdk.py b/scripts/west_commands/sdk.py index d8381d4508d3..aa0a31e8f5ee 100755 --- a/scripts/west_commands/sdk.py +++ b/scripts/west_commands/sdk.py @@ -82,7 +82,7 @@ def do_add_parser(self, parser_adder): Run 'west sdk install' to install Zephyr SDK. Set --version option to install a specific version of the SDK. - If not specified, the install version is detected from "${ZEPHYR_BASE}/SDK_VERSION file. + If not specified, the install version is detected from ${ZEPHYR_BASE}/SDK_VERSION file. SDKs older than 0.14.1 are not supported. You can specify the installation directory with --install-dir or --install-base. @@ -128,7 +128,7 @@ def do_add_parser(self, parser_adder): metavar="BASE", help="Base directory to SDK install. " "The subdirectory created by extracting the archive in will be the SDK installation directory. " - "For example, -b /foo/bar will install the SDK in `/foo/bar/zephyr-sdk-'." + "For example, -b /foo/bar will install the SDK in '/foo/bar/zephyr-sdk-'." ) install_args_parser.add_argument( "-d", @@ -156,7 +156,7 @@ def do_add_parser(self, parser_adder): help="toolchain(s) to install (e.g. 'arm-zephyr-eabi'). " "If this option is not given, toolchains for all architectures will be installed. " "If you are unsure which one to install, install all toolchains. " - "This requires downloading several gigabytes and the corresponding disk space." + "This requires downloading several gigabytes and occupies significant disk space. " "Each Zephyr SDK release may include different toolchains; " "see the release notes at https://github.com/zephyrproject-rtos/sdk-ng/releases.", ) From bc5f5f88292b573a45df9e6bdedc45d257633fbf Mon Sep 17 00:00:00 2001 From: Gaetan Perrot Date: Fri, 16 Jan 2026 16:51:55 +0900 Subject: [PATCH 1931/3659] boards: adi: fix evaluation typo in board names Fix a spelling mistake in the board name description for ADI evaluation boards. No functional change. Signed-off-by: Gaetan Perrot --- boards/adi/eval_adin1110ebz/adi_eval_adin1110ebz.yaml | 2 +- .../adi/eval_adin2111d1z/adi_eval_adin2111d1z_max32690_m4.yaml | 2 +- boards/adi/eval_adin2111ebz/adi_eval_adin2111ebz.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/boards/adi/eval_adin1110ebz/adi_eval_adin1110ebz.yaml b/boards/adi/eval_adin1110ebz/adi_eval_adin1110ebz.yaml index f7d2a100e2a5..818c6bf24ff7 100644 --- a/boards/adi/eval_adin1110ebz/adi_eval_adin1110ebz.yaml +++ b/boards/adi/eval_adin1110ebz/adi_eval_adin1110ebz.yaml @@ -1,5 +1,5 @@ identifier: adi_eval_adin1110ebz -name: ADI EVAL-ADIN1110EBZ evaulation board +name: ADI EVAL-ADIN1110EBZ evaluation board type: mcu arch: arm toolchain: diff --git a/boards/adi/eval_adin2111d1z/adi_eval_adin2111d1z_max32690_m4.yaml b/boards/adi/eval_adin2111d1z/adi_eval_adin2111d1z_max32690_m4.yaml index 9a5440723614..86d641925c28 100644 --- a/boards/adi/eval_adin2111d1z/adi_eval_adin2111d1z_max32690_m4.yaml +++ b/boards/adi/eval_adin2111d1z/adi_eval_adin2111d1z_max32690_m4.yaml @@ -1,5 +1,5 @@ identifier: adi_eval_adin2111d1z/max32690/m4 -name: ADI EVAL-ADIN2111D1Z evaulation board +name: ADI EVAL-ADIN2111D1Z evaluation board type: mcu arch: arm vendor: adi diff --git a/boards/adi/eval_adin2111ebz/adi_eval_adin2111ebz.yaml b/boards/adi/eval_adin2111ebz/adi_eval_adin2111ebz.yaml index 8c95a7748287..97d0cba14c87 100644 --- a/boards/adi/eval_adin2111ebz/adi_eval_adin2111ebz.yaml +++ b/boards/adi/eval_adin2111ebz/adi_eval_adin2111ebz.yaml @@ -1,5 +1,5 @@ identifier: adi_eval_adin2111ebz -name: ADI EVAL-ADIN2111EBZ evaulation board +name: ADI EVAL-ADIN2111EBZ evaluation board type: mcu arch: arm toolchain: From 4808de2498bdbb48a7612dfe334b8859eeee30f5 Mon Sep 17 00:00:00 2001 From: Jason Yu Date: Sun, 16 Nov 2025 20:28:39 +0800 Subject: [PATCH 1932/3659] drivers: flash: soc_mcux: Fix ram function permission issue Add workaround for MCUXSDK FTFX driver when FTFx_DRIVER_IS_FLASH_RESIDENT is enabled. The SDK places the run command function in data section which is not executable when Zephyr configures memory permissions. Implement a RAM function to replace the FTFX driver's run command function Fixes: #98560 Signed-off-by: Jason Yu --- drivers/flash/soc_flash_mcux.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/drivers/flash/soc_flash_mcux.c b/drivers/flash/soc_flash_mcux.c index 8300c0870b99..fc5e8bbb943b 100644 --- a/drivers/flash/soc_flash_mcux.c +++ b/drivers/flash/soc_flash_mcux.c @@ -157,6 +157,23 @@ static void clear_flash_caches(void) #define clear_flash_caches(...) #endif +#if defined(FTFx_DRIVER_IS_FLASH_RESIDENT) && FTFx_DRIVER_IS_FLASH_RESIDENT +/* + * MCUXSDK FTFX driver (fsl_ftfx_controller.c) places the run command function + * in data section (array s_ftfxRunCommand). When Zephyr configured the memory + * permission, the data section is not executable. The workaround is + * implementing a ram function in Zephyr, to replace FTFX driver's run command + * function. + */ +static __ramfunc void flash_ftfx_run_command(FTFx_REG8_ACCESS_TYPE ftfx_fstat) +{ + *ftfx_fstat = FTFx_FSTAT_CCIF_MASK; + + while (!((*ftfx_fstat) & FTFx_FSTAT_CCIF_MASK)) { + } +} +#endif /* FTFx_DRIVER_IS_FLASH_RESIDENT */ + struct flash_priv { flash_config_t config; /* @@ -378,6 +395,15 @@ static int flash_mcux_init(const struct device *dev) rc = FLASH_Init(&priv->config); +#if defined(FTFx_DRIVER_IS_FLASH_RESIDENT) && FTFx_DRIVER_IS_FLASH_RESIDENT + /* MCUXSDK FTFX driver's commadAddr is an address to data (LSB = 0), but + * (uint32_t)flash_ftfx_run_command is an address to code (LDB = 1), so + * clear the LSB here. + */ + priv->config.ftfxConfig->runCmdFuncAddr.commadAddr = + ((uint32_t)flash_ftfx_run_command) & ~0x01U; +#endif /* FTFx_DRIVER_IS_FLASH_RESIDENT */ + FLASH_GetProperty(&priv->config, FLASH_PROP_BLOCK_BASE, &pflash_block_base); priv->pflash_block_base = (uint32_t) pflash_block_base; From 69c7befe26727c426804e5d00e6ff01c36bbb929 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Sun, 4 Jan 2026 20:36:28 +0000 Subject: [PATCH 1933/3659] drivers: eth_nxp_enet_qos: add promisc mode support Add support for ETHERNET_CONFIG_TYPE_PROMISC_MODE. Signed-off-by: Fabio Baltieri --- .../eth_nxp_enet_qos/eth_nxp_enet_qos_mac.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/drivers/ethernet/eth_nxp_enet_qos/eth_nxp_enet_qos_mac.c b/drivers/ethernet/eth_nxp_enet_qos/eth_nxp_enet_qos_mac.c index ee87763c352c..58572521072e 100644 --- a/drivers/ethernet/eth_nxp_enet_qos/eth_nxp_enet_qos_mac.c +++ b/drivers/ethernet/eth_nxp_enet_qos/eth_nxp_enet_qos_mac.c @@ -220,7 +220,12 @@ static void tx_dma_done(const struct device *dev) static enum ethernet_hw_caps eth_nxp_enet_qos_get_capabilities(const struct device *dev) { - return ETHERNET_LINK_100BASE | ETHERNET_LINK_10BASE | ENET_MAC_PACKET_FILTER_PM_MASK; + return ETHERNET_LINK_100BASE | + ETHERNET_LINK_10BASE | +#if defined(CONFIG_NET_PROMISCUOUS_MODE) + ETHERNET_PROMISC_MODE | +#endif + ENET_MAC_PACKET_FILTER_PM_MASK; } static bool software_owns_descriptor(volatile union nxp_enet_qos_rx_desc *desc) @@ -802,6 +807,15 @@ static int eth_nxp_enet_qos_set_config(const struct device *dev, data->mac_addr.addr[2], data->mac_addr.addr[3], data->mac_addr.addr[4], data->mac_addr.addr[5]); return 0; +#if defined(CONFIG_NET_PROMISCUOUS_MODE) + case ETHERNET_CONFIG_TYPE_PROMISC_MODE: + if (cfg->promisc_mode) { + base->MAC_PACKET_FILTER |= ENET_MAC_PACKET_FILTER_PR_MASK; + } else { + base->MAC_PACKET_FILTER &= ~ENET_MAC_PACKET_FILTER_PR_MASK; + } + return 0; +#endif default: break; } From bdf1e58a97aef023ca1f7665ba86b23f376cd578 Mon Sep 17 00:00:00 2001 From: Isabelle OGER Date: Tue, 2 Dec 2025 14:55:59 +0100 Subject: [PATCH 1934/3659] drivers: modem: introduce STMicroelectronics ST87M01 modem driver The STMicroelectronics ST87M01 modem is an ultra-compact low-power NB-IoT industrial module. The ST87M01 is a high-performance, fully programmable, ultra-compact, and low-power LTE Cat NB2 NB-IoT industrial module series, offering comprehensive worldwide band coverage and advanced security features. Supporting a wide range of IoT protocols, the ST87M01 module includes PDU SMS services and internet protocols such as TCP/IP, TLS/DTLS, CoAP, LwM2M, MQTT, and HTTP/HTTPS, enabling versatile connectivity and application scenarios. This driver introduces support for AT commands to query modem information and socket offloading for TCP/UDP transfers. Signed-off-by: Isabelle OGER --- drivers/modem/CMakeLists.txt | 1 + drivers/modem/Kconfig | 1 + drivers/modem/Kconfig.st87mxx | 47 ++ drivers/modem/st87mxx.c | 1447 +++++++++++++++++++++++++++++++++ drivers/modem/st87mxx.h | 217 +++++ 5 files changed, 1713 insertions(+) create mode 100644 drivers/modem/Kconfig.st87mxx create mode 100644 drivers/modem/st87mxx.c create mode 100644 drivers/modem/st87mxx.h diff --git a/drivers/modem/CMakeLists.txt b/drivers/modem/CMakeLists.txt index b92258b55b14..e3f7f8bdd9e8 100644 --- a/drivers/modem/CMakeLists.txt +++ b/drivers/modem/CMakeLists.txt @@ -20,6 +20,7 @@ zephyr_library_sources_ifdef(CONFIG_MODEM_QUECTEL_BG9X quectel-bg9x.c) zephyr_library_sources_ifdef(CONFIG_MODEM_RECEIVER modem_receiver.c) zephyr_library_sources_ifdef(CONFIG_MODEM_SHELL modem_shell.c) zephyr_library_sources_ifdef(CONFIG_MODEM_SOCKET modem_socket.c) +zephyr_library_sources_ifdef(CONFIG_MODEM_ST87MXX st87mxx.c) zephyr_library_sources_ifdef(CONFIG_MODEM_UBLOX_SARA ublox-sara-r4.c) zephyr_library_sources_ifdef(CONFIG_MODEM_WNCM14A2A wncm14a2a.c) # zephyr-keep-sorted-stop diff --git a/drivers/modem/Kconfig b/drivers/modem/Kconfig index 0d2fc2935b62..8f211f8d57d2 100644 --- a/drivers/modem/Kconfig +++ b/drivers/modem/Kconfig @@ -193,6 +193,7 @@ source "drivers/modem/Kconfig.at_shell" source "drivers/modem/Kconfig.cellular" source "drivers/modem/Kconfig.hl7800" source "drivers/modem/Kconfig.quectel-bg9x" +source "drivers/modem/Kconfig.st87mxx" source "drivers/modem/Kconfig.ublox-sara-r4" source "drivers/modem/Kconfig.wncm14a2a" source "drivers/modem/hl78xx/Kconfig.hl78xx" diff --git a/drivers/modem/Kconfig.st87mxx b/drivers/modem/Kconfig.st87mxx new file mode 100644 index 000000000000..0eaf38a3be92 --- /dev/null +++ b/drivers/modem/Kconfig.st87mxx @@ -0,0 +1,47 @@ +# Copyright (c) 2025 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +# ST87MXX driver options + +config MODEM_ST87MXX + bool "ST87MXX modem driver" + select MODEM_RECEIVER + select MODEM_CONTEXT + select MODEM_CMD_HANDLER + select MODEM_IFACE_UART + select MODEM_SOCKET + select NET_OFFLOAD + select NET_SOCKETS_OFFLOAD + imply GPIO + help + Enable ST87M01 NB-IoT modem driver. + +if MODEM_ST87MXX + config MODEM_ST87MXX_INIT_PRIORITY + int "ST87M01 driver init priority" + default 80 + help + ST87M01 device driver initialization priority. + Do not mess with it unless you know what you are doing. + Note that the priority needs to be lower than the net stack + so that it can start before the networking sub-system. + +config MODEM_ST87MXX_MAX_RX_DATA_LENGTH + int "Size of the receive buffer for the ST87M01 modem" + default 1024 + help + This buffer is used by the ST87M01 RX AT command logic. + +config MODEM_ST87MXX_MAX_TX_DATA_LENGTH + int "Size of the transmit buffer for the ST87M01 modem" + default 1024 + help + This buffer is used by the ST87M01 TX AT command logic. + +config MODEM_ST87MXX_RX_STACK_SIZE + int "Size of the stack for the ST87M01 modem driver RX thread" + default 1024 + help + This stack is used by the ST87M01 RX thread. + +endif # MODEM_ST87MXX diff --git a/drivers/modem/st87mxx.c b/drivers/modem/st87mxx.c new file mode 100644 index 000000000000..361b25247c04 --- /dev/null +++ b/drivers/modem/st87mxx.c @@ -0,0 +1,1447 @@ +/* + * Copyright (c) 2025 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT st_st87mxx + +#include +#include +#include +#include +#include "st87mxx.h" +#include +#include +#include +#include +#include +#include "modem_receiver.h" + +LOG_MODULE_REGISTER(modem_st87mxx, CONFIG_MODEM_LOG_LEVEL); + +#define MDM_BASE_SOCKET_NUM 0 + +/* RX thread structures */ +K_KERNEL_STACK_DEFINE(modem_rx_stack, CONFIG_MODEM_ST87MXX_RX_STACK_SIZE); +NET_BUF_POOL_DEFINE(mdm_recv_pool, MDM_RECV_MAX_BUF, MDM_RECV_BUF_SIZE, 0, NULL); +struct k_thread modem_rx_thread; + +static void ring_pin_cb(const struct device *dev, struct gpio_callback *cb, uint32_t pins); + +static const struct gpio_dt_spec reset_gpio = GPIO_DT_SPEC_INST_GET(0, mdm_reset_gpios); +static const struct gpio_dt_spec ring_gpio = GPIO_DT_SPEC_INST_GET(0, mdm_ring_gpios); +static struct gpio_callback ring_gpio_callback_data; +static char tmp_data[128]; +/** + * ST87 Reset states + */ +typedef enum { + RESET_PIN_OFF = 0, /* Reset Pin off */ + RESET_PIN_ON = 1, /* Reset Pin on */ + RESET_PIN_PULSE = 2 /* Reset Pin toggle */ +} st87mxx_reset_pin_t; + +/** + * Static Data for ST87MXX + */ +struct st87mxx_register { + struct mdm_receiver_context *mctx; + struct gpio_dt_spec *reset_gpio; + struct gpio_dt_spec *ring_gpio; +}; + +static const struct socket_op_vtable offload_socket_fd_op_vtable; +#if defined(CONFIG_DNS_RESOLVER) +static const struct socket_dns_offload offload_dns_ops; +static struct zsock_addrinfo dns_result; +static struct sockaddr dns_result_addr; +static char dns_result_canonname[DNS_MAX_NAME_SIZE + 1]; +#endif + +static struct modem_context mctx; +static struct st87mxx_data mdata; + + +static int offload_socket(int family, int type, int proto); + +static inline int digits(int n) +{ + int count = 0; + + while (n != 0) { + n /= 10; + ++count; + } + return count; +} + +/* Find first occurrence of a delimiter (either ',' or '\r') in a given string. */ +static const char *find_delim(const char *start) +{ + const char *comma = strchr(start, ','); + const char *cr = strchr(start, '\r'); + const char *delim; + + /* Find first occurrence of either ',' or '\r' after start */ + if (comma && cr) { + delim = (comma < cr) ? comma : cr; + } else if (comma) { + delim = comma; + } else { + delim = cr; + } + return delim; +} + +/* Extract the hex value for a given tag and return as unsigned long. */ +static int extract_hex_value(const char *input, const char *tag, unsigned long *output) +{ + char pattern[32]; + + snprintf(pattern, sizeof(pattern), "%s=", tag); + const char *start = strstr(input, pattern); + + if (!start) { + return 0; + } + + start += strlen(pattern); + const char *end = find_delim(start); + + if (!end) { + end = input + strlen(input); + } + + size_t len = end - start; + + if (len == 0 || len >= 16) { + return 0; + } + + char hex_str[17] = {0}; + + strncpy(hex_str, start, len); + hex_str[len] = '\0'; + + char *endptr; + + unsigned long val = strtoul(hex_str, &endptr, 16); + + if (*endptr != '\0') { + return 0; /* invalid hex */ + } + + *output = val; + return 1; +} + +MODEM_CMD_DEFINE(on_cmd_cgmi) +{ + size_t out_len = net_buf_linearize( + mdata.mdm_manufacturer, sizeof(mdata.mdm_manufacturer) - 1, data->rx_buf, 0, len); + mdata.mdm_manufacturer[out_len] = '\0'; + LOG_INF("Manufacturer: %s", mdata.mdm_manufacturer); + return 0; +} + +MODEM_CMD_DEFINE(on_cmd_cgmm) +{ + size_t out_len = net_buf_linearize(mdata.mdm_model, sizeof(mdata.mdm_model) - 1, + data->rx_buf, 0, len); + mdata.mdm_model[out_len] = '\0'; + LOG_INF("Model: %s", mdata.mdm_model); + return 0; +} + +MODEM_CMD_DEFINE(on_cmd_cgmr) +{ + size_t out_len = net_buf_linearize(mdata.mdm_revision, sizeof(mdata.mdm_revision) - 1, + data->rx_buf, 0, len); + mdata.mdm_revision[out_len] = '\0'; + LOG_INF("Revision: %s", mdata.mdm_revision); + return 0; +} + +MODEM_CMD_DEFINE(on_cmd_cgsn) +{ + size_t out_len = net_buf_linearize(mdata.mdm_imei, sizeof(mdata.mdm_imei) - 1, + data->rx_buf, 1, len); + mdata.mdm_imei[out_len] = '\0'; + LOG_INF("IMEI: %s", mdata.mdm_imei); + return 0; +} + +#if defined(CONFIG_MODEM_SIM_NUMBERS) +MODEM_CMD_DEFINE(on_cmd_cimi) +{ + size_t out_len = + net_buf_linearize(mdata.mdm_imsi, sizeof(mdata.mdm_imsi) - 1, data->rx_buf, 0, len); + mdata.mdm_imsi[out_len] = '\0'; + + /* Log the received information. */ + LOG_INF("IMSI: %s", mdata.mdm_imsi); + return 0; +} + +MODEM_CMD_DEFINE(on_cmd_iccid) +{ + size_t out_len = net_buf_linearize(mdata.mdm_iccid, sizeof(mdata.mdm_iccid) - 1, + data->rx_buf, 1, len); + mdata.mdm_iccid[out_len] = '\0'; + + /* Log the received information. */ + LOG_INF("%s", mdata.mdm_iccid); + return 0; +} +#endif + +MODEM_CMD_DEFINE(on_cmd_steng) +{ + unsigned long output = 0; + + net_buf_linearize(tmp_data, len, data->rx_buf, 2, len); + + extract_hex_value(tmp_data, "SRV1", &output); + + mdata.mdm_rssi = output >> 16; + mdata.mdm_rssi -= 0x10000; + + LOG_INF("RSSI: %d", mdata.mdm_rssi); + return 0; +} + +MODEM_CMD_DEFINE(on_cmd_ok) +{ + modem_cmd_handler_set_error(data, 0); + k_sem_give(&mdata.sem_response); + return 0; +} + +MODEM_CMD_DEFINE(on_cmd_error) +{ + modem_cmd_handler_set_error(data, -EIO); + k_sem_give(&mdata.sem_response); + return 0; +} + + +MODEM_CMD_DEFINE(on_cmd_sim_status) +{ + LOG_INF("on_cmd_sim_status %s", argv[0]); + return 0; +} + + + +MODEM_CMD_DEFINE(on_cmd_connection_status) +{ + LOG_INF("on_cmd_connection_status: %s", argv[0]); + return 0; +} + + +MODEM_CMD_DEFINE(on_cmd_registration_status) +{ + mdata.mdm_registration = atoi(argv[1]); + LOG_INF("on_cmd_registration_status: CREG: %u", mdata.mdm_registration); + return 0; +} + +MODEM_CMD_DEFINE(on_cmd_ip_config_status) +{ + mdata.context_id = atoi(argv[0]); + LOG_INF("on_cmd_ip_config_status: mdata.context_id: %u", mdata.context_id); + return 0; +} + +MODEM_CMD_DEFINE(on_cmd_sleep) +{ + LOG_INF("on_cmd_sleep: %s", argv[0]); + return 0; +} + +MODEM_CMD_DEFINE(on_cmd_wakeup) +{ + LOG_INF("on_cmd_wakeup: %s", argv[0]); + k_sem_give(&mdata.sem_response); + return 0; +} + +MODEM_CMD_DEFINE(on_cmd_socket_create) +{ + LOG_INF("on_cmd_socket_create: %s", argv[0]); + struct modem_socket *sock = NULL; + + /* Look up new socket by id. */ + sock = modem_socket_from_id(&mdata.socket_config, atoi(argv[0])); + return 0; +} + +MODEM_CMD_DEFINE(on_cmd_socket_ipread) +{ + LOG_INF("on_cmd_socket_ipread"); + int socket_data_length; + int bytes_to_skip; + int sock_id; + struct socket_read_data *sock_data; + int ret, i; + struct modem_socket *sock = NULL; + + if (!len) { + LOG_ERR("Invalid length, Aborting!"); + return -EAGAIN; + } + + /* Make sure we still have buf data. */ + if (!data->rx_buf) { + LOG_ERR("Incorrect format! Ignoring data!"); + return -EINVAL; + } + + socket_data_length = atoi(argv[2]); + + LOG_INF("socket_data_length = %d", socket_data_length); + + + /* No (or not enough) data available on the socket. */ + /* Skip context_id, socket_id, commas, len, CRLF */ + bytes_to_skip = digits(socket_data_length) + 2 + 4; + if (socket_data_length <= 0) { + LOG_ERR("Length problem (%d). Aborting!", socket_data_length); + return -EAGAIN; + } + + /* Check to make sure we have all of the data. */ + if (net_buf_frags_len(data->rx_buf) < (socket_data_length + bytes_to_skip)) { + LOG_DBG("Not enough data -- wait!"); + return -EAGAIN; + } + + /* Skip "len" and CRLF. */ + bytes_to_skip = digits(socket_data_length) + 2; + + + for (i = 0; i < bytes_to_skip; i++) { + net_buf_pull_u8(data->rx_buf); + } + + if (!data->rx_buf->len) { + data->rx_buf = net_buf_frag_del(NULL, data->rx_buf); + } + + sock_id = atoi(argv[1]); + + sock = modem_socket_from_id(&mdata.socket_config, sock_id); + if (!sock) { + LOG_ERR("Socket not found! (%d)", sock_id); + ret = -EINVAL; + goto exit; + } + + sock_data = (struct socket_read_data *)sock->data; + if (!sock_data) { + LOG_ERR("Socket data not found! Skip handling (%d)", sock_id); + ret = -EINVAL; + goto exit; + } + + ret = net_buf_linearize(sock_data->recv_buf, sock_data->recv_buf_len, + data->rx_buf, 0, (uint16_t)socket_data_length); + data->rx_buf = net_buf_skip(data->rx_buf, ret); + + sock_data->recv_read_len = ret; + if (ret != socket_data_length) { + LOG_ERR("Total copied data is different than received data!" + " copied:%d vs. received:%d", ret, socket_data_length); + ret = -EINVAL; + } + +exit: + /* Remove packet from list (ignore errors). */ + (void)modem_socket_packet_size_update(&mdata.socket_config, sock, + -socket_data_length); + return ret; +} + + +MODEM_CMD_DEFINE(on_cmd_ip_recv) +{ + LOG_INF("on_cmd_ip_recv"); + + struct modem_socket *sock; + int sock_id; + + sock_id = atoi(argv[1]); + + sock = modem_socket_from_id(&mdata.socket_config, sock_id); + if (!sock) { + return 0; + } + + /* Modem does not tell packet size. Set dummy for receive. */ + modem_socket_packet_size_update(&mdata.socket_config, sock, 1); + + LOG_INF("Data available on socket id: %d", sock_id); + modem_socket_data_ready(&mdata.socket_config, sock); + return 0; +} + +#if defined(CONFIG_DNS_RESOLVER) +MODEM_CMD_DEFINE(on_cmd_dns) +{ + LOG_INF("on_cmd_dns"); + + argv[0][strlen(argv[0])] = '\0'; + + /* Hard-code DNS to return IPv4. */ + dns_result_addr.sa_family = AF_INET; + (void)net_addr_pton(dns_result.ai_family, &argv[0][0], + &((struct sockaddr_in *)&dns_result_addr)->sin_addr); + + k_sem_give(&mdata.sem_dns); + return 0; +} +#endif + +MODEM_CMD_DEFINE(on_cmd_nvmread) +{ + LOG_INF("on_cmd_nvmread"); + + int ret = 0; + int tmp = 0; + size_t out_len; + char nvmrd[3]; + + out_len = net_buf_linearize(nvmrd, sizeof(nvmrd), data->rx_buf, 0, len); + nvmrd[out_len] = '\0'; + + ret = sscanf((const char *)nvmrd, "%x", (int *)&tmp); + mdata.cold_init_version = (uint8_t)tmp; + + k_sem_give(&mdata.sem_nvm); + return ret; +} + +/* + * Possible responses by the ST87MXX. + */ +static const struct modem_cmd response_cmds[] = { + MODEM_CMD("OK", on_cmd_ok, 0U, ""), + MODEM_CMD("ERROR", on_cmd_error, 0U, ""), + MODEM_CMD("+CME ERROR", on_cmd_error, 1U, ""), +}; + +/* + * Possible unsolicited commands. + */ +static const struct modem_cmd unsolicited_cmds[] = { + MODEM_CMD("#SIMST", on_cmd_sim_status, 1U, ""), + MODEM_CMD("+CSCON", on_cmd_connection_status, 1U, ""), + MODEM_CMD("#IPCFG: ", on_cmd_ip_config_status, 3U, ","), + MODEM_CMD("#IPRECV: ", on_cmd_ip_recv, 2U, ","), + MODEM_CMD("#SLEEP", on_cmd_sleep, 1U, ""), + MODEM_CMD("#WAKEUP", on_cmd_wakeup, 1U, ""), + MODEM_CMD("#STENG", on_cmd_steng, 1U, ""), +}; + +/* ST87MXX one-shot NVM configuration commands (sent at boot time). */ +static const struct setup_cmd init_cmds[] = { + SETUP_CMD("AT+CMEE=1", "", NULL, 0U, ""), + SETUP_CMD("AT+CEREG=5", "", NULL, 0U, ""), + SETUP_CMD("AT+CSCON=1", "", NULL, 0U, ""), + SETUP_CMD("AT#SLEEPIND=0x1F", "", NULL, 0U, ""), + SETUP_CMD("AT#WDGMODE=0", "", NULL, 0U, ""), + SETUP_CMD("AT#TEMPLIMIT=-40, 85, "STRINGIFY(TEMP_LOW_SHUTDOWN)", " + STRINGIFY(TEMP_HIGH_SHUTDONW)", 0, " + STRINGIFY(TEMP_SHUTDOWN), "", NULL, 0U, ""), + SETUP_CMD("AT#VBATLIMIT=2200, 3000, "STRINGIFY(VBAT_LOW_SHUTDOWN)", " + STRINGIFY(VBAT_HIGH_SHUTDOWN)", " + STRINGIFY(VBAT_SHUTDOWN)", 0, 0", "", NULL, 0U, ""), + SETUP_CMD("AT+CFUN=0", "", NULL, 0U, ""), + SETUP_CMD("AT#BANDSEL="BANDLIST, "", NULL, 0U, ""), + SETUP_CMD("AT#BANDCFG="BANDCFG, "", NULL, 0U, ""), + SETUP_CMD("AT#BANDCFG="BANDCFG_NMO1, "", NULL, 0U, ""), + SETUP_CMD("AT#BANDCFG="BANDCFG_NMO2, "", NULL, 0U, ""), + SETUP_CMD("AT#BANDCFG="BANDCFG_NMO3, "", NULL, 0U, ""), + SETUP_CMD("AT#SCAN=1,-104,1,360,1,360", "", NULL, 0U, ""), + SETUP_CMD("AT+CEDRXS=1,5,"STRINGIFY(EDRX_VALUE), "", NULL, 0U, ""), + SETUP_CMD("AT#PTW="STRINGIFY(PTW_VALUE), "", NULL, 0U, ""), + SETUP_CMD("AT+CPSMS="STRINGIFY(PSM_ENABLE)",,, "STRINGIFY(PERIODIC_TAU)", " + STRINGIFY(ACTIVE_TIME), "", NULL, 0U, ""), + SETUP_CMD("AT#SLEEPMODE=1, "STRINGIFY(HOLD_TIME)", " + STRINGIFY(AWAKE_TIME), "", NULL, 0U, ""), + SETUP_CMD("AT#RINGPIN="STRINGIFY(RING_PIN_ENABLE)", "STRINGIFY(RING_PIN_GPIO)", " + STRINGIFY(RING_PIN_POLARITY)", "STRINGIFY(RING_PIN_DELAY), "", NULL, 0U, ""), + SETUP_CMD("AT#WAKEUPEVENT=15, 3", "", NULL, 0U, ""), + SETUP_CMD("AT#IPPARAMS=1, 0, 65535, 60, "STRINGIFY(NB_PACKET_SENT_ENABLE)", " + STRINGIFY(DOMAIN_NAME), "", NULL, 0U, ""), + SETUP_CMD("AT#NVMWR="STRINGIFY(ST87MXX_COLD_VERSION_NVM_PAGE)", " + STRINGIFY(ST87MXX_COLD_VERSION_NVM_OFFSET)", 1, " + STRINGIFY(ST87MXX_COLD_CONFIG_VERSION), "", NULL, 0U, ""), + SETUP_CMD("AT#RESET=1", "", NULL, 0U, ""), +}; + + +/* Commands sent to the modem to set it up at init time. */ +static const struct setup_cmd setup_cmds[] = { + + /* Commands to read info from the modem (e.g. IMEI, Manufacturer Model etc). */ + SETUP_CMD("AT+CGMI", "", on_cmd_cgmi, 0U, ""), + SETUP_CMD("AT+CGMM", "", on_cmd_cgmm, 0U, ""), + SETUP_CMD("AT+CGMR", "", on_cmd_cgmr, 0U, ""), + SETUP_CMD("AT+CGSN", "", on_cmd_cgsn, 0U, ""), +#if defined(CONFIG_MODEM_SIM_NUMBERS) + SETUP_CMD("AT+CIMI", "", on_cmd_cimi, 0U, ""), + SETUP_CMD("AT+ICCID", "", on_cmd_iccid, 0U, ""), +#endif + SETUP_CMD("AT#STENG=8,8", "", NULL, 0U, ""), +}; + +static inline uint8_t *modem_get_mac(const struct device *dev) +{ + mdata.mac_addr[0] = 0x00; + mdata.mac_addr[1] = 0x10; + + sys_rand_get(&mdata.mac_addr[2], 4U); + + return mdata.mac_addr; +} + +static void ring_pin_cb(const struct device *dev, struct gpio_callback *cb, uint32_t pins) +{ + LOG_INF("RING CB"); +} + +/* Setup the Modem NET Interface. */ +static void modem_net_iface_init(struct net_if *iface) +{ + const struct device *dev = net_if_get_device(iface); + struct st87mxx_data *data = dev->data; + + net_if_set_link_addr(iface, modem_get_mac(dev), sizeof(data->mac_addr), NET_LINK_ETHERNET); + + data->netif = iface; +#ifdef CONFIG_DNS_RESOLVER + socket_offload_dns_register(&offload_dns_ops); +#endif + net_if_socket_offload_set(iface, offload_socket); +} + + +static bool offload_is_supported(int family, int type, int proto) +{ + LOG_INF("OFFLOAD IS SUPPORTED"); + + if ((family != AF_INET) && (family != AF_INET6)) { + return false; + } + + if ((type != SOCK_DGRAM) && (type != SOCK_STREAM)) { + return false; + } + + if ((proto != IPPROTO_TCP) && (proto != IPPROTO_UDP)) { + return false; + } + + return true; +} + +static int st87mxx_gpio_init(void) +{ + int ret = 0; + + if (!gpio_is_ready_dt(mdata.reset_gpio) || !gpio_is_ready_dt(mdata.ring_gpio)) { + ret = -1; + } + + /* Configure a GPO for ST87 Reset GPIO */ + if (gpio_pin_configure_dt(mdata.reset_gpio, GPIO_OUTPUT) < 0) { + ret = -1; + } + + /* Configure a GPI for ST87 ring pin */ + if (gpio_pin_configure_dt(mdata.ring_gpio, GPIO_INPUT) < 0) { + ret = -1; + } else { + if (gpio_pin_interrupt_configure_dt(mdata.ring_gpio, + GPIO_INT_EDGE_TO_ACTIVE) < 0) { + ret = -1; + } else { + gpio_init_callback(&ring_gpio_callback_data, + ring_pin_cb, BIT(mdata.ring_gpio->pin)); + gpio_add_callback(mdata.ring_gpio->port, &ring_gpio_callback_data); + } + } + + return ret; +} + +static int st87mxx_drive_reset_pin(st87mxx_reset_pin_t state) +{ + uint8_t status = 0; + int ret = 0; + + switch (state) { + case RESET_PIN_ON: + status = (uint8_t)gpio_pin_set_dt(mdata.reset_gpio, 1); + break; + + case RESET_PIN_OFF: + status = (uint8_t)gpio_pin_set_dt(mdata.reset_gpio, 0); + break; + + case RESET_PIN_PULSE: + status = (uint8_t)gpio_pin_set_dt(mdata.reset_gpio, 0); + k_msleep(15); + status += (uint8_t)gpio_pin_set_dt(mdata.reset_gpio, 1); + break; + + default: + break; + } + + if (status > 0) { + ret = -1; + } + + return ret; +} + +static int st87mxx_reset(void) +{ + uint8_t status = 0; + int ret = 0; + + /* GPIO initialization */ + status = (uint8_t)st87mxx_gpio_init(); + + /* Reset ST87 module */ + status += (uint8_t)st87mxx_drive_reset_pin(RESET_PIN_PULSE); + + k_msleep(500); /* Wait for ST87 Hw reset prior to proceeding. */ + + if (status > 0) { + ret = -1; + } + + return ret; +} + +static int st87mxx_cold_param_init(void) +{ + int ret = 0; + + struct modem_cmd cmd[] = { MODEM_CMD("#NVMRD: ", on_cmd_nvmread, 1U, "") }; + char buf[sizeof("AT#NVMRD=##,##,##")]; + + ret = snprintk(buf, sizeof(buf), "AT#NVMRD=%d,%d,1", ST87MXX_COLD_VERSION_NVM_PAGE, + ST87MXX_COLD_VERSION_NVM_OFFSET); + if (ret < 0) { + LOG_ERR("Failed to read the NVM"); + goto error; + } + ret = modem_cmd_send(&mctx.iface, &mctx.cmd_handler, cmd, ARRAY_SIZE(cmd), buf, + &mdata.sem_response, MDM_CMD_TIMEOUT); + if (ret < 0) { + LOG_ERR("Failed to send AT command: %s ret: %d", buf, ret); + goto error; + } + + /* Wait for the answer. */ + k_sem_reset(&mdata.sem_nvm); + ret = k_sem_take(&mdata.sem_nvm, MDM_CMD_TIMEOUT); + + if (mdata.cold_init_version == ST87MXX_COLD_CONFIG_VERSION) { + /* Cold config already up-to-date */ + LOG_DBG("ST87MXX NVM up-to-date"); + return 0; + } + LOG_DBG("ST87M01 NVM config version mismatch: %d, going to rewrite the config...", + mdata.cold_init_version); + + /* Run init commands on the modem. */ + ret = modem_cmd_handler_setup_cmds(&mctx.iface, &mctx.cmd_handler, + init_cmds, ARRAY_SIZE(init_cmds), + &mdata.sem_response, MDM_REGISTRATION_TIMEOUT); + if (ret < 0) { + goto error; + } + return 0; + +error: + return -1; +} + + +static int st87mxx_init(struct st87mxx_register *reg) +{ + LOG_INF("ST87MXX Init"); + int ret = 0; + uint8_t status = 0; + int counter = 0; + const char *buf = "AT+CEREG?"; + struct modem_cmd cmds[] = { MODEM_CMD("+CEREG: ", on_cmd_registration_status, 2U, ",") }; + + /* Register Data to Local mdata */ + mdata.mctx = reg->mctx; + mdata.reset_gpio = reg->reset_gpio; + mdata.ring_gpio = reg->ring_gpio; + + /* Reset of the whole system as init */ + status += (uint8_t)st87mxx_reset(); + + /* Trig cold parameter initialization sequence */ + status += (uint8_t)st87mxx_cold_param_init(); + + if (status > 0) { + ret = -1; + goto error; + } + + k_sleep(K_SECONDS(1)); + + /* wait for +CREG: 1(normal) or 5(roaming) */ + counter = 0; + while ((counter++ < MDM_MAX_CEREG_WAITS) && (mdata.mdm_registration != 1) && + (mdata.mdm_registration != 5)) { + ret = modem_cmd_send(&mctx.iface, &mctx.cmd_handler, cmds, ARRAY_SIZE(cmds), buf, + &mdata.sem_response, MDM_CMD_TIMEOUT); + if (ret < 0) { + LOG_ERR("Failed to query registration!!"); + return -1; + } + + k_sleep(K_SECONDS(1)); + } + + LOG_INF("Network registration done!"); + + if (counter >= MDM_MAX_CEREG_WAITS) { + LOG_WRN("Network registration failed!"); + ret = -1; + goto error; + } + +error: + return ret; +} + +/*Process all messages received from the modem. */ +static void modem_rx(void *p1, void *p2, void *p3) +{ + ARG_UNUSED(p1); + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + while (true) { + /* Wait for incoming data */ + modem_iface_uart_rx_wait(&mctx.iface, K_FOREVER); + + modem_cmd_handler_process(&mctx.cmd_handler, &mctx.iface); + } +} + +/* + * Initializes modem handlers and context. + * After successful init this function calls + * modem_setup. + */ +static int modem_init(const struct device *dev) +{ + int ret = 0; + + ARG_UNUSED(dev); + LOG_INF("ST87M01 modem initialization"); + + k_sem_init(&mdata.sem_response, 0, 1); + k_sem_init(&mdata.sem_dns, 0, 1); + k_sem_init(&mdata.sem_nvm, 0, 1); + + /* Assume the modem is not registered to the network. */ + mdata.mdm_registration = 0; + + mdata.current_sock_written = 0; + + /* Socket config. */ + ret = modem_socket_init(&mdata.socket_config, &mdata.sockets[0], ARRAY_SIZE(mdata.sockets), + MDM_BASE_SOCKET_NUM, true, &offload_socket_fd_op_vtable); + if (ret < 0) { + goto error; + } + + /* Command handler. */ + const struct modem_cmd_handler_config cmd_handler_config = { + .match_buf = &mdata.cmd_match_buf[0], + .match_buf_len = sizeof(mdata.cmd_match_buf), + .buf_pool = &mdm_recv_pool, + .alloc_timeout = BUF_ALLOC_TIMEOUT, + .eol = "\r\n", + .user_data = NULL, + .response_cmds = response_cmds, + .response_cmds_len = ARRAY_SIZE(response_cmds), + .unsol_cmds = unsolicited_cmds, + .unsol_cmds_len = ARRAY_SIZE(unsolicited_cmds), + }; + + ret = modem_cmd_handler_init(&mctx.cmd_handler, &mdata.cmd_handler_data, + &cmd_handler_config); + if (ret < 0) { + goto error; + } + + /* Uart handler. */ + const struct modem_iface_uart_config uart_config = { + .rx_rb_buf = &mdata.iface_rb_buf[0], + .rx_rb_buf_len = sizeof(mdata.iface_rb_buf), + .dev = MDM_UART_DEV, + .hw_flow_control = DT_PROP(MDM_UART_NODE, hw_flow_control), + }; + + ret = modem_iface_uart_init(&mctx.iface, &mdata.iface_data, &uart_config); + if (ret < 0) { + goto error; + } + + mctx.data_manufacturer = mdata.mdm_manufacturer; + mctx.data_model = mdata.mdm_model; + mctx.data_revision = mdata.mdm_revision; + mctx.data_imei = mdata.mdm_imei; +#if defined(CONFIG_MODEM_SIM_NUMBERS) + mctx.data_imsi = mdata.mdm_imsi; + mctx.data_iccid = mdata.mdm_iccid; +#endif + mctx.data_rssi = &mdata.mdm_rssi; + + mctx.driver_data = &mdata; + + ret = modem_context_register(&mctx); + if (ret < 0) { + LOG_ERR("Error registering modem context: %d", ret); + goto error; + } + + k_thread_create(&modem_rx_thread, modem_rx_stack, K_KERNEL_STACK_SIZEOF(modem_rx_stack), + modem_rx, NULL, NULL, NULL, K_PRIO_COOP(7), 0, K_NO_WAIT); + + struct st87mxx_register reg; + + reg.mctx = (struct mdm_receiver_context *)&mctx; + reg.reset_gpio = (struct gpio_dt_spec *)(&reset_gpio); + reg.ring_gpio = (struct gpio_dt_spec *)(&ring_gpio); + st87mxx_init(®); + + /* Run setup commands on the modem. */ + ret = modem_cmd_handler_setup_cmds(&mctx.iface, &mctx.cmd_handler, + setup_cmds, ARRAY_SIZE(setup_cmds), + &mdata.sem_response, MDM_REGISTRATION_TIMEOUT); + if (ret < 0) { + goto error; + } + +error: + return ret; +} + +static void socket_close(struct modem_socket *sock) +{ + int ret; + char buf[sizeof("AT#SOCKETCLOSE=##,##")]; + + ret = snprintk(buf, sizeof(buf), "AT#SOCKETCLOSE=%d,%d", mdata.context_id, sock->id); + if (ret < 0) { + LOG_ERR("Failed to close the socket %d", sock->id); + } + + ret = modem_cmd_send(&mctx.iface, &mctx.cmd_handler, NULL, 0U, buf, &mdata.sem_response, + MDM_CMD_TIMEOUT); + if (ret < 0) { + LOG_ERR("%s ret: %d", buf, ret); + } + + modem_socket_put(&mdata.socket_config, sock->sock_fd); +} + +static int st87mxx_create_socket(struct modem_socket *sock, const struct sockaddr *addr) +{ + char *protocol; + struct modem_cmd cmd[] = { MODEM_CMD("#SOCKETCREATE: ", on_cmd_socket_create, 1U, "") }; + char buf[sizeof("AT#SOCKETCREATE: #,#,###,,##,##,#")]; + char ip_str[NET_IPV6_ADDR_LEN]; + int ret = 0; + int ip_mode = -1; + + /* Get the IP version */ + if (addr->sa_family == AF_INET6) { + LOG_INF("addr->sa_family: AF_INET6"); + ip_mode = 1; + } else if (addr->sa_family == AF_INET) { + LOG_INF("addr->sa_family: AF_INET"); + ip_mode = 0; + } else { + } + + /* Get protocol */ + protocol = (sock->type == SOCK_STREAM) ? "TCP" : "UDP"; + + ret = modem_context_sprint_ip_addr(addr, ip_str, sizeof(ip_str)); + if (ret != 0) { + LOG_ERR("Failed to format IP!"); + errno = ENOMEM; + return -1; + } + + ret = snprintk(buf, sizeof(buf), "AT#SOCKETCREATE=%d,%d,%s,,%d,%d,%d", mdata.context_id, + ip_mode, protocol, SOCKET_SEND_TIMEOUT, + SOCKET_RECEIVE_TIMEOUT, SOCKET_FRAME_RECEIVED_URC); + if (ret < 0) { + LOG_ERR("Failed to build connect command. ID: %d, FD: %d", sock->id, sock->sock_fd); + errno = ENOMEM; + return -1; + } + + ret = modem_cmd_send(&mctx.iface, &mctx.cmd_handler, cmd, ARRAY_SIZE(cmd), buf, + &mdata.sem_response, MDM_CONNECT_TIMEOUT); + if (ret < 0) { + LOG_ERR("%s ret: %d", buf, ret); + socket_close(sock); + goto error; + } + + ret = modem_cmd_handler_get_error(&mdata.cmd_handler_data); + if (ret != 0) { + LOG_ERR("Closing the socket!"); + socket_close(sock); + goto error; + } + + sock->is_connected = true; + errno = 0; + return 0; +error: + errno = -ret; + return -1; + +} + +static int st87mxx_tcp_connect(struct modem_socket *sock, const struct sockaddr *addr) +{ + int ret; + uint16_t dst_port = 0; + char ip_str[NET_IPV6_ADDR_LEN]; + char send_buf[sizeof("AT#TCPCONNECT=#,#,#xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:" + "xxx.xxx.xxx.xxx#,####")] = { 0 }; + + if (sock->type == SOCK_STREAM) { + /* Get the destination port */ + if (addr->sa_family == AF_INET6) { + dst_port = ntohs(net_sin6(addr)->sin6_port); + } else if (addr->sa_family == AF_INET) { + dst_port = ntohs(net_sin(addr)->sin_port); + } else { + } + + ret = modem_context_sprint_ip_addr(addr, ip_str, sizeof(ip_str)); + if (ret != 0) { + LOG_ERR("Failed to format IP!"); + errno = ENOMEM; + return -1; + } + + ret = snprintk(send_buf, sizeof(send_buf), "AT#TCPCONNECT=%d,%d,%s,%d", + mdata.context_id, sock->id, ip_str, dst_port); + + if (ret < 0) { + LOG_ERR("Failed to build send command!!"); + errno = ENOMEM; + return -1; + } + + ret = modem_cmd_send_nolock(&mctx.iface, &mctx.cmd_handler, + NULL, 0U, send_buf, NULL, K_NO_WAIT); + + sock->is_connected = true; + + /* Wait for the OK */ + k_sem_reset(&mdata.sem_response); + ret = k_sem_take(&mdata.sem_response, MDM_CMD_TIMEOUT); + } + return 0; +} + +static int offload_socket(int family, int type, int proto) +{ + LOG_INF("OFFLOAD SOCKET"); + + int ret; + + /* Defer modem's socket create call to bind(). */ + ret = modem_socket_get(&mdata.socket_config, family, type, proto); + if (ret < 0) { + errno = -ret; + return -1; + } + + errno = 0; + return ret; +} + + +static int offload_bind(void *obj, const struct sockaddr *addr, socklen_t addrlen) +{ + LOG_INF("OFFLOAD BIND"); + struct modem_socket *sock = (struct modem_socket *)obj; + + /* Save bind address information. */ + memcpy(&sock->src, addr, sizeof(*addr)); + + /* Make sure we've created the socket. */ + if (modem_socket_is_allocated(&mdata.socket_config, sock) == true) { + if (st87mxx_create_socket(sock, addr) != 0) { + LOG_ERR("Socket creation failed"); + return -EOPNOTSUPP; + } + } + return 0; +} + +static int offload_close(void *obj) +{ + struct modem_socket *sock = (struct modem_socket *)obj; + + /* Make sure socket is allocated. */ + if (modem_socket_is_allocated(&mdata.socket_config, sock) == false) { + return 0; + } + + /* Close the socket only if it is connected. */ + if (sock->is_connected) { + socket_close(sock); + } + return 0; +} + +static int offload_ioctl(void *obj, unsigned int request, va_list args) +{ + LOG_INF("OFFLOAD IOCTL"); + + switch (request) { + case ZFD_IOCTL_POLL_PREPARE: { + + LOG_INF("OFFLOAD IOCTL 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 *); + + return modem_socket_poll_prepare(&mdata.socket_config, obj, pfd, pev, pev_end); + } + case ZFD_IOCTL_POLL_UPDATE: { + LOG_INF("OFFLOAD IOCTL 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 **); + + return modem_socket_poll_update(obj, pfd, pev); + } + + default: + errno = EINVAL; + return -1; + } +} + +static int offload_connect(void *obj, const struct sockaddr *addr, socklen_t addrlen) +{ + LOG_INF("OFFLOAD CONNECT"); + + struct modem_socket *sock = (struct modem_socket *)obj; + int ret; + + if (modem_socket_is_allocated(&mdata.socket_config, sock) == false) { + LOG_ERR("Invalid socket id %d from fd %d", sock->id, sock->sock_fd); + errno = EINVAL; + return -1; + } + + if (sock->is_connected == true) { + LOG_INF("Socket is already connected! id: %d, fd: %d", sock->id, sock->sock_fd); + } else { + if (st87mxx_create_socket(sock, addr) != 0) { + LOG_ERR("Socket creation failed"); + return -EOPNOTSUPP; + } + } + + if (sock->type == SOCK_STREAM) { + ret = (int)st87mxx_tcp_connect(sock, addr); + } + + ret = modem_cmd_handler_get_error(&mdata.cmd_handler_data); + if (ret != 0) { + LOG_ERR("Closing the socket!"); + socket_close(sock); + goto error; + } + + sock->is_connected = true; + errno = 0; + return 0; +error: + errno = -ret; + return -1; +} + +static ssize_t offload_sendto(void *obj, const void *buf, size_t len, int flags, + const struct sockaddr *dest_addr, socklen_t addrlen) +{ + LOG_INF("OFFLOAD SENDTO"); + + int ret; + struct modem_socket *sock = (struct modem_socket *)obj; + char send_buf_udp[sizeof("AT#IPSENDUDP=##,##,#xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:" + "xxx.xxx.xxx.xxx#,##,##,##,####")] = { 0 }; + char send_buf_tcp[sizeof("AT#IPSENDTCP=##,##,#,####")] = { 0 }; + char ip_str[NET_IPV6_ADDR_LEN]; + uint16_t dst_port = 0; + + /* Do some sanity checks. */ + if (!buf || len == 0) { + errno = EINVAL; + return -1; + } + + /* Socket has to be connected. */ + if (!sock->is_connected) { + errno = ENOTCONN; + return -1; + } + + /* Only send up to Maximum Transmission Unit bytes. */ + if (len > MDM_MAX_DATA_LENGTH) { + len = MDM_MAX_DATA_LENGTH; + } + + /* Make sure only one send can be done at a time. */ + k_sem_take(&mdata.cmd_handler_data.sem_tx_lock, K_FOREVER); + + switch (sock->type) { + case SOCK_STREAM: + ret = snprintk(send_buf_tcp, sizeof(send_buf_tcp), "AT#IPSENDTCP=%d,%d,1,%zu", + mdata.context_id, sock->id, len); + if (ret < 0) { + LOG_ERR("Failed to build send command!!"); + errno = ENOMEM; + return -1; + } + + ret = modem_cmd_send_nolock(&mctx.iface, &mctx.cmd_handler, + NULL, 0U, send_buf_tcp, NULL, K_NO_WAIT); + if (ret < 0) { + LOG_ERR("Failed to send AT#IPSENDTCP command!!"); + goto exit; + } + + /* Wait for the OK */ + k_sem_reset(&mdata.sem_response); + ret = k_sem_take(&mdata.sem_response, MDM_CMD_TIMEOUT); + + break; + + case SOCK_DGRAM: + + /* Get the destination port. */ + if (dest_addr->sa_family == AF_INET6) { + dst_port = ntohs(net_sin6(dest_addr)->sin6_port); + } else if (dest_addr->sa_family == AF_INET) { + dst_port = ntohs(net_sin(dest_addr)->sin_port); + } else { + } + + ret = modem_context_sprint_ip_addr(dest_addr, ip_str, sizeof(ip_str)); + if (ret != 0) { + LOG_ERR("Failed to format IP!"); + errno = ENOMEM; + return -1; + } + + ret = snprintk(send_buf_udp, sizeof(send_buf_udp), "AT#IPSENDUDP=%d,%d,%s,%d,%d,%d,%zu", + mdata.context_id, sock->id, ip_str, dst_port, 0, 1, len); + if (ret < 0) { + LOG_ERR("Failed to build send command!!"); + errno = ENOMEM; + return -1; + } + + ret = modem_cmd_send_nolock(&mctx.iface, &mctx.cmd_handler, + NULL, 0U, send_buf_udp, NULL, K_NO_WAIT); + + if (ret < 0) { + LOG_ERR("Failed to send AT#IPSENDUDP command!!"); + goto exit; + } + + /* Wait for the OK. */ + k_sem_reset(&mdata.sem_response); + ret = k_sem_take(&mdata.sem_response, MDM_CMD_TIMEOUT); + + break; + + default: + break; + } + + /* Send data */ + modem_cmd_send_data_nolock(&mctx.iface, buf, len); + + /* Wait for the OK */ + k_sem_reset(&mdata.sem_response); + ret = k_sem_take(&mdata.sem_response, MDM_CMD_TIMEOUT); + + +exit: + k_sem_give(&mdata.cmd_handler_data.sem_tx_lock); + + /* Data was successfully sent. */ + + if (ret < 0) { + errno = -ret; + return -1; + } + + errno = 0; + mdata.current_sock_written = len; + return mdata.current_sock_written; + +} + +static ssize_t offload_recvfrom(void *obj, void *buf, size_t max_len, int flags, + struct sockaddr *src_addr, socklen_t *addrlen) +{ + LOG_INF("OFFLOAD RECVFROM"); + + struct modem_socket *sock = (struct modem_socket *)obj; + char sendbuf[sizeof("AT#IPREAD=#####,####")]; + int ret, packet_size; + struct socket_read_data sock_data; + + struct modem_cmd data_cmd[] = { MODEM_CMD("#IPREAD: ", on_cmd_socket_ipread, 3U, ",") }; + + if (!buf || max_len == 0) { + errno = EINVAL; + return -1; + } + + if (flags & ZSOCK_MSG_PEEK) { + errno = ENOTSUP; + return -1; + } + + packet_size = modem_socket_next_packet_size(&mdata.socket_config, sock); + if (!packet_size) { + if (flags & ZSOCK_MSG_DONTWAIT) { + errno = EAGAIN; + return -1; + } + + modem_socket_wait_data(&mdata.socket_config, sock); + packet_size = modem_socket_next_packet_size(&mdata.socket_config, sock); + } + + max_len = (max_len > MDM_MAX_DATA_LENGTH) ? MDM_MAX_DATA_LENGTH : max_len; + snprintk(sendbuf, sizeof(sendbuf), "AT#IPREAD=%d,%d", mdata.context_id, sock->id); + + memset(&sock_data, 0, sizeof(sock_data)); + sock_data.recv_buf = buf; + sock_data.recv_buf_len = max_len + 2; /* margin */ + sock_data.recv_addr = src_addr; + sock->data = &sock_data; + + ret = modem_cmd_send(&mctx.iface, &mctx.cmd_handler, data_cmd, ARRAY_SIZE(data_cmd), + sendbuf, &mdata.sem_response, MDM_CMD_TIMEOUT); + if (ret < 0) { + errno = -ret; + ret = -1; + goto exit; + } + + /* Use dst address as src. */ + if (src_addr && addrlen) { + *addrlen = sizeof(sock->dst); + memcpy(src_addr, &sock->dst, *addrlen); + } + + errno = 0; + ret = sock_data.recv_read_len; + +exit: + /* Clear socket data. */ + sock->data = NULL; + return ret; + +} + +static ssize_t offload_sendmsg(void *obj, const struct msghdr *msg, int flags) +{ + LOG_INF("OFFLOAD SENDMSG"); + + ssize_t sent = 0; + int rc; + + LOG_DBG("msg_iovlen:%zd flags:%d", msg->msg_iovlen, flags); + + for (int i = 0; i < msg->msg_iovlen; i++) { + const char *buf = msg->msg_iov[i].iov_base; + size_t len = msg->msg_iov[i].iov_len; + + while (len > 0) { + rc = offload_sendto(obj, buf, len, flags, + msg->msg_name, msg->msg_namelen); + if (rc < 0) { + if (rc == -EAGAIN) { + k_sleep(MDM_SENDMSG_SLEEP); + } else { + sent = rc; + break; + } + } else { + sent += rc; + buf += rc; + len -= rc; + } + } + } + + return (ssize_t) sent; +} + +static ssize_t offload_read(void *obj, void *buffer, size_t count) +{ + return offload_recvfrom(obj, buffer, count, 0, NULL, 0); +} + +static ssize_t offload_write(void *obj, const void *buffer, size_t count) +{ + return offload_sendto(obj, buffer, count, 0, NULL, 0); +} + +#if defined(CONFIG_DNS_RESOLVER) +static int offload_getaddrinfo(const char *node, const char *service, + const struct zsock_addrinfo *hints, struct zsock_addrinfo **res) +{ + LOG_INF("OFFLOAD GETADDRINFO"); + + struct modem_cmd cmd[] = { MODEM_CMD("#DNS: ", on_cmd_dns, 2U, ",") }; + /* DNS command + 128 bytes for domain name parameter */ + char sendbuf[sizeof("AT#DNS=#,#,'[]'")+128]; + uint32_t port = 0; + int ret; + + /* Init result */ + (void)memset(&dns_result, 0, sizeof(dns_result)); + (void)memset(&dns_result_addr, 0, sizeof(dns_result_addr)); + + /* Currently only supports IPv4. */ + dns_result.ai_family = AF_INET; + dns_result_addr.sa_family = AF_INET; + dns_result.ai_addr = &dns_result_addr; + dns_result.ai_addrlen = sizeof(dns_result_addr); + dns_result.ai_canonname = dns_result_canonname; + dns_result_canonname[0] = '\0'; + + if (service) { + port = atoi(service); + if (port < 1 || port > USHRT_MAX) { + return DNS_EAI_SERVICE; + } + } + + if (port > 0U) { + if (dns_result.ai_family == AF_INET) { + net_sin(&dns_result_addr)->sin_port = htons(port); + } + } + + /* Check if node is an IP address. */ + if (net_addr_pton(dns_result.ai_family, node, + &((struct sockaddr_in *)&dns_result_addr)->sin_addr) == 0) { + *res = &dns_result; + return 0; + } + + /* User flagged node as numeric host, but we failed net_addr_pton. */ + if (hints && hints->ai_flags & AI_NUMERICHOST) { + return DNS_EAI_NONAME; + } + + /* Send dummy AT command to wake the modem up in case it is sleeping. */ + snprintk(sendbuf, sizeof(sendbuf), "AT"); + ret = modem_cmd_send_nolock(&mctx.iface, &mctx.cmd_handler, + NULL, 0U, sendbuf, NULL, K_NO_WAIT); + + /* Wait for the OK. */ + k_sem_reset(&mdata.sem_response); + ret = k_sem_take(&mdata.sem_response, MDM_CMD_TIMEOUT); + + k_sem_reset(&mdata.sem_response); + + snprintk(sendbuf, sizeof(sendbuf), "AT#DNS=%d,0,%s", mdata.context_id, node); + ret = modem_cmd_send(&mctx.iface, &mctx.cmd_handler, cmd, ARRAY_SIZE(cmd), sendbuf, + &mdata.sem_response, MDM_CMD_TIMEOUT); + + *res = (struct zsock_addrinfo *)&dns_result; + return 0; +} + +static void offload_freeaddrinfo(struct zsock_addrinfo *res) +{ + /* No need to free static memory. */ + ARG_UNUSED(res); +} +#endif + + +#if defined(CONFIG_DNS_RESOLVER) +static const struct socket_dns_offload offload_dns_ops = { + .getaddrinfo = offload_getaddrinfo, + .freeaddrinfo = offload_freeaddrinfo, +}; +#endif + +static struct offloaded_if_api api_funcs = { + .iface_api.init = modem_net_iface_init, +}; + +static const struct socket_op_vtable offload_socket_fd_op_vtable = { + .fd_vtable = { + .read = offload_read, + .write = offload_write, + .close = offload_close, + .ioctl = offload_ioctl, + }, + .bind = offload_bind, + .connect = offload_connect, + .sendto = offload_sendto, + .recvfrom = offload_recvfrom, + .listen = NULL, + .accept = NULL, + .sendmsg = offload_sendmsg, + .getsockopt = NULL, + .setsockopt = NULL, +}; + +/* Register device with the networking stack. */ +NET_DEVICE_DT_INST_OFFLOAD_DEFINE(0, modem_init, NULL, &mdata, NULL, + CONFIG_MODEM_ST87MXX_INIT_PRIORITY, &api_funcs, + CONFIG_MODEM_ST87MXX_MAX_RX_DATA_LENGTH); + +NET_SOCKET_OFFLOAD_REGISTER(st87mxx, CONFIG_NET_SOCKETS_OFFLOAD_PRIORITY, + AF_UNSPEC, offload_is_supported, offload_socket); diff --git a/drivers/modem/st87mxx.h b/drivers/modem/st87mxx.h new file mode 100644 index 000000000000..1c2d73f2adc7 --- /dev/null +++ b/drivers/modem/st87mxx.h @@ -0,0 +1,217 @@ +/* Copyright (c) 2025 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef STM87MXX_H +#define STM87MXX_H + +#include +#include +#include +#include +#include +#include + +#include "modem_context.h" +#include "modem_socket.h" +#include "modem_cmd_handler.h" +#include "modem_iface_uart.h" + +#define MDM_CMD_TIMEOUT K_SECONDS(10) +#define MDM_DNS_TIMEOUT K_SECONDS(210) +#define MDM_REGISTRATION_TIMEOUT K_SECONDS(180) +#define MDM_AT_CMD_WAKEUP_TIMEOUT 5000 +#define MDM_RECV_MAX_BUF 30 +#define MDM_RECV_BUF_SIZE 1024 +#define MDM_WAIT_FOR_DATA_RETRIES 3 +#define MDM_MAX_CEREG_WAITS 40 +#define MDM_CONNECT_TIMEOUT K_SECONDS(90) +#define MDM_SENDMSG_SLEEP K_MSEC(1) + +#define SOCKET_SEND_TIMEOUT 10 +#define SOCKET_RECEIVE_TIMEOUT 10 +#define SOCKET_FRAME_RECEIVED_URC 1 + +#define BUF_ALLOC_TIMEOUT K_SECONDS(1) + +#define MDM_MAX_SOCKETS 3 +#define NO_TAG_CMD_MAX_LENGTH 32 + +/* + * Default length of modem data. + */ +#define MDM_MANUFACTURER_LENGTH 18 +#define MDM_MODEL_LENGTH 16 +#define MDM_REVISION_LENGTH 64 +#define MDM_IMEI_LENGTH 16 +#define MDM_IMSI_LENGTH 16 +#define MDM_ICCID_LENGTH 32 +#define MDM_RSSI_LENGTH 32 + +#define MDM_UART_NODE DT_INST_BUS(0) +#define MDM_UART_DEV DEVICE_DT_GET(MDM_UART_NODE) + +#define MDM_MAX_DATA_LENGTH 1024 + +#define ST87MXX_COLD_CONFIG_VERSION 0 + +#define ST87MXX_COLD_VERSION_INDEX 8 +#define ST87MXX_COLD_VERSION_NVM_PAGE 5 +#define ST87MXX_COLD_VERSION_NVM_OFFSET 12 + + +/*******ST87MXX NVM config parameters: user modifiable *******/ +/* Temperature limit */ +/* + * Signed integer type Temperature low threshold + * in Celsius degree for shutdown display and shutdown + */ +#define TEMP_LOW_SHUTDOWN -45 +/* + * Signed integer type Temperature high threshold + * in Celsius degree for shutdown display and shutdown + */ +#define TEMP_HIGH_SHUTDONW 110 +/* + * Integer type 0: Disable shutdown if the shutdown threshold is reached + * 1: Enable shutdown if the shutdown threshold is reached + */ +#define TEMP_SHUTDOWN 1 + +/* Battery level settings */ +/* Integer type Low battery threshold in mV for shutdown display and shutdown */ +#define VBAT_LOW_SHUTDOWN 2000 +/* Integer type High battery threshold in mV for shutdown display and shutdown */ +#define VBAT_HIGH_SHUTDOWN 3200 +/* + * Integer type 0: Disable shutdown if the shutdown threshold is reached + * 1: Enable shutdown if the shutdown threshold is reached + */ +#define VBAT_SHUTDOWN 1 + +/****************************** NBIOT configuration ****************************/ +/* Band selection : configure the band usage and split between various NMO */ +#define BANDLIST "20,8" /* Band selected comma separated */ +#define BANDCFG "0,0,20,01,7910" /* Band=20, Option=01, StartFreq=7910 */ +#define BANDCFG_NMO1 "0,1,0,2,1,100,0" /* Pref=0, Guard=2, In=1, BW=100, OffsetFreq=0 */ +#define BANDCFG_NMO2 "0,2,0,2,1,100,100" /* Pref=0, Guard=2, In=1, BW=100, OffsetFreq=100 */ +#define BANDCFG_NMO3 "0,3,0,2,1,100,200" /* Pref=0, Guard=2, In=1, BW=100, OffsetFreq=200 */ + +/* EDRX Setting */ +/* Requested EDRX value "1011" -> 655.36s See 3GPP 24.008 Table 10.5.5.32 */ +#define EDRX_VALUE 1011 + +/* Paging Time Window*/ +/* PTW value "0011" -> 10.24s See 3GPP TS 24.008 Table 10.5.5.32 */ +#define PTW_VALUE 0011 + +/* Power saving mode setting */ +#define PSM_ENABLE 1 +/* + * TAU value (T3412) "00100001" -> 1H See 3GPP TS 24.008 Table 10.5.5.32 + * TAU value (T3412) "00111000" -> 24H See 3GPP TS 24.008 Table 10.5.5.32 + */ +#define PERIODIC_TAU "00100001" +/* Active time (T3324) "00000101" */ +#define ACTIVE_TIME "00000101" + +/* IP configuration */ +/* + * Activation of the counting of the number of UDP packets actually received + * and acknowledged by the eNodeB. + * However, it does not guarantee that the packet has been received by the remote server. + * If NB_PACKET_SENT is 1, counting is active. + * If NB_PACKET_SENT is 0, counting is inactive. + * NbUdpPacketsSent counter var in EC Lib State structure (ST87EC_Lib_Status_t) + * keeps 0 value. + */ +#define NB_PACKET_SENT_ENABLE 1 +#define DOMAIN_NAME "8.8.8.8" /* IP address for DNS resolution */ + +/****************************** ST87 configuration ****************************/ +/* Sleep mode configuration */ +/* Integer type Time in seconds between the last AT command and the sleep mode entry */ +#define HOLD_TIME 10 +/* + * Integer type Define the timeout in seconds that the module is awake at each wake up + * (telecom activity, AT command activity..) + */ +#define AWAKE_TIME 0 + +/*Parameters to be configured for Ring pin setup*/ +/* Ring pin enable */ +#define RING_PIN_ENABLE 0 +/* Ring pin number to be set for ST87M01. The GPIO number between 8 and 31 */ +#define RING_PIN_GPIO 10 +/* Ring pin voltage polarity (0: active low and 1: active high) */ +#define RING_PIN_POLARITY 1 +/* Time in ms when ring pin is active (min: 10ms and max:300ms by 10ms steps) */ +#define RING_PIN_DELAY 200 + +/* Types ---------------------------------------------------------------------*/ + +struct st87mxx_data { + /* + * Network interface of the sim module. + */ + struct net_if *netif; + uint8_t mac_addr[6]; + + uint8_t context_id; + /* + * Uart interface of the modem. + */ + struct modem_iface_uart_data iface_data; + uint8_t iface_rb_buf[MDM_MAX_DATA_LENGTH]; + + /* + * Modem command handler. + */ + struct modem_cmd_handler_data cmd_handler_data; + uint8_t cmd_match_buf[MDM_RECV_BUF_SIZE + 1]; + + /* + * Modem socket data. + */ + struct modem_socket_config socket_config; + struct modem_socket sockets[MDM_MAX_SOCKETS]; + + int current_sock_written; + + struct mdm_receiver_context *mctx; + struct gpio_dt_spec *reset_gpio; + struct gpio_dt_spec *ring_gpio; + + uint8_t cold_init_version; + + char mdm_imei[MDM_IMEI_LENGTH]; + char mdm_manufacturer[MDM_MANUFACTURER_LENGTH+1]; + char mdm_model[MDM_MODEL_LENGTH]; +#if defined(CONFIG_MODEM_SIM_NUMBERS) + char mdm_iccid[MDM_ICCID_LENGTH]; + char mdm_imsi[MDM_IMSI_LENGTH]; +#endif + char mdm_revision[MDM_REVISION_LENGTH]; + int mdm_rssi; + uint8_t mdm_registration; + + /* + * Semaphore(s). + */ + struct k_sem sem_response; + struct k_sem sem_dns; + struct k_sem sem_nvm; +}; + +/* + * Socket read callback data. + */ +struct socket_read_data { + char *recv_buf; + size_t recv_buf_len; + struct sockaddr *recv_addr; + uint16_t recv_read_len; +}; + +#endif From d6e3b498374fcbe277285066a724048a033869a3 Mon Sep 17 00:00:00 2001 From: Isabelle OGER Date: Tue, 2 Dec 2025 15:13:42 +0100 Subject: [PATCH 1935/3659] dts: bindings: add support for STMicroelectronics ST87M01 module. Add support for the STMicroelectronics ultra-compact low-power NB-IoT industrial ST87M01 module. Signed-off-by: Isabelle OGER --- dts/bindings/modem/st,st87mxx.yaml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 dts/bindings/modem/st,st87mxx.yaml diff --git a/dts/bindings/modem/st,st87mxx.yaml b/dts/bindings/modem/st,st87mxx.yaml new file mode 100644 index 000000000000..86f629b830b2 --- /dev/null +++ b/dts/bindings/modem/st,st87mxx.yaml @@ -0,0 +1,19 @@ +# Copyright (c) 2025 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +description: ST87MXX NBIoT modem + +compatible: "st,st87mxx" + +include: uart-device.yaml + +properties: + mdm-reset-gpios: + type: phandle-array + required: true + description: GPIO for modem reset + + mdm-ring-gpios: + type: phandle-array + required: true + description: GPIO for modem wake From 69a826c7f5ba46a45f667dd8726f49a663d69122 Mon Sep 17 00:00:00 2001 From: Isabelle OGER Date: Tue, 2 Dec 2025 15:17:07 +0100 Subject: [PATCH 1936/3659] tests: drivers: build_all: add support for ST87M01 module. Add support for the STMicroelectronics ultra-compact low-power NB-IoT industrial ST87M01 module. Signed-off-by: Isabelle OGER --- tests/drivers/build_all/modem/modem_st87mxx.conf | 5 +++++ tests/drivers/build_all/modem/testcase.yaml | 8 ++++++++ tests/drivers/build_all/modem/uart.dtsi | 7 +++++++ 3 files changed, 20 insertions(+) create mode 100644 tests/drivers/build_all/modem/modem_st87mxx.conf diff --git a/tests/drivers/build_all/modem/modem_st87mxx.conf b/tests/drivers/build_all/modem/modem_st87mxx.conf new file mode 100644 index 000000000000..8e6cd5fcafbd --- /dev/null +++ b/tests/drivers/build_all/modem/modem_st87mxx.conf @@ -0,0 +1,5 @@ +CONFIG_GPIO=y +CONFIG_SERIAL=y +CONFIG_MODEM=y +CONFIG_NETWORKING=y +CONFIG_NET_SOCKETS=y diff --git a/tests/drivers/build_all/modem/testcase.yaml b/tests/drivers/build_all/modem/testcase.yaml index 9716d83bea44..7f4137883742 100644 --- a/tests/drivers/build_all/modem/testcase.yaml +++ b/tests/drivers/build_all/modem/testcase.yaml @@ -57,3 +57,11 @@ tests: extra_args: CONF_FILE=modem_simcom_sim7080.conf extra_configs: - CONFIG_UART_ASYNC_API=y + drivers.modem.modem_st87mxx.interrupt_driven.build: + extra_args: CONF_FILE=modem_st87mxx.conf + extra_configs: + - CONFIG_UART_INTERRUPT_DRIVEN=y + drivers.modem.modem_st87mxx.async.build: + extra_args: CONF_FILE=modem_st87mxx.conf + extra_configs: + - CONFIG_UART_ASYNC_API=y diff --git a/tests/drivers/build_all/modem/uart.dtsi b/tests/drivers/build_all/modem/uart.dtsi index 2f333c19d975..78dc82140e50 100644 --- a/tests/drivers/build_all/modem/uart.dtsi +++ b/tests/drivers/build_all/modem/uart.dtsi @@ -78,3 +78,10 @@ test_sqn_gm02s: sqn_gm02s { mdm-reset-gpios = <&test_gpio 0 0>; }; + +test_st_st87mxx: st87mxx { + compatible = "st,st87mxx"; + + mdm-reset-gpios = <&test_gpio 0 0>; + mdm-ring-gpios = <&test_gpio 0 0>; +}; From a2a14b548ede92f87bd409f4ca612acb8cd67968 Mon Sep 17 00:00:00 2001 From: Isabelle OGER Date: Tue, 2 Dec 2025 14:44:24 +0100 Subject: [PATCH 1937/3659] boards: shields: add support for ST87M01 module. Add support for the STMicroelectronics ultra-compact low-power NB-IoT industrial ST87M01 module. Signed-off-by: Isabelle OGER --- boards/shields/st87mxx/Kconfig.defconfig | 26 ++++++++ boards/shields/st87mxx/Kconfig.shield | 5 ++ .../shields/st87mxx/doc/EVKITST87M01-1.webp | Bin 0 -> 58210 bytes boards/shields/st87mxx/doc/index.rst | 63 ++++++++++++++++++ boards/shields/st87mxx/shield.yml | 6 ++ boards/shields/st87mxx/st87mxx.overlay | 17 +++++ 6 files changed, 117 insertions(+) create mode 100644 boards/shields/st87mxx/Kconfig.defconfig create mode 100644 boards/shields/st87mxx/Kconfig.shield create mode 100644 boards/shields/st87mxx/doc/EVKITST87M01-1.webp create mode 100644 boards/shields/st87mxx/doc/index.rst create mode 100644 boards/shields/st87mxx/shield.yml create mode 100644 boards/shields/st87mxx/st87mxx.overlay diff --git a/boards/shields/st87mxx/Kconfig.defconfig b/boards/shields/st87mxx/Kconfig.defconfig new file mode 100644 index 000000000000..bb457c240aeb --- /dev/null +++ b/boards/shields/st87mxx/Kconfig.defconfig @@ -0,0 +1,26 @@ +# Copyright (c) 2025 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +if SHIELD_ST87MXX + +if NETWORKING + +config MODEM + default y + +config UART_INTERRUPT_DRIVEN + default y + +config MODEM_SHELL + default y + +config MODEM_ST87MXX + default y + +# extend retry timing to 20 seconds for LTE/LTE-M +config COAP_INIT_ACK_TIMEOUT_MS + default 20000 + +endif # NETWORKING + +endif # SHIELD_ST87MXX diff --git a/boards/shields/st87mxx/Kconfig.shield b/boards/shields/st87mxx/Kconfig.shield new file mode 100644 index 000000000000..e5c2ba3b2cfd --- /dev/null +++ b/boards/shields/st87mxx/Kconfig.shield @@ -0,0 +1,5 @@ +# Copyright (c) 2025 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +config SHIELD_ST87MXX + def_bool $(shields_list_contains,shield_st87mxx) diff --git a/boards/shields/st87mxx/doc/EVKITST87M01-1.webp b/boards/shields/st87mxx/doc/EVKITST87M01-1.webp new file mode 100644 index 0000000000000000000000000000000000000000..2bd710cdfb5797388b15df0bc71f987e336f6952 GIT binary patch literal 58210 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�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 literal 0 HcmV?d00001 diff --git a/boards/shields/st87mxx/doc/index.rst b/boards/shields/st87mxx/doc/index.rst new file mode 100644 index 000000000000..4654869c0744 --- /dev/null +++ b/boards/shields/st87mxx/doc/index.rst @@ -0,0 +1,63 @@ +.. _st87mxx_generic: + +ST87MXX shield +############## + +Overview +******** + +The ST87M01 is a high-performance, fully programmable, ultra-compact, +and low-power LTE Cat NB2 NB-IoT industrial module series, offering +comprehensive worldwide band coverage and advanced security features. + +.. figure:: EVKITST87M01-1.webp + :align: center + :alt: ST87M01 module on EVKITST87M01-1 board + +Pins Assignment of the ST87MXX Shield +====================================== + ++-----------------------+------------------------+ +| K207 Connector Pin | Function | ++=======================+========================+ +| 1 | MODEM_WAKE-UP | ++-----------------------+------------------------+ +| 2 | MODEM_RESET | ++-----------------------+------------------------+ +| 7 | GND | ++-----------------------+------------------------+ + ++-----------------------+------------------------+ +| K208 Connector Pin | Function | ++=======================+========================+ +| 4 | 3V3 | ++-----------------------+------------------------+ +| 5 | 5V0 | ++-----------------------+------------------------+ +| 6 | GND | ++-----------------------+------------------------+ +| 7 | GND | ++-----------------------+------------------------+ + ++-----------------------+------------------------+ +| K209 Connector Pin | Function | ++=======================+========================+ +| 1 | UART_RXD | ++-----------------------+------------------------+ +| 2 | UART_TXD | ++-----------------------+------------------------+ + + +Requirements +************ + +This shield can only be used with a board that provides a configuration +for Arduino connectors and defines node aliases for UART and GPIO interfaces. + +References +********** + +.. target-notes:: + +.. _ST87MXX: + https://www.st.com/en/wireless-connectivity/st87m01.html diff --git a/boards/shields/st87mxx/shield.yml b/boards/shields/st87mxx/shield.yml new file mode 100644 index 000000000000..c012f84f53ae --- /dev/null +++ b/boards/shields/st87mxx/shield.yml @@ -0,0 +1,6 @@ +shield: + name: st87mxx + full_name: ST87MXX module + vendor: st + supported_features: + - modem diff --git a/boards/shields/st87mxx/st87mxx.overlay b/boards/shields/st87mxx/st87mxx.overlay new file mode 100644 index 000000000000..be38157168bb --- /dev/null +++ b/boards/shields/st87mxx/st87mxx.overlay @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2025 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&arduino_serial { + current-speed = <115200>; + status = "okay"; + + st_87mxx: modem { + compatible = "st,st87mxx"; + mdm-reset-gpios = <&arduino_header 15 0>; + mdm-ring-gpios = <&arduino_header 14 0>; + status = "okay"; + }; +}; From 334f5726b478da8635448eb0e7acfe849262b19f Mon Sep 17 00:00:00 2001 From: Yves Wang Date: Fri, 19 Dec 2025 17:05:17 +0800 Subject: [PATCH 1938/3659] soc: nxp: unify DISABLE_WDOG condition Aligh the macro to determine DISABLE_WDOG definition for nxp devices. Signed-off-by: Yves Wang --- soc/nxp/mcx/mcxe/mcxe24x/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/soc/nxp/mcx/mcxe/mcxe24x/CMakeLists.txt b/soc/nxp/mcx/mcxe/mcxe24x/CMakeLists.txt index e01a54ecc0ab..8c3dcf192280 100644 --- a/soc/nxp/mcx/mcxe/mcxe24x/CMakeLists.txt +++ b/soc/nxp/mcx/mcxe/mcxe24x/CMakeLists.txt @@ -18,4 +18,4 @@ zephyr_linker_sources_ifdef(CONFIG_MCXE_FLASH_CONFIG # CMSIS SystemInit will disable watchdog unless instructed not to. # Add a compiler definition here to leave watchdog untouched # if this Kconfig is set -zephyr_compile_definitions_ifdef(CONFIG_WDOG_ENABLE_AT_BOOT DISABLE_WDOG=0) +zephyr_compile_definitions_ifndef(CONFIG_WDT_DISABLE_AT_BOOT DISABLE_WDOG=0) From 0b30562497d7f649365d0f0aad3c130614bdd1c3 Mon Sep 17 00:00:00 2001 From: Chay Guo Date: Fri, 26 Dec 2025 10:31:53 +0800 Subject: [PATCH 1939/3659] doc: boards: mimxrt700_evk: fix build command for display - Fix the build command for display samples. Signed-off-by: Chay Guo --- boards/nxp/mimxrt700_evk/doc/index.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/boards/nxp/mimxrt700_evk/doc/index.rst b/boards/nxp/mimxrt700_evk/doc/index.rst index 65303b10f6ca..510c68496cad 100644 --- a/boards/nxp/mimxrt700_evk/doc/index.rst +++ b/boards/nxp/mimxrt700_evk/doc/index.rst @@ -252,7 +252,7 @@ directly, but some modifications are required (see for a list). The display sample can be built for this module like so: .. zephyr-app-commands:: - :board: mimxrt700_evk + :board: mimxrt700_evk/mimxrt798s/cm33_cpu0 :shield: g1120b0mipi :zephyr-app: samples/drivers/display :goals: build @@ -269,7 +269,7 @@ region must be used, which needs to connect JP45 1-2. The display sample can be module like so: .. zephyr-app-commands:: - :board: mimxrt700_evk + :board: mimxrt700_evk/mimxrt798s/cm33_cpu0 :shield: rk055hdmipi4ma0 :zephyr-app: samples/drivers/display :goals: build @@ -284,7 +284,7 @@ directly, but some modifications are required (see for a list). The display sample can be built for this module like so: .. zephyr-app-commands:: - :board: mimxrt700_evk + :board: mimxrt700_evk/mimxrt798s/cm33_cpu0 :shield: zc143ac72mipi :zephyr-app: samples/drivers/display :goals: build From eac5cfa0e42685153f320da254dc4b6885bf9071 Mon Sep 17 00:00:00 2001 From: Neil Chen Date: Mon, 29 Dec 2025 16:37:47 +0800 Subject: [PATCH 1940/3659] boards: nxp: frdm_mcxn947,mcx_n9xx_evk: Update doc Update frdm_mcxn947,mcx_n9xx_evk boards' Datasheet and Reference manual link Signed-off-by: Neil Chen --- boards/nxp/frdm_mcxn947/doc/index.rst | 4 ++-- boards/nxp/mcx_nx4x_evk/doc/mcx_n9xx_evk.rst | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/boards/nxp/frdm_mcxn947/doc/index.rst b/boards/nxp/frdm_mcxn947/doc/index.rst index 6efce05fde43..f7d2a9088f14 100644 --- a/boards/nxp/frdm_mcxn947/doc/index.rst +++ b/boards/nxp/frdm_mcxn947/doc/index.rst @@ -369,10 +369,10 @@ Troubleshooting https://www.nxp.com/products/processors-and-microcontrollers/arm-microcontrollers/general-purpose-mcus/mcx-arm-cortex-m/mcx-n-series-microcontrollers/mcx-n94x-54x-highly-integrated-multicore-mcus-with-on-chip-accelerators-intelligent-peripherals-and-advanced-security:MCX-N94X-N54X .. _MCX-N947 Datasheet: - https://www.nxp.com/docs/en/data-sheet/MCXNx4xDS.pdf + https://www.nxp.com/docs/en/data-sheet/MCXNP184M150F70.pdf .. _MCX-N947 Reference Manual: - https://www.nxp.com/webapp/Download?colCode=MCXNX4XRM + https://www.nxp.com/webapp/Download?colCode=MCXNP184M150F70RM .. _FRDM-MCXN947 Website: https://www.nxp.com/design/design-center/development-boards/general-purpose-mcus/frdm-development-board-for-mcx-n94-n54-mcus:FRDM-MCXN947 diff --git a/boards/nxp/mcx_nx4x_evk/doc/mcx_n9xx_evk.rst b/boards/nxp/mcx_nx4x_evk/doc/mcx_n9xx_evk.rst index c266108fd7c7..1f0872f01347 100644 --- a/boards/nxp/mcx_nx4x_evk/doc/mcx_n9xx_evk.rst +++ b/boards/nxp/mcx_nx4x_evk/doc/mcx_n9xx_evk.rst @@ -362,10 +362,10 @@ Troubleshooting https://www.nxp.com/products/processors-and-microcontrollers/arm-microcontrollers/general-purpose-mcus/mcx-arm-cortex-m/mcx-n-series-microcontrollers/mcx-n94x-54x-highly-integrated-multicore-mcus-with-on-chip-accelerators-intelligent-peripherals-and-advanced-security:MCX-N94X-N54X .. _MCX-N947 Datasheet: - https://www.nxp.com/docs/en/data-sheet/MCXNx4xDS.pdf + https://www.nxp.com/docs/en/data-sheet/MCXNP184M150F70.pdf .. _MCX-N947 Reference Manual: - https://www.nxp.com/webapp/Download?colCode=MCXNX4XRM + https://www.nxp.com/webapp/Download?colCode=MCXNP184M150F70RM .. _MCX-N9XX-EVK Website: https://www.nxp.com/design/design-center/development-boards-and-designs/MCX-N9XX-EVK From 051940789d3776bd0222ba50531bea08444f0092 Mon Sep 17 00:00:00 2001 From: Derek Snell Date: Wed, 7 Jan 2026 17:47:49 -0500 Subject: [PATCH 1941/3659] boards: nxp: mimxrt1040_evk: enable Ethernet Tested with samples dhcpv4_client and http_server. Signed-off-by: Derek Snell --- boards/nxp/mimxrt1040_evk/Kconfig.defconfig | 3 ++ .../mimxrt1040_evk-pinctrl.dtsi | 49 +++++++++++++++++++ boards/nxp/mimxrt1040_evk/mimxrt1040_evk.dts | 29 +++++++++++ boards/nxp/mimxrt1040_evk/mimxrt1040_evk.yaml | 1 + 4 files changed, 82 insertions(+) diff --git a/boards/nxp/mimxrt1040_evk/Kconfig.defconfig b/boards/nxp/mimxrt1040_evk/Kconfig.defconfig index 87cdb61799a5..f53272558695 100644 --- a/boards/nxp/mimxrt1040_evk/Kconfig.defconfig +++ b/boards/nxp/mimxrt1040_evk/Kconfig.defconfig @@ -9,4 +9,7 @@ config DEVICE_CONFIGURATION_DATA config NXP_IMX_EXTERNAL_SDRAM default y +configdefault NET_L2_ETHERNET + default y if DT_HAS_NXP_ENET_ENABLED + endif # BOARD_MIMXRT1040_EVK diff --git a/boards/nxp/mimxrt1040_evk/mimxrt1040_evk-pinctrl.dtsi b/boards/nxp/mimxrt1040_evk/mimxrt1040_evk-pinctrl.dtsi index ef34bea94090..aec855de37e3 100644 --- a/boards/nxp/mimxrt1040_evk/mimxrt1040_evk-pinctrl.dtsi +++ b/boards/nxp/mimxrt1040_evk/mimxrt1040_evk-pinctrl.dtsi @@ -20,6 +20,55 @@ }; }; + pinmux_enet: pinmux_enet { + group0 { + pinmux = <&iomuxc_gpio_b1_10_enet_ref_clk>; + bias-disable; + drive-strength = "r0-6"; + slew-rate = "fast"; + nxp,speed = "50-mhz"; + input-enable; + }; + + group1 { + pinmux = <&iomuxc_gpio_b1_04_enet_rx_data0>, + <&iomuxc_gpio_b1_05_enet_rx_data1>, + <&iomuxc_gpio_b1_06_enet_rx_en>, + <&iomuxc_gpio_b1_07_enet_tx_data0>, + <&iomuxc_gpio_b1_08_enet_tx_data1>, + <&iomuxc_gpio_b1_09_enet_tx_en>, + <&iomuxc_gpio_b1_11_enet_rx_er>; + drive-strength = "r0-5"; + bias-pull-up; + bias-pull-up-value = "100k"; + slew-rate = "fast"; + nxp,speed = "200-mhz"; + }; + }; + + pinmux_enet_mdio: pinmux_enet_mdio { + group0 { + pinmux = <&iomuxc_gpio_emc_40_enet_mdc>, + <&iomuxc_gpio_emc_41_enet_mdio>, + <&iomuxc_gpio_sd_b1_04_gpio3_io04>; + drive-strength = "r0-5"; + bias-pull-up; + bias-pull-up-value = "100k"; + slew-rate = "fast"; + nxp,speed = "200-mhz"; + }; + }; + + pinmux_ptp: pinmux_ptp { + group0 { + pinmux = <&iomuxc_gpio_ad_b1_02_enet_1588_event2_out>, + <&iomuxc_gpio_ad_b1_03_enet_1588_event2_in>; + drive-strength = "r0-6"; + slew-rate = "slow"; + nxp,speed = "100-mhz"; + }; + }; + /* Route PWM1 A3 to J16, pin 6 on arduino header */ pinmux_flexpwm1_pwm3: pinmux_flexpwm1_pwm3 { group0 { diff --git a/boards/nxp/mimxrt1040_evk/mimxrt1040_evk.dts b/boards/nxp/mimxrt1040_evk/mimxrt1040_evk.dts index 78b8ca72c24e..65ef8de0b79d 100644 --- a/boards/nxp/mimxrt1040_evk/mimxrt1040_evk.dts +++ b/boards/nxp/mimxrt1040_evk/mimxrt1040_evk.dts @@ -173,6 +173,35 @@ pinctrl-names = "default", "sleep"; }; +&enet_mac { + status = "okay"; + pinctrl-0 = <&pinmux_enet>; + pinctrl-names = "default"; + phy-handle = <&phy>; + zephyr,random-mac-address; + phy-connection-type = "rmii"; +}; + +&enet_mdio { + status = "okay"; + pinctrl-0 = <&pinmux_enet_mdio>; + pinctrl-names = "default"; + + phy: phy@0 { + compatible = "microchip,ksz8081"; + reg = <0>; + status = "okay"; + reset-gpios = <&gpio3 4 GPIO_ACTIVE_LOW>; + microchip,interface-type = "rmii"; + }; +}; + +&enet_ptp_clock { + status = "okay"; + pinctrl-0 = <&pinmux_ptp>; + pinctrl-names = "default"; +}; + &flexpwm1_pwm3 { status = "okay"; pinctrl-0 = <&pinmux_flexpwm1_pwm3>; diff --git a/boards/nxp/mimxrt1040_evk/mimxrt1040_evk.yaml b/boards/nxp/mimxrt1040_evk/mimxrt1040_evk.yaml index de7742a9c13c..1af828c609fb 100644 --- a/boards/nxp/mimxrt1040_evk/mimxrt1040_evk.yaml +++ b/boards/nxp/mimxrt1040_evk/mimxrt1040_evk.yaml @@ -20,6 +20,7 @@ supported: - flash - gpio - i2c + - netif:eth - pwm - spi - rtc From c4f1ccb9607a217fa8abc13db270a1cf54eb561c Mon Sep 17 00:00:00 2001 From: TOKITA Hiroshi Date: Mon, 12 Jan 2026 17:22:18 +0900 Subject: [PATCH 1942/3659] boards: qnx: Add support for QNX Hypervisor virtual machine Adding support for running Zephyr OS as a guest virtual machine in the QNX Hypervisor environment. This change introduces a new board configuration for ARM64-based QNX Hypervisor VM. Signed-off-by: TOKITA Hiroshi --- boards/blackberry/index.rst | 10 ++ boards/blackberry/qnxhv_vm/Kconfig.qnxhv_vm | 5 + boards/blackberry/qnxhv_vm/board.yml | 6 + boards/blackberry/qnxhv_vm/doc/index.rst | 105 ++++++++++++++++++ boards/blackberry/qnxhv_vm/qnxhv_vm.dts | 85 ++++++++++++++ boards/blackberry/qnxhv_vm/qnxhv_vm.yaml | 9 ++ boards/blackberry/qnxhv_vm/qnxhv_vm_defconfig | 7 ++ dts/bindings/vendor-prefixes.txt | 1 + soc/blackberry/qnxhv_vm/CMakeLists.txt | 6 + soc/blackberry/qnxhv_vm/Kconfig | 7 ++ soc/blackberry/qnxhv_vm/Kconfig.defconfig | 14 +++ soc/blackberry/qnxhv_vm/Kconfig.soc | 8 ++ soc/blackberry/qnxhv_vm/mmu_regions.c | 27 +++++ soc/blackberry/qnxhv_vm/soc.yml | 4 + 14 files changed, 294 insertions(+) create mode 100644 boards/blackberry/index.rst create mode 100644 boards/blackberry/qnxhv_vm/Kconfig.qnxhv_vm create mode 100644 boards/blackberry/qnxhv_vm/board.yml create mode 100644 boards/blackberry/qnxhv_vm/doc/index.rst create mode 100644 boards/blackberry/qnxhv_vm/qnxhv_vm.dts create mode 100644 boards/blackberry/qnxhv_vm/qnxhv_vm.yaml create mode 100644 boards/blackberry/qnxhv_vm/qnxhv_vm_defconfig create mode 100644 soc/blackberry/qnxhv_vm/CMakeLists.txt create mode 100644 soc/blackberry/qnxhv_vm/Kconfig create mode 100644 soc/blackberry/qnxhv_vm/Kconfig.defconfig create mode 100644 soc/blackberry/qnxhv_vm/Kconfig.soc create mode 100644 soc/blackberry/qnxhv_vm/mmu_regions.c create mode 100644 soc/blackberry/qnxhv_vm/soc.yml diff --git a/boards/blackberry/index.rst b/boards/blackberry/index.rst new file mode 100644 index 000000000000..6031e708b092 --- /dev/null +++ b/boards/blackberry/index.rst @@ -0,0 +1,10 @@ +.. _boards-blackberry: + +BlackBerry +########## + +.. toctree:: + :maxdepth: 1 + :glob: + + **/* diff --git a/boards/blackberry/qnxhv_vm/Kconfig.qnxhv_vm b/boards/blackberry/qnxhv_vm/Kconfig.qnxhv_vm new file mode 100644 index 000000000000..be9bb59e74b5 --- /dev/null +++ b/boards/blackberry/qnxhv_vm/Kconfig.qnxhv_vm @@ -0,0 +1,5 @@ +# Copyright (c) 2025 TOKITA Hiroshi +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_QNXHV_VM + select SOC_QNXHV_VM diff --git a/boards/blackberry/qnxhv_vm/board.yml b/boards/blackberry/qnxhv_vm/board.yml new file mode 100644 index 000000000000..ec77f7c72766 --- /dev/null +++ b/boards/blackberry/qnxhv_vm/board.yml @@ -0,0 +1,6 @@ +board: + name: qnxhv_vm + full_name: QNX Hypervisor Virtual Machine + vendor: blackberry + socs: + - name: qnxhv_vm diff --git a/boards/blackberry/qnxhv_vm/doc/index.rst b/boards/blackberry/qnxhv_vm/doc/index.rst new file mode 100644 index 000000000000..fac4a99d9b24 --- /dev/null +++ b/boards/blackberry/qnxhv_vm/doc/index.rst @@ -0,0 +1,105 @@ +.. zephyr:board:: qnxhv_vm + +Overview +******** + +This board enables running Zephyr as a guest inside a QNX Hypervisor virtual +machine. + +This is an example configuration. VM layouts are typically unique per product, +so you will likely need to adjust the devicetree and Kconfig options to match +your VM configuration (memory map, interrupt routing, clocks, devices, etc.). + +Hardware +******** + +Supported Features +================== + +.. zephyr:board-supported-hw:: + +.. _qvmconf: + +QNX Hypervisor Virtual Machine Configuration +-------------------------------------------- + +The virtual hardware exposed to the guest depends on the VM configuration file. +The above features are supported by following configuration. + +.. code-block:: + + # Guest name (optional) + system zephyr + + # One vCPU + cpu + + # Guest RAM base/size + ram 0x80000000,128M + + # Virtual interrupt controller + vdev gic version 2 + + # Load Zephyr image (ELF is supported by qvm) + load ./zephyr.elf + + # PL011 UART mapped into the guest at loc, routed to a host device/endpoint + vdev pl011 + hostdev >- # QVM console (stdout/stderr), keeps early output visible + loc 0x1c090000 + intr gic:37 + + +Building and Running +******************** + +Build an application +==================== + +Use this board configuration to run basic Zephyr applications as a guest. +For example, build the :zephyr:code-sample:`synchronization` sample: + +.. zephyr-app-commands:: + :zephyr-app: samples/synchronization + :board: qnxhv_vm + :goals: build + +This produces a guest image (e.g. ``zephyr/zephyr.elf``) under the build directory. + +Create a VM Configuration file +============================== + +You also need to create ``.qvmconf`` file to configure virtual machine. +:ref:`qvmconf` is a example QVM configuration which is support by default +``qnxhv_vm`` configuration. + +Here, create a file named ``zephyr.qvmconf`` with the contents of this example. + +Running an application +====================== + +Transfer both the Zephyr image and the QVM configuration file to the QNX +Hypervisor machine, then start the VM: + +.. code-block:: console + + qvm @zephyr.qvmconf + +You will see Zephyr output: + +.. code-block:: console + + *** Booting Zephyr OS build v4.3.0-3524-g5c47f098ffc4 *** + thread_a: Hello World from cpu 0 on qnxhv_vm! + thread_b: Hello World from cpu 0 on qnxhv_vm! + thread_a: Hello World from cpu 0 on qnxhv_vm! + thread_b: Hello World from cpu 0 on qnxhv_vm! + thread_a: Hello World from cpu 0 on qnxhv_vm! + +Use :kbd:`CTRL+C` to stop the virtual machine. + + +References +********** + +- `QNX Hypervisor User's Guide (VM configuration) `_ diff --git a/boards/blackberry/qnxhv_vm/qnxhv_vm.dts b/boards/blackberry/qnxhv_vm/qnxhv_vm.dts new file mode 100644 index 000000000000..22687374815a --- /dev/null +++ b/boards/blackberry/qnxhv_vm/qnxhv_vm.dts @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2025 TOKITA Hiroshi + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include +#include + +/ { + model = "QNX Hypervisor Virtual Machine"; + compatible = "blackberry,qnxhv_vm"; + + chosen { + zephyr,sram = &sram0; + zephyr,console = &qvm_console; + zephyr,shell-uart = &qvm_console; + }; + + cpus { + #address-cells = <0x01>; + #size-cells = <0x00>; + + cpu@0 { + device_type = "cpu"; + compatible = "arm,armv8"; + enable-method = "psci"; + reg = <0x00>; + }; + }; + + uartclk: apb-pclk { + compatible = "fixed-clock"; + clock-frequency = <24000000>; + #clock-cells = <0>; + }; + + psci { + compatible = "arm,psci-0.2"; + method = "hvc"; + }; + + soc { + #address-cells = <2>; + #size-cells = <2>; + interrupt-parent = <&gic>; + + sram0: memory@80000000 { + compatible = "mmio-sram"; + reg = <0x0 0x80000000 0x0 DT_SIZE_M(128)>; + }; + + gic: interrupt-controller@2c001000 { + compatible = "arm,gic-v2", "arm,gic"; + reg = <0x00 0x2c001000 0x00 0x00001000>, + <0x00 0x2c002000 0x00 0x00002000>; + interrupt-controller; + #interrupt-cells = <4>; + status = "okay"; + }; + + timer: timer { + compatible = "arm,armv8-timer"; + interrupt-parent = <&gic>; + interrupts = , + , + , + ; + clock-frequency = <54000000>; + }; + + qvm_console: uart@1c090000 { + compatible = "arm,pl011"; + reg = <0x00 0x1c090000 0x00 0x1000>; + interrupts = ; + interrupt-names = "irq_0"; + clocks = <&uartclk>; + current-speed = <115200>; + status = "okay"; + }; + }; +}; diff --git a/boards/blackberry/qnxhv_vm/qnxhv_vm.yaml b/boards/blackberry/qnxhv_vm/qnxhv_vm.yaml new file mode 100644 index 000000000000..8ad8ffbc4701 --- /dev/null +++ b/boards/blackberry/qnxhv_vm/qnxhv_vm.yaml @@ -0,0 +1,9 @@ +identifier: qnxhv_vm +name: QNX Hypervisor Virtual Machine +type: mcu +arch: arm64 +toolchain: + - zephyr + - cross-compile +ram: 131072 +vendor: blackberry diff --git a/boards/blackberry/qnxhv_vm/qnxhv_vm_defconfig b/boards/blackberry/qnxhv_vm/qnxhv_vm_defconfig new file mode 100644 index 000000000000..b7d592cecb6f --- /dev/null +++ b/boards/blackberry/qnxhv_vm/qnxhv_vm_defconfig @@ -0,0 +1,7 @@ +# Copyright (c) 2025 TOKITA Hiroshi +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SERIAL=y +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_UART_INTERRUPT_DRIVEN=y diff --git a/dts/bindings/vendor-prefixes.txt b/dts/bindings/vendor-prefixes.txt index 09dd15e40af7..428afc7ea6c1 100644 --- a/dts/bindings/vendor-prefixes.txt +++ b/dts/bindings/vendor-prefixes.txt @@ -107,6 +107,7 @@ beagle BeagleBoard.org Foundation bflb Bouffalo Lab (Nanjing) Co., Ltd. bhf Beckhoff Automation GmbH & Co. KG bitmain Bitmain Technologies +blackberry BlackBerry Limited blues Blues Wireless blutek BluTek Power boe BOE Technology Group Co., Ltd. diff --git a/soc/blackberry/qnxhv_vm/CMakeLists.txt b/soc/blackberry/qnxhv_vm/CMakeLists.txt new file mode 100644 index 000000000000..f469b865cdad --- /dev/null +++ b/soc/blackberry/qnxhv_vm/CMakeLists.txt @@ -0,0 +1,6 @@ +# Copyright (c) 2025 TOKITA Hiroshi +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library_sources_ifdef(CONFIG_ARM_MMU mmu_regions.c) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm64/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/blackberry/qnxhv_vm/Kconfig b/soc/blackberry/qnxhv_vm/Kconfig new file mode 100644 index 000000000000..1c7e2bfa13c0 --- /dev/null +++ b/soc/blackberry/qnxhv_vm/Kconfig @@ -0,0 +1,7 @@ +# Copyright (c) 2025 TOKITA Hiroshi +# SPDX-License-Identifier: Apache-2.0 + +config SOC_QNXHV_VM + select ARM64 + select ARM_ARCH_TIMER if SYS_CLOCK_EXISTS + select CPU_CORTEX_A72 diff --git a/soc/blackberry/qnxhv_vm/Kconfig.defconfig b/soc/blackberry/qnxhv_vm/Kconfig.defconfig new file mode 100644 index 000000000000..98eabfa4f140 --- /dev/null +++ b/soc/blackberry/qnxhv_vm/Kconfig.defconfig @@ -0,0 +1,14 @@ +# Copyright (c) 2025 TOKITA Hiroshi +# SPDX-License-Identifier: Apache-2.0 + +if SOC_QNXHV_VM + +DT_TIMER_PATH := $(dt_nodelabel_path,timer) + +config SYS_CLOCK_HW_CYCLES_PER_SEC + default $(dt_node_int_prop_int,$(DT_TIMER_PATH),clock-frequency) + +config NUM_IRQS + default 256 + +endif diff --git a/soc/blackberry/qnxhv_vm/Kconfig.soc b/soc/blackberry/qnxhv_vm/Kconfig.soc new file mode 100644 index 000000000000..2402b21635e0 --- /dev/null +++ b/soc/blackberry/qnxhv_vm/Kconfig.soc @@ -0,0 +1,8 @@ +# Copyright (c) 2025 TOKITA Hiroshi +# SPDX-License-Identifier: Apache-2.0 + +config SOC_QNXHV_VM + bool + +config SOC + default "qnxhv_vm" if SOC_QNXHV_VM diff --git a/soc/blackberry/qnxhv_vm/mmu_regions.c b/soc/blackberry/qnxhv_vm/mmu_regions.c new file mode 100644 index 000000000000..b5d1205775f0 --- /dev/null +++ b/soc/blackberry/qnxhv_vm/mmu_regions.c @@ -0,0 +1,27 @@ +/* + * Copyright 2019 Broadcom + * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries. + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include + +static const struct arm_mmu_region mmu_regions[] = { + + MMU_REGION_FLAT_ENTRY("GIC", + DT_REG_ADDR_BY_IDX(DT_INST(0, arm_gic), 0), + DT_REG_SIZE_BY_IDX(DT_INST(0, arm_gic), 0), + MT_DEVICE_nGnRnE | MT_P_RW_U_NA | MT_DEFAULT_SECURE_STATE), + + MMU_REGION_FLAT_ENTRY("GIC", + DT_REG_ADDR_BY_IDX(DT_INST(0, arm_gic), 1), + DT_REG_SIZE_BY_IDX(DT_INST(0, arm_gic), 1), + MT_DEVICE_nGnRnE | MT_P_RW_U_NA | MT_DEFAULT_SECURE_STATE), +}; + +const struct arm_mmu_config mmu_config = { + .num_regions = ARRAY_SIZE(mmu_regions), + .mmu_regions = mmu_regions, +}; diff --git a/soc/blackberry/qnxhv_vm/soc.yml b/soc/blackberry/qnxhv_vm/soc.yml new file mode 100644 index 000000000000..2546b5985155 --- /dev/null +++ b/soc/blackberry/qnxhv_vm/soc.yml @@ -0,0 +1,4 @@ +series: +- name: qnxhv_vm + socs: + - name: qnxhv_vm From a28b6f8ed75b53d84086c9cb2f8f4fc7067aa6fd Mon Sep 17 00:00:00 2001 From: Tom Hughes Date: Mon, 12 Jan 2026 16:48:20 -0800 Subject: [PATCH 1943/3659] arc: Use ARG_UNUSED instead of self-assignment to avoid clang warnings clang warns about self assignment when -Wself-assign is enabled. Signed-off-by: Tom Hughes --- arch/arc/include/v2/irq.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arc/include/v2/irq.h b/arch/arc/include/v2/irq.h index f24ac01315a5..df14ece1e54b 100644 --- a/arch/arc/include/v2/irq.h +++ b/arch/arc/include/v2/irq.h @@ -68,7 +68,7 @@ static ALWAYS_INLINE void z_irq_setup(void) #ifdef CONFIG_ARC_NORMAL_FIRMWARE /* normal mode cannot write irq_ctrl, ignore it */ - aux_irq_ctrl_value = aux_irq_ctrl_value; + ARG_UNUSED(aux_irq_ctrl_value); #else z_arc_v2_aux_reg_write(_ARC_V2_AUX_IRQ_CTRL, aux_irq_ctrl_value); #endif From a0fdebcc908ad484c29092c30be5513b9d346651 Mon Sep 17 00:00:00 2001 From: Tom Hughes Date: Fri, 16 Jan 2026 12:09:32 -0800 Subject: [PATCH 1944/3659] tests: drivers: build_all: input: Fix warning When building the drivers.input.adc_keys test with clang and -Winitializer-overrides, it warns: subsys/input/input_keymap.c:123:29: error: initializer overrides prior initialization of this subobject [-Werror,-Winitializer-overrides] 123 | DT_INST_FOREACH_STATUS_OKAY(INPUT_KEYMAP_DEFINE) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~ /include/zephyr/devicetree.h:5306:25: note: expanded from macro 'DT_INST_FOREACH_STATUS_OKAY' 5304 | COND_CODE_1(DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT), \ | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 5305 | (UTIL_CAT(DT_FOREACH_OKAY_INST_, \ | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 5306 | DT_DRV_COMPAT)(fn)), \ | ~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~ 5307 | ()) | ~~~ Signed-off-by: Tom Hughes --- tests/drivers/build_all/input/app.overlay | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/drivers/build_all/input/app.overlay b/tests/drivers/build_all/input/app.overlay index db3183d90b4b..a7ae80116f29 100644 --- a/tests/drivers/build_all/input/app.overlay +++ b/tests/drivers/build_all/input/app.overlay @@ -5,6 +5,7 @@ */ #include +#include / { test { @@ -88,9 +89,10 @@ keymap { compatible = "input-keymap"; - keymap = <0 1 2>; row-size = <2>; col-size = <2>; + keymap = ; }; }; From f46f921b7f4f8a7ba2999e2e84354a984162b14d Mon Sep 17 00:00:00 2001 From: Felix Wang Date: Thu, 27 Nov 2025 23:54:13 +0800 Subject: [PATCH 1945/3659] drivers: pwm: Fix ASSERTION FAIL in pwm_mcux In PWM_SetupPwm implementation, there is a check: temp = pwmClock / pwmFreq_Hz; assert(temp <= 0xFFFFU); Currently pwmFreq_Hz is 1, makes assert failed with high frequency pwmClock. Since VALx values is set directly for edge aligned PWM, the pwmFreq_Hz here is a dummy value, set pwmFreq_Hz equal to pwmClock frequency to pass assert check. Signed-off-by: Felix Wang --- drivers/pwm/pwm_mcux.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pwm/pwm_mcux.c b/drivers/pwm/pwm_mcux.c index 1c0b00c656b7..fecff8469623 100644 --- a/drivers/pwm/pwm_mcux.c +++ b/drivers/pwm/pwm_mcux.c @@ -82,7 +82,7 @@ static int mcux_pwm_set_cycles_internal(const struct device *dev, uint32_t chann status = PWM_SetupPwm(config->base, config->index, &data->channel[channel], 1U, - config->mode, 1U, clock_freq); + config->mode, clock_freq >> config->prescale, clock_freq); if (status != kStatus_Success) { LOG_ERR("Could not set up pwm"); return -ENOTSUP; From bf829e647653a044079fc7b9234ef55edfe28217 Mon Sep 17 00:00:00 2001 From: Felix Wang Date: Thu, 27 Nov 2025 23:08:21 +0800 Subject: [PATCH 1946/3659] dts: bindings: pwm: Add input filter properties for nxp,imx-pwm.yaml Add device tree binding properties for PWM input capture filtering functionality to the NXP i.MX PWM driver binding. New properties added: - input-filter-count: Configure number of consecutive samples required before accepting input transitions - input-filter-period: Set sampling period in IPBus clock cycles for input capture filtering These properties enable configuration of input filtering to reduce noise and improve signal integrity for PWM capture operations. Setting filter period to 0 bypasses the input filter entirely. Signed-off-by: Felix Wang --- dts/bindings/pwm/nxp,imx-pwm.yaml | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/dts/bindings/pwm/nxp,imx-pwm.yaml b/dts/bindings/pwm/nxp,imx-pwm.yaml index 08fa0ab5e09d..e9f27ba505a8 100644 --- a/dts/bindings/pwm/nxp,imx-pwm.yaml +++ b/dts/bindings/pwm/nxp,imx-pwm.yaml @@ -1,4 +1,5 @@ -# Copyright (c) 2019, Linaro Limited +# Copyright (c) 2019 Linaro Limited +# Copyright 2025 NXP # SPDX-License-Identifier: Apache-2.0 description: NXP MCUX PWM @@ -47,6 +48,24 @@ properties: "full-cycle" - registers loaded on a PWM full cycle; "half-and-full-cycle" - registers loaded on a PWM half & full cycle. + input-filter-count: + type: int + description: | + Set the number of consecutive samples that must agree prior to + the input filter accepting an input transition. The number of samples + is the decimal value of this field plus three: the bit field value of 0-7 + represents 3-10 samples, respectively. The value affects the input latency. + Valid range: 0 - 7 + + input-filter-period: + type: int + description: | + Set the sampling period (in IPBus clock cycles) of the input capture pin input filter. + Each input is sampled multiple times at the rate specified by this field. + If the value is 0x00 (default), then the input filter is bypassed. The value affects + the input latency. + Valid range: 0 - 255 + "#pwm-cells": const: 3 From 8dcd7579eb1362d08f8e7eeb81379a46a06fdbfb Mon Sep 17 00:00:00 2001 From: Felix Wang Date: Thu, 27 Nov 2025 23:03:45 +0800 Subject: [PATCH 1947/3659] drivers: pwm: Add PWM capture functionality for pwm_mcux Add support for PWM input capture functionality to the NXP MCUX PWM driver. This enables measurement of pulse width and period of external PWM signals. Key features added: - PWM capture configuration and control APIs - Interrupt-driven capture with overflow handling - Support for both pulse width and period measurement - Configurable input filtering - Support for continuous and one-shot capture modes The implementation uses FlexPWM channel X as the dedicated input capture channel, while channels 0 and 1 remain available for PWM output. Capture functionality is conditionally compiled based on CONFIG_PWM_CAPTURE configuration option. Signed-off-by: Felix Wang --- drivers/pwm/pwm_mcux.c | 349 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 348 insertions(+), 1 deletion(-) diff --git a/drivers/pwm/pwm_mcux.c b/drivers/pwm/pwm_mcux.c index fecff8469623..8db626938e95 100644 --- a/drivers/pwm/pwm_mcux.c +++ b/drivers/pwm/pwm_mcux.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2019, Linaro - * + * Copyright 2025 NXP * SPDX-License-Identifier: Apache-2.0 */ @@ -15,12 +15,27 @@ #include #include +#ifdef CONFIG_PWM_CAPTURE +#include +#endif + #include LOG_MODULE_REGISTER(pwm_mcux, CONFIG_PWM_LOG_LEVEL); #define CHANNEL_COUNT 2 +#ifdef CONFIG_PWM_CAPTURE +struct pwm_mcux_capture_data { + pwm_capture_callback_handler_t callback; + void *user_data; + uint32_t overflow_count; + uint32_t capture_channel; + bool continuous : 1; + bool pulse_capture : 1; +}; +#endif /* CONFIG_PWM_CAPTURE */ + struct pwm_mcux_config { PWM_Type *base; uint8_t index; @@ -32,12 +47,21 @@ struct pwm_mcux_config { bool run_wait; bool run_debug; const struct pinctrl_dev_config *pincfg; +#ifdef CONFIG_PWM_CAPTURE + uint8_t input_filter_count; + uint8_t input_filter_period; + void (*irq_config_func)(const struct device *dev); +#endif }; struct pwm_mcux_data { uint32_t period_cycles[CHANNEL_COUNT]; pwm_signal_param_t channel[CHANNEL_COUNT]; struct k_mutex lock; +#ifdef CONFIG_PWM_CAPTURE + struct pwm_mcux_capture_data capture; + bool capture_active; +#endif }; static int mcux_pwm_set_cycles_internal(const struct device *dev, uint32_t channel, @@ -48,6 +72,13 @@ static int mcux_pwm_set_cycles_internal(const struct device *dev, uint32_t chann struct pwm_mcux_data *data = dev->data; pwm_level_select_t level; +#ifdef CONFIG_PWM_CAPTURE + if (data->capture_active) { + LOG_ERR("PWM capture is active, cannot set PWM output"); + return -EBUSY; + } +#endif + if (flags & PWM_POLARITY_INVERTED) { level = kPWM_LowTrue; } else { @@ -204,6 +235,287 @@ static int mcux_pwm_get_cycles_per_sec(const struct device *dev, return 0; } +#ifdef CONFIG_PWM_CAPTURE +static int mcux_pwm_calc_ticks(uint16_t first_capture, uint16_t second_capture, uint32_t mod, + uint32_t overflows, uint32_t *result) +{ + uint32_t ticks; + + if (second_capture >= first_capture) { + /* No timer overflow between captures */ + ticks = second_capture - first_capture; + } else { + /* Timer overflowed between captures */ + ticks = (mod - first_capture) + second_capture + 1U; + if (overflows > 0) { + /* Account for the overflow we just calculated */ + overflows--; + } + } + + /* Add additional overflows */ + if (u32_mul_overflow(overflows, mod, &overflows)) { + LOG_ERR("overflow while calculating overflow cycles."); + return -ERANGE; + } + + if (u32_add_overflow(ticks, overflows, &ticks)) { + LOG_ERR("overflow while calculating capture cycles."); + return -ERANGE; + } + + *result = ticks; + + return 0; +} + +static void mcux_pwm_isr(const struct device *dev) +{ + const struct pwm_mcux_config *config = dev->config; + struct pwm_mcux_data *data = dev->data; + struct pwm_mcux_capture_data *capture = &data->capture; + uint32_t status; + uint16_t first_edge_value; + uint16_t second_edge_value; + uint32_t ticks = 0; + int err = 0; + + uint16_t modValue = config->base->SM[config->index].VAL1 - + config->base->SM[config->index].INIT; + + status = PWM_GetStatusFlags(config->base, config->index); + PWM_ClearStatusFlags(config->base, config->index, status); + + if (status & kPWM_ReloadFlag) { + err = u32_add_overflow(capture->overflow_count, 1, &capture->overflow_count); + } + + if (status & kPWM_CaptureX0Flag) { + capture->overflow_count = 0; + } + + if (status & kPWM_CaptureX1Flag) { + if (err != 0) { + LOG_ERR("overflow_count overflows."); + } else { + first_edge_value = config->base->SM[config->index].CVAL0; + second_edge_value = config->base->SM[config->index].CVAL1; + err = mcux_pwm_calc_ticks(first_edge_value, second_edge_value, modValue, + capture->overflow_count, &ticks); + LOG_DBG("First edge capture: %d, second edge capture: %d," + "overflow: %d, ticks: %d", first_edge_value, second_edge_value, + capture->overflow_count, ticks); + } + + if (capture->pulse_capture) { + capture->callback(dev, capture->capture_channel, 0, ticks, err, + capture->user_data); + } else { + capture->callback(dev, capture->capture_channel, ticks, 0, err, + capture->user_data); + } + + capture->overflow_count = 0; + } +} + +static int check_channel(const struct device *dev, uint32_t channel) +{ + struct pwm_mcux_data *data = dev->data; + + /* Check if the channel is already used for PWM output */ + if (channel < CHANNEL_COUNT && data->period_cycles[channel] != 0) { + LOG_ERR("Channel %d is already used for PWM output", channel); + return -EBUSY; + } + + /* Check if the channel supports capture based on hardware features */ + if (channel == 0U) { +#if defined(FSL_FEATURE_PWM_HAS_CAPTURE_ON_CHANNELA) && \ + (FSL_FEATURE_PWM_HAS_CAPTURE_ON_CHANNELA == 0U) + LOG_ERR("Channel A does not support capture on this hardware"); + return -ENOTSUP; +#endif + } else if (channel == 1U) { +#if defined(FSL_FEATURE_PWM_HAS_CAPTURE_ON_CHANNELB) && \ + (FSL_FEATURE_PWM_HAS_CAPTURE_ON_CHANNELB == 0U) + LOG_ERR("Channel B does not support capture on this hardware"); + return -ENOTSUP; +#endif + } else if (channel == 2U) { +#if defined(FSL_FEATURE_PWM_HAS_CAPTURE_ON_CHANNELX) && \ + (FSL_FEATURE_PWM_HAS_CAPTURE_ON_CHANNELX == 0U) + LOG_ERR("Channel X does not support capture on this hardware"); + return -ENOTSUP; +#endif + } else { + LOG_ERR("Invalid channel %d", channel); + return -EINVAL; + } + + return 0; +} + +static int mcux_pwm_configure_capture(const struct device *dev, + uint32_t channel, pwm_flags_t flags, + pwm_capture_callback_handler_t cb, + void *user_data) +{ + const struct pwm_mcux_config *config = dev->config; + struct pwm_mcux_data *data = dev->data; + bool inverted = (flags & PWM_POLARITY_MASK) == PWM_POLARITY_INVERTED; + int ret; + pwm_channels_t pwm_channel; + pwm_input_capture_param_t capture_config; + + memset(&capture_config, 0, sizeof(capture_config)); + + ret = check_channel(dev, channel); + if (ret != 0) { + return ret; + } + + if (cb == NULL) { + LOG_ERR("PWM capture callback is not configured"); + return -EINVAL; + } + + if (data->capture_active) { + LOG_ERR("PWM capture already in progress"); + return -EBUSY; + } + + if (!(flags & PWM_CAPTURE_TYPE_MASK)) { + LOG_ERR("No capture type specified"); + return -EINVAL; + } + + if ((flags & PWM_CAPTURE_TYPE_MASK) == PWM_CAPTURE_TYPE_BOTH) { + LOG_ERR("Cannot capture both period and pulse width"); + return -ENOTSUP; + } + + /* Initialize capture data */ + data->capture.callback = cb; + data->capture.user_data = user_data; + data->capture.capture_channel = channel; + data->capture.continuous = + (flags & PWM_CAPTURE_MODE_MASK) == PWM_CAPTURE_MODE_CONTINUOUS; + data->capture.pulse_capture = + (flags & PWM_CAPTURE_TYPE_MASK) == PWM_CAPTURE_TYPE_PULSE; + data->capture.overflow_count = 0; + + /* Configure input capture parameters */ + capture_config.captureInputSel = false; /* Use raw input signal (not edge counter) */ + if (data->capture.pulse_capture) { + capture_config.edge0 = inverted ? kPWM_FallingEdge : kPWM_RisingEdge; + capture_config.edge1 = inverted ? kPWM_RisingEdge : kPWM_FallingEdge; + } else { + capture_config.edge0 = inverted ? kPWM_FallingEdge : kPWM_RisingEdge; + capture_config.edge1 = inverted ? kPWM_FallingEdge : kPWM_RisingEdge; + } + capture_config.enableOneShotCapture = !data->capture.continuous; + capture_config.fifoWatermark = 0; + + /* Fix mismatch because kPWM_PwmA is 1U, kPWM_PwmB is 0U */ + if (channel == 0U) { + pwm_channel = kPWM_PwmA; + } else if (channel == 1U) { + pwm_channel = kPWM_PwmB; + } else { + pwm_channel = kPWM_PwmX; + } + + /* Setup input capture on channel */ + PWM_SetupInputCapture(config->base, config->index, pwm_channel, &capture_config); + + /* Set capture filter */ + PWM_SetFilterSampleCount(config->base, pwm_channel, config->index, + config->input_filter_count); + PWM_SetFilterSamplePeriod(config->base, pwm_channel, config->index, + config->input_filter_period); + + return 0; +} + +static int mcux_pwm_enable_capture(const struct device *dev, uint32_t channel) +{ + const struct pwm_mcux_config *config = dev->config; + struct pwm_mcux_data *data = dev->data; + uint32_t status; + int ret; + + ret = check_channel(dev, channel); + if (ret != 0) { + return ret; + } + + if (!data->capture.callback) { + LOG_ERR("PWM capture not configured"); + return -EINVAL; + } + + if (data->capture_active) { + LOG_ERR("PWM capture already enabled"); + return -EBUSY; + } + + data->capture_active = true; + /* Make sure the flags are cleared in case it enters IRQ immediately after enable + * interrupts, results in error result at first. + */ + status = PWM_GetStatusFlags(config->base, config->index); + PWM_ClearStatusFlags(config->base, config->index, status); + + if (channel == 0U) { + PWM_EnableInterrupts(config->base, config->index, kPWM_CaptureA0InterruptEnable | + kPWM_CaptureA1InterruptEnable | kPWM_ReloadInterruptEnable); + } else if (channel == 1U) { + PWM_EnableInterrupts(config->base, config->index, kPWM_CaptureB0InterruptEnable | + kPWM_CaptureB1InterruptEnable | kPWM_ReloadInterruptEnable); + } else { + PWM_EnableInterrupts(config->base, config->index, kPWM_CaptureX0InterruptEnable | + kPWM_CaptureX1InterruptEnable | kPWM_ReloadInterruptEnable); + } + + /* Start the PWM counter if it's stopped.*/ + if ((config->base->MCTRL & PWM_MCTRL_RUN_MASK) == 0) { + PWM_StartTimer(config->base, (1U << config->index)); + } + + return 0; +} + +static int mcux_pwm_disable_capture(const struct device *dev, uint32_t channel) +{ + const struct pwm_mcux_config *config = dev->config; + struct pwm_mcux_data *data = dev->data; + int ret; + + ret = check_channel(dev, channel); + if (ret != 0) { + return ret; + } + + /* Disable capture interrupts */ + if (channel == 0U) { + PWM_DisableInterrupts(config->base, config->index, kPWM_CaptureA0InterruptEnable | + kPWM_CaptureA1InterruptEnable | kPWM_ReloadInterruptEnable); + } else if (channel == 1U) { + PWM_DisableInterrupts(config->base, config->index, kPWM_CaptureB0InterruptEnable | + kPWM_CaptureB1InterruptEnable | kPWM_ReloadInterruptEnable); + } else { + PWM_DisableInterrupts(config->base, config->index, kPWM_CaptureX0InterruptEnable | + kPWM_CaptureX1InterruptEnable | kPWM_ReloadInterruptEnable); + } + + data->capture_active = false; + data->capture.callback = NULL; + + return 0; +} +#endif /* CONFIG_PWM_CAPTURE */ + static int pwm_mcux_init(const struct device *dev) { const struct pwm_mcux_config *config = dev->config; @@ -233,6 +545,10 @@ static int pwm_mcux_init(const struct device *dev) pwm_config.clockSource = kPWM_BusClock; pwm_config.enableDebugMode = config->run_debug; #if !defined(FSL_FEATURE_PWM_HAS_NO_WAITEN) || (!FSL_FEATURE_PWM_HAS_NO_WAITEN) + /* Note: When the CPU enters a low-power mode, if enableWait is not set to true, + * the FlexPWM module will stop operating, which may interfere with input capture + * functionality + */ pwm_config.enableWait = config->run_wait; #endif @@ -252,17 +568,47 @@ static int pwm_mcux_init(const struct device *dev) data->channel[1].pwmChannel = kPWM_PwmB; data->channel[1].level = kPWM_HighTrue; +#ifdef CONFIG_PWM_CAPTURE + if (config->irq_config_func) { + config->irq_config_func(dev); + } +#endif + return 0; } static DEVICE_API(pwm, pwm_mcux_driver_api) = { .set_cycles = mcux_pwm_set_cycles, .get_cycles_per_sec = mcux_pwm_get_cycles_per_sec, +#ifdef CONFIG_PWM_CAPTURE + .configure_capture = mcux_pwm_configure_capture, + .enable_capture = mcux_pwm_enable_capture, + .disable_capture = mcux_pwm_disable_capture, +#endif }; +#ifdef CONFIG_PWM_CAPTURE + +#define PWM_MCUX_IRQ_CONFIG_FUNC(n) \ + static void pwm_mcux_config_func_##n(const struct device *dev) \ + { \ + IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority), \ + mcux_pwm_isr, DEVICE_DT_INST_GET(n), 0); \ + irq_enable(DT_INST_IRQN(n)); \ + } +#define PWM_MCUX_CAPTURE_CONFIG_INIT(n) \ + .irq_config_func = pwm_mcux_config_func_##n, \ + .input_filter_count = DT_INST_PROP_OR(n, input_filter_count, 0), \ + .input_filter_period = DT_INST_PROP_OR(n, input_filter_period, 0), +#else +#define PWM_MCUX_IRQ_CONFIG_FUNC(n) +#define PWM_MCUX_CAPTURE_CONFIG_INIT(n) +#endif /* CONFIG_PWM_CAPTURE */ + #define PWM_DEVICE_INIT_MCUX(n) \ static struct pwm_mcux_data pwm_mcux_data_ ## n; \ PINCTRL_DT_INST_DEFINE(n); \ + PWM_MCUX_IRQ_CONFIG_FUNC(n) \ \ static const struct pwm_mcux_config pwm_mcux_config_ ## n = { \ .base = (PWM_Type *)DT_REG_ADDR(DT_INST_PARENT(n)), \ @@ -276,6 +622,7 @@ static DEVICE_API(pwm, pwm_mcux_driver_api) = { .run_wait = DT_INST_PROP(n, run_in_wait), \ .run_debug = DT_INST_PROP(n, run_in_debug), \ .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ + PWM_MCUX_CAPTURE_CONFIG_INIT(n) \ }; \ \ DEVICE_DT_INST_DEFINE(n, \ From c84fdef122df6e6489464afca115a3fe446abf66 Mon Sep 17 00:00:00 2001 From: Felix Wang Date: Thu, 27 Nov 2025 23:18:16 +0800 Subject: [PATCH 1948/3659] tests: pwm: pwm_loopback: Add board overlay for mimxrt1180_evk Add device tree overlay for PWM loopback testing on the MIMXRT1180EVK board using FlexPWM1 module. Configuration includes: - Pin configuration for PWM output (gpio_ad_00/J69-3) and input capture (gpio_ad_06/J70-1) using FlexPWM1 channels - PWM loopback test node with output on channel 0 and input on channel 2 - Input filter settings with minimal count and period for testing - Physical connection requirement between J69-3 and J70-1 Signed-off-by: Felix Wang --- ...rt1180_evk_mimxrt1189_cm33_flexpwm.overlay | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 tests/drivers/pwm/pwm_loopback/boards/mimxrt1180_evk_mimxrt1189_cm33_flexpwm.overlay diff --git a/tests/drivers/pwm/pwm_loopback/boards/mimxrt1180_evk_mimxrt1189_cm33_flexpwm.overlay b/tests/drivers/pwm/pwm_loopback/boards/mimxrt1180_evk_mimxrt1189_cm33_flexpwm.overlay new file mode 100644 index 000000000000..df4da6f88fb6 --- /dev/null +++ b/tests/drivers/pwm/pwm_loopback/boards/mimxrt1180_evk_mimxrt1189_cm33_flexpwm.overlay @@ -0,0 +1,41 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include + +&pinctrl { + flexpwm1_pwm0_default: flexpwm1_pwm0_default { + group0 { + pinmux = <&iomuxc_gpio_ad_00_flexpwm1_pwm0_a>; + drive-strength = "normal"; + slew-rate = "fast"; + }; + + group1 { + pinmux = <&iomuxc_gpio_ad_06_flexpwm1_pwm0_x>; + drive-strength = "normal"; + slew-rate = "fast"; + }; + }; +}; +/* To test this sample, connect + * gpio_ad_00(J69-3) ---> gpio_ad_06(J70-1) + */ + +/ { + pwm_loopback_0 { + compatible = "test-pwm-loopback"; + pwms = <&flexpwm1_pwm0 0 0 PWM_POLARITY_NORMAL>, /* gpio_ad_00 J69-3, out */ + <&flexpwm1_pwm0 2 0 PWM_POLARITY_NORMAL>; /* gpio_ad_06 J70-1, in */ + }; +}; + +&flexpwm1_pwm0 { + status = "okay"; + pinctrl-0 = <&flexpwm1_pwm0_default>; + pinctrl-names = "default"; + input-filter-count = <1>; + input-filter-period = <1>; +}; From baaf468bc176a5b836324e941672a273c49eac9e Mon Sep 17 00:00:00 2001 From: Derek Snell Date: Wed, 10 Dec 2025 16:55:12 -0500 Subject: [PATCH 1949/3659] soc: nxp: imxrt1180: enable more CM7 memory execution options Enables other RAM locations for CM7 instead of hardcoding to ITCM. Signed-off-by: Derek Snell --- soc/nxp/imxrt/imxrt118x/soc.c | 45 ++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/soc/nxp/imxrt/imxrt118x/soc.c b/soc/nxp/imxrt/imxrt118x/soc.c index 4ec8961c4bbc..7d47f7219b1c 100644 --- a/soc/nxp/imxrt/imxrt118x/soc.c +++ b/soc/nxp/imxrt/imxrt118x/soc.c @@ -70,20 +70,6 @@ const __imx_boot_container_section container boot_header = { }; #endif -#if defined(CONFIG_SECOND_CORE_MCUX) && defined(CONFIG_CPU_CORTEX_M33) -#if !defined(CONFIG_CM7_BOOT_FROM_FLASH) -#include -/* Memcpy macro to copy segments from secondary core image stored in flash - * to RAM section that secondary core boots from. - * n is the segment number, as defined in zephyr_image_info.h - */ -#define MEMCPY_SEGMENT(n, _) \ - memcpy((uint32_t *)(((SEGMENT_LMA_ADDRESS_ ## n) - ADJUSTED_LMA) + 0x303C0000), \ - (uint32_t *)(SEGMENT_LMA_ADDRESS_ ## n), \ - (SEGMENT_SIZE_ ## n)) -#endif /* !defined(CONFIG_CM7_BOOT_FROM_FLASH) */ -#endif - /* * Set ELE_STICK_FAILED_STS to 0 when ELE status check is not required, * which is useful when debug reset, where the core has already get the @@ -116,13 +102,14 @@ const __imx_boot_container_section container boot_header = { #endif #if (defined(CONFIG_SECOND_CORE_MCUX) && defined(CONFIG_CPU_CORTEX_M33)) -/* Handle CM7 core initialization based on execution mode */ -#if !defined(CONFIG_CM7_BOOT_FROM_FLASH) -#define CM7_BOOT_ADDRESS (0) -#else /* Get CM7 partition address from device tree */ #define CM7_PARTITION_NODE DT_CHOSEN(zephyr_code_m7_partition) #define CM7_FLASH_ADDR DT_REG_ADDR(CM7_PARTITION_NODE) + +/* Handle CM7 core initialization based on execution mode */ +#if !defined(CONFIG_CM7_BOOT_FROM_FLASH) +#define CM7_BOOT_ADDRESS (CM7_FLASH_ADDR + CONFIG_CM7_FLEXSPI_OFFSET - ADJUSTED_LMA) +#else #define CM7_BOOT_ADDRESS (CM7_FLASH_ADDR + CONFIG_CM7_FLEXSPI_OFFSET) #endif /* defined(CONFIG_CM7_BOOT_FROM_FLASH) */ #endif /* (defined(CONFIG_SECOND_CORE_MCUX) && defined(CONFIG_CPU_CORTEX_M33)) */ @@ -878,6 +865,26 @@ void soc_early_init_hook(void) #if (defined(CONFIG_SECOND_CORE_MCUX) && defined(CONFIG_CPU_CORTEX_M33)) #if !defined(CONFIG_CM7_BOOT_FROM_FLASH) +#include + +/* Determine if CM33 needs to adjust the address to access CM7 memory */ +#if ((CM7_BOOT_ADDRESS >= 0U) && (CM7_BOOT_ADDRESS <= 0x1FFFFU)) + /* Adjust to CM33 address to access CM7 ITCM */ + #define MEMMAP_ADJUST 0x303C0000U +#else + #define MEMMAP_ADJUST 0U /* No adjustment needed */ +#endif + +/* Memcpy macro to copy segments from secondary core image stored in flash + * to RAM section that secondary core boots from. + * n is the segment number, as defined in zephyr_image_info.h + */ +#define MEMCPY_SEGMENT(n, _) \ + memcpy((uint32_t *)(((SEGMENT_LMA_ADDRESS_ ## n) \ + - ADJUSTED_LMA) + MEMMAP_ADJUST), \ + (uint32_t *)(SEGMENT_LMA_ADDRESS_ ## n), \ + (SEGMENT_SIZE_ ## n)) + /** * Copy CM7 core from flash to memory. Note that depending on where the * user decided to store CM7 code, this is likely going to read from the @@ -888,8 +895,8 @@ void soc_early_init_hook(void) * ensure the data is written directly to RAM (since the M4 core will use it) */ LISTIFY(SEGMENT_NUM, MEMCPY_SEGMENT, (;)); -#endif /* (defined(CONFIG_SECOND_CORE_MCUX) && defined(CONFIG_CPU_CORTEX_M33)) */ #endif /* !defined(CONFIG_CM7_BOOT_FROM_FLASH) */ +#endif /* (defined(CONFIG_SECOND_CORE_MCUX) && defined(CONFIG_CPU_CORTEX_M33)) */ /* Enable data cache */ sys_cache_data_enable(); From 694ecafce2fdfc5f59b5bbb3ab04c1a391330f40 Mon Sep 17 00:00:00 2001 From: Derek Snell Date: Thu, 11 Dec 2025 08:40:09 -0500 Subject: [PATCH 1950/3659] boards: nxp: mimxrt1180_evk: enable CM7 execution from hyperram * adds CM7 HyperRAM overlay and documentation * removes hardcoded Kconfig settings for ITCM * adds example cm33_sram_dtcm.overlay Signed-off-by: Derek Snell --- boards/nxp/mimxrt1180_evk/Kconfig.defconfig | 9 +-- .../nxp/mimxrt1180_evk/cm33_sram_dtcm.overlay | 21 ++++++ .../mimxrt1180_evk/cm7_code_hyperram.overlay | 42 +++++++++++ boards/nxp/mimxrt1180_evk/doc/index.rst | 70 ++++++++++++++++--- 4 files changed, 127 insertions(+), 15 deletions(-) create mode 100644 boards/nxp/mimxrt1180_evk/cm33_sram_dtcm.overlay create mode 100644 boards/nxp/mimxrt1180_evk/cm7_code_hyperram.overlay diff --git a/boards/nxp/mimxrt1180_evk/Kconfig.defconfig b/boards/nxp/mimxrt1180_evk/Kconfig.defconfig index 6f3f7c263be5..ab6cc49963d2 100644 --- a/boards/nxp/mimxrt1180_evk/Kconfig.defconfig +++ b/boards/nxp/mimxrt1180_evk/Kconfig.defconfig @@ -29,17 +29,18 @@ config BUILD_OUTPUT_INFO_HEADER default y DT_CHOSEN_IMAGE_M7 = nxp,m7-partition +DT_CHOSEN_ZEPHYR_FLASH = zephyr,flash -# Only adjust LMA if running from ITCM +# Only adjust LMA if running from RAM if !CM7_BOOT_FROM_FLASH -# Adjust the offset of the output image if building for RT118x SOC ITCM +# Adjust the offset of the output image if building for RT118x SOC in RAM FLEXSPI_BASE := $(dt_nodelabel_reg_addr_hex,flexspi,1) -ITCM_BASE := $(dt_nodelabel_reg_addr_hex,itcm,1) +M7_CODE_BASE := $(dt_chosen_reg_addr_hex,$(DT_CHOSEN_ZEPHYR_FLASH)) IMAGE_M7_ADDR := $(dt_chosen_reg_addr_hex,$(DT_CHOSEN_IMAGE_M7)) config BUILD_OUTPUT_ADJUST_LMA - default "($(IMAGE_M7_ADDR) + $(FLEXSPI_BASE) - $(ITCM_BASE))" + default "($(IMAGE_M7_ADDR) + $(FLEXSPI_BASE) - $(M7_CODE_BASE))" endif # !CM7_BOOT_FROM_FLASH endif # SECOND_CORE_MCUX && BOARD_MIMXRT1180_EVK_MIMXRT1189_CM7 diff --git a/boards/nxp/mimxrt1180_evk/cm33_sram_dtcm.overlay b/boards/nxp/mimxrt1180_evk/cm33_sram_dtcm.overlay new file mode 100644 index 000000000000..345322f0dc9c --- /dev/null +++ b/boards/nxp/mimxrt1180_evk/cm33_sram_dtcm.overlay @@ -0,0 +1,21 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* Remove property from DTCM: zephyr,memory-region = "DTCM"; */ +/delete-node/ &dtcm; + +/ { + chosen { + zephyr,sram = &dtcm; + }; + + soc { + dtcm: memory@30000000 { + compatible = "nmmio-sram"; + reg = <0x30000000 DT_SIZE_K(128)>; + }; + }; +}; diff --git a/boards/nxp/mimxrt1180_evk/cm7_code_hyperram.overlay b/boards/nxp/mimxrt1180_evk/cm7_code_hyperram.overlay new file mode 100644 index 000000000000..2ea5cc199312 --- /dev/null +++ b/boards/nxp/mimxrt1180_evk/cm7_code_hyperram.overlay @@ -0,0 +1,42 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include + +/ { + chosen { + zephyr,flash = &hyperram0; + zephyr,code-partition = &slot1_partition; + }; +}; + +&flexspi2 { + status = "okay"; +}; + +&hyperram0 { + /* + * Currently, HyperRAM on this board must be accessed under XIP mode, + * so that the ROM bootloader can initialize it by reading the XMCD configuration. + * These XMCD configurations are stored in the default settings file + * `xip/evkmimxrt1180_flexspi_nor_config.c`. (If modifications are needed, + * please refer to the examples and the "System Boot" chapter in the + * RT1180 Reference Manual.) + * The CM33 core of the MIMXRT1180_EVK runs in XIP mode and uses the + * HyperRAM space as the RAM region by default. Therefore, the status of the + * full hyperram0 memory node is set to "okay" for cm33 core. + * At this point, the CM7 core can also access the HyperRAM. + * However, since the entire HyperRAM region is occupied in the CM33's DTS, + * users can allocate the HyperRAM reasonably so that both cores (CM33 and CM7) + * can use HyperRAM as their RAM region. + * + * If not configured by the ROM bootloader, the user must ensure the hyperram0 + * device is enabled in the DTS, otherwise, the user must set 'status = "disabled"; + * Note: mpu_region.c uses the status property from the DTS to configure the + * corresponding MPU settings. + */ + zephyr,memory-attr = ; + status = "okay"; +}; diff --git a/boards/nxp/mimxrt1180_evk/doc/index.rst b/boards/nxp/mimxrt1180_evk/doc/index.rst index 43f5081179c6..fad0f84fccd0 100644 --- a/boards/nxp/mimxrt1180_evk/doc/index.rst +++ b/boards/nxp/mimxrt1180_evk/doc/index.rst @@ -128,6 +128,17 @@ The MIMXRT1180 SoC is configured to use SysTick as the system clock source, running at 240MHz. When targeting the M7 core, SysTick will also be used, running at 792MHz +ITCM and DTCM +============= + +If placing ``zephyr,flash`` in ITCM or ``zephyr,sram`` in DTCM, the property +``zephyr,memory-region`` should be deleted from the memory device node. +For example, this overlay moves the CM33 ``zephyr,sram`` to DTCM: + +.. code-block:: none + + boards/nxp/mimxrt1180_evk/cm33_sram_dtcm.overlay + Serial Port =========== @@ -177,23 +188,28 @@ starting the CM7 core. CM7 Execution Modes =================== -The CM7 core can execute code in two different modes: +The CM7 core is enabled to execute code in three memory options: -1. **ITCM Mode (Default)**: The CM7 code is copied from flash to ITCM (Instruction Tightly Coupled Memory) +1. **ITCM (Default)**: The CM7 code is copied from flash to ITCM (Instruction Tightly Coupled Memory) and executed from there. This provides faster execution but is limited by the ITCM size. -2. **Flash Mode**: The CM7 code is executed directly from flash memory (XIP - eXecute In Place). +2. **Flash**: The CM7 code is executed directly from flash memory (XIP - eXecute In Place). This allows for larger code size but may be slower than ITCM execution. When booting CM7 from Flash the TRDC execution permissions has to be set by CM33 core. -Configuring CM7 Execution Mode -============================== +3. **HyperRAM**: The CM7 code is copied from flash to external HyperRAM and executed from there. + This allows for larger code size but may be slower than ITCM execution. Be aware, the CM33 + default data placement ``zephyr,sram`` is in HyperRAM. Ensure the CM33 and CM7 are not using overlapping + regions in HyperRAM. One option given below moves the CM33 data to DTCM. + +Configuring CM7 Execution memory +================================ -To configure the CM7 execution mode, you can use the following Kconfig option: +To configure the memory for CM7 execution, you can use the following Kconfig option: .. code-block:: none - CONFIG_CM7_BOOT_FROM_FLASH=n # For ITCM execution (default) + CONFIG_CM7_BOOT_FROM_FLASH=n # For RAM execution, ITCM or HyperRAM (default) CONFIG_CM7_BOOT_FROM_FLASH=y # For flash execution When building with west, you can specify this option on the command line: @@ -212,6 +228,11 @@ When building with west, you can specify this option on the command line: -Dremote_EXTRA_DTC_OVERLAY_FILE=${ZEPHYR_BASE}/boards/nxp/mimxrt1180_evk/cm7_flash_boot.overlay \ -DCONFIG_CM7_BOOT_FROM_FLASH=y -Dremote_CONFIG_CM7_BOOT_FROM_FLASH=y + # For HyperRAM execution + west build -b mimxrt1180_evk//cm33 samples/drivers/mbox --sysbuild -- \ + -Dremote_EXTRA_DTC_OVERLAY_FILE=${ZEPHYR_BASE}/boards/nxp/mimxrt1180_evk/cm7_code_hyperram.overlay \ + -DEXTRA_DTC_OVERLAY_FILE=${ZEPHYR_BASE}/boards/nxp/mimxrt1180_evk/cm33_sram_dtcm.overlay + Flash Boot Overlay ================== @@ -224,17 +245,44 @@ the flash memory properly. The overlay file is located at: This overlay configures the CM7 core to use the flash memory for code execution instead of ITCM. +HyperRAM Execution Overlay +========================== + +When executing the CM7 core from HyperRAM, you need to apply a device tree overlay. An example +overlay file is located at: + +.. code-block:: none + + boards/nxp/mimxrt1180_evk/cm7_code_hyperram.overlay + +The MPU attributes for the board also need to be changed in this file: + +.. code-block:: none + + boards/nxp/mimxrt1180_evk/cm7/mpu_regions.c + +Changing the line below enables execution from the HyperRAM region by setting the flash attribute: + +.. code-block:: none + + #if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(hyperram0)) + MPU_REGION_ENTRY("HYPER_RAM", REGION_HYPER_RAM_BASE_ADDRESS, + - REGION_RAM_ATTR(REGION_HYPER_RAM_SIZE)), + + REGION_FLASH_ATTR(REGION_HYPER_RAM_SIZE)), + #endif + Memory Usage ============ -* **ITCM Mode**: The CM7 code is copied from flash to ITCM. -* **Flash Mode**: The CM7 code is executed directly from flash, which allows for larger code size. +* **from RAM**: The CM7 code is copied from flash to ITCM or HyperRAM. +* **from Flash**: The CM7 code is executed directly from flash, which allows for larger code size than ITCM. Performance Considerations ========================== -* **ITCM Mode**: Provides faster execution due to the low-latency ITCM memory. -* **Flash Mode**: May be slower due to flash memory access times, but allows for larger code size. +* **from ITCM**: Provides faster execution due to the low-latency internal ITCM memory. +* **from external memory**: External flash or HyperRAM may be slower due to memory access times, + but allows for larger code size. Dual Core samples Debugging =========================== From d2c4dda0c6a8240138b9626581a5cb6c2f7a298f Mon Sep 17 00:00:00 2001 From: Felix Wang Date: Mon, 15 Dec 2025 08:52:28 +0530 Subject: [PATCH 1951/3659] dts: bindings: pwm: clarify prescaler description for ctimer pwm Clarify that the prescaler value divides the clock by (prescaler + 1), not by the prescaler value directly. This helps users understand the actual clock division behavior. Signed-off-by: Felix Wang --- dts/bindings/pwm/nxp,ctimer-pwm.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dts/bindings/pwm/nxp,ctimer-pwm.yaml b/dts/bindings/pwm/nxp,ctimer-pwm.yaml index 7b7f8e31a7ba..cda89fffd19b 100644 --- a/dts/bindings/pwm/nxp,ctimer-pwm.yaml +++ b/dts/bindings/pwm/nxp,ctimer-pwm.yaml @@ -14,7 +14,9 @@ properties: prescaler: type: int default: 1 - description: prescaling value + description: | + Specifies the prescale value. Valid range: 0x0 - 0xFFFFFFFF. + The clock is divided by (prescaler + 1). clk-source: type: int From fa48bee6c478b0a0c42c9685177bffa5b1f9ad90 Mon Sep 17 00:00:00 2001 From: Felix Wang Date: Mon, 15 Dec 2025 09:27:20 +0530 Subject: [PATCH 1952/3659] drivers: pwm: fix prescaler calculation for pwm_mcux_ctimer The prescaler divides the clock by (prescaler + 1), not by the prescaler value directly. Update the calculation to correctly account for this. Signed-off-by: Felix Wang --- drivers/pwm/pwm_mcux_ctimer.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/pwm/pwm_mcux_ctimer.c b/drivers/pwm/pwm_mcux_ctimer.c index 27d48211cc86..c6dd105d6f12 100644 --- a/drivers/pwm/pwm_mcux_ctimer.c +++ b/drivers/pwm/pwm_mcux_ctimer.c @@ -1,5 +1,6 @@ /* * (c) Meta Platforms, Inc. and affiliates. + * Copyright 2025 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -206,9 +207,9 @@ static int mcux_ctimer_pwm_get_cycles_per_sec(const struct device *dev, uint32_t return err; } - if (config->prescale > 0) { - *cycles /= config->prescale; - } + *cycles /= (uint64_t)config->prescale + 1; + __ASSERT((*cycles) > 0, "Invalid PWM frequency: cycles per second is 0(check clock rate + and prescaler)"); return err; } From c30ad66e46a6e95e9ce6ba63c5f23d9848f758a5 Mon Sep 17 00:00:00 2001 From: Felix Wang Date: Mon, 15 Dec 2025 09:33:11 +0530 Subject: [PATCH 1953/3659] tests: drivers: pwm: pwm_api: boards: Enable frdm_mcxa153 test Add device tree overlay to enable PWM API testing on the frdm_mcxa153 board using ctimer0. The overlay configures: - PWM test alias pointing to ctimer0 - Pin P2_12 (J2_12) as PWM output - ctimer0 in PWM mode with prescaler set to 1 Signed-off-by: Felix Wang --- .../pwm/pwm_api/boards/frdm_mcxa153.overlay | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 tests/drivers/pwm/pwm_api/boards/frdm_mcxa153.overlay diff --git a/tests/drivers/pwm/pwm_api/boards/frdm_mcxa153.overlay b/tests/drivers/pwm/pwm_api/boards/frdm_mcxa153.overlay new file mode 100644 index 000000000000..e05b3bf7ff12 --- /dev/null +++ b/tests/drivers/pwm/pwm_api/boards/frdm_mcxa153.overlay @@ -0,0 +1,31 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + pwm-test = &ctimer0; + }; +}; + +&pinctrl { + ctimer0_default: ctimer0_default { + group0 { + /* PWM output P2_12 (J2_12) */ + pinmux = ; + drive-strength = "high"; + slew-rate = "fast"; + }; + }; +}; + +&ctimer0 { + compatible = "nxp,ctimer-pwm"; + status = "okay"; + pinctrl-0 = <&ctimer0_default>; + pinctrl-names = "default"; + #pwm-cells = <3>; + prescaler = <1>; +}; From e7840a9d27cd3fbefa917f254d41718eb22278fc Mon Sep 17 00:00:00 2001 From: Felix Wang Date: Wed, 17 Dec 2025 23:04:22 +0800 Subject: [PATCH 1954/3659] drivers: pwm: Fix polarity update on duty cycle change 1.Add mcux_sctimer_pwm_update_polarity() function to properly reconfigure PWM output polarity when duty cycle is updated. 2.Update Match Reload Value register when Match register is set. 3.Stop timer before update to prevent bus error Signed-off-by: Felix Wang --- drivers/pwm/pwm_mcux_sctimer.c | 39 +++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/drivers/pwm/pwm_mcux_sctimer.c b/drivers/pwm/pwm_mcux_sctimer.c index 9f572f452ee1..54a6a9264966 100644 --- a/drivers/pwm/pwm_mcux_sctimer.c +++ b/drivers/pwm/pwm_mcux_sctimer.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, NXP + * Copyright (c) 2021, 2025 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -78,6 +78,36 @@ static int mcux_sctimer_new_channel(const struct device *dev, return 0; } +static void mcux_sctimer_pwm_update_polarity(const struct device *dev, uint32_t channel) +{ + const struct pwm_mcux_sctimer_config *config = dev->config; + struct pwm_mcux_sctimer_data *data = dev->data; + uint32_t period_event = data->event_number[channel]; + uint32_t pulse_event = period_event + 1; + + /* clear polarity setting*/ + config->base->OUTPUT &= ~(1UL << channel); + config->base->OUT[channel].SET &= ~((1UL << pulse_event) | (1UL << period_event)); + config->base->OUT[channel].CLR &= ~((1UL << pulse_event) | (1UL << period_event)); + + /* Set polarity based on channel level configuration */ + if (data->channel[channel].level == kSCTIMER_HighTrue) { + /* Set the initial output level to low which is the inactive state */ + config->base->OUTPUT &= ~(1UL << channel); + /* Set the output when we reach the PWM period */ + SCTIMER_SetupOutputSetAction(config->base, channel, period_event); + /* Clear the output when we reach the PWM pulse value */ + SCTIMER_SetupOutputClearAction(config->base, channel, pulse_event); + } else { + /* Set the initial output level to high which is the inactive state */ + config->base->OUTPUT |= (1UL << channel); + /* Clear the output when we reach the PWM period */ + SCTIMER_SetupOutputClearAction(config->base, channel, period_event); + /* Set the output when we reach the PWM pulse value */ + SCTIMER_SetupOutputSetAction(config->base, channel, pulse_event); + } +} + static int mcux_sctimer_pwm_set_cycles(const struct device *dev, uint32_t channel, uint32_t period_cycles, uint32_t pulse_cycles, pwm_flags_t flags) @@ -177,11 +207,18 @@ static int mcux_sctimer_pwm_set_cycles(const struct device *dev, * (which the SDK will setup as the pulse match event) */ SCTIMER_StopTimer(config->base, kSCTIMER_Counter_U); + /* Update polarity */ + mcux_sctimer_pwm_update_polarity(dev, channel); + config->base->MATCH[period_event] = period_cycles - 1U; config->base->MATCHREL[period_event] = period_cycles - 1U; + config->base->MATCH[period_event + 1] = pulse_cycles - 1U; config->base->MATCHREL[period_event + 1] = pulse_cycles - 1U; SCTIMER_StartTimer(config->base, kSCTIMER_Counter_U); data->match_period = period_cycles; } else { + SCTIMER_StopTimer(config->base, kSCTIMER_Counter_U); + /* Update polarity */ + mcux_sctimer_pwm_update_polarity(dev, channel); /* Only duty cycle needs to be updated */ SCTIMER_UpdatePwmDutycycle(config->base, channel, duty_cycle, data->event_number[channel]); From 3a5f9c886e0009f349a2427525530f9479b4204f Mon Sep 17 00:00:00 2001 From: Felix Wang Date: Wed, 17 Dec 2025 23:11:26 +0800 Subject: [PATCH 1955/3659] dts: bindings: pwm: Add input capture properties to nxp,sctimer-pwm Add input-channels and inputmux-connections properties to the nxp,sctimer-pwm device tree binding to support SCTimer input capture configuration. Signed-off-by: Felix Wang --- dts/bindings/pwm/nxp,sctimer-pwm.yaml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/dts/bindings/pwm/nxp,sctimer-pwm.yaml b/dts/bindings/pwm/nxp,sctimer-pwm.yaml index 50222e6413bd..e378aeb4842d 100644 --- a/dts/bindings/pwm/nxp,sctimer-pwm.yaml +++ b/dts/bindings/pwm/nxp,sctimer-pwm.yaml @@ -22,6 +22,23 @@ properties: - 64 - 128 + input-channels: + type: array + description: | + Array of SCTimer input channel numbers that are configured for capture. + Each element represents an input channel (0-7 for most NXP SoCs). + Example: <0 1 2> configures IN0, IN1, and IN2. + + inputmux-connections: + type: array + description: | + Array of INPUTMUX connection types for each input channel. + Each element corresponds to the input channel at the same index in input-channels. + Values map to device-specific inputmux_connection_t enum values from + fsl_inputmux_connections.h, take LPC55S36 as example: + - 0: kINPUTMUX_SctGpioInAToSct0 (GPIO to SCT input A) + - 1: kINPUTMUX_SctGpioInBToSct0 (GPIO to SCT input B) + "#pwm-cells": const: 3 From e72d11e9030fa31bb7b00b0a33f35acd3f01ae1f Mon Sep 17 00:00:00 2001 From: Felix Wang Date: Wed, 17 Dec 2025 23:55:03 +0800 Subject: [PATCH 1956/3659] drivers: pwm: Add input capture support to nxp,sctimer-pwm Implement PWM input capture functionality for the NXP SCTimer driver with support for both pulse width and period measurement in single-shot and continuous modes. Signed-off-by: Felix Wang --- drivers/pwm/pwm_mcux_sctimer.c | 482 ++++++++++++++++++++++++++++++++- 1 file changed, 472 insertions(+), 10 deletions(-) diff --git a/drivers/pwm/pwm_mcux_sctimer.c b/drivers/pwm/pwm_mcux_sctimer.c index 54a6a9264966..0d41541566f3 100644 --- a/drivers/pwm/pwm_mcux_sctimer.c +++ b/drivers/pwm/pwm_mcux_sctimer.c @@ -13,13 +13,18 @@ #include #include #include - +#ifdef CONFIG_PWM_CAPTURE +#include +#include +#endif #include LOG_MODULE_REGISTER(pwm_mcux_sctimer, CONFIG_PWM_LOG_LEVEL); #define CHANNEL_COUNT FSL_FEATURE_SCT_NUMBER_OF_OUTPUTS +#define CAPTURE_CHANNEL_COUNT FSL_FEATURE_SCT_NUMBER_OF_MATCH_CAPTURE + /* Constant identifying that no event number has been set */ #define EVENT_NOT_SET FSL_FEATURE_SCT_NUMBER_OF_EVENTS @@ -29,13 +34,44 @@ struct pwm_mcux_sctimer_config { const struct pinctrl_dev_config *pincfg; const struct device *clock_dev; clock_control_subsys_t clock_subsys; +#ifdef CONFIG_PWM_CAPTURE + const uint32_t *input_channels; + const uint32_t *inputmux_connections; + uint8_t input_channel_count; + void (*irq_config_func)(const struct device *dev); +#endif /* CONFIG_PWM_CAPTURE */ +}; + +#ifdef CONFIG_PWM_CAPTURE +struct pwm_mcux_sctimer_capture_data { + pwm_capture_callback_handler_t callback; + void *user_data; + uint32_t overflow_count; + uint32_t first_capture_event; + uint32_t second_capture_event; + uint32_t first_limit_count; + uint32_t second_limit_count; + uint32_t first_capture_value; + uint32_t second_capture_value; + + bool continuous : 1; + bool overflowed : 1; + bool pulse_capture : 1; + bool capture_ready : 1; + bool channel_used: 1; + bool first_edge_captured : 1; }; +#endif /* CONFIG_PWM_CAPTURE */ struct pwm_mcux_sctimer_data { uint32_t event_number[CHANNEL_COUNT]; sctimer_pwm_signal_param_t channel[CHANNEL_COUNT]; uint32_t match_period; uint32_t configured_chan; +#ifdef CONFIG_PWM_CAPTURE + uint32_t match_event; + struct pwm_mcux_sctimer_capture_data capture_data[CAPTURE_CHANNEL_COUNT]; +#endif /* CONFIG_PWM_CAPTURE */ }; /* Helper to setup channel that has not previously been configured for PWM */ @@ -56,7 +92,6 @@ static int mcux_sctimer_new_channel(const struct device *dev, } pwm_freq = (clock_freq / config->prescale) / period_cycles; - if (pwm_freq == 0) { LOG_ERR("Could not set up pwm_freq=%d", pwm_freq); return -EINVAL; @@ -72,6 +107,12 @@ static int mcux_sctimer_new_channel(const struct device *dev, LOG_ERR("Could not set up pwm"); return -ENOTSUP; } +#ifdef CONFIG_PWM_CAPTURE + /* All channel share same period, so we can use one of pwm period + * as capture period. + */ + data->match_event = data->event_number[channel]; +#endif /* CONFIG_PWM_CAPTURE */ SCTIMER_StartTimer(config->base, kSCTIMER_Counter_U); data->configured_chan++; @@ -244,6 +285,379 @@ static int mcux_sctimer_pwm_get_cycles_per_sec(const struct device *dev, return 0; } + +#ifdef CONFIG_PWM_CAPTURE +static void mcux_sctimer_get_edge_events(bool inverted, bool pulse_capture, + sctimer_event_t *first_edge, sctimer_event_t *second_edge) +{ + if (inverted) { + *first_edge = kSCTIMER_InputFallEvent; + *second_edge = pulse_capture ? kSCTIMER_InputRiseEvent : kSCTIMER_InputFallEvent; + } else { + *first_edge = kSCTIMER_InputRiseEvent; + *second_edge = pulse_capture ? kSCTIMER_InputFallEvent : kSCTIMER_InputRiseEvent; + } +} + +static int mcux_sctimer_setup_capture_events(const struct device *dev, uint32_t channel, + sctimer_event_t first_edge_event, + sctimer_event_t second_edge_event, + uint32_t *first_capture_event, + uint32_t *second_capture_event) +{ + const struct pwm_mcux_sctimer_config *config = dev->config; + struct pwm_mcux_sctimer_data *data = dev->data; + uint32_t capture_reg; + + /* Create first edge capture event */ + if (SCTIMER_CreateAndScheduleEvent(config->base, first_edge_event, + 0, channel, kSCTIMER_Counter_U, + first_capture_event) != kStatus_Success) { + LOG_ERR("Failed to create first edge event"); + return -ENOTSUP; + } + + /* Setup capture action for first edge */ + if (SCTIMER_SetupCaptureAction(config->base, kSCTIMER_Counter_U, + &capture_reg, *first_capture_event) != kStatus_Success) { + LOG_ERR("Failed to setup first edge capture"); + return -ENOTSUP; + } + + /* Create second edge capture event */ + if (SCTIMER_CreateAndScheduleEvent(config->base, second_edge_event, + 0, channel, kSCTIMER_Counter_U, + second_capture_event) != kStatus_Success) { + LOG_ERR("Failed to create second edge event"); + return -ENOTSUP; + } + + /* Setup capture action for second edge */ + if (SCTIMER_SetupCaptureAction(config->base, kSCTIMER_Counter_U, + &capture_reg, *second_capture_event) != kStatus_Success) { + LOG_ERR("Failed to setup second edge capture"); + return -ENOTSUP; + } + + if (data->match_event == EVENT_NOT_SET) { + /* Create limit event for overflow detection */ + if (SCTIMER_CreateAndScheduleEvent(config->base, kSCTIMER_MatchEventOnly, + 0xFFFF, 0, kSCTIMER_Counter_U, + &data->match_event) != kStatus_Success) { + LOG_ERR("Failed to create limit event"); + return -ENOTSUP; + } + /* Setup counter limit action */ + SCTIMER_SetupCounterLimitAction(config->base, kSCTIMER_Counter_U, + data->match_event); + } + + return 0; +} + +static int mcux_sctimer_configure_capture(const struct device *dev, + uint32_t channel, pwm_flags_t flags, + pwm_capture_callback_handler_t cb, + void *user_data) +{ + const struct pwm_mcux_sctimer_config *config = dev->config; + struct pwm_mcux_sctimer_data *data = dev->data; + bool inverted = (flags & PWM_POLARITY_INVERTED) != 0; + bool pulse_capture = (flags & PWM_CAPTURE_TYPE_PERIOD) == 0; + uint32_t first_capture_event = EVENT_NOT_SET; + uint32_t second_capture_event = EVENT_NOT_SET; + sctimer_event_t first_edge_event; + sctimer_event_t second_edge_event; + int ret; + + if (channel >= CAPTURE_CHANNEL_COUNT) { + LOG_ERR("invalid channel %d", channel); + return -EINVAL; + } + + if (!(flags & PWM_CAPTURE_TYPE_MASK)) { + LOG_ERR("No capture type specified"); + return -EINVAL; + } + + if ((flags & PWM_CAPTURE_TYPE_MASK) == PWM_CAPTURE_TYPE_BOTH) { + LOG_ERR("Cannot capture both period and pulse width"); + return -ENOTSUP; + } + + if (data->capture_data[channel].channel_used) { + LOG_ERR("pwm capture in progress"); + return -EBUSY; + } + + mcux_sctimer_get_edge_events(inverted, pulse_capture, &first_edge_event, + &second_edge_event); + + data->capture_data[channel].callback = cb; + data->capture_data[channel].user_data = user_data; + data->capture_data[channel].continuous = + (flags & PWM_CAPTURE_MODE_MASK) == PWM_CAPTURE_MODE_CONTINUOUS; + data->capture_data[channel].pulse_capture = pulse_capture; + data->capture_data[channel].first_edge_captured = false; + + /* If capture is already configured, return success */ + if (data->capture_data[channel].first_capture_event == EVENT_NOT_SET && + data->capture_data[channel].second_capture_event == EVENT_NOT_SET) { + ret = mcux_sctimer_setup_capture_events(dev, channel, first_edge_event, + second_edge_event, &first_capture_event, &second_capture_event); + if (ret != 0) { + return ret; + } + /* Store capture configuration */ + data->capture_data[channel].first_capture_event = first_capture_event; + data->capture_data[channel].second_capture_event = second_capture_event; + } else { + /* Capture already configured, update capture events */ + config->base->EV[data->capture_data[channel].first_capture_event].CTRL &= + ~(SCT_EV_CTRL_IOCOND_MASK | SCT_EV_CTRL_IOSEL_MASK); + config->base->EV[data->capture_data[channel].first_capture_event].CTRL |= + first_edge_event | SCT_EV_CTRL_IOSEL(channel); + + config->base->EV[data->capture_data[channel].second_capture_event].CTRL &= + ~(SCT_EV_CTRL_IOCOND_MASK | SCT_EV_CTRL_IOSEL_MASK); + config->base->EV[data->capture_data[channel].second_capture_event].CTRL |= + second_edge_event | SCT_EV_CTRL_IOSEL(channel); + } + + return 0; +} + +static int mcux_sctimer_enable_capture(const struct device *dev, uint32_t channel) +{ + const struct pwm_mcux_sctimer_config *config = dev->config; + struct pwm_mcux_sctimer_data *data = dev->data; + uint32_t status_flags; + + if (channel >= CAPTURE_CHANNEL_COUNT) { + LOG_ERR("invalid channel %d", channel); + return -EINVAL; + } + + if (!data->capture_data[channel].callback) { + LOG_ERR("PWM capture not configured"); + return -EINVAL; + } + + if (data->capture_data[channel].channel_used) { + LOG_ERR("pwm capture channel in progress"); + return -EBUSY; + } + + /* Reset capture state */ + data->capture_data[channel].channel_used = true; + + /* The flag is set when match events happen even if interrupt is disabled. + * Clear status before enabling interrupt. + */ + status_flags = SCTIMER_GetStatusFlags(config->base); + SCTIMER_ClearStatusFlags(config->base, status_flags); + + /* Enable interrupts for capture events and limit */ + SCTIMER_EnableInterrupts(config->base, + (1 << data->capture_data[channel].first_capture_event) | + (1 << data->capture_data[channel].second_capture_event) | + (1 << data->match_event)); + + return 0; +} + +static int mcux_sctimer_disable_capture(const struct device *dev, uint32_t channel) +{ + const struct pwm_mcux_sctimer_config *config = dev->config; + struct pwm_mcux_sctimer_data *data = dev->data; + + if (channel >= CAPTURE_CHANNEL_COUNT) { + LOG_ERR("invalid channel %d", channel); + return -EINVAL; + } + + /* Disable interrupts */ + if (data->capture_data[channel].channel_used) { + data->capture_data[channel].channel_used = false; + SCTIMER_DisableInterrupts(config->base, + (1 << data->capture_data[channel].first_capture_event) | + (1 << data->capture_data[channel].second_capture_event) | + (1 << data->match_event)); + } + + /* Stop timer */ + SCTIMER_StopTimer(config->base, kSCTIMER_Counter_U); + + return 0; +} + +static int mcux_sctimer_calc_ticks(uint32_t period, uint32_t first_limit, uint32_t second_limit, + uint32_t first_capture, uint32_t second_capture, + uint32_t *result) +{ + uint32_t ticks; + uint32_t overflow_ticks; + + /* Calculate overflow ticks */ + if (u32_mul_overflow(second_limit - first_limit, period, &overflow_ticks)) { + return -ERANGE; + } + + /* Add capture difference */ + if (second_capture >= first_capture) { + if (u32_add_overflow(overflow_ticks, second_capture - first_capture, &ticks)) { + return -ERANGE; + } + } else { + /* Handle counter wrap */ + if (u32_add_overflow(overflow_ticks, period - first_capture + second_capture, + &ticks)) { + return -ERANGE; + } + } + + *result = ticks; + + return 0; +} + +static void mcux_sctimer_capture_first_edge(const struct device *dev, uint32_t channel) +{ + const struct pwm_mcux_sctimer_config *config = dev->config; + struct pwm_mcux_sctimer_data *data = dev->data; + + data->capture_data[channel].first_capture_value = + SCTIMER_GetCaptureValue(config->base, kSCTIMER_Counter_U, + data->capture_data[channel].first_capture_event); + data->capture_data[channel].first_limit_count = + data->capture_data[channel].overflow_count; + data->capture_data[channel].first_edge_captured = true; +} + +static void mcux_sctimer_capture_second_edge(const struct device *dev, uint32_t channel) +{ + const struct pwm_mcux_sctimer_config *config = dev->config; + struct pwm_mcux_sctimer_data *data = dev->data; + + data->capture_data[channel].second_capture_value = + SCTIMER_GetCaptureValue(config->base, kSCTIMER_Counter_U, + data->capture_data[channel].second_capture_event); + data->capture_data[channel].second_limit_count = + data->capture_data[channel].overflow_count; + data->capture_data[channel].capture_ready = true; + data->capture_data[channel].first_edge_captured = false; +} + +static void prepare_next_capture(const struct device *dev, uint32_t channel) +{ + const struct pwm_mcux_sctimer_config *config = dev->config; + struct pwm_mcux_sctimer_data *data = dev->data; + + data->capture_data[channel].capture_ready = false; + data->capture_data[channel].overflowed = false; + data->capture_data[channel].overflow_count = 0; + + /* Clear first capture setting */ + data->capture_data[channel].first_limit_count = 0; + data->capture_data[channel].first_capture_value = 0; + + if (data->capture_data[channel].continuous) { + if (!data->capture_data[channel].pulse_capture) { + /* For period capture, current first edge is start of next period */ + data->capture_data[channel].first_capture_value = + data->capture_data[channel].second_capture_value; + data->capture_data[channel].first_limit_count = + data->capture_data[channel].second_limit_count; + data->capture_data[channel].first_edge_captured = true; + } else { + /* No actions required. */ + } + } else { + /* Single capture mode: Disable interrupts */ + SCTIMER_DisableInterrupts(config->base, + (1 << data->capture_data[channel].first_capture_event) | + (1 << data->capture_data[channel].second_capture_event) | + (1 << data->match_event)); + } + + /* Clear second capture setting */ + data->capture_data[channel].second_limit_count = 0; + data->capture_data[channel].second_capture_value = 0; +} + +static void mcux_sctimer_process_channel_events(const struct device *dev, uint32_t channel, + uint32_t status_flags) +{ + struct pwm_mcux_sctimer_data *data = dev->data; + uint32_t ticks = 0; + int err; + + /* Handle limit/overflow interrupt */ + if (status_flags & (1 << data->match_event)) { + data->capture_data[channel].overflowed |= u32_add_overflow(1, + data->capture_data[channel].overflow_count, + &data->capture_data[channel].overflow_count); + } + + /* Handle first edge capture */ + if (status_flags & (1 << data->capture_data[channel].first_capture_event)) { + if (!data->capture_data[channel].first_edge_captured) { + mcux_sctimer_capture_first_edge(dev, channel); + return; + } + } + + /* Handle second edge capture */ + if (status_flags & (1 << data->capture_data[channel].second_capture_event)) { + if (data->capture_data[channel].first_edge_captured) { + mcux_sctimer_capture_second_edge(dev, channel); + } + } + + /* Process capture if ready */ + if (data->capture_data[channel].capture_ready) { + + err = mcux_sctimer_calc_ticks(data->match_period, + data->capture_data[channel].first_limit_count, + data->capture_data[channel].second_limit_count, + data->capture_data[channel].first_capture_value, + data->capture_data[channel].second_capture_value, + &ticks); + + if (!data->capture_data[channel].callback) { + return; + } + + if (data->capture_data[channel].pulse_capture) { + data->capture_data[channel].callback(dev, channel, + 0, ticks, err, data->capture_data[channel].user_data); + } else { + data->capture_data[channel].callback(dev, channel, + ticks, 0, err, data->capture_data[channel].user_data); + } + + prepare_next_capture(dev, channel); + } +} + +static void mcux_sctimer_isr(const struct device *dev) +{ + const struct pwm_mcux_sctimer_config *config = dev->config; + struct pwm_mcux_sctimer_data *data = dev->data; + uint32_t status_flags; + + status_flags = SCTIMER_GetStatusFlags(config->base); + SCTIMER_ClearStatusFlags(config->base, status_flags); + + for (uint32_t channel = 0; channel < CAPTURE_CHANNEL_COUNT; channel++) { + if (!data->capture_data[channel].channel_used) { + continue; + } + mcux_sctimer_process_channel_events(dev, channel, status_flags); + } +} +#endif /* CONFIG_PWM_CAPTURE */ + static int mcux_sctimer_pwm_init(const struct device *dev) { const struct pwm_mcux_sctimer_config *config = dev->config; @@ -277,26 +691,74 @@ static int mcux_sctimer_pwm_init(const struct device *dev) data->match_period = 0; data->configured_chan = 0; +#ifdef CONFIG_PWM_CAPTURE + /* set inputmux connections */ + INPUTMUX_Init(INPUTMUX); + for (i = 0; i < config->input_channel_count; i++) { + INPUTMUX_AttachSignal(INPUTMUX, config->input_channels[i], + config->inputmux_connections[i]); + } + /* Initialize capture data */ + data->match_event = EVENT_NOT_SET; + for (i = 0; i < CAPTURE_CHANNEL_COUNT; i++) { + /* Reset capture state */ + memset(&data->capture_data[i], 0, sizeof(struct pwm_mcux_sctimer_capture_data)); + data->capture_data[i].first_capture_event = EVENT_NOT_SET; + data->capture_data[i].second_capture_event = EVENT_NOT_SET; + } + /* Configure IRQ */ + config->irq_config_func(dev); +#endif /* CONFIG_PWM_CAPTURE */ + return 0; } static DEVICE_API(pwm, pwm_mcux_sctimer_driver_api) = { .set_cycles = mcux_sctimer_pwm_set_cycles, .get_cycles_per_sec = mcux_sctimer_pwm_get_cycles_per_sec, +#ifdef CONFIG_PWM_CAPTURE + .configure_capture = mcux_sctimer_configure_capture, + .enable_capture = mcux_sctimer_enable_capture, + .disable_capture = mcux_sctimer_disable_capture, +#endif }; -#define PWM_MCUX_SCTIMER_DEVICE_INIT_MCUX(n) \ - PINCTRL_DT_INST_DEFINE(n); \ - static struct pwm_mcux_sctimer_data pwm_mcux_sctimer_data_##n; \ - \ - static const struct pwm_mcux_sctimer_config pwm_mcux_sctimer_config_##n = { \ +#define SCTIMER_DECLARE_CFG(n, CAPTURE_INIT) \ + static const struct pwm_mcux_sctimer_config pwm_mcux_sctimer_config_##n = { \ .base = (SCT_Type *)DT_INST_REG_ADDR(n), \ .prescale = 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),\ - }; \ + .clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(n)), \ + .clock_subsys = (clock_control_subsys_t)DT_INST_CLOCKS_CELL(n, name), \ + CAPTURE_INIT \ + } + +#ifdef CONFIG_PWM_CAPTURE +#define SCTIMER_CONFIG_FUNC(n) \ +static void mcux_sctimer_config_func_##n(const struct device *dev) \ +{ \ + IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority), \ + mcux_sctimer_isr, DEVICE_DT_INST_GET(n), 0); \ + irq_enable(DT_INST_IRQN(n)); \ +} +#define SCTIMER_CFG_CAPTURE_INIT(n) \ + .input_channels = (const uint32_t[]) DT_INST_PROP(n, input_channels), \ + .inputmux_connections = (const uint32_t[]) DT_INST_PROP(n, inputmux_connections), \ + .input_channel_count = DT_INST_PROP_LEN(n, input_channels), \ + .irq_config_func = mcux_sctimer_config_func_##n +#define SCTIMER_INIT_CFG(n) SCTIMER_DECLARE_CFG(n, SCTIMER_CFG_CAPTURE_INIT(n)) +#else /* !CONFIG_PWM_CAPTURE */ +#define SCTIMER_CONFIG_FUNC(n) +#define SCTIMER_CFG_CAPTURE_INIT +#define SCTIMER_INIT_CFG(n) SCTIMER_DECLARE_CFG(n, SCTIMER_CFG_CAPTURE_INIT) +#endif /* !CONFIG_PWM_CAPTURE */ + +#define PWM_MCUX_SCTIMER_DEVICE_INIT_MCUX(n) \ + PINCTRL_DT_INST_DEFINE(n); \ + static struct pwm_mcux_sctimer_data pwm_mcux_sctimer_data_##n; \ \ + SCTIMER_CONFIG_FUNC(n) \ + SCTIMER_INIT_CFG(n); \ DEVICE_DT_INST_DEFINE(n, \ mcux_sctimer_pwm_init, \ NULL, \ From 63c2ea005423b30914ef01de78e21d9d46a216fd Mon Sep 17 00:00:00 2001 From: Felix Wang Date: Thu, 18 Dec 2025 00:01:23 +0800 Subject: [PATCH 1957/3659] tests: drivers: pwm: pwm_loopback: boards: Enabe test on lpcxpresso55s36 Add lpcxpresso55s36 board configuration file. Signed-off-by: Felix Wang --- .../boards/lpcxpresso55s36.overlay | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 tests/drivers/pwm/pwm_loopback/boards/lpcxpresso55s36.overlay diff --git a/tests/drivers/pwm/pwm_loopback/boards/lpcxpresso55s36.overlay b/tests/drivers/pwm/pwm_loopback/boards/lpcxpresso55s36.overlay new file mode 100644 index 000000000000..bc85368b9888 --- /dev/null +++ b/tests/drivers/pwm/pwm_loopback/boards/lpcxpresso55s36.overlay @@ -0,0 +1,48 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/ { + aliases { + pwm-test = &sc_timer; + }; +}; + +&pinctrl { + pinmux_pwm0: pinmux_pwm0 { + group0 { + pinmux = ; + slew-rate = "standard"; + }; + + group1 { + pinmux = ; + slew-rate = "standard"; + }; + }; +}; + +/* To test this sample, connect + * J10-5 ---> J10-3 + */ + +/ { + pwm_loopback_0 { + compatible = "test-pwm-loopback"; + pwms = <&sc_timer 0 0 PWM_POLARITY_NORMAL>, /* PIO1_4 J10 pin 5 */ + <&sc_timer 1 0 PWM_POLARITY_NORMAL>; /* PIO0_13 J10 pin 3 */ + }; +}; + +&sc_timer { + status = "okay"; + pinctrl-0 = <&pinmux_pwm0>; + pinctrl-names = "default"; + prescaler = <1>; + input-channels = <1>; + inputmux-connections = <0>; +}; From 7bd6c0079b61d81a2559eb1322959abcce50ceaf Mon Sep 17 00:00:00 2001 From: Daniel Schaefer Date: Mon, 5 Jan 2026 15:37:22 +0800 Subject: [PATCH 1958/3659] boards: framework: Add framework_ledmatrix board The following examples build and work as expected: > west build -p -b framework_ledmatrix samples/basic/button > west build -p -b framework_ledmatrix samples/basic/minimal > west build -p -b framework_ledmatrix samples/subsys/usb/console > west build -p -b framework_ledmatrix samples/subsys/usb/cdc_acm > west build -p -b framework_ledmatrix samples/subsys/input/input_dump Signed-off-by: Daniel Schaefer --- boards/framework/framework_ledmatrix/Kconfig | 5 + .../framework_ledmatrix/Kconfig.defconfig | 19 +++ .../Kconfig.framework_ledmatrix | 5 + .../framework/framework_ledmatrix/board.cmake | 6 + .../framework/framework_ledmatrix/board.yml | 6 + .../doc/img/framework_ledmatrix.webp | Bin 0 -> 57284 bytes .../framework_ledmatrix/doc/index.rst | 65 +++++++++++ .../framework_ledmatrix-pinctrl.dtsi | 16 +++ .../framework_ledmatrix.dts | 108 ++++++++++++++++++ .../framework_ledmatrix.yaml | 18 +++ .../framework_ledmatrix_defconfig | 16 +++ 11 files changed, 264 insertions(+) create mode 100644 boards/framework/framework_ledmatrix/Kconfig create mode 100644 boards/framework/framework_ledmatrix/Kconfig.defconfig create mode 100644 boards/framework/framework_ledmatrix/Kconfig.framework_ledmatrix create mode 100644 boards/framework/framework_ledmatrix/board.cmake create mode 100644 boards/framework/framework_ledmatrix/board.yml create mode 100644 boards/framework/framework_ledmatrix/doc/img/framework_ledmatrix.webp create mode 100644 boards/framework/framework_ledmatrix/doc/index.rst create mode 100644 boards/framework/framework_ledmatrix/framework_ledmatrix-pinctrl.dtsi create mode 100644 boards/framework/framework_ledmatrix/framework_ledmatrix.dts create mode 100644 boards/framework/framework_ledmatrix/framework_ledmatrix.yaml create mode 100644 boards/framework/framework_ledmatrix/framework_ledmatrix_defconfig diff --git a/boards/framework/framework_ledmatrix/Kconfig b/boards/framework/framework_ledmatrix/Kconfig new file mode 100644 index 000000000000..716eca330a52 --- /dev/null +++ b/boards/framework/framework_ledmatrix/Kconfig @@ -0,0 +1,5 @@ +# Copyright (c) 2025 Framework Computer Inc +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_FRAMEWORK_LEDMATRIX + select RP2_FLASH_W25Q080 diff --git a/boards/framework/framework_ledmatrix/Kconfig.defconfig b/boards/framework/framework_ledmatrix/Kconfig.defconfig new file mode 100644 index 000000000000..1f6193a3b14b --- /dev/null +++ b/boards/framework/framework_ledmatrix/Kconfig.defconfig @@ -0,0 +1,19 @@ +# Copyright (c) 2025 Framework Computer Inc +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_FRAMEWORK_LEDMATRIX + +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_FRAMEWORK_LEDMATRIX diff --git a/boards/framework/framework_ledmatrix/Kconfig.framework_ledmatrix b/boards/framework/framework_ledmatrix/Kconfig.framework_ledmatrix new file mode 100644 index 000000000000..4c3e54ff04ac --- /dev/null +++ b/boards/framework/framework_ledmatrix/Kconfig.framework_ledmatrix @@ -0,0 +1,5 @@ +# Copyright (c) 2025 Framework Computer Inc +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_FRAMEWORK_LEDMATRIX + select SOC_RP2040 diff --git a/boards/framework/framework_ledmatrix/board.cmake b/boards/framework/framework_ledmatrix/board.cmake new file mode 100644 index 000000000000..affc290a869d --- /dev/null +++ b/boards/framework/framework_ledmatrix/board.cmake @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright (c) 2023 TOKITA Hiroshi + +board_runner_args(uf2 "--board-id=RPI-RP2") + +include(${ZEPHYR_BASE}/boards/common/uf2.board.cmake) diff --git a/boards/framework/framework_ledmatrix/board.yml b/boards/framework/framework_ledmatrix/board.yml new file mode 100644 index 000000000000..8af63ebc061f --- /dev/null +++ b/boards/framework/framework_ledmatrix/board.yml @@ -0,0 +1,6 @@ +board: + name: framework_ledmatrix + full_name: Framework LED Matrix + vendor: framework + socs: + - name: rp2040 diff --git a/boards/framework/framework_ledmatrix/doc/img/framework_ledmatrix.webp b/boards/framework/framework_ledmatrix/doc/img/framework_ledmatrix.webp new file mode 100644 index 0000000000000000000000000000000000000000..dbea55283f8de33943b422564af9efcbf8e44262 GIT binary patch literal 57284 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 F006E=6pa7? literal 0 HcmV?d00001 diff --git a/boards/framework/framework_ledmatrix/doc/index.rst b/boards/framework/framework_ledmatrix/doc/index.rst new file mode 100644 index 000000000000..7dbc9f539b1b --- /dev/null +++ b/boards/framework/framework_ledmatrix/doc/index.rst @@ -0,0 +1,65 @@ +.. zephyr:board:: framework_ledmatrix + +Overview +******** + +The Framework Laptop 16 compatible LED Matrix module is based on an RP2040 MCU and has an array of +9x36 white PWM LEDs controlled by a Lumissil IS31FL3741A. + +Hardware +******** + +* Dual core Arm Cortex-M0+ processor running up to 133MHz +* 264KB on-chip SRAM +* 1MB on-board QSPI flash with XIP capabilities +* Built-in 9x36 white LED matrix +* 2 way DIP Switch - one for user control, one to stay in bootloader +* USB 1.1 controller (host/device) +* 8 Programmable I/O (PIO) for custom peripherals +* 1 Watchdog timer peripheral + +Supported Features +================== + +.. zephyr:board-supported-hw:: + +Programming and Debugging +************************* + +.. zephyr:board-supported-runners:: + +Flashing +======== + +Using UF2 +--------- + +Here is an example of building the sample for enabling USB console. + +.. zephyr-app-commands:: + :zephyr-app: samples/subsys/usb/console + :board: framework_ledmatrix + :goals: build + :compact: + +You must flash the LED Matrix with an UF2 file. One option is to use West (Zephyr’s meta-tool). To +enter the UF2 flashing mode, remove the module flip the dip switch 2 and assemble it again. It will +appear on the host as a mass storage device. At this point you can flash the image file by running: + +.. code-block:: bash + + west flash + +After flashing, switch the DIP switch back again to run the firmware. + +Alternatively, you can locate the generated :file:`build/zephyr/zephyr.uf2` file and simply +drag-and-drop to the device after entering the UF2 flashing mode. + +References +********** + +* `Official Product Page`_ +* `Official Developer Documentation`_ + +.. _Official Product Page: https://frame.work/products/16-led-matrix +.. _Official Developer Documentation: https://github.com/FrameworkComputer/InputModules diff --git a/boards/framework/framework_ledmatrix/framework_ledmatrix-pinctrl.dtsi b/boards/framework/framework_ledmatrix/framework_ledmatrix-pinctrl.dtsi new file mode 100644 index 000000000000..f7cdac52e003 --- /dev/null +++ b/boards/framework/framework_ledmatrix/framework_ledmatrix-pinctrl.dtsi @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025 Framework Computer Inc + * SPDX-License-Identifier: Apache-2.0 + */ +#include + +&pinctrl { + i2c1_default: i2c1_default { + group1 { + pinmux = , + ; + input-enable; + input-schmitt-enable; + }; + }; +}; diff --git a/boards/framework/framework_ledmatrix/framework_ledmatrix.dts b/boards/framework/framework_ledmatrix/framework_ledmatrix.dts new file mode 100644 index 000000000000..5e4f4e862a04 --- /dev/null +++ b/boards/framework/framework_ledmatrix/framework_ledmatrix.dts @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2025 Framework Computer Inc + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include +#include +#include "framework_ledmatrix-pinctrl.dtsi" + +/ { + chosen { + zephyr,sram = &sram0; + zephyr,flash = &flash0; + zephyr,flash-controller = &ssi; + zephyr,code-partition = &code_partition; + }; + + aliases { + /* Alias to easily get the device in C */ + led-blank-switch = &lid_closed; + rtc = &rtc; + watchdog0 = &wdt0; + }; + + gpio_keys { + compatible = "gpio-keys"; + + /* Dip switch on the back - not normally accessible during usage */ + dip1: dip1 { + gpios = <&gpio0 25 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + zephyr,code = ; + label = "DIP1"; + }; + + /* Pin from the EC on the mainboard - low indicating lid of the laptop is closed */ + lid_closed: lid-closed { + gpios = <&gpio0 0 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + zephyr,code = ; + label = "Lid closed"; + }; + }; +}; + +&flash0 { + reg = <0x10000000 DT_SIZE_M(1)>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + /* Reserved memory for the second stage bootloader */ + second_stage_bootloader: partition@0 { + reg = <0x00000000 0x100>; + read-only; + }; + + /* + * Usable flash. Starts at 0x100, after the bootloader. The partition + * size is 1MB minus the 0x100 bytes taken by the bootloader. + */ + code_partition: partition@100 { + reg = <0x100 (DT_SIZE_M(1) - 0x100)>; + read-only; + }; + }; +}; + +&i2c1 { + status = "okay"; + pinctrl-0 = <&i2c1_default>; + pinctrl-names = "default"; + clock-frequency = ; + + is31fl3741@30 { + status = "okay"; + reg = <0x30>; + }; +}; + +&timer { + status = "okay"; +}; + +&wdt0 { + status = "okay"; +}; + +&rtc { + clocks = <&clocks RPI_PICO_CLKID_CLK_RTC>; + status = "okay"; +}; + +zephyr_udc0: &usbd { + status = "okay"; +}; + +&gpio0 { + status = "okay"; +}; + +&vreg { + regulator-always-on; + regulator-allowed-modes = ; +}; diff --git a/boards/framework/framework_ledmatrix/framework_ledmatrix.yaml b/boards/framework/framework_ledmatrix/framework_ledmatrix.yaml new file mode 100644 index 000000000000..ae933fa5deff --- /dev/null +++ b/boards/framework/framework_ledmatrix/framework_ledmatrix.yaml @@ -0,0 +1,18 @@ +identifier: framework_ledmatrix +name: Framework Laptop 16 LED Matrix +type: mcu +arch: arm +flash: 1024 +ram: 264 +toolchain: + - zephyr +supported: + - i2c + - gpio + - usb_device + - watchdog + - hwinfo + - dma + - counter + - clock +vendor: framework diff --git a/boards/framework/framework_ledmatrix/framework_ledmatrix_defconfig b/boards/framework/framework_ledmatrix/framework_ledmatrix_defconfig new file mode 100644 index 000000000000..1af1e54e1836 --- /dev/null +++ b/boards/framework/framework_ledmatrix/framework_ledmatrix_defconfig @@ -0,0 +1,16 @@ +# Copyright (c) 2025 Framework Computer Inc +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SERIAL=y +CONFIG_CONSOLE=y + +# Enable reset by default +CONFIG_RESET=y +CONFIG_CLOCK_CONTROL=y + +# Code partition needed to target the correct flash range +CONFIG_USE_DT_CODE_PARTITION=y + +# Output UF2 by default, maskrom bootloader supports it. +CONFIG_BUILD_OUTPUT_UF2=y +CONFIG_BUILD_OUTPUT_HEX=y From e64a7a28178c6c5b1ce1ab3cb8e60bdb10110534 Mon Sep 17 00:00:00 2001 From: Daniel Schaefer Date: Sun, 18 Jan 2026 00:05:32 +0800 Subject: [PATCH 1959/3659] boards: framework: Remove unnecessary figure Requested during code review to remove. Apparently zephyr:board:: automatically does it. Signed-off-by: Daniel Schaefer --- boards/framework/laptop16_keyboard/doc/index.rst | 4 ---- 1 file changed, 4 deletions(-) diff --git a/boards/framework/laptop16_keyboard/doc/index.rst b/boards/framework/laptop16_keyboard/doc/index.rst index bdf4801ff41f..803755037623 100644 --- a/boards/framework/laptop16_keyboard/doc/index.rst +++ b/boards/framework/laptop16_keyboard/doc/index.rst @@ -17,10 +17,6 @@ and with per-key RGB or white backlight: * ISO Keyboard * Numpad -.. figure:: img/framework_laptop16_keyboard.webp - :align: center - :alt: Framework Laptop 16 Keyboard - Hardware ******** * Dual core Arm Cortex-M0+ processor running up to 133MHz From 7ade290225ae8d5375bff2a4d88bf62cd6d22d4f Mon Sep 17 00:00:00 2001 From: Neil Chen Date: Wed, 17 Dec 2025 11:16:27 +0800 Subject: [PATCH 1960/3659] boards: frdm_mcxc444: add flash support - enable flash support - verified tests/drivers/flash/common Signed-off-by: Neil Chen --- boards/nxp/frdm_mcxc444/frdm_mcxc444.dts | 29 ++++++++++++++++++++++++ dts/arm/nxp/nxp_mcxc_common.dtsi | 2 +- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/boards/nxp/frdm_mcxc444/frdm_mcxc444.dts b/boards/nxp/frdm_mcxc444/frdm_mcxc444.dts index 9e9fa9fbf9b0..b120147eb273 100644 --- a/boards/nxp/frdm_mcxc444/frdm_mcxc444.dts +++ b/boards/nxp/frdm_mcxc444/frdm_mcxc444.dts @@ -203,3 +203,32 @@ zephyr_udc0: &usb { &dac { status = "okay"; }; + +&flash0 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 DT_SIZE_K(64)>; + read-only; + }; + + slot0_partition: partition@10000 { + label = "image-0"; + reg = <0x00010000 DT_SIZE_K(80)>; + }; + + slot1_partition: partition@24000 { + label = "image-1"; + reg = <0x00024000 DT_SIZE_K(80)>; + }; + + storage_partition: partition@38000 { + label = "storage"; + reg = <0x00038000 DT_SIZE_K(32)>; + }; + }; +}; diff --git a/dts/arm/nxp/nxp_mcxc_common.dtsi b/dts/arm/nxp/nxp_mcxc_common.dtsi index 4803ed9f9047..2756aa6b7721 100644 --- a/dts/arm/nxp/nxp_mcxc_common.dtsi +++ b/dts/arm/nxp/nxp_mcxc_common.dtsi @@ -70,7 +70,7 @@ compatible = "nxp,kinetis-ftfa"; reg = <0x40020000 0x14>; interrupts = <5 0>; - status = "disabled"; + status = "okay"; #address-cells = <1>; #size-cells = <1>; fsec = <0xfe>; From 348cc0116dc16f29204c29eb4d72d625abd05622 Mon Sep 17 00:00:00 2001 From: Neil Chen Date: Fri, 12 Dec 2025 10:38:43 +0800 Subject: [PATCH 1961/3659] tests: drivers: flash: add flash test support for frdm_mcxac444 add erase_block and flash_map support for frdm_mcxc444 board Signed-off-by: Neil Chen --- tests/drivers/flash/erase_blocks/testcase.yaml | 1 + tests/subsys/storage/flash_map/testcase.yaml | 1 + 2 files changed, 2 insertions(+) diff --git a/tests/drivers/flash/erase_blocks/testcase.yaml b/tests/drivers/flash/erase_blocks/testcase.yaml index 4a6cdcf3aff6..6c3ed6e4eaf8 100644 --- a/tests/drivers/flash/erase_blocks/testcase.yaml +++ b/tests/drivers/flash/erase_blocks/testcase.yaml @@ -15,5 +15,6 @@ tests: - b_u585i_iot02a - nrf9160dk/nrf9160 - nrf5340dk/nrf5340/cpuapp + - frdm_mcxc444 integration_platforms: - nrf9160dk/nrf9160 diff --git a/tests/subsys/storage/flash_map/testcase.yaml b/tests/subsys/storage/flash_map/testcase.yaml index fd381e6034a8..c25f657cbb05 100644 --- a/tests/subsys/storage/flash_map/testcase.yaml +++ b/tests/subsys/storage/flash_map/testcase.yaml @@ -11,6 +11,7 @@ tests: - s32z2xxdc2/s32z270/rtu1 - s32z2xxdc2@D/s32z270/rtu0 - s32z2xxdc2@D/s32z270/rtu1 + - frdm_mcxc444 tags: flash_map integration_platforms: - native_sim From 84415a125221998fe48ccff736690876fd636684 Mon Sep 17 00:00:00 2001 From: Pieter De Gendt Date: Wed, 14 Jan 2026 15:05:35 +0100 Subject: [PATCH 1962/3659] boards: nxp: mimxrt1064_evk: Fix PWM polarity for user LED The user LED is active low, or when using the PWM, polarity inverted. Signed-off-by: Pieter De Gendt --- boards/nxp/mimxrt1064_evk/mimxrt1064_evk.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boards/nxp/mimxrt1064_evk/mimxrt1064_evk.dts b/boards/nxp/mimxrt1064_evk/mimxrt1064_evk.dts index 28f64e1f8339..8a836f73f989 100644 --- a/boards/nxp/mimxrt1064_evk/mimxrt1064_evk.dts +++ b/boards/nxp/mimxrt1064_evk/mimxrt1064_evk.dts @@ -85,7 +85,7 @@ compatible = "pwm-leds"; green_pwm_led: green_pwm_led { - pwms = <&flexpwm2_pwm3 0 PWM_MSEC(20) PWM_POLARITY_NORMAL>; + pwms = <&flexpwm2_pwm3 0 PWM_MSEC(20) PWM_POLARITY_INVERTED>; }; }; From 3dfe5a98f6d99d63cab90475bbff5932ee3cc4bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Thu, 19 Oct 2023 09:44:34 +0200 Subject: [PATCH 1963/3659] doc: code_data_relocation: Add syntax highlight to cmake snippets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix code-blocks that had improper syntax highlighting set Signed-off-by: Benjamin Cabé --- doc/kernel/code-relocation.rst | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/doc/kernel/code-relocation.rst b/doc/kernel/code-relocation.rst index 82f08d19a337..58fc89c0dd7e 100644 --- a/doc/kernel/code-relocation.rst +++ b/doc/kernel/code-relocation.rst @@ -69,7 +69,7 @@ for data copy operations from ROM to required memory type. .. note:: - function zephyr_code_relocate() can be called as many times as required. + function ``zephyr_code_relocate()`` can be called as many times as required. Additional Configurations ========================= @@ -79,7 +79,7 @@ This section shows additional configuration options that can be set in * If the memory is ``SRAM1``, ``SRAM2``, ``CCD``, or ``AON``, then place the full object in the sections. For example: - .. code-block:: none + .. code-block:: cmake zephyr_code_relocate(FILES src/file1.c LOCATION SRAM2) zephyr_code_relocate(FILES src/file2.c LOCATION SRAM) @@ -88,7 +88,7 @@ This section shows additional configuration options that can be set in ``_BSS`` or ``_NOINIT``, only the selected memory is placed in the required memory region. For example: - .. code-block:: none + .. code-block:: cmake zephyr_code_relocate(FILES src/file1.c LOCATION SRAM2_DATA) zephyr_code_relocate(FILES src/file2.c LOCATION SRAM2_TEXT) @@ -100,7 +100,7 @@ This section shows additional configuration options that can be set in * Multiple files can be passed to the ``FILES`` argument, or CMake generator expressions can be used to relocate a comma-separated list of files. - .. code-block:: none + .. code-block:: cmake file(GLOB sources "file*.c") zephyr_code_relocate(FILES ${sources} LOCATION SRAM) @@ -118,7 +118,7 @@ select the file's symbols when this one has been built with ``-ffunction-sections`` and ``-fdata-sections`` which is the case by default. - .. code-block:: none + .. code-block:: cmake zephyr_code_relocate(FILES src/file1.c FILTER ".*\\.func1|.*\\.func2" LOCATION SRAM2_TEXT) @@ -133,7 +133,7 @@ contain unused symbols, then they will not be discarded by the linker, even when it is invoked with ``--gc-sections``. If you'd like to override this behavior, you can pass ``NOKEEP`` to your ``zephyr_code_relocate()`` call. - .. code-block:: none + .. code-block:: cmake zephyr_code_relocate(FILES src/file1.c LOCATION SRAM2_TEXT NOKEEP) @@ -152,7 +152,7 @@ This example will place the .text section of the ``xip_external_flash.c`` file to the ``EXTFLASH`` memory region where it will be executed from (XIP). The .data will be relocated as usual into SRAM. - .. code-block:: none + .. code-block:: cmake zephyr_code_relocate(FILES src/xip_external_flash.c LOCATION EXTFLASH_TEXT NOCOPY) zephyr_code_relocate(FILES src/xip_external_flash.c LOCATION SRAM_DATA) @@ -164,7 +164,7 @@ Libraries can be relocated using the LIBRARY argument to ``zephyr_code_relocation()`` with the library name. For example, the following snippet will relocate serial drivers to SRAM2: - .. code-block:: none + .. code-block:: cmake zephyr_code_relocate(LIBRARY drivers__serial LOCATION SRAM2) From 2c81aef9242ea04a43350b9a0b57d7a3fe4d8925 Mon Sep 17 00:00:00 2001 From: Henrik Lindblom Date: Fri, 5 Sep 2025 14:48:44 +0300 Subject: [PATCH 1964/3659] dts: bindings: ads1x4s0x: add reference buffers Add boolean properties to control whether the reference voltage buffers are enabled or not. After reset the positive reference buffer is enabled and the negative is disabled. Signed-off-by: Henrik Lindblom --- dts/bindings/adc/ti,ads1x4s0x-base.yaml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/dts/bindings/adc/ti,ads1x4s0x-base.yaml b/dts/bindings/adc/ti,ads1x4s0x-base.yaml index be1070a76ee5..16b054dde113 100644 --- a/dts/bindings/adc/ti,ads1x4s0x-base.yaml +++ b/dts/bindings/adc/ti,ads1x4s0x-base.yaml @@ -50,5 +50,21 @@ properties: description: | bias voltage level: 0 - (AVDD+AVSS)/2, 1 - (AVDD+AVSS)/12 + positive-reference-buffer-disable: + type: boolean + description: | + Disables the positive reference buffer for all channels. Recommended when using external + reference voltage and V(REFPx) is close to AVDD. + + The positive reference buffer is enabled at reset. + + negative-reference-buffer-disable: + type: boolean + description: | + Disables the negative reference buffer for all channels. Recommended when using external + reference voltage and V(REFNx) is close to AVSS. + + The negative reference buffer is disabled at reset. + io-channel-cells: - input From 79e9b72534b97097d9deab6e1c1136626b5b3514 Mon Sep 17 00:00:00 2001 From: Henrik Lindblom Date: Fri, 5 Sep 2025 14:54:21 +0300 Subject: [PATCH 1965/3659] drivers: adc: ads1x4s0x: configure reference buffers Configure the reference buffers when using external reference voltage for a channel. For the internal reference the datasheet[1] recommends that the buffers are disabled and for external references they should be disabled if REFPx/REFNx is close to AVDD/AVSS. After reset the positive reference buffer is enabled and the negative is disabled. The default values correspond to the example circuit for a two-wire and four-wire PT100 RTD measurement with low-side reference.[2][3] The values configured by the driver are maybe a little opinionated, but the current behaviour is kept to avoid surprises for people that are happy with the drivers defaults. The change applies to both ads11xs0x and ads124xs0x series. Link: [1]: https://www.ti.com/lit/ds/symlink/ads124s08.pdf Link: [2]: https://www.ti.com/lit/an/sbaa329b/sbaa329b.pdf Link: [3]: https://www.ti.com/lit/an/sbaa336b/sbaa336b.pdf Signed-off-by: Henrik Lindblom --- drivers/adc/adc_ads1x4s0x.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/drivers/adc/adc_ads1x4s0x.c b/drivers/adc/adc_ads1x4s0x.c index 2b813583a3b9..6c668e466cc5 100644 --- a/drivers/adc/adc_ads1x4s0x.c +++ b/drivers/adc/adc_ads1x4s0x.c @@ -431,6 +431,8 @@ struct ads1x4s0x_config { const struct gpio_dt_spec gpio_start_sync; int idac_current; uint8_t vbias_level; + bool positive_ref_buf_disable; + bool negative_ref_buf_disable; uint8_t channels; uint8_t resolution; }; @@ -658,6 +660,8 @@ static int ads1x4s0x_channel_setup(const struct device *dev, ADS1X4S0X_REGISTER_DATARATE_DR_SET(data_rate, acquisition_time_value); } + uint8_t pos_ref_buf = config->positive_ref_buf_disable ? 0b1 : 0b0; + uint8_t neg_ref_buf = config->negative_ref_buf_disable ? 0b1 : 0b0; switch (channel_cfg->reference) { case ADC_REF_INTERNAL: /* disable negative reference buffer */ @@ -668,19 +672,19 @@ static int ads1x4s0x_channel_setup(const struct device *dev, ADS1X4S0X_REGISTER_REF_REFSEL_SET(reference_control, 0b10); break; case ADC_REF_EXTERNAL0: - /* enable negative reference buffer */ - ADS1X4S0X_REGISTER_REF_NOT_REFN_BUF_SET(reference_control, 0b0); - /* enable positive reference buffer */ - ADS1X4S0X_REGISTER_REF_NOT_REFP_BUF_SET(reference_control, 0b0); - /* use external reference 0*/ + /* configure negative reference buffer */ + ADS1X4S0X_REGISTER_REF_NOT_REFN_BUF_SET(reference_control, neg_ref_buf); + /* configure positive reference buffer */ + ADS1X4S0X_REGISTER_REF_NOT_REFP_BUF_SET(reference_control, pos_ref_buf); + /* use external reference 0 */ ADS1X4S0X_REGISTER_REF_REFSEL_SET(reference_control, 0b00); break; case ADC_REF_EXTERNAL1: - /* enable negative reference buffer */ - ADS1X4S0X_REGISTER_REF_NOT_REFN_BUF_SET(reference_control, 0b0); - /* enable positive reference buffer */ - ADS1X4S0X_REGISTER_REF_NOT_REFP_BUF_SET(reference_control, 0b0); - /* use external reference 0*/ + /* configure negative reference buffer */ + ADS1X4S0X_REGISTER_REF_NOT_REFN_BUF_SET(reference_control, neg_ref_buf); + /* configure positive reference buffer */ + ADS1X4S0X_REGISTER_REF_NOT_REFP_BUF_SET(reference_control, pos_ref_buf); + /* use external reference 1 */ ADS1X4S0X_REGISTER_REF_REFSEL_SET(reference_control, 0b01); break; default: @@ -1583,6 +1587,10 @@ BUILD_ASSERT(CONFIG_ADC_INIT_PRIORITY > CONFIG_SPI_INIT_PRIORITY, .gpio_start_sync = GPIO_DT_SPEC_INST_GET_OR(n, start_sync_gpios, {0}), \ .idac_current = DT_INST_PROP(n, idac_current), \ .vbias_level = DT_INST_PROP(n, vbias_level), \ + .positive_ref_buf_disable = \ + DT_INST_PROP(n, positive_reference_buffer_disable), \ + .negative_ref_buf_disable = \ + DT_INST_PROP(n, negative_reference_buffer_disable), \ .resolution = res, \ .channels = ch, \ }; \ From 58febe86903c24914adcc62c8affc16da68d0b9f Mon Sep 17 00:00:00 2001 From: Chay Guo Date: Wed, 17 Dec 2025 18:01:19 +0800 Subject: [PATCH 1966/3659] boards: nxp: doc: ke1xz: Correct system clock source and frequency The System clock was changed to LPFLL by commit 68937acbb8d633d55. Updated the clock source and frequency description in board documentation. Regarding boards: frdm_ke15z, frdm_ke17z, frdm_ke17z512 Signed-off-by: Chay Guo --- boards/nxp/frdm_ke15z/doc/index.rst | 2 +- boards/nxp/frdm_ke17z/doc/index.rst | 2 +- boards/nxp/frdm_ke17z512/doc/index.rst | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/boards/nxp/frdm_ke15z/doc/index.rst b/boards/nxp/frdm_ke15z/doc/index.rst index 42a5f13050b5..a134482dabb3 100644 --- a/boards/nxp/frdm_ke15z/doc/index.rst +++ b/boards/nxp/frdm_ke15z/doc/index.rst @@ -37,7 +37,7 @@ Supported Features System Clock ============ -The KE15 SoC is configured to run at 48 MHz using the FIRC. +The KE15 SoC is configured to run at 72 MHz using the LPFLL. Serial Port =========== diff --git a/boards/nxp/frdm_ke17z/doc/index.rst b/boards/nxp/frdm_ke17z/doc/index.rst index f99b6b7ac776..5e1d505f79db 100644 --- a/boards/nxp/frdm_ke17z/doc/index.rst +++ b/boards/nxp/frdm_ke17z/doc/index.rst @@ -39,7 +39,7 @@ Supported Features System Clock ============ -The KE17Z SoC is configured to run at 48 MHz using the FIRC. +The KE17Z SoC is configured to run at 72 MHz using the LPFLL. Serial Port =========== diff --git a/boards/nxp/frdm_ke17z512/doc/index.rst b/boards/nxp/frdm_ke17z512/doc/index.rst index 710564561c2e..ad7e82e07e3d 100644 --- a/boards/nxp/frdm_ke17z512/doc/index.rst +++ b/boards/nxp/frdm_ke17z512/doc/index.rst @@ -40,7 +40,7 @@ Supported Features System Clock ============ -The KE17Z9 SoC is configured to run at 48 MHz using the FIRC. +The KE17Z9 SoC is configured to run at 72 MHz using the LPFLL. Serial Port =========== From 43d73f19bdc14cfefc1a06299468c4e0eb94e0c2 Mon Sep 17 00:00:00 2001 From: Chay Guo Date: Wed, 17 Dec 2025 18:08:50 +0800 Subject: [PATCH 1967/3659] boards: nxp: frdm_ke15z: Support ADC feature. Enable ADC0 CH0 as input channel Tested with tests/drivers/adc/adc_api/ on frdm_ke15z Signed-off-by: Chay Guo --- boards/nxp/frdm_ke15z/frdm_ke15z-pinctrl.dtsi | 8 +++++++ boards/nxp/frdm_ke15z/frdm_ke15z.dts | 8 +++++++ boards/nxp/frdm_ke15z/frdm_ke15z.yaml | 1 + .../adc/adc_api/boards/frdm_ke15z.overlay | 24 +++++++++++++++++++ 4 files changed, 41 insertions(+) create mode 100644 tests/drivers/adc/adc_api/boards/frdm_ke15z.overlay diff --git a/boards/nxp/frdm_ke15z/frdm_ke15z-pinctrl.dtsi b/boards/nxp/frdm_ke15z/frdm_ke15z-pinctrl.dtsi index 78f93888f925..0e94db0b02fa 100644 --- a/boards/nxp/frdm_ke15z/frdm_ke15z-pinctrl.dtsi +++ b/boards/nxp/frdm_ke15z/frdm_ke15z-pinctrl.dtsi @@ -6,6 +6,14 @@ #include &pinctrl { + adc0_default: adc0_default { + group0 { + pinmux = ; + drive-strength = "low"; + slew-rate = "slow"; + }; + }; + lpuart1_default: lpuart1_default { group0 { pinmux = , diff --git a/boards/nxp/frdm_ke15z/frdm_ke15z.dts b/boards/nxp/frdm_ke15z/frdm_ke15z.dts index 68d5f27ba71c..2085cda99cd4 100644 --- a/boards/nxp/frdm_ke15z/frdm_ke15z.dts +++ b/boards/nxp/frdm_ke15z/frdm_ke15z.dts @@ -102,6 +102,14 @@ pinctrl-names = "default"; }; +&adc0 { + status = "okay"; + sample-time = <12>; + vref-mv = <3300>; + pinctrl-0 = <&adc0_default>; + pinctrl-names = "default"; +}; + &gpiob { status = "okay"; }; diff --git a/boards/nxp/frdm_ke15z/frdm_ke15z.yaml b/boards/nxp/frdm_ke15z/frdm_ke15z.yaml index c7296fc12ea3..c739f958a58c 100644 --- a/boards/nxp/frdm_ke15z/frdm_ke15z.yaml +++ b/boards/nxp/frdm_ke15z/frdm_ke15z.yaml @@ -8,6 +8,7 @@ toolchain: flash: 256 ram: 24 supported: + - adc - flash - gpio - uart diff --git a/tests/drivers/adc/adc_api/boards/frdm_ke15z.overlay b/tests/drivers/adc/adc_api/boards/frdm_ke15z.overlay new file mode 100644 index 000000000000..b8d04141d056 --- /dev/null +++ b/tests/drivers/adc/adc_api/boards/frdm_ke15z.overlay @@ -0,0 +1,24 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + zephyr,user { + io-channels = <&adc0 0>; + }; +}; + +&adc0 { + #address-cells = <1>; + #size-cells = <0>; + + channel@0 { + reg = <0>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; +}; From 035d0267416c0b62452e0de0a18ad3d8ce10bb88 Mon Sep 17 00:00:00 2001 From: Chay Guo Date: Fri, 19 Dec 2025 09:47:50 +0800 Subject: [PATCH 1968/3659] samples: nxp: frdm_ke15z: Enable ADC samples. ADC0 CH0 as input channel Enabled samples/drivers/adc on frdm_ke15z Signed-off-by: Chay Guo --- .../adc/adc_dt/boards/frdm_ke15z.overlay | 24 +++++++++++++++ samples/drivers/adc/adc_dt/sample.yaml | 1 + .../adc_sequence/boards/frdm_ke15z.overlay | 30 +++++++++++++++++++ samples/drivers/adc/adc_sequence/sample.yaml | 1 + 4 files changed, 56 insertions(+) create mode 100644 samples/drivers/adc/adc_dt/boards/frdm_ke15z.overlay create mode 100644 samples/drivers/adc/adc_sequence/boards/frdm_ke15z.overlay diff --git a/samples/drivers/adc/adc_dt/boards/frdm_ke15z.overlay b/samples/drivers/adc/adc_dt/boards/frdm_ke15z.overlay new file mode 100644 index 000000000000..b8d04141d056 --- /dev/null +++ b/samples/drivers/adc/adc_dt/boards/frdm_ke15z.overlay @@ -0,0 +1,24 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + zephyr,user { + io-channels = <&adc0 0>; + }; +}; + +&adc0 { + #address-cells = <1>; + #size-cells = <0>; + + channel@0 { + reg = <0>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; +}; diff --git a/samples/drivers/adc/adc_dt/sample.yaml b/samples/drivers/adc/adc_dt/sample.yaml index 693538ba5c87..b7e8d03b5199 100644 --- a/samples/drivers/adc/adc_dt/sample.yaml +++ b/samples/drivers/adc/adc_dt/sample.yaml @@ -46,6 +46,7 @@ tests: - slwrb4180a - xg27_rb4194a - xg29_rb4412a + - frdm_ke15z - frdm_mcxa346 - frdm_mcxa266 - frdm_mcxa366 diff --git a/samples/drivers/adc/adc_sequence/boards/frdm_ke15z.overlay b/samples/drivers/adc/adc_sequence/boards/frdm_ke15z.overlay new file mode 100644 index 000000000000..02a9f3145a24 --- /dev/null +++ b/samples/drivers/adc/adc_sequence/boards/frdm_ke15z.overlay @@ -0,0 +1,30 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright 2025 NXP + */ + +/ { + aliases { + adc0 = &adc0; + }; +}; + +&adc0 { + #address-cells = <1>; + #size-cells = <0>; + + /* + * To use this sample: + * - Connect ADC0 SE0 signal to voltage between 0~3.3V (J4 pin 2) + */ + + channel@0 { + reg = <0>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,vref-mv = <3300>; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; +}; diff --git a/samples/drivers/adc/adc_sequence/sample.yaml b/samples/drivers/adc/adc_sequence/sample.yaml index 5f3367675266..1d183d433a2e 100644 --- a/samples/drivers/adc/adc_sequence/sample.yaml +++ b/samples/drivers/adc/adc_sequence/sample.yaml @@ -26,6 +26,7 @@ tests: - ophelia4ev/nrf54l15/cpuapp - ucans32k1sic - s32k148_evb + - frdm_ke15z - frdm_mcxc242 - frdm_mcxe247 - siwx917_rb4342a From fa7037ca714548a2ed31b2991889bfde2f0c4ab0 Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Tue, 28 Oct 2025 15:55:29 -0600 Subject: [PATCH 1969/3659] input: pinnacle: Perform software reset on init Don't rely on power-on-reset for the connected device, issue a software reset on init to be sure we're reset before continuing. Signed-off-by: Peter Johanson --- drivers/input/input_pinnacle.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/drivers/input/input_pinnacle.c b/drivers/input/input_pinnacle.c index c576ee40603a..7d107e7de8c1 100644 --- a/drivers/input/input_pinnacle.c +++ b/drivers/input/input_pinnacle.c @@ -761,6 +761,22 @@ static int pinnacle_init(const struct device *dev) return -ENODEV; } + /* Clear CC */ + rc = pinnacle_write(dev, PINNACLE_REG_STATUS1, 0); + if (rc < 0) { + LOG_ERR("Failed to clear CC from STATUS1 register (%d)", rc); + return rc; + } + + k_usleep(50); + /* Datasheet: RESET bit is read-only, reality: write 1 for software reset */ + rc = pinnacle_write(dev, PINNACLE_REG_SYS_CONFIG1, PINNACLE_SYS_CONFIG1_RESET); + + if (rc < 0) { + LOG_ERR("Failed to write reset to SYS_CONFIG1 (%d)", rc); + return rc; + } + /* Wait until the calibration is completed (SW_CC is asserted) */ ret = WAIT_FOR(pinnacle_read(dev, PINNACLE_REG_STATUS1, &value) == 0 && (value & PINNACLE_STATUS1_SW_CC) == PINNACLE_STATUS1_SW_CC, @@ -768,7 +784,7 @@ static int pinnacle_init(const struct device *dev) PINNACLE_CALIBRATION_AWAIT_DELAY_POLL_US, k_sleep(K_USEC(PINNACLE_CALIBRATION_AWAIT_DELAY_POLL_US))); if (!ret) { - LOG_ERR("Failed to wait for calibration complition"); + LOG_ERR("Failed to wait for calibration completion"); return -EIO; } From a17503cb1746ab3b7dbdcf14eeee3c4c7d131193 Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Tue, 9 Dec 2025 01:33:51 -0700 Subject: [PATCH 1970/3659] drivers: input: Add sleep-mode-enable property for Pinnacle Add a new sleep-mode-enable property for the Cirque Pinnacle input driver, to enable the sleep-mode for those peripherals, which will go into a lower power state after 5 seconds with no fingers detected. Signed-off-by: Peter Johanson --- drivers/input/input_pinnacle.c | 9 ++++++++- dts/bindings/input/cirque,pinnacle-common.yaml | 6 ++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/input/input_pinnacle.c b/drivers/input/input_pinnacle.c index 7d107e7de8c1..ab7501b6f18b 100644 --- a/drivers/input/input_pinnacle.c +++ b/drivers/input/input_pinnacle.c @@ -174,6 +174,7 @@ struct pinnacle_config { enum pinnacle_sensitivity sensitivity; bool relative_mode; + bool sleep_mode_enable; uint8_t idle_packets_count; bool clipping_enabled; @@ -802,7 +803,12 @@ static int pinnacle_init(const struct device *dev) return -EIO; } - rc = pinnacle_write(dev, PINNACLE_REG_SYS_CONFIG1, 0x00); + value = 0x00; + if (config->sleep_mode_enable) { + value |= PINNACLE_SYS_CONFIG1_LOW_POWER_MODE; + } + + rc = pinnacle_write(dev, PINNACLE_REG_SYS_CONFIG1, value); if (rc) { LOG_ERR("Failed to write SysConfig1"); return rc; @@ -896,6 +902,7 @@ static int pinnacle_init(const struct device *dev) .relative_mode = DT_INST_ENUM_IDX(inst, data_mode), \ .sensitivity = DT_INST_ENUM_IDX(inst, sensitivity), \ .idle_packets_count = DT_INST_PROP(inst, idle_packets_count), \ + .sleep_mode_enable = DT_INST_PROP(inst, sleep_mode_enable), \ .clipping_enabled = DT_INST_PROP(inst, clipping_enable), \ .active_range_x_min = DT_INST_PROP(inst, active_range_x_min), \ .active_range_x_max = DT_INST_PROP(inst, active_range_x_max), \ diff --git a/dts/bindings/input/cirque,pinnacle-common.yaml b/dts/bindings/input/cirque,pinnacle-common.yaml index 9b2035385626..2487d417baab 100644 --- a/dts/bindings/input/cirque,pinnacle-common.yaml +++ b/dts/bindings/input/cirque,pinnacle-common.yaml @@ -44,6 +44,12 @@ properties: taps. When set to 0, no empty packets are sent. Supported values from 0 to 255. + sleep-mode-enable: + type: boolean + description: | + Enable sleep mode, allowing the hardware to enter a lower power mode + after 5 seconds with no finger detected. + clipping-enable: type: boolean description: | From 11b51eafe06dcd7b7701c37f19262145ec0cd28a Mon Sep 17 00:00:00 2001 From: Arunprasath P Date: Wed, 24 Dec 2025 10:21:37 +0530 Subject: [PATCH 1971/3659] dts: arm: microchip: Add AC node for PIC32CX-SG family devices Add Analog comparator node to enable Comparator G1 driver support on PIC32CX-SG devices. Signed-off-by: Arunprasath P --- .../pic32c/pic32cx_sg/common/pic32cx_sg.dtsi | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/dts/arm/microchip/pic32c/pic32cx_sg/common/pic32cx_sg.dtsi b/dts/arm/microchip/pic32c/pic32cx_sg/common/pic32cx_sg.dtsi index 6b7c83681a69..3bd4c33f7b16 100644 --- a/dts/arm/microchip/pic32c/pic32cx_sg/common/pic32cx_sg.dtsi +++ b/dts/arm/microchip/pic32c/pic32cx_sg/common/pic32cx_sg.dtsi @@ -257,6 +257,17 @@ status = "disabled"; }; + ac: ac@42002000 { + compatible = "microchip,ac-g1-comparator"; + reg = <0x42002000 0x26>; + interrupts = <122 0>; + interrupt-names = "ac"; + clocks = <&mclkperiph CLOCK_MCHP_MCLKPERIPH_ID_APBC_AC>, + <&gclkperiph CLOCK_MCHP_GCLKPERIPH_ID_AC>; + clock-names = "mclk", "gclk"; + status = "disabled"; + }; + tcc3: tcc@42001000 { compatible = "microchip,tcc-g1"; reg = <0x42001000 0x2000>; From c201b11a85f31e838e3d61aff762b2460e173df0 Mon Sep 17 00:00:00 2001 From: Arunprasath P Date: Wed, 24 Dec 2025 10:22:09 +0530 Subject: [PATCH 1972/3659] boards: microchip: pic32cx_sg41_cult: Add comparator support Update pic32cx_sg41_cult.yml to include Comparator in the supported features list. Signed-off-by: Arunprasath P --- boards/microchip/pic32c/pic32cx_sg41_cult/pic32cx_sg41_cult.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/boards/microchip/pic32c/pic32cx_sg41_cult/pic32cx_sg41_cult.yaml b/boards/microchip/pic32c/pic32cx_sg41_cult/pic32cx_sg41_cult.yaml index 937aaa1b226d..84620b22ed61 100644 --- a/boards/microchip/pic32c/pic32cx_sg41_cult/pic32cx_sg41_cult.yaml +++ b/boards/microchip/pic32c/pic32cx_sg41_cult/pic32cx_sg41_cult.yaml @@ -11,6 +11,7 @@ flash: 1024 ram: 256 supported: - clock_control + - comparator - dma - flash - gpio From 33845c2e4447e4e98860d87ba7008fbcd34e2190 Mon Sep 17 00:00:00 2001 From: Arunprasath P Date: Wed, 24 Dec 2025 10:26:23 +0530 Subject: [PATCH 1973/3659] boards: microchip: pic32cx_sg61_cult: Add comparator support Update pic32cx_sg61_cult.yml to include Comparator in the supported features list. Signed-off-by: Arunprasath P --- boards/microchip/pic32c/pic32cx_sg61_cult/pic32cx_sg61_cult.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/boards/microchip/pic32c/pic32cx_sg61_cult/pic32cx_sg61_cult.yaml b/boards/microchip/pic32c/pic32cx_sg61_cult/pic32cx_sg61_cult.yaml index 6fb96788eea3..e9f012d4e06a 100644 --- a/boards/microchip/pic32c/pic32cx_sg61_cult/pic32cx_sg61_cult.yaml +++ b/boards/microchip/pic32c/pic32cx_sg61_cult/pic32cx_sg61_cult.yaml @@ -11,6 +11,7 @@ flash: 1024 ram: 256 supported: - clock_control + - comparator - dma - flash - gpio From f04a3cfa7a56e516a9cd9adea7d02611ebfb66b3 Mon Sep 17 00:00:00 2001 From: Arunprasath P Date: Wed, 24 Dec 2025 10:22:35 +0530 Subject: [PATCH 1974/3659] tests: comparator: microchip: Add board overlay file Add board overlay file for pic32cx_sg41_cult to enable comparator test cases to run on this board. Signed-off-by: Arunprasath P --- .../boards/pic32cx_sg41_cult.overlay | 42 +++++++++++++++++++ .../comparator/gpio_loopback/testcase.yaml | 4 ++ 2 files changed, 46 insertions(+) create mode 100644 tests/drivers/comparator/gpio_loopback/boards/pic32cx_sg41_cult.overlay diff --git a/tests/drivers/comparator/gpio_loopback/boards/pic32cx_sg41_cult.overlay b/tests/drivers/comparator/gpio_loopback/boards/pic32cx_sg41_cult.overlay new file mode 100644 index 000000000000..615f3d71ac6f --- /dev/null +++ b/tests/drivers/comparator/gpio_loopback/boards/pic32cx_sg41_cult.overlay @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* connect the PA04 to PA03 for the test */ + +/ { + aliases { + test-comp = ∾ + }; + + zephyr,user { + test-gpios = <&porta 3 GPIO_ACTIVE_HIGH>; + }; +}; + +&ac { + comparator-channel = <0>; + positive-mux-input = "pin0"; + negative-mux-input = "bandgap"; + run-standby; + hysteresis-enable; + hysteresis-level = "hyst150"; + filter-length = "maj5"; + // single-shot-mode; + + /* Assign pinctrl for PA04 */ + pinctrl-0 = <&pinctrl_ac>; + pinctrl-names = "default"; + + status = "okay"; +}; + +&pinctrl { + pinctrl_ac: ac_pins { + group1 { + pinmux = ; + }; + }; +}; diff --git a/tests/drivers/comparator/gpio_loopback/testcase.yaml b/tests/drivers/comparator/gpio_loopback/testcase.yaml index 0bb7c95758b0..59a18a7e1f41 100644 --- a/tests/drivers/comparator/gpio_loopback/testcase.yaml +++ b/tests/drivers/comparator/gpio_loopback/testcase.yaml @@ -64,3 +64,7 @@ tests: - frdm_mcxn947/mcxn947/cpu0 - mcx_n9xx_evk/mcxn947/cpu0/qspi - mcx_n9xx_evk/mcxn947/cpu0 + drivers.comparator.gpio_loopback.mchp: + platform_allow: + - sam_e54_xpro + - pic32cx_sg41_cult From 6e095400c2eaea0718434ef796560881640d3b11 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Fri, 14 Nov 2025 13:17:54 +0100 Subject: [PATCH 1975/3659] drivers: ethernet: stm32: use STM32_DT_INST_CLOCK_INFO_BY_NAME() Update STM32 ethernet driver to use STM32_DT_INST_CLOCK_INFO_BY_NAME() helper macro to always get all clock information, not only the bus ID and bit position. Signed-off-by: Etienne Carriere --- drivers/ethernet/eth_stm32_hal_common.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/ethernet/eth_stm32_hal_common.c b/drivers/ethernet/eth_stm32_hal_common.c index 728586a47805..d6ce55f62254 100644 --- a/drivers/ethernet/eth_stm32_hal_common.c +++ b/drivers/ethernet/eth_stm32_hal_common.c @@ -407,12 +407,10 @@ static const struct eth_stm32_hal_dev_cfg eth0_config = { .pclken_ptp = STM32_DT_INST_CLOCK_INFO_BY_NAME(0, mac_clk_ptp), #endif #if DT_INST_CLOCKS_HAS_NAME(0, mac_clk) - .pclken_mac = {.bus = DT_INST_CLOCKS_CELL_BY_NAME(0, mac_clk, bus), - .enr = DT_INST_CLOCKS_CELL_BY_NAME(0, mac_clk, bits)}, + .pclken_mac = STM32_DT_INST_CLOCK_INFO_BY_NAME(0, mac_clk), #endif #if DT_INST_CLOCKS_HAS_NAME(0, eth_ker) - .pclken_ker = {.bus = DT_INST_CLOCKS_CELL_BY_NAME(0, eth_ker, bus), - .enr = DT_INST_CLOCKS_CELL_BY_NAME(0, eth_ker, bits)}, + .pclken_ker = STM32_DT_INST_CLOCK_INFO_BY_NAME(0, eth_ker), #endif .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(0), }; From d965feeea461e1f26d1ad6e091333b713c312647 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Fri, 14 Nov 2025 16:56:29 +0100 Subject: [PATCH 1976/3659] drivers: ethernet: stm32: prepare move of MAC clocks to parent node Prepare move of STM23 ethernet MAC clocks to the controller node (parent node). For sake of simplicity, define a filed for all possible clocks in struct eth_stm32_hal_dev_cfg, a later change will replace the whole with a single STM32 clock instance (struct stm32_pclken) array pointer. Signed-off-by: Etienne Carriere --- drivers/ethernet/eth_dwmac_stm32h7x.c | 11 ++++++++-- drivers/ethernet/eth_stm32_hal_common.c | 29 +++++++++++++++---------- drivers/ethernet/eth_stm32_hal_priv.h | 6 ----- 3 files changed, 27 insertions(+), 19 deletions(-) diff --git a/drivers/ethernet/eth_dwmac_stm32h7x.c b/drivers/ethernet/eth_dwmac_stm32h7x.c index b4066f683147..8a915e06ccbe 100644 --- a/drivers/ethernet/eth_dwmac_stm32h7x.c +++ b/drivers/ethernet/eth_dwmac_stm32h7x.c @@ -32,9 +32,16 @@ PINCTRL_DT_INST_DEFINE(0); static const struct pinctrl_dev_config *eth0_pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(0); +/* Temporary helper macro to smooth moving clocks from mac node to controller (parent) node */ +#if DT_CLOCKS_HAS_NAME(DT_INST_PARENT(0), mac_clk_tx) +#define MAC_CLOCKS_NODE DT_INST_PARENT(0) +#else +#define MAC_CLOCKS_NODE DT_DRV_INST(0) +#endif + static const struct stm32_pclken pclken = STM32_CLOCK_INFO_BY_NAME(DT_INST_PARENT(0), stm_eth); -static const struct stm32_pclken pclken_tx = STM32_DT_INST_CLOCK_INFO_BY_NAME(0, mac_clk_tx); -static const struct stm32_pclken pclken_rx = STM32_DT_INST_CLOCK_INFO_BY_NAME(0, mac_clk_rx); +static const struct stm32_pclken pclken_tx = STM32_CLOCK_INFO_BY_NAME(MAC_CLOCKS_NODE, mac_clk_tx); +static const struct stm32_pclken pclken_rx = STM32_CLOCK_INFO_BY_NAME(MAC_CLOCKS_NODE, mac_clk_rx); int dwmac_bus_init(struct dwmac_priv *p) { diff --git a/drivers/ethernet/eth_stm32_hal_common.c b/drivers/ethernet/eth_stm32_hal_common.c index d6ce55f62254..534099e136b1 100644 --- a/drivers/ethernet/eth_stm32_hal_common.c +++ b/drivers/ethernet/eth_stm32_hal_common.c @@ -42,6 +42,13 @@ LOG_MODULE_REGISTER(eth_stm32_hal, CONFIG_ETHERNET_LOG_LEVEL); #define ETH_STM32_HAL_MTU NET_ETH_MTU #define ETH_STM32_HAL_FRAME_SIZE_MAX (ETH_STM32_HAL_MTU + 18) +/* Temporary helper macro to smooth moving clocks from mac node to controller (parent) node */ +#if DT_CLOCKS_HAS_NAME(DT_INST_PARENT(0), mac_clk_tx) +#define MAC_CLOCKS_NODE DT_INST_PARENT(0) +#else +#define MAC_CLOCKS_NODE DT_DRV_INST(0) +#endif + uint8_t dma_rx_buffer[ETH_RXBUFNB][ETH_STM32_RX_BUF_SIZE] __eth_stm32_buf; uint8_t dma_tx_buffer[ETH_TXBUFNB][ETH_STM32_TX_BUF_SIZE] __eth_stm32_buf; @@ -159,16 +166,16 @@ static int eth_initialize(const struct device *dev) (clock_control_subsys_t)&cfg->pclken_tx); ret |= clock_control_on(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE), (clock_control_subsys_t)&cfg->pclken_rx); -#if DT_INST_CLOCKS_HAS_NAME(0, mac_clk_ptp) +#if DT_CLOCKS_HAS_NAME(MAC_CLOCKS_NODE, mac_clk_ptp) ret |= clock_control_on(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE), (clock_control_subsys_t)&cfg->pclken_ptp); #endif -#if DT_INST_CLOCKS_HAS_NAME(0, eth_ker) +#if DT_CLOCKS_HAS_NAME(MAC_CLOCKS_NODE, eth_ker) ret |= clock_control_configure(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE), (clock_control_subsys_t)&cfg->pclken_ker, NULL); #endif -#if DT_INST_CLOCKS_HAS_NAME(0, mac_clk) +#if DT_CLOCKS_HAS_NAME(MAC_CLOCKS_NODE, mac_clk) ret |= clock_control_on(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE), (clock_control_subsys_t)&cfg->pclken_mac); #endif @@ -401,16 +408,16 @@ PINCTRL_DT_INST_DEFINE(0); static const struct eth_stm32_hal_dev_cfg eth0_config = { .config_func = eth0_irq_config, .pclken = STM32_CLOCK_INFO_BY_NAME(DT_INST_PARENT(0), stm_eth), - .pclken_tx = STM32_DT_INST_CLOCK_INFO_BY_NAME(0, mac_clk_tx), - .pclken_rx = STM32_DT_INST_CLOCK_INFO_BY_NAME(0, mac_clk_rx), -#if DT_INST_CLOCKS_HAS_NAME(0, mac_clk_ptp) - .pclken_ptp = STM32_DT_INST_CLOCK_INFO_BY_NAME(0, mac_clk_ptp), + .pclken_tx = STM32_CLOCK_INFO_BY_NAME(MAC_CLOCKS_NODE, mac_clk_tx), + .pclken_rx = STM32_CLOCK_INFO_BY_NAME(MAC_CLOCKS_NODE, mac_clk_rx), +#if DT_CLOCKS_HAS_NAME(MAC_CLOCKS_NODE, mac_clk_ptp) + .pclken_ptp = STM32_CLOCK_INFO_BY_NAME(MAC_CLOCKS_NODE, mac_clk_ptp), #endif -#if DT_INST_CLOCKS_HAS_NAME(0, mac_clk) - .pclken_mac = STM32_DT_INST_CLOCK_INFO_BY_NAME(0, mac_clk), +#if DT_CLOCKS_HAS_NAME(MAC_CLOCKS_NODE, mac_clk) + .pclken_mac = STM32_CLOCK_INFO_BY_NAME(MAC_CLOCKS_NODE, mac_clk), #endif -#if DT_INST_CLOCKS_HAS_NAME(0, eth_ker) - .pclken_ker = STM32_DT_INST_CLOCK_INFO_BY_NAME(0, eth_ker), +#if DT_CLOCKS_HAS_NAME(MAC_CLOCKS_NODE, eth_ker) + .pclken_ker = STM32_CLOCK_INFO_BY_NAME(MAC_CLOCKS_NODE, eth_ker), #endif .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(0), }; diff --git a/drivers/ethernet/eth_stm32_hal_priv.h b/drivers/ethernet/eth_stm32_hal_priv.h index 879fb35362e9..a0e7887497dd 100644 --- a/drivers/ethernet/eth_stm32_hal_priv.h +++ b/drivers/ethernet/eth_stm32_hal_priv.h @@ -105,17 +105,11 @@ extern ETH_DMADescTypeDef dma_tx_desc_tab[ETH_TXBUFNB]; struct eth_stm32_hal_dev_cfg { void (*config_func)(void); struct stm32_pclken pclken; -#if DT_INST_CLOCKS_HAS_NAME(0, mac_clk) struct stm32_pclken pclken_mac; -#endif -#if DT_INST_CLOCKS_HAS_NAME(0, eth_ker) struct stm32_pclken pclken_ker; -#endif struct stm32_pclken pclken_rx; struct stm32_pclken pclken_tx; -#if DT_INST_CLOCKS_HAS_NAME(0, mac_clk_ptp) struct stm32_pclken pclken_ptp; -#endif const struct pinctrl_dev_config *pcfg; }; From 0a49c46958eaa57554e32f2122b03647149e1e4d Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Fri, 14 Nov 2025 12:18:21 +0100 Subject: [PATCH 1977/3659] dts: arm: st: move ethernet clocks from mac to controller node Move the ethernet controller clocks from mac node to controller node. This change simplifies how clocks are gathered and handled in STM32 ethernet drivers. Signed-off-by: Etienne Carriere --- dts/arm/st/f1/stm32f107.dtsi | 9 ++++----- dts/arm/st/f2/stm32f207.dtsi | 12 +++++------- dts/arm/st/f4/stm32f407.dtsi | 12 +++++------- dts/arm/st/f7/stm32f745.dtsi | 12 +++++------- dts/arm/st/f7/stm32f765.dtsi | 12 +++++------- dts/arm/st/h5/stm32h563.dtsi | 9 ++++----- dts/arm/st/h7/stm32h7.dtsi | 9 ++++----- dts/arm/st/h7rs/stm32h7rs.dtsi | 9 ++++----- dts/arm/st/mp13/stm32mp13.dtsi | 13 ++++++------- dts/arm/st/n6/stm32n6.dtsi | 9 ++++----- dts/bindings/ethernet/st,stm32-ethernet-common.yaml | 4 ---- 11 files changed, 46 insertions(+), 64 deletions(-) diff --git a/dts/arm/st/f1/stm32f107.dtsi b/dts/arm/st/f1/stm32f107.dtsi index 0e4301aab3fe..fd4040365abe 100644 --- a/dts/arm/st/f1/stm32f107.dtsi +++ b/dts/arm/st/f1/stm32f107.dtsi @@ -21,15 +21,14 @@ ethernet@40028000 { reg = <0x40028000 0x2000>; - clock-names = "stm-eth"; - clocks = <&rcc STM32_CLOCK(AHB1, 14)>; + clock-names = "stm-eth", "mac-clk-tx", "mac-clk-rx"; + clocks = <&rcc STM32_CLOCK(AHB1, 14)>, + <&rcc STM32_CLOCK(AHB1, 15)>, + <&rcc STM32_CLOCK(AHB1, 16)>; mac: ethernet { compatible = "st,stm32-ethernet"; interrupts = <61 0>; - clock-names = "mac-clk-tx", "mac-clk-rx"; - clocks = <&rcc STM32_CLOCK(AHB1, 15)>, - <&rcc STM32_CLOCK(AHB1, 16)>; status = "disabled"; }; diff --git a/dts/arm/st/f2/stm32f207.dtsi b/dts/arm/st/f2/stm32f207.dtsi index c2414d9b253e..bc5e46044aa9 100644 --- a/dts/arm/st/f2/stm32f207.dtsi +++ b/dts/arm/st/f2/stm32f207.dtsi @@ -13,17 +13,15 @@ ethernet@40028000 { reg = <0x40028000 0x8000>; compatible = "st,stm32-ethernet-controller"; - clock-names = "stm-eth"; - clocks = <&rcc STM32_CLOCK(AHB1, 25)>; + clock-names = "stm-eth", "mac-clk-tx", "mac-clk-rx", "mac-clk-ptp"; + clocks = <&rcc STM32_CLOCK(AHB1, 25)>, + <&rcc STM32_CLOCK(AHB1, 26)>, + <&rcc STM32_CLOCK(AHB1, 27)>, + <&rcc STM32_CLOCK(AHB1, 28)>; mac: ethernet { compatible = "st,stm32-ethernet"; interrupts = <61 0>; - clock-names = "mac-clk-tx", "mac-clk-rx", - "mac-clk-ptp"; - clocks = <&rcc STM32_CLOCK(AHB1, 26)>, - <&rcc STM32_CLOCK(AHB1, 27)>, - <&rcc STM32_CLOCK(AHB1, 28)>; status = "disabled"; }; diff --git a/dts/arm/st/f4/stm32f407.dtsi b/dts/arm/st/f4/stm32f407.dtsi index f4ec4a6a128c..bb42e2d818c5 100644 --- a/dts/arm/st/f4/stm32f407.dtsi +++ b/dts/arm/st/f4/stm32f407.dtsi @@ -13,17 +13,15 @@ ethernet@40028000 { reg = <0x40028000 0x8000>; compatible = "st,stm32-ethernet-controller"; - clock-names = "stm-eth"; - clocks = <&rcc STM32_CLOCK(AHB1, 25)>; + clock-names = "stm-eth", "mac-clk-tx", "mac-clk-rx", "mac-clk-ptp"; + clocks = <&rcc STM32_CLOCK(AHB1, 25)>, + <&rcc STM32_CLOCK(AHB1, 26)>, + <&rcc STM32_CLOCK(AHB1, 27)>, + <&rcc STM32_CLOCK(AHB1, 28)>; mac: ethernet { compatible = "st,stm32-ethernet"; interrupts = <61 0>; - clock-names = "mac-clk-tx", "mac-clk-rx", - "mac-clk-ptp"; - clocks = <&rcc STM32_CLOCK(AHB1, 26)>, - <&rcc STM32_CLOCK(AHB1, 27)>, - <&rcc STM32_CLOCK(AHB1, 28)>; status = "disabled"; }; diff --git a/dts/arm/st/f7/stm32f745.dtsi b/dts/arm/st/f7/stm32f745.dtsi index b5e552d32aba..5651796c482b 100644 --- a/dts/arm/st/f7/stm32f745.dtsi +++ b/dts/arm/st/f7/stm32f745.dtsi @@ -79,17 +79,15 @@ ethernet@40028000 { reg = <0x40028000 0x8000>; compatible = "st,stm32-ethernet-controller"; - clock-names = "stm-eth"; - clocks = <&rcc STM32_CLOCK(AHB1, 25)>; + clock-names = "stm-eth", "mac-clk-tx", "mac-clk-rx", "mac-clk-ptp"; + clocks = <&rcc STM32_CLOCK(AHB1, 25)>, + <&rcc STM32_CLOCK(AHB1, 26)>, + <&rcc STM32_CLOCK(AHB1, 27)>, + <&rcc STM32_CLOCK(AHB1, 28)>; mac: ethernet { compatible = "st,stm32-ethernet"; interrupts = <61 0>; - clock-names = "mac-clk-tx", "mac-clk-rx", - "mac-clk-ptp"; - clocks = <&rcc STM32_CLOCK(AHB1, 26)>, - <&rcc STM32_CLOCK(AHB1, 27)>, - <&rcc STM32_CLOCK(AHB1, 28)>; status = "disabled"; }; diff --git a/dts/arm/st/f7/stm32f765.dtsi b/dts/arm/st/f7/stm32f765.dtsi index ebbbf5e5d557..a4c99c20d93a 100644 --- a/dts/arm/st/f7/stm32f765.dtsi +++ b/dts/arm/st/f7/stm32f765.dtsi @@ -72,17 +72,15 @@ ethernet@40028000 { reg = <0x40028000 0x8000>; compatible = "st,stm32-ethernet-controller"; - clock-names = "stm-eth"; - clocks = <&rcc STM32_CLOCK(AHB1, 25)>; + clock-names = "stm-eth", "mac-clk-tx", "mac-clk-rx", "mac-clk-ptp"; + clocks = <&rcc STM32_CLOCK(AHB1, 25)>, + <&rcc STM32_CLOCK(AHB1, 26)>, + <&rcc STM32_CLOCK(AHB1, 27)>, + <&rcc STM32_CLOCK(AHB1, 28)>; mac: ethernet { compatible = "st,stm32-ethernet"; interrupts = <61 0>; - clock-names = "mac-clk-tx", "mac-clk-rx", - "mac-clk-ptp"; - clocks = <&rcc STM32_CLOCK(AHB1, 26)>, - <&rcc STM32_CLOCK(AHB1, 27)>, - <&rcc STM32_CLOCK(AHB1, 28)>; status = "disabled"; }; diff --git a/dts/arm/st/h5/stm32h563.dtsi b/dts/arm/st/h5/stm32h563.dtsi index 0ace35b53608..39a58513fca3 100644 --- a/dts/arm/st/h5/stm32h563.dtsi +++ b/dts/arm/st/h5/stm32h563.dtsi @@ -23,16 +23,15 @@ ethernet@40028000 { reg = <0x40028000 0x8000>; compatible = "st,stm32-ethernet-controller"; - clock-names = "stm-eth"; - clocks = <&rcc STM32_CLOCK(AHB1, 19)>; + clock-names = "stm-eth", "mac-clk-tx", "mac-clk-rx"; + clocks = <&rcc STM32_CLOCK(AHB1, 19)>, + <&rcc STM32_CLOCK(AHB1, 20)>, + <&rcc STM32_CLOCK(AHB1, 21)>; mac: ethernet { compatible = "st,stm32h5-ethernet", "st,stm32h7-ethernet", "st,stm32-ethernet"; interrupts = <106 0>; - clock-names = "mac-clk-tx", "mac-clk-rx"; - clocks = <&rcc STM32_CLOCK(AHB1, 20)>, - <&rcc STM32_CLOCK(AHB1, 21)>; status = "disabled"; }; diff --git a/dts/arm/st/h7/stm32h7.dtsi b/dts/arm/st/h7/stm32h7.dtsi index d40aca13a6f6..08d42105c050 100644 --- a/dts/arm/st/h7/stm32h7.dtsi +++ b/dts/arm/st/h7/stm32h7.dtsi @@ -1123,15 +1123,14 @@ ethernet@40028000 { reg = <0x40028000 0x8000>; compatible = "st,stm32-ethernet-controller"; - clock-names = "stm-eth"; - clocks = <&rcc STM32_CLOCK(AHB1, 15)>; + clock-names = "stm-eth", "mac-clk-tx", "mac-clk-rx"; + clocks = <&rcc STM32_CLOCK(AHB1, 15)>, + <&rcc STM32_CLOCK(AHB1, 16)>, + <&rcc STM32_CLOCK(AHB1, 17)>; mac: ethernet { compatible = "st,stm32h7-ethernet", "st,stm32-ethernet"; interrupts = <61 0>; - clock-names = "mac-clk-tx", "mac-clk-rx"; - clocks = <&rcc STM32_CLOCK(AHB1, 16)>, - <&rcc STM32_CLOCK(AHB1, 17)>; memory-regions = <&sram2>; status = "disabled"; }; diff --git a/dts/arm/st/h7rs/stm32h7rs.dtsi b/dts/arm/st/h7rs/stm32h7rs.dtsi index ffbd2d0f9ff7..60471b063a31 100644 --- a/dts/arm/st/h7rs/stm32h7rs.dtsi +++ b/dts/arm/st/h7rs/stm32h7rs.dtsi @@ -925,15 +925,14 @@ ethernet@40028000 { reg = <0x40028000 0x8000>; compatible = "st,stm32-ethernet-controller"; - clock-names = "stm-eth"; - clocks = <&rcc STM32_CLOCK(AHB1, 15)>; + clock-names = "stm-eth", "mac-clk-tx", "mac-clk-rx"; + clocks = <&rcc STM32_CLOCK(AHB1, 15)>, + <&rcc STM32_CLOCK(AHB1, 16)>, + <&rcc STM32_CLOCK(AHB1, 17)>; mac: ethernet { compatible = "st,stm32h7-ethernet", "st,stm32-ethernet"; interrupts = <92 0>; - clock-names = "mac-clk-tx", "mac-clk-rx"; - clocks = <&rcc STM32_CLOCK(AHB1, 16)>, - <&rcc STM32_CLOCK(AHB1, 17)>; memory-regions = <&sram2>; status = "disabled"; }; diff --git a/dts/arm/st/mp13/stm32mp13.dtsi b/dts/arm/st/mp13/stm32mp13.dtsi index 8e309bece5a7..6779edf64dd0 100644 --- a/dts/arm/st/mp13/stm32mp13.dtsi +++ b/dts/arm/st/mp13/stm32mp13.dtsi @@ -250,19 +250,18 @@ eth0: ethernet@5800a000 { reg = <0x5800a000 0x2000>; compatible = "st,stm32-ethernet-controller"; - clock-names = "stm-eth"; - clocks = <&rcc STM32_CLOCK(AHB6, 7)>; + clock-names = "stm-eth", "mac-clk", "mac-clk-tx", "mac-clk-rx", "eth-ker"; + clocks = <&rcc STM32_CLOCK(AHB6, 7)>, + <&rcc STM32_CLOCK(AHB6, 8)>, + <&rcc STM32_CLOCK(AHB6, 9)>, + <&rcc STM32_CLOCK(AHB6, 10)>, + <&rcc STM32_SRC_PLL4_Q ETH1_SEL(0)>; mac: ethernet { compatible = "st,stm32mp13-ethernet", "st,stm32h7-ethernet", "st,stm32-ethernet"; interrupts = , ; - clock-names = "mac-clk", "mac-clk-tx", "mac-clk-rx", "eth-ker"; - clocks = <&rcc STM32_CLOCK(AHB6, 8)>, - <&rcc STM32_CLOCK(AHB6, 9)>, - <&rcc STM32_CLOCK(AHB6, 10)>, - <&rcc STM32_SRC_PLL4_Q ETH1_SEL(0)>; status = "disabled"; }; diff --git a/dts/arm/st/n6/stm32n6.dtsi b/dts/arm/st/n6/stm32n6.dtsi index fb0fc21847bb..f6d3e45744f4 100644 --- a/dts/arm/st/n6/stm32n6.dtsi +++ b/dts/arm/st/n6/stm32n6.dtsi @@ -787,16 +787,15 @@ ethernet@58036000 { reg = <0x58036000 0x8000>; compatible = "st,stm32-ethernet-controller"; - clock-names = "stm-eth"; - clocks = <&rcc STM32_CLOCK(AHB5, 22)>; + clock-names = "stm-eth", "mac-clk-tx", "mac-clk-rx"; + clocks = <&rcc STM32_CLOCK(AHB5, 22)>, + <&rcc STM32_CLOCK(AHB5, 23)>, + <&rcc STM32_CLOCK(AHB5, 24)>; mac: ethernet { compatible = "st,stm32n6-ethernet", "st,stm32h7-ethernet", "st,stm32-ethernet"; interrupts = <179 0>; - clock-names = "mac-clk-tx", "mac-clk-rx"; - clocks = <&rcc STM32_CLOCK(AHB5, 23)>, - <&rcc STM32_CLOCK(AHB5, 24)>; status = "disabled"; }; diff --git a/dts/bindings/ethernet/st,stm32-ethernet-common.yaml b/dts/bindings/ethernet/st,stm32-ethernet-common.yaml index 2ebaae6a481f..d90f1301232b 100644 --- a/dts/bindings/ethernet/st,stm32-ethernet-common.yaml +++ b/dts/bindings/ethernet/st,stm32-ethernet-common.yaml @@ -8,10 +8,6 @@ include: [ethernet-controller.yaml, pinctrl-device.yaml] properties: interrupts: required: true - clocks: - required: true - clock-names: - required: true pinctrl-0: required: true pinctrl-names: From c623c4544d447ac9f6cf2c30dc9611f50e4a684f Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Fri, 14 Nov 2025 16:59:28 +0100 Subject: [PATCH 1978/3659] drivers: ethernet: stm32: finalize move of clocks to controller node Remove helper macro used to transition from MAC clocks defined by the MAC node to definition in the controller (parent) node. Signed-off-by: Etienne Carriere --- drivers/ethernet/eth_dwmac_stm32h7x.c | 11 ++-------- drivers/ethernet/eth_stm32_hal_common.c | 29 ++++++++++--------------- 2 files changed, 13 insertions(+), 27 deletions(-) diff --git a/drivers/ethernet/eth_dwmac_stm32h7x.c b/drivers/ethernet/eth_dwmac_stm32h7x.c index 8a915e06ccbe..aa95ed92a2d6 100644 --- a/drivers/ethernet/eth_dwmac_stm32h7x.c +++ b/drivers/ethernet/eth_dwmac_stm32h7x.c @@ -32,16 +32,9 @@ PINCTRL_DT_INST_DEFINE(0); static const struct pinctrl_dev_config *eth0_pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(0); -/* Temporary helper macro to smooth moving clocks from mac node to controller (parent) node */ -#if DT_CLOCKS_HAS_NAME(DT_INST_PARENT(0), mac_clk_tx) -#define MAC_CLOCKS_NODE DT_INST_PARENT(0) -#else -#define MAC_CLOCKS_NODE DT_DRV_INST(0) -#endif - static const struct stm32_pclken pclken = STM32_CLOCK_INFO_BY_NAME(DT_INST_PARENT(0), stm_eth); -static const struct stm32_pclken pclken_tx = STM32_CLOCK_INFO_BY_NAME(MAC_CLOCKS_NODE, mac_clk_tx); -static const struct stm32_pclken pclken_rx = STM32_CLOCK_INFO_BY_NAME(MAC_CLOCKS_NODE, mac_clk_rx); +static const struct stm32_pclken pclken_tx = STM32_CLOCK_INFO_BY_NAME(DT_INST_PARENT(0), mac_clk_tx); +static const struct stm32_pclken pclken_rx = STM32_CLOCK_INFO_BY_NAME(DT_INST_PARENT(0), mac_clk_rx); int dwmac_bus_init(struct dwmac_priv *p) { diff --git a/drivers/ethernet/eth_stm32_hal_common.c b/drivers/ethernet/eth_stm32_hal_common.c index 534099e136b1..f2dc1d8267a0 100644 --- a/drivers/ethernet/eth_stm32_hal_common.c +++ b/drivers/ethernet/eth_stm32_hal_common.c @@ -42,13 +42,6 @@ LOG_MODULE_REGISTER(eth_stm32_hal, CONFIG_ETHERNET_LOG_LEVEL); #define ETH_STM32_HAL_MTU NET_ETH_MTU #define ETH_STM32_HAL_FRAME_SIZE_MAX (ETH_STM32_HAL_MTU + 18) -/* Temporary helper macro to smooth moving clocks from mac node to controller (parent) node */ -#if DT_CLOCKS_HAS_NAME(DT_INST_PARENT(0), mac_clk_tx) -#define MAC_CLOCKS_NODE DT_INST_PARENT(0) -#else -#define MAC_CLOCKS_NODE DT_DRV_INST(0) -#endif - uint8_t dma_rx_buffer[ETH_RXBUFNB][ETH_STM32_RX_BUF_SIZE] __eth_stm32_buf; uint8_t dma_tx_buffer[ETH_TXBUFNB][ETH_STM32_TX_BUF_SIZE] __eth_stm32_buf; @@ -166,16 +159,16 @@ static int eth_initialize(const struct device *dev) (clock_control_subsys_t)&cfg->pclken_tx); ret |= clock_control_on(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE), (clock_control_subsys_t)&cfg->pclken_rx); -#if DT_CLOCKS_HAS_NAME(MAC_CLOCKS_NODE, mac_clk_ptp) +#if DT_CLOCKS_HAS_NAME(DT_INST_PARENT(0), mac_clk_ptp) ret |= clock_control_on(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE), (clock_control_subsys_t)&cfg->pclken_ptp); #endif -#if DT_CLOCKS_HAS_NAME(MAC_CLOCKS_NODE, eth_ker) +#if DT_CLOCKS_HAS_NAME(DT_INST_PARENT(0), eth_ker) ret |= clock_control_configure(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE), (clock_control_subsys_t)&cfg->pclken_ker, NULL); #endif -#if DT_CLOCKS_HAS_NAME(MAC_CLOCKS_NODE, mac_clk) +#if DT_CLOCKS_HAS_NAME(DT_INST_PARENT(0), mac_clk) ret |= clock_control_on(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE), (clock_control_subsys_t)&cfg->pclken_mac); #endif @@ -408,16 +401,16 @@ PINCTRL_DT_INST_DEFINE(0); static const struct eth_stm32_hal_dev_cfg eth0_config = { .config_func = eth0_irq_config, .pclken = STM32_CLOCK_INFO_BY_NAME(DT_INST_PARENT(0), stm_eth), - .pclken_tx = STM32_CLOCK_INFO_BY_NAME(MAC_CLOCKS_NODE, mac_clk_tx), - .pclken_rx = STM32_CLOCK_INFO_BY_NAME(MAC_CLOCKS_NODE, mac_clk_rx), -#if DT_CLOCKS_HAS_NAME(MAC_CLOCKS_NODE, mac_clk_ptp) - .pclken_ptp = STM32_CLOCK_INFO_BY_NAME(MAC_CLOCKS_NODE, mac_clk_ptp), + .pclken_tx = STM32_CLOCK_INFO_BY_NAME(DT_INST_PARENT(0), mac_clk_tx), + .pclken_rx = STM32_CLOCK_INFO_BY_NAME(DT_INST_PARENT(0), mac_clk_rx), +#if DT_CLOCKS_HAS_NAME(DT_INST_PARENT(0), mac_clk_ptp) + .pclken_ptp = STM32_CLOCK_INFO_BY_NAME(DT_INST_PARENT(0), mac_clk_ptp), #endif -#if DT_CLOCKS_HAS_NAME(MAC_CLOCKS_NODE, mac_clk) - .pclken_mac = STM32_CLOCK_INFO_BY_NAME(MAC_CLOCKS_NODE, mac_clk), +#if DT_CLOCKS_HAS_NAME(DT_INST_PARENT(0), mac_clk) + .pclken_mac = STM32_CLOCK_INFO_BY_NAME(DT_INST_PARENT(0), mac_clk), #endif -#if DT_CLOCKS_HAS_NAME(MAC_CLOCKS_NODE, eth_ker) - .pclken_ker = STM32_CLOCK_INFO_BY_NAME(MAC_CLOCKS_NODE, eth_ker), +#if DT_CLOCKS_HAS_NAME(DT_INST_PARENT(0), eth_ker) + .pclken_ker = STM32_CLOCK_INFO_BY_NAME(DT_INST_PARENT(0), eth_ker), #endif .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(0), }; From 82ef82dff1c6cf34d743bf11d00ee874b6e64171 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Fri, 14 Nov 2025 10:20:16 +0100 Subject: [PATCH 1979/3659] drivers: ethernet: stm32: factorize clock handles MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Factorize STM32 interface clocks configuration in a single array. This change eases later integration of other SoCs with different clocks names while the driver only has to enable (possibly disable) the clocks on a single sequence. Suggested-by: Fin Maaß Signed-off-by: Etienne Carriere --- drivers/ethernet/eth_dwmac_stm32h7x.c | 16 +++---- drivers/ethernet/eth_stm32_hal_common.c | 63 ++++++++++++------------- drivers/ethernet/eth_stm32_hal_priv.h | 14 +++--- drivers/ethernet/eth_stm32_hal_ptp.c | 9 ++-- 4 files changed, 47 insertions(+), 55 deletions(-) diff --git a/drivers/ethernet/eth_dwmac_stm32h7x.c b/drivers/ethernet/eth_dwmac_stm32h7x.c index aa95ed92a2d6..690d0dbc6ecd 100644 --- a/drivers/ethernet/eth_dwmac_stm32h7x.c +++ b/drivers/ethernet/eth_dwmac_stm32h7x.c @@ -32,9 +32,7 @@ PINCTRL_DT_INST_DEFINE(0); static const struct pinctrl_dev_config *eth0_pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(0); -static const struct stm32_pclken pclken = STM32_CLOCK_INFO_BY_NAME(DT_INST_PARENT(0), stm_eth); -static const struct stm32_pclken pclken_tx = STM32_CLOCK_INFO_BY_NAME(DT_INST_PARENT(0), mac_clk_tx); -static const struct stm32_pclken pclken_rx = STM32_CLOCK_INFO_BY_NAME(DT_INST_PARENT(0), mac_clk_rx); +static const struct stm32_pclken pclken[] = STM32_DT_CLOCKS(DT_INST_PARENT(0)); int dwmac_bus_init(struct dwmac_priv *p) { @@ -48,12 +46,12 @@ int dwmac_bus_init(struct dwmac_priv *p) return -ENODEV; } - ret = clock_control_on(p->clock, (clock_control_subsys_t)&pclken); - ret |= clock_control_on(p->clock, (clock_control_subsys_t)&pclken_tx); - ret |= clock_control_on(p->clock, (clock_control_subsys_t)&pclken_rx); - if (ret) { - LOG_ERR("Failed to enable ethernet clock"); - return -EIO; + for (size_t n = 0; n < ARRAY_SIZE(pclken); n++) { + ret = clock_control_on(p->clock, (clock_control_subsys_t)&pclken[n]); + if (ret) { + LOG_ERR("Failed to enable ethernet clock #%zu", n); + return -EIO; + } } ret = pinctrl_apply_state(eth0_pcfg, PINCTRL_STATE_DEFAULT); diff --git a/drivers/ethernet/eth_stm32_hal_common.c b/drivers/ethernet/eth_stm32_hal_common.c index f2dc1d8267a0..ccdb586d8435 100644 --- a/drivers/ethernet/eth_stm32_hal_common.c +++ b/drivers/ethernet/eth_stm32_hal_common.c @@ -20,6 +20,7 @@ #include #include #include +#include #include "eth.h" #include "eth_stm32_hal_priv.h" @@ -152,30 +153,21 @@ static int eth_initialize(const struct device *dev) return -ENODEV; } - /* enable clock */ - ret = clock_control_on(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE), - (clock_control_subsys_t)&cfg->pclken); - ret |= clock_control_on(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE), - (clock_control_subsys_t)&cfg->pclken_tx); - ret |= clock_control_on(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE), - (clock_control_subsys_t)&cfg->pclken_rx); -#if DT_CLOCKS_HAS_NAME(DT_INST_PARENT(0), mac_clk_ptp) - ret |= clock_control_on(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE), - (clock_control_subsys_t)&cfg->pclken_ptp); -#endif -#if DT_CLOCKS_HAS_NAME(DT_INST_PARENT(0), eth_ker) - ret |= clock_control_configure(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE), - (clock_control_subsys_t)&cfg->pclken_ker, - NULL); -#endif -#if DT_CLOCKS_HAS_NAME(DT_INST_PARENT(0), mac_clk) - ret |= clock_control_on(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE), - (clock_control_subsys_t)&cfg->pclken_mac); -#endif + /* Enable clocks */ + for (size_t n = 0; n < cfg->pclken_cnt; n++) { + if (n == cfg->kclk_sel_idx) { + ret = clock_control_configure(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE), + (clock_control_subsys_t)&cfg->pclken[n], + NULL); + } else { + ret = clock_control_on(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE), + (clock_control_subsys_t)&cfg->pclken[n]); + } - if (ret) { - LOG_ERR("Failed to enable ethernet clock"); - return -EIO; + if (ret != 0) { + LOG_ERR("Failed to setup ethernet clock #%zu", n); + return -EIO; + } } /* configure pinmux */ @@ -398,19 +390,22 @@ static void eth0_irq_config(void) PINCTRL_DT_INST_DEFINE(0); +static const struct stm32_pclken eth0_pclken[] = STM32_DT_CLOCKS(DT_INST_PARENT(0)); + +#define ETH_STM32_HAS_PTP_CLOCK DT_CLOCKS_HAS_NAME(DT_INST_PARENT(0), mac_clk_ptp) + static const struct eth_stm32_hal_dev_cfg eth0_config = { .config_func = eth0_irq_config, - .pclken = STM32_CLOCK_INFO_BY_NAME(DT_INST_PARENT(0), stm_eth), - .pclken_tx = STM32_CLOCK_INFO_BY_NAME(DT_INST_PARENT(0), mac_clk_tx), - .pclken_rx = STM32_CLOCK_INFO_BY_NAME(DT_INST_PARENT(0), mac_clk_rx), -#if DT_CLOCKS_HAS_NAME(DT_INST_PARENT(0), mac_clk_ptp) - .pclken_ptp = STM32_CLOCK_INFO_BY_NAME(DT_INST_PARENT(0), mac_clk_ptp), -#endif -#if DT_CLOCKS_HAS_NAME(DT_INST_PARENT(0), mac_clk) - .pclken_mac = STM32_CLOCK_INFO_BY_NAME(DT_INST_PARENT(0), mac_clk), -#endif -#if DT_CLOCKS_HAS_NAME(DT_INST_PARENT(0), eth_ker) - .pclken_ker = STM32_CLOCK_INFO_BY_NAME(DT_INST_PARENT(0), eth_ker), + .pclken = eth0_pclken, + .pclken_cnt = DT_NUM_CLOCKS(DT_INST_PARENT(0)), + .kclk_sel_idx = COND_CODE_1(DT_PROP_HAS_NAME(DT_INST_PARENT(0), clocks, eth_ker), + (DT_PHA_ELEM_IDX_BY_NAME(DT_INST_PARENT(0), clocks, eth_ker)), + (UINT8_MAX)), +#ifdef CONFIG_PTP_CLOCK_STM32_HAL + /* If no PTP clock is defined, bus clock ("stm-eth") gives the ethernet clock rate */ + .rate_pclken_idx = DT_PHA_ELEM_IDX_BY_NAME(DT_INST_PARENT(0), clocks, + COND_CODE_1(ETH_STM32_HAS_PTP_CLOCK, + (mac_clk_ptp), (stm_eth))), #endif .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(0), }; diff --git a/drivers/ethernet/eth_stm32_hal_priv.h b/drivers/ethernet/eth_stm32_hal_priv.h index a0e7887497dd..4586200e3a73 100644 --- a/drivers/ethernet/eth_stm32_hal_priv.h +++ b/drivers/ethernet/eth_stm32_hal_priv.h @@ -104,12 +104,14 @@ extern ETH_DMADescTypeDef dma_tx_desc_tab[ETH_TXBUFNB]; /* Device constant configuration parameters */ struct eth_stm32_hal_dev_cfg { void (*config_func)(void); - struct stm32_pclken pclken; - struct stm32_pclken pclken_mac; - struct stm32_pclken pclken_ker; - struct stm32_pclken pclken_rx; - struct stm32_pclken pclken_tx; - struct stm32_pclken pclken_ptp; + const struct stm32_pclken *pclken; + uint8_t pclken_cnt; + /* Index of the clock used for kernel clock selection ("eth-ker"), or UINT8_MAX if none */ + uint8_t kclk_sel_idx; +#ifdef CONFIG_PTP_CLOCK_STM32_HAL + /* Index of the clock that gives the ethernet clock rate */ + uint8_t rate_pclken_idx; +#endif const struct pinctrl_dev_config *pcfg; }; diff --git a/drivers/ethernet/eth_stm32_hal_ptp.c b/drivers/ethernet/eth_stm32_hal_ptp.c index b6dea8ef3652..c34069af64a8 100644 --- a/drivers/ethernet/eth_stm32_hal_ptp.c +++ b/drivers/ethernet/eth_stm32_hal_ptp.c @@ -303,12 +303,9 @@ static int ptp_stm32_init(const struct device *port) eth_stm32_ptp_enable_timestamping(heth); /* Query ethernet clock rate */ - ret = clock_control_get_rate(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE), -#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) - (clock_control_subsys_t)ð_cfg->pclken, -#else - (clock_control_subsys_t)ð_cfg->pclken_ptp, -#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) */ + clock_control_subsys_t rate_clk = (void *)ð_cfg->pclken[eth_cfg->rate_pclken_idx]; + + ret = clock_control_get_rate(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE), rate_clk, &ptp_hclk_rate); if (ret) { LOG_ERR("Failed to query ethernet clock"); From 21cd98a5e1fab84db3ea58b33557fd5b0d416247 Mon Sep 17 00:00:00 2001 From: Thomas Hebb Date: Sat, 22 Nov 2025 01:54:28 -0500 Subject: [PATCH 1980/3659] drivers: sdhc: imx_usdhc: Extend all reset timeouts commit bf61a47887ba ("drivers: sdhc: imx_usdhc: extend reset timeout duration") extended the timeout from 100 iterations to 1000 iterations for the USDHC_Reset() call in imx_usdhc_reset() but not in the other places it's called. I have observed a "usdhc: Failed to reset command line" error from imx_usdhc_error_recovery() on an i.MX RT1061, which goes away if I extend the timeout. Do so there and also at other call sites for good measure. Signed-off-by: Thomas Hebb --- drivers/sdhc/imx_usdhc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/sdhc/imx_usdhc.c b/drivers/sdhc/imx_usdhc.c index c1f7a6a132e8..57eaa68060df 100644 --- a/drivers/sdhc/imx_usdhc.c +++ b/drivers/sdhc/imx_usdhc.c @@ -225,14 +225,14 @@ static void imx_usdhc_error_recovery(const struct device *dev) if (status & kUSDHC_CommandInhibitFlag) { /* Reset command line */ - if (!USDHC_Reset(base, kUSDHC_ResetCommand, 100U)) { + if (!USDHC_Reset(base, kUSDHC_ResetCommand, 1000U)) { LOG_ERR("Failed to reset command line"); } } if (((status & (uint32_t)kUSDHC_DataInhibitFlag) != 0U) || (USDHC_GetAdmaErrorStatusFlags(base) != 0U)) { /* Reset data line */ - if (!USDHC_Reset(base, kUSDHC_ResetData, 100U)) { + if (!USDHC_Reset(base, kUSDHC_ResetData, 1000U)) { LOG_ERR("Failed to reset data line"); } } @@ -654,7 +654,7 @@ static int imx_usdhc_execute_tuning(const struct device *dev) #endif /* Reset tuning circuit */ - USDHC_Reset(base, kUSDHC_ResetTuning, 100U); + USDHC_Reset(base, kUSDHC_ResetTuning, 1000U); /* Disable standard tuning */ USDHC_EnableStandardTuning(base, IMX_USDHC_STANDARD_TUNING_START, IMX_USDHC_TUNING_STEP, false); From 8564d10c75de7788a93c9762e2859fdeaf0a2485 Mon Sep 17 00:00:00 2001 From: Neil Chen Date: Mon, 8 Dec 2025 10:46:54 +0800 Subject: [PATCH 1981/3659] boards: nxp: frdm_mcxa344: Support lpi2c for NXP frdm_mcxa344 board Support lpi2c for NXP frdm_mcxa344 board. Signed-off-by: Neil Chen --- boards/nxp/frdm_mcxa344/board.c | 10 ++++++++ .../frdm_mcxa344/frdm_mcxa344-pinctrl.dtsi | 24 +++++++++++++++++++ boards/nxp/frdm_mcxa344/frdm_mcxa344.dts | 12 ++++++++++ boards/nxp/frdm_mcxa344/frdm_mcxa344.yaml | 1 + 4 files changed, 47 insertions(+) diff --git a/boards/nxp/frdm_mcxa344/board.c b/boards/nxp/frdm_mcxa344/board.c index 4163c88b0bd1..c3e49da42fdb 100644 --- a/boards/nxp/frdm_mcxa344/board.c +++ b/boards/nxp/frdm_mcxa344/board.c @@ -134,6 +134,16 @@ void board_early_init_hook(void) CLOCK_EnableClock(kCLOCK_GateGPIO4); #endif +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(lpi2c0)) + CLOCK_SetClockDiv(kCLOCK_DivLPI2C0, 1u); + CLOCK_AttachClk(kFRO_LF_DIV_to_LPI2C0); +#endif + +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(lpi2c1)) + CLOCK_SetClockDiv(kCLOCK_DivLPI2C1, 1u); + CLOCK_AttachClk(kFRO_LF_DIV_to_LPI2C1); +#endif + #if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(lptmr0)) /* diff --git a/boards/nxp/frdm_mcxa344/frdm_mcxa344-pinctrl.dtsi b/boards/nxp/frdm_mcxa344/frdm_mcxa344-pinctrl.dtsi index cc94e3423317..9a3e6599f03e 100644 --- a/boards/nxp/frdm_mcxa344/frdm_mcxa344-pinctrl.dtsi +++ b/boards/nxp/frdm_mcxa344/frdm_mcxa344-pinctrl.dtsi @@ -6,6 +6,30 @@ #include &pinctrl { + pinmux_lpi2c0: pinmux_lpi2c0 { + group0 { + pinmux = , + ; + slew-rate = "fast"; + drive-strength = "low"; + input-enable; + bias-pull-up; + drive-open-drain; + }; + }; + + pinmux_lpi2c1: pinmux_lpi2c1 { + group0 { + pinmux = , + ; + slew-rate = "fast"; + drive-strength = "low"; + input-enable; + bias-pull-up; + drive-open-drain; + }; + }; + pinmux_lpuart2: pinmux_lpuart2 { group0 { pinmux = , diff --git a/boards/nxp/frdm_mcxa344/frdm_mcxa344.dts b/boards/nxp/frdm_mcxa344/frdm_mcxa344.dts index 7ab11baf64ee..c0a39d1edf73 100644 --- a/boards/nxp/frdm_mcxa344/frdm_mcxa344.dts +++ b/boards/nxp/frdm_mcxa344/frdm_mcxa344.dts @@ -158,6 +158,18 @@ status = "okay"; }; +&lpi2c0 { + status = "okay"; + pinctrl-0 = <&pinmux_lpi2c0>; + pinctrl-names = "default"; +}; + +&lpi2c1 { + status = "okay"; + pinctrl-0 = <&pinmux_lpi2c1>; + pinctrl-names = "default"; +}; + &lptmr0 { status = "okay"; }; diff --git a/boards/nxp/frdm_mcxa344/frdm_mcxa344.yaml b/boards/nxp/frdm_mcxa344/frdm_mcxa344.yaml index d458aaa7dff1..18b3b74ca717 100644 --- a/boards/nxp/frdm_mcxa344/frdm_mcxa344.yaml +++ b/boards/nxp/frdm_mcxa344/frdm_mcxa344.yaml @@ -19,5 +19,6 @@ supported: - counter - flash - gpio + - i2c - uart vendor: nxp From 7d522e1064d7a1663dcef6a47690b160dda2fd86 Mon Sep 17 00:00:00 2001 From: Neil Chen Date: Thu, 15 Jan 2026 16:16:55 +0800 Subject: [PATCH 1982/3659] tests: drivers: i2c: add i2c test support for frdm_mcxa344 board add i2c test support for frdm_mcxa344 board Signed-off-by: Neil Chen --- .../boards/frdm_mcxa344.overlay | 26 +++++++++++++++++++ .../drivers/i2c/i2c_target_api/testcase.yaml | 1 + 2 files changed, 27 insertions(+) create mode 100644 tests/drivers/i2c/i2c_target_api/boards/frdm_mcxa344.overlay diff --git a/tests/drivers/i2c/i2c_target_api/boards/frdm_mcxa344.overlay b/tests/drivers/i2c/i2c_target_api/boards/frdm_mcxa344.overlay new file mode 100644 index 000000000000..d70dca164dac --- /dev/null +++ b/tests/drivers/i2c/i2c_target_api/boards/frdm_mcxa344.overlay @@ -0,0 +1,26 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* To test this sample, connect + * LPI2C0 SCL(J2-20) --> LPI2C1 SCL(J5-5) + * LPI2C0 SDA(J2-18) --> LPI2C1 SDA(J5-6) + */ + +&lpi2c0 { + eeprom0: eeprom@54 { + compatible = "zephyr,i2c-target-eeprom"; + reg = <0x54>; + size = <256>; + }; +}; + +&lpi2c1 { + eeprom1: eeprom@56 { + compatible = "zephyr,i2c-target-eeprom"; + reg = <0x56>; + size = <256>; + }; +}; diff --git a/tests/drivers/i2c/i2c_target_api/testcase.yaml b/tests/drivers/i2c/i2c_target_api/testcase.yaml index bbf6cb2ae104..77d15be20739 100644 --- a/tests/drivers/i2c/i2c_target_api/testcase.yaml +++ b/tests/drivers/i2c/i2c_target_api/testcase.yaml @@ -58,6 +58,7 @@ tests: - frdm_mcxa346 - frdm_mcxa266 - frdm_mcxa366 + - frdm_mcxa344 - frdm_mcxc242 - max32655evkit/max32655/m4 - max32662evkit From 9f866e17c9a108bc8f796ac8f8b839b1284b2ca5 Mon Sep 17 00:00:00 2001 From: Neil Chen Date: Mon, 8 Dec 2025 10:50:42 +0800 Subject: [PATCH 1983/3659] boards: nxp: frdm_mcxa344: Support lpspi for NXP frdm_mcxa344 board Support lpspi for NXP frdm_mcxa344 board. Signed-off-by: Neil Chen --- boards/nxp/frdm_mcxa344/board.c | 10 ++++++++ .../frdm_mcxa344/frdm_mcxa344-pinctrl.dtsi | 24 +++++++++++++++++++ boards/nxp/frdm_mcxa344/frdm_mcxa344.dts | 6 +++++ boards/nxp/frdm_mcxa344/frdm_mcxa344.yaml | 1 + 4 files changed, 41 insertions(+) diff --git a/boards/nxp/frdm_mcxa344/board.c b/boards/nxp/frdm_mcxa344/board.c index c3e49da42fdb..19f0ac984004 100644 --- a/boards/nxp/frdm_mcxa344/board.c +++ b/boards/nxp/frdm_mcxa344/board.c @@ -144,6 +144,16 @@ void board_early_init_hook(void) CLOCK_AttachClk(kFRO_LF_DIV_to_LPI2C1); #endif +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(lpspi0)) + CLOCK_SetClockDiv(kCLOCK_DivLPSPI0, 1u); + CLOCK_AttachClk(kFRO_LF_DIV_to_LPSPI0); +#endif + +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(lpspi1)) + CLOCK_SetClockDiv(kCLOCK_DivLPSPI1, 1u); + CLOCK_AttachClk(kFRO_LF_DIV_to_LPSPI1); +#endif + #if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(lptmr0)) /* diff --git a/boards/nxp/frdm_mcxa344/frdm_mcxa344-pinctrl.dtsi b/boards/nxp/frdm_mcxa344/frdm_mcxa344-pinctrl.dtsi index 9a3e6599f03e..75f68bf50fba 100644 --- a/boards/nxp/frdm_mcxa344/frdm_mcxa344-pinctrl.dtsi +++ b/boards/nxp/frdm_mcxa344/frdm_mcxa344-pinctrl.dtsi @@ -30,6 +30,30 @@ }; }; + pinmux_lpspi0: pinmux_lpspi0 { + group0 { + pinmux = , + , + , + ; + slew-rate = "fast"; + drive-strength = "low"; + input-enable; + }; + }; + + pinmux_lpspi1: pinmux_lpspi1 { + group0 { + pinmux = , + , + , + ; + slew-rate = "fast"; + drive-strength = "low"; + input-enable; + }; + }; + pinmux_lpuart2: pinmux_lpuart2 { group0 { pinmux = , diff --git a/boards/nxp/frdm_mcxa344/frdm_mcxa344.dts b/boards/nxp/frdm_mcxa344/frdm_mcxa344.dts index c0a39d1edf73..3c396ff49b7b 100644 --- a/boards/nxp/frdm_mcxa344/frdm_mcxa344.dts +++ b/boards/nxp/frdm_mcxa344/frdm_mcxa344.dts @@ -170,6 +170,12 @@ pinctrl-names = "default"; }; +&lpspi1 { + status = "okay"; + pinctrl-0 = <&pinmux_lpspi1>; + pinctrl-names = "default"; +}; + &lptmr0 { status = "okay"; }; diff --git a/boards/nxp/frdm_mcxa344/frdm_mcxa344.yaml b/boards/nxp/frdm_mcxa344/frdm_mcxa344.yaml index 18b3b74ca717..e299ab1a30ee 100644 --- a/boards/nxp/frdm_mcxa344/frdm_mcxa344.yaml +++ b/boards/nxp/frdm_mcxa344/frdm_mcxa344.yaml @@ -20,5 +20,6 @@ supported: - flash - gpio - i2c + - spi - uart vendor: nxp From f782c6e32e494a9666cd1eb989ac622c70c3f3cf Mon Sep 17 00:00:00 2001 From: Neil Chen Date: Thu, 11 Dec 2025 15:39:11 +0800 Subject: [PATCH 1984/3659] tests: drivers: spi: add spi test support for frdm_mcxa344 board add spi test support for frdm_mcxa344 board Signed-off-by: Neil Chen --- .../spi_loopback/boards/frdm_mcxa344.overlay | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 tests/drivers/spi/spi_loopback/boards/frdm_mcxa344.overlay diff --git a/tests/drivers/spi/spi_loopback/boards/frdm_mcxa344.overlay b/tests/drivers/spi/spi_loopback/boards/frdm_mcxa344.overlay new file mode 100644 index 000000000000..44c29e11c64d --- /dev/null +++ b/tests/drivers/spi/spi_loopback/boards/frdm_mcxa344.overlay @@ -0,0 +1,22 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* To test this sample, connect + * LPSPI1 MOSI(J2-8, P3_8/LPSPI1_SDO) --> LPSPI0 MISO(J2-10, P3_9/LPSPI1_SDI) + */ +&lpspi1 { + slow@0 { + compatible = "test-spi-loopback-slow"; + reg = <0>; + spi-max-frequency = <500000>; + }; + + fast@0 { + compatible = "test-spi-loopback-fast"; + reg = <0>; + spi-max-frequency = <16000000>; + }; +}; From c0473e1fbe089d03174a598e3226fda0afdcf1fa Mon Sep 17 00:00:00 2001 From: Neil Chen Date: Thu, 27 Nov 2025 14:06:16 +0800 Subject: [PATCH 1985/3659] boards: nxp: frdm_mcxa344: Support wwdt for NXP frdm_mcxa344 board Support watchdog for NXP frdm_mcxa344 board. Test using samples/drivers/watchdog. Signed-off-by: Neil Chen --- boards/nxp/frdm_mcxa344/board.c | 4 ++++ boards/nxp/frdm_mcxa344/frdm_mcxa344.dts | 5 +++++ boards/nxp/frdm_mcxa344/frdm_mcxa344.yaml | 1 + 3 files changed, 10 insertions(+) diff --git a/boards/nxp/frdm_mcxa344/board.c b/boards/nxp/frdm_mcxa344/board.c index 19f0ac984004..11caf4d28ad1 100644 --- a/boards/nxp/frdm_mcxa344/board.c +++ b/boards/nxp/frdm_mcxa344/board.c @@ -197,6 +197,10 @@ void board_early_init_hook(void) RESET_ReleasePeripheralReset(kLPUART3_RST_SHIFT_RSTn); #endif +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(wwdt0)) + CLOCK_SetClockDiv(kCLOCK_DivWWDT0, 1u); +#endif + /* Set SystemCoreClock variable. */ SystemCoreClock = CLOCK_INIT_CORE_CLOCK; } diff --git a/boards/nxp/frdm_mcxa344/frdm_mcxa344.dts b/boards/nxp/frdm_mcxa344/frdm_mcxa344.dts index 3c396ff49b7b..9e6433e974d7 100644 --- a/boards/nxp/frdm_mcxa344/frdm_mcxa344.dts +++ b/boards/nxp/frdm_mcxa344/frdm_mcxa344.dts @@ -21,6 +21,7 @@ led2 = &blue_led; sw0 = &user_button_2; sw1 = &user_button_3; + watchdog0 = &wwdt0; }; chosen { @@ -186,3 +187,7 @@ pinctrl-0 = <&pinmux_lpuart2>; pinctrl-names = "default"; }; + +&wwdt0 { + status = "okay"; +}; diff --git a/boards/nxp/frdm_mcxa344/frdm_mcxa344.yaml b/boards/nxp/frdm_mcxa344/frdm_mcxa344.yaml index e299ab1a30ee..80065d651ca4 100644 --- a/boards/nxp/frdm_mcxa344/frdm_mcxa344.yaml +++ b/boards/nxp/frdm_mcxa344/frdm_mcxa344.yaml @@ -22,4 +22,5 @@ supported: - i2c - spi - uart + - watchdog vendor: nxp From 8907c9ab8de0f550e53f446d85f74e99442673cd Mon Sep 17 00:00:00 2001 From: alperen sener Date: Wed, 20 Aug 2025 15:39:52 +0200 Subject: [PATCH 1986/3659] tests: Bluetooth: tester: Fix Central Address Resolution chr. read CAR characteristic read process was incomplete, CAR status was not actually stored. Added a new BTP_GAP_EV_PEER_CAR_RECEIVED to tester. This is to prevent disconnect events before IUT successfully reads CAR from central. Updated start_directed_advertising() so that if the central has no CAR support we must not send directed advertisements. IUT might enter another connectable mode according to specification, thus IUT starts sending connectable undirected advertisements with resovable address. Signed-off-by: alperen sener --- tests/bluetooth/tester/src/btp/btp_gap.h | 6 ++ tests/bluetooth/tester/src/btp_gap.c | 94 +++++++++++++++++++----- 2 files changed, 82 insertions(+), 18 deletions(-) diff --git a/tests/bluetooth/tester/src/btp/btp_gap.h b/tests/bluetooth/tester/src/btp/btp_gap.h index 1530d774e1c9..578a9f0be57f 100644 --- a/tests/bluetooth/tester/src/btp/btp_gap.h +++ b/tests/bluetooth/tester/src/btp/btp_gap.h @@ -619,6 +619,12 @@ struct btp_gap_periodic_biginfo_ev { uint8_t encryption; } __packed; +#define BTP_GAP_EV_PEER_CAR_RECEIVED 0x98 +struct btp_gap_peer_car_status_ev { + bt_addr_le_t address; + uint8_t car; +} __packed; + struct bt_le_per_adv_param; struct bt_le_per_adv_sync_param; struct bt_le_adv_param; diff --git a/tests/bluetooth/tester/src/btp_gap.c b/tests/bluetooth/tester/src/btp_gap.c index 4d0867b5a33f..bee8a44b168d 100644 --- a/tests/bluetooth/tester/src/btp_gap.c +++ b/tests/bluetooth/tester/src/btp_gap.c @@ -66,35 +66,65 @@ static struct bt_le_oob oob_sc_remote = { 0 }; #define REJECT_LATENCY 0x0000 #define REJECT_SUPERVISION_TIMEOUT 0x0C80 +/** + * Used to store CAR support status of bonded peer devices not every connected peer. + * So it is sufficient to have storage enough for CONFIG_BT_MAX_PAIRED. + * CAR status is only requested from peers that are bonded, because GATT CARR read is + * triggered in auth_pairing_complete callback. + * Thus GATT read callback calls add_to_peers_with_car and bond_deleted callback resets the + * CAR status when bond is deleted. + */ static struct { bt_addr_le_t addr; bool supported; -} cars[CONFIG_BT_MAX_PAIRED]; +} peers_with_car[CONFIG_BT_MAX_PAIRED]; + +static void add_to_peers_with_car(const bt_addr_le_t *addr, bool supported) +{ + /* Check if the peer is already in the list, update the supported state */ + for (int i = 0; i < CONFIG_BT_MAX_PAIRED; i++) { + if (bt_addr_le_eq(addr, &peers_with_car[i].addr)) { + peers_with_car[i].supported = supported; + return; + } + } + + /* If the peer is not in the list, add it */ + for (int i = 0; i < CONFIG_BT_MAX_PAIRED; i++) { + if (bt_addr_le_eq(&peers_with_car[i].addr, &bt_addr_le_any)) { + peers_with_car[i].supported = supported; + bt_addr_le_copy(&peers_with_car[i].addr, addr); + return; + } + } +} static uint8_t read_car_cb(struct bt_conn *conn, uint8_t err, struct bt_gatt_read_params *params, const void *data, uint16_t length) { + struct btp_gap_peer_car_status_ev ev; struct bt_conn_info info; bool supported = false; + ev.car = 0x00; + if (!err && data && length == 1) { const uint8_t *tmp = data; /* only 0 or 1 are valid values */ if (tmp[0] == 1) { supported = true; + ev.car = 0x01; } } bt_conn_get_info(conn, &info); - for (int i = 0; i < CONFIG_BT_MAX_PAIRED; i++) { - if (bt_addr_le_eq(info.le.dst, &cars[i].addr)) { - cars[i].supported = supported; - break; - } - } + add_to_peers_with_car(info.le.dst, supported); + + bt_addr_le_copy(&ev.address, info.le.dst); + tester_event(BTP_SERVICE_ID_GAP, BTP_GAP_EV_PEER_CAR_RECEIVED, &ev, sizeof(ev)); return BT_GATT_ITER_STOP; } @@ -967,31 +997,47 @@ static uint8_t start_advertising(const void *cmd, uint16_t cmd_len, return BTP_STATUS_SUCCESS; } +/** + * Start directed advertising with a peer address with or without RPA. + * If privacy is enabled and the peer does not support Central Address Resolution, + * the advertisement will be started as undirected with RPA. + */ static uint8_t start_directed_advertising(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) { const struct btp_gap_start_directed_adv_cmd *cp = cmd; struct btp_gap_start_directed_adv_rp *rp = rsp; - struct bt_le_adv_param adv_param; + struct bt_le_adv_param adv_param = BT_LE_ADV_PARAM_INIT( + BT_LE_ADV_OPT_CONN, BT_GAP_ADV_FAST_INT_MIN_2, BT_GAP_ADV_FAST_INT_MAX_2, NULL); uint16_t options = sys_le16_to_cpu(cp->options); - adv_param = *BT_LE_ADV_CONN_DIR(&cp->address); - - if (!(options & BTP_GAP_START_DIRECTED_ADV_HD)) { - adv_param.options |= BT_LE_ADV_OPT_DIR_MODE_LOW_DUTY; - adv_param.interval_max = BT_GAP_ADV_FAST_INT_MAX_2; - adv_param.interval_min = BT_GAP_ADV_FAST_INT_MIN_2; + if (bt_addr_le_eq(&cp->address, &bt_addr_le_any)) { + LOG_ERR("Invalid peer address"); + return BTP_STATUS_FAILED; } if (IS_ENABLED(CONFIG_BT_PRIVACY) && (options & BTP_GAP_START_DIRECTED_ADV_PEER_RPA)) { - /* check if peer supports Central Address Resolution */ + /** + * In accordance with the test spec for test case GAP/CONN/DCON/BV-05-C, if the peer + * does not support Central Address Resolution, the advertisement will be started + * as undirected. + */ for (int i = 0; i < CONFIG_BT_MAX_PAIRED; i++) { - if (bt_addr_le_eq(&cp->address, &cars[i].addr)) { - if (cars[i].supported) { - adv_param.options |= BT_LE_ADV_OPT_DIR_ADDR_RPA; + if (bt_addr_le_eq(&cp->address, &peers_with_car[i].addr) && + peers_with_car[i].supported) { + adv_param.options |= BT_LE_ADV_OPT_DIR_ADDR_RPA; + adv_param.peer = &cp->address; + if ((options & BTP_GAP_START_DIRECTED_ADV_HD) == 0U) { + adv_param.options |= BT_LE_ADV_OPT_DIR_MODE_LOW_DUTY; } + break; } } + } else { + adv_param.peer = &cp->address; + if ((options & BTP_GAP_START_DIRECTED_ADV_HD) == 0U) { + adv_param.options |= BT_LE_ADV_OPT_DIR_MODE_LOW_DUTY; + } } if (bt_le_adv_start(&adv_param, NULL, 0, NULL, 0) < 0) { @@ -1575,9 +1621,21 @@ static void auth_pairing_complete(struct bt_conn *conn, bool bonded) } } +static void bond_deleted(uint8_t id, const bt_addr_le_t *peer) +{ + for (int i = 0; i < CONFIG_BT_MAX_PAIRED; i++) { + if (bt_addr_le_eq(peer, &peers_with_car[i].addr)) { + peers_with_car[i].supported = false; + bt_addr_le_copy(&peers_with_car[i].addr, &bt_addr_le_any); + return; + } + } +} + static struct bt_conn_auth_info_cb auth_info_cb = { .pairing_failed = auth_pairing_failed, .pairing_complete = auth_pairing_complete, + .bond_deleted = bond_deleted, }; #if defined(CONFIG_BT_CLASSIC) From 0c169bb5eaa7f027f8d27600eb81e2b11d818a5d Mon Sep 17 00:00:00 2001 From: Jonas Berg Date: Sat, 3 Jan 2026 02:29:47 +0100 Subject: [PATCH 1987/3659] boards: Add support for DFRobot Beetle RP2350 Tested with the commands mentioned in index.rst Product photo from https://www.dfrobot.com/product-2913.html Signed-off-by: Jonas Berg --- .../beetle_rp2350/Kconfig.beetle_rp2350 | 6 + .../dfrobot/beetle_rp2350/Kconfig.defconfig | 9 ++ .../beetle_rp2350/beetle_rp2350-pinctrl.dtsi | 45 ++++++ .../dfrobot/beetle_rp2350/beetle_rp2350.dtsi | 120 +++++++++++++++ .../beetle_rp2350_rp2350a_hazard3.dts | 12 ++ .../beetle_rp2350_rp2350a_hazard3.yaml | 22 +++ .../beetle_rp2350_rp2350a_hazard3_defconfig | 13 ++ .../beetle_rp2350_rp2350a_m33.dts | 12 ++ .../beetle_rp2350_rp2350a_m33.yaml | 23 +++ .../beetle_rp2350_rp2350a_m33_defconfig | 13 ++ boards/dfrobot/beetle_rp2350/board.cmake | 27 ++++ boards/dfrobot/beetle_rp2350/board.yml | 6 + .../beetle_rp2350/doc/img/beetle_rp2350.webp | Bin 0 -> 20106 bytes boards/dfrobot/beetle_rp2350/doc/index.rst | 145 ++++++++++++++++++ .../dfrobot/beetle_rp2350/support/openocd.cfg | 11 ++ 15 files changed, 464 insertions(+) create mode 100644 boards/dfrobot/beetle_rp2350/Kconfig.beetle_rp2350 create mode 100644 boards/dfrobot/beetle_rp2350/Kconfig.defconfig create mode 100644 boards/dfrobot/beetle_rp2350/beetle_rp2350-pinctrl.dtsi create mode 100644 boards/dfrobot/beetle_rp2350/beetle_rp2350.dtsi create mode 100644 boards/dfrobot/beetle_rp2350/beetle_rp2350_rp2350a_hazard3.dts create mode 100644 boards/dfrobot/beetle_rp2350/beetle_rp2350_rp2350a_hazard3.yaml create mode 100644 boards/dfrobot/beetle_rp2350/beetle_rp2350_rp2350a_hazard3_defconfig create mode 100644 boards/dfrobot/beetle_rp2350/beetle_rp2350_rp2350a_m33.dts create mode 100644 boards/dfrobot/beetle_rp2350/beetle_rp2350_rp2350a_m33.yaml create mode 100644 boards/dfrobot/beetle_rp2350/beetle_rp2350_rp2350a_m33_defconfig create mode 100644 boards/dfrobot/beetle_rp2350/board.cmake create mode 100644 boards/dfrobot/beetle_rp2350/board.yml create mode 100644 boards/dfrobot/beetle_rp2350/doc/img/beetle_rp2350.webp create mode 100644 boards/dfrobot/beetle_rp2350/doc/index.rst create mode 100644 boards/dfrobot/beetle_rp2350/support/openocd.cfg diff --git a/boards/dfrobot/beetle_rp2350/Kconfig.beetle_rp2350 b/boards/dfrobot/beetle_rp2350/Kconfig.beetle_rp2350 new file mode 100644 index 000000000000..435fe5470e9a --- /dev/null +++ b/boards/dfrobot/beetle_rp2350/Kconfig.beetle_rp2350 @@ -0,0 +1,6 @@ +# Copyright (c) 2026 Jonas Berg +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_BEETLE_RP2350 + select SOC_RP2350A_HAZARD3 if BOARD_BEETLE_RP2350_RP2350A_HAZARD3 + select SOC_RP2350A_M33 if BOARD_BEETLE_RP2350_RP2350A_M33 diff --git a/boards/dfrobot/beetle_rp2350/Kconfig.defconfig b/boards/dfrobot/beetle_rp2350/Kconfig.defconfig new file mode 100644 index 000000000000..9e3f8d981e3d --- /dev/null +++ b/boards/dfrobot/beetle_rp2350/Kconfig.defconfig @@ -0,0 +1,9 @@ +# Copyright (c) 2025 Stephano Cetola +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_BEETLE_RP2350 + +config USB_SELF_POWERED + default n + +endif # BOARD_BEETLE_RP2350 diff --git a/boards/dfrobot/beetle_rp2350/beetle_rp2350-pinctrl.dtsi b/boards/dfrobot/beetle_rp2350/beetle_rp2350-pinctrl.dtsi new file mode 100644 index 000000000000..fa2c3ab0a1c8 --- /dev/null +++ b/boards/dfrobot/beetle_rp2350/beetle_rp2350-pinctrl.dtsi @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2026 Jonas Berg + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&pinctrl { + adc_default: adc_default { + group1 { + pinmux = , ; + input-enable; + }; + }; + + i2c0_default: i2c0_default { + group1 { + pinmux = , ; + input-enable; + }; + }; + + spi0_default: spi0_default { + group1 { + pinmux = , ; + }; + + group2 { + pinmux = ; + input-enable; + }; + }; + + uart0_default: uart0_default { + group1 { + pinmux = ; + }; + + group2 { + pinmux = ; + input-enable; + }; + }; +}; diff --git a/boards/dfrobot/beetle_rp2350/beetle_rp2350.dtsi b/boards/dfrobot/beetle_rp2350/beetle_rp2350.dtsi new file mode 100644 index 000000000000..e25285a27773 --- /dev/null +++ b/boards/dfrobot/beetle_rp2350/beetle_rp2350.dtsi @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2025 Stephano Cetola + * Copyright (c) 2026 Jonas Berg + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include + +#include +#include +#include +#include +#include "beetle_rp2350-pinctrl.dtsi" + +/ { + chosen { + zephyr,sram = &sram0; + zephyr,flash = &flash0; + zephyr,console = &uart0; + zephyr,shell-uart = &uart0; + }; + + aliases { + led0 = &red_led; + watchdog0 = &wdt0; + }; + + zephyr,user { + io-channels = <&adc 0>, <&adc 1>, <&adc 2>, <&adc 3>; + }; + + leds: leds { + compatible = "gpio-leds"; + + red_led: red_led { + gpios = <&gpio0 25 GPIO_ACTIVE_HIGH>; + label = "User LED"; + }; + }; +}; + +&flash0 { + reg = <0x10000000 DT_SIZE_M(2)>; +}; + +&gpio0 { + status = "okay"; +}; + +&uart0 { + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&uart0_default>; + pinctrl-names = "default"; +}; + +&i2c0 { + status = "okay"; + pinctrl-0 = <&i2c0_default>; + pinctrl-names = "default"; + clock-frequency = ; +}; + +&spi0 { + pinctrl-0 = <&spi0_default>; + pinctrl-names = "default"; + status = "okay"; +}; + +&adc { + status = "okay"; + pinctrl-0 = <&adc_default>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + + channel@0 { + reg = <0>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; + + channel@1 { + reg = <1>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; + + channel@2 { + reg = <2>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; + + channel@3 { + reg = <3>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; +}; + +&timer0 { + status = "okay"; +}; + +&wdt0 { + status = "okay"; +}; + +zephyr_udc0: &usbd { + status = "okay"; +}; diff --git a/boards/dfrobot/beetle_rp2350/beetle_rp2350_rp2350a_hazard3.dts b/boards/dfrobot/beetle_rp2350/beetle_rp2350_rp2350a_hazard3.dts new file mode 100644 index 000000000000..73e055defd82 --- /dev/null +++ b/boards/dfrobot/beetle_rp2350/beetle_rp2350_rp2350a_hazard3.dts @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2026 Jonas Berg + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include + +#include "beetle_rp2350.dtsi" diff --git a/boards/dfrobot/beetle_rp2350/beetle_rp2350_rp2350a_hazard3.yaml b/boards/dfrobot/beetle_rp2350/beetle_rp2350_rp2350a_hazard3.yaml new file mode 100644 index 000000000000..90055a10a847 --- /dev/null +++ b/boards/dfrobot/beetle_rp2350/beetle_rp2350_rp2350a_hazard3.yaml @@ -0,0 +1,22 @@ +identifier: beetle_rp2350/rp2350a/hazard3 +name: DFRobot Beetle RP2350 (Hazard3) +type: mcu +arch: riscv +flash: 2048 +ram: 520 +toolchain: + - zephyr +supported: + - adc + - clock + - counter + - dma + - flash + - gpio + - hwinfo + - i2c + - pwm + - spi + - uart + - usbd + - watchdog diff --git a/boards/dfrobot/beetle_rp2350/beetle_rp2350_rp2350a_hazard3_defconfig b/boards/dfrobot/beetle_rp2350/beetle_rp2350_rp2350a_hazard3_defconfig new file mode 100644 index 000000000000..85b60ee95c5a --- /dev/null +++ b/boards/dfrobot/beetle_rp2350/beetle_rp2350_rp2350a_hazard3_defconfig @@ -0,0 +1,13 @@ +# Copyright (c) 2026 Jonas Berg +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_BUILD_OUTPUT_HEX=y +CONFIG_BUILD_OUTPUT_UF2=y +CONFIG_CLOCK_CONTROL=y +CONFIG_CONSOLE=y +CONFIG_GPIO=y +CONFIG_RESET=y +CONFIG_SERIAL=y +CONFIG_UART_CONSOLE=y +CONFIG_UART_INTERRUPT_DRIVEN=y +CONFIG_USE_DT_CODE_PARTITION=y diff --git a/boards/dfrobot/beetle_rp2350/beetle_rp2350_rp2350a_m33.dts b/boards/dfrobot/beetle_rp2350/beetle_rp2350_rp2350a_m33.dts new file mode 100644 index 000000000000..48f9708428c4 --- /dev/null +++ b/boards/dfrobot/beetle_rp2350/beetle_rp2350_rp2350a_m33.dts @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2026 Jonas Berg + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include + +#include "beetle_rp2350.dtsi" diff --git a/boards/dfrobot/beetle_rp2350/beetle_rp2350_rp2350a_m33.yaml b/boards/dfrobot/beetle_rp2350/beetle_rp2350_rp2350a_m33.yaml new file mode 100644 index 000000000000..5d7fe671c516 --- /dev/null +++ b/boards/dfrobot/beetle_rp2350/beetle_rp2350_rp2350a_m33.yaml @@ -0,0 +1,23 @@ +identifier: beetle_rp2350/rp2350a/m33 +name: DFRobot Beetle RP2350 (Cortex M33) +type: mcu +arch: arm +flash: 2048 +ram: 520 +toolchain: + - zephyr + - gnuarmemb +supported: + - adc + - clock + - counter + - dma + - flash + - gpio + - hwinfo + - i2c + - pwm + - spi + - uart + - usbd + - watchdog diff --git a/boards/dfrobot/beetle_rp2350/beetle_rp2350_rp2350a_m33_defconfig b/boards/dfrobot/beetle_rp2350/beetle_rp2350_rp2350a_m33_defconfig new file mode 100644 index 000000000000..85b60ee95c5a --- /dev/null +++ b/boards/dfrobot/beetle_rp2350/beetle_rp2350_rp2350a_m33_defconfig @@ -0,0 +1,13 @@ +# Copyright (c) 2026 Jonas Berg +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_BUILD_OUTPUT_HEX=y +CONFIG_BUILD_OUTPUT_UF2=y +CONFIG_CLOCK_CONTROL=y +CONFIG_CONSOLE=y +CONFIG_GPIO=y +CONFIG_RESET=y +CONFIG_SERIAL=y +CONFIG_UART_CONSOLE=y +CONFIG_UART_INTERRUPT_DRIVEN=y +CONFIG_USE_DT_CODE_PARTITION=y diff --git a/boards/dfrobot/beetle_rp2350/board.cmake b/boards/dfrobot/beetle_rp2350/board.cmake new file mode 100644 index 000000000000..787e2850a863 --- /dev/null +++ b/boards/dfrobot/beetle_rp2350/board.cmake @@ -0,0 +1,27 @@ +# SPDX-License-Identifier: Apache-2.0 +# Adapted from boards/raspberrypi/rpi_pico2/board.cmake + +if("${RPI_PICO_DEBUG_ADAPTER}" STREQUAL "") + set(RPI_PICO_DEBUG_ADAPTER "cmsis-dap") +endif() + +board_runner_args(openocd --cmd-pre-init "source [find interface/${RPI_PICO_DEBUG_ADAPTER}.cfg]") +if(CONFIG_ARM) + board_runner_args(openocd --cmd-pre-init "source [find target/rp2350.cfg]") +else() + board_runner_args(openocd --cmd-pre-init "source [find target/rp2350-riscv.cfg]") +endif() + +# The adapter speed is expected to be set by interface configuration. +# The Raspberry Pi's OpenOCD fork doesn't, so match their documentation at +# https://www.raspberrypi.com/documentation/microcontrollers/debug-probe.html#debugging-with-swd +board_runner_args(openocd --cmd-pre-init "set_adapter_speed_if_not_set 5000") +board_runner_args(probe-rs "--chip=RP235x") +board_runner_args(jlink "--device=RP2350_M33_0") +board_runner_args(uf2 "--board-id=RP2350") + +# Default runner should be listed first +include(${ZEPHYR_BASE}/boards/common/uf2.board.cmake) +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) +include(${ZEPHYR_BASE}/boards/common/probe-rs.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/dfrobot/beetle_rp2350/board.yml b/boards/dfrobot/beetle_rp2350/board.yml new file mode 100644 index 000000000000..955f63413927 --- /dev/null +++ b/boards/dfrobot/beetle_rp2350/board.yml @@ -0,0 +1,6 @@ +board: + name: beetle_rp2350 + full_name: Beetle RP2350 + vendor: dfrobot + socs: + - name: rp2350a diff --git a/boards/dfrobot/beetle_rp2350/doc/img/beetle_rp2350.webp b/boards/dfrobot/beetle_rp2350/doc/img/beetle_rp2350.webp new file mode 100644 index 0000000000000000000000000000000000000000..7a09e59d05ea584522e2139263e26a27c1eaae04 GIT binary patch literal 20106 zcmV)YK&-z~Nk&G3P5=N`MM6+kP&goVP5=OqKmnZrD)a%B0Y05bol2@ICM79X+5oT< ziDz#7Q&}3{&~$7^wK3B%{PX>{_zzrI1odC={Q-T^{3qGcYEqtwNbiX+JR+Q3yXNK!>x57}r3MX#O!NJoPnOfRQ_`sOeh=_}gZv-h{|C&I z0utDI(rA;ft_Q&{J#&NqQ~{L!($mA`pu~YVo;|vsynl0LjVSwhH=ZaPTGJkw^v9+> zG3QFA_G-~3t=sRjyjONF(>OKW1rIb~vn5*A&qQ>FcOd;TfbJ!O3;N|ZN`9jMX7WHe zWVCUS`;pv^-3qNX&c@RcbM216yG=Od8?1J}{wcF>Lnb;;)^Xhcz8@NId$65sbp14;}7pMr6J4eU;dichjJez$G1{HP-m+{mf_*nQc zkK#xtY(s3jaqwyP77iuORYFU}`|sCA1>S}@2p9SO1+6<2N*luI ziSz*9vs_k5s)_LVrK>p-{#}By4I~h*6mYeTzFrJ-jC(2jWM7)4x?T)o`6Ul*x4CnxZKgZvT?^9Uslv~{7LJ|vMExbiK@z6jhhO9?N8-P0_( zO+l!D2eGIKi1XLPSY;Xamk*@0ICb>1UWEE#jl*xMN*N+zm$c}z7us@DLBa&g5~~EL z`Xc_8N0(Rf1+xZs(Yj1X%7@}IxUhp6k4}_jDYdzjoo}+4OvSv~>H^IA$dhN{Kem5^ z`tBs(yP+LR`=G<%YCF6iKbpO86m*XE{ZK+`A8h-HA0WBiW$<&kW>rO3?^A@D0GXxf zLN3TD80B+YFX9jTt`9Q*OH}EdGvWp;uzElaYmvR3xZH@5L6_7OH_`i_{iXn(XJfkm z&C8MVg}J$rx<;jXAc>A$#KXYgBt zU~-pu$MW1S0V5e~>VphWojrZ@d;2-*NDfw-m4*;eQ8nUhUVKW__Bb5(jBO9A<6gJJ zWFPu_CFLjzY%e7$XvJ()3MAI@hobh4z~InkOZS3S9E(a@1UsfJW?ih%1?FvqV%B4sMf}7tIhs$_AC3P-aBVou>mH2({*NK=l@sxVuH6Hw z`OZswOm*I44bf{#@%6g&hc^ThNR_q?Rv$~xTJgZ*=ygg8GvX_qt3x|ScFj5%woO); zyB|Oez(ZOYM5v0i&a#6h}uI>3zt9d7|ymr zVDEbp#C3OiTZH9)>~|TdOOzx(7gCkjLL{Ra!Ia=<2G{=*077w5glglNy)7`qEz6D) zoB%NO2dFQ$%%i37bMn150{9o9Umv+;s%NUv39TPygEmrZp!?;o+2zZ7L5#hL{)9Z2 zHLR*|Z>@B?&gZT?Pvp;iLJW@-$w6XYgm$rSX~#Hs^gA6{Gz)bkZ}S8F z8YbHCkF70Ofs45B&yMyt#4I~#GjkrA3rNkIrGzry)0VT@IQ8!h{aA8|Q6S(N!-7>T z;)Rf%%qKDmKcAd;{xSioh!w*2Y#TZ&Sr0Ytq;&fEbE)b{nEgAHW>iEgKacKVE&W#M zlNJ21Yu!X98*z8!!tIr6wBJ7T33(I2KU~^~-IzNX5_zc?f5~;QKWY&xJp60X)yA$a zqJ@7ed^r`@jJpAe|H13{q_6Nq2Xo8iW6)0N@*t?<-3vwroSN*S|>y`yfX%w_eZvL z2v#n!1cYn|#X~ch2ZYR#?q*^S@PC8mV1xTBz2tFqt6d5*e`J3@r88DNGeL&!6*@y@ z%e`8huSQ#jjt2pLxY-cq%X#Y#ur#{-dR14cLtnp1{)h-ff|~CvO)pzj=$EUa18Z7YGcCfE+Lz}KQS!IkJqgN~XEFaMRhx9+8{TjyJ)b%Oa zO`t$1SYt+IwZ0%=00W~_3{^(gn%ye%+2dhO=lCewe*2QDxtuEg}S9*Db)%tKTA& zet=?3<^=AbGEXz;pR z`H5eD8=}elcYP0pzntPEiLfRDqR1A=&ELo9Y2HcFj3^snF(HrizIG>9MWJSrX(xpc zcpxa>;0xF3-rqGont%WR4+GwlmQ71+RCvQbCBUbCo)<;F`8i8Z&lzn`z;bfwY%KQZ zi;V^P>`QfrE*nGR9O_3`ZQ4HsQ*8B9tBLBhlp%=D1g7%V#DT)$qVYjw~pJHK$< z8`bl+57>W{sid6i6O>Gn*Mg)gg36(3I zVrSyL#zbPi6J2{wXA_BqY8@l&Eeg(z^Bk-`5(m>)8yA7=yoeH*=4FA{Dmxwg)~fT- zWHJ)>^vIn`d>3Rt=;kAB?|NF+?Bm1qcArv?U{P~gQXr~Z<<<#R2sMsA!7LnrhJ&3* zA)ucNL>cV#MC1Sf8@WCE7K?_u(uWklgtm;0AS<0iC-&;M?C>!PzF6{N%>aL4?p!QEgk}!)|L=pX#h~N!cBhm_sQ5qW=R;;}tn= zN;2B4K8|1)p!N^iBlkf_wN#UcdFo@1-5=)X2Dw6X8(rePP`M&^?Ps zA}R5^Ok&}YrSQw%DAPr`G-2TRE82*zmt@xFQ~&_bd`%YoQekn2X)no*@fo?Ba`Cyi zgr=))D?hwYXqM1Lm>@~3S96cY`469BoKyN5MVc5zN(7tzHIO^D)Lij^H8;~w8H1AQ z%hzh(ww~a8MGoPmA04kta_Pn2Sr%J7F5Jfdy}DDpS6*{Y>azoo-?hhfyO_^bU<;-W z(Wu+queiU(pVQ+S2*g}2Lbg1+J=8TZG{>;V+Ywt(W;WxF`4ZMN0ydWBCk*AoHFp{|u@Bf|vK%h5E7mx=0){|ZQsl2G zEOHa7NJr@f<-AJ4H6E=82LXpKKpxuM$-=UN0z&wakRiJUvd2XudG!>ha`}~JUmaz$ z=;^a=%X?(X3Iyk)o&KD^uVB*~L>UiWEtz-Uzq@_fnpAxqhr(O<+&SElTu6VtP*b^9 zWa_2!6iEJA)xGhVR zgzRsC3W@kTg&_IBZnXP(To>o*ik>3VUBM=08(?V-Z=VKmEL z&Y}FaL2&*x-gSj@{txf7@lJJ+6GxBp+iKyEKR6DhJ@Km!MUhKNBLfqro>)#X9dW@f z>SjIKX!jG(<^>nNAv0CT$NwTJp``5e?}fM<4-=ZB6r97-gjR~c+DybdkKyHg7Q;F> zI%bFZ$!DROj9cBuP7g>F1Va_ti?87dr_R5CH z1v6HcW9pl><6Hu6wrjZLiq%Xt&Fr2N2gqKZPjQ)Z2Jag?r?&~sVZfDrB7jsPe^H>@ z=pn1Fu5|uN6u_}pt6+kKHZb+Z-C#GOLK$P&_ zQihkWA@({ntp2E&xi}(yQO!8kn=_r*Xnqt@g_4Or(6&-uEsEx1Q?vNyJlfp%fh(TM z872`(q%h|7ikc`NRs*M5v#m)Wp0kvn97?U(G?)PCy*dUz8wRI#|LV!R&)C&rouI#$ zQx~=C;WIo-nYKQktDYN9vM%%Z$Y4iduu4>k!GX2LevG=-1n*h-1S}Ip!XlaBUq(eG z#N?)!5eiR|7-^$y=1Jh&*fmh_i_`uZWNr}%{wIE!l~;s_6}j+c3u&suC(O%%rgio= z!o-B>PF=~lECh#2e$}1i6Kfa-9nO9`m_m=-2OdS4n48S`*X~hqE7w!#AuH3h7m75t z1JN?lJw$ngJ&Fe5R~HM7E@?!2yLaO6qLT4q9wthdy8+=Eo(My~humL^B`* z#PCCoV_>X?d@wQShWN9lj~vtQ<_Du}MadW$Jz5inaX1dr&cc_^N=!I=xhi~D*qS`O z4K}0QpVij%yhn8E1DAxuTK%mDEUH%a9a1q1iGQs~EhyvK2HwPC@AZHJ2evHxMa!%uF`NoT@((Y;Ezf z>rFpZhEdQM|GWwi*T{N17E&^HI?255es*s^VQRHWW+LrsOW?m9Sf0~ z1em;#iUf*%$gJtm5@5q6cEXBv$-SYE+Jdcyx8$i^?PZ&TCltn_FAfF*ome^S*bd&F2cwAJF3P>i>X5&3BMPtthu^ z^??ESxZ*m5A*wJcp&a2XJ7Qqwt&+@ zicbimQdAaGFEb1Q3$jyqB~Y8>od0X_EIrI#0km8G@n`q<8&<=Rv-8Eh76%WSG*mde z_7azc1xpLRq|-lY;sO6jD1rHF zaKrW@5sWij<$!VM1i2a8ef`Y>ntrUYNrvfl|6RzN>N!`AUi;Z=D#`hJ!RnT6?84-P zd(JM29HsZEs$RWetrmLxOJ^86!Q;Ahbd@74oB(CEp)Ve*=N9O?MzDqXv-fLyZVQ?d z^rLn}bkhoiU^P!wR194ON+^M;=^p9rZDKYVWKZQr6 zDvO&ywj6J}mc)^~DBjU+v08FZ?4pJ*LRr!&NwpU3^yuegZ?EY}& zkK$K$mW^UY4|-5=6iN3>y@gFUOOt&m^Ov*Oc#5uJW1sG9qJGxl=H8bgKkN%jm^KXE zqzq%<6Qji5T*OYSn@!fuAwQ;a4vwzsJH0PK^|J&1GHOUjW1eeyaAfJWiX(Q1Y+-p3 z4p+qhAWmd6FR;0 z$3ZGQ6i}1fWU>`=+JsLNMaE$Pn2HTl{y>@O`^{CP7!}Xj1M=BpP~gO zHr>Y8M;h-S;^EB~$W?M#f53I&$){J!S(qH2(i+Y5!*ENAXB}EA%%UVUy7&;UAa_f!w&YW8ve{73e>Xx)I%z;ZQle#X z$Davgr1UqPEpxj_?c>{J^BPbwwc^>_+GYPMQj(lPEUs!R;G`=FhtYi}u%8AG!!bEX zh05;YP}@{#no-j}Xzs(&%?^1H#Y~m&tJNL->QhTg_RD7LJi^6#GzgtubRT=V9K}}{ zqNj|?aJtF9l@&$_r*cktiqiv(j0Dq{-!vmQC$Zv>RO(R`xf^A<`9<`HuGkR_cljaz^x9_7(y6AN&OEIX%=LcdAD($RBP850h=UEfo&GNy>_e4>3IT?B5*xppB(F|C0bEZ2d{ zId>wC)o_oi(RNeZ^ty}iBCrD-h~PZ}=KKz!EO6X-LDh6y)D=w%gd-3LbA`z@wpHcx z-8h?7^t+*&7rveHX}{*4j)bPGwG?|HxW*XFt7W(x|wb9pT+tIn8N&R%{1t~VxWfKq?Z2jjksYr?6eQN_G zmC$$bCo&Qu6gP#XSv*J$_2dsCO;C%L4K4=W-O=Taoj~B> zjbKyT1V>d=48)1*>Motn_~RgG-K(-1YB|A=lElmDB|S;ct&3K6g}{@q1>oLckJdFU z0lCzIr!DeN_;cwGng$3!hW>G4IkAP&JR7Lm>-Y@tN%q=s6eqt;d83uym{+bWC>M1{ z_~D8_r-59J*VM)Oj(fUJj2i8P&=~FPxBNCp`nQU|=C~+}!pS9MDztzjSO9O#=j>D= zG*;cF&~a~{BSocf5oAZp^y&<#JnTwq7_rVG?UMM<^r73VD5<}#XW4DE%>#U5@rhPx z7U_KvHqHX^nnA&{w>>m+T;BODP>G^V(~PD#=<+X_n?bm7Q{`?~&-l=?ud1UE0my_Y zc8Rmbx!e_jZz2h7k%iQI4DE4EfUNrjeNiUQEuqpeHdi@TmnrP$PuUzMYB0nToMj6e zTR-?Pp2^E&ol_0Mz!a`3N1Niw*h1Z4o&mb?Ny#gyW`)?^E5XUAg97Gg+MFX($o6+$ z*d)}2(ENWhwG`h?x7aKJgDq=uQO*NY?tllzXTcK3RQ{9rBF|&*9#40zjb=g70|73j zJynW1_VH<%fzc#DWI+*%y7$_%wk1jhDSN50OITA~33i&ZDcx!<`ipMAMB6e=Rm(qQ z4XKgbnf{R@OZbCecC~S+USWhzkZkI+W+v&0UYQ+JJI!a%Lku&D7TpfMaO=E%bs7+H z|9_pO?7lZQRlq}Fv!J<(6LMUv$rEp#^u;#ilJk3OtvYl8ZRm^hO-W_hF&0KNEd)cF zs5g9CL?{hNgznxf=H+bl#3Btv`$~gHOcLVk^@6Pe75PCiS-_d}-(!6xz8PA@t`Vy% z2&!0z1kRw|ntu%_01X|Of(e&tUXCROUTsmE|5mcic7f9=lJ_@%JD6-Ss#+|nr#z2# zVKn*(c>In%1{i6Zjw~hEUd-!*5bdo6eqVOOY7O>mZ}T8tmkxYr_Fww*;>;A}cz_m3 za@0ybsB7AXyhl60^(Eyz1H}aiZ8Kk zJ+ViizY73=PJ1NySNQ6kiwtjecx;(|Nb;{Rhp~??Bd@QQnYP73r#8{iioKN&n!q;S zbTtU)!Ig;He^`7yMr)A&tT(nXG}c2j7)LsRR?MAp^>v{~x1}!Xf+<8()FdCCJqW9_ zR5p^#gW_Ut7^W?^NKmg-Y2zDS7`f}6#{b(f!zJ#OQc1v6qsh3UsKL2@2&yQ0=!AdZ z#~t5%!>>Suk!u3tOpRe!z4;&SVj8je7ea^NVd=i!?Mg+4h&>&f4mP~{ZFxFCdgA_R zeG2RIg>TWjMj7Qcfb(>YQ(;5+>BdKwI}u(=C0mdjZJGyPgRdD!sJkd4pCM96c>SBk z%T1-VV$dxuT?}Dk%QZ9pNh$uZpab4w16BrM%z4?O1c86lAo_D{FKspaDWB3Iq#wf8 zMoAj${wIAqi`FX=D}~=a(c1rH?f57b37zlnWm&A>DkdRL7S7q7Bg^|IQBdKPeV(s_ zv^MGF2ton=_AetKK0-o9F@22t1WEifr~|@GKr<)F(-$n=ZowNmgGbEX?@Tv)F!YH& z&60VB^^_mv!y!k6Khi?QK9cMAKAgDERq_A0obA0eBU9aFJleFr!j<)M)hS^t9#=$4 z-kQX$51;Y#f2QZ{lfxRD>5OV5qT?H~8~8u>aCAH2wCGIBg+QaQ<*4cfMX|>cpMq7V z#-p%bf!lm5=gwnAbX@s_r@ykBNw(l=g=Pr1&7ut+PPD1@;t(T!xk>q4oay$7PI%RS z5#J+LdmV#A3`W;km)Bcj-iN2(7S3OJNPO{G2}?|0E&LSVn48iZLb1Buo}%-z{HEMQ5~JgFG(2jdxMrp6w5 zEVUuy+H&pbzhr561ol&?f#H&mw;#I4XkFV5_!_yQ`6tGeV9c+hnpx1@j4h!Td-3p* z^vK%8Sfpu5%gJwQa~pdC0K4Nq^b$h%5!zya+@w~L3)D2Ex5WCuz+2$HofK!IvAE== zP!I!E@>1LCJFm>>#k8u6^QG!InzZUiYEx?@BptDlwbXnF7w;6;XA^4?@#Ws5_#t>3QU;JPoTlH&oSd^ z*KPt^NDDB4587E!idaW+hb$ftZQc=vLiSV=Gf)LFsqdU_1+l zAZsT$&jT*^nxkKQ?B`SmfwQ5xuq6lySSpZn1r9;+gb|s(`%+9<2OonO9Ac6>(q$&I z4cb|K+{kid&lS^o+(GnGPVS+nhH#K(HB4DrE6g5IEJeI6{+bIml1FvEM2^0n9iJ`vWW;^v{}ZgZ+jtxfO8$ z3!!`yixaW(!Q-Es#oKBw^qqJs?jpuV#cNySQZAPB1KDt&*V0v9nOgQ zc&}8jGSwCaqn3gw0*Z#cA}onF1F^19+L)ryCzrFLoa`r(g)x>QSe{Bj-FQ_3P@@-x z-F7=z{=A95;Mvb(lqZMdc{-OsnmW6T_Wn>VEe22=vAvN=uznOZo|zc=0aYU2PpUE` zu*L&|Z-v+GpO1SfTL5YBxJ32~uf?x+Uf8E{ba(vg7?Uf1Vv69Vo^WL8Ww6UfL+}Kb z%f(z8GkgY$c1Ih^#L`xAdP$UK_5ft(PM$y5PdeW>xq>_nsRX1oOEmR^m*#5yd9evw zf;}=MV`evakn=KJvpfl%OOkpM3QT)cQ2mp1c~XPbGPb1#v$YP=YqN9Vhq-TZ-<2pW zet*OaSGdGZ@6sHhXY38treTj6Um?6>%pfT>JgRfr`>E5(0@`8xp8dV;YZ( zv4qye(!}`BB=?y<49TookREh?g&&pZ`q_fTvT6Y)G-OJf7Ep>;Kc!rwFxOdEZHsUu z6F2eS!opS|56Tx58H{_TNVfiX(BW8)i+m21_299C^&PCj0iK%5$`5{VqAv4douy6J z!Z*^!bAr&Qfq)2@l1fPr>QOjy6@{4lVOOJ-A0_2BJuCxUqvpYLjI;0=u|NUEaPO?{ ztbwxB7+#32>$X)uCnnS7kc@G?r2M88;sw5SVt+hxqMlF)2#DcI6CWK^ZSzjd78Zw` zX)sK}H4!d*;s6VUjLtU`ORqQ&nmY(EFwa{vPfmVUhd*$AU>Ulla7Rr-+B&4N^)IHF zD8z2;yd*1-Xxn$gKu4n6(%(jS^ZIO57@;>40fnEdj!!osR5vcQ)T{`o`maNA)dP9Xmelx`=WK1C@8#b{qvQ5AW*lf=uwW z5@sj9i81iDquOu?7PdZYy5R;W$TvW zZ`k+OLoJr&aMQ``lO=13E!bF*9Vv&QF_K@!cJ9hJf=C#}vNe10We9@UuR0~+M*^cF zGzbAE?8tS5l7}bwmm1Y8A3GK9uFe?agp&*)*DnAZw!ap^I;%i4Ud}hb_467Z4^!J` zqkLaZiyloOuIpCx;vQ>}iyLSPv|ylER|a!VBV%v-NNF(^`zIgKR%V?Dek%W^vMOEl zGFy(YzpzkX|02TLvbxiB6`Faa{)jITh_1e{R$C^de_vc@+mt)Qj&Q?MX|LZUJ2}HJe=@Ax#b;Rk*{)x|487}~`Kmex zl;)Rz9>CdoZbqqtfeFnJ1A5y7!j<0_k{wA z&TE#=v45z2IxfgVA3sEeJeGTyL-H1ihcX0Eh$l=P!)FbnKXPdZMjR=DH(L}~yBZI{ zPC8=j^Gs}0Wme`#;4lTf{rb)`HWiL!>RYocZ$B>XYumBrge*g^eP{Ii=*0^t_saQD zSL7b=7n@FI2|S)V47OB0C|+~2Li^o=iW+cL!D|P(?Mu$SOt}b#fIdl3&qG*m33yOq z2^@vqAQQc@y-GDyd5pb?` zOT#A}xgb|k{ZsA{eMo90BX{t+Yg-g9w8sLD30yvjBfG$aMgu#!{HlV>tZqMXJj$11 zMEJ?>2Z?WF<R02F3Dd%$$GLFmDK8omcO8;g+O z-05Qbe490K3&gmrsQzx8z(G+Ih3+a_6BV70y1uc}^c?wtu8eN{r9Z0cs(Q24U3pJJ z9*F1Kodvr4Jp~7hQZ6~kTPn3bhSwS#Y=*q1NyfSMkieTJSq63s$*|esjc91=j5Ai3 zKgbPC+u{3!Q-1+9EKV0EQdnR^t7*e-h?ruW;&I>8>I)yGS0WhRy*e*hzo$8%WkHB2 zxYFskbVqF~RP8QVd+lIE5xoJ$irgk9S&|ZVEPUwLHAt#T_o>bsO7qsj>#-kxj#hyM z&PlfO0SeN`Img!puBPwchxEBr)nXj=Z2xG!Ua(!fi*^b#Q%7h~ICkz{WJIMtrvw$G zA7ZKaA9eeW8(*2s>?!^FP7WEdfgZjAOugz+U130YMH@uHd82K?Q2D8i|aQj^E@WIwzg~u?y zr!ApCGvyHTu)+wS_bb$#!>?^mc!fc5U_x|*VsHT@j--b`g=~!vf}`&PG3a2B+jD=0 zxGGvcQOp3AH0X-F$)aUs+#J)5^;00I+(Dvd#%skS6U?P7|LE{j> zlxvHV@d}2O<_@ATP~f?j$DqqGiP!CF0d=V|x*-DU^hmMqd~+JNnW~XeVkF1+S4pYI z24{nDE=FO_zHg%DmP8Ya3n)a>Y)RZtqt1@XZ0ik&@x%bPZWAt2fDP6So9w~>?Ma;^ z%J8frC=VdbNx7|-T%CMIEbcR!XUJZCj@02XtEbGiT>K~&FJj5pAWk6mQ?#eh zEA#k8oWwEqfCbBpbCIE+g|1!YM6ADHjvy(W8+^5)Y9IYqH@(JsWZAlapoM-<+~@~i zn|T;LU45He}vy#;e4uPczj}~sdtIu zWdQzy7du5=V=2-x;u%Z?m-j0xo*bUZhb0#}n z?5Dma<#fAACMmR-Ac|H_m1H?xi@L==g7i4*9Kk1VAom0nF=#Fi@<~|_)H1hs45g<@ z^t?{sUlDg~l=**{uOELG9?}YA#uc^*>OwQv`_X~#Y?{p}=ZU98u~T4(Lz608@WUch z;Qee7rXIABk&+TpfEu!SCt8wW#`BS8zg^l$%REq%$R5J9ke0d+*67RWDImBgN&J%N za#%PATvOwF+w9@88H8au_=jJ5Kl4DK0EO-JVPoJ3jF6ZGIz!+&2s}t>P=#8ICaS1_ zjS%t(0XZE+Z7IO4LxA;lhVS~w673xF2hRUMZA68-vZR$p7O^4hI2(s z5tY&+*5R!oG5FJ$W66A9+4=#R!_gU{*_<^jG3f*RPdb<`Tucp809$A^C2*)FX#s-k zJ6%$cjQWnH%#^4;kUah93N#D%RWa6zmETv19M?+_OV$r(2Dr3P>a-z!QjfqoDLm66 z%s=SnFRm#=(z11F7(H@?Vrn>B;gf~^SHDllt8UD;!LE$#SiY6f8$Lc!p!s|gh{6_8 zsuI;6vQ>y*=2rTKv!;G?5^8vLy&-oPt)^qC7EBtjd1ShnR7FKt@79(!Ye2!1b1-4| z?Lqh^JT*>zvp31E><#OsV5f}ed%;OeO0}Sy7L>YInA>bm@{W}Bh}>(l2PA$)ZI9`K zk_DAt&B)88A3MFLrat$KEI4$?Sctifn||g#N67!Xx}Uw-DXcxFBY1%QYop*}rInjw zemTwu3O8w`#A|p${{fk4c4O((JQNq+=B2SFk0>ay9-OdD+Htucy4vwJMuJ=DdTzN< zHvYHjBy9m~uEha6yztcTP~aX;>Ed{YjCAd;wDLpc`10{V8Epu`jml!(z|yyZ`a-T_ z?XB8UiB6ZnzO$G<2tZHYG6uc|nc>AE^8{5O=#(Xpl%uyYWgd6rb-b8!JH;obBZqw% zU#>v8W0wHX#4i3Rv!dI>5pQv(-CzkTmJOlvHULfgfN&oG5)Gzk+_|wpN&htQlGgVM zX|j02zf|S+~_%<%p8t?kJ<)mgle+d;DkDTY%KaU<|`lOpqM?17a`sG2C%I8yl=mK z?}YL2Nb(UH4QuXdBa)}R;#FF~Xi@{l*~=BfH1<&8vP%07rvHDVg6Kd878T(nVuXJ&>uQAjIh z>mf0>?d5r_bkUqzb_H_bX6Q0?%TVN^@FQ^z^^*Wfci}~L8hq1JqJ+r^Iu$CbX?IAX ze_i~BS5B$217v|uwTO`E!i^bHDsSZn0#>AxNLQb!(kz6bEfR4Y~I4w;LxB<{S&~8JIS)WhN zSRB2%KG+(~TmK0%vWNyN^0uHdb4tHTgTeHAKIF>4kZ7+HLjDT&SaHT_toI-ji`h}w zHwvR6CB+eMWEDMZ+6WLqQ}jBp`oFpn={=;|7$fLp3=A>Xb8@2DarRFaRhxlWDP4`n zU~l4u?h;tP3f+w}0|(u=heye7w-keNMRD!P!wA7by~LiMzEwb8JZ87;TZ8l}-)Rq&fC;X7D%Ha0;|w!pAR; ztEO+7h2WT3`?$l?yHUl#9KFBI+_y4+7QloBQ-@gqQUC8#Nh%taRA~I)>FVT4oKoJ) z+q?ee=|hHEMXZC9N2;?c(P1+j=wFJI-9GwDPva`;ew!x3o|klP+e~*Fwo1vi=05pM zMnD-52kd06Y7pfo0#1#)WfXTi>@eK;JKjNnTP};uiJ$xvV-`r#SsYL4NWH`K!08~A zHJ|@x6X0kE18#p1QgxJ6@|quIy#TadRxvlo+`BthJVnRYmVg=r2k7$l4XZk$YDl>u z!Dh`4i`Cbc!Xm}tFRzfVyXZ{T2gvDj=ObxW9pc-K^+T4mHk1Yz$+h>%WyD13SfGgP zL;;2%%ItvP==WA!jxAsZ8>%oAGug(MfiWEM2rxA^67LN{*`Wf3COtHQ-91EUr{OK8AK*7vcrJ9iVIJjPcA+OZwfi2j`nz~Un=B3s{Q(KyG|4@AZ|lO$@%lNi~; z7rZSA^k}W_0)E>6U!DBZ9}rsXRWsWfr8PQA+!O~LYaN;{34>%bA_}W(SCDK_kSz>& z$S=Wc<4iW;$32-6mV46w%s#4u_ZMz`V`xkyrv6usrTSWoE(oDy)9^&-lkx~8r z8&m^(v)Q)P^zk_#l4cGjuONhqDsCW!cYEXDq84biyF>h_CJx7W9UhP;Z{XRcU#VWi znkNn{?05(f7y?ubi`UFcfoa?|_wjG=#%%2;T5CSCO9z`H&jpG1V?HJkd_Co(Tx*q= zP^BiQwD-BEDfIo^FeeI8n1_&0!8y)vsLvb40UD4{3J!|VRj@XbTz#iEI${q+WBr7rZI-Y2Nt1_c)O-e`**|p0+^< zfIc#<+aU7!4GMr$C=z@j0lTjd>*6z7VPCX`tg85=tK5h%gj(>igATpsxF569dNGy5 z85VXAB>E6#tJHotWP3tkBNc?S4^m1$coFYbDPBNHjC-mII;K=)s@VnV zP&QF$E7en~kz6?5_T|BP3`to)Gc=#MJDezOB5HV(|Lm`h1D}my%Ac?_+X!$CqJDd= zdpi|hHo_I+Lo@nBNuU+0F8r&b^v-GGvM$p7vy!($fkpl=BG1Za&al^7N-<-H!LM&x zK}d_>9(%|oxIxr&?zG4|tyiOnTEjX&lZYmC;^^|(;V3?pEadg(CwDfXLHDW&s{=te zRMKiIhx>+wwqyz>&)}WbO!T2wg)J|SI?9S#;?E=Rl^%aa3+lnsX+v8GXc&QG9b2y{ z0Hf2`P4Ka61FDZ&bqyKnIh;_sE3e~OQi~6eoES-HHAI`G{%`1sE~E0;pfX9}a6VQW zzlz}BxTY)3Aem>_yMxepPNk{PU|7Jq5}<k(@OD4B%DQ zbs#+t4E|s#oSA#!1WA#z(3Iw7pX4XRr72H|_Jrslxg6`}Vg#G-)(dp?TX?dhlsJ7! zW$@;y<`XIfXqVbw>|(a4WV^kwVE zkru{T|HRx-7;Yy!0KAe@roF+7%zT8HqUHGpOkF44{;;#1Emz#NiUg&DX#UTKPzIfh z00@pz-lw{z0_J-TlaJ(lNHF~kp7Z|n2YS;>2^tkZd~r=lFdTz!oY6Q@JV$pLz+oVU zHVd*ha&{SAD+k8ZE6n=|>0~p!zw*+Af$(t?FB_9MvhG`F{}69=WRb4XU=>o!NEcN_ zSph-+!jVxtivaV?M#3u?g&~Eg{n7bvm+YVg-D>{=CAK60Ct4Lj%z_9Qy$YFbjz5?K zgJZDflpG_q^gypp_Dm}7iaQgh1565>jD^xE@B%#icT1bW_-w)J8~o)czKgqKiw}PH zG|mZ}XtqW4Oj+{v%Q^)cj#?_VV=UpOF4%I5++x2=^kg=gE%%o|%|sA#@H;UbBl>5BRO z)>&I*#Af%@Jcq>e5m_&qnm9IaV6Sojq`ADnobGQVa=dKp-h)y}LVKxkEU>;5@jPc;ygzLE0WlRL$-4~OTv0_{zgNOdF26I3M zq4!=CoTs*(Qg{wz5dHgNo@fmBbdgW^#LQ>h5q>8w=4lLxVD9nrv0IrD={@)05pmO9 zOrq$+d%Wq;5BqJ3FQ%e4DwHzzh=6_OGDV$<8SJFJ0!(+=I0Qd(gzNz~4#@FtMtlaL zPF>Ydp{7_aGK-RtV5*yy;F~u9?DBd9)Qh?SG2riQ=2@-sDwrYZK*vM<)U&c`Hkm!O+$2gU4}_-Q_Rc zlTaoF3hem#ok~|=JUxN{0crlKj|4)Hj3DxqJO#oc6kupyy}5~RFhM6lJjWj69zThm zG)Yn2g(jWyj(VqgH-(Bauv~b$9V31O>F{x)O#QD?DT8Mu!VmcfMsf*|s{5p%o73iuz zAx?Av^X~=mY0FtQUu?S@Nb#U)V5f`!d2LQ5dYl4pGl^aq&1zLU&*+|Pk zX{gplCJvYu$5HQ-pj_UK-DB~sV@w8%-wT=Zab2eEw|ouUlLTE_ixi^jkcRFYQ+Y>d zMLS{L=0gYBkP>eGUR08g9Eh;`flYtYGfnf7On)5vP=m<7v_wyNkql7Noz;{tH#}e% z{YaE>C(;dpk;2l*QBh&F_cy#J#sHqz&Ab!9{{*_Vt|puzcu77+iGHaSf^#eP&zf-W;fedk z;z;F!>d6bx&n4wEx$TJ3OZ+Oaz%U2lQV z&x_!h7*0Tea$$etvY?jRdtp((i{yHl;R8;JAw-E@vVZ2_Eobq}NiOzWn8km*mf=q!cu^9mZA1A!8#W>TQJvy8`g8aBXx8Xx# z*Y{@)Br1XO|Ho-aGOcx<|1QN9uPPsNbT7KDT*VF(W3BvZ`3)0?L@9A6N=f?HsPO@h z%Q%wDVjFybuCY4>_r3+b4!BqnW;F3`IXi&1Gn$Bvh=z>lvLt&^R_@WPZ2M&=-3g>& zYO_A0){Kt+@6Pr9L+0A41Q1kn#Z|4-vivGlG;e%Uq_u{dDVb+Qp?cx3-oo@aRe3r6 z$vXr~W4_Iaf`F6IMjPP_ZQMZEr2k{wXRy5%04IL)a_%?%UPz>I%N>tQb~=(V^b=Et z`-R6pLcqziZ|^%3$ACq8#Q})OAE^_rkN_ts3JGkKJto-%)hgW!^3u$6c7mk;w6+iD ziUNMvvPq&NlOB%S0o?Nu##FB=AQe&TJJ@n zh`=w5Dzd?z%06B+(w=zk*n0onpVg{o!!qU zVU+BxV7$3p!A-ZmwL!no@p&oAI~EEkV=EIyLLRWhf7EIaj!nAi^J?#U9RheR5 z_nEkiKDRaSa^OKei*vDa>ff=$m9sF0LTM z+Zdz5LMM}}_NVa}Qw|_67GmkR0EVcr@L0#yXSte0ftqCZvjZr&Ls$VMvi!$$l}CDK zKyOQK0=<#Am@t8(KDx4gCz2f(H@Y2Ig>o8EF9K}o!K`f1YWaQC##~mD;4IR|JvsMX zStuYEu|xDi@Nc|v_Mou!r;|ebs%`yEEI}LF@{Vg@O1RLNXlFtFh^M4-l8r^;I zX6SmL^yFw4D{K1q&7b==!=8ru1uBj$WNCuX)>$nd*TDa1$5u*tfB*@UNCXMkYccMt zf(kvZyT`X&!<)dbrkjBFhQ9L~`;CJEFnua52XfZ#CZHoX-%vr1(daAPkJ#ki)%_hpZ zav0ZF$%>RW)Nu<$W0k$duRpo_+NuT3|3vL)y-VY`t7BBfzKp79zLt0vsTDEwowTTY zf0OmKTPkxhd60*~->H{mTERdxCzHW~Na%vtjY+ykm>)V5<+k#oV6CM~lJQ`!qUwb4Si5hPN&}_}ak%hs?PnrtZKqd8#o>FIdMY3y_Au z+&67LS++_D+b)j{16s){a9s6GmgG*ABvBM>EMVaMK+Cj=i_(E?QxGFz8x*##=>|!S zrTfWU3U!2-6)`R&K(h8F$8W>V2>=`k-F_Ht1MmU7hpNA|rd*$kCNCA6UQy&cjXbqmoPMFw==F5L{+zUnIL#QMs+IS{JeukngyVoEvV+k-!g?)_=$F@opUrk}$8u;e zgXJ**2i=fV(W-LOWJal&xn4I;yoP{${F#Y3XNhoVZ%v@%EEdqXEwFLGGM4$FtJ}fL ztuY0-_HyMg+++A3QUy|%h5P30#RmE|5^&vjoPv=Ny@BNGS72xYMWlnkI}!KMm}GUa zz6MGq3~msq0lp%5C@I%A+IGr99)$73`_bLnFNom$9$x3IB4a@S-EMj?19T|Pasw+% zp8Q2 zlxcbkRn#2ZY>Qxr-Sn-qd9+Xwll`aAAAEL`rnz(bl^wwp8Iq70&}m?C8!H>M`XiaQHOJj&F~%58_}he0|kP+5L` zo;J`fq`QBNa{vJyn`0K}tw>3@gC3=?_Q4Cun*2pD8N-iXHrbBxlCUi`ddZz|4=<~j z-8r{O{cj03yUz@AY(0KTe@Q!IFQH-7S{nuJbfdzvb*!E=4RlnuP$zLd2%u3_yTN|C zjnAG(>PP?0_LRDr8FwTX5>(LZ-5~Zx9CDO7C-sH-oGeAO46-D%=ZM`cB0ya(G)Q3l zI8|~i_*qpE5%R*K`A{wf_|Gbd^*y>MC5<6*U04B zvm=Pu1yV+oeg){i)Z=~N00S0`_?d`&VxzF)8%w=qM|VE{t%xNy8CqTTAL#~oeFyka z=v{4EH>zc|JfLlM9N{7e+Y&)&&5w6*lV@C+Z+9Kf1!To~V;Bs#$$AF=6XorIJs7OK@Wd`t+1p|p%R9A&G((l=&h=wv_-=nS?3{C znxJOJb}MD@0nnXwGPg_bWuC;;G@Jr*+>jagg!}jv+dl9On6an;01S!NOn~d12rx(Y z#mgHirb$8(5eAt#sHwafQ6)gt{t*1h@hQpY9ZKV+jYf6xXC xBXAo^nbX*;qc$D0y{7z0hSpoT;$e$`=XfQQz*(GFk{AtCG=KmA00000003ebA^rdW literal 0 HcmV?d00001 diff --git a/boards/dfrobot/beetle_rp2350/doc/index.rst b/boards/dfrobot/beetle_rp2350/doc/index.rst new file mode 100644 index 000000000000..0ac3c101ebdb --- /dev/null +++ b/boards/dfrobot/beetle_rp2350/doc/index.rst @@ -0,0 +1,145 @@ +.. zephyr:board:: beetle_rp2350 + +Overview +******** + +The `DFRobot Beetle RP2350`_ board is based on the RP2350A microcontroller from Raspberry Pi Ltd. +The board has two 8-pin headers and a USB type C connector. + + +Hardware +******** + +- Microcontroller Raspberry Pi RP2350A, with a max frequency of 150 MHz +- Dual ARM Cortex M33 cores, and dual RISC-V Hazard3 cores. +- 520 kByte SRAM +- 2 Mbyte QSPI flash +- 9 GPIO pins +- 2 ADC pins +- I2C +- UART +- SPI +- USB type C connector +- Lithium battery charger +- Reset and boot buttons +- User LED + + +Default Zephyr Peripheral Mapping +================================= + ++---------------+--------+------------+ +| Description | Pin | Comments | ++===============+========+============+ +| User LED | GPIO25 | Alias led0 | ++---------------+--------+------------+ + + +GPIO header: + ++-------+--------+-----------------+ +| Label | Pin | Default pin mux | ++=======+========+=================+ +| 0 | GPIO0 | UART0 TX | ++-------+--------+-----------------+ +| 1 | GPIO1 | UART0 RX | ++-------+--------+-----------------+ +| 4 | GPIO4 | I2C0 SDA | ++-------+--------+-----------------+ +| 5 | GPIO5 | I2C0 SCL | ++-------+--------+-----------------+ +| 8 | GPIO8 | | ++-------+--------+-----------------+ +| 9 | GPIO9 | | ++-------+--------+-----------------+ +| 16 | GPIO16 | SPI0 MISO | ++-------+--------+-----------------+ +| 18 | GPIO18 | SPI0 SCK | ++-------+--------+-----------------+ +| 19 | GPIO19 | SPI0 MOSI | ++-------+--------+-----------------+ +| 26 | GPIO26 | ADC0 | ++-------+--------+-----------------+ +| 27 | GPIO27 | ADC1 | ++-------+--------+-----------------+ + +See also `pinout`_ and `schematic`_. + + +Supported Features +================== + +.. zephyr:board-supported-hw:: + + +Programming and Debugging +************************* + +.. zephyr:board-supported-runners:: + +By default programming is done via the USB connector. Press and hold the BOOT button, and then +press the RST button, and the device will appear as a USB mass storage unit. +Building your application will result in a :file:`build/zephyr/zephyr.uf2` file. +Drag and drop the file to the USB mass storage unit, and the board will be reprogrammed. + +It is also possible to program and debug the board via the SWDIO and SWCLK pins in the DEBUG +connector. You must solder a 3-pin or 4-pin header to the back of the board in order to use +this feature. A separate programming hardware tool is required, and for example +the :command:`openocd` software is used. You might need to use Raspberry Pi's forked +version of OpenOCD. Typically the ``OPENOCD`` and ``OPENOCD_DEFAULT_PATH`` values should be +set when building, and the ``--runner openocd`` argument should be used when flashing. +For more details on programming RP2040-based and RP2350-based boards, +see :ref:`rpi_pico_programming_and_debugging`. + + +Flashing the M33 core +===================== + +To run the :zephyr:code-sample:`blinky` sample: + +.. zephyr-app-commands:: + :zephyr-app: samples/basic/blinky/ + :board: beetle_rp2350/rp2350a/m33 + :goals: build flash + +Try also the :zephyr:code-sample:`hello_world` and +:zephyr:code-sample:`adc_dt` samples. + +Use the shell to control the GPIO pins: + +.. zephyr-app-commands:: + :zephyr-app: samples/sensor/sensor_shell + :board: beetle_rp2350/rp2350a/m33 + :gen-args: -DCONFIG_GPIO=y -DCONFIG_GPIO_SHELL=y + :goals: build flash + +To set one of the GPIO pins high, use these commands in the shell: + +.. code-block:: shell + + gpio conf gpio0 8 o + gpio set gpio0 8 1 + + +Flashing the Hazard3 core +========================= + +The RP2350A microcontroller has two ARM M33 cores and two RISC-V Hazard3 cores. +To flash one of the Hazard3 cores, use the board argument ``beetle_rp2350/rp2350a/hazard3``. +The sample :zephyr:code-sample:`blinky` has been verified for this core. +Use the USB mass storage programming method described above. + + +References +********** + +.. target-notes:: + +.. _DFRobot Beetle RP2350: + https://www.dfrobot.com/product-2913.html + +.. _pinout: + https://wiki.dfrobot.com/SKU_DFR1188_Beetle_RP2350#target_4 + +.. _schematic: + https://dfimg.dfrobot.com/5d57611a3416442fa39bffca/wiki/f18e5f3a683e6d8a9c8582ac6f89b023.pdf diff --git a/boards/dfrobot/beetle_rp2350/support/openocd.cfg b/boards/dfrobot/beetle_rp2350/support/openocd.cfg new file mode 100644 index 000000000000..68211b3720f7 --- /dev/null +++ b/boards/dfrobot/beetle_rp2350/support/openocd.cfg @@ -0,0 +1,11 @@ +# Copyright (c) 2022 Tokita, Hiroshi +# SPDX-License-Identifier: Apache-2.0 + +# Checking and set 'adapter speed'. +# Set the adapter speed, if unset, and given as an argument. +proc set_adapter_speed_if_not_set { speed } { + puts "checking adapter speed..." + if { [catch {adapter speed} ret] } { + adapter speed $speed + } +} From ac6e27d95b2c8a6b2ee99e2e98ac3cdbb36017d1 Mon Sep 17 00:00:00 2001 From: Jonas Berg Date: Sat, 3 Jan 2026 14:53:54 +0100 Subject: [PATCH 1988/3659] boards: Add support for Pimoroni Tiny 2040 Tested with the commands mentioned in the index.rst file. Product photo from https://shop.pimoroni.com/products/tiny-2040 Signed-off-by: Jonas Berg --- boards/pimoroni/tiny2040/Kconfig | 5 + boards/pimoroni/tiny2040/Kconfig.defconfig | 16 ++ boards/pimoroni/tiny2040/Kconfig.tiny2040 | 5 + boards/pimoroni/tiny2040/board.cmake | 38 ++++ boards/pimoroni/tiny2040/board.yml | 6 + .../pimoroni/tiny2040/doc/img/tiny2040.webp | Bin 0 -> 16812 bytes boards/pimoroni/tiny2040/doc/index.rst | 128 +++++++++++++ boards/pimoroni/tiny2040/support/openocd.cfg | 11 ++ .../pimoroni/tiny2040/tiny2040-pinctrl.dtsi | 34 ++++ boards/pimoroni/tiny2040/tiny2040.dts | 180 ++++++++++++++++++ boards/pimoroni/tiny2040/tiny2040.yaml | 22 +++ boards/pimoroni/tiny2040/tiny2040_defconfig | 13 ++ 12 files changed, 458 insertions(+) create mode 100644 boards/pimoroni/tiny2040/Kconfig create mode 100644 boards/pimoroni/tiny2040/Kconfig.defconfig create mode 100644 boards/pimoroni/tiny2040/Kconfig.tiny2040 create mode 100644 boards/pimoroni/tiny2040/board.cmake create mode 100644 boards/pimoroni/tiny2040/board.yml create mode 100644 boards/pimoroni/tiny2040/doc/img/tiny2040.webp create mode 100644 boards/pimoroni/tiny2040/doc/index.rst create mode 100644 boards/pimoroni/tiny2040/support/openocd.cfg create mode 100644 boards/pimoroni/tiny2040/tiny2040-pinctrl.dtsi create mode 100644 boards/pimoroni/tiny2040/tiny2040.dts create mode 100644 boards/pimoroni/tiny2040/tiny2040.yaml create mode 100644 boards/pimoroni/tiny2040/tiny2040_defconfig diff --git a/boards/pimoroni/tiny2040/Kconfig b/boards/pimoroni/tiny2040/Kconfig new file mode 100644 index 000000000000..f00270131578 --- /dev/null +++ b/boards/pimoroni/tiny2040/Kconfig @@ -0,0 +1,5 @@ +# Copyright (c) 2026 Jonas Berg +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_TINY2040 + select RP2_FLASH_W25Q080 diff --git a/boards/pimoroni/tiny2040/Kconfig.defconfig b/boards/pimoroni/tiny2040/Kconfig.defconfig new file mode 100644 index 000000000000..f6f207e10859 --- /dev/null +++ b/boards/pimoroni/tiny2040/Kconfig.defconfig @@ -0,0 +1,16 @@ +# Copyright (c) 2022 Peter Johanson +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_TINY2040 + +if I2C_DW + +config I2C_DW_CLOCK_SPEED + default 125 + +endif # I2C_DW + +config USB_SELF_POWERED + default n + +endif # BOARD_TINY2040 diff --git a/boards/pimoroni/tiny2040/Kconfig.tiny2040 b/boards/pimoroni/tiny2040/Kconfig.tiny2040 new file mode 100644 index 000000000000..aa88ea3dc72d --- /dev/null +++ b/boards/pimoroni/tiny2040/Kconfig.tiny2040 @@ -0,0 +1,5 @@ +# Copyright (c) 2026 Jonas Berg +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_TINY2040 + select SOC_RP2040 diff --git a/boards/pimoroni/tiny2040/board.cmake b/boards/pimoroni/tiny2040/board.cmake new file mode 100644 index 000000000000..414bfe8d9583 --- /dev/null +++ b/boards/pimoroni/tiny2040/board.cmake @@ -0,0 +1,38 @@ +# SPDX-License-Identifier: Apache-2.0 +# Adapted from boards/raspberrypi/rpi_pico/board.cmake + +# This configuration allows selecting what debug adapter debugging rpi_pico +# by a command-line argument. +# It is mainly intended to support both the 'picoprobe' and 'raspberrypi-swd' +# adapter described in "Getting started with Raspberry Pi Pico". +# And any other SWD debug adapter might also be usable with this configuration. + +# Set RPI_PICO_DEBUG_ADAPTER to select debug adapter by command-line arguments. +# e.g.) west build -b rpi_pico -- -DRPI_PICO_DEBUG_ADAPTER=raspberrypi-swd +# The value is treated as a part of an interface file name that +# the debugger's configuration file. +# The value must be the 'stem' part of the name of one of the files +# in the openocd interface configuration file. +# The setting is stored to CMakeCache.txt. +if("${RPI_PICO_DEBUG_ADAPTER}" STREQUAL "") + set(RPI_PICO_DEBUG_ADAPTER "cmsis-dap") +endif() + +board_runner_args(openocd --cmd-pre-init "source [find interface/${RPI_PICO_DEBUG_ADAPTER}.cfg]") +board_runner_args(openocd --cmd-pre-init "transport select swd") +board_runner_args(openocd --cmd-pre-init "source [find target/rp2040.cfg]") + +# The adapter speed is expected to be set by interface configuration. +# But if not so, set 2000 to adapter speed. +board_runner_args(openocd --cmd-pre-init "set_adapter_speed_if_not_set 2000") + +board_runner_args(jlink "--device=RP2040_M0_0") +board_runner_args(uf2 "--board-id=RPI-RP2") +board_runner_args(pyocd "--target=rp2040") + +# Default runner should be listed first +include(${ZEPHYR_BASE}/boards/common/uf2.board.cmake) +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) +include(${ZEPHYR_BASE}/boards/common/blackmagicprobe.board.cmake) +include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake) diff --git a/boards/pimoroni/tiny2040/board.yml b/boards/pimoroni/tiny2040/board.yml new file mode 100644 index 000000000000..92d431dfd464 --- /dev/null +++ b/boards/pimoroni/tiny2040/board.yml @@ -0,0 +1,6 @@ +board: + name: tiny2040 + full_name: Pimoroni Tiny 2040 + vendor: pimoroni + socs: + - name: rp2040 diff --git a/boards/pimoroni/tiny2040/doc/img/tiny2040.webp b/boards/pimoroni/tiny2040/doc/img/tiny2040.webp new file mode 100644 index 0000000000000000000000000000000000000000..ee61dff751ceb6da2e1e918d079ebc717c8e67c7 GIT binary patch literal 16812 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 +# SPDX-License-Identifier: Apache-2.0 + +# Checking and set 'adapter speed'. +# Set the adaptor speed, if unset, and given as an argument. +proc set_adapter_speed_if_not_set { speed } { + puts "checking adapter speed..." + if { [catch {adapter speed} ret] } { + adapter speed $speed + } +} diff --git a/boards/pimoroni/tiny2040/tiny2040-pinctrl.dtsi b/boards/pimoroni/tiny2040/tiny2040-pinctrl.dtsi new file mode 100644 index 000000000000..a1f7d743ead3 --- /dev/null +++ b/boards/pimoroni/tiny2040/tiny2040-pinctrl.dtsi @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2026 Jonas Berg + * + * 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; + }; + }; + + adc_default: adc_default { + group1 { + pinmux = , , , ; + input-enable; + }; + }; +}; diff --git a/boards/pimoroni/tiny2040/tiny2040.dts b/boards/pimoroni/tiny2040/tiny2040.dts new file mode 100644 index 000000000000..99d6e714511c --- /dev/null +++ b/boards/pimoroni/tiny2040/tiny2040.dts @@ -0,0 +1,180 @@ +/* + * Copyright (c) 2021 Yonatan Schachter + * Copyright (c) 2022 Peter Johanson + * Copyright (c) 2026 Jonas Berg + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include +#include +#include +#include "tiny2040-pinctrl.dtsi" + +/ { + model = "Pimoroni Tiny 2040"; + compatible = "pimoroni,tiny2040"; + + 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; + led0 = &red_led; + led1 = &green_led; + led2 = &blue_led; + sw0 = &boot_button; + }; + + zephyr,user { + io-channels = <&adc 0>, <&adc 1>, <&adc 2>, <&adc 3>; + }; + + leds: leds { + compatible = "gpio-leds"; + + red_led: red_led { + gpios = <&gpio0 18 GPIO_ACTIVE_LOW>; + label = "Red LED"; + }; + + green_led: green_led { + gpios = <&gpio0 19 GPIO_ACTIVE_LOW>; + label = "Green LED"; + }; + + blue_led: blue_led { + gpios = <&gpio0 20 GPIO_ACTIVE_LOW>; + label = "Blue LED"; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + + boot_button: boot_button { + label = "Boot button"; + gpios = <&gpio0 23 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + zephyr,code = ; + }; + }; +}; + +&flash0 { + reg = <0x10000000 DT_SIZE_M(8)>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + /* Reserved memory for the second stage bootloader */ + second_stage_bootloader: partition@0 { + label = "second_stage_bootloader"; + reg = <0x00000000 0x100>; + read-only; + }; + + /* + * Usable flash. Starts at 0x100, after the bootloader. The partition + * size is 8 MB minus the 0x100 bytes taken by the bootloader. + */ + code_partition: partition@100 { + label = "code-partition"; + reg = <0x100 (DT_SIZE_M(8) - 0x100)>; + read-only; + }; + }; +}; + +&gpio0 { + 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 = ; +}; + +&timer { + status = "okay"; +}; + +&wdt0 { + status = "okay"; +}; + +&adc { + status = "okay"; + pinctrl-0 = <&adc_default>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + + channel@0 { + reg = <0>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; + + channel@1 { + reg = <1>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; + + channel@2 { + reg = <2>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; + + channel@3 { + reg = <3>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; +}; + +zephyr_udc0: &usbd { + status = "okay"; +}; + +&die_temp { + status = "okay"; +}; + +&vreg { + regulator-always-on; + regulator-allowed-modes = ; +}; + +&xosc { + startup-delay-multiplier = <64>; +}; diff --git a/boards/pimoroni/tiny2040/tiny2040.yaml b/boards/pimoroni/tiny2040/tiny2040.yaml new file mode 100644 index 000000000000..91f7ce5f08d5 --- /dev/null +++ b/boards/pimoroni/tiny2040/tiny2040.yaml @@ -0,0 +1,22 @@ +identifier: tiny2040 +name: Pimoroni Tiny 2040 +type: mcu +arch: arm +flash: 8192 +ram: 264 +toolchain: + - zephyr + - gnuarmemb +supported: + - adc + - clock + - counter + - dma + - flash + - gpio + - hwinfo + - i2c + - pwm + - spi + - uart + - watchdog diff --git a/boards/pimoroni/tiny2040/tiny2040_defconfig b/boards/pimoroni/tiny2040/tiny2040_defconfig new file mode 100644 index 000000000000..85b60ee95c5a --- /dev/null +++ b/boards/pimoroni/tiny2040/tiny2040_defconfig @@ -0,0 +1,13 @@ +# Copyright (c) 2026 Jonas Berg +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_BUILD_OUTPUT_HEX=y +CONFIG_BUILD_OUTPUT_UF2=y +CONFIG_CLOCK_CONTROL=y +CONFIG_CONSOLE=y +CONFIG_GPIO=y +CONFIG_RESET=y +CONFIG_SERIAL=y +CONFIG_UART_CONSOLE=y +CONFIG_UART_INTERRUPT_DRIVEN=y +CONFIG_USE_DT_CODE_PARTITION=y From 9927c16d1f7f5a6a54c982da5507f8a0c9e1b0da Mon Sep 17 00:00:00 2001 From: Gaetan Perrot Date: Tue, 6 Jan 2026 01:49:08 +0900 Subject: [PATCH 1989/3659] drivers: clock_control: bl70x: make set_root_clock_dividers void clock_control_bl70x_set_root_clock_dividers() never reports errors and always returns 0. The error check at the call site is therefore dead code. Make the function void and drop the unused error handling. Signed-off-by: Gaetan Perrot --- drivers/clock_control/clock_control_bl70x.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/drivers/clock_control/clock_control_bl70x.c b/drivers/clock_control/clock_control_bl70x.c index 3c464c78261f..010fde64f481 100644 --- a/drivers/clock_control/clock_control_bl70x.c +++ b/drivers/clock_control/clock_control_bl70x.c @@ -105,7 +105,7 @@ static int clock_control_bl70x_init_crystal(void) } /* HCLK is the core clock */ -static int clock_control_bl70x_set_root_clock_dividers(uint32_t hclk_div, uint32_t bclk_div) +static void clock_control_bl70x_set_root_clock_dividers(uint32_t hclk_div, uint32_t bclk_div) { uint32_t tmp; uint32_t old_rootclk; @@ -139,8 +139,6 @@ static int clock_control_bl70x_set_root_clock_dividers(uint32_t hclk_div, uint32 clock_bflb_set_root_clock(old_rootclk); clock_bflb_settle(); - - return 0; } static void clock_control_bl70x_set_machine_timer_clock_enable(bool enable) @@ -441,9 +439,7 @@ static int clock_control_bl70x_update_root(const struct device *dev) /* set root clock to internal 32MHz Oscillator as failsafe */ clock_bflb_set_root_clock(BFLB_MAIN_CLOCK_RC32M); - if (clock_control_bl70x_set_root_clock_dividers(0, 0) != 0) { - return -EIO; - } + clock_control_bl70x_set_root_clock_dividers(0, 0); sys_write32(BFLB_RC32M_FREQUENCY, CORECLOCKREGISTER); if (data->crystal_enabled) { @@ -454,11 +450,7 @@ static int clock_control_bl70x_update_root(const struct device *dev) clock_control_bl70x_deinit_crystal(); } - ret = clock_control_bl70x_set_root_clock_dividers(data->root.divider - 1, - data->bclk.divider - 1); - if (ret < 0) { - return ret; - } + clock_control_bl70x_set_root_clock_dividers(data->root.divider - 1, data->bclk.divider - 1); if (data->root.source == bl70x_clkid_clk_dll) { clock_control_bl70x_init_root_as_dll(dev); From 46ad3814cc333327ba52fa80c47a5c6263724400 Mon Sep 17 00:00:00 2001 From: Gaetan Perrot Date: Tue, 6 Jan 2026 01:57:11 +0900 Subject: [PATCH 1990/3659] drivers: clock_control: bl60x: make set_root_clock_dividers void clock_control_bl60x_set_root_clock_dividers() never reports errors and always returns 0. The error check at the call site is therefore dead code. Make the function void and drop the unused error handling. Signed-off-by: Gaetan Perrot --- drivers/clock_control/clock_control_bl60x.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/drivers/clock_control/clock_control_bl60x.c b/drivers/clock_control/clock_control_bl60x.c index 4d353e37d94c..5543aeb20d76 100644 --- a/drivers/clock_control/clock_control_bl60x.c +++ b/drivers/clock_control/clock_control_bl60x.c @@ -130,7 +130,7 @@ static int clock_control_bl60x_init_crystal(void) } /* HCLK is the core clock */ -static int clock_control_bl60x_set_root_clock_dividers(uint32_t hclk_div, uint32_t bclk_div) +static void clock_control_bl60x_set_root_clock_dividers(uint32_t hclk_div, uint32_t bclk_div) { uint32_t tmp; uint32_t old_rootclk; @@ -164,8 +164,6 @@ static int clock_control_bl60x_set_root_clock_dividers(uint32_t hclk_div, uint32 clock_bflb_set_root_clock(old_rootclk); clock_bflb_settle(); - - return 0; } static void clock_control_bl60x_set_machine_timer_clock_enable(bool enable) @@ -559,9 +557,7 @@ static int clock_control_bl60x_update_root(const struct device *dev) /* set root clock to internal 32MHz Oscillator as failsafe */ clock_bflb_set_root_clock(BFLB_MAIN_CLOCK_RC32M); - if (clock_control_bl60x_set_root_clock_dividers(0, 0) != 0) { - return -EIO; - } + clock_control_bl60x_set_root_clock_dividers(0, 0); sys_write32(BFLB_RC32M_FREQUENCY, CORECLOCKREGISTER); clock_control_bl60x_set_PKA_clock(0); @@ -574,11 +570,7 @@ static int clock_control_bl60x_update_root(const struct device *dev) clock_control_bl60x_deinit_crystal(); } - ret = clock_control_bl60x_set_root_clock_dividers(data->root.divider - 1, - data->bclk.divider - 1); - if (ret < 0) { - return ret; - } + clock_control_bl60x_set_root_clock_dividers(data->root.divider - 1, data->bclk.divider - 1); if (data->root.source == bl60x_clkid_clk_pll) { clock_control_bl60x_init_root_as_pll(dev); From a4d8ee8836a81f729ad4584ef7f2696b2536a13f Mon Sep 17 00:00:00 2001 From: Grzegorz Ferenc Date: Tue, 6 Jan 2026 11:19:53 +0100 Subject: [PATCH 1991/3659] doc: smp_svr: CDC USB port note Added a note to the USB CDC_ACM building scenario. The note reminds the user to connect to the correct USB port when programming. NCSIDB-1733. Signed-off-by: Grzegorz Ferenc --- samples/subsys/mgmt/mcumgr/smp_svr/README.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/samples/subsys/mgmt/mcumgr/smp_svr/README.rst b/samples/subsys/mgmt/mcumgr/smp_svr/README.rst index 9e4972aee23e..47d966bf4efe 100644 --- a/samples/subsys/mgmt/mcumgr/smp_svr/README.rst +++ b/samples/subsys/mgmt/mcumgr/smp_svr/README.rst @@ -104,6 +104,11 @@ included. The ``smp_svr`` sample comes in different flavours. :gen-args: -DEXTRA_CONF_FILE="cdc.conf" -DEXTRA_DTC_OVERLAY_FILE="usb.overlay" :compact: + .. note:: + If you are building the sample with the CDC overlay files + and plan to test it, make sure to connect to the USB port + on your board that is connected directly to the MCU. + .. group-tab:: Shell To build the shell sample: From 695dd30ba0a516563b34ffeb17237b5b636bca9f Mon Sep 17 00:00:00 2001 From: Muhammed Asif Date: Fri, 12 Dec 2025 18:24:16 +0530 Subject: [PATCH 1992/3659] dts: arm: microchip: pic32cx_sg : Add tc nodes - Adds the tc nodes to the common dtsi files Signed-off-by: Muhammed Asif --- .../pic32c/pic32cx_sg/common/pic32cx_sg.dtsi | 78 +++++++++++++++++++ .../pic32cx_sg/common/pic32cx_sg_100.dtsi | 24 ++++++ .../pic32cx_sg/common/pic32cx_sg_128.dtsi | 24 ++++++ 3 files changed, 126 insertions(+) diff --git a/dts/arm/microchip/pic32c/pic32cx_sg/common/pic32cx_sg.dtsi b/dts/arm/microchip/pic32c/pic32cx_sg/common/pic32cx_sg.dtsi index 3bd4c33f7b16..b1eb97dabf74 100644 --- a/dts/arm/microchip/pic32c/pic32cx_sg/common/pic32cx_sg.dtsi +++ b/dts/arm/microchip/pic32c/pic32cx_sg/common/pic32cx_sg.dtsi @@ -135,6 +135,33 @@ status = "disabled"; }; + tc0: tc@40003800 { + compatible = "microchip,tc-g1"; + reg = <0x40003800 0x400>; + interrupts = <107 0>; + clocks = <&mclkperiph CLOCK_MCHP_MCLKPERIPH_ID_APBA_TC0>, + <&gclkperiph CLOCK_MCHP_GCLKPERIPH_ID_TC0>, + <&mclkperiph CLOCK_MCHP_MCLKPERIPH_ID_APBA_TC1>; + clock-names = "mclk", "gclk", "client_mclk"; + max-bit-width = <16>; + prescaler = <1>; + channels = <2>; + status = "disabled"; + }; + + tc1: tc@40003c00 { + compatible = "microchip,tc-g1"; + reg = <0x40003c00 0x400>; + interrupts = <108 0>; + clocks = <&mclkperiph CLOCK_MCHP_MCLKPERIPH_ID_APBA_TC1>, + <&gclkperiph CLOCK_MCHP_GCLKPERIPH_ID_TC1>; + clock-names = "mclk", "gclk"; + max-bit-width = <16>; + prescaler = <1>; + channels = <2>; + status = "disabled"; + }; + nvmctrl: nvmctrl@41004000 { compatible = "microchip,nvmctrl-g1-flash"; reg = <0x41004000 0x30>; @@ -245,6 +272,33 @@ status = "disabled"; }; + tc2: tc@4101a000 { + compatible = "microchip,tc-g1"; + reg = <0x4101a000 0x400>; + interrupts = <109 0>; + clocks = <&mclkperiph CLOCK_MCHP_MCLKPERIPH_ID_APBB_TC2>, + <&gclkperiph CLOCK_MCHP_GCLKPERIPH_ID_TC2>, + <&mclkperiph CLOCK_MCHP_MCLKPERIPH_ID_APBB_TC3>; + clock-names = "mclk", "gclk", "client_mclk"; + max-bit-width = <16>; + prescaler = <1>; + channels = <2>; + status = "disabled"; + }; + + tc3: tc@4101c000 { + compatible = "microchip,tc-g1"; + reg = <0x4101c000 0x400>; + interrupts = <110 0>; + clocks = <&mclkperiph CLOCK_MCHP_MCLKPERIPH_ID_APBB_TC3>, + <&gclkperiph CLOCK_MCHP_GCLKPERIPH_ID_TC3>; + clock-names = "mclk", "gclk"; + max-bit-width = <16>; + prescaler = <1>; + channels = <2>; + status = "disabled"; + }; + tcc2: tcc@42000c00 { compatible = "microchip,tcc-g1"; reg = <0x42000c00 0x2000>; @@ -280,6 +334,30 @@ status = "disabled"; }; + tc4: tc@42001400 { + compatible = "microchip,tc-g1"; + reg = <0x42001400 0x400>; + interrupts = <111 0>; + clocks = <&mclkperiph CLOCK_MCHP_MCLKPERIPH_ID_APBC_TC4>, + <&gclkperiph CLOCK_MCHP_GCLKPERIPH_ID_TC4>; + clock-names = "mclk", "gclk"; + max-bit-width = <16>; + channels = <2>; + status = "disabled"; + }; + + tc5: tc@42001800 { + compatible = "microchip,tc-g1"; + reg = <0x42001800 0x400>; + interrupts = <112 0>; + clocks = <&mclkperiph CLOCK_MCHP_MCLKPERIPH_ID_APBC_TC5>, + <&gclkperiph CLOCK_MCHP_GCLKPERIPH_ID_TC5>; + clock-names = "mclk", "gclk"; + max-bit-width = <16>; + channels = <2>; + status = "disabled"; + }; + sercom4: sercom@43000000 { compatible = "microchip,sercom-g1"; reg = <0x43000000 0x29>; diff --git a/dts/arm/microchip/pic32c/pic32cx_sg/common/pic32cx_sg_100.dtsi b/dts/arm/microchip/pic32c/pic32cx_sg/common/pic32cx_sg_100.dtsi index 02eaf29c47c1..dca7bcb888df 100644 --- a/dts/arm/microchip/pic32c/pic32cx_sg/common/pic32cx_sg_100.dtsi +++ b/dts/arm/microchip/pic32c/pic32cx_sg/common/pic32cx_sg_100.dtsi @@ -31,6 +31,30 @@ clock-names = "mclk", "gclk"; status = "disabled"; }; + + tc6: tc@43001400 { + compatible = "microchip,tc-g1"; + reg = <0x43001400 0x400>; + interrupts = <113 0>; + clocks = <&mclkperiph CLOCK_MCHP_MCLKPERIPH_ID_APBD_TC6>, + <&gclkperiph CLOCK_MCHP_GCLKPERIPH_ID_TC6>; + clock-names = "mclk", "gclk"; + max-bit-width = <16>; + channels = <2>; + status = "disabled"; + }; + + tc7: tc@43001800 { + compatible = "microchip,tc-g1"; + reg = <0x43001800 0x400>; + interrupts = <114 0>; + clocks = <&mclkperiph CLOCK_MCHP_MCLKPERIPH_ID_APBD_TC7>, + <&gclkperiph CLOCK_MCHP_GCLKPERIPH_ID_TC7>; + clock-names = "mclk", "gclk"; + max-bit-width = <16>; + channels = <2>; + status = "disabled"; + }; }; }; diff --git a/dts/arm/microchip/pic32c/pic32cx_sg/common/pic32cx_sg_128.dtsi b/dts/arm/microchip/pic32c/pic32cx_sg/common/pic32cx_sg_128.dtsi index 6428b4c44b04..093bf0ef6aab 100644 --- a/dts/arm/microchip/pic32c/pic32cx_sg/common/pic32cx_sg_128.dtsi +++ b/dts/arm/microchip/pic32c/pic32cx_sg/common/pic32cx_sg_128.dtsi @@ -31,6 +31,30 @@ clock-names = "mclk", "gclk"; status = "disabled"; }; + + tc6: tc@43001400 { + compatible = "microchip,tc-g1"; + reg = <0x43001400 0x400>; + interrupts = <113 0>; + clocks = <&mclkperiph CLOCK_MCHP_MCLKPERIPH_ID_APBD_TC6>, + <&gclkperiph CLOCK_MCHP_GCLKPERIPH_ID_TC6>; + clock-names = "mclk", "gclk"; + max-bit-width = <16>; + channels = <2>; + status = "disabled"; + }; + + tc7: tc@43001800 { + compatible = "microchip,tc-g1"; + reg = <0x43001800 0x400>; + interrupts = <114 0>; + clocks = <&mclkperiph CLOCK_MCHP_MCLKPERIPH_ID_APBD_TC7>, + <&gclkperiph CLOCK_MCHP_GCLKPERIPH_ID_TC7>; + clock-names = "mclk", "gclk"; + max-bit-width = <16>; + channels = <2>; + status = "disabled"; + }; }; }; From 81437027cc4608e8be41e6ea0ea642cdfc0a6e7c Mon Sep 17 00:00:00 2001 From: Muhammed Asif Date: Thu, 18 Dec 2025 13:02:33 +0530 Subject: [PATCH 1993/3659] boards: microchip: pic32cx_sg61_cult: Adds pwm tc node - Adds support for pwm with tc node on the board file Signed-off-by: Muhammed Asif --- .../pic32cx_sg61_cult/pic32cx_sg61_cult-pinctrl.dtsi | 7 +++++++ .../pic32c/pic32cx_sg61_cult/pic32cx_sg61_cult.dts | 10 ++++++++++ 2 files changed, 17 insertions(+) diff --git a/boards/microchip/pic32c/pic32cx_sg61_cult/pic32cx_sg61_cult-pinctrl.dtsi b/boards/microchip/pic32c/pic32cx_sg61_cult/pic32cx_sg61_cult-pinctrl.dtsi index 496b4933c524..59463e6f07aa 100644 --- a/boards/microchip/pic32c/pic32cx_sg61_cult/pic32cx_sg61_cult-pinctrl.dtsi +++ b/boards/microchip/pic32c/pic32cx_sg61_cult/pic32cx_sg61_cult-pinctrl.dtsi @@ -21,6 +21,13 @@ }; }; + tc5_pwm_default: tc5_pwm_default { + group1 { + pinmux = , + ; + }; + }; + tcc0_pwm_default: tcc0_pwm_default { group1 { pinmux = ; diff --git a/boards/microchip/pic32c/pic32cx_sg61_cult/pic32cx_sg61_cult.dts b/boards/microchip/pic32c/pic32cx_sg61_cult/pic32cx_sg61_cult.dts index 99e15faca91b..2f5331862797 100644 --- a/boards/microchip/pic32c/pic32cx_sg61_cult/pic32cx_sg61_cult.dts +++ b/boards/microchip/pic32c/pic32cx_sg61_cult/pic32cx_sg61_cult.dts @@ -217,3 +217,13 @@ dma-names = "rx", "tx"; status = "okay"; }; + +&tc5 { + compatible = "microchip,tc-g1-pwm"; + #pwm-cells = <3>; + pinctrl-0 = <&tc5_pwm_default>; + pinctrl-names = "default"; + max-bit-width = <16>; + prescaler = <64>; + status = "okay"; +}; From d0d7df2568846fd8b51c9455274ca3b2ade002fa Mon Sep 17 00:00:00 2001 From: Muhammed Asif Date: Thu, 18 Dec 2025 13:08:42 +0530 Subject: [PATCH 1994/3659] boards: microchip: pic32cx_sg41_cult: Adds pwm tc node - Adds support for pwm with tc node on the board file Signed-off-by: Muhammed Asif --- .../pic32cx_sg41_cult/pic32cx_sg41_cult-pinctrl.dtsi | 7 +++++++ .../pic32c/pic32cx_sg41_cult/pic32cx_sg41_cult.dts | 10 ++++++++++ 2 files changed, 17 insertions(+) diff --git a/boards/microchip/pic32c/pic32cx_sg41_cult/pic32cx_sg41_cult-pinctrl.dtsi b/boards/microchip/pic32c/pic32cx_sg41_cult/pic32cx_sg41_cult-pinctrl.dtsi index ad73390481d9..b4dec783d205 100644 --- a/boards/microchip/pic32c/pic32cx_sg41_cult/pic32cx_sg41_cult-pinctrl.dtsi +++ b/boards/microchip/pic32c/pic32cx_sg41_cult/pic32cx_sg41_cult-pinctrl.dtsi @@ -21,6 +21,13 @@ }; }; + tc5_pwm_default: tc5_pwm_default { + group1 { + pinmux = , + ; + }; + }; + tcc0_pwm_default: tcc0_pwm_default { group1 { pinmux = ; diff --git a/boards/microchip/pic32c/pic32cx_sg41_cult/pic32cx_sg41_cult.dts b/boards/microchip/pic32c/pic32cx_sg41_cult/pic32cx_sg41_cult.dts index d463fc67f1d8..4656a25a3281 100644 --- a/boards/microchip/pic32c/pic32cx_sg41_cult/pic32cx_sg41_cult.dts +++ b/boards/microchip/pic32c/pic32cx_sg41_cult/pic32cx_sg41_cult.dts @@ -223,3 +223,13 @@ dma-names = "rx", "tx"; status = "okay"; }; + +&tc5 { + compatible = "microchip,tc-g1-pwm"; + #pwm-cells = <3>; + pinctrl-0 = <&tc5_pwm_default>; + pinctrl-names = "default"; + max-bit-width = <16>; + prescaler = <64>; + status = "okay"; +}; From 73efb8678c901833b28ff19be892c77dd3d7bea4 Mon Sep 17 00:00:00 2001 From: Farsin Nasar V A Date: Fri, 19 Dec 2025 15:26:27 +0530 Subject: [PATCH 1995/3659] tests: drivers: pwm: Adds pwm test support file Adds PWM test support files for pic32cx_sg41_cult Signed-off-by: Farsin Nasar V A --- tests/drivers/pwm/pwm_api/Kconfig | 8 ++++---- .../microchip/pic32cx_sg41_cult_tc5.overlay | 20 +++++++++++++++++++ tests/drivers/pwm/pwm_api/testcase.yaml | 5 ++++- 3 files changed, 28 insertions(+), 5 deletions(-) create mode 100644 tests/drivers/pwm/pwm_api/boards/microchip/pic32cx_sg41_cult_tc5.overlay diff --git a/tests/drivers/pwm/pwm_api/Kconfig b/tests/drivers/pwm/pwm_api/Kconfig index ea95c12fad61..b07406b27fb0 100644 --- a/tests/drivers/pwm/pwm_api/Kconfig +++ b/tests/drivers/pwm/pwm_api/Kconfig @@ -7,14 +7,14 @@ source "Kconfig.zephyr" config DEFAULT_PWM_PORT int "Default PWM port/channel" - default 1 if PWM_STM32 || PWM_MCHP_G1_TCC || PWM_MCHP_G1_TC + default 1 if PWM_STM32 || PWM_MCHP_G1_TCC || PWM_MCHP_TC_G1 default 0 help PWM port matching the channel associated with PWM pin. config INVALID_PWM_PORT int "Invalid PWM port/channel" - default 9 if PWM_NRFX || PWM_MCHP_G1_TCC || PWM_MCHP_G1_TC + default 9 if PWM_NRFX || PWM_MCHP_G1_TCC || PWM_MCHP_TC_G1 default -1 help Invalid PWM port/channel for negative testing. @@ -38,7 +38,7 @@ config DEFAULT_PULSE_CYCLE config DEFAULT_PERIOD_NSEC int "Default PWM period in nanoseconds" default 4000000 if SOC_FAMILY_MCXW - default 546000 if PWM_MCHP_G1_TCC || PWM_MCHP_G1_TC + default 546000 if PWM_MCHP_G1_TCC default 2000000 help Default PWM period in nanoseconds. @@ -48,7 +48,7 @@ config DEFAULT_PULSE_NSEC default 500000 if SOC_MK64F12 || SOC_MKW41Z4 || SOC_ESP32S2 || SOC_ESP32S3 || SOC_ESP32C3 default 500000 if PWM_INTEL_BLINKY default 2000000 if SOC_FAMILY_MCXW - default 273000 if PWM_MCHP_G1_TCC || PWM_MCHP_G1_TC + default 273000 if PWM_MCHP_G1_TCC default 1000000 help Default PWM pulse in nanoseconds. diff --git a/tests/drivers/pwm/pwm_api/boards/microchip/pic32cx_sg41_cult_tc5.overlay b/tests/drivers/pwm/pwm_api/boards/microchip/pic32cx_sg41_cult_tc5.overlay new file mode 100644 index 000000000000..b6c25616ed63 --- /dev/null +++ b/tests/drivers/pwm/pwm_api/boards/microchip/pic32cx_sg41_cult_tc5.overlay @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2026 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + pwm-test = &tc5; + }; +}; + +&tcc0 { + status = "disabled"; +}; + +&tc5 { + prescaler = <256>; + status = "okay"; +}; diff --git a/tests/drivers/pwm/pwm_api/testcase.yaml b/tests/drivers/pwm/pwm_api/testcase.yaml index 6a3a07856eb9..a88aaaca39f2 100644 --- a/tests/drivers/pwm/pwm_api/testcase.yaml +++ b/tests/drivers/pwm/pwm_api/testcase.yaml @@ -132,9 +132,12 @@ tests: - sam_e54_xpro filter: dt_alias_exists("pwm-test") drivers.pwm.mchp_tc5: - extra_args: DTC_OVERLAY_FILE="boards/microchip/sam_e54_xpro_tc5.overlay" + extra_args: + - DTC_OVERLAY_FILE="boards/microchip/sam_e54_xpro_tc5.overlay" + - DTC_OVERLAY_FILE="boards/microchip/pic32cx_sg41_cult_tc5.overlay" platform_allow: - sam_e54_xpro + - pic32cx_sg41_cult filter: dt_alias_exists("pwm-test") drivers.pwm.mchp_tc6: extra_args: DTC_OVERLAY_FILE="boards/microchip/sam_e54_xpro_tc6.overlay" From b72388027967e485905083923ad7d6553b81d1af Mon Sep 17 00:00:00 2001 From: Can Wang Date: Wed, 14 Jan 2026 10:56:06 +0800 Subject: [PATCH 1996/3659] Bluetooth: Classic: OBEX: adjust MOPL handling when exceeding MTU When MOPL exceeds MTU, adjust it to match MTU instead of sending the error code. This handles the common case where mainstream mobile operating systems (iPhone and Android) negotiate MOPL values greater than the RFCOMM or L2CAP MTU. Signed-off-by: Can Wang --- subsys/bluetooth/host/classic/obex.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/subsys/bluetooth/host/classic/obex.c b/subsys/bluetooth/host/classic/obex.c index 86783b70afcb..db2f3e00e230 100644 --- a/subsys/bluetooth/host/classic/obex.c +++ b/subsys/bluetooth/host/classic/obex.c @@ -219,8 +219,12 @@ static int obex_server_connect(struct bt_obex_server *server, uint16_t len, stru if (mopl > server->obex->tx.mtu) { LOG_WRN("MOPL exceeds MTU (%d > %d)", mopl, server->obex->tx.mtu); - rsp_code = BT_OBEX_RSP_CODE_PRECON_FAIL; - goto failed; + /* In mainstream mobile operating system settings, such as IPhone and Android, + * MOPL is usually greater than the MTU of rfcomm or l2cap. + * Therefore, the smaller value among them is selected as the final MOPL and + * transmitted to the application by callback. + */ + mopl = server->obex->tx.mtu; } server->tx.mopl = mopl; From 363387890db5522c86da36c5a5d8ae33063e3de7 Mon Sep 17 00:00:00 2001 From: Gaetan Perrot Date: Thu, 15 Jan 2026 02:51:12 +0900 Subject: [PATCH 1997/3659] sensing: sensor_mgmt: make init_sensor void init_sensor() never reports errors and always returns 0. The error check at the call site is therefore dead code. Make the function void and drop the unused error handling. Signed-off-by: Gaetan Perrot --- subsys/sensing/sensor_mgmt.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/subsys/sensing/sensor_mgmt.c b/subsys/sensing/sensor_mgmt.c index c8437f9eb592..c931879ce7a4 100644 --- a/subsys/sensing/sensor_mgmt.c +++ b/subsys/sensing/sensor_mgmt.c @@ -290,7 +290,7 @@ static void sensing_sensor_polling_timer(struct k_timer *timer_id) sensor_read_async_mempool(sensor->iodev, &sensing_rtio_ctx, sensor); } -static int init_sensor(struct sensing_sensor *sensor) +static void init_sensor(struct sensing_sensor *sensor) { struct sensing_submit_config *config; struct sensing_connection *conn; @@ -313,27 +313,20 @@ static int init_sensor(struct sensing_sensor *sensor) config = sensor->iodev->data; config->chan = sensing_sensor_type_to_chan(sensor->info->type); - - return 0; } static int sensing_init(const struct device *dev) { struct sensing_context *ctx = dev->data; - enum sensing_sensor_state state; int ret = 0; LOG_INF("sensing init begin..."); for_each_sensor(sensor) { - ret = init_sensor(sensor); - if (ret) { - LOG_ERR("sensor:%s initial error", sensor->dev->name); - } - state = (ret ? SENSING_SENSOR_STATE_OFFLINE : SENSING_SENSOR_STATE_READY); - ret = set_sensor_state(sensor, state); + init_sensor(sensor); + ret = set_sensor_state(sensor, SENSING_SENSOR_STATE_READY); if (ret) { - LOG_ERR("set sensor:%s state:%d error", sensor->dev->name, state); + LOG_ERR("set sensor:%s error", sensor->dev->name); } LOG_INF("sensing init, sensor:%s, state:%d", sensor->dev->name, sensor->state); } From 9f39f80e726063296549774e62a2eb5a39937f68 Mon Sep 17 00:00:00 2001 From: Gaetan Perrot Date: Thu, 15 Jan 2026 02:54:48 +0900 Subject: [PATCH 1998/3659] sensing: sensor_mgmt: make set_sensor_state void set_sensor_state() never reports errors and always returns 0. The error check at the call site is therefore dead code. Make the function void and drop the unused error handling. Signed-off-by: Gaetan Perrot --- subsys/sensing/sensor_mgmt.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/subsys/sensing/sensor_mgmt.c b/subsys/sensing/sensor_mgmt.c index c931879ce7a4..8b466fdae27f 100644 --- a/subsys/sensing/sensor_mgmt.c +++ b/subsys/sensing/sensor_mgmt.c @@ -252,13 +252,11 @@ static void save_config_and_notify(struct sensing_sensor *sensor) k_sem_give(&ctx->event_sem); } -static int set_sensor_state(struct sensing_sensor *sensor, enum sensing_sensor_state state) +static void set_sensor_state(struct sensing_sensor *sensor, enum sensing_sensor_state state) { __ASSERT(sensor, "set sensor state, sensing_sensor is NULL"); sensor->state = state; - - return 0; } static void init_connection(struct sensing_connection *conn, @@ -318,16 +316,12 @@ static void init_sensor(struct sensing_sensor *sensor) static int sensing_init(const struct device *dev) { struct sensing_context *ctx = dev->data; - int ret = 0; LOG_INF("sensing init begin..."); for_each_sensor(sensor) { init_sensor(sensor); - ret = set_sensor_state(sensor, SENSING_SENSOR_STATE_READY); - if (ret) { - LOG_ERR("set sensor:%s error", sensor->dev->name); - } + set_sensor_state(sensor, SENSING_SENSOR_STATE_READY); LOG_INF("sensing init, sensor:%s, state:%d", sensor->dev->name, sensor->state); } @@ -336,7 +330,7 @@ static int sensing_init(const struct device *dev) LOG_INF("create sensing runtime thread ok"); ctx->sensing_initialized = true; - return ret; + return 0; } int open_sensor(struct sensing_sensor *sensor, struct sensing_connection **conn) From 31863b30ae65b5ae6fe4f3c209cf1ff360d7bfab Mon Sep 17 00:00:00 2001 From: Yasushi SHOJI Date: Thu, 15 Jan 2026 10:37:15 +0900 Subject: [PATCH 1999/3659] soc: xlnx: versal: Select VFPv3-D16 The Versal RPU uses Arm Cortex-R5F cores, which implement VFPv3-D16 (single and double precision with 16 double-word registers):. Select VFP_DP_D16 to describe the available VFP configuration for this SoC. Signed-off-by: Yasushi SHOJI --- soc/xlnx/versal/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/soc/xlnx/versal/Kconfig b/soc/xlnx/versal/Kconfig index e92e59ffe806..464c38e43c40 100644 --- a/soc/xlnx/versal/Kconfig +++ b/soc/xlnx/versal/Kconfig @@ -9,4 +9,5 @@ config SOC_VERSAL_RPU select CPU_CORTEX_R5 select CPU_HAS_ARM_MPU select CPU_HAS_DCLS + select VFP_DP_D16 select SOC_RESET_HOOK From 47ae7f4a502cb93ff315995bac6b9a17017935ff Mon Sep 17 00:00:00 2001 From: Gaetan Perrot Date: Thu, 15 Jan 2026 03:09:18 +0900 Subject: [PATCH 2000/3659] pmci: mctp: mctp_i3c_controller: remove dead code in controller start mctp_i3c_controller_start() contains a conditional check on a return code that is never updated, making the error handling path unreachable. Remove the dead code to avoid misleading logic and make the current controller startup behavior explicit. Signed-off-by: Gaetan Perrot --- subsys/pmci/mctp/mctp_i3c_controller.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/subsys/pmci/mctp/mctp_i3c_controller.c b/subsys/pmci/mctp/mctp_i3c_controller.c index 22027384b6ef..d229ca27f073 100644 --- a/subsys/pmci/mctp/mctp_i3c_controller.c +++ b/subsys/pmci/mctp/mctp_i3c_controller.c @@ -128,15 +128,11 @@ int mctp_i3c_controller_tx(struct mctp_binding *binding, struct mctp_pktbuf *pkt int mctp_i3c_controller_start(struct mctp_binding *binding) { - int rc = 0; + int rc; struct mctp_binding_i3c_controller *b = CONTAINER_OF(binding, struct mctp_binding_i3c_controller, binding); - if (rc != 0) { - LOG_WRN("Could not do dynamic address assignment"); - } - for (int i = 0; i < b->num_endpoints; i++) { mctp_i3c_endpoint_bind(b->devices[i], b, &b->endpoint_i3c_devs[i]); LOG_INF("Enabling IBI for TARGET %p PID %llx BCR %x", From c4bd68def0e7c9d45414db91f8842755833911d7 Mon Sep 17 00:00:00 2001 From: Florijan Plohl Date: Wed, 5 Mar 2025 13:01:27 +0100 Subject: [PATCH 2001/3659] dts: arm: phytec: add support for phyCORE-RT1170 SOM Add phyCORE-1170 SOM dtsi for streamlined inclusion on carrier boards and uses a dual-core NXP i.MX RT1170 SoC as a basis. Signed-off-by: Florijan Plohl Signed-off-by: Daniel Schultz --- dts/arm/phytec/phycore_rt1170-pinctrl.dtsi | 84 +++++++++++ dts/arm/phytec/phycore_rt1170_common.dtsi | 138 ++++++++++++++++++ .../phytec/phycore_rt1170_mimxrt1176_cm7.dtsi | 78 ++++++++++ 3 files changed, 300 insertions(+) create mode 100644 dts/arm/phytec/phycore_rt1170-pinctrl.dtsi create mode 100644 dts/arm/phytec/phycore_rt1170_common.dtsi create mode 100644 dts/arm/phytec/phycore_rt1170_mimxrt1176_cm7.dtsi diff --git a/dts/arm/phytec/phycore_rt1170-pinctrl.dtsi b/dts/arm/phytec/phycore_rt1170-pinctrl.dtsi new file mode 100644 index 000000000000..64be58db08a6 --- /dev/null +++ b/dts/arm/phytec/phycore_rt1170-pinctrl.dtsi @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2025 PHYTEC America LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&pinctrl { + 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_emc_b2_19_enet_1g_mdc>, + <&iomuxc_gpio_emc_b2_20_enet_1g_mdio>; + drive-strength = "high"; + bias-pull-down; + slew-rate = "fast"; + }; + + group1 { + pinmux = <&iomuxc_gpio_disp_b2_01_gpio_mux5_io02>; /* ETHPHY_RST */ + drive-strength = "high"; + bias-pull-down; + slew-rate = "slow"; + }; + }; + + pinmux_flexspi1: pinmux_flexspi1 { + group0 { + pinmux = <&iomuxc_gpio_sd_b2_05_flexspi1_a_dqs>, + <&iomuxc_gpio_sd_b2_06_flexspi1_a_ss0_b>, + <&iomuxc_gpio_sd_b2_07_flexspi1_a_sclk>, + <&iomuxc_gpio_sd_b2_08_flexspi1_a_data00>, + <&iomuxc_gpio_sd_b2_09_flexspi1_a_data01>, + <&iomuxc_gpio_sd_b2_10_flexspi1_a_data02>, + <&iomuxc_gpio_sd_b2_11_flexspi1_a_data03>; + bias-pull-down; + input-enable; + }; + }; + + pinmux_lpi2c2: pinmux_lpi2c2 { + group0 { + pinmux = <&iomuxc_gpio_ad_18_lpi2c2_scl>, + <&iomuxc_gpio_ad_19_lpi2c2_sda>; + drive-strength = "normal"; + drive-open-drain; + slew-rate = "fast"; + input-enable; + }; + }; +}; diff --git a/dts/arm/phytec/phycore_rt1170_common.dtsi b/dts/arm/phytec/phycore_rt1170_common.dtsi new file mode 100644 index 000000000000..80d8c9393513 --- /dev/null +++ b/dts/arm/phytec/phycore_rt1170_common.dtsi @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2025 PHYTEC America LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + sdram0: memory@80000000 { + /* MT48LC16M16A2B4-7EIT */ + device_type = "memory"; + reg = <0x80000000 DT_SIZE_M(64)>; + }; + + leds { + compatible = "gpio-leds"; + + som_green_led: led-1 { + gpios = <&gpio13 12 GPIO_ACTIVE_HIGH>; + label = "Green LED D8"; + }; + + som_red_led: led-2 { + gpios = <&gpio13 11 GPIO_ACTIVE_HIGH>; + label = "Red LED D7"; + }; + }; + + soc { + snvs: snvs@40c90000 { + compatible = "nxp,imx-snvs"; + reg = <0x40c90000 0x4000>; + + snvs_rtc: rtc { + compatible = "nxp,imx-snvs-rtc"; + interrupts = <66 0>; + }; + }; + }; +}; + +&lpi2c2 { + pinctrl-0 = <&pinmux_lpi2c2>; + pinctrl-names = "default"; + status = "okay"; + + eeprom0: eeprom@50 { + compatible = "st,m24xxx", "atmel,at24"; + reg = <0x50>; + status = "okay"; + size = <256>; + pagesize = <8>; + address-width = <16>; + timeout = <5>; + }; +}; + +&enet1g { + status = "okay"; +}; + +&enet1g_mac { + status = "okay"; + pinctrl-0 = <&pinmux_enet1g>; + pinctrl-names = "default"; + phy-handle = <&enet1g_phy>; + phy-connection-type = "rgmii"; + zephyr,random-mac-address; +}; + +&enet1g_mdio { + status = "okay"; + pinctrl-0 = <&pinmux_enet1g_mdio>; + pinctrl-names = "default"; + + enet1g_phy: phy@0 { + compatible = "ti,dp83867"; + reg = <0>; + status = "okay"; + reset-gpios = <&gpio5 2 GPIO_ACTIVE_HIGH>; + int-gpios = <&gpio5 15 GPIO_ACTIVE_LOW>; + }; +}; + +&flexspi { + pinctrl-0 = <&pinmux_flexspi1>; + pinctrl-names = "default"; +}; + +&flexspi { + status = "okay"; + ahb-prefetch; + ahb-read-addr-opt; + rx-clock-source = <1>; + reg = <0x400cc000 0x4000>, <0x30000000 DT_SIZE_M(16)>; + + mx25u12832f: mx25u12832f@0 { + compatible = "nxp,imx-flexspi-nor"; + /* MX25U12832FM2I02 is 16MB, 128MBit flash part */ + size = ; + reg = <0>; + spi-max-frequency = <100000000>; + status = "okay"; + jedec-id = [c2 25 38]; + erase-block-size = <4096>; + write-block-size = <1>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 DT_SIZE_K(128)>; + }; + + /* Note slot 0 has one additional sector, + * this is intended for use with the swap move algorithm + */ + slot0_partition: partition@20000 { + label = "image-0"; + reg = <0x00020000 0x301000>; + }; + + slot1_partition: partition@321000 { + label = "image-1"; + reg = <0x00321000 0x300000>; + }; + + storage_partition: partition@621000 { + label = "storage"; + reg = <0x00621000 DT_SIZE_K(1984)>; + }; + }; + }; +}; diff --git a/dts/arm/phytec/phycore_rt1170_mimxrt1176_cm7.dtsi b/dts/arm/phytec/phycore_rt1170_mimxrt1176_cm7.dtsi new file mode 100644 index 000000000000..76bed82929b6 --- /dev/null +++ b/dts/arm/phytec/phycore_rt1170_mimxrt1176_cm7.dtsi @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2025 PHYTEC America LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include + +/ { + chosen { + zephyr,sram = &sdram0; + zephyr,dtcm = &dtcm; + zephyr,itcm = &itcm; + zephyr,flash-controller = &mx25u12832f; + zephyr,flash = &mx25u12832f; + zephyr,code-partition = &slot0_partition; + zephyr,cpu1-region = &ocram; + zephyr,ipc = &mailbox_a; + }; + + zephyr,user { + dac = <&dac>; + dac-channel-id = <0>; + dac-resolution = <12>; + }; +}; + +&dac { + status = "okay"; +}; + +&lpuart1 { + status = "okay"; + current-speed = <115200>; +}; + +&lpuart5 { + status = "okay"; + current-speed = <115200>; +}; + +&som_green_led { + status = "okay"; +}; + +&som_red_led { + status = "okay"; +}; + +/* GPT and Systick are enabled. If power management is enabled, the GPT + * timer will be used instead of systick, as allows the core clock to + * be gated. + */ +&gpt_hw_timer { + status = "okay"; +}; + +&systick { + status = "okay"; +}; + +&wdog1 { + status = "okay"; +}; + +&mailbox_a { + status = "okay"; +}; + +&pit1 { + status = "okay"; +}; + +&pit2 { + status = "okay"; +}; From b56a4e100097c6305f17cf214a6ac5ae221aef22 Mon Sep 17 00:00:00 2001 From: Daniel Schultz Date: Thu, 26 Jun 2025 09:14:52 +0200 Subject: [PATCH 2002/3659] boards: phytec: add support for phyBOARD-Atlas i.MX RT1170 Add initial support for PHYTEC phyBOARD-Atlas i.MX RT1170 based on the PHYTEC phyCORE-i.MX RT1170 SOM. SOM uses dual-core NXP i.MX RT1170 SoC as a basis, with Cortex-M7 core running at 1 GHz and Cortex-M4 core at 400 MHz. Supported features: * Accelerometer * Audio codec * CAN * DAC * EEPROM * Ethernet * External display * I2C * RS-232 * SD-Card * SPI * UART * USB Signed-off-by: John Ma Signed-off-by: Florijan Plohl Signed-off-by: Daniel Schultz --- boards/phytec/phyboard_atlas/CMakeLists.txt | 32 + .../phytec/phyboard_atlas/Kconfig.defconfig | 37 + .../phyboard_atlas/Kconfig.phyboard_atlas | 8 + boards/phytec/phyboard_atlas/board.cmake | 27 + boards/phytec/phyboard_atlas/board.yml | 6 + boards/phytec/phyboard_atlas/dcd/dcd.c | 887 ++++++++++++++++++ boards/phytec/phyboard_atlas/dcd/dcd.h | 18 + .../doc/img/phyboard_atlas.webp | Bin 0 -> 56534 bytes boards/phytec/phyboard_atlas/doc/index.rst | 346 +++++++ .../phyboard_atlas-pinctrl.dtsi | 325 +++++++ .../phytec/phyboard_atlas/phyboard_atlas.dtsi | 211 +++++ .../phyboard_atlas_mimxrt1176_cm7.dts | 152 +++ .../phyboard_atlas_mimxrt1176_cm7.yaml | 29 + .../phyboard_atlas_mimxrt1176_cm7_defconfig | 9 + ...phyboard_atlas_mimxrt1176_cm7_usb2.overlay | 8 + .../xip/phycore_rt1170_flexspi_nor_config.c | 89 ++ .../xip/phycore_rt1170_flexspi_nor_config.h | 375 ++++++++ boards/phytec/phyboard_atlas/xmcd/xmcd.c | 34 + boards/phytec/phyboard_atlas/xmcd/xmcd.h | 13 + 19 files changed, 2606 insertions(+) create mode 100644 boards/phytec/phyboard_atlas/CMakeLists.txt create mode 100644 boards/phytec/phyboard_atlas/Kconfig.defconfig create mode 100644 boards/phytec/phyboard_atlas/Kconfig.phyboard_atlas create mode 100644 boards/phytec/phyboard_atlas/board.cmake create mode 100644 boards/phytec/phyboard_atlas/board.yml create mode 100644 boards/phytec/phyboard_atlas/dcd/dcd.c create mode 100644 boards/phytec/phyboard_atlas/dcd/dcd.h create mode 100644 boards/phytec/phyboard_atlas/doc/img/phyboard_atlas.webp create mode 100644 boards/phytec/phyboard_atlas/doc/index.rst create mode 100644 boards/phytec/phyboard_atlas/phyboard_atlas-pinctrl.dtsi create mode 100644 boards/phytec/phyboard_atlas/phyboard_atlas.dtsi create mode 100644 boards/phytec/phyboard_atlas/phyboard_atlas_mimxrt1176_cm7.dts create mode 100644 boards/phytec/phyboard_atlas/phyboard_atlas_mimxrt1176_cm7.yaml create mode 100644 boards/phytec/phyboard_atlas/phyboard_atlas_mimxrt1176_cm7_defconfig create mode 100644 boards/phytec/phyboard_atlas/phyboard_atlas_mimxrt1176_cm7_usb2.overlay create mode 100644 boards/phytec/phyboard_atlas/xip/phycore_rt1170_flexspi_nor_config.c create mode 100644 boards/phytec/phyboard_atlas/xip/phycore_rt1170_flexspi_nor_config.h create mode 100644 boards/phytec/phyboard_atlas/xmcd/xmcd.c create mode 100644 boards/phytec/phyboard_atlas/xmcd/xmcd.h diff --git a/boards/phytec/phyboard_atlas/CMakeLists.txt b/boards/phytec/phyboard_atlas/CMakeLists.txt new file mode 100644 index 000000000000..576a480cdaa6 --- /dev/null +++ b/boards/phytec/phyboard_atlas/CMakeLists.txt @@ -0,0 +1,32 @@ +# +# Copyright 2025 PHYTEC America, LLC +# +# SPDX-License-Identifier: Apache-2.0 +# + +if(CONFIG_NXP_IMXRT_BOOT_HEADER) + zephyr_library() + set(RT1170_BOARD_NAME "phycore_rt1170") + + if(CONFIG_BOOT_FLEXSPI_NOR) + zephyr_library_sources(xip/${RT1170_BOARD_NAME}_flexspi_nor_config.c) + zephyr_library_include_directories(xip) + endif() + + if(CONFIG_EXTERNAL_MEM_CONFIG_DATA) + zephyr_library_compile_definitions(XIP_BOOT_HEADER_XMCD_ENABLE=1) + zephyr_library_sources(xmcd/xmcd.c) + else() + if(CONFIG_SRAM_BASE_ADDRESS EQUAL 0x80000000) + message(WARNING "You are using SDRAM as RAM but no external memory" + "configuration data (XMCD) is included. This configuration may not boot") + endif() + endif() + +endif() + +if(CONFIG_MCUX_GPT_TIMER) + message(WARNING "You appear to be using the GPT hardware timer. " + "This timer will enable lower power modes, but at the cost of reduced " + "hardware timer resolution") +endif() diff --git a/boards/phytec/phyboard_atlas/Kconfig.defconfig b/boards/phytec/phyboard_atlas/Kconfig.defconfig new file mode 100644 index 000000000000..799a446d568b --- /dev/null +++ b/boards/phytec/phyboard_atlas/Kconfig.defconfig @@ -0,0 +1,37 @@ +# PHYBOARD-ATLAS + +# Copyright (c) 2025 PHYTEC America, LLC +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_PHYBOARD_ATLAS + +if CPU_CORTEX_M7 + +# Use External Memory Configuration Data (XMCD) by default when booting primary core (M7) +config EXTERNAL_MEM_CONFIG_DATA + default y + +config NXP_IMX_EXTERNAL_SDRAM + default y + +configdefault NET_L2_ETHERNET + default y # No cache memory support is required for driver + +endif # CPU_CORTEX_M7 + +if SECOND_CORE_MCUX && CPU_CORTEX_M4 + +config BUILD_OUTPUT_INFO_HEADER + default y + +DT_CHOSEN_IMAGE_M4 = nxp,m4-partition + +# Adjust the offset of the output image if building for RT11xx SOC +config BUILD_OUTPUT_ADJUST_LMA + default "($(dt_chosen_reg_addr_hex,$(DT_CHOSEN_IMAGE_M4)) + \ + $(dt_node_reg_addr_hex,/soc/spi@400cc000,1)) - \ + $(dt_node_reg_addr_hex,/soc/ocram@20200000)" + +endif # SECOND_CORE_MCUX && CPU_CORTEX_M4 + +endif # BOARD_PHYBOARD_ATLAS diff --git a/boards/phytec/phyboard_atlas/Kconfig.phyboard_atlas b/boards/phytec/phyboard_atlas/Kconfig.phyboard_atlas new file mode 100644 index 000000000000..cb3c0a77ff7d --- /dev/null +++ b/boards/phytec/phyboard_atlas/Kconfig.phyboard_atlas @@ -0,0 +1,8 @@ +# +# Copyright 2025 PHYTEC America, LLC +# +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_PHYBOARD_ATLAS + select SOC_PART_NUMBER_MIMXRT1176DVMAA + select SOC_MIMXRT1176_CM7 if BOARD_PHYBOARD_ATLAS_MIMXRT1176_CM7 diff --git a/boards/phytec/phyboard_atlas/board.cmake b/boards/phytec/phyboard_atlas/board.cmake new file mode 100644 index 000000000000..c2f0b61896bf --- /dev/null +++ b/boards/phytec/phyboard_atlas/board.cmake @@ -0,0 +1,27 @@ +# +# Copyright 2025 PHYTEC America, LLC +# +# SPDX-License-Identifier: Apache-2.0 +# + +if(CONFIG_SOC_MIMXRT1176_CM7 OR CONFIG_SECOND_CORE_MCUX) + board_runner_args(linkserver "--no-reset") + board_runner_args(pyocd "--target=mimxrt1170_cm7") + board_runner_args(jlink "--device=MIMXRT1176xxxA_M7") + board_runner_args(jlink "--no-reset") + + board_runner_args(linkserver "--device=MIMXRT1176xxxxx:MIMXRT1170-EVK") + board_runner_args(linkserver "--core=cm7") +elseif(CONFIG_SOC_MIMXRT1176_CM4) + board_runner_args(pyocd "--target=mimxrt1170_cm4") + # Note: Use J-Link version 7.50 or later. Debugging only supports running + # the CM4 image, since the board’s default boot core is CM7. + board_runner_args(jlink "--device=MIMXRT1176xxxA_M4") + + board_runner_args(linkserver "--device=MIMXRT1176xxxxx:MIMXRT1170-EVK") + board_runner_args(linkserver "--core=cm4") +endif() + +include(${ZEPHYR_BASE}/boards/common/linkserver.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) +include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake) diff --git a/boards/phytec/phyboard_atlas/board.yml b/boards/phytec/phyboard_atlas/board.yml new file mode 100644 index 000000000000..acde92130990 --- /dev/null +++ b/boards/phytec/phyboard_atlas/board.yml @@ -0,0 +1,6 @@ +board: + name: phyboard_atlas + full_name: phyBOARD-Atlas i.MX RT1170 + vendor: phytec + socs: + - name: mimxrt1176 diff --git a/boards/phytec/phyboard_atlas/dcd/dcd.c b/boards/phytec/phyboard_atlas/dcd/dcd.c new file mode 100644 index 000000000000..c8b675eb9a5b --- /dev/null +++ b/boards/phytec/phyboard_atlas/dcd/dcd.c @@ -0,0 +1,887 @@ +/* + * Copyright 2020-2021 NXP + * All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "dcd.h" + +#if defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_BOOT_FLEXSPI_NOR) +#if defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_DEVICE_CONFIGURATION_DATA) +__attribute__((section(".boot_hdr.dcd_data"), used)) + +const uint8_t dcd_data[] = { + /* HEADER */ + /* Tag */ + 0xD2, + /* Image Length */ + 0x04, 0xB8, + /* Version */ + 0x41, + + /* COMMANDS */ + + /* group: 'Imported Commands' */ + /* #1.1-129, command header bytes for merged 'Write - value' command */ + 0xCC, 0x04, 0x0C, 0x04, + /* #1.1, command: write_value, address: + * CCM_CLOCK_ROOT4_CONTROL, + * value: 0x00, 0x703, size: 4 + */ + 0x40, 0xCC, 0x02, 0x00, 0x00, 0x00, 0x07, 0x03, + /* #1.2, command: write_value, address: + * IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_B1_00, + * value: 0x00, + * size: 4 + */ + 0x40, 0x0E, 0x80, 0x10, 0x00, 0x00, 0x00, 0x00, + /* #1.3, command: write_value, address: + * IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_B1_01, + * value: 0x00, 0x00, + * size: 4 + */ + 0x40, 0x0E, 0x80, 0x14, 0x00, 0x00, 0x00, 0x00, + /* #1.4, command: write_value, address: + * IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_B1_02, + * value: 0x00, 0x00, + * size: 4 + */ + 0x40, 0x0E, 0x80, 0x18, 0x00, 0x00, 0x00, 0x00, + /* #1.5, command: write_value, address: + * IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_B1_03, + * value: 0x00, 0x00, + * size: 4 + */ + 0x40, 0x0E, 0x80, 0x1C, 0x00, 0x00, 0x00, 0x00, + /* #1.6, command: write_value, address: + * IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_B1_04, + * value: 0x00, 0x00, + * size: 4 + */ + 0x40, 0x0E, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, + /* #1.7, command: write_value, address: + * IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_B1_05, + * value: 0x00, 0x00, + * size: 4 + */ + 0x40, 0x0E, 0x80, 0x24, 0x00, 0x00, 0x00, 0x00, + /* #1.8, command: write_value, address: + * IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_B1_06, + * value: 0x00, 0x00, + * size: 4 + */ + 0x40, 0x0E, 0x80, 0x28, 0x00, 0x00, 0x00, 0x00, + /* #1.9, command: write_value, address: + * IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_B1_07, + * value: 0x00, 0x00, + * size: 4 + */ + 0x40, 0x0E, 0x80, 0x2C, 0x00, 0x00, 0x00, 0x00, + /* #1.10, command: write_value, address: + * IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_B1_08, + * value: 0x00, 0x00, + * size: 4 + */ + 0x40, 0x0E, 0x80, 0x30, 0x00, 0x00, 0x00, 0x00, + /* #1.11, command: write_value, address: + * IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_B1_09, + * value: 0x00, 0x00, + * size: 4 + */ + 0x40, 0x0E, 0x80, 0x34, 0x00, 0x00, 0x00, 0x00, + /* #1.12, command: write_value, address: + * IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_B1_10, + * value: 0x00, 0x00, + * size: 4 + */ + 0x40, 0x0E, 0x80, 0x38, 0x00, 0x00, 0x00, 0x00, + /* #1.13, command: write_value, address: + * IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_B1_11, + * value: 0x00, 0x00, + * size: 4 + */ + 0x40, 0x0E, 0x80, 0x3C, 0x00, 0x00, 0x00, 0x00, + /* #1.14, command: write_value, address: + * IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_B1_12, + * value: 0x00, 0x00, + * size: 4 + */ + 0x40, 0x0E, 0x80, 0x40, 0x00, 0x00, 0x00, 0x00, + /* #1.15, command: write_value, address: + * IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_B1_13, + * value: 0x00, 0x00, + * size: 4 + */ + 0x40, 0x0E, 0x80, 0x44, 0x00, 0x00, 0x00, 0x00, + /* #1.16, command: write_value, address: + * IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_B1_14, + * value: 0x00, 0x00, + * size: 4 + */ + 0x40, 0x0E, 0x80, 0x48, 0x00, 0x00, 0x00, 0x00, + /* #1.17, command: write_value, address: + * IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_B1_15, + * value: 0x00, 0x00, + * size: 4 + */ + 0x40, 0x0E, 0x80, 0x4C, 0x00, 0x00, 0x00, 0x00, + /* #1.18, command: write_value, address: + * IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_B1_16, + * value: 0x00, 0x00, + * size: 4 + */ + 0x40, 0x0E, 0x80, 0x50, 0x00, 0x00, 0x00, 0x00, + /* #1.19, command: write_value, address: + * IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_B1_17, + * value: 0x00, 0x00, + * size: 4 + */ + 0x40, 0x0E, 0x80, 0x54, 0x00, 0x00, 0x00, 0x00, + /* #1.20, command: write_value, address: + * IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_B1_18, + * value: 0x00, 0x00, + * size: 4 + */ + 0x40, 0x0E, 0x80, 0x58, 0x00, 0x00, 0x00, 0x00, + /* #1.21, command: write_value, address: + * IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_B1_19, + * value: 0x00, 0x00, + * size: 4 + */ + 0x40, 0x0E, 0x80, 0x5C, 0x00, 0x00, 0x00, 0x00, + /* #1.22, command: write_value, address: + * IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_B1_20, + * value: 0x00, 0x00, + * size: 4 + */ + 0x40, 0x0E, 0x80, 0x60, 0x00, 0x00, 0x00, 0x00, + /* #1.23, command: write_value, address: + * IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_B1_21, + * value: 0x00, 0x00, + * size: 4 + */ + 0x40, 0x0E, 0x80, 0x64, 0x00, 0x00, 0x00, 0x00, + /* #1.24, command: write_value, address: + * IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_B1_22, + * value: 0x00, 0x00, + * size: 4 + */ + 0x40, 0x0E, 0x80, 0x68, 0x00, 0x00, 0x00, 0x00, + /* #1.25, command: write_value, address: + * IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_B1_23, + * value: 0x00, 0x00, + * size: 4 + */ + 0x40, 0x0E, 0x80, 0x6C, 0x00, 0x00, 0x00, 0x00, + /* #1.26, command: write_value, address: + * IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_B1_24, + * value: 0x00, 0x00, + * size: 4 + */ + 0x40, 0x0E, 0x80, 0x70, 0x00, 0x00, 0x00, 0x00, + /* #1.27, command: write_value, address: + * IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_B1_25, + * value: 0x00, 0x00, + * size: 4 + */ + 0x40, 0x0E, 0x80, 0x74, 0x00, 0x00, 0x00, 0x00, + /* #1.28, command: write_value, address: + * IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_B1_26, + * value: 0x00, 0x00, + * size: 4 + */ + 0x40, 0x0E, 0x80, 0x78, 0x00, 0x00, 0x00, 0x00, + /* #1.29, command: write_value, address: + * IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_B1_27, + * value: 0x00, 0x00, + * size: 4 + */ + 0x40, 0x0E, 0x80, 0x7C, 0x00, 0x00, 0x00, 0x00, + /* #1.30, command: write_value, address: + * IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_B1_28, + * value: 0x00, 0x00, + * size: 4 + */ + 0x40, 0x0E, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, + /* #1.31, command: write_value, address: + * IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_B1_29, + * value: 0x00, 0x00, + * size: 4 + */ + 0x40, 0x0E, 0x80, 0x84, 0x00, 0x00, 0x00, 0x00, + /* #1.32, command: write_value, address: + * IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_B1_30, + * value: 0x00, 0x00, + * size: 4 + */ + 0x40, 0x0E, 0x80, 0x88, 0x00, 0x00, 0x00, 0x00, + /* #1.33, command: write_value, address: + * IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_B1_31, + * value: 0x00, 0x00, + * size: 4 + */ + 0x40, 0x0E, 0x80, 0x8C, 0x00, 0x00, 0x00, 0x00, + /* #1.34, command: write_value, address: + * IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_B1_32, + * value: 0x00, 0x00, + * size: 4 + */ + 0x40, 0x0E, 0x80, 0x90, 0x00, 0x00, 0x00, 0x00, + /* #1.35, command: write_value, address: + * IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_B1_33, + * value: 0x00, 0x00, + * size: 4 + */ + 0x40, 0x0E, 0x80, 0x94, 0x00, 0x00, 0x00, 0x00, + /* #1.36, command: write_value, address: + * IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_B1_34, + * value: 0x00, 0x00, + * size: 4 + */ + 0x40, 0x0E, 0x80, 0x98, 0x00, 0x00, 0x00, 0x00, + /* #1.37, command: write_value, address: + * IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_B1_35, + * value: 0x00, 0x00, + * size: 4 + */ + 0x40, 0x0E, 0x80, 0x9C, 0x00, 0x00, 0x00, 0x00, + /* #1.38, command: write_value, address: + * IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_B1_36, + * value: 0x00, 0x00, + * size: 4 + */ + 0x40, 0x0E, 0x80, 0xA0, 0x00, 0x00, 0x00, 0x00, + /* #1.39, command: write_value, address: + * IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_B1_37, + * value: 0x00, 0x00, + * size: 4 + */ + 0x40, 0x0E, 0x80, 0xA4, 0x00, 0x00, 0x00, 0x00, + /* #1.40, command: write_value, address: + * IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_B1_38, + * value: 0x00, 0x00, + * size: 4 + */ + 0x40, 0x0E, 0x80, 0xA8, 0x00, 0x00, 0x00, 0x00, + /* #1.41, command: write_value, address: + * IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_B1_39, + * value: 0x00, 0x10, + * size: 4 + */ + 0x40, 0x0E, 0x80, 0xAC, 0x00, 0x00, 0x00, 0x10, + /* #1.42, command: write_value, address: + * IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_B2_00, + * value: 0x00, 0x00, + * size: 4 + */ + 0x40, 0x0E, 0x80, 0xB8, 0x00, 0x00, 0x00, 0x00, + /* #1.43, command: write_value, address: + * IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_B2_01, + * value: 0x00, 0x00, + * size: 4 + */ + 0x40, 0x0E, 0x80, 0xBC, 0x00, 0x00, 0x00, 0x00, + /* #1.44, command: write_value, address: + * IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_B2_02, + * value: 0x00, 0x00, + * size: 4 + */ + 0x40, 0x0E, 0x80, 0xC0, 0x00, 0x00, 0x00, 0x00, + /* #1.45, command: write_value, address: + * IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_B2_03, + * value: 0x00, 0x00, + * size: 4 + */ + 0x40, 0x0E, 0x80, 0xC4, 0x00, 0x00, 0x00, 0x00, + /* #1.46, command: write_value, address: + * IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_B2_04, + * value: 0x00, 0x00, + * size: 4 + */ + 0x40, 0x0E, 0x80, 0xC8, 0x00, 0x00, 0x00, 0x00, + /* #1.47, command: write_value, address: + * IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_B2_05, + * value: 0x00, 0x00, + * size: 4 + */ + 0x40, 0x0E, 0x80, 0xCC, 0x00, 0x00, 0x00, 0x00, + /* #1.48, command: write_value, address: + * IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_B2_06, + * value: 0x00, 0x00, + * size: 4 + */ + 0x40, 0x0E, 0x80, 0xD0, 0x00, 0x00, 0x00, 0x00, + /* #1.49, command: write_value, address: + * IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_B2_07, + * value: 0x00, 0x00, + * size: 4 + */ + 0x40, 0x0E, 0x80, 0xD4, 0x00, 0x00, 0x00, 0x00, + /* #1.50, command: write_value, address: + * IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_B2_08, + * value: 0x00, 0x00, + * size: 4 + */ + 0x40, 0x0E, 0x80, 0xD8, 0x00, 0x00, 0x00, 0x00, + /* #1.51, command: write_value, address: + * IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_B2_09, + * value: 0x00, 0x00, + * size: 4 + */ + 0x40, 0x0E, 0x80, 0xDC, 0x00, 0x00, 0x00, 0x00, + /* #1.52, command: write_value, address: + * IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_B2_10, + * value: 0x00, 0x00, + * size: 4 + */ + 0x40, 0x0E, 0x80, 0xE0, 0x00, 0x00, 0x00, 0x00, + /* #1.53, command: write_value, address: + * IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_B2_11, + * value: 0x00, 0x00, + * size: 4 + */ + 0x40, 0x0E, 0x80, 0xE4, 0x00, 0x00, 0x00, 0x00, + /* #1.54, command: write_value, address: + * IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_B2_12, + * value: 0x00, 0x00, + * size: 4 + */ + 0x40, 0x0E, 0x80, 0xE8, 0x00, 0x00, 0x00, 0x00, + /* #1.55, command: write_value, address: + * IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_B2_13, + * value: 0x00, 0x00, + * size: 4 + */ + 0x40, 0x0E, 0x80, 0xEC, 0x00, 0x00, 0x00, 0x00, + /* #1.56, command: write_value, address: + * IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_B2_14, + * value: 0x00, 0x00, + * size: 4 + */ + 0x40, 0x0E, 0x80, 0xF0, 0x00, 0x00, 0x00, 0x00, + /* #1.57, command: write_value, address: + * IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_B2_15, + * value: 0x00, 0x00, + * size: 4 + */ + 0x40, 0x0E, 0x80, 0xF4, 0x00, 0x00, 0x00, 0x00, + /* #1.58, command: write_value, address: + * IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_B2_16, + * value: 0x00, 0x00, + * size: 4 + */ + 0x40, 0x0E, 0x80, 0xF8, 0x00, 0x00, 0x00, 0x00, + /* #1.59, command: write_value, address: + * IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_B2_17, + * value: 0x00, 0x00, + * size: 4 + */ + 0x40, 0x0E, 0x80, 0xFC, 0x00, 0x00, 0x00, 0x00, + /* #1.60, command: write_value, address: + * IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_B1_00, + * value: 0x00, 0x08, + * size: 4 + */ + 0x40, 0x0E, 0x82, 0x54, 0x00, 0x00, 0x00, 0x08, + /* #1.61, command: write_value, address: + * IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_B1_01, + * value: 0x00, 0x08, + * size: 4 + */ + 0x40, 0x0E, 0x82, 0x58, 0x00, 0x00, 0x00, 0x08, + /* #1.62, command: write_value, address: + * IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_B1_02, + * value: 0x00, 0x08, + * size: 4 + */ + 0x40, 0x0E, 0x82, 0x5C, 0x00, 0x00, 0x00, 0x08, + /* #1.63, command: write_value, address: + * IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_B1_03, + * value: 0x00, 0x08, + * size: 4 + */ + 0x40, 0x0E, 0x82, 0x60, 0x00, 0x00, 0x00, 0x08, + /* #1.64, command: write_value, address: + * IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_B1_04, + * value: 0x00, 0x08, + * size: 4 + */ + 0x40, 0x0E, 0x82, 0x64, 0x00, 0x00, 0x00, 0x08, + /* #1.65, command: write_value, address: + * IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_B1_05, + * value: 0x00, 0x08, + * size: 4 + */ + 0x40, 0x0E, 0x82, 0x68, 0x00, 0x00, 0x00, 0x08, + /* #1.66, command: write_value, address: + * IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_B1_06, + * value: 0x00, 0x08, + * size: 4 + */ + 0x40, 0x0E, 0x82, 0x6C, 0x00, 0x00, 0x00, 0x08, + /* #1.67, command: write_value, address: + * IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_B1_07, + * value: 0x00, 0x08, + * size: 4 + */ + 0x40, 0x0E, 0x82, 0x70, 0x00, 0x00, 0x00, 0x08, + /* #1.68, command: write_value, address: + * IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_B1_08, + * value: 0x00, 0x08, + * size: 4 + */ + 0x40, 0x0E, 0x82, 0x74, 0x00, 0x00, 0x00, 0x08, + /* #1.69, command: write_value, address: + * IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_B1_09, + * value: 0x00, 0x08, + * size: 4 + */ + 0x40, 0x0E, 0x82, 0x78, 0x00, 0x00, 0x00, 0x08, + /* #1.70, command: write_value, address: + * IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_B1_10, + * value: 0x00, 0x08, + * size: 4 + */ + 0x40, 0x0E, 0x82, 0x7C, 0x00, 0x00, 0x00, 0x08, + /* #1.71, command: write_value, address: + * IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_B1_11, + * value: 0x00, 0x08, + * size: 4 + */ + 0x40, 0x0E, 0x82, 0x80, 0x00, 0x00, 0x00, 0x08, + /* #1.72, command: write_value, address: + * IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_B1_12, + * value: 0x00, 0x08, + * size: 4 + */ + 0x40, 0x0E, 0x82, 0x84, 0x00, 0x00, 0x00, 0x08, + /* #1.73, command: write_value, address: + * IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_B1_13, + * value: 0x00, 0x08, + * size: 4 + */ + 0x40, 0x0E, 0x82, 0x88, 0x00, 0x00, 0x00, 0x08, + /* #1.74, command: write_value, address: + * IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_B1_14, + * value: 0x00, 0x08, + * size: 4 + */ + 0x40, 0x0E, 0x82, 0x8C, 0x00, 0x00, 0x00, 0x08, + /* #1.75, command: write_value, address: + * IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_B1_15, + * value: 0x00, 0x08, + * size: 4 + */ + 0x40, 0x0E, 0x82, 0x90, 0x00, 0x00, 0x00, 0x08, + /* #1.76, command: write_value, address: + * IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_B1_16, + * value: 0x00, 0x08, + * size: 4 + */ + 0x40, 0x0E, 0x82, 0x94, 0x00, 0x00, 0x00, 0x08, + /* #1.77, command: write_value, address: + * IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_B1_17, + * value: 0x00, 0x08, + * size: 4 + */ + 0x40, 0x0E, 0x82, 0x98, 0x00, 0x00, 0x00, 0x08, + /* #1.78, command: write_value, address: + * IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_B1_18, + * value: 0x00, 0x08, + * size: 4 + */ + 0x40, 0x0E, 0x82, 0x9C, 0x00, 0x00, 0x00, 0x08, + /* #1.79, command: write_value, address: + * IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_B1_19, + * value: 0x00, 0x08, + * size: 4 + */ + 0x40, 0x0E, 0x82, 0xA0, 0x00, 0x00, 0x00, 0x08, + /* #1.80, command: write_value, address: + * IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_B1_20, + * value: 0x00, 0x08, + * size: 4 + */ + 0x40, 0x0E, 0x82, 0xA4, 0x00, 0x00, 0x00, 0x08, + /* #1.81, command: write_value, address: + * IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_B1_21, + * value: 0x00, 0x08, + * size: 4 + */ + 0x40, 0x0E, 0x82, 0xA8, 0x00, 0x00, 0x00, 0x08, + /* #1.82, command: write_value, address: + * IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_B1_22, + * value: 0x00, 0x08, + * size: 4 + */ + 0x40, 0x0E, 0x82, 0xAC, 0x00, 0x00, 0x00, 0x08, + /* #1.83, command: write_value, address: + * IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_B1_23, + * value: 0x00, 0x08, + * size: 4 + */ + 0x40, 0x0E, 0x82, 0xB0, 0x00, 0x00, 0x00, 0x08, + /* #1.84, command: write_value, address: + * IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_B1_24, + * value: 0x00, 0x08, + * size: 4 + */ + 0x40, 0x0E, 0x82, 0xB4, 0x00, 0x00, 0x00, 0x08, + /* #1.85, command: write_value, address: + * IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_B1_25, + * value: 0x00, 0x08, + * size: 4 + */ + 0x40, 0x0E, 0x82, 0xB8, 0x00, 0x00, 0x00, 0x08, + /* #1.86, command: write_value, address: + * IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_B1_26, + * value: 0x00, 0x08, + * size: 4 + */ + 0x40, 0x0E, 0x82, 0xBC, 0x00, 0x00, 0x00, 0x08, + /* #1.87, command: write_value, address: + * IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_B1_27, + * value: 0x00, 0x08, + * size: 4 + */ + 0x40, 0x0E, 0x82, 0xC0, 0x00, 0x00, 0x00, 0x08, + /* #1.88, command: write_value, address: + * IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_B1_28, + * value: 0x00, 0x08, + * size: 4 + */ + 0x40, 0x0E, 0x82, 0xC4, 0x00, 0x00, 0x00, 0x08, + /* #1.89, command: write_value, address: + * IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_B1_29, + * value: 0x00, 0x08, + * size: 4 + */ + 0x40, 0x0E, 0x82, 0xC8, 0x00, 0x00, 0x00, 0x08, + /* #1.90, command: write_value, address: + * IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_B1_30, + * value: 0x00, 0x08, + * size: 4 + */ + 0x40, 0x0E, 0x82, 0xCC, 0x00, 0x00, 0x00, 0x08, + /* #1.91, command: write_value, address: + * IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_B1_31, + * value: 0x00, 0x08, + * size: 4 + */ + 0x40, 0x0E, 0x82, 0xD0, 0x00, 0x00, 0x00, 0x08, + /* #1.92, command: write_value, address: + * IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_B1_32, + * value: 0x00, 0x08, + * size: 4 + */ + 0x40, 0x0E, 0x82, 0xD4, 0x00, 0x00, 0x00, 0x08, + /* #1.93, command: write_value, address: + * IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_B1_33, + * value: 0x00, 0x08, + * size: 4 + */ + 0x40, 0x0E, 0x82, 0xD8, 0x00, 0x00, 0x00, 0x08, + /* #1.94, command: write_value, address: + * IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_B1_34, + * value: 0x00, 0x08, + * size: 4 + */ + 0x40, 0x0E, 0x82, 0xDC, 0x00, 0x00, 0x00, 0x08, + /* #1.95, command: write_value, address: + * IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_B1_35, + * value: 0x00, 0x08, + * size: 4 + */ + 0x40, 0x0E, 0x82, 0xE0, 0x00, 0x00, 0x00, 0x08, + /* #1.96, command: write_value, address: + * IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_B1_36, + * value: 0x00, 0x08, + * size: 4 + */ + 0x40, 0x0E, 0x82, 0xE4, 0x00, 0x00, 0x00, 0x08, + /* #1.97, command: write_value, address: + * IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_B1_37, + * value: 0x00, 0x08, + * size: 4 + */ + 0x40, 0x0E, 0x82, 0xE8, 0x00, 0x00, 0x00, 0x08, + /* #1.98, command: write_value, address: + * IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_B1_38, + * value: 0x00, 0x08, + * size: 4 + */ + 0x40, 0x0E, 0x82, 0xEC, 0x00, 0x00, 0x00, 0x08, + /* #1.99, command: write_value, address: + * IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_B1_39, + * value: 0x00, 0x08, + * size: 4 + */ + 0x40, 0x0E, 0x82, 0xF0, 0x00, 0x00, 0x00, 0x08, + /* #1.100, command: write_value, address: + * IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_B2_00, + * value: 0x00, 0x08, + * size: 4 + */ + 0x40, 0x0E, 0x82, 0xFC, 0x00, 0x00, 0x00, 0x08, + /* #1.101, command: write_value, address: + * IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_B2_01, + * value: 0x00, 0x08, + * size: 4 + */ + 0x40, 0x0E, 0x83, 0x00, 0x00, 0x00, 0x00, 0x08, + /* #1.102, command: write_value, address: + * IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_B2_02, + * value: 0x00, 0x08, + * size: 4 + */ + 0x40, 0x0E, 0x83, 0x04, 0x00, 0x00, 0x00, 0x08, + /* #1.103, command: write_value, address: + * IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_B2_03, + * value: 0x00, 0x08, + * size: 4 + */ + 0x40, 0x0E, 0x83, 0x08, 0x00, 0x00, 0x00, 0x08, + /* #1.104, command: write_value, address: + * IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_B2_04, + * value: 0x00, 0x08, + * size: 4 + */ + 0x40, 0x0E, 0x83, 0x0C, 0x00, 0x00, 0x00, 0x08, + /* #1.105, command: write_value, address: + * IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_B2_05, + * value: 0x00, 0x08, + * size: 4 + */ + 0x40, 0x0E, 0x83, 0x10, 0x00, 0x00, 0x00, 0x08, + /* #1.106, command: write_value, address: + * IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_B2_06, + * value: 0x00, 0x08, + * size: 4 + */ + 0x40, 0x0E, 0x83, 0x14, 0x00, 0x00, 0x00, 0x08, + /* #1.107, command: write_value, address: + * IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_B2_07, + * value: 0x00, 0x08, + * size: 4 + */ + 0x40, 0x0E, 0x83, 0x18, 0x00, 0x00, 0x00, 0x08, + /* #1.108, command: write_value, address: + * IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_B2_08, + * value: 0x00, 0x08, + * size: 4 + */ + 0x40, 0x0E, 0x83, 0x1C, 0x00, 0x00, 0x00, 0x08, + /* #1.109, command: write_value, address: + * IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_B2_09, + * value: 0x00, 0x08, + * size: 4 + */ + 0x40, 0x0E, 0x83, 0x20, 0x00, 0x00, 0x00, 0x08, + /* #1.110, command: write_value, address: + * IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_B2_10, + * value: 0x00, 0x08, + * size: 4 + */ + 0x40, 0x0E, 0x83, 0x24, 0x00, 0x00, 0x00, 0x08, + /* #1.111, command: write_value, address: + * IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_B2_11, + * value: 0x00, 0x08, + * size: 4 + */ + 0x40, 0x0E, 0x83, 0x28, 0x00, 0x00, 0x00, 0x08, + /* #1.112, command: write_value, address: + * IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_B2_12, + * value: 0x00, 0x08, + * size: 4 + */ + 0x40, 0x0E, 0x83, 0x2C, 0x00, 0x00, 0x00, 0x08, + /* #1.113, command: write_value, address: + * IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_B2_13, + * value: 0x00, 0x08, + * size: 4 + */ + 0x40, 0x0E, 0x83, 0x30, 0x00, 0x00, 0x00, 0x08, + /* #1.114, command: write_value, address: + * IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_B2_14, + * value: 0x00, 0x08, + * size: 4 + */ + 0x40, 0x0E, 0x83, 0x34, 0x00, 0x00, 0x00, 0x08, + /* #1.115, command: write_value, address: + * IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_B2_15, + * value: 0x00, 0x08, + * size: 4 + */ + 0x40, 0x0E, 0x83, 0x38, 0x00, 0x00, 0x00, 0x08, + /* #1.116, command: write_value, address: + * IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_B2_16, + * value: 0x00, 0x08, + * size: 4 + */ + 0x40, 0x0E, 0x83, 0x3C, 0x00, 0x00, 0x00, 0x08, + /* #1.117, command: write_value, address: + * IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_B2_17, + * value: 0x00, 0x08, + * size: 4 + */ + 0x40, 0x0E, 0x83, 0x40, 0x00, 0x00, 0x00, 0x08, + /* #1.118, command: write_value, address: + * SEMC_MCR, + * value: 0x00, 0x10000004, size: 4 + */ + 0x40, 0x0D, 0x40, 0x00, 0x10, 0x00, 0x00, 0x04, + /* #1.119, command: write_value, address: + * SEMC_BMCR0, + * value: 0x00, 0x81, size: 4 + */ + 0x40, 0x0D, 0x40, 0x08, 0x00, 0x00, 0x00, 0x81, + /* #1.120, command: write_value, address: + * SEMC_BMCR1, + * value: 0x00, 0x81, size: 4 + */ + 0x40, 0x0D, 0x40, 0x0C, 0x00, 0x00, 0x00, 0x81, + /* #1.121, command: write_value, address: + * SEMC_BR0, + * value: 0x00, 0x8000001D, size: 4 + */ + 0x40, 0x0D, 0x40, 0x10, 0x80, 0x00, 0x00, 0x1D, + /* #1.122, command: write_value, address: + * SEMC_SDRAMCR0, + * value: 0x00, 0xF32, size: 4 + */ + 0x40, 0x0D, 0x40, 0x40, 0x00, 0x00, 0x0F, 0x32, + /* #1.123, command: write_value, address: + * SEMC_SDRAMCR1, + * value: 0x00, 0x772A22, size: 4 + */ + 0x40, 0x0D, 0x40, 0x44, 0x00, 0x77, 0x2A, 0x22, + /* #1.124, command: write_value, address: + * SEMC_SDRAMCR2, + * value: 0x00, 0x10A0D, size: 4 + */ + 0x40, 0x0D, 0x40, 0x48, 0x00, 0x01, 0x0A, 0x0D, + /* #1.125, command: write_value, address: + * SEMC_SDRAMCR3, + * value: 0x00, 0x21210408, size: 4 + */ + 0x40, 0x0D, 0x40, 0x4C, 0x21, 0x21, 0x04, 0x08, + /* #1.126, command: write_value, address: + * SEMC_IPCR0, + * value: 0x00, 0x80000000, size: 4 + */ + 0x40, 0x0D, 0x40, 0x90, 0x80, 0x00, 0x00, 0x00, + /* #1.127, command: write_value, address: + * SEMC_IPCR1, + * value: 0x00, 0x02, size: 4 + */ + 0x40, 0x0D, 0x40, 0x94, 0x00, 0x00, 0x00, 0x02, + /* #1.128, command: write_value, address: + * SEMC_IPCR2, + * value: 0x00, 0x00, size: 4 + */ + 0x40, 0x0D, 0x40, 0x98, 0x00, 0x00, 0x00, 0x00, + /* #1.129, command: write_value, address: + * SEMC_IPCMD, + * value: 0x00, 0xA55A000F, size: 4 + */ + 0x40, 0x0D, 0x40, 0x9C, 0xA5, 0x5A, 0x00, 0x0F, + /* #2, command: nop */ + 0xC0, 0x00, 0x04, 0x00, + /* #3, command: nop */ + 0xC0, 0x00, 0x04, 0x00, + /* #4, command: nop */ + 0xC0, 0x00, 0x04, 0x00, + /* #5, command: nop */ + 0xC0, 0x00, 0x04, 0x00, + /* #6, command: nop */ + 0xC0, 0x00, 0x04, 0x00, + /* #7.1-2, command header bytes for merged 'Write - value' command */ + 0xCC, 0x00, 0x14, 0x04, + /* #7.1, command: write_value, address: + * SEMC_INTR, + * value: 0x00, 0x03, size: 4 + */ + 0x40, 0x0D, 0x40, 0x3C, 0x00, 0x00, 0x00, 0x03, + /* #7.2, command: write_value, address: + * SEMC_IPCMD, + * value: 0x00, 0xA55A000C, size: 4 + */ + 0x40, 0x0D, 0x40, 0x9C, 0xA5, 0x5A, 0x00, 0x0C, + /* #8, command: nop */ + 0xC0, 0x00, 0x04, 0x00, + /* #9, command: nop */ + 0xC0, 0x00, 0x04, 0x00, + /* #10, command: nop */ + 0xC0, 0x00, 0x04, 0x00, + /* #11, command: nop */ + 0xC0, 0x00, 0x04, 0x00, + /* #12, command: nop */ + 0xC0, 0x00, 0x04, 0x00, + /* #13.1-2, command header bytes for merged 'Write - value' command */ + 0xCC, 0x00, 0x14, 0x04, + /* #13.1, command: write_value, address: + * SEMC_INTR, + * value: 0x00, 0x03, size: 4 + */ + 0x40, 0x0D, 0x40, 0x3C, 0x00, 0x00, 0x00, 0x03, + /* #13.2, command: write_value, address: + * SEMC_IPCMD, + * value: 0x00, 0xA55A000C, size: 4 + */ + 0x40, 0x0D, 0x40, 0x9C, 0xA5, 0x5A, 0x00, 0x0C, + /* #14, command: nop */ + 0xC0, 0x00, 0x04, 0x00, + /* #15, command: nop */ + 0xC0, 0x00, 0x04, 0x00, + /* #16, command: nop */ + 0xC0, 0x00, 0x04, 0x00, + /* #17, command: nop */ + 0xC0, 0x00, 0x04, 0x00, + /* #18, command: nop */ + 0xC0, 0x00, 0x04, 0x00, + /* #19.1-3, command header bytes for merged 'Write - value' command */ + 0xCC, 0x00, 0x1C, 0x04, + /* #19.1, command: write_value, address: + * SEMC_INTR, + * value: 0x00, 0x03, size: 4 + */ + 0x40, 0x0D, 0x40, 0x3C, 0x00, 0x00, 0x00, 0x03, + /* #19.2, command: write_value, address: + * SEMC_IPTXDAT, + * value: 0x00, 0x33, size: 4 + */ + 0x40, 0x0D, 0x40, 0xA0, 0x00, 0x00, 0x00, 0x33, + /* #19.3, command: write_value, address: + * SEMC_IPCMD, + * value: 0x00, 0xA55A000A, size: 4 + */ + 0x40, 0x0D, 0x40, 0x9C, 0xA5, 0x5A, 0x00, 0x0A, + /* #20, command: nop */ + 0xC0, 0x00, 0x04, 0x00, + /* #21, command: nop */ + 0xC0, 0x00, 0x04, 0x00, + /* #22, command: nop */ + 0xC0, 0x00, 0x04, 0x00, + /* #23, command: nop */ + 0xC0, 0x00, 0x04, 0x00, + /* #24, command: nop */ + 0xC0, 0x00, 0x04, 0x00, + /* #25.1-2, command header bytes for merged 'Write - value' command */ + 0xCC, 0x00, 0x14, 0x04, + /* #25.1, command: write_value, address: + * SEMC_INTR, + * value: 0x00, 0x03, size: 4 + */ + 0x40, 0x0D, 0x40, 0x3C, 0x00, 0x00, 0x00, 0x03, + /* #25.2, command: write_value, address: + * SEMC_SDRAMCR3, + * value: 0x00, 0x21210409, size: 4 + */ + 0x40, 0x0D, 0x40, 0x4C, 0x21, 0x21, 0x04, 0x09}; +/* BE CAREFUL MODIFYING THIS SETTINGS - IT IS YAML SETTINGS FOR TOOLS */ + +#else +const uint8_t dcd_data[] = {0x00}; +#endif /* defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_DEVICE_CONFIGURATION_DATA) */ +#endif /* defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_BOOT_FLEXSPI_NOR) */ diff --git a/boards/phytec/phyboard_atlas/dcd/dcd.h b/boards/phytec/phyboard_atlas/dcd/dcd.h new file mode 100644 index 000000000000..21ba0522bc0d --- /dev/null +++ b/boards/phytec/phyboard_atlas/dcd/dcd.h @@ -0,0 +1,18 @@ +/* + * Copyright 2020 NXP + * All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef DCD_ +#define DCD_ + +#include + +#define DCD_TAG_HEADER (0xD2) +#define DCD_VERSION (0x41) +#define DCD_TAG_HEADER_SHIFT (24) +#define DCD_ARRAY_SIZE 1 + +#endif /* DCD_ */ diff --git a/boards/phytec/phyboard_atlas/doc/img/phyboard_atlas.webp b/boards/phytec/phyboard_atlas/doc/img/phyboard_atlas.webp new file mode 100644 index 0000000000000000000000000000000000000000..54954bca017ef08431d2cb3b84e6c78d1cc92221 GIT binary patch literal 56534 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 + +&pinctrl { + pinmux_csi: pinmux_csi { + group0 { + pinmux = <&iomuxc_gpio_disp_b2_14_gpio11_io15>; + drive-strength = "high"; + bias-pull-down; + slew-rate = "fast"; + }; + + group1 { + pinmux = <&iomuxc_gpio_ad_26_gpio9_io25>; + drive-strength = "high"; + bias-pull-up; + slew-rate = "fast"; + }; + }; + + pinmux_enet: pinmux_enet { + group0 { + pinmux = <&iomuxc_gpio_disp_b2_08_enet_rx_en>, + <&iomuxc_gpio_disp_b2_09_enet_rx_er>; + drive-strength = "high"; + bias-pull-down; + slew-rate = "fast"; + }; + + group1 { + pinmux = <&iomuxc_gpio_disp_b2_06_enet_rdata00>, + <&iomuxc_gpio_disp_b2_07_enet_rdata01>; + drive-strength = "high"; + bias-pull-down; + slew-rate = "fast"; + input-enable; + }; + + group2 { + pinmux = <&iomuxc_gpio_disp_b2_02_enet_tdata00>, + <&iomuxc_gpio_disp_b2_03_enet_tdata01>, + <&iomuxc_gpio_disp_b2_04_enet_tx_en>; + drive-strength = "high"; + slew-rate = "fast"; + }; + + group3 { + pinmux = <&iomuxc_gpio_disp_b2_05_enet_ref_clk>; + drive-strength = "high"; + slew-rate = "slow"; + input-enable; + }; + }; + + pinmux_enet_mdio: pinmux_enet_mdio { + group0 { + pinmux = <&iomuxc_gpio_ad_32_enet_mdc>, + <&iomuxc_gpio_ad_33_enet_mdio>; + drive-strength = "high"; + slew-rate = "fast"; + }; + }; + + pinmux_lcdif: pinmux_lcdif { + group0 { + pinmux = <&iomuxc_gpio_ad_30_gpio9_io29>, + <&iomuxc_gpio_ad_31_gpio9_io30>; + drive-strength = "high"; + bias-pull-down; + slew-rate = "fast"; + }; + + group1 { + pinmux = <&iomuxc_gpio_disp_b2_15_gpio11_io16>; + drive-strength = "high"; + bias-pull-up; + slew-rate = "fast"; + }; + }; + + pinmux_lpi2c1: pinmux_lpi2c1 { + group0 { + pinmux = <&iomuxc_gpio_ad_08_lpi2c1_scl>, + <&iomuxc_gpio_ad_09_lpi2c1_sda>; + drive-strength = "normal"; + drive-open-drain; + slew-rate = "fast"; + input-enable; + }; + }; + + pinmux_lpi2c2: pinmux_lpi2c2 { + group0 { + pinmux = <&iomuxc_gpio_ad_18_lpi2c2_scl>, + <&iomuxc_gpio_ad_19_lpi2c2_sda>; + drive-strength = "high"; + slew-rate = "fast"; + input-enable; + }; + }; + + pinmux_lpi2c5: pinmux_lpi2c5 { + group0 { + pinmux = <&iomuxc_lpsr_gpio_lpsr_08_lpi2c5_sda>, + <&iomuxc_lpsr_gpio_lpsr_09_lpi2c5_scl>; + drive-strength = "normal"; + drive-open-drain; + slew-rate = "fast"; + input-enable; + }; + }; + + pinmux_lpspi1: pinmux_lpspi1 { + group0 { + pinmux = <&iomuxc_gpio_ad_29_lpspi1_pcs0>, + <&iomuxc_gpio_ad_28_lpspi1_sck>, + <&iomuxc_gpio_ad_31_lpspi1_sdi>, + <&iomuxc_gpio_ad_30_lpspi1_sdo>; + drive-strength = "high"; + slew-rate = "fast"; + }; + }; + + pinmux_lpspi5: pinmux_lpspi5 { + group0 { + pinmux = <&iomuxc_lpsr_gpio_lpsr_03_lpspi5_pcs0>, + <&iomuxc_lpsr_gpio_lpsr_06_lpspi5_pcs1>, + <&iomuxc_lpsr_gpio_lpsr_07_lpspi5_pcs2>, + <&iomuxc_lpsr_gpio_lpsr_02_lpspi5_sck>, + <&iomuxc_lpsr_gpio_lpsr_05_lpspi5_sdi>, + <&iomuxc_lpsr_gpio_lpsr_04_lpspi5_sdo>; + drive-strength = "high"; + slew-rate = "fast"; + }; + }; + + pinmux_lpuart1: pinmux_lpuart1 { + group0 { + pinmux = <&iomuxc_gpio_ad_25_lpuart1_rx>, + <&iomuxc_gpio_ad_24_lpuart1_tx>; + drive-strength = "high"; + slew-rate = "fast"; + }; + }; + + pinmux_lpuart1_sleep: pinmux_lpuart1_sleep { + group0 { + pinmux = <&iomuxc_gpio_ad_25_gpio_mux3_io24>; + drive-strength = "high"; + bias-pull-up; + slew-rate = "fast"; + }; + + group1 { + pinmux = <&iomuxc_gpio_ad_24_lpuart1_tx>; + drive-strength = "high"; + slew-rate = "fast"; + }; + }; + + pinmux_lpuart2: pinmux_lpuart2 { + group0 { + pinmux = <&iomuxc_gpio_disp_b2_11_lpuart2_rx>, + <&iomuxc_gpio_disp_b2_10_lpuart2_tx>; + drive-strength = "high"; + slew-rate = "fast"; + }; + }; + + pinmux_lpuart2_sleep: pinmux_lpuart2_sleep { + group0 { + pinmux = <&iomuxc_gpio_disp_b2_11_gpio_mux5_io12>; + drive-strength = "high"; + bias-pull-up; + slew-rate = "fast"; + }; + + group1 { + pinmux = <&iomuxc_gpio_disp_b2_10_lpuart2_tx>; + drive-strength = "high"; + slew-rate = "fast"; + }; + }; + + pinmux_lpuart5: pinmux_lpuart5 { + group0 { + pinmux = <&iomuxc_gpio_ad_29_lpuart5_rx>, + <&iomuxc_gpio_ad_28_lpuart5_tx>; + drive-strength = "high"; + slew-rate = "fast"; + }; + }; + + pinmux_lpuart5_sleep: pinmux_lpuart5_sleep { + group0 { + pinmux = <&iomuxc_gpio_ad_29_gpio_mux3_io28>; + drive-strength = "high"; + bias-pull-up; + slew-rate = "fast"; + }; + + group1 { + pinmux = <&iomuxc_gpio_ad_28_lpuart5_tx>; + drive-strength = "high"; + slew-rate = "fast"; + }; + }; + + pinmux_lpuart6: pinmux_lpuart6 { + group0 { + pinmux = <&iomuxc_gpio_emc_b1_41_lpuart6_rx>, + <&iomuxc_gpio_emc_b1_40_lpuart6_tx>; + drive-strength = "high"; + slew-rate = "fast"; + }; + }; + + pinmux_lpuart6_sleep: pinmux_lpuart6_sleep { + group0 { + pinmux = <&iomuxc_gpio_emc_b1_41_gpio_mux2_io09>; + drive-strength = "high"; + bias-pull-up; + slew-rate = "fast"; + }; + + group1 { + pinmux = <&iomuxc_gpio_emc_b1_40_lpuart6_tx>; + drive-strength = "high"; + slew-rate = "fast"; + }; + }; + + pinmux_lpuart8: pinmux_lpuart8 { + group0 { + pinmux = <&iomuxc_gpio_ad_03_lpuart8_rx>, + <&iomuxc_gpio_ad_02_lpuart8_tx>; + drive-strength = "high"; + slew-rate = "fast"; + }; + }; + + pinmux_lpuart8_sleep: pinmux_lpuart8_sleep { + group0 { + pinmux = <&iomuxc_gpio_ad_03_gpio9_io02>; + drive-strength = "high"; + bias-pull-up; + slew-rate = "fast"; + }; + + group1 { + pinmux = <&iomuxc_gpio_ad_02_lpuart8_tx>; + drive-strength = "high"; + slew-rate = "fast"; + }; + }; + + pinmux_lpuart8_flowcontrol: pinmux_lpuart8_flowcontrol { + group0 { + pinmux = <&iomuxc_gpio_ad_03_lpuart8_rx>, + <&iomuxc_gpio_ad_02_lpuart8_tx>, + <&iomuxc_gpio_ad_04_lpuart8_cts_b>, + <&iomuxc_gpio_ad_05_lpuart8_rts_b>; + drive-strength = "high"; + slew-rate = "fast"; + }; + }; + + pinmux_flexcan3: pinmux_flexcan3 { + group0 { + pinmux = <&iomuxc_lpsr_gpio_lpsr_01_can3_rx>, + <&iomuxc_lpsr_gpio_lpsr_00_can3_tx>; + drive-strength = "high"; + slew-rate = "fast"; + }; + }; + + pinmux_sai1: pinmux_sai1 { + group0 { + pinmux = <&iomuxc_gpio_ad_17_sai1_mclk>, + <&iomuxc_gpio_ad_20_sai1_rx_data00>, + <&iomuxc_gpio_ad_21_sai1_tx_data00>, + <&iomuxc_gpio_ad_22_sai1_tx_bclk>, + <&iomuxc_gpio_ad_23_sai1_tx_sync>; + drive-strength = "high"; + slew-rate = "fast"; + input-enable; + }; + }; + + pinmux_usdhc1: pinmux_usdhc1 { + group0 { + pinmux = <&iomuxc_gpio_sd_b1_00_usdhc1_cmd>, + <&iomuxc_gpio_sd_b1_01_usdhc1_clk>, + <&iomuxc_gpio_sd_b1_02_usdhc1_data0>, + <&iomuxc_gpio_sd_b1_03_usdhc1_data1>, + <&iomuxc_gpio_sd_b1_04_usdhc1_data2>, + <&iomuxc_gpio_sd_b1_05_usdhc1_data3>; + bias-pull-up; + input-enable; + }; + }; + + /* removes pull on dat3 for card detect */ + pinmux_usdhc1_dat3_nopull: pinmux_usdhc1_dat3_nopull { + group0 { + pinmux = <&iomuxc_gpio_sd_b1_05_usdhc1_data3>; + bias-disable; + input-enable; + }; + + group1 { + pinmux = <&iomuxc_gpio_sd_b1_00_usdhc1_cmd>, + <&iomuxc_gpio_sd_b1_01_usdhc1_clk>, + <&iomuxc_gpio_sd_b1_02_usdhc1_data0>, + <&iomuxc_gpio_sd_b1_03_usdhc1_data1>, + <&iomuxc_gpio_sd_b1_04_usdhc1_data2>; + bias-pull-up; + input-enable; + }; + }; +}; diff --git a/boards/phytec/phyboard_atlas/phyboard_atlas.dtsi b/boards/phytec/phyboard_atlas/phyboard_atlas.dtsi new file mode 100644 index 000000000000..cb9d9ce78281 --- /dev/null +++ b/boards/phytec/phyboard_atlas/phyboard_atlas.dtsi @@ -0,0 +1,211 @@ +/* + * Copyright (c) 2025 PHYTEC America LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "phyboard_atlas-pinctrl.dtsi" +#include + +/ { + aliases { + accel0 = &icm40627; + eeprom0 = &eeprom0; + i2s-codec-tx = &sai1; + led0 = &som_green_led; + led1 = &som_red_led; + led3 = &board_red_led; + led4 = &board_green_led; + sdhc0 = &usdhc1; + sdram0 = &sdram0; + sw0 = &user_button; + watchdog0 = &wdog1; + }; + + gpio_keys { + compatible = "gpio-keys"; + + user_button: button-1 { + label = "User Button"; + gpios = <&gpio4 2 GPIO_ACTIVE_HIGH>; + zephyr,code = ; + }; + }; + + leds { + compatible = "gpio-leds"; + + board_red_led: led-3 { + label = "Red LED1 D4"; + gpios = <&gpio9 13 GPIO_ACTIVE_HIGH>; + }; + + board_green_led: led-4 { + label = "Green LED2 D11"; + gpios = <&gpio12 13 GPIO_ACTIVE_HIGH>; + }; + }; + + expansion_header: connector { + compatible = "gpio-nexus"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <11 0 &gpio4 1 0>, /* Pin 11, GPIO_AD_34 */ + <27 0 &gpio3 25 0>, /* Pin 27, EXP_AD_26 */ + <29 0 &gpio3 26 0>, /* Pin 29, EXP_AD_27 */ + <31 0 &gpio5 1 0>, /* Pin 31, GPIO_DISP_B2_00 */ + <33 0 &gpio13 3 0>, /* Pin 33, GPIO_SNVS_00 */ + <35 0 &gpio13 4 0>, /* Pin 35, GPIO_SNVS_01 */ + <36 0 &gpio13 5 0>, /* Pin 36, GPIO_SNVS_02 */ + <37 0 &gpio13 6 0>, /* Pin 37, GPIO_SNVS_03 */ + <38 0 &gpio13 7 1>, /* Pin 38, GPIO_SNVS_04 */ + <40 0 &gpio13 8 1>; /* Pin 40, GPIO_SNVS_05 */ + }; + + transceiver0: can-phy0 { + compatible = "can-transceiver-gpio"; + standby-gpios = <&gpio6 10 GPIO_ACTIVE_HIGH>; + #phy-cells = <0>; + max-bitrate = <5000000>; + }; +}; + +&enet_mac { + status = "okay"; + pinctrl-0 = <&pinmux_enet>; + pinctrl-names = "default"; + phy-handle = <&phy>; + phy-connection-type = "rmii"; + zephyr,random-mac-address; +}; + +&enet_mdio { + status = "okay"; + pinctrl-0 = <&pinmux_enet_mdio>; + pinctrl-names = "default"; + + phy: phy@1 { + compatible = "microchip,ksz8081"; + reg = <1>; + status = "okay"; + microchip,interface-type = "rmii"; + }; +}; + +&enet_ptp_clock { + status = "okay"; +}; + +&csi { + pinctrl-0 = <&pinmux_csi>; + pinctrl-names = "default"; +}; + +&flexcan3 { + pinctrl-0 = <&pinmux_flexcan3>; + pinctrl-names = "default"; +}; + +&lcdif { + pinctrl-0 = <&pinmux_lcdif>; + pinctrl-names = "default"; +}; + +&lpi2c1 { + pinctrl-0 = <&pinmux_lpi2c1>; + pinctrl-names = "default"; +}; + +&lpi2c2 { + pinctrl-0 = <&pinmux_lpi2c2>; + pinctrl-names = "default"; +}; + +&lpi2c5 { + pinctrl-0 = <&pinmux_lpi2c5>; + pinctrl-names = "default"; + status = "okay"; + + audio_codec: tlv320aic3110@18 { + compatible = "ti,tlv320aic3110"; + reg = <0x18>; + status = "okay"; + clocks = <&ccm IMX_CCM_SAI1_CLK 0x2004 4>; + clock-names = "mclk"; + }; + + icm40627: icm40627@6b { + compatible = "invensense,icm40627"; + reg = <0x6b>; + status = "okay"; + accel-hz = <1000>; + accel-fs = <16>; + gyro-hz = <1000>; + gyro-fs = <2000>; + int-gpios = <&gpio3 25 GPIO_ACTIVE_HIGH>, + <&gpio3 26 GPIO_ACTIVE_HIGH>; + }; +}; + +&lpspi1 { + pinctrl-0 = <&pinmux_lpspi1>; + pinctrl-names = "default"; +}; + +&lpspi5 { + pinctrl-0 = <&pinmux_lpspi5>; + pinctrl-names = "default"; +}; + +&lpuart1 { + pinctrl-0 = <&pinmux_lpuart1>; + pinctrl-1 = <&pinmux_lpuart1_sleep>; + pinctrl-names = "default", "sleep"; +}; + +&lpuart2 { + pinctrl-0 = <&pinmux_lpuart2>; + pinctrl-1 = <&pinmux_lpuart2_sleep>; + pinctrl-names = "default", "sleep"; + current-speed = <115200>; + status = "okay"; +}; + +&lpuart5 { + pinctrl-0 = <&pinmux_lpuart5>; + pinctrl-1 = <&pinmux_lpuart5_sleep>; + pinctrl-names = "default", "sleep"; +}; + +&lpuart6 { + pinctrl-0 = <&pinmux_lpuart6>; + pinctrl-1 = <&pinmux_lpuart6_sleep>; + pinctrl-names = "default", "sleep"; +}; + +&lpuart8 { + pinctrl-0 = <&pinmux_lpuart8_flowcontrol>; + pinctrl-1 = <&pinmux_lpuart8_sleep>; + pinctrl-names = "default", "sleep"; + hw-flow-control; +}; + +&pxp { + status = "okay"; +}; + +&sai1 { + pinctrl-0 = <&pinmux_sai1>; + pinctrl-names = "default"; + clock-mux = <1>; + pre-div = <0>; + podf = <2>; + nxp,tx-dma-channel = <8>; + nxp,rx-dma-channel = <9>; +}; + +&usdhc1 { + pinctrl-0 = <&pinmux_usdhc1>; + pinctrl-1 = <&pinmux_usdhc1_dat3_nopull>; + pinctrl-names = "default", "nopull"; +}; diff --git a/boards/phytec/phyboard_atlas/phyboard_atlas_mimxrt1176_cm7.dts b/boards/phytec/phyboard_atlas/phyboard_atlas_mimxrt1176_cm7.dts new file mode 100644 index 000000000000..e2bef87442e7 --- /dev/null +++ b/boards/phytec/phyboard_atlas/phyboard_atlas_mimxrt1176_cm7.dts @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2025 PHYTEC America LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include "phyboard_atlas.dtsi" + +/ { + model = "PHYTEC phyBOARD-Atlas i.MX RT1170 CM7"; + compatible = "phytec,phyboard_atlas"; + + aliases { + mipi-dsi = &mipi_dsi; + }; + + chosen { + zephyr,console = &lpuart1; + zephyr,shell-uart = &lpuart1; + zephyr,canbus = &flexcan3; + }; + + nxp_mipi_connector: mipi-connector { + compatible = "gpio-nexus"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <0 0 &gpio9 29 0>, /* Pin 1, LEDK */ + <21 0 &gpio9 30 0>, /* Pin 21, RESET */ + <28 0 &gpio9 0 0>, /* Pin 28, CTP_RST */ + <29 0 &gpio2 31 0>, /* Pin 29, CTP_INT */ + <32 0 &gpio11 16 0>, /* Pin 32, PWR_EN */ + <34 0 &gpio9 29 0>; /* Pin 34, BL_PWM */ + }; + + 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 */ + }; +}; + +&user_button { + status = "okay"; +}; + +&board_green_led { + status = "okay"; +}; + +&board_red_led { + status = "okay"; +}; + +&flexcan3 { + status = "okay"; + phys = <&transceiver0>; +}; + +&lpspi1 { + dmas = <&edma0 0 36>, <&edma0 1 37>; + dma-names = "rx", "tx"; + status = "disabled"; /* LPSPI1 conflicts with LPUART5 */ +}; + +&lpspi5 { + status = "okay"; +}; + +&edma0 { + status = "okay"; +}; + +&lpuart1 { + status = "okay"; + current-speed = <115200>; +}; + +&lpuart5 { + status = "okay"; + current-speed = <115200>; +}; + +&lpuart8 { + status = "okay"; + current-speed = <115200>; +}; + +nxp_mipi_i2c: &lpi2c5 { + pinctrl-0 = <&pinmux_lpi2c5>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; +}; + +&sai1 { + status = "okay"; +}; + +zephyr_udc0: &usb1 { + status = "okay"; + phy-handle = <&usbphy1>; +}; + +&usbphy1 { + status = "okay"; + tx-d-cal = <7>; + tx-cal-45-dp-ohms = <6>; + tx-cal-45-dm-ohms = <6>; +}; + +&usb2 { + status = "disabled"; + phy-handle = <&usbphy2>; +}; + +&usbphy2 { + status = "okay"; + tx-d-cal = <7>; + tx-cal-45-dp-ohms = <6>; + tx-cal-45-dm-ohms = <6>; +}; + +&usdhc1 { + status = "okay"; + detect-dat3; + no-1-8-v; + + sdmmc { + compatible = "zephyr,sdmmc-disk"; + disk-name = "SD"; + status = "okay"; + }; +}; + +zephyr_lcdif: &lcdif {}; + +zephyr_mipi_dsi: &mipi_dsi { + dphy-ref-frequency = <24000000>; + phy-clock = <792000000>; +}; + +nxp_cam_i2c: &lpi2c2 {}; + +nxp_mipi_csi: &mipi_csi2rx {}; + +nxp_csi: &csi {}; diff --git a/boards/phytec/phyboard_atlas/phyboard_atlas_mimxrt1176_cm7.yaml b/boards/phytec/phyboard_atlas/phyboard_atlas_mimxrt1176_cm7.yaml new file mode 100644 index 000000000000..e42d9304dcdc --- /dev/null +++ b/boards/phytec/phyboard_atlas/phyboard_atlas_mimxrt1176_cm7.yaml @@ -0,0 +1,29 @@ +# Copyright (c) 2025 PHYTEC America LLC +# SPDX-License-Identifier: Apache-2.0 + +identifier: phyboard_atlas/mimxrt1176/cm7 +name: PHYTEC phyBOARD-Atlas i.MX RT1170 CM7 +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb + - xtools +ram: 256 +flash: 16384 +supported: + - can + - dac + - display + - dma + - flash + - gpio + - i2c + - i2s + - mipi_dsi + - netif:eth + - spi + - uart + - usb_device + - usbd +vendor: phytec diff --git a/boards/phytec/phyboard_atlas/phyboard_atlas_mimxrt1176_cm7_defconfig b/boards/phytec/phyboard_atlas/phyboard_atlas_mimxrt1176_cm7_defconfig new file mode 100644 index 000000000000..311064af8a38 --- /dev/null +++ b/boards/phytec/phyboard_atlas/phyboard_atlas_mimxrt1176_cm7_defconfig @@ -0,0 +1,9 @@ +# Copyright (c) 2025 PHYTEC America LLC +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_GPIO=y +CONFIG_ARM_MPU=y +CONFIG_HW_STACK_PROTECTION=y diff --git a/boards/phytec/phyboard_atlas/phyboard_atlas_mimxrt1176_cm7_usb2.overlay b/boards/phytec/phyboard_atlas/phyboard_atlas_mimxrt1176_cm7_usb2.overlay new file mode 100644 index 000000000000..4caaf115f2c4 --- /dev/null +++ b/boards/phytec/phyboard_atlas/phyboard_atlas_mimxrt1176_cm7_usb2.overlay @@ -0,0 +1,8 @@ +/* + * Copyright (c) 2025 PHYTEC America LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +/delete-node/ &zephyr_udc0; + +zephyr_udc0: &usb2 {}; diff --git a/boards/phytec/phyboard_atlas/xip/phycore_rt1170_flexspi_nor_config.c b/boards/phytec/phyboard_atlas/xip/phycore_rt1170_flexspi_nor_config.c new file mode 100644 index 000000000000..e817c6f3cc99 --- /dev/null +++ b/boards/phytec/phyboard_atlas/xip/phycore_rt1170_flexspi_nor_config.c @@ -0,0 +1,89 @@ +/* + * Copyright 2018-2020 NXP + * All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "phycore_rt1170_flexspi_nor_config.h" + +#if defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_BOOT_FLEXSPI_NOR) +__attribute__((section(".boot_hdr.conf"), used)) + +#define FLASH_DUMMY_CYCLES 0x09 +#define FLASH_DUMMY_VALUE 0x09 + +const flexspi_nor_config_t qspi_flash_config = { + .mem_config = { + .tag = FLEXSPI_CFG_BLK_TAG, + .version = FLEXSPI_CFG_BLK_VERSION, + .read_sample_clk_src = + FLEXSPI_READ_SAMPLE_CLK_LOOPBACK_FROM_DQS_PAD, + .cs_hold_time = 3u, + .cs_setup_time = 3u, + /* Enable DDR mode, Wordaddassable, Safe configuration, Differential clock */ + .controller_misc_option = 0x10, + .device_type = FLEXSPI_DEVICE_TYPE_SERIAL_NOR, + .sflash_pad_type = SERIAL_FLASH_4_PADS, + .serial_clk_freq = FLEXSPI_SERIAL_CLK_133MHZ, + .sflash_a1_size = 16u * 1024u * 1024u, + /* Enable flash configuration feature */ + .config_cmd_enable = 1u, + .config_mode_type[0] = DEVICE_CONFIG_CMD_TYPE_GENERIC, + /* Set configuration command sequences */ + .config_cmd_seqs[0] = { + .seq_num = 1, + .seq_id = 12, + .reserved = 0, + }, + /* Prepare setting value for Read Register in flash */ + .config_cmd_args[0] = (FLASH_DUMMY_VALUE << 3), + .lookup_table = { + /* Read LUTs */ + [0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, + 0xEB, RADDR_SDR, FLEXSPI_4PAD, 0x18), + [1] = FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, + FLASH_DUMMY_CYCLES, READ_SDR, FLEXSPI_4PAD, + 0x04), + + /* Read Status LUTs */ + [4 * 1 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, + 0x05, READ_SDR, FLEXSPI_1PAD, 0x04), + + /* Write Enable LUTs */ + [4 * 3 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, + 0x06, STOP, FLEXSPI_1PAD, 0x0), + + /* Erase Sector LUTs */ + [4 * 5 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, + 0x20, RADDR_SDR, FLEXSPI_1PAD, 0x18), + + /* Erase Block LUTs */ + [4 * 8 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, + 0xD8, RADDR_SDR, FLEXSPI_1PAD, 0x18), + + /* Pape Program LUTs */ + [4 * 9 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, + 0x02, RADDR_SDR, FLEXSPI_1PAD, 0x18), + [4 * 9 + 1] = FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, + 0x04, STOP, FLEXSPI_1PAD, 0x0), + + /* Erase Chip LUTs */ + [4 * 11 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, + 0x60, STOP, FLEXSPI_1PAD, 0x0), + + /* Set Read Register LUTs */ + [4 * 12 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, + 0xC0, WRITE_SDR, FLEXSPI_1PAD, 0x01), + [4 * 12 + 1] = FLEXSPI_LUT_SEQ(STOP, FLEXSPI_1PAD, + 0x00, 0, 0, 0), + }, + }, + .page_size = 256u, + .sector_size = 4u * 1024u, + .ipcmd_serial_clk_freq = 0x1, + .block_size = 64u * 1024u, + .is_uniform_block_size = false, +}; + +#endif /* defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_BOOT_FLEXSPI_NOR) */ diff --git a/boards/phytec/phyboard_atlas/xip/phycore_rt1170_flexspi_nor_config.h b/boards/phytec/phyboard_atlas/xip/phycore_rt1170_flexspi_nor_config.h new file mode 100644 index 000000000000..c3eca7df6b7e --- /dev/null +++ b/boards/phytec/phyboard_atlas/xip/phycore_rt1170_flexspi_nor_config.h @@ -0,0 +1,375 @@ +/* + * Copyright 2018-2020, 2022 NXP + * All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef PHYCORE_FLEXSPI_NOR_CONFIG_ +#define PHYCORE_FLEXSPI_NOR_CONFIG_ + +#include +#include +#include "fsl_common.h" + +/* FLEXSPI memory config block related definitions */ +#define FLEXSPI_CFG_BLK_TAG (0x42464346UL) /* ascii "FCFB" Big Endian */ +#define FLEXSPI_CFG_BLK_VERSION (0x56010400UL) /* V1.4.0 */ +#define FLEXSPI_CFG_BLK_SIZE (512) + +/* FLEXSPI Feature related definitions */ +#define FLEXSPI_FEATURE_HAS_PARALLEL_MODE 1 + +/* Lookup table related definitions */ +#define CMD_INDEX_READ 0 +#define CMD_INDEX_READSTATUS 1 +#define CMD_INDEX_WRITEENABLE 2 +#define CMD_INDEX_WRITE 4 + +#define CMD_LUT_SEQ_IDX_READ 0 +#define CMD_LUT_SEQ_IDX_READSTATUS 1 +#define CMD_LUT_SEQ_IDX_WRITEENABLE 3 +#define CMD_LUT_SEQ_IDX_WRITE 9 + +#define CMD_SDR 0x01 +#define CMD_DDR 0x21 +#define RADDR_SDR 0x02 +#define RADDR_DDR 0x22 +#define CADDR_SDR 0x03 +#define CADDR_DDR 0x23 +#define MODE1_SDR 0x04 +#define MODE1_DDR 0x24 +#define MODE2_SDR 0x05 +#define MODE2_DDR 0x25 +#define MODE4_SDR 0x06 +#define MODE4_DDR 0x26 +#define MODE8_SDR 0x07 +#define MODE8_DDR 0x27 +#define WRITE_SDR 0x08 +#define WRITE_DDR 0x28 +#define READ_SDR 0x09 +#define READ_DDR 0x29 +#define LEARN_SDR 0x0A +#define LEARN_DDR 0x2A +#define DATSZ_SDR 0x0B +#define DATSZ_DDR 0x2B +#define DUMMY_SDR 0x0C +#define DUMMY_DDR 0x2C +#define DUMMY_RWDS_SDR 0x0D +#define DUMMY_RWDS_DDR 0x2D +#define JMP_ON_CS 0x1F +#define STOP 0 + +#define FLEXSPI_1PAD 0 +#define FLEXSPI_2PAD 1 +#define FLEXSPI_4PAD 2 +#define FLEXSPI_8PAD 3 + +#define FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) \ + (FLEXSPI_LUT_OPERAND0(op0) | FLEXSPI_LUT_NUM_PADS0(pad0) | \ + FLEXSPI_LUT_OPCODE0(cmd0) | FLEXSPI_LUT_OPERAND1(op1) | \ + FLEXSPI_LUT_NUM_PADS1(pad1) | FLEXSPI_LUT_OPCODE1(cmd1)) + +/*! @brief Definitions for FlexSPI Serial Clock Frequency */ +typedef enum flexspi_serial_clock_freq { + FLEXSPI_SERIAL_CLK_30MHZ = 1, + FLEXSPI_SERIAL_CLK_50MHZ = 2, + FLEXSPI_SERIAL_CLK_60MHZ = 3, + FLEXSPI_SERIAL_CLK_80MHZ = 4, + FLEXSPI_SERIAL_CLK_100MHZ = 5, + FLEXSPI_SERIAL_CLK_120MHZ = 6, + FLEXSPI_SERIAL_CLK_133MHZ = 7, + FLEXSPI_SERIAL_CLK_166MHZ = 8, + FLEXSPI_SERIAL_CLK_200MHZ = 9, +} flexspi_serial_clk_freq_t; + +/*! @brief FlexSPI clock configuration type */ +enum { + /* Clock configure for SDR mode */ + FLEXSPI_CLK_SDR, + /* Clock configurat for DDR mode */ + FLEXSPI_CLK_DDR, +}; + +/*! @brief FlexSPI Read Sample Clock Source definition */ +typedef enum flexspi_read_sample_clk_source { + FLEXSPI_READ_SAMPLE_CLK_LOOPBACK_INTERNALLY = 0, + FLEXSPI_READ_SAMPLE_CLK_LOOPBACK_FROM_DQS_PAD = 1, + FLEXSPI_READ_SAMPLE_CLK_LOOPBACK_FROM_SCK_PAD = 2, + FLEXSPI_READ_SAMPLE_CLK_EXTERNAL_INPUT_FROM_DQS_PAD = 3, +} flexspi_read_sample_clk_t; + +/*! @brief Misc feature bit definitions */ +enum { + /* Bit for Differential clock enable */ + FLEXSPI_MISC_OFFSET_DIFF_CLK_ENABLE = 0, + /* Bit for CK2 enable */ + FLEXSPI_MISC_OFFSET_CK2_ENABLE = 1, + /* Bit for Parallel mode enable */ + FLEXSPI_MISC_OFFSET_PARALLEL_ENABLE = 2, + /* Bit for Word Addressable enable */ + FLEXSPI_MISC_OFFSET_WORD_ADDRESSABLE_ENABLE = 3, + /* Bit for Safe Configuration Frequency enable */ + FLEXSPI_MISC_OFFSET_SAFE_CONFIG_FREQ_ENABLE = 4, + /* Bit for Pad setting override enable */ + FLEXSPI_MISC_OFFSET_PAD_SETTING_OVERRIDE_ENABLE = 5, + /* Bit for DDR clock confiuration indication. */ + FLEXSPI_MISC_OFFSET_DDR_MODE_ENABLE = 6, +}; + +/*! @brief Flash Type Definition */ +enum { + /* Flash devices are Serial NOR */ + FLEXSPI_DEVICE_TYPE_SERIAL_NOR = 1, + /* Flash devices are Serial NAND */ + FLEXSPI_DEVICE_TYPE_SERIAL_NAND = 2, + /* Flash devices are Serial RAM/HyperFLASH */ + FLEXSPI_DEVICE_TYPE_SERIAL_RAM = 3, + /* Flash device is MCP device, A1 is Serial NOR, A2 is Serial NAND */ + FLEXSPI_DEVICE_TYPE_MCP_NOR_NAND = 0x12, + /* Flash device is MCP device, A1 is Serial NOR, A2 is Serial RAMs */ + FLEXSPI_DEVICE_TYPE_MCP_NOR_RAM = 0x13, +}; + +/*! @brief Flash Pad Definitions */ +enum { + SERIAL_FLASH_1_PADS = 1, + SERIAL_FLASH_2_PADS = 2, + SERIAL_FLASH_4_PADS = 4, + SERIAL_FLASH_8_PADS = 8, +}; + +/*! @brief FlexSPI LUT Sequence structure */ +typedef struct _lut_sequence { + uint8_t seq_num; /* Sequence Number, valid number: 1-16 */ + uint8_t seq_id; /* Sequence Index, valid number: 0-15 */ + uint16_t reserved; +} flexspi_lut_seq_t; + +/*! @brief Flash Configuration Command Type */ +enum { + /* Generic command, for example: configure dummy cycles, + * drive strength, etc + */ + DEVICE_CONFIG_CMD_TYPE_GENERIC, + /* Quad Enable command */ + DEVICE_CONFIG_CMD_TYPE_QUAD_ENABLE, + /* Switch from SPI to DPI/QPI/OPI mode */ + DEVICE_CONFIG_CMD_TYPE_SPI2XPI, + /* Switch from DPI/QPI/OPI to SPI mode */ + DEVICE_CONFIG_CMD_TYPE_XPI2SPI, + /* Switch to 0-4-4/0-8-8 mode */ + DEVICE_CONFIG_CMD_TYPE_SPI2NOCMD, + /* Reset device command */ + DEVICE_CONFIG_CMD_TYPE_RESET, +}; + +/*! @brief FlexSPI Memory Configuration Block */ +typedef struct flexspi_config { + /* [0x000-0x003] Tag, fixed value 0x42464346UL */ + uint32_t tag; + /* [0x004-0x007] Version, [31:24] -'V', + * [23:16] - Major, + * [15:8] - Minor, + * [7:0] - bugfix + */ + uint32_t version; + /* [0x008-0x00b] Reserved for future use */ + uint32_t reserved0; + /* [0x00c-0x00c] Read Sample Clock Source, valid value: 0/1/3 */ + uint8_t read_sample_clk_src; + /* [0x00d-0x00d] CS hold time, default value: 3 */ + uint8_t cs_hold_time; + /* [0x00e-0x00e] CS setup time, default value: 3 */ + uint8_t cs_setup_time; + /* [0x00f-0x00f] Column Address with, for HyperBus protocol, + * it is fixed to 3, For Serial NAND, need to refer to datasheet + */ + uint8_t column_address_width; + /* [0x010-0x010] Device Mode Configure enable flag, + * 1 - Enable, 0 - Disable + */ + uint8_t device_mode_cfg_enable; + /* [0x011-0x011] Specify the configuration command type:Quad Enable, + * DPI/QPI/OPI switch, Generic configuration, etc. + */ + uint8_t device_mode_type; + /* [0x012-0x013] Wait time for all configuration commands, + * unit: 100us, Used for DPI/QPI/OPI switch or reset command + */ + uint16_t wait_time_cfg_commands; + /* [0x014-0x017] Device mode sequence info, + * [7:0] - LUT sequence id, + * [15:8] - LUt sequence number, + * [31:16] Reserved + */ + flexspi_lut_seq_t device_mode_seq; + /* [0x018-0x01b] Argument/Parameter for device configuration */ + uint32_t device_mode_arg; + /* [0x01c-0x01c] Configure command Enable Flag, + * 1 - Enable, 0 - Disable + */ + uint8_t config_cmd_enable; + /* [0x01d-0x01f] Configure Mode Type, similar as deviceModeTpe */ + uint8_t config_mode_type[3]; + /* [0x020-0x02b] Sequence info for Device Configuration command, + * similar as deviceModeSeq + */ + flexspi_lut_seq_t config_cmd_seqs[3]; + /* [0x02c-0x02f] Reserved for future use */ + uint32_t reserved1; + /* [0x030-0x03b] Arguments/Parameters for + * device Configuration commands + */ + uint32_t config_cmd_args[3]; + /* [0x03c-0x03f] Reserved for future use */ + uint32_t reserved2; + /* [0x040-0x043] Controller Misc Options, see Misc feature bit + * definitions for more details + */ + uint32_t controller_misc_option; + /* [0x044-0x044] Device Type: + * See Flash Type Definition for more details + */ + uint8_t device_type; + /* [0x045-0x045] Serial Flash Pad Type: + * 1 - Single, + * 2 - Dual, + * 4 - Quad, + * 8 - Octal + */ + uint8_t sflash_pad_type; + /* [0x046-0x046] Serial Flash Frequencey, device specific + * definitions, See System Boot Chapter for more details + */ + uint8_t serial_clk_freq; + /* [0x047-0x047] LUT customization Enable, it is required if + * the program/erase cannot be done using 1 LUT sequence, + * currently, only applicable to HyperFLASH + */ + uint8_t lut_custom_seq_enable; + /* [0x048-0x04f] Reserved for future use */ + uint32_t reserved3[2]; + /* [0x050-0x053] Size of Flash connected to A1 */ + uint32_t sflash_a1_size; + /* [0x054-0x057] Size of Flash connected to A2 */ + uint32_t sflash_a2_size; + /* [0x058-0x05b] Size of Flash connected to B1 */ + uint32_t sflash_b1_size; + /* [0x05c-0x05f] Size of Flash connected to B2 */ + uint32_t sflash_b2_size; + /* [0x060-0x063] CS pad setting override value */ + uint32_t cs_pad_setting_override; + /* [0x064-0x067] SCK pad setting override value */ + uint32_t sclk_pad_setting_override; + /* [0x068-0x06b] data pad setting override value */ + uint32_t data_pad_setting_override; + /* [0x06c-0x06f] DQS pad setting override value */ + uint32_t dqs_pad_setting_override; + /* [0x070-0x073] Timeout threshold for read status command */ + uint32_t timeout_in_ms; + /* [0x074-0x077] CS deselect interval between two commands */ + uint32_t command_interval; + /* [0x078-0x07b] CLK edge to data valid time + * for PORT A and PORT B, in terms of 0.1ns + */ + uint16_t data_valid_time[2]; + /* [0x07c-0x07d] Busy offset, valid value: 0-31 */ + uint16_t busy_offset; + /* [0x07e-0x07f] Busy flag polarity, 0 - busy flag is 1 + * when flash device is busy, 1 - busy flag is 0 when + * flash device is busy + */ + uint16_t busy_bit_polarity; + /* [0x080-0x17f] Lookup table holds Flash command sequences */ + uint32_t lookup_table[64]; + /* [0x180-0x1af] Customizable LUT Sequences */ + flexspi_lut_seq_t lut_custom_seq[12]; + /* [0x1b0-0x1bf] Reserved for future use */ + uint32_t reserved4[4]; +} flexspi_mem_config_t; + +#define NOR_CMD_INDEX_READ CMD_INDEX_READ /* 0 */ +#define NOR_CMD_INDEX_READSTATUS CMD_INDEX_READSTATUS /* 1 */ +#define NOR_CMD_INDEX_WRITEENABLE CMD_INDEX_WRITEENABLE /* 2 */ +#define NOR_CMD_INDEX_ERASESECTOR 3 /* 3 */ +#define NOR_CMD_INDEX_PAGEPROGRAM CMD_INDEX_WRITE /* 4 */ +#define NOR_CMD_INDEX_CHIPERASE 5 /* 5 */ +#define NOR_CMD_INDEX_DUMMY 6 /* 6 */ +#define NOR_CMD_INDEX_ERASEBLOCK 7 /* 7 */ + +/* 0 READ LUT sequence id in lookupTable stored in config block */ +#define NOR_CMD_LUT_SEQ_IDX_READ CMD_LUT_SEQ_IDX_READ +/* 1 Read Status LUT sequence id in lookupTable stored in config block */ +#define NOR_CMD_LUT_SEQ_IDX_READSTATUS CMD_LUT_SEQ_IDX_READSTATUS +/* 2 Read status DPI/QPI/OPI sequence id in + * lookupTable stored in config block + */ +#define NOR_CMD_LUT_SEQ_IDX_READSTATUS_XPI 2 +/* 3 Write Enable sequence id in lookupTable stored in config block */ +#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE CMD_LUT_SEQ_IDX_WRITEENABLE +/* 4 Write Enable DPI/QPI/OPI sequence id in + * lookupTable stored in config block + */ +#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE_XPI 4 +/* 5 Erase Sector sequence id in lookupTable stored in config block */ +#define NOR_CMD_LUT_SEQ_IDX_ERASESECTOR 5 +/* 8 Erase Block sequence id in lookupTable stored in config block */ +#define NOR_CMD_LUT_SEQ_IDX_ERASEBLOCK 8 +/* 9 Program sequence id in lookupTable stored in config block */ +#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM CMD_LUT_SEQ_IDX_WRITE +/* 11 Chip Erase sequence in lookupTable id stored in config block */ +#define NOR_CMD_LUT_SEQ_IDX_CHIPERASE 11 +/* 13 Read SFDP sequence in lookupTable id stored in config block */ +#define NOR_CMD_LUT_SEQ_IDX_READ_SFDP 13 +/* 14 Restore 0-4-4/0-8-8 mode sequence id in + * lookupTable stored in config block + */ +#define NOR_CMD_LUT_SEQ_IDX_RESTORE_NOCMD 14 +/* 15 Exit 0-4-4/0-8-8 mode sequence id in + * lookupTable stored in config blobk + */ +#define NOR_CMD_LUT_SEQ_IDX_EXIT_NOCMD 15 + +/* + * Serial NOR configuration block + */ +typedef struct _flexspi_nor_config { + /* Common memory configuration info via FlexSPI */ + flexspi_mem_config_t mem_config; + /* Page size of Serial NOR */ + uint32_t page_size; + /* Sector size of Serial NOR */ + uint32_t sector_size; + /* Clock frequency for IP command */ + uint8_t ipcmd_serial_clk_freq; + /* Sector/Block size is the same */ + uint8_t is_uniform_block_size; + /* The data order is swapped in OPI DDR mode */ + uint8_t is_data_order_swapped; + /* Reserved for future use */ + uint8_t reserved0; + /* Serial NOR Flash type: 0/1/2/3 */ + uint8_t serial_nor_type; + /* Need to exit NoCmd mode before other IP command */ + uint8_t need_exit_nocmd_mode; + /* Half the Serial Clock for non-read command: true/false */ + uint8_t half_clk_for_non_read_cmd; + /* Need to Restore NoCmd mode after IP commmand execution */ + uint8_t need_restore_nocmd_mode; + /* Block size */ + uint32_t block_size; + /* Flash State Context after being configured */ + uint32_t flash_state_ctx; + /* Reserved for future use */ + uint32_t reserve2[10]; +} flexspi_nor_config_t; + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif +#endif /* #ifndef PHYCORE_FLEXSPI_NOR_CONFIG_ */ diff --git a/boards/phytec/phyboard_atlas/xmcd/xmcd.c b/boards/phytec/phyboard_atlas/xmcd/xmcd.c new file mode 100644 index 000000000000..4f4893dbb999 --- /dev/null +++ b/boards/phytec/phyboard_atlas/xmcd/xmcd.c @@ -0,0 +1,34 @@ +/* + * Copyright 2022 NXP + * All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "xmcd.h" + +#if defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_BOOT_FLEXSPI_NOR) + +#if defined(XIP_BOOT_HEADER_XMCD_ENABLE) && (XIP_BOOT_HEADER_XMCD_ENABLE == 1) +__attribute__((section(".boot_hdr.xmcd_data"), used)) + +const uint32_t xmcd_data[] = { + /* Tag = 0xC, Version = 0, Memory Interface: SEMC, + * Instance: 0 - ignored, + * Configuration block type: 0 - Ignored(Handled inside + * the SDRAM configuration structure) + * Configuration block size: 13 (4-byte header + 9-byte + * option block) + */ + 0xC010000Du, + /* Magic_number = 0xA1, Version = 1, + * Config_option: Simplified, SDRAM clock: 198MHz + */ + 0xC60001A1u, + /* SDRAM CS0 size: 64MBytes */ + 0x00010000u, + /* Port_size: 32-bit */ + 0x02u}; + +#endif /* XIP_BOOT_HEADER_XMCD_ENABLE */ +#endif /* defined(CONFIG_NXP_IMXRT_BOOT_HEADER) && defined(CONFIG_BOOT_FLEXSPI_NOR) */ diff --git a/boards/phytec/phyboard_atlas/xmcd/xmcd.h b/boards/phytec/phyboard_atlas/xmcd/xmcd.h new file mode 100644 index 000000000000..82933b423917 --- /dev/null +++ b/boards/phytec/phyboard_atlas/xmcd/xmcd.h @@ -0,0 +1,13 @@ +/* + * Copyright 2022 NXP + * All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef XMCD_ +#define XMCD_ + +#include + +#endif /* XMCD_ */ From 1e3602b73513aa7f94a580f01f6a21108cab8ef4 Mon Sep 17 00:00:00 2001 From: Daniel Schultz Date: Tue, 9 Sep 2025 11:44:49 +0200 Subject: [PATCH 2003/3659] tests: dac: Add phyBOARD-Atlas phyBOARD-Atlas is based on NXP's RT1176 MCU. Add this board nex to the NXP defines. Signed-off-by: Daniel Schultz --- tests/drivers/dac/dac_api/src/test_dac.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/drivers/dac/dac_api/src/test_dac.c b/tests/drivers/dac/dac_api/src/test_dac.c index f5312851988a..7e126cb5c188 100644 --- a/tests/drivers/dac/dac_api/src/test_dac.c +++ b/tests/drivers/dac/dac_api/src/test_dac.c @@ -85,7 +85,8 @@ defined(CONFIG_BOARD_YD_ESP32) || \ defined(CONFIG_BOARD_MIMXRT1170_EVK) || \ defined(CONFIG_BOARD_MIMXRT1180_EVK) || \ - defined(CONFIG_BOARD_FRDM_MCXC444) + defined(CONFIG_BOARD_FRDM_MCXC444) || \ + defined(CONFIG_BOARD_PHYBOARD_ATLAS) #define DAC_DEVICE_NODE DT_NODELABEL(dac) #define DAC_RESOLUTION 12 From e540442ec9c01c0434be2775eabd07dc89f2a047 Mon Sep 17 00:00:00 2001 From: Daniel Schultz Date: Wed, 10 Sep 2025 07:20:18 +0200 Subject: [PATCH 2004/3659] samples: net: prometheus: Exclude phyBOARD-Atlas This sample doesn't compile for the phyBOARD-Atlas. Exlude this board until it got fixed. Signed-off-by: Daniel Schultz --- samples/net/prometheus/sample.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/samples/net/prometheus/sample.yaml b/samples/net/prometheus/sample.yaml index 944e0df61a3a..b4e65654e58b 100644 --- a/samples/net/prometheus/sample.yaml +++ b/samples/net/prometheus/sample.yaml @@ -15,5 +15,7 @@ common: filter: not CONFIG_HAS_RENESAS_RA_FSP integration_platforms: - qemu_x86 + platform_exclude: + - phyboard_atlas/mimxrt1176/cm7 tests: sample.net.prometheus: {} From 16c40508fdcf715bf1701bd5f537ff57147cfd30 Mon Sep 17 00:00:00 2001 From: Daniel Schultz Date: Mon, 19 Jan 2026 08:58:07 +0100 Subject: [PATCH 2005/3659] tests: i2c: i2c_speed: Add phyBOARD-Atlas Files Add an overlay and conf file for the phyBOARD-Atlas. Those files are copies from NXP's RT1176 board, because the phyBOARD-Atlas is using the same MCU. Signed-off-by: Daniel Schultz --- tests/drivers/i2s/i2s_api/testcase.yaml | 2 ++ .../boards/phyboard_atlas_mimxrt1176_cm7.conf | 25 +++++++++++++++++++ .../phyboard_atlas_mimxrt1176_cm7.overlay | 19 ++++++++++++++ 3 files changed, 46 insertions(+) create mode 100644 tests/drivers/i2s/i2s_speed/boards/phyboard_atlas_mimxrt1176_cm7.conf create mode 100644 tests/drivers/i2s/i2s_speed/boards/phyboard_atlas_mimxrt1176_cm7.overlay diff --git a/tests/drivers/i2s/i2s_api/testcase.yaml b/tests/drivers/i2s/i2s_api/testcase.yaml index e29955d15c30..72cc8ba5d7b9 100644 --- a/tests/drivers/i2s/i2s_api/testcase.yaml +++ b/tests/drivers/i2s/i2s_api/testcase.yaml @@ -15,6 +15,7 @@ tests: - frdm_mcxn236/mcxn236 - mimxrt1180_evk/mimxrt1189/cm33 - mimxrt1180_evk/mimxrt1189/cm7 + - phyboard_atlas/mimxrt1176/cm7 drivers.i2s.gpio_loopback: depends_on: - i2s @@ -31,6 +32,7 @@ tests: - mimxrt685_evk/mimxrt685s/cm33 - nrf54h20dk/nrf54h20/cpuapp - frdm_mcxn236/mcxn236 + - phyboard_atlas/mimxrt1176/cm7 harness_config: fixture: gpio_loopback drivers.i2s.gpio_loopback.nrf54h: diff --git a/tests/drivers/i2s/i2s_speed/boards/phyboard_atlas_mimxrt1176_cm7.conf b/tests/drivers/i2s/i2s_speed/boards/phyboard_atlas_mimxrt1176_cm7.conf new file mode 100644 index 000000000000..8a1e1c2c47a8 --- /dev/null +++ b/tests/drivers/i2s/i2s_speed/boards/phyboard_atlas_mimxrt1176_cm7.conf @@ -0,0 +1,25 @@ +# +# Copyright (c) 2021, NXP +# +# SPDX-License-Identifier: Apache-2.0 +# + +# SAI peripheral does not have loopback mode but we can connect CLK, SYNC, +# RXD and TXD of one SAI for test purpose. +CONFIG_I2S_TEST_SEPARATE_DEVICES=n + +# CONFIG_DMA_TCD_QUEUE_SIZE sets size of queue used to chain DMA blocks (TCDs) +# together, and should be sized as needed by the application. If not large +# enough, the DMA may starve. Symptoms of this issue include transmit blocks +# repeated, or RX blocks skipped. For I2S driver, queue size must be at least 3. +CONFIG_DMA_TCD_QUEUE_SIZE=4 + +# Repeat test continually to help find intermittent issues +CONFIG_ZTEST_RETEST_IF_PASSED=y + +# I2S and DMA logging can occur in interrupt context, and interfere with I2S +# stream timing. If using either logging, set logging to deferred +# CONFIG_LOG_MODE_DEFERRED=y + +CONFIG_DMA_LOG_LEVEL_OFF=y +CONFIG_I2S_LOG_LEVEL_OFF=y diff --git a/tests/drivers/i2s/i2s_speed/boards/phyboard_atlas_mimxrt1176_cm7.overlay b/tests/drivers/i2s/i2s_speed/boards/phyboard_atlas_mimxrt1176_cm7.overlay new file mode 100644 index 000000000000..b60e45acd5f9 --- /dev/null +++ b/tests/drivers/i2s/i2s_speed/boards/phyboard_atlas_mimxrt1176_cm7.overlay @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2025 PHYTEC America LLC + * SPDX-License-Identifier: Apache-2.0 + * + * i2s_speed with CONFIG_I2S_TEST_SEPARATE_DEVICES=n uses only one I2S peripheral: + * i2s-node0 is both the transitter and receiver. + * uses SAI1 peripheral on RT1170 + */ +/ { + aliases { + i2s-node0 = &sai1; + }; +}; + +/* Default DMA channel 0 and 1 maybe used by other peripherals like UART. */ +&sai1 { + nxp,tx-dma-channel = <8>; + nxp,rx-dma-channel = <9>; +}; From 8c82334f5b2c3ac4f3e60e83e6498f5b23e600a0 Mon Sep 17 00:00:00 2001 From: Pierre-Henry Moussay Date: Wed, 11 Jun 2025 11:00:41 +0100 Subject: [PATCH 2006/3659] soc: microchip: pic64: Add minimal support for PIC64GX Add minimal support for PIC64GX SoC and devicetree Signed-off-by: Pierre-Henry Moussay --- dts/riscv/microchip/pic64gx.dtsi | 298 ++++++++++++++++++ soc/microchip/pic64/CMakeLists.txt | 4 + soc/microchip/pic64/Kconfig | 8 + soc/microchip/pic64/Kconfig.defconfig | 8 + soc/microchip/pic64/Kconfig.soc | 10 + soc/microchip/pic64/pic64gx/CMakeLists.txt | 6 + soc/microchip/pic64/pic64gx/Kconfig | 39 +++ soc/microchip/pic64/pic64gx/Kconfig.defconfig | 28 ++ .../pic64gx/Kconfig.defconfig.pic64gx1000_u54 | 17 + soc/microchip/pic64/pic64gx/Kconfig.soc | 28 ++ soc/microchip/pic64/soc.yml | 9 + 11 files changed, 455 insertions(+) create mode 100644 dts/riscv/microchip/pic64gx.dtsi create mode 100644 soc/microchip/pic64/CMakeLists.txt create mode 100644 soc/microchip/pic64/Kconfig create mode 100644 soc/microchip/pic64/Kconfig.defconfig create mode 100644 soc/microchip/pic64/Kconfig.soc create mode 100644 soc/microchip/pic64/pic64gx/CMakeLists.txt create mode 100644 soc/microchip/pic64/pic64gx/Kconfig create mode 100644 soc/microchip/pic64/pic64gx/Kconfig.defconfig create mode 100644 soc/microchip/pic64/pic64gx/Kconfig.defconfig.pic64gx1000_u54 create mode 100644 soc/microchip/pic64/pic64gx/Kconfig.soc create mode 100644 soc/microchip/pic64/soc.yml diff --git a/dts/riscv/microchip/pic64gx.dtsi b/dts/riscv/microchip/pic64gx.dtsi new file mode 100644 index 000000000000..7bb3ab39ec80 --- /dev/null +++ b/dts/riscv/microchip/pic64gx.dtsi @@ -0,0 +1,298 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + #address-cells = <1>; + #size-cells = <1>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + clock-frequency = <0>; + compatible = "sifive,e51", "riscv"; + device_type = "cpu"; + reg = <0x0>; + riscv,isa = "rv64imac_zicsr_zifencei"; + + hlic0: interrupt-controller { + compatible = "riscv,cpu-intc"; + #address-cells = <0>; + #interrupt-cells = <1>; + interrupt-controller; + }; + }; + + cpu@1 { + clock-frequency = <0>; + compatible = "sifive,u54", "riscv"; + device_type = "cpu"; + reg = <0x1>; + riscv,isa = "rv64gc"; + + hlic1: interrupt-controller { + compatible = "riscv,cpu-intc"; + #address-cells = <0>; + #interrupt-cells = <1>; + interrupt-controller; + }; + }; + + cpu@2 { + clock-frequency = <0>; + compatible = "sifive,u54", "riscv"; + device_type = "cpu"; + reg = <0x2>; + riscv,isa = "rv64gc"; + + hlic2: interrupt-controller { + compatible = "riscv,cpu-intc"; + #address-cells = <0>; + #interrupt-cells = <1>; + interrupt-controller; + }; + }; + + cpu@3 { + clock-frequency = <0>; + compatible = "sifive,u54", "riscv"; + device_type = "cpu"; + reg = <0x3>; + riscv,isa = "rv64gc"; + + hlic3: interrupt-controller { + compatible = "riscv,cpu-intc"; + #address-cells = <0>; + #interrupt-cells = <1>; + interrupt-controller; + }; + }; + + cpu@4 { + clock-frequency = <0>; + compatible = "sifive,u54", "riscv"; + device_type = "cpu"; + reg = <0x4>; + riscv,isa = "rv64gc"; + + hlic4: interrupt-controller { + compatible = "riscv,cpu-intc"; + #address-cells = <0>; + #interrupt-cells = <1>; + interrupt-controller; + }; + }; + }; + + soc { + #address-cells = <1>; + #size-cells = <1>; + compatible = "simple-bus"; + ranges; + + clint: clint@2000000 { + compatible = "sifive,clint0"; + interrupts-extended = <&hlic0 3 + &hlic1 3 + &hlic2 3 + &hlic3 3 + &hlic4 3>; + interrupt-names = "soft0", "soft1", "soft2", "soft3", + "soft4"; + reg = <0x2000000 0x10000>; + }; + + mtimer: timer@200bff8 { + compatible = "riscv,machine-timer"; + interrupts-extended = <&hlic0 7 + &hlic1 7 + &hlic2 7 + &hlic3 7 + &hlic4 7>; + reg = <0x200bff8 0x8 0x2004000 0x8>; + reg-names = "mtime", "mtimecmp"; + }; + + plic: interrupt-controller@c000000 { + compatible = "sifive,plic-1.0.0"; + #interrupt-cells = <2>; + #address-cells = <1>; + interrupt-controller; + interrupts-extended = <&hlic0 11 + &hlic1 11 &hlic1 9 + &hlic2 11 &hlic2 9 + &hlic3 11 &hlic3 9 + &hlic4 11 &hlic4 9>; + reg = <0x0c000000 0x04000000>; + riscv,max-priority = <7>; + riscv,ndev = <185>; + }; + + mmuart0: serial@20000000 { + compatible = "ns16550"; + reg = <0x20000000 0x1000>; + clock-frequency = <150000000>; + current-speed = <115200>; + interrupt-parent = <&plic>; + interrupts = <90 1>; + reg-shift = <2>; + status = "disabled"; + }; + + mmuart1: serial@20100000 { + compatible = "ns16550"; + reg = <0x20100000 0x1000>; + clock-frequency = <150000000>; + current-speed = <115200>; + interrupt-parent = <&plic>; + interrupts = <91 1>; + reg-shift = <2>; + status = "disabled"; + }; + + mmuart2: serial@20102000 { + compatible = "ns16550"; + reg = <0x20102000 0x1000>; + clock-frequency = <150000000>; + current-speed = <115200>; + interrupt-parent = <&plic>; + interrupts = <92 1>; + reg-shift = <2>; + status = "disabled"; + }; + + mmuart3: serial@20104000 { + compatible = "ns16550"; + reg = <0x20104000 0x1000>; + clock-frequency = <150000000>; + current-speed = <115200>; + interrupt-parent = <&plic>; + interrupts = <93 1>; + reg-shift = <2>; + status = "disabled"; + }; + + mmuart4: serial@20106000 { + compatible = "ns16550"; + reg = <0x20106000 0x1000>; + clock-frequency = <150000000>; + current-speed = <115200>; + interrupt-parent = <&plic>; + interrupts = <94 1>; + reg-shift = <2>; + status = "disabled"; + }; + + spi0: spi@20108000 { + compatible = "microchip,pic64gx-spi", "microchip,mpfs-spi"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x20108000 0x1000>; + interrupt-parent = <&plic>; + interrupts = <54 1>; + status = "disabled"; + clock-frequency = <150000000>; + }; + + spi1: spi@20109000 { + compatible = "microchip,pic64gx-spi", "microchip,mpfs-spi"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x20109000 0x1000>; + interrupt-parent = <&plic>; + interrupts = <55 1>; + status = "disabled"; + clock-frequency = <150000000>; + }; + + i2c0: i2c@2010a000 { + compatible = "microchip,pic64gx-i2c", "microchip,mpfs-i2c"; + reg = <0x2010a000 0x1000>; + interrupt-parent = <&plic>; + interrupts = <58 1>; + #address-cells = <1>; + #size-cells = <0>; + clock-frequency = <100000>; + status = "disabled"; + }; + + i2c1: i2c@2010b000 { + compatible = "microchip,pic64gx-i2c", "microchip,mpfs-i2c"; + reg = <0x2010b000 0x1000>; + interrupt-parent = <&plic>; + interrupts = <61 1>; + #address-cells = <1>; + #size-cells = <0>; + clock-frequency = <100000>; + status = "disabled"; + }; + + gpio0: gpio@20120000 { + compatible = "microchip,pic64gx-gpio", "microchip,mpfs-gpio"; + reg = <0x20120000 0x1000>; + interrupt-parent = <&plic>; + interrupts = <51 1>; + interrupt-controller; + #interrupt-cells = <1>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <32>; + status = "disabled"; + }; + + gpio1: gpio@20121000 { + compatible = "microchip,pic64gx-gpio", "microchip,mpfs-gpio"; + reg = <0x20121000 0x1000>; + interrupt-parent = <&plic>; + interrupts = <52 1>; + interrupt-controller; + #interrupt-cells = <1>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <32>; + status = "disabled"; + }; + + gpio2: gpio@20122000 { + compatible = "microchip,pic64gx-gpio", "microchip,mpfs-gpio"; + reg = <0x20122000 0x1000>; + interrupt-parent = <&plic>; + interrupts = <53 1>; + interrupt-controller; + #interrupt-cells = <1>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <32>; + status = "disabled"; + }; + + qspi: spi@21000000 { + compatible = "microchip,pic64gx-qspi", "microchip,mpfs-qspi"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x21000000 0x1000>; + interrupt-parent = <&plic>; + interrupts = <85 1>; + status = "disabled"; + clock-frequency = <150000000>; + }; + + syscontroller_qspi: spi@37020100 { + compatible = "microchip,pic64gx-qspi", "microchip,mpfs-qspi"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x37020100 0x1000>; + interrupt-parent = <&plic>; + interrupts = <110 1>; + status = "disabled"; + clock-frequency = <150000000>; + }; + }; +}; diff --git a/soc/microchip/pic64/CMakeLists.txt b/soc/microchip/pic64/CMakeLists.txt new file mode 100644 index 000000000000..c11e65d03ac2 --- /dev/null +++ b/soc/microchip/pic64/CMakeLists.txt @@ -0,0 +1,4 @@ +# Copyright (c) 2025 Microchip Technology Inc +# SPDX-License-Identifier: Apache-2.0 + +add_subdirectory(${SOC_SERIES}) diff --git a/soc/microchip/pic64/Kconfig b/soc/microchip/pic64/Kconfig new file mode 100644 index 000000000000..a81f7773db79 --- /dev/null +++ b/soc/microchip/pic64/Kconfig @@ -0,0 +1,8 @@ +# Copyright (c) 2025 Microchip Technology Inc +# SPDX-License-Identifier: Apache-2.0 + +if SOC_FAMILY_MICROCHIP_PIC64 + +rsource "*/Kconfig" + +endif # SOC_FAMILY_MICROCHIP_PIC64 diff --git a/soc/microchip/pic64/Kconfig.defconfig b/soc/microchip/pic64/Kconfig.defconfig new file mode 100644 index 000000000000..de7f248e0599 --- /dev/null +++ b/soc/microchip/pic64/Kconfig.defconfig @@ -0,0 +1,8 @@ +# Copyright (c) 2025 Microchip Technology Inc +# SPDX-License-Identifier: Apache-2.0 + +if SOC_FAMILY_MICROCHIP_PIC64 + +rsource "*/Kconfig.defconfig" + +endif # SOC_FAMILY_MICROCHIP_PIC64 diff --git a/soc/microchip/pic64/Kconfig.soc b/soc/microchip/pic64/Kconfig.soc new file mode 100644 index 000000000000..f50490bdffe4 --- /dev/null +++ b/soc/microchip/pic64/Kconfig.soc @@ -0,0 +1,10 @@ +# Copyright (c) 2025 Microchip Technology Inc +# SPDX-License-Identifier: Apache-2.0 + +config SOC_FAMILY_MICROCHIP_PIC64 + bool + +config SOC_FAMILY + default "microchip_pic64" if SOC_FAMILY_MICROCHIP_PIC64 + +rsource "*/Kconfig.soc" diff --git a/soc/microchip/pic64/pic64gx/CMakeLists.txt b/soc/microchip/pic64/pic64gx/CMakeLists.txt new file mode 100644 index 000000000000..0ce57d6c5a28 --- /dev/null +++ b/soc/microchip/pic64/pic64gx/CMakeLists.txt @@ -0,0 +1,6 @@ +# Copyright (c) 2025 Microchip Technology Inc +# SPDX-License-Identifier: Apache-2.0 + +zephyr_sources() + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/riscv/common/linker.ld CACHE INTERNAL "") diff --git a/soc/microchip/pic64/pic64gx/Kconfig b/soc/microchip/pic64/pic64gx/Kconfig new file mode 100644 index 000000000000..b8cc439b9367 --- /dev/null +++ b/soc/microchip/pic64/pic64gx/Kconfig @@ -0,0 +1,39 @@ +# RISCV64 Microchip PIC64GX SOC configuration options + +# Copyright (c) 2025 Microchip Technology Inc +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_PIC64GX + select RISCV + select RISCV_PRIVILEGED + select RISCV_HAS_PLIC + select RISCV_PMP + select RISCV_SOC_HAS_GP_RELATIVE_ADDRESSING + imply XIP + +config SOC_PIC64GX1000 + bool + select 64BIT + select SCHED_IPI_SUPPORTED + select ATOMIC_OPERATIONS_BUILTIN + select INCLUDE_RESET_VECTOR + select RISCV_SOC_HAS_GP_RELATIVE_ADDRESSING + select USE_SWITCH_SUPPORTED + select USE_SWITCH + +config SOC_PIC64GX1000_U54 + bool + select CPU_HAS_FPU + select CPU_HAS_FPU_DOUBLE_PRECISION + select RISCV_ISA_RV64I + select RISCV_ISA_EXT_G + select RISCV_ISA_EXT_C + +config SOC_PIC64GX1000_E51 + bool + select RISCV_ISA_RV64I + select RISCV_ISA_EXT_M + select RISCV_ISA_EXT_A + select RISCV_ISA_EXT_C + select RISCV_ISA_EXT_ZICSR + select RISCV_ISA_EXT_ZIFENCEI diff --git a/soc/microchip/pic64/pic64gx/Kconfig.defconfig b/soc/microchip/pic64/pic64gx/Kconfig.defconfig new file mode 100644 index 000000000000..78bc963eca64 --- /dev/null +++ b/soc/microchip/pic64/pic64gx/Kconfig.defconfig @@ -0,0 +1,28 @@ +# Copyright (c) 2025 Microchip Technology Inc +# SPDX-License-Identifier: Apache-2.0 + +if SOC_SERIES_PIC64GX + +rsource "Kconfig.defconfig.pic64gx*" + +# PIC64GX should be configured so that the mtimer clock is 1MHz independent of the CPU clock... + +config SYS_CLOCK_HW_CYCLES_PER_SEC + default 1000000 + +config RISCV_SOC_INTERRUPT_INIT + default y + +config 2ND_LVL_ISR_TBL_OFFSET + default 12 + +config 2ND_LVL_INTR_00_OFFSET + default 11 + +config MAX_IRQ_PER_AGGREGATOR + default 186 + +config NUM_IRQS + default 198 + +endif # SOC_SERIES_PIC64GX diff --git a/soc/microchip/pic64/pic64gx/Kconfig.defconfig.pic64gx1000_u54 b/soc/microchip/pic64/pic64gx/Kconfig.defconfig.pic64gx1000_u54 new file mode 100644 index 000000000000..340e17ea97cf --- /dev/null +++ b/soc/microchip/pic64/pic64gx/Kconfig.defconfig.pic64gx1000_u54 @@ -0,0 +1,17 @@ +# Copyright (c) 2025 Microchip Technology Inc +# SPDX-License-Identifier: Apache-2.0 + +if SOC_PIC64GX1000_U54 + +DT_COMPAT_SIFIVE_U54 := sifive,u54 + +config MP_MAX_NUM_CPUS + default $(dt_compat_enabled_num,$(DT_COMPAT_SIFIVE_U54)) + +config RV_BOOT_HART + default 1 if ($(dt_path_enabled,/cpus/cpu@1)) + default 2 if ($(dt_path_enabled,/cpus/cpu@2)) + default 3 if ($(dt_path_enabled,/cpus/cpu@3)) + default 4 if ($(dt_path_enabled,/cpus/cpu@4)) + +endif diff --git a/soc/microchip/pic64/pic64gx/Kconfig.soc b/soc/microchip/pic64/pic64gx/Kconfig.soc new file mode 100644 index 000000000000..b9c19910490e --- /dev/null +++ b/soc/microchip/pic64/pic64gx/Kconfig.soc @@ -0,0 +1,28 @@ +# RISCV64 Microchip PIC64GX SOC configuration options + +# Copyright (c) 2025 Microchip Technology Inc +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_PIC64GX + bool + select SOC_FAMILY_MICROCHIP_PIC64 + help + Enable support for Microchip PIC64GX SoC. + +config SOC_PIC64GX1000 + bool + select SOC_SERIES_PIC64GX + +config SOC_PIC64GX1000_U54 + bool + select SOC_PIC64GX1000 + +config SOC_PIC64GX1000_E51 + bool + select SOC_PIC64GX1000 + +config SOC_SERIES + default "pic64gx" if SOC_SERIES_PIC64GX + +config SOC + default "pic64gx1000" if SOC_PIC64GX1000 diff --git a/soc/microchip/pic64/soc.yml b/soc/microchip/pic64/soc.yml new file mode 100644 index 000000000000..3e7404fdf4f3 --- /dev/null +++ b/soc/microchip/pic64/soc.yml @@ -0,0 +1,9 @@ +family: +- name: microchip_pic64 + series: + - name: pic64gx + socs: + - name: pic64gx1000 + cpuclusters: + - name: e51 + - name: u54 From e19fd33b6c85026936f8308f7a8af523c6c29c9e Mon Sep 17 00:00:00 2001 From: Pierre-Henry Moussay Date: Wed, 11 Jun 2025 11:02:52 +0100 Subject: [PATCH 2007/3659] boards: microchip: Add minimal support for pic64gx_curiosity_kit Add minimal support for PIC64GX curiosity kit Signed-off-by: Pierre-Henry Moussay --- .../Kconfig.pic64gx_curiosity_kit | 7 ++ .../pic64gx_curiosity_kit/board.cmake | 13 ++ .../microchip/pic64gx_curiosity_kit/board.yml | 9 ++ .../doc/img/pic64gx_curiosity_kit.webp | Bin 0 -> 77300 bytes .../pic64gx_curiosity_kit/doc/index.rst | 114 +++++++++++++++++ .../pic64gx_curiosity_kit_common.dtsi | 118 ++++++++++++++++++ .../pic64gx_curiosity_kit_defconfig | 14 +++ .../pic64gx_curiosity_kit_pic64gx1000_e51.dts | 42 +++++++ ...pic64gx_curiosity_kit_pic64gx1000_e51.yaml | 12 ++ ...gx_curiosity_kit_pic64gx1000_e51_defconfig | 13 ++ .../pic64gx_curiosity_kit_pic64gx1000_u54.dts | 30 +++++ ...pic64gx_curiosity_kit_pic64gx1000_u54.yaml | 12 ++ ...gx_curiosity_kit_pic64gx1000_u54_defconfig | 13 ++ ...64gx_curiosity_kit_pic64gx1000_u54_smp.dts | 24 ++++ ...4gx_curiosity_kit_pic64gx1000_u54_smp.yaml | 12 ++ ...uriosity_kit_pic64gx1000_u54_smp_defconfig | 14 +++ .../support/embedded_flashpro5.cfg | 38 ++++++ .../pic64gx_curiosity_kit/support/openocd.cfg | 73 +++++++++++ 18 files changed, 558 insertions(+) create mode 100644 boards/microchip/pic64gx_curiosity_kit/Kconfig.pic64gx_curiosity_kit create mode 100644 boards/microchip/pic64gx_curiosity_kit/board.cmake create mode 100644 boards/microchip/pic64gx_curiosity_kit/board.yml create mode 100644 boards/microchip/pic64gx_curiosity_kit/doc/img/pic64gx_curiosity_kit.webp create mode 100644 boards/microchip/pic64gx_curiosity_kit/doc/index.rst create mode 100644 boards/microchip/pic64gx_curiosity_kit/pic64gx_curiosity_kit_common.dtsi create mode 100644 boards/microchip/pic64gx_curiosity_kit/pic64gx_curiosity_kit_defconfig create mode 100644 boards/microchip/pic64gx_curiosity_kit/pic64gx_curiosity_kit_pic64gx1000_e51.dts create mode 100644 boards/microchip/pic64gx_curiosity_kit/pic64gx_curiosity_kit_pic64gx1000_e51.yaml create mode 100644 boards/microchip/pic64gx_curiosity_kit/pic64gx_curiosity_kit_pic64gx1000_e51_defconfig create mode 100644 boards/microchip/pic64gx_curiosity_kit/pic64gx_curiosity_kit_pic64gx1000_u54.dts create mode 100644 boards/microchip/pic64gx_curiosity_kit/pic64gx_curiosity_kit_pic64gx1000_u54.yaml create mode 100644 boards/microchip/pic64gx_curiosity_kit/pic64gx_curiosity_kit_pic64gx1000_u54_defconfig create mode 100644 boards/microchip/pic64gx_curiosity_kit/pic64gx_curiosity_kit_pic64gx1000_u54_smp.dts create mode 100644 boards/microchip/pic64gx_curiosity_kit/pic64gx_curiosity_kit_pic64gx1000_u54_smp.yaml create mode 100644 boards/microchip/pic64gx_curiosity_kit/pic64gx_curiosity_kit_pic64gx1000_u54_smp_defconfig create mode 100644 boards/microchip/pic64gx_curiosity_kit/support/embedded_flashpro5.cfg create mode 100644 boards/microchip/pic64gx_curiosity_kit/support/openocd.cfg diff --git a/boards/microchip/pic64gx_curiosity_kit/Kconfig.pic64gx_curiosity_kit b/boards/microchip/pic64gx_curiosity_kit/Kconfig.pic64gx_curiosity_kit new file mode 100644 index 000000000000..43944b72d610 --- /dev/null +++ b/boards/microchip/pic64gx_curiosity_kit/Kconfig.pic64gx_curiosity_kit @@ -0,0 +1,7 @@ +# Copyright (c) 2025 Microchip Technology Inc +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_PIC64GX_CURIOSITY_KIT + select SOC_PIC64GX1000_U54 if BOARD_PIC64GX_CURIOSITY_KIT_PIC64GX1000_U54 || \ + BOARD_PIC64GX_CURIOSITY_KIT_PIC64GX1000_U54_SMP + select SOC_PIC64GX1000_E51 if BOARD_PIC64GX_CURIOSITY_KIT_PIC64GX1000_E51 diff --git a/boards/microchip/pic64gx_curiosity_kit/board.cmake b/boards/microchip/pic64gx_curiosity_kit/board.cmake new file mode 100644 index 000000000000..f7270b10e7f2 --- /dev/null +++ b/boards/microchip/pic64gx_curiosity_kit/board.cmake @@ -0,0 +1,13 @@ +# SPDX-License-Identifier: Apache-2.0 + +set(OPENOCD_USE_LOAD_IMAGE NO) + +board_runner_args(openocd --use-elf --no-load) + +if(CONFIG_BOARD_PIC64GX_CURIOSITY_KIT_PIC64GX1000_E51) + board_runner_args(openocd --gdb-client-port=3333) +elseif(CONFIG_BOARD_PIC64GX_CURIOSITY_KIT_PIC64GX1000_U54) + board_runner_args(openocd --gdb-client-port=3334) +endif() + +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) diff --git a/boards/microchip/pic64gx_curiosity_kit/board.yml b/boards/microchip/pic64gx_curiosity_kit/board.yml new file mode 100644 index 000000000000..fd9710620725 --- /dev/null +++ b/boards/microchip/pic64gx_curiosity_kit/board.yml @@ -0,0 +1,9 @@ +board: + name: pic64gx_curiosity_kit + full_name: pic64gx_curiosity_kit + vendor: microchip + socs: + - name: pic64gx1000 + variants: + - name: smp + cpucluster: u54 diff --git a/boards/microchip/pic64gx_curiosity_kit/doc/img/pic64gx_curiosity_kit.webp b/boards/microchip/pic64gx_curiosity_kit/doc/img/pic64gx_curiosity_kit.webp new file mode 100644 index 0000000000000000000000000000000000000000..37084cb5e4f0a7c195208906de88c21112cc9bac GIT binary patch literal 77300 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. + +Programming and debugging +************************* + +Building +======== + +Applications for the ``pic64gx_curiosity_kit`` board configuration can be built as usual +(see :ref:`build_an_application`): + +.. zephyr-app-commands:: + :board: pic64gx_curiosity_kit/pic64gx1000/u54 + :goals: build + +.. zephyr-app-commands:: + :board: pic64gx_curiosity_kit/pic64gx1000/u54/smp + :goals: build + +Flashing +======== + +To Flash to the device, the easiest way to proceed is to load the binary using a sdcard. +The binary on the sdcard can then be loaded by the bootloader at the designated address. + +For the bootloader to be able to load the application, a payload file needs to be generated. +Please proceed as follows: + +To get the hss-payload-generator tool, please clone the following repository and build the tool: + +.. code-block:: bash + + git clone https://github.com/pic64gx/pic64gx-hart-software-services.git + cd pic64gx-hart-software-services/tools/hss-payload-generator + make + +To generate a payload: + +.. code-block:: bash + + ./hss-payload-generator -c config.yaml -v output.bin + +A payload generator config file such as the following should be used to generate a compatible with the Hart Software Services (HSS). +https://github.com/pic64gx/pic64gx-hart-software-services + +For single core: + +.. code-block:: yaml + + set-name: 'Zephyr-DDR' + + hart-entry-points: { + u54_1: '0x80000000' + } + + payloads: + build/zephyr/zephyr.elf: { + exec-addr: '0x80000000', + owner-hart: u54_1, + priv-mode: prv_m, + skip-opensbi: true, + payload-name: "zephyr" + } + +For SMP: + +.. code-block:: yaml + + set-name: 'Zephyr-SMP-DDR' + + hart-entry-points: { + u54_1: '0x80000000', + u54_2: '0x80000000', + u54_3: '0x80000000', + u54_4: '0x80000000' + } + + payloads: + build/zephyr/zephyr.elf: { + exec-addr: '0x80000000', + owner-hart: u54_1, + secondary-hart: u54_2, + secondary-hart: u54_3, + secondary-hart: u54_4, + priv-mode: prv_m, + skip-opensbi: true, + payload-name: "zephyr" + } + +Please refer to the following README.md for more information on payload generation: +https://github.com/pic64gx/pic64gx-hart-software-services/blob/pic64gx/tools/hss-payload-generator/README.md + +Then the output payload file needs to be copied to the sdcard (assuming the sdcard is mounted at /dev/sdx). + +.. code-block:: bash + + sudo dd if= of=/dev/sdx + +Debugging +========= + +Please note that in most use cases, the application must be loaded in the external DDR memory. +And therefore DDR must be initialized before loading the application or debugging the application. + +The way to proceed is to load the HSS firmware first, then load the application in DDR memory through +the HSS loader following the instructions in `Flashing`_. + +Then proceed to debug the application as usual (ie: :ref:`application_debugging`.) diff --git a/boards/microchip/pic64gx_curiosity_kit/pic64gx_curiosity_kit_common.dtsi b/boards/microchip/pic64gx_curiosity_kit/pic64gx_curiosity_kit_common.dtsi new file mode 100644 index 000000000000..1997446f9956 --- /dev/null +++ b/boards/microchip/pic64gx_curiosity_kit/pic64gx_curiosity_kit_common.dtsi @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include +#include + +/ { + model = "Microchip PIC64GX Curiosity Kit"; + compatible = "microchip,pic64gx-curiosity-kit", "microchip,pic64gx"; + + aliases { + led0 = &led1; + sw0 = &sw1; + i2c0 = &i2c0; + i2c1 = &i2c1; + }; + + soc { + dram: memory@80000000 { + compatible = "mmio-sram"; + reg = <0x80000000 0x40000000>; + }; + }; + + leds { + compatible = "gpio-leds"; + + led1: led1 { + gpios = <&gpio1 2 (GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH)>; + label = "LED_1"; + }; + + led2: led2 { + gpios = <&gpio1 3 (GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH)>; + label = "LED_2"; + }; + + led3: led3 { + gpios = <&gpio1 4 (GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH)>; + label = "LED_3"; + }; + + led4: led4 { + gpios = <&gpio1 5 (GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH)>; + label = "LED_4"; + }; + + led5: led5 { + gpios = <&gpio1 6 (GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH)>; + label = "LED_5"; + }; + + led6: led6 { + gpios = <&gpio1 7 (GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH)>; + label = "LED_6"; + }; + + led7: led7 { + gpios = <&gpio1 8 (GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH)>; + label = "LED_7"; + }; + + led8: led8 { + gpios = <&gpio1 9 (GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH)>; + label = "LED_8"; + }; + }; + + keys { + compatible = "gpio-keys"; + + sw1: sw1 { + gpios = <&gpio2 28 GPIO_ACTIVE_LOW>; + label = "SW_1"; + zephyr,code = ; + }; + + sw2: sw2 { + gpios = <&gpio2 6 GPIO_ACTIVE_LOW>; + label = "SW_2"; + zephyr,code = ; + }; + }; +}; + +&gpio1 { + status = "okay"; + + mux-hog { + gpio-hog; + gpios = <2 GPIO_ACTIVE_HIGH>, <3 GPIO_ACTIVE_HIGH>, + <4 GPIO_ACTIVE_HIGH>, <5 GPIO_ACTIVE_HIGH>, + <6 GPIO_ACTIVE_HIGH>, <7 GPIO_ACTIVE_HIGH>, + <8 GPIO_ACTIVE_HIGH>, <9 GPIO_ACTIVE_HIGH>; + output-low; + }; +}; + +&spi1 { + status = "okay"; +}; + +&gpio2 { + status = "okay"; +}; + +&i2c0 { + status = "okay"; +}; + +&i2c1 { + status = "okay"; +}; diff --git a/boards/microchip/pic64gx_curiosity_kit/pic64gx_curiosity_kit_defconfig b/boards/microchip/pic64gx_curiosity_kit/pic64gx_curiosity_kit_defconfig new file mode 100644 index 000000000000..0501f1bf1218 --- /dev/null +++ b/boards/microchip/pic64gx_curiosity_kit/pic64gx_curiosity_kit_defconfig @@ -0,0 +1,14 @@ +# Copyright (c) 2025 Microchip Technology Inc +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_BASE64=y +CONFIG_INCLUDE_RESET_VECTOR=y +CONFIG_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_UART_CONSOLE=y +CONFIG_XIP=n +CONFIG_INIT_STACKS=y +CONFIG_SYS_CLOCK_TICKS_PER_SEC=1000 +CONFIG_FPU=n +# GPIO driver options +CONFIG_GPIO=y diff --git a/boards/microchip/pic64gx_curiosity_kit/pic64gx_curiosity_kit_pic64gx1000_e51.dts b/boards/microchip/pic64gx_curiosity_kit/pic64gx_curiosity_kit_pic64gx1000_e51.dts new file mode 100644 index 000000000000..22eef350de5d --- /dev/null +++ b/boards/microchip/pic64gx_curiosity_kit/pic64gx_curiosity_kit_pic64gx1000_e51.dts @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include "pic64gx_curiosity_kit_common.dtsi" + +/ { + compatible = "microchip,pic64gx-curiosity-kit", "microchip,pic64gx"; + + cpus { + cpu@1 { + status = "disabled"; + }; + + cpu@2 { + status = "disabled"; + }; + + cpu@3 { + status = "disabled"; + }; + + cpu@4 { + status = "disabled"; + }; + }; + + chosen { + zephyr,console = &mmuart0; + zephyr,shell-uart = &mmuart0; + zephyr,sram = &dram; + }; +}; + +&mmuart0 { + status = "okay"; + current-speed = <115200>; + clock-frequency = <150000000>; +}; diff --git a/boards/microchip/pic64gx_curiosity_kit/pic64gx_curiosity_kit_pic64gx1000_e51.yaml b/boards/microchip/pic64gx_curiosity_kit/pic64gx_curiosity_kit_pic64gx1000_e51.yaml new file mode 100644 index 000000000000..0a41b341b508 --- /dev/null +++ b/boards/microchip/pic64gx_curiosity_kit/pic64gx_curiosity_kit_pic64gx1000_e51.yaml @@ -0,0 +1,12 @@ +identifier: pic64gx_curiosity_kit/pic64gx1000/e51 +name: Microchip PIC64GX Curiosity kit +type: mcu +arch: riscv +toolchain: + - zephyr +ram: 1024 +testing: + ignore_tags: + - net + - bluetooth +vendor: microchip diff --git a/boards/microchip/pic64gx_curiosity_kit/pic64gx_curiosity_kit_pic64gx1000_e51_defconfig b/boards/microchip/pic64gx_curiosity_kit/pic64gx_curiosity_kit_pic64gx1000_e51_defconfig new file mode 100644 index 000000000000..186867521425 --- /dev/null +++ b/boards/microchip/pic64gx_curiosity_kit/pic64gx_curiosity_kit_pic64gx1000_e51_defconfig @@ -0,0 +1,13 @@ +# Copyright (c) 2025 Microchip Technology Inc +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_BASE64=y +CONFIG_INCLUDE_RESET_VECTOR=y +CONFIG_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_UART_CONSOLE=y +CONFIG_XIP=n +CONFIG_INIT_STACKS=y +CONFIG_SYS_CLOCK_TICKS_PER_SEC=1000 +# GPIO driver options +CONFIG_GPIO=y diff --git a/boards/microchip/pic64gx_curiosity_kit/pic64gx_curiosity_kit_pic64gx1000_u54.dts b/boards/microchip/pic64gx_curiosity_kit/pic64gx_curiosity_kit_pic64gx1000_u54.dts new file mode 100644 index 000000000000..bca7e8338be6 --- /dev/null +++ b/boards/microchip/pic64gx_curiosity_kit/pic64gx_curiosity_kit_pic64gx1000_u54.dts @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include "pic64gx_curiosity_kit_common.dtsi" + +/ { + compatible = "microchip,pic64gx-curiosity-kit", "microchip,pic64gx"; + + cpus { + cpu@0 { + status = "disabled"; + }; + }; + + chosen { + zephyr,console = &mmuart1; + zephyr,shell-uart = &mmuart1; + zephyr,sram = &dram; + }; +}; + +&mmuart1 { + status = "okay"; + current-speed = <115200>; + clock-frequency = <150000000>; +}; diff --git a/boards/microchip/pic64gx_curiosity_kit/pic64gx_curiosity_kit_pic64gx1000_u54.yaml b/boards/microchip/pic64gx_curiosity_kit/pic64gx_curiosity_kit_pic64gx1000_u54.yaml new file mode 100644 index 000000000000..9841884511ae --- /dev/null +++ b/boards/microchip/pic64gx_curiosity_kit/pic64gx_curiosity_kit_pic64gx1000_u54.yaml @@ -0,0 +1,12 @@ +identifier: pic64gx_curiosity_kit/pic64gx1000/u54 +name: Microchip PIC64GX Curiosity kit +type: mcu +arch: riscv +toolchain: + - zephyr +ram: 1024 +testing: + ignore_tags: + - net + - bluetooth +vendor: microchip diff --git a/boards/microchip/pic64gx_curiosity_kit/pic64gx_curiosity_kit_pic64gx1000_u54_defconfig b/boards/microchip/pic64gx_curiosity_kit/pic64gx_curiosity_kit_pic64gx1000_u54_defconfig new file mode 100644 index 000000000000..186867521425 --- /dev/null +++ b/boards/microchip/pic64gx_curiosity_kit/pic64gx_curiosity_kit_pic64gx1000_u54_defconfig @@ -0,0 +1,13 @@ +# Copyright (c) 2025 Microchip Technology Inc +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_BASE64=y +CONFIG_INCLUDE_RESET_VECTOR=y +CONFIG_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_UART_CONSOLE=y +CONFIG_XIP=n +CONFIG_INIT_STACKS=y +CONFIG_SYS_CLOCK_TICKS_PER_SEC=1000 +# GPIO driver options +CONFIG_GPIO=y diff --git a/boards/microchip/pic64gx_curiosity_kit/pic64gx_curiosity_kit_pic64gx1000_u54_smp.dts b/boards/microchip/pic64gx_curiosity_kit/pic64gx_curiosity_kit_pic64gx1000_u54_smp.dts new file mode 100644 index 000000000000..4a1b709c2253 --- /dev/null +++ b/boards/microchip/pic64gx_curiosity_kit/pic64gx_curiosity_kit_pic64gx1000_u54_smp.dts @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2025 Microchip Technology Inc + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include "pic64gx_curiosity_kit_pic64gx1000_u54.dts" + +/ { + compatible = "microchip,pic64gx-curiosity-kit", "microchip,pic64gx"; + + chosen { + zephyr,console = &mmuart1; + zephyr,shell-uart = &mmuart1; + zephyr,sram = &dram; + }; +}; + +&mmuart1 { + status = "okay"; + current-speed = <115200>; + clock-frequency = <150000000>; +}; diff --git a/boards/microchip/pic64gx_curiosity_kit/pic64gx_curiosity_kit_pic64gx1000_u54_smp.yaml b/boards/microchip/pic64gx_curiosity_kit/pic64gx_curiosity_kit_pic64gx1000_u54_smp.yaml new file mode 100644 index 000000000000..48d2e3e30e82 --- /dev/null +++ b/boards/microchip/pic64gx_curiosity_kit/pic64gx_curiosity_kit_pic64gx1000_u54_smp.yaml @@ -0,0 +1,12 @@ +identifier: pic64gx_curiosity_kit/pic64gx1000/u54/smp +name: Microchip PIC64GX Curiosity kit +type: mcu +arch: riscv +toolchain: + - zephyr +ram: 1024 +testing: + ignore_tags: + - net + - bluetooth +vendor: microchip diff --git a/boards/microchip/pic64gx_curiosity_kit/pic64gx_curiosity_kit_pic64gx1000_u54_smp_defconfig b/boards/microchip/pic64gx_curiosity_kit/pic64gx_curiosity_kit_pic64gx1000_u54_smp_defconfig new file mode 100644 index 000000000000..7b885a673457 --- /dev/null +++ b/boards/microchip/pic64gx_curiosity_kit/pic64gx_curiosity_kit_pic64gx1000_u54_smp_defconfig @@ -0,0 +1,14 @@ +# Copyright (c) 2025 Microchip Technology Inc +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_BASE64=y +CONFIG_INCLUDE_RESET_VECTOR=y +CONFIG_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_UART_CONSOLE=y +CONFIG_XIP=n +CONFIG_INIT_STACKS=y +CONFIG_SYS_CLOCK_TICKS_PER_SEC=1000 +# GPIO driver options +CONFIG_GPIO=y +CONFIG_SMP=y diff --git a/boards/microchip/pic64gx_curiosity_kit/support/embedded_flashpro5.cfg b/boards/microchip/pic64gx_curiosity_kit/support/embedded_flashpro5.cfg new file mode 100644 index 000000000000..9de3a16273b3 --- /dev/null +++ b/boards/microchip/pic64gx_curiosity_kit/support/embedded_flashpro5.cfg @@ -0,0 +1,38 @@ +# SPDX-License-Identifier: Apache-2.0 + +# +# Embedded FlashPro5 custom configuration for PIC64GX Curiosity Kit +# + +adapter speed 6000 + +adapter driver ftdi + +ftdi vid_pid 0x1514 0x200a + +# That FTDI has 4 channels (channel 0 and 1 are MPSSE-capable, 2 and 3 are bitbang +ftdi channel 0 + +# Initial Layout - data[0..15] direction[0..15] +ftdi layout_init 0x0018 0xfdfb +# Signal Data Direction Notes +# AD0 TCK 0 1 (out) Port A TCK +# AD1 TDI 0 1 (out) Port A TDI +# AD2 TDO 0 0 (in) PORT A TDO +# AD3 TMS 1 1 (out) Port A TMS +# AD4 GPIOL0 1 1 (out) Port A TRST +# AD5 GPIOL1 0 1 (out) (unused) +# AD6 GPIOL2 0 1 (out) (unused) +# AD7 GPIOL3 0 1 (out) (unused) + +# BD0 TCK 0 1 (out) FTDI_UART_B_TXD +# BD1 TDI 0 0 (in) FTDI_UART_B_RXD +# BD2 TDO 0 1 (out) (unused) +# BD3 TMS 0 1 (out) (unused) +# BD4 GPIOL0 0 1 (out) (unused) +# BD5 GPIOL1 0 1 (out) (unused) +# BD6 GPIOL2 0 1 (out) (unused) +# BD7 GPIOL2 0 1 (out) (unused) + +# Signals definition +ftdi layout_signal nTRST -data 0x0010 -oe 0x0010 diff --git a/boards/microchip/pic64gx_curiosity_kit/support/openocd.cfg b/boards/microchip/pic64gx_curiosity_kit/support/openocd.cfg new file mode 100644 index 000000000000..7f371e83bf3a --- /dev/null +++ b/boards/microchip/pic64gx_curiosity_kit/support/openocd.cfg @@ -0,0 +1,73 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# Target: Pic64gx processor by Microchip Technologies +# +# https://www.microchip.com/en-us/products/microprocessors/64-bit-mpus/pic64gx +# + +adapter speed 6000 + +source [find embedded_flashpro5.cfg] + +if { [info exists CHIPNAME] } { + set _CHIPNAME $CHIPNAME +} else { + set _CHIPNAME pic64gx +} + +# Process COREID variable +if {![exists COREID]} { + set COREID -1 +} + +transport select jtag + +# PIC64GX hart id to name lookup table +array set hart_names { + 0 e51 + 1 u54_1 + 2 u54_2 + 3 u54_3 + 4 u54_4 +} + +# PIC64GX table +set pic64gx_tap_info { + PIC64GX1000 0x0f8531cf +} + +proc expected_ids {tap_list} { + set str "" + dict for {key value} $tap_list { + append str "-expected-id" " " $value " " + } + + return $str +} + +set irlen 8 +set expected_ids [expected_ids $pic64gx_tap_info] +eval jtag newtap $_CHIPNAME cpu -irlen $irlen $expected_ids -ignore-version + +if {$COREID == -1} { + # Single debug connection to all harts + set _TARGETNAME_0 $_CHIPNAME.$hart_names(0) + set _TARGETNAME_1 $_CHIPNAME.$hart_names(1) + set _TARGETNAME_2 $_CHIPNAME.$hart_names(2) + set _TARGETNAME_3 $_CHIPNAME.$hart_names(3) + set _TARGETNAME_4 $_CHIPNAME.$hart_names(4) + + target create $_TARGETNAME_0 riscv -chain-position $_CHIPNAME.cpu -coreid 0 -rtos hwthread + target create $_TARGETNAME_1 riscv -chain-position $_CHIPNAME.cpu -coreid 1 -rtos hwthread + target create $_TARGETNAME_2 riscv -chain-position $_CHIPNAME.cpu -coreid 2 -rtos hwthread + target create $_TARGETNAME_3 riscv -chain-position $_CHIPNAME.cpu -coreid 3 -rtos hwthread + target create $_TARGETNAME_4 riscv -chain-position $_CHIPNAME.cpu -coreid 4 -rtos hwthread + target smp $_TARGETNAME_1 $_TARGETNAME_2 $_TARGETNAME_3 $_TARGETNAME_4 +} else { + # Debug connection to a specific hart + set _TARGETNAME_0 $_CHIPNAME.$hart_names($COREID) + target create $_TARGETNAME_0 riscv -chain-position $_CHIPNAME.cpu -coreid $COREID +} + +# Only TRSTn supported +reset_config trst_only \ No newline at end of file From b60fbc2abca6d61f2d18126ed317086c1ffbe540 Mon Sep 17 00:00:00 2001 From: Pierre-Henry Moussay Date: Thu, 12 Jun 2025 00:29:34 +0100 Subject: [PATCH 2008/3659] MAINTAINERS.yml: Add pic64 SoC and pic64gx_curiosity_kit Add pic64 SoC and pic64gx_curiosity_kit to Microchip RISCV board and SoC Signed-off-by: Pierre-Henry Moussay --- MAINTAINERS.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index a2a345dbae11..cd19824ccc8d 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -3406,11 +3406,14 @@ Microchip RISC-V Platforms: collaborators: - kgugala - tgorochowik + - con-pax files: - boards/microchip/m2gl025_miv/ - boards/microchip/mpfs_icicle/ + - boards/microchip/pic64gx_curiosity_kit/ - dts/riscv/microchip/ - soc/microchip/miv/ + - soc/microchip/pic64/ labels: - "platform: Microchip RISC-V" From 577906b09b127bc8710dd9a50af29c1780294317 Mon Sep 17 00:00:00 2001 From: Hieu Nguyen Date: Thu, 11 Dec 2025 09:23:14 +0700 Subject: [PATCH 2009/3659] dts: renesas: Add PWM support for RZ SoCs Add GPT nodes for devicetree of - RZ/T2L - RZ/G2L, RZ/G2LC - RZ/V2H R8 Core, RZ/V2H M33 Core, RZ/V2N Update GPT nodes for devicetree of RZ/G3S Signed-off-by: Hieu Nguyen Signed-off-by: Tien Nguyen --- dts/arm/renesas/rz/rzg/r9a07g044.dtsi | 144 +++++++ dts/arm/renesas/rz/rzg/r9a08g045.dtsi | 16 +- dts/arm/renesas/rz/rzt/r9a07g074.dtsi | 446 +++++++++++++++++++++ dts/arm/renesas/rz/rzv/r9a07g054.dtsi | 16 +- dts/arm/renesas/rz/rzv/r9a09g056.dtsi | 264 ++++++++++++ dts/arm/renesas/rz/rzv/r9a09g057_cm33.dtsi | 264 ++++++++++++ dts/arm/renesas/rz/rzv/r9a09g057_cr8.dtsi | 296 ++++++++++++++ 7 files changed, 1430 insertions(+), 16 deletions(-) diff --git a/dts/arm/renesas/rz/rzg/r9a07g044.dtsi b/dts/arm/renesas/rz/rzg/r9a07g044.dtsi index a81fc9eac987..09c897341a32 100644 --- a/dts/arm/renesas/rz/rzg/r9a07g044.dtsi +++ b/dts/arm/renesas/rz/rzg/r9a07g044.dtsi @@ -538,6 +538,150 @@ interrupt-names = "eri", "bri", "rxi", "txi", "tei"; status = "disabled"; }; + + gpt32e0: gpt32e@40048000 { + compatible = "renesas,rz-gpt"; + reg = <0x40048000 0x100>; + channel = <0>; + interrupts = <218 1>, <219 1>, <220 1>, <221 1>, <222 1>, + <223 1>, <224 1>, <225 1>, <226 1>, <227 1>; + interrupt-names = "ccmpa", "ccmpb", "cmpc", "cmpd", "cmpe", + "cmpf", "adtrga", "adtrgb", "ovf", "unf"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt32e1: gpt32e@40048100 { + compatible = "renesas,rz-gpt"; + reg = <0x40048100 0x100>; + channel = <1>; + interrupts = <231 1>, <232 1>, <233 1>, <234 1>, <235 1>, + <236 1>, <237 1>, <238 1>, <239 1>, <240 1>; + interrupt-names = "ccmpa", "ccmpb", "cmpc", "cmpd", "cmpe", + "cmpf", "adtrga", "adtrgb", "ovf", "unf"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt32e2: gpt32e@40048200 { + compatible = "renesas,rz-gpt"; + reg = <0x40048200 0x100>; + channel = <2>; + interrupts = <244 1>, <245 1>, <246 1>, <247 1>, <248 1>, + <249 1>, <250 1>, <251 1>, <252 1>, <253 1>; + interrupt-names = "ccmpa", "ccmpb", "cmpc", "cmpd", "cmpe", + "cmpf", "adtrga", "adtrgb", "ovf", "unf"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt32e3: gpt32e@40048300 { + compatible = "renesas,rz-gpt"; + reg = <0x40048300 0x100>; + channel = <3>; + interrupts = <257 1>, <258 1>, <259 1>, <260 1>, <261 1>, + <262 1>, <263 1>, <264 1>, <265 1>, <266 1>; + interrupt-names = "ccmpa", "ccmpb", "cmpc", "cmpd", "cmpe", + "cmpf", "adtrga", "adtrgb", "ovf", "unf"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt32e4: gpt32e@40048400 { + compatible = "renesas,rz-gpt"; + reg = <0x40048400 0x100>; + channel = <4>; + interrupts = <270 1>, <271 1>, <272 1>, <273 1>, <274 1>, + <275 1>, <276 1>, <277 1>, <278 1>, <279 1>; + interrupt-names = "ccmpa", "ccmpb", "cmpc", "cmpd", "cmpe", + "cmpf", "adtrga", "adtrgb", "ovf", "unf"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt32e5: gpt32e@40048500 { + compatible = "renesas,rz-gpt"; + reg = <0x40048500 0x100>; + channel = <5>; + interrupts = <283 1>, <284 1>, <285 1>, <286 1>, <287 1>, + <288 1>, <289 1>, <290 1>, <291 1>, <292 1>; + interrupt-names = "ccmpa", "ccmpb", "cmpc", "cmpd", "cmpe", + "cmpf", "adtrga", "adtrgb", "ovf", "unf"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt32e6: gpt32e@40048600 { + compatible = "renesas,rz-gpt"; + reg = <0x40048600 0x100>; + channel = <6>; + interrupts = <296 1>, <297 1>, <298 1>, <299 1>, <300 1>, + <301 1>, <302 1>, <303 1>, <304 1>, <305 1>; + interrupt-names = "ccmpa", "ccmpb", "cmpc", "cmpd", "cmpe", + "cmpf", "adtrga", "adtrgb", "ovf", "unf"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt32e7: gpt32e@40048700 { + compatible = "renesas,rz-gpt"; + reg = <0x40048700 0x100>; + channel = <7>; + interrupts = <309 1>, <310 1>, <311 1>, <312 1>, <313 1>, + <314 1>, <315 1>, <316 1>, <317 1>, <318 1>; + interrupt-names = "ccmpa", "ccmpb", "cmpc", "cmpd", "cmpe", + "cmpf", "adtrga", "adtrgb", "ovf", "unf"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; }; }; diff --git a/dts/arm/renesas/rz/rzg/r9a08g045.dtsi b/dts/arm/renesas/rz/rzg/r9a08g045.dtsi index 8e1042799299..da303200dbb2 100644 --- a/dts/arm/renesas/rz/rzg/r9a08g045.dtsi +++ b/dts/arm/renesas/rz/rzg/r9a08g045.dtsi @@ -731,7 +731,7 @@ gpt32e0: gpt32e@50048000 { compatible = "renesas,rz-gpt"; - reg = <0x50048000 0xa4>; + reg = <0x50048000 0x100>; channel = <0>; interrupts = <128 1>, <129 1>, <130 1>, <131 1>, <132 1>, <133 1>, <134 1>, <135 1>, <136 1>, <137 1>; @@ -749,7 +749,7 @@ gpt32e1: gpt32e@50048100 { compatible = "renesas,rz-gpt"; - reg = <0x50048100 0xa4>; + reg = <0x50048100 0x100>; channel = <1>; interrupts = <141 1>, <142 1>, <143 1>, <144 1>, <145 1>, <146 1>, <147 1>, <148 1>, <149 1>, <150 1>; @@ -767,7 +767,7 @@ gpt32e2: gpt32e@50048200 { compatible = "renesas,rz-gpt"; - reg = <0x50048200 0xa4>; + reg = <0x50048200 0x100>; channel = <2>; interrupts = <154 1>, <155 1>, <156 1>, <157 1>, <158 1>, <159 1>, <160 1>, <161 1>, <162 1>, <163 1>; @@ -785,7 +785,7 @@ gpt32e3: gpt32e@50048300 { compatible = "renesas,rz-gpt"; - reg = <0x50048300 0xa4>; + reg = <0x50048300 0x100>; channel = <3>; interrupts = <167 1>, <168 1>, <169 1>, <170 1>, <171 1>, <172 1>, <173 1>, <174 1>, <175 1>, <176 1>; @@ -803,7 +803,7 @@ gpt32e4: gpt32e@50048400 { compatible = "renesas,rz-gpt"; - reg = <0x50048400 0xa4>; + reg = <0x50048400 0x100>; channel = <4>; interrupts = <180 1>, <181 1>, <182 1>, <183 1>, <184 1>, <185 1>, <186 1>, <187 1>, <188 1>, <189 1>; @@ -821,7 +821,7 @@ gpt32e5: gpt32e@50048500 { compatible = "renesas,rz-gpt"; - reg = <0x50048500 0xa4>; + reg = <0x50048500 0x100>; channel = <5>; interrupts = <193 1>, <194 1>, <195 1>, <196 1>, <197 1>, <198 1>, <199 1>, <200 1>, <201 1>, <202 1>; @@ -839,7 +839,7 @@ gpt32e6: gpt32e@50048600 { compatible = "renesas,rz-gpt"; - reg = <0x50048600 0xa4>; + reg = <0x50048600 0x100>; channel = <6>; interrupts = <206 1>, <207 1>, <208 1>, <209 1>, <210 1>, <211 1>, <212 1>, <213 1>, <214 1>, <215 1>; @@ -857,7 +857,7 @@ gpt32e7: gpt32e@50048700 { compatible = "renesas,rz-gpt"; - reg = <0x50048700 0xa4>; + reg = <0x50048700 0x100>; channel = <7>; interrupts = <219 1>, <220 1>, <221 1>, <222 1>, <223 1>, <224 1>, <225 1>, <226 1>, <227 1>, <228 1>; diff --git a/dts/arm/renesas/rz/rzt/r9a07g074.dtsi b/dts/arm/renesas/rz/rzt/r9a07g074.dtsi index 05e4e39657ed..795f4bc3b0da 100644 --- a/dts/arm/renesas/rz/rzt/r9a07g074.dtsi +++ b/dts/arm/renesas/rz/rzt/r9a07g074.dtsi @@ -589,5 +589,451 @@ status = "disabled"; }; }; + + gpt0: gpt0@90002000 { + compatible = "renesas,rz-gpt"; + reg = <0x90002000 0x100>; + channel = <0>; + interrupts = , + , + , + , + , + , + , + , + ; + interrupt-names = "ccmpa", "ccmpb", "cmpc", "cmpd", "cmpe", + "cmpf", "ovf", "udf", "dte"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt1: gpt1@90002100 { + compatible = "renesas,rz-gpt"; + reg = <0x90002100 0x100>; + channel = <1>; + interrupts = , + , + , + , + , + , + , + , + ; + interrupt-names = "ccmpa", "ccmpb", "cmpc", "cmpd", "cmpe", + "cmpf", "ovf", "udf", "dte"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt2: gpt2@90002200 { + compatible = "renesas,rz-gpt"; + reg = <0x90002200 0x100>; + channel = <2>; + interrupts = , + , + , + , + , + , + , + , + ; + interrupt-names = "ccmpa", "ccmpb", "cmpc", "cmpd", "cmpe", + "cmpf", "ovf", "udf", "dte"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt3: gpt3@90002300 { + compatible = "renesas,rz-gpt"; + reg = <0x90002300 0x100>; + channel = <3>; + interrupts = , + , + , + , + , + , + , + , + ; + interrupt-names = "ccmpa", "ccmpb", "cmpc", "cmpd", "cmpe", + "cmpf", "ovf", "udf", "dte"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt4: gpt4@90002400 { + compatible = "renesas,rz-gpt"; + reg = <0x90002400 0x100>; + channel = <4>; + interrupts = , + , + , + , + , + , + , + , + ; + interrupt-names = "ccmpa", "ccmpb", "cmpc", "cmpd", "cmpe", + "cmpf", "ovf", "udf", "dte"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt5: gpt5@90002500 { + compatible = "renesas,rz-gpt"; + reg = <0x90002500 0x100>; + channel = <5>; + interrupts = , + , + , + , + , + , + , + , + ; + interrupt-names = "ccmpa", "ccmpb", "cmpc", "cmpd", "cmpe", + "cmpf", "ovf", "udf", "dte"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt6: gpt6@90002600 { + compatible = "renesas,rz-gpt"; + reg = <0x90002600 0x100>; + channel = <6>; + interrupts = , + , + , + , + , + , + , + , + ; + interrupt-names = "ccmpa", "ccmpb", "cmpc", "cmpd", "cmpe", + "cmpf", "ovf", "udf", "dte"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt7: gpt7@80000000 { + compatible = "renesas,rz-gpt"; + reg = <0x80000000 0x100>; + channel = <7>; + interrupts = , + , + , + , + , + , + , + , + ; + interrupt-names = "ccmpa", "ccmpb", "cmpc", "cmpd", "cmpe", + "cmpf", "ovf", "udf", "dte"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt8: gpt8@80000100 { + compatible = "renesas,rz-gpt"; + reg = <0x80000100 0x100>; + channel = <8>; + interrupts = , + , + , + , + , + , + , + , + ; + interrupt-names = "ccmpa", "ccmpb", "cmpc", "cmpd", "cmpe", + "cmpf", "ovf", "udf", "dte"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt9: gpt9@80000200 { + compatible = "renesas,rz-gpt"; + reg = <0x80000200 0x100>; + channel = <9>; + interrupts = , + , + , + , + , + , + , + , + ; + interrupt-names = "ccmpa", "ccmpb", "cmpc", "cmpd", "cmpe", + "cmpf", "ovf", "udf", "dte"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt10: gpt10@80000300 { + compatible = "renesas,rz-gpt"; + reg = <0x80000300 0x100>; + channel = <10>; + interrupts = , + , + , + , + , + , + , + , + ; + interrupt-names = "ccmpa", "ccmpb", "cmpc", "cmpd", "cmpe", + "cmpf", "ovf", "udf", "dte"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt11: gpt11@80000400 { + compatible = "renesas,rz-gpt"; + reg = <0x80000400 0x100>; + channel = <11>; + interrupts = , + , + , + , + , + , + , + , + ; + interrupt-names = "ccmpa", "ccmpb", "cmpc", "cmpd", "cmpe", + "cmpf", "ovf", "udf", "dte"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt12: gpt12@80000500 { + compatible = "renesas,rz-gpt"; + reg = <0x80000500 0x100>; + channel = <12>; + interrupts = , + , + , + , + , + , + , + , + ; + interrupt-names = "ccmpa", "ccmpb", "cmpc", "cmpd", "cmpe", + "cmpf", "ovf", "udf", "dte"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt13: gpt13@80000600 { + compatible = "renesas,rz-gpt"; + reg = <0x80000600 0x100>; + channel = <13>; + interrupts = , + , + , + , + , + , + , + , + ; + interrupt-names = "ccmpa", "ccmpb", "cmpc", "cmpd", "cmpe", + "cmpf", "ovf", "udf", "dte"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt14: gpt14@81000000 { + compatible = "renesas,rz-gpt"; + reg = <0x81000000 0x100>; + channel = <14>; + interrupts = , + , + , + , + , + , + , + ; + interrupt-names = "ccmpa", "ccmpb", "cmpc", "cmpd", "cmpe", + "cmpf", "ovf", "udf"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt15: gpt15@81000100 { + compatible = "renesas,rz-gpt"; + reg = <0x81000100 0x100>; + channel = <15>; + interrupts = , + , + , + , + , + , + , + ; + interrupt-names = "ccmpa", "ccmpb", "cmpc", "cmpd", "cmpe", + "cmpf", "ovf", "udf"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt16: gpt16@81000200 { + compatible = "renesas,rz-gpt"; + reg = <0x81000200 0x100>; + channel = <16>; + interrupts = , + , + , + , + , + , + , + ; + interrupt-names = "ccmpa", "ccmpb", "cmpc", "cmpd", "cmpe", + "cmpf", "ovf", "udf"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt17: gpt17@81000300 { + compatible = "renesas,rz-gpt"; + reg = <0x81000300 0x100>; + channel = <17>; + interrupts = , + , + , + , + , + , + , + ; + interrupt-names = "ccmpa", "ccmpb", "cmpc", "cmpd", "cmpe", + "cmpf", "ovf", "udf"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; }; }; diff --git a/dts/arm/renesas/rz/rzv/r9a07g054.dtsi b/dts/arm/renesas/rz/rzv/r9a07g054.dtsi index a3d3fb86bcaf..28924790ac50 100644 --- a/dts/arm/renesas/rz/rzv/r9a07g054.dtsi +++ b/dts/arm/renesas/rz/rzv/r9a07g054.dtsi @@ -729,7 +729,7 @@ gpt32e0: gpt32e@40048000 { compatible = "renesas,rz-gpt"; - reg = <0x40048000 0xa4>; + reg = <0x40048000 0x100>; channel = <0>; interrupts = <218 1>, <219 1>, <220 1>, <221 1>, <222 1>, <223 1>, <224 1>, <225 1>, <226 1>, <227 1>; @@ -747,7 +747,7 @@ gpt32e1: gpt32e@40048100 { compatible = "renesas,rz-gpt"; - reg = <0x40048100 0xa4>; + reg = <0x40048100 0x100>; channel = <1>; interrupts = <231 1>, <232 1>, <233 1>, <234 1>, <235 1>, <236 1>, <237 1>, <238 1>, <239 1>, <240 1>; @@ -765,7 +765,7 @@ gpt32e2: gpt32e@40048200 { compatible = "renesas,rz-gpt"; - reg = <0x40048200 0xa4>; + reg = <0x40048200 0x100>; channel = <2>; interrupts = <244 1>, <245 1>, <246 1>, <247 1>, <248 1>, <249 1>, <250 1>, <251 1>, <252 1>, <253 1>; @@ -783,7 +783,7 @@ gpt32e3: gpt32e@40048300 { compatible = "renesas,rz-gpt"; - reg = <0x40048300 0xa4>; + reg = <0x40048300 0x100>; channel = <3>; interrupts = <257 1>, <258 1>, <259 1>, <260 1>, <261 1>, <262 1>, <263 1>, <264 1>, <265 1>, <266 1>; @@ -801,7 +801,7 @@ gpt32e4: gpt32e@40048400 { compatible = "renesas,rz-gpt"; - reg = <0x40048400 0xa4>; + reg = <0x40048400 0x100>; channel = <4>; interrupts = <270 1>, <271 1>, <272 1>, <273 1>, <274 1>, <275 1>, <276 1>, <277 1>, <278 1>, <279 1>; @@ -819,7 +819,7 @@ gpt32e5: gpt32e@40048500 { compatible = "renesas,rz-gpt"; - reg = <0x40048500 0xa4>; + reg = <0x40048500 0x100>; channel = <5>; interrupts = <283 1>, <284 1>, <285 1>, <286 1>, <287 1>, <288 1>, <289 1>, <290 1>, <291 1>, <292 1>; @@ -837,7 +837,7 @@ gpt32e6: gpt32e@40048600 { compatible = "renesas,rz-gpt"; - reg = <0x40048600 0xa4>; + reg = <0x40048600 0x100>; channel = <6>; interrupts = <296 1>, <297 1>, <298 1>, <299 1>, <300 1>, <301 1>, <302 1>, <303 1>, <304 1>, <305 1>; @@ -855,7 +855,7 @@ gpt32e7: gpt32e@40048700 { compatible = "renesas,rz-gpt"; - reg = <0x40048700 0xa4>; + reg = <0x40048700 0x100>; channel = <7>; interrupts = <309 1>, <310 1>, <311 1>, <312 1>, <313 1>, <314 1>, <315 1>, <316 1>, <317 1>, <318 1>; diff --git a/dts/arm/renesas/rz/rzv/r9a09g056.dtsi b/dts/arm/renesas/rz/rzv/r9a09g056.dtsi index b7ccddee2759..db65e3752dde 100644 --- a/dts/arm/renesas/rz/rzv/r9a09g056.dtsi +++ b/dts/arm/renesas/rz/rzv/r9a09g056.dtsi @@ -161,6 +161,270 @@ }; }; + gpt0: gpt@43010000 { + compatible = "renesas,rz-gpt"; + reg = <0x43010000 0x100>; + channel = <0>; + interrupts = <406 1>, <407 1>, <408 1>; + interrupt-names = "ccmpa", "ccmpb", "ovf"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt1: gpt@43010100 { + compatible = "renesas,rz-gpt"; + reg = <0x43010100 0x100>; + channel = <1>; + interrupts = <409 1>, <410 1>, <411 1>; + interrupt-names = "ccmpa", "ccmpb", "ovf"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt2: gpt@43010200 { + compatible = "renesas,rz-gpt"; + reg = <0x43010200 0x100>; + channel = <2>; + interrupts = <412 1>, <413 1>, <414 1>; + interrupt-names = "ccmpa", "ccmpb", "ovf"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt3: gpt@43010300 { + compatible = "renesas,rz-gpt"; + reg = <0x43010300 0x100>; + channel = <3>; + interrupts = <415 1>, <416 1>, <417 1>; + interrupt-names = "ccmpa", "ccmpb", "ovf"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt4: gpt@43010400 { + compatible = "renesas,rz-gpt"; + reg = <0x43010400 0x100>; + channel = <4>; + interrupts = <418 1>, <419 1>, <420 1>; + interrupt-names = "ccmpa", "ccmpb", "ovf"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt5: gpt@43010500 { + compatible = "renesas,rz-gpt"; + reg = <0x43010500 0x100>; + channel = <5>; + interrupts = <421 1>, <422 1>, <423 1>; + interrupt-names = "ccmpa", "ccmpb", "ovf"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt6: gpt@43010600 { + compatible = "renesas,rz-gpt"; + reg = <0x43010600 0x100>; + channel = <6>; + interrupts = <424 1>, <425 1>, <426 1>; + interrupt-names = "ccmpa", "ccmpb", "ovf"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt7: gpt@43010700 { + compatible = "renesas,rz-gpt"; + reg = <0x43010700 0x100>; + channel = <7>; + interrupts = <427 1>, <428 1>, <429 1>; + interrupt-names = "ccmpa", "ccmpb", "ovf"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt8: gpt@43020000 { + compatible = "renesas,rz-gpt"; + reg = <0x43020000 0x100>; + channel = <8>; + interrupts = <430 1>, <431 1>, <432 1>; + interrupt-names = "ccmpa", "ccmpb", "ovf"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt9: gpt@43020100 { + compatible = "renesas,rz-gpt"; + reg = <0x43020100 0x100>; + channel = <9>; + interrupts = <433 1>, <434 1>, <435 1>; + interrupt-names = "ccmpa", "ccmpb", "ovf"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt10: gpt@43020200 { + compatible = "renesas,rz-gpt"; + reg = <0x43020200 0x100>; + channel = <10>; + interrupts = <436 1>, <437 1>, <438 1>; + interrupt-names = "ccmpa", "ccmpb", "ovf"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt11: gpt@43020300 { + compatible = "renesas,rz-gpt"; + reg = <0x43020300 0x100>; + channel = <11>; + interrupts = <439 1>, <440 1>, <441 1>; + interrupt-names = "ccmpa", "ccmpb", "ovf"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt12: gpt@43020400 { + compatible = "renesas,rz-gpt"; + reg = <0x43020400 0x100>; + channel = <12>; + interrupts = <442 1>, <443 1>, <444 1>; + interrupt-names = "ccmpa", "ccmpb", "ovf"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt13: gpt@43020500 { + compatible = "renesas,rz-gpt"; + reg = <0x43020500 0x100>; + channel = <13>; + interrupts = <445 1>, <446 1>, <447 1>; + interrupt-names = "ccmpa", "ccmpb", "ovf"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt14: gpt@43020600 { + compatible = "renesas,rz-gpt"; + reg = <0x43020600 0x100>; + channel = <14>; + interrupts = <448 1>, <449 1>, <450 1>; + interrupt-names = "ccmpa", "ccmpb", "ovf"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt15: gpt@43020700 { + compatible = "renesas,rz-gpt"; + reg = <0x43020700 0x100>; + channel = <15>; + interrupts = <451 1>, <452 1>, <453 1>; + interrupt-names = "ccmpa", "ccmpb", "ovf"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + intc: intc@40400000 { + compatible = "renesas,rz-intc"; + reg = <0x40400000 DT_SIZE_K(64)>; + #address-cells = <1>; + #size-cells = <0>; + interrupt-parent = <&nvic>; + }; + sci0: sci0@42800c00 { compatible = "renesas,rz-sci-b"; reg = <0x42800c00 0x400>; diff --git a/dts/arm/renesas/rz/rzv/r9a09g057_cm33.dtsi b/dts/arm/renesas/rz/rzv/r9a09g057_cm33.dtsi index 2209abd57467..f5b27ae4593a 100644 --- a/dts/arm/renesas/rz/rzv/r9a09g057_cm33.dtsi +++ b/dts/arm/renesas/rz/rzv/r9a09g057_cm33.dtsi @@ -161,6 +161,270 @@ }; }; + gpt0: gpt@43010000 { + compatible = "renesas,rz-gpt"; + reg = <0x43010000 0x100>; + channel = <0>; + interrupts = <404 1>, <405 1>, <406 1>; + interrupt-names = "ccmpa", "ccmpb", "ovf"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt1: gpt@43010100 { + compatible = "renesas,rz-gpt"; + reg = <0x43010100 0x100>; + channel = <1>; + interrupts = <407 1>, <408 1>, <409 1>; + interrupt-names = "ccmpa", "ccmpb", "ovf"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt2: gpt@43010200 { + compatible = "renesas,rz-gpt"; + reg = <0x43010200 0x100>; + channel = <2>; + interrupts = <410 1>, <411 1>, <412 1>; + interrupt-names = "ccmpa", "ccmpb", "ovf"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt3: gpt@43010300 { + compatible = "renesas,rz-gpt"; + reg = <0x43010300 0x100>; + channel = <3>; + interrupts = <413 1>, <414 1>, <415 1>; + interrupt-names = "ccmpa", "ccmpb", "ovf"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt4: gpt@43010400 { + compatible = "renesas,rz-gpt"; + reg = <0x43010400 0x100>; + channel = <4>; + interrupts = <416 1>, <417 1>, <418 1>; + interrupt-names = "ccmpa", "ccmpb", "ovf"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt5: gpt@43010500 { + compatible = "renesas,rz-gpt"; + reg = <0x43010500 0x100>; + channel = <5>; + interrupts = <419 1>, <420 1>, <421 1>; + interrupt-names = "ccmpa", "ccmpb", "ovf"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt6: gpt@43010600 { + compatible = "renesas,rz-gpt"; + reg = <0x43010600 0x100>; + channel = <6>; + interrupts = <422 1>, <423 1>, <424 1>; + interrupt-names = "ccmpa", "ccmpb", "ovf"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt7: gpt@43010700 { + compatible = "renesas,rz-gpt"; + reg = <0x43010700 0x100>; + channel = <7>; + interrupts = <425 1>, <426 1>, <427 1>; + interrupt-names = "ccmpa", "ccmpb", "ovf"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt8: gpt@43020000 { + compatible = "renesas,rz-gpt"; + reg = <0x43020000 0x100>; + channel = <8>; + interrupts = <428 1>, <429 1>, <430 1>; + interrupt-names = "ccmpa", "ccmpb", "ovf"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt9: gpt@43020100 { + compatible = "renesas,rz-gpt"; + reg = <0x43020100 0x100>; + channel = <9>; + interrupts = <431 1>, <432 1>, <433 1>; + interrupt-names = "ccmpa", "ccmpb", "ovf"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt10: gpt@43020200 { + compatible = "renesas,rz-gpt"; + reg = <0x43020200 0x100>; + channel = <10>; + interrupts = <434 1>, <435 1>, <436 1>; + interrupt-names = "ccmpa", "ccmpb", "ovf"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt11: gpt@43020300 { + compatible = "renesas,rz-gpt"; + reg = <0x43020300 0x100>; + channel = <11>; + interrupts = <437 1>, <438 1>, <439 1>; + interrupt-names = "ccmpa", "ccmpb", "ovf"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt12: gpt@43020400 { + compatible = "renesas,rz-gpt"; + reg = <0x43020400 0x100>; + channel = <12>; + interrupts = <440 1>, <441 1>, <442 1>; + interrupt-names = "ccmpa", "ccmpb", "ovf"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt13: gpt@43020500 { + compatible = "renesas,rz-gpt"; + reg = <0x43020500 0x100>; + channel = <13>; + interrupts = <443 1>, <444 1>, <445 1>; + interrupt-names = "ccmpa", "ccmpb", "ovf"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt14: gpt@43020600 { + compatible = "renesas,rz-gpt"; + reg = <0x43020600 0x100>; + channel = <14>; + interrupts = <446 1>, <447 1>, <448 1>; + interrupt-names = "ccmpa", "ccmpb", "ovf"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt15: gpt@43020700 { + compatible = "renesas,rz-gpt"; + reg = <0x43020700 0x100>; + channel = <15>; + interrupts = <449 1>, <450 1>, <451 1>; + interrupt-names = "ccmpa", "ccmpb", "ovf"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + intc: intc@40400000 { + compatible = "renesas,rz-intc"; + reg = <0x40400000 DT_SIZE_K(64)>; + #address-cells = <1>; + #size-cells = <0>; + interrupt-parent = <&nvic>; + }; + sci0: sci0@42800c00 { compatible = "renesas,rz-sci-b"; reg = <0x42800c00 0x400>; diff --git a/dts/arm/renesas/rz/rzv/r9a09g057_cr8.dtsi b/dts/arm/renesas/rz/rzv/r9a09g057_cr8.dtsi index 607d82f05001..f8b034787feb 100644 --- a/dts/arm/renesas/rz/rzv/r9a09g057_cr8.dtsi +++ b/dts/arm/renesas/rz/rzv/r9a09g057_cr8.dtsi @@ -224,6 +224,302 @@ }; }; + gpt0: gpt@13010000 { + compatible = "renesas,rz-gpt"; + reg = <0x13010000 0x100>; + channel = <0>; + interrupts = , + , + ; + interrupt-names = "ccmpa", "ccmpb", "ovf"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt1: gpt@13010100 { + compatible = "renesas,rz-gpt"; + reg = <0x13010100 0x100>; + channel = <1>; + interrupts = , + , + ; + interrupt-names = "ccmpa", "ccmpb", "ovf"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt2: gpt@13010200 { + compatible = "renesas,rz-gpt"; + reg = <0x13010200 0x100>; + channel = <2>; + interrupts = , + , + ; + interrupt-names = "ccmpa", "ccmpb", "ovf"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt3: gpt@13010300 { + compatible = "renesas,rz-gpt"; + reg = <0x13010300 0x100>; + channel = <3>; + interrupts = , + , + ; + interrupt-names = "ccmpa", "ccmpb", "ovf"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt4: gpt@13010400 { + compatible = "renesas,rz-gpt"; + reg = <0x13010400 0x100>; + channel = <4>; + interrupts = , + , + ; + interrupt-names = "ccmpa", "ccmpb", "ovf"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt5: gpt@13010500 { + compatible = "renesas,rz-gpt"; + reg = <0x13010500 0x100>; + channel = <5>; + interrupts = , + , + ; + interrupt-names = "ccmpa", "ccmpb", "ovf"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt6: gpt@13010600 { + compatible = "renesas,rz-gpt"; + reg = <0x13010600 0x100>; + channel = <6>; + interrupts = , + , + ; + interrupt-names = "ccmpa", "ccmpb", "ovf"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt7: gpt@13010700 { + compatible = "renesas,rz-gpt"; + reg = <0x13010700 0x100>; + channel = <7>; + interrupts = , + , + ; + interrupt-names = "ccmpa", "ccmpb", "ovf"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt8: gpt@13020000 { + compatible = "renesas,rz-gpt"; + reg = <0x13020000 0x100>; + channel = <8>; + interrupts = , + , + ; + interrupt-names = "ccmpa", "ccmpb", "ovf"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt9: gpt@13020100 { + compatible = "renesas,rz-gpt"; + reg = <0x13020100 0x100>; + channel = <9>; + interrupts = , + , + ; + interrupt-names = "ccmpa", "ccmpb", "ovf"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt10: gpt@13020200 { + compatible = "renesas,rz-gpt"; + reg = <0x13020200 0x100>; + channel = <10>; + interrupts = , + , + ; + interrupt-names = "ccmpa", "ccmpb", "ovf"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt11: gpt@13020300 { + compatible = "renesas,rz-gpt"; + reg = <0x13020300 0x100>; + channel = <11>; + interrupts = , + , + ; + interrupt-names = "ccmpa", "ccmpb", "ovf"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt12: gpt@13020400 { + compatible = "renesas,rz-gpt"; + reg = <0x13020400 0x100>; + channel = <12>; + interrupts = , + , + ; + interrupt-names = "ccmpa", "ccmpb", "ovf"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt13: gpt@13020500 { + compatible = "renesas,rz-gpt"; + reg = <0x13020500 0x100>; + channel = <13>; + interrupts = , + , + ; + interrupt-names = "ccmpa", "ccmpb", "ovf"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt14: gpt@13020600 { + compatible = "renesas,rz-gpt"; + reg = <0x13020600 0x100>; + channel = <14>; + interrupts = , + , + ; + interrupt-names = "ccmpa", "ccmpb", "ovf"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + gpt15: gpt@13020700 { + compatible = "renesas,rz-gpt"; + reg = <0x13020700 0x100>; + channel = <15>; + interrupts = , + , + ; + interrupt-names = "ccmpa", "ccmpb", "ovf"; + prescaler = <1>; + status = "disabled"; + + pwm { + compatible = "renesas,rz-gpt-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + intc: intc@10400000 { + compatible = "renesas,rz-intc"; + reg = <0x10400000 DT_SIZE_K(64)>; + #address-cells = <1>; + #size-cells = <0>; + interrupt-parent = <&gic>; + }; + sci0: sci0@12800c00 { compatible = "renesas,rz-sci-b"; reg = <0x12800c00 0x400>; From 4890a26f1c2d1d9bfd4a1a79b5953302bcc6fb90 Mon Sep 17 00:00:00 2001 From: Hieu Nguyen Date: Thu, 11 Dec 2025 09:39:14 +0700 Subject: [PATCH 2010/3659] drivers: pwm: Update driver for RZ devices Implement interrupt settings to expand the driver to RZ/V2H, V2N SoCs Signed-off-by: Hieu Nguyen Signed-off-by: Tien Nguyen --- drivers/pwm/pwm_renesas_rz_gpt.c | 48 ++++++++++++++++++++++++++ dts/bindings/timer/renesas,rz-gpt.yaml | 7 ++-- 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/drivers/pwm/pwm_renesas_rz_gpt.c b/drivers/pwm/pwm_renesas_rz_gpt.c index 0e603d609b27..435940a75062 100644 --- a/drivers/pwm/pwm_renesas_rz_gpt.c +++ b/drivers/pwm/pwm_renesas_rz_gpt.c @@ -324,6 +324,11 @@ static int pwm_rz_gpt_configure_capture(const struct device *dev, uint32_t chann } else if (channel == RZ_PWM_GPT_IO_B) { fsp_cfg_extend->stop_source = fsp_cfg_extend->capture_b_source; } + + if (data->capture.capture_type_flag == PWM_CAPTURE_TYPE_BOTH) { + fsp_cfg_extend->stop_source = (gpt_source_t)(GPT_SOURCE_NONE); + } + fsp_cfg_extend->clear_source = fsp_cfg_extend->start_source; } @@ -606,6 +611,48 @@ static void pwm_rz_gpt_ovf_isr(const struct device *dev) gpt_counter_overflow_isr(); } +#if defined(CONFIG_SOC_SERIES_RZV2H) || defined(CONFIG_SOC_SERIES_RZV2N) +#define RZ_INTC_BASE DT_REG_ADDR(DT_NODELABEL(intc)) + +#ifdef CONFIG_CPU_CORTEX_M33 +#define RZ_INTM33SEL_ADDR_OFFSET 0x200 +#define RZ_INTC_INTSEL_BASE RZ_INTC_BASE + RZ_INTM33SEL_ADDR_OFFSET +#else /* CONFIG_CPU_CORTEX_R8 */ +#define RZ_INTR8SEL_ADDR_OFFSET 0x140 +#define RZ_INTC_INTSEL_BASE RZ_INTC_BASE + RZ_INTR8SEL_ADDR_OFFSET +#endif + +#define OFFSET(y) ((y) - 353 - COND_CODE_1(CONFIG_GIC, (GIC_SPI_INT_BASE), (0))) +#define REG_INTSEL_READ(y) sys_read32(RZ_INTC_INTSEL_BASE + (OFFSET(y) / 3) * 4) +#define REG_INTSEL_WRITE(y, v) sys_write32((v), RZ_INTC_INTSEL_BASE + (OFFSET(y) / 3) * 4) +#define REG_INTSEL_SPIk_SEL_MASK(y) (BIT_MASK(10) << ((OFFSET(y) % 3) * 10)) + +/** + * @brief Connect an @p irq number with an @p event + */ +static void intc_connect_irq_event(IRQn_Type irq, IRQSELn_Type event) +{ + uint32_t reg_val = REG_INTSEL_READ(irq); + + reg_val &= ~REG_INTSEL_SPIk_SEL_MASK(irq); + reg_val |= FIELD_PREP(REG_INTSEL_SPIk_SEL_MASK(irq), event); + REG_INTSEL_WRITE(irq, reg_val); +} + +#define PWM_RZ_CONNECT_IRQ_SELECT(inst) \ + do { \ + intc_connect_irq_event(DT_IRQ_BY_NAME(GPT(inst), ccmpa, irq), \ + CONCAT(GPT, DT_PROP(GPT(inst), channel), _CCMPA_IRQSELn)); \ + intc_connect_irq_event(DT_IRQ_BY_NAME(GPT(inst), ccmpb, irq), \ + CONCAT(GPT, DT_PROP(GPT(inst), channel), _CCMPB_IRQSELn)); \ + intc_connect_irq_event(DT_IRQ_BY_NAME(GPT(inst), ovf, irq), \ + CONCAT(GPT, DT_PROP(GPT(inst), channel), _OVF_IRQSELn)); \ + } while (0) + +#else +#define PWM_RZ_CONNECT_IRQ_SELECT(inst) +#endif /* CONFIG_SOC_SERIES_RZV2H || CONFIG_SOC_SERIES_RZV2N */ + #ifdef CONFIG_CPU_CORTEX_M #define GPT_GET_IRQ_FLAGS(idx, irq_name) 0 #else /* Cortex-A/R */ @@ -614,6 +661,7 @@ static void pwm_rz_gpt_ovf_isr(const struct device *dev) #define PWM_RZ_IRQ_CONFIG_INIT(inst) \ do { \ + PWM_RZ_CONNECT_IRQ_SELECT(inst); \ IRQ_CONNECT(DT_IRQ_BY_NAME(GPT(inst), ccmpa, irq), \ DT_IRQ_BY_NAME(GPT(inst), ccmpa, priority), pwm_rz_gpt_ccmpa_isr, \ DEVICE_DT_INST_GET(inst), GPT_GET_IRQ_FLAGS(inst, ccmpa)); \ diff --git a/dts/bindings/timer/renesas,rz-gpt.yaml b/dts/bindings/timer/renesas,rz-gpt.yaml index e70cda203615..64669ec93766 100644 --- a/dts/bindings/timer/renesas,rz-gpt.yaml +++ b/dts/bindings/timer/renesas,rz-gpt.yaml @@ -1,4 +1,4 @@ -# Copyright (c) 2024 Renesas Electronics Corporation +# Copyright (c) 2024-2025 Renesas Electronics Corporation # SPDX-License-Identifier: Apache-2.0 description: Renesas RZ GPT @@ -23,7 +23,10 @@ properties: - 256 - 512 - 1024 - description: Input clock prescaler. For RZ/G3S, only 1, 4, 16, 64, 256, 1024 are supported. + description: | + Input clock prescaler: + - For RZ/G3S, RZ/G2, and RZ/V2L, only prescalers 1, 4, 16, 64, 256, and 1024 are supported. + - For RZ/V2H, RZ/V2N, RZ/T2, and RZ/N2, prescalers 128 and 512 are prohibited. channel: type: int From 002a7a7cbdfdde26492dbc0e8ed4b3be8e67d669 Mon Sep 17 00:00:00 2001 From: Hieu Nguyen Date: Thu, 11 Dec 2025 09:42:11 +0700 Subject: [PATCH 2011/3659] boards: renesas: Add PWM support for RZ devices Add PWM support for: - RZ/T2L-RSK - RZ/G2L-SMARC, RZ/G2LC-SMARC - RZ/V2N-EVK, RZ/V2H-EVK Signed-off-by: Hieu Nguyen Signed-off-by: Tien Nguyen --- .../renesas/rzg2l_smarc/rzg2l_smarc-pinctrl.dtsi | 12 ++++++++++++ .../rzg2l_smarc_r9a07g044l23gbg_cm33.yaml | 1 + .../renesas/rzg2lc_smarc/rzg2lc_smarc-pinctrl.dtsi | 12 ++++++++++++ .../rzg2lc_smarc_r9a07g044c22gbg_cm33.yaml | 1 + boards/renesas/rzt2l_rsk/rzt2l_rsk-pinctrl.dtsi | 14 ++++++++++++++ boards/renesas/rzt2l_rsk/rzt2l_rsk.yaml | 1 + boards/renesas/rzv2h_evk/rzv2h_evk-pinctrl.dtsi | 14 ++++++++++++++ .../rzv2h_evk/rzv2h_evk_r9a09g057h44gbg_cm33.yaml | 1 + .../rzv2h_evk/rzv2h_evk_r9a09g057h44gbg_cr8_0.yaml | 1 + boards/renesas/rzv2n_evk/rzv2n_evk-pinctrl.dtsi | 14 ++++++++++++++ .../rzv2n_evk/rzv2n_evk_r9a09g056n48gbg_cm33.yaml | 1 + 11 files changed, 72 insertions(+) diff --git a/boards/renesas/rzg2l_smarc/rzg2l_smarc-pinctrl.dtsi b/boards/renesas/rzg2l_smarc/rzg2l_smarc-pinctrl.dtsi index 7990abe700e6..7c1899c43ac0 100644 --- a/boards/renesas/rzg2l_smarc/rzg2l_smarc-pinctrl.dtsi +++ b/boards/renesas/rzg2l_smarc/rzg2l_smarc-pinctrl.dtsi @@ -20,4 +20,16 @@ ; /* RXD */ }; }; + + /omit-if-no-ref/ gpt3_pins: gpt3 { + gpt3-pinmux { + pinmux = ; /* GTIOCB */ + }; + }; + + /omit-if-no-ref/ gpt6_pins: gpt6 { + gpt6-pinmux { + pinmux = ; /* GTIOCA */ + }; + }; }; diff --git a/boards/renesas/rzg2l_smarc/rzg2l_smarc_r9a07g044l23gbg_cm33.yaml b/boards/renesas/rzg2l_smarc/rzg2l_smarc_r9a07g044l23gbg_cm33.yaml index f2f11f6f5d8c..5f563d2b6102 100644 --- a/boards/renesas/rzg2l_smarc/rzg2l_smarc_r9a07g044l23gbg_cm33.yaml +++ b/boards/renesas/rzg2l_smarc/rzg2l_smarc_r9a07g044l23gbg_cm33.yaml @@ -8,3 +8,4 @@ toolchain: supported: - uart - gpio + - pwm diff --git a/boards/renesas/rzg2lc_smarc/rzg2lc_smarc-pinctrl.dtsi b/boards/renesas/rzg2lc_smarc/rzg2lc_smarc-pinctrl.dtsi index ecae377d2a40..654a749c30d8 100644 --- a/boards/renesas/rzg2lc_smarc/rzg2lc_smarc-pinctrl.dtsi +++ b/boards/renesas/rzg2lc_smarc/rzg2lc_smarc-pinctrl.dtsi @@ -20,4 +20,16 @@ ; /* RXD */ }; }; + + /omit-if-no-ref/ gpt6_pins: gpt6 { + gpt6-pinmux { + pinmux = ; /* GTIOCA */ + }; + }; + + /omit-if-no-ref/ gpt7_pins: gpt7 { + gpt7-pinmux { + pinmux = ; /* GTIOCB */ + }; + }; }; diff --git a/boards/renesas/rzg2lc_smarc/rzg2lc_smarc_r9a07g044c22gbg_cm33.yaml b/boards/renesas/rzg2lc_smarc/rzg2lc_smarc_r9a07g044c22gbg_cm33.yaml index 5d0aac9cdb14..cd6ea91be013 100644 --- a/boards/renesas/rzg2lc_smarc/rzg2lc_smarc_r9a07g044c22gbg_cm33.yaml +++ b/boards/renesas/rzg2lc_smarc/rzg2lc_smarc_r9a07g044c22gbg_cm33.yaml @@ -8,3 +8,4 @@ toolchain: supported: - uart - gpio + - pwm diff --git a/boards/renesas/rzt2l_rsk/rzt2l_rsk-pinctrl.dtsi b/boards/renesas/rzt2l_rsk/rzt2l_rsk-pinctrl.dtsi index 4f63c4a83678..da63daa0f7e9 100644 --- a/boards/renesas/rzt2l_rsk/rzt2l_rsk-pinctrl.dtsi +++ b/boards/renesas/rzt2l_rsk/rzt2l_rsk-pinctrl.dtsi @@ -20,4 +20,18 @@ input-enable; }; }; + + /omit-if-no-ref/ gpt5_pins: gpt5 { + gpt5-pinmux { + pinmux = , /* GTIOCA */ + ; /* GTIOCB */ + }; + }; + + /omit-if-no-ref/ gpt6_pins: gpt6 { + gpt6-pinmux { + pinmux = , /* GTIOCA */ + ; /* GTIOCB */ + }; + }; }; diff --git a/boards/renesas/rzt2l_rsk/rzt2l_rsk.yaml b/boards/renesas/rzt2l_rsk/rzt2l_rsk.yaml index 6bfd1397438c..cce771549160 100644 --- a/boards/renesas/rzt2l_rsk/rzt2l_rsk.yaml +++ b/boards/renesas/rzt2l_rsk/rzt2l_rsk.yaml @@ -10,4 +10,5 @@ toolchain: supported: - uart - gpio + - pwm vendor: renesas diff --git a/boards/renesas/rzv2h_evk/rzv2h_evk-pinctrl.dtsi b/boards/renesas/rzv2h_evk/rzv2h_evk-pinctrl.dtsi index cb87c2794f5d..48c697400307 100644 --- a/boards/renesas/rzv2h_evk/rzv2h_evk-pinctrl.dtsi +++ b/boards/renesas/rzv2h_evk/rzv2h_evk-pinctrl.dtsi @@ -14,4 +14,18 @@ drive-strength = <1>; }; }; + + /omit-if-no-ref/ gpt3_pins: gpt3 { + gpt3-pinmux { + pinmux = , /* GTIOCA */ + ; /* GTIOCB */ + }; + }; + + /omit-if-no-ref/ gpt5_pins: gpt5 { + gpt5-pinmux { + pinmux = , /* GTIOCA */ + ; /* GTIOCB */ + }; + }; }; diff --git a/boards/renesas/rzv2h_evk/rzv2h_evk_r9a09g057h44gbg_cm33.yaml b/boards/renesas/rzv2h_evk/rzv2h_evk_r9a09g057h44gbg_cm33.yaml index 9e45f21aa046..e23440de521c 100644 --- a/boards/renesas/rzv2h_evk/rzv2h_evk_r9a09g057h44gbg_cm33.yaml +++ b/boards/renesas/rzv2h_evk/rzv2h_evk_r9a09g057h44gbg_cm33.yaml @@ -8,4 +8,5 @@ toolchain: supported: - uart - gpio + - pwm vendor: renesas diff --git a/boards/renesas/rzv2h_evk/rzv2h_evk_r9a09g057h44gbg_cr8_0.yaml b/boards/renesas/rzv2h_evk/rzv2h_evk_r9a09g057h44gbg_cr8_0.yaml index 1195932fbc85..0fc67899d7c9 100644 --- a/boards/renesas/rzv2h_evk/rzv2h_evk_r9a09g057h44gbg_cr8_0.yaml +++ b/boards/renesas/rzv2h_evk/rzv2h_evk_r9a09g057h44gbg_cr8_0.yaml @@ -8,4 +8,5 @@ toolchain: supported: - uart - gpio + - pwm vendor: renesas diff --git a/boards/renesas/rzv2n_evk/rzv2n_evk-pinctrl.dtsi b/boards/renesas/rzv2n_evk/rzv2n_evk-pinctrl.dtsi index bbd5d1f77b7a..be72aa0d485c 100644 --- a/boards/renesas/rzv2n_evk/rzv2n_evk-pinctrl.dtsi +++ b/boards/renesas/rzv2n_evk/rzv2n_evk-pinctrl.dtsi @@ -13,4 +13,18 @@ ; /* RXD */ }; }; + + /omit-if-no-ref/ gpt3_pins: gpt3 { + gpt3-pinmux { + pinmux = , /* GTIOCA */ + ; /* GTIOCB */ + }; + }; + + /omit-if-no-ref/ gpt5_pins: gpt5 { + gpt5-pinmux { + pinmux = , /* GTIOCA */ + ; /* GTIOCB */ + }; + }; }; diff --git a/boards/renesas/rzv2n_evk/rzv2n_evk_r9a09g056n48gbg_cm33.yaml b/boards/renesas/rzv2n_evk/rzv2n_evk_r9a09g056n48gbg_cm33.yaml index 7bdedda75f7e..fbeb66b5a069 100644 --- a/boards/renesas/rzv2n_evk/rzv2n_evk_r9a09g056n48gbg_cm33.yaml +++ b/boards/renesas/rzv2n_evk/rzv2n_evk_r9a09g056n48gbg_cm33.yaml @@ -8,4 +8,5 @@ toolchain: supported: - uart - gpio + - pwm vendor: renesas From 33914a65dbbc90eccf68ba378540d6e28b49bf12 Mon Sep 17 00:00:00 2001 From: Hieu Nguyen Date: Thu, 11 Dec 2025 09:45:31 +0700 Subject: [PATCH 2012/3659] tests: drivers: pwm: Add support for RZ devices Add test support for PWM driver of: - RZ/T2L-RSK - RZ/G2L-SMARC, RZ/G2LC-SMARC - RZ/V2N-EVK, RZ/V2H-EVK Signed-off-by: Hieu Nguyen Signed-off-by: Tien Nguyen --- .../rzg2l_smarc_r9a07g044l23gbg_cm33.overlay | 19 ++++++++++ .../rzg2lc_smarc_r9a07g044c22gbg_cm33.overlay | 19 ++++++++++ .../pwm/pwm_api/boards/rzt2l_rsk.overlay | 21 +++++++++++ .../rzv2h_evk_r9a09g057h44gbg_cm33.overlay | 19 ++++++++++ .../rzv2h_evk_r9a09g057h44gbg_cr8_0.overlay | 19 ++++++++++ .../rzv2n_evk_r9a09g056n48gbg_cm33.overlay | 19 ++++++++++ .../rzg2l_smarc_r9a07g044l23gbg_cm33.overlay | 36 +++++++++++++++++++ .../rzg2lc_smarc_r9a07g044c22gbg_cm33.overlay | 36 +++++++++++++++++++ .../pwm/pwm_loopback/boards/rzt2l_rsk.overlay | 36 +++++++++++++++++++ .../rzv2h_evk_r9a09g057h44gbg_cm33.overlay | 36 +++++++++++++++++++ .../rzv2h_evk_r9a09g057h44gbg_cr8_0.overlay | 36 +++++++++++++++++++ .../rzv2n_evk_r9a09g056n48gbg_cm33.overlay | 36 +++++++++++++++++++ 12 files changed, 332 insertions(+) create mode 100644 tests/drivers/pwm/pwm_api/boards/rzg2l_smarc_r9a07g044l23gbg_cm33.overlay create mode 100644 tests/drivers/pwm/pwm_api/boards/rzg2lc_smarc_r9a07g044c22gbg_cm33.overlay create mode 100644 tests/drivers/pwm/pwm_api/boards/rzt2l_rsk.overlay create mode 100644 tests/drivers/pwm/pwm_api/boards/rzv2h_evk_r9a09g057h44gbg_cm33.overlay create mode 100644 tests/drivers/pwm/pwm_api/boards/rzv2h_evk_r9a09g057h44gbg_cr8_0.overlay create mode 100644 tests/drivers/pwm/pwm_api/boards/rzv2n_evk_r9a09g056n48gbg_cm33.overlay create mode 100644 tests/drivers/pwm/pwm_loopback/boards/rzg2l_smarc_r9a07g044l23gbg_cm33.overlay create mode 100644 tests/drivers/pwm/pwm_loopback/boards/rzg2lc_smarc_r9a07g044c22gbg_cm33.overlay create mode 100644 tests/drivers/pwm/pwm_loopback/boards/rzt2l_rsk.overlay create mode 100644 tests/drivers/pwm/pwm_loopback/boards/rzv2h_evk_r9a09g057h44gbg_cm33.overlay create mode 100644 tests/drivers/pwm/pwm_loopback/boards/rzv2h_evk_r9a09g057h44gbg_cr8_0.overlay create mode 100644 tests/drivers/pwm/pwm_loopback/boards/rzv2n_evk_r9a09g056n48gbg_cm33.overlay diff --git a/tests/drivers/pwm/pwm_api/boards/rzg2l_smarc_r9a07g044l23gbg_cm33.overlay b/tests/drivers/pwm/pwm_api/boards/rzg2l_smarc_r9a07g044l23gbg_cm33.overlay new file mode 100644 index 000000000000..6506a958b637 --- /dev/null +++ b/tests/drivers/pwm/pwm_api/boards/rzg2l_smarc_r9a07g044l23gbg_cm33.overlay @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + pwm-test = &pwm6; + }; +}; + +&gpt32e6 { + pwm6: pwm { + status = "okay"; + pinctrl-0 = <&gpt6_pins>; + pinctrl-names = "default"; + }; +}; diff --git a/tests/drivers/pwm/pwm_api/boards/rzg2lc_smarc_r9a07g044c22gbg_cm33.overlay b/tests/drivers/pwm/pwm_api/boards/rzg2lc_smarc_r9a07g044c22gbg_cm33.overlay new file mode 100644 index 000000000000..6506a958b637 --- /dev/null +++ b/tests/drivers/pwm/pwm_api/boards/rzg2lc_smarc_r9a07g044c22gbg_cm33.overlay @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + pwm-test = &pwm6; + }; +}; + +&gpt32e6 { + pwm6: pwm { + status = "okay"; + pinctrl-0 = <&gpt6_pins>; + pinctrl-names = "default"; + }; +}; diff --git a/tests/drivers/pwm/pwm_api/boards/rzt2l_rsk.overlay b/tests/drivers/pwm/pwm_api/boards/rzt2l_rsk.overlay new file mode 100644 index 000000000000..3ce5eb3365e4 --- /dev/null +++ b/tests/drivers/pwm/pwm_api/boards/rzt2l_rsk.overlay @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + pwm-test = &pwm5; + }; +}; + +&gpt5 { + status = "okay"; + + pwm5: pwm { + status = "okay"; + pinctrl-0 = <&gpt5_pins>; + pinctrl-names = "default"; + }; +}; diff --git a/tests/drivers/pwm/pwm_api/boards/rzv2h_evk_r9a09g057h44gbg_cm33.overlay b/tests/drivers/pwm/pwm_api/boards/rzv2h_evk_r9a09g057h44gbg_cm33.overlay new file mode 100644 index 000000000000..c75edca4c494 --- /dev/null +++ b/tests/drivers/pwm/pwm_api/boards/rzv2h_evk_r9a09g057h44gbg_cm33.overlay @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + pwm-test = &pwm3; + }; +}; + +&gpt3 { + pwm3: pwm { + status = "okay"; + pinctrl-0 = <&gpt3_pins>; + pinctrl-names = "default"; + }; +}; diff --git a/tests/drivers/pwm/pwm_api/boards/rzv2h_evk_r9a09g057h44gbg_cr8_0.overlay b/tests/drivers/pwm/pwm_api/boards/rzv2h_evk_r9a09g057h44gbg_cr8_0.overlay new file mode 100644 index 000000000000..c75edca4c494 --- /dev/null +++ b/tests/drivers/pwm/pwm_api/boards/rzv2h_evk_r9a09g057h44gbg_cr8_0.overlay @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + pwm-test = &pwm3; + }; +}; + +&gpt3 { + pwm3: pwm { + status = "okay"; + pinctrl-0 = <&gpt3_pins>; + pinctrl-names = "default"; + }; +}; diff --git a/tests/drivers/pwm/pwm_api/boards/rzv2n_evk_r9a09g056n48gbg_cm33.overlay b/tests/drivers/pwm/pwm_api/boards/rzv2n_evk_r9a09g056n48gbg_cm33.overlay new file mode 100644 index 000000000000..c75edca4c494 --- /dev/null +++ b/tests/drivers/pwm/pwm_api/boards/rzv2n_evk_r9a09g056n48gbg_cm33.overlay @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + pwm-test = &pwm3; + }; +}; + +&gpt3 { + pwm3: pwm { + status = "okay"; + pinctrl-0 = <&gpt3_pins>; + pinctrl-names = "default"; + }; +}; diff --git a/tests/drivers/pwm/pwm_loopback/boards/rzg2l_smarc_r9a07g044l23gbg_cm33.overlay b/tests/drivers/pwm/pwm_loopback/boards/rzg2l_smarc_r9a07g044l23gbg_cm33.overlay new file mode 100644 index 000000000000..33201e6365ef --- /dev/null +++ b/tests/drivers/pwm/pwm_loopback/boards/rzg2l_smarc_r9a07g044l23gbg_cm33.overlay @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + pwm_loopback_0 { + compatible = "test-pwm-loopback"; + pwms = <&pwm3 RZ_PWM_GPT_IO_B 0 PWM_POLARITY_NORMAL>, + <&pwm6 RZ_PWM_GPT_IO_A 0 PWM_POLARITY_NORMAL>; + }; +}; + +&gpt32e3 { + status = "okay"; + + pwm3: pwm { + status = "okay"; + pinctrl-0 = <&gpt3_pins>; + pinctrl-names = "default"; + }; +}; + +&gpt32e6 { + status = "okay"; + + pwm6: pwm { + status = "okay"; + pinctrl-0 = <&gpt6_pins>; + pinctrl-names = "default"; + }; +}; diff --git a/tests/drivers/pwm/pwm_loopback/boards/rzg2lc_smarc_r9a07g044c22gbg_cm33.overlay b/tests/drivers/pwm/pwm_loopback/boards/rzg2lc_smarc_r9a07g044c22gbg_cm33.overlay new file mode 100644 index 000000000000..2c5c272801bf --- /dev/null +++ b/tests/drivers/pwm/pwm_loopback/boards/rzg2lc_smarc_r9a07g044c22gbg_cm33.overlay @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + pwm_loopback_0 { + compatible = "test-pwm-loopback"; + pwms = <&pwm6 RZ_PWM_GPT_IO_A 0 PWM_POLARITY_NORMAL>, + <&pwm7 RZ_PWM_GPT_IO_B 0 PWM_POLARITY_NORMAL>; + }; +}; + +&gpt32e6 { + status = "okay"; + + pwm6: pwm { + status = "okay"; + pinctrl-0 = <&gpt6_pins>; + pinctrl-names = "default"; + }; +}; + +&gpt32e7 { + status = "okay"; + + pwm7: pwm { + status = "okay"; + pinctrl-0 = <&gpt7_pins>; + pinctrl-names = "default"; + }; +}; diff --git a/tests/drivers/pwm/pwm_loopback/boards/rzt2l_rsk.overlay b/tests/drivers/pwm/pwm_loopback/boards/rzt2l_rsk.overlay new file mode 100644 index 000000000000..c7bec64e0403 --- /dev/null +++ b/tests/drivers/pwm/pwm_loopback/boards/rzt2l_rsk.overlay @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + pwm_loopback_0 { + compatible = "test-pwm-loopback"; + pwms = <&pwm5 RZ_PWM_GPT_IO_A 0 PWM_POLARITY_NORMAL>, + <&pwm6 RZ_PWM_GPT_IO_A 0 PWM_POLARITY_NORMAL>; + }; +}; + +&gpt5 { + status = "okay"; + + pwm5: pwm { + status = "okay"; + pinctrl-0 = <&gpt5_pins>; + pinctrl-names = "default"; + }; +}; + +&gpt6 { + status = "okay"; + + pwm6: pwm { + status = "okay"; + pinctrl-0 = <&gpt6_pins>; + pinctrl-names = "default"; + }; +}; diff --git a/tests/drivers/pwm/pwm_loopback/boards/rzv2h_evk_r9a09g057h44gbg_cm33.overlay b/tests/drivers/pwm/pwm_loopback/boards/rzv2h_evk_r9a09g057h44gbg_cm33.overlay new file mode 100644 index 000000000000..e933a28be45d --- /dev/null +++ b/tests/drivers/pwm/pwm_loopback/boards/rzv2h_evk_r9a09g057h44gbg_cm33.overlay @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + pwm_loopback_0 { + compatible = "test-pwm-loopback"; + pwms = <&pwm3 RZ_PWM_GPT_IO_A 0 PWM_POLARITY_NORMAL>, + <&pwm5 RZ_PWM_GPT_IO_A 0 PWM_POLARITY_NORMAL>; + }; +}; + +&gpt3 { + status = "okay"; + + pwm3: pwm { + status = "okay"; + pinctrl-0 = <&gpt3_pins>; + pinctrl-names = "default"; + }; +}; + +&gpt5 { + status = "okay"; + + pwm5: pwm { + status = "okay"; + pinctrl-0 = <&gpt5_pins>; + pinctrl-names = "default"; + }; +}; diff --git a/tests/drivers/pwm/pwm_loopback/boards/rzv2h_evk_r9a09g057h44gbg_cr8_0.overlay b/tests/drivers/pwm/pwm_loopback/boards/rzv2h_evk_r9a09g057h44gbg_cr8_0.overlay new file mode 100644 index 000000000000..e933a28be45d --- /dev/null +++ b/tests/drivers/pwm/pwm_loopback/boards/rzv2h_evk_r9a09g057h44gbg_cr8_0.overlay @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + pwm_loopback_0 { + compatible = "test-pwm-loopback"; + pwms = <&pwm3 RZ_PWM_GPT_IO_A 0 PWM_POLARITY_NORMAL>, + <&pwm5 RZ_PWM_GPT_IO_A 0 PWM_POLARITY_NORMAL>; + }; +}; + +&gpt3 { + status = "okay"; + + pwm3: pwm { + status = "okay"; + pinctrl-0 = <&gpt3_pins>; + pinctrl-names = "default"; + }; +}; + +&gpt5 { + status = "okay"; + + pwm5: pwm { + status = "okay"; + pinctrl-0 = <&gpt5_pins>; + pinctrl-names = "default"; + }; +}; diff --git a/tests/drivers/pwm/pwm_loopback/boards/rzv2n_evk_r9a09g056n48gbg_cm33.overlay b/tests/drivers/pwm/pwm_loopback/boards/rzv2n_evk_r9a09g056n48gbg_cm33.overlay new file mode 100644 index 000000000000..e933a28be45d --- /dev/null +++ b/tests/drivers/pwm/pwm_loopback/boards/rzv2n_evk_r9a09g056n48gbg_cm33.overlay @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + pwm_loopback_0 { + compatible = "test-pwm-loopback"; + pwms = <&pwm3 RZ_PWM_GPT_IO_A 0 PWM_POLARITY_NORMAL>, + <&pwm5 RZ_PWM_GPT_IO_A 0 PWM_POLARITY_NORMAL>; + }; +}; + +&gpt3 { + status = "okay"; + + pwm3: pwm { + status = "okay"; + pinctrl-0 = <&gpt3_pins>; + pinctrl-names = "default"; + }; +}; + +&gpt5 { + status = "okay"; + + pwm5: pwm { + status = "okay"; + pinctrl-0 = <&gpt5_pins>; + pinctrl-names = "default"; + }; +}; From de2b8994ac38b33ce734c6f5a07425b3c9fca878 Mon Sep 17 00:00:00 2001 From: Yves Wang Date: Wed, 17 Dec 2025 16:43:53 +0800 Subject: [PATCH 2013/3659] tests: watchdog: format wdt_basic_api Format the file with clang-format Signed-off-by: Yves Wang --- .../watchdog/wdt_basic_api/src/test_wdt.c | 29 +++++++++---------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/tests/drivers/watchdog/wdt_basic_api/src/test_wdt.c b/tests/drivers/watchdog/wdt_basic_api/src/test_wdt.c index 0b6a74ffcc03..ae7b69817cde 100644 --- a/tests/drivers/watchdog/wdt_basic_api/src/test_wdt.c +++ b/tests/drivers/watchdog/wdt_basic_api/src/test_wdt.c @@ -70,8 +70,8 @@ #if DT_NODE_HAS_STATUS_OKAY(DT_ALIAS(watchdog0)) #define WDT_NODE DT_ALIAS(watchdog0) #elif DT_HAS_COMPAT_STATUS_OKAY(st_stm32_window_watchdog) -#define WDT_NODE DT_INST(0, st_stm32_window_watchdog) -#define TIMEOUTS 0 +#define WDT_NODE DT_INST(0, st_stm32_window_watchdog) +#define TIMEOUTS 0 #define WDT_TEST_MAX_WINDOW 200 #elif DT_HAS_COMPAT_STATUS_OKAY(st_stm32_watchdog) #define WDT_NODE DT_INST(0, st_stm32_watchdog) @@ -105,16 +105,16 @@ #define WDT_NODE DT_INST(0, nuvoton_numaker_wwdt) #define TIMEOUTS 1 #elif DT_HAS_COMPAT_STATUS_OKAY(andestech_atcwdt200) -#define WDT_NODE DT_INST(0, andestech_atcwdt200) -#define TIMEOUTS 0 +#define WDT_NODE DT_INST(0, andestech_atcwdt200) +#define TIMEOUTS 0 #define WDT_TEST_MAX_WINDOW 200U #endif #if DT_HAS_COMPAT_STATUS_OKAY(raspberrypi_pico_watchdog) #define WDT_TEST_MAX_WINDOW 8000U -#define TIMEOUTS 0 +#define TIMEOUTS 0 #endif #if DT_HAS_COMPAT_STATUS_OKAY(intel_tco_wdt) -#define TIMEOUTS 0 +#define TIMEOUTS 0 #define WDT_TEST_MAX_WINDOW 3000U #endif #if DT_HAS_COMPAT_STATUS_OKAY(nxp_wdog32) @@ -124,23 +124,22 @@ #define WDT_TEST_STATE_IDLE 0 #define WDT_TEST_STATE_CHECK_RESET 1 -#define WDT_TEST_CB0_TEST_VALUE 0x0CB0 -#define WDT_TEST_CB1_TEST_VALUE 0x0CB1 +#define WDT_TEST_CB0_TEST_VALUE 0x0CB0 +#define WDT_TEST_CB1_TEST_VALUE 0x0CB1 #ifndef WDT_TEST_MAX_WINDOW -#define WDT_TEST_MAX_WINDOW 2000U +#define WDT_TEST_MAX_WINDOW 2000U #endif #ifndef TIMEOUTS -#define TIMEOUTS 1 +#define TIMEOUTS 1 #endif #if !(defined(CONFIG_HAS_WDT_NO_CALLBACKS) && CONFIG_HAS_WDT_NO_CALLBACKS) -#define TEST_WDT_CALLBACK_1 (TIMEOUTS > 0) -#define TEST_WDT_CALLBACK_2 (TIMEOUTS > 1) +#define TEST_WDT_CALLBACK_1 (TIMEOUTS > 0) +#define TEST_WDT_CALLBACK_2 (TIMEOUTS > 1) #endif - static struct wdt_timeout_cfg m_cfg_wdt0; #if TEST_WDT_CALLBACK_2 static struct wdt_timeout_cfg m_cfg_wdt1; @@ -281,7 +280,6 @@ static int test_wdt_callback_1(void) TC_PRINT("CB1 not supported on platform\n"); m_testcase_index++; return TC_PASS; - } TC_PRINT("Watchdog install error\n"); return TC_FAIL; @@ -472,8 +470,7 @@ static int test_wdt_enable_wait_mode(void) ZTEST(wdt_basic_test_suite, test_wdt) { - if ((m_testcase_index != 1U) && (m_testcase_index != 2U) - && (m_testcase_index != 3U)) { + if ((m_testcase_index != 1U) && (m_testcase_index != 2U) && (m_testcase_index != 3U)) { zassert_true(test_wdt_no_callback() == TC_PASS); } if (m_testcase_index == 1U) { From 587e4aacaaeee8e9ee2c732719b6a2da3a74b456 Mon Sep 17 00:00:00 2001 From: Yves Wang Date: Wed, 17 Dec 2025 16:47:26 +0800 Subject: [PATCH 2014/3659] tests: watchdog: fixed incorrect skip statement - Remove ztest_test_skip in sub testcase because it will skip all following code in the testcase. - Print sub testcase name at the case begining. - Wrap bad window and wait mode test with macros. - For nxp,cop, need disable it when the testcase ends. Signed-off-by: Yves Wang --- .../wdt_basic_api/boards/frdm_mcxc444.conf | 4 -- .../wdt_basic_api/boards/frdm_mcxc444.overlay | 9 +++ .../watchdog/wdt_basic_api/src/test_wdt.c | 61 +++++++++++++------ 3 files changed, 51 insertions(+), 23 deletions(-) delete mode 100644 tests/drivers/watchdog/wdt_basic_api/boards/frdm_mcxc444.conf create mode 100644 tests/drivers/watchdog/wdt_basic_api/boards/frdm_mcxc444.overlay diff --git a/tests/drivers/watchdog/wdt_basic_api/boards/frdm_mcxc444.conf b/tests/drivers/watchdog/wdt_basic_api/boards/frdm_mcxc444.conf deleted file mode 100644 index 5d07ddf84678..000000000000 --- a/tests/drivers/watchdog/wdt_basic_api/boards/frdm_mcxc444.conf +++ /dev/null @@ -1,4 +0,0 @@ -# Copyright 2025 NXP -# SPDX-License-Identifier: Apache-2.0 - -CONFIG_WDT_DISABLE_AT_BOOT=y diff --git a/tests/drivers/watchdog/wdt_basic_api/boards/frdm_mcxc444.overlay b/tests/drivers/watchdog/wdt_basic_api/boards/frdm_mcxc444.overlay new file mode 100644 index 000000000000..ca3c4cd37c25 --- /dev/null +++ b/tests/drivers/watchdog/wdt_basic_api/boards/frdm_mcxc444.overlay @@ -0,0 +1,9 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&cop { + timeout-cycles = <8192>; +}; diff --git a/tests/drivers/watchdog/wdt_basic_api/src/test_wdt.c b/tests/drivers/watchdog/wdt_basic_api/src/test_wdt.c index ae7b69817cde..7526d908774c 100644 --- a/tests/drivers/watchdog/wdt_basic_api/src/test_wdt.c +++ b/tests/drivers/watchdog/wdt_basic_api/src/test_wdt.c @@ -120,6 +120,10 @@ #if DT_HAS_COMPAT_STATUS_OKAY(nxp_wdog32) #define WDT_TEST_MAX_WINDOW 1000U #endif +#if DT_HAS_COMPAT_STATUS_OKAY(nxp_cop) +#define WDT_TEST_BAD_MAX_WINDOW 0 +#define WDT_TEST_FINAL_DISABLE 1 +#endif #define WDT_TEST_STATE_IDLE 0 #define WDT_TEST_STATE_CHECK_RESET 1 @@ -140,6 +144,14 @@ #define TEST_WDT_CALLBACK_2 (TIMEOUTS > 1) #endif +#if CONFIG_PM +#define TEST_WDT_WAIT_MODE 1 +#endif + +#ifndef WDT_TEST_BAD_MAX_WINDOW +#define WDT_TEST_BAD_MAX_WINDOW 1 +#endif + static struct wdt_timeout_cfg m_cfg_wdt0; #if TEST_WDT_CALLBACK_2 static struct wdt_timeout_cfg m_cfg_wdt1; @@ -199,13 +211,13 @@ static int test_wdt_no_callback(void) int err; const struct device *const wdt = DEVICE_DT_GET(WDT_NODE); + TC_PRINT("Testcase: %s\n", __func__); + if (!device_is_ready(wdt)) { TC_PRINT("WDT device is not ready\n"); return TC_FAIL; } - TC_PRINT("Testcase: %s\n", __func__); - if (m_state == WDT_TEST_STATE_CHECK_RESET) { m_state = WDT_TEST_STATE_IDLE; m_testcase_index = 1U; @@ -246,13 +258,13 @@ static int test_wdt_callback_1(void) int err; const struct device *const wdt = DEVICE_DT_GET(WDT_NODE); + TC_PRINT("Testcase: %s\n", __func__); + if (!device_is_ready(wdt)) { TC_PRINT("WDT device is not ready\n"); return TC_FAIL; } - TC_PRINT("Testcase: %s\n", __func__); - if (m_state == WDT_TEST_STATE_CHECK_RESET) { m_state = WDT_TEST_STATE_IDLE; m_testcase_index++; @@ -310,13 +322,13 @@ static int test_wdt_callback_2(void) int err; const struct device *const wdt = DEVICE_DT_GET(WDT_NODE); + TC_PRINT("Testcase: %s\n", __func__); + if (!device_is_ready(wdt)) { TC_PRINT("WDT device is not ready\n"); return TC_FAIL; } - TC_PRINT("Testcase: %s\n", __func__); - if (m_state == WDT_TEST_STATE_CHECK_RESET) { m_state = WDT_TEST_STATE_IDLE; m_testcase_index++; @@ -375,18 +387,19 @@ static int test_wdt_callback_2(void) } #endif +#if TEST_WDT_BAD_MAX_WINDOW static int test_wdt_bad_window_max(void) { int err; const struct device *const wdt = DEVICE_DT_GET(WDT_NODE); + TC_PRINT("Testcase: %s\n", __func__); + if (!device_is_ready(wdt)) { TC_PRINT("WDT device is not ready\n"); return TC_FAIL; } - TC_PRINT("Testcase: %s\n", __func__); - err = wdt_disable(wdt); if (err < 0 && err != -EPERM && err != -EFAULT) { TC_PRINT("Watchdog disable error\n"); @@ -403,28 +416,25 @@ static int test_wdt_bad_window_max(void) return TC_FAIL; } +#endif +#if TEST_WDT_WAIT_MODE static int test_wdt_enable_wait_mode(void) { -#ifndef CONFIG_PM - TC_PRINT("Testcase: %s\n", __func__); - ztest_test_skip(); - m_state = WDT_TEST_STATE_IDLE; - return TC_SKIP; -#else int err; int wdt_channel_id; const struct device *const wdt = DEVICE_DT_GET(WDT_NODE); + TC_PRINT("Testcase: %s\n", __func__); + if (!device_is_ready(wdt)) { TC_PRINT("WDT device is not ready\n"); return TC_FAIL; } - TC_PRINT("Testcase: %s\n", __func__); - if (m_state == WDT_TEST_STATE_CHECK_RESET) { m_state = WDT_TEST_STATE_IDLE; + m_testcase_index++; TC_PRINT("Testcase passed\n"); return TC_PASS; } @@ -445,10 +455,13 @@ static int test_wdt_enable_wait_mode(void) } err = wdt_setup(wdt, (WDT_OPT_PAUSE_HALTED_BY_DBG | WDT_OPT_PAUSE_IN_SLEEP)); + if (err == -ENOTSUP) { + TC_PRINT("- pausing watchdog in sleep mode or by debugger is not supported\n"); + err = wdt_setup(wdt, 0); + } if (err < 0) { printk("Watchdog setup error\n"); - ztest_test_skip(); - return TC_SKIP; + return TC_FAIL; } for (int i = 0; i < 20; ++i) { @@ -465,8 +478,8 @@ static int test_wdt_enable_wait_mode(void) } return TC_PASS; -#endif } +#endif ZTEST(wdt_basic_test_suite, test_wdt) { @@ -488,14 +501,24 @@ ZTEST(wdt_basic_test_suite, test_wdt) #endif } if (m_testcase_index == 3U) { +#if TEST_WDT_WAIT_MODE zassert_true(test_wdt_enable_wait_mode() == TC_PASS); +#else m_testcase_index++; +#endif } if (m_testcase_index == 4U) { +#if TEST_WDT_BAD_MAX_WINDOW zassert_true(test_wdt_bad_window_max() == TC_PASS); +#endif m_testcase_index++; } if (m_testcase_index > 4) { m_state = WDT_TEST_STATE_IDLE; +#if WDT_TEST_FINAL_DISABLE + const struct device *const wdt = DEVICE_DT_GET(WDT_NODE); + + wdt_disable(wdt); +#endif } } From 28a9b43459aff6ca4df4f875bb653c65db609fb1 Mon Sep 17 00:00:00 2001 From: Antoni Duda Date: Mon, 5 Jan 2026 18:26:55 +0100 Subject: [PATCH 2015/3659] bluetooth: host: Allow unregistering per adv sync cbs Introduce bt_le_per_adv_sync_cb_unregister to allow unregistering of the periodic sync callbacks. Signed-off-by: Antoni Duda --- doc/releases/release-notes-4.4.rst | 1 + include/zephyr/bluetooth/bluetooth.h | 12 ++++++++ subsys/bluetooth/host/scan.c | 45 ++++++++++++++++++---------- 3 files changed, 42 insertions(+), 16 deletions(-) diff --git a/doc/releases/release-notes-4.4.rst b/doc/releases/release-notes-4.4.rst index 6176bfb717e9..2adfbbb422bc 100644 --- a/doc/releases/release-notes-4.4.rst +++ b/doc/releases/release-notes-4.4.rst @@ -123,6 +123,7 @@ New APIs and options * Host * :c:func:`bt_gatt_cb_unregister` Added an API to unregister GATT callback handlers. + * :c:func:`bt_le_per_adv_sync_cb_unregister` * Mesh diff --git a/include/zephyr/bluetooth/bluetooth.h b/include/zephyr/bluetooth/bluetooth.h index 593ebf1551e6..82d1a08e0dc6 100644 --- a/include/zephyr/bluetooth/bluetooth.h +++ b/include/zephyr/bluetooth/bluetooth.h @@ -2115,6 +2115,18 @@ int bt_le_per_adv_sync_delete(struct bt_le_per_adv_sync *per_adv_sync); */ int bt_le_per_adv_sync_cb_register(struct bt_le_per_adv_sync_cb *cb); +/** + * @brief Unregister periodic advertising sync callbacks. + * + * Removes the callback structure from the list of periodic advertising + * sync callbacks. + * + * @param cb Callback struct. + * + * @retval Zero on success or (negative) error code otherwise. + */ +int bt_le_per_adv_sync_cb_unregister(struct bt_le_per_adv_sync_cb *cb); + /** * @brief Enables receiving periodic advertising reports for a sync. * diff --git a/subsys/bluetooth/host/scan.c b/subsys/bluetooth/host/scan.c index 53d856c9b7e7..b993dd72a573 100644 --- a/subsys/bluetooth/host/scan.c +++ b/subsys/bluetooth/host/scan.c @@ -1022,9 +1022,9 @@ void bt_hci_le_per_adv_report_recv(struct bt_le_per_adv_sync *per_adv_sync, const struct bt_le_per_adv_sync_recv_info *info) { struct net_buf_simple_state state; - struct bt_le_per_adv_sync_cb *listener; + struct bt_le_per_adv_sync_cb *listener, *tmp; - SYS_SLIST_FOR_EACH_CONTAINER(&pa_sync_cbs, listener, node) { + SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&pa_sync_cbs, listener, tmp, node) { if (listener->recv) { net_buf_simple_save(buf, &state); listener->recv(per_adv_sync, info, buf); @@ -1037,9 +1037,9 @@ void bt_hci_le_per_adv_report_recv(struct bt_le_per_adv_sync *per_adv_sync, static void bt_hci_le_per_adv_report_recv_failure(struct bt_le_per_adv_sync *per_adv_sync, const struct bt_le_per_adv_sync_recv_info *info) { - struct bt_le_per_adv_sync_cb *listener; + struct bt_le_per_adv_sync_cb *listener, *tmp; - SYS_SLIST_FOR_EACH_CONTAINER(&pa_sync_cbs, listener, node) { + SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&pa_sync_cbs, listener, tmp, node) { if (listener->recv) { listener->recv(per_adv_sync, info, NULL); } @@ -1180,14 +1180,14 @@ static void per_adv_sync_terminated(struct bt_le_per_adv_sync *per_adv_sync, uin .sid = per_adv_sync->sid, .reason = reason, }; - struct bt_le_per_adv_sync_cb *listener; + struct bt_le_per_adv_sync_cb *listener, *tmp; /* Deleting before callback, so the caller will be able * to restart sync in the callback. */ per_adv_sync_delete(per_adv_sync); - SYS_SLIST_FOR_EACH_CONTAINER(&pa_sync_cbs, listener, node) { + SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&pa_sync_cbs, listener, tmp, node) { if (listener->term) { listener->term(per_adv_sync, &term_info); } @@ -1206,7 +1206,7 @@ static void bt_hci_le_per_adv_sync_established_common(struct net_buf *buf) struct bt_le_per_adv_sync_synced_info sync_info; struct bt_le_per_adv_sync *pending_per_adv_sync; - struct bt_le_per_adv_sync_cb *listener; + struct bt_le_per_adv_sync_cb *listener, *tmp; bt_addr_le_t id_addr; bool unexpected_evt; int err; @@ -1312,7 +1312,7 @@ static void bt_hci_le_per_adv_sync_established_common(struct net_buf *buf) sync_info.recv_enabled = !atomic_test_bit(pending_per_adv_sync->flags, BT_PER_ADV_SYNC_RECV_DISABLED); - SYS_SLIST_FOR_EACH_CONTAINER(&pa_sync_cbs, listener, node) { + SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&pa_sync_cbs, listener, tmp, node) { if (listener->synced) { listener->synced(pending_per_adv_sync, &sync_info); } @@ -1443,7 +1443,7 @@ static void bt_hci_le_past_received_common(struct net_buf *buf) #endif /* defined(CONFIG_BT_PER_ADV_SYNC_RSP) */ struct bt_le_per_adv_sync_synced_info sync_info; - struct bt_le_per_adv_sync_cb *listener; + struct bt_le_per_adv_sync_cb *listener, *tmp; struct bt_le_per_adv_sync *per_adv_sync; bt_addr_le_t id_addr; @@ -1517,7 +1517,7 @@ static void bt_hci_le_past_received_common(struct net_buf *buf) sync_info.response_slot_spacing = per_adv_sync->response_slot_spacing; #endif /* defined(CONFIG_BT_PER_ADV_SYNC_RSP) */ - SYS_SLIST_FOR_EACH_CONTAINER(&pa_sync_cbs, listener, node) { + SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&pa_sync_cbs, listener, tmp, node) { if (listener->synced) { listener->synced(per_adv_sync, &sync_info); } @@ -1562,7 +1562,7 @@ void bt_hci_le_biginfo_adv_report(struct net_buf *buf) { struct bt_hci_evt_le_biginfo_adv_report *evt; struct bt_le_per_adv_sync *per_adv_sync; - struct bt_le_per_adv_sync_cb *listener; + struct bt_le_per_adv_sync_cb *listener, *tmp; struct bt_iso_biginfo biginfo; evt = net_buf_pull_mem(buf, sizeof(*evt)); @@ -1590,7 +1590,7 @@ void bt_hci_le_biginfo_adv_report(struct net_buf *buf) biginfo.framing = evt->framing; biginfo.encryption = evt->encryption ? true : false; - SYS_SLIST_FOR_EACH_CONTAINER(&pa_sync_cbs, listener, node) { + SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&pa_sync_cbs, listener, tmp, node) { if (listener->biginfo) { listener->biginfo(per_adv_sync, &biginfo); } @@ -1604,7 +1604,7 @@ static void bt_hci_le_df_connectionless_iq_report_common(uint8_t event, struct n struct bt_df_per_adv_sync_iq_samples_report cte_report; struct bt_le_per_adv_sync *per_adv_sync; - struct bt_le_per_adv_sync_cb *listener; + struct bt_le_per_adv_sync_cb *listener, *tmp; if (event == BT_HCI_EVT_LE_CONNECTIONLESS_IQ_REPORT) { err = hci_df_prepare_connectionless_iq_report(buf, &cte_report, &per_adv_sync); @@ -1624,7 +1624,7 @@ static void bt_hci_le_df_connectionless_iq_report_common(uint8_t event, struct n return; } - SYS_SLIST_FOR_EACH_CONTAINER(&pa_sync_cbs, listener, node) { + SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&pa_sync_cbs, listener, tmp, node) { if (listener->cte_report_cb) { listener->cte_report_cb(per_adv_sync, &cte_report); } @@ -2065,10 +2065,23 @@ int bt_le_per_adv_sync_cb_register(struct bt_le_per_adv_sync_cb *cb) return 0; } +int bt_le_per_adv_sync_cb_unregister(struct bt_le_per_adv_sync_cb *cb) +{ + if (cb == NULL) { + return -EINVAL; + } + + if (!sys_slist_find_and_remove(&pa_sync_cbs, &cb->node)) { + return -ENOENT; + } + + return 0; +} + static int bt_le_set_per_adv_recv_enable(struct bt_le_per_adv_sync *per_adv_sync, bool enable) { struct bt_hci_cp_le_set_per_adv_recv_enable *cp; - struct bt_le_per_adv_sync_cb *listener; + struct bt_le_per_adv_sync_cb *listener, *tmp; struct bt_le_per_adv_sync_state_info info; struct net_buf *buf; struct bt_hci_cmd_state_set state; @@ -2113,7 +2126,7 @@ static int bt_le_set_per_adv_recv_enable(struct bt_le_per_adv_sync *per_adv_sync info.recv_enabled = !atomic_test_bit(per_adv_sync->flags, BT_PER_ADV_SYNC_RECV_DISABLED); - SYS_SLIST_FOR_EACH_CONTAINER(&pa_sync_cbs, listener, node) { + SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&pa_sync_cbs, listener, tmp, node) { if (listener->state_changed) { listener->state_changed(per_adv_sync, &info); } From 44194206185f4bb3dd0940a347b3c30a8615b33f Mon Sep 17 00:00:00 2001 From: Antoni Duda Date: Wed, 14 Jan 2026 18:09:55 +0100 Subject: [PATCH 2016/3659] tests: Bluetooth: Test for unregistering of per adv callbacks Introduces a testcase for the new api function bt_le_per_adv_sync_cb_unregister. Signed-off-by: Antoni Duda --- .../host/adv/periodic/src/per_adv_sync.c | 53 +++++++++++++++++++ .../per_adv_unregister_sync_cb.sh | 27 ++++++++++ 2 files changed, 80 insertions(+) create mode 100755 tests/bsim/bluetooth/host/adv/periodic/tests_scripts/per_adv_unregister_sync_cb.sh diff --git a/tests/bsim/bluetooth/host/adv/periodic/src/per_adv_sync.c b/tests/bsim/bluetooth/host/adv/periodic/src/per_adv_sync.c index 9f4399a8b2dd..18622cdcb636 100644 --- a/tests/bsim/bluetooth/host/adv/periodic/src/per_adv_sync.c +++ b/tests/bsim/bluetooth/host/adv/periodic/src/per_adv_sync.c @@ -239,6 +239,16 @@ static void start_bonding(void) printk("done.\n"); } +static void unregister_cb(void) +{ + int err; + + err = bt_le_per_adv_sync_cb_unregister(&sync_callbacks); + if (err != 0) { + TEST_FAIL("Failed to unregister callbacks: %d", err); + } +} + static void main_per_adv_sync(void) { struct bt_le_per_adv_sync *sync = NULL; @@ -364,6 +374,42 @@ static void main_per_adv_long_data_sync(void) TEST_PASS("Periodic advertising long data sync passed"); } +static void main_per_adv_unregister_sync_cb(void) +{ + struct bt_le_per_adv_sync *sync = NULL; + + common_init(); + start_scan(); + + printk("Waiting for periodic advertising...\n"); + WAIT_FOR_FLAG(flag_per_adv); + printk("Found periodic advertising.\n"); + + create_pa_sync(&sync); + + printk("Waiting to receive periodic advertisement...\n"); + WAIT_FOR_FLAG(flag_per_adv_recv); + + unregister_cb(); + UNSET_FLAG(flag_per_adv_recv); + k_sleep(K_SECONDS(2)); + + if (IS_FLAG_SET(flag_per_adv_recv)) { + /* Rarely the testcase might fail here due to a race condition as brought up in: + * https://github.com/zephyrproject-rtos/zephyr/pull/98458#issuecomment-3474097193 + */ + TEST_FAIL("Received a callback after bt_le_per_adv_sync_cb_unregister"); + return; + } + + bt_le_per_adv_sync_cb_register(&sync_callbacks); + WAIT_FOR_FLAG(flag_per_adv_recv); + + printk("Waiting for periodic sync lost...\n"); + WAIT_FOR_FLAG(flag_per_adv_sync_lost); + TEST_PASS("Periodic advertising sync callback unregister passed"); +} + static const struct bst_test_instance per_adv_sync[] = { { .test_id = "per_adv_sync", @@ -399,6 +445,13 @@ static const struct bst_test_instance per_adv_sync[] = { "reassembly of long data is handeled correctly.", .test_main_f = main_per_adv_long_data_sync }, + { + .test_id = "per_adv_unregister_sync_cb", + .test_descr = "Periodic advertising sync test, but sync callbacks " + "get unregistered. Test is used to verify that " + "the sync callbacks can be properly unregistered.", + .test_main_f = main_per_adv_unregister_sync_cb + }, BSTEST_END_MARKER }; diff --git a/tests/bsim/bluetooth/host/adv/periodic/tests_scripts/per_adv_unregister_sync_cb.sh b/tests/bsim/bluetooth/host/adv/periodic/tests_scripts/per_adv_unregister_sync_cb.sh new file mode 100755 index 000000000000..513f55a57d99 --- /dev/null +++ b/tests/bsim/bluetooth/host/adv/periodic/tests_scripts/per_adv_unregister_sync_cb.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash +# Copyright (c) 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +# Basic periodic advertising sync test: an advertiser advertises with periodic +# advertising, and a scanner scans for and syncs to the periodic advertising. +# Tests if sync callbacks are properly unregistered. + +source ${ZEPHYR_BASE}/tests/bsim/sh_common.source + +simulation_id="per_adv_unregister_sync_cb" +verbosity_level=2 + +cd ${BSIM_OUT_PATH}/bin + +Execute ./bs_${BOARD_TS}_tests_bsim_bluetooth_host_adv_periodic_prj_conf \ + -v=${verbosity_level} -s=${simulation_id} -d=0 -RealEncryption=0 \ + -testid=per_adv_long_data_advertiser -rs=23 + +Execute ./bs_${BOARD_TS}_tests_bsim_bluetooth_host_adv_periodic_prj_conf \ + -v=${verbosity_level} -s=${simulation_id} -d=1 -RealEncryption=0 \ + -testid=per_adv_unregister_sync_cb -rs=6 + +Execute ./bs_2G4_phy_v1 -v=${verbosity_level} -s=${simulation_id} \ + -D=2 -sim_length=15e6 $@ + +wait_for_background_jobs From ddaf21c02db812df3ac1fba18d37df87cabf1cfa Mon Sep 17 00:00:00 2001 From: Abderrahmane JARMOUNI Date: Wed, 7 Jan 2026 17:59:48 +0100 Subject: [PATCH 2017/3659] Revert "drivers: display: st7796s: Add display_set_orientation API" This reverts commit 132ab06a3fe48d8197c1bce034adde095d68126b. Signed-off-by: Abderrahmane JARMOUNI --- drivers/display/display_st7796s.c | 42 +------------------------------ drivers/display/display_st7796s.h | 6 ----- 2 files changed, 1 insertion(+), 47 deletions(-) diff --git a/drivers/display/display_st7796s.c b/drivers/display/display_st7796s.c index 75434e9a0eb8..faa90497da37 100644 --- a/drivers/display/display_st7796s.c +++ b/drivers/display/display_st7796s.c @@ -51,11 +51,6 @@ struct st7796s_config { bool rgb_is_inverted; }; -/* Display data struct */ -struct st7796s_data { - enum display_orientation orientation; -}; - static int st7796s_send_cmd(const struct device *dev, uint8_t cmd, const uint8_t *data, size_t len) { @@ -190,7 +185,6 @@ static int st7796s_write(const struct device *dev, static void st7796s_get_capabilities(const struct device *dev, struct display_capabilities *capabilities) { - struct st7796s_data *data = dev->data; const struct st7796s_config *config = dev->config; memset(capabilities, 0, sizeof(struct display_capabilities)); @@ -199,7 +193,7 @@ static void st7796s_get_capabilities(const struct device *dev, capabilities->x_resolution = config->width; capabilities->y_resolution = config->height; - capabilities->current_orientation = data->orientation; + capabilities->current_orientation = DISPLAY_ORIENTATION_NORMAL; } static int st7796s_lcd_config(const struct device *dev) @@ -314,39 +308,6 @@ static int st7796s_lcd_config(const struct device *dev) return st7796s_send_cmd(dev, ST7796S_CMD_CSCON, ¶m, sizeof(param)); } -static int st7796s_set_orientation(const struct device *dev, - const enum display_orientation orientation) -{ - struct st7796s_data *data = dev->data; - uint8_t tx_data = ST7796S_MADCTL_BGR; - int ret; - - if (orientation == DISPLAY_ORIENTATION_NORMAL) { - /* works 0° - default */ - tx_data |= ST7796S_MADCTL_MV; - } else if (orientation == DISPLAY_ORIENTATION_ROTATED_90) { - /* works CW 90° */ - tx_data |= ST7796S_MADCTL_MY; - } else if (orientation == DISPLAY_ORIENTATION_ROTATED_180) { - /* works CW 180° */ - tx_data |= ST7796S_MADCTL_MX | ST7796S_MADCTL_MY | ST7796S_MADCTL_MV; - } else if (orientation == DISPLAY_ORIENTATION_ROTATED_270) { - /* works CW 270° */ - tx_data |= ST7796S_MADCTL_MX; - } else { - return -EINVAL; - } - - ret = st7796s_send_cmd(dev, ST7796S_CMD_MADCTL, &tx_data, 1U); - if (ret < 0) { - return ret; - } - - data->orientation = orientation; - - return 0; -} - static int st7796s_init(const struct device *dev) { const struct st7796s_config *config = dev->config; @@ -406,7 +367,6 @@ static DEVICE_API(display, st7796s_api) = { .blanking_off = st7796s_blanking_off, .write = st7796s_write, .get_capabilities = st7796s_get_capabilities, - .set_orientation = st7796s_set_orientation, }; diff --git a/drivers/display/display_st7796s.h b/drivers/display/display_st7796s.h index 3f2c8acf46ed..43e4e2e4b9c6 100644 --- a/drivers/display/display_st7796s.h +++ b/drivers/display/display_st7796s.h @@ -35,12 +35,6 @@ #define ST7796S_CMD_CSCON 0xF0 /* Command set control */ #define ST7796S_CONTROL_16BIT 0x5 /* Sets control interface to 16 bit mode */ - -#define ST7796S_MADCTL_MY BIT(7) /* Set row address order */ -#define ST7796S_MADCTL_MX BIT(6) /* Set column address order */ -#define ST7796S_MADCTL_MV BIT(5) /* Set row/column exchange */ -#define ST7796S_MADCTL_ML BIT(4) /* Set vertical refresh order */ -#define ST7796S_MADCTL_MH BIT(2) /* Set horizontal refresh order */ #define ST7796S_MADCTL_BGR BIT(3) /* Sets BGR color mode */ From b25ecfd35818c4e97edfb7292a7e35c417b54e1a Mon Sep 17 00:00:00 2001 From: Wilfried Chauveau Date: Thu, 11 Dec 2025 23:28:05 +0000 Subject: [PATCH 2018/3659] cmake: sysbuild: propagate WEST_PYTHON & Python3_EXECUTABLE Without this, the parent CMake and the sub-processes may use different Python environment. Co-authored-by: Torsten Tejlmand Rasmussen Signed-off-by: Wilfried Chauveau --- share/sysbuild/cmake/modules/sysbuild_extensions.cmake | 2 ++ 1 file changed, 2 insertions(+) diff --git a/share/sysbuild/cmake/modules/sysbuild_extensions.cmake b/share/sysbuild/cmake/modules/sysbuild_extensions.cmake index af289d28bfe5..f5a1137712a5 100644 --- a/share/sysbuild/cmake/modules/sysbuild_extensions.cmake +++ b/share/sysbuild/cmake/modules/sysbuild_extensions.cmake @@ -320,6 +320,8 @@ function(ExternalZephyrProject_Add) shared_cmake_variables_list CMAKE_BUILD_TYPE CMAKE_VERBOSE_MAKEFILE + WEST_PYTHON # Temporary export. Waiting for #87083 and extensions.cmake to be cleaned up. + Python3_EXECUTABLE # Temporary export. Waiting for #87083 and extensions.cmake to be cleaned up. ) set(sysbuild_cache_file ${CMAKE_BINARY_DIR}/${ZBUILD_APPLICATION}_sysbuild_cache.txt) From 0b75b100cc77cf5538163f78cab6d0475dc1e25a Mon Sep 17 00:00:00 2001 From: Thomas Hebb Date: Mon, 12 Jan 2026 01:23:12 -0500 Subject: [PATCH 2019/3659] drivers: bluetooth: h4: Pass params to vendor setup function If the vendor driver knows how to set a public MAC, it can select CONFIG_BT_HCI_SET_PUBLIC_ADDR and set the address in this argument, allowing applications to set a public address with bt_id_create(). Signed-off-by: Thomas Hebb --- drivers/bluetooth/hci/h4.c | 7 +++---- drivers/bluetooth/hci/h4_infineon_cyw43xxx.c | 7 +++++-- drivers/bluetooth/hci/hci_nxp_setup.c | 5 ++++- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/drivers/bluetooth/hci/h4.c b/drivers/bluetooth/hci/h4.c index 21be2213fb87..d12676b31b0a 100644 --- a/drivers/bluetooth/hci/h4.c +++ b/drivers/bluetooth/hci/h4.c @@ -583,17 +583,16 @@ static int h4_setup(const struct device *dev, const struct bt_hci_setup_params * { const struct h4_config *cfg = dev->config; - ARG_UNUSED(params); - /* Extern bt_h4_vnd_setup function. * This function executes vendor-specific commands sequence to * initialize BT Controller before BT Host executes Reset sequence. * bt_h4_vnd_setup function must be implemented in vendor-specific HCI * extansion module if CONFIG_BT_HCI_SETUP is enabled. */ - extern int bt_h4_vnd_setup(const struct device *dev); + extern int bt_h4_vnd_setup(const struct device *dev, + const struct bt_hci_setup_params *params); - return bt_h4_vnd_setup(cfg->uart); + return bt_h4_vnd_setup(cfg->uart, params); } #endif diff --git a/drivers/bluetooth/hci/h4_infineon_cyw43xxx.c b/drivers/bluetooth/hci/h4_infineon_cyw43xxx.c index 54fe94287f88..c97b109dd898 100644 --- a/drivers/bluetooth/hci/h4_infineon_cyw43xxx.c +++ b/drivers/bluetooth/hci/h4_infineon_cyw43xxx.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -64,7 +65,7 @@ enum { * bt_h4_vnd_setup function must be implemented in vendor-specific HCI * extansion module if CONFIG_BT_HCI_SETUP is enabled. */ -int bt_h4_vnd_setup(const struct device *dev); +int bt_h4_vnd_setup(const struct device *dev, const struct bt_hci_setup_params *params); static int bt_hci_uart_set_baudrate(const struct device *bt_uart_dev, uint32_t baudrate) { @@ -205,13 +206,15 @@ static int bt_firmware_download(const uint8_t *firmware_image, uint32_t size) return 0; } -int bt_h4_vnd_setup(const struct device *dev) +int bt_h4_vnd_setup(const struct device *dev, const struct bt_hci_setup_params *params) { int err; uint32_t default_uart_speed = DT_PROP(DT_INST_BUS(0), current_speed); uint32_t hci_operation_speed = DT_INST_PROP_OR(0, hci_operation_speed, default_uart_speed); uint32_t fw_download_speed = DT_INST_PROP_OR(0, fw_download_speed, default_uart_speed); + ARG_UNUSED(params); + /* Check BT Uart instance */ if (!device_is_ready(dev)) { return -EINVAL; diff --git a/drivers/bluetooth/hci/hci_nxp_setup.c b/drivers/bluetooth/hci/hci_nxp_setup.c index 4f862af81218..d85edb65a074 100644 --- a/drivers/bluetooth/hci/hci_nxp_setup.c +++ b/drivers/bluetooth/hci/hci_nxp_setup.c @@ -18,6 +18,7 @@ #include #include +#include #include #include @@ -1412,13 +1413,15 @@ static int bt_hci_baudrate_update(const struct device *dev, uint32_t baudrate) return 0; } -int bt_h4_vnd_setup(const struct device *dev) +int bt_h4_vnd_setup(const struct device *dev, const struct bt_hci_setup_params *params) { int err; uint32_t default_speed; uint32_t operation_speed; bool flowcontrol_of_hci; + ARG_UNUSED(params); + if (dev != uart_dev) { return -EINVAL; } From bf81b7ca079abb558163bc88ac271dd5a1e08916 Mon Sep 17 00:00:00 2001 From: Thomas Hebb Date: Mon, 12 Jan 2026 01:38:03 -0500 Subject: [PATCH 2020/3659] bluetooth: cyw43xxx: Wire up vendor command to set MAC address There's a standardized way to set a public Bluetooth address in the core, and this hardware has a vendor specific command to do just that. Tell the core we support the operation and implement the command. This allows applications to set a MAC by calling bt_id_create() prior to bt_enable(). Signed-off-by: Thomas Hebb --- drivers/bluetooth/hci/Kconfig | 1 + drivers/bluetooth/hci/h4_infineon_cyw43xxx.c | 29 ++++++++++++++++++-- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/drivers/bluetooth/hci/Kconfig b/drivers/bluetooth/hci/Kconfig index 8e650f93eb69..9e8c522db4c6 100644 --- a/drivers/bluetooth/hci/Kconfig +++ b/drivers/bluetooth/hci/Kconfig @@ -259,6 +259,7 @@ config BT_AIROC select UART if BT_H4 select UART_USE_RUNTIME_CONFIGURE if BT_H4 select BT_HCI_SETUP + select BT_HCI_SET_PUBLIC_ADDR 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 diff --git a/drivers/bluetooth/hci/h4_infineon_cyw43xxx.c b/drivers/bluetooth/hci/h4_infineon_cyw43xxx.c index c97b109dd898..8877bbc5803d 100644 --- a/drivers/bluetooth/hci/h4_infineon_cyw43xxx.c +++ b/drivers/bluetooth/hci/h4_infineon_cyw43xxx.c @@ -53,6 +53,7 @@ extern const uint8_t brcm_patchram_buf[]; extern const int brcm_patch_ram_length; enum { + BT_HCI_VND_OP_SET_MAC = 0xFC01, BT_HCI_VND_OP_DOWNLOAD_MINIDRIVER = 0xFC2E, BT_HCI_VND_OP_WRITE_RAM = 0xFC4C, BT_HCI_VND_OP_LAUNCH_RAM = 0xFC4E, @@ -147,6 +148,22 @@ static int bt_update_controller_baudrate(const struct device *bt_uart_dev, uint3 return 0; } +static int bt_set_mac_address(const bt_addr_t *addr) +{ + struct net_buf *buf; + int err; + + buf = bt_hci_cmd_alloc(K_FOREVER); + net_buf_add_mem(buf, addr->val, 6); + + err = bt_hci_cmd_send_sync(BT_HCI_VND_OP_SET_MAC, buf, NULL); + if (err) { + return err; + } + + return 0; +} + static int bt_firmware_download(const uint8_t *firmware_image, uint32_t size) { uint8_t *data = (uint8_t *)firmware_image; @@ -209,12 +226,11 @@ static int bt_firmware_download(const uint8_t *firmware_image, uint32_t size) int bt_h4_vnd_setup(const struct device *dev, const struct bt_hci_setup_params *params) { int err; + const bt_addr_t *public_addr; uint32_t default_uart_speed = DT_PROP(DT_INST_BUS(0), current_speed); uint32_t hci_operation_speed = DT_INST_PROP_OR(0, hci_operation_speed, default_uart_speed); uint32_t fw_download_speed = DT_INST_PROP_OR(0, fw_download_speed, default_uart_speed); - ARG_UNUSED(params); - /* Check BT Uart instance */ if (!device_is_ready(dev)) { return -EINVAL; @@ -310,5 +326,14 @@ int bt_h4_vnd_setup(const struct device *dev, const struct bt_hci_setup_params * } } + /* Set public address if present */ + public_addr = ¶ms->public_addr; + if (!bt_addr_eq(public_addr, BT_ADDR_ANY) && !bt_addr_eq(public_addr, BT_ADDR_NONE)) { + err = bt_set_mac_address(public_addr); + if (err) { + return err; + } + } + return 0; } From 6b5af821640ae467e896c3c71b7143bbe4ce1d54 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Mon, 12 Jan 2026 12:10:06 -0500 Subject: [PATCH 2021/3659] cmake: compiler: arm64: Disable SVE for ARMv9-A when CONFIG_ARM64_SVE=n When building for ARMv9-A platforms with CONFIG_ARM64_SVE disabled, compilers still emit SVE instructions because ARMv9-A includes SVE by default in the architecture specification. Add explicit +nosve flag to -march when CONFIG_ARMV9_A=y but CONFIG_ARM64_SVE=n to prevent SVE instruction emission. This ensures the compiler respects the SVE configuration and only emits SVE instructions when explicitly enabled. Applied to both GCC and Clang/LLVM toolchains. Signed-off-by: Nicolas Pitre --- cmake/compiler/clang/target_arm64.cmake | 17 +++++++++++++++++ cmake/compiler/gcc/target_arm64.cmake | 9 ++++++++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/cmake/compiler/clang/target_arm64.cmake b/cmake/compiler/clang/target_arm64.cmake index 44933802d0c4..21795c1ce8b8 100644 --- a/cmake/compiler/clang/target_arm64.cmake +++ b/cmake/compiler/clang/target_arm64.cmake @@ -1,4 +1,21 @@ # SPDX-License-Identifier: Apache-2.0 + +# Add SVE support if enabled, or explicitly disable it for ARMv9-A +if(CONFIG_ARM64_SVE) + if(DEFINED GCC_M_ARCH) + set(GCC_M_ARCH "${GCC_M_ARCH}+sve") + else() + set(GCC_M_ARCH "armv9-a+sve") + endif() +elseif(CONFIG_ARMV9_A) + # ARMv9-A includes SVE by default, so explicitly disable it when not configured + if(DEFINED GCC_M_ARCH) + set(GCC_M_ARCH "${GCC_M_ARCH}+nosve") + else() + set(GCC_M_ARCH "armv9-a+nosve") + endif() +endif() + if(DEFINED GCC_M_CPU) list(APPEND TOOLCHAIN_C_FLAGS -mcpu=${GCC_M_CPU}) list(APPEND TOOLCHAIN_LD_FLAGS -mcpu=${GCC_M_CPU}) diff --git a/cmake/compiler/gcc/target_arm64.cmake b/cmake/compiler/gcc/target_arm64.cmake index 7c3304e58bb2..0b1bc9911015 100644 --- a/cmake/compiler/gcc/target_arm64.cmake +++ b/cmake/compiler/gcc/target_arm64.cmake @@ -1,12 +1,19 @@ # SPDX-License-Identifier: Apache-2.0 -# Add SVE support if enabled +# Add SVE support if enabled, or explicitly disable it for ARMv9-A if(CONFIG_ARM64_SVE) if(DEFINED GCC_M_ARCH) set(GCC_M_ARCH "${GCC_M_ARCH}+sve") else() set(GCC_M_ARCH "armv9-a+sve") endif() +elseif(CONFIG_ARMV9_A) + # ARMv9-A includes SVE by default, so explicitly disable it when not configured + if(DEFINED GCC_M_ARCH) + set(GCC_M_ARCH "${GCC_M_ARCH}+nosve") + else() + set(GCC_M_ARCH "armv9-a+nosve") + endif() endif() if(DEFINED GCC_M_CPU) From e0a268f501a6375dab159875df13ec4e6ed24823 Mon Sep 17 00:00:00 2001 From: Robert Hancock Date: Fri, 7 Feb 2025 14:01:36 -0600 Subject: [PATCH 2022/3659] drivers: dma: dma_xilinx_axi_dma: Add dependency for cache disable option The DMA_XILINX_AXI_DMA_DISABLE_CACHE_WHEN_ACCESSING_SG_DESCRIPTORS option is not meaningful to enable unless the platform/configuration actually supports the corresponding cache maintenance operations. Add dependencies accordingly. Signed-off-by: Robert Hancock --- drivers/dma/Kconfig.xilinx_axi_dma | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/dma/Kconfig.xilinx_axi_dma b/drivers/dma/Kconfig.xilinx_axi_dma index 1326ba500cb7..22d97a81c8d9 100644 --- a/drivers/dma/Kconfig.xilinx_axi_dma +++ b/drivers/dma/Kconfig.xilinx_axi_dma @@ -14,6 +14,8 @@ config DMA_XILINX_AXI_DMA config DMA_XILINX_AXI_DMA_DISABLE_CACHE_WHEN_ACCESSING_SG_DESCRIPTORS bool "Disable data cache while accessing Scatter-Gather Descriptors." depends on DMA_XILINX_AXI_DMA + depends on CACHE_MANAGEMENT + depends on DCACHE default n help Disable dcache while operating on Scatter-Gather descriptors. From 36909486e72a9152aaa5f603d620b3b6a1b8040d Mon Sep 17 00:00:00 2001 From: Robert Hancock Date: Fri, 7 Feb 2025 14:19:39 -0600 Subject: [PATCH 2023/3659] drivers: dma: dma_xilinx_axi_dma: Cleanup register access Instead of using a packed structure to define the register map, just create an enum for the registers and use that to refer to them. This avoids the need for repeatedly disabling GCC warnings for taking the address of packed structure members. Signed-off-by: Robert Hancock --- drivers/dma/dma_xilinx_axi_dma.c | 133 ++++++++++++------------------- 1 file changed, 51 insertions(+), 82 deletions(-) diff --git a/drivers/dma/dma_xilinx_axi_dma.c b/drivers/dma/dma_xilinx_axi_dma.c index 2b08080e0c53..af53a26472c8 100644 --- a/drivers/dma/dma_xilinx_axi_dma.c +++ b/drivers/dma/dma_xilinx_axi_dma.c @@ -176,43 +176,30 @@ __aligned(64) static struct dma_xilinx_axi_dma_sg_descriptor descriptors_tx[CONFIG_DMA_XILINX_AXI_DMA_SG_DESCRIPTOR_NUM_TX] = {0}; __aligned(64) static struct dma_xilinx_axi_dma_sg_descriptor descriptors_rx[CONFIG_DMA_XILINX_AXI_DMA_SG_DESCRIPTOR_NUM_RX] = {0}; -/* registers are the same with different name */ -struct __attribute__((__packed__)) dma_xilinx_axi_dma_mm2s_s2mm_registers { + +enum dma_xilinx_axi_dma_register { /* DMA control register */ /* bitfield, masks defined above */ - uint32_t dmacr; + XILINX_AXI_DMA_REG_DMACR = 0x00, /* DMA status register */ /* bitfield, masks defined above */ - uint32_t dmasr; + XILINX_AXI_DMA_REG_DMASR = 0x04, /* current descriptor address[31:0] */ - uint32_t curdesc; - /* current descriptor address[63:0] */ - uint32_t curdesc_msb; + XILINX_AXI_DMA_REG_CURDESC = 0x08, + /* current descriptor address[63:32] */ + XILINX_AXI_DMA_REG_CURDESC_MSB = 0x0C, /* current descriptor address[31:0] */ - uint32_t taildesc; - /* current descriptor address[63:0] */ - uint32_t taildesc_msb; - /* transfer source address for "direct register mode"[31:0] */ - uint32_t sa; - /* transfer source address for "direct register mode"[63:32] */ - uint32_t sa_msb; - uint32_t reserved1; - uint32_t reserved2; - /* transfer length for "direct register mode" */ - uint32_t length; + XILINX_AXI_DMA_REG_TAILDESC = 0x10, + /* current descriptor address[63:32] */ + XILINX_AXI_DMA_REG_TAILDESC_MSB = 0x14, }; -struct __attribute__((__packed__)) dma_xilinx_axi_dma_register_space { - struct dma_xilinx_axi_dma_mm2s_s2mm_registers mm2s_registers; - /* scatter/gather user and cache register or reserved */ - /* controls arcache/awcache and aruser/awuser of generated transactions */ - uint32_t sg_ctl; - struct dma_xilinx_axi_dma_mm2s_s2mm_registers s2mm_registers; -}; +#define XILINX_AXI_DMA_MM2S_REG_OFFSET 0x00 +#define XILINX_AXI_DMA_S2MM_REG_OFFSET 0x30 /* global configuration per DMA device */ struct dma_xilinx_axi_dma_config { - void *reg; + mm_reg_t reg; /* this should always be 2 - one for TX, one for RX */ uint32_t channels; void (*irq_configure)(); @@ -244,7 +231,7 @@ struct dma_xilinx_axi_dma_channel { size_t current_transfer_start_index, current_transfer_end_index; - volatile struct dma_xilinx_axi_dma_mm2s_s2mm_registers *channel_regs; + mm_reg_t channel_regs; enum dma_channel_direction last_transfer_direction; @@ -342,14 +329,16 @@ static inline void dma_xilinx_axi_dma_unlock_irq(const struct dma_xilinx_axi_dma #error "No IRQ strategy selected in Kconfig!" #endif -static inline void dma_xilinx_axi_dma_write_reg(volatile uint32_t *reg, uint32_t val) +static void dma_xilinx_axi_dma_write_reg(const struct dma_xilinx_axi_dma_channel *channel_data, + enum dma_xilinx_axi_dma_register reg, uint32_t val) { - sys_write32(val, (mem_addr_t)(uintptr_t)reg); + sys_write32(val, channel_data->channel_regs + reg); } -static inline uint32_t dma_xilinx_axi_dma_read_reg(volatile uint32_t *reg) +static uint32_t dma_xilinx_axi_dma_read_reg(const struct dma_xilinx_axi_dma_channel *channel_data, + enum dma_xilinx_axi_dma_register reg) { - return sys_read32((mem_addr_t)(uintptr_t)reg); + return sys_read32(channel_data->channel_regs + reg); } uint32_t dma_xilinx_axi_dma_last_received_frame_length(const struct device *dev) @@ -359,20 +348,16 @@ uint32_t dma_xilinx_axi_dma_last_received_frame_length(const struct device *dev) return data->channels[XILINX_AXI_DMA_RX_CHANNEL_NUM].last_rx_size; } -TOOLCHAIN_DISABLE_WARNING(TOOLCHAIN_WARNING_ADDRESS_OF_PACKED_MEMBER) static inline void dma_xilinx_axi_dma_acknowledge_interrupt(struct dma_xilinx_axi_dma_channel *channel_data) { /* interrupt handler might have called dma_start */ /* this overwrites the DMA control register */ /* so we cannot just write the old value back */ - uint32_t dmacr = dma_xilinx_axi_dma_read_reg(&channel_data->channel_regs->dmacr); + uint32_t dmacr = dma_xilinx_axi_dma_read_reg(channel_data, XILINX_AXI_DMA_REG_DMACR); - dma_xilinx_axi_dma_write_reg(&channel_data->channel_regs->dmacr, dmacr); + dma_xilinx_axi_dma_write_reg(channel_data, XILINX_AXI_DMA_REG_DMACR, dmacr); } -TOOLCHAIN_ENABLE_WARNING(TOOLCHAIN_WARNING_ADDRESS_OF_PACKED_MEMBER) - -TOOLCHAIN_DISABLE_WARNING(TOOLCHAIN_WARNING_ADDRESS_OF_PACKED_MEMBER) static bool dma_xilinx_axi_dma_channel_has_error( const struct dma_xilinx_axi_dma_channel *channel_data, volatile const struct dma_xilinx_axi_dma_sg_descriptor *descriptor) @@ -380,45 +365,45 @@ static bool dma_xilinx_axi_dma_channel_has_error( bool error = false; /* check register errors first, as the SG descriptor might not be valid */ - if (dma_xilinx_axi_dma_read_reg(&channel_data->channel_regs->dmasr) & + if (dma_xilinx_axi_dma_read_reg(channel_data, XILINX_AXI_DMA_REG_DMASR) & XILINX_AXI_DMA_REGS_DMASR_INTERR) { LOG_ERR("DMA has internal error, DMASR = %" PRIx32, - dma_xilinx_axi_dma_read_reg(&channel_data->channel_regs->dmasr)); + dma_xilinx_axi_dma_read_reg(channel_data, XILINX_AXI_DMA_REG_DMASR)); error = true; } - if (dma_xilinx_axi_dma_read_reg(&channel_data->channel_regs->dmasr) & + if (dma_xilinx_axi_dma_read_reg(channel_data, XILINX_AXI_DMA_REG_DMASR) & XILINX_AXI_DMA_REGS_DMASR_SLVERR) { LOG_ERR("DMA has slave error, DMASR = %" PRIx32, - dma_xilinx_axi_dma_read_reg(&channel_data->channel_regs->dmasr)); + dma_xilinx_axi_dma_read_reg(channel_data, XILINX_AXI_DMA_REG_DMASR)); error = true; } - if (dma_xilinx_axi_dma_read_reg(&channel_data->channel_regs->dmasr) & + if (dma_xilinx_axi_dma_read_reg(channel_data, XILINX_AXI_DMA_REG_DMASR) & XILINX_AXI_DMA_REGS_DMASR_DMADECERR) { LOG_ERR("DMA has decode error, DMASR = %" PRIx32, - dma_xilinx_axi_dma_read_reg(&channel_data->channel_regs->dmasr)); + dma_xilinx_axi_dma_read_reg(channel_data, XILINX_AXI_DMA_REG_DMASR)); error = true; } - if (dma_xilinx_axi_dma_read_reg(&channel_data->channel_regs->dmasr) & + if (dma_xilinx_axi_dma_read_reg(channel_data, XILINX_AXI_DMA_REG_DMASR) & XILINX_AXI_DMA_REGS_DMASR_SGINTERR) { LOG_ERR("DMA has SG internal error, DMASR = %" PRIx32, - dma_xilinx_axi_dma_read_reg(&channel_data->channel_regs->dmasr)); + dma_xilinx_axi_dma_read_reg(channel_data, XILINX_AXI_DMA_REG_DMASR)); error = true; } - if (dma_xilinx_axi_dma_read_reg(&channel_data->channel_regs->dmasr) & + if (dma_xilinx_axi_dma_read_reg(channel_data, XILINX_AXI_DMA_REG_DMASR) & XILINX_AXI_DMA_REGS_DMASR_SGSLVERR) { LOG_ERR("DMA has SG slave error, DMASR = %" PRIx32, - dma_xilinx_axi_dma_read_reg(&channel_data->channel_regs->dmasr)); + dma_xilinx_axi_dma_read_reg(channel_data, XILINX_AXI_DMA_REG_DMASR)); error = true; } - if (dma_xilinx_axi_dma_read_reg(&channel_data->channel_regs->dmasr) & + if (dma_xilinx_axi_dma_read_reg(channel_data, XILINX_AXI_DMA_REG_DMASR) & XILINX_AXI_DMA_REGS_DMASR_SGDECERR) { LOG_ERR("DMA has SG decode error, DMASR = %" PRIx32, - dma_xilinx_axi_dma_read_reg(&channel_data->channel_regs->dmasr)); + dma_xilinx_axi_dma_read_reg(channel_data, XILINX_AXI_DMA_REG_DMASR)); error = true; } @@ -439,7 +424,6 @@ static bool dma_xilinx_axi_dma_channel_has_error( return error; } -TOOLCHAIN_ENABLE_WARNING(TOOLCHAIN_WARNING_ADDRESS_OF_PACKED_MEMBER) static int dma_xilinx_axi_dma_clean_up_sg_descriptors(const struct device *dev, @@ -520,11 +504,9 @@ dma_xilinx_axi_dma_clean_up_sg_descriptors(const struct device *dev, processed_packets++; } - TOOLCHAIN_DISABLE_WARNING(TOOLCHAIN_WARNING_ADDRESS_OF_PACKED_MEMBER); /* this clears the IRQ */ /* FIXME write the same value back... */ - dma_xilinx_axi_dma_write_reg(&channel_data->channel_regs->dmasr, 0xffffffff); - TOOLCHAIN_ENABLE_WARNING(TOOLCHAIN_WARNING_ADDRESS_OF_PACKED_MEMBER); + dma_xilinx_axi_dma_write_reg(channel_data, XILINX_AXI_DMA_REG_DMASR, 0xffffffff); /* writes must commit before returning from ISR */ barrier_dmem_fence_full(); @@ -612,8 +594,7 @@ static int dma_xilinx_axi_dma_start(const struct device *dev, uint32_t channel) channel == XILINX_AXI_DMA_TX_CHANNEL_NUM ? "TX" : "RX", tail_descriptor, channel_data->current_transfer_end_index); - TOOLCHAIN_DISABLE_WARNING(TOOLCHAIN_WARNING_ADDRESS_OF_PACKED_MEMBER); - if (dma_xilinx_axi_dma_read_reg(&channel_data->channel_regs->dmasr) & + if (dma_xilinx_axi_dma_read_reg(channel_data, XILINX_AXI_DMA_REG_DMASR) & XILINX_AXI_DMA_REGS_DMASR_HALTED) { halted = true; @@ -622,17 +603,16 @@ static int dma_xilinx_axi_dma_start(const struct device *dev, uint32_t channel) #ifdef CONFIG_DMA_64BIT dma_xilinx_axi_dma_write_reg( - &channel_data->channel_regs->curdesc, + channel_data, XILINX_AXI_DMA_REG_CURDESC, (uint32_t)(((uintptr_t)first_unprocessed_descriptor) & 0xffffffff)); dma_xilinx_axi_dma_write_reg( - &channel_data->channel_regs->curdesc_msb, + channel_data, XILINX_AXI_DMA_REG_CURDESC_MSB, (uint32_t)(((uintptr_t)first_unprocessed_descriptor) >> 32)); #else - dma_xilinx_axi_dma_write_reg(&channel_data->channel_regs->curdesc, + dma_xilinx_axi_dma_write_reg(channel_data, XILINX_AXI_DMA_REG_CURDESC, (uint32_t)(uintptr_t)first_unprocessed_descriptor); #endif } - TOOLCHAIN_ENABLE_WARNING(TOOLCHAIN_WARNING_ADDRESS_OF_PACKED_MEMBER); /* current descriptor MUST be set before tail descriptor */ barrier_dmem_fence_full(); @@ -665,22 +645,20 @@ static int dma_xilinx_axi_dma_start(const struct device *dev, uint32_t channel) LOG_DBG("New DMACR value: %" PRIx32, new_control); - TOOLCHAIN_DISABLE_WARNING(TOOLCHAIN_WARNING_ADDRESS_OF_PACKED_MEMBER); - dma_xilinx_axi_dma_write_reg(&channel_data->channel_regs->dmacr, new_control); + dma_xilinx_axi_dma_write_reg(channel_data, XILINX_AXI_DMA_REG_DMACR, new_control); /* need to make sure start was committed before writing tail */ barrier_dmem_fence_full(); } #ifdef CONFIG_DMA_64BIT - dma_xilinx_axi_dma_write_reg(&channel_data->channel_regs->taildesc, + dma_xilinx_axi_dma_write_reg(channel_data, XILINX_AXI_DMA_REG_TAILDESC, (uint32_t)(((uintptr_t)current_descriptor) & 0xffffffff)); - dma_xilinx_axi_dma_write_reg(&channel_data->channel_regs->taildesc_msb, + dma_xilinx_axi_dma_write_reg(channel_data, XILINX_AXI_DMA_REG_TAILDESC_MSB, (uint32_t)(((uintptr_t)current_descriptor) >> 32)); #else - dma_xilinx_axi_dma_write_reg(&channel_data->channel_regs->taildesc, + dma_xilinx_axi_dma_write_reg(channel_data, XILINX_AXI_DMA_REG_TAILDESC, (uint32_t)(uintptr_t)current_descriptor); #endif - TOOLCHAIN_ENABLE_WARNING(TOOLCHAIN_WARNING_ADDRESS_OF_PACKED_MEMBER); dma_xilinx_axi_dma_enable_cache(); @@ -708,13 +686,11 @@ static int dma_xilinx_axi_dma_stop(const struct device *dev, uint32_t channel) k_timer_stop(&channel_data->polling_timer); - new_control = channel_data->channel_regs->dmacr; + new_control = dma_xilinx_axi_dma_read_reg(channel_data, XILINX_AXI_DMA_REG_DMACR); /* RS = 0 --> DMA will complete ongoing transactions and then go into hold */ new_control = new_control & ~XILINX_AXI_DMA_REGS_DMACR_RS; - TOOLCHAIN_DISABLE_WARNING(TOOLCHAIN_WARNING_ADDRESS_OF_PACKED_MEMBER); - dma_xilinx_axi_dma_write_reg(&channel_data->channel_regs->dmacr, new_control); - TOOLCHAIN_ENABLE_WARNING(TOOLCHAIN_WARNING_ADDRESS_OF_PACKED_MEMBER); + dma_xilinx_axi_dma_write_reg(channel_data, XILINX_AXI_DMA_REG_DMACR, new_control); /* commit before returning to caller */ barrier_dmem_fence_full(); @@ -737,12 +713,10 @@ static int dma_xilinx_axi_dma_get_status(const struct device *dev, uint32_t chan memset(stat, 0, sizeof(*stat)); - TOOLCHAIN_DISABLE_WARNING(TOOLCHAIN_WARNING_ADDRESS_OF_PACKED_MEMBER); - stat->busy = !(dma_xilinx_axi_dma_read_reg(&channel_data->channel_regs->dmasr) & + stat->busy = !(dma_xilinx_axi_dma_read_reg(channel_data, XILINX_AXI_DMA_REG_DMASR) & XILINX_AXI_DMA_REGS_DMASR_IDLE) && - !(dma_xilinx_axi_dma_read_reg(&channel_data->channel_regs->dmasr) & + !(dma_xilinx_axi_dma_read_reg(channel_data, XILINX_AXI_DMA_REG_DMASR) & XILINX_AXI_DMA_REGS_DMASR_HALTED); - TOOLCHAIN_ENABLE_WARNING(TOOLCHAIN_WARNING_ADDRESS_OF_PACKED_MEMBER); stat->dir = channel_data->last_transfer_direction; /* FIXME fill hardware-specific fields */ @@ -860,9 +834,6 @@ static int dma_xilinx_axi_dma_configure(const struct device *dev, uint32_t chann int ret = 0; int block_count = 0; - struct dma_xilinx_axi_dma_register_space *regs = - (struct dma_xilinx_axi_dma_register_space *)cfg->reg; - if (channel >= cfg->channels) { LOG_ERR("Invalid channel %" PRIu32 " - must be < %" PRIu32 "!", channel, cfg->channels); @@ -925,25 +896,23 @@ static int dma_xilinx_axi_dma_configure(const struct device *dev, uint32_t chann data->channels[channel].descriptors = descriptors_tx; data->channels[channel].num_descriptors = ARRAY_SIZE(descriptors_tx); - data->channels[channel].channel_regs = ®s->mm2s_registers; + data->channels[channel].channel_regs = cfg->reg + XILINX_AXI_DMA_MM2S_REG_OFFSET; } else { data->channels[channel].descriptors = descriptors_rx; data->channels[channel].num_descriptors = ARRAY_SIZE(descriptors_rx); - data->channels[channel].channel_regs = ®s->s2mm_registers; + data->channels[channel].channel_regs = cfg->reg + XILINX_AXI_DMA_S2MM_REG_OFFSET; } LOG_DBG("Resetting DMA channel!"); if (!data->device_has_been_reset) { LOG_INF("Soft-resetting the DMA core!"); - TOOLCHAIN_DISABLE_WARNING(TOOLCHAIN_WARNING_ADDRESS_OF_PACKED_MEMBER); /* this resets BOTH RX and TX channels, although it is triggered in per-channel * DMACR */ - dma_xilinx_axi_dma_write_reg(&data->channels[channel].channel_regs->dmacr, + dma_xilinx_axi_dma_write_reg(&data->channels[channel], XILINX_AXI_DMA_REG_DMACR, XILINX_AXI_DMA_REGS_DMACR_RESET); - TOOLCHAIN_ENABLE_WARNING(TOOLCHAIN_WARNING_ADDRESS_OF_PACKED_MEMBER); data->device_has_been_reset = true; } @@ -1095,7 +1064,7 @@ static int dma_xilinx_axi_dma_init(const struct device *dev) static uint32_t dma_xilinx_axi_dma##inst##_irq0_channels[] = \ DT_INST_PROP_OR(inst, interrupts, {0}); \ static const struct dma_xilinx_axi_dma_config dma_xilinx_axi_dma##inst##_config = { \ - .reg = (void *)(uintptr_t)DT_INST_REG_ADDR(inst), \ + .reg = DT_INST_REG_ADDR(inst), \ .channels = DT_INST_PROP(inst, dma_channels), \ .irq_configure = dma_xilinx_axi_dma##inst##_irq_configure, \ .irq0_channels = dma_xilinx_axi_dma##inst##_irq0_channels, \ From 1874b172b00f8e272087dea9165765c97e3db7ee Mon Sep 17 00:00:00 2001 From: Robert Hancock Date: Fri, 7 Feb 2025 14:36:29 -0600 Subject: [PATCH 2024/3659] drivers: dma: dma_xilinx_axi_dma: Move global reset to init function Doing a reset of the DMA engine during the dma_configure operation is problematic when using the DMA core in combination with the Xilinx AXI Ethernet core, since the DMA core's reset signals are normally propagated into the Ethernet core. This means that after the Ethernet core initializes and starts a DMA operation for the first time, the DMA core is reset, wiping out all of the register settings that the Ethernet core has made. To avoid this, move the DMA core reset and other initialization which only needs to be done once into the init function, so this is done during initial driver load and not deferred until later. Signed-off-by: Robert Hancock --- drivers/dma/dma_xilinx_axi_dma.c | 115 +++++++++++++++---------------- drivers/dma/dma_xilinx_axi_dma.h | 2 + 2 files changed, 58 insertions(+), 59 deletions(-) diff --git a/drivers/dma/dma_xilinx_axi_dma.c b/drivers/dma/dma_xilinx_axi_dma.c index af53a26472c8..1fa3315e185d 100644 --- a/drivers/dma/dma_xilinx_axi_dma.c +++ b/drivers/dma/dma_xilinx_axi_dma.c @@ -233,7 +233,7 @@ struct dma_xilinx_axi_dma_channel { mm_reg_t channel_regs; - enum dma_channel_direction last_transfer_direction; + enum dma_channel_direction direction; /* call this when the transfer is complete */ dma_callback_t completion_callback; @@ -249,7 +249,6 @@ struct dma_xilinx_axi_dma_channel { struct dma_xilinx_axi_dma_data { struct dma_context ctx; struct dma_xilinx_axi_dma_channel *channels; - bool device_has_been_reset; }; #ifdef CONFIG_DMA_XILINX_AXI_DMA_LOCK_ALL_IRQS @@ -565,8 +564,6 @@ static int dma_xilinx_axi_dma_start(const struct device *dev, uint32_t channel) volatile struct dma_xilinx_axi_dma_sg_descriptor *first_unprocessed_descriptor; size_t tail_descriptor; - bool halted = false; - /* running ISR in parallel could cause issues with the metadata */ const int irq_key = dma_xilinx_axi_dma_lock_irq(cfg, channel); @@ -596,30 +593,10 @@ static int dma_xilinx_axi_dma_start(const struct device *dev, uint32_t channel) if (dma_xilinx_axi_dma_read_reg(channel_data, XILINX_AXI_DMA_REG_DMASR) & XILINX_AXI_DMA_REGS_DMASR_HALTED) { - - halted = true; + uint32_t new_control = 0; LOG_DBG("AXI DMA is halted - restart operation!"); -#ifdef CONFIG_DMA_64BIT - dma_xilinx_axi_dma_write_reg( - channel_data, XILINX_AXI_DMA_REG_CURDESC, - (uint32_t)(((uintptr_t)first_unprocessed_descriptor) & 0xffffffff)); - dma_xilinx_axi_dma_write_reg( - channel_data, XILINX_AXI_DMA_REG_CURDESC_MSB, - (uint32_t)(((uintptr_t)first_unprocessed_descriptor) >> 32)); -#else - dma_xilinx_axi_dma_write_reg(channel_data, XILINX_AXI_DMA_REG_CURDESC, - (uint32_t)(uintptr_t)first_unprocessed_descriptor); -#endif - } - - /* current descriptor MUST be set before tail descriptor */ - barrier_dmem_fence_full(); - - if (halted) { - uint32_t new_control = 0; - new_control |= XILINX_AXI_DMA_REGS_DMACR_RS; /* no reset */ new_control &= ~XILINX_AXI_DMA_REGS_DMACR_RESET; @@ -717,7 +694,7 @@ static int dma_xilinx_axi_dma_get_status(const struct device *dev, uint32_t chan XILINX_AXI_DMA_REGS_DMASR_IDLE) && !(dma_xilinx_axi_dma_read_reg(channel_data, XILINX_AXI_DMA_REG_DMASR) & XILINX_AXI_DMA_REGS_DMASR_HALTED); - stat->dir = channel_data->last_transfer_direction; + stat->dir = channel_data->direction; /* FIXME fill hardware-specific fields */ @@ -840,13 +817,6 @@ static int dma_xilinx_axi_dma_configure(const struct device *dev, uint32_t chann return -EINVAL; } - if (cfg->channels != XILINX_AXI_DMA_NUM_CHANNELS) { - LOG_ERR("Invalid number of configured channels (%" PRIu32 - ") - Xilinx AXI DMA must have %" PRIu32 " channels!", - cfg->channels, XILINX_AXI_DMA_NUM_CHANNELS); - return -EINVAL; - } - if (dma_cfg->head_block->source_addr_adj == DMA_ADDR_ADJ_DECREMENT) { LOG_ERR("Xilinx AXI DMA only supports incrementing addresses!"); return -ENOTSUP; @@ -888,34 +858,8 @@ static int dma_xilinx_axi_dma_configure(const struct device *dev, uint32_t chann (channel == XILINX_AXI_DMA_TX_CHANNEL_NUM) ? dma_xilinx_axi_dma_tx_isr : dma_xilinx_axi_dma_rx_isr; - data->channels[channel].last_transfer_direction = dma_cfg->channel_direction; - dma_xilinx_axi_dma_disable_cache(); - if (channel == XILINX_AXI_DMA_TX_CHANNEL_NUM) { - data->channels[channel].descriptors = descriptors_tx; - data->channels[channel].num_descriptors = ARRAY_SIZE(descriptors_tx); - - data->channels[channel].channel_regs = cfg->reg + XILINX_AXI_DMA_MM2S_REG_OFFSET; - } else { - data->channels[channel].descriptors = descriptors_rx; - data->channels[channel].num_descriptors = ARRAY_SIZE(descriptors_rx); - - data->channels[channel].channel_regs = cfg->reg + XILINX_AXI_DMA_S2MM_REG_OFFSET; - } - - LOG_DBG("Resetting DMA channel!"); - - if (!data->device_has_been_reset) { - LOG_INF("Soft-resetting the DMA core!"); - /* this resets BOTH RX and TX channels, although it is triggered in per-channel - * DMACR - */ - dma_xilinx_axi_dma_write_reg(&data->channels[channel], XILINX_AXI_DMA_REG_DMACR, - XILINX_AXI_DMA_REGS_DMACR_RESET); - data->device_has_been_reset = true; - } - LOG_DBG("Configuring %zu DMA descriptors for %s", data->channels[channel].num_descriptors, channel == XILINX_AXI_DMA_TX_CHANNEL_NUM ? "TX" : "RX"); @@ -952,6 +896,17 @@ static int dma_xilinx_axi_dma_configure(const struct device *dev, uint32_t chann dma_xilinx_axi_dma_enable_cache(); +#ifdef CONFIG_DMA_64BIT + dma_xilinx_axi_dma_write_reg( + &data->channels[channel], XILINX_AXI_DMA_REG_CURDESC, + (uint32_t)(((uintptr_t)&data->channels[channel].descriptors[0]) & 0xffffffff)); + dma_xilinx_axi_dma_write_reg( + &data->channels[channel], XILINX_AXI_DMA_REG_CURDESC_MSB, + (uint32_t)(((uintptr_t)&data->channels[channel].descriptors[0]) >> 32)); +#else + dma_xilinx_axi_dma_write_reg(&data->channels[channel], XILINX_AXI_DMA_REG_CURDESC, + (uint32_t)(uintptr_t)&data->channels[channel].descriptors[0]); +#endif data->channels[channel].check_csum_in_isr = false; /* the DMA passes the app fields through to the AXIStream-connected device */ @@ -1036,6 +991,48 @@ static DEVICE_API(dma, dma_xilinx_axi_dma_driver_api) = { static int dma_xilinx_axi_dma_init(const struct device *dev) { const struct dma_xilinx_axi_dma_config *cfg = dev->config; + struct dma_xilinx_axi_dma_data *data = dev->data; + bool reset = false; + + if (cfg->channels != XILINX_AXI_DMA_NUM_CHANNELS) { + LOG_ERR("Invalid number of configured channels (%" PRIu32 + ") - Xilinx AXI DMA must have %" PRIu32 " channels!", + cfg->channels, XILINX_AXI_DMA_NUM_CHANNELS); + return -EINVAL; + } + + data->channels[XILINX_AXI_DMA_TX_CHANNEL_NUM].descriptors = descriptors_tx; + data->channels[XILINX_AXI_DMA_TX_CHANNEL_NUM].num_descriptors = ARRAY_SIZE(descriptors_tx); + data->channels[XILINX_AXI_DMA_TX_CHANNEL_NUM].channel_regs = + cfg->reg + XILINX_AXI_DMA_MM2S_REG_OFFSET; + data->channels[XILINX_AXI_DMA_TX_CHANNEL_NUM].direction = MEMORY_TO_PERIPHERAL; + + data->channels[XILINX_AXI_DMA_RX_CHANNEL_NUM].descriptors = descriptors_rx; + data->channels[XILINX_AXI_DMA_RX_CHANNEL_NUM].num_descriptors = ARRAY_SIZE(descriptors_rx); + data->channels[XILINX_AXI_DMA_RX_CHANNEL_NUM].channel_regs = + cfg->reg + XILINX_AXI_DMA_S2MM_REG_OFFSET; + data->channels[XILINX_AXI_DMA_RX_CHANNEL_NUM].direction = PERIPHERAL_TO_MEMORY; + + LOG_INF("Soft-resetting the DMA core!"); + /* this resets BOTH RX and TX channels, although it is triggered in per-channel + * DMACR + */ + dma_xilinx_axi_dma_write_reg(&data->channels[XILINX_AXI_DMA_RX_CHANNEL_NUM], + XILINX_AXI_DMA_REG_DMACR, XILINX_AXI_DMA_REGS_DMACR_RESET); + for (int i = 0; i < XILINX_AXI_DMA_RESET_TIMEOUT_MS; i++) { + if (dma_xilinx_axi_dma_read_reg(&data->channels[XILINX_AXI_DMA_RX_CHANNEL_NUM], + XILINX_AXI_DMA_REG_DMACR) & + XILINX_AXI_DMA_REGS_DMACR_RESET) { + k_msleep(1); + } else { + reset = true; + break; + } + } + if (!reset) { + LOG_ERR("DMA reset timed out!"); + return -EIO; + } cfg->irq_configure(); return 0; diff --git a/drivers/dma/dma_xilinx_axi_dma.h b/drivers/dma/dma_xilinx_axi_dma.h index 05d335663702..7d97755ca2fd 100644 --- a/drivers/dma/dma_xilinx_axi_dma.h +++ b/drivers/dma/dma_xilinx_axi_dma.h @@ -16,6 +16,8 @@ #define XILINX_AXI_DMA_LINKED_CHANNEL_NO_CSUM_OFFLOAD 0x0 #define XILINX_AXI_DMA_LINKED_CHANNEL_FULL_CSUM_OFFLOAD 0x1 +#define XILINX_AXI_DMA_RESET_TIMEOUT_MS 1000 + #include #include From dd352c1e5dbfcb602683d77f872afec764cbf21f Mon Sep 17 00:00:00 2001 From: Robert Hancock Date: Fri, 7 Feb 2025 14:43:52 -0600 Subject: [PATCH 2025/3659] drivers: dma: dma_xilinx_axi_dma: Fixes for DMA interrupt processing Fix some issues in the driver's DMA interrupt handling: -Ensure that interrupts are cleared prior to handling interrupt events, so that events raised during interrupt processing will cause the hardware to raise a new interrupt -Ensure that we do not overwrite existing DMA descriptors which are incomplete (such as by trying to execute more transfers than there are slots in the descriptor ring) -Ensure that error events reported by the DMA engine are reported -Rename some of the variables to track pending and completed ring locations for better clarity Signed-off-by: Robert Hancock --- drivers/dma/dma_xilinx_axi_dma.c | 231 +++++++++++++------------------ 1 file changed, 99 insertions(+), 132 deletions(-) diff --git a/drivers/dma/dma_xilinx_axi_dma.c b/drivers/dma/dma_xilinx_axi_dma.c index 1fa3315e185d..0e1fbe57c0fd 100644 --- a/drivers/dma/dma_xilinx_axi_dma.c +++ b/drivers/dma/dma_xilinx_axi_dma.c @@ -229,7 +229,11 @@ struct dma_xilinx_axi_dma_channel { size_t num_descriptors; - size_t current_transfer_start_index, current_transfer_end_index; + /* Last descriptor populated with pending transfer */ + size_t populated_desc_index; + + /* Next descriptor to check for completion by HW */ + size_t completion_desc_index; mm_reg_t channel_regs; @@ -347,103 +351,37 @@ uint32_t dma_xilinx_axi_dma_last_received_frame_length(const struct device *dev) return data->channels[XILINX_AXI_DMA_RX_CHANNEL_NUM].last_rx_size; } -static inline void -dma_xilinx_axi_dma_acknowledge_interrupt(struct dma_xilinx_axi_dma_channel *channel_data) -{ - /* interrupt handler might have called dma_start */ - /* this overwrites the DMA control register */ - /* so we cannot just write the old value back */ - uint32_t dmacr = dma_xilinx_axi_dma_read_reg(channel_data, XILINX_AXI_DMA_REG_DMACR); - - dma_xilinx_axi_dma_write_reg(channel_data, XILINX_AXI_DMA_REG_DMACR, dmacr); -} -static bool dma_xilinx_axi_dma_channel_has_error( - const struct dma_xilinx_axi_dma_channel *channel_data, - volatile const struct dma_xilinx_axi_dma_sg_descriptor *descriptor) -{ - bool error = false; - - /* check register errors first, as the SG descriptor might not be valid */ - if (dma_xilinx_axi_dma_read_reg(channel_data, XILINX_AXI_DMA_REG_DMASR) & - XILINX_AXI_DMA_REGS_DMASR_INTERR) { - LOG_ERR("DMA has internal error, DMASR = %" PRIx32, - dma_xilinx_axi_dma_read_reg(channel_data, XILINX_AXI_DMA_REG_DMASR)); - error = true; - } - - if (dma_xilinx_axi_dma_read_reg(channel_data, XILINX_AXI_DMA_REG_DMASR) & - XILINX_AXI_DMA_REGS_DMASR_SLVERR) { - LOG_ERR("DMA has slave error, DMASR = %" PRIx32, - dma_xilinx_axi_dma_read_reg(channel_data, XILINX_AXI_DMA_REG_DMASR)); - error = true; - } - - if (dma_xilinx_axi_dma_read_reg(channel_data, XILINX_AXI_DMA_REG_DMASR) & - XILINX_AXI_DMA_REGS_DMASR_DMADECERR) { - LOG_ERR("DMA has decode error, DMASR = %" PRIx32, - dma_xilinx_axi_dma_read_reg(channel_data, XILINX_AXI_DMA_REG_DMASR)); - error = true; - } - - if (dma_xilinx_axi_dma_read_reg(channel_data, XILINX_AXI_DMA_REG_DMASR) & - XILINX_AXI_DMA_REGS_DMASR_SGINTERR) { - LOG_ERR("DMA has SG internal error, DMASR = %" PRIx32, - dma_xilinx_axi_dma_read_reg(channel_data, XILINX_AXI_DMA_REG_DMASR)); - error = true; - } - - if (dma_xilinx_axi_dma_read_reg(channel_data, XILINX_AXI_DMA_REG_DMASR) & - XILINX_AXI_DMA_REGS_DMASR_SGSLVERR) { - LOG_ERR("DMA has SG slave error, DMASR = %" PRIx32, - dma_xilinx_axi_dma_read_reg(channel_data, XILINX_AXI_DMA_REG_DMASR)); - error = true; - } - - if (dma_xilinx_axi_dma_read_reg(channel_data, XILINX_AXI_DMA_REG_DMASR) & - XILINX_AXI_DMA_REGS_DMASR_SGDECERR) { - LOG_ERR("DMA has SG decode error, DMASR = %" PRIx32, - dma_xilinx_axi_dma_read_reg(channel_data, XILINX_AXI_DMA_REG_DMASR)); - error = true; - } - - if (descriptor->status & XILINX_AXI_DMA_SG_DESCRIPTOR_STATUS_DEC_ERR_MASK) { - LOG_ERR("Descriptor has SG decode error, status=%" PRIx32, descriptor->status); - error = true; - } - - if (descriptor->status & XILINX_AXI_DMA_SG_DESCRIPTOR_STATUS_SLV_ERR_MASK) { - LOG_ERR("Descriptor has SG slave error, status=%" PRIx32, descriptor->status); - error = true; - } - - if (descriptor->status & XILINX_AXI_DMA_SG_DESCRIPTOR_STATUS_INT_ERR_MASK) { - LOG_ERR("Descriptor has SG internal error, status=%" PRIx32, descriptor->status); - error = true; - } - - return error; -} - static int dma_xilinx_axi_dma_clean_up_sg_descriptors(const struct device *dev, struct dma_xilinx_axi_dma_channel *channel_data, const char *chan_name) { volatile struct dma_xilinx_axi_dma_sg_descriptor *current_descriptor = - &channel_data->descriptors[channel_data->current_transfer_end_index]; + &channel_data->descriptors[channel_data->completion_desc_index]; unsigned int processed_packets = 0; + uint32_t current_status = current_descriptor->status; - while (current_descriptor->status & XILINX_AXI_DMA_SG_DESCRIPTOR_STATUS_COMPLETE_MASK || - current_descriptor->status & ~XILINX_AXI_DMA_SG_DESCRIPTOR_STATUS_TRANSFERRED_MASK) { + while (current_status & ~XILINX_AXI_DMA_SG_DESCRIPTOR_STATUS_TRANSFERRED_MASK) { /* descriptor completed or errored out - need to call callback */ int retval = DMA_STATUS_COMPLETE; /* this is meaningless / ignored for TX channel */ - channel_data->last_rx_size = current_descriptor->status & - XILINX_AXI_DMA_SG_DESCRIPTOR_STATUS_LENGTH_MASK; + channel_data->last_rx_size = + current_status & XILINX_AXI_DMA_SG_DESCRIPTOR_STATUS_LENGTH_MASK; + + if (current_status & XILINX_AXI_DMA_SG_DESCRIPTOR_STATUS_DEC_ERR_MASK) { + LOG_ERR("Descriptor has SG decode error, status=%" PRIx32, current_status); + retval = -EFAULT; + } + + if (current_status & XILINX_AXI_DMA_SG_DESCRIPTOR_STATUS_SLV_ERR_MASK) { + LOG_ERR("Descriptor has SG slave error, status=%" PRIx32, current_status); + retval = -EFAULT; + } - if (dma_xilinx_axi_dma_channel_has_error(channel_data, current_descriptor)) { - LOG_ERR("Channel / descriptor error on %s chan!", chan_name); + if (current_status & XILINX_AXI_DMA_SG_DESCRIPTOR_STATUS_INT_ERR_MASK) { + LOG_ERR("Descriptor has SG internal error, status=%" PRIx32, + current_status); retval = -EFAULT; } @@ -481,32 +419,27 @@ dma_xilinx_axi_dma_clean_up_sg_descriptors(const struct device *dev, /* as we do not have per-skb flags for checksum status */ } - /* clears the flags such that the DMA does not transfer it twice or errors */ - current_descriptor->control = current_descriptor->status = 0; - - /* callback might start new transfer */ - /* hence, the transfer end needs to be updated */ - channel_data->current_transfer_end_index++; - if (channel_data->current_transfer_end_index >= channel_data->num_descriptors) { - channel_data->current_transfer_end_index = 0; - } - if (channel_data->completion_callback) { - LOG_DBG("Received packet with %u bytes!", channel_data->last_rx_size); + LOG_DBG("Completed packet descriptor %zu with %u bytes!", + channel_data->completion_desc_index, channel_data->last_rx_size); channel_data->completion_callback( dev, channel_data->completion_callback_user_data, XILINX_AXI_DMA_TX_CHANNEL_NUM, retval); } + /* clears the flags such that the DMA does not transfer it twice or errors */ + current_descriptor->control = current_descriptor->status = 0; + + channel_data->completion_desc_index++; + if (channel_data->completion_desc_index >= channel_data->num_descriptors) { + channel_data->completion_desc_index = 0; + } current_descriptor = - &channel_data->descriptors[channel_data->current_transfer_end_index]; + &channel_data->descriptors[channel_data->completion_desc_index]; + current_status = current_descriptor->status; processed_packets++; } - /* this clears the IRQ */ - /* FIXME write the same value back... */ - dma_xilinx_axi_dma_write_reg(channel_data, XILINX_AXI_DMA_REG_DMASR, 0xffffffff); - /* writes must commit before returning from ISR */ barrier_dmem_fence_full(); @@ -518,17 +451,31 @@ static void dma_xilinx_axi_dma_tx_isr(const struct device *dev) struct dma_xilinx_axi_dma_data *data = dev->data; struct dma_xilinx_axi_dma_channel *channel_data = &data->channels[XILINX_AXI_DMA_TX_CHANNEL_NUM]; - int processed_packets; + uint32_t dmasr = dma_xilinx_axi_dma_read_reg(channel_data, XILINX_AXI_DMA_REG_DMASR); - dma_xilinx_axi_dma_disable_cache(); + if (dmasr & XILINX_AXI_DMA_REGS_DMASR_ERR_IRQ) { + LOG_ERR("DMA reports TX error, DMASR = 0x%" PRIx32, dmasr); + dma_xilinx_axi_dma_write_reg(channel_data, XILINX_AXI_DMA_REG_DMASR, + XILINX_AXI_DMA_REGS_DMASR_ERR_IRQ); + } - processed_packets = dma_xilinx_axi_dma_clean_up_sg_descriptors(dev, channel_data, "TX"); + if (dmasr & (XILINX_AXI_DMA_REGS_DMASR_IOC_IRQ | XILINX_AXI_DMA_REGS_DMASR_DLY_IRQ)) { + int processed_packets; - dma_xilinx_axi_dma_enable_cache(); + /* Clear the IRQ now so that new completions trigger another interrupt */ + dma_xilinx_axi_dma_write_reg(channel_data, XILINX_AXI_DMA_REG_DMASR, + dmasr & (XILINX_AXI_DMA_REGS_DMASR_IOC_IRQ | + XILINX_AXI_DMA_REGS_DMASR_DLY_IRQ)); + + dma_xilinx_axi_dma_disable_cache(); - LOG_DBG("Received %u RX packets in this ISR!\n", processed_packets); + processed_packets = + dma_xilinx_axi_dma_clean_up_sg_descriptors(dev, channel_data, "TX"); + + dma_xilinx_axi_dma_enable_cache(); - dma_xilinx_axi_dma_acknowledge_interrupt(channel_data); + LOG_DBG("Completed %u TX packets in this ISR!\n", processed_packets); + } } static void dma_xilinx_axi_dma_rx_isr(const struct device *dev) @@ -536,17 +483,31 @@ static void dma_xilinx_axi_dma_rx_isr(const struct device *dev) struct dma_xilinx_axi_dma_data *data = dev->data; struct dma_xilinx_axi_dma_channel *channel_data = &data->channels[XILINX_AXI_DMA_RX_CHANNEL_NUM]; - int processed_packets; + uint32_t dmasr = dma_xilinx_axi_dma_read_reg(channel_data, XILINX_AXI_DMA_REG_DMASR); - dma_xilinx_axi_dma_disable_cache(); + if (dmasr & XILINX_AXI_DMA_REGS_DMASR_ERR_IRQ) { + LOG_ERR("DMA reports RX error, DMASR = 0x%" PRIx32, dmasr); + dma_xilinx_axi_dma_write_reg(channel_data, XILINX_AXI_DMA_REG_DMASR, + XILINX_AXI_DMA_REGS_DMASR_ERR_IRQ); + } - processed_packets = dma_xilinx_axi_dma_clean_up_sg_descriptors(dev, channel_data, "RX"); + if (dmasr & (XILINX_AXI_DMA_REGS_DMASR_IOC_IRQ | XILINX_AXI_DMA_REGS_DMASR_DLY_IRQ)) { + int processed_packets; - dma_xilinx_axi_dma_enable_cache(); + /* Clear the IRQ now so that new completions trigger another interrupt */ + dma_xilinx_axi_dma_write_reg(channel_data, XILINX_AXI_DMA_REG_DMASR, + dmasr & (XILINX_AXI_DMA_REGS_DMASR_IOC_IRQ | + XILINX_AXI_DMA_REGS_DMASR_DLY_IRQ)); + + dma_xilinx_axi_dma_disable_cache(); - LOG_DBG("Cleaned up %u TX packets in this ISR!\n", processed_packets); + processed_packets = + dma_xilinx_axi_dma_clean_up_sg_descriptors(dev, channel_data, "RX"); - dma_xilinx_axi_dma_acknowledge_interrupt(channel_data); + dma_xilinx_axi_dma_enable_cache(); + + LOG_DBG("Cleaned up %u RX packets in this ISR!", processed_packets); + } } #ifdef CONFIG_DMA_64BIT @@ -559,10 +520,8 @@ static int dma_xilinx_axi_dma_start(const struct device *dev, uint32_t channel) { const struct dma_xilinx_axi_dma_config *cfg = dev->config; struct dma_xilinx_axi_dma_data *data = dev->data; - struct dma_xilinx_axi_dma_channel *channel_data = &data->channels[channel]; + struct dma_xilinx_axi_dma_channel *channel_data; volatile struct dma_xilinx_axi_dma_sg_descriptor *current_descriptor; - volatile struct dma_xilinx_axi_dma_sg_descriptor *first_unprocessed_descriptor; - size_t tail_descriptor; /* running ISR in parallel could cause issues with the metadata */ const int irq_key = dma_xilinx_axi_dma_lock_irq(cfg, channel); @@ -574,22 +533,14 @@ static int dma_xilinx_axi_dma_start(const struct device *dev, uint32_t channel) return -EINVAL; } - tail_descriptor = channel_data->current_transfer_start_index++; - - if (channel_data->current_transfer_start_index >= channel_data->num_descriptors) { - LOG_DBG("Wrapping tail descriptor on %s chan!", - channel == XILINX_AXI_DMA_TX_CHANNEL_NUM ? "TX" : "RX"); - channel_data->current_transfer_start_index = 0; - } + channel_data = &data->channels[channel]; + current_descriptor = &channel_data->descriptors[channel_data->populated_desc_index]; dma_xilinx_axi_dma_disable_cache(); - current_descriptor = &channel_data->descriptors[tail_descriptor]; - first_unprocessed_descriptor = - &channel_data->descriptors[channel_data->current_transfer_end_index]; - LOG_DBG("Starting DMA on %s channel with tail ptr %zu start ptr %zu", - channel == XILINX_AXI_DMA_TX_CHANNEL_NUM ? "TX" : "RX", tail_descriptor, - channel_data->current_transfer_end_index); + LOG_DBG("Starting DMA on %s channel with descriptor %zu at %p", + channel == XILINX_AXI_DMA_TX_CHANNEL_NUM ? "TX" : "RX", + channel_data->populated_desc_index, (void *)current_descriptor); if (dma_xilinx_axi_dma_read_reg(channel_data, XILINX_AXI_DMA_REG_DMASR) & XILINX_AXI_DMA_REGS_DMASR_HALTED) { @@ -715,11 +666,25 @@ static inline int dma_xilinx_axi_dma_transfer_block(const struct dma_xilinx_axi_ /* running ISR in parallel could cause issues with the metadata */ const int irq_key = dma_xilinx_axi_dma_lock_irq(cfg, channel); + size_t next_desc_index = channel_data->populated_desc_index + 1; - current_descriptor = &channel_data->descriptors[channel_data->current_transfer_start_index]; + if (next_desc_index >= channel_data->num_descriptors) { + next_desc_index = 0; + } + + current_descriptor = &channel_data->descriptors[next_desc_index]; dma_xilinx_axi_dma_disable_cache(); + if (current_descriptor->control || current_descriptor->status) { + /* Do not overwrite this descriptor as it has not been completed yet. */ + LOG_WRN("Descriptor %" PRIu32 " is not yet completed, not starting new transfer!", + next_desc_index); + dma_xilinx_axi_dma_enable_cache(); + dma_xilinx_axi_dma_unlock_irq(cfg, channel, irq_key); + return -EBUSY; + } + #ifdef CONFIG_DMA_64BIT current_descriptor->buffer_address = (uint32_t)buffer_addr & 0xffffffff; current_descriptor->buffer_address_msb = (uint32_t)(buffer_addr >> 32); @@ -753,6 +718,8 @@ static inline int dma_xilinx_axi_dma_transfer_block(const struct dma_xilinx_axi_ dma_xilinx_axi_dma_enable_cache(); + channel_data->populated_desc_index = next_desc_index; + dma_xilinx_axi_dma_unlock_irq(cfg, channel, irq_key); return 0; @@ -865,8 +832,8 @@ static int dma_xilinx_axi_dma_configure(const struct device *dev, uint32_t chann /* only configures fields whos default is not 0, as descriptors are in zero-initialized */ /* segment */ - data->channels[channel].current_transfer_start_index = - data->channels[channel].current_transfer_end_index = 0; + data->channels[channel].populated_desc_index = data->channels[channel].num_descriptors - 1; + data->channels[channel].completion_desc_index = 0; for (int i = 0; i < data->channels[channel].num_descriptors; i++) { uintptr_t nextdesc; uint32_t low_bytes; From 01d089ae0250c20cd4d0e859a18ecd78bbdd2eb2 Mon Sep 17 00:00:00 2001 From: Robert Hancock Date: Fri, 7 Feb 2025 14:48:51 -0600 Subject: [PATCH 2026/3659] drivers: dma: dma_xilinx_axi_dma: Remove polling timer The driver previously had a timer to periodically check for completed TX/RX transfers in case an interrupt notification was missed. With previous changes to the driver to avoid lost interrupt wakeups, this workaround should no longer be required, so remove it. Signed-off-by: Robert Hancock --- drivers/dma/Kconfig.xilinx_axi_dma | 13 -------- drivers/dma/dma_xilinx_axi_dma.c | 49 ------------------------------ 2 files changed, 62 deletions(-) diff --git a/drivers/dma/Kconfig.xilinx_axi_dma b/drivers/dma/Kconfig.xilinx_axi_dma index 22d97a81c8d9..dbbc4f63e5e7 100644 --- a/drivers/dma/Kconfig.xilinx_axi_dma +++ b/drivers/dma/Kconfig.xilinx_axi_dma @@ -70,19 +70,6 @@ config DMA_XILINX_AXI_DMA_LOCK_CHANNEL_IRQ endchoice -config DMA_XILINX_AXI_DMA_POLL_INTERVAL - int "Period of the timer used for polling the DMA in milliseconds" - depends on DMA_XILINX_AXI_DMA - default 100 - help - On certain platforms (e.g., RISC-V), the DMA driver can sometimes miss interrupts. - This can cause the DMA driver to stop processing completed transactions. - In order to prevent this, the DMA driver periodically polls the DMA's registers and - determines whether it needs to handle outstanding transactions. - This configuration controls how often this happens. - Choose a larger value to minimize overhead and a smaller value to minimize - worst-case latency. - config DMA_XILINX_AXI_DMA_INTERRUPT_THRESHOLD int "Number of completed transactions after which to trigger an interrupt" depends on DMA_XILINX_AXI_DMA diff --git a/drivers/dma/dma_xilinx_axi_dma.c b/drivers/dma/dma_xilinx_axi_dma.c index 0e1fbe57c0fd..7a0ef43adb16 100644 --- a/drivers/dma/dma_xilinx_axi_dma.c +++ b/drivers/dma/dma_xilinx_axi_dma.c @@ -209,24 +209,10 @@ struct dma_xilinx_axi_dma_config { typedef void (*dma_xilinx_axi_dma_isr_t)(const struct device *dev); -/* parameters for polling timer */ -struct dma_xilinx_axi_dma_timer_params { - /* back reference for the device */ - const struct device *dev; - /* number of this channel's IRQ */ - unsigned int irq_number; - /* ISR that normally handles the channel's interrupts */ - dma_xilinx_axi_dma_isr_t isr; -}; - /* per-channel state */ struct dma_xilinx_axi_dma_channel { volatile struct dma_xilinx_axi_dma_sg_descriptor *descriptors; - struct k_timer polling_timer; - - struct dma_xilinx_axi_dma_timer_params polling_timer_params; - size_t num_descriptors; /* Last descriptor populated with pending transfer */ @@ -612,8 +598,6 @@ static int dma_xilinx_axi_dma_stop(const struct device *dev, uint32_t channel) return -EINVAL; } - k_timer_stop(&channel_data->polling_timer); - new_control = dma_xilinx_axi_dma_read_reg(channel_data, XILINX_AXI_DMA_REG_DMACR); /* RS = 0 --> DMA will complete ongoing transactions and then go into hold */ new_control = new_control & ~XILINX_AXI_DMA_REGS_DMACR_RS; @@ -748,27 +732,6 @@ static inline int dma_xilinx_axi_dma_config_reload(const struct device *dev, uin size, true, true); } -/* regularly check if we missed an interrupt from the device */ -/* as interrupts are level-sensitive, this can happen on certain platforms */ -static void polling_timer_handler(struct k_timer *timer) -{ - struct dma_xilinx_axi_dma_channel *channel = - CONTAINER_OF(timer, struct dma_xilinx_axi_dma_channel, polling_timer); - const struct device *dev = channel->polling_timer_params.dev; - const unsigned int irq_number = channel->polling_timer_params.irq_number; - const int was_enabled = irq_is_enabled(irq_number); - - irq_disable(irq_number); - - LOG_DBG("Polling ISR!"); - - channel->polling_timer_params.isr(dev); - - if (was_enabled) { - irq_enable(irq_number); - } -} - static int dma_xilinx_axi_dma_configure(const struct device *dev, uint32_t channel, struct dma_config *dma_cfg) { @@ -817,14 +780,6 @@ static int dma_xilinx_axi_dma_configure(const struct device *dev, uint32_t chann return -ENOTSUP; } - k_timer_init(&data->channels[channel].polling_timer, polling_timer_handler, NULL); - - data->channels[channel].polling_timer_params.dev = dev; - data->channels[channel].polling_timer_params.irq_number = cfg->irq0_channels[channel]; - data->channels[channel].polling_timer_params.isr = - (channel == XILINX_AXI_DMA_TX_CHANNEL_NUM) ? dma_xilinx_axi_dma_tx_isr - : dma_xilinx_axi_dma_rx_isr; - dma_xilinx_axi_dma_disable_cache(); LOG_DBG("Configuring %zu DMA descriptors for %s", data->channels[channel].num_descriptors, @@ -921,10 +876,6 @@ static int dma_xilinx_axi_dma_configure(const struct device *dev, uint32_t chann block_count++; } while ((current_block = current_block->next_block) && ret == 0); - k_timer_start(&data->channels[channel].polling_timer, - K_MSEC(CONFIG_DMA_XILINX_AXI_DMA_POLL_INTERVAL), - K_MSEC(CONFIG_DMA_XILINX_AXI_DMA_POLL_INTERVAL)); - return ret; } From c00f01fb974b6e9012d7a3bfd92e169ca2249c02 Mon Sep 17 00:00:00 2001 From: Robert Hancock Date: Mon, 10 Feb 2025 15:29:54 -0600 Subject: [PATCH 2027/3659] drivers: dma: dma_xilinx_axi_dma: Use selective dcache flush/invalidate This driver has a config option DMA_XILINX_AXI_DMA_DISABLE_CACHE_WHEN_ACCESSING_SG_DESCRIPTORS to allow it to be used on platforms where DMA memory access is not automatically cache coherent. However, fully disabling the dcache when accessing DMA buffers/descriptors is not necessary and is potentially problematic. This can be handled more selectively by doing explicit cache invalidate and/or flush operations on the buffers involved as required. Note that this does introduce a requirement that RX DMA buffers provided to the driver are cache line aligned, as otherwise the required cache invalidate operation could potentially corrupt unrelated data. This is explicitly checked when a DMA RX operation is started. Tested on Cortex-R5 with data cache enabled. Signed-off-by: Robert Hancock --- drivers/dma/Kconfig.xilinx_axi_dma | 3 +- drivers/dma/dma_xilinx_axi_dma.c | 92 ++++++++++++++++-------------- 2 files changed, 51 insertions(+), 44 deletions(-) diff --git a/drivers/dma/Kconfig.xilinx_axi_dma b/drivers/dma/Kconfig.xilinx_axi_dma index dbbc4f63e5e7..912323929bcd 100644 --- a/drivers/dma/Kconfig.xilinx_axi_dma +++ b/drivers/dma/Kconfig.xilinx_axi_dma @@ -18,7 +18,8 @@ config DMA_XILINX_AXI_DMA_DISABLE_CACHE_WHEN_ACCESSING_SG_DESCRIPTORS depends on DCACHE default n help - Disable dcache while operating on Scatter-Gather descriptors. + Controls whether to explicitly flush or invalidate the data cache when accessing + DMA descriptors or buffers. This allows the DMA to be used on architectures that do not provide coherency for DMA accesses. If you are unsure whether you need this feature, you should select n here. diff --git a/drivers/dma/dma_xilinx_axi_dma.c b/drivers/dma/dma_xilinx_axi_dma.c index 7a0ef43adb16..22de0ca1dbba 100644 --- a/drivers/dma/dma_xilinx_axi_dma.c +++ b/drivers/dma/dma_xilinx_axi_dma.c @@ -13,6 +13,7 @@ #include #include #include +#include #include "dma_xilinx_axi_dma.h" @@ -123,26 +124,18 @@ LOG_MODULE_REGISTER(dma_xilinx_axi_dma, CONFIG_DMA_LOG_LEVEL); #define XILINX_AXI_DMA_REGS_SG_CTRL_USER_MASK 0x00000F00 #define XILINX_AXI_DMA_REGS_SG_CTRL_RES2_MASK 0xFFFFF000 -#ifdef CONFIG_DMA_XILINX_AXI_DMA_DISABLE_CACHE_WHEN_ACCESSING_SG_DESCRIPTORS -#include -static inline void dma_xilinx_axi_dma_disable_cache(void) -{ - cache_data_disable(); -} -static inline void dma_xilinx_axi_dma_enable_cache(void) -{ - cache_data_enable(); -} -#else -static inline void dma_xilinx_axi_dma_disable_cache(void) +static inline void dma_xilinx_axi_dma_flush_dcache(void *addr, size_t len) { - /* do nothing */ +#ifdef CONFIG_DMA_XILINX_AXI_DMA_DISABLE_CACHE_WHEN_ACCESSING_SG_DESCRIPTORS + sys_cache_data_flush_range(addr, len); +#endif } -static inline void dma_xilinx_axi_dma_enable_cache(void) +static inline void dma_xilinx_axi_dma_invd_dcache(void *addr, size_t len) { - /* do nothing */ -} +#ifdef CONFIG_DMA_XILINX_AXI_DMA_DISABLE_CACHE_WHEN_ACCESSING_SG_DESCRIPTORS + sys_cache_data_invd_range(addr, len); #endif +} /* in-memory descriptor, read by the DMA, that instructs it how many bits to transfer from which */ /* buffer */ @@ -345,7 +338,10 @@ dma_xilinx_axi_dma_clean_up_sg_descriptors(const struct device *dev, volatile struct dma_xilinx_axi_dma_sg_descriptor *current_descriptor = &channel_data->descriptors[channel_data->completion_desc_index]; unsigned int processed_packets = 0; - uint32_t current_status = current_descriptor->status; + uint32_t current_status; + + dma_xilinx_axi_dma_invd_dcache((void *)current_descriptor, sizeof(*current_descriptor)); + current_status = current_descriptor->status; while (current_status & ~XILINX_AXI_DMA_SG_DESCRIPTOR_STATUS_TRANSFERRED_MASK) { /* descriptor completed or errored out - need to call callback */ @@ -408,13 +404,24 @@ dma_xilinx_axi_dma_clean_up_sg_descriptors(const struct device *dev, if (channel_data->completion_callback) { LOG_DBG("Completed packet descriptor %zu with %u bytes!", channel_data->completion_desc_index, channel_data->last_rx_size); + if (channel_data->direction == PERIPHERAL_TO_MEMORY) { + dma_xilinx_axi_dma_invd_dcache( + (void *)current_descriptor->buffer_address, + channel_data->last_rx_size); + } channel_data->completion_callback( dev, channel_data->completion_callback_user_data, - XILINX_AXI_DMA_TX_CHANNEL_NUM, retval); + channel_data->direction == MEMORY_TO_PERIPHERAL + ? XILINX_AXI_DMA_TX_CHANNEL_NUM + : XILINX_AXI_DMA_RX_CHANNEL_NUM, + retval); } /* clears the flags such that the DMA does not transfer it twice or errors */ current_descriptor->control = current_descriptor->status = 0; + barrier_dmem_fence_full(); + dma_xilinx_axi_dma_flush_dcache((void *)current_descriptor, + sizeof(*current_descriptor)); channel_data->completion_desc_index++; if (channel_data->completion_desc_index >= channel_data->num_descriptors) { @@ -422,13 +429,12 @@ dma_xilinx_axi_dma_clean_up_sg_descriptors(const struct device *dev, } current_descriptor = &channel_data->descriptors[channel_data->completion_desc_index]; + dma_xilinx_axi_dma_invd_dcache((void *)current_descriptor, + sizeof(*current_descriptor)); current_status = current_descriptor->status; processed_packets++; } - /* writes must commit before returning from ISR */ - barrier_dmem_fence_full(); - return processed_packets; } @@ -453,13 +459,9 @@ static void dma_xilinx_axi_dma_tx_isr(const struct device *dev) dmasr & (XILINX_AXI_DMA_REGS_DMASR_IOC_IRQ | XILINX_AXI_DMA_REGS_DMASR_DLY_IRQ)); - dma_xilinx_axi_dma_disable_cache(); - processed_packets = dma_xilinx_axi_dma_clean_up_sg_descriptors(dev, channel_data, "TX"); - dma_xilinx_axi_dma_enable_cache(); - LOG_DBG("Completed %u TX packets in this ISR!\n", processed_packets); } } @@ -485,13 +487,9 @@ static void dma_xilinx_axi_dma_rx_isr(const struct device *dev) dmasr & (XILINX_AXI_DMA_REGS_DMASR_IOC_IRQ | XILINX_AXI_DMA_REGS_DMASR_DLY_IRQ)); - dma_xilinx_axi_dma_disable_cache(); - processed_packets = dma_xilinx_axi_dma_clean_up_sg_descriptors(dev, channel_data, "RX"); - dma_xilinx_axi_dma_enable_cache(); - LOG_DBG("Cleaned up %u RX packets in this ISR!", processed_packets); } } @@ -522,8 +520,6 @@ static int dma_xilinx_axi_dma_start(const struct device *dev, uint32_t channel) channel_data = &data->channels[channel]; current_descriptor = &channel_data->descriptors[channel_data->populated_desc_index]; - dma_xilinx_axi_dma_disable_cache(); - LOG_DBG("Starting DMA on %s channel with descriptor %zu at %p", channel == XILINX_AXI_DMA_TX_CHANNEL_NUM ? "TX" : "RX", channel_data->populated_desc_index, (void *)current_descriptor); @@ -574,8 +570,6 @@ static int dma_xilinx_axi_dma_start(const struct device *dev, uint32_t channel) (uint32_t)(uintptr_t)current_descriptor); #endif - dma_xilinx_axi_dma_enable_cache(); - dma_xilinx_axi_dma_unlock_irq(cfg, channel, irq_key); /* commit stores before returning to caller */ @@ -658,17 +652,33 @@ static inline int dma_xilinx_axi_dma_transfer_block(const struct dma_xilinx_axi_ current_descriptor = &channel_data->descriptors[next_desc_index]; - dma_xilinx_axi_dma_disable_cache(); - + dma_xilinx_axi_dma_invd_dcache((void *)current_descriptor, sizeof(*current_descriptor)); if (current_descriptor->control || current_descriptor->status) { /* Do not overwrite this descriptor as it has not been completed yet. */ LOG_WRN("Descriptor %" PRIu32 " is not yet completed, not starting new transfer!", next_desc_index); - dma_xilinx_axi_dma_enable_cache(); dma_xilinx_axi_dma_unlock_irq(cfg, channel, irq_key); return -EBUSY; } + if (channel == XILINX_AXI_DMA_TX_CHANNEL_NUM) { + /* Ensure DMA can see contents of TX buffer */ + dma_xilinx_axi_dma_flush_dcache((void *)buffer_addr, block_size); + } else { +#ifdef CONFIG_DMA_XILINX_AXI_DMA_DISABLE_CACHE_WHEN_ACCESSING_SG_DESCRIPTORS + if (((uintptr_t)buffer_addr & (sys_cache_data_line_size_get() - 1)) || + (block_size & (sys_cache_data_line_size_get() - 1))) { + LOG_ERR("RX buffer address and block size must be cache line size aligned"); + dma_xilinx_axi_dma_unlock_irq(cfg, channel, irq_key); + return -EINVAL; + } +#endif + /* Invalidate before starting the read, to ensure the CPU does not + * try to write back data to the buffer and clobber the DMA transfer. + */ + dma_xilinx_axi_dma_invd_dcache((void *)buffer_addr, block_size); + } + #ifdef CONFIG_DMA_64BIT current_descriptor->buffer_address = (uint32_t)buffer_addr & 0xffffffff; current_descriptor->buffer_address_msb = (uint32_t)(buffer_addr >> 32); @@ -680,7 +690,6 @@ static inline int dma_xilinx_axi_dma_transfer_block(const struct dma_xilinx_axi_ if (block_size > UINT32_MAX) { LOG_ERR("Too large block: %zu bytes!", block_size); - dma_xilinx_axi_dma_enable_cache(); dma_xilinx_axi_dma_unlock_irq(cfg, channel, irq_key); return -EINVAL; @@ -699,8 +708,7 @@ static inline int dma_xilinx_axi_dma_transfer_block(const struct dma_xilinx_axi_ /* SG descriptor must be completed BEFORE hardware is made aware of it */ barrier_dmem_fence_full(); - - dma_xilinx_axi_dma_enable_cache(); + dma_xilinx_axi_dma_flush_dcache((void *)current_descriptor, sizeof(*current_descriptor)); channel_data->populated_desc_index = next_desc_index; @@ -780,8 +788,6 @@ static int dma_xilinx_axi_dma_configure(const struct device *dev, uint32_t chann return -ENOTSUP; } - dma_xilinx_axi_dma_disable_cache(); - LOG_DBG("Configuring %zu DMA descriptors for %s", data->channels[channel].num_descriptors, channel == XILINX_AXI_DMA_TX_CHANNEL_NUM ? "TX" : "RX"); @@ -814,10 +820,10 @@ static int dma_xilinx_axi_dma_configure(const struct device *dev, uint32_t chann high_bytes = (uint32_t)(((uint64_t)nextdesc >> 32) & 0xffffffff); data->channels[channel].descriptors[i].nxtdesc_msb = high_bytes; #endif + dma_xilinx_axi_dma_flush_dcache((void *)&data->channels[channel].descriptors[i], + sizeof(data->channels[channel].descriptors[i])); } - dma_xilinx_axi_dma_enable_cache(); - #ifdef CONFIG_DMA_64BIT dma_xilinx_axi_dma_write_reg( &data->channels[channel], XILINX_AXI_DMA_REG_CURDESC, From 0345fc9d2a47c408feea8f23fa1905bff42335e1 Mon Sep 17 00:00:00 2001 From: Robert Hancock Date: Thu, 20 Feb 2025 13:30:26 -0600 Subject: [PATCH 2028/3659] drivers: dma: dma_xilinx_axi_dma: Fix up IRQ locking The way the driver was storing IRQ numbers for later use in the various locking modes was not correct, causing the wrong IRQs to potentially be disabled/enabled in some modes. Refactor the way this is done to be cleaner, and also the way the different locking modes are implemented in order to ensure that all modes receive compile test coverage. Also, ensure that the IRQ for the RX or TX channel is always disabled during the execution of the corresponding ISR, to prevent it from being preempted by itself if the DMA core raises another interrupt during the ISR execution. Signed-off-by: Robert Hancock --- drivers/dma/dma_xilinx_axi_dma.c | 186 ++++++++++++++----------------- 1 file changed, 82 insertions(+), 104 deletions(-) diff --git a/drivers/dma/dma_xilinx_axi_dma.c b/drivers/dma/dma_xilinx_axi_dma.c index 22de0ca1dbba..8ec7b404e4e4 100644 --- a/drivers/dma/dma_xilinx_axi_dma.c +++ b/drivers/dma/dma_xilinx_axi_dma.c @@ -190,14 +190,14 @@ enum dma_xilinx_axi_dma_register { #define XILINX_AXI_DMA_MM2S_REG_OFFSET 0x00 #define XILINX_AXI_DMA_S2MM_REG_OFFSET 0x30 +struct dma_xilinx_axi_dma_data; + /* global configuration per DMA device */ struct dma_xilinx_axi_dma_config { mm_reg_t reg; /* this should always be 2 - one for TX, one for RX */ uint32_t channels; - void (*irq_configure)(); - uint32_t *irq0_channels; - size_t irq0_channels_size; + void (*irq_configure)(struct dma_xilinx_axi_dma_data *data); }; typedef void (*dma_xilinx_axi_dma_isr_t)(const struct device *dev); @@ -216,6 +216,8 @@ struct dma_xilinx_axi_dma_channel { mm_reg_t channel_regs; + uint32_t irq; + enum dma_channel_direction direction; /* call this when the transfer is complete */ @@ -234,82 +236,59 @@ struct dma_xilinx_axi_dma_data { struct dma_xilinx_axi_dma_channel *channels; }; -#ifdef CONFIG_DMA_XILINX_AXI_DMA_LOCK_ALL_IRQS -static inline int dma_xilinx_axi_dma_lock_irq(const struct dma_xilinx_axi_dma_config *cfg, - const uint32_t channel_num) -{ - (void)cfg; - (void)channel_num; - return irq_lock(); -} - -static inline void dma_xilinx_axi_dma_unlock_irq(const struct dma_xilinx_axi_dma_config *cfg, - const uint32_t channel_num, int key) -{ - (void)cfg; - (void)channel_num; - return irq_unlock(key); -} -#elif defined(CONFIG_DMA_XILINX_AXI_DMA_LOCK_DMA_IRQS) -static inline int dma_xilinx_axi_dma_lock_irq(const struct dma_xilinx_axi_dma_config *cfg, - const uint32_t channel_num) +static inline int dma_xilinx_axi_dma_lock_irq(const struct device *dev, const uint32_t channel_num) { + const struct dma_xilinx_axi_dma_data *data = dev->data; int ret; - (void)channel_num; - - /* TX is 0, RX is 1 */ - ret = irq_is_enabled(cfg->irq0_channels[0]) ? 1 : 0; - ret |= (irq_is_enabled(cfg->irq0_channels[1]) ? 1 : 0) << 1; - LOG_DBG("DMA IRQ state: %x TX IRQN: %" PRIu32 " RX IRQN: %" PRIu32, ret, - cfg->irq0_channels[0], cfg->irq0_channels[1]); + if (IS_ENABLED(CONFIG_DMA_XILINX_AXI_DMA_LOCK_ALL_IRQS)) { + ret = irq_lock(); + } else if (IS_ENABLED(CONFIG_DMA_XILINX_AXI_DMA_LOCK_DMA_IRQS)) { + /* TX is 0, RX is 1 */ + ret = irq_is_enabled(data->channels[0].irq) ? 1 : 0; + ret |= (irq_is_enabled(data->channels[1].irq) ? 1 : 0) << 1; - irq_disable(cfg->irq0_channels[0]); - irq_disable(cfg->irq0_channels[1]); + LOG_DBG("DMA IRQ state: %x TX IRQN: %" PRIu32 " RX IRQN: %" PRIu32, ret, + data->channels[0].irq, data->channels[1].irq); - return ret; -} + irq_disable(data->channels[0].irq); + irq_disable(data->channels[1].irq); + } else { + /* CONFIG_DMA_XILINX_AXI_DMA_LOCK_CHANNEL_IRQ */ + ret = irq_is_enabled(data->channels[channel_num].irq); -static inline void dma_xilinx_axi_dma_unlock_irq(const struct dma_xilinx_axi_dma_config *cfg, - const uint32_t channel_num, int key) -{ - (void)channel_num; + LOG_DBG("DMA IRQ state: %x ", ret); - if (key & 0x1) { - /* TX was enabled */ - irq_enable(cfg->irq0_channels[0]); + irq_disable(data->channels[channel_num].irq); } - if (key & 0x2) { - /* RX was enabled */ - irq_enable(cfg->irq0_channels[1]); - } -} -#elif defined(CONFIG_DMA_XILINX_AXI_DMA_LOCK_CHANNEL_IRQ) -static inline int dma_xilinx_axi_dma_lock_irq(const struct dma_xilinx_axi_dma_config *cfg, - const uint32_t channel_num) -{ - int ret; - - ret = irq_is_enabled(cfg->irq0_channels[channel_num]); - - LOG_DBG("DMA IRQ state: %x ", ret); - - irq_disable(cfg->irq0_channels[channel_num]); return ret; } -static inline void dma_xilinx_axi_dma_unlock_irq(const struct dma_xilinx_axi_dma_config *cfg, +static inline void dma_xilinx_axi_dma_unlock_irq(const struct device *dev, const uint32_t channel_num, int key) { - if (key) { - /* was enabled */ - irq_enable(cfg->irq0_channels[channel_num]); + const struct dma_xilinx_axi_dma_data *data = dev->data; + + if (IS_ENABLED(CONFIG_DMA_XILINX_AXI_DMA_LOCK_ALL_IRQS)) { + irq_unlock(key); + } else if (IS_ENABLED(CONFIG_DMA_XILINX_AXI_DMA_LOCK_DMA_IRQS)) { + if (key & 0x1) { + /* TX was enabled */ + irq_enable(data->channels[0].irq); + } + if (key & 0x2) { + /* RX was enabled */ + irq_enable(data->channels[1].irq); + } + } else { + /* CONFIG_DMA_XILINX_AXI_DMA_LOCK_CHANNEL_IRQ */ + if (key) { + /* was enabled */ + irq_enable(data->channels[channel_num].irq); + } } } -#else -#error "No IRQ strategy selected in Kconfig!" -#endif static void dma_xilinx_axi_dma_write_reg(const struct dma_xilinx_axi_dma_channel *channel_data, enum dma_xilinx_axi_dma_register reg, uint32_t val) @@ -443,7 +422,11 @@ static void dma_xilinx_axi_dma_tx_isr(const struct device *dev) struct dma_xilinx_axi_dma_data *data = dev->data; struct dma_xilinx_axi_dma_channel *channel_data = &data->channels[XILINX_AXI_DMA_TX_CHANNEL_NUM]; - uint32_t dmasr = dma_xilinx_axi_dma_read_reg(channel_data, XILINX_AXI_DMA_REG_DMASR); + const int irq_enabled = irq_is_enabled(channel_data->irq); + uint32_t dmasr; + + irq_disable(channel_data->irq); + dmasr = dma_xilinx_axi_dma_read_reg(channel_data, XILINX_AXI_DMA_REG_DMASR); if (dmasr & XILINX_AXI_DMA_REGS_DMASR_ERR_IRQ) { LOG_ERR("DMA reports TX error, DMASR = 0x%" PRIx32, dmasr); @@ -464,6 +447,9 @@ static void dma_xilinx_axi_dma_tx_isr(const struct device *dev) LOG_DBG("Completed %u TX packets in this ISR!\n", processed_packets); } + if (irq_enabled) { + irq_enable(channel_data->irq); + } } static void dma_xilinx_axi_dma_rx_isr(const struct device *dev) @@ -471,7 +457,11 @@ static void dma_xilinx_axi_dma_rx_isr(const struct device *dev) struct dma_xilinx_axi_dma_data *data = dev->data; struct dma_xilinx_axi_dma_channel *channel_data = &data->channels[XILINX_AXI_DMA_RX_CHANNEL_NUM]; - uint32_t dmasr = dma_xilinx_axi_dma_read_reg(channel_data, XILINX_AXI_DMA_REG_DMASR); + const int irq_enabled = irq_is_enabled(channel_data->irq); + uint32_t dmasr; + + irq_disable(channel_data->irq); + dmasr = dma_xilinx_axi_dma_read_reg(channel_data, XILINX_AXI_DMA_REG_DMASR); if (dmasr & XILINX_AXI_DMA_REGS_DMASR_ERR_IRQ) { LOG_ERR("DMA reports RX error, DMASR = 0x%" PRIx32, dmasr); @@ -492,6 +482,9 @@ static void dma_xilinx_axi_dma_rx_isr(const struct device *dev) LOG_DBG("Cleaned up %u RX packets in this ISR!", processed_packets); } + if (irq_enabled) { + irq_enable(channel_data->irq); + } } #ifdef CONFIG_DMA_64BIT @@ -508,12 +501,12 @@ static int dma_xilinx_axi_dma_start(const struct device *dev, uint32_t channel) volatile struct dma_xilinx_axi_dma_sg_descriptor *current_descriptor; /* running ISR in parallel could cause issues with the metadata */ - const int irq_key = dma_xilinx_axi_dma_lock_irq(cfg, channel); + const int irq_key = dma_xilinx_axi_dma_lock_irq(dev, channel); if (channel >= cfg->channels) { LOG_ERR("Invalid channel %" PRIu32 " - must be < %" PRIu32 "!", channel, cfg->channels); - dma_xilinx_axi_dma_unlock_irq(cfg, channel, irq_key); + dma_xilinx_axi_dma_unlock_irq(dev, channel, irq_key); return -EINVAL; } @@ -570,7 +563,7 @@ static int dma_xilinx_axi_dma_start(const struct device *dev, uint32_t channel) (uint32_t)(uintptr_t)current_descriptor); #endif - dma_xilinx_axi_dma_unlock_irq(cfg, channel, irq_key); + dma_xilinx_axi_dma_unlock_irq(dev, channel, irq_key); /* commit stores before returning to caller */ barrier_dmem_fence_full(); @@ -634,16 +627,16 @@ static int dma_xilinx_axi_dma_get_status(const struct device *dev, uint32_t chan * If is_first or is_last are NOT set, the buffer is considered part of a SG transfer consisting of * multiple blocks. Otherwise, the block is one transfer. */ -static inline int dma_xilinx_axi_dma_transfer_block(const struct dma_xilinx_axi_dma_config *cfg, - uint32_t channel, - struct dma_xilinx_axi_dma_channel *channel_data, +static inline int dma_xilinx_axi_dma_transfer_block(const struct device *dev, uint32_t channel, dma_addr_t buffer_addr, size_t block_size, bool is_first, bool is_last) { + struct dma_xilinx_axi_dma_data *data = dev->data; + struct dma_xilinx_axi_dma_channel *channel_data = &data->channels[channel]; volatile struct dma_xilinx_axi_dma_sg_descriptor *current_descriptor; /* running ISR in parallel could cause issues with the metadata */ - const int irq_key = dma_xilinx_axi_dma_lock_irq(cfg, channel); + const int irq_key = dma_xilinx_axi_dma_lock_irq(dev, channel); size_t next_desc_index = channel_data->populated_desc_index + 1; if (next_desc_index >= channel_data->num_descriptors) { @@ -657,7 +650,7 @@ static inline int dma_xilinx_axi_dma_transfer_block(const struct dma_xilinx_axi_ /* Do not overwrite this descriptor as it has not been completed yet. */ LOG_WRN("Descriptor %" PRIu32 " is not yet completed, not starting new transfer!", next_desc_index); - dma_xilinx_axi_dma_unlock_irq(cfg, channel, irq_key); + dma_xilinx_axi_dma_unlock_irq(dev, channel, irq_key); return -EBUSY; } @@ -669,7 +662,7 @@ static inline int dma_xilinx_axi_dma_transfer_block(const struct dma_xilinx_axi_ if (((uintptr_t)buffer_addr & (sys_cache_data_line_size_get() - 1)) || (block_size & (sys_cache_data_line_size_get() - 1))) { LOG_ERR("RX buffer address and block size must be cache line size aligned"); - dma_xilinx_axi_dma_unlock_irq(cfg, channel, irq_key); + dma_xilinx_axi_dma_unlock_irq(dev, channel, irq_key); return -EINVAL; } #endif @@ -690,7 +683,7 @@ static inline int dma_xilinx_axi_dma_transfer_block(const struct dma_xilinx_axi_ if (block_size > UINT32_MAX) { LOG_ERR("Too large block: %zu bytes!", block_size); - dma_xilinx_axi_dma_unlock_irq(cfg, channel, irq_key); + dma_xilinx_axi_dma_unlock_irq(dev, channel, irq_key); return -EINVAL; } @@ -712,7 +705,7 @@ static inline int dma_xilinx_axi_dma_transfer_block(const struct dma_xilinx_axi_ channel_data->populated_desc_index = next_desc_index; - dma_xilinx_axi_dma_unlock_irq(cfg, channel, irq_key); + dma_xilinx_axi_dma_unlock_irq(dev, channel, irq_key); return 0; } @@ -726,8 +719,6 @@ static inline int dma_xilinx_axi_dma_config_reload(const struct device *dev, uin #endif { const struct dma_xilinx_axi_dma_config *cfg = dev->config; - struct dma_xilinx_axi_dma_data *data = dev->data; - struct dma_xilinx_axi_dma_channel *channel_data = &data->channels[channel]; if (channel >= cfg->channels) { LOG_ERR("Invalid channel %" PRIu32 " - must be < %" PRIu32 "!", channel, @@ -736,8 +727,8 @@ static inline int dma_xilinx_axi_dma_config_reload(const struct device *dev, uin } /* one-block-at-a-time transfer */ return dma_xilinx_axi_dma_transfer_block( - cfg, channel, channel_data, channel == XILINX_AXI_DMA_TX_CHANNEL_NUM ? src : dst, - size, true, true); + dev, channel, channel == XILINX_AXI_DMA_TX_CHANNEL_NUM ? src : dst, size, true, + true); } static int dma_xilinx_axi_dma_configure(const struct device *dev, uint32_t channel, @@ -873,7 +864,7 @@ static int dma_xilinx_axi_dma_configure(const struct device *dev, uint32_t chann do { ret = ret || - dma_xilinx_axi_dma_transfer_block(cfg, channel, &data->channels[channel], + dma_xilinx_axi_dma_transfer_block(dev, channel, channel == XILINX_AXI_DMA_TX_CHANNEL_NUM ? current_block->source_address : current_block->dest_address, @@ -958,42 +949,29 @@ static int dma_xilinx_axi_dma_init(const struct device *dev) return -EIO; } - cfg->irq_configure(); + cfg->irq_configure(data); return 0; } -/* first IRQ is TX */ -#define TX_IRQ_CONFIGURE(inst) \ - IRQ_CONNECT(DT_INST_IRQN_BY_IDX(inst, 0), DT_INST_IRQ_BY_IDX(inst, 0, priority), \ - dma_xilinx_axi_dma_tx_isr, DEVICE_DT_INST_GET(inst), 0); \ - irq_enable(DT_INST_IRQN_BY_IDX(inst, 0)); -/* second IRQ is RX */ -#define RX_IRQ_CONFIGURE(inst) \ - IRQ_CONNECT(DT_INST_IRQN_BY_IDX(inst, 1), DT_INST_IRQ_BY_IDX(inst, 1, priority), \ - dma_xilinx_axi_dma_rx_isr, DEVICE_DT_INST_GET(inst), 0); \ - irq_enable(DT_INST_IRQN_BY_IDX(inst, 1)); - -#define CONFIGURE_ALL_IRQS(inst) \ - TX_IRQ_CONFIGURE(inst); \ - RX_IRQ_CONFIGURE(inst); - #define XILINX_AXI_DMA_INIT(inst) \ - static void dma_xilinx_axi_dma##inst##_irq_configure(void) \ + static void dma_xilinx_axi_dma##inst##_irq_configure(struct dma_xilinx_axi_dma_data *data) \ { \ - CONFIGURE_ALL_IRQS(inst); \ + data->channels[XILINX_AXI_DMA_TX_CHANNEL_NUM].irq = DT_INST_IRQN_BY_IDX(inst, 0); \ + IRQ_CONNECT(DT_INST_IRQN_BY_IDX(inst, 0), DT_INST_IRQ_BY_IDX(inst, 0, priority), \ + dma_xilinx_axi_dma_tx_isr, DEVICE_DT_INST_GET(inst), 0); \ + irq_enable(DT_INST_IRQN_BY_IDX(inst, 0)); \ + data->channels[XILINX_AXI_DMA_RX_CHANNEL_NUM].irq = DT_INST_IRQN_BY_IDX(inst, 1); \ + IRQ_CONNECT(DT_INST_IRQN_BY_IDX(inst, 1), DT_INST_IRQ_BY_IDX(inst, 1, priority), \ + dma_xilinx_axi_dma_rx_isr, DEVICE_DT_INST_GET(inst), 0); \ + irq_enable(DT_INST_IRQN_BY_IDX(inst, 1)); \ } \ - static uint32_t dma_xilinx_axi_dma##inst##_irq0_channels[] = \ - DT_INST_PROP_OR(inst, interrupts, {0}); \ static const struct dma_xilinx_axi_dma_config dma_xilinx_axi_dma##inst##_config = { \ .reg = DT_INST_REG_ADDR(inst), \ .channels = DT_INST_PROP(inst, dma_channels), \ .irq_configure = dma_xilinx_axi_dma##inst##_irq_configure, \ - .irq0_channels = dma_xilinx_axi_dma##inst##_irq0_channels, \ - .irq0_channels_size = ARRAY_SIZE(dma_xilinx_axi_dma##inst##_irq0_channels), \ }; \ static struct dma_xilinx_axi_dma_channel \ dma_xilinx_axi_dma##inst##_channels[DT_INST_PROP(inst, dma_channels)]; \ - ATOMIC_DEFINE(dma_xilinx_axi_dma_atomic##inst, DT_INST_PROP(inst, dma_channels)); \ static struct dma_xilinx_axi_dma_data dma_xilinx_axi_dma##inst##_data = { \ .ctx = {.magic = DMA_MAGIC, .atomic = NULL}, \ .channels = dma_xilinx_axi_dma##inst##_channels, \ From 8b287a6a7425d9dd04599489a64370669ad8fca9 Mon Sep 17 00:00:00 2001 From: Robert Hancock Date: Thu, 6 Mar 2025 11:41:33 -0600 Subject: [PATCH 2029/3659] drivers: dma: dma_xilinx_axi_dma: Make descriptors per-instance Move the descriptor storage into the per-instance data structure rather than being global, as they should not be shared between instances. Signed-off-by: Robert Hancock --- drivers/dma/dma_xilinx_axi_dma.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/drivers/dma/dma_xilinx_axi_dma.c b/drivers/dma/dma_xilinx_axi_dma.c index 8ec7b404e4e4..69d52d41b917 100644 --- a/drivers/dma/dma_xilinx_axi_dma.c +++ b/drivers/dma/dma_xilinx_axi_dma.c @@ -165,11 +165,6 @@ struct __attribute__((__packed__)) dma_xilinx_axi_dma_sg_descriptor { uint32_t app4; } __aligned(64); -__aligned(64) static struct dma_xilinx_axi_dma_sg_descriptor - descriptors_tx[CONFIG_DMA_XILINX_AXI_DMA_SG_DESCRIPTOR_NUM_TX] = {0}; -__aligned(64) static struct dma_xilinx_axi_dma_sg_descriptor - descriptors_rx[CONFIG_DMA_XILINX_AXI_DMA_SG_DESCRIPTOR_NUM_RX] = {0}; - enum dma_xilinx_axi_dma_register { /* DMA control register */ /* bitfield, masks defined above */ @@ -234,6 +229,11 @@ struct dma_xilinx_axi_dma_channel { struct dma_xilinx_axi_dma_data { struct dma_context ctx; struct dma_xilinx_axi_dma_channel *channels; + + __aligned(64) struct dma_xilinx_axi_dma_sg_descriptor + descriptors_tx[CONFIG_DMA_XILINX_AXI_DMA_SG_DESCRIPTOR_NUM_TX]; + __aligned(64) struct dma_xilinx_axi_dma_sg_descriptor + descriptors_rx[CONFIG_DMA_XILINX_AXI_DMA_SG_DESCRIPTOR_NUM_RX]; }; static inline int dma_xilinx_axi_dma_lock_irq(const struct device *dev, const uint32_t channel_num) @@ -916,14 +916,16 @@ static int dma_xilinx_axi_dma_init(const struct device *dev) return -EINVAL; } - data->channels[XILINX_AXI_DMA_TX_CHANNEL_NUM].descriptors = descriptors_tx; - data->channels[XILINX_AXI_DMA_TX_CHANNEL_NUM].num_descriptors = ARRAY_SIZE(descriptors_tx); + data->channels[XILINX_AXI_DMA_TX_CHANNEL_NUM].descriptors = data->descriptors_tx; + data->channels[XILINX_AXI_DMA_TX_CHANNEL_NUM].num_descriptors = + ARRAY_SIZE(data->descriptors_tx); data->channels[XILINX_AXI_DMA_TX_CHANNEL_NUM].channel_regs = cfg->reg + XILINX_AXI_DMA_MM2S_REG_OFFSET; data->channels[XILINX_AXI_DMA_TX_CHANNEL_NUM].direction = MEMORY_TO_PERIPHERAL; - data->channels[XILINX_AXI_DMA_RX_CHANNEL_NUM].descriptors = descriptors_rx; - data->channels[XILINX_AXI_DMA_RX_CHANNEL_NUM].num_descriptors = ARRAY_SIZE(descriptors_rx); + data->channels[XILINX_AXI_DMA_RX_CHANNEL_NUM].descriptors = data->descriptors_rx; + data->channels[XILINX_AXI_DMA_RX_CHANNEL_NUM].num_descriptors = + ARRAY_SIZE(data->descriptors_rx); data->channels[XILINX_AXI_DMA_RX_CHANNEL_NUM].channel_regs = cfg->reg + XILINX_AXI_DMA_S2MM_REG_OFFSET; data->channels[XILINX_AXI_DMA_RX_CHANNEL_NUM].direction = PERIPHERAL_TO_MEMORY; From 5cfcbf2e871b386241a856f8ce8821aa8d60d411 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Fri, 14 Nov 2025 07:30:40 +0100 Subject: [PATCH 2030/3659] drivers: counter: nrfx_timer: Optimize interrupt handler MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Check only events which have interrupt enabled. Signed-off-by: Krzysztof Chruściński --- drivers/counter/counter_nrfx_timer.c | 74 ++++++++++------------------ 1 file changed, 27 insertions(+), 47 deletions(-) diff --git a/drivers/counter/counter_nrfx_timer.c b/drivers/counter/counter_nrfx_timer.c index 1a614b391c06..81e2210ea343 100644 --- a/drivers/counter/counter_nrfx_timer.c +++ b/drivers/counter/counter_nrfx_timer.c @@ -143,7 +143,7 @@ static void set_cc_int_pending(const struct device *dev, uint8_t chan) const struct counter_nrfx_config *config = dev->config; struct counter_nrfx_data *data = dev->data; - atomic_or(&data->cc_int_pending, BIT(chan)); + atomic_or(&data->cc_int_pending, BIT(chan + TIMER_INTENSET_COMPARE0_Pos)); NRFX_IRQ_PENDING_SET(NRFX_IRQ_NUMBER_GET(config->timer)); } @@ -345,66 +345,46 @@ static int set_guard_period(const struct device *dev, uint32_t guard, return 0; } -static void top_irq_handle(const struct device *dev) +static void alarm_handle(const struct device *dev, uint32_t ch, uint32_t cc_val) { const struct counter_nrfx_config *config = dev->config; - struct counter_nrfx_data *data = dev->data; - - NRF_TIMER_Type *reg = config->timer; - counter_top_callback_t cb = data->top_cb; + counter_alarm_callback_t cb = config->ch_data[ch].callback; - if (nrf_timer_event_check(reg, COUNTER_TOP_EVT) && - nrf_timer_int_enable_check(reg, COUNTER_TOP_INT_MASK)) { - nrf_timer_event_clear(reg, COUNTER_TOP_EVT); - __ASSERT(cb != NULL, "top event enabled - expecting callback"); - cb(dev, data->top_user_data); + config->ch_data[ch].callback = NULL; + if (cb) { + cb(dev, ch, cc_val, config->ch_data[ch].user_data); } } -static void alarm_irq_handle(const struct device *dev, uint32_t id) +static void irq_handler(const void *arg) { + const struct device *dev = arg; const struct counter_nrfx_config *config = dev->config; struct counter_nrfx_data *data = dev->data; - - uint32_t cc = ID_TO_CC(id); NRF_TIMER_Type *reg = config->timer; - uint32_t int_mask = nrf_timer_compare_int_get(cc); - nrf_timer_event_t evt = nrf_timer_compare_event_get(cc); - bool hw_irq_pending = nrf_timer_event_check(reg, evt) && - nrf_timer_int_enable_check(reg, int_mask); - bool sw_irq_pending = data->cc_int_pending & BIT(cc); - - if (hw_irq_pending || sw_irq_pending) { - struct counter_nrfx_ch_data *chdata; - counter_alarm_callback_t cb; - - nrf_timer_event_clear(reg, evt); - atomic_and(&data->cc_int_pending, ~BIT(cc)); - nrf_timer_int_disable(reg, int_mask); - - chdata = &config->ch_data[id]; - cb = chdata->callback; - chdata->callback = NULL; - - if (cb) { - uint32_t cc_val = nrf_timer_cc_get(reg, cc); - - cb(dev, id, cc_val, chdata->user_data); + uint32_t int_en_mask = nrf_timer_int_enable_check(reg, UINT32_MAX); + uint32_t int_sw_pending = atomic_set(&data->cc_int_pending, 0); + uint32_t idx, ch; + nrf_timer_event_t event; + + int_en_mask |= int_sw_pending; + while (int_en_mask) { + idx = __builtin_ctz(int_en_mask); + event = (nrf_timer_event_t)NRFY_INT_BITPOS_TO_EVENT(idx); + int_en_mask &= ~BIT(idx); + ch = idx - TIMER_INTENSET_COMPARE0_Pos; + if (nrf_timer_event_check(reg, event) || (int_sw_pending & BIT(idx))) { + nrf_timer_event_clear(reg, event); + if (ch == TOP_CH) { + data->top_cb(dev, data->top_user_data); + } else { + nrf_timer_int_disable(reg, BIT(idx)); + alarm_handle(dev, CC_TO_ID(ch), nrf_timer_cc_get(reg, ch)); + } } } } -static void irq_handler(const void *arg) -{ - const struct device *dev = arg; - - top_irq_handle(dev); - - for (uint32_t i = 0; i < counter_get_num_of_channels(dev); i++) { - alarm_irq_handle(dev, i); - } -} - static DEVICE_API(counter, counter_nrfx_driver_api) = { .start = start, .stop = stop, From 85446aafd71302e80f05e27c60ab141ef6d7628a Mon Sep 17 00:00:00 2001 From: Can Wang Date: Wed, 31 Dec 2025 14:43:34 +0800 Subject: [PATCH 2031/3659] Bluetooth: OBEX: add bt_obex_has_app_param helper function Add a new helper function bt_obex_has_app_param() to check whether a specific application parameter tag exists in the OBEX buffer. The function uses the existing bt_obex_get_header_app_param() to retrieve the application parameters, then parses them using bt_obex_tlv_parse() with a callback to search for the specified tag ID. This simplifies checking for the presence of application parameters without needing to manually parse the TLV structure. Signed-off-by: Can Wang --- include/zephyr/bluetooth/classic/obex.h | 9 ++++++ subsys/bluetooth/host/classic/obex.c | 41 +++++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/include/zephyr/bluetooth/classic/obex.h b/include/zephyr/bluetooth/classic/obex.h index cb4ddf01719f..a5dd9d9e4e9a 100644 --- a/include/zephyr/bluetooth/classic/obex.h +++ b/include/zephyr/bluetooth/classic/obex.h @@ -1745,6 +1745,15 @@ bool bt_obex_string_is_valid(uint8_t id, uint16_t len, const uint8_t *str); */ bool bt_obex_has_header(struct net_buf *buf, uint8_t id); +/** @brief Check whether the buf has the specified application parameter + * + * @param buf Buffer needs to be sent. + * @param id The tag id of the application parameter. + * + * @return true if the tag is found or false otherwise. + */ +bool bt_obex_has_app_param(struct net_buf *buf, uint8_t id); + #ifdef __cplusplus } #endif diff --git a/subsys/bluetooth/host/classic/obex.c b/subsys/bluetooth/host/classic/obex.c index db2f3e00e230..86aea5a5b909 100644 --- a/subsys/bluetooth/host/classic/obex.c +++ b/subsys/bluetooth/host/classic/obex.c @@ -3647,6 +3647,47 @@ int bt_obex_get_header_app_param(struct net_buf *buf, uint16_t *len, const uint8 return 0; } +struct bt_obex_has_app_param { + uint8_t id; + bool found; +}; + +static bool bt_obex_has_app_param_cb(struct bt_obex_tlv *tlv, void *user_data) +{ + struct bt_obex_has_app_param *data = user_data; + + if (tlv->type == data->id) { + data->found = true; + return false; + } + return true; +} + +bool bt_obex_has_app_param(struct net_buf *buf, uint8_t id) +{ + struct bt_obex_has_app_param ap; + uint16_t len = 0; + const uint8_t *data = NULL; + int err; + + if (bt_obex_get_header_app_param(buf, &len, &data) != 0) { + return false; + } + if (len == 0U || data == NULL) { + return false; + } + + ap.id = id; + ap.found = false; + + err = bt_obex_tlv_parse(len, data, bt_obex_has_app_param_cb, &ap); + if (err != 0) { + return false; + } + + return ap.found; +} + int bt_obex_get_header_auth_challenge(struct net_buf *buf, uint16_t *len, const uint8_t **auth) { struct bt_obex_find_header_data data; From 3138be0b08ced5a41f098698778aca0eb557ed52 Mon Sep 17 00:00:00 2001 From: Can Wang Date: Wed, 31 Dec 2025 14:48:47 +0800 Subject: [PATCH 2032/3659] Bluetooth: OBEX: allow zero-length body in End-of-Body header According to OBEX Version 1.5, section 2.2.9, it is legal to send a zero-length End-of-Body header when object body data is generated on the fly and the end cannot be anticipated. Update parameter validation in bt_obex_add_header_body_or_end_body() and bt_obex_add_header_end_body() to allow NULL body pointer when length is zero, while still rejecting NULL body with non-zero length. This enables proper support for zero-length End-of-Body headers as specified in the OBEX specification. Signed-off-by: Can Wang --- include/zephyr/bluetooth/classic/obex.h | 10 ++++++++-- subsys/bluetooth/host/classic/obex.c | 8 +++++++- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/include/zephyr/bluetooth/classic/obex.h b/include/zephyr/bluetooth/classic/obex.h index a5dd9d9e4e9a..5215f649d0ab 100644 --- a/include/zephyr/bluetooth/classic/obex.h +++ b/include/zephyr/bluetooth/classic/obex.h @@ -1177,8 +1177,14 @@ static inline int bt_obex_add_header_body_or_end_body(struct net_buf *buf, uint1 uint16_t tx_len; int err; - if ((buf == NULL) || (body == NULL) || (added_len == NULL) || (mopl < BT_OBEX_MIN_MTU) || - (len == 0)) { + /* + * OBEX Version 1.5, section 2.2.9 Body, End-of-Body + * The `body` could be a NULL, so the `len` of the name could 0. + * In some cases, the object body data is generated on the fly and the end cannot + * be anticipated, so it is legal to send a zero length End-of-Body header. + */ + if ((buf == NULL) || ((len != 0) && (body == NULL)) || (added_len == NULL) || + (mopl < BT_OBEX_MIN_MTU)) { return -EINVAL; } diff --git a/subsys/bluetooth/host/classic/obex.c b/subsys/bluetooth/host/classic/obex.c index 86aea5a5b909..ad5f5b8d57d9 100644 --- a/subsys/bluetooth/host/classic/obex.c +++ b/subsys/bluetooth/host/classic/obex.c @@ -2757,7 +2757,13 @@ int bt_obex_add_header_end_body(struct net_buf *buf, uint16_t len, const uint8_t { size_t total; - if (!buf || !body || !len) { + /* + * OBEX Version 1.5, section 2.2.9 Body, End-of-Body + * The `body` could be a NULL, so the `len` of the name could 0. + * In some cases, the object body data is generated on the fly and the end cannot + * be anticipated, so it is legal to send a zero length End-of-Body header. + */ + if ((buf == NULL) || ((len != 0) && (body == NULL))) { LOG_WRN("Invalid parameter"); return -EINVAL; } From 40931508ca9e1cfb0f856de29e0f9aa1f8a6ceda Mon Sep 17 00:00:00 2001 From: Can Wang Date: Wed, 31 Dec 2025 14:50:30 +0800 Subject: [PATCH 2033/3659] Bluetooth: OBEX: fix incorrect error code in obex_transport_disconn The function obex_transport_disconn() was always returning -EINVAL regardless of the actual error code returned by the transport disconnect operation. Fix this by returning the actual error code from the transport disconnect call instead of the hardcoded -EINVAL value. Signed-off-by: Can Wang --- subsys/bluetooth/host/classic/obex.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/bluetooth/host/classic/obex.c b/subsys/bluetooth/host/classic/obex.c index ad5f5b8d57d9..54e25f15f7c4 100644 --- a/subsys/bluetooth/host/classic/obex.c +++ b/subsys/bluetooth/host/classic/obex.c @@ -76,7 +76,7 @@ static int obex_transport_disconn(struct bt_obex *obex) if (err) { LOG_ERR("Fail to disconnect transport (err %d)", err); } - return -EINVAL; + return err; } struct bt_obex_has_header { From d9a5b9cc4a5baa64187d0d986184e032368bde7c Mon Sep 17 00:00:00 2001 From: Can Wang Date: Fri, 16 Jan 2026 17:09:39 +0800 Subject: [PATCH 2034/3659] Bluetooth: OBEX: add setpath flags enum Add documentation for the setpath flags parameter by defining a new enum bt_obex_setpath_flags that describes the available flags: - BT_OBEX_SETPATH_FLAG_BACKUP: backup a level before applying name - BT_OBEX_SETPATH_FLAG_NO_CREATE: don't create folder if it doesn't exist Update the documentation for bt_obex_setpath() and the setpath callback in bt_obex_server_ops to reference the new enum, improving clarity for users of the OBEX setpath operation. Signed-off-by: Can Wang --- include/zephyr/bluetooth/classic/obex.h | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/include/zephyr/bluetooth/classic/obex.h b/include/zephyr/bluetooth/classic/obex.h index 5215f649d0ab..c7c3737cda85 100644 --- a/include/zephyr/bluetooth/classic/obex.h +++ b/include/zephyr/bluetooth/classic/obex.h @@ -310,7 +310,7 @@ struct bt_obex_server_ops { * received. * * @param server The OBEX server object. - * @param flags The flags. + * @param flags The flags @ref bt_obex_setpath_flags. * @param buf Optional headers. */ void (*setpath)(struct bt_obex_server *server, uint8_t flags, struct net_buf *buf); @@ -883,6 +883,14 @@ int bt_obex_abort(struct bt_obex_client *client, struct net_buf *buf); */ int bt_obex_abort_rsp(struct bt_obex_server *server, uint8_t rsp_code, struct net_buf *buf); +/** @brief OBEX SetPath operation flags. */ +enum __packed bt_obex_setpath_flags { + /** Backup a level before applying name (equivalent to ../ on many systems). */ + BT_OBEX_SETPATH_FLAG_BACKUP = BIT(0U), + /** Don't create folder if it does not exist, return an error instead. */ + BT_OBEX_SETPATH_FLAG_NO_CREATE = BIT(1U), +}; + /** @brief OBEX setpath request * * The setpath request is used to set the "current folder" on the receiving side in order to @@ -909,7 +917,7 @@ int bt_obex_abort_rsp(struct bt_obex_server *server, uint8_t rsp_code, struct ne * the caller retains the ownership of the buffer. * * @param client OBEX client object. - * @param flags Flags for setpath request. + * @param flags Flags for setpath request @ref bt_obex_setpath_flags. * @param buf Sequence of headers to be sent out. * * @return 0 in case of success or negative value in case of error. From f9444d2d8081d4306a442f43bd9711c0303b9f63 Mon Sep 17 00:00:00 2001 From: Holt Sun Date: Mon, 5 Jan 2026 20:55:52 +0800 Subject: [PATCH 2035/3659] drivers: timer: cortex_m_systick: fix LPM entry with RESET_BY_LPM Clear pending SysTick interrupt before entering low-power mode when CONFIG_CORTEX_M_SYSTICK_RESET_BY_LPM is enabled. A pending interrupt can inhibit LPM entry or cause immediate wakeup. This is safe since cycle_count was already updated. Also improve RESET_BY_LPM Kconfig help text. Signed-off-by: Holt Sun --- drivers/timer/Kconfig.cortex_m_systick | 8 +++++--- drivers/timer/cortex_m_systick.c | 11 +++++++++++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/drivers/timer/Kconfig.cortex_m_systick b/drivers/timer/Kconfig.cortex_m_systick index d9128efdeaec..789afd40e642 100644 --- a/drivers/timer/Kconfig.cortex_m_systick +++ b/drivers/timer/Kconfig.cortex_m_systick @@ -105,8 +105,10 @@ config CORTEX_M_SYSTICK_RESET_BY_LPM special care from the driver - notably, SysTick needs to be restarted after waking up from such a low-power mode. - Select this symbol if your SoC has a low-power mode that places SysTick - under reset. Note that this requires that the platform provides a timer - active in low-power mode, since SysTick cannot be used for timekeeping. + Select this option if your SoC has at least one such low-power mode with + its corresponding "zephyr,power-state" node enabled (i.e., if the system + may enter in a low-power mode that resets SysTick). Note that a low-power + mode timer must be provided by the platform in such configurations since + SysTick cannot be reliably used for timekeeping. Refer to CONFIG_CORTEX_M_SYSTICK_LPM_TIMER for more details. diff --git a/drivers/timer/cortex_m_systick.c b/drivers/timer/cortex_m_systick.c index c827d7a0dd15..c3172b045fa5 100644 --- a/drivers/timer/cortex_m_systick.c +++ b/drivers/timer/cortex_m_systick.c @@ -384,6 +384,17 @@ void sys_clock_set_timeout(int32_t ticks, bool idle) * to it after waking up. */ sys_clock_disable(); + /* Ensure the SysTick interrupt is not pending. This is safe + * as we just did the ISR's job, and MUST be done because + * a pending interrupt could inhibit low-power mode entry. + * Note: On Armv8-M, ICSR.STTNS is R/W, so preserve it while + * writing the write-1-to-clear PENDSTCLR bit. + */ +#ifdef SCB_ICSR_STTNS_Msk + SCB->ICSR = (SCB->ICSR & SCB_ICSR_STTNS_Msk) | SCB_ICSR_PENDSTCLR_Msk; +#else + SCB->ICSR = SCB_ICSR_PENDSTCLR_Msk; +#endif cycle_count += elapsed(); overflow_cyc = 0; From 2f3b4a461194828f1b06e263ef3019761809b038 Mon Sep 17 00:00:00 2001 From: Holt Sun Date: Mon, 5 Jan 2026 21:08:29 +0800 Subject: [PATCH 2036/3659] drivers: timer: cortex_m_systick: fix counter read order on LPM exit Read the idle timer counter value after getting interrupt status and top value to ensure more accurate timing measurements when exiting low-power mode. Signed-off-by: Holt Sun --- drivers/timer/cortex_m_systick.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/timer/cortex_m_systick.c b/drivers/timer/cortex_m_systick.c index c3172b045fa5..cc06e04db879 100644 --- a/drivers/timer/cortex_m_systick.c +++ b/drivers/timer/cortex_m_systick.c @@ -176,9 +176,9 @@ uint64_t z_cms_lptim_hook_on_lpm_exit(void) uint32_t idle_timer_post, idle_timer_diff, idle_timer_top; bool idle_timer_int_pending, idle_timer_wrap; - counter_get_value(idle_timer, &idle_timer_post); idle_timer_int_pending = counter_get_pending_int(idle_timer) ? true : false; idle_timer_top = counter_get_top_value(idle_timer); + counter_get_value(idle_timer, &idle_timer_post); /** * Check for counter timer overflow From 6fc50ff4f00a6b07acb58d26fd98c8f428699d25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fin=20Maa=C3=9F?= Date: Wed, 14 Jan 2026 13:46:59 +0100 Subject: [PATCH 2037/3659] drivers: ethernet: litex: remove redunant tx mutex MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit remove redunant tx mutex, as the networking subsystem already provides one since 61c392c5b13fbc448ca0e4c047848c72c3096a07 Signed-off-by: Fin Maaß --- drivers/ethernet/eth_litex_liteeth.c | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/drivers/ethernet/eth_litex_liteeth.c b/drivers/ethernet/eth_litex_liteeth.c index 810009930b1c..93efd81498cf 100644 --- a/drivers/ethernet/eth_litex_liteeth.c +++ b/drivers/ethernet/eth_litex_liteeth.c @@ -35,7 +35,6 @@ struct eth_litex_dev_data { struct net_if *iface; uint8_t mac_addr[6]; uint8_t txslot; - struct k_mutex tx_mutex; struct k_sem sem_tx_ready; }; @@ -64,7 +63,6 @@ static int eth_initialize(const struct device *dev) const struct eth_litex_config *config = dev->config; struct eth_litex_dev_data *context = dev->data; - k_mutex_init(&context->tx_mutex); k_sem_init(&context->sem_tx_ready, 1, 1); config->config_func(dev); @@ -81,8 +79,6 @@ static int eth_tx(const struct device *dev, struct net_pkt *pkt) const struct eth_litex_config *config = dev->config; int ret; - k_mutex_lock(&context->tx_mutex, K_FOREVER); - /* get data from packet and send it */ len = net_pkt_get_len(pkt); net_pkt_read(pkt, @@ -95,7 +91,8 @@ static int eth_tx(const struct device *dev, struct net_pkt *pkt) /* wait for the device to be ready to transmit */ ret = k_sem_take(&context->sem_tx_ready, MAX_TX_FAILURE); if (ret < 0) { - goto error; + LOG_ERR("TX fifo failed"); + return -EIO; }; /* start transmitting */ litex_write8(1, config->tx_start_addr); @@ -103,13 +100,7 @@ static int eth_tx(const struct device *dev, struct net_pkt *pkt) /* change slot */ context->txslot = (context->txslot + 1) % config->tx_buf_n; - k_mutex_unlock(&context->tx_mutex); - return 0; -error: - k_mutex_unlock(&context->tx_mutex); - LOG_ERR("TX fifo failed"); - return -EIO; } static void eth_rx(const struct device *port) From 999223f36e313aa95d103d063080ceba602a4475 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fin=20Maa=C3=9F?= Date: Wed, 14 Jan 2026 13:50:38 +0100 Subject: [PATCH 2038/3659] drivers: ethernet: numaker: remove redunant tx mutex MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit remove redunant tx mutex, as the networking subsystem already provides one since 61c392c5b13fbc448ca0e4c047848c72c3096a07 Signed-off-by: Fin Maaß --- drivers/ethernet/eth_numaker.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/ethernet/eth_numaker.c b/drivers/ethernet/eth_numaker.c index 888f9f43dce1..55f6f4cb1cc6 100644 --- a/drivers/ethernet/eth_numaker.c +++ b/drivers/ethernet/eth_numaker.c @@ -66,7 +66,6 @@ struct eth_numaker_data { synopGMACdevice *gmacdev; struct net_if *iface; uint8_t mac_addr[NU_HWADDR_SIZE]; - struct k_mutex tx_frame_buf_mutex; struct k_spinlock rx_frame_buf_lock; }; @@ -478,7 +477,6 @@ static int numaker_eth_tx(const struct device *dev, struct net_pkt *pkt) uint8_t *buffer; /* Get exclusive access */ - k_mutex_lock(&data->tx_frame_buf_mutex, K_FOREVER); if (total_len > NET_ETH_MAX_FRAME_SIZE) { /* NuMaker SDK reserve 2048 for tx_buf */ LOG_ERR("TX packet length [%d] over max [%d]", total_len, NET_ETH_MAX_FRAME_SIZE); @@ -498,13 +496,10 @@ static int numaker_eth_tx(const struct device *dev, struct net_pkt *pkt) /* Prepare transmit descriptors to give to DMA */ m_numaker_gmacdev_trigger_tx(gmacdev, total_len); - k_mutex_unlock(&data->tx_frame_buf_mutex); - return 0; error: LOG_ERR("Writing pkt to TX descriptor failed"); - k_mutex_unlock(&data->tx_frame_buf_mutex); return -EIO; } @@ -720,8 +715,6 @@ static int eth_numaker_init(const struct device *dev) gmacdev = &GMACdev[NUMAKER_GMAC_INTF]; data->gmacdev = gmacdev; - k_mutex_init(&data->tx_frame_buf_mutex); - eth_phy_addr = cfg->phy_addr; /* CLK controller */ From d043dd3cdf81eae46d1d99c48bff8a59bcc261bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fin=20Maa=C3=9F?= Date: Wed, 14 Jan 2026 13:51:49 +0100 Subject: [PATCH 2039/3659] drivers: ethernet: sensry: remove redunant tx mutex MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit remove redunant tx mutex, as the networking subsystem already provides one since 61c392c5b13fbc448ca0e4c047848c72c3096a07 Signed-off-by: Fin Maaß --- drivers/ethernet/eth_sensry_sy1xx_mac.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/drivers/ethernet/eth_sensry_sy1xx_mac.c b/drivers/ethernet/eth_sensry_sy1xx_mac.c index b151ac1773c4..8cc4d7f83184 100644 --- a/drivers/ethernet/eth_sensry_sy1xx_mac.c +++ b/drivers/ethernet/eth_sensry_sy1xx_mac.c @@ -75,8 +75,6 @@ struct sy1xx_mac_dma_buffers { }; struct sy1xx_mac_dev_data { - struct k_mutex mutex; - /* current state of link and mac address */ bool link_is_up; enum phy_link_speed link_speed; @@ -118,8 +116,6 @@ static int sy1xx_mac_initialize(const struct device *dev) data->link_is_up = false; data->link_speed = -1; - k_mutex_init(&data->mutex); - /* PAD config */ ret = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT); if (ret) { @@ -452,8 +448,6 @@ static int sy1xx_mac_send(const struct device *dev, struct net_pkt *pkt) uint32_t retries_left; struct net_buf *frag; - k_mutex_lock(&data->mutex, K_FOREVER); - /* push all fragments of the packet into one linear buffer */ frag = pkt->buffer; data->temp.tx_len = 0; @@ -464,7 +458,6 @@ static int sy1xx_mac_send(const struct device *dev, struct net_pkt *pkt) data->temp.tx[data->temp.tx_len++] = frag->data[i]; } else { LOG_ERR("tx buffer overflow"); - k_mutex_unlock(&data->mutex); return -ENOMEM; } } @@ -481,14 +474,12 @@ static int sy1xx_mac_send(const struct device *dev, struct net_pkt *pkt) } if (ret != -EBUSY) { LOG_ERR("tx error"); - k_mutex_unlock(&data->mutex); return ret; } k_sleep(K_MSEC(1)); retries_left--; }; - k_mutex_unlock(&data->mutex); return ret; } From 77cbd69a3eace505b05eba7ce50f6072e72df659 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fin=20Maa=C3=9F?= Date: Wed, 14 Jan 2026 13:54:18 +0100 Subject: [PATCH 2040/3659] drivers: ethernet: stm32: remove redunant tx mutex MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit remove redunant tx mutex, as the networking subsystem already provides one since 61c392c5b13fbc448ca0e4c047848c72c3096a07 Signed-off-by: Fin Maaß --- drivers/ethernet/eth_stm32_hal_priv.h | 1 - drivers/ethernet/eth_stm32_hal_v1.c | 20 ++++---------------- drivers/ethernet/eth_stm32_hal_v2.c | 9 --------- 3 files changed, 4 insertions(+), 26 deletions(-) diff --git a/drivers/ethernet/eth_stm32_hal_priv.h b/drivers/ethernet/eth_stm32_hal_priv.h index 4586200e3a73..da63b1f2ac6c 100644 --- a/drivers/ethernet/eth_stm32_hal_priv.h +++ b/drivers/ethernet/eth_stm32_hal_priv.h @@ -120,7 +120,6 @@ struct eth_stm32_hal_dev_data { struct net_if *iface; uint8_t mac_addr[6]; ETH_HandleTypeDef heth; - struct k_mutex tx_mutex; struct k_sem rx_int_sem; #if defined(CONFIG_ETH_STM32_HAL_API_V2) struct k_sem tx_int_sem; diff --git a/drivers/ethernet/eth_stm32_hal_v1.c b/drivers/ethernet/eth_stm32_hal_v1.c index be2ad3d32d02..03c911c0794b 100644 --- a/drivers/ethernet/eth_stm32_hal_v1.c +++ b/drivers/ethernet/eth_stm32_hal_v1.c @@ -58,7 +58,6 @@ int eth_stm32_tx(const struct device *dev, struct net_pkt *pkt) { struct eth_stm32_hal_dev_data *dev_data = dev->data; ETH_HandleTypeDef *heth = &dev_data->heth; - int res; size_t total_len; uint8_t *dma_buffer; __IO ETH_DMADescTypeDef *dma_tx_desc; @@ -73,8 +72,6 @@ int eth_stm32_tx(const struct device *dev, struct net_pkt *pkt) return -EIO; } - k_mutex_lock(&dev_data->tx_mutex, K_FOREVER); - dma_tx_desc = heth->TxDesc; while (IS_ETH_DMATXDESC_OWN(dma_tx_desc) != (uint32_t)RESET) { k_yield(); @@ -83,16 +80,14 @@ int eth_stm32_tx(const struct device *dev, struct net_pkt *pkt) dma_buffer = (uint8_t *)(dma_tx_desc->Buffer1Addr); if (net_pkt_read(pkt, dma_buffer, total_len)) { - res = -ENOBUFS; - goto error; + return -ENOBUFS; } hal_ret = HAL_ETH_TransmitFrame(heth, total_len); if (hal_ret != HAL_OK) { LOG_ERR("HAL_ETH_Transmit: failed!"); - res = -EIO; - goto error; + return -EIO; } /* When Transmit Underflow flag is set, clear it and issue a @@ -103,16 +98,10 @@ int eth_stm32_tx(const struct device *dev, struct net_pkt *pkt) heth->Instance->DMASR = ETH_DMASR_TUS; /* Resume DMA transmission*/ heth->Instance->DMATPDR = 0; - res = -EIO; - goto error; + return -EIO; } - res = 0; -error: - - k_mutex_unlock(&dev_data->tx_mutex); - - return res; + return 0; } struct net_pkt *eth_stm32_rx(const struct device *dev) @@ -197,7 +186,6 @@ int eth_stm32_hal_init(const struct device *dev) } /* Initialize semaphores */ - k_mutex_init(&dev_data->tx_mutex); k_sem_init(&dev_data->rx_int_sem, 0, K_SEM_MAX_LIMIT); if (HAL_ETH_DMATxDescListInit(heth, dma_tx_desc_tab, diff --git a/drivers/ethernet/eth_stm32_hal_v2.c b/drivers/ethernet/eth_stm32_hal_v2.c index f075ba2e42dd..f8b83e610693 100644 --- a/drivers/ethernet/eth_stm32_hal_v2.c +++ b/drivers/ethernet/eth_stm32_hal_v2.c @@ -169,8 +169,6 @@ int eth_stm32_tx(const struct device *dev, struct net_pkt *pkt) return -EIO; } - k_mutex_lock(&dev_data->tx_mutex, K_FOREVER); - while (ctx == NULL) { ctx = allocate_tx_context_async(pkt); if (ctx == NULL) { @@ -232,8 +230,6 @@ int eth_stm32_tx(const struct device *dev, struct net_pkt *pkt) HAL_ETH_TxFreeCallback((uint32_t *)ctx); } - k_mutex_unlock(&dev_data->tx_mutex); - return res; } #else @@ -277,8 +273,6 @@ int eth_stm32_tx(const struct device *dev, struct net_pkt *pkt) return -EIO; } - k_mutex_lock(&dev_data->tx_mutex, K_FOREVER); - ctx = allocate_tx_context(pkt); buf_header = &dma_tx_buffer_header[ctx->first_tx_buffer_index]; @@ -390,8 +384,6 @@ int eth_stm32_tx(const struct device *dev, struct net_pkt *pkt) HAL_ETH_TxFreeCallback(STM32_ETH_ARGS(heth, (uint32_t *)ctx)); } - k_mutex_unlock(&dev_data->tx_mutex); - return res; } #endif /* ETH_STM32_HAL_TX_ASYNC */ @@ -635,7 +627,6 @@ int eth_stm32_hal_init(const struct device *dev) #endif /* CONFIG_PTP_CLOCK_STM32_HAL */ /* Initialize semaphores */ - k_mutex_init(&dev_data->tx_mutex); k_sem_init(&dev_data->rx_int_sem, 0, K_SEM_MAX_LIMIT); k_sem_init(&dev_data->tx_int_sem, 0, 1); From 9ff85c87d566da42942da46de34a9604fa206853 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fin=20Maa=C3=9F?= Date: Wed, 14 Jan 2026 13:55:45 +0100 Subject: [PATCH 2041/3659] drivers: ethernet: nxp: remove redunant tx mutex MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit remove redunant tx mutex, as the networking subsystem already provides one since f65ac5effb02bdc4cb70b205545971e70c53c282 Signed-off-by: Fin Maaß --- drivers/ethernet/eth_nxp_enet.c | 16 +++------------- drivers/ethernet/eth_nxp_s32_gmac.c | 5 ----- drivers/ethernet/eth_nxp_s32_netc.c | 7 +------ drivers/ethernet/eth_nxp_s32_netc_priv.h | 1 - drivers/ethernet/nxp_imx_netc/eth_nxp_imx_netc.c | 6 ------ .../nxp_imx_netc/eth_nxp_imx_netc_priv.h | 1 - 6 files changed, 4 insertions(+), 32 deletions(-) diff --git a/drivers/ethernet/eth_nxp_enet.c b/drivers/ethernet/eth_nxp_enet.c index 0950db87d997..3d7a09d8122f 100644 --- a/drivers/ethernet/eth_nxp_enet.c +++ b/drivers/ethernet/eth_nxp_enet.c @@ -106,7 +106,6 @@ struct nxp_enet_mac_data { struct k_work rx_work; const struct device *dev; struct k_sem rx_thread_sem; - struct k_mutex tx_frame_buf_mutex; struct k_mutex rx_frame_buf_mutex; #ifdef CONFIG_PTP_CLOCK_NXP_ENET struct nxp_enet_ptp_data ptp; @@ -219,13 +218,10 @@ static int eth_nxp_enet_tx(const struct device *dev, struct net_pkt *pkt) /* Wait for a TX buffer descriptor to be available */ k_sem_take(&data->tx_buf_sem, K_FOREVER); - /* Enter critical section for TX frame buffer access */ - k_mutex_lock(&data->tx_frame_buf_mutex, K_FOREVER); - ret = net_pkt_read(pkt, data->tx_frame_buf, total_len); if (ret) { k_sem_give(&data->tx_buf_sem); - goto exit; + return ret; } frame_is_timestamped = @@ -237,19 +233,14 @@ static int eth_nxp_enet_tx(const struct device *dev, struct net_pkt *pkt) if (ret != kStatus_Success) { LOG_ERR("ENET_SendFrame error: %d", ret); ENET_ReclaimTxDescriptor(data->base, &data->enet_handle, RING_ID); - ret = -EIO; - goto exit; + return -EIO; } if (frame_is_timestamped) { eth_wait_for_ptp_ts(dev, pkt); } -exit: - /* Leave critical section for TX frame buffer access */ - k_mutex_unlock(&data->tx_frame_buf_mutex); - - return ret; + return 0; } static enum ethernet_hw_caps eth_nxp_enet_get_capabilities(const struct device *dev) @@ -695,7 +686,6 @@ static int eth_nxp_enet_init(const struct device *dev) } k_mutex_init(&data->rx_frame_buf_mutex); - k_mutex_init(&data->tx_frame_buf_mutex); k_sem_init(&data->rx_thread_sem, 0, CONFIG_ETH_NXP_ENET_RX_BUFFERS); k_sem_init(&data->tx_buf_sem, CONFIG_ETH_NXP_ENET_TX_BUFFERS, CONFIG_ETH_NXP_ENET_TX_BUFFERS); diff --git a/drivers/ethernet/eth_nxp_s32_gmac.c b/drivers/ethernet/eth_nxp_s32_gmac.c index 2552e593f5d7..32315f2d1795 100644 --- a/drivers/ethernet/eth_nxp_s32_gmac.c +++ b/drivers/ethernet/eth_nxp_s32_gmac.c @@ -53,7 +53,6 @@ struct eth_nxp_s32_data { struct net_if *iface; uint8_t mac_addr[ETH_NXP_S32_MAC_ADDR_LEN]; uint8_t if_suspended; - struct k_mutex tx_mutex; struct k_sem rx_sem; struct k_sem tx_sem; struct k_thread rx_thread; @@ -209,7 +208,6 @@ static int eth_nxp_s32_init(const struct device *dev) return -EIO; } - k_mutex_init(&ctx->tx_mutex); k_sem_init(&ctx->rx_sem, 0, 1); k_sem_init(&ctx->tx_sem, 0, 1); @@ -350,7 +348,6 @@ static int eth_nxp_s32_tx(const struct device *dev, struct net_pkt *pkt) __ASSERT(pkt, "Packet pointer is NULL"); - k_mutex_lock(&ctx->tx_mutex, K_FOREVER); k_sem_reset(&ctx->tx_sem); buf.Length = (uint16_t)pkt_len; @@ -396,8 +393,6 @@ static int eth_nxp_s32_tx(const struct device *dev, struct net_pkt *pkt) } error: - k_mutex_unlock(&ctx->tx_mutex); - if (res != 0) { eth_stats_update_errors_tx(ctx->iface); } diff --git a/drivers/ethernet/eth_nxp_s32_netc.c b/drivers/ethernet/eth_nxp_s32_netc.c index a2e9bc6ffba8..52bfef59b815 100644 --- a/drivers/ethernet/eth_nxp_s32_netc.c +++ b/drivers/ethernet/eth_nxp_s32_netc.c @@ -80,7 +80,6 @@ int nxp_s32_eth_initialize_common(const struct device *dev) } } - k_mutex_init(&ctx->tx_mutex); k_sem_init(&ctx->rx_sem, 0, 1); k_thread_create(&ctx->rx_thread, ctx->rx_thread_stack, @@ -122,7 +121,7 @@ void nxp_s32_eth_mcast_filter(const struct device *dev, const struct ethernet_fi int nxp_s32_eth_tx(const struct device *dev, struct net_pkt *pkt) { - struct nxp_s32_eth_data *ctx = dev->data; + __maybe_unused struct nxp_s32_eth_data *ctx = dev->data; const struct nxp_s32_eth_config *cfg = dev->config; size_t pkt_len = net_pkt_get_len(pkt); int res = 0; @@ -131,8 +130,6 @@ int nxp_s32_eth_tx(const struct device *dev, struct net_pkt *pkt) __ASSERT(pkt, "Packet pointer is NULL"); - k_mutex_lock(&ctx->tx_mutex, K_FOREVER); - buf.length = (uint16_t)pkt_len; buf.data = NULL; status = Netc_Eth_Ip_GetTxBuff(cfg->si_idx, cfg->tx_ring_idx, &buf, NULL); @@ -163,8 +160,6 @@ int nxp_s32_eth_tx(const struct device *dev, struct net_pkt *pkt) } error: - k_mutex_unlock(&ctx->tx_mutex); - if (res != 0) { eth_stats_update_errors_tx(ctx->iface); } diff --git a/drivers/ethernet/eth_nxp_s32_netc_priv.h b/drivers/ethernet/eth_nxp_s32_netc_priv.h index 760522b501bd..33d335231b52 100644 --- a/drivers/ethernet/eth_nxp_s32_netc_priv.h +++ b/drivers/ethernet/eth_nxp_s32_netc_priv.h @@ -121,7 +121,6 @@ struct nxp_s32_eth_config { struct nxp_s32_eth_data { struct net_if *iface; uint8_t mac_addr[6]; - struct k_mutex tx_mutex; struct k_sem rx_sem; struct k_thread rx_thread; diff --git a/drivers/ethernet/nxp_imx_netc/eth_nxp_imx_netc.c b/drivers/ethernet/nxp_imx_netc/eth_nxp_imx_netc.c index 9106e17fcd7a..67b2068e5061 100644 --- a/drivers/ethernet/nxp_imx_netc/eth_nxp_imx_netc.c +++ b/drivers/ethernet/nxp_imx_netc/eth_nxp_imx_netc.c @@ -422,8 +422,6 @@ int netc_eth_init_common(const struct device *dev) EP_MsixSetEntryMask(&data->handle, NETC_TX_MSIX_ENTRY_IDX, false); EP_MsixSetEntryMask(&data->handle, NETC_RX_MSIX_ENTRY_IDX, false); - k_mutex_init(&data->tx_mutex); - k_sem_init(&data->rx_sem, 0, 1); k_thread_create(&data->rx_thread, data->rx_thread_stack, K_KERNEL_STACK_SIZEOF(data->rx_thread_stack), netc_eth_rx_thread, @@ -480,8 +478,6 @@ int netc_eth_tx(const struct device *dev, struct net_pkt *pkt) } #endif - k_mutex_lock(&data->tx_mutex, K_FOREVER); - #ifdef NETC_PTP_TIMESTAMPING_SUPPORT pkt_is_gptp = net_ntohs(NET_ETH_HDR(pkt)->type) == NET_ETH_PTYPE_PTP; if ((pkt_is_gptp || net_pkt_is_tx_timestamping(pkt)) && @@ -562,8 +558,6 @@ int netc_eth_tx(const struct device *dev, struct net_pkt *pkt) ret = 0; error: - k_mutex_unlock(&data->tx_mutex); - if (ret != 0) { eth_stats_update_errors_tx(iface_dst); } diff --git a/drivers/ethernet/nxp_imx_netc/eth_nxp_imx_netc_priv.h b/drivers/ethernet/nxp_imx_netc/eth_nxp_imx_netc_priv.h index c765bf0a6ffb..c58ae57f0ef3 100644 --- a/drivers/ethernet/nxp_imx_netc/eth_nxp_imx_netc_priv.h +++ b/drivers/ethernet/nxp_imx_netc/eth_nxp_imx_netc_priv.h @@ -120,7 +120,6 @@ struct netc_eth_data { struct net_if *iface; uint8_t mac_addr[6]; /* TX */ - struct k_mutex tx_mutex; uint8_t *tx_buff; volatile bool tx_done; /* RX */ From 7fb1573311a4511e5522fc28bdb029d7191fc063 Mon Sep 17 00:00:00 2001 From: Pieter De Gendt Date: Fri, 9 Jan 2026 13:57:41 +0100 Subject: [PATCH 2042/3659] drivers: flash: flexspi-nor: Support reset GPIO Add optional reset pin to flash devices. Signed-off-by: Pieter De Gendt --- drivers/flash/flash_mcux_flexspi_nor.c | 40 +++++++++++++++++++++++ dts/bindings/mtd/nxp,imx-flexspi-nor.yaml | 17 ++++++++++ 2 files changed, 57 insertions(+) diff --git a/drivers/flash/flash_mcux_flexspi_nor.c b/drivers/flash/flash_mcux_flexspi_nor.c index e24d104cd287..32f182b63f8c 100644 --- a/drivers/flash/flash_mcux_flexspi_nor.c +++ b/drivers/flash/flash_mcux_flexspi_nor.c @@ -19,6 +19,10 @@ #include #endif +#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(reset_gpios) +#include +#endif + #define NOR_WRITE_SIZE 1 #define NOR_ERASE_VALUE 0xff @@ -68,6 +72,11 @@ struct flash_flexspi_nor_config { * into a RAM structure */ const struct device *controller; +#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(reset_gpios) + const struct gpio_dt_spec rst_gpio; + uint16_t rst_assert_ms; + uint16_t rst_deassert_ms; +#endif }; /* Device variables used in critical sections should be in this structure */ @@ -1639,6 +1648,26 @@ static int flash_flexspi_nor_init(const struct device *dev) return -ENODEV; } +#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(reset_gpios) + if (config->rst_gpio.port != NULL) { + if (!gpio_is_ready_dt(&config->rst_gpio)) { + LOG_ERR("Reset GPIO device is not ready"); + return -ENODEV; + } + + if (gpio_pin_configure_dt(&config->rst_gpio, GPIO_OUTPUT_ACTIVE) < 0) { + LOG_ERR("Reset GPIO config failed"); + return -EIO; + } + + k_sleep(K_MSEC(config->rst_assert_ms)); + + gpio_pin_set_dt(&config->rst_gpio, 0); + + k_sleep(K_MSEC(config->rst_deassert_ms)); + } +#endif + if (flash_flexspi_nor_probe(data)) { if (memc_flexspi_is_running_xip(&data->controller)) { /* We can't continue from here- the LUT stored in @@ -1689,6 +1718,16 @@ static DEVICE_API(flash, flash_flexspi_nor_api) = { #define AHB_WRITE_WAIT_UNIT(unit) \ CONCAT3(kFLEXSPI_AhbWriteWaitUnit, unit, AhbCycle) + +#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(reset_gpios) +#define FLASH_FLEXSPI_RST_GPIO(inst) \ + .rst_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, reset_gpios, {0}), \ + .rst_assert_ms = DT_INST_PROP_OR(inst, reset_assert_duration_ms, 0), \ + .rst_deassert_ms = DT_INST_PROP_OR(inst, boot_duration_ms, 0), +#else +#define FLASH_FLEXSPI_RST_GPIO(inst) +#endif + #define FLASH_FLEXSPI_DEVICE_CONFIG(n) \ { \ .flexspiRootClk = DT_INST_PROP(n, spi_max_frequency), \ @@ -1717,6 +1756,7 @@ static DEVICE_API(flash, flash_flexspi_nor_api) = { static const struct flash_flexspi_nor_config \ flash_flexspi_nor_config_##n = { \ .controller = DEVICE_DT_GET(DT_INST_BUS(n)), \ + FLASH_FLEXSPI_RST_GPIO(n) \ }; \ static struct flash_flexspi_nor_data \ flash_flexspi_nor_data_##n = { \ diff --git a/dts/bindings/mtd/nxp,imx-flexspi-nor.yaml b/dts/bindings/mtd/nxp,imx-flexspi-nor.yaml index 8bde7df0af6e..18a07e534d4d 100644 --- a/dts/bindings/mtd/nxp,imx-flexspi-nor.yaml +++ b/dts/bindings/mtd/nxp,imx-flexspi-nor.yaml @@ -6,3 +6,20 @@ description: NXP FlexSPI NOR compatible: "nxp,imx-flexspi-nor" include: ["nxp,imx-flexspi-device.yaml", soc-nv-flash.yaml] + +properties: + reset-gpios: + type: phandle-array + description: Reset GPIO pin. + + reset-assert-duration-ms: + type: int + description: | + Minimum duration to activate a hardware reset. + Ignored if no reset GPIO pin specified. + + boot-duration-ms: + type: int + description: | + Minimum time to wait following a hardware reset. + Ignored if no reset GPIO pin specified. From 32e305700992f1014b737c757efad360b3f8c48c Mon Sep 17 00:00:00 2001 From: Gaetan Perrot Date: Thu, 15 Jan 2026 11:52:39 +0900 Subject: [PATCH 2043/3659] net: mqtt_sn: make process_search void process_search() never reports errors and always returns 0. The error check at the call site is therefore dead code. Make the function void and drop the unused error handling. Signed-off-by: Gaetan Perrot --- subsys/net/lib/mqtt_sn/mqtt_sn.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/subsys/net/lib/mqtt_sn/mqtt_sn.c b/subsys/net/lib/mqtt_sn/mqtt_sn.c index a9468e7809eb..7e3f9cf5e258 100644 --- a/subsys/net/lib/mqtt_sn/mqtt_sn.c +++ b/subsys/net/lib/mqtt_sn/mqtt_sn.c @@ -1032,9 +1032,8 @@ static int process_ping(struct mqtt_sn_client *client, int64_t *next_cycle) * * @param client * @param next_cycle will be set to the time when the next action is required - * @retval 0 on success */ -static int process_search(struct mqtt_sn_client *client, int64_t *next_cycle) +static void process_search(struct mqtt_sn_client *client, int64_t *next_cycle) { const int64_t now = k_uptime_get(); @@ -1064,8 +1063,6 @@ static int process_search(struct mqtt_sn_client *client, int64_t *next_cycle) } LOG_DBG("next_cycle: %lld", *next_cycle); - - return 0; } /** @@ -1124,10 +1121,7 @@ static void process_work(struct k_work *wrk) } /* Handle GW search process timers */ - err = process_search(client, &next_cycle); - if (err) { - return; - } + process_search(client, &next_cycle); process_pubs_qos_m1(client); From 287d6e9dddff052c4d6da24332cb95d13c801678 Mon Sep 17 00:00:00 2001 From: Gaetan Perrot Date: Thu, 15 Jan 2026 11:53:45 +0900 Subject: [PATCH 2044/3659] net: mqtt_sn: make process_advertise void process_advertise() never reports errors and always returns 0. The error check at the call site is therefore dead code. Make the function void and drop the unused error handling. Signed-off-by: Gaetan Perrot --- subsys/net/lib/mqtt_sn/mqtt_sn.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/subsys/net/lib/mqtt_sn/mqtt_sn.c b/subsys/net/lib/mqtt_sn/mqtt_sn.c index 7e3f9cf5e258..23ff2200f6ec 100644 --- a/subsys/net/lib/mqtt_sn/mqtt_sn.c +++ b/subsys/net/lib/mqtt_sn/mqtt_sn.c @@ -1070,9 +1070,8 @@ static void process_search(struct mqtt_sn_client *client, int64_t *next_cycle) * * @param client * @param next_cycle will be set to the time when the next action is required - * @return int */ -static int process_advertise(struct mqtt_sn_client *client, int64_t *next_cycle) +static void process_advertise(struct mqtt_sn_client *client, int64_t *next_cycle) { const int64_t now = k_uptime_get(); struct mqtt_sn_gateway *gw; @@ -1092,8 +1091,6 @@ static int process_advertise(struct mqtt_sn_client *client, int64_t *next_cycle) } } LOG_DBG("next_cycle: %lld", *next_cycle); - - return 0; } /** @@ -1115,10 +1112,7 @@ static void process_work(struct k_work *wrk) k_uptime_get()); /* Clean up old advertised gateways from list */ - err = process_advertise(client, &next_cycle); - if (err) { - return; - } + process_advertise(client, &next_cycle); /* Handle GW search process timers */ process_search(client, &next_cycle); From a53edb7cfd87df34dba1891a912d4d8053d9c0e1 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Thu, 15 Jan 2026 11:33:50 +0000 Subject: [PATCH 2045/3659] soc: andestech: ae350: Fix wrong implementation of SoC Fixes a wrongly added SoC feature which should not have been accepted in the original way it was added, by correctly adding a Kconfig to select an optional build configuration for this SoC Signed-off-by: Jamie McCrae --- .../andestech/adp_xc7k_ae350/Kconfig.adp_xc7k | 3 +- .../adp_xc7k_ae350/Kconfig.defconfig | 9 ++++++ soc/andestech/ae350/Kconfig | 28 ++++++++++++------- soc/andestech/ae350/Kconfig.defconfig.ae350 | 4 +-- soc/andestech/ae350/Kconfig.soc | 8 +----- tests/arch/common/gen_isr_table/src/main.c | 2 +- 6 files changed, 32 insertions(+), 22 deletions(-) create mode 100644 boards/andestech/adp_xc7k_ae350/Kconfig.defconfig diff --git a/boards/andestech/adp_xc7k_ae350/Kconfig.adp_xc7k b/boards/andestech/adp_xc7k_ae350/Kconfig.adp_xc7k index 8cf2c3fb842e..305328dcf2a4 100644 --- a/boards/andestech/adp_xc7k_ae350/Kconfig.adp_xc7k +++ b/boards/andestech/adp_xc7k_ae350/Kconfig.adp_xc7k @@ -2,5 +2,4 @@ # SPDX-License-Identifier: Apache-2.0 config BOARD_ADP_XC7K - select SOC_ANDES_AE350 if BOARD_ADP_XC7K_AE350 - select SOC_ANDES_AE350_CLIC if BOARD_ADP_XC7K_AE350_CLIC + select SOC_ANDES_AE350 if BOARD_ADP_XC7K_AE350 || BOARD_ADP_XC7K_AE350_CLIC diff --git a/boards/andestech/adp_xc7k_ae350/Kconfig.defconfig b/boards/andestech/adp_xc7k_ae350/Kconfig.defconfig new file mode 100644 index 000000000000..2c8d0e6c66c7 --- /dev/null +++ b/boards/andestech/adp_xc7k_ae350/Kconfig.defconfig @@ -0,0 +1,9 @@ +# +# Copyright (c) 2026 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 +# + +choice SOC_AE350_INTERRUPT_TYPE + default SOC_AE350_INTERRUPT_TYPE_CLIC if BOARD_ADP_XC7K_AE350_CLIC + +endchoice diff --git a/soc/andestech/ae350/Kconfig b/soc/andestech/ae350/Kconfig index 669d817edf7d..b1a263656be2 100644 --- a/soc/andestech/ae350/Kconfig +++ b/soc/andestech/ae350/Kconfig @@ -23,20 +23,29 @@ config SOC_SERIES_ANDES_AE350 select SOC_PER_CORE_INIT_HOOK if RISCV_CUSTOM_CSR_ANDES_PMA imply XIP -config SOC_ANDES_AE350 +if SOC_SERIES_ANDES_AE350 + +choice SOC_AE350_INTERRUPT_TYPE + prompt "Base interrupt type" + depends on SOC_ANDES_AE350 + default SOC_AE350_INTERRUPT_TYPE_PLIC + +config SOC_AE350_INTERRUPT_TYPE_PLIC + bool "PLIC" select RISCV_HAS_PLIC -config SOC_ANDES_AE350_CLIC +config SOC_AE350_INTERRUPT_TYPE_CLIC + bool "CLIC" select RISCV_HAS_CLIC select CLIC_SMCLICSHV_EXT if RISCV_VECTORED_MODE select CLIC_SMCLICCONFIG_EXT select LEGACY_CLIC_MEMORYMAP_ACCESS -if SOC_SERIES_ANDES_AE350 +endchoice choice -prompt "Base CPU ISA options" -default RV32I_CPU + prompt "Base CPU ISA options" + default RV32I_CPU config RV32I_CPU bool "RISCV32 CPU ISA" @@ -53,8 +62,8 @@ config RV64I_CPU endchoice choice -prompt "FPU options" -default NO_FPU + prompt "FPU options" + default NO_FPU config NO_FPU bool "No FPU" @@ -98,8 +107,7 @@ config SOC_ANDES_V5_IOCP bool "Andes V5 I/O Coherence Port (IOCP)" depends on DCACHE help - Support Andes V5 I/O Coherence Port to handle cache coherency - between cache and external non-caching master, such as DMA - controller. + Support Andes V5 I/O Coherence Port to handle cache coherency between cache and external + non-caching master, such as DMA controller. endif # SOC_SERIES_ANDES_AE350 diff --git a/soc/andestech/ae350/Kconfig.defconfig.ae350 b/soc/andestech/ae350/Kconfig.defconfig.ae350 index 0b9294a55d5e..ba661c96e637 100644 --- a/soc/andestech/ae350/Kconfig.defconfig.ae350 +++ b/soc/andestech/ae350/Kconfig.defconfig.ae350 @@ -1,7 +1,7 @@ # Copyright (c) 2021 Andes Technology Corporation # SPDX-License-Identifier: Apache-2.0 -if SOC_ANDES_AE350 || SOC_ANDES_AE350_CLIC +if SOC_ANDES_AE350 config SYS_CLOCK_TICKS_PER_SEC default 100 if (!ICACHE || XIP) @@ -22,4 +22,4 @@ config MP_MAX_NUM_CPUS default 1 range 1 8 -endif # SOC_ANDES_AE350 || SOC_ANDES_AE350_CLIC +endif # SOC_ANDES_AE350 diff --git a/soc/andestech/ae350/Kconfig.soc b/soc/andestech/ae350/Kconfig.soc index 9ef1cc087f95..be7310adcc23 100644 --- a/soc/andestech/ae350/Kconfig.soc +++ b/soc/andestech/ae350/Kconfig.soc @@ -13,14 +13,8 @@ config SOC_ANDES_AE350 help Andes AE350 SoC implementation" -config SOC_ANDES_AE350_CLIC - bool - select SOC_SERIES_ANDES_AE350 - help - Andes AE350 CLIC SoC implementation" - config SOC_SERIES default "ae350" if SOC_SERIES_ANDES_AE350 config SOC - default "ae350" if SOC_ANDES_AE350 || SOC_ANDES_AE350_CLIC + default "ae350" if SOC_ANDES_AE350 diff --git a/tests/arch/common/gen_isr_table/src/main.c b/tests/arch/common/gen_isr_table/src/main.c index c280de89d863..ebd10e267385 100644 --- a/tests/arch/common/gen_isr_table/src/main.c +++ b/tests/arch/common/gen_isr_table/src/main.c @@ -61,7 +61,7 @@ extern const uintptr_t _irq_vector_table[]; #define ISR3_OFFSET 17 #define ISR5_OFFSET 18 #define TRIG_CHECK_SIZE 19 -#elif defined(CONFIG_SOC_ANDES_AE350_CLIC) +#elif defined(CONFIG_SOC_AE350_INTERRUPT_TYPE_CLIC) #define ISR1_OFFSET 19 #define ISR3_OFFSET 20 #define ISR5_OFFSET 21 From f3fa86ec1a2de58b16fa28a5e4e0cb8658b4bfd0 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Thu, 15 Jan 2026 11:38:14 +0000 Subject: [PATCH 2046/3659] soc: andestech: Fix Kconfig naming Fixes Kconfig naming to be properly set as required by HWMv2, to allow for future build system features to work Signed-off-by: Jamie McCrae --- boards/andestech/adp_xc7k_ae350/Kconfig.adp_xc7k | 2 +- soc/andestech/ae350/Kconfig | 8 ++++---- soc/andestech/ae350/Kconfig.defconfig | 4 ++-- soc/andestech/ae350/Kconfig.defconfig.ae350 | 4 ++-- soc/andestech/ae350/Kconfig.soc | 10 +++++----- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/boards/andestech/adp_xc7k_ae350/Kconfig.adp_xc7k b/boards/andestech/adp_xc7k_ae350/Kconfig.adp_xc7k index 305328dcf2a4..24493297fc02 100644 --- a/boards/andestech/adp_xc7k_ae350/Kconfig.adp_xc7k +++ b/boards/andestech/adp_xc7k_ae350/Kconfig.adp_xc7k @@ -2,4 +2,4 @@ # SPDX-License-Identifier: Apache-2.0 config BOARD_ADP_XC7K - select SOC_ANDES_AE350 if BOARD_ADP_XC7K_AE350 || BOARD_ADP_XC7K_AE350_CLIC + select SOC_AE350 if BOARD_ADP_XC7K_AE350 || BOARD_ADP_XC7K_AE350_CLIC diff --git a/soc/andestech/ae350/Kconfig b/soc/andestech/ae350/Kconfig index b1a263656be2..109e6a2f8541 100644 --- a/soc/andestech/ae350/Kconfig +++ b/soc/andestech/ae350/Kconfig @@ -1,7 +1,7 @@ # Copyright (c) 2021 Andes Technology Corporation # SPDX-License-Identifier: Apache-2.0 -config SOC_SERIES_ANDES_AE350 +config SOC_SERIES_AE350 select RISCV select RISCV_PRIVILEGED select RISCV_PMP @@ -23,11 +23,11 @@ config SOC_SERIES_ANDES_AE350 select SOC_PER_CORE_INIT_HOOK if RISCV_CUSTOM_CSR_ANDES_PMA imply XIP -if SOC_SERIES_ANDES_AE350 +if SOC_SERIES_AE350 choice SOC_AE350_INTERRUPT_TYPE prompt "Base interrupt type" - depends on SOC_ANDES_AE350 + depends on SOC_AE350 default SOC_AE350_INTERRUPT_TYPE_PLIC config SOC_AE350_INTERRUPT_TYPE_PLIC @@ -110,4 +110,4 @@ config SOC_ANDES_V5_IOCP Support Andes V5 I/O Coherence Port to handle cache coherency between cache and external non-caching master, such as DMA controller. -endif # SOC_SERIES_ANDES_AE350 +endif # SOC_SERIES_AE350 diff --git a/soc/andestech/ae350/Kconfig.defconfig b/soc/andestech/ae350/Kconfig.defconfig index 81a1ce0d5c8f..8f5f2a7bc819 100644 --- a/soc/andestech/ae350/Kconfig.defconfig +++ b/soc/andestech/ae350/Kconfig.defconfig @@ -1,7 +1,7 @@ # Copyright (c) 2021 Andes Technology Corporation # SPDX-License-Identifier: Apache-2.0 -if SOC_SERIES_ANDES_AE350 +if SOC_SERIES_AE350 rsource "Kconfig.defconfig.ae*" @@ -55,4 +55,4 @@ choice CACHE_TYPE default EXTERNAL_CACHE endchoice -endif # SOC_SERIES_ANDES_AE350 +endif # SOC_SERIES_AE350 diff --git a/soc/andestech/ae350/Kconfig.defconfig.ae350 b/soc/andestech/ae350/Kconfig.defconfig.ae350 index ba661c96e637..27dc609198a1 100644 --- a/soc/andestech/ae350/Kconfig.defconfig.ae350 +++ b/soc/andestech/ae350/Kconfig.defconfig.ae350 @@ -1,7 +1,7 @@ # Copyright (c) 2021 Andes Technology Corporation # SPDX-License-Identifier: Apache-2.0 -if SOC_ANDES_AE350 +if SOC_AE350 config SYS_CLOCK_TICKS_PER_SEC default 100 if (!ICACHE || XIP) @@ -22,4 +22,4 @@ config MP_MAX_NUM_CPUS default 1 range 1 8 -endif # SOC_ANDES_AE350 +endif # SOC_AE350 diff --git a/soc/andestech/ae350/Kconfig.soc b/soc/andestech/ae350/Kconfig.soc index be7310adcc23..e491848ce497 100644 --- a/soc/andestech/ae350/Kconfig.soc +++ b/soc/andestech/ae350/Kconfig.soc @@ -1,20 +1,20 @@ # Copyright (c) 2021 Andes Technology Corporation # SPDX-License-Identifier: Apache-2.0 -config SOC_SERIES_ANDES_AE350 +config SOC_SERIES_AE350 bool select SOC_FAMILY_ANDES_V5 help Andes V5 AE350 SoC Series Implementation" -config SOC_ANDES_AE350 +config SOC_AE350 bool - select SOC_SERIES_ANDES_AE350 + select SOC_SERIES_AE350 help Andes AE350 SoC implementation" config SOC_SERIES - default "ae350" if SOC_SERIES_ANDES_AE350 + default "ae350" if SOC_SERIES_AE350 config SOC - default "ae350" if SOC_ANDES_AE350 + default "ae350" if SOC_AE350 From bc63b5cd3013c6b5dc46ee62d6c2609626c9e7d8 Mon Sep 17 00:00:00 2001 From: Pieter De Gendt Date: Thu, 15 Jan 2026 13:13:51 +0100 Subject: [PATCH 2047/3659] nvmem: Improve doxygen in public APIs Update the NVMEM doxygen in accordance with the contribution guidelines. Signed-off-by: Pieter De Gendt --- include/zephyr/devicetree/nvmem.h | 109 +++++++++++++++++------------- include/zephyr/nvmem.h | 77 +++++++++++---------- 2 files changed, 103 insertions(+), 83 deletions(-) diff --git a/include/zephyr/devicetree/nvmem.h b/include/zephyr/devicetree/nvmem.h index 00fc3515ea69..105b80100b25 100644 --- a/include/zephyr/devicetree/nvmem.h +++ b/include/zephyr/devicetree/nvmem.h @@ -1,6 +1,7 @@ /** * @file - * @brief NVMEM Devicetree public API header file. + * @brief Public NVMEM devicetree header file. + * @ingroup devicetree-nvmem */ /* @@ -18,8 +19,10 @@ extern "C" { #endif /** - * @defgroup devicetree-nvmem Devicetree NVMEM API + * @defgroup devicetree-nvmem NVMEM Devicetree Helpers + * @brief Devicetree support for NVMEM. * @ingroup devicetree + * @ingroup nvmem_interface * @{ */ @@ -45,15 +48,15 @@ extern "C" { * DT_NVMEM_CELLS_HAS_IDX(DT_NODELABEL(eth), 1) // 0 * @endcode * - * @param node_id node identifier; may or may not have any nvmem-cells property - * @param idx index of a nvmem-cells property phandle-array whose existence to check + * @param node_id Node identifier that may or may not have an nvmem-cells property. + * @param idx Index of an nvmem-cells property phandle-array whose existence to check. * - * @return 1 if the index exists, 0 otherwise + * @return 1 if the index exists, 0 otherwise. */ #define DT_NVMEM_CELLS_HAS_IDX(node_id, idx) DT_PROP_HAS_IDX(node_id, nvmem_cells, idx) /** - * @brief Test if a node has an nvmem-cell-names array property hold a given name. + * @brief Test if a node has an nvmem-cell-names array property holds a given name. * * This expands to 1 if the name is available as nvmem-cells-name array property cell. * Otherwise, it expands to 0. @@ -74,10 +77,10 @@ extern "C" { * DT_NVMEM_CELLS_HAS_NAME(DT_NODELABEL(eth), bogus) // 0 * @endcode * - * @param node_id node identifier; may or may not have any nvmem-cell-names property - * @param name lowercase-and-underscores nvmem-cell-names cell value name to check + * @param node_id Node identifier that may or may not have an nvmem-cell-names property. + * @param name Lowercase-and-underscores nvmem-cell-names cell value name to check. * - * @return 1 if the index exists, 0 otherwise + * @return 1 if the index exists, 0 otherwise. */ #define DT_NVMEM_CELLS_HAS_NAME(node_id, name) DT_PROP_HAS_NAME(node_id, nvmem_cells, name) @@ -99,9 +102,9 @@ extern "C" { * DT_NUM_NVMEM_CELLS(DT_NODELABEL(eth)) // 1 * @endcode * - * @param node_id node identifier with an nvmem-cells property + * @param node_id Node identifier for a node with an nvmem-cells property. * - * @return number of elements in the property + * @return Number of elements in the property. */ #define DT_NUM_NVMEM_CELLS(node_id) DT_PROP_LEN(node_id, nvmem_cells) @@ -136,20 +139,22 @@ extern "C" { * DT_NVMEM_CELL_BY_IDX(DT_NODELABEL(eth), 0) // DT_NODELABEL(mac_address) * @endcode * - * @param node_id node identifier for a node with a nvmem-cells property - * @param idx index into the nvmem-cells property + * @param node_id Node identifier for a node with an nvmem-cells property. + * @param idx Index into the nvmem-cells property. * - * @return the node identifier for the NVMEM cell at index idx + * @return The node identifier for the NVMEM cell at index idx. */ #define DT_NVMEM_CELL_BY_IDX(node_id, idx) DT_PHANDLE_BY_IDX(node_id, nvmem_cells, idx) /** - * @brief Equivalent to DT_NVMEM_CELL_BY_IDX(node_id, 0) + * @brief Get the node identifier for the NVMEM cell at index 0. * - * @param node_id node identifier + * Equivalent to DT_NVMEM_CELL_BY_IDX(node_id, 0). * - * @return a node identifier for the NVMEM cell at index 0 - * in "nvmem-cells" + * @param node_id Node identifier for a node with an nvmem-cells property. + * + * @return A node identifier for the NVMEM cell at index 0 + * in "nvmem-cells". * * @see DT_NVMEM_CELL_BY_IDX() */ @@ -186,40 +191,46 @@ extern "C" { * DT_NVMEM_CELL_BY_NAME(DT_NODELABEL(eth), mac_address) // DT_NODELABEL(mac_address) * @endcode * - * @param node_id node identifier for a node with a nvmem-cells property - * @param name lowercase-and-underscores name of an nvmem-cells element - * as defined by the node's nvmem-cell-names property + * @param node_id Node identifier for a node with an nvmem-cells property. + * @param name Lowercase-and-underscores name of an nvmem-cells element + * as defined by the node's nvmem-cell-names property. * - * @return the node identifier for the NVMEM cell by name + * @return The node identifier for the NVMEM cell by name. */ #define DT_NVMEM_CELL_BY_NAME(node_id, name) DT_PHANDLE_BY_NAME(node_id, nvmem_cells, name) /** - * @brief Equivalent to DT_NVMEM_CELLS_HAS_IDX(DT_DRV_INST(inst), idx) + * @brief Test if a DT_DRV_COMPAT instance has an nvmem-cells property at a given index. + * + * Equivalent to DT_NVMEM_CELLS_HAS_IDX(DT_DRV_INST(inst), idx). * - * @param inst DT_DRV_COMPAT instance number; may or may not have any nvmem-cells property - * @param idx index of an nvmem-cells property phandle-array whose existence to check + * @param inst DT_DRV_COMPAT instance number that may or may not have an nvmem-cells property. + * @param idx Index of an nvmem-cells property phandle-array whose existence to check. * - * @return 1 if the index exists, 0 otherwise + * @return 1 if the index exists, 0 otherwise. */ #define DT_INST_NVMEM_CELLS_HAS_IDX(inst, idx) DT_NVMEM_CELLS_HAS_IDX(DT_DRV_INST(inst), idx) /** - * @brief Equivalent to DT_NVMEM_CELLS_HAS_NAME(DT_DRV_INST(inst), name) + * @brief Test if a DT_DRV_COMPAT instance has an nvmem-cell-names property with a given name. + * + * Equivalent to DT_NVMEM_CELLS_HAS_NAME(DT_DRV_INST(inst), name). * - * @param inst DT_DRV_COMPAT instance number; may or may not have any nvmem-cell-names property. - * @param name lowercase-and-underscores nvmem-cell-names cell value name to check + * @param inst DT_DRV_COMPAT instance number that may or may not have an nvmem-cell-names property. + * @param name Lowercase-and-underscores nvmem-cell-names cell value name to check. * - * @return 1 if the nvmem cell name exists, 0 otherwise + * @return 1 if the nvmem cell name exists, 0 otherwise. */ #define DT_INST_NVMEM_CELLS_HAS_NAME(inst, name) DT_NVMEM_CELLS_HAS_NAME(DT_DRV_INST(inst), name) /** - * @brief Equivalent to DT_NUM_NVMEM_CELLS(DT_DRV_INST(inst)) + * @brief Get the number of elements in a DT_DRV_COMPAT instance's nvmem-cells property. * - * @param inst instance number + * Equivalent to DT_NUM_NVMEM_CELLS(DT_DRV_INST(inst)). * - * @return number of elements in the nvmem-cells property + * @param inst DT_DRV_COMPAT instance number. + * + * @return Number of elements in the nvmem-cells property. */ #define DT_INST_NUM_NVMEM_CELLS(inst) DT_NUM_NVMEM_CELLS(DT_DRV_INST(inst)) @@ -227,23 +238,25 @@ extern "C" { * @brief Get the node identifier for the controller phandle from an * nvmem-cells phandle-array property at an index * - * @param inst instance number - * @param idx logical index into nvmem-cells + * @param inst DT_DRV_COMPAT instance number. + * @param idx Logical index into nvmem-cells property. * - * @return the node identifier for the nvmem cell referenced at - * index "idx" + * @return The node identifier for the nvmem cell referenced at + * index "idx". * * @see DT_NVMEM_CELL_CTLR_BY_IDX() */ #define DT_INST_NVMEM_CELL_BY_IDX(inst, idx) DT_NVMEM_CELL_BY_IDX(DT_DRV_INST(inst), idx) /** - * @brief Equivalent to DT_INST_NVMEM_CELL_BY_IDX(inst, 0) + * @brief Get the node identifier for a DT_DRV_COMPAT instance's NVMEM cell at index 0. + * + * Equivalent to DT_INST_NVMEM_CELL_BY_IDX(inst, 0). * - * @param inst instance number + * @param inst DT_DRV_COMPAT instance number. * - * @return a node identifier for the nvmem cell at index 0 - * in nvmem-cells + * @return A node identifier for the nvmem cell at index 0 + * in nvmem-cells. * * @see DT_NVMEM_CELL() */ @@ -253,12 +266,12 @@ extern "C" { * @brief Get the node identifier for the controller phandle from an * nvmem-cells phandle-array property by name * - * @param inst instance number - * @param name lowercase-and-underscores name of an nvmem-cells element - * as defined by the node's nvmem-cell-names property + * @param inst DT_DRV_COMPAT instance number. + * @param name Lowercase-and-underscores name of an nvmem-cells element + * as defined by the node's nvmem-cell-names property. * - * @return the node identifier for the nvmem cell referenced by - * the named element + * @return The node identifier for the nvmem cell referenced by + * the named element. * * @see DT_NVMEM_CELL_BY_NAME() */ @@ -295,9 +308,9 @@ extern "C" { * DT_MTD_FROM_NVMEM_CELL(DT_NVMEM_CELL(DT_NODELABEL(eth))) // DT_NODELABEL(mac_eeprom) * @endcode * - * @param node_id node identifier for an nvmem cell node + * @param node_id Node identifier for an NVMEM cell. * - * @return the node identifier of the Memory Technology Device (MTD) that + * @return The node identifier of the Memory Technology Device (MTD) that * contains the nvmem cell node. */ #define DT_MTD_FROM_NVMEM_CELL(node_id) DT_GPARENT(node_id) diff --git a/include/zephyr/nvmem.h b/include/zephyr/nvmem.h index ba89151a59c7..b928dfcf6934 100644 --- a/include/zephyr/nvmem.h +++ b/include/zephyr/nvmem.h @@ -5,7 +5,7 @@ /** * @file - * @brief Main header file for NVMEM API. + * @brief Public NVMEM header file. * @ingroup nvmem_interface */ @@ -13,8 +13,8 @@ #define ZEPHYR_INCLUDE_NVMEM_H_ /** - * @brief Interfaces for NVMEM cells. * @defgroup nvmem_interface NVMEM + * @brief Non-volatile memory cells. * @since 4.3 * @version 0.1.0 * @ingroup io_interfaces @@ -45,7 +45,7 @@ struct nvmem_cell { }; /** - * @brief Static initializer for a struct nvmem_cell. + * @brief Get a static initializer for a struct nvmem_cell. * * This returns a static initializer for a struct nvmem_cell given a devicetree * node identifier. @@ -84,7 +84,7 @@ struct nvmem_cell { * // } * @endcode * - * @param node_id Devicetree node identifier. + * @param node_id Node identifier for an NVMEM cell. * * @return Static initializer for a struct nvmem_cell */ @@ -97,7 +97,7 @@ struct nvmem_cell { } /** - * @brief Static initializer for a struct nvmem_cell. + * @brief Get a static initializer for a struct nvmem_cell by name. * * This returns a static initializer for a struct nvmem_cell given a devicetree * node identifier and a name. @@ -139,7 +139,7 @@ struct nvmem_cell { * // } * @endcode * - * @param node_id Devicetree node identifier. + * @param node_id Node identifier for a node with an nvmem-cells property. * @param name Lowercase-and-underscores name of an nvmem-cells element as defined by * the node's nvmem-cell-names property. * @@ -150,10 +150,10 @@ struct nvmem_cell { #define NVMEM_CELL_GET_BY_NAME(node_id, name) NVMEM_CELL_INIT(DT_NVMEM_CELL_BY_NAME(node_id, name)) /** - * @brief Static initializer for a struct nvmem_cell from a DT_DRV_COMPAT - * instance. + * @brief Get a static initializer for a struct nvmem_cell from a DT_DRV_COMPAT + * instance by name. * - * @param inst DT_DRV_COMPAT instance number + * @param inst DT_DRV_COMPAT instance number. * @param name Lowercase-and-underscores name of an nvmem-cells element as defined by * the node's nvmem-cell-names property. * @@ -164,14 +164,14 @@ struct nvmem_cell { #define NVMEM_CELL_INST_GET_BY_NAME(inst, name) NVMEM_CELL_GET_BY_NAME(DT_DRV_INST(inst), name) /** - * @brief Like NVMEM_CELL_GET_BY_NAME(), with a fallback to a default value. + * @brief Get a static initializer for a struct nvmem_cell by name, with a fallback. * * If the devicetree node identifier 'node_id' refers to a node with a property * 'nvmem-cells', this expands to NVMEM_CELL_GET_BY_NAME(node_id, name). The * @p default_value parameter is not expanded in this case. Otherwise, this * expands to @p default_value. * - * @param node_id Devicetree node identifier. + * @param node_id Node identifier for a node that may have an nvmem-cells property. * @param name Lowercase-and-underscores name of an nvmem-cells element as defined by * the node's nvmem-cell-names property. * @param default_value Fallback value to expand to. @@ -187,10 +187,10 @@ struct nvmem_cell { (default_value)) /** - * @brief Like NVMEM_CELL_INST_GET_BY_NAME(), with a fallback to a default - * value. + * @brief Get a static initializer for a struct nvmem_cell from a DT_DRV_COMPAT + * instance by name, with a fallback. * - * @param inst DT_DRV_COMPAT instance number + * @param inst DT_DRV_COMPAT instance number. * @param name Lowercase-and-underscores name of an nvmem-cells element as defined by * the node's nvmem-cell-names property. * @param default_value Fallback value to expand to. @@ -204,7 +204,7 @@ struct nvmem_cell { NVMEM_CELL_GET_BY_NAME_OR(DT_DRV_INST(inst), name, default_value) /** - * @brief Static initializer for a struct nvmem_cell. + * @brief Get a static initializer for a struct nvmem_cell by index. * * This returns a static initializer for a struct nvmem_cell given a devicetree * node identifier and an index. @@ -246,7 +246,7 @@ struct nvmem_cell { * // } * @endcode * - * @param node_id Devicetree node identifier. + * @param node_id Node identifier for a node with an nvmem-cells property. * @param idx Logical index into 'nvmem-cells' property. * * @return Static initializer for a struct nvmem_cell for the property. @@ -256,10 +256,10 @@ struct nvmem_cell { #define NVMEM_CELL_GET_BY_IDX(node_id, idx) NVMEM_CELL_INIT(DT_NVMEM_CELL_BY_IDX(node_id, idx)) /** - * @brief Static initializer for a struct nvmem_cell from a DT_DRV_COMPAT - * instance. + * @brief Get a static initializer for a struct nvmem_cell from a DT_DRV_COMPAT + * instance by index. * - * @param inst DT_DRV_COMPAT instance number + * @param inst DT_DRV_COMPAT instance number. * @param idx Logical index into 'nvmem-cells' property. * * @return Static initializer for a struct nvmem_cell for the property. @@ -269,14 +269,14 @@ struct nvmem_cell { #define NVMEM_CELL_INST_GET_BY_IDX(inst, idx) NVMEM_CELL_GET_BY_IDX(DT_DRV_INST(inst), idx) /** - * @brief Like NVMEM_CELL_GET_BY_IDX(), with a fallback to a default value. + * @brief Get a static initializer for a struct nvmem_cell by index, with a fallback. * * If the devicetree node identifier 'node_id' refers to a node with a property * 'nvmem-cells', this expands to NVMEM_CELL_GET_BY_IDX(node_id, idx). The * @p default_value parameter is not expanded in this case. Otherwise, this * expands to @p default_value. * - * @param node_id Devicetree node identifier. + * @param node_id Node identifier for a node that may have an nvmem-cells property. * @param idx Logical index into 'nvmem-cells' property. * @param default_value Fallback value to expand to. * @@ -291,10 +291,10 @@ struct nvmem_cell { (default_value)) /** - * @brief Like NVMEM_CELL_INST_GET_BY_IDX(), with a fallback to a default - * value. + * @brief Get a static initializer for a struct nvmem_cell from a DT_DRV_COMPAT + * instance by index, with a fallback. * - * @param inst DT_DRV_COMPAT instance number + * @param inst DT_DRV_COMPAT instance number. * @param idx Logical index into 'nvmem-cells' property. * @param default_value Fallback value to expand to. * @@ -309,27 +309,34 @@ struct nvmem_cell { /** * @brief Read data from an NVMEM cell. * - * @param cell The NVMEM cell. - * @param data Buffer to store read data. - * @param off The offset to start reading from. + * @param cell NVMEM cell to read from. + * @param[out] data Buffer to store the read data. + * Must be at least @p len bytes. + * @param off Offset within the cell to start reading from, in bytes. + * Must be less than the cell size. * @param len Number of bytes to read. + * @p off + @p len must not exceed the cell size. * * @kconfig_dep{CONFIG_NVMEM} * * @retval -EINVAL Invalid offset or length arguments. * @retval -ENODEV The controller device is not ready. * @retval -ENXIO No runtime device API available. - * @return the result of the underlying device API call. + * @return The result of the underlying device API call. */ int nvmem_cell_read(const struct nvmem_cell *cell, void *data, off_t off, size_t len); /** * @brief Write data to an NVMEM cell. * - * @param cell The NVMEM cell. - * @param data Buffer with data to write. - * @param off The offset to start writing to. + * @param cell NVMEM cell to write to. + * Must not be read-only. + * @param data Buffer containing data to write. + * Must be at least @p len bytes. + * @param off Offset within the cell to start writing to, in bytes. + * Must be less than the cell size. * @param len Number of bytes to write. + * @p off + @p len must not exceed the cell size. * * @kconfig_dep{CONFIG_NVMEM} * @@ -337,16 +344,16 @@ int nvmem_cell_read(const struct nvmem_cell *cell, void *data, off_t off, size_t * @retval -EROFS Writing to a read-only NVMEM Cell. * @retval -ENODEV The controller device is not ready. * @retval -ENXIO No runtime device API available. - * @return the result of the underlying device API call. + * @return The result of the underlying device API call. */ int nvmem_cell_write(const struct nvmem_cell *cell, const void *data, off_t off, size_t len); /** - * @brief Validate that the NVMEM cell is ready. + * @brief Check if an NVMEM cell is ready. * - * @param cell The NVMEM cell. + * @param cell NVMEM cell to check. May be NULL. * - * @return true if the NVMEM cell is ready for use and false otherwise. + * @return True if the NVMEM cell is ready for use and false otherwise. */ static inline bool nvmem_cell_is_ready(const struct nvmem_cell *cell) { From 4690b7f966a58cb5c68c15442d11d17d22866026 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Sat, 17 Jan 2026 22:42:44 -0800 Subject: [PATCH 2048/3659] entropy: gd32: Fix build error entropy_gd32_recover() had not return type defined causing the following issue when building: drivers/entropy/entropy_gd32.c:61:8: error: return type defaults to 'int' [-Werror=implicit-int] Fix it and change the function to void since it was returning a constant 0 that is never checked or used. Signed-off-by: Flavio Ceolin --- drivers/entropy/entropy_gd32.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/entropy/entropy_gd32.c b/drivers/entropy/entropy_gd32.c index 8fe159e721f1..93035106459c 100644 --- a/drivers/entropy/entropy_gd32.c +++ b/drivers/entropy/entropy_gd32.c @@ -58,7 +58,7 @@ static bool entropy_gd32_ck48m_ready(void) return (RCU_CTL & RCU_CTL_PLLSTB) != 0U; } -static entropy_gd32_recover(void) +static void entropy_gd32_recover(void) { /* * For GD32F4xx TRNG the HAL exposes status bits (CECS/SECS) but provides @@ -69,8 +69,6 @@ static entropy_gd32_recover(void) trng_deinit(); entropy_gd32_clear_int_flags(); trng_enable(); - - return 0; } static int entropy_gd32_wait_drdy(void) From 6a8be27ec01b695b65a57363d1213e1be4622061 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Sat, 17 Jan 2026 22:47:55 -0800 Subject: [PATCH 2049/3659] dts: arm/gd: Add entropy to chosen properties Add zephyr,entropy and sets to TRNG0. This is needed by the random subsys when using entropy device. Signed-off-by: Flavio Ceolin --- dts/arm/gd/gd32f4xx/gd32f4xx.dtsi | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dts/arm/gd/gd32f4xx/gd32f4xx.dtsi b/dts/arm/gd/gd32f4xx/gd32f4xx.dtsi index 3900edf648c8..f94ddc4e38e7 100644 --- a/dts/arm/gd/gd32f4xx/gd32f4xx.dtsi +++ b/dts/arm/gd/gd32f4xx/gd32f4xx.dtsi @@ -13,6 +13,10 @@ #include / { + chosen { + zephyr,entropy = &trng0; + }; + cpus { #address-cells = <1>; #size-cells = <0>; From 58bdfd1f46a85f2b4587f8fc478b948ce99c181a Mon Sep 17 00:00:00 2001 From: Neil Chen Date: Mon, 19 Jan 2026 17:54:41 +0800 Subject: [PATCH 2050/3659] drivers: syscon: Fix mcxn547 CLOCK_GetFlexcanClkFreq issue mcxn547 only have one flexcan, but When calling CLOCK_GetFlexcanClkFreq, parameters are required. Signed-off-by: Neil Chen --- drivers/clock_control/clock_control_mcux_syscon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clock_control/clock_control_mcux_syscon.c b/drivers/clock_control/clock_control_mcux_syscon.c index 2f64bb55e112..270137738ebe 100644 --- a/drivers/clock_control/clock_control_mcux_syscon.c +++ b/drivers/clock_control/clock_control_mcux_syscon.c @@ -610,7 +610,7 @@ static int mcux_lpc_syscon_clock_control_get_subsys_rate(const struct device *de #if defined(CONFIG_CAN_MCUX_FLEXCAN) #if (defined(FSL_FEATURE_SOC_FLEXCAN_COUNT) && (FSL_FEATURE_SOC_FLEXCAN_COUNT == 1) && \ - !defined(CONFIG_SOC_MCXA346)) + !defined(CONFIG_SOC_MCXA346) && !defined(CONFIG_SOC_MCXN547)) case MCUX_FLEXCAN0_CLK: *rate = CLOCK_GetFlexcanClkFreq(); break; From 88d4709b45790f23bd2862a4669cf1997a8c60a1 Mon Sep 17 00:00:00 2001 From: Felix Wang Date: Mon, 19 Jan 2026 13:07:10 +0530 Subject: [PATCH 2051/3659] drivers: pwm: mcux_ctimer: Fix multi-line assertion message formatting Fix formatting of the __ASSERT message in mcux_ctimer_pwm_get_cycles_per_sec to properly concatenate the string across multiple lines. Signed-off-by: Felix Wang --- drivers/pwm/pwm_mcux_ctimer.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/pwm/pwm_mcux_ctimer.c b/drivers/pwm/pwm_mcux_ctimer.c index c6dd105d6f12..c31f9ab87f49 100644 --- a/drivers/pwm/pwm_mcux_ctimer.c +++ b/drivers/pwm/pwm_mcux_ctimer.c @@ -1,6 +1,6 @@ /* * (c) Meta Platforms, Inc. and affiliates. - * Copyright 2025 NXP + * Copyright 2025-2026 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -208,8 +208,8 @@ static int mcux_ctimer_pwm_get_cycles_per_sec(const struct device *dev, uint32_t } *cycles /= (uint64_t)config->prescale + 1; - __ASSERT((*cycles) > 0, "Invalid PWM frequency: cycles per second is 0(check clock rate - and prescaler)"); + __ASSERT((*cycles) > 0, "Invalid PWM frequency: cycles per second is 0(check clock rate " + "and prescaler)"); return err; } From b016be13a191b0830efd2917c9591fda47bc01e6 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Thu, 15 Jan 2026 12:26:37 +0000 Subject: [PATCH 2052/3659] soc: nordic: kconfig: Fix dt function usage Fixes using a dt function which suffered from firstly trying to take the value from a variable that isn't defined, and which if is ignored, was entirely invalid due to supplying a chosen node, not a path as the dt function explicitly requires Signed-off-by: Jamie McCrae --- soc/nordic/Kconfig | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/soc/nordic/Kconfig b/soc/nordic/Kconfig index ef66efea38a6..7ffc9319415a 100644 --- a/soc/nordic/Kconfig +++ b/soc/nordic/Kconfig @@ -104,7 +104,6 @@ config TFM_NRF_NS_STORAGE endif # BUILD_WITH_TFM - config NRF_MPU_FLASH_REGION_SIZE hex default 0x1000 @@ -112,16 +111,19 @@ config NRF_MPU_FLASH_REGION_SIZE help FLASH region size for the NRF_MPU peripheral. +DT_CHOSEN_ZEPHYR_FLASH := zephyr,flash +DT_CHOSEN_ZEPHYR_FLASH_PATH := $(dt_chosen_path,$(DT_CHOSEN_ZEPHYR_FLASH)) + config NRF_BPROT_FLASH_REGION_SIZE hex - default $(dt_node_int_prop_hex,$(DT_CHOSEN_ZEPHYR_FLASH),erase-block-size) + default $(dt_node_int_prop_hex,$(DT_CHOSEN_ZEPHYR_FLASH_PATH),erase-block-size) depends on HAS_HW_NRF_BPROT help FLASH region size for the NRF_BPROT peripheral (nRF52). config NRF_ACL_FLASH_REGION_SIZE hex - default $(dt_node_int_prop_hex,$(DT_CHOSEN_ZEPHYR_FLASH),erase-block-size) + default $(dt_node_int_prop_hex,$(DT_CHOSEN_ZEPHYR_FLASH_PATH),erase-block-size) depends on HAS_HW_NRF_ACL help FLASH region size for the NRF_ACL peripheral. From bf261206bb57ab87029fe2cfb5d0a517ba5abbb6 Mon Sep 17 00:00:00 2001 From: Aleksandr Khromykh Date: Thu, 15 Jan 2026 14:44:46 +0100 Subject: [PATCH 2053/3659] bluetooth: mesh: remove secure sorage for tfm crypto provider Commit removes selection secure storage for tfm crypto provider. The secure storage is under the secure image management. Non-secure image is not required in the secure storage subsystem. Signed-off-by: Aleksandr Khromykh --- subsys/bluetooth/mesh/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/bluetooth/mesh/Kconfig b/subsys/bluetooth/mesh/Kconfig index 7e708d3b15a0..c37c3e03129a 100644 --- a/subsys/bluetooth/mesh/Kconfig +++ b/subsys/bluetooth/mesh/Kconfig @@ -1533,7 +1533,7 @@ config BT_MESH_CRYPTO_LIB select PSA_WANT_ALG_SHA_256 select PSA_WANT_ALG_ECDH select PSA_WANT_ECC_SECP_R1_256 - select BT_MESH_SECURE_STORAGE if BT_SETTINGS + select BT_MESH_SECURE_STORAGE if BT_SETTINGS && PSA_CRYPTO_PROVIDER_MBEDTLS imply MBEDTLS_AES_ROM_TABLES if PSA_CRYPTO_PROVIDER_MBEDTLS help Crypto library support for mesh security. From 6bd273ad9f68d7c3df7d88428b58eeeb62b083a8 Mon Sep 17 00:00:00 2001 From: Piotr Kosycarz Date: Mon, 19 Jan 2026 08:14:38 +0100 Subject: [PATCH 2054/3659] samples: subsys: ipc: ipc_service: icmsg: Skip test if no second UART If a second UART was not configured in the hardware map, then skip the testcase instead of failing. Signed-off-by: Piotr Kosycarz --- samples/subsys/ipc/ipc_service/icmsg/pytest/test_ipc_icmsg.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/samples/subsys/ipc/ipc_service/icmsg/pytest/test_ipc_icmsg.py b/samples/subsys/ipc/ipc_service/icmsg/pytest/test_ipc_icmsg.py index 492c7c33e305..c496a31d1944 100644 --- a/samples/subsys/ipc/ipc_service/icmsg/pytest/test_ipc_icmsg.py +++ b/samples/subsys/ipc/ipc_service/icmsg/pytest/test_ipc_icmsg.py @@ -23,5 +23,7 @@ def test_ipc_icmsg(dut: DeviceAdapter): # check output from the remote core (skip for non-hardware devices, e.g. bsim) if dut.device_config.type == "hardware": + if len(dut.connections) < 2: + pytest.skip("Only one UART connection configured for this device") lines_from_remote = dut.readlines_until(connection_index=1, regex="demo ended") pytest.LineMatcher(lines_from_remote).fnmatch_lines(expected_lines) From 8345c07ed3c536db2f4c99c29d3cd54f594b5b32 Mon Sep 17 00:00:00 2001 From: Georgios Vasilakis Date: Wed, 12 Nov 2025 15:43:48 +0100 Subject: [PATCH 2055/3659] manifest: tf-m: Remove reserved memory for FLPR in TF-M for Nordic Update the memory layout of the Nordic nRF54L devices to avoid reserving volatile and non-volatile memory for FLPR since it is not yet supported with TF-M. Signed-off-by: Georgios Vasilakis --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index ca5999498921..d7b3c675b8ed 100644 --- a/west.yml +++ b/west.yml @@ -386,7 +386,7 @@ manifest: groups: - tee - name: trusted-firmware-m - revision: 8b3158f4d4023fef9efa5648e6236875a2f058e5 + revision: 677e0565e030cbe4946ac0cbde5603eae7d6392f path: modules/tee/tf-m/trusted-firmware-m groups: - tee From 0b71dea5101abc6b34ec96cc4a7604180a9e1e54 Mon Sep 17 00:00:00 2001 From: Georgios Vasilakis Date: Tue, 11 Nov 2025 12:32:46 +0100 Subject: [PATCH 2056/3659] dts: nordic: nrf54l15 ns refactor/update memory mapping Update the memory layout of nrf54l15 for TF-M builds so that it does not reserve any memory for FLPR since it is not supported with TF-M. This affects both the SRAM and the RRAM partitioning. To do that I refactored the dts files, specifically: 1) I created new files for the _ns targets since they have different available RRAM/SRAM sizes now. 2) I moved the SRAM partitioning to the nrf54l15_ns_partition.dtsi and removed it from individual board files so it can be updated for all the platforms in one place. Signed-off-by: Georgios Vasilakis --- .../bl54l15_dvk_nrf54l15_cpuapp_ns.dts | 31 +------------- .../bl54l15u_dvk_nrf54l15_cpuapp_ns.dts | 31 +------------- .../nrf54l15dk_nrf54l15_cpuapp_ns.dts | 31 +------------- .../panb611evb_nrf54l15_cpuapp_ns.dts | 31 +------------- ...raytac_an54lq_db_15_nrf54l15_cpuapp_ns.dts | 31 +------------- dts/arm/nordic/nrf54l15_cpuapp_ns.dtsi | 8 ++++ dts/arm/nordic/nrf54l_05_10_15_cpuapp.dtsi | 5 ++- dts/vendor/nordic/nrf54l15_ns.dtsi | 16 ++++++++ dts/vendor/nordic/nrf54l15_ns_partition.dtsi | 41 +++++++++++++++---- 9 files changed, 67 insertions(+), 158 deletions(-) create mode 100644 dts/arm/nordic/nrf54l15_cpuapp_ns.dtsi create mode 100644 dts/vendor/nordic/nrf54l15_ns.dtsi diff --git a/boards/ezurio/bl54l15_dvk/bl54l15_dvk_nrf54l15_cpuapp_ns.dts b/boards/ezurio/bl54l15_dvk/bl54l15_dvk_nrf54l15_cpuapp_ns.dts index bca01b2b0624..e6b3b2f2a642 100644 --- a/boards/ezurio/bl54l15_dvk/bl54l15_dvk_nrf54l15_cpuapp_ns.dts +++ b/boards/ezurio/bl54l15_dvk/bl54l15_dvk_nrf54l15_cpuapp_ns.dts @@ -9,7 +9,7 @@ #define USE_NON_SECURE_ADDRESS_MAP 1 -#include +#include #include "nrf54l_10_15_cpuapp_common.dtsi" / { @@ -29,35 +29,6 @@ }; }; -/ { - /* - * Default SRAM planning when building for nRF54L15 with ARM TrustZone-M support - * - Lowest 80 kB SRAM allocated to Secure image (sram0_s). - * - Upper 80 kB SRAM allocated to Non-Secure image (sram0_ns). - * - * nRF54L15 has 256 kB of volatile memory (SRAM) but the last 96kB are reserved for - * the FLPR MCU. - * This static layout needs to be the same with the upstream TF-M layout in the - * header flash_layout.h of the relevant platform. Any updates in the layout - * needs to happen both in the flash_layout.h and in this file at the same time. - */ - reserved-memory { - #address-cells = <1>; - #size-cells = <1>; - ranges; - - sram0_s: image_s@20000000 { - /* Secure image memory */ - reg = <0x20000000 DT_SIZE_K(80)>; - }; - - sram0_ns: image_ns@20014000 { - /* Non-Secure image memory */ - reg = <0x20014000 DT_SIZE_K(80)>; - }; - }; -}; - &uart30 { /* Disable so that TF-M can use this UART */ status = "disabled"; diff --git a/boards/ezurio/bl54l15u_dvk/bl54l15u_dvk_nrf54l15_cpuapp_ns.dts b/boards/ezurio/bl54l15u_dvk/bl54l15u_dvk_nrf54l15_cpuapp_ns.dts index 6530b554d343..aa392a5c5363 100644 --- a/boards/ezurio/bl54l15u_dvk/bl54l15u_dvk_nrf54l15_cpuapp_ns.dts +++ b/boards/ezurio/bl54l15u_dvk/bl54l15u_dvk_nrf54l15_cpuapp_ns.dts @@ -9,7 +9,7 @@ #define USE_NON_SECURE_ADDRESS_MAP 1 -#include +#include #include "nrf54l15_cpuapp_common.dtsi" / { @@ -29,35 +29,6 @@ }; }; -/ { - /* - * Default SRAM planning when building for nRF54L15 with ARM TrustZone-M support - * - Lowest 80 kB SRAM allocated to Secure image (sram0_s). - * - Upper 80 kB SRAM allocated to Non-Secure image (sram0_ns). - * - * nRF54L15 has 256 kB of volatile memory (SRAM) but the last 96kB are reserved for - * the FLPR MCU. - * This static layout needs to be the same with the upstream TF-M layout in the - * header flash_layout.h of the relevant platform. Any updates in the layout - * needs to happen both in the flash_layout.h and in this file at the same time. - */ - reserved-memory { - #address-cells = <1>; - #size-cells = <1>; - ranges; - - sram0_s: image_s@20000000 { - /* Secure image memory */ - reg = <0x20000000 DT_SIZE_K(80)>; - }; - - sram0_ns: image_ns@20014000 { - /* Non-Secure image memory */ - reg = <0x20014000 DT_SIZE_K(80)>; - }; - }; -}; - &uart30 { /* Disable so that TF-M can use this UART */ status = "disabled"; diff --git a/boards/nordic/nrf54l15dk/nrf54l15dk_nrf54l15_cpuapp_ns.dts b/boards/nordic/nrf54l15dk/nrf54l15dk_nrf54l15_cpuapp_ns.dts index f78a1f864e2f..68ed3ee76418 100644 --- a/boards/nordic/nrf54l15dk/nrf54l15dk_nrf54l15_cpuapp_ns.dts +++ b/boards/nordic/nrf54l15dk/nrf54l15dk_nrf54l15_cpuapp_ns.dts @@ -8,7 +8,7 @@ #define USE_NON_SECURE_ADDRESS_MAP 1 -#include +#include #include "nrf54l_05_10_15_cpuapp_common.dtsi" / { @@ -28,35 +28,6 @@ }; }; -/ { - /* - * Default SRAM planning when building for nRF54L15 with ARM TrustZone-M support - * - Lowest 80 kB SRAM allocated to Secure image (sram0_s). - * - Upper 80 kB SRAM allocated to Non-Secure image (sram0_ns). - * - * nRF54L15 has 256 kB of volatile memory (SRAM) but the last 96kB are reserved for - * the FLPR MCU. - * This static layout needs to be the same with the upstream TF-M layout in the - * header flash_layout.h of the relevant platform. Any updates in the layout - * needs to happen both in the flash_layout.h and in this file at the same time. - */ - reserved-memory { - #address-cells = <1>; - #size-cells = <1>; - ranges; - - sram0_s: image_s@20000000 { - /* Secure image memory */ - reg = <0x20000000 DT_SIZE_K(80)>; - }; - - sram0_ns: image_ns@20014000 { - /* Non-Secure image memory */ - reg = <0x20014000 DT_SIZE_K(80)>; - }; - }; -}; - &uart30 { /* Disable so that TF-M can use this UART */ status = "disabled"; diff --git a/boards/panasonic/panb611evb/panb611evb_nrf54l15_cpuapp_ns.dts b/boards/panasonic/panb611evb/panb611evb_nrf54l15_cpuapp_ns.dts index cebc30ff0899..545c864be4b3 100644 --- a/boards/panasonic/panb611evb/panb611evb_nrf54l15_cpuapp_ns.dts +++ b/boards/panasonic/panb611evb/panb611evb_nrf54l15_cpuapp_ns.dts @@ -8,7 +8,7 @@ #define USE_NON_SECURE_ADDRESS_MAP 1 -#include +#include #include "panb611evb_nrf54l15_cpuapp_common.dtsi" / { @@ -28,35 +28,6 @@ }; }; -/ { - /* - * Default SRAM planning when building for nRF54L15 with ARM TrustZone-M support - * - Lowest 80 kB SRAM allocated to Secure image (sram0_s). - * - Upper 80 kB SRAM allocated to Non-Secure image (sram0_ns). - * - * nRF54L15 has 256 kB of volatile memory (SRAM) but the last 96kB are reserved for - * the FLPR MCU. - * This static layout needs to be the same with the upstream TF-M layout in the - * header flash_layout.h of the relevant platform. Any updates in the layout - * needs to happen both in the flash_layout.h and in this file at the same time. - */ - reserved-memory { - #address-cells = <1>; - #size-cells = <1>; - ranges; - - sram0_s: image_s@20000000 { - /* Secure image memory */ - reg = <0x20000000 DT_SIZE_K(80)>; - }; - - sram0_ns: image_ns@20014000 { - /* Non-Secure image memory */ - reg = <0x20014000 DT_SIZE_K(80)>; - }; - }; -}; - &uart20 { /* Disable so that TF-M can use this UART */ status = "disabled"; diff --git a/boards/raytac/an54lq_db_15/raytac_an54lq_db_15_nrf54l15_cpuapp_ns.dts b/boards/raytac/an54lq_db_15/raytac_an54lq_db_15_nrf54l15_cpuapp_ns.dts index 8582e62d2f23..3e53d6e012f9 100644 --- a/boards/raytac/an54lq_db_15/raytac_an54lq_db_15_nrf54l15_cpuapp_ns.dts +++ b/boards/raytac/an54lq_db_15/raytac_an54lq_db_15_nrf54l15_cpuapp_ns.dts @@ -9,7 +9,7 @@ #define USE_NON_SECURE_ADDRESS_MAP 1 -#include +#include #include "raytac_an54lq_db_15_cpuapp_common.dtsi" / { @@ -29,35 +29,6 @@ }; }; -/ { - /* - * Default SRAM planning when building for nRF54L15 with ARM TrustZone-M support - * - Lowest 80 kB SRAM allocated to Secure image (sram0_s). - * - Upper 80 kB SRAM allocated to Non-Secure image (sram0_ns). - * - * nRF54L15 has 256 kB of volatile memory (SRAM) but the last 96kB are reserved for - * the FLPR MCU. - * This static layout needs to be the same with the upstream TF-M layout in the - * header flash_layout.h of the relevant platform. Any updates in the layout - * needs to happen both in the flash_layout.h and in this file at the same time. - */ - reserved-memory { - #address-cells = <1>; - #size-cells = <1>; - ranges; - - sram0_s: image_s@20000000 { - /* Secure image memory */ - reg = <0x20000000 DT_SIZE_K(80)>; - }; - - sram0_ns: image_ns@20014000 { - /* Non-Secure image memory */ - reg = <0x20014000 DT_SIZE_K(80)>; - }; - }; -}; - &uart30 { /* Disable so that TF-M can use this UART */ status = "disabled"; diff --git a/dts/arm/nordic/nrf54l15_cpuapp_ns.dtsi b/dts/arm/nordic/nrf54l15_cpuapp_ns.dtsi new file mode 100644 index 000000000000..c8467c487f0c --- /dev/null +++ b/dts/arm/nordic/nrf54l15_cpuapp_ns.dtsi @@ -0,0 +1,8 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "nrf54l_05_10_15_cpuapp.dtsi" diff --git a/dts/arm/nordic/nrf54l_05_10_15_cpuapp.dtsi b/dts/arm/nordic/nrf54l_05_10_15_cpuapp.dtsi index ee8be4b8d765..8bbd9bcc892d 100644 --- a/dts/arm/nordic/nrf54l_05_10_15_cpuapp.dtsi +++ b/dts/arm/nordic/nrf54l_05_10_15_cpuapp.dtsi @@ -11,9 +11,12 @@ systick: &cpuapp_systick {}; nvic: &cpuapp_nvic {}; /delete-node/ &cpuflpr; +/delete-node/ &cpuflpr_clic; + +#ifndef USE_NON_SECURE_ADDRESS_MAP /delete-node/ &cpuflpr_rram; /delete-node/ &cpuflpr_sram; -/delete-node/ &cpuflpr_clic; +#endif / { chosen { diff --git a/dts/vendor/nordic/nrf54l15_ns.dtsi b/dts/vendor/nordic/nrf54l15_ns.dtsi new file mode 100644 index 000000000000..a96865325b8a --- /dev/null +++ b/dts/vendor/nordic/nrf54l15_ns.dtsi @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "nrf54l_05_10_15.dtsi" + +&cpuapp_sram { + reg = <0x20000000 DT_SIZE_K(256)>; + ranges = <0x0 0x20000000 DT_SIZE_K(256)>; +}; + +&cpuapp_rram { + reg = <0x0 DT_SIZE_K(1524)>; +}; diff --git a/dts/vendor/nordic/nrf54l15_ns_partition.dtsi b/dts/vendor/nordic/nrf54l15_ns_partition.dtsi index ac15dc79f33c..c224df7b3e84 100644 --- a/dts/vendor/nordic/nrf54l15_ns_partition.dtsi +++ b/dts/vendor/nordic/nrf54l15_ns_partition.dtsi @@ -4,6 +4,34 @@ * SPDX-License-Identifier: Apache-2.0 */ +/ { + /* + * Default SRAM planning when building for nRF54L15 with ARM TrustZone-M support + * - Lowest 128 kB SRAM allocated to Secure image (sram0_s). + * - Upper 128 kB SRAM allocated to Non-Secure image (sram0_ns). + * + * nRF54L15 has 256 kB of volatile memory (SRAM). + * This static layout needs to be the same with the upstream TF-M layout in the + * header flash_layout.h of the relevant platform. Any updates in the layout + * needs to happen both in the flash_layout.h and in this file at the same time. + */ + reserved-memory { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + sram0_s: image_s@20000000 { + /* Secure image memory */ + reg = <0x20000000 DT_SIZE_K(128)>; + }; + + sram0_ns: image_ns@20020000 { + /* Non-Secure image memory */ + reg = <0x20020000 DT_SIZE_K(128)>; + }; + }; +}; + &cpuapp_rram { /* * Default NVM layout on NRF54L15 Application MCU without BL2: @@ -13,8 +41,8 @@ * 0x0008_0000 Protected Storage Area (16 KB) * 0x0008_4000 Internal Trusted Storage Area (16 KB) * 0x0008_8000 OTP / NV counters area (8 KB) - * 0x0008_A000 Non-secure image primary (844 KB) - * 0x0015_D000 Non-secure storage, used when built with NRF_NS_STORAGE=ON, + * 0x0008_A000 Non-secure image primary (940 KB) + * 0x0017_5000 Non-secure storage, used when built with NRF_NS_STORAGE=ON, * otherwise unused (32 KB) */ partitions { @@ -22,8 +50,7 @@ #address-cells = <1>; #size-cells = <1>; - /* nRF54L15 has 1524 kB of non volatile memory (RRAM) but the - * last 96kB are reserved for the FLPR MCU. + /* nRF54L15 has 1524 kB of non volatile memory (RRAM) * * This static layout needs to be the same with the upstream TF-M layout in the * header flash_layout.h of the relevant platform. Any updates in the layout @@ -51,12 +78,12 @@ slot0_ns_partition: partition@8A000 { label = "image-0-nonsecure"; - reg = <0x0008A000 DT_SIZE_K(844)>; + reg = <0x0008A000 DT_SIZE_K(940)>; }; - storage_partition: partition@15D000 { + storage_partition: partition@175000 { label = "storage"; - reg = <0x00015D000 DT_SIZE_K(32)>; + reg = <0x000175000 DT_SIZE_K(32)>; }; }; }; From 01056bcfabc8c33b7a2f3dd935b39c9431b94c94 Mon Sep 17 00:00:00 2001 From: Georgios Vasilakis Date: Tue, 11 Nov 2025 16:42:57 +0100 Subject: [PATCH 2057/3659] dts: nordic: nrf54lm20a ns refactor/update memory mapping Update the memory layout of nrf54lm20a for TF-M builds so that it does not reserve any memory for FLPR since it is not supported with TF-M. This affects both the SRAM and the RRAM partitioning. I moved the SRAM partitioning to the nrf54lm20a_ns_partition.dtsi and removed it from individual board files so it can be updated for all the platforms in one place. Signed-off-by: Georgios Vasilakis --- .../nrf54lm20dk_nrf54lm20a_cpuapp_ns.dts | 28 ------------- dts/arm/nordic/nrf54lm20a_enga_cpuapp.dtsi | 5 ++- dts/vendor/nordic/nrf54lm20a.dtsi | 13 ++++++ .../nordic/nrf54lm20a_ns_partition.dtsi | 41 +++++++++++++++---- 4 files changed, 51 insertions(+), 36 deletions(-) diff --git a/boards/nordic/nrf54lm20dk/nrf54lm20dk_nrf54lm20a_cpuapp_ns.dts b/boards/nordic/nrf54lm20dk/nrf54lm20dk_nrf54lm20a_cpuapp_ns.dts index 04cb9d04a60c..d9964c0399a1 100644 --- a/boards/nordic/nrf54lm20dk/nrf54lm20dk_nrf54lm20a_cpuapp_ns.dts +++ b/boards/nordic/nrf54lm20dk/nrf54lm20dk_nrf54lm20a_cpuapp_ns.dts @@ -27,34 +27,6 @@ }; }; -/ { - /* - * Default SRAM planning when building for nRF54LM20A with ARM TrustZone-M support - * - Lowest 208 kB SRAM allocated to Secure image (sram0_s). - * - Upper 208 kB SRAM allocated to Non-Secure image (sram0_ns). - * - * nRF54LM20A has 512 kB of volatile memory (SRAM), but 96kB is allocated for the FLPR MCU. - * This static layout needs to be the same with the upstream TF-M layout in the - * header flash_layout.h of the relevant platform. Any updates in the layout - * needs to happen both in the flash_layout.h and in this file at the same time. - */ - reserved-memory { - #address-cells = <1>; - #size-cells = <1>; - ranges; - - sram0_s: image_s@20000000 { - /* Secure image memory */ - reg = <0x20000000 DT_SIZE_K(208)>; - }; - - sram0_ns: image_ns@20034000 { - /* Non-Secure image memory */ - reg = <0x20034000 DT_SIZE_K(208)>; - }; - }; -}; - &bt_hci_controller { status = "disabled"; }; diff --git a/dts/arm/nordic/nrf54lm20a_enga_cpuapp.dtsi b/dts/arm/nordic/nrf54lm20a_enga_cpuapp.dtsi index 1798088d6f4a..d74a33745c01 100644 --- a/dts/arm/nordic/nrf54lm20a_enga_cpuapp.dtsi +++ b/dts/arm/nordic/nrf54lm20a_enga_cpuapp.dtsi @@ -13,9 +13,12 @@ systick: &cpuapp_systick {}; nvic: &cpuapp_nvic {}; /delete-node/ &cpuflpr; +/delete-node/ &cpuflpr_clic; + +#ifndef USE_NON_SECURE_ADDRESS_MAP /delete-node/ &cpuflpr_rram; /delete-node/ &cpuflpr_sram; -/delete-node/ &cpuflpr_clic; +#endif / { chosen { diff --git a/dts/vendor/nordic/nrf54lm20a.dtsi b/dts/vendor/nordic/nrf54lm20a.dtsi index 4d4eb645ac7b..f09ca573f56f 100644 --- a/dts/vendor/nordic/nrf54lm20a.dtsi +++ b/dts/vendor/nordic/nrf54lm20a.dtsi @@ -105,6 +105,16 @@ }; #endif +#ifdef USE_NON_SECURE_ADDRESS_MAP + /* FLPR/VPR is not used with TF-M so NS can use its memory */ + cpuapp_sram: memory@20000000 { + compatible = "mmio-sram"; + reg = <0x20000000 0x2007FE40>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x20000000 0x2007FE40>; + }; +#else cpuapp_sram: memory@20000000 { compatible = "mmio-sram"; reg = <0x20000000 DT_SIZE_K(511)>; @@ -120,6 +130,7 @@ #size-cells = <1>; ranges = <0x0 0x20067c00 DT_SIZE_K(96)>; }; +#endif #ifdef USE_NON_SECURE_ADDRESS_MAP global_peripherals: peripheral@40000000 { @@ -858,12 +869,14 @@ write-block-size = <16>; }; +#ifndef USE_NON_SECURE_ADDRESS_MAP cpuflpr_rram: rram@1e5000 { compatible = "soc-nv-flash"; reg = <0x1e5000 DT_SIZE_K(96)>; erase-block-size = <4096>; write-block-size = <16>; }; +#endif }; nrf_mpc: memory@50041000 { diff --git a/dts/vendor/nordic/nrf54lm20a_ns_partition.dtsi b/dts/vendor/nordic/nrf54lm20a_ns_partition.dtsi index 954dd8290453..916795ba3a32 100644 --- a/dts/vendor/nordic/nrf54lm20a_ns_partition.dtsi +++ b/dts/vendor/nordic/nrf54lm20a_ns_partition.dtsi @@ -4,6 +4,34 @@ * SPDX-License-Identifier: Apache-2.0 */ +/ { + /* + * Default SRAM planning when building for nRF54LM20A with ARM TrustZone-M support + * - Lowest 256 kB SRAM allocated to Secure image (sram0_s). + * - Upper 256 kB SRAM allocated to Non-Secure image (sram0_ns). + * + * nRF54LM20A has 512 kB of volatile memory (SRAM). + * This static layout needs to be the same with the upstream TF-M layout in the + * header flash_layout.h of the relevant platform. Any updates in the layout + * needs to happen both in the flash_layout.h and in this file at the same time. + */ + reserved-memory { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + sram0_s: image_s@20000000 { + /* Secure image memory */ + reg = <0x20000000 DT_SIZE_K(256)>; + }; + + sram0_ns: image_ns@20040000 { + /* Non-Secure image memory */ + reg = <0x20040000 0x2007FE40>; + }; + }; +}; + &cpuapp_rram { /* * Default NVM layout on NRF54LM20A Application MCU without BL2: @@ -13,8 +41,8 @@ * 0x0008_0000 Protected Storage Area (16 KB) * 0x0008_4000 Internal Trusted Storage Area (16 KB) * 0x0008_8000 OTP / NV counters area (8 KB) - * 0x0008_A000 Non-secure image primary (1356 KB) - * 0x001D_DD00 Non-secure storage, used when built with NRF_NS_STORAGE=ON, + * 0x0008_A000 Non-secure image primary (1452 KB) + * 0x001F_5000 Non-secure storage, used when built with NRF_NS_STORAGE=ON, * otherwise unused (32 KB) */ partitions { @@ -22,8 +50,7 @@ #address-cells = <1>; #size-cells = <1>; - /* nRF54LM20A has 2036 kB of non-volatile memory (RRAM) but the last - * 96 kB are reserved for the FLPR MCU. + /* nRF54LM20A has 2036 kB of non-volatile memory (RRAM) * * This static layout needs to be the same with the upstream TF-M layout in the * header flash_layout.h of the relevant platform. Any updates in the layout @@ -51,12 +78,12 @@ slot0_ns_partition: partition@8A000 { label = "image-0-nonsecure"; - reg = <0x0008A000 DT_SIZE_K(1356)>; + reg = <0x0008A000 DT_SIZE_K(1452)>; }; - storage_partition: partition@1DD000 { + storage_partition: partition@1F5000 { label = "storage"; - reg = <0x001DD000 DT_SIZE_K(32)>; + reg = <0x001F5000 DT_SIZE_K(32)>; }; }; }; From ba59fa7882cd0f5af3bac773d3821f5d3b50fbc1 Mon Sep 17 00:00:00 2001 From: Georgios Vasilakis Date: Tue, 11 Nov 2025 16:50:47 +0100 Subject: [PATCH 2058/3659] dts: nordic: nrf54l10 ns refactor/update memory mapping Update the memory layout of nrf54l10 for TF-M builds so that it does not reserve any memory for FLPR since it is not supported with TF-M. This affects both the SRAM and the RRAM partitioning. I moved the SRAM partitioning to the nrf54l10_ns_partition.dtsi and removed it from individual board files so it can be updated for all the platforms in one place. Signed-off-by: Georgios Vasilakis --- .../bl54l15_dvk_nrf54l10_cpuapp_ns.dts | 79 +------------------ .../nrf54l15dk_nrf54l10_cpuapp_ns.dts | 79 +------------------ dts/arm/nordic/nrf54l10_cpuapp_ns.dtsi | 8 ++ dts/vendor/nordic/nrf54l10_ns.dtsi | 16 ++++ dts/vendor/nordic/nrf54l10_ns_partition.dtsi | 77 ++++++++++++++++++ 5 files changed, 109 insertions(+), 150 deletions(-) create mode 100644 dts/arm/nordic/nrf54l10_cpuapp_ns.dtsi create mode 100644 dts/vendor/nordic/nrf54l10_ns.dtsi create mode 100644 dts/vendor/nordic/nrf54l10_ns_partition.dtsi diff --git a/boards/ezurio/bl54l15_dvk/bl54l15_dvk_nrf54l10_cpuapp_ns.dts b/boards/ezurio/bl54l15_dvk/bl54l15_dvk_nrf54l10_cpuapp_ns.dts index 59ba8bbed25a..99ab331c15ec 100644 --- a/boards/ezurio/bl54l15_dvk/bl54l15_dvk_nrf54l10_cpuapp_ns.dts +++ b/boards/ezurio/bl54l15_dvk/bl54l15_dvk_nrf54l10_cpuapp_ns.dts @@ -9,7 +9,7 @@ #define USE_NON_SECURE_ADDRESS_MAP 1 -#include +#include #include "nrf54l_10_15_cpuapp_common.dtsi" / { @@ -29,81 +29,10 @@ }; }; -/ { - /* - * Default SRAM planning when building for nRF54L10 with ARM TrustZone-M support. - * - Lowest 72 kB SRAM allocated to Secure image (sram0_s). - * - Upper 72 kB SRAM allocated to Non-Secure image (sram0_ns). - * - * nRF54L10 has 192 kB of volatile memory (SRAM) but the last 42kB are reserved for - * the FLPR MCU. - * This static layout needs to be the same with the upstream TF-M layout in the - * header flash_layout.h of the relevant platform. Any updates in the layout - * needs to happen both in the flash_layout.h and in this file at the same time. - */ - reserved-memory { - #address-cells = <1>; - #size-cells = <1>; - ranges; - - sram0_s: image_s@20000000 { - /* Secure image memory */ - reg = <0x20000000 DT_SIZE_K(72)>; - }; - - sram0_ns: image_ns@20012000 { - /* Non-Secure image memory */ - reg = <0x20012000 DT_SIZE_K(72)>; - }; - }; -}; - -&cpuapp_rram { - partitions { - compatible = "fixed-partitions"; - #address-cells = <1>; - #size-cells = <1>; - - /* nRF54L10 has 1012 kB of non volatile memory (RRAM) but the - * last 62kB are reserved for the FLPR MCU. - * - * This static layout needs to be the same with the upstream TF-M layout in the - * header flash_layout.h of the relevant platform. Any updates in the layout - * needs to happen both in the flash_layout.h and in this file at the same time. - */ - slot0_partition: partition@0 { - label = "image-0"; - reg = <0x0000000 DT_SIZE_K(384)>; - }; - - tfm_ps_partition: partition@60000 { - label = "tfm-ps"; - reg = <0x00060000 DT_SIZE_K(16)>; - }; - - tfm_its_partition: partition@64000 { - label = "tfm-its"; - reg = <0x00064000 DT_SIZE_K(16)>; - }; - - tfm_otp_partition: partition@68000 { - label = "tfm-otp"; - reg = <0x00068000 DT_SIZE_K(8)>; - }; - - slot0_ns_partition: partition@6A000 { - label = "image-0-nonsecure"; - reg = <0x0006A000 DT_SIZE_K(494)>; - }; - - storage_partition: partition@E5800 { - label = "storage"; - reg = <0x000E5800 DT_SIZE_K(32)>; - }; - }; -}; - &uart30 { /* Disable so that TF-M can use this UART */ status = "disabled"; }; + +/* Include default memory partition configuration file */ +#include diff --git a/boards/nordic/nrf54l15dk/nrf54l15dk_nrf54l10_cpuapp_ns.dts b/boards/nordic/nrf54l15dk/nrf54l15dk_nrf54l10_cpuapp_ns.dts index af0d14163345..000155e35c0d 100644 --- a/boards/nordic/nrf54l15dk/nrf54l15dk_nrf54l10_cpuapp_ns.dts +++ b/boards/nordic/nrf54l15dk/nrf54l15dk_nrf54l10_cpuapp_ns.dts @@ -8,7 +8,7 @@ #define USE_NON_SECURE_ADDRESS_MAP 1 -#include +#include #include "nrf54l_05_10_15_cpuapp_common.dtsi" / { @@ -28,81 +28,10 @@ }; }; -/ { - /* - * Default SRAM planning when building for nRF54L10 with ARM TrustZone-M support. - * - Lowest 72 kB SRAM allocated to Secure image (sram0_s). - * - Upper 72 kB SRAM allocated to Non-Secure image (sram0_ns). - * - * nRF54L10 has 192 kB of volatile memory (SRAM) but the last 42kB are reserved for - * the FLPR MCU. - * This static layout needs to be the same with the upstream TF-M layout in the - * header flash_layout.h of the relevant platform. Any updates in the layout - * needs to happen both in the flash_layout.h and in this file at the same time. - */ - reserved-memory { - #address-cells = <1>; - #size-cells = <1>; - ranges; - - sram0_s: image_s@20000000 { - /* Secure image memory */ - reg = <0x20000000 DT_SIZE_K(72)>; - }; - - sram0_ns: image_ns@20012000 { - /* Non-Secure image memory */ - reg = <0x20012000 DT_SIZE_K(72)>; - }; - }; -}; - -&cpuapp_rram { - partitions { - compatible = "fixed-partitions"; - #address-cells = <1>; - #size-cells = <1>; - - /* nRF54L10 has 1012 kB of non volatile memory (RRAM) but the - * last 62kB are reserved for the FLPR MCU. - * - * This static layout needs to be the same with the upstream TF-M layout in the - * header flash_layout.h of the relevant platform. Any updates in the layout - * needs to happen both in the flash_layout.h and in this file at the same time. - */ - slot0_partition: partition@0 { - label = "image-0"; - reg = <0x0000000 DT_SIZE_K(384)>; - }; - - tfm_ps_partition: partition@60000 { - label = "tfm-ps"; - reg = <0x00060000 DT_SIZE_K(16)>; - }; - - tfm_its_partition: partition@64000 { - label = "tfm-its"; - reg = <0x00064000 DT_SIZE_K(16)>; - }; - - tfm_otp_partition: partition@68000 { - label = "tfm-otp"; - reg = <0x00068000 DT_SIZE_K(8)>; - }; - - slot0_ns_partition: partition@6A000 { - label = "image-0-nonsecure"; - reg = <0x0006A000 DT_SIZE_K(494)>; - }; - - storage_partition: partition@E5800 { - label = "storage"; - reg = <0x000E5800 DT_SIZE_K(32)>; - }; - }; -}; - &uart30 { /* Disable so that TF-M can use this UART */ status = "disabled"; }; + +/* Include default memory partition configuration file */ +#include diff --git a/dts/arm/nordic/nrf54l10_cpuapp_ns.dtsi b/dts/arm/nordic/nrf54l10_cpuapp_ns.dtsi new file mode 100644 index 000000000000..6ef21a6d594c --- /dev/null +++ b/dts/arm/nordic/nrf54l10_cpuapp_ns.dtsi @@ -0,0 +1,8 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "nrf54l_05_10_15_cpuapp.dtsi" diff --git a/dts/vendor/nordic/nrf54l10_ns.dtsi b/dts/vendor/nordic/nrf54l10_ns.dtsi new file mode 100644 index 000000000000..1ee743b11786 --- /dev/null +++ b/dts/vendor/nordic/nrf54l10_ns.dtsi @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "nrf54l_05_10_15.dtsi" + +&cpuapp_sram { + reg = <0x20000000 DT_SIZE_K(192)>; + ranges = <0x0 0x20000000 DT_SIZE_K(192)>; +}; + +&cpuapp_rram { + reg = <0x0 DT_SIZE_K(1012)>; +}; diff --git a/dts/vendor/nordic/nrf54l10_ns_partition.dtsi b/dts/vendor/nordic/nrf54l10_ns_partition.dtsi new file mode 100644 index 000000000000..135c1688de00 --- /dev/null +++ b/dts/vendor/nordic/nrf54l10_ns_partition.dtsi @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + /* + * Default SRAM planning when building for nRF54L10 with ARM TrustZone-M support + * - Lowest 96 kB SRAM allocated to Secure image (sram0_s). + * - Upper 96 kB SRAM allocated to Non-Secure image (sram0_ns). + * + * nRF54L10 has 192 kB of volatile memory (SRAM). + * This static layout needs to be the same with the upstream TF-M layout in the + * header flash_layout.h of the relevant platform. Any updates in the layout + * needs to happen both in the flash_layout.h and in this file at the same time. + */ + reserved-memory { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + sram0_s: image_s@20000000 { + /* Secure image memory */ + reg = <0x20000000 DT_SIZE_K(96)>; + }; + + sram0_ns: image_ns@20018000 { + /* Non-Secure image memory */ + reg = <0x20018000 DT_SIZE_K(96)>; + }; + }; +}; + +&cpuapp_rram { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + /* nRF54L10 has 1012 kB of non volatile memory (RRAM). + * + * This static layout needs to be the same with the upstream TF-M layout in the + * header flash_layout.h of the relevant platform. Any updates in the layout + * needs to happen both in the flash_layout.h and in this file at the same time. + */ + slot0_partition: partition@0 { + label = "image-0"; + reg = <0x0000000 DT_SIZE_K(384)>; + }; + + tfm_ps_partition: partition@60000 { + label = "tfm-ps"; + reg = <0x00060000 DT_SIZE_K(16)>; + }; + + tfm_its_partition: partition@64000 { + label = "tfm-its"; + reg = <0x00064000 DT_SIZE_K(16)>; + }; + + tfm_otp_partition: partition@68000 { + label = "tfm-otp"; + reg = <0x00068000 DT_SIZE_K(8)>; + }; + + slot0_ns_partition: partition@6A000 { + label = "image-0-nonsecure"; + reg = <0x0006A000 DT_SIZE_K(556)>; + }; + + storage_partition: partition@F5000 { + label = "storage"; + reg = <0x000F5000 DT_SIZE_K(32)>; + }; + }; +}; From 00287376c44670e8cf480bd0a2e8e69ee2fa1e6f Mon Sep 17 00:00:00 2001 From: Georgios Vasilakis Date: Mon, 17 Nov 2025 14:39:21 +0100 Subject: [PATCH 2059/3659] dts: nordic: nrf54l refactor SRAM partitioning for NS builds Refactor the SRAM partitioning for TF-M builds for the Nordic nRF54L devices. Instead of using the reserved-memory node this just partitions the normal SRAM node. This aligns the design with the rest of the Nordic devices. Signed-off-by: Georgios Vasilakis --- dts/vendor/nordic/nrf54l10_ns_partition.dtsi | 45 ++++++++++--------- dts/vendor/nordic/nrf54l15_ns_partition.dtsi | 44 +++++++++--------- .../nordic/nrf54lm20a_ns_partition.dtsi | 44 +++++++++--------- 3 files changed, 67 insertions(+), 66 deletions(-) diff --git a/dts/vendor/nordic/nrf54l10_ns_partition.dtsi b/dts/vendor/nordic/nrf54l10_ns_partition.dtsi index 135c1688de00..b7b976463de0 100644 --- a/dts/vendor/nordic/nrf54l10_ns_partition.dtsi +++ b/dts/vendor/nordic/nrf54l10_ns_partition.dtsi @@ -4,31 +4,32 @@ * SPDX-License-Identifier: Apache-2.0 */ -/ { - /* - * Default SRAM planning when building for nRF54L10 with ARM TrustZone-M support - * - Lowest 96 kB SRAM allocated to Secure image (sram0_s). - * - Upper 96 kB SRAM allocated to Non-Secure image (sram0_ns). - * - * nRF54L10 has 192 kB of volatile memory (SRAM). - * This static layout needs to be the same with the upstream TF-M layout in the - * header flash_layout.h of the relevant platform. Any updates in the layout - * needs to happen both in the flash_layout.h and in this file at the same time. - */ - reserved-memory { +/* + * Default SRAM planning when building for nRF54L10 with ARM TrustZone-M support + * - Lowest 96 kB SRAM allocated to Secure image (sram0_s). + * - Upper 96 kB SRAM allocated to Non-Secure image (sram0_ns). + * + * nRF54L10 has 192 kB of volatile memory (SRAM). + * This static layout needs to be the same with the upstream TF-M layout in the + * header flash_layout.h of the relevant platform. Any updates in the layout + * needs to happen both in the flash_layout.h and in this file at the same time. + */ + +&cpuapp_sram { + sram0_s: image_s@0 { #address-cells = <1>; #size-cells = <1>; - ranges; - - sram0_s: image_s@20000000 { - /* Secure image memory */ - reg = <0x20000000 DT_SIZE_K(96)>; - }; + /* Secure image memory */ + reg = <0x0 DT_SIZE_K(96)>; + ranges = <0x0 0x0 DT_SIZE_K(96)>; + }; - sram0_ns: image_ns@20018000 { - /* Non-Secure image memory */ - reg = <0x20018000 DT_SIZE_K(96)>; - }; + sram0_ns: image_ns@18000 { + #address-cells = <1>; + #size-cells = <1>; + /* Non-Secure image memory */ + reg = <0x18000 DT_SIZE_K(96)>; + ranges = <0x0 0x18000 DT_SIZE_K(96)>; }; }; diff --git a/dts/vendor/nordic/nrf54l15_ns_partition.dtsi b/dts/vendor/nordic/nrf54l15_ns_partition.dtsi index c224df7b3e84..2586516cfefb 100644 --- a/dts/vendor/nordic/nrf54l15_ns_partition.dtsi +++ b/dts/vendor/nordic/nrf54l15_ns_partition.dtsi @@ -4,31 +4,31 @@ * SPDX-License-Identifier: Apache-2.0 */ -/ { - /* - * Default SRAM planning when building for nRF54L15 with ARM TrustZone-M support - * - Lowest 128 kB SRAM allocated to Secure image (sram0_s). - * - Upper 128 kB SRAM allocated to Non-Secure image (sram0_ns). - * - * nRF54L15 has 256 kB of volatile memory (SRAM). - * This static layout needs to be the same with the upstream TF-M layout in the - * header flash_layout.h of the relevant platform. Any updates in the layout - * needs to happen both in the flash_layout.h and in this file at the same time. - */ - reserved-memory { +/* + * Default SRAM planning when building for nRF54L15 with ARM TrustZone-M support + * - Lowest 128 kB SRAM allocated to Secure image (sram0_s). + * - Upper 128 kB SRAM allocated to Non-Secure image (sram0_ns). + * + * nRF54L15 has 256 kB of volatile memory (SRAM). + * This static layout needs to be the same with the upstream TF-M layout in the + * header flash_layout.h of the relevant platform. Any updates in the layout + * needs to happen both in the flash_layout.h and in this file at the same time. + */ +&cpuapp_sram { + sram0_s: image_s@0 { #address-cells = <1>; #size-cells = <1>; - ranges; - - sram0_s: image_s@20000000 { - /* Secure image memory */ - reg = <0x20000000 DT_SIZE_K(128)>; - }; + /* Secure image memory */ + reg = <0x0 DT_SIZE_K(128)>; + ranges = <0x0 0x0 DT_SIZE_K(128)>; + }; - sram0_ns: image_ns@20020000 { - /* Non-Secure image memory */ - reg = <0x20020000 DT_SIZE_K(128)>; - }; + sram0_ns: image_ns@20000 { + #address-cells = <1>; + #size-cells = <1>; + /* Non-Secure image memory */ + reg = <0x20000 DT_SIZE_K(128)>; + ranges = <0x0 0x20000 DT_SIZE_K(128)>; }; }; diff --git a/dts/vendor/nordic/nrf54lm20a_ns_partition.dtsi b/dts/vendor/nordic/nrf54lm20a_ns_partition.dtsi index 916795ba3a32..6fb92c1bbaed 100644 --- a/dts/vendor/nordic/nrf54lm20a_ns_partition.dtsi +++ b/dts/vendor/nordic/nrf54lm20a_ns_partition.dtsi @@ -4,31 +4,31 @@ * SPDX-License-Identifier: Apache-2.0 */ -/ { - /* - * Default SRAM planning when building for nRF54LM20A with ARM TrustZone-M support - * - Lowest 256 kB SRAM allocated to Secure image (sram0_s). - * - Upper 256 kB SRAM allocated to Non-Secure image (sram0_ns). - * - * nRF54LM20A has 512 kB of volatile memory (SRAM). - * This static layout needs to be the same with the upstream TF-M layout in the - * header flash_layout.h of the relevant platform. Any updates in the layout - * needs to happen both in the flash_layout.h and in this file at the same time. - */ - reserved-memory { +/* + * Default SRAM planning when building for nRF54LM20A with ARM TrustZone-M support + * - Lowest 256 kB SRAM allocated to Secure image (sram0_s). + * - Upper 256 kB SRAM allocated to Non-Secure image (sram0_ns). + * + * nRF54LM20A has 512 kB of volatile memory (SRAM). + * This static layout needs to be the same with the upstream TF-M layout in the + * header flash_layout.h of the relevant platform. Any updates in the layout + * needs to happen both in the flash_layout.h and in this file at the same time. + */ +&cpuapp_sram { + sram0_s: image_s@0 { #address-cells = <1>; #size-cells = <1>; - ranges; - - sram0_s: image_s@20000000 { - /* Secure image memory */ - reg = <0x20000000 DT_SIZE_K(256)>; - }; + /* Secure image memory */ + reg = <0x0 DT_SIZE_K(256)>; + ranges = <0x0 0x0 DT_SIZE_K(256)>; + }; - sram0_ns: image_ns@20040000 { - /* Non-Secure image memory */ - reg = <0x20040000 0x2007FE40>; - }; + sram0_ns: image_ns@40000 { + #address-cells = <1>; + #size-cells = <1>; + /* Non-Secure image memory */ + reg = <0x40000 0x7FE40>; + ranges = <0x0 0x40000 0x7FE40>; }; }; From dac69073cdb712ae7209581e2fe715c5362756c1 Mon Sep 17 00:00:00 2001 From: Georgios Vasilakis Date: Wed, 26 Nov 2025 16:48:05 +0100 Subject: [PATCH 2060/3659] dts: nordic: Rename all Nordic dtsi files for non secure Rename all dtsi files for Nordic boards for non secure builds to have a _ prefix before "ns" to increase readiblity. At the same time, change the path to include the arm folder in order to be able to differentiate with the vendor folder which has similar files. Signed-off-by: Georgios Vasilakis --- boards/actinius/icarus/actinius_icarus_nrf9160_ns.dts | 2 +- boards/actinius/icarus_bee/actinius_icarus_bee_nrf9160_ns.dts | 2 +- boards/actinius/icarus_som/actinius_icarus_som_nrf9160_ns.dts | 2 +- .../icarus_som_dk/actinius_icarus_som_dk_nrf9160_ns.dts | 2 +- boards/circuitdojo/feather/circuitdojo_feather_nrf9160_ns.dts | 2 +- boards/ct/ctcc/ctcc_nrf9161_ns.dts | 2 +- boards/ezurio/bl5340_dvk/bl5340_dvk_nrf5340_cpuapp_ns.dts | 2 +- boards/innblue/innblue21/innblue21_nrf9160_ns.dts | 2 +- boards/innblue/innblue22/innblue22_nrf9160_ns.dts | 2 +- .../nrf5340_audio_dk/nrf5340_audio_dk_nrf5340_cpuapp_ns.dts | 2 +- boards/nordic/nrf5340dk/nrf5340dk_nrf5340_cpuapp_ns.dts | 2 +- boards/nordic/nrf9131ek/nrf9131ek_nrf9131_ns.dts | 2 +- boards/nordic/nrf9151dk/nrf9151dk_nrf9151_ns.dts | 2 +- boards/nordic/nrf9160dk/nrf9160dk_nrf9160_ns.dts | 2 +- boards/nordic/nrf9161dk/nrf9161dk_nrf9161_ns.dts | 2 +- boards/nordic/thingy53/thingy53_nrf5340_cpuapp_ns.dts | 2 +- boards/norik/octopus_io_board/octopus_io_board_nrf9160_ns.dts | 2 +- boards/norik/octopus_som/octopus_som_nrf9160_ns.dts | 2 +- .../mdbt53_db_40/raytac_mdbt53_db_40_nrf5340_cpuapp_ns.dts | 2 +- .../mdbt53v_db_40/raytac_mdbt53v_db_40_nrf5340_cpuapp_ns.dts | 2 +- boards/sparkfun/thing_plus/sparkfun_thing_plus_nrf9160_ns.dts | 2 +- .../nordic/{nrf5340_cpuappns.dtsi => nrf5340_cpuapp_ns.dtsi} | 0 .../{nrf5340_cpuappns_qkaa.dtsi => nrf5340_cpuapp_ns_qkaa.dtsi} | 2 +- dts/arm/nordic/{nrf9161ns_laca.dtsi => nrf9131_ns_laca.dtsi} | 2 +- dts/arm/nordic/{nrf9131ns_laca.dtsi => nrf9151_ns_laca.dtsi} | 2 +- dts/arm/nordic/{nrf9160ns_sica.dtsi => nrf9160_ns_sica.dtsi} | 2 +- dts/arm/nordic/{nrf9151ns_laca.dtsi => nrf9161_ns_laca.dtsi} | 2 +- dts/arm/nordic/{nrf91ns.dtsi => nrf91_ns.dtsi} | 1 + 28 files changed, 27 insertions(+), 26 deletions(-) rename dts/arm/nordic/{nrf5340_cpuappns.dtsi => nrf5340_cpuapp_ns.dtsi} (100%) rename dts/arm/nordic/{nrf5340_cpuappns_qkaa.dtsi => nrf5340_cpuapp_ns_qkaa.dtsi} (87%) rename dts/arm/nordic/{nrf9161ns_laca.dtsi => nrf9131_ns_laca.dtsi} (89%) rename dts/arm/nordic/{nrf9131ns_laca.dtsi => nrf9151_ns_laca.dtsi} (89%) rename dts/arm/nordic/{nrf9160ns_sica.dtsi => nrf9160_ns_sica.dtsi} (89%) rename dts/arm/nordic/{nrf9151ns_laca.dtsi => nrf9161_ns_laca.dtsi} (89%) rename dts/arm/nordic/{nrf91ns.dtsi => nrf91_ns.dtsi} (97%) diff --git a/boards/actinius/icarus/actinius_icarus_nrf9160_ns.dts b/boards/actinius/icarus/actinius_icarus_nrf9160_ns.dts index 14017067f584..e10b4a667cbc 100644 --- a/boards/actinius/icarus/actinius_icarus_nrf9160_ns.dts +++ b/boards/actinius/icarus/actinius_icarus_nrf9160_ns.dts @@ -5,7 +5,7 @@ */ /dts-v1/; -#include +#include #include "actinius_icarus_common.dtsi" / { diff --git a/boards/actinius/icarus_bee/actinius_icarus_bee_nrf9160_ns.dts b/boards/actinius/icarus_bee/actinius_icarus_bee_nrf9160_ns.dts index b9d1493053fc..1a40879e16d1 100644 --- a/boards/actinius/icarus_bee/actinius_icarus_bee_nrf9160_ns.dts +++ b/boards/actinius/icarus_bee/actinius_icarus_bee_nrf9160_ns.dts @@ -5,7 +5,7 @@ */ /dts-v1/; -#include +#include #include "actinius_icarus_bee_common.dtsi" / { diff --git a/boards/actinius/icarus_som/actinius_icarus_som_nrf9160_ns.dts b/boards/actinius/icarus_som/actinius_icarus_som_nrf9160_ns.dts index 4ae2ca17343a..1561f269014e 100644 --- a/boards/actinius/icarus_som/actinius_icarus_som_nrf9160_ns.dts +++ b/boards/actinius/icarus_som/actinius_icarus_som_nrf9160_ns.dts @@ -5,7 +5,7 @@ */ /dts-v1/; -#include +#include #include "actinius_icarus_som_common.dtsi" / { diff --git a/boards/actinius/icarus_som_dk/actinius_icarus_som_dk_nrf9160_ns.dts b/boards/actinius/icarus_som_dk/actinius_icarus_som_dk_nrf9160_ns.dts index 3fef59bf93bc..20a57865812f 100644 --- a/boards/actinius/icarus_som_dk/actinius_icarus_som_dk_nrf9160_ns.dts +++ b/boards/actinius/icarus_som_dk/actinius_icarus_som_dk_nrf9160_ns.dts @@ -5,7 +5,7 @@ */ /dts-v1/; -#include +#include #include "actinius_icarus_som_dk_common.dtsi" / { diff --git a/boards/circuitdojo/feather/circuitdojo_feather_nrf9160_ns.dts b/boards/circuitdojo/feather/circuitdojo_feather_nrf9160_ns.dts index ae1589e85b22..c4e93476e1fe 100644 --- a/boards/circuitdojo/feather/circuitdojo_feather_nrf9160_ns.dts +++ b/boards/circuitdojo/feather/circuitdojo_feather_nrf9160_ns.dts @@ -6,7 +6,7 @@ */ /dts-v1/; -#include +#include #include "circuitdojo_feather_nrf9160_common.dtsi" / { diff --git a/boards/ct/ctcc/ctcc_nrf9161_ns.dts b/boards/ct/ctcc/ctcc_nrf9161_ns.dts index 1c23b0b8410c..f8a8e5883936 100644 --- a/boards/ct/ctcc/ctcc_nrf9161_ns.dts +++ b/boards/ct/ctcc/ctcc_nrf9161_ns.dts @@ -5,7 +5,7 @@ */ /dts-v1/; -#include +#include #include "ctcc_nrf9161_common.dtsi" / { diff --git a/boards/ezurio/bl5340_dvk/bl5340_dvk_nrf5340_cpuapp_ns.dts b/boards/ezurio/bl5340_dvk/bl5340_dvk_nrf5340_cpuapp_ns.dts index 35410c51b70c..535440fe8587 100644 --- a/boards/ezurio/bl5340_dvk/bl5340_dvk_nrf5340_cpuapp_ns.dts +++ b/boards/ezurio/bl5340_dvk/bl5340_dvk_nrf5340_cpuapp_ns.dts @@ -6,7 +6,7 @@ */ /dts-v1/; -#include +#include #include "bl5340_dvk_nrf5340_cpuapp_common.dtsi" / { diff --git a/boards/innblue/innblue21/innblue21_nrf9160_ns.dts b/boards/innblue/innblue21/innblue21_nrf9160_ns.dts index 2afcddfd579d..35e82e58cae6 100644 --- a/boards/innblue/innblue21/innblue21_nrf9160_ns.dts +++ b/boards/innblue/innblue21/innblue21_nrf9160_ns.dts @@ -5,7 +5,7 @@ */ /dts-v1/; -#include +#include #include "innblue21_common.dtsi" / { diff --git a/boards/innblue/innblue22/innblue22_nrf9160_ns.dts b/boards/innblue/innblue22/innblue22_nrf9160_ns.dts index 93fa33ba334c..6d1b7523e049 100644 --- a/boards/innblue/innblue22/innblue22_nrf9160_ns.dts +++ b/boards/innblue/innblue22/innblue22_nrf9160_ns.dts @@ -5,7 +5,7 @@ */ /dts-v1/; -#include +#include #include "innblue22_common.dtsi" / { diff --git a/boards/nordic/nrf5340_audio_dk/nrf5340_audio_dk_nrf5340_cpuapp_ns.dts b/boards/nordic/nrf5340_audio_dk/nrf5340_audio_dk_nrf5340_cpuapp_ns.dts index 8b906eb1c9a2..577fdbd13f87 100644 --- a/boards/nordic/nrf5340_audio_dk/nrf5340_audio_dk_nrf5340_cpuapp_ns.dts +++ b/boards/nordic/nrf5340_audio_dk/nrf5340_audio_dk_nrf5340_cpuapp_ns.dts @@ -5,7 +5,7 @@ */ /dts-v1/; -#include +#include #include "nrf5340_audio_dk_nrf5340_cpuapp_common.dtsi" / { diff --git a/boards/nordic/nrf5340dk/nrf5340dk_nrf5340_cpuapp_ns.dts b/boards/nordic/nrf5340dk/nrf5340dk_nrf5340_cpuapp_ns.dts index dbd4a770be3d..453d62507863 100644 --- a/boards/nordic/nrf5340dk/nrf5340dk_nrf5340_cpuapp_ns.dts +++ b/boards/nordic/nrf5340dk/nrf5340dk_nrf5340_cpuapp_ns.dts @@ -5,7 +5,7 @@ */ /dts-v1/; -#include +#include #include "nrf5340_cpuapp_common.dtsi" / { diff --git a/boards/nordic/nrf9131ek/nrf9131ek_nrf9131_ns.dts b/boards/nordic/nrf9131ek/nrf9131ek_nrf9131_ns.dts index 7dcf700bcf6f..987940b973ed 100644 --- a/boards/nordic/nrf9131ek/nrf9131ek_nrf9131_ns.dts +++ b/boards/nordic/nrf9131ek/nrf9131ek_nrf9131_ns.dts @@ -5,7 +5,7 @@ */ /dts-v1/; -#include +#include #include "nrf9131ek_nrf9131_common.dtsi" / { diff --git a/boards/nordic/nrf9151dk/nrf9151dk_nrf9151_ns.dts b/boards/nordic/nrf9151dk/nrf9151dk_nrf9151_ns.dts index 8074695d251b..b7d2fab385e8 100644 --- a/boards/nordic/nrf9151dk/nrf9151dk_nrf9151_ns.dts +++ b/boards/nordic/nrf9151dk/nrf9151dk_nrf9151_ns.dts @@ -5,7 +5,7 @@ */ /dts-v1/; -#include +#include #include "nrf9151dk_nrf9151_common.dtsi" / { diff --git a/boards/nordic/nrf9160dk/nrf9160dk_nrf9160_ns.dts b/boards/nordic/nrf9160dk/nrf9160dk_nrf9160_ns.dts index 1bac60d26622..2b72f59da11c 100644 --- a/boards/nordic/nrf9160dk/nrf9160dk_nrf9160_ns.dts +++ b/boards/nordic/nrf9160dk/nrf9160dk_nrf9160_ns.dts @@ -5,7 +5,7 @@ */ /dts-v1/; -#include +#include #include "nrf9160dk_nrf9160_common.dtsi" / { diff --git a/boards/nordic/nrf9161dk/nrf9161dk_nrf9161_ns.dts b/boards/nordic/nrf9161dk/nrf9161dk_nrf9161_ns.dts index 1bb0c0f2512c..e465dfe1a79b 100644 --- a/boards/nordic/nrf9161dk/nrf9161dk_nrf9161_ns.dts +++ b/boards/nordic/nrf9161dk/nrf9161dk_nrf9161_ns.dts @@ -5,7 +5,7 @@ */ /dts-v1/; -#include +#include #include "nrf9161dk_nrf9161_common.dtsi" / { diff --git a/boards/nordic/thingy53/thingy53_nrf5340_cpuapp_ns.dts b/boards/nordic/thingy53/thingy53_nrf5340_cpuapp_ns.dts index fee8c98c10b2..6991df96bb77 100644 --- a/boards/nordic/thingy53/thingy53_nrf5340_cpuapp_ns.dts +++ b/boards/nordic/thingy53/thingy53_nrf5340_cpuapp_ns.dts @@ -5,7 +5,7 @@ */ /dts-v1/; -#include +#include #include "thingy53_nrf5340_common.dtsi" #include <../boards/common/usb/cdc_acm_serial.dtsi> diff --git a/boards/norik/octopus_io_board/octopus_io_board_nrf9160_ns.dts b/boards/norik/octopus_io_board/octopus_io_board_nrf9160_ns.dts index fa24ffbf5650..1e80b5c101ab 100644 --- a/boards/norik/octopus_io_board/octopus_io_board_nrf9160_ns.dts +++ b/boards/norik/octopus_io_board/octopus_io_board_nrf9160_ns.dts @@ -4,7 +4,7 @@ */ /dts-v1/; -#include +#include #include "octopus_io_board_common.dtsi" / { diff --git a/boards/norik/octopus_som/octopus_som_nrf9160_ns.dts b/boards/norik/octopus_som/octopus_som_nrf9160_ns.dts index 3cd80c2ca33a..7cff43bf21a9 100644 --- a/boards/norik/octopus_som/octopus_som_nrf9160_ns.dts +++ b/boards/norik/octopus_som/octopus_som_nrf9160_ns.dts @@ -4,7 +4,7 @@ */ /dts-v1/; -#include +#include #include "octopus_som_common.dtsi" / { diff --git a/boards/raytac/mdbt53_db_40/raytac_mdbt53_db_40_nrf5340_cpuapp_ns.dts b/boards/raytac/mdbt53_db_40/raytac_mdbt53_db_40_nrf5340_cpuapp_ns.dts index 261b7bae5b3f..135ba2108481 100644 --- a/boards/raytac/mdbt53_db_40/raytac_mdbt53_db_40_nrf5340_cpuapp_ns.dts +++ b/boards/raytac/mdbt53_db_40/raytac_mdbt53_db_40_nrf5340_cpuapp_ns.dts @@ -5,7 +5,7 @@ */ /dts-v1/; -#include +#include #include "raytac_mdbt53_db_40_nrf5340_cpuapp_common.dtsi" / { diff --git a/boards/raytac/mdbt53v_db_40/raytac_mdbt53v_db_40_nrf5340_cpuapp_ns.dts b/boards/raytac/mdbt53v_db_40/raytac_mdbt53v_db_40_nrf5340_cpuapp_ns.dts index d5fb39a68dc7..8ff76906d414 100644 --- a/boards/raytac/mdbt53v_db_40/raytac_mdbt53v_db_40_nrf5340_cpuapp_ns.dts +++ b/boards/raytac/mdbt53v_db_40/raytac_mdbt53v_db_40_nrf5340_cpuapp_ns.dts @@ -5,7 +5,7 @@ */ /dts-v1/; -#include +#include #include "raytac_mdbt53v_db_40_nrf5340_cpuapp_common.dtsi" / { diff --git a/boards/sparkfun/thing_plus/sparkfun_thing_plus_nrf9160_ns.dts b/boards/sparkfun/thing_plus/sparkfun_thing_plus_nrf9160_ns.dts index 27ad9058980e..19b41a530143 100644 --- a/boards/sparkfun/thing_plus/sparkfun_thing_plus_nrf9160_ns.dts +++ b/boards/sparkfun/thing_plus/sparkfun_thing_plus_nrf9160_ns.dts @@ -6,7 +6,7 @@ */ /dts-v1/; -#include +#include #include "sparkfun_thing_plus_nrf9160_common.dtsi" / { diff --git a/dts/arm/nordic/nrf5340_cpuappns.dtsi b/dts/arm/nordic/nrf5340_cpuapp_ns.dtsi similarity index 100% rename from dts/arm/nordic/nrf5340_cpuappns.dtsi rename to dts/arm/nordic/nrf5340_cpuapp_ns.dtsi diff --git a/dts/arm/nordic/nrf5340_cpuappns_qkaa.dtsi b/dts/arm/nordic/nrf5340_cpuapp_ns_qkaa.dtsi similarity index 87% rename from dts/arm/nordic/nrf5340_cpuappns_qkaa.dtsi rename to dts/arm/nordic/nrf5340_cpuapp_ns_qkaa.dtsi index 6e18f646977d..bdcd4d9d462c 100644 --- a/dts/arm/nordic/nrf5340_cpuappns_qkaa.dtsi +++ b/dts/arm/nordic/nrf5340_cpuapp_ns_qkaa.dtsi @@ -5,7 +5,7 @@ */ #include -#include +#include &flash0 { reg = <0x00000000 DT_SIZE_K(1024)>; diff --git a/dts/arm/nordic/nrf9161ns_laca.dtsi b/dts/arm/nordic/nrf9131_ns_laca.dtsi similarity index 89% rename from dts/arm/nordic/nrf9161ns_laca.dtsi rename to dts/arm/nordic/nrf9131_ns_laca.dtsi index 8426efcde26a..ab95bee3deb0 100644 --- a/dts/arm/nordic/nrf9161ns_laca.dtsi +++ b/dts/arm/nordic/nrf9131_ns_laca.dtsi @@ -5,7 +5,7 @@ */ #include -#include +#include &flash0 { reg = <0x00000000 DT_SIZE_K(1024)>; diff --git a/dts/arm/nordic/nrf9131ns_laca.dtsi b/dts/arm/nordic/nrf9151_ns_laca.dtsi similarity index 89% rename from dts/arm/nordic/nrf9131ns_laca.dtsi rename to dts/arm/nordic/nrf9151_ns_laca.dtsi index 8426efcde26a..ab95bee3deb0 100644 --- a/dts/arm/nordic/nrf9131ns_laca.dtsi +++ b/dts/arm/nordic/nrf9151_ns_laca.dtsi @@ -5,7 +5,7 @@ */ #include -#include +#include &flash0 { reg = <0x00000000 DT_SIZE_K(1024)>; diff --git a/dts/arm/nordic/nrf9160ns_sica.dtsi b/dts/arm/nordic/nrf9160_ns_sica.dtsi similarity index 89% rename from dts/arm/nordic/nrf9160ns_sica.dtsi rename to dts/arm/nordic/nrf9160_ns_sica.dtsi index a10a5df325c9..3fad45ebb2d9 100644 --- a/dts/arm/nordic/nrf9160ns_sica.dtsi +++ b/dts/arm/nordic/nrf9160_ns_sica.dtsi @@ -5,7 +5,7 @@ */ #include -#include +#include &flash0 { reg = <0x00000000 DT_SIZE_K(1024)>; diff --git a/dts/arm/nordic/nrf9151ns_laca.dtsi b/dts/arm/nordic/nrf9161_ns_laca.dtsi similarity index 89% rename from dts/arm/nordic/nrf9151ns_laca.dtsi rename to dts/arm/nordic/nrf9161_ns_laca.dtsi index 8426efcde26a..ab95bee3deb0 100644 --- a/dts/arm/nordic/nrf9151ns_laca.dtsi +++ b/dts/arm/nordic/nrf9161_ns_laca.dtsi @@ -5,7 +5,7 @@ */ #include -#include +#include &flash0 { reg = <0x00000000 DT_SIZE_K(1024)>; diff --git a/dts/arm/nordic/nrf91ns.dtsi b/dts/arm/nordic/nrf91_ns.dtsi similarity index 97% rename from dts/arm/nordic/nrf91ns.dtsi rename to dts/arm/nordic/nrf91_ns.dtsi index ab258dd1bffc..7d52cd28902c 100644 --- a/dts/arm/nordic/nrf91ns.dtsi +++ b/dts/arm/nordic/nrf91_ns.dtsi @@ -42,6 +42,7 @@ peripheral@40000000 { #address-cells = <1>; #size-cells = <1>; + reg = <0x40000000 0x10000000>; ranges = <0x0 0x40000000 0x10000000>; /* Common nRF91 peripherals description. */ From 347b2c90772ba7a53f43e434cfc8888a04affa89 Mon Sep 17 00:00:00 2001 From: Georgios Vasilakis Date: Wed, 7 Jan 2026 16:14:23 +0100 Subject: [PATCH 2061/3659] dts: nordic: Rename the dts/vendor dtsi files This renames the dtsi files in the dts/vendor/nordic to include the cpuapp in the filename. At the same time it updates the inclusion of these files to include the vendor in the path because the same filenames exists in both: dts/vendor/nordic dts/arm/nordic Signed-off-by: Georgios Vasilakis --- boards/ezurio/bl54l15_dvk/bl54l15_dvk_nrf54l10_cpuapp.dts | 2 +- boards/ezurio/bl54l15_dvk/bl54l15_dvk_nrf54l10_cpuapp_ns.dts | 2 +- boards/ezurio/bl54l15_dvk/bl54l15_dvk_nrf54l15_cpuapp.dts | 2 +- boards/ezurio/bl54l15_dvk/bl54l15_dvk_nrf54l15_cpuapp_ns.dts | 2 +- boards/ezurio/bl54l15u_dvk/bl54l15u_dvk_nrf54l15_cpuapp.dts | 2 +- boards/ezurio/bl54l15u_dvk/bl54l15u_dvk_nrf54l15_cpuapp_ns.dts | 2 +- boards/holyiot/holyiot_25008/holyiot_25008_nrf54l15_cpuapp.dts | 2 +- boards/nordic/nrf54l15dk/nrf54l15dk_nrf54l10_cpuapp.dts | 2 +- boards/nordic/nrf54l15dk/nrf54l15dk_nrf54l10_cpuapp_ns.dts | 2 +- boards/nordic/nrf54l15dk/nrf54l15dk_nrf54l15_cpuapp.dts | 2 +- boards/nordic/nrf54l15dk/nrf54l15dk_nrf54l15_cpuapp_ns.dts | 2 +- boards/nordic/nrf54lm20dk/nrf54lm20dk_nrf54lm20a_cpuapp.dts | 2 +- boards/nordic/nrf54lm20dk/nrf54lm20dk_nrf54lm20a_cpuapp_ns.dts | 2 +- boards/panasonic/panb611evb/panb611evb_nrf54l15_cpuapp.dts | 2 +- boards/panasonic/panb611evb/panb611evb_nrf54l15_cpuapp_ns.dts | 2 +- .../raytac/an54lq_db_15/raytac_an54lq_db_15_nrf54l15_cpuapp.dts | 2 +- .../an54lq_db_15/raytac_an54lq_db_15_nrf54l15_cpuapp_ns.dts | 2 +- boards/seeed/xiao_nrf54l15/xiao_nrf54l15_nrf54l15_cpuapp.dts | 2 +- boards/we/ophelia4ev/ophelia4ev_nrf54l15_cpuapp.dts | 2 +- dts/arm/nordic/nrf54l10_cpuapp_ns.dtsi | 2 +- dts/arm/nordic/nrf54l15_cpuapp_ns.dtsi | 2 +- dts/vendor/nordic/{nrf54l10_ns.dtsi => nrf54l10_cpuapp_ns.dtsi} | 0 ...4l10_ns_partition.dtsi => nrf54l10_cpuapp_ns_partition.dtsi} | 0 .../{nrf54l10_partition.dtsi => nrf54l10_cpuapp_partition.dtsi} | 0 dts/vendor/nordic/{nrf54l15_ns.dtsi => nrf54l15_cpuapp_ns.dtsi} | 0 ...4l15_ns_partition.dtsi => nrf54l15_cpuapp_ns_partition.dtsi} | 0 .../{nrf54l15_partition.dtsi => nrf54l15_cpuapp_partition.dtsi} | 0 ...0a_ns_partition.dtsi => nrf54lm20a_cpuapp_ns_partition.dtsi} | 0 ...f54lm20a_partition.dtsi => nrf54lm20a_cpuapp_partition.dtsi} | 0 29 files changed, 21 insertions(+), 21 deletions(-) rename dts/vendor/nordic/{nrf54l10_ns.dtsi => nrf54l10_cpuapp_ns.dtsi} (100%) rename dts/vendor/nordic/{nrf54l10_ns_partition.dtsi => nrf54l10_cpuapp_ns_partition.dtsi} (100%) rename dts/vendor/nordic/{nrf54l10_partition.dtsi => nrf54l10_cpuapp_partition.dtsi} (100%) rename dts/vendor/nordic/{nrf54l15_ns.dtsi => nrf54l15_cpuapp_ns.dtsi} (100%) rename dts/vendor/nordic/{nrf54l15_ns_partition.dtsi => nrf54l15_cpuapp_ns_partition.dtsi} (100%) rename dts/vendor/nordic/{nrf54l15_partition.dtsi => nrf54l15_cpuapp_partition.dtsi} (100%) rename dts/vendor/nordic/{nrf54lm20a_ns_partition.dtsi => nrf54lm20a_cpuapp_ns_partition.dtsi} (100%) rename dts/vendor/nordic/{nrf54lm20a_partition.dtsi => nrf54lm20a_cpuapp_partition.dtsi} (100%) diff --git a/boards/ezurio/bl54l15_dvk/bl54l15_dvk_nrf54l10_cpuapp.dts b/boards/ezurio/bl54l15_dvk/bl54l15_dvk_nrf54l10_cpuapp.dts index 0654c4139c5a..96abc76fa453 100644 --- a/boards/ezurio/bl54l15_dvk/bl54l15_dvk_nrf54l10_cpuapp.dts +++ b/boards/ezurio/bl54l15_dvk/bl54l15_dvk_nrf54l10_cpuapp.dts @@ -27,4 +27,4 @@ }; /* Include default memory partition configuration file */ -#include +#include diff --git a/boards/ezurio/bl54l15_dvk/bl54l15_dvk_nrf54l10_cpuapp_ns.dts b/boards/ezurio/bl54l15_dvk/bl54l15_dvk_nrf54l10_cpuapp_ns.dts index 99ab331c15ec..dc11d1bd3ee3 100644 --- a/boards/ezurio/bl54l15_dvk/bl54l15_dvk_nrf54l10_cpuapp_ns.dts +++ b/boards/ezurio/bl54l15_dvk/bl54l15_dvk_nrf54l10_cpuapp_ns.dts @@ -35,4 +35,4 @@ }; /* Include default memory partition configuration file */ -#include +#include diff --git a/boards/ezurio/bl54l15_dvk/bl54l15_dvk_nrf54l15_cpuapp.dts b/boards/ezurio/bl54l15_dvk/bl54l15_dvk_nrf54l15_cpuapp.dts index 50a03e2d48f7..1236f74dbe6a 100644 --- a/boards/ezurio/bl54l15_dvk/bl54l15_dvk_nrf54l15_cpuapp.dts +++ b/boards/ezurio/bl54l15_dvk/bl54l15_dvk_nrf54l15_cpuapp.dts @@ -21,4 +21,4 @@ }; /* Include default memory partition configuration file */ -#include +#include diff --git a/boards/ezurio/bl54l15_dvk/bl54l15_dvk_nrf54l15_cpuapp_ns.dts b/boards/ezurio/bl54l15_dvk/bl54l15_dvk_nrf54l15_cpuapp_ns.dts index e6b3b2f2a642..2d18b5b88dbb 100644 --- a/boards/ezurio/bl54l15_dvk/bl54l15_dvk_nrf54l15_cpuapp_ns.dts +++ b/boards/ezurio/bl54l15_dvk/bl54l15_dvk_nrf54l15_cpuapp_ns.dts @@ -40,4 +40,4 @@ }; /* Include default memory partition configuration file */ -#include +#include diff --git a/boards/ezurio/bl54l15u_dvk/bl54l15u_dvk_nrf54l15_cpuapp.dts b/boards/ezurio/bl54l15u_dvk/bl54l15u_dvk_nrf54l15_cpuapp.dts index 00ffc3f5449c..1f1fdd24a7b4 100644 --- a/boards/ezurio/bl54l15u_dvk/bl54l15u_dvk_nrf54l15_cpuapp.dts +++ b/boards/ezurio/bl54l15u_dvk/bl54l15u_dvk_nrf54l15_cpuapp.dts @@ -21,4 +21,4 @@ }; /* Include default memory partition configuration file */ -#include +#include diff --git a/boards/ezurio/bl54l15u_dvk/bl54l15u_dvk_nrf54l15_cpuapp_ns.dts b/boards/ezurio/bl54l15u_dvk/bl54l15u_dvk_nrf54l15_cpuapp_ns.dts index aa392a5c5363..f8c82c05e463 100644 --- a/boards/ezurio/bl54l15u_dvk/bl54l15u_dvk_nrf54l15_cpuapp_ns.dts +++ b/boards/ezurio/bl54l15u_dvk/bl54l15u_dvk_nrf54l15_cpuapp_ns.dts @@ -40,4 +40,4 @@ }; /* Include default memory partition configuration file */ -#include +#include diff --git a/boards/holyiot/holyiot_25008/holyiot_25008_nrf54l15_cpuapp.dts b/boards/holyiot/holyiot_25008/holyiot_25008_nrf54l15_cpuapp.dts index c6df67bbba1f..ad15b0c2fd38 100644 --- a/boards/holyiot/holyiot_25008/holyiot_25008_nrf54l15_cpuapp.dts +++ b/boards/holyiot/holyiot_25008/holyiot_25008_nrf54l15_cpuapp.dts @@ -27,4 +27,4 @@ }; /* Include default memory partition configuration file */ -#include +#include diff --git a/boards/nordic/nrf54l15dk/nrf54l15dk_nrf54l10_cpuapp.dts b/boards/nordic/nrf54l15dk/nrf54l15dk_nrf54l10_cpuapp.dts index e3ee6b5434fc..c94d2a178133 100644 --- a/boards/nordic/nrf54l15dk/nrf54l15dk_nrf54l10_cpuapp.dts +++ b/boards/nordic/nrf54l15dk/nrf54l15dk_nrf54l10_cpuapp.dts @@ -26,4 +26,4 @@ }; /* Include default memory partition configuration file */ -#include +#include diff --git a/boards/nordic/nrf54l15dk/nrf54l15dk_nrf54l10_cpuapp_ns.dts b/boards/nordic/nrf54l15dk/nrf54l15dk_nrf54l10_cpuapp_ns.dts index 000155e35c0d..5ed2c41c29cb 100644 --- a/boards/nordic/nrf54l15dk/nrf54l15dk_nrf54l10_cpuapp_ns.dts +++ b/boards/nordic/nrf54l15dk/nrf54l15dk_nrf54l10_cpuapp_ns.dts @@ -34,4 +34,4 @@ }; /* Include default memory partition configuration file */ -#include +#include diff --git a/boards/nordic/nrf54l15dk/nrf54l15dk_nrf54l15_cpuapp.dts b/boards/nordic/nrf54l15dk/nrf54l15dk_nrf54l15_cpuapp.dts index 6e6629025612..6ece56bf004a 100644 --- a/boards/nordic/nrf54l15dk/nrf54l15dk_nrf54l15_cpuapp.dts +++ b/boards/nordic/nrf54l15dk/nrf54l15dk_nrf54l15_cpuapp.dts @@ -20,4 +20,4 @@ }; /* Include default memory partition configuration file */ -#include +#include diff --git a/boards/nordic/nrf54l15dk/nrf54l15dk_nrf54l15_cpuapp_ns.dts b/boards/nordic/nrf54l15dk/nrf54l15dk_nrf54l15_cpuapp_ns.dts index 68ed3ee76418..196245a12dbc 100644 --- a/boards/nordic/nrf54l15dk/nrf54l15dk_nrf54l15_cpuapp_ns.dts +++ b/boards/nordic/nrf54l15dk/nrf54l15dk_nrf54l15_cpuapp_ns.dts @@ -39,4 +39,4 @@ }; /* Include default memory partition configuration file */ -#include +#include diff --git a/boards/nordic/nrf54lm20dk/nrf54lm20dk_nrf54lm20a_cpuapp.dts b/boards/nordic/nrf54lm20dk/nrf54lm20dk_nrf54lm20a_cpuapp.dts index 2e79bbb98215..a5d1600de247 100644 --- a/boards/nordic/nrf54lm20dk/nrf54lm20dk_nrf54lm20a_cpuapp.dts +++ b/boards/nordic/nrf54lm20dk/nrf54lm20dk_nrf54lm20a_cpuapp.dts @@ -7,7 +7,7 @@ /dts-v1/; #include "nrf54lm20a_cpuapp_common.dtsi" -#include +#include / { compatible = "nordic,nrf54lm20dk_nrf54lm20a-cpuapp"; diff --git a/boards/nordic/nrf54lm20dk/nrf54lm20dk_nrf54lm20a_cpuapp_ns.dts b/boards/nordic/nrf54lm20dk/nrf54lm20dk_nrf54lm20a_cpuapp_ns.dts index d9964c0399a1..78da8edbccd4 100644 --- a/boards/nordic/nrf54lm20dk/nrf54lm20dk_nrf54lm20a_cpuapp_ns.dts +++ b/boards/nordic/nrf54lm20dk/nrf54lm20dk_nrf54lm20a_cpuapp_ns.dts @@ -37,4 +37,4 @@ }; /* Include default memory partition configuration file */ -#include +#include diff --git a/boards/panasonic/panb611evb/panb611evb_nrf54l15_cpuapp.dts b/boards/panasonic/panb611evb/panb611evb_nrf54l15_cpuapp.dts index 25b838667289..f7b9b478e9af 100644 --- a/boards/panasonic/panb611evb/panb611evb_nrf54l15_cpuapp.dts +++ b/boards/panasonic/panb611evb/panb611evb_nrf54l15_cpuapp.dts @@ -20,4 +20,4 @@ }; /* Include default memory partition configuration file */ -#include +#include diff --git a/boards/panasonic/panb611evb/panb611evb_nrf54l15_cpuapp_ns.dts b/boards/panasonic/panb611evb/panb611evb_nrf54l15_cpuapp_ns.dts index 545c864be4b3..301c2c990444 100644 --- a/boards/panasonic/panb611evb/panb611evb_nrf54l15_cpuapp_ns.dts +++ b/boards/panasonic/panb611evb/panb611evb_nrf54l15_cpuapp_ns.dts @@ -39,4 +39,4 @@ }; /* Include default memory partition configuration file */ -#include +#include diff --git a/boards/raytac/an54lq_db_15/raytac_an54lq_db_15_nrf54l15_cpuapp.dts b/boards/raytac/an54lq_db_15/raytac_an54lq_db_15_nrf54l15_cpuapp.dts index 7fa21fafd021..b57c2d3f8b4e 100644 --- a/boards/raytac/an54lq_db_15/raytac_an54lq_db_15_nrf54l15_cpuapp.dts +++ b/boards/raytac/an54lq_db_15/raytac_an54lq_db_15_nrf54l15_cpuapp.dts @@ -21,4 +21,4 @@ }; /* Include default memory partition configuration file */ -#include +#include diff --git a/boards/raytac/an54lq_db_15/raytac_an54lq_db_15_nrf54l15_cpuapp_ns.dts b/boards/raytac/an54lq_db_15/raytac_an54lq_db_15_nrf54l15_cpuapp_ns.dts index 3e53d6e012f9..3d0ab9ac71c1 100644 --- a/boards/raytac/an54lq_db_15/raytac_an54lq_db_15_nrf54l15_cpuapp_ns.dts +++ b/boards/raytac/an54lq_db_15/raytac_an54lq_db_15_nrf54l15_cpuapp_ns.dts @@ -40,4 +40,4 @@ }; /* Include default memory partition configuration file */ -#include +#include diff --git a/boards/seeed/xiao_nrf54l15/xiao_nrf54l15_nrf54l15_cpuapp.dts b/boards/seeed/xiao_nrf54l15/xiao_nrf54l15_nrf54l15_cpuapp.dts index 80f627a671d1..da97ca296ec2 100644 --- a/boards/seeed/xiao_nrf54l15/xiao_nrf54l15_nrf54l15_cpuapp.dts +++ b/boards/seeed/xiao_nrf54l15/xiao_nrf54l15_nrf54l15_cpuapp.dts @@ -151,4 +151,4 @@ dmic_dev: &pdm20 { }; /* Include default memory partition configuration file */ -#include +#include diff --git a/boards/we/ophelia4ev/ophelia4ev_nrf54l15_cpuapp.dts b/boards/we/ophelia4ev/ophelia4ev_nrf54l15_cpuapp.dts index ecbd975b1f81..f341d71171ef 100644 --- a/boards/we/ophelia4ev/ophelia4ev_nrf54l15_cpuapp.dts +++ b/boards/we/ophelia4ev/ophelia4ev_nrf54l15_cpuapp.dts @@ -153,4 +153,4 @@ }; /* Include default memory partition configuration file */ -#include +#include diff --git a/dts/arm/nordic/nrf54l10_cpuapp_ns.dtsi b/dts/arm/nordic/nrf54l10_cpuapp_ns.dtsi index 6ef21a6d594c..718a85947d54 100644 --- a/dts/arm/nordic/nrf54l10_cpuapp_ns.dtsi +++ b/dts/arm/nordic/nrf54l10_cpuapp_ns.dtsi @@ -4,5 +4,5 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include #include "nrf54l_05_10_15_cpuapp.dtsi" diff --git a/dts/arm/nordic/nrf54l15_cpuapp_ns.dtsi b/dts/arm/nordic/nrf54l15_cpuapp_ns.dtsi index c8467c487f0c..c2b17c2620da 100644 --- a/dts/arm/nordic/nrf54l15_cpuapp_ns.dtsi +++ b/dts/arm/nordic/nrf54l15_cpuapp_ns.dtsi @@ -4,5 +4,5 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include #include "nrf54l_05_10_15_cpuapp.dtsi" diff --git a/dts/vendor/nordic/nrf54l10_ns.dtsi b/dts/vendor/nordic/nrf54l10_cpuapp_ns.dtsi similarity index 100% rename from dts/vendor/nordic/nrf54l10_ns.dtsi rename to dts/vendor/nordic/nrf54l10_cpuapp_ns.dtsi diff --git a/dts/vendor/nordic/nrf54l10_ns_partition.dtsi b/dts/vendor/nordic/nrf54l10_cpuapp_ns_partition.dtsi similarity index 100% rename from dts/vendor/nordic/nrf54l10_ns_partition.dtsi rename to dts/vendor/nordic/nrf54l10_cpuapp_ns_partition.dtsi diff --git a/dts/vendor/nordic/nrf54l10_partition.dtsi b/dts/vendor/nordic/nrf54l10_cpuapp_partition.dtsi similarity index 100% rename from dts/vendor/nordic/nrf54l10_partition.dtsi rename to dts/vendor/nordic/nrf54l10_cpuapp_partition.dtsi diff --git a/dts/vendor/nordic/nrf54l15_ns.dtsi b/dts/vendor/nordic/nrf54l15_cpuapp_ns.dtsi similarity index 100% rename from dts/vendor/nordic/nrf54l15_ns.dtsi rename to dts/vendor/nordic/nrf54l15_cpuapp_ns.dtsi diff --git a/dts/vendor/nordic/nrf54l15_ns_partition.dtsi b/dts/vendor/nordic/nrf54l15_cpuapp_ns_partition.dtsi similarity index 100% rename from dts/vendor/nordic/nrf54l15_ns_partition.dtsi rename to dts/vendor/nordic/nrf54l15_cpuapp_ns_partition.dtsi diff --git a/dts/vendor/nordic/nrf54l15_partition.dtsi b/dts/vendor/nordic/nrf54l15_cpuapp_partition.dtsi similarity index 100% rename from dts/vendor/nordic/nrf54l15_partition.dtsi rename to dts/vendor/nordic/nrf54l15_cpuapp_partition.dtsi diff --git a/dts/vendor/nordic/nrf54lm20a_ns_partition.dtsi b/dts/vendor/nordic/nrf54lm20a_cpuapp_ns_partition.dtsi similarity index 100% rename from dts/vendor/nordic/nrf54lm20a_ns_partition.dtsi rename to dts/vendor/nordic/nrf54lm20a_cpuapp_ns_partition.dtsi diff --git a/dts/vendor/nordic/nrf54lm20a_partition.dtsi b/dts/vendor/nordic/nrf54lm20a_cpuapp_partition.dtsi similarity index 100% rename from dts/vendor/nordic/nrf54lm20a_partition.dtsi rename to dts/vendor/nordic/nrf54lm20a_cpuapp_partition.dtsi From 5720f4aa54e92b8473f5468e4154216a0928b3f1 Mon Sep 17 00:00:00 2001 From: Ren Chen Date: Tue, 30 Dec 2025 13:47:36 +0800 Subject: [PATCH 2062/3659] tests: secure_storage: skip flash erase if no storage partition On the it51xxx soc, the psa/its twister test was failing because there is no storage partition defined. This change ensures the flash erase function in the psa/its test only runs if fixed partition labeled 'storage_partition' exists. Tested with: - west twister -p it51xxx_evb/it51526aw \ -s secure_storage.psa.its.secure_storage.custom.both - west twister -p it51xxx_evb/it51526aw \ -s secure_storage.psa.its.secure_storage.custom.store Signed-off-by: Ren Chen --- tests/subsys/secure_storage/psa/its/src/main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/subsys/secure_storage/psa/its/src/main.c b/tests/subsys/secure_storage/psa/its/src/main.c index fc075f1d3e17..712be32c7606 100644 --- a/tests/subsys/secure_storage/psa/its/src/main.c +++ b/tests/subsys/secure_storage/psa/its/src/main.c @@ -9,7 +9,8 @@ /* The flash must be erased after this test suite is run for the write-once entry test to pass. */ #if !defined(CONFIG_BUILD_WITH_TFM) && defined(CONFIG_FLASH_PAGE_LAYOUT) && \ - DT_HAS_CHOSEN(zephyr_flash_controller) + DT_HAS_CHOSEN(zephyr_flash_controller) && \ + DT_FIXED_PARTITION_EXISTS(DT_NODELABEL(storage_partition)) static int erase_flash(void) { const struct device *const fdev = DEVICE_DT_GET(DT_CHOSEN(zephyr_flash_controller)); From fa646a28fca9f199fedf0e328cc7eaf94ba21b15 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Sat, 17 Jan 2026 20:12:01 +0000 Subject: [PATCH 2063/3659] ci: pr_metadata_check: do not rerun on edited This workflow used to host the "empty" description check and had to rerun on PR title edit, but that has been moved to into the (faster) dnm workflow in db18e4c5079. Drop the "edited" trigger from this one as it's not needed anymore. Signed-off-by: Fabio Baltieri --- .github/workflows/pr_metadata_check.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/pr_metadata_check.yml b/.github/workflows/pr_metadata_check.yml index bec49363375f..6d48d29129b1 100644 --- a/.github/workflows/pr_metadata_check.yml +++ b/.github/workflows/pr_metadata_check.yml @@ -8,7 +8,6 @@ on: - reopened - labeled - unlabeled - - edited permissions: contents: read From c8e1138bc63f02431066f5468981110e43ebc510 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 15 Jan 2026 15:11:07 +0100 Subject: [PATCH 2064/3659] manifest: Update nRF hw models to latest Update the HW models module to: 4d11a73d62bf999205f16de21a0ef675501f5b21 Including the following: 4d11a73 makefile: Check for more types of build warnings e53f8db hal: Disable unused-parameter warning when building hal files 5dfba9f RADIO: Avoid 2 shadow redefinition warnings 4a4f979 nrf_hack: Avoid a shadowed redefinition warning 4b9e63b misc: Fix a couple of signedness comparison warnings d46094f CRACEN: Fix an unused parameter warning 1cf2b04 CLOCK: Fix prototype and one warning 2dab612 nrf_clock: Select header based on symbol instead of platform 0b45a30 54 CRACEN: Make it clear that fallthrough is intentional 7945bf8 GRTC: Add PASTCC model 0a997e5 nrf_hack: Trivial refactoring to remove duplicate code f328e9b cmake: Add build defines to nrfx library 3824f9c hal: nrf_common: Add repl. for nrf_address_{bus,slave}_get() Signed-off-by: Alberto Escolar Piedras --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index d7b3c675b8ed..0fd53432ccf5 100644 --- a/west.yml +++ b/west.yml @@ -344,7 +344,7 @@ manifest: groups: - tools - name: nrf_hw_models - revision: 0f0c43748111c65800c6920f1c0690676423a351 + revision: 4d11a73d62bf999205f16de21a0ef675501f5b21 path: modules/bsim_hw_models/nrf_hw_models - name: nrf_wifi revision: eaf223da0c3f987caa1156cbed54b513bee4ba37 From e38ddf4edf733ace84830434fd40c8304861c91d Mon Sep 17 00:00:00 2001 From: Gaetan Perrot Date: Wed, 14 Jan 2026 02:19:19 +0900 Subject: [PATCH 2065/3659] tests: bluetooth: btp_mesh: return error when blob target list is full cmd_blob_target() always returned 0 even when the target list was full, making error checks at call sites unreachable. Return a proper error code when no more targets can be added so callers can correctly detect and handle the failure. Signed-off-by: Gaetan Perrot --- tests/bluetooth/tester/src/btp_mesh.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/bluetooth/tester/src/btp_mesh.c b/tests/bluetooth/tester/src/btp_mesh.c index fac15d8a8963..25cebad46683 100644 --- a/tests/bluetooth/tester/src/btp_mesh.c +++ b/tests/bluetooth/tester/src/btp_mesh.c @@ -4486,7 +4486,7 @@ static int cmd_blob_target(uint16_t addr) if (blob_cli_xfer.target_count == ARRAY_SIZE(blob_cli_xfer.targets)) { LOG_ERR("No more room"); - return 0; + return -ENOMEM; } t = &blob_cli_xfer.targets[blob_cli_xfer.target_count]; From e9b8784f2fbb69eb1626403ec21aa3f2d040168c Mon Sep 17 00:00:00 2001 From: Stephan Linz Date: Fri, 9 Jan 2026 22:11:59 +0100 Subject: [PATCH 2066/3659] boards: shields: mikroe_mcp2518fd_click: prepare for variations MikroElektronica offers various click shields, all based on the MCP251xFD chip family. These include, for example, the MCP2517FD and MCP251863. All of these chips are software compatible, meaning they can be used with the same driver. This preparation makes it possible to introduce additional click shields, each with their own name. These do not differ in terms of functionality and handling, so a separate directory for each additional "similar" module is not necessary. Only an additional DTS overlay and documentation need to be added. In addition, missing copyright strings have been added or their labeling has been adapted to the current guidelines. Signed-off-by: Stephan Linz --- boards/shields/mikroe_mcp2518fd_click/shield.yml | 6 ------ .../Kconfig.shield | 2 +- .../doc/index.rst | 0 .../mikroe_mcp2518fd_click.overlay | 5 +++++ boards/shields/mikroe_mcp251xfd_click/shield.yml | 9 +++++++++ 5 files changed, 15 insertions(+), 7 deletions(-) delete mode 100644 boards/shields/mikroe_mcp2518fd_click/shield.yml rename boards/shields/{mikroe_mcp2518fd_click => mikroe_mcp251xfd_click}/Kconfig.shield (69%) rename boards/shields/{mikroe_mcp2518fd_click => mikroe_mcp251xfd_click}/doc/index.rst (100%) rename boards/shields/{mikroe_mcp2518fd_click => mikroe_mcp251xfd_click}/mikroe_mcp2518fd_click.overlay (78%) create mode 100644 boards/shields/mikroe_mcp251xfd_click/shield.yml diff --git a/boards/shields/mikroe_mcp2518fd_click/shield.yml b/boards/shields/mikroe_mcp2518fd_click/shield.yml deleted file mode 100644 index 817ea25ca7fe..000000000000 --- a/boards/shields/mikroe_mcp2518fd_click/shield.yml +++ /dev/null @@ -1,6 +0,0 @@ -shield: - name: mikroe_mcp2518fd_click - full_name: MikroElektronika MCP2518FD Click shield - vendor: mikroe - supported_features: - - can diff --git a/boards/shields/mikroe_mcp2518fd_click/Kconfig.shield b/boards/shields/mikroe_mcp251xfd_click/Kconfig.shield similarity index 69% rename from boards/shields/mikroe_mcp2518fd_click/Kconfig.shield rename to boards/shields/mikroe_mcp251xfd_click/Kconfig.shield index 5db87f809c78..76ed0ab4ae09 100644 --- a/boards/shields/mikroe_mcp2518fd_click/Kconfig.shield +++ b/boards/shields/mikroe_mcp251xfd_click/Kconfig.shield @@ -1,4 +1,4 @@ -# Copyright (c) 2023 Andriy Gelman +# SPDX-FileCopyrightText: Copyright (c) 2023 Andriy Gelman # SPDX-License-Identifier: Apache-2.0 config SHIELD_MIKROE_MCP2518FD_CLICK diff --git a/boards/shields/mikroe_mcp2518fd_click/doc/index.rst b/boards/shields/mikroe_mcp251xfd_click/doc/index.rst similarity index 100% rename from boards/shields/mikroe_mcp2518fd_click/doc/index.rst rename to boards/shields/mikroe_mcp251xfd_click/doc/index.rst diff --git a/boards/shields/mikroe_mcp2518fd_click/mikroe_mcp2518fd_click.overlay b/boards/shields/mikroe_mcp251xfd_click/mikroe_mcp2518fd_click.overlay similarity index 78% rename from boards/shields/mikroe_mcp2518fd_click/mikroe_mcp2518fd_click.overlay rename to boards/shields/mikroe_mcp251xfd_click/mikroe_mcp2518fd_click.overlay index 5836f654438f..c5e0fce74289 100644 --- a/boards/shields/mikroe_mcp2518fd_click/mikroe_mcp2518fd_click.overlay +++ b/boards/shields/mikroe_mcp251xfd_click/mikroe_mcp2518fd_click.overlay @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2023 Andriy Gelman + * SPDX-License-Identifier: Apache-2.0 + */ + &mikrobus_spi { cs-gpios = <&mikrobus_header 2 GPIO_ACTIVE_LOW>; diff --git a/boards/shields/mikroe_mcp251xfd_click/shield.yml b/boards/shields/mikroe_mcp251xfd_click/shield.yml new file mode 100644 index 000000000000..607cc01b077d --- /dev/null +++ b/boards/shields/mikroe_mcp251xfd_click/shield.yml @@ -0,0 +1,9 @@ +# SPDX-FileCopyrightText: Copyright (c) 2023 Andriy Gelman +# SPDX-License-Identifier: Apache-2.0 + +shields: + - name: mikroe_mcp2518fd_click + full_name: MikroElektronika MCP2518FD Click shield + vendor: mikroe + supported_features: + - can From db302632e6bd594a07f4e9f09da5f9ed538a522c Mon Sep 17 00:00:00 2001 From: Stephan Linz Date: Fri, 9 Jan 2026 22:31:43 +0100 Subject: [PATCH 2067/3659] boards: shields: mikroe_mcp251xfd_click: adjust documentation The documentation now contains an introductory section covering the possible variants of this shield. Furthermore, the existing documentation for the MikroElektronika MCP2518FD click shield has been enhanced with additional WEB references and the missing picture. Signed-off-by: Stephan Linz --- .../mikroe_mcp251xfd_click/doc/index.rst | 41 +++++++++++++++--- .../doc/mcp2518fd_click.webp | Bin 0 -> 39584 bytes 2 files changed, 34 insertions(+), 7 deletions(-) create mode 100644 boards/shields/mikroe_mcp251xfd_click/doc/mcp2518fd_click.webp diff --git a/boards/shields/mikroe_mcp251xfd_click/doc/index.rst b/boards/shields/mikroe_mcp251xfd_click/doc/index.rst index e54bf7509c7f..ed7584790227 100644 --- a/boards/shields/mikroe_mcp251xfd_click/doc/index.rst +++ b/boards/shields/mikroe_mcp251xfd_click/doc/index.rst @@ -1,24 +1,39 @@ +.. _mikroe_mcp251xfd_click_shield: + +MikroElektronika MCP251xFD Click shields +######################################## + +Zephyr supports a few different MikroElektronika Click shields carrying the +Microchip `External CAN FD Controllers`_, either with or without integrated +`CAN FD Transceiver`_. + .. _mikroe_mcp2518fd_click_shield: MikroElektronika MCP2518FD Click shield -####################################### +*************************************** Overview -------- -MCP2518FD Click shield has a MCP2518FD CAN FD controller via a SPI -interface and a high-speed ATA6563 CAN transceiver. +The MCP2518FD Click shield has a `MCP2518FD`_ CAN FD controller via a SPI +interface and a high-speed `ATA6563`_ CAN transceiver. More information about the shield can be found at `Mikroe MCP2518FD click`_. +.. figure:: mcp2518fd_click.webp + :align: center + :alt: MikroElektronika MCP2518FD Click + + MikroElektronika MCP2518FD Click (Credit: MikroElektronika) + Requirements ************ -The shield uses a mikroBUS interface. The target board must define -a ``mikrobus_spi`` and ``mikrobus_header`` node labels -(see :ref:`shields` for more details). The target board must also -support level triggered interrupts. +These shields use a mikroBUS interface. The target board must define the +``mikrobus_spi`` and ``mikrobus_header`` node labels (see :ref:`shields` +for more details). The target board must also support level triggered +interrupts and SPI clock frequency of up to 18 MHz. Programming *********** @@ -37,5 +52,17 @@ References .. target-notes:: +.. _External CAN FD Controllers: + https://www.microchip.com/en-us/products/interface-and-connectivity/can/can-external-controllers + +.. _CAN FD Transceiver: + https://www.microchip.com/en-us/products/interface-and-connectivity/can/can-transceivers + +.. _ATA6563: + https://www.microchip.com/en-us/product/ATA6563 + +.. _MCP2518FD: + https://www.microchip.com/en-us/product/MCP2518FD + .. _Mikroe MCP2518FD click: https://www.mikroe.com/mcp2518fd-click diff --git a/boards/shields/mikroe_mcp251xfd_click/doc/mcp2518fd_click.webp b/boards/shields/mikroe_mcp251xfd_click/doc/mcp2518fd_click.webp new file mode 100644 index 0000000000000000000000000000000000000000..06e7c8019b2d463cbd81ed26cde8d65d4199b72e GIT binary patch literal 39584 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 ocaa#%H4e?S6C-hm(xz Date: Fri, 9 Jan 2026 23:05:44 +0100 Subject: [PATCH 2068/3659] boards: shields: mikroe_mcp251xfd_click: add MCP2517FD click shield Adds MikroElektronica MCP251xFD click shield with the Microchip MCP2517FD CAN FD controller. Signed-off-by: Stephan Linz --- .../mikroe_mcp251xfd_click/Kconfig.shield | 5 +++ .../mikroe_mcp251xfd_click/doc/index.rst | 36 +++++++++++++++++- .../doc/mcp2517fd_click.webp | Bin 0 -> 52894 bytes .../mikroe_mcp2517fd_click.overlay | 25 ++++++++++++ .../shields/mikroe_mcp251xfd_click/shield.yml | 8 ++++ 5 files changed, 72 insertions(+), 2 deletions(-) create mode 100644 boards/shields/mikroe_mcp251xfd_click/doc/mcp2517fd_click.webp create mode 100644 boards/shields/mikroe_mcp251xfd_click/mikroe_mcp2517fd_click.overlay diff --git a/boards/shields/mikroe_mcp251xfd_click/Kconfig.shield b/boards/shields/mikroe_mcp251xfd_click/Kconfig.shield index 76ed0ab4ae09..d4c30469a01e 100644 --- a/boards/shields/mikroe_mcp251xfd_click/Kconfig.shield +++ b/boards/shields/mikroe_mcp251xfd_click/Kconfig.shield @@ -1,5 +1,10 @@ # SPDX-FileCopyrightText: Copyright (c) 2023 Andriy Gelman +# SPDX-FileCopyrightText: Copyright (c) 2026 Navimatix GmbH +# SPDX-FileCopyrightText: Copyright (c) 2026 TiaC Systems # SPDX-License-Identifier: Apache-2.0 +config SHIELD_MIKROE_MCP2517FD_CLICK + def_bool $(shields_list_contains,mikroe_mcp2517fd_click) + config SHIELD_MIKROE_MCP2518FD_CLICK def_bool $(shields_list_contains,mikroe_mcp2518fd_click) diff --git a/boards/shields/mikroe_mcp251xfd_click/doc/index.rst b/boards/shields/mikroe_mcp251xfd_click/doc/index.rst index ed7584790227..fafc9eb72b41 100644 --- a/boards/shields/mikroe_mcp251xfd_click/doc/index.rst +++ b/boards/shields/mikroe_mcp251xfd_click/doc/index.rst @@ -7,6 +7,26 @@ Zephyr supports a few different MikroElektronika Click shields carrying the Microchip `External CAN FD Controllers`_, either with or without integrated `CAN FD Transceiver`_. +.. _mikroe_mcp2517fd_click_shield: + +MikroElektronika MCP2517FD Click shield +*************************************** + +Overview +-------- + +The MCP2517FD Click shield has a `MCP2517FD`_ CAN FD controller via a SPI +interface and a high-speed `ATA6563`_ CAN transceiver. + +More information about the shield can be found at +`Mikroe MCP2517FD click`_. + +.. figure:: mcp2517fd_click.webp + :align: center + :alt: MikroElektronika MCP2517FD Click + + MikroElektronika MCP2517FD Click (Credit: MikroElektronika) + .. _mikroe_mcp2518fd_click_shield: MikroElektronika MCP2518FD Click shield @@ -38,8 +58,14 @@ interrupts and SPI clock frequency of up to 18 MHz. Programming *********** -Set ``--shield mikroe_mcp2518fd_click`` when you invoke ``west build``, -for example: +Set ``--shield mikroe_mcp2517fd_click`` or ``--shield mikroe_mcp2518fd_click`` +when you invoke ``west build``, for example: + +.. zephyr-app-commands:: + :zephyr-app: samples/drivers/can/counter + :board: lpcxpresso55s28 + :shield: mikroe_mcp2517fd_click + :goals: build flash .. zephyr-app-commands:: :zephyr-app: samples/drivers/can/counter @@ -61,8 +87,14 @@ References .. _ATA6563: https://www.microchip.com/en-us/product/ATA6563 +.. _MCP2517FD: + https://www.microchip.com/en-us/product/MCP2517FD + .. _MCP2518FD: https://www.microchip.com/en-us/product/MCP2518FD +.. _Mikroe MCP2517FD click: + https://www.mikroe.com/mcp2517fd-click + .. _Mikroe MCP2518FD click: https://www.mikroe.com/mcp2518fd-click diff --git a/boards/shields/mikroe_mcp251xfd_click/doc/mcp2517fd_click.webp b/boards/shields/mikroe_mcp251xfd_click/doc/mcp2517fd_click.webp new file mode 100644 index 0000000000000000000000000000000000000000..255b8499fe3c3650875c859525ce7eae31bebe2e GIT binary patch literal 52894 zcma%CQ;;S+upQgBZSL5%ZQIt4ZQJ(j*tYH2v2D+H_kXze`Bo(_N$PZ}>vW&4N=I2r zTs&IKN&>^$5^$$boj?X zxa1>dVfdJY{_j))lAFy@+qt5#Q65M0UAP)INh7#bhH%Q?<=f#q@b~PEmNH|p zGoOO)w@D(?RpN5?2IF;%R|nH%op3$%LZM-{0!V`d6X>$78ijMuQOJz&B13t*HfY60 z98uU=+F(mb2P|aiWt^7la!&VnQD$nz5Mv)WRPxSACJ3xsma#l%>KoCDIbH-+&+Jq| z-S8`oSu{+ltUoJ5QgMaaJ}C!RwD?IB*r9D{K}QJBx5-LpN=n=VvKxn%V39wIT+K~a z%y=+rR)6A6ssCzK0<(EcH2R0DbhB-eY9ja6?=ZcjiPqom7|rB1etG<&bkkdlUspnT z36Av6$>`QeYcP{SZn2&)K>o3dn+sA0DAP zNPYa=%mL&~AM9;+$J0ba);l&gdyf+V)h2(p_d&SpfNbGip0~L9LKv7X^a?!<~bM8cuo-6FLMzpshE7IY;w51aO#BT+-J7RRQ{4;? z0?lHUdh*y_qDJQc>@_By?rcyaOC@%}sc@@k|LN_1x!I`ZfACG zEefcK|BaD;De{*H^;Hv0cpR!+#TB-f7b#=>V?JMXgUo_l--) zv0<>NJw(c>5@f*2F6kh~XunwruLK4yorzk$%@+V4O>Tvvdj_1nSG7q#U^NPuHKS&5 z)C$})3>9-E{hI=&vGN~fGi{1FCDExEjFfZi;n!{)qn3J;(JVYq8qqM@OZF0%8vmKx zb+JQ(tOOY$myKGY|Lh{Sn4EhluH`cqA>seGp4tL@@9irSI z>($>BYF(!rSbOn>+Amc|3E7^+5KpZXFh>-N$OUb#aN}|{kw6`hm_>pPHbnsvc2#7H z$bv_zLWzsa{YUpYsgnP;85F!MnjX^_j1aX_K)cusB0zp=z~S(7u5d4>x%G7TfAp>? z*Oq#U!!h+Vp5*(Jz5Tp?-+u1C_CcZn{ZkjBn>-*Oq!8d-V45f3Ct!YTm=Gc2(5`1N z2p}W6+MVT`Hsb|TNFts%o)(VHdYxW@V~<9Es#nr;LP&qx@4C;fpYRWZR)h<_-S6A) z{PsDISu+6e_vKgkXZ+PJ0Py;~2ypvZdjvhMe@1)|xat|`lNaa#xc>kEn4gpYz)yZy z-yUEY5PfU#squOHAy91q3djU#0t~+MU+a%Azh6Hco(OyU=l~UfWPr>M?zhDEZUNyT zVD9I$*G}N%lja|Zd;s~|gzvX63SWeIeGGtGz`cLbH{e6)r}8Hl0Qq6C8(+|OM!4;N z_It_y^Bo8(F8;R~`3)fJwKHraZ<*&%!oG-GXctT{d zSORyfi#*jVUu3*2x8{**H@P-rRtsXJ0kW;GMUH~ z0C66n@AAhl^4Z)ae=UEjk55&$`19Qe>d5ADGCtPH5N~=Y0pHRWJE7<9k?&cDG1~(N zhP4+muv2Tj@;=05Z$l`>PSf{P@hb!!)irF>cx$QZ5K%cp$AZPicwVhy(Cz7t3&g%b zjQ-yr?glv>C%Y^Zz+=L)ZFfUl@Lo!K2C@t)hXK)+v+RdD*`JIT1mvBOCAqZJm*~X@ z97d=Eot_N$6z|{2G?tq6iAo0sjbVmFzGs;@%bLX(AS@O8P87E;_V0lc5G-L*KAjN9-P;%X&>S@0DB~IZ?hOQkTka3G@cUq$XJZDyGYE zDYUV3uE5NN<5QI_O%7npwF<3{4T7A6kA)Kc5#rQ&HjwQ$5J58~oi#?2pg+s*qfweb zzq7mgv!WE&)y3<}snqVLTXg++o$bs+w-D0KYP*7LuT@$rN;WmXh{;}=)~@CP849$Q zt2?LpRaTTS<~h@oFjGA}_=R5<3lwcj{XCY!8nd|^@5@B{xnjc*%(9J=0+}d_d~A+_ zQ-eNv7t-iQ=2}2WRF*Z{#c_pR_B|Lf>CU$G-W*h=*@lAg zH+B~o40*%h(x{MU;bfwF>p^G|%GYDh7Z9O}1!AsZjF~8{6r%mq=5`(Gsk3M%dmg}3 zevo=R4_}Wgj^+v)rMtiV)8Z;wUXNovd!IS8h#<%uE%QzOex$W4Ewi=)_sLwB308ZU z#jd@5OAsh+#e%~WKM!SKc4yj`P$Pfe+sEL+=WHRiYzbcIvj407~+jsj*MpQ+xG$W$QSOj%;qFy^4x>t2Zpm3 z@AyU>2wuZ(XqIA63$`Yzk|ssC7P=8c$9Kkg{B?oJTsv5DY;Z-M4Q1T=K7;y(gBN1} z8+{0-x*dXu6yO>COV1ryy2|p@1RnDOJl#|h`xcZ@b1C#8$cQP^{Hvcuh<6ET_PsJ~ zeF9|n3MLjDIz*w+J8#OqoWT!Q>y;7;RsDO_?iD`6IpuHd%b~*e?}`}WK^mYVk=6WT z5U*Ph#k;&Nsl?u0kF>|>rgAb0`7a?^?ny=+>kjx|5g6NCrMi=#Yt(v0;at+QB$aOu z%xC&9oQ>Z|YeX3`p|rx#^>Blx|$5(Lct;cCU0xW%r(@kaX zh^pDEPY`C6p!5^Bj4FR)ldwT0ST-wP(!F=2isXH%2A6zLU2?iy0COT29j3KNXr+PQ z+Lv23J(nAMWCGDwFKKAweo+#;#_7{qZAGg_o8W&)1tbnVIUk+7HOMB~v^fLO3 zt5by|1fX0>6)wS^3^mlmeh$*O`V4)69ys&ITd)c=Lbbsk(rwT7CRlcdKK?O0lC_pW z&)C-Y&@gBv=1b<+rHo~2UhfsL6tXJ(q!pDZy9+!ePJs}X3!hl(S`ClEY<4A4t}IjJ zMgoPlpwY|;4H@MRFE)jaq*U4u-w=uKQ&W`XD%xZEH<(f0(qyKU z9~XV9-KQ1$c$(q$CO5ca_&uI_S74AX!J_oORc+UGXS+K>9OMmXG)s1d8e!#QaV|Hu z;&5s2!Tff!R}!Idy1!=WBXQq~h=vOHTXTLLF2ZgkKDrprZ8wTio!~Gdm}fmqG?%J1 zX1yYRw`4`4K(QK3Ocb6{+VKV8a$cm~1#J>NQ{qk>@Qc=cC-0a(1CnJniQ@pql$uRn zEAka?eW!cZWwcA7C%rrA5gEBCUFAx-cLnM}-OecUC=G-pvLNu?r z8LEacwp1yqz`RrJoPH$2FUo*fE`2)EFIsqHt#vkBJsP(wO@#O3`>#4Ys`0C>9v}EO zr;y_5c*9r*8_T!jmnD|v<3MXEiBOv@e7$swVRCfu`JF$n*maiCR{2fY-Z|j3iP&<& zw*=JeZ$Evv(d1kU`e5z~*)qULgT$5r2t$3dR+#ahUz z3Ft&?QT$&-hrsopb{n7=a{Y90s0c##YNd96PGp|*5wA)Uy<%J1tK03;&!bjbpklOd zszmL(_Yb(*SzSWMmuVnGQ28d=WC7S?e;tJ50U&LE^VCk{Q=B8t*k z^E1i_?N~&vl;4p-$)@~j-J=M|-W*U#q3T_B!>8DjT1g&Z19%MP@hAZObh(eNkX05Q z;g0BUtgPq|J4&1f&=iJd%&JopfU$3Z>kQ@7M;c8P;umVd|G0?FIWxva6cX1YepmjJ za8T}?W{(w_Gcq}1_%NIO8+I~KZI5odrTP_6>(`O`N40)o5occH?M>Do{y25slf?!k ze>GZApzoaCO5&xfgY7@5`uZrPxX~&Tnjl0TF=sZ>F@cvkhQwLL!q|$-)d25Iix*6M_<@dv(Xz z!A6c60-j`gt&RF3Io^p{Vs}&NLC-d%tq(I8(3FJFKZ@ZV1$mNC@1IIZShRd|sZM&>KiW*{gP7HF{)T!Lg<*M;yt}61 zpmm{?{7wz)5Y7PZv)b=6^apf1lcop#sUi&NXcZ`RuJ2*!xyN(oxI+;T;lgX^P#Xlz z->J|upm6hlp~SS+zyH)FPC$P(V*);?ckK14@K{kXMNL!*4vX9Qy>4G5iELhyYWH1M zMxevW6|ch}DKaEiD7{Iqu7-5o)jiQ<#pL}{&$t#?f?cztJd6P@b1sOL@?e+ENRc03c{K=KF-KKwc8$nyE&ZtsCd8|9QJ-ki=P$1tV^nG zOA9`inzO7Z3vv4RQPHfcsDSg%wmVMk&q75%LlV8)-xxOKPKB(1Qc3_d!;;j?AFQ?v zD9=JpR6fk$>2QM^l5d0(MNM-{)x1HkbT}j+s*IG{ZM~R7pS}X_S&gfD1Mw!xGurGm z-&8n8?#}U!?Gs`t0>mE-8JpxqEZ_#8*wfxZXEWuxg?#0Q9m0jXYEPBsqRHKGO%F1mk`0y`_`N@l&e43yQK+K-bR)JH ziQ{B)5~vs=Znv}W8l!<-${8$qkdi-0&t|U^gKq4C0l>Pha6-HoEtrV4pgPIFMY>zW z9D{^L^{lE?mp@WY!SCZ7iVFFkB$m_W`&AyhT)k;&f{<~9GHvvfJrLybIK|De`;hIbp zr*!@lj@SYTrvj8e{{Vc<@RE}LYVElR+MF)y1`R7 zYeeQ@mlMEk?e16qMc>M~M05G-;e$%b&V2j?l9QvQ)*vS8AX`?+&X3(_+nLuLQ!Y^xEIQSRGob4mPL%8nYNgzQk^ys5#_RRP1F! z_J=7$b4|yOdMKe_m%g8ug zv}|Mxa>~=(EajU=Z*TgP*Qn3VOE*(tX4_W0JE%2#sc%qbDdCUpAr!a&0gf{Iy2Pk@ zMr6E28JdNs8TwrZ(iwOoY9yvq-b2Yp|0jybZAoK^C3T%E8w*@PrOu3pNiC6W|;)z2k zPUd&A+rWD>D-_g$Wh?uPjQAe*Lxku@8<>G&gCVrno2U$ zIcGVWiKLJWIP@X4(t-BHhH7wvL}EhKfRXh;Eq(Bk<$33I91Rg=pQ_?OoE#N)J@8B? zk~J*%aQ1COO&-Nq2~H;OKQ=m7vqA-{X?Fa5iDBLWY`8Vr9yq|(`Jaq1e& z`&V&Kc+g6;T_Ochv7%>tnpJZQvaOpd$_6PDp~Cv_!SV&@^FqhEI(Sw$e!C4Now{HD z#QiMD(Prz>@GIew*{U>Pt5qf{0gJUy-R0a!x$r?~D(fmZZot61rh<1zItO|2M$FId z`+*5$*oe$CyiVDso?2k!9#K_iQdcN-HtAEKj9&7Ioey*7Fq6~1dM;;luy+g%Ep7Ym z7dZ7#k!py@6qdBpeci##bV~?dF=`6do<@8q(cip)r=ExheF` z?0T`r6*2Xz`KIW(7WE4bl+aLnx@J0!J}JUqP7a9PXso`GiSpxmDbRSnnh3AU1E-`K zo$dAh@285e!pqQ68!yiC|_YJn$ciD=zk$p;c1N}Iou5*>tE{2-M)L#xeC*VBegTpS8 zU|EU(NMPk&R3yxp^j!b0Uxl#wdAA5JI{C9&n~Ydz%EoY4nv$rjW%|ZKaV(oaLN&|C zgwqMMdxRfUg)6`~vcRdUx~pL3jYwKax3}XMG%|ojqmBplwgvx$;Wzqe7ma75O#VAZ zc`GGf@kXW&-#wC<=1fdd3O&BAA{k`CP|+TM;kdBz@Oi-Iax)@f;WK9v)MNlWwSoZH zf^Q>&hR^_N_p3>1Ynr9_Ny>`@-g?y1x*lcP!?oAx^9=dy{wFRkuNpTqYl)n$!hg>T z>rIYfv)AwLmu|I#D2FqH`WRO`FE?Y+oIfpiP4YWHBF2=ZuXX6Z`zd^+#T)~nWl<;u|_gDf^4Rm zqDD^pC(pCjse?Jrc5tL_PoZ^z;FUgU(aMmEa)D@^R$+6MP!Z5J;)ic{Lx&-@&Dh*uh z@55uD(eK{k8df|RXlQBFbMkQ>QxDPdd-}L{i5=p%2(AMNW)>_K-+CQit9_jUS~d?1 z=jXpKO4!&RDE?6AzS|Kv4q7O^%FAUUUr#63GF#9*`j2gntR|ge^6JhFIR{q9!{w9# zzd9kWPYgZQP3du31NUk`&@>aNuH9WOQbYxTCX{7e@{@a7gg{l(MZ zIDpS2wh!Ii^3Ru7gvAdp+|4^weIm+&X_%&PnO3@1^ituytJ`aS6o^V*M(~4Q5smej z;8RCBItPAvnpAk!1|{>sb#nPA*FQ|8GW4aT7Ue4`x1^IbJ5=O#m`>Zlo6}6jTl%2X z9C&iz?jcV$$)U!}wjWFp|Jo=#t;U}7%FEz8scW|MCPP9i3ML&4WVOWLGNv3yRiCS_ z{sdSDiko7XO+0LhWaA`}j;HbulrLSx;tf>&Ma|;_;+KlmXrQ*2!I{lFCG`D_U-${v z<$DS}fXGl$-rdhh7nvLX%~$&d6aI1_+K&2%XnJbbFVkxp>`I5(dMtnJ9uekF>6dCJ zQ7j`$Q)}3o#z1DUwmKn5$Y!CW{Pd#i+Lgu;l7DChxCJUT4b8^YqVPRt2+IrxBE1?9 z7)tCfubr5a?Fn0zRGkOUW6%o>o(JAzUmO>m)*E3zGZp`zoU1n~=2`oBPl? z9aPOsy>p9OKJi6&T51a^$t8>GG!qW*Bd(od%HG4c5Q{d&nY?9cSQ+N_FEuc{Lw@cb zO&z&sxV7W~W%XqNRM==i!zFNmTN(czedPzzp;;En`vdVl#gUS&?b^u)p8|a5mGVP@GeKkslW92fT1R)^+Q)^QOg5B*|_(`3Pzik zuc98=K_^p<6bjjxbnaCs2;Q~pAZWYyXzYHkhLJKlF$VT{mQ7QSiB*Lhm{B@E5G}$* zIVwB}$^%pQy#44)*=U;+l4OL7X3=_>4DU3@A{F+*u}fv@{hFpXC6kPV8!`?{;5W9Pu%i*S7*;w5D&DREvx zF9=QM9FQ~4B|;&dX}~j%{WmB9!f{)ZwZY~3heoR+_G~lXabIkqyQtEfZWXKxDGT0q^@Ce#XkkO z{G?#J8$b!7`Tz#DGW0qQhrfT+OZ$wPP|G#+VfbJg8-5GK{Ep2LA09VvcD|UXKF~?U zwY*dsev6GMD#iH2HZ8!v6GU3Fm>fMbIdl~n%*4wE z@#{_xGanK%UZ#aGLC)NuHT|!Z$oDwOv~Mq}y`IpDXB4#JD`!PU6TtYgxThbb9bx@|7z zU+~da!nM2~Dk*Z`m^p@XVOBN6c*Pkyrw=|W&((1NUAmb9wn!oFt!Yj%GUki*uimKE zThFO&G2~>2_>HfeNeutH4{2hYGHRVdp&Ql!X01}TX-8U(!fI66XBHd_;2{|zBDO-rIcpAmUvGp2edY|mZ|Z|4Kxpc4H#_zm$^qWr z%WV9l6jB5D-FW#q9E4<7&P%pg>S@)nC+=X>F`g49v`=z;hMz#`UIqm&B~VqXrBsPv z?g4XX%tmDTIg32tC3UZG5-d|r*5sRLwP1%no@^B2XW|d7hBuv6Nu#z%`m+!&pp`8_ z5@|MJ2DdLECVc#zOfK@L*e`Vlrxu^Erhz>lRO!0JtdZ>yQ%EUkfvIqm9`nID)42`$ zRWGQtv8<&vA0QWu&@>1ksc~Qkb(V}E@5|HDG`6r#I}a-XVnMyGosK|3?Nl}*U1!(A zHQTtVA4iJr+tor$}n!L)G=B;v>vwV-s9yZOU*a z^2T}$$Rj0HW#E{;VkEkZLpPBo@J@*eO!FaJ&PsfxsAwy`%9_G`li1=-;Q`FXmP6(T zKOUrqG+vV^%wnieZmJwl7wuC~0wTB*u$^vRNA+n%?xJ7g9g>({5`DHL_Ab=h29+{G8Z8Oc?VbwfdxvFx6fNTkQ)Az?Z#ehDHVeCA2vhJqCJX*1jRU6|^*J5W=Z&Bdq~&kWm5; za;4?oYCDBxouZi6zcwE?Yri?pOg>a zsv8TfBm?0zX%f*U{dO(Z61CW6ixE+RD zX$WTp4u%}d1oLFI5rsiJi6}_ba;o%RuWJcMK)mGysh&>*OCojL^t*n*JhQEzub2Q+ zuPVtsYh0RR#C17Rn)uj4d*o4KoVq~1IM1<}QHLtxbp`kS>$1}UX= z#}Ipnpq|7ssMa7qjBa0eNvIw{S09W*mcJ*P(eK~*iX%y@)xj@oEMw$n(JcfXc$_7c zsG^FL1$lFEOj=2@Vz|vS&MWkef|SL%gb335*}u%ff-ecGCj+Y}eJyMjC)CS9VaQoa zcUeq^%roD^*aE5i5Cvv5>zz>Y`zRAHKcX}fZ01E}U8;SPE*}dMv=X8XHm)=KqeQ1+ ztq`GOJJtJz_mWBKmFEcs8Yz7_-fe6et~R&macBY`ah6{>s;YoNSz>0kG98Mgcp2I% z@igX8K)|T}m~+`e3&u)9f9iEMoZ5-R)d|94Fj{Ayg6S6W!;5zkxl!gsPY#(UtXTCV z>lp3WSyf`?iX+7FEm{SvI>!cD4_d=WJz|*N&4Cpf>~on-F7iee{tiJ-c@^k2q0}4{ z7Y5N5RF*2lIYDV-e-W&O7y8BF6sxaO_c_4Thaas;yneZW-{In2{k zYiw)E31npq+lb|1b@StC8@a~*kQVV|QN@raLBcc`&{xSR@yOJd!V)+^fD)9VP|WA8 zHb|N5uQA6g5NkP9j3Do3m184MY})d18I>*W!w7QMr=!=Um#wL=eJKRgd}f15FqvR{ zYF9Ef^|Jt;U6t3QJQKB`5o&=O?%Ly6`hpYkz6lMOC8~(r2nBL9NL|5V*s9>?X58k| z1Up~!s|bXa(vsQcO=l|Qi7C=A6wB+HV4utG%KlqVEiJ1qYe)!stBo+ z7SXG~zdhg1P&+`61^=>0_T1&(`(Eb5D6;B-00_~2v{^-s&u*~a&xdqlTYvD(8zJ

    W>&w=#5(8Cz0P79XAWU z4wMMk57XsD40ddl)Pe-a0b8>$oOlG*fpNn$dPotTxR_2Pi){yvToR+2JMF{OHdq`I zGX&D{g!RerO{*!XcsZOxxXM-vW_CRHu*I!|>Pryb%E@rmVoxBNPLls~>QfloLtQGb zk})eJ(cfW@_w1tBQp)}l^BCW5nfN}IGkd6GF}-I;IL>8i`etQ`lf@9~Lg-PsO_U0nuX4HioOxBX&A67M7q_ml<4uEFa9i2iDx*kkh^%t5E>lFqE{f-6HLHtvvh zGV`bcEKk^SX`)af*~JKb6Ssy(Q6`RL`jtz#mk4KQeUTUL5PF?QEhnEZ4QQlsgZ(Jo zznTUPKU0H{(eh_1lS5Qkt-{9J!U1eJci1#)ffMCDk%1u#O+%M%TCCVCbdjsDpwb=- zjYN$sH@!sC=i&1i;+yx6HtSPLGd~kMpo>LBK0oX!zspq+6ej}+?Y--RiC#M9qU82* zN3huG$)tMoSWqAhy=GUVei^O@G^( zQy;{yaa5Hlk_I_TkS&E#%n_IErGu4aUrap-*snuxH2cgE9`1xD$r_V;(HiZG-VwJs zX=uRQ;o@j;tIL2X`n9yBD;-#yl-fx8dG>EwX~LYlZ^Lci~dgh0l13b5c<0iD`}W# zlG8b5x(KO%>;Z`lXe`J){bj5{zHZ@Asa=~Am-89NjBPGW1!`W61K)Y#tXJ`)sp|;? z#2-)zq&!B5YLvZVl`|WySN^4|J8}Sr5s16pzPradRD6G7giJcQCSF*U362fZXy@0w zh@jXyv%c<_GUGo4Ng)x%DN<~kv{s<(*t6qj*tucE&fSo$m#mE?KX*XvT|jl(wV&rj zobD404QEM$Om>-ALR1Rh?`h#LBlb(ZBFBjDcsN=nj_+X&KD-U`8FK=yIfEo(D8I_a zPDNx)LxhBS`!NW%^ud#?lh+12!ciblCKZQiq3M^SEO}YO4buK(`u$&ruBp>gu`m_< zHpkn;`Q2glasetq_2948#xjk-kV4z=<|f#oyKA?AQnLLej}a5OwMJHLafJqv5m_of zxPtwYG8}w);Gq{08p^nO3hrqF`fZSUf@;c7uIA@~l{7aBAgdJ|x{|$nGWP<}YYq!D z{g#VgtoTs`p{Msk;Fz+}C5r4qGK9Co9G7uK9nPs%A4Hzz?qzw?!U~d*X(dp-?*s3w zV{=ahp3UBv3r zZJRgpKUM!4xuaPFJHKW_hE!TBvoY#c97DrCZkBJ`s@}AK2M)S-cY2Sr!;GEKG1ct@ z^jpL~kr|yVUBVaUIy^jd|Adh%qqaWM)pU`6Y4c{fKtW$(p}nC;KS`aQyBd%!>9|W5 z6fb!Sx$Vp+H`M1e>N%;+$UA+SZ%dg1b4njJbpjPpSWQ^-70Y&mfb2)jU== ztQOsE>#*(p)nQ7KILU8sm3J_AG_mO={Q zD$l>Gowyut{D5ZExvjmFOP>;%){oZ0d6a}@b8x$pAzg?m;U#r~GcGG8Uba1_ldcMm z2pKhyu5St6N##tihs2rC@KY)H#<$D0rv*QwiAbIASsBy>*j2wm{l@ud4r6yh62{lA zFDo!5RFAItdx*@^U4s$UV#%;$!gU^x`~H&d;!-HlbxQNf-CqE)_&6J*o=CX>Gc@eX zMA2sK+0QhJ6^8q?=BqtPk^B`J8UeE#)w-FxTNM0$?9t6M>!Q z2nj6cbiN|Ge0~N8xh*LphDH{PV~B)65{Ai4!rngr=c27WnJAQ$jH91%kl@viB%#3- zwTr!rq^a?&u3%SEKZcqzH*dD-+9hY{1Na-dQ+zmEFJgDLOg%{ij^EJMjQ9hkO#mz{ zso1N-V*MKoG>=3bj$33&YDk7?hD*lQ$2y-kwq<$(aeDm>ekGALVh3SVmc&&lSr1W7JQi-cb)tIIeyYuoJsB!}B!h@s3D7a0#y;W)(|K;*ilj;0*67S?7^=-8_SJbiT* z76zqc4PPPrD>;o*tDX*yzMdx&V}CoZC51_*x)4phNl&jhQ17C0a+PvA**T2Ptm78F z8Gdo7N)gm`XLyvDKp;Vf+d??b!%jys@o6+K0EHyUGSc-lxwHX2!PnhL z46LlX(ey%6%`!DK5^hkTTx87z&nvt?vCnq^9ZEob zz5t;O*f@CT*Ck&>M`lx39`_Y&bv6Q{|Lh22c!KZ-{LuIJwQ{1;90-eF{6SBHSF*3Y zRG~~2e_25#Ve(j?uHZr0=@gKk<@v1glPah=#Rn`uXggHrexgMB-gkmM)9fS%G`OX` zv4mTwb_kJTb#>K5u)TFw&9g092h=Ikca(0G4#@5jLM!-w!gd4L#6j+rs5sh*gYk-6@Af~6GxdTFx|Ql zXS8v>{=MD6jnDhfUvpxdrEo3MR{BpTP#FZw7u-bw&6oO;_E*z&&qG=SK->70pU{?v zpq}9p@K@Q6kH)yd`iYFW#tcEws3sw7iXn>VY34zyyy`t_K&D*{l^*I1UjS02EnI8R zC`3-Q)cME7$QGVur_Z#L=Tx*Kv4vqGPH4bCw`Ko?qZu3xZ$cZHqZHAz>#ur$wG~_z zpQHZ!HW!bdoHN1VAW9SeItEKSUNj~nKoC~AB?bdcb3PZnc2FbM>b@P)o2Bf^syz9H zVZ;b#B+xU-B+p7blwz4g2EHXb6=ZH*5=31FO4)AZulc$7ZS0rwj<%R1p2^&0)!WZI z`ymADa~4e5MRZ^CVy5Ts2AT<{q$yj}9U=YD=tXVw9&YvF9L7J$EIcl+ah~#s!0~(T zzy>OL9^QRH#;WNY!D-&@Z~eA%5>sc7o#fOhE-d?8}2dj=$2h?826fDqjfsndY8$2l>F{0ID-X ze=-^g!!^c^5hg~F1^d3am{fZ7{&g1NaJ$%+wOd^Zdn|=}UFHO5l1Ih}3ga(Wl>K_% zFEJ(VIWWiLcDAy$@fFcq3Al1x5MWH>)aDRgBbUCpD(<0clW6MLkxgvjw{^lhqX1fS zJCdL1SKEQwj9X_1xM9D5Bd=(0*Q7cJJWsBXuo5X^VycA7hjk;#f%zVnV2f`H`AYQ!C~eTc(FcT$!7RKj|lcgpy_6SBz{cRW^Hu5QnMSQt^EV|uWzq(5S; z&Hb0^!leREv&M=d^OA&BI@$$$g#$-3DeaIM#R8Zf+_Zy=_e{p7%dRHE7I_ZjMv~7o zhFo(O)8Hg(Bp8?t!%pkOwPmZNavbEc7iLObF<3QH3FI}IJ*jIu@2x(Ne>9C3O=S>_ z-}Mu;C*KiF!X0oH)q4|*uu}3fW!JCG*j~iL>DF^}L?9o+>vGUTbZReP30z2#;s|9* zqFaKy6#soX>=9CIHDEDMx-m7sNN(i6BcJ~jv#tN*$u$vuf*olpeiNlR$%sU%Rmp*{ zAG|D0*Cl~EUz8WwTo6ABlj*0dNi|l3PC%+V zg5?7N?yvY{{#GB>UjdKrz{y1iwbIgEx4ul{S4LzIk%8=^9Ca3!gigbf6B zLQuu^=Ne4c!LCU1=mJ09EJ=zv%!s8I)P?0vjYir+OFd5iwj1btWm~5d`^hYgU3)Uc zyfpt}TkV<1jDF9?Ro^9kn6>>2vZ?qn5&Rb?XF%$3ClXf@4K6Y+R8b+g)0!rc#x$lC(KHcvpE#GE}G>C3&MbNz6s|3Ke(FviAD zqyerwlBOa~)lbU=BG=SI(a10zya|hP;8({v z32A?d_P~BPK~GdKU4XjuFj)lZNG+;4r1JdlOZ{k;RjD$rjJ>A;;+wv9NP+j@N&`K< zo4^X?$eb*t(ebj?$g3xH^G#{)oF_#$PSt;QhO* zWz-4&^v6T?JPAthua`4KJx7eBOBH}S<$^n7ARh5v(KD(Z&d}0LyRO3=$eso`XiQBr zUavHPGN2&3^z&wvbRWR}wS}ptSgVN0(&WXB0+|(d9Pru079}#s}Oo z$OTPb(TQgQ)gi9>mzh3vLKRLKuwkyJcpq(jAhG^Z`{J;5Na?mT?W351xQ=LR7@X{u zySmD#$>1OEqY&uv=&BUgToHST>)3``RSGI+=Gdco&m46p{j_O(e2!o51_*ecNXbzA z;whE+xZ*pR3N{wCP*_VL3R{L{WedeEw0nhl6Fr71NV{;$1Gv zR>|Jwfh_(tn>Gds-zne+ZO=r7jg?@2ltI@<_yunBVY&TMrx296Xbzb-p32)c!*F7h zHaEV|H@+}YY^YQQ8k%mbv%XK3*+mP-T6p*ad-Up`o~x1pa?odJqzT=8?0Miu0H)(O^oB_zp=-=Of`58_&J4b0=S z&aT7#H}SHh^L^>FS$}TwI|(`cKhDE)nH8zxJ=K5x4*)el%D?iVxiVc|3`d{5SaFk* zH|@gHU$s`qg@Vt)g8RpzcykNskv~}fQcOvdQKU=dJfN1Rm&j$iT|3L25i8(<#P@KbKPOK4Kwc6(Y2xILH8{?<`_0dAo(9i!BP^_C4 zp}TF3AO{n1RO=@90*;vhYQ*eQGirWhJFSCNn#6ck6Kx@l>oXBV($)>pAkYJ=c_<~L*@Ie)e47FQ(aoZfv0EDV9FCM=+#!9iY{ z2#|HqWl<$`v|on1j$$xh)(|r1OWOE{gXx}`j4x}^dMcz~&Ku8af&0*FeT0{-W&jVM zVRwm75tzR;a@#znEVa16)`Cy(4dCtG~^qepKBupt*NW zJUuh=EF6085Ssap?_-LeAWSL8TLcmm9?ytoPbS!<|0I+0!>vMh6NMXj$xfFx;t?B4 z1}rkf*>^8Xg5);JfDIpQH*T+*oe`A&P>0kEny1Nf57L4^eHwl(FF$XXw+`DO$|B_- zZUi<{t*${jCnKer$fey?Pe6|-j5L<-1==kC?%{N!r3#egwr;HV5#v2hz@9Q`mzvuV zP&j$H4gV!B4;Ttp_v()8i@pewSk_9!JI{o<0dTszN7-rn=91zgBdjTDhAm%grE{VSZpuHn4 zQyR9&(p6m7D%=6}SyWgjJllz@GfWRP($_qZs7?}Z;w2fp0@cY!iKdTN`XCL1Wgxsb5wd8Q-+}HZ(fVSZ#|oYGW380jA8~n zPHioz3v5#&EqUjBc z`iteffkTDQsXYndEqzIiJr5V5xPhEXcj>QdfAwTvc8*=M?4~erm6p2;NTtW8zAmVD zSUX&=^C%_y8Sx-}Wg@kr|>rqxMgPcXm8YgnEyECOekMpI=s{kiJ+vx7%CkxFyQq11dT?!a9I9#6 z!ZkDWv~Al7@w#Kf*YKl2N%YANZ0m*DoAai@QFi*Dlrx(;0t{>~qiI*YXd>|vDI&Pr z;8x_tbFGBlc7t=)`n0`nGo;Fq-Hx{d zNe3>xA573Hx$xYRE=|4*m=t61H$yf()<5MZ7Hv{Hkk3zC{Q1J*Wsn}*4gdDErtg5I z<0mz^WpADo6<@15wz%r0Q@w`pz%qw2CXGV7-pC_-(O>j1>#r#*rD;`NCLxz4+Vh^S zyg+lF>u&}>AZ73QFybRe?4pRg|Kf=UxEVwIzwIwI7{otKWU{USQO?r=NX*nE0*-TrwODvLsdMkO8JP> zz|@~f@jhPuSa@E5*TmX=?dj#jp8u+%{1=4b7D)+}og__my7edarYH4y! zgLNR$za1-=!i`y}J8y42&u^8VN#~|$LENvNktp?Ud@gL>1StGtc&UX`bgX(d-xz0t zf1`Q=JvVB78FBhsa6{zX`lep88q-7rBUc1z-cAsZ{I_?G1@LaIYQod%X_@NXw(_9! zPt_Ez8&6UeFCN9J|904xo>*BNk~S~-w>3saU{{rFc_QvmHY?w>3owkz&ua)w(k!z| zrk@`jCX`c-8zOG2fp%Ose+wZGn)0KrZ-R+cyl2LG1u7279;*lETx?i!89a@m_j;{( zG?Da@POe37J&e2;+!Qa+`d?A!-}z%e{Dgu-(>P}2r(DK1D8Fha*e_7osFcA*5G)NIfC|3@R@ZMg(ir|im&O7eV%tCnPSKA z!k!M}{gYc&6Ur3-#iE+h{n7T}@MoB9qzf$zA1-0?)s} zFIgIbEWeDG(f~yRy znnQFx3YmXDq5YKT1`0A6i^8oLA7-KYB6E+yEJucsCB*)PEsXv*F)q(Jmq z{ejvqdtx*H@R?Q|S-${XBHfeBK^eYTY*2Op=AW$KoK0mF6FL!ard7!HO6p!gpx_eO zzuQx|w-npE#t6zJ9$IgvYinG!n!Q;xa*D4zI%N3RqOR;=)NQQMl2;pQ2RrXtP2){9 zw(E_&-z}%DcVf!;bd>1z$NE_=2R_3bB6Z~!zrzGGZ;Ml#g0llu1t=4MiC*r3OU2eO zhxwj(DUXcc;CpV6pib)K!L6rYhqa3X5R3()9V)kug8$#Gg$1(Tt9T=sT>M#*Z)X(- z;l|oo0C7~A7Nb#Nu#z5{KvcZCsU^g{sZE6O^-}S}jLM?xc2-rrmmChvs`o9j9=7MJ zrZk)%SqX$6EeNP}dv7(r9a43oF-?pbB0=}<@v~ci|F2RJYRvY_<#57Lf^?W|Uw$l8 zOQ3t^GYXHRSaC3s8bJCv{`tN8|0>t_koz~i#HGa|79lV({K)SE-#*H*o>gjdw{TiB zxo-L&*;%lZ0YLs9m3uhGQ5Jl0!CZz6g}4B&`U?;x(w@K*zIE{b$x z5ArRy#@xnf2@47w06hO&vPIOZfXPXMc6TahD<^<6gy z@Ow8VC(uyKt+IPg1zs--r39-<4y_qe#zn%H45#$dM5e55OP7P?i!vbyyS8(LCspF< zZQ;BjjIT3OpDTkqteU5{$qjOO)7Sz1><){^KoWT}dfpDJ`sY_H_?efg+b#IA*g23+ zYW@|ZHSXHS8#Gl*?gRK#k^8(LF7!_rr8j&|iF2lwcgQ{@yZ09fWkx(@a!?WgHAIpX zb#{Q}GkZ;rIXkQ}cGtWq`^597F^8rr8wj7LP2MqaW^H;kkgd62!9`wHrfjELh||oH zE70gE>Ke$1sr$%1;ne)#c1`31d$H?;&=ku>(V`=8NIM!XtUZt}e_lW)> z6=S*GJ`Rd935rMBG%NnrDJhFAt5<>CACrKtM9!$Z=?6OUJSR4$CynvoxHTW2nHJ7n zEAaqC?Yo)Xh8I)=J3V_%7jBu{r0Ny1kf=(%5$hIf!L60LO7l-p#I`;TW5|d^j}~|O zho0N&MA$5)CJN02oP>`r)U%Si&>DiioorODCe`~dnccZ2`xoUB7>Z?M_{tsP`Y zmozT<6NE2+27|@haMcGjZ&ej3!=!K%T`_`;@C7W1bS@32yoM-c{D8Lj8T_zaZLavv z4tOW_=;jo|_|4P@8fvB3Fn45?6rR=#!YSSzr)?P3Bu_sLXj}Hq>49=g;ID9tp!7cJ z#w=NV-M5$J5@-7V-1cvP?bz>=2oNk3SsVsXloYW-_Atxk%O~-pnc3tC5$EXCqgIK= zBacylB>9lTo-Dt*KsX=eCPdjh>yWy0E1RyokFjd4J&R~&b)`oHCZdF$bSSKx^f2)_ zlW1tVnz&L0-ylMDIqL5kGPKZr(>Cm+W8+Z^IPEqdLpphim{3xfgUM7}m;<$fXLNi< zLHZ%sUFPvfLfEeF)u{Mmh4+oVTiZL1J1)lBleGuDWh{`-lK`!o<97EO5VPx%=E(mO zTDK@^4v1MO8gl)x6S&FxUBTAa22Fc+W=z#~)RRb(tAH4|;mUG?JSLVW2GlCChzBFZ zi};AU_sXTE6}TF+Lrtg(DW=GLeVh(IUY_bjqxPjSZ$2YLSgezf#s%w*Ok08BbO+16 zG$Y}t^u*pU<&iNuu4t7?E=#yVdqQ!l)FwYH;z&%l$e6QKCtdDH9au#W$0cNXPO$Zi zGTe9f2pt=T-FML8a-WdyBPs{_1DM@!ohTyp+i1|(`(YUL`NT*_9yqJY7D+erQS9-s zMy1&v64v|G?O3!Z&Kp;%fEzrcHd(Yl&Yh%E zfcTWG>U zvhI_g5d;C*aJA1Gcj|N6wcBW=oculkiN3RkW3#fr#PSUEk1Ujpd!cyWgKA30eg`1# z{B<}6xJyWW#(ngZ5Mky+Nf+zZN(X*u+MHcnA*PhBeDOt-HEMm(t?02JN08WK6cYM@dFNB?!6JLx(a)r zxl0}xl)I^3;%@!iC4!+Rz30Uz}=RA2S@-((`pLpVt{%)1IeGg}c+B%9fa zpfUYQ8IoBCy*kVK+lIXO=>A98u26OEkk^$cTTtxPgVc14Hwtm3eK`<}h3}Kh$tHkR zkxz2=-2AiHw`?Jf`swmxE5^?)6vhTAlBbE3V;tVknml@41Ys#RN3-ji+9k$i{58ut z`j8&OBGJei@paW1z(#Z@f=>=9&)R(OnS_2R1!9GTV2h^2<(JP3e;yAp3W5)`M-H15 z#L;3EpIxr&a8`}&B`6jU&WUz zrXS&9(yi&ns9V(i@#@TR9z~!Tb;|A>@F(wN0Ky0Jt7Lpt3T+l&YM|9y$V@X6HcZS#PBz#C za-o4WIHGm6TUcvch0y+!;gb6_Y z%9M;I4rWlc&?&^gNz3xCl?M2?ZIB0AXst@eqOwwNM_s8+>m5pARmkhvx7>A6>jaq7 zk$c%`F)^inZvR?^ofGe1*x2qHM9Yo1EoOnzLDHY)sc$e#rI}#G{60IKtWm7Y4qXdy zzI2uIy_wRvm>!cJ$v$L}o0HXmxQmBWtSaAFmj(hhO_UZe0YhEHb(MF1sV_z@8=vG> zjjWQ!lU!nAHk+{hlCBB|`*357{k778b&PyM1dx6~nj+g0AVdFeNY3V~%Wm>@TdXhQ{`O!K~Mjnw@9K|bE85h_;-0!X7CmEznVfgrA@I|D14`vwvC zt`>2uG$7Q3O9}@iX|-i_k6OyoX{kv-uu#;ZuPGE(Yq+7CJiEDG<(5G@5$*DsL75LD zB@>2kacl0<`hTRzAok>8!u&ZckH8LO?Li95dru6e8$wa3t*=|H=X;k%P2 zPuH;7S-`=maEqYBn*_%$SKupPk4RD_%1bk9}+R%isvPKDwTub!@nmsF=f(MIoT<{G%s3mwkkB%*@2^3!e*d z%qG|Pa-PBDkU3pn$RMOAZ@WMi3Ug)$WzQ?ASzh9h-7#o3q1=L=Z{Z$^y_a+ci zRxhc+iMd6yFgCExBa!!pX?HQ|yWOE)`(|bWTPUz?j`4L(9O;uGxa7bSL8oYS4!)wj z1+N*Ok?XDoh-MY%S^sImMWcVWUX_?=hEyuyLS7ISipVSNaXzI+FjDqP2QmcI8?Q zw%?o^!eA(F$tbP9i^g@~rs+X7*Ywb&44-opF|WVXtTc=pS`h4h775};I&czvt;(Is z4m(g*sUqwbeMMmW`APFE4_FPkjsb3rmf0}tO=3NMta0`OZ*JhX@0k zm99;&mr2wlolZL`y7~9rL{n(cVuC1rrg*8~$`+$+_FZosq*+?*qJP^aNfnIQnh(CsA=(;GgIPsnr-B z%F15`bl%-t?WJsb)>3@jJ~rvWcJ+ z5DsPcA1oCXiJlKds(6$rak_!!cFU54ZM1k5Hz3RFEjo8)$`!CE4i>0p2dJmvu9>fh zW1aWERU8VkR2&!JzD|=mOBpnth|WxL^S<`}PW5B*-NUp)j)rM%>!QI2F+EWAJdHZK8lZCfo%8h90` zvu&gg^DL?fY9N^FtJaz6?pv9;@1-j+{@8O=CP24=Sn$pkQ;%;WRyO(v00*iWvO8u? z`XA3f=g(D=5Qq8`)cfXj2je>EL7UncE&JMK2dU^zwxEU~tx1(59tt0>(L`uzK_+4-ICOI zPn?dY#AG`R`rBY7D1oFXm`+k&$#H!bnUHIVUN;~zy#6G}_*95OO`%NTjg0n%h*NL0 z`s`(o^g9u96v7n?>4X&C@TtI>ci5lMYCGAOTUDFDz$>GH)UP2^V`lnOk$|DEI#s*0 zNNQ~Q1505^52h707qc~pHNo8zD{#6jo}wl>4zMGUYz<%Jn-J}J68FIhF5sC7Zjm*= zTE@xmM%KFAii1~Bz;Keu!bh&-;*aKHs}X6@cG;9NB+F?`YldOVCnm(ji!H6yh~w%C z_LL?d)19b}e9V#d9(sTUI^cXZD=={=NdaMNKg!(OOV1R90G!*Bjtm96% zzfkmtU7P&f)yE|S2-AjG>c`J^jY zkBAUL_5ys`F_udM!Lj5k5OcJRvIW8Z3gXC<<=N2CNT!s!Pe85;=Vgv+CUF-y$SnhV z#NPy^NE|b zpKcb^tV@Q;Sf_{-NpwGC{qG{)-@;VZyP4j-woA8y`+^cIFDB0e->5m6TH~B^D4-Hl zQovw*ELjY7<2#H+mu=v`HQtR0-BwICrALDJAn4o?3{>#=D`usN3)C?JJcjI%FdI1( zT?bKpWGBpIjv|lV*ok)4g>Q-?<pv@mQo|zH?vBd^EpwUqcn=FiZFS zL**z!h~)2jQ^gxvaAVs4;vd|3FwRl z4}Y{CLEuJk?h>q%eqZqOTE<39*~UZdg#1wF@KQ}JU7m4ri1GCM_hv3pQai;Ko`RCK z0V5B21qXeEe9__m_+cp-od9>DLQQ~vpS{~2G5A+@bF=q)-0`-T_fozjuO-a~))WUA z=`gLUZ^5F)!$xj)tTwr&I)oR^r8`2pxvs}(Qm}q$u&lHtRL=_r@b}+v+O~uSk%6v= z-}uI0itTC?D4mb9M5I7HBk|fW=b2RB z3l5f~3`)9mMApm(vV)nervL0NF<}7lCkUZS&-sMsjy&RAFLXJ@`Bk6l-{(7rGcsyu zDAKD{_jauL4dw}*RA61*yRC3Ki0m7nTg4OXln5v+0pG|OJGCjH!OF4JUU_$xPFXQY z>y>sd@J57dH~}O;=V{%n(qKt{`hnZr8&p_(W&Dh14uk)*D4#z^j0+2MR>ZbRN91vC z-)}Ziu$3G$pRFa*_&cSD600%JWmb&|}LLH$7b1G4psAj=cCHI%aKUP)t-c404Ox zi~e(X+U$-6m;EQfkb_9PsCS!XlQ?AWbb)8ndHVi;8|f__4N3ZWW5|O<|CCkmik4<; zm#uK~c>l@&msr}qXiDjx$QzPp4b98Xs+t=-0;Mp=ZX4xZNr93S7!q^aS@|cvKH4)J zp0mu7Fo_8#4+_yyDz*$I_7W0#{>o&NFP+*~M@7^1d^V^*q!tTJ_^tARq`{>qahUvj zs*U>DMdqzhety&+KK=Wg9^YRWGyr+_TtmvH@N_Ihym_md{q>tK|Ge zA=fS!4UN^~I-4?d;?|XD*WTj37?uRka>NwzK{lApM0z`A8lIY3K>6kmxu zI7-(E#6c@#N$|**hS-8N-#dDhe-DP%Z87De`iGcQvkdoB>MG7gHh}ynT3*V2qqm@b z1XcUQ%S4f(f)1Qp6r0JdPF_v`P-7|RQDlqKdW!%D`OVPR66EK2<*&fFD9+ETl~y4@ z`Me~A<0mjh2$h=^IQ0j(5zK_~CB~=cLk8kti&ohP1XRD)r7|T&yqT=1p9i`>nYE*v zAZp?VCZIYXF%ELLY2iaNx~dwTP3aKRjebmG2=&qz><-pR69k=E1`+oS`$^tvLW{Te zl~`74g{7Fb=+i#q)(=$*WCVw(+D~lg<;p);s?1GoGjtF-24OdtqyN=-6PEU)lZ+^v zllzTCfJPVX!4VUk*NDoBRX&9hVQu{_c$7WRJLie+PzA=u=AezW`q& zL?igb)D%Q)lhWqK3 zKwZ8-(TpeCOT1J`y@AkC4tIpC)M7v^nD2tvx*9)h%>-?x5&Y3SH%@aXJI8QR3yOtm ziRjpQ$GyQM;kvH04QTr*y@lRG)~lmU*pTz|3jx#<7G!fB&~hoF4o;q3@QEn36T0dF zC@N#?eJ7&y?@EhYwsf6nuapqEtJZQAJ*xr4?iad*wM9P?mXmOsPt74YW6v({$F!Od zYeX~TcaZk?!jcoWJf+2i)`x)qnp^f_w&S9R{n+W-P3$R@J`i3=fQ|#N0=`@Afih|^ z1+Q@W92!{DMTWF0RpL@n)#e?vdV65TeAc?K!A_Ct&uQ@oMtLV<5xRAG`~?J=#u4O4 zAZKT1I5+JFbA)e9jN=qcX*3*$znbF0Vaz3-XC`G%bFwT?RGv${q;7p}T=##+o6ud| z3W%mSG?Y(lbZNa8riD>^r*T?Yq!zB2VBjjHK%|&MZ%n*;qj2M$+RbX1gNEM4Vx-tn5yS@2Uc@W`lm&?uO zPBGP!P%`tYSPaWKvhZ&mp zqt_yubWpoB+mA!w!vKF6k){pWaG33*1J#e z148*w{|IrK*iL;OePsLIFn{#KK4@VT3K>mVYRKkQR>ce?EKeqB(zBF&$I*yztbt=i z(7l{0jT_&pARTB~b;Uj(#tIp1o`ZC?!8p^jv(CYcHQ%=Et(_1t^7PJYHt0oJ&$6m1j0{TCEpxO8`qr1)n-|2`!6)vcwjz3sE#0fjj-z5zN{ls6hFP_VP=z+rg{bFp zh5(hG)TZ2N*20SKK1ALBU(btUh=fgGhO#JL-kN+2Yts(l;8oPPS_e&S5(;B{`}xxq z94>R6h)W&Q%*^Pw=1;_e`?*A4C7uP49~w#3XCTZA;AKhthj{w3$BklF9ZqX@j(k7o z{eB%{p&S@u_Av*zi!7pXORS&BCXB9b<(oQw9I%UnvQ zFMqts;0X;|=s0#L-{5*Lgl~JuSr`3Q*}EeI7PpVt1eQkdlE~aeF7z-XMUo5wv7}mo zzdh)fn`i`2qWv_I|77=ZzDAPeeLV%KvB3!e&KgzP^OVGwbO^YF`=x@GPP1GCm-KKg z@y=m)b%;B|vV`7QNn5JAYAlxq3LGPZ$(}6p0O-G>caDfTW9bg)_qIAKSQPD+?zBbnfA9 z@mL1@(y_WsmsRM|{|VFVn}-7{RX&uUW!`QsQk2#QmAUaFT|dMinq5W~C;)Sf!M;iJGMCCoIp*=3o=ZcPdgJJAnM@Fl2nMP>V%u1PnqWzm ze6qJrEhDq@GL9Hgi@Smapj2y$zBJ2DSGK*9bPG^BoouMV&}`_>iMta&KJDeUirYTY zwE$y$DmUYiY)2*Yd?=Ce%D8ta4;B2}62j z-j<0)+0~b40PziAFfE82f8{75N*8ThS2N#b8jUGETNQIc@}-J z04i`1jq-#kAexSgS!~8NjjDF^!gQ}lBe4!BMMVJf7=vfAZj0$zgJT^)r;j_y%wF8p z_4)lAONZ}z`G`G{UBaOXKX#8<)j1E7C7quPTGz`0z2#mpu)N^Gs*L=V4duZkKd07E zHcHMj_a>kQq8dh>MZ^)!)bOe9_E#Q8XDEHhlVilbLblp<@wrKZoLm+wy_b=}lJYv1 zgqL+w_Y7UNkbLq|{19SoyTO(1lT(TQvPx`c_jw;=GR3o_#2O_^5ZsvaeS^bPC`paS znfx=&>{Ht;)g$MDmMhB1!U0A{nMIhKt%-t2&S!IYXl`_b>n0w6l_&vQO;rs8f_8uS z=2DH1>yZEKx6?AJ;`ch9Sjr0B?)RPmv*5~>edvw($bjn^hGk_>>f4=2604Y7TMrKK zp%uDe)=G-g=y8cww=bs^nj^8QApQig08rbraP}I=q}|L{KDp8p4MeovZ|6dNf$aZ#6A0} z{Ns>^fHR;tKY|IdKNIi0(7fe0L4a<@)jL({1|dPGF#>sULc)p?MVdUxb4sX*%gqTI z8mUBddPL0~)~Q=XlVsC8dvO`ljI)R+`6dP51_&K!529v0dF?#sXY!K(!_SznpL(i5 z2L+UW!EK205!0K1-g0$oDe!)K!GalZfo#kVax!cz#+q$HO#T8XXslS{kbP`2i^<$sZL?JXTS*?}0@YNP`8ofb01Et@=%yoAtGOjvgyR6kU1 z?lTyWFI59W-KW!N$mWn1bo4{$JefEwPU-*YT1Arfsgc^ghuvUOur%)YGa-}LLHkCP z3p^z(z`Cxgt7e%8B~li-Tba`3r2Cg3%!Q{wa}~yZUU3rt*DXdFqX{+3z~iGl1;(V_ z-sz0?A4`BUYw!moq%}k^kuJUH@XjpAUKa_-ZeNR3PqE9bz8zyqt2$2X|1LFve2Sop zt)(78=-ASzcENj5HK%!aY{(mnd%Xg?b?n-gXukfpsYhfeg+r(Cfc}A@P`eqg>R>$M zNNt(>>Q?yE!oLb~*z^1x>x>hOI7fp7?G>&-u{r(eS<3cGm{X*4h-^-pT)Wif8vIKw zsD$t9U`l)wsU!sKtt(Q^)J9D*^)Fkt?=O%rYrKFTZ=LZI> z-lRZ~j6SK)yMQLcUO#r`@-HTP3Fs+vvHQC^7P#%q&@;B8(MyK8=dQQWh+Cr&IynJ3rNl%PxSCB2HBUhoj^w|4XM2J3B}`l@&c`sumx})rOYe7?lYz{!S>|6^D5sZ4yx9 zq{$!#GsDLddE*j_2KPB+cm$rZCgsKT4{?wFw z9c3hEEd;tZ$vzco@_5Z6sTe&UVNxw7bPYOVICV87>i6!c28`TBYj50b%^?9G@DXc~ z4Kuox5=u8Vx*{5vAeGbQE?7AR&+~wf(Cu%BbNube#(5|WQ``Tw4Z1l=7o-gHNF;#O z1HA8wztI)$SNf%B3cV8{ zOaZP^g=fWqc77U^Jz)c>%EOUkA|8(3Ba~J8xU3f6-x|42i^zG6>)6Uz0cpVQr|`v+ zpZ8*k&#!ASk=shukeNOzKyD5H+&j0CDWIc`ZCkJyVy34>qg#(exAdp|?^Y8_&Lgx{ zPd%^(tPspkeDg(YYne#$E`qbnkAr?FvnJ@p*d_@QZL`NQrtG=6S_&YPd4Rd@* z_fY6iO9$L@)D&jQ?Mv_8l<4~dx|0&YQ54uklDVbH_vIPMdS9@i-RBs5TJcCS&Ij8z zg-wCsumtNfU~H$VfK5iUIxuZ5go+q@Ggv(H(}4kaS+RE5Rcq^2;BrTtU#5x^&his8 z&I#UdKLtU>19fx%0O6|afbdH;Rw+B4FW(*0p@5=X%3%qnfE%3;awxU|7P`e~BL@~n z?;_f)zM<(KJ|Ms)(by=t0>f)z72ibq{2{CZeznVL8T&FaTBF=)@g>R@vQ>5n^Y|fA zR&n$};b}-gAYMhoRg_2Tc{)OZ3a%U-wiZ2GW`7r2>jX**EYg~K^R-M)oN={z2jfQv zy(4q{RFm7>F1)~&ONb;Qv7Ha`5g|a$+Mx8(SuFwSK7Pg&x=0)zrhyb)GP@s^2%uWs z(c;zBM~R*{!gXm_G#^SNDO9qX@bk3UJ)q{4wN}iKPdz+Fm#>km-0k0N!-Z|1B83Mt z0qw*@9~Bu|Ym)P~QqW)C1x?7jO(?c5{z`Na*f{96r$)9#ke~>omqNk=!9-Y z#x&ZxF0rM&Z^PIpaTXPyKhc?@-essTh;D3CKrjdv>09L#1c)?U-p80k!YI0E!6x%! zN}tY72wTqM40_8AWs>~P*>0d8`5g^4N{3JQua2x|{YPxij7)1<{TZFi$R-0IZn|}y z_SW>yRh^a{iV!uj!d;Oh{c;OA%;c;=O{T`680kM>eUSL#o@Q}n!cmgzj6PQRn%CHy zCU08oUPLuda-gw|nqYRs{Y#(pD@OjzHu`GM%eN+dxb#u1wOL@`%Cv4PahKnW9S%&- zwme{RZkcI)aFB&|>T|ZV9lU$Q-N%{KH}!mqL(`2>f#5gx5!)epZ(`SzIF3xvS zL+lv{h~uc{6Vg{wnMMex8Bt6oXaXUj$*x7Ur~F?;z%tKm(oVg)vT@`EZ)l{<`LQF+ z!C9L9-pO2+TBg_p?%w?{U)Y2Lm|+ zVCDf>A(o}gZT21QZ)BNU6{h_(-+mArmS~gqHl|1ujUE(^a+~AzR30sPO0OcXxS&%a zTEynoc>MQ%jP%P95uPu(73u#sPWE_V%@#*|S5@%&C*d2LYYpmIRDjFpb2SrW3=Oms zI_;-;wO6={^TYdgdzAHcI&>hbEFRtPxHHA-(fAbGg1eRR5Wwk<=~n#AAIVKdxk!XI zX!fxXozyyc#10Qcqq~t(F$BH)fVHNxik&v&*ie{eVL{2CR^fBV%WP;#UC{rQC9B9JU?Z&Owz1v$Pdq`;dy; z7kEMD776%9)PE-f$?xV43Ulg#d{=XY5gEH(&lX|p`Jii7X4{;O-zd?h_CYi?a;{G9 zw#{xZg@;pI-6);s2XEF*&yjI(2JDx1Q{W=BSh~1!M0N$^N|DK&2re;3PWoV)$HucvY=OGz9KnH0&L6K>mmFWPs zD*DnYSU%;tIr26O3A~%{*yi@VV*#A`8xha>v8MmyQjb3Ywh!8o<Y&lqPv2fNaQ*IpP2%c6SF_1XBd!e zV3!C7AZe9FgO&ZB1*0}vQZL{Y2K>O;UlVmsS@&UeCRnr0(V z(Piv4otX7=zjG8nbA0mrIwWG9zT5~>T|D-2em_aQ*t&Jn&+@u&BvLZb)VpWnQg1lB z%Gk4_ptxh_CIKY^8x`srY^{)=ghrG6ULg7g#wrak(_$tXkExQ?G8)9WpI zj9==|dL&X2L2(fAX{h7ON=N$fIHlI@=Ry5HBCqgcV<8(ud-C$3Tf zS5xvcyc8z5Txr8%X6XKwe4;rCfP>qe-VE`d$%Ov3zXsEByDVp3I?5ENx47W|rL`bc zc*T!*4N~QZ7cCoqVD`CU^~{S&_bn3k64tz9guaxGLGLusP=G@K*3vucre7^RJJ8}V zla>g5Q25+&l~dj)=e0YLtwz~fK{SqYOHj5bW))Fg8a+UmB=FwStP&?g8b8#?>CEwz z3Bc8B5W4T)_?~74t}H|^P+}+5#twdyzK@f7U-k_3#ukp#b}_gC`t8IQFC_C}k1K9W z0Ege1wbuqv*1=G}z?x0aq*4FE{Tm@0N@AYueAAF8=HfBC!-u%|T;vC?ilA0MpC8$% zR9n!!t%Rg$r}M9bg691E{dhjHr%&%nXuFq@nZzKf=Q{@_n7oruJ#AsInO1DHx3z_$ zBt9I?9yS-8^y%F4e8b&VXnz0#wnff4;P5(2*Z8M5aqLgr7&dK{X=!9%Zh%WvRkj>P zKdUugW4C%|$~hb$CZ8pey&k$sayBJl3I3*zcW3^s>`Ba$C?l)ClGcJvWtSaP(nIh- z4K!Ai&aiJt*g)TL)?po!FXb7Fwyo*z|EMAIUp+#lGI0_oLC5Kp4uJPn!nzuRo6s&> z3sigAx^i_NAg5~PNrSf3l6O(`dbv=-kRQ$Dj-ZGttBQLvwbB~r|j?NOG*PBO^w_=*{SUO zi>|-J0)p3LM-U2mPT;JGVXYOnkxhpI_OI6smKyK8uTUrEExdBYq^UaPwDpo##J=5Gdi%J6?&WQ!E{yaMil#4Wq%3V*NKxeZ<*8|}=q`{)+`~e!poa6hBKN=1N3zWtlQQjJSvy(T*5kGXi z)m*a`GIjV)*El&8Y;$tSgnuj4R*|mLN)*A+onf>0V&^8W3K+Uy4vc%^VJT+Cvcmw> zk2QNX3g}p?X%!9aN<%QL6DS9?l|B9p6Luuqh@5K?6cc2!@;+X_*aho@!bnl`dYY2?W3ODo=4?nZvO%cP zsN~D!|e^pb}FkiUodu{6Ek4y8YWz9WuE#cza){Q@RS~y{ zoYUPVg#U-?y;tH*xvYwx;`RF#z&GNH3wzwq&-Gy-i+@GNH7@Y0N(9={iQw%(nNHN0 z%)TGtXV3vjNbO;P1FHJ(nT@l;R7Vj`JMolAm$j_CYPFdCRBjUm5H-ceJFi@e?keYE zhO37Ct=BHSA5MaWo>y_>I9n>_z@v^sn8_i1?|)}Tel_M*Nb8+2UBOOnDrAAka$2&# z(Z6RAN&V1~m|ARncsIo#Zn&*{>Aw%Ce}eNDdSt$z)(u-Cx;7IveM^ILBy?v6;M^UN z^)F{FsjNNp38}^?qWFl&hj_l#vD{vfiU-Qw@F!lrfWbW@ z5JTy}RwbryXYK*1h}y$V7(T4mf@?Mj=h^uxotYFTvEG+p zeAf@M=Z*ny)TSNJvBvFjIZus(T$4RI?I!P88ua$`7hsoRi@(nBz-N)WozQLcLxqSS z3HYvp>^hMLFG)NMF7;eH(DS4Qo9}v~q{yL84$BLH&^CF(=7$PxZ}B{I_&H7pNr+5y zU}>^ocesUS)c4?)(AxQ}8KY)yg#6C7gGqd!|5~5Cq~e8&bw=hv)DYd6U~*f}7RyqG7?86V`ohzF~EdujDMQ-HukA40O@ z0KJLSBPb$CE}vr=j!t2;I28j+E5m%w?dH#yNU#(`MBet;yGlv(@YZkE~f z)@O3|oa>v6s`MS?USKF2%AJ4QP6UH6)i0Ry$1KLjQ5U(}lD7D2xgXC>kW-J@QrFZ6 z@jTtd?-D8`ejrkHLvE?#rs@K-`q@nC#EoP}8{)25hM*ftH|xE${72ZmV|`&CHa;98 z40+C!KSj@m2{e8?VAdH9Wmg@-rWp$9$@Y<=q53wP8}lATLsq17oQYsNA21*?z+wH0 zduSZO`(#StFN=FKsUdIlsciZZ2yHvK!zaTqWJy2DKpTPye+#dhPL*{Un$qbx24oG7GP!Zn{bHhOogMxK74l<*IGWH1nSN{>q6oXdxJP!(U_D22EUG8smMPaiVV>(FCJj zb7W^;c?{I%g~ZiR4O+8uXJX?Pwrqml_SaE8qs$*x#Utq3?O&|1TjQ;$Q6-E!Hp9ii zhWs?m)tALYlEf!jJ~UP_q9)3I_7cMB^!d<2PG!7ri+Nv9G*b$O=o_e-630Kln{T>J2O4%pXYrX{Nb0Il)S+AdL zb(2|L;?^I(9u~<)Y}(!(P-gUsB~B7O)S@Wc!-66$E{o2pC&B?jxJ1 z)%xY)6IZMYMv2UJ>k1N+(kmQjKO;zyA!QIsW`J0Y1&HdyY+g&Wk+6f2i&Tj!=hL$T z4PqjpD;~%9Zt?7txyw@fNcz~qxa^`pJT@l%$_S+flyb1@+ov5s(G1jBumhE@B(dRF zDCW=(9k}>?+n~%O%Crxh+kTgdn1JvQcv+D*E1kod`PhZBh;{&nDk5Z>cDhtKlV#LT z;fQ-#>DS>!>|$$HGR!c=@3xtsd%RDML+vt#%-}475;PrA_Ng-A1KPFsO(dcDM}mtl z7y5;x5>td=brPdMjMFRZGy4h3-V(g$SE8|~aql1Ms1cOUw7#nP8!dj9+#Rm-9%JiW z#vP41xeDezp%=i8Le6R7yX z;;!Q87#s`6M(wIfM`he{0ESX-WfYu}XD6q(sm5s0CswZGU-%PGkg@uC9G1Gp3!QHK zZuX!rI2s=u5-1MxT3W9rMVRhVT?M%vY@|I`F);Q0Ii&ogS|;oqVtIFtV^2c1 zJZdyCv=<<9%;dB|OKhCtWE)wP2^2w*7r#+SL0kK#Z@aMgflPG~6p%X9F zs#U|71BjB8Qx&aNlS8!_W9cdk!3(yam+Je}W^<@*|wWv`u))_&NB z-(R+XHp431|V$~C^BpI9XD ztPsP!3sdRn6yI{yz)(X1Z!z`@Q0gNe^_P|1`b=)_*)pMmbO)~5BmZYX>wyyV$V zV2|VZ$x(JM-yr!&J zc@;_Fq4OR7VnZU$6dPPF0vIPdc60TLQk%>QQ20RAcqw9E<-nSo z>J7bRqbRQX*Hgr0ZPovA`Afv@cxNKhBmkziC3F z+TMw;Voz@I9PNJK0lcu&l|=Z;?v2!6tVN?ER#h_;iLOz;>z+RnL7|V^?1++^f{JrW zq!8##+pi<_MA6)i86V+&Qp3eyuo+5{f>1iVAcAZ!orFMixo^xm(bAK~f137W>y#;R z^rF{PtVyKPl|51U>}nQRRoJuYYb*5Ag}b`p#Y4>H4c_|*pM2^!DrS(`z@>7v8E;)4 z-P*?x4h3b_;{9l+*8Yqxoj5aHG}-H%`CeYZ3+?@=L-DLtF#;o5W%b;^jEH>e`Exy0 zI~(*9Nac|()=p_cSJ_RG797)H&Uw!%!CFmD@G5uKAiSe}TYJHJv}q)g*(O4Vx>F#0 z$BfSDQ(b|j^-YECuaau_O-e2*vSKxA<>){qe zRzAGr7uyd#=33kFmD;uB;5+IaQJ^)}rDQf$t<6XM+k13=^qPwC5jJ2c*|SoOAl~~O z>q50WP&yx*yH;U+kuqG%Z%ly0tShQ{T z*>S;^P0RuHfOqxzZjKh|Y1!a=LOm>9>)rt!=h}P{ImF(`Ee7}pk1Fd-6;a?i72IQ? zv~n-*wJ%oXpXe>U?JQ}e&!zymYO}!UVEk!Qgfa30G!0VKzi#1=H-=xP1Fd<{hXjOg zQsHKvbs_`H&U|L)dql=Q6VfvItX=e@2{QsmyPX{C^fy_(rH-1^f)n9zs26{asv9`7 z>ODR&eWWD{d>s19x5PN=UE6#%EsLWUQtv^+!I;IiK~C{u^L!X>8dWG4X}0wc2D*{Q zrDCAaWA?&4HyKa6HJ10_ycVaFGLKQizSZ*Q zpZL3_e71;oputIdivo~4M~#xs3ODt5Zhr{yNJpW>in)iWH zlmB8WgQ0F;K0GIumC=hgVvco29UvSFVUe3|^saTO+r|y!=eDA7ZbPlmHNA3jMx4xY zXSMtEL$QV-vS6UbY495TZ1=Q{5LG6%ws>s7_@slcZYG44%kfA_IAa9lJ%C%jugN>Z)>2&Yu|-8f-)05xf_`m@`LrXL zJ(zBYBc2V{bhuGk(bn|^A_<}niivW1SP3k~v_1*?5U1T=2gaUy{>^$A6%=-o@dWoH zbWg?9DRj-9AC~>oFcgD#u;@DsX5c=T1_oO}az;L^rBUz{)JVN}cOr_5r+AT$Cg{*@ zYSG53^I(LCC2!EBBerWRx8TD^sDC64Z4Gg!_OO8j&}B_DA@1q?2> zj{s!9nVSpusB>y)DIXtK8oQrDI~+(H`8G`&b=YnEey1{?`FIp%=1Jsup97qmcCS@M zkyj+HejYY@tZk6&w{MPfxdZrF~T;>E^2)90r3XTa>yVl!~v5WH4(I2xvHhvHCe(vGYdW!}}V_2D;K#8{#9*{Kw#S$sE@WD3+I}%J<)O}0&>$54Il12>UuC_0j1B9K zrM%GtK791`dsWm7iKHGge%1|3u@H@O0#^m^s@CVm24*~+XY6R-b};PU|J6g*115a! zkXBSLCAHY(K#vbg=0@$=N&wP<@3ynv94mH41oKl1to>zgO<0kSB0qVJil9;Hh$1Uv zgB2?4Zqc#CIjA5Y?VuktvH_VzKFkHHN(<1yk-8;UGS{S;joM$$9Z+BtM;ijSt(0JD$5UcZM?YK-rj-k>vJ~E+jiv_p>5$D|>R38^uTE zQwP*8@NsRt zgTnFetppMiVTPO_G~|{TKPLt&`t*rK=v~Q4xXnEwVocyUJB$qZHTGsi?YGeY_n?zG za*ol!ToABAY}9?@8|~c9JT3DiW{LSDQ8UnfR*rOF z%TeC@{n=M8fXyr}y45u#ROVcfF!sn5dLa-FOzYYtw+iOM1f5v}^0RW^oYl{g(w-30 zJY4QjA;!#%b2Tzat|Qc(&+1=4TSkggH~gh_x~${#99cWn`bj)}{g}esfv|;fnN;DA zp6!1+ZtAx!SCG==vzVV{Oh(a*LkBV)x-Bxn;-%aasbTx3Ekw{q8EBs${$5_+xSBM* zx->JILe*hKC{A_vjR$rs7x6f;6Gp+EPBPu8VBOvCOk$OyF+i3|cc4@z%_(+}$pPsC|%6T0cas?4$}y%if2p=2!15oaRV{R2F2{^x-t zaEwH_nrJ(4H^VEsa>_>@gA6IH{~od95i5A;Sm`l`?y3GRY_wwuR?2j2<}b5$B zBI-@Ew2QnJ%BND5a~tpEtOA5sH^ed`%&%wreHs_z$%2zJb#Z>RGpY-tqFj`Dd=MQ* zTzY*DAlA@BOr^ou@x)UbndeK zq?BCr@bc4cn^TFK^I>yM^DnK4LOx)Z=VXXP2*N!+6&Ngm{lgm^VIslBEER!CfGKIl zB7gTmk<+U&_Gc)Ua)chU5rPsQQ2A~k4#zk7;7j10q2y*`z*v3M>m#tKXUq89Zy(TR zMbPoD7dw6g-R&H#3KFegC;rjT^iHMPm#8prAgdK@vO-d}6*_$wR%olq`~zdpMwJagYlfufDJsSxb(_ z+$U5%OG_YEGi|9DV$-d{DOnghdek{(96o%Eh#*BK7z*{$OZ`i>xf8vZKww@^Jjgi3 znb1e)mZ)8S5F#GBOAfL{HbBSx(x9r%%xa2~MYdemM(GRi7dC)n!<7ey>zT~OPcT|U-kyzN;j`e?Ycv5>N`hjhW#a=-O4i}(l`^>xzAp|Y7??yyc?9WacxUNR+MQ0T@0V5=@2Q%8LqxF z-_za)>ylZ6IbrGE+D)^To7EhsYQ>DUU5y&v&m~PguC)7TU)qHhUt-S^!|QQgsHGlc zXgcJ1R@XB*f~TyYA%ph&DJVxdjuFm{dY@JtR`v7gMgbF}-DQ||LqY*eLhS8MB{T#)S#F`YFSVQ9d z=GJB#g4vgA)mNWuLg{kej@^k!1p=|GS}ac7TJlJ8noT@{>K?dRJnt^mrg&>5m+-Io zT)Dhp5Kvbaq=|S%q5m5}+MUueeY|?VgK4I2*IUfG*j;>c6e}w%E&@fDesC;IAvfyc zC|_*cz!@0`Weo)4=nf}FS5a;Yehtw$zFeN|eCg#VGjKhmV3c@ZMHhmcYHe1m?#qoN z;d#0SmLEtf^gQ1B?^^lkCP?HLgX!FhP3{OG+f&(IDwcK`*yZ93VR*I-va^kjd3p@- zf>HKuU#I&S=SPkL@^8<`i+1ZsUy%jV;|)g}B) zyQl@W96q+Jmc{K@w%iiCA0Z=>;n}+dzPu5emJOoC79R@B^wU0#(IETUjS49AcyxU+ z;!drLDGAmNJ~`5RK~H$|11Yh4n`azoej9n<^!|y4p2Z?JdpY5MQQS5vs`&+ZA0pt@ zJ59t|irPFH3ccsJ^r)T(f(9v^_`J7C``(4S9uhOL~y_fVlpdM`^1|*I5t>pfLSd^D8tUJG6Pj; zkYYWSTx|-NKbmzF46rcetGr&p16Fw)+aN*XyqRq>L=aPEMt;c#o5h3s$DcvXhr$^` z;)|^N>d`2DGVN(A-BffHbd{fsG-B!A(qPEOh-^_3t43%K+bW@udly$^AIZD62$w5c zLuW@DTq@u)U*tNAAt+fi^r?0FDya~hv&p2jS8_LKX^|iJx5m1ELM`l#iU5_MB&3}6 zSMxA(yNSzThIY#JE@$>Ovw(Pz_l_q%jNV}W2zSH%fJ9wXXr0p{htV=cx~5*Spt;c3QX??@I+Tx=@MW2sMQ zjw)^&*V1Y|NmOh0LUD30T|Jg!dm>!a@iXQe5j!$3*HW!&xYm3r$e1Wy@-;!t*sp%y#|)SEyJ0}WubUu zk(A1dl$KR$1=ro%7$;vPYRaEi|3#R4{3@qvx!3_hkc%Y(;w8{*OdkD%3tqF<1%4%sY8GY>6!&e=})LdU*)NFuv ztX=>YoLC=X_}!SkJ49y6^Eb4Lu9LZ0dL>)8kJjax-nm&vb=tt8Y??Ww-o2TFtc&km zFxdQMpC~uPUN%wCcC9)fEc?^D5TQ+E6FR;;8ev}BKN$8Ws>2Hb&8a56etob_A1$EG z7V)FXkTQb+7=N;{{|a!9fq4D+8_Xrlj}R(lgA<$QQ~xH-^_?qFg;OLV;}jH$aVEK9 zfuVG&#av3vaVhGUU{>9Y`Mt+3@f8lrV%I338Rp#PjfuaMDXK32aZPW5tpv@sVIUsa zbaO9@3e^5mqd^BNEHw+Fm{06fXri$&N&wH}F_g*L@Rs)jFs5!Lx#CcwQ~N-1f|30b z#N$}61{f}~KeP#o$NG5mS``}#_cP!P-?Ypsjpy~#dBx{Q{JBNNA+z)V1$5n*h>`q; z${Q2<2s<+BByqF*$Y&fn!tVqGY;hT69TZFbb6&%zT?9 zzE=e8w35XcVXJsdF!Sn5I4H||sl5g%y(gvxx@yU8NTP!C>;9oX*ZYaeWVNE=&(AQV z;+`$z!O`CSALgAtk|w^d#7@6n5$S$L<~h|VJ03rid5}^_FouA^(b*e7qva4MRk z){*yK-*-ABL*cmu_xjBCS{TQz>a)Dy2_dzfrQvtbK#mq8oAK9E%$>Y;MRLR22ct`E zMR`F%(Td(Z3m@JPj0+%T&Q1!4-kPYFJc;_tzRcsXX)D7nXIe?JkU&n|lsBY?U*8Ot zWSatw*LPtmHDHm+TxYw!-XMat>4LwA$3ySMFboL>9fOIa3O&ljp~f@Zm19ffzZxZy zA$jPj`!*|uh-Um;9eu+-iKVZ|kN-D+XF9|Yc!6Zj4Ay=E zbps#?DS*&ib_a-C5T?P_M!r`lmt?Kx%=i5@i{NgV*^(rJ&bjyfB9H-ch|+`yVmls- ztx-p71aYO8VBCshZeT%28{FnAn3lS!U^oDv`8T@zt%>jV|fc`oD&Vc?G9vBD&0PXjoJ@SQr>sEMyb}R6J|~d^~JiTtZTM3PNI95?owL4k}tk zCRSEf0tzlZPG(+u7FOneIst-$f`WyC#e{>yWG2ETV*Wo)U)=yC$bZHJ0z?b|Mgjss z0{ZF)5PXjl4Cvp|zeD*4Cz|<1pxyC1^uq|_^tyR$lttg(7YZ630}~6IjGTg!ikg*;or9B$TS!<$ zR7_k#Qb}1wRZU$()4P#+~JR-le5cTS3m!Nz@Xre(Ac>6gv6xel+@h3{DQ)w z;*!$Zy84F3rskH`-oE~U!J*-i(b>8Ag~g@imDQcyz5Rp3qvMm)o7=nlhsUSqm)C!A z{e$yA(!V47FSwAtaRGyZf`CH&g9`}Q`5)j&pkPEy;K)A|Ab#7S5HtHgqW+A@`L%vG8_0m zQQ|5@Yir;JBmzw-m9=+Vq{SSY9N^hP{Dy8KZlY|;${L#cC8mFE3^|{F5fjS$heF(> zAdetKlIl>vy8uJT!^RU+W!FS*fhBpa3!A2%gM@g&o{kFH z23_LHBDpf*J{RQ*7pN_u8{)aT>Ut{ZoHdI;OQdLuA;GOs);%n6gH~hIuv$eC3IcOq z&zBorO{n^VXIt&D+Q4Au-;k6a` z1;D;wJ?@+#Uoo~9B(1lp?<$hU{{oCADf|3RWQCUf7zg3nSjsw*-M0I6J+Yef0qgYZ zX{T#2>e={0>NAjs;q7{BPvtCIC{nJT}O(zTt&rFe5uUb)K0dW@be1G@wMiLjH;kMyYo0+Shgau3; z4Tj**Aw|Vsl^Khy2&d8`7`%R)<|Yu#lUK!Nd=wFOR3fde|EVs-Lrpb9P==x)<{kA2eM9k}P;wDJRK(K53^>bLj(B`1agi81ADNW&Q zJBvw)&X{G>6Tf{A?M%^1JQS>5-38sDdkakX_8uQi%6}1_|0+zB*)Xjf??J3zfY+C( zFThWJ6_< znpt{Yr5!w{M=Mbayx$bfJO{#wblz`1bP1q<2?JCUzU@)7L>6k7rS|DA7=Z_AHrlFZY$Jy@Q*dcJR3a zdFuqmyIc??50yeP&q>=6h&-Cdt+6SbWHH)Vg@)Uz-p?C5j<{wV+piv(44?F=(qbxJ zI~&ZsWN}j9PylN2=%!Iyw@hx&`b2K@G%w=L9G1x&D&_G2*JwGR3+7WJ03&U30_&I248^PlV$kWH_^I=n7o>{M92{Yf2(CqkgjQ!G6Cr0xw7?1 ze2Id%af3soVfl`Z#OBB6r5#nvFMz=oi`Nol-4`HdwrYp~wg{@g942#9_`5@s+-|Eh zv1+e6t@c33>tOLoWmxE252MVn-5D)ka1_v7up0FkLv zv+g3>Rv2Pd+>2}d$b#0J$7wz=j7}=L{jk5qY&0|8&2}WvlFnb3*UQ^UHLyUv+&0r> zcR8b=L9x>K7nMZR+jbqfv2%y(&s(>%;uqUCpjQS7&wA>{U@+df3n;!Vj34lSmG4 zz#)^mJ&}u!M4XOJLln3NOR+Cfi|g@d{S%HSbWnTgS>aGipi#W|3s6sT1@Z;h`Wel$ zE_Bx@d&!B0BUEos6`az*`r8lWerOXlW>YLHaZ{GZy0BdQsECc%4ss2k1QUUA8WCsx z1$de+`U05w^)w1(@C%2-rX!oDheN;&Qo_V`7W#hyirv2e?NryNBm{J2nOiO@q(jLF zvTpNp($}C&jL=${R6v%S;-dV6%U=N3fVKp$gNZKgwd;+6jL8r?yn%X@4OEX>Yoa~t z{)nwVwyvs60fpCZCm2x08hir-HT;$nKAHJ?HkcqF>8`W()#r8?2xPaVI3_b?vd;vaVWpo3s^CUe)_tYaK-#dk>4SGPvzaPb* z1HrT!`nEzXxm_5n^Zh_!M$E0Tc>YCFgM;p&rTZ&gDVJUu*`1|4>3&brrDhj{AMIKp z)*ynJhISJvxVC;ycE_?}xcD@^JJPKTC8)VRweNC`xColC0e;qe%_Veu;}jhvMp3?ux|t_e>fJ#x9nnsBbucy{r^FGTooh%J>~|O_AF5vTDNgkK7O!1R{>8r{E4WydsO+X zRcv>)i}otefi3+4jMcs(yqd|S^R?AFvBXl40BIMW4UnD7(#e;mn`F``ixqwWrZ%>A z%)8$0(-U8RlW-(;1(be|HipU}?2P@`p_+!abZp*1H_mJ?->)y$Y@`SyrKdk~t%amz zihl)Hm6Ux|ey0IX7?@G8{?{ju+HU=f`WIm6vCy-zbJ%6RaN6$HD>!OLmgABGU5Edj%1eV#?f5z<)(e z|5ok|j(q{p=)NzDr5BNQeAr^kYZi6E2$#qo%Q4eZ3z+=sSj8J28=dUI9d&yIMFa>; z5;T?qxuWB`(+TQ6Qt^>`Ao8n>6yMTtkP(Vbh>}t<9j?ZE`eln&^_IlP(@_ydVkBHW z&TdjKaNL44nOhVQU58g+>l!p+KpDjGQe7UXnXd~g=^B*rZlXPK5d{e1Ii%4n*$ zQubyDk}AF~7S(ovQr*TRia^?3<@)yY$w3JYMk9GQ%FpexI@5d2;^Q_ah-SFwuSbbL`!-xiurUm=z}Up7}JLl3U6)9O@>w`ES-x(t4~5vc!c>+h8yx4x6&{v zn11Q(gLI57k{4WWh2V47$ngU`Xh$3x>J4bosgJQ#TRW z^PbjJsgp&ub@2#!Yc2swkgBuiSuvpD-R~86%byVqsRlUL3J;tmwXka- zHtqEbm>T8O{md}GutE?~jJNtWg=Bu0aiea36zz?rzZ$;GZEf%rm9q|yxt_gR9A zWjVD|X4R1$9Ua|WJRKpsn|j^DZWCpXhW6{(_nQ#X%yc3~iV%ZIQHZqg?Dy)A`t=2< z7FqfXV=F1l;89}U5c&<*Ej zWvy1(c6Z6?iLYmIpCGCw}{t$Ko_3WV9x8nplpGfa!l4)4OeS^e|RWp#d z`l=0>ZiQn$nxfY4C|kwlL@mxpu__YMDD44wf~!uj+kQ(+oEZ8bZnjoGvwLMo9Bv@M?)nfRnwqY8rM5mYVR5OJ?o>SxCp?@AuT4eAK z)22`*c~oXwjmU4XG&^JtVHW4j9|XQGUJ&~^R(!uJTkUwmau7VWOzmjmBg`{Y631>* z;Wo=Lh4va7E6#))*ls&cx?r6x+nKHwVx#V-UzvEF-LYK$!RcU;4Rp(oWOt^i=060f z;oQR|@T4v!x5&HUO`54kSF_g|t-_wHz;%=K)ru^NbeQ5Cw41GFsaIy17_b-3ixB8P zbH^oQ^&=w$&oMrRl4s)fam7dtW{np#vggE1~f>>8A)gZr?V z`L-;BcImLY^^rq4epZU1tsAbF?mHr=szLStli>bS@4;2tSYlUxI$}|xt2JO=C?8`O z)fTr7cI=uu(0RQvSu8T1+WsVKgg*QoQd-%@?7Sp%{Xx?0um zGP8WzcHrRgtS|4UV4r|zm&Y5Y*%woM0Q9zYOS7#YJ7<3euYk#!fh zOG4tfmvFt_=3VcVlxMif`Y!euhV^krCc96=E-}|pZNE2Db6q{F&A>g~t#&<)5MnpXeN zCv}IxXP5C8V0uDsCk&57VLqHYJqZRgxal&I(PclQXbF$!;URHz5MG6P{*mc&mZ_j2 z_DAa`M+(A|8mSwuno915nNutCs`hGgtU(Bgn<&YZUGw(-A3m1>1$0-T=U)RTy#Yn_ ziAdHamg1qah_;*~L%IUg&8!vVGS<6DR;EP!_-~RR9K&^g^)4y+95MxPl_Zu=d*w@H zN~(sIK7r^iE@S>!HLi&xgF)7Wq1b&7Zc#t{l8PVgm7^E&F6P>3 zI-uAm3dQFk=SkJ!?vwa)EhS@PEwVocvoUL6i>zmJbg)+>J+CBU0^w_Oh_r^2{E$Vb zK{~<&%FDo8>56}UK3XAJzm}Qh96beR5p%4j_VaM#sIk?%hkAf~2oP;w@vK_C6k2UT7h?lBna_BQp(j=A*QE(Hx}c-|avDlm5mopf zE6V@BJ%3e3CE2_qXLjZ;YN#C3=oB(IkD50&J4KVbgLYwy8-3o6ODrG%3*DjuvlPit zb&a!9Z}AaX;7qt4uIoklt$CB0bE?R@m5p7k(Uuv>Zw=)#cnAeQzvs~YPUFUFcPBH) z$7KF_ZOLlswB`MD7WZu1m7$y~jZ8W-x2U6+6nwHqlN;5_(KA0c4&%?4$C7t8EB=hX zABA)ml`)FSP$XzQK=z)7zu$$LstQDQL(mCOPuIdQIAX6MCpoeVe2xXMCv{ZCcU%&s za!`X9Fq6S-q$AqrA9xqIezs+$;Z((c&LDnda#Hwca`j6B*S*x@UW2<3n&5RXDJy@T zWpvoZHWV;6FWj$XC>W>&Nd~euJ9|tK#i|jt!lpL~NdDml&tY44VyfpiSca33;_MC% zzxD7ab7?R*HkIMFb7oq(-Um|z{|i#VE|l4Br^&vma?pDmg_4ck9)(sZ%cTbG>a*9C8~pE`H<7pH-ov6%zaf(4qLaw}85IKNNVr zHNCX*XLKQvy}KZfS^Zi1ICood$Uo-`9k?I&@rbwdN+qnh%*&~yFRv4JR5+gz7&>D86&RFOp5kNJ39FwjS(rDq-|Rj$s;)5)ielaIf+f3VXVUC|2) z2di0KeZnPmB#a=Pfr~g#|4y2pYd*Yf;GAjUs8JQc@r&H9>5D{U$7Mo+;MuLAk!{qS z-E8S-YOSdcn6w&)RM%(xgOkS7=S{t1wJ!GM7fha*J}m&f3<6zlDm-S#VkaH z&8=ZV7|Q+9%(KZY^m^V;@3-gqa6X-{=XWmu^FQaG=Uo^t&gnRK4YI=H&TF0dmF*5| z{kA-_(VzK6C4;Atu=?Tjgyz%e?nbu#1j`Qr5~T^g6%&v%;}Ibuj^ zSEOa${}DDT+VhzB8zBC^koFdnH=aouK&D@oFd~|?JoaKq>x?h0Es^G3A$c|2v{rVj zQiIbKYkZ$2AUZ=h2Np6#RUXRknT>fc2__0oR;5HlN_b;2W^YWL%merZ?_yzyz16uNtHZnf`I^i3SPl8J3!b`@bg!sxkgs>lVC_ojH+S3bVp`=tusX+O{fHN9 zljBYb;`btB^#%UX(H~p~D^Q~ed8hhx${hm+i#>v|r;e-!9u!sl4ft8I3MnemY~t_u zf3E)5(a#>(pGyi`n6+;Vj)>}%)@xbQ<7t)1S0F>Ej`9 zdM0H1J3YM>C%>p={Xz>oGbeVbQYrrT5o(t4jUIVavi-5L7f~*=%aKRkH@7|2+w&-W z20&kM3;ckd#p2ePh}P1VRcYMSCIfTe+-61cn>S0b5K|$TP+O~yIvA}kEI8F|2K7(E z&mYKVh8Jf4LBUw>bWHx}6*9W@b(?pSv-07lox$mBDC>0}QosIL18LaKL<)b;&RU&1 zYx>2$*uA<_pPqWhIN8c*xMdHsNL<7WAY+J>#_7e{fakX%QM+nl_l`JF26)^*aPnH@ zqxSZ89vITw0XKGDU@n_mrSkq#4r%4w;bodYruocY$`+dQJ1QzL6)1Cw7cSSrI zBE5`V(n1Ij9U_k6B+-k&C5+8*sDz|**JfJYnK0afb>)99lu55JyEiV5ud142yYUu6R6_|#9opBe zF)}k@3iOxBCgcXM4mj*DbHOCD_{I6Y2%lIpA!_pc=ks*~`BnK7e7L6SlNknv>dP?@`QvVbWtU~tXAsD26ODm^CzjLRPle+VhcnKHBb0ll zSymc&Cv21Gh)mvF3(7Exk33VR&eqLLLG7+*m}L)Co=aYLfX)>KG%fE$6@9+_cPPjF zLlXZx$&2!BX8aRY(P)ikk*UH=Ig1BF2hni3==u`{rx%c=e-P?Y2i&E(7YA z?oYY%eY6OW5fAw(EI|OLkxyows3Vqy$&T63`3|*|@tk0riPO@{IT`FS8l{(`GaGT$ z@e(Apqj1K{mtl(DesWua;oRbS2&rLrER>1ph9y*o zhTP81ykSR+J?%E*16Qn)+WorrOa#vzaDX@dI}`pFG?!AHH9h;J|^4G0Skmw6g zawO(w*2sCL$*{J0h_pub^q;}1Hudgq`Ew;Hw?=o-UUpGmq)Bm5cze*1AFYY*g1q}; za!i0A$$Q}zv(#E};w^}w)=|u``jkLuuI-GVH z@BCMe(IjXfPV7QlSt=#{EVsdgh%IQ4a&xht;$#fvTf5w#hAQ|dlBuuB(3ygPm0xb! z@_bv90Jib%Y&Pp~Onc4q$G#)6#tZ|^?ypC09PGqlb@GV7aLK6%S!Mt z+;-)nG~gd>&&suQOj+PsSfg?cWt@9r_?TSAiNs5(9xNUt5Om*G8#`J09vu<$A@7aZXGTp5eM*l{@_9 z&|K9ib@7dhsO|xYURJ4(6Q`?%p--PQHuWy|_aj}&MZYU43ho$t0c?u|LC3}VF0=jg zPos2s{N#8|F#>t|{^S@c(T*}Yu^EJ+K)j;1De5{u%W-<}Tc!wSGbt{%16{0ySP_PJrhhwX<^5IMyQ+%*D~Fn4~QU8TJxa~F4u zHu1~OmV)*aW+9$khT)zfHs$AjY@zdq)Kmvo7UNGMra6nZ8vMhe_}uoz)VB6gL+C)N zdN@Yp-K$mtLHd^I_;9k6nj>1%%uuEsM!nqQ_{q?3VkkE9beQ&Jif#6>v5;e)!7(#7 z`#)%kdXJp>?C@zV%hA9_;A)p_J&jt8h|73M6;VPWHk^>4L{+da&;!(~Mx!O18a`ao zVv()SA~0~5z7SC&O9$4u#1~SWanAlFd6WmJecvN-5j}&JwSo?Bts~QsmC=J+DhO)d zmT`1cPC)$kTK-hBf7&s%kgF}iWV<~j$Ok`>{p0rJ(E|Oh%68KLhPpSooGc1Ut0~?> zEHhq0;Tqf7wyV+FPu{nrT8KXP-gE9adcj&TOJlwMyGvmbfgs;0&A2E>7sG!{R7G~; z?%NCZB^jfRdX$&*<``#3yC0sRv0YhKZ@n|KPQPLXYOd?NBE!X= RZ+iZJnhE~jFZz23@L$t?uzUaj literal 0 HcmV?d00001 diff --git a/boards/shields/mikroe_mcp251xfd_click/mikroe_mcp2517fd_click.overlay b/boards/shields/mikroe_mcp251xfd_click/mikroe_mcp2517fd_click.overlay new file mode 100644 index 000000000000..a62ca249f127 --- /dev/null +++ b/boards/shields/mikroe_mcp251xfd_click/mikroe_mcp2517fd_click.overlay @@ -0,0 +1,25 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 Navimatix GmbH + * SPDX-FileCopyrightText: Copyright (c) 2026 TiaC Systems + * SPDX-License-Identifier: Apache-2.0 + */ + +&mikrobus_spi { + cs-gpios = <&mikrobus_header 2 GPIO_ACTIVE_LOW>; + + mcp2517fd_mikroe_mcp2517fd_click: mcp2517fd@0 { + compatible = "microchip,mcp251xfd"; + status = "okay"; + + spi-max-frequency = <18000000>; + int-gpios = <&mikrobus_header 7 GPIO_ACTIVE_LOW>; + reg = <0x0>; + osc-freq = <40000000>; + }; +}; + +/ { + chosen { + zephyr,canbus = &mcp2517fd_mikroe_mcp2517fd_click; + }; +}; diff --git a/boards/shields/mikroe_mcp251xfd_click/shield.yml b/boards/shields/mikroe_mcp251xfd_click/shield.yml index 607cc01b077d..590fbf949910 100644 --- a/boards/shields/mikroe_mcp251xfd_click/shield.yml +++ b/boards/shields/mikroe_mcp251xfd_click/shield.yml @@ -1,7 +1,15 @@ # SPDX-FileCopyrightText: Copyright (c) 2023 Andriy Gelman +# SPDX-FileCopyrightText: Copyright (c) 2026 Navimatix GmbH +# SPDX-FileCopyrightText: Copyright (c) 2026 TiaC Systems # SPDX-License-Identifier: Apache-2.0 shields: + - name: mikroe_mcp2517fd_click + full_name: MikroElektronika MCP2517FD Click shield + vendor: mikroe + supported_features: + - can + - name: mikroe_mcp2518fd_click full_name: MikroElektronika MCP2518FD Click shield vendor: mikroe From ef55e9bfc1af268ca3994f39b59d2815b7e43a81 Mon Sep 17 00:00:00 2001 From: Stephan Linz Date: Fri, 9 Jan 2026 23:45:28 +0100 Subject: [PATCH 2069/3659] boards: shields: mikroe_mcp251xfd_click: add MCP251863 click shield Adds MikroElektronica MCP251xFD click shield with the Microchip MCP251863 CAN FD controller. Signed-off-by: Stephan Linz --- .../mikroe_mcp251xfd_click/Kconfig.shield | 3 ++ .../mikroe_mcp251xfd_click/doc/index.rst | 37 +++++++++++++++++- .../doc/mcp251863_click.webp | Bin 0 -> 50470 bytes .../mikroe_mcp251863_click.overlay | 25 ++++++++++++ .../shields/mikroe_mcp251xfd_click/shield.yml | 6 +++ 5 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 boards/shields/mikroe_mcp251xfd_click/doc/mcp251863_click.webp create mode 100644 boards/shields/mikroe_mcp251xfd_click/mikroe_mcp251863_click.overlay diff --git a/boards/shields/mikroe_mcp251xfd_click/Kconfig.shield b/boards/shields/mikroe_mcp251xfd_click/Kconfig.shield index d4c30469a01e..6e9e35de0919 100644 --- a/boards/shields/mikroe_mcp251xfd_click/Kconfig.shield +++ b/boards/shields/mikroe_mcp251xfd_click/Kconfig.shield @@ -8,3 +8,6 @@ config SHIELD_MIKROE_MCP2517FD_CLICK config SHIELD_MIKROE_MCP2518FD_CLICK def_bool $(shields_list_contains,mikroe_mcp2518fd_click) + +config SHIELD_MIKROE_MCP251863_CLICK + def_bool $(shields_list_contains,mikroe_mcp251863_click) diff --git a/boards/shields/mikroe_mcp251xfd_click/doc/index.rst b/boards/shields/mikroe_mcp251xfd_click/doc/index.rst index fafc9eb72b41..196c1d2e551e 100644 --- a/boards/shields/mikroe_mcp251xfd_click/doc/index.rst +++ b/boards/shields/mikroe_mcp251xfd_click/doc/index.rst @@ -47,6 +47,28 @@ More information about the shield can be found at MikroElektronika MCP2518FD Click (Credit: MikroElektronika) +.. _mikroe_mcp251863_click_shield: + +MikroElektronika MCP251863 Click shield +*************************************** + +Overview +-------- + +The MCP251863 Click shield has a `MCP251863`_ CAN FD controller via a SPI +interface with an integrated high-speed `ATA6563`_ CAN transceiver. This +CAN FD controller is software compatible with the stand-alone `MCP2518FD`_ +CAN FD controller. + +More information about the shield can be found at +`Mikroe MCP251863 click`_. + +.. figure:: mcp251863_click.webp + :align: center + :alt: MikroElektronika MCP251863 Click + + MikroElektronika MCP251863 Click (Credit: MikroElektronika) + Requirements ************ @@ -59,7 +81,8 @@ Programming *********** Set ``--shield mikroe_mcp2517fd_click`` or ``--shield mikroe_mcp2518fd_click`` -when you invoke ``west build``, for example: +or ``--shield mikroe_mcp251863_click`` when you invoke ``west build``, +for example: .. zephyr-app-commands:: :zephyr-app: samples/drivers/can/counter @@ -73,6 +96,12 @@ when you invoke ``west build``, for example: :shield: mikroe_mcp2518fd_click :goals: build flash +.. zephyr-app-commands:: + :zephyr-app: samples/drivers/can/counter + :board: lpcxpresso55s28 + :shield: mikroe_mcp251863_click + :goals: build flash + References ********** @@ -93,8 +122,14 @@ References .. _MCP2518FD: https://www.microchip.com/en-us/product/MCP2518FD +.. _MCP251863: + https://www.microchip.com/en-us/product/MCP251863 + .. _Mikroe MCP2517FD click: https://www.mikroe.com/mcp2517fd-click .. _Mikroe MCP2518FD click: https://www.mikroe.com/mcp2518fd-click + +.. _Mikroe MCP251863 click: + https://www.mikroe.com/mcp251863-click diff --git a/boards/shields/mikroe_mcp251xfd_click/doc/mcp251863_click.webp b/boards/shields/mikroe_mcp251xfd_click/doc/mcp251863_click.webp new file mode 100644 index 0000000000000000000000000000000000000000..325cdeb34ca19cd441555b4d8b4cbe7a23ac7831 GIT binary patch literal 50470 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 CxrTFbGjy| zy9Qk>spv+SZ1Sr0Je!;wxL1Oseq~wkWAmTB%iZ8p3d-anet8Np)iwlpWEuFAyPv*L z%8F#05i^TCWEsg0yTK3|XaD4jlmM|&mRjZ(E4yxBpT#s)-XvaanSyVVUY#UEGR3*# zAYu^93K%*H6MX<#Y8IM9EefXfF9GyZFe&-F?IsQ#hdajrSk=xI;Y<50x>OC#r0c5cColg1cnC+72erV#k02gDvBfp4T1P4*)HT3*J!JPSUV3aa z0D=)Hffg;z@?7UiLpq_87M5z;kEY?B*e>{H;(AzTVUCOA0q_E$icr&^zG83;g+ZT9 zL-|EhYnct|_OXTgc`!dmAL}>AL%7(#QimFkxhCW3L>Q{+xkr=~2J-O~xRcp#j$ru&{_$FfAaw;fP#?H>D7u`2s0kD>(pC?{}JQL_Z#KtXe|$ zHRCI_d!3>r33?5mH~dtvM+fYyZXxTM84u@_Y>;1^vv|eB+rp*7Aza3uE<}P<@N$Q zSGZWLmlj1(Ev($NEEgnlo~8ql{9>i!3g)l~NQuBriLkR5Ig-zu{l4UjQWt@5lP?W4 z5OM_>@kw9pqNpC$sCY~?)@V5*bpiQ^%ZYB;*X8`V7HILjQoCH;uV$y}i@;BThRP+v z2;)}s<5BHCdLK;m0W^8F*sw`-5VGgx3mfsdq+5>Yj6Q#A*A*{gw6=sh`ElzozgTbdxeclb_0m+{=1=dI0$D3TrFEO@=+QN&#>rJ; zk)6-TAdlsS$HsGy{Oqz)%?I&_fO0RVdc-uc%tmR&w4RA)1V(yCT#XlQVF zpF2Fxhc6!zZ9bWaT?`L#KiB&0mycyqiHxp`y^0y(jWo}A;p(rnCi^&$LW5Ua9I7~b z;^`W+HoPmCad89h_;8Y@OHC7DPmjqV_d4pu-8i}s_i?qzp}>iEh%`HX@$39v34F1! zEP4n~pP^`1Bevnqh5O1wp5q1oVBfpkS30r{KaaV+>mosYu{y+W_Q0VaR!OgEQ5UC{ ze|4bmY9kujUpSPfuegL!pbC}!4K5iqNl6<=Q_Y z!XK%S+%o3o=W;PK1brcSVv z0BO=Y$}7KkCn+M#9O{qu^+OjYZjA#UCdtRIYsGt1bJL4Na%Lo!e!|;;OOu~DOB&X zK;Xg&03iEEABSiBmbw69c}ivNgE#rWO>iXFJ1Uj7NaT^^?&x66JRj<-LUd$g=Kiqy zsG|@8@M9kH{WQFu9HaZ0IBs76qONc}Hk=8Y=3RYqCMqwq7&$0DLqotA2S~r(YF|<> zXa%zZ&bnn8cyTt3T9;oqVM?!j)#^*};#P|(K9M;BB}z*ABkmylBtiUs^IkR;-RR>Y zF&0z%qtK%N2dVwyqXW2%#nDs-DpM0Z#naSI&~72lQUXpc-5Uk`F;eED#7a5L5sAxG zQ(=O!#Ldf|(!Uo!;B_^ojU`D$BXZ^T5+-aIwfH0<7h{=wWe7PqRl%`UX_)9f`7f#l zuVZ*n>PRBe)Qp_J%&=t<`<#5X=Udm@LHCcUhydBlLJx%NNmL5cYE-K-vN;6c4jtiQ zXSjMnK8-)`P?kH3#Kqr0r-ny`z(}&Nw&Em@>$MpkbUhi?KE9X~6GZ z>Y%OxX60{J4VGNwý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 literal 0 HcmV?d00001 diff --git a/boards/shields/mikroe_mcp251xfd_click/mikroe_mcp251863_click.overlay b/boards/shields/mikroe_mcp251xfd_click/mikroe_mcp251863_click.overlay new file mode 100644 index 000000000000..ecdcda01b246 --- /dev/null +++ b/boards/shields/mikroe_mcp251xfd_click/mikroe_mcp251863_click.overlay @@ -0,0 +1,25 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 Navimatix GmbH + * SPDX-FileCopyrightText: Copyright (c) 2026 TiaC Systems + * SPDX-License-Identifier: Apache-2.0 + */ + +&mikrobus_spi { + cs-gpios = <&mikrobus_header 2 GPIO_ACTIVE_LOW>; + + mcp251863_mikroe_mcp251863_click: mcp251863@0 { + compatible = "microchip,mcp251xfd"; + status = "okay"; + + spi-max-frequency = <18000000>; + int-gpios = <&mikrobus_header 7 GPIO_ACTIVE_LOW>; + reg = <0x0>; + osc-freq = <40000000>; + }; +}; + +/ { + chosen { + zephyr,canbus = &mcp251863_mikroe_mcp251863_click; + }; +}; diff --git a/boards/shields/mikroe_mcp251xfd_click/shield.yml b/boards/shields/mikroe_mcp251xfd_click/shield.yml index 590fbf949910..a5216e43d69c 100644 --- a/boards/shields/mikroe_mcp251xfd_click/shield.yml +++ b/boards/shields/mikroe_mcp251xfd_click/shield.yml @@ -15,3 +15,9 @@ shields: vendor: mikroe supported_features: - can + + - name: mikroe_mcp251863_click + full_name: MikroElektronika MCP251863 Click shield + vendor: mikroe + supported_features: + - can From 9d205d65f97ac8e2b66d905cbc89b39db61f4e5b Mon Sep 17 00:00:00 2001 From: Stephan Linz Date: Fri, 9 Jan 2026 23:52:52 +0100 Subject: [PATCH 2070/3659] MAINTAINERS: include MCP251xFD Click shields in CAN drivers This commit adds the MikroE MCP251xFD Click shields under the same assignees as other of the CAN driver based shields. Signed-off-by: Stephan Linz --- MAINTAINERS.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index cd19824ccc8d..900ae4da8ff6 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -1326,6 +1326,7 @@ Documentation Infrastructure: - boards/shields/canis_canpico/ - boards/shields/mcp2515/ - boards/shields/mikroe_can_fd_6_click/ + - boards/shields/mikroe_mcp251xfd_click/ - boards/shields/tcan4550evm/ - doc/connectivity/canbus/ - doc/hardware/peripherals/can/ From b13d9a0510b5ba4c6413665efb15e5233818c5e6 Mon Sep 17 00:00:00 2001 From: Alain Volmat Date: Mon, 22 Dec 2025 22:28:45 +0100 Subject: [PATCH 2071/3659] display: rename current BGR_565 format into RGB_565X The format currently expected by devices and sample display application for BGR_565 is actually RGB_565 format with bytes swapped (not B / R swapped). That is: PIXEL_FORMAT_RGB_565: * @code{.unparsed} * 7......0 15.....8 * | gggBbbbb RrrrrGgg | ... * @endcode current PIXEL_FORMAT_BGR_565: * @code{.unparsed} * 7......0 15.....8 * | RrrrrGgg gggBbbbb | ... * @endcode This is explained in both st7796s display driver but also is what is generated by the sample display application. As a video format (ex: V4L2), such format is not mentioned as BGR (for which R and B are swapped) but RGB_565X. Within the whole Zephyr tree, rename the curremt BGR_565 format into RGB_565X in order to emphasis that this is a byte swapped format rather than a B/G component swapped format. This also correct the description of the format in display.h file, which wasn't correct based on what was being used by display driver or sample display app. Signed-off-by: Alain Volmat --- boards/lilygo/twatch_s3/Kconfig.defconfig | 2 +- boards/st/stm32h573i_dk/Kconfig.defconfig | 2 +- boards/st/stm32l562e_dk/Kconfig.defconfig | 2 +- doc/releases/migration-guide-4.4.rst | 14 ++++++++++ drivers/display/Kconfig.sdl | 4 +-- drivers/display/Kconfig.st7789v | 4 +-- drivers/display/display_ili9xxx.c | 10 +++---- drivers/display/display_mcux_lcdifv3.c | 4 +-- drivers/display/display_sdl.c | 26 +++++++++---------- drivers/display/display_st7735r.c | 8 +++--- drivers/display/display_st7789v.c | 14 +++++----- drivers/display/display_st7796s.c | 16 ++++++------ drivers/mipi_dbi/mipi_dbi_esp32.c | 2 +- drivers/mipi_dbi/mipi_dbi_nxp_dcnano_lcdif.c | 2 +- drivers/mipi_dsi/Kconfig.mcux | 4 +-- include/zephyr/drivers/display.h | 10 +++---- include/zephyr/dt-bindings/display/panel.h | 2 +- modules/lvgl/lvgl_display.c | 2 +- samples/drivers/display/src/main.c | 8 +++--- .../drivers/display/display_check/src/main.c | 8 +++--- .../display/display_read_write/src/main.c | 2 +- .../display/display_read_write/testcase.yaml | 4 +-- 22 files changed, 82 insertions(+), 68 deletions(-) diff --git a/boards/lilygo/twatch_s3/Kconfig.defconfig b/boards/lilygo/twatch_s3/Kconfig.defconfig index f7e4f32af392..c8b14cc5e4e2 100644 --- a/boards/lilygo/twatch_s3/Kconfig.defconfig +++ b/boards/lilygo/twatch_s3/Kconfig.defconfig @@ -4,7 +4,7 @@ if DISPLAY choice ST7789V_PIXEL_FORMAT - default ST7789V_BGR565 + default ST7789V_RGB565X endchoice if LVGL diff --git a/boards/st/stm32h573i_dk/Kconfig.defconfig b/boards/st/stm32h573i_dk/Kconfig.defconfig index b24ccf7f1065..19258057d180 100644 --- a/boards/st/stm32h573i_dk/Kconfig.defconfig +++ b/boards/st/stm32h573i_dk/Kconfig.defconfig @@ -16,7 +16,7 @@ configdefault SDMMC_STM32_CLOCK_CHECK if DISPLAY choice ST7789V_PIXEL_FORMAT - default ST7789V_BGR565 + default ST7789V_RGB565X endchoice # Required to enable LCD backlight diff --git a/boards/st/stm32l562e_dk/Kconfig.defconfig b/boards/st/stm32l562e_dk/Kconfig.defconfig index 55ce2572f7dc..ef0832f6c9fa 100644 --- a/boards/st/stm32l562e_dk/Kconfig.defconfig +++ b/boards/st/stm32l562e_dk/Kconfig.defconfig @@ -25,7 +25,7 @@ config MIPI_DBI_STM32_FMC_MEM_BARRIER if DISPLAY choice ST7789V_PIXEL_FORMAT - default ST7789V_BGR565 + default ST7789V_RGB565X endchoice endif # DISPLAY diff --git a/doc/releases/migration-guide-4.4.rst b/doc/releases/migration-guide-4.4.rst index f45f88b12d3f..fb8b1ad773c7 100644 --- a/doc/releases/migration-guide-4.4.rst +++ b/doc/releases/migration-guide-4.4.rst @@ -326,6 +326,20 @@ Display * For ILI9341 controller, display mirroring configuration has been updated to conform with the described behavior of the sample ``samples/drivers/display``. (:github:`99267`). +* The ``PIXEL_FORMAT_BGR_565`` pixel format has been renamed to + :c:macro:`PIXEL_FORMAT_RGB_565X` to correctly reflect that it is a + byte-swapped version of RGB_565, not a channel-swapped format. + Applications using ``PIXEL_FORMAT_BGR_565`` must update to use + :c:macro:`PIXEL_FORMAT_RGB_565X`. (:github:`99276`) + +* The devicetree macro ``PANEL_PIXEL_FORMAT_BGR_565`` has been renamed to + :c:macro:`PANEL_PIXEL_FORMAT_RGB_565X`. (:github:`99276`) + +* The Kconfig options ``SDL_DISPLAY_DEFAULT_PIXEL_FORMAT_BGR_565`` and + ``ST7789V_BGR565`` have been renamed to + :kconfig:option:`SDL_DISPLAY_DEFAULT_PIXEL_FORMAT_RGB_565X` and :kconfig:option:`ST7789V_RGB565X` + respectively. (:github:`99276`) + DMA === diff --git a/drivers/display/Kconfig.sdl b/drivers/display/Kconfig.sdl index ff5c14473786..578ce5863c2c 100644 --- a/drivers/display/Kconfig.sdl +++ b/drivers/display/Kconfig.sdl @@ -34,8 +34,8 @@ choice SDL_DISPLAY_DEFAULT_PIXEL_FORMAT config SDL_DISPLAY_DEFAULT_PIXEL_FORMAT_RGB_565 bool "RGB 565" - config SDL_DISPLAY_DEFAULT_PIXEL_FORMAT_BGR_565 - bool "BGR 565" + config SDL_DISPLAY_DEFAULT_PIXEL_FORMAT_RGB_565X + bool "RGB 565X" config SDL_DISPLAY_DEFAULT_PIXEL_FORMAT_L_8 bool "Grayscale 8bit" diff --git a/drivers/display/Kconfig.st7789v b/drivers/display/Kconfig.st7789v index f38cba1c9f07..88721d2e9098 100644 --- a/drivers/display/Kconfig.st7789v +++ b/drivers/display/Kconfig.st7789v @@ -24,7 +24,7 @@ config ST7789V_RGB888 config ST7789V_RGB565 bool "RGB565" -config ST7789V_BGR565 - bool "BGR565" +config ST7789V_RGB565X + bool "RGB565X" endchoice diff --git a/drivers/display/display_ili9xxx.c b/drivers/display/display_ili9xxx.c index f44af0956601..f75a11f7039d 100644 --- a/drivers/display/display_ili9xxx.c +++ b/drivers/display/display_ili9xxx.c @@ -294,7 +294,7 @@ ili9xxx_set_pixel_format(const struct device *dev, uint8_t tx_data; uint8_t bytes_per_pixel; - if (pixel_format == PIXEL_FORMAT_RGB_565 || pixel_format == PIXEL_FORMAT_BGR_565) { + if (pixel_format == PIXEL_FORMAT_RGB_565 || pixel_format == PIXEL_FORMAT_RGB_565X) { bytes_per_pixel = 2U; tx_data = ILI9XXX_PIXSET_MCU_16_BIT | ILI9XXX_PIXSET_RGB_16_BIT; } else if (pixel_format == PIXEL_FORMAT_RGB_888) { @@ -323,7 +323,7 @@ static int ili9xxx_set_orientation(const struct device *dev, struct ili9xxx_data *data = dev->data; int r; - uint8_t tx_data = data->pixel_format == PIXEL_FORMAT_BGR_565 + uint8_t tx_data = data->pixel_format == PIXEL_FORMAT_RGB_565X ? ILI9XXX_MADCTL_BGR : 0; if (config->quirks->cmd_set == CMD_SET_1) { if (orientation == DISPLAY_ORIENTATION_NORMAL) { @@ -368,7 +368,7 @@ static void ili9xxx_get_capabilities(const struct device *dev, memset(capabilities, 0, sizeof(struct display_capabilities)); capabilities->supported_pixel_formats = - PIXEL_FORMAT_RGB_565 | PIXEL_FORMAT_RGB_888 | PIXEL_FORMAT_BGR_565; + PIXEL_FORMAT_RGB_565 | PIXEL_FORMAT_RGB_888 | PIXEL_FORMAT_RGB_565X; capabilities->current_pixel_format = data->pixel_format; if (data->orientation == DISPLAY_ORIENTATION_NORMAL || @@ -394,8 +394,8 @@ static int ili9xxx_configure(const struct device *dev) /* pixel format */ if (config->pixel_format == PANEL_PIXEL_FORMAT_RGB_565) { pixel_format = PIXEL_FORMAT_RGB_565; - } else if (config->pixel_format == PANEL_PIXEL_FORMAT_BGR_565) { - pixel_format = PIXEL_FORMAT_BGR_565; + } else if (config->pixel_format == PANEL_PIXEL_FORMAT_RGB_565X) { + pixel_format = PIXEL_FORMAT_RGB_565X; } else if (config->pixel_format == PANEL_PIXEL_FORMAT_RGB_888) { pixel_format = PIXEL_FORMAT_RGB_888; } else { diff --git a/drivers/display/display_mcux_lcdifv3.c b/drivers/display/display_mcux_lcdifv3.c index e759f7c2b118..8121bac52c90 100644 --- a/drivers/display/display_mcux_lcdifv3.c +++ b/drivers/display/display_mcux_lcdifv3.c @@ -254,7 +254,7 @@ static int mcux_lcdifv3_init(const struct device *dev) lcdifv3_buffer_config_t buffer_config = config->buffer_config; lcdifv3_display_config_t display_config = config->display_config; /* Set the Pixel format */ - if (config->pixel_format == PIXEL_FORMAT_BGR_565) { + if (config->pixel_format == PIXEL_FORMAT_RGB_565X) { buffer_config.pixelFormat = kLCDIFV3_PixelFormatRGB565; } else if (config->pixel_format == PIXEL_FORMAT_RGB_888) { buffer_config.pixelFormat = kLCDIFV3_PixelFormatRGB888; @@ -289,7 +289,7 @@ static const struct display_driver_api mcux_lcdifv3_api = { #define GET_PIXEL_FORMAT(id) \ ((DT_INST_ENUM_IDX(id, pixel_format) == 0) \ - ? PIXEL_FORMAT_BGR_565 \ + ? PIXEL_FORMAT_RGB_565X \ : ((DT_INST_ENUM_IDX(id, pixel_format) == 1) ? PIXEL_FORMAT_RGB_888 \ : PIXEL_FORMAT_ARGB_8888)) diff --git a/drivers/display/display_sdl.c b/drivers/display/display_sdl.c index 08a769ef8e48..5abd9c55dcb3 100644 --- a/drivers/display/display_sdl.c +++ b/drivers/display/display_sdl.c @@ -189,8 +189,8 @@ static int sdl_display_init(const struct device *dev) PIXEL_FORMAT_MONO10 #elif defined(CONFIG_SDL_DISPLAY_DEFAULT_PIXEL_FORMAT_RGB_565) PIXEL_FORMAT_RGB_565 -#elif defined(CONFIG_SDL_DISPLAY_DEFAULT_PIXEL_FORMAT_BGR_565) - PIXEL_FORMAT_BGR_565 +#elif defined(CONFIG_SDL_DISPLAY_DEFAULT_PIXEL_FORMAT_RGB_565X) + PIXEL_FORMAT_RGB_565X #elif defined(CONFIG_SDL_DISPLAY_DEFAULT_PIXEL_FORMAT_L_8) PIXEL_FORMAT_L_8 #elif defined(CONFIG_SDL_DISPLAY_DEFAULT_PIXEL_FORMAT_AL_88) @@ -296,8 +296,8 @@ static void sdl_display_write_rgb565(uint8_t *disp_buf, } } -static void sdl_display_write_bgr565(uint8_t *disp_buf, - const struct display_buffer_descriptor *desc, const void *buf) +static void sdl_display_write_rgb565x(uint8_t *disp_buf, + const struct display_buffer_descriptor *desc, const void *buf) { uint32_t w_idx; uint32_t h_idx; @@ -415,8 +415,8 @@ static int sdl_display_write(const struct device *dev, const uint16_t x, sdl_display_write_mono(disp_data->buf, desc, buf, false); } else if (disp_data->current_pixel_format == PIXEL_FORMAT_RGB_565) { sdl_display_write_rgb565(disp_data->buf, desc, buf); - } else if (disp_data->current_pixel_format == PIXEL_FORMAT_BGR_565) { - sdl_display_write_bgr565(disp_data->buf, desc, buf); + } else if (disp_data->current_pixel_format == PIXEL_FORMAT_RGB_565X) { + sdl_display_write_rgb565x(disp_data->buf, desc, buf); } else if (disp_data->current_pixel_format == PIXEL_FORMAT_L_8) { sdl_display_write_l8(disp_data->buf, desc, buf); } else if (disp_data->current_pixel_format == PIXEL_FORMAT_AL_88) { @@ -493,8 +493,8 @@ static void sdl_display_read_rgb565(const uint8_t *read_buf, } } -static void sdl_display_read_bgr565(const uint8_t *read_buf, - const struct display_buffer_descriptor *desc, void *buf) +static void sdl_display_read_rgb565x(const uint8_t *read_buf, + const struct display_buffer_descriptor *desc, void *buf) { uint32_t w_idx; uint32_t h_idx; @@ -641,8 +641,8 @@ static int sdl_display_read(const struct device *dev, const uint16_t x, const ui sdl_display_read_mono(disp_data->read_buf, desc, buf, false); } else if (disp_data->current_pixel_format == PIXEL_FORMAT_RGB_565) { sdl_display_read_rgb565(disp_data->read_buf, desc, buf); - } else if (disp_data->current_pixel_format == PIXEL_FORMAT_BGR_565) { - sdl_display_read_bgr565(disp_data->read_buf, desc, buf); + } else if (disp_data->current_pixel_format == PIXEL_FORMAT_RGB_565X) { + sdl_display_read_rgb565x(disp_data->read_buf, desc, buf); } else if (disp_data->current_pixel_format == PIXEL_FORMAT_L_8) { sdl_display_read_l8(disp_data->read_buf, desc, buf); } else if (disp_data->current_pixel_format == PIXEL_FORMAT_AL_88) { @@ -679,7 +679,7 @@ static int sdl_display_clear(const struct device *dev) bgcolor = 0xFFu; break; case PIXEL_FORMAT_RGB_565: - case PIXEL_FORMAT_BGR_565: + case PIXEL_FORMAT_RGB_565X: size = config->width * config->height * 2U; break; case PIXEL_FORMAT_AL_88: @@ -757,7 +757,7 @@ static void sdl_display_get_capabilities( PIXEL_FORMAT_MONO01 | PIXEL_FORMAT_MONO10 | PIXEL_FORMAT_RGB_565 | - PIXEL_FORMAT_BGR_565 | + PIXEL_FORMAT_RGB_565X | PIXEL_FORMAT_L_8 | PIXEL_FORMAT_AL_88; capabilities->current_pixel_format = disp_data->current_pixel_format; @@ -777,7 +777,7 @@ static int sdl_display_set_pixel_format(const struct device *dev, case PIXEL_FORMAT_MONO01: case PIXEL_FORMAT_MONO10: case PIXEL_FORMAT_RGB_565: - case PIXEL_FORMAT_BGR_565: + case PIXEL_FORMAT_RGB_565X: case PIXEL_FORMAT_L_8: case PIXEL_FORMAT_AL_88: disp_data->current_pixel_format = pixel_format; diff --git a/drivers/display/display_st7735r.c b/drivers/display/display_st7735r.c index 6d785f9056d1..5c10bfd1dd52 100644 --- a/drivers/display/display_st7735r.c +++ b/drivers/display/display_st7735r.c @@ -212,7 +212,7 @@ static int st7735r_write(const struct device *dev, if (!(config->madctl & ST7735R_MADCTL_BGR) != !config->rgb_is_inverted) { - fmt = PIXEL_FORMAT_BGR_565; + fmt = PIXEL_FORMAT_RGB_565X; } else { fmt = PIXEL_FORMAT_RGB_565; } @@ -262,8 +262,8 @@ static void st7735r_get_capabilities(const struct device *dev, * It is a workaround for supporting buggy modules that display RGB as BGR. */ if (!(config->madctl & ST7735R_MADCTL_BGR) != !config->rgb_is_inverted) { - capabilities->supported_pixel_formats = PIXEL_FORMAT_BGR_565; - capabilities->current_pixel_format = PIXEL_FORMAT_BGR_565; + capabilities->supported_pixel_formats = PIXEL_FORMAT_RGB_565X; + capabilities->current_pixel_format = PIXEL_FORMAT_RGB_565X; } else { capabilities->supported_pixel_formats = PIXEL_FORMAT_RGB_565; capabilities->current_pixel_format = PIXEL_FORMAT_RGB_565; @@ -282,7 +282,7 @@ static int st7735r_set_pixel_format(const struct device *dev, return 0; } - if ((pixel_format == PIXEL_FORMAT_BGR_565) && + if ((pixel_format == PIXEL_FORMAT_RGB_565X) && (config->madctl & ST7735R_MADCTL_BGR)) { return 0; } diff --git a/drivers/display/display_st7789v.c b/drivers/display/display_st7789v.c index 084d48a3e549..5d9408fbae16 100644 --- a/drivers/display/display_st7789v.c +++ b/drivers/display/display_st7789v.c @@ -184,8 +184,8 @@ static int st7789v_write(const struct device *dev, } if (IS_ENABLED(CONFIG_ST7789V_RGB565)) { pixfmt = PIXEL_FORMAT_RGB_565; - } else if (IS_ENABLED(CONFIG_ST7789V_BGR565)) { - pixfmt = PIXEL_FORMAT_BGR_565; + } else if (IS_ENABLED(CONFIG_ST7789V_RGB565X)) { + pixfmt = PIXEL_FORMAT_RGB_565X; } else { pixfmt = PIXEL_FORMAT_RGB_888; } @@ -225,9 +225,9 @@ static void st7789v_get_capabilities(const struct device *dev, #ifdef CONFIG_ST7789V_RGB565 capabilities->supported_pixel_formats = PIXEL_FORMAT_RGB_565; capabilities->current_pixel_format = PIXEL_FORMAT_RGB_565; -#elif CONFIG_ST7789V_BGR565 - capabilities->supported_pixel_formats = PIXEL_FORMAT_BGR_565; - capabilities->current_pixel_format = PIXEL_FORMAT_BGR_565; +#elif CONFIG_ST7789V_RGB565X + capabilities->supported_pixel_formats = PIXEL_FORMAT_RGB_565X; + capabilities->current_pixel_format = PIXEL_FORMAT_RGB_565X; #else capabilities->supported_pixel_formats = PIXEL_FORMAT_RGB_888; capabilities->current_pixel_format = PIXEL_FORMAT_RGB_888; @@ -240,8 +240,8 @@ static int st7789v_set_pixel_format(const struct device *dev, { #ifdef CONFIG_ST7789V_RGB565 if (pixel_format == PIXEL_FORMAT_RGB_565) { -#elif CONFIG_ST7789V_BGR565 - if (pixel_format == PIXEL_FORMAT_BGR_565) { +#elif CONFIG_ST7789V_RGB565X + if (pixel_format == PIXEL_FORMAT_RGB_565X) { #else if (pixel_format == PIXEL_FORMAT_RGB_888) { #endif diff --git a/drivers/display/display_st7796s.c b/drivers/display/display_st7796s.c index faa90497da37..5065b650ad91 100644 --- a/drivers/display/display_st7796s.c +++ b/drivers/display/display_st7796s.c @@ -105,19 +105,19 @@ static int st7796s_get_pixelfmt(const struct device *dev) * Zephyr uses little endian byte order when the pixel format has * multiple bytes. * - * For BGR565, Red is placed in byte 1 and Blue in byte 0. - * For RGB565, Red is placed in byte 0 and Blue in byte 1. + * For RGB565, Red is placed in byte 1 and Blue in byte 0. + * For RGB565X, Red is placed in byte 0 and Blue in byte 1. * * This is not an issue when using a 16-bit interface. * For RGB565, this would map to Red being in D[11:15] and - * Blue in D[0:4] and vice versa for BGR565. + * Blue in D[0:4] and vice versa for RGB565X. * * However this is an issue when using a 8-bit interface. - * For BGR565, Blue is placed in byte 0 as mentioned earlier. + * For RGB565, Blue is placed in byte 0 as mentioned earlier. * However the controller expects Red to be in D[3:7] of byte 0. * - * Hence we report pixel format as RGB when MADCTL setting is BGR - * and vice versa. + * Hence we report pixel format as RGB565 when MADCTL setting is + * RGB565X and vice versa. */ if (config->dbi_config.mode == MIPI_DBI_MODE_8080_BUS_8_BIT) { /* @@ -129,7 +129,7 @@ static int st7796s_get_pixelfmt(const struct device *dev) config->rgb_is_inverted) { return PIXEL_FORMAT_RGB_565; } else { - return PIXEL_FORMAT_BGR_565; + return PIXEL_FORMAT_RGB_565X; } } @@ -145,7 +145,7 @@ static int st7796s_get_pixelfmt(const struct device *dev) config->rgb_is_inverted) { return PIXEL_FORMAT_RGB_565; } else { - return PIXEL_FORMAT_BGR_565; + return PIXEL_FORMAT_RGB_565X; } } diff --git a/drivers/mipi_dbi/mipi_dbi_esp32.c b/drivers/mipi_dbi/mipi_dbi_esp32.c index a651170399ef..272feed05b23 100644 --- a/drivers/mipi_dbi/mipi_dbi_esp32.c +++ b/drivers/mipi_dbi/mipi_dbi_esp32.c @@ -286,7 +286,7 @@ static int mipi_dbi_esp32_write_display(const struct device *dev, struct mipi_dbi_esp32_data *drv_data = dev->data; int ret; - if (pixfmt != PIXEL_FORMAT_RGB_565 && pixfmt != PIXEL_FORMAT_BGR_565) { + if (pixfmt != PIXEL_FORMAT_RGB_565 && pixfmt != PIXEL_FORMAT_RGB_565X) { return -ENOTSUP; } diff --git a/drivers/mipi_dbi/mipi_dbi_nxp_dcnano_lcdif.c b/drivers/mipi_dbi/mipi_dbi_nxp_dcnano_lcdif.c index 8870f1ef3e39..67ba8be4e20e 100644 --- a/drivers/mipi_dbi/mipi_dbi_nxp_dcnano_lcdif.c +++ b/drivers/mipi_dbi/mipi_dbi_nxp_dcnano_lcdif.c @@ -219,7 +219,7 @@ static int mipi_dbi_dcnano_lcdif_write_display(const struct device *dev, fbConfig.format = kLCDIF_PixelFormatARGB8888; bytes_per_pixel = 4U; break; - case PIXEL_FORMAT_BGR_565: + case PIXEL_FORMAT_RGB_565X: fbConfig.inOrder = kLCDIF_PixelInputOrderABGR; case PIXEL_FORMAT_RGB_565: fbConfig.format = kLCDIF_PixelFormatRGB565; diff --git a/drivers/mipi_dsi/Kconfig.mcux b/drivers/mipi_dsi/Kconfig.mcux index 73880601267c..4e8cd0e53e6b 100644 --- a/drivers/mipi_dsi/Kconfig.mcux +++ b/drivers/mipi_dsi/Kconfig.mcux @@ -23,8 +23,8 @@ config MIPI_DSI_MCUX_2L_SMARTDMA depends on DMA_MCUX_SMARTDMA help Use SMARTDMA. This accelerator will automatically - convert RGB565 input data to BGR565 (little endian to big endian), - and write it to the MIPI DSI. + convert RGB565 input data to RGB565X, and write it + to the MIPI DSI. config MIPI_DSI_MCUX_NXP_DCNANO_LCDIF bool "Use NXP DCNano DBI controller with MIPI DSI" diff --git a/include/zephyr/drivers/display.h b/include/zephyr/drivers/display.h index f662abfd065e..0f58ea0d8373 100644 --- a/include/zephyr/drivers/display.h +++ b/include/zephyr/drivers/display.h @@ -62,16 +62,16 @@ enum display_pixel_format { */ PIXEL_FORMAT_RGB_565 = BIT(4), /** - * 16-bit RGB format packed into two bytes: 5 blue bits [15:11], 6 - * green bits [10:5], 5 red bits [4:0]. For example, in little-endian machine: + * 16-bit RGB format packed into two bytes. Byte swapped version of + * the PIXEL_FORMAT_RGB_565 format. * * @code{.unparsed} * 7......0 15.....8 - * | gggRrrrr BbbbbGgg | ... + * | RrrrrGgg gggBbbbb | ... * @endcode * */ - PIXEL_FORMAT_BGR_565 = BIT(5), + PIXEL_FORMAT_RGB_565X = BIT(5), PIXEL_FORMAT_L_8 = BIT(6), /**< 8-bit Grayscale/Luminance, equivalent to */ /**< GRAY, GREY, GRAY8, Y8, R8, etc... */ PIXEL_FORMAT_AL_88 = BIT(7), /**< 8-bit Grayscale/Luminance with alpha */ @@ -90,7 +90,7 @@ enum display_pixel_format { (((fmt & PIXEL_FORMAT_MONO10) >> 2) * 1U) + \ (((fmt & PIXEL_FORMAT_ARGB_8888) >> 3) * 32U) + \ (((fmt & PIXEL_FORMAT_RGB_565) >> 4) * 16U) + \ - (((fmt & PIXEL_FORMAT_BGR_565) >> 5) * 16U) + \ + (((fmt & PIXEL_FORMAT_RGB_565X) >> 5) * 16U) + \ (((fmt & PIXEL_FORMAT_L_8) >> 6) * 8U) + \ (((fmt & PIXEL_FORMAT_AL_88) >> 7) * 16U)) diff --git a/include/zephyr/dt-bindings/display/panel.h b/include/zephyr/dt-bindings/display/panel.h index 32d50babde7f..4bc302006fbd 100644 --- a/include/zephyr/dt-bindings/display/panel.h +++ b/include/zephyr/dt-bindings/display/panel.h @@ -28,7 +28,7 @@ #define PANEL_PIXEL_FORMAT_MONO10 (0x1 << 2) /* 1=Black 0=White */ #define PANEL_PIXEL_FORMAT_ARGB_8888 (0x1 << 3) #define PANEL_PIXEL_FORMAT_RGB_565 (0x1 << 4) -#define PANEL_PIXEL_FORMAT_BGR_565 (0x1 << 5) +#define PANEL_PIXEL_FORMAT_RGB_565X (0x1 << 5) #define PANEL_PIXEL_FORMAT_L_8 (0x1 << 6) #define PANEL_PIXEL_FORMAT_AL_88 (0x1 << 7) diff --git a/modules/lvgl/lvgl_display.c b/modules/lvgl/lvgl_display.c index d2c253238981..fe4fc5955d75 100644 --- a/modules/lvgl/lvgl_display.c +++ b/modules/lvgl/lvgl_display.c @@ -90,7 +90,7 @@ int set_lvgl_rendering_cb(lv_display_t *display) display); break; case PIXEL_FORMAT_RGB_565: - case PIXEL_FORMAT_BGR_565: + case PIXEL_FORMAT_RGB_565X: lv_display_set_color_format(display, LV_COLOR_FORMAT_RGB565); lv_display_set_flush_cb(display, lvgl_flush_cb_16bit); lv_display_add_event_cb(display, lvgl_rounder_cb, LV_EVENT_INVALIDATE_AREA, diff --git a/samples/drivers/display/src/main.c b/samples/drivers/display/src/main.c index 273349e5897d..17ad4d5635a7 100644 --- a/samples/drivers/display/src/main.c +++ b/samples/drivers/display/src/main.c @@ -119,8 +119,8 @@ static uint16_t get_rgb565_color(enum corner corner, uint8_t grey) return color; } -static void fill_buffer_bgr565(enum corner corner, uint8_t grey, uint8_t *buf, - size_t buf_size) +static void fill_buffer_rgb565x(enum corner corner, uint8_t grey, uint8_t *buf, + size_t buf_size) { uint16_t color = get_rgb565_color(corner, grey); @@ -295,9 +295,9 @@ int main(void) fill_buffer_fnc = fill_buffer_rgb565; buf_size *= 2; break; - case PIXEL_FORMAT_BGR_565: + case PIXEL_FORMAT_RGB_565X: bg_color = 0xFFu; - fill_buffer_fnc = fill_buffer_bgr565; + fill_buffer_fnc = fill_buffer_rgb565x; buf_size *= 2; break; case PIXEL_FORMAT_L_8: diff --git a/tests/drivers/display/display_check/src/main.c b/tests/drivers/display/display_check/src/main.c index 33a3ec9dd156..8c5cc802090f 100644 --- a/tests/drivers/display/display_check/src/main.c +++ b/tests/drivers/display/display_check/src/main.c @@ -114,8 +114,8 @@ static uint16_t get_rgb565_color(enum corner corner, uint8_t grey) return color; } -static void fill_buffer_bgr565(enum corner corner, uint8_t grey, uint8_t *buf, - size_t buf_size) +static void fill_buffer_rgb565x(enum corner corner, uint8_t grey, uint8_t *buf, + size_t buf_size) { uint16_t color = get_rgb565_color(corner, grey); @@ -287,9 +287,9 @@ int test_display(void) fill_buffer_fnc = fill_buffer_rgb565; buf_size *= 2; break; - case PIXEL_FORMAT_BGR_565: + case PIXEL_FORMAT_RGB_565X: bg_color = 0xFFu; - fill_buffer_fnc = fill_buffer_bgr565; + fill_buffer_fnc = fill_buffer_rgb565x; buf_size *= 2; break; case PIXEL_FORMAT_L_8: diff --git a/tests/drivers/display/display_read_write/src/main.c b/tests/drivers/display/display_read_write/src/main.c index 6ae88b1fb97b..9460af253ea0 100644 --- a/tests/drivers/display/display_read_write/src/main.c +++ b/tests/drivers/display/display_read_write/src/main.c @@ -43,7 +43,7 @@ static inline uint8_t bytes_per_pixel(enum display_pixel_format pixel_format) case PIXEL_FORMAT_RGB_888: return 3; case PIXEL_FORMAT_RGB_565: - case PIXEL_FORMAT_BGR_565: + case PIXEL_FORMAT_RGB_565X: case PIXEL_FORMAT_AL_88: return 2; case PIXEL_FORMAT_L_8: diff --git a/tests/drivers/display/display_read_write/testcase.yaml b/tests/drivers/display/display_read_write/testcase.yaml index 62c63a9c3ea8..fb29ea7c35b6 100644 --- a/tests/drivers/display/display_read_write/testcase.yaml +++ b/tests/drivers/display/display_read_write/testcase.yaml @@ -89,12 +89,12 @@ tests: - native_sim/native/64 extra_configs: - CONFIG_SDL_DISPLAY_DEFAULT_PIXEL_FORMAT_RGB_565=y - drivers.display.read_write.sdl.bgr565: + drivers.display.read_write.sdl.rgb565x: platform_allow: - native_sim - native_sim/native/64 extra_configs: - - CONFIG_SDL_DISPLAY_DEFAULT_PIXEL_FORMAT_BGR_565=y + - CONFIG_SDL_DISPLAY_DEFAULT_PIXEL_FORMAT_RGB_565X=y drivers.display.read_write.ili9340: tags: - shield From 83e6e4379b580fc7cb7958ea93558700b175d200 Mon Sep 17 00:00:00 2001 From: Alain Volmat Date: Wed, 12 Nov 2025 20:47:29 +0100 Subject: [PATCH 2072/3659] include: display: Add description for all formats Add detailed description for all supported display formats. Signed-off-by: Alain Volmat --- include/zephyr/drivers/display.h | 70 +++++++++++++++++++++++++++++++- 1 file changed, 69 insertions(+), 1 deletion(-) diff --git a/include/zephyr/drivers/display.h b/include/zephyr/drivers/display.h index 0f58ea0d8373..6faa52566745 100644 --- a/include/zephyr/drivers/display.h +++ b/include/zephyr/drivers/display.h @@ -46,21 +46,65 @@ extern "C" { * big endian. */ enum display_pixel_format { + /** + * 24-bit RGB format with 8 bits per component. + * + * Below shows how data are organized in memory. + * + * @code{.unparsed} + * Byte 0 Byte 1 Byte 2 + * 7......0 15.....8 23....16 + * | Bbbbbbbb Gggggggg Rrrrrrrr | ... + * @endcode + * + */ PIXEL_FORMAT_RGB_888 = BIT(0), /**< 24-bit RGB */ + + /** + * 1-bit monochrome format with 1 bit per pixel, thus each byte represent 8 pixels + * Two variants, with black being either represented by 0 or 1 + * + * Below shows how data are organized in memory. + * + * @code{.unparsed} + * Byte 0 | Byte 1 | + * 7......0 7......0 + * | MMMMMMMM | MMMMMMMM | ... + * @endcode + * + */ PIXEL_FORMAT_MONO01 = BIT(1), /**< Monochrome (0=Black 1=White) */ PIXEL_FORMAT_MONO10 = BIT(2), /**< Monochrome (1=Black 0=White) */ + + /** + * 32-bit RGB format with 8 bits per component and 8 bits for alpha. + * + * Below shows how data are organized in memory. + * + * @code{.unparsed} + * Byte 0 Byte 1 Byte 2 Byte 3 + * 7......0 15.....8 23....16 31....24 + * | Bbbbbbbb Gggggggg Rrrrrrrr Aaaaaaaa | ... + * @endcode + * + */ PIXEL_FORMAT_ARGB_8888 = BIT(3), /**< 32-bit ARGB */ + /** * 16-bit RGB format packed into two bytes: 5 red bits [15:11], 6 - * green bits [10:5], 5 blue bits [4:0]. For example, in little-endian machine: + * green bits [10:5], 5 blue bits [4:0]. + * + * Below shows how data are organized in memory. * * @code{.unparsed} + * Byte 0 Byte 1 | * 7......0 15.....8 * | gggBbbbb RrrrrGgg | ... * @endcode * */ PIXEL_FORMAT_RGB_565 = BIT(4), + /** * 16-bit RGB format packed into two bytes. Byte swapped version of * the PIXEL_FORMAT_RGB_565 format. @@ -72,8 +116,32 @@ enum display_pixel_format { * */ PIXEL_FORMAT_RGB_565X = BIT(5), + + /** + * 8-bit Greyscale format + * + * Below shows how data are organized in memory. + * + * @code{.unparsed} + * Byte 0 | Byte 1 | + * 7......0 7......0 + * | Gggggggg | Gggggggg | ... + * @endcode + */ PIXEL_FORMAT_L_8 = BIT(6), /**< 8-bit Grayscale/Luminance, equivalent to */ /**< GRAY, GREY, GRAY8, Y8, R8, etc... */ + + /** + * 16-bit Greyscale format with 8-bit luminance and 8-bit for alpha + * + * Below shows how data are organized in memory. + * + * @code{.unparsed} + * Byte 0 Byte 1 | + * 7......0 15.....8 + * | Gggggggg Aaaaaaaa | ... + * @endcode + */ PIXEL_FORMAT_AL_88 = BIT(7), /**< 8-bit Grayscale/Luminance with alpha */ }; From 26afede1db980a8a7037412043468666a67ee29d Mon Sep 17 00:00:00 2001 From: Alain Volmat Date: Mon, 22 Dec 2025 22:54:41 +0100 Subject: [PATCH 2073/3659] samples: display: ensure data proper endianness buffer fill Ensure proper endianness when data are written via 16 or 32bit write. Signed-off-by: Alain Volmat --- samples/drivers/display/src/main.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/samples/drivers/display/src/main.c b/samples/drivers/display/src/main.c index 17ad4d5635a7..82cb64439dcf 100644 --- a/samples/drivers/display/src/main.c +++ b/samples/drivers/display/src/main.c @@ -13,6 +13,7 @@ LOG_MODULE_REGISTER(sample, LOG_LEVEL_INF); #include #include #include +#include #ifdef CONFIG_ARCH_POSIX #include "posix_board_if.h" @@ -64,7 +65,7 @@ static void fill_buffer_argb8888(enum corner corner, uint8_t grey, uint8_t *buf, } for (size_t idx = 0; idx < buf_size; idx += 4) { - *((uint32_t *)(buf + idx)) = color; + *((uint32_t *)(buf + idx)) = sys_cpu_to_le32(color); } } @@ -189,7 +190,7 @@ static void fill_buffer_al_88(enum corner corner, uint8_t grey, uint8_t *buf, } for (size_t idx = 0; idx < buf_size; idx += 2) { - *((uint16_t *)(buf + idx)) = color; + *((uint16_t *)(buf + idx)) = sys_cpu_to_le16(color); } } From 321f08ae9758494eb3b9a50f0eabb8b34e717c96 Mon Sep 17 00:00:00 2001 From: Alain Volmat Date: Wed, 12 Nov 2025 20:48:35 +0100 Subject: [PATCH 2074/3659] samples: display: fix RGB888 red/blue values The RGB888 colors generated leads to having byte0 - R byte1 - G byte2 - B while the RGB888 is usually described as B - G - R going from byte0 to byte2. Signed-off-by: Alain Volmat --- samples/drivers/display/src/main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/samples/drivers/display/src/main.c b/samples/drivers/display/src/main.c index 82cb64439dcf..b93980b09915 100644 --- a/samples/drivers/display/src/main.c +++ b/samples/drivers/display/src/main.c @@ -90,9 +90,9 @@ static void fill_buffer_rgb888(enum corner corner, uint8_t grey, uint8_t *buf, } for (size_t idx = 0; idx < buf_size; idx += 3) { - *(buf + idx + 0) = color >> 16; - *(buf + idx + 1) = color >> 8; - *(buf + idx + 2) = color >> 0; + *(buf + idx + 0) = (color >> 0) & 0xFFu; + *(buf + idx + 1) = (color >> 8) & 0xFFu; + *(buf + idx + 2) = (color >> 16) & 0xFFu; } } From b39b8bc94c5376592e9c16ab48e5fdaa83fe0e11 Mon Sep 17 00:00:00 2001 From: Alain Volmat Date: Mon, 22 Dec 2025 23:34:11 +0100 Subject: [PATCH 2075/3659] samples: display: add corner colors in L_8 mode Draw different greyscale in all 4 corners in L_8 mode. Signed-off-by: Alain Volmat --- samples/drivers/display/src/main.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/samples/drivers/display/src/main.c b/samples/drivers/display/src/main.c index b93980b09915..3cfdacf79035 100644 --- a/samples/drivers/display/src/main.c +++ b/samples/drivers/display/src/main.c @@ -161,8 +161,29 @@ static void fill_buffer_mono(enum corner corner, uint8_t grey, static inline void fill_buffer_l_8(enum corner corner, uint8_t grey, uint8_t *buf, size_t buf_size) { + uint8_t color; + + switch (corner) { + case TOP_LEFT: + color = 0x00u; + break; + case TOP_RIGHT: + /* Use 0xE0 since 0xFF leads to drawing white corner on white back-ground */ + color = 0xE0u; + break; + case BOTTOM_RIGHT: + color = 0x88u; + break; + case BOTTOM_LEFT: + color = 0x00u | grey; + break; + default: + color = 0; + break; + } + for (size_t idx = 0; idx < buf_size; idx += 1) { - *(uint8_t *)(buf + idx) = grey; + *(uint8_t *)(buf + idx) = color; } } From 5b5cdecb97e906de867677e903647e2a9461a752 Mon Sep 17 00:00:00 2001 From: Alain Volmat Date: Sun, 21 Dec 2025 21:06:17 +0100 Subject: [PATCH 2076/3659] display: fix SDL display format handling Switch SDL buffers from SDL_PIXELFORMAT_ARGB8888 to SDL_PIXELFORMAT_BGRA32. BGRA32 is platform endianness independent description, defined as below: Byte 0 Byte 1 Byte 2 Byte 3 7......0 15.....8 23....16 31....24 Bbbbbbbb Gggggggg Rrrrrrrr Aaaaaaaa The driver is then updated in order to ensure that all buffers, given via a PIXEL_FORMAT_ described format are properly converted into the SDL_PIXELFORMAT_BGRA32. At the same time endianness conversion code is also added in order to avoid taking assumption that the running platform is little-endian and ensure that data are properly read as expected. Signed-off-by: Alain Volmat --- drivers/display/display_sdl.c | 184 ++++++++++++++++++++++----- drivers/display/display_sdl_bottom.c | 8 +- 2 files changed, 156 insertions(+), 36 deletions(-) diff --git a/drivers/display/display_sdl.c b/drivers/display/display_sdl.c index 5abd9c55dcb3..b6207c879b6d 100644 --- a/drivers/display/display_sdl.c +++ b/drivers/display/display_sdl.c @@ -212,6 +212,15 @@ static int sdl_display_init(const struct device *dev) return 0; } +/* + * Convert from Byte 0 Byte 1 Byte 2 Byte 3 + * 7......0 15.....8 23....16 31....24 + * PIXEL_FORMAT_ARGB_8888 Bbbbbbbb Gggggggg Rrrrrrrr Aaaaaaaa + * into + * SDL_PIXELFORMAT_BGRA32 Bbbbbbbb Gggggggg Rrrrrrrr Aaaaaaaa + * + * Hence, simple copy is enough + */ static void sdl_display_write_argb8888(void *disp_buf, const struct display_buffer_descriptor *desc, const void *buf) { @@ -221,6 +230,13 @@ static void sdl_display_write_argb8888(void *disp_buf, memcpy(disp_buf, buf, desc->pitch * 4U * desc->height); } +/* + * Convert from Byte 0 Byte 1 Byte 2 Byte 3 + * 7......0 15.....8 23....16 31....24 + * PIXEL_FORMAT_RGB_888 Bbbbbbbb Gggggggg Rrrrrrrr Bbbbbbbb + * into + * SDL_PIXELFORMAT_BGRA32 Bbbbbbbb Gggggggg Rrrrrrrr Ffffffff + */ static void sdl_display_write_rgb888(uint8_t *disp_buf, const struct display_buffer_descriptor *desc, const void *buf) { @@ -236,15 +252,24 @@ static void sdl_display_write_rgb888(uint8_t *disp_buf, for (w_idx = 0U; w_idx < desc->width; ++w_idx) { byte_ptr = (const uint8_t *)buf + ((h_idx * desc->pitch) + w_idx) * 3U; - pixel = *byte_ptr << 16; - pixel |= *(byte_ptr + 1) << 8; - pixel |= *(byte_ptr + 2); - *((uint32_t *)disp_buf) = pixel | 0xFF000000; + pixel = *(byte_ptr + 2) << 16; /* R */ + pixel |= *(byte_ptr + 1) << 8; /* G */ + pixel |= *byte_ptr; /* B */ + *((uint32_t *)disp_buf) = sys_cpu_to_le32(pixel | 0xFF000000); disp_buf += 4; } } } +/* + * Convert from Byte 0 Byte 1 Byte 2 Byte 3 + * 7......0 15.....8 23....16 31....24 + * PIXEL_FORMAT_AL_88 Gggggggg Aaaaaaaa Gggggggg Aaaaaaaa + * into + * SDL_PIXELFORMAT_BGRA32 Bbbbbbbb Gggggggg Rrrrrrrr Aaaaaaaa + * + * G value is applied to all R/G/B value for BGRA32 + */ static void sdl_display_write_al88(uint8_t *disp_buf, const struct display_buffer_descriptor *desc, const void *buf) { @@ -260,16 +285,23 @@ static void sdl_display_write_al88(uint8_t *disp_buf, for (w_idx = 0U; w_idx < desc->width; ++w_idx) { byte_ptr = (const uint8_t *)buf + ((h_idx * desc->pitch) + w_idx) * 2U; - pixel = *(byte_ptr + 1) << 24; - pixel |= *(byte_ptr) << 16; - pixel |= *(byte_ptr) << 8; - pixel |= *(byte_ptr); - *((uint32_t *)disp_buf) = pixel; + pixel = *(byte_ptr + 1) << 24; /* A */ + pixel |= *(byte_ptr) << 16; /* R */ + pixel |= *(byte_ptr) << 8; /* G */ + pixel |= *(byte_ptr); /* B */ + *((uint32_t *)disp_buf) = sys_cpu_to_le32(pixel); disp_buf += 4; } } } +/* + * Convert from Byte 0 Byte 1 Byte 2 Byte 3 + * 7......0 15.....8 23....16 31....24 + * PIXEL_FORMAT_RGB_565 gggBbbbb RrrrrGgg gggBbbbb RrrrrGgg + * into + * SDL_PIXELFORMAT_BGRA32 Bbbbbbbb Gggggggg Rrrrrrrr Ffffffff + */ static void sdl_display_write_rgb565(uint8_t *disp_buf, const struct display_buffer_descriptor *desc, const void *buf) { @@ -286,16 +318,23 @@ static void sdl_display_write_rgb565(uint8_t *disp_buf, for (w_idx = 0U; w_idx < desc->width; ++w_idx) { pix_ptr = (const uint16_t *)buf + ((h_idx * desc->pitch) + w_idx); - rgb565 = sys_be16_to_cpu(*pix_ptr); - pixel = (((rgb565 >> 11) & 0x1F) * 255 / 31) << 16; - pixel |= (((rgb565 >> 5) & 0x3F) * 255 / 63) << 8; - pixel |= (rgb565 & 0x1F) * 255 / 31; - *((uint32_t *)disp_buf) = pixel | 0xFF000000; + rgb565 = sys_le16_to_cpu(*pix_ptr); + pixel = (((rgb565 >> 11) & 0x1F) * 255 / 31) << 16; /* R */ + pixel |= (((rgb565 >> 5) & 0x3F) * 255 / 63) << 8; /* G */ + pixel |= (rgb565 & 0x1F) * 255 / 31; /* B */ + *((uint32_t *)disp_buf) = sys_cpu_to_le32(pixel | 0xFF000000); disp_buf += 4; } } } +/* + * Convert from Byte 0 Byte 1 Byte 2 Byte 3 + * 7......0 15.....8 23....16 31....24 + * PIXEL_FORMAT_RGB_565X RrrrrGgg gggBbbbb RrrrrGgg gggBbbbb + * into + * SDL_PIXELFORMAT_BGRA32 Bbbbbbbb Gggggggg Rrrrrrrr Ffffffff + */ static void sdl_display_write_rgb565x(uint8_t *disp_buf, const struct display_buffer_descriptor *desc, const void *buf) { @@ -303,6 +342,7 @@ static void sdl_display_write_rgb565x(uint8_t *disp_buf, uint32_t h_idx; uint32_t pixel; const uint16_t *pix_ptr; + uint16_t rgb565; __ASSERT((desc->pitch * 2U * desc->height) <= desc->buf_size, "Input buffer too small"); @@ -311,15 +351,27 @@ static void sdl_display_write_rgb565x(uint8_t *disp_buf, for (w_idx = 0U; w_idx < desc->width; ++w_idx) { pix_ptr = (const uint16_t *)buf + ((h_idx * desc->pitch) + w_idx); - pixel = (((*pix_ptr >> 11) & 0x1F) * 255 / 31) << 16; - pixel |= (((*pix_ptr >> 5) & 0x3F) * 255 / 63) << 8; - pixel |= (*pix_ptr & 0x1F) * 255 / 31; - *((uint32_t *)disp_buf) = pixel | 0xFF000000; + /* + * Perform be16_to_cpu here in order to swap it so that handling + * is same as for rgb565 + */ + rgb565 = sys_be16_to_cpu(*pix_ptr); + pixel = (((rgb565 >> 11) & 0x1F) * 255 / 31) << 16; /* R */ + pixel |= (((rgb565 >> 5) & 0x3F) * 255 / 63) << 8; /* G */ + pixel |= (rgb565 & 0x1F) * 255 / 31; /* B */ + *((uint32_t *)disp_buf) = sys_cpu_to_le32(pixel | 0xFF000000); disp_buf += 4; } } } +/* + * Convert from Byte 0 Byte 1 Byte 2 Byte 3 + * 7......0 15.....8 23....16 31....24 + * PIXEL_FORMAT_MONO(01/10) MMMMMMMM MMMMMMMM MMMMMMMM MMMMMMMM + * into + * SDL_PIXELFORMAT_BGRA32 Bbbbbbbb Gggggggg Rrrrrrrr Ffffffff + */ static void sdl_display_write_mono(uint8_t *disp_buf, const struct display_buffer_descriptor *desc, const void *buf, const bool one_is_black) { @@ -343,12 +395,22 @@ static void sdl_display_write_mono(uint8_t *disp_buf, const struct display_buffe pixel = !!(*byte_ptr & mono_pixel_order(w_idx % 8U)); } - *((uint32_t *)disp_buf) = (pixel ? pixel_on : ~pixel_on) | 0xFF000000; + *((uint32_t *)disp_buf) = + sys_cpu_to_le32((pixel ? pixel_on : ~pixel_on) | 0xFF000000); disp_buf += 4; } } } +/* + * Convert from Byte 0 Byte 1 Byte 2 Byte 3 + * 7......0 15.....8 23....16 31....24 + * PIXEL_FORMAT_L_8 Gggggggg Gggggggg Gggggggg Gggggggg + * into + * SDL_PIXELFORMAT_BGRA32 Bbbbbbbb Gggggggg Rrrrrrrr Ffffffff + * + * G value is applied to all R/G/B value for BGRA32 + */ static void sdl_display_write_l8(uint8_t *disp_buf, const struct display_buffer_descriptor *desc, const void *buf) { @@ -362,8 +424,10 @@ static void sdl_display_write_l8(uint8_t *disp_buf, const struct display_buffer_ for (h_idx = 0U; h_idx < desc->height; ++h_idx) { for (w_idx = 0U; w_idx < desc->width; ++w_idx) { byte_ptr = (const uint8_t *)buf + ((h_idx * desc->pitch) + w_idx); - pixel = *byte_ptr; - *((uint32_t *)disp_buf) = pixel | (pixel << 8) | (pixel << 16) | 0xFF000000; + pixel = *byte_ptr << 16; /* R */ + pixel |= *byte_ptr << 8; /* G */ + pixel |= *byte_ptr; /* B */ + *((uint32_t *)disp_buf) = sys_cpu_to_le32(pixel | 0xFF000000); disp_buf += 4; } } @@ -435,6 +499,15 @@ static int sdl_display_write(const struct device *dev, const uint16_t x, return 0; } +/* + * Convert from Byte 0 Byte 1 Byte 2 Byte 3 + * 7......0 15.....8 23....16 31....24 + * SDL_PIXELFORMAT_BGRA32 Bbbbbbbb Gggggggg Rrrrrrrr Aaaaaaaa + * into + * PIXEL_FORMAT_ARGB_8888 Bbbbbbbb Gggggggg Rrrrrrrr Aaaaaaaa + * + * Hence, simple copy is enough + */ static void sdl_display_read_argb8888(const uint8_t *read_buf, const struct display_buffer_descriptor *desc, void *buf) { @@ -443,6 +516,13 @@ static void sdl_display_read_argb8888(const uint8_t *read_buf, memcpy(buf, read_buf, desc->pitch * 4U * desc->height); } +/* + * Convert from Byte 0 Byte 1 Byte 2 Byte 3 + * 7......0 15.....8 23....16 31....24 + * SDL_PIXELFORMAT_BGRA32 Bbbbbbbb Gggggggg Rrrrrrrr Ffffffff + * into + * PIXEL_FORMAT_RGB_888 Bbbbbbbb Gggggggg Rrrrrrrr Bbbbbbbb + */ static void sdl_display_read_rgb888(const uint8_t *read_buf, const struct display_buffer_descriptor *desc, void *buf) { @@ -458,16 +538,24 @@ static void sdl_display_read_rgb888(const uint8_t *read_buf, for (w_idx = 0U; w_idx < desc->width; ++w_idx) { pix_ptr = (const uint32_t *)read_buf + ((h_idx * desc->pitch) + w_idx); - *buf8 = (*pix_ptr & 0xFF0000) >> 16; + pix_ptr = sys_le32_to_cpu(pix_ptr); + *buf8 = (*pix_ptr & 0xFF); /* B */ buf8 += 1; - *buf8 = (*pix_ptr & 0xFF00) >> 8; + *buf8 = (*pix_ptr & 0xFF00) >> 8; /* G */ buf8 += 1; - *buf8 = (*pix_ptr & 0xFF); + *buf8 = (*pix_ptr & 0xFF0000) >> 16; /* R */ buf8 += 1; } } } +/* + * Convert from Byte 0 Byte 1 Byte 2 Byte 3 + * 7......0 15.....8 23....16 31....24 + * SDL_PIXELFORMAT_BGRA32 Bbbbbbbb Gggggggg Rrrrrrrr Ffffffff + * into + * PIXEL_FORMAT_RGB_565 gggBbbbb RrrrrGgg gggBbbbb RrrrrGgg + */ static void sdl_display_read_rgb565(const uint8_t *read_buf, const struct display_buffer_descriptor *desc, void *buf) { @@ -484,15 +572,23 @@ static void sdl_display_read_rgb565(const uint8_t *read_buf, for (w_idx = 0U; w_idx < desc->width; ++w_idx) { pix_ptr = (const uint32_t *)read_buf + ((h_idx * desc->pitch) + w_idx); - pixel = (*pix_ptr & 0xF80000) >> 8; - pixel |= (*pix_ptr & 0x00FC00) >> 5; - pixel |= (*pix_ptr & 0x0000F8) >> 3; - *buf16 = sys_be16_to_cpu(pixel); + pix_ptr = sys_le32_to_cpu(pix_ptr); + pixel = (*pix_ptr & 0xF80000) >> 8; /* R */ + pixel |= (*pix_ptr & 0x00FC00) >> 5; /* G */ + pixel |= (*pix_ptr & 0x0000F8) >> 3; /* B */ + *buf16 = sys_le16_to_cpu(pixel); buf16 += 1; } } } +/* + * Convert from Byte 0 Byte 1 Byte 2 Byte 3 + * 7......0 15.....8 23....16 31....24 + * SDL_PIXELFORMAT_BGRA32 Bbbbbbbb Gggggggg Rrrrrrrr Ffffffff + * into + * PIXEL_FORMAT_RGB_565X RrrrrGgg gggBbbbb RrrrrGgg gggBbbbb + */ static void sdl_display_read_rgb565x(const uint8_t *read_buf, const struct display_buffer_descriptor *desc, void *buf) { @@ -509,15 +605,27 @@ static void sdl_display_read_rgb565x(const uint8_t *read_buf, for (w_idx = 0U; w_idx < desc->width; ++w_idx) { pix_ptr = (const uint32_t *)read_buf + ((h_idx * desc->pitch) + w_idx); - pixel = (*pix_ptr & 0xF80000) >> 8; - pixel |= (*pix_ptr & 0x00FC00) >> 5; - pixel |= (*pix_ptr & 0x0000F8) >> 3; - *buf16 = pixel; + pix_ptr = sys_le32_to_cpu(pix_ptr); + pixel = (*pix_ptr & 0xF80000) >> 8; /* R */ + pixel |= (*pix_ptr & 0x00FC00) >> 5; /* G */ + pixel |= (*pix_ptr & 0x0000F8) >> 3; /* B */ + /* + * Perform cpu_to_be16 here in order to swap it so that handling + * is same as for rgb565 + */ + *buf16 = sys_cpu_to_be16(pixel); buf16 += 1; } } } +/* + * Convert from Byte 0 Byte 1 Byte 2 Byte 3 + * 7......0 15.....8 23....16 31....24 + * SDL_PIXELFORMAT_BGRA32 Bbbbbbbb Gggggggg Rrrrrrrr Ffffffff + * into + * PIXEL_FORMAT_MONO(01/10) MMMMMMMM MMMMMMMM MMMMMMMM MMMMMMMM + */ static void sdl_display_read_mono(const uint8_t *read_buf, const struct display_buffer_descriptor *desc, void *buf, const bool one_is_black) @@ -534,6 +642,7 @@ static void sdl_display_read_mono(const uint8_t *read_buf, for (h_idx = 0U; h_idx < desc->height; ++h_idx) { for (w_idx = 0U; w_idx < desc->width; ++w_idx) { pix_ptr = (const uint32_t *)read_buf + h_idx * desc->pitch + w_idx; + pix_ptr = sys_cpu_to_le32(pix_ptr); buf8 = buf; if (IS_ENABLED(CONFIG_SDL_DISPLAY_MONO_VTILED)) { @@ -553,6 +662,15 @@ static void sdl_display_read_mono(const uint8_t *read_buf, } } +/* + * Convert from Byte 0 Byte 1 Byte 2 Byte 3 + * 7......0 15.....8 23....16 31....24 + * SDL_PIXELFORMAT_BGRA32 Bbbbbbbb Gggggggg Rrrrrrrr Ffffffff + * into + * PIXEL_FORMAT_L_8 Gggggggg Gggggggg Gggggggg Gggggggg + * + * G value is taken from the B component of SDL_PIXELFORMAT_BGRA32 + */ static void sdl_display_read_l8(const uint8_t *read_buf, const struct display_buffer_descriptor *desc, void *buf) { @@ -568,6 +686,7 @@ static void sdl_display_read_l8(const uint8_t *read_buf, for (w_idx = 0U; w_idx < desc->width; ++w_idx) { pix_ptr = (const uint32_t *)read_buf + ((h_idx * desc->pitch) + w_idx); + pix_ptr = sys_le32_to_cpu(pix_ptr); *buf8 = *pix_ptr & 0xFF; buf8 += 1; } @@ -589,6 +708,7 @@ static void sdl_display_read_al88(const uint8_t *read_buf, for (w_idx = 0U; w_idx < desc->width; ++w_idx) { pix_ptr = (const uint32_t *)read_buf + ((h_idx * desc->pitch) + w_idx); + pix_ptr = sys_le32_to_cpu(pix_ptr); *buf8 = (*pix_ptr & 0xFF); buf8 += 1; *buf8 = (*pix_ptr & 0xFF000000) >> 24; diff --git a/drivers/display/display_sdl_bottom.c b/drivers/display/display_sdl_bottom.c index e7c5ce3d3c92..f6f2f6f02e8b 100644 --- a/drivers/display/display_sdl_bottom.c +++ b/drivers/display/display_sdl_bottom.c @@ -103,7 +103,7 @@ int sdl_display_init_bottom(struct sdl_display_init_params *params) SDL_RenderSetLogicalSize(*params->renderer, params->width, params->height); *params->texture = - SDL_CreateTexture(*params->renderer, SDL_PIXELFORMAT_ARGB8888, + SDL_CreateTexture(*params->renderer, SDL_PIXELFORMAT_BGRA32, SDL_TEXTUREACCESS_STATIC, params->width, params->height); if (*params->texture == NULL) { nsi_print_warning("Failed to create SDL texture: %s", SDL_GetError()); @@ -112,7 +112,7 @@ int sdl_display_init_bottom(struct sdl_display_init_params *params) SDL_SetTextureBlendMode(*params->texture, SDL_BLENDMODE_BLEND); *params->read_texture = - SDL_CreateTexture(*params->renderer, SDL_PIXELFORMAT_ARGB8888, + SDL_CreateTexture(*params->renderer, SDL_PIXELFORMAT_BGRA32, SDL_TEXTUREACCESS_TARGET, params->width, params->height); if (*params->read_texture == NULL) { nsi_print_warning("Failed to create SDL texture for read: %s", SDL_GetError()); @@ -120,7 +120,7 @@ int sdl_display_init_bottom(struct sdl_display_init_params *params) } *params->background_texture = - SDL_CreateTexture(*params->renderer, SDL_PIXELFORMAT_ARGB8888, + SDL_CreateTexture(*params->renderer, SDL_PIXELFORMAT_BGRA32, SDL_TEXTUREACCESS_STREAMING, params->width, params->height); if (*params->background_texture == NULL) { nsi_print_warning("Failed to create SDL texture: %s", SDL_GetError()); @@ -234,7 +234,7 @@ int sdl_display_read_bottom(const struct sdl_display_read_params *params) SDL_RenderClear(params->renderer); SDL_RenderCopy(params->renderer, params->texture, NULL, NULL); - SDL_RenderReadPixels(params->renderer, &rect, SDL_PIXELFORMAT_ARGB8888, params->buf, + SDL_RenderReadPixels(params->renderer, &rect, SDL_PIXELFORMAT_BGRA32, params->buf, params->width * 4); SDL_SetTextureBlendMode(params->texture, SDL_BLENDMODE_BLEND); From 290b8e6748648684d97f56d8daceb626efb4e133 Mon Sep 17 00:00:00 2001 From: Alain Volmat Date: Fri, 16 Jan 2026 14:56:28 +0100 Subject: [PATCH 2077/3659] samples: display: use white background for ARGB_8888 Set the background color to 0xFF (white) in case of ARGB_8888 framebuffer format so that it is same for all formats except AL88 and MONO. Signed-off-by: Alain Volmat --- samples/drivers/display/src/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/drivers/display/src/main.c b/samples/drivers/display/src/main.c index 3cfdacf79035..e788c4533472 100644 --- a/samples/drivers/display/src/main.c +++ b/samples/drivers/display/src/main.c @@ -303,7 +303,7 @@ int main(void) switch (capabilities.current_pixel_format) { case PIXEL_FORMAT_ARGB_8888: - bg_color = 0x00u; + bg_color = 0xFFu; fill_buffer_fnc = fill_buffer_argb8888; buf_size *= 4; break; From 0d66cdd54bc2f3d057a05e6e789749761e72848e Mon Sep 17 00:00:00 2001 From: Yves Wang Date: Mon, 3 Nov 2025 18:28:08 +0800 Subject: [PATCH 2078/3659] dts: nxp: support watchdog on more nxp platforms Add ewm dts node for mimxrt1170. Enable ewm clock for frdm_mcxe247. Enable wdog for frdm_mcxe247 and frdm_ke15z. Signed-off-by: Yves Wang --- boards/nxp/frdm_ke15z/frdm_ke15z.dts | 7 ++++++- boards/nxp/frdm_ke15z/frdm_ke15z.yaml | 1 + boards/nxp/frdm_mcxe247/board.c | 3 +-- boards/nxp/frdm_mcxe247/frdm_mcxe247.dts | 4 ++++ boards/nxp/frdm_mcxe247/frdm_mcxe247.yaml | 1 + dts/arm/nxp/nxp_rt11xx.dtsi | 9 +++++++++ 6 files changed, 22 insertions(+), 3 deletions(-) diff --git a/boards/nxp/frdm_ke15z/frdm_ke15z.dts b/boards/nxp/frdm_ke15z/frdm_ke15z.dts index 2085cda99cd4..23d523ecab20 100644 --- a/boards/nxp/frdm_ke15z/frdm_ke15z.dts +++ b/boards/nxp/frdm_ke15z/frdm_ke15z.dts @@ -1,5 +1,5 @@ /* - * Copyright 2024 NXP + * Copyright 2024-2025 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -16,6 +16,7 @@ compatible = "nxp,ke15z", "nxp,mke15z7"; aliases { + watchdog0 = &wdog; led0 = &green_led; led1 = &blue_led; led2 = &red_led; @@ -117,3 +118,7 @@ &gpiod { status = "okay"; }; + +&wdog { + status = "okay"; +}; diff --git a/boards/nxp/frdm_ke15z/frdm_ke15z.yaml b/boards/nxp/frdm_ke15z/frdm_ke15z.yaml index c739f958a58c..faa24903d8d3 100644 --- a/boards/nxp/frdm_ke15z/frdm_ke15z.yaml +++ b/boards/nxp/frdm_ke15z/frdm_ke15z.yaml @@ -12,3 +12,4 @@ supported: - flash - gpio - uart + - watchdog diff --git a/boards/nxp/frdm_mcxe247/board.c b/boards/nxp/frdm_mcxe247/board.c index 939fa2b8e24c..179acb77ae83 100644 --- a/boards/nxp/frdm_mcxe247/board.c +++ b/boards/nxp/frdm_mcxe247/board.c @@ -267,8 +267,7 @@ __weak void clock_init(void) DT_CLOCKS_CELL(DT_NODELABEL(ftm7), ip_source)); #endif #if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(ewm0)) - CLOCK_SetIpSrc(kCLOCK_Ewm0, - DT_CLOCKS_CELL(DT_NODELABEL(ewm0), ip_source)); + CLOCK_EnableClock(kCLOCK_Ewm0); #endif #if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(flexio0)) CLOCK_SetIpSrc(kCLOCK_Flexio0, diff --git a/boards/nxp/frdm_mcxe247/frdm_mcxe247.dts b/boards/nxp/frdm_mcxe247/frdm_mcxe247.dts index c499e331ba1d..aaba060b124a 100644 --- a/boards/nxp/frdm_mcxe247/frdm_mcxe247.dts +++ b/boards/nxp/frdm_mcxe247/frdm_mcxe247.dts @@ -267,3 +267,7 @@ &crc { status = "okay"; }; + +&wdog { + status = "okay"; +}; diff --git a/boards/nxp/frdm_mcxe247/frdm_mcxe247.yaml b/boards/nxp/frdm_mcxe247/frdm_mcxe247.yaml index bae8bf5bfedf..108f121b728c 100644 --- a/boards/nxp/frdm_mcxe247/frdm_mcxe247.yaml +++ b/boards/nxp/frdm_mcxe247/frdm_mcxe247.yaml @@ -24,4 +24,5 @@ supported: - arduino_gpio - comparator - dma + - watchdog vendor: nxp diff --git a/dts/arm/nxp/nxp_rt11xx.dtsi b/dts/arm/nxp/nxp_rt11xx.dtsi index 9a05c425eabb..c962666e6c97 100644 --- a/dts/arm/nxp/nxp_rt11xx.dtsi +++ b/dts/arm/nxp/nxp_rt11xx.dtsi @@ -57,6 +57,15 @@ }; soc { + ewm0: ewm@4002c000 { + compatible = "nxp,ewm"; + reg = <0x4002c000 0x6>; + interrupts = <114 0>; + clk-divider = <0>; + clk-sel = "lpo_clk[2]"; + status = "disabled"; + }; + dac: dac@40064000 { compatible = "nxp,dac12"; reg = <0x40064000 0x4000>; From 92142744644ed00a346a41928621325a38430a89 Mon Sep 17 00:00:00 2001 From: Yves Wang Date: Mon, 3 Nov 2025 18:29:33 +0800 Subject: [PATCH 2079/3659] tests: watchdog: Enable watchdog reset none for more nxp socs Enable reset_none_ewm for frdm_ke15z, frdm_mcxe247 and mimxrt1170. Signed-off-by: Yves Wang --- ..._ke1xz.overlay => app_ewm_no_wdog.overlay} | 0 .../boards/nxp_rt11xx.overlay | 15 ++++++++++++++ .../wdt_basic_reset_none/testcase.yaml | 20 +++++++++++++++++-- 3 files changed, 33 insertions(+), 2 deletions(-) rename tests/drivers/watchdog/wdt_basic_reset_none/boards/{frdm_ke1xz.overlay => app_ewm_no_wdog.overlay} (100%) create mode 100644 tests/drivers/watchdog/wdt_basic_reset_none/boards/nxp_rt11xx.overlay diff --git a/tests/drivers/watchdog/wdt_basic_reset_none/boards/frdm_ke1xz.overlay b/tests/drivers/watchdog/wdt_basic_reset_none/boards/app_ewm_no_wdog.overlay similarity index 100% rename from tests/drivers/watchdog/wdt_basic_reset_none/boards/frdm_ke1xz.overlay rename to tests/drivers/watchdog/wdt_basic_reset_none/boards/app_ewm_no_wdog.overlay diff --git a/tests/drivers/watchdog/wdt_basic_reset_none/boards/nxp_rt11xx.overlay b/tests/drivers/watchdog/wdt_basic_reset_none/boards/nxp_rt11xx.overlay new file mode 100644 index 000000000000..d5215a9c7a8a --- /dev/null +++ b/tests/drivers/watchdog/wdt_basic_reset_none/boards/nxp_rt11xx.overlay @@ -0,0 +1,15 @@ +/* + * Copyright 2025 NXP + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + watchdog0 = &ewm0; + }; +}; + +&ewm0 { + status = "okay"; + clk-divider = <3>; +}; diff --git a/tests/drivers/watchdog/wdt_basic_reset_none/testcase.yaml b/tests/drivers/watchdog/wdt_basic_reset_none/testcase.yaml index 57b8ad8b17f5..b0be8c9bdb6d 100644 --- a/tests/drivers/watchdog/wdt_basic_reset_none/testcase.yaml +++ b/tests/drivers/watchdog/wdt_basic_reset_none/testcase.yaml @@ -33,15 +33,31 @@ tests: extra_configs: - CONFIG_TEST_WDT_MAX_WINDOW_TIME=254 - CONFIG_TEST_WDT_SLEEP_TIME=68 - drivers.watchdog.reset_none_ewm_ke1xz: + drivers.watchdog.reset_none_ewm_no_wdog: filter: dt_compat_enabled("nxp,ewm") platform_allow: + - frdm_ke15z - frdm_ke17z + - frdm_mcxe247 integration_platforms: - frdm_ke17z + - frdm_mcxe247 extra_args: - EXTRA_CONF_FILE="app_ewm.conf" - - DTC_OVERLAY_FILE="boards/frdm_ke1xz.overlay" + - DTC_OVERLAY_FILE="boards/app_ewm_no_wdog.overlay" + extra_configs: + - CONFIG_TEST_WDT_MAX_WINDOW_TIME=254 + - CONFIG_TEST_WDT_SLEEP_TIME=68 + drivers.watchdog.reset_none_ewm_11xx: + filter: dt_compat_enabled("nxp,ewm") + platform_allow: + - mimxrt1170_evk@A/mimxrt1176/cm7 + - mimxrt1170_evk@B/mimxrt1176/cm7 + integration_platforms: + - mimxrt1170_evk@A/mimxrt1176/cm7 + extra_args: + - EXTRA_CONF_FILE="app_ewm.conf" + - DTC_OVERLAY_FILE="boards/nxp_rt11xx.overlay" extra_configs: - CONFIG_TEST_WDT_MAX_WINDOW_TIME=254 - CONFIG_TEST_WDT_SLEEP_TIME=68 From b93fabaf25ef34fdb2f8d40d28e7337c40d14651 Mon Sep 17 00:00:00 2001 From: Alessandro Manganaro Date: Thu, 15 Jan 2026 11:24:33 +0100 Subject: [PATCH 2080/3659] drivers: timers: stm32: improving lptim configuration sequence Moving the reset of ltpim hw ip at the beginning of sys_clock_driver_init to improve the reliability of lptim hw configuration sequence. Signed-off-by: Alessandro Manganaro --- drivers/timer/stm32_lptim_timer.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/timer/stm32_lptim_timer.c b/drivers/timer/stm32_lptim_timer.c index 86994fa9a952..625b2cc59843 100644 --- a/drivers/timer/stm32_lptim_timer.c +++ b/drivers/timer/stm32_lptim_timer.c @@ -525,6 +525,9 @@ static int sys_clock_driver_init(void) return -ENODEV; } + /* Reset timer to default state using RCC */ + (void)reset_line_toggle_dt(&lptim_reset); + /* Enable LPTIM bus clock */ err = clock_control_on(clk_ctrl, (clock_control_subsys_t) &lptim_clk[0]); if (err < 0) { @@ -562,9 +565,6 @@ static int sys_clock_driver_init(void) } #endif - /* Reset timer to default state using RCC */ - (void)reset_line_toggle_dt(&lptim_reset); - #if DT_PROP(DT_NODELABEL(stm32_lp_tick_source), st_timeout) uint32_t timeout = DT_PROP(DT_NODELABEL(stm32_lp_tick_source), st_timeout); From 68b86a15a19b614786c72745b8de16a0491be0e7 Mon Sep 17 00:00:00 2001 From: Ashirwad Paswan Date: Tue, 25 Nov 2025 11:02:04 +0530 Subject: [PATCH 2081/3659] dma: rpi_pico: fix transfer count calculation The Pico SDK expects a transfer count (items), not a byte count. The driver incorrectly passed the byte size, causing buffer overflows on 16-bit and 32-bit transfers.Fix this by storing the transfer width in the channel configuration and dividing the block size by that width to calculate the correct transfer count. Fixes #99435 Signed-off-by: Ashirwad Paswan --- drivers/dma/dma_rpi_pico.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/dma/dma_rpi_pico.c b/drivers/dma/dma_rpi_pico.c index 8c458129ff98..e3e7caccbde0 100644 --- a/drivers/dma/dma_rpi_pico.c +++ b/drivers/dma/dma_rpi_pico.c @@ -43,6 +43,7 @@ struct dma_rpi_pico_channel { void *source_address; void *dest_address; size_t block_size; + uint32_t source_data_size; }; struct dma_rpi_pico_data { @@ -197,6 +198,7 @@ static int dma_rpi_pico_config(const struct device *dev, uint32_t channel, data->channels[channel].callback = dma_cfg->dma_callback; data->channels[channel].user_data = dma_cfg->user_data; + data->channels[channel].source_data_size = dma_cfg->source_data_size; data->channels[channel].direction = dma_cfg->channel_direction; return 0; @@ -221,7 +223,8 @@ static int dma_rpi_pico_reload(const struct device *dev, uint32_t ch, uint32_t s data->channels[ch].dest_address = (void *)dst; data->channels[ch].block_size = size; dma_channel_configure(ch, &data->channels[ch].config, data->channels[ch].dest_address, - data->channels[ch].source_address, data->channels[ch].block_size, + data->channels[ch].source_address, + data->channels[ch].block_size / data->channels[ch].source_data_size, true); return 0; @@ -241,7 +244,8 @@ static int dma_rpi_pico_start(const struct device *dev, uint32_t ch) dma_irqn_set_channel_enabled(dma_rpi_pico_channel_irq(dev, ch), ch, true); dma_channel_configure(ch, &data->channels[ch].config, data->channels[ch].dest_address, - data->channels[ch].source_address, data->channels[ch].block_size, + data->channels[ch].source_address, + data->channels[ch].block_size / data->channels[ch].source_data_size, true); return 0; From 8d677b2c29178d228acca01696911b6a6e36c8ae Mon Sep 17 00:00:00 2001 From: Guillaume Gautier Date: Mon, 12 Jan 2026 17:13:37 +0100 Subject: [PATCH 2082/3659] drivers: clock: use concat instead of ## Use CONCAT macro instead of ## to create the PLL division macro. Signed-off-by: Guillaume Gautier --- drivers/clock_control/clock_stm32_ll_common.h | 84 ++++++------------- 1 file changed, 24 insertions(+), 60 deletions(-) diff --git a/drivers/clock_control/clock_stm32_ll_common.h b/drivers/clock_control/clock_stm32_ll_common.h index 86b1445fe1e7..927309425e8b 100644 --- a/drivers/clock_control/clock_stm32_ll_common.h +++ b/drivers/clock_control/clock_stm32_ll_common.h @@ -11,82 +11,46 @@ #include #include +#include #include /* Macros to fill up multiplication and division factors values */ -#define z_pllm(v) LL_RCC_PLLM_DIV_ ## v -#define pllm(v) z_pllm(v) - -#define z_pllp(v) LL_RCC_PLLP_DIV_ ## v -#define pllp(v) z_pllp(v) - -#define z_pllq(v) LL_RCC_PLLQ_DIV_ ## v -#define pllq(v) z_pllq(v) - -#define z_pllr(v) LL_RCC_PLLR_DIV_ ## v -#define pllr(v) z_pllr(v) +#define pllm(v) CONCAT(LL_RCC_PLLM_DIV_, v) +#define pllp(v) CONCAT(LL_RCC_PLLP_DIV_, v) +#define pllq(v) CONCAT(LL_RCC_PLLQ_DIV_, v) +#define pllr(v) CONCAT(LL_RCC_PLLR_DIV_, v) #if defined(RCC_PLLI2SCFGR_PLLI2SM) /* Some stm32F4 devices have a dedicated PLL I2S with M divider */ -#define z_plli2s_m(v) LL_RCC_PLLI2SM_DIV_ ## v +#define plli2sm(v) CONCAT(LL_RCC_PLLI2SM_DIV_, v) #else /* Some stm32F4 devices (typ. stm32F401) have a dedicated PLL I2S with PLL M divider */ -#define z_plli2s_m(v) LL_RCC_PLLM_DIV_ ## v +#define plli2sm(v) CONCAT(LL_RCC_PLLM_DIV_, v) #endif /* RCC_PLLI2SCFGR_PLLI2SM */ -#define plli2sm(v) z_plli2s_m(v) - -#define z_plli2s_q(v) LL_RCC_PLLI2SQ_DIV_ ## v -#define plli2sq(v) z_plli2s_q(v) - -#define z_plli2s_r(v) LL_RCC_PLLI2SR_DIV_ ## v -#define plli2sr(v) z_plli2s_r(v) - -#define z_pllsai_m(v) LL_RCC_PLLM_DIV_ ## v -#define pllsaim(v) z_pllsai_m(v) - -#define z_pllsai_p(v) LL_RCC_PLLSAIP_DIV_ ## v -#define pllsaip(v) z_pllsai_p(v) - -#define z_pllsai_q(v) LL_RCC_PLLSAIQ_DIV_ ## v -#define pllsaiq(v) z_pllsai_q(v) +#define plli2sq(v) CONCAT(LL_RCC_PLLI2SQ_DIV_, v) +#define plli2sr(v) CONCAT(LL_RCC_PLLI2SR_DIV_, v) -#define z_pllsai_divq(v) LL_RCC_PLLSAIDIVQ_DIV_ ## v -#define pllsaidivq(v) z_pllsai_divq(v) +#define pllsaim(v) CONCAT(LL_RCC_PLLM_DIV_, v) +#define pllsaip(v) CONCAT(LL_RCC_PLLSAIP_DIV_, v) +#define pllsaiq(v) CONCAT(LL_RCC_PLLSAIQ_DIV_, v) +#define pllsaidivq(v) CONCAT(LL_RCC_PLLSAIDIVQ_DIV_, v) +#define pllsair(v) CONCAT(LL_RCC_PLLSAIR_DIV_, v) +#define pllsaidivr(v) CONCAT(LL_RCC_PLLSAIDIVR_DIV_, v) -#define z_pllsai_r(v) LL_RCC_PLLSAIR_DIV_ ## v -#define pllsair(v) z_pllsai_r(v) - -#define z_pllsai_divr(v) LL_RCC_PLLSAIDIVR_DIV_ ## v -#define pllsaidivr(v) z_pllsai_divr(v) - -#define z_pllsai1_p(v) LL_RCC_PLLSAI1P_DIV_ ## v -#define pllsai1p(v) z_pllsai1_p(v) - -#define z_pllsai1_q(v) LL_RCC_PLLSAI1Q_DIV_ ## v -#define pllsai1q(v) z_pllsai1_q(v) - -#define z_pllsai1_r(v) LL_RCC_PLLSAI1R_DIV_ ## v -#define pllsai1r(v) z_pllsai1_r(v) +#define pllsai1p(v) CONCAT(LL_RCC_PLLSAI1P_DIV_, v) +#define pllsai1q(v) CONCAT(LL_RCC_PLLSAI1Q_DIV_, v) +#define pllsai1r(v) CONCAT(LL_RCC_PLLSAI1R_DIV_, v) #if defined(RCC_PLLSAI2M_DIV_1_16_SUPPORT) -#define z_pllsai2_m(v) LL_RCC_PLLSAI2M_DIV_ ## v +#define pllsai2m(v) CONCAT(LL_RCC_PLLSAI2M_DIV_, v) #else -#define z_pllsai2_m(v) LL_RCC_PLLM_DIV_ ## v +#define pllsai2m(v) CONCAT(LL_RCC_PLLM_DIV_, v) #endif -#define pllsai2m(v) z_pllsai2_m(v) - -#define z_pllsai2_p(v) LL_RCC_PLLSAI2P_DIV_ ## v -#define pllsai2p(v) z_pllsai2_p(v) - -#define z_pllsai2_q(v) LL_RCC_PLLSAI2Q_DIV_ ## v -#define pllsai2q(v) z_pllsai2_q(v) - -#define z_pllsai2_r(v) LL_RCC_PLLSAI2R_DIV_ ## v -#define pllsai2r(v) z_pllsai2_r(v) - -#define z_pllsai2_divr(v) LL_RCC_PLLSAI2DIVR_DIV_ ## v -#define pllsai2divr(v) z_pllsai2_divr(v) +#define pllsai2p(v) CONCAT(LL_RCC_PLLSAI2P_DIV_, v) +#define pllsai2q(v) CONCAT(LL_RCC_PLLSAI2Q_DIV_, v) +#define pllsai2r(v) CONCAT(LL_RCC_PLLSAI2R_DIV_, v) +#define pllsai2divr(v) CONCAT(LL_RCC_PLLSAI2DIVR_DIV_, v) #ifdef __cplusplus extern "C" { From d985cfa9f50f9b27be375119a78ef654c0b4b871 Mon Sep 17 00:00:00 2001 From: Guillaume Gautier Date: Tue, 9 Dec 2025 15:29:03 +0100 Subject: [PATCH 2083/3659] dts: bindings: clock: st: use a single binding for stm32f2, f4 and f7 PLLs STM32F2, F4 and F7 have up to 3 PLLs: PLL, PLLI2S and PLLSAI. These PLLs are very similar, the principal differences are which outputs are available for which PLL of each SoC. Instead of having a large number of files to describe all the possible very similar variants, use one single binding to rule them all. Signed-off-by: Guillaume Gautier --- dts/bindings/clock/st,stm32f2-pll-clock.yaml | 60 --------- dts/bindings/clock/st,stm32f4-pll-clock.yaml | 70 ---------- .../clock/st,stm32f4-plli2s-clock.yaml | 42 ------ .../clock/st,stm32f411-plli2s-clock.yaml | 46 ------- dts/bindings/clock/st,stm32f7-pll-clock.yaml | 58 --------- dts/bindings/clock/st,stm32fx-pll-clock.yaml | 120 ++++++++++++++++++ .../clock/st,stm32fx-pllsai-clock.yaml | 92 -------------- 7 files changed, 120 insertions(+), 368 deletions(-) delete mode 100644 dts/bindings/clock/st,stm32f2-pll-clock.yaml delete mode 100644 dts/bindings/clock/st,stm32f4-pll-clock.yaml delete mode 100644 dts/bindings/clock/st,stm32f4-plli2s-clock.yaml delete mode 100644 dts/bindings/clock/st,stm32f411-plli2s-clock.yaml delete mode 100644 dts/bindings/clock/st,stm32f7-pll-clock.yaml create mode 100644 dts/bindings/clock/st,stm32fx-pll-clock.yaml delete mode 100644 dts/bindings/clock/st,stm32fx-pllsai-clock.yaml diff --git a/dts/bindings/clock/st,stm32f2-pll-clock.yaml b/dts/bindings/clock/st,stm32f2-pll-clock.yaml deleted file mode 100644 index 917b64768b80..000000000000 --- a/dts/bindings/clock/st,stm32f2-pll-clock.yaml +++ /dev/null @@ -1,60 +0,0 @@ -# Copyright (c) 2021, Linaro ltd -# SPDX-License-Identifier: Apache-2.0 - -description: | - STM32F2 Main PLL. - - Takes one of clk_hse or clk_hsi as input clock. - - Up to 2 output clocks could be supported and for each output clock, the - frequency can be computed with the following formula: - - f(PLL_P) = f(VCO clock) / PLLP --> PLLCLK (System Clock) - f(PLL_Q) = f(VCO clock) / PLLQ --> PLL48CLK (Optional) - - with f(VCO clock) = f(PLL clock input) × (PLLN / PLLM) - - The PLL output frequency must not exceed 168 MHz. - - -compatible: "st,stm32f2-pll-clock" - -include: [clock-controller.yaml, base.yaml] - -properties: - "#clock-cells": - const: 0 - - clocks: - required: true - - div-m: - type: int - required: true - description: | - Division factor for the PLL input clock - Valid range: 2 - 63 - - mul-n: - type: int - required: true - description: | - PLL multiplication factor for VCO - Valid range: 192 - 432 - - div-p: - type: int - required: true - description: | - PLL division factor for PLLCLK - enum: - - 2 - - 4 - - 6 - - 8 - - div-q: - type: int - description: | - PLL division factor for PLL48CK - Valid range: 2 - 15 diff --git a/dts/bindings/clock/st,stm32f4-pll-clock.yaml b/dts/bindings/clock/st,stm32f4-pll-clock.yaml deleted file mode 100644 index 81ccb5182da4..000000000000 --- a/dts/bindings/clock/st,stm32f4-pll-clock.yaml +++ /dev/null @@ -1,70 +0,0 @@ -# Copyright (c) 2021, Linaro ltd -# SPDX-License-Identifier: Apache-2.0 - -description: | - STM32F4 Main PLL. - - Takes one of clk_hse or clk_hsi as input clock, with an - input frequency from 1 to 2 MHz. PLLM factor is used to set the input clock - in this acceptable range. - - Up to 2 output clocks could be supported and for each output clock, the - frequency can be computed with the following formula: - - f(PLL_P) = f(VCO clock) / PLLP --> PLLCLK (System Clock) - f(PLL_Q) = f(VCO clock) / PLLQ --> PLL48CLK (Optional) - - with f(VCO clock) = f(PLL clock input) × (PLLN / PLLM) - - The PLL output frequency must not exceed 80 MHz. - - -compatible: "st,stm32f4-pll-clock" - -include: [clock-controller.yaml, base.yaml] - -properties: - "#clock-cells": - const: 0 - - clocks: - required: true - - div-m: - type: int - required: true - description: | - Division factor for the PLL input clock - Valid range: 2 - 63 - - mul-n: - type: int - required: true - description: | - Main PLL multiplication factor for VCO - Valid range: 50 - 432 - - div-p: - type: int - required: true - description: | - Main PLL division factor for PLLSAI2CLK - enum: - - 2 - - 4 - - 6 - - 8 - - div-q: - type: int - description: | - Main PLL (PLL) division factor for USB OTG FS, SDMMC and random number - generator clocks. - Valid range: 2 - 15 - - div-r: - type: int - description: | - Main PLL (PLL) division factor for I2S and DFSDM - generator clocks. - Valid range: 2 - 7 diff --git a/dts/bindings/clock/st,stm32f4-plli2s-clock.yaml b/dts/bindings/clock/st,stm32f4-plli2s-clock.yaml deleted file mode 100644 index aff08c757884..000000000000 --- a/dts/bindings/clock/st,stm32f4-plli2s-clock.yaml +++ /dev/null @@ -1,42 +0,0 @@ -# Copyright (c) 2023, Linaro ltd -# SPDX-License-Identifier: Apache-2.0 - -description: | - STM32F4 PLL I2S. - - Takes same input as Main PLL. PLLM factor and PLL source are common with Main PLL - - 1 output clocks supported, the frequency can be computed with the following formula: - - f(PLL_R) = f(VCO clock) / PLLR --> PLLI2S - - with f(VCO clock) = f(PLL clock input) × (PLLNI2S / PLLM) - - -compatible: "st,stm32f4-plli2s-clock" - -include: [clock-controller.yaml, base.yaml] - -properties: - "#clock-cells": - const: 0 - - mul-n: - type: int - required: true - description: | - PLLI2S multiplication factor for VCO - Valid range may vary between parts: 50 - 432 , 192 - 432 - - div-r: - type: int - required: true - description: | - PLLI2S division factor for I2S Clocks - enum: - - 2 - - 3 - - 4 - - 5 - - 6 - - 7 diff --git a/dts/bindings/clock/st,stm32f411-plli2s-clock.yaml b/dts/bindings/clock/st,stm32f411-plli2s-clock.yaml deleted file mode 100644 index ed9b235d3275..000000000000 --- a/dts/bindings/clock/st,stm32f411-plli2s-clock.yaml +++ /dev/null @@ -1,46 +0,0 @@ -# Copyright (c) 2023, Linaro ltd -# SPDX-License-Identifier: Apache-2.0 - -description: | - STM32F411 PLL I2S. - - Fully configurable I2S dedicated PLL. - - 1 output clocks supported, the frequency can be computed with the following formula: - - f(PLLI2S_R) = f(VCO clock) / PLLI2S R --> PLLI2S - - with f(VCO clock) = f(PLL I2S clock input) × (PLLI2S N / PLLI2S M) - - -compatible: "st,stm32f411-plli2s-clock" - -include: st,stm32f4-plli2s-clock.yaml - -properties: - div-m: - type: int - required: true - description: | - Division factor for the PLL input clock - Valid range: 2 - 63 - - div-q: - type: int - description: | - PLLI2S division factor for I2S Clocks to supply USB/SDIO/RNG - enum: - - 2 - - 3 - - 4 - - 5 - - 6 - - 7 - - 8 - - 9 - - 10 - - 11 - - 12 - - 13 - - 14 - - 15 diff --git a/dts/bindings/clock/st,stm32f7-pll-clock.yaml b/dts/bindings/clock/st,stm32f7-pll-clock.yaml deleted file mode 100644 index fc1a29fca297..000000000000 --- a/dts/bindings/clock/st,stm32f7-pll-clock.yaml +++ /dev/null @@ -1,58 +0,0 @@ -# Copyright (c) 2021, Linaro ltd -# SPDX-License-Identifier: Apache-2.0 - -description: | - STM32F7 Main PLL. - - Takes one of clk_hse or clk_hsi as input clock. - - Up to 2 output clocks could be supported and for each output clock, the - frequency can be computed with the following formula: - - f(PLL_P) = f(VCO clock) / PLLP --> PLLCLK (System Clock) - f(PLL_Q) = f(VCO clock) / PLLQ --> PLL48CLK (Optional) - - with f(VCO clock) = f(PLL clock input) × (PLLN / PLLM) - - -compatible: "st,stm32f7-pll-clock" - -include: [clock-controller.yaml, base.yaml] - -properties: - "#clock-cells": - const: 0 - - clocks: - required: true - - div-m: - type: int - required: true - description: | - Division factor for the PLL input clock - Valid range: 2 - 63 - - mul-n: - type: int - required: true - description: | - PLL multiplication factor for VCO - Valid range: 50 - 432 - - div-p: - type: int - required: true - description: | - PLL division factor for PLLCLK - enum: - - 2 - - 4 - - 6 - - 8 - - div-q: - type: int - description: | - PLL division factor for PLL48CK - Valid range: 2 - 15 diff --git a/dts/bindings/clock/st,stm32fx-pll-clock.yaml b/dts/bindings/clock/st,stm32fx-pll-clock.yaml new file mode 100644 index 000000000000..473f28e6398d --- /dev/null +++ b/dts/bindings/clock/st,stm32fx-pll-clock.yaml @@ -0,0 +1,120 @@ +# Copyright (c) 2025, STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +description: | + PLL node binding for STM32F2, STM32F4 and STM32F7 device + + This binding can be used to describe any PLL present on these SoCs: + - PLL + - PLLI2S + - PLLSAI + + Takes one of clk_hse or clk_hsi as input clock. + + The PLL can have up to 3 output clocks and for each output clock, the + frequency can be computed with the following formulae: + + f(PLL_P) = f(VCO clock) / PLLP + f(PLL_Q) = f(VCO clock) / PLLQ + f(PLL_R) = f(VCO clock) / PLLR + + with f(VCO clock) = f(PLL clock input) × (PLLN / PLLM) + + An additional divisor is available on some SoCs for the Q and R outputs. + + The PLL clock input is shared between PLLs (PLL / PLLI2S / PLLSAI) of the + SoC hence all PLLs must have the same source set. + +compatible: "st,stm32fx-pll-clock" + +include: [clock-controller.yaml, base.yaml] + +properties: + "#clock-cells": + const: 0 + + clocks: + required: true + + div-m: + type: int + required: true + description: | + Division factor for the PLL input clock. + On STM32F411, F412, F413, F423 and F446, the division M + factor is independent from other PLLs. + On all other SoCs, the division factor M is shared between + PLL, PLLSAI and PLLI2S, hence same value must be used + for those PLLs when used together. + Valid range: 2 - 63 + + mul-n: + type: int + required: true + description: | + Multiplication factor for VCO. + Valid range: + - 192 - 432 for STM32F2x and STM32F401 + - 50 - 432 for other STM32F4x and for STM32F7x + + div-p: + type: int + description: | + Division factor for PLL_P. + Available on all SoCs for main PLL. + Available only on STM32F446 and on STM32F74x and higher for PLLI2S. + Available only on STM32F446, F469, F479 and on all STM32F7x for PLLSAI. + enum: + - 2 + - 4 + - 6 + - 8 + + div-q: + type: int + description: | + Division factor for PLL_Q + Available on all SoCs for main PLL. + Available only on STM32F412, F413, F423, F427, F429, F437, F439, F446, F469, F479 + and on all STM32F7x for PLLI2S. + Available only on STM32F427, F429, F437, F439, F446, F469, F479 + and on all STM32F7x for PLLSAI. + Valid range: 2 - 15 + + post-div-q: + type: int + description: | + Division factor after PLL_Q. + Available only on STM32F427, F429, F437, F439, F446, F469, F479 + and on all STM32F7x for PLLI2S. + Available only on STM32F427, F429, F437, F439, F446, F469, F479 + and on all STM32F7x for PLLSAI. + If the div-q property is used and this property is applicable for the SoC, then it is + required to define it. + Valid range: 1 - 32 + + div-r: + type: int + description: | + Division factor for PLL_R. + Available only on STM32F410, F412, F413, F423, F446, F469, F479, F769 and F779 for main PLL. + Available on all SoCs except STM32F410 for PLLI2S. + Available only on STM32F427, F429, F437, F439, F469, F479 + and on STM32F74x and higher for PLLSAI. + Valid range: 2 - 7 + + post-div-r: + type: int + description: | + Division factor after PLL_R. + Available only on STM32F413 and F423 for main PLL. + Available only on STM32F413 and F423 for PLLI2S. + Available only on STM32F427, F429, F437, F439, F469, F479 + and on STM32F74x and higher for PLLSAI. + If the div-r property is used and this property is applicable for the SoC, then it is + required to define it. + enum: + - 2 + - 4 + - 8 + - 16 diff --git a/dts/bindings/clock/st,stm32fx-pllsai-clock.yaml b/dts/bindings/clock/st,stm32fx-pllsai-clock.yaml deleted file mode 100644 index 6081471864b3..000000000000 --- a/dts/bindings/clock/st,stm32fx-pllsai-clock.yaml +++ /dev/null @@ -1,92 +0,0 @@ -# Copyright (c) 2025, STMicroelectronics -# SPDX-License-Identifier: Apache-2.0 - -description: | - PLLSAI node binding for STM32F4 and STM32F7 device - - Takes one of clk_hse or clk_hsi as input clock. - - The PLL can have up to 3 output clocks and for each output clock, the - frequency can be computed with the following formulae: - - f(PLLSAI_P) = f(VCO clock) / PLLSAIP - f(PLLSAI_Q) = f(VCO clock) / PLLSAIQ - f(PLLSAI_R) = f(VCO clock) / PLLSAIR - - with f(VCO clock) = f(PLL clock input) × (PLLSAIN / PLLSAIM) - - The PLL clock input is shared with other PLLs (PLL / PLLI2S) of the - SoC hence all PLLs must have the same source set. - -compatible: "st,stm32fx-pllsai-clock" - -include: [clock-controller.yaml, base.yaml] - -properties: - "#clock-cells": - const: 0 - - clocks: - required: true - - div-m: - type: int - required: true - description: | - Division factor for PLLSAI input clock. - On STM32F446xx, the division M factor is independent from - other PLLs. - On all other SoCs, the division factor M is shared between - PLL, PLLSAI and PLLI2S, hence same value should be used - for those PLLs when used together. - Valid range: 2 - 63 - - mul-n: - type: int - required: true - description: | - Multiplication factor for VCO. - Valid range: 50 - 432 - - div-p: - type: int - description: | - Division factor for PLLSAI_P. - Only available on STM32F446/STM32F469/STM32F479 and STM32F7 series. - enum: - - 2 - - 4 - - 6 - - 8 - - div-q: - type: int - description: | - Division factor for PLLSAI_Q - Valid range: 2 - 15 - - div-divq: - type: int - description: | - Division factor after PLLSAI_Q for the SAI1 clock. - Valid range: 1 - 32 - - div-r: - type: int - description: | - Division factor for PLLSAI_R. - Only available on STM32F42x / STM32F43x / STM32F469 / STM32F479 - and on STM32F74x and higher. - Valid range: 2 - 7 - - div-divr: - type: int - description: | - Division factor after PLLSAI_R for the LTDC pixel clock. - Only available on STM32F42x / STM32F43x / STM32F469 / STM32F479 - and on STM32F74x and higher. - enum: - - 2 - - 4 - - 8 - - 16 From 97cc7adf256d662952b5e903f008b1494008db72 Mon Sep 17 00:00:00 2001 From: Guillaume Gautier Date: Tue, 9 Dec 2025 15:34:08 +0100 Subject: [PATCH 2084/3659] dts: arm: st: update stm32f2, f4 and f7 pll compatibles For all STM32F2, F4 and F7, use the new binding instead of the various ones previously defined. For F411 and F446, this removes the need to define the PLLI2S since it is already included in F401. For F7, this commit also adds the PLLI2S that was missing. Also update post-div-x properties for some boards and overlays. Signed-off-by: Guillaume Gautier --- .../boards/stm32f769i_disco.overlay | 2 +- boards/st/stm32f429i_disc1/stm32f429i_disc1.dts | 2 +- boards/st/stm32f469i_disco/stm32f469i_disco.dts | 2 +- boards/st/stm32f746g_disco/stm32f746g_disco.dts | 2 +- boards/st/stm32f7508_dk/stm32f7508_dk.dts | 2 +- dts/arm/st/f2/stm32f2.dtsi | 2 +- dts/arm/st/f4/stm32f4.dtsi | 2 +- dts/arm/st/f4/stm32f401.dtsi | 2 +- dts/arm/st/f4/stm32f411.dtsi | 8 -------- dts/arm/st/f4/stm32f412.dtsi | 2 +- dts/arm/st/f4/stm32f427.dtsi | 2 +- dts/arm/st/f4/stm32f446.dtsi | 6 +----- dts/arm/st/f7/stm32f7.dtsi | 10 ++++++++-- .../drivers/i2s/output/boards/nucleo_f429zi.overlay | 2 +- .../drivers/i2s/output/boards/nucleo_f767zi.overlay | 2 +- 15 files changed, 21 insertions(+), 27 deletions(-) diff --git a/boards/shields/st_b_lcd40_dsi1_mb1166/boards/stm32f769i_disco.overlay b/boards/shields/st_b_lcd40_dsi1_mb1166/boards/stm32f769i_disco.overlay index 66323d16944e..26f7b429b3e3 100644 --- a/boards/shields/st_b_lcd40_dsi1_mb1166/boards/stm32f769i_disco.overlay +++ b/boards/shields/st_b_lcd40_dsi1_mb1166/boards/stm32f769i_disco.overlay @@ -21,7 +21,7 @@ div-m = <25>; mul-n = <384>; div-r = <5>; - div-divr = <8>; + post-div-r = <8>; clocks = <&clk_hse>; status = "okay"; }; diff --git a/boards/st/stm32f429i_disc1/stm32f429i_disc1.dts b/boards/st/stm32f429i_disc1/stm32f429i_disc1.dts index 5ed576dea0bf..b94606c56343 100644 --- a/boards/st/stm32f429i_disc1/stm32f429i_disc1.dts +++ b/boards/st/stm32f429i_disc1/stm32f429i_disc1.dts @@ -121,7 +121,7 @@ div-m = <8>; mul-n = <192>; div-r = <4>; - div-divr = <8>; + post-div-r = <8>; clocks = <&clk_hse>; status = "okay"; }; diff --git a/boards/st/stm32f469i_disco/stm32f469i_disco.dts b/boards/st/stm32f469i_disco/stm32f469i_disco.dts index 17022e34ecd2..b2c25d421203 100644 --- a/boards/st/stm32f469i_disco/stm32f469i_disco.dts +++ b/boards/st/stm32f469i_disco/stm32f469i_disco.dts @@ -98,7 +98,7 @@ mul-n = <266>; div-p = <2>; div-r = <5>; - div-divr = <2>; + post-div-r = <2>; clocks = <&clk_hse>; status = "okay"; }; diff --git a/boards/st/stm32f746g_disco/stm32f746g_disco.dts b/boards/st/stm32f746g_disco/stm32f746g_disco.dts index 70a3c642b70e..cbe975b7e2cd 100644 --- a/boards/st/stm32f746g_disco/stm32f746g_disco.dts +++ b/boards/st/stm32f746g_disco/stm32f746g_disco.dts @@ -91,7 +91,7 @@ div-m = <25>; mul-n = <384>; div-r = <5>; - div-divr = <8>; + post-div-r = <8>; clocks = <&clk_hse>; status = "okay"; }; diff --git a/boards/st/stm32f7508_dk/stm32f7508_dk.dts b/boards/st/stm32f7508_dk/stm32f7508_dk.dts index e51f027ce091..3177880ec27f 100644 --- a/boards/st/stm32f7508_dk/stm32f7508_dk.dts +++ b/boards/st/stm32f7508_dk/stm32f7508_dk.dts @@ -82,7 +82,7 @@ div-m = <25>; mul-n = <384>; div-r = <5>; - div-divr = <8>; + post-div-r = <8>; clocks = <&clk_hse>; status = "okay"; }; diff --git a/dts/arm/st/f2/stm32f2.dtsi b/dts/arm/st/f2/stm32f2.dtsi index aae245c3a980..ed6d29df32cc 100644 --- a/dts/arm/st/f2/stm32f2.dtsi +++ b/dts/arm/st/f2/stm32f2.dtsi @@ -71,7 +71,7 @@ pll: pll { #clock-cells = <0>; - compatible = "st,stm32f2-pll-clock"; + compatible = "st,stm32fx-pll-clock"; status = "disabled"; }; }; diff --git a/dts/arm/st/f4/stm32f4.dtsi b/dts/arm/st/f4/stm32f4.dtsi index 458228afea18..556b2a4e708e 100644 --- a/dts/arm/st/f4/stm32f4.dtsi +++ b/dts/arm/st/f4/stm32f4.dtsi @@ -89,7 +89,7 @@ pll: pll { #clock-cells = <0>; - compatible = "st,stm32f4-pll-clock"; + compatible = "st,stm32fx-pll-clock"; status = "disabled"; }; }; diff --git a/dts/arm/st/f4/stm32f401.dtsi b/dts/arm/st/f4/stm32f401.dtsi index d76a45ef45f2..db777656fc3b 100644 --- a/dts/arm/st/f4/stm32f401.dtsi +++ b/dts/arm/st/f4/stm32f401.dtsi @@ -10,7 +10,7 @@ clocks { plli2s: plli2s { #clock-cells = <0>; - compatible = "st,stm32f4-plli2s-clock"; + compatible = "st,stm32fx-pll-clock"; status = "disabled"; }; }; diff --git a/dts/arm/st/f4/stm32f411.dtsi b/dts/arm/st/f4/stm32f411.dtsi index 8d3489ed57a3..a287950c5af7 100644 --- a/dts/arm/st/f4/stm32f411.dtsi +++ b/dts/arm/st/f4/stm32f411.dtsi @@ -7,14 +7,6 @@ #include / { - clocks { - plli2s: plli2s { - #clock-cells = <0>; - compatible = "st,stm32f411-plli2s-clock"; - status = "disabled"; - }; - }; - soc { compatible = "st,stm32f411", "st,stm32f4", "simple-bus"; diff --git a/dts/arm/st/f4/stm32f412.dtsi b/dts/arm/st/f4/stm32f412.dtsi index 607a5e329332..2185cbee3451 100644 --- a/dts/arm/st/f4/stm32f412.dtsi +++ b/dts/arm/st/f4/stm32f412.dtsi @@ -14,7 +14,7 @@ clocks { plli2s: plli2s { #clock-cells = <0>; - compatible = "st,stm32f411-plli2s-clock"; + compatible = "st,stm32fx-pll-clock"; status = "disabled"; }; diff --git a/dts/arm/st/f4/stm32f427.dtsi b/dts/arm/st/f4/stm32f427.dtsi index ad7616b5fcf9..1251dc3dfa43 100644 --- a/dts/arm/st/f4/stm32f427.dtsi +++ b/dts/arm/st/f4/stm32f427.dtsi @@ -12,7 +12,7 @@ / { clocks { pllsai: pllsai { - compatible = "st,stm32fx-pllsai-clock"; + compatible = "st,stm32fx-pll-clock"; #clock-cells = <0>; status = "disabled"; }; diff --git a/dts/arm/st/f4/stm32f446.dtsi b/dts/arm/st/f4/stm32f446.dtsi index 11f01822e978..763d33a40a36 100644 --- a/dts/arm/st/f4/stm32f446.dtsi +++ b/dts/arm/st/f4/stm32f446.dtsi @@ -11,12 +11,8 @@ / { clocks { - plli2s: plli2s { - compatible = "st,stm32f411-plli2s-clock"; - }; - pllsai: pllsai { - compatible = "st,stm32fx-pllsai-clock"; + compatible = "st,stm32fx-pll-clock"; #clock-cells = <0>; status = "disabled"; }; diff --git a/dts/arm/st/f7/stm32f7.dtsi b/dts/arm/st/f7/stm32f7.dtsi index 12d54ab9553b..be818d2edcab 100644 --- a/dts/arm/st/f7/stm32f7.dtsi +++ b/dts/arm/st/f7/stm32f7.dtsi @@ -85,12 +85,18 @@ pll: pll { #clock-cells = <0>; - compatible = "st,stm32f7-pll-clock"; + compatible = "st,stm32fx-pll-clock"; + status = "disabled"; + }; + + plli2s: plli2s { + #clock-cells = <0>; + compatible = "st,stm32fx-pll-clock"; status = "disabled"; }; pllsai: pllsai { - compatible = "st,stm32fx-pllsai-clock"; + compatible = "st,stm32fx-pll-clock"; #clock-cells = <0>; status = "disabled"; }; diff --git a/samples/drivers/i2s/output/boards/nucleo_f429zi.overlay b/samples/drivers/i2s/output/boards/nucleo_f429zi.overlay index be1266e6ea47..681861c59e00 100644 --- a/samples/drivers/i2s/output/boards/nucleo_f429zi.overlay +++ b/samples/drivers/i2s/output/boards/nucleo_f429zi.overlay @@ -15,7 +15,7 @@ div-m = <8>; mul-n = <101>; div-q = <9>; - div-divq = <1>; + post-div-q = <1>; clocks = <&clk_hse>; status = "okay"; }; diff --git a/samples/drivers/i2s/output/boards/nucleo_f767zi.overlay b/samples/drivers/i2s/output/boards/nucleo_f767zi.overlay index 3c65683ef366..cc889370976f 100644 --- a/samples/drivers/i2s/output/boards/nucleo_f767zi.overlay +++ b/samples/drivers/i2s/output/boards/nucleo_f767zi.overlay @@ -15,7 +15,7 @@ div-m = <4>; mul-n = <119>; div-q = <7>; - div-divq = <3>; + post-div-q = <3>; clocks = <&clk_hse>; status = "okay"; }; From 447d552ac061afd74b2734433fd3112bf1846bd0 Mon Sep 17 00:00:00 2001 From: Guillaume Gautier Date: Tue, 9 Dec 2025 15:35:57 +0100 Subject: [PATCH 2085/3659] include: dt-bindings: clock: stm32fx: add missing clock sources Add some missing clock sources and reorganize them to class the PLL outputs together for STM32F4 and F7. Signed-off-by: Guillaume Gautier --- dts/arm/st/f4/stm32f469.dtsi | 2 +- dts/arm/st/f7/stm32f767.dtsi | 2 +- .../zephyr/dt-bindings/clock/stm32f4_clock.h | 24 +++++++++++-------- .../zephyr/dt-bindings/clock/stm32f7_clock.h | 22 +++++++++-------- 4 files changed, 28 insertions(+), 22 deletions(-) diff --git a/dts/arm/st/f4/stm32f469.dtsi b/dts/arm/st/f4/stm32f469.dtsi index e8d6d73bf8be..19ea883f1d0d 100644 --- a/dts/arm/st/f4/stm32f469.dtsi +++ b/dts/arm/st/f4/stm32f469.dtsi @@ -34,7 +34,7 @@ clock-names = "dsiclk", "refclk", "pixelclk"; clocks = <&rcc STM32_CLOCK(APB2, 27)>, <&rcc STM32_SRC_HSE NO_SEL>, - <&rcc STM32_SRC_PLLSAI_DIVR NO_SEL>; + <&rcc STM32_SRC_PLLSAI_POST_R NO_SEL>; resets = <&rctl STM32_RESET(APB2, 27)>; status = "disabled"; }; diff --git a/dts/arm/st/f7/stm32f767.dtsi b/dts/arm/st/f7/stm32f767.dtsi index 6895158346d2..937f2cc1179d 100644 --- a/dts/arm/st/f7/stm32f767.dtsi +++ b/dts/arm/st/f7/stm32f767.dtsi @@ -30,7 +30,7 @@ clock-names = "dsiclk", "refclk", "pixelclk"; clocks = <&rcc STM32_CLOCK(APB2, 27)>, <&rcc STM32_SRC_HSE NO_SEL>, - <&rcc STM32_SRC_PLLSAI_DIVR NO_SEL>; + <&rcc STM32_SRC_PLLSAI_POST_R NO_SEL>; resets = <&rctl STM32_RESET(APB2, 27)>; status = "disabled"; }; diff --git a/include/zephyr/dt-bindings/clock/stm32f4_clock.h b/include/zephyr/dt-bindings/clock/stm32f4_clock.h index 5f09416e0a08..0ca2306561ed 100644 --- a/include/zephyr/dt-bindings/clock/stm32f4_clock.h +++ b/include/zephyr/dt-bindings/clock/stm32f4_clock.h @@ -34,21 +34,25 @@ #define STM32_SRC_PLL_P (STM32_SRC_HSE + 1) #define STM32_SRC_PLL_Q (STM32_SRC_PLL_P + 1) #define STM32_SRC_PLL_R (STM32_SRC_PLL_Q + 1) -/** I2S sources */ -#define STM32_SRC_PLLI2S_Q (STM32_SRC_PLL_R + 1) -#define STM32_SRC_PLLI2S_R (STM32_SRC_PLLI2S_Q + 1) +#define STM32_SRC_PLL_POST_R (STM32_SRC_PLL_R + 1) +/** PLLI2S clock outputs */ +#define STM32_SRC_PLLI2S_P (STM32_SRC_PLL_POST_R + 1) +#define STM32_SRC_PLLI2S_Q (STM32_SRC_PLLI2S_P + 1) +#define STM32_SRC_PLLI2S_POST_Q (STM32_SRC_PLLI2S_Q + 1) +#define STM32_SRC_PLLI2S_R (STM32_SRC_PLLI2S_POST_Q + 1) +#define STM32_SRC_PLLI2S_POST_R (STM32_SRC_PLLI2S_R + 1) +/* PLLSAI clock outputs */ +#define STM32_SRC_PLLSAI_P (STM32_SRC_PLLI2S_POST_R + 1) +#define STM32_SRC_PLLSAI_Q (STM32_SRC_PLLSAI_P + 1) +#define STM32_SRC_PLLSAI_POST_Q (STM32_SRC_PLLSAI_Q + 1) +#define STM32_SRC_PLLSAI_R (STM32_SRC_PLLSAI_POST_Q + 1) +#define STM32_SRC_PLLSAI_POST_R (STM32_SRC_PLLSAI_R + 1) /* CLK48MHz sources */ -#define STM32_SRC_CK48 (STM32_SRC_PLLI2S_R + 1) +#define STM32_SRC_CK48 (STM32_SRC_PLLSAI_POST_R + 1) /** Bus clock */ #define STM32_SRC_TIMPCLK1 (STM32_SRC_CK48 + 1) #define STM32_SRC_TIMPCLK2 (STM32_SRC_TIMPCLK1 + 1) -/* PLLSAI clocks */ -#define STM32_SRC_PLLSAI_P (STM32_SRC_TIMPCLK2 + 1) -#define STM32_SRC_PLLSAI_Q (STM32_SRC_PLLSAI_P + 1) -#define STM32_SRC_PLLSAI_DIVQ (STM32_SRC_PLLSAI_Q + 1) -#define STM32_SRC_PLLSAI_R (STM32_SRC_PLLSAI_DIVQ + 1) -#define STM32_SRC_PLLSAI_DIVR (STM32_SRC_PLLSAI_R + 1) /* I2S_CKIN not supported yet */ /* #define STM32_SRC_I2S_CKIN TBD */ diff --git a/include/zephyr/dt-bindings/clock/stm32f7_clock.h b/include/zephyr/dt-bindings/clock/stm32f7_clock.h index 5a441af624ad..718d9547247e 100644 --- a/include/zephyr/dt-bindings/clock/stm32f7_clock.h +++ b/include/zephyr/dt-bindings/clock/stm32f7_clock.h @@ -35,20 +35,22 @@ #define STM32_SRC_PLL_P (STM32_SRC_HSE + 1) #define STM32_SRC_PLL_Q (STM32_SRC_PLL_P + 1) #define STM32_SRC_PLL_R (STM32_SRC_PLL_Q + 1) +/** PLLI2S clock outputs */ +#define STM32_SRC_PLLI2S_P (STM32_SRC_PLL_R + 1) +#define STM32_SRC_PLLI2S_Q (STM32_SRC_PLLI2S_P + 1) +#define STM32_SRC_PLLI2S_POST_Q (STM32_SRC_PLLI2S_Q + 1) +#define STM32_SRC_PLLI2S_R (STM32_SRC_PLLI2S_POST_Q + 1) +/* PLLSAI clock outputs */ +#define STM32_SRC_PLLSAI_P (STM32_SRC_PLLI2S_R + 1) +#define STM32_SRC_PLLSAI_Q (STM32_SRC_PLLSAI_P + 1) +#define STM32_SRC_PLLSAI_POST_Q (STM32_SRC_PLLSAI_Q + 1) +#define STM32_SRC_PLLSAI_R (STM32_SRC_PLLSAI_POST_Q + 1) +#define STM32_SRC_PLLSAI_POST_R (STM32_SRC_PLLSAI_R + 1) /** Peripheral bus clock */ -#define STM32_SRC_PCLK (STM32_SRC_PLL_R + 1) +#define STM32_SRC_PCLK (STM32_SRC_PLLSAI_POST_R + 1) #define STM32_SRC_TIMPCLK1 (STM32_SRC_PCLK + 1) #define STM32_SRC_TIMPCLK2 (STM32_SRC_TIMPCLK1 + 1) -#define STM32_SRC_PLLI2S_R (STM32_SRC_TIMPCLK2 + 1) - -/* PLLSAI clocks */ -#define STM32_SRC_PLLSAI_P (STM32_SRC_PLLI2S_R + 1) -#define STM32_SRC_PLLSAI_Q (STM32_SRC_PLLSAI_P + 1) -#define STM32_SRC_PLLSAI_DIVQ (STM32_SRC_PLLSAI_Q + 1) -#define STM32_SRC_PLLSAI_R (STM32_SRC_PLLSAI_DIVQ + 1) -#define STM32_SRC_PLLSAI_DIVR (STM32_SRC_PLLSAI_R + 1) - /** @brief RCC_CFGRx register offset */ #define CFGR_REG 0x08 From 5960c2d5a1f347979c147f603bec08be0b3df8f0 Mon Sep 17 00:00:00 2001 From: Guillaume Gautier Date: Tue, 9 Dec 2025 15:47:22 +0100 Subject: [PATCH 2086/3659] drivers: clock: stm32: update stm32f2_f4_f7 driver with the new binding This commit updates the STM32Fx clock driver to add complete support for all PLLs for all SoCs. Supports all outputs and additional divisors: - PLL-DIV-R - PLLI2S-P - PLLI2S-DIV-Q - PLLI2S-DIV-R Adds global checks to make sure that all: - All PLLs share the same source clocks - All PLLs share the same M-Divisor (on applicable SoCs) - Both div-X and div-divX are defined (on applicable SoCs) Functions get_plli2s_source and get_plli2ssrc_frequency are added to make sure that PLLI2S can be used even if PLL is not defined. Signed-off-by: Guillaume Gautier --- drivers/clock_control/clock_stm32_ll_common.c | 101 ++++++-- drivers/clock_control/clock_stm32_ll_common.h | 5 + drivers/clock_control/clock_stm32f2_f4_f7.c | 216 +++++++++++++++--- .../clock_control/stm32_clock_control.h | 71 +++--- 4 files changed, 299 insertions(+), 94 deletions(-) diff --git a/drivers/clock_control/clock_stm32_ll_common.c b/drivers/clock_control/clock_stm32_ll_common.c index c657a3db2b51..eeb77dcdc110 100644 --- a/drivers/clock_control/clock_stm32_ll_common.c +++ b/drivers/clock_control/clock_stm32_ll_common.c @@ -222,6 +222,20 @@ int enabled_clock(uint32_t src_clk) } break; #endif /* STM32_SRC_PLL_R */ +#if defined(STM32_SRC_PLL_POST_R) + case STM32_SRC_PLL_POST_R: + if (!IS_ENABLED(STM32_PLL_R_ENABLED)) { + r = -ENOTSUP; + } + break; +#endif /* STM32_SRC_PLL_POST_R */ +#if defined(STM32_SRC_PLLI2S_P) + case STM32_SRC_PLLI2S_P: + if (!IS_ENABLED(STM32_PLLI2S_P_ENABLED)) { + r = -ENOTSUP; + } + break; +#endif /* STM32_SRC_PLLI2S_P */ #if defined(STM32_SRC_PLLI2S_Q) case STM32_SRC_PLLI2S_Q: if (!IS_ENABLED(STM32_PLLI2S_Q_ENABLED)) { @@ -229,6 +243,13 @@ int enabled_clock(uint32_t src_clk) } break; #endif /* STM32_SRC_PLLI2S_Q */ +#if defined(STM32_SRC_PLLI2S_POST_Q) + case STM32_SRC_PLLI2S_POST_Q: + if (!IS_ENABLED(STM32_PLLI2S_Q_ENABLED)) { + r = -ENOTSUP; + } + break; +#endif /* STM32_SRC_PLLI2S_POST_Q */ #if defined(STM32_SRC_PLLI2S_R) case STM32_SRC_PLLI2S_R: if (!IS_ENABLED(STM32_PLLI2S_R_ENABLED)) { @@ -236,6 +257,13 @@ int enabled_clock(uint32_t src_clk) } break; #endif /* STM32_SRC_PLLI2S_R */ +#if defined(STM32_SRC_PLLI2S_POST_R) + case STM32_SRC_PLLI2S_POST_R: + if (!IS_ENABLED(STM32_PLLI2S_R_ENABLED)) { + r = -ENOTSUP; + } + break; +#endif /* STM32_SRC_PLLI2S_POST_R */ #if defined(STM32_SRC_PLLSAI_P) case STM32_SRC_PLLSAI_P: if (!IS_ENABLED(STM32_PLLSAI_P_ENABLED)) { @@ -250,13 +278,13 @@ int enabled_clock(uint32_t src_clk) } break; #endif /* STM32_SRC_PLLSAI_Q */ -#if defined(STM32_SRC_PLLSAI_DIVQ) - case STM32_SRC_PLLSAI_DIVQ: +#if defined(STM32_SRC_PLLSAI_POST_Q) + case STM32_SRC_PLLSAI_POST_Q: if (!IS_ENABLED(STM32_PLLSAI_Q_ENABLED)) { r = -ENOTSUP; } break; -#endif /* STM32_SRC_PLLSAI_DIVQ */ +#endif /* STM32_SRC_PLLSAI_POST_Q */ #if defined(STM32_SRC_PLLSAI_R) case STM32_SRC_PLLSAI_R: if (!IS_ENABLED(STM32_PLLSAI_R_ENABLED)) { @@ -264,13 +292,13 @@ int enabled_clock(uint32_t src_clk) } break; #endif /* STM32_SRC_PLLSAI_R */ -#if defined(STM32_SRC_PLLSAI_DIVR) - case STM32_SRC_PLLSAI_DIVR: +#if defined(STM32_SRC_PLLSAI_POST_R) + case STM32_SRC_PLLSAI_POST_R: if (!IS_ENABLED(STM32_PLLSAI_R_ENABLED)) { r = -ENOTSUP; } break; -#endif /* STM32_SRC_PLLSAI_DIVR */ +#endif /* STM32_SRC_PLLSAI_POST_R */ #if defined(STM32_SRC_PLLSAI1_P) case STM32_SRC_PLLSAI1_P: if (!IS_ENABLED(STM32_PLLSAI1_P_ENABLED)) { @@ -524,22 +552,57 @@ static int stm32_clock_control_get_subsys_rate(const struct device *clock, STM32_PLL_R_DIVISOR); break; #endif -#if defined(STM32_SRC_PLLI2S_Q) && STM32_PLLI2S_Q_ENABLED && STM32_PLLI2S_ENABLED - case STM32_SRC_PLLI2S_Q: +#if defined(STM32_SRC_PLL_POST_R) && STM32_PLL_R_ENABLED && STM32_PLL_POST_R_ENABLED + case STM32_SRC_PLL_POST_R: *rate = get_pll_div_frequency(get_pllsrc_frequency(), + STM32_PLL_M_DIVISOR, + STM32_PLL_N_MULTIPLIER, + STM32_PLL_R_DIVISOR); + *rate /= STM32_PLL_POST_R_DIVISOR; + break; +#endif +#if defined(STM32_SRC_PLLI2S_P) && STM32_PLLI2S_P_ENABLED + case STM32_SRC_PLLI2S_P: + *rate = get_pll_div_frequency(get_plli2ssrc_frequency(), + STM32_PLLI2S_M_DIVISOR, + STM32_PLLI2S_N_MULTIPLIER, + STM32_PLLI2S_P_DIVISOR); + break; +#endif /* STM32_SRC_PLLI2S_P */ +#if defined(STM32_SRC_PLLI2S_Q) && STM32_PLLI2S_Q_ENABLED + case STM32_SRC_PLLI2S_Q: + *rate = get_pll_div_frequency(get_plli2ssrc_frequency(), STM32_PLLI2S_M_DIVISOR, STM32_PLLI2S_N_MULTIPLIER, STM32_PLLI2S_Q_DIVISOR); break; #endif /* STM32_SRC_PLLI2S_Q */ -#if defined(STM32_SRC_PLLI2S_R) && STM32_PLLI2S_ENABLED +#if defined(STM32_SRC_PLLI2S_POST_Q) && STM32_PLLI2S_Q_ENABLED && STM32_PLLI2S_POST_Q_ENABLED + case STM32_SRC_PLLI2S_POST_Q: + *rate = get_pll_div_frequency(get_plli2ssrc_frequency(), + STM32_PLLI2S_M_DIVISOR, + STM32_PLLI2S_N_MULTIPLIER, + STM32_PLLI2S_Q_DIVISOR); + *rate /= STM32_PLLI2S_POST_Q_DIVISOR; + break; +#endif /* STM32_SRC_PLLI2S_POST_Q */ +#if defined(STM32_SRC_PLLI2S_R) && STM32_PLLI2S_R_ENABLED case STM32_SRC_PLLI2S_R: - *rate = get_pll_div_frequency(get_pllsrc_frequency(), + *rate = get_pll_div_frequency(get_plli2ssrc_frequency(), STM32_PLLI2S_M_DIVISOR, STM32_PLLI2S_N_MULTIPLIER, STM32_PLLI2S_R_DIVISOR); break; #endif /* STM32_SRC_PLLI2S_R */ +#if defined(STM32_SRC_PLLI2S_POST_R) && STM32_PLLI2S_R_ENABLED && STM32_PLLI2S_POST_R_ENABLED + case STM32_SRC_PLLI2S_POST_R: + *rate = get_pll_div_frequency(get_plli2ssrc_frequency(), + STM32_PLLI2S_M_DIVISOR, + STM32_PLLI2S_N_MULTIPLIER, + STM32_PLLI2S_R_DIVISOR); + *rate /= STM32_PLLI2S_POST_R_DIVISOR; + break; +#endif /* STM32_SRC_PLLI2S_POST_R */ #if defined(STM32_SRC_PLLSAI_P) && STM32_PLLSAI_P_ENABLED case STM32_SRC_PLLSAI_P: *rate = get_pll_div_frequency(get_pllsaisrc_frequency(), @@ -556,16 +619,15 @@ static int stm32_clock_control_get_subsys_rate(const struct device *clock, STM32_PLLSAI_Q_DIVISOR); break; #endif /* STM32_SRC_PLLSAI_Q */ -#if defined(STM32_SRC_PLLSAI_DIVQ) && STM32_PLLSAI_Q_ENABLED && STM32_PLLSAI_DIVQ_ENABLED && \ - defined(STM32_PLLSAI_DIVQ_DIVISOR) - case STM32_SRC_PLLSAI_DIVQ: +#if defined(STM32_SRC_PLLSAI_POST_Q) && STM32_PLLSAI_Q_ENABLED && STM32_PLLSAI_POST_Q_ENABLED + case STM32_SRC_PLLSAI_POST_Q: *rate = get_pll_div_frequency(get_pllsaisrc_frequency(), STM32_PLLSAI_M_DIVISOR, STM32_PLLSAI_N_MULTIPLIER, STM32_PLLSAI_Q_DIVISOR); - *rate /= STM32_PLLSAI_DIVQ_DIVISOR; + *rate /= STM32_PLLSAI_POST_Q_DIVISOR; break; -#endif /* STM32_SRC_PLLSAI_DIVQ */ +#endif /* STM32_SRC_PLLSAI_POST_Q */ #if defined(STM32_SRC_PLLSAI_R) && STM32_PLLSAI_R_ENABLED case STM32_SRC_PLLSAI_R: *rate = get_pll_div_frequency(get_pllsaisrc_frequency(), @@ -574,16 +636,15 @@ static int stm32_clock_control_get_subsys_rate(const struct device *clock, STM32_PLLSAI_R_DIVISOR); break; #endif /* STM32_SRC_PLLSAI_R */ -#if defined(STM32_SRC_PLLSAI_DIVR) && STM32_PLLSAI_R_ENABLED && STM32_PLLSAI_DIVR_ENABLED && \ - defined(STM32_PLLSAI_DIVR_DIVISOR) - case STM32_SRC_PLLSAI_DIVR: +#if defined(STM32_SRC_PLLSAI_POST_R) && STM32_PLLSAI_R_ENABLED && STM32_PLLSAI_POST_R_ENABLED + case STM32_SRC_PLLSAI_POST_R: *rate = get_pll_div_frequency(get_pllsaisrc_frequency(), STM32_PLLSAI_M_DIVISOR, STM32_PLLSAI_N_MULTIPLIER, STM32_PLLSAI_R_DIVISOR); - *rate /= STM32_PLLSAI_DIVR_DIVISOR; + *rate /= STM32_PLLSAI_POST_R_DIVISOR; break; -#endif /* STM32_SRC_PLLSAI_DIVR */ +#endif /* STM32_SRC_PLLSAI_POST_R */ #if defined(STM32_SRC_PLLSAI1_P) && STM32_PLLSAI1_P_ENABLED case STM32_SRC_PLLSAI1_P: *rate = get_pll_div_frequency(get_pllsai1src_frequency(), diff --git a/drivers/clock_control/clock_stm32_ll_common.h b/drivers/clock_control/clock_stm32_ll_common.h index 927309425e8b..09e0d7164f4f 100644 --- a/drivers/clock_control/clock_stm32_ll_common.h +++ b/drivers/clock_control/clock_stm32_ll_common.h @@ -20,6 +20,7 @@ #define pllp(v) CONCAT(LL_RCC_PLLP_DIV_, v) #define pllq(v) CONCAT(LL_RCC_PLLQ_DIV_, v) #define pllr(v) CONCAT(LL_RCC_PLLR_DIV_, v) +#define plldivr(v) CONCAT(LL_RCC_PLLDIVR_DIV_, v) #if defined(RCC_PLLI2SCFGR_PLLI2SM) /* Some stm32F4 devices have a dedicated PLL I2S with M divider */ @@ -28,8 +29,11 @@ /* Some stm32F4 devices (typ. stm32F401) have a dedicated PLL I2S with PLL M divider */ #define plli2sm(v) CONCAT(LL_RCC_PLLM_DIV_, v) #endif /* RCC_PLLI2SCFGR_PLLI2SM */ +#define plli2sp(v) CONCAT(LL_RCC_PLLI2SP_DIV_, v) #define plli2sq(v) CONCAT(LL_RCC_PLLI2SQ_DIV_, v) +#define plli2sdivq(v) CONCAT(LL_RCC_PLLI2SDIVQ_DIV_, v) #define plli2sr(v) CONCAT(LL_RCC_PLLI2SR_DIV_, v) +#define plli2sdivr(v) CONCAT(LL_RCC_PLLI2SDIVR_DIV_, v) #define pllsaim(v) CONCAT(LL_RCC_PLLM_DIV_, v) #define pllsaip(v) CONCAT(LL_RCC_PLLSAIP_DIV_, v) @@ -65,6 +69,7 @@ uint32_t get_pllsrc_frequency(void); void config_pll2(void); #endif #if defined(STM32_PLLI2S_ENABLED) +uint32_t get_plli2ssrc_frequency(void); void config_plli2s(void); #endif #if defined(STM32_PLLSAI_ENABLED) diff --git a/drivers/clock_control/clock_stm32f2_f4_f7.c b/drivers/clock_control/clock_stm32f2_f4_f7.c index a7be342a5d9a..66de022c755d 100644 --- a/drivers/clock_control/clock_stm32f2_f4_f7.c +++ b/drivers/clock_control/clock_stm32f2_f4_f7.c @@ -17,7 +17,73 @@ #include #include "clock_stm32_ll_common.h" -#if defined(STM32_PLL_ENABLED) +/* On all STM32F2x, F4x and F7x, the PLLs share the same source. + * Ensure that it is the case for those enabled. + */ +#if defined(STM32_PLL_ENABLED) && defined(STM32_PLLI2S_ENABLED) +BUILD_ASSERT(DT_SAME_NODE(DT_PLL_CLOCKS_CTRL, DT_PLLI2S_CLOCKS_CTRL), + "PLL and PLLI2S must have the same source"); +#endif /* pll && plli2s */ + +#if defined(STM32_PLL_ENABLED) && defined(STM32_PLLSAI_ENABLED) +BUILD_ASSERT(DT_SAME_NODE(DT_PLL_CLOCKS_CTRL, DT_PLLSAI_CLOCKS_CTRL), + "PLL and PLLSAI must have the same source"); +#endif /* pll && pllsai */ + +#if defined(STM32_PLLI2S_ENABLED) && defined(STM32_PLLSAI_ENABLED) +BUILD_ASSERT(DT_SAME_NODE(DT_PLLI2S_CLOCKS_CTRL, DT_PLLSAI_CLOCKS_CTRL), + "PLLI2S and PLLSAI must have the same source"); +#endif /* plli2s && pllsai */ + +#if !defined(RCC_PLLI2SCFGR_PLLI2SM) +/* Except for STM32F411 / F412 / F413 / F423 and F446, all PLLs on F2x, F4x and F7x share + * the same M divisor. If several PLLs are defined, their div-m must have the same value. + */ +#if defined(STM32_PLL_ENABLED) && defined(STM32_PLLI2S_ENABLED) +BUILD_ASSERT(STM32_PLL_M_DIVISOR == STM32_PLLI2S_M_DIVISOR, + "PLL M and PLLI2S M should have the same value"); +#endif /* STM32_PLL_ENABLED && STM32_PLLI2S_ENABLED */ + +#if defined(STM32_PLL_ENABLED) && defined(STM32_PLLSAI_ENABLED) +BUILD_ASSERT(STM32_PLL_M_DIVISOR == STM32_PLLSAI_M_DIVISOR, + "PLL M and PLLSAI M should have the same value"); +#endif /* STM32_PLL_ENABLED && STM32_PLLSAI_ENABLED */ + +#if defined(STM32_PLLI2S_ENABLED) && defined(STM32_PLLSAI_ENABLED) +BUILD_ASSERT(STM32_PLLI2S_M_DIVISOR == STM32_PLLSAI_M_DIVISOR, + "PLLI2S M and PLLSAI M should have the same value"); +#endif /* STM32_PLLI2S_ENABLED && STM32_PLLSAI_ENABLED */ +#endif /* RCC_PLLI2SCFGR_PLLI2SM */ + +/* Some SoCs have a secondary divisor for some PLL outputs. + * When that's the case, ensure that if one is defined, the other also is. + */ +#if defined(STM32_PLL_ENABLED) && defined(RCC_DCKCFGR_PLLDIVR) +BUILD_ASSERT(STM32_PLL_R_ENABLED == STM32_PLL_POST_R_ENABLED, + "For the PLL, both div-r and post-divr must be present if one of them is present"); +#endif /* STM32_PLL_ENABLED && RCC_DCKCFGR_PLLDIVR */ + +#if defined(STM32_PLLI2S_ENABLED) && defined(RCC_DCKCFGR_PLLI2SDIVQ) +BUILD_ASSERT(STM32_PLLI2S_Q_ENABLED == STM32_PLLI2S_POST_Q_ENABLED, + "For the PLLI2S, both div-q and post-divq must be present if one of them is present"); +#endif /* STM32_PLLI2S_ENABLED && RCC_DCKCFGR_PLLI2SDIVQ */ + +#if defined(STM32_PLLI2S_ENABLED) && defined(RCC_DCKCFGR_PLLI2SDIVR) +BUILD_ASSERT(STM32_PLLI2S_R_ENABLED == STM32_PLLI2S_POST_R_ENABLED, + "For the PLLI2S, both div-r and post-divr must be present if one of them is present"); +#endif /* STM32_PLLI2S_ENABLED && RCC_DCKCFGR_PLLI2SDIVR */ + +#if defined(STM32_PLLSAI_ENABLED) +BUILD_ASSERT(STM32_PLLSAI_Q_ENABLED == STM32_PLLSAI_POST_Q_ENABLED, + "For the PLLSAI, both div-q and post-divq must be present if one of them is present"); +#endif /* STM32_PLLSAI_ENABLED */ + +#if defined(STM32_PLLSAI_ENABLED) && defined(RCC_PLLSAICFGR_PLLSAIR) +BUILD_ASSERT(STM32_PLLSAI_R_ENABLED == STM32_PLLSAI_POST_R_ENABLED, + "For the PLLSAI, both div-r and post-divr must be present if one of them is present"); +#endif /* STM32_PLLSAI_ENABLED && RCC_PLLSAICFGR_PLLSAIR */ + +#ifdef STM32_PLL_ENABLED /** * @brief Return PLL source @@ -97,22 +163,47 @@ uint32_t get_ck48_frequency(void) __unused void config_pll_sysclock(void) { -#if defined(STM32_SRC_PLL_R) && STM32_PLL_R_ENABLED && defined(RCC_PLLCFGR_PLLR) - stm32_reg_modify_bits(&RCC->PLLCFGR, RCC_PLLCFGR_PLLR, pllr(STM32_PLL_R_DIVISOR)); -#endif +#if STM32_PLL_P_ENABLED + /* All STM32F2x, F4x and F7x */ LL_RCC_PLL_ConfigDomain_SYS(get_pll_source(), pllm(STM32_PLL_M_DIVISOR), STM32_PLL_N_MULTIPLIER, pllp(STM32_PLL_P_DIVISOR)); +#endif /* STM32_PLL_P_ENABLED */ #if STM32_PLL_Q_ENABLED - /* There is a Q divider on the PLL to configure the PLL48CK */ + /* All STM32F2x, F4x and F7x */ LL_RCC_PLL_ConfigDomain_48M(get_pll_source(), pllm(STM32_PLL_M_DIVISOR), STM32_PLL_N_MULTIPLIER, pllq(STM32_PLL_Q_DIVISOR)); #endif /* STM32_PLLI2S_Q_ENABLED */ +#if STM32_PLL_R_ENABLED +#if defined(RCC_DCKCFGR_PLLDIVR) + /* STM32F413 / F423 */ + LL_RCC_PLL_ConfigDomain_SAI(get_pll_source(), + pllm(STM32_PLL_M_DIVISOR), + STM32_PLL_N_MULTIPLIER, + pllr(STM32_PLL_R_DIVISOR) + plldivr(STM32_PLL_POST_R_DIVISOR)); +#elif defined(RCC_PLLR_I2S_CLKSOURCE_SUPPORT) /* RCC_DCKCFGR_PLLDIVR */ + /* STM32F410 / F412 / F446 */ + LL_RCC_PLL_ConfigDomain_I2S(get_pll_source(), + pllm(STM32_PLL_M_DIVISOR), + STM32_PLL_N_MULTIPLIER, + pllr(STM32_PLL_R_DIVISOR)); +#elif defined(DSI) /* RCC_PLLR_I2S_CLKSOURCE_SUPPORT */ + /* STM32F469 / F479 / F769 / F779 */ + LL_RCC_PLL_ConfigDomain_DSI(get_pll_source(), + pllm(STM32_PLL_M_DIVISOR), + STM32_PLL_N_MULTIPLIER, + pllr(STM32_PLL_R_DIVISOR)); +#else /* DSI */ +#error "PLL doesn't have R output on this SOC" +#endif /* DSI */ +#endif /* STM32_PLL_R_ENABLED */ + #if defined(CONFIG_SOC_SERIES_STM32F7X) /* Assuming we stay on Power Scale default value: Power Scale 1 */ if (CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC > 180000000) { @@ -143,34 +234,103 @@ void config_pll_sysclock(void) #endif /* CONFIG_SOC_SERIES_STM32F7X */ } -#endif /* defined(STM32_PLL_ENABLED) */ +#endif /* STM32_PLL_ENABLED */ #ifdef STM32_PLLI2S_ENABLED +/** + * @brief Return PLLI2S source + */ +__unused +static uint32_t get_plli2s_source(void) +{ + /* Configure PLL source */ + if (IS_ENABLED(STM32_PLLI2S_SRC_HSI)) { + return LL_RCC_PLLSOURCE_HSI; + } else if (IS_ENABLED(STM32_PLLI2S_SRC_HSE)) { + return LL_RCC_PLLSOURCE_HSE; + } + + __ASSERT(0, "Invalid source"); + return 0; +} + +/** + * @brief Get the PLLI2S source frequency + */ +__unused +uint32_t get_plli2ssrc_frequency(void) +{ + if (IS_ENABLED(STM32_PLLI2S_SRC_HSI)) { + return STM32_HSI_FREQ; + } else if (IS_ENABLED(STM32_PLLI2S_SRC_HSE)) { + return STM32_HSE_FREQ; + } + + __ASSERT(0, "Invalid source"); + return 0; +} + /** * @brief Set up PLL I2S configuration */ __unused void config_plli2s(void) { - LL_RCC_PLLI2S_ConfigDomain_I2S(get_pll_source(), +#if STM32_PLLI2S_P_ENABLED +#if defined(SPDIFRX) + /* STM32F446 / F74x and higher */ + LL_RCC_PLLI2S_ConfigDomain_SPDIFRX(get_plli2s_source(), + plli2sm(STM32_PLLI2S_M_DIVISOR), + STM32_PLLI2S_N_MULTIPLIER, + plli2sp(STM32_PLLI2S_P_DIVISOR)); +#else /* SPDIFRX */ +#error "PLLI2S doesn't have P output on this SOC" +#endif /* SPDIFRX */ +#endif /* STM32_PLLI2S_P_ENABLED */ + +#if STM32_PLLI2S_Q_ENABLED +#if defined(RCC_DCKCFGR_PLLI2SDIVQ) + /* STM32F427 / F429 / F437 / F439 / F446 / F469 / F479 / F7x */ + LL_RCC_PLLI2S_ConfigDomain_SAI(get_plli2s_source(), plli2sm(STM32_PLLI2S_M_DIVISOR), STM32_PLLI2S_N_MULTIPLIER, - plli2sr(STM32_PLLI2S_R_DIVISOR)); - -#if STM32_PLLI2S_Q_ENABLED && \ - (defined(RCC_PLLI2SCFGR_PLLI2SQ) && !defined(RCC_DCKCFGR_PLLI2SDIVQ)) - /* There is a Q divider on the PLLI2S to configure the PLL48CK */ - LL_RCC_PLLI2S_ConfigDomain_48M(get_pll_source(), + plli2sq(STM32_PLLI2S_Q_DIVISOR), + plli2sdivq(STM32_PLLI2S_POST_Q_DIVISOR)); +#elif defined(RCC_PLLI2SCFGR_PLLI2SQ) /* RCC_DCKCFGR_PLLI2SDIVQ */ + /* STM32F412 / F413 / F423 */ + LL_RCC_PLLI2S_ConfigDomain_48M(get_plli2s_source(), plli2sm(STM32_PLLI2S_M_DIVISOR), STM32_PLLI2S_N_MULTIPLIER, plli2sq(STM32_PLLI2S_Q_DIVISOR)); +#else /* RCC_PLLI2SCFGR_PLLI2SQ */ +#error "PLLI2S doesn't have Q output on this SOC" +#endif /* RCC_PLLI2SCFGR_PLLI2SQ */ #endif /* STM32_PLLI2S_Q_ENABLED */ + +#if STM32_PLLI2S_R_ENABLED +#if defined(RCC_DCKCFGR_PLLI2SDIVR) + /* STM32F413 / F423 */ + LL_RCC_PLLI2S_ConfigDomain_SAI(get_plli2s_source(), + plli2sm(STM32_PLLI2S_M_DIVISOR), + STM32_PLLI2S_N_MULTIPLIER, + plli2sr(STM32_PLLI2S_R_DIVISOR), + plli2sdivr(STM32_PLLI2S_POST_R_DIVISOR)); +#elif defined(RCC_PLLI2SCFGR_PLLI2SR) /* RCC_DCKCFGR_PLLI2SDIVR */ + /* All STM32F2x, F4x (except F410 / F413 / F423) and F7x */ + LL_RCC_PLLI2S_ConfigDomain_I2S(get_plli2s_source(), + plli2sm(STM32_PLLI2S_M_DIVISOR), + STM32_PLLI2S_N_MULTIPLIER, + plli2sr(STM32_PLLI2S_R_DIVISOR)); +#else /* RCC_PLLI2SCFGR_PLLI2SR */ +#error "PLLI2S doesn't have R output on this SOC" +#endif /* RCC_PLLI2SCFGR_PLLI2SR */ +#endif /* STM32_PLLI2S_R_ENABLED */ } #endif /* STM32_PLLI2S_ENABLED */ -#if defined(STM32_PLLSAI_ENABLED) +#ifdef STM32_PLLSAI_ENABLED /** * @brief Return PLLSAI source @@ -211,16 +371,6 @@ uint32_t get_pllsaisrc_frequency(void) __unused void config_pllsai(void) { - /* - * In case there is no dedicated M_DIVISOR for PLLSAI, the input is shared - * with PLL and PLLI2S. Ensure that if they exist, they have the same value - */ -#if !defined(RCC_PLLSAICFGR_PLLSAIM) -#if defined(STM32_PLL_M_DIVISOR) && (STM32_PLL_M_DIVISOR != STM32_PLLSAI_M_DIVISOR) -#error "PLLSAI M divisor must have same value as PLL M divisor" -#endif -#endif - #if STM32_PLLSAI_P_ENABLED #if defined(RCC_PLLSAICFGR_PLLSAIP) LL_RCC_PLLSAI_ConfigDomain_48M(get_pllsai_source(), @@ -228,33 +378,33 @@ void config_pllsai(void) STM32_PLLSAI_N_MULTIPLIER, pllsaip(STM32_PLLSAI_P_DIVISOR)); #else -#error "PLLSAI do not have P output on this SOC" +#error "PLLSAI doesn't have P output on this SOC" #endif #endif /* STM32_PLLSAI_P_ENABLED */ -#if STM32_PLLSAI_Q_ENABLED && STM32_PLLSAI_DIVQ_ENABLED +#if STM32_PLLSAI_Q_ENABLED && STM32_PLLSAI_POST_Q_ENABLED #if defined(RCC_PLLSAICFGR_PLLSAIQ) LL_RCC_PLLSAI_ConfigDomain_SAI(get_pllsai_source(), pllsaim(STM32_PLLSAI_M_DIVISOR), STM32_PLLSAI_N_MULTIPLIER, pllsaiq(STM32_PLLSAI_Q_DIVISOR), - pllsaidivq(STM32_PLLSAI_DIVQ_DIVISOR)); + pllsaidivq(STM32_PLLSAI_POST_Q_DIVISOR)); #else -#error "PLLSAI do not have Q output on this SOC" +#error "PLLSAI doesn't have Q output on this SOC" #endif -#endif /* STM32_PLLSAI_Q_ENABLED && STM32_PLLSAI_DIVQ_ENABLED */ +#endif /* STM32_PLLSAI_Q_ENABLED && STM32_PLLSAI_POST_Q_ENABLED */ -#if STM32_PLLSAI_R_ENABLED && STM32_PLLSAI_DIVR_ENABLED +#if STM32_PLLSAI_R_ENABLED && STM32_PLLSAI_POST_R_ENABLED #if defined(RCC_PLLSAICFGR_PLLSAIR) LL_RCC_PLLSAI_ConfigDomain_LTDC(get_pllsai_source(), pllsaim(STM32_PLLSAI_M_DIVISOR), STM32_PLLSAI_N_MULTIPLIER, pllsair(STM32_PLLSAI_R_DIVISOR), - pllsaidivr(STM32_PLLSAI_DIVR_DIVISOR)); + pllsaidivr(STM32_PLLSAI_POST_R_DIVISOR)); #else -#error "PLLSAI do not have R output on this SOC" +#error "PLLSAI doesn't have R output on this SOC" #endif -#endif /* STM32_PLLSAI_R_ENABLED && STM32_PLLSAI_DIVR_ENABLED */ +#endif /* STM32_PLLSAI_R_ENABLED && STM32_PLLSAI_POST_R_ENABLED */ } #endif /* STM32_PLLSAI_ENABLED */ diff --git a/include/zephyr/drivers/clock_control/stm32_clock_control.h b/include/zephyr/drivers/clock_control/stm32_clock_control.h index f5e438d7e5a6..b7283acb2048 100644 --- a/include/zephyr/drivers/clock_control/stm32_clock_control.h +++ b/include/zephyr/drivers/clock_control/stm32_clock_control.h @@ -179,9 +179,7 @@ /** PLL node related symbols */ -#if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll), st_stm32f2_pll_clock, okay) || \ - DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll), st_stm32f4_pll_clock, okay) || \ - DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll), st_stm32f7_pll_clock, okay) || \ +#if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll), st_stm32fx_pll_clock, okay) || \ DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll), st_stm32g0_pll_clock, okay) || \ DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll), st_stm32g4_pll_clock, okay) || \ DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll), st_stm32l4_pll_clock, okay) || \ @@ -201,52 +199,44 @@ #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_POST_R_ENABLED DT_NODE_HAS_PROP(DT_NODELABEL(pll), post_div_r) +#define STM32_PLL_POST_R_DIVISOR DT_PROP_OR(DT_NODELABEL(pll), post_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, 0) #endif -#if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(plli2s), st_stm32f4_plli2s_clock, okay) -#define STM32_PLLI2S_ENABLED 1 -#define STM32_PLLI2S_M_DIVISOR STM32_PLL_M_DIVISOR -#define STM32_PLLI2S_N_MULTIPLIER DT_PROP(DT_NODELABEL(plli2s), mul_n) -#define STM32_PLLI2S_R_ENABLED DT_NODE_HAS_PROP(DT_NODELABEL(plli2s), div_r) -#define STM32_PLLI2S_R_DIVISOR DT_PROP_OR(DT_NODELABEL(plli2s), div_r, 1) -#endif - -#if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(plli2s), st_stm32f411_plli2s_clock, okay) -#define STM32_PLLI2S_ENABLED 1 +#if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(plli2s), st_stm32fx_pll_clock, okay) +#define STM32_PLLI2S_ENABLED 1 #define STM32_PLLI2S_M_DIVISOR DT_PROP(DT_NODELABEL(plli2s), div_m) #define STM32_PLLI2S_N_MULTIPLIER DT_PROP(DT_NODELABEL(plli2s), mul_n) +#define STM32_PLLI2S_P_ENABLED DT_NODE_HAS_PROP(DT_NODELABEL(plli2s), div_p) +#define STM32_PLLI2S_P_DIVISOR DT_PROP_OR(DT_NODELABEL(plli2s), div_p, 1) #define STM32_PLLI2S_Q_ENABLED DT_NODE_HAS_PROP(DT_NODELABEL(plli2s), div_q) #define STM32_PLLI2S_Q_DIVISOR DT_PROP_OR(DT_NODELABEL(plli2s), div_q, 1) +#define STM32_PLLI2S_POST_Q_ENABLED DT_NODE_HAS_PROP(DT_NODELABEL(plli2s), post_div_q) +#define STM32_PLLI2S_POST_Q_DIVISOR DT_PROP_OR(DT_NODELABEL(plli2s), post_div_q, 1) #define STM32_PLLI2S_R_ENABLED DT_NODE_HAS_PROP(DT_NODELABEL(plli2s), div_r) #define STM32_PLLI2S_R_DIVISOR DT_PROP_OR(DT_NODELABEL(plli2s), div_r, 1) +#define STM32_PLLI2S_POST_R_ENABLED DT_NODE_HAS_PROP(DT_NODELABEL(plli2s), post_div_r) +#define STM32_PLLI2S_POST_R_DIVISOR DT_PROP_OR(DT_NODELABEL(plli2s), post_div_r, 1) #endif -#if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pllsai), st_stm32fx_pllsai_clock, okay) -#define STM32_PLLSAI_ENABLED 1 +#if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pllsai), st_stm32fx_pll_clock, okay) +#define STM32_PLLSAI_ENABLED 1 #define STM32_PLLSAI_M_DIVISOR DT_PROP(DT_NODELABEL(pllsai), div_m) #define STM32_PLLSAI_N_MULTIPLIER DT_PROP(DT_NODELABEL(pllsai), mul_n) #define STM32_PLLSAI_P_ENABLED DT_NODE_HAS_PROP(DT_NODELABEL(pllsai), div_p) #define STM32_PLLSAI_P_DIVISOR DT_PROP_OR(DT_NODELABEL(pllsai), div_p, 1) #define STM32_PLLSAI_Q_ENABLED DT_NODE_HAS_PROP(DT_NODELABEL(pllsai), div_q) -#define STM32_PLLSAI_DIVQ_ENABLED DT_NODE_HAS_PROP(DT_NODELABEL(pllsai), div_divq) -#if (STM32_PLLSAI_Q_ENABLED && !STM32_PLLSAI_DIVQ_ENABLED) || \ - (!STM32_PLLSAI_Q_ENABLED && STM32_PLLSAI_DIVQ_ENABLED) -#error "On STM32F4/STM32F7, both div_q and div_divq must be present if one of them is present" -#endif #define STM32_PLLSAI_Q_DIVISOR DT_PROP_OR(DT_NODELABEL(pllsai), div_q, 1) -#define STM32_PLLSAI_DIVQ_DIVISOR DT_PROP_OR(DT_NODELABEL(pllsai), div_divq, 1) +#define STM32_PLLSAI_POST_Q_ENABLED DT_NODE_HAS_PROP(DT_NODELABEL(pllsai), post_div_q) +#define STM32_PLLSAI_POST_Q_DIVISOR DT_PROP_OR(DT_NODELABEL(pllsai), post_div_q, 1) #define STM32_PLLSAI_R_ENABLED DT_NODE_HAS_PROP(DT_NODELABEL(pllsai), div_r) -#define STM32_PLLSAI_DIVR_ENABLED DT_NODE_HAS_PROP(DT_NODELABEL(pllsai), div_divr) -#if (STM32_PLLSAI_R_ENABLED && !STM32_PLLSAI_DIVR_ENABLED) || \ - (!STM32_PLLSAI_R_ENABLED && STM32_PLLSAI_DIVR_ENABLED) -#error "On STM32F4/STM32F7, both div_r and div_divr must be present if one of them is present" -#endif #define STM32_PLLSAI_R_DIVISOR DT_PROP_OR(DT_NODELABEL(pllsai), div_r, 1) -#define STM32_PLLSAI_DIVR_DIVISOR DT_PROP_OR(DT_NODELABEL(pllsai), div_divr, 1) +#define STM32_PLLSAI_POST_R_ENABLED DT_NODE_HAS_PROP(DT_NODELABEL(pllsai), post_div_r) +#define STM32_PLLSAI_POST_R_DIVISOR DT_PROP_OR(DT_NODELABEL(pllsai), post_div_r, 1) #endif #if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pllsai1), st_stm32l4_pllsai_clock, okay) @@ -464,6 +454,19 @@ #endif +/** PLLI2S clock source */ +#if DT_NODE_HAS_STATUS(DT_NODELABEL(plli2s), okay) && \ + DT_NODE_HAS_PROP(DT_NODELABEL(plli2s), clocks) +#define DT_PLLI2S_CLOCKS_CTRL DT_CLOCKS_CTLR(DT_NODELABEL(plli2s)) +#if DT_SAME_NODE(DT_PLLI2S_CLOCKS_CTRL, DT_NODELABEL(clk_hsi)) +#define STM32_PLLI2S_SRC_HSI 1 +#endif +#if DT_SAME_NODE(DT_PLLI2S_CLOCKS_CTRL, DT_NODELABEL(clk_hse)) +#define STM32_PLLI2S_SRC_HSE 1 +#endif + +#endif + /** PLLSAI clock source */ #if DT_NODE_HAS_STATUS(DT_NODELABEL(pllsai), okay) && \ DT_NODE_HAS_PROP(DT_NODELABEL(pllsai), clocks) @@ -509,20 +512,6 @@ #endif -/* On STM32F4 series - PLL and PLLSAI share the same source */ -#if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll), st_stm32f4_pll_clock, okay) && \ - DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pllsai), st_stm32fx_pllsai_clock, okay) && \ - !DT_SAME_NODE(DT_PLL_CLOCKS_CTRL, DT_PLLSAI_CLOCKS_CTRL) -#error "On STM32F4 series, PLL and PLLSAI must have the same source" -#endif - -/* On STM32F7 series - PLL and PLLSAI share the same source */ -#if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll), st_stm32f7_pll_clock, okay) && \ - DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pllsai), st_stm32fx_pllsai_clock, okay) && \ - !DT_SAME_NODE(DT_PLL_CLOCKS_CTRL, DT_PLLSAI_CLOCKS_CTRL) -#error "On STM32F7 series, PLL and PLLSAI must have the same source" -#endif - /* On STM32L4 series - PLL / PLLSAI1 and PLLSAI2 shared same source */ #if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll), st_stm32l4_pll_clock, okay) && \ DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pllsai1), st_stm32l4_pllsai_clock, okay) && \ From 21e433eed6ebfcfe9d41d5cf1cb413d6a23de736 Mon Sep 17 00:00:00 2001 From: Guillaume Gautier Date: Tue, 13 Jan 2026 08:56:42 +0100 Subject: [PATCH 2087/3659] include: drivers: clock: stm32: clean up indentation Clean up indentation for consistency. Signed-off-by: Guillaume Gautier --- .../clock_control/stm32_clock_control.h | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/include/zephyr/drivers/clock_control/stm32_clock_control.h b/include/zephyr/drivers/clock_control/stm32_clock_control.h index b7283acb2048..5c456f0481f5 100644 --- a/include/zephyr/drivers/clock_control/stm32_clock_control.h +++ b/include/zephyr/drivers/clock_control/stm32_clock_control.h @@ -190,21 +190,21 @@ 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) || \ DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll), st_stm32mp13_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) -#define STM32_PLL_P_ENABLED DT_NODE_HAS_PROP(DT_NODELABEL(pll), div_p) -#define STM32_PLL_P_DIVISOR DT_PROP_OR(DT_NODELABEL(pll), div_p, 1) -#define STM32_PLL_Q_ENABLED DT_NODE_HAS_PROP(DT_NODELABEL(pll), div_q) -#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_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) +#define STM32_PLL_P_ENABLED DT_NODE_HAS_PROP(DT_NODELABEL(pll), div_p) +#define STM32_PLL_P_DIVISOR DT_PROP_OR(DT_NODELABEL(pll), div_p, 1) +#define STM32_PLL_Q_ENABLED DT_NODE_HAS_PROP(DT_NODELABEL(pll), div_q) +#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_POST_R_ENABLED DT_NODE_HAS_PROP(DT_NODELABEL(pll), post_div_r) #define STM32_PLL_POST_R_DIVISOR DT_PROP_OR(DT_NODELABEL(pll), post_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, 0) +#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, 0) #endif #if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(plli2s), st_stm32fx_pll_clock, okay) From 4bf38ff694509dd389f3219767e2bd6b32411446 Mon Sep 17 00:00:00 2001 From: Guillaume Gautier Date: Tue, 9 Dec 2025 15:49:36 +0100 Subject: [PATCH 2088/3659] boards: stm32f4: add missing pll properties With the new PLL bindings, fixes a few board dts and overlays that are missing some properties. Signed-off-by: Guillaume Gautier --- boards/96boards/stm32_sensor_mez/96b_stm32_sensor_mez.dts | 1 + boards/st/stm32f4_disco/stm32f4_disco.dts | 2 ++ .../stm32_common_devices/boards/f4_i2s2_pll.overlay | 2 ++ .../src/test_stm32_clock_configuration_sdmmc.c | 2 +- 4 files changed, 6 insertions(+), 1 deletion(-) diff --git a/boards/96boards/stm32_sensor_mez/96b_stm32_sensor_mez.dts b/boards/96boards/stm32_sensor_mez/96b_stm32_sensor_mez.dts index d1f7d7ae4619..fe4f3e43d6bb 100644 --- a/boards/96boards/stm32_sensor_mez/96b_stm32_sensor_mez.dts +++ b/boards/96boards/stm32_sensor_mez/96b_stm32_sensor_mez.dts @@ -80,6 +80,7 @@ mul-n = <192>; div-r = <3>; div-q = <4>; + post-div-q = <1>; clocks = <&clk_hse>; status = "okay"; /* 48MHz on PLLI2SQ */ }; diff --git a/boards/st/stm32f4_disco/stm32f4_disco.dts b/boards/st/stm32f4_disco/stm32f4_disco.dts index 67b58aef8628..9f435039275c 100644 --- a/boards/st/stm32f4_disco/stm32f4_disco.dts +++ b/boards/st/stm32f4_disco/stm32f4_disco.dts @@ -200,8 +200,10 @@ zephyr_udc0: &usbotg_fs { * Note: because the PLLI2S is dependent on the main PLL, the latter * should not be changed without checking impact on PLLI2S */ + div-m = <8>; mul-n = <271>; div-r = <2>; + clocks = <&clk_hse>; status = "okay"; }; diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_devices/boards/f4_i2s2_pll.overlay b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_devices/boards/f4_i2s2_pll.overlay index c40ff7de2232..d478f43084d8 100644 --- a/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_devices/boards/f4_i2s2_pll.overlay +++ b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_devices/boards/f4_i2s2_pll.overlay @@ -64,8 +64,10 @@ }; &plli2s { + div-m = <8>; mul-n = <384>; div-r = <2>; + clocks = <&clk_hse>; status = "okay"; }; diff --git a/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_devices/src/test_stm32_clock_configuration_sdmmc.c b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_devices/src/test_stm32_clock_configuration_sdmmc.c index e8755adc4fa8..e2bc12d8920b 100644 --- a/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_devices/src/test_stm32_clock_configuration_sdmmc.c +++ b/tests/drivers/clock_control/stm32_clock_configuration/stm32_common_devices/src/test_stm32_clock_configuration_sdmmc.c @@ -20,7 +20,7 @@ #warning "Missing clock 48MHz" #endif -#if !DT_HAS_COMPAT_STATUS_OKAY(st_stm32f411_plli2s_clock) +#ifndef STM32_PLLI2S_ENABLED #warning "Missing clock I2S PLL clock" #endif From e5dbb600bce02272c100eb244c288521594f7371 Mon Sep 17 00:00:00 2001 From: Guillaume Gautier Date: Wed, 10 Dec 2025 08:32:53 +0100 Subject: [PATCH 2089/3659] include: dt-bindings: clock: stm32f4: rename clock sel macro Rename CLK48M_SEL to CK48M_SEL for consistency with stm32f410_clock.h. Signed-off-by: Guillaume Gautier --- boards/st/stm32f469i_disco/stm32f469i_disco.dts | 2 +- dts/arm/st/f4/stm32f469.dtsi | 2 +- include/zephyr/dt-bindings/clock/stm32f427_clock.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/boards/st/stm32f469i_disco/stm32f469i_disco.dts b/boards/st/stm32f469i_disco/stm32f469i_disco.dts index b2c25d421203..7f13e866ca37 100644 --- a/boards/st/stm32f469i_disco/stm32f469i_disco.dts +++ b/boards/st/stm32f469i_disco/stm32f469i_disco.dts @@ -162,7 +162,7 @@ zephyr_udc0: &usbotg_fs { &sdmmc1 { clocks = <&rcc STM32_CLOCK(APB2, 11)>, - <&rcc STM32_SRC_PLL_Q CLK48M_SEL(0)>; + <&rcc STM32_SRC_PLL_Q CK48M_SEL(0)>; status = "okay"; pinctrl-0 = <&sdio_d0_pc8 &sdio_d1_pc9 diff --git a/dts/arm/st/f4/stm32f469.dtsi b/dts/arm/st/f4/stm32f469.dtsi index 19ea883f1d0d..8628e1252cf7 100644 --- a/dts/arm/st/f4/stm32f469.dtsi +++ b/dts/arm/st/f4/stm32f469.dtsi @@ -19,7 +19,7 @@ usbotg_fs: usb@50000000 { num-bidir-endpoints = <6>; clocks = <&rcc STM32_CLOCK(AHB2, 7)>, - <&rcc STM32_SRC_PLL_Q CLK48M_SEL(0)>; + <&rcc STM32_SRC_PLL_Q CK48M_SEL(0)>; }; usbotg_hs: usb@40040000 { diff --git a/include/zephyr/dt-bindings/clock/stm32f427_clock.h b/include/zephyr/dt-bindings/clock/stm32f427_clock.h index e4f520a805cb..d10e0080c891 100644 --- a/include/zephyr/dt-bindings/clock/stm32f427_clock.h +++ b/include/zephyr/dt-bindings/clock/stm32f427_clock.h @@ -17,7 +17,7 @@ #define CKDFSDM1A_SEL(val) STM32_DT_CLOCK_SELECT((val), 15, 15, DCKCFGR_REG) #define SAI1A_SEL(val) STM32_DT_CLOCK_SELECT((val), 21, 20, DCKCFGR_REG) #define SAI1B_SEL(val) STM32_DT_CLOCK_SELECT((val), 23, 22, DCKCFGR_REG) -#define CLK48M_SEL(val) STM32_DT_CLOCK_SELECT((val), 27, 27, DCKCFGR_REG) +#define CK48M_SEL(val) STM32_DT_CLOCK_SELECT((val), 27, 27, DCKCFGR_REG) #define SDMMC_SEL(val) STM32_DT_CLOCK_SELECT((val), 28, 28, DCKCFGR_REG) #define DSI_SEL(val) STM32_DT_CLOCK_SELECT((val), 29, 29, DCKCFGR_REG) From 4536b15bcac72f107e4f56fa23c317cfda60c372 Mon Sep 17 00:00:00 2001 From: Guillaume Gautier Date: Tue, 9 Dec 2025 16:07:42 +0100 Subject: [PATCH 2090/3659] drivers: clock: stm32f2_f4_f7: move get_ck48_frequency function Move get_ck48_frequency function outside of the #if STM32_PLL_ENABLED because it should be usable even if the main PLL is not used. The mux can indeed be used with PLLI2S. Signed-off-by: Guillaume Gautier --- drivers/clock_control/clock_stm32f2_f4_f7.c | 75 ++++++++++----------- 1 file changed, 35 insertions(+), 40 deletions(-) diff --git a/drivers/clock_control/clock_stm32f2_f4_f7.c b/drivers/clock_control/clock_stm32f2_f4_f7.c index 66de022c755d..ed56488e2ba9 100644 --- a/drivers/clock_control/clock_stm32f2_f4_f7.c +++ b/drivers/clock_control/clock_stm32f2_f4_f7.c @@ -117,46 +117,6 @@ uint32_t get_pllsrc_frequency(void) return 0; } -#if defined(STM32_CK48_ENABLED) -/** - * @brief calculate the CK48 frequency depending on its clock source - */ -__unused -uint32_t get_ck48_frequency(void) -{ - uint32_t source; - - if (LL_RCC_GetCK48MClockSource(LL_RCC_CK48M_CLKSOURCE) == - LL_RCC_CK48M_CLKSOURCE_PLL) { - /* Get the PLL48CK source : HSE or HSI */ - source = (LL_RCC_PLL_GetMainSource() == LL_RCC_PLLSOURCE_HSE) - ? HSE_VALUE - : HSI_VALUE; - /* Get the PLL48CK Q freq. No HAL macro for that */ - return __LL_RCC_CALC_PLLCLK_48M_FREQ(source, - LL_RCC_PLL_GetDivider(), - LL_RCC_PLL_GetN(), - LL_RCC_PLL_GetQ() - ); - } else if (LL_RCC_GetCK48MClockSource(LL_RCC_CK48M_CLKSOURCE) == - LL_RCC_CK48M_CLKSOURCE_PLLI2S) { - /* Get the PLL I2S source : HSE or HSI */ - source = (LL_RCC_PLLI2S_GetMainSource() == LL_RCC_PLLSOURCE_HSE) - ? HSE_VALUE - : HSI_VALUE; - /* Get the PLL I2S Q freq. No HAL macro for that */ - return __LL_RCC_CALC_PLLI2S_48M_FREQ(source, - LL_RCC_PLLI2S_GetDivider(), - LL_RCC_PLLI2S_GetN(), - LL_RCC_PLLI2S_GetQ() - ); - } - - __ASSERT(0, "Invalid source"); - return 0; -} -#endif - /** * @brief Set up pll configuration */ @@ -409,6 +369,41 @@ void config_pllsai(void) #endif /* STM32_PLLSAI_ENABLED */ +#ifdef STM32_CK48_ENABLED +/** + * @brief calculate the CK48 frequency depending on its clock source + */ +__unused +uint32_t get_ck48_frequency(void) +{ + uint32_t source = LL_RCC_GetCK48MClockSource(LL_RCC_CK48M_CLKSOURCE); + + if (source == LL_RCC_CK48M_CLKSOURCE_PLL) { + /* Get the PLL48CK source : HSE or HSI */ + source = (LL_RCC_PLL_GetMainSource() == LL_RCC_PLLSOURCE_HSE) ? + HSE_VALUE : HSI_VALUE; + /* Get the PLL48CK Q freq. No HAL macro for that */ + return __LL_RCC_CALC_PLLCLK_48M_FREQ(source, + LL_RCC_PLL_GetDivider(), + LL_RCC_PLL_GetN(), + LL_RCC_PLL_GetQ()); + } else if (source == LL_RCC_CK48M_CLKSOURCE_PLLI2S) { + /* Get the PLL I2S source : HSE or HSI */ + source = (LL_RCC_PLLI2S_GetMainSource() == LL_RCC_PLLSOURCE_HSE) ? + HSE_VALUE : HSI_VALUE; + /* Get the PLL I2S Q freq. No HAL macro for that */ + return __LL_RCC_CALC_PLLI2S_48M_FREQ(source, + LL_RCC_PLLI2S_GetDivider(), + LL_RCC_PLLI2S_GetN(), + LL_RCC_PLLI2S_GetQ()); + } else { + __ASSERT(0, "Invalid source"); + } + + return 0; +} +#endif + /** * @brief Activate default clocks */ From a26ad94d826c09d513852a9970465f8aa12327b8 Mon Sep 17 00:00:00 2001 From: Guillaume Gautier Date: Tue, 9 Dec 2025 16:13:30 +0100 Subject: [PATCH 2091/3659] drivers: clock: stm32f2_f4_f7: extend get_ck48_frequency function On STM32F446, F469, F479 and on STM32F7x, the CK48M mux can have either PLL Q or PLLSAI P as input. Adds the support for the PLLSAI P input in the driver. Signed-off-by: Guillaume Gautier --- drivers/clock_control/clock_stm32f2_f4_f7.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/clock_control/clock_stm32f2_f4_f7.c b/drivers/clock_control/clock_stm32f2_f4_f7.c index ed56488e2ba9..70dcb2f9ce99 100644 --- a/drivers/clock_control/clock_stm32f2_f4_f7.c +++ b/drivers/clock_control/clock_stm32f2_f4_f7.c @@ -387,6 +387,7 @@ uint32_t get_ck48_frequency(void) LL_RCC_PLL_GetDivider(), LL_RCC_PLL_GetN(), LL_RCC_PLL_GetQ()); +#ifdef LL_RCC_CK48M_CLKSOURCE_PLLI2S } else if (source == LL_RCC_CK48M_CLKSOURCE_PLLI2S) { /* Get the PLL I2S source : HSE or HSI */ source = (LL_RCC_PLLI2S_GetMainSource() == LL_RCC_PLLSOURCE_HSE) ? @@ -396,6 +397,18 @@ uint32_t get_ck48_frequency(void) LL_RCC_PLLI2S_GetDivider(), LL_RCC_PLLI2S_GetN(), LL_RCC_PLLI2S_GetQ()); +#endif /* LL_RCC_CK48M_CLKSOURCE_PLLI2S */ +#ifdef LL_RCC_CK48M_CLKSOURCE_PLLSAI + } else if (source == LL_RCC_CK48M_CLKSOURCE_PLLSAI) { + /* Get the PLL SAI source : HSE or HSI */ + source = (LL_RCC_PLLSAI_GetMainSource() == LL_RCC_PLLSOURCE_HSE) ? + HSE_VALUE : HSI_VALUE; + /* Get the PLL SAI P freq. No HAL macro for that */ + return __LL_RCC_CALC_PLLSAI_48M_FREQ(source, + LL_RCC_PLLSAI_GetDivider(), + LL_RCC_PLLSAI_GetN(), + LL_RCC_PLLSAI_GetP()); +#endif /* LL_RCC_CK48M_CLKSOURCE_PLLSAI */ } else { __ASSERT(0, "Invalid source"); } From 911d6905d059452de1b5f20307608ea64eb2a87f Mon Sep 17 00:00:00 2001 From: Guillaume Gautier Date: Tue, 9 Dec 2025 16:23:14 +0100 Subject: [PATCH 2092/3659] dts: arm: st: add clk48 clock mux for f446, f469, f479 and f7 For STM32F446, F469, F479 and F7x, add the clk48 node in the dtsi. This allows configuring the clock source of the CLK48 clock. It is necessary to add it for the SDIO peripheral that can have either SYSCLK or CLK48 as clock source. Signed-off-by: Guillaume Gautier --- dts/arm/st/f4/stm32f446.dtsi | 7 +++++++ dts/arm/st/f4/stm32f469.dtsi | 9 +++++++++ dts/arm/st/f7/stm32f7.dtsi | 7 +++++++ 3 files changed, 23 insertions(+) diff --git a/dts/arm/st/f4/stm32f446.dtsi b/dts/arm/st/f4/stm32f446.dtsi index 763d33a40a36..067bd91811e7 100644 --- a/dts/arm/st/f4/stm32f446.dtsi +++ b/dts/arm/st/f4/stm32f446.dtsi @@ -16,6 +16,13 @@ #clock-cells = <0>; status = "disabled"; }; + + clk48: clk48 { + #clock-cells = <0>; + compatible = "st,stm32-clock-mux"; + clocks = <&rcc STM32_SRC_PLL_Q CK48M_SEL(0)>; + status = "disabled"; + }; }; soc { diff --git a/dts/arm/st/f4/stm32f469.dtsi b/dts/arm/st/f4/stm32f469.dtsi index 8628e1252cf7..7d1ed71513da 100644 --- a/dts/arm/st/f4/stm32f469.dtsi +++ b/dts/arm/st/f4/stm32f469.dtsi @@ -8,6 +8,15 @@ #include / { + clocks { + clk48: clk48 { + #clock-cells = <0>; + compatible = "st,stm32-clock-mux"; + clocks = <&rcc STM32_SRC_PLL_Q CK48M_SEL(0)>; + status = "disabled"; + }; + }; + soc { compatible = "st,stm32f469", "st,stm32f4", "simple-bus"; diff --git a/dts/arm/st/f7/stm32f7.dtsi b/dts/arm/st/f7/stm32f7.dtsi index be818d2edcab..c68f62f55a0f 100644 --- a/dts/arm/st/f7/stm32f7.dtsi +++ b/dts/arm/st/f7/stm32f7.dtsi @@ -100,6 +100,13 @@ #clock-cells = <0>; status = "disabled"; }; + + clk48: clk48 { + #clock-cells = <0>; + compatible = "st,stm32-clock-mux"; + clocks = <&rcc STM32_SRC_PLL_Q CK48M_SEL(0)>; + status = "disabled"; + }; }; mcos { From 3e7fa6c5e9046e8d83330fa9bf28a583ed6f3696 Mon Sep 17 00:00:00 2001 From: Guillaume Gautier Date: Tue, 13 Jan 2026 10:39:59 +0100 Subject: [PATCH 2093/3659] drivers: clock: stm32_f2_f4_f7: remove __unused from exported functions Remove the __unused keyword from exported functions. Signed-off-by: Guillaume Gautier --- drivers/clock_control/clock_stm32f2_f4_f7.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/clock_control/clock_stm32f2_f4_f7.c b/drivers/clock_control/clock_stm32f2_f4_f7.c index 70dcb2f9ce99..557b853a8141 100644 --- a/drivers/clock_control/clock_stm32f2_f4_f7.c +++ b/drivers/clock_control/clock_stm32f2_f4_f7.c @@ -104,7 +104,6 @@ static uint32_t get_pll_source(void) /** * @brief get the pll source frequency */ -__unused uint32_t get_pllsrc_frequency(void) { if (IS_ENABLED(STM32_PLL_SRC_HSI)) { @@ -120,7 +119,6 @@ uint32_t get_pllsrc_frequency(void) /** * @brief Set up pll configuration */ -__unused void config_pll_sysclock(void) { #if STM32_PLL_P_ENABLED @@ -218,7 +216,6 @@ static uint32_t get_plli2s_source(void) /** * @brief Get the PLLI2S source frequency */ -__unused uint32_t get_plli2ssrc_frequency(void) { if (IS_ENABLED(STM32_PLLI2S_SRC_HSI)) { @@ -234,7 +231,6 @@ uint32_t get_plli2ssrc_frequency(void) /** * @brief Set up PLL I2S configuration */ -__unused void config_plli2s(void) { #if STM32_PLLI2S_P_ENABLED @@ -312,7 +308,6 @@ static uint32_t get_pllsai_source(void) /** * @brief Get the PLLSAI source frequency */ -__unused uint32_t get_pllsaisrc_frequency(void) { if (IS_ENABLED(STM32_PLLSAI_SRC_HSI)) { @@ -328,7 +323,6 @@ uint32_t get_pllsaisrc_frequency(void) /** * @brief Set up PLLSAI configuration */ -__unused void config_pllsai(void) { #if STM32_PLLSAI_P_ENABLED @@ -373,7 +367,6 @@ void config_pllsai(void) /** * @brief calculate the CK48 frequency depending on its clock source */ -__unused uint32_t get_ck48_frequency(void) { uint32_t source = LL_RCC_GetCK48MClockSource(LL_RCC_CK48M_CLKSOURCE); From c62748a9e08fea75c1e88cb74abd499b5a151832 Mon Sep 17 00:00:00 2001 From: Guillaume Gautier Date: Wed, 14 Jan 2026 08:46:46 +0100 Subject: [PATCH 2094/3659] doc: releases: migration guide: add a note for stm32f2/f4/f7 pll rework Add a note for the STM32F2/F4/F7 PLL clock rework in the migration guide. Signed-off-by: Guillaume Gautier --- doc/releases/migration-guide-4.4.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/doc/releases/migration-guide-4.4.rst b/doc/releases/migration-guide-4.4.rst index fb8b1ad773c7..d50c6e09dce4 100644 --- a/doc/releases/migration-guide-4.4.rst +++ b/doc/releases/migration-guide-4.4.rst @@ -563,6 +563,15 @@ STM32 The previous ``swap using move`` mode can still be selected in sysbuild by enabling :kconfig:option:`SB_CONFIG_MCUBOOT_MODE_SWAP_USING_MOVE`. +* For STM32F2x/F4x/F7x, the different PLL bindings (:dtcompatible:`st,stm32f2-pll-clock`, + :dtcompatible:`st,stm32f4-pll-clock`, :dtcompatible:`st,stm32f4-plli2s-clock`, + :dtcompatible:`st,stm32f411-plli2s-clock`, :dtcompatible:`st,stm32f7-pll-clock` and + :dtcompatible:`st,stm32fx-pllsai-clock` ) has been merged into a single one + :dtcompatible:`st,stm32fx-pll-clock`. This merge brings some changes, notably ``div-divq`` and + ``div-divr`` properties have been renamed respectively to ``post-div-q`` and ``post-div-r``. + Besides, when applicable to the SoC, these properties need to be defined if the corresponding + ``div-q`` or ``div-r`` properties are used. + USB === From 60c1970c4d022639b3511f2b8837dfc0783c5a23 Mon Sep 17 00:00:00 2001 From: Eve Redero Date: Mon, 22 Dec 2025 22:36:32 +0100 Subject: [PATCH 2095/3659] doc: build: use dt_freq_m in example Example dts should use dt_freq_m instead of lots of zeros. Signed-off-by: Eve Redero --- doc/build/dts/howtos.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/build/dts/howtos.rst b/doc/build/dts/howtos.rst index def093f40784..4fa0cffa9972 100644 --- a/doc/build/dts/howtos.rst +++ b/doc/build/dts/howtos.rst @@ -362,7 +362,7 @@ child device on an existing bus node, do something like this: /* Configure other SPI device properties as needed. * Find your device's DT binding for details. */ - spi-max-frequency = <4000000>; + spi-max-frequency = ; }; }; From dd2dedf3430d1966bb671c20353122e13c08a461 Mon Sep 17 00:00:00 2001 From: Martin Moya Date: Mon, 12 Jan 2026 15:40:00 -0300 Subject: [PATCH 2096/3659] sensor: bosch: bma4xx: add attr_get to device API This feature allows the user to get the chip's id from the sensor's API easily Signed-off-by: Martin Moya --- drivers/sensor/bosch/bma4xx/bma4xx.c | 27 +++++++++++++++++++++++ drivers/sensor/bosch/bma4xx/bma4xx_defs.h | 1 + include/zephyr/drivers/sensor.h | 2 ++ 3 files changed, 30 insertions(+) diff --git a/drivers/sensor/bosch/bma4xx/bma4xx.c b/drivers/sensor/bosch/bma4xx/bma4xx.c index 543224716f66..73bc583019e3 100644 --- a/drivers/sensor/bosch/bma4xx/bma4xx.c +++ b/drivers/sensor/bosch/bma4xx/bma4xx.c @@ -275,6 +275,17 @@ static int bma4xx_chip_init(const struct device *dev) } LOG_DBG("chip_id is 0x%02x", bma4xx->chip_id); + switch (bma4xx->chip_id) { + case BMA4XX_CHIP_ID_BMA423: + LOG_WRN("Driver tested for BMA422/BMA400. Check for unintended operation."); + case BMA4XX_CHIP_ID_BMA400: + case BMA4XX_CHIP_ID_BMA422: + break; + default: + LOG_ERR("Chip id (0x%02X) not supported", bma4xx->chip_id); + return -ENODEV; + } + if (bma4xx->chip_id != BMA4XX_CHIP_ID_BMA422) { LOG_WRN("Driver tested for BMA422. Check for unintended operation."); } @@ -308,11 +319,27 @@ static int bma4xx_chip_init(const struct device *dev) return 0; } +static int bma4xx_attr_get(const struct device *dev, enum sensor_channel chan, + enum sensor_attribute attr, struct sensor_value *val) +{ + struct bma4xx_data *bma4xx = dev->data; + + switch (attr) { + case SENSOR_ATTR_CHIP_ID: + val->val1 = bma4xx->chip_id; + return 0; + default: + LOG_ERR("Attribute not supported"); + return -EINVAL; + } +} + /* * Sensor driver API */ static DEVICE_API(sensor, bma4xx_driver_api) = { + .attr_get = bma4xx_attr_get, .attr_set = bma4xx_attr_set, .get_decoder = bma4xx_get_decoder, .submit = bma4xx_submit, diff --git a/drivers/sensor/bosch/bma4xx/bma4xx_defs.h b/drivers/sensor/bosch/bma4xx/bma4xx_defs.h index 243b8eafd3e8..3b5b1931cc56 100644 --- a/drivers/sensor/bosch/bma4xx/bma4xx_defs.h +++ b/drivers/sensor/bosch/bma4xx/bma4xx_defs.h @@ -173,6 +173,7 @@ /* BMA4xx chip id */ #define BMA4XX_CHIP_ID_BMA422 (0x12) #define BMA4XX_CHIP_ID_BMA423 (0x13) +#define BMA4XX_CHIP_ID_BMA400 (0x90) #define BMA4XX_REG_I2C_READ_BIT BIT(7) diff --git a/include/zephyr/drivers/sensor.h b/include/zephyr/drivers/sensor.h index dff01990bb08..c67fea68e2a8 100644 --- a/include/zephyr/drivers/sensor.h +++ b/include/zephyr/drivers/sensor.h @@ -374,6 +374,8 @@ enum sensor_attribute { SENSOR_ATTR_GAIN, /* Configure the resolution of a sensor. */ SENSOR_ATTR_RESOLUTION, + /* Chip ID of the sensor*/ + SENSOR_ATTR_CHIP_ID, /** * Number of all common sensor attributes. */ From c057340a8686d171869bf266072637d2a5166dbf Mon Sep 17 00:00:00 2001 From: Tomas Galbicka Date: Wed, 14 Jan 2026 12:05:28 +0100 Subject: [PATCH 2097/3659] soc: RT600 DSP Hifi4 enable cache handling This commit adds cache handling for Hifi4 core on RT600. Enable CACHE_MANAGEMENT and HAS_DCACHE. This is required for proper data coherency when the DSP shares memory with other cores (e.g., Cortex-M33) or DMA peripherals. With this change, applications can now use sys_cache_data_flush_range() and sys_cache_data_invd_range() to ensure cache coherency in shared memory scenarios. Signed-off-by: Tomas Galbicka --- soc/nxp/imxrt/imxrt6xx/Kconfig | 2 ++ soc/nxp/imxrt/imxrt6xx/Kconfig.defconfig | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/soc/nxp/imxrt/imxrt6xx/Kconfig b/soc/nxp/imxrt/imxrt6xx/Kconfig index bdc600d74ded..b8961f43c648 100644 --- a/soc/nxp/imxrt/imxrt6xx/Kconfig +++ b/soc/nxp/imxrt/imxrt6xx/Kconfig @@ -30,6 +30,8 @@ config SOC_MIMXRT685S_HIFI4 select HAS_MCUX select SOC_EARLY_INIT_HOOK select NXP_INPUTMUX + select CACHE_MANAGEMENT + select CPU_HAS_DCACHE if SOC_SERIES_IMXRT6XX diff --git a/soc/nxp/imxrt/imxrt6xx/Kconfig.defconfig b/soc/nxp/imxrt/imxrt6xx/Kconfig.defconfig index 895783aa7c91..4d391db16b48 100644 --- a/soc/nxp/imxrt/imxrt6xx/Kconfig.defconfig +++ b/soc/nxp/imxrt/imxrt6xx/Kconfig.defconfig @@ -74,4 +74,8 @@ config SYS_CLOCK_HW_CYCLES_PER_SEC config MCUX_CORE_SUFFIX default "_dsp" +# Must match XCHAL_DCACHE_LINESIZE from core-isa.h +config DCACHE_LINE_SIZE + default 256 + endif # SOC_MIMXRT685S_HIFI4 From 143fa22b4d8b109fa4d08852eedeb0f9593d9a70 Mon Sep 17 00:00:00 2001 From: Alain Volmat Date: Wed, 14 Jan 2026 14:35:25 +0100 Subject: [PATCH 2098/3659] samples: lvgl: demos: remove CONFIG_INPUT from st25dv_mb1283_disco.conf CONFIG_INPUT=y is already part of the demos sample prj.conf file so it is not necessary to have it enabled in the st25dv_mb1283_disco board specific conf file. Signed-off-by: Alain Volmat --- samples/modules/lvgl/demos/boards/st25dv_mb1283_disco.conf | 1 - 1 file changed, 1 deletion(-) diff --git a/samples/modules/lvgl/demos/boards/st25dv_mb1283_disco.conf b/samples/modules/lvgl/demos/boards/st25dv_mb1283_disco.conf index e5f19abc888f..c14d92acb8f3 100644 --- a/samples/modules/lvgl/demos/boards/st25dv_mb1283_disco.conf +++ b/samples/modules/lvgl/demos/boards/st25dv_mb1283_disco.conf @@ -1,3 +1,2 @@ CONFIG_LV_COLOR_DEPTH_32=y CONFIG_GPIO=y -CONFIG_INPUT=y From 2619ef5e5fc38c2d91095f9cae22cb445e724ec1 Mon Sep 17 00:00:00 2001 From: Alain Volmat Date: Wed, 14 Jan 2026 14:39:31 +0100 Subject: [PATCH 2099/3659] samples: display: lvgl: make CONFIG_INPUT common in prj.conf Always enable the CONFIG_INPUT in the project since it is trying to use inputs, and let inside the application figure out if there is really an input device available or not to either simply draw a label or a button with a label. This also allow avoid need to have board specific conf file just to enable CONFIG_INPUT as well has allow to use shields which embed touchpanels. Signed-off-by: Alain Volmat --- samples/subsys/display/lvgl/boards/native_sim.conf | 1 - samples/subsys/display/lvgl/boards/st25dv_mb1283_disco.conf | 1 - samples/subsys/display/lvgl/boards/stm32f469i_disco.conf | 5 ----- samples/subsys/display/lvgl/boards/wio_terminal.conf | 1 - samples/subsys/display/lvgl/prj.conf | 2 ++ 5 files changed, 2 insertions(+), 8 deletions(-) delete mode 100644 samples/subsys/display/lvgl/boards/stm32f469i_disco.conf delete mode 100644 samples/subsys/display/lvgl/boards/wio_terminal.conf diff --git a/samples/subsys/display/lvgl/boards/native_sim.conf b/samples/subsys/display/lvgl/boards/native_sim.conf index e5f19abc888f..c14d92acb8f3 100644 --- a/samples/subsys/display/lvgl/boards/native_sim.conf +++ b/samples/subsys/display/lvgl/boards/native_sim.conf @@ -1,3 +1,2 @@ CONFIG_LV_COLOR_DEPTH_32=y CONFIG_GPIO=y -CONFIG_INPUT=y diff --git a/samples/subsys/display/lvgl/boards/st25dv_mb1283_disco.conf b/samples/subsys/display/lvgl/boards/st25dv_mb1283_disco.conf index e5f19abc888f..c14d92acb8f3 100644 --- a/samples/subsys/display/lvgl/boards/st25dv_mb1283_disco.conf +++ b/samples/subsys/display/lvgl/boards/st25dv_mb1283_disco.conf @@ -1,3 +1,2 @@ CONFIG_LV_COLOR_DEPTH_32=y CONFIG_GPIO=y -CONFIG_INPUT=y diff --git a/samples/subsys/display/lvgl/boards/stm32f469i_disco.conf b/samples/subsys/display/lvgl/boards/stm32f469i_disco.conf deleted file mode 100644 index c93c2efa4dfb..000000000000 --- a/samples/subsys/display/lvgl/boards/stm32f469i_disco.conf +++ /dev/null @@ -1,5 +0,0 @@ -# Copyright (c) Philippe Peurichard -# SPDX-License-Identifier: Apache-2.0 - -# Enable Input driver for touch screen -CONFIG_INPUT=y diff --git a/samples/subsys/display/lvgl/boards/wio_terminal.conf b/samples/subsys/display/lvgl/boards/wio_terminal.conf deleted file mode 100644 index de103d88fedb..000000000000 --- a/samples/subsys/display/lvgl/boards/wio_terminal.conf +++ /dev/null @@ -1 +0,0 @@ -CONFIG_INPUT=y diff --git a/samples/subsys/display/lvgl/prj.conf b/samples/subsys/display/lvgl/prj.conf index 2d7f2f196f24..2b2ccc3aa4b3 100644 --- a/samples/subsys/display/lvgl/prj.conf +++ b/samples/subsys/display/lvgl/prj.conf @@ -5,6 +5,8 @@ CONFIG_MAIN_STACK_SIZE=4096 CONFIG_DISPLAY=y CONFIG_DISPLAY_LOG_LEVEL_ERR=y +CONFIG_INPUT=y + CONFIG_LOG=y CONFIG_SHELL=y From 4711521016b62368781e3cc0a7f92622034274fc Mon Sep 17 00:00:00 2001 From: Alain Volmat Date: Wed, 14 Jan 2026 14:55:37 +0100 Subject: [PATCH 2100/3659] boards: st: avoid enabling CONFIG_INPUT in board/shield defconfig Usage or not of the input subsystem is an application decision hence boards or shields defconfig should not force it, even if there might be a touchpanel available on the board. This commit remove enabling of CONFIG_INPUT in ST shields / boards. This shouldn't have impact on in-tree application since LVGL samples already enable CONFIG_INPUT. Signed-off-by: Alain Volmat --- boards/shields/st_b_lcd40_dsi1_mb1166/Kconfig.defconfig | 3 --- boards/shields/st_lcd_dsi_mb1835/Kconfig.defconfig | 3 --- boards/st/stm32f429i_disc1/Kconfig.defconfig | 3 --- boards/st/stm32f746g_disco/Kconfig.defconfig | 3 --- boards/st/stm32f7508_dk/Kconfig.defconfig | 3 --- boards/st/stm32f769i_disco/Kconfig.defconfig | 3 --- boards/st/stm32h573i_dk/Kconfig.defconfig | 3 --- boards/st/stm32h7b3i_dk/Kconfig.defconfig | 3 --- boards/st/stm32l562e_dk/Kconfig.defconfig | 3 --- boards/st/stm32n6570_dk/Kconfig.defconfig | 3 --- 10 files changed, 30 deletions(-) diff --git a/boards/shields/st_b_lcd40_dsi1_mb1166/Kconfig.defconfig b/boards/shields/st_b_lcd40_dsi1_mb1166/Kconfig.defconfig index 5c734b992f38..344ddf2a796f 100644 --- a/boards/shields/st_b_lcd40_dsi1_mb1166/Kconfig.defconfig +++ b/boards/shields/st_b_lcd40_dsi1_mb1166/Kconfig.defconfig @@ -8,9 +8,6 @@ orsource "boards/*.defconfig" if LVGL -config INPUT - default y - config LV_Z_BITS_PER_PIXEL default 32 diff --git a/boards/shields/st_lcd_dsi_mb1835/Kconfig.defconfig b/boards/shields/st_lcd_dsi_mb1835/Kconfig.defconfig index 76b0d6cc180e..ec63817f0d11 100644 --- a/boards/shields/st_lcd_dsi_mb1835/Kconfig.defconfig +++ b/boards/shields/st_lcd_dsi_mb1835/Kconfig.defconfig @@ -7,9 +7,6 @@ orsource "boards/*.defconfig" if LVGL -config INPUT - default y - config LV_Z_BITS_PER_PIXEL default 32 diff --git a/boards/st/stm32f429i_disc1/Kconfig.defconfig b/boards/st/stm32f429i_disc1/Kconfig.defconfig index 1d783097dad4..df3fb60a015a 100644 --- a/boards/st/stm32f429i_disc1/Kconfig.defconfig +++ b/boards/st/stm32f429i_disc1/Kconfig.defconfig @@ -5,9 +5,6 @@ if BOARD_STM32F429I_DISC1 -config INPUT - default y if DISPLAY - config MEMC default y if DISPLAY diff --git a/boards/st/stm32f746g_disco/Kconfig.defconfig b/boards/st/stm32f746g_disco/Kconfig.defconfig index a849b3018ffd..7c4254b20e96 100644 --- a/boards/st/stm32f746g_disco/Kconfig.defconfig +++ b/boards/st/stm32f746g_disco/Kconfig.defconfig @@ -8,9 +8,6 @@ if BOARD_STM32F746G_DISCO configdefault NET_L2_ETHERNET default y -config INPUT - default y if LVGL - if DISPLAY # MEMC needs to be enabled in order to store diff --git a/boards/st/stm32f7508_dk/Kconfig.defconfig b/boards/st/stm32f7508_dk/Kconfig.defconfig index a055d88790d6..19174da98b8e 100644 --- a/boards/st/stm32f7508_dk/Kconfig.defconfig +++ b/boards/st/stm32f7508_dk/Kconfig.defconfig @@ -17,7 +17,4 @@ config MEMC endif # DISPLAY -config INPUT - default y if LVGL - endif # BOARD_STM32F7508_DK diff --git a/boards/st/stm32f769i_disco/Kconfig.defconfig b/boards/st/stm32f769i_disco/Kconfig.defconfig index 47c71704e7eb..be94784e1386 100644 --- a/boards/st/stm32f769i_disco/Kconfig.defconfig +++ b/boards/st/stm32f769i_disco/Kconfig.defconfig @@ -9,9 +9,6 @@ config SPI_STM32_INTERRUPT default y depends on SPI -config INPUT - default y if LVGL - configdefault NET_L2_ETHERNET default y diff --git a/boards/st/stm32h573i_dk/Kconfig.defconfig b/boards/st/stm32h573i_dk/Kconfig.defconfig index 19258057d180..8d1a96b9d8db 100644 --- a/boards/st/stm32h573i_dk/Kconfig.defconfig +++ b/boards/st/stm32h573i_dk/Kconfig.defconfig @@ -23,9 +23,6 @@ endchoice config REGULATOR default y -config INPUT - default y if LVGL - config I2C_STM32_V2_TIMING default y if INPUT diff --git a/boards/st/stm32h7b3i_dk/Kconfig.defconfig b/boards/st/stm32h7b3i_dk/Kconfig.defconfig index 54b2cbb20a7b..5749015f137b 100644 --- a/boards/st/stm32h7b3i_dk/Kconfig.defconfig +++ b/boards/st/stm32h7b3i_dk/Kconfig.defconfig @@ -6,9 +6,6 @@ if BOARD_STM32H7B3I_DK -config INPUT - default y if LVGL - # MEMC needs to be enabled in order to store # display buffer to external SDRAM connected to FMC config MEMC diff --git a/boards/st/stm32l562e_dk/Kconfig.defconfig b/boards/st/stm32l562e_dk/Kconfig.defconfig index ef0832f6c9fa..99056537fbe8 100644 --- a/boards/st/stm32l562e_dk/Kconfig.defconfig +++ b/boards/st/stm32l562e_dk/Kconfig.defconfig @@ -30,9 +30,6 @@ endchoice endif # DISPLAY -config INPUT - default y if LVGL - if INPUT config INPUT_FT5336_INTERRUPT diff --git a/boards/st/stm32n6570_dk/Kconfig.defconfig b/boards/st/stm32n6570_dk/Kconfig.defconfig index d1319ca0a9d1..b078ade8a6af 100644 --- a/boards/st/stm32n6570_dk/Kconfig.defconfig +++ b/boards/st/stm32n6570_dk/Kconfig.defconfig @@ -16,9 +16,6 @@ config MEMC endif # DISPLAY || VIDEO if DISPLAY -config INPUT - default y - config I2C_STM32_V2_TIMING default y if INPUT endif # DISPLAY From 11f7d3be2fc951c9ab1ecf87fc444fbbe80bd04f Mon Sep 17 00:00:00 2001 From: Fabrice DJIATSA Date: Thu, 15 Jan 2026 15:17:44 +0100 Subject: [PATCH 2101/3659] tests: drivers: rtc: rtc_api: remove alarm support from wb09ke Alarms are not supported due to RTC interrupt not triggered in Run mode erratum. Delete the overlay since RTC node already defined in the board dts. Signed-off-by: Fabrice DJIATSA --- tests/drivers/rtc/rtc_api/boards/nucleo_wb09ke.conf | 4 +++- .../drivers/rtc/rtc_api/boards/nucleo_wb09ke.overlay | 11 ----------- 2 files changed, 3 insertions(+), 12 deletions(-) delete mode 100644 tests/drivers/rtc/rtc_api/boards/nucleo_wb09ke.overlay diff --git a/tests/drivers/rtc/rtc_api/boards/nucleo_wb09ke.conf b/tests/drivers/rtc/rtc_api/boards/nucleo_wb09ke.conf index 8c6c114ee41f..cabd3c618778 100644 --- a/tests/drivers/rtc/rtc_api/boards/nucleo_wb09ke.conf +++ b/tests/drivers/rtc/rtc_api/boards/nucleo_wb09ke.conf @@ -1,2 +1,4 @@ CONFIG_RTC_CALIBRATION=y -CONFIG_RTC_ALARM=y +# RTC alarms disabled due to STM32WB09xE erratum ES0584 §2.5.2: +# RTC interrupts may be lost in Run mode (LSI/LSE clock) +CONFIG_RTC_ALARM=n diff --git a/tests/drivers/rtc/rtc_api/boards/nucleo_wb09ke.overlay b/tests/drivers/rtc/rtc_api/boards/nucleo_wb09ke.overlay deleted file mode 100644 index cb60b3b72d7c..000000000000 --- a/tests/drivers/rtc/rtc_api/boards/nucleo_wb09ke.overlay +++ /dev/null @@ -1,11 +0,0 @@ -/* - * Copyright (c) 2025 STMicroelectronics - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/ { - aliases { - rtc = &rtc; - }; -}; From e734c05d78dd8113ed22cf026bd3b0d5777302d4 Mon Sep 17 00:00:00 2001 From: Tim Knodel Date: Tue, 6 Jan 2026 11:43:06 -0800 Subject: [PATCH 2102/3659] drivers: i2c: mcux_flexcomm: Add ip block reset to bus recovery The bus recovery implementation did not reset the I2C block. If a glitch on the bus looks like a start condition, the I2C block will be stuck forever waiting for the associated stop. This adds reset to the I2C block to address this type of error. Signed-off-by: Tim Knodel --- drivers/i2c/i2c_mcux_flexcomm.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/i2c/i2c_mcux_flexcomm.c b/drivers/i2c/i2c_mcux_flexcomm.c index 4527f2764da4..c330a89a6d8f 100644 --- a/drivers/i2c/i2c_mcux_flexcomm.c +++ b/drivers/i2c/i2c_mcux_flexcomm.c @@ -254,6 +254,7 @@ static int mcux_flexcomm_recover_bus(const struct device *dev) }; uint32_t bitrate_cfg; int error = 0; + I2C_Type *base = config->base; if (!gpio_is_ready_dt(&config->scl)) { LOG_ERR("SCL GPIO device not ready"); @@ -265,6 +266,13 @@ static int mcux_flexcomm_recover_bus(const struct device *dev) return -EIO; } + /* If a glitch on the bus looks like a start condition, the i2c block will be stuck + * waiting forever for a stop. This resets the I2C block to clear this condition before + * the bitbang recovery proceedure which should clear any other devices on the bus. + */ + I2C_MasterEnable(base, false); + I2C_MasterEnable(base, true); + k_sem_take(&data->lock, K_FOREVER); error = gpio_pin_configure_dt(&config->scl, GPIO_OUTPUT_HIGH); From 42f96fc78da22b9b482d64e4b77f0a61ba019b6f Mon Sep 17 00:00:00 2001 From: Pieter De Gendt Date: Wed, 14 Jan 2026 10:42:18 +0100 Subject: [PATCH 2103/3659] manifest: Update hal_nxp with PWM assert to error patch Update the NXP HAL with a change where PWM_Setup can return an error value instead of asserting. Signed-off-by: Pieter De Gendt --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 0fd53432ccf5..ebc9fc7d5101 100644 --- a/west.yml +++ b/west.yml @@ -210,7 +210,7 @@ manifest: groups: - hal - name: hal_nxp - revision: 9424596b87f119f5e4049855e9a73eb16efd2c80 + revision: 0a0c1680179b286997f0bfec4cb89ca90f2b8685 path: modules/hal/nxp groups: - hal From eee57d48cbc6a0bf4ec1c56ed30d665828207989 Mon Sep 17 00:00:00 2001 From: Pieter De Gendt Date: Wed, 14 Jan 2026 10:43:41 +0100 Subject: [PATCH 2104/3659] drivers: pwm: mcux: Print status value on error When PWM_SetupPwm returns an error, add the value of status to the error log message. Signed-off-by: Pieter De Gendt --- drivers/pwm/pwm_mcux.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pwm/pwm_mcux.c b/drivers/pwm/pwm_mcux.c index 8db626938e95..8da0ea45e973 100644 --- a/drivers/pwm/pwm_mcux.c +++ b/drivers/pwm/pwm_mcux.c @@ -115,7 +115,7 @@ static int mcux_pwm_set_cycles_internal(const struct device *dev, uint32_t chann &data->channel[channel], 1U, config->mode, clock_freq >> config->prescale, clock_freq); if (status != kStatus_Success) { - LOG_ERR("Could not set up pwm"); + LOG_ERR("Could not set up pwm (%d)", status); return -ENOTSUP; } From fb9c9f034bdad825793ecabe8b9ae2917d564a91 Mon Sep 17 00:00:00 2001 From: Charles Hardin Date: Thu, 15 Jan 2026 14:42:43 -0800 Subject: [PATCH 2105/3659] drivers: ethernet: lan9250: Add promiscuous mode support Handle both multicast packets and promiscuous mode in the driver. This will allow the lan9250 to be added to a bridge as well as process multicast packets being received. Signed-off-by: Charles Hardin --- drivers/ethernet/eth_lan9250.c | 63 ++++++++++++++++++++++++++++++---- 1 file changed, 56 insertions(+), 7 deletions(-) diff --git a/drivers/ethernet/eth_lan9250.c b/drivers/ethernet/eth_lan9250.c index 69d11db82ef9..050e5d56f065 100644 --- a/drivers/ethernet/eth_lan9250.c +++ b/drivers/ethernet/eth_lan9250.c @@ -390,14 +390,17 @@ static int lan9250_configure(const struct device *dev) /* Configure HMAC control: * * - Automatically strip the pad field on incoming packets + * - Full duplex * - TX enable * - RX enable - * - Full duplex + * - Pass all multicast frames + * - Hash filtering disabled * - Promiscuous disabled */ lan9250_write_mac_reg(dev, LAN9250_HMAC_CR, - LAN9250_HMAC_CR_PADSTR | LAN9250_HMAC_CR_TXEN | LAN9250_HMAC_CR_RXEN | - LAN9250_HMAC_CR_FDPX); + LAN9250_HMAC_CR_PADSTR | LAN9250_HMAC_CR_FDPX | + LAN9250_HMAC_CR_TXEN | LAN9250_HMAC_CR_RXEN | + LAN9250_HMAC_CR_MCPAS); /* Configure TX: * @@ -620,7 +623,11 @@ static enum ethernet_hw_caps lan9250_get_capabilities(const struct device *dev) { ARG_UNUSED(dev); - return ETHERNET_LINK_10BASE | ETHERNET_LINK_100BASE; + return ETHERNET_LINK_10BASE | ETHERNET_LINK_100BASE +#if defined(CONFIG_NET_PROMISCUOUS_MODE) + | ETHERNET_PROMISC_MODE +#endif + ; } static void lan9250_iface_init(struct net_if *iface) @@ -641,11 +648,53 @@ static int lan9250_set_config(const struct device *dev, enum ethernet_config_typ { struct lan9250_runtime *ctx = dev->data; - if (type == ETHERNET_CONFIG_TYPE_MAC_ADDRESS) { - memcpy(ctx->mac_address, config->mac_address.addr, sizeof(ctx->mac_address)); + switch (type) { + case ETHERNET_CONFIG_TYPE_MAC_ADDRESS: + memcpy(ctx->mac_address, config->mac_address.addr, + sizeof(ctx->mac_address)); lan9250_set_macaddr(dev); - return net_if_set_link_addr(ctx->iface, ctx->mac_address, sizeof(ctx->mac_address), + + LOG_INF("%s MAC set to %02x:%02x:%02x:%02x:%02x:%02x", + dev->name, + ctx->mac_address[0], ctx->mac_address[1], + ctx->mac_address[2], ctx->mac_address[3], + ctx->mac_address[4], ctx->mac_address[5]); + + /* register the new mac address with the upper layer */ + return net_if_set_link_addr(ctx->iface, ctx->mac_address, + sizeof(ctx->mac_address), NET_LINK_ETHERNET); + case ETHERNET_CONFIG_TYPE_PROMISC_MODE: + if (IS_ENABLED(CONFIG_NET_PROMISCUOUS_MODE)) { + uint32_t reg; + + lan9250_read_mac_reg(dev, LAN9250_HMAC_CR, ®); + + /* See Table 11-1 from the LAN9250 data sheet */ + if (config->promisc_mode) { + if ((reg & LAN9250_HMAC_CR_PRMS) != 0) { + return -EALREADY; + } + + reg &= ~LAN9250_HMAC_CR_MCPAS; + reg |= LAN9250_HMAC_CR_PRMS; + reg &= ~LAN9250_HMAC_CR_HO; + } else { + if ((reg & LAN9250_HMAC_CR_PRMS) == 0) { + return -EALREADY; + } + + reg |= LAN9250_HMAC_CR_MCPAS; + reg &= ~LAN9250_HMAC_CR_PRMS; + reg &= ~LAN9250_HMAC_CR_HO; + } + + return lan9250_write_mac_reg(dev, LAN9250_HMAC_CR, reg); + } + + break; + default: + break; } return -ENOTSUP; From 44e0c38c63d28af10a89822ef05adabd10083a52 Mon Sep 17 00:00:00 2001 From: Gaetan Perrot Date: Fri, 16 Jan 2026 08:36:52 +0900 Subject: [PATCH 2106/3659] net: coap: coap_client: make coap_client_schedule_poll void coap_client_schedule_poll() never reports errors and always returns 0. The error check at the call site is therefore dead code. Make the function void and drop the unused error handling. Signed-off-by: Gaetan Perrot --- subsys/net/lib/coap/coap_client.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/subsys/net/lib/coap/coap_client.c b/subsys/net/lib/coap/coap_client.c index 1a75f9da2244..989fdd75b1dc 100644 --- a/subsys/net/lib/coap/coap_client.c +++ b/subsys/net/lib/coap/coap_client.c @@ -87,7 +87,7 @@ static void release_internal_request(struct coap_client_internal_request *reques request->pending.timeout = 0; } -static int coap_client_schedule_poll(struct coap_client *client, int sock, +static void coap_client_schedule_poll(struct coap_client *client, int sock, struct coap_client_request *req, struct coap_client_internal_request *internal_req) { @@ -96,8 +96,6 @@ static int coap_client_schedule_poll(struct coap_client *client, int sock, internal_req->request_ongoing = true; k_sem_give(&coap_client_recv_sem); - - return 0; } static bool exchange_lifetime_exceeded(struct coap_client_internal_request *internal_req) @@ -486,11 +484,7 @@ int coap_client_req(struct coap_client *client, int sock, const struct net_socka client->send_echo = false; } - ret = coap_client_schedule_poll(client, sock, req, internal_req); - if (ret < 0) { - LOG_ERR("Failed to schedule polling"); - goto release; - } + coap_client_schedule_poll(client, sock, req, internal_req); ret = coap_pending_init(&internal_req->pending, &internal_req->request, &client->address, params); From 93bf06a235dac35274f5f9946a564425ee13bdf1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Mon, 19 Jan 2026 17:52:41 +0100 Subject: [PATCH 2107/3659] drivers: firmware: scmi: inclusive language fixes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As per coding guidelines, "sanity check" must be avoided. Signed-off-by: Benjamin Cabé --- drivers/firmware/scmi/clk.c | 12 ++++++------ drivers/firmware/scmi/nxp/cpu.c | 10 +++++----- drivers/firmware/scmi/pinctrl.c | 2 +- drivers/firmware/scmi/power.c | 4 ++-- drivers/firmware/scmi/shmem.c | 4 ++-- drivers/firmware/scmi/system.c | 2 +- 6 files changed, 17 insertions(+), 17 deletions(-) diff --git a/drivers/firmware/scmi/clk.c b/drivers/firmware/scmi/clk.c index e47e4efdfda2..646a719a8ceb 100644 --- a/drivers/firmware/scmi/clk.c +++ b/drivers/firmware/scmi/clk.c @@ -41,7 +41,7 @@ int scmi_clock_rate_get(struct scmi_protocol *proto, struct scmi_clock_rate_set_reply reply_buffer; bool use_polling; - /* sanity checks */ + /* input validation */ if (!proto || !rate) { return -EINVAL; } @@ -81,7 +81,7 @@ int scmi_clock_rate_set(struct scmi_protocol *proto, struct scmi_clock_rate_conf int status, ret; bool use_polling; - /* sanity checks */ + /* input validation */ if (!proto || !cfg) { return -EINVAL; } @@ -120,7 +120,7 @@ int scmi_clock_parent_get(struct scmi_protocol *proto, uint32_t clk_id, uint32_t struct scmi_clock_parent_get_reply reply_buffer; bool use_polling; - /* sanity checks */ + /* input validation */ if (!proto || !parent_id) { return -EINVAL; } @@ -161,7 +161,7 @@ int scmi_clock_parent_set(struct scmi_protocol *proto, uint32_t clk_id, uint32_t int status, ret; bool use_polling; - /* sanity checks */ + /* input validation */ if (!proto) { return -EINVAL; } @@ -196,7 +196,7 @@ int scmi_clock_config_set(struct scmi_protocol *proto, int status, ret; bool use_polling; - /* sanity checks */ + /* input validation */ if (!proto || !cfg) { return -EINVAL; } @@ -246,7 +246,7 @@ int scmi_clock_protocol_attributes(struct scmi_protocol *proto, uint32_t *attrib int ret; bool use_polling; - /* sanity checks */ + /* input validation */ if (!proto || !attributes) { return -EINVAL; } diff --git a/drivers/firmware/scmi/nxp/cpu.c b/drivers/firmware/scmi/nxp/cpu.c index e2ec6c764383..06d5d0454ad3 100644 --- a/drivers/firmware/scmi/nxp/cpu.c +++ b/drivers/firmware/scmi/nxp/cpu.c @@ -23,7 +23,7 @@ int scmi_nxp_cpu_sleep_mode_set(struct scmi_nxp_cpu_sleep_mode_config *cfg) int status, ret; bool use_polling; - /* sanity checks */ + /* input validation */ if (!proto || !cfg) { return -EINVAL; } @@ -61,7 +61,7 @@ int scmi_nxp_cpu_pd_lpm_set(struct scmi_nxp_cpu_pd_lpm_config *cfg) int status, ret; bool use_polling; - /* sanity checks */ + /* input validation */ if (!proto || !cfg) { return -EINVAL; } @@ -95,7 +95,7 @@ int scmi_nxp_cpu_set_irq_mask(struct scmi_nxp_cpu_irq_mask_config *cfg) struct scmi_message msg, reply; int status, ret; - /* sanity checks */ + /* input validation */ if (!proto || !cfg) { return -EINVAL; } @@ -127,7 +127,7 @@ int scmi_nxp_cpu_reset_vector(struct scmi_nxp_cpu_vector_config *cfg) struct scmi_message msg, reply; int status, ret; - /* sanity checks */ + /* input validation */ if (!proto || !cfg) { return -EINVAL; } @@ -160,7 +160,7 @@ int scmi_nxp_cpu_info_get(uint32_t cpu_id, struct scmi_nxp_cpu_info *cfg) struct scmi_nxp_cpu_info_get_reply reply_buffer; int ret; - /* sanity checks */ + /* input validation */ if (!proto || !cfg) { return -EINVAL; } diff --git a/drivers/firmware/scmi/pinctrl.c b/drivers/firmware/scmi/pinctrl.c index abfcae844a67..22508c6d7bda 100644 --- a/drivers/firmware/scmi/pinctrl.c +++ b/drivers/firmware/scmi/pinctrl.c @@ -20,7 +20,7 @@ int scmi_pinctrl_settings_configure(struct scmi_pinctrl_settings *settings) proto = &SCMI_PROTOCOL_NAME(SCMI_PROTOCOL_PINCTRL); - /* sanity checks */ + /* input validation */ if (!settings) { return -EINVAL; } diff --git a/drivers/firmware/scmi/power.c b/drivers/firmware/scmi/power.c index 6396029071be..d1a7a869ba10 100644 --- a/drivers/firmware/scmi/power.c +++ b/drivers/firmware/scmi/power.c @@ -24,7 +24,7 @@ int scmi_power_state_get(uint32_t domain_id, uint32_t *power_state) int ret; bool use_polling; - /* sanity checks */ + /* input validation */ if (!proto || !power_state) { return -EINVAL; } @@ -65,7 +65,7 @@ int scmi_power_state_set(struct scmi_power_state_config *cfg) int status, ret; bool use_polling; - /* sanity checks */ + /* input validation */ if (!proto || !cfg) { return -EINVAL; } diff --git a/drivers/firmware/scmi/shmem.c b/drivers/firmware/scmi/shmem.c index 86b1a9659d49..2bdb23465126 100644 --- a/drivers/firmware/scmi/shmem.c +++ b/drivers/firmware/scmi/shmem.c @@ -68,7 +68,7 @@ int scmi_shmem_read_message(const struct device *shmem, struct scmi_message *msg cfg = shmem->config; layout = (struct scmi_shmem_layout *)data->regmap; - /* some sanity checks first */ + /* some input validation first */ if (!msg) { return -EINVAL; } @@ -120,7 +120,7 @@ int scmi_shmem_write_message(const struct device *shmem, struct scmi_message *ms cfg = shmem->config; layout = (struct scmi_shmem_layout *)data->regmap; - /* some sanity checks first */ + /* some input validation first */ if (!msg) { return -EINVAL; } diff --git a/drivers/firmware/scmi/system.c b/drivers/firmware/scmi/system.c index d96efd27e3bb..46eb9a23e0de 100644 --- a/drivers/firmware/scmi/system.c +++ b/drivers/firmware/scmi/system.c @@ -47,7 +47,7 @@ int scmi_system_power_state_set(struct scmi_system_power_state_config *cfg) int ret; bool use_polling; - /* sanity checks */ + /* input validation */ if (!proto || !cfg) { return -EINVAL; } From 00dfe39149db1e8f5a15147e1b1d3848991488e5 Mon Sep 17 00:00:00 2001 From: Joel Guittet Date: Mon, 19 Jan 2026 21:25:14 +0100 Subject: [PATCH 2108/3659] dts: fix nxp mcxn94x opamp1 reg value It seems there is currently no impact except a warning displayed when building: "unit address and first address in 'reg' (0x40113000) don't match for /soc/peripheral@50000000/opamp@113000" Signed-off-by: Joel Guittet --- dts/arm/nxp/nxp_mcxn94x_common.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dts/arm/nxp/nxp_mcxn94x_common.dtsi b/dts/arm/nxp/nxp_mcxn94x_common.dtsi index 48106779602a..c5d50978c09b 100644 --- a/dts/arm/nxp/nxp_mcxn94x_common.dtsi +++ b/dts/arm/nxp/nxp_mcxn94x_common.dtsi @@ -95,7 +95,7 @@ opamp1: opamp@113000 { compatible = "nxp,opamp"; - reg = <0x40113000 0x1000>; + reg = <0x113000 0x1000>; status = "disabled"; operation-mode = "low_noise"; functional-mode = "follower"; From 537b8a635b1b401d56fb87157637bb8159697ace Mon Sep 17 00:00:00 2001 From: Gaetan Perrot Date: Tue, 20 Jan 2026 11:50:12 +0900 Subject: [PATCH 2109/3659] boards: arduino: fix intereface typo in openocd cfg file Fix a spelling mistake in the board openocd cfg file for arduino boards. No functional change. Signed-off-by: Gaetan Perrot --- boards/arduino/giga_r1/support/openocd_arduino_giga_r1_m4.cfg | 2 +- boards/arduino/giga_r1/support/openocd_arduino_giga_r1_m7.cfg | 2 +- .../nicla_vision/support/openocd_arduino_nicla_vision_m4.cfg | 2 +- .../nicla_vision/support/openocd_arduino_nicla_vision_m7.cfg | 2 +- boards/arduino/opta/support/openocd_opta_stm32h747xx_m7.cfg | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/boards/arduino/giga_r1/support/openocd_arduino_giga_r1_m4.cfg b/boards/arduino/giga_r1/support/openocd_arduino_giga_r1_m4.cfg index 174696ee8214..ff820c112d25 100644 --- a/boards/arduino/giga_r1/support/openocd_arduino_giga_r1_m4.cfg +++ b/boards/arduino/giga_r1/support/openocd_arduino_giga_r1_m4.cfg @@ -1,7 +1,7 @@ source [find interface/stlink-dap.cfg] transport select dapdirect_swd # If your ST-Link adapter embedded firmware dates prior version v2j24 -# DAP transport/intereface is not supported. In this case, refer to +# DAP transport/interface is not supported. In this case, refer to # https://docs.zephyrproject.org/latest/develop/flash_debug/probes.html#OpenOCD-deprecates-hla-st-link-interface set DUAL_BANK 1 diff --git a/boards/arduino/giga_r1/support/openocd_arduino_giga_r1_m7.cfg b/boards/arduino/giga_r1/support/openocd_arduino_giga_r1_m7.cfg index 5c1d0af36d1a..75e20243d417 100644 --- a/boards/arduino/giga_r1/support/openocd_arduino_giga_r1_m7.cfg +++ b/boards/arduino/giga_r1/support/openocd_arduino_giga_r1_m7.cfg @@ -1,7 +1,7 @@ source [find interface/stlink-dap.cfg] transport select dapdirect_swd # If your ST-Link adapter embedded firmware dates prior version v2j24 -# DAP transport/intereface is not supported. In this case, refer to +# DAP transport/interface is not supported. In this case, refer to # https://docs.zephyrproject.org/latest/develop/flash_debug/probes.html#OpenOCD-deprecates-hla-st-link-interface source [find target/stm32h7x.cfg] diff --git a/boards/arduino/nicla_vision/support/openocd_arduino_nicla_vision_m4.cfg b/boards/arduino/nicla_vision/support/openocd_arduino_nicla_vision_m4.cfg index 174696ee8214..ff820c112d25 100644 --- a/boards/arduino/nicla_vision/support/openocd_arduino_nicla_vision_m4.cfg +++ b/boards/arduino/nicla_vision/support/openocd_arduino_nicla_vision_m4.cfg @@ -1,7 +1,7 @@ source [find interface/stlink-dap.cfg] transport select dapdirect_swd # If your ST-Link adapter embedded firmware dates prior version v2j24 -# DAP transport/intereface is not supported. In this case, refer to +# DAP transport/interface is not supported. In this case, refer to # https://docs.zephyrproject.org/latest/develop/flash_debug/probes.html#OpenOCD-deprecates-hla-st-link-interface set DUAL_BANK 1 diff --git a/boards/arduino/nicla_vision/support/openocd_arduino_nicla_vision_m7.cfg b/boards/arduino/nicla_vision/support/openocd_arduino_nicla_vision_m7.cfg index 5c1d0af36d1a..75e20243d417 100644 --- a/boards/arduino/nicla_vision/support/openocd_arduino_nicla_vision_m7.cfg +++ b/boards/arduino/nicla_vision/support/openocd_arduino_nicla_vision_m7.cfg @@ -1,7 +1,7 @@ source [find interface/stlink-dap.cfg] transport select dapdirect_swd # If your ST-Link adapter embedded firmware dates prior version v2j24 -# DAP transport/intereface is not supported. In this case, refer to +# DAP transport/interface is not supported. In this case, refer to # https://docs.zephyrproject.org/latest/develop/flash_debug/probes.html#OpenOCD-deprecates-hla-st-link-interface source [find target/stm32h7x.cfg] diff --git a/boards/arduino/opta/support/openocd_opta_stm32h747xx_m7.cfg b/boards/arduino/opta/support/openocd_opta_stm32h747xx_m7.cfg index 5c1d0af36d1a..75e20243d417 100644 --- a/boards/arduino/opta/support/openocd_opta_stm32h747xx_m7.cfg +++ b/boards/arduino/opta/support/openocd_opta_stm32h747xx_m7.cfg @@ -1,7 +1,7 @@ source [find interface/stlink-dap.cfg] transport select dapdirect_swd # If your ST-Link adapter embedded firmware dates prior version v2j24 -# DAP transport/intereface is not supported. In this case, refer to +# DAP transport/interface is not supported. In this case, refer to # https://docs.zephyrproject.org/latest/develop/flash_debug/probes.html#OpenOCD-deprecates-hla-st-link-interface source [find target/stm32h7x.cfg] From 1efa88e51a4e3a571e2f58cf19785c8326933135 Mon Sep 17 00:00:00 2001 From: Gaetan Perrot Date: Tue, 20 Jan 2026 02:30:26 +0900 Subject: [PATCH 2110/3659] drivers: ethernet: phy: phy_tja11xx: remove dead error handling phy_tja11xx_get_link_state() always returns 0, making callers' error checks ineffective. Remove the unused return variable and drop the dead conditional in invoke_link_cb() to silence static analysis warnings and simplify the code. No functional change. Signed-off-by: Gaetan Perrot --- drivers/ethernet/phy/phy_tja11xx.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/ethernet/phy/phy_tja11xx.c b/drivers/ethernet/phy/phy_tja11xx.c index 505d6d3c9e89..a25d33cb6ddc 100644 --- a/drivers/ethernet/phy/phy_tja11xx.c +++ b/drivers/ethernet/phy/phy_tja11xx.c @@ -93,7 +93,6 @@ static int update_link_state(const struct device *dev) static int phy_tja11xx_get_link_state(const struct device *dev, struct phy_link_state *state) { struct phy_tja11xx_data *const data = dev->data; - int rc = 0; k_sem_take(&data->sem, K_FOREVER); @@ -101,7 +100,7 @@ static int phy_tja11xx_get_link_state(const struct device *dev, struct phy_link_ k_sem_give(&data->sem); - return rc; + return 0; } static void invoke_link_cb(const struct device *dev) @@ -114,9 +113,7 @@ static void invoke_link_cb(const struct device *dev) } /* Send callback only on link state change */ - if (phy_tja11xx_get_link_state(dev, &state) != 0) { - return; - } + phy_tja11xx_get_link_state(dev, &state); data->cb(dev, &state, data->cb_data); } From 52ac7438e7a2cecae6b130c1043baa8b245e399e Mon Sep 17 00:00:00 2001 From: Jingxing Lai Date: Tue, 20 Jan 2026 11:29:55 +0800 Subject: [PATCH 2111/3659] =?UTF-8?q?=EF=BB=BFboards:=20seeed:=20xiao=5Fnr?= =?UTF-8?q?f54l15:=20add=20more=20GPIO=20mappings?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add GPIO mappings for D11 to D15 Signed-off-by: Jingxing Lai --- boards/seeed/xiao_nrf54l15/seeed_xiao_connector.dtsi | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/boards/seeed/xiao_nrf54l15/seeed_xiao_connector.dtsi b/boards/seeed/xiao_nrf54l15/seeed_xiao_connector.dtsi index 220e1d57f32a..f505ce0f1e9d 100644 --- a/boards/seeed/xiao_nrf54l15/seeed_xiao_connector.dtsi +++ b/boards/seeed/xiao_nrf54l15/seeed_xiao_connector.dtsi @@ -18,7 +18,12 @@ <7 0 &gpio2 7 0>, /* D7 */ <8 0 &gpio2 1 0>, /* D8 */ <9 0 &gpio2 4 0>, /* D9 */ - <10 0 &gpio2 2 0>; /* D10 */ + <10 0 &gpio2 2 0>, /* D10 */ + <11 0 &gpio0 3 0>, /* D11 */ + <12 0 &gpio0 4 0>, /* D12 */ + <13 0 &gpio2 10 0>, /* D13 */ + <14 0 &gpio2 9 0>, /* D14 */ + <15 0 &gpio2 6 0>; /* D15 */ }; }; From dcfa19b3cf0166e8cc418acc827e3b0eb556a5bd Mon Sep 17 00:00:00 2001 From: Jingxing Lai Date: Tue, 20 Jan 2026 11:30:01 +0800 Subject: [PATCH 2112/3659] =?UTF-8?q?=EF=BB=BFboards:=20seeed:=20xiao=5Fnr?= =?UTF-8?q?f54l15:=20fix=20IMU=20device=20tree=20driver=20binding?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix the device tree configuration for the IMU sensor to ensure proper driver binding. Signed-off-by: Jingxing Lai --- .../seeed/xiao_nrf54l15/xiao_nrf54l15_nrf54l15_cpuapp.dts | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/boards/seeed/xiao_nrf54l15/xiao_nrf54l15_nrf54l15_cpuapp.dts b/boards/seeed/xiao_nrf54l15/xiao_nrf54l15_nrf54l15_cpuapp.dts index da97ca296ec2..98ac16348d96 100644 --- a/boards/seeed/xiao_nrf54l15/xiao_nrf54l15_nrf54l15_cpuapp.dts +++ b/boards/seeed/xiao_nrf54l15/xiao_nrf54l15_nrf54l15_cpuapp.dts @@ -53,7 +53,7 @@ }; aliases { - imu0 = &lsm6dso; + imu0 = &lsm6ds3tr_c; }; }; @@ -87,12 +87,10 @@ &i2c30 { status = "okay"; - lsm6dso: lsm6dso@6a { - compatible = "st,lsm6dso"; + lsm6ds3tr_c: lsm6ds3tr-c@6a { + compatible = "st,lsm6dsl"; reg = <0x6a>; irq-gpios = <&gpio0 2 GPIO_ACTIVE_HIGH>; - accel-pm = ; - gyro-pm = ; status = "okay"; }; }; From 0fa079d81e7806cddc140d896234194e60b7acfd Mon Sep 17 00:00:00 2001 From: Jingxing Lai Date: Tue, 20 Jan 2026 11:28:35 +0800 Subject: [PATCH 2113/3659] =?UTF-8?q?=EF=BB=BFboards:=20seeed:=20xiao=5Fnr?= =?UTF-8?q?f54l15:=20enable=20key=20SoC=20peripherals=20and=20HFXO=20confi?= =?UTF-8?q?g?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Enable and configure essential peripherals that are typically required for meaningful use of the XIAO nRF54L15 board, especially for wireless and sensing applications: - Configure HFXO with internal load capacitors (16 pF) for better RF performance/stability - Enable IEEE 802.15.4 radio support - Enable temperature sensor - Enable radio core - Enable NFCT (NFC tag) - Enable clock controller These changes make the board usable out-of-the-box for Bluetooth LE, Thread, Matter, NFC and basic temperature monitoring use cases. Signed-off-by: Jingxing Lai --- .../xiao_nrf54l15_nrf54l15_cpuapp.dts | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/boards/seeed/xiao_nrf54l15/xiao_nrf54l15_nrf54l15_cpuapp.dts b/boards/seeed/xiao_nrf54l15/xiao_nrf54l15_nrf54l15_cpuapp.dts index 98ac16348d96..eadd1a478964 100644 --- a/boards/seeed/xiao_nrf54l15/xiao_nrf54l15_nrf54l15_cpuapp.dts +++ b/boards/seeed/xiao_nrf54l15/xiao_nrf54l15_nrf54l15_cpuapp.dts @@ -148,5 +148,31 @@ dmic_dev: &pdm20 { status = "okay"; }; +&hfxo { + load-capacitors = "internal"; + load-capacitance-femtofarad = <16000>; + status = "okay"; +}; + +&ieee802154 { + status = "okay"; +}; + +&temp { + status = "okay"; +}; + +&radio { + status = "okay"; +}; + +&nfct { + status = "okay"; +}; + +&clock { + status = "okay"; +}; + /* Include default memory partition configuration file */ #include From 96c44c540b6c272f39dc1684925e24fe653f89ab Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Fri, 16 Jan 2026 00:07:25 -0800 Subject: [PATCH 2114/3659] pm: device_runtime: Fix possible inconsistent state In pm_device_runtime_get, when resume fails after the domain as claimed, the flag PM_DEVICE_FLAG_PD_CLAIMED is not cleared (but the domain is released). This leaves this flag in a consistent state and in a further resume this device won't resume its domain leading to bigger problems. Signed-off-by: Flavio Ceolin --- subsys/pm/device_runtime.c | 1 + 1 file changed, 1 insertion(+) diff --git a/subsys/pm/device_runtime.c b/subsys/pm/device_runtime.c index 9f453ca44d04..ad9a4d612cb6 100644 --- a/subsys/pm/device_runtime.c +++ b/subsys/pm/device_runtime.c @@ -290,6 +290,7 @@ int pm_device_runtime_get(const struct device *dev) pm->base.usage--; if (domain != NULL) { (void)pm_device_runtime_put(domain); + atomic_clear_bit(&dev->pm_base->flags, PM_DEVICE_FLAG_PD_CLAIMED); } goto unlock; } From 15d6ab8ae8fcc150e81396f290d835949b9a368b Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Fri, 16 Jan 2026 00:11:53 -0800 Subject: [PATCH 2115/3659] pm: device: Acknowledge unused variable action_cb is not used in pm_device_driver_deinit is not used when CONFIG_PM_DEVICE is enabled. Signed-off-by: Flavio Ceolin --- subsys/pm/device.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/subsys/pm/device.c b/subsys/pm/device.c index b02299fc986f..e9cc80577633 100644 --- a/subsys/pm/device.c +++ b/subsys/pm/device.c @@ -408,6 +408,8 @@ int pm_device_driver_init(const struct device *dev, int pm_device_driver_deinit(const struct device *dev, pm_device_action_cb_t action_cb) { + ARG_UNUSED(action_cb); + struct pm_device_base *pm = dev->pm_base; return pm->state == PM_DEVICE_STATE_SUSPENDED || From 4ae5f63aa97f3ed186cb8ea0ad2bc7146f8092c5 Mon Sep 17 00:00:00 2001 From: Kyra Lengfeld Date: Fri, 16 Jan 2026 08:41:06 +0100 Subject: [PATCH 2116/3659] Bluetooth: Host: Give option to disable TX processor thread It is not recommended to disable the tx processor thread as otherwise deadlocks may occur, but it has been observed that some boards and configurations may have too little RAM to accommodate the TX processor thread stack. As such BT_TX_PROCESSOR_THREAD gets a prompt. Signed-off-by: Kyra Lengfeld --- subsys/bluetooth/host/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/bluetooth/host/Kconfig b/subsys/bluetooth/host/Kconfig index bfa60942a812..05e69f9e8c2a 100644 --- a/subsys/bluetooth/host/Kconfig +++ b/subsys/bluetooth/host/Kconfig @@ -136,7 +136,7 @@ config BT_DRIVER_RX_HIGH_PRIO config BT_TX_PROCESSOR_THREAD # This thread is used to send pending HCI Commands, ACL and ISO data to # Controller. - bool + bool "TX processor thread. Disabling may cause deadlocks." # This option is automatically selected for all platforms except nRF51 # due to limited RAM on nRF51 devices. default y if !SOC_SERIES_NRF51X From bf5460b6610880e488eee41081ac7863fe1eede7 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Fri, 16 Jan 2026 06:48:25 +0000 Subject: [PATCH 2117/3659] soc: arm: musca: Fix SoC Kconfig naming Fixes the Kconfig name of this so that it matches the value from soc.yml, this has not been deprecated because this SoC is a virtual SoC used only with the 2 boards in zephyr meaning it should not cause any breakage of out-of-tree boards Signed-off-by: Jamie McCrae --- boards/arm/v2m_musca_b1/Kconfig.v2m_musca_b1 | 2 +- boards/arm/v2m_musca_s1/Kconfig.v2m_musca_s1 | 2 +- samples/subsys/ipc/openamp/remote/src/main.c | 2 +- samples/subsys/ipc/openamp/src/main.c | 4 ++-- samples/subsys/ipc/rpmsg_service/src/main.c | 2 +- soc/arm/musca/CMakeLists.txt | 4 ++-- soc/arm/musca/Kconfig | 4 ++-- soc/arm/musca/Kconfig.defconfig | 4 ++-- soc/arm/musca/Kconfig.soc | 8 ++++---- subsys/ipc/rpmsg_service/rpmsg_backend.c | 2 +- 10 files changed, 17 insertions(+), 17 deletions(-) diff --git a/boards/arm/v2m_musca_b1/Kconfig.v2m_musca_b1 b/boards/arm/v2m_musca_b1/Kconfig.v2m_musca_b1 index 3171dc5033ef..0014c62d93cb 100644 --- a/boards/arm/v2m_musca_b1/Kconfig.v2m_musca_b1 +++ b/boards/arm/v2m_musca_b1/Kconfig.v2m_musca_b1 @@ -2,4 +2,4 @@ # SPDX-License-Identifier: Apache-2.0 config BOARD_V2M_MUSCA_B1 - select SOC_V2M_MUSCA_B1 + select SOC_MUSCA_B1 diff --git a/boards/arm/v2m_musca_s1/Kconfig.v2m_musca_s1 b/boards/arm/v2m_musca_s1/Kconfig.v2m_musca_s1 index fd5ab86f341c..0d6c6497a218 100644 --- a/boards/arm/v2m_musca_s1/Kconfig.v2m_musca_s1 +++ b/boards/arm/v2m_musca_s1/Kconfig.v2m_musca_s1 @@ -2,4 +2,4 @@ # SPDX-License-Identifier: Apache-2.0 config BOARD_V2M_MUSCA_S1 - select SOC_V2M_MUSCA_S1 + select SOC_MUSCA_S1 diff --git a/samples/subsys/ipc/openamp/remote/src/main.c b/samples/subsys/ipc/openamp/remote/src/main.c index 73da4bbb5e66..cae2682cf417 100644 --- a/samples/subsys/ipc/openamp/remote/src/main.c +++ b/samples/subsys/ipc/openamp/remote/src/main.c @@ -56,7 +56,7 @@ static uint32_t ipc_virtio_get_features(struct virtio_device *dev) static void ipc_virtio_notify(struct virtqueue *vq) { #if defined(CONFIG_SOC_MPS2_AN521) || \ - defined(CONFIG_SOC_V2M_MUSCA_B1) + defined(CONFIG_SOC_MUSCA_B1) uint32_t current_core = sse_200_platform_get_cpu_id(); ipm_send(ipm_handle, 0, current_core ? 0 : 1, 0, 1); diff --git a/samples/subsys/ipc/openamp/src/main.c b/samples/subsys/ipc/openamp/src/main.c index 997ffdc7389e..27b998c3a242 100644 --- a/samples/subsys/ipc/openamp/src/main.c +++ b/samples/subsys/ipc/openamp/src/main.c @@ -66,7 +66,7 @@ static void ipc_virtio_set_features(struct virtio_device *dev, uint32_t features static void ipc_virtio_notify(struct virtqueue *vq) { #if defined(CONFIG_SOC_MPS2_AN521) || \ - defined(CONFIG_SOC_V2M_MUSCA_B1) + defined(CONFIG_SOC_MUSCA_B1) uint32_t current_core = sse_200_platform_get_cpu_id(); ipm_send(ipm_handle, 0, current_core ? 0 : 1, 0, 1); @@ -254,7 +254,7 @@ int main(void) NULL, NULL, NULL, K_PRIO_COOP(7), 0, K_NO_WAIT); #if defined(CONFIG_SOC_MPS2_AN521) || \ - defined(CONFIG_SOC_V2M_MUSCA_B1) + defined(CONFIG_SOC_MUSCA_B1) wakeup_cpu1(); k_msleep(500); #endif /* #if defined(CONFIG_SOC_MPS2_AN521) */ diff --git a/samples/subsys/ipc/rpmsg_service/src/main.c b/samples/subsys/ipc/rpmsg_service/src/main.c index d8ebe8f8ea4e..2bffc2acdc4b 100644 --- a/samples/subsys/ipc/rpmsg_service/src/main.c +++ b/samples/subsys/ipc/rpmsg_service/src/main.c @@ -88,7 +88,7 @@ int main(void) k_thread_create(&thread_data, thread_stack, CONFIG_MAIN_APP_TASK_STACK_SIZE, app_task, NULL, NULL, NULL, K_PRIO_COOP(7), 0, K_NO_WAIT); -#if defined(CONFIG_SOC_MPS2_AN521) || defined(CONFIG_SOC_V2M_MUSCA_B1) +#if defined(CONFIG_SOC_MPS2_AN521) || defined(CONFIG_SOC_MUSCA_B1) wakeup_cpu1(); k_msleep(500); #endif /* #if defined(CONFIG_SOC_MPS2_AN521) */ diff --git a/soc/arm/musca/CMakeLists.txt b/soc/arm/musca/CMakeLists.txt index 988efa187581..d92e4d837693 100644 --- a/soc/arm/musca/CMakeLists.txt +++ b/soc/arm/musca/CMakeLists.txt @@ -4,10 +4,10 @@ # SPDX-License-Identifier: Apache-2.0 # -if(CONFIG_SOC_V2M_MUSCA_B1) +if(CONFIG_SOC_MUSCA_B1) zephyr_sources(b1/soc.c) zephyr_include_directories(b1) -elseif(CONFIG_SOC_V2M_MUSCA_S1) +elseif(CONFIG_SOC_MUSCA_S1) zephyr_include_directories(s1) endif() diff --git a/soc/arm/musca/Kconfig b/soc/arm/musca/Kconfig index 83abe182c1e6..275a40f99ff5 100644 --- a/soc/arm/musca/Kconfig +++ b/soc/arm/musca/Kconfig @@ -5,13 +5,13 @@ config SOC_SERIES_MUSCA select ARM select BUILD_OUTPUT_HEX -config SOC_V2M_MUSCA_B1 +config SOC_MUSCA_B1 select CPU_CORTEX_M33 select CPU_HAS_ARM_SAU select CPU_HAS_ARM_MPU select CPU_CORTEX_M_HAS_DWT -config SOC_V2M_MUSCA_S1 +config SOC_MUSCA_S1 select CPU_CORTEX_M33 select CPU_HAS_ARM_SAU select CPU_HAS_ARM_MPU diff --git a/soc/arm/musca/Kconfig.defconfig b/soc/arm/musca/Kconfig.defconfig index 8f457d9d50b2..06969a0dea61 100644 --- a/soc/arm/musca/Kconfig.defconfig +++ b/soc/arm/musca/Kconfig.defconfig @@ -2,8 +2,8 @@ # SPDX-License-Identifier: Apache-2.0 config SYS_CLOCK_HW_CYCLES_PER_SEC - default 40000000 if SOC_V2M_MUSCA_B1 - default 50000000 if SOC_V2M_MUSCA_S1 + default 40000000 if SOC_MUSCA_B1 + default 50000000 if SOC_MUSCA_S1 config NUM_IRQS default 96 if SOC_SERIES_MUSCA diff --git a/soc/arm/musca/Kconfig.soc b/soc/arm/musca/Kconfig.soc index 3c81f3d5713e..d5a10b08641b 100644 --- a/soc/arm/musca/Kconfig.soc +++ b/soc/arm/musca/Kconfig.soc @@ -7,13 +7,13 @@ config SOC_SERIES_MUSCA help ARM v2m MUSCA MCU Series -config SOC_V2M_MUSCA_B1 +config SOC_MUSCA_B1 bool select SOC_SERIES_MUSCA help ARM Cortex-M33 SMM-SSE-200 on V2M-MUSCA-B1 -config SOC_V2M_MUSCA_S1 +config SOC_MUSCA_S1 bool select SOC_SERIES_MUSCA help @@ -23,5 +23,5 @@ config SOC_SERIES default "musca" if SOC_SERIES_MUSCA config SOC - default "musca_b1" if SOC_V2M_MUSCA_B1 - default "musca_s1" if SOC_V2M_MUSCA_S1 + default "musca_b1" if SOC_MUSCA_B1 + default "musca_s1" if SOC_MUSCA_S1 diff --git a/subsys/ipc/rpmsg_service/rpmsg_backend.c b/subsys/ipc/rpmsg_service/rpmsg_backend.c index 4a35880f36d5..6594c0bf1cd8 100644 --- a/subsys/ipc/rpmsg_service/rpmsg_backend.c +++ b/subsys/ipc/rpmsg_service/rpmsg_backend.c @@ -106,7 +106,7 @@ static void ipc_virtio_notify(struct virtqueue *vq) #elif defined(CONFIG_RPMSG_SERVICE_SINGLE_IPM_SUPPORT) #if defined(CONFIG_SOC_MPS2_AN521) || \ - defined(CONFIG_SOC_V2M_MUSCA_B1) + defined(CONFIG_SOC_MUSCA_B1) uint32_t current_core = sse_200_platform_get_cpu_id(); status = ipm_send(ipm_handle, 0, current_core ? 0 : 1, 0, 1); From 13bcf52b290bd9c2298d52621d3b952db93a1ca2 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Fri, 16 Jan 2026 06:55:50 +0000 Subject: [PATCH 2118/3659] soc: arm: mps2: Fix SoC Kconfig naming Fixes the Kconfig name of this so that it matches the value from soc.yml, this has not been deprecated because this SoC is a virtual SoC used only with the boards in zephyr meaning it should not cause any breakage of out-of-tree boards Signed-off-by: Jamie McCrae --- boards/arm/mps2/Kconfig.mps2 | 14 +++++----- samples/subsys/ipc/openamp/remote/src/main.c | 4 +-- samples/subsys/ipc/openamp/src/main.c | 8 +++--- samples/subsys/ipc/rpmsg_service/src/main.c | 4 +-- soc/arm/mps2/Kconfig | 14 +++++----- soc/arm/mps2/Kconfig.defconfig.an383 | 2 +- soc/arm/mps2/Kconfig.defconfig.an385 | 2 +- soc/arm/mps2/Kconfig.defconfig.an386 | 2 +- soc/arm/mps2/Kconfig.defconfig.an500 | 2 +- soc/arm/mps2/Kconfig.defconfig.an521 | 2 +- soc/arm/mps2/Kconfig.soc | 28 +++++++++---------- subsys/ipc/rpmsg_service/rpmsg_backend.c | 4 +-- .../oot_root/boards/arm/mps2/Kconfig.mps2 | 2 +- .../board_extend/oot_root/soc/arm/Kconfig.soc | 4 +-- tests/cmake/hwm/board_extend/src/main.c | 2 +- tests/lib/heap/src/main.c | 2 +- 16 files changed, 48 insertions(+), 48 deletions(-) diff --git a/boards/arm/mps2/Kconfig.mps2 b/boards/arm/mps2/Kconfig.mps2 index c350ffeb8cb2..811aa31a24c4 100644 --- a/boards/arm/mps2/Kconfig.mps2 +++ b/boards/arm/mps2/Kconfig.mps2 @@ -3,10 +3,10 @@ # SPDX-License-Identifier: Apache-2.0 config BOARD_MPS2 - select SOC_MPS2_AN383 if BOARD_MPS2_AN383 - select SOC_MPS2_AN385 if BOARD_MPS2_AN385 - select SOC_MPS2_AN386 if BOARD_MPS2_AN386 - select SOC_MPS2_AN500 if BOARD_MPS2_AN500 - select SOC_MPS2_AN521_CPU0 if BOARD_MPS2_AN521_CPU0 - select SOC_MPS2_AN521_CPU0 if BOARD_MPS2_AN521_CPU0_NS - select SOC_MPS2_AN521_CPU1 if BOARD_MPS2_AN521_CPU1 + select SOC_AN383 if BOARD_MPS2_AN383 + select SOC_AN385 if BOARD_MPS2_AN385 + select SOC_AN386 if BOARD_MPS2_AN386 + select SOC_AN500 if BOARD_MPS2_AN500 + select SOC_AN521_CPU0 if BOARD_MPS2_AN521_CPU0 + select SOC_AN521_CPU0 if BOARD_MPS2_AN521_CPU0_NS + select SOC_AN521_CPU1 if BOARD_MPS2_AN521_CPU1 diff --git a/samples/subsys/ipc/openamp/remote/src/main.c b/samples/subsys/ipc/openamp/remote/src/main.c index cae2682cf417..275fdbaa243c 100644 --- a/samples/subsys/ipc/openamp/remote/src/main.c +++ b/samples/subsys/ipc/openamp/remote/src/main.c @@ -55,7 +55,7 @@ static uint32_t ipc_virtio_get_features(struct virtio_device *dev) static void ipc_virtio_notify(struct virtqueue *vq) { -#if defined(CONFIG_SOC_MPS2_AN521) || \ +#if defined(CONFIG_SOC_AN521) || \ defined(CONFIG_SOC_MUSCA_B1) uint32_t current_core = sse_200_platform_get_cpu_id(); @@ -64,7 +64,7 @@ static void ipc_virtio_notify(struct virtqueue *vq) uint32_t dummy_data = 0x00110011; /* Some data must be provided */ ipm_send(ipm_handle, 0, 0, &dummy_data, sizeof(dummy_data)); -#endif /* #if defined(CONFIG_SOC_MPS2_AN521) */ +#endif /* #if defined(CONFIG_SOC_AN521) */ } struct virtio_dispatch dispatch = { diff --git a/samples/subsys/ipc/openamp/src/main.c b/samples/subsys/ipc/openamp/src/main.c index 27b998c3a242..7aba82f32770 100644 --- a/samples/subsys/ipc/openamp/src/main.c +++ b/samples/subsys/ipc/openamp/src/main.c @@ -65,7 +65,7 @@ static void ipc_virtio_set_features(struct virtio_device *dev, uint32_t features static void ipc_virtio_notify(struct virtqueue *vq) { -#if defined(CONFIG_SOC_MPS2_AN521) || \ +#if defined(CONFIG_SOC_AN521) || \ defined(CONFIG_SOC_MUSCA_B1) uint32_t current_core = sse_200_platform_get_cpu_id(); @@ -74,7 +74,7 @@ static void ipc_virtio_notify(struct virtqueue *vq) uint32_t dummy_data = 0x55005500; /* Some data must be provided */ ipm_send(ipm_handle, 0, 0, &dummy_data, sizeof(dummy_data)); -#endif /* #if defined(CONFIG_SOC_MPS2_AN521) */ +#endif /* #if defined(CONFIG_SOC_AN521) */ } struct virtio_dispatch dispatch = { @@ -253,11 +253,11 @@ int main(void) app_task, NULL, NULL, NULL, K_PRIO_COOP(7), 0, K_NO_WAIT); -#if defined(CONFIG_SOC_MPS2_AN521) || \ +#if defined(CONFIG_SOC_AN521) || \ defined(CONFIG_SOC_MUSCA_B1) wakeup_cpu1(); k_msleep(500); -#endif /* #if defined(CONFIG_SOC_MPS2_AN521) */ +#endif /* #if defined(CONFIG_SOC_AN521) */ return 0; } diff --git a/samples/subsys/ipc/rpmsg_service/src/main.c b/samples/subsys/ipc/rpmsg_service/src/main.c index 2bffc2acdc4b..d597a4a22901 100644 --- a/samples/subsys/ipc/rpmsg_service/src/main.c +++ b/samples/subsys/ipc/rpmsg_service/src/main.c @@ -88,10 +88,10 @@ int main(void) k_thread_create(&thread_data, thread_stack, CONFIG_MAIN_APP_TASK_STACK_SIZE, app_task, NULL, NULL, NULL, K_PRIO_COOP(7), 0, K_NO_WAIT); -#if defined(CONFIG_SOC_MPS2_AN521) || defined(CONFIG_SOC_MUSCA_B1) +#if defined(CONFIG_SOC_AN521) || defined(CONFIG_SOC_MUSCA_B1) wakeup_cpu1(); k_msleep(500); -#endif /* #if defined(CONFIG_SOC_MPS2_AN521) */ +#endif /* #if defined(CONFIG_SOC_AN521) */ return 0; } diff --git a/soc/arm/mps2/Kconfig b/soc/arm/mps2/Kconfig index 2c999393a773..ee4ef8794181 100644 --- a/soc/arm/mps2/Kconfig +++ b/soc/arm/mps2/Kconfig @@ -6,32 +6,32 @@ config SOC_SERIES_MPS2 select ARM select GPIO_MMIO32 if GPIO -config SOC_MPS2_AN521 +config SOC_AN521 select CPU_CORTEX_M33 select CPU_HAS_ARM_MPU -config SOC_MPS2_AN383 +config SOC_AN383 select CPU_CORTEX_M0PLUS select CPU_HAS_ARM_MPU select CPU_CORTEX_M_HAS_SYSTICK select CPU_CORTEX_M_HAS_VTOR -config SOC_MPS2_AN385 +config SOC_AN385 select CPU_CORTEX_M3 select CPU_HAS_ARM_MPU -config SOC_MPS2_AN386 +config SOC_AN386 select CPU_CORTEX_M4 select CPU_HAS_ARM_MPU select CPU_HAS_VFP -config SOC_MPS2_AN500 +config SOC_AN500 select CPU_CORTEX_M7 select CPU_HAS_ARM_MPU -config SOC_MPS2_AN521_CPU0 +config SOC_AN521_CPU0 select CPU_HAS_ARM_SAU -config SOC_MPS2_AN521_CPU1 +config SOC_AN521_CPU1 select CPU_HAS_FPU select ARMV8_M_DSP diff --git a/soc/arm/mps2/Kconfig.defconfig.an383 b/soc/arm/mps2/Kconfig.defconfig.an383 index 0d59cb09d261..dff73cdd9c6d 100644 --- a/soc/arm/mps2/Kconfig.defconfig.an383 +++ b/soc/arm/mps2/Kconfig.defconfig.an383 @@ -1,7 +1,7 @@ # Copyright 2024 Arm Limited and/or its affiliates # SPDX-License-Identifier: Apache-2.0 -if SOC_MPS2_AN383 +if SOC_AN383 config NUM_IRQS default 32 diff --git a/soc/arm/mps2/Kconfig.defconfig.an385 b/soc/arm/mps2/Kconfig.defconfig.an385 index fbcec3977f11..873c407590d6 100644 --- a/soc/arm/mps2/Kconfig.defconfig.an385 +++ b/soc/arm/mps2/Kconfig.defconfig.an385 @@ -1,7 +1,7 @@ # Copyright (c) 2017 Linaro Limited # SPDX-License-Identifier: Apache-2.0 -if SOC_MPS2_AN385 +if SOC_AN385 config NUM_IRQS default 32 diff --git a/soc/arm/mps2/Kconfig.defconfig.an386 b/soc/arm/mps2/Kconfig.defconfig.an386 index 9c75afbef8b1..106372c8c4fc 100644 --- a/soc/arm/mps2/Kconfig.defconfig.an386 +++ b/soc/arm/mps2/Kconfig.defconfig.an386 @@ -1,7 +1,7 @@ # Copyright 2024 Arm Limited and/or its affiliates # SPDX-License-Identifier: Apache-2.0 -if SOC_MPS2_AN386 +if SOC_AN386 config NUM_IRQS default 32 diff --git a/soc/arm/mps2/Kconfig.defconfig.an500 b/soc/arm/mps2/Kconfig.defconfig.an500 index 8cf914f573ae..48c708f7ab2f 100644 --- a/soc/arm/mps2/Kconfig.defconfig.an500 +++ b/soc/arm/mps2/Kconfig.defconfig.an500 @@ -1,7 +1,7 @@ # Copyright 2024 Arm Limited and/or its affiliates # SPDX-License-Identifier: Apache-2.0 -if SOC_MPS2_AN500 +if SOC_AN500 config NUM_IRQS default 32 diff --git a/soc/arm/mps2/Kconfig.defconfig.an521 b/soc/arm/mps2/Kconfig.defconfig.an521 index 944bdf4f067b..378dca10d7b6 100644 --- a/soc/arm/mps2/Kconfig.defconfig.an521 +++ b/soc/arm/mps2/Kconfig.defconfig.an521 @@ -1,7 +1,7 @@ # Copyright (c) 2018-2019 Linaro Limited # SPDX-License-Identifier: Apache-2.0 -if SOC_MPS2_AN521 +if SOC_AN521 config NUM_IRQS default 96 diff --git a/soc/arm/mps2/Kconfig.soc b/soc/arm/mps2/Kconfig.soc index 42ba48639bb3..771394370e7a 100644 --- a/soc/arm/mps2/Kconfig.soc +++ b/soc/arm/mps2/Kconfig.soc @@ -8,43 +8,43 @@ config SOC_SERIES_MPS2 help Enable support for ARM MPS2 MCU Series -config SOC_MPS2_AN383 +config SOC_AN383 bool select SOC_SERIES_MPS2 help ARM Cortex-M0+ SMM on V2M-MPS2 (Application Note AN383) -config SOC_MPS2_AN385 +config SOC_AN385 bool select SOC_SERIES_MPS2 help ARM Cortex-M3 SMM on V2M-MPS2 (Application Note AN385) -config SOC_MPS2_AN386 +config SOC_AN386 bool select SOC_SERIES_MPS2 help ARM Cortex-M4 SMM on V2M-MPS2 (Application Note AN386) -config SOC_MPS2_AN500 +config SOC_AN500 bool select SOC_SERIES_MPS2 help ARM Cortex-M7 SMM on V2M-MPS2+ (Application Note AN500) -config SOC_MPS2_AN521 +config SOC_AN521 bool select SOC_SERIES_MPS2 -config SOC_MPS2_AN521_CPU0 +config SOC_AN521_CPU0 bool - select SOC_MPS2_AN521 + select SOC_AN521 help ARM Cortex-M33 SMM-SSE-200 on V2M-MPS2+ (AN521) CPU0 -config SOC_MPS2_AN521_CPU1 +config SOC_AN521_CPU1 bool - select SOC_MPS2_AN521 + select SOC_AN521 help ARM Cortex-M33 SMM-SSE-200 on V2M-MPS2+ (AN521) CPU1 @@ -52,8 +52,8 @@ config SOC_SERIES default "mps2" if SOC_SERIES_MPS2 config SOC - default "an383" if SOC_MPS2_AN383 - default "an385" if SOC_MPS2_AN385 - default "an386" if SOC_MPS2_AN386 - default "an500" if SOC_MPS2_AN500 - default "an521" if SOC_MPS2_AN521 + default "an383" if SOC_AN383 + default "an385" if SOC_AN385 + default "an386" if SOC_AN386 + default "an500" if SOC_AN500 + default "an521" if SOC_AN521 diff --git a/subsys/ipc/rpmsg_service/rpmsg_backend.c b/subsys/ipc/rpmsg_service/rpmsg_backend.c index 6594c0bf1cd8..4e77e9512820 100644 --- a/subsys/ipc/rpmsg_service/rpmsg_backend.c +++ b/subsys/ipc/rpmsg_service/rpmsg_backend.c @@ -105,7 +105,7 @@ static void ipc_virtio_notify(struct virtqueue *vq) status = ipm_send(ipm_tx_handle, 0, 0, NULL, 0); #elif defined(CONFIG_RPMSG_SERVICE_SINGLE_IPM_SUPPORT) -#if defined(CONFIG_SOC_MPS2_AN521) || \ +#if defined(CONFIG_SOC_AN521) || \ defined(CONFIG_SOC_MUSCA_B1) uint32_t current_core = sse_200_platform_get_cpu_id(); @@ -123,7 +123,7 @@ static void ipc_virtio_notify(struct virtqueue *vq) uint32_t dummy_data = 0x55005500; status = ipm_send(ipm_handle, 0, 0, &dummy_data, sizeof(dummy_data)); -#endif /* #if defined(CONFIG_SOC_MPS2_AN521) */ +#endif /* #if defined(CONFIG_SOC_AN521) */ #endif diff --git a/tests/cmake/hwm/board_extend/oot_root/boards/arm/mps2/Kconfig.mps2 b/tests/cmake/hwm/board_extend/oot_root/boards/arm/mps2/Kconfig.mps2 index 448c9cc13080..8005b28ad64e 100644 --- a/tests/cmake/hwm/board_extend/oot_root/boards/arm/mps2/Kconfig.mps2 +++ b/tests/cmake/hwm/board_extend/oot_root/boards/arm/mps2/Kconfig.mps2 @@ -2,4 +2,4 @@ # SPDX-License-Identifier: Apache-2.0 config BOARD_MPS2 - select SOC_MPS2_AN521_CPUTEST if BOARD_MPS2_AN521_CPUTEST + select SOC_AN521_CPUTEST if BOARD_MPS2_AN521_CPUTEST diff --git a/tests/cmake/hwm/board_extend/oot_root/soc/arm/Kconfig.soc b/tests/cmake/hwm/board_extend/oot_root/soc/arm/Kconfig.soc index a699e8413a1e..f518afe047a5 100644 --- a/tests/cmake/hwm/board_extend/oot_root/soc/arm/Kconfig.soc +++ b/tests/cmake/hwm/board_extend/oot_root/soc/arm/Kconfig.soc @@ -1,6 +1,6 @@ # Copyright (c) 2024, Nordic Semiconductor ASA # SPDX-License-Identifier: Apache-2.0 -config SOC_MPS2_AN521_CPUTEST +config SOC_AN521_CPUTEST bool - select SOC_MPS2_AN521 + select SOC_AN521 diff --git a/tests/cmake/hwm/board_extend/src/main.c b/tests/cmake/hwm/board_extend/src/main.c index 9795bd8dcb8f..76258f0ee348 100644 --- a/tests/cmake/hwm/board_extend/src/main.c +++ b/tests/cmake/hwm/board_extend/src/main.c @@ -36,7 +36,7 @@ #define BASE_BOARD_CONFIG 0 #endif -#ifdef CONFIG_SOC_MPS2_AN521_CPUTEST +#ifdef CONFIG_SOC_AN521_CPUTEST #define EXTENDED_SOC 1 #else #define EXTENDED_SOC 0 diff --git a/tests/lib/heap/src/main.c b/tests/lib/heap/src/main.c index 3f82cfd744ab..24f901abc5b2 100644 --- a/tests/lib/heap/src/main.c +++ b/tests/lib/heap/src/main.c @@ -13,7 +13,7 @@ * platform, with workarounds. */ -#if defined(CONFIG_SOC_MPS2_AN521) && defined(CONFIG_QEMU_TARGET) +#if defined(CONFIG_SOC_AN521) && defined(CONFIG_QEMU_TARGET) /* mps2/an521 blows up if allowed to link into large area, even though * the link is successful and it claims the memory is there. We get * hard faults on boot in qemu before entry to cstart() once MEMSZ is From fcb77f2491f1b211f698565c2d776a55a9ebd847 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Fri, 16 Jan 2026 06:57:28 +0000 Subject: [PATCH 2119/3659] soc: arm: mps3: Fix SoC Kconfig naming Fixes the Kconfig name of this so that it matches the value from soc.yml, this has not been deprecated because this SoC is a virtual SoC used only with the boards in zephyr meaning it should not cause any breakage of out-of-tree boards Signed-off-by: Jamie McCrae --- boards/arm/mps3/Kconfig.mps3 | 4 ++-- soc/arm/mps3/Kconfig | 8 ++++---- soc/arm/mps3/Kconfig.defconfig.mps3_corstone300 | 2 +- soc/arm/mps3/Kconfig.defconfig.mps3_corstone310 | 2 +- soc/arm/mps3/Kconfig.soc | 8 ++++---- tests/arch/arm/arm_mpu_pxn/CMakeLists.txt | 4 ++-- 6 files changed, 14 insertions(+), 14 deletions(-) diff --git a/boards/arm/mps3/Kconfig.mps3 b/boards/arm/mps3/Kconfig.mps3 index 02d081f826ae..45127d4593b4 100644 --- a/boards/arm/mps3/Kconfig.mps3 +++ b/boards/arm/mps3/Kconfig.mps3 @@ -5,13 +5,13 @@ config BOARD_MPS3 select SOC_SERIES_MPS3 - select SOC_MPS3_CORSTONE300 if BOARD_MPS3_CORSTONE300_AN547 || \ + select SOC_CORSTONE300 if BOARD_MPS3_CORSTONE300_AN547 || \ BOARD_MPS3_CORSTONE300_AN547_NS || \ BOARD_MPS3_CORSTONE300_AN552 || \ BOARD_MPS3_CORSTONE300_AN552_NS || \ BOARD_MPS3_CORSTONE300_FVP || \ BOARD_MPS3_CORSTONE300_FVP_NS - select SOC_MPS3_CORSTONE310 if BOARD_MPS3_CORSTONE310_AN555 || \ + select SOC_CORSTONE310 if BOARD_MPS3_CORSTONE310_AN555 || \ BOARD_MPS3_CORSTONE310_AN555_NS || \ BOARD_MPS3_CORSTONE310_FVP || \ BOARD_MPS3_CORSTONE310_FVP_NS diff --git a/soc/arm/mps3/Kconfig b/soc/arm/mps3/Kconfig index 32e98f61259e..993f0924d19a 100644 --- a/soc/arm/mps3/Kconfig +++ b/soc/arm/mps3/Kconfig @@ -6,7 +6,7 @@ config SOC_SERIES_MPS3 select ARM select GPIO_MMIO32 if GPIO -config SOC_MPS3_CORSTONE300 +config SOC_CORSTONE300 select CPU_CORTEX_M55 select CPU_HAS_ARM_SAU select CPU_HAS_ARM_MPU @@ -16,7 +16,7 @@ config SOC_MPS3_CORSTONE300 select ARMV8_1_M_MVEF select ARMV8_1_M_PMU -config SOC_MPS3_CORSTONE310 +config SOC_CORSTONE310 select CPU_CORTEX_M85 select CPU_HAS_ARM_SAU select CPU_HAS_ARM_MPU @@ -28,5 +28,5 @@ config SOC_MPS3_CORSTONE310 config ARMV8_1_M_PMU_EVENTCNT int - default 8 if SOC_MPS3_CORSTONE300 - default 8 if SOC_MPS3_CORSTONE310 + default 8 if SOC_CORSTONE300 + default 8 if SOC_CORSTONE310 diff --git a/soc/arm/mps3/Kconfig.defconfig.mps3_corstone300 b/soc/arm/mps3/Kconfig.defconfig.mps3_corstone300 index df86713214fc..40a49097b305 100644 --- a/soc/arm/mps3/Kconfig.defconfig.mps3_corstone300 +++ b/soc/arm/mps3/Kconfig.defconfig.mps3_corstone300 @@ -2,7 +2,7 @@ # Copyright 2024 Arm Limited and/or its affiliates # SPDX-License-Identifier: Apache-2.0 -if SOC_MPS3_CORSTONE300 +if SOC_CORSTONE300 config NUM_IRQS default 128 diff --git a/soc/arm/mps3/Kconfig.defconfig.mps3_corstone310 b/soc/arm/mps3/Kconfig.defconfig.mps3_corstone310 index 11aebd44f7bd..5c0f819f0bc3 100644 --- a/soc/arm/mps3/Kconfig.defconfig.mps3_corstone310 +++ b/soc/arm/mps3/Kconfig.defconfig.mps3_corstone310 @@ -1,7 +1,7 @@ # Copyright 2024 Arm Limited and/or its affiliates # SPDX-License-Identifier: Apache-2.0 -if SOC_MPS3_CORSTONE310 +if SOC_CORSTONE310 config NUM_IRQS default 128 diff --git a/soc/arm/mps3/Kconfig.soc b/soc/arm/mps3/Kconfig.soc index 94c9538b5260..7ace4e1f3640 100644 --- a/soc/arm/mps3/Kconfig.soc +++ b/soc/arm/mps3/Kconfig.soc @@ -11,14 +11,14 @@ config SOC_SERIES_MPS3 config SOC_SERIES default "mps3" if SOC_SERIES_MPS3 -config SOC_MPS3_CORSTONE300 +config SOC_CORSTONE300 bool select SOC_SERIES_MPS3 -config SOC_MPS3_CORSTONE310 +config SOC_CORSTONE310 bool select SOC_SERIES_MPS3 config SOC - default "corstone300" if SOC_MPS3_CORSTONE300 - default "corstone310" if SOC_MPS3_CORSTONE310 + default "corstone300" if SOC_CORSTONE300 + default "corstone310" if SOC_CORSTONE310 diff --git a/tests/arch/arm/arm_mpu_pxn/CMakeLists.txt b/tests/arch/arm/arm_mpu_pxn/CMakeLists.txt index 13e7bcdc09f2..708e44e827ec 100644 --- a/tests/arch/arm/arm_mpu_pxn/CMakeLists.txt +++ b/tests/arch/arm/arm_mpu_pxn/CMakeLists.txt @@ -6,7 +6,7 @@ find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) project(arm_mpu_pxn) target_sources(app PRIVATE src/main.c) -zephyr_linker_sources_ifdef(CONFIG_SOC_MPS3_CORSTONE300 RAM_SECTIONS mps3_corstone300.ld) -zephyr_linker_sources_ifdef(CONFIG_SOC_MPS3_CORSTONE310 RAM_SECTIONS mps3_corstone310.ld) +zephyr_linker_sources_ifdef(CONFIG_SOC_CORSTONE300 RAM_SECTIONS mps3_corstone300.ld) +zephyr_linker_sources_ifdef(CONFIG_SOC_CORSTONE310 RAM_SECTIONS mps3_corstone310.ld) zephyr_linker_sources_ifdef(CONFIG_SOC_MPS4_CORSTONE315 RAM_SECTIONS mps4_corstone315.ld) zephyr_linker_sources_ifdef(CONFIG_SOC_MPS4_CORSTONE320 RAM_SECTIONS mps4_corstone320.ld) From 7d54f9c7c5ac1640c2133cbf33fab555f1c26302 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Fri, 16 Jan 2026 06:58:26 +0000 Subject: [PATCH 2120/3659] soc: arm: mps4: Fix SoC Kconfig naming Fixes the Kconfig name of this so that it matches the value from soc.yml, this has not been deprecated because this SoC is a virtual SoC used only with the boards in zephyr meaning it should not cause any breakage of out-of-tree boards Signed-off-by: Jamie McCrae --- boards/arm/mps4/Kconfig.mps4 | 4 ++-- modules/hal_ethos_u/Kconfig | 4 ++-- soc/arm/mps4/Kconfig | 8 ++++---- soc/arm/mps4/Kconfig.defconfig.mps4_corstone315 | 2 +- soc/arm/mps4/Kconfig.defconfig.mps4_corstone320 | 2 +- soc/arm/mps4/Kconfig.soc | 8 ++++---- tests/arch/arm/arm_mpu_pxn/CMakeLists.txt | 4 ++-- 7 files changed, 16 insertions(+), 16 deletions(-) diff --git a/boards/arm/mps4/Kconfig.mps4 b/boards/arm/mps4/Kconfig.mps4 index 46ce14cc0620..bab6870bfd8e 100644 --- a/boards/arm/mps4/Kconfig.mps4 +++ b/boards/arm/mps4/Kconfig.mps4 @@ -3,5 +3,5 @@ config BOARD_MPS4 select SOC_SERIES_MPS4 - select SOC_MPS4_CORSTONE315 if BOARD_MPS4_CORSTONE315_FVP || BOARD_MPS4_CORSTONE315_FVP_NS - select SOC_MPS4_CORSTONE320 if BOARD_MPS4_CORSTONE320_FVP || BOARD_MPS4_CORSTONE320_FVP_NS + select SOC_CORSTONE315 if BOARD_MPS4_CORSTONE315_FVP || BOARD_MPS4_CORSTONE315_FVP_NS + select SOC_CORSTONE320 if BOARD_MPS4_CORSTONE320_FVP || BOARD_MPS4_CORSTONE320_FVP_NS diff --git a/modules/hal_ethos_u/Kconfig b/modules/hal_ethos_u/Kconfig index e1a4d97b656f..f56269464229 100644 --- a/modules/hal_ethos_u/Kconfig +++ b/modules/hal_ethos_u/Kconfig @@ -14,8 +14,8 @@ menu "Ethos-U NPU configuration" choice ETHOS_U_NPU_CONFIG prompt "Ethos-U NPU configuration" default ETHOS_U55_128 if SOC_SERIES_MPS3 - default ETHOS_U65_256 if SOC_MPS4_CORSTONE315 - default ETHOS_U85_256 if SOC_MPS4_CORSTONE320 + default ETHOS_U65_256 if SOC_CORSTONE315 + default ETHOS_U85_256 if SOC_CORSTONE320 default ETHOS_U55_256 if SOC_SERIES_M55M1X config ETHOS_U55_64 bool "using Ethos-U55 with 64 macs" diff --git a/soc/arm/mps4/Kconfig b/soc/arm/mps4/Kconfig index ea733d1566dc..20ff97ebc8ef 100644 --- a/soc/arm/mps4/Kconfig +++ b/soc/arm/mps4/Kconfig @@ -5,7 +5,7 @@ config SOC_SERIES_MPS4 select ARM select GPIO_MMIO32 if GPIO -config SOC_MPS4_CORSTONE315 +config SOC_CORSTONE315 select CPU_CORTEX_M85 select CPU_HAS_ARM_SAU select CPU_HAS_ARM_MPU @@ -16,7 +16,7 @@ config SOC_MPS4_CORSTONE315 select ARMV8_1_M_PMU select ARM_MPU_PXN if ARM_MPU -config SOC_MPS4_CORSTONE320 +config SOC_CORSTONE320 select CPU_CORTEX_M85 select CPU_HAS_ARM_SAU select CPU_HAS_ARM_MPU @@ -29,5 +29,5 @@ config SOC_MPS4_CORSTONE320 config ARMV8_1_M_PMU_EVENTCNT int - default 8 if SOC_MPS4_CORSTONE315 - default 8 if SOC_MPS4_CORSTONE320 + default 8 if SOC_CORSTONE315 + default 8 if SOC_CORSTONE320 diff --git a/soc/arm/mps4/Kconfig.defconfig.mps4_corstone315 b/soc/arm/mps4/Kconfig.defconfig.mps4_corstone315 index 191b5d45df44..ea64fac4d895 100644 --- a/soc/arm/mps4/Kconfig.defconfig.mps4_corstone315 +++ b/soc/arm/mps4/Kconfig.defconfig.mps4_corstone315 @@ -1,7 +1,7 @@ # Copyright 2025 Arm Limited and/or its affiliates # SPDX-License-Identifier: Apache-2.0 -if SOC_MPS4_CORSTONE315 +if SOC_CORSTONE315 config NUM_IRQS default 232 diff --git a/soc/arm/mps4/Kconfig.defconfig.mps4_corstone320 b/soc/arm/mps4/Kconfig.defconfig.mps4_corstone320 index f7348d7fcadf..5a6495e563db 100644 --- a/soc/arm/mps4/Kconfig.defconfig.mps4_corstone320 +++ b/soc/arm/mps4/Kconfig.defconfig.mps4_corstone320 @@ -1,7 +1,7 @@ # Copyright 2025 Arm Limited and/or its affiliates # SPDX-License-Identifier: Apache-2.0 -if SOC_MPS4_CORSTONE320 +if SOC_CORSTONE320 config NUM_IRQS default 232 diff --git a/soc/arm/mps4/Kconfig.soc b/soc/arm/mps4/Kconfig.soc index 98087bb36763..1f510caa16ce 100644 --- a/soc/arm/mps4/Kconfig.soc +++ b/soc/arm/mps4/Kconfig.soc @@ -10,14 +10,14 @@ config SOC_SERIES_MPS4 config SOC_SERIES default "mps4" if SOC_SERIES_MPS4 -config SOC_MPS4_CORSTONE315 +config SOC_CORSTONE315 bool select SOC_SERIES_MPS4 -config SOC_MPS4_CORSTONE320 +config SOC_CORSTONE320 bool select SOC_SERIES_MPS4 config SOC - default "corstone315" if SOC_MPS4_CORSTONE315 - default "corstone320" if SOC_MPS4_CORSTONE320 + default "corstone315" if SOC_CORSTONE315 + default "corstone320" if SOC_CORSTONE320 diff --git a/tests/arch/arm/arm_mpu_pxn/CMakeLists.txt b/tests/arch/arm/arm_mpu_pxn/CMakeLists.txt index 708e44e827ec..ced20953b11f 100644 --- a/tests/arch/arm/arm_mpu_pxn/CMakeLists.txt +++ b/tests/arch/arm/arm_mpu_pxn/CMakeLists.txt @@ -8,5 +8,5 @@ project(arm_mpu_pxn) target_sources(app PRIVATE src/main.c) zephyr_linker_sources_ifdef(CONFIG_SOC_CORSTONE300 RAM_SECTIONS mps3_corstone300.ld) zephyr_linker_sources_ifdef(CONFIG_SOC_CORSTONE310 RAM_SECTIONS mps3_corstone310.ld) -zephyr_linker_sources_ifdef(CONFIG_SOC_MPS4_CORSTONE315 RAM_SECTIONS mps4_corstone315.ld) -zephyr_linker_sources_ifdef(CONFIG_SOC_MPS4_CORSTONE320 RAM_SECTIONS mps4_corstone320.ld) +zephyr_linker_sources_ifdef(CONFIG_SOC_CORSTONE315 RAM_SECTIONS mps4_corstone315.ld) +zephyr_linker_sources_ifdef(CONFIG_SOC_CORSTONE320 RAM_SECTIONS mps4_corstone320.ld) From d74f5d7d231dfc1c74343e46f18ac8ddc76fe940 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Mon, 12 Jan 2026 16:54:29 +0100 Subject: [PATCH 2121/3659] Bluetooth: Audio: depend on UTF8 Add a dependency for UTF8 for LE Audio. Since (nearly?) all string in LE Audio are UTF8 and that the stack wants to be able to check and validate strings coming both from remove deviecs and from the application, it will depend on the utf8 API that is guarded by CONFIG_UTF8. Signed-off-by: Emil Gydesen --- samples/bluetooth/bap_broadcast_assistant/prj.conf | 1 + samples/bluetooth/bap_broadcast_sink/prj.conf | 1 + samples/bluetooth/bap_broadcast_source/prj.conf | 1 + samples/bluetooth/bap_unicast_client/prj.conf | 1 + samples/bluetooth/bap_unicast_server/prj.conf | 1 + samples/bluetooth/cap_acceptor/prj.conf | 1 + samples/bluetooth/cap_initiator/prj.conf | 1 + samples/bluetooth/pbp_public_broadcast_source/prj.conf | 1 + samples/bluetooth/tmap_bms/prj.conf | 1 + subsys/bluetooth/audio/Kconfig | 3 ++- subsys/bluetooth/audio/Kconfig.has | 3 +-- subsys/bluetooth/audio/Kconfig.mcs | 3 +-- subsys/bluetooth/audio/Kconfig.tbs | 5 +---- tests/bluetooth/audio/bap_base/prj.conf | 1 + tests/bluetooth/audio/ccid/prj.conf | 1 + tests/bluetooth/audio/codec/prj.conf | 1 + tests/bluetooth/audio/pacs/prj.conf | 1 + 17 files changed, 18 insertions(+), 9 deletions(-) diff --git a/samples/bluetooth/bap_broadcast_assistant/prj.conf b/samples/bluetooth/bap_broadcast_assistant/prj.conf index 370ff75f2606..a098211f18fd 100644 --- a/samples/bluetooth/bap_broadcast_assistant/prj.conf +++ b/samples/bluetooth/bap_broadcast_assistant/prj.conf @@ -4,6 +4,7 @@ CONFIG_BT_CENTRAL=y CONFIG_BT_GATT_CLIENT=y CONFIG_BT_GATT_AUTO_DISCOVER_CCC=y CONFIG_BT_GATT_AUTO_UPDATE_MTU=y +CONFIG_UTF8=y CONFIG_BT_AUDIO=y CONFIG_BT_SMP=y CONFIG_BT_BUF_ACL_RX_SIZE=255 diff --git a/samples/bluetooth/bap_broadcast_sink/prj.conf b/samples/bluetooth/bap_broadcast_sink/prj.conf index c3780e12539c..20deb374b7fd 100644 --- a/samples/bluetooth/bap_broadcast_sink/prj.conf +++ b/samples/bluetooth/bap_broadcast_sink/prj.conf @@ -1,5 +1,6 @@ CONFIG_BT=y CONFIG_LOG=y +CONFIG_UTF8=y CONFIG_BT_AUDIO=y CONFIG_BT_SMP=y CONFIG_BT_PAC_SNK=y diff --git a/samples/bluetooth/bap_broadcast_source/prj.conf b/samples/bluetooth/bap_broadcast_source/prj.conf index 34d636f7e0fd..61247884434c 100644 --- a/samples/bluetooth/bap_broadcast_source/prj.conf +++ b/samples/bluetooth/bap_broadcast_source/prj.conf @@ -2,6 +2,7 @@ CONFIG_MAIN_STACK_SIZE=2048 CONFIG_BT=y CONFIG_LOG=y +CONFIG_UTF8=y CONFIG_BT_AUDIO=y CONFIG_BT_ISO_BROADCASTER=y CONFIG_BT_BAP_BROADCAST_SOURCE=y diff --git a/samples/bluetooth/bap_unicast_client/prj.conf b/samples/bluetooth/bap_unicast_client/prj.conf index 6d6658d728bf..2fb1f6b076b5 100644 --- a/samples/bluetooth/bap_unicast_client/prj.conf +++ b/samples/bluetooth/bap_unicast_client/prj.conf @@ -6,6 +6,7 @@ CONFIG_BT_ISO_CENTRAL=y CONFIG_BT_GATT_CLIENT=y CONFIG_BT_GATT_AUTO_DISCOVER_CCC=y CONFIG_BT_GATT_AUTO_UPDATE_MTU=y +CONFIG_UTF8=y CONFIG_BT_AUDIO=y CONFIG_BT_BAP_UNICAST_CLIENT=y CONFIG_BT_ISO_TX_BUF_COUNT=4 diff --git a/samples/bluetooth/bap_unicast_server/prj.conf b/samples/bluetooth/bap_unicast_server/prj.conf index 766fed3aec94..8fe532a8ad6a 100644 --- a/samples/bluetooth/bap_unicast_server/prj.conf +++ b/samples/bluetooth/bap_unicast_server/prj.conf @@ -9,6 +9,7 @@ CONFIG_BT_PERIPHERAL_PREF_MAX_INT=70 CONFIG_BT_PERIPHERAL_PREF_LATENCY=0 CONFIG_BT_PERIPHERAL_PREF_TIMEOUT=400 CONFIG_BT_ISO_PERIPHERAL=y +CONFIG_UTF8=y CONFIG_BT_AUDIO=y CONFIG_BT_GATT_DYNAMIC_DB=y CONFIG_BT_BAP_UNICAST_SERVER=y diff --git a/samples/bluetooth/cap_acceptor/prj.conf b/samples/bluetooth/cap_acceptor/prj.conf index 4f02a26f34a5..a92b21e89c02 100644 --- a/samples/bluetooth/cap_acceptor/prj.conf +++ b/samples/bluetooth/cap_acceptor/prj.conf @@ -11,6 +11,7 @@ CONFIG_BT_GATT_DYNAMIC_DB=y CONFIG_BT_GATT_CLIENT=y CONFIG_BT_EXT_ADV=y CONFIG_BT_DEVICE_NAME="CAP Acceptor" +CONFIG_UTF8=y CONFIG_BT_AUDIO=y CONFIG_BT_SMP=y CONFIG_BT_KEYS_OVERWRITE_OLDEST=y diff --git a/samples/bluetooth/cap_initiator/prj.conf b/samples/bluetooth/cap_initiator/prj.conf index ad5f8117a70b..e6ee04f0a460 100644 --- a/samples/bluetooth/cap_initiator/prj.conf +++ b/samples/bluetooth/cap_initiator/prj.conf @@ -3,6 +3,7 @@ CONFIG_MAIN_STACK_SIZE=2048 CONFIG_BT=y CONFIG_BT_SMP=y +CONFIG_UTF8=y CONFIG_BT_AUDIO=y CONFIG_BT_EXT_ADV=y CONFIG_BT_DEVICE_NAME="CAP Initiator" diff --git a/samples/bluetooth/pbp_public_broadcast_source/prj.conf b/samples/bluetooth/pbp_public_broadcast_source/prj.conf index d7d6e9fe6676..bdee616242b6 100644 --- a/samples/bluetooth/pbp_public_broadcast_source/prj.conf +++ b/samples/bluetooth/pbp_public_broadcast_source/prj.conf @@ -2,6 +2,7 @@ CONFIG_MAIN_STACK_SIZE=2048 CONFIG_BT=y CONFIG_LOG=y +CONFIG_UTF8=y CONFIG_BT_AUDIO=y CONFIG_BT_PERIPHERAL=y diff --git a/samples/bluetooth/tmap_bms/prj.conf b/samples/bluetooth/tmap_bms/prj.conf index 62219183f308..7d097da743b7 100644 --- a/samples/bluetooth/tmap_bms/prj.conf +++ b/samples/bluetooth/tmap_bms/prj.conf @@ -3,6 +3,7 @@ CONFIG_MAIN_STACK_SIZE=2048 CONFIG_BT=y CONFIG_LOG=y CONFIG_BT_PERIPHERAL=y +CONFIG_UTF8=y CONFIG_BT_AUDIO=y CONFIG_BT_SMP=y diff --git a/subsys/bluetooth/audio/Kconfig b/subsys/bluetooth/audio/Kconfig index bc3335aaf5df..e3473944230f 100644 --- a/subsys/bluetooth/audio/Kconfig +++ b/subsys/bluetooth/audio/Kconfig @@ -2,13 +2,14 @@ # # Copyright (c) 2020 Intel Corporation -# Copyright (c) 2022 Nordic Semiconductor ASA +# Copyright (c) 2022-2026 Nordic Semiconductor ASA # # SPDX-License-Identifier: Apache-2.0 # menuconfig BT_AUDIO bool "Bluetooth Audio support" + depends on UTF8 help This option enables Bluetooth Audio support. The specific features that are available may depend on other features diff --git a/subsys/bluetooth/audio/Kconfig.has b/subsys/bluetooth/audio/Kconfig.has index 541ee84468bb..48e2384759b2 100644 --- a/subsys/bluetooth/audio/Kconfig.has +++ b/subsys/bluetooth/audio/Kconfig.has @@ -1,12 +1,12 @@ # Bluetooth Audio - Hearing Access Service options # # Copyright (c) 2022 Codecoup +# Copyright (c) 2026 Nordic Semiconductor ASA # # SPDX-License-Identifier: Apache-2.0 menuconfig BT_HAS bool "Hearing Access Service support" - depends on UTF8 depends on BT_GATT_DYNAMIC_DB depends on BT_BAP_UNICAST_SERVER help @@ -56,7 +56,6 @@ endif # BT_HAS config BT_HAS_CLIENT bool "Hearing Access Service Client support" - depends on UTF8 depends on BT_GATT_CLIENT depends on BT_GATT_AUTO_DISCOVER_CCC depends on BT_GATT_AUTO_UPDATE_MTU diff --git a/subsys/bluetooth/audio/Kconfig.mcs b/subsys/bluetooth/audio/Kconfig.mcs index d1103f796d3b..79f9c3d7d446 100644 --- a/subsys/bluetooth/audio/Kconfig.mcs +++ b/subsys/bluetooth/audio/Kconfig.mcs @@ -1,7 +1,7 @@ # Bluetooth Audio - Media control configuration options # -# Copyright (c) 2020-2022 Nordic Semiconductor +# Copyright (c) 2020-2026 Nordic Semiconductor # # SPDX-License-Identifier: Apache-2.0 # @@ -11,7 +11,6 @@ config BT_MCS bool "Media Control Service Support" depends on MCTL_LOCAL_PLAYER_REMOTE_CONTROL - depends on UTF8 depends on BT_GATT_DYNAMIC_DB depends on BT_SMP help diff --git a/subsys/bluetooth/audio/Kconfig.tbs b/subsys/bluetooth/audio/Kconfig.tbs index 3a06931495b0..51345b1cbd85 100644 --- a/subsys/bluetooth/audio/Kconfig.tbs +++ b/subsys/bluetooth/audio/Kconfig.tbs @@ -1,7 +1,7 @@ # Bluetooth Audio - Call control configuration options # # Copyright (c) 2020 Bose Corporation -# Copyright (c) 2024 Nordic Semiconductor ASA +# Copyright (c) 2024-2026 Nordic Semiconductor ASA # # SPDX-License-Identifier: Apache-2.0 # @@ -14,7 +14,6 @@ config BT_TBS bool "Telephone Bearer Service Support" depends on BT_GATT_DYNAMIC_DB depends on BT_SMP - depends on UTF8 help This option enables support for Telephone Bearer Service. By default this only initializes the GTBS service. If specific TBS services are wanted, they need to be @@ -70,7 +69,6 @@ config BT_TBS_CLIENT_GTBS depends on BT_GATT_CLIENT depends on BT_GATT_AUTO_DISCOVER_CCC depends on BT_SMP - depends on UTF8 help This option enables support for the GTBS-oriented Call Control client. @@ -79,7 +77,6 @@ config BT_TBS_CLIENT_TBS depends on BT_GATT_CLIENT depends on BT_GATT_AUTO_DISCOVER_CCC depends on BT_SMP - depends on UTF8 help This option enables support for the TBS-oriented Call Control client. diff --git a/tests/bluetooth/audio/bap_base/prj.conf b/tests/bluetooth/audio/bap_base/prj.conf index 6a009f22b509..ed0af24e09b7 100644 --- a/tests/bluetooth/audio/bap_base/prj.conf +++ b/tests/bluetooth/audio/bap_base/prj.conf @@ -2,6 +2,7 @@ CONFIG_ZTEST=y CONFIG_BT=y CONFIG_BT_SMP=y +CONFIG_UTF8=y CONFIG_BT_AUDIO=y CONFIG_BT_PERIPHERAL=y CONFIG_BT_OBSERVER=y diff --git a/tests/bluetooth/audio/ccid/prj.conf b/tests/bluetooth/audio/ccid/prj.conf index 53a381c240c8..7db0a56b6961 100644 --- a/tests/bluetooth/audio/ccid/prj.conf +++ b/tests/bluetooth/audio/ccid/prj.conf @@ -3,6 +3,7 @@ CONFIG_ZTEST=y CONFIG_BT=y CONFIG_BT_PERIPHERAL=y CONFIG_BT_GATT_DYNAMIC_DB=y +CONFIG_UTF8=y CONFIG_BT_AUDIO=y CONFIG_ASSERT=y diff --git a/tests/bluetooth/audio/codec/prj.conf b/tests/bluetooth/audio/codec/prj.conf index 6ec6e976f7f8..d6cbc31a8cf5 100644 --- a/tests/bluetooth/audio/codec/prj.conf +++ b/tests/bluetooth/audio/codec/prj.conf @@ -4,6 +4,7 @@ CONFIG_BT=y CONFIG_BT_SMP=y CONFIG_BT_PERIPHERAL=y CONFIG_BT_ISO_PERIPHERAL=y +CONFIG_UTF8=y CONFIG_BT_AUDIO=y CONFIG_BT_GATT_DYNAMIC_DB=y CONFIG_BT_ATT_PREPARE_COUNT=1 diff --git a/tests/bluetooth/audio/pacs/prj.conf b/tests/bluetooth/audio/pacs/prj.conf index 4846edb9f54b..44a2ddd7ab27 100644 --- a/tests/bluetooth/audio/pacs/prj.conf +++ b/tests/bluetooth/audio/pacs/prj.conf @@ -4,6 +4,7 @@ CONFIG_BT=y CONFIG_BT_PERIPHERAL=y CONFIG_BT_SMP=y CONFIG_BT_GATT_DYNAMIC_DB=y +CONFIG_UTF8=y CONFIG_BT_AUDIO=y CONFIG_BT_PAC_SNK=y CONFIG_BT_PAC_SNK_LOC=y From a6c54dcf689f41ed291d4775c47f47be87c8d94a Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Thu, 15 Jan 2026 21:06:27 +0100 Subject: [PATCH 2122/3659] doc: releases: Add note about UTF8 for CONFIG_BT_AUDIO CONFIG_BT_AUDIO now depends on CONFIG_UTF8. Add instructions on how to (easily) migrate. Signed-off-by: Emil Gydesen --- doc/releases/migration-guide-4.4.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/releases/migration-guide-4.4.rst b/doc/releases/migration-guide-4.4.rst index d50c6e09dce4..399377aa4e1d 100644 --- a/doc/releases/migration-guide-4.4.rst +++ b/doc/releases/migration-guide-4.4.rst @@ -613,6 +613,9 @@ Bluetooth Audio receive states at the end of the procedure. Users will have to manually call :c:func:`bt_bap_broadcast_assistant_read_recv_state` to read the existing receive states, if any, prior to performing any operations. (:github:`91587`) +* :kconfig:option:`CONFIG_BT_AUDIO` now depends on :kconfig:option:`CONFIG_UTF8`. + Applications that enable :kconfig:option:`CONFIG_BT_AUDIO` must also have + :kconfig:option:`CONFIG_UTF8` enabled. (:github:`102350`) Bluetooth Mesh ============== From e5126a08741a4a019681ab35228dcda5a9312286 Mon Sep 17 00:00:00 2001 From: Tomasz Gorochowik Date: Thu, 15 Jan 2026 13:07:27 +0100 Subject: [PATCH 2123/3659] doc/develop/manifest/external: add grvl Add grvl [1] as an external module to Zephyr. 1: https://github.com/antmicro/grvl Signed-off-by: Tomasz Gorochowik --- doc/develop/manifest/external/grvl.rst | 79 ++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 doc/develop/manifest/external/grvl.rst diff --git a/doc/develop/manifest/external/grvl.rst b/doc/develop/manifest/external/grvl.rst new file mode 100644 index 000000000000..f8bb876c52f5 --- /dev/null +++ b/doc/develop/manifest/external/grvl.rst @@ -0,0 +1,79 @@ +.. _external_module_grvl: + +grvl +#### + +Introduction +************ + +`Graphics Rendering Visual Library`_ (grvl) is a lightweight GUI library for Zephyr-based MCUs, +providing a portable solution that is both suitable for resource-constrained devices and offers +a modern, responsive user experience. + +Internally, grvl links to a standard XML library called `tinyxml`_ that is used for parsing the GUI +config instead of code. The UI interaction can be scripted with JavaScript using the integrated +`Duktape`_ JavaScript engine. + +grvl features: + +* Native support for PNG and JPEG graphics +* Simple DirectMedia Layer compatibility +* POSIX compliance and Zephyr support +* A collection of built-in components + + * Popups + * Fonts + * Labels + * Buttons + * Sliders + +* User-defined prefabs that can be used to instantiate complex structures at runtime +* XML-based layout and a JavaScript engine + +grvl is licensed under the Apache License 2.0. +tinyxml is licensed under the Zlib license. +Duktape is licensed under the MIT License. + +Usage with Zephyr +***************** + +To use grvl as a Zephyr :ref:`module `, add the following entry: + +.. code-block:: yaml + + manifest: + projects: + - name: grvl + url: https://github.com/antmicro/grvl + revision: main + path: modules/grvl # adjust the path as needed + +to a Zephyr submanifest (e.g. ``zephyr/submanifests/grvl.yaml``) and run ``west update``, or add it +as a West project in your project's ``west.yaml`` manifest. + +For more information, see the `grvl documentation`_ or the `grvl blog article`_. + +You can also try an interactive `Zephyr calendar demo`_. + +Reference +********* + +.. target-notes:: + +.. _Graphics Rendering Visual Library: + https://github.com/antmicro/grvl + +.. _tinyxml: + https://github.com/leethomason/tinyxml2 + +.. _Duktape: + https://github.com/svaarala/duktape + +.. _grvl documentation: + https://antmicro.github.io/grvl/ + +.. _Zephyr calendar demo: + https://github.com/antmicro/grvl-zephyr-calendar-demo + +.. _grvl blog article: + https://antmicro.com/blog/2025/12/grvl-a-lightweight-gui-library-for-zephyr-based-mcus From ed5683250c7b0dd3692f56fe0e21fd453dfefe04 Mon Sep 17 00:00:00 2001 From: Kyra Lengfeld Date: Thu, 15 Jan 2026 12:20:26 +0100 Subject: [PATCH 2124/3659] Bluetooth: Host: make TX processor stack size configurable While the tx processor thread is needed to prevent deadlocks and is as such always enabled, its stack size may be adjusted based on need. What is needed is dependent on which features are enabled in the zephyr host as well as other project configurations impacting the zephyr host. Signed-off-by: Kyra Lengfeld --- subsys/bluetooth/host/Kconfig | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/subsys/bluetooth/host/Kconfig b/subsys/bluetooth/host/Kconfig index 05e69f9e8c2a..4054d6c99a41 100644 --- a/subsys/bluetooth/host/Kconfig +++ b/subsys/bluetooth/host/Kconfig @@ -148,8 +148,12 @@ config BT_TX_PROCESSOR_THREAD_PRIO default SYSTEM_WORKQUEUE_PRIORITY config BT_TX_PROCESSOR_STACK_SIZE - int + int "TX processor thread stack size" default 1024 + help + Size of the TX processor thread stack. How much stack is needed depends on which + and how many host features are enabled. One might try to decrease it to save RAM, + or increase it if there are stack overflows. endif From 03e8e88d79cd58010de910f3aab1870114ace03f Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Thu, 15 Jan 2026 09:00:15 +0000 Subject: [PATCH 2125/3659] soc: nordic: Add SOC_SERIES_NRF* Kconfigs without X suffix This is to start the process of fixing the issue of the SoC series not matching the value in the soc.yml file, which is needed to support future build system features for automatically creating SoC Kconfigs by the build system. This also fixes some oddities with how the Kconfigs were set out, which included duplicated Kconfigs and duplicate selections and having them in the wrong (or differing) files, to actually follow how HWMv2 should define these Kconfigs. Signed-off-by: Jamie McCrae --- scripts/west_commands/tests/test_nrf.py | 2 +- soc/nordic/Kconfig.soc | 62 ------------------------- soc/nordic/nrf51/Kconfig.soc | 10 +++- soc/nordic/nrf52/Kconfig.soc | 10 +++- soc/nordic/nrf53/Kconfig.soc | 9 +++- soc/nordic/nrf54h/Kconfig.soc | 13 ++++++ soc/nordic/nrf54l/Kconfig.soc | 13 ++++++ soc/nordic/nrf71/Kconfig.soc | 9 ++++ soc/nordic/nrf91/Kconfig.soc | 10 +++- soc/nordic/nrf92/Kconfig.soc | 13 ++++++ 10 files changed, 84 insertions(+), 67 deletions(-) diff --git a/scripts/west_commands/tests/test_nrf.py b/scripts/west_commands/tests/test_nrf.py index 0f40c2d27a9a..2c3483ab4207 100644 --- a/scripts/west_commands/tests/test_nrf.py +++ b/scripts/west_commands/tests/test_nrf.py @@ -364,7 +364,7 @@ def fix_up_runner_config(test_case, runner_config, tmpdir): dotconfig = os.fspath(zephyr / '.config') with open(dotconfig, 'w') as f: f.write(f''' -CONFIG_SOC_SERIES_{test_case.family.upper()}X=y +CONFIG_SOC_SERIES_{test_case.family.upper()}=y ''') if test_case.family == 'nrf53': f.write(f''' diff --git a/soc/nordic/Kconfig.soc b/soc/nordic/Kconfig.soc index 15913e12dce0..b6b68882db8e 100644 --- a/soc/nordic/Kconfig.soc +++ b/soc/nordic/Kconfig.soc @@ -2,72 +2,10 @@ # SPDX-License-Identifier: Apache-2.0 -# This file contains Zephyr hw module v2 Kconfig description for -# Nordic Semiconductor SoCs. -# The hw model v2 is generic and contains no Kconfig references outside its own -# tree structure and is therefore reusable in Kconfig trees outside a Zephyr build. - -config SOC_SERIES - default "nrf51" if SOC_SERIES_NRF51X - default "nrf52" if SOC_SERIES_NRF52X - default "nrf53" if SOC_SERIES_NRF53X - default "nrf54h" if SOC_SERIES_NRF54HX - default "nrf54l" if SOC_SERIES_NRF54LX - default "nrf71" if SOC_SERIES_NRF71 - default "nrf91" if SOC_SERIES_NRF91X - default "nrf92" if SOC_SERIES_NRF92X - config SOC_FAMILY_NORDIC_NRF bool config SOC_FAMILY default "nordic_nrf" if SOC_FAMILY_NORDIC_NRF -config SOC_SERIES_NRF51X - bool - help - Enable support for NRF51 MCU series - -config SOC_SERIES_NRF52X - bool - select SOC_FAMILY_NORDIC_NRF - help - Enable support for NRF52 MCU series - -config SOC_SERIES_NRF53X - bool - select SOC_FAMILY_NORDIC_NRF - help - Enable support for NRF53 MCU series - -config SOC_SERIES_NRF54HX - bool - select SOC_FAMILY_NORDIC_NRF - help - Nordic Semiconductor nRF54H series MCU - -config SOC_SERIES_NRF54LX - bool - select SOC_FAMILY_NORDIC_NRF - help - Nordic Semiconductor nRF54L series MCU - -config SOC_SERIES_NRF71 - bool - select SOC_FAMILY_NORDIC_NRF - help - Nordic Semiconductor nRF71 series MCU - -config SOC_SERIES_NRF91X - bool - select SOC_FAMILY_NORDIC_NRF - help - Enable support for NRF91 MCU series - -config SOC_SERIES_NRF92X - bool - select SOC_FAMILY_NORDIC_NRF - help - Enable support for NRF92 MCU series - rsource "*/Kconfig.soc" diff --git a/soc/nordic/nrf51/Kconfig.soc b/soc/nordic/nrf51/Kconfig.soc index c19da7a18a14..ce2bc7d1e227 100644 --- a/soc/nordic/nrf51/Kconfig.soc +++ b/soc/nordic/nrf51/Kconfig.soc @@ -3,11 +3,19 @@ # Copyright (c) 2016 Linaro Limited # SPDX-License-Identifier: Apache-2.0 -config SOC_SERIES_NRF51X +config SOC_SERIES_NRF51 + bool select SOC_FAMILY_NORDIC_NRF help Enable support for NRF51 MCU series +config SOC_SERIES_NRF51X + bool + select SOC_SERIES_NRF51 + +config SOC_SERIES + default "nrf51" if SOC_SERIES_NRF51 + config SOC_NRF51822_QFAA bool select SOC_SERIES_NRF51X diff --git a/soc/nordic/nrf52/Kconfig.soc b/soc/nordic/nrf52/Kconfig.soc index 24a5249205da..2a5eec9a52d3 100644 --- a/soc/nordic/nrf52/Kconfig.soc +++ b/soc/nordic/nrf52/Kconfig.soc @@ -3,11 +3,19 @@ # Copyright (c) 2022-2023 Nordic Semiconductor ASA # SPDX-License-Identifier: Apache-2.0 -config SOC_SERIES_NRF52X +config SOC_SERIES_NRF52 + bool select SOC_FAMILY_NORDIC_NRF help Enable support for NRF52 MCU series +config SOC_SERIES_NRF52X + bool + select SOC_SERIES_NRF52 + +config SOC_SERIES + default "nrf52" if SOC_SERIES_NRF52 + config SOC_NRF52805 bool select SOC_SERIES_NRF52X diff --git a/soc/nordic/nrf53/Kconfig.soc b/soc/nordic/nrf53/Kconfig.soc index 87889775dc74..6374644d2ea5 100644 --- a/soc/nordic/nrf53/Kconfig.soc +++ b/soc/nordic/nrf53/Kconfig.soc @@ -3,12 +3,19 @@ # Copyright (c) 2023 Nordic Semiconductor ASA # SPDX-License-Identifier: Apache-2.0 -config SOC_SERIES_NRF53X +config SOC_SERIES_NRF53 bool select SOC_FAMILY_NORDIC_NRF help Enable support for NRF53 MCU series +config SOC_SERIES_NRF53X + bool + select SOC_SERIES_NRF53 + +config SOC_SERIES + default "nrf53" if SOC_SERIES_NRF53 + config SOC_NRF5340_CPUAPP bool select SOC_SERIES_NRF53X diff --git a/soc/nordic/nrf54h/Kconfig.soc b/soc/nordic/nrf54h/Kconfig.soc index 459854e13b2d..0cc8910f872d 100644 --- a/soc/nordic/nrf54h/Kconfig.soc +++ b/soc/nordic/nrf54h/Kconfig.soc @@ -3,6 +3,19 @@ # Copyright (c) 2024 Nordic Semiconductor ASA # SPDX-License-Identifier: Apache-2.0 +config SOC_SERIES_NRF54H + bool + select SOC_FAMILY_NORDIC_NRF + help + Nordic Semiconductor nRF54H series MCU + +config SOC_SERIES_NRF54HX + bool + select SOC_SERIES_NRF54H + +config SOC_SERIES + default "nrf54h" if SOC_SERIES_NRF54H + config SOC_NRF54H20 bool select SOC_SERIES_NRF54HX diff --git a/soc/nordic/nrf54l/Kconfig.soc b/soc/nordic/nrf54l/Kconfig.soc index 9e2efd1d762b..cd5f026d623c 100644 --- a/soc/nordic/nrf54l/Kconfig.soc +++ b/soc/nordic/nrf54l/Kconfig.soc @@ -3,6 +3,19 @@ # Copyright (c) 2024 Nordic Semiconductor ASA # SPDX-License-Identifier: Apache-2.0 +config SOC_SERIES_NRF54L + bool + select SOC_FAMILY_NORDIC_NRF + help + Nordic Semiconductor nRF54L series MCU + +config SOC_SERIES_NRF54LX + bool + select SOC_SERIES_NRF54L + +config SOC_SERIES + default "nrf54l" if SOC_SERIES_NRF54L + config SOC_NRF54L05 bool select SOC_SERIES_NRF54LX diff --git a/soc/nordic/nrf71/Kconfig.soc b/soc/nordic/nrf71/Kconfig.soc index 93521c98caa0..dafd82ab9691 100644 --- a/soc/nordic/nrf71/Kconfig.soc +++ b/soc/nordic/nrf71/Kconfig.soc @@ -3,12 +3,21 @@ # Copyright (c) 2025 Nordic Semiconductor ASA # SPDX-License-Identifier: Apache-2.0 +config SOC_SERIES_NRF71 + bool + select SOC_FAMILY_NORDIC_NRF + help + Nordic Semiconductor nRF71 series MCU + config SOC_NRF7120 bool select SOC_SERIES_NRF71 help NRF7120 +config SOC_SERIES + default "nrf71" if SOC_SERIES_NRF71 + config SOC_NRF7120_ENGA bool select SOC_NRF7120 diff --git a/soc/nordic/nrf91/Kconfig.soc b/soc/nordic/nrf91/Kconfig.soc index 452c353a109e..9ff096674695 100644 --- a/soc/nordic/nrf91/Kconfig.soc +++ b/soc/nordic/nrf91/Kconfig.soc @@ -3,11 +3,19 @@ # Copyright (c) 2018 Nordic Semiconductor ASA # SPDX-License-Identifier: Apache-2.0 -config SOC_SERIES_NRF91X +config SOC_SERIES_NRF91 + bool select SOC_FAMILY_NORDIC_NRF help Enable support for NRF91 MCU series +config SOC_SERIES_NRF91X + bool + select SOC_SERIES_NRF91 + +config SOC_SERIES + default "nrf91" if SOC_SERIES_NRF91 + config SOC_NRF9120 bool select SOC_SERIES_NRF91X diff --git a/soc/nordic/nrf92/Kconfig.soc b/soc/nordic/nrf92/Kconfig.soc index 99fc28643b74..0f7672e98b18 100644 --- a/soc/nordic/nrf92/Kconfig.soc +++ b/soc/nordic/nrf92/Kconfig.soc @@ -18,6 +18,19 @@ # as build target, and so that its definition can also be re-used # for other SiPs. +config SOC_SERIES_NRF92 + bool + select SOC_FAMILY_NORDIC_NRF + help + Enable support for NRF92 MCU series + +config SOC_SERIES_NRF92X + bool + select SOC_SERIES_NRF92 + +config SOC_SERIES + default "nrf92" if SOC_SERIES_NRF92 + config SOC_NRF9230_ENGB bool select SOC_SERIES_NRF92X From 212b63a6ca3cbd649d74eed012ae4b4572635cc0 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Thu, 15 Jan 2026 09:02:19 +0000 Subject: [PATCH 2126/3659] soc: nordic: Update to use SOC_SERIES_NRF Kconfigs without X suffix Updates usage of the old Kconfig to use the new Kconfig Signed-off-by: Jamie McCrae --- soc/nordic/Kconfig | 20 ++++++++++---------- soc/nordic/common/CMakeLists.txt | 2 +- soc/nordic/common/nrf_sys_event.c | 2 +- soc/nordic/common/poweroff.c | 14 +++++++------- soc/nordic/common/uicr/Kconfig.sysbuild | 2 +- soc/nordic/common/vpr/Kconfig | 4 ++-- soc/nordic/nrf51/Kconfig | 2 +- soc/nordic/nrf51/Kconfig.defconfig | 4 ++-- soc/nordic/nrf51/Kconfig.soc | 6 +++--- soc/nordic/nrf52/Kconfig | 6 +++--- soc/nordic/nrf52/Kconfig.defconfig | 4 ++-- soc/nordic/nrf52/Kconfig.soc | 14 +++++++------- soc/nordic/nrf53/Kconfig | 6 +++--- soc/nordic/nrf53/Kconfig.defconfig | 4 ++-- soc/nordic/nrf53/Kconfig.soc | 4 ++-- soc/nordic/nrf54h/Kconfig | 2 +- soc/nordic/nrf54h/Kconfig.defconfig | 4 ++-- soc/nordic/nrf54h/Kconfig.soc | 2 +- soc/nordic/nrf54l/Kconfig | 6 +++--- soc/nordic/nrf54l/Kconfig.defconfig | 4 ++-- soc/nordic/nrf54l/Kconfig.soc | 8 ++++---- soc/nordic/nrf91/Kconfig | 6 +++--- soc/nordic/nrf91/Kconfig.defconfig | 4 ++-- soc/nordic/nrf91/Kconfig.soc | 4 ++-- soc/nordic/nrf92/Kconfig | 2 +- soc/nordic/nrf92/Kconfig.defconfig | 4 ++-- soc/nordic/nrf92/Kconfig.soc | 2 +- soc/nordic/timing.c | 4 ++-- soc/nordic/validate_base_addresses.c | 8 ++++---- soc/nordic/validate_enabled_instances.c | 12 ++++++------ 30 files changed, 83 insertions(+), 83 deletions(-) diff --git a/soc/nordic/Kconfig b/soc/nordic/Kconfig index 7ffc9319415a..22ae416bfbfa 100644 --- a/soc/nordic/Kconfig +++ b/soc/nordic/Kconfig @@ -69,8 +69,8 @@ rsource "*/Kconfig" config NRF_SOC_SECURE_SUPPORTED def_bool !TRUSTED_EXECUTION_NONSECURE || (BUILD_WITH_TFM && TFM_PARTITION_PLATFORM) - depends on !SOC_SERIES_NRF54HX - depends on !SOC_SERIES_NRF92X + depends on !SOC_SERIES_NRF54H + depends on !SOC_SERIES_NRF92 help Hidden function to indicate that the soc_secure functions are available. @@ -130,8 +130,8 @@ config NRF_ACL_FLASH_REGION_SIZE choice NRF_APPROTECT_HANDLING bool "APPROTECT handling" - depends on SOC_SERIES_NRF52X || SOC_SERIES_NRF53X || SOC_NRF54L_CPUAPP_COMMON || \ - SOC_SERIES_NRF91X + depends on SOC_SERIES_NRF52 || SOC_SERIES_NRF53 || SOC_NRF54L_CPUAPP_COMMON || \ + SOC_SERIES_NRF91 default NRF_APPROTECT_DISABLE if SOC_NRF54L_CPUAPP_COMMON default NRF_APPROTECT_USE_UICR help @@ -147,7 +147,7 @@ config NRF_APPROTECT_DISABLE config NRF_APPROTECT_USE_UICR bool "Use UICR" - depends on SOC_SERIES_NRF52X || SOC_SERIES_NRF53X || SOC_SERIES_NRF91X + depends on SOC_SERIES_NRF52 || SOC_SERIES_NRF53 || SOC_SERIES_NRF91 help When this option is selected, the SystemInit() function loads the firmware branch state of the APPROTECT mechanism from UICR, so if @@ -162,7 +162,7 @@ config NRF_APPROTECT_LOCK config NRF_APPROTECT_USER_HANDLING bool "Allow user handling" - depends on !SOC_SERIES_NRF52X + depends on !SOC_SERIES_NRF52 help When this option is selected, the SystemInit() function does not touch the APPROTECT mechanism, allowing the user code to handle it @@ -172,7 +172,7 @@ endchoice choice NRF_SECURE_APPROTECT_HANDLING bool "Secure APPROTECT handling" - depends on SOC_NRF5340_CPUAPP || SOC_NRF54L_CPUAPP_COMMON || SOC_SERIES_NRF91X + depends on SOC_NRF5340_CPUAPP || SOC_NRF54L_CPUAPP_COMMON || SOC_SERIES_NRF91 default NRF_SECURE_APPROTECT_DISABLE if SOC_NRF54L_CPUAPP_COMMON default NRF_SECURE_APPROTECT_USE_UICR help @@ -188,7 +188,7 @@ config NRF_SECURE_APPROTECT_DISABLE config NRF_SECURE_APPROTECT_USE_UICR bool "Use UICR" - depends on SOC_NRF5340_CPUAPP || SOC_SERIES_NRF91X + depends on SOC_NRF5340_CPUAPP || SOC_SERIES_NRF91 help When this option is selected, the SystemInit() function loads the firmware branch state of the secure APPROTECT mechanism from UICR, @@ -204,7 +204,7 @@ config NRF_SECURE_APPROTECT_LOCK config NRF_SECURE_APPROTECT_USER_HANDLING bool "Allow user handling" - depends on !SOC_SERIES_NRF52X + depends on !SOC_SERIES_NRF52 help When this option is selected, the SystemInit() function does not touch the secure APPROTECT mechanism, allowing the user code to @@ -224,7 +224,7 @@ config NRF_SKIP_CLOCK_CONFIG config NRF_TRACE_PORT bool "nRF TPIU" - depends on !SOC_SERIES_NRF51X + depends on !SOC_SERIES_NRF51 help Enable this option to initialize the TPIU (Trace Port Interface Unit) for tracing using a hardware probe. If disabled, the trace diff --git a/soc/nordic/common/CMakeLists.txt b/soc/nordic/common/CMakeLists.txt index 0a2825dd741f..ea52fd5dfc4e 100644 --- a/soc/nordic/common/CMakeLists.txt +++ b/soc/nordic/common/CMakeLists.txt @@ -19,7 +19,7 @@ if(CONFIG_ARM) zephyr_library_sources_ifdef(CONFIG_NRF_PLATFORM_HALTIUM soc_lrcconf.c) endif() -if((CONFIG_SOC_SERIES_NRF54HX OR CONFIG_SOC_SERIES_NRF92X) AND CONFIG_CPU_HAS_CUSTOM_FIXED_SOC_MPU_REGIONS) +if((CONFIG_SOC_SERIES_NRF54H OR CONFIG_SOC_SERIES_NRF92) AND CONFIG_CPU_HAS_CUSTOM_FIXED_SOC_MPU_REGIONS) zephyr_library_sources(nrf54hx_nrf92x_mpu_regions.c) endif() diff --git a/soc/nordic/common/nrf_sys_event.c b/soc/nordic/common/nrf_sys_event.c index 423ec641689f..809ad2e71005 100644 --- a/soc/nordic/common/nrf_sys_event.c +++ b/soc/nordic/common/nrf_sys_event.c @@ -16,7 +16,7 @@ #endif LOG_MODULE_DECLARE(soc, CONFIG_SOC_LOG_LEVEL); -#if CONFIG_SOC_SERIES_NRF54HX +#if CONFIG_SOC_SERIES_NRF54H /* * The 54HX is not yet supported by an nrfx driver nor the system controller so diff --git a/soc/nordic/common/poweroff.c b/soc/nordic/common/poweroff.c index ebce3aae77cd..eae8341c3e69 100644 --- a/soc/nordic/common/poweroff.c +++ b/soc/nordic/common/poweroff.c @@ -7,14 +7,14 @@ #include #include -#if defined(CONFIG_SOC_SERIES_NRF51X) || defined(CONFIG_SOC_SERIES_NRF52X) +#if defined(CONFIG_SOC_SERIES_NRF51) || defined(CONFIG_SOC_SERIES_NRF52) #include -#elif defined(CONFIG_SOC_SERIES_NRF54HX) +#elif defined(CONFIG_SOC_SERIES_NRF54H) #include #else #include #endif -#if defined(CONFIG_SOC_SERIES_NRF54LX) +#if defined(CONFIG_SOC_SERIES_NRF54L) #include #include #endif @@ -23,7 +23,7 @@ #include #endif -#if defined(CONFIG_SOC_SERIES_NRF54LX) +#if defined(CONFIG_SOC_SERIES_NRF54L) #define VPR_POWER_IDX 1 #define VPR_RET_BIT MEMCONF_POWER_RET_MEM0_Pos #endif @@ -64,15 +64,15 @@ void z_sys_poweroff(void) (void)z_nrf_retained_mem_retention_apply(); #endif -#if defined(CONFIG_SOC_SERIES_NRF54LX) +#if defined(CONFIG_SOC_SERIES_NRF54L) /* Set VPR to remain in its reset state when waking from OFF */ nrf_memconf_ramblock_ret_enable_set(NRF_MEMCONF, VPR_POWER_IDX, VPR_RET_BIT, false); nrfx_reset_reason_clear(UINT32_MAX); #endif -#if defined(CONFIG_SOC_SERIES_NRF51X) || defined(CONFIG_SOC_SERIES_NRF52X) +#if defined(CONFIG_SOC_SERIES_NRF51) || defined(CONFIG_SOC_SERIES_NRF52) nrf_power_system_off(NRF_POWER); -#elif defined(CONFIG_SOC_SERIES_NRF54HX) +#elif defined(CONFIG_SOC_SERIES_NRF54H) nrf_poweroff(); #else nrf_regulators_system_off(NRF_REGULATORS); diff --git a/soc/nordic/common/uicr/Kconfig.sysbuild b/soc/nordic/common/uicr/Kconfig.sysbuild index 977f910b1617..df44dc0fcc99 100644 --- a/soc/nordic/common/uicr/Kconfig.sysbuild +++ b/soc/nordic/common/uicr/Kconfig.sysbuild @@ -3,7 +3,7 @@ config NRF_HALTIUM_GENERATE_UICR bool "Generate UICR artifacts" - depends on SOC_SERIES_NRF54HX || SOC_SERIES_NRF92X + depends on SOC_SERIES_NRF54H || SOC_SERIES_NRF92 default y help When enabled, a UICR generator image is included in the build. diff --git a/soc/nordic/common/vpr/Kconfig b/soc/nordic/common/vpr/Kconfig index bab6a30a6a9f..e3f8a717cba3 100644 --- a/soc/nordic/common/vpr/Kconfig +++ b/soc/nordic/common/vpr/Kconfig @@ -15,8 +15,8 @@ config RISCV_CORE_NORDIC_VPR select RISCV_HAS_CLIC select RISCV_SOC_CONTEXT_SAVE select HAS_FLASH_LOAD_OFFSET - select ARCH_HAS_CUSTOM_CPU_IDLE if !SOC_SERIES_NRF54LX - select ARCH_HAS_CUSTOM_CPU_ATOMIC_IDLE if !SOC_SERIES_NRF54LX + select ARCH_HAS_CUSTOM_CPU_IDLE if !SOC_SERIES_NRF54L + select ARCH_HAS_CUSTOM_CPU_ATOMIC_IDLE if !SOC_SERIES_NRF54L select INCLUDE_RESET_VECTOR imply XIP help diff --git a/soc/nordic/nrf51/Kconfig b/soc/nordic/nrf51/Kconfig index e212c7ecd660..162896e1fb9d 100644 --- a/soc/nordic/nrf51/Kconfig +++ b/soc/nordic/nrf51/Kconfig @@ -4,7 +4,7 @@ # Copyright (c) 2018 Nordic Semiconductor ASA # SPDX-License-Identifier: Apache-2.0 -config SOC_SERIES_NRF51X +config SOC_SERIES_NRF51 select ARM select CPU_CORTEX_M0 imply XIP diff --git a/soc/nordic/nrf51/Kconfig.defconfig b/soc/nordic/nrf51/Kconfig.defconfig index dad7aedf09c8..81a7047ddbf2 100644 --- a/soc/nordic/nrf51/Kconfig.defconfig +++ b/soc/nordic/nrf51/Kconfig.defconfig @@ -4,7 +4,7 @@ # Copyright (c) 2018 Nordic Semiconductor ASA # SPDX-License-Identifier: Apache-2.0 -if SOC_SERIES_NRF51X +if SOC_SERIES_NRF51 config NUM_IRQS default 26 @@ -12,4 +12,4 @@ config NUM_IRQS config SYS_CLOCK_HW_CYCLES_PER_SEC default $(dt_nodelabel_int_prop,rtc1,clock-frequency) -endif # SOC_SERIES_NRF51X +endif # SOC_SERIES_NRF51 diff --git a/soc/nordic/nrf51/Kconfig.soc b/soc/nordic/nrf51/Kconfig.soc index ce2bc7d1e227..96d0d885e9b2 100644 --- a/soc/nordic/nrf51/Kconfig.soc +++ b/soc/nordic/nrf51/Kconfig.soc @@ -18,15 +18,15 @@ config SOC_SERIES config SOC_NRF51822_QFAA bool - select SOC_SERIES_NRF51X + select SOC_SERIES_NRF51 config SOC_NRF51822_QFAB bool - select SOC_SERIES_NRF51X + select SOC_SERIES_NRF51 config SOC_NRF51822_QFAC bool - select SOC_SERIES_NRF51X + select SOC_SERIES_NRF51 config SOC default "nrf51822" if SOC_NRF51822_QFAA || SOC_NRF51822_QFAB || SOC_NRF51822_QFAC diff --git a/soc/nordic/nrf52/Kconfig b/soc/nordic/nrf52/Kconfig index ff29b6ac69de..fe406abfa016 100644 --- a/soc/nordic/nrf52/Kconfig +++ b/soc/nordic/nrf52/Kconfig @@ -3,7 +3,7 @@ # Copyright (c) 2016-2023 Nordic Semiconductor ASA # SPDX-License-Identifier: Apache-2.0 -config SOC_SERIES_NRF52X +config SOC_SERIES_NRF52 select ARM select SOC_COMPATIBLE_NRF52X select CPU_CORTEX_M4 @@ -29,7 +29,7 @@ config SOC_NRF52840 select CPU_CORTEX_M_HAS_DWT select CPU_HAS_FPU -if SOC_SERIES_NRF52X +if SOC_SERIES_NRF52 config SOC_DCDC_NRF52X bool @@ -136,4 +136,4 @@ config NRF52_ANOMALY_219_WORKAROUND the I2C specification at 400 kHz. This workaround configures the I2C frequency to 390 kHz instead of 400 kHz. -endif # SOC_SERIES_NRF52X +endif # SOC_SERIES_NRF52 diff --git a/soc/nordic/nrf52/Kconfig.defconfig b/soc/nordic/nrf52/Kconfig.defconfig index a8220ea2f489..03a84750ff65 100644 --- a/soc/nordic/nrf52/Kconfig.defconfig +++ b/soc/nordic/nrf52/Kconfig.defconfig @@ -3,11 +3,11 @@ # Copyright (c) 2016-2018 Nordic Semiconductor ASA # SPDX-License-Identifier: Apache-2.0 -if SOC_SERIES_NRF52X +if SOC_SERIES_NRF52 rsource "Kconfig.defconfig.nrf52*" config SYS_CLOCK_HW_CYCLES_PER_SEC default $(dt_nodelabel_int_prop,rtc1,clock-frequency) -endif # SOC_SERIES_NRF52X +endif # SOC_SERIES_NRF52 diff --git a/soc/nordic/nrf52/Kconfig.soc b/soc/nordic/nrf52/Kconfig.soc index 2a5eec9a52d3..f510637a3fac 100644 --- a/soc/nordic/nrf52/Kconfig.soc +++ b/soc/nordic/nrf52/Kconfig.soc @@ -18,31 +18,31 @@ config SOC_SERIES config SOC_NRF52805 bool - select SOC_SERIES_NRF52X + select SOC_SERIES_NRF52 config SOC_NRF52810 bool - select SOC_SERIES_NRF52X + select SOC_SERIES_NRF52 config SOC_NRF52811 bool - select SOC_SERIES_NRF52X + select SOC_SERIES_NRF52 config SOC_NRF52820 bool - select SOC_SERIES_NRF52X + select SOC_SERIES_NRF52 config SOC_NRF52832 bool - select SOC_SERIES_NRF52X + select SOC_SERIES_NRF52 config SOC_NRF52833 bool - select SOC_SERIES_NRF52X + select SOC_SERIES_NRF52 config SOC_NRF52840 bool - select SOC_SERIES_NRF52X + select SOC_SERIES_NRF52 config SOC_NRF52805_CAAA bool diff --git a/soc/nordic/nrf53/Kconfig b/soc/nordic/nrf53/Kconfig index 7260d5c7d66d..f56351d8d053 100644 --- a/soc/nordic/nrf53/Kconfig +++ b/soc/nordic/nrf53/Kconfig @@ -3,7 +3,7 @@ # Copyright (c) 2019 Nordic Semiconductor ASA # SPDX-License-Identifier: Apache-2.0 -config SOC_SERIES_NRF53X +config SOC_SERIES_NRF53 bool select ARM select SOC_COMPATIBLE_NRF53X @@ -38,7 +38,7 @@ config SOC_NRF5340_CPUNET imply SOC_NRF53_RTC_PRETICK if !WDT_NRFX imply SOC_NRF53_ANOMALY_168_WORKAROUND -if SOC_SERIES_NRF53X +if SOC_SERIES_NRF53 VREGMAIN_PATH := $(dt_nodelabel_path,vregmain) VREGRADIO_PATH := $(dt_nodelabel_path,vregradio) @@ -292,4 +292,4 @@ config BUILD_WITH_TFM rsource "Kconfig.sync_rtc" -endif # SOC_SERIES_NRF53X +endif # SOC_SERIES_NRF53 diff --git a/soc/nordic/nrf53/Kconfig.defconfig b/soc/nordic/nrf53/Kconfig.defconfig index 82974c027426..92d8ff138e6f 100644 --- a/soc/nordic/nrf53/Kconfig.defconfig +++ b/soc/nordic/nrf53/Kconfig.defconfig @@ -3,11 +3,11 @@ # Copyright (c) 2019 Nordic Semiconductor ASA # SPDX-License-Identifier: Apache-2.0 -if SOC_SERIES_NRF53X +if SOC_SERIES_NRF53 rsource "Kconfig.defconfig.nrf53*" config SYS_CLOCK_HW_CYCLES_PER_SEC default $(dt_nodelabel_int_prop,rtc1,clock-frequency) -endif # SOC_SERIES_NRF53X +endif # SOC_SERIES_NRF53 diff --git a/soc/nordic/nrf53/Kconfig.soc b/soc/nordic/nrf53/Kconfig.soc index 6374644d2ea5..35c1e961a9ad 100644 --- a/soc/nordic/nrf53/Kconfig.soc +++ b/soc/nordic/nrf53/Kconfig.soc @@ -18,11 +18,11 @@ config SOC_SERIES config SOC_NRF5340_CPUAPP bool - select SOC_SERIES_NRF53X + select SOC_SERIES_NRF53 config SOC_NRF5340_CPUNET bool - select SOC_SERIES_NRF53X + select SOC_SERIES_NRF53 config SOC_NRF5340_CPUAPP_QKAA bool diff --git a/soc/nordic/nrf54h/Kconfig b/soc/nordic/nrf54h/Kconfig index f8a1c31f6534..2b524c90caf2 100644 --- a/soc/nordic/nrf54h/Kconfig +++ b/soc/nordic/nrf54h/Kconfig @@ -3,7 +3,7 @@ # Copyright (c) 2024 Nordic Semiconductor ASA # SPDX-License-Identifier: Apache-2.0 -config SOC_SERIES_NRF54HX +config SOC_SERIES_NRF54H select HAS_IRONSIDE_SE select HAS_NRFS select HAS_NRFX diff --git a/soc/nordic/nrf54h/Kconfig.defconfig b/soc/nordic/nrf54h/Kconfig.defconfig index 3e4c61810984..3284dc56368d 100644 --- a/soc/nordic/nrf54h/Kconfig.defconfig +++ b/soc/nordic/nrf54h/Kconfig.defconfig @@ -3,7 +3,7 @@ # Copyright (c) 2024 Nordic Semiconductor ASA # SPDX-License-Identifier: Apache-2.0 -if SOC_SERIES_NRF54HX +if SOC_SERIES_NRF54H rsource "Kconfig.defconfig.nrf54h*" @@ -65,4 +65,4 @@ endif # PM_DEVICE config SYS_CLOCK_HW_CYCLES_PER_SEC default $(dt_nodelabel_int_prop,grtc,clock-frequency) if NRF_GRTC_TIMER -endif # SOC_SERIES_NRF54HX +endif # SOC_SERIES_NRF54H diff --git a/soc/nordic/nrf54h/Kconfig.soc b/soc/nordic/nrf54h/Kconfig.soc index 0cc8910f872d..38138fb71cc8 100644 --- a/soc/nordic/nrf54h/Kconfig.soc +++ b/soc/nordic/nrf54h/Kconfig.soc @@ -18,7 +18,7 @@ config SOC_SERIES config SOC_NRF54H20 bool - select SOC_SERIES_NRF54HX + select SOC_SERIES_NRF54H help nRF54H20 diff --git a/soc/nordic/nrf54l/Kconfig b/soc/nordic/nrf54l/Kconfig index 6d10e4c80f1c..b3e290dd6eb2 100644 --- a/soc/nordic/nrf54l/Kconfig +++ b/soc/nordic/nrf54l/Kconfig @@ -3,7 +3,7 @@ # Copyright (c) 2024 Nordic Semiconductor ASA # SPDX-License-Identifier: Apache-2.0 -config SOC_SERIES_NRF54LX +config SOC_SERIES_NRF54L select SOC_COMPATIBLE_NRF54LX select HAS_NRFX select HAS_NORDIC_DRIVERS @@ -68,7 +68,7 @@ config SOC_NRF54L15_CPUFLPR config SOC_NRF54LM20A_ENGA_CPUFLPR select RISCV_CORE_NORDIC_VPR -if SOC_SERIES_NRF54LX +if SOC_SERIES_NRF54L config SOC_NRF54LX_DISABLE_FICR_TRIMCNF bool "Disable trimming of the device" @@ -91,4 +91,4 @@ config SOC_NRF54L_ANOMALY_56_WORKAROUND help This option enables configuration workaround 56 for nRF54L Series SoCs. -endif # SOC_SERIES_NRF54LX +endif # SOC_SERIES_NRF54L diff --git a/soc/nordic/nrf54l/Kconfig.defconfig b/soc/nordic/nrf54l/Kconfig.defconfig index 929d13655c54..2cd38dca0e95 100644 --- a/soc/nordic/nrf54l/Kconfig.defconfig +++ b/soc/nordic/nrf54l/Kconfig.defconfig @@ -3,7 +3,7 @@ # Copyright (c) 2024 Nordic Semiconductor ASA # SPDX-License-Identifier: Apache-2.0 -if SOC_SERIES_NRF54LX +if SOC_SERIES_NRF54L rsource "Kconfig.defconfig.nrf54l*" @@ -52,4 +52,4 @@ endif # RISCV config SYS_CLOCK_HW_CYCLES_PER_SEC default $(dt_nodelabel_int_prop,grtc,clock-frequency) if NRF_GRTC_TIMER -endif # SOC_SERIES_NRF54LX +endif # SOC_SERIES_NRF54L diff --git a/soc/nordic/nrf54l/Kconfig.soc b/soc/nordic/nrf54l/Kconfig.soc index cd5f026d623c..8a8fa084ac25 100644 --- a/soc/nordic/nrf54l/Kconfig.soc +++ b/soc/nordic/nrf54l/Kconfig.soc @@ -18,7 +18,7 @@ config SOC_SERIES config SOC_NRF54L05 bool - select SOC_SERIES_NRF54LX + select SOC_SERIES_NRF54L help NRF54L05 @@ -36,7 +36,7 @@ config SOC_NRF54L05_CPUFLPR config SOC_NRF54L10 bool - select SOC_SERIES_NRF54LX + select SOC_SERIES_NRF54L help NRF54L10 @@ -54,7 +54,7 @@ config SOC_NRF54L10_CPUFLPR config SOC_NRF54L15 bool - select SOC_SERIES_NRF54LX + select SOC_SERIES_NRF54L help NRF54L15 @@ -72,7 +72,7 @@ config SOC_NRF54L15_CPUFLPR config SOC_NRF54LM20A bool - select SOC_SERIES_NRF54LX + select SOC_SERIES_NRF54L help NRF54LM20A diff --git a/soc/nordic/nrf91/Kconfig b/soc/nordic/nrf91/Kconfig index ed38eff73a2d..3f80e00ec66d 100644 --- a/soc/nordic/nrf91/Kconfig +++ b/soc/nordic/nrf91/Kconfig @@ -3,7 +3,7 @@ # Copyright (c) 2018 Nordic Semiconductor ASA # SPDX-License-Identifier: Apache-2.0 -config SOC_SERIES_NRF91X +config SOC_SERIES_NRF91 select ARM select CPU_CORTEX_M33 select CPU_CORTEX_M_HAS_DWT @@ -16,7 +16,7 @@ config SOC_SERIES_NRF91X select HAS_SEGGER_RTT if ZEPHYR_SEGGER_MODULE select HAS_POWEROFF -if SOC_SERIES_NRF91X +if SOC_SERIES_NRF91 config NRF_SPU_FLASH_REGION_SIZE hex @@ -34,4 +34,4 @@ config NRF_ENABLE_ICACHE bool "Instruction cache (I-Cache)" default y -endif # SOC_SERIES_NRF91X +endif # SOC_SERIES_NRF91 diff --git a/soc/nordic/nrf91/Kconfig.defconfig b/soc/nordic/nrf91/Kconfig.defconfig index bad2765c1b0c..06c77cfdb8cb 100644 --- a/soc/nordic/nrf91/Kconfig.defconfig +++ b/soc/nordic/nrf91/Kconfig.defconfig @@ -3,11 +3,11 @@ # Copyright (c) 2018 Nordic Semiconductor ASA # SPDX-License-Identifier: Apache-2.0 -if SOC_SERIES_NRF91X +if SOC_SERIES_NRF91 rsource "Kconfig.defconfig.nrf91*" config SYS_CLOCK_HW_CYCLES_PER_SEC default $(dt_nodelabel_int_prop,rtc1,clock-frequency) -endif # SOC_SERIES_NRF91X +endif # SOC_SERIES_NRF91 diff --git a/soc/nordic/nrf91/Kconfig.soc b/soc/nordic/nrf91/Kconfig.soc index 9ff096674695..9e5fb2d8e6ff 100644 --- a/soc/nordic/nrf91/Kconfig.soc +++ b/soc/nordic/nrf91/Kconfig.soc @@ -18,7 +18,7 @@ config SOC_SERIES config SOC_NRF9120 bool - select SOC_SERIES_NRF91X + select SOC_SERIES_NRF91 config SOC_NRF9131_LACA bool @@ -30,7 +30,7 @@ config SOC_NRF9151_LACA config SOC_NRF9160 bool - select SOC_SERIES_NRF91X + select SOC_SERIES_NRF91 config SOC_NRF9160_SICA bool diff --git a/soc/nordic/nrf92/Kconfig b/soc/nordic/nrf92/Kconfig index 1c5b1af8deb3..48583001d2a2 100644 --- a/soc/nordic/nrf92/Kconfig +++ b/soc/nordic/nrf92/Kconfig @@ -3,7 +3,7 @@ # Copyright (c) 2024 Nordic Semiconductor ASA # SPDX-License-Identifier: Apache-2.0 -config SOC_SERIES_NRF92X +config SOC_SERIES_NRF92 select HAS_IRONSIDE_SE select HAS_NRFS select HAS_NRFX diff --git a/soc/nordic/nrf92/Kconfig.defconfig b/soc/nordic/nrf92/Kconfig.defconfig index fe88daacefcf..b356bcf740d8 100644 --- a/soc/nordic/nrf92/Kconfig.defconfig +++ b/soc/nordic/nrf92/Kconfig.defconfig @@ -3,7 +3,7 @@ # Copyright (c) 2024 Nordic Semiconductor ASA # SPDX-License-Identifier: Apache-2.0 -if SOC_SERIES_NRF92X +if SOC_SERIES_NRF92 rsource "Kconfig.defconfig.nrf92*" @@ -41,4 +41,4 @@ config SPI_DW_ACCESS_WORD_ONLY config SYS_CLOCK_HW_CYCLES_PER_SEC default $(dt_nodelabel_int_prop,grtc,clock-frequency) if NRF_GRTC_TIMER -endif # SOC_SERIES_NRF92X +endif # SOC_SERIES_NRF92 diff --git a/soc/nordic/nrf92/Kconfig.soc b/soc/nordic/nrf92/Kconfig.soc index 0f7672e98b18..757ca00aa7a1 100644 --- a/soc/nordic/nrf92/Kconfig.soc +++ b/soc/nordic/nrf92/Kconfig.soc @@ -33,7 +33,7 @@ config SOC_SERIES config SOC_NRF9230_ENGB bool - select SOC_SERIES_NRF92X + select SOC_SERIES_NRF92 config SOC_NRF9230_ENGB_CPUAPP bool diff --git a/soc/nordic/timing.c b/soc/nordic/timing.c index 9d75cd4aad7d..5c7f610b54cb 100644 --- a/soc/nordic/timing.c +++ b/soc/nordic/timing.c @@ -19,7 +19,7 @@ void soc_timing_init(void) NRF_TIMER2->TASKS_CLEAR = 1; /* Clear Timer */ NRF_TIMER2->MODE = 0; /* Timer Mode */ NRF_TIMER2->PRESCALER = 0; /* 16M Hz */ -#if defined(CONFIG_SOC_SERIES_NRF51X) +#if defined(CONFIG_SOC_SERIES_NRF51) NRF_TIMER2->BITMODE = 0; /* 16 - bit */ #else NRF_TIMER2->BITMODE = 3; /* 32 - bit */ @@ -45,7 +45,7 @@ timing_t soc_timing_counter_get(void) uint64_t soc_timing_cycles_get(volatile timing_t *const start, volatile timing_t *const end) { -#if defined(CONFIG_SOC_SERIES_NRF51X) +#if defined(CONFIG_SOC_SERIES_NRF51) #define COUNTER_SPAN BIT(16) #else #define COUNTER_SPAN BIT64(32) diff --git a/soc/nordic/validate_base_addresses.c b/soc/nordic/validate_base_addresses.c index f8e5245b51cb..2a81aef568ae 100644 --- a/soc/nordic/validate_base_addresses.c +++ b/soc/nordic/validate_base_addresses.c @@ -74,7 +74,7 @@ #endif #if !defined(NRF_POWER_GPREGRET1) && defined(NRF_POWER) -#if defined(CONFIG_SOC_SERIES_NRF51X) || defined(CONFIG_SOC_SERIES_NRF52X) +#if defined(CONFIG_SOC_SERIES_NRF51) || defined(CONFIG_SOC_SERIES_NRF52) #define NRF_POWER_GPREGRET1 (&NRF_POWER->GPREGRET) #else #define NRF_POWER_GPREGRET1 (&NRF_POWER->GPREGRET[0]) @@ -82,7 +82,7 @@ #endif #if !defined(NRF_POWER_GPREGRET2) && defined(NRF_POWER) -#if defined(CONFIG_SOC_SERIES_NRF51X) || defined(CONFIG_SOC_SERIES_NRF52X) +#if defined(CONFIG_SOC_SERIES_NRF51) || defined(CONFIG_SOC_SERIES_NRF52) #define NRF_POWER_GPREGRET2 (&NRF_POWER->GPREGRET2) #else #define NRF_POWER_GPREGRET2 (&NRF_POWER->GPREGRET[1]) @@ -346,7 +346,7 @@ CHECK_DT_REG(uart134, NRF_UARTE134); CHECK_DT_REG(uart135, NRF_UARTE135); CHECK_DT_REG(uart136, NRF_UARTE136); CHECK_DT_REG(uart137, NRF_UARTE137); -#if !defined(CONFIG_SOC_SERIES_NRF54HX) && !defined(CONFIG_SOC_SERIES_NRF92X) +#if !defined(CONFIG_SOC_SERIES_NRF54H) && !defined(CONFIG_SOC_SERIES_NRF92) CHECK_DT_REG(uicr, NRF_UICR); #else CHECK_DT_REG(uicr, NRF_APPLICATION_UICR); @@ -361,7 +361,7 @@ CHECK_DT_REG(usbreg, NRF_USBREGULATOR); CHECK_DT_REG(vmc, NRF_VMC); CHECK_DT_REG(cpuflpr_clic, NRF_FLPR_VPRCLIC); CHECK_DT_REG(cpuppr_clic, NRF_PPR_VPRCLIC); -#if defined(CONFIG_SOC_SERIES_NRF54LX) +#if defined(CONFIG_SOC_SERIES_NRF54L) CHECK_DT_REG(cpuflpr_vpr, NRF_VPR00); #elif defined(CONFIG_NRF_PLATFORM_HALTIUM) CHECK_DT_REG(cpuflpr_vpr, NRF_VPR121); diff --git a/soc/nordic/validate_enabled_instances.c b/soc/nordic/validate_enabled_instances.c index afcfc6e8ca83..0b48b18e4752 100644 --- a/soc/nordic/validate_enabled_instances.c +++ b/soc/nordic/validate_enabled_instances.c @@ -13,9 +13,9 @@ DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(spi##idx))) #define UART_ENABLED(idx) (IS_ENABLED(CONFIG_SERIAL) && \ - (IS_ENABLED(CONFIG_SOC_SERIES_NRF53X) || \ - IS_ENABLED(CONFIG_SOC_SERIES_NRF54LX) || \ - IS_ENABLED(CONFIG_SOC_SERIES_NRF91X)) && \ + (IS_ENABLED(CONFIG_SOC_SERIES_NRF53) || \ + IS_ENABLED(CONFIG_SOC_SERIES_NRF54L) || \ + IS_ENABLED(CONFIG_SOC_SERIES_NRF91)) && \ DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(uart##idx))) /* @@ -39,9 +39,9 @@ #define MSG(idx) \ "Only one of the following peripherals can be enabled: " \ "SPI"#idx", SPIM"#idx", SPIS"#idx", TWI"#idx", TWIM"#idx", TWIS"#idx \ - IF_ENABLED(CONFIG_SOC_SERIES_NRF53X, (", UARTE"#idx)) \ - IF_ENABLED(CONFIG_SOC_SERIES_NRF54LX, (", UARTE"#idx)) \ - IF_ENABLED(CONFIG_SOC_SERIES_NRF91X, (", UARTE"#idx)) \ + IF_ENABLED(CONFIG_SOC_SERIES_NRF53, (", UARTE"#idx)) \ + IF_ENABLED(CONFIG_SOC_SERIES_NRF54L, (", UARTE"#idx)) \ + IF_ENABLED(CONFIG_SOC_SERIES_NRF91, (", UARTE"#idx)) \ ". Check nodes with status \"okay\" in zephyr.dts." #if (!IS_ENABLED(CONFIG_SOC_NRF52810) && \ From 3a9189aa3e7bfebab4fc3f9ee094c7e58b8da4d5 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Thu, 15 Jan 2026 09:02:59 +0000 Subject: [PATCH 2127/3659] drivers: Update to use SOC_SERIES_NRF Kconfigs without X suffix Updates usage of the old Kconfig to use the new Kconfig Signed-off-by: Jamie McCrae --- drivers/audio/dmic_nrfx_pdm.c | 2 +- drivers/clock_control/Kconfig.nrf | 8 ++++---- drivers/dp/swdp_ll_pin.h | 2 +- drivers/flash/nrf_qspi_nor.c | 8 ++++---- drivers/hwinfo/Kconfig.nrf | 2 +- drivers/i2s/Kconfig.nrfx | 2 +- drivers/ieee802154/Kconfig.nrf5 | 8 ++++---- drivers/ieee802154/ieee802154_nrf5.c | 4 ++-- drivers/led_strip/Kconfig.ws2812 | 2 +- drivers/mbox/Kconfig.nrf_vevif_event | 2 +- drivers/modem/hl78xx/Kconfig.hl78xx | 2 +- drivers/usb/device/usb_dc_nrfx.c | 2 +- drivers/usb/udc/Kconfig.dwc2 | 2 +- drivers/usb/udc/udc_nrf.c | 2 +- drivers/wifi/nrf_wifi/Kconfig.nrfwifi | 4 ++-- 15 files changed, 26 insertions(+), 26 deletions(-) diff --git a/drivers/audio/dmic_nrfx_pdm.c b/drivers/audio/dmic_nrfx_pdm.c index 8f6acce02bd3..661f96e837bd 100644 --- a/drivers/audio/dmic_nrfx_pdm.c +++ b/drivers/audio/dmic_nrfx_pdm.c @@ -21,7 +21,7 @@ LOG_MODULE_REGISTER(dmic_nrfx_pdm, CONFIG_AUDIO_DMIC_LOG_LEVEL); #define NODE_AUDIO_AUXPLL DT_NODELABEL(audio_auxpll) #define NODE_AUDIOPLL DT_NODELABEL(audiopll) -#if CONFIG_SOC_SERIES_NRF54HX +#if CONFIG_SOC_SERIES_NRF54H #define DMIC_NRFX_CLOCK_FREQ MHZ(16) #define DMIC_NRFX_AUDIO_CLOCK_FREQ DT_PROP_OR(NODE_AUDIOPLL, frequency, 0) #elif DT_NODE_HAS_STATUS_OKAY(NODE_AUDIO_AUXPLL) diff --git a/drivers/clock_control/Kconfig.nrf b/drivers/clock_control/Kconfig.nrf index f8d51383a35c..98b4ebac0fd1 100644 --- a/drivers/clock_control/Kconfig.nrf +++ b/drivers/clock_control/Kconfig.nrf @@ -46,18 +46,18 @@ config CLOCK_CONTROL_NRF_K32SRC_XTAL config CLOCK_CONTROL_NRF_K32SRC_SYNTH bool "Synthesized from HFCLK" - depends on !SOC_SERIES_NRF91X + depends on !SOC_SERIES_NRF91 select NRFX_CLOCK_LF_SRC_SYNTH if !CLOCK_CONTROL_NRF_FORCE_ALT config CLOCK_CONTROL_NRF_K32SRC_EXT_LOW_SWING bool "External low swing" - depends on SOC_SERIES_NRF52X + depends on SOC_SERIES_NRF52 select NRFX_CLOCK_LFXO_TWO_STAGE_ENABLED if !CLOCK_CONTROL_NRF_FORCE_ALT select NRFX_CLOCK_LF_SRC_LOW_SWING if !CLOCK_CONTROL_NRF_FORCE_ALT config CLOCK_CONTROL_NRF_K32SRC_EXT_FULL_SWING bool "External full swing" - depends on SOC_SERIES_NRF52X + depends on SOC_SERIES_NRF52 select NRFX_CLOCK_LFXO_TWO_STAGE_ENABLED if !CLOCK_CONTROL_NRF_FORCE_ALT select NRFX_CLOCK_LF_SRC_FULL_SWING if !CLOCK_CONTROL_NRF_FORCE_ALT @@ -65,7 +65,7 @@ endchoice config CLOCK_CONTROL_NRF_K32SRC_RC_CALIBRATION bool "LF clock calibration" - depends on !SOC_SERIES_NRF91X && CLOCK_CONTROL_NRF_K32SRC_RC + depends on !SOC_SERIES_NRF91 && CLOCK_CONTROL_NRF_K32SRC_RC default y if !SOC_NRF53_CPUNET_ENABLE select NRFX_CLOCK_LF_CAL_ENABLED if !CLOCK_CONTROL_NRF_FORCE_ALT help diff --git a/drivers/dp/swdp_ll_pin.h b/drivers/dp/swdp_ll_pin.h index c0590d774adc..cf463bce7565 100644 --- a/drivers/dp/swdp_ll_pin.h +++ b/drivers/dp/swdp_ll_pin.h @@ -24,7 +24,7 @@ static ALWAYS_INLINE void pin_delay_asm(uint32_t delay) #endif } -#if defined(CONFIG_SOC_SERIES_NRF52X) || defined(CONFIG_SOC_SERIES_NRF53X) +#if defined(CONFIG_SOC_SERIES_NRF52) || defined(CONFIG_SOC_SERIES_NRF53) #include "swdp_ll_pin_nrf.h" diff --git a/drivers/flash/nrf_qspi_nor.c b/drivers/flash/nrf_qspi_nor.c index a1ef25e23827..716920332e0f 100644 --- a/drivers/flash/nrf_qspi_nor.c +++ b/drivers/flash/nrf_qspi_nor.c @@ -96,7 +96,7 @@ BUILD_ASSERT(INST_0_SCK_FREQUENCY >= (NRF_QSPI_BASE_CLOCK_FREQ / 16), * need to be used to achieve the SCK frequency as close as possible (but not * higher) to the one specified in DT. */ -#if defined(CONFIG_SOC_SERIES_NRF53X) +#if defined(CONFIG_SOC_SERIES_NRF53) /* * On nRF53 Series SoCs, the default /4 divider for the HFCLK192M clock can * only be used when the QSPI peripheral is idle. When a QSPI operation is @@ -149,7 +149,7 @@ BUILD_ASSERT(INST_0_SCK_FREQUENCY >= (NRF_QSPI_BASE_CLOCK_FREQ / 16), #endif -#endif /* defined(CONFIG_SOC_SERIES_NRF53X) */ +#endif /* defined(CONFIG_SOC_SERIES_NRF53) */ /* 0 for MODE0 (CPOL=0, CPHA=0), 1 for MODE3 (CPOL=1, CPHA=1). */ #define INST_0_SPI_MODE DT_INST_PROP(0, cpol) @@ -257,7 +257,7 @@ static inline void qspi_unlock(const struct device *dev) static inline void qspi_clock_div_change(const struct device *dev) { -#ifdef CONFIG_SOC_SERIES_NRF53X +#ifdef CONFIG_SOC_SERIES_NRF53 #if NRF53_ERRATA_159_ENABLE_WORKAROUND struct qspi_nor_data *dev_data = dev->data; @@ -277,7 +277,7 @@ static inline void qspi_clock_div_change(const struct device *dev) static inline void qspi_clock_div_restore(const struct device *dev) { -#ifdef CONFIG_SOC_SERIES_NRF53X +#ifdef CONFIG_SOC_SERIES_NRF53 /* Restore the default base clock divider to reduce power * consumption when the QSPI peripheral is idle. */ diff --git a/drivers/hwinfo/Kconfig.nrf b/drivers/hwinfo/Kconfig.nrf index 0f326b17fb82..bae67e0a81d3 100644 --- a/drivers/hwinfo/Kconfig.nrf +++ b/drivers/hwinfo/Kconfig.nrf @@ -5,7 +5,7 @@ config HWINFO_NRF bool "NRF device ID" default y depends on SOC_FAMILY_NORDIC_NRF - depends on SOC_SERIES_NRF54HX || NRF_SOC_SECURE_SUPPORTED + depends on SOC_SERIES_NRF54H || NRF_SOC_SECURE_SUPPORTED select HWINFO_HAS_DRIVER help Enable Nordic NRF hwinfo driver. diff --git a/drivers/i2s/Kconfig.nrfx b/drivers/i2s/Kconfig.nrfx index 786de1ba68b8..740dc431b88d 100644 --- a/drivers/i2s/Kconfig.nrfx +++ b/drivers/i2s/Kconfig.nrfx @@ -22,7 +22,7 @@ config I2S_NRFX_TX_BLOCK_COUNT config I2S_NRFX_ALLOW_MCK_BYPASS bool "Allow MCK bypass if a ratio exists" - depends on SOC_SERIES_NRF53X + depends on SOC_SERIES_NRF53 help Search for a supported ratio directly from MCK and LRCK and enable bypass if a ratio exists. If not, fallback to diff --git a/drivers/ieee802154/Kconfig.nrf5 b/drivers/ieee802154/Kconfig.nrf5 index 0a9401aa63a9..73f02f7ee18d 100644 --- a/drivers/ieee802154/Kconfig.nrf5 +++ b/drivers/ieee802154/Kconfig.nrf5 @@ -41,7 +41,7 @@ config IEEE802154_NRF5_EXT_IRQ_MGMT config IEEE802154_NRF5_UICR_EUI64_ENABLE bool "Support usage of EUI64 value stored in UICR registers" depends on !IEEE802154_VENDOR_OUI_ENABLE - depends on SOC_SERIES_NRF52X || SOC_SERIES_NRF53X || SOC_SERIES_NRF54LX + depends on SOC_SERIES_NRF52 || SOC_SERIES_NRF53 || SOC_SERIES_NRF54L help This option enables setting custom vendor EUI64 value stored in User information configuration registers (UICR). @@ -53,9 +53,9 @@ if IEEE802154_NRF5_UICR_EUI64_ENABLE config IEEE802154_NRF5_UICR_EUI64_REG int "UICR base register for the EUI64 value" - range 0 30 if SOC_SERIES_NRF52X - range 0 190 if SOC_SERIES_NRF53X - range 0 318 if SOC_SERIES_NRF54LX + range 0 30 if SOC_SERIES_NRF52 + range 0 190 if SOC_SERIES_NRF53 + range 0 318 if SOC_SERIES_NRF54L default 0 help Base of the two consecutive registers from the UICR customer diff --git a/drivers/ieee802154/ieee802154_nrf5.c b/drivers/ieee802154/ieee802154_nrf5.c index 911120d2783c..e8c39832f1e2 100644 --- a/drivers/ieee802154/ieee802154_nrf5.c +++ b/drivers/ieee802154/ieee802154_nrf5.c @@ -71,7 +71,7 @@ static const struct device *nrf5_dev; #define NSEC_PER_TEN_SYMBOLS (10 * IEEE802154_PHY_OQPSK_780_TO_2450MHZ_SYMBOL_PERIOD_NS) #if defined(CONFIG_IEEE802154_NRF5_UICR_EUI64_ENABLE) -#if defined(CONFIG_SOC_NRF5340_CPUAPP) || defined(CONFIG_SOC_SERIES_NRF54LX) +#if defined(CONFIG_SOC_NRF5340_CPUAPP) || defined(CONFIG_SOC_SERIES_NRF54L) #if defined(CONFIG_TRUSTED_EXECUTION_NONSECURE) #error "NRF_UICR->OTP is not supported to read from non-secure" #else @@ -79,7 +79,7 @@ static const struct device *nrf5_dev; #endif /* CONFIG_TRUSTED_EXECUTION_NONSECURE */ #else #define EUI64_ADDR (NRF_UICR->CUSTOMER) -#endif /* CONFIG_SOC_NRF5340_CPUAPP || CONFIG_SOC_SERIES_NRF54LX*/ +#endif /* CONFIG_SOC_NRF5340_CPUAPP || CONFIG_SOC_SERIES_NRF54L */ #endif /* CONFIG_IEEE802154_NRF5_UICR_EUI64_ENABLE */ #if defined(CONFIG_IEEE802154_NRF5_UICR_EUI64_ENABLE) diff --git a/drivers/led_strip/Kconfig.ws2812 b/drivers/led_strip/Kconfig.ws2812 index ed5527a85043..b50e6029d4fc 100644 --- a/drivers/led_strip/Kconfig.ws2812 +++ b/drivers/led_strip/Kconfig.ws2812 @@ -56,7 +56,7 @@ config WS2812_STRIP_GPIO # nRF52 and nRF53 is supported currently. default y depends on DT_HAS_WORLDSEMI_WS2812_GPIO_ENABLED - depends on (SOC_SERIES_NRF91X || SOC_SERIES_NRF51X || SOC_SERIES_NRF52X || SOC_SERIES_NRF53X) + depends on (SOC_SERIES_NRF91 || SOC_SERIES_NRF51 || SOC_SERIES_NRF52 || SOC_SERIES_NRF53) help Enable driver for WS2812 (and compatible) LED strips directly controlling with GPIO. The GPIO driver does bit-banging with inline diff --git a/drivers/mbox/Kconfig.nrf_vevif_event b/drivers/mbox/Kconfig.nrf_vevif_event index 655cc82f3850..cbdfb074ec32 100644 --- a/drivers/mbox/Kconfig.nrf_vevif_event +++ b/drivers/mbox/Kconfig.nrf_vevif_event @@ -17,5 +17,5 @@ config MBOX_NRF_VEVIF_EVENT_TX config MBOX_NRF_VEVIF_EVENT_USE_54L_ERRATA_16 bool "Apply errata 16 for nRF54L series" - depends on SOC_SERIES_NRF54LX + depends on SOC_SERIES_NRF54L default y diff --git a/drivers/modem/hl78xx/Kconfig.hl78xx b/drivers/modem/hl78xx/Kconfig.hl78xx index 335f48a76c59..8795cc0f80b6 100644 --- a/drivers/modem/hl78xx/Kconfig.hl78xx +++ b/drivers/modem/hl78xx/Kconfig.hl78xx @@ -80,7 +80,7 @@ endif # MODEM_HL78XX_AT_SHELL menuconfig MODEM_HL78XX_AUTO_BAUDRATE bool "Auto Baud Rate Detection and Switching" - select UART_USE_RUNTIME_CONFIGURE if SOC_SERIES_NRF52X + select UART_USE_RUNTIME_CONFIGURE if SOC_SERIES_NRF52 help Enable automatic baud rate detection and switching for the HL78xx modem. The driver will attempt to detect the modem's current baud rate and diff --git a/drivers/usb/device/usb_dc_nrfx.c b/drivers/usb/device/usb_dc_nrfx.c index da5257b17582..ca27652ef110 100644 --- a/drivers/usb/device/usb_dc_nrfx.c +++ b/drivers/usb/device/usb_dc_nrfx.c @@ -1898,7 +1898,7 @@ static int usb_init(void) .dcdcen = (DT_PROP(DT_INST(0, nordic_nrf5x_regulator), regulator_initial_mode) == NRF5X_REG_MODE_DCDC), #if NRFX_POWER_SUPPORTS_DCDCEN_VDDH - .dcdcenhv = COND_CODE_1(CONFIG_SOC_SERIES_NRF52X, + .dcdcenhv = COND_CODE_1(CONFIG_SOC_SERIES_NRF52, (DT_NODE_HAS_STATUS_OKAY(DT_INST(0, nordic_nrf52x_regulator_hv))), (DT_NODE_HAS_STATUS_OKAY(DT_INST(0, nordic_nrf53x_regulator_hv)))), #endif diff --git a/drivers/usb/udc/Kconfig.dwc2 b/drivers/usb/udc/Kconfig.dwc2 index 43fdf0c96731..03b123dfab5d 100644 --- a/drivers/usb/udc/Kconfig.dwc2 +++ b/drivers/usb/udc/Kconfig.dwc2 @@ -50,7 +50,7 @@ config UDC_DWC2_THREAD_PRIORITY config UDC_DWC2_USBHS_VBUS_READY_TIMEOUT int "UDC DWC2 USBHS VBUS ready event timeout in ms" - depends on SOC_SERIES_NRF54HX || SOC_SERIES_NRF54LX || SOC_SERIES_NRF92X + depends on SOC_SERIES_NRF54H || SOC_SERIES_NRF54L || SOC_SERIES_NRF92 default 0 help UDC DWC2 USBHS VBUS ready event timeout. If the VBUS is not ready diff --git a/drivers/usb/udc/udc_nrf.c b/drivers/usb/udc/udc_nrf.c index 7b18862fa596..5e86061f46e0 100644 --- a/drivers/usb/udc/udc_nrf.c +++ b/drivers/usb/udc/udc_nrf.c @@ -1880,7 +1880,7 @@ static const struct udc_nrf_config udc_nrf_cfg = { .dcdcen = (DT_PROP(DT_INST(0, nordic_nrf5x_regulator), regulator_initial_mode) == NRF5X_REG_MODE_DCDC), #if NRFX_POWER_SUPPORTS_DCDCEN_VDDH - .dcdcenhv = COND_CODE_1(CONFIG_SOC_SERIES_NRF52X, + .dcdcenhv = COND_CODE_1(CONFIG_SOC_SERIES_NRF52, (DT_NODE_HAS_STATUS_OKAY(DT_INST(0, nordic_nrf52x_regulator_hv))), (DT_NODE_HAS_STATUS_OKAY(DT_INST(0, nordic_nrf53x_regulator_hv)))), #endif diff --git a/drivers/wifi/nrf_wifi/Kconfig.nrfwifi b/drivers/wifi/nrf_wifi/Kconfig.nrfwifi index c168d9596087..3a276a8ff707 100644 --- a/drivers/wifi/nrf_wifi/Kconfig.nrfwifi +++ b/drivers/wifi/nrf_wifi/Kconfig.nrfwifi @@ -10,7 +10,7 @@ menuconfig WIFI_NRF70 select NET_L2_WIFI_MGMT if NETWORKING select NET_L2_ETHERNET_MGMT if NETWORKING && NET_L2_ETHERNET select WIFI_USE_NATIVE_NETWORKING if NETWORKING - select EXPERIMENTAL if !SOC_SERIES_NRF53X && !SOC_SERIES_NRF91X + select EXPERIMENTAL if !SOC_SERIES_NRF53 && !SOC_SERIES_NRF91 select NRF70_BUSLIB default y depends on \ @@ -933,7 +933,7 @@ config NRF_WIFI_ZERO_COPY_TX select NET_L2_ETHERNET_RESERVE_HEADER select EXPERIMENTAL # 54L has lower RAM - default y if SOC_SERIES_NRF54LX + default y if SOC_SERIES_NRF54L help Enable this configuration to use zero copy Transmit path. The driver will use the network buffer directly for transmission From 723476370d970bf4c81256977f65a0970f1a091d Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Thu, 15 Jan 2026 09:03:15 +0000 Subject: [PATCH 2128/3659] modules: Update to use SOC_SERIES_NRF Kconfigs without X suffix Updates usage of the old Kconfig to use the new Kconfig Signed-off-by: Jamie McCrae --- modules/hal_nordic/Kconfig | 2 +- modules/hal_nordic/Kconfig.nrf_regtool | 2 +- modules/hal_nordic/ironside/se/dvfs.c | 2 +- modules/hal_nordic/nrf_802154/CMakeLists.txt | 4 ++-- modules/hal_nordic/nrfx/CMakeLists.txt | 20 ++++++++-------- modules/hal_nordic/nrfx/Kconfig | 24 +++++++++---------- modules/hal_nordic/nrfx/nrfx_kconfig.h | 4 ++-- .../hal_nordic/nrfx/nrfx_reserved_resources.h | 4 ++-- modules/nrf_wifi/bus/qspi_if.c | 16 ++++++------- 9 files changed, 39 insertions(+), 39 deletions(-) diff --git a/modules/hal_nordic/Kconfig b/modules/hal_nordic/Kconfig index 935c4fb4ff38..d918d77e3047 100644 --- a/modules/hal_nordic/Kconfig +++ b/modules/hal_nordic/Kconfig @@ -38,7 +38,7 @@ if NRF_802154_RADIO_DRIVER config NRF_802154_CONSTLAT_CONTROL def_bool y - depends on SOC_SERIES_NRF54LX && NRF_802154_SL_OPENSOURCE + depends on SOC_SERIES_NRF54L && NRF_802154_SL_OPENSOURCE select NRF_SYS_EVENT help Allows the nRF 802.15.4 radio driver to manage the constant latency state. diff --git a/modules/hal_nordic/Kconfig.nrf_regtool b/modules/hal_nordic/Kconfig.nrf_regtool index 12f7a53f471c..1d13c0879e50 100644 --- a/modules/hal_nordic/Kconfig.nrf_regtool +++ b/modules/hal_nordic/Kconfig.nrf_regtool @@ -2,7 +2,7 @@ # SPDX-License-Identifier: Apache-2.0 menu "nrf-regtool options" - depends on SOC_SERIES_NRF92X + depends on SOC_SERIES_NRF92 config NRF_REGTOOL_GENERATE_UICR bool "Generate UICR" diff --git a/modules/hal_nordic/ironside/se/dvfs.c b/modules/hal_nordic/ironside/se/dvfs.c index 8bba1a28f9a3..1494e981ee40 100644 --- a/modules/hal_nordic/ironside/se/dvfs.c +++ b/modules/hal_nordic/ironside/se/dvfs.c @@ -9,7 +9,7 @@ static enum ironside_se_dvfs_oppoint current_dvfs_oppoint = IRONSIDE_SE_DVFS_OPP_HIGH; -#if defined(CONFIG_SOC_SERIES_NRF54HX) +#if defined(CONFIG_SOC_SERIES_NRF54H) #define ABB_STATUSANA_LOCKED_L_Pos (0UL) #define ABB_STATUSANA_LOCKED_L_Msk (0x1UL << ABB_STATUSANA_LOCKED_L_Pos) #define ABB_STATUSANA_REG_OFFSET (0x102UL) diff --git a/modules/hal_nordic/nrf_802154/CMakeLists.txt b/modules/hal_nordic/nrf_802154/CMakeLists.txt index 5b04b556c565..c3216b3961be 100644 --- a/modules/hal_nordic/nrf_802154/CMakeLists.txt +++ b/modules/hal_nordic/nrf_802154/CMakeLists.txt @@ -102,8 +102,8 @@ if(CONFIG_NRF_802154_ASSERT_ZEPHYR OR CONFIG_NRF_802154_ASSERT_ZEPHYR_MINIMAL) target_sources(nrf-802154-platform PRIVATE nrf_802154_assert_handler.c) endif() -set(NRF52_SERIES ${CONFIG_SOC_SERIES_NRF52X}) -set(NRF53_SERIES ${CONFIG_SOC_SERIES_NRF53X}) +set(NRF52_SERIES ${CONFIG_SOC_SERIES_NRF52}) +set(NRF53_SERIES ${CONFIG_SOC_SERIES_NRF53}) set(SER_HOST ${CONFIG_NRF_802154_SER_HOST}) set(SL_OPENSOURCE ${CONFIG_NRF_802154_SL_OPENSOURCE}) diff --git a/modules/hal_nordic/nrfx/CMakeLists.txt b/modules/hal_nordic/nrfx/CMakeLists.txt index df079455b506..f2b5265ed2d0 100644 --- a/modules/hal_nordic/nrfx/CMakeLists.txt +++ b/modules/hal_nordic/nrfx/CMakeLists.txt @@ -36,7 +36,7 @@ zephyr_include_directories(.) include(${BSP_DIR}/zephyr/nrfx.cmake OPTIONAL) # Define MDK defines globally -zephyr_compile_definitions_ifdef(CONFIG_SOC_SERIES_NRF51X NRF51) +zephyr_compile_definitions_ifdef(CONFIG_SOC_SERIES_NRF51 NRF51) zephyr_compile_definitions_ifdef(CONFIG_SOC_NRF51822_QFAA NRF51422_XXAA) zephyr_compile_definitions_ifdef(CONFIG_SOC_NRF51822_QFAB NRF51422_XXAB) zephyr_compile_definitions_ifdef(CONFIG_SOC_NRF51822_QFAC NRF51422_XXAC) @@ -104,14 +104,14 @@ zephyr_library_compile_definitions_ifdef(CONFIG_NRF_TRACE_PORT zephyr_compile_definitions_ifdef(CONFIG_SOC_NRF5340_CPUAPP NRF_SKIP_FICR_NS_COPY_TO_RAM) -zephyr_compile_definitions_ifdef(CONFIG_SOC_SERIES_NRF91X +zephyr_compile_definitions_ifdef(CONFIG_SOC_SERIES_NRF91 NRF_SKIP_FICR_NS_COPY_TO_RAM) # Connect Kconfig compilation option for Non-Secure software with option required by MDK/nrfx zephyr_compile_definitions_ifdef(CONFIG_ARM_NONSECURE_FIRMWARE NRF_TRUSTZONE_NONSECURE) zephyr_compile_definitions_ifdef(CONFIG_LOG_BACKEND_SWO ENABLE_SWO) -zephyr_library_sources_ifdef(CONFIG_SOC_SERIES_NRF51X ${MDK_DIR}/system_nrf51.c) +zephyr_library_sources_ifdef(CONFIG_SOC_SERIES_NRF51 ${MDK_DIR}/system_nrf51.c) zephyr_library_sources_ifdef(CONFIG_SOC_NRF52805 ${MDK_DIR}/system_nrf52805.c) zephyr_library_sources_ifdef(CONFIG_SOC_NRF52810 ${MDK_DIR}/system_nrf52810.c) zephyr_library_sources_ifdef(CONFIG_SOC_NRF52811 ${MDK_DIR}/system_nrf52811.c) @@ -121,13 +121,13 @@ zephyr_library_sources_ifdef(CONFIG_SOC_NRF52833 ${MDK_DIR}/system_nrf5283 zephyr_library_sources_ifdef(CONFIG_SOC_NRF52840 ${MDK_DIR}/system_nrf52840.c) zephyr_library_sources_ifdef(CONFIG_SOC_NRF5340_CPUAPP ${MDK_DIR}/system_nrf5340_application.c) zephyr_library_sources_ifdef(CONFIG_SOC_NRF5340_CPUNET ${MDK_DIR}/system_nrf5340_network.c) -zephyr_library_sources_ifdef(CONFIG_SOC_SERIES_NRF54HX ${MDK_DIR}/system_nrf54h.c) -if(CONFIG_SOC_SERIES_NRF54LX OR CONFIG_SOC_SERIES_BSIM_NRF54LX) +zephyr_library_sources_ifdef(CONFIG_SOC_SERIES_NRF54H ${MDK_DIR}/system_nrf54h.c) +if(CONFIG_SOC_SERIES_NRF54L OR CONFIG_SOC_SERIES_BSIM_NRF54LX) zephyr_library_sources(${MDK_DIR}/system_nrf54l.c) endif() zephyr_library_sources_ifdef(CONFIG_SOC_SERIES_NRF71 ${MDK_DIR}/system_nrf7120_enga.c) -zephyr_library_sources_ifdef(CONFIG_SOC_SERIES_NRF91X ${MDK_DIR}/system_nrf91.c) -zephyr_library_sources_ifdef(CONFIG_SOC_SERIES_NRF92X ${MDK_DIR}/system_nrf92.c) +zephyr_library_sources_ifdef(CONFIG_SOC_SERIES_NRF91 ${MDK_DIR}/system_nrf91.c) +zephyr_library_sources_ifdef(CONFIG_SOC_SERIES_NRF92 ${MDK_DIR}/system_nrf92.c) zephyr_library_sources(nrfx_glue.c) zephyr_library_sources(${HELPERS_DIR}/nrfx_flag32_allocator.c) @@ -135,7 +135,7 @@ zephyr_library_sources_ifdef(CONFIG_HAS_NORDIC_RAM_CTRL ${HELPERS_DIR}/nrf if(CONFIG_NRFX_GPPI AND NOT CONFIG_NRFX_GPPI_V1) zephyr_library_sources_ifdef(CONFIG_HAS_HW_NRF_PPI ${HELPERS_DIR}/nrfx_gppi_ppi.c) - if(CONFIG_SOC_SERIES_NRF54LX OR CONFIG_SOC_SERIES_NRF71 OR CONFIG_HAS_HW_NRF_DPPIC) + if(CONFIG_SOC_SERIES_NRF54L OR CONFIG_SOC_SERIES_NRF71 OR CONFIG_HAS_HW_NRF_DPPIC) zephyr_library_sources(${HELPERS_DIR}/nrfx_gppi_dppi.c) endif() if(CONFIG_SOC_COMPATIBLE_NRF54LX OR CONFIG_SOC_SERIES_NRF71) @@ -244,7 +244,7 @@ zephyr_compile_definitions_ifdef(CONFIG_SOC_NRF54LX_DISABLE_FICR_TRIMCNF NRF_DIS zephyr_compile_definitions_ifdef(CONFIG_SOC_NRF54LX_SKIP_GLITCHDETECTOR_DISABLE NRF_SKIP_GLITCHDETECTOR_DISABLE) zephyr_compile_definitions_ifndef(CONFIG_SOC_NRF54L_ANOMALY_56_WORKAROUND NRF54L_CONFIGURATION_56_ENABLE=0) -if(CONFIG_SOC_SERIES_NRF54HX AND CONFIG_NRFX_GPPI_V1) +if(CONFIG_SOC_SERIES_NRF54H AND CONFIG_NRFX_GPPI_V1) zephyr_library_sources(${HELPERS_DIR}/internal/nrfx_gppiv1_ipct.c) zephyr_library_sources(${HELPERS_DIR}/internal/nrfx_gppiv1_shim.c) endif() @@ -256,7 +256,7 @@ macro(mdk_svd_ifdef feature_toggle filename) endif() endmacro() -mdk_svd_ifdef(CONFIG_SOC_SERIES_NRF51X nrf51.svd) +mdk_svd_ifdef(CONFIG_SOC_SERIES_NRF51 nrf51.svd) mdk_svd_ifdef(CONFIG_SOC_NRF52805 nrf52805.svd) mdk_svd_ifdef(CONFIG_SOC_NRF52810 nrf52810.svd) mdk_svd_ifdef(CONFIG_SOC_NRF52811 nrf52811.svd) diff --git a/modules/hal_nordic/nrfx/Kconfig b/modules/hal_nordic/nrfx/Kconfig index 9561e5e28d20..3c410d8af208 100644 --- a/modules/hal_nordic/nrfx/Kconfig +++ b/modules/hal_nordic/nrfx/Kconfig @@ -11,7 +11,7 @@ rsource "Kconfig.logging" config NRFX_ADC bool "ADC driver" - depends on $(dt_nodelabel_exists,adc) && SOC_SERIES_NRF51X + depends on $(dt_nodelabel_exists,adc) && SOC_SERIES_NRF51 config NRFX_CLOCK bool "CLOCK driver" @@ -35,15 +35,15 @@ config NRFX_CLOCK_LF_SRC_XTAL bool "Crystal Oscillator" config NRFX_CLOCK_LF_SRC_SYNTH - depends on !SOC_SERIES_NRF91X + depends on !SOC_SERIES_NRF91 bool "Synthesized from HFCLK" config NRFX_CLOCK_LF_SRC_LOW_SWING - depends on SOC_SERIES_NRF52X + depends on SOC_SERIES_NRF52 bool "External low swing" config NRFX_CLOCK_LF_SRC_FULL_SWING - depends on SOC_SERIES_NRF52X + depends on SOC_SERIES_NRF52 bool "External full swing" endif # NRFX_CLOCK @@ -167,7 +167,7 @@ config NRFX_GPPI config NRFX_GPPI_V1 bool "GPPI layer legacy" depends on NRFX_GPPI - default y if SOC_SERIES_NRF54HX + default y if SOC_SERIES_NRF54H help When enabled then legacy version of Generic PPI layer is used. @@ -257,24 +257,24 @@ config NRFX_RTC131 config NRFX_SAADC bool "SAADC driver" - depends on $(dt_nodelabel_exists,adc) && !SOC_SERIES_NRF51X + depends on $(dt_nodelabel_exists,adc) && !SOC_SERIES_NRF51 config NRFX_SPI bool config NRFX_SPI0 bool "SPI0 driver instance" - depends on $(dt_nodelabel_exists,spi0) && (SOC_SERIES_NRF51X || SOC_SERIES_NRF52X) + depends on $(dt_nodelabel_exists,spi0) && (SOC_SERIES_NRF51 || SOC_SERIES_NRF52) select NRFX_SPI config NRFX_SPI1 bool "SPI1 driver instance" - depends on $(dt_nodelabel_exists,spi1) && (SOC_SERIES_NRF51X || SOC_SERIES_NRF52X) + depends on $(dt_nodelabel_exists,spi1) && (SOC_SERIES_NRF51 || SOC_SERIES_NRF52) select NRFX_SPI config NRFX_SPI2 bool "SPI2 driver instance" - depends on $(dt_nodelabel_exists,spi2) && SOC_SERIES_NRF52X + depends on $(dt_nodelabel_exists,spi2) && SOC_SERIES_NRF52 select NRFX_SPI config NRFX_SPIM @@ -305,12 +305,12 @@ config NRFX_TWI config NRFX_TWI0 bool "TWI0 driver instance" - depends on $(dt_nodelabel_exists,i2c0) && (SOC_SERIES_NRF51X || SOC_SERIES_NRF52X) + depends on $(dt_nodelabel_exists,i2c0) && (SOC_SERIES_NRF51 || SOC_SERIES_NRF52) select NRFX_TWI config NRFX_TWI1 bool "TWI1 driver instance" - depends on $(dt_nodelabel_exists,i2c1) && (SOC_SERIES_NRF51X || SOC_SERIES_NRF52X) + depends on $(dt_nodelabel_exists,i2c1) && (SOC_SERIES_NRF51 || SOC_SERIES_NRF52) select NRFX_TWI config NRFX_TWIM @@ -324,7 +324,7 @@ config NRFX_UART config NRFX_UART0 bool "UART0 driver instance" - depends on $(dt_nodelabel_exists,uart0) && (SOC_SERIES_NRF51X || SOC_SERIES_NRF52X) + depends on $(dt_nodelabel_exists,uart0) && (SOC_SERIES_NRF51 || SOC_SERIES_NRF52) select NRFX_UART config NRFX_UARTE diff --git a/modules/hal_nordic/nrfx/nrfx_kconfig.h b/modules/hal_nordic/nrfx/nrfx_kconfig.h index 833fc6f23c75..d98d9c03d04a 100644 --- a/modules/hal_nordic/nrfx/nrfx_kconfig.h +++ b/modules/hal_nordic/nrfx/nrfx_kconfig.h @@ -42,7 +42,7 @@ #endif #ifdef CONFIG_NRFX_CLOCK_LF_SRC_RC -#if defined(CONFIG_SOC_SERIES_NRF91X) || defined(CONFIG_SOC_COMPATIBLE_NRF53X) +#if defined(CONFIG_SOC_SERIES_NRF91) || defined(CONFIG_SOC_COMPATIBLE_NRF53X) #define NRFX_CLOCK_CONFIG_LF_SRC 1 #else #define NRFX_CLOCK_CONFIG_LF_SRC 0 @@ -50,7 +50,7 @@ #endif #ifdef CONFIG_NRFX_CLOCK_LF_SRC_XTAL -#if defined(CONFIG_SOC_SERIES_NRF91X) || defined(CONFIG_SOC_COMPATIBLE_NRF53X) +#if defined(CONFIG_SOC_SERIES_NRF91) || defined(CONFIG_SOC_COMPATIBLE_NRF53X) #define NRFX_CLOCK_CONFIG_LF_SRC 2 #else #define NRFX_CLOCK_CONFIG_LF_SRC 1 diff --git a/modules/hal_nordic/nrfx/nrfx_reserved_resources.h b/modules/hal_nordic/nrfx/nrfx_reserved_resources.h index 9958699723ff..573d3461ac58 100644 --- a/modules/hal_nordic/nrfx/nrfx_reserved_resources.h +++ b/modules/hal_nordic/nrfx/nrfx_reserved_resources.h @@ -53,7 +53,7 @@ */ #if defined(CONFIG_BT_LL_SW_SPLIT) #include -#if defined(CONFIG_SOC_SERIES_NRF51X) || defined(CONFIG_SOC_COMPATIBLE_NRF52X) +#if defined(CONFIG_SOC_SERIES_NRF51) || defined(CONFIG_SOC_COMPATIBLE_NRF52X) #define NRFX_PPI_CHANNELS_USED_BY_BT_CTLR BT_CTLR_USED_PPI_CHANNELS #define NRFX_PPI_GROUPS_USED_BY_BT_CTLR BT_CTLR_USED_PPI_GROUPS #elif defined(CONFIG_SOC_COMPATIBLE_NRF53X) @@ -78,7 +78,7 @@ #include <../src/nrf_802154_peripherals_nrf54l.h> #define NRFX_DPPI10_CHANNELS_USED_BY_802154_DRV NRF_802154_DPPI_CHANNELS_USED_MASK #define NRFX_DPPI10_GROUPS_USED_BY_802154_DRV NRF_802154_DPPI_GROUPS_USED_MASK -#elif defined(CONFIG_SOC_SERIES_NRF54HX) +#elif defined(CONFIG_SOC_SERIES_NRF54H) #include <../src/nrf_802154_peripherals_nrf54h.h> #define NRFX_DPPI020_CHANNELS_USED_BY_802154_DRV NRF_802154_DPPI_CHANNELS_USED_MASK #define NRFX_DPPI020_GROUPS_USED_BY_802154_DRV NRF_802154_DPPI_GROUPS_USED_MASK diff --git a/modules/nrf_wifi/bus/qspi_if.c b/modules/nrf_wifi/bus/qspi_if.c index 9b42ed6f1eb0..948b4a07be74 100644 --- a/modules/nrf_wifi/bus/qspi_if.c +++ b/modules/nrf_wifi/bus/qspi_if.c @@ -76,7 +76,7 @@ BUILD_ASSERT(QSPI_IF_DEVICE_FREQUENCY >= (NRF_QSPI_BASE_CLOCK_FREQ / 16), * need to be used to achieve the SCK frequency as close as possible (but not * higher) to the one specified in DT. */ -#if defined(CONFIG_SOC_SERIES_NRF53X) +#if defined(CONFIG_SOC_SERIES_NRF53) /* * On nRF53 Series SoCs, the default /4 divider for the HFCLK192M clock can * only be used when the QSPI peripheral is idle. When a QSPI operation is @@ -145,7 +145,7 @@ BUILD_ASSERT(QSPI_IF_DEVICE_FREQUENCY >= (NRF_QSPI_BASE_CLOCK_FREQ / 16), /* For 8 MHz, use PCLK32M / 4 */ #define INST_0_SCK_CFG_WAKE NRF_QSPI_FREQ_DIV4 -#endif /* defined(CONFIG_SOC_SERIES_NRF53X) */ +#endif /* defined(CONFIG_SOC_SERIES_NRF53) */ static int qspi_device_init(const struct device *dev); static void qspi_device_uninit(const struct device *dev); @@ -358,7 +358,7 @@ static inline void qspi_lock(const struct device *dev) * to perform a QSPI operation, otherwise the power consumption would be * increased also when the QSPI peripheral is idle. */ -#if defined(CONFIG_SOC_SERIES_NRF53X) +#if defined(CONFIG_SOC_SERIES_NRF53) nrf_clock_hfclk192m_div_set(NRF_CLOCK, BASE_CLOCK_DIV); k_busy_wait(BASE_CLOCK_SWITCH_DELAY_US); #endif @@ -366,7 +366,7 @@ static inline void qspi_lock(const struct device *dev) static inline void qspi_unlock(const struct device *dev) { -#if defined(CONFIG_SOC_SERIES_NRF53X) +#if defined(CONFIG_SOC_SERIES_NRF53) /* Restore the default base clock divider to reduce power consumption. */ nrf_clock_hfclk192m_div_set(NRF_CLOCK, NRF_CLOCK_HFCLK_DIV_4); @@ -701,7 +701,7 @@ static int qspi_nrfx_configure(const struct device *dev) qspi_fill_init_struct(&QSPIconfig); -#if defined(CONFIG_SOC_SERIES_NRF53X) +#if defined(CONFIG_SOC_SERIES_NRF53) /* When the QSPI peripheral is activated, during the nrfx_qspi driver * initialization, it reads the status of the connected flash chip. * Make sure this transaction is performed with a valid base clock @@ -713,7 +713,7 @@ static int qspi_nrfx_configure(const struct device *dev) int ret = _nrfx_qspi_init(&QSPIconfig, qspi_handler, dev_data); -#if defined(CONFIG_SOC_SERIES_NRF53X) +#if defined(CONFIG_SOC_SERIES_NRF53) /* Restore the default /4 divider after the QSPI initialization. */ nrf_clock_hfclk192m_div_set(NRF_CLOCK, NRF_CLOCK_HFCLK_DIV_4); k_busy_wait(BASE_CLOCK_SWITCH_DELAY_US); @@ -984,7 +984,7 @@ static int qspi_nor_init(const struct device *dev) return qspi_nor_configure(dev); } -#if defined(CONFIG_SOC_SERIES_NRF53X) +#if defined(CONFIG_SOC_SERIES_NRF53) static int qspi_cmd_encryption(const struct device *dev, nrf_qspi_encryption_t *p_cfg) { const struct qspi_buf tx_buf = { .buf = (uint8_t *)&p_cfg->nonce[1], @@ -1404,7 +1404,7 @@ int qspi_cmd_sleep_rpu(const struct device *dev) int qspi_enable_encryption(uint8_t *key) { -#if defined(CONFIG_SOC_SERIES_NRF53X) +#if defined(CONFIG_SOC_SERIES_NRF53) int err = 0; if (qspi_cfg->encryption) { From cc9287d29174800742a19b297234072981fc0aa1 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Thu, 15 Jan 2026 09:03:26 +0000 Subject: [PATCH 2129/3659] samples: Update to use SOC_SERIES_NRF Kconfigs without X suffix Updates usage of the old Kconfig to use the new Kconfig Signed-off-by: Jamie McCrae --- samples/boards/nordic/nrfx/Kconfig | 12 ++++++------ .../subsys/usb/uac2_explicit_feedback/CMakeLists.txt | 2 +- .../usb/uac2_explicit_feedback/src/feedback_nrf.c | 2 +- .../subsys/usb/uac2_implicit_feedback/CMakeLists.txt | 2 +- .../usb/uac2_implicit_feedback/src/feedback_nrf.c | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/samples/boards/nordic/nrfx/Kconfig b/samples/boards/nordic/nrfx/Kconfig index 776090f5bd23..781a66a34ede 100644 --- a/samples/boards/nordic/nrfx/Kconfig +++ b/samples/boards/nordic/nrfx/Kconfig @@ -4,11 +4,11 @@ source "Kconfig.zephyr" config NRFX_GPIOTE0 - default y if SOC_SERIES_NRF51X || \ - SOC_SERIES_NRF52X || \ - (SOC_SERIES_NRF53X && !TRUSTED_EXECUTION_NONSECURE) || \ - (SOC_SERIES_NRF91X && !TRUSTED_EXECUTION_NONSECURE) + default y if SOC_SERIES_NRF51 || \ + SOC_SERIES_NRF52 || \ + (SOC_SERIES_NRF53 && !TRUSTED_EXECUTION_NONSECURE) || \ + (SOC_SERIES_NRF91 && !TRUSTED_EXECUTION_NONSECURE) config NRFX_GPIOTE1 - default y if (SOC_SERIES_NRF53X && TRUSTED_EXECUTION_NONSECURE) || \ - (SOC_SERIES_NRF91X && TRUSTED_EXECUTION_NONSECURE) + default y if (SOC_SERIES_NRF53 && TRUSTED_EXECUTION_NONSECURE) || \ + (SOC_SERIES_NRF91 && TRUSTED_EXECUTION_NONSECURE) diff --git a/samples/subsys/usb/uac2_explicit_feedback/CMakeLists.txt b/samples/subsys/usb/uac2_explicit_feedback/CMakeLists.txt index 443fae217b1a..8c29ad9e24cc 100644 --- a/samples/subsys/usb/uac2_explicit_feedback/CMakeLists.txt +++ b/samples/subsys/usb/uac2_explicit_feedback/CMakeLists.txt @@ -7,7 +7,7 @@ project(usb_audio_async_i2s) include(${ZEPHYR_BASE}/samples/subsys/usb/common/common.cmake) target_sources(app PRIVATE src/main.c) -if(CONFIG_SOC_COMPATIBLE_NRF5340_CPUAPP OR CONFIG_SOC_SERIES_NRF54HX) +if(CONFIG_SOC_COMPATIBLE_NRF5340_CPUAPP OR CONFIG_SOC_SERIES_NRF54H) target_sources(app PRIVATE src/feedback_nrf.c) else() target_sources(app PRIVATE src/feedback_dummy.c) diff --git a/samples/subsys/usb/uac2_explicit_feedback/src/feedback_nrf.c b/samples/subsys/usb/uac2_explicit_feedback/src/feedback_nrf.c index 711dd570d4de..97534c73194c 100644 --- a/samples/subsys/usb/uac2_explicit_feedback/src/feedback_nrf.c +++ b/samples/subsys/usb/uac2_explicit_feedback/src/feedback_nrf.c @@ -38,7 +38,7 @@ static inline void feedback_target_init(void) } } -#elif IS_ENABLED(CONFIG_SOC_SERIES_NRF54HX) +#elif IS_ENABLED(CONFIG_SOC_SERIES_NRF54H) #include diff --git a/samples/subsys/usb/uac2_implicit_feedback/CMakeLists.txt b/samples/subsys/usb/uac2_implicit_feedback/CMakeLists.txt index 443fae217b1a..8c29ad9e24cc 100644 --- a/samples/subsys/usb/uac2_implicit_feedback/CMakeLists.txt +++ b/samples/subsys/usb/uac2_implicit_feedback/CMakeLists.txt @@ -7,7 +7,7 @@ project(usb_audio_async_i2s) include(${ZEPHYR_BASE}/samples/subsys/usb/common/common.cmake) target_sources(app PRIVATE src/main.c) -if(CONFIG_SOC_COMPATIBLE_NRF5340_CPUAPP OR CONFIG_SOC_SERIES_NRF54HX) +if(CONFIG_SOC_COMPATIBLE_NRF5340_CPUAPP OR CONFIG_SOC_SERIES_NRF54H) target_sources(app PRIVATE src/feedback_nrf.c) else() target_sources(app PRIVATE src/feedback_dummy.c) diff --git a/samples/subsys/usb/uac2_implicit_feedback/src/feedback_nrf.c b/samples/subsys/usb/uac2_implicit_feedback/src/feedback_nrf.c index c1c72dc07c41..6cb95440cb7f 100644 --- a/samples/subsys/usb/uac2_implicit_feedback/src/feedback_nrf.c +++ b/samples/subsys/usb/uac2_implicit_feedback/src/feedback_nrf.c @@ -29,7 +29,7 @@ static inline void feedback_target_init(void) /* No target specific init necessary */ } -#elif IS_ENABLED(CONFIG_SOC_SERIES_NRF54HX) +#elif IS_ENABLED(CONFIG_SOC_SERIES_NRF54H) #include From a7e099f20b5ba4b74f15b667955702a839ef5329 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Thu, 15 Jan 2026 09:03:33 +0000 Subject: [PATCH 2130/3659] scripts: Update to use SOC_SERIES_NRF Kconfigs without X suffix Updates usage of the old Kconfig to use the new Kconfig Signed-off-by: Jamie McCrae --- scripts/west_commands/runners/nrf_common.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/scripts/west_commands/runners/nrf_common.py b/scripts/west_commands/runners/nrf_common.py index 5cdca1e6b3f6..212b22e83bf7 100644 --- a/scripts/west_commands/runners/nrf_common.py +++ b/scripts/west_commands/runners/nrf_common.py @@ -216,19 +216,19 @@ def ensure_family(self): if self.family is not None: return - if self.build_conf.getboolean('CONFIG_SOC_SERIES_NRF51X'): + if self.build_conf.getboolean('CONFIG_SOC_SERIES_NRF51'): self.family = 'nrf51' - elif self.build_conf.getboolean('CONFIG_SOC_SERIES_NRF52X'): + elif self.build_conf.getboolean('CONFIG_SOC_SERIES_NRF52'): self.family = 'nrf52' - elif self.build_conf.getboolean('CONFIG_SOC_SERIES_NRF53X'): + elif self.build_conf.getboolean('CONFIG_SOC_SERIES_NRF53'): self.family = 'nrf53' - elif self.build_conf.getboolean('CONFIG_SOC_SERIES_NRF54LX'): + elif self.build_conf.getboolean('CONFIG_SOC_SERIES_NRF54L'): self.family = 'nrf54l' - elif self.build_conf.getboolean('CONFIG_SOC_SERIES_NRF54HX'): + elif self.build_conf.getboolean('CONFIG_SOC_SERIES_NRF54H'): self.family = 'nrf54h' - elif self.build_conf.getboolean('CONFIG_SOC_SERIES_NRF91X'): + elif self.build_conf.getboolean('CONFIG_SOC_SERIES_NRF91'): self.family = 'nrf91' - elif self.build_conf.getboolean('CONFIG_SOC_SERIES_NRF92X'): + elif self.build_conf.getboolean('CONFIG_SOC_SERIES_NRF92'): self.family = 'nrf92' else: raise RuntimeError(f'unknown nRF; update {__file__}') From 9700579f6acaf1c47f289e5d8cfb7b9681efeec9 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Thu, 15 Jan 2026 09:03:51 +0000 Subject: [PATCH 2131/3659] bluetooth: Update to use SOC_SERIES_NRF Kconfigs without X suffix Updates usage of the old Kconfig to use the new Kconfig Signed-off-by: Jamie McCrae --- subsys/bluetooth/controller/Kconfig | 30 +++++++++---------- .../bluetooth/controller/Kconfig.ll_sw_split | 20 ++++++------- .../nrf5/nrfx_glue/bt_ctlr_used_resources.h | 4 +-- .../ll_sw/nordic/hal/nrf5/radio/radio.c | 28 ++++++++--------- .../ll_sw/nordic/hal/nrf5/radio/radio_nrf5.h | 8 ++--- .../controller/ll_sw/nordic/hal/nrf5/swi.h | 2 +- .../controller/ll_sw/nordic/hci/hci_vendor.h | 2 +- subsys/bluetooth/host/Kconfig | 4 +-- 8 files changed, 49 insertions(+), 49 deletions(-) diff --git a/subsys/bluetooth/controller/Kconfig b/subsys/bluetooth/controller/Kconfig index 07cdcd2941fd..0d5cba824162 100644 --- a/subsys/bluetooth/controller/Kconfig +++ b/subsys/bluetooth/controller/Kconfig @@ -353,54 +353,54 @@ config BT_CTLR_TX_PWR_PLUS_12 config BT_CTLR_TX_PWR_PLUS_10 bool "+10 dBm" - depends on SOC_SERIES_NRF54HX + depends on SOC_SERIES_NRF54H config BT_CTLR_TX_PWR_PLUS_9 bool "+9 dBm" - depends on SOC_SERIES_NRF54HX || SOC_FAMILY_ESPRESSIF_ESP32 + depends on SOC_SERIES_NRF54H || SOC_FAMILY_ESPRESSIF_ESP32 config BT_CTLR_TX_PWR_PLUS_8 bool "+8 dBm" - depends on HAS_HW_NRF_RADIO_TX_PWR_HIGH || SOC_SERIES_NRF54HX || SOC_COMPATIBLE_NRF54LX + depends on HAS_HW_NRF_RADIO_TX_PWR_HIGH || SOC_SERIES_NRF54H || SOC_COMPATIBLE_NRF54LX config BT_CTLR_TX_PWR_PLUS_7 bool "+7 dBm" - depends on HAS_HW_NRF_RADIO_TX_PWR_HIGH || SOC_SERIES_NRF54HX || SOC_COMPATIBLE_NRF54LX + depends on HAS_HW_NRF_RADIO_TX_PWR_HIGH || SOC_SERIES_NRF54H || SOC_COMPATIBLE_NRF54LX config BT_CTLR_TX_PWR_PLUS_6 bool "+6 dBm" - depends on HAS_HW_NRF_RADIO_TX_PWR_HIGH || SOC_SERIES_NRF54HX || SOC_COMPATIBLE_NRF54LX || SOC_FAMILY_ESPRESSIF_ESP32 + depends on HAS_HW_NRF_RADIO_TX_PWR_HIGH || SOC_SERIES_NRF54H || SOC_COMPATIBLE_NRF54LX || SOC_FAMILY_ESPRESSIF_ESP32 config BT_CTLR_TX_PWR_PLUS_5 bool "+5 dBm" - depends on HAS_HW_NRF_RADIO_TX_PWR_HIGH || SOC_SERIES_NRF54HX || SOC_COMPATIBLE_NRF54LX + depends on HAS_HW_NRF_RADIO_TX_PWR_HIGH || SOC_SERIES_NRF54H || SOC_COMPATIBLE_NRF54LX config BT_CTLR_TX_PWR_PLUS_4 bool "+4 dBm" - depends on SOC_SERIES_NRF51X || SOC_COMPATIBLE_NRF52X || SOC_SERIES_NRF54HX || SOC_COMPATIBLE_NRF54LX + depends on SOC_SERIES_NRF51 || SOC_COMPATIBLE_NRF52X || SOC_SERIES_NRF54H || SOC_COMPATIBLE_NRF54LX config BT_CTLR_TX_PWR_PLUS_3 bool "+3 dBm" - depends on SOC_COMPATIBLE_NRF52X || SOC_COMPATIBLE_NRF53X || SOC_SERIES_NRF54HX || SOC_COMPATIBLE_NRF54LX || SOC_FAMILY_ESPRESSIF_ESP32 + depends on SOC_COMPATIBLE_NRF52X || SOC_COMPATIBLE_NRF53X || SOC_SERIES_NRF54H || SOC_COMPATIBLE_NRF54LX || SOC_FAMILY_ESPRESSIF_ESP32 config BT_CTLR_TX_PWR_PLUS_2 bool "+2 dBm" - depends on HAS_HW_NRF_RADIO_TX_PWR_HIGH || SOC_COMPATIBLE_NRF53X || SOC_SERIES_NRF54HX || SOC_COMPATIBLE_NRF54LX + depends on HAS_HW_NRF_RADIO_TX_PWR_HIGH || SOC_COMPATIBLE_NRF53X || SOC_SERIES_NRF54H || SOC_COMPATIBLE_NRF54LX config BT_CTLR_TX_PWR_PLUS_1 bool "+1 dBm" - depends on SOC_COMPATIBLE_NRF53X || SOC_SERIES_NRF54HX || SOC_COMPATIBLE_NRF54LX + depends on SOC_COMPATIBLE_NRF53X || SOC_SERIES_NRF54H || SOC_COMPATIBLE_NRF54LX config BT_CTLR_TX_PWR_0 bool "0 dBm" config BT_CTLR_TX_PWR_MINUS_1 bool "-1 dBm" - depends on SOC_COMPATIBLE_NRF53X || SOC_SERIES_NRF54HX || SOC_COMPATIBLE_NRF54LX + depends on SOC_COMPATIBLE_NRF53X || SOC_SERIES_NRF54H || SOC_COMPATIBLE_NRF54LX config BT_CTLR_TX_PWR_MINUS_2 bool "-2 dBm" - depends on SOC_COMPATIBLE_NRF53X || SOC_SERIES_NRF54HX || SOC_COMPATIBLE_NRF54LX + depends on SOC_COMPATIBLE_NRF53X || SOC_SERIES_NRF54H || SOC_COMPATIBLE_NRF54LX config BT_CTLR_TX_PWR_MINUS_3 bool "-3 dBm" @@ -467,11 +467,11 @@ config BT_CTLR_TX_PWR_MINUS_26 config BT_CTLR_TX_PWR_MINUS_30 bool "-30 dBm" - depends on SOC_SERIES_NRF51X || SOC_SERIES_NRF54HX + depends on SOC_SERIES_NRF51 || SOC_SERIES_NRF54H config BT_CTLR_TX_PWR_MINUS_40 bool "-40 dBm" - depends on SOC_COMPATIBLE_NRF52X || SOC_COMPATIBLE_NRF53X || SOC_SERIES_NRF54HX || SOC_COMPATIBLE_NRF54LX + depends on SOC_COMPATIBLE_NRF52X || SOC_COMPATIBLE_NRF53X || SOC_SERIES_NRF54H || SOC_COMPATIBLE_NRF54LX config BT_CTLR_TX_PWR_MINUS_46 bool "-46 dBm" @@ -479,7 +479,7 @@ config BT_CTLR_TX_PWR_MINUS_46 config BT_CTLR_TX_PWR_MINUS_70 bool "-70 dBm" - depends on SOC_SERIES_NRF54HX + depends on SOC_SERIES_NRF54H endchoice diff --git a/subsys/bluetooth/controller/Kconfig.ll_sw_split b/subsys/bluetooth/controller/Kconfig.ll_sw_split index 931a7ba3438a..98a74224f624 100644 --- a/subsys/bluetooth/controller/Kconfig.ll_sw_split +++ b/subsys/bluetooth/controller/Kconfig.ll_sw_split @@ -23,7 +23,7 @@ config BT_LLL_VENDOR_NORDIC !BT_CTLR_DATA_LENGTH_CLEAR && \ !BT_CTLR_PHY_2M_NRF select BT_CTLR_PRIVACY_SUPPORT if BT_CTLR_CRYPTO_SUPPORT && \ - !SOC_SERIES_NRF51X + !SOC_SERIES_NRF51 select BT_CTLR_CONN_PARAM_REQ_SUPPORT select BT_CTLR_EXT_REJ_IND_SUPPORT select BT_CTLR_PER_INIT_FEAT_XCHG_SUPPORT @@ -356,7 +356,7 @@ config BT_CTLR_TRPA_CACHE_SIZE config BT_CTLR_DATA_LENGTH_CLEAR bool "Data Length Support (Cleartext only)" - depends on SOC_SERIES_NRF51X + depends on SOC_SERIES_NRF51 help Enable support for Bluetooth v4.2 LE Data Length Update procedure, up to 251 byte cleartext payloads in the Controller. Encrypted connections @@ -365,7 +365,7 @@ config BT_CTLR_DATA_LENGTH_CLEAR config BT_CTLR_PHY_2M_NRF bool "2Mbps Nordic Semiconductor PHY Support (Cleartext only)" - depends on SOC_SERIES_NRF51X + depends on SOC_SERIES_NRF51 help Enable support for Nordic Semiconductor proprietary 2Mbps PHY in the Controller. Encrypted connections are not supported. @@ -889,7 +889,7 @@ config BT_CTLR_SLOT_RESERVATION_UPDATE config BT_CTLR_LLL_PRIO int "Lower Link Layer (Radio) IRQ priority" if (BT_CTLR_ULL_LLL_PRIO_SUPPORT && !BT_CTLR_ZLI) - range 0 3 if SOC_SERIES_NRF51X + range 0 3 if SOC_SERIES_NRF51 range 0 6 if (SOC_COMPATIBLE_NRF52X || SOC_COMPATIBLE_NRF53X) default 0 help @@ -897,7 +897,7 @@ config BT_CTLR_LLL_PRIO config BT_CTLR_ULL_HIGH_PRIO int "Upper Link Layer High IRQ priority" if BT_CTLR_ULL_LLL_PRIO_SUPPORT - range BT_CTLR_LLL_PRIO 3 if SOC_SERIES_NRF51X + range BT_CTLR_LLL_PRIO 3 if SOC_SERIES_NRF51 range BT_CTLR_LLL_PRIO 6 if (SOC_COMPATIBLE_NRF52X || SOC_COMPATIBLE_NRF53X) default BT_CTLR_LLL_PRIO if (!BT_CTLR_ULL_LLL_PRIO_SUPPORT || BT_CTLR_ZLI || BT_CTLR_LOW_LAT) default 1 @@ -907,7 +907,7 @@ config BT_CTLR_ULL_HIGH_PRIO config BT_CTLR_ULL_LOW_PRIO int "Upper Link Layer Low IRQ priority" if BT_CTLR_ULL_LLL_PRIO_SUPPORT - range BT_CTLR_ULL_HIGH_PRIO 3 if SOC_SERIES_NRF51X + range BT_CTLR_ULL_HIGH_PRIO 3 if SOC_SERIES_NRF51 range BT_CTLR_ULL_HIGH_PRIO 6 if (SOC_COMPATIBLE_NRF52X || SOC_COMPATIBLE_NRF53X) default BT_CTLR_ULL_HIGH_PRIO help @@ -917,7 +917,7 @@ config BT_CTLR_ULL_LOW_PRIO config BT_CTLR_LOW_LAT bool "Low latency non-negotiating event preemption" depends on BT_CTLR_LOW_LAT_ULL && BT_CTLR_LOW_LAT_ULL_DONE - default y if SOC_SERIES_NRF51X + default y if SOC_SERIES_NRF51 help Use low latency non-negotiating event preemption. This reduces Radio ISR latencies by the controller event scheduling framework. @@ -926,14 +926,14 @@ config BT_CTLR_LOW_LAT config BT_CTLR_LOW_LAT_ULL bool "Low latency ULL" - default y if SOC_SERIES_NRF51X + default y if SOC_SERIES_NRF51 help Low latency ULL implementation that uses tailchaining instead of while loop to demux rx messages from LLL. config BT_CTLR_LOW_LAT_ULL_DONE bool "Low latency ULL prepare dequeue" - default y if SOC_SERIES_NRF51X + default y if SOC_SERIES_NRF51 help Done events be processed and dequeued in ULL context. @@ -1240,7 +1240,7 @@ config BT_TICKER_CNTR_FREE_RUNNING config BT_TICKER_LOW_LAT bool "Ticker low latency mode" - default y if SOC_SERIES_NRF51X + default y if SOC_SERIES_NRF51 help This option enables legacy ticker scheduling which defers overlapping ticker node timeouts and thereby prevents ticker interrupts during diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/nrfx_glue/bt_ctlr_used_resources.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/nrfx_glue/bt_ctlr_used_resources.h index 6275a72c0aaa..c0300199096f 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/nrfx_glue/bt_ctlr_used_resources.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/nrfx_glue/bt_ctlr_used_resources.h @@ -12,7 +12,7 @@ * conditionally compile them based on feature Kconfig defines in those * resources header file. */ -#if defined(CONFIG_SOC_SERIES_NRF51X) || defined(CONFIG_SOC_COMPATIBLE_NRF52X) +#if defined(CONFIG_SOC_SERIES_NRF51) || defined(CONFIG_SOC_COMPATIBLE_NRF52X) #include "../radio/radio_nrf5_ppi_resources.h" #else #include "../radio/radio_nrf5_dppi_resources.h" @@ -78,7 +78,7 @@ #endif #if defined(CONFIG_BT_CTLR_DF_PHYEND_OFFSET_COMPENSATION_ENABLE) -#if !defined(CONFIG_SOC_SERIES_NRF51X) && !defined(CONFIG_SOC_COMPATIBLE_NRF52X) +#if !defined(CONFIG_SOC_SERIES_NRF51) && !defined(CONFIG_SOC_COMPATIBLE_NRF52X) #define HAL_USED_PPI_CHANNELS_7 \ (BIT(HAL_SW_SWITCH_TIMER_PHYEND_DELAY_COMPENSATION_DISABLE_PPI)) #else diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c index 62f4019198b4..00ed03050fdb 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c @@ -294,7 +294,7 @@ void radio_phy_set(uint8_t phy, uint8_t flags) NRF_RADIO->MODE = (mode << RADIO_MODE_MODE_Pos) & RADIO_MODE_MODE_Msk; -#if !defined(CONFIG_SOC_SERIES_NRF51X) && !defined(CONFIG_SOC_COMPATIBLE_NRF54LX) +#if !defined(CONFIG_SOC_SERIES_NRF51) && !defined(CONFIG_SOC_COMPATIBLE_NRF54LX) #if defined(CONFIG_BT_CTLR_RADIO_ENABLE_FAST) NRF_RADIO->MODECNF0 = ((RADIO_MODECNF0_DTX_Center << RADIO_MODECNF0_DTX_Pos) & @@ -307,7 +307,7 @@ void radio_phy_set(uint8_t phy, uint8_t flags) RADIO_MODECNF0_DTX_Pos) & RADIO_MODECNF0_DTX_Msk; #endif /* !CONFIG_BT_CTLR_RADIO_ENABLE_FAST */ -#endif /* !CONFIG_SOC_SERIES_NRF51X && !CONFIG_SOC_COMPATIBLE_NRF54LX */ +#endif /* !CONFIG_SOC_SERIES_NRF51 && !CONFIG_SOC_COMPATIBLE_NRF54LX */ } void radio_tx_power_set(int8_t power) @@ -385,7 +385,7 @@ void radio_pkt_configure(uint8_t bits_len, uint8_t max_len, uint8_t flags) uint32_t extra; uint8_t phy; -#if defined(CONFIG_SOC_SERIES_NRF51X) +#if defined(CONFIG_SOC_SERIES_NRF51) ARG_UNUSED(phy); extra = 0U; @@ -1056,7 +1056,7 @@ void radio_rssi_measure(void) { NRF_RADIO->SHORTS |= (RADIO_SHORTS_ADDRESS_RSSISTART_Msk | -#if defined(CONFIG_SOC_SERIES_NRF51X) || \ +#if defined(CONFIG_SOC_SERIES_NRF51) || \ defined(CONFIG_SOC_COMPATIBLE_NRF52X) || \ defined(CONFIG_SOC_COMPATIBLE_NRF5340_CPUNET) RADIO_SHORTS_DISABLED_RSSISTOP_Msk | @@ -1071,7 +1071,7 @@ uint32_t radio_rssi_get(void) void radio_rssi_status_reset(void) { -#if defined(CONFIG_SOC_SERIES_NRF51X) || \ +#if defined(CONFIG_SOC_SERIES_NRF51) || \ defined(CONFIG_SOC_COMPATIBLE_NRF52X) || \ defined(CONFIG_SOC_COMPATIBLE_NRF5340_CPUNET) nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_RSSIEND); @@ -1080,7 +1080,7 @@ void radio_rssi_status_reset(void) uint32_t radio_rssi_is_ready(void) { -#if defined(CONFIG_SOC_SERIES_NRF51X) || \ +#if defined(CONFIG_SOC_SERIES_NRF51) || \ defined(CONFIG_SOC_COMPATIBLE_NRF52X) || \ defined(CONFIG_SOC_COMPATIBLE_NRF5340_CPUNET) return (NRF_RADIO->EVENTS_RSSIEND != 0); @@ -2109,7 +2109,7 @@ static void *radio_ccm_ext_rx_pkt_set(struct ccm *cnf, uint8_t phy, uint8_t pdu_ mode |= (CCM_MODE_LENGTH_Extended << CCM_MODE_LENGTH_Pos) & CCM_MODE_LENGTH_Msk; -#elif defined(CONFIG_SOC_SERIES_NRF51X) +#elif defined(CONFIG_SOC_SERIES_NRF51) mode = (CCM_MODE_MODE_Decryption << CCM_MODE_MODE_Pos) & CCM_MODE_MODE_Msk; @@ -2121,10 +2121,10 @@ static void *radio_ccm_ext_rx_pkt_set(struct ccm *cnf, uint8_t phy, uint8_t pdu_ switch (phy) { default: case PHY_1M: -#if !defined(CONFIG_SOC_SERIES_NRF51X) && !defined(CONFIG_SOC_COMPATIBLE_NRF54LX) +#if !defined(CONFIG_SOC_SERIES_NRF51) && !defined(CONFIG_SOC_COMPATIBLE_NRF54LX) mode |= (CCM_MODE_DATARATE_1Mbit << CCM_MODE_DATARATE_Pos) & CCM_MODE_DATARATE_Msk; -#endif /* !CONFIG_SOC_SERIES_NRF51X && !CONFIG_SOC_COMPATIBLE_NRF54LX */ +#endif /* !CONFIG_SOC_SERIES_NRF51 && !CONFIG_SOC_COMPATIBLE_NRF54LX */ if (false) { @@ -2147,10 +2147,10 @@ static void *radio_ccm_ext_rx_pkt_set(struct ccm *cnf, uint8_t phy, uint8_t pdu_ break; case PHY_2M: -#if !defined(CONFIG_SOC_SERIES_NRF51X) && !defined(CONFIG_SOC_COMPATIBLE_NRF54LX) +#if !defined(CONFIG_SOC_SERIES_NRF51) && !defined(CONFIG_SOC_COMPATIBLE_NRF54LX) mode |= (CCM_MODE_DATARATE_2Mbit << CCM_MODE_DATARATE_Pos) & CCM_MODE_DATARATE_Msk; -#endif /* !CONFIG_SOC_SERIES_NRF51X && !CONFIG_SOC_COMPATIBLE_NRF54LX */ +#endif /* !CONFIG_SOC_SERIES_NRF51 && !CONFIG_SOC_COMPATIBLE_NRF54LX */ hal_trigger_crypt_ppi_config(); hal_radio_nrf_ppi_channels_enable(BIT(HAL_TRIGGER_CRYPT_PPI)); @@ -2208,7 +2208,7 @@ static void *radio_ccm_ext_rx_pkt_set(struct ccm *cnf, uint8_t phy, uint8_t pdu_ * CONFIG_SOC_COMPATIBLE_NRF54LX */ -#if !defined(CONFIG_SOC_SERIES_NRF51X) && \ +#if !defined(CONFIG_SOC_SERIES_NRF51) && \ !defined(CONFIG_SOC_NRF52832) && \ !defined(CONFIG_SOC_COMPATIBLE_NRF54LX) && \ (!defined(CONFIG_BT_CTLR_DATA_LENGTH_MAX) || \ @@ -2363,7 +2363,7 @@ static void *radio_ccm_ext_tx_pkt_set(struct ccm *cnf, uint8_t pdu_type, void *p mode |= (CCM_MODE_DATARATE_2Mbit << CCM_MODE_DATARATE_Pos) & CCM_MODE_DATARATE_Msk; -#elif defined(CONFIG_SOC_SERIES_NRF51X) +#elif defined(CONFIG_SOC_SERIES_NRF51) mode = (CCM_MODE_MODE_Encryption << CCM_MODE_MODE_Pos) & CCM_MODE_MODE_Msk; @@ -2397,7 +2397,7 @@ static void *radio_ccm_ext_tx_pkt_set(struct ccm *cnf, uint8_t pdu_type, void *p * CONFIG_SOC_COMPATIBLE_NRF54LX */ -#if !defined(CONFIG_SOC_SERIES_NRF51X) && \ +#if !defined(CONFIG_SOC_SERIES_NRF51) && \ !defined(CONFIG_SOC_NRF52832) && \ !defined(CONFIG_SOC_COMPATIBLE_NRF54LX) && \ (!defined(CONFIG_BT_CTLR_DATA_LENGTH_MAX) || \ diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5.h index 1b15f41c4080..f12b0a4d1915 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5.h @@ -20,7 +20,7 @@ #define HAL_RADIO_NS2US_ROUND(ns) ((ns + 500)/1000) /* SoC specific defines */ -#if defined(CONFIG_SOC_SERIES_NRF51X) +#if defined(CONFIG_SOC_SERIES_NRF51) #include "radio_nrf51.h" #elif defined(CONFIG_SOC_NRF52805) #include "radio_nrf52805.h" @@ -39,7 +39,7 @@ #elif defined(CONFIG_SOC_NRF5340_CPUNET) #include #include "radio_nrf5340.h" -#elif defined(CONFIG_SOC_SERIES_NRF54LX) +#elif defined(CONFIG_SOC_SERIES_NRF54L) #include #include "radio_nrf54lx.h" #elif defined(CONFIG_BOARD_NRF52_BSIM) @@ -81,7 +81,7 @@ /* Include RTC/GRTC Compare Index used to Trigger Radio TXEN/RXEN */ #include "hal/cntr.h" -#if defined(CONFIG_SOC_SERIES_NRF51X) || defined(CONFIG_SOC_COMPATIBLE_NRF52X) +#if defined(CONFIG_SOC_SERIES_NRF51) || defined(CONFIG_SOC_COMPATIBLE_NRF52X) #include #include "radio_nrf5_ppi_resources.h" #include "radio_nrf5_ppi.h" @@ -102,7 +102,7 @@ #define HAL_RADIO_RESET_VALUE_PCNF1 0x00000000UL /* SoC specific Radio PDU length field maximum value */ -#if defined(CONFIG_SOC_SERIES_NRF51X) +#if defined(CONFIG_SOC_SERIES_NRF51) #define HAL_RADIO_PDU_LEN_MAX (BIT(5) - 1) #else #define HAL_RADIO_PDU_LEN_MAX (BIT(8) - 1) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/swi.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/swi.h index 801479206461..d34f3b4d6aab 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/swi.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/swi.h @@ -5,7 +5,7 @@ */ /* nRF51 and nRF52 Series IRQ mapping*/ -#if defined(CONFIG_SOC_SERIES_NRF51X) || defined(CONFIG_SOC_COMPATIBLE_NRF52X) +#if defined(CONFIG_SOC_SERIES_NRF51) || defined(CONFIG_SOC_COMPATIBLE_NRF52X) #define HAL_SWI_RADIO_IRQ SWI4_IRQn #define HAL_SWI_WORKER_IRQ RTC0_IRQn diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hci/hci_vendor.h b/subsys/bluetooth/controller/ll_sw/nordic/hci/hci_vendor.h index 93abbd5ae5d2..c73fa9537daa 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hci/hci_vendor.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hci/hci_vendor.h @@ -6,7 +6,7 @@ #if defined(CONFIG_SOC_COMPATIBLE_NRF) #define BT_HCI_VS_HW_PLAT BT_HCI_VS_HW_PLAT_NORDIC -#if defined(CONFIG_SOC_SERIES_NRF51X) +#if defined(CONFIG_SOC_SERIES_NRF51) #define BT_HCI_VS_HW_VAR BT_HCI_VS_HW_VAR_NORDIC_NRF51X #elif defined(CONFIG_SOC_COMPATIBLE_NRF52X) #define BT_HCI_VS_HW_VAR BT_HCI_VS_HW_VAR_NORDIC_NRF52X diff --git a/subsys/bluetooth/host/Kconfig b/subsys/bluetooth/host/Kconfig index 4054d6c99a41..ea8b2f79e558 100644 --- a/subsys/bluetooth/host/Kconfig +++ b/subsys/bluetooth/host/Kconfig @@ -75,7 +75,7 @@ config BT_HCI_TX_PRIO choice BT_RECV_CONTEXT prompt "BT RX Thread Selection" - default BT_RECV_WORKQ_SYS if SOC_SERIES_NRF51X + default BT_RECV_WORKQ_SYS if SOC_SERIES_NRF51 default BT_RECV_WORKQ_BT help Selects in which context incoming low priority HCI packets are processed. @@ -139,7 +139,7 @@ config BT_TX_PROCESSOR_THREAD bool "TX processor thread. Disabling may cause deadlocks." # This option is automatically selected for all platforms except nRF51 # due to limited RAM on nRF51 devices. - default y if !SOC_SERIES_NRF51X + default y if !SOC_SERIES_NRF51 if BT_TX_PROCESSOR_THREAD From 70fcffd5def5b75da133e58ef60796d5a69ba104 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Thu, 15 Jan 2026 09:04:05 +0000 Subject: [PATCH 2132/3659] tests: Update to use SOC_SERIES_NRF Kconfigs without X suffix Updates usage of the old Kconfig to use the new Kconfig Signed-off-by: Jamie McCrae --- .../ram_context_for_isr/Kconfig | 2 +- .../arm_irq_vector_table/src/arm_irq_vector_table.c | 12 ++++++------ tests/arch/common/gen_isr_table/src/main.c | 6 +++--- tests/arch/common/interrupt/src/nested_irq.c | 4 ++-- .../drivers/clock_control/clock_control_api/Kconfig | 2 +- .../clock_control/nrf_onoff_and_bt/src/main.c | 2 +- tests/drivers/flash/negative_tests/src/main.c | 2 +- tests/drivers/watchdog/wdt_error_cases/src/main.c | 2 +- tests/kernel/sleep/src/usleep.c | 2 +- tests/lib/cpp/cxx/testcase.yaml | 2 +- tests/lib/mpsc_pbuf/src/main.c | 4 ++-- 11 files changed, 20 insertions(+), 20 deletions(-) diff --git a/tests/application_development/ram_context_for_isr/Kconfig b/tests/application_development/ram_context_for_isr/Kconfig index b4031538b4b9..53cee6732e7f 100644 --- a/tests/application_development/ram_context_for_isr/Kconfig +++ b/tests/application_development/ram_context_for_isr/Kconfig @@ -12,7 +12,7 @@ config TEST_IRQ_NUM default 18 if SOC_SERIES_STM32C0X default 1 if (SOC_SERIES_NPCX9 || SOC_SERIES_NPCX7 || SOC_SERIES_NPCK3) default 29 if SOC_K32L2B31A - default 28 if SOC_SERIES_NRF54LX + default 28 if SOC_SERIES_NRF54L default 0 help IRQ number to use for testing purposes. This should be an diff --git a/tests/arch/arm/arm_irq_vector_table/src/arm_irq_vector_table.c b/tests/arch/arm/arm_irq_vector_table/src/arm_irq_vector_table.c index c971f5c1268c..71f7241515ca 100644 --- a/tests/arch/arm/arm_irq_vector_table/src/arm_irq_vector_table.c +++ b/tests/arch/arm/arm_irq_vector_table/src/arm_irq_vector_table.c @@ -24,10 +24,10 @@ * the TIMER0 IRQ line, which is used by the system timer. */ #define _ISR_OFFSET (TIMER0_IRQn + 1) -#elif defined(CONFIG_SOC_SERIES_NRF54LX) || defined(CONFIG_SOC_SERIES_NRF71) +#elif defined(CONFIG_SOC_SERIES_NRF54L) || defined(CONFIG_SOC_SERIES_NRF71) /* For nRF54L Series, use SWI00-02 interrupt lines. */ #define _ISR_OFFSET SWI00_IRQn -#elif defined(CONFIG_SOC_SERIES_NRF54HX) || defined(CONFIG_SOC_SERIES_NRF92X) +#elif defined(CONFIG_SOC_SERIES_NRF54H) || defined(CONFIG_SOC_SERIES_NRF92) /* For nRF54H and nRF92 Series, use BELLBOARD_0-2 interrupt lines. */ #define _ISR_OFFSET BELLBOARD_0_IRQn #else @@ -144,9 +144,9 @@ typedef void (*vth)(void); /* Vector Table Handler */ * Note: qemu_cortex_m0 uses TIMER0 to implement system timer. */ void nrfx_power_clock_irq_handler(void); -#if defined(CONFIG_SOC_SERIES_NRF51X) || defined(CONFIG_SOC_SERIES_NRF52X) +#if defined(CONFIG_SOC_SERIES_NRF51) || defined(CONFIG_SOC_SERIES_NRF52) #define POWER_CLOCK_IRQ_NUM POWER_CLOCK_IRQn -#elif defined(CONFIG_SOC_SERIES_NRF54HX) || defined(CONFIG_SOC_SERIES_NRF92X) +#elif defined(CONFIG_SOC_SERIES_NRF54H) || defined(CONFIG_SOC_SERIES_NRF92) #define POWER_CLOCK_IRQ_NUM -1 /* not needed */ #else #define POWER_CLOCK_IRQ_NUM CLOCK_POWER_IRQn @@ -156,8 +156,8 @@ void nrfx_power_clock_irq_handler(void); void timer0_nrf_isr(void); #define TIMER_IRQ_HANDLER timer0_nrf_isr #define TIMER_IRQ_NUM TIMER0_IRQn -#elif defined(CONFIG_SOC_SERIES_NRF54LX) || defined(CONFIG_SOC_SERIES_NRF54HX) || \ - defined(CONFIG_SOC_SERIES_NRF71) || defined(CONFIG_SOC_SERIES_NRF92X) +#elif defined(CONFIG_SOC_SERIES_NRF54L) || defined(CONFIG_SOC_SERIES_NRF54H) || \ + defined(CONFIG_SOC_SERIES_NRF71) || defined(CONFIG_SOC_SERIES_NRF92) void nrfx_grtc_irq_handler(void); #define TIMER_IRQ_HANDLER nrfx_grtc_irq_handler #define TIMER_IRQ_NUM DT_IRQN(DT_NODELABEL(grtc)) diff --git a/tests/arch/common/gen_isr_table/src/main.c b/tests/arch/common/gen_isr_table/src/main.c index ebd10e267385..443aa78f9249 100644 --- a/tests/arch/common/gen_isr_table/src/main.c +++ b/tests/arch/common/gen_isr_table/src/main.c @@ -31,13 +31,13 @@ extern const uintptr_t _irq_vector_table[]; #if defined(CONFIG_NRFX_CLIC) -#if (defined(CONFIG_SOC_SERIES_NRF54LX) || defined(CONFIG_SOC_NRF54H20_CPUFLPR)) && \ +#if (defined(CONFIG_SOC_SERIES_NRF54L) || defined(CONFIG_SOC_NRF54H20_CPUFLPR)) && \ defined(CONFIG_RISCV_CORE_NORDIC_VPR) #define ISR1_OFFSET 16 #define ISR3_OFFSET 17 #define ISR5_OFFSET 18 #define TRIG_CHECK_SIZE 19 -#elif defined(CONFIG_SOC_SERIES_NRF54HX) && defined(CONFIG_RISCV_CORE_NORDIC_VPR) +#elif defined(CONFIG_SOC_SERIES_NRF54H) && defined(CONFIG_RISCV_CORE_NORDIC_VPR) #define ISR1_OFFSET 14 #define ISR3_OFFSET 15 #define ISR5_OFFSET 16 @@ -110,7 +110,7 @@ extern const uintptr_t _irq_vector_table[]; * with isr used here, so add a workaround */ #define TEST_NUM_IRQS 105 -#elif defined(CONFIG_SOC_NRF5340_CPUAPP) || defined(CONFIG_SOC_SERIES_NRF91X) +#elif defined(CONFIG_SOC_NRF5340_CPUAPP) || defined(CONFIG_SOC_SERIES_NRF91) /* In the application core of nRF5340 and nRF9 series, not all interrupts with highest * numbers are implemented. Thus, limit the number of interrupts reported to * the test, so that it does not try to use some unavailable ones. diff --git a/tests/arch/common/interrupt/src/nested_irq.c b/tests/arch/common/interrupt/src/nested_irq.c index 87f26e8693a6..6f15184a4e3f 100644 --- a/tests/arch/common/interrupt/src/nested_irq.c +++ b/tests/arch/common/interrupt/src/nested_irq.c @@ -62,14 +62,14 @@ */ #define IRQ0_PRIO IRQ_DEFAULT_PRIORITY #define IRQ1_PRIO 0x0 -#elif (defined(CONFIG_SOC_SERIES_NRF54LX) || defined(CONFIG_SOC_NRF54H20_CPUFLPR)) && \ +#elif (defined(CONFIG_SOC_SERIES_NRF54L) || defined(CONFIG_SOC_NRF54H20_CPUFLPR)) && \ defined(CONFIG_RISCV_CORE_NORDIC_VPR) #define IRQ0_LINE 16 #define IRQ1_LINE 17 #define IRQ0_PRIO 1 #define IRQ1_PRIO 2 -#elif defined(CONFIG_SOC_SERIES_NRF54HX) && defined(CONFIG_RISCV_CORE_NORDIC_VPR) +#elif defined(CONFIG_SOC_SERIES_NRF54H) && defined(CONFIG_RISCV_CORE_NORDIC_VPR) #define IRQ0_LINE 14 #define IRQ1_LINE 15 diff --git a/tests/drivers/clock_control/clock_control_api/Kconfig b/tests/drivers/clock_control/clock_control_api/Kconfig index 9315f3e337bc..c8ada20f8ac1 100644 --- a/tests/drivers/clock_control/clock_control_api/Kconfig +++ b/tests/drivers/clock_control/clock_control_api/Kconfig @@ -3,7 +3,7 @@ config TEST_NRF_HF_STARTUP_TIME_US int "Delay required for HF clock startup." - default 3000 if SOC_SERIES_NRF91X + default 3000 if SOC_SERIES_NRF91 default 500 depends on SOC_FAMILY_NORDIC_NRF help diff --git a/tests/drivers/clock_control/nrf_onoff_and_bt/src/main.c b/tests/drivers/clock_control/nrf_onoff_and_bt/src/main.c index 5a400f30d2d6..377cbc0c6d6a 100644 --- a/tests/drivers/clock_control/nrf_onoff_and_bt/src/main.c +++ b/tests/drivers/clock_control/nrf_onoff_and_bt/src/main.c @@ -14,7 +14,7 @@ LOG_MODULE_REGISTER(test); #define TEST_TIME_MS 10000 -#ifdef CONFIG_SOC_SERIES_NRF54LX +#ifdef CONFIG_SOC_SERIES_NRF54L #define HF_STARTUP_TIME_US 600 #else #define HF_STARTUP_TIME_US 400 diff --git a/tests/drivers/flash/negative_tests/src/main.c b/tests/drivers/flash/negative_tests/src/main.c index cc6c08df21c8..fa3723b52312 100644 --- a/tests/drivers/flash/negative_tests/src/main.c +++ b/tests/drivers/flash/negative_tests/src/main.c @@ -26,7 +26,7 @@ #define TEST_AREA_SIZE FIXED_PARTITION_SIZE(TEST_AREA) #define TEST_AREA_DEVICE FIXED_PARTITION_DEVICE(TEST_AREA) -#if defined(CONFIG_SOC_SERIES_NRF54LX) || defined(CONFIG_SOC_FAMILY_MICROCHIP_SAM_D5X_E5X) +#if defined(CONFIG_SOC_SERIES_NRF54L) || defined(CONFIG_SOC_FAMILY_MICROCHIP_SAM_D5X_E5X) #define TEST_FLASH_START (DT_REG_ADDR(DT_MEM_FROM_FIXED_PARTITION(DT_NODELABEL(TEST_AREA)))) #define TEST_FLASH_SIZE (DT_REG_SIZE(DT_MEM_FROM_FIXED_PARTITION(DT_NODELABEL(TEST_AREA)))) #elif defined(CONFIG_SOC_NRF54H20) diff --git a/tests/drivers/watchdog/wdt_error_cases/src/main.c b/tests/drivers/watchdog/wdt_error_cases/src/main.c index b5b78d94af66..281e849354aa 100644 --- a/tests/drivers/watchdog/wdt_error_cases/src/main.c +++ b/tests/drivers/watchdog/wdt_error_cases/src/main.c @@ -44,7 +44,7 @@ #define DEFAULT_WINDOW_MIN (0U) /* Align tests to the specific target: */ -#if defined(CONFIG_SOC_SERIES_NRF53X) || defined(CONFIG_SOC_SERIES_NRF54LX) || \ +#if defined(CONFIG_SOC_SERIES_NRF53) || defined(CONFIG_SOC_SERIES_NRF54L) || \ defined(CONFIG_SOC_SERIES_NRF71) || defined(CONFIG_SOC_NRF54H20) || \ defined(CONFIG_SOC_NRF9280) #define WDT_TEST_FLAGS \ diff --git a/tests/kernel/sleep/src/usleep.c b/tests/kernel/sleep/src/usleep.c index a7c212e59b96..9f3fd4dbe94b 100644 --- a/tests/kernel/sleep/src/usleep.c +++ b/tests/kernel/sleep/src/usleep.c @@ -28,7 +28,7 @@ /* The overhead of k_usleep() adds three ticks per loop iteration on * nRF51, which has a slow CPU clock. */ -#define MAXIMUM_SHORTEST_TICKS (IS_ENABLED(CONFIG_SOC_SERIES_NRF51X) ? 6 : 3) +#define MAXIMUM_SHORTEST_TICKS (IS_ENABLED(CONFIG_SOC_SERIES_NRF51) ? 6 : 3) /* Similar situation for TI CC13XX/CC26XX RTC kernel timer due to the * limitation that a value too close to the current time cannot be * loaded to its comparator. diff --git a/tests/lib/cpp/cxx/testcase.yaml b/tests/lib/cpp/cxx/testcase.yaml index cf32b2b46b4c..14a6d64becbf 100644 --- a/tests/lib/cpp/cxx/testcase.yaml +++ b/tests/lib/cpp/cxx/testcase.yaml @@ -44,7 +44,7 @@ tests: not CONFIG_HAS_SILABS_WISECONNECT and not CONFIG_SOC_FAMILY_AMBIQ and not (CONFIG_CPU_CORTEX_M and (CONFIG_NRF_PLATFORM_HALTIUM or - CONFIG_SOC_SERIES_NRF54LX or CONFIG_SOC_SERIES_NRF71)) + CONFIG_SOC_SERIES_NRF54L or CONFIG_SOC_SERIES_NRF71)) build_only: true extra_configs: - CONFIG_STD_CPP98=y diff --git a/tests/lib/mpsc_pbuf/src/main.c b/tests/lib/mpsc_pbuf/src/main.c index 8a7d6ca1aab7..39dea613a3df 100644 --- a/tests/lib/mpsc_pbuf/src/main.c +++ b/tests/lib/mpsc_pbuf/src/main.c @@ -95,7 +95,7 @@ static void init(struct mpsc_pbuf_buffer *buffer, uint32_t wlen, bool overwrite) mpsc_buf_cfg.size = wlen; mpsc_pbuf_init(buffer, &mpsc_buf_cfg); -#if CONFIG_SOC_SERIES_NRF52X +#if CONFIG_SOC_SERIES_NRF52 DCB->DEMCR |= DCB_DEMCR_TRCENA_Msk; DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk; DWT->CYCCNT = 0; @@ -104,7 +104,7 @@ static void init(struct mpsc_pbuf_buffer *buffer, uint32_t wlen, bool overwrite) static inline uint32_t get_cyc(void) { -#if CONFIG_SOC_SERIES_NRF52X +#if CONFIG_SOC_SERIES_NRF52 return DWT->CYCCNT; #else return k_cycle_get_32(); From 2d0f632c319060775f0284c27d6d8e7adc691ac3 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Thu, 15 Jan 2026 09:07:51 +0000 Subject: [PATCH 2133/3659] soc: nordic: kconfig: Deprecate SOC_SERIES_NRF Kconfigs with X in Deprecates these Kconfigs, as they have been replaced Signed-off-by: Jamie McCrae --- soc/nordic/nrf51/Kconfig | 3 +++ soc/nordic/nrf51/Kconfig.soc | 2 ++ soc/nordic/nrf52/Kconfig | 3 +++ soc/nordic/nrf52/Kconfig.soc | 2 ++ soc/nordic/nrf53/Kconfig | 3 +++ soc/nordic/nrf53/Kconfig.soc | 2 ++ soc/nordic/nrf54h/Kconfig | 3 +++ soc/nordic/nrf54h/Kconfig.soc | 2 ++ soc/nordic/nrf54l/Kconfig | 3 +++ soc/nordic/nrf54l/Kconfig.soc | 2 ++ soc/nordic/nrf91/Kconfig | 3 +++ soc/nordic/nrf91/Kconfig.soc | 2 ++ soc/nordic/nrf92/Kconfig | 3 +++ soc/nordic/nrf92/Kconfig.soc | 2 ++ 14 files changed, 35 insertions(+) diff --git a/soc/nordic/nrf51/Kconfig b/soc/nordic/nrf51/Kconfig index 162896e1fb9d..6c295abaf7d8 100644 --- a/soc/nordic/nrf51/Kconfig +++ b/soc/nordic/nrf51/Kconfig @@ -11,3 +11,6 @@ config SOC_SERIES_NRF51 select HAS_NRFX select HAS_SEGGER_RTT if ZEPHYR_SEGGER_MODULE select HAS_POWEROFF + +config SOC_SERIES_NRF51X + select DEPRECATED diff --git a/soc/nordic/nrf51/Kconfig.soc b/soc/nordic/nrf51/Kconfig.soc index 96d0d885e9b2..3c957df71862 100644 --- a/soc/nordic/nrf51/Kconfig.soc +++ b/soc/nordic/nrf51/Kconfig.soc @@ -12,6 +12,8 @@ config SOC_SERIES_NRF51 config SOC_SERIES_NRF51X bool select SOC_SERIES_NRF51 + help + Deprecated Kconfig, use SOC_SERIES_NRF51 instead config SOC_SERIES default "nrf51" if SOC_SERIES_NRF51 diff --git a/soc/nordic/nrf52/Kconfig b/soc/nordic/nrf52/Kconfig index fe406abfa016..ce6393b1095a 100644 --- a/soc/nordic/nrf52/Kconfig +++ b/soc/nordic/nrf52/Kconfig @@ -16,6 +16,9 @@ config SOC_SERIES_NRF52 select HAS_SWO select HAS_POWEROFF +config SOC_SERIES_NRF52X + select DEPRECATED + config SOC_NRF52832 select CPU_CORTEX_M_HAS_DWT select CPU_HAS_FPU diff --git a/soc/nordic/nrf52/Kconfig.soc b/soc/nordic/nrf52/Kconfig.soc index f510637a3fac..cfc3537f8a3a 100644 --- a/soc/nordic/nrf52/Kconfig.soc +++ b/soc/nordic/nrf52/Kconfig.soc @@ -12,6 +12,8 @@ config SOC_SERIES_NRF52 config SOC_SERIES_NRF52X bool select SOC_SERIES_NRF52 + help + Deprecated Kconfig, use SOC_SERIES_NRF52 instead config SOC_SERIES default "nrf52" if SOC_SERIES_NRF52 diff --git a/soc/nordic/nrf53/Kconfig b/soc/nordic/nrf53/Kconfig index f56351d8d053..7794fba63ba1 100644 --- a/soc/nordic/nrf53/Kconfig +++ b/soc/nordic/nrf53/Kconfig @@ -21,6 +21,9 @@ config SOC_SERIES_NRF53 help Enable support for NRF53 MCU series +config SOC_SERIES_NRF53X + select DEPRECATED + config SOC_NRF5340_CPUAPP select CPU_HAS_NRF_IDAU select CPU_HAS_FPU diff --git a/soc/nordic/nrf53/Kconfig.soc b/soc/nordic/nrf53/Kconfig.soc index 35c1e961a9ad..da21da6614a7 100644 --- a/soc/nordic/nrf53/Kconfig.soc +++ b/soc/nordic/nrf53/Kconfig.soc @@ -12,6 +12,8 @@ config SOC_SERIES_NRF53 config SOC_SERIES_NRF53X bool select SOC_SERIES_NRF53 + help + Deprecated Kconfig, use SOC_SERIES_NRF53 instead config SOC_SERIES default "nrf53" if SOC_SERIES_NRF53 diff --git a/soc/nordic/nrf54h/Kconfig b/soc/nordic/nrf54h/Kconfig index 2b524c90caf2..b23ee3f22a0a 100644 --- a/soc/nordic/nrf54h/Kconfig +++ b/soc/nordic/nrf54h/Kconfig @@ -12,6 +12,9 @@ config SOC_SERIES_NRF54H select NRF_PLATFORM_HALTIUM select EXPERIMENTAL if MCUBOOT +config SOC_SERIES_NRF54HX + select DEPRECATED + config SOC_NRF54H20_CPUAPP_COMMON bool select ARM diff --git a/soc/nordic/nrf54h/Kconfig.soc b/soc/nordic/nrf54h/Kconfig.soc index 38138fb71cc8..a951a5c3ea0f 100644 --- a/soc/nordic/nrf54h/Kconfig.soc +++ b/soc/nordic/nrf54h/Kconfig.soc @@ -12,6 +12,8 @@ config SOC_SERIES_NRF54H config SOC_SERIES_NRF54HX bool select SOC_SERIES_NRF54H + help + Deprecated Kconfig, use SOC_SERIES_NRF54H instead config SOC_SERIES default "nrf54h" if SOC_SERIES_NRF54H diff --git a/soc/nordic/nrf54l/Kconfig b/soc/nordic/nrf54l/Kconfig index b3e290dd6eb2..3d940eaa0540 100644 --- a/soc/nordic/nrf54l/Kconfig +++ b/soc/nordic/nrf54l/Kconfig @@ -10,6 +10,9 @@ config SOC_SERIES_NRF54L select HAS_SEGGER_RTT if ZEPHYR_SEGGER_MODULE select NRF_PLATFORM_LUMOS +config SOC_SERIES_NRF54LX + select DEPRECATED + config SOC_NRF54L_CPUAPP_COMMON bool select ARM diff --git a/soc/nordic/nrf54l/Kconfig.soc b/soc/nordic/nrf54l/Kconfig.soc index 8a8fa084ac25..3363948e6ebb 100644 --- a/soc/nordic/nrf54l/Kconfig.soc +++ b/soc/nordic/nrf54l/Kconfig.soc @@ -12,6 +12,8 @@ config SOC_SERIES_NRF54L config SOC_SERIES_NRF54LX bool select SOC_SERIES_NRF54L + help + Deprecated Kconfig, use SOC_SERIES_NRF54L instead config SOC_SERIES default "nrf54l" if SOC_SERIES_NRF54L diff --git a/soc/nordic/nrf91/Kconfig b/soc/nordic/nrf91/Kconfig index 3f80e00ec66d..1af0e06c87dc 100644 --- a/soc/nordic/nrf91/Kconfig +++ b/soc/nordic/nrf91/Kconfig @@ -16,6 +16,9 @@ config SOC_SERIES_NRF91 select HAS_SEGGER_RTT if ZEPHYR_SEGGER_MODULE select HAS_POWEROFF +config SOC_SERIES_NRF91X + select DEPRECATED + if SOC_SERIES_NRF91 config NRF_SPU_FLASH_REGION_SIZE diff --git a/soc/nordic/nrf91/Kconfig.soc b/soc/nordic/nrf91/Kconfig.soc index 9e5fb2d8e6ff..3dec64ebc753 100644 --- a/soc/nordic/nrf91/Kconfig.soc +++ b/soc/nordic/nrf91/Kconfig.soc @@ -12,6 +12,8 @@ config SOC_SERIES_NRF91 config SOC_SERIES_NRF91X bool select SOC_SERIES_NRF91 + help + Deprecated Kconfig, use SOC_SERIES_NRF91 instead config SOC_SERIES default "nrf91" if SOC_SERIES_NRF91 diff --git a/soc/nordic/nrf92/Kconfig b/soc/nordic/nrf92/Kconfig index 48583001d2a2..86978d745665 100644 --- a/soc/nordic/nrf92/Kconfig +++ b/soc/nordic/nrf92/Kconfig @@ -12,6 +12,9 @@ config SOC_SERIES_NRF92 select NRF_PLATFORM_HALTIUM select EXPERIMENTAL if MCUBOOT +config SOC_SERIES_NRF92X + select DEPRECATED + config SOC_NRF9230_ENGB_CPUAPP select ARM select ARMV8_M_DSP diff --git a/soc/nordic/nrf92/Kconfig.soc b/soc/nordic/nrf92/Kconfig.soc index 757ca00aa7a1..06a8ca3c89b0 100644 --- a/soc/nordic/nrf92/Kconfig.soc +++ b/soc/nordic/nrf92/Kconfig.soc @@ -27,6 +27,8 @@ config SOC_SERIES_NRF92 config SOC_SERIES_NRF92X bool select SOC_SERIES_NRF92 + help + Deprecated Kconfig, use SOC_SERIES_NRF92 instead config SOC_SERIES default "nrf92" if SOC_SERIES_NRF92 From 8c093a08f56cc255a0e1897eeff148a39ad30fd3 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Thu, 15 Jan 2026 09:12:29 +0000 Subject: [PATCH 2134/3659] doc: release: migration_guide: 4.4: Add note on NRF Kconfig change Adds a note on required changed for SOC_SERIES_NRF Kconfigs with an X in them Signed-off-by: Jamie McCrae --- doc/releases/migration-guide-4.4.rst | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/doc/releases/migration-guide-4.4.rst b/doc/releases/migration-guide-4.4.rst index 399377aa4e1d..51db2ef756ae 100644 --- a/doc/releases/migration-guide-4.4.rst +++ b/doc/releases/migration-guide-4.4.rst @@ -83,6 +83,17 @@ Boards ``hal_nxp/rt11xx/fsl_flexspi_nor_boot.h``, they were added to the corresponding SoC-layer CMakeLists.txt files using ``zephyr_library_compile_definitions()`` to limit their scope. +* The following Nordic SoC Kconfigs have been deprecated and replaced, and Kconfig/CMake/code + needs to be updated if they reference the deprecated Kconfigs: + + * :kconfig:option:`CONFIG_SOC_SERIES_NRF51X` with :kconfig:option:`CONFIG_SOC_SERIES_NRF51` + * :kconfig:option:`CONFIG_SOC_SERIES_NRF52X` with :kconfig:option:`CONFIG_SOC_SERIES_NRF52` + * :kconfig:option:`CONFIG_SOC_SERIES_NRF53X` with :kconfig:option:`CONFIG_SOC_SERIES_NRF53` + * :kconfig:option:`CONFIG_SOC_SERIES_NRF54HX` with :kconfig:option:`CONFIG_SOC_SERIES_NRF54H` + * :kconfig:option:`CONFIG_SOC_SERIES_NRF54LX` with :kconfig:option:`CONFIG_SOC_SERIES_NRF54L` + * :kconfig:option:`CONFIG_SOC_SERIES_NRF91X` with :kconfig:option:`CONFIG_SOC_SERIES_NRF91` + * :kconfig:option:`CONFIG_SOC_SERIES_NRF92X` with :kconfig:option:`CONFIG_SOC_SERIES_NRF92` + Device Drivers and Devicetree ***************************** From 3233c2915a1da8e35a46c7901f472f6344824c56 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Thu, 15 Jan 2026 09:20:22 +0000 Subject: [PATCH 2135/3659] arch: arm: core: cortex_m: timing: Remove stray comment Removes a stray comment mentioning a Kconfig which actually has nothing to do with the code Signed-off-by: Jamie McCrae --- arch/arm/core/cortex_m/timing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/core/cortex_m/timing.c b/arch/arm/core/cortex_m/timing.c index 2ce7f64552ba..621df0e4f200 100644 --- a/arch/arm/core/cortex_m/timing.c +++ b/arch/arm/core/cortex_m/timing.c @@ -75,7 +75,7 @@ static inline uint64_t z_arm_dwt_freq_get(void) dwt_frequency = (cyc_freq * ddwt) / dcyc; } return dwt_frequency; -#endif /* CONFIG_SOC_FAMILY_NORDIC_NRF */ +#endif } void arch_timing_init(void) From 6006b3b32ad54f6052c7014cf79bb4b7e6495930 Mon Sep 17 00:00:00 2001 From: Yasushi SHOJI Date: Thu, 15 Jan 2026 10:30:36 +0900 Subject: [PATCH 2136/3659] MAINTAINERS: Add Space Cubics Platforms entry Register Space Cubics on-board computer platforms in MAINTAINERS.yml. Mark the area as maintained, set yashi as maintainer, and scope it to boards/sc/. Add a short description for the platform group. Signed-off-by: Yasushi SHOJI --- MAINTAINERS.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index 900ae4da8ff6..cd048cc80659 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -4928,6 +4928,17 @@ Silabs SiM3U Platforms: description: >- SiM3U SoCs, dts files, and related drivers. Boards based on SiM3U SoCs. +Space Cubics Platforms: + status: maintained + maintainers: + - yashi + files: + - boards/sc/ + labels: + - "platform: Space Cubics" + description: >- + Space Cubics on-board computers (OBCs). + State machine framework: status: maintained maintainers: From f5f7bb44618f315d37e5c43b9061c1a6242f3e65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5vard=20Reierstad?= Date: Mon, 12 Jan 2026 12:47:38 +0100 Subject: [PATCH 2137/3659] Bluetooth: Host: Add bt_keys config flag MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds a flag `cfg_flags` to the `bt_keys` struct and a version field `cfg_version` in order to be able to detect configuration changes between firmware updates. This is needed because the `bt_keys` struct has fields which are compiled in depending on which Kconfig options are enabled, enabling the possibility of stored data being intepreted wrongly if the struct changes. Signed-off-by: Håvard Reierstad --- subsys/bluetooth/host/keys.c | 38 +++++++++++++++++++++++++++++++++++- subsys/bluetooth/host/keys.h | 10 ++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/subsys/bluetooth/host/keys.c b/subsys/bluetooth/host/keys.c index 0ab157599408..d7fc881eb81e 100644 --- a/subsys/bluetooth/host/keys.c +++ b/subsys/bluetooth/host/keys.c @@ -43,6 +43,18 @@ static struct bt_keys key_pool[CONFIG_BT_MAX_PAIRED]; #define BT_KEYS_STORAGE_LEN_COMPAT (BT_KEYS_STORAGE_LEN - sizeof(uint32_t)) +/* Configuration version used to detect if the device has configuration flags present in the stored + * keys. Shall be higher than the maximum value of the `enc_size` field (16). + */ +#define STORAGE_CFG_VERSION 17U +BUILD_ASSERT(STORAGE_CFG_VERSION <= UINT8_MAX, "STORAGE_CFG_VERSION is too large"); +/* Configuration flags for storage. Based on the bt_keys_cfg_flags enum. */ +#define STORAGE_CFG_FLAGS \ + ((IS_ENABLED(CONFIG_BT_SIGNING) ? BT_KEYS_CFG_SIGNING : 0) | \ + (IS_ENABLED(CONFIG_BT_SMP_SC_PAIR_ONLY) ? BT_KEYS_CFG_SC_PAIR_ONLY : 0) | \ + (IS_ENABLED(CONFIG_BT_KEYS_OVERWRITE_OLDEST) ? BT_KEYS_CFG_OVERWRITE_OLDEST : 0)) +BUILD_ASSERT(STORAGE_CFG_FLAGS < BIT(24), "STORAGE_CFG_FLAGS is too large"); + #if defined(CONFIG_BT_KEYS_OVERWRITE_OLDEST) static uint32_t aging_counter_val; static struct bt_keys *last_keys_updated; @@ -148,6 +160,8 @@ struct bt_keys *bt_keys_get_addr(uint8_t id, const bt_addr_le_t *addr) keys = &key_pool[first_free_slot]; keys->id = id; bt_addr_le_copy(&keys->addr, addr); + keys->cfg_version = STORAGE_CFG_VERSION; + sys_put_le24(STORAGE_CFG_FLAGS, keys->cfg_flags); #if defined(CONFIG_BT_KEYS_OVERWRITE_OLDEST) keys->aging_counter = ++aging_counter_val; last_keys_updated = keys; @@ -410,8 +424,19 @@ static int keys_set(const char *name, size_t len_rd, settings_read_cb read_cb, return -ENOMEM; } if (len != BT_KEYS_STORAGE_LEN) { - if (IS_ENABLED(CONFIG_BT_KEYS_OVERWRITE_OLDEST) && + if ((uint8_t)val[0] != (uint8_t)STORAGE_CFG_VERSION && len == BT_KEYS_STORAGE_LEN_COMPAT) { + /* This check migrates keys without configuration flags to the new format + * granted only the configuration version and flags are missing. Older keys + * are recognized by the first octet being the enc_size field. + */ + LOG_DBG("Keys for %s do not have configuration flags, adding automatically", + bt_addr_le_str(&addr)); + keys->cfg_version = STORAGE_CFG_VERSION; + sys_put_le24(STORAGE_CFG_FLAGS, keys->cfg_flags); + memcpy((char *)keys + offsetof(struct bt_keys, enc_size), val, len); + } else if (IS_ENABLED(CONFIG_BT_KEYS_OVERWRITE_OLDEST) && + len == BT_KEYS_STORAGE_LEN_COMPAT) { /* Load shorter structure for compatibility with old * records format with no counter. */ @@ -427,6 +452,17 @@ static int keys_set(const char *name, size_t len_rd, settings_read_cb read_cb, memcpy(keys->storage_start, val, len); } + /* Some Kconfig options can change the size of the keys structure. This check will clear + * the stored keys if the config flags are not matching between firmware updates. + */ + if ((keys->cfg_version != STORAGE_CFG_VERSION) || + (sys_get_le24(keys->cfg_flags) != STORAGE_CFG_FLAGS)) { + LOG_ERR("Stored keys for %s do not match current config flags or version", + bt_addr_le_str(&addr)); + bt_keys_clear(keys); + return -EINVAL; + } + /* As of Core v6.2, authenticated keys are only valid for OOB or LE SC pairing * methods. This check ensures that keys are valid if a device is updated from a * previous version that did not enforce this requirement. diff --git a/subsys/bluetooth/host/keys.h b/subsys/bluetooth/host/keys.h index ab83aff8ebf0..4fd0f38cb5d3 100644 --- a/subsys/bluetooth/host/keys.h +++ b/subsys/bluetooth/host/keys.h @@ -47,6 +47,13 @@ enum { BT_KEYS_OOB = BIT(5), }; +enum bt_keys_cfg_flags { + BT_KEYS_CFG_SIGNING = BIT(0), + BT_KEYS_CFG_SC_PAIR_ONLY = BIT(1), + BT_KEYS_CFG_OVERWRITE_OLDEST = BIT(2), + /* BIT(24) and higher: Invalid. See STORAGE_CFG_FLAGS. */ +}; + struct bt_ltk { uint8_t rand[8]; uint8_t ediv[2]; @@ -74,6 +81,9 @@ struct bt_keys { bt_addr_le_t addr; uint8_t state; uint8_t storage_start[0] __aligned(sizeof(void *)); + /* cfg_version and cfg_flags total 4 octets to maintain struct alignment */ + uint8_t cfg_version; + uint8_t cfg_flags[3]; uint8_t enc_size; uint8_t flags; uint16_t keys; From 96c4de16cac02454d9c3f76b0df4af19a93e0f4b Mon Sep 17 00:00:00 2001 From: Muhammed Asif Date: Sun, 21 Dec 2025 13:19:14 +0530 Subject: [PATCH 2138/3659] dts: arm: microchip: pic32cx_sg: Add dts node of watchdog - Add the watchdog node for pic32cx_sg device Signed-off-by: Muhammed Asif --- .../pic32c/pic32cx_sg/common/pic32cx_sg.dtsi | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/dts/arm/microchip/pic32c/pic32cx_sg/common/pic32cx_sg.dtsi b/dts/arm/microchip/pic32c/pic32cx_sg/common/pic32cx_sg.dtsi index b1eb97dabf74..8229fc230cf8 100644 --- a/dts/arm/microchip/pic32c/pic32cx_sg/common/pic32cx_sg.dtsi +++ b/dts/arm/microchip/pic32c/pic32cx_sg/common/pic32cx_sg.dtsi @@ -10,6 +10,10 @@ #include / { + aliases { + watchdog0 = &wdt; + }; + cpus { #address-cells = <1>; #size-cells = <0>; @@ -100,6 +104,20 @@ reg = <0x40000c00 0x400>; }; + wdt: watchdog@40002000 { + compatible = "microchip,wdt-g1"; + reg = <0x40002000 13>; + interrupts = <10 0>; + interrupt-names = "wdt-ew"; + clocks = <&mclkperiph CLOCK_MCHP_MCLKPERIPH_ID_APBA_WDT>; + clock-names = "mclk"; + max-installable-timeout-count = <1>; + max-timeout-window = <0x4000>; /* 16384 milliseconds */ + max-timeout-window-mode = <0x8000>; /* 32768 milliseconds */ + min-window-limit = <0x8>; /* 8 milliseconds */ + status = "disabled"; + }; + rtc: rtc@40002400 { compatible = "microchip,rtc-g1"; reg = <0x40002400 0x400>; From 7dc784a3f93dcfc07fb79022619b37f3cece9e1f Mon Sep 17 00:00:00 2001 From: Muhammed Asif Date: Sun, 21 Dec 2025 13:26:55 +0530 Subject: [PATCH 2139/3659] boards: microchip: pic32cx_sg41_cult: Add watchdog tag in board file - Add watchdog tag in the board yaml file section to allow CI run watchdog tests on this board. Signed-off-by: Muhammed Asif --- boards/microchip/pic32c/pic32cx_sg41_cult/pic32cx_sg41_cult.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/boards/microchip/pic32c/pic32cx_sg41_cult/pic32cx_sg41_cult.yaml b/boards/microchip/pic32c/pic32cx_sg41_cult/pic32cx_sg41_cult.yaml index 84620b22ed61..d6067284a172 100644 --- a/boards/microchip/pic32c/pic32cx_sg41_cult/pic32cx_sg41_cult.yaml +++ b/boards/microchip/pic32c/pic32cx_sg41_cult/pic32cx_sg41_cult.yaml @@ -22,4 +22,5 @@ supported: - reset - rtc - uart + - watchdog vendor: microchip From a207f0d8a8dbf21e884c3521f126915c7ea5fe7c Mon Sep 17 00:00:00 2001 From: Muhammed Asif Date: Mon, 22 Dec 2025 10:34:18 +0530 Subject: [PATCH 2140/3659] samples: drivers: watchdog: Adds pic32cx_sg41_cult board overlay file - Adds the overlay file for pic32cx_sg41_cult board for supporting watchdog sample application Signed-off-by: Muhammed Asif --- .../drivers/watchdog/boards/pic32cx_sg41_cult.overlay | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 samples/drivers/watchdog/boards/pic32cx_sg41_cult.overlay diff --git a/samples/drivers/watchdog/boards/pic32cx_sg41_cult.overlay b/samples/drivers/watchdog/boards/pic32cx_sg41_cult.overlay new file mode 100644 index 000000000000..9b49bee33ca7 --- /dev/null +++ b/samples/drivers/watchdog/boards/pic32cx_sg41_cult.overlay @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2026 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&wdt { + status = "okay"; +}; From c6b8d5c470b7421182eddf604a897d3ad5307fd5 Mon Sep 17 00:00:00 2001 From: Muhammed Asif Date: Sun, 21 Dec 2025 13:32:49 +0530 Subject: [PATCH 2141/3659] boards: microchip: pic32cx_sg61_cult: Add watchdog tag in board file - Add watchdog tag in the board yaml file section to allow CI run watchdog tests on this board. Signed-off-by: Muhammed Asif --- boards/microchip/pic32c/pic32cx_sg61_cult/pic32cx_sg61_cult.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/boards/microchip/pic32c/pic32cx_sg61_cult/pic32cx_sg61_cult.yaml b/boards/microchip/pic32c/pic32cx_sg61_cult/pic32cx_sg61_cult.yaml index e9f012d4e06a..92b919ca5a3d 100644 --- a/boards/microchip/pic32c/pic32cx_sg61_cult/pic32cx_sg61_cult.yaml +++ b/boards/microchip/pic32c/pic32cx_sg61_cult/pic32cx_sg61_cult.yaml @@ -22,4 +22,5 @@ supported: - reset - rtc - uart + - watchdog vendor: microchip From a6335e34e258873ca594509d299c3b31360b30bc Mon Sep 17 00:00:00 2001 From: Muhammed Asif Date: Mon, 22 Dec 2025 10:38:45 +0530 Subject: [PATCH 2142/3659] samples: drivers: watchdog: Adds pic32cx_sg61_cult board overlay file - Adds the overlay file for pic32cx_sg61_cult board for supporting watchdog sample application Signed-off-by: Muhammed Asif --- .../drivers/watchdog/boards/pic32cx_sg61_cult.overlay | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 samples/drivers/watchdog/boards/pic32cx_sg61_cult.overlay diff --git a/samples/drivers/watchdog/boards/pic32cx_sg61_cult.overlay b/samples/drivers/watchdog/boards/pic32cx_sg61_cult.overlay new file mode 100644 index 000000000000..9b49bee33ca7 --- /dev/null +++ b/samples/drivers/watchdog/boards/pic32cx_sg61_cult.overlay @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2026 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&wdt { + status = "okay"; +}; From d5317f5d4279f1f14a3bf1fe74901baebacd0c15 Mon Sep 17 00:00:00 2001 From: Farsin Nasar V A Date: Mon, 22 Dec 2025 12:18:09 +0530 Subject: [PATCH 2143/3659] tests: drivers: watchdog: Adds pic32cxsg test support files - Adds pic32cx_sg41_cult.overlay for wdt test projects. - Adds pic32cx_sg41_cult platform allow in testcase.yaml. - Adds wdt board specific configuration in main.c Signed-off-by: Farsin Nasar V A --- .../wdt_basic_api/boards/pic32cx_sg41_cult.overlay | 9 +++++++++ tests/drivers/watchdog/wdt_basic_api/testcase.yaml | 1 + .../wdt_error_cases/boards/pic32cx_sg41_cult.overlay | 9 +++++++++ tests/drivers/watchdog/wdt_error_cases/src/main.c | 3 ++- tests/drivers/watchdog/wdt_error_cases/testcase.yaml | 1 + 5 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 tests/drivers/watchdog/wdt_basic_api/boards/pic32cx_sg41_cult.overlay create mode 100644 tests/drivers/watchdog/wdt_error_cases/boards/pic32cx_sg41_cult.overlay diff --git a/tests/drivers/watchdog/wdt_basic_api/boards/pic32cx_sg41_cult.overlay b/tests/drivers/watchdog/wdt_basic_api/boards/pic32cx_sg41_cult.overlay new file mode 100644 index 000000000000..9b49bee33ca7 --- /dev/null +++ b/tests/drivers/watchdog/wdt_basic_api/boards/pic32cx_sg41_cult.overlay @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2026 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&wdt { + status = "okay"; +}; diff --git a/tests/drivers/watchdog/wdt_basic_api/testcase.yaml b/tests/drivers/watchdog/wdt_basic_api/testcase.yaml index 12c5021b6484..75cdc5da40e3 100644 --- a/tests/drivers/watchdog/wdt_basic_api/testcase.yaml +++ b/tests/drivers/watchdog/wdt_basic_api/testcase.yaml @@ -37,6 +37,7 @@ tests: - raytac_an54lq_db_15/nrf54l15/cpuapp/ns - frdm_mcxw23 - mcxw23_evk + - pic32cx_sg61_cult drivers.watchdog.stm32wwdg: filter: dt_compat_enabled("st,stm32-window-watchdog") or dt_compat_enabled("st,stm32-watchdog") extra_args: DTC_OVERLAY_FILE="boards/stm32_wwdg.overlay" diff --git a/tests/drivers/watchdog/wdt_error_cases/boards/pic32cx_sg41_cult.overlay b/tests/drivers/watchdog/wdt_error_cases/boards/pic32cx_sg41_cult.overlay new file mode 100644 index 000000000000..9b49bee33ca7 --- /dev/null +++ b/tests/drivers/watchdog/wdt_error_cases/boards/pic32cx_sg41_cult.overlay @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2026 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&wdt { + status = "okay"; +}; diff --git a/tests/drivers/watchdog/wdt_error_cases/src/main.c b/tests/drivers/watchdog/wdt_error_cases/src/main.c index 281e849354aa..a72a4353a1c7 100644 --- a/tests/drivers/watchdog/wdt_error_cases/src/main.c +++ b/tests/drivers/watchdog/wdt_error_cases/src/main.c @@ -70,7 +70,8 @@ #define MAX_INSTALLABLE_TIMEOUTS (1) #define WDT_WINDOW_MAX_ALLOWED (0x40001U) #define DEFAULT_OPTIONS (WDT_OPT_PAUSE_IN_SLEEP | WDT_OPT_PAUSE_HALTED_BY_DBG) -#elif defined(CONFIG_SOC_FAMILY_MICROCHIP_SAM_D5X_E5X) +#elif defined(CONFIG_SOC_FAMILY_MICROCHIP_SAM_D5X_E5X) || \ + defined(CONFIG_SOC_FAMILY_MICROCHIP_PIC32CX_SG) #define WDT_TEST_FLAGS \ (WDT_DISABLE_SUPPORTED | WDT_FLAG_RESET_SOC_SUPPORTED | \ WDT_FLAG_RESET_CPU_CORE_SUPPORTED | WDT_FLAG_ONLY_ONE_TIMEOUT_VALUE_SUPPORTED | \ diff --git a/tests/drivers/watchdog/wdt_error_cases/testcase.yaml b/tests/drivers/watchdog/wdt_error_cases/testcase.yaml index dd3ba54adc4c..61f5bd0da614 100644 --- a/tests/drivers/watchdog/wdt_error_cases/testcase.yaml +++ b/tests/drivers/watchdog/wdt_error_cases/testcase.yaml @@ -21,6 +21,7 @@ tests: - xg27_dk2602a - raytac_an54lq_db_15/nrf54l15/cpuapp - sam_e54_xpro + - pic32cx_sg41_cult integration_platforms: - nrf54l15dk/nrf54l15/cpuapp - ophelia4ev/nrf54l15/cpuapp From df32725c46856630988030ed221c2c1756c8234f Mon Sep 17 00:00:00 2001 From: cyliang tw Date: Thu, 8 Jan 2026 18:10:33 +0800 Subject: [PATCH 2144/3659] boards: nuvoton: add support for numaker m55m1 Add new development board numaker_gai_m55m1 for m55m1x series. Signed-off-by: cyliang tw --- .../Kconfig.numaker_gai_m55m1 | 8 ++ boards/nuvoton/numaker_gai_m55m1/board.cmake | 6 + boards/nuvoton/numaker_gai_m55m1/board.yml | 6 + .../numaker_gai_m55m1/doc/gai_m55m1.webp | Bin 0 -> 55666 bytes .../nuvoton/numaker_gai_m55m1/doc/index.rst | 88 +++++++++++++++ .../numaker_gai_m55m1-pinctrl.dtsi | 23 ++++ .../numaker_gai_m55m1/numaker_gai_m55m1.dts | 104 ++++++++++++++++++ .../numaker_gai_m55m1/numaker_gai_m55m1.yaml | 16 +++ .../numaker_gai_m55m1_defconfig | 15 +++ .../numaker_gai_m55m1/support/openocd.cfg | 2 + west.yml | 2 +- 11 files changed, 269 insertions(+), 1 deletion(-) create mode 100644 boards/nuvoton/numaker_gai_m55m1/Kconfig.numaker_gai_m55m1 create mode 100644 boards/nuvoton/numaker_gai_m55m1/board.cmake create mode 100644 boards/nuvoton/numaker_gai_m55m1/board.yml create mode 100644 boards/nuvoton/numaker_gai_m55m1/doc/gai_m55m1.webp create mode 100644 boards/nuvoton/numaker_gai_m55m1/doc/index.rst create mode 100644 boards/nuvoton/numaker_gai_m55m1/numaker_gai_m55m1-pinctrl.dtsi create mode 100644 boards/nuvoton/numaker_gai_m55m1/numaker_gai_m55m1.dts create mode 100644 boards/nuvoton/numaker_gai_m55m1/numaker_gai_m55m1.yaml create mode 100644 boards/nuvoton/numaker_gai_m55m1/numaker_gai_m55m1_defconfig create mode 100644 boards/nuvoton/numaker_gai_m55m1/support/openocd.cfg diff --git a/boards/nuvoton/numaker_gai_m55m1/Kconfig.numaker_gai_m55m1 b/boards/nuvoton/numaker_gai_m55m1/Kconfig.numaker_gai_m55m1 new file mode 100644 index 000000000000..eb944229d642 --- /dev/null +++ b/boards/nuvoton/numaker_gai_m55m1/Kconfig.numaker_gai_m55m1 @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# Nuvoton NuMaker NUGESTUREAI M55M1 board configuration +# +# Copyright (c) 2026 Nuvoton Technology Corporation. + +config BOARD_NUMAKER_GAI_M55M1 + select SOC_M55M1XXX diff --git a/boards/nuvoton/numaker_gai_m55m1/board.cmake b/boards/nuvoton/numaker_gai_m55m1/board.cmake new file mode 100644 index 000000000000..834a265466e1 --- /dev/null +++ b/boards/nuvoton/numaker_gai_m55m1/board.cmake @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(pyocd "--target=m55m1h2ljae") + +include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake) +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) diff --git a/boards/nuvoton/numaker_gai_m55m1/board.yml b/boards/nuvoton/numaker_gai_m55m1/board.yml new file mode 100644 index 000000000000..4c87158715c9 --- /dev/null +++ b/boards/nuvoton/numaker_gai_m55m1/board.yml @@ -0,0 +1,6 @@ +board: + name: numaker_gai_m55m1 + full_name: NUMAKER NUGESTUREAI M55M1 + vendor: nuvoton + socs: + - name: m55m1xxx diff --git a/boards/nuvoton/numaker_gai_m55m1/doc/gai_m55m1.webp b/boards/nuvoton/numaker_gai_m55m1/doc/gai_m55m1.webp new file mode 100644 index 0000000000000000000000000000000000000000..df06076e5d2d5a77dea51648942841d8355d2741 GIT binary patch literal 55666 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

    c9TYvu-E+pG6tuk#V=NJ0)K z1Pr?12z^SjIBFuK?Jz z7OV%V2ADPj57JoMG}Vqxa0oUkemD7vh~xWvH`UdT40I{Rt&noO_2BBl2^BY0b1vN# zI6?RGY5Xfg^Qs7Ivw=H<@oG=iwWf2Xn4$hSh=fUY5v!2pgy&PQ2V+RGlCDZ{iMQe{ z(=q<82q8+p`5SO5-$IT~m0*g-WYK$GUrB8IwP7J1QxMj0r}Fi?VqV>T_dPHchO1yx zc3*TMX6`z$gwYg)X5!z-r5)L^+1P}GLF&T1MW$w*iX=P%D6$e^-Oi8yMfqHZscXDpidx0o%#%_fR?x|g)72+U|svBW=NxJ8oq6T{} z<^c757Z>=ZvYo7>05<0EF%jOmksT*g3KU=BTSaiHxkkKoLYsslxzSIFoWnw0G-qZd z!|=Eds~TSv4c?YNnCG`tKxa9mbm|EPPn`ZP{}#snWA0BzSRi%lz-Tu27YWDm^Mmgc zq3Q<_2_5U(JoB#nEsoX<8Y6ymFJdhC?^LDL*(VGwW(FT-_b@gu)oHrRW}5}knlxtbOPkZfTRZ+?gbWBeG$`R;c)man7~!-@ z=HGo<8H0@&E=I@11#Cb}j9U0SM&k5mw(GlbY;>F_stchWqrvd!w2q#EV?>?)?yA*y zvIqJfdCn?|iap&#US(rAEG!JGqvul`*iWIfoa~%6MBF$TNh^yDNdwLYjwOB`(Uo-b zpTaA!SO9N^tWu)%35F=Aa|$3#AoF`go6+*thR%@ux5bc$%1WSYi>QD`|5)=; z^pd_Gx3#rCs*rt|DSD74y_<&h#;yQF*FX-y{mWK3esUFJEbCt95|qOpf7kJW3-~W` z)40g&UWfes`4R`%cDyxSom!Fh#7O{{tpz&Acpb`mcij3%NftMBW7YWmQZeCu6$QOf zWdWCmCqMdGdMjJH6tld_jp!Q~)tX^(k=Q@R9M!`x@MyZ%uf*WE_`X$d`!sW8;Spuh zk0eOClXvZ(I(y$d=e5ep^FygPHOKfHY)&%oatJ=3d0tzx0c3C;!N^sh`AlwCAnL|7 zD<9M!G%B2?eQMq`#3<&@Mdm)9EhsA!kWo$(AjtDg=lU#I9l+6^9t5WKjWX4V-;c@o zZ+{A9<-H9>VOIHiK%25SA2ZDSv@@L6Wd7-35!2J+I|bu%0$ScQ?(>e3F36( zz_P|KraE6=+3XP|CISB}(oWUD&R>?v+As9xi{jcKKv_0R^P$BSSE;aJ;vv!)l6KNM zZvjj_>=dKi;xarL4 zI?cUGYh*FR=1Z4QZ-?aJHaHlHp1ok)4bg8A)1&eLBZv=tt{+;epK2Es>BpYHRz^Gv zCVC8ZS>$ZJS4ZQ#*KxV{$<8@0|Kz}MF0r-9G{sNvpj&$_b~iZ4b8YW_5j$0!rAmRr zgS~k%G)IcsdG@U8L5vPqdOW5|`{L}0L^O;z6eD=VNqHoT zn7<@vZdG${wAhBe3cCGQ2uFU<8?w8RYO{9yHH&XXf@B{X{Yp182L^uqmp236_BAHF+<2Q{Y#5Zt!cpX0#b7>4_0j_sfUGdF?(C6NZgnJG|q5vLpc zm8-9V*>7K+xYyAN+`^0j1XSO7KdU%X7)(*T5s14)a#(wlr^?Dw#nE7_>42{IW~&WY z*WNF^E=wAXUiGa6nKBKkpJf_omZA;jE2HJZ}pI;E&>z<1cRCqZV9)+-gjo}p|XD<2M5 zjHDv^z|a>{;;9qnz+klFGHxEjL>*bnK8`spjwGi zV6AK8268p{Wf$G0qo*&T>NwfNNEbHkV9t6U48bjwq~~r(#;tgbjEu9yNBtITPeJ=x z5E_<$xYrt^jhfbK1ZyF`@Lsptm)XnD-CEVPbfxb z5o^`+R0S}Adfc6^Om@Oh(}Ov(oYOTNJAiGN)`NukG?at(&7gjq6^& z@eI-3zoN1))CCg>9EyJw0lVTIj7UqT%$vTS60d+3{O?@{#B*CPngv^Gur@?J0eW-9 zQVyu>6sgGHZ5W(Gd^J7r@9$zK@oyovNZnl6#8FH2bB`70p484thEuxN!0nX1!H7hJ z#yU{!cIvHPDDcDhEo{ZlfH;qV(sE3sp60>Z5h?^sU&6nK$Jo47j7peKzgqZ4lc&9_gs&1r)SuASG7Rx@&ww5H z2buI+B-bp;AUgwnncWg245N2j3r3}J)h)yzHjB|Pmdy0Vfcojj(K@dOt?2CIcTPMX z*Kb2qHSh#$2i2d;QwiJ;PcQ%ZNsWp=^_NXHz9nj{Rf=qz$%w!ce(rkm0D@F;?lIO? z)6!eOiDzePH>LndLG)k2Ll~j(Ld`4L?-GKqFR9zq)&+DUzw(I}MD}pW!>D)b{y8&X z-InBr*;txtonIiAt*>uuu{YgVs|$4q-^*Uzg5$a}@aCcU&lj=2l0+m^$^Y|LY(wFr z)~h_o+1lsCySw;~7YDA0yCGy1@6rI3-ZpyHZ7BObhNn{*Stf{syp(*?q0M6-n50(? zPLn$*6GY)+3u_#hL}kY;o+rC0VvBh-ymX%Im0@_xunH8O>O_g}yr3KQyH{^sPX}3Q zoa`+up|L{4296cr={5ecToGo$Z9-0=xeY!_>HF|0!mTE;vzX#P%^+QeJKI+l0kq9;`Xug4sKd7r9*emoKL8+B;OJq!}nKzq}GXZ)PHqy|4@8WRQ7`wD3QCuo_bV zzko>Dq-6$jcvAyDf8s=VlvXbC$f?Z}AF(n8epxr;`V4=vyrHS)K!bob%~AN!*0!HA zZ@Lz^&c7xN?ncjEX<0?J2{I&XX}4H*l(UxaGpdccHN^G8Ef9sX%5p6ydU^A>DUXbg zn&0q?TtkCMjDKXC%f7sni;E2qOvpe|a9%8gl~HqJsI`(a+idKkhd`H3su%p&CKzVr|TVNVwkuq6)|$lCjTVG7_0xU}1~Htt@?VMm?akND@4A>SHxe=DwsE)k^M9;*5 z@@K|Z_|ZKqXsWGef|N~Dg4OdAB`@U=9nX_(TiH^tLoyx4Q*Q@nswhlQK$ zNo#t3rKV701omD9d|#99zDuCTpURC|eGv3vksV&PamGkHhOG^D4tTBOZmT5mf7thb zHgMSOgORY)v9EURK4uNJ(o1Czu4`h`*}|;|yjPi=*%V%3!!?JFbpnH9gA`CeZvOU{ zNayFa9qdi6X>gX*m#xx5v@*|j(piPk^0983XQ(>{QN`C0D&7gcE)+I}N!uY9+Xm~D zXVmyHRuj6fuTHq-EobUh4aBJ-)z;nLi&2ioXlLS&Hcg|L>+v@h>8f zHPSpdcj({(q(sFWy{=|~rXOaixy@EJY+biuRG^ZM|XA0cFBQ}tt=lmmbs7cj&u(RsrPFOR&e9_-M44UZ2SACCo&Bi z8KDUbsx*i-DfnMmM`i*B+`aj!NJS^Mn>@Z&ork=>|KIt)&f|Q@O^QVuwImOnaS{9( zc*g2-=McO4_4hBXpmhw>Oo1v+>w&x^ZCb8}m|TH$phGGc{UYL5q%m&#b%&I#Yt+5O zXh*8FIa&@LBJ5eSyg>h`5L)oLI5?9d8q+`3=QUex+j_Q7-{+B0t2J&^)}&9}!ez*( z%Ww@-Lpf{>0ISWAFW*Z1gOjv0F>H>$&1ih$1?p#+MpsA{9*K)G`vX0R7+*eBnRDkK z5(+s@J{3#k^g|3^fp8if_YQ&Fa-2onXpd-YRoWRHVHllBZOUso&Q4|Mg+GrEJ$fcC z5+Wdmgid_L2B4>kn>m0%Jz_K?hS$@kB*zp+Z zPoM_+OyFm$y2$3H9gpX0RXd6x7Booc(YJD@*diksgVAv4YRU>X$!oc}7V)xz=D61w z5y_!-4kC|}F^jeb^64ONTVQjR2Oa|wpaVzBe=UiolJC1q2|zEU!}rgD&8W3d+W6_+ zgyL{s>2N1=U1?o)FW@}Kujr)?q@}FFP9R&iv`CZbIPoF5 zmzk>z+`a=~M$&Nho`Qjps+5*kyv(s3)e2mTian@B=H zMb&9tt(*~ryV*3*IC<)$gswcoO0`cG7K4(`S?SswfE6b1$^NR$9Yw_!Tg2(}CMom5 z8%d^mu}?y2$Vr@3QVu2L3oDWj1?EopBL+QOjyw22q)GB-mnQc%3UOrrDixwyNBm{` zFS6}Meh{in0m1&2^p?>p74S>X-%;0oY9xbW5QS~%I7NWK>ThfS)y(;zuWB#p25}=d zZ163XKtjjJbnw~arzk1Nkoopnjke$yoa%Xvj9)KVcHuj6cLKN(z9=aZI3-!dxL=$H z))kRuaq-`^>*7pdNgZ?GPbk+Rap`eVZ>M3|dQR1nQyd>AcbDm{SG^4U;OL_dsP%hi z@*GV+;#+SykOXmZ;ZUhrwt57zsCHOTk*y%5u;fh6PQ8^+R}J5yklFpsx}$SdYt+C4 zdI}9=XJ9Z8t`+*%e=yNhCYr9pO2vH@7AfEbeJa$eIlEv17r;d%sy$is25!dx_b~5L zNqfrD0_)Aq3^`M`L#x%5XC)ngboZF(lBn|;_4~--F4&Z}V^rr#K7N5t2`xWvzYw39 zobR>!!lPAYbUHAkV1JAFq(>BhqFpvIx16gtt=1tH(V8)N%>6@@=5OCzsM~~KH{7Wg zuBp1WTM&AlfS&)H#NC|j>Vjt(73J(xY!3W@_hAQslt+{G{r%5t9TXy4@vzXlCIlzK zfm-GA761E$OxQ_U?GGJxY4&uT$-Wa#@3&V4d>0l3!_qcPboAtu-O$9{8cz9eOYxED z|JM#ynBwl27m@;)*<&P-u&H&)9T*2AmH4E5P@x!jdyY+vSJpGN9P%_JIs(7{=-;LNsY;2YlA*< zd&w)>mknntdG26;pU@E043=v(mcZ2&C%ldTbGnUdf|vq#(B+*Fwrj%C<$_!kq@(05 z2)smZ^o!{e&xSOmls0?RljxtKe+K304TAUkb^so^q7wl^TXwKOVXGowrRv|_EaaAS zg-O~UQ`3lfQ(j%(`F25x4mv(h2NWTzRz1lmq}&&MbsX-OU*~13YQ{`sHS5475L$L1 zRGwIU`lkWC|B480f`0qjtbbaLmVIVjMlZt4>W7m@pp9ND8;=n-@leSh*9;0K*4MM- zB$zx~tLKGMp;PSP&%=L?v%k&(ocjA5Hq=JaoaZ^|mpV~kp;~>Kxh*b`n!foRflX%Y zJk9&#Gz%ZAv@=2dY(^&chY;jv>#P%4D=I;WK)Zb@`)dC#YAJ z0{&bN1edp)i!EG`cjhGLMOspGfgYCQ2`XKYVAK*|{6obM)>yh<=1(;2h!`vUJewOI z)7kPsOUA=ZYI1XgVgXx~>*e8%$LX&IH_zrxg2~YN;&w%X5>p@z&bFI;D@&e`bIvPJGI38rvC{Cwst66bZmFF$xZmZQP+XLrSiI>fjl z@Re2|NSW%SBtJ@~Y(0Oa4{aHxgw{fH^1G>#9HwRe7Wyjl$*TUFMn3EfaY-Q2P@YAS zggT(!uoEg@ZlxxGiV_E8%SQ5w3i8&=SK$Z8ap?!;lq1q@n+x*6k>ul8U!W{w60rfO zo#a6O(`pK@MH`DIbm&gyMKeDSmpMz72L~_K5I}RncjG`1xhN4yWu1mAMR9l!wxUUG4GAQEVwLM1i@nx^^0Zk?C$l+zaUI&j z=888l>UCMVnZ~yU=N+o7A<2>%tA!{@MjHbM`O~STw*6M^nLqG5s9%r_1rR95)P>fE zza?t6fMv+ju$E+}*GoUimPyyQbs2k7cZdThy-ieH##{1e0?kBIS+Bm9U4k9~m%HR8 z1xxPl@larDfpJf<3nW`J*7ia3J6OGxrn#e>dF60R)+!2zSqwf`mDqbta-Ju%^N*NG>(2-!VpCyZOs*XA%! zK;1B_1X9?7mCh-%suK7`TD`xyk<#ZoB} zN!`r~o%dxyAL}P;W1T>@VQ-Oe$xB>#7(OH zqx)U}u+lddu;EFq9U9sOqU$gpdL&_F=(0gGs8K7f!R2hIr9FrSn1zKotIb09?y)bs1xR%orm+% zqwX4YXG-W3H`rFg^(EjHE4ck>-70q8xU8u*DF@`Mry^3%3Dl8o5RK)J#-BO@a(lQgIaD%z}_p zwNcRQ2!C~JnqK5`~%)qUH%HcZc`1@-MT}?`c%Y@RT zq&_a;w&iuHf5aV;P`loj-ou2Ao;J1%MNVTg7GSSsqq1Q|=N$&njI$cp7ua$z@rZ7q z6!4XLGQ;ZOJJ|n= z9zO0H(*VBTcz~wYO0L4j}?GH z<&|CF1R5=q$1|cDT4BS_W_Tyf>=?d@O*6j%0}oFd}Rw_q(oqZX}x{&12t9_d%GYw6n8o6wMA&DGJAp?r~Tr-%5$|qhV%(Zu0UfJHojNO@ozW$)ll&*Y065vtoQ=!*$<9?@;xtgSS zGn>?&oV*}s7vAoYPN#Im7w0Djcwa1^rdg0MyC8Bv?!AH3xrpCq3XyW~PoRy?s~Obm z=-+ec!|V!DqEy?#!6SL08Nh`l?C>!+;PJp1#oL1Aa*N5PZ!?u=?ruI3iQeqE?=?F& z!tX$Ubmovw?T*%k;q(c=#}84%1l^vEZNS`_hRVrh2kf4|_bOM4V#-a|T4&RqDL=VrTpn=LsNib9M+WF^ z^}~e=Osdi4TxJE81fKO;0+#w-9*#y`5UcOr3wy`&B`8M`h$HXK^Ppv{Q zcPT?{eJ}M)G^C3mc9?^iO9FZ}?i?qie?G+C9znjBb{Z@LSokD>1oMSf#pdr@f)xJc z-AD8rKcT`voGD;c6-M|La(FXC)ylXjmIylZ`VB}X5|Y*CV~s6&V_N{)?oL?Suf8=} zDawxgQ_e}5>R+P=@^s9kibtt{?(|>IEl7~>;(v{;DpEI+imG*atka2_kh-({q!TmX zro96GG(u!`GY}s)Iq#q-wX?cx<1|hr6|^b{e>H-vH*ROyJTp#O6UuzDZ4DG0+vss# znmibI-zgI<8Y=1R0<9uW15sE~EmRn^=+i8GMhr3qn0Q6k!wljHjcjt+JrTK;h%Bwx z1z{el+A8#~D}BcwOTOLxE+;WE1He5Ub4DL4`mY6`F`nuE#+#E2SNhWd=Qe=HUi(-a zvi346+x{Zkb6v>8jJf$-*CEuLI5zWl~&WYN{%xh%wIeav*DbvI9eJz zu0F)0Ca80Vq55tzn?dNBmZyCr4uUNVC&<7TKDw(+!l#bpgCCWL*8GeZjzlW;MJq;h z=B5o@Uxd(1r2VU84uS_blfUNkiCUoIA6Lhf{|psEQ5i(L`(6JGchvf*l0ibCy)Jx? z9?*o_to&w3l4zud0K-HX0?0=&jo3uzuKp8aqx(HVsD*rDB6_g;o7w zP@*??@$?Zwxrhu0NJUVlAXrd1;#u^qIkJ_K45crhWk7TuR5vh#g(z)Hj3mR;ikfmN zR1{%uABWL}J2(}i3RA=Q_#dQF1d_{#^$Rq6N6L}-QxNDd0=?1*E>*g`u|maGJh9q& zkYq9-BMSd(q!wL=X4I{U7-DZ}i|4&yAueW;G8!<^1DLPei!t=v-qub+(VGvjCDj!n znt&q;iXvbN+MDl0{{gGjfE(XnxGCwd+3yIizAHpw{mO;Ro%J}nO8-w$OMqtWnP zSJB4s)(s_6BT7E*%0!%UZ6$9P+4Z^lXDEcqjLgRhzmMx%{s(#;myUFhH7c(DrA5YT z@f&WC?niI}gP2Z>pm$V;T+Y?20PL!y^Njt1wnFWd)RM7a#SOojX-XL-M_cLs&(@|k ztn2wcScaT9^(DtnkV~mf;gu?kldmR8BGIJ8hsn*FYwe(XrG1%47QWLVa zRtQ4SRNwDd7b zKLWNJVqZgH$2$n`^IaG>ERcNNk_x$i*IUq|i19^*wchuZ>@U+8l*vW|z1OmY^IHhQE zIJa!0|!8X~v)g#YMrF{4d$z;*alLemz z1z215$jm!0kZP(mHsl?g&KQNl#_b+;3ZvDiY1@RvJrWhxS7P~zpdzg|zF!32C z{B^ZkPoIj%9EW0tm`uVW&L13z{zYzbH;#2;WN9)CccH;pUo;gUVVnh0&GXJ;tK-Ni z(vkr%PCqHb&vN^(FTLON)Zq|JHTICTLUr2R=oN8eWm-X}7f@D>>L5Ky>^lsJ_uW1o zUtMVSgW*->Td%1vsc&d-zasC_P-I!3II~b9!<6M$NU&5U zRy@SY{MA11x!Qw$|1%I^KXoEq@-amlKB#Fd5BJ++!O>6k6Xp4qXlE~7R8+p=gdY6} z$|#Ggcdxtoe|97r3Gu{N=&lhad7FD6gvmDVG84-myw;k zSpNY+mUJyW9q*Z3b1Q8*&7-A2-l|{p?kf^PSa`>MWoGO3PFWCkGB5i{VvYe>CP>$} zNf5)mA@}rHx_gGIWUlD@NqCh-C#ScQ{!34jNw=$wO?f!=##w}MIX%`1**|RoQ&*%{ zaL{cq{cx`~G0XI12wx`(G4WL4W{A4hlwI`4|Ym|t49)Oj3r(2`pKt?>8ofk||h}GjNp3ZDnzLlvt z8T!;1{%_4-;Avf7XED}kIhS(YwY=0%SWaO|F*8yCb7S<SI?qKo}<>N!<|q z-oS!yB-vO*iCr7%$%_r6J*Frq&!TfR>xf_F4=lK~h0t+<5!c~la=igc=$*GCB%4dd z<2&#D{M3@DHXf!}gi&j#n)gb7ZM-)s^^|ENM(`2FB|B?w=uR42)2BEa2!>vvNj76* zHZ8?Jh6j=QsLn75FU?X@IU`302U|5T+x!73TTs~>g{n_#*#Fo79dD1&SB7>7HgD+T z1&t58XOfc9jHzZTPCp9k#ZREL@YfzKo^woK?P!WUb9eE}ErShloT`vknQehuf9yo^ zs~`ESL0{>2Zzn@bcPdl=LK%`(ml|n}2mO!Jr-0n83enO;>iAA2t&HlZO{Tw`8N z;CLB^uWC~wC+cqJVWgKyuFcXn- zSTsv=s(ClLXn??noKQI4yzhJfp8qn-hSf^WY0QR5%%Vuew6XZ4E9#8*`7I#K!UoTp%#FYn`tV%xCfa!wQhSaX=!;z3 z1zXd)$Uk7P<8+}{ua4HykUS>lmX}a_KA7vr7;a=<)^l*wf}uf!Eu{>&VZ|!Z(TBDd z=??Rz#8L%ZEipr?q+1zae8e@Ae!%KJd?)_$!gW{j_V0QD-mZ33W zc4S+7EhO1^SE7X$I2Sx1^+4JfV#V3R*P(@GrF-{qmlepS7zM2`9N$lab25#VG47Hm>*7jlIobU~<=IwPlSIsX1tqxI$s6%2&-hr@9Z|+V zZY|4{CNv2@ym#~w#H(`mZr{mPy?){@8xGZsIn(g!g4uNzwvp(2rHnff(AE!hF<1!| zum9Lbs~rxxqP6#g3jyXB8RuQ31PxCNz|6ba@H2CH1e*`HCHHOYgMuly4OZELh>mBt zGG0>=v(vhp79agoPLBYzMvQGxf}*Fp3iBO1P)owJu_$qUBjnI{VXPSsbM51cwY>HP zMt&SzBfmD?Vzu+_Rj4z4g<4bE4WRhMv}iH_*0!&^rREqZF4db~{`8Hmk-p=a73@+5 zCya8zqabw`x;B$q8g_!uBrYlK6g(x1lO-uzE}_e78}$|xl+q4Md_WN!AGVE_L1Dyc zwMWa1PNEMpzWd%Le2NnmVEZd<0;2~U*GH^KIGn+LFDi{^!E4ecpL*!My)08TYYNjnhh#oNo!dZc|vjks=PplLoE;^i=bn&|I z=|sVxe><99WOcx$W~|+v&|w&x#4e|JXlMm2*vjJ{`c^BY6aw@hB&%!fodU<-C%z9M zEKAlA3O;$}~~rbB0W#W1C*iFS*QtX~+<$XB3| z!cS6d`QxrWIE;m@Hx;MP{k>cnk7I`JepM$#2qeFqvynzcYL2E}tk{f1m!*t^B2w+2 zohTz>hnSc>xkDn3n8%2b97q*`?gzI|AF33gn802->D_MIT6;x!a!hyM%DPnHHGXyv z-`gbzo+nV*1ac1o-A*w8BK2R&gwO`}pj-_e3Rc;()YfU97v;N5umZJv?$TGac^m8J z;SGc=0A@*Ie^(Y5!oz?zY6y9ycOHZT)hne>c@fGifyQ8wJ7xX zTbJ-*>u%4iG?10|P3ZS7A(ui;o36i!%1Y|*ffVM3JBp$Twqpn6rlc*s-Oe*PJ=6R> zhoqILOlsiyBBWVPyJx74y!-rPDH_p_*tsLbw5S@9Bvz{Jd*P!)3HU1xA3z{~aXa-E z+yz^F4=X0ti6Iu>)IA>>lH)RlX2BkbCo1(@uaj$bq4<4^%FFAX0a}Nr@m2ouvrnUI ztA8$M;okaw1NX_TOZiDWmX;CUsmRn)ZN}n50YAlXfs$0nQ2HSQVnw$3ANEXO%h#*- z2(v1ys?K>%4KC-8wZd3K&uZ zglfQiJ$6xNEsim8!O}cq6(7;|CC5c^=Uw`z3aJI-d_=elktb*Qa0=fXK4Bq_AK5Dy#VO+B2fptjSP;xg+ zdQLT64w4ZASq>v}yHZgyDq8!DRuHp?gi!C=uTh6@QO?&qi#Z!d>E!7;gTW95i}9D?an&OU%}+pSXVeO?j0-2Zrg;><3~)teyy?>(8!;&TM2%EnK2sQGF_B zDlW8r^X(kpLKcy!Y&8GOE*wDl7d9A^G13I>`S{+kT(nO31p#aU+4DaO2*8lF@lmw2 zIqlRkuLQeTMu7g5-q|QxtUpRa4o96IXhs+q*T7WhiL13HmK&Qdqov0RNKe6rk$>v! z@tM}uPcWpsiMHBFO`X*8`{+R)@O_N?xy#A3_y_AR+EO9R)A#RVg%LUAAG-xuZ_Vsn zN%Dx|L1A^rCe0AQxxTnpVb$_cCe6S?=ZIlhq`(@xwK26aVxWOfN%}$+Op8j^LuA}E z{O(`86mBx;T2r*rTJJQz9R5JQgRq+WHJmWHKg-tjrgUNnGU@OxH}hTMfLCvpa52$G zn__@eh3NX+nKh|Ld$8fP-ysi8U<3n!{2K)|$Rj$R&_CC}AFHFe7*Y#*dsrVazBJIo z{ReOUt+>+HX&8@p3T%LuSjGkb-?0lfR!HgZ8f#A3G)eSye{qBcv^)R|(sMY7d-84W z?8)v;_y9Yi`zpmnIV$FDrAw&B$GoxC9cXgzy4o$>xxseWdX==%%*jU`0HhEnZddp| zFIzhl5S?Sb>=2Zrni4vVISm~1#x7ky0{!onn$+dyB~YCJ$Bx+rT!xm-&n+_X`@sYI zh%$lu3*_r`b{9}U^@8<(v5b=|hvMKqq(qNLhC@Ph+V%6V7_#?q(?8VI;T?g%wp!Yb zS;FTp+^wGsycjs0w|ElEdBE-e|4yf2>eP%6m(+%j&r-c|_Jv>QW|HsY6?{yX)9V@n zV*BA*Gd=M9En0a7@$EC_5=Pb41rsl%eke0n;fcwDq)V%vb@kBA{n|%Ql^ijswgx7N zTX`=q-pMc4vLXUt!g{0fbNs36x^KadBT1P}^d8f)g#qcod)WxIo}P@VEg0+8^ERC~ zmt?5nrii=x5K*+X_cxJsp5N1x;3zvd7dXGphB+sHxV{5g)g_nnI@K@J99=%(3Vg*Y zP7fNZOWF5n+t~f+G{eD=J|9*JpoL^ovqEq)BvN0!+Xo=~;I$0tWD-HZxA31pVXrW1 z4xAxQiw|{700O9xfmuioc&U(0bka_pG`kg+Kt0< zA!q*6$4b9@d4W=r-QN;k%}NQ%bdFutbj3u(gx*MipI5n=ITWiw`8(~afEj{V?dVaC z_ZM&$_b`Q`ve#T(#0$jvOEv6LaH&?>T98dvg`~F*`olU|Y2Bwmj;@P3ABB20s`c1Q z@2FDUw83S%%hMlYviH4?o~aHxb4uA4iQM?|q*=`%`pVT?2m;@YZjX|jIclm3ce8T7 z8a$3S$tQZp^E`{HfOW0?vi()W6f4l&OdO@?xhH#gCrh!w1S+zO*kMbr(wODE_h3o5 zIpk1~)#&E|C@+}AbFz0yd&PCH)<^lNPkb4wP-!`**B(1s!v%UKQ=L;AChP3`q0MCRw=ddZANU5KiIA#jS zWq3q~FT=f!q{yCPXuW(=5`$|ed?ff?4?Hl$A`_|j9?xbuF1sfx&}2X2s^YF@Tp@Wq zsDgbd%4o6f)%7n1qN@8>)(k%45B_;Ib&+nvzpLC|;H@;gYNa&Hd(3N;t#et+JNKcM z>p#lAF;^=g>9Av&li>ClvspH51M{%$Y%gS&?jpUXqJJ%IDbxnQ(3jjnm#YufkIe2@ zk5*b#U^|t9WjEopYDx7E7M?1Jy%Do0uDxl^sQW8ILnz|U#0sZ3Gx!By-^k!@M1} z3{i%6BB|Q}8sYnFHmmINn#uq-pzC3=^j`(GSeWs&Bp)*GR<=-Zx}KPpKgWMNYYwHY zO=|5GeQklO|1KFh%;6PGU8MJl`oKl%v$3eeFOeE1Aa6>6b(4FPm%tE{ zr96cYLix`Sy!nAtP#4??3=4CtIP=mJ?-W@&pPqKp!)v zG@H({zT!nlCDVc)rn8eO+$#3NNlI}Ytmj${CGHZXbUEg)V|MSP=scPBO~RD&)2_$| zL@4{%Gx+y02vTb%csvYx7T0ACO(|CqRzqahFe?uA9QDAKSn2(`G!=3jN@0AmZ`^ng z9(Oi_1+W(q_|XlcfKStPZ*b8tE!ochG!y?+El4zu^EZivlofZg3A^2pYp%O9j`1() zTbRk@w2MtD#$T-(K9Ga5ZG*IL@Hejxo&pbef}p;-jQ#vnXqbh)HdMHKUr5y2>lv4@A=5rhd}5V1;* zypL#II|yxFnVw;P3kw>r9m0ZgL??gP?+OKg$nKTdODl?wfX;4uP5eq$dZxQkYo+1o zY#hkk$2uAfYu6ZwAqg0P7r77dr%?H%T@?Flpq0nxX|v=I`~RRrBb`o(1zNSB*-6zK zLP2~5U-Mq@L+xN}t<=`~OQ9pAJBCvA4$ zy@R9{aVb|oevjF7($9{svv3>f=1kLr1SUVP|Jmh!4sx!$UPBSrTVM(y%&YXe6+);L z(AejXSvmeaM=X6|9J}2`xirUaz@;_AUQ=wW4 ztvBd{rKI3fb#YUjkT>8F-s#Nuh<_R$QVH5e|dYVZuTS(oR0-k8i z?qIYQ)&%lel=z0v3P##d{DCi5ihccW2ekUrxK3*=8ud0uvW;{G(p{9(Eygq?PO1G? z4d4+Lsd+SL7$mMZrc;dBGdNu2_sszvIB42vdlqG zSAeMJf`l8mJoWnJfVJl-Z7ot2is&EB-lhfXcDAmjJg&ac_Q6+5$4mRtwx{jLE4$sd zH?aIM2#**3s)WEXdkMST*ww{Cw6v2H;M44bwH8*mjnvi;k;RfIuW?==yqC9Pi~Zdg z`&{&Z`u}H6l1Z$J^bCL26K) z?>6neDjo;HD40!x8xzvf+u@XwqIofl>{Jla1LZvP?OeF*4>AKFrY4?F0*O{Q%%4pW zPEA!I>N~&WL0!bxCK9cl%ws{vH}E|QthDP&8J+Lrj#o8LJ!fPcD;FFoOV|1Jh|NeV zdTlw{ZiJ>r@d1{Q7^&UxbCVHaKS;7lU2sxvgXc6SZCL7LLQZ2>^pEf#NS5!foxmVj z9P|yM8$S8?779-2hkDJh1l#-$9~e$qtqD)Pu=NKL z*W9sa?s3VyaSUMwf^Hle4A7b%ps$J(T*GMHvM0rUwmim;Y{>OwgE=!Ff+~FBf*ooC z52#{W9pHHpR8{$4y^fWK;ofHaGvG3u)X1;x%xuq(!1;V;9MZ^3^xj?13MFvOA=irr z_k;nR`?6LZl3kk;mTp#geK>XIDOMHO*z4*~7J>JJhY?eVN#gG0fytsjA)8}=n|(gs z*t_vG6u3iQ@o%Yg66=amTlf>TxpuT2j*>;Q3%WM4J+*BDI0~K>fD2W{!{@j%_!C1> z$e2}q<~+u;0#ZSLFU|g z0NdEE=^C*oBK0n35IUa-iX4gJDcn>p>RE{mH^IwYOND(SXszSH{DVafJ&2N<)^6dI z)I|b?*O(8IWQH#>+9?C`y--a!a2ih@#2JybR3R8CCH_-ke&9zUc0hnR9*S z$hj8Q)=7cv%6&i>fIW1SxShB59P?Uz2K2so$iGIdDF$Z3j$?eERdIM8-OyLm_{s`c zBzR3q!fI~1L$3zp5JzTifgD-bqm5@IA`#YcJW4Eu;Dwe7fp3R7_RQp0OwBkA- z!p!-2DNl@P9_kkjz~%B?|MG+33V1X89WDfvt~O{H`ipA-4SPV0fkDF-6edURK6SwK zh*2*pUJ>ys_Q-PS0f)mA-imx7-k4Ry>k0K*>nge|4O1|+le1ES7l&?O;xs-zdI}J> zn=gs!m{2}}^Z#CnJ!Ct-FQayhNfeOcB4?8CdDG9&2)6WXBnapPRXN?9VZc?5A)!8s z;Zk|vs=ZpklJXNz4y1vzwh12F1b7yPoyA|i2Lv(#-e2ZwTLAc-cpO-%K(1^oo^p^= zYE`8lkL&{HRFelH^SQGvApw)Q7kHN!(t}ut8Dco3pYCyOJ*p%E7V{kiFfu*xY61nE z8#Z`!1f^1WcKLBiSe8Ihabc$``1u2R-Iw0LSX8?E`rz{ z5Dy8Vx6-r8SWMylvo`wqlAB9&cS4R(<`v;ih`MikLYF7QPUj&#!!u$<+@&|4=TfAb*Sr05`5?OfC_01SeD);4AZMDBtl`CnC<9 zKHJCqRcYA&ehO%!Lhutas3faJ-H}V3jBr;Snilkw=w^RSA2Wa>F#0z-OX42fXNXjd z@5B@Y_mps`LA;kr#nh`6U|*2!U#R}nf5Ub-mXa_&bdmrtwW1KhaG%VK2y$>)5_cX* zAM+%MrA^x!p5JAxi2n`UZGiggt<}|t#8U>pkY z_`yazOTAO0?$-#u&1*m@V`oxi(Obx_nD1kGj|=Amw50R#GH16poo_aNK%XJkioOC> znm_i8fwD=nbWWshVHtNV>NT2$qM-E9dze@9Pre>;an%*UtzGLs*xu(6Y79xHmtROA z7J9c2H*O}_5ikUh2e*ha0T?2-(ZWJ1Rli>A+6RJ%djB5pnKff2%H2T3mI$WqZ#O_5 zP~8T)mCr1y+Kg@{E`@iv2sD5rhp|X)<}uB~0x< z#t{BwisC7MTjE*cdYG_2X;zpe3e<_kO%g!^!vRffZMCv5F5ps1x=&oAVus)K%Q7tO zrA9X;S~B^d35#pYq7v-&4%!nx1Q!_4-V&zk6KG?n{2HUufe z*PT*om+T?e`MnVI&&W++-wq1DHf~XeUB@>XCdKIcQa;WO&q&!5Jt-{_9a8oN9H)e% z^-D7+XnrlX{)i(3@jg({#I#N7m8167cvs^_GK@u!t~A+Og~LUcr1jj1j9(i&paDYQ z00prwL2*JF=1r7mrH>WKeib{0(~pjL@?Nq}1WgJ#;9@e+D29c~Avsrr6)oia=JiT~ zRcA5kvs5o1!lP9A2;lJFQ^!^n=@5G?*N!BLj`PH0fNgoT7R7D1P%XINnD)S0pQqT& zRZ^)a*5GZxY!vzJ6doXp+&_TKCRE4{Eai<{WjX5k8D}D49(KY2001$=c53`u2}gh! zhCq)4qItq?&3E_GBc$Q6u*+)X8+AK48u)&6ml=TOYia*dXZm0+U`=H$a9rxGvg#|4 zC3gJaL(x;rht)ISxrlB$9f*ilfXUn%w19}f0000000000000000000000000=J_WD literal 0 HcmV?d00001 diff --git a/boards/nuvoton/numaker_gai_m55m1/doc/index.rst b/boards/nuvoton/numaker_gai_m55m1/doc/index.rst new file mode 100644 index 000000000000..ad0bbb9d5187 --- /dev/null +++ b/boards/nuvoton/numaker_gai_m55m1/doc/index.rst @@ -0,0 +1,88 @@ +.. zephyr:board:: numaker_gai_m55m1 + +Overview +******** + +The NuMaker M55M1 is an Internet of Things (IoT) application focused platform +specially developed by Nuvoton. The NuGestureAI-M55M1 is based on the NuMicro® M55M1 +series MCU with ARM® -Cortex®-M55 core. + +Features +======== +- 32-bit Arm Cortex®-M55 M55M1H2LJAE MCU +- Core clock up to 220 MHz +- 2 MB embedded Dual Bank Flash and 1344 KB SRAM +- 128 KB DTCM and 64 KB ITCM +- USB 2.0 Full-Speed OTG / Device +- USB 1.1 Host +- One push-button is for reset +- Two LEDs: one is for power indication and the other is for user-defined +- One SWD connector + +More information about the board can be found at the `NuMaker M55M1 User Manual`_. + +Supported Features +================== + +.. zephyr:board-supported-hw:: + +The on-board 12-MHz crystal allows the device to run at its maximum operating speed of 220 MHz. + +More details about the supported peripherals are available in `M55M1 TRM`_ + +Building and Flashing +********************* + +.. zephyr:board-supported-runners:: + +Flashing +======== + +Here is an example for the :zephyr:code-sample:`hello_world` application. + +On board debugger Nu-link2 can emulate UART0 as a virtual COM port over usb, +To enable this, set ISW1 DIP switch 1-3 (TXD RXD VOM) to ON. +Connect the NuMaker-M55M1 to your host computer using the USB port, then +run a serial host program to connect with your board. For example: + +.. code-block:: console + + $ minicom -D /dev/ttyACM0 + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: numaker_gai_m55m1 + :goals: flash + +Debugging +========= + +Here is an example for the :zephyr:code-sample:`hello_world` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: numaker_gai_m55m1 + :goals: debug + +Step through the application in your debugger. + +VS Code Support +=============== + +Here is to go through VS Code instead of command line. + +Please install Nuvoton NuMicro Cortex-M Pack and follow getting start guide of this pack. +This pack is a complete development toolkit for Nuvoton’s NuMicro Cortex-M microcontrollers +in Visual Studio Code. +URL of this pack is +https://marketplace.visualstudio.com/items?itemName=Nuvoton.nuvoton-numicro-cortex-m-pack + +References +********** + +.. target-notes:: + +.. _NuMaker M55M1 User Manual: + https://www.nuvoton.com/products/microcontrollers/arm-cortex-m55-mcus/m55m1-series/ +.. _M55M1 TRM: + https://www.nuvoton.com/products/microcontrollers/arm-cortex-m55-mcus/m55m1-series/ diff --git a/boards/nuvoton/numaker_gai_m55m1/numaker_gai_m55m1-pinctrl.dtsi b/boards/nuvoton/numaker_gai_m55m1/numaker_gai_m55m1-pinctrl.dtsi new file mode 100644 index 000000000000..eb3800b70d98 --- /dev/null +++ b/boards/nuvoton/numaker_gai_m55m1/numaker_gai_m55m1-pinctrl.dtsi @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2026 Nuvoton Technology Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "pinctrl/m55m1h2l-pinctrl.h" + +&pinctrl { + uart5_default: uart5_default { + group0 { + pinmux = , + ; + }; + }; + + uart2_default: uart2_default { + group0 { + pinmux = , + ; + }; + }; +}; diff --git a/boards/nuvoton/numaker_gai_m55m1/numaker_gai_m55m1.dts b/boards/nuvoton/numaker_gai_m55m1/numaker_gai_m55m1.dts new file mode 100644 index 000000000000..a31a9b954ca0 --- /dev/null +++ b/boards/nuvoton/numaker_gai_m55m1/numaker_gai_m55m1.dts @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2026 Nuvoton Technology Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include "numaker_gai_m55m1-pinctrl.dtsi" +#include + +/ { + model = "Nuvoton NuMaker GestureAI M55M1 board"; + compatible = "nuvoton,numaker-m55m1"; + + aliases { + led0 = &yellow_led; + sw0 = &btn0; + }; + + chosen { + zephyr,console = &uart5; + zephyr,shell-uart = &uart5; + zephyr,sram = &sram0; + zephyr,dtcm = &dtcm; + zephyr,itcm = &itcm; + zephyr,flash = &flash0; + zephyr,code-partition = &slot0_partition; + }; + + leds { + compatible = "gpio-leds"; + + yellow_led: led_0 { + gpios = <&gpioa 7 GPIO_ACTIVE_LOW>; + label = "User LD0"; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + + btn0: btn0 { + label = "BTN0"; + gpios = <&gpioa 4 GPIO_ACTIVE_LOW>; + zephyr,code = ; + }; + }; +}; + +&scc { + lxt = "disable"; + hxt = "enable"; +}; + +&gpioa { + status = "okay"; +}; + +&flash0 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x0 0xfe00>; + }; + + slot0_partition: partition@fe00 { + label = "image-0"; + reg = <0xfe00 0xf4000>; + }; + + slot1_partition: partition@103e00 { + label = "image-1"; + reg = <0x103e00 0xf4000>; + }; + + storage_partition: partition@1f7e00 { + label = "storage"; + reg = <0x1f7e00 0x8200>; + }; + }; +}; + +&sram0 { + reg = <0x20100000 DT_SIZE_K(1344)>; +}; + +&uart5 { + current-speed = <115200>; + pinctrl-0 = <&uart5_default>; + pinctrl-names = "default"; + status = "okay"; +}; + +/* On enabled, husbd phy is required HXT. */ +zephyr_udc0: &hsusbd { + /* Needn't pinctrl for pins being dedicated */ + status = "okay"; +}; diff --git a/boards/nuvoton/numaker_gai_m55m1/numaker_gai_m55m1.yaml b/boards/nuvoton/numaker_gai_m55m1/numaker_gai_m55m1.yaml new file mode 100644 index 000000000000..65fe23d8e290 --- /dev/null +++ b/boards/nuvoton/numaker_gai_m55m1/numaker_gai_m55m1.yaml @@ -0,0 +1,16 @@ +# Copyright (c) 2026 Nuvoton Technology Corporation. +# SPDX-License-Identifier: Apache-2.0 + +identifier: numaker_gai_m55m1 +name: NUVOTON NUMAKER-GAI-M55M1 Kit +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb +ram: 1536 +flash: 2048 +supported: + - gpio + - usb +vendor: nuvoton diff --git a/boards/nuvoton/numaker_gai_m55m1/numaker_gai_m55m1_defconfig b/boards/nuvoton/numaker_gai_m55m1/numaker_gai_m55m1_defconfig new file mode 100644 index 000000000000..903b01170325 --- /dev/null +++ b/boards/nuvoton/numaker_gai_m55m1/numaker_gai_m55m1_defconfig @@ -0,0 +1,15 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_GPIO=y + +# Enable system clock controller driver +CONFIG_CLOCK_CONTROL=y +CONFIG_CLOCK_CONTROL_NUMAKER_SCC=y + +# Enable UART driver +CONFIG_SERIAL=y +CONFIG_UART_INTERRUPT_DRIVEN=y + +# Console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y diff --git a/boards/nuvoton/numaker_gai_m55m1/support/openocd.cfg b/boards/nuvoton/numaker_gai_m55m1/support/openocd.cfg new file mode 100644 index 000000000000..c393f756c4de --- /dev/null +++ b/boards/nuvoton/numaker_gai_m55m1/support/openocd.cfg @@ -0,0 +1,2 @@ +source [find interface/nulink.cfg] +source [find target/numicro.cfg] diff --git a/west.yml b/west.yml index ebc9fc7d5101..67e8e1c13d75 100644 --- a/west.yml +++ b/west.yml @@ -205,7 +205,7 @@ manifest: groups: - hal - name: hal_nuvoton - revision: 602db600cae5275ab0946de696a6068d769a6b3d + revision: 8f1bf948a94cf59926ea7b686985e1d6c6f954c7 path: modules/hal/nuvoton groups: - hal From 7a18e3a8cc34cc337bc0fded62185c118ac03bc9 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Tue, 13 Jan 2026 09:31:49 +0000 Subject: [PATCH 2145/3659] scripts: dts: gen_dts_cmake: Add DT_UNIT_ADDR to pickled CMake Adds a new property which outputs the absolute address of a dts device (if it is available) which will take the parent nodes into consideration without a user having to manually trawl through devices (which is error prone depending upon how they are layered) Signed-off-by: Jamie McCrae --- scripts/dts/gen_dts_cmake.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/scripts/dts/gen_dts_cmake.py b/scripts/dts/gen_dts_cmake.py index a8a2c3df611f..e3ec1997ee10 100755 --- a/scripts/dts/gen_dts_cmake.py +++ b/scripts/dts/gen_dts_cmake.py @@ -156,6 +156,10 @@ def main(): cmake_props.append(f'"DT_REG|{node.path}|ADDR" "{cmake_addr}"') cmake_props.append(f'"DT_REG|{node.path}|SIZE" "{cmake_size}"') + cmake_unit_addr_int = 'NONE' if node.unit_addr is None else hex(node.unit_addr) + + cmake_props.append(f'"DT_UNIT_ADDR|{node.path}" "{cmake_unit_addr_int}"') + for comp in compatible2paths.keys(): cmake_path = '' for path in compatible2paths[comp]: From 4146c053d22d4387d9411afc2a0b1232af2bad52 Mon Sep 17 00:00:00 2001 From: Lyle Zhu Date: Tue, 6 Jan 2026 16:53:57 +0800 Subject: [PATCH 2146/3659] bluetooth: shell: Fix error code formatting in BR/EDR shell Fix incorrect error code formatting in Bluetooth BR/EDR shell commands. Error codes are already negative values, so remove the redundant negation when printing error messages. Also update PSM registration message to print the PSM value in hexadecimal format for consistency. Changes: - Remove negation of error codes in shell_error() calls - Change PSM format specifier from %u to %04x for hex display - Affects l2cap_disconnect, l2cap_send, l2cap_credits, l2cap_echo_reg, l2cap_echo_unreg, l2cap_echo_req, and l2cap_echo_rsp commands Signed-off-by: Lyle Zhu --- subsys/bluetooth/host/classic/shell/bredr.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/subsys/bluetooth/host/classic/shell/bredr.c b/subsys/bluetooth/host/classic/shell/bredr.c index 81b9faf17b12..292ffb7698d9 100644 --- a/subsys/bluetooth/host/classic/shell/bredr.c +++ b/subsys/bluetooth/host/classic/shell/bredr.c @@ -476,7 +476,7 @@ static int cmd_l2cap_register(const struct shell *sh, size_t argc, char *argv[]) return -ENOEXEC; } - shell_print(sh, "L2CAP psm %u registered", l2cap_server.server.psm); + shell_print(sh, "L2CAP psm %04x registered", l2cap_server.server.psm); return 0; } @@ -573,7 +573,7 @@ static int cmd_l2cap_disconnect(const struct shell *sh, size_t argc, char *argv[ err = bt_l2cap_chan_disconnect(&l2cap_chan.chan.chan); if (err) { - shell_error(sh, "Unable to disconnect: %u", -err); + shell_error(sh, "Unable to disconnect: %d", err); } return err; @@ -618,7 +618,7 @@ static int cmd_l2cap_send(const struct shell *sh, size_t argc, char *argv[]) net_buf_add_mem(buf, buf_data, len); err = bt_l2cap_chan_send(&l2cap_chan.chan.chan, buf); if (err < 0) { - shell_error(sh, "Unable to send: %d", -err); + shell_error(sh, "Unable to send: %d", err); net_buf_unref(buf); return -ENOEXEC; } @@ -637,7 +637,7 @@ static int cmd_l2cap_credits(const struct shell *sh, size_t argc, char *argv[]) if (buf != NULL) { err = bt_l2cap_chan_recv_complete(&l2cap_chan.chan.chan, buf); if (err < 0) { - shell_error(sh, "Unable to set recv_complete: %d", -err); + shell_error(sh, "Unable to set recv_complete: %d", err); } } else { shell_warn(sh, "No pending recv buffer"); @@ -676,7 +676,7 @@ static int cmd_l2cap_echo_reg(const struct shell *sh, size_t argc, char *argv[]) err = bt_l2cap_br_echo_cb_register(&echo_cb); if (err) { - shell_error(sh, "Failed to register echo callback: %d", -err); + shell_error(sh, "Failed to register echo callback: %d", err); return err; } @@ -689,7 +689,7 @@ static int cmd_l2cap_echo_unreg(const struct shell *sh, size_t argc, char *argv[ err = bt_l2cap_br_echo_cb_unregister(&echo_cb); if (err) { - shell_error(sh, "Failed to unregister echo callback: %d", -err); + shell_error(sh, "Failed to unregister echo callback: %d", err); return err; } @@ -721,7 +721,7 @@ static int cmd_l2cap_echo_req(const struct shell *sh, size_t argc, char *argv[]) net_buf_add_mem(buf, buf_data, len); err = bt_l2cap_br_echo_req(default_conn, buf); if (err < 0) { - shell_error(sh, "Unable to send ECHO REQ: %d", -err); + shell_error(sh, "Unable to send ECHO REQ: %d", err); net_buf_unref(buf); return -ENOEXEC; } @@ -757,7 +757,7 @@ static int cmd_l2cap_echo_rsp(const struct shell *sh, size_t argc, char *argv[]) net_buf_add_mem(buf, buf_data, len); err = bt_l2cap_br_echo_rsp(default_conn, identifier, buf); if (err < 0) { - shell_error(sh, "Unable to send ECHO RSP: %d", -err); + shell_error(sh, "Unable to send ECHO RSP: %d", err); net_buf_unref(buf); return -ENOEXEC; } From ef7b132bfde8b207e41987eb22a5370b58c329b9 Mon Sep 17 00:00:00 2001 From: Lyle Zhu Date: Tue, 6 Jan 2026 15:36:54 +0800 Subject: [PATCH 2147/3659] Bluetooth: Classic: Fix initialization to support re-initialization In current implementation, the Classic L2CAP server list will be cleared when the function `bt_enable()` called. It causes the registered Classic L2CAP servers are unregistered. However, the higher-ups were completely unaware of this behavior. It causes the Classic L2CAP server cannot work after executing the sequence `bt_enable()`, `bt_disable()`, and `bt_enable()`. Also this behavior is inconsistent with LE L2CAP server. Remove the initialization of Classic L2CAP server list from function `bt_l2cap_br_init()` to fix the issue. Make Bluetooth Classic profile initialization functions idempotent by adding static initialized flags to prevent re-initialization. Change return type from int to void since errors are now logged but not propagated. Changes include: - Add initialized flag to prevent multiple initialization - Change return type to void for init functions - Mark err variables as __maybe_unused where appropriate - Improve error logging with error codes - Handle -EEXIST and -EALREADY errors for re-registration - Initialize connection pools before checking initialized flag in AVRCP to support re-initialization scenarios - Remove unnecessary sys_slist_init in bt_l2cap_br_init Signed-off-by: Lyle Zhu --- subsys/bluetooth/host/classic/a2dp.c | 24 +++---- subsys/bluetooth/host/classic/a2dp_internal.h | 3 +- subsys/bluetooth/host/classic/avctp.c | 13 +++- .../bluetooth/host/classic/avctp_internal.h | 3 +- subsys/bluetooth/host/classic/avdtp.c | 21 ++++-- .../bluetooth/host/classic/avdtp_internal.h | 4 +- subsys/bluetooth/host/classic/avrcp.c | 65 +++++++++++-------- .../bluetooth/host/classic/avrcp_internal.h | 3 +- subsys/bluetooth/host/classic/did.c | 18 ++++- subsys/bluetooth/host/classic/did_internal.h | 2 +- subsys/bluetooth/host/classic/l2cap_br.c | 2 - subsys/bluetooth/host/classic/rfcomm.c | 14 +++- subsys/bluetooth/host/classic/sdp.c | 18 +++-- 13 files changed, 128 insertions(+), 62 deletions(-) diff --git a/subsys/bluetooth/host/classic/a2dp.c b/subsys/bluetooth/host/classic/a2dp.c index 720515a61e68..190d5ce9dbbd 100644 --- a/subsys/bluetooth/host/classic/a2dp.c +++ b/subsys/bluetooth/host/classic/a2dp.c @@ -4,7 +4,7 @@ /* * Copyright (c) 2015-2016 Intel Corporation - * Copyright 2021,2024 NXP + * Copyright 2021,2024-2025 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -1463,23 +1463,25 @@ static struct bt_avdtp_event_cb avdtp_cb = { .accept = a2dp_accept, }; -int bt_a2dp_init(void) +void bt_a2dp_init(void) { - int err; + __maybe_unused int err; - /* Register event handlers with AVDTP */ - err = bt_avdtp_register(&avdtp_cb); - if (err < 0) { - LOG_ERR("A2DP registration failed"); - return err; + static bool initialized; + + if (initialized) { + return; } - ARRAY_FOR_EACH(connection, i) { - memset(&connection[i], 0, sizeof(struct bt_a2dp)); + /* Register event handlers with AVDTP */ + err = bt_avdtp_register(&avdtp_cb); + if ((err < 0) && (err != -EALREADY)) { + LOG_ERR("A2DP registration failed (err %d)", err); + return; } LOG_DBG("A2DP Initialized successfully."); - return 0; + initialized = true; } struct bt_a2dp *bt_a2dp_connect(struct bt_conn *conn) diff --git a/subsys/bluetooth/host/classic/a2dp_internal.h b/subsys/bluetooth/host/classic/a2dp_internal.h index 08e8b76b4b12..dd4f327ba2f9 100644 --- a/subsys/bluetooth/host/classic/a2dp_internal.h +++ b/subsys/bluetooth/host/classic/a2dp_internal.h @@ -4,9 +4,10 @@ /* * Copyright (c) 2015-2016 Intel Corporation + * Copyright 2025 NXP * * SPDX-License-Identifier: Apache-2.0 */ /* To be called when first SEP is being registered */ -int bt_a2dp_init(void); +void bt_a2dp_init(void); diff --git a/subsys/bluetooth/host/classic/avctp.c b/subsys/bluetooth/host/classic/avctp.c index 0d38e4c0ba7f..11f5374793ce 100644 --- a/subsys/bluetooth/host/classic/avctp.c +++ b/subsys/bluetooth/host/classic/avctp.c @@ -5,6 +5,7 @@ /* * Copyright (c) 2015-2016 Intel Corporation * Copyright (C) 2024 Xiaomi Corporation + * Copyright 2025 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -718,12 +719,18 @@ int bt_avctp_server_register(struct bt_avctp_server *server) return err; } -int bt_avctp_init(void) +void bt_avctp_init(void) { + static bool initialized; + + if (initialized) { + return; + } + + initialized = true; + LOG_DBG("Initializing AVCTP"); /* Locking semaphore initialized to 1 (unlocked) */ k_sem_init(&avctp_lock, 1, 1); k_work_init_delayable(&avctp_tx_work, avctp_tx_processor); - - return 0; } diff --git a/subsys/bluetooth/host/classic/avctp_internal.h b/subsys/bluetooth/host/classic/avctp_internal.h index 793820a2cc03..04c02157334d 100644 --- a/subsys/bluetooth/host/classic/avctp_internal.h +++ b/subsys/bluetooth/host/classic/avctp_internal.h @@ -5,6 +5,7 @@ /* * Copyright (c) 2015-2016 Intel Corporation * Copyright (C) 2024 Xiaomi Corporation + * Copyright 2025 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -158,7 +159,7 @@ struct bt_avctp_event_cb { }; /* Initialize AVCTP layer*/ -int bt_avctp_init(void); +void bt_avctp_init(void); /* Application register with AVCTP layer */ int bt_avctp_server_register(struct bt_avctp_server *server); diff --git a/subsys/bluetooth/host/classic/avdtp.c b/subsys/bluetooth/host/classic/avdtp.c index 155bfbdde557..03af05755969 100644 --- a/subsys/bluetooth/host/classic/avdtp.c +++ b/subsys/bluetooth/host/classic/avdtp.c @@ -1,7 +1,7 @@ /* * Audio Video Distribution Protocol * - * Copyright 2024 - 2025 NXP + * Copyright 2024-2025 NXP * * SPDX-License-Identifier: Apache-2.0 * @@ -2233,10 +2233,14 @@ int bt_avdtp_register(struct bt_avdtp_event_cb *cb) { LOG_DBG(""); - if (event_cb) { + if (event_cb == cb) { return -EALREADY; } + if (event_cb != NULL) { + return -EEXIST; + } + event_cb = cb; return 0; @@ -2280,9 +2284,11 @@ int bt_avdtp_register_sep(uint8_t media_type, uint8_t sep_type, struct bt_avdtp_ } /* init function */ -int bt_avdtp_init(void) +void bt_avdtp_init(void) { int err; + + static bool initialized; static struct bt_l2cap_server avdtp_l2cap = { .psm = BT_L2CAP_PSM_AVDTP, .sec_level = BT_SECURITY_L2, @@ -2291,13 +2297,18 @@ int bt_avdtp_init(void) LOG_DBG(""); + if (initialized) { + return; + } + /* Register AVDTP PSM with L2CAP */ err = bt_l2cap_br_server_register(&avdtp_l2cap); - if (err < 0) { + if ((err < 0) && (err != -EEXIST)) { LOG_ERR("AVDTP L2CAP Registration failed %d", err); + return; } - return err; + initialized = true; } /* AVDTP Discover Request */ diff --git a/subsys/bluetooth/host/classic/avdtp_internal.h b/subsys/bluetooth/host/classic/avdtp_internal.h index 71df55fdd659..e9758570b03a 100644 --- a/subsys/bluetooth/host/classic/avdtp_internal.h +++ b/subsys/bluetooth/host/classic/avdtp_internal.h @@ -2,7 +2,7 @@ * avdtp_internal.h - avdtp handling * Copyright (c) 2015-2016 Intel Corporation - * Copyright 2021,2024 NXP + * Copyright 2021,2024-2025 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -279,7 +279,7 @@ struct bt_avdtp_event_cb { }; /* Initialize AVDTP layer*/ -int bt_avdtp_init(void); +void bt_avdtp_init(void); /* Application register with AVDTP layer */ int bt_avdtp_register(struct bt_avdtp_event_cb *cb); diff --git a/subsys/bluetooth/host/classic/avrcp.c b/subsys/bluetooth/host/classic/avrcp.c index 0a7d994071e3..701b6362fc4b 100644 --- a/subsys/bluetooth/host/classic/avrcp.c +++ b/subsys/bluetooth/host/classic/avrcp.c @@ -5,6 +5,7 @@ /* * Copyright (c) 2015-2016 Intel Corporation * Copyright (C) 2024 Xiaomi Corporation + * Copyright 2025 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -2935,17 +2936,44 @@ static int avrcp_browsing_accept(struct bt_conn *conn, struct bt_avctp **session } #endif /* CONFIG_BT_AVRCP_BROWSING */ -int bt_avrcp_init(void) +void bt_avrcp_init(void) { - int err; + __maybe_unused int err; + + static bool initialized; + + /* Init CT and TG connection pool*/ + __ASSERT(ARRAY_SIZE(bt_avrcp_ct_pool) == ARRAY_SIZE(avrcp_connection), "CT size mismatch"); + __ASSERT(ARRAY_SIZE(bt_avrcp_tg_pool) == ARRAY_SIZE(avrcp_connection), "TG size mismatch"); + + ARRAY_FOR_EACH(avrcp_connection, i) { + bt_avrcp_ct_pool[i].avrcp = &avrcp_connection[i]; + bt_avrcp_tg_pool[i].avrcp = &avrcp_connection[i]; + + if (!initialized) { + /* Init delay work */ + k_work_init_delayable(&bt_avrcp_tg_pool[i].vd_rsp_tx_work, + bt_avrcp_tg_vendor_tx_work); + sys_slist_init(&bt_avrcp_tg_pool[i].vd_rsp_tx_pending); + + k_sem_init(&bt_avrcp_tg_pool[i].lock, 1, 1); + } + + memset(bt_avrcp_ct_pool[i].ct_notify, 0, sizeof(bt_avrcp_ct_pool[i].ct_notify)); + memset(bt_avrcp_tg_pool[i].tg_notify, 0, sizeof(bt_avrcp_tg_pool[i].tg_notify)); + } + + if (initialized) { + return; + } /* Register event handlers with AVCTP */ avctp_server.l2cap.psm = BT_L2CAP_PSM_AVRCP; avctp_server.accept = avrcp_accept; err = bt_avctp_server_register(&avctp_server); if (err < 0) { - LOG_ERR("AVRCP registration failed"); - return err; + LOG_ERR("AVRCP registration failed (err %d)", err); + return; } #if defined(CONFIG_BT_AVRCP_BROWSING) @@ -2953,16 +2981,16 @@ int bt_avrcp_init(void) avctp_browsing_server.accept = avrcp_browsing_accept; err = bt_avctp_server_register(&avctp_browsing_server); if (err < 0) { - LOG_ERR("AVRCP browsing registration failed"); - return err; + LOG_ERR("AVRCP browsing registration failed (err %d)", err); + return; } #endif /* CONFIG_BT_AVRCP_BROWSING */ #if defined(CONFIG_BT_AVRCP_TG_COVER_ART) err = bt_avrcp_tg_cover_art_init(&bt_avrcp_tg_cover_art_psm); if (err < 0) { - LOG_ERR("AVRCP Cover Art initialization failed"); - return err; + LOG_ERR("AVRCP Cover Art initialization failed (err %d)", err); + return; } #endif /* CONFIG_BT_AVRCP_TG_COVER_ART */ @@ -2974,26 +3002,9 @@ int bt_avrcp_init(void) bt_sdp_register_service(&avrcp_ct_rec); #endif /* CONFIG_BT_AVRCP_CONTROLLER */ - /* Init CT and TG connection pool*/ - __ASSERT(ARRAY_SIZE(bt_avrcp_ct_pool) == ARRAY_SIZE(avrcp_connection), "CT size mismatch"); - __ASSERT(ARRAY_SIZE(bt_avrcp_tg_pool) == ARRAY_SIZE(avrcp_connection), "TG size mismatch"); - - ARRAY_FOR_EACH(avrcp_connection, i) { - bt_avrcp_ct_pool[i].avrcp = &avrcp_connection[i]; - bt_avrcp_tg_pool[i].avrcp = &avrcp_connection[i]; - /* Init delay work */ - k_work_init_delayable(&bt_avrcp_tg_pool[i].vd_rsp_tx_work, - bt_avrcp_tg_vendor_tx_work); - sys_slist_init(&bt_avrcp_tg_pool[i].vd_rsp_tx_pending); - - k_sem_init(&bt_avrcp_tg_pool[i].lock, 1, 1); - - memset(bt_avrcp_ct_pool[i].ct_notify, 0, sizeof(bt_avrcp_ct_pool[i].ct_notify)); - - memset(bt_avrcp_tg_pool[i].tg_notify, 0, sizeof(bt_avrcp_tg_pool[i].tg_notify)); - } LOG_DBG("AVRCP Initialized successfully."); - return 0; + + initialized = true; } int bt_avrcp_connect(struct bt_conn *conn) diff --git a/subsys/bluetooth/host/classic/avrcp_internal.h b/subsys/bluetooth/host/classic/avrcp_internal.h index 0cf170bf6c34..5ccaf5d30c9e 100644 --- a/subsys/bluetooth/host/classic/avrcp_internal.h +++ b/subsys/bluetooth/host/classic/avrcp_internal.h @@ -5,6 +5,7 @@ /* * Copyright (c) 2015-2016 Intel Corporation * Copyright (C) 2024 Xiaomi Corporation + * Copyright 2025 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -279,7 +280,7 @@ struct bt_avrcp_frame { uint8_t data[]; } __packed; -int bt_avrcp_init(void); +void bt_avrcp_init(void); int bt_avrcp_tg_cover_art_init(uint16_t *psm); diff --git a/subsys/bluetooth/host/classic/did.c b/subsys/bluetooth/host/classic/did.c index f1f2b19326e9..f6800df59e4d 100644 --- a/subsys/bluetooth/host/classic/did.c +++ b/subsys/bluetooth/host/classic/did.c @@ -65,7 +65,21 @@ static struct bt_sdp_attribute did_attrs[] = { static struct bt_sdp_record did_rec = BT_SDP_RECORD(did_attrs); -int bt_did_init(void) +void bt_did_init(void) { - return bt_sdp_register_service(&did_rec); + __maybe_unused int err; + + static bool initialized; + + if (initialized) { + return; + } + + err = bt_sdp_register_service(&did_rec); + if (err != 0) { + LOG_ERR("Failed to register DID SDP record (err %d)", err); + return; + } + + initialized = true; } diff --git a/subsys/bluetooth/host/classic/did_internal.h b/subsys/bluetooth/host/classic/did_internal.h index 453d2ce3efd2..ec91ec80366e 100644 --- a/subsys/bluetooth/host/classic/did_internal.h +++ b/subsys/bluetooth/host/classic/did_internal.h @@ -9,4 +9,4 @@ */ /** Device Identification Init. **/ -int bt_did_init(void); +void bt_did_init(void); diff --git a/subsys/bluetooth/host/classic/l2cap_br.c b/subsys/bluetooth/host/classic/l2cap_br.c index b290ee6a4c94..56d35222811a 100644 --- a/subsys/bluetooth/host/classic/l2cap_br.c +++ b/subsys/bluetooth/host/classic/l2cap_br.c @@ -6195,8 +6195,6 @@ BT_L2CAP_BR_CHANNEL_DEFINE(br_fixed_chan, BT_L2CAP_CID_BR_SIG, l2cap_br_accept); void bt_l2cap_br_init(void) { - sys_slist_init(&br_servers); - if (IS_ENABLED(CONFIG_BT_RFCOMM)) { bt_rfcomm_init(); } diff --git a/subsys/bluetooth/host/classic/rfcomm.c b/subsys/bluetooth/host/classic/rfcomm.c index ba0cb315f2cc..2fcd81e6313d 100644 --- a/subsys/bluetooth/host/classic/rfcomm.c +++ b/subsys/bluetooth/host/classic/rfcomm.c @@ -2,6 +2,7 @@ /* * Copyright (c) 2016 Intel Corporation + * Copyright 2024-2025 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -1861,15 +1862,24 @@ static int rfcomm_accept(struct bt_conn *conn, struct bt_l2cap_server *server, void bt_rfcomm_init(void) { + __maybe_unused int err; + + static bool initialized; static struct bt_l2cap_server server = { .psm = BT_L2CAP_PSM_RFCOMM, .accept = rfcomm_accept, .sec_level = BT_SECURITY_L1, }; - __maybe_unused int err; + + if (initialized) { + return; + } err = bt_l2cap_br_server_register(&server); - if (err != 0) { + if ((err != 0) && (err != -EEXIST)) { LOG_ERR("Failed to register L2CAP server for RFCOMM (err %d)", err); + return; } + + initialized = true; } diff --git a/subsys/bluetooth/host/classic/sdp.c b/subsys/bluetooth/host/classic/sdp.c index 0fc74075a920..716e79493f7e 100644 --- a/subsys/bluetooth/host/classic/sdp.c +++ b/subsys/bluetooth/host/classic/sdp.c @@ -4,6 +4,7 @@ /* * Copyright (c) 2016 Intel Corporation + * Copyright 2024-2025 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -1673,22 +1674,31 @@ static int bt_sdp_accept(struct bt_conn *conn, struct bt_l2cap_server *server, void bt_sdp_init(void) { + __maybe_unused int err; + + static bool initialized; static struct bt_l2cap_server server = { .psm = SDP_PSM, .accept = bt_sdp_accept, .sec_level = BT_SECURITY_L0, }; - int res; - res = bt_l2cap_br_server_register(&server); - if (res) { - LOG_ERR("L2CAP server registration failed with error %d", res); + if (initialized) { + return; + } + + err = bt_l2cap_br_server_register(&server); + if ((err != 0) && (err != -EEXIST)) { + LOG_ERR("Failed to register SDP L2CAP server (error %d)", err); + return; } ARRAY_FOR_EACH(bt_sdp_client_pool, i) { /* Locking semaphore initialized to 1 (unlocked) */ k_sem_init(&bt_sdp_client_pool[i].sem_lock, 1, 1); } + + initialized = true; } int bt_sdp_register_service(struct bt_sdp_record *service) From a25598eab97b0f2718f24a5b012cdc324b627776 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Sat, 3 Jan 2026 15:03:38 +0100 Subject: [PATCH 2148/3659] Bluetooth: CSIP: Fix set member register issue Fix issue with re-registering CSIS where it relied on a stack allocated value during the service unregistering and reset. To fix this properly, and to allow for further optimization, the register function was refactored to dynamically create the service, rather than relying on a static allocation and dynamically remove unwanted characteristics. Additionally this new approach also allow us to rely on IS_ENABLED and remove some #if defined, as well as reducing both ROM and RAM memory usage. Signed-off-by: Emil Gydesen --- subsys/bluetooth/audio/csip_set_member.c | 367 +++++++++++------- .../audio/src/csip_set_member_test.c | 9 +- 2 files changed, 244 insertions(+), 132 deletions(-) diff --git a/subsys/bluetooth/audio/csip_set_member.c b/subsys/bluetooth/audio/csip_set_member.c index 912b5272d675..3798e87849a8 100644 --- a/subsys/bluetooth/audio/csip_set_member.c +++ b/subsys/bluetooth/audio/csip_set_member.c @@ -2,7 +2,7 @@ /* * Copyright (c) 2019 Bose Corporation - * Copyright (c) 2020-2025 Nordic Semiconductor ASA + * Copyright (c) 2020-2026 Nordic Semiconductor ASA * * SPDX-License-Identifier: Apache-2.0 */ @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -41,6 +42,7 @@ #include "../host/keys.h" #include "../host/settings.h" +#include "common/bt_settings_commit.h" #include "common/bt_str.h" #include "audio_internal.h" #include "csip_internal.h" @@ -51,6 +53,10 @@ #define CSIS_CHAR_ATTR_COUNT 3 /* declaration + value + cccd */ #define CSIS_RANK_CHAR_ATTR_COUNT 2 /* declaration + value */ +#define CSIS_MAX_ATTR \ + (10U + IS_ENABLED(CONFIG_BT_CSIP_SET_MEMBER_SIRK_NOTIFIABLE) + \ + IS_ENABLED(CONFIG_BT_CSIP_SET_MEMBER_SIZE_NOTIFIABLE)) + LOG_MODULE_REGISTER(bt_csip_set_member, CONFIG_BT_CSIP_SET_MEMBER_LOG_LEVEL); enum csip_flag { @@ -77,8 +83,11 @@ struct bt_csip_set_member_svc_inst { struct bt_csip_set_member_cb *cb; struct k_work_delayable set_lock_timer; bt_addr_le_t lock_client_addr; - struct bt_gatt_service *service_p; struct csip_client clients[CONFIG_BT_MAX_PAIRED]; + + struct bt_gatt_service gatt_svc; + struct bt_gatt_attr attrs[CSIS_MAX_ATTR]; + /* Must be last: exclude from memset during unregister */ struct k_mutex mutex; }; @@ -307,12 +316,10 @@ static ssize_t read_sirk(struct bt_conn *conn, const struct bt_gatt_attr *attr, sirk, sizeof(*sirk)); } -#if defined(CONFIG_BT_CSIP_SET_MEMBER_SIRK_NOTIFIABLE) static void sirk_cfg_changed(const struct bt_gatt_attr *attr, uint16_t value) { LOG_DBG("value 0x%04x", value); } -#endif /* CONFIG_BT_CSIP_SET_MEMBER_SIRK_NOTIFIABLE */ static ssize_t read_set_size(struct bt_conn *conn, const struct bt_gatt_attr *attr, @@ -327,13 +334,11 @@ static ssize_t read_set_size(struct bt_conn *conn, sizeof(svc_inst->set_size)); } -#if defined(CONFIG_BT_CSIP_SET_MEMBER_SIZE_NOTIFIABLE) static void set_size_cfg_changed(const struct bt_gatt_attr *attr, uint16_t value) { LOG_DBG("value 0x%04x", value); } -#endif /* CONFIG_BT_CSIP_SET_MEMBER_SIZE_NOTIFIABLE */ static ssize_t read_set_lock(struct bt_conn *conn, const struct bt_gatt_attr *attr, @@ -659,55 +664,14 @@ static struct bt_conn_auth_info_cb auth_callbacks = { .bond_deleted = csip_bond_deleted }; -#if defined(CONFIG_BT_CSIP_SET_MEMBER_SIRK_NOTIFIABLE) -#define BT_CSIS_CHR_SIRK(_csip) \ - BT_AUDIO_CHRC(BT_UUID_CSIS_SIRK, BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \ - BT_GATT_PERM_READ_ENCRYPT, read_sirk, NULL, &_csip), \ - BT_AUDIO_CCC(sirk_cfg_changed) -#else -#define BT_CSIS_CHR_SIRK(_csip) \ - BT_AUDIO_CHRC(BT_UUID_CSIS_SIRK, BT_GATT_CHRC_READ, BT_GATT_PERM_READ_ENCRYPT, read_sirk, \ - NULL, &_csip) -#endif /* CONFIG_BT_CSIP_SET_MEMBER_SIRK_NOTIFIABLE */ - -#if defined(CONFIG_BT_CSIP_SET_MEMBER_SIZE_NOTIFIABLE) -#define BT_CSIS_CHR_SIZE(_csip) \ - BT_AUDIO_CHRC(BT_UUID_CSIS_SET_SIZE, BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \ - BT_GATT_PERM_READ_ENCRYPT, read_set_size, NULL, &_csip), \ - BT_AUDIO_CCC(set_size_cfg_changed) -#else -#define BT_CSIS_CHR_SIZE(_csip) \ - BT_AUDIO_CHRC(BT_UUID_CSIS_SET_SIZE, BT_GATT_CHRC_READ, BT_GATT_PERM_READ_ENCRYPT, \ - read_set_size, NULL, &_csip) -#endif /* CONFIG_BT_CSIP_SET_MEMBER_SIZE_NOTIFIABLE */ - -#define BT_CSIP_SERVICE_DEFINITION(_csip) {\ - BT_GATT_PRIMARY_SERVICE(BT_UUID_CSIS), \ - BT_CSIS_CHR_SIRK(_csip), \ - BT_CSIS_CHR_SIZE(_csip), \ - BT_AUDIO_CHRC(BT_UUID_CSIS_SET_LOCK, \ - BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY | BT_GATT_CHRC_WRITE, \ - BT_GATT_PERM_READ_ENCRYPT | BT_GATT_PERM_WRITE_ENCRYPT, \ - read_set_lock, write_set_lock, &_csip), \ - BT_AUDIO_CCC(set_lock_cfg_changed), \ - BT_AUDIO_CHRC(BT_UUID_CSIS_RANK, \ - BT_GATT_CHRC_READ, \ - BT_GATT_PERM_READ_ENCRYPT, \ - read_rank, NULL, &_csip) \ - } - -BT_GATT_SERVICE_INSTANCE_DEFINE(csip_set_member_service_list, svc_insts, - CONFIG_BT_CSIP_SET_MEMBER_MAX_INSTANCE_COUNT, - BT_CSIP_SERVICE_DEFINITION); - /****************************** Public API ******************************/ void *bt_csip_set_member_svc_decl_get(const struct bt_csip_set_member_svc_inst *svc_inst) { - if (svc_inst == NULL || svc_inst->service_p == NULL) { + if (svc_inst == NULL || svc_inst->gatt_svc.attrs == NULL) { return NULL; } - return svc_inst->service_p->attrs; + return svc_inst->gatt_svc.attrs; } static bool valid_register_param(const struct bt_csip_set_member_register_param *param) @@ -733,60 +697,13 @@ static bool valid_register_param(const struct bt_csip_set_member_register_param return true; } -static void remove_csis_char(const struct bt_uuid *uuid, struct bt_gatt_service *svc) -{ - size_t attrs_to_rem; - - /* Rank does not have any CCCD */ - if (bt_uuid_cmp(uuid, BT_UUID_CSIS_RANK) == 0) { - attrs_to_rem = CSIS_RANK_CHAR_ATTR_COUNT; - } else { - attrs_to_rem = CSIS_CHAR_ATTR_COUNT; - } - - /* Start at index 4 as the first 4 attributes are mandatory */ - for (size_t i = 4U; i < svc->attr_count; i++) { - if (bt_uuid_cmp(svc->attrs[i].uuid, uuid) == 0) { - /* Remove the characteristic declaration, the characteristic value and - * potentially the CCCD. The value declaration will be a i - 1, the - * characteristic value at i and the CCCD is potentially at i + 1 - */ - - /* We use attrs_to_rem to determine whether there is a CCCD after the - * characteristic value or not, which then determines if this is the last - * characteristic or not - */ - if (i == (svc->attr_count - (attrs_to_rem - 1))) { - /* This is the last characteristic in the service: just decrement - * the attr_count by number of attributes to remove - * (CSIS_CHAR_ATTR_COUNT) - */ - } else { - /* Move all following attributes attrs_to_rem locations "up" */ - for (size_t j = i - 1U; j < svc->attr_count - attrs_to_rem; j++) { - svc->attrs[j] = svc->attrs[j + attrs_to_rem]; - } - } - - svc->attr_count -= attrs_to_rem; - - return; - } - } - - __ASSERT(false, "Failed to remove CSIS char %s", bt_uuid_str(uuid)); -} - static void notify(struct bt_csip_set_member_svc_inst *svc_inst, struct bt_conn *conn, const struct bt_uuid *uuid, const void *data, uint16_t len) { int err; const struct bt_gatt_attr *attr; - attr = bt_gatt_find_by_uuid( - svc_inst->service_p->attrs, - svc_inst->service_p->attr_count, - uuid); + attr = bt_gatt_find_by_uuid(svc_inst->gatt_svc.attrs, svc_inst->gatt_svc.attr_count, uuid); if (attr == NULL) { LOG_WRN("Attribute for UUID %p not found", uuid); @@ -836,7 +753,7 @@ static void notify_cb(struct bt_conn *conn, void *data) continue; } - if (svc_inst->service_p == NULL || svc_inst->service_p->attrs == NULL) { + if (svc_inst->gatt_svc.attrs == NULL) { goto unlock_and_return; } @@ -907,6 +824,214 @@ static void add_bonded_addr_to_client_list(const struct bt_bond_info *info, void } } +/* Set sirk */ +static const struct bt_gatt_chrc set_sirk_user_data = BT_GATT_CHRC_INIT( + BT_UUID_CSIS_SIRK, 0U, + BT_GATT_CHRC_READ | + (IS_ENABLED(CONFIG_BT_CSIP_SET_MEMBER_SIRK_NOTIFIABLE) ? BT_GATT_CHRC_NOTIFY : 0U)); + +#define CSIS_SET_SIRK_AUDIO_USER_DATA(_n, ...) \ + (struct bt_audio_attr_user_data) \ + BT_AUDIO_ATTR_USER_DATA_INIT(read_sirk, NULL, &svc_insts[(_n)]) + +static const struct bt_audio_attr_user_data set_sirk_audio_user_data[] = { + LISTIFY(CONFIG_BT_CSIP_SET_MEMBER_MAX_INSTANCE_COUNT, + CSIS_SET_SIRK_AUDIO_USER_DATA, (,)), +}; + +#define CSIS_SET_SIRK_AUDIO_CCC_USER_DATA(_n, ...) \ + (struct bt_gatt_ccc_managed_user_data) \ + BT_GATT_CCC_MANAGED_USER_DATA_INIT(sirk_cfg_changed, bt_audio_ccc_cfg_write, NULL) + +/* Unlike the other user_data used for CSIP this + * one needs to be in RAM as it contains the `value` written by clients + */ +static struct bt_gatt_ccc_managed_user_data set_sirk_audio_ccc_user_data[] = { + LISTIFY(CONFIG_BT_CSIP_SET_MEMBER_MAX_INSTANCE_COUNT, + CSIS_SET_SIRK_AUDIO_CCC_USER_DATA, (,)), +}; + +/* Set size */ +static const struct bt_gatt_chrc set_size_user_data = BT_GATT_CHRC_INIT( + BT_UUID_CSIS_SET_SIZE, 0U, + BT_GATT_CHRC_READ | + (IS_ENABLED(CONFIG_BT_CSIP_SET_MEMBER_SIZE_NOTIFIABLE) ? BT_GATT_CHRC_NOTIFY : 0U)); + +#define CSIS_SET_SIZE_AUDIO_USER_DATA(_n, ...) \ + (struct bt_audio_attr_user_data) \ + BT_AUDIO_ATTR_USER_DATA_INIT(read_set_size, NULL, &svc_insts[(_n)]) + +static const struct bt_audio_attr_user_data set_size_audio_user_data[] = { + LISTIFY(CONFIG_BT_CSIP_SET_MEMBER_MAX_INSTANCE_COUNT, + CSIS_SET_SIZE_AUDIO_USER_DATA, (,)), +}; + +#define CSIS_SET_SIZE_AUDIO_CCC_USER_DATA(_n, ...) \ + (struct bt_gatt_ccc_managed_user_data) BT_GATT_CCC_MANAGED_USER_DATA_INIT( \ + set_size_cfg_changed, bt_audio_ccc_cfg_write, NULL) + +/* Unlike the other user_data used for CSIP this + * one needs to be in RAM as it contains the `value` written by clients + */ +static struct bt_gatt_ccc_managed_user_data set_size_audio_ccc_user_data[] = { + LISTIFY(CONFIG_BT_CSIP_SET_MEMBER_MAX_INSTANCE_COUNT, + CSIS_SET_SIZE_AUDIO_CCC_USER_DATA, (,)), +}; + +/* Set lock */ +static const struct bt_gatt_chrc set_lock_user_data = BT_GATT_CHRC_INIT( + BT_UUID_CSIS_SET_LOCK, 0U, BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE | BT_GATT_CHRC_NOTIFY); + +#define CSIS_SET_LOCK_AUDIO_USER_DATA(_n, ...) \ + (struct bt_audio_attr_user_data) \ + BT_AUDIO_ATTR_USER_DATA_INIT(read_set_lock, write_set_lock, &svc_insts[(_n)]) + +static const struct bt_audio_attr_user_data set_lock_audio_user_data[] = { + LISTIFY(CONFIG_BT_CSIP_SET_MEMBER_MAX_INSTANCE_COUNT, + CSIS_SET_LOCK_AUDIO_USER_DATA, (,)), +}; + +#define CSIS_SET_LOCK_AUDIO_CCC_USER_DATA(_n, ...) \ + (struct bt_gatt_ccc_managed_user_data) BT_GATT_CCC_MANAGED_USER_DATA_INIT( \ + set_lock_cfg_changed, bt_audio_ccc_cfg_write, NULL) + +/* Unlike the other user_data used for CSIP this + * one needs to be in RAM as it contains the `value` written by clients + */ +static struct bt_gatt_ccc_managed_user_data set_lock_audio_ccc_user_data[] = { + LISTIFY(CONFIG_BT_CSIP_SET_MEMBER_MAX_INSTANCE_COUNT, + CSIS_SET_LOCK_AUDIO_CCC_USER_DATA, (,)), +}; + +/* Rank */ +static const struct bt_gatt_chrc rank_user_data = + BT_GATT_CHRC_INIT(BT_UUID_CSIS_RANK, 0U, BT_GATT_CHRC_READ); + +#define CSIS_RANK_AUDIO_USER_DATA(_n, ...) \ + (struct bt_audio_attr_user_data) \ + BT_AUDIO_ATTR_USER_DATA_INIT(read_rank, NULL, &svc_insts[(_n)]) + +static const struct bt_audio_attr_user_data rank_audio_user_data[] = { + LISTIFY(CONFIG_BT_CSIP_SET_MEMBER_MAX_INSTANCE_COUNT, + CSIS_RANK_AUDIO_USER_DATA, (,)), +}; + +static const struct bt_uuid *svc_uuid = BT_UUID_GATT_PRIMARY; +static const struct bt_uuid *ccc_uuid = BT_UUID_GATT_CCC; +static const struct bt_uuid *chrc_uuid = BT_UUID_GATT_CHRC; +static const struct bt_uuid *csis_uuid = BT_UUID_CSIS; +static const struct bt_uuid *sirk_uuid = BT_UUID_CSIS_SIRK; +static const struct bt_uuid *size_uuid = BT_UUID_CSIS_SET_SIZE; +static const struct bt_uuid *lock_uuid = BT_UUID_CSIS_SET_LOCK; +static const struct bt_uuid *rank_uuid = BT_UUID_CSIS_RANK; +static void instantiate_service(struct bt_csip_set_member_svc_inst *inst, + const struct bt_csip_set_member_register_param *param) +{ + const ptrdiff_t idx = ARRAY_INDEX(svc_insts, inst); + size_t attr_cnt = 0U; + + inst->gatt_svc.attrs = inst->attrs; + /* Primary service */ + inst->attrs[attr_cnt].uuid = svc_uuid; + inst->attrs[attr_cnt].perm = BT_GATT_PERM_READ; + inst->attrs[attr_cnt].read = bt_gatt_attr_read_service; + inst->attrs[attr_cnt].user_data = (void *)csis_uuid; + attr_cnt++; + + /* Set SIRK declaration */ + inst->attrs[attr_cnt].uuid = chrc_uuid; + inst->attrs[attr_cnt].perm = BT_GATT_PERM_READ; + inst->attrs[attr_cnt].read = bt_gatt_attr_read_chrc; + inst->attrs[attr_cnt].user_data = (void *)&set_sirk_user_data; + attr_cnt++; + + /* Set SIRK value */ + inst->attrs[attr_cnt].uuid = sirk_uuid; + inst->attrs[attr_cnt].perm = BT_GATT_PERM_READ_ENCRYPT; + inst->attrs[attr_cnt].read = bt_audio_read_chrc; + inst->attrs[attr_cnt].user_data = (void *)&set_sirk_audio_user_data[idx]; + attr_cnt++; + + if (IS_ENABLED(CONFIG_BT_CSIP_SET_MEMBER_SIRK_NOTIFIABLE)) { + /* Set SIRK CCCD */ + inst->attrs[attr_cnt].uuid = ccc_uuid; + inst->attrs[attr_cnt].perm = BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT; + inst->attrs[attr_cnt].read = bt_gatt_attr_read_ccc; + inst->attrs[attr_cnt].write = bt_gatt_attr_write_ccc; + inst->attrs[attr_cnt].user_data = (void *)&set_sirk_audio_ccc_user_data[idx]; + attr_cnt++; + } + + if (param->set_size > 0U) { + /* Set Size declaration */ + inst->attrs[attr_cnt].uuid = chrc_uuid; + inst->attrs[attr_cnt].perm = BT_GATT_PERM_READ; + inst->attrs[attr_cnt].read = bt_gatt_attr_read_chrc; + inst->attrs[attr_cnt].user_data = (void *)&set_size_user_data; + attr_cnt++; + + /* Set Size value */ + inst->attrs[attr_cnt].uuid = size_uuid; + inst->attrs[attr_cnt].perm = BT_GATT_PERM_READ_ENCRYPT; + inst->attrs[attr_cnt].read = bt_audio_read_chrc; + inst->attrs[attr_cnt].user_data = (void *)&set_size_audio_user_data[idx]; + attr_cnt++; + + if (IS_ENABLED(CONFIG_BT_CSIP_SET_MEMBER_SIZE_NOTIFIABLE)) { + /* Set Size CCCD */ + inst->attrs[attr_cnt].uuid = ccc_uuid; + inst->attrs[attr_cnt].perm = BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT; + inst->attrs[attr_cnt].read = bt_gatt_attr_read_ccc; + inst->attrs[attr_cnt].write = bt_gatt_attr_write_ccc; + inst->attrs[attr_cnt].user_data = + (void *)&set_size_audio_ccc_user_data[idx]; + attr_cnt++; + } + } + if (param->lockable) { + /* Set lock declaration */ + inst->attrs[attr_cnt].uuid = chrc_uuid; + inst->attrs[attr_cnt].perm = BT_GATT_PERM_READ; + inst->attrs[attr_cnt].read = bt_gatt_attr_read_chrc; + inst->attrs[attr_cnt].user_data = (void *)&set_lock_user_data; + attr_cnt++; + + /* Set lock value */ + inst->attrs[attr_cnt].uuid = lock_uuid; + inst->attrs[attr_cnt].perm = BT_GATT_PERM_READ_ENCRYPT | BT_GATT_PERM_WRITE_ENCRYPT; + inst->attrs[attr_cnt].read = bt_audio_read_chrc; + inst->attrs[attr_cnt].write = bt_audio_write_chrc; + inst->attrs[attr_cnt].user_data = (void *)&set_lock_audio_user_data[idx]; + attr_cnt++; + + /* Set lock CCCD */ + inst->attrs[attr_cnt].uuid = ccc_uuid; + inst->attrs[attr_cnt].perm = BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT; + inst->attrs[attr_cnt].read = bt_gatt_attr_read_ccc; + inst->attrs[attr_cnt].write = bt_gatt_attr_write_ccc; + inst->attrs[attr_cnt].user_data = (void *)&set_lock_audio_ccc_user_data[idx]; + attr_cnt++; + } + + if (param->rank > 0U) { + /* Rank declaration */ + inst->attrs[attr_cnt].uuid = chrc_uuid; + inst->attrs[attr_cnt].perm = BT_GATT_PERM_READ; + inst->attrs[attr_cnt].read = bt_gatt_attr_read_chrc; + inst->attrs[attr_cnt].user_data = (void *)&rank_user_data; + attr_cnt++; + + /* Rank value */ + inst->attrs[attr_cnt].uuid = rank_uuid; + inst->attrs[attr_cnt].perm = BT_GATT_PERM_READ_ENCRYPT; + inst->attrs[attr_cnt].read = bt_audio_read_chrc; + inst->attrs[attr_cnt].user_data = (void *)&rank_audio_user_data[idx]; + attr_cnt++; + } + + inst->gatt_svc.attr_count = attr_cnt; +} + int bt_csip_set_member_register(const struct bt_csip_set_member_register_param *param, struct bt_csip_set_member_svc_inst **svc_inst) { @@ -933,18 +1058,19 @@ int bt_csip_set_member_register(const struct bt_csip_set_member_register_param * } inst = NULL; - ARRAY_FOR_EACH(svc_insts, i) { - if (svc_insts[i].service_p == NULL) { - inst = &svc_insts[i]; - - err = k_mutex_lock(&inst->mutex, K_NO_WAIT); - if (err != 0) { - /* Try the next */ - continue; - } + ARRAY_FOR_EACH_PTR(svc_insts, si) { + err = k_mutex_lock(&si->mutex, K_NO_WAIT); + if (err != 0) { + /* Try the next */ + continue; + } - inst->service_p = &csip_set_member_service_list[i]; + if (si->gatt_svc.attrs == NULL) { + inst = si; break; + } else { + err = k_mutex_unlock(&si->mutex); + __ASSERT(err == 0, "Failed to unlock mutex: %d", err); } } @@ -953,23 +1079,9 @@ int bt_csip_set_member_register(const struct bt_csip_set_member_register_param * return -ENOMEM; } - /* The removal of the optional characteristics should be done in reverse order of the order - * in BT_CSIP_SERVICE_DEFINITION, as that improves the performance of remove_csis_char, - * since it's easier to remove the last characteristic - */ - if (param->rank == 0U) { - remove_csis_char(BT_UUID_CSIS_RANK, inst->service_p); - } - - if (param->set_size == 0U) { - remove_csis_char(BT_UUID_CSIS_SET_SIZE, inst->service_p); - } - - if (!param->lockable) { - remove_csis_char(BT_UUID_CSIS_SET_LOCK, inst->service_p); - } + instantiate_service(inst, param); - err = bt_gatt_service_register(inst->service_p); + err = bt_gatt_service_register(&inst->gatt_svc); if (err != 0) { int mutex_err; @@ -1011,7 +1123,6 @@ int bt_csip_set_member_register(const struct bt_csip_set_member_register_param * int bt_csip_set_member_unregister(struct bt_csip_set_member_svc_inst *svc_inst) { - const struct bt_gatt_attr csis_definition[] = BT_CSIP_SERVICE_DEFINITION(svc_inst); int err; CHECKIF(svc_inst == NULL) { @@ -1025,7 +1136,7 @@ int bt_csip_set_member_unregister(struct bt_csip_set_member_svc_inst *svc_inst) return -EBUSY; } - err = bt_gatt_service_unregister(svc_inst->service_p); + err = bt_gatt_service_unregister(&svc_inst->gatt_svc); if (err != 0) { int mutex_err; @@ -1036,10 +1147,6 @@ int bt_csip_set_member_unregister(struct bt_csip_set_member_svc_inst *svc_inst) return err; } - /* Restore original declaration */ - (void)memcpy(svc_inst->service_p->attrs, csis_definition, sizeof(csis_definition)); - svc_inst->service_p->attr_count = ARRAY_SIZE(csis_definition); - (void)k_work_cancel_delayable(&svc_inst->set_lock_timer); memset(svc_inst, 0, offsetof(struct bt_csip_set_member_svc_inst, mutex)); diff --git a/tests/bsim/bluetooth/audio/src/csip_set_member_test.c b/tests/bsim/bluetooth/audio/src/csip_set_member_test.c index c001669eebe0..5f2526079182 100644 --- a/tests/bsim/bluetooth/audio/src/csip_set_member_test.c +++ b/tests/bsim/bluetooth/audio/src/csip_set_member_test.c @@ -290,12 +290,17 @@ static void test_new_set_size_and_rank(void) static void test_register(void) { - for (size_t iteration = 1; iteration <= 5; iteration++) { + for (size_t iteration = 0U; iteration < 5U; iteration++) { struct bt_csip_set_member_svc_inst *svc_insts[CONFIG_BT_CSIP_SET_MEMBER_MAX_INSTANCE_COUNT]; int err; - printk("Running iteration %zu\n", iteration); + printk("Running iteration %zu\n", iteration + 1); + + /* Run with different parameters for each iteration */ + param.lockable = !param.lockable; + param.rank = iteration % 2; + param.set_size = iteration % 3; ARRAY_FOR_EACH(svc_insts, i) { err = bt_csip_set_member_register(¶m, &svc_insts[i]); From 25c2aaef9b18bf9474cc1328a0f59e99187471bf Mon Sep 17 00:00:00 2001 From: Chris Friedt Date: Tue, 23 Dec 2025 09:55:12 -0500 Subject: [PATCH 2149/3659] posix: xsi: streams: deprecate CONFIG_XOPEN_STREAMS (again) CONFIG_XOPEN_STREAMS does not follow the pattern of other XSI Option Groups, where the Option Group name is not the same as the feature test macro that indicates it is supported by the implementation. Deprecate CONFIG_XOPEN_STREAMS and rename it to CONFIG_XSI_STREAMS. For more information, please see https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/\ V1_chap02.html#tag_02_01_05_09 Signed-off-by: Chris Friedt --- doc/services/portability/posix/conformance/index.rst | 2 +- doc/services/portability/posix/option_groups/index.rst | 2 +- lib/posix/options/CMakeLists.txt | 2 +- lib/posix/options/Kconfig.xsi_streams | 9 ++++++++- samples/modules/thrift/hello/client/prj.conf | 2 +- samples/modules/thrift/hello/server/prj.conf | 2 +- tests/modules/thrift/ThriftTest/prj.conf | 2 +- tests/posix/common/prj.conf | 2 +- tests/posix/eventfd/prj.conf | 2 +- tests/posix/xsi_streams/prj.conf | 2 +- 10 files changed, 17 insertions(+), 10 deletions(-) diff --git a/doc/services/portability/posix/conformance/index.rst b/doc/services/portability/posix/conformance/index.rst index 23faa7568fa0..cea2ed3d15b4 100644 --- a/doc/services/portability/posix/conformance/index.rst +++ b/doc/services/portability/posix/conformance/index.rst @@ -97,7 +97,7 @@ POSIX System Interfaces _XOPEN_CRYPT, -1, :ref:`_XOPEN_REALTIME `, 700, :kconfig:option:`CONFIG_XSI_REALTIME` _XOPEN_REALTIME_THREADS, -1, - :ref:`_XOPEN_STREAMS`, 200809L, :kconfig:option:`CONFIG_XOPEN_STREAMS` + :ref:`_XOPEN_STREAMS`, 200809L, :kconfig:option:`CONFIG_XSI_STREAMS` _XOPEN_UNIX, -1, diff --git a/doc/services/portability/posix/option_groups/index.rst b/doc/services/portability/posix/option_groups/index.rst index 695d57051da3..4f33044fad7b 100644 --- a/doc/services/portability/posix/option_groups/index.rst +++ b/doc/services/portability/posix/option_groups/index.rst @@ -1111,7 +1111,7 @@ implemented in Zephyr but are provided so that conformant applications can still Unimplemented functions in this option group will fail, setting ``errno`` to ``ENOSYS`` :ref:`†`. -Enable this option with :kconfig:option:`CONFIG_XOPEN_STREAMS`. +Enable this option with :kconfig:option:`CONFIG_XSI_STREAMS`. .. csv-table:: _XOPEN_STREAMS :header: API, Supported diff --git a/lib/posix/options/CMakeLists.txt b/lib/posix/options/CMakeLists.txt index c15d38d08d53..808a80fa448c 100644 --- a/lib/posix/options/CMakeLists.txt +++ b/lib/posix/options/CMakeLists.txt @@ -165,7 +165,7 @@ if(NOT CONFIG_TC_PROVIDES_XSI_REALTIME) zephyr_library_sources_ifdef(CONFIG_POSIX_SHARED_MEMORY_OBJECTS shm.c) endif() -zephyr_library_sources_ifdef(CONFIG_XOPEN_STREAMS stropts.c) +zephyr_library_sources_ifdef(CONFIG_XSI_STREAMS stropts.c) if(NOT CONFIG_TC_PROVIDES_XSI_SINGLE_PROCESS) zephyr_library_sources_ifdef(CONFIG_XSI_SINGLE_PROCESS diff --git a/lib/posix/options/Kconfig.xsi_streams b/lib/posix/options/Kconfig.xsi_streams index 21b7e2010b51..06088d48455b 100644 --- a/lib/posix/options/Kconfig.xsi_streams +++ b/lib/posix/options/Kconfig.xsi_streams @@ -2,7 +2,7 @@ # # SPDX-License-Identifier: Apache-2.0 -config XOPEN_STREAMS +config XSI_STREAMS bool "X/Open streams" help This option provides support for the X/Open Streams interface, including functions such as @@ -10,3 +10,10 @@ config XOPEN_STREAMS For more information, please see https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap02.html#tag_02_01_05_09 + +config XOPEN_STREAMS + bool "X/Open Streams [DEPRECATED]" + select XSI_STREAMS + select DEPRECATED + help + This option is deprecated. Please use XSI_STREAMS instead. diff --git a/samples/modules/thrift/hello/client/prj.conf b/samples/modules/thrift/hello/client/prj.conf index dea85eac5e0c..9a581877c2a7 100644 --- a/samples/modules/thrift/hello/client/prj.conf +++ b/samples/modules/thrift/hello/client/prj.conf @@ -5,7 +5,6 @@ CONFIG_CPP=y CONFIG_STD_CPP17=y CONFIG_CPP_EXCEPTIONS=y CONFIG_POSIX_API=y -CONFIG_XOPEN_STREAMS=y CONFIG_COMMON_LIBC_THRD=y CONFIG_DYNAMIC_THREAD=y CONFIG_THREAD_STACK_INFO=y @@ -14,6 +13,7 @@ CONFIG_NET_SOCKETS=y CONFIG_NET_SOCKETPAIR=y CONFIG_HEAP_MEM_POOL_SIZE=16384 CONFIG_EVENTFD=y +CONFIG_XSI_STREAMS=y CONFIG_THRIFT=y diff --git a/samples/modules/thrift/hello/server/prj.conf b/samples/modules/thrift/hello/server/prj.conf index e8f3044415f8..0f7c523db595 100644 --- a/samples/modules/thrift/hello/server/prj.conf +++ b/samples/modules/thrift/hello/server/prj.conf @@ -6,7 +6,7 @@ CONFIG_CPP=y CONFIG_STD_CPP17=y CONFIG_CPP_EXCEPTIONS=y CONFIG_POSIX_API=y -CONFIG_XOPEN_STREAMS=y +CONFIG_XSI_STREAMS=y CONFIG_NET_SOCKETPAIR=y CONFIG_HEAP_MEM_POOL_SIZE=16384 CONFIG_EVENTFD=y diff --git a/tests/modules/thrift/ThriftTest/prj.conf b/tests/modules/thrift/ThriftTest/prj.conf index a4727acced11..d7d5e5fdb8c9 100755 --- a/tests/modules/thrift/ThriftTest/prj.conf +++ b/tests/modules/thrift/ThriftTest/prj.conf @@ -7,7 +7,7 @@ CONFIG_STD_CPP17=y CONFIG_CPP_EXCEPTIONS=y CONFIG_GLIBCXX_LIBCPP=y CONFIG_POSIX_API=y -CONFIG_XOPEN_STREAMS=y +CONFIG_XSI_STREAMS=y CONFIG_NETWORKING=y CONFIG_NET_TCP=y CONFIG_NET_SOCKETS=y diff --git a/tests/posix/common/prj.conf b/tests/posix/common/prj.conf index f50d956f8b27..7c34c53b0e21 100644 --- a/tests/posix/common/prj.conf +++ b/tests/posix/common/prj.conf @@ -16,7 +16,7 @@ CONFIG_TEST_EXTRA_STACK_SIZE=4096 CONFIG_POSIX_C_LIB_EXT=y # for putmsg() -CONFIG_XOPEN_STREAMS=y +CONFIG_XSI_STREAMS=y # for sleep(), getpid() CONFIG_POSIX_MULTI_PROCESS=y diff --git a/tests/posix/eventfd/prj.conf b/tests/posix/eventfd/prj.conf index a5839a7a447a..d3c4ddb9296f 100644 --- a/tests/posix/eventfd/prj.conf +++ b/tests/posix/eventfd/prj.conf @@ -9,5 +9,5 @@ CONFIG_TEST_RANDOM_GENERATOR=y CONFIG_ZTEST=y CONFIG_POSIX_API=y -CONFIG_XOPEN_STREAMS=y +CONFIG_XSI_STREAMS=y CONFIG_EVENTFD=y diff --git a/tests/posix/xsi_streams/prj.conf b/tests/posix/xsi_streams/prj.conf index 6a39c38d1c68..ee23313bd295 100644 --- a/tests/posix/xsi_streams/prj.conf +++ b/tests/posix/xsi_streams/prj.conf @@ -2,4 +2,4 @@ CONFIG_POSIX_API=y CONFIG_ZTEST=y CONFIG_POSIX_AEP_CHOICE_BASE=y -CONFIG_XOPEN_STREAMS=y +CONFIG_XSI_STREAMS=y From c2cad209a308323309e38def8aa5f365ce49f4b0 Mon Sep 17 00:00:00 2001 From: Chris Friedt Date: Thu, 1 Jan 2026 20:54:08 -0500 Subject: [PATCH 2150/3659] posix: xsi_streams: add tc-provides-xsi-streams kconfig option Enable the toolchain to provide the XSI_STREAMS Option Group. Signed-off-by: Chris Friedt --- lib/posix/Kconfig.toolchain | 3 +++ lib/posix/options/CMakeLists.txt | 10 ++++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/lib/posix/Kconfig.toolchain b/lib/posix/Kconfig.toolchain index 4ee30a824654..e22d357b2a50 100644 --- a/lib/posix/Kconfig.toolchain +++ b/lib/posix/Kconfig.toolchain @@ -219,6 +219,9 @@ config TC_PROVIDES_XSI_SIGNALS config TC_PROVIDES_XSI_SINGLE_PROCESS bool +config TC_PROVIDES_XSI_STREAMS + bool + config TC_PROVIDES_XSI_SYSTEM_DATABASE bool diff --git a/lib/posix/options/CMakeLists.txt b/lib/posix/options/CMakeLists.txt index 808a80fa448c..b09b745982e5 100644 --- a/lib/posix/options/CMakeLists.txt +++ b/lib/posix/options/CMakeLists.txt @@ -1,6 +1,7 @@ # SPDX-License-Identifier: Apache-2.0 set(POSIX_VERSION 200809L) +set(XOPEN_VERSION 700) set(GEN_DIR ${ZEPHYR_BINARY_DIR}/include/generated) zephyr_compile_definitions(-D_POSIX_C_SOURCE=${POSIX_VERSION}) @@ -165,8 +166,6 @@ if(NOT CONFIG_TC_PROVIDES_XSI_REALTIME) zephyr_library_sources_ifdef(CONFIG_POSIX_SHARED_MEMORY_OBJECTS shm.c) endif() -zephyr_library_sources_ifdef(CONFIG_XSI_STREAMS stropts.c) - if(NOT CONFIG_TC_PROVIDES_XSI_SINGLE_PROCESS) zephyr_library_sources_ifdef(CONFIG_XSI_SINGLE_PROCESS env_common.c @@ -174,6 +173,13 @@ if(NOT CONFIG_TC_PROVIDES_XSI_SINGLE_PROCESS) ) endif() +if(NOT CONFIG_TC_PROVIDES_XSI_STREAMS) + zephyr_library_sources_ifdef(CONFIG_XSI_STREAMS stropts.c) +endif() +if(CONFIG_XSI_STREAMS) + zephyr_compile_definitions(-D_XOPEN_STREAMS=${XOPEN_VERSION}) +endif() + if(NOT CONFIG_TC_PROVIDES_XSI_SYSTEM_LOGGING) zephyr_library_sources_ifdef(CONFIG_XSI_SYSTEM_LOGGING syslog.c) endif() From e59a65386e537f849a76ff23176b777c3f70c74d Mon Sep 17 00:00:00 2001 From: Chris Friedt Date: Tue, 23 Dec 2025 09:55:20 -0500 Subject: [PATCH 2151/3659] doc: release: 4.4: deprecate CONFIG_XOPEN_STREAMS (again) Deprecate the CONFIG_XOPEN_STREAMS Kconfig option in favour of CONFIG_XSI_STREAMS, which matches the naming conventions of other XSI Kconfig options and the actual Option Group name in the specification. Please use CONFIG_XSI_STREAMS instead. Note: this option was originally deprecated prior to 4.3. Signed-off-by: Chris Friedt --- doc/releases/release-notes-4.4.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/releases/release-notes-4.4.rst b/doc/releases/release-notes-4.4.rst index 2adfbbb422bc..1742b0235f2d 100644 --- a/doc/releases/release-notes-4.4.rst +++ b/doc/releases/release-notes-4.4.rst @@ -85,6 +85,10 @@ Deprecated APIs and options :c:member:`bt_conn_le_info.interval_us` instead. Note that the units have changed: ``interval`` was in units of 1.25 milliseconds, while ``interval_us`` is in microseconds. +* POSIX + + * :kconfig:option:`CONFIG_XOPEN_STREAMS` was deprecated. Instead, use :kconfig:option:`CONFIG_XSI_STREAMS` + * Sensors * NXP From 8260974216f44a8550e9a8f89e3bc8e40486077d Mon Sep 17 00:00:00 2001 From: Holt Sun Date: Fri, 9 Jan 2026 15:21:03 +0800 Subject: [PATCH 2152/3659] soc: nxp: ke1xz: Add power management support Implement power management with IDLE, STOP, PSTOP1, and PSTOP2 modes. - Add power state definitions with timing parameters - Implement pm_state_set() with proper SLEEPDEEP handling - Add XIP-safe WFI execution from RAM - Enable SMC driver and power mode protection - Remove forced timer Kconfig defaults Signed-off-by: Holt Sun --- dts/arm/nxp/nxp_ke1xz.dtsi | 11 +++- .../mcux/mcux-sdk-ng/drivers/drivers.cmake | 1 + soc/nxp/kinetis/ke1xz/Kconfig.defconfig | 8 +-- soc/nxp/kinetis/ke1xz/power.c | 52 ++++++++++++++----- soc/nxp/kinetis/ke1xz/soc.c | 4 ++ 5 files changed, 56 insertions(+), 20 deletions(-) diff --git a/dts/arm/nxp/nxp_ke1xz.dtsi b/dts/arm/nxp/nxp_ke1xz.dtsi index f03c26c32a6d..a10d728de237 100644 --- a/dts/arm/nxp/nxp_ke1xz.dtsi +++ b/dts/arm/nxp/nxp_ke1xz.dtsi @@ -26,31 +26,40 @@ compatible = "arm,cortex-m0+"; clock-frequency = ; reg = <0>; - cpu-power-states = <&idle &stop &pstop1 &pstop2>; + cpu-power-states = <&idle &pstop2 &pstop1 &stop>; }; power-states { idle: idle { compatible = "zephyr,power-state"; power-state-name = "runtime-idle"; + min-residency-us = <10>; + /* 0.7 µs rounded */ + exit-latency-us = <1>; }; stop: stop { compatible = "zephyr,power-state"; power-state-name = "suspend-to-idle"; substate-id = <0>; + min-residency-us = <14>; + exit-latency-us = <140>; }; pstop1: pstop1 { compatible = "zephyr,power-state"; power-state-name = "suspend-to-idle"; substate-id = <1>; + min-residency-us = <13>; + exit-latency-us = <130>; }; pstop2: pstop2 { compatible = "zephyr,power-state"; power-state-name = "suspend-to-idle"; substate-id = <2>; + min-residency-us = <12>; + exit-latency-us = <120>; }; }; }; diff --git a/modules/hal_nxp/mcux/mcux-sdk-ng/drivers/drivers.cmake b/modules/hal_nxp/mcux/mcux-sdk-ng/drivers/drivers.cmake index c47f9bdb1d99..dd933fd635fb 100644 --- a/modules/hal_nxp/mcux/mcux-sdk-ng/drivers/drivers.cmake +++ b/modules/hal_nxp/mcux/mcux-sdk-ng/drivers/drivers.cmake @@ -69,6 +69,7 @@ set_variable_ifdef(CONFIG_ENTROPY_MCUX_TRNG CONFIG_MCUX_COMPONENT_driver.trn set_variable_ifdef(CONFIG_ENTROPY_MCUX_CAAM CONFIG_MCUX_COMPONENT_driver.caam) set_variable_ifdef(CONFIG_ETH_NXP_ENET CONFIG_MCUX_COMPONENT_driver.enet) set_variable_ifdef(CONFIG_SOC_SERIES_KINETIS_K2X CONFIG_MCUX_COMPONENT_driver.smc) +set_variable_ifdef(CONFIG_SOC_SERIES_KE1XZ CONFIG_MCUX_COMPONENT_driver.smc) set_variable_ifdef(CONFIG_I2C_MCUX CONFIG_MCUX_COMPONENT_driver.i2c) set_variable_ifdef(CONFIG_I2C_NXP_II2C CONFIG_MCUX_COMPONENT_driver.ii2c) set_variable_ifdef(CONFIG_I3C_MCUX CONFIG_MCUX_COMPONENT_driver.i3c) diff --git a/soc/nxp/kinetis/ke1xz/Kconfig.defconfig b/soc/nxp/kinetis/ke1xz/Kconfig.defconfig index 7bb46e3a9d09..48deae503faf 100644 --- a/soc/nxp/kinetis/ke1xz/Kconfig.defconfig +++ b/soc/nxp/kinetis/ke1xz/Kconfig.defconfig @@ -1,17 +1,11 @@ # Kinetis KE1xZ series configuration options # Copyright (c) 2019-2021 Vestas Wind Systems A/S -# Copyright 2024 NXP +# Copyright 2024-2025 NXP # SPDX-License-Identifier: Apache-2.0 if SOC_SERIES_KE1XZ -config MCUX_LPTMR_TIMER - default y if PM - -config CORTEX_M_SYSTICK - default n if MCUX_LPTMR_TIMER - config SYS_CLOCK_HW_CYCLES_PER_SEC default $(dt_node_int_prop_int,/cpus/cpu@0,clock-frequency) if CORTEX_M_SYSTICK default $(dt_node_int_prop_int,/soc/lptmr@40040000,clock-frequency) if MCUX_LPTMR_TIMER diff --git a/soc/nxp/kinetis/ke1xz/power.c b/soc/nxp/kinetis/ke1xz/power.c index 43aef2ebf0c3..97601a599c04 100644 --- a/soc/nxp/kinetis/ke1xz/power.c +++ b/soc/nxp/kinetis/ke1xz/power.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2021 Vestas Wind Systems A/S - * Copyright 2021, 2024 NXP + * Copyright 2021, 2024-2025 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -12,7 +12,8 @@ LOG_MODULE_DECLARE(power, CONFIG_PM_LOG_LEVEL); -__ramfunc static void wait_for_flash_prefetch_and_idle(void) +#ifdef CONFIG_XIP +__ramfunc static void wait_for_flash_prefetch_and_wfi(void) { uint32_t i; @@ -20,27 +21,54 @@ __ramfunc static void wait_for_flash_prefetch_and_idle(void) arch_nop(); } - k_cpu_idle(); + /* + * Must execute WFI directly from RAM when XIP is enabled. + * Calling k_cpu_idle() may jump back into flash. + */ + __DSB(); + __ISB(); + __WFI(); } +#endif /* CONFIG_XIP */ void pm_state_set(enum pm_state state, uint8_t substate_id) { switch (state) { case PM_STATE_RUNTIME_IDLE: - k_cpu_idle(); + /* Normal WAIT: WFI with SLEEPDEEP cleared. */ + SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk; + __DSB(); + __ISB(); + __WFI(); + irq_unlock(0); break; case PM_STATE_SUSPEND_TO_IDLE: - /* Set partial stop mode and enable deep sleep */ - SMC->STOPCTRL = SMC_STOPCTRL_PSTOPO(substate_id); - SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; - if (IS_ENABLED(CONFIG_XIP)) { - wait_for_flash_prefetch_and_idle(); - } else { - k_cpu_idle(); + if (substate_id > 2U) { + LOG_WRN("Unsupported substate-id %u, using 0", substate_id); + substate_id = 0U; } + /* Ensure STOPM is set to normal STOP (not VLPS/VLLS families), if present. */ + SMC->PMCTRL &= ~SMC_PMCTRL_STOPM_MASK; + +#if (defined(FSL_FEATURE_SMC_HAS_PSTOPO) && FSL_FEATURE_SMC_HAS_PSTOPO) + SMC->STOPCTRL = (SMC->STOPCTRL & ~SMC_STOPCTRL_PSTOPO_MASK) | + SMC_STOPCTRL_PSTOPO(substate_id); +#endif + + SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; + /* readback to complete bus writes */ + (void)SMC->PMCTRL; + __DSB(); + __ISB(); +#ifdef CONFIG_XIP + wait_for_flash_prefetch_and_wfi(); +#else + __WFI(); +#endif if (SMC->PMCTRL & SMC_PMCTRL_STOPA_MASK) { LOG_DBG("partial stop aborted"); } + irq_unlock(0); break; default: LOG_WRN("Unsupported power state %u", state); @@ -54,7 +82,7 @@ void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) if (state == PM_STATE_SUSPEND_TO_IDLE) { /* Disable deep sleep upon exit */ - SCB->SCR &= ~(SCB_SCR_SLEEPDEEP_Msk); + SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk; } irq_unlock(0); diff --git a/soc/nxp/kinetis/ke1xz/soc.c b/soc/nxp/kinetis/ke1xz/soc.c index 69bd7494c6ba..498ddd0a402f 100644 --- a/soc/nxp/kinetis/ke1xz/soc.c +++ b/soc/nxp/kinetis/ke1xz/soc.c @@ -14,6 +14,7 @@ #include #include #include +#include "fsl_smc.h" #define ASSERT_WITHIN_RANGE(val, min, max, str) BUILD_ASSERT(val >= min && val <= max, str) @@ -186,6 +187,9 @@ void soc_early_init_hook(void) { /* Initialize system clocks and PLL */ clk_init(); +#ifdef CONFIG_PM + SMC_SetPowerModeProtection(SMC, kSMC_AllowPowerModeAll); +#endif /* CONFIG_PM */ } #ifdef CONFIG_SOC_RESET_HOOK From 0037a5fc4bd6e61befd273e20eac17b87853f221 Mon Sep 17 00:00:00 2001 From: Holt Sun Date: Fri, 9 Jan 2026 15:25:02 +0800 Subject: [PATCH 2153/3659] boards: frdm_ke17z: Add power management support Enable power management using LPTMR0 as the idle timer. - Set zephyr,cortex-m-idle-timer to lptmr0 - Remove redundant stop state DTS overrides - Add power_mgmt_soc test configuration and overlay Signed-off-by: Holt Sun --- boards/nxp/frdm_ke17z/frdm_ke17z.dts | 8 ++---- .../pm/power_mgmt_soc/boards/frdm_ke17z.conf | 10 +++++++ .../power_mgmt_soc/boards/frdm_ke17z.overlay | 27 +++++++++++++++++++ 3 files changed, 39 insertions(+), 6 deletions(-) create mode 100644 tests/subsys/pm/power_mgmt_soc/boards/frdm_ke17z.conf create mode 100644 tests/subsys/pm/power_mgmt_soc/boards/frdm_ke17z.overlay diff --git a/boards/nxp/frdm_ke17z/frdm_ke17z.dts b/boards/nxp/frdm_ke17z/frdm_ke17z.dts index 173c2298a99a..91bdb0605ecd 100644 --- a/boards/nxp/frdm_ke17z/frdm_ke17z.dts +++ b/boards/nxp/frdm_ke17z/frdm_ke17z.dts @@ -1,5 +1,5 @@ /* - * Copyright 2024 NXP + * Copyright 2024-2025 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -36,6 +36,7 @@ zephyr,uart-mcumgr = &lpuart0; zephyr,console = &lpuart0; zephyr,shell-uart = &lpuart0; + zephyr,cortex-m-idle-timer = &lptmr0; }; leds { @@ -126,11 +127,6 @@ min-residency-us = <1>; }; -&stop { - min-residency-us = <20000>; - exit-latency-us = <13>; -}; - &lpuart0 { dmas = <&edma 1 2>, <&edma 2 3>; dma-names = "rx", "tx"; diff --git a/tests/subsys/pm/power_mgmt_soc/boards/frdm_ke17z.conf b/tests/subsys/pm/power_mgmt_soc/boards/frdm_ke17z.conf new file mode 100644 index 000000000000..39352d36ef68 --- /dev/null +++ b/tests/subsys/pm/power_mgmt_soc/boards/frdm_ke17z.conf @@ -0,0 +1,10 @@ +# Copyright 2025 NXP +# +# SPDX-License-Identifier: Apache-2.0 + +# Keep LPTMR as wake/idle timer via counter API +CONFIG_COUNTER=y +CONFIG_COUNTER_MCUX_LPTMR=y +CONFIG_COUNTER_MCUX_LPTMR_ALARM=y +CONFIG_PM_PREWAKEUP_CONV_MODE_CEIL=y +CONFIG_CORTEX_M_SYSTICK_RESET_BY_LPM=y diff --git a/tests/subsys/pm/power_mgmt_soc/boards/frdm_ke17z.overlay b/tests/subsys/pm/power_mgmt_soc/boards/frdm_ke17z.overlay new file mode 100644 index 000000000000..88f9299ebadc --- /dev/null +++ b/tests/subsys/pm/power_mgmt_soc/boards/frdm_ke17z.overlay @@ -0,0 +1,27 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&lptmr0 { + /delete-property/ prescale-glitch-filter-bypass; + prescale-glitch-filter = <4>; + status = "okay"; +}; + +&idle { + exit-latency-us = <100>; +}; + +&stop { + exit-latency-us = <500>; +}; + +&pstop1 { + exit-latency-us = <300>; +}; + +&pstop2 { + exit-latency-us = <200>; +}; From 982231a8fe4f4f04bc72e1cc8b088fd305455452 Mon Sep 17 00:00:00 2001 From: Nhut Nguyen Date: Wed, 17 Dec 2025 14:19:44 +0700 Subject: [PATCH 2154/3659] drivers: intc: renesas: Add gpio interrupt (tint) for RZ family Add support for gpio interrupt (tint) for Renesas RZ familiy. Signed-off-by: Nhut Nguyen --- drivers/interrupt_controller/CMakeLists.txt | 1 + .../interrupt_controller/Kconfig.renesas_rz | 29 +- .../intc_renesas_rz_tint.c | 256 ++++++++++++++++++ .../renesas,rz-intc-v2.yaml | 21 ++ .../interrupt-controller/renesas,rz-intc.yaml | 10 + .../interrupt-controller/renesas,rz-tint.yaml | 27 ++ .../interrupt_controller/intc_rz_tint.h | 66 +++++ 7 files changed, 409 insertions(+), 1 deletion(-) create mode 100644 drivers/interrupt_controller/intc_renesas_rz_tint.c create mode 100644 dts/bindings/interrupt-controller/renesas,rz-intc-v2.yaml create mode 100644 dts/bindings/interrupt-controller/renesas,rz-tint.yaml create mode 100644 include/zephyr/drivers/interrupt_controller/intc_rz_tint.h diff --git a/drivers/interrupt_controller/CMakeLists.txt b/drivers/interrupt_controller/CMakeLists.txt index 35b2de363f9c..073ebed42f66 100644 --- a/drivers/interrupt_controller/CMakeLists.txt +++ b/drivers/interrupt_controller/CMakeLists.txt @@ -60,6 +60,7 @@ zephyr_library_sources_ifdef(CONFIG_NXP_SIUL2_EIRQ intc_nxp_siul2_eirq.c) zephyr_library_sources_ifdef(CONFIG_PLIC intc_plic.c) zephyr_library_sources_ifdef(CONFIG_RENESAS_RX_ICU intc_renesas_rx_icu.c) zephyr_library_sources_ifdef(CONFIG_RENESAS_RZ_EXT_IRQ intc_renesas_rz_ext_irq.c) +zephyr_library_sources_ifdef(CONFIG_RENESAS_RZ_TINT intc_renesas_rz_tint.c) zephyr_library_sources_ifdef(CONFIG_RV32M1_INTMUX intc_rv32m1_intmux.c) zephyr_library_sources_ifdef(CONFIG_SAM0_EIC intc_sam0_eic.c) zephyr_library_sources_ifdef(CONFIG_SHARED_IRQ intc_shared_irq.c) diff --git a/drivers/interrupt_controller/Kconfig.renesas_rz b/drivers/interrupt_controller/Kconfig.renesas_rz index 9b13bd03df0b..a173478020c5 100644 --- a/drivers/interrupt_controller/Kconfig.renesas_rz +++ b/drivers/interrupt_controller/Kconfig.renesas_rz @@ -1,4 +1,4 @@ -# Copyright (c) 2024 Renesas Electronics Corporation +# Copyright (c) 2024-2025 Renesas Electronics Corporation # SPDX-License-Identifier: Apache-2.0 config RENESAS_RZ_EXT_IRQ @@ -20,3 +20,30 @@ config RENESAS_RZ_INTC_HAS_NMI Renesas RZ interrupt controller has NMI (Non Maskable Interrupt) pin endif + +config RENESAS_RZ_INTC_SELECT_INTERRUPT + bool "Renesas RZ INTC select interrupt" + default y + depends on DT_HAS_RENESAS_RZ_INTC_V2_ENABLED + help + Renesas RZ INTC select interrupt + +config RENESAS_RZ_TINT + bool "Renesas RZ GPIO interrupt (TINT) controller driver" + default y + depends on DT_HAS_RENESAS_RZ_TINT_ENABLED + help + Renesas RZ GPIO interrupt (TINT) controller driver + +if RENESAS_RZ_TINT + +config RENESAS_RZ_TINT_SUPPORT_STATUS_CLEAR_REG + bool "Renesas RZ TINT support status clear register" + default y + depends on DT_HAS_RENESAS_RZ_INTC_V2_ENABLED + help + Renesas RZ/V2H, RZ/V2N support a Status Clear Register + to reset interrupt flags, while the remaining SoCs + reset interrupt flags in the Status Register. + +endif diff --git a/drivers/interrupt_controller/intc_renesas_rz_tint.c b/drivers/interrupt_controller/intc_renesas_rz_tint.c new file mode 100644 index 000000000000..9254c05c5138 --- /dev/null +++ b/drivers/interrupt_controller/intc_renesas_rz_tint.c @@ -0,0 +1,256 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT renesas_rz_tint + +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(rz_intc, CONFIG_INTC_LOG_LEVEL); + +struct intc_rz_tint_config { + uint8_t tint; + uint8_t max_gpioint; + uint32_t irq; + uint32_t prio; +}; + +struct intc_rz_tint_data { + uint8_t port; + uint8_t pin; + uint8_t gpioint; + enum intc_rz_tint_trigger trigger_type; + intc_rz_tint_callback_t callback; + void *callback_data; +}; + +#define RZ_INTC_BASE DT_REG_ADDR(DT_NODELABEL(intc)) +#define RZ_INTC_TSCR (RZ_INTC_BASE + DT_REG_ADDR_BY_NAME(DT_NODELABEL(intc), tscr)) +#define RZ_INTC_TITSR0 (RZ_INTC_BASE + DT_REG_ADDR_BY_NAME(DT_NODELABEL(intc), titsr0)) +#define RZ_INTC_TSSR0 (RZ_INTC_BASE + DT_REG_ADDR_BY_NAME(DT_NODELABEL(intc), tssr0)) +#define RZ_INTC_INTSEL (RZ_INTC_BASE + DT_REG_ADDR_BY_NAME(DT_NODELABEL(intc), intsel)) + +#define REG_TITSR_READ(tint) sys_read32(RZ_INTC_TITSR0 + ((tint) / 16) * 4) +#define REG_TITSR_WRITE(tint, v) sys_write32((v), RZ_INTC_TITSR0 + ((tint) / 16) * 4) +#define REG_TITSR_TITSEL_MASK(tint) (BIT_MASK(2) << ((tint % 16) * 2)) + +#define REG_TSSR_READ(tint) sys_read32(RZ_INTC_TSSR0 + ((tint) / 4) * 4) +#define REG_TSSR_WRITE(tint, v) sys_write32((v), RZ_INTC_TSSR0 + ((tint) / 4) * 4) +#define REG_TSSR_TSSEL_MASK(tint) (BIT_MASK(7) << ((tint % 4) * 8)) +#define REG_TSSR_TIEN_MASK(tint) (BIT(7) << ((tint % 4) * 8)) + +#if defined(CONFIG_RENESAS_RZ_TINT_SUPPORT_STATUS_CLEAR_REG) +/* V2H, V2N */ +#define REG_TSCTR_READ(tint) sys_read32(RZ_INTC_TSCR) +#define REG_TSCLR_WRITE(tint, v) sys_write32((v), RZ_INTC_TSCR + 4) +#define TINT_STATUS_READ(tint) REG_TSCTR_READ(tint) +#define TINT_STATUS_CLEAR(tint) REG_TSCLR_WRITE(tint, TINT_STATUS_READ(tint) | BIT(tint)) +#else +#define REG_TSCR_READ(tint) sys_read32(RZ_INTC_TSCR) +#define REG_TSCR_WRITE(tint, v) sys_write32((v), RZ_INTC_TSCR) +#define TINT_STATUS_READ(tint) REG_TSCR_READ(tint) +#define TINT_STATUS_CLEAR(tint) REG_TSCR_WRITE(tint, TINT_STATUS_READ(tint) & ~BIT(tint)) +#endif + +#define OFFSET(irq) ((irq) - 353 - COND_CODE_1(CONFIG_GIC, (32), (0))) +#define REG_INTSEL_READ(irq) sys_read32(RZ_INTC_INTSEL + (OFFSET(irq) / 3) * 4) +#define REG_INTSEL_WRITE(irq, v) sys_write32((v), RZ_INTC_INTSEL + (OFFSET(irq) / 3) * 4) +#define REG_INTSEL_SPIk_SEL_MASK(irq) (BIT_MASK(10) << ((OFFSET(irq) % 3) * 10)) + +static const uint8_t gpioint_table[] = DT_PROP(DT_NODELABEL(intc), gpioint_table); + +static inline void intc_rz_tint_clear_irq_status(const struct device *dev) +{ + const struct intc_rz_tint_config *config = dev->config; + uint8_t tint = config->tint; + + TINT_STATUS_CLEAR(tint); + + /* + * User's manual: Clear Timing of Interrupt Cause + * Dummy read is required after write + */ + TINT_STATUS_READ(tint); +} + +int intc_rz_tint_enable(const struct device *dev) +{ + const struct intc_rz_tint_config *config = dev->config; + + irq_enable(config->irq); + + return 0; +} + +int intc_rz_tint_disable(const struct device *dev) +{ + const struct intc_rz_tint_config *config = dev->config; + + irq_disable(config->irq); + + return 0; +} + +int intc_rz_tint_set_type(const struct device *dev, enum intc_rz_tint_trigger trig) +{ + const struct intc_rz_tint_config *config = dev->config; + struct intc_rz_tint_data *data = dev->data; + uint8_t tint = config->tint; + uint32_t reg_val = REG_TITSR_READ(tint); + uint32_t flags = IRQ_TYPE_LEVEL; + uint32_t set = 0; + + switch (trig) { + case RZ_TINT_FAILING_EDGE: + set = 1; + break; + case RZ_TINT_RISING_EDGE: + set = 0; + break; + case RZ_TINT_LOW_LEVEL: + set = 3; + break; + case RZ_TINT_HIGH_LEVEL: + set = 2; + break; + case RZ_TINT_BOTH_EDGE: + default: + return -ENOTSUP; + } + + /* Select interrupt type */ + reg_val = (reg_val & ~REG_TITSR_TITSEL_MASK(tint)) | + FIELD_PREP(REG_TITSR_TITSEL_MASK(tint), set); + REG_TITSR_WRITE(tint, reg_val); + + /* + * User's manual: Precaution when Changing Interrupt Settings + * When changing the TINT interrupt detection method to the edge type, + * write 0 to the TSTATn bit of TSCR. + */ + if ((trig == RZ_TINT_RISING_EDGE) || (trig == RZ_TINT_FAILING_EDGE)) { + flags = IRQ_TYPE_EDGE; + intc_rz_tint_clear_irq_status(dev); + } + + /* Set interrupt type for GIC, and clear pending interrupt */ +#ifdef CONFIG_GIC + arm_gic_irq_set_priority(config->irq, config->prio, flags); + arm_gic_irq_clear_pending(config->irq); +#else + NVIC_ClearPendingIRQ(config->irq); +#endif + + data->trigger_type = trig; + + return 0; +} + +void intc_rz_tint_isr(const struct device *dev) +{ + const struct intc_rz_tint_config *config = dev->config; + struct intc_rz_tint_data *data = dev->data; + + intc_rz_tint_clear_irq_status(dev); + + /* Clear pending interrupt */ +#ifdef CONFIG_GIC + arm_gic_irq_clear_pending(config->irq); +#else + NVIC_ClearPendingIRQ(config->irq); +#endif + + if (data->callback) { + data->callback(data->callback_data); + } +} + +static int intc_rz_tint_init(const struct device *dev) +{ + struct intc_rz_tint_data *data = dev->data; + +#if defined(CONFIG_RENESAS_RZ_INTC_SELECT_INTERRUPT) + const struct intc_rz_tint_config *config = dev->config; + uint8_t tint = config->tint; + uint32_t irq = config->irq; + uint32_t reg_val = REG_INTSEL_READ(irq); + + reg_val &= ~REG_INTSEL_SPIk_SEL_MASK(irq); + reg_val |= FIELD_PREP(REG_INTSEL_SPIk_SEL_MASK(irq), tint); + + REG_INTSEL_WRITE(irq, reg_val); +#endif + return intc_rz_tint_set_type(dev, data->trigger_type); +}; + +int intc_rz_tint_connect(const struct device *dev, uint8_t port, uint8_t pin) +{ + const struct intc_rz_tint_config *config = dev->config; + struct intc_rz_tint_data *data = dev->data; + + uint8_t tint = config->tint; + + /* Map to GPIOINT */ + uint8_t gpioint = gpioint_table[port] + pin; + + if (gpioint > config->max_gpioint) { + return -EINVAL; + } + + uint32_t reg_val = REG_TSSR_READ(tint); + + reg_val &= ~(REG_TSSR_TSSEL_MASK(tint) | REG_TSSR_TIEN_MASK(tint)); + reg_val |= FIELD_PREP(REG_TSSR_TSSEL_MASK(tint), gpioint); + reg_val |= FIELD_PREP(REG_TSSR_TIEN_MASK(tint), 1U); + REG_TSSR_WRITE(tint, reg_val); + + data->gpioint = gpioint; + data->port = port; + data->pin = pin; + + return 0; +} + +int intc_rz_tint_set_callback(const struct device *dev, intc_rz_tint_callback_t cb, void *arg) +{ + struct intc_rz_tint_data *data = dev->data; + + data->callback = cb; + data->callback_data = arg; + + return 0; +} + +#define TINT_RZ_IRQ_CONNECT(index, isr) \ + IRQ_CONNECT(DT_INST_IRQ_BY_IDX(index, 0, irq), DT_INST_IRQ_BY_IDX(index, 0, priority), \ + isr, DEVICE_DT_INST_GET(index), \ + COND_CODE_1(CONFIG_GIC, (DT_INST_IRQ_BY_IDX(index, 0, flags)), (0))); + +#define INTC_RZ_TINT_INIT(index) \ + static const struct intc_rz_tint_config intc_rz_tint_config##index = { \ + .tint = DT_INST_REG_ADDR(index), \ + .irq = DT_INST_IRQ_BY_IDX(index, 0, irq), \ + .prio = DT_INST_IRQ_BY_IDX(index, 0, priority), \ + .max_gpioint = DT_PROP(DT_INST_PARENT(index), max_gpioint), \ + }; \ + struct intc_rz_tint_data intc_rz_tint_data##index = { \ + .trigger_type = DT_INST_ENUM_IDX_OR(index, trigger_type, 0), \ + }; \ + static int intc_rz_tint_init##index(const struct device *dev) \ + { \ + TINT_RZ_IRQ_CONNECT(index, intc_rz_tint_isr) \ + return intc_rz_tint_init(dev); \ + }; \ + \ + DEVICE_DT_INST_DEFINE(index, intc_rz_tint_init##index, NULL, &intc_rz_tint_data##index, \ + &intc_rz_tint_config##index, PRE_KERNEL_2, \ + CONFIG_INTC_INIT_PRIORITY, NULL); + +DT_INST_FOREACH_STATUS_OKAY(INTC_RZ_TINT_INIT) diff --git a/dts/bindings/interrupt-controller/renesas,rz-intc-v2.yaml b/dts/bindings/interrupt-controller/renesas,rz-intc-v2.yaml new file mode 100644 index 000000000000..89dd3636802b --- /dev/null +++ b/dts/bindings/interrupt-controller/renesas,rz-intc-v2.yaml @@ -0,0 +1,21 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +description: Renesas RZ Interrupt Controller +compatible: "renesas,rz-intc-v2" + +include: base.yaml + +properties: + reg: + required: true + + reg-names: + required: true + + gpioint-table: + type: array + + max-gpioint: + required: true + type: int diff --git a/dts/bindings/interrupt-controller/renesas,rz-intc.yaml b/dts/bindings/interrupt-controller/renesas,rz-intc.yaml index 9505c8001843..e40ee7f5eb2d 100644 --- a/dts/bindings/interrupt-controller/renesas,rz-intc.yaml +++ b/dts/bindings/interrupt-controller/renesas,rz-intc.yaml @@ -9,3 +9,13 @@ include: base.yaml properties: reg: required: true + + reg-names: + required: true + + gpioint-table: + type: array + + max-gpioint: + required: true + type: int diff --git a/dts/bindings/interrupt-controller/renesas,rz-tint.yaml b/dts/bindings/interrupt-controller/renesas,rz-tint.yaml new file mode 100644 index 000000000000..e0991c69fcde --- /dev/null +++ b/dts/bindings/interrupt-controller/renesas,rz-tint.yaml @@ -0,0 +1,27 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +description: Renesas RZ GPIO interrupt (TINT) controller + +compatible: "renesas,rz-tint" + +include: base.yaml + +properties: + trigger-type: + required: true + type: string + description: | + Indicates the condition that will trigger an interrupt when detected. + enum: + - "rising" + - "falling" + - "high_level" + - "low_level" + + "#irq-cells": + type: int + const: 1 + +irq-cells: + - pin diff --git a/include/zephyr/drivers/interrupt_controller/intc_rz_tint.h b/include/zephyr/drivers/interrupt_controller/intc_rz_tint.h new file mode 100644 index 000000000000..c3d39be9fbe7 --- /dev/null +++ b/include/zephyr/drivers/interrupt_controller/intc_rz_tint.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +enum intc_rz_tint_trigger { + /** Interrupt triggered on falling edge */ + RZ_TINT_FAILING_EDGE, + /** Interrupt triggered on rising edge */ + RZ_TINT_RISING_EDGE, + /** Interrupt triggered on both edges */ + RZ_TINT_BOTH_EDGE, + /** Interrupt triggered on low-level */ + RZ_TINT_LOW_LEVEL, + /** Interrupt triggered on high-level */ + RZ_TINT_HIGH_LEVEL, +}; + +/** RZ GPIO interrupt (TINT) callback */ +typedef void (*intc_rz_tint_callback_t)(void *arg); + +/** + * @brief Connect a TINT channel to a specific GPIO pins + * + * @param dev: pointer to interrupt controller instance + * @param port: GPIO port + * @param pin: GPIO pin + * @return 0 on success, or negative value on error + */ +int intc_rz_tint_connect(const struct device *dev, uint8_t port, uint8_t pin); + +/** + * @brief Change trigger interrupt type + * + * @param dev: pointer to interrupt controller instance + * @param trig: trigger type to be changed + * @return 0 on success, or negative value on error + */ +int intc_rz_tint_set_type(const struct device *dev, enum intc_rz_tint_trigger trig); + +/** + * @brief Enable TINT interrupt. + * + * @param dev: pointer to interrupt controller instance + * @return 0 on success, or negative value on error + */ +int intc_rz_tint_enable(const struct device *dev); + +/** + * @brief Disable TINT interrupt. + * + * @param dev: pointer to interrupt controller instance + * @return 0 on success, or negative value on error + */ +int intc_rz_tint_disable(const struct device *dev); + +/** + * @brief Updates the user callback + * + * @param dev: pointer to interrupt controller instance + * @param cb: callback to set + * @param arg: user data passed to callback + * @return 0 on success, or negative value on error + */ +int intc_rz_tint_set_callback(const struct device *dev, intc_rz_tint_callback_t cb, void *arg); From 76d3333d22b635d4c165d0c2d5d10315664424de Mon Sep 17 00:00:00 2001 From: Nhut Nguyen Date: Thu, 18 Dec 2025 13:42:08 +0700 Subject: [PATCH 2155/3659] dts: renesas: Add interrupt controller nodes for RZ family Add interrupt controller `intc` and `tint` nodes for Renesas RZ family. Signed-off-by: Nhut Nguyen --- dts/arm/renesas/rz/rzg/r9a07g043.dtsi | 303 ++++++++++++++++++++ dts/arm/renesas/rz/rzg/r9a07g044.dtsi | 304 +++++++++++++++++++++ dts/arm/renesas/rz/rzg/r9a08g045.dtsi | 297 +++++++++++++++++++- dts/arm/renesas/rz/rzv/r9a07g054.dtsi | 298 +++++++++++++++++++- dts/arm/renesas/rz/rzv/r9a09g056.dtsi | 299 +++++++++++++++++++- dts/arm/renesas/rz/rzv/r9a09g057_cm33.dtsi | 299 +++++++++++++++++++- dts/arm/renesas/rz/rzv/r9a09g057_cr8.dtsi | 299 +++++++++++++++++++- dts/arm64/renesas/rz/rza/r9a07g063.dtsi | 297 +++++++++++++++++++- 8 files changed, 2387 insertions(+), 9 deletions(-) diff --git a/dts/arm/renesas/rz/rzg/r9a07g043.dtsi b/dts/arm/renesas/rz/rzg/r9a07g043.dtsi index de1500ab9ad9..ab34fb3bb9c0 100644 --- a/dts/arm/renesas/rz/rzg/r9a07g043.dtsi +++ b/dts/arm/renesas/rz/rzg/r9a07g043.dtsi @@ -268,6 +268,309 @@ interrupt-names = "eri", "bri", "rxi", "txi", "tei"; status = "disabled"; }; + + intc: intc@410b0000 { + compatible = "renesas,rz-intc"; + reg = <0x410b0000 DT_SIZE_K(64)>, + <0x20 0x4>, + <0x24 0x4>, + <0x30 0x4>; + reg-names = "intc", "tscr", "titsr0", "tssr0"; + gpioint-table = <0 4 9 13 17 23 28 33 38 43 + 47 52 56 58 63 66 70 72 76>; + max-gpioint = <81>; + #address-cells = <1>; + #size-cells = <0>; + interrupt-parent = <&nvic>; + + tint0: tint0@0 { + compatible = "renesas,rz-tint"; + reg = <0x0>; + interrupts = <444 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint1: tint1@1 { + compatible = "renesas,rz-tint"; + reg = <0x1>; + interrupts = <445 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint2: tint2@2 { + compatible = "renesas,rz-tint"; + reg = <0x2>; + interrupts = <446 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint3: tint3@3 { + compatible = "renesas,rz-tint"; + reg = <0x3>; + interrupts = <447 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint4: tint4@4 { + compatible = "renesas,rz-tint"; + reg = <0x4>; + interrupts = <448 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint5: tint5@5 { + compatible = "renesas,rz-tint"; + reg = <0x5>; + interrupts = <449 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint6: tint6@6 { + compatible = "renesas,rz-tint"; + reg = <0x6>; + interrupts = <450 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint7: tint7@7 { + compatible = "renesas,rz-tint"; + reg = <0x7>; + interrupts = <451 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint8: tint8@8 { + compatible = "renesas,rz-tint"; + reg = <0x8>; + interrupts = <452 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint9: tint9@9 { + compatible = "renesas,rz-tint"; + reg = <0x9>; + interrupts = <453 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint10: tint10@a { + compatible = "renesas,rz-tint"; + reg = <0xa>; + interrupts = <454 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint11: tint11@b { + compatible = "renesas,rz-tint"; + reg = <0xb>; + interrupts = <455 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint12: tint12@c { + compatible = "renesas,rz-tint"; + reg = <0xc>; + interrupts = <456 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint13: tint13@d { + compatible = "renesas,rz-tint"; + reg = <0xd>; + interrupts = <457 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint14: tint14@e { + compatible = "renesas,rz-tint"; + reg = <0xe>; + interrupts = <458 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint15: tint15@f { + compatible = "renesas,rz-tint"; + reg = <0xf>; + interrupts = <459 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint16: tint16@10 { + compatible = "renesas,rz-tint"; + reg = <0x10>; + interrupts = <460 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint17: tint17@11 { + compatible = "renesas,rz-tint"; + reg = <0x11>; + interrupts = <461 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint18: tint18@12 { + compatible = "renesas,rz-tint"; + reg = <0x12>; + interrupts = <462 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint19: tint19@13 { + compatible = "renesas,rz-tint"; + reg = <0x13>; + interrupts = <463 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint20: tint20@14 { + compatible = "renesas,rz-tint"; + reg = <0x14>; + interrupts = <464 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint21: tint21@15 { + compatible = "renesas,rz-tint"; + reg = <0x15>; + interrupts = <465 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint22: tint22@16 { + compatible = "renesas,rz-tint"; + reg = <0x16>; + interrupts = <466 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint23: tint23@17 { + compatible = "renesas,rz-tint"; + reg = <0x17>; + interrupts = <467 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint24: tint24@18 { + compatible = "renesas,rz-tint"; + reg = <0x18>; + interrupts = <468 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint25: tint25@19 { + compatible = "renesas,rz-tint"; + reg = <0x19>; + interrupts = <469 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint26: tint26@1a { + compatible = "renesas,rz-tint"; + reg = <0x1a>; + interrupts = <470 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint27: tint27@1b { + compatible = "renesas,rz-tint"; + reg = <0x1b>; + interrupts = <471 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint28: tint28@1c { + compatible = "renesas,rz-tint"; + reg = <0x1c>; + interrupts = <472 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint29: tint29@1d { + compatible = "renesas,rz-tint"; + reg = <0x1d>; + interrupts = <473 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint30: tint30@1e { + compatible = "renesas,rz-tint"; + reg = <0x1e>; + interrupts = <474 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint31: tint31@1f { + compatible = "renesas,rz-tint"; + reg = <0x1f>; + interrupts = <475 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + }; }; }; diff --git a/dts/arm/renesas/rz/rzg/r9a07g044.dtsi b/dts/arm/renesas/rz/rzg/r9a07g044.dtsi index 09c897341a32..c45c80e42611 100644 --- a/dts/arm/renesas/rz/rzg/r9a07g044.dtsi +++ b/dts/arm/renesas/rz/rzg/r9a07g044.dtsi @@ -682,6 +682,310 @@ status = "disabled"; }; }; + + intc: intc@410b0000 { + compatible = "renesas,rz-intc"; + reg = <0x410b0000 DT_SIZE_K(64)>, + <0x20 0x4>, + <0x24 0x4>, + <0x30 0x4>; + reg-names = "intc", "tscr", "titsr0", "tssr0"; + gpioint-table = <0 2 4 6 8 10 13 15 18 21 23 25 27 29 32 34 36 + 38 41 43 45 48 50 52 54 56 58 60 62 64 66 68 70 72 + 74 76 78 80 83 85 88 91 93 98 102 106 110 114 118>; + max-gpioint = <122>; + #address-cells = <1>; + #size-cells = <0>; + interrupt-parent = <&nvic>; + + tint0: tint0@0 { + compatible = "renesas,rz-tint"; + reg = <0x0>; + interrupts = <444 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint1: tint1@1 { + compatible = "renesas,rz-tint"; + reg = <0x1>; + interrupts = <445 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint2: tint2@2 { + compatible = "renesas,rz-tint"; + reg = <0x2>; + interrupts = <446 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint3: tint3@3 { + compatible = "renesas,rz-tint"; + reg = <0x3>; + interrupts = <447 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint4: tint4@4 { + compatible = "renesas,rz-tint"; + reg = <0x4>; + interrupts = <448 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint5: tint5@5 { + compatible = "renesas,rz-tint"; + reg = <0x5>; + interrupts = <449 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint6: tint6@6 { + compatible = "renesas,rz-tint"; + reg = <0x6>; + interrupts = <450 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint7: tint7@7 { + compatible = "renesas,rz-tint"; + reg = <0x7>; + interrupts = <451 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint8: tint8@8 { + compatible = "renesas,rz-tint"; + reg = <0x8>; + interrupts = <452 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint9: tint9@9 { + compatible = "renesas,rz-tint"; + reg = <0x9>; + interrupts = <453 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint10: tint10@a { + compatible = "renesas,rz-tint"; + reg = <0xa>; + interrupts = <454 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint11: tint11@b { + compatible = "renesas,rz-tint"; + reg = <0xb>; + interrupts = <455 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint12: tint12@c { + compatible = "renesas,rz-tint"; + reg = <0xc>; + interrupts = <456 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint13: tint13@d { + compatible = "renesas,rz-tint"; + reg = <0xd>; + interrupts = <457 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint14: tint14@e { + compatible = "renesas,rz-tint"; + reg = <0xe>; + interrupts = <458 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint15: tint15@f { + compatible = "renesas,rz-tint"; + reg = <0xf>; + interrupts = <459 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint16: tint16@10 { + compatible = "renesas,rz-tint"; + reg = <0x10>; + interrupts = <460 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint17: tint17@11 { + compatible = "renesas,rz-tint"; + reg = <0x11>; + interrupts = <461 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint18: tint18@12 { + compatible = "renesas,rz-tint"; + reg = <0x12>; + interrupts = <462 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint19: tint19@13 { + compatible = "renesas,rz-tint"; + reg = <0x13>; + interrupts = <463 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint20: tint20@14 { + compatible = "renesas,rz-tint"; + reg = <0x14>; + interrupts = <464 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint21: tint21@15 { + compatible = "renesas,rz-tint"; + reg = <0x15>; + interrupts = <465 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint22: tint22@16 { + compatible = "renesas,rz-tint"; + reg = <0x16>; + interrupts = <466 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint23: tint23@17 { + compatible = "renesas,rz-tint"; + reg = <0x17>; + interrupts = <467 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint24: tint24@18 { + compatible = "renesas,rz-tint"; + reg = <0x18>; + interrupts = <468 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint25: tint25@19 { + compatible = "renesas,rz-tint"; + reg = <0x19>; + interrupts = <469 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint26: tint26@1a { + compatible = "renesas,rz-tint"; + reg = <0x1a>; + interrupts = <470 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint27: tint27@1b { + compatible = "renesas,rz-tint"; + reg = <0x1b>; + interrupts = <471 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint28: tint28@1c { + compatible = "renesas,rz-tint"; + reg = <0x1c>; + interrupts = <472 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint29: tint29@1d { + compatible = "renesas,rz-tint"; + reg = <0x1d>; + interrupts = <473 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint30: tint30@1e { + compatible = "renesas,rz-tint"; + reg = <0x1e>; + interrupts = <474 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint31: tint31@1f { + compatible = "renesas,rz-tint"; + reg = <0x1f>; + interrupts = <475 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + }; }; }; diff --git a/dts/arm/renesas/rz/rzg/r9a08g045.dtsi b/dts/arm/renesas/rz/rzg/r9a08g045.dtsi index da303200dbb2..14e041e58b95 100644 --- a/dts/arm/renesas/rz/rzg/r9a08g045.dtsi +++ b/dts/arm/renesas/rz/rzg/r9a08g045.dtsi @@ -875,11 +875,306 @@ intc: intc@41060000 { compatible = "renesas,rz-intc"; - reg = <0x41060000 DT_SIZE_K(64)>; + reg = <0x41060000 DT_SIZE_K(64)>, + <0x20 0x4>, + <0x24 0x4>, + <0x30 0x4>; + reg-names = "intc", "tscr", "titsr0", "tssr0"; + gpioint-table = <0 4 9 13 17 23 28 33 38 43 + 47 52 56 58 63 66 70 72 76>; + max-gpioint = <81>; #address-cells = <1>; #size-cells = <0>; interrupt-parent = <&nvic>; + tint0: tint0@0 { + compatible = "renesas,rz-tint"; + reg = <0x0>; + interrupts = <429 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint1: tint1@1 { + compatible = "renesas,rz-tint"; + reg = <0x1>; + interrupts = <430 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint2: tint2@2 { + compatible = "renesas,rz-tint"; + reg = <0x2>; + interrupts = <431 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint3: tint3@3 { + compatible = "renesas,rz-tint"; + reg = <0x3>; + interrupts = <432 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint4: tint4@4 { + compatible = "renesas,rz-tint"; + reg = <0x4>; + interrupts = <433 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint5: tint5@5 { + compatible = "renesas,rz-tint"; + reg = <0x5>; + interrupts = <434 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint6: tint6@6 { + compatible = "renesas,rz-tint"; + reg = <0x6>; + interrupts = <435 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint7: tint7@7 { + compatible = "renesas,rz-tint"; + reg = <0x7>; + interrupts = <436 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint8: tint8@8 { + compatible = "renesas,rz-tint"; + reg = <0x8>; + interrupts = <437 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint9: tint9@9 { + compatible = "renesas,rz-tint"; + reg = <0x9>; + interrupts = <438 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint10: tint10@a { + compatible = "renesas,rz-tint"; + reg = <0xa>; + interrupts = <439 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint11: tint11@b { + compatible = "renesas,rz-tint"; + reg = <0xb>; + interrupts = <440 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint12: tint12@c { + compatible = "renesas,rz-tint"; + reg = <0xc>; + interrupts = <441 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint13: tint13@d { + compatible = "renesas,rz-tint"; + reg = <0xd>; + interrupts = <442 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint14: tint14@e { + compatible = "renesas,rz-tint"; + reg = <0xe>; + interrupts = <443 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint15: tint15@f { + compatible = "renesas,rz-tint"; + reg = <0xf>; + interrupts = <444 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint16: tint16@10 { + compatible = "renesas,rz-tint"; + reg = <0x10>; + interrupts = <445 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint17: tint17@11 { + compatible = "renesas,rz-tint"; + reg = <0x11>; + interrupts = <446 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint18: tint18@12 { + compatible = "renesas,rz-tint"; + reg = <0x12>; + interrupts = <447 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint19: tint19@13 { + compatible = "renesas,rz-tint"; + reg = <0x13>; + interrupts = <448 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint20: tint20@14 { + compatible = "renesas,rz-tint"; + reg = <0x14>; + interrupts = <449 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint21: tint21@15 { + compatible = "renesas,rz-tint"; + reg = <0x15>; + interrupts = <450 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint22: tint22@16 { + compatible = "renesas,rz-tint"; + reg = <0x16>; + interrupts = <451 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint23: tint23@17 { + compatible = "renesas,rz-tint"; + reg = <0x17>; + interrupts = <452 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint24: tint24@18 { + compatible = "renesas,rz-tint"; + reg = <0x18>; + interrupts = <453 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint25: tint25@19 { + compatible = "renesas,rz-tint"; + reg = <0x19>; + interrupts = <454 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint26: tint26@1a { + compatible = "renesas,rz-tint"; + reg = <0x1a>; + interrupts = <455 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint27: tint27@1b { + compatible = "renesas,rz-tint"; + reg = <0x1b>; + interrupts = <456 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint28: tint28@1c { + compatible = "renesas,rz-tint"; + reg = <0x1c>; + interrupts = <457 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint29: tint29@1d { + compatible = "renesas,rz-tint"; + reg = <0x1d>; + interrupts = <458 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint30: tint30@1e { + compatible = "renesas,rz-tint"; + reg = <0x1e>; + interrupts = <459 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint31: tint31@1f { + compatible = "renesas,rz-tint"; + reg = <0x1f>; + interrupts = <460 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + nmi: nmi { compatible = "renesas,rz-ext-irq"; interrupt-controller; diff --git a/dts/arm/renesas/rz/rzv/r9a07g054.dtsi b/dts/arm/renesas/rz/rzv/r9a07g054.dtsi index 28924790ac50..c59cbfdb3a96 100644 --- a/dts/arm/renesas/rz/rzv/r9a07g054.dtsi +++ b/dts/arm/renesas/rz/rzv/r9a07g054.dtsi @@ -873,7 +873,15 @@ intc: intc@410b0000 { compatible = "renesas,rz-intc"; - reg = <0x410b0000 DT_SIZE_K(64)>; + reg = <0x410b0000 DT_SIZE_K(64)>, + <0x20 0x4>, + <0x24 0x4>, + <0x30 0x4>; + reg-names = "intc", "tscr", "titsr0", "tssr0"; + gpioint-table = <0 2 4 6 8 10 13 15 18 21 23 25 27 29 32 34 36 + 38 41 43 45 48 50 52 54 56 58 60 62 64 66 68 70 72 + 74 76 78 80 83 85 88 91 93 98 102 106 110 114 118>; + max-gpioint = <122>; #address-cells = <1>; #size-cells = <0>; interrupt-parent = <&nvic>; @@ -949,6 +957,294 @@ interrupts = <8 1>; status = "disabled"; }; + + tint0: tint0@0 { + compatible = "renesas,rz-tint"; + reg = <0x0>; + interrupts = <444 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint1: tint1@1 { + compatible = "renesas,rz-tint"; + reg = <0x1>; + interrupts = <445 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint2: tint2@2 { + compatible = "renesas,rz-tint"; + reg = <0x2>; + interrupts = <446 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint3: tint3@3 { + compatible = "renesas,rz-tint"; + reg = <0x3>; + interrupts = <447 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint4: tint4@4 { + compatible = "renesas,rz-tint"; + reg = <0x4>; + interrupts = <448 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint5: tint5@5 { + compatible = "renesas,rz-tint"; + reg = <0x5>; + interrupts = <449 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint6: tint6@6 { + compatible = "renesas,rz-tint"; + reg = <0x6>; + interrupts = <450 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint7: tint7@7 { + compatible = "renesas,rz-tint"; + reg = <0x7>; + interrupts = <451 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint8: tint8@8 { + compatible = "renesas,rz-tint"; + reg = <0x8>; + interrupts = <452 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint9: tint9@9 { + compatible = "renesas,rz-tint"; + reg = <0x9>; + interrupts = <453 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint10: tint10@a { + compatible = "renesas,rz-tint"; + reg = <0xa>; + interrupts = <454 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint11: tint11@b { + compatible = "renesas,rz-tint"; + reg = <0xb>; + interrupts = <455 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint12: tint12@c { + compatible = "renesas,rz-tint"; + reg = <0xc>; + interrupts = <456 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint13: tint13@d { + compatible = "renesas,rz-tint"; + reg = <0xd>; + interrupts = <457 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint14: tint14@e { + compatible = "renesas,rz-tint"; + reg = <0xe>; + interrupts = <458 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint15: tint15@f { + compatible = "renesas,rz-tint"; + reg = <0xf>; + interrupts = <459 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint16: tint16@10 { + compatible = "renesas,rz-tint"; + reg = <0x10>; + interrupts = <460 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint17: tint17@11 { + compatible = "renesas,rz-tint"; + reg = <0x11>; + interrupts = <461 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint18: tint18@12 { + compatible = "renesas,rz-tint"; + reg = <0x12>; + interrupts = <462 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint19: tint19@13 { + compatible = "renesas,rz-tint"; + reg = <0x13>; + interrupts = <463 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint20: tint20@14 { + compatible = "renesas,rz-tint"; + reg = <0x14>; + interrupts = <464 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint21: tint21@15 { + compatible = "renesas,rz-tint"; + reg = <0x15>; + interrupts = <465 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint22: tint22@16 { + compatible = "renesas,rz-tint"; + reg = <0x16>; + interrupts = <466 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint23: tint23@17 { + compatible = "renesas,rz-tint"; + reg = <0x17>; + interrupts = <467 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint24: tint24@18 { + compatible = "renesas,rz-tint"; + reg = <0x18>; + interrupts = <468 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint25: tint25@19 { + compatible = "renesas,rz-tint"; + reg = <0x19>; + interrupts = <469 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint26: tint26@1a { + compatible = "renesas,rz-tint"; + reg = <0x1a>; + interrupts = <470 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint27: tint27@1b { + compatible = "renesas,rz-tint"; + reg = <0x1b>; + interrupts = <471 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint28: tint28@1c { + compatible = "renesas,rz-tint"; + reg = <0x1c>; + interrupts = <472 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint29: tint29@1d { + compatible = "renesas,rz-tint"; + reg = <0x1d>; + interrupts = <473 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint30: tint30@1e { + compatible = "renesas,rz-tint"; + reg = <0x1e>; + interrupts = <474 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint31: tint31@1f { + compatible = "renesas,rz-tint"; + reg = <0x1f>; + interrupts = <475 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; }; i2c0: i2c@40058000 { diff --git a/dts/arm/renesas/rz/rzv/r9a09g056.dtsi b/dts/arm/renesas/rz/rzv/r9a09g056.dtsi index db65e3752dde..fc3c8d068804 100644 --- a/dts/arm/renesas/rz/rzv/r9a09g056.dtsi +++ b/dts/arm/renesas/rz/rzv/r9a09g056.dtsi @@ -418,11 +418,306 @@ }; intc: intc@40400000 { - compatible = "renesas,rz-intc"; - reg = <0x40400000 DT_SIZE_K(64)>; + compatible = "renesas,rz-intc-v2"; + reg = <0x40400000 DT_SIZE_K(64)>, + <0x20 0x4>, + <0x28 0x4>, + <0x30 0x4>, + <0x200 0xac>; + reg-names = "intc", "tscr", "titsr0", "tssr0", "intsel"; + gpioint-table = <0 8 14 16 24 32 40 48 56 64 72 80>; + max-gpioint = <85>; #address-cells = <1>; #size-cells = <0>; interrupt-parent = <&nvic>; + + tint0: tint0@0 { + compatible = "renesas,rz-tint"; + reg = <0x0>; + interrupts = <353 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint1: tint1@1 { + compatible = "renesas,rz-tint"; + reg = <0x1>; + interrupts = <354 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint2: tint2@2 { + compatible = "renesas,rz-tint"; + reg = <0x2>; + interrupts = <355 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint3: tint3@3 { + compatible = "renesas,rz-tint"; + reg = <0x3>; + interrupts = <356 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint4: tint4@4 { + compatible = "renesas,rz-tint"; + reg = <0x4>; + interrupts = <357 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint5: tint5@5 { + compatible = "renesas,rz-tint"; + reg = <0x5>; + interrupts = <358 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint6: tint6@6 { + compatible = "renesas,rz-tint"; + reg = <0x6>; + interrupts = <359 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint7: tint7@7 { + compatible = "renesas,rz-tint"; + reg = <0x7>; + interrupts = <360 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint8: tint8@8 { + compatible = "renesas,rz-tint"; + reg = <0x8>; + interrupts = <361 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint9: tint9@9 { + compatible = "renesas,rz-tint"; + reg = <0x9>; + interrupts = <362 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint10: tint10@a { + compatible = "renesas,rz-tint"; + reg = <0xa>; + interrupts = <363 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint11: tint11@b { + compatible = "renesas,rz-tint"; + reg = <0xb>; + interrupts = <364 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint12: tint12@c { + compatible = "renesas,rz-tint"; + reg = <0xc>; + interrupts = <365 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint13: tint13@d { + compatible = "renesas,rz-tint"; + reg = <0xd>; + interrupts = <366 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint14: tint14@e { + compatible = "renesas,rz-tint"; + reg = <0xe>; + interrupts = <367 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint15: tint15@f { + compatible = "renesas,rz-tint"; + reg = <0xf>; + interrupts = <368 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint16: tint16@10 { + compatible = "renesas,rz-tint"; + reg = <0x10>; + interrupts = <369 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint17: tint17@11 { + compatible = "renesas,rz-tint"; + reg = <0x11>; + interrupts = <370 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint18: tint18@12 { + compatible = "renesas,rz-tint"; + reg = <0x12>; + interrupts = <371 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint19: tint19@13 { + compatible = "renesas,rz-tint"; + reg = <0x13>; + interrupts = <372 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint20: tint20@14 { + compatible = "renesas,rz-tint"; + reg = <0x14>; + interrupts = <373 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint21: tint21@15 { + compatible = "renesas,rz-tint"; + reg = <0x15>; + interrupts = <374 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint22: tint22@16 { + compatible = "renesas,rz-tint"; + reg = <0x16>; + interrupts = <375 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint23: tint23@17 { + compatible = "renesas,rz-tint"; + reg = <0x17>; + interrupts = <376 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint24: tint24@18 { + compatible = "renesas,rz-tint"; + reg = <0x18>; + interrupts = <377 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint25: tint25@19 { + compatible = "renesas,rz-tint"; + reg = <0x19>; + interrupts = <378 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint26: tint26@1a { + compatible = "renesas,rz-tint"; + reg = <0x1a>; + interrupts = <379 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint27: tint27@1b { + compatible = "renesas,rz-tint"; + reg = <0x1b>; + interrupts = <380 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint28: tint28@1c { + compatible = "renesas,rz-tint"; + reg = <0x1c>; + interrupts = <381 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint29: tint29@1d { + compatible = "renesas,rz-tint"; + reg = <0x1d>; + interrupts = <382 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint30: tint30@1e { + compatible = "renesas,rz-tint"; + reg = <0x1e>; + interrupts = <383 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint31: tint31@1f { + compatible = "renesas,rz-tint"; + reg = <0x1f>; + interrupts = <384 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; }; sci0: sci0@42800c00 { diff --git a/dts/arm/renesas/rz/rzv/r9a09g057_cm33.dtsi b/dts/arm/renesas/rz/rzv/r9a09g057_cm33.dtsi index f5b27ae4593a..47a1512cfdee 100644 --- a/dts/arm/renesas/rz/rzv/r9a09g057_cm33.dtsi +++ b/dts/arm/renesas/rz/rzv/r9a09g057_cm33.dtsi @@ -418,11 +418,306 @@ }; intc: intc@40400000 { - compatible = "renesas,rz-intc"; - reg = <0x40400000 DT_SIZE_K(64)>; + compatible = "renesas,rz-intc-v2"; + reg = <0x40400000 DT_SIZE_K(64)>, + <0x20 0x4>, + <0x28 0x4>, + <0x30 0x4>, + <0x200 0xac>; + reg-names = "intc", "tscr", "titsr0", "tssr0", "intsel"; + gpioint-table = <0 8 14 16 24 32 40 48 56 64 72 80>; + max-gpioint = <85>; #address-cells = <1>; #size-cells = <0>; interrupt-parent = <&nvic>; + + tint0: tint0@0 { + compatible = "renesas,rz-tint"; + reg = <0x0>; + interrupts = <353 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint1: tint1@1 { + compatible = "renesas,rz-tint"; + reg = <0x1>; + interrupts = <354 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint2: tint2@2 { + compatible = "renesas,rz-tint"; + reg = <0x2>; + interrupts = <355 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint3: tint3@3 { + compatible = "renesas,rz-tint"; + reg = <0x3>; + interrupts = <356 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint4: tint4@4 { + compatible = "renesas,rz-tint"; + reg = <0x4>; + interrupts = <357 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint5: tint5@5 { + compatible = "renesas,rz-tint"; + reg = <0x5>; + interrupts = <358 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint6: tint6@6 { + compatible = "renesas,rz-tint"; + reg = <0x6>; + interrupts = <359 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint7: tint7@7 { + compatible = "renesas,rz-tint"; + reg = <0x7>; + interrupts = <360 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint8: tint8@8 { + compatible = "renesas,rz-tint"; + reg = <0x8>; + interrupts = <361 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint9: tint9@9 { + compatible = "renesas,rz-tint"; + reg = <0x9>; + interrupts = <362 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint10: tint10@a { + compatible = "renesas,rz-tint"; + reg = <0xa>; + interrupts = <363 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint11: tint11@b { + compatible = "renesas,rz-tint"; + reg = <0xb>; + interrupts = <364 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint12: tint12@c { + compatible = "renesas,rz-tint"; + reg = <0xc>; + interrupts = <365 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint13: tint13@d { + compatible = "renesas,rz-tint"; + reg = <0xd>; + interrupts = <366 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint14: tint14@e { + compatible = "renesas,rz-tint"; + reg = <0xe>; + interrupts = <367 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint15: tint15@f { + compatible = "renesas,rz-tint"; + reg = <0xf>; + interrupts = <368 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint16: tint16@10 { + compatible = "renesas,rz-tint"; + reg = <0x10>; + interrupts = <369 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint17: tint17@11 { + compatible = "renesas,rz-tint"; + reg = <0x11>; + interrupts = <370 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint18: tint18@12 { + compatible = "renesas,rz-tint"; + reg = <0x12>; + interrupts = <371 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint19: tint19@13 { + compatible = "renesas,rz-tint"; + reg = <0x13>; + interrupts = <372 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint20: tint20@14 { + compatible = "renesas,rz-tint"; + reg = <0x14>; + interrupts = <373 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint21: tint21@15 { + compatible = "renesas,rz-tint"; + reg = <0x15>; + interrupts = <374 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint22: tint22@16 { + compatible = "renesas,rz-tint"; + reg = <0x16>; + interrupts = <375 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint23: tint23@17 { + compatible = "renesas,rz-tint"; + reg = <0x17>; + interrupts = <376 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint24: tint24@18 { + compatible = "renesas,rz-tint"; + reg = <0x18>; + interrupts = <377 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint25: tint25@19 { + compatible = "renesas,rz-tint"; + reg = <0x19>; + interrupts = <378 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint26: tint26@1a { + compatible = "renesas,rz-tint"; + reg = <0x1a>; + interrupts = <379 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint27: tint27@1b { + compatible = "renesas,rz-tint"; + reg = <0x1b>; + interrupts = <380 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint28: tint28@1c { + compatible = "renesas,rz-tint"; + reg = <0x1c>; + interrupts = <381 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint29: tint29@1d { + compatible = "renesas,rz-tint"; + reg = <0x1d>; + interrupts = <382 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint30: tint30@1e { + compatible = "renesas,rz-tint"; + reg = <0x1e>; + interrupts = <383 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint31: tint31@1f { + compatible = "renesas,rz-tint"; + reg = <0x1f>; + interrupts = <384 1>; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; }; sci0: sci0@42800c00 { diff --git a/dts/arm/renesas/rz/rzv/r9a09g057_cr8.dtsi b/dts/arm/renesas/rz/rzv/r9a09g057_cr8.dtsi index f8b034787feb..1c194fe38cfd 100644 --- a/dts/arm/renesas/rz/rzv/r9a09g057_cr8.dtsi +++ b/dts/arm/renesas/rz/rzv/r9a09g057_cr8.dtsi @@ -513,11 +513,306 @@ }; intc: intc@10400000 { - compatible = "renesas,rz-intc"; - reg = <0x10400000 DT_SIZE_K(64)>; + compatible = "renesas,rz-intc-v2"; + reg = <0x10400000 DT_SIZE_K(64)>, + <0x20 0x4>, + <0x28 0x4>, + <0x30 0x4>, + <0x140 0xac>; + reg-names = "intc", "tscr", "titsr0", "tssr0", "intsel"; + gpioint-table = <0 8 14 16 24 32 40 48 56 64 72 80>; + max-gpioint = <85>; #address-cells = <1>; #size-cells = <0>; interrupt-parent = <&gic>; + + tint0: tint0@0 { + compatible = "renesas,rz-tint"; + reg = <0x0>; + interrupts = ; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint1: tint1@1 { + compatible = "renesas,rz-tint"; + reg = <0x1>; + interrupts = ; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint2: tint2@2 { + compatible = "renesas,rz-tint"; + reg = <0x2>; + interrupts = ; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint3: tint3@3 { + compatible = "renesas,rz-tint"; + reg = <0x3>; + interrupts = ; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint4: tint4@4 { + compatible = "renesas,rz-tint"; + reg = <0x4>; + interrupts = ; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint5: tint5@5 { + compatible = "renesas,rz-tint"; + reg = <0x5>; + interrupts = ; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint6: tint6@6 { + compatible = "renesas,rz-tint"; + reg = <0x6>; + interrupts = ; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint7: tint7@7 { + compatible = "renesas,rz-tint"; + reg = <0x7>; + interrupts = ; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint8: tint8@8 { + compatible = "renesas,rz-tint"; + reg = <0x8>; + interrupts = ; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint9: tint9@9 { + compatible = "renesas,rz-tint"; + reg = <0x9>; + interrupts = ; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint10: tint10@a { + compatible = "renesas,rz-tint"; + reg = <0xa>; + interrupts = ; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint11: tint11@b { + compatible = "renesas,rz-tint"; + reg = <0xb>; + interrupts = ; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint12: tint12@c { + compatible = "renesas,rz-tint"; + reg = <0xc>; + interrupts = ; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint13: tint13@d { + compatible = "renesas,rz-tint"; + reg = <0xd>; + interrupts = ; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint14: tint14@e { + compatible = "renesas,rz-tint"; + reg = <0xe>; + interrupts = ; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint15: tint15@f { + compatible = "renesas,rz-tint"; + reg = <0xf>; + interrupts = ; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint16: tint16@10 { + compatible = "renesas,rz-tint"; + reg = <0x10>; + interrupts = ; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint17: tint17@11 { + compatible = "renesas,rz-tint"; + reg = <0x11>; + interrupts = ; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint18: tint18@12 { + compatible = "renesas,rz-tint"; + reg = <0x12>; + interrupts = ; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint19: tint19@13 { + compatible = "renesas,rz-tint"; + reg = <0x13>; + interrupts = ; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint20: tint20@14 { + compatible = "renesas,rz-tint"; + reg = <0x14>; + interrupts = ; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint21: tint21@15 { + compatible = "renesas,rz-tint"; + reg = <0x15>; + interrupts = ; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint22: tint22@16 { + compatible = "renesas,rz-tint"; + reg = <0x16>; + interrupts = ; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint23: tint23@17 { + compatible = "renesas,rz-tint"; + reg = <0x17>; + interrupts = ; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint24: tint24@18 { + compatible = "renesas,rz-tint"; + reg = <0x18>; + interrupts = ; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint25: tint25@19 { + compatible = "renesas,rz-tint"; + reg = <0x19>; + interrupts = ; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint26: tint26@1a { + compatible = "renesas,rz-tint"; + reg = <0x1a>; + interrupts = ; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint27: tint27@1b { + compatible = "renesas,rz-tint"; + reg = <0x1b>; + interrupts = ; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint28: tint28@1c { + compatible = "renesas,rz-tint"; + reg = <0x1c>; + interrupts = ; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint29: tint29@1d { + compatible = "renesas,rz-tint"; + reg = <0x1d>; + interrupts = ; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint30: tint30@1e { + compatible = "renesas,rz-tint"; + reg = <0x1e>; + interrupts = ; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint31: tint31@1f { + compatible = "renesas,rz-tint"; + reg = <0x1f>; + interrupts = ; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; }; sci0: sci0@12800c00 { diff --git a/dts/arm64/renesas/rz/rza/r9a07g063.dtsi b/dts/arm64/renesas/rz/rza/r9a07g063.dtsi index 19d69767560f..ecb9ae4cf57e 100644 --- a/dts/arm64/renesas/rz/rza/r9a07g063.dtsi +++ b/dts/arm64/renesas/rz/rza/r9a07g063.dtsi @@ -693,7 +693,14 @@ intc: intc@110a0000 { compatible = "renesas,rz-intc"; - reg = <0x110a0000 DT_SIZE_K(64)>; + reg = <0x110a0000 DT_SIZE_K(64)>, + <0x20 0x4>, + <0x24 0x4>, + <0x30 0x4>; + reg-names = "intc", "tscr", "titsr0", "tssr0"; + gpioint-table = <0 4 9 13 17 23 28 33 38 43 + 47 52 56 58 63 66 70 72 76>; + max-gpioint = <81>; #address-cells = <1>; #size-cells = <0>; interrupt-parent = <&gic>; @@ -777,6 +784,294 @@ interrupts = ; status = "disabled"; }; + + tint0: tint0@0 { + compatible = "renesas,rz-tint"; + reg = <0x0>; + interrupts = ; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint1: tint1@1 { + compatible = "renesas,rz-tint"; + reg = <0x1>; + interrupts = ; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint2: tint2@2 { + compatible = "renesas,rz-tint"; + reg = <0x2>; + interrupts = ; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint3: tint3@3 { + compatible = "renesas,rz-tint"; + reg = <0x3>; + interrupts = ; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint4: tint4@4 { + compatible = "renesas,rz-tint"; + reg = <0x4>; + interrupts = ; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint5: tint5@5 { + compatible = "renesas,rz-tint"; + reg = <0x5>; + interrupts = ; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint6: tint6@6 { + compatible = "renesas,rz-tint"; + reg = <0x6>; + interrupts = ; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint7: tint7@7 { + compatible = "renesas,rz-tint"; + reg = <0x7>; + interrupts = ; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint8: tint8@8 { + compatible = "renesas,rz-tint"; + reg = <0x8>; + interrupts = ; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint9: tint9@9 { + compatible = "renesas,rz-tint"; + reg = <0x9>; + interrupts = ; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint10: tint10@a { + compatible = "renesas,rz-tint"; + reg = <0xa>; + interrupts = ; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint11: tint11@b { + compatible = "renesas,rz-tint"; + reg = <0xb>; + interrupts = ; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint12: tint12@c { + compatible = "renesas,rz-tint"; + reg = <0xc>; + interrupts = ; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint13: tint13@d { + compatible = "renesas,rz-tint"; + reg = <0xd>; + interrupts = ; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint14: tint14@e { + compatible = "renesas,rz-tint"; + reg = <0xe>; + interrupts = ; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint15: tint15@f { + compatible = "renesas,rz-tint"; + reg = <0xf>; + interrupts = ; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint16: tint16@10 { + compatible = "renesas,rz-tint"; + reg = <0x10>; + interrupts = ; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint17: tint17@11 { + compatible = "renesas,rz-tint"; + reg = <0x11>; + interrupts = ; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint18: tint18@12 { + compatible = "renesas,rz-tint"; + reg = <0x12>; + interrupts = ; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint19: tint19@13 { + compatible = "renesas,rz-tint"; + reg = <0x13>; + interrupts = ; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint20: tint20@14 { + compatible = "renesas,rz-tint"; + reg = <0x14>; + interrupts = ; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint21: tint21@15 { + compatible = "renesas,rz-tint"; + reg = <0x15>; + interrupts = ; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint22: tint22@16 { + compatible = "renesas,rz-tint"; + reg = <0x16>; + interrupts = ; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint23: tint23@17 { + compatible = "renesas,rz-tint"; + reg = <0x17>; + interrupts = ; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint24: tint24@18 { + compatible = "renesas,rz-tint"; + reg = <0x18>; + interrupts = ; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint25: tint25@19 { + compatible = "renesas,rz-tint"; + reg = <0x19>; + interrupts = ; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint26: tint26@1a { + compatible = "renesas,rz-tint"; + reg = <0x1a>; + interrupts = ; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint27: tint27@1b { + compatible = "renesas,rz-tint"; + reg = <0x1b>; + interrupts = ; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint28: tint28@1c { + compatible = "renesas,rz-tint"; + reg = <0x1c>; + interrupts = ; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint29: tint29@1d { + compatible = "renesas,rz-tint"; + reg = <0x1d>; + interrupts = ; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint30: tint30@1e { + compatible = "renesas,rz-tint"; + reg = <0x1e>; + interrupts = ; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; + + tint31: tint31@1f { + compatible = "renesas,rz-tint"; + reg = <0x1f>; + interrupts = ; + trigger-type = "rising"; + #irq-cells = <1>; + status = "disabled"; + }; }; i2c0: i2c@10058000 { From 1de74c98e27765b3e5b9fce39da5f13a6803c153 Mon Sep 17 00:00:00 2001 From: Nhut Nguyen Date: Thu, 18 Dec 2025 14:53:56 +0700 Subject: [PATCH 2156/3659] bindings: intc: Update Renesas RZ external interrupt Add `#irq-cells` to Renesas RZ external interrupt binding `renesas,rz-ext-irq`. Signed-off-by: Nhut Nguyen --- .../interrupt-controller/renesas,rz-ext-irq.yaml | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/dts/bindings/interrupt-controller/renesas,rz-ext-irq.yaml b/dts/bindings/interrupt-controller/renesas,rz-ext-irq.yaml index 2777e3bc65e0..c4e28395d9ce 100644 --- a/dts/bindings/interrupt-controller/renesas,rz-ext-irq.yaml +++ b/dts/bindings/interrupt-controller/renesas,rz-ext-irq.yaml @@ -1,16 +1,13 @@ -# Copyright (c) 2024 Renesas Electronics Corporation +# Copyright (c) 2024-2025 Renesas Electronics Corporation # SPDX-License-Identifier: Apache-2.0 description: Renesas RZ external interrupt controller compatible: "renesas,rz-ext-irq" -include: [interrupt-controller.yaml, base.yaml, pinctrl-device.yaml] +include: [base.yaml, pinctrl-device.yaml] properties: - "#interrupt-cells": - const: 2 - trigger-type: required: true type: string @@ -21,3 +18,10 @@ properties: - "rising" - "both_edges" - "low_level" + + "#irq-cells": + type: int + const: 1 + +irq-cells: + - pin From 2537ee030a9c33405507965d7104a73455e50b21 Mon Sep 17 00:00:00 2001 From: Nhut Nguyen Date: Wed, 17 Dec 2025 14:23:36 +0700 Subject: [PATCH 2157/3659] drivers: intc: renesas: Update external interrupt of RZ family Added a condition to check trigger type as high-level detection is not supported by Renesas RZ external interrupt. Signed-off-by: Nhut Nguyen --- drivers/interrupt_controller/intc_renesas_rz_ext_irq.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/interrupt_controller/intc_renesas_rz_ext_irq.c b/drivers/interrupt_controller/intc_renesas_rz_ext_irq.c index f261cf354fb9..cea0d40b7e20 100644 --- a/drivers/interrupt_controller/intc_renesas_rz_ext_irq.c +++ b/drivers/interrupt_controller/intc_renesas_rz_ext_irq.c @@ -97,6 +97,11 @@ int intc_rz_ext_irq_set_type(const struct device *dev, uint8_t trig) fsp_err_t err = FSP_SUCCESS; external_irq_cfg_t *p_cfg = (external_irq_cfg_t *)config->fsp_cfg; + /* High level detection is not supported by HW */ + if (trig == EXTERNAL_IRQ_TRIG_LEVEL_HIGH) { + return -ENOTSUP; + } + p_cfg->trigger = (external_irq_trigger_t)trig; err = config->fsp_api->close(data->fsp_ctrl); From ad2ca49df70cb215f15d6e3b5b3df1d038da1794 Mon Sep 17 00:00:00 2001 From: Nhut Nguyen Date: Thu, 18 Dec 2025 15:05:36 +0700 Subject: [PATCH 2158/3659] dts: renesas: Update renesas,rz-ext-irq nodes Added `#irq-cells` to `renesas,rz-ext-irq` nodes to reflect the update of `renesas,rz-ext-irq` binding. Signed-off-by: Nhut Nguyen --- dts/arm/renesas/rz/rzn/r9a07g084.dtsi | 48 +++++++++---------------- dts/arm/renesas/rz/rzt/r9a07g074.dtsi | 48 +++++++++---------------- dts/arm/renesas/rz/rzt/r9a07g075.dtsi | 48 +++++++++---------------- dts/arm/renesas/rz/rzv/r9a07g054.dtsi | 24 +++++-------- dts/arm64/renesas/rz/rza/r9a07g063.dtsi | 27 +++++--------- 5 files changed, 65 insertions(+), 130 deletions(-) diff --git a/dts/arm/renesas/rz/rzn/r9a07g084.dtsi b/dts/arm/renesas/rz/rzn/r9a07g084.dtsi index 5727dac0f73a..bcd3ef4691dc 100644 --- a/dts/arm/renesas/rz/rzn/r9a07g084.dtsi +++ b/dts/arm/renesas/rz/rzn/r9a07g084.dtsi @@ -239,8 +239,7 @@ compatible = "renesas,rz-ext-irq"; reg = <0x0>; interrupts = ; - interrupt-controller; - #interrupt-cells = <2>; + #irq-cells = <1>; status = "disabled"; }; @@ -248,8 +247,7 @@ compatible = "renesas,rz-ext-irq"; reg = <0x1>; interrupts = ; - interrupt-controller; - #interrupt-cells = <2>; + #irq-cells = <1>; status = "disabled"; }; @@ -257,8 +255,7 @@ compatible = "renesas,rz-ext-irq"; reg = <0x2>; interrupts = ; - interrupt-controller; - #interrupt-cells = <2>; + #irq-cells = <1>; status = "disabled"; }; @@ -266,8 +263,7 @@ compatible = "renesas,rz-ext-irq"; reg = <0x3>; interrupts = ; - interrupt-controller; - #interrupt-cells = <2>; + #irq-cells = <1>; status = "disabled"; }; @@ -275,8 +271,7 @@ compatible = "renesas,rz-ext-irq"; reg = <0x4>; interrupts = ; - interrupt-controller; - #interrupt-cells = <2>; + #irq-cells = <1>; status = "disabled"; }; @@ -284,8 +279,7 @@ compatible = "renesas,rz-ext-irq"; reg = <0x5>; interrupts = ; - interrupt-controller; - #interrupt-cells = <2>; + #irq-cells = <1>; status = "disabled"; }; @@ -293,8 +287,7 @@ compatible = "renesas,rz-ext-irq"; reg = <0x6>; interrupts = ; - interrupt-controller; - #interrupt-cells = <2>; + #irq-cells = <1>; status = "disabled"; }; @@ -302,8 +295,7 @@ compatible = "renesas,rz-ext-irq"; reg = <0x7>; interrupts = ; - interrupt-controller; - #interrupt-cells = <2>; + #irq-cells = <1>; status = "disabled"; }; @@ -311,8 +303,7 @@ compatible = "renesas,rz-ext-irq"; reg = <0x8>; interrupts = ; - interrupt-controller; - #interrupt-cells = <2>; + #irq-cells = <1>; status = "disabled"; }; @@ -320,8 +311,7 @@ compatible = "renesas,rz-ext-irq"; reg = <0x9>; interrupts = ; - interrupt-controller; - #interrupt-cells = <2>; + #irq-cells = <1>; status = "disabled"; }; @@ -329,8 +319,7 @@ compatible = "renesas,rz-ext-irq"; reg = <0xa>; interrupts = ; - interrupt-controller; - #interrupt-cells = <2>; + #irq-cells = <1>; status = "disabled"; }; @@ -338,8 +327,7 @@ compatible = "renesas,rz-ext-irq"; reg = <0xb>; interrupts = ; - interrupt-controller; - #interrupt-cells = <2>; + #irq-cells = <1>; status = "disabled"; }; @@ -347,8 +335,7 @@ compatible = "renesas,rz-ext-irq"; reg = <0xc>; interrupts = ; - interrupt-controller; - #interrupt-cells = <2>; + #irq-cells = <1>; status = "disabled"; }; @@ -356,8 +343,7 @@ compatible = "renesas,rz-ext-irq"; reg = <0xd>; interrupts = ; - interrupt-controller; - #interrupt-cells = <2>; + #irq-cells = <1>; status = "disabled"; }; @@ -365,8 +351,7 @@ compatible = "renesas,rz-ext-irq"; reg = <0xe>; interrupts = ; - interrupt-controller; - #interrupt-cells = <2>; + #irq-cells = <1>; status = "disabled"; }; @@ -374,8 +359,7 @@ compatible = "renesas,rz-ext-irq"; reg = <0xf>; interrupts = ; - interrupt-controller; - #interrupt-cells = <2>; + #irq-cells = <1>; status = "disabled"; }; }; diff --git a/dts/arm/renesas/rz/rzt/r9a07g074.dtsi b/dts/arm/renesas/rz/rzt/r9a07g074.dtsi index 795f4bc3b0da..fadce051ca7b 100644 --- a/dts/arm/renesas/rz/rzt/r9a07g074.dtsi +++ b/dts/arm/renesas/rz/rzt/r9a07g074.dtsi @@ -100,8 +100,7 @@ compatible = "renesas,rz-ext-irq"; reg = <0x0>; interrupts = ; - interrupt-controller; - #interrupt-cells = <2>; + #irq-cells = <1>; status = "disabled"; }; @@ -109,8 +108,7 @@ compatible = "renesas,rz-ext-irq"; reg = <0x1>; interrupts = ; - interrupt-controller; - #interrupt-cells = <2>; + #irq-cells = <1>; status = "disabled"; }; @@ -118,8 +116,7 @@ compatible = "renesas,rz-ext-irq"; reg = <0x2>; interrupts = ; - interrupt-controller; - #interrupt-cells = <2>; + #irq-cells = <1>; status = "disabled"; }; @@ -127,8 +124,7 @@ compatible = "renesas,rz-ext-irq"; reg = <0x3>; interrupts = ; - interrupt-controller; - #interrupt-cells = <2>; + #irq-cells = <1>; status = "disabled"; }; @@ -136,8 +132,7 @@ compatible = "renesas,rz-ext-irq"; reg = <0x4>; interrupts = ; - interrupt-controller; - #interrupt-cells = <2>; + #irq-cells = <1>; status = "disabled"; }; @@ -145,8 +140,7 @@ compatible = "renesas,rz-ext-irq"; reg = <0x5>; interrupts = ; - interrupt-controller; - #interrupt-cells = <2>; + #irq-cells = <1>; status = "disabled"; }; @@ -154,8 +148,7 @@ compatible = "renesas,rz-ext-irq"; reg = <0x6>; interrupts = ; - interrupt-controller; - #interrupt-cells = <2>; + #irq-cells = <1>; status = "disabled"; }; @@ -163,8 +156,7 @@ compatible = "renesas,rz-ext-irq"; reg = <0x7>; interrupts = ; - interrupt-controller; - #interrupt-cells = <2>; + #irq-cells = <1>; status = "disabled"; }; @@ -172,8 +164,7 @@ compatible = "renesas,rz-ext-irq"; reg = <0x8>; interrupts = ; - interrupt-controller; - #interrupt-cells = <2>; + #irq-cells = <1>; status = "disabled"; }; @@ -181,8 +172,7 @@ compatible = "renesas,rz-ext-irq"; reg = <0x9>; interrupts = ; - interrupt-controller; - #interrupt-cells = <2>; + #irq-cells = <1>; status = "disabled"; }; @@ -190,8 +180,7 @@ compatible = "renesas,rz-ext-irq"; reg = <0xa>; interrupts = ; - interrupt-controller; - #interrupt-cells = <2>; + #irq-cells = <1>; status = "disabled"; }; @@ -199,8 +188,7 @@ compatible = "renesas,rz-ext-irq"; reg = <0xb>; interrupts = ; - interrupt-controller; - #interrupt-cells = <2>; + #irq-cells = <1>; status = "disabled"; }; @@ -208,8 +196,7 @@ compatible = "renesas,rz-ext-irq"; reg = <0xc>; interrupts = ; - interrupt-controller; - #interrupt-cells = <2>; + #irq-cells = <1>; status = "disabled"; }; @@ -217,8 +204,7 @@ compatible = "renesas,rz-ext-irq"; reg = <0xd>; interrupts = ; - interrupt-controller; - #interrupt-cells = <2>; + #irq-cells = <1>; status = "disabled"; }; @@ -226,8 +212,7 @@ compatible = "renesas,rz-ext-irq"; reg = <0xe>; interrupts = ; - interrupt-controller; - #interrupt-cells = <2>; + #irq-cells = <1>; status = "disabled"; }; @@ -235,8 +220,7 @@ compatible = "renesas,rz-ext-irq"; reg = <0xf>; interrupts = ; - interrupt-controller; - #interrupt-cells = <2>; + #irq-cells = <1>; status = "disabled"; }; }; diff --git a/dts/arm/renesas/rz/rzt/r9a07g075.dtsi b/dts/arm/renesas/rz/rzt/r9a07g075.dtsi index 7615c23cc08c..554efde30a1e 100644 --- a/dts/arm/renesas/rz/rzt/r9a07g075.dtsi +++ b/dts/arm/renesas/rz/rzt/r9a07g075.dtsi @@ -252,8 +252,7 @@ compatible = "renesas,rz-ext-irq"; reg = <0x0>; interrupts = ; - interrupt-controller; - #interrupt-cells = <2>; + #irq-cells = <1>; status = "disabled"; }; @@ -261,8 +260,7 @@ compatible = "renesas,rz-ext-irq"; reg = <0x1>; interrupts = ; - interrupt-controller; - #interrupt-cells = <2>; + #irq-cells = <1>; status = "disabled"; }; @@ -270,8 +268,7 @@ compatible = "renesas,rz-ext-irq"; reg = <0x2>; interrupts = ; - interrupt-controller; - #interrupt-cells = <2>; + #irq-cells = <1>; status = "disabled"; }; @@ -279,8 +276,7 @@ compatible = "renesas,rz-ext-irq"; reg = <0x3>; interrupts = ; - interrupt-controller; - #interrupt-cells = <2>; + #irq-cells = <1>; status = "disabled"; }; @@ -288,8 +284,7 @@ compatible = "renesas,rz-ext-irq"; reg = <0x4>; interrupts = ; - interrupt-controller; - #interrupt-cells = <2>; + #irq-cells = <1>; status = "disabled"; }; @@ -297,8 +292,7 @@ compatible = "renesas,rz-ext-irq"; reg = <0x5>; interrupts = ; - interrupt-controller; - #interrupt-cells = <2>; + #irq-cells = <1>; status = "disabled"; }; @@ -306,8 +300,7 @@ compatible = "renesas,rz-ext-irq"; reg = <0x6>; interrupts = ; - interrupt-controller; - #interrupt-cells = <2>; + #irq-cells = <1>; status = "disabled"; }; @@ -315,8 +308,7 @@ compatible = "renesas,rz-ext-irq"; reg = <0x7>; interrupts = ; - interrupt-controller; - #interrupt-cells = <2>; + #irq-cells = <1>; status = "disabled"; }; @@ -324,8 +316,7 @@ compatible = "renesas,rz-ext-irq"; reg = <0x8>; interrupts = ; - interrupt-controller; - #interrupt-cells = <2>; + #irq-cells = <1>; status = "disabled"; }; @@ -333,8 +324,7 @@ compatible = "renesas,rz-ext-irq"; reg = <0x9>; interrupts = ; - interrupt-controller; - #interrupt-cells = <2>; + #irq-cells = <1>; status = "disabled"; }; @@ -342,8 +332,7 @@ compatible = "renesas,rz-ext-irq"; reg = <0xa>; interrupts = ; - interrupt-controller; - #interrupt-cells = <2>; + #irq-cells = <1>; status = "disabled"; }; @@ -351,8 +340,7 @@ compatible = "renesas,rz-ext-irq"; reg = <0xb>; interrupts = ; - interrupt-controller; - #interrupt-cells = <2>; + #irq-cells = <1>; status = "disabled"; }; @@ -360,8 +348,7 @@ compatible = "renesas,rz-ext-irq"; reg = <0xc>; interrupts = ; - interrupt-controller; - #interrupt-cells = <2>; + #irq-cells = <1>; status = "disabled"; }; @@ -369,8 +356,7 @@ compatible = "renesas,rz-ext-irq"; reg = <0xd>; interrupts = ; - interrupt-controller; - #interrupt-cells = <2>; + #irq-cells = <1>; status = "disabled"; }; @@ -378,8 +364,7 @@ compatible = "renesas,rz-ext-irq"; reg = <0xe>; interrupts = ; - interrupt-controller; - #interrupt-cells = <2>; + #irq-cells = <1>; status = "disabled"; }; @@ -387,8 +372,7 @@ compatible = "renesas,rz-ext-irq"; reg = <0xf>; interrupts = ; - interrupt-controller; - #interrupt-cells = <2>; + #irq-cells = <1>; status = "disabled"; }; }; diff --git a/dts/arm/renesas/rz/rzv/r9a07g054.dtsi b/dts/arm/renesas/rz/rzv/r9a07g054.dtsi index c59cbfdb3a96..ded6556c61ac 100644 --- a/dts/arm/renesas/rz/rzv/r9a07g054.dtsi +++ b/dts/arm/renesas/rz/rzv/r9a07g054.dtsi @@ -889,72 +889,64 @@ irq0: irq@0 { compatible = "renesas,rz-ext-irq"; reg = <0x0>; - interrupt-controller; - #interrupt-cells = <2>; interrupts = <1 1>; + #irq-cells = <1>; status = "disabled"; }; irq1: irq@1 { compatible = "renesas,rz-ext-irq"; reg = <0x1>; - interrupt-controller; - #interrupt-cells = <2>; interrupts = <2 1>; + #irq-cells = <1>; status = "disabled"; }; irq2: irq@2 { compatible = "renesas,rz-ext-irq"; reg = <0x2>; - interrupt-controller; - #interrupt-cells = <2>; interrupts = <3 1>; + #irq-cells = <1>; status = "disabled"; }; irq3: irq@3 { compatible = "renesas,rz-ext-irq"; reg = <0x3>; - interrupt-controller; - #interrupt-cells = <2>; interrupts = <4 1>; + #irq-cells = <1>; status = "disabled"; }; irq4: irq@4 { compatible = "renesas,rz-ext-irq"; reg = <0x4>; - interrupt-controller; - #interrupt-cells = <2>; interrupts = <5 1>; + #irq-cells = <1>; status = "disabled"; }; irq5: irq@5 { compatible = "renesas,rz-ext-irq"; reg = <0x5>; - interrupt-controller; - #interrupt-cells = <2>; interrupts = <6 1>; + #irq-cells = <1>; status = "disabled"; }; irq6: irq@6 { compatible = "renesas,rz-ext-irq"; reg = <0x6>; - interrupt-controller; - #interrupt-cells = <2>; interrupts = <7 1>; + #irq-cells = <1>; status = "disabled"; }; irq7: irq@7 { compatible = "renesas,rz-ext-irq"; reg = <0x7>; - interrupt-controller; - #interrupt-cells = <2>; interrupts = <8 1>; + #irq-cells = <1>; status = "disabled"; }; diff --git a/dts/arm64/renesas/rz/rza/r9a07g063.dtsi b/dts/arm64/renesas/rz/rza/r9a07g063.dtsi index ecb9ae4cf57e..11b8a5fbb9e6 100644 --- a/dts/arm64/renesas/rz/rza/r9a07g063.dtsi +++ b/dts/arm64/renesas/rz/rza/r9a07g063.dtsi @@ -707,81 +707,72 @@ nmi: nmi { compatible = "renesas,rz-ext-irq"; - interrupt-controller; - #interrupt-cells = <2>; interrupts = ; + #irq-cells = <1>; status = "disabled"; }; irq0: irq@0 { compatible = "renesas,rz-ext-irq"; reg = <0x0>; - interrupt-controller; - #interrupt-cells = <2>; interrupts = ; + #irq-cells = <1>; status = "disabled"; }; irq1: irq@1 { compatible = "renesas,rz-ext-irq"; reg = <0x1>; - interrupt-controller; - #interrupt-cells = <2>; interrupts = ; + #irq-cells = <1>; status = "disabled"; }; irq2: irq@2 { compatible = "renesas,rz-ext-irq"; reg = <0x2>; - interrupt-controller; - #interrupt-cells = <2>; interrupts = ; + #irq-cells = <1>; status = "disabled"; }; irq3: irq@3 { compatible = "renesas,rz-ext-irq"; reg = <0x3>; - interrupt-controller; - #interrupt-cells = <2>; interrupts = ; + #irq-cells = <1>; status = "disabled"; }; irq4: irq@4 { compatible = "renesas,rz-ext-irq"; reg = <0x4>; - interrupt-controller; - #interrupt-cells = <2>; interrupts = ; + #irq-cells = <1>; status = "disabled"; }; irq5: irq@5 { compatible = "renesas,rz-ext-irq"; reg = <0x5>; - interrupt-controller; - #interrupt-cells = <2>; interrupts = ; + #irq-cells = <1>; status = "disabled"; }; irq6: irq@6 { compatible = "renesas,rz-ext-irq"; reg = <0x6>; - interrupt-controller; - #interrupt-cells = <2>; interrupts = ; + #irq-cells = <1>; status = "disabled"; }; irq7: irq@7 { compatible = "renesas,rz-ext-irq"; reg = <0x7>; - interrupt-controller; - #interrupt-cells = <2>; interrupts = ; + #irq-cells = <1>; status = "disabled"; }; From f671c98b0814b834620a55f8cfe0f7aec46f9210 Mon Sep 17 00:00:00 2001 From: Nhut Nguyen Date: Wed, 17 Dec 2025 15:20:32 +0700 Subject: [PATCH 2159/3659] bindings: pinctrl: Remove required tag from Renesas RZ Remove required tag from `req` and `reg-names` as the pinctrl node is changed into a dummy node to avoid cycle in devicetree between irq, gpio and pinctrl so these properties are not required for Renesas RZ/A,G,V series. Signed-off-by: Nhut Nguyen --- dts/bindings/pinctrl/renesas,rza-pinctrl.yaml | 6 ------ dts/bindings/pinctrl/renesas,rzg-pinctrl.yaml | 6 ------ dts/bindings/pinctrl/renesas,rzv-pinctrl.yaml | 6 ------ 3 files changed, 18 deletions(-) diff --git a/dts/bindings/pinctrl/renesas,rza-pinctrl.yaml b/dts/bindings/pinctrl/renesas,rza-pinctrl.yaml index 9055f0bb319d..40b080a81d38 100644 --- a/dts/bindings/pinctrl/renesas,rza-pinctrl.yaml +++ b/dts/bindings/pinctrl/renesas,rza-pinctrl.yaml @@ -28,12 +28,6 @@ description: | compatible: "renesas,rza-pinctrl" include: base.yaml -properties: - reg: - required: true - - reg-names: - required: true child-binding: description: | diff --git a/dts/bindings/pinctrl/renesas,rzg-pinctrl.yaml b/dts/bindings/pinctrl/renesas,rzg-pinctrl.yaml index a4061f1615ad..bbd30635e6c2 100644 --- a/dts/bindings/pinctrl/renesas,rzg-pinctrl.yaml +++ b/dts/bindings/pinctrl/renesas,rzg-pinctrl.yaml @@ -34,12 +34,6 @@ description: | compatible: "renesas,rzg-pinctrl" include: base.yaml -properties: - reg: - required: true - - reg-names: - required: true child-binding: description: | diff --git a/dts/bindings/pinctrl/renesas,rzv-pinctrl.yaml b/dts/bindings/pinctrl/renesas,rzv-pinctrl.yaml index 5644ba108682..9f4baf4025aa 100644 --- a/dts/bindings/pinctrl/renesas,rzv-pinctrl.yaml +++ b/dts/bindings/pinctrl/renesas,rzv-pinctrl.yaml @@ -32,12 +32,6 @@ description: | compatible: "renesas,rzv-pinctrl" include: base.yaml -properties: - reg: - required: true - - reg-names: - required: true child-binding: description: | From 69285c4294d179103e1a5658d7dd9a7e3ef31849 Mon Sep 17 00:00:00 2001 From: Nhut Nguyen Date: Wed, 17 Dec 2025 15:28:47 +0700 Subject: [PATCH 2160/3659] drivers: pinctrl: renesas: Refactor RZ pinctrl data structure - Replaced the previous struct layout with a union type. This change exposes all register fields that were hidden for pinctrl, but now they are useful for gpio to reuse. - Remove `_t` suffix from struct tag to avoid duplication with typedef alias. Signed-off-by: Nhut Nguyen --- soc/renesas/rz/common/pinctrl_rza.h | 41 ++++++++++++-------- soc/renesas/rz/common/pinctrl_rzg.h | 41 ++++++++++++-------- soc/renesas/rz/common/pinctrl_rzn.h | 23 +++++++----- soc/renesas/rz/common/pinctrl_rzt.h | 23 +++++++----- soc/renesas/rz/common/pinctrl_rzv.h | 58 +++++++++++++++++------------ 5 files changed, 111 insertions(+), 75 deletions(-) diff --git a/soc/renesas/rz/common/pinctrl_rza.h b/soc/renesas/rz/common/pinctrl_rza.h index 5471a358699f..f969eac76f03 100644 --- a/soc/renesas/rz/common/pinctrl_rza.h +++ b/soc/renesas/rz/common/pinctrl_rza.h @@ -15,20 +15,25 @@ extern "C" { #endif /* Porting */ -typedef struct pinctrl_cfg_data_t { - uint32_t reserved: 4; - uint32_t pupd_reg: 6; - uint32_t iolh_reg: 6; - uint32_t pmc_reg: 1; - uint32_t sr_reg: 1; - uint32_t ien_reg: 1; - uint32_t filonoff_reg: 1; - uint32_t filnum_reg: 2; - uint32_t filclksel_reg: 2; - uint32_t pfc_reg: 3; +typedef union { + uint32_t cfg; + struct { + uint32_t p_reg: 2; + uint32_t pm_reg: 2; + uint32_t pupd_reg: 6; + uint32_t iolh_reg: 4; + uint32_t isel_reg: 2; + uint32_t pmc_reg: 1; + uint32_t sr_reg: 1; + uint32_t ien_reg: 1; + uint32_t filonoff_reg: 1; + uint32_t filnum_reg: 2; + uint32_t filclksel_reg: 2; + uint32_t pfc_reg: 3; + } cfg_b; } pinctrl_cfg_data_t; -typedef struct pinctrl_soc_pin_t { +typedef struct pinctrl_soc_pin { bsp_io_port_pin_t port_pin; pinctrl_cfg_data_t config; } pinctrl_soc_pin_t; @@ -66,11 +71,13 @@ typedef struct pinctrl_soc_pin_t { #define Z_PINCTRL_PINMUX_INIT(node_id, state_prop, idx) \ { \ .port_pin = RZA_GET_PORT_PIN(DT_PROP_BY_IDX(node_id, state_prop, idx)), \ - .config = \ + .config.cfg_b = \ { \ - .reserved = 0, \ + .p_reg = 0, \ + .pm_reg = 0, \ .pupd_reg = RZA_GET_PU_PD(node_id), \ .iolh_reg = DT_PROP(node_id, drive_strength), \ + .isel_reg = 0, \ .pmc_reg = 1, \ .sr_reg = DT_ENUM_IDX(node_id, slew_rate), \ .ien_reg = DT_PROP(node_id, input_enable), \ @@ -84,11 +91,13 @@ typedef struct pinctrl_soc_pin_t { #define Z_PINCTRL_SPECIAL_PINS_INIT(node_id, state_prop, idx) \ { \ .port_pin = DT_PROP_BY_IDX(node_id, state_prop, idx), \ - .config = \ + .config.cfg_b = \ { \ - .reserved = 0, \ + .p_reg = 0, \ + .pm_reg = 0, \ .pupd_reg = RZA_GET_PU_PD(node_id), \ .iolh_reg = DT_PROP(node_id, drive_strength), \ + .isel_reg = 0, \ .pmc_reg = 0, \ .sr_reg = DT_ENUM_IDX(node_id, slew_rate), \ .ien_reg = DT_PROP(node_id, input_enable), \ diff --git a/soc/renesas/rz/common/pinctrl_rzg.h b/soc/renesas/rz/common/pinctrl_rzg.h index 9a580540a716..86dfebba7642 100644 --- a/soc/renesas/rz/common/pinctrl_rzg.h +++ b/soc/renesas/rz/common/pinctrl_rzg.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Renesas Electronics Corporation + * Copyright (c) 2024-2025 Renesas Electronics Corporation * SPDX-License-Identifier: Apache-2.0 */ #ifndef ZEPHYR_SOC_RENESAS_RZ_COMMON_PINCTRL_RZG_H_ @@ -15,19 +15,24 @@ extern "C" { #endif /*Porting*/ -typedef struct pinctrl_cfg_data_t { - uint32_t reserved: 4; - uint32_t pupd_reg: 6; - uint32_t iolh_reg: 6; - uint32_t pmc_reg: 2; - uint32_t ien_reg: 1; - uint32_t filonoff_reg: 1; - uint32_t filnum_reg: 2; - uint32_t filclksel_reg: 2; - uint32_t pfc_reg: 3; +typedef union { + uint32_t cfg; + struct { + uint32_t p_reg: 2; + uint32_t pm_reg: 2; + uint32_t pupd_reg: 6; + uint32_t iolh_reg: 4; + uint32_t isel_reg: 2; + uint32_t pmc_reg: 2; + uint32_t ien_reg: 1; + uint32_t filonoff_reg: 1; + uint32_t filnum_reg: 2; + uint32_t filclksel_reg: 2; + uint32_t pfc_reg: 3; + } cfg_b; } pinctrl_cfg_data_t; -typedef struct pinctrl_soc_pin_t { +typedef struct pinctrl_soc_pin { bsp_io_port_pin_t port_pin; pinctrl_cfg_data_t config; } pinctrl_soc_pin_t; @@ -73,11 +78,13 @@ typedef struct pinctrl_soc_pin_t { #define Z_PINCTRL_PINMUX_INIT(node_id, state_prop, idx) \ { \ .port_pin = RZG_GET_PORT_PIN(DT_PROP_BY_IDX(node_id, state_prop, idx)), \ - .config = \ + .config.cfg_b = \ { \ - .reserved = 0, \ + .p_reg = 0, \ + .pm_reg = 0, \ .pupd_reg = RZG_GET_PU_PD(node_id), \ .iolh_reg = DT_PROP(node_id, drive_strength), \ + .isel_reg = 0, \ .pmc_reg = 1, \ .ien_reg = DT_PROP(node_id, input_enable), \ .filonoff_reg = RZG_FILTER_ON_OFF(node_id), \ @@ -90,11 +97,13 @@ typedef struct pinctrl_soc_pin_t { #define Z_PINCTRL_SPECIAL_PINS_INIT(node_id, state_prop, idx) \ { \ .port_pin = DT_PROP_BY_IDX(node_id, state_prop, idx), \ - .config = \ + .config.cfg_b = \ { \ - .reserved = 0, \ + .p_reg = 0, \ + .pm_reg = 0, \ .pupd_reg = RZG_GET_PU_PD(node_id), \ .iolh_reg = DT_PROP(node_id, drive_strength), \ + .isel_reg = 0, \ .pmc_reg = 0, \ .ien_reg = DT_PROP(node_id, input_enable), \ .filonoff_reg = RZG_FILTER_ON_OFF(node_id), \ diff --git a/soc/renesas/rz/common/pinctrl_rzn.h b/soc/renesas/rz/common/pinctrl_rzn.h index 5779dab1a49f..9657c206168a 100644 --- a/soc/renesas/rz/common/pinctrl_rzn.h +++ b/soc/renesas/rz/common/pinctrl_rzn.h @@ -17,17 +17,20 @@ extern "C" { #define RZN_GET_FUNC(pinmux) ((pinmux & 0xF0) >> 4) /* Porting */ -typedef struct pinctrl_cfg_data_t { - uint32_t p_reg: 1; - uint32_t pm_reg: 2; - uint32_t pmc_reg: 1; - uint32_t pfc_reg: 4; - uint32_t drct_reg: 6; - uint32_t rsel_reg: 1; - uint32_t reserved: 17; +typedef union { + uint32_t cfg; + struct { + uint32_t p_reg: 1; + uint32_t pm_reg: 2; + uint32_t pmc_reg: 1; + uint32_t pfc_reg: 4; + uint32_t drct_reg: 6; + uint32_t rsel_reg: 1; + uint32_t reserved: 17; + } cfg_b; } pinctrl_cfg_data_t; -typedef struct pinctrl_soc_pin_t { +typedef struct pinctrl_soc_pin { bsp_io_port_pin_t port_pin; pinctrl_cfg_data_t config; } pinctrl_soc_pin_t; @@ -35,7 +38,7 @@ typedef struct pinctrl_soc_pin_t { #define Z_PINCTRL_STATE_PIN_INIT(node_id, prop, idx) \ { \ .port_pin = RZN_GET_PORT_PIN(DT_PROP_BY_IDX(node_id, prop, idx)), \ - .config = \ + .config.cfg_b = \ { \ .p_reg = DT_PROP(node_id, output_high), \ .pm_reg = DT_PROP(node_id, input_enable) == 1 \ diff --git a/soc/renesas/rz/common/pinctrl_rzt.h b/soc/renesas/rz/common/pinctrl_rzt.h index e9dc810a572b..f4f3e9c3bcdf 100644 --- a/soc/renesas/rz/common/pinctrl_rzt.h +++ b/soc/renesas/rz/common/pinctrl_rzt.h @@ -17,17 +17,20 @@ extern "C" { #define RZT_GET_FUNC(pinmux) ((pinmux & 0xF0) >> 4) /*Porting*/ -typedef struct pinctrl_cfg_data_t { - uint32_t p_reg: 1; - uint32_t pm_reg: 2; - uint32_t pmc_reg: 1; - uint32_t pfc_reg: 4; - uint32_t drct_reg: 6; - uint32_t rsel_reg: 1; - uint32_t reserved: 17; +typedef union { + uint32_t cfg; + struct { + uint32_t p_reg: 1; + uint32_t pm_reg: 2; + uint32_t pmc_reg: 1; + uint32_t pfc_reg: 4; + uint32_t drct_reg: 6; + uint32_t rsel_reg: 1; + uint32_t reserved: 17; + } cfg_b; } pinctrl_cfg_data_t; -typedef struct pinctrl_soc_pin_t { +typedef struct pinctrl_soc_pin { bsp_io_port_pin_t port_pin; pinctrl_cfg_data_t config; } pinctrl_soc_pin_t; @@ -35,7 +38,7 @@ typedef struct pinctrl_soc_pin_t { #define Z_PINCTRL_STATE_PIN_INIT(node_id, prop, idx) \ { \ .port_pin = RZT_GET_PORT_PIN(DT_PROP_BY_IDX(node_id, prop, idx)), \ - .config = \ + .config.cfg_b = \ { \ .p_reg = DT_PROP(node_id, output_high), \ .pm_reg = DT_PROP(node_id, input_enable) == 1 \ diff --git a/soc/renesas/rz/common/pinctrl_rzv.h b/soc/renesas/rz/common/pinctrl_rzv.h index c6bb736fa0e5..43384813c57b 100644 --- a/soc/renesas/rz/common/pinctrl_rzv.h +++ b/soc/renesas/rz/common/pinctrl_rzv.h @@ -15,20 +15,25 @@ extern "C" { #endif /* Porting */ -typedef struct pinctrl_cfg_data_t { - uint32_t reserved: 4; - uint32_t pupd_reg: 6; - uint32_t iolh_reg: 6; - uint32_t pmc_reg: 1; - uint32_t sr_reg: 1; - uint32_t ien_reg: 1; - uint32_t filonoff_reg: 1; - uint32_t filnum_reg: 2; - uint32_t filclksel_reg: 2; - uint32_t pfc_reg: 4; +typedef union { + uint32_t cfg; + struct { + uint32_t p_reg: 2; + uint32_t pm_reg: 2; + uint32_t pupd_reg: 6; + uint32_t iolh_reg: 4; + uint32_t isel_reg: 2; + uint32_t pmc_reg: 1; + uint32_t sr_reg: 1; + uint32_t ien_reg: 1; + uint32_t filonoff_reg: 1; + uint32_t filnum_reg: 2; + uint32_t filclksel_reg: 2; + uint32_t pfc_reg: 4; + } cfg_b; } pinctrl_cfg_data_t; -typedef struct pinctrl_soc_pin_t { +typedef struct pinctrl_soc_pin { bsp_io_port_pin_t port_pin; pinctrl_cfg_data_t config; } pinctrl_soc_pin_t; @@ -66,16 +71,21 @@ typedef struct pinctrl_soc_pin_t { #define Z_PINCTRL_PINMUX_INIT(node_id, state_prop, idx) \ { \ .port_pin = RZV_GET_PORT_PIN(DT_PROP_BY_IDX(node_id, state_prop, idx)), \ - .config = {.reserved = 0, \ - .pupd_reg = RZV_GET_PU_PD(node_id), \ - .iolh_reg = DT_PROP(node_id, drive_strength), \ - .pmc_reg = 1, \ - .sr_reg = DT_ENUM_IDX(node_id, slew_rate), \ - .ien_reg = DT_PROP(node_id, input_enable), \ - .filonoff_reg = RZV_FILTER_ON_OFF(node_id), \ - .filnum_reg = RZV_GET_FILNUM(node_id), \ - .filclksel_reg = RZV_GET_FILCLKSEL(node_id), \ - .pfc_reg = RZV_GET_FUNC(DT_PROP_BY_IDX(node_id, state_prop, idx))}, \ + .config.cfg_b = \ + { \ + .p_reg = 0, \ + .pm_reg = 0, \ + .pupd_reg = RZV_GET_PU_PD(node_id), \ + .iolh_reg = DT_PROP(node_id, drive_strength), \ + .isel_reg = 0, \ + .pmc_reg = 1, \ + .sr_reg = DT_ENUM_IDX(node_id, slew_rate), \ + .ien_reg = DT_PROP(node_id, input_enable), \ + .filonoff_reg = RZV_FILTER_ON_OFF(node_id), \ + .filnum_reg = RZV_GET_FILNUM(node_id), \ + .filclksel_reg = RZV_GET_FILCLKSEL(node_id), \ + .pfc_reg = RZV_GET_FUNC(DT_PROP_BY_IDX(node_id, state_prop, idx)), \ + }, \ }, #define Z_PINCTRL_SPECIAL_PINS_INIT(node_id, state_prop, idx) \ @@ -83,9 +93,11 @@ typedef struct pinctrl_soc_pin_t { .port_pin = DT_PROP_BY_IDX(node_id, state_prop, idx), \ .config = \ { \ - .reserved = 0, \ + .p_reg = 0, \ + .pm_reg = 0, \ .pupd_reg = RZV_GET_PU_PD(node_id), \ .iolh_reg = DT_PROP(node_id, drive_strength), \ + .isel_reg = 0, \ .pmc_reg = 0, \ .sr_reg = DT_ENUM_IDX(node_id, slew_rate), \ .ien_reg = DT_PROP(node_id, input_enable), \ From e200e829099d21fbf9ac5862482ab06db5a1f1bb Mon Sep 17 00:00:00 2001 From: Nhut Nguyen Date: Wed, 17 Dec 2025 15:55:59 +0700 Subject: [PATCH 2161/3659] drivers: gpio: renesas: Refactor gpio for RZ family - Decouple interrupt settings from gpio drivers, making them configured and handled independently by tint and ext_irq drivers. - Remove device-specific hardware definitions in gpio_renesas_rz.h and take advantage of pinctrl data type and dtsi for certain series. Signed-off-by: Nhut Nguyen --- drivers/gpio/Kconfig.renesas_rz | 13 +- drivers/gpio/gpio_renesas_rz.c | 677 +++++++++--------- drivers/gpio/gpio_renesas_rz.h | 181 ----- .../gpio/renesas,rz-gpio-common-v2.yaml | 8 + dts/bindings/gpio/renesas,rz-gpio-common.yaml | 8 + dts/bindings/gpio/renesas,rz-gpio.yaml | 30 +- 6 files changed, 367 insertions(+), 550 deletions(-) delete mode 100644 drivers/gpio/gpio_renesas_rz.h create mode 100644 dts/bindings/gpio/renesas,rz-gpio-common-v2.yaml create mode 100644 dts/bindings/gpio/renesas,rz-gpio-common.yaml diff --git a/drivers/gpio/Kconfig.renesas_rz b/drivers/gpio/Kconfig.renesas_rz index 5c9306ec2c4f..b7f18c9ae794 100644 --- a/drivers/gpio/Kconfig.renesas_rz +++ b/drivers/gpio/Kconfig.renesas_rz @@ -1,4 +1,4 @@ -# Copyright (c) 2024 Renesas Electronics Corporation +# Copyright (c) 2024-2025 Renesas Electronics Corporation # SPDX-License-Identifier: Apache-2.0 config GPIO_RENESAS_RZ @@ -9,9 +9,12 @@ config GPIO_RENESAS_RZ help Enable Renesas RZ series gpio driver. -config GPIO_RENESAS_RZ_HAS_GPIO_INTERRUPT +config GPIO_RENESAS_RZ_TYPE1 bool default y - depends on DT_HAS_RENESAS_RZ_GPIO_INT_ENABLED - help - GPIO pins can generate interrupts at port mode. + depends on DT_HAS_RENESAS_RZ_GPIO_COMMON_ENABLED + +config GPIO_RENESAS_RZ_TYPE2 + bool + default y + depends on DT_HAS_RENESAS_RZ_GPIO_COMMON_V2_ENABLED diff --git a/drivers/gpio/gpio_renesas_rz.c b/drivers/gpio/gpio_renesas_rz.c index d99a9975112f..46fcac2810e9 100644 --- a/drivers/gpio/gpio_renesas_rz.c +++ b/drivers/gpio/gpio_renesas_rz.c @@ -13,16 +13,39 @@ #include "r_ioport.h" #include #include -#include "gpio_renesas_rz.h" #include +#if defined(CONFIG_RENESAS_RZ_TINT) +#include +#endif #if defined(CONFIG_RENESAS_RZ_EXT_IRQ) #include "r_icu.h" #include #endif +#include "pinctrl_soc.h" LOG_MODULE_REGISTER(rz_gpio, CONFIG_GPIO_LOG_LEVEL); -#define LOG_DEV_ERR(dev, format, ...) LOG_ERR("%s:" #format, (dev)->name, ##__VA_ARGS__) -#define LOG_DEV_DBG(dev, format, ...) LOG_DBG("%s:" #format, (dev)->name, ##__VA_ARGS__) +#define GPIO_RZ_MODE_HIZ (0x0U) +#define GPIO_RZ_MODE_IN (0x1U) +#define GPIO_RZ_MODE_OUT (0x2U) +#define GPIO_RZ_MODE_OUT_IN (0x3U) + +#define GPIO_RZ_INT_EDGE_FALLING (0x0U) +#define GPIO_RZ_INT_EDGE_RISING (0x1U) +#define GPIO_RZ_INT_BOTH_EDGE (0x2U) +#define GPIO_RZ_INT_LEVEL_LOW (0x3U) +#define GPIO_RZ_INT_LEVEL_HIGH (0x4U) + +#define REG_P_READ(base, port) sys_read8((base) + regs.p + (port)) +#define REG_P_WRITE(base, port, v) sys_write8((v), (base) + regs.p + (port)) +#define REG_PM_READ(base, port) sys_read16((base) + regs.pm + (port) * 2) +#define REG_PM_WRITE(base, port, v) sys_write16((v), (base) + regs.pm + (port) * 2) +#define REG_PFC_READ(base, port) sys_read32((base) + regs.pfc + (port) * 4) +#define REG_PFC_WRITE(base, port, v) sys_write32((v), (base) + regs.pfc + (port) * 4) +#define REG_RSELP_READ(rselp, port) sys_read8(rselp + (port)) +#define REG_RSELP_WRITE(rselp, port, v) sys_write8((v), (rselp) + (port)) + +#define PORT(port_pin) FIELD_GET(BIT_MASK(8) << 8, port_pin) +#define PIN(port_pin) FIELD_GET(BIT_MASK(8), port_pin) struct gpio_rz_config { struct gpio_driver_config common; @@ -31,87 +54,214 @@ struct gpio_rz_config { bsp_io_port_t fsp_port; const ioport_cfg_t *fsp_cfg; const ioport_api_t *fsp_api; - const struct device *gpio_int_dev; - uint8_t int_num[GPIO_RZ_MAX_INT_NUM]; -#if defined(CONFIG_RENESAS_RZ_EXT_IRQ) - const struct device *ext_irq_dev[GPIO_RZ_MAX_INT_NUM]; - - void (*cb_list[GPIO_RZ_MAX_INT_NUM])(void *arg); -#endif + struct gpio_rz_irq_info *irq_info; + uint8_t irq_info_size; }; struct gpio_rz_data { struct gpio_driver_data common; sys_slist_t cb; - ioport_instance_ctrl_t *fsp_ctrl; + ioport_ctrl_t *fsp_ctrl; struct k_spinlock lock; -#if defined(CONFIG_RENESAS_RZ_EXT_IRQ) - uint8_t pin[GPIO_RZ_MAX_INT_NUM]; -#endif }; -struct gpio_rz_isr_data { +struct gpio_rz_pin { + uint32_t mode; + uint32_t func; + uint32_t out_state; +}; +struct gpio_rz_irq_info { + const struct device *irq_dev; const struct device *gpio_dev; - gpio_pin_t pin; + uint8_t pin; }; -struct gpio_rz_int_data { - struct gpio_rz_isr_data gpio_mapping[GPIO_RZ_MAX_INT_NUM]; - uint32_t irq_set_edge; +struct gpio_rz_regs { + mem_addr_t p; + mem_addr_t pm; + mem_addr_t pfc; +#ifdef CONFIG_GPIO_RENESAS_RZ_TYPE1 + mem_addr_t base; +#endif +#ifdef CONFIG_GPIO_RENESAS_RZ_TYPE2 + mem_addr_t rselp; + struct { + mem_addr_t ns; + mem_addr_t s; + } base; +#endif +} regs = { + .p = DT_REG_ADDR_BY_NAME(DT_NODELABEL(gpio), p), + .pm = DT_REG_ADDR_BY_NAME(DT_NODELABEL(gpio), pm), + .pfc = DT_REG_ADDR_BY_NAME(DT_NODELABEL(gpio), pfc), +#ifdef CONFIG_GPIO_RENESAS_RZ_TYPE1 + .base = DT_REG_ADDR_BY_NAME(DT_NODELABEL(gpio), base), +#endif +#ifdef CONFIG_GPIO_RENESAS_RZ_TYPE2 + .rselp = DT_REG_ADDR_BY_NAME(DT_NODELABEL(gpio), rselp), + .base = { + .ns = DT_REG_ADDR_BY_NAME(DT_NODELABEL(gpio), base_ns), + .s = DT_REG_ADDR_BY_NAME(DT_NODELABEL(gpio), base_s), + }, +#endif }; -struct gpio_rz_flags { - gpio_flags_t gpio_flags; - uint8_t pfc; -}; +/* Helper function to get current pin state from P register */ +static inline uint32_t gpio_rz_get_out_state(mem_addr_t base, uint8_t port, gpio_pin_t pin) +{ + return FIELD_GET(BIT_MASK(1) << pin, REG_P_READ(base, port)); +} -struct gpio_rz_int_config { - void (*gpio_int_init)(void); -}; +/* Helper function to get pin mode from PM register */ +static inline uint32_t gpio_rz_get_mode(mem_addr_t base, uint8_t port, gpio_pin_t pin) +{ + return FIELD_GET(BIT_MASK(2) << (pin * 2), REG_PM_READ(base, port)); +} -static int gpio_rz_pin_config_get_raw(bsp_io_port_pin_t port_pin, struct gpio_rz_flags *rz_flags); +/* Helper function to get pin function from PFC register */ +static inline uint32_t gpio_rz_get_func(mem_addr_t base, uint8_t port, gpio_pin_t pin) +{ + return FIELD_GET(BIT_MASK(4) << (pin * 4), REG_PFC_READ(base, port)); +} -#ifdef CONFIG_GPIO_GET_CONFIG -static int gpio_rz_pin_get_config(const struct device *dev, gpio_pin_t pin, gpio_flags_t *flags) +static __maybe_unused int gpio_rz_pincfg_to_flags(const struct gpio_rz_pin *pincfg, + gpio_flags_t *out_flags) { - const struct gpio_rz_config *config = dev->config; - bsp_io_port_pin_t port_pin = config->fsp_port | pin; - struct gpio_rz_flags rz_flags; + gpio_flags_t flags = 0; + + if (pincfg->mode == GPIO_RZ_MODE_OUT || pincfg->mode == GPIO_RZ_MODE_OUT_IN) { + if (pincfg->out_state != 0) { + flags |= GPIO_OUTPUT_HIGH; + } else { + flags |= GPIO_OUTPUT_LOW; + } + } - gpio_rz_pin_config_get_raw(port_pin, &rz_flags); - *flags = rz_flags.gpio_flags; + if (pincfg->mode == GPIO_RZ_MODE_IN || pincfg->mode == GPIO_RZ_MODE_OUT_IN) { + flags |= GPIO_INPUT; + } + + *out_flags = flags; return 0; } + +/* Get pin's configuration, used by pin_configure/pin_interrupt_configure api */ +static int gpio_rz_pin_config_get_raw(bsp_io_port_pin_t port_pin, struct gpio_rz_pin *pincfg) +{ + uint8_t port = PORT(port_pin); + gpio_pin_t pin = PIN(port_pin); + +#ifdef CONFIG_GPIO_RENESAS_RZ_TYPE1 + pincfg->mode = gpio_rz_get_mode(regs.base, port, pin); + pincfg->func = gpio_rz_get_func(regs.base, port, pin); + pincfg->out_state = gpio_rz_get_out_state(regs.base, port, pin); +#else /* CONFIG_GPIO_RENESAS_RZ_TYPE2 */ + pincfg->mode = gpio_rz_get_mode(regs.base.ns, port, pin); + pincfg->mode |= gpio_rz_get_mode(regs.base.s, port, pin); + + pincfg->func = gpio_rz_get_func(regs.base.ns, port, pin); + pincfg->func |= gpio_rz_get_func(regs.base.s, port, pin); + + pincfg->out_state = gpio_rz_get_out_state(regs.base.ns, port, pin); + pincfg->out_state |= gpio_rz_get_out_state(regs.base.s, port, pin); #endif -/* Get previous pin's configuration, used by pin_configure/pin_interrupt_configure api */ -static int gpio_rz_pin_config_get_raw(bsp_io_port_pin_t port_pin, struct gpio_rz_flags *rz_flags) + return 0; +} + +static int gpio_rz_flags_to_cfg(const gpio_flags_t flags, const struct gpio_rz_pin *curr_pincfg, + uint32_t *out_cfg) { - bsp_io_port_t port = (port_pin >> 8U) & 0xFF; - gpio_pin_t pin = port_pin & 0xFF; - volatile uint8_t *p_p = GPIO_RZ_P_REG_GET(port, pin); - volatile uint16_t *p_pm = GPIO_RZ_PM_REG_GET(port, pin); - volatile uint32_t *p_pfc = GPIO_RZ_PFC_REG_GET(port, pin); - - uint8_t p_value; - uint16_t pm_value; - uint32_t pfc_value; - - p_value = GPIO_RZ_P_VALUE_GET(*p_p, pin); - pm_value = GPIO_RZ_PM_VALUE_GET(*p_pm, pin); - pfc_value = GPIO_RZ_PFC_VALUE_GET(*p_pfc, pin); - - rz_flags->pfc = pfc_value; - rz_flags->gpio_flags = (pm_value << 16); - if (rz_flags->gpio_flags & GPIO_OUTPUT) { - if (p_value) { - rz_flags->gpio_flags |= GPIO_OUTPUT_INIT_HIGH; + if (flags & GPIO_OPEN_DRAIN) { + return -ENOTSUP; + } + + pinctrl_cfg_data_t pincfg; + + pincfg.cfg = 0; + if (flags & GPIO_INPUT) { + if (flags & GPIO_OUTPUT) { + pincfg.cfg |= IOPORT_CFG_PORT_DIRECTION_OUTPUT_INPUT; } else { - rz_flags->gpio_flags |= GPIO_OUTPUT_INIT_LOW; + pincfg.cfg |= IOPORT_CFG_PORT_DIRECTION_INPUT; } + } else if (flags & GPIO_OUTPUT) { + pincfg.cfg |= IOPORT_CFG_PORT_DIRECTION_OUTPUT; + } else { + pincfg.cfg |= IOPORT_CFG_PORT_DIRECTION_HIZ; } + if (flags & GPIO_OUTPUT_INIT_HIGH) { + pincfg.cfg |= IOPORT_CFG_PORT_OUTPUT_HIGH; + } else if (flags & GPIO_OUTPUT_INIT_LOW) { + pincfg.cfg &= ~IOPORT_CFG_PORT_OUTPUT_HIGH; + } else { + /* Keep the current state */ + pincfg.cfg_b.p_reg = curr_pincfg->out_state; + } + + if (flags & GPIO_PULL_UP) { + pincfg.cfg |= IOPORT_CFG_PULLUP_ENABLE; + } else if (flags & GPIO_PULL_DOWN) { + pincfg.cfg |= IOPORT_CFG_PULLDOWN_ENABLE; + } + + if (flags & GPIO_INT_ENABLE) { + IF_ENABLED(CONFIG_GPIO_RENESAS_RZ_TYPE1, ( + pincfg.cfg_b.isel_reg = 1; + )) + + IF_ENABLED(CONFIG_GPIO_RENESAS_RZ_TYPE2, ( + pincfg.cfg_b.pmc_reg = 1; + )) + } else if (flags & GPIO_INT_DISABLE) { + IF_ENABLED(CONFIG_GPIO_RENESAS_RZ_TYPE1, ( + pincfg.cfg_b.isel_reg = 0; + )) + + IF_ENABLED(CONFIG_GPIO_RENESAS_RZ_TYPE2, ( + pincfg.cfg_b.pmc_reg = 0; + )) + } + + /* Type 1 (RZ/A,G,V): IOLH, FILONOFF, FILNUM, FILCLKSEL + * Type 2 (RZ/T,N): DRCTL, RSELP + */ + IF_ENABLED(CONFIG_GPIO_RENESAS_RZ_TYPE1, ( + pincfg.cfg_b.iolh_reg = FIELD_GET(GENMASK(9, 8), flags); + pincfg.cfg_b.filonoff_reg = FIELD_GET(BIT(10), flags); + pincfg.cfg_b.filnum_reg = FIELD_GET(GENMASK(12, 11), flags); + pincfg.cfg_b.filclksel_reg = FIELD_GET(GENMASK(14, 13), flags); + )) + + IF_ENABLED(CONFIG_GPIO_RENESAS_RZ_TYPE2, ( + /* Must use OR for DRCTL since it is already updated for pull-up/down above */ + pincfg.cfg_b.drct_reg |= FIELD_GET(GENMASK(9, 8), flags); + pincfg.cfg_b.rsel_reg = FIELD_GET(BIT(14), flags); + )) + + /* PFC */ + pincfg.cfg_b.pfc_reg = curr_pincfg->func; + + *out_cfg = pincfg.cfg; + + return 0; +} + +static __maybe_unused int gpio_rz_pin_get_config(const struct device *dev, gpio_pin_t pin, + gpio_flags_t *flags) +{ + const struct gpio_rz_config *config = dev->config; + bsp_io_port_pin_t port_pin = config->fsp_port | pin; + struct gpio_rz_pin pincfg; + + /* Get the current pin config */ + gpio_rz_pin_config_get_raw(port_pin, &pincfg); + + /* Convert the pin config to flags */ + gpio_rz_pincfg_to_flags(&pincfg, flags); + return 0; } @@ -120,76 +270,21 @@ static int gpio_rz_pin_configure(const struct device *dev, gpio_pin_t pin, gpio_ const struct gpio_rz_config *config = dev->config; struct gpio_rz_data *data = dev->data; bsp_io_port_pin_t port_pin = config->fsp_port | pin; - uint32_t ioport_config_data = 0; - struct gpio_rz_flags rz_flags; + struct gpio_rz_pin curr_pincfg; + uint32_t cfg = 0; fsp_err_t err; + int ret; - gpio_rz_pin_config_get_raw(port_pin, &rz_flags); - - if (!flags) { - /* Disconnect mode */ - GPIO_RZ_PIN_DISCONNECT(config->fsp_port, pin); - } else if (!(flags & GPIO_OPEN_DRAIN)) { - /* PM register */ - if (flags & GPIO_INPUT) { - if (flags & GPIO_OUTPUT) { - ioport_config_data |= IOPORT_CFG_PORT_DIRECTION_OUTPUT_INPUT; - } else { - ioport_config_data |= IOPORT_CFG_PORT_DIRECTION_INPUT; - } - } else if (flags & GPIO_OUTPUT) { - ioport_config_data |= IOPORT_CFG_PORT_DIRECTION_OUTPUT; - } - /* P register */ - if (!(flags & (GPIO_OUTPUT_INIT_HIGH | GPIO_OUTPUT_INIT_LOW))) { - flags |= rz_flags.gpio_flags & - (GPIO_OUTPUT_INIT_HIGH | GPIO_OUTPUT_INIT_LOW); - } - - if (flags & GPIO_OUTPUT_INIT_HIGH) { - ioport_config_data |= IOPORT_CFG_PORT_OUTPUT_HIGH; - } else if (flags & GPIO_OUTPUT_INIT_LOW) { - ioport_config_data &= ~(IOPORT_CFG_PORT_OUTPUT_HIGH); - } - /* PUPD register */ - if (flags & GPIO_PULL_UP) { - ioport_config_data |= IOPORT_CFG_PULLUP_ENABLE; - } else if (flags & GPIO_PULL_DOWN) { - ioport_config_data |= IOPORT_CFG_PULLDOWN_ENABLE; - } - - /* - * Interrupt register - * RZ/A,G,V: ISEL - * RZ/T,N: PMC - */ - if (flags & GPIO_INT_ENABLE) { - ioport_config_data |= GPIO_RZ_INT_ENABLE; - } else if (flags & GPIO_INT_DISABLE) { - ioport_config_data &= GPIO_RZ_INT_DISABLE; - } + /* Get the current pin config */ + gpio_rz_pin_config_get_raw(port_pin, &curr_pincfg); - /* - * Drive ability register - * RZ/A,G,V: IOLH - * RZ/T,N: DRCTL - */ - ioport_config_data |= GPIO_RZ_FLAG_GET_CONFIG(flags); - - /* PFC register */ - ioport_config_data |= GPIO_RZ_FLAG_SET_PFC(rz_flags.pfc); - - /* - * Specific register - * RZ/A,G,V: FILONOFF, FILNUM, FILCLKSEL - * RZ/T,N: RSELP - */ - ioport_config_data |= GPIO_RZ_FLAG_GET_SPECIFIC(flags); - } else { - return -ENOTSUP; + /* Convert flags and current pin config to pin config */ + ret = gpio_rz_flags_to_cfg(flags, &curr_pincfg, &cfg); + if (ret < 0) { + return ret; } - err = config->fsp_api->pinCfg(data->fsp_ctrl, port_pin, ioport_config_data); + err = config->fsp_api->pinCfg(data->fsp_ctrl, port_pin, cfg); if (err != FSP_SUCCESS) { return -EIO; } @@ -265,121 +360,108 @@ static int gpio_rz_port_clear_bits_raw(const struct device *dev, gpio_port_pins_ static int gpio_rz_port_toggle_bits(const struct device *dev, gpio_port_pins_t pins) { const struct gpio_rz_config *config = dev->config; - struct gpio_rz_data *data = dev->data; - bsp_io_port_pin_t port_pin; - struct gpio_rz_flags rz_flags; - ioport_size_t value = 0; - fsp_err_t err; + uint8_t val; + uint8_t port = PORT(config->fsp_port); - for (uint8_t idx = 0; idx < config->ngpios; idx++) { - if (pins & (1U << idx)) { - port_pin = config->fsp_port | idx; - gpio_rz_pin_config_get_raw(port_pin, &rz_flags); - if (rz_flags.gpio_flags & GPIO_OUTPUT_INIT_HIGH) { - value &= (1U << idx); - } else if (rz_flags.gpio_flags & GPIO_OUTPUT_INIT_LOW) { - value |= (1U << idx); - } - } - } - err = config->fsp_api->portWrite(data->fsp_ctrl, config->fsp_port, value, - (ioport_size_t)pins); - if (err != FSP_SUCCESS) { - return -EIO; - } +#ifdef CONFIG_GPIO_RENESAS_RZ_TYPE1 + val = REG_P_READ(regs.base, port); + REG_P_WRITE(regs.base, port, val ^ pins); +#else /* CONFIG_GPIO_RENESAS_RZ_TYPE2 */ + uint8_t rselp = REG_RSELP_READ(regs.rselp, port); + + uint8_t pins_ns = rselp & pins; + uint8_t pins_s = ~rselp & pins; + + val = REG_P_READ(regs.base.ns, port); + REG_P_WRITE(regs.base.ns, port, val ^ pins_ns); + + val = REG_P_READ(regs.base.s, port); + REG_P_WRITE(regs.base.s, port, val ^ pins_s); +#endif /* CONFIG_GPIO_RENESAS_RZ_TYPE1 */ return 0; } -#if defined(CONFIG_GPIO_RENESAS_RZ_HAS_GPIO_INTERRUPT) || defined(CONFIG_RENESAS_RZ_EXT_IRQ) -static int gpio_rz_int_disable(const struct device *dev, const struct device *gpio_dev, - uint8_t int_num, gpio_pin_t pin) +#if defined(CONFIG_RENESAS_RZ_TINT) || defined(CONFIG_RENESAS_RZ_EXT_IRQ) +static int gpio_rz_int_disable(struct gpio_rz_irq_info *irq_info) { -#if defined(CONFIG_GPIO_RENESAS_RZ_HAS_GPIO_INTERRUPT) - volatile uint32_t *tssr = &R_INTC->TSSR0; - volatile uint32_t *titsr = &R_INTC->TITSR0; - struct gpio_rz_int_data *data = dev->data; - - /* Get register offset base on interrupt number. */ - tssr = &tssr[int_num / 4]; - titsr = &titsr[int_num / 16]; - GPIO_RZ_TINT_SELECT_SOURCE_REG_CLEAR(int_num); - - irq_disable(GPIO_RZ_TINT_IRQ_GET(int_num)); - /* Disable interrupt and clear interrupt source. */ - *tssr &= ~(0xFF << GPIO_RZ_TSSR_OFFSET(int_num)); - /* Reset interrupt dectect type to default. */ - *titsr &= ~(0x3 << GPIO_RZ_TITSR_OFFSET(int_num)); - - /* Clear interrupt detection status. */ - if (data->irq_set_edge & BIT(int_num)) { - GPIO_RZ_TINT_STATUS_REG_CLEAR(int_num); - data->irq_set_edge &= ~BIT(int_num); +#if defined(CONFIG_RENESAS_RZ_TINT) + if (strstr(irq_info->irq_dev->name, "tint") != NULL) { + return intc_rz_tint_disable(irq_info->irq_dev); } +#endif /* CONFIG_RENESAS_RZ_TINT */ - data->gpio_mapping[int_num].gpio_dev = NULL; - data->gpio_mapping[int_num].pin = UINT8_MAX; -#elif defined(CONFIG_RENESAS_RZ_EXT_IRQ) - const struct gpio_rz_config *gpio_config = gpio_dev->config; - const struct device *ext_irq_dev = gpio_config->ext_irq_dev[pin]; - - if (device_is_ready(ext_irq_dev)) { - intc_rz_ext_irq_disable(ext_irq_dev); +#if defined(CONFIG_RENESAS_RZ_EXT_IRQ) + if (strstr(irq_info->irq_dev->name, "irq") != NULL) { + return intc_rz_ext_irq_disable(irq_info->irq_dev); } #endif /* CONFIG_RENESAS_RZ_EXT_IRQ */ return 0; } -static int gpio_rz_int_enable(const struct device *gpio_int_dev, const struct device *gpio_dev, - uint8_t int_num, uint8_t irq_type, gpio_pin_t pin) +static void gpio_rz_callback(void *arg); + +static int gpio_rz_int_enable(struct gpio_rz_irq_info *irq_info, uint8_t irq_type) { - if (irq_type == GPIO_RZ_INT_UNSUPPORTED) { - return -ENOTSUP; + int ret = 0; + const struct device *irq_dev = irq_info->irq_dev; + +#if defined(CONFIG_RENESAS_RZ_TINT) + if (strstr(irq_dev->name, "tint") != NULL) { + const struct gpio_rz_config *gpio_config = irq_info->gpio_dev->config; + + ret = intc_rz_tint_connect(irq_dev, gpio_config->port_num, irq_info->pin); + if (ret < 0) { + return ret; + } + + ret = intc_rz_tint_set_type(irq_dev, irq_type); + if (ret < 0) { + return ret; + } + + intc_rz_tint_enable(irq_dev); + intc_rz_tint_set_callback(irq_dev, gpio_rz_callback, (void *)irq_info); } +#endif /* CONFIG_RENESAS_RZ_TINT */ + +#if defined(CONFIG_RENESAS_RZ_EXT_IRQ) + if (strstr(irq_dev->name, "irq") != NULL) { + ret = intc_rz_ext_irq_set_type(irq_dev, irq_type); + if (ret < 0) { + return ret; + } - const struct gpio_rz_config *gpio_config = gpio_dev->config; - -#if defined(CONFIG_GPIO_RENESAS_RZ_HAS_GPIO_INTERRUPT) - volatile uint32_t *tssr = &R_INTC->TSSR0; - volatile uint32_t *titsr = &R_INTC->TITSR0; - struct gpio_rz_int_data *gpio_int_data = gpio_int_dev->data; - - tssr = &tssr[int_num / 4]; - titsr = &titsr[int_num / 16]; - /* Select interrupt detect type. */ - *titsr &= ~(3U << GPIO_RZ_TITSR_OFFSET(int_num)); - *titsr |= (irq_type << GPIO_RZ_TITSR_OFFSET(int_num)); - /* Select interrupt source base on port and pin number. */ - *tssr &= ~(0xFF << (int_num)); - *tssr |= (GPIO_RZ_TSSR_VAL(gpio_config->port_num, pin)) << GPIO_RZ_TSSR_OFFSET(int_num); - /* Select TINT source */ - GPIO_RZ_TINT_SELECT_SOURCE_REG_CLEAR(int_num); - GPIO_RZ_TINT_SELECT_SOURCE_REG_SET(int_num); - - if (irq_type == GPIO_RZ_INT_EDGE_RISING || irq_type == GPIO_RZ_INT_EDGE_FALLING) { - gpio_int_data->irq_set_edge |= BIT(int_num); - /* Clear interrupt status. */ - GPIO_RZ_TINT_STATUS_REG_CLEAR(int_num); + intc_rz_ext_irq_enable(irq_dev); + intc_rz_ext_irq_set_callback(irq_dev, gpio_rz_callback, (void *)irq_info); } - GPIO_RZ_TINT_CLEAR_PENDING(int_num); - irq_enable(GPIO_RZ_TINT_IRQ_GET(int_num)); - gpio_int_data->gpio_mapping[int_num].gpio_dev = gpio_dev; - gpio_int_data->gpio_mapping[int_num].pin = pin; -#elif defined(CONFIG_RENESAS_RZ_EXT_IRQ) - const struct device *ext_irq_dev = gpio_config->ext_irq_dev[pin]; +#endif /* CONFIG_RENESAS_RZ_EXT_IRQ */ + + return ret; +} + +static void gpio_rz_callback(void *arg) +{ + const struct gpio_rz_irq_info *irq_info = (const struct gpio_rz_irq_info *)arg; + const struct device *gpio_dev = irq_info->gpio_dev; struct gpio_rz_data *gpio_data = gpio_dev->data; - gpio_data->pin[int_num] = pin; - if (device_is_ready(ext_irq_dev)) { - intc_rz_ext_irq_set_type(ext_irq_dev, irq_type); - intc_rz_ext_irq_enable(ext_irq_dev); - intc_rz_ext_irq_set_callback(ext_irq_dev, gpio_config->cb_list[int_num], - (void *)gpio_dev); + gpio_fire_callbacks(&gpio_data->cb, gpio_dev, BIT(irq_info->pin)); +} + +static struct gpio_rz_irq_info *gpio_rz_get_irq_info(const struct device *dev, gpio_pin_t pin) +{ + const struct gpio_rz_config *config = dev->config; + struct gpio_rz_irq_info *irq_info = config->irq_info; + + for (int i = 0; i < config->irq_info_size; i++) { + if (irq_info[i].pin == pin) { + return &irq_info[i]; + } } -#endif /* CONFIG_GPIO_RENESAS_RZ_HAS_GPIO_INTERRUPT */ - return 0; + return NULL; } static int gpio_rz_pin_interrupt_configure(const struct device *dev, gpio_pin_t pin, @@ -387,28 +469,32 @@ static int gpio_rz_pin_interrupt_configure(const struct device *dev, gpio_pin_t { const struct gpio_rz_config *config = dev->config; struct gpio_rz_data *data = dev->data; - bsp_io_port_pin_t port_pin = config->fsp_port | pin; - uint8_t int_num = config->int_num[pin]; uint8_t irq_type = 0; - struct gpio_rz_flags rz_flags; + gpio_flags_t flags; k_spinlock_key_t key; int ret = 0; - if (int_num >= GPIO_RZ_MAX_INT_NUM) { - LOG_DEV_ERR(dev, "Invalid interrupt:%d >= %d", int_num, GPIO_RZ_MAX_INT_NUM); - } - - if (pin > config->ngpios) { + if (pin >= config->ngpios) { return -EINVAL; } key = k_spin_lock(&data->lock); + gpio_rz_pin_get_config(dev, pin, &flags); + ret = gpio_rz_pin_configure(dev, pin, flags | mode); + if (ret < 0) { + goto exit_unlock; + } + + struct gpio_rz_irq_info *irq_info = gpio_rz_get_irq_info(dev, pin); + + if (!irq_info || !device_is_ready(irq_info->irq_dev)) { + /* No interrupt to configure */ + goto exit_unlock; + } + if (mode == GPIO_INT_MODE_DISABLED) { - gpio_rz_pin_config_get_raw(port_pin, &rz_flags); - rz_flags.gpio_flags |= GPIO_INT_DISABLE; - gpio_rz_pin_configure(dev, pin, rz_flags.gpio_flags); - gpio_rz_int_disable(config->gpio_int_dev, dev, int_num, pin); + ret = gpio_rz_int_disable(irq_info); goto exit_unlock; } @@ -428,12 +514,7 @@ static int gpio_rz_pin_interrupt_configure(const struct device *dev, gpio_pin_t } } - ret = gpio_rz_int_enable(config->gpio_int_dev, dev, int_num, irq_type, pin); - if (ret == 0) { - gpio_rz_pin_config_get_raw(port_pin, &rz_flags); - rz_flags.gpio_flags |= GPIO_INT_ENABLE; - gpio_rz_pin_configure(dev, pin, rz_flags.gpio_flags); - } + ret = gpio_rz_int_enable(irq_info, irq_type); exit_unlock: k_spin_unlock(&data->lock, key); @@ -449,38 +530,7 @@ static int gpio_rz_manage_callback(const struct device *dev, struct gpio_callbac return gpio_manage_callback(&data->cb, callback, set); } -static void gpio_rz_isr(uint16_t irq, void *param) -{ -#if defined(CONFIG_GPIO_RENESAS_RZ_HAS_GPIO_INTERRUPT) - const struct device *dev = param; - struct gpio_rz_int_data *gpio_int_data = dev->data; - -#if GPIO_RZ_TINT_SPURIOUS_HANDLE - if (!(*GPIO_RZ_TINT_STATUS_REG_GET & BIT(irq))) { - LOG_DEV_DBG(dev, "tint:%u spurious irq, status 0", irq); - return; - } -#endif /* GPIO_RZ_TINT_SPURIOUS_HANDLE */ - - if (gpio_int_data->irq_set_edge & BIT(irq)) { - GPIO_RZ_TINT_STATUS_REG_CLEAR(irq); - } - - uint8_t pin = gpio_int_data->gpio_mapping[irq].pin; - const struct device *gpio_dev = gpio_int_data->gpio_mapping[irq].gpio_dev; - struct gpio_rz_data *gpio_data = gpio_dev->data; - - gpio_fire_callbacks(&gpio_data->cb, gpio_dev, BIT(pin)); -#elif defined(CONFIG_RENESAS_RZ_EXT_IRQ) - const struct device *gpio_dev = (const struct device *)param; - struct gpio_rz_data *gpio_data = gpio_dev->data; - uint8_t pin = gpio_data->pin[irq]; - - gpio_fire_callbacks(&gpio_data->cb, gpio_dev, BIT(pin)); -#endif /* CONFIG_GPIO_RENESAS_RZ_HAS_GPIO_INTERRUPT */ -} - -#endif /* CONFIG_GPIO_RENESAS_RZ_HAS_GPIO_INTERRUPT || CONFIG_RENESAS_RZ_EXT_IRQ */ +#endif /* CONFIG_RENESAS_RZ_TINT || CONFIG_RENESAS_RZ_EXT_IRQ */ static DEVICE_API(gpio, gpio_rz_driver_api) = { .pin_configure = gpio_rz_pin_configure, @@ -492,100 +542,26 @@ static DEVICE_API(gpio, gpio_rz_driver_api) = { .port_set_bits_raw = gpio_rz_port_set_bits_raw, .port_clear_bits_raw = gpio_rz_port_clear_bits_raw, .port_toggle_bits = gpio_rz_port_toggle_bits, -#if defined(CONFIG_GPIO_RENESAS_RZ_HAS_GPIO_INTERRUPT) || defined(CONFIG_RENESAS_RZ_EXT_IRQ) +#if defined(CONFIG_RENESAS_RZ_TINT) || defined(CONFIG_RENESAS_RZ_EXT_IRQ) .pin_interrupt_configure = gpio_rz_pin_interrupt_configure, .manage_callback = gpio_rz_manage_callback, #endif }; -/* Initialize GPIO interrupt device */ -#define GPIO_RZ_ISR_DEFINE(idx, _) \ - static void rz_gpio_isr##idx(void *param) \ +#define IRQ_INFO_GET_BY_IDX(node_id, prop, idx, inst) \ { \ - gpio_rz_isr(idx, param); \ + .irq_dev = DEVICE_DT_GET_OR_NULL(DT_PHANDLE_BY_IDX(node_id, irqs, idx)), \ + .gpio_dev = DEVICE_DT_INST_GET(inst), \ + .pin = DT_PHA_BY_IDX(node_id, irqs, idx, pin), \ } -#define GPIO_RZ_ALL_ISR_DEFINE(irq_num) LISTIFY(irq_num, GPIO_RZ_ISR_DEFINE, ()) - -#if defined(CONFIG_GPIO_RENESAS_RZ_HAS_GPIO_INTERRUPT) || defined(CONFIG_RENESAS_RZ_EXT_IRQ) -#if defined(CONFIG_GPIO_RENESAS_RZ_HAS_GPIO_INTERRUPT) - -#define GPIO_RZ_INT_DEFINE(inst) \ - .gpio_int_dev = DEVICE_DT_GET_OR_NULL(DT_INST(0, renesas_rz_gpio_int)) - -static int gpio_rz_int_init(const struct device *dev) -{ - const struct gpio_rz_int_config *config = dev->config; - - config->gpio_int_init(); - - return 0; -} - -#define GPIO_RZ_INT_CONNECT(idx, node_id) \ - IRQ_CONNECT(DT_IRQ_BY_IDX(node_id, idx, irq), DT_IRQ_BY_IDX(node_id, idx, priority), \ - rz_gpio_isr##idx, DEVICE_DT_GET(node_id), 0); - -#define GPIO_RZ_INT_CONNECT_FUNC(node_id) \ - static void rz_gpio_int_connect_func##node_id(void) \ - { \ - LISTIFY(DT_NUM_IRQS(node_id), \ - GPIO_RZ_INT_CONNECT, (;), \ - node_id) \ - } -/* Initialize GPIO device */ -#define GPIO_RZ_INT_INIT(node_id) \ - GPIO_RZ_ALL_ISR_DEFINE(DT_NUM_IRQS(node_id)) \ - GPIO_RZ_INT_CONNECT_FUNC(node_id) \ - static const struct gpio_rz_int_config rz_gpio_int_cfg_##node_id = { \ - .gpio_int_init = rz_gpio_int_connect_func##node_id, \ - }; \ - static struct gpio_rz_int_data rz_gpio_int_data_##node_id = {}; \ - DEVICE_DT_DEFINE(node_id, gpio_rz_int_init, NULL, &rz_gpio_int_data_##node_id, \ - &rz_gpio_int_cfg_##node_id, POST_KERNEL, \ - UTIL_DEC(CONFIG_GPIO_INIT_PRIORITY), NULL); -DT_FOREACH_STATUS_OKAY(renesas_rz_gpio_int, GPIO_RZ_INT_INIT) - -#elif defined(CONFIG_RENESAS_RZ_EXT_IRQ) - -GPIO_RZ_ALL_ISR_DEFINE(GPIO_RZ_MAX_INT_NUM) - -#define EXT_IRQ_CB_GET(ext_irq, _) [ext_irq] = rz_gpio_isr##ext_irq - -#define EXT_IRQ_DEV_LABEL_GET(inst, idx) CONCAT(irq, DT_INST_PROP_BY_IDX(inst, irqs, UTIL_INC(idx))) - -#define EXT_IRQ_DEV_GET(idx, inst) \ - COND_CODE_1(DT_INST_PROP_HAS_IDX(inst, irqs, idx), \ - ([DT_INST_PROP_BY_IDX(inst, irqs, idx)] = \ - DEVICE_DT_GET_OR_NULL(DT_NODELABEL(EXT_IRQ_DEV_LABEL_GET(inst, idx))),), \ - ()) - -#define ALL_EXT_IRQ_DEV_GET(inst) \ - FOR_EACH_FIXED_ARG(EXT_IRQ_DEV_GET, (), inst, \ - LISTIFY(DT_INST_PROP_LEN_OR(inst, irqs, 0), VALUE_2X, (,))) - -#define GPIO_RZ_INT_DEFINE(inst) \ - .ext_irq_dev = {ALL_EXT_IRQ_DEV_GET(inst)}, \ - .cb_list = {LISTIFY(GPIO_RZ_MAX_INT_NUM, EXT_IRQ_CB_GET, (,))} - -#endif /* CONFIG_GPIO_RENESAS_RZ_HAS_GPIO_INTERRUPT */ - -#else -#define GPIO_RZ_INT_DEFINE(inst) -#endif /* CONFIG_GPIO_RENESAS_RZ_HAS_GPIO_INTERRUPT || CONFIG_RENESAS_RZ_EXT_IRQ */ - -#define VALUE_2X(i, _) UTIL_X2(i) -#define PIN_IRQ_GET(idx, inst) \ - COND_CODE_1(DT_INST_PROP_HAS_IDX(inst, irqs, idx), \ - ([DT_INST_PROP_BY_IDX(inst, irqs, idx)] = \ - DT_INST_PROP_BY_IDX(inst, irqs, UTIL_INC(idx)),), \ - ()) - -#define PIN_IRQS_GET(inst) \ - FOR_EACH_FIXED_ARG(PIN_IRQ_GET, (), inst, \ - LISTIFY(DT_INST_PROP_LEN_OR(inst, irqs, 0), VALUE_2X, (,))) +#define IRQ_INFO_GET(inst) \ + COND_CODE_1(DT_INST_NODE_HAS_PROP(inst, irqs), \ + (DT_INST_FOREACH_PROP_ELEM_SEP_VARGS(inst, irqs, \ + IRQ_INFO_GET_BY_IDX, (,), inst)), ()) #define RZ_GPIO_PORT_INIT(inst) \ + static struct gpio_rz_irq_info gpio_rz_irq_info_##inst[] = {IRQ_INFO_GET(inst)}; \ static ioport_cfg_t g_ioport_##inst##_cfg = { \ .number_of_pins = 0, \ .p_pin_cfg_data = NULL, \ @@ -602,8 +578,9 @@ GPIO_RZ_ALL_ISR_DEFINE(GPIO_RZ_MAX_INT_NUM) .ngpios = (uint8_t)DT_INST_PROP(inst, ngpios), \ .fsp_cfg = &g_ioport_##inst##_cfg, \ .fsp_api = &g_ioport_on_ioport, \ - .int_num = {PIN_IRQS_GET(inst)}, \ - GPIO_RZ_INT_DEFINE(inst)}; \ + .irq_info = gpio_rz_irq_info_##inst, \ + .irq_info_size = ARRAY_SIZE(gpio_rz_irq_info_##inst), \ + }; \ static ioport_instance_ctrl_t g_ioport_##inst##_ctrl; \ static struct gpio_rz_data gpio_rz_##inst##_data = { \ .fsp_ctrl = &g_ioport_##inst##_ctrl, \ diff --git a/drivers/gpio/gpio_renesas_rz.h b/drivers/gpio/gpio_renesas_rz.h deleted file mode 100644 index 3258ca8bd06b..000000000000 --- a/drivers/gpio/gpio_renesas_rz.h +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright (c) 2024-2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef ZEPHYR_DRIVERS_GPIO_RENESAS_RZ_H_ -#define ZEPHYR_DRIVERS_GPIO_RENESAS_RZ_H_ - -#include "r_ioport.h" -#include - -#define GPIO_RZ_INT_UNSUPPORTED 0xF - -#if defined(CONFIG_SOC_SERIES_RZG3S) || defined(CONFIG_SOC_SERIES_RZA3UL) || \ - defined(CONFIG_SOC_SERIES_RZV2L) || defined(CONFIG_SOC_SERIES_RZG2L) || \ - defined(CONFIG_SOC_SERIES_RZV2H) || defined(CONFIG_SOC_SERIES_RZG2UL) || \ - defined(CONFIG_SOC_SERIES_RZV2N) -#include - -#if defined(CONFIG_SOC_SERIES_RZG3S) -#define GPIO_RZ_P_REG_BASE_GET (&R_GPIO->P_20) -#define GPIO_RZ_PM_REG_BASE_GET (&R_GPIO->PM_20) -#define GPIO_RZ_PFC_REG_BASE_GET (&R_GPIO->PFC_20) -#define GPIO_RZ_MAX_PORT_NUM 19 -#define GPIO_RZ_TINT_IRQ_OFFSET 429 -#define R_INTC R_INTC_IM33 -#define GPIO_RZ_TINT_STATUS_REG_CLEAR(tint_num) (R_INTC_IM33->TSCR &= ~BIT(tint_num)) -static const uint8_t gpio_rz_int[GPIO_RZ_MAX_PORT_NUM] = {0, 4, 9, 13, 17, 23, 28, 33, 38, 43, - 47, 52, 56, 58, 63, 66, 70, 72, 76}; - -#elif defined(CONFIG_SOC_SERIES_RZA3UL) -#define GPIO_RZ_P_REG_BASE_GET (&R_GPIO->P10) -#define GPIO_RZ_PM_REG_BASE_GET (&R_GPIO->PM10) -#define GPIO_RZ_PFC_REG_BASE_GET (&R_GPIO->PFC10) -#define GPIO_RZ_MAX_PORT_NUM 19 -#define GPIO_RZ_TINT_IRQ_OFFSET 476 -#define R_INTC R_INTC_IA55 -#define GPIO_RZ_TINT_STATUS_REG_CLEAR(tint_num) (R_INTC_IA55->TSCR &= ~BIT(tint_num)) -static const uint8_t gpio_rz_int[GPIO_RZ_MAX_PORT_NUM] = {0, 4, 9, 13, 17, 23, 28, 33, 38, 43, - 47, 52, 56, 58, 63, 66, 70, 72, 76}; - -#elif defined(CONFIG_SOC_SERIES_RZV2H) || defined(CONFIG_SOC_SERIES_RZV2N) -#define GPIO_RZ_P_REG_BASE_GET (&R_GPIO->P20) -#define GPIO_RZ_PM_REG_BASE_GET (&R_GPIO->PM20) -#define GPIO_RZ_PFC_REG_BASE_GET (&R_GPIO->PFC20) -#define GPIO_RZ_TINT_STATUS_REG_GET (&R_INTC->TSCTR) - -#ifdef CONFIG_CPU_CORTEX_M -#define GPIO_RZ_TINT_IRQ_OFFSET 353 -#define GPIO_RZ_TINT_SPURIOUS_HANDLE 0 -#define GPIO_RZ_TINT_SELECT_SOURCE_REG_GET (&R_INTC->INTM33SEL0) -#else /* Cortex-R */ -#define GPIO_RZ_TINT_IRQ_OFFSET (GIC_SPI_INT_BASE + 353) -#define GPIO_RZ_TINT_SELECT_SOURCE_REG_GET (&R_INTC->INTR8SEL0) -#endif - -#define GPIO_RZ_MAX_PORT_NUM 12 -#define GPIO_RZ_TINT_STATUS_REG_CLEAR(tint_num) (R_INTC->TSCLR |= BIT(tint_num)) -#define GPIO_RZ_TINT_SELECT_SOURCE_REG_CLEAR(tint_num) \ - GPIO_RZ_TINT_SELECT_SOURCE_REG_GET[int_num / 3] &= ~(0x3FF << ((int_num % 3) * 10)); -#define GPIO_RZ_TINT_SELECT_SOURCE_REG_SET(tint_num) \ - GPIO_RZ_TINT_SELECT_SOURCE_REG_GET[int_num / 3] |= (int_num << ((int_num % 3) * 10)); -static const uint8_t gpio_rz_int[GPIO_RZ_MAX_PORT_NUM] = {0, 8, 14, 16, 24, 32, - 40, 48, 56, 64, 72, 80}; - -#elif defined(CONFIG_SOC_SERIES_RZV2L) || defined(CONFIG_SOC_SERIES_RZG2L) -#define GPIO_RZ_P_REG_BASE_GET (&R_GPIO->P10) -#define GPIO_RZ_PM_REG_BASE_GET (&R_GPIO->PM10) -#define GPIO_RZ_PFC_REG_BASE_GET (&R_GPIO->PFC10) -#define GPIO_RZ_MAX_PORT_NUM 49 -#define GPIO_RZ_TINT_IRQ_OFFSET 444 -#define R_INTC R_INTC_IM33 -#define GPIO_RZ_TINT_STATUS_REG_CLEAR(tint_num) (R_INTC_IM33->TSCR &= ~BIT(tint_num)) -static const uint8_t gpio_rz_int[GPIO_RZ_MAX_PORT_NUM] = { - 0, 2, 4, 6, 8, 10, 13, 15, 18, 21, 24, 25, 27, 29, 32, 34, 36, - 38, 41, 43, 45, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, - 74, 76, 78, 80, 83, 85, 88, 91, 93, 98, 102, 106, 110, 114, 118}; -#elif defined(CONFIG_SOC_SERIES_RZG2UL) -#define GPIO_RZ_P_REG_BASE_GET (&R_GPIO->P10) -#define GPIO_RZ_PM_REG_BASE_GET (&R_GPIO->PM10) -#define GPIO_RZ_PFC_REG_BASE_GET (&R_GPIO->PFC10) -#define GPIO_RZ_MAX_PORT_NUM 19 -#define GPIO_RZ_TINT_IRQ_OFFSET 444 -#define R_INTC R_INTC_IM33 -#define GPIO_RZ_TINT_STATUS_REG_CLEAR(tint_num) (R_INTC_IM33->TSCR &= ~BIT(tint_num)) -static const uint8_t gpio_rz_int[GPIO_RZ_MAX_PORT_NUM] = {0, 4, 9, 13, 17, 23, 28, 33, 38, 43, - 47, 52, 56, 58, 63, 66, 70, 72, 76}; -#endif - -#ifndef GPIO_RZ_TINT_SELECT_SOURCE_REG_CLEAR -#define GPIO_RZ_TINT_SELECT_SOURCE_REG_CLEAR(tint_num) -#define GPIO_RZ_TINT_SELECT_SOURCE_REG_SET(tint_num) -#endif - -#ifndef GPIO_RZ_TINT_STATUS_REG_GET -#define GPIO_RZ_TINT_STATUS_REG_GET (&R_INTC->TSCR) -#endif - -#ifndef GPIO_RZ_TINT_SPURIOUS_HANDLE -#define GPIO_RZ_TINT_SPURIOUS_HANDLE 1 -#endif - -#define GPIO_RZ_P_REG_GET(port, pin) (&GPIO_RZ_P_REG_BASE_GET[port]) -#define GPIO_RZ_PM_REG_GET(port, pin) (&GPIO_RZ_PM_REG_BASE_GET[port]) -#define GPIO_RZ_PFC_REG_GET(port, pin) (&GPIO_RZ_PFC_REG_BASE_GET[port]) - -#define GPIO_RZ_P_VALUE_GET(value, pin) ((value >> pin) & 1U) -#define GPIO_RZ_PM_VALUE_GET(value, pin) ((value >> (pin * 2)) & 3U) -#define GPIO_RZ_PFC_VALUE_GET(value, pin) ((value >> (pin * 4)) & 0xF) - -#define GPIO_RZ_PIN_DISCONNECT(port, pin) /* do nothing */ - -#define GPIO_RZ_MAX_INT_NUM 32 - -#define GPIO_RZ_TINT_IRQ_GET(tint_num) (tint_num + GPIO_RZ_TINT_IRQ_OFFSET) -#define GPIO_RZ_TINT_CLEAR_PENDING(tint_num) R_BSP_IrqClearPending(GPIO_RZ_TINT_IRQ_GET(tint_num)) - -#define GPIO_RZ_INT_EDGE_RISING 0x0 -#define GPIO_RZ_INT_EDGE_FALLING 0x1 -#define GPIO_RZ_INT_LEVEL_HIGH 0x2 -#define GPIO_RZ_INT_LEVEL_LOW 0x3 -#define GPIO_RZ_INT_BOTH_EDGE GPIO_RZ_INT_UNSUPPORTED -#define GPIO_RZ_INT_ENABLE IOPORT_CFG_TINT_ENABLE -#define GPIO_RZ_INT_DISABLE (~(IOPORT_CFG_TINT_ENABLE)) - -#define GPIO_RZ_TSSR_VAL(port, pin) (0x80 | (gpio_rz_int[port] + pin)) -#define GPIO_RZ_TSSR_OFFSET(irq) ((irq % 4) * 8) -#define GPIO_RZ_TITSR_OFFSET(irq) ((irq % 16) * 2) - -#define GPIO_RZ_FLAG_GET_CONFIG(flag) (((flag >> RZ_GPIO_IOLH_SHIFT) & 0x3) << 10U) -#define GPIO_RZ_FLAG_GET_FILTER(flag) (((flags >> RZ_GPIO_FILTER_SHIFT) & 0x1F) << 19U) -#define GPIO_RZ_FLAG_SET_PFC(value) (value << 24) -#define GPIO_RZ_FLAG_GET_SPECIFIC(flag) GPIO_RZ_FLAG_GET_FILTER(flag) - -#elif defined(CONFIG_SOC_SERIES_RZN2L) || defined(CONFIG_SOC_SERIES_RZT2L) || \ - defined(CONFIG_SOC_SERIES_RZT2M) -#include -#define GPIO_RZ_REG_REGION_GET(p) (R_BSP_IoRegionGet(p) == BSP_IO_REGION_NOT_SAFE ? 1 : 0) - -#define GPIO_RZ_P_REG_BASE_GET(port, pin) \ - (GPIO_RZ_REG_REGION_GET((port << 8U) | pin) == 1 ? &R_PORT_NSR->P[port] \ - : &R_PORT_SR->P[port]) - -#define GPIO_RZ_PM_REG_BASE_GET(port, pin) \ - (GPIO_RZ_REG_REGION_GET((port << 8U) | pin) == 1 ? &R_PORT_NSR->PM[port] \ - : &R_PORT_SR->PM[port]) - -#define GPIO_RZ_PFC_REG_BASE_GET(port, pin) \ - (GPIO_RZ_REG_REGION_GET((port << 8U) | pin) == 1 ? &R_PORT_NSR->PFC[port] \ - : &R_PORT_SR->PFC[port]) - -#define GPIO_RZ_P_REG_GET(port, pin) (GPIO_RZ_P_REG_BASE_GET(port, pin)) -#define GPIO_RZ_PM_REG_GET(port, pin) (GPIO_RZ_PM_REG_BASE_GET(port, pin)) -#define GPIO_RZ_PFC_REG_GET(port, pin) (GPIO_RZ_PFC_REG_BASE_GET(port, pin)) - -#define GPIO_RZ_P_VALUE_GET(value, pin) ((value >> pin) & 1U) -#define GPIO_RZ_PM_VALUE_GET(value, pin) ((value >> (pin * 2)) & 3U) -#define GPIO_RZ_PFC_VALUE_GET(value, pin) ((value >> (pin * 4)) & 0xF) - -#define GPIO_RZ_PIN_DISCONNECT(port, pin) \ - *GPIO_RZ_PM_REG_GET((port >> 8U), pin) &= ~(3U << (pin * 2)) - -#define GPIO_RZ_MAX_INT_NUM 16 - -#define GPIO_RZ_INT_EDGE_FALLING 0x0 -#define GPIO_RZ_INT_EDGE_RISING 0x1 -#define GPIO_RZ_INT_BOTH_EDGE 0x2 -#define GPIO_RZ_INT_LEVEL_LOW 0x3 -#define GPIO_RZ_INT_LEVEL_HIGH GPIO_RZ_INT_UNSUPPORTED -#define GPIO_RZ_INT_ENABLE (1U << 3) -#define GPIO_RZ_INT_DISABLE (~(1U << 3)) -#define GPIO_RZ_TINT_CLEAR_PENDING(int_num) - -#define GPIO_RZ_FLAG_GET_CONFIG(flag) (((flag >> RZTN_GPIO_DRCTL_SHIFT) & 0x33) << 8U) -#define GPIO_RZ_FLAG_SET_PFC(value) (value << 4) -#define GPIO_RZ_FLAG_GET_SPECIFIC(flag) IOPORT_CFG_REGION_NSAFETY - -#endif /* CONFIG_SOC_* */ - -#endif /* ZEPHYR_DRIVERS_GPIO_RENESAS_RZ_H_ */ diff --git a/dts/bindings/gpio/renesas,rz-gpio-common-v2.yaml b/dts/bindings/gpio/renesas,rz-gpio-common-v2.yaml new file mode 100644 index 000000000000..2842e2224915 --- /dev/null +++ b/dts/bindings/gpio/renesas,rz-gpio-common-v2.yaml @@ -0,0 +1,8 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +description: Renesas RZ GPIO common V2 + +compatible: "renesas,rz-gpio-common-v2" + +include: base.yaml diff --git a/dts/bindings/gpio/renesas,rz-gpio-common.yaml b/dts/bindings/gpio/renesas,rz-gpio-common.yaml new file mode 100644 index 000000000000..57f3fb9f7d0d --- /dev/null +++ b/dts/bindings/gpio/renesas,rz-gpio-common.yaml @@ -0,0 +1,8 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +description: Renesas RZ GPIO common + +compatible: "renesas,rz-gpio-common" + +include: base.yaml diff --git a/dts/bindings/gpio/renesas,rz-gpio.yaml b/dts/bindings/gpio/renesas,rz-gpio.yaml index ecf3808f4871..dabdb54504c9 100644 --- a/dts/bindings/gpio/renesas,rz-gpio.yaml +++ b/dts/bindings/gpio/renesas,rz-gpio.yaml @@ -1,20 +1,22 @@ -# Copyright (c) 2024 Renesas Electronics Corporation +# Copyright (c) 2024-2025 Renesas Electronics Corporation # SPDX-License-Identifier: Apache-2.0 description: | Renesas RZ GPIO controller. - Sample of usage: - gpio-consumer{ - out-gpio = <&gpio8 2 (GPIO_PULL_UP); - }; - &gpio8{ - irq = <2 10>, <9 1>; - status = "okay"; - }; - Example above will configure pin 2 port 8: - - Using interrupt TINT10 - - Set Pullup + The following example configures pull-up for pin 2 port 8 and maps it to GPIO interrupt TINT10 + gpio-consumer { + out-gpio = <&gpio8 2 (GPIO_PULL_UP)>; + }; + + &gpio8 { + irqs = <&tint10 2>; + status = "okay"; + }; + + Note that for RZ/T, RZ/N series ("gpio-common-v2" compatible), please replace "&tint10" with + a "renesas,rz-ext-irq" node to map the pin to an external interrupt. + For example, setting "irqs = <&irq10 2>" maps the pin to IRQ10. compatible: "renesas,rz-gpio" @@ -32,8 +34,8 @@ properties: description: GPIO port number irqs: - type: array - description: pin-irq pairs + type: phandle-array + description: Interrupts corresponding to pins "#gpio-cells": const: 2 From 45c7710fe4f54f5cd37578406f6fc3102869f386 Mon Sep 17 00:00:00 2001 From: Nhut Nguyen Date: Wed, 17 Dec 2025 14:50:33 +0700 Subject: [PATCH 2162/3659] dts: renesas: Update pinctrl and gpio nodes for RZ family Update pinctrl and gpio nodes for Renesas RZ family Signed-off-by: Nhut Nguyen --- dts/arm/renesas/rz/rzg/r9a07g043.dtsi | 374 +++++---- dts/arm/renesas/rz/rzg/r9a07g044.dtsi | 914 ++++++++++---------- dts/arm/renesas/rz/rzg/r9a08g045.dtsi | 374 +++++---- dts/arm/renesas/rz/rzn/r9a07g084.dtsi | 22 +- dts/arm/renesas/rz/rzt/r9a07g074.dtsi | 18 +- dts/arm/renesas/rz/rzt/r9a07g075.dtsi | 22 +- dts/arm/renesas/rz/rzv/r9a07g054.dtsi | 916 ++++++++++----------- dts/arm/renesas/rz/rzv/r9a09g056.dtsi | 248 +++--- dts/arm/renesas/rz/rzv/r9a09g057_cm33.dtsi | 248 +++--- dts/arm/renesas/rz/rzv/r9a09g057_cr8.dtsi | 274 +++--- dts/arm64/renesas/rz/rza/r9a07g063.dtsi | 406 +++++---- 11 files changed, 1886 insertions(+), 1930 deletions(-) diff --git a/dts/arm/renesas/rz/rzg/r9a07g043.dtsi b/dts/arm/renesas/rz/rzg/r9a07g043.dtsi index ab34fb3bb9c0..f40b425f9338 100644 --- a/dts/arm/renesas/rz/rzg/r9a07g043.dtsi +++ b/dts/arm/renesas/rz/rzg/r9a07g043.dtsi @@ -6,6 +6,7 @@ #include #include #include +#include / { compatible = "renesas,r9a07g043"; @@ -31,196 +32,191 @@ }; }; + /* Dummy pinctrl node, filled with pin mux options at board level */ + pinctrl: pinctrl { + compatible = "renesas,rzg-pinctrl"; + }; + soc { - pinctrl: pin-controller@41030000 { - compatible = "renesas,rzg-pinctrl"; - reg = <0x41030000 DT_SIZE_K(64)>; - reg-names = "pinctrl"; - - gpio: gpio-common { - compatible = "renesas,rz-gpio-int"; - interrupts = <444 10>, <445 10>, <446 10>, <447 10>, - <448 10>, <449 10>, <450 10>, <451 10>, - <452 10>, <453 10>, <454 10>, <455 10>, - <456 10>, <457 10>, <458 10>, <459 10>, - <460 10>, <461 10>, <462 10>, <463 10>, - <464 10>, <465 10>, <466 10>, <467 10>, - <468 10>, <469 10>, <470 10>, <471 10>, - <472 10>, <473 10>, <474 10>, <475 10>; - #address-cells = <1>; - #size-cells = <0>; - status = "disabled"; - - gpio0: gpio@0 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <4>; - reg = <0x0>; - status = "disabled"; - }; - - gpio1: gpio@100 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <5>; - reg = <0x100>; - status = "disabled"; - }; - - gpio2: gpio@200 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <4>; - reg = <0x200>; - status = "disabled"; - }; - - gpio3: gpio@300 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <4>; - reg = <0x300>; - status = "disabled"; - }; - - gpio4: gpio@400 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <6>; - reg = <0x400>; - status = "disabled"; - }; - - gpio5: gpio@500 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <5>; - reg = <0x500>; - status = "disabled"; - }; - - gpio6: gpio@600 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <5>; - reg = <0x600>; - status = "disabled"; - }; - - gpio7: gpio@700 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <5>; - reg = <0x700>; - status = "disabled"; - }; - - gpio8: gpio@800 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <5>; - reg = <0x800>; - status = "disabled"; - }; - - gpio9: gpio@900 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <4>; - reg = <0x900>; - status = "disabled"; - }; - - gpio10: gpio@a00 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <5>; - reg = <0xa00>; - status = "disabled"; - }; - - gpio11: gpio@b00 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <4>; - reg = <0xb00>; - status = "disabled"; - }; - - gpio12: gpio@c00 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0xc00>; - status = "disabled"; - }; - - gpio13: gpio@d00 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <5>; - reg = <0xd00>; - status = "disabled"; - }; - - gpio14: gpio@e00 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <3>; - reg = <0xe00>; - status = "disabled"; - }; - - gpio15: gpio@f00 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <4>; - reg = <0xf00>; - status = "disabled"; - }; - - gpio16: gpio@1000 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0x1000>; - status = "disabled"; - }; - - gpio17: gpio@1100 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <4>; - reg = <0x1100>; - status = "disabled"; - }; - - gpio18: gpio@1200 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <6>; - reg = <0x1200>; - status = "disabled"; - }; + gpio: gpio@41030000 { + compatible = "renesas,rz-gpio-common"; + reg = <0x41030000 DT_SIZE_K(64)>, + <0x10 0x13>, + <0x120 0x26>, + <0x440 0x4c>; + reg-names = "base", "p", "pm", "pfc"; + #address-cells = <1>; + #size-cells = <0>; + + gpio0: gpio@0 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <4>; + reg = <0x0>; + status = "disabled"; + }; + + gpio1: gpio@100 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <5>; + reg = <0x100>; + status = "disabled"; + }; + + gpio2: gpio@200 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <4>; + reg = <0x200>; + status = "disabled"; + }; + + gpio3: gpio@300 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <4>; + reg = <0x300>; + status = "disabled"; + }; + + gpio4: gpio@400 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <6>; + reg = <0x400>; + status = "disabled"; + }; + + gpio5: gpio@500 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <5>; + reg = <0x500>; + status = "disabled"; + }; + + gpio6: gpio@600 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <5>; + reg = <0x600>; + status = "disabled"; + }; + + gpio7: gpio@700 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <5>; + reg = <0x700>; + status = "disabled"; + }; + + gpio8: gpio@800 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <5>; + reg = <0x800>; + status = "disabled"; + }; + + gpio9: gpio@900 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <4>; + reg = <0x900>; + status = "disabled"; + }; + + gpio10: gpio@a00 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <5>; + reg = <0xa00>; + status = "disabled"; + }; + + gpio11: gpio@b00 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <4>; + reg = <0xb00>; + status = "disabled"; + }; + + gpio12: gpio@c00 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0xc00>; + status = "disabled"; + }; + + gpio13: gpio@d00 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <5>; + reg = <0xd00>; + status = "disabled"; + }; + + gpio14: gpio@e00 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <3>; + reg = <0xe00>; + status = "disabled"; + }; + + gpio15: gpio@f00 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <4>; + reg = <0xf00>; + status = "disabled"; + }; + + gpio16: gpio@1000 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0x1000>; + status = "disabled"; + }; + + gpio17: gpio@1100 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <4>; + reg = <0x1100>; + status = "disabled"; + }; + + gpio18: gpio@1200 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <6>; + reg = <0x1200>; + status = "disabled"; }; }; diff --git a/dts/arm/renesas/rz/rzg/r9a07g044.dtsi b/dts/arm/renesas/rz/rzg/r9a07g044.dtsi index c45c80e42611..f4c0d9e1cee7 100644 --- a/dts/arm/renesas/rz/rzg/r9a07g044.dtsi +++ b/dts/arm/renesas/rz/rzg/r9a07g044.dtsi @@ -6,6 +6,7 @@ #include #include #include +#include / { compatible = "renesas,r9a07g044"; @@ -31,466 +32,461 @@ }; }; + /* Dummy pinctrl node, filled with pin mux options at board level */ + pinctrl: pinctrl { + compatible = "renesas,rzg-pinctrl"; + }; + soc { - pinctrl: pin-controller@41030000 { - compatible = "renesas,rzg-pinctrl"; - reg = <0x41030000 DT_SIZE_K(64)>; - reg-names = "pinctrl"; - - gpio: gpio-common { - compatible = "renesas,rz-gpio-int"; - interrupts = <444 10>, <445 10>, <446 10>, <447 10>, - <448 10>, <449 10>, <450 10>, <451 10>, - <452 10>, <453 10>, <454 10>, <455 10>, - <456 10>, <457 10>, <458 10>, <459 10>, - <460 10>, <461 10>, <462 10>, <463 10>, - <464 10>, <465 10>, <466 10>, <467 10>, - <468 10>, <469 10>, <470 10>, <471 10>, - <472 10>, <473 10>, <474 10>, <475 10>; - #address-cells = <1>; - #size-cells = <0>; - status = "disabled"; - - gpio0: gpio@0 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0x0>; - status = "disabled"; - }; - - gpio1: gpio@100 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0x100>; - status = "disabled"; - }; - - gpio2: gpio@200 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0x200>; - status = "disabled"; - }; - - gpio3: gpio@300 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0x300>; - status = "disabled"; - }; - - gpio4: gpio@400 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0x400>; - status = "disabled"; - }; - - gpio5: gpio@500 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <3>; - reg = <0x500>; - status = "disabled"; - }; - - gpio6: gpio@600 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0x600>; - status = "disabled"; - }; - - gpio7: gpio@700 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <3>; - reg = <0x700>; - status = "disabled"; - }; - - gpio8: gpio@800 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0x800>; - status = "disabled"; - }; - - gpio9: gpio@900 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0x900>; - status = "disabled"; - }; - - gpio10: gpio@a00 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0xa00>; - status = "disabled"; - }; - - gpio11: gpio@b00 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0xb00>; - status = "disabled"; - }; - - gpio12: gpio@c00 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0xc00>; - status = "disabled"; - }; - - gpio13: gpio@d00 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <3>; - reg = <0xd00>; - status = "disabled"; - }; - - gpio14: gpio@e00 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0xe00>; - status = "disabled"; - }; - - gpio15: gpio@f00 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0xf00>; - status = "disabled"; - }; - - gpio16: gpio@1000 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0x1000>; - status = "disabled"; - }; - - gpio17: gpio@1100 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <3>; - reg = <0x1100>; - status = "disabled"; - }; - - gpio18: gpio@1200 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0x1200>; - status = "disabled"; - }; - - gpio19: gpio@1300 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0x1300>; - status = "disabled"; - }; - - gpio20: gpio@1400 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <3>; - reg = <0x1400>; - status = "disabled"; - }; - - gpio21: gpio@1500 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0x1500>; - status = "disabled"; - }; - - gpio22: gpio@1600 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0x1600>; - status = "disabled"; - }; - - gpio23: gpio@1700 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0x1700>; - status = "disabled"; - }; - - gpio24: gpio@1800 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0x1800>; - status = "disabled"; - }; - - gpio25: gpio@1900 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0x1900>; - status = "disabled"; - }; - - gpio26: gpio@1a00 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0x1a00>; - status = "disabled"; - }; - - gpio27: gpio@1b00 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0x1b00>; - status = "disabled"; - }; - - gpio28: gpio@1c00 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0x1c00>; - status = "disabled"; - }; - - gpio29: gpio@1d00 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0x1d00>; - status = "disabled"; - }; - - gpio30: gpio@1e00 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0x1e00>; - status = "disabled"; - }; - - gpio31: gpio@1f00 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0x1f00>; - status = "disabled"; - }; - - gpio32: gpio@2000 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0x2000>; - status = "disabled"; - }; - - gpio33: gpio@2100 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0x2100>; - status = "disabled"; - }; - - gpio34: gpio@2200 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0x2200>; - status = "disabled"; - }; - - gpio35: gpio@2300 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0x2300>; - status = "disabled"; - }; - - gpio36: gpio@2400 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0x2400>; - status = "disabled"; - }; - - gpio37: gpio@2500 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <3>; - reg = <0x2500>; - status = "disabled"; - }; - - gpio38: gpio@2600 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <3>; - reg = <0x2600>; - status = "disabled"; - }; - - gpio39: gpio@2700 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0x2700>; - status = "disabled"; - }; - - gpio40: gpio@2800 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0x2800>; - status = "disabled"; - }; - - gpio41: gpio@2900 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0x2900>; - status = "disabled"; - }; - - gpio42: gpio@2a00 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0x2a00>; - status = "disabled"; - }; - - gpio43: gpio@2b00 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <5>; - reg = <0x2b00>; - status = "disabled"; - }; - - gpio44: gpio@2c00 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <3>; - reg = <0x2c00>; - status = "disabled"; - }; - - gpio45: gpio@2d00 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <4>; - reg = <0x2d00>; - status = "disabled"; - }; - - gpio46: gpio@2e00 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <4>; - reg = <0x2e00>; - status = "disabled"; - }; - - gpio47: gpio@2f00 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <4>; - reg = <0x2f00>; - status = "disabled"; - }; - - gpio48: gpio@3000 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <4>; - reg = <0x3000>; - status = "disabled"; - }; + gpio: gpio@41030000 { + compatible = "renesas,rz-gpio-common"; + reg = <0x41030000 DT_SIZE_K(64)>, + <0x10 0x31>, + <0x120 0x62>, + <0x440 0xc4>; + reg-names = "base", "p", "pm", "pfc"; + #address-cells = <1>; + #size-cells = <0>; + + gpio0: gpio@0 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0x0>; + status = "disabled"; + }; + + gpio1: gpio@100 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0x100>; + status = "disabled"; + }; + + gpio2: gpio@200 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0x200>; + status = "disabled"; + }; + + gpio3: gpio@300 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0x300>; + status = "disabled"; + }; + + gpio4: gpio@400 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0x400>; + status = "disabled"; + }; + + gpio5: gpio@500 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <3>; + reg = <0x500>; + status = "disabled"; + }; + + gpio6: gpio@600 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0x600>; + status = "disabled"; + }; + + gpio7: gpio@700 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <3>; + reg = <0x700>; + status = "disabled"; + }; + + gpio8: gpio@800 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0x800>; + status = "disabled"; + }; + + gpio9: gpio@900 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0x900>; + status = "disabled"; + }; + + gpio10: gpio@a00 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0xa00>; + status = "disabled"; + }; + + gpio11: gpio@b00 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0xb00>; + status = "disabled"; + }; + + gpio12: gpio@c00 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0xc00>; + status = "disabled"; + }; + + gpio13: gpio@d00 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <3>; + reg = <0xd00>; + status = "disabled"; + }; + + gpio14: gpio@e00 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0xe00>; + status = "disabled"; + }; + + gpio15: gpio@f00 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0xf00>; + status = "disabled"; + }; + + gpio16: gpio@1000 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0x1000>; + status = "disabled"; + }; + + gpio17: gpio@1100 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <3>; + reg = <0x1100>; + status = "disabled"; + }; + + gpio18: gpio@1200 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0x1200>; + status = "disabled"; + }; + + gpio19: gpio@1300 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0x1300>; + status = "disabled"; + }; + + gpio20: gpio@1400 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <3>; + reg = <0x1400>; + status = "disabled"; + }; + + gpio21: gpio@1500 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0x1500>; + status = "disabled"; + }; + + gpio22: gpio@1600 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0x1600>; + status = "disabled"; + }; + + gpio23: gpio@1700 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0x1700>; + status = "disabled"; + }; + + gpio24: gpio@1800 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0x1800>; + status = "disabled"; + }; + + gpio25: gpio@1900 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0x1900>; + status = "disabled"; + }; + + gpio26: gpio@1a00 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0x1a00>; + status = "disabled"; + }; + + gpio27: gpio@1b00 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0x1b00>; + status = "disabled"; + }; + + gpio28: gpio@1c00 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0x1c00>; + status = "disabled"; + }; + + gpio29: gpio@1d00 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0x1d00>; + status = "disabled"; + }; + + gpio30: gpio@1e00 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0x1e00>; + status = "disabled"; + }; + + gpio31: gpio@1f00 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0x1f00>; + status = "disabled"; + }; + + gpio32: gpio@2000 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0x2000>; + status = "disabled"; + }; + + gpio33: gpio@2100 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0x2100>; + status = "disabled"; + }; + + gpio34: gpio@2200 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0x2200>; + status = "disabled"; + }; + + gpio35: gpio@2300 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0x2300>; + status = "disabled"; + }; + + gpio36: gpio@2400 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0x2400>; + status = "disabled"; + }; + + gpio37: gpio@2500 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <3>; + reg = <0x2500>; + status = "disabled"; + }; + + gpio38: gpio@2600 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <3>; + reg = <0x2600>; + status = "disabled"; + }; + + gpio39: gpio@2700 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0x2700>; + status = "disabled"; + }; + + gpio40: gpio@2800 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0x2800>; + status = "disabled"; + }; + + gpio41: gpio@2900 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0x2900>; + status = "disabled"; + }; + + gpio42: gpio@2a00 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0x2a00>; + status = "disabled"; + }; + + gpio43: gpio@2b00 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <5>; + reg = <0x2b00>; + status = "disabled"; + }; + + gpio44: gpio@2c00 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <3>; + reg = <0x2c00>; + status = "disabled"; + }; + + gpio45: gpio@2d00 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <4>; + reg = <0x2d00>; + status = "disabled"; + }; + + gpio46: gpio@2e00 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <4>; + reg = <0x2e00>; + status = "disabled"; + }; + + gpio47: gpio@2f00 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <4>; + reg = <0x2f00>; + status = "disabled"; + }; + + gpio48: gpio@3000 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <4>; + reg = <0x3000>; + status = "disabled"; }; }; diff --git a/dts/arm/renesas/rz/rzg/r9a08g045.dtsi b/dts/arm/renesas/rz/rzg/r9a08g045.dtsi index 14e041e58b95..050644aaa40a 100644 --- a/dts/arm/renesas/rz/rzg/r9a08g045.dtsi +++ b/dts/arm/renesas/rz/rzg/r9a08g045.dtsi @@ -11,6 +11,7 @@ #include #include #include +#include / { compatible = "renesas,r9a08g045"; @@ -49,6 +50,11 @@ #clock-cells = <0>; }; + /* Dummy pinctrl node, filled with pin mux options at board level */ + pinctrl: pinctrl { + compatible = "renesas,rzg-pinctrl"; + }; + soc { cpg: clock-controller@41010000 { compatible = "renesas,rz-cpg"; @@ -213,195 +219,185 @@ status = "disabled"; }; - pinctrl: pin-controller@41030000 { - compatible = "renesas,rzg-pinctrl"; - reg = <0x41030000 DT_SIZE_K(64)>; - reg-names = "pinctrl"; - - gpio: gpio-common { - compatible = "renesas,rz-gpio-int"; - interrupts = <429 10>, <430 10>, <431 10>, <432 10>, - <433 10>, <434 10>, <435 10>, <436 10>, - <437 10>, <438 10>, <439 10>, <440 10>, - <441 10>, <442 10>, <443 10>, <444 10>, - <445 10>, <446 10>, <447 10>, <448 10>, - <449 10>, <450 10>, <451 10>, <452 10>, - <453 10>, <454 10>, <455 10>, <456 10>, - <457 10>, <458 10>, <459 10>, <460 10>; - #address-cells = <1>; - #size-cells = <0>; - status = "disabled"; - - gpio0: gpio@0 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <4>; - reg = <0x0>; - status = "disabled"; - }; - - gpio1: gpio@1000 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <5>; - reg = <0x1000>; - status = "disabled"; - }; - - gpio2: gpio@1100 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <4>; - reg = <0x1100>; - status = "disabled"; - }; - - gpio3: gpio@1200 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <4>; - reg = <0x1200>; - status = "disabled"; - }; - - gpio4: gpio@1300 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <6>; - reg = <0x1300>; - status = "disabled"; - }; - - gpio5: gpio@100 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <5>; - reg = <0x100>; - status = "disabled"; - }; - - gpio6: gpio@200 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <5>; - reg = <0x200>; - status = "disabled"; - }; - - gpio7: gpio@1400 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <5>; - reg = <0x1400>; - status = "disabled"; - }; - - gpio8: gpio@1500 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <5>; - reg = <0x1500>; - status = "disabled"; - }; - - gpio9: gpio@1600 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <4>; - reg = <0x1600>; - status = "disabled"; - }; - - gpio10: gpio@1700 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <5>; - reg = <0x1700>; - status = "disabled"; - }; - - gpio11: gpio@300 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <4>; - reg = <0x300>; - status = "disabled"; - }; - - gpio12: gpio@400 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0x400>; - status = "disabled"; - }; - - gpio13: gpio@500 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <5>; - reg = <0x500>; - status = "disabled"; - }; - - gpio14: gpio@600 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <3>; - reg = <0x600>; - status = "disabled"; - }; - - gpio15: gpio@700 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <4>; - reg = <0x700>; - status = "disabled"; - }; - - gpio16: gpio@800 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0x800>; - status = "disabled"; - }; - - gpio17: gpio@900 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <4>; - reg = <0x900>; - status = "disabled"; - }; - - gpio18: gpio@A00 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <6>; - reg = <0xA00>; - status = "disabled"; - }; + gpio: gpio@41030000 { + compatible = "renesas,rz-gpio-common"; + reg = <0x41030000 DT_SIZE_K(64)>, + <0x20 0x18>, + <0x140 0x30>, + <0x480 0x60>; + reg-names = "base", "p", "pm", "pfc"; + #address-cells = <1>; + #size-cells = <0>; + + gpio0: gpio@0 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <4>; + reg = <0x0>; + status = "disabled"; + }; + + gpio1: gpio@1000 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <5>; + reg = <0x1000>; + status = "disabled"; + }; + + gpio2: gpio@1100 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <4>; + reg = <0x1100>; + status = "disabled"; + }; + + gpio3: gpio@1200 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <4>; + reg = <0x1200>; + status = "disabled"; + }; + + gpio4: gpio@1300 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <6>; + reg = <0x1300>; + status = "disabled"; + }; + + gpio5: gpio@100 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <5>; + reg = <0x100>; + status = "disabled"; + }; + + gpio6: gpio@200 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <5>; + reg = <0x200>; + status = "disabled"; + }; + + gpio7: gpio@1400 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <5>; + reg = <0x1400>; + status = "disabled"; + }; + + gpio8: gpio@1500 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <5>; + reg = <0x1500>; + status = "disabled"; + }; + + gpio9: gpio@1600 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <4>; + reg = <0x1600>; + status = "disabled"; + }; + + gpio10: gpio@1700 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <5>; + reg = <0x1700>; + status = "disabled"; + }; + + gpio11: gpio@300 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <4>; + reg = <0x300>; + status = "disabled"; + }; + + gpio12: gpio@400 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0x400>; + status = "disabled"; + }; + + gpio13: gpio@500 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <5>; + reg = <0x500>; + status = "disabled"; + }; + + gpio14: gpio@600 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <3>; + reg = <0x600>; + status = "disabled"; + }; + + gpio15: gpio@700 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <4>; + reg = <0x700>; + status = "disabled"; + }; + + gpio16: gpio@800 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0x800>; + status = "disabled"; + }; + + gpio17: gpio@900 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <4>; + reg = <0x900>; + status = "disabled"; + }; + + gpio18: gpio@A00 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <6>; + reg = <0xA00>; + status = "disabled"; }; }; diff --git a/dts/arm/renesas/rz/rzn/r9a07g084.dtsi b/dts/arm/renesas/rz/rzn/r9a07g084.dtsi index bcd3ef4691dc..e7a48f2e9743 100644 --- a/dts/arm/renesas/rz/rzn/r9a07g084.dtsi +++ b/dts/arm/renesas/rz/rzn/r9a07g084.dtsi @@ -7,10 +7,11 @@ #include #include #include -#include #include -#include #include +#include +#include +#include / { #address-cells = <1>; @@ -43,6 +44,11 @@ #clock-cells = <0>; }; + /* Dummy pinctrl node, filled with pin mux options at board level */ + pinctrl: pinctrl { + compatible = "renesas,rzt-pinctrl"; + }; + soc { interrupt-parent = <&gic>; @@ -364,9 +370,15 @@ }; }; - pinctrl: pinctrl@800a0000 { - compatible = "renesas,rzn-pinctrl"; - reg = <0x800a0000 0x1000 0x81030c00 0x1000>; + gpio: gpio@800a0000 { + compatible = "renesas,rz-gpio-common-v2"; + reg = <0x800a0000 0x1000>, + <0x81030000 0x1000>, + <0x81030c00 0x64>, + <0x0 0x19>, + <0x200 0x32>, + <0x600 0x64>; + reg-names = "base_ns", "base_s", "rselp", "p", "pm", "pfc"; #address-cells = <1>; #size-cells = <0>; diff --git a/dts/arm/renesas/rz/rzt/r9a07g074.dtsi b/dts/arm/renesas/rz/rzt/r9a07g074.dtsi index fadce051ca7b..abe232f261a8 100644 --- a/dts/arm/renesas/rz/rzt/r9a07g074.dtsi +++ b/dts/arm/renesas/rz/rzt/r9a07g074.dtsi @@ -7,6 +7,7 @@ #include #include #include +#include / { compatible = "renesas,r9a07g074"; @@ -33,6 +34,11 @@ interrupt-parent = <&gic>; }; + /* Dummy pinctrl node, filled with pin mux options at board level */ + pinctrl: pinctrl { + compatible = "renesas,rzt-pinctrl"; + }; + soc { interrupt-parent = <&gic>; @@ -225,9 +231,15 @@ }; }; - pinctrl: pinctrl@800a0000 { - compatible = "renesas,rzt-pinctrl"; - reg = <0x800a0000 0x1000 0x81030c00 0x1000>; + gpio: gpio@800a0000 { + compatible = "renesas,rz-gpio-common-v2"; + reg = <0x800a0000 0x1000>, + <0x81030000 0x1000>, + <0x81030c00 0x64>, + <0x0 0x19>, + <0x200 0x32>, + <0x600 0x64>; + reg-names = "base_ns", "base_s", "rselp", "p", "pm", "pfc"; #address-cells = <1>; #size-cells = <0>; diff --git a/dts/arm/renesas/rz/rzt/r9a07g075.dtsi b/dts/arm/renesas/rz/rzt/r9a07g075.dtsi index 554efde30a1e..c9962c5a51eb 100644 --- a/dts/arm/renesas/rz/rzt/r9a07g075.dtsi +++ b/dts/arm/renesas/rz/rzt/r9a07g075.dtsi @@ -9,10 +9,11 @@ #include #include #include -#include #include -#include #include +#include +#include +#include / { compatible = "renesas,r9a07g075"; @@ -51,6 +52,11 @@ #clock-cells = <0>; }; + /* Dummy pinctrl node, filled with pin mux options at board level */ + pinctrl: pinctrl { + compatible = "renesas,rzt-pinctrl"; + }; + soc { interrupt-parent = <&gic>; @@ -377,9 +383,15 @@ }; }; - pinctrl: pinctrl@800a0000 { - compatible = "renesas,rzt-pinctrl"; - reg = <0x800a0000 0x1000 0x81030c00 0x1000>; + gpio: gpio@800a0000 { + compatible = "renesas,rz-gpio-common-v2"; + reg = <0x800a0000 0x1000>, + <0x81030000 0x1000>, + <0x81030c00 0x64>, + <0x0 0x19>, + <0x200 0x32>, + <0x600 0x64>; + reg-names = "base_ns", "base_s", "rselp", "p", "pm", "pfc"; #address-cells = <1>; #size-cells = <0>; diff --git a/dts/arm/renesas/rz/rzv/r9a07g054.dtsi b/dts/arm/renesas/rz/rzv/r9a07g054.dtsi index ded6556c61ac..b0a357baca56 100644 --- a/dts/arm/renesas/rz/rzv/r9a07g054.dtsi +++ b/dts/arm/renesas/rz/rzv/r9a07g054.dtsi @@ -7,9 +7,10 @@ #include #include #include -#include #include +#include #include +#include / { compatible = "renesas,r9a07g054"; @@ -41,6 +42,11 @@ #clock-cells = <0>; }; + /* Dummy pinctrl node, filled with pin mux options at board level */ + pinctrl: pinctrl { + compatible = "renesas,rzv-pinctrl"; + }; + soc { adc: adc@40059000 { compatible = "renesas,rz-adc-c"; @@ -180,465 +186,455 @@ }; }; - pinctrl: pin-controller@41030000 { - compatible = "renesas,rzv-pinctrl"; - reg = <0x41030000 DT_SIZE_K(64)>; - reg-names = "pinctrl"; - - gpio: gpio-common { - compatible = "renesas,rz-gpio-int"; - interrupts = <444 10>, <445 10>, <446 10>, <447 10>, - <448 10>, <449 10>, <450 10>, <451 10>, - <452 10>, <453 10>, <454 10>, <455 10>, - <456 10>, <457 10>, <458 10>, <459 10>, - <460 10>, <461 10>, <462 10>, <463 10>, - <464 10>, <465 10>, <466 10>, <467 10>, - <468 10>, <469 10>, <470 10>, <471 10>, - <472 10>, <473 10>, <474 10>, <475 10>; - #address-cells = <1>; - #size-cells = <0>; - status = "disabled"; - - gpio0: gpio@0 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0x0>; - status = "disabled"; - }; - - gpio1: gpio@100 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0x100>; - status = "disabled"; - }; - - gpio2: gpio@200 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0x200>; - status = "disabled"; - }; - - gpio3: gpio@300 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0x300>; - status = "disabled"; - }; - - gpio4: gpio@400 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0x400>; - status = "disabled"; - }; - - gpio5: gpio@500 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <3>; - reg = <0x500>; - status = "disabled"; - }; - - gpio6: gpio@600 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0x600>; - status = "disabled"; - }; - - gpio7: gpio@700 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <3>; - reg = <0x700>; - status = "disabled"; - }; - - gpio8: gpio@800 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <3>; - reg = <0x800>; - status = "disabled"; - }; - - gpio9: gpio@900 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0x900>; - status = "disabled"; - }; - - gpio10: gpio@a00 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0xa00>; - status = "disabled"; - }; - - gpio11: gpio@b00 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0xb00>; - status = "disabled"; - }; - - gpio12: gpio@c00 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0xc00>; - status = "disabled"; - }; - - gpio13: gpio@d00 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <3>; - reg = <0xd00>; - status = "disabled"; - }; - - gpio14: gpio@e00 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0xe00>; - status = "disabled"; - }; - - gpio15: gpio@f00 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0xf00>; - status = "disabled"; - }; - - gpio16: gpio@1000 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0x1000>; - status = "disabled"; - }; - - gpio17: gpio@1100 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <3>; - reg = <0x1100>; - status = "disabled"; - }; - - gpio18: gpio@1200 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0x1200>; - status = "disabled"; - }; - - gpio19: gpio@1300 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0x1300>; - status = "disabled"; - }; - - gpio20: gpio@1400 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <3>; - reg = <0x1400>; - status = "disabled"; - }; - - gpio21: gpio@1500 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0x1500>; - status = "disabled"; - }; - - gpio22: gpio@1600 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0x1600>; - status = "disabled"; - }; - - gpio23: gpio@1700 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0x1700>; - status = "disabled"; - }; - - gpio24: gpio@1800 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0x1800>; - status = "disabled"; - }; - - gpio25: gpio@1900 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0x1900>; - status = "disabled"; - }; - - gpio26: gpio@1a00 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0x1a00>; - status = "disabled"; - }; - - gpio27: gpio@1b00 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0x1b00>; - status = "disabled"; - }; - - gpio28: gpio@1c00 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0x1c00>; - status = "disabled"; - }; - - gpio29: gpio@1d00 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0x1d00>; - status = "disabled"; - }; - - gpio30: gpio@1e00 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0x1e00>; - status = "disabled"; - }; - - gpio31: gpio@1f00 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0x1f00>; - status = "disabled"; - }; - - gpio32: gpio@2000 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0x2000>; - status = "disabled"; - }; - - gpio33: gpio@2100 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0x2100>; - status = "disabled"; - }; - - gpio34: gpio@2200 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0x2200>; - status = "disabled"; - }; - - gpio35: gpio@2300 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0x2300>; - status = "disabled"; - }; - - gpio36: gpio@2400 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0x2400>; - status = "disabled"; - }; - - gpio37: gpio@2500 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <3>; - reg = <0x2500>; - status = "disabled"; - }; - - gpio38: gpio@2600 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0x2600>; - status = "disabled"; - }; - - gpio39: gpio@2700 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <3>; - reg = <0x2700>; - status = "disabled"; - }; - - gpio40: gpio@2800 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <3>; - reg = <0x2800>; - status = "disabled"; - }; - - gpio41: gpio@2900 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0x2900>; - status = "disabled"; - }; - - gpio42: gpio@2a00 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <5>; - reg = <0x2a00>; - status = "disabled"; - }; - - gpio43: gpio@2b00 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <4>; - reg = <0x2b00>; - status = "disabled"; - }; - - gpio44: gpio@2c00 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <4>; - reg = <0x2c00>; - status = "disabled"; - }; - - gpio45: gpio@2d00 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <4>; - reg = <0x2d00>; - status = "disabled"; - }; - - gpio46: gpio@2e00 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <4>; - reg = <0x2e00>; - status = "disabled"; - }; - - gpio47: gpio@2f00 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <4>; - reg = <0x2f00>; - status = "disabled"; - }; - - gpio48: gpio@3000 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <5>; - reg = <0x3000>; - status = "disabled"; - }; + gpio: gpio@41030000 { + compatible = "renesas,rz-gpio-common"; + reg = <0x41030000 DT_SIZE_K(64)>, + <0x10 0x31>, + <0x120 0x62>, + <0x440 0xc4>; + reg-names = "base", "p", "pm", "pfc"; + #address-cells = <1>; + #size-cells = <0>; + + gpio0: gpio@0 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0x0>; + status = "disabled"; + }; + + gpio1: gpio@100 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0x100>; + status = "disabled"; + }; + + gpio2: gpio@200 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0x200>; + status = "disabled"; + }; + + gpio3: gpio@300 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0x300>; + status = "disabled"; + }; + + gpio4: gpio@400 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0x400>; + status = "disabled"; + }; + + gpio5: gpio@500 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <3>; + reg = <0x500>; + status = "disabled"; + }; + + gpio6: gpio@600 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0x600>; + status = "disabled"; + }; + + gpio7: gpio@700 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <3>; + reg = <0x700>; + status = "disabled"; + }; + + gpio8: gpio@800 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <3>; + reg = <0x800>; + status = "disabled"; + }; + + gpio9: gpio@900 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0x900>; + status = "disabled"; + }; + + gpio10: gpio@a00 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0xa00>; + status = "disabled"; + }; + + gpio11: gpio@b00 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0xb00>; + status = "disabled"; + }; + + gpio12: gpio@c00 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0xc00>; + status = "disabled"; + }; + + gpio13: gpio@d00 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <3>; + reg = <0xd00>; + status = "disabled"; + }; + + gpio14: gpio@e00 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0xe00>; + status = "disabled"; + }; + + gpio15: gpio@f00 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0xf00>; + status = "disabled"; + }; + + gpio16: gpio@1000 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0x1000>; + status = "disabled"; + }; + + gpio17: gpio@1100 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <3>; + reg = <0x1100>; + status = "disabled"; + }; + + gpio18: gpio@1200 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0x1200>; + status = "disabled"; + }; + + gpio19: gpio@1300 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0x1300>; + status = "disabled"; + }; + + gpio20: gpio@1400 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <3>; + reg = <0x1400>; + status = "disabled"; + }; + + gpio21: gpio@1500 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0x1500>; + status = "disabled"; + }; + + gpio22: gpio@1600 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0x1600>; + status = "disabled"; + }; + + gpio23: gpio@1700 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0x1700>; + status = "disabled"; + }; + + gpio24: gpio@1800 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0x1800>; + status = "disabled"; + }; + + gpio25: gpio@1900 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0x1900>; + status = "disabled"; + }; + + gpio26: gpio@1a00 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0x1a00>; + status = "disabled"; + }; + + gpio27: gpio@1b00 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0x1b00>; + status = "disabled"; + }; + + gpio28: gpio@1c00 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0x1c00>; + status = "disabled"; + }; + + gpio29: gpio@1d00 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0x1d00>; + status = "disabled"; + }; + + gpio30: gpio@1e00 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0x1e00>; + status = "disabled"; + }; + + gpio31: gpio@1f00 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0x1f00>; + status = "disabled"; + }; + + gpio32: gpio@2000 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0x2000>; + status = "disabled"; + }; + + gpio33: gpio@2100 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0x2100>; + status = "disabled"; + }; + + gpio34: gpio@2200 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0x2200>; + status = "disabled"; + }; + + gpio35: gpio@2300 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0x2300>; + status = "disabled"; + }; + + gpio36: gpio@2400 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0x2400>; + status = "disabled"; + }; + + gpio37: gpio@2500 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <3>; + reg = <0x2500>; + status = "disabled"; + }; + + gpio38: gpio@2600 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0x2600>; + status = "disabled"; + }; + + gpio39: gpio@2700 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <3>; + reg = <0x2700>; + status = "disabled"; + }; + + gpio40: gpio@2800 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <3>; + reg = <0x2800>; + status = "disabled"; + }; + + gpio41: gpio@2900 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0x2900>; + status = "disabled"; + }; + + gpio42: gpio@2a00 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <5>; + reg = <0x2a00>; + status = "disabled"; + }; + + gpio43: gpio@2b00 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <4>; + reg = <0x2b00>; + status = "disabled"; + }; + + gpio44: gpio@2c00 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <4>; + reg = <0x2c00>; + status = "disabled"; + }; + + gpio45: gpio@2d00 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <4>; + reg = <0x2d00>; + status = "disabled"; + }; + + gpio46: gpio@2e00 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <4>; + reg = <0x2e00>; + status = "disabled"; + }; + + gpio47: gpio@2f00 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <4>; + reg = <0x2f00>; + status = "disabled"; + }; + + gpio48: gpio@3000 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <5>; + reg = <0x3000>; + status = "disabled"; }; }; diff --git a/dts/arm/renesas/rz/rzv/r9a09g056.dtsi b/dts/arm/renesas/rz/rzv/r9a09g056.dtsi index fc3c8d068804..4dbe6691befc 100644 --- a/dts/arm/renesas/rz/rzv/r9a09g056.dtsi +++ b/dts/arm/renesas/rz/rzv/r9a09g056.dtsi @@ -6,6 +6,7 @@ #include #include #include +#include / { compatible = "renesas,r9a09g056"; @@ -31,133 +32,128 @@ }; }; + /* Dummy pinctrl node, filled with pin mux options at board level */ + pinctrl: pinctrl { + compatible = "renesas,rzv-pinctrl"; + }; + soc { - pinctrl: pin-controller@40410000 { - compatible = "renesas,rzv-pinctrl"; - reg = <0x40410000 DT_SIZE_K(64)>; - reg-names = "pinctrl"; - - gpio: gpio-common { - compatible = "renesas,rz-gpio-int"; - interrupts = <353 10>, <354 10>, <355 10>, <356 10>, - <357 10>, <358 10>, <359 10>, <360 10>, - <361 10>, <362 10>, <363 10>, <364 10>, - <365 10>, <366 10>, <367 10>, <368 10>, - <369 10>, <370 10>, <371 10>, <372 10>, - <373 10>, <374 10>, <375 10>, <376 10>, - <377 10>, <378 10>, <379 10>, <380 10>, - <381 10>, <382 10>, <383 10>, <384 10>; - #address-cells = <1>; - #size-cells = <0>; - status = "disabled"; - - gpio0: gpio@0 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <8>; - reg = <0x0>; - status = "disabled"; - }; - - gpio1: gpio@100 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <6>; - reg = <0x100>; - status = "disabled"; - }; - - gpio2: gpio@200 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0x200>; - status = "disabled"; - }; - - gpio3: gpio@300 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <8>; - reg = <0x300>; - status = "disabled"; - }; - - gpio4: gpio@400 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <8>; - reg = <0x400>; - status = "disabled"; - }; - - gpio5: gpio@500 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <8>; - reg = <0x500>; - status = "disabled"; - }; - - gpio6: gpio@600 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <8>; - reg = <0x600>; - status = "disabled"; - }; - - gpio7: gpio@700 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <8>; - reg = <0x700>; - status = "disabled"; - }; - - gpio8: gpio@800 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <8>; - reg = <0x800>; - status = "disabled"; - }; - - gpio9: gpio@900 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <8>; - reg = <0x900>; - status = "disabled"; - }; - - gpio10: gpio@a00 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <8>; - reg = <0xa00>; - status = "disabled"; - }; - - gpio11: gpio@b00 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <6>; - reg = <0xb00>; - status = "disabled"; - }; + gpio: gpio@40410000 { + compatible = "renesas,rz-gpio-common"; + reg = <0x40410000 DT_SIZE_K(64)>, + <0x20 0xc>, + <0x140 0x18>, + <0x480 0x30>; + reg-names = "base", "p", "pm", "pfc"; + #address-cells = <1>; + #size-cells = <0>; + + gpio0: gpio@0 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <8>; + reg = <0x0>; + status = "disabled"; + }; + + gpio1: gpio@100 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <6>; + reg = <0x100>; + status = "disabled"; + }; + + gpio2: gpio@200 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0x200>; + status = "disabled"; + }; + + gpio3: gpio@300 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <8>; + reg = <0x300>; + status = "disabled"; + }; + + gpio4: gpio@400 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <8>; + reg = <0x400>; + status = "disabled"; + }; + + gpio5: gpio@500 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <8>; + reg = <0x500>; + status = "disabled"; + }; + + gpio6: gpio@600 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <8>; + reg = <0x600>; + status = "disabled"; + }; + + gpio7: gpio@700 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <8>; + reg = <0x700>; + status = "disabled"; + }; + + gpio8: gpio@800 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <8>; + reg = <0x800>; + status = "disabled"; + }; + + gpio9: gpio@900 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <8>; + reg = <0x900>; + status = "disabled"; + }; + + gpio10: gpio@a00 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <8>; + reg = <0xa00>; + status = "disabled"; + }; + + gpio11: gpio@b00 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <6>; + reg = <0xb00>; + status = "disabled"; }; }; diff --git a/dts/arm/renesas/rz/rzv/r9a09g057_cm33.dtsi b/dts/arm/renesas/rz/rzv/r9a09g057_cm33.dtsi index 47a1512cfdee..5b919bb56634 100644 --- a/dts/arm/renesas/rz/rzv/r9a09g057_cm33.dtsi +++ b/dts/arm/renesas/rz/rzv/r9a09g057_cm33.dtsi @@ -6,6 +6,7 @@ #include #include #include +#include / { compatible = "renesas,r9a09g057-m33"; @@ -31,133 +32,128 @@ }; }; + /* Dummy pinctrl node, filled with pin mux options at board level */ + pinctrl: pinctrl { + compatible = "renesas,rzv-pinctrl"; + }; + soc { - pinctrl: pin-controller@40410000 { - compatible = "renesas,rzv-pinctrl"; - reg = <0x40410000 DT_SIZE_K(64)>; - reg-names = "pinctrl"; - - gpio: gpio-common { - compatible = "renesas,rz-gpio-int"; - interrupts = <353 10>, <354 10>, <355 10>, <356 10>, - <357 10>, <358 10>, <359 10>, <360 10>, - <361 10>, <362 10>, <363 10>, <364 10>, - <365 10>, <366 10>, <367 10>, <368 10>, - <369 10>, <370 10>, <371 10>, <372 10>, - <373 10>, <374 10>, <375 10>, <376 10>, - <377 10>, <378 10>, <379 10>, <380 10>, - <381 10>, <382 10>, <383 10>, <384 10>; - #address-cells = <1>; - #size-cells = <0>; - status = "disabled"; - - gpio0: gpio@0 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <8>; - reg = <0x0>; - status = "disabled"; - }; - - gpio1: gpio@100 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <6>; - reg = <0x100>; - status = "disabled"; - }; - - gpio2: gpio@200 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0x200>; - status = "disabled"; - }; - - gpio3: gpio@300 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <8>; - reg = <0x300>; - status = "disabled"; - }; - - gpio4: gpio@400 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <8>; - reg = <0x400>; - status = "disabled"; - }; - - gpio5: gpio@500 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <8>; - reg = <0x500>; - status = "disabled"; - }; - - gpio6: gpio@600 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <8>; - reg = <0x600>; - status = "disabled"; - }; - - gpio7: gpio@700 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <8>; - reg = <0x700>; - status = "disabled"; - }; - - gpio8: gpio@800 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <8>; - reg = <0x800>; - status = "disabled"; - }; - - gpio9: gpio@900 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <8>; - reg = <0x900>; - status = "disabled"; - }; - - gpio10: gpio@a00 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <8>; - reg = <0xa00>; - status = "disabled"; - }; - - gpio11: gpio@b00 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <6>; - reg = <0xb00>; - status = "disabled"; - }; + gpio: gpio@40410000 { + compatible = "renesas,rz-gpio-common"; + reg = <0x40410000 DT_SIZE_K(64)>, + <0x20 0xc>, + <0x140 0x18>, + <0x480 0x30>; + reg-names = "base", "p", "pm", "pfc"; + #address-cells = <1>; + #size-cells = <0>; + + gpio0: gpio@0 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <8>; + reg = <0x0>; + status = "disabled"; + }; + + gpio1: gpio@100 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <6>; + reg = <0x100>; + status = "disabled"; + }; + + gpio2: gpio@200 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0x200>; + status = "disabled"; + }; + + gpio3: gpio@300 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <8>; + reg = <0x300>; + status = "disabled"; + }; + + gpio4: gpio@400 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <8>; + reg = <0x400>; + status = "disabled"; + }; + + gpio5: gpio@500 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <8>; + reg = <0x500>; + status = "disabled"; + }; + + gpio6: gpio@600 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <8>; + reg = <0x600>; + status = "disabled"; + }; + + gpio7: gpio@700 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <8>; + reg = <0x700>; + status = "disabled"; + }; + + gpio8: gpio@800 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <8>; + reg = <0x800>; + status = "disabled"; + }; + + gpio9: gpio@900 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <8>; + reg = <0x900>; + status = "disabled"; + }; + + gpio10: gpio@a00 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <8>; + reg = <0xa00>; + status = "disabled"; + }; + + gpio11: gpio@b00 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <6>; + reg = <0xb00>; + status = "disabled"; }; }; diff --git a/dts/arm/renesas/rz/rzv/r9a09g057_cr8.dtsi b/dts/arm/renesas/rz/rzv/r9a09g057_cr8.dtsi index 1c194fe38cfd..9127fd27de52 100644 --- a/dts/arm/renesas/rz/rzv/r9a09g057_cr8.dtsi +++ b/dts/arm/renesas/rz/rzv/r9a09g057_cr8.dtsi @@ -3,10 +3,11 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include #include #include +#include +#include / { #address-cells = <1>; @@ -26,6 +27,11 @@ }; }; + /* Dummy pinctrl node, filled with pin mux options at board level */ + pinctrl: pinctrl { + compatible = "renesas,rzv-pinctrl"; + }; + soc { #address-cells = <1>; #size-cells = <1>; @@ -71,156 +77,122 @@ zephyr,memory-region = "SRAM3"; }; - pinctrl: pin-controller@10410000 { - compatible = "renesas,rzv-pinctrl"; - reg = <0x10410000 DT_SIZE_K(64)>; - reg-names = "pinctrl"; - - gpio: gpio-common { - compatible = "renesas,rz-gpio-int"; - interrupts = , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - ; - #address-cells = <1>; - #size-cells = <0>; - status = "disabled"; - - gpio0: gpio@0 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <8>; - reg = <0x0>; - status = "disabled"; - }; - - gpio1: gpio@100 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <6>; - reg = <0x100>; - status = "disabled"; - }; - - gpio2: gpio@200 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0x200>; - status = "disabled"; - }; - - gpio3: gpio@300 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <8>; - reg = <0x300>; - status = "disabled"; - }; - - gpio4: gpio@400 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <8>; - reg = <0x400>; - status = "disabled"; - }; - - gpio5: gpio@500 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <8>; - reg = <0x500>; - status = "disabled"; - }; - - gpio6: gpio@600 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <8>; - reg = <0x600>; - status = "disabled"; - }; - - gpio7: gpio@700 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <8>; - reg = <0x700>; - status = "disabled"; - }; - - gpio8: gpio@800 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <8>; - reg = <0x800>; - status = "disabled"; - }; - - gpio9: gpio@900 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <8>; - reg = <0x900>; - status = "disabled"; - }; - - gpio10: gpio@a00 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <8>; - reg = <0xa00>; - status = "disabled"; - }; - - gpio11: gpio@b00 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <6>; - reg = <0xb00>; - status = "disabled"; - }; + gpio: gpio@10410000 { + compatible = "renesas,rz-gpio-common"; + reg = <0x10410000 DT_SIZE_K(64)>, + <0x20 0xc>, + <0x140 0x18>, + <0x480 0x30>; + reg-names = "base", "p", "pm", "pfc"; + #address-cells = <1>; + #size-cells = <0>; + + gpio0: gpio@0 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <8>; + reg = <0x0>; + status = "disabled"; + }; + + gpio1: gpio@100 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <6>; + reg = <0x100>; + status = "disabled"; + }; + + gpio2: gpio@200 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0x200>; + status = "disabled"; + }; + + gpio3: gpio@300 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <8>; + reg = <0x300>; + status = "disabled"; + }; + + gpio4: gpio@400 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <8>; + reg = <0x400>; + status = "disabled"; + }; + + gpio5: gpio@500 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <8>; + reg = <0x500>; + status = "disabled"; + }; + + gpio6: gpio@600 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <8>; + reg = <0x600>; + status = "disabled"; + }; + + gpio7: gpio@700 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <8>; + reg = <0x700>; + status = "disabled"; + }; + + gpio8: gpio@800 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <8>; + reg = <0x800>; + status = "disabled"; + }; + + gpio9: gpio@900 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <8>; + reg = <0x900>; + status = "disabled"; + }; + + gpio10: gpio@a00 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <8>; + reg = <0xa00>; + status = "disabled"; + }; + + gpio11: gpio@b00 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <6>; + reg = <0xb00>; + status = "disabled"; }; }; diff --git a/dts/arm64/renesas/rz/rza/r9a07g063.dtsi b/dts/arm64/renesas/rz/rza/r9a07g063.dtsi index 11b8a5fbb9e6..5c097e953601 100644 --- a/dts/arm64/renesas/rz/rza/r9a07g063.dtsi +++ b/dts/arm64/renesas/rz/rza/r9a07g063.dtsi @@ -7,12 +7,13 @@ #include #include #include -#include -#include -#include #include -#include #include +#include +#include +#include +#include +#include / { compatible = "renesas,r9a07g063"; @@ -46,6 +47,11 @@ #clock-cells = <0>; }; + /* Dummy pinctrl node, filled with pin mux options at board level */ + pinctrl: pinctrl { + compatible = "renesas,rza-pinctrl"; + }; + soc { interrupt-parent = <&gic>; @@ -270,219 +276,185 @@ status = "disabled"; }; - pinctrl: pin-controller@11030000 { - compatible = "renesas,rza-pinctrl"; - reg = <0x11030000 DT_SIZE_K(64)>; - reg-names = "pinctrl"; - - gpio: gpio-common { - compatible = "renesas,rz-gpio-int"; - interrupts = , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - ; - #address-cells = <1>; - #size-cells = <0>; - status = "disabled"; - - gpio0: gpio@0 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <4>; - reg = <0x0>; - status = "disabled"; - }; - - gpio1: gpio@100 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <5>; - reg = <0x100>; - status = "disabled"; - }; - - gpio2: gpio@200 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <4>; - reg = <0x200>; - status = "disabled"; - }; - - gpio3: gpio@300 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <4>; - reg = <0x300>; - status = "disabled"; - }; - - gpio4: gpio@400 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <6>; - reg = <0x400>; - status = "disabled"; - }; - - gpio5: gpio@500 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <5>; - reg = <0x500>; - status = "disabled"; - }; - - gpio6: gpio@600 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <5>; - reg = <0x600>; - status = "disabled"; - }; - - gpio7: gpio@700 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <5>; - reg = <0x700>; - status = "disabled"; - }; - - gpio8: gpio@800 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <5>; - reg = <0x800>; - status = "disabled"; - }; - - gpio9: gpio@900 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <4>; - reg = <0x900>; - status = "disabled"; - }; - - gpio10: gpio@a00 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <5>; - reg = <0xa00>; - status = "disabled"; - }; - - gpio11: gpio@b00 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <4>; - reg = <0xb00>; - status = "disabled"; - }; - - gpio12: gpio@c00 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0xc00>; - status = "disabled"; - }; - - gpio13: gpio@d00 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <5>; - reg = <0xd00>; - status = "disabled"; - }; - - gpio14: gpio@e00 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <3>; - reg = <0xe00>; - status = "disabled"; - }; - - gpio15: gpio@f00 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <4>; - reg = <0xf00>; - status = "disabled"; - }; - - gpio16: gpio@1000 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <2>; - reg = <0x1000>; - status = "disabled"; - }; - - gpio17: gpio@1100 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <4>; - reg = <0x1100>; - status = "disabled"; - }; - - gpio18: gpio@1200 { - compatible = "renesas,rz-gpio"; - gpio-controller; - #gpio-cells = <2>; - ngpios = <6>; - reg = <0x1200>; - status = "disabled"; - }; + gpio: gpio@11030000 { + compatible = "renesas,rz-gpio-common"; + reg = <0x11030000 DT_SIZE_K(64)>, + <0x10 0x13>, + <0x120 0x26>, + <0x440 0x4c>; + reg-names = "base", "p", "pm", "pfc"; + #address-cells = <1>; + #size-cells = <0>; + + gpio0: gpio@0 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <4>; + reg = <0x0>; + status = "disabled"; + }; + + gpio1: gpio@100 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <5>; + reg = <0x100>; + status = "disabled"; + }; + + gpio2: gpio@200 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <4>; + reg = <0x200>; + status = "disabled"; + }; + + gpio3: gpio@300 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <4>; + reg = <0x300>; + status = "disabled"; + }; + + gpio4: gpio@400 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <6>; + reg = <0x400>; + status = "disabled"; + }; + + gpio5: gpio@500 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <5>; + reg = <0x500>; + status = "disabled"; + }; + + gpio6: gpio@600 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <5>; + reg = <0x600>; + status = "disabled"; + }; + + gpio7: gpio@700 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <5>; + reg = <0x700>; + status = "disabled"; + }; + + gpio8: gpio@800 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <5>; + reg = <0x800>; + status = "disabled"; + }; + + gpio9: gpio@900 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <4>; + reg = <0x900>; + status = "disabled"; + }; + + gpio10: gpio@a00 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <5>; + reg = <0xa00>; + status = "disabled"; + }; + + gpio11: gpio@b00 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <4>; + reg = <0xb00>; + status = "disabled"; + }; + + gpio12: gpio@c00 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0xc00>; + status = "disabled"; + }; + + gpio13: gpio@d00 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <5>; + reg = <0xd00>; + status = "disabled"; + }; + + gpio14: gpio@e00 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <3>; + reg = <0xe00>; + status = "disabled"; + }; + + gpio15: gpio@f00 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <4>; + reg = <0xf00>; + status = "disabled"; + }; + + gpio16: gpio@1000 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0x1000>; + status = "disabled"; + }; + + gpio17: gpio@1100 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <4>; + reg = <0x1100>; + status = "disabled"; + }; + + gpio18: gpio@1200 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <6>; + reg = <0x1200>; + status = "disabled"; }; }; From af766e0cdae3f9c75a1b6d535ebd95bc5ae1f74d Mon Sep 17 00:00:00 2001 From: Nhut Nguyen Date: Wed, 17 Dec 2025 18:02:54 +0700 Subject: [PATCH 2163/3659] boards: renesas: Update irq property of gpio nodes to use irq phandle Update irq property of gpio nodes to use irq phandle for rzn2l_rsk, rzt2l_rsk, rzt2m_rsk Signed-off-by: Nhut Nguyen --- boards/renesas/rzn2l_rsk/rzn2l_rsk.dts | 2 +- boards/renesas/rzt2l_rsk/rzt2l_rsk.dts | 2 +- boards/renesas/rzt2m_rsk/rzt2m_rsk_r9a07g075m24gbg_cr520.dts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/boards/renesas/rzn2l_rsk/rzn2l_rsk.dts b/boards/renesas/rzn2l_rsk/rzn2l_rsk.dts index c08c80df0903..f29fca88939b 100644 --- a/boards/renesas/rzn2l_rsk/rzn2l_rsk.dts +++ b/boards/renesas/rzn2l_rsk/rzn2l_rsk.dts @@ -103,7 +103,7 @@ }; &gpio16 { - irqs = <3 7>; + irqs = <&irq7 3>; status = "okay"; }; diff --git a/boards/renesas/rzt2l_rsk/rzt2l_rsk.dts b/boards/renesas/rzt2l_rsk/rzt2l_rsk.dts index 00fe010130d0..c06c9b273fdc 100644 --- a/boards/renesas/rzt2l_rsk/rzt2l_rsk.dts +++ b/boards/renesas/rzt2l_rsk/rzt2l_rsk.dts @@ -74,7 +74,7 @@ }; &gpio16 { - irqs = <3 7>; + irqs = <&irq7 3>; status = "okay"; }; diff --git a/boards/renesas/rzt2m_rsk/rzt2m_rsk_r9a07g075m24gbg_cr520.dts b/boards/renesas/rzt2m_rsk/rzt2m_rsk_r9a07g075m24gbg_cr520.dts index 6606eb199508..aac9b1e409a8 100644 --- a/boards/renesas/rzt2m_rsk/rzt2m_rsk_r9a07g075m24gbg_cr520.dts +++ b/boards/renesas/rzt2m_rsk/rzt2m_rsk_r9a07g075m24gbg_cr520.dts @@ -94,7 +94,7 @@ }; &gpio10 { - irqs = <5 2>; + irqs = <&irq2 5>; status = "okay"; }; From 315ea7bdccb1f045871111b76024b56b58ad4573 Mon Sep 17 00:00:00 2001 From: Nhut Nguyen Date: Wed, 17 Dec 2025 18:05:23 +0700 Subject: [PATCH 2164/3659] tests: drivers: gpio: Update Renesas RZ overlay files Update all Renesas RZ overlays for GPIO tests to replace raw values with IRQ phandles. Signed-off-by: Nhut Nguyen --- .../drivers/gpio/gpio_api_1pin/boards/rza3ul_smarc.overlay | 4 ++-- .../boards/rzg2l_smarc_r9a07g044l23gbg_cm33.overlay | 4 ++-- .../boards/rzg2lc_smarc_r9a07g044c22gbg_cm33.overlay | 4 ++-- .../boards/rzg2ul_smarc_r9a07g043u11gbg_cm33.overlay | 4 ++-- .../boards/rzg3s_smarc_r9a08g045s33gbg_cm33.overlay | 4 ++-- .../boards/rzv2h_evk_r9a09g057h44gbg_cm33.overlay | 4 ++-- .../boards/rzv2h_evk_r9a09g057h44gbg_cr8_0.overlay | 6 +++++- .../boards/rzv2l_smarc_r9a07g054l23gbg_cm33.overlay | 4 ++-- .../boards/rzv2n_evk_r9a09g056n48gbg_cm33.overlay | 6 +++++- .../drivers/gpio/gpio_basic_api/boards/rza3ul_smarc.overlay | 4 ++-- .../boards/rzg2l_smarc_r9a07g044l23gbg_cm33.overlay | 4 ++-- .../boards/rzg2lc_smarc_r9a07g044c22gbg_cm33.overlay | 5 ++--- .../boards/rzg2ul_smarc_r9a07g043u11gbg_cm33.overlay | 4 ++-- .../boards/rzg3s_smarc_r9a08g045s33gbg_cm33.overlay | 4 ++-- tests/drivers/gpio/gpio_basic_api/boards/rzn2l_rsk.overlay | 2 +- tests/drivers/gpio/gpio_basic_api/boards/rzt2l_rsk.overlay | 2 +- .../boards/rzt2m_rsk_r9a07g075m24gbg_cr520.overlay | 2 +- .../boards/rzv2h_evk_r9a09g057h44gbg_cm33.overlay | 4 ++-- .../boards/rzv2h_evk_r9a09g057h44gbg_cr8_0.overlay | 6 +++++- .../boards/rzv2l_smarc_r9a07g054l23gbg_cm33.overlay | 4 ++-- .../boards/rzv2n_evk_r9a09g056n48gbg_cm33.overlay | 6 +++++- 21 files changed, 51 insertions(+), 36 deletions(-) diff --git a/tests/drivers/gpio/gpio_api_1pin/boards/rza3ul_smarc.overlay b/tests/drivers/gpio/gpio_api_1pin/boards/rza3ul_smarc.overlay index 080d687daf43..49bfab50ccb1 100644 --- a/tests/drivers/gpio/gpio_api_1pin/boards/rza3ul_smarc.overlay +++ b/tests/drivers/gpio/gpio_api_1pin/boards/rza3ul_smarc.overlay @@ -17,11 +17,11 @@ }; }; -&gpio { +&tint15 { status = "okay"; }; &gpio1 { - irqs = <3 15>; + irqs = <&tint15 3>; status = "okay"; }; diff --git a/tests/drivers/gpio/gpio_api_1pin/boards/rzg2l_smarc_r9a07g044l23gbg_cm33.overlay b/tests/drivers/gpio/gpio_api_1pin/boards/rzg2l_smarc_r9a07g044l23gbg_cm33.overlay index f5aae70d3889..5b46533b9087 100644 --- a/tests/drivers/gpio/gpio_api_1pin/boards/rzg2l_smarc_r9a07g044l23gbg_cm33.overlay +++ b/tests/drivers/gpio/gpio_api_1pin/boards/rzg2l_smarc_r9a07g044l23gbg_cm33.overlay @@ -17,11 +17,11 @@ }; }; -&gpio { +&tint1 { status = "okay"; }; &gpio43 { - irqs = <1 1>; + irqs = <&tint1 1>; status = "okay"; }; diff --git a/tests/drivers/gpio/gpio_api_1pin/boards/rzg2lc_smarc_r9a07g044c22gbg_cm33.overlay b/tests/drivers/gpio/gpio_api_1pin/boards/rzg2lc_smarc_r9a07g044c22gbg_cm33.overlay index f5aae70d3889..5b46533b9087 100644 --- a/tests/drivers/gpio/gpio_api_1pin/boards/rzg2lc_smarc_r9a07g044c22gbg_cm33.overlay +++ b/tests/drivers/gpio/gpio_api_1pin/boards/rzg2lc_smarc_r9a07g044c22gbg_cm33.overlay @@ -17,11 +17,11 @@ }; }; -&gpio { +&tint1 { status = "okay"; }; &gpio43 { - irqs = <1 1>; + irqs = <&tint1 1>; status = "okay"; }; diff --git a/tests/drivers/gpio/gpio_api_1pin/boards/rzg2ul_smarc_r9a07g043u11gbg_cm33.overlay b/tests/drivers/gpio/gpio_api_1pin/boards/rzg2ul_smarc_r9a07g043u11gbg_cm33.overlay index 2ada701c60fc..40a546767460 100644 --- a/tests/drivers/gpio/gpio_api_1pin/boards/rzg2ul_smarc_r9a07g043u11gbg_cm33.overlay +++ b/tests/drivers/gpio/gpio_api_1pin/boards/rzg2ul_smarc_r9a07g043u11gbg_cm33.overlay @@ -17,11 +17,11 @@ }; }; -&gpio { +&tint20 { status = "okay"; }; &gpio1 { - irqs = <4 20>; + irqs = <&tint20 4>; status = "okay"; }; diff --git a/tests/drivers/gpio/gpio_api_1pin/boards/rzg3s_smarc_r9a08g045s33gbg_cm33.overlay b/tests/drivers/gpio/gpio_api_1pin/boards/rzg3s_smarc_r9a08g045s33gbg_cm33.overlay index e97dd4429215..cf384b689241 100644 --- a/tests/drivers/gpio/gpio_api_1pin/boards/rzg3s_smarc_r9a08g045s33gbg_cm33.overlay +++ b/tests/drivers/gpio/gpio_api_1pin/boards/rzg3s_smarc_r9a08g045s33gbg_cm33.overlay @@ -17,11 +17,11 @@ }; }; -&gpio { +&tint1 { status = "okay"; }; &gpio13 { - irqs = <1 1>; + irqs = <&tint1 1>; status = "okay"; }; diff --git a/tests/drivers/gpio/gpio_api_1pin/boards/rzv2h_evk_r9a09g057h44gbg_cm33.overlay b/tests/drivers/gpio/gpio_api_1pin/boards/rzv2h_evk_r9a09g057h44gbg_cm33.overlay index a3c6e608d136..c0a60aea3144 100644 --- a/tests/drivers/gpio/gpio_api_1pin/boards/rzv2h_evk_r9a09g057h44gbg_cm33.overlay +++ b/tests/drivers/gpio/gpio_api_1pin/boards/rzv2h_evk_r9a09g057h44gbg_cm33.overlay @@ -3,11 +3,11 @@ * SPDX-License-Identifier: Apache-2.0 */ -&gpio { +&tint1 { status = "okay"; }; &gpio0 { - irqs = <0 1>; + irqs = <&tint1 0>; status = "okay"; }; diff --git a/tests/drivers/gpio/gpio_api_1pin/boards/rzv2h_evk_r9a09g057h44gbg_cr8_0.overlay b/tests/drivers/gpio/gpio_api_1pin/boards/rzv2h_evk_r9a09g057h44gbg_cr8_0.overlay index 3c827fb2aa30..c0a60aea3144 100644 --- a/tests/drivers/gpio/gpio_api_1pin/boards/rzv2h_evk_r9a09g057h44gbg_cr8_0.overlay +++ b/tests/drivers/gpio/gpio_api_1pin/boards/rzv2h_evk_r9a09g057h44gbg_cr8_0.overlay @@ -3,7 +3,11 @@ * SPDX-License-Identifier: Apache-2.0 */ +&tint1 { + status = "okay"; +}; + &gpio0 { - irqs = <0 1>; + irqs = <&tint1 0>; status = "okay"; }; diff --git a/tests/drivers/gpio/gpio_api_1pin/boards/rzv2l_smarc_r9a07g054l23gbg_cm33.overlay b/tests/drivers/gpio/gpio_api_1pin/boards/rzv2l_smarc_r9a07g054l23gbg_cm33.overlay index f5aae70d3889..5b46533b9087 100644 --- a/tests/drivers/gpio/gpio_api_1pin/boards/rzv2l_smarc_r9a07g054l23gbg_cm33.overlay +++ b/tests/drivers/gpio/gpio_api_1pin/boards/rzv2l_smarc_r9a07g054l23gbg_cm33.overlay @@ -17,11 +17,11 @@ }; }; -&gpio { +&tint1 { status = "okay"; }; &gpio43 { - irqs = <1 1>; + irqs = <&tint1 1>; status = "okay"; }; diff --git a/tests/drivers/gpio/gpio_api_1pin/boards/rzv2n_evk_r9a09g056n48gbg_cm33.overlay b/tests/drivers/gpio/gpio_api_1pin/boards/rzv2n_evk_r9a09g056n48gbg_cm33.overlay index 3c827fb2aa30..c0a60aea3144 100644 --- a/tests/drivers/gpio/gpio_api_1pin/boards/rzv2n_evk_r9a09g056n48gbg_cm33.overlay +++ b/tests/drivers/gpio/gpio_api_1pin/boards/rzv2n_evk_r9a09g056n48gbg_cm33.overlay @@ -3,7 +3,11 @@ * SPDX-License-Identifier: Apache-2.0 */ +&tint1 { + status = "okay"; +}; + &gpio0 { - irqs = <0 1>; + irqs = <&tint1 0>; status = "okay"; }; diff --git a/tests/drivers/gpio/gpio_basic_api/boards/rza3ul_smarc.overlay b/tests/drivers/gpio/gpio_basic_api/boards/rza3ul_smarc.overlay index d0821d8c8421..6c2463137d46 100644 --- a/tests/drivers/gpio/gpio_basic_api/boards/rza3ul_smarc.overlay +++ b/tests/drivers/gpio/gpio_basic_api/boards/rza3ul_smarc.overlay @@ -11,11 +11,11 @@ }; }; -&gpio { +&tint20 { status = "okay"; }; &gpio1 { - irqs = <4 20>; + irqs = <&tint20 4>; status = "okay"; }; diff --git a/tests/drivers/gpio/gpio_basic_api/boards/rzg2l_smarc_r9a07g044l23gbg_cm33.overlay b/tests/drivers/gpio/gpio_basic_api/boards/rzg2l_smarc_r9a07g044l23gbg_cm33.overlay index fba1f4baee3a..9f4d53b7cf3f 100644 --- a/tests/drivers/gpio/gpio_basic_api/boards/rzg2l_smarc_r9a07g044l23gbg_cm33.overlay +++ b/tests/drivers/gpio/gpio_basic_api/boards/rzg2l_smarc_r9a07g044l23gbg_cm33.overlay @@ -11,11 +11,11 @@ }; }; -&gpio { +&tint20 { status = "okay"; }; &gpio43 { - irqs = <2 20>; + irqs = <&tint20 2>; status = "okay"; }; diff --git a/tests/drivers/gpio/gpio_basic_api/boards/rzg2lc_smarc_r9a07g044c22gbg_cm33.overlay b/tests/drivers/gpio/gpio_basic_api/boards/rzg2lc_smarc_r9a07g044c22gbg_cm33.overlay index 3b2766f7b33f..411a6e4859b1 100644 --- a/tests/drivers/gpio/gpio_basic_api/boards/rzg2lc_smarc_r9a07g044c22gbg_cm33.overlay +++ b/tests/drivers/gpio/gpio_basic_api/boards/rzg2lc_smarc_r9a07g044c22gbg_cm33.overlay @@ -11,16 +11,15 @@ }; }; -&gpio { +&tint20 { status = "okay"; }; &gpio4 { - irqs = <2 20>; status = "okay"; }; &gpio43 { - irqs = <2 20>; + irqs = <&tint20 0>; status = "okay"; }; diff --git a/tests/drivers/gpio/gpio_basic_api/boards/rzg2ul_smarc_r9a07g043u11gbg_cm33.overlay b/tests/drivers/gpio/gpio_basic_api/boards/rzg2ul_smarc_r9a07g043u11gbg_cm33.overlay index d0821d8c8421..6c2463137d46 100644 --- a/tests/drivers/gpio/gpio_basic_api/boards/rzg2ul_smarc_r9a07g043u11gbg_cm33.overlay +++ b/tests/drivers/gpio/gpio_basic_api/boards/rzg2ul_smarc_r9a07g043u11gbg_cm33.overlay @@ -11,11 +11,11 @@ }; }; -&gpio { +&tint20 { status = "okay"; }; &gpio1 { - irqs = <4 20>; + irqs = <&tint20 4>; status = "okay"; }; diff --git a/tests/drivers/gpio/gpio_basic_api/boards/rzg3s_smarc_r9a08g045s33gbg_cm33.overlay b/tests/drivers/gpio/gpio_basic_api/boards/rzg3s_smarc_r9a08g045s33gbg_cm33.overlay index 1087f9b0b5c3..a5b3db19b49c 100644 --- a/tests/drivers/gpio/gpio_basic_api/boards/rzg3s_smarc_r9a08g045s33gbg_cm33.overlay +++ b/tests/drivers/gpio/gpio_basic_api/boards/rzg3s_smarc_r9a08g045s33gbg_cm33.overlay @@ -11,11 +11,11 @@ }; }; -&gpio { +&tint1 { status = "okay"; }; &gpio8 { - irqs = <3 20>; + irqs = <&tint1 3>; status = "okay"; }; diff --git a/tests/drivers/gpio/gpio_basic_api/boards/rzn2l_rsk.overlay b/tests/drivers/gpio/gpio_basic_api/boards/rzn2l_rsk.overlay index 85624d2667de..878dc6f12336 100644 --- a/tests/drivers/gpio/gpio_basic_api/boards/rzn2l_rsk.overlay +++ b/tests/drivers/gpio/gpio_basic_api/boards/rzn2l_rsk.overlay @@ -28,6 +28,6 @@ }; &gpio2 { - irqs = <0 4>; + irqs = <&irq4 0>; status = "okay"; }; diff --git a/tests/drivers/gpio/gpio_basic_api/boards/rzt2l_rsk.overlay b/tests/drivers/gpio/gpio_basic_api/boards/rzt2l_rsk.overlay index 9c90d2668166..8190ed25bf29 100644 --- a/tests/drivers/gpio/gpio_basic_api/boards/rzt2l_rsk.overlay +++ b/tests/drivers/gpio/gpio_basic_api/boards/rzt2l_rsk.overlay @@ -28,6 +28,6 @@ }; &gpio15 { - irqs = <4 3>; + irqs = <&irq3 4>; status = "okay"; }; diff --git a/tests/drivers/gpio/gpio_basic_api/boards/rzt2m_rsk_r9a07g075m24gbg_cr520.overlay b/tests/drivers/gpio/gpio_basic_api/boards/rzt2m_rsk_r9a07g075m24gbg_cr520.overlay index 106f582dd8da..28835d8521a1 100644 --- a/tests/drivers/gpio/gpio_basic_api/boards/rzt2m_rsk_r9a07g075m24gbg_cr520.overlay +++ b/tests/drivers/gpio/gpio_basic_api/boards/rzt2m_rsk_r9a07g075m24gbg_cr520.overlay @@ -28,6 +28,6 @@ }; &gpio2 { - irqs = <0 4>; + irqs = <&irq4 0>; status = "okay"; }; diff --git a/tests/drivers/gpio/gpio_basic_api/boards/rzv2h_evk_r9a09g057h44gbg_cm33.overlay b/tests/drivers/gpio/gpio_basic_api/boards/rzv2h_evk_r9a09g057h44gbg_cm33.overlay index 83dc81f312c4..1caa7822d42c 100644 --- a/tests/drivers/gpio/gpio_basic_api/boards/rzv2h_evk_r9a09g057h44gbg_cm33.overlay +++ b/tests/drivers/gpio/gpio_basic_api/boards/rzv2h_evk_r9a09g057h44gbg_cm33.overlay @@ -11,11 +11,11 @@ }; }; -&gpio { +&tint24 { status = "okay"; }; &gpio8 { - irqs = <1 24>; + irqs = <&tint24 1>; status = "okay"; }; diff --git a/tests/drivers/gpio/gpio_basic_api/boards/rzv2h_evk_r9a09g057h44gbg_cr8_0.overlay b/tests/drivers/gpio/gpio_basic_api/boards/rzv2h_evk_r9a09g057h44gbg_cr8_0.overlay index 45be9442f5df..1caa7822d42c 100644 --- a/tests/drivers/gpio/gpio_basic_api/boards/rzv2h_evk_r9a09g057h44gbg_cr8_0.overlay +++ b/tests/drivers/gpio/gpio_basic_api/boards/rzv2h_evk_r9a09g057h44gbg_cr8_0.overlay @@ -11,7 +11,11 @@ }; }; +&tint24 { + status = "okay"; +}; + &gpio8 { - irqs = <1 24>; + irqs = <&tint24 1>; status = "okay"; }; diff --git a/tests/drivers/gpio/gpio_basic_api/boards/rzv2l_smarc_r9a07g054l23gbg_cm33.overlay b/tests/drivers/gpio/gpio_basic_api/boards/rzv2l_smarc_r9a07g054l23gbg_cm33.overlay index fba1f4baee3a..9f4d53b7cf3f 100644 --- a/tests/drivers/gpio/gpio_basic_api/boards/rzv2l_smarc_r9a07g054l23gbg_cm33.overlay +++ b/tests/drivers/gpio/gpio_basic_api/boards/rzv2l_smarc_r9a07g054l23gbg_cm33.overlay @@ -11,11 +11,11 @@ }; }; -&gpio { +&tint20 { status = "okay"; }; &gpio43 { - irqs = <2 20>; + irqs = <&tint20 2>; status = "okay"; }; diff --git a/tests/drivers/gpio/gpio_basic_api/boards/rzv2n_evk_r9a09g056n48gbg_cm33.overlay b/tests/drivers/gpio/gpio_basic_api/boards/rzv2n_evk_r9a09g056n48gbg_cm33.overlay index 45be9442f5df..1caa7822d42c 100644 --- a/tests/drivers/gpio/gpio_basic_api/boards/rzv2n_evk_r9a09g056n48gbg_cm33.overlay +++ b/tests/drivers/gpio/gpio_basic_api/boards/rzv2n_evk_r9a09g056n48gbg_cm33.overlay @@ -11,7 +11,11 @@ }; }; +&tint24 { + status = "okay"; +}; + &gpio8 { - irqs = <1 24>; + irqs = <&tint24 1>; status = "okay"; }; From 541e732f3540ea499ca2ee0963d15eb36c9e9d4d Mon Sep 17 00:00:00 2001 From: Nhut Nguyen Date: Fri, 16 Jan 2026 11:23:25 +0700 Subject: [PATCH 2165/3659] doc: migration-guide-4.4: Document renesas,rz-gpio change Document renesas,rz-gpio change Signed-off-by: Nhut Nguyen --- doc/releases/migration-guide-4.4.rst | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/doc/releases/migration-guide-4.4.rst b/doc/releases/migration-guide-4.4.rst index 51db2ef756ae..04b88edad762 100644 --- a/doc/releases/migration-guide-4.4.rst +++ b/doc/releases/migration-guide-4.4.rst @@ -422,6 +422,27 @@ GPIO The Devicetree property ``port-is-output`` has been removed. The reg-names are now taken directly from LiteX. (:github:`99329`) +* The ``irqs`` property of :dtcompatible:`renesas,rz-gpio` has been reworked + to map a pin to an interrupt phandle explicitly instead of an interrupt index (:github:`101256`). + + .. code-block:: devicetree + + /* Old (Zephyr ≤ 4.3) */ + &gpio16 { + /* Map port16 pin3 to tint7 */ + irqs = <3 7>; + }; + + /* New (Zephyr ≥ 4.4) */ + &tint7 { + status = "okay"; + }; + + &gpio16 { + /* Map port16 pin3 to tint7 */ + irqs = <&tint7 3>; + }; + Infineon ======== From f1edde06f03efb662909bce61794c561c5b9c85d Mon Sep 17 00:00:00 2001 From: Deepika R Date: Tue, 23 Dec 2025 12:44:55 +0530 Subject: [PATCH 2166/3659] drivers: counter: Add Infineon counter driver Add implementation of the Infineon PSoC4 TCPWM-based counter driver. - Provides basic counter operations including start, stop, read, and set alarm. - Supports configuration and initialization through Device Tree. - Enables alarm callback handling for precise time-based event generation. Signed-off-by: Deepika R Signed-off-by: Sayooj K Karun --- drivers/counter/counter_infineon_tcpwm.c | 81 ++++++++++++++++-------- 1 file changed, 56 insertions(+), 25 deletions(-) diff --git a/drivers/counter/counter_infineon_tcpwm.c b/drivers/counter/counter_infineon_tcpwm.c index 33eca426e135..96430836bb11 100644 --- a/drivers/counter/counter_infineon_tcpwm.c +++ b/drivers/counter/counter_infineon_tcpwm.c @@ -11,10 +11,12 @@ #include #include +#include #include #include #include #include +#include #include LOG_MODULE_REGISTER(ifx_tcpwm_counter, CONFIG_COUNTER_LOG_LEVEL); @@ -56,7 +58,11 @@ static const cy_stc_tcpwm_counter_config_t counter_default_config = { .compare0 = 16384, .compare1 = 16384, .enableCompareSwap = false, +#if defined(CONFIG_SOC_FAMILY_INFINEON_PSOC4) + .interruptSources = CY_TCPWM_INT_ON_CC_OR_TC, +#else .interruptSources = CY_TCPWM_INT_NONE, +#endif .captureInputMode = 0x3U, .captureInput = CY_TCPWM_INPUT_0, .reloadInputMode = 0x3U, @@ -179,7 +185,12 @@ static int ifx_tcpwm_counter_start(const struct device *dev) const struct ifx_tcpwm_counter_config *config = dev->config; Cy_TCPWM_Counter_Enable(config->reg_base, config->index); + +#if defined(CONFIG_SOC_FAMILY_INFINEON_PSOC4) + Cy_TCPWM_TriggerStart(config->reg_base, BIT(config->index)); +#else Cy_TCPWM_TriggerStart_Single(config->reg_base, config->index); +#endif return 0; } @@ -207,9 +218,7 @@ static uint32_t ifx_tcpwm_counter_get_freq(const struct device *dev) /* Calculate clock connection based on TCPWM index */ clk_connection = ifx_cat1_tcpwm_get_clock_index(tcpwm_block, config->index); - uint32_t frequency = ifx_cat1_utils_peri_pclk_get_frequency(clk_connection, - &data->clock); - + uint32_t frequency = ifx_cat1_utils_peri_pclk_get_frequency(clk_connection, &data->clock); return frequency; } @@ -253,13 +262,19 @@ static int ifx_tcpwm_counter_set_top_value(const struct device *dev, data->value = Cy_TCPWM_Counter_GetCounter(config->reg_base, config->index); } +#if defined(CONFIG_SOC_FAMILY_INFINEON_PSOC4) + Cy_TCPWM_Counter_SetPeriod(config->reg_base, config->index, cfg->ticks); +#else Cy_TCPWM_Block_SetPeriod(config->reg_base, config->index, cfg->ticks); +#endif /* Register an top_value terminal count event callback handler if * callback is not NULL. */ if (cfg->callback != NULL) { counter_enable_event(dev, COUNTER_IRQ_TERMINAL_COUNT, true); + } else { + counter_enable_event(dev, COUNTER_IRQ_TERMINAL_COUNT, false); } return 0; @@ -383,8 +398,11 @@ static int ifx_tcpwm_counter_set_alarm(const struct device *dev, uint8_t chan_id data->compare_value = compare_value; /* Reconfigure timer */ +#if defined(CONFIG_SOC_FAMILY_INFINEON_PSOC4) + Cy_TCPWM_Counter_SetCompare0(config->reg_base, config->index, compare_value); +#else Cy_TCPWM_Block_SetCC0Val(config->reg_base, config->index, compare_value); - +#endif counter_enable_event(dev, COUNTER_IRQ_CAPTURE_COMPARE, true); } @@ -397,6 +415,7 @@ static int ifx_tcpwm_counter_cancel_alarm(const struct device *dev, uint8_t chan __ASSERT_NO_MSG(dev != NULL); counter_enable_event(dev, COUNTER_IRQ_CAPTURE_COMPARE, false); + return 0; } @@ -405,8 +424,15 @@ static uint32_t ifx_tcpwm_counter_get_pending_int(const struct device *dev) __ASSERT_NO_MSG(dev != NULL); const struct ifx_tcpwm_counter_config *const config = dev->config; + uint32_t pending = 0U; + + pending = Cy_TCPWM_GetInterruptStatusMasked(config->reg_base, config->index); +#if defined(CONFIG_SOC_FAMILY_INFINEON_PSOC4) + return (pending & CY_TCPWM_INT_ON_CC) ? COUNTER_IRQ_CAPTURE_COMPARE : 0U; +#else return NVIC_GetPendingIRQ(config->irq_num); +#endif } static uint32_t ifx_tcpwm_counter_get_guard_period(const struct device *dev, uint32_t flags) @@ -429,6 +455,7 @@ static int ifx_tcpwm_counter_set_guard_period(const struct device *dev, uint32_t struct ifx_tcpwm_counter_data *const data = dev->data; data->guard_period = guard; + return 0; } @@ -459,23 +486,29 @@ static DEVICE_API(counter, counter_api) = { #if defined(CONFIG_SOC_FAMILY_INFINEON_EDGE) #define COUNTER_PERI_CLOCK_INIT(n) \ - .clock = \ - { \ - .block = IFX_CAT1_PERIPHERAL_GROUP_ADJUST( \ - DT_PROP_BY_IDX(DT_INST_PHANDLE(n, clocks), peri_group, 0), \ - DT_PROP_BY_IDX(DT_INST_PHANDLE(n, clocks), peri_group, 1), \ - DT_INST_PROP_BY_PHANDLE(n, clocks, div_type)), \ - .channel = DT_INST_PROP_BY_PHANDLE(n, clocks, channel), \ - } + .clock = { \ + .block = IFX_CAT1_PERIPHERAL_GROUP_ADJUST( \ + DT_PROP_BY_IDX(DT_INST_PHANDLE(n, clocks), peri_group, 0), \ + DT_PROP_BY_IDX(DT_INST_PHANDLE(n, clocks), peri_group, 1), \ + DT_INST_PROP_BY_PHANDLE(n, clocks, div_type)), \ + .channel = DT_INST_PROP_BY_PHANDLE(n, clocks, channel), \ + } #else #define COUNTER_PERI_CLOCK_INIT(n) \ - .clock = \ - { \ - .block = IFX_CAT1_PERIPHERAL_GROUP_ADJUST( \ - DT_PROP_BY_IDX(DT_INST_PHANDLE(n, clocks), peri_group, 1), \ - DT_INST_PROP_BY_PHANDLE(n, clocks, div_type)), \ - .channel = DT_INST_PROP_BY_PHANDLE(n, clocks, channel), \ - } + .clock = { \ + .block = IFX_CAT1_PERIPHERAL_GROUP_ADJUST( \ + DT_PROP_BY_IDX(DT_INST_PHANDLE(n, clocks), peri_group, 1), \ + DT_INST_PROP_BY_PHANDLE(n, clocks, div_type)), \ + .channel = DT_INST_PROP_BY_PHANDLE(n, clocks, channel), \ + } +#endif + +#if defined(CONFIG_SOC_FAMILY_INFINEON_PSOC4) +#define TCPWM_CNT_IDX(n) .index = DT_NODE_CHILD_IDX(DT_INST_PARENT(n)) +#else +#define TCPWM_CNT_IDX(n) \ + .index = (DT_REG_ADDR(DT_INST_PARENT(n)) - DT_REG_ADDR(DT_PARENT(DT_INST_PARENT(n)))) / \ + DT_REG_SIZE(DT_INST_PARENT(n)) #endif /* Counter driver init macros */ @@ -488,8 +521,8 @@ static DEVICE_API(counter, counter_api) = { irq_enable(DT_IRQN(DT_INST_PARENT(n))); \ } \ \ - static struct ifx_tcpwm_counter_data ifx_tcpwm_counter##n##_data = \ - {COUNTER_PERI_CLOCK_INIT(n)}; \ + static struct ifx_tcpwm_counter_data ifx_tcpwm_counter##n##_data = { \ + COUNTER_PERI_CLOCK_INIT(n)}; \ \ static const struct ifx_tcpwm_counter_config ifx_tcpwm_counter##n##_config = { \ .counter_info = {.max_top_value = (DT_PROP(DT_INST_PARENT(n), resolution) == 32) \ @@ -497,10 +530,8 @@ static DEVICE_API(counter, counter_api) = { : UINT16_MAX, \ .flags = COUNTER_CONFIG_INFO_COUNT_UP, \ .channels = 1}, \ - .reg_base = (TCPWM_Type *)DT_REG_ADDR(DT_PARENT(DT_INST_PARENT(n))), \ - .index = (DT_REG_ADDR(DT_INST_PARENT(n)) - \ - DT_REG_ADDR(DT_PARENT(DT_INST_PARENT(n)))) / \ - DT_REG_SIZE(DT_INST_PARENT(n)), \ + .reg_base = (TCPWM_Type *)(DT_REG_ADDR(DT_PARENT(DT_INST_PARENT(n)))), \ + TCPWM_CNT_IDX(n), \ .irq_num = DT_IRQN(DT_INST_PARENT(n)), \ .resolution_32_bits = \ (DT_PROP(DT_INST_PARENT(n), resolution) == 32) ? true : false, \ From 4c295bf6816b2dc199b2ec7124149faec288cc2f Mon Sep 17 00:00:00 2001 From: Deepika R Date: Tue, 23 Dec 2025 12:47:24 +0530 Subject: [PATCH 2167/3659] samples: drivers: counter: alarm: boards: Add overlay file - Add an overlay to enable TCPWM Counter sample. - Contains configurations for Counter and Clock Signed-off-by: Deepika R Signed-off-by: Sayooj K Karun --- .../alarm/boards/cy8cproto_041tp.overlay | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 samples/drivers/counter/alarm/boards/cy8cproto_041tp.overlay diff --git a/samples/drivers/counter/alarm/boards/cy8cproto_041tp.overlay b/samples/drivers/counter/alarm/boards/cy8cproto_041tp.overlay new file mode 100644 index 000000000000..b9198adda9a2 --- /dev/null +++ b/samples/drivers/counter/alarm/boards/cy8cproto_041tp.overlay @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&tcpwm0_1 { + status = "okay"; + interrupts = <17 0>; + + counter0_1 { + status = "okay"; + clocks = <&peri_clk_div3>; + }; +}; + +&peri_clk_div3 { + resource-channel = <1>; + status = "okay"; +}; From 47ed66bcc22e668e84b373f39c7a0d5661d8368b Mon Sep 17 00:00:00 2001 From: Deepika R Date: Tue, 23 Dec 2025 12:49:01 +0530 Subject: [PATCH 2168/3659] dts: arm: infineon: Change TCPWM Base Register -Change base register for TCPWM to 0x40200000 which controls the entire IP block. - enabling/disabling counters and handling global interrupts. Signed-off-by: Deepika R Signed-off-by: Sayooj K Karun --- dts/arm/infineon/psoc4/psoc4100tp/psoc4100tp.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dts/arm/infineon/psoc4/psoc4100tp/psoc4100tp.dtsi b/dts/arm/infineon/psoc4/psoc4100tp/psoc4100tp.dtsi index 25893b48d590..ba02c71345c0 100644 --- a/dts/arm/infineon/psoc4/psoc4100tp/psoc4100tp.dtsi +++ b/dts/arm/infineon/psoc4/psoc4100tp/psoc4100tp.dtsi @@ -128,8 +128,8 @@ status = "disabled"; }; - tcpwm0: tcpwm0@40200100 { - reg = <0x40200100 0x180>; + tcpwm0: tcpwm0@40200000 { + reg = <0x40200000 0x280>; #address-cells = <1>; #size-cells = <1>; From 2120eb30275c4af768314e743e2091adafd009db Mon Sep 17 00:00:00 2001 From: Mathieu Choplain Date: Mon, 24 Nov 2025 12:53:32 +0100 Subject: [PATCH 2169/3659] drivers: usb: udc: stm32: move power configuration to common code Create infrastructure for shared USB common code on STM32 family, and move the Power Controller configuration logic to common code. This removes some midly unrelated code from the UDC driver while enabling reuse by a future UHC driver implementation for STM32. While at it, clean up the migrated code. Signed-off-by: Mathieu Choplain --- drivers/usb/common/CMakeLists.txt | 1 + drivers/usb/common/Kconfig | 1 + drivers/usb/common/stm32/CMakeLists.txt | 10 ++ drivers/usb/common/stm32/Kconfig | 16 +++ drivers/usb/common/stm32/stm32_usb_common.h | 18 +++ drivers/usb/common/stm32/stm32_usb_pwr.c | 133 ++++++++++++++++++++ drivers/usb/udc/Kconfig.stm32 | 1 + drivers/usb/udc/udc_stm32.c | 98 ++------------- 8 files changed, 188 insertions(+), 90 deletions(-) create mode 100644 drivers/usb/common/stm32/CMakeLists.txt create mode 100644 drivers/usb/common/stm32/Kconfig create mode 100644 drivers/usb/common/stm32/stm32_usb_common.h create mode 100644 drivers/usb/common/stm32/stm32_usb_pwr.c diff --git a/drivers/usb/common/CMakeLists.txt b/drivers/usb/common/CMakeLists.txt index 56e4c734ced9..621e848d6e0c 100644 --- a/drivers/usb/common/CMakeLists.txt +++ b/drivers/usb/common/CMakeLists.txt @@ -1,3 +1,4 @@ # SPDX-License-Identifier: Apache-2.0 add_subdirectory_ifdef(CONFIG_HAS_NRFX nrf_usbd_common) +add_subdirectory_ifdef(CONFIG_SOC_FAMILY_STM32 stm32) diff --git a/drivers/usb/common/Kconfig b/drivers/usb/common/Kconfig index d5a0d4dc1b4a..d80a784c7e48 100644 --- a/drivers/usb/common/Kconfig +++ b/drivers/usb/common/Kconfig @@ -4,5 +4,6 @@ menu "USB common" rsource "nrf_usbd_common/Kconfig" +rsource "stm32/Kconfig" endmenu diff --git a/drivers/usb/common/stm32/CMakeLists.txt b/drivers/usb/common/stm32/CMakeLists.txt new file mode 100644 index 000000000000..5012b9acf8dc --- /dev/null +++ b/drivers/usb/common/stm32/CMakeLists.txt @@ -0,0 +1,10 @@ +# Copyright (c) 2025 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +if(CONFIG_STM32_USB_COMMON) + zephyr_library() + + zephyr_include_directories(.) + + zephyr_library_sources(stm32_usb_pwr.c) +endif() diff --git a/drivers/usb/common/stm32/Kconfig b/drivers/usb/common/stm32/Kconfig new file mode 100644 index 000000000000..9a626faec6e1 --- /dev/null +++ b/drivers/usb/common/stm32/Kconfig @@ -0,0 +1,16 @@ +# Copyright (c) 2025 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +if SOC_FAMILY_STM32 + +config STM32_USB_COMMON + bool + help + Enable compilation of STM32 USB common code. + This option is selected by the USB drivers when appropriate. + +module = STM32_USB_COMMON +module-str = STM32 USB common code +source "subsys/logging/Kconfig.template.log_config" + +endif # SOC_FAMILY_STM32 diff --git a/drivers/usb/common/stm32/stm32_usb_common.h b/drivers/usb/common/stm32/stm32_usb_common.h new file mode 100644 index 000000000000..2c9c63acaa77 --- /dev/null +++ b/drivers/usb/common/stm32/stm32_usb_common.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2025 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_USB_COMMON_STM32_STM32_USB_COMMON_H_ +#define ZEPHYR_DRIVERS_USB_COMMON_STM32_STM32_USB_COMMON_H_ + +/** + * @brief Configures the Power Controller as necessary + * for proper operation of the USB controllers + * + * @returns 0 on success, negative error code otherwise. + */ +int stm32_usb_pwr_enable(void); + +#endif /* ZEPHYR_DRIVERS_USB_COMMON_STM32_STM32_USB_COMMON_H_ */ diff --git a/drivers/usb/common/stm32/stm32_usb_pwr.c b/drivers/usb/common/stm32/stm32_usb_pwr.c new file mode 100644 index 000000000000..6e24e5e47bea --- /dev/null +++ b/drivers/usb/common/stm32/stm32_usb_pwr.c @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2025 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +LOG_MODULE_REGISTER(stm32_usb_pwr, CONFIG_STM32_USB_COMMON_LOG_LEVEL); + +/* + * Keep track of whether power is already + * enabled here to simplify the USB drivers. + */ +static K_SEM_DEFINE(pwr_refcount_mutex, 1, 1); +static uint32_t usb_pwr_refcount; + +int stm32_usb_pwr_enable(void) +{ + uint32_t old_count; + int err; + + err = k_sem_take(&pwr_refcount_mutex, K_FOREVER); + if (err != 0) { + return err; + } + + old_count = usb_pwr_refcount++; + if (old_count > 0) { + /* Already enabled - nothing to do */ + err = 0; + goto fini; + } + +#if defined(CONFIG_SOC_SERIES_STM32H7X) + LL_PWR_EnableUSBVoltageDetector(); + + /* Per AN2606: USBREGEN not supported when running in FS mode. */ + LL_PWR_DisableUSBReg(); + while (!LL_PWR_IsActiveFlag_USB()) { + LOG_INF("PWR not active yet"); + k_msleep(100); + } +#elif defined(CONFIG_SOC_SERIES_STM32U5X) + __ASSERT_NO_MSG(LL_AHB3_GRP1_IsEnabledClock(LL_AHB3_GRP1_PERIPH_PWR)); + + /* Check that power range is 1 or 2 */ + if (LL_PWR_GetRegulVoltageScaling() < LL_PWR_REGU_VOLTAGE_SCALE2) { + LOG_ERR("Wrong Power range to use USB OTG HS"); + err = -EIO; + goto fini; + } + + LL_PWR_EnableVddUSB(); + +# if DT_HAS_COMPAT_STATUS_OKAY(st_stm32_otghs) + /* Enable HS PHY power supply */ + LL_PWR_EnableUSBPowerSupply(); + LL_PWR_EnableUSBEPODBooster(); + while (LL_PWR_IsActiveFlag_USBBOOST() != 1) { + /* Wait for USB EPOD BOOST ready */ + } +# endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32_otghs) */ +#elif defined(CONFIG_SOC_SERIES_STM32N6X) + /* Enable Vdd33USB voltage monitoring */ + LL_PWR_EnableVddUSBMonitoring(); + while (!LL_PWR_IsActiveFlag_USB33RDY()) { + /* Wait for Vdd33USB ready */ + } + + /* Enable VDDUSB */ + LL_PWR_EnableVddUSB(); +#elif defined(CONFIG_SOC_SERIES_STM32WBAX) + /* Remove VDDUSB power isolation */ + LL_PWR_EnableVddUSB(); + + /* Make sure that voltage scaling is Range 1 */ + __ASSERT_NO_MSG(LL_PWR_GetRegulCurrentVOS() == LL_PWR_REGU_VOLTAGE_SCALE1); + + /* Enable VDD11USB */ + LL_PWR_EnableVdd11USB(); + + /* Enable USB OTG internal power */ + LL_PWR_EnableUSBPWR(); + + while (!LL_PWR_IsActiveFlag_VDD11USBRDY()) { + /* Wait for VDD11USB supply to be ready */ + } + + /* Enable USB OTG booster */ + LL_PWR_EnableUSBBooster(); + + while (!LL_PWR_IsActiveFlag_USBBOOSTRDY()) { + /* Wait for USB OTG booster to be ready */ + } +#elif defined(PWR_USBSCR_USB33SV) || defined(PWR_SVMCR_USV) + /* + * VDDUSB independent USB supply (PWR clock is on) + * with LL_PWR_EnableVDDUSB function (higher case) + */ + LL_PWR_EnableVDDUSB(); +#elif defined(PWR_CR2_USV) + /* + * Required for at least STM32L4 devices as they electrically + * isolate USB features from VDDUSB. It must be enabled before + * USB can function. Refer to section 5.1.3 in DM00083560 or + * DM00310109. + */ + LL_PWR_EnableVddUSB(); +#endif + /* Successful control flow in series-specific code above + * will fall here. Set `err` to success value in a single + * place to avoid duplication. + */ + err = 0; + +fini: + if (err != 0) { + /* An error occurred - drop reference before unlocking */ + usb_pwr_refcount--; + } + + k_sem_give(&pwr_refcount_mutex); + + return err; +} diff --git a/drivers/usb/udc/Kconfig.stm32 b/drivers/usb/udc/Kconfig.stm32 index e99839ca92b9..b3648b6cd195 100644 --- a/drivers/usb/udc/Kconfig.stm32 +++ b/drivers/usb/udc/Kconfig.stm32 @@ -10,6 +10,7 @@ config UDC_STM32 select USE_STM32_HAL_PCD select USE_STM32_HAL_PCD_EX select UDC_DRIVER_HAS_HIGH_SPEED_SUPPORT + select STM32_USB_COMMON select PINCTRL default y help diff --git a/drivers/usb/udc/udc_stm32.c b/drivers/usb/udc/udc_stm32.c index 243683258bd5..619833066f6c 100644 --- a/drivers/usb/udc/udc_stm32.c +++ b/drivers/usb/udc/udc_stm32.c @@ -22,6 +22,7 @@ #include #include "udc_common.h" +#include #include LOG_MODULE_REGISTER(udc_stm32, CONFIG_UDC_DRIVER_LOG_LEVEL); @@ -720,6 +721,13 @@ int udc_stm32_init(const struct device *dev) struct udc_stm32_data *priv = udc_get_private(dev); const struct udc_stm32_config *cfg = dev->config; HAL_StatusTypeDef status; + int err; + + err = stm32_usb_pwr_enable(); + if (err != 0) { + LOG_ERR("Error enabling USB power: %d", err); + return err; + } if (udc_stm32_clock_enable(dev) < 0) { LOG_ERR("Error enabling clock(s)"); @@ -1296,76 +1304,6 @@ static int udc_stm32_clock_enable(const struct device *dev) return -ENODEV; } - /* Power configuration */ -#if defined(CONFIG_SOC_SERIES_STM32H7X) - LL_PWR_EnableUSBVoltageDetector(); - - /* Per AN2606: USBREGEN not supported when running in FS mode. */ - LL_PWR_DisableUSBReg(); - while (!LL_PWR_IsActiveFlag_USB()) { - LOG_INF("PWR not active yet"); - k_msleep(100); - } -#elif defined(CONFIG_SOC_SERIES_STM32U5X) - /* Sequence to enable the power of the OTG HS on a stm32U5 serie : Enable VDDUSB */ - __ASSERT_NO_MSG(LL_AHB3_GRP1_IsEnabledClock(LL_AHB3_GRP1_PERIPH_PWR)); - - /* Check that power range is 1 or 2 */ - if (LL_PWR_GetRegulVoltageScaling() < LL_PWR_REGU_VOLTAGE_SCALE2) { - LOG_ERR("Wrong Power range to use USB OTG HS"); - return -EIO; - } - - LL_PWR_EnableVddUSB(); - - #if DT_HAS_COMPAT_STATUS_OKAY(st_stm32_otghs) - /* Configure VOSR register of USB HSTransceiverSupply(); */ - LL_PWR_EnableUSBPowerSupply(); - LL_PWR_EnableUSBEPODBooster(); - while (LL_PWR_IsActiveFlag_USBBOOST() != 1) { - /* Wait for USB EPOD BOOST ready */ - } - #endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32_otghs) */ -#elif defined(CONFIG_SOC_SERIES_STM32N6X) - /* Enable Vdd33USB voltage monitoring */ - LL_PWR_EnableVddUSBMonitoring(); - while (!LL_PWR_IsActiveFlag_USB33RDY()) { - /* Wait for Vdd33USB ready */ - } - - /* Enable VDDUSB */ - LL_PWR_EnableVddUSB(); -#elif defined(CONFIG_SOC_SERIES_STM32WBAX) - /* Remove VDDUSB power isolation */ - LL_PWR_EnableVddUSB(); - - /* Make sure that voltage scaling is Range 1 */ - __ASSERT_NO_MSG(LL_PWR_GetRegulCurrentVOS() == LL_PWR_REGU_VOLTAGE_SCALE1); - - /* Enable VDD11USB */ - LL_PWR_EnableVdd11USB(); - - /* Enable USB OTG internal power */ - LL_PWR_EnableUSBPWR(); - - while (!LL_PWR_IsActiveFlag_VDD11USBRDY()) { - /* Wait for VDD11USB supply to be ready */ - } - - /* Enable USB OTG booster */ - LL_PWR_EnableUSBBooster(); - - while (!LL_PWR_IsActiveFlag_USBBOOSTRDY()) { - /* Wait for USB OTG booster to be ready */ - } -#elif defined(PWR_USBSCR_USB33SV) || defined(PWR_SVMCR_USV) - /* - * VDDUSB independent USB supply (PWR clock is on) - * with LL_PWR_EnableVDDUSB function (higher case) - */ - LL_PWR_EnableVDDUSB(); -#endif - if (cfg->num_clocks > 1) { if (clock_control_configure(clk, &cfg->pclken[1], NULL) != 0) { LOG_ERR("Could not select USB domain clock"); @@ -1618,26 +1556,6 @@ static int udc_stm32_driver_init0(const struct device *dev) } } - /*cd - * Required for at least STM32L4 devices as they electrically - * isolate USB features from VDDUSB. It must be enabled before - * USB can function. Refer to section 5.1.3 in DM00083560 or - * DM00310109. - */ -#ifdef PWR_CR2_USV -#if defined(LL_APB1_GRP1_PERIPH_PWR) - if (LL_APB1_GRP1_IsEnabledClock(LL_APB1_GRP1_PERIPH_PWR)) { - LL_PWR_EnableVddUSB(); - } else { - LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_PWR); - LL_PWR_EnableVddUSB(); - LL_APB1_GRP1_DisableClock(LL_APB1_GRP1_PERIPH_PWR); - } - #else - LL_PWR_EnableVddUSB(); -#endif /* defined(LL_APB1_GRP1_PERIPH_PWR) */ -#endif /* PWR_CR2_USV */ - return 0; } From dac9d3e1c304a2cfde096b7a4d8158a080463026 Mon Sep 17 00:00:00 2001 From: Mathieu Choplain Date: Thu, 11 Dec 2025 15:22:44 +0100 Subject: [PATCH 2170/3659] drivers: usb: common: stm32: pwr: add power disable support Add code to disable the USB power supply. Signed-off-by: Mathieu Choplain --- drivers/usb/common/stm32/stm32_usb_common.h | 9 +++ drivers/usb/common/stm32/stm32_usb_pwr.c | 70 +++++++++++++++++++++ drivers/usb/udc/udc_stm32.c | 7 +++ 3 files changed, 86 insertions(+) diff --git a/drivers/usb/common/stm32/stm32_usb_common.h b/drivers/usb/common/stm32/stm32_usb_common.h index 2c9c63acaa77..38312687a93b 100644 --- a/drivers/usb/common/stm32/stm32_usb_common.h +++ b/drivers/usb/common/stm32/stm32_usb_common.h @@ -15,4 +15,13 @@ */ int stm32_usb_pwr_enable(void); +/** + * @brief Configures the Power Controller to disable + * USB-related regulators/etc if no controller is + * still active (refcounted). + * + * @returns 0 on success, negative error code otherwise. + */ +int stm32_usb_pwr_disable(void); + #endif /* ZEPHYR_DRIVERS_USB_COMMON_STM32_STM32_USB_COMMON_H_ */ diff --git a/drivers/usb/common/stm32/stm32_usb_pwr.c b/drivers/usb/common/stm32/stm32_usb_pwr.c index 6e24e5e47bea..c11f271c2775 100644 --- a/drivers/usb/common/stm32/stm32_usb_pwr.c +++ b/drivers/usb/common/stm32/stm32_usb_pwr.c @@ -131,3 +131,73 @@ int stm32_usb_pwr_enable(void) return err; } + +int stm32_usb_pwr_disable(void) +{ + uint32_t new_count; + int err; + + err = k_sem_take(&pwr_refcount_mutex, K_FOREVER); + if (err != 0) { + return err; + } + + new_count = --usb_pwr_refcount; + if (new_count > 0) { + /* There are other users - don't disable now */ + err = 0; + goto fini; + } + +#if defined(CONFIG_SOC_SERIES_STM32H7X) + LL_PWR_DisableUSBVoltageDetector(); +#elif defined(CONFIG_SOC_SERIES_STM32U5X) +# if DT_HAS_COMPAT_STATUS_OKAY(st_stm32_otghs) + LL_PWR_DisableUSBEPODBooster(); + while (LL_PWR_IsActiveFlag_USBBOOST() != 0) { + /* Wait for USB EPOD BOOST off */ + } + + LL_PWR_DisableUSBPowerSupply(); +# endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32_otghs) */ + + LL_PWR_DisableVddUSB(); +#elif defined(CONFIG_SOC_SERIES_STM32N6X) + /* Disable Vdd33USB voltage monitoring */ + LL_PWR_DisableVddUSBMonitoring(); + + /* Disable VDDUSB */ + LL_PWR_DisableVddUSB(); +#elif defined(CONFIG_SOC_SERIES_STM32WBAX) + /* Disable USB OTG booster */ + LL_PWR_DisableUSBBooster(); + + while (LL_PWR_IsActiveFlag_USBBOOSTRDY()) { + /* Wait until USB OTG booster is off */ + } + + /* Disable USB OTG internal power */ + LL_PWR_DisableUSBPWR(); + + /* Disable VDD11USB */ + LL_PWR_DisableVdd11USB(); + + while (LL_PWR_IsActiveFlag_VDD11USBRDY()) { + /* Wait until VDD11USB supply is off */ + } + + /* Enable VDDUSB power isolation */ + LL_PWR_DisableVddUSB(); +#elif defined(PWR_USBSCR_USB33SV) || defined(PWR_SVMCR_USV) + /* Enable VDDUSB power isolation */ + LL_PWR_DisableVDDUSB(); +#elif defined(PWR_CR2_USV) + /* Enable VDDUSB power isolation */ + LL_PWR_DisableVddUSB(); +#endif + +fini: + k_sem_give(&pwr_refcount_mutex); + + return err; +} diff --git a/drivers/usb/udc/udc_stm32.c b/drivers/usb/udc/udc_stm32.c index 619833066f6c..614178a53f1c 100644 --- a/drivers/usb/udc/udc_stm32.c +++ b/drivers/usb/udc/udc_stm32.c @@ -954,6 +954,7 @@ static int udc_stm32_shutdown(const struct device *dev) struct udc_stm32_data *priv = udc_get_private(dev); const struct udc_stm32_config *cfg = dev->config; HAL_StatusTypeDef status; + int err; status = HAL_PCD_DeInit(&priv->pcd); if (status != HAL_OK) { @@ -966,6 +967,12 @@ static int udc_stm32_shutdown(const struct device *dev) /* continue anyway */ } + err = stm32_usb_pwr_disable(); + if (err != 0) { + LOG_ERR("Error disabling USB power: %d", err); + /* continue anyway */ + } + if (irq_is_enabled(cfg->irqn)) { irq_disable(cfg->irqn); } From 4d5f4888b4f4cdc8d7bcc04bf78672890a667754 Mon Sep 17 00:00:00 2001 From: Khoa Nguyen Date: Mon, 29 Sep 2025 09:00:54 +0000 Subject: [PATCH 2171/3659] soc: renesas: ra: Add invisible RENESAS_PN config Add invisible RENESAS_PN config to reflect the SoC hardware information and provide input for hal_renesas Signed-off-by: Khoa Nguyen --- soc/renesas/ra/ra2a1/Kconfig | 16 ++++++++++++++++ soc/renesas/ra/ra2l1/Kconfig | 20 +++++++++++++++++++ soc/renesas/ra/ra4c1/Kconfig | 13 +++++++++++++ soc/renesas/ra/ra4e1/Kconfig | 14 ++++++++++++++ soc/renesas/ra/ra4e2/Kconfig | 16 ++++++++++++++++ soc/renesas/ra/ra4l1/Kconfig | 18 ++++++++++++++++++ soc/renesas/ra/ra4m1/Kconfig | 16 ++++++++++++++++ soc/renesas/ra/ra4m2/Kconfig | 15 +++++++++++++++ soc/renesas/ra/ra4m3/Kconfig | 16 ++++++++++++++++ soc/renesas/ra/ra4t1/Kconfig | 20 +++++++++++++++++++ soc/renesas/ra/ra6e1/Kconfig | 14 ++++++++++++++ soc/renesas/ra/ra6e2/Kconfig | 16 ++++++++++++++++ soc/renesas/ra/ra6m1/Kconfig | 15 +++++++++++++++ soc/renesas/ra/ra6m2/Kconfig | 14 ++++++++++++++ soc/renesas/ra/ra6m3/Kconfig | 16 ++++++++++++++++ soc/renesas/ra/ra6m4/Kconfig | 16 ++++++++++++++++ soc/renesas/ra/ra6m5/Kconfig | 24 +++++++++++++++++++++++ soc/renesas/ra/ra8d1/Kconfig | 21 ++++++++++++++++++++ soc/renesas/ra/ra8d2/Kconfig | 35 ++++++++++++++++++++++++++++++++++ soc/renesas/ra/ra8m1/Kconfig | 15 +++++++++++++++ soc/renesas/ra/ra8m2/Kconfig | 36 +++++++++++++++++++++++++++++++++++ soc/renesas/ra/ra8p1/Kconfig | 37 ++++++++++++++++++++++++++++++++++++ soc/renesas/ra/ra8t1/Kconfig | 15 +++++++++++++++ soc/renesas/ra/ra8t2/Kconfig | 37 ++++++++++++++++++++++++++++++++++++ 24 files changed, 475 insertions(+) diff --git a/soc/renesas/ra/ra2a1/Kconfig b/soc/renesas/ra/ra2a1/Kconfig index a9915c0f4adc..e42ae36eac1c 100644 --- a/soc/renesas/ra/ra2a1/Kconfig +++ b/soc/renesas/ra/ra2a1/Kconfig @@ -11,3 +11,19 @@ config SOC_SERIES_RA2A1 select XIP select HAS_RENESAS_RA_FSP select SOC_EARLY_INIT_HOOK + +if SOC_SERIES_RA2A1 + +config RENESAS_PN_PACKAGE_TYPE + int + range 1 5 + default 1 if SOC_R7FA2A1AB3CFM + help + Package type: + 1 -> FM: LQFP 64 pins + 2 -> FJ: LQFP 32 pins + 3 -> BT: BGA 36 pins + 4 -> NE: QFN 48 pins + 5 -> NF: QFN 40 pins + +endif # SOC_SERIES_RA2A1 diff --git a/soc/renesas/ra/ra2l1/Kconfig b/soc/renesas/ra/ra2l1/Kconfig index e3a0ab7ceabe..6d781dc1f8f0 100644 --- a/soc/renesas/ra/ra2l1/Kconfig +++ b/soc/renesas/ra/ra2l1/Kconfig @@ -12,3 +12,23 @@ config SOC_SERIES_RA2L1 select CLOCK_CONTROL_RENESAS_RA_CGC if CLOCK_CONTROL select HAS_SWO select SOC_EARLY_INIT_HOOK + +if SOC_SERIES_RA2L1 + +config RENESAS_PN_PACKAGE_TYPE + int + range 1 5 + default 1 if SOC_R7FA2L1ABXXFP || SOC_R7FA2L1A9XXFP + default 2 if SOC_R7FA2L1ABXXFN || SOC_R7FA2L1A9XXFN + default 3 if SOC_R7FA2L1ABXXFM || SOC_R7FA2L1A9XXFM + default 4 if SOC_R7FA2L1ABXXFL || SOC_R7FA2L1A9XXFL + default 5 if SOC_R7FA2L1ABXXNE || SOC_R7FA2L1A9XXNE + help + Package type: + 1 -> FP: LQFP 100 pins + 2 -> FN: LQFP 80 pins + 3 -> FM: LQFP 64 pins + 4 -> FL: LQFP 48 pins + 5 -> NE: HWQFN 48 pins + +endif # SOC_SERIES_RA2L1 diff --git a/soc/renesas/ra/ra4c1/Kconfig b/soc/renesas/ra/ra4c1/Kconfig index 6daafe2eabb2..38075b3dd06a 100644 --- a/soc/renesas/ra/ra4c1/Kconfig +++ b/soc/renesas/ra/ra4c1/Kconfig @@ -14,3 +14,16 @@ config SOC_SERIES_RA4C1 select HAS_SWO select XIP select SOC_EARLY_INIT_HOOK + +if SOC_SERIES_RA4C1 + +config RENESAS_PN_PACKAGE_TYPE + int + range 1 2 + default 2 if SOC_R7FA4C1BD3CFP + help + Package type: + 1 -> FM: LQFP 64 pins + 2 -> FP: LQFP 100 pins + +endif # SOC_SERIES_RA4C1 diff --git a/soc/renesas/ra/ra4e1/Kconfig b/soc/renesas/ra/ra4e1/Kconfig index dd5a14ef2bf4..b48567294a7e 100644 --- a/soc/renesas/ra/ra4e1/Kconfig +++ b/soc/renesas/ra/ra4e1/Kconfig @@ -15,3 +15,17 @@ config SOC_SERIES_RA4E1 select XIP select SOC_EARLY_INIT_HOOK select GPIO_RA_HAS_VBTICTLR + +if SOC_SERIES_RA4E1 + +config RENESAS_PN_PACKAGE_TYPE + int + range 1 2 + default 1 if SOC_R7FA4E10D2CFM + default 2 if SOC_R7FA4E10D2CNE + help + Package type: + 1 -> FM: LQFP 64 pins + 2 -> NE: QFN 48 pins + +endif # SOC_SERIES_RA4E1 diff --git a/soc/renesas/ra/ra4e2/Kconfig b/soc/renesas/ra/ra4e2/Kconfig index bfe486040c48..701c68a76631 100644 --- a/soc/renesas/ra/ra4e2/Kconfig +++ b/soc/renesas/ra/ra4e2/Kconfig @@ -14,3 +14,19 @@ config SOC_SERIES_RA4E2 select HAS_SWO select XIP select SOC_EARLY_INIT_HOOK + +if SOC_SERIES_RA4E2 + +config RENESAS_PN_PACKAGE_TYPE + int + range 1 5 + default 1 if SOC_R7FA4E2B93CFM + help + Package type: + 1 -> FM: LQFP 64 pins + 2 -> NE: QFN 48 pins + 3 -> NH: QFN 32 pins + 4 -> BB: BGA 64 pins + 5 -> BC: BGA 36 pins + +endif # SOC_SERIES_RA4E2 diff --git a/soc/renesas/ra/ra4l1/Kconfig b/soc/renesas/ra/ra4l1/Kconfig index 314e037d34e7..525f45693bbb 100644 --- a/soc/renesas/ra/ra4l1/Kconfig +++ b/soc/renesas/ra/ra4l1/Kconfig @@ -14,3 +14,21 @@ config SOC_SERIES_RA4L1 select CLOCK_CONTROL_RENESAS_RA_CGC if CLOCK_CONTROL select XIP select SOC_EARLY_INIT_HOOK + +if SOC_SERIES_RA4L1 + +config RENESAS_PN_PACKAGE_TYPE + int + range 1 7 + default 3 if SOC_R7FA4L1BD4CFP + help + Package type: + 1 -> FL: LQFP 48 pins + 2 -> FM: LQFP 64 pins + 3 -> FP: LQFP 100 pins + 4 -> NE: QFN 48 Pins + 5 -> AH: BGA 64 pins + 6 -> AG: BGA 100 pins + 7 -> DB: WLCSP 72 pins + +endif # SOC_SERIES_RA4L1 diff --git a/soc/renesas/ra/ra4m1/Kconfig b/soc/renesas/ra/ra4m1/Kconfig index f75e56ae2063..b5fa5e108bc6 100644 --- a/soc/renesas/ra/ra4m1/Kconfig +++ b/soc/renesas/ra/ra4m1/Kconfig @@ -21,4 +21,20 @@ config SOC_OPTION_SETTING_MEMORY bool "Option Setting Memory" default y +config RENESAS_PN_PACKAGE_TYPE + int + range 1 7 + default 1 if SOC_R7FA4M1AB3CFP + default 2 if SOC_R7FA4M1AB3CFM + default 6 if SOC_R7FA4M1AB3CNE + help + Package type: + 1 -> FP: LQFP 100 pins + 2 -> FM: LQFP 64 pins + 3 -> FL: LQFP 48 pins + 4 -> LJ: LGA 100 pins + 5 -> NB: QFN 64 pins + 6 -> NE: QFN 48 pins + 7 -> NF: QFN 40 pins + endif diff --git a/soc/renesas/ra/ra4m2/Kconfig b/soc/renesas/ra/ra4m2/Kconfig index 5058fde96165..0412eaaa63b7 100644 --- a/soc/renesas/ra/ra4m2/Kconfig +++ b/soc/renesas/ra/ra4m2/Kconfig @@ -15,3 +15,18 @@ config SOC_SERIES_RA4M2 select XIP select SOC_EARLY_INIT_HOOK select GPIO_RA_HAS_VBTICTLR + +if SOC_SERIES_RA4M2 + +config RENESAS_PN_PACKAGE_TYPE + int + range 1 4 + default 3 if SOC_R7FA4M2AD3CFP + help + Package type: + 1 -> FL: LQFP 48 pins + 2 -> FM: LQFP 64 pins + 3 -> FP: LQFP 100 pins + 4 -> NE: QFN 48 pins + +endif # SOC_SERIES_RA4M2 diff --git a/soc/renesas/ra/ra4m3/Kconfig b/soc/renesas/ra/ra4m3/Kconfig index dfa371906865..379253245469 100644 --- a/soc/renesas/ra/ra4m3/Kconfig +++ b/soc/renesas/ra/ra4m3/Kconfig @@ -15,3 +15,19 @@ config SOC_SERIES_RA4M3 select XIP select SOC_EARLY_INIT_HOOK select GPIO_RA_HAS_VBTICTLR + +if SOC_SERIES_RA4M3 + +config RENESAS_PN_PACKAGE_TYPE + int + range 1 5 + default 3 if SOC_R7FA4M3AF3CFB + help + Package type: + 1 -> BM: FBGA 144 pins + 2 -> BQ: FBGA 64 pins + 3 -> FB: LQFP 144 pins + 4 -> FM: LQFP 64 pins + 5 -> FP: LQFP 100 pins + +endif # SOC_SERIES_RA4M3 diff --git a/soc/renesas/ra/ra4t1/Kconfig b/soc/renesas/ra/ra4t1/Kconfig index c3e3cd22738e..5b2a50a95760 100644 --- a/soc/renesas/ra/ra4t1/Kconfig +++ b/soc/renesas/ra/ra4t1/Kconfig @@ -13,3 +13,23 @@ config SOC_SERIES_RA4T1 select FPU select XIP select SOC_EARLY_INIT_HOOK + +if SOC_SERIES_RA4T1 + +config RENESAS_PN_PACKAGE_TYPE + int + range 1 5 + default 1 if SOC_R7FA4T1BB3CFM || SOC_R7FA4T1B93CFM + default 2 if SOC_R7FA4T1BB3CFL || SOC_R7FA4T1B93CFL + default 3 if SOC_R7FA4T1BB3CFJ || SOC_R7FA4T1B93CFJ + default 4 if SOC_R7FA4T1BB3CNE || SOC_R7FA4T1B93CNE + default 5 if SOC_R7FA4T1BB3CNH || SOC_R7FA4T1B93CNH + help + Package type: + 1 -> FM: LQFP 64 pins + 2 -> FL: LQFP 48 pins + 3 -> FJ: LQFP 32 pins + 4 -> NE: QFN 48 pins + 5 -> NH: QFN 32 pins + +endif # SOC_SERIES_RA4T1 diff --git a/soc/renesas/ra/ra6e1/Kconfig b/soc/renesas/ra/ra6e1/Kconfig index 097baa624148..b93d85a76ffd 100644 --- a/soc/renesas/ra/ra6e1/Kconfig +++ b/soc/renesas/ra/ra6e1/Kconfig @@ -15,3 +15,17 @@ config SOC_SERIES_RA6E1 select XIP select SOC_EARLY_INIT_HOOK select GPIO_RA_HAS_VBTICTLR + +if SOC_SERIES_RA6E1 + +config RENESAS_PN_PACKAGE_TYPE + int + range 1 3 + default 1 if SOC_R7FA6E10F2CFP + help + Package type: + 1 -> FP: LQFP 100 pins + 2 -> FM: LQFP 64 pins + 3 -> NE: QFN 48pins + +endif # SOC_SERIES_RA6E1 diff --git a/soc/renesas/ra/ra6e2/Kconfig b/soc/renesas/ra/ra6e2/Kconfig index f7081a1c9587..841bafe2fcd9 100644 --- a/soc/renesas/ra/ra6e2/Kconfig +++ b/soc/renesas/ra/ra6e2/Kconfig @@ -14,3 +14,19 @@ config SOC_SERIES_RA6E2 select HAS_SWO select XIP select SOC_EARLY_INIT_HOOK + +if SOC_SERIES_RA6E2 + +config RENESAS_PN_PACKAGE_TYPE + int + range 1 5 + default 1 if SOC_R7FA6E2BB3CFM + help + Package type: + 1 -> FM: LQFP 64 pins + 2 -> NE: QFN 48 pins + 3 -> NH: QFN 32 pins + 4 -> BB: BGA 64 pins + 5 -> BC: BGA 36 pins + +endif # SOC_SERIES_RA6E2 diff --git a/soc/renesas/ra/ra6m1/Kconfig b/soc/renesas/ra/ra6m1/Kconfig index ffe573117178..d637b0aaf1ca 100644 --- a/soc/renesas/ra/ra6m1/Kconfig +++ b/soc/renesas/ra/ra6m1/Kconfig @@ -14,3 +14,18 @@ config SOC_SERIES_RA6M1 select XIP select SOC_EARLY_INIT_HOOK select GPIO_RA_HAS_VBTICTLR + +if SOC_SERIES_RA6M1 + +config RENESAS_PN_PACKAGE_TYPE + int + range 1 4 + default 1 if SOC_R7FA6M1AD3CFP + help + Package type: + 1 -> FP: LQFP 100 pins + 2 -> FM: LQFP 64 pins + 3 -> LJ: LGA 100 pins + 4 -> NB: QFN 64 pins + +endif # SOC_SERIES_RA6M1 diff --git a/soc/renesas/ra/ra6m2/Kconfig b/soc/renesas/ra/ra6m2/Kconfig index 09c6427a52ea..3946ee6bdd99 100644 --- a/soc/renesas/ra/ra6m2/Kconfig +++ b/soc/renesas/ra/ra6m2/Kconfig @@ -14,3 +14,17 @@ config SOC_SERIES_RA6M2 select XIP select SOC_EARLY_INIT_HOOK select GPIO_RA_HAS_VBTICTLR + +if SOC_SERIES_RA6M2 + +config RENESAS_PN_PACKAGE_TYPE + int + range 1 3 + default 1 if SOC_R7FA6M2AF3CFB + help + Package type: + 1 -> FB: LQFP 144 pins + 2 -> FP: LQFP 100 pins + 3 -> LK: LGA 145 pins + +endif # SOC_SERIES_RA6M2 diff --git a/soc/renesas/ra/ra6m3/Kconfig b/soc/renesas/ra/ra6m3/Kconfig index 3dea36935aea..21fe71c4a48a 100644 --- a/soc/renesas/ra/ra6m3/Kconfig +++ b/soc/renesas/ra/ra6m3/Kconfig @@ -14,3 +14,19 @@ config SOC_SERIES_RA6M3 select XIP select SOC_EARLY_INIT_HOOK select GPIO_RA_HAS_VBTICTLR + +if SOC_SERIES_RA6M3 + +config RENESAS_PN_PACKAGE_TYPE + int + range 1 5 + default 2 if SOC_R7FA6M3AH3CFC + help + Package type: + 1 -> BG: BGA 176 pins + 2 -> FC: LQFP 176 pins + 3 -> FB: LQFP 144 pins + 4 -> FP: LQFP 100 pins + 5 -> LK: LGA 145 pins + +endif # SOC_SERIES_RA6M3 diff --git a/soc/renesas/ra/ra6m4/Kconfig b/soc/renesas/ra/ra6m4/Kconfig index 89e6dfb30066..50af68b81788 100644 --- a/soc/renesas/ra/ra6m4/Kconfig +++ b/soc/renesas/ra/ra6m4/Kconfig @@ -17,3 +17,19 @@ config SOC_SERIES_RA6M4 select SOC_EARLY_INIT_HOOK select GPIO_RA_HAS_VBTICTLR select OUTPUT_RPD if ETH_RENESAS_RA + +if SOC_SERIES_RA6M4 + +config RENESAS_PN_PACKAGE_TYPE + int + range 1 5 + default 3 if SOC_R7FA6M4AF3CFB + help + Package type: + 1 -> BM: FBGA 144 pins + 2 -> BQ: FBGA 64 pins + 3 -> FB: LQFP 144 pins + 4 -> FM: LQFP 64 pins + 5 -> FP: LQFP 100 pins + +endif # SOC_SERIES_RA6M4 diff --git a/soc/renesas/ra/ra6m5/Kconfig b/soc/renesas/ra/ra6m5/Kconfig index ef8a38394890..c7d645907272 100644 --- a/soc/renesas/ra/ra6m5/Kconfig +++ b/soc/renesas/ra/ra6m5/Kconfig @@ -17,3 +17,27 @@ config SOC_SERIES_RA6M5 select SOC_EARLY_INIT_HOOK select GPIO_RA_HAS_VBTICTLR select OUTPUT_RPD if ETH_RENESAS_RA + +if SOC_SERIES_RA6M5 + +config RENESAS_PN_PACKAGE_TYPE + int + range 1 5 + default 4 if SOC_R7FA6M5BH3CFC + help + Package type: + 1 -> BG: FBGA 176 pins + 2 -> BM: FBGA 144 pins + 3 -> FB: LQFP 144 pins + 4 -> FC: LQFP 176 pins + 5 -> FP: LQFP 100 pins + +config RENESAS_PN_FEATURE_SET + hex + default 0x42 if SOC_R7FA6M5BH3CFC + help + Feature set (Convert the feature set character into its ASCII hex value): + - A (0x41): Supporting only Classical CAN (Not supporting Flexible Data rate) + - B (0x42): Supporting Classical CAN with Flexible Data rate + +endif # SOC_SERIES_RA6M5 diff --git a/soc/renesas/ra/ra8d1/Kconfig b/soc/renesas/ra/ra8d1/Kconfig index b229ca381689..bf456b39ff11 100644 --- a/soc/renesas/ra/ra8d1/Kconfig +++ b/soc/renesas/ra/ra8d1/Kconfig @@ -16,3 +16,24 @@ config SOC_SERIES_RA8D1 select SOC_EARLY_INIT_HOOK select GPIO_RA_HAS_VBTICTLR select HAS_PM + +if SOC_SERIES_RA8D1 + +config RENESAS_PN_PACKAGE_TYPE + int + range 1 2 + default 1 if SOC_R7FA8D1BHECBD + help + Package type: + 1 -> BD: FBGA 224 pins + 2 -> FC: LQFP 176 pins + +config RENESAS_PN_FEATURE_SET + hex + default 0x42 if SOC_R7FA8D1BHECBD + help + Feature set (Convert the feature set character into its ASCII hex value): + - A (0x41): MIPI DSI is not available + - B (0x42): MIPI DSI is available + +endif # SOC_SERIES_RA8D1 diff --git a/soc/renesas/ra/ra8d2/Kconfig b/soc/renesas/ra/ra8d2/Kconfig index 9591ad7e5e94..581d925133d8 100644 --- a/soc/renesas/ra/ra8d2/Kconfig +++ b/soc/renesas/ra/ra8d2/Kconfig @@ -23,3 +23,38 @@ config SOC_R7KA8D2KFLCAC_CM85 config SOC_R7KA8D2KFLCAC_CM33 select CPU_CORTEX_M33 select SOC_RA_SECOND_CORE_BUILD + +if SOC_SERIES_RA8D2 + +config RENESAS_PN_ROM_SIZE + hex + default 0x100000 if SOC_R7KA8D2KFLCAC + help + Code MRAM and Flash size + +config RENESAS_PN_PACKAGE_TYPE + int + range 1 3 + default 2 if SOC_R7KA8D2KFLCAC + help + Package type: + 1 -> AB: LFBGA 224 pins + 2 -> AC: LFBGA 289 pins + 3 -> AJ: LFBGA 303 pins + +config RENESAS_PN_FEATURE_SET + hex + default 0x4a if SOC_R7KA8D2KFLCAC + help + Feature set (Convert the feature set character into its ASCII hex value): + - A (0x41): Single Core (CM85 only) + - J (0x4a): Dual Core + +config RENESAS_PN_NUMBER_OF_CORES + int + range 1 2 + default 2 if SOC_R7KA8D2KFLCAC + help + Number of SoC cores + +endif # SOC_SERIES_RA8D2 diff --git a/soc/renesas/ra/ra8m1/Kconfig b/soc/renesas/ra/ra8m1/Kconfig index e7ee49781390..2b6813522a9d 100644 --- a/soc/renesas/ra/ra8m1/Kconfig +++ b/soc/renesas/ra/ra8m1/Kconfig @@ -18,3 +18,18 @@ config SOC_SERIES_RA8M1 select HAS_PM help Enable support for Renesas RA8M1 MCU series + +if SOC_SERIES_RA8M1 + +config RENESAS_PN_PACKAGE_TYPE + int + range 1 4 + default 1 if SOC_R7FA8M1AHECBD + help + Package type: + 1 -> BD: FBGA 224 pins + 2 -> FC: LQFP 176 pins + 3 -> FB: LQFP 144 pins + 4 -> FP: LQFP 100 pins + +endif # SOC_SERIES_RA8M1 diff --git a/soc/renesas/ra/ra8m2/Kconfig b/soc/renesas/ra/ra8m2/Kconfig index 3c5c5dd352a2..8a22472a6755 100644 --- a/soc/renesas/ra/ra8m2/Kconfig +++ b/soc/renesas/ra/ra8m2/Kconfig @@ -23,3 +23,39 @@ config SOC_R7KA8M2JFLCAC_CM85 config SOC_R7KA8M2JFLCAC_CM33 select CPU_CORTEX_M33 select SOC_RA_SECOND_CORE_BUILD + +if SOC_SERIES_RA8M2 + +config RENESAS_PN_ROM_SIZE + hex + default 0x100000 if SOC_R7KA8M2JFLCAC + help + Code MRAM and Flash size + +config RENESAS_PN_PACKAGE_TYPE + int + range 1 4 + default 2 if SOC_R7KA8M2JFLCAC + help + Package type: + 1 -> AB: LFBGA 224 pins + 2 -> AC: LFBGA 289 pins + 3 -> AJ: LFBGA 303 pins + 4 -> HC: HLQFP 176 pins + +config RENESAS_PN_FEATURE_SET + hex + default 0x4a if SOC_R7KA8M2JFLCAC + help + Feature set (Convert the feature set character into its ASCII hex value): + - A (0x41): Single Core (CM85 only) + - J (0x4a): Dual Core + +config RENESAS_PN_NUMBER_OF_CORES + int + range 1 2 + default 2 if SOC_R7KA8M2JFLCAC + help + Number of SoC cores + +endif # SOC_SERIES_RA8M2 diff --git a/soc/renesas/ra/ra8p1/Kconfig b/soc/renesas/ra/ra8p1/Kconfig index 55fa436e10cd..9ecd8df9ab95 100644 --- a/soc/renesas/ra/ra8p1/Kconfig +++ b/soc/renesas/ra/ra8p1/Kconfig @@ -24,3 +24,40 @@ config SOC_R7KA8P1KFLCAC_CM85 config SOC_R7KA8P1KFLCAC_CM33 select CPU_CORTEX_M33 select SOC_RA_SECOND_CORE_BUILD + +if SOC_SERIES_RA8P1 + +config RENESAS_PN_ROM_SIZE + hex + default 0x100000 if SOC_R7KA8P1KFLCAC + help + Code MRAM and Flash size + +config RENESAS_PN_PACKAGE_TYPE + int + range 1 3 + default 2 if SOC_R7KA8P1KFLCAC + help + Package type: + 1 -> AB: LFBGA 224 pins + 2 -> AC: LFBGA 289 pins + 3 -> AJ: LFBGA 303 pins + +config RENESAS_PN_FEATURE_SET + hex + default 0x4b if SOC_R7KA8P1KFLCAC + help + Feature set (Convert the feature set character into its ASCII hex value): + - A (0x41): Single Core (CM85 only), MIPI DSI/CSI is not available + - B (0x42): Single Core (CM85 only), MIPI DSI/CSI is available + - J (0x4a): Dual Core, MIPI DSI/CSI is not available + - K (0x4b): Dual Core, MIPI DSI/CSI is available + +config RENESAS_PN_NUMBER_OF_CORES + int + range 1 2 + default 2 if SOC_R7KA8P1KFLCAC + help + Number of SoC cores + +endif # SOC_SERIES_RA8P1 diff --git a/soc/renesas/ra/ra8t1/Kconfig b/soc/renesas/ra/ra8t1/Kconfig index 17afc4ced608..ba1825598171 100644 --- a/soc/renesas/ra/ra8t1/Kconfig +++ b/soc/renesas/ra/ra8t1/Kconfig @@ -16,3 +16,18 @@ config SOC_SERIES_RA8T1 select SOC_EARLY_INIT_HOOK select GPIO_RA_HAS_VBTICTLR select HAS_PM + +if SOC_SERIES_RA8T1 + +config RENESAS_PN_PACKAGE_TYPE + int + range 1 4 + default 1 if SOC_R7FA8T1AHECBD + help + Package type: + 1 -> BD: FBGA 224 pins + 2 -> FC: LQFP 176 pins + 3 -> FB: LQFP 144 pins + 4 -> FP: LQFP 100 pins + +endif # SOC_SERIES_RA8T1 diff --git a/soc/renesas/ra/ra8t2/Kconfig b/soc/renesas/ra/ra8t2/Kconfig index 5bd1bf97bbe0..c41407520a1d 100644 --- a/soc/renesas/ra/ra8t2/Kconfig +++ b/soc/renesas/ra/ra8t2/Kconfig @@ -23,3 +23,40 @@ config SOC_R7KA8T2LFECAC_CM85 config SOC_R7KA8T2LFECAC_CM33 select CPU_CORTEX_M33 select SOC_RA_SECOND_CORE_BUILD + +if SOC_SERIES_RA8T2 + +config RENESAS_PN_ROM_SIZE + hex + default 0x100000 if SOC_R7KA8T2LFECAC + help + Code MRAM and Flash size + +config RENESAS_PN_PACKAGE_TYPE + int + range 1 4 + default 2 if SOC_R7KA8T2LFECAC + help + Package type: + 1 -> AB: LFBGA 224 pins + 2 -> AC: LFBGA 289 pins + 3 -> AJ: LFBGA 303 pins + 4 -> HC: HLQFP 176 pins + +config RENESAS_PN_FEATURE_SET + hex + default 0x4c if SOC_R7KA8T2LFECAC + help + Feature set (Convert the feature set character into its ASCII hex value): + - A (0x41): Single Core (CM85 only), EtherCAT slave controller is not available + - C (0x43): Single Core (CM85 only), EtherCAT slave controller is available + - L (0x4c): Dual Core, EtherCAT slave controller is available + +config RENESAS_PN_NUMBER_OF_CORES + int + range 1 2 + default 2 if SOC_R7KA8T2LFECAC + help + Number of SoC cores + +endif # SOC_SERIES_RA8T2 From 04a334360cb64c11a3544421079102d72a8cd8a0 Mon Sep 17 00:00:00 2001 From: Khoa Nguyen Date: Fri, 16 Jan 2026 11:03:37 +0000 Subject: [PATCH 2172/3659] soc: renesas: ra: Update condition for SOC_RA_ENABLE_START_SECOND_CORE Update condition to use config RENESAS_PN_NUMBER_OF_CORES for SOC_RA_ENABLE_START_SECOND_CORE Signed-off-by: Khoa Nguyen --- soc/renesas/ra/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/soc/renesas/ra/Kconfig b/soc/renesas/ra/Kconfig index e6df4f733b92..ef0822de420a 100644 --- a/soc/renesas/ra/Kconfig +++ b/soc/renesas/ra/Kconfig @@ -26,7 +26,7 @@ rsource "*/Kconfig" config SOC_RA_ENABLE_START_SECOND_CORE bool "Allows the primary core to start the secondary core" - depends on (SOC_SERIES_RA8P1 && CPU_CORTEX_M85) + depends on ((RENESAS_PN_NUMBER_OF_CORES = 2) && CPU_CORTEX_M85) select SOC_LATE_INIT_HOOK help Indicates the second core will be start in the soc_late_init_hook when enabled From 7b81e406d64a8e02df8d811fb2436b81b19f2ca0 Mon Sep 17 00:00:00 2001 From: Ren Chen Date: Tue, 30 Dec 2025 10:24:42 +0800 Subject: [PATCH 2173/3659] board: ite: it515xx_evb: rename it515xx_evb to it51xxx_evb This change accommodates support for next-generation soc(it51600). Tested with: west build -p always -b it51xxx_evb/it51526aw samples/hello_world/ Signed-off-by: Ren Chen --- boards/deprecated.cmake | 3 ++ .../Kconfig.defconfig | 4 +-- .../Kconfig.it51xxx_evb} | 4 +-- .../{it515xx_evb => it51xxx_evb}/board.yml | 2 +- .../doc/index.rst | 32 ++++++++++-------- .../doc/it51xxx_evb_and_debug_card.webp} | Bin .../doc/it51xxx_evb_wiring.webp} | Bin .../it51xxx_evb_it51526aw.dts} | 4 +-- .../it51xxx_evb_it51526aw.yaml} | 4 +-- .../it51xxx_evb_it51526aw_defconfig} | 0 doc/_scripts/redirects.py | 1 + doc/releases/migration-guide-4.4.rst | 2 ++ doc/releases/release-notes-4.2.rst | 2 +- ...xx_evb.conf => it51xxx_evb_it51526aw.conf} | 0 ....overlay => it51xxx_evb_it51526aw.overlay} | 0 .../comparator/gpio_loopback/testcase.yaml | 3 ++ ....overlay => it51xxx_evb_it51526aw.overlay} | 0 ...t515xx_m1k.overlay => it51xxx_m1k.overlay} | 0 tests/drivers/flash/common/testcase.yaml | 8 ++--- ....overlay => it51xxx_evb_it51526aw.overlay} | 0 ...xx_evb.conf => it51xxx_evb_it51526aw.conf} | 0 ....overlay => it51xxx_evb_it51526aw.overlay} | 0 .../drivers/i2c/i2c_target_api/testcase.yaml | 1 + 23 files changed, 41 insertions(+), 29 deletions(-) rename boards/ite/{it515xx_evb => it51xxx_evb}/Kconfig.defconfig (81%) rename boards/ite/{it515xx_evb/Kconfig.it515xx_evb => it51xxx_evb/Kconfig.it51xxx_evb} (55%) rename boards/ite/{it515xx_evb => it51xxx_evb}/board.yml (79%) rename boards/ite/{it515xx_evb => it51xxx_evb}/doc/index.rst (83%) rename boards/ite/{it515xx_evb/doc/it515xx_evb_and_debug_card.webp => it51xxx_evb/doc/it51xxx_evb_and_debug_card.webp} (100%) rename boards/ite/{it515xx_evb/doc/it515xx_evb_wiring.webp => it51xxx_evb/doc/it51xxx_evb_wiring.webp} (100%) rename boards/ite/{it515xx_evb/it515xx_evb.dts => it51xxx_evb/it51xxx_evb_it51526aw.dts} (97%) rename boards/ite/{it515xx_evb/it515xx_evb.yaml => it51xxx_evb/it51xxx_evb_it51526aw.yaml} (66%) rename boards/ite/{it515xx_evb/it515xx_evb_defconfig => it51xxx_evb/it51xxx_evb_it51526aw_defconfig} (100%) rename tests/drivers/comparator/gpio_loopback/boards/{it515xx_evb.conf => it51xxx_evb_it51526aw.conf} (100%) rename tests/drivers/comparator/gpio_loopback/boards/{it515xx_evb.overlay => it51xxx_evb_it51526aw.overlay} (100%) rename tests/drivers/counter/counter_basic_api/boards/{it515xx_evb.overlay => it51xxx_evb_it51526aw.overlay} (100%) rename tests/drivers/flash/common/boards/{it515xx_m1k.overlay => it51xxx_m1k.overlay} (100%) rename tests/drivers/gpio/gpio_basic_api/boards/{it515xx_evb.overlay => it51xxx_evb_it51526aw.overlay} (100%) rename tests/drivers/i2c/i2c_target_api/boards/{it515xx_evb.conf => it51xxx_evb_it51526aw.conf} (100%) rename tests/drivers/i2c/i2c_target_api/boards/{it515xx_evb.overlay => it51xxx_evb_it51526aw.overlay} (100%) diff --git a/boards/deprecated.cmake b/boards/deprecated.cmake index 8a884009de24..bc664f79b06b 100644 --- a/boards/deprecated.cmake +++ b/boards/deprecated.cmake @@ -67,3 +67,6 @@ set(esp32s3_devkitm/esp32s3/appcpu_DEPRECATED set(ubx_evk_iris_w1_fidelex/rw612_DEPRECATED ubx_evk_iris_w1@fidelix/rw612 ) +set(it51xxx_evb_DEPRECATED + it515xx_evb/it51526aw +) diff --git a/boards/ite/it515xx_evb/Kconfig.defconfig b/boards/ite/it51xxx_evb/Kconfig.defconfig similarity index 81% rename from boards/ite/it515xx_evb/Kconfig.defconfig rename to boards/ite/it51xxx_evb/Kconfig.defconfig index e5033cdd7c32..4f3ad984ebaa 100644 --- a/boards/ite/it515xx_evb/Kconfig.defconfig +++ b/boards/ite/it51xxx_evb/Kconfig.defconfig @@ -1,7 +1,7 @@ # Copyright (c) 2025 ITE Corporation. All Rights Reserved. # SPDX-License-Identifier: Apache-2.0 -if BOARD_IT515XX_EVB +if BOARD_IT51XXX_EVB if PM @@ -14,4 +14,4 @@ endchoice endif # PM -endif # BOARD_IT515XX_EVB +endif # BOARD_IT51XXX_EVB diff --git a/boards/ite/it515xx_evb/Kconfig.it515xx_evb b/boards/ite/it51xxx_evb/Kconfig.it51xxx_evb similarity index 55% rename from boards/ite/it515xx_evb/Kconfig.it515xx_evb rename to boards/ite/it51xxx_evb/Kconfig.it51xxx_evb index 123837216ab8..41719913887f 100644 --- a/boards/ite/it515xx_evb/Kconfig.it515xx_evb +++ b/boards/ite/it51xxx_evb/Kconfig.it51xxx_evb @@ -1,5 +1,5 @@ # Copyright (c) 2025 ITE Corporation. All Rights Reserved. # SPDX-License-Identifier: Apache-2.0 -config BOARD_IT515XX_EVB - select SOC_IT51526AW +config BOARD_IT51XXX_EVB + select SOC_IT51526AW if BOARD_IT51XXX_EVB_IT51526AW diff --git a/boards/ite/it515xx_evb/board.yml b/boards/ite/it51xxx_evb/board.yml similarity index 79% rename from boards/ite/it515xx_evb/board.yml rename to boards/ite/it51xxx_evb/board.yml index d4c7074979fa..1c9edb2edf70 100644 --- a/boards/ite/it515xx_evb/board.yml +++ b/boards/ite/it51xxx_evb/board.yml @@ -1,5 +1,5 @@ board: - name: it515xx_evb + name: it51xxx_evb full_name: IT51XXX series vendor: ite socs: diff --git a/boards/ite/it515xx_evb/doc/index.rst b/boards/ite/it51xxx_evb/doc/index.rst similarity index 83% rename from boards/ite/it515xx_evb/doc/index.rst rename to boards/ite/it51xxx_evb/doc/index.rst index cdd3ad54735b..a0fdff39bcf3 100644 --- a/boards/ite/it515xx_evb/doc/index.rst +++ b/boards/ite/it51xxx_evb/doc/index.rst @@ -1,4 +1,4 @@ -.. zephyr:board:: it515xx_evb +.. zephyr:board:: it51xxx_evb Overview ******** @@ -6,9 +6,10 @@ Overview The IT51XXX is a 32-bit RISC-V microcontroller. And a highly integrated embedded controller with system functions. It is suitable for mobile system applications. The picture below is -the IT51526 development board (also known as it515xx_evb) and its debug card. +the IT51526 development board (also known as it51xxx_evb/it51526aw) +and its debug card. -.. figure:: it515xx_evb_and_debug_card.webp +.. figure:: it51xxx_evb_and_debug_card.webp :align: center :alt: IT51526 EVB @@ -52,22 +53,22 @@ Wiring ======= #. Connect the Download Board to your host computer using the USB cable. -#. Connect the it515xx_evb to the evolution motherboard. +#. Connect the it51xxx_evb to the evolution motherboard. #. Connect the Download Board J5 to J38(GPC1 & GPC2) on the evolution motherboard. #. Connect the USB to UART wire to UART0 connector on the evolution motherboard. - .. image:: it515xx_evb_wiring.webp + .. image:: it51xxx_evb_wiring.webp :align: center - :alt: it515xx_evb wiring + :alt: it51xxx_evb wiring .. note:: Be careful during connection! - Use separate wires to connect I2C pins with pins on the it515xx_evb board. + Use separate wires to connect I2C pins with pins on the it51xxx_evb board. Wiring connection is described in the table below. +-------------+---------------+ - | J5 | it515xx_evb | + | J5 | it51xxx_evb | | Connector | J38 Connector | +=============+===============+ | 2 | C1 | @@ -95,7 +96,7 @@ Building (see :`Zephyr Getting Started Guide`_):. .. zephyr-app-commands:: - :board: it515xx_evb + :board: it51xxx_evb/it51526aw :zephyr-app: samples/hello_world :goals: build @@ -108,12 +109,13 @@ Windows -------- Use the winflash tool to program a zephyr application -to the it515xx board flash. +to the it51xxx/it51526aw board flash. #. Flashing steps as described in the link: `Flashing steps`_. -#. Turn on the it515xx_evb board switch, you should see ``"Hello World! it515xx_evb"`` - sent by the board. If you don't see this message, press the Reset button and the +#. Turn on the it51xxx_evb/it51526aw board switch, you should see + ``"Hello World! it51xxx_evb/it51526aw"`` sent by the board. + If you don't see this message, press the Reset button and the message should appear. Ubuntu @@ -138,20 +140,20 @@ Ubuntu https://www.ite.com.tw/upload/2024_01_23/6_20240123162336wu55j1Rjm4.bz2 #. Split first and second terminal windows to view both of them. - You should see ``"Hello World! it515xx_evb"`` in the first terminal window. + You should see ``"Hello World! it51xxx_evb/it51526aw"`` in the first terminal window. If you don't see this message, press the Reset button and the message should appear. Debugging ========= -it515xx_evb board can be debugged by connecting USB to UART. We can write commands and +it51xxx_evb board can be debugged by connecting USB to UART. We can write commands and read messages through minicom in the Ubuntu terminal. Troubleshooting =============== #. If the flash tool reports a failure, re-plug the 8390 Download board or - power cycle the it515xx_evb board and try again. + power cycle the it51xxx_evb board and try again. References ========== diff --git a/boards/ite/it515xx_evb/doc/it515xx_evb_and_debug_card.webp b/boards/ite/it51xxx_evb/doc/it51xxx_evb_and_debug_card.webp similarity index 100% rename from boards/ite/it515xx_evb/doc/it515xx_evb_and_debug_card.webp rename to boards/ite/it51xxx_evb/doc/it51xxx_evb_and_debug_card.webp diff --git a/boards/ite/it515xx_evb/doc/it515xx_evb_wiring.webp b/boards/ite/it51xxx_evb/doc/it51xxx_evb_wiring.webp similarity index 100% rename from boards/ite/it515xx_evb/doc/it515xx_evb_wiring.webp rename to boards/ite/it51xxx_evb/doc/it51xxx_evb_wiring.webp diff --git a/boards/ite/it515xx_evb/it515xx_evb.dts b/boards/ite/it51xxx_evb/it51xxx_evb_it51526aw.dts similarity index 97% rename from boards/ite/it515xx_evb/it515xx_evb.dts rename to boards/ite/it51xxx_evb/it51xxx_evb_it51526aw.dts index b9be1896e0cc..e3495cdc9da2 100644 --- a/boards/ite/it515xx_evb/it515xx_evb.dts +++ b/boards/ite/it51xxx_evb/it51xxx_evb_it51526aw.dts @@ -11,8 +11,8 @@ #include / { - model = "IT515XX EV-Board"; - compatible = "ite,it515xx-evb"; + model = "IT51XXX EV-Board"; + compatible = "ite,it51xxx-evb"; aliases { i2c-0 = &i2c0; diff --git a/boards/ite/it515xx_evb/it515xx_evb.yaml b/boards/ite/it51xxx_evb/it51xxx_evb_it51526aw.yaml similarity index 66% rename from boards/ite/it515xx_evb/it515xx_evb.yaml rename to boards/ite/it51xxx_evb/it51xxx_evb_it51526aw.yaml index 5ac8ab272d7e..a9c13ede0047 100644 --- a/boards/ite/it515xx_evb/it515xx_evb.yaml +++ b/boards/ite/it51xxx_evb/it51xxx_evb_it51526aw.yaml @@ -1,5 +1,5 @@ -identifier: it515xx_evb -name: ITE IT51XXX EVB +identifier: it51xxx_evb/it51526aw +name: ITE-IT51XXX-EVB-IT51526AW type: mcu arch: riscv toolchain: diff --git a/boards/ite/it515xx_evb/it515xx_evb_defconfig b/boards/ite/it51xxx_evb/it51xxx_evb_it51526aw_defconfig similarity index 100% rename from boards/ite/it515xx_evb/it515xx_evb_defconfig rename to boards/ite/it51xxx_evb/it51xxx_evb_it51526aw_defconfig diff --git a/doc/_scripts/redirects.py b/doc/_scripts/redirects.py index bee8ac631129..b36e39d3e1cd 100644 --- a/doc/_scripts/redirects.py +++ b/doc/_scripts/redirects.py @@ -19,6 +19,7 @@ ('boards/arm/fvp_baser_aemv8r/doc/aarch32', 'boards/arm/fvp_baser_aemv8r/doc/index'), ('boards/arm/fvp_baser_aemv8r/doc/aarch64', 'boards/arm/fvp_baser_aemv8r/doc/index'), ('boards/arm/fvp_baser_aemv8r/doc/debug-with-arm-ds', 'boards/arm/fvp_baser_aemv8r/doc/index'), + ('boards/ite/it515xx_evb/doc/index', 'boards/ite/it51xxx_evb/doc/index'), ('boards/nordic/nrf54l20pdk/doc/index', 'boards/nordic/nrf54lm20dk/doc/index'), ('boards/nxp/hexiwear/doc/index', 'boards/mikroe/hexiwear/doc/index'), ('boards/panasonic/panb511evb/doc/index', 'boards/panasonic/panb611evb/doc/index'), diff --git a/doc/releases/migration-guide-4.4.rst b/doc/releases/migration-guide-4.4.rst index 04b88edad762..11498e15a83c 100644 --- a/doc/releases/migration-guide-4.4.rst +++ b/doc/releases/migration-guide-4.4.rst @@ -94,6 +94,8 @@ Boards * :kconfig:option:`CONFIG_SOC_SERIES_NRF91X` with :kconfig:option:`CONFIG_SOC_SERIES_NRF91` * :kconfig:option:`CONFIG_SOC_SERIES_NRF92X` with :kconfig:option:`CONFIG_SOC_SERIES_NRF92` +* ITE ``it515xx_evb`` is renamed to ``it51xxx_evb``. + Device Drivers and Devicetree ***************************** diff --git a/doc/releases/release-notes-4.2.rst b/doc/releases/release-notes-4.2.rst index e4b74b0459e8..36c98445eee3 100644 --- a/doc/releases/release-notes-4.2.rst +++ b/doc/releases/release-notes-4.2.rst @@ -590,7 +590,7 @@ New Boards * ITE Tech. Inc. - * :zephyr:board:`it515xx_evb` (``it515xx_evb``) + * ``it515xx_evb`` * KWS Computersysteme Gmbh diff --git a/tests/drivers/comparator/gpio_loopback/boards/it515xx_evb.conf b/tests/drivers/comparator/gpio_loopback/boards/it51xxx_evb_it51526aw.conf similarity index 100% rename from tests/drivers/comparator/gpio_loopback/boards/it515xx_evb.conf rename to tests/drivers/comparator/gpio_loopback/boards/it51xxx_evb_it51526aw.conf diff --git a/tests/drivers/comparator/gpio_loopback/boards/it515xx_evb.overlay b/tests/drivers/comparator/gpio_loopback/boards/it51xxx_evb_it51526aw.overlay similarity index 100% rename from tests/drivers/comparator/gpio_loopback/boards/it515xx_evb.overlay rename to tests/drivers/comparator/gpio_loopback/boards/it51xxx_evb_it51526aw.overlay diff --git a/tests/drivers/comparator/gpio_loopback/testcase.yaml b/tests/drivers/comparator/gpio_loopback/testcase.yaml index 59a18a7e1f41..a628911ec904 100644 --- a/tests/drivers/comparator/gpio_loopback/testcase.yaml +++ b/tests/drivers/comparator/gpio_loopback/testcase.yaml @@ -68,3 +68,6 @@ tests: platform_allow: - sam_e54_xpro - pic32cx_sg41_cult + drivers.comparator.gpio_loopback.ite: + platform_allow: + - it51xxx_evb/it51526aw diff --git a/tests/drivers/counter/counter_basic_api/boards/it515xx_evb.overlay b/tests/drivers/counter/counter_basic_api/boards/it51xxx_evb_it51526aw.overlay similarity index 100% rename from tests/drivers/counter/counter_basic_api/boards/it515xx_evb.overlay rename to tests/drivers/counter/counter_basic_api/boards/it51xxx_evb_it51526aw.overlay diff --git a/tests/drivers/flash/common/boards/it515xx_m1k.overlay b/tests/drivers/flash/common/boards/it51xxx_m1k.overlay similarity index 100% rename from tests/drivers/flash/common/boards/it515xx_m1k.overlay rename to tests/drivers/flash/common/boards/it51xxx_m1k.overlay diff --git a/tests/drivers/flash/common/testcase.yaml b/tests/drivers/flash/common/testcase.yaml index 2547a3e98296..6a3250727d9c 100644 --- a/tests/drivers/flash/common/testcase.yaml +++ b/tests/drivers/flash/common/testcase.yaml @@ -237,15 +237,15 @@ tests: platform_allow: - it8xxx2_evb - it82xx2_evb - - it515xx_evb + - it51xxx_evb/it51526aw extra_args: - DTC_OVERLAY_FILE="./boards/it8xxx2_indirect.overlay" - drivers.flash.common.it515xx_m1k: + drivers.flash.common.it51xxx_m1k: build_only: true platform_allow: - - it515xx_evb + - it51xxx_evb/it51526aw extra_args: - - DTC_OVERLAY_FILE="./boards/it515xx_m1k.overlay" + - DTC_OVERLAY_FILE="./boards/it51xxx_m1k.overlay" drivers.flash.common.mspi_single_io_low_frequency: platform_allow: - nrf54h20dk/nrf54h20/cpuapp diff --git a/tests/drivers/gpio/gpio_basic_api/boards/it515xx_evb.overlay b/tests/drivers/gpio/gpio_basic_api/boards/it51xxx_evb_it51526aw.overlay similarity index 100% rename from tests/drivers/gpio/gpio_basic_api/boards/it515xx_evb.overlay rename to tests/drivers/gpio/gpio_basic_api/boards/it51xxx_evb_it51526aw.overlay diff --git a/tests/drivers/i2c/i2c_target_api/boards/it515xx_evb.conf b/tests/drivers/i2c/i2c_target_api/boards/it51xxx_evb_it51526aw.conf similarity index 100% rename from tests/drivers/i2c/i2c_target_api/boards/it515xx_evb.conf rename to tests/drivers/i2c/i2c_target_api/boards/it51xxx_evb_it51526aw.conf diff --git a/tests/drivers/i2c/i2c_target_api/boards/it515xx_evb.overlay b/tests/drivers/i2c/i2c_target_api/boards/it51xxx_evb_it51526aw.overlay similarity index 100% rename from tests/drivers/i2c/i2c_target_api/boards/it515xx_evb.overlay rename to tests/drivers/i2c/i2c_target_api/boards/it51xxx_evb_it51526aw.overlay diff --git a/tests/drivers/i2c/i2c_target_api/testcase.yaml b/tests/drivers/i2c/i2c_target_api/testcase.yaml index 77d15be20739..0ac4cc223cd9 100644 --- a/tests/drivers/i2c/i2c_target_api/testcase.yaml +++ b/tests/drivers/i2c/i2c_target_api/testcase.yaml @@ -76,6 +76,7 @@ tests: - ophelia4ev/nrf54l15/cpuapp - s32k5xxcvb/s32k566/m7 - s32k5xxcvb/s32k566/r52 + - it51xxx_evb/it51526aw integration_platforms: - max32690evkit/max32690/m4 - nrf54l15dk/nrf54l15/cpuapp From 39a60f8a0b5aff44f270813493ae1fb24fa74c63 Mon Sep 17 00:00:00 2001 From: Alain Volmat Date: Sat, 20 Dec 2025 19:07:41 +0100 Subject: [PATCH 2174/3659] video: st: remove soc specific dcmipp compatibles Only st,stm32-dcmipp is described and only st,stm32n6-dcmipp was used within the driver to decide if CSI / PIXEL_PIPES are available. Instead of this, look at HAL provided macros to know if the selected soc has the functionalities or not. Signed-off-by: Alain Volmat --- drivers/video/video_stm32_dcmipp.c | 4 +++- dts/arm/st/mp13/stm32mp135.dtsi | 2 +- dts/arm/st/n6/stm32n6.dtsi | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/video/video_stm32_dcmipp.c b/drivers/video/video_stm32_dcmipp.c index 650532acb136..ef305458f8d3 100644 --- a/drivers/video/video_stm32_dcmipp.c +++ b/drivers/video/video_stm32_dcmipp.c @@ -30,8 +30,10 @@ #define HAL_DCMIPP_PARALLEL_SetConfig HAL_DCMIPP_SetParallelConfig #endif -#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32n6_dcmipp) +#if defined(DCMIPP_SERIAL_MODE) #define STM32_DCMIPP_HAS_CSI +#endif +#if defined(DCMIPP_PIPE1) && defined(DCMIPP_PIPE2) #define STM32_DCMIPP_HAS_PIXEL_PIPES #endif diff --git a/dts/arm/st/mp13/stm32mp135.dtsi b/dts/arm/st/mp13/stm32mp135.dtsi index a935b37b0dfd..c54827d42697 100644 --- a/dts/arm/st/mp13/stm32mp135.dtsi +++ b/dts/arm/st/mp13/stm32mp135.dtsi @@ -12,7 +12,7 @@ compatible = "st,stm32mp135", "st,stm32mp13", "simple-bus"; dcmipp: dcmipp@5a000000 { - compatible = "st,stm32mp13-dcmipp", "st,stm32-dcmipp"; + compatible = "st,stm32-dcmipp"; reg = <0x5a000000 0x400>; interrupts = ; clocks = <&rcc STM32_CLOCK(APB4, 1)>, diff --git a/dts/arm/st/n6/stm32n6.dtsi b/dts/arm/st/n6/stm32n6.dtsi index f6d3e45744f4..298c5b56335a 100644 --- a/dts/arm/st/n6/stm32n6.dtsi +++ b/dts/arm/st/n6/stm32n6.dtsi @@ -747,7 +747,7 @@ }; dcmipp: dcmipp@58002000 { - compatible = "st,stm32n6-dcmipp", "st,stm32-dcmipp"; + compatible = "st,stm32-dcmipp"; reg = <0x58002000 0x1000>; clock-names = "dcmipp", "dcmipp-ker", "csi"; clocks = <&rcc STM32_CLOCK(APB5, 2)>, From 8f9e370bfbc863ba1787e3e8e2a796a860256faf Mon Sep 17 00:00:00 2001 From: Alain Volmat Date: Fri, 31 Oct 2025 22:28:09 +0100 Subject: [PATCH 2175/3659] drivers: clock: h7rs: add PCLKx support Addition of PCLKx clock source which can be used by some peripherals. Signed-off-by: Alain Volmat --- drivers/clock_control/clock_stm32_ll_h7.c | 20 +++++++++++++++++++ .../dt-bindings/clock/stm32h7rs_clock.h | 4 ++++ 2 files changed, 24 insertions(+) diff --git a/drivers/clock_control/clock_stm32_ll_h7.c b/drivers/clock_control/clock_stm32_ll_h7.c index b84f8b963258..efef824c3f61 100644 --- a/drivers/clock_control/clock_stm32_ll_h7.c +++ b/drivers/clock_control/clock_stm32_ll_h7.c @@ -362,6 +362,10 @@ int enabled_clock(uint32_t src_clk) (src_clk == STM32_SRC_HCLK3) || (src_clk == STM32_SRC_HCLK4) || (src_clk == STM32_SRC_HCLK5) || + (src_clk == STM32_SRC_PCLK1) || + (src_clk == STM32_SRC_PCLK2) || + (src_clk == STM32_SRC_PCLK4) || + (src_clk == STM32_SRC_PCLK5) || ((src_clk == STM32_SRC_PLL2_S) && IS_ENABLED(STM32_PLL2_S_ENABLED)) || ((src_clk == STM32_SRC_PLL2_T) && IS_ENABLED(STM32_PLL2_T_ENABLED)) || ((src_clk == STM32_SRC_PLL3_S) && IS_ENABLED(STM32_PLL3_S_ENABLED)) || @@ -501,9 +505,17 @@ static int stm32_clock_control_get_subsys_rate(const struct device *clock, break; case STM32_CLOCK_BUS_APB1: case STM32_CLOCK_BUS_APB1_2: +#if defined(CONFIG_SOC_SERIES_STM32H7RSX) + /* PCLK1 is a possible source clock for some peripherals */ + case STM32_SRC_PCLK1: +#endif /* CONFIG_SOC_SERIES_STM32H7RSX */ *rate = apb1_clock; break; case STM32_CLOCK_BUS_APB2: +#if defined(CONFIG_SOC_SERIES_STM32H7RSX) + /* PCLK2 is a possible source clock for some peripherals */ + case STM32_SRC_PCLK2: +#endif *rate = apb2_clock; break; #if !defined(CONFIG_SOC_SERIES_STM32H7RSX) @@ -512,10 +524,18 @@ static int stm32_clock_control_get_subsys_rate(const struct device *clock, break; #endif /* !CONFIG_SOC_SERIES_STM32H7RSX */ case STM32_CLOCK_BUS_APB4: +#if defined(CONFIG_SOC_SERIES_STM32H7RSX) + /* PCLK2 is a possible source clock for some peripherals */ + case STM32_SRC_PCLK4: +#endif *rate = apb4_clock; break; #if defined(CONFIG_SOC_SERIES_STM32H7RSX) case STM32_CLOCK_BUS_APB5: +#if defined(CONFIG_SOC_SERIES_STM32H7RSX) + /* PCLK5 is a possible source clock for some peripherals */ + case STM32_SRC_PCLK5: +#endif *rate = apb5_clock; break; case STM32_CLOCK_BUS_AHB5: diff --git a/include/zephyr/dt-bindings/clock/stm32h7rs_clock.h b/include/zephyr/dt-bindings/clock/stm32h7rs_clock.h index e9133f65457b..5d3e434bcba4 100644 --- a/include/zephyr/dt-bindings/clock/stm32h7rs_clock.h +++ b/include/zephyr/dt-bindings/clock/stm32h7rs_clock.h @@ -45,6 +45,10 @@ #define STM32_SRC_HCLK5 (STM32_SRC_HCLK4 + 1) #define STM32_SRC_TIMPCLK1 (STM32_SRC_HCLK5 + 1) #define STM32_SRC_TIMPCLK2 (STM32_SRC_TIMPCLK1 + 1) +#define STM32_SRC_PCLK1 (STM32_SRC_TIMPCLK2 + 1) +#define STM32_SRC_PCLK2 (STM32_SRC_PCLK1 + 1) +#define STM32_SRC_PCLK4 (STM32_SRC_PCLK2 + 1) +#define STM32_SRC_PCLK5 (STM32_SRC_PCLK4 + 1) /** Others: Not yet supported */ /** Bus clocks */ From 94d5de3ffe2ae67bd2b2b451929502b3e2a4f99d Mon Sep 17 00:00:00 2001 From: Alain Volmat Date: Sat, 2 Aug 2025 16:37:01 +0200 Subject: [PATCH 2176/3659] dts: arm: st: add dcmipp node in stm32h7rs.dtsi The STM32H7RS series embeds a parallel interface based DCMIPP block allowing to capture data from sensors and store them into memory. Signed-off-by: Alain Volmat --- dts/arm/st/h7rs/stm32h7rs.dtsi | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/dts/arm/st/h7rs/stm32h7rs.dtsi b/dts/arm/st/h7rs/stm32h7rs.dtsi index 60471b063a31..c2f877a5df04 100644 --- a/dts/arm/st/h7rs/stm32h7rs.dtsi +++ b/dts/arm/st/h7rs/stm32h7rs.dtsi @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -1006,6 +1007,26 @@ resets = <&rctl STM32_RESET(APB5, 1)>; status = "disabled"; }; + + dcmipp: dcmipp@50002000 { + compatible = "st,stm32-dcmipp"; + reg = <0x50002000 0x400>; + clocks = <&rcc STM32_CLOCK(APB5, 2)>, + <&rcc STM32_SRC_PCLK5 NO_SEL>; + clock-names = "dcmipp", "dcmipp-ker"; + interrupts = <95 0>; + resets = <&rctl STM32_RESET(APB5, 2)>; + status = "disabled"; + + pipe_dump: pipe {}; + + port { + endpoint { + remote-endpoint-label = ""; + bus-type = ; + }; + }; + }; }; otgfs_phy: otgfs_phy { From 9e993d31114661633694094ce474963326c2c06a Mon Sep 17 00:00:00 2001 From: Alain Volmat Date: Tue, 20 Jan 2026 13:18:44 +0100 Subject: [PATCH 2177/3659] boards: st: stm32h7s78_dk: correct SPI4 chip select On this board the chip select is connected to GPIO E10 and must be controlled via GPIO since SPI4 CS is accessible via either E4 or E11 which are both already used by other functions on this board. Signed-off-by: Alain Volmat --- boards/st/stm32h7s78_dk/stm32h7s78_dk-common.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/boards/st/stm32h7s78_dk/stm32h7s78_dk-common.dtsi b/boards/st/stm32h7s78_dk/stm32h7s78_dk-common.dtsi index 41dab8d3aefc..56549bc28e5e 100644 --- a/boards/st/stm32h7s78_dk/stm32h7s78_dk-common.dtsi +++ b/boards/st/stm32h7s78_dk/stm32h7s78_dk-common.dtsi @@ -199,9 +199,9 @@ }; &spi4 { - pinctrl-0 = <&spi4_nss_pe4 &spi4_sck_pe12 - &spi4_miso_pe13 &spi4_mosi_pe14>; + pinctrl-0 = <&spi4_sck_pe12 &spi4_miso_pe13 &spi4_mosi_pe14>; pinctrl-names = "default"; + cs-gpios = <&gpioe 10 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; status = "okay"; }; From 8078db0419247dd78b9c04d607c1cb87ed41619c Mon Sep 17 00:00:00 2001 From: Alain Volmat Date: Fri, 31 Oct 2025 20:42:15 +0100 Subject: [PATCH 2178/3659] boards: st: add camera connector and camera interface in stm32h7s78 Describe the camera related pins of the 30pins connectors of the stm32h7s78 as well as DCMIPP pin assignments for the stm32h7s78 Signed-off-by: Alain Volmat --- .../stm32h7s78_dk/stm32h7s78_dk-common.dtsi | 32 ++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/boards/st/stm32h7s78_dk/stm32h7s78_dk-common.dtsi b/boards/st/stm32h7s78_dk/stm32h7s78_dk-common.dtsi index 56549bc28e5e..0e5d6bb72f48 100644 --- a/boards/st/stm32h7s78_dk/stm32h7s78_dk-common.dtsi +++ b/boards/st/stm32h7s78_dk/stm32h7s78_dk-common.dtsi @@ -67,6 +67,28 @@ }; }; + dcmi_camera_connector: connector_dcmi_camera { + compatible = "st,stm32-dcmi-camera-fpu-330zh"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <3 0 &gpiob 6 0>, /* I2C1_SCL */ + <4 0 &gpiob 9 0>, /* I2C1_SDA */ + <5 0 &gpion 7 0>, /* RESET */ + <6 0 &gpiof 5 0>, /* PWDN_EN */ + <12 0 &gpiob 7 0>, /* DCMI_VSYNC */ + <14 0 &gpiog 3 0>, /* DCMI_HSYNC */ + <16 0 &gpiod 5 0>, /* DCMI_PIXCK */ + <20 0 &gpiod 14 0>, /* DCMI_D7 */ + <21 0 &gpiob 8 0>, /* DCMI_D6 */ + <22 0 &gpiod 3 0>, /* DCMI_D5 */ + <23 0 &gpioe 4 0>, /* DCMI_D4 */ + <24 0 &gpioe 1 0>, /* DCMI_D3 */ + <25 0 &gpioe 0 0>, /* DCMI_D2 */ + <26 0 &gpioc 7 0>, /* DCMI_D1 */ + <27 0 &gpioc 6 0>; /* DCMI_D0 */ + }; + aliases { led0 = &blue_led; sw0 = &user_button; @@ -205,7 +227,7 @@ status = "okay"; }; -&i2c1 { +st_cam_i2c: &i2c1 { pinctrl-0 = <&i2c1_scl_pb6 &i2c1_sda_pb9>; pinctrl-names = "default"; /* @@ -383,3 +405,11 @@ zephyr_udc0: &usb2 {}; def-back-color-green = <0xff>; def-back-color-blue = <0xff>; }; + +st_cam_dvp: &dcmipp { + pinctrl-0 = <&dcmipp_d0_pc6 &dcmipp_d1_pc7 &dcmipp_d2_pe0 &dcmipp_d3_pe1 + &dcmipp_d4_pe4 &dcmipp_d5_pd3 &dcmipp_d6_pb8 &dcmipp_d7_pd14 + &dcmipp_pixclk_pd5 &dcmipp_hsync_pg3 &dcmipp_vsync_pb7>; + + pinctrl-names = "default"; +}; From cd82d84153c2d3d53e9c2454113e5d9ff707d8a9 Mon Sep 17 00:00:00 2001 From: Alain Volmat Date: Fri, 31 Oct 2025 21:23:45 +0100 Subject: [PATCH 2179/3659] boards: st: stm32h7s78_dk: use PSRAM for video buffers Use the psram to store video buffers. Signed-off-by: Alain Volmat --- boards/st/stm32h7s78_dk/Kconfig.defconfig | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/boards/st/stm32h7s78_dk/Kconfig.defconfig b/boards/st/stm32h7s78_dk/Kconfig.defconfig index d587f115b102..ad5a8cc0a2f0 100644 --- a/boards/st/stm32h7s78_dk/Kconfig.defconfig +++ b/boards/st/stm32h7s78_dk/Kconfig.defconfig @@ -10,12 +10,21 @@ if BOARD_STM32H7S78_DK configdefault NET_L2_ETHERNET default y -if DISPLAY +if DISPLAY || VIDEO # MEMC needs to be enabled in order to store -# display frame buffer to external PSRAM +# display frame buffer and video buffer pool to external PSRAM config MEMC default y -endif # DISPLAY + +if VIDEO +# Place video buffer pool into the PSRAM +config VIDEO_BUFFER_POOL_ZEPHYR_REGION + default y + +config VIDEO_BUFFER_POOL_ZEPHYR_REGION_NAME + default "PSRAM" +endif # VIDEO +endif # DISPLAY || VIDEO if INPUT From 7cc95ae919c6195d69e4f8aeb981f7cef4aae2de Mon Sep 17 00:00:00 2001 From: Alain Volmat Date: Fri, 31 Oct 2025 22:34:24 +0100 Subject: [PATCH 2180/3659] boards: shields: st_b_cams_omv_mb1683: add stm32h7s78_dk confs Add board specific configuration and overlay for enabling the st_b_cams_omv_mb1683 shield on the stm32h7s78_dk board. Signed-off-by: Alain Volmat --- .../stm32h7s78_dk_stm32h7s7xx_ext_flash_app.conf | 3 +++ .../stm32h7s78_dk_stm32h7s7xx_ext_flash_app.overlay | 11 +++++++++++ 2 files changed, 14 insertions(+) create mode 100644 boards/shields/st_b_cams_omv_mb1683/boards/stm32h7s78_dk_stm32h7s7xx_ext_flash_app.conf create mode 100644 boards/shields/st_b_cams_omv_mb1683/boards/stm32h7s78_dk_stm32h7s7xx_ext_flash_app.overlay diff --git a/boards/shields/st_b_cams_omv_mb1683/boards/stm32h7s78_dk_stm32h7s7xx_ext_flash_app.conf b/boards/shields/st_b_cams_omv_mb1683/boards/stm32h7s78_dk_stm32h7s7xx_ext_flash_app.conf new file mode 100644 index 000000000000..eb92e26de99d --- /dev/null +++ b/boards/shields/st_b_cams_omv_mb1683/boards/stm32h7s78_dk_stm32h7s7xx_ext_flash_app.conf @@ -0,0 +1,3 @@ +CONFIG_VIDEO_STM32_DCMIPP_SENSOR_PIXEL_FORMAT="RGBP" +CONFIG_VIDEO_STM32_DCMIPP_SENSOR_WIDTH=320 +CONFIG_VIDEO_STM32_DCMIPP_SENSOR_HEIGHT=240 diff --git a/boards/shields/st_b_cams_omv_mb1683/boards/stm32h7s78_dk_stm32h7s7xx_ext_flash_app.overlay b/boards/shields/st_b_cams_omv_mb1683/boards/stm32h7s78_dk_stm32h7s7xx_ext_flash_app.overlay new file mode 100644 index 000000000000..3237ffd29076 --- /dev/null +++ b/boards/shields/st_b_cams_omv_mb1683/boards/stm32h7s78_dk_stm32h7s7xx_ext_flash_app.overlay @@ -0,0 +1,11 @@ +/* + * Copyright (c) 2026 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + chosen { + zephyr,camera = &pipe_dump; + }; +}; From 7a1cc72efac87d6ce3511a5f2cd5b325f4a25480 Mon Sep 17 00:00:00 2001 From: Biwen Li Date: Mon, 20 Oct 2025 18:05:30 +0900 Subject: [PATCH 2181/3659] drivers: i2s: mcux_sai: init base,mask,offset as 0 Initialize mclk_control_base, mclk_pin_mask, mclk_pin_offset as 0 and skip mclk settings when there is no property pinmuxes. Signed-off-by: Biwen Li --- drivers/i2s/i2s_mcux_sai.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/drivers/i2s/i2s_mcux_sai.c b/drivers/i2s/i2s_mcux_sai.c index de7765e023fa..d48432c7730d 100644 --- a/drivers/i2s/i2s_mcux_sai.c +++ b/drivers/i2s/i2s_mcux_sai.c @@ -427,6 +427,10 @@ static void enable_mclk_direction(const struct device *dev, bool dir) uint32_t mask = dev_cfg->mclk_pin_mask; uint32_t *base = (uint32_t *)(control_base + offset); + if (control_base == 0 && offset == 0 && mask == 0) { + return; + } + if (dir) { *base |= mask; } else { @@ -1215,6 +1219,15 @@ static DEVICE_API(i2s, i2s_mcux_driver_api) = { .trigger = i2s_mcux_trigger, }; +#define I2S_MCUX_PINMUX_INIT(i2s_id) \ + COND_CODE_1(DT_NODE_HAS_PROP(DT_DRV_INST(i2s_id), pinmuxes), \ + (.mclk_control_base = DT_REG_ADDR(DT_PHANDLE(DT_DRV_INST(i2s_id), pinmuxes)), \ + .mclk_pin_mask = DT_PHA_BY_IDX(DT_DRV_INST(i2s_id), pinmuxes, 0, mask), \ + .mclk_pin_offset = DT_PHA_BY_IDX(DT_DRV_INST(i2s_id), pinmuxes, 0, offset),), \ + (.mclk_control_base = 0, \ + .mclk_pin_mask = 0, \ + .mclk_pin_offset = 0,)) + #define I2S_MCUX_INIT(i2s_id) \ static void i2s_irq_connect_##i2s_id(const struct device *dev); \ \ @@ -1230,10 +1243,7 @@ static DEVICE_API(i2s, i2s_mcux_driver_api) = { .pll_pd = DT_PHA_BY_NAME_OR(DT_DRV_INST(i2s_id), pll_clocks, pd, value, 0), \ .pll_num = DT_PHA_BY_NAME_OR(DT_DRV_INST(i2s_id), pll_clocks, num, value, 0), \ .pll_den = DT_PHA_BY_NAME_OR(DT_DRV_INST(i2s_id), pll_clocks, den, value, 0), \ - .mclk_control_base = COND_CODE_1(DT_NODE_HAS_PROP(DT_DRV_INST(i2s_id), pinmuxes), \ - (DT_REG_ADDR(DT_PHANDLE(DT_DRV_INST(i2s_id), pinmuxes))), (0)), \ - .mclk_pin_mask = DT_PHA_BY_IDX_OR(DT_DRV_INST(i2s_id), pinmuxes, 0, mask, 0), \ - .mclk_pin_offset = DT_PHA_BY_IDX_OR(DT_DRV_INST(i2s_id), pinmuxes, 0, offset, 0), \ + I2S_MCUX_PINMUX_INIT(i2s_id) \ .mclk_output = DT_INST_PROP_OR(i2s_id, mclk_output, 0), \ .clk_sub_sys = \ (clock_control_subsys_t)DT_INST_CLOCKS_CELL_BY_IDX(i2s_id, 0, name), \ From 1cbc2de20fdaeed1f6b259b4b07b6a755a5b740b Mon Sep 17 00:00:00 2001 From: Aiden Hu Date: Tue, 16 Dec 2025 14:15:34 +0800 Subject: [PATCH 2182/3659] drivers: usb: uhc: fix unused variable warning for phy_config Remove phy_config local variable then use controller-specific config struct for usb PHY initialization Signed-off-by: Aiden Hu --- drivers/usb/uhc/uhc_mcux_ehci.c | 13 ++++++------- drivers/usb/uhc/uhc_mcux_ip3516hs.c | 13 ++++++------- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/drivers/usb/uhc/uhc_mcux_ehci.c b/drivers/usb/uhc/uhc_mcux_ehci.c index 90ba04b6f6f5..6f3e87f250ce 100644 --- a/drivers/usb/uhc/uhc_mcux_ehci.c +++ b/drivers/usb/uhc/uhc_mcux_ehci.c @@ -92,8 +92,7 @@ static usb_status_t mcux_host_callback(usb_device_handle deviceHandle, static int uhc_mcux_init(const struct device *dev) { - const struct uhc_mcux_config *config = dev->config; - usb_phy_config_struct_t *phy_config; + const struct uhc_mcux_ehci_config *config = dev->config; struct uhc_mcux_data *priv = uhc_get_private(dev); k_thread_entry_t thread_entry = NULL; usb_status_t status; @@ -108,9 +107,8 @@ static int uhc_mcux_init(const struct device *dev) } #ifdef CONFIG_DT_HAS_NXP_USBPHY_ENABLED - phy_config = ((const struct uhc_mcux_ehci_config *)dev->config)->phy_config; - if (phy_config != NULL) { - USB_EhciPhyInit(priv->controller_id, 0u, phy_config); + if (config->phy_config != NULL) { + USB_EhciPhyInit(priv->controller_id, 0u, config->phy_config); } #endif @@ -124,8 +122,9 @@ static int uhc_mcux_init(const struct device *dev) } /* Create MCUX USB host driver task */ - k_thread_create(&priv->drv_stack_data, config->drv_stack, CONFIG_UHC_NXP_THREAD_STACK_SIZE, - thread_entry, (void *)dev, NULL, NULL, K_PRIO_COOP(2), 0, K_NO_WAIT); + k_thread_create(&priv->drv_stack_data, config->uhc_config.drv_stack, + CONFIG_UHC_NXP_THREAD_STACK_SIZE, thread_entry, + (void *)dev, NULL, NULL, K_PRIO_COOP(2), 0, K_NO_WAIT); k_thread_name_set(&priv->drv_stack_data, "uhc_mcux_ehci"); return 0; diff --git a/drivers/usb/uhc/uhc_mcux_ip3516hs.c b/drivers/usb/uhc/uhc_mcux_ip3516hs.c index ac9f36c83a98..03bddb11059d 100644 --- a/drivers/usb/uhc/uhc_mcux_ip3516hs.c +++ b/drivers/usb/uhc/uhc_mcux_ip3516hs.c @@ -67,8 +67,7 @@ static usb_status_t mcux_host_callback(usb_device_handle deviceHandle, static int uhc_mcux_init(const struct device *dev) { - const struct uhc_mcux_config *config = dev->config; - usb_phy_config_struct_t *phy_config; + const struct uhc_mcux_ip3516hs_config *config = dev->config; struct uhc_mcux_data *priv = uhc_get_private(dev); k_thread_entry_t thread_entry = NULL; usb_status_t status; @@ -83,9 +82,8 @@ static int uhc_mcux_init(const struct device *dev) } #ifdef CONFIG_DT_HAS_NXP_USBPHY_ENABLED - phy_config = ((const struct uhc_mcux_ip3516hs_config *)dev->config)->phy_config; - if (phy_config != NULL) { - USB_EhciPhyInit(priv->controller_id, 0u, phy_config); + if (config->phy_config != NULL) { + USB_EhciPhyInit(priv->controller_id, 0u, config->phy_config); } #endif @@ -99,8 +97,9 @@ static int uhc_mcux_init(const struct device *dev) } /* Create MCUX USB host driver task */ - k_thread_create(&priv->drv_stack_data, config->drv_stack, CONFIG_UHC_NXP_THREAD_STACK_SIZE, - thread_entry, (void *)dev, NULL, NULL, K_PRIO_COOP(2), 0, K_NO_WAIT); + k_thread_create(&priv->drv_stack_data, config->uhc_config.drv_stack, + CONFIG_UHC_NXP_THREAD_STACK_SIZE, thread_entry, + (void *)dev, NULL, NULL, K_PRIO_COOP(2), 0, K_NO_WAIT); k_thread_name_set(&priv->drv_stack_data, "uhc_mcux_ip3516hs"); return 0; From ac348a7ab5a379468e2cace1d05cf10332980e7f Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Wed, 17 Dec 2025 07:52:10 +0000 Subject: [PATCH 2183/3659] scripts: dts: gen_dts_cmake: Output compatibles for no prop. nodes Seemingly partitions (fixed-partitions) have no properties when the edt file is loaded, work around this issue by outputting compatibles for nodes that have them but have no properties, also fixes some other outputs for misc. devices Signed-off-by: Jamie McCrae --- scripts/dts/gen_dts_cmake.py | 38 ++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/scripts/dts/gen_dts_cmake.py b/scripts/dts/gen_dts_cmake.py index e3ec1997ee10..ef2c9a7f932f 100755 --- a/scripts/dts/gen_dts_cmake.py +++ b/scripts/dts/gen_dts_cmake.py @@ -118,21 +118,29 @@ def main(): for label in node.labels: cmake_props.append(f'"DT_NODELABEL|{label}" "{node.path}"') - for item in node.props: - # We currently do not support phandles for edt -> cmake conversion. - if "phandle" not in node.props[item].type: - if "array" in node.props[item].type: - # Convert array to CMake list - cmake_value = '' - for val in node.props[item].val: - cmake_value = f'{cmake_value}{val};' - else: - cmake_value = node.props[item].val - - # Encode node's property 'item' as a CMake target property - # with a name like 'DT_PROP||'. - cmake_prop = f'DT_PROP|{node.path}|{item}' - cmake_props.append(f'"{cmake_prop}" "{escape(cmake_value)}"') + if node.props: + for item in node.props: + # We currently do not support phandles for edt -> cmake conversion. + if "phandle" not in node.props[item].type: + if "array" in node.props[item].type: + # Convert array to CMake list + cmake_value = '' + for val in node.props[item].val: + cmake_value = f'{cmake_value}{val};' + else: + cmake_value = node.props[item].val + + # Encode node's property 'item' as a CMake target property + # with a name like 'DT_PROP||'. + cmake_prop = f'DT_PROP|{node.path}|{item}' + cmake_props.append(f'"{cmake_prop}" "{escape(cmake_value)}"') + elif node.compats: + # Manually output compatibles for nodes that have no properties + cmake_value = '' + for val in node.compats: + cmake_value = f'{cmake_value}{val};' + cmake_prop = f'DT_PROP|{node.path}|compatible' + cmake_props.append(f'"{cmake_prop}" "{escape(cmake_value)}"') for comp in node.compats: compatible2paths[comp].append(node.path) From 7f864309a723f620ac3a54405e566671e0ea3285 Mon Sep 17 00:00:00 2001 From: Jiafei Pan Date: Thu, 18 Dec 2025 17:42:14 +0800 Subject: [PATCH 2184/3659] boards: imx943_evk: fix board document footer Move footer to the end of the document. Signed-off-by: Jiafei Pan --- boards/nxp/imx943_evk/doc/index.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/boards/nxp/imx943_evk/doc/index.rst b/boards/nxp/imx943_evk/doc/index.rst index 13ec782f4807..8f31d451fab0 100644 --- a/boards/nxp/imx943_evk/doc/index.rst +++ b/boards/nxp/imx943_evk/doc/index.rst @@ -201,8 +201,6 @@ Then the following log could be found on UART1 console: *** Booting Zephyr OS build v4.1.0-3650-gdb71736adb68 *** Hello World! imx943_evk/mimx94398/a55 -.. include:: ../../common/board-footer.rst.inc - Programming and Debugging (M33 in NETC MIX, M7_0 in M7MIX0, M7_1 in M7MIX1) *************************************************************************** @@ -428,3 +426,5 @@ and UART8, below bcu (`bcu 1.1.113 download`_) configuration is needed to use UA .. _i.MX Linux BSP release: https://www.nxp.com/design/design-center/software/embedded-software/i-mx-software/embedded-linux-for-i-mx-applications-processors:IMXLINUX + +.. include:: ../../common/board-footer.rst.inc From 0be4e58871a4aa28ce49c8f5cdfc7bcd7d77c61c Mon Sep 17 00:00:00 2001 From: Jiafei Pan Date: Thu, 18 Dec 2025 10:09:57 +0800 Subject: [PATCH 2185/3659] boards: imx943_evk: add A55 SMP board variant The default SMP board variant runs SMP Zephyr on four A55 Cores, it could be changed by disabling some CPU core nodes in dts and change CONFIG_MP_MAX_NUM_CPUS accordingly. Signed-off-by: Jiafei Pan --- boards/nxp/imx943_evk/Kconfig.imx943_evk | 2 +- boards/nxp/imx943_evk/board.yml | 2 + boards/nxp/imx943_evk/doc/index.rst | 19 ++++++++ .../imx943_evk_mimx94398_a55_smp.dts | 48 +++++++++++++++++++ .../imx943_evk_mimx94398_a55_smp.yaml | 20 ++++++++ .../imx943_evk_mimx94398_a55_smp_defconfig | 38 +++++++++++++++ 6 files changed, 128 insertions(+), 1 deletion(-) create mode 100644 boards/nxp/imx943_evk/imx943_evk_mimx94398_a55_smp.dts create mode 100644 boards/nxp/imx943_evk/imx943_evk_mimx94398_a55_smp.yaml create mode 100644 boards/nxp/imx943_evk/imx943_evk_mimx94398_a55_smp_defconfig diff --git a/boards/nxp/imx943_evk/Kconfig.imx943_evk b/boards/nxp/imx943_evk/Kconfig.imx943_evk index 37ab2872ded2..cc3b0922f878 100644 --- a/boards/nxp/imx943_evk/Kconfig.imx943_evk +++ b/boards/nxp/imx943_evk/Kconfig.imx943_evk @@ -2,7 +2,7 @@ # SPDX-License-Identifier: Apache-2.0 config BOARD_IMX943_EVK - select SOC_MIMX94398_A55 if BOARD_IMX943_EVK_MIMX94398_A55 + select SOC_MIMX94398_A55 if BOARD_IMX943_EVK_MIMX94398_A55 || BOARD_IMX943_EVK_MIMX94398_A55_SMP select SOC_MIMX94398_M33 if BOARD_IMX943_EVK_MIMX94398_M33 || BOARD_IMX943_EVK_MIMX94398_M33_DDR select SOC_MIMX94398_M7_0 if BOARD_IMX943_EVK_MIMX94398_M7_0 select SOC_MIMX94398_M7_1 if BOARD_IMX943_EVK_MIMX94398_M7_1 diff --git a/boards/nxp/imx943_evk/board.yml b/boards/nxp/imx943_evk/board.yml index 568781db2cc9..b3ac421c6cd1 100644 --- a/boards/nxp/imx943_evk/board.yml +++ b/boards/nxp/imx943_evk/board.yml @@ -7,3 +7,5 @@ board: variants: - name: ddr cpucluster: m33 + - name: smp + cpucluster: a55 diff --git a/boards/nxp/imx943_evk/doc/index.rst b/boards/nxp/imx943_evk/doc/index.rst index 8f31d451fab0..1f76384616ec 100644 --- a/boards/nxp/imx943_evk/doc/index.rst +++ b/boards/nxp/imx943_evk/doc/index.rst @@ -201,6 +201,25 @@ Then the following log could be found on UART1 console: *** Booting Zephyr OS build v4.1.0-3650-gdb71736adb68 *** Hello World! imx943_evk/mimx94398/a55 +Cortex-A55 SMP +============== + +The default SMP variant runs on all four Cortex-A Core, it could be changed by +disabling some A55 Core nodes in dts and change :kconfig:option:`CONFIG_MP_MAX_NUM_CPUS` +to the count of enabled A55 Cores in dts. + +Building SMP kernel, for example, with the :zephyr:code-sample:`synchronization` sample: + +.. zephyr-app-commands:: + :zephyr-app: samples/synchronization + :host-os: unix + :board: imx943_evk/mimx94398/a55/smp + :goals: build + +For different booting method, need to make sure SMP Zephyr to be started from the first +CPU Core listed in "cpus" dts node, so the first A55 Core in default SMP variant dts +is Core0, it could be booted by U-Boot "go" command, J-Link runner or SPSDK runner. + Programming and Debugging (M33 in NETC MIX, M7_0 in M7MIX0, M7_1 in M7MIX1) *************************************************************************** diff --git a/boards/nxp/imx943_evk/imx943_evk_mimx94398_a55_smp.dts b/boards/nxp/imx943_evk/imx943_evk_mimx94398_a55_smp.dts new file mode 100644 index 000000000000..99f5e6eeb132 --- /dev/null +++ b/boards/nxp/imx943_evk/imx943_evk_mimx94398_a55_smp.dts @@ -0,0 +1,48 @@ +/* + * SPDX-FileCopyrightText: Copyright 2026 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include "imx943_evk_mimx94398_a55.dts" + +/ { + model = "NXP i.MX943 A55"; + compatible = "fsl,mimx943"; + + chosen { + zephyr,console = &lpuart1; + zephyr,shell-uart = &lpuart1; + /* sram node actually locates at DDR DRAM */ + zephyr,sram = &dram; + }; + + psci { + compatible = "arm,psci-1.1"; + method = "smc"; + }; + + cpus { + cpu@0 { + status = "okay"; + }; + + cpu@100 { + status = "okay"; + }; + + cpu@200 { + status = "okay"; + }; + + cpu@300 { + status = "okay"; + }; + }; + + dram: memory@d0000000 { + reg = <0xd0000000 DT_SIZE_M(10)>; + }; +}; diff --git a/boards/nxp/imx943_evk/imx943_evk_mimx94398_a55_smp.yaml b/boards/nxp/imx943_evk/imx943_evk_mimx94398_a55_smp.yaml new file mode 100644 index 000000000000..3d970a802f45 --- /dev/null +++ b/boards/nxp/imx943_evk/imx943_evk_mimx94398_a55_smp.yaml @@ -0,0 +1,20 @@ +# +# SPDX-FileCopyrightText: Copyright 2026 NXP +# +# SPDX-License-Identifier: Apache-2.0 +# + +identifier: imx943_evk/mimx94398/a55/smp +name: NXP i.MX943 EVK A55 SMP +type: mcu +arch: arm64 +toolchain: + - zephyr + - cross-compile +ram: 10240 +supported: + - counter + - gpio + - net + - uart +vendor: nxp diff --git a/boards/nxp/imx943_evk/imx943_evk_mimx94398_a55_smp_defconfig b/boards/nxp/imx943_evk/imx943_evk_mimx94398_a55_smp_defconfig new file mode 100644 index 000000000000..759218d6c9e9 --- /dev/null +++ b/boards/nxp/imx943_evk/imx943_evk_mimx94398_a55_smp_defconfig @@ -0,0 +1,38 @@ +# +# SPDX-FileCopyrightText: Copyright 2026 NXP +# +# SPDX-License-Identifier: Apache-2.0 + +# ARM Options +CONFIG_AARCH64_IMAGE_HEADER=y +CONFIG_ARMV8_A_NS=y + +# MMU Options +CONFIG_MAX_XLAT_TABLES=24 + +# Cache Options +CONFIG_CACHE_MANAGEMENT=y +CONFIG_DCACHE_LINE_SIZE_DETECT=y +CONFIG_ICACHE_LINE_SIZE_DETECT=y + +# Zephyr Kernel Configuration +CONFIG_XIP=n +CONFIG_KERNEL_DIRECT_MAP=y + +# SMP +CONFIG_SMP=y +CONFIG_MP_MAX_NUM_CPUS=4 +CONFIG_PM_CPU_OPS=y + +# Serial Drivers +CONFIG_SERIAL=y +CONFIG_UART_INTERRUPT_DRIVEN=y + +# Enable Console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +CONFIG_CLOCK_CONTROL=y + +CONFIG_MBOX=y +CONFIG_ARM_SCMI=y From 5d73bc00cac520d8291ede4243523ed351b46f94 Mon Sep 17 00:00:00 2001 From: Grzegorz Chwierut Date: Thu, 18 Dec 2025 19:18:07 +0100 Subject: [PATCH 2186/3659] twister: fix --list-tests output, remove duplication in names This fixes the issue where --list-tests and --test-tree commands showed duplicated testsuite IDs in the output, simplifies testcase name handling in harness and runner modules. Removed feature to extend behaviour of --no-detailed-test-id to shorten test case names - feature was introduced in #82302. This makes the twister output more predictable and the codebase easier to maintain. Signed-off-by: Grzegorz Chwierut --- doc/develop/test/twister.rst | 3 --- .../pylib/twister/twisterlib/environment.py | 13 ++--------- scripts/pylib/twister/twisterlib/harness.py | 4 ++-- scripts/pylib/twister/twisterlib/runner.py | 2 +- .../pylib/twister/twisterlib/testinstance.py | 3 --- scripts/pylib/twister/twisterlib/testplan.py | 12 ++++------ scripts/pylib/twister/twisterlib/testsuite.py | 23 ++++--------------- scripts/tests/twister/test_harness.py | 4 ++-- scripts/tests/twister/test_runner.py | 2 +- scripts/tests/twister_blackbox/test_output.py | 5 ---- 10 files changed, 16 insertions(+), 55 deletions(-) diff --git a/doc/develop/test/twister.rst b/doc/develop/test/twister.rst index f0644f5f0cc0..e74acb264586 100644 --- a/doc/develop/test/twister.rst +++ b/doc/develop/test/twister.rst @@ -305,9 +305,6 @@ The ``--no-detailed-test-id`` command line option modifies the above rules in th #. With short Test Suite names in this mode, all corresponding Test Scenario names must be unique for the Twister execution scope. -#. **Ztest** Test Case names have only Ztest components ``.``. - Its parent Test Suite name equals to the corresponding Test Scenario identifier. - The following is an example test configuration with a few options that are explained in this document. diff --git a/scripts/pylib/twister/twisterlib/environment.py b/scripts/pylib/twister/twisterlib/environment.py index 3fb87e668d3e..fd496a1ef973 100644 --- a/scripts/pylib/twister/twisterlib/environment.py +++ b/scripts/pylib/twister/twisterlib/environment.py @@ -346,7 +346,6 @@ def add_parse_arguments(parser = None) -> argparse.ArgumentParser: Example_2: 'debug.coredump.logging_backend' is a standalone test scenario name. Note: This selection mechanism works only for Ztest suite and test function names in the source files which are not generated by macro-substitutions. - Note: With --no-detailed-test-id use only Ztest names without scenario name. """) parser.add_argument( @@ -683,20 +682,12 @@ def add_parse_arguments(parser = None) -> argparse.ArgumentParser: parser.add_argument( '--detailed-test-id', action='store_true', help="Compose each test Suite name from its configuration path (relative to root) and " - "the appropriate Scenario name using PATH_TO_TEST_CONFIG/SCENARIO_NAME schema. " - "Also (for Ztest only), prefix each test Case name with its Scenario name. " - "For example: 'kernel.common.timing' Scenario with test Suite name " - "'tests/kernel/sleep/kernel.common.timing' and 'kernel.common.timing.sleep.usleep' " - "test Case (where 'sleep' is its Ztest suite name and 'usleep' is Ztest test name.") + "the appropriate Scenario name using PATH_TO_TEST_CONFIG/SCENARIO_NAME schema.") parser.add_argument( "--no-detailed-test-id", dest='detailed_test_id', action="store_false", help="Don't prefix each test Suite name with its configuration path, " - "so it is the same as the appropriate Scenario name. " - "Also (for Ztest only), don't prefix each Ztest Case name with its Scenario name. " - "For example: 'kernel.common.timing' Scenario name, the same Suite name, " - "and 'sleep.usleep' test Case (where 'sleep' is its Ztest suite name " - "and 'usleep' is Ztest test name.") + "so it is the same as the appropriate Scenario name.") # Do not include paths in names by default. parser.set_defaults(detailed_test_id=False) diff --git a/scripts/pylib/twister/twisterlib/harness.py b/scripts/pylib/twister/twisterlib/harness.py index 9a06e059feca..d00d308c5542 100644 --- a/scripts/pylib/twister/twisterlib/harness.py +++ b/scripts/pylib/twister/twisterlib/harness.py @@ -860,7 +860,7 @@ def get_testcase(self, tc_name, phase, ts_name=None): for ts_name_ in ts_names: if self.started_suites[ts_name_]['count'] < (0 if phase == 'TS_SUM' else 1): continue - tc_fq_id = self.instance.compose_case_name(f"{ts_name_}.{tc_name}") + tc_fq_id = self.instance.testsuite.compose_case_name(f"{ts_name_}.{tc_name}") if tc := self.instance.get_case_by_name(tc_fq_id): if self.trace: logger.debug(f"{phase}: Ztest case '{tc_name}' matched to '{tc_fq_id}") @@ -869,7 +869,7 @@ def get_testcase(self, tc_name, phase, ts_name=None): f"{phase}: Ztest case '{tc_name}' is not known" f" in {self.started_suites} running suite(s)." ) - tc_id = self.instance.compose_case_name(tc_name) + tc_id = self.instance.testsuite.compose_case_name(tc_name) return self.instance.get_case_or_create(tc_id) def start_suite(self, suite_name, phase='TS_START'): diff --git a/scripts/pylib/twister/twisterlib/runner.py b/scripts/pylib/twister/twisterlib/runner.py index 165853e64f58..3c504a984f50 100644 --- a/scripts/pylib/twister/twisterlib/runner.py +++ b/scripts/pylib/twister/twisterlib/runner.py @@ -1257,7 +1257,7 @@ def determine_testcases(self, results): f"not present in: {self.instance.testsuite.ztest_suite_names}" ) test_func_name = m_[2].replace("test_", "", 1) - testcase_id = self.instance.compose_case_name( + testcase_id = self.instance.testsuite.compose_case_name( f"{new_ztest_suite}.{test_func_name}" ) detected_cases.append(testcase_id) diff --git a/scripts/pylib/twister/twisterlib/testinstance.py b/scripts/pylib/twister/twisterlib/testinstance.py index 3e33062cc4fb..622f8cc9631a 100644 --- a/scripts/pylib/twister/twisterlib/testinstance.py +++ b/scripts/pylib/twister/twisterlib/testinstance.py @@ -186,9 +186,6 @@ def __setstate__(self, d): def __lt__(self, other): return self.name < other.name - def compose_case_name(self, tc_name) -> str: - return self.testsuite.compose_case_name(tc_name) - def set_case_status_by_name(self, name, status, reason=None): tc = self.get_case_or_create(name) tc.status = status diff --git a/scripts/pylib/twister/twisterlib/testplan.py b/scripts/pylib/twister/twisterlib/testplan.py index 1c641b2b4e38..a9e65a11df6b 100755 --- a/scripts/pylib/twister/twisterlib/testplan.py +++ b/scripts/pylib/twister/twisterlib/testplan.py @@ -373,13 +373,9 @@ def handle_modules(self): def report(self): if self.options.test_tree: - if not self.options.detailed_test_id: - logger.info("Test tree is always shown with detailed test-id.") self.report_test_tree() return 0 elif self.options.list_tests: - if not self.options.detailed_test_id: - logger.info("Test list is always shown with detailed test-id.") self.report_test_list() return 0 elif self.options.list_tags: @@ -501,18 +497,18 @@ def get_tests_list(self): for _, ts in self.testsuites.items(): if ts.tags.intersection(tag_filter): for case in ts.testcases: - testcases.append(case.detailed_name) + testcases.append(case.name) else: for _, ts in self.testsuites.items(): for case in ts.testcases: - testcases.append(case.detailed_name) + testcases.append(case.name) if exclude_tag := self.options.exclude_tag: for _, ts in self.testsuites.items(): if ts.tags.intersection(exclude_tag): for case in ts.testcases: - if case.detailed_name in testcases: - testcases.remove(case.detailed_name) + if case.name in testcases: + testcases.remove(case.name) return testcases def _is_testsuite_selected(self, suite: TestSuite, testsuite_filter, testsuite_patterns_r): diff --git a/scripts/pylib/twister/twisterlib/testsuite.py b/scripts/pylib/twister/twisterlib/testsuite.py index 5d4f346effc1..1e837cc38057 100644 --- a/scripts/pylib/twister/twisterlib/testsuite.py +++ b/scripts/pylib/twister/twisterlib/testsuite.py @@ -376,19 +376,14 @@ def _find_src_dir_path(test_dir_path): class TestCase(DisablePyTestCollectionMixin): - def __init__(self, name=None, testsuite=None): + def __init__(self, name): self.duration = 0 self.name = name self._status = TwisterStatus.NONE self.reason = None - self.testsuite = testsuite self.output = "" self.freeform = False - @property - def detailed_name(self) -> str: - return TestSuite.get_case_name_(self.testsuite, self.name, detailed=True) - @property def status(self) -> TwisterStatus: return self._status @@ -447,7 +442,7 @@ def __init__(self, suite_root, suite_path, name, data=None, detailed_test_id=Tru os.path.realpath(suite_path), start=canonical_zephyr_base ) self.yamlfile = suite_path - self.testcases = [] + self.testcases: list[TestCase] = [] self.integration_platforms = [] self.ztest_suite_names = [] @@ -480,18 +475,8 @@ def load(self, data): 'Harness config error: console harness defined without a configuration.' ) - @staticmethod - def get_case_name_(test_suite, tc_name, detailed=True) -> str: - return f"{test_suite.id}.{tc_name}" \ - if test_suite and detailed and not test_suite.detailed_test_id else f"{tc_name}" - - @staticmethod - def compose_case_name_(test_suite, tc_name) -> str: - return f"{test_suite.id}.{tc_name}" \ - if test_suite and test_suite.detailed_test_id else f"{tc_name}" - def compose_case_name(self, tc_name) -> str: - return self.compose_case_name_(self, tc_name) + return f"{self.id}.{tc_name}" if self.id != tc_name else tc_name def add_subcases(self, data, parsed_subcases=None, suite_names=None): testcases = data.get("testcases", []) @@ -509,7 +494,7 @@ def add_subcases(self, data, parsed_subcases=None, suite_names=None): self.ztest_suite_names = suite_names def add_testcase(self, name, freeform=False): - tc = TestCase(name=name, testsuite=self) + tc = TestCase(name=name) tc.freeform = freeform self.testcases.append(tc) diff --git a/scripts/tests/twister/test_harness.py b/scripts/tests/twister/test_harness.py index 7e10078ee2de..fc90205f32e2 100644 --- a/scripts/tests/twister/test_harness.py +++ b/scripts/tests/twister/test_harness.py @@ -888,7 +888,7 @@ def test_get_harness(name): "START - test_testcase", [], {}, - { 'testcase': { 'count': 1 } }, + { 'dummy.test_id.testcase': { 'count': 1 } }, TwisterStatus.PASS, False, TwisterStatus.PASS, @@ -929,7 +929,7 @@ def test_test_handle( mock_testsuite.ztest_suite_names = [] mock_testsuite.detailed_test_id = detailed_id mock_testsuite.source_dir_rel = "dummy_suite" - mock_testsuite.compose_case_name.return_value = TestSuite.compose_case_name_(mock_testsuite, "testcase") + mock_testsuite.compose_case_name.return_value = TestSuite.compose_case_name(mock_testsuite, "testcase") outdir = tmp_path / "ztest_out" with mock.patch('twisterlib.testsuite.TestSuite.get_unique', return_value="dummy_suite"): diff --git a/scripts/tests/twister/test_runner.py b/scripts/tests/twister/test_runner.py index d971727fb5ef..c9d01bf05890 100644 --- a/scripts/tests/twister/test_runner.py +++ b/scripts/tests/twister/test_runner.py @@ -1648,7 +1648,7 @@ def test_projectbuilder_determine_testcases( instance_mock.testsuite.id = 'dummy.test_id' instance_mock.testsuite.ztest_suite_names = [] instance_mock.testsuite.detailed_test_id = detailed_id - instance_mock.compose_case_name = mock.Mock(side_effect=iter(added_tcs)) + instance_mock.testsuite.compose_case_name = mock.Mock(side_effect=iter(added_tcs)) pb = ProjectBuilder(instance_mock, mocked_env, mocked_jobserver) diff --git a/scripts/tests/twister_blackbox/test_output.py b/scripts/tests/twister_blackbox/test_output.py index 6535a342d749..8bba373d7ade 100644 --- a/scripts/tests/twister_blackbox/test_output.py +++ b/scripts/tests/twister_blackbox/test_output.py @@ -76,11 +76,6 @@ def test_detailed_test_id(self, out_path, flag, expect_paths): expected_start = os.path.relpath(TEST_DATA, ZEPHYR_BASE) if expect_paths else 'dummy.' assert all([testsuite.startswith(expected_start) for _, testsuite, _ in filtered_j]) - if expect_paths: - assert all([(tc_name.count('.') > 1) for _, _, tc_name in filtered_j]) - else: - assert all([(tc_name.count('.') == 1) for _, _, tc_name in filtered_j]) - def test_inline_logs(self, out_path): test_platforms = ['qemu_x86', 'intel_adl_crb'] From 46d8f1baa9f8127c2a5bd69b9c663688e965d26b Mon Sep 17 00:00:00 2001 From: Vinit Mehta Date: Mon, 29 Dec 2025 18:02:04 +0530 Subject: [PATCH 2187/3659] drivers: bluetooth: hci: add host wakeup for IW612 BT controller Add wakeup IO config for IW612 shield for BT host wakeup functionality. Add kconfig to enable/disable BT host wakeup functionality Add kconfig to toggle onboard LED upon detecting BT activity Signed-off-by: Vinit Mehta --- .../nxp_m2_wifi_bt/nxp_m2_2el_wifi_bt.overlay | 3 +- drivers/bluetooth/hci/Kconfig.nxp | 15 +++- drivers/bluetooth/hci/hci_nxp_setup.c | 90 ++++++++++++++++++- dts/bindings/bluetooth/nxp,bt-hci-uart.yaml | 10 ++- 4 files changed, 114 insertions(+), 4 deletions(-) diff --git a/boards/shields/nxp_m2_wifi_bt/nxp_m2_2el_wifi_bt.overlay b/boards/shields/nxp_m2_wifi_bt/nxp_m2_2el_wifi_bt.overlay index 5fb1406d636f..ce4b79cdf2a3 100644 --- a/boards/shields/nxp_m2_wifi_bt/nxp_m2_2el_wifi_bt.overlay +++ b/boards/shields/nxp_m2_wifi_bt/nxp_m2_2el_wifi_bt.overlay @@ -1,5 +1,5 @@ /* - * Copyright 2025 NXP + * Copyright 2025-2026 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -25,6 +25,7 @@ fw-download-primary-speed = <115200>; fw-download-secondary-speed = <3000000>; fw-download-secondary-flowcontrol; + wakeup-bt-gpios = <&gpio1 1 GPIO_ACTIVE_LOW>; }; }; }; diff --git a/drivers/bluetooth/hci/Kconfig.nxp b/drivers/bluetooth/hci/Kconfig.nxp index 4db2c08cd83c..c31776bbc2cd 100644 --- a/drivers/bluetooth/hci/Kconfig.nxp +++ b/drivers/bluetooth/hci/Kconfig.nxp @@ -1,5 +1,5 @@ # -# Copyright 2023-2025 NXP +# Copyright 2023-2026 NXP # # SPDX-License-Identifier: Apache-2.0 # @@ -12,6 +12,19 @@ config HCI_NXP_ENABLE_AUTO_SLEEP Enabling this feature will allow to save power at the cost of some latency when sending a HCI message to the Controller as the Host will need to wake it up. +config BT_NXP_CTRL_WAKE_ON_BT + bool "Config to enable/disable wake on BT/BLE for NXP controllers" + help + Enable/Disable BT wakeup IO triggers for NXP BT IW416/NW612/IW610 SOC. + +config BT_NXP_CTRL_WAKE_ON_BT_LED_BLINK + bool "Config LED0 to blink upon observing activity on BT wakeup IO" + depends on BT_NXP_CTRL_WAKE_ON_BT + depends on $(dt_alias_enabled,led0) + help + Enable LED blinking to indicate Bluetooth activity when wake-on-BT + is triggered. Requires led0 alias to be defined in device tree. + config HCI_NXP_SET_CAL_DATA bool "Bluetooth Controller calibration data" default y if BT_NXP_NW612 || BT_NXP_IW416 diff --git a/drivers/bluetooth/hci/hci_nxp_setup.c b/drivers/bluetooth/hci/hci_nxp_setup.c index d85edb65a074..5ed739379e9c 100644 --- a/drivers/bluetooth/hci/hci_nxp_setup.c +++ b/drivers/bluetooth/hci/hci_nxp_setup.c @@ -1,5 +1,5 @@ /* - * Copyright 2024-2025 NXP + * Copyright 2024-2026 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -72,6 +72,40 @@ static struct nxp_ctlr_dev_data uart_dev_data; static unsigned long crc_table[256U]; static bool made_table; +#if (defined(CONFIG_BT_NXP_CTRL_WAKE_ON_BT) && defined(CONFIG_BT_NXP_CTRL_WAKE_ON_BT_LED_BLINK)) +#define LED0_NODE DT_ALIAS(led0) + +static const struct gpio_dt_spec led_gpio = GPIO_DT_SPEC_GET(LED0_NODE, gpios); +#define BLINK_ONOFF K_MSEC(1000) +static struct k_work_delayable led_blink_work; +static void led_blink_cb(struct k_work *work) +{ + int current_state = gpio_pin_get_dt(&led_gpio); + + if (current_state == 0) { + /* LED is OFF, turn it ON briefly */ + gpio_pin_set_dt(&led_gpio, 1); + k_work_reschedule(&led_blink_work, BLINK_ONOFF); + } else { + /* LED is ON, turn it OFF and keep it OFF */ + gpio_pin_set_dt(&led_gpio, 0); + /* Don't reschedule - wait for next interrupt */ + } +} + +#endif /* CONFIG_BT_NXP_CTRL_WAKE_ON_BT && CONFIG_BT_NXP_CTRL_WAKE_ON_BT_LED_BLINK */ + +#if defined(CONFIG_BT_NXP_CTRL_WAKE_ON_BT) +static struct gpio_callback bt_wakeup_callback; +static void gpio_wakeup_callback_bt(const struct device *port, struct gpio_callback *cb, + gpio_port_pins_t pins) +{ +#if (defined(CONFIG_BT_NXP_CTRL_WAKE_ON_BT_LED_BLINK)) + /* Schedule LED blink when activity is detected on wake-up IO */ + k_work_schedule(&led_blink_work, BLINK_ONOFF); +#endif +} +#endif static void fw_upload_gen_crc32_table(void) { @@ -1467,7 +1501,61 @@ int bt_h4_vnd_setup(const struct device *dev, const struct bt_hci_setup_params * LOG_ERR("Fail to load annex-100 calibration data"); return err; } +#if defined(CONFIG_BT_NXP_CTRL_WAKE_ON_BT) +#if DT_NODE_HAS_PROP(DT_DRV_INST(0), wakeup_bt_gpios) + struct gpio_dt_spec wakeup = GPIO_DT_SPEC_GET(DT_DRV_INST(0), wakeup_bt_gpios); + + LOG_DBG("Configuring Wakeup IOs\n"); + if (!gpio_is_ready_dt(&wakeup)) { + LOG_ERR("Error: failed to configure wakeup %s pin %d", wakeup.port->name, + wakeup.pin); + return -EIO; + } + + /* Configure wakeup gpio as input */ + err = gpio_pin_configure_dt(&wakeup, GPIO_INPUT); + if (err) { + LOG_ERR("Error %d: failed to configure wakeup %s pin %d", err, + wakeup.port->name, wakeup.pin); + return err; + } + + err = gpio_pin_set_dt(&wakeup, 0); + if (err) { + return err; + } + + /* Configure wakeup gpio interrupt */ + err = gpio_pin_interrupt_configure_dt(&wakeup, GPIO_INT_EDGE_FALLING); + if (err) { + return err; + } + + /* Set wakeup gpio callback function */ + gpio_init_callback(&bt_wakeup_callback, gpio_wakeup_callback_bt, BIT(wakeup.pin)); + err = gpio_add_callback_dt(&wakeup, &bt_wakeup_callback); + if (err) { + return err; + } +#endif + +#if (defined(CONFIG_BT_NXP_CTRL_WAKE_ON_BT_LED_BLINK)) + LOG_DBG("Configuring LED0 for BT Activity\n"); + if (!gpio_is_ready_dt(&led_gpio)) { + return 0; + } + + err = gpio_pin_configure_dt(&led_gpio, GPIO_OUTPUT_ACTIVE); + if (err < 0) { + return 0; + } + + /* Setting the default value for LED0 to off*/ + gpio_pin_set_dt(&led_gpio, 0); + k_work_init_delayable(&led_blink_work, led_blink_cb); +#endif /* CONFIG_BT_NXP_CTRL_WAKE_ON_BT_LED_BLINK */ +#endif /* CONFIG_BT_NXP_CTRL_WAKE_ON_BT */ fw_upload.is_setup_done = true; } diff --git a/dts/bindings/bluetooth/nxp,bt-hci-uart.yaml b/dts/bindings/bluetooth/nxp,bt-hci-uart.yaml index 362c54050725..a7af85ff9edf 100644 --- a/dts/bindings/bluetooth/nxp,bt-hci-uart.yaml +++ b/dts/bindings/bluetooth/nxp,bt-hci-uart.yaml @@ -1,4 +1,4 @@ -# Copyright 2024 NXP +# Copyright 2024,2026 NXP # SPDX-License-Identifier: Apache-2.0 description: | @@ -48,3 +48,11 @@ properties: type: boolean description: | Flow control setting for secondary speed. + + wakeup-bt-gpios: + type: phandle-array + description: | + BT wakeup host pin + This pin defaults to active low when consumed by the SDK card. The + property value should ensure the flags properly describe the signal + that is presented to the driver. From fddcf70d57d0b941ec40877c3e142eefb81e02cf Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Fri, 9 Jan 2026 09:57:10 +0000 Subject: [PATCH 2188/3659] snippets: Add slot1-partition snippet Adds a snippet which sets the chosen code partition to slot1_partition, which can be used with things like MCUboot Signed-off-by: Jamie McCrae --- snippets/slot1-partition/README.rst | 24 +++++++++++++++++++ .../slot1-partition/slot1-partition.overlay | 5 ++++ snippets/slot1-partition/snippet.yml | 3 +++ 3 files changed, 32 insertions(+) create mode 100644 snippets/slot1-partition/README.rst create mode 100644 snippets/slot1-partition/slot1-partition.overlay create mode 100644 snippets/slot1-partition/snippet.yml diff --git a/snippets/slot1-partition/README.rst b/snippets/slot1-partition/README.rst new file mode 100644 index 000000000000..89cee1172c5b --- /dev/null +++ b/snippets/slot1-partition/README.rst @@ -0,0 +1,24 @@ +.. _snippet-slot1-partition: + +Slot1 partition snippet (slot1-partition) +######################################### + +.. code-block:: console + + west build -S slot1-partition [...] + +Overview +******** + +This snippet changes the chosen flash partition to be the ``slot1_partition`` node, this can be +used to build for the alternate slot in MCUboot direct-xip or firmware loader modes. + +Requirements +************ + +Partition mapping correct setup in devicetree, for example: + +.. literalinclude:: ../../dts/vendor/nordic/nrf52840_partition.dtsi + :language: dts + :dedent: + :lines: 15- diff --git a/snippets/slot1-partition/slot1-partition.overlay b/snippets/slot1-partition/slot1-partition.overlay new file mode 100644 index 000000000000..eba132c978bc --- /dev/null +++ b/snippets/slot1-partition/slot1-partition.overlay @@ -0,0 +1,5 @@ +/ { + chosen { + zephyr,code-partition = &slot1_partition; + }; +}; diff --git a/snippets/slot1-partition/snippet.yml b/snippets/slot1-partition/snippet.yml new file mode 100644 index 000000000000..1be2b7d1d5d8 --- /dev/null +++ b/snippets/slot1-partition/snippet.yml @@ -0,0 +1,3 @@ +name: slot1-partition +append: + EXTRA_DTC_OVERLAY_FILE: slot1-partition.overlay From 8312b20ca98fe0d9510d647f22f522b398cd0b9c Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Tue, 6 Jan 2026 11:53:14 +0000 Subject: [PATCH 2189/3659] sysbuild: Add ability to generate slot 1 variant image Adds a new experimental Kconfig option to sysbuild which allows generating a variant image to use with MCUboot in direct-xip mode. It also includes base sysbuild infrastructure for creating additional variant images in future (including out-of-tree), whereby they use the base configuration of an existing image but modify it, without creating the default zephyr extra targets for images (e.g. menuconfig) to prevent changing configuration that should not be changed. Signed-off-by: Jamie McCrae --- cmake/modules/dts.cmake | 6 + cmake/modules/kconfig.cmake | 20 +- .../cmake/modules/sysbuild_extensions.cmake | 224 +++++++++++++++++- .../sysbuild/images/bootloader/CMakeLists.txt | 10 +- share/sysbuild/images/bootloader/Kconfig | 11 + 5 files changed, 260 insertions(+), 11 deletions(-) diff --git a/cmake/modules/dts.cmake b/cmake/modules/dts.cmake index 376245fbdc11..f72bf4b7289f 100644 --- a/cmake/modules/dts.cmake +++ b/cmake/modules/dts.cmake @@ -127,6 +127,9 @@ set(DTS_KCONFIG ${KCONFIG_BINARY_DIR}/Kconfig.dts) # modules. set(VENDOR_PREFIXES dts/bindings/vendor-prefixes.txt) +# Fetch variable from sysbuild which might be forcing a configuration (for variant build images) +zephyr_get(DTS_SOURCE SYSBUILD LOCAL) + if(NOT DEFINED DTS_SOURCE) zephyr_build_string(board_string SHORT shortened_board_string BOARD ${BOARD} BOARD_QUALIFIERS ${BOARD_QUALIFIERS} @@ -258,6 +261,9 @@ zephyr_dt_preprocess( WORKING_DIRECTORY ${APPLICATION_SOURCE_DIR} ) +# Fetch variable from sysbuild which might be forcing a configuration (for variant build images) +zephyr_get(DTS_DEPS SYSBUILD LOCAL) + # # Make sure we re-run CMake if any devicetree sources or transitive # includes change. diff --git a/cmake/modules/kconfig.cmake b/cmake/modules/kconfig.cmake index 1a6332298ba6..fe56fb3ffb1f 100644 --- a/cmake/modules/kconfig.cmake +++ b/cmake/modules/kconfig.cmake @@ -51,6 +51,8 @@ else() set(KCONFIG_ROOT ${ZEPHYR_BASE}/Kconfig) endif() +zephyr_get(KCONFIG_VARIANT_SOURCE SYSBUILD LOCAL) + if(NOT DEFINED BOARD_DEFCONFIG) zephyr_file(CONF_FILES ${BOARD_DIRECTORIES} DEFCONFIG BOARD_DEFCONFIG) endif() @@ -197,7 +199,11 @@ set(EXTRA_KCONFIG_TARGET_COMMAND_FOR_traceconfig ${PROJECT_BINARY_DIR}/kconfig-trace.md ) -set_ifndef(KCONFIG_TARGETS menuconfig guiconfig hardenconfig traceconfig) +zephyr_get(KCONFIG_TARGETS SYSBUILD LOCAL) + +if(NOT DEFINED KCONFIG_TARGETS) + set(KCONFIG_TARGETS menuconfig guiconfig hardenconfig traceconfig) +endif() foreach(kconfig_target ${KCONFIG_TARGETS} @@ -313,6 +319,13 @@ foreach(f ${merge_config_files}) endif() endforeach() +if(KCONFIG_VARIANT_SOURCE) + set( + merge_config_files + ${KCONFIG_VARIANT_SOURCE} + ) +endif() + # Calculate a checksum of merge_config_files to determine if we need # to re-generate .config set(merge_config_files_checksum "") @@ -355,7 +368,10 @@ if(EXISTS ${DOTCONFIG} AND EXISTS ${merge_config_files_checksum_file}) endif() if(CREATE_NEW_DOTCONFIG) - set(input_configs_flags --handwritten-input-configs) + if(NOT KCONFIG_VARIANT_SOURCE) + set(input_configs_flags --handwritten-input-configs) + endif() + set(input_configs ${merge_config_files} ${FORCED_CONF_FILE}) build_info(kconfig files PATH ${input_configs}) else() diff --git a/share/sysbuild/cmake/modules/sysbuild_extensions.cmake b/share/sysbuild/cmake/modules/sysbuild_extensions.cmake index f5a1137712a5..2efbd2f126e7 100644 --- a/share/sysbuild/cmake/modules/sysbuild_extensions.cmake +++ b/share/sysbuild/cmake/modules/sysbuild_extensions.cmake @@ -1,4 +1,4 @@ -# Copyright (c) 2021-2023 Nordic Semiconductor +# Copyright (c) 2021-2026 Nordic Semiconductor # # SPDX-License-Identifier: Apache-2.0 @@ -192,7 +192,8 @@ endfunction() # ExternalZephyrProject_Add(APPLICATION # SOURCE_DIR

    # [BOARD [BOARD_REVISION ]] -# [APP_TYPE ] +# [APP_TYPE ] +# [BUILD_ONLY ] # ) # # This function includes a Zephyr based build system into the multiimage @@ -204,13 +205,14 @@ endfunction() # BOARD : Use for application build instead user defined BOARD. # BOARD_REVISION : Use of for application (only valid if # is also supplied). -# APP_TYPE : Application type. -# MAIN indicates this application is the main application +# APP_TYPE MAIN indicates this application is the main application # and where user defined settings should be passed on as-is # except for multi image build flags. # For example, -DCONF_FILES= will be passed on to the # MAIN_APP unmodified. # BOOTLOADER indicates this app is a bootloader +# FIRMWARE_LOADER indicates this app is a firmware loader image for MCUboot # BUILD_ONLY : Mark the application as build-only. If evaluates to # true, then this application will be excluded from flashing # and debugging. @@ -329,12 +331,12 @@ function(ExternalZephyrProject_Add) set(shared_cmake_vars_argument) foreach(shared_var ${shared_cmake_variables_list}) if(DEFINED CACHE{${ZBUILD_APPLICATION}_${shared_var}}) - get_property(var_type CACHE ${ZBUILD_APPLICATION}_${shared_var} PROPERTY TYPE) + get_property(var_type CACHE ${ZBUILD_APPLICATION}_${shared_var} PROPERTY TYPE) list(APPEND shared_cmake_vars_argument "-D${shared_var}:${var_type}=$CACHE{${ZBUILD_APPLICATION}_${shared_var}}" ) elseif(DEFINED CACHE{${shared_var}}) - get_property(var_type CACHE ${shared_var} PROPERTY TYPE) + get_property(var_type CACHE ${shared_var} PROPERTY TYPE) list(APPEND shared_cmake_vars_argument "-D${shared_var}:${var_type}=$CACHE{${shared_var}}" ) @@ -385,6 +387,7 @@ function(ExternalZephyrProject_Add) BUILD_ALWAYS True USES_TERMINAL_BUILD True ) + set_property(TARGET ${ZBUILD_APPLICATION} PROPERTY APP_SOURCE_DIR ${ZBUILD_SOURCE_DIR}) set_property(TARGET ${ZBUILD_APPLICATION} PROPERTY APP_TYPE ${ZBUILD_APP_TYPE}) set_property(TARGET ${ZBUILD_APPLICATION} PROPERTY CONFIG "# sysbuild controlled configuration settings\n" @@ -447,6 +450,197 @@ function(ExternalZephyrProject_Add) endif() endfunction() +# Usage: +# ExternalZephyrVariantProject_Add(APPLICATION +# SOURCE_APP +# [SNIPPET ] +# [EXTRA_DTC_OVERLAY_FILE ] +# [EXTRA_CONF_FILE ] +# [BUILD_ONLY ] +# ) +# +# This function duplicates an existing Zephyr based build system into the multi-image +# build system with a specified modification. This will not creates the extra build targets that +# ExternalZephyrProject_Add() adds e.g. ``_menuconfig``. Note that the variant image must +# either have a ``CONF_FILE``, ``EXTRA_CONF_FILE``, ``EXTRA_DTC_OVERLAY_FILE`` or ``SNIPPET`` +# added to it or it will be invalid and image configuration will result in a fatal error. +# +# APPLICATION: : Name of the application, name will also be used for build folder +# of the application. +# SOURCE_APP : Name of the existing image to use for duplication. +# SNIPPET : List of default snippets to apply for variant image. +# EXTRA_DTC_OVERLAY_FILE : List of default extra DTC files to apply for variant image. +# EXTRA_CONF_FILE : List of default extra Kconfig fragments to apply for variant +# image. +# BUILD_ONLY : Mark the application as build-only. If evaluates to true, +# then this application will be excluded from flashing and +# debugging. +# +function(ExternalZephyrVariantProject_Add) + cmake_parse_arguments(ZBUILD "" "SOURCE_APP;APPLICATION;SNIPPET;EXTRA_DTC_OVERLAY_FILE;EXTRA_CONF_FILE;BUILD_ONLY" "" ${ARGN}) + + if(ZBUILD_UNPARSED_ARGUMENTS) + message(FATAL_ERROR + "ExternalZephyrVariantProject_Add(${ARGV0} ...) given unknown arguments:" + " ${ZBUILD_UNPARSED_ARGUMENTS}" + ) + endif() + + if(TARGET ${ZBUILD_APPLICATION}) + message(FATAL_ERROR + "ExternalZephyrVariantProject_Add(APPLICATION ${ZBUILD_APPLICATION} ...) " + "already exists. Application names must be unique." + ) + endif() + + if(NOT DEFINED ZBUILD_SOURCE_APP OR NOT TARGET ${ZBUILD_SOURCE_APP}) + message(FATAL_ERROR + "ExternalZephyrVariantProject_Add(SOURCE_APP ${ZBUILD_SOURCE_APP} ...) " + "does not exist. Existing image must already exist." + ) + endif() + + if(NOT DEFINED SYSBUILD_CURRENT_SOURCE_DIR) + message(FATAL_ERROR + "ExternalZephyrVariantProject_Add(${ARGV0} ...) must not be called outside of" + " sysbuild_add_subdirectory(). SYSBUILD_CURRENT_SOURCE_DIR is undefined." + ) + endif() + + get_target_property(ZBUILD_BOARD ${DEFAULT_IMAGE} BOARD) + get_target_property(ZBUILD_SOURCE_DIR ${DEFAULT_IMAGE} APP_SOURCE_DIR) + get_property(var_type CACHE ${ZBUILD_SOURCE_APP}_${shared_var} PROPERTY TYPE) + + set_property( + DIRECTORY "${SYSBUILD_CURRENT_SOURCE_DIR}" + APPEND PROPERTY sysbuild_images ${ZBUILD_APPLICATION} + ) + set_property( + GLOBAL + APPEND PROPERTY sysbuild_images ${ZBUILD_APPLICATION} + ) + + # Update ROOT variables with relative paths to use absolute paths based on + # the source application directory. + foreach(type MODULE_EXT BOARD SOC ARCH SCA) + if(DEFINED CACHE{${ZBUILD_APPLICATION}_${type}_ROOT} AND NOT IS_ABSOLUTE $CACHE{${ZBUILD_APPLICATION}_${type}_ROOT}) + set(rel_path $CACHE{${ZBUILD_APPLICATION}_${type}_ROOT}) + cmake_path(ABSOLUTE_PATH rel_path BASE_DIRECTORY "${ZBUILD_SOURCE_DIR}" NORMALIZE OUTPUT_VARIABLE abs_path) + set(${ZBUILD_APPLICATION}_${type}_ROOT ${abs_path} CACHE PATH "Sysbuild adjusted absolute path" FORCE) + endif() + endforeach() + + # CMake variables which must be known by all Zephyr CMake build systems + # Those are settings which controls the build and must be known to CMake at + # invocation time, and thus cannot be passed through the sysbuild cache file. + set( + shared_cmake_variables_list + CMAKE_BUILD_TYPE + CMAKE_VERBOSE_MAKEFILE + ) + + set(sysbuild_cache_file ${CMAKE_BINARY_DIR}/${ZBUILD_APPLICATION}_sysbuild_cache.txt) + set(shared_cmake_vars_argument) + + foreach(shared_var ${shared_cmake_variables_list}) + if(DEFINED CACHE{${ZBUILD_SOURCE_APP}_${shared_var}}) + get_property(var_type CACHE ${ZBUILD_SOURCE_APP}_${shared_var} PROPERTY TYPE) + list(APPEND shared_cmake_vars_argument + "-D${shared_var}:${var_type}=$CACHE{${ZBUILD_SOURCE_APP}_${shared_var}}" + ) + elseif(DEFINED CACHE{${ZBUILD_APPLICATION}_${shared_var}}) + get_property(var_type CACHE ${ZBUILD_APPLICATION}_${shared_var} PROPERTY TYPE) + list(APPEND shared_cmake_vars_argument + "-D${shared_var}:${var_type}=$CACHE{${ZBUILD_APPLICATION}_${shared_var}}" + ) + elseif(DEFINED CACHE{${shared_var}}) + get_property(var_type CACHE ${shared_var} PROPERTY TYPE) + list(APPEND shared_cmake_vars_argument + "-D${shared_var}:${var_type}=$CACHE{${shared_var}}" + ) + endif() + endforeach() + + set(list_separator ",") + + include(ExternalProject) + set(application_binary_dir ${CMAKE_BINARY_DIR}/${ZBUILD_APPLICATION}) + ExternalProject_Add( + ${ZBUILD_APPLICATION} + SOURCE_DIR ${ZBUILD_SOURCE_DIR} + BINARY_DIR ${application_binary_dir} + CONFIGURE_COMMAND "" + LIST_SEPARATOR "${list_separator}" + CMAKE_ARGS -DSYSBUILD:BOOL=True + -DSYSBUILD_CACHE:FILEPATH=${sysbuild_cache_file} + ${shared_cmake_vars_argument} + BUILD_COMMAND ${CMAKE_COMMAND} --build . + INSTALL_COMMAND "" + BUILD_ALWAYS True + USES_TERMINAL_BUILD True + ) + + get_property(${ZBUILD_SOURCE_APP}_APP_TYPE TARGET ${ZBUILD_SOURCE_APP} PROPERTY APP_TYPE) + + set_property(TARGET ${ZBUILD_APPLICATION} PROPERTY APP_TYPE ${${ZBUILD_SOURCE_APP}_APP_TYPE}) + set_property(TARGET ${ZBUILD_APPLICATION} PROPERTY CONFIG + "# sysbuild controlled configuration settings\n" + ) + set_target_properties(${ZBUILD_APPLICATION} PROPERTIES CACHE_FILE ${sysbuild_cache_file}) + set_target_properties(${ZBUILD_APPLICATION} PROPERTIES KCONFIG_BINARY_DIR + ${application_binary_dir}/Kconfig + ) + + if("${${ZBUILD_SOURCE_APP}_APP_TYPE}" STREQUAL "MAIN") + set_target_properties(${ZBUILD_APPLICATION} PROPERTIES MAIN_APP True) + endif() + + set(${ZBUILD_APPLICATION}_DTS_SOURCE ${CMAKE_BINARY_DIR}/${ZBUILD_SOURCE_APP}/zephyr/zephyr.dts + CACHE INTERNAL "Application DTC file" FORCE + ) + + set(${ZBUILD_APPLICATION}_DTS_DEPS ${CMAKE_BINARY_DIR}/${ZBUILD_SOURCE_APP}/zephyr/zephyr.dts.d + CACHE INTERNAL "Application DTC dependency file" FORCE + ) + + set(${ZBUILD_APPLICATION}_KCONFIG_VARIANT_SOURCE + ${CMAKE_BINARY_DIR}/${ZBUILD_SOURCE_APP}/zephyr/.config + CACHE INTERNAL "Application config file" FORCE + ) + + set(${ZBUILD_APPLICATION}_KCONFIG_TARGETS "KCONFIG_TARGETS-NOTFOUND" + CACHE INTERNAL "Disable Kconfig targets" FORCE + ) + + set(${ZBUILD_APPLICATION}_SNIPPET ${ZBUILD_SNIPPET} + CACHE INTERNAL "Application snippet" FORCE + ) + + set(${ZBUILD_APPLICATION}_EXTRA_DTC_OVERLAY_FILE ${ZBUILD_EXTRA_DTC_OVERLAY_FILE} + CACHE INTERNAL "Application extra DTC overlay file" FORCE + ) + + set(${ZBUILD_APPLICATION}_EXTRA_CONF_FILE ${ZBUILD_EXTRA_CONF_FILE} + CACHE INTERNAL "Application extra config file" FORCE + ) + + set_target_properties(${ZBUILD_APPLICATION} PROPERTIES IMAGE_CONF_SCRIPT "") + set_target_properties(${ZBUILD_APPLICATION} PROPERTIES APP_CLONE ${ZBUILD_SOURCE_APP}) + + if(DEFINED ZBUILD_BOARD) + # Only set image specific board if provided. + # The sysbuild BOARD is exported through sysbuild cache, and will be used + # unless _BOARD is defined. + set_target_properties(${ZBUILD_APPLICATION} PROPERTIES BOARD ${ZBUILD_BOARD}) + endif() + + if(DEFINED ZBUILD_BUILD_ONLY) + set_target_properties(${ZBUILD_APPLICATION} PROPERTIES BUILD_ONLY ${ZBUILD_BUILD_ONLY}) + endif() + + sysbuild_add_dependencies(CONFIGURE ${ZBUILD_APPLICATION} ${ZBUILD_SOURCE_APP}) +endfunction() + # Usage: # ExternalZephyrProject_Cmake(APPLICATION ) # @@ -500,18 +694,32 @@ function(ExternalZephyrProject_Cmake) ExternalProject_Get_Property(${ZCMAKE_APPLICATION} SOURCE_DIR BINARY_DIR CMAKE_ARGS LIST_SEPARATOR) get_target_property(${ZCMAKE_APPLICATION}_BOARD ${ZCMAKE_APPLICATION} BOARD) + get_target_property(${ZCMAKE_APPLICATION}_APP_CLONE ${ZCMAKE_APPLICATION} APP_CLONE) + set(dotconfigsysbuild ${BINARY_DIR}/zephyr/.config.sysbuild) + sysbuild_cache(CREATE APPLICATION ${ZCMAKE_APPLICATION}) get_property(${ZCMAKE_APPLICATION}_CONF_SCRIPT TARGET ${ZCMAKE_APPLICATION} PROPERTY IMAGE_CONF_SCRIPT ) - sysbuild_cache(CREATE APPLICATION ${ZCMAKE_APPLICATION}) + if(${ZCMAKE_APPLICATION}_APP_CLONE) + if(NOT ${ZCMAKE_APPLICATION}_CONF_SCRIPT AND NOT ${ZCMAKE_APPLICATION}_EXTRA_CONF_FILE AND NOT + ${ZCMAKE_APPLICATION}_EXTRA_DTC_OVERLAY_FILE AND NOT ${ZCMAKE_APPLICATION}_SNIPPET + ) + message(FATAL_ERROR + "${ZCMAKE_APPLICATION} is a variant application but has no CONF_SCRIPT, EXTRA_CONF_FILE, " + "EXTRA_DTC_OVERLAY_FILE or SNIPPET variables defined, which is not valid." + ) + endif() + + get_target_property(config_content ${${ZCMAKE_APPLICATION}_APP_CLONE} CONFIG) + set_property(TARGET ${ZCMAKE_APPLICATION} PROPERTY CONFIG ${config_content}) + endif() foreach(script ${${ZCMAKE_APPLICATION}_CONF_SCRIPT}) include(${script}) endforeach() - set(dotconfigsysbuild ${BINARY_DIR}/zephyr/.config.sysbuild) get_target_property(config_content ${ZCMAKE_APPLICATION} CONFIG) string(CONFIGURE "${config_content}" config_content) file(WRITE ${dotconfigsysbuild} ${config_content}) diff --git a/share/sysbuild/images/bootloader/CMakeLists.txt b/share/sysbuild/images/bootloader/CMakeLists.txt index 501a1f366f2a..243e794d7d30 100644 --- a/share/sysbuild/images/bootloader/CMakeLists.txt +++ b/share/sysbuild/images/bootloader/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2022 Nordic Semiconductor +# Copyright (c) 2022-2026 Nordic Semiconductor # # SPDX-License-Identifier: Apache-2.0 @@ -15,4 +15,12 @@ if(SB_CONFIG_BOOTLOADER_MCUBOOT) sysbuild_add_dependencies(FLASH ${DEFAULT_IMAGE} ${image}) set_config_string(${image} CONFIG_BOOT_SIGNATURE_KEY_FILE "${SB_CONFIG_BOOT_SIGNATURE_KEY_FILE}") + + if(SB_CONFIG_MCUBOOT_DIRECT_XIP_GENERATE_VARIANT) + ExternalZephyrVariantProject_Add( + APPLICATION ${DEFAULT_IMAGE}_slot1_variant + SOURCE_APP ${DEFAULT_IMAGE} + SNIPPET slot1-partition + ) + endif() endif() diff --git a/share/sysbuild/images/bootloader/Kconfig b/share/sysbuild/images/bootloader/Kconfig index a3c9bbef83a3..40790490cda6 100644 --- a/share/sysbuild/images/bootloader/Kconfig +++ b/share/sysbuild/images/bootloader/Kconfig @@ -150,6 +150,17 @@ config MCUBOOT_MODE_SINGLE_APP_RAM_LOAD endchoice +config MCUBOOT_DIRECT_XIP_GENERATE_VARIANT + bool "Generate slot 1 variant image [EXPERIMENTAL]" + depends on MCUBOOT_MODE_DIRECT_XIP || MCUBOOT_MODE_DIRECT_XIP_WITH_REVERT + select EXPERIMENTAL + default y + help + Will generate an image for the alternate partition (``slot1_partition``) which can be + used for firmware updates. This image will have the same configuration options applied + as the main image, with an extra dts overlay that changes the chosen flash partition to + slot1_partition, and will be named ``_slot_1_variant``. + config MCUBOOT_MODE_FIRMWARE_UPDATER_BOOT_MODE_ENTRANCE bool "Firmware updater retention boot mode entrance" depends on MCUBOOT_MODE_FIRMWARE_UPDATER From 43b0c9895d82ed3684d72f82d0d64cce9a71f242 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Thu, 8 Jan 2026 10:01:46 +0000 Subject: [PATCH 2190/3659] tests: boot: Add mcuboot_direct_xip test Adds a test which checks that the sysbuild slot1 variant image is generated, and ensures that it boots properly when both images are present or when only the second image is present Signed-off-by: Jamie McCrae --- tests/boot/mcuboot_direct_xip/CMakeLists.txt | 15 +++++++ .../boot/mcuboot_direct_xip/Kconfig.sysbuild | 10 +++++ tests/boot/mcuboot_direct_xip/prj.conf | 1 + tests/boot/mcuboot_direct_xip/sysbuild.cmake | 11 +++++ tests/boot/mcuboot_direct_xip/sysbuild.conf | 2 + tests/boot/mcuboot_direct_xip/testcase.yaml | 44 +++++++++++++++++++ 6 files changed, 83 insertions(+) create mode 100644 tests/boot/mcuboot_direct_xip/CMakeLists.txt create mode 100644 tests/boot/mcuboot_direct_xip/Kconfig.sysbuild create mode 100644 tests/boot/mcuboot_direct_xip/prj.conf create mode 100644 tests/boot/mcuboot_direct_xip/sysbuild.cmake create mode 100644 tests/boot/mcuboot_direct_xip/sysbuild.conf create mode 100644 tests/boot/mcuboot_direct_xip/testcase.yaml diff --git a/tests/boot/mcuboot_direct_xip/CMakeLists.txt b/tests/boot/mcuboot_direct_xip/CMakeLists.txt new file mode 100644 index 000000000000..2ccbb8c2daaf --- /dev/null +++ b/tests/boot/mcuboot_direct_xip/CMakeLists.txt @@ -0,0 +1,15 @@ +# +# Copyright (c) 2026 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 +# + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(mcuboot_direct_xip) + +if(NOT (DEFINED SYSBUILD)) + message(FATAL_ERROR "This test must be built with sysbuild.") +endif() + +target_sources(app PRIVATE ${ZEPHYR_BASE}/samples/hello_world/src/main.c) diff --git a/tests/boot/mcuboot_direct_xip/Kconfig.sysbuild b/tests/boot/mcuboot_direct_xip/Kconfig.sysbuild new file mode 100644 index 000000000000..61978640f512 --- /dev/null +++ b/tests/boot/mcuboot_direct_xip/Kconfig.sysbuild @@ -0,0 +1,10 @@ +# +# Copyright (c) 2026 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 +# + +config SLOT0_IMAGE_BUILD_ONLY + bool "Slot0 image build only" + +source "share/sysbuild/Kconfig" diff --git a/tests/boot/mcuboot_direct_xip/prj.conf b/tests/boot/mcuboot_direct_xip/prj.conf new file mode 100644 index 000000000000..b2a4ba591044 --- /dev/null +++ b/tests/boot/mcuboot_direct_xip/prj.conf @@ -0,0 +1 @@ +# nothing here diff --git a/tests/boot/mcuboot_direct_xip/sysbuild.cmake b/tests/boot/mcuboot_direct_xip/sysbuild.cmake new file mode 100644 index 000000000000..75e7ba2d8f9e --- /dev/null +++ b/tests/boot/mcuboot_direct_xip/sysbuild.cmake @@ -0,0 +1,11 @@ +# +# Copyright (c) 2026 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 +# + +if(SB_CONFIG_SLOT0_IMAGE_BUILD_ONLY) + set_target_properties(${DEFAULT_IMAGE} PROPERTIES BUILD_ONLY y) +else() + set_target_properties(${DEFAULT_IMAGE} PROPERTIES BUILD_ONLY n) +endif() diff --git a/tests/boot/mcuboot_direct_xip/sysbuild.conf b/tests/boot/mcuboot_direct_xip/sysbuild.conf new file mode 100644 index 000000000000..06c8ad027910 --- /dev/null +++ b/tests/boot/mcuboot_direct_xip/sysbuild.conf @@ -0,0 +1,2 @@ +SB_CONFIG_BOOTLOADER_MCUBOOT=y +SB_CONFIG_MCUBOOT_MODE_DIRECT_XIP=y diff --git a/tests/boot/mcuboot_direct_xip/testcase.yaml b/tests/boot/mcuboot_direct_xip/testcase.yaml new file mode 100644 index 000000000000..d546688af16f --- /dev/null +++ b/tests/boot/mcuboot_direct_xip/testcase.yaml @@ -0,0 +1,44 @@ +# +# Copyright (c) 2026 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 +# + +common: + sysbuild: true + timeout: 10 + harness: console + platform_allow: + - nrf52840dk/nrf52840 + integration_platforms: + - nrf52840dk/nrf52840 + tags: + - mcuboot + - sysbuild +tests: + bootloader.mcuboot.direct.xip: + harness_config: + type: multi_line + regex: + - "Starting Direct-XIP bootloader" + - "Primary slot: version=0.0.0+0" + - "Secondary slot: version=0.0.0+0" + - "Image 0 loaded from the primary slot" + - "Bootloader chainload address offset" + - "Image version: v0.0.0" + - "Jumping to the image slot" + - "Hello World" + bootloader.mcuboot.direct.xip.slot1.only: + extra_args: + - SB_CONFIG_SLOT0_IMAGE_BUILD_ONLY=y + harness_config: + type: multi_line + regex: + - "Starting Direct-XIP bootloader" + - "Image 0 Primary slot: Image not found" + - "Secondary slot: version=0.0.0+0" + - "Image 0 loaded from the secondary slot" + - "Bootloader chainload address offset" + - "Image version: v0.0.0" + - "Jumping to the image slot" + - "Hello World" From 78772ba863be45865fcf9efc8b462f372ea6a8e0 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Thu, 8 Jan 2026 10:26:56 +0000 Subject: [PATCH 2191/3659] doc: build: sysbuild: Add details on variant images Adds details about the ``ExternalZephyrVariantProject_Add`` sysbuild function which has been newly added, that allows for creating variant images Signed-off-by: Jamie McCrae --- doc/build/sysbuild/index.rst | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/doc/build/sysbuild/index.rst b/doc/build/sysbuild/index.rst index 1d1e0185b882..c347fbb5a591 100644 --- a/doc/build/sysbuild/index.rst +++ b/doc/build/sysbuild/index.rst @@ -512,6 +512,14 @@ applications as sysbuild domains. Call this CMake function from your application's :file:`sysbuild.cmake` file, or any other CMake file you know will run as part sysbuild CMake invocation. +A variant image can also added using the ``ExternalZephyrVariantProject_Add()`` function which +will duplicate an existing image in the sysbuild project, and allows for slight differences in +configuration. An example use case for this feature is to change the chosen flash node of an image +but having the rest of the configuration identical to the base image. When this is used, neither +sysbuild itself nor the image will have the extra Kconfig targets made for it such as menuconfig, +guiconfig, hardenconfig or traceconfig, as the base image can be used for viewing/adjusting +these instead. + Targeting the same board ======================== From 58f9d5e6c35b5ef87aafcb1fe0306021199a4f15 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Thu, 8 Jan 2026 10:28:57 +0000 Subject: [PATCH 2192/3659] doc: releases: release-notes: 4.4: Add notes on new bits Adds a new on the newly introduced sysbuild variant image feature and a new slot1-partition snippet Signed-off-by: Jamie McCrae --- doc/releases/release-notes-4.4.rst | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/doc/releases/release-notes-4.4.rst b/doc/releases/release-notes-4.4.rst index 1742b0235f2d..b75b99cc4cb2 100644 --- a/doc/releases/release-notes-4.4.rst +++ b/doc/releases/release-notes-4.4.rst @@ -145,11 +145,21 @@ New APIs and options * Build system + * Added :ref:`slot1-partition ` snippet. + * Sysbuild * Added :kconfig:option:`SB_CONFIG_MERGED_HEX_FILES` which allows generating :ref:`merged hex files `. + * Added experimental ``ExternalZephyrVariantProject_Add()`` sysbuild CMake function which + allows for adding :ref:`variant images` to projects which are + based on existing images in a build. + + * Added :kconfig:option:`SB_CONFIG_MCUBOOT_DIRECT_XIP_GENERATE_VARIANT` which allows for + generating slot 1 images automatically in sysbuild projects when using MCUboot in + direct-xip mode. + * Ethernet * Driver MAC address configuration with support for NVMEM cell. From fd6fdb817f5539c547876296f51b8bda3a1f1016 Mon Sep 17 00:00:00 2001 From: Jiafei Pan Date: Tue, 9 Dec 2025 11:04:05 +0800 Subject: [PATCH 2193/3659] boards: frdm_imx91: add J-Link runner support Added J-Link runner to support west flash and west debug. Signed-off-by: Jiafei Pan --- boards/nxp/frdm_imx91/board.cmake | 7 ++++ boards/nxp/frdm_imx91/doc/index.rst | 58 +++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+) create mode 100644 boards/nxp/frdm_imx91/board.cmake diff --git a/boards/nxp/frdm_imx91/board.cmake b/boards/nxp/frdm_imx91/board.cmake new file mode 100644 index 000000000000..aef990660faf --- /dev/null +++ b/boards/nxp/frdm_imx91/board.cmake @@ -0,0 +1,7 @@ +# +# SPDX-FileCopyrightText: Copyright 2026 NXP +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(jlink "--device=MIMX9131" "--no-reset" "--flash-sram") + +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/nxp/frdm_imx91/doc/index.rst b/boards/nxp/frdm_imx91/doc/index.rst index a4c628cd81ce..4997665812a8 100644 --- a/boards/nxp/frdm_imx91/doc/index.rst +++ b/boards/nxp/frdm_imx91/doc/index.rst @@ -104,6 +104,13 @@ uSDHC2 for testing: Programming and Debugging ************************* +.. zephyr:board-supported-runners:: + +There are multiple methods to program and debug Zephyr + +Option 1. Boot Zephyr by Using U-Boot Command +============================================= + U-Boot "go" command is used to load and kick Zephyr to Cortex-A55 Core. Stop the board at U-Boot command line, then need to download Zephyr binary image into @@ -149,4 +156,55 @@ display the following console output: thread_a: Hello World from cpu 0 on frdm_imx91! thread_b: Hello World from cpu 0 on frdm_imx91! +Option 2. Boot Zephyr by Using JLink Runner +=========================================== + +Hardware Setup +-------------- + +The default runner for the board is JLink runner, there is one SWD connnector P14 on +the FRDM-IMX91 board, connect P14 to J-Link debugger with Pin1 of P14 connect to SWDCLK, +Pin2 of P14 connect to SWDIO, and Pin3 of P14 connect to GND, the VCC of J-Link debugger +could connect to P1 of P12 connector. + +Flash and Run +------------- + +Power up the board and stop the board at U-Boot command line. + +Then use "west flash" command to load the zephyr.bin image from the host computer and +start the Zephyr application on A55 core. + +Here is an example for the :zephyr:code-sample:`hello_world` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :host-os: unix + :board: frdm_imx91/mimx9131 + :goals: flash + +Then the following log could be found on UART1 console: + +.. code-block:: console + + + *** Booting Zephyr OS build v4.3.0-1976-g8f0df404c2ee *** + Hello World! frdm_imx91/mimx9131 + +Debug +----- + +Power up the board and stop the board at U-Boot command line. + +Then use "west debug" command to load the zephyr.bin image from the host computer and +debug the Zephyr application on A55 core. + +Here is an example for the :zephyr:code-sample:`hello_world` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :host-os: unix + :board: frdm_imx91/mimx9131 + :goals: debug + .. include:: ../../common/board-footer.rst.inc From ec8205162fcc1d7c50313489a8e55f6d29bdd8fd Mon Sep 17 00:00:00 2001 From: Jiafei Pan Date: Tue, 9 Dec 2025 11:34:23 +0800 Subject: [PATCH 2194/3659] boards: frdm_imx93: add J-Link runner support Added J-Link runner to support west flash and west debug. Signed-off-by: Jiafei Pan --- boards/nxp/frdm_imx93/board.cmake | 11 +++++ boards/nxp/frdm_imx93/doc/index.rst | 64 +++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 boards/nxp/frdm_imx93/board.cmake diff --git a/boards/nxp/frdm_imx93/board.cmake b/boards/nxp/frdm_imx93/board.cmake new file mode 100644 index 000000000000..8e6c3322b769 --- /dev/null +++ b/boards/nxp/frdm_imx93/board.cmake @@ -0,0 +1,11 @@ +# +# SPDX-FileCopyrightText: Copyright 2026 NXP +# SPDX-License-Identifier: Apache-2.0 + +if(CONFIG_SOC_MIMX9352_A55) + +board_runner_args(jlink "--device=MIMX9352_A55_0" "--no-reset" "--flash-sram") + +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) + +endif() diff --git a/boards/nxp/frdm_imx93/doc/index.rst b/boards/nxp/frdm_imx93/doc/index.rst index 3bfbc071c254..1b61cebe2a94 100644 --- a/boards/nxp/frdm_imx93/doc/index.rst +++ b/boards/nxp/frdm_imx93/doc/index.rst @@ -122,6 +122,13 @@ Note: The overlay only supports ``mimx9352/a55``, but can be extended to support Programming and Debugging (A55) ******************************* +.. zephyr:board-supported-runners:: + +There are multiple methods to program and debug Zephyr + +Option 1. Boot Zephyr by Using U-Boot Command +============================================= + U-Boot "cpu" command is used to load and kick Zephyr to Cortex-A secondary Core, Currently it is supported in : `Real-Time Edge U-Boot`_ (use the branch "uboot_vxxxx.xx-y.y.y, xxxx.xx is uboot version and y.y.y is Real-Time Edge Software version, for example @@ -171,6 +178,63 @@ display the following console output: thread_a: Hello World from cpu 0 on frdm_imx93! thread_b: Hello World from cpu 0 on frdm_imx93! +Option 2. Boot Zephyr by Using JLink Runner +=========================================== + +Hardware Setup +-------------- + + +The default runner for the board is JLink runner, there is one SWD connnector P14 on +the FRDM-IMX93 board. + +Refer to `NXP online document`_ to rework FRDM-IMX93 board and connect SWD connector P14 +to J-Link debugger. + +.. _NXP online document: + https://community.nxp.com/t5/FRDM-Training-Hub/How-to-use-J-link-on-FRDM-IMX93/ta-p/2122902 + + +Flash and Run +------------- + +Power up the board and stop the board at U-Boot command line. + +Then use "west flash" command to load the zephyr.bin image from the host computer and +start the Zephyr application on A55 core. + +Here is an example for the :zephyr:code-sample:`hello_world` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :host-os: unix + :board: frdm_imx93/mimx9352/a55 + :goals: flash + +Then the following log could be found on UART1 console: + +.. code-block:: console + + + *** Booting Zephyr OS build v4.3.0-1976-g8f0df404c2ee *** + Hello World! frdm_imx93/mimx9352 + +Debug +----- + +Power up the board and stop the board at U-Boot command line. + +Then use "west debug" command to load the zephyr.bin image from the host computer and +debug the Zephyr application on A55 core. + +Here is an example for the :zephyr:code-sample:`hello_world` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :host-os: unix + :board: frdm_imx93/mimx9352/a55 + :goals: debug + System Reboot (A55) =================== From 253336c3963b89953ef7ba0730302b9b567567d3 Mon Sep 17 00:00:00 2001 From: James Roy Date: Fri, 9 Jan 2026 23:51:51 +0800 Subject: [PATCH 2195/3659] doc: Add dt api documentation for nvmem Add devicetree API documentation for nvmem, it's located in `api.html#hardware-specific-apis`. Signed-off-by: James Roy --- doc/build/dts/api/api.rst | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/doc/build/dts/api/api.rst b/doc/build/dts/api/api.rst index 0a7296831d93..ce011e202f35 100644 --- a/doc/build/dts/api/api.rst +++ b/doc/build/dts/api/api.rst @@ -296,6 +296,16 @@ and properties related to them. .. doxygengroup:: devicetree-mbox +.. _devicetree-nvmem-api: + +NVMEM +===== + +These conveniences may be used for nodes which describe Non-Volatile +Memory, and properties related to them. + +.. doxygengroup:: devicetree-nvmem + .. _devicetree-pinctrl-api: Pinctrl (pin control) From 9c6cc7d6cb32057f7584bc38b53be055f7783f35 Mon Sep 17 00:00:00 2001 From: James Roy Date: Fri, 9 Jan 2026 23:52:40 +0800 Subject: [PATCH 2196/3659] doc: Add dt api documentation for display Add devicetree API documentation for display, it's located in `api.html#hardware-specific-apis`. Signed-off-by: James Roy --- doc/build/dts/api/api.rst | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/doc/build/dts/api/api.rst b/doc/build/dts/api/api.rst index ce011e202f35..9a8499da588f 100644 --- a/doc/build/dts/api/api.rst +++ b/doc/build/dts/api/api.rst @@ -257,6 +257,16 @@ controllers or channels, and properties related to them. .. doxygengroup:: devicetree-dmas +.. _devicetree-display-api: + +Display +======= + +These conveniences may be used for nodes which describe display +controllers, and properties related to them. + +.. doxygengroup:: devicetree-display + .. _devicetree-flash-api: Fixed flash partitions From 2faf427d6a34309010142beca0534d0af3f9c5de Mon Sep 17 00:00:00 2001 From: James Roy Date: Fri, 9 Jan 2026 23:53:44 +0800 Subject: [PATCH 2197/3659] doc: Add dt api documentation for ordinals Add devicetree API documentation for ordinals, it's located in `api.html#hardware-specific-apis`. Signed-off-by: James Roy --- doc/build/dts/api/api.rst | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/doc/build/dts/api/api.rst b/doc/build/dts/api/api.rst index 9a8499da588f..22c85c19cd68 100644 --- a/doc/build/dts/api/api.rst +++ b/doc/build/dts/api/api.rst @@ -316,6 +316,16 @@ Memory, and properties related to them. .. doxygengroup:: devicetree-nvmem +.. _devicetree-ordinals-api: + +Ordinals +======== + +These conveniences may be used for nodes which describe Dependency +tracking, and properties related to them. + +.. doxygengroup:: devicetree-dep-ord + .. _devicetree-pinctrl-api: Pinctrl (pin control) From 34a6cac24c0b2c6fdcd562bbb1821be42d1fd3b9 Mon Sep 17 00:00:00 2001 From: James Roy Date: Fri, 9 Jan 2026 23:56:34 +0800 Subject: [PATCH 2198/3659] doc: Add dt api documentation for hwspinlock Add devicetree API documentation for hwspinlock, it's located in `api.html#hardware-specific-apis`. Signed-off-by: James Roy --- doc/build/dts/api/api.rst | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/doc/build/dts/api/api.rst b/doc/build/dts/api/api.rst index 22c85c19cd68..6a65e4924a64 100644 --- a/doc/build/dts/api/api.rst +++ b/doc/build/dts/api/api.rst @@ -288,6 +288,16 @@ and properties related to them. .. doxygengroup:: devicetree-gpio +.. _devicetree-hwspinlock-api: + +HWSpinlock +========== + +These conveniences may be used for nodes which describe hardware spinlock, +and properties related to them. + +.. doxygengroup:: devicetree-hwspinlock + IO channels =========== From e830376b71299c02e1f9ee3b1050c63a65a0f2ce Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Fri, 9 Jan 2026 11:25:56 +0000 Subject: [PATCH 2199/3659] mgmt: mcumgr: Refactor callback header files Refactors these so that each group defines the events it raises Signed-off-by: Jamie McCrae --- .../grp/enum_mgmt/enum_mgmt_callbacks.h | 11 ++ .../mcumgr/grp/fs_mgmt/fs_mgmt_callbacks.h | 14 ++ .../mcumgr/grp/img_mgmt/img_mgmt_callbacks.h | 44 +++++ .../mcumgr/grp/os_mgmt/os_mgmt_callbacks.h | 29 +++ .../settings_mgmt/settings_mgmt_callbacks.h | 11 ++ .../mgmt/mcumgr/mgmt/callback_defines.h | 86 +++++++++ include/zephyr/mgmt/mcumgr/mgmt/callbacks.h | 179 +----------------- 7 files changed, 202 insertions(+), 172 deletions(-) create mode 100644 include/zephyr/mgmt/mcumgr/mgmt/callback_defines.h diff --git a/include/zephyr/mgmt/mcumgr/grp/enum_mgmt/enum_mgmt_callbacks.h b/include/zephyr/mgmt/mcumgr/grp/enum_mgmt/enum_mgmt_callbacks.h index f6584c931abd..4612e323a95f 100644 --- a/include/zephyr/mgmt/mcumgr/grp/enum_mgmt/enum_mgmt_callbacks.h +++ b/include/zephyr/mgmt/mcumgr/grp/enum_mgmt/enum_mgmt_callbacks.h @@ -19,6 +19,17 @@ extern "C" { * @{ */ +/** + * MGMT event opcodes for enumeration management group. + */ +enum enum_mgmt_group_events { + /** Callback when fetching details on supported command groups. */ + MGMT_EVT_OP_ENUM_MGMT_DETAILS = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_ENUM, 0), + + /** Used to enable all enum_mgmt_group events. */ + MGMT_EVT_OP_ENUM_MGMT_ALL = MGMT_DEF_EVT_OP_ALL(MGMT_EVT_GRP_ENUM), +}; + /** * Structure provided in the #MGMT_EVT_OP_ENUM_MGMT_DETAILS notification callback: This callback * function is called once per command group when the detail command is used, it can be used to diff --git a/include/zephyr/mgmt/mcumgr/grp/fs_mgmt/fs_mgmt_callbacks.h b/include/zephyr/mgmt/mcumgr/grp/fs_mgmt/fs_mgmt_callbacks.h index b903d865ba93..512db752685c 100644 --- a/include/zephyr/mgmt/mcumgr/grp/fs_mgmt/fs_mgmt_callbacks.h +++ b/include/zephyr/mgmt/mcumgr/grp/fs_mgmt/fs_mgmt_callbacks.h @@ -20,6 +20,20 @@ extern "C" { * @{ */ +/** + * MGMT event opcodes for filesystem management group. + */ +enum fs_mgmt_group_events { + /** Callback when a file has been accessed, data is @ref fs_mgmt_file_access. */ + MGMT_EVT_OP_FS_MGMT_FILE_ACCESS = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_FS, 0), + + /** Callback when a file upload/download is finished, data is @ref fs_mgmt_file_access. */ + MGMT_EVT_OP_FS_MGMT_FILE_ACCESS_DONE = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_FS, 1), + + /** Used to enable all fs_mgmt_group events. */ + MGMT_EVT_OP_FS_MGMT_ALL = MGMT_DEF_EVT_OP_ALL(MGMT_EVT_GRP_FS), +}; + /** The type of operation that is being requested for a given file access callback. */ enum fs_mgmt_file_access_types { /** Access to read file (file download). */ diff --git a/include/zephyr/mgmt/mcumgr/grp/img_mgmt/img_mgmt_callbacks.h b/include/zephyr/mgmt/mcumgr/grp/img_mgmt/img_mgmt_callbacks.h index 73d942eaf82f..442aa38f656e 100644 --- a/include/zephyr/mgmt/mcumgr/grp/img_mgmt/img_mgmt_callbacks.h +++ b/include/zephyr/mgmt/mcumgr/grp/img_mgmt/img_mgmt_callbacks.h @@ -28,6 +28,50 @@ struct img_mgmt_upload_req; * @{ */ +/** + * MGMT event opcodes for image management group. + */ +enum img_mgmt_group_events { + /** Callback when a client sends a file upload chunk, data is @ref img_mgmt_upload_check. */ + MGMT_EVT_OP_IMG_MGMT_DFU_CHUNK = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_IMG, 0), + + /** Callback when a DFU operation is stopped. */ + MGMT_EVT_OP_IMG_MGMT_DFU_STOPPED = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_IMG, 1), + + /** Callback when a DFU operation is started. */ + MGMT_EVT_OP_IMG_MGMT_DFU_STARTED = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_IMG, 2), + + /** Callback when a DFU operation has finished being transferred. */ + MGMT_EVT_OP_IMG_MGMT_DFU_PENDING = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_IMG, 3), + + /** Callback when an image has been confirmed. data is @ref img_mgmt_image_confirmed. */ + MGMT_EVT_OP_IMG_MGMT_DFU_CONFIRMED = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_IMG, 4), + + /** Callback when an image write command has finished writing to flash. */ + MGMT_EVT_OP_IMG_MGMT_DFU_CHUNK_WRITE_COMPLETE = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_IMG, 5), + + /** + * Callback when an image slot's state is encoded for a response, data is + * @ref img_mgmt_state_slot_encode. + */ + MGMT_EVT_OP_IMG_MGMT_IMAGE_SLOT_STATE = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_IMG, 6), + + /** + * Callback when a slot list command outputs fields for an image, data is + * @ref img_mgmt_slot_info_image. + */ + MGMT_EVT_OP_IMG_MGMT_SLOT_INFO_IMAGE = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_IMG, 7), + + /** + * Callback when a slot list command outputs fields for a slot of an image, data is + * @ref img_mgmt_slot_info_slot. + */ + MGMT_EVT_OP_IMG_MGMT_SLOT_INFO_SLOT = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_IMG, 8), + + /** Used to enable all img_mgmt_group events. */ + MGMT_EVT_OP_IMG_MGMT_ALL = MGMT_DEF_EVT_OP_ALL(MGMT_EVT_GRP_IMG), +}; + /** * Structure provided in the #MGMT_EVT_OP_IMG_MGMT_DFU_CHUNK notification callback: This callback * function is used to notify the application about a pending firmware upload packet from a client diff --git a/include/zephyr/mgmt/mcumgr/grp/os_mgmt/os_mgmt_callbacks.h b/include/zephyr/mgmt/mcumgr/grp/os_mgmt/os_mgmt_callbacks.h index b5c50e2f16e2..06970a17e8f9 100644 --- a/include/zephyr/mgmt/mcumgr/grp/os_mgmt/os_mgmt_callbacks.h +++ b/include/zephyr/mgmt/mcumgr/grp/os_mgmt/os_mgmt_callbacks.h @@ -19,6 +19,35 @@ extern "C" { * @{ */ +/** + * MGMT event opcodes for operating system management group. + */ +enum os_mgmt_group_events { + /** Callback when a reset command has been received, data is @ref os_mgmt_reset_data. */ + MGMT_EVT_OP_OS_MGMT_RESET = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_OS, 0), + + /** Callback when an info command is processed, data is @ref os_mgmt_info_check. */ + MGMT_EVT_OP_OS_MGMT_INFO_CHECK = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_OS, 1), + + /** Callback when an info command needs to output data, data is @ref os_mgmt_info_append. */ + MGMT_EVT_OP_OS_MGMT_INFO_APPEND = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_OS, 2), + + /** Callback when a datetime get command has been received. */ + MGMT_EVT_OP_OS_MGMT_DATETIME_GET = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_OS, 3), + + /** Callback when a datetime set command has been received, data is @ref rtc_time. */ + MGMT_EVT_OP_OS_MGMT_DATETIME_SET = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_OS, 4), + + /** + * Callback when a bootloader info command has been received, data is + * os_mgmt_bootloader_info_data(). + */ + MGMT_EVT_OP_OS_MGMT_BOOTLOADER_INFO = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_OS, 5), + + /** Used to enable all os_mgmt_group events. */ + MGMT_EVT_OP_OS_MGMT_ALL = MGMT_DEF_EVT_OP_ALL(MGMT_EVT_GRP_OS), +}; + /** * Structure provided in the #MGMT_EVT_OP_OS_MGMT_RESET notification callback: This callback * function is used to notify the application about a pending device reboot request and to diff --git a/include/zephyr/mgmt/mcumgr/grp/settings_mgmt/settings_mgmt_callbacks.h b/include/zephyr/mgmt/mcumgr/grp/settings_mgmt/settings_mgmt_callbacks.h index 03d257d857c6..2c540bd55cd4 100644 --- a/include/zephyr/mgmt/mcumgr/grp/settings_mgmt/settings_mgmt_callbacks.h +++ b/include/zephyr/mgmt/mcumgr/grp/settings_mgmt/settings_mgmt_callbacks.h @@ -19,6 +19,17 @@ extern "C" { * @{ */ +/** + * MGMT event opcodes for settings management group. + */ +enum settings_mgmt_group_events { + /** Callback when a setting is read/written/deleted. */ + MGMT_EVT_OP_SETTINGS_MGMT_ACCESS = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_SETTINGS, 0), + + /** Used to enable all settings_mgmt_group events. */ + MGMT_EVT_OP_SETTINGS_MGMT_ALL = MGMT_DEF_EVT_OP_ALL(MGMT_EVT_GRP_SETTINGS), +}; + /** * @name Settings access types * @{ diff --git a/include/zephyr/mgmt/mcumgr/mgmt/callback_defines.h b/include/zephyr/mgmt/mcumgr/mgmt/callback_defines.h new file mode 100644 index 000000000000..40921dbbf834 --- /dev/null +++ b/include/zephyr/mgmt/mcumgr/mgmt/callback_defines.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2026 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef H_MCUMGR_CALLBACK_DEFINES_ +#define H_MCUMGR_CALLBACK_DEFINES_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief MCUmgr Callback API + * @defgroup mcumgr_callback_api Callbacks + * @ingroup mcumgr + * @{ + */ + +/** @cond INTERNAL_HIDDEN */ +/** Event which signifies that all event IDs for a particular group should be enabled. */ +#define MGMT_EVT_OP_ID_ALL 0xffff + +/** Get event for a particular group and event ID. */ +#define MGMT_DEF_EVT_OP_ID(group, event_id) ((group << 16) | BIT(event_id)) + +/** Get event used for enabling all event IDs of a particular group. */ +#define MGMT_DEF_EVT_OP_ALL(group) ((group << 16) | MGMT_EVT_OP_ID_ALL) +/** @endcond */ + +/** Get group from event. */ +#define MGMT_EVT_GET_GROUP(event) ((event >> 16) & MGMT_EVT_OP_ID_ALL) + +/** Get event ID from event. */ +#define MGMT_EVT_GET_ID(event) (event & MGMT_EVT_OP_ID_ALL) + +/** + * MGMT event callback return value. + */ +enum mgmt_cb_return { + /** No error. */ + MGMT_CB_OK, + + /** SMP protocol error and ``err_rc`` contains the #mcumgr_err_t error code. */ + MGMT_CB_ERROR_RC, + + /** + * Group (application-level) error and ``err_group`` contains the group ID that caused + * the error and ``err_rc`` contains the error code of that group to return. + */ + MGMT_CB_ERROR_ERR, +}; + +/** + * MGMT event callback group IDs. Note that this is not a 1:1 mapping with #mcumgr_group_t values. + */ +enum mgmt_cb_groups { + MGMT_EVT_GRP_ALL = 0, + MGMT_EVT_GRP_SMP, + MGMT_EVT_GRP_OS, + MGMT_EVT_GRP_IMG, + MGMT_EVT_GRP_FS, + MGMT_EVT_GRP_SETTINGS, + MGMT_EVT_GRP_ENUM, + + MGMT_EVT_GRP_USER_CUSTOM_START = MGMT_GROUP_ID_PERUSER, +}; + +/** + * MGMT event opcodes for all command processing. + */ +enum smp_all_events { + /** Used to enable all events. */ + MGMT_EVT_OP_ALL = MGMT_DEF_EVT_OP_ALL(MGMT_EVT_GRP_ALL), +}; + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* H_MCUMGR_CALLBACK_DEFINES_ */ diff --git a/include/zephyr/mgmt/mcumgr/mgmt/callbacks.h b/include/zephyr/mgmt/mcumgr/mgmt/callbacks.h index 831aceda71f1..6b3662c75cb7 100644 --- a/include/zephyr/mgmt/mcumgr/mgmt/callbacks.h +++ b/include/zephyr/mgmt/mcumgr/mgmt/callbacks.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022-2023 Nordic Semiconductor ASA + * Copyright (c) 2022-2026 Nordic Semiconductor ASA * * SPDX-License-Identifier: Apache-2.0 */ @@ -10,24 +10,25 @@ #include #include #include +#include "callback_defines.h" -#ifdef CONFIG_MCUMGR_GRP_FS +#if defined(CONFIG_MCUMGR_GRP_FS) || defined(__DOXYGEN__) #include #endif -#ifdef CONFIG_MCUMGR_GRP_IMG +#if defined(CONFIG_MCUMGR_GRP_IMG) || defined(__DOXYGEN__) #include #endif -#ifdef CONFIG_MCUMGR_GRP_OS +#if defined(CONFIG_MCUMGR_GRP_OS) || defined(__DOXYGEN__) #include #endif -#ifdef CONFIG_MCUMGR_GRP_SETTINGS +#if defined(CONFIG_MCUMGR_GRP_SETTINGS) || defined(__DOXYGEN__) #include #endif -#ifdef CONFIG_MCUMGR_GRP_ENUM +#if defined(CONFIG_MCUMGR_GRP_ENUM) || defined(__DOXYGEN__) #include #endif @@ -42,40 +43,6 @@ extern "C" { * @{ */ -/** @cond INTERNAL_HIDDEN */ -/** Event which signifies that all event IDs for a particular group should be enabled. */ -#define MGMT_EVT_OP_ID_ALL 0xffff - -/** Get event for a particular group and event ID. */ -#define MGMT_DEF_EVT_OP_ID(group, event_id) ((group << 16) | BIT(event_id)) - -/** Get event used for enabling all event IDs of a particular group. */ -#define MGMT_DEF_EVT_OP_ALL(group) ((group << 16) | MGMT_EVT_OP_ID_ALL) -/** @endcond */ - -/** Get group from event. */ -#define MGMT_EVT_GET_GROUP(event) ((event >> 16) & MGMT_EVT_OP_ID_ALL) - -/** Get event ID from event. */ -#define MGMT_EVT_GET_ID(event) (event & MGMT_EVT_OP_ID_ALL) - -/** - * MGMT event callback return value. - */ -enum mgmt_cb_return { - /** No error. */ - MGMT_CB_OK, - - /** SMP protocol error and ``err_rc`` contains the #mcumgr_err_t error code. */ - MGMT_CB_ERROR_RC, - - /** - * Group (application-level) error and ``err_group`` contains the group ID that caused - * the error and ``err_rc`` contains the error code of that group to return. - */ - MGMT_CB_ERROR_ERR, -}; - /** * @typedef mgmt_cb * @brief Function to be called on MGMT notification/event. @@ -109,29 +76,6 @@ typedef enum mgmt_cb_return (*mgmt_cb)(uint32_t event, enum mgmt_cb_return prev_ int32_t *rc, uint16_t *group, bool *abort_more, void *data, size_t data_size); -/** - * MGMT event callback group IDs. Note that this is not a 1:1 mapping with #mcumgr_group_t values. - */ -enum mgmt_cb_groups { - MGMT_EVT_GRP_ALL = 0, - MGMT_EVT_GRP_SMP, - MGMT_EVT_GRP_OS, - MGMT_EVT_GRP_IMG, - MGMT_EVT_GRP_FS, - MGMT_EVT_GRP_SETTINGS, - MGMT_EVT_GRP_ENUM, - - MGMT_EVT_GRP_USER_CUSTOM_START = MGMT_GROUP_ID_PERUSER, -}; - -/** - * MGMT event opcodes for all command processing. - */ -enum smp_all_events { - /** Used to enable all events. */ - MGMT_EVT_OP_ALL = MGMT_DEF_EVT_OP_ALL(MGMT_EVT_GRP_ALL), -}; - /** * MGMT event opcodes for base SMP command processing. */ @@ -149,115 +93,6 @@ enum smp_group_events { MGMT_EVT_OP_CMD_ALL = MGMT_DEF_EVT_OP_ALL(MGMT_EVT_GRP_SMP), }; -/** - * MGMT event opcodes for filesystem management group. - */ -enum fs_mgmt_group_events { - /** Callback when a file has been accessed, data is @ref fs_mgmt_file_access. */ - MGMT_EVT_OP_FS_MGMT_FILE_ACCESS = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_FS, 0), - - /** Callback when a file upload/download is finished, data is @ref fs_mgmt_file_access. */ - MGMT_EVT_OP_FS_MGMT_FILE_ACCESS_DONE = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_FS, 1), - - /** Used to enable all fs_mgmt_group events. */ - MGMT_EVT_OP_FS_MGMT_ALL = MGMT_DEF_EVT_OP_ALL(MGMT_EVT_GRP_FS), -}; - -/** - * MGMT event opcodes for image management group. - */ -enum img_mgmt_group_events { - /** Callback when a client sends a file upload chunk, data is @ref img_mgmt_upload_check. */ - MGMT_EVT_OP_IMG_MGMT_DFU_CHUNK = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_IMG, 0), - - /** Callback when a DFU operation is stopped. */ - MGMT_EVT_OP_IMG_MGMT_DFU_STOPPED = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_IMG, 1), - - /** Callback when a DFU operation is started. */ - MGMT_EVT_OP_IMG_MGMT_DFU_STARTED = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_IMG, 2), - - /** Callback when a DFU operation has finished being transferred. */ - MGMT_EVT_OP_IMG_MGMT_DFU_PENDING = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_IMG, 3), - - /** Callback when an image has been confirmed. data is @ref img_mgmt_image_confirmed. */ - MGMT_EVT_OP_IMG_MGMT_DFU_CONFIRMED = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_IMG, 4), - - /** Callback when an image write command has finished writing to flash. */ - MGMT_EVT_OP_IMG_MGMT_DFU_CHUNK_WRITE_COMPLETE = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_IMG, 5), - - /** - * Callback when an image slot's state is encoded for a response, data is - * @ref img_mgmt_state_slot_encode. - */ - MGMT_EVT_OP_IMG_MGMT_IMAGE_SLOT_STATE = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_IMG, 6), - - /** - * Callback when a slot list command outputs fields for an image, data is - * @ref img_mgmt_slot_info_image. - */ - MGMT_EVT_OP_IMG_MGMT_SLOT_INFO_IMAGE = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_IMG, 7), - - /** - * Callback when a slot list command outputs fields for a slot of an image, data is - * @ref img_mgmt_slot_info_slot. - */ - MGMT_EVT_OP_IMG_MGMT_SLOT_INFO_SLOT = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_IMG, 8), - - /** Used to enable all img_mgmt_group events. */ - MGMT_EVT_OP_IMG_MGMT_ALL = MGMT_DEF_EVT_OP_ALL(MGMT_EVT_GRP_IMG), -}; - -/** - * MGMT event opcodes for operating system management group. - */ -enum os_mgmt_group_events { - /** Callback when a reset command has been received, data is @ref os_mgmt_reset_data. */ - MGMT_EVT_OP_OS_MGMT_RESET = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_OS, 0), - - /** Callback when an info command is processed, data is @ref os_mgmt_info_check. */ - MGMT_EVT_OP_OS_MGMT_INFO_CHECK = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_OS, 1), - - /** Callback when an info command needs to output data, data is @ref os_mgmt_info_append. */ - MGMT_EVT_OP_OS_MGMT_INFO_APPEND = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_OS, 2), - - /** Callback when a datetime get command has been received. */ - MGMT_EVT_OP_OS_MGMT_DATETIME_GET = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_OS, 3), - - /** Callback when a datetime set command has been received, data is @ref rtc_time. */ - MGMT_EVT_OP_OS_MGMT_DATETIME_SET = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_OS, 4), - - /** - * Callback when a bootloader info command has been received, data is - * os_mgmt_bootloader_info_data(). - */ - MGMT_EVT_OP_OS_MGMT_BOOTLOADER_INFO = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_OS, 5), - - /** Used to enable all os_mgmt_group events. */ - MGMT_EVT_OP_OS_MGMT_ALL = MGMT_DEF_EVT_OP_ALL(MGMT_EVT_GRP_OS), -}; - -/** - * MGMT event opcodes for settings management group. - */ -enum settings_mgmt_group_events { - /** Callback when a setting is read/written/deleted. */ - MGMT_EVT_OP_SETTINGS_MGMT_ACCESS = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_SETTINGS, 0), - - /** Used to enable all settings_mgmt_group events. */ - MGMT_EVT_OP_SETTINGS_MGMT_ALL = MGMT_DEF_EVT_OP_ALL(MGMT_EVT_GRP_SETTINGS), -}; - -/** - * MGMT event opcodes for enumeration management group. - */ -enum enum_mgmt_group_events { - /** Callback when fetching details on supported command groups. */ - MGMT_EVT_OP_ENUM_MGMT_DETAILS = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_ENUM, 0), - - /** Used to enable all enum_mgmt_group events. */ - MGMT_EVT_OP_ENUM_MGMT_ALL = MGMT_DEF_EVT_OP_ALL(MGMT_EVT_GRP_ENUM), -}; - /** * MGMT callback struct */ From 42ee9832b4b6186bc2d263d86e91b004fdfb5c0c Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Fri, 9 Jan 2026 11:59:56 +0000 Subject: [PATCH 2200/3659] mgmt: mcumgr: kconfig: Fix various issues Fixes various issues in the Kconfigs including not properly having abbreviations in the correct case, line lengths, duplicating other Kconfigs, etc. Signed-off-by: Jamie McCrae --- subsys/mgmt/mcumgr/Kconfig | 19 ++- subsys/mgmt/mcumgr/grp/enum_mgmt/Kconfig | 4 +- subsys/mgmt/mcumgr/grp/fs_mgmt/Kconfig | 114 ++++++++---------- subsys/mgmt/mcumgr/grp/img_mgmt/Kconfig | 78 ++++++------ subsys/mgmt/mcumgr/grp/os_mgmt/Kconfig | 73 +++++------ subsys/mgmt/mcumgr/grp/settings_mgmt/Kconfig | 30 ++--- subsys/mgmt/mcumgr/grp/shell_mgmt/Kconfig | 41 +++---- subsys/mgmt/mcumgr/grp/stat_mgmt/Kconfig | 14 +-- subsys/mgmt/mcumgr/mgmt/Kconfig | 6 +- subsys/mgmt/mcumgr/smp/Kconfig | 86 ++++++------- subsys/mgmt/mcumgr/smp_client/Kconfig | 4 +- subsys/mgmt/mcumgr/transport/Kconfig | 27 ++--- .../mgmt/mcumgr/transport/Kconfig.bluetooth | 28 ++--- subsys/mgmt/mcumgr/transport/Kconfig.dummy | 9 +- subsys/mgmt/mcumgr/transport/Kconfig.shell | 22 ++-- subsys/mgmt/mcumgr/transport/Kconfig.uart | 17 ++- subsys/mgmt/mcumgr/transport/Kconfig.udp | 9 +- 17 files changed, 256 insertions(+), 325 deletions(-) diff --git a/subsys/mgmt/mcumgr/Kconfig b/subsys/mgmt/mcumgr/Kconfig index 49bd17f46691..c917b1e55e0a 100644 --- a/subsys/mgmt/mcumgr/Kconfig +++ b/subsys/mgmt/mcumgr/Kconfig @@ -3,11 +3,11 @@ # SPDX-License-Identifier: Apache-2.0 menuconfig MCUMGR - bool "mcumgr Support" + bool "MCUmgr Support" depends on NET_BUF depends on ZCBOR help - This option enables the mcumgr management library. + This option enables the MCUmgr management library. if MCUMGR @@ -23,14 +23,13 @@ config MCUMGR_SMP_LEGACY_RC_BEHAVIOUR bool "Legacy rc (result code) response behaviour" depends on MCUMGR_SMP_SUPPORT_ORIGINAL_PROTOCOL help - This will enable legacy result code response behaviour of having rc - present in responses when the status is 0. With this option disabled, - mcumgr acts with new behaviour and will only return rc is the result - code is non-zero (i.e. an error occurred). - - If a command only returns a result code, this will mean that the - response will be empty with the new behaviour enabled, as opposed to - the old behaviour where the rc field will be present in the response. + This will enable legacy result code response behaviour of having rc present in responses + when the status is 0. With this option disabled, MCUmgr acts with new behaviour and will + only return rc is the result code is non-zero (i.e. an error occurred). + + If a command only returns a result code, this will mean that the response will be empty + with the new behaviour enabled, as opposed to the old behaviour where the rc field will + be present in the response. menu "SMP Client" diff --git a/subsys/mgmt/mcumgr/grp/enum_mgmt/Kconfig b/subsys/mgmt/mcumgr/grp/enum_mgmt/Kconfig index b6a73a134b6e..27ada8f7f28f 100644 --- a/subsys/mgmt/mcumgr/grp/enum_mgmt/Kconfig +++ b/subsys/mgmt/mcumgr/grp/enum_mgmt/Kconfig @@ -16,8 +16,8 @@ menuconfig MCUMGR_GRP_ENUM select MCUMGR_SMP_CBOR_MIN_DECODING_LEVEL_2 select MCUMGR_SMP_CBOR_MIN_DECODING_LEVEL_3 if ZCBOR_CANONICAL help - Enables MCUmgr handlers for enumeration management. This allows - for listing supported command groups. + Enables MCUmgr handlers for enumeration management. This allows for listing supported + command groups. if MCUMGR_GRP_ENUM diff --git a/subsys/mgmt/mcumgr/grp/fs_mgmt/Kconfig b/subsys/mgmt/mcumgr/grp/fs_mgmt/Kconfig index edac04c4f6c6..0cfc2609f5ed 100644 --- a/subsys/mgmt/mcumgr/grp/fs_mgmt/Kconfig +++ b/subsys/mgmt/mcumgr/grp/fs_mgmt/Kconfig @@ -19,13 +19,11 @@ menuconfig MCUMGR_GRP_FS help Enables MCUmgr handlers for file management - This option allows MCUmgr clients to access anything in the - file system, including application-stored secrets like - private keys. Use of this feature in production without adequate - protection mechanisms is strongly discouraged (applications can - enable MCUMGR_GRP_FS_FILE_ACCESS_HOOK and register to receive - callbacks when file access is attempted, which they can then filter, - allow, deny or rewrite paths). + Note: This option allows MCUmgr clients to access anything in the file system, including + application-stored secrets like private keys. Use of this feature in production without + adequate protection mechanisms is strongly discouraged (applications can enable + MCUMGR_GRP_FS_FILE_ACCESS_HOOK and register to receive callbacks when file access is + attempted, which they can then filter, allow, deny or rewrite paths). if MCUMGR_GRP_FS @@ -33,16 +31,15 @@ choice MCUMGR_GRP_FS_MAX_FILE_SIZE prompt "Maximum file size that could be uploaded/downloaded" default MCUMGR_GRP_FS_MAX_FILE_SIZE_64KB help - Maximum file size that will be allowed to be downloaded from - device. - This option decides on number of bytes that are reserved in - CBOR frame for storage of offset/size of file downloaded. + Maximum file size that will be allowed to be downloaded from device. This option decides + on number of bytes that are reserved in CBOR frame for storage of offset/size of file + downloaded. config MCUMGR_GRP_FS_MAX_FILE_SIZE_64KB bool "<= 64KB" help - Files that have size up to 64KB require 1 to 3 bytes to encode - size/offset within CBOR frame with file chunk. + Files that have size up to 64KB require 1 to 3 bytes to encode size/offset within CBOR + frame with file chunk. config MCUMGR_GRP_FS_MAX_FILE_SIZE_4GB bool "<= 4GB" @@ -57,23 +54,21 @@ config MCUMGR_GRP_FS_MAX_OFFSET_LEN default 3 if MCUMGR_GRP_FS_MAX_FILE_SIZE_64KB default 5 if MCUMGR_GRP_FS_MAX_FILE_SIZE_4GB help - Maximal byte length of encoded offset/size, within transferred - CBOR frame containing chunk of downloaded file. - This value affects how much of data will fit into download buffer, - as it selects sizes of fields within headers. - NOTE: This option is hidden intentionally as it is intended - to be assigned from limited set of allowed values, depending on - the selection made in MCUMGR_GRP_FS_MAX_FILE_SIZE menu. + Maximal byte length of encoded offset/size, within transferred CBOR frame containing + chunk of downloaded file. This value affects how much of data will fit into download + buffer, as it selects sizes of fields within headers. + + Note: This option is hidden intentionally as it is intended to be assigned from limited + set of allowed values, depending on the selection made in MCUMGR_GRP_FS_MAX_FILE_SIZE + menu. config MCUMGR_GRP_FS_DL_CHUNK_SIZE_LIMIT bool "Setting custom size of download file chunk" help - By default file chunk, that will be read off storage and fit into - MCUmgr frame, is automatically calculated to fit into buffer - of size MCUMGR_TRANSPORT_NETBUF_SIZE with all headers. - Enabling this option allows to set MAXIMUM value that will be - allowed for such chunk. - Look inside fs_mgmt_config.h for details. + By default file chunk, that will be read off storage and fit into MCUmgr frame, is + automatically calculated to fit into buffer of size MCUMGR_TRANSPORT_NETBUF_SIZE with + all headers. Enabling this option allows to set MAXIMUM value that will be allowed for + such chunk. Look inside fs_mgmt_config.h for details. if MCUMGR_GRP_FS_DL_CHUNK_SIZE_LIMIT @@ -82,12 +77,11 @@ config MCUMGR_GRP_FS_DL_CHUNK_SIZE range 65 MCUMGR_TRANSPORT_NETBUF_SIZE default MCUMGR_TRANSPORT_NETBUF_SIZE help - Sets the MAXIMUM size of chunk which will be rounded down to - number of bytes that, with all the required headers, will fit - into MCUMGR_TRANSPORT_NETBUF_SIZE. This means that actual value - might be lower then selected, in which case compiler warning will - be issued. Look inside fs_mgmt_config.h for details. - Note that header sizes are affected by MCUMGR_GRP_FS_MAX_OFFSET_LEN. + Sets the MAXIMUM size of chunk which will be rounded down to number of bytes that, with + all the required headers, will fit into MCUMGR_TRANSPORT_NETBUF_SIZE. This means that + actual value might be lower then selected, in which case compiler warning will be issued. + Look inside fs_mgmt_config.h for details. Note that header sizes are affected by + MCUMGR_GRP_FS_MAX_OFFSET_LEN. endif @@ -95,16 +89,15 @@ config MCUMGR_GRP_FS_FILE_STATUS bool "File status command" default y help - This command allows a remote device to retrieve the status of a file, - at present only the size of the file is returned (if it exists). + This command allows a remote device to retrieve the status of a file, at present only the + size of the file is returned (if it exists). config MCUMGR_GRP_FS_CHECKSUM_HASH bool "Checksum/hash MCUmgr functions" help - Enable this to support the hash/checksum MCUmgr functionality, - individual checksum and hash types need to be enabled below. - Note that this requires enough stack space to buffer data - from the file being read and generate the output hash/checksum. + Enable this to support the hash/checksum MCUmgr functionality, individual checksum and + hash types need to be enabled below. Note that this requires enough stack space to buffer + data from the file being read and generate the output hash/checksum. if MCUMGR_GRP_FS_CHECKSUM_HASH @@ -113,8 +106,7 @@ config MCUMGR_GRP_FS_CHECKSUM_HASH_CHUNK_SIZE range 32 16384 default 128 help - Chunk size of buffer to use when calculating file checksum or hash - (uses stack). + Chunk size of buffer to use when calculating file checksum or hash (uses stack). config MCUMGR_GRP_FS_CHECKSUM_IEEE_CRC32 bool "IEEE CRC32 checksum support" @@ -134,17 +126,17 @@ config MCUMGR_GRP_FS_CHECKSUM_HASH_SUPPORTED_CMD bool "Supported hash/checksum command" select MCUMGR_SMP_CBOR_MIN_ENCODING_LEVEL_3 if ZCBOR_CANONICAL help - Enable the supported hash/checksum command which will return details on - supported hash and checksum types that can be used. + Enable the supported hash/checksum command which will return details on supported hash + and checksum types that can be used. config MCUMGR_GRP_FS_CHECKSUM_HASH_SUPPORTED_MAX_TYPES int "Predicted maximum number of types to return on supported list" default 10 depends on MCUMGR_GRP_FS_CHECKSUM_HASH_SUPPORTED_CMD help - This is used for defining CBOR map holding supported hash/checksum info. - The value does not affect memory allocation, it is used by zcbor to - figure out how to encode map depending on its predicted size. + This is used for defining CBOR map holding supported hash/checksum info. The value does + not affect memory allocation, it is used by zcbor to figure out how to encode map + depending on its predicted size. endif @@ -152,41 +144,35 @@ config MCUMGR_GRP_FS_PATH_LEN int "Maximum file path length" default 64 help - Limits the maximum path length for file operations, in bytes. A buffer - of this size gets allocated on the stack during handling of file upload - and download commands. + Limits the maximum path length for file operations, in bytes. A buffer of this size gets + allocated on the stack during handling of file upload and download commands. config MCUMGR_GRP_FS_FILE_ACCESS_HOOK bool "File access hooks" depends on MCUMGR_MGMT_NOTIFICATION_HOOKS help - Allows applications to control file access (e.g. for uploading and - downloading of files) by registering for a callback which is then - triggered whenever a files are accessed using the FS management group - function. This also, optionally, allows re-writing or changing of - supplied file paths. - Note that this may be called multiple times for each file read and - write due to MCUmgr's method of operation with a single file state. + Allows applications to control file access (e.g. for uploading and downloading of files) + by registering for a callback which is then triggered whenever a files are accessed + using the FS management group function. This also, optionally, allows re-writing or + changing of supplied file paths. Note that this may be called multiple times for each + file read and write due to MCUmgr's method of operation with a single file state. config MCUMGR_GRP_FS_FILE_SEMAPHORE_TAKE_TIME int "File handle semaphore take time (ms)" default 100 help - Maximum time (in ms) to acquire the file handle semaphore when a file - upload/download command is used. If unable to acquire the semaphore, - then MGMT_ERR_EBUSY will be returned. - - Can specify 0 to not wait for the lock and return instantly if it - cannot be acquired. + Maximum time (in ms) to acquire the file handle semaphore when a file upload/download + command is used. If unable to acquire the semaphore, then MGMT_ERR_EBUSY will be + returned. Can specify 0 to not wait for the lock and return instantly if it cannot be + acquired. config MCUMGR_GRP_FS_FILE_AUTOMATIC_IDLE_CLOSE_TIME int "Automatic file handle close time (ms)" default 4000 range 1 99999999 help - Time (in ms) for a file upload/download to be declared aborted and - file handle cleaned up. Each access to the file will reset the idle - time to 0. + Time (in ms) for a file upload/download to be declared aborted and file handle cleaned + up. Each access to the file will reset the idle time to 0. module = MCUMGR_GRP_FS module-str = mcumgr_grp_fs diff --git a/subsys/mgmt/mcumgr/grp/img_mgmt/Kconfig b/subsys/mgmt/mcumgr/grp/img_mgmt/Kconfig index 25979180e2c9..ca5362f1fd68 100644 --- a/subsys/mgmt/mcumgr/grp/img_mgmt/Kconfig +++ b/subsys/mgmt/mcumgr/grp/img_mgmt/Kconfig @@ -13,7 +13,7 @@ # try to group them together by the same stem after prefix. menuconfig MCUMGR_GRP_IMG - bool "Mcumgr handlers for image management" + bool "MCUmgr handlers for image management" depends on FLASH depends on IMG_MANAGER depends on !MCUBOOT_BOOTLOADER_MODE_SINGLE_APP @@ -50,7 +50,8 @@ config MCUMGR_GRP_IMG_UPDATABLE_IMAGE_NUMBER help Sets how many application images are supported (pairs of secondary and primary slots). Setting this to 2 requires MCUMGR_TRANSPORT_NETBUF_SIZE to be at least 512b. - NOTE: The UPDATEABLE_IMAGE_NUMBER of MCUBOOT configuration, even for Zephyr build, + + Note: The UPDATEABLE_IMAGE_NUMBER of MCUBOOT configuration, even for Zephyr build, needs to be set to the same value; this is due to the fact that the MCUmgr uses boot_util and the UPDATEABLE_IMAGE_NUMBER controls number of images supported by that library. @@ -59,50 +60,48 @@ config MCUMGR_GRP_IMG_VERBOSE_ERR bool "Verbose error responses when uploading application image" select MCUMGR_SMP_VERBOSE_ERR_RESPONSE help - Add additional "rsn" key to SMP responses, where provided, explaining - non-0 "rc" codes. + Add additional "rsn" key to SMP responses, where provided, explaining non-0 "rc" codes. config MCUMGR_GRP_IMG_ALLOW_CONFIRM_NON_ACTIVE_IMAGE_SECONDARY bool "Allow to confirm secondary slot of non-active image" depends on !MCUBOOT_BOOTLOADER_MODE_FIRMWARE_UPDATER default y help - Allows to confirm secondary (non-active) slot of non-active image. - Normally it should not be allowed to confirm any slots of non-active - image, via MCUmgr commands, to prevent confirming something that is - broken and may not boot in other slot; instead application should - have means to test and confirm the image. + Allows to confirm secondary (non-active) slot of non-active image. Normally it should not + be allowed to confirm any slots of non-active image, via MCUmgr commands, to prevent + confirming something that is broken and may not boot in other slot; instead application + should have a means to test and confirm the image. config MCUMGR_GRP_IMG_ALLOW_CONFIRM_NON_ACTIVE_IMAGE_ANY bool "Allow to confirm slots of non-active image" depends on !MCUBOOT_BOOTLOADER_MODE_FIRMWARE_UPDATER select MCUMGR_GRP_IMG_ALLOW_CONFIRM_NON_ACTIVE_IMAGE_SECONDARY help - Allows to confirm any slot of non-active image. - Normally it should not be allowed to confirm any slots of non-active - image, via MCUmgr commands, to prevent confirming something that is - broken and may not boot in other slot; instead application should - have means to test and confirm the image. + Allows to confirm any slot of non-active image. Normally it should not be allowed to + confirm any slots of non-active image, via MCUmgr commands, to prevent confirming + something that is broken and may not boot in other slot; instead application should have + a means to test and confirm the image. config MCUMGR_GRP_IMG_ALLOW_ERASE_PENDING bool "Allow to erase pending slot" depends on !MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP default y help - Allows erasing secondary slot which is marked for test or confirmed; this allows - erasing slots that have been set for next boot but the device has not - reset yet, so has not yet been swapped. + Allows erasing secondary slot which is marked for test or confirmed; this allows erasing + slots that have been set for next boot but the device has not reset yet, so have not yet + been swapped. config MCUMGR_GRP_IMG_DIRECT_UPLOAD bool "Allow direct image upload" depends on !MCUBOOT_BOOTLOADER_MODE_FIRMWARE_UPDATER help - Enables directly uploading image to selected image partition. - This changes how "image" is understood by MCUmgr: normally MCUmgr allows uploading to - the first slot of the only image it knows, where image is understood as two slots - (two DTS images for Zephyr); this allows to treat every DTS defined image as direct - target for upload, and more than two may be used (4 at this time). - NOTE: When direct upload is used the image numbers are shifted by + 1, and the default + Enables directly uploading image to selected image partition. This changes how "image" is + understood by MCUmgr: normally MCUmgr allows uploading to the first slot of the only + image it knows, where image is understood as two slots (two DTS images for Zephyr); this + allows to treat every DTS defined image as direct target for upload, and more than two + may be used (4 at this time). + + Note: When direct upload is used the image numbers are shifted by + 1, and the default behaviour is, when image is not selected, to upload to image that represents secondary slot in normal operation. @@ -110,12 +109,10 @@ config MCUMGR_GRP_IMG_REJECT_DIRECT_XIP_MISMATCHED_SLOT bool "Reject Direct-XIP applications with mismatched address" depends on MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP || MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP_WITH_REVERT help - When enabled, the MCUmgr will compare base address of application, - encoded into .bin file header with use of imgtool, on upload and will - reject binaries that would not be able to start from available - Direct-XIP address. - The base address can be set, to an image binary header, with imgtool, - using the --rom-fixed command line option. + When enabled, the MCUmgr will compare base address of application, encoded into .bin + file header with use of imgtool, on upload and will reject binaries that would not be + able to start from available Direct-XIP address. The base address can be set, to an image + binary header, with imgtool, using the --rom-fixed command line option. config MCUMGR_GRP_IMG_ALLOW_CONFIRM_NON_ACTIVE_SLOT bool "Allow to confirm non-active slots of any image" if !MCUBOOT_BOOTLOADER_MODE_OVERWRITE_ONLY @@ -127,28 +124,25 @@ config MCUMGR_GRP_IMG_ALLOW_CONFIRM_NON_ACTIVE_SLOT MCUBOOT_BOOTLOADER_MODE_OVERWRITE_ONLY default y help - Allows to confirm non-active slot of any image. - Normally it should not be allowed to confirm any slots via MCUmgr - commands, to prevent confirming something that is broken and was not - verified to boot correctly. - Option always enabled in the overwrite mode, because the permanent - update, that uses the confirm flag, is the intended way to provide + Allows to confirm non-active slot of any image. Normally it should not be allowed to + confirm any slots via MCUmgr commands, to prevent confirming something that is broken + and was not verified to boot correctly. Option is always enabled when in overwrite only + mode, because updates are permanent and using the confirm flag is the intended method for updates. config MCUMGR_GRP_IMG_FRUGAL_LIST bool "Omit zero, empty or false values from status list" help The status list send back from the device will only be filled with data that is non-zero, - non-empty or true. This option slightly reduces number of bytes transferred back from + non-empty or true. This option slightly reduces number of bytes transferred back from a device but requires support in client software, which has to default omitted values. Works correctly with the go mcumgr-cli application. config MCUMGR_GRP_IMG_VERSION_CMP_USE_BUILD_NUMBER bool "Use build number while comparing image version" help - By default, the image version comparison relies only on version major, - minor and revision. Enable this option to take into account the build - number as well. + By default, the image version comparison relies only on version major, minor and + revision. Enable this option to take into account the build number as well. config MCUMGR_GRP_IMG_UPLOAD_CHECK_HOOK bool "Upload check hook" @@ -219,9 +213,9 @@ config MCUMGR_GRP_IMG_IMAGE_SLOT_STATE_STATES prompt "Predicted maximum number of entries per group" if MCUMGR_GRP_IMG_IMAGE_SLOT_STATE_HOOK default 15 help - This is used for defining CBOR map holding group data. - The value does not affect memory allocation, it is used by zcbor - to figure out how to encode map depending on its predicted size. + This is used for defining CBOR map holding group data. The value does not affect memory + allocation, it is used by zcbor to figure out how to encode map depending on its + predicted size. config MCUMGR_GRP_IMG_SLOT_INFO bool "Slot info" diff --git a/subsys/mgmt/mcumgr/grp/os_mgmt/Kconfig b/subsys/mgmt/mcumgr/grp/os_mgmt/Kconfig index 15df1cc7eb39..cbe617089d24 100644 --- a/subsys/mgmt/mcumgr/grp/os_mgmt/Kconfig +++ b/subsys/mgmt/mcumgr/grp/os_mgmt/Kconfig @@ -13,7 +13,7 @@ # try to group them together by the same stem after prefix. menuconfig MCUMGR_GRP_OS - bool "Mcumgr handlers for OS management" + bool "MCUmgr handlers for OS management" imply REBOOT help Enables MCUmgr handlers for OS management @@ -27,21 +27,19 @@ config MCUMGR_GRP_OS_RESET_MS default 250 depends on MULTITHREADING help - When a reset command is received, the system waits this many milliseconds - before performing the reset. This delay allows time for the MCUmgr - response to be delivered. + When a reset command is received, the system waits this many milliseconds before + performing the reset. This delay allows time for the MCUmgr response to be delivered. config MCUMGR_GRP_OS_RESET_HOOK bool "Reset hook" depends on MCUMGR_MGMT_NOTIFICATION_HOOKS help - Allows applications to control and get notifications of when a reset - command has been issued via an MCUmgr command. With this option - disabled, modules will reboot when the command is received without - notification, when this is enabled and a handler is registered, the - application will be notified that a reset command has been received - and will allow the application to perform any required operations - before accepting or declining the reset request. + Allows applications to control and get notifications of when a reset command has been + issued via an MCUmgr command. With this option disabled, modules will reboot when the + command is received without notification, when this is enabled and a handler is + registered, the application will be notified that a reset command has been received and + will allow the application to perform any required operations before accepting or + declining the reset request. config MCUMGR_GRP_OS_RESET_BOOT_MODE bool "Boot mode" @@ -64,10 +62,9 @@ config MCUMGR_GRP_OS_TASKSTAT_ONLY_SUPPORTED_STATS bool "Send only data gathered by Zephyr" default y help - Response will not include fields the Zephyr does not collect statistic for. - Enable this if your client software is able to process "taskstat" response - that would be missing "runtime", "cswcnt", "last_checkin" and "next_checkin" - map entries for each listed task. + Response will not include fields the Zephyr does not collect statistic for. Enable this + if your client software is able to process "taskstat" response that would be missing + "runtime", "cswcnt", "last_checkin" and "next_checkin" map entries for each listed task. Enabling this option will slightly reduce code size. choice MCUMGR_GRP_OS_TASKSTAT_THREAD_NAME_CHOICE @@ -75,8 +72,8 @@ choice MCUMGR_GRP_OS_TASKSTAT_THREAD_NAME_CHOICE default MCUMGR_GRP_OS_TASKSTAT_USE_THREAD_NAME_FOR_NAME if THREAD_NAME default MCUMGR_GRP_OS_TASKSTAT_USE_THREAD_PRIO_FOR_NAME help - Select what will serve as thread name in "taskstat" response. - By default taskstat responses use thread priority, when THREAD_NAME is disabled, + Select what will serve as thread name in "taskstat" response. By default taskstat + responses use thread priority, when THREAD_NAME is disabled, config MCUMGR_GRP_OS_TASKSTAT_USE_THREAD_NAME_FOR_NAME bool "Thread name" @@ -94,9 +91,9 @@ config MCUMGR_GRP_OS_TASKSTAT_MAX_NUM_THREADS int "Predicted maximum number of threads to return on taskstat list" default 50 help - This is used for defining CBOR map holding thread info. - The value does not affect memory allocation, it is used by zcbor - to figure out how to encode map depending on its predicted size. + This is used for defining CBOR map holding thread info. The value does not affect memory + allocation, it is used by zcbor to figure out how to encode map depending on its + predicted size. config MCUMGR_GRP_OS_TASKSTAT_THREAD_NAME_LEN int "Length of thread name to return in response" @@ -105,35 +102,31 @@ config MCUMGR_GRP_OS_TASKSTAT_THREAD_NAME_LEN range 3 THREAD_MAX_NAME_LEN if THREAD_NAME range 3 6 if !THREAD_NAME help - The length of the string that is sent in response to taskstat command, - as a thread name. + The length of the string that is sent in response to taskstat command, as a thread name. When THREAD_NAME is enabled then this defaults to THREAD_MAX_NAME_LEN. - When THREAD_NAME is disabled the name is generated from thread priority, - signed integer, and this number regulates how many digits will be used; - in such case this value should also take into account possible '-' - sign. + When THREAD_NAME is disabled the name is generated from thread priority, signed integer, + and this number regulates how many digits will be used; in such case this value should + also take into account possible '-' sign. config MCUMGR_GRP_OS_TASKSTAT_SIGNED_PRIORITY bool "Signed priorities" default y help - Zephyr uses int8_t as thread priorities, but in taskstat response it encodes - them as unsigned. Enabling this option will use signed int for priorities in - responses, which is more natural for Zephyr. - Disable this option if your client software is unable to properly decode and - accept signed integers as priorities. + Zephyr uses int8_t as thread priorities, but in taskstat response it encodes them as + unsigned. Enabling this option will use signed int for priorities in responses, which is + more natural for Zephyr. Disable this option if your client software is unable to + properly decode and accept signed integers as priorities. config MCUMGR_GRP_OS_TASKSTAT_STACK_INFO bool "Include stack info in taskstat responses" depends on THREAD_STACK_INFO help - Enabling this option adds stack information into "taskstat" command - responses, this is default when THREAD_STACK_INFO is selected. - Disable this option only when your client application is able to - process "taskstat" response without the "stksiz" and "stkuse" fields. - It is worth disabling this option when THREAD_STACK_INFO is disabled, - as it will prevent sending zeroed stack information just to fill - all the fields in "taskstat" responses, and it will slightly reduce code size. + Enabling this option adds stack information into "taskstat" command responses, this is + default when THREAD_STACK_INFO is selected. Disable this option only when your client + application is able to process "taskstat" response without the "stksiz" and "stkuse" + fields. It is worth disabling this option when THREAD_STACK_INFO is disabled, as it will + prevent sending zeroed stack information just to fill all the fields in "taskstat" + responses, and it will slightly reduce code size. endif @@ -180,8 +173,8 @@ config MCUMGR_GRP_OS_DATETIME_HOOK depends on MCUMGR_GRP_OS_DATETIME depends on MCUMGR_MGMT_NOTIFICATION_HOOKS help - Allows applications to control and get notifications of when a datetime set/get - command has been issued via an MCUmgr command. + Allows applications to control and get notifications of when a datetime set/get command + has been issued via an MCUmgr command. config MCUMGR_GRP_OS_MCUMGR_PARAMS bool "MCUMGR Parameters retrieval command" diff --git a/subsys/mgmt/mcumgr/grp/settings_mgmt/Kconfig b/subsys/mgmt/mcumgr/grp/settings_mgmt/Kconfig index ed61f4d7c5f5..c7d24062b6d2 100644 --- a/subsys/mgmt/mcumgr/grp/settings_mgmt/Kconfig +++ b/subsys/mgmt/mcumgr/grp/settings_mgmt/Kconfig @@ -17,14 +17,14 @@ choice MCUMGR_GRP_SETTINGS_BUFFER_TYPE prompt "Buffer type" default MCUMGR_GRP_SETTINGS_BUFFER_TYPE_STACK help - Selects if the stack or heap will be used for variables that are - needed when processing requests. + Selects if the stack or heap will be used for variables that are needed when processing + requests. config MCUMGR_GRP_SETTINGS_BUFFER_TYPE_STACK bool "Stack (fixed size)" help - Use a fixed size stack buffer, any user-supplied values longer than - this will be rejected. + Use a fixed size stack buffer, any user-supplied values longer than this will be + rejected. Note that stack usage for parameter storage alone will be MCUMGR_GRP_SETTINGS_NAME_LEN + MCUMGR_GRP_SETTINGS_VALUE_LEN, @@ -34,9 +34,8 @@ config MCUMGR_GRP_SETTINGS_BUFFER_TYPE_HEAP bool "Heap (dynamic size)" depends on COMMON_LIBC_MALLOC_ARENA_SIZE > 0 help - Use dynamic heap memory allocation through malloc, if there is - insufficient heap memory for the allocation then the request will be - rejected. + Use dynamic heap memory allocation through malloc, if there is insufficient heap memory + for the allocation then the request will be rejected. endchoice @@ -44,25 +43,22 @@ config MCUMGR_GRP_SETTINGS_NAME_LEN int "Maximum setting name length" default 32 help - Maximum length of a key to lookup, this will be the size of the - variable if placed on the stack or the maximum allocated size of the - variable if placed on the heap. + Maximum length of a key to lookup, this will be the size of the variable if placed on + the stack or the maximum allocated size of the variable if placed on the heap. config MCUMGR_GRP_SETTINGS_VALUE_LEN int "Maximum setting value length" default 32 help - Maximum length of a value to read, this will be the size of the - variable if placed on the stack or the allocated size of the - variable if placed on the heap (settings does not support getting - the size of a value prior to looking it up). + Maximum length of a value to read, this will be the size of the variable if placed on + the stack or the allocated size of the variable if placed on the heap (settings does not + support getting the size of a value prior to looking it up). config MCUMGR_GRP_SETTINGS_ACCESS_HOOK bool "Settings access hook" depends on MCUMGR_MGMT_NOTIFICATION_HOOKS help - Allows applications to control settings management access by - registering for a callback which is then triggered whenever a - settings read or write attempt is made. + Allows applications to control settings management access by registering for a callback + which is then triggered whenever a settings read or write attempt is made. endif diff --git a/subsys/mgmt/mcumgr/grp/shell_mgmt/Kconfig b/subsys/mgmt/mcumgr/grp/shell_mgmt/Kconfig index 6030a25ea8c1..d4cc9e816134 100644 --- a/subsys/mgmt/mcumgr/grp/shell_mgmt/Kconfig +++ b/subsys/mgmt/mcumgr/grp/shell_mgmt/Kconfig @@ -13,42 +13,31 @@ # try to group them together by the same stem after prefix. menuconfig MCUMGR_GRP_SHELL - bool "Mcumgr handlers for shell management" + bool "MCUmgr handlers for shell management" depends on SHELL depends on SHELL_BACKEND_DUMMY select MCUMGR_SMP_CBOR_MIN_DECODING_LEVEL_2 help - Enables MCUmgr handlers for shell management. The handler will utilize - the dummy backend to execute shell commands and capture the output to - an internal memory buffer. This way, there is no interaction with - physical interfaces outside of the scope of the user. - It is possible to use additional shell backends in coordination - with this handler and they will not interfere. - The MCUMGR_GRP_SHELL_BACKEND_DUMMY_BUF_SIZE will affect how many characters - will be returned from command output, if your output gets cut, then - increase the value. Remember to set MCUMGR_TRANSPORT_NETBUF_SIZE accordingly. - Note that maximum length of shell command accepted is regulated by - the CONFIG_SHELL_CMD_BUFF_SIZE, and a buffer for a command is allocated - on a stack, by the MCUmgr, so enabling MCUMGR_GRP_SHELL and - changes to the CONFIG_SHELL_CMD_BUFF_SIZE may increase stack size - requirements. + Enables MCUmgr handlers for shell management. The handler will utilize the dummy backend + to execute shell commands and capture the output to an internal memory buffer. This way, + there is no interaction with physical interfaces outside of the scope of the user. It is + possible to use additional shell backends in coordination with this handler and they will + not interfere. The CONFIG_SHELL_BACKEND_DUMMY_BUF_SIZE Kconfig will affect how many + characters will be returned from command output, if your output gets cut, then increase + the value. Remember to set MCUMGR_TRANSPORT_NETBUF_SIZE accordingly. Note that maximum + length of shell command accepted is regulated by the CONFIG_SHELL_CMD_BUFF_SIZE, and a + buffer for a command is allocated on a stack, by the MCUmgr, so enabling MCUMGR_GRP_SHELL + and changes to the CONFIG_SHELL_CMD_BUFF_SIZE may increase stack size requirements. if MCUMGR_GRP_SHELL -# Show dummy shell buffer size here, will show help text of original prompt so -# nothing extra is needed here, nor a default value. -config SHELL_BACKEND_DUMMY_BUF_SIZE - int "Shell output buffer size (Size of dummy buffer size)" - config MCUMGR_GRP_SHELL_LEGACY_RC_RETURN_CODE bool "Legacy behaviour: Use rc field for shell function return code" help - Enabling this options brings back legacy behaviour where the shell - return code is returned, incorrectly, in the rc field that was - originally designated for returning SMP processing errors. When - disabled, there will be an additional ret field which contains the - shell command exit code, and rc will be used for SMP processing - error codes. + Enabling this options brings back legacy behaviour where the shell return code is + returned, incorrectly, in the rc field that was originally designated for returning SMP + processing errors. When disabled, there will be an additional ret field which contains + the shell command exit code, and rc will be used for SMP processing error codes. module = MCUMGR_GRP_SHELL module-str = mcumgr_grp_shell diff --git a/subsys/mgmt/mcumgr/grp/stat_mgmt/Kconfig b/subsys/mgmt/mcumgr/grp/stat_mgmt/Kconfig index 1ab882c33ee7..041f10dc0ab1 100644 --- a/subsys/mgmt/mcumgr/grp/stat_mgmt/Kconfig +++ b/subsys/mgmt/mcumgr/grp/stat_mgmt/Kconfig @@ -13,7 +13,7 @@ # try to group them together by the same stem after prefix. menuconfig MCUMGR_GRP_STAT - bool "Mcumgr handlers for statistics management" + bool "MCUmgr handlers for statistics management" depends on STATS select MCUMGR_SMP_CBOR_MIN_DECODING_LEVEL_2 select MCUMGR_SMP_CBOR_MIN_ENCODING_LEVEL_3 if ZCBOR_CANONICAL @@ -27,13 +27,11 @@ config MCUMGR_GRP_STAT_MAX_NAME_LEN default 32 depends on MCUMGR_GRP_STAT help - Limits the maximum stat group name length in MCUmgr requests, in bytes. - For stat group names. a buffer of this size gets allocated on the stack - during handling of all stat read commands. If a stat group's name - exceeds this limit, it will be impossible to retrieve its values with - a stat show command. - For stat names s_name and snm_name, this is the maximum length when - encoding the name to cbor. + Limits the maximum stat group name length in MCUmgr requests, in bytes. For stat group + names, a buffer of this size gets allocated on the stack during handling of all stat read + commands. If a stat group's name exceeds this limit, it will be impossible to retrieve + its values with a stat show command. For stat names s_name and snm_name, this is the + maximum length when encoding the name to CBOR. module = MCUMGR_GRP_STAT module-str = mcumgr_grp_stat diff --git a/subsys/mgmt/mcumgr/mgmt/Kconfig b/subsys/mgmt/mcumgr/mgmt/Kconfig index 32fc05fed285..e627d0f10248 100644 --- a/subsys/mgmt/mcumgr/mgmt/Kconfig +++ b/subsys/mgmt/mcumgr/mgmt/Kconfig @@ -35,6 +35,6 @@ config MCUMGR_MGMT_HANDLER_USER_DATA config MCUMGR_MGMT_CUSTOM_PAYLOAD bool "MCUmgr custom payload" help - When this config is enabled, a user can use the field `custom_payload` in `mgmt_handler` to - skip the generation of the cbor start- and end byte in `smp_handle_single_payload` and - instead use a user defined payload in SMP messages. + When this config is enabled, a user can use the field `custom_payload` in `mgmt_handler` + to skip the generation of the CBOR start- and end byte in `smp_handle_single_payload` + and instead use a user defined payload in SMP messages. diff --git a/subsys/mgmt/mcumgr/smp/Kconfig b/subsys/mgmt/mcumgr/smp/Kconfig index aab861fa9cf9..518da3c52f26 100644 --- a/subsys/mgmt/mcumgr/smp/Kconfig +++ b/subsys/mgmt/mcumgr/smp/Kconfig @@ -15,26 +15,16 @@ config MCUMGR_SMP_CBOR_MAX_MAIN_MAP_ENTRIES int "Number of predicted maximum entries to main response map" default 15 help - This is number of predicted entries in main response map, - the one that encapsulates everything within response. - This value is used by zcbor to predict needed map encoding, - and does not affect memory allocation or usage. - Builtin command processors rarely add large amounts of - data directly to main map, creating sub-maps instead so - the default value works fine with them. - If your app directly adds fields to main map, without - encapsulating them, you may want to increase this value - in case when encoding starts to fail. + This is number of predicted entries in main response map, the one that encapsulates + everything within response. This value is used by zcbor to predict needed map encoding, + and does not affect memory allocation or usage. Builtin command processors rarely add + large amounts of data directly to main map, creating sub-maps instead so the default + value works fine with them. If your app directly adds fields to main map, without + encapsulating them, you may want to increase this value in case when encoding starts to + fail. config MCUMGR_SMP_CBOR_MIN_DECODING_LEVELS int - help - Minimal decoding levels, map/list encapsulation, required - to be supported by zcbor decoding of SMP responses - is auto generated from MCUMGR_SMP_CBOR_MIN_DECODING_LEVEL_? options. - A group or command that adds additional maps/lists above the - base map, which is already taken into account, should - select one of the MCUMGR_SMP_CBOR_MIN_DECODING_LEVEL_?. default 7 if MCUMGR_SMP_CBOR_MIN_DECODING_LEVEL_7 default 6 if MCUMGR_SMP_CBOR_MIN_DECODING_LEVEL_6 default 5 if MCUMGR_SMP_CBOR_MIN_DECODING_LEVEL_5 @@ -43,6 +33,11 @@ config MCUMGR_SMP_CBOR_MIN_DECODING_LEVELS default 2 if MCUMGR_SMP_CBOR_MIN_DECODING_LEVEL_2 default 1 if MCUMGR_SMP_CBOR_MIN_DECODING_LEVEL_1 default 0 + help + Minimal decoding levels, map/list encapsulation, required to be supported by zcbor + decoding of SMP responses is auto generated from MCUMGR_SMP_CBOR_MIN_DECODING_LEVEL_? + options. A group or command that adds additional maps/lists above the base map, which is + already taken into account, should select one of the MCUMGR_SMP_CBOR_MIN_DECODING_LEVEL_?. config MCUMGR_SMP_CBOR_MIN_DECODING_LEVEL_1 bool @@ -70,27 +65,16 @@ config MCUMGR_SMP_CBOR_MAX_DECODING_LEVELS range MCUMGR_SMP_CBOR_MIN_DECODING_LEVELS 15 default MCUMGR_SMP_CBOR_MIN_DECODING_LEVELS help - This is a maximum number of levels of maps/lists that will - be expected to be decoded within different command groups. - SMP commands/groups that provide no CBOR encoded payload - have no requirements. - Commands that provide CBOR payload require at least 1 level, - and additional levels for each map/list encapsulation. - For example if command accepts payload of map of parameters - it will need 2 levels. - This number translates to zcbor backup states, it increases - size of cbor_nb_reader structure by zcbor_state_t size per - one unit selected here. + This is a maximum number of levels of maps/lists that will be expected to be decoded + within different command groups. SMP commands/groups that provide no CBOR encoded payload + have no requirements. Commands that provide CBOR payload require at least 1 level, and + additional levels for each map/list encapsulation. For example if command accepts payload + of map of parameters it will need 2 levels. This number translates to zcbor backup states, + it increases size of cbor_nb_reader structure by zcbor_state_t size per one unit selected + here. config MCUMGR_SMP_CBOR_MIN_ENCODING_LEVELS int - help - Minimal encoding levels, map/list encapsulation, required - to be supported by zcbor encoding of SMP responses - is auto generated from MCUMGR_SMP_CBOR_MIN_ENCODING_LEVEL_? options. - A group or command that adds additional maps/lists above the - base map, which is already taken into account, should - select one of the MCUMGR_SMP_CBOR_MIN_ENCODING_LEVEL_?. default 7 if MCUMGR_SMP_CBOR_MIN_ENCODING_LEVEL_7 default 6 if MCUMGR_SMP_CBOR_MIN_ENCODING_LEVEL_6 default 5 if MCUMGR_SMP_CBOR_MIN_ENCODING_LEVEL_5 @@ -99,6 +83,11 @@ config MCUMGR_SMP_CBOR_MIN_ENCODING_LEVELS default 2 if MCUMGR_SMP_CBOR_MIN_ENCODING_LEVEL_2 default 1 if MCUMGR_SMP_CBOR_MIN_ENCODING_LEVEL_1 || ZCBOR_CANONICAL default 0 + help + Minimal encoding levels, map/list encapsulation, required to be supported by zcbor + encoding of SMP responses is auto generated from MCUMGR_SMP_CBOR_MIN_ENCODING_LEVEL_? + options. A group or command that adds additional maps/lists above the base map, which is + already taken into account, should select one of the MCUMGR_SMP_CBOR_MIN_ENCODING_LEVEL_?. config MCUMGR_SMP_CBOR_MIN_ENCODING_LEVEL_1 bool @@ -126,11 +115,9 @@ config MCUMGR_SMP_CBOR_MAX_ENCODING_LEVELS range MCUMGR_SMP_CBOR_MIN_ENCODING_LEVELS 15 default MCUMGR_SMP_CBOR_MIN_ENCODING_LEVELS help - This is a maximum number of levels of maps/lists that will - be encoded within different comm&& groups. - This number translates to zcbor backup states, it increases - size of cbor_nb_writer structure by zcbor_state_t size per - one unit selected here. + This is a maximum number of levels of maps/lists that will be encoded within different + commmand groups. This number translates to zcbor backup states, it increases size of + cbor_nb_writer structure by zcbor_state_t size per one unit selected here. config MCUMGR_SMP_COMMAND_STATUS_HOOKS bool "SMP command status hooks" @@ -143,19 +130,16 @@ config MCUMGR_SMP_SUPPORT_ORIGINAL_PROTOCOL bool "Support original protocol" default y help - This option will enable supporting the original SMP protocol whereby - all errors are returned in the "rc" field as well as the new protocol - whereby there is a dedicated entry for command error/result codes. - The protocol selection is indicated by the request header sent by the - client. + This option will enable supporting the original SMP protocol whereby all errors are + returned in the "rc" field as well as the new protocol whereby there is a dedicated + entry for command error/result codes. The protocol selection is indicated by the request + header sent by the client. config MCUMGR_SMP_VERBOSE_ERR_RESPONSE bool "Support verbose error response" depends on MCUMGR_SMP_SUPPORT_ORIGINAL_PROTOCOL help - Support for encoding "rc" code explanation in form of "rsn" - text string. This is useful, when returning MGMT_ERR_EUNKNOWN, - to add additional information on the source of an error. - Note that the "rsn" is string additional to "rc" code, - so MCUMGR_TRANSPORT_NETBUF_SIZE should be large enough to be able - to encode both. + Support for encoding "rc" code explanation in form of "rsn" text string. This is useful, + when returning MGMT_ERR_EUNKNOWN, to add additional information on the source of an + error. Note that the "rsn" is string additional to "rc" code, so + MCUMGR_TRANSPORT_NETBUF_SIZE should be large enough to be able to encode both. diff --git a/subsys/mgmt/mcumgr/smp_client/Kconfig b/subsys/mgmt/mcumgr/smp_client/Kconfig index b946efe1b324..d80e0b7c092e 100644 --- a/subsys/mgmt/mcumgr/smp_client/Kconfig +++ b/subsys/mgmt/mcumgr/smp_client/Kconfig @@ -26,8 +26,8 @@ config SMP_CMD_RETRY_TIME range 100 1000 default 500 help - The time (in ms) which the SMP client will wait for a response before re-sending - a command. + The time (in ms) which the SMP client will wait for a response before re-sending a + command. config SMP_CLIENT_CMD_MAX int "SMP client max buffer count" diff --git a/subsys/mgmt/mcumgr/transport/Kconfig b/subsys/mgmt/mcumgr/transport/Kconfig index 90bd158ed161..aacf27ee194f 100644 --- a/subsys/mgmt/mcumgr/transport/Kconfig +++ b/subsys/mgmt/mcumgr/transport/Kconfig @@ -30,23 +30,23 @@ config MCUMGR_TRANSPORT_REASSEMBLY Enable structures and functions needed for packet reassembly by SMP backend. config MCUMGR_TRANSPORT_NETBUF_COUNT - int "Number of mcumgr buffers" + int "Number of MCUmgr buffers" default 2 if MCUMGR_TRANSPORT_UDP default 4 help - The number of net_bufs to allocate for mcumgr. These buffers are - used for both requests and responses. + The number of net_bufs to allocate for MCUmgr. These buffers are used for both requests + and responses. config MCUMGR_TRANSPORT_NETBUF_SIZE - int "Size of each mcumgr buffer" + int "Size of each MCUmgr buffer" default 2048 if MCUMGR_TRANSPORT_UDP default 384 help - The size, in bytes, of each mcumgr buffer. This value must satisfy - the following relation: + The size, in bytes, of each MCUmgr buffer. This value must satisfy the following + relation: MCUMGR_TRANSPORT_NETBUF_SIZE >= transport-specific-MTU + transport-overhead - In case when MCUMGR_TRANSPORT_SHELL is enabled this value should be set to - at least MCUMGR_GRP_SHELL_BACKEND_DUMMY_BUF_SIZE + 32. + In case when MCUMGR_TRANSPORT_SHELL is enabled this value should be set to at least + CONFIG_SHELL_BACKEND_DUMMY_BUF_SIZE + 32. config MCUMGR_TRANSPORT_NETBUF_MIN_USER_DATA_SIZE int @@ -59,16 +59,15 @@ config MCUMGR_TRANSPORT_NETBUF_MIN_USER_DATA_SIZE Hidden option to determine minimum user data size. config MCUMGR_TRANSPORT_NETBUF_USER_DATA_SIZE - int "Size of mcumgr buffer user data" + int "Size of MCUmgr buffer user data" range MCUMGR_TRANSPORT_NETBUF_MIN_USER_DATA_SIZE 128 default MCUMGR_TRANSPORT_NETBUF_MIN_USER_DATA_SIZE help - The size, in bytes, of user data to allocate for each mcumgr buffer. + The size, in bytes, of user data to allocate for each MCUmgr buffer. - Different mcumgr transports impose different requirements for this - setting. A value of 4 is sufficient for UART and shell, a value of 8 - is sufficient for Bluetooth. For UDP, the userdata must be large - enough to hold IPv4/IPv6 addresses. + Different MCUmgr transports impose different requirements for this setting. A value of 4 + is sufficient for UART and shell, a value of 8 is sufficient for Bluetooth. For UDP, the + userdata must be large enough to hold IPv4/IPv6 addresses. module = MCUMGR_TRANSPORT module-str = mcumgr_transport diff --git a/subsys/mgmt/mcumgr/transport/Kconfig.bluetooth b/subsys/mgmt/mcumgr/transport/Kconfig.bluetooth index 1e1d5c7f6e44..573b45b7da40 100644 --- a/subsys/mgmt/mcumgr/transport/Kconfig.bluetooth +++ b/subsys/mgmt/mcumgr/transport/Kconfig.bluetooth @@ -10,7 +10,7 @@ # MCUMGR_TRANSPORT_BT_ menuconfig MCUMGR_TRANSPORT_BT - bool "Bluetooth mcumgr SMP transport" + bool "Bluetooth MCUmgr SMP transport" depends on BT_PERIPHERAL help Enables handling of SMP commands received over Bluetooth. @@ -21,8 +21,8 @@ config MCUMGR_TRANSPORT_BT_REASSEMBLY bool "Reassemble packets in Bluetooth SMP transport" select MCUMGR_TRANSPORT_REASSEMBLY help - When enabled, the SMP BT transport will buffer and reassemble received - packet fragments before passing it for further processing. + When enabled, the SMP BT transport will buffer and reassemble received packet fragments + before passing it for further processing. choice MCUMGR_TRANSPORT_BT_PERM prompt "Permission used for the SMP service" @@ -49,10 +49,9 @@ config MCUMGR_TRANSPORT_BT_CONN_PARAM_CONTROL depends on SYSTEM_WORKQUEUE_PRIORITY < 0 depends on BT_GAP_PERIPHERAL_PREF_PARAMS help - Enables support for requesting specific connection parameters when - SMP commands are handled. This option allows to speed up the command - exchange process. - Its recommended to enable this if SMP is used for DFU. + Enables support for requesting specific connection parameters when SMP commands are + handled. This option allows to speed up the command exchange process. + It is recommended to enable this if SMP is used for DFU. if MCUMGR_TRANSPORT_BT_CONN_PARAM_CONTROL @@ -89,17 +88,16 @@ config MCUMGR_TRANSPORT_BT_CONN_PARAM_CONTROL_RESTORE_TIME default 5000 range 1000 $(UINT16_MAX) help - The value is a time of inactivity on the SMP characteristic after which - connection parameters are restored to peripheral preferred values - (BT_GAP_PERIPHERAL_PREF_PARAMS). + The value is a time of inactivity on the SMP characteristic after which connection + parameters are restored to peripheral preferred values (BT_GAP_PERIPHERAL_PREF_PARAMS). config MCUMGR_TRANSPORT_BT_CONN_PARAM_CONTROL_RETRY_TIME int "Connection parameters update retry time in milliseconds" default 1000 range 1 5000 help - In case connection parameters update fails due to an error, this - option specifies the time of the next update attempt. + In case connection parameters update fails due to an error, this option specifies the + time of the next update attempt. endif # MCUMGR_TRASNPORT_BT_CONN_PARAM_CONTROL @@ -108,8 +106,8 @@ config MCUMGR_TRANSPORT_BT_DYNAMIC_SVC_REGISTRATION depends on BT_GATT_DYNAMIC_DB default y help - When enabled, the SMP service will be automatically registered at boot time - and can then be dynamically registered/unregistered using a dedicated API. - Otherwise, the SMP service will be statically defined and registered. + When enabled, the SMP service will be automatically registered at boot time and can then + be dynamically registered/unregistered using a dedicated API. Otherwise, the SMP service + will be statically defined and registered. endif # MCUMGR_TRANSPORT_BT diff --git a/subsys/mgmt/mcumgr/transport/Kconfig.dummy b/subsys/mgmt/mcumgr/transport/Kconfig.dummy index 7fbb61744d44..f0753a6ebf0e 100644 --- a/subsys/mgmt/mcumgr/transport/Kconfig.dummy +++ b/subsys/mgmt/mcumgr/transport/Kconfig.dummy @@ -13,8 +13,8 @@ menuconfig MCUMGR_TRANSPORT_DUMMY bool "Dummy SMP backend" depends on BASE64 help - Enables the dummy SMP backend which can be used for unit testing - SMP functionality without needing a real interface or driver. + Enables the dummy SMP backend which can be used for unit testing SMP functionality + without needing a real interface or driver. if MCUMGR_TRANSPORT_DUMMY @@ -22,8 +22,7 @@ config MCUMGR_TRANSPORT_DUMMY_RX_BUF_SIZE int "Size of receive buffer for dummy interface mcumgr fragments" default 128 help - Specifies the size of the mcumgr dummy backend receive buffer, - in bytes. This value must be large enough to accommodate any - line sent by an mcumgr client. + Specifies the size of the MCUmgr dummy backend receive buffer, in bytes. This value + must be large enough to accommodate any line sent by an MCUmgr client. endif # MCUMGR_TRANSPORT_DUMMY diff --git a/subsys/mgmt/mcumgr/transport/Kconfig.shell b/subsys/mgmt/mcumgr/transport/Kconfig.shell index 8198b0ebda6b..c0d63fa82347 100644 --- a/subsys/mgmt/mcumgr/transport/Kconfig.shell +++ b/subsys/mgmt/mcumgr/transport/Kconfig.shell @@ -10,13 +10,13 @@ # MCUMGR_TRANSPORT_SHELL_ menuconfig MCUMGR_TRANSPORT_SHELL - bool "Shell mcumgr SMP transport" + bool "Shell MCUmgr SMP transport" depends on SHELL depends on BASE64 depends on CRC help - Enables handling of SMP commands received over shell. This allows - the shell to be use for both mcumgr commands and shell commands. + Enables handling of SMP commands received over shell. This allows the shell to be use + for both MCUmgr commands and shell commands. if MCUMGR_TRANSPORT_SHELL @@ -24,8 +24,8 @@ config MCUMGR_TRANSPORT_SHELL_MTU int "Shell SMP MTU" default 256 help - Maximum size of SMP frames sent and received over shell. This value - must satisfy the following relation: + Maximum size of SMP frames sent and received over shell. This value must satisfy the + following relation: MCUMGR_TRANSPORT_SHELL_MTU <= MCUMGR_TRANSPORT_NETBUF_SIZE + 2 config MCUMGR_TRANSPORT_SHELL_RX_BUF_COUNT @@ -37,18 +37,16 @@ config MCUMGR_TRANSPORT_SHELL_RX_BUF_COUNT config MCUMGR_TRANSPORT_SHELL_INPUT_TIMEOUT bool "Shell input expiration" help - If enabled, will time out a partial or erroneous MCUmgr command - received via the shell transport after a given time. This prevents - the shell from becoming locked if it never receives the full packet - that a header indicated it would receive. + If enabled, will time out a partial or erroneous MCUmgr command received via the shell + transport after a given time. This prevents the shell from becoming locked if it never + receives the full packet that a header indicated it would receive. config MCUMGR_TRANSPORT_SHELL_INPUT_TIMEOUT_TIME int "Shell input expiration timeout" depends on MCUMGR_TRANSPORT_SHELL_INPUT_TIMEOUT default 3000 help - Time (in msec) after receiving a valid MCUmgr header on the serial - transport before considering it as timed out and returning the shell - to normal operation. + Time (in msec) after receiving a valid MCUmgr header on the serial transport before + considering it as timed out and returning the shell to normal operation. endif # MCUMGR_TRANSPORT_SHELL diff --git a/subsys/mgmt/mcumgr/transport/Kconfig.uart b/subsys/mgmt/mcumgr/transport/Kconfig.uart index e5d2bd697cc8..096819b0c20e 100644 --- a/subsys/mgmt/mcumgr/transport/Kconfig.uart +++ b/subsys/mgmt/mcumgr/transport/Kconfig.uart @@ -10,16 +10,15 @@ # MCUMGR_TRANSPORT_UART_ menuconfig MCUMGR_TRANSPORT_UART - bool "UART mcumgr SMP transport" + bool "UART MCUmgr SMP transport" depends on CONSOLE depends on BASE64 depends on CRC select UART_MCUMGR help - Enables handling of SMP commands received over UART. This is a - lightweight alternative to MCUMGR_TRANSPORT_SHELL. It allows mcumgr - commands to be received over UART without requiring an additional - thread. + Enables handling of SMP commands received over UART. This is a lightweight alternative + to MCUMGR_TRANSPORT_SHELL. It allows MCUmgr commands to be received over UART without + requiring an additional thread. if MCUMGR_TRANSPORT_UART @@ -28,7 +27,7 @@ if UART_ASYNC_API menuconfig MCUMGR_TRANSPORT_UART_ASYNC bool "Use async UART API when available" help - The option enables use of UART async API when available for selected mcumgr uart port. + The option enables use of UART async API when available for selected MCUmgr UART port. if MCUMGR_TRANSPORT_UART_ASYNC @@ -39,7 +38,7 @@ config MCUMGR_TRANSPORT_UART_ASYNC_BUFS help The asynchronous UART API requires registering RX buffers for received data; when the RX reaches the end of a buffer, it will send event requesting next buffer, to be able to - receive data without stopping due to running out of buffer space. At least two buffers + receive data without stopping due to running out of buffer space. At least two buffers area required for smooth RX operation. config MCUMGR_TRANSPORT_UART_ASYNC_BUF_SIZE @@ -56,8 +55,8 @@ config MCUMGR_TRANSPORT_UART_MTU int "UART SMP MTU" default 256 help - Maximum size of SMP frames sent and received over UART, in bytes. - This value must satisfy the following relation: + Maximum size of SMP frames sent and received over UART, in bytes. This value must + satisfy the following relation: MCUMGR_TRANSPORT_UART_MTU <= MCUMGR_TRANSPORT_NETBUF_SIZE + 2 endif # MCUMGR_TRANSPORT_UART diff --git a/subsys/mgmt/mcumgr/transport/Kconfig.udp b/subsys/mgmt/mcumgr/transport/Kconfig.udp index 19de5cf3ce59..4d93f47aabaa 100644 --- a/subsys/mgmt/mcumgr/transport/Kconfig.udp +++ b/subsys/mgmt/mcumgr/transport/Kconfig.udp @@ -10,7 +10,7 @@ # MCUMGR_TRANSPORT_UDP_ menuconfig MCUMGR_TRANSPORT_UDP - bool "UDP mcumgr SMP transport" + bool "UDP MCUmgr SMP transport" depends on NET_UDP depends on NET_SOCKETS select NET_CONNECTION_MANAGER @@ -88,9 +88,8 @@ config MCUMGR_TRANSPORT_UDP_AUTOMATIC_INIT default y depends on !MCUMGR_TRANSPORT_UDP_DTLS help - Enable starting the UDP SMP transport at boot time without needing - any code in the application to do this, otherwise will need the user - application to manually start and stop the transport using - `smp_udp_open` and `smp_udp_close`. + Enable starting the UDP SMP transport at boot time without needing any code in the + application to do this, otherwise will need the user application to manually start and + stop the transport using `smp_udp_open` and `smp_udp_close`. endif # MCUMGR_TRANSPORT_UDP From e3371aaf247a72194aa7f90d0f66077af1bd9eab Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Tue, 20 Jan 2026 12:00:00 +0000 Subject: [PATCH 2201/3659] mgmt: mcumgr: Add name to CMake libraries Adds names to these libraries to prevent using auto-generated names of the paths, which can be longer than the maximum supported length on the current version of gcc for windows Signed-off-by: Jamie McCrae --- subsys/mgmt/mcumgr/grp/enum_mgmt/CMakeLists.txt | 2 +- subsys/mgmt/mcumgr/grp/fs_mgmt/CMakeLists.txt | 2 +- subsys/mgmt/mcumgr/grp/img_mgmt/CMakeLists.txt | 2 +- subsys/mgmt/mcumgr/grp/img_mgmt_client/CMakeLists.txt | 2 +- subsys/mgmt/mcumgr/grp/os_mgmt/CMakeLists.txt | 2 +- subsys/mgmt/mcumgr/grp/os_mgmt_client/CMakeLists.txt | 2 +- subsys/mgmt/mcumgr/grp/settings_mgmt/CMakeLists.txt | 2 +- subsys/mgmt/mcumgr/grp/shell_mgmt/CMakeLists.txt | 2 +- subsys/mgmt/mcumgr/grp/stat_mgmt/CMakeLists.txt | 2 +- subsys/mgmt/mcumgr/grp/zephyr_basic/CMakeLists.txt | 2 +- subsys/mgmt/mcumgr/mgmt/CMakeLists.txt | 2 +- subsys/mgmt/mcumgr/smp/CMakeLists.txt | 2 +- subsys/mgmt/mcumgr/smp_client/CMakeLists.txt | 2 +- subsys/mgmt/mcumgr/transport/CMakeLists.txt | 2 +- subsys/mgmt/mcumgr/util/CMakeLists.txt | 2 +- 15 files changed, 15 insertions(+), 15 deletions(-) diff --git a/subsys/mgmt/mcumgr/grp/enum_mgmt/CMakeLists.txt b/subsys/mgmt/mcumgr/grp/enum_mgmt/CMakeLists.txt index 745539eed2a8..9aa3c37db9d6 100644 --- a/subsys/mgmt/mcumgr/grp/enum_mgmt/CMakeLists.txt +++ b/subsys/mgmt/mcumgr/grp/enum_mgmt/CMakeLists.txt @@ -6,7 +6,7 @@ # Enumeration management group public API is exported by MCUmgr interface API, # when Enumeration Management is enabled. -zephyr_library() +zephyr_library_named(mcumgr_grp_enum_mgmt) zephyr_library_sources(src/enum_mgmt.c) zephyr_library_include_directories(include) diff --git a/subsys/mgmt/mcumgr/grp/fs_mgmt/CMakeLists.txt b/subsys/mgmt/mcumgr/grp/fs_mgmt/CMakeLists.txt index a8d819652f51..0286fa083cc5 100644 --- a/subsys/mgmt/mcumgr/grp/fs_mgmt/CMakeLists.txt +++ b/subsys/mgmt/mcumgr/grp/fs_mgmt/CMakeLists.txt @@ -8,7 +8,7 @@ # File System management group public API is exposed by MCUmgr API # interface, when File System management is enabled. -zephyr_library() +zephyr_library_named(mcumgr_grp_fs_mgmt) zephyr_library_sources(src/fs_mgmt.c) zephyr_library_sources_ifdef(CONFIG_MCUMGR_GRP_FS_CHECKSUM_HASH src/fs_mgmt_hash_checksum.c) zephyr_library_sources_ifdef(CONFIG_MCUMGR_GRP_FS_CHECKSUM_IEEE_CRC32 src/fs_mgmt_hash_checksum_crc32.c) diff --git a/subsys/mgmt/mcumgr/grp/img_mgmt/CMakeLists.txt b/subsys/mgmt/mcumgr/grp/img_mgmt/CMakeLists.txt index 3fc140ce1477..af22908f5b30 100644 --- a/subsys/mgmt/mcumgr/grp/img_mgmt/CMakeLists.txt +++ b/subsys/mgmt/mcumgr/grp/img_mgmt/CMakeLists.txt @@ -7,7 +7,7 @@ # Image management group public API is exported by MCUmgr interface API, # when Image Management is enabled. -zephyr_library() +zephyr_library_named(mcumgr_grp_img_mgmt) zephyr_library_sources( src/zephyr_img_mgmt.c src/img_mgmt_state.c diff --git a/subsys/mgmt/mcumgr/grp/img_mgmt_client/CMakeLists.txt b/subsys/mgmt/mcumgr/grp/img_mgmt_client/CMakeLists.txt index 7bf85b6b5872..768f9db0917d 100644 --- a/subsys/mgmt/mcumgr/grp/img_mgmt_client/CMakeLists.txt +++ b/subsys/mgmt/mcumgr/grp/img_mgmt_client/CMakeLists.txt @@ -7,7 +7,7 @@ # Image management client group public API is exported by MCUmgr interface API, # when Image Management client is enabled. -zephyr_library() +zephyr_library_named(mcumgr_grp_img_mgmt_client) zephyr_library_sources( src/img_mgmt_client.c ) diff --git a/subsys/mgmt/mcumgr/grp/os_mgmt/CMakeLists.txt b/subsys/mgmt/mcumgr/grp/os_mgmt/CMakeLists.txt index 091d66c250fe..3af71b9cf56f 100644 --- a/subsys/mgmt/mcumgr/grp/os_mgmt/CMakeLists.txt +++ b/subsys/mgmt/mcumgr/grp/os_mgmt/CMakeLists.txt @@ -7,7 +7,7 @@ # OS Management group public API is exposed through zephyr_interface, # when OS Management is enabled. -zephyr_library() +zephyr_library_named(mcumgr_grp_os_mgmt) zephyr_library_sources(src/os_mgmt.c) zephyr_library_include_directories(include) diff --git a/subsys/mgmt/mcumgr/grp/os_mgmt_client/CMakeLists.txt b/subsys/mgmt/mcumgr/grp/os_mgmt_client/CMakeLists.txt index 964be958047b..067f0462efd5 100644 --- a/subsys/mgmt/mcumgr/grp/os_mgmt_client/CMakeLists.txt +++ b/subsys/mgmt/mcumgr/grp/os_mgmt_client/CMakeLists.txt @@ -6,6 +6,6 @@ # OS Management client group public API is exposed through zephyr_interface, # when OS Management is enabled. -zephyr_library() +zephyr_library_named(mcumgr_grp_os_mgmt_client) zephyr_library_sources(src/os_mgmt_client.c) zephyr_library_include_directories(include) diff --git a/subsys/mgmt/mcumgr/grp/settings_mgmt/CMakeLists.txt b/subsys/mgmt/mcumgr/grp/settings_mgmt/CMakeLists.txt index a069a3c46eb5..f22c0ce0a04c 100644 --- a/subsys/mgmt/mcumgr/grp/settings_mgmt/CMakeLists.txt +++ b/subsys/mgmt/mcumgr/grp/settings_mgmt/CMakeLists.txt @@ -6,7 +6,7 @@ # Settings management group public API is exposed by MCUmgr API # interface, when settings management is enabled. -zephyr_library() +zephyr_library_named(mcumgr_grp_settings_mgmt) zephyr_library_sources(src/settings_mgmt.c) if(CONFIG_MCUMGR_GRP_SETTINGS AND NOT CONFIG_MCUMGR_GRP_SETTINGS_ACCESS_HOOK) diff --git a/subsys/mgmt/mcumgr/grp/shell_mgmt/CMakeLists.txt b/subsys/mgmt/mcumgr/grp/shell_mgmt/CMakeLists.txt index b381f55828e9..eaa04977b0b2 100644 --- a/subsys/mgmt/mcumgr/grp/shell_mgmt/CMakeLists.txt +++ b/subsys/mgmt/mcumgr/grp/shell_mgmt/CMakeLists.txt @@ -7,7 +7,7 @@ # Shell Management group public API is exposed by MCUmgr API # interface, when Shell Management is enabled. -zephyr_library() +zephyr_library_named(mcumgr_grp_shell_mgmt) zephyr_library_sources(src/shell_mgmt.c) zephyr_library_include_directories(include) diff --git a/subsys/mgmt/mcumgr/grp/stat_mgmt/CMakeLists.txt b/subsys/mgmt/mcumgr/grp/stat_mgmt/CMakeLists.txt index 6c0fde964b34..8d14c5a27666 100644 --- a/subsys/mgmt/mcumgr/grp/stat_mgmt/CMakeLists.txt +++ b/subsys/mgmt/mcumgr/grp/stat_mgmt/CMakeLists.txt @@ -7,7 +7,7 @@ # Statistics management group public API is exposed by MCUmgr API # interface, when Statistics management is enabled. -zephyr_library() +zephyr_library_named(mcumgr_grp_stat_mgmt) zephyr_library_sources(src/stat_mgmt.c) zephyr_library_include_directories(include) diff --git a/subsys/mgmt/mcumgr/grp/zephyr_basic/CMakeLists.txt b/subsys/mgmt/mcumgr/grp/zephyr_basic/CMakeLists.txt index 0db02be08896..050d18374af1 100644 --- a/subsys/mgmt/mcumgr/grp/zephyr_basic/CMakeLists.txt +++ b/subsys/mgmt/mcumgr/grp/zephyr_basic/CMakeLists.txt @@ -4,5 +4,5 @@ # SPDX-License-Identifier: Apache-2.0 # -zephyr_library() +zephyr_library_named(mcumgr_grp_zephyr_basic) zephyr_library_sources_ifdef(CONFIG_MCUMGR_GRP_ZBASIC_STORAGE_ERASE src/basic_mgmt.c) diff --git a/subsys/mgmt/mcumgr/mgmt/CMakeLists.txt b/subsys/mgmt/mcumgr/mgmt/CMakeLists.txt index ceb6339cfba4..4bc6aa86fc9b 100644 --- a/subsys/mgmt/mcumgr/mgmt/CMakeLists.txt +++ b/subsys/mgmt/mcumgr/mgmt/CMakeLists.txt @@ -5,7 +5,7 @@ # SPDX-License-Identifier: Apache-2.0 # Provides MCUmgr services, group registration, event handling etc. -zephyr_library() +zephyr_library_named(mcumgr_mgmt) zephyr_library_sources(src/mgmt.c) zephyr_library_include_directories(include) diff --git a/subsys/mgmt/mcumgr/smp/CMakeLists.txt b/subsys/mgmt/mcumgr/smp/CMakeLists.txt index 4bf9159ab60c..c0f29a474428 100644 --- a/subsys/mgmt/mcumgr/smp/CMakeLists.txt +++ b/subsys/mgmt/mcumgr/smp/CMakeLists.txt @@ -5,5 +5,5 @@ # SPDX-License-Identifier: Apache-2.0 # # Protocol API is only exposed to MCUmgr internals. -zephyr_library() +zephyr_library_named(mcumgr_smp) zephyr_library_sources(src/smp.c) diff --git a/subsys/mgmt/mcumgr/smp_client/CMakeLists.txt b/subsys/mgmt/mcumgr/smp_client/CMakeLists.txt index 32907b0c7531..031b41f9b2d3 100644 --- a/subsys/mgmt/mcumgr/smp_client/CMakeLists.txt +++ b/subsys/mgmt/mcumgr/smp_client/CMakeLists.txt @@ -5,5 +5,5 @@ # # Protocol API is only exposed to MCUmgr internals. -zephyr_library() +zephyr_library_named(mcumgr_smp_client) zephyr_library_sources(src/client.c) diff --git a/subsys/mgmt/mcumgr/transport/CMakeLists.txt b/subsys/mgmt/mcumgr/transport/CMakeLists.txt index 3a85e39b38bf..e99752777a49 100644 --- a/subsys/mgmt/mcumgr/transport/CMakeLists.txt +++ b/subsys/mgmt/mcumgr/transport/CMakeLists.txt @@ -7,7 +7,7 @@ # mgmt_mcumgr_transport covers interface API, allowing to implement transports. # It is exposed with mgmt_mcumgr interface. -zephyr_library() +zephyr_library_named(mcumgr_transport) zephyr_library_sources(src/smp.c) zephyr_library_sources_ifdef(CONFIG_MCUMGR_TRANSPORT_REASSEMBLY diff --git a/subsys/mgmt/mcumgr/util/CMakeLists.txt b/subsys/mgmt/mcumgr/util/CMakeLists.txt index fa3beba30951..d885af18e888 100644 --- a/subsys/mgmt/mcumgr/util/CMakeLists.txt +++ b/subsys/mgmt/mcumgr/util/CMakeLists.txt @@ -8,7 +8,7 @@ # MCUmgr utilities, for use within the library. # API interface for utilities is exposed by mgmt_mcumgr_util, # and should not be exposed outside of mgmt_mcumgr. -zephyr_library() +zephyr_library_named(mcumgr_util) zephyr_library_sources(src/zcbor_bulk.c) zephyr_include_directories(include) From f6c7299295d61c64cd2217bdad40c6235470343d Mon Sep 17 00:00:00 2001 From: Axel Le Bourhis Date: Tue, 13 Jan 2026 14:56:02 +0100 Subject: [PATCH 2202/3659] hal_nxp: move multicore middleware to mcux-sdk-ng integration Move the multicore middleware to the new mcux-sdk-ng integration from hal_nxp, instead of using the legacy integration method. This will allow for easier integration of future releases. Signed-off-by: Axel Le Bourhis --- modules/hal_nxp/mcux/Kconfig.mcux | 5 +++++ .../mcux/mcux-sdk-ng/middleware/middleware.cmake | 1 + .../mcux/mcux-sdk-ng/middleware/multicore.cmake | 14 ++++++++++++++ soc/nxp/mcx/mcxw/mcxw7xx/Kconfig | 8 ++++++++ west.yml | 2 +- 5 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 modules/hal_nxp/mcux/mcux-sdk-ng/middleware/multicore.cmake diff --git a/modules/hal_nxp/mcux/Kconfig.mcux b/modules/hal_nxp/mcux/Kconfig.mcux index 628428c57d92..a771ce44624b 100644 --- a/modules/hal_nxp/mcux/Kconfig.mcux +++ b/modules/hal_nxp/mcux/Kconfig.mcux @@ -93,6 +93,11 @@ config NXP_IEEE802154_MAC If enabled, the NBU firmware used by the device will be use the 802.15.4 MAC interface. +config NXP_MULTICORE + bool "NXP Multicore Manager support" + help + Includes NXP Multicore Manager support. + endif # HAS_MCUX config BT_NXP_PCM_PINS_DIR_REVERSE diff --git a/modules/hal_nxp/mcux/mcux-sdk-ng/middleware/middleware.cmake b/modules/hal_nxp/mcux/mcux-sdk-ng/middleware/middleware.cmake index f0ee5e0b233a..31d094b7be05 100644 --- a/modules/hal_nxp/mcux/mcux-sdk-ng/middleware/middleware.cmake +++ b/modules/hal_nxp/mcux/mcux-sdk-ng/middleware/middleware.cmake @@ -57,3 +57,4 @@ add_subdirectory(${MCUX_SDK_NG_DIR}/middleware/usb ) include(${CMAKE_CURRENT_LIST_DIR}/connectivity_framework.cmake) +include(${CMAKE_CURRENT_LIST_DIR}/multicore.cmake) diff --git a/modules/hal_nxp/mcux/mcux-sdk-ng/middleware/multicore.cmake b/modules/hal_nxp/mcux/mcux-sdk-ng/middleware/multicore.cmake new file mode 100644 index 000000000000..23b93441b7da --- /dev/null +++ b/modules/hal_nxp/mcux/mcux-sdk-ng/middleware/multicore.cmake @@ -0,0 +1,14 @@ +if(CONFIG_NXP_MULTICORE) + set(CONFIG_MCUX_COMPONENT_middleware.multicore.mcmgr ON) + set_variable_ifdef(CONFIG_SOC_MCXW716C CONFIG_MCUX_COMPONENT_middleware.multicore.mcmgr.mcxw716) + set_variable_ifdef(CONFIG_SOC_MCXW727C_CPU0 CONFIG_MCUX_COMPONENT_middleware.multicore.mcmgr.mcxw727) + + set(CONFIG_MCUX_COMPONENT_middleware.multicore.rpmsg-lite ON) + set(CONFIG_MCUX_COMPONENT_middleware.multicore.rpmsg-lite.zephyr ON) + set_variable_ifdef(CONFIG_SOC_MCXW716C CONFIG_MCUX_COMPONENT_middleware.multicore.rpmsg-lite.mcxw71x) + set_variable_ifdef(CONFIG_SOC_MCXW727C_CPU0 CONFIG_MCUX_COMPONENT_middleware.multicore.rpmsg-lite.mcxw72x) + + add_subdirectory(${MCUX_SDK_NG_DIR}/middleware/mcuxsdk-middleware-multicore + ${CMAKE_CURRENT_BINARY_DIR}/mcuxsdk-middleware-multicore + ) +endif() diff --git a/soc/nxp/mcx/mcxw/mcxw7xx/Kconfig b/soc/nxp/mcx/mcxw/mcxw7xx/Kconfig index 29ab1b34bc9c..0c1ee475850e 100644 --- a/soc/nxp/mcx/mcxw/mcxw7xx/Kconfig +++ b/soc/nxp/mcx/mcxw/mcxw7xx/Kconfig @@ -7,3 +7,11 @@ rsource "../../../common/Kconfig.nbu" config MCUX_CORE_SUFFIX default "_cm33_core0" if SOC_MCXW727C_CPU0 default "_cm33_core1" if SOC_MCXW727C_CPU1 + +config SOC_MCXW716C + bool + select NXP_MULTICORE if NXP_NBU + +config SOC_MCXW727C_CPU0 + bool + select NXP_MULTICORE if NXP_NBU diff --git a/west.yml b/west.yml index 67e8e1c13d75..e70bf2db431b 100644 --- a/west.yml +++ b/west.yml @@ -210,7 +210,7 @@ manifest: groups: - hal - name: hal_nxp - revision: 0a0c1680179b286997f0bfec4cb89ca90f2b8685 + revision: 26ab97dc6e55e01a43db486ace71b57b6ee3ff06 path: modules/hal/nxp groups: - hal From cf356b32a1971a063f5cd4f8104ef2879afdd731 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Wed, 14 Jan 2026 12:18:05 +0000 Subject: [PATCH 2203/3659] tests: twister: only instantiate the Linux instance This test has been changed in d7a8f29ce71 to drop all the steps that were running on the other platforms, change it to just instantiate the Linux instance and drop the conditional. Signed-off-by: Fabio Baltieri --- .github/workflows/twister_tests_blackbox.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/twister_tests_blackbox.yml b/.github/workflows/twister_tests_blackbox.yml index 4cd8f3531215..8fc09d7c040c 100644 --- a/.github/workflows/twister_tests_blackbox.yml +++ b/.github/workflows/twister_tests_blackbox.yml @@ -27,9 +27,8 @@ jobs: strategy: matrix: python-version: ['3.10', '3.11', '3.12', '3.13'] - os: [ubuntu-24.04, macos-14, windows-2022] fail-fast: false - runs-on: ${{ matrix.os }} + runs-on: ubuntu-24.04 steps: - name: Checkout uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 @@ -54,7 +53,6 @@ jobs: west-project-filter: -nrf_hw_models,+cmsis,+hal_xtensa,+cmsis_6 - name: Run Pytest For Twister Black Box Tests - if: ${{ runner.os == 'Linux' }} working-directory: zephyr shell: bash env: From 6df440012be5e18f4ccb0303b562af4e6b36b9ca Mon Sep 17 00:00:00 2001 From: Yongxu Wang Date: Fri, 16 Jan 2026 14:08:48 +0800 Subject: [PATCH 2204/3659] drivers: power_domain: add SCMI power domain driver Add ARM SCMI-based power domain driver for managing power domains through the SCMI protocol. Signed-off-by: Yongxu Wang --- drivers/power_domain/CMakeLists.txt | 1 + drivers/power_domain/Kconfig | 19 +++++ drivers/power_domain/power_domain_arm_scmi.c | 82 +++++++++++++++++++ .../power-domain/arm,scmi-power-domain.yaml | 13 +++ 4 files changed, 115 insertions(+) create mode 100644 drivers/power_domain/power_domain_arm_scmi.c create mode 100644 dts/bindings/power-domain/arm,scmi-power-domain.yaml diff --git a/drivers/power_domain/CMakeLists.txt b/drivers/power_domain/CMakeLists.txt index 91767e44ce2e..8d1afcb2ef59 100644 --- a/drivers/power_domain/CMakeLists.txt +++ b/drivers/power_domain/CMakeLists.txt @@ -4,6 +4,7 @@ zephyr_library() # zephyr-keep-sorted-start +zephyr_library_sources_ifdef(CONFIG_POWER_DOMAIN_ARM_SCMI power_domain_arm_scmi.c) zephyr_library_sources_ifdef(CONFIG_POWER_DOMAIN_GPIO power_domain_gpio.c) zephyr_library_sources_ifdef(CONFIG_POWER_DOMAIN_GPIO_MONITOR power_domain_gpio_monitor.c) zephyr_library_sources_ifdef(CONFIG_POWER_DOMAIN_INTEL_ADSP power_domain_intel_adsp.c) diff --git a/drivers/power_domain/Kconfig b/drivers/power_domain/Kconfig index a064b1e94ca1..2859b461342d 100644 --- a/drivers/power_domain/Kconfig +++ b/drivers/power_domain/Kconfig @@ -123,6 +123,25 @@ config SOC_POWER_DOMAIN_INIT endif #POWER_DOMAIN_TISCI +config POWER_DOMAIN_ARM_SCMI + bool "ARM SCMI Power Domain driver" + default y + depends on ARM_SCMI_POWER_DOMAIN_HELPERS + depends on DT_HAS_ARM_SCMI_POWER_DOMAIN_ENABLED + select DEVICE_DEPS + help + Enable SCMI-based power domain driver. + +if POWER_DOMAIN_ARM_SCMI + +config POWER_DOMAIN_ARM_SCMI_INIT_PRIORITY + int "ARM SCMI PD driver init priority" + default 10 + help + ARM SCMI PD driver initialization priority. + +endif #POWER_DOMAIN_ARM_SCMI + # zephyr-keep-sorted-start rsource "Kconfig.nrfs_gdpwr" rsource "Kconfig.nrfs_swext" diff --git a/drivers/power_domain/power_domain_arm_scmi.c b/drivers/power_domain/power_domain_arm_scmi.c new file mode 100644 index 000000000000..2b7cca0a8530 --- /dev/null +++ b/drivers/power_domain/power_domain_arm_scmi.c @@ -0,0 +1,82 @@ +/* + * Copyright 2026 NXP + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT arm_scmi_power_domain + +#include +#include +#include +#include + +#include + +LOG_MODULE_REGISTER(scmi_power_domain, CONFIG_POWER_DOMAIN_LOG_LEVEL); + +struct scmi_pd_config { + uint32_t domain_id; +}; + +static int scmi_pd_pm_action(const struct device *dev, + enum pm_device_action action) +{ + const struct scmi_pd_config *cfg = dev->config; + struct scmi_power_state_config pwr_cfg; + int ret; + + LOG_INF("attempting PM action %d on domain %d", action, cfg->domain_id); + + switch (action) { + case PM_DEVICE_ACTION_RESUME: + pwr_cfg.domain_id = cfg->domain_id; + pwr_cfg.flags = 0; + pwr_cfg.power_state = SCMI_POWER_STATE_GENERIC_ON; + + ret = scmi_power_state_set(&pwr_cfg); + if (ret < 0) { + return ret; + } + pm_device_children_action_run(dev, PM_DEVICE_ACTION_TURN_ON, NULL); + break; + case PM_DEVICE_ACTION_SUSPEND: + pm_device_children_action_run(dev, PM_DEVICE_ACTION_TURN_OFF, NULL); + + pwr_cfg.domain_id = cfg->domain_id; + pwr_cfg.flags = 0; + pwr_cfg.power_state = SCMI_POWER_STATE_GENERIC_OFF; + + ret = scmi_power_state_set(&pwr_cfg); + if (ret < 0) { + return ret; + } + break; + case PM_DEVICE_ACTION_TURN_ON: + break; + case PM_DEVICE_ACTION_TURN_OFF: + break; + default: + return -ENOTSUP; + } + + return 0; +} + +static int scmi_pd_init(const struct device *dev) +{ + return pm_device_driver_init(dev, scmi_pd_pm_action); +} +#define SCMI_PD_DEVICE(inst) \ + static const struct scmi_pd_config scmi_pd_cfg_##inst = { \ + .domain_id = DT_INST_REG_ADDR(inst), \ + }; \ + \ + PM_DEVICE_DT_INST_DEFINE(inst, scmi_pd_pm_action); \ + DEVICE_DT_INST_DEFINE(inst, scmi_pd_init, \ + PM_DEVICE_DT_INST_GET(inst), \ + NULL, \ + &scmi_pd_cfg_##inst, \ + PRE_KERNEL_2, \ + CONFIG_POWER_DOMAIN_ARM_SCMI_INIT_PRIORITY, \ + NULL); +DT_INST_FOREACH_STATUS_OKAY(SCMI_PD_DEVICE) diff --git a/dts/bindings/power-domain/arm,scmi-power-domain.yaml b/dts/bindings/power-domain/arm,scmi-power-domain.yaml new file mode 100644 index 000000000000..66a732af25e7 --- /dev/null +++ b/dts/bindings/power-domain/arm,scmi-power-domain.yaml @@ -0,0 +1,13 @@ +# Copyright 2026 NXP +# SPDX-License-Identifier: Apache-2.0 + +description: ARM SCMI Power Domain + +compatible: "arm,scmi-power-domain" + +include: power-domain.yaml + +properties: + reg: + required: true + description: SCMI power domain ID From ae6be9bed69dc9f1471df935a29fa45499b1d1a7 Mon Sep 17 00:00:00 2001 From: Yongxu Wang Date: Fri, 16 Jan 2026 14:12:17 +0800 Subject: [PATCH 2205/3659] dts: arm: nxp: imx95_m7: add NETC power domain support Add SCMI power domain definition for NETC (Network Controller) subsystem. Signed-off-by: Yongxu Wang --- dts/arm/nxp/nxp_imx95_m7.dtsi | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/dts/arm/nxp/nxp_imx95_m7.dtsi b/dts/arm/nxp/nxp_imx95_m7.dtsi index d345f8d48042..7937ab7ab01d 100644 --- a/dts/arm/nxp/nxp_imx95_m7.dtsi +++ b/dts/arm/nxp/nxp_imx95_m7.dtsi @@ -108,6 +108,17 @@ }; }; + power-domains { + #address-cells = <1>; + #size-cells = <0>; + + netc_mix: power-domain@12 { + compatible = "arm,scmi-power-domain"; + reg = <18>; + #power-domain-cells = <0>; + }; + }; + soc { itcm: itcm@0 { compatible = "zephyr,memory-region", "nxp,imx-itcm"; @@ -749,6 +760,7 @@ reg-names = "ierb", "prb", "netcmix"; #address-cells = <1>; #size-cells = <1>; + power-domains = <&netc_mix>; ranges; netc: ethernet { @@ -766,6 +778,7 @@ reg-names = "port", "pfconfig"; mac-index = <0>; si-index = <0>; + power-domains = <&netc_mix>; status = "disabled"; }; @@ -776,6 +789,7 @@ reg-names = "port", "pfconfig"; mac-index = <1>; si-index = <1>; + power-domains = <&netc_mix>; status = "disabled"; }; @@ -786,6 +800,7 @@ reg-names = "port", "pfconfig"; mac-index = <2>; si-index = <2>; + power-domains = <&netc_mix>; status = "disabled"; }; @@ -797,6 +812,7 @@ clocks = <&scmi_clk IMX95_CLK_ENET>; #address-cells = <1>; #size-cells = <0>; + power-domains = <&netc_mix>; status = "disabled"; }; @@ -804,6 +820,7 @@ compatible = "nxp,netc-ptp-clock"; reg = <0x4ccc0000 0x10000>; clocks = <&scmi_clk IMX95_CLK_ENET>; + power-domains = <&netc_mix>; status = "disabled"; }; }; From 1b5e94197bc45303949f13ff1f3e3fe420327d38 Mon Sep 17 00:00:00 2001 From: Yongxu Wang Date: Fri, 16 Jan 2026 14:20:04 +0800 Subject: [PATCH 2206/3659] soc: nxp: imx95_m7: enable power domain support Enable power domain support for i.MX95 M7 core when PM_DEVICE is enabled. Signed-off-by: Yongxu Wang --- soc/nxp/imx/imx9/imx95/Kconfig.defconfig.mimx95.m7 | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/soc/nxp/imx/imx9/imx95/Kconfig.defconfig.mimx95.m7 b/soc/nxp/imx/imx9/imx95/Kconfig.defconfig.mimx95.m7 index 7addf0e79919..c0f40a2a4383 100644 --- a/soc/nxp/imx/imx9/imx95/Kconfig.defconfig.mimx95.m7 +++ b/soc/nxp/imx/imx9/imx95/Kconfig.defconfig.mimx95.m7 @@ -57,6 +57,13 @@ config IDLE_STACK_SIZE default 640 endif +if PM_DEVICE + +config POWER_DOMAIN + default y + +endif # PM_DEVICE + config ROM_START_OFFSET default 0x800 if BOOTLOADER_MCUBOOT From 551843cff06e7d8a27e2f7fe4d253950e1b84dd7 Mon Sep 17 00:00:00 2001 From: Gaetan Perrot Date: Tue, 20 Jan 2026 19:23:20 +0900 Subject: [PATCH 2207/3659] boards: nxp: fix typos in comments Fix spelling and wording issues in comments across NXP board FlexSPI NOR configuration headers. No functional change. Signed-off-by: Gaetan Perrot --- boards/nxp/frdm_mcxn947/xip/mcxn_flexspi_nor_config.h | 6 +++--- boards/nxp/mcx_nx4x_evk/xip/mcxn_flexspi_nor_config.h | 6 +++--- .../mimxrt1010_evk/xip/evkmimxrt1010_flexspi_nor_config.h | 6 +++--- .../mimxrt1015_evk/xip/evkmimxrt1015_flexspi_nor_config.h | 6 +++--- .../mimxrt1020_evk/xip/evkmimxrt1020_flexspi_nor_config.h | 6 +++--- .../mimxrt1024_evk/xip/evkmimxrt1024_flexspi_nor_config.h | 6 +++--- .../mimxrt1040_evk/xip/evkmimxrt1040_flexspi_nor_config.h | 6 +++--- .../mimxrt1050_evk/xip/evkbimxrt1050_flexspi_nor_config.h | 6 +++--- .../mimxrt1060_evk/xip/evkbmimxrt1060_flexspi_nor_config.h | 6 +++--- .../mimxrt1060_evk/xip/evkmimxrt1060_flexspi_nor_config.h | 6 +++--- .../mimxrt1064_evk/xip/evkmimxrt1064_flexspi_nor_config.h | 6 +++--- .../mimxrt1160_evk/xip/evkmimxrt1160_flexspi_nor_config.h | 6 +++--- .../mimxrt1170_evk/xip/evkbmimxrt1170_flexspi_nor_config.h | 6 +++--- .../mimxrt1170_evk/xip/evkmimxrt1170_flexspi_nor_config.h | 6 +++--- .../mimxrt1180_evk/xip/evkmimxrt1180_flexspi_nor_config.h | 2 +- boards/nxp/mimxrt595_evk/flash_config/flash_config.h | 2 +- boards/nxp/mimxrt685_evk/flash_config/flash_config.h | 6 +++--- boards/nxp/mimxrt700_evk/flash_config/flash_config.h | 6 +++--- .../nxp/vmu_rt1170/xip/evkmimxrt1170_flexspi_nor_config.h | 6 +++--- 19 files changed, 53 insertions(+), 53 deletions(-) diff --git a/boards/nxp/frdm_mcxn947/xip/mcxn_flexspi_nor_config.h b/boards/nxp/frdm_mcxn947/xip/mcxn_flexspi_nor_config.h index 49ed7a5699f6..800a92345c52 100644 --- a/boards/nxp/frdm_mcxn947/xip/mcxn_flexspi_nor_config.h +++ b/boards/nxp/frdm_mcxn947/xip/mcxn_flexspi_nor_config.h @@ -109,7 +109,7 @@ enum { FLEXSPI_MISC_OFFSET_SAFE_CONFIG_FREQ_ENABLE = 4, /* Bit for Pad setting override enable */ FLEXSPI_MISC_OFFSET_PAD_SETTING_OVERRIDE_ENABLE = 5, - /* Bit for DDR clock confiuration indication. */ + /* Bit for DDR clock configuration indication. */ FLEXSPI_MISC_OFFSET_DDR_MODE_ENABLE = 6, }; @@ -239,7 +239,7 @@ typedef struct flexspi_config { * 8 - Octal */ uint8_t sflash_pad_type; - /* [0x046-0x046] Serial Flash Frequencey, device specific + /* [0x046-0x046] Serial Flash Frequency, device specific * definitions, See System Boot Chapter for more details */ uint8_t serial_clk_freq; @@ -355,7 +355,7 @@ typedef struct _flexspi_nor_config { uint8_t need_exit_nocmd_mode; /* Half the Serial Clock for non-read command: true/false */ uint8_t half_clk_for_non_read_cmd; - /* Need to Restore NoCmd mode after IP commmand execution */ + /* Need to Restore NoCmd mode after IP command execution */ uint8_t need_restore_nocmd_mode; /* Block size */ uint32_t block_size; diff --git a/boards/nxp/mcx_nx4x_evk/xip/mcxn_flexspi_nor_config.h b/boards/nxp/mcx_nx4x_evk/xip/mcxn_flexspi_nor_config.h index 49ed7a5699f6..800a92345c52 100644 --- a/boards/nxp/mcx_nx4x_evk/xip/mcxn_flexspi_nor_config.h +++ b/boards/nxp/mcx_nx4x_evk/xip/mcxn_flexspi_nor_config.h @@ -109,7 +109,7 @@ enum { FLEXSPI_MISC_OFFSET_SAFE_CONFIG_FREQ_ENABLE = 4, /* Bit for Pad setting override enable */ FLEXSPI_MISC_OFFSET_PAD_SETTING_OVERRIDE_ENABLE = 5, - /* Bit for DDR clock confiuration indication. */ + /* Bit for DDR clock configuration indication. */ FLEXSPI_MISC_OFFSET_DDR_MODE_ENABLE = 6, }; @@ -239,7 +239,7 @@ typedef struct flexspi_config { * 8 - Octal */ uint8_t sflash_pad_type; - /* [0x046-0x046] Serial Flash Frequencey, device specific + /* [0x046-0x046] Serial Flash Frequency, device specific * definitions, See System Boot Chapter for more details */ uint8_t serial_clk_freq; @@ -355,7 +355,7 @@ typedef struct _flexspi_nor_config { uint8_t need_exit_nocmd_mode; /* Half the Serial Clock for non-read command: true/false */ uint8_t half_clk_for_non_read_cmd; - /* Need to Restore NoCmd mode after IP commmand execution */ + /* Need to Restore NoCmd mode after IP command execution */ uint8_t need_restore_nocmd_mode; /* Block size */ uint32_t block_size; diff --git a/boards/nxp/mimxrt1010_evk/xip/evkmimxrt1010_flexspi_nor_config.h b/boards/nxp/mimxrt1010_evk/xip/evkmimxrt1010_flexspi_nor_config.h index 8240795e0d29..c757440148d2 100644 --- a/boards/nxp/mimxrt1010_evk/xip/evkmimxrt1010_flexspi_nor_config.h +++ b/boards/nxp/mimxrt1010_evk/xip/evkmimxrt1010_flexspi_nor_config.h @@ -112,7 +112,7 @@ enum { FLEXSPI_MISC_OFFSET_SAFE_CONFIG_FREQ_ENABLE = 4, /* Bit for Pad setting override enable */ FLEXSPI_MISC_OFFSET_PAD_SETTING_OVERRIDE_ENABLE = 5, - /* Bit for DDR clock confiuration indication. */ + /* Bit for DDR clock configuration indication. */ FLEXSPI_MISC_OFFSET_DDR_MODE_ENABLE = 6, }; @@ -238,7 +238,7 @@ typedef struct flexspi_config { * 8 - Octal */ uint8_t sflash_pad_type; - /* [0x046-0x046] Serial Flash Frequencey, device specific + /* [0x046-0x046] Serial Flash Frequency, device specific * definitions, See System Boot Chapter for more details */ uint8_t serial_clk_freq; @@ -352,7 +352,7 @@ typedef struct _flexspi_nor_config { uint8_t need_exit_nocmd_mode; /* Half the Serial Clock for non-read command: true/false */ uint8_t half_clk_for_non_read_cmd; - /* Need to Restore NoCmd mode after IP commmand execution */ + /* Need to Restore NoCmd mode after IP command execution */ uint8_t need_restore_nocmd_mode; /* Block size */ uint32_t block_size; diff --git a/boards/nxp/mimxrt1015_evk/xip/evkmimxrt1015_flexspi_nor_config.h b/boards/nxp/mimxrt1015_evk/xip/evkmimxrt1015_flexspi_nor_config.h index 80c383d33b58..5c305246f943 100644 --- a/boards/nxp/mimxrt1015_evk/xip/evkmimxrt1015_flexspi_nor_config.h +++ b/boards/nxp/mimxrt1015_evk/xip/evkmimxrt1015_flexspi_nor_config.h @@ -111,7 +111,7 @@ enum { FLEXSPI_MISC_OFFSET_SAFE_CONFIG_FREQ_ENABLE = 4, /* Bit for Pad setting override enable */ FLEXSPI_MISC_OFFSET_PAD_SETTING_OVERRIDE_ENABLE = 5, - /* Bit for DDR clock confiuration indication. */ + /* Bit for DDR clock configuration indication. */ FLEXSPI_MISC_OFFSET_DDR_MODE_ENABLE = 6, }; @@ -237,7 +237,7 @@ typedef struct flexspi_config { * 8 - Octal */ uint8_t sflash_pad_type; - /* [0x046-0x046] Serial Flash Frequencey, device specific + /* [0x046-0x046] Serial Flash Frequency, device specific * definitions, See System Boot Chapter for more details */ uint8_t serial_clk_freq; @@ -351,7 +351,7 @@ typedef struct _flexspi_nor_config { uint8_t need_exit_nocmd_mode; /* Half the Serial Clock for non-read command: true/false */ uint8_t half_clk_for_non_read_cmd; - /* Need to Restore NoCmd mode after IP commmand execution */ + /* Need to Restore NoCmd mode after IP command execution */ uint8_t need_restore_nocmd_mode; /* Block size */ uint32_t block_size; diff --git a/boards/nxp/mimxrt1020_evk/xip/evkmimxrt1020_flexspi_nor_config.h b/boards/nxp/mimxrt1020_evk/xip/evkmimxrt1020_flexspi_nor_config.h index 56195bfb7495..54150ab8eafd 100644 --- a/boards/nxp/mimxrt1020_evk/xip/evkmimxrt1020_flexspi_nor_config.h +++ b/boards/nxp/mimxrt1020_evk/xip/evkmimxrt1020_flexspi_nor_config.h @@ -111,7 +111,7 @@ enum { FLEXSPI_MISC_OFFSET_SAFE_CONFIG_FREQ_ENABLE = 4, /* Bit for Pad setting override enable */ FLEXSPI_MISC_OFFSET_PAD_SETTING_OVERRIDE_ENABLE = 5, - /* Bit for DDR clock confiuration indication. */ + /* Bit for DDR clock configuration indication. */ FLEXSPI_MISC_OFFSET_DDR_MODE_ENABLE = 6, }; @@ -241,7 +241,7 @@ typedef struct flexspi_config { * 8 - Octal */ uint8_t sflash_pad_type; - /* [0x046-0x046] Serial Flash Frequencey, device specific + /* [0x046-0x046] Serial Flash Frequency, device specific * definitions, See System Boot Chapter for more details */ uint8_t serial_clk_freq; @@ -355,7 +355,7 @@ typedef struct _flexspi_nor_config { uint8_t need_exit_nocmd_mode; /* Half the Serial Clock for non-read command: true/false */ uint8_t half_clk_for_non_read_cmd; - /* Need to Restore NoCmd mode after IP commmand execution */ + /* Need to Restore NoCmd mode after IP command execution */ uint8_t need_restore_nocmd_mode; /* Block size */ uint32_t block_size; diff --git a/boards/nxp/mimxrt1024_evk/xip/evkmimxrt1024_flexspi_nor_config.h b/boards/nxp/mimxrt1024_evk/xip/evkmimxrt1024_flexspi_nor_config.h index 870c6fc7fdc6..e358bf6d87c2 100644 --- a/boards/nxp/mimxrt1024_evk/xip/evkmimxrt1024_flexspi_nor_config.h +++ b/boards/nxp/mimxrt1024_evk/xip/evkmimxrt1024_flexspi_nor_config.h @@ -111,7 +111,7 @@ enum { FLEXSPI_MISC_OFFSET_SAFE_CONFIG_FREQ_ENABLE = 4, /* Bit for Pad setting override enable */ FLEXSPI_MISC_OFFSET_PAD_SETTING_OVERRIDE_ENABLE = 5, - /* Bit for DDR clock confiuration indication. */ + /* Bit for DDR clock configuration indication. */ FLEXSPI_MISC_OFFSET_DDR_MODE_ENABLE = 6, }; @@ -237,7 +237,7 @@ typedef struct flexspi_config { * 8 - Octal */ uint8_t sflash_pad_type; - /* [0x046-0x046] Serial Flash Frequencey, device specific + /* [0x046-0x046] Serial Flash Frequency, device specific * definitions, See System Boot Chapter for more details */ uint8_t serial_clk_freq; @@ -351,7 +351,7 @@ typedef struct _flexspi_nor_config { uint8_t need_exit_nocmd_mode; /* Half the Serial Clock for non-read command: true/false */ uint8_t half_clk_for_non_read_cmd; - /* Need to Restore NoCmd mode after IP commmand execution */ + /* Need to Restore NoCmd mode after IP command execution */ uint8_t need_restore_nocmd_mode; /* Block size */ uint32_t block_size; diff --git a/boards/nxp/mimxrt1040_evk/xip/evkmimxrt1040_flexspi_nor_config.h b/boards/nxp/mimxrt1040_evk/xip/evkmimxrt1040_flexspi_nor_config.h index 7dd4084f24a8..b9105c13ef74 100644 --- a/boards/nxp/mimxrt1040_evk/xip/evkmimxrt1040_flexspi_nor_config.h +++ b/boards/nxp/mimxrt1040_evk/xip/evkmimxrt1040_flexspi_nor_config.h @@ -113,7 +113,7 @@ enum { FLEXSPI_MISC_OFFSET_SAFE_CONFIG_FREQ_ENABLE = 4, /* Bit for Pad setting override enable */ FLEXSPI_MISC_OFFSET_PAD_SETTING_OVERRIDE_ENABLE = 5, - /* Bit for DDR clock confiuration indication. */ + /* Bit for DDR clock configuration indication. */ FLEXSPI_MISC_OFFSET_DDR_MODE_ENABLE = 6, }; @@ -239,7 +239,7 @@ typedef struct flexspi_config { * 8 - Octal */ uint8_t sflash_pad_type; - /* [0x046-0x046] Serial Flash Frequencey, device specific + /* [0x046-0x046] Serial Flash Frequency, device specific * definitions, See System Boot Chapter for more details */ uint8_t serial_clk_freq; @@ -353,7 +353,7 @@ typedef struct _flexspi_nor_config { uint8_t need_exit_nocmd_mode; /* Half the Serial Clock for non-read command: true/false */ uint8_t half_clk_for_non_read_cmd; - /* Need to Restore NoCmd mode after IP commmand execution */ + /* Need to Restore NoCmd mode after IP command execution */ uint8_t need_restore_nocmd_mode; /* Block size */ uint32_t block_size; diff --git a/boards/nxp/mimxrt1050_evk/xip/evkbimxrt1050_flexspi_nor_config.h b/boards/nxp/mimxrt1050_evk/xip/evkbimxrt1050_flexspi_nor_config.h index 013e4f0852a5..6ee8b2085ccc 100644 --- a/boards/nxp/mimxrt1050_evk/xip/evkbimxrt1050_flexspi_nor_config.h +++ b/boards/nxp/mimxrt1050_evk/xip/evkbimxrt1050_flexspi_nor_config.h @@ -112,7 +112,7 @@ enum { FLEXSPI_MISC_OFFSET_SAFE_CONFIG_FREQ_ENABLE = 4, /* Bit for Pad setting override enable */ FLEXSPI_MISC_OFFSET_PAD_SETTING_OVERRIDE_ENABLE = 5, - /* Bit for DDR clock confiuration indication. */ + /* Bit for DDR clock configuration indication. */ FLEXSPI_MISC_OFFSET_DDR_MODE_ENABLE = 6, }; @@ -238,7 +238,7 @@ typedef struct flexspi_config { * 8 - Octal */ uint8_t sflash_pad_type; - /* [0x046-0x046] Serial Flash Frequencey, device specific + /* [0x046-0x046] Serial Flash Frequency, device specific * definitions, See System Boot Chapter for more details */ uint8_t serial_clk_freq; @@ -352,7 +352,7 @@ typedef struct _flexspi_nor_config { uint8_t need_exit_nocmd_mode; /* Half the Serial Clock for non-read command: true/false */ uint8_t half_clk_for_non_read_cmd; - /* Need to Restore NoCmd mode after IP commmand execution */ + /* Need to Restore NoCmd mode after IP command execution */ uint8_t need_restore_nocmd_mode; /* Block size */ uint32_t block_size; diff --git a/boards/nxp/mimxrt1060_evk/xip/evkbmimxrt1060_flexspi_nor_config.h b/boards/nxp/mimxrt1060_evk/xip/evkbmimxrt1060_flexspi_nor_config.h index fb5149c7d929..0b31a4510145 100644 --- a/boards/nxp/mimxrt1060_evk/xip/evkbmimxrt1060_flexspi_nor_config.h +++ b/boards/nxp/mimxrt1060_evk/xip/evkbmimxrt1060_flexspi_nor_config.h @@ -113,7 +113,7 @@ enum { FLEXSPI_MISC_OFFSET_SAFE_CONFIG_FREQ_ENABLE = 4, /* Bit for Pad setting override enable */ FLEXSPI_MISC_OFFSET_PAD_SETTING_OVERRIDE_ENABLE = 5, - /* Bit for DDR clock confiuration indication. */ + /* Bit for DDR clock configuration indication. */ FLEXSPI_MISC_OFFSET_DDR_MODE_ENABLE = 6, }; @@ -239,7 +239,7 @@ typedef struct flexspi_config { * 8 - Octal */ uint8_t sflash_pad_type; - /* [0x046-0x046] Serial Flash Frequencey, device specific + /* [0x046-0x046] Serial Flash Frequency, device specific * definitions, See System Boot Chapter for more details */ uint8_t serial_clk_freq; @@ -353,7 +353,7 @@ typedef struct _flexspi_nor_config { uint8_t need_exit_nocmd_mode; /* Half the Serial Clock for non-read command: true/false */ uint8_t half_clk_for_non_read_cmd; - /* Need to Restore NoCmd mode after IP commmand execution */ + /* Need to Restore NoCmd mode after IP command execution */ uint8_t need_restore_nocmd_mode; /* Block size */ uint32_t block_size; diff --git a/boards/nxp/mimxrt1060_evk/xip/evkmimxrt1060_flexspi_nor_config.h b/boards/nxp/mimxrt1060_evk/xip/evkmimxrt1060_flexspi_nor_config.h index 34f571df7f14..688eef989981 100644 --- a/boards/nxp/mimxrt1060_evk/xip/evkmimxrt1060_flexspi_nor_config.h +++ b/boards/nxp/mimxrt1060_evk/xip/evkmimxrt1060_flexspi_nor_config.h @@ -113,7 +113,7 @@ enum { FLEXSPI_MISC_OFFSET_SAFE_CONFIG_FREQ_ENABLE = 4, /* Bit for Pad setting override enable */ FLEXSPI_MISC_OFFSET_PAD_SETTING_OVERRIDE_ENABLE = 5, - /* Bit for DDR clock confiuration indication. */ + /* Bit for DDR clock configuration indication. */ FLEXSPI_MISC_OFFSET_DDR_MODE_ENABLE = 6, }; @@ -239,7 +239,7 @@ typedef struct flexspi_config { * 8 - Octal */ uint8_t sflash_pad_type; - /* [0x046-0x046] Serial Flash Frequencey, device specific + /* [0x046-0x046] Serial Flash Frequency, device specific * definitions, See System Boot Chapter for more details */ uint8_t serial_clk_freq; @@ -353,7 +353,7 @@ typedef struct _flexspi_nor_config { uint8_t need_exit_nocmd_mode; /* Half the Serial Clock for non-read command: true/false */ uint8_t half_clk_for_non_read_cmd; - /* Need to Restore NoCmd mode after IP commmand execution */ + /* Need to Restore NoCmd mode after IP command execution */ uint8_t need_restore_nocmd_mode; /* Block size */ uint32_t block_size; diff --git a/boards/nxp/mimxrt1064_evk/xip/evkmimxrt1064_flexspi_nor_config.h b/boards/nxp/mimxrt1064_evk/xip/evkmimxrt1064_flexspi_nor_config.h index f4332cefb454..87cb391d86fb 100644 --- a/boards/nxp/mimxrt1064_evk/xip/evkmimxrt1064_flexspi_nor_config.h +++ b/boards/nxp/mimxrt1064_evk/xip/evkmimxrt1064_flexspi_nor_config.h @@ -113,7 +113,7 @@ enum { FLEXSPI_MISC_OFFSET_SAFE_CONFIG_FREQ_ENABLE = 4, /* Bit for Pad setting override enable */ FLEXSPI_MISC_OFFSET_PAD_SETTING_OVERRIDE_ENABLE = 5, - /* Bit for DDR clock confiuration indication. */ + /* Bit for DDR clock configuration indication. */ FLEXSPI_MISC_OFFSET_DDR_MODE_ENABLE = 6, }; @@ -237,7 +237,7 @@ typedef struct flexspi_config { * 8 - Octal */ uint8_t sflash_pad_type; - /* [0x046-0x046] Serial Flash Frequencey, device specific + /* [0x046-0x046] Serial Flash Frequency, device specific * definitions, See System Boot Chapter for more details */ uint8_t serial_clk_freq; @@ -351,7 +351,7 @@ typedef struct _flexspi_nor_config { uint8_t need_exit_nocmd_mode; /* Half the Serial Clock for non-read command: true/false */ uint8_t half_clk_for_non_read_cmd; - /* Need to Restore NoCmd mode after IP commmand execution */ + /* Need to Restore NoCmd mode after IP command execution */ uint8_t need_restore_nocmd_mode; /* Block size */ uint32_t block_size; diff --git a/boards/nxp/mimxrt1160_evk/xip/evkmimxrt1160_flexspi_nor_config.h b/boards/nxp/mimxrt1160_evk/xip/evkmimxrt1160_flexspi_nor_config.h index e9d12927697f..f1acb4d41b50 100644 --- a/boards/nxp/mimxrt1160_evk/xip/evkmimxrt1160_flexspi_nor_config.h +++ b/boards/nxp/mimxrt1160_evk/xip/evkmimxrt1160_flexspi_nor_config.h @@ -112,7 +112,7 @@ enum { FLEXSPI_MISC_OFFSET_SAFE_CONFIG_FREQ_ENABLE = 4, /* Bit for Pad setting override enable */ FLEXSPI_MISC_OFFSET_PAD_SETTING_OVERRIDE_ENABLE = 5, - /* Bit for DDR clock confiuration indication. */ + /* Bit for DDR clock configuration indication. */ FLEXSPI_MISC_OFFSET_DDR_MODE_ENABLE = 6, }; @@ -242,7 +242,7 @@ typedef struct flexspi_config { * 8 - Octal */ uint8_t sflash_pad_type; - /* [0x046-0x046] Serial Flash Frequencey, device specific + /* [0x046-0x046] Serial Flash Frequency, device specific * definitions, See System Boot Chapter for more details */ uint8_t serial_clk_freq; @@ -358,7 +358,7 @@ typedef struct _flexspi_nor_config { uint8_t need_exit_nocmd_mode; /* Half the Serial Clock for non-read command: true/false */ uint8_t half_clk_for_non_read_cmd; - /* Need to Restore NoCmd mode after IP commmand execution */ + /* Need to Restore NoCmd mode after IP command execution */ uint8_t need_restore_nocmd_mode; /* Block size */ uint32_t block_size; diff --git a/boards/nxp/mimxrt1170_evk/xip/evkbmimxrt1170_flexspi_nor_config.h b/boards/nxp/mimxrt1170_evk/xip/evkbmimxrt1170_flexspi_nor_config.h index bc9c9e523ffe..7199ab1e63d9 100644 --- a/boards/nxp/mimxrt1170_evk/xip/evkbmimxrt1170_flexspi_nor_config.h +++ b/boards/nxp/mimxrt1170_evk/xip/evkbmimxrt1170_flexspi_nor_config.h @@ -112,7 +112,7 @@ enum { FLEXSPI_MISC_OFFSET_SAFE_CONFIG_FREQ_ENABLE = 4, /* Bit for Pad setting override enable */ FLEXSPI_MISC_OFFSET_PAD_SETTING_OVERRIDE_ENABLE = 5, - /* Bit for DDR clock confiuration indication. */ + /* Bit for DDR clock configuration indication. */ FLEXSPI_MISC_OFFSET_DDR_MODE_ENABLE = 6, }; @@ -242,7 +242,7 @@ typedef struct flexspi_config { * 8 - Octal */ uint8_t sflash_pad_type; - /* [0x046-0x046] Serial Flash Frequencey, device specific + /* [0x046-0x046] Serial Flash Frequency, device specific * definitions, See System Boot Chapter for more details */ uint8_t serial_clk_freq; @@ -358,7 +358,7 @@ typedef struct _flexspi_nor_config { uint8_t need_exit_nocmd_mode; /* Half the Serial Clock for non-read command: true/false */ uint8_t half_clk_for_non_read_cmd; - /* Need to Restore NoCmd mode after IP commmand execution */ + /* Need to Restore NoCmd mode after IP command execution */ uint8_t need_restore_nocmd_mode; /* Block size */ uint32_t block_size; diff --git a/boards/nxp/mimxrt1170_evk/xip/evkmimxrt1170_flexspi_nor_config.h b/boards/nxp/mimxrt1170_evk/xip/evkmimxrt1170_flexspi_nor_config.h index 1b986f32dd81..b7f05c5d966d 100644 --- a/boards/nxp/mimxrt1170_evk/xip/evkmimxrt1170_flexspi_nor_config.h +++ b/boards/nxp/mimxrt1170_evk/xip/evkmimxrt1170_flexspi_nor_config.h @@ -113,7 +113,7 @@ enum { FLEXSPI_MISC_OFFSET_SAFE_CONFIG_FREQ_ENABLE = 4, /* Bit for Pad setting override enable */ FLEXSPI_MISC_OFFSET_PAD_SETTING_OVERRIDE_ENABLE = 5, - /* Bit for DDR clock confiuration indication. */ + /* Bit for DDR clock configuration indication. */ FLEXSPI_MISC_OFFSET_DDR_MODE_ENABLE = 6, }; @@ -239,7 +239,7 @@ typedef struct flexspi_config { * 8 - Octal */ uint8_t sflash_pad_type; - /* [0x046-0x046] Serial Flash Frequencey, device specific + /* [0x046-0x046] Serial Flash Frequency, device specific * definitions, See System Boot Chapter for more details */ uint8_t serial_clk_freq; @@ -355,7 +355,7 @@ typedef struct _flexspi_nor_config { uint8_t need_exit_nocmd_mode; /* Half the Serial Clock for non-read command: true/false */ uint8_t half_clk_for_non_read_cmd; - /* Need to Restore NoCmd mode after IP commmand execution */ + /* Need to Restore NoCmd mode after IP command execution */ uint8_t need_restore_nocmd_mode; /* Block size */ uint32_t block_size; diff --git a/boards/nxp/mimxrt1180_evk/xip/evkmimxrt1180_flexspi_nor_config.h b/boards/nxp/mimxrt1180_evk/xip/evkmimxrt1180_flexspi_nor_config.h index 07e52dbceb09..c9b8a03e165e 100644 --- a/boards/nxp/mimxrt1180_evk/xip/evkmimxrt1180_flexspi_nor_config.h +++ b/boards/nxp/mimxrt1180_evk/xip/evkmimxrt1180_flexspi_nor_config.h @@ -190,7 +190,7 @@ typedef struct flexspi_config { * 8 - Octal */ uint8_t sflash_pad_type; - /* [0x046-0x046] Serial Flash Frequencey, device specific + /* [0x046-0x046] Serial Flash Frequency, device specific * definitions, See System Boot Chapter for more details */ uint8_t serial_clk_freq; diff --git a/boards/nxp/mimxrt595_evk/flash_config/flash_config.h b/boards/nxp/mimxrt595_evk/flash_config/flash_config.h index 7b6ae4ac83b0..6332e9d62d8a 100644 --- a/boards/nxp/mimxrt595_evk/flash_config/flash_config.h +++ b/boards/nxp/mimxrt595_evk/flash_config/flash_config.h @@ -88,7 +88,7 @@ enum { FLEXSPI_MISC_OFFSET_SAFE_CONFIG_FREQ_ENABLE = 4, /* Bit for Pad setting override enable */ FLEXSPI_MISC_OFFSET_PAD_SETTING_OVERRIDE_ENABLE = 5, - /* Bit for DDR clock confiuration indication. */ + /* Bit for DDR clock configuration indication. */ FLEXSPI_MISC_OFFSET_DDR_MODE_ENABLE = 6, /* Bit for DLLCR settings under all modes */ FLEXSPI_MISC_OFFSET_USE_VALID_TIME_FOR_ALL_FREQ = 7, diff --git a/boards/nxp/mimxrt685_evk/flash_config/flash_config.h b/boards/nxp/mimxrt685_evk/flash_config/flash_config.h index dede879429f1..0dc8055c7bc0 100644 --- a/boards/nxp/mimxrt685_evk/flash_config/flash_config.h +++ b/boards/nxp/mimxrt685_evk/flash_config/flash_config.h @@ -95,7 +95,7 @@ enum { FLEXSPI_MISC_OFFSET_WORD_ADDRESSABLE_ENABLE = 3, /* Bit for Safe Configuration Frequency enable */ FLEXSPI_MISC_OFFSET_SAFE_CONFIG_FREQ_ENABLE = 4, - /* Bit for DDR clock confiuration indication. */ + /* Bit for DDR clock configuration indication. */ FLEXSPI_MISC_OFFSET_DDR_MODE_ENABLE = 6, }; @@ -201,7 +201,7 @@ typedef struct flexspi_config { * 1 - Single, 2 - Dual, 4 - Quad, 8 - Octal */ uint8_t sflash_pad_type; - /* !< [0x046-0x046] Serial Flash Frequencey, + /* !< [0x046-0x046] Serial Flash Frequency, * device specific definitions, * See System Boot Chapter for more details */ @@ -275,7 +275,7 @@ typedef struct _flexspi_nor_config { uint8_t need_exit_nocmd_mode; /* !< Half the Serial Clock for non-read command: true/false */ uint8_t half_clk_for_non_read_cmd; - /* !< Need to Restore NoCmd mode after IP commmand execution */ + /* !< Need to Restore NoCmd mode after IP command execution */ uint8_t need_restore_nocmd_mode; /* !< Block size */ uint32_t block_size; diff --git a/boards/nxp/mimxrt700_evk/flash_config/flash_config.h b/boards/nxp/mimxrt700_evk/flash_config/flash_config.h index 0b0dcbd62636..5347fcb4e873 100644 --- a/boards/nxp/mimxrt700_evk/flash_config/flash_config.h +++ b/boards/nxp/mimxrt700_evk/flash_config/flash_config.h @@ -96,7 +96,7 @@ enum { FC_XSPI_MISC_OFFSET_WORD_ADDRESSABLE_ENABLE = 3, /* !< Bit for Safe Configuration Frequency enable */ FC_XSPI_MISC_OFFSET_SAFE_CONFIG_FREQ_ENABLE = 4, - /* !< Bit for DDR clock confiuration indication. */ + /* !< Bit for DDR clock configuration indication. */ FC_XSPI_MISC_OFFSET_DDR_MODE_ENABLE = 6, }; @@ -194,7 +194,7 @@ typedef struct xspi_config { *1 - Single, 2 - Dual, 4 - Quad, 8 - Octal */ uint8_t sflash_pad_type; - /* !< [0x046-0x046] Serial Flash Frequencey + /* !< [0x046-0x046] Serial Flash Frequency * 1: 30 mhz * 2: 50 mhz * 3: 60 mhz @@ -295,7 +295,7 @@ typedef struct _fc_xspi_nor_config { uint8_t need_exit_nocmd_mode; /* !< Half the Serial Clock for non-read command: true/false */ uint8_t half_clk_for_non_read_cmd; - /* !< Need to Restore NoCmd mode after IP commmand execution */ + /* !< Need to Restore NoCmd mode after IP command execution */ uint8_t need_restore_nocmd_mode; /* !< Block size */ uint32_t block_size; diff --git a/boards/nxp/vmu_rt1170/xip/evkmimxrt1170_flexspi_nor_config.h b/boards/nxp/vmu_rt1170/xip/evkmimxrt1170_flexspi_nor_config.h index 4e8fba474961..95cb2e88240b 100644 --- a/boards/nxp/vmu_rt1170/xip/evkmimxrt1170_flexspi_nor_config.h +++ b/boards/nxp/vmu_rt1170/xip/evkmimxrt1170_flexspi_nor_config.h @@ -113,7 +113,7 @@ enum { FLEXSPI_MISC_OFFSET_SAFE_CONFIG_FREQ_ENABLE = 4, /* Bit for Pad setting override enable */ FLEXSPI_MISC_OFFSET_PAD_SETTING_OVERRIDE_ENABLE = 5, - /* Bit for DDR clock confiuration indication. */ + /* Bit for DDR clock configuration indication. */ FLEXSPI_MISC_OFFSET_DDR_MODE_ENABLE = 6, }; @@ -239,7 +239,7 @@ typedef struct flexspi_config { * 8 - Octal */ uint8_t sflash_pad_type; - /* [0x046-0x046] Serial Flash Frequencey, device specific + /* [0x046-0x046] Serial Flash Frequency, device specific * definitions, See System Boot Chapter for more details */ uint8_t serial_clk_freq; @@ -355,7 +355,7 @@ typedef struct _flexspi_nor_config { uint8_t need_exit_nocmd_mode; /* Half the Serial Clock for non-read command: true/false */ uint8_t half_clk_for_non_read_cmd; - /* Need to Restore NoCmd mode after IP commmand execution */ + /* Need to Restore NoCmd mode after IP command execution */ uint8_t need_restore_nocmd_mode; /* Block size */ uint32_t block_size; From 8f2b245fe6f2ca7606a6436e83730562056e1f5b Mon Sep 17 00:00:00 2001 From: Razvan Heghedus Date: Fri, 16 Jan 2026 16:53:37 +0200 Subject: [PATCH 2208/3659] dma: mcux_edma: Fix channel gap for edma_reload_loop `edma_reload_loop` doesn't take into account the DMA possible channel gap. This is an issue for S32K3 series leading to system crashes when higher DMA channels are used. Signed-off-by: Razvan Heghedus --- drivers/dma/dma_mcux_edma.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/dma/dma_mcux_edma.c b/drivers/dma/dma_mcux_edma.c index 60963afc2956..fa506c130cee 100644 --- a/drivers/dma/dma_mcux_edma.c +++ b/drivers/dma/dma_mcux_edma.c @@ -785,9 +785,12 @@ static int edma_reload_loop(const struct device *dev, uint32_t channel, struct call_back *data = DEV_CHANNEL_DATA(dev, channel); edma_tcd_t *tcd = NULL; edma_tcd_t *pre_tcd = NULL; + uint32_t hw_channel; uint32_t hw_id, sw_id; uint8_t pre_idx; + hw_channel = dma_mcux_edma_add_channel_gap(dev, channel); + if (data->transfer_settings.empty_tcds == 0) { LOG_ERR("TCD list is full in loop mode."); return -ENOBUFS; @@ -819,13 +822,13 @@ static int edma_reload_loop(const struct device *dev, uint32_t channel, * code between EDMA_DisableChannelRequest() and * EDMA_EnableChannelRequest() is minimum. */ - EDMA_DisableChannelRequest(DEV_BASE(dev), channel); + EDMA_DisableChannelRequest(DEV_BASE(dev), hw_channel); /* Wait for the DMA to be inactive before updating the TCDs. * The CSR[ACTIVE] bit will deassert quickly after the EDMA's * minor loop burst completes. */ - while (EDMA_HW_TCD_CSR(dev, channel) & EDMA_HW_TCD_CH_ACTIVE_MASK) { + while (EDMA_HW_TCD_CSR(dev, hw_channel) & EDMA_HW_TCD_CH_ACTIVE_MASK) { ; } @@ -836,7 +839,7 @@ static int edma_reload_loop(const struct device *dev, uint32_t channel, /* All transfers have been done.DMA is stopped automatically, * invalid TCD has been loaded into the HW, update HW. */ - dma_mcux_edma_update_hw_tcd(dev, channel, src, dst, size); + dma_mcux_edma_update_hw_tcd(dev, hw_channel, src, dst, size); LOG_DBG("Transfer done,auto stop"); } else { @@ -851,7 +854,7 @@ static int edma_reload_loop(const struct device *dev, uint32_t channel, /* DMA is running on last transfer. HW has loaded the last one, * we need ensure it's DREQ is cleared. */ - EDMA_EnableAutoStopRequest(DEV_BASE(dev), channel, false); + EDMA_EnableAutoStopRequest(DEV_BASE(dev), hw_channel, false); LOG_DBG("Last transfer."); } LOG_DBG("Manu stop"); @@ -867,7 +870,7 @@ static int edma_reload_loop(const struct device *dev, uint32_t channel, /*We have not verified if this issue exist on V3/V4 HW, jut place a holder here. */ #endif /* TCDs are configured. Resume DMA */ - EDMA_EnableChannelRequest(DEV_BASE(dev), channel); + EDMA_EnableChannelRequest(DEV_BASE(dev), hw_channel); /* Update the write index and available TCD numbers. */ data->transfer_settings.write_idx = From 4138155273bcc600af1d59c38591395f30aa0306 Mon Sep 17 00:00:00 2001 From: Holt Sun Date: Fri, 16 Jan 2026 22:33:38 +0800 Subject: [PATCH 2209/3659] drivers: uart_mcux_lpuart: refine DMA TX busy/error handling Split DMA status error from busy state handling. Use LOG_DBG for busy state and LOG_ERR for status query failures. Return -EBUSY as required by async UART API when transfer is in progress. Signed-off-by: Holt Sun --- drivers/serial/uart_mcux_lpuart.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/serial/uart_mcux_lpuart.c b/drivers/serial/uart_mcux_lpuart.c index ecb18f4e031c..d3be5c3e2c77 100644 --- a/drivers/serial/uart_mcux_lpuart.c +++ b/drivers/serial/uart_mcux_lpuart.c @@ -741,16 +741,22 @@ static int mcux_lpuart_tx(const struct device *dev, const uint8_t *buf, size_t l unsigned int key = irq_lock(); - /* Check for an ongiong transfer and abort if it is pending */ + /* If a previous transfer is still in progress, the async UART API requires -EBUSY. */ struct dma_status status; const int get_status_result = dma_get_status(config->tx_dma_config.dma_dev, config->tx_dma_config.dma_channel, &status); - if (get_status_result < 0 || status.busy) { + if (get_status_result < 0) { irq_unlock(key); - LOG_ERR("Unable to submit UART DMA Transfer."); - return get_status_result < 0 ? get_status_result : -EBUSY; + LOG_ERR("Failed to get DMA(Tx) status (%d)", get_status_result); + return get_status_result; + } + + if (status.busy) { + irq_unlock(key); + LOG_DBG("UART TX busy (DMA ch %u)", config->tx_dma_config.dma_channel); + return -EBUSY; } int ret; From 3881d4bad7a663d6b401ee3eb61f7f1027aa12e9 Mon Sep 17 00:00:00 2001 From: Grzegorz Chwierut Date: Fri, 16 Jan 2026 14:18:47 +0100 Subject: [PATCH 2210/3659] scripts: west: Fix sysbuild overwrite by test item parameter When sysbuild is enabled globally and running west build with a selected test scenario, the sysbuild setting was being overwritten with False when sysbuild was not explicitly set in the test YAML file. Signed-off-by: Grzegorz Chwierut --- scripts/west_commands/build.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/scripts/west_commands/build.py b/scripts/west_commands/build.py index 4672ec46667e..f7aab1adb147 100644 --- a/scripts/west_commands/build.py +++ b/scripts/west_commands/build.py @@ -354,7 +354,7 @@ def _parse_test_item(self, test_item, board): self.die(f"Test item {test_item} not found in {yf}") item = tests.get(test_item) - sysbuild = False + sysbuild = None extra_dtc_overlay_files = [] extra_overlay_confs = [] extra_conf_files = [] @@ -417,7 +417,8 @@ def _parse_test_item(self, test_item, board): self.args.cmake_opts.extend(args) - self.args.sysbuild = sysbuild + if sysbuild is not None: + self.args.sysbuild = sysbuild if found_test_metadata: args = [] From 258eef1017c41873c456cfb9ab555e18beedbee8 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Fri, 16 Jan 2026 12:31:21 +0100 Subject: [PATCH 2211/3659] tests: Bluetooth: Bump qualification materials to Core Spec 6.2 This enables Bluetooth Core 6.2. No functional changes. Signed-off-by: Szymon Janc --- .../ICS_Zephyr_Bluetooth_Host.bqw | 3140 ++++++++--------- .../ICS_Zephyr_Bluetooth_Host.pts | 26 +- 2 files changed, 1583 insertions(+), 1583 deletions(-) diff --git a/tests/bluetooth/qualification/ICS_Zephyr_Bluetooth_Host.bqw b/tests/bluetooth/qualification/ICS_Zephyr_Bluetooth_Host.bqw index 4a85480206c8..ba713782dcec 100644 --- a/tests/bluetooth/qualification/ICS_Zephyr_Bluetooth_Host.bqw +++ b/tests/bluetooth/qualification/ICS_Zephyr_Bluetooth_Host.bqw @@ -7,6 +7,12 @@ + GAP 17b/2 + GAP 30a/5 + GAP 17/5 + GAP 30a/10 + GAP 36/6 + GAP 8a/18 GAP 27c/1 GAP 35/11 GAP 25/13b @@ -19,49 +25,6 @@ GAP 8/5 GAP 35/13 GAP 30a/1 - GAP 17b/2 - GAP 30a/5 - GAP 17/5 - GAP 30a/10 - GAP 36/6 - GAP 8a/18 - GAP 11b/3 - GAP 37c/2 - GAP 37/7 - GAP 37a/5 - GAP 20A/14a - GAP 37b/2 - GAP 30a/12 - GAP 17a/5 - GAP 0b/2 - GAP 14a/4 - GAP 14a/14 - GAP 26/5 - GAP 30a/7 - GAP 37b/7 - GAP 17/3 - GAP 19/2 - GAP 19/3 - GAP 20A/10 - GAP 20A/12 - GAP 20A/17 - GAP 21/3 - GAP 25/7 - GAP 29/1 - GAP 29/2 - GAP 35/1 - GAP 35/4 - GAP 35/9 - GAP 36/3 - GAP 37a/1 - GAP 5/1 - GAP 8/1 - GAP 8/4 - GAP 8a/6 - GAP 8a/7 - GAP 10/4 - GAP 16/2 - GAP 16/4 GAP 8a/14a GAP 14a/16 GAP 27b/2 @@ -101,6 +64,100 @@ GAP 10/5 GAP 11b/1 GAP 16/3 + GAP 27b/1 + GAP 30a/4 + GAP 37a/4 + GAP 30a/13 + GAP 11/5 + GAP 26/6 + GAP 30a/2 + GAP 11a/1 + GAP 12/1 + GAP 13/1 + GAP 17/2 + GAP 20/7 + GAP 20A/11 + GAP 20A/13 + GAP 20A/16 + GAP 20A/2 + GAP 20A/9 + GAP 21/7 + GAP 23/1 + GAP 23/5 + GAP 27/1 + GAP 27/9 + GAP 28/1 + GAP 30/2 + GAP 31/1 + GAP 31/6 + GAP 31/9 + GAP 8a/10 + GAP 8a/13 + GAP 8a/17 + GAP 8a/3 + GAP 8a/8 + GAP 33/7 + GAP 11c/1 + GAP 27b/7 + GAP 27b/12 + GAP 20/8 + GAP 37b/1 + GAP 27a/6 + GAP 14a/1 + GAP 14a/13 + GAP 8a/19 + GAP 20A/1 + GAP 20A/14 + GAP 21/10 + GAP 21/2 + GAP 22/1 + GAP 22/3 + GAP 24/4 + GAP 27/2 + GAP 31/10 + GAP 32/1 + GAP 32/2 + GAP 37/1 + GAP 5/4 + GAP 8a/1 + GAP 8a/4 + GAP 11b/3 + GAP 37c/2 + GAP 37/7 + GAP 37a/5 + GAP 20A/14a + GAP 37b/2 + GAP 30a/12 + GAP 17a/5 + GAP 0b/2 + GAP 14a/4 + GAP 14a/14 + GAP 26/5 + GAP 30a/7 + GAP 37b/7 + GAP 17/3 + GAP 19/2 + GAP 19/3 + GAP 20A/10 + GAP 20A/12 + GAP 20A/17 + GAP 21/3 + GAP 25/7 + GAP 29/1 + GAP 29/2 + GAP 35/1 + GAP 35/4 + GAP 35/9 + GAP 36/3 + GAP 37a/1 + GAP 5/1 + GAP 8/1 + GAP 8/4 + GAP 8a/6 + GAP 8a/7 + GAP 10/4 + GAP 16/2 + GAP 16/4 GAP 35/12 GAP 11/2 GAP 12/2 @@ -131,106 +188,6 @@ GAP 8a/9 GAP 10/2 GAP 33/8 - GAP 11c/1 - GAP 27b/7 - GAP 27b/12 - GAP 20/8 - GAP 37b/1 - GAP 27a/6 - GAP 14a/1 - GAP 14a/13 - GAP 8a/19 - GAP 20A/1 - GAP 20A/14 - GAP 21/10 - GAP 21/2 - GAP 22/1 - GAP 22/3 - GAP 24/4 - GAP 27/2 - GAP 31/10 - GAP 32/1 - GAP 32/2 - GAP 37/1 - GAP 5/4 - GAP 8a/1 - GAP 8a/4 - GAP 37c/3 - GAP 37/6 - GAP 35/15 - GAP 14a/17 - GAP 11/4 - GAP 37b/9 - GAP 37c/1 - GAP 37b/11 - GAP 17b/4 - GAP 11b/4 - GAP 37b/3 - GAP 30a/15 - GAP 11b/2 - GAP 14a/15 - GAP 20A/19 - GAP 30a/16 - GAP 27b/11 - GAP 14a/10 - GAP 27b/3 - GAP 27b/6 - GAP 25/11 - GAP 11/1 - GAP 20/2 - GAP 20A/4 - GAP 21/6 - GAP 21/8 - GAP 23/4 - GAP 25/3 - GAP 25/8 - GAP 31/11 - GAP 31/2 - GAP 31/5 - GAP 33/6 - GAP 35/7 - GAP 37/2 - GAP 37a/3 - GAP 7/2 - GAP 8/2 - GAP 25/12 - GAP 30a/19 - GAP 30a/18 - GAP 30a/14 - GAP 37a/6 - GAP 14a/11 - GAP 25/13a - GAP 14a/9 - GAP 30a/9 - GAP 33/8a - GAP 14a/14a - GAP 11/3 - GAP 13/2 - GAP 15/1 - GAP 17/1 - GAP 17a/2 - GAP 18/1 - GAP 18/2 - GAP 20/4 - GAP 20/6 - GAP 20A/5 - GAP 20A/8 - GAP 21/5 - GAP 23/2 - GAP 25/1 - GAP 27/7 - GAP 28/2 - GAP 33/4 - GAP 34/1 - GAP 35/10 - GAP 36/1 - GAP 37/3 - GAP 6/2 - GAP 7/1 - GAP 8a/12 - GAP 8a/14 - GAP 17b/1 - GAP 23/6 GAP 35/14 GAP 17a/4 GAP 14a/7 @@ -270,50 +227,92 @@ GAP 10/3 GAP 23/7 GAP 7/3 - GAP 27b/1 - GAP 30a/4 - GAP 37a/4 - GAP 30a/13 - GAP 11/5 - GAP 26/6 - GAP 30a/2 - GAP 11a/1 - GAP 12/1 - GAP 13/1 - GAP 17/2 - GAP 20/7 - GAP 20A/11 - GAP 20A/13 - GAP 20A/16 - GAP 20A/2 - GAP 20A/9 - GAP 21/7 - GAP 23/1 - GAP 23/5 - GAP 27/1 - GAP 27/9 - GAP 28/1 - GAP 30/2 - GAP 31/1 - GAP 31/6 - GAP 31/9 - GAP 8a/10 - GAP 8a/13 - GAP 8a/17 - GAP 8a/3 - GAP 8a/8 - GAP 33/7 + GAP 25/12 + GAP 30a/19 + GAP 30a/18 + GAP 30a/14 + GAP 37a/6 + GAP 14a/11 + GAP 25/13a + GAP 14a/9 + GAP 30a/9 + GAP 33/8a + GAP 14a/14a + GAP 11/3 + GAP 13/2 + GAP 15/1 + GAP 17/1 + GAP 17a/2 + GAP 18/1 + GAP 18/2 + GAP 20/4 + GAP 20/6 + GAP 20A/5 + GAP 20A/8 + GAP 21/5 + GAP 23/2 + GAP 25/1 + GAP 27/7 + GAP 28/2 + GAP 33/4 + GAP 34/1 + GAP 35/10 + GAP 36/1 + GAP 37/3 + GAP 6/2 + GAP 7/1 + GAP 8a/12 + GAP 8a/14 + GAP 17b/1 + GAP 23/6 + GAP 37c/3 + GAP 37/6 + GAP 35/15 + GAP 14a/17 + GAP 11/4 + GAP 37b/9 + GAP 37c/1 + GAP 37b/11 + GAP 17b/4 + GAP 11b/4 + GAP 37b/3 + GAP 30a/15 + GAP 11b/2 + GAP 14a/15 + GAP 20A/19 + GAP 30a/16 + GAP 27b/11 + GAP 14a/10 + GAP 27b/3 + GAP 27b/6 + GAP 25/11 + GAP 11/1 + GAP 20/2 + GAP 20A/4 + GAP 21/6 + GAP 21/8 + GAP 23/4 + GAP 25/3 + GAP 25/8 + GAP 31/11 + GAP 31/2 + GAP 31/5 + GAP 33/6 + GAP 35/7 + GAP 37/2 + GAP 37a/3 + GAP 7/2 + GAP 8/2 - L2CAP 2/45a - L2CAP 1/6 - L2CAP 2/40 - L2CAP 2/42 - L2CAP 2/47 + L2CAP 4/1 + L2CAP 2/43 + L2CAP 3/12 + L2CAP 1/4 + L2CAP 2/48 L2CAP 3/16 - L2CAP 2/49 L2CAP 2/48b L2CAP 4/2 L2CAP 2/41 @@ -321,17 +320,46 @@ L2CAP 3/1 L2CAP 0a/2 L2CAP 1/3 + L2CAP 2/40 + L2CAP 2/42 + L2CAP 2/47 L2CAP 4/3 L2CAP 1/5 - L2CAP 4/1 - L2CAP 2/43 - L2CAP 3/12 - L2CAP 1/4 - L2CAP 2/48 + L2CAP 2/49 + L2CAP 2/45a + L2CAP 1/6 + GATT 3a/1 + GATT 9/12 + GATT 1a/1 + GATT 1a/3 + GATT 4/11 + GATT 4/12 + GATT 4/9 + GATT 7/2 + GATT 4a/1 + GATT 1/1 + GATT 3/29 + GATT 3/21 + GATT 3/22 + GATT 3/23 + GATT 3/5 + GATT 4/10 + GATT 4/15 + GATT 4/7 + GATT 8/8 + GATT 10/5 + GATT 9/6 + GATT 9/5 + GATT 3/1 + GATT 3/7 + GATT 4/14 + GATT 4/25 + GATT 4/8 + GATT 7/7 GATT 10/7 GATT 10/12 GATT 9/8 @@ -345,14 +373,6 @@ GATT 4/21 GATT 4/22 GATT 7/4 - GATT 3a/1 - GATT 9/12 - GATT 1a/1 - GATT 1a/3 - GATT 4/11 - GATT 4/12 - GATT 4/9 - GATT 7/2 GATT 10/1 GATT 9/4 GATT 10/3 @@ -363,31 +383,14 @@ GATT 4/17 GATT 4/19 GATT 4/4 - GATT 8/8 - GATT 10/5 - GATT 9/6 - GATT 9/5 - GATT 3/1 - GATT 3/7 - GATT 4/14 - GATT 4/25 - GATT 4/8 - GATT 7/7 - GATT 10/11 - GATT 2/3a - GATT 9/2 - GATT 3a/2 - GATT 2/4 - GATT 9/1 - GATT 4/30 - GATT 4/31 - GATT 2/2 - GATT 3/15 - GATT 3/4 - GATT 3/9 - GATT 4/1 - GATT 4/18 - GATT 4/3 + GATT 9/3 + GATT 8/2 + GATT 10/2 + GATT 9/13 + GATT 7/8 + GATT 10/9 + GATT 9/9 + GATT 3/10 GATT 9/15 GATT 2/5 GATT 9/11 @@ -403,63 +406,60 @@ GATT 4/27 GATT 4/5 GATT 4/6 - GATT 9/3 - GATT 8/2 - GATT 10/2 - GATT 9/13 - GATT 7/8 - GATT 10/9 - GATT 9/9 - GATT 3/10 GATT 3/11 GATT 3/18 GATT 4/20 GATT 4/23 GATT 4/26 - GATT 4a/1 - GATT 1/1 - GATT 3/29 - GATT 3/21 - GATT 3/22 - GATT 3/23 - GATT 3/5 - GATT 4/10 - GATT 4/15 - GATT 4/7 + GATT 10/11 + GATT 2/3a + GATT 9/2 + GATT 3a/2 + GATT 2/4 + GATT 9/1 + GATT 4/30 + GATT 4/31 + GATT 2/2 + GATT 3/15 + GATT 3/4 + GATT 3/9 + GATT 4/1 + GATT 4/18 + GATT 4/3 - SM 4a/1 - SM 2a/1 - SM 5/3 - SM 1/1 SM 4b/1 - SM 4a/2 - SM 7a/1 SM 7a/2 SM 4a/3 SM 5/1 SM 5/4 + SM 4a/1 + SM 2a/1 + SM 5/3 + SM 4a/2 + SM 7a/1 + SM 4b/3 + SM 1/2 SM 2a/2 SM 7b/2 SM 4b/2 SM 5/2 - SM 4b/3 - SM 1/2 SM 7b/1 + SM 1/1 - ATT 6/1 - ATT 3/12 - ATT 3/15 - ATT 3/18 - ATT 4/10 - ATT 4/20 - ATT 3/10 - ATT 3/16 + ATT 7/2 + ATT 3/23 + ATT 3/8 + ATT 4/14 + ATT 4/17 + ATT 4/23 + ATT 4/4 + ATT 4/5 ATT 2/3a ATT 3/31 ATT 4/33 @@ -474,14 +474,28 @@ ATT 4/16 ATT 4/2 ATT 4/26 - ATT 7/2 - ATT 3/23 - ATT 3/8 - ATT 4/14 - ATT 4/17 - ATT 4/23 - ATT 4/4 - ATT 4/5 + ATT 6/1 + ATT 3/12 + ATT 3/15 + ATT 3/18 + ATT 4/10 + ATT 4/20 + ATT 3/10 + ATT 3/16 + ATT 7/1 + ATT 3/30 + ATT 3/32 + ATT 4/12 + ATT 4/22 + ATT 4/24 + ATT 4/27 + ATT 4/7 + ATT 4/8 + ATT 1/1 + ATT 4/31 + ATT 3/26 + ATT 4/1 + ATT 4/13 ATT 1/2 ATT 3/1 ATT 3/13 @@ -495,15 +509,6 @@ ATT 4/18 ATT 4/25 ATT 4/28 - ATT 7/1 - ATT 3/30 - ATT 3/32 - ATT 4/12 - ATT 4/22 - ATT 4/24 - ATT 4/27 - ATT 4/7 - ATT 4/8 ATT 7/3 ATT 4/32 ATT 2/2 @@ -515,133 +520,115 @@ ATT 4/3 ATT 4/6 ATT 4/9 - ATT 1/1 - ATT 4/31 - ATT 3/26 - ATT 4/1 - ATT 4/13 + DIS 2/11 DIS 3/3 DIS 2/7 - DIS 2/11 - DIS 2/4 - DIS 2/6 DIS 1/2 DIS 2/2 + DIS 2/4 + DIS 2/6 + DIS 2/5 + DIS 2/3 DIS 5/1 DIS 0/2 DIS 2/1 - DIS 2/3 - DIS 2/5 - IAS 3/1 + IAS 2/2 + IAS 2/3 + IAS 3/2 + IAS 1/2 IAS 0/1 IAS 2/1 IAS 2/4 - IAS 3/2 - IAS 1/2 - IAS 2/2 - IAS 2/3 + IAS 3/1 - HRS 1/2 + HRS 3/6 + HRS 2/1 HRS 0/1 HRS 3/2 HRS 3/5 - HRS 2/2 HRS 3/4 - HRS 3/6 - HRS 2/1 + HRS 1/2 + HRS 2/2 + BAS 4/1 BAS 3/3 BAS 2/1 BAS 3/5 - BAS 4/1 - BAS 4/2 - BAS 1/2 BAS 0/2 BAS 2/3 + BAS 4/2 + BAS 1/2 - OTS 8/2 - OTS 2/1 - OTS 4/6 - OTS 6/2 - OTS 6/4 - OTS 6/5 - OTS 4/1 - OTS 5/5 OTS 4/16 OTS 4/2 OTS 4/20 OTS 4/3 OTS 5/1 - OTS 8/6 - OTS 4/13 - OTS 4/15 - OTS 6/1 + OTS 8/7 OTS 8/3 OTS 3/2 OTS 4/12 OTS 4/4 OTS 4/5 OTS 5/2 - OTS 8/1b - OTS 8/8 - OTS 5/9 - OTS 6/3 - OTS 7/1 - OTS 8/7 + OTS 8/2 + OTS 2/1 + OTS 4/6 + OTS 6/2 + OTS 6/4 + OTS 6/5 + OTS 8/6 + OTS 4/13 + OTS 4/15 + OTS 6/1 OTS 8/4 OTS 3/3 OTS 4/7 OTS 5/3 OTS 5/6 + OTS 8/1b + OTS 8/8 + OTS 5/9 + OTS 6/3 + OTS 7/1 OTS 0/1 + OTS 4/1 + OTS 5/5 - OTP 9/10 - OTP 2/1 - OTP 6/11 - OTP 7/15 - OTP 7/17 - OTP 10/1 - OTP 9/14 - OTP 9/16 - OTP 4/1 - OTP 6/14 - OTP 6/2 - OTP 7/2 - OTP 8/17 - OTP 9/11 - OTP 9/15 OTP 9/18 OTP 3/2 OTP 6/1 OTP 6/13 OTP 7/16 OTP 8/18 - OTP 9/12 - OTP 6/10 - OTP 6/12 - OTP 7/1 - OTP 7/20 - OTP 7/7 + OTP 9/11 + OTP 9/15 + OTP 9/4 + OTP 9/9 + OTP 2/2 + OTP 5/1 + OTP 7/12 + OTP 7/6 OTP 9/3 OTP 0/1 OTP 6/3 @@ -650,32 +637,38 @@ OTP 7/3 OTP 8/2 OTP 8/30 + OTP 9/10 + OTP 2/1 + OTP 6/11 + OTP 7/15 + OTP 7/17 + OTP 9/12 + OTP 6/10 + OTP 6/12 + OTP 7/1 + OTP 7/20 + OTP 7/7 OTP 9/13 OTP 9/6 OTP 6/7 OTP 6/9 OTP 8/19 - OTP 9/4 - OTP 9/9 - OTP 2/2 - OTP 5/1 - OTP 7/12 - OTP 7/6 OTP 9/5 OTP 9/8 OTP 7/18 OTP 8/1 + OTP 10/1 + OTP 9/14 + OTP 9/16 + OTP 4/1 + OTP 6/14 + OTP 6/2 + OTP 7/2 + OTP 8/17 - MESH 11/24 - MESH 11/22 - MESH 11/1 - MESH 11/4 - MESH 12/1 - MESH 15/1 - MESH 20/3 MESH 11/20 MESH 10/5 MESH 2/3 @@ -706,22 +699,6 @@ MESH 18/7 MESH 20/4 MESH 21/3 - MESH 11/16 - MESH 11/7 - MESH 11/19 - MESH 11/5 - MESH 10/2 - MESH 11/3 - MESH 13/2 - MESH 14/5 - MESH 4/10 - MESH 4/5 - MESH 5/1 - MESH 5/2 - MESH 6/2 - MESH 18/5 - MESH 18/8 - MESH 20/1 MESH 11/11 MESH 4/14 MESH 12/8 @@ -734,6 +711,30 @@ MESH 4/7 MESH 7/3 MESH 19/1 + MESH 11/22 + MESH 11/1 + MESH 11/4 + MESH 11/12 + MESH 4/15 + MESH 11/18 + MESH 0/2 + MESH 12/7 + MESH 11/17 + MESH 11/21 + MESH 12/11 + MESH 10/3 + MESH 11/2 + MESH 12/5 + MESH 4/2 + MESH 4/6 + MESH 6/1 + MESH 7/5 + MESH 18/10 + MESH 18/3 + MESH 20/5 + MESH 12/1 + MESH 15/1 + MESH 20/3 MESH 11/23 MESH 12/12 MESH 18/12 @@ -755,24 +756,6 @@ MESH 5/4 MESH 18/11 MESH 21/2 - MESH 11/12 - MESH 4/15 - MESH 11/18 - MESH 0/2 - MESH 12/7 - MESH 11/17 - MESH 11/21 - MESH 12/11 - MESH 10/3 - MESH 11/2 - MESH 12/5 - MESH 4/2 - MESH 4/6 - MESH 6/1 - MESH 7/5 - MESH 18/10 - MESH 18/3 - MESH 20/5 MESH 4/17 MESH 10/1 MESH 13/1 @@ -785,71 +768,83 @@ MESH 20/2 MESH 21/1 MESH 21/4 + MESH 11/24 + MESH 11/16 + MESH 11/7 + MESH 11/19 + MESH 11/5 + MESH 10/2 + MESH 11/3 + MESH 13/2 + MESH 14/5 + MESH 4/10 + MESH 4/5 + MESH 5/1 + MESH 5/2 + MESH 6/2 + MESH 18/5 + MESH 18/8 + MESH 20/1 - LC3 3/6 - LC3 5/5 + LC3 6/1 + LC3 5/1 + LC3 2/3 + LC3 4/1 + LC3 2/1 + LC3 3/3 + LC3 5/3 + LC3 3/5 LC3 6/2 LC3 3/1 LC3 3/4 LC3 0/1 LC3 3/2 - LC3 2/3 - LC3 4/1 - LC3 4/2 - LC3 2/2 - LC3 2/1 - LC3 3/3 - LC3 5/3 - LC3 3/5 LC3 5/4 LC3 1/1 LC3 5/6 LC3 5/2 - LC3 6/1 - LC3 5/1 + LC3 4/2 + LC3 2/2 + LC3 3/6 + LC3 5/5 - AICS 4/3 - AICS 2/4 - AICS 3/5 - AICS 3/2 - AICS 2/8 + AICS 2/2 + AICS 2/6 + AICS 2/7 AICS 4/4 AICS 0a/1 AICS 2/1 AICS 4/6 AICS 1/2 - AICS 2/2 - AICS 2/6 - AICS 2/7 + AICS 4/3 + AICS 2/4 + AICS 3/5 + AICS 3/2 + AICS 2/8 + AICS 2/10 + AICS 3/4 + AICS 2/3 + AICS 2/9 + AICS 2/5 AICS 3/3 AICS 3/1 AICS 0/1 - AICS 2/10 AICS 4/1 AICS 4/2 AICS 3/3b - AICS 3/4 - AICS 2/3 - AICS 2/9 - AICS 2/5 - VOCS 3/3 VOCS 3/2 VOCS 0/1 - VOCS 1/2 - VOCS 2/3 - VOCS 2/1 - VOCS 2/6 - VOCS 2/8 + VOCS 3/3 VOCS 2/2 VOCS 3/4 VOCS 2/5 @@ -858,45 +853,38 @@ VOCS 2/4 VOCS 2/7 VOCS 3/1 + VOCS 1/2 + VOCS 2/3 + VOCS 2/1 + VOCS 2/6 + VOCS 2/8 - VCS 3/7 - VCS 3/4 - VCS 4/1 VCS 4/4 VCS 0a/1 VCS 4/2 - VCS 3/3 - VCS 1/2 - VCS 2/3 + VCS 3/7 + VCS 3/4 + VCS 4/1 + VCS 3/2 + VCS 3/1 VCS 3/6 VCS 2/1 VCS 2/4 - VCS 3/2 - VCS 3/1 VCS 0/1 VCS 3/5 VCS 4/6 VCS 2/2 VCS 4/3 + VCS 3/3 + VCS 1/2 + VCS 2/3 - VCP 17/11 - VCP 16/9 - VCP 13/1 - VCP 6/1 - VCP 18/1 - VCP 17/7 - VCP 17/10 - VCP 12/11 - VCP 14/4 - VCP 18/12 - VCP 17/2 - VCP 6/13 VCP 14/2 VCP 8/1 VCP 10/3 @@ -912,29 +900,18 @@ VCP 15/2 VCP 16/7 VCP 14/5 - VCP 12/8 - VCP 16/10 - VCP 11/2 - VCP 18/3 - VCP 14/3 - VCP 15/4 - VCP 12/7 - VCP 6/2 - VCP 12/5 - VCP 15/5 - VCP 16/4 - VCP 12/2 - VCP 14/9 - VCP 13/2 - VCP 16/3 - VCP 10/1 - VCP 6/3 - VCP 17/9 - VCP 12/12 - VCP 12/1 - VCP 12/6 - VCP 13/3 - VCP 16/6 + VCP 17/11 + VCP 16/9 + VCP 13/1 + VCP 6/1 + VCP 18/1 + VCP 17/7 + VCP 17/10 + VCP 12/11 + VCP 14/4 + VCP 18/12 + VCP 17/2 + VCP 6/13 VCP 18/15 VCP 15/3 VCP 12/3 @@ -948,6 +925,16 @@ VCP 14/6 VCP 18/6 VCP 1/1 + VCP 13/2 + VCP 16/3 + VCP 10/1 + VCP 6/3 + VCP 17/9 + VCP 12/12 + VCP 12/1 + VCP 12/6 + VCP 13/3 + VCP 16/6 VCP 17/5 VCP 16/11 VCP 18/7 @@ -973,34 +960,44 @@ VCP 6/8 VCP 17/13 VCP 17/6 + VCP 12/8 + VCP 16/10 + VCP 11/2 + VCP 18/3 + VCP 14/3 + VCP 15/4 + VCP 12/7 + VCP 6/2 + VCP 12/5 + VCP 15/5 + VCP 16/4 + VCP 12/2 + VCP 14/9 - MICS 3/6 - MICS 1/2 - MICS 3/1 - MICS 2/1 - MICS 3/3 MICS 0/1 MICS 3/4 + MICS 2/1 + MICS 3/3 + MICS 3/6 + MICS 1/2 MICS 3/2 + MICS 3/1 - MICP 14/9 - MICP 14/5 - MICP 16/7 - MICP 6/1 - MICP 15/10 MICP 16/3 - MICP 6/5 - MICP 12/1 - MICP 13/2 - MICP 16/6 - MICP 15/3 - MICP 14/14 + MICP 15/8 + MICP 16/5 + MICP 14/11 + MICP 15/1 + MICP 14/7 + MICP 3/1 + MICP 16/14 + MICP 14/12 MICP 14/2 MICP 14/13 MICP 15/2 @@ -1011,14 +1008,19 @@ MICP 16/4 MICP 13/5 MICP 5/2 - MICP 15/8 - MICP 16/5 - MICP 14/11 - MICP 15/1 - MICP 14/7 - MICP 3/1 - MICP 16/14 - MICP 14/12 + MICP 15/6 + MICP 15/11 + MICP 10/1 + MICP 12/3 + MICP 15/4 + MICP 12/2 + MICP 14/1 + MICP 14/4 + MICP 14/9 + MICP 14/5 + MICP 16/7 + MICP 6/1 + MICP 15/10 MICP 15/5 MICP 6/6 MICP 15/13 @@ -1036,38 +1038,25 @@ MICP 16/1 MICP 13/1 MICP 10/2 - MICP 15/6 - MICP 15/11 - MICP 10/1 - MICP 12/3 - MICP 15/4 - MICP 12/2 - MICP 14/1 - MICP 14/4 MICP 8/1 MICP 16/13 MICP 13/6 MICP 14/6 MICP 13/4 MICP 2/2 + MICP 6/5 + MICP 12/1 + MICP 13/2 + MICP 16/6 + MICP 15/3 + MICP 14/14 - MCS 23/19 - MCS 23/4 - MCS 23/3 - MCS 23/7 - MCS 24/1 - MCS 22/19 - MCS 22/5 - MCS 24/2 - MCS 23/10 - MCS 25/4 - MCS 22/20 - MCS 22/13 - MCS 25/2 - MCS 22/25 + MCS 23/11 + MCS 23/17 + MCS 22/6 MCS 22/3 MCS 20/1 MCS 22/23 @@ -1090,12 +1079,17 @@ MCS 25/1 MCS 0b/2 MCS 23/18 - MCS 24/3 - MCS 22/7 - MCS 22/24 - MCS 23/20 - MCS 25/3 - MCS 23/14 + MCS 23/7 + MCS 24/1 + MCS 22/19 + MCS 22/5 + MCS 24/2 + MCS 23/10 + MCS 25/4 + MCS 22/20 + MCS 22/13 + MCS 25/2 + MCS 22/25 MCS 23/21 MCS 22/26 MCS 22/11 @@ -1106,41 +1100,38 @@ MCS 22/9 MCS 22/8 MCS 22/14 - MCS 23/11 - MCS 23/17 - MCS 22/6 + MCS 24/3 + MCS 22/7 + MCS 22/24 + MCS 23/20 + MCS 25/3 + MCS 23/14 MCS 22/10 MCS 23/1 MCS 22/18 MCS 23/2 MCS 22/4 + MCS 23/19 + MCS 23/4 + MCS 23/3 - MCP 18/5 - MCP 5/4 - MCP 16/12 - MCP 17/2 - MCP 18a/3 - MCP 9/1 - MCP 6/7 - MCP 18/6 - MCP 16/3 - MCP 16/1 - MCP 17/10 - MCP 5/3 - MCP 17/16 - MCP 16/18 - MCP 18/2 - MCP 16/22 - MCP 6/2 - MCP 18/7 - MCP 17/12 - MCP 16/14 - MCP 18a/10 - MCP 16/13 - MCP 17/8 + MCP 9/2 + MCP 21/2 + MCP 18a/14 + MCP 20/1 + MCP 6/1 + MCP 17/6 + MCP 16/17 + MCP 16/11 + MCP 17/5 + MCP 18a/11 + MCP 9/3 + MCP 16/5 + MCP 13/3 + MCP 18/8 MCP 16/19 MCP 21/3 MCP 8/1 @@ -1151,11 +1142,6 @@ MCP 6/4 MCP 1/2 MCP 18a/4 - MCP 16/4 - MCP 6/5 - MCP 18/4 - MCP 18/3 - MCP 6/13 MCP 21/1 MCP 18a/6 MCP 2/2 @@ -1177,13 +1163,15 @@ MCP 17/14 MCP 16/20 MCP 1/1 - MCP 16/10 - MCP 17/20 - MCP 17/15 - MCP 16/2 - MCP 10/1 - MCP 18a/2 - MCP 16/15 + MCP 18/2 + MCP 16/22 + MCP 6/2 + MCP 18/7 + MCP 17/12 + MCP 16/14 + MCP 18a/10 + MCP 16/13 + MCP 17/8 MCP 6/3 MCP 18a/12 MCP 18a/13 @@ -1197,24 +1185,58 @@ MCP 16/16 MCP 5/2 MCP 18a/7 - MCP 9/2 - MCP 21/2 - MCP 18a/14 - MCP 20/1 - MCP 6/1 - MCP 17/6 - MCP 16/17 - MCP 16/11 - MCP 17/5 - MCP 18a/11 - MCP 9/3 - MCP 16/5 - MCP 13/3 - MCP 18/8 + MCP 16/4 + MCP 6/5 + MCP 18/4 + MCP 18/3 + MCP 6/13 + MCP 16/10 + MCP 17/20 + MCP 17/15 + MCP 16/2 + MCP 10/1 + MCP 18a/2 + MCP 16/15 + MCP 18/5 + MCP 5/4 + MCP 16/12 + MCP 17/2 + MCP 18a/3 + MCP 9/1 + MCP 6/7 + MCP 18/6 + MCP 16/3 + MCP 16/1 + MCP 17/10 + MCP 5/3 + MCP 17/16 + MCP 16/18 + TBS 2/15 + TBS 23/1 + TBS 20/1 + TBS 22/19 + TBS 22/8 + TBS 4/1 + TBS 24/1 + TBS 2/11 + TBS 23/4 + TBS 3/5 + TBS 22/20 + TBS 24/5 + TBS 2/7 + TBS 23/6 + TBS 2/19 + TBS 22/18 + TBS 22/25 + TBS 22/21 + TBS 2/24 + TBS 22/23 + TBS 24/4 + TBS 22/9 TBS 23/5 TBS 2/12 TBS 24/2 @@ -1229,21 +1251,6 @@ TBS 1/2 TBS 24/7 TBS 22/11 - TBS 4/3 - TBS 23/2 - TBS 0b/1 - TBS 2/15 - TBS 23/1 - TBS 20/1 - TBS 22/19 - TBS 22/8 - TBS 4/1 - TBS 24/1 - TBS 2/11 - TBS 23/4 - TBS 3/5 - TBS 22/20 - TBS 24/5 TBS 3/1 TBS 22/17 TBS 22/15 @@ -1256,16 +1263,12 @@ TBS 2/17 TBS 4/4 TBS 2/20 - TBS 2/7 - TBS 23/6 - TBS 2/19 - TBS 22/18 - TBS 22/25 - TBS 22/21 - TBS 2/24 - TBS 22/23 - TBS 24/4 - TBS 22/9 + TBS 22/2 + TBS 4/2 + TBS 2/14 + TBS 0/1 + TBS 22/5 + TBS 3/3 TBS 22/3 TBS 2/13 TBS 4/5 @@ -1276,12 +1279,6 @@ TBS 2/10 TBS 22/22 TBS 2/8 - TBS 22/2 - TBS 4/2 - TBS 2/14 - TBS 0/1 - TBS 22/5 - TBS 3/3 TBS 22/7 TBS 22/24 TBS 2/2 @@ -1295,25 +1292,13 @@ TBS 21/2 TBS 22/6 TBS 2/1 + TBS 4/3 + TBS 23/2 + TBS 0b/1 - CCP 12/7 - CCP 17/3 - CCP 17/13 - CCP 12/11 - CCP 15/3 - CCP 10/2 - CCP 12/8 - CCP 12/22 - CCP 14/16 - CCP 12/4 - CCP 12/15 - CCP 14/17 - CCP 11/7 - CCP 13/4 - CCP 8/1 CCP 12/6 CCP 13/5 CCP 13/10 @@ -1328,15 +1313,6 @@ CCP 15/7 CCP 11/10 CCP 13/9 - CCP 14/8 - CCP 6/2 - CCP 14/3 - CCP 12/3 - CCP 12/19 - CCP 14/14 - CCP 13/11 - CCP 12/20 - CCP 11/6 CCP 13/14 CCP 17/7 CCP 11/9 @@ -1368,6 +1344,32 @@ CCP 15/4 CCP 2/2 CCP 11/16 + CCP 12/7 + CCP 17/3 + CCP 17/13 + CCP 12/11 + CCP 15/3 + CCP 10/2 + CCP 12/8 + CCP 12/22 + CCP 14/16 + CCP 12/4 + CCP 12/15 + CCP 14/17 + CCP 11/7 + CCP 13/4 + CCP 8/1 + CCP 14/8 + CCP 6/2 + CCP 14/3 + CCP 12/3 + CCP 12/19 + CCP 14/14 + CCP 13/11 + CCP 12/20 + CCP 11/6 + CCP 17/15 + CCP 12/13 CCP 17/14 CCP 17/6 CCP 6/4 @@ -1400,12 +1402,7 @@ CCP 13/7 CCP 6/5 CCP 17/4 - CCP 17/15 - CCP 12/13 CCP 14/5 - CCP 14/1 - CCP 11/13 - CCP 12/1 CCP 12/17 CCP 11/2 CCP 17/9 @@ -1416,42 +1413,35 @@ CCP 13/2 CCP 14/15 CCP 14/12 + CCP 12/1 + CCP 14/1 + CCP 11/13 - CSIS 2/2 - CSIS 2/6 - CSIS 0a/2 - CSIS 3/1 CSIS 2/7 CSIS 1/2 CSIS 3/3 CSIS 2a/1 CSIS 2/1 CSIS 3/6 - CSIS 2/4 + CSIS 2/2 + CSIS 2/6 + CSIS 0a/2 + CSIS 3/1 CSIS 2/3 - CSIS 2/5 - CSIS 5/1 - CSIS 3/4 + CSIS 2/4 CSIS 0/1 CSIS 2a/2 CSIS 3/2 + CSIS 5/1 + CSIS 3/4 + CSIS 2/5 - CSIP 12/2 - CSIP 6/15 - CSIP 6/9 - CSIP 6/1 - CSIP 5/5 - CSIP 13/10 - CSIP 5/1 - CSIP 4/2 - CSIP 9/2 - CSIP 14/4 CSIP 14/2 CSIP 13/6 CSIP 5/2 @@ -1470,8 +1460,16 @@ CSIP 5/6 CSIP 11/4 CSIP 5/7 - CSIP 6/16 - CSIP 6/8 + CSIP 12/2 + CSIP 6/15 + CSIP 6/9 + CSIP 6/1 + CSIP 5/5 + CSIP 13/10 + CSIP 5/1 + CSIP 4/2 + CSIP 9/2 + CSIP 14/4 CSIP 14/6 CSIP 12/4 CSIP 1/1 @@ -1480,15 +1478,8 @@ CSIP 11/2 CSIP 14/3 CSIP 5/8 - CSIP 6/3 - CSIP 13/5 - CSIP 14/8 - CSIP 13/2 - CSIP 13/7 - CSIP 13/1 - CSIP 6/6 - CSIP 13/11 - CSIP 2/2 + CSIP 6/16 + CSIP 6/8 CSIP 14/9 CSIP 5/4 CSIP 6/2 @@ -1498,46 +1489,62 @@ CSIP 12/3 CSIP 13/3 CSIP 3/1 + CSIP 13/1 + CSIP 6/6 + CSIP 13/11 + CSIP 2/2 + CSIP 6/3 + CSIP 13/5 + CSIP 14/8 + CSIP 13/2 + CSIP 13/7 - PACS 4/5 - PACS 4/11 - PACS 3/4 - PACS 1/2 - PACS 4/3 - PACS 3/1 - PACS 4/14 - PACS 4/8 - PACS 6/7 - PACS 3/6 PACS 4/12 PACS 0/1 PACS 6/2 PACS 3/5 PACS 4/16 PACS 6/5 - PACS 4/9 - PACS 4/10 - PACS 6/4 PACS 6/3 PACS 4/6 PACS 4/2 PACS 3/3 PACS 6/1 PACS 5/1 + PACS 4/5 + PACS 4/11 + PACS 3/4 + PACS 1/2 + PACS 4/3 + PACS 3/1 + PACS 4/14 + PACS 4/9 + PACS 4/10 + PACS 6/4 + PACS 2/2 PACS 4/4 PACS 3/2 - PACS 2/2 PACS 4/15 PACS 4/1 PACS 4/13 PACS 4/7 + PACS 4/8 + PACS 6/7 + PACS 3/6 + ASCS 6/3 + ASCS 7/2 + ASCS 6/8 + ASCS 1/1 + ASCS 4/2 + ASCS 9/6 + ASCS 6/4 ASCS 9/2 ASCS 9/9 ASCS 4/3 @@ -1549,39 +1556,27 @@ ASCS 7/5 ASCS 6/5 ASCS 2/2 - ASCS 9/6 - ASCS 6/4 - ASCS 6/3 - ASCS 7/2 - ASCS 6/8 - ASCS 1/1 - ASCS 4/2 - ASCS 5/3 - ASCS 6/6 - ASCS 5/2 ASCS 6/2 ASCS 8/1 ASCS 6/1 ASCS 6/9 ASCS 4/1 - ASCS 9/3 - ASCS 7/1 - ASCS 0/1 ASCS 6/7 ASCS 7/4 ASCS 9/7 ASCS 9/1 ASCS 8/2 + ASCS 5/3 + ASCS 6/6 + ASCS 5/2 + ASCS 9/3 + ASCS 7/1 + ASCS 0/1 - BASS 5/8 - BASS 3/3 BASS 4/3 - BASS 3/2a - BASS 5/3 - BASS 1/1 BASS 4/6 BASS 4/2 BASS 0/1 @@ -1589,19 +1584,133 @@ BASS 3/4 BASS 2/2 BASS 4/4 - BASS 5/5 - BASS 5/4 - BASS 5/1 - BASS 4/5 + BASS 5/8 + BASS 3/3 + BASS 3/2a + BASS 5/3 + BASS 1/1 BASS 5/2 BASS 5/6 BASS 3/5 BASS 4/1 BASS 3/2 + BASS 5/5 + BASS 5/4 + BASS 5/1 + BASS 4/5 + BAP 33a/7 + BAP 68/6 + BAP 32/1 + BAP 43/1 + BAP 65/5 + BAP 74/12 + BAP 20/9 + BAP 39/9 + BAP 15/13 + BAP 41/13 + BAP 37/7 + BAP 77/1 + BAP 41/16 + BAP 69/13 + BAP 21/7 + BAP 38/6 + BAP 90/17 + BAP 15/12 + BAP 61/3 + BAP 33a/8 + BAP 45/4 + BAP 55/4 + BAP 22/9 + BAP 88/5 + BAP 16/5 + BAP 74/25 + BAP 38/7 + BAP 39/14 + BAP 40/1 + BAP 86/4 + BAP 74/3 + BAP 69/4 + BAP 45/16 + BAP 69/14 + BAP 26/1 + BAP 61/5 + BAP 74/23 + BAP 9a/1 + BAP 22/12 + BAP 41/11 + BAP 72/1 + BAP 89/15 + BAP 12/3 + BAP 34/2 + BAP 65/4 + BAP 31/1 + BAP 1/2 + BAP 65/2 + BAP 21/6 + BAP 16/10 + BAP 46/3 + BAP 14/5 + BAP 85/4 + BAP 36/14 + BAP 83/1 + BAP 8/1 + BAP 23/6 + BAP 17/8 + BAP 13/15 + BAP 60/4 + BAP 23/18 + BAP 69/5 + BAP 80/21 + BAP 55/11 + BAP 90/1 + BAP 69/8 + BAP 12/7 + BAP 78/3 + BAP 54/1 + BAP 22/5 + BAP 55/10 + BAP 16/15 + BAP 17/6 + BAP 89/9 + BAP 30/1 + BAP 74/2 + BAP 9/4 + BAP 73/6 + BAP 32/3 + BAP 56/9 + BAP 36/10 + BAP 52/5 + BAP 68/7 + BAP 44/4 + BAP 56/11 + BAP 74/9 + BAP 70/8 + BAP 68/5 + BAP 33/3 + BAP 37/2 + BAP 54/3 + BAP 93/2 + BAP 1/6 + BAP 7/3 + BAP 88/4 + BAP 55/16 + BAP 21/1 + BAP 20/5 + BAP 14/16 + BAP 41/9 + BAP 37/6 + BAP 80/14 + BAP 80/2 + BAP 59/3 + BAP 44/14 + BAP 31/6 + BAP 68/14 + BAP 33a/6 + BAP 34/1 BAP 70/11 BAP 14/11 BAP 54/4 @@ -1722,170 +1831,6 @@ BAP 92/1 BAP 70/16 BAP 73/8 - BAP 23/6 - BAP 17/8 - BAP 13/15 - BAP 60/4 - BAP 23/18 - BAP 69/5 - BAP 80/21 - BAP 55/11 - BAP 90/1 - BAP 69/8 - BAP 12/7 - BAP 78/3 - BAP 54/1 - BAP 22/5 - BAP 55/10 - BAP 16/15 - BAP 17/6 - BAP 89/9 - BAP 30/1 - BAP 74/2 - BAP 9/4 - BAP 73/6 - BAP 32/3 - BAP 56/9 - BAP 36/10 - BAP 52/5 - BAP 68/7 - BAP 44/4 - BAP 56/11 - BAP 74/9 - BAP 70/8 - BAP 68/5 - BAP 33/3 - BAP 37/2 - BAP 54/3 - BAP 93/2 - BAP 1/6 - BAP 7/3 - BAP 88/4 - BAP 55/16 - BAP 21/1 - BAP 20/5 - BAP 14/16 - BAP 41/9 - BAP 37/6 - BAP 80/14 - BAP 80/2 - BAP 59/3 - BAP 44/14 - BAP 31/6 - BAP 68/14 - BAP 33a/6 - BAP 34/1 - BAP 33a/7 - BAP 68/6 - BAP 32/1 - BAP 43/1 - BAP 65/5 - BAP 74/12 - BAP 20/9 - BAP 39/9 - BAP 15/13 - BAP 41/13 - BAP 37/7 - BAP 77/1 - BAP 41/16 - BAP 69/13 - BAP 21/7 - BAP 38/6 - BAP 90/17 - BAP 15/12 - BAP 61/3 - BAP 33a/8 - BAP 45/4 - BAP 55/4 - BAP 22/9 - BAP 88/5 - BAP 16/5 - BAP 74/25 - BAP 38/7 - BAP 39/14 - BAP 40/1 - BAP 86/4 - BAP 74/3 - BAP 69/4 - BAP 45/16 - BAP 69/14 - BAP 26/1 - BAP 61/5 - BAP 74/23 - BAP 9a/1 - BAP 22/12 - BAP 41/11 - BAP 72/1 - BAP 89/15 - BAP 12/3 - BAP 34/2 - BAP 65/4 - BAP 31/1 - BAP 1/2 - BAP 65/2 - BAP 21/6 - BAP 16/10 - BAP 46/3 - BAP 14/5 - BAP 85/4 - BAP 36/14 - BAP 83/1 - BAP 8/1 - BAP 38/5 - BAP 38/11 - BAP 22/8 - BAP 90/6 - BAP 20/1 - BAP 40/5 - BAP 59/6 - BAP 12/13 - BAP 39/3 - BAP 52/3 - BAP 39/16 - BAP 23/7 - BAP 69/12 - BAP 72/3 - BAP 74/22 - BAP 88/7 - BAP 44/1 - BAP 55/8 - BAP 33a/4 - BAP 38/8 - BAP 82/2 - BAP 74/8 - BAP 74/15 - BAP 22/1 - BAP 39/6 - BAP 73/3 - BAP 44/5 - BAP 45/3 - BAP 33a/5 - BAP 89/11 - BAP 46/4 - BAP 12/1 - BAP 86/3 - BAP 15/11 - BAP 37/10 - BAP 89/3 - BAP 54/16 - BAP 9a/2 - BAP 33/8 - BAP 51/2 - BAP 66/1 - BAP 37/12 - BAP 59/9 - BAP 37/5 - BAP 31/3 - BAP 70/9 - BAP 54/2 - BAP 22/11 - BAP 73/7 - BAP 94/1 - BAP 17/1 - BAP 7/4 - BAP 23/19 - BAP 14/6 - BAP 12/15 BAP 66/2 BAP 89/2 BAP 38/9 @@ -1944,62 +1889,6 @@ BAP 13/12 BAP 59/4 BAP 94/2 - BAP 44/13 - BAP 10/1 - BAP 89/13 - BAP 68/11 - BAP 9a/6 - BAP 21/9 - BAP 88/3 - BAP 1/4 - BAP 51/4 - BAP 7/7 - BAP 21/12 - BAP 40/2 - BAP 73/9 - BAP 21/8 - BAP 29/1 - BAP 21/11 - BAP 36/6 - BAP 60/1 - BAP 39/7 - BAP 76/3 - BAP 21/4 - BAP 92/7 - BAP 16/6 - BAP 36/11 - BAP 45/9 - BAP 55/1 - BAP 16/16 - BAP 44/10 - BAP 55/15 - BAP 65/3 - BAP 76/4 - BAP 39/13 - BAP 16/7 - BAP 37/4 - BAP 22/3 - BAP 59/1 - BAP 92/3 - BAP 59/10 - BAP 80/10 - BAP 34/5 - BAP 60/2 - BAP 37/11 - BAP 59/8 - BAP 12/14 - BAP 23/4 - BAP 38/14 - BAP 68/17 - BAP 40/12 - BAP 74/11 - BAP 14/7 - BAP 73/4 - BAP 45/10 - BAP 80/24 - BAP 17/15 - BAP 38/16 - BAP 36/4 BAP 7/8 BAP 93/4 BAP 14/13 @@ -2058,105 +1947,176 @@ BAP 14/4 BAP 27/5 BAP 34/3 - BAP 74/1 - BAP 20/8 - BAP 16/1 - BAP 7/6 - BAP 20/6 - BAP 95/6 - BAP 21/5 - BAP 90/11 - BAP 37/3 - BAP 73/10 - BAP 74/10 - BAP 21/3 - BAP 38/3 - BAP 51/3 - BAP 40/13 - BAP 68/16 - BAP 15/9 - BAP 14/1 - BAP 10/2 - BAP 36/16 - BAP 40/10 - BAP 44/3 - BAP 90/8 - BAP 55/3 - BAP 90/7 - BAP 54/15 - BAP 16/12 - BAP 92/4 - BAP 89/12 - BAP 39/2 - BAP 64/2 - BAP 31/2 - BAP 15/5 - BAP 95/4 - BAP 15/3 - BAP 85/2 - BAP 41/12 - BAP 45/7 - BAP 44/11 - BAP 87/4 - BAP 44/16 - BAP 11/2 - BAP 12/2 - BAP 80/3 - BAP 12/6 - BAP 15/4 - BAP 7/2 - BAP 88/2 - BAP 32/4 - BAP 37/14 - BAP 44/12 - BAP 55/14 - BAP 20/10 - BAP 52/4 - BAP 32/8 - BAP 46/1 - BAP 30/2 - BAP 70/10 - BAP 79/2 - BAP 56/7 - BAP 23/5 - BAP 65/1 - BAP 40/3 - BAP 69/3 - BAP 61/2 - BAP 17/3 - BAP 13/9 - BAP 15/1 - BAP 38/10 - BAP 10/4 - BAP 9a/8 - BAP 70/13 - BAP 67/2 - BAP 59/2 - BAP 55/9 - BAP 33/2 - BAP 69/7 - BAP 57/1 - BAP 68/3 - BAP 70/3 - BAP 61/6 - BAP 17/11 - BAP 35/1 - BAP 56/4 - BAP 49/1 - BAP 70/14 - BAP 44/6 - BAP 9/7 - BAP 29/2 - BAP 54/5 - BAP 13/17 - BAP 61/4 - BAP 41/10 - BAP 56/3 - BAP 15/6 - BAP 17/16 - BAP 3/1 - BAP 15/7 - BAP 56/15 + BAP 38/5 + BAP 38/11 + BAP 22/8 + BAP 90/6 + BAP 20/1 + BAP 40/5 + BAP 59/6 + BAP 12/13 + BAP 39/3 + BAP 52/3 + BAP 39/16 + BAP 23/7 + BAP 69/12 + BAP 72/3 + BAP 74/22 + BAP 88/7 + BAP 44/1 + BAP 55/8 + BAP 33a/4 + BAP 38/8 + BAP 82/2 + BAP 74/8 + BAP 74/15 + BAP 22/1 + BAP 39/6 + BAP 73/3 + BAP 44/5 + BAP 45/3 + BAP 33a/5 + BAP 89/11 + BAP 46/4 + BAP 12/1 + BAP 86/3 + BAP 15/11 + BAP 37/10 + BAP 89/3 + BAP 54/16 + BAP 9a/2 + BAP 33/8 + BAP 51/2 + BAP 66/1 + BAP 37/12 + BAP 59/9 + BAP 37/5 + BAP 31/3 + BAP 70/9 + BAP 54/2 + BAP 22/11 + BAP 73/7 + BAP 94/1 + BAP 17/1 + BAP 7/4 + BAP 23/19 + BAP 14/6 + BAP 12/15 + BAP 44/13 + BAP 10/1 + BAP 89/13 + BAP 68/11 + BAP 9a/6 + BAP 21/9 + BAP 88/3 + BAP 1/4 + BAP 51/4 + BAP 7/7 + BAP 21/12 + BAP 40/2 + BAP 73/9 + BAP 21/8 + BAP 29/1 + BAP 21/11 + BAP 36/6 + BAP 60/1 + BAP 39/7 + BAP 76/3 + BAP 21/4 + BAP 92/7 + BAP 16/6 + BAP 36/11 + BAP 45/9 + BAP 55/1 + BAP 16/16 + BAP 44/10 + BAP 55/15 + BAP 65/3 + BAP 76/4 + BAP 39/13 + BAP 16/7 + BAP 37/4 + BAP 22/3 + BAP 59/1 + BAP 92/3 + BAP 59/10 + BAP 80/10 + BAP 34/5 + BAP 60/2 + BAP 37/11 + BAP 59/8 + BAP 12/14 + BAP 23/4 + BAP 38/14 + BAP 68/17 + BAP 40/12 + BAP 74/11 + BAP 14/7 + BAP 73/4 + BAP 45/10 + BAP 80/24 + BAP 17/15 + BAP 38/16 + BAP 36/4 + BAP 54/15 + BAP 16/12 + BAP 92/4 + BAP 89/12 + BAP 39/2 + BAP 64/2 + BAP 31/2 + BAP 15/5 + BAP 95/4 + BAP 15/3 + BAP 85/2 + BAP 41/12 + BAP 45/7 + BAP 44/11 + BAP 87/4 + BAP 44/16 + BAP 11/2 + BAP 12/2 + BAP 80/3 + BAP 12/6 + BAP 15/4 + BAP 7/2 + BAP 88/2 + BAP 32/4 + BAP 37/14 + BAP 44/12 + BAP 55/14 + BAP 20/10 + BAP 52/4 + BAP 32/8 + BAP 46/1 + BAP 30/2 + BAP 70/10 + BAP 79/2 + BAP 56/7 + BAP 33/2 + BAP 69/7 + BAP 57/1 + BAP 68/3 + BAP 70/3 + BAP 61/6 + BAP 17/11 + BAP 35/1 + BAP 56/4 + BAP 49/1 + BAP 70/14 + BAP 44/6 + BAP 9/7 + BAP 29/2 + BAP 54/5 + BAP 13/17 + BAP 61/4 + BAP 41/10 + BAP 56/3 + BAP 15/6 + BAP 17/16 + BAP 3/1 + BAP 15/7 + BAP 56/15 BAP 9a/5 BAP 14/14 BAP 37/8 @@ -2165,6 +2125,84 @@ BAP 90/15 BAP 16/2 BAP 89/4 + BAP 74/1 + BAP 20/8 + BAP 16/1 + BAP 7/6 + BAP 20/6 + BAP 95/6 + BAP 21/5 + BAP 90/11 + BAP 37/3 + BAP 73/10 + BAP 74/10 + BAP 21/3 + BAP 38/3 + BAP 51/3 + BAP 40/13 + BAP 68/16 + BAP 15/9 + BAP 14/1 + BAP 10/2 + BAP 36/16 + BAP 40/10 + BAP 44/3 + BAP 90/8 + BAP 55/3 + BAP 90/7 + BAP 23/5 + BAP 65/1 + BAP 40/3 + BAP 69/3 + BAP 61/2 + BAP 17/3 + BAP 13/9 + BAP 15/1 + BAP 38/10 + BAP 10/4 + BAP 9a/8 + BAP 70/13 + BAP 67/2 + BAP 59/2 + BAP 55/9 + BAP 51/5 + BAP 7/5 + BAP 46/5 + BAP 13/6 + BAP 25/1 + BAP 93/1 + BAP 96/1 + BAP 48/3 + BAP 40/16 + BAP 33/7 + BAP 56/12 + BAP 92/2 + BAP 60/3 + BAP 70/1 + BAP 38/2 + BAP 16/11 + BAP 80/7 + BAP 86/2 + BAP 82/4 + BAP 14/3 + BAP 70/7 + BAP 90/14 + BAP 68/10 + BAP 69/1 + BAP 45/5 + BAP 68/15 + BAP 1/1 + BAP 39/8 + BAP 41/15 + BAP 44/2 + BAP 40/7 + BAP 36/3 + BAP 89/6 + BAP 39/15 + BAP 39/1 + BAP 46/15 + BAP 17/14 + BAP 41/7 BAP 59/7 BAP 36/15 BAP 22/10 @@ -2234,44 +2272,6 @@ BAP 51/6 BAP 17/4 BAP 18/1 - BAP 51/5 - BAP 7/5 - BAP 46/5 - BAP 13/6 - BAP 25/1 - BAP 93/1 - BAP 96/1 - BAP 48/3 - BAP 40/16 - BAP 33/7 - BAP 56/12 - BAP 92/2 - BAP 60/3 - BAP 70/1 - BAP 38/2 - BAP 16/11 - BAP 80/7 - BAP 86/2 - BAP 82/4 - BAP 14/3 - BAP 70/7 - BAP 90/14 - BAP 68/10 - BAP 69/1 - BAP 45/5 - BAP 68/15 - BAP 1/1 - BAP 39/8 - BAP 41/15 - BAP 44/2 - BAP 40/7 - BAP 36/3 - BAP 89/6 - BAP 39/15 - BAP 39/1 - BAP 46/15 - BAP 17/14 - BAP 41/7 @@ -2284,23 +2284,6 @@ - CAP 11/11 - CAP 1/1 - CAP 12/1 - CAP 4/1 - CAP 28/9 - CAP 7/8 - CAP 6/4 - CAP 28/5 - CAP 3/1 - CAP 20/1 - CAP 28/2 - CAP 28/4 - CAP 28/7 - CAP 11/3 - CAP 22/5 - CAP 6b/2 - CAP 27/5 CAP 8/3 CAP 31/4 CAP 17/2 @@ -2322,22 +2305,6 @@ CAP 8/4 CAP 6a/3 CAP 21/4 - CAP 22/1 - CAP 28/1 - CAP 26/6 - CAP 28/8 - CAP 20/2 - CAP 13/2 - CAP 30/3 - CAP 27/1 - CAP 6/6 - CAP 27/2 - CAP 15/1 - CAP 6/5 - CAP 6a/1 - CAP 20/4 - CAP 22/6 - CAP 11/1 CAP 2/2 CAP 16/2 CAP 19/2 @@ -2365,6 +2332,64 @@ CAP 23a/3 CAP 30/4 CAP 19/4 + CAP 11/11 + CAP 1/1 + CAP 12/1 + CAP 4/1 + CAP 28/9 + CAP 7/8 + CAP 6/4 + CAP 28/5 + CAP 3/1 + CAP 20/1 + CAP 28/2 + CAP 28/4 + CAP 28/7 + CAP 11/3 + CAP 22/5 + CAP 6b/2 + CAP 27/5 + CAP 22/1 + CAP 28/1 + CAP 26/6 + CAP 28/8 + CAP 20/2 + CAP 13/2 + CAP 30/3 + CAP 27/1 + CAP 6/6 + CAP 27/2 + CAP 15/1 + CAP 6/5 + CAP 6a/1 + CAP 20/4 + CAP 22/6 + CAP 11/1 + CAP 18/2 + CAP 28/3 + CAP 6/1 + CAP 6/7 + CAP 7/6 + CAP 22/8 + CAP 23a/1 + CAP 26/2 + CAP 13/1 + CAP 32/1 + CAP 31/3 + CAP 31/1 + CAP 22/9 + CAP 17/3 + CAP 33a/4 + CAP 11/2 + CAP 28/6 + CAP 6/3 + CAP 22/10 + CAP 30/1 + CAP 21/1 + CAP 17/4 + CAP 27/4 + CAP 11/12 + CAP 16/3 CAP 28/11 CAP 7/1 CAP 19/1 @@ -2401,53 +2426,15 @@ CAP 20/6 CAP 7/5 CAP 17/1 - CAP 18/2 - CAP 28/3 - CAP 6/1 - CAP 6/7 - CAP 7/6 - CAP 22/8 - CAP 23a/1 - CAP 26/2 - CAP 13/1 - CAP 32/1 - CAP 31/3 - CAP 31/1 - CAP 22/9 - CAP 17/3 - CAP 33a/4 - CAP 11/2 - CAP 28/6 - CAP 6/3 - CAP 22/10 - CAP 30/1 - CAP 21/1 - CAP 17/4 - CAP 27/4 - CAP 11/12 - CAP 16/3 - HAS 4/2 - HAS 5/5 - HAS 3/6 - HAS 0/1 - HAS 5/2 - HAS 5/3 - HAS 4/6 + HAS 3/14 HAS 4/4 HAS 1/1 HAS 4/9 HAS 3/1a - HAS 4/7 - HAS 2/2 - HAS 3/4 - HAS 3/9 - HAS 3/13 - HAS 3/8 - HAS 3/3 HAS 4/8 HAS 4/3 HAS 3/7 @@ -2459,28 +2446,35 @@ HAS 4/5 HAS 5/7 HAS 3/1 + HAS 5/2 + HAS 5/3 + HAS 4/6 HAS 5/4 HAS 5/1 HAS 4/1 HAS 5/6 HAS 3/10 - HAS 3/14 + HAS 4/7 + HAS 2/2 + HAS 3/4 + HAS 3/9 + HAS 3/13 + HAS 3/8 + HAS 3/3 + HAS 4/2 + HAS 5/5 + HAS 3/6 + HAS 0/1 - HAP 12/7 - HAP 13/7 - HAP 12/6 - HAP 11/1 - HAP 93/2 - HAP 46/1 - HAP 24/2 - HAP 13/1 - HAP 43/4 - HAP 24/6 - HAP 13/5 - HAP 93/4 + HAP 12/5 + HAP 14/3 + HAP 13/2 + HAP 16/2 + HAP 13/3 + HAP 12/4 HAP 10/1 HAP 92/1 HAP 51/1 @@ -2490,11 +2484,6 @@ HAP 17/1 HAP 43/1 HAP 41/1 - HAP 13/6 - HAP 50/3 - HAP 18/1 - HAP 1/1 - HAP 19/2 HAP 26/1 HAP 93/1 HAP 16/1 @@ -2506,6 +2495,12 @@ HAP 19/1 HAP 24/4 HAP 14/1 + HAP 24/2 + HAP 13/1 + HAP 43/4 + HAP 24/6 + HAP 13/5 + HAP 93/4 HAP 50/1 HAP 24/5 HAP 13/4 @@ -2519,78 +2514,21 @@ HAP 12/1 HAP 93/5 HAP 1/4 - HAP 12/5 - HAP 14/3 - HAP 13/2 - HAP 16/2 - HAP 13/3 - HAP 12/4 + HAP 13/6 + HAP 50/3 + HAP 18/1 + HAP 1/1 + HAP 19/2 + HAP 12/7 + HAP 13/7 + HAP 12/6 + HAP 11/1 + HAP 93/2 + HAP 46/1 - TMAP 57/2 - TMAP 19/1 - TMAP 96/16 - TMAP 116/9 - TMAP 96/2 - TMAP 75/3 - TMAP 10/1 - TMAP 153/1 - TMAP 17/7 - TMAP 94/6 - TMAP 71/1 - TMAP 14/8 - TMAP 151/1 - TMAP 115/4 - TMAP 74/7 - TMAP 130/4 - TMAP 131/1 - TMAP 154/1 - TMAP 118/1 - TMAP 36/3 - TMAP 14/7 - TMAP 35/8 - TMAP 94/2 - TMAP 39/2 - TMAP 33/1 - TMAP 116/12 - TMAP 95/3 - TMAP 36/11 - TMAP 130/1 - TMAP 95/8 - TMAP 32/1 - TMAP 2/2 - TMAP 112/1 - TMAP 54/2 - TMAP 100/2 - TMAP 75/1 - TMAP 56/3 - TMAP 94/4 - TMAP 12/1 - TMAP 1/3 - TMAP 116/16 - TMAP 95/2 - TMAP 12/3 - TMAP 73/1 - TMAP 54/4 - TMAP 152/1 - TMAP 74/5 - TMAP 18/1 - TMAP 96/4 - TMAP 56/16 - TMAP 72/2 - TMAP 116/3 - TMAP 116/10 - TMAP 15/2 - TMAP 36/7 - TMAP 96/8 - TMAP 95/1 - TMAP 96/11 - TMAP 12/2 - TMAP 35/5 - TMAP 55/7 - TMAP 34/6 TMAP 38/2 TMAP 95/7 TMAP 76/3 @@ -2614,27 +2552,6 @@ TMAP 15/5 TMAP 121/2 TMAP 77/2 - TMAP 79/1 - TMAP 116/5 - TMAP 96/12 - TMAP 94/1 - TMAP 35/3 - TMAP 116/1 - TMAP 1/4 - TMAP 97/1 - TMAP 15/4 - TMAP 115/1 - TMAP 56/6 - TMAP 78/3 - TMAP 36/5 - TMAP 56/4 - TMAP 116/15 - TMAP 74/3 - TMAP 14/6 - TMAP 153/3 - TMAP 54/1 - TMAP 76/2 - TMAP 156/1 TMAP 115/8 TMAP 96/9 TMAP 115/7 @@ -2669,6 +2586,27 @@ TMAP 1/5 TMAP 115/2 TMAP 115/6 + TMAP 57/2 + TMAP 19/1 + TMAP 96/16 + TMAP 116/9 + TMAP 96/2 + TMAP 75/3 + TMAP 10/1 + TMAP 153/1 + TMAP 17/7 + TMAP 94/6 + TMAP 71/1 + TMAP 14/8 + TMAP 151/1 + TMAP 115/4 + TMAP 74/7 + TMAP 130/4 + TMAP 131/1 + TMAP 154/1 + TMAP 118/1 + TMAP 36/3 + TMAP 14/7 TMAP 31/1 TMAP 34/4 TMAP 36/8 @@ -2678,6 +2616,74 @@ TMAP 121/1 TMAP 112/2 TMAP 55/1 + TMAP 56/16 + TMAP 72/2 + TMAP 116/3 + TMAP 116/10 + TMAP 15/2 + TMAP 36/7 + TMAP 96/8 + TMAP 95/1 + TMAP 96/11 + TMAP 12/2 + TMAP 35/5 + TMAP 55/7 + TMAP 34/6 + TMAP 79/1 + TMAP 116/5 + TMAP 96/12 + TMAP 94/1 + TMAP 35/3 + TMAP 116/1 + TMAP 1/4 + TMAP 97/1 + TMAP 15/4 + TMAP 115/1 + TMAP 56/6 + TMAP 78/3 + TMAP 36/5 + TMAP 56/4 + TMAP 116/15 + TMAP 74/3 + TMAP 14/6 + TMAP 153/3 + TMAP 54/1 + TMAP 76/2 + TMAP 156/1 + TMAP 20/1 + TMAP 18/2 + TMAP 56/14 + TMAP 36/6 + TMAP 1/1 + TMAP 115/3 + TMAP 54/5 + TMAP 1/8 + TMAP 116/11 + TMAP 70/1 + TMAP 36/10 + TMAP 130/3 + TMAP 34/2 + TMAP 93/1 + TMAP 34/3 + TMAP 96/13 + TMAP 114/1 + TMAP 75/4 + TMAP 17/1 + TMAP 77/1 + TMAP 32/2 + TMAP 53/1 + TMAP 120/1 + TMAP 13/1 + TMAP 130/2 + TMAP 55/6 + TMAP 75/5 + TMAP 96/10 + TMAP 35/6 + TMAP 116/8 + TMAP 98/1 + TMAP 153/2 + TMAP 92/1 + TMAP 111/1 TMAP 95/5 TMAP 114/4 TMAP 57/3 @@ -2687,13 +2693,6 @@ TMAP 55/3 TMAP 113/1 TMAP 98/3 - TMAP 56/11 - TMAP 94/3 - TMAP 75/6 - TMAP 36/12 - TMAP 74/4 - TMAP 2/2a - TMAP 151/2 TMAP 17/6 TMAP 115/5 TMAP 39/1 @@ -2720,55 +2719,6 @@ TMAP 35/4 TMAP 95/6 TMAP 74/6 - TMAP 20/1 - TMAP 18/2 - TMAP 56/14 - TMAP 36/6 - TMAP 1/1 - TMAP 115/3 - TMAP 54/5 - TMAP 1/8 - TMAP 116/11 - TMAP 70/1 - TMAP 36/10 - TMAP 130/3 - TMAP 34/2 - TMAP 93/1 - TMAP 34/3 - TMAP 96/13 - TMAP 114/1 - TMAP 75/4 - TMAP 17/1 - TMAP 77/1 - TMAP 32/2 - TMAP 53/1 - TMAP 120/1 - TMAP 13/1 - TMAP 130/2 - TMAP 55/6 - TMAP 75/5 - TMAP 96/10 - TMAP 35/6 - TMAP 116/8 - TMAP 98/1 - TMAP 153/2 - TMAP 92/1 - TMAP 111/1 - TMAP 96/3 - TMAP 114/3 - TMAP 16/2 - TMAP 116/14 - TMAP 56/15 - TMAP 40/2 - TMAP 92/2 - TMAP 99/1 - TMAP 17/4 - TMAP 36/14 - TMAP 56/2 - TMAP 74/1 - TMAP 151/5 - TMAP 151/4 - TMAP 94/5 TMAP 32/3 TMAP 96/15 TMAP 114/5 @@ -2789,6 +2739,21 @@ TMAP 36/9 TMAP 96/1 TMAP 11/1 + TMAP 96/3 + TMAP 114/3 + TMAP 16/2 + TMAP 116/14 + TMAP 56/15 + TMAP 40/2 + TMAP 92/2 + TMAP 99/1 + TMAP 17/4 + TMAP 36/14 + TMAP 56/2 + TMAP 74/1 + TMAP 151/5 + TMAP 151/4 + TMAP 94/5 TMAP 75/2 TMAP 36/1 TMAP 14/2 @@ -2803,23 +2768,45 @@ TMAP 56/8 TMAP 50/1 TMAP 14/4 + TMAP 35/8 + TMAP 94/2 + TMAP 39/2 + TMAP 33/1 + TMAP 116/12 + TMAP 95/3 + TMAP 36/11 + TMAP 130/1 + TMAP 95/8 + TMAP 32/1 + TMAP 2/2 + TMAP 112/1 + TMAP 54/2 + TMAP 100/2 + TMAP 75/1 + TMAP 56/3 + TMAP 94/4 + TMAP 12/1 + TMAP 1/3 + TMAP 116/16 + TMAP 95/2 + TMAP 12/3 + TMAP 73/1 + TMAP 54/4 + TMAP 152/1 + TMAP 74/5 + TMAP 18/1 + TMAP 96/4 + TMAP 56/11 + TMAP 94/3 + TMAP 75/6 + TMAP 36/12 + TMAP 74/4 + TMAP 2/2a + TMAP 151/2 - PBP 14a/1 - PBP 14/10 - PBP 12/1 - PBP 1/1 - PBP 14/12 - PBP 14/5 - PBP 17/2 - PBP 8/4 - PBP 13/3 - PBP 5/1 - PBP 15/1 - PBP 8/12 - PBP 4/2 PBP 8/10 PBP 11/2 PBP 17a/1 @@ -2829,12 +2816,6 @@ PBP 6/9 PBP 6/1 PBP 8/3 - PBP 7/4 - PBP 8/7 - PBP 1/3 - PBP 8/6 - PBP 14/6 - PBP 7/3 PBP 8/5 PBP 11/1 PBP 8/2 @@ -2848,12 +2829,19 @@ PBP 6/3 PBP 14/8 PBP 1/2 - PBP 8/9 - PBP 16/2 - PBP 12/2 - PBP 10/2 - PBP 14/11 - PBP 6/6 + PBP 14a/1 + PBP 14/10 + PBP 12/1 + PBP 1/1 + PBP 14/12 + PBP 14/5 + PBP 17/2 + PBP 7/4 + PBP 8/7 + PBP 1/3 + PBP 8/6 + PBP 14/6 + PBP 7/3 PBP 13/4 PBP 14/4 PBP 5/2 @@ -2862,6 +2850,12 @@ PBP 6/2 PBP 9/1 PBP 3/1 + PBP 8/9 + PBP 16/2 + PBP 12/2 + PBP 10/2 + PBP 14/11 + PBP 6/6 PBP 6/8 PBP 12/3 PBP 6/4 @@ -2870,38 +2864,133 @@ PBP 7/1 PBP 17/1 PBP 14/7 + PBP 8/4 + PBP 13/3 + PBP 5/1 + PBP 15/1 + PBP 8/12 + PBP 4/2 - MBT 20/2 + MBT 20/1 + MBT 3/2 MBT 0/1 MBT 10/1 MBT 10/2 MBT 3/1 - MBT 20/1 - MBT 3/2 + MBT 20/2 - DFU 22/3 - DFU 30/1 DFU 10/1 DFU 3/1 DFU 21/1 + DFU 22/3 + DFU 30/1 DFU 22/1 DFU 3/2 + DFU 11/2 + DFU 21/2 DFU 3/3 DFU 11/1 DFU 0/1 DFU 20/1 - DFU 11/2 - DFU 21/2 + GMAP 32/3 + GMAP 20/85 + GMAP 107/2 + GMAP 57/3 + GMAP 40/3 + GMAP 20/43 + GMAP 92/1 + GMAP 20/56 + GMAP 56/2 + GMAP 41/1 + GMAP 38/2 + GMAP 79/14 + GMAP 20/110 + GMAP 101/1 + GMAP 40/1 + GMAP 14/7 + GMAP 14/4 + GMAP 20/82 + GMAP 20/24 + GMAP 32/2 + GMAP 34/3 + GMAP 20/90 + GMAP 20/71 + GMAP 20/41 + GMAP 92/5 + GMAP 40/23 + GMAP 76/2 + GMAP 20/11 + GMAP 102/4 + GMAP 18/2 + GMAP 40/44 + GMAP 40/12 + GMAP 1/2 + GMAP 20/54 + GMAP 40/17 + GMAP 20/42 + GMAP 40/15 + GMAP 79/16 + GMAP 40/38 + GMAP 20/40 + GMAP 36/2 + GMAP 75/1 + GMAP 59/8 + GMAP 40/7 + GMAP 20/73 + GMAP 40/32 + GMAP 18/6 + GMAP 56/4 + GMAP 93/4 + GMAP 103/4 + GMAP 20/63 + GMAP 20/80 + GMAP 16/2 + GMAP 40/62 + GMAP 11/1 + GMAP 40/42 + GMAP 20/1 + GMAP 78/2 + GMAP 35/12 + GMAP 14/12 + GMAP 37/1 + GMAP 40/68 + GMAP 40/51 + GMAP 102/2 + GMAP 59/2 + GMAP 1/6 + GMAP 18/4 + GMAP 1/1 + GMAP 40/24 + GMAP 18/5 + GMAP 40/59 + GMAP 59/7 + GMAP 20/58 + GMAP 17/4 + GMAP 72/2 + GMAP 102/5 + GMAP 40/16 + GMAP 57/2 + GMAP 40/53 + GMAP 40/40 + GMAP 20/35 + GMAP 20/49 + GMAP 32/6 + GMAP 20/101 + GMAP 40/64 + GMAP 40/45 + GMAP 20/99 + GMAP 108/1 + GMAP 36/4 GMAP 20/92 GMAP 20/19 GMAP 20/95 @@ -2924,22 +3013,6 @@ GMAP 40/49 GMAP 40/69 GMAP 39/1 - GMAP 32/3 - GMAP 20/85 - GMAP 107/2 - GMAP 57/3 - GMAP 40/3 - GMAP 20/43 - GMAP 92/1 - GMAP 20/56 - GMAP 56/2 - GMAP 41/1 - GMAP 38/2 - GMAP 79/14 - GMAP 20/110 - GMAP 101/1 - GMAP 40/1 - GMAP 14/7 GMAP 79/2 GMAP 38/5 GMAP 58/2 @@ -2977,89 +3050,6 @@ GMAP 57/4 GMAP 59/10 GMAP 20/21 - GMAP 20/63 - GMAP 20/80 - GMAP 16/2 - GMAP 40/62 - GMAP 11/1 - GMAP 40/42 - GMAP 20/1 - GMAP 78/2 - GMAP 35/12 - GMAP 14/12 - GMAP 37/1 - GMAP 40/68 - GMAP 40/51 - GMAP 102/2 - GMAP 59/2 - GMAP 1/6 - GMAP 18/4 - GMAP 1/1 - GMAP 40/24 - GMAP 18/5 - GMAP 40/59 - GMAP 59/7 - GMAP 20/58 - GMAP 17/4 - GMAP 72/2 - GMAP 102/5 - GMAP 40/16 - GMAP 57/2 - GMAP 40/53 - GMAP 40/40 - GMAP 20/35 - GMAP 20/49 - GMAP 32/6 - GMAP 20/101 - GMAP 40/64 - GMAP 40/45 - GMAP 20/99 - GMAP 108/1 - GMAP 36/4 - GMAP 20/32 - GMAP 34/5 - GMAP 90/1 - GMAP 32/1 - GMAP 105/3 - GMAP 103/3 - GMAP 100/1 - GMAP 20/5 - GMAP 93/6 - GMAP 40/22 - GMAP 1/3 - GMAP 77/3 - GMAP 70/1 - GMAP 20/62 - GMAP 20/28 - GMAP 56/3 - GMAP 54/4 - GMAP 78/3 - GMAP 20/108 - GMAP 57/1 - GMAP 20/20 - GMAP 81/1 - GMAP 12/1 - GMAP 17/6 - GMAP 20/51 - GMAP 21/2 - GMAP 60/2 - GMAP 40/54 - GMAP 79/15 - GMAP 73/1 - GMAP 36/6 - GMAP 92/2 - GMAP 20/74 - GMAP 34/1 - GMAP 79/11 - GMAP 17/1 - GMAP 20/70 - GMAP 40/2 - GMAP 20/81 - GMAP 55/1 - GMAP 19/3 - GMAP 40/29 - GMAP 40/56 - GMAP 79/1 GMAP 102/1 GMAP 77/1 GMAP 20/59 @@ -3070,80 +3060,46 @@ GMAP 14/11 GMAP 40/70 GMAP 104/1 - GMAP 20/105 - GMAP 40/61 - GMAP 54/1 - GMAP 82/1 - GMAP 20/60 - GMAP 40/66 - GMAP 40/31 - GMAP 20/87 - GMAP 16/1 - GMAP 20/76 - GMAP 71/1 - GMAP 110/1 - GMAP 15/1 - GMAP 76/3 - GMAP 40/30 - GMAP 20/68 - GMAP 20/86 - GMAP 21/1 - GMAP 20/8 - GMAP 74/3 - GMAP 40/11 - GMAP 36/3 - GMAP 104/3 - GMAP 20/83 - GMAP 17/5 - GMAP 107/1 - GMAP 20/53 - GMAP 20/104 - GMAP 37/3 - GMAP 40/37 - GMAP 20/69 - GMAP 40/48 - GMAP 40/28 - GMAP 20/44 - GMAP 34/2 - GMAP 38/4 - GMAP 40/9 - GMAP 40/10 - GMAP 20/34 - GMAP 20/2 - GMAP 20/106 - GMAP 35/3 - GMAP 20/112 - GMAP 20/113 - GMAP 79/5 - GMAP 52/1 - GMAP 102/3 - GMAP 20/6 - GMAP 22/1 - GMAP 16/4 - GMAP 20/100 - GMAP 50/1 - GMAP 40/41 - GMAP 20/3 - GMAP 20/23 - GMAP 17/3 - GMAP 20/18 - GMAP 79/7 - GMAP 35/11 - GMAP 20/65 - GMAP 75/2 - GMAP 38/1 - GMAP 94/1 - GMAP 92/4 - GMAP 40/60 - GMAP 105/2 - GMAP 103/2 - GMAP 17/2 - GMAP 20/107 - GMAP 20/77 - GMAP 74/2 - GMAP 20/37 - GMAP 18/1 - GMAP 79/10 + GMAP 40/19 + GMAP 40/39 + GMAP 20/84 + GMAP 93/2 + GMAP 40/6 + GMAP 20/15 + GMAP 59/6 + GMAP 20/88 + GMAP 20/22 + GMAP 76/4 + GMAP 59/11 + GMAP 20/16 + GMAP 20/78 + GMAP 35/2 + GMAP 34/4 + GMAP 111/1 + GMAP 20/64 + GMAP 20/57 + GMAP 20/111 + GMAP 31/1 + GMAP 59/5 + GMAP 38/6 + GMAP 105/7 + GMAP 20/31 + GMAP 20/103 + GMAP 14/1 + GMAP 59/9 + GMAP 14/6 + GMAP 12/3 + GMAP 35/1 + GMAP 79/8 + GMAP 20/79 + GMAP 107/1 + GMAP 20/53 + GMAP 20/104 + GMAP 37/3 + GMAP 40/37 + GMAP 20/69 + GMAP 40/48 + GMAP 40/28 GMAP 40/65 GMAP 59/1 GMAP 40/50 @@ -3180,6 +3136,31 @@ GMAP 20/94 GMAP 20/93 GMAP 59/3 + GMAP 20/105 + GMAP 40/61 + GMAP 54/1 + GMAP 82/1 + GMAP 20/60 + GMAP 40/66 + GMAP 40/31 + GMAP 20/87 + GMAP 16/1 + GMAP 20/76 + GMAP 71/1 + GMAP 110/1 + GMAP 15/1 + GMAP 76/3 + GMAP 40/30 + GMAP 20/68 + GMAP 20/86 + GMAP 21/1 + GMAP 20/8 + GMAP 74/3 + GMAP 40/11 + GMAP 36/3 + GMAP 104/3 + GMAP 20/83 + GMAP 17/5 GMAP 20/33 GMAP 20/29 GMAP 79/6 @@ -3238,129 +3219,148 @@ GMAP 92/3 GMAP 91/1 GMAP 20/72 - GMAP 14/4 - GMAP 20/82 - GMAP 20/24 - GMAP 32/2 - GMAP 34/3 - GMAP 20/90 - GMAP 20/71 - GMAP 20/41 - GMAP 92/5 - GMAP 40/23 - GMAP 76/2 - GMAP 20/11 - GMAP 102/4 - GMAP 18/2 - GMAP 40/44 - GMAP 40/12 - GMAP 1/2 - GMAP 20/54 - GMAP 40/17 - GMAP 20/42 - GMAP 40/15 - GMAP 79/16 - GMAP 40/38 - GMAP 20/40 - GMAP 36/2 - GMAP 75/1 - GMAP 59/8 - GMAP 40/7 - GMAP 20/73 - GMAP 40/32 - GMAP 18/6 - GMAP 56/4 - GMAP 93/4 - GMAP 103/4 - GMAP 40/19 - GMAP 40/39 - GMAP 20/84 - GMAP 93/2 - GMAP 40/6 - GMAP 20/15 - GMAP 59/6 - GMAP 20/88 - GMAP 20/22 - GMAP 76/4 - GMAP 59/11 - GMAP 20/16 - GMAP 20/78 - GMAP 35/2 - GMAP 34/4 - GMAP 111/1 - GMAP 20/64 - GMAP 20/57 - GMAP 20/111 - GMAP 31/1 - GMAP 59/5 - GMAP 38/6 - GMAP 105/7 - GMAP 20/31 - GMAP 20/103 - GMAP 14/1 - GMAP 59/9 - GMAP 14/6 - GMAP 12/3 - GMAP 35/1 - GMAP 79/8 - GMAP 20/79 + GMAP 20/44 + GMAP 34/2 + GMAP 38/4 + GMAP 40/9 + GMAP 40/10 + GMAP 20/34 + GMAP 20/2 + GMAP 20/106 + GMAP 35/3 + GMAP 20/112 + GMAP 20/113 + GMAP 79/5 + GMAP 52/1 + GMAP 102/3 + GMAP 20/6 + GMAP 22/1 + GMAP 16/4 + GMAP 20/100 + GMAP 50/1 + GMAP 40/41 + GMAP 20/3 + GMAP 20/23 + GMAP 17/3 + GMAP 20/18 + GMAP 79/7 + GMAP 35/11 + GMAP 20/65 + GMAP 75/2 + GMAP 38/1 + GMAP 94/1 + GMAP 92/4 + GMAP 40/60 + GMAP 105/2 + GMAP 103/2 + GMAP 17/2 + GMAP 20/107 + GMAP 20/77 + GMAP 74/2 + GMAP 20/37 + GMAP 18/1 + GMAP 79/10 + GMAP 20/32 + GMAP 34/5 + GMAP 90/1 + GMAP 32/1 + GMAP 105/3 + GMAP 103/3 + GMAP 100/1 + GMAP 20/5 + GMAP 93/6 + GMAP 40/22 + GMAP 1/3 + GMAP 77/3 + GMAP 70/1 + GMAP 20/62 + GMAP 20/28 + GMAP 56/3 + GMAP 54/4 + GMAP 78/3 + GMAP 20/108 + GMAP 57/1 + GMAP 20/20 + GMAP 81/1 + GMAP 12/1 + GMAP 17/6 + GMAP 20/51 + GMAP 21/2 + GMAP 60/2 + GMAP 40/54 + GMAP 79/15 + GMAP 73/1 + GMAP 36/6 + GMAP 92/2 + GMAP 20/74 + GMAP 34/1 + GMAP 79/11 + GMAP 17/1 + GMAP 20/70 + GMAP 40/2 + GMAP 20/81 + GMAP 55/1 + GMAP 19/3 + GMAP 40/29 + GMAP 40/56 + GMAP 79/1 - CORE 2a/54 - CORE 2a/51 - CORE 41/2 - CORE 11/5 - CORE 2a/52 - CORE 2b/61 - CORE 12/3 CORE 40/2 CORE 11/3 CORE 11/6 CORE 20a/1 - CORE 2b/60 + CORE 2a/62 CORE 20/4 CORE 2a/50 + CORE 2a/54 + CORE 2a/51 + CORE 41/2 + CORE 11/5 + CORE 2a/52 + CORE 12/3 + CORE 2/62 CORE 2b/62 - CORE 2/60 - CORE 2/1 + CORE 2a/53 + CORE 2a/61 + CORE 31/2 CORE 11/2 CORE 11/1 CORE 2a/60 CORE 12/1 - CORE 2a/53 - CORE 31/2 + CORE 2/1 - UHCI 0/60 + UHCI 0/62 - IOPT 2/63b - IOPT 2/19b - IOPT 2/28b + IOPT 2/30b + IOPT 2/55b + IOPT 2/2b + IOPT 2/45b + IOPT 2/42b + IOPT 2/12b + IOPT 2/16b + IOPT 2/33b IOPT 2/7b IOPT 2/59b IOPT 2/5b IOPT 2/53b - IOPT 2/2b + IOPT 2/58b IOPT 2/6b IOPT 2a/2 IOPT 2/29b IOPT 2/44b IOPT 2/35b - IOPT 2/45b - IOPT 2/42b - IOPT 2/12b - IOPT 2/16b - IOPT 2/33b - IOPT 2/58b - IOPT 2/30b - IOPT 2/55b + IOPT 2/63b + IOPT 2/19b + IOPT 2/28b diff --git a/tests/bluetooth/qualification/ICS_Zephyr_Bluetooth_Host.pts b/tests/bluetooth/qualification/ICS_Zephyr_Bluetooth_Host.pts index 192555599d24..8f486ffc243f 100644 --- a/tests/bluetooth/qualification/ICS_Zephyr_Bluetooth_Host.pts +++ b/tests/bluetooth/qualification/ICS_Zephyr_Bluetooth_Host.pts @@ -12715,10 +12715,6 @@ CORE - - 2b
    - 61 -
    12
    3 @@ -12727,6 +12723,10 @@ 2a
    53
    + + 2a
    + 61 +
    40
    2 @@ -12735,18 +12735,10 @@ 11
    6
    - - 2
    - 60 -
    20a
    1
    - - 2b
    - 60 -
    11
    2 @@ -12767,6 +12759,10 @@ 31
    2
    + + 2
    + 62 +
    41
    2 @@ -12779,6 +12775,10 @@ 2
    1
    + + 2a
    + 62 +
    20
    4 @@ -12812,7 +12812,7 @@ UHCI 0
    - 60 + 62
    From 55e6102ac2113871afb2cee80f8a5acdf7a03f54 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Sun, 11 Jan 2026 01:51:06 +0530 Subject: [PATCH 2212/3659] mainfest: nrf_wifi: Pull fix for raw TX header alignment Align the raw TX header to 4bytes and make it packed. Signed-off-by: Chaitanya Tata --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index e70bf2db431b..acfd4a9b1bf3 100644 --- a/west.yml +++ b/west.yml @@ -347,7 +347,7 @@ manifest: revision: 4d11a73d62bf999205f16de21a0ef675501f5b21 path: modules/bsim_hw_models/nrf_hw_models - name: nrf_wifi - revision: eaf223da0c3f987caa1156cbed54b513bee4ba37 + revision: 29afb11a512787bc68e2afd58c9dfde4bb4d5dc4 path: modules/lib/nrf_wifi - name: open-amp revision: 5efe7974f9546582e99f5a842a816ea4b65f5227 From 23ba648b8216c4acaab04555d56b5066de3879a3 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Tue, 9 Dec 2025 13:33:59 +0530 Subject: [PATCH 2213/3659] net: lib: zperf: Add raw socket upload support This helps in benchamrking raw socket (packet socket) performance in the lines of UDP/TCP. Signed-off-by: Chaitanya Tata --- include/zephyr/net/zperf.h | 55 +++++ subsys/net/lib/zperf/CMakeLists.txt | 1 + subsys/net/lib/zperf/Kconfig | 15 ++ subsys/net/lib/zperf/zperf_common.c | 11 +- subsys/net/lib/zperf/zperf_internal.h | 2 + subsys/net/lib/zperf/zperf_raw_uploader.c | 265 ++++++++++++++++++++++ subsys/net/lib/zperf/zperf_shell.c | 245 ++++++++++++++++++++ 7 files changed, 593 insertions(+), 1 deletion(-) create mode 100644 subsys/net/lib/zperf/zperf_raw_uploader.c diff --git a/include/zephyr/net/zperf.h b/include/zephyr/net/zperf.h index 3cf7dee56401..6ce9a2f73260 100644 --- a/include/zephyr/net/zperf.h +++ b/include/zephyr/net/zperf.h @@ -76,6 +76,32 @@ struct zperf_download_params { char if_name[NET_IFNAMSIZ]; }; +#ifdef CONFIG_NET_ZPERF_RAW_TX +/** + * Raw TX upload parameters + * + * Buffer structure sent to driver: + * [User-provided header] + [Payload 'z'] + * + * The user provides everything as a single header blob (vendor metadata, + * frame header like 802.11/Ethernet, etc.). Zperf appends 'z' payload + * bytes to reach the desired packet_size. This is generic and works + * with any frame format. + * + * Header bytes are transmitted exactly as provided - no byte order conversion + * is performed. Users must provide bytes in the format expected by their + * target driver/hardware. + */ +struct zperf_raw_upload_params { + uint32_t duration_ms; /**< Duration of the test in milliseconds */ + uint32_t rate_kbps; /**< Target rate in kilobits per second */ + uint16_t packet_size; /**< Total packet size (header + payload) */ + uint8_t *hdr; /**< Header bytes (vendor metadata + frame hdr) */ + uint16_t hdr_len; /**< Length of header in bytes */ + int if_index; /**< Network interface index */ +}; +#endif /* CONFIG_NET_ZPERF_RAW_TX */ + /** @endcond */ /** Performance results */ @@ -200,6 +226,35 @@ int zperf_udp_download_stop(void); */ int zperf_tcp_download_stop(void); +#ifdef CONFIG_NET_ZPERF_RAW_TX +/** + * @brief Synchronous raw packet TX upload operation. The function blocks until + * the upload is complete. + * + * @param param Upload parameters including custom header and destination MAC. + * @param result Session results. + * + * @return 0 if session completed successfully, a negative error code otherwise. + */ +int zperf_raw_upload(const struct zperf_raw_upload_params *param, + struct zperf_results *result); + +/** + * @brief Asynchronous raw packet TX upload operation. + * + * @note Only one asynchronous raw TX upload can be performed at a time. + * + * @param param Upload parameters including custom header and destination MAC. + * @param callback Session results callback. + * @param user_data A pointer to the user data to be provided with the callback. + * + * @return 0 if session was scheduled successfully, a negative error code + * otherwise. + */ +int zperf_raw_upload_async(const struct zperf_raw_upload_params *param, + zperf_callback callback, void *user_data); +#endif /* CONFIG_NET_ZPERF_RAW_TX */ + #ifdef __cplusplus } #endif diff --git a/subsys/net/lib/zperf/CMakeLists.txt b/subsys/net/lib/zperf/CMakeLists.txt index f265c0389e14..81429dcb8862 100644 --- a/subsys/net/lib/zperf/CMakeLists.txt +++ b/subsys/net/lib/zperf/CMakeLists.txt @@ -5,6 +5,7 @@ zephyr_library_named(zperf) zephyr_library_sources(zperf_common.c) zephyr_library_sources_ifdef(CONFIG_NET_UDP zperf_udp_uploader.c) zephyr_library_sources_ifdef(CONFIG_NET_TCP zperf_tcp_uploader.c) +zephyr_library_sources_ifdef(CONFIG_NET_ZPERF_RAW_TX zperf_raw_uploader.c) if(CONFIG_NET_ZPERF_SERVER) zephyr_library_sources(zperf_session.c) diff --git a/subsys/net/lib/zperf/Kconfig b/subsys/net/lib/zperf/Kconfig index dcf4572b4262..e2f415e501be 100644 --- a/subsys/net/lib/zperf/Kconfig +++ b/subsys/net/lib/zperf/Kconfig @@ -81,5 +81,20 @@ config NET_ZPERF_UDP_REPORT_RETANSMISSION_COUNT report from the server. `0` means the report will not be requested at all, which is useful for testing purposes. +config NET_ZPERF_RAW_TX + bool "Raw packet TX support" + depends on NET_SOCKETS_PACKET + help + Enable raw packet socket TX support in zperf. This allows sending + custom raw packets with user-defined headers for performance testing. + Useful for testing vendor-specific protocols or custom L2 frames. + +config NET_ZPERF_RAW_TX_MAX_HDR_SIZE + int "Maximum raw TX header size" + depends on NET_ZPERF_RAW_TX + default 64 + help + Maximum size of the custom header that can be prepended to raw TX + packets. The header is provided as hex bytes by the user. endif diff --git a/subsys/net/lib/zperf/zperf_common.c b/subsys/net/lib/zperf/zperf_common.c index 86e19ec761cf..70763e4274a3 100644 --- a/subsys/net/lib/zperf/zperf_common.c +++ b/subsys/net/lib/zperf/zperf_common.c @@ -281,7 +281,13 @@ uint32_t zperf_packet_duration(uint32_t packet_size, uint32_t rate_in_kbps) void zperf_async_work_submit(enum session_proto proto, int session_id, struct k_work *work) { #if defined(CONFIG_ZPERF_SESSION_PER_THREAD) - k_work_submit_to_queue(zperf_work_q[proto * SESSION_INDEX + session_id].queue, work); + /* Raw TX doesn't support per-thread sessions, use first available queue */ + if (proto == SESSION_RAW || session_id < 0) { + k_work_submit_to_queue(zperf_work_q[0].queue, work); + } else { + k_work_submit_to_queue(zperf_work_q[proto * SESSION_INDEX + session_id].queue, + work); + } #else ARG_UNUSED(proto); ARG_UNUSED(session_id); @@ -333,6 +339,9 @@ static int zperf_init(void) if (IS_ENABLED(CONFIG_NET_TCP)) { zperf_tcp_uploader_init(); } + if (IS_ENABLED(CONFIG_NET_ZPERF_RAW_TX)) { + zperf_raw_uploader_init(); + } if (IS_ENABLED(CONFIG_NET_ZPERF_SERVER) || IS_ENABLED(CONFIG_ZPERF_SESSION_PER_THREAD)) { diff --git a/subsys/net/lib/zperf/zperf_internal.h b/subsys/net/lib/zperf/zperf_internal.h index 843c5eef1380..420c698c20cc 100644 --- a/subsys/net/lib/zperf/zperf_internal.h +++ b/subsys/net/lib/zperf/zperf_internal.h @@ -56,6 +56,7 @@ enum session_proto { SESSION_UDP = 0, SESSION_TCP = 1, + SESSION_RAW = 2, SESSION_PROTO_END }; @@ -136,6 +137,7 @@ uint32_t zperf_packet_duration(uint32_t packet_size, uint32_t rate_in_kbps); void zperf_async_work_submit(enum session_proto proto, int session_id, struct k_work *work); void zperf_udp_uploader_init(void); void zperf_tcp_uploader_init(void); +void zperf_raw_uploader_init(void); void zperf_shell_init(void); diff --git a/subsys/net/lib/zperf/zperf_raw_uploader.c b/subsys/net/lib/zperf/zperf_raw_uploader.c new file mode 100644 index 000000000000..4eb45fd75e6a --- /dev/null +++ b/subsys/net/lib/zperf/zperf_raw_uploader.c @@ -0,0 +1,265 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +LOG_MODULE_DECLARE(net_zperf, CONFIG_NET_ZPERF_LOG_LEVEL); + +#include +#include +#include +#include + +#include "zperf_internal.h" + +#if defined(CONFIG_NET_ZPERF_RAW_TX) + +/* Buffer for raw packet: user-provided header + payload */ +static uint8_t raw_packet_buffer[PACKET_SIZE_MAX]; + +struct zperf_raw_async_upload_context { + struct k_work work; + struct zperf_raw_upload_params param; + uint8_t hdr_storage[CONFIG_NET_ZPERF_RAW_TX_MAX_HDR_SIZE]; + zperf_callback callback; + void *user_data; +}; + +static struct zperf_raw_async_upload_context raw_async_upload_ctx; + +/** + * @brief Internal raw packet TX upload implementation + * + * Buffer structure for raw TX: + * [User-provided header] + [Payload 'z'] + * + * The user provides everything (vendor metadata + frame header) as a single + * blob. Zperf appends 'z' payload bytes to reach the desired packet_size. + * This is generic and works with any frame format (802.11, Ethernet, etc.). + * + * @param param Upload parameters + * @param results Pointer to store results + * + * @return 0 on success, negative errno on failure + */ +static int raw_upload(const struct zperf_raw_upload_params *param, + struct zperf_results *results) +{ + uint32_t duration_in_ms = param->duration_ms; + uint32_t packet_size = param->packet_size; + uint32_t rate_in_kbps = param->rate_kbps; + uint32_t packet_duration_us; + uint32_t packet_duration; + uint32_t delay; + uint32_t nb_packets = 0U; + int64_t start_time, end_time; + int64_t last_loop_time; + int raw_sock; + struct net_sockaddr_ll raw_addr; + ssize_t sent_bytes; + int ret; + + if (packet_size > PACKET_SIZE_MAX) { + NET_WARN("Packet size too large! max size: %u", PACKET_SIZE_MAX); + packet_size = PACKET_SIZE_MAX; + } + + if (packet_size < param->hdr_len) { + NET_ERR("Packet size (%u) must be >= header length (%u)", + packet_size, param->hdr_len); + return -EINVAL; + } + + /* Rate limiting based on total packet size */ + packet_duration_us = zperf_packet_duration(packet_size, rate_in_kbps); + packet_duration = k_us_to_ticks_ceil32(packet_duration_us); + delay = packet_duration; + + /* Create raw packet socket (proto=0 for TX only) */ + raw_sock = zsock_socket(NET_AF_PACKET, NET_SOCK_RAW, 0); + if (raw_sock < 0) { + NET_ERR("Cannot create raw socket (%d)", errno); + return -errno; + } + + /* Set up net_sockaddr_ll structure */ + memset(&raw_addr, 0, sizeof(raw_addr)); + raw_addr.sll_family = NET_AF_PACKET; + raw_addr.sll_ifindex = param->if_index; + + /* Bind to the interface */ + ret = zsock_bind(raw_sock, (struct net_sockaddr *)&raw_addr, sizeof(raw_addr)); + if (ret < 0) { + NET_ERR("Failed to bind raw socket (%d)", errno); + zsock_close(raw_sock); + return -errno; + } + + /* + * Build buffer: [User-provided header] + [Payload 'z'] + * User provides everything (vendor metadata + frame header). + * We just append 'z' payload to reach packet_size. + */ + memset(raw_packet_buffer, 'z', packet_size); + + /* Copy user-provided header (vendor metadata + frame header) */ + if (param->hdr && param->hdr_len > 0) { + memcpy(raw_packet_buffer, param->hdr, param->hdr_len); + } + + /* Rest is already filled with 'z' from memset above */ + + /* Start the transmission loop */ + start_time = k_uptime_ticks(); + last_loop_time = start_time; + end_time = start_time + k_ms_to_ticks_ceil64(duration_in_ms); + + do { + int64_t loop_time; + int32_t adjust; + + /* Timestamp */ + loop_time = k_uptime_ticks(); + + /* Algorithm to maintain a given baud rate */ + if (last_loop_time != loop_time) { + adjust = packet_duration; + adjust -= (int32_t)(loop_time - last_loop_time); + } else { + adjust = 0; + } + + if ((adjust >= 0) || (-adjust < (int32_t)delay)) { + delay += adjust; + } else { + delay = 0U; + } + + last_loop_time = loop_time; + + /* Send the raw packet */ + sent_bytes = zsock_sendto(raw_sock, raw_packet_buffer, packet_size, 0, + (struct net_sockaddr *)&raw_addr, sizeof(raw_addr)); + + if (sent_bytes < 0) { + NET_DBG("Failed to send raw packet (%d)", errno); + results->nb_packets_errors++; + } else { + nb_packets++; + } + + /* Wait to maintain rate */ +#if defined(CONFIG_ARCH_POSIX) + k_busy_wait(USEC_PER_MSEC); +#else + if (delay > 0) { + k_sleep(K_TICKS(delay)); + } +#endif + } while (last_loop_time < end_time); + + end_time = k_uptime_ticks(); + + zsock_close(raw_sock); + + /* Fill in results */ + results->nb_packets_sent = nb_packets; + results->client_time_in_us = k_ticks_to_us_ceil64(end_time - start_time); + results->packet_size = packet_size; + results->nb_packets_rcvd = 0; /* TX only, no RX stats */ + results->nb_packets_lost = 0; + results->nb_packets_outorder = 0; + results->total_len = (uint64_t)nb_packets * packet_size; + results->time_in_us = results->client_time_in_us; + results->jitter_in_us = 0; + results->is_multicast = false; + + return 0; +} + +int zperf_raw_upload(const struct zperf_raw_upload_params *param, + struct zperf_results *result) +{ + if (param == NULL || result == NULL) { + return -EINVAL; + } + + if (param->if_index <= 0) { + NET_ERR("Invalid interface index"); + return -EINVAL; + } + + if (param->hdr_len > CONFIG_NET_ZPERF_RAW_TX_MAX_HDR_SIZE) { + NET_ERR("Header length exceeds maximum (%d > %d)", + param->hdr_len, CONFIG_NET_ZPERF_RAW_TX_MAX_HDR_SIZE); + return -EINVAL; + } + + memset(result, 0, sizeof(*result)); + + return raw_upload(param, result); +} + +static void raw_upload_async_work(struct k_work *work) +{ + struct zperf_raw_async_upload_context *upload_ctx = + CONTAINER_OF(work, struct zperf_raw_async_upload_context, work); + struct zperf_results result = { 0 }; + int ret; + + upload_ctx->callback(ZPERF_SESSION_STARTED, NULL, upload_ctx->user_data); + + ret = raw_upload(&upload_ctx->param, &result); + if (ret < 0) { + upload_ctx->callback(ZPERF_SESSION_ERROR, NULL, upload_ctx->user_data); + } else { + upload_ctx->callback(ZPERF_SESSION_FINISHED, &result, upload_ctx->user_data); + } +} + +int zperf_raw_upload_async(const struct zperf_raw_upload_params *param, + zperf_callback callback, void *user_data) +{ + if (param == NULL || callback == NULL) { + return -EINVAL; + } + + if (param->if_index <= 0) { + NET_ERR("Invalid interface index"); + return -EINVAL; + } + + if (param->hdr_len > CONFIG_NET_ZPERF_RAW_TX_MAX_HDR_SIZE) { + NET_ERR("Header length exceeds maximum (%d > %d)", + param->hdr_len, CONFIG_NET_ZPERF_RAW_TX_MAX_HDR_SIZE); + return -EINVAL; + } + + if (k_work_is_pending(&raw_async_upload_ctx.work)) { + return -EBUSY; + } + + memcpy(&raw_async_upload_ctx.param, param, sizeof(*param)); + + /* Store metadata in local buffer since caller's buffer may go out of scope */ + if (param->hdr && param->hdr_len > 0) { + memcpy(raw_async_upload_ctx.hdr_storage, param->hdr, param->hdr_len); + raw_async_upload_ctx.param.hdr = raw_async_upload_ctx.hdr_storage; + } + + raw_async_upload_ctx.callback = callback; + raw_async_upload_ctx.user_data = user_data; + + zperf_async_work_submit(SESSION_RAW, -1, &raw_async_upload_ctx.work); + + return 0; +} + +void zperf_raw_uploader_init(void) +{ + k_work_init(&raw_async_upload_ctx.work, raw_upload_async_work); +} + +#endif /* CONFIG_NET_ZPERF_RAW_TX */ diff --git a/subsys/net/lib/zperf/zperf_shell.c b/subsys/net/lib/zperf/zperf_shell.c index 0452ada18cb2..f8ae82b491fb 100644 --- a/subsys/net/lib/zperf/zperf_shell.c +++ b/subsys/net/lib/zperf/zperf_shell.c @@ -18,6 +18,8 @@ LOG_MODULE_DECLARE(net_zperf, CONFIG_NET_ZPERF_LOG_LEVEL); #include #include #include +#include +#include #include #include @@ -2063,6 +2065,244 @@ SHELL_STATIC_SUBCMD_SET_CREATE(zperf_cmd_jobs, SHELL_CMD(start, NULL, "Start waiting jobs", cmd_jobs_start), ); +#ifdef CONFIG_NET_ZPERF_RAW_TX +/** + * Parse hex string to byte array + * Returns number of bytes parsed, or negative error + */ +static int parse_hex_bytes(const char *hex_str, uint8_t *buf, size_t buf_size) +{ + size_t hex_len = strlen(hex_str); + size_t byte_len; + size_t i; + + if ((hex_len % 2) != 0) { + return -EINVAL; + } + + byte_len = hex_len / 2; + if (byte_len > buf_size) { + return -ENOMEM; + } + + for (i = 0; i < byte_len; i++) { + char hex_byte[3] = { hex_str[i * 2], hex_str[i * 2 + 1], '\0' }; + char *endptr; + long val; + + val = strtol(hex_byte, &endptr, 16); + if (*endptr != '\0' || val < 0 || val > 255) { + return -EINVAL; + } + buf[i] = (uint8_t)val; + } + + return byte_len; +} + +static void shell_raw_upload_print_stats(const struct shell *sh, + struct zperf_results *results) +{ + uint64_t client_rate_in_kbps; + + shell_fprintf(sh, SHELL_NORMAL, "-\nRaw TX upload completed!\n"); + + if (results->client_time_in_us != 0U) { + client_rate_in_kbps = (uint32_t) + (((uint64_t)results->nb_packets_sent * + (uint64_t)results->packet_size * (uint64_t)8 * + (uint64_t)USEC_PER_SEC) / + (results->client_time_in_us * 1000U)); + } else { + client_rate_in_kbps = 0U; + } + + shell_fprintf(sh, SHELL_NORMAL, "Duration:\t\t"); + print_number_64(sh, results->client_time_in_us, TIME_US, TIME_US_UNIT); + shell_fprintf(sh, SHELL_NORMAL, "\n"); + shell_fprintf(sh, SHELL_NORMAL, "Num packets:\t\t%u\n", results->nb_packets_sent); + shell_fprintf(sh, SHELL_NORMAL, "Num errors:\t\t%u\n", results->nb_packets_errors); + shell_fprintf(sh, SHELL_NORMAL, "Total bytes:\t\t"); + print_number_64(sh, results->total_len, K, K_UNIT); + shell_fprintf(sh, SHELL_NORMAL, "\n"); + shell_fprintf(sh, SHELL_NORMAL, "Rate:\t\t\t"); + print_number(sh, client_rate_in_kbps, KBPS, KBPS_UNIT); + shell_fprintf(sh, SHELL_NORMAL, "\n"); +} + +static void raw_upload_cb(enum zperf_status status, + struct zperf_results *result, + void *user_data) +{ + const struct shell *sh = user_data; + + switch (status) { + case ZPERF_SESSION_STARTED: + shell_fprintf(sh, SHELL_NORMAL, "Raw TX upload started\n"); + break; + + case ZPERF_SESSION_FINISHED: + shell_raw_upload_print_stats(sh, result); + break; + + case ZPERF_SESSION_ERROR: + shell_fprintf(sh, SHELL_ERROR, "Raw TX upload failed\n"); + break; + + default: + break; + } +} + +static int cmd_raw_upload(const struct shell *sh, size_t argc, char *argv[]) +{ + struct zperf_raw_upload_params param = { 0 }; + struct zperf_results results = { 0 }; + static uint8_t hdr_buf[CONFIG_NET_ZPERF_RAW_TX_MAX_HDR_SIZE]; + bool async = false; + size_t opt_cnt = 0; + int start = 0; + int ret; + + /* Parse options */ + for (size_t i = 1; i < argc; ++i) { + if (*argv[i] != '-') { + break; + } + + switch (argv[i][1]) { + case 'a': + async = true; + opt_cnt += 1; + break; + + default: + shell_fprintf(sh, SHELL_WARNING, + "Unrecognized argument: %s\n", argv[i]); + return -ENOEXEC; + } + } + + start += opt_cnt; + argc -= opt_cnt; + + /* Required: */ + if (argc < 3) { + shell_fprintf(sh, SHELL_WARNING, + "Usage: zperf raw upload [-a] " + "[] [] []\n"); + shell_fprintf(sh, SHELL_WARNING, + "Example: zperf raw upload 1 " + "12345678000400030000000000<802.11_hdr_hex> 5 256 1000\n"); + shell_fprintf(sh, SHELL_WARNING, + " Network interface index (use 'net iface' to list)\n" + " Header as hex (vendor metadata + frame header)\n" + " Test duration in seconds (default: 1)\n" + " Total packet size in bytes (default: 256)\n" + " Target rate in Kbps (default: 10)\n"); + shell_fprintf(sh, SHELL_WARNING, + "Options:\n" + " -a Asynchronous mode (shell will not block)\n"); + return -ENOEXEC; + } + + /* Parse interface index */ + param.if_index = strtol(argv[start + 1], NULL, 10); + if (param.if_index <= 0) { + shell_fprintf(sh, SHELL_WARNING, "Invalid interface index: %s\n", argv[start + 1]); + return -EINVAL; + } + + /* Parse header hex bytes (vendor metadata + frame header) */ + ret = parse_hex_bytes(argv[start + 2], hdr_buf, sizeof(hdr_buf)); + if (ret < 0) { + shell_fprintf(sh, SHELL_WARNING, "Invalid header hex string\n"); + return -EINVAL; + } + param.hdr = hdr_buf; + param.hdr_len = ret; + + /* Optional: duration (default: 1 second) */ + if (argc > 3) { + param.duration_ms = MSEC_PER_SEC * strtoul(argv[start + 3], NULL, 10); + } else { + param.duration_ms = MSEC_PER_SEC * DEF_DURATION_SECONDS; + } + + /* Optional: packet size (default: 256) */ + if (argc > 4) { + param.packet_size = parse_number(argv[start + 4], K, K_UNIT); + } else { + param.packet_size = DEF_PACKET_SIZE; + } + + /* Optional: rate in kbps (default: 10) */ + if (argc > 5) { + param.rate_kbps = (parse_number(argv[start + 5], K, K_UNIT) + 999) / 1000; + } else { + param.rate_kbps = DEF_RATE_KBPS; + } + + /* Print configuration */ + shell_fprintf(sh, SHELL_NORMAL, "Raw TX configuration:\n"); + shell_fprintf(sh, SHELL_NORMAL, " Interface index: %d\n", param.if_index); + shell_fprintf(sh, SHELL_NORMAL, " Header: %u bytes\n", param.hdr_len); + shell_fprintf(sh, SHELL_NORMAL, " Duration: "); + print_number_64(sh, (uint64_t)param.duration_ms * USEC_PER_MSEC, TIME_US, TIME_US_UNIT); + shell_fprintf(sh, SHELL_NORMAL, "\n"); + shell_fprintf(sh, SHELL_NORMAL, " Packet size: %u bytes\n", param.packet_size); + shell_fprintf(sh, SHELL_NORMAL, " Rate: "); + print_number(sh, param.rate_kbps, KBPS, KBPS_UNIT); + shell_fprintf(sh, SHELL_NORMAL, "\n"); + + if (async) { + ret = zperf_raw_upload_async(¶m, raw_upload_cb, (void *)sh); + if (ret < 0) { + shell_fprintf(sh, SHELL_ERROR, + "Failed to start async raw TX upload (%d)\n", ret); + return ret; + } + shell_fprintf(sh, SHELL_NORMAL, "Async raw TX upload started\n"); + } else { + shell_fprintf(sh, SHELL_NORMAL, "Starting raw TX upload...\n"); + ret = zperf_raw_upload(¶m, &results); + if (ret < 0) { + shell_fprintf(sh, SHELL_ERROR, "Raw TX upload failed (%d)\n", ret); + return ret; + } + shell_raw_upload_print_stats(sh, &results); + } + + return 0; +} + +static int cmd_raw(const struct shell *sh, size_t argc, char *argv[]) +{ + ARG_UNUSED(argc); + ARG_UNUSED(argv); + + shell_help(sh); + return -ENOEXEC; +} + +SHELL_STATIC_SUBCMD_SET_CREATE(zperf_cmd_raw, + SHELL_CMD(upload, NULL, + "[-a] [] [] []\n" + "Send raw packets. User provides full header (vendor metadata + frame hdr).\n" + " Network interface index\n" + " Header as hex bytes (vendor metadata + 802.11/Eth header)\n" + " Duration in seconds (default: 1)\n" + " Total packet size in bytes (default: 256)\n" + " Target rate in Kbps (default: 10)\n" + "Options:\n" + " -a: Asynchronous mode\n" + "Example: raw upload 1 12345678000400030000000000 5 256 1000\n", + cmd_raw_upload), + SHELL_SUBCMD_SET_END +); + +#endif /* CONFIG_NET_ZPERF_RAW_TX */ + SHELL_STATIC_SUBCMD_SET_CREATE(zperf_commands, SHELL_CMD(connectap, NULL, "Connect to AP", @@ -2070,6 +2310,11 @@ SHELL_STATIC_SUBCMD_SET_CREATE(zperf_commands, SHELL_CMD(jobs, &zperf_cmd_jobs, "Show currently active tests", cmd_jobs), +#ifdef CONFIG_NET_ZPERF_RAW_TX + SHELL_CMD(raw, &zperf_cmd_raw, + "Raw packet TX operations", + cmd_raw), +#endif /* CONFIG_NET_ZPERF_RAW_TX */ SHELL_CMD(setip, NULL, "Set IP address\n" " \n" From 0907ffb370466ba1ace867f2f6d1e92dc4190dbb Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Sat, 3 Jan 2026 11:02:27 +0530 Subject: [PATCH 2214/3659] net: lib: shell: Add TX injection command This to make the interface operationally UP to allow data packets in RAW socket mode. Signed-off-by: Chaitanya Tata --- subsys/net/lib/shell/iface.c | 63 ++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/subsys/net/lib/shell/iface.c b/subsys/net/lib/shell/iface.c index 68e60c0b062b..c61faba742f6 100644 --- a/subsys/net/lib/shell/iface.c +++ b/subsys/net/lib/shell/iface.c @@ -815,6 +815,63 @@ static int cmd_net_default_iface(const struct shell *sh, size_t argc, char *argv return 0; } +#if defined(CONFIG_NET_L2_ETHERNET_MGMT) +static int cmd_net_txinjection(const struct shell *sh, size_t argc, char *argv[]) +{ + struct net_if *iface; + int idx; + int ret; + bool enable; + + if (argc < 3) { + PR_WARNING("Usage: net iface txinjection \n"); + return -ENOEXEC; + } + + idx = get_iface_idx(sh, argv[1]); + if (idx < 0) { + return -ENOEXEC; + } + + iface = net_if_get_by_index(idx); + if (!iface) { + PR_WARNING("No such interface in index %d\n", idx); + return -ENOEXEC; + } + + if (net_if_l2(iface) != &NET_L2_GET_NAME(ETHERNET)) { + PR_WARNING("TX injection mode only supported on Ethernet interfaces\n"); + return -ENOEXEC; + } + + if (!(net_eth_get_hw_capabilities(iface) & ETHERNET_TXINJECTION_MODE)) { + PR_WARNING("TX injection mode not supported by this interface\n"); + return -ENOTSUP; + } + + if (!strcmp(argv[2], "on") || !strcmp(argv[2], "1") || + !strcmp(argv[2], "enable")) { + enable = true; + } else if (!strcmp(argv[2], "off") || !strcmp(argv[2], "0") || + !strcmp(argv[2], "disable")) { + enable = false; + } else { + PR_WARNING("Invalid argument: %s (use on/off)\n", argv[2]); + return -EINVAL; + } + + ret = net_eth_txinjection_mode(iface, enable); + if (ret < 0) { + PR_WARNING("Failed to set TX injection mode (%d)\n", ret); + return ret; + } + + PR("TX injection mode %s on interface %d\n", enable ? "enabled" : "disabled", idx); + + return 0; +} +#endif /* CONFIG_NET_L2_ETHERNET */ + #if defined(CONFIG_ETH_PHY_DRIVER) static int cmd_net_link_speed(const struct shell *sh, size_t argc, char *argv[]) { @@ -921,6 +978,12 @@ SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_iface, SHELL_CMD(default, IFACE_DYN_CMD, "'net iface default []' displays or sets the default network interface.", cmd_net_default_iface), +#if defined(CONFIG_NET_L2_ETHERNET_MGMT) + SHELL_CMD(txinjection, IFACE_DYN_CMD, + "'net iface txinjection ' enables or disables " + "TX injection mode on the network interface.", + cmd_net_txinjection), +#endif /* CONFIG_NET_L2_ETHERNET_MGMT */ #if defined(CONFIG_ETH_PHY_DRIVER) SHELL_CMD(set_link, IFACE_DYN_CMD, "'net iface set_link " From ec1bdb212b4e562db186b77f3cb82b5e790859b9 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Mon, 12 Jan 2026 22:10:04 +0530 Subject: [PATCH 2215/3659] samples: net: zperf: Add raw TX to twister Add raw TX for QEMU and nRF7002DK to twister. Signed-off-by: Chaitanya Tata --- samples/net/zperf/sample.yaml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/samples/net/zperf/sample.yaml b/samples/net/zperf/sample.yaml index 832122c198a0..1bbf2d2eea9e 100644 --- a/samples/net/zperf/sample.yaml +++ b/samples/net/zperf/sample.yaml @@ -105,3 +105,16 @@ tests: extra_configs: - CONFIG_BUILD_ONLY_NO_BLOBS=y platform_allow: nrf7002dk/nrf5340/cpuapp + sample.net.zperf.raw_tx: + harness: net + platform_allow: qemu_x86 + extra_configs: + - CONFIG_NET_SOCKETS_PACKET=y + - CONFIG_NET_ZPERF_RAW_TX=y + sample.net.zperf.raw_tx.nrf7002dk: + extra_args: SNIPPET=wifi-ipv4 + extra_configs: + - CONFIG_BUILD_ONLY_NO_BLOBS=y + - CONFIG_NET_SOCKETS_PACKET=y + - CONFIG_NET_ZPERF_RAW_TX=y + platform_allow: nrf7002dk/nrf5340/cpuapp From acd5815cb1b85159ac8cd47343dc2aac5df878f0 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Mon, 12 Jan 2026 22:12:24 +0530 Subject: [PATCH 2216/3659] doc: connectivity: networking: Add zperf raw TX mode Add a section for raw TX mode. Signed-off-by: Chaitanya Tata --- doc/connectivity/networking/api/zperf.rst | 53 +++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/doc/connectivity/networking/api/zperf.rst b/doc/connectivity/networking/api/zperf.rst index 3e68decb25f7..f58f336c54fc 100644 --- a/doc/connectivity/networking/api/zperf.rst +++ b/doc/connectivity/networking/api/zperf.rst @@ -246,3 +246,56 @@ generation of custom packet contents instead of sending a constant packet consisting solely of the ``z`` character. An example use case would be determining the maximum throughput of uploading data from an external flash memory chip. + +Raw TX Mode +*********** + +zperf supports raw packet transmission mode for testing custom L2 frames or +vendor-specific protocols. This mode bypasses UDP/TCP and sends raw packets +directly using packet sockets. + +To enable raw TX mode, set the following Kconfig options: + +.. code-block:: kconfig + + CONFIG_NET_SOCKETS_PACKET=y + CONFIG_NET_ZPERF_RAW_TX=y + +The maximum header size can be configured with +:kconfig:option:`CONFIG_NET_ZPERF_RAW_TX_MAX_HDR_SIZE` (default: 64 bytes). + +Before using raw TX mode, TX injection mode must be enabled on the network +interface: + +.. code-block:: console + + uart:~$ net iface txinjection 1 on + +The raw TX upload command syntax is: + +.. code-block:: console + + zperf raw upload [-a] [] [] [] + +Where: + +- ``-a``: Optional async mode flag +- ``if_index``: Network interface index (e.g., 1) +- ``header_hex``: User-provided header as hex string (vendor metadata + frame header) +- ``duration_sec``: Test duration in seconds (default: 1) +- ``packet_size``: Total packet size including header (default: 256) +- ``rate_kbps``: Target rate in Kbps, supports K/M suffixes (default: 10) + +Example for sending raw 802.11 frames with vendor metadata: + +.. code-block:: console + + uart:~$ zperf raw upload 1 12345678000400030000000088000000ffffffffffa06960e35215a06960e3521500000000aaaa030000000800 10 1024 50M + +The header hex string contains: + +- Vendor metadata (first 12 bytes in this example) +- 802.11 QoS Data header with LLC/SNAP + +The payload (filled with ``z`` characters) is automatically appended to reach +the specified packet size. From 6100817e34bd00181aeb4b06a6f0c3b2737d6d91 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Wed, 7 Jan 2026 00:57:22 +0530 Subject: [PATCH 2217/3659] drivers: nrf_wifi: Fix raw TX shell When using shell the users input raw header as big-endian, so, add support for both formats for the magic number. Signed-off-by: Chaitanya Tata --- drivers/wifi/nrf_wifi/src/net_if.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/wifi/nrf_wifi/src/net_if.c b/drivers/wifi/nrf_wifi/src/net_if.c index 0d8669f94a10..c93313e5a071 100644 --- a/drivers/wifi/nrf_wifi/src/net_if.c +++ b/drivers/wifi/nrf_wifi/src/net_if.c @@ -19,6 +19,7 @@ LOG_MODULE_DECLARE(wifi_nrf, CONFIG_WIFI_NRF70_LOG_LEVEL); #include +#include #include #include "net_private.h" @@ -427,7 +428,13 @@ int nrf_wifi_if_send(const struct device *dev, } #ifdef CONFIG_NRF70_RAW_DATA_TX - if ((*(unsigned int *)pkt->frags->data) == NRF_WIFI_MAGIC_NUM_RAWTX) { + /* + * Check for raw TX magic number in both byte orders: + * - Little-endian: programmatic API stores native uint32_t + * - Big-endian: shell hex input "12345678" stores bytes 0x12,0x34,0x56,0x78 + */ + if (sys_get_le32(pkt->frags->data) == NRF_WIFI_MAGIC_NUM_RAWTX || + sys_get_be32(pkt->frags->data) == NRF_WIFI_MAGIC_NUM_RAWTX) { if (vif_ctx_zep->if_carr_state != NRF_WIFI_FMAC_IF_CARR_STATE_ON) { goto drop; } From 0305a9f157e7ed5054ef5ddc65af13c514a205bf Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Sun, 11 Jan 2026 21:10:12 +0530 Subject: [PATCH 2218/3659] net: l2: ethernet: Fix build error When Ethernet management is not enabled, the respective calls should also be compiled out. In case there are no callers the toolchain will remove this, hence it worked till date. Signed-off-by: Chaitanya Tata --- subsys/net/l2/ethernet/ethernet.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/subsys/net/l2/ethernet/ethernet.c b/subsys/net/l2/ethernet/ethernet.c index f15eec57cfb9..c6fab4333c3f 100644 --- a/subsys/net/l2/ethernet/ethernet.c +++ b/subsys/net/l2/ethernet/ethernet.c @@ -1020,6 +1020,7 @@ int net_eth_promisc_mode(struct net_if *iface, bool enable) int net_eth_txinjection_mode(struct net_if *iface, bool enable) { +#ifdef CONFIG_NET_L2_ETHERNET_MGMT struct ethernet_req_params params; if (!(net_eth_get_hw_capabilities(iface) & ETHERNET_TXINJECTION_MODE)) { @@ -1030,6 +1031,12 @@ int net_eth_txinjection_mode(struct net_if *iface, bool enable) return net_mgmt(NET_REQUEST_ETHERNET_SET_TXINJECTION_MODE, iface, ¶ms, sizeof(struct ethernet_req_params)); +#else + ARG_UNUSED(iface); + ARG_UNUSED(enable); + + return -ENOTSUP; +#endif } int net_eth_mac_filter(struct net_if *iface, struct net_eth_addr *mac, From c5bc1a977985e4be317d9f06f872ad0e273d6516 Mon Sep 17 00:00:00 2001 From: Lukasz Fundakowski Date: Tue, 20 Jan 2026 13:52:23 +0100 Subject: [PATCH 2219/3659] twister: fix access to item in empty list Fixed default argument in run_cmake_script method, which cannot be an empty list. Signed-off-by: Lukasz Fundakowski --- scripts/pylib/twister/twisterlib/environment.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/scripts/pylib/twister/twisterlib/environment.py b/scripts/pylib/twister/twisterlib/environment.py index fd496a1ef973..7dab35210d68 100644 --- a/scripts/pylib/twister/twisterlib/environment.py +++ b/scripts/pylib/twister/twisterlib/environment.py @@ -19,6 +19,7 @@ from datetime import datetime, timezone from importlib import metadata from pathlib import Path +from typing import Any import zephyr_module from twisterlib.constants import SUPPORTED_SIMS @@ -1033,10 +1034,12 @@ def parse_arguments( return options + def strip_ansi_sequences(s: str) -> str: """Remove ANSI escape sequences from a string.""" return re.sub(r'\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])', "", s) + class TwisterEnv: def __init__(self, options : argparse.Namespace, default_options=None) -> None: @@ -1137,9 +1140,9 @@ def check_zephyr_version(self): logger.exception("Failure while reading head commit date.") @staticmethod - def run_cmake_script(args=None): - if args is None: - args = [] + def run_cmake_script(args: list[str]) -> dict[str, Any]: + if not args: + raise ValueError("args list cannot be empty") script = os.fspath(args[0]) logger.debug(f"Running cmake script {script}") From 213b1605d8d712ec51ebb42eda59f1982b6a39d6 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Fri, 16 Jan 2026 09:23:20 -0800 Subject: [PATCH 2220/3659] random: ctr_drbg: Fix sys_csrand_get types This implementation of sys_csrand_get was using a different type for the length parameter. Signed-off-by: Flavio Ceolin --- subsys/random/random_ctr_drbg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/random/random_ctr_drbg.c b/subsys/random/random_ctr_drbg.c index 25f563e30404..487ea67ea46e 100644 --- a/subsys/random/random_ctr_drbg.c +++ b/subsys/random/random_ctr_drbg.c @@ -62,7 +62,7 @@ static int ctr_drbg_initialize(void) } -int z_impl_sys_csrand_get(void *dst, uint32_t outlen) +int z_impl_sys_csrand_get(void *dst, size_t outlen) { int ret; From cc1391b5f7f509c170de8b7abc8dc11b89eb369d Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Fri, 16 Jan 2026 09:29:35 -0800 Subject: [PATCH 2221/3659] random: entropy: Always check device is ready Use a proper branch instead of an assert to check if the device is ready. It can potentialy lead to improper random value that can compromise security. Signed-off-by: Flavio Ceolin --- subsys/random/random_entropy_device.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/subsys/random/random_entropy_device.c b/subsys/random/random_entropy_device.c index 2ffc569b6904..d8427d1e1f57 100644 --- a/subsys/random/random_entropy_device.c +++ b/subsys/random/random_entropy_device.c @@ -17,8 +17,9 @@ static int rand_get(uint8_t *dst, size_t outlen, bool csrand) uint32_t random_num; int ret; - __ASSERT(device_is_ready(entropy_dev), "Entropy device %s not ready", - entropy_dev->name); + if (!device_is_ready(entropy_dev)) { + return -ENODEV; + } ret = entropy_get_entropy(entropy_dev, dst, outlen); From 2ed0e04dc832e36643aa660ec998f107fa898141 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fin=20Maa=C3=9F?= Date: Fri, 16 Jan 2026 18:10:12 +0100 Subject: [PATCH 2222/3659] console: use k_timeout_t internally MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit use k_timeout_t internally, that way the timeout has only to be calculated, when setting it and not every time when it is used. Also use the ys_timepoint* api instead of counting the ms. Signed-off-by: Fin Maaß --- include/zephyr/console/tty.h | 8 ++++---- subsys/console/tty.c | 15 +++++++-------- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/include/zephyr/console/tty.h b/include/zephyr/console/tty.h index 9776b11a8ea6..13e188b02153 100644 --- a/include/zephyr/console/tty.h +++ b/include/zephyr/console/tty.h @@ -22,13 +22,13 @@ struct tty_serial { uint8_t *rx_ringbuf; uint32_t rx_ringbuf_sz; uint16_t rx_get, rx_put; - int32_t rx_timeout; + k_timeout_t rx_timeout; struct k_sem tx_sem; uint8_t *tx_ringbuf; uint32_t tx_ringbuf_sz; uint16_t tx_get, tx_put; - int32_t tx_timeout; + k_timeout_t tx_timeout; }; /** @@ -62,7 +62,7 @@ int tty_init(struct tty_serial *tty, const struct device *uart_dev); */ static inline void tty_set_rx_timeout(struct tty_serial *tty, int32_t timeout) { - tty->rx_timeout = timeout; + tty->rx_timeout = SYS_TIMEOUT_MS(timeout); } /** @@ -76,7 +76,7 @@ static inline void tty_set_rx_timeout(struct tty_serial *tty, int32_t timeout) */ static inline void tty_set_tx_timeout(struct tty_serial *tty, int32_t timeout) { - tty->tx_timeout = timeout; + tty->tx_timeout = SYS_TIMEOUT_MS(timeout); } /** diff --git a/subsys/console/tty.c b/subsys/console/tty.c index aa8a94c59604..b1d706436ef4 100644 --- a/subsys/console/tty.c +++ b/subsys/console/tty.c @@ -8,6 +8,7 @@ #include #include #include +#include static int tty_irq_input_hook(struct tty_serial *tty, uint8_t c); static int tty_putchar(struct tty_serial *tty, uint8_t c); @@ -73,8 +74,7 @@ static int tty_putchar(struct tty_serial *tty, uint8_t c) int res; res = k_sem_take(&tty->tx_sem, - k_is_in_isr() ? K_NO_WAIT : - SYS_TIMEOUT_MS(tty->tx_timeout)); + k_is_in_isr() ? K_NO_WAIT : tty->tx_timeout); if (res < 0) { return res; } @@ -144,7 +144,7 @@ static int tty_getchar(struct tty_serial *tty) uint8_t c; int res; - res = k_sem_take(&tty->rx_sem, SYS_TIMEOUT_MS(tty->rx_timeout)); + res = k_sem_take(&tty->rx_sem, tty->rx_timeout); if (res < 0) { return res; } @@ -164,7 +164,7 @@ static ssize_t tty_read_unbuf(struct tty_serial *tty, void *buf, size_t size) uint8_t *p = buf; size_t out_size = 0; int res = 0; - uint32_t timeout = tty->rx_timeout; + k_timepoint_t timeout = sys_timepoint_calc(tty->rx_timeout); while (size) { uint8_t c; @@ -187,8 +187,7 @@ static ssize_t tty_read_unbuf(struct tty_serial *tty, void *buf, size_t size) size--; } - if (size == 0 || - ((timeout != SYS_FOREVER_MS) && timeout-- == 0U)) { + if (size == 0 || sys_timepoint_expired(timeout)) { break; } @@ -254,8 +253,8 @@ int tty_init(struct tty_serial *tty, const struct device *uart_dev) tty->rx_get = tty->rx_put = tty->tx_get = tty->tx_put = 0U; - tty->rx_timeout = SYS_FOREVER_MS; - tty->tx_timeout = SYS_FOREVER_MS; + tty->rx_timeout = K_FOREVER; + tty->tx_timeout = K_FOREVER; uart_irq_callback_user_data_set(uart_dev, tty_uart_isr, tty); From 77c4fd9a5306e236114c1ec27f3c3dbfa442be74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fin=20Maa=C3=9F?= Date: Fri, 16 Jan 2026 18:16:26 +0100 Subject: [PATCH 2223/3659] console: add functions to set the timeout MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit While the tty_* api already has functions to set the rx and the tx timeout, the console_* api didn't had one. Signed-off-by: Fin Maaß --- include/zephyr/console/console.h | 22 ++++++++++++++++++++++ subsys/console/getchar.c | 10 ++++++++++ 2 files changed, 32 insertions(+) diff --git a/include/zephyr/console/console.h b/include/zephyr/console/console.h index fbecfdad0d3b..31827780f7c9 100644 --- a/include/zephyr/console/console.h +++ b/include/zephyr/console/console.h @@ -110,6 +110,28 @@ void console_getline_init(void); */ char *console_getline(void); +/** + * @brief Set receive timeout for console operations. + * + * Set timeout for console_getchar() and console_read() operations. + * Default timeout after initialization is K_FOREVER. + * + * @param timeout Maximum time to wait when reading. + */ +void console_set_rx_timeout(k_timeout_t timeout); + + +/** + * @brief Set transmit timeout for console operations. + * + * Set timeout for console_putchar() and console_write() operations, for + * a case when output buffer is full. + * Default timeout after initialization is K_FOREVER. + * + * @param timeout Maximum time to wait when writing. + */ +void console_set_tx_timeout(k_timeout_t timeout); + #ifdef __cplusplus } #endif diff --git a/subsys/console/getchar.c b/subsys/console/getchar.c index ba8055ecfe08..c11ebdc9a3e2 100644 --- a/subsys/console/getchar.c +++ b/subsys/console/getchar.c @@ -47,6 +47,16 @@ int console_getchar(void) return c; } +void console_set_rx_timeout(k_timeout_t timeout) +{ + console_serial.rx_timeout = timeout; +} + +void console_set_tx_timeout(k_timeout_t timeout) +{ + console_serial.tx_timeout = timeout; +} + int console_init(void) { const struct device *uart_dev; From 18e3d5c36884c72f242c2c925bf8da696a2a6fdb Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Fri, 16 Jan 2026 08:48:49 -0800 Subject: [PATCH 2224/3659] pm: device_runtime: Fix doxygen inconsistency Fix an inconsistency / typo in pm_device_runtime_get return value documentation. Signed-off-by: Flavio Ceolin --- include/zephyr/pm/device_runtime.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/zephyr/pm/device_runtime.h b/include/zephyr/pm/device_runtime.h index fde8f631ca2f..3f78bcc73ac6 100644 --- a/include/zephyr/pm/device_runtime.h +++ b/include/zephyr/pm/device_runtime.h @@ -163,7 +163,7 @@ bool pm_device_runtime_is_enabled(const struct device *dev); * * @param dev Device instance. * - * @returns the current usage counter. + * @retval The current usage counter. * @retval -ENOTSUP If the device is not using runtime PM. * @retval -ENOSYS If the runtime PM is not enabled at all. */ From dbf3bb64a95fe861a2c9846f952a1831374f93d5 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Fri, 16 Jan 2026 08:52:20 -0800 Subject: [PATCH 2225/3659] pm: state: Fix pm_state_in_constraints stub It was missing the const qualifier in pm_state_in_constraints when CONFIG_PM is not enabled. Signed-off-by: Flavio Ceolin --- include/zephyr/pm/state.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/zephyr/pm/state.h b/include/zephyr/pm/state.h index 9679c26919a8..ecc893e77d84 100644 --- a/include/zephyr/pm/state.h +++ b/include/zephyr/pm/state.h @@ -499,8 +499,8 @@ static inline const struct pm_state_info *pm_state_get(uint8_t cpu, return NULL; } -static inline bool pm_state_in_constraints(struct pm_state_constraints *constraints, - struct pm_state_constraint match) +static inline bool pm_state_in_constraints(const struct pm_state_constraints *constraints, + const struct pm_state_constraint match) { ARG_UNUSED(constraints); ARG_UNUSED(match); From 9003da65b7db25ad5cdc319f8fec759bbd25a5f4 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Fri, 16 Jan 2026 09:00:16 -0800 Subject: [PATCH 2226/3659] pm: policy: Fix pm_policy_event signatures Fix pm_policy_event_register() and pm_policy_event_update signatures when CONFIG_PM is disabled. Signed-off-by: Flavio Ceolin --- include/zephyr/pm/policy.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/zephyr/pm/policy.h b/include/zephyr/pm/policy.h index 8175214e8774..1f344bee18d1 100644 --- a/include/zephyr/pm/policy.h +++ b/include/zephyr/pm/policy.h @@ -302,16 +302,16 @@ static inline bool pm_policy_state_lock_is_active(enum pm_state state, uint8_t s return false; } -static inline void pm_policy_event_register(struct pm_policy_event *evt, uint32_t cycle) +static inline void pm_policy_event_register(struct pm_policy_event *evt, int64_t uptime_ticks) { ARG_UNUSED(evt); - ARG_UNUSED(cycle); + ARG_UNUSED(uptime_ticks); } -static inline void pm_policy_event_update(struct pm_policy_event *evt, uint32_t cycle) +static inline void pm_policy_event_update(struct pm_policy_event *evt, int64_t uptime_ticks) { ARG_UNUSED(evt); - ARG_UNUSED(cycle); + ARG_UNUSED(uptime_ticks); } static inline void pm_policy_event_unregister(struct pm_policy_event *evt) From 6595aaf280fe0ee6e5527e4b22958bf30233c8af Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Fri, 16 Jan 2026 09:04:05 -0800 Subject: [PATCH 2227/3659] pm: device_runtime: Fix documentation typo s/EWOUDBLOCK/EWOULDBLOCK in pm_device_runtime_get() documentation. Signed-off-by: Flavio Ceolin --- include/zephyr/pm/device_runtime.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/zephyr/pm/device_runtime.h b/include/zephyr/pm/device_runtime.h index 3f78bcc73ac6..f59464ff3528 100644 --- a/include/zephyr/pm/device_runtime.h +++ b/include/zephyr/pm/device_runtime.h @@ -91,7 +91,7 @@ int pm_device_runtime_disable(const struct device *dev); * * @retval 0 If it succeeds. In case device runtime PM is not enabled or not * available this function will be a no-op and will also return 0. - * @retval -EWOUDBLOCK If call would block but it is not allowed (e.g. in ISR). + * @retval -EWOULDBLOCK If call would block but it is not allowed (e.g. in ISR). * @retval -errno Other negative errno, result of the PM action callback. */ int pm_device_runtime_get(const struct device *dev); From c4a5c5cc32150f9f2d7ff798c7a99ef65e1c61ad Mon Sep 17 00:00:00 2001 From: Carlo Caione Date: Fri, 16 Jan 2026 18:05:49 +0100 Subject: [PATCH 2228/3659] lorawan: loramac-node: Use zephyr_library_compile_definitions_ifdef Replace zephyr_compile_definitions_ifdef with zephyr_library_compile_definitions_ifdef to avoid setting options globally. Signed-off-by: Carlo Caione --- subsys/lorawan/loramac-node/CMakeLists.txt | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/subsys/lorawan/loramac-node/CMakeLists.txt b/subsys/lorawan/loramac-node/CMakeLists.txt index ef47e0e2393c..81421067fe1b 100644 --- a/subsys/lorawan/loramac-node/CMakeLists.txt +++ b/subsys/lorawan/loramac-node/CMakeLists.txt @@ -12,16 +12,16 @@ endif() # Add include path for local headers (lw_priv.h) zephyr_library_include_directories(${CMAKE_CURRENT_SOURCE_DIR}) -zephyr_compile_definitions_ifdef(CONFIG_LORAWAN_REGION_AS923 REGION_AS923) -zephyr_compile_definitions_ifdef(CONFIG_LORAWAN_REGION_AU915 REGION_AU915) -zephyr_compile_definitions_ifdef(CONFIG_LORAWAN_REGION_CN470 REGION_CN470) -zephyr_compile_definitions_ifdef(CONFIG_LORAWAN_REGION_CN779 REGION_CN779) -zephyr_compile_definitions_ifdef(CONFIG_LORAWAN_REGION_EU433 REGION_EU433) -zephyr_compile_definitions_ifdef(CONFIG_LORAWAN_REGION_EU868 REGION_EU868) -zephyr_compile_definitions_ifdef(CONFIG_LORAWAN_REGION_KR920 REGION_KR920) -zephyr_compile_definitions_ifdef(CONFIG_LORAWAN_REGION_IN865 REGION_IN865) -zephyr_compile_definitions_ifdef(CONFIG_LORAWAN_REGION_US915 REGION_US915) -zephyr_compile_definitions_ifdef(CONFIG_LORAWAN_REGION_RU864 REGION_RU864) +zephyr_library_compile_definitions_ifdef(CONFIG_LORAWAN_REGION_AS923 REGION_AS923) +zephyr_library_compile_definitions_ifdef(CONFIG_LORAWAN_REGION_AU915 REGION_AU915) +zephyr_library_compile_definitions_ifdef(CONFIG_LORAWAN_REGION_CN470 REGION_CN470) +zephyr_library_compile_definitions_ifdef(CONFIG_LORAWAN_REGION_CN779 REGION_CN779) +zephyr_library_compile_definitions_ifdef(CONFIG_LORAWAN_REGION_EU433 REGION_EU433) +zephyr_library_compile_definitions_ifdef(CONFIG_LORAWAN_REGION_EU868 REGION_EU868) +zephyr_library_compile_definitions_ifdef(CONFIG_LORAWAN_REGION_KR920 REGION_KR920) +zephyr_library_compile_definitions_ifdef(CONFIG_LORAWAN_REGION_IN865 REGION_IN865) +zephyr_library_compile_definitions_ifdef(CONFIG_LORAWAN_REGION_US915 REGION_US915) +zephyr_library_compile_definitions_ifdef(CONFIG_LORAWAN_REGION_RU864 REGION_RU864) # Don't build the real implementation when the emulator is used if(NOT CONFIG_LORAWAN_EMUL) From f8e4c6cf6a020d20b5f4e6c41a339a647854e818 Mon Sep 17 00:00:00 2001 From: Grzegorz Chwierut Date: Fri, 16 Jan 2026 16:53:21 +0100 Subject: [PATCH 2229/3659] twister: pytest: Fix post-script calling in initialization phase The post-script was being called multiple times and during the initialization phase when it should only run after the reader thread has started and the device testing is complete. Fixes #102386 Signed-off-by: Grzegorz Chwierut --- .../src/twister_harness/device/device_adapter.py | 4 ++++ .../src/twister_harness/device/hardware_adapter.py | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/scripts/pylib/pytest-twister-harness/src/twister_harness/device/device_adapter.py b/scripts/pylib/pytest-twister-harness/src/twister_harness/device/device_adapter.py index 5680760f84ca..05103bc5698c 100644 --- a/scripts/pylib/pytest-twister-harness/src/twister_harness/device/device_adapter.py +++ b/scripts/pylib/pytest-twister-harness/src/twister_harness/device/device_adapter.py @@ -223,3 +223,7 @@ def is_device_connected(self) -> bool: Added to keep backward compatibility as it is used in fixtures. """ return self.connections and self.connections[0].is_device_connected() + + def is_reader_started(self) -> bool: + """Check if the reader thread is started.""" + return self._reader_started.is_set() diff --git a/scripts/pylib/pytest-twister-harness/src/twister_harness/device/hardware_adapter.py b/scripts/pylib/pytest-twister-harness/src/twister_harness/device/hardware_adapter.py index 2de075d2d98b..ef5d1d6d8b02 100644 --- a/scripts/pylib/pytest-twister-harness/src/twister_harness/device/hardware_adapter.py +++ b/scripts/pylib/pytest-twister-harness/src/twister_harness/device/hardware_adapter.py @@ -177,7 +177,9 @@ def _flash_and_run(self) -> None: raise TwisterHarnessException(msg) def _close_device(self) -> None: - if self.device_config.post_script: + # Run post script only if the reader thread is started to avoid running it + # multiple times and when in initialization phase + if self.is_reader_started() and self.device_config.post_script: self._run_custom_script(self.device_config.post_script, self.base_timeout) @staticmethod From e19ebfb49a3507cfd1b6687f4f71f19cda46b38e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gu=C3=B0ni=20M=C3=A1r=20Gilbert?= Date: Sat, 10 Jan 2026 15:37:01 +0000 Subject: [PATCH 2230/3659] scripts: twister: use os.scandir for platform YAML discovery MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use a single os.scandir() pass per board directory to load twister.yaml and collect legacy *.yaml files, replacing Path checks and globbing. On my end this reduces execution time by ~50ms on Ubuntu 24.04 and eliminates ~80k Python function calls. Signed-off-by: Guðni Már Gilbert --- scripts/pylib/twister/twisterlib/platform.py | 22 +++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/scripts/pylib/twister/twisterlib/platform.py b/scripts/pylib/twister/twisterlib/platform.py index 6fd98b83b2cc..66115c233216 100644 --- a/scripts/pylib/twister/twisterlib/platform.py +++ b/scripts/pylib/twister/twisterlib/platform.py @@ -216,16 +216,18 @@ def generate_platforms(board_roots, soc_roots, arch_roots): if board_dir in dir2data: # don't load the same board data twice continue - file = board_dir / "twister.yaml" - if file.is_file(): - data = scl.yaml_load_verify(file, Platform.platform_schema) - else: - data = None - dir2data[board_dir] = data + data = None - legacy_files.extend( - file for file in board_dir.glob("*.yaml") if file.name != "twister.yaml" - ) + for entry in os.scandir(board_dir): + if not entry.is_file(): + continue + + if entry.name == "twister.yaml": + data = scl.yaml_load_verify(entry.path, Platform.platform_schema) + elif entry.name.endswith(".yaml"): + legacy_files.append(entry.path) + + dir2data[board_dir] = data for qual in list_boards.board_v2_qualifiers(board): if board.revisions: @@ -298,7 +300,7 @@ def generate_platforms(board_roots, soc_roots, arch_roots): board = target2board[target] if dir2data[board.dir] is not None: # all targets are already loaded for this board - logger.error(f"Duplicate platform {target} in {file.parent}") + logger.error(f"Duplicate platform {target} in {os.path.dirname(file)}") raise Exception(f"Duplicate platform identifier {target} found") platform = Platform() From 0b02c507c950f6bd8b404eb8fab4e65405bbe689 Mon Sep 17 00:00:00 2001 From: Laura Carlesso Date: Thu, 15 Jan 2026 17:07:35 -0800 Subject: [PATCH 2231/3659] soc: infineon: Fix NMI handling in PSOC6 for legacy boards cy8ckit_062_wifi_bt board requires NMI handler to point to the prefefined address 0x0000000D in order to correctly run system calls. This can be achieved by specifying the runtime nmi configuration and hardcoding the address in soc.c. With the introduction of this change the system calls can correctly be executed correctly thus resolving open issue #99642 . Signed-off-by: Laura Carlesso --- .../cy8ckit_062_wifi_bt_cy8c6247_m0_defconfig | 2 ++ soc/infineon/cat1a/psoc6_legacy/soc.c | 15 +++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/boards/cypress/cy8ckit_062_wifi_bt/cy8ckit_062_wifi_bt_cy8c6247_m0_defconfig b/boards/cypress/cy8ckit_062_wifi_bt/cy8ckit_062_wifi_bt_cy8c6247_m0_defconfig index d9ff32f44cc9..3f99f942388d 100644 --- a/boards/cypress/cy8ckit_062_wifi_bt/cy8ckit_062_wifi_bt_cy8c6247_m0_defconfig +++ b/boards/cypress/cy8ckit_062_wifi_bt/cy8ckit_062_wifi_bt_cy8c6247_m0_defconfig @@ -9,3 +9,5 @@ CONFIG_UART_CONSOLE=y # UART driver CONFIG_SERIAL=y + +CONFIG_RUNTIME_NMI=y diff --git a/soc/infineon/cat1a/psoc6_legacy/soc.c b/soc/infineon/cat1a/psoc6_legacy/soc.c index 71dc7cd2ce21..27907ec4c9e1 100644 --- a/soc/infineon/cat1a/psoc6_legacy/soc.c +++ b/soc/infineon/cat1a/psoc6_legacy/soc.c @@ -111,9 +111,24 @@ static inline void Cy_SysClk_ClkSlowInit(void) Cy_SysClk_ClkSlowSetDivider(0u); } +#ifdef CONFIG_RUNTIME_NMI + /* Address of the NMI handler extracted from startup_psoc6_0x_cm0plus.S */ + #define CY_NMI_HANLDER_ADDR 0x0000000D +#endif /* CONFIG_RUNTIME_NMI */ static void init_cycfg_platform(void) { + #ifdef CONFIG_RUNTIME_NMI + /* This is required for System Calls, see following excerpt from + * TRM section 8.4.2: + * NMI exception handler address is automatically initialized to + * the system call API located in SROM (at 0x0000000D) by the boot + * code. The value should be retained during vector table relocations; + * otherwise, no system call will be executed. + */ + z_arm_nmi_set_handler((void *)CY_NMI_HANLDER_ADDR); + #endif + /* Set worst case memory wait states (! ultra low power, 150 MHz), will * update at the end */ From c9dc320cf567455c465260519605f8281adfa53d Mon Sep 17 00:00:00 2001 From: Albort Xue Date: Wed, 14 Jan 2026 22:39:47 +0800 Subject: [PATCH 2232/3659] drivers: watchdog: wdt_mcux_wdog32: Support named clocks for clock sources Add support for named clocks in the WDOG32 driver to properly handle different clock sources. The driver now uses clock-names property to identify which clock source is being used, based on the clk-source property. This change enables proper clock configuration and control for platforms where the clock frequency is not statically defined in the device tree. The driver will now configure and enable the appropriate clock during initialization. Updated all affected device tree files to include the clock-names property aligned with their clk-source configuration. Signed-off-by: Albort Xue --- drivers/watchdog/wdt_mcux_wdog32.c | 46 ++++++++++++++++++++++++++--- dts/arm/nxp/nxp_ke1xf.dtsi | 1 + dts/arm/nxp/nxp_ke1xz.dtsi | 1 + dts/arm/nxp/nxp_mcxe24x_common.dtsi | 1 + dts/arm/nxp/nxp_mcxw7x_common.dtsi | 2 ++ dts/arm/nxp/nxp_s32k1xx.dtsi | 1 + dts/arm64/nxp/nxp_mimx93_a55.dtsi | 2 ++ 7 files changed, 50 insertions(+), 4 deletions(-) diff --git a/drivers/watchdog/wdt_mcux_wdog32.c b/drivers/watchdog/wdt_mcux_wdog32.c index 2f142a05c3da..f5323c795a0f 100644 --- a/drivers/watchdog/wdt_mcux_wdog32.c +++ b/drivers/watchdog/wdt_mcux_wdog32.c @@ -1,6 +1,6 @@ /* * Copyright (2) 2019 Vestas Wind Systems A/S - * Copyright 2025 NXP + * Copyright 2025-2026 NXP * * Based on wdt_mcux_wdog.c, which is: * Copyright (c) 2018, NXP @@ -205,6 +205,27 @@ static int mcux_wdog32_init(const struct device *dev) { const struct mcux_wdog32_config *config = dev->config; +#if (!DT_NODE_HAS_PROP(DT_INST_PHANDLE(0, clocks), clock_frequency)) + int ret; + + ret = clock_control_configure(config->clock_dev, config->clock_subsys, NULL); + if (ret != 0) { + /* Check if error is due to lack of support */ + if (ret != -ENOSYS) { + /* Real error occurred */ + LOG_ERR("Failed to configure clock: %d", ret); + return ret; + } + } + +#if FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL + ret = clock_control_on(config->clock_dev, config->clock_subsys); + if (ret) { + LOG_ERR("Failed to enable clock: %d", ret); + return ret; + } +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +#endif /* Map the named MMIO region */ DEVICE_MMIO_NAMED_MAP(dev, reg, K_MEM_CACHE_NONE | K_MEM_DIRECT_MAP); @@ -223,15 +244,32 @@ static DEVICE_API(wdt, mcux_wdog32_api) = { #define TO_WDOG32_CLK_SRC(val) _DO_CONCAT(kWDOG32_ClockSource, val) #define TO_WDOG32_CLK_DIV(val) _DO_CONCAT(kWDOG32_ClockPrescalerDivide, val) +#define WDOG32_CLK_SOURCE(id) DT_INST_PROP(id, clk_source) +#define WDOG32_CLK_SOURCE_NAME(id) CONCAT(clksrc, WDOG32_CLK_SOURCE(id)) + +#define WDOG32_INST_CLOCKS_FROM_CLK_SOURCE(id) \ + .clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR_BY_NAME(id, WDOG32_CLK_SOURCE_NAME(id))), \ + .clock_subsys = (clock_control_subsys_t) \ + DT_INST_CLOCKS_CELL_BY_NAME(id, WDOG32_CLK_SOURCE_NAME(id), name) + +#define WDOG32_INST_CLOCKS(id) \ + WDOG32_INST_CLOCKS_FROM_CLK_SOURCE(id) + +#define WDOG32_CHECK_CLK_SOURCES(id) \ + IF_DISABLED(DT_NODE_HAS_PROP(DT_INST_PHANDLE(0, clocks), clock_frequency), \ + (BUILD_ASSERT(DT_INST_CLOCKS_HAS_NAME(id, WDOG32_CLK_SOURCE_NAME(id)), \ + "WDOG32 instance " STRINGIFY(id) " clk-source without named clock"))) + static void mcux_wdog32_config_func_0(const struct device *dev); +WDOG32_CHECK_CLK_SOURCES(0); + static const struct mcux_wdog32_config mcux_wdog32_config_0 = { DEVICE_MMIO_NAMED_ROM_INIT(reg, DT_DRV_INST(0)), #if DT_NODE_HAS_PROP(DT_INST_PHANDLE(0, clocks), clock_frequency) .clock_frequency = DT_INST_PROP_BY_PHANDLE(0, clocks, clock_frequency), -#else /* !DT_NODE_HAS_PROP(DT_INST_PHANDLE(0, clocks), clock_frequency) */ - .clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(0)), - .clock_subsys = (clock_control_subsys_t)DT_INST_CLOCKS_CELL(0, name), +#else /* !DT_NODE_HAS_PROP(DT_INST_PHANDLE(0, clocks), clock_frequency) */ + WDOG32_INST_CLOCKS(0), #endif /* DT_NODE_HAS_PROP(DT_INST_PHANDLE(0, clocks), clock_frequency) */ .clk_source = TO_WDOG32_CLK_SRC(DT_INST_PROP(0, clk_source)), .clk_divider = TO_WDOG32_CLK_DIV(DT_INST_PROP(0, clk_divider)), diff --git a/dts/arm/nxp/nxp_ke1xf.dtsi b/dts/arm/nxp/nxp_ke1xf.dtsi index 421e00c04b24..dc5a6a745f5f 100644 --- a/dts/arm/nxp/nxp_ke1xf.dtsi +++ b/dts/arm/nxp/nxp_ke1xf.dtsi @@ -299,6 +299,7 @@ reg = <0x40052000 0x1000>; interrupts = <22 0>; clocks = <&lpo>; + clock-names = "clksrc1"; clk-source = <1>; clk-divider = <256>; }; diff --git a/dts/arm/nxp/nxp_ke1xz.dtsi b/dts/arm/nxp/nxp_ke1xz.dtsi index a10d728de237..fcc65090a08b 100644 --- a/dts/arm/nxp/nxp_ke1xz.dtsi +++ b/dts/arm/nxp/nxp_ke1xz.dtsi @@ -263,6 +263,7 @@ reg = <0x40052000 0x1000>; interrupts = <28 0>; clocks = <&lpo>; + clock-names = "clksrc1"; clk-source = <1>; clk-divider = <256>; status = "disabled"; diff --git a/dts/arm/nxp/nxp_mcxe24x_common.dtsi b/dts/arm/nxp/nxp_mcxe24x_common.dtsi index 69278670bb77..d9b6def2fb98 100644 --- a/dts/arm/nxp/nxp_mcxe24x_common.dtsi +++ b/dts/arm/nxp/nxp_mcxe24x_common.dtsi @@ -693,6 +693,7 @@ reg = <0x40052000 0x1000>; interrupts = <22 0>; clocks = <&lpo>; + clock-names = "clksrc1"; clk-source = <1>; clk-divider = <256>; status = "disabled"; diff --git a/dts/arm/nxp/nxp_mcxw7x_common.dtsi b/dts/arm/nxp/nxp_mcxw7x_common.dtsi index f52f2200e593..178f95607239 100644 --- a/dts/arm/nxp/nxp_mcxw7x_common.dtsi +++ b/dts/arm/nxp/nxp_mcxw7x_common.dtsi @@ -315,6 +315,7 @@ reg = <0x1a000 10>; interrupts = <23 0>; clocks = <&scg SCG_K4_RTCOSC_CLK 0x68>; + clock-names = "clksrc1"; clk-source = <1>; clk-divider = <1>; status = "okay"; @@ -325,6 +326,7 @@ reg = <0x1b000 10>; interrupts = <24 0>; clocks = <&scg SCG_K4_RTCOSC_CLK 0x6c>; + clock-names = "clksrc1"; clk-source = <1>; clk-divider = <1>; status = "disabled"; diff --git a/dts/arm/nxp/nxp_s32k1xx.dtsi b/dts/arm/nxp/nxp_s32k1xx.dtsi index 72fb1b70747c..3767410c8c02 100644 --- a/dts/arm/nxp/nxp_s32k1xx.dtsi +++ b/dts/arm/nxp/nxp_s32k1xx.dtsi @@ -139,6 +139,7 @@ reg = <0x40052000 0x1000>; interrupts = <22 0>; clocks = <&clock NXP_S32_LPO_128K_CLK>; + clock-names = "clksrc1"; clk-source = <1>; clk-divider = <256>; }; diff --git a/dts/arm64/nxp/nxp_mimx93_a55.dtsi b/dts/arm64/nxp/nxp_mimx93_a55.dtsi index 6ffb3e0a9187..b4fcb596a32c 100644 --- a/dts/arm64/nxp/nxp_mimx93_a55.dtsi +++ b/dts/arm64/nxp/nxp_mimx93_a55.dtsi @@ -123,6 +123,7 @@ interrupt-parent = <&gic>; /* clk-source and clocks must aligned: 0-ipg_clk, 1-lpo_clk, 2-int_clk, 3-ext_clk */ clocks = <&lpo_clk>; + clock-names = "clksrc1"; clk-source = <1>; clk-divider = <256>; status = "disabled"; @@ -135,6 +136,7 @@ interrupt-parent = <&gic>; /* clk-source and clocks must aligned: 0-ipg_clk, 1-lpo_clk, 2-int_clk, 3-ext_clk */ clocks = <&lpo_clk>; + clock-names = "clksrc1"; clk-source = <1>; clk-divider = <256>; status = "disabled"; From c170fede6b2934fe8aceb50422ed91af76056a45 Mon Sep 17 00:00:00 2001 From: Greg Leach Date: Sun, 11 Jan 2026 15:37:53 +0000 Subject: [PATCH 2233/3659] boards: ezurio: Add lyra_24_dvk support Add support for the Ezurio Lyra 24 DVK board family. Signed-off-by: Greg Leach --- boards/ezurio/lyra_24_dvk/Kconfig.defconfig | 25 ++ .../lyra_24_dvk/Kconfig.lyra_24_dvk_p10 | 6 + .../lyra_24_dvk/Kconfig.lyra_24_dvk_p20 | 6 + .../lyra_24_dvk/Kconfig.lyra_24_dvk_p20rf | 6 + .../lyra_24_dvk/Kconfig.lyra_24_dvk_s10 | 6 + boards/ezurio/lyra_24_dvk/board.cmake | 9 + boards/ezurio/lyra_24_dvk/board.yml | 21 ++ .../lyra_24_dvk/doc/img/lyra_24_dvk_p10.webp | Bin 0 -> 33542 bytes .../lyra_24_dvk/doc/img/lyra_24_dvk_p20.webp | Bin 0 -> 33542 bytes .../doc/img/lyra_24_dvk_p20rf.webp | Bin 0 -> 33542 bytes .../lyra_24_dvk/doc/img/lyra_24_dvk_s10.webp | Bin 0 -> 30292 bytes .../doc/lyra_24_dvk_common_1.rst.inc | 56 ++++ .../doc/lyra_24_dvk_common_2.rst.inc | 58 ++++ .../doc/lyra_24_dvk_common_3.rst.inc | 24 ++ .../lyra_24_dvk/doc/lyra_24_dvk_p10.rst | 27 ++ .../lyra_24_dvk/doc/lyra_24_dvk_p20.rst | 27 ++ .../lyra_24_dvk/doc/lyra_24_dvk_p20rf.rst | 27 ++ .../doc/lyra_24_dvk_p_pinmap.rst.inc | 59 ++++ .../doc/lyra_24_dvk_p_references.rst.inc | 12 + .../lyra_24_dvk/doc/lyra_24_dvk_s10.rst | 101 +++++++ .../lyra_24_dvk/lyra_24_dvk-pinctrl.dtsi | 84 ++++++ boards/ezurio/lyra_24_dvk/lyra_24_dvk.dtsi | 280 ++++++++++++++++++ boards/ezurio/lyra_24_dvk/lyra_24_dvk_p10.dts | 15 + .../ezurio/lyra_24_dvk/lyra_24_dvk_p10.yaml | 28 ++ .../lyra_24_dvk/lyra_24_dvk_p10_defconfig | 11 + boards/ezurio/lyra_24_dvk/lyra_24_dvk_p20.dts | 15 + .../ezurio/lyra_24_dvk/lyra_24_dvk_p20.yaml | 28 ++ .../lyra_24_dvk/lyra_24_dvk_p20_defconfig | 11 + .../ezurio/lyra_24_dvk/lyra_24_dvk_p20rf.dts | 15 + .../ezurio/lyra_24_dvk/lyra_24_dvk_p20rf.yaml | 28 ++ .../lyra_24_dvk/lyra_24_dvk_p20rf_defconfig | 11 + boards/ezurio/lyra_24_dvk/lyra_24_dvk_s10.dts | 15 + .../ezurio/lyra_24_dvk/lyra_24_dvk_s10.yaml | 28 ++ .../lyra_24_dvk/lyra_24_dvk_s10_defconfig | 11 + boards/ezurio/lyra_24_dvk/pre_dt_board.cmake | 6 + 35 files changed, 1056 insertions(+) create mode 100644 boards/ezurio/lyra_24_dvk/Kconfig.defconfig create mode 100644 boards/ezurio/lyra_24_dvk/Kconfig.lyra_24_dvk_p10 create mode 100644 boards/ezurio/lyra_24_dvk/Kconfig.lyra_24_dvk_p20 create mode 100644 boards/ezurio/lyra_24_dvk/Kconfig.lyra_24_dvk_p20rf create mode 100644 boards/ezurio/lyra_24_dvk/Kconfig.lyra_24_dvk_s10 create mode 100644 boards/ezurio/lyra_24_dvk/board.cmake create mode 100644 boards/ezurio/lyra_24_dvk/board.yml create mode 100644 boards/ezurio/lyra_24_dvk/doc/img/lyra_24_dvk_p10.webp create mode 100644 boards/ezurio/lyra_24_dvk/doc/img/lyra_24_dvk_p20.webp create mode 100644 boards/ezurio/lyra_24_dvk/doc/img/lyra_24_dvk_p20rf.webp create mode 100644 boards/ezurio/lyra_24_dvk/doc/img/lyra_24_dvk_s10.webp create mode 100644 boards/ezurio/lyra_24_dvk/doc/lyra_24_dvk_common_1.rst.inc create mode 100644 boards/ezurio/lyra_24_dvk/doc/lyra_24_dvk_common_2.rst.inc create mode 100644 boards/ezurio/lyra_24_dvk/doc/lyra_24_dvk_common_3.rst.inc create mode 100644 boards/ezurio/lyra_24_dvk/doc/lyra_24_dvk_p10.rst create mode 100644 boards/ezurio/lyra_24_dvk/doc/lyra_24_dvk_p20.rst create mode 100644 boards/ezurio/lyra_24_dvk/doc/lyra_24_dvk_p20rf.rst create mode 100644 boards/ezurio/lyra_24_dvk/doc/lyra_24_dvk_p_pinmap.rst.inc create mode 100644 boards/ezurio/lyra_24_dvk/doc/lyra_24_dvk_p_references.rst.inc create mode 100644 boards/ezurio/lyra_24_dvk/doc/lyra_24_dvk_s10.rst create mode 100644 boards/ezurio/lyra_24_dvk/lyra_24_dvk-pinctrl.dtsi create mode 100644 boards/ezurio/lyra_24_dvk/lyra_24_dvk.dtsi create mode 100644 boards/ezurio/lyra_24_dvk/lyra_24_dvk_p10.dts create mode 100644 boards/ezurio/lyra_24_dvk/lyra_24_dvk_p10.yaml create mode 100644 boards/ezurio/lyra_24_dvk/lyra_24_dvk_p10_defconfig create mode 100644 boards/ezurio/lyra_24_dvk/lyra_24_dvk_p20.dts create mode 100644 boards/ezurio/lyra_24_dvk/lyra_24_dvk_p20.yaml create mode 100644 boards/ezurio/lyra_24_dvk/lyra_24_dvk_p20_defconfig create mode 100644 boards/ezurio/lyra_24_dvk/lyra_24_dvk_p20rf.dts create mode 100644 boards/ezurio/lyra_24_dvk/lyra_24_dvk_p20rf.yaml create mode 100644 boards/ezurio/lyra_24_dvk/lyra_24_dvk_p20rf_defconfig create mode 100644 boards/ezurio/lyra_24_dvk/lyra_24_dvk_s10.dts create mode 100644 boards/ezurio/lyra_24_dvk/lyra_24_dvk_s10.yaml create mode 100644 boards/ezurio/lyra_24_dvk/lyra_24_dvk_s10_defconfig create mode 100644 boards/ezurio/lyra_24_dvk/pre_dt_board.cmake diff --git a/boards/ezurio/lyra_24_dvk/Kconfig.defconfig b/boards/ezurio/lyra_24_dvk/Kconfig.defconfig new file mode 100644 index 000000000000..7a62e8426b73 --- /dev/null +++ b/boards/ezurio/lyra_24_dvk/Kconfig.defconfig @@ -0,0 +1,25 @@ +# Copyright (c) 2021, Sateesh Kotapati +# Copyright (c) 2026 Ezurio LLC +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_LYRA_24_DVK_P10 || BOARD_LYRA_24_DVK_P20 || BOARD_LYRA_24_DVK_P20RF || BOARD_LYRA_24_DVK_S10 + +config REGULATOR + default y + +config LOG_BACKEND_SWO_FREQ_HZ + default 875000 + depends on LOG_BACKEND_SWO + +config FPU + default y if SOC_GECKO_USE_RAIL || BT + +if BT + +config MAIN_STACK_SIZE + default 3072 if PM + default 2304 + +endif # BT + +endif # BOARD_LYRA_24_DVK_P10 || BOARD_LYRA_24_DVK_P20 || BOARD_LYRA_24_DVK_P20RF || BOARD_LYRA_24_DVK_S10 diff --git a/boards/ezurio/lyra_24_dvk/Kconfig.lyra_24_dvk_p10 b/boards/ezurio/lyra_24_dvk/Kconfig.lyra_24_dvk_p10 new file mode 100644 index 000000000000..1ea9a0ab06dd --- /dev/null +++ b/boards/ezurio/lyra_24_dvk/Kconfig.lyra_24_dvk_p10 @@ -0,0 +1,6 @@ +# Copyright (c) 2021, Sateesh Kotapati +# Copyright (c) 2026 Ezurio LLC +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_LYRA_24_DVK_P10 + select SOC_BGM240PB22VNA diff --git a/boards/ezurio/lyra_24_dvk/Kconfig.lyra_24_dvk_p20 b/boards/ezurio/lyra_24_dvk/Kconfig.lyra_24_dvk_p20 new file mode 100644 index 000000000000..a69534eb88c5 --- /dev/null +++ b/boards/ezurio/lyra_24_dvk/Kconfig.lyra_24_dvk_p20 @@ -0,0 +1,6 @@ +# Copyright (c) 2021, Sateesh Kotapati +# Copyright (c) 2026 Ezurio LLC +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_LYRA_24_DVK_P20 + select SOC_BGM240PB32VNA diff --git a/boards/ezurio/lyra_24_dvk/Kconfig.lyra_24_dvk_p20rf b/boards/ezurio/lyra_24_dvk/Kconfig.lyra_24_dvk_p20rf new file mode 100644 index 000000000000..53411520f6a7 --- /dev/null +++ b/boards/ezurio/lyra_24_dvk/Kconfig.lyra_24_dvk_p20rf @@ -0,0 +1,6 @@ +# Copyright (c) 2021, Sateesh Kotapati +# Copyright (c) 2026 Ezurio LLC +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_LYRA_24_DVK_P20RF + select SOC_BGM240PB32VNN diff --git a/boards/ezurio/lyra_24_dvk/Kconfig.lyra_24_dvk_s10 b/boards/ezurio/lyra_24_dvk/Kconfig.lyra_24_dvk_s10 new file mode 100644 index 000000000000..739a73a54647 --- /dev/null +++ b/boards/ezurio/lyra_24_dvk/Kconfig.lyra_24_dvk_s10 @@ -0,0 +1,6 @@ +# Copyright (c) 2021, Sateesh Kotapati +# Copyright (c) 2026 Ezurio LLC +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_LYRA_24_DVK_S10 + select SOC_BGM240SB22VNA diff --git a/boards/ezurio/lyra_24_dvk/board.cmake b/boards/ezurio/lyra_24_dvk/board.cmake new file mode 100644 index 000000000000..c2d7111f1ce5 --- /dev/null +++ b/boards/ezurio/lyra_24_dvk/board.cmake @@ -0,0 +1,9 @@ +# Copyright (c) 2021, Sateesh Kotapati +# Copyright (c) 2026 Ezurio LLC +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(jlink "--device=EFR32MG24BxxxF1536" "--reset-after-load") +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) + +board_runner_args(silabs_commander "--device=${CONFIG_SOC}") +include(${ZEPHYR_BASE}/boards/common/silabs_commander.board.cmake) diff --git a/boards/ezurio/lyra_24_dvk/board.yml b/boards/ezurio/lyra_24_dvk/board.yml new file mode 100644 index 000000000000..705ef866ddf5 --- /dev/null +++ b/boards/ezurio/lyra_24_dvk/board.yml @@ -0,0 +1,21 @@ +boards: + - name: lyra_24_dvk_p10 + vendor: ezurio + full_name: Lyra 24 P10 DVK + socs: + - name: bgm240pb22vna + - name: lyra_24_dvk_p20 + vendor: ezurio + full_name: Lyra 24 P20 DVK + socs: + - name: bgm240pb32vna + - name: lyra_24_dvk_p20rf + vendor: ezurio + full_name: Lyra 24 P20RF DVK + socs: + - name: bgm240pb32vnn + - name: lyra_24_dvk_s10 + vendor: ezurio + full_name: Lyra 24 S10 DVK + socs: + - name: bgm240sb22vna diff --git a/boards/ezurio/lyra_24_dvk/doc/img/lyra_24_dvk_p10.webp b/boards/ezurio/lyra_24_dvk/doc/img/lyra_24_dvk_p10.webp new file mode 100644 index 0000000000000000000000000000000000000000..007662ae9e4189fdfe573aebdd24e00622db9501 GIT binary patch literal 33542 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

    _(Dqq7Z{E!kZRA(6$|@s)!<>Q# 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 W01Ea%0000000000000000002Jh9?;S literal 0 HcmV?d00001 diff --git a/boards/ezurio/lyra_24_dvk/doc/img/lyra_24_dvk_p20.webp b/boards/ezurio/lyra_24_dvk/doc/img/lyra_24_dvk_p20.webp new file mode 100644 index 0000000000000000000000000000000000000000..007662ae9e4189fdfe573aebdd24e00622db9501 GIT binary patch literal 33542 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

    _(Dqq7Z{E!kZRA(6$|@s)!<>Q# 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 W01Ea%0000000000000000002Jh9?;S literal 0 HcmV?d00001 diff --git a/boards/ezurio/lyra_24_dvk/doc/img/lyra_24_dvk_p20rf.webp b/boards/ezurio/lyra_24_dvk/doc/img/lyra_24_dvk_p20rf.webp new file mode 100644 index 0000000000000000000000000000000000000000..007662ae9e4189fdfe573aebdd24e00622db9501 GIT binary patch literal 33542 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

    _(Dqq7Z{E!kZRA(6$|@s)!<>Q# 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 W01Ea%0000000000000000002Jh9?;S literal 0 HcmV?d00001 diff --git a/boards/ezurio/lyra_24_dvk/doc/img/lyra_24_dvk_s10.webp b/boards/ezurio/lyra_24_dvk/doc/img/lyra_24_dvk_s10.webp new file mode 100644 index 0000000000000000000000000000000000000000..a6b085e96050fe4bdf6545d97e42179de3c79847 GIT binary patch literal 30292 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 literal 0 HcmV?d00001 diff --git a/boards/ezurio/lyra_24_dvk/doc/lyra_24_dvk_common_1.rst.inc b/boards/ezurio/lyra_24_dvk/doc/lyra_24_dvk_common_1.rst.inc new file mode 100644 index 000000000000..223256adfed4 --- /dev/null +++ b/boards/ezurio/lyra_24_dvk/doc/lyra_24_dvk_common_1.rst.inc @@ -0,0 +1,56 @@ +.. SPDX-License-Identifier: Apache-2.0 +.. +.. Copyright (c) 2026 Ezurio LLC + +Overview +******** + +The Lyra 24 |Lyra 24 variant| Development Kit provides support for the Ezurio Lyra 24 |Lyra 24 variant| Bluetooth Low Energy v5.4 module. + +The module is based on the Silicon Laboratories |SoC| module and includes an EFR32BG24 Arm Cortex-M33 CPU. + +The Lyra 24 |Lyra 24 variant| module incorporates the QFN package EFR32BG24 (1024kB Flash, 256kB RAM). The part features +up to |Number of IO| configurable GPIOs and BLE Radio TX Power up to |BLE TX Power|. + +The kit features a USB interface, an on-board SEGGER J-Link debugger, one user-LED and button, and +support for hardware add-on boards via a `mikroBUS`_ socket and a `Qwiic`_ connector. + +.. note:: + You can find more information about the Lyra 24 family of modules in the `Lyra 24 product brief`_ and on the `Lyra 24 website`_. + + You can find more information about the Lyra 24 |Lyra 24 variant| module in the |Datasheet Ref|. + + You can find more information about the underlying |SoC| module in the |SoC Datasheet Ref|. + + You can find more information about the underlying EFR32BG24 SoC in the `EFR32BG24 datasheet`_ + and `EFR32BG24 reference manual`_. + +Hardware +******** + +The Lyra 24 |Lyra 24 variant| DVK has two crystal oscillators as follows. + +* High-frequency 39 MHz crystal oscillator (HFXO) +* Low-frequency 32.768 kHz crystal oscillator (LFXO) + +The high-frequency crystal oscillator is fitted within the Lyra 24 |Lyra 24 variant| module. + +The low-frequency crystal oscillator is fitted to the DVK and is external to the Lyra 24 |Lyra 24 variant| module. + +The module supports an |Antenna Type| Bluetooth Low Energy antenna. + +Full details of the DVK can be found in the |User Guide Ref| and |Schematics Ref|. + +Supported Features +================== + +.. zephyr:board-supported-hw:: + +Connections and IOs +=================== + +In the following table, the column **Name** contains Pin names. For example, PA2 +means Pin number 2 on PORTA, as used in the board's datasheets and manuals. + +The **Direction** column indicates the pin direction from the module perspective, with +I indicating Input, O Output, I/O for both and N/A where not applicable. diff --git a/boards/ezurio/lyra_24_dvk/doc/lyra_24_dvk_common_2.rst.inc b/boards/ezurio/lyra_24_dvk/doc/lyra_24_dvk_common_2.rst.inc new file mode 100644 index 000000000000..30cd9fda2034 --- /dev/null +++ b/boards/ezurio/lyra_24_dvk/doc/lyra_24_dvk_common_2.rst.inc @@ -0,0 +1,58 @@ +.. SPDX-License-Identifier: Apache-2.0 +.. +.. Copyright (c) 2026 Ezurio LLC + +.. note:: + Qwiic SCL is multipexed to the same I/O as MikroBUS SCL. MikroBUS I2C based boards can be used + in conjunction with Qwiic boards by closing solder bridges SB5 and SB6. + + Qwiic SDA is multipexed to the same I/O as MikroBUS SDA. MikroBUS I2C based boards can be used + in conjunction with Qwiic boards by closing solder bridges SB9 and SB10. + + Refer to the |User Guide Ref| and |Schematics Ref| for further details. + +System Clock +============ + +The Lyra 24 |Lyra 24 variant| is configured to use the 39 MHz external oscillator on the +board, and can operate at clock speeds of up to 78 MHz. + +Serial Port +=========== + +The Lyra 24 |Lyra 24 variant| has two EUSARTs and one USART. + +* EUSART0 defaults to the mikroBUS UART. +* EUSART1 defaults to the mikroBUS SPI port. +* USART0 is connected to the board controller and is used for the console. + +Programming and Debugging +************************* + +Applications for the |Board Quoted| board can be built, flashed, and debugged in the usual way. +See :ref:`build_an_application` and :ref:`application_run` for more details on building and running. + +.. note:: + Before using the kit you should update the J-Link firmware + in `Simplicity Studio`_. + +Testing the LED and button +========================== + +The :zephyr:code-sample:`blinky` sample can be used to test the DVK LED. + +The :zephyr:code-sample:`button` sample can be used to test the DVK button. + +Bluetooth Low Energy +==================== + +To use Bluetooth Low Energy functionality, run the command below to retrieve necessary binary +blobs from the Silicon Labs HAL repository. + +.. code-block:: console + + west blobs fetch hal_silabs + +Then build the Zephyr kernel and a Bluetooth sample with the following +command. The :zephyr:code-sample:`bluetooth_observer` sample application is used in +this example. diff --git a/boards/ezurio/lyra_24_dvk/doc/lyra_24_dvk_common_3.rst.inc b/boards/ezurio/lyra_24_dvk/doc/lyra_24_dvk_common_3.rst.inc new file mode 100644 index 000000000000..8be1e8f471cd --- /dev/null +++ b/boards/ezurio/lyra_24_dvk/doc/lyra_24_dvk_common_3.rst.inc @@ -0,0 +1,24 @@ +.. SPDX-License-Identifier: Apache-2.0 +.. +.. Copyright (c) 2026 Ezurio LLC + +.. _Lyra 24 product brief: + https://www.ezurio.com/documentation/product-brief-lyra-24-series + +.. _Lyra 24 website: + https://www.ezurio.com/wireless-modules/bluetooth-modules/bluetooth-5-modules/lyra-24-series-bluetooth-5-modules + +.. _EFR32BG24 datasheet: + https://www.silabs.com/documents/public/data-sheets/efr32bg24-datasheet.pdf + +.. _EFR32BG24 reference manual: + https://www.silabs.com/documents/public/reference-manuals/efr32xg24-rm.pdf + +.. _mikroBUS: + https://www.mikroe.com/mikrobus + +.. _Qwiic: + https://www.sparkfun.com/qwiic + +.. _Simplicity Studio: + https://www.silabs.com/software-and-tools/simplicity-studio diff --git a/boards/ezurio/lyra_24_dvk/doc/lyra_24_dvk_p10.rst b/boards/ezurio/lyra_24_dvk/doc/lyra_24_dvk_p10.rst new file mode 100644 index 000000000000..8c22440e235d --- /dev/null +++ b/boards/ezurio/lyra_24_dvk/doc/lyra_24_dvk_p10.rst @@ -0,0 +1,27 @@ +.. zephyr:board:: lyra_24_dvk_p10 + +.. |Lyra 24 variant| replace:: P10 +.. |Datasheet Ref| replace:: `Lyra 24 P datasheet`_ +.. |SoC| replace:: BGM240PB22VNA +.. |SoC Datasheet Ref| replace:: `BGM240P datasheet`_ +.. |Antenna Type| replace:: on-chip +.. |Number of IO| replace:: 26 +.. |BLE TX Power| replace:: 10dBm +.. |Board Quoted| replace:: ``lyra_24_dvk_p10`` +.. |User Guide Ref| replace:: `Lyra 24 P DVK user guide`_ +.. |Schematics Ref| replace:: `Lyra 24 P10 DVK schematics`_ + +.. include:: lyra_24_dvk_common_1.rst.inc +.. include:: lyra_24_dvk_p_pinmap.rst.inc +.. include:: lyra_24_dvk_common_2.rst.inc + +.. zephyr-app-commands:: + :zephyr-app: samples/bluetooth/observer + :board: lyra_24_dvk_p10 + :goals: build + +.. include:: lyra_24_dvk_common_3.rst.inc +.. include:: lyra_24_dvk_p_references.rst.inc + +.. _Lyra 24 P10 DVK schematics: + https://www.ezurio.com/documentation/schematic-pcb-assembly-dvk-lyra-24p-devboard-integrated-antenna-10dbm-453-00142-k1 diff --git a/boards/ezurio/lyra_24_dvk/doc/lyra_24_dvk_p20.rst b/boards/ezurio/lyra_24_dvk/doc/lyra_24_dvk_p20.rst new file mode 100644 index 000000000000..e3fbf77ce619 --- /dev/null +++ b/boards/ezurio/lyra_24_dvk/doc/lyra_24_dvk_p20.rst @@ -0,0 +1,27 @@ +.. zephyr:board:: lyra_24_dvk_p20 + +.. |Lyra 24 variant| replace:: P20 +.. |Datasheet Ref| replace:: `Lyra 24 P datasheet`_ +.. |SoC| replace:: BGM240PB32VNA +.. |SoC Datasheet Ref| replace:: `BGM240P datasheet`_ +.. |Antenna Type| replace:: on-chip +.. |Number of IO| replace:: 26 +.. |BLE TX Power| replace:: 20dBm +.. |Board Quoted| replace:: ``lyra_24_dvk_p20`` +.. |User Guide Ref| replace:: `Lyra 24 P DVK user guide`_ +.. |Schematics Ref| replace:: `Lyra 24 P20 DVK schematics`_ + +.. include:: lyra_24_dvk_common_1.rst.inc +.. include:: lyra_24_dvk_p_pinmap.rst.inc +.. include:: lyra_24_dvk_common_2.rst.inc + +.. zephyr-app-commands:: + :zephyr-app: samples/bluetooth/observer + :board: lyra_24_dvk_p20 + :goals: build + +.. include:: lyra_24_dvk_common_3.rst.inc +.. include:: lyra_24_dvk_p_references.rst.inc + +.. _Lyra 24 P20 DVK schematics: + https://www.ezurio.com/documentation/schematic-pcb-assembly-dvk-lyra-24p-devboard-integrated-antenna-20dbm-453-00145-k1 diff --git a/boards/ezurio/lyra_24_dvk/doc/lyra_24_dvk_p20rf.rst b/boards/ezurio/lyra_24_dvk/doc/lyra_24_dvk_p20rf.rst new file mode 100644 index 000000000000..b4640cd259b7 --- /dev/null +++ b/boards/ezurio/lyra_24_dvk/doc/lyra_24_dvk_p20rf.rst @@ -0,0 +1,27 @@ +.. zephyr:board:: lyra_24_dvk_p20rf + +.. |Lyra 24 variant| replace:: P20RF +.. |Datasheet Ref| replace:: `Lyra 24 P datasheet`_ +.. |SoC| replace:: BGM240PB32VNN +.. |SoC Datasheet Ref| replace:: `BGM240P datasheet`_ +.. |Antenna Type| replace:: external +.. |Number of IO| replace:: 26 +.. |BLE TX Power| replace:: 20dBm +.. |Board Quoted| replace:: ``lyra_24_dvk_p20rf`` +.. |User Guide Ref| replace:: `Lyra 24 P DVK user guide`_ +.. |Schematics Ref| replace:: `Lyra 24 P20RF DVK schematics`_ + +.. include:: lyra_24_dvk_common_1.rst.inc +.. include:: lyra_24_dvk_p_pinmap.rst.inc +.. include:: lyra_24_dvk_common_2.rst.inc + +.. zephyr-app-commands:: + :zephyr-app: samples/bluetooth/observer + :board: lyra_24_dvk_p20rf + :goals: build + +.. include:: lyra_24_dvk_common_3.rst.inc +.. include:: lyra_24_dvk_p_references.rst.inc + +.. _Lyra 24 P20RF DVK schematics: + https://www.ezurio.com/documentation/schematic-pcb-assembly-dvk-lyra-24p-devboard-rf-trace-pad-20dbm-453-00148-k1 diff --git a/boards/ezurio/lyra_24_dvk/doc/lyra_24_dvk_p_pinmap.rst.inc b/boards/ezurio/lyra_24_dvk/doc/lyra_24_dvk_p_pinmap.rst.inc new file mode 100644 index 000000000000..657f97c86996 --- /dev/null +++ b/boards/ezurio/lyra_24_dvk/doc/lyra_24_dvk_p_pinmap.rst.inc @@ -0,0 +1,59 @@ +.. SPDX-License-Identifier: Apache-2.0 +.. +.. Copyright (c) 2026 Ezurio LLC + ++-------+-------------+-------------------------------------+-----------+ +| Name | Function | Usage | Direction | ++=======+=============+=====================================+===========+ +| PA0 | USART0_TX | UART Console VCOM_TX | O | ++-------+-------------+-------------------------------------+-----------+ +| PA1 | SWD_SWCLK | JLink SWCLK | I | ++-------+-------------+-------------------------------------+-----------+ +| PA2 | SWD_SWDIO | JLink SWDIO | I/O | ++-------+-------------+-------------------------------------+-----------+ +| PA3 | SWD_SWO | JLink SWO | O | ++-------+-------------+-------------------------------------+-----------+ +| PA4 | USART0_RTS | UART Console VCOM_RTS | O | ++-------+-------------+-------------------------------------+-----------+ +| PA5 | USART0_CTS | UART Console VCOM_CTS | I | ++-------+-------------+-------------------------------------+-----------+ +| PA6 | GPIO | Breakout Connector GPIO | I/O | ++-------+-------------+-------------------------------------+-----------+ +| PA7 | USART0_RX | UART Console VCOM_RX | I | ++-------+-------------+-------------------------------------+-----------+ +| PA8 | GPIO | LED 0 | O | ++-------+-------------+-------------------------------------+-----------+ +| PB0 | GPIO | mikroBUS AN | I | ++-------+-------------+-------------------------------------+-----------+ +| PB1 | EUSART0_TX | mikroBUS TX | O | ++-------+-------------+-------------------------------------+-----------+ +| PB2 | EUSART0_RX | mikroBUS RX | I | ++-------+-------------+-------------------------------------+-----------+ +| PB3 | GPIO | mikroBUS INT | I | ++-------+-------------+-------------------------------------+-----------+ +| PB4 | GPIO | mikroBUS PWM | O | ++-------+-------------+-------------------------------------+-----------+ +| PC0 | PTI_FRAME | Packet Trace Interface FRAME | O | ++-------+-------------+-------------------------------------+-----------+ +| PC1 | PTI_DATA | Packet Trace Interface DATA | O | ++-------+-------------+-------------------------------------+-----------+ +| PC2 | EUSART1_SCK | mikroBUS SCK | O | ++-------+-------------+-------------------------------------+-----------+ +| PC3 | GPIO | mikroBUS CS | O | ++-------+-------------+-------------------------------------+-----------+ +| PC4 | EUSART1_TX | mikroBUS MOSI | O | ++-------+-------------+-------------------------------------+-----------+ +| PC5 | EUSART1_RX | mikroBUS MISO | I | ++-------+-------------+-------------------------------------+-----------+ +| PC6 | GPIO | mikroBUS RST | O | ++-------+-------------+-------------------------------------+-----------+ +| PC7 | GPIO | Button 0 | I | ++-------+-------------+-------------------------------------+-----------+ +| PD0 | LFXO | LFXO | N/A | ++-------+-------------+-------------------------------------+-----------+ +| PD1 | LFXO | LFXO | N/A | ++-------+-------------+-------------------------------------+-----------+ +| PD2 | I2C0_SCL | mikroBUS SCL / Qwiic SCL | I/O | ++-------+-------------+-------------------------------------+-----------+ +| PD3 | I2C0_SDA | mikroBUS SDA / Qwiic SDA | I/O | ++-------+-------------+-------------------------------------+-----------+ diff --git a/boards/ezurio/lyra_24_dvk/doc/lyra_24_dvk_p_references.rst.inc b/boards/ezurio/lyra_24_dvk/doc/lyra_24_dvk_p_references.rst.inc new file mode 100644 index 000000000000..5b96213ee952 --- /dev/null +++ b/boards/ezurio/lyra_24_dvk/doc/lyra_24_dvk_p_references.rst.inc @@ -0,0 +1,12 @@ +.. SPDX-License-Identifier: Apache-2.0 +.. +.. Copyright (c) 2026 Ezurio LLC + +.. _Lyra 24 P datasheet: + https://www.ezurio.com/documentation/datasheet-lyra-24p + +.. _BGM240P datasheet: + https://www.silabs.com/documents/public/data-sheets/bgm240p-datasheet.pdf + +.. _Lyra 24 P DVK user guide: + https://www.ezurio.com/documentation/user-guide-lyra-24p-development-kit diff --git a/boards/ezurio/lyra_24_dvk/doc/lyra_24_dvk_s10.rst b/boards/ezurio/lyra_24_dvk/doc/lyra_24_dvk_s10.rst new file mode 100644 index 000000000000..ceffd2e064e8 --- /dev/null +++ b/boards/ezurio/lyra_24_dvk/doc/lyra_24_dvk_s10.rst @@ -0,0 +1,101 @@ +.. zephyr:board:: lyra_24_dvk_s10 + +.. |Lyra 24 variant| replace:: S10 +.. |Datasheet Ref| replace:: `Lyra 24 S datasheet`_ +.. |SoC| replace:: BGM240SB22VNA +.. |SoC Datasheet Ref| replace:: `BGM240S datasheet`_ +.. |Antenna Type| replace:: on-chip or external +.. |Number of IO| replace:: 31 +.. |BLE TX Power| replace:: 10dBm +.. |Board Quoted| replace:: ``lyra_24_dvk_s10`` +.. |User Guide Ref| replace:: `Lyra 24 S DVK user guide`_ +.. |Schematics Ref| replace:: `Lyra 24 S10 DVK schematics`_ + +.. include:: lyra_24_dvk_common_1.rst.inc + ++-------+-------------+-------------------------------------+-----------+ +| Name | Function | Usage | Direction | ++=======+=============+=====================================+===========+ +| PA0 | USART0_TX | UART Console VCOM_TX | O | ++-------+-------------+-------------------------------------+-----------+ +| PA1 | SWD_SWCLK | JLink SWCLK | I | ++-------+-------------+-------------------------------------+-----------+ +| PA2 | SWD_SWDIO | JLink SWDIO | I/O | ++-------+-------------+-------------------------------------+-----------+ +| PA3 | SWD_SWO | JLink SWO | O | ++-------+-------------+-------------------------------------+-----------+ +| PA4 | USART0_RTS | UART Console VCOM_RTS | O | ++-------+-------------+-------------------------------------+-----------+ +| PA5 | USART0_CTS | UART Console VCOM_CTS | I | ++-------+-------------+-------------------------------------+-----------+ +| PA6 | GPIO | Breakout Connector GPIO | I/O | ++-------+-------------+-------------------------------------+-----------+ +| PA7 | USART0_RX | UART Console VCOM_RX | I | ++-------+-------------+-------------------------------------+-----------+ +| PA8 | GPIO | LED 0 | O | ++-------+-------------+-------------------------------------+-----------+ +| PB0 | GPIO | mikroBUS AN | I | ++-------+-------------+-------------------------------------+-----------+ +| PB1 | EUSART0_TX | mikroBUS TX | O | ++-------+-------------+-------------------------------------+-----------+ +| PB2 | EUSART0_RX | mikroBUS RX | I | ++-------+-------------+-------------------------------------+-----------+ +| PB3 | GPIO | mikroBUS INT | I | ++-------+-------------+-------------------------------------+-----------+ +| PB4 | GPIO | mikroBUS PWM | O | ++-------+-------------+-------------------------------------+-----------+ +| PB5 | GPIO | Test Point GPIO | I/O | ++-------+-------------+-------------------------------------+-----------+ +| PC0 | PTI_FRAME | Packet Trace Interface FRAME | O | ++-------+-------------+-------------------------------------+-----------+ +| PC1 | PTI_DATA | Packet Trace Interface DATA | O | ++-------+-------------+-------------------------------------+-----------+ +| PC2 | EUSART1_SCK | mikroBUS SCK | O | ++-------+-------------+-------------------------------------+-----------+ +| PC3 | GPIO | mikroBUS CS | O | ++-------+-------------+-------------------------------------+-----------+ +| PC4 | EUSART1_TX | mikroBUS MOSI | O | ++-------+-------------+-------------------------------------+-----------+ +| PC5 | EUSART1_RX | mikroBUS MISO | I | ++-------+-------------+-------------------------------------+-----------+ +| PC6 | GPIO | mikroBUS RST | O | ++-------+-------------+-------------------------------------+-----------+ +| PC7 | GPIO | Button 0 | I | ++-------+-------------+-------------------------------------+-----------+ +| PC8 | GPIO | Test Point GPIO | I/O | ++-------+-------------+-------------------------------------+-----------+ +| PC9 | GPIO | Test Point GPIO | I/O | ++-------+-------------+-------------------------------------+-----------+ +| PD0 | LFXO | LFXO | N/A | ++-------+-------------+-------------------------------------+-----------+ +| PD1 | LFXO | LFXO | N/A | ++-------+-------------+-------------------------------------+-----------+ +| PD2 | I2C0_SCL | mikroBUS SCL / Qwiic SCL | I/O | ++-------+-------------+-------------------------------------+-----------+ +| PD3 | I2C0_SDA | mikroBUS SDA / Qwiic SDA | I/O | ++-------+-------------+-------------------------------------+-----------+ +| PD4 | GPIO | Test Point GPIO | I/O | ++-------+-------------+-------------------------------------+-----------+ +| PD5 | GPIO | Test Point GPIO | I/O | ++-------+-------------+-------------------------------------+-----------+ + +.. include:: lyra_24_dvk_common_2.rst.inc + +.. zephyr-app-commands:: + :zephyr-app: samples/bluetooth/observer + :board: lyra_24_dvk_s10 + :goals: build + +.. include:: lyra_24_dvk_common_3.rst.inc + +.. _Lyra 24 S datasheet: + https://www.ezurio.com/documentation/datasheet-lyra-24s + +.. _BGM240S datasheet: + https://www.silabs.com/documents/public/data-sheets/bgm240s-datasheet.pdf + +.. _Lyra 24 S DVK user guide: + https://www.ezurio.com/documentation/user-guide-lyra-24s-development-kit + +.. _Lyra 24 S10 DVK schematics: + https://www.ezurio.com/documentation/schematic-pcb-assembly-dvk-lyra-24s-devboard-integrated-antenna-10dbm-453-00170-k1 diff --git a/boards/ezurio/lyra_24_dvk/lyra_24_dvk-pinctrl.dtsi b/boards/ezurio/lyra_24_dvk/lyra_24_dvk-pinctrl.dtsi new file mode 100644 index 000000000000..caf2fd614c61 --- /dev/null +++ b/boards/ezurio/lyra_24_dvk/lyra_24_dvk-pinctrl.dtsi @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2024 Silicon Laboratories Inc. + * Copyright (c) 2026 Ezurio LLC + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&pinctrl { + timer0_default: timer0_default { + group0 { + pins = ; + drive-push-pull; + output-high; + }; + }; + + usart0_default: usart0_default { + group0 { + pins = , ; + drive-push-pull; + output-high; + }; + + group1 { + pins = , ; + input-enable; + silabs,input-filter; + }; + }; + + eusart1_default: eusart1_default { + group0 { + pins = , ; + drive-push-pull; + output-high; + }; + + group1 { + pins = ; + input-enable; + silabs,input-filter; + }; + }; + + i2c0_default: i2c0_default { + group0 { + pins = , ; + bias-pull-up; + drive-open-drain; + }; + }; + + eusart0_default: eusart0_default { + group0 { + pins = ; + drive-push-pull; + output-high; + }; + + group1 { + pins = ; + input-enable; + silabs,input-filter; + }; + }; + + itm_default: itm_default { + group0 { + pins = ; + drive-push-pull; + output-high; + }; + }; + + pti_default: pti_default { + group0 { + pins = , ; + drive-push-pull; + output-high; + }; + }; +}; diff --git a/boards/ezurio/lyra_24_dvk/lyra_24_dvk.dtsi b/boards/ezurio/lyra_24_dvk/lyra_24_dvk.dtsi new file mode 100644 index 000000000000..d5d6798c4ce6 --- /dev/null +++ b/boards/ezurio/lyra_24_dvk/lyra_24_dvk.dtsi @@ -0,0 +1,280 @@ +/* + * Copyright (c) 2020 TriaGnoSys GmbH + * Copyright (c) 2026 Ezurio LLC + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include "lyra_24_dvk-pinctrl.dtsi" + +/ { + chosen { + zephyr,bt-hci = &bt_hci_silabs; + zephyr,code-partition = &slot0_partition; + zephyr,console = &usart0; + zephyr,flash = &flash0; + zephyr,shell-uart = &usart0; + zephyr,sram = &sram0; + zephyr,uart-pipe = &usart0; + }; + + aliases { + led0 = &led0; + pwm-led0 = &pwm_led0; + sw0 = &button0; + watchdog0 = &wdog0; + }; + + leds { + compatible = "gpio-leds"; + + led0: led_0 { + gpios = <&gpioa 8 GPIO_ACTIVE_LOW>; + }; + }; + + pwmleds { + compatible = "pwm-leds"; + + pwm_led0: pwm_led_0 { + pwms = <&timer0_pwm 0 PWM_MSEC(20) PWM_POLARITY_INVERTED>; + }; + }; + + buttons { + compatible = "gpio-keys"; + + button0: button_0 { + gpios = <&gpioc 7 GPIO_ACTIVE_LOW>; + zephyr,code = ; + }; + }; + + mikrobus_header: mikrobus-connector { + compatible = "mikro-bus"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0>; + gpio-map-pass-thru = <0 GPIO_DT_FLAGS_MASK>; + gpio-map = <0 0 &gpiob 0 0>, /* AN */ + <1 0 &gpioc 6 0>, /* RST */ + <2 0 &gpioc 3 0>, /* CS */ + <3 0 &gpioc 2 0>, /* SCK */ + <4 0 &gpioc 5 0>, /* MISO */ + <5 0 &gpioc 4 0>, /* MOSI */ + <6 0 &gpiob 4 0>, /* PWM */ + <7 0 &gpiob 3 0>, /* INT */ + <8 0 &gpiob 2 0>, /* RX */ + <9 0 &gpiob 1 0>, /* TX */ + <10 0 &gpiod 2 0>, /* SCL */ + <11 0 &gpiod 3 0>; /* SDA */ + }; + + qwiic_connector: stemma-qt-connector { + compatible = "stemma-qt-connector"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0>; + gpio-map-pass-thru = <0 GPIO_DT_FLAGS_MASK>; + gpio-map = <0 0 &gpiod 2 0>, /* SCL */ + <1 0 &gpiod 3 0>; /* SDA */ + }; + + mikrobus_adc: zephyr,user { + io-channels = <&adc0 0>; + }; +}; + +&em23grpaclk { + clocks = <&lfxo>; +}; + +&em4grpaclk { + clocks = <&lfxo>; +}; + +&sysrtcclk { + clocks = <&lfxo>; +}; + +&wdog0clk { + clocks = <&lfxo>; +}; + +&wdog1clk { + clocks = <&lfxo>; +}; + +&cpu0 { + clock-frequency = <39000000>; +}; + +&hfrcodpll { + clock-frequency = ; + clocks = <&hfxo>; + dpll-autorecover; + dpll-edge = "fall"; + dpll-lock = "phase"; + dpll-m = <3839>; + dpll-n = <3839>; +}; + +&hfxo { + ctune = <140>; + precision = <50>; + status = "okay"; +}; + +&lfxo { + status = "okay"; + ctune = <63>; + precision = <50>; +}; + +&gpio { + status = "okay"; +}; + +&gpioa { + status = "okay"; +}; + +&gpiob { + status = "okay"; +}; + +&gpioc { + status = "okay"; +}; + +&gpiod { + status = "okay"; +}; + +&timer0 { + status = "okay"; + + timer0_pwm: pwm { + pinctrl-0 = <&timer0_default>; + pinctrl-names = "default"; + status = "okay"; + }; +}; + +&usart0 { + current-speed = <115200>; + pinctrl-0 = <&usart0_default>; + pinctrl-names = "default"; + status = "okay"; +}; + +&dcdc { + regulator-boot-on; + regulator-initial-mode = ; + status = "okay"; +}; + +&eusart1 { + compatible = "silabs,eusart-spi"; + #address-cells = <1>; + #size-cells = <0>; + pinctrl-0 = <&eusart1_default>; + pinctrl-names = "default"; + status = "okay"; +}; + +&sysrtc0 { + status = "okay"; +}; + +&adc0 { + status = "okay"; +}; + +&vdac0 { + status = "okay"; +}; + +&vdac1 { + status = "okay"; +}; + +&i2c0 { + pinctrl-0 = <&i2c0_default>; + pinctrl-names = "default"; + status = "okay"; +}; + +&wdog0 { + status = "okay"; +}; + +&eusart0 { + compatible = "silabs,eusart-uart"; + pinctrl-0 = <&eusart0_default>; + pinctrl-names = "default"; + status = "okay"; +}; + +&se { + status = "okay"; +}; + +&itm { + pinctrl-0 = <&itm_default>; + pinctrl-names = "default"; + swo-ref-frequency = ; +}; + +&bt_hci_silabs { + status = "okay"; +}; + +&pti { + pinctrl-0 = <&pti_default>; + pinctrl-names = "default"; +}; + +mikrobus_i2c: &i2c0 {}; + +mikrobus_spi: &eusart1 {}; + +mikrobus_uart: &eusart0 {}; + +zephyr_i2c: &i2c0 {}; + +zephyr_spi: &eusart1 {}; + +&flash0 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + /* Reserve 48 kB for the bootloader */ + boot_partition: partition@0 { + reg = <0x0 DT_SIZE_K(48)>; + label = "mcuboot"; + read-only; + }; + + /* Reserve 728 kB for the application in slot 0 */ + slot0_partition: partition@c000 { + reg = <0x0000c000 DT_SIZE_K(728)>; + label = "image-0"; + }; + + /* Reserve 728 kB for the application in slot 1 */ + slot1_partition: partition@c2000 { + reg = <0x000c2000 DT_SIZE_K(728)>; + label = "image-1"; + }; + + /* Set 32 kB of storage at the end of the 1536 kB of flash */ + storage_partition: partition@178000 { + reg = <0x00178000 DT_SIZE_K(32)>; + label = "storage"; + }; + }; +}; diff --git a/boards/ezurio/lyra_24_dvk/lyra_24_dvk_p10.dts b/boards/ezurio/lyra_24_dvk/lyra_24_dvk_p10.dts new file mode 100644 index 000000000000..e3e8eecb43f1 --- /dev/null +++ b/boards/ezurio/lyra_24_dvk/lyra_24_dvk_p10.dts @@ -0,0 +1,15 @@ +/* + * Copyright The Zephyr Project Contributors + * Copyright (c) 2026 Ezurio LLC + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include "lyra_24_dvk.dtsi" + +/ { + model = "Ezurio Lyra 24 P10 DVK"; + compatible = "ezurio,lyra_24_dvk_p10", "silabs,efr32bg24"; +}; diff --git a/boards/ezurio/lyra_24_dvk/lyra_24_dvk_p10.yaml b/boards/ezurio/lyra_24_dvk/lyra_24_dvk_p10.yaml new file mode 100644 index 000000000000..a5c606c801f6 --- /dev/null +++ b/boards/ezurio/lyra_24_dvk/lyra_24_dvk_p10.yaml @@ -0,0 +1,28 @@ +identifier: lyra_24_dvk_p10 +name: Lyra 24 P10 DVK +type: mcu +arch: arm +ram: 256 +flash: 728 +toolchain: + - zephyr + - gnuarmemb +supported: + - adc + - bluetooth + - clock_control + - comparator + - counter + - dac + - dma + - entropy + - gpio + - flash + - i2c + - led + - pinctrl + - pwm + - spi + - uart + - watchdog +vendor: ezurio diff --git a/boards/ezurio/lyra_24_dvk/lyra_24_dvk_p10_defconfig b/boards/ezurio/lyra_24_dvk/lyra_24_dvk_p10_defconfig new file mode 100644 index 000000000000..363b0169db67 --- /dev/null +++ b/boards/ezurio/lyra_24_dvk/lyra_24_dvk_p10_defconfig @@ -0,0 +1,11 @@ +# Copyright (c) 2022 Silicon Labs +# Copyright (c) 2026 Ezurio LLC +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_ARM_MPU=y +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_GPIO=y +CONFIG_HW_STACK_PROTECTION=y +CONFIG_REGULATOR=y diff --git a/boards/ezurio/lyra_24_dvk/lyra_24_dvk_p20.dts b/boards/ezurio/lyra_24_dvk/lyra_24_dvk_p20.dts new file mode 100644 index 000000000000..4dfcb43ca555 --- /dev/null +++ b/boards/ezurio/lyra_24_dvk/lyra_24_dvk_p20.dts @@ -0,0 +1,15 @@ +/* + * Copyright The Zephyr Project Contributors + * Copyright (c) 2026 Ezurio LLC + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include "lyra_24_dvk.dtsi" + +/ { + model = "Ezurio Lyra 24 P20 DVK"; + compatible = "ezurio,lyra_24_dvk_p20", "silabs,efr32bg24"; +}; diff --git a/boards/ezurio/lyra_24_dvk/lyra_24_dvk_p20.yaml b/boards/ezurio/lyra_24_dvk/lyra_24_dvk_p20.yaml new file mode 100644 index 000000000000..e3b679696b3e --- /dev/null +++ b/boards/ezurio/lyra_24_dvk/lyra_24_dvk_p20.yaml @@ -0,0 +1,28 @@ +identifier: lyra_24_dvk_p20 +name: Lyra 24 P20 DVK +type: mcu +arch: arm +ram: 256 +flash: 728 +toolchain: + - zephyr + - gnuarmemb +supported: + - adc + - bluetooth + - clock_control + - comparator + - counter + - dac + - dma + - entropy + - gpio + - flash + - i2c + - led + - pinctrl + - pwm + - spi + - uart + - watchdog +vendor: ezurio diff --git a/boards/ezurio/lyra_24_dvk/lyra_24_dvk_p20_defconfig b/boards/ezurio/lyra_24_dvk/lyra_24_dvk_p20_defconfig new file mode 100644 index 000000000000..363b0169db67 --- /dev/null +++ b/boards/ezurio/lyra_24_dvk/lyra_24_dvk_p20_defconfig @@ -0,0 +1,11 @@ +# Copyright (c) 2022 Silicon Labs +# Copyright (c) 2026 Ezurio LLC +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_ARM_MPU=y +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_GPIO=y +CONFIG_HW_STACK_PROTECTION=y +CONFIG_REGULATOR=y diff --git a/boards/ezurio/lyra_24_dvk/lyra_24_dvk_p20rf.dts b/boards/ezurio/lyra_24_dvk/lyra_24_dvk_p20rf.dts new file mode 100644 index 000000000000..98a70116c064 --- /dev/null +++ b/boards/ezurio/lyra_24_dvk/lyra_24_dvk_p20rf.dts @@ -0,0 +1,15 @@ +/* + * Copyright The Zephyr Project Contributors + * Copyright (c) 2026 Ezurio LLC + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include "lyra_24_dvk.dtsi" + +/ { + model = "Ezurio Lyra 24 P20RF DVK"; + compatible = "ezurio,lyra_24_dvk_p20rf", "silabs,efr32bg24"; +}; diff --git a/boards/ezurio/lyra_24_dvk/lyra_24_dvk_p20rf.yaml b/boards/ezurio/lyra_24_dvk/lyra_24_dvk_p20rf.yaml new file mode 100644 index 000000000000..8d06182bc28d --- /dev/null +++ b/boards/ezurio/lyra_24_dvk/lyra_24_dvk_p20rf.yaml @@ -0,0 +1,28 @@ +identifier: lyra_24_dvk_p20rf +name: Lyra 24 P20RF DVK +type: mcu +arch: arm +ram: 256 +flash: 728 +toolchain: + - zephyr + - gnuarmemb +supported: + - adc + - bluetooth + - clock_control + - comparator + - counter + - dac + - dma + - entropy + - gpio + - flash + - i2c + - led + - pinctrl + - pwm + - spi + - uart + - watchdog +vendor: ezurio diff --git a/boards/ezurio/lyra_24_dvk/lyra_24_dvk_p20rf_defconfig b/boards/ezurio/lyra_24_dvk/lyra_24_dvk_p20rf_defconfig new file mode 100644 index 000000000000..363b0169db67 --- /dev/null +++ b/boards/ezurio/lyra_24_dvk/lyra_24_dvk_p20rf_defconfig @@ -0,0 +1,11 @@ +# Copyright (c) 2022 Silicon Labs +# Copyright (c) 2026 Ezurio LLC +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_ARM_MPU=y +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_GPIO=y +CONFIG_HW_STACK_PROTECTION=y +CONFIG_REGULATOR=y diff --git a/boards/ezurio/lyra_24_dvk/lyra_24_dvk_s10.dts b/boards/ezurio/lyra_24_dvk/lyra_24_dvk_s10.dts new file mode 100644 index 000000000000..bdcbe5fec90f --- /dev/null +++ b/boards/ezurio/lyra_24_dvk/lyra_24_dvk_s10.dts @@ -0,0 +1,15 @@ +/* + * Copyright The Zephyr Project Contributors + * Copyright (c) 2026 Ezurio LLC + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include "lyra_24_dvk.dtsi" + +/ { + model = "Ezurio Lyra 24 S10 DVK"; + compatible = "ezurio,lyra_24_dvk_s10", "silabs,efr32bg24"; +}; diff --git a/boards/ezurio/lyra_24_dvk/lyra_24_dvk_s10.yaml b/boards/ezurio/lyra_24_dvk/lyra_24_dvk_s10.yaml new file mode 100644 index 000000000000..f616ac98c3f9 --- /dev/null +++ b/boards/ezurio/lyra_24_dvk/lyra_24_dvk_s10.yaml @@ -0,0 +1,28 @@ +identifier: lyra_24_dvk_s10 +name: Lyra 24 S10 DVK +type: mcu +arch: arm +ram: 256 +flash: 728 +toolchain: + - zephyr + - gnuarmemb +supported: + - adc + - bluetooth + - clock_control + - comparator + - counter + - dac + - dma + - entropy + - gpio + - flash + - i2c + - led + - pinctrl + - pwm + - spi + - uart + - watchdog +vendor: ezurio diff --git a/boards/ezurio/lyra_24_dvk/lyra_24_dvk_s10_defconfig b/boards/ezurio/lyra_24_dvk/lyra_24_dvk_s10_defconfig new file mode 100644 index 000000000000..363b0169db67 --- /dev/null +++ b/boards/ezurio/lyra_24_dvk/lyra_24_dvk_s10_defconfig @@ -0,0 +1,11 @@ +# Copyright (c) 2022 Silicon Labs +# Copyright (c) 2026 Ezurio LLC +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_ARM_MPU=y +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_GPIO=y +CONFIG_HW_STACK_PROTECTION=y +CONFIG_REGULATOR=y diff --git a/boards/ezurio/lyra_24_dvk/pre_dt_board.cmake b/boards/ezurio/lyra_24_dvk/pre_dt_board.cmake new file mode 100644 index 000000000000..e0a341833fe4 --- /dev/null +++ b/boards/ezurio/lyra_24_dvk/pre_dt_board.cmake @@ -0,0 +1,6 @@ +# Copyright (c) 2021 Linaro Limited +# Copyright (c) 2026 Ezurio LLC +# 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") From c584b8601019e29361f7ecd03c66864c2eb1c1a3 Mon Sep 17 00:00:00 2001 From: Greg Leach Date: Sun, 11 Jan 2026 14:24:17 +0000 Subject: [PATCH 2234/3659] boards: ezurio: Add lyra_dvk support Add support for the Ezurio Lyra DVK board family. Signed-off-by: Greg Leach --- boards/ezurio/lyra_dvk/Kconfig.defconfig | 22 ++ boards/ezurio/lyra_dvk/Kconfig.lyra_dvk_p | 6 + boards/ezurio/lyra_dvk/Kconfig.lyra_dvk_s | 6 + boards/ezurio/lyra_dvk/board.cmake | 9 + boards/ezurio/lyra_dvk/board.yml | 11 + .../ezurio/lyra_dvk/doc/img/lyra_dvk_p.webp | Bin 0 -> 32682 bytes .../ezurio/lyra_dvk/doc/img/lyra_dvk_s.webp | Bin 0 -> 32106 bytes .../lyra_dvk/doc/lyra_dvk_common_1.rst.inc | 26 ++ .../lyra_dvk/doc/lyra_dvk_common_2.rst.inc | 17 ++ .../lyra_dvk/doc/lyra_dvk_common_3.rst.inc | 54 ++++ .../lyra_dvk/doc/lyra_dvk_common_4.rst.inc | 24 ++ boards/ezurio/lyra_dvk/doc/lyra_dvk_p.rst | 102 +++++++ boards/ezurio/lyra_dvk/doc/lyra_dvk_s.rst | 106 +++++++ boards/ezurio/lyra_dvk/lyra_dvk-pinctrl.dtsi | 90 ++++++ boards/ezurio/lyra_dvk/lyra_dvk.dtsi | 283 ++++++++++++++++++ boards/ezurio/lyra_dvk/lyra_dvk_p.dts | 24 ++ boards/ezurio/lyra_dvk/lyra_dvk_p.yaml | 27 ++ boards/ezurio/lyra_dvk/lyra_dvk_p_defconfig | 10 + boards/ezurio/lyra_dvk/lyra_dvk_s.dts | 24 ++ boards/ezurio/lyra_dvk/lyra_dvk_s.yaml | 27 ++ boards/ezurio/lyra_dvk/lyra_dvk_s_defconfig | 10 + boards/ezurio/lyra_dvk/pre_dt_board.cmake | 6 + 22 files changed, 884 insertions(+) create mode 100644 boards/ezurio/lyra_dvk/Kconfig.defconfig create mode 100644 boards/ezurio/lyra_dvk/Kconfig.lyra_dvk_p create mode 100644 boards/ezurio/lyra_dvk/Kconfig.lyra_dvk_s create mode 100644 boards/ezurio/lyra_dvk/board.cmake create mode 100644 boards/ezurio/lyra_dvk/board.yml create mode 100644 boards/ezurio/lyra_dvk/doc/img/lyra_dvk_p.webp create mode 100644 boards/ezurio/lyra_dvk/doc/img/lyra_dvk_s.webp create mode 100644 boards/ezurio/lyra_dvk/doc/lyra_dvk_common_1.rst.inc create mode 100644 boards/ezurio/lyra_dvk/doc/lyra_dvk_common_2.rst.inc create mode 100644 boards/ezurio/lyra_dvk/doc/lyra_dvk_common_3.rst.inc create mode 100644 boards/ezurio/lyra_dvk/doc/lyra_dvk_common_4.rst.inc create mode 100644 boards/ezurio/lyra_dvk/doc/lyra_dvk_p.rst create mode 100644 boards/ezurio/lyra_dvk/doc/lyra_dvk_s.rst create mode 100644 boards/ezurio/lyra_dvk/lyra_dvk-pinctrl.dtsi create mode 100644 boards/ezurio/lyra_dvk/lyra_dvk.dtsi create mode 100644 boards/ezurio/lyra_dvk/lyra_dvk_p.dts create mode 100644 boards/ezurio/lyra_dvk/lyra_dvk_p.yaml create mode 100644 boards/ezurio/lyra_dvk/lyra_dvk_p_defconfig create mode 100644 boards/ezurio/lyra_dvk/lyra_dvk_s.dts create mode 100644 boards/ezurio/lyra_dvk/lyra_dvk_s.yaml create mode 100644 boards/ezurio/lyra_dvk/lyra_dvk_s_defconfig create mode 100644 boards/ezurio/lyra_dvk/pre_dt_board.cmake diff --git a/boards/ezurio/lyra_dvk/Kconfig.defconfig b/boards/ezurio/lyra_dvk/Kconfig.defconfig new file mode 100644 index 000000000000..e7e04f727254 --- /dev/null +++ b/boards/ezurio/lyra_dvk/Kconfig.defconfig @@ -0,0 +1,22 @@ +# Copyright The Zephyr Project Contributors +# Copyright (c) 2026 Ezurio LLC +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_LYRA_DVK_P || BOARD_LYRA_DVK_S + +config LOG_BACKEND_SWO_FREQ_HZ + default 875000 + depends on LOG_BACKEND_SWO + +config FPU + default y if SOC_GECKO_USE_RAIL || BT + +if BT + +config MAIN_STACK_SIZE + default 3072 if PM + default 2304 + +endif # BT + +endif diff --git a/boards/ezurio/lyra_dvk/Kconfig.lyra_dvk_p b/boards/ezurio/lyra_dvk/Kconfig.lyra_dvk_p new file mode 100644 index 000000000000..1bb70468e16a --- /dev/null +++ b/boards/ezurio/lyra_dvk/Kconfig.lyra_dvk_p @@ -0,0 +1,6 @@ +# Copyright The Zephyr Project Contributors +# Copyright (c) 2026 Ezurio LLC +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_LYRA_DVK_P + select SOC_BGM220PC22HNA diff --git a/boards/ezurio/lyra_dvk/Kconfig.lyra_dvk_s b/boards/ezurio/lyra_dvk/Kconfig.lyra_dvk_s new file mode 100644 index 000000000000..d11b8b93609c --- /dev/null +++ b/boards/ezurio/lyra_dvk/Kconfig.lyra_dvk_s @@ -0,0 +1,6 @@ +# Copyright The Zephyr Project Contributors +# Copyright (c) 2026 Ezurio LLC +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_LYRA_DVK_S + select SOC_BGM220SC22HNA diff --git a/boards/ezurio/lyra_dvk/board.cmake b/boards/ezurio/lyra_dvk/board.cmake new file mode 100644 index 000000000000..42a606a3cf90 --- /dev/null +++ b/boards/ezurio/lyra_dvk/board.cmake @@ -0,0 +1,9 @@ +# Copyright The Zephyr Project Contributors +# Copyright (c) 2026 Ezurio LLC +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(jlink "--device=EFR32BG22C224F512IM40" "--reset-after-load") +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) + +board_runner_args(silabs_commander "--device=${CONFIG_SOC}") +include(${ZEPHYR_BASE}/boards/common/silabs_commander.board.cmake) diff --git a/boards/ezurio/lyra_dvk/board.yml b/boards/ezurio/lyra_dvk/board.yml new file mode 100644 index 000000000000..8410169b2914 --- /dev/null +++ b/boards/ezurio/lyra_dvk/board.yml @@ -0,0 +1,11 @@ +boards: + - name: lyra_dvk_p + full_name: Lyra P DVK + vendor: ezurio + socs: + - name: bgm220pc22hna + - name: lyra_dvk_s + full_name: Lyra S DVK + vendor: ezurio + socs: + - name: bgm220sc22hna diff --git a/boards/ezurio/lyra_dvk/doc/img/lyra_dvk_p.webp b/boards/ezurio/lyra_dvk/doc/img/lyra_dvk_p.webp new file mode 100644 index 0000000000000000000000000000000000000000..03c8fee64b2eda3bf839d2e03116d96d086e1c77 GIT binary patch literal 32682 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 literal 0 HcmV?d00001 diff --git a/boards/ezurio/lyra_dvk/doc/img/lyra_dvk_s.webp b/boards/ezurio/lyra_dvk/doc/img/lyra_dvk_s.webp new file mode 100644 index 0000000000000000000000000000000000000000..40e4a872d6d1270f66087c5dc54bb2f6e8f2d04f GIT binary patch literal 32106 zcmV(jK=!{fZcTCCxnqh$=khM`&Vh3~T|JdKfT*_W z;=5c~4j^jweSC*XolPzbN4Bsj^i=Vr;lL#{LPA^vg^I-mvoJzn zy8yQ)F~1!?V6i-NxCY>Vv&Sm(+D8_y>{Di+JTkHX z5Ejp3_Q_hA#WGXKB%Du63Xde&eJakt!ucp$*lX-Av#{6Lea4l@kps-dNyiSeIamoT z9Um1DBZ`4VUFoQ5uw+rm*922zjhL!GX3<^*iN)d~h>-*&!V+Lm$K;}mJ7q-XFu7e4 zi^YdbvQzv+zVmAfK|^_e7+G{Ff|gCPP!SCHR8bi)8@tSE8Emq<%|;g8Wsq15?hVOO zs#4xE*H{d0vp{nGN0MQ%5dnPt3xQRQz%orN)qzD@CDkNTjY1;0X)0C3Y%R<{USD?q&$B!1K9O{EARlvYkdd!pT`=ObGl1B>Q1({1s)MOso@FjDmY zYznm|bnB!?>;ie2#gl+5lZ-GYGs=Cy@av3J*~jQsKD{0GdM0KYh>^ zvXRz+%6~Ghx*Sz}ClnQMwXM2`ywoLj=u8#huV;n?`~i*74Faz)_?tE7-_W>^oRHg! zaRwL_rV(moEo71rYQ7Wn%5`H^vC89<*Okx-@F?cCa?kb@OJhacF^R>xi8PnY%?q~5HI|~+%jgo| z)PRv9pw&!!MVwQQdb0$t^=dE8cgQU51*tjjer!6I^@{Jkc@5p>u1NTNLM=`;p?nxlbrgId_F(<($jCvW9os$5kt5_#uO{ z{A1PXp^dZr3Cq3@09H^qAh37<0MO+DodGJi0l5M`kwBVBrK6&xDAO#cuo4MP(pq69 zm&=R)ng2(%22b}#@W0LaaB?qwp8)(9?C`AHY}YPul-y z?JfO->^u7p*5~&>|Npuf)Iq>y2B>xafn|I^3#)l4I{9*z0TXaOtq~z!S@l|4j>~)xBkn3W2%m!&qrjd(uobzS|_*%lfNzed0Cfs%%4Rm zURSq&jMy!o=S_7ECqd6dP1RjkJC6lLI+hjz6(%R9|0wE86wDcK}p8}Rk!{yW4*u! zV2T`Qk(IQ0JPkJC*{%{uRHFzI=u%w4Jr%_$Ds?-{?9SuCmoGj7g&qbmv zI<^1Db;+!g)g4u5GG^koE}xlUkO+9Rc^~SQL1I(3P^TP~w;G2uD=T)hi`n=)Hkl&z z@RcnLVlhX{gW{qG+i8rWM#nty8yy4Tf$#ZuSnWUu3*1U>38C<%UgH##7+E(#)R2LI z$%rlI#}<4dAocR_7Brqj+ zi!g@*Da=9P-Tyvj35BaRb}U$(*x^79Itf%)q4rW5x$!IlV|x@%L^H)CL4u;G$#z>2}!D5KAVTe-hwG z$Ba?c4y&II!uLyCk)l9%$#c`hXwHV9GJU!pc7FXy;A1+{nqbxKt=X7pDVRYclKZ17%Yb;vnA_u09=#&|Hfyuy0Uldd_ z=Hv+4L|E-7rhvVlp*(oVEY0~$4dkliCbZw64Uv$xtPV!Px5wNr9y4LPkZO(~n_gBKO zA<&Hg2?GQY{r|vMqopb6TBI)zN3-L<-ZPoROj|F5lp=~}DVBQ+1+;9m#hxbV$RodM!c6l@XW-UC5;*Hq% z(*`3iR2&f$8qB3*vN&H(qv0J&?Ud>{?SEt!*0MKyc6kX9!U)gHSEL*ljO4Bsk`XAWi{V;piz|M`1=j7(-zK*Qf3*w9aL;_=OqMj8_>25Q!u|{PI@pF_Tg`h<@L%azwnNWn1hi}E+ zR->wUvM(A5D4QV*PbF^I1VPXeW}lisY0*8`r(!&1rBEx+2L%eX&MJd{(#Pya?nCmZ z8l6kR*g)dScDET0McX6b*oxk^pkVU{2AFOD9uwt0I1%z}pGH68!Fu&%phxs^@68YV zIXmYRoUJ=^nJ~nnlo~v=EF=%)p>J6?xc#0eC~u$fdh61Z`QKsF0o4@Lkuc_^vC8T& zwWU{P%S(K9N-k`&aein_Z!bML^=&PaATyW&Kxot0o)~qWIpR z0sC-8=$Qkjy`yDus?f)Z<-9DvG}3=eSU^3`Hkv!*o1uQ}uSRbJ*W3u~iqFc4zNEuu zN;j%N2*N>E#HsIMLCycBmBt;JK)}3QBM>UsG*;?53SZlim10buxj*mY2BB`X& z($8X#ZBaZBf*XISC4_^j21(pNP#$@X(vgGMZU<0nA23aMir{-pC?OPuATjN73 z#QZ^*Ey*mTwqN-qcYGz7SwJ1II4f2x9m!XldS%&yt=my^;L4vit|X@>T3cY8_DD_q zJ6;}fY40kc297i&{FA9|z8mD7ro=a34p+l-a=l}qwwuy?e0+d6T#w(71MC~R$YY6h z=JSy{{Yr`w!rq4Jsz?4&Zp<2XgYJ^O*BsK8e!!YH+xgII)!f8g?wo4sN~$3P*pna_ z_WE2lNnh_8HvjTmq$lLO8Ny>*UPX0oiYI-6VPl9Jg~Hr3k&UW^`YG7bk}(O&!Q)bm zFE-n8z4@15{tN3e^_%h7o>QPc~;o&!5clxK1j~oaWoMZ^@RJQQ!!cXj1f-sx}HY=RJvAq;U z*}0QiMvwY^l~8H_bf!h~V98ubPgggn(9(-FrrlS!%dCr}NbIis= zzs>y)5hoe=?UG|&PR(`Ab^1hlqGK~(=Z-gw)Y_osNA)v|yl4(-;nJ#9tJvGWy4Xsn z59p}UXb?V4np#mJADY*@4n{}C1(u?>@Ubc_kGP;4L#?k7szY>EFSaD;0dY%o;IpHq z2vmTd!Ntm47q4&P5u+~Yy z5^f(n`Klt58v|4wbyBqEf!ILw_Q1hGJTTp$B{ z>_CD!2*d1tN7|l9Ob`|Vt$5Ovizyp*RI6k+{~y49+Xo4MRtTR!_c;$LB0%;U^`PE0 zpiZO&Lw&&mp3+z=IqPTGf_P$9+6q z6;RV50&>+u9Xvvj0)sN#cWPWi&Q0gNm24KREq|LRI&(V5f0IDB0XYNog8-A693twW z5%>NM1&T%kSl*U#96;9qZ^=mb#HYpX-0L!sPqV>Pxn%zJlut06H>~?xPI`uRPNOK~ z@V)WKIQq?bYr?+Pp&)hs^hEE&noxVU(mMtX@(%AEG`zmB7|MUn1bV=!(}?vc`2ckc z9)%fbw!P4ld6v(&H$J{tdTS(^W_7r3UP^9;@*@H89MQFnQTVgTF71@Xk-3}l$Q?Hu zDPM&xG7U5DX493bi@CSbO2Bd~KKBjb4SYoObodK!%+N4lLYF-%#0JIAP6*q5R6|O1 znj-At5{#k4v!Hg5_=94LGRUpDqM#=RKycZ4E>P5| zZ+>5x1(!%h->>A`cr=2mz7{scyx zx{@jITgk0OmmBC`e#k?{{*AxJiUUdFaxMdBtVQlI80ALImCjSEh9r~tdNUcG&|f;1 zY|bLWLD8Y_18ySvVX%si9a*KA93>$!%ysTHenZa*Bde^jY|>oL_-gA(+i?6MwDtEE zvtZFfmR6K7Pt-4nI|5@R%@j@Fs!eSI7wt2I(|~vs@k%q(FvZ9j=dweChyVmIK2|Oa zjY=Yy6MMFwzL?ZY`0;RlK0Xp2hK@1@8ZycajwhxB!+A2W?d5zs@9W70;^GULO~-j; zr}?nj>ZdJao6VBC(;e^mssf1I&msq>SKibWZBHi2{SoEyWeICBE={ij;tsgnWvDwc zSnDVs_60mbQ;ip17w7(Y1)2UtnZyNbVR~v5H#AP$v!@RU1+e9b?0qq?D;koL*}bU? zc=K&w^jydwf$^dqXW)QySF84lN;?S)bJXBaRfD$5l5|se7|l2DEt_u|Y~K<9yiYJl%?~Q&{0r=l=CNdcSTFuzHgj6m#&(opXVSUgDyrdusVQ3iBkdXp_Z#O#U zMjg#7bO@-w@UIsE)wIZ|-m}D9O~gM7v#}09DuXAeY%y0lNoUZnU0%)-3piZ?y-eCR z<5Zg|w@%;N@0|&f5>E#lO$G5gV+^m=el;6=7J1x?L~tf}&-dBFHJ^`~By{x%MmOvY zFPCBgRs%^GoYR&d+SJN8yBi%#NOh_P-`HIP*qPWVctuOf=G;=!uL#DT5ZG)He*YA| zm&{G3){>}us3~S&}Xb;e`AEW;5xn-Z`Z5SFkG#s~z)ZamS zYdlW2op|&?39p**&IAr=SW%9)^o$0$kS#s{o@*Is)L#9)hbh(RZu(D*Hd$>jefPZ% zE9#*=lz}J`yL+lMB@e*vH%4&gN`Ec=~{e` zbU1KBa%BQg<+kZmw=eg(!0qW8DtIV#u94S1AWE}UiY<({oC6xMUgO)@oZ)GZrKUHX zvEs`Qp&%5h&H;T9_~cIYu6m!!xiIJnZ+*l>spK<|V@%c<7DxB@K&EQmn>_1nxy52) zV(dP+7PW~yVZQLnQ>Zh>6J4yB$qPie=Y}Ep^nGpC*YV!H#8kr$=qc;7y(ICZUZ?Vb zmjcNF>9dw}knpg8;02%}*Qs<@u(?nL2&j;$@Fih|ra$^24Yd7?)yWhwNNy zxJDy`ECYn&fTwGY)R2)uT?$~2( z3M4z!AH7UuD=Gugq9a*DGxqrfA}vihoYwN81;ZO$L&>lbRrmpn+*A$JguQr$t zjrS#M14Qnh6ob$}K)~9X5VKAs?zdy}INweR7eCSqR7xYiFv$0kG3rCBHB2eu1*MIR zI}rr0ABItM#nH14S;urF`k^OY(=eWDCQ{x85eb)p5E?e$xV+d^RVC5(_oAD_&7a{i zURH`z9@=K0f4DIJE{QP1RMDft;&2y641Y+MP5lSFnKMNW>Ybv~G1kqLtg@{j{m#v0 z_BLj@7q;>jJ2?udwvn!!CJlrNqkU*!c%A_QN6u0gE?XfDy=o)$FoP(@k8%2#p%pD4 zRE3a)Mn*$w01K?`jk_tofCZ3jyQkWYT`I}-tc$|3F zeea{L3=;06EP`n*RVchIaOVR{H znK=OTcOsn@oZlQWDQ;tV#Z-OPb2|cL;}lZnb-Xkgam~y27&IY%yCgqK64e^wX&3M0 zSiee;GpjJq?4K_X*)iJ0k0x(8-G1Pr(A>D!KGJDlM1cV0O6(e4d>~E3Ml(d^RgND1 zkAH6|G#V8BC&xjNr;iVnb{0GnhIEhpQc2RroJzTmIvviZj7StI1O8es4TUJ~YyjJf2_D(dNVbuCuBdjZQ6eZ> zxRH|sY3u%tn_&YaJ5y%9Q7D2`(BUa7Vs$7vaD>g4jdGu;P`lO&kBBuCdbRUxa_9M!jym+N zA`{q8ZH*;F(LuZ2E-^am@GJNW-aA^LRpU>v;{Jd>;Mnd{;%4_mNQ&&IB;?{=!+9Z` zn`=zXBajhRJR0EF9*;k@Ps^4pus7L9PL$2=wPWW%Q)JldaJ*FXJ}or`Gr)^C(nr}p zyxo?;6nbpDze8}=97-2=^OM-gdRfR9ZKYgZA|4P>UlAZN5laXLmT1T3-Q}8{XcOBy{I|je+i;5V``$WgZe6ygbJ^b(&dtGUOXiP+7c9rYj)? zj^+e?t8hV;bKdg{4u(Tn9{UwBj(iJt1_;J*(!cXfxBH$=Lr+vgE)}RL*MqqN%6=j1 znzTqnJApgY@KdS`uxAq$AjzCiu04^`FZnNx_P!>s9`6zm4odBVR z=`^(c%j7D(a|a7LX7Wo&rbsxe9Su_o4GA5-UM!w)gKJ7Oa2X8Vxz?$}Z`J7l;S%|F zcQ4fUxXesde`buDVl*FEYxrk>Qx%vRS?lC!M1ADevTdd&PVk(f4#Pwk(wl#|;Wvxs zEUduO7qlJ)NVZJodLPlON$0>0y!eQg&J`v5n z)Z`!Cy$X{md0&o1GcKX9xSw{(&CwUU50U&@%@}hS4wh)0m!#{`&eM(kFXL9)QfncA z9IX8_S(7p!N7mj?e)OrvFN1l4O5JuF9R-t7nTs+|DUFH(kjU-7`&vs)J8Py-zZA>h z?-U$)jx>n7VZc7=^Vb-aU3-umV9uwyc z*YQLRHy3k%Ik1ChaHGpiz2Xrn_>hUGi^Q!^j48Uq3qG%GFPu%|){P#SBk(U+j#SC% zZQc<_mdN>`u-$z~8(t-{kHFbZQFlXC#!asf7lJslZU>KdyQ~o@(rC#cYlOg?XbMjm zUO3NQ3kbv#w@AE*3=+e_?zvT7@urKqXOr4Ia_-w57oY0WYOD-9w4ckitK_JBT7iSB zPvcK;FOLcwQC4=lo6|gG2&(a>V)um~Z7PbBd`hnMSfD@b+Dc`u;%V&SB6b4l=PKD3 zU|WY}6I{%XI>bH)oENKEc`SU2X&4CI2^Xv95J6s#%J5h8sGUYMT`*exu6cVRAa`>Bwe_ zc_6^oFoMfb%tcHz?L*08J!?N2d{8<=1K(&NFJ)q9dlBg#$d2$td@HO?fX8Qjh+#j_ zYBt5C-**?Cha#5x@%YGP(jB3JYnpNWe^x0R(1leYPDFSz>5KU*zCge$>bTI2Zyrw4 ztEJ>b>&Dw4-60H)#mM7_hTSOey}-~N@y`9X5Tl^iF?#S8LC~I+!9X%-X8(cenHh@1 z9lVDxS)M=iI9E9ZAg*bFJaTECbY&+vDyTT%j@Dys(oT0m4ZUGW>Cg5t#3V&$=F58Q zt1N*6`y9dG_V}OnROfk!*}fGnP30Y&Gay z66WD^3)DX*i(fRHuj4hUEyaG#@Dx^$lOxYu@Ut}HpFlyY zeCPa8+FF!h*>$l>z+?G-44^Q>XZ-!dvkP;ruqyTQRO&I2-#-+kKm02;ZtN?THw*q& zH@*F1LHVI-L~;b?ljxV2|8U=)Ayw_=FlLVapDqbA~1m%C-Zk z(=NQF!|uI_gA$9d#l9yToqO3fj8KOQ#^pa{>)-IlIZ3llW<`OlmI+66Llu=0&%B)N zSc;QyiJHZ_bgmUwSo+NL;P}BGLt+@XWFb}Kgz}C3_^3ND(2(@A%0p1D2HgKI5_uk4 zC>B4=Pqp)1*ZN!M#QXyw_fn?W;O60lFX7kz)9zH5&@j}6nTH+956D<<+s=krLHfNL zxJ#&SzKHIns6BydP}Uq8K}$-o8uVyJwQxk4;dyE#A(R=L_(g_c`ubRA-rWzt%Do}f zA4T7Y4Ni^jsnE9ufuU54AGz<}W7zJ|o`FLT2q|2*tHb?iN#O3Bk_Fx*9b77rr}O{T za+;l-3d=*>_q|Z%+yps`*;YUz-V|V z=M>p#%O44{qxDj(zZ~oUb{uNHw!|Uuqq(SfOfAae(D7YUerb=)Wtp<;-1{kAf!>2Y z?Z)k{4n>Y&z{Vh9{~12u&`mmt;b^rj&RIvgH9$E0lvWk*e^#*u%DiBvPwZM=iUfWD z4l^?O%-zK_O#)<8784GwV4gU+h6K6===AbSHB5vJdB&*aT1Z>nb4(oPPp z#wWw>wq_oVLU9os8dXhj%WN2{jHx#VxwC-&)Ml@99abb-CPv!TXkwAlM#;j9x)BAt zOM|i*;iQ%3JyfJqjR0&CXaznF5MlnmE_o#C9U)(PG@oSW!|3uN4?I)*vVR|n$-OQB z2sAUzON^iUkXz%52yX**hYr7Ft#G&I+8ZjQhJ+)}`)+kgz4K6z#2bhHsau^?bues| znqi2U^~wk&Bld)XdK3bCL>$|e15Ms#V-9QD(yBr$hlm9>+ejf?*51AL?o z%5N~Ljw3_Xs3P-iavas3x*mlUbzRkQsgVwh!ziUN_ zBbeJl(pb+wrMD0Wy150!5AXZ)o|5p|4g>fn16_YweD_j~E75&4%4-j27^oB}0`cky z$mK~(iL?|D4k2Hx0a3eN^3fpU>+G@%@XHwkP;CoWYi1wdd5|67Ma(Sk(Kh_KErVg^ zafT3by)YG`BCXP1M4~>Usmq->7+q=mHFR2R>mmf;4&7(VAl9KXYY(mXx|Vx61YA=o#BONKPydBrtO$LkyF<$M%t>)3vd$}yg z%_dK0hrE^jETOFEo~OS3Q+RCKMomYH+)Z#yJTxiYS|B03_>MsB+3coBm5CQX!RRy%d?5uqVOPO{Feq;zD$49z7!Q=7eD0=MwNG z!%%z~Bvzl}A@WT$U;gTqo@)U!Zc|KyI1GAWQ(sy_Y(j%3JyE#=LmL`&B#q-qw-~Pz zh0XtpOEk>M?X-zNM?4IN%VhdKVWXAOz-n=huY!~)_o{c7Mw376j!&~5jos>S1NsQ_ z#4)`|^6m7*S6o^8nm(#4IB;n_cS={c2H?iXiw;<}hMe1$(0?SIzv=G+fzH(>=bbWR z3Mk@Y1uIebhNry{qgFgf=xYacDKlsltZH)C$kuN_KKqU@CT!=otJ=k4`)FpFh($q( zkGxH7j@%v;PvGTtI+vO6!%|<=s=OC7g1^j1mU06cF@zfvPUA<7@s>E5tax@Zav4RM z=uzZzEsvpZ>ip~mW1OF|rRBtXh(O3b6RTziD?>3RBm;K*>70i=Bny`B-{B;upSfxU1Ma>#sFQaH}1Mgr7m8nhVGxWo^UcC=A%le8M(` z?Ckv2=2}KQ<|-){G-D`zZN#YPP^?+qQM#a|P{FOh(U8#RF4ZH4EQVPVeW%h|yPexU&d#81uOIN+L#)Jiv*1l`mI#dcI z^|V`kue%#Ry=l7=Q>9A{eD%u~mUU+h$iTUNf4c(^0PaU!K1N*K$D;@SM|palF%Cll z+d^l=nh6o{t$Q;k!TG;us=Ce;%yr zoOD7y8xci(jwsE>yoIs#CY%<(%LREHR;yft=B&D(aTv z94uoZh`KMU=ejG)E0U75JJ;Ai*n|iz9in~8gt(^WVR+-gJ@g0K}7(KYLSdQ^bUx z5j$bYS~uHMS!*2c0rK@ICzc6CT%2BX6$j24P2(4g*MQ_(8MIZrN{JA`Uy*Mfrf33{ zAK#)`9PTBV7sEJE-f))ql=!F9>LCv}+NTS;Y>NECnoO^;rJq(Mf^iA4KkK5o$mk%3 zsh?S+F{GqyMhGS?wBrH_yL6ewrtb;(GJ4=CD@2CbHtZEK@=@{3KW1HmMTw@Nl0?Cspl!8kN8W@ zI}#WKOq>@T%(bCCwx}Q%4lkms5qL4Vg$E&`@TT(B*g}Pg{s04;?n%T+gc_}oI7c63 zT@T5r4SqYPhI(q3R>7Gtt_OFKQa6l;?Ul;lIER%AkV75v(q66pBI8JMPDDa{7*&QH zr-fmbY-l(F=;f~hf!7Iqs) z3w6aIGFUkKDfCbGFKV*wk5`Rv$QVzDnOirz_7nG*MzZ`PRYE=G+}ZD3s~{>L)v;A- z39`+whfovBIdoi|{`&|e_aF1vHu(jDr)j<=S=#`*1!sXLtVUq<_-3-P>XH_&I-5o@)}@Bq12Bvdf1bP0g$K8u&3{lSmKm{JhvWa+%_B)^S1}-&+*F zKmU_&b*1EdtK0Ji0;3_m1`po7%_>j)_DG7xo%ee7vo*MyJD-p#&CP53G`Tuh6dweE zjTy|^wm<+sBm{z=Mg&9ClzGw)H=6zl?K z-lbqzvB=MX=lkVl%3>2)bjB{hqsd=sf`TV5 zp+t;q4QxO&VcO?{GVQ7}ckdlaQiTo)vZrH1O;dwYAoWmUQ$pjFuKrD)!f`=%*f}N- zkY>U$xaVR^_T3%~@fA~S;0G~e)DK*wqtC2#ylWEP(h| zomn0?AVyKO`d>3?Zxz{Y*=hZnPA#spR4J;tTC(BJ1%J>EG`k=s3ad3$n8ColkjHq*p7@%@*0t9uju(XbgPTpsa{< z&*&j)aMcO&^Dy#04D{h39I_S!iybi>Q)14%MsS8+xfN@voWWGJFf~GQ2Y+FKO{;*j zV=Rg;7BBz-r2lGZ)_!-JyhPJ<0P;2*Y}7>FAtNX!zQk4jh)KEK;H6T{XkIZjkxH4) z*}YC({DM2IQ2$$lmz4|5lVG`czI-ym2BJ!i?^Ar{Uf71#bzF*K7zv4Ip;!ja{8k`D zbaA-4JtU(xHJ20AZ{EUQ=6DZXEWOX6S?#U0jBGhqkiI7kId*OHCx3t>r<7JJ+b z(oac5wy!54;`3gaHXu-|&d)Q(ND7-oXJ%u0BNnkXpn}?>7Bd+0IZLqlNdyKXxiFKW9qO`WDHMc^j;HH6H)(baaHC%)ib z&4r;KDnf4B*dRSB?gKaGknMA$<@wYg&ZTD^xU0!$Ovemym(8+7?#iabmO1gZ8Ta@b zH*|do+EvWb7h@&pLrkiHaFn8zI35L zxJMVMsI~4xt}PB=&x0q70S9A{Ul;PzCxRC8kC{)0L@=o|-wVP(*w8R=cNC-JU-TBQ z`Et!GkTD9j4Z%a%fEMclj?MHO&9&;|`9P@>QA$QGL~||0ys!t+DmW!%01zV}3g>if z(a8Z}6<@Tc2)w5&rPq_%Pj*{3QaLo2W-F~&wLWBd9Z+0;_A6*o;&wxCJauD5*w*AS zWLq$mZQtUBP_JyB5i)K!<)F(xN1SfwOys#k0hQZsw~9}Lt*EPq0MM-#by|E7CDi%eXL^N(rPZa{jIa703C@#i zs#5>^$Ekks1hBWFB^^-t4zp0>hD{k*cIbN&P~o}6 zINs`q7_Vpn87M0MLildSxK@Jbc+{*Y!${mZR;1oeq@^$m8M-~wzyN&H*7{1=l!Dg4 zn{}{)Zi}(a{XvO=F9)k^xq%y~&N>7C<1prS#b|JIHL_f;EpKvTPZb=nT6c|QYVmM4 z&;?e%-}ld!Zr-&DD!1o;TA;oxF{{|b4q+IPac8ze@Oi2v2;u4Js8AOVxo~W|D30*4 zfHpg;u*MhDFWc|>)2klJHbnIH^lgv~cuLR$;yvnl8W0qUv@aA*D-+b}b7k&B@qY*I{NI+h_-L}<> z%XPM;xcf7fNwAt)p2xTf>+*s4$yiC@F_y3Wq}7BjR;GcjUU0^G^GV)f-<@!@gkA;7 z>pt_tPQzhoCf+;X)8^06lX*6)Y$3vB_HEw8lgmR5*E511tC|E3*Z}5c75$J%5!h`) zv|`=ptqaZWr)06PUAgE2Sy^IuOLwSlU@`_d!EQef_{^QAu7w5PgfBgipi_0Gi^K8!yc%8(36kYXbj1XN6h7 ziM>{Y#!Pg4I&jf*hIzcGK4-~T?kkvjlZVN^%-3}QqrBuK^P8o5{WTM{VHP#nGOb#8B`-t;1)0`U%?y}x77A_n}rrhk~#YcBDvOEmPY$A<1~!D;YnhE`DX#4 zdgTdF^@apc;Pp}D;PBgqJ#Z8h>-?&7?WlT;*0oRf*1B^1Bj|X}a6CJJw_O;oG7j!@c+elH{2D+u>Lm0UH}1ErY@0U$#0gz3c_m5&y#N z-LdyKD)3?%Vw2zzmgBzHhEJC$p9vCxTGF!C=n6vpj_!DCwpIpv3Kt?bE9%DNIPfBb zDP#WLhLU#l_FX%CnkGJ%V)FI~-x}jmG{;iU@(cmn6C~0?>Wd-(S(_n&wuyC@Yu#^a z*-X(-bUyCNusOJZ(=#BI$)CB+P)L%6D`@V=;eq0?hjPUj38~$@)3cMNjUsrrTm;3( zDr^C#t zd0Hh301GvCc%v~_=h4e~i>m$oI@s?y+4#$+-jhwGp5(H5dOMVWTs=h)V7| zPZEMJkMaynwoPN+n(a(M5D_6;!9Lpefn6(Nc00b>aa7r({TuhnYbr4a*Sp*ZO*3b; z6+6)stRoD}praeqG+I@7;|l(p4(Us1VIwW83XvGu;&TgAtByt46RR*|&Bl*wEcgw7 zy^paAs6xBq<OA!G_&0hQpvF{1cO#RMOPB^5I`2>3uo6d!H4%H0ZnieF_0i9TT%tS# zZ=;k!fri;T62Td!hX*Vhre;}^@rZ6XJo)!yDG5ZC%u{Qq^G2UVml%T=l2>XUV?6I> z#w}Dbo`}_AWfC|?j1+{-SZS|e%1`5k%C3v%(m-yh7IxOo-~Oy_OSI716Y8X{k+~;A za<(nVXCBvYcxxu!1-Q`Dsf1MisCuFwP}lmqP10;bSBK{%<(iAop|n}O&sq9YWl_cT zG=-pDY|#_{Kk2I6952a!{n>0;^awEV6*=+SM>JZ4UY^XLW6jycL{AKUoKt9PR7VE5 zBNee;`8Y2bhjAs21(*V1JT*B|c!VWo|9LUyIey?DuC)75i~UVDwQz&JetX`I zf2Lk@wD+^Pd&6XYR0`Lcu>vmoi{1ofGJCWr)ZAD$2&kIdGh_^2(q*Hb&5`S0im`o> zwboy%Lzs-r?eKx1?M?R!iQKS(mgf>IYJB<(vtrC6g}K6Lx=IwYwrDxrhW)RO5D<6@ zsE}Qt)^s#HeE6;S(9{-hjiYyy?*0vLArtst=0rD`%LeH;#LnLI5j|~7Nt>Lemfn^X zA4xU4=5z}Hlc9f^o=C``zl9kx32O}IqXhJPgfsUX2XL!Ea+L}6Dh*-$B zZRt1mYZA}Ho%U0W;h>DZ$mNmph!HNu5u!ae0)1@sxpOHJ!|MqrsQkq~QZZ=V zI!ROV4aY&^r0tT_ln07+pIK7Giem^~djZ&Eu1?AIsFoLZF99z%!|@;T{k}%h#prQk z3hI``myrA;sEtf243$OSxis8AQ+sfnkvfwTElA*+myvAoI+JmW)WL9(*``f6#IP%= zz+0;r2LUMTE-};Hk-4&fLzF4Xs~A~_>Ush3#NC1{^BGW@&T`0ukwp~G9#e0 zKkL?NqqQ#&s?Te(&A%G=1B#Sf0J&Sysl44g)Y`oDQ>>N(_$k%C=g>kKYQdLnr-%4I z+sgjIs-UxZ%clI73;KWMz#o3UOnv2MP77;41}lK@)msX#WbE&g;GL56hy>|;gF3}h zR#Bd~arQ$(f-J^Yh<7?fgp=71y~YBza1*G<`mNomshr&xgr8^k=cQo%Kp^_}E9cVp{>H_YzhL?nh zM+^vZV~^t*Bz3k^(It9skLesIbnWU})r*HGFrVv* zMx=;lfR<@1#9Udb4@+d#&mfn_64^nR9*`VQf&ribH zZYz|7ByB&R)oDWO)KtT$-k+jxW%LtzmcTiLoDa^(s{OII+5qt$Bn{A(g>dW}LQz|a zjpPI@@&Me{$s7(&l%U#pK4C3+0cWAB{eWc)aBpHV1g0Gtd|&!;R1O9q2X`VFCwgT~ z&qgJy$&~A7s-kcGS2+7NG{wV2vN;!;dY^-ky??G*KYLrAb=f~5j+Ru)xpe82dTIPP zcb7VVyy{gj?>kP`w8px!r$BrJyA-&>ie)8qr?PPC!J$pgnqfA>ccibxC}5?5sr1n7 z; zTpYh4DtDJtF7m*v0_e=AW=IU=#Fj|AxR>A?Ye+X3&ZfAs$c8GA8cR)ds+p+*(8{rNEeT&x#RMkaQMir_Co}L~! zp}L8{#cru73A^XeKqugAaV8qctK<&$CFs()Fl2sfuq$|FQ;BV7)*V&olyO=D6FD<@ zlTpXTKH{8mQP2o2Zk=d_D1yk-nm6lL#D`1%=csri}zZA#l2_e13#FagBf)hbaQ$beKL(mI%K#C3Mqsnv=RS3 zzo*7;nM5FNvfohr1Egcp>uyYh()_paz&WmQSP3$@Nmy8%y8k5ch|x*CdC zR8mM-yw2#E75^mOx=CBx^UQWyPf<6b+R{@vdRDTmMKVro;DUG`fH=3{*RoDa3l}^mCeOUgLrD%2p zZHUQF#((;T8KeK7d7=bJzE`N5Rz8xf>XWUBI*4Q{NMS01P!>;@_qPwSV&$OOMe4#A zLBBplVY&w=EWUa=%bIq|gzl`WDqn0VbESb!TV>;j-JMdCD(I<Blw6@!d44byblBn+;q`kU$L(a0sF7+%57qJ(d z#Trp=m8ac)yk=~u9dn{}wHjJz0bxC!!d8rVvDAwMhI#Ma3ew`lEx97R6AWooyTU>A z19^Y+oJYV?##DkpOD^nP9W;=0CpdJ z95iJ_J-3T&=p+knF``iShf<6wZ+*b~e1r`iYFepQ^X;*&`yyL+V6Q${Q+*xiaB|Cu z%(5s#i`f5W`-G~U_PbG;cBK0{fT%afnV7Rra;?N}-?JTP?*@dZU{t{<0q6Pv1=6)E zWp0b~VA&RXNP~|iyD{Kf96p2~CM$~(q49sq6`XiVo=(3N z;myH|@AwwTDUlB|i8GIAEdFX_il@%hI6#*?u~2&{T3RyDSywssRYQX}`TFqL*fJRe z5(X4Gtl3V&{WaKgmwa{9t==cuVHIm8@gEpNao|VGx5gpfVu#R(T>-sI3mglyewN`+ z9n}%)eXOz^r?p10No4TQqOdPr%2@?2NOM3(!skR0Ikc^ox3M7!fg=jo!>I5m3VJd& zP;Q&xS*h^92#ANl3`Ds<f2azjdK^HBN{mEnb=~qlyozf0)hi zlgredxf4y*7vc>XCfOW-vbL!eKO9~V&#m128Z!untc)z>b@Th}C1scjg-cHa3?*WP8q80xA>}f~b z@L%585b9gesjRm*Vzy*!DK6X;*?%$`D;|G=Vog)>O7#e^w>z+(?WKKBi3dkU2%vqINO zpF8Pc09VjnY{)Dt~ z`EPB2An%6NTcga5lxkUP!!2hqWuRbR#{i8pH%yp7vkG09lNedYw;Ssyez^2zR851d zq2clQf@zKYVp}r8EZa`KMnt+tQ*PcQlX0x zPT0;klMkw+^pMGs48weI-IbRQiB&#O?K|m#wkZE0Lh(KE5OKjL9j2P|H-BD5bF~v@ z*SD-+)-MFmAI|+|H&PF{cr+(M_&fd@vNf2qO3wp>yTUG@<+W#QxHoKHS~g=fwF5`v>u z)=ExqOM~$_>HK!-X;zS%4=qznz#m&}`QlMiJxjlVk{u0Xqpt$gp?M=SFXAntKgE|i z@$827sVsv~%TTfkNlMxZ`c7C?G?TfRjpe=}alvynvr$I$loR9&z`fQ=|7I|R^&XW^ zNkPaK1}OkWcB2`csM1H%A0(t@oyjm_gW+UNC5guvfKr-Y4xzGTdR~Qd$q30bLBMkN z{oAA5P?)QH)*m5b*Kk)TYMeE-czG@2S*bZ?(5`?hG~JVW`DS);xI_aX%|=&JkD&=M zVdEp}7oZ}Ko^^jE(5#YHkDMZEF9u68v5}iKlPNGdZGz@Y*O}=~}*^4pVDG)!o4%&qN*%RU3IJ)*UZ<8WK=M*ls&hecF7fzY&1LS{TyWO zbtWvEE#v+;HgKO4vb82b>`r#qxc`uTuh0zey}@lT{@4VoHg=7`Q^x}S3mN^*XtfBa zzZUIQ27dkR{_#_5=6rfBxtM^atASGez?3f3$eCxNBY$|5h#_$fIIYJ~I*LlD#$ zC?g)&GXK{o%+NTUu@$mT?OJUwkk=w=?}zl+E0WmagExv5l*MJ^12I=!s0$+FN+GAa zhOZ&?_}lG>0ZbqjrBxizh9!x|J1ytUkU@PP8(axRauZuS<^$@>(oS0CN`y;8z>2$~ z?TMe|{(QxQ2mgw6oS}^lTB!%Lvy8ejFRXM}!+%LBtIt#*xiQ8geWNI4iaH3UoGCOT z-fGWwmK%TzoW9r-xTq6@4<>%=*~Oe`a|T>HS#ZBC@Kuy2WqeI*9icj}CJjbnz&@w6 z3QughWuMPM1#KB8BN!WwxmYgcQE@}!nFybZQ1d`G{c+K*s5Ah!D%Y=p6o&9)Y1?;v^b{egZ_7%je>sAP4}Lbxu4KlzxaVwJ!LHs9m_KCB zrx`d6QfFgc(Jvkb-ix&XQ^XMG*9}RCQKHSPBU0<=<(cjPzZKh{fU?MedKl+Wih0~W zmZx&mg2Zd%YIbo7-5Z=fPs^flzmW|8Y;Dr_RKY&;qqZm|zeO{yrc4nv4J~5~^@x!9 zmM0qF^YdQG-3!31?;;!eKJOxZ$vA&0JKSNr+7rm7LvT;fr|cT$&!WaI(Ba<%`Pf}P z$nJ2pOZ2sx^VuS7e6z&$LI@rFh-&%EJQLE=m-qP53+!qgo}$cOW^vupnA&bBDhMk#Z5S3*D>~q}x*x3tFw}ACy3|K#pAzftRm{03R-=lHIXpQto)e@4+@s5tv=R2MJw6J=Z2)db@KIUxvSzA_OI8ZHp*eY zNDHy$L>N4F*uD@-lQ5+s$))_8$_Ve^+WJ;{Lw^U$KVehB96)5U;BBl(G;&ncazKXJ zJ#sI=(7I#0LXu~^0m72;sGEWvBPIGJ4c};fIW^fCsC>F!j$IIp#_BPOBFzq5gwuGs|>zpsE}Hy5v`|`8?3C7O(8w zvp0tE75hks+VB{& zBpa40?)60Z8DzvX#ZdK){2Us^t6mfZq6{NDEeFvl6jpsN_{`uny9?azsV-X;m-=*iXl zf6%(ly5*DdA1oBxUx$e<4hYAc`DLTu258Gt$YkDYRhzM|heRbHuA%1hL78Ud)cM1T zS>LN{08TlV**M8Am|RCe*4CEwgreTdw2CqBc)UDRUr}4-{Vf?!sc>?-YfJke0YBD3 zJ-#K47g{q#YOpQQO9fXLZ=nZ65@OIB+vFmcO?w)!N!3Iq@t^e4iKraTY9+y8GL}b` z_yNPdU9!exh-g-Bz%-L4TRlavb-ai=i|~X=XH_j%&u}Ne%Cv~s0rU)Z13==DQv4&; z*c4>vwE~0(Vb$)Vx-`cuB+;6pHQ<~FI#OjSj;>)H3}{QS#b8%OUEK{C;isK1uM9Js zjbrJbb%19M1%yK|Ux!F>dgP}w0SnLQp*w1@G=LDT)^zd4GW_Qzf;?MP7s@WxJP9aB zQEZXyyj14xOjMaL;V+CmyNel2H|Zsf@iYQR`zT0Z(eeNZJ)Uw4uxgur_2EFt`jpQU zfN#ktm2DW^*w_?2HBe}5RCUtf_65d5!Fo=}VgvOq8I>i92f?6`Ca{bGCbX$w{UL;Lz94yHhmkyv~FV%;JGmRh-15sZeo22{cYQ1VT{(1BV#bJ1gGN!r{_apM4N$*LQlh$` z{sal=&EOCauGnQ^T-gG5WWM)e;W|6WJbEL=GWT+(`BNQFJTo$10w$6(=@t9j-^GTz zyHOZ6vcbMxw<5b(>S>3NRfoB6IGP5&1u+ic?E_!HI0x+yi!l zfo)N~ehwaYjqyfDoEjN7CtkThfo0-JkY&#w7VnJ?gu>$t5?PXmI5syQ3qoCULbry* zyRWwxaT8PrNcmtZ`$Cxv*cM>@e&eZkSggN|HF%@fi8O+wKChfODU z#^)s`S9;gWUdk>FI`~Oe{`?I-z4h*2O2IEqt#L2}!w{EZE0o^=+;Lq8t3p|Z8FdD# zaruqMfV*iq%yjW0T#So;@MP}vAI*4Ep217r14Qw=+1K8(_q z3))4Rms<0}A(a>@kUl1e(C*9xs-yJ$V#B`BDyiBoGY(vYQC5M9JtWn%LKCyx%9nB0 ziOe*5gw@n#K+LU}fCY!Iq=%fz$EyU1RN-SA-v89E&H(BCHUMKR7iSgx2{yf9ykU2> zcV7BI^N($?Af{4m>`=VLuF18O5Cz`S2~P-oCPy1OtD95WiE-(HO6*y z3+O&e|D=Pxp~IdF2xprk^dYBOI_G+T!`OHE)9JNf-RtjHRdkUl?Cry4G2VyqR z!v{4vULDbt1>7Jh#HY7#0pMD8k?;pXb=BASyQZ5I~6 zY90a}_JL6-YHcMT*oByAjzy&`?z6?8=0!ls{VXHf8CY|@pOMul*&Tk%NyMRy=|w4N zDrf6XVa3m&Ny%-mn7Ibf;b|T`vfw;|YD%Ia4X@)n5zkEac6xy;PjV zk^6Q&gn4mR1FRoPO70;Z+*uzQY| z$HbQEV1D;ItP<)^twR{@$Zsr#=jO$J6*<}?J=qSCPkEAx$dL9;;3S!=7d6Gc=V(3| z3?9)T?h&{>2_YGt_t$~L=zoZLJ;#d2{}JRNn{daCW&$ReYB!z~#E~pvB~Gd>^yuuc z#4BlX4~s#GK1{-PcCAfL6!Ojc-J4>Ua3`aw*6sCbRVhzwYDI!>qE6ot2CF8EV{~fY z)p%ANa*VxDGi|($n4~XHSg=&vBeUL@l%_F`jD|lw6nTI(7mE2T zbA^eIkuSTdAFgI9FJL?SJ#sZWtbM9bKv>*LaZq@0MshcPm875B=(x@&PCdw*@CP)JSq#hz_saRT0cj_LV6#t5u$&e_^ja||+kHEIIVWhT*A&R}O zP^4idur_#t$}Vaf4eZ$-ngO0_*ZmXcxWmL25{e?{DKmk?jG~HnLcSy2q%Y%sX+b)~DLtK4VLtfqtjG-V=zJK@KdWYJekggb-vWV** z|IdW`+%Q1VQiTL?vaKICzw!9tLi~x}vl17eo!_+v+#TJ~KlI@%-N<#c=C*v(Oz7Z! zwc2=0M?xmyIjI{pbo%IV1@V6%Zm6NMlbdkQAJ5%N26i=-IB*M7?hp!EL)@Hq)U}fh@WIV%buhm!hU##+2a{`W+;&AUz`S zce|N=6MAzpG;4q}uY8ND(*CFiLo9Ck;L9Cca({cY_%1HL8%HDS^f?RHO1(7eG-3si z^h2xZn7ryunBuby}Q=A6-X*Jqg zQsM;U{sZ8K4I@k4JYc36j;b@}wbSMy<}W#2T^MYtT-CUEroMw`2fv7S?y7c5A}1Oj zaxyrqKRxK=;vUJ;6g5p-_?oi#n!Y65&qb18N%X1^xeZy^Pc^W#E#6D0irns=Pa_$!cKEM_4_@>U*(37eY=3i(g zvZCRG#A)1$=a7mY@;1l&&+@d^ji{KDd%;Q=oG@B&C2y7lfb!_Lv-7Eaeuoe@ulj(6 zgB;%dDyCs(MwDUcLg<}|iyHzLa3j{qQ;9{~$zxuNLI;4AER%JUGB^HQBV&XO0j3dj9#Y5dvtiEh~IH?ob6Ldici4sh5>DdSZ>&NB3yWLh3|1uH|ciK#wMomuGIqjE4 zt|A!o+`iFX2wS^^U$4iG6m)tr%Nz*5X!1kB1fs5N%?p)@ZB?c9dyH6nu99w8rIepu zx(W4P?i|)#y{MW#`@j*tQgFUYf8UAhrOj9KB%?y;1&Jq#Rfj;e1P6jfv!<#-iJpEl z3LQ*^=2IRMrv&CZGZZ&wURpD4ef=s#w<$K3+GN-y^snC5oLj;3dBi4!%Sa*zVhF*7 zn1ybA8k$6`X1V;ON`))KsKB$TjA?C$96hKz_Y0747kP`o{BY_o4XuYS!X&tmg}2cx zup;+n@*!*MaDG5Dh2=!pSB6>NBWog4X%?srNqjv;pH%M3;V?0l1C%`P$=IR z7#enj5tH$!%YYYsi-jg63q4<%1eH(#5N3t6W~*Y%5|rO%gj-<0u=t|=NDreTSkxFgTq+(00IW#Y5RqISGw;8E< zYztr6nCu_v&?Rqkhf@LzqNsY2zE)(4SK4Q3WU+MDU%xpBMxUvr+;Q->_5>$1aLIfU z3z!<_ylRI+F^Xjqyv%UI5Cq@)0DSN_fNbZrtjPd9z6fd9t$9SnC3rT$|5X2QST-y4 ze|Gwpy7TiV8+A?V>xEf&7d0#juh@2l=~63-H>ivpw2)ibhcvj6 z`w7VF?2L$So&oKnIUCMC`L3K&jmJ@Sh=e8?FQ7@K_*H2WbC!)mZWWl!o()IIl`W$d zDBiM#X&cw?ZAUoO$VT7>=s$G@Me)i=r6olu1gQKsI*z3L zYu09&9uc>+$+fiqxYgo>6wIK@1uS`O#z)iATu)&+Sz`fj#-tU@On)Mp*Fv^jw(F~4 zF8`g9#!8SUV*4|#9ll;trE-qkfwY+%{{)ld6YQ8LG+KMkcL08>du*asy=7thtM4f| z&bzh&g^M58pPtlBr)7V;7q=5&A^RplSWsh=aDg#}@^qSp%Wcb2-|?@i8?Hl3yx^9s zVw3SbID5u$SmQF>%YI|eFGv*YJMeH-zGAq{bb)(F{k~0&2IhKB=UgNRGK8>PF(}r< zUR%M4Z=N>y?VcSPNvXH|3!9^B#wGUopq_JGC;x&Lx<75(xLDZ#5jp|e1-g4PT3Z!x zj)7lbp?y&gs?o>hMsaQrnH+0;Y*B0ry%E?{OxSX=c-aN=D^}L$u2Tdracq2Wy#{3v zXx!`TU}D2@nAh*quPFHFipdv)18?>on$VQh4=UQB$dR#k-=tdJ_`rNWk9(M7!B3|= zzn*G_V@hgfB!^b}tH$x8BGc4P+FaiJhb{5TABAAo;h_sXqb;$?Aa{e zm9L9OiVH^j)ns#e@Y}vk}>L zGb=k|fk~O1;FLatJRwAnH{z*{H)S&Qi2_t$M1G^*cIc50z* zX13!n`H^R@^+S@E8&?72>Jyua$gV#(cG4Hsi0EHv$DUu#hq^8~RAQfD7-X<@e#taO zUl!nNv6R}?Z%<#2F|m{G>wW1B_JXF8f3Z2QHC@u*erLhs9H1P%@N5n~SyeU$dTzG? zUEyjk&PxdY!$v>BvD%zm#`yCnw~12=h_j8voajLBav%W-<~lStom^vn_?{Vfyq)Je zDawLp)eda_qkeZTcLm|>I3D`t1yy|~NA;fixy5kTuQPCm>vaN#4c~xo(M-B7A$}XR zz1@^1cX|S8Gy}Kl(-AnZ?-*7?g>KD1&=M91F~KVA4N3Z(k*Ik2zHVqXX5x;D@4VfDQGzIOdDTw76}YbnAtrY}a(m{G!1 z&BcA59glw8Yo*!&`b!6C(-68T>2bMqM7(c`YJG8~z8HPjZ_M2=AOpM{y!!OB)UNcb z(4>3=uMlRo-~u8W)&OxRYv^od7lunw=>~SGB)60s!hvRv&%O6gQuMW*)~*_6+VG0D ztO{E{4Wny(%qFWtba}HKK19EjSqQG*!D1t5Kqk_Q7wrQ`icA7O<@EfSHsMf*LjUY6 zr+U@5dzV2;WijdiV8USELBb%RlG&UeXx>X8mz=AM-uTe9-(?`d{!!5&!EivbaUvn3 zw+JdgX;M4g;v;(obRB2c*O77w_$!zEzhumO3_lyrfR>ALIWo@%8AfQd$}2D zmjZ%J_;>_@=pQOb_VAq=>*4vPjsd%rCOR$wj1Y7`qbvoSKIhv;!;Y}jfwaT(=8c+| zI$I=l<}ZeY6eQd)g|&F@?dEl^jI%2CU2#mg)bYcaAbu&AJ47ACj9{84pZDJp{O#`0 zyS|lwwVa8!`kdJR2 zN%sJHonZdGaAE`kdxPWdLk}$9JED4Jo8Ohqm|#0Q&wey>%{y8A0h+zUklskFGOj`7 zg=csc+g^gAw1Zc#zN-ceW7;+53o1MgekaPOwnP1{IXw7S>a?jP3-n;K$Q_moYRcRJ zp~Cm6w_~EG{~!R<_8Fn*d87>C8kbk1wB@HnB|;PJQusQ1#TsV06zYEmSEf$Cg&bBH zdEBts$!0nD|7C)D4u&?Fgri<>wGd0};GJ(Y?|W{udv{5aZpDFTi@##hKv^nqauBF_ zp}TF!=|4Rl-{8;G3|+}~&|U^FDTeeQFA4n;&Di2#s{`)m%Tb$0h3x3IY?XG^jB}=R za=egDsgV$v;KCI>QBN@1m*mXK3opr(esvr0+)yidhox4v#SW8w9BSD<6|6YtJ>*(J zTp-lSEyCrf$s}w;)#~l*BDP1m?3rcaowVKH3QZj5epbd@%s}eoL;{S*3Y!twBK) z`>?(UwzC(86SDqm{O)U1{p2%f-GEjWhadk^SUQ%~gwk;KAU`MC&V7}la*2raREQ#=d*B405Wzhq3NFt9v14}Kc@zp9;8JC)*HRxZ z+2>7FRB}Ys{euLL{WT>2ag{>+0jt0^=qz=}U?;R4hWYW4Qdis8fb<=~dW2AAfk634DCfB%^3bPtuNn*s&>=Cb2;a;W#FQZO@*aKXvtklWVt zPJ7-s@_>c{ejAku_7*!>=Ax}$Qgg zBGfy6Y_}Mud;d<|OXoB1)k|j{$b=~4SZXN?1iD*p|=vGc5H=^?tk+78|lB z_$8xte(z@^TJhQ0XX0~12kD`!KYFgj2W- zgx2vTUf%DJ5(P@Vo{cpsM4MVlS8g%qJkU=D|mJ)ZOEk`R=k}CxrW5mO-$dKGqd=qKIJaWNBAzzBB}6ZiVpW3 z#vg?D325NlayC4md=g841Sbwmgx!ndkTf%c%XAb#hICw)a)(JJhm$%gxO^-R=9&}0cK3#ECm)YMe zrn%wPtT8*mmE070-X8GWWAn4tV-Ql4l&xSmNa(zahJ)l9_W`b$0ZtdEiT*QpyKDED)xRD$ zYTpL=L7Q{O?daFxJxv9Bjj47%`-J2FIToAB)KwJ!jq*P}E*BJ}Uc0c@Xf{5|S!x5? zFvR{7pz%-fgUD{Sax+bxziYNLE{Hal#aF(mF)gt-dsOhf9Ke-BgL1dqGg6q-n%#AS zdGd&5XMRfkf!^apI$#+OPkZ!XmL&Q%D166uo<;fsNzbacV7)83ZTOF&acXw9iLg=7 zr_ZLFle<}GmxU}Q1fwiN?fH0)otZf9KokhZ&2@^|^zl@8MgvK)f()L0f(xFOQF8=K zPkRY%jHE*ARUnxv`6NkYo4-W~-Mv>~il$K{4M^B@&2^;abBZ@cQWEO~vEG;CT$e-* zZ&ir3v38u5MeS<#haG=@NRz!FOc(sD&w@Ja8B0B+-*R%z*UKsYEnxOY9uEfyyI5aN^dks*yc4cXqFAZUbI6}5|PSX#Iob~gsfEWlut@{CA5ELBdozK z^&kqW1n+|<=h#xCf@5Jo|Ox*U@U;%j%Kr zzivSYIbAK~1u5V#LC5943e2(lvbddFs;WJH^V~iMr`b!e8K7QB_1jh<^k>E$sP6~7 zdEgCwLlwaAhr&FO?Q!^t(lVSQ zIbd!V+%9;s1O^UP?neK$S<4&m<@@#w-mV2TiY6?<3Lt@?Fw2ucB1ULa29K~8tZdmn zGf2P~u`jno9$bam027zw`+^<$ z<-S84iZ$;ih@BaSw%@Pz4$+>C@=VtpcYKC!|`9jm817OiA?o$pK1 zi#-J1gJd>^UIcQ=grS?;V2sJPeBLY3_Xur5-Rq&G6S5SFcmeI#E|K42!HBJNvH;p`$7vhH(?qqv>NYc*Y!jKL9T5(Yz73XB`jiA zqF9kin8`}&6G1aIMeWKcq$^RWm3zpg@(3MoA(gx3-V3+8NA>P_!;nu%1oJ9?Zg zG$+3ee*oG5Qfa_ENJw3D3)T5Y+HbGN8lehh`jX*D`gl*tj9NET?0&7|ZkU8`Lm;5D zpijmVx8q1^y3ryP6nS-)l?%srG6APy*PGBu^+B0U(6Fe8l{ zZsBKH;jzIv6mm}{cCM+zTTp0|&RhrucTf%rD$pkC z-Kc(Z>>NtXSD5W9#?ndq0f$l!04#Co+M=+~PcW~KK|iRyCgd3lCB*Z>;(YgWYz)tY z|cBnkUJ|w`h3ZJRt;C@I`l$<>shrW)=go-Ie zs>f0^h~ghQ%W=#qc1*E1XKZ_xj2GI9KeMO~B(QeRO;a98G|=bDRxqjG^ zSq@I>36-Cw5bX;sh?uUJ8sRrc5K5BFT41AU1Q3KLr1sP~qM^@Ct5r~K>Wp+AY!u1} zbL@BCe?14M#$sLpX(FmTwdVl#d-w!K(ypwf84AtVB)z#U@fOKuc6`W%1E{yVya`4tMx*KApE_?2Q9BWJ zhpA?8c9hk_0XKr}QOt!n1@pW5AWXL=hXL&ScWFfv>UApupuiUEP3rWrtEBSVuNqa0{ri8y!_}BN(%yz|>5H?Ln6***o&_{JA?)u?MYbg-e#aC=jZ9ofF zV8LvQ{XNekW2a`lzDB#TZ0CPCihYu+2&|lZE}>}xf%aJ0^1Tq8jqQlC#xw zdxU*ytQ0A9)q2?1HjjZZveVG9&!c%lnj}o>ETEwL0E^5a(KZc!O)}^C!PyS)dh^h< z4*BwTEAiwTTuc2VvcC5IMK>Ey15|6dis)%=`Zpq9B;o28m+|mO?&uiFrCjjl@*hC4 zCm^Yv>EVFFt_Q+xC@9l`S8fGeH#{n=f*c-ec**rt8D*P3Q;wvwXM92_1xcnYL5&{M zSU(IIRBoWpyfhEP9^*JqNH}BBGU*qSf`6hsFBa(~Ig7~X(O>s0f)24(=H17*Pf6}` zRE+Q1)Wi%gvvBec=aUB4t&e8@8kXJ%Rtr}?7hBhAghIe~^5Djw^XLDGNbJgg`?)@X z>PBLc3upb{tM_0OSFzNREl}1RwP;~_8aj>+U=L^fuS3aJ@(wOfus^6cdL@;D_9V4| z5Z#CP3^UEJ!se)YePvA^kY|4hjIoH_T#f(v33I}4Mnl@#Yr=ibJn{|F2tCK@4`+BA z+_e4z>GQ4)&mqfusUtUG;E4c6ygf$}rOjem39A1hu%TQ@wZ7Pwn7=`TdQiF<`8vYRo{VjqEEZMAaQd;O6SOBWNr2cn_6(|}c zwGqPvompGGsZAwZVYEbk8?>4Yv&*n}yjd-%CRarie^ZdFm!Oh0B|$44a@W1{yP4Hl zL)xmJuQXQ*;q#Ex%cD>qh9~zBY$#NHpY7ey38epJv`>{it=TE(v63B2FKadHS)jnCW<^H_4^V!a?hes%ZDV>Ks*~8j-AC#sY$+&rF24>9tD*N_5 zVG<2>g>#gI%w3TVr2zsK6`QDk@IE+9Yeybv&ue5pLcJDVVI)KhyZblR>eZ3;hO)_8 zlWV9v7O99a!L1*hMZY_^Gd8v78a;-g%b|kA_=aa;a$d<@^ zaHlhYR;BEX`MG_h0}qjklc@DjLcAN=-1%JtB8;U5R6Vtkk}qMhK(@x#Cln|=M800SrX(pk(rCd@Kz{94OtvElTFtJ2K;dW7CRLEIC(D(+GEn{<+;T?-nNpqAsYaqOA*q7BPoVuzgqlW?=4j%NBmfat#0T zd1B3~{rR9P!1@D|>UkP*iP_F(5Nw~`k}NTdemM4AT9U51B@88xgF?GPruSJqWoyyz z(VQRZ-m8y2lGEMswHRW6IR#l;7?*(rXFh?8WHf?h(8GMC0St&|FLUK6{JvF`BX zeekXFY(0U(A0LoB9QDEeovNiqlL0)}_m7*O$CInLIBwEQ9SrUh@-6GRGtan&g-jlX zDP6z&=g60_>*snKnXVks>-Z=)m-;V+l0@tMwjzd45PtQ#BNp3Q;B*dY3^1!-Su|Av z(ojl1LN*WoY0&h0D*B1QKQM`~6Uyy^Cl0o8K;uGd|ed6_tE>+itK1HtSh)t~xqD_Av}& z?>N9t^o-#Z!}4)5Ak{*qK=)Z{we8me7115MTDp&|lcI9_Ycue6Qq+#@ZS7Dz?}qlz z`Zy6h#wl7*B)M<>a-vVgypw)V3#AL>TsSkSfR>m2rAxNg(VG=BD2KYYEsAYIQiltj zwxZ`lS&JJTmIZr=>l|9RGA5{3! z*wO>?_%~cV@zo5if&toa7$sLI<6qgRBj&n%lnUsz;6i;$I3IDA@9XgTW^q&!38A{0mD4`Q3(H|YX8Q!)^)PFFXui4jA|Fl=AFF76OYW!njLKtp{ZjsS-|s6%(%Kof;UJuo!0o*#WrFc$ z6H}nU{E}QtaWVTa)0WTIVZM7)Oo5F8rcMS?^r*tH-Q7M{X6boS)FV~?y<-PalYb(A z?4GOZE^++e;Y9h>IOb5w$`=FS2SFye`;eaK=QLEqT;oG9p@G=uYqCdsgs(U6+8{cI zGqtOTAdJu9k?cCdlj5}hKV3ZnkE5wYyW^#Wb0=PXa1S0;3OX3(3OkGI_RqcRmlI~O z%%$^+Ej_mQS}Vei^_;Zz8@VVAR(9rmDJX>Cekl{*{B=kF{tf~#QT~kX?9IUhOFIWa zjY=QCT+Se@3m*(U*CZ^0HgD|t*U#TKesk*x$t&;m<$>50;QTf+fe(3%Wir>vW+d9L zQ8n))MHufx1~Fhcd<1OX%9h*n&L5%efOPX_z(Iw*#jozsx?~F7EUal&O6AiKna8J;C?tH4@=;Bt{+&cT^6b@`EkJs z`5h@6nHfL;0000Xx~QgUkCDiuj7dNf@znokyWXw6=?iw+<}N>I$~>fsPV@5my + +&pinctrl { + timer0_default: timer0_default { + group0 { + pins = ; + drive-push-pull; + output-high; + }; + }; + + usart0_default: usart0_default { + group0 { + pins = , ; + drive-push-pull; + output-high; + }; + + group1 { + pins = ; + input-enable; + silabs,input-filter; + }; + }; + + usart1_default: usart1_default { + group0 { + pins = , ; + drive-push-pull; + output-high; + }; + + group1 { + pins = , ; + input-enable; + silabs,input-filter; + }; + }; + + iadc0_default: iadc0_default { + group0 { + silabs,analog-bus = ; + }; + }; + + i2c0_default: i2c0_default { + group0 { + pins = , ; + bias-pull-up; + drive-open-drain; + }; + }; + + euart0_default: euart0_default { + group0 { + pins = ; + drive-push-pull; + output-high; + }; + + group1 { + pins = ; + input-enable; + silabs,input-filter; + }; + }; + + itm_default: itm_default { + group0 { + pins = ; + drive-push-pull; + output-high; + }; + }; + + pti_default: pti_default { + group0 { + pins = , ; + drive-push-pull; + output-high; + }; + }; +}; diff --git a/boards/ezurio/lyra_dvk/lyra_dvk.dtsi b/boards/ezurio/lyra_dvk/lyra_dvk.dtsi new file mode 100644 index 000000000000..8dec8dde13c5 --- /dev/null +++ b/boards/ezurio/lyra_dvk/lyra_dvk.dtsi @@ -0,0 +1,283 @@ +/* + * Copyright The Zephyr Project Contributors + * Copyright (c) 2026 Ezurio LLC + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include "lyra_dvk-pinctrl.dtsi" + +/ { + chosen { + zephyr,bt-hci = &bt_hci_silabs; + zephyr,code-partition = &slot0_partition; + zephyr,console = &usart1; + zephyr,flash = &flash0; + zephyr,shell-uart = &usart1; + zephyr,sram = &sram0; + zephyr,uart-pipe = &usart1; + }; + + aliases { + led0 = &led0; + pwm-led0 = &pwm_led0; + sw0 = &button0; + watchdog0 = &wdog0; + + /* If enabled, MCUboot uses this for recovery mode entrance */ + mcuboot-led0 = &led0; + mcuboot-button0 = &button0; + }; + + leds { + compatible = "gpio-leds"; + + led0: led_0 { + gpios = <&gpioa 8 GPIO_ACTIVE_HIGH>; + }; + }; + + mikrobus_header: mikrobus-connector { + compatible = "mikro-bus"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0>; + gpio-map-pass-thru = <0 GPIO_DT_FLAGS_MASK>; + gpio-map = <0 0 &gpiob 0 0>, /* AN */ + <1 0 &gpioc 6 0>, /* RST */ + <2 0 &gpioc 3 0>, /* CS */ + <3 0 &gpioc 2 0>, /* SCK */ + <4 0 &gpioc 5 0>, /* MISO */ + <5 0 &gpioc 4 0>, /* MOSI */ + <6 0 &gpiob 4 0>, /* PWM */ + <7 0 &gpiob 3 0>, /* INT */ + <8 0 &gpiob 2 0>, /* RX */ + <9 0 &gpiob 1 0>, /* TX */ + <10 0 &gpiod 2 0>, /* SCL */ + <11 0 &gpiod 3 0>; /* SDA */ + }; + + pwmleds { + compatible = "pwm-leds"; + + pwm_led0: pwm_led_0 { + pwms = <&timer0_pwm 0 PWM_MSEC(20) PWM_POLARITY_NORMAL>; + }; + }; + + qwiic_connector: stemma-qt-connector { + compatible = "stemma-qt-connector"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0>; + gpio-map-pass-thru = <0 GPIO_DT_FLAGS_MASK>; + gpio-map = <0 0 &gpiod 2 0>, /* SCL */ + <1 0 &gpiod 3 0>; /* SDA */ + }; + + mikrobus_adc: zephyr,user { + io-channels = <&adc0 0>; + }; +}; + +&em23grpaclk { + clocks = <&lfxo>; +}; + +&em4grpaclk { + clocks = <&lfxo>; +}; + +&prortcclk { + clocks = <&lfxo>; +}; + +&rtccclk { + clocks = <&lfxo>; +}; + +&wdog0clk { + clocks = <&lfxo>; +}; + +&cpu0 { + clock-frequency = ; +}; + +&hfrcodpll { + clock-frequency = ; + clocks = <&hfxo>; + dpll-autorecover; + dpll-edge = "fall"; + dpll-lock = "phase"; + dpll-m = <3839>; + dpll-n = <3839>; +}; + +&hfxo { + ctune = <140>; + precision = <50>; + status = "okay"; +}; + +&lfxo { + ctune = <63>; + precision = <50>; + status = "okay"; +}; + +&gpio { + status = "okay"; +}; + +&gpioa { + status = "okay"; +}; + +&gpiob { + status = "okay"; +}; + +&gpioc { + status = "okay"; +}; + +&gpiod { + status = "okay"; +}; + +&timer0 { + status = "okay"; + + timer0_pwm: pwm { + pinctrl-0 = <&timer0_default>; + pinctrl-names = "default"; + status = "okay"; + }; +}; + +&usart0 { + compatible = "silabs,usart-spi"; + #address-cells = <1>; + #size-cells = <0>; + pinctrl-0 = <&usart0_default>; + pinctrl-names = "default"; + cs-gpios = <&gpioc 3 GPIO_ACTIVE_LOW>; + status = "okay"; +}; + +&usart1 { + compatible = "silabs,usart-uart"; + current-speed = <115200>; + pinctrl-0 = <&usart1_default>; + pinctrl-names = "default"; + status = "okay"; +}; + +&dcdc { + regulator-boot-on; + regulator-initial-mode = ; + status = "okay"; +}; + +&rtcc0 { + status = "okay"; +}; + +&adc0 { + pinctrl-0 = <&iadc0_default>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + channel@0 { + reg = <0>; + zephyr,acquisition-time = ; + zephyr,gain = "ADC_GAIN_1"; + zephyr,input-positive = ; + zephyr,reference = "ADC_REF_VDD_1"; + zephyr,resolution = <12>; + zephyr,vref-mv = <3300>; + }; +}; + +&i2c0 { + pinctrl-0 = <&i2c0_default>; + pinctrl-names = "default"; + status = "disabled"; +}; + +&wdog0 { + status = "okay"; +}; + +&euart0 { + pinctrl-0 = <&euart0_default>; + pinctrl-names = "default"; + status = "disabled"; +}; + +&trng { + status = "okay"; +}; + +&itm { + pinctrl-0 = <&itm_default>; + pinctrl-names = "default"; + swo-ref-frequency = ; +}; + +&bt_hci_silabs { + status = "okay"; +}; + +&pti { + pinctrl-0 = <&pti_default>; + pinctrl-names = "default"; +}; + +mikrobus_i2c: &i2c0 {}; + +mikrobus_spi: &usart0 {}; + +mikrobus_uart: &euart0 {}; + +zephyr_i2c: &i2c0 {}; + +zephyr_spi: &usart0 {}; + +&flash0 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + /* Reserve 48 KiB for the bootloader */ + boot_partition: partition@0 { + reg = <0x00000000 DT_SIZE_K(48)>; + label = "mcuboot"; + read-only; + }; + + /* Reserve 224 KiB for the application in slot 0 */ + slot0_partition: partition@c000 { + reg = <0x0000c000 DT_SIZE_K(224)>; + label = "image-0"; + }; + + /* Reserve 224 KiB for the application in slot 1 */ + slot1_partition: partition@44000 { + reg = <0x00044000 DT_SIZE_K(224)>; + label = "image-1"; + }; + + /* Set 16 KiB of storage at the end of the 512 KiB of flash */ + storage_partition: partition@7c000 { + reg = <0x0007c000 DT_SIZE_K(16)>; + label = "storage"; + }; + }; +}; diff --git a/boards/ezurio/lyra_dvk/lyra_dvk_p.dts b/boards/ezurio/lyra_dvk/lyra_dvk_p.dts new file mode 100644 index 000000000000..682069384965 --- /dev/null +++ b/boards/ezurio/lyra_dvk/lyra_dvk_p.dts @@ -0,0 +1,24 @@ +/* + * Copyright The Zephyr Project Contributors + * Copyright (c) 2026 Ezurio LLC + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include "lyra_dvk.dtsi" + +/ { + model = "Ezurio Lyra P DVK"; + compatible = "ezurio,lyra_dvk_p", "silabs,efr32bg22"; + + buttons { + compatible = "gpio-keys"; + + button0: button_0 { + gpios = <&gpioc 7 GPIO_ACTIVE_LOW>; + zephyr,code = ; + }; + }; +}; diff --git a/boards/ezurio/lyra_dvk/lyra_dvk_p.yaml b/boards/ezurio/lyra_dvk/lyra_dvk_p.yaml new file mode 100644 index 000000000000..a3fc634e1ecb --- /dev/null +++ b/boards/ezurio/lyra_dvk/lyra_dvk_p.yaml @@ -0,0 +1,27 @@ +identifier: lyra_dvk_p +name: Lyra P DVK +type: mcu +arch: arm +ram: 32 +flash: 224 +toolchain: + - zephyr + - gnuarmemb +supported: + - adc + - bluetooth + - clock_control + - comparator + - counter + - dma + - entropy + - gpio + - flash + - i2c + - led + - pinctrl + - pwm + - spi + - uart + - watchdog +vendor: ezurio diff --git a/boards/ezurio/lyra_dvk/lyra_dvk_p_defconfig b/boards/ezurio/lyra_dvk/lyra_dvk_p_defconfig new file mode 100644 index 000000000000..5ee421b84580 --- /dev/null +++ b/boards/ezurio/lyra_dvk/lyra_dvk_p_defconfig @@ -0,0 +1,10 @@ +# Copyright The Zephyr Project Contributors +# Copyright (c) 2026 Ezurio LLC +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_ARM_MPU=y +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_GPIO=y +CONFIG_HW_STACK_PROTECTION=y diff --git a/boards/ezurio/lyra_dvk/lyra_dvk_s.dts b/boards/ezurio/lyra_dvk/lyra_dvk_s.dts new file mode 100644 index 000000000000..b8f0f5db8b2b --- /dev/null +++ b/boards/ezurio/lyra_dvk/lyra_dvk_s.dts @@ -0,0 +1,24 @@ +/* + * Copyright The Zephyr Project Contributors + * Copyright (c) 2026 Ezurio LLC + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include "lyra_dvk.dtsi" + +/ { + model = "Ezurio Lyra S DVK"; + compatible = "ezurio,lyra_dvk_s", "silabs,efr32bg22"; + + buttons { + compatible = "gpio-keys"; + + button0: button_0 { + gpios = <&gpioa 6 GPIO_ACTIVE_LOW>; + zephyr,code = ; + }; + }; +}; diff --git a/boards/ezurio/lyra_dvk/lyra_dvk_s.yaml b/boards/ezurio/lyra_dvk/lyra_dvk_s.yaml new file mode 100644 index 000000000000..11b37581581a --- /dev/null +++ b/boards/ezurio/lyra_dvk/lyra_dvk_s.yaml @@ -0,0 +1,27 @@ +identifier: lyra_dvk_s +name: Lyra S DVK +type: mcu +arch: arm +ram: 32 +flash: 224 +toolchain: + - zephyr + - gnuarmemb +supported: + - adc + - bluetooth + - clock_control + - comparator + - counter + - dma + - entropy + - gpio + - flash + - i2c + - led + - pinctrl + - pwm + - spi + - uart + - watchdog +vendor: ezurio diff --git a/boards/ezurio/lyra_dvk/lyra_dvk_s_defconfig b/boards/ezurio/lyra_dvk/lyra_dvk_s_defconfig new file mode 100644 index 000000000000..5ee421b84580 --- /dev/null +++ b/boards/ezurio/lyra_dvk/lyra_dvk_s_defconfig @@ -0,0 +1,10 @@ +# Copyright The Zephyr Project Contributors +# Copyright (c) 2026 Ezurio LLC +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_ARM_MPU=y +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_GPIO=y +CONFIG_HW_STACK_PROTECTION=y diff --git a/boards/ezurio/lyra_dvk/pre_dt_board.cmake b/boards/ezurio/lyra_dvk/pre_dt_board.cmake new file mode 100644 index 000000000000..e0a341833fe4 --- /dev/null +++ b/boards/ezurio/lyra_dvk/pre_dt_board.cmake @@ -0,0 +1,6 @@ +# Copyright (c) 2021 Linaro Limited +# Copyright (c) 2026 Ezurio LLC +# 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") From 7bb9b42c99324ee04d53ac31658aec530bfec3f5 Mon Sep 17 00:00:00 2001 From: Dat Nguyen Duy Date: Fri, 9 Jan 2026 13:27:00 +0700 Subject: [PATCH 2235/3659] drivers: can_nxp_s32_canxl: switch to freeze mode before setting baudrate Switch canxl hw to freeze mode before setting baudrate Signed-off-by: Dat Nguyen Duy --- drivers/can/can_nxp_s32_canxl.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/can/can_nxp_s32_canxl.c b/drivers/can/can_nxp_s32_canxl.c index 6a38796ecda4..a39dcd852cc7 100644 --- a/drivers/can/can_nxp_s32_canxl.c +++ b/drivers/can/can_nxp_s32_canxl.c @@ -712,9 +712,13 @@ static int can_nxp_s32_set_timing(const struct device *dev, nxp_s32_zcan_timing_to_canxl_timing(timing, &can_time_segment); + Canexcel_Ip_EnterFreezeMode(config->instance); + /* Set timing for CAN instance*/ CanXL_SetBaudRate(config->base_sic, &can_time_segment); + Canexcel_Ip_ExitFreezeMode(config->instance); + return 0; } @@ -732,12 +736,16 @@ static int can_nxp_s32_set_timing_data(const struct device *dev, nxp_s32_zcan_timing_to_canxl_timing(timing_data, &can_fd_time_segment); + Canexcel_Ip_EnterFreezeMode(config->instance); + /* 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)); + Canexcel_Ip_ExitFreezeMode(config->instance); + return 0; } #endif From 478a0ffc6b94428f4fd734b1e24573b1ae39ef5c Mon Sep 17 00:00:00 2001 From: Dat Nguyen Duy Date: Wed, 7 Jan 2026 16:34:28 +0700 Subject: [PATCH 2236/3659] dts: arm: nxp: add canxl node for s32k566 Add CANXL node for S32K566 Signed-off-by: Dat Nguyen Duy --- dts/arm/nxp/nxp_s32k566.dtsi | 8 ++++++++ dts/arm/nxp/nxp_s32k566_m7.dtsi | 5 +++++ dts/arm/nxp/nxp_s32k566_r52.dtsi | 5 +++++ west.yml | 2 +- 4 files changed, 19 insertions(+), 1 deletion(-) diff --git a/dts/arm/nxp/nxp_s32k566.dtsi b/dts/arm/nxp/nxp_s32k566.dtsi index a50f189da15d..201148656739 100644 --- a/dts/arm/nxp/nxp_s32k566.dtsi +++ b/dts/arm/nxp/nxp_s32k566.dtsi @@ -962,5 +962,13 @@ status = "disabled"; }; }; + + canxl: can@6a01b000 { + compatible = "nxp,s32-canxl"; + reg = <0x6a01b000 0x1000>; + reg-names = "sic"; + status = "disabled"; + clocks = <&clock NXP_S32_CAN_PE_CLK>; + }; }; }; diff --git a/dts/arm/nxp/nxp_s32k566_m7.dtsi b/dts/arm/nxp/nxp_s32k566_m7.dtsi index 55cc97bb85eb..34112665aebf 100644 --- a/dts/arm/nxp/nxp_s32k566_m7.dtsi +++ b/dts/arm/nxp/nxp_s32k566_m7.dtsi @@ -461,3 +461,8 @@ &lpe_ftm { interrupts = <223 0>; }; + +&canxl { + interrupts = <97 0>; + interrupt-names = "rx_tx_mru_error"; +}; diff --git a/dts/arm/nxp/nxp_s32k566_r52.dtsi b/dts/arm/nxp/nxp_s32k566_r52.dtsi index d37db24bdc52..f674b44b63b4 100644 --- a/dts/arm/nxp/nxp_s32k566_r52.dtsi +++ b/dts/arm/nxp/nxp_s32k566_r52.dtsi @@ -411,3 +411,8 @@ &lpe_ftm { interrupts = ; }; + +&canxl { + interrupts = ; + interrupt-names = "rx_tx_mru_error"; +}; diff --git a/west.yml b/west.yml index acfd4a9b1bf3..1f0d439fc5f1 100644 --- a/west.yml +++ b/west.yml @@ -210,7 +210,7 @@ manifest: groups: - hal - name: hal_nxp - revision: 26ab97dc6e55e01a43db486ace71b57b6ee3ff06 + revision: 57b8fcad0337a803cbefd5ac635f8c5d37a7f806 path: modules/hal/nxp groups: - hal From abb4ca38454e34b4c4f31e6afcfea31e902b04aa Mon Sep 17 00:00:00 2001 From: Dat Nguyen Duy Date: Wed, 7 Jan 2026 16:37:33 +0700 Subject: [PATCH 2237/3659] drivers: can: add support canxl for s32k5 - The RX Message Descriptor in CANXL on newer SoC such as the S32K5 supports receiving both classic and FD frames, so enable the RX FIFO only for S32ZE SoC. - The CANXL bare-metal driver has significant changes, the current codebase for S32ZE need to be guarded and modified to support newer SoC - Expand the peripheral region to 1G to include the CANXL area. Signed-off-by: Dat Nguyen Duy --- drivers/can/Kconfig.nxp_s32 | 3 + drivers/can/can_nxp_s32_canxl.c | 254 +++++++++++++++++++++++++---- soc/nxp/s32/s32k5/m7/mpu_regions.c | 2 +- soc/nxp/s32/s32k5/m7/soc.h | 2 + soc/nxp/s32/s32k5/r52/soc.h | 2 + 5 files changed, 227 insertions(+), 36 deletions(-) diff --git a/drivers/can/Kconfig.nxp_s32 b/drivers/can/Kconfig.nxp_s32 index 011e3a7d3f45..4db29db933d1 100644 --- a/drivers/can/Kconfig.nxp_s32 +++ b/drivers/can/Kconfig.nxp_s32 @@ -11,9 +11,11 @@ config CAN_NXP_S32_CANXL Enable support for NXP S32 CANXL driver. if CAN_NXP_S32_CANXL + config CAN_NXP_S32_RX_FIFO bool "NXP S32 CANXL uses RX FIFO" default y + depends on SOC_SERIES_S32ZE help If this is enabled, NXP S32 CANXL uses RX FIFO. Otherwise NXP S32 CANXL uses RX Message Descriptor. @@ -32,4 +34,5 @@ config CAN_NXP_S32_MAX_TX range 1 128 help Maximum number of TX descriptors. + endif # CAN_NXP_S32_CANXL diff --git a/drivers/can/can_nxp_s32_canxl.c b/drivers/can/can_nxp_s32_canxl.c index a39dcd852cc7..9d601ad703ef 100644 --- a/drivers/can/can_nxp_s32_canxl.c +++ b/drivers/can/can_nxp_s32_canxl.c @@ -1,5 +1,5 @@ /* - * Copyright 2022-2024 NXP + * Copyright 2022-2024,2026 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -24,12 +24,14 @@ * vice versa. */ #ifdef CONFIG_CAN_NXP_S32_RX_FIFO +BUILD_ASSERT(IS_ENABLED(CONFIG_SOC_SERIES_S32ZE), + "The driver only supports RX FIFO for S32ZE platform"); #define RX_MBIDX_TO_ALLOC_IDX(x) (x) #define ALLOC_IDX_TO_RXMB_IDX(x) (x) #else #define RX_MBIDX_TO_ALLOC_IDX(x) (x - CONFIG_CAN_NXP_S32_MAX_TX) #define ALLOC_IDX_TO_RXMB_IDX(x) (x + CONFIG_CAN_NXP_S32_MAX_TX) -#endif +#endif /* CONFIG_CAN_NXP_S32_RX_FIFO */ /* @@ -39,10 +41,19 @@ #define TX_MBIDX_TO_ALLOC_IDX(x) (x) #define ALLOC_IDX_TO_TXMB_IDX(x) (x) -#define CAN_NXP_S32_TIMEOUT_MS 1 #define CAN_NXP_S32_MAX_BITRATE 8000000 #define CAN_NXP_S32_DATA_LENGTH 64 +#ifdef CONFIG_SOC_SERIES_S32ZE +/* Keep compatible with the old RTD */ +#define Canexcel_Ip_TxDataInfoType Canexcel_Ip_DataInfoType +#define Canexcel_Ip_RxMdConfigType Canexcel_Ip_DataInfoType +#else +#define SIZEOF_TX_MD (TX_HEADER_END + CAN_NXP_S32_DATA_LENGTH / sizeof(uint32_t)) +#define SIZEOF_RX_MD (RX_HEADER_END + CAN_NXP_S32_DATA_LENGTH / sizeof(uint32_t)) +#define CANXL_TX_HEADER_RTR_MASK 0x80000000u +#endif + #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 @@ -52,7 +63,9 @@ #define CAN_NXP_S32_RX_FIFO_WATERMARK 1 #endif -#if defined(CONFIG_CAN_FD_MODE) && defined(CONFIG_CAN_NXP_S32_RX_FIFO) +#if defined(CONFIG_CAN_FD_MODE) && \ + (defined(CONFIG_CAN_NXP_S32_RX_FIFO) || \ + defined(CANXL_MSG_DESCRIPTORS_RXCTRL_FDMODSEL_MASK)) #define CAN_NXP_S32_FD_MODE 1 #endif @@ -76,7 +89,11 @@ struct can_nxp_s32_config { CANXL_RXFIFO_Type * base_rx_fifo; CANXL_RXFIFO_CONTROL_Type *base_rx_fifo_ctrl; #endif + +#ifdef CONFIG_SOC_SERIES_S32ZE CANXL_MRU_Type * base_mru; +#endif + uint8 instance; const struct device *clock_dev; clock_control_subsys_t clock_subsys; @@ -86,7 +103,7 @@ struct can_nxp_s32_config { }; struct can_nxp_s32_tx_callback { - Canexcel_Ip_DataInfoType tx_info; + Canexcel_Ip_TxDataInfoType tx_info; can_tx_callback_t function; void *arg; }; @@ -94,7 +111,7 @@ struct can_nxp_s32_tx_callback { struct can_nxp_s32_rx_callback { struct can_filter filter; #ifndef CONFIG_CAN_NXP_S32_RX_FIFO - Canexcel_Ip_DataInfoType rx_info; + Canexcel_Ip_RxMdConfigType rx_info; #endif can_rx_callback_t function; void *arg; @@ -107,15 +124,24 @@ struct can_nxp_s32_data { ATOMIC_DEFINE(rx_allocs, CONFIG_CAN_NXP_S32_MAX_RX); struct k_mutex rx_mutex; struct can_nxp_s32_rx_callback rx_cbs[CONFIG_CAN_NXP_S32_MAX_RX]; + #ifndef CONFIG_CAN_NXP_S32_RX_FIFO +#ifdef CONFIG_SOC_SERIES_S32ZE Canexcel_RxFdMsg *rx_msg; +#else + uint32_t (*rx_msg)[SIZEOF_RX_MD]; +#endif #endif ATOMIC_DEFINE(tx_allocs, CONFIG_CAN_NXP_S32_MAX_TX); struct k_sem tx_allocs_sem; struct k_mutex tx_mutex; struct can_nxp_s32_tx_callback tx_cbs[CONFIG_CAN_NXP_S32_MAX_TX]; +#ifdef CONFIG_SOC_SERIES_S32ZE Canexcel_TxFdMsgType *tx_msg; +#else + uint32_t (*tx_msg)[SIZEOF_TX_MD]; +#endif #ifdef CONFIG_CAN_NXP_S32_RX_FIFO Canexcel_Ip_RxFifoFilterID_ADDR * rx_fifo_filter; @@ -217,6 +243,22 @@ static int can_nxp_s32_start(const struct device *dev) return 0; } +static int can_nxp_s32_abort_msg(uint8_t instance, int mb_idx) +{ +#if (CANXL_IP_HAS_ABORT == STD_ON) + /* Deactivation MD requires the MD is in EMPTY state first */ + if (Canexcel_Ip_AbortMD(instance, mb_idx)) { + return -EIO; + } +#endif + + if (Canexcel_Ip_DeactivateMD(instance, mb_idx)) { + return -EIO; + } + + return 0; +} + static int can_nxp_s32_stop(const struct device *dev) { const struct can_nxp_s32_config *config = dev->config; @@ -238,8 +280,7 @@ static int can_nxp_s32_stop(const struct device *dev) arg = data->tx_cbs[alloc].arg; if (atomic_test_and_clear_bit(data->tx_allocs, alloc)) { - if (Canexcel_Ip_DeactivateMD(config->instance, - ALLOC_IDX_TO_TXMB_IDX(alloc))) { + if (can_nxp_s32_abort_msg(config->instance, ALLOC_IDX_TO_TXMB_IDX(alloc))) { LOG_ERR("Can't abort message !"); }; @@ -467,11 +508,10 @@ static void can_nxp_s32_remove_rx_filter(const struct device *dev, int filter_id Canexcel_Ip_ExitFreezeMode(config->instance); #else - if (Canexcel_Ip_DeactivateMD(config->instance, mb_indx)) { + if (can_nxp_s32_abort_msg(config->instance, mb_indx)) { LOG_ERR("Can't abort message !"); }; #endif - data->rx_cbs[filter_id].function = NULL; data->rx_cbs[filter_id].arg = NULL; data->rx_cbs[filter_id].filter = (struct can_filter){0}; @@ -491,7 +531,6 @@ static int can_nxp_s32_add_rx_filter(const struct device *dev, struct can_nxp_s32_data *data = dev->data; int alloc = -ENOSPC; int mb_indx; - uint32_t mask; if ((filter->flags & ~(CAN_FILTER_IDE)) != 0) { LOG_ERR("unsupported CAN filter flags 0x%02x", filter->flags); @@ -519,6 +558,10 @@ static int can_nxp_s32_add_rx_filter(const struct device *dev, /* Set Rx Mb individual mask for */ mb_indx = ALLOC_IDX_TO_RXMB_IDX(alloc); + +#ifdef CONFIG_SOC_SERIES_S32ZE + uint32_t mask; + if (!!(filter->flags & CAN_FILTER_IDE)) { mask = filter->mask & CANXL_IP_ID_EXT_MASK; } else { @@ -529,8 +572,6 @@ static int can_nxp_s32_add_rx_filter(const struct device *dev, mask |= CANXL_MSG_DESCRIPTORS_MDFLT1FD_RTRMSK_MASK; #endif /* !CONFIG_CAN_ACCEPT_RTR */ - Canexcel_Ip_EnterFreezeMode(config->instance); - #ifdef CONFIG_CAN_NXP_S32_RX_FIFO uint32_t filter_id; @@ -544,26 +585,54 @@ static int can_nxp_s32_add_rx_filter(const struct device *dev, data->rx_fifo_filter[mb_indx].idAddrFilterL = mask; data->rx_fifo_filter[mb_indx].idAddrFilterH = filter_id; + Canexcel_Ip_EnterFreezeMode(config->instance); + can_nxp_s32_config_rx_fifo_filter(dev, mb_indx); -#else - data->rx_cbs[alloc].rx_info = (Canexcel_Ip_DataInfoType) { + + Canexcel_Ip_ExitFreezeMode(config->instance); +#else /* CONFIG_CAN_NXP_S32_RX_FIFO=n */ + data->rx_cbs[alloc].rx_info = (Canexcel_Ip_RxMdConfigType) { .frame = CANEXCEL_CLASIC_FRAME, .idType = !!(filter->flags & CAN_FILTER_IDE) ? CANEXCEL_MSG_ID_EXT : CANEXCEL_MSG_ID_STD, .dataLength = CAN_NXP_S32_DATA_LENGTH, }; + Canexcel_Ip_EnterFreezeMode(config->instance); + Canexcel_Ip_SetRxIndividualMask(config->instance, mb_indx, - data->rx_cbs[alloc].rx_info.frame, mask); + data->rx_cbs[alloc].rx_info.frame, mask); - Canexcel_Ip_ConfigRx(config->instance, mb_indx, filter->id, - &data->rx_cbs[alloc].rx_info); + Canexcel_Ip_ConfigRx(config->instance, mb_indx, filter->id, &data->rx_cbs[alloc].rx_info); Canexcel_Ip_ReceiveFD(config->instance, mb_indx, &data->rx_msg[alloc], FALSE); -#endif Canexcel_Ip_ExitFreezeMode(config->instance); +#endif /* CONFIG_CAN_NXP_S32_RX_FIFO */ + +#else /* CONFIG_SOC_SERIES_S32ZE=n */ + data->rx_cbs[alloc].rx_info = (Canexcel_Ip_RxMdConfigType) { + .frame = CANEXCEL_CLASIC_FD_FRAME, + .idType = !!(filter->flags & CAN_FILTER_IDE) ? + CANEXCEL_MSG_ID_EXT : CANEXCEL_MSG_ID_STD, + .MbSize = CAN_NXP_S32_DATA_LENGTH, + .IDEMask = !!(filter->flags & CAN_FILTER_IDE) ? 1 : 0, + .RTRRRSMask = !IS_ENABLED(CONFIG_CAN_ACCEPT_RTR) ? 1 : 0, + .IdH = filter->id, + }; + + Canexcel_Ip_EnterFreezeMode(config->instance); + + Canexcel_Ip_ConfigRx(config->instance, mb_indx, &data->rx_cbs[alloc].rx_info); + + Canexcel_Ip_SetMsgDescInterrupt(config->instance, mb_indx, TRUE); + + Canexcel_Ip_ReceiveFD(config->instance, mb_indx, &data->rx_msg[alloc][0]); + + Canexcel_Ip_ExitFreezeMode(config->instance); +#endif /* CONFIG_SOC_SERIES_S32ZE */ + unlock: k_mutex_unlock(&data->rx_mutex); @@ -649,13 +718,15 @@ static int can_nxp_s32_send(const struct device *dev, data->tx_cbs[alloc].function = callback; data->tx_cbs[alloc].arg = user_data; mb_indx = ALLOC_IDX_TO_TXMB_IDX(alloc); - data->tx_cbs[alloc].tx_info = (Canexcel_Ip_DataInfoType) { + + data->tx_cbs[alloc].tx_info = (Canexcel_Ip_TxDataInfoType) { .frame = !!(frame->flags & CAN_FRAME_FDF) ? CANEXCEL_FD_FRAME : CANEXCEL_CLASIC_FRAME, .enable_brs = !!(frame->flags & CAN_FRAME_BRS) ? TRUE : FALSE, .idType = !!(frame->flags & CAN_FRAME_IDE) ? CANEXCEL_MSG_ID_EXT : CANEXCEL_MSG_ID_STD, .priority = 0, + .retransmission = 0, .fd_padding = 0, .dataLength = data_length, .is_polling = FALSE @@ -673,9 +744,18 @@ static int can_nxp_s32_send(const struct device *dev, !!(frame->flags & CAN_FRAME_BRS) ? "BRS" : ""); k_mutex_lock(&data->tx_mutex, K_FOREVER); + +#ifdef CONFIG_SOC_SERIES_S32ZE /* Send MB Interrupt */ status = Canexcel_Ip_SendFDMsg(config->instance, mb_indx, &data->tx_cbs[alloc].tx_info, frame->id, (uint8_t *)&frame->data, &data->tx_msg[alloc]); +#else + Canexcel_Ip_SetMsgDescInterrupt(config->instance, mb_indx, TRUE); + + status = Canexcel_Ip_SendFDMsg(config->instance, mb_indx, &data->tx_cbs[alloc].tx_info, + frame->id, (uint8_t *)&frame->data, &data->tx_msg[alloc][0]); +#endif /* CONFIG_SOC_SERIES_S32ZE */ + k_mutex_unlock(&data->tx_mutex); if (status != CANEXCEL_STATUS_SUCCESS) { @@ -825,7 +905,7 @@ static void can_nxp_s32_err_callback(const struct device *dev, arg = data->tx_cbs[alloc].arg; if (atomic_test_and_clear_bit(data->tx_allocs, alloc)) { - if (Canexcel_Ip_DeactivateMD(config->instance, + if (can_nxp_s32_abort_msg(config->instance, ALLOC_IDX_TO_TXMB_IDX(alloc))) { LOG_ERR("Can't abort message !"); }; @@ -837,6 +917,8 @@ static void can_nxp_s32_err_callback(const struct device *dev, } } +#ifdef CONFIG_SOC_SERIES_S32ZE + static void nxp_s32_msg_data_to_zcan_frame(Canexcel_RxFdMsg msg_data, struct can_frame *frame) { @@ -875,6 +957,60 @@ static void nxp_s32_msg_data_to_zcan_frame(Canexcel_RxFdMsg msg_data, #endif /* CAN_RX_TIMESTAMP */ } +#else /* CONFIG_SOC_SERIES_S32ZE=n */ + +static void nxp_s32_msg_data_to_zcan_frame(uint32_t *msg_data, + struct can_frame *frame) +{ + uint8_t data_length = 0; + +#ifdef CONFIG_CAN_RX_TIMESTAMP + uint8_t timestamp_idx = RX_HEADER_END; +#endif + + memset(frame, 0, sizeof(*frame)); + + if (!!(msg_data[RX_ID] & CANXL_TX_HEADER_IDE_MASK)) { + frame->flags |= CAN_FRAME_IDE; + } + + if (!!(frame->flags & CAN_FRAME_IDE)) { + frame->id = (msg_data[RX_ID] & CANXL_IP_ID_EXT_MASK); + } else { + frame->id = ((msg_data[RX_ID] & CANXL_IP_ID_STD_MASK) + >> CANXL_IP_ID_STD_SHIFT); + } + + frame->dlc = (msg_data[RX_CONTROL] & CANXL_TX_HEADER_DLC_MASK) + >> CANXL_TX_HEADER_DLC_SHIFT; + + if (!!(msg_data[RX_CONTROL] & CANXL_TX_HEADER_FDF_MASK)) { + frame->flags |= CAN_FRAME_FDF; + } + + if (!!(msg_data[RX_CONTROL] & CANXL_TX_HEADER_BRS_MASK)) { + frame->flags |= CAN_FRAME_BRS; + } + + if (!!(msg_data[RX_ID] & CANXL_TX_HEADER_RTR_MASK)) { + frame->flags |= CAN_FRAME_RTR; + } else { + data_length = can_dlc_to_bytes(frame->dlc); + memcpy(frame->data, &msg_data[RX_FD_DATA], data_length); + } + +#ifdef CONFIG_CAN_RX_TIMESTAMP + timestamp_idx += data_length / 4U; + + if (data_length % 4U) { + timestamp_idx++; + } + + frame->timestamp = (uint16_t)msg_data[timestamp_idx]; +#endif /* CAN_RX_TIMESTAMP */ +} +#endif /* CONFIG_SOC_SERIES_S32ZE */ + static void can_nxp_s32_ctrl_callback(const struct device *dev, Canexcel_Ip_EventType eventType, uint32_t buffidx, const Canexcel_Ip_StateType *canexcelState) @@ -890,10 +1026,16 @@ static void can_nxp_s32_ctrl_callback(const struct device *dev, alloc = TX_MBIDX_TO_ALLOC_IDX(buffidx); tx_func = data->tx_cbs[alloc].function; LOG_DBG("%s: Sent Tx Mb %d", dev->name, buffidx); +#ifdef CONFIG_SOC_SERIES_S32ZE if (atomic_test_and_clear_bit(data->tx_allocs, alloc)) { +#else + if (atomic_test_and_clear_bit(data->tx_allocs, alloc) && + !Canexcel_Ip_GetTxBuffStatus(config->instance, buffidx, NULL, NULL)) { +#endif tx_func(dev, 0, data->tx_cbs[alloc].arg); k_sem_give(&data->tx_allocs_sem); } + #ifdef CONFIG_CAN_NXP_S32_RX_FIFO } else if (eventType == CANEXCEL_EVENT_RXFIFO_COMPLETE) { uint8_t queue_idx = ((config->base_rx_fifo_ctrl->RXFCSTA & @@ -929,7 +1071,12 @@ static void can_nxp_s32_ctrl_callback(const struct device *dev, } else if (eventType == CANEXCEL_EVENT_RX_COMPLETE) { alloc = RX_MBIDX_TO_ALLOC_IDX(buffidx); rx_func = data->rx_cbs[alloc].function; +#ifdef CONFIG_SOC_SERIES_S32ZE if (atomic_test_bit(data->rx_allocs, alloc)) { +#else + if (atomic_test_bit(data->rx_allocs, alloc) && + !Canexcel_Ip_GetRxBuffStatus(config->instance, buffidx, NULL, NULL, NULL)) { +#endif nxp_s32_msg_data_to_zcan_frame(data->rx_msg[alloc], &frame); LOG_DBG("%s: Received %d bytes Rx Mb %d, " @@ -945,8 +1092,13 @@ static void can_nxp_s32_ctrl_callback(const struct device *dev, rx_func(dev, &frame, data->rx_cbs[alloc].arg); +#ifdef CONFIG_SOC_SERIES_S32ZE if (Canexcel_Ip_ReceiveFD(config->instance, buffidx, &data->rx_msg[alloc], FALSE) != CANEXCEL_STATUS_SUCCESS) { +#else + if (Canexcel_Ip_ReceiveFD(config->instance, buffidx, + &data->rx_msg[alloc][0]) != CANEXCEL_STATUS_SUCCESS) { +#endif LOG_ERR("MB %d is not ready for receiving next message", buffidx); } } @@ -995,8 +1147,12 @@ static int can_nxp_s32_init(const struct device *dev) } /* Enable CANXL HW */ +#ifdef CONFIG_SOC_SERIES_S32K5 + IP_GPR_0->GPR_RWF_0 = IP_GPR_0->GPR_RWF_0 & 0x7fffffff; +#else IP_MC_RGM->PRST_0[0].PRST_0 &= ~(MC_RGM_PRST_0_PERIPH_16_RST_MASK | MC_RGM_PRST_0_PERIPH_24_RST_MASK); +#endif err = can_calc_timing(dev, &data->timing, config->common.bitrate, config->common.sample_point); @@ -1069,6 +1225,7 @@ static int can_nxp_s32_init(const struct device *dev) return 0; } +#ifdef CONFIG_SOC_SERIES_S32ZE static void can_nxp_s32_isr_rx_tx_mru(const struct device *dev) { const struct can_nxp_s32_config *config = dev->config; @@ -1088,6 +1245,21 @@ static void can_nxp_s32_isr_error(const struct device *dev) Canexcel_Ip_ErrIRQHandler(config->instance); } +#else /* CONFIG_SOC_SERIES_S32ZE=n */ +static void can_nxp_s32_isr_rx_tx_mru_error(const struct device *dev) +{ + const struct can_nxp_s32_config *config = dev->config; + + Canexcel_Ip_RxTxIRQHandler(config->instance); + + Canexcel_Ip_MruSpuriousIRQHandler(config->instance); + +#if (CANEXCEL_IP_HAS_DEDICATED_COM_ERR_EVT == STD_OFF) + Canexcel_Ip_ErrIRQHandler(config->instance); +#endif +} +#endif /* CONFIG_SOC_SERIES_S32ZE */ + static DEVICE_API(can, can_nxp_s32_driver_api) = { .get_capabilities = can_nxp_s32_get_capabilities, .start = can_nxp_s32_start, @@ -1144,7 +1316,8 @@ static DEVICE_API(can, can_nxp_s32_driver_api) = { UTIL_CAT(can_nxp_s32_isr_, \ DT_STRING_TOKEN_BY_IDX(node_id, prop, idx)), \ DEVICE_DT_GET(node_id), \ - DT_IRQ_BY_IDX(node_id, idx, flags)); \ + COND_CODE_1(DT_INST_IRQ_HAS_CELL(n, flags), \ + (DT_INST_IRQ(n, flags)), (0))); \ irq_enable(DT_IRQ_BY_IDX(node_id, idx, irq)); \ } while (false); @@ -1189,13 +1362,21 @@ static DEVICE_API(can, can_nxp_s32_driver_api) = { PINCTRL_DT_INST_DEFINE(n); \ \ __nocache Canexcel_Ip_StateType can_nxp_s32_state##n; \ - __nocache Canexcel_TxFdMsgType tx_msg##n[CONFIG_CAN_NXP_S32_MAX_TX]; \ - IF_DISABLED(CONFIG_CAN_NXP_S32_RX_FIFO, \ - (__nocache Canexcel_RxFdMsg rx_msg_##n[CONFIG_CAN_NXP_S32_MAX_RX];)) \ - IF_ENABLED(CONFIG_CAN_NXP_S32_RX_FIFO, \ - (__nocache Canexcel_RxFdMsg rx_fifo_##n[CAN_NXP_S32_RX_FIFO_DEPTH]; \ - static Canexcel_Ip_RxFifoFilterID_ADDR \ - rx_fifo_filter##n[CONFIG_CAN_NXP_S32_MAX_RX];)) \ + COND_CODE_1(CONFIG_SOC_SERIES_S32ZE, \ + (COND_CODE_1(CONFIG_CAN_NXP_S32_RX_FIFO, \ + (static Canexcel_Ip_RxFifoFilterID_ADDR \ + rx_fifo_filter##n[CONFIG_CAN_NXP_S32_MAX_RX]; \ + __nocache Canexcel_RxFdMsg \ + rx_fifo_##n[CAN_NXP_S32_RX_FIFO_DEPTH];), ()) \ + __nocache Canexcel_TxFdMsgType tx_msg##n[CONFIG_CAN_NXP_S32_MAX_TX]; \ + __nocache Canexcel_RxFdMsg rx_msg_##n[CONFIG_CAN_NXP_S32_MAX_RX]; \ + ), \ + (__nocache uint32_t tx_msg##n[CONFIG_CAN_NXP_S32_MAX_TX][SIZEOF_TX_MD]; \ + __nocache uint32_t rx_msg_##n[CONFIG_CAN_NXP_S32_MAX_RX][SIZEOF_RX_MD]; \ + __nocache Canexcel_Ip_MDhandleType \ + msg_desc_##n[CONFIG_CAN_NXP_S32_MAX_TX + CONFIG_CAN_NXP_S32_MAX_RX]; \ + ) \ + ) \ Canexcel_Ip_ConfigType can_nxp_s32_default_config##n = { \ .rx_mbdesc = (uint8)IS_ENABLED(CONFIG_CAN_NXP_S32_RX_FIFO) ? \ 0 : CONFIG_CAN_NXP_S32_MAX_RX, \ @@ -1206,6 +1387,8 @@ static DEVICE_API(can, can_nxp_s32_driver_api) = { .ctrlOptions = CANXL_IP_BUSOFF_RECOVERY_U32, \ .Callback = nxp_s32_can_##n##_ctrl_callback, \ .ErrorCallback = nxp_s32_can_##n##_err_callback, \ + IF_DISABLED(CONFIG_SOC_SERIES_S32ZE, \ + (.allocatedMsgDescList = &msg_desc_##n[0],)) \ IF_ENABLED(CONFIG_CAN_NXP_S32_RX_FIFO, \ (.is_rx_fifo_needed = (boolean)TRUE, \ .pRxFifoConfig = { \ @@ -1220,12 +1403,11 @@ static DEVICE_API(can, can_nxp_s32_driver_api) = { static struct can_nxp_s32_data can_nxp_s32_data_##n = { \ .can_state = (Canexcel_Ip_StateType *)&can_nxp_s32_state##n, \ .tx_msg = tx_msg##n, \ - IF_DISABLED(CONFIG_CAN_NXP_S32_RX_FIFO, \ - (.rx_msg = rx_msg_##n,)) \ - IF_ENABLED(CONFIG_CAN_NXP_S32_RX_FIFO, \ + COND_CODE_1(CONFIG_CAN_NXP_S32_RX_FIFO, \ (.rx_fifo = rx_fifo_##n, \ - .rx_fifo_filter = \ - (Canexcel_Ip_RxFifoFilterID_ADDR *)&rx_fifo_filter##n,))\ + .rx_fifo_filter = \ + (Canexcel_Ip_RxFifoFilterID_ADDR *)&rx_fifo_filter##n,),\ + (.rx_msg = rx_msg_##n,)) \ }; \ static struct can_nxp_s32_config can_nxp_s32_config_##n = { \ .common = CAN_DT_DRIVER_CONFIG_INST_GET(n, 0, CAN_NXP_S32_MAX_BITRATE), \ @@ -1235,7 +1417,9 @@ static DEVICE_API(can, can_nxp_s32_driver_api) = { DT_INST_REG_ADDR_BY_NAME(n, rx_fifo), \ .base_rx_fifo_ctrl = (CANXL_RXFIFO_CONTROL_Type *) \ DT_INST_REG_ADDR_BY_NAME(n, rx_fifo_ctrl),)) \ - .base_mru = (CANXL_MRU_Type *)DT_INST_REG_ADDR_BY_NAME(n, mru), \ + IF_ENABLED(CONFIG_SOC_SERIES_S32ZE, \ + (.base_mru = (CANXL_MRU_Type *) \ + DT_INST_REG_ADDR_BY_NAME(n, mru),)) \ .instance = CAN_NXP_S32_HW_INSTANCE(n), \ .clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(n)), \ .clock_subsys = (clock_control_subsys_t) \ diff --git a/soc/nxp/s32/s32k5/m7/mpu_regions.c b/soc/nxp/s32/s32k5/m7/mpu_regions.c index 551178ad753e..b8df97af446a 100644 --- a/soc/nxp/s32/s32k5/m7/mpu_regions.c +++ b/soc/nxp/s32/s32k5/m7/mpu_regions.c @@ -13,7 +13,7 @@ extern char _rom_attr[]; #endif #define REGION_PERIPHERAL_BASE_ADDRESS 0x40000000 -#define REGION_PERIPHERAL_SIZE REGION_512M +#define REGION_PERIPHERAL_SIZE REGION_1G #define REGION_PPB_BASE_ADDRESS 0xE0000000 #define REGION_PPB_SIZE REGION_1M diff --git a/soc/nxp/s32/s32k5/m7/soc.h b/soc/nxp/s32/s32k5/m7/soc.h index f12728ad99b0..148074e09331 100644 --- a/soc/nxp/s32/s32k5/m7/soc.h +++ b/soc/nxp/s32/s32k5/m7/soc.h @@ -18,4 +18,6 @@ #define IP_ADC_1_BASE IP_SARADC_1_BASE #define IP_ADC_2_BASE IP_LPE_SARADC_BASE +#define IP_CANXL_0__SIC_BASE IP_CANEXCEL__SIC_BASE + #endif /* _NXP_S32_S32K5_M7_SOC_H_ */ diff --git a/soc/nxp/s32/s32k5/r52/soc.h b/soc/nxp/s32/s32k5/r52/soc.h index 1a2fd107ea9d..d1e1d6464a75 100644 --- a/soc/nxp/s32/s32k5/r52/soc.h +++ b/soc/nxp/s32/s32k5/r52/soc.h @@ -20,4 +20,6 @@ #define IP_ADC_1_BASE IP_SARADC_1_BASE #define IP_ADC_2_BASE IP_LPE_SARADC_BASE +#define IP_CANXL_0__SIC_BASE IP_CANEXCEL__SIC_BASE + #endif /* _NXP_S32_S32K5_R52_SOC_H_ */ From 0c97804b3d2a6480a99d384b4f02f0f021f3c3e9 Mon Sep 17 00:00:00 2001 From: Dat Nguyen Duy Date: Wed, 7 Jan 2026 16:41:42 +0700 Subject: [PATCH 2238/3659] boards: nxp_s32k5xx_mb: add support for can Add support can (canxl) for nxp_s32k5xx_mb Signed-off-by: Dat Nguyen Duy --- .../shields/nxp_s32k5xx_mb/nxp_s32k5xx_mb.overlay | 15 +++++++++++++++ .../nxp_s32k5xx_mb/nxp_s32k5xx_mb_pinctrl.dtsi | 12 ++++++++++++ boards/shields/nxp_s32k5xx_mb/shield.yml | 1 + 3 files changed, 28 insertions(+) diff --git a/boards/shields/nxp_s32k5xx_mb/nxp_s32k5xx_mb.overlay b/boards/shields/nxp_s32k5xx_mb/nxp_s32k5xx_mb.overlay index f0c6404981b8..282b3cf431a3 100644 --- a/boards/shields/nxp_s32k5xx_mb/nxp_s32k5xx_mb.overlay +++ b/boards/shields/nxp_s32k5xx_mb/nxp_s32k5xx_mb.overlay @@ -10,6 +10,15 @@ chosen { zephyr,console = &lpuart3; zephyr,shell-uart = &lpuart3; + zephyr,canbus = &canxl; + }; + + can_phy0: can-phy0 { + compatible = "nxp,tja1463", "can-transceiver-gpio"; + enable-gpios = <&gpiop 2 GPIO_ACTIVE_HIGH>; + standby-gpios = <&gpiop 6 GPIO_ACTIVE_LOW>; + max-bitrate = <8000000>; + #phy-cells = <0>; }; }; @@ -19,3 +28,9 @@ current-speed = <115200>; status = "okay"; }; + +&canxl { + pinctrl-0 = <&canxl_default>; + pinctrl-names = "default"; + status = "okay"; +}; diff --git a/boards/shields/nxp_s32k5xx_mb/nxp_s32k5xx_mb_pinctrl.dtsi b/boards/shields/nxp_s32k5xx_mb/nxp_s32k5xx_mb_pinctrl.dtsi index 68ccd35b379d..f0e873108cdf 100644 --- a/boards/shields/nxp_s32k5xx_mb/nxp_s32k5xx_mb_pinctrl.dtsi +++ b/boards/shields/nxp_s32k5xx_mb/nxp_s32k5xx_mb_pinctrl.dtsi @@ -18,4 +18,16 @@ input-enable; }; }; + + canxl_default: canxl_default { + group1 { + pinmux = ; + input-enable; + }; + + group2 { + pinmux = ; + output-enable; + }; + }; }; diff --git a/boards/shields/nxp_s32k5xx_mb/shield.yml b/boards/shields/nxp_s32k5xx_mb/shield.yml index 084c53b6a7f6..17d3efb576a0 100644 --- a/boards/shields/nxp_s32k5xx_mb/shield.yml +++ b/boards/shields/nxp_s32k5xx_mb/shield.yml @@ -4,3 +4,4 @@ shield: vendor: nxp supported_features: - uart + - can From fd9b0b81b72931730cfda2c04d3678c55ac0a3a3 Mon Sep 17 00:00:00 2001 From: Camille BAUD Date: Thu, 8 Jan 2026 22:00:08 +0100 Subject: [PATCH 2239/3659] drivers: input: Add CH9350L USB keyboard driver Adds a driver that allows using CH9350 as a USB keyboard interface chip Signed-off-by: Camille BAUD --- drivers/input/CMakeLists.txt | 1 + drivers/input/Kconfig | 1 + drivers/input/Kconfig.ch9350l | 23 ++ drivers/input/input_ch9350l.c | 414 ++++++++++++++++++++++++++++ dts/bindings/input/wch,ch9350l.yaml | 42 +++ 5 files changed, 481 insertions(+) create mode 100644 drivers/input/Kconfig.ch9350l create mode 100644 drivers/input/input_ch9350l.c create mode 100644 dts/bindings/input/wch,ch9350l.yaml diff --git a/drivers/input/CMakeLists.txt b/drivers/input/CMakeLists.txt index bed126ff38db..7fcb28827b1f 100644 --- a/drivers/input/CMakeLists.txt +++ b/drivers/input/CMakeLists.txt @@ -10,6 +10,7 @@ zephyr_library_sources_ifdef(CONFIG_INPUT_ANALOG_AXIS_SETTINGS input_analog_axis zephyr_library_sources_ifdef(CONFIG_INPUT_BFLB_IRX input_bflb_irx.c) zephyr_library_sources_ifdef(CONFIG_INPUT_CAP12XX input_cap12xx.c) zephyr_library_sources_ifdef(CONFIG_INPUT_CF1133 input_cf1133.c) +zephyr_library_sources_ifdef(CONFIG_INPUT_CH9350L input_ch9350l.c) zephyr_library_sources_ifdef(CONFIG_INPUT_CHSC5X input_chsc5x.c) zephyr_library_sources_ifdef(CONFIG_INPUT_CHSC6X input_chsc6x.c) zephyr_library_sources_ifdef(CONFIG_INPUT_CST816S input_cst816s.c) diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig index d38892973617..39ff62f197eb 100644 --- a/drivers/input/Kconfig +++ b/drivers/input/Kconfig @@ -11,6 +11,7 @@ source "drivers/input/Kconfig.analog_axis" source "drivers/input/Kconfig.bflb" source "drivers/input/Kconfig.cap12xx" source "drivers/input/Kconfig.cf1133" +source "drivers/input/Kconfig.ch9350l" source "drivers/input/Kconfig.chsc5x" source "drivers/input/Kconfig.chsc6x" source "drivers/input/Kconfig.cst816s" diff --git a/drivers/input/Kconfig.ch9350l b/drivers/input/Kconfig.ch9350l new file mode 100644 index 000000000000..e73680ae3916 --- /dev/null +++ b/drivers/input/Kconfig.ch9350l @@ -0,0 +1,23 @@ +# Copyright (c) 2026 MASSDRIVER EI (massdriver.space) +# SPDX-License-Identifier: Apache-2.0 + +config INPUT_CH9350L + bool "WinChipHead CH9350L USB HID to UART control chip" + default y + depends on DT_HAS_WCH_CH9350L_ENABLED + depends on SERIAL_SUPPORT_INTERRUPT + select UART + select UART_INTERRUPT_DRIVEN + help + This option enables the driver for WinChipHead CH9350L USB HID to UART control chips. + +if INPUT_CH9350L + +config INPUT_CH9350L_FRAME_COUNT + int "Number of frames allocatable" + range 1 128 + default 2 + help + Number of input frames queueable at once. + +endif # INPUT_CH9350L diff --git a/drivers/input/input_ch9350l.c b/drivers/input/input_ch9350l.c new file mode 100644 index 000000000000..9f58faf0f162 --- /dev/null +++ b/drivers/input/input_ch9350l.c @@ -0,0 +1,414 @@ +/* + * Copyright (c) 2026 MASSDRIVER EI (massdriver.space) + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT wch_ch9350l + +#include +#include +#include +#include +#include + +#include +LOG_MODULE_REGISTER(input_ch9350l, CONFIG_INPUT_LOG_LEVEL); + +/* The theorical maximum is 72 */ +#define CH9350L_FRAME_SIZE_MAX 72 +#define CH9350L_FRAME_SIZE_MIN 8 +#define CH9350L_WAIT_TIMEOUT_MS 100 + +#define CH9350L_READBUF_SIZE 16 + +#define CH9350L_FRAME_HEAD_0 0x57 +#define CH9350L_FRAME_HEAD_1 0xAB +#define CH9350L_FRAME_HEAD_KEY_0 0x83 +#define CH9350L_FRAME_HEAD_KEY_1 0x88 +#define CH9350L_FRAME_HEAD_OFF 3 +#define CH9350L_FRAME_LENGTH_OFF 4 + +#define CH9350L_FRAME_VALUE_MAX (CH9350L_FRAME_SIZE_MAX - CH9350L_FRAME_HEAD_OFF - 4) + +#define CH9350L_FRAME_TYPE_MASK GENMASK(5, 4) +#define CH9350L_FRAME_TYPE_POS 4 +#define CH9350L_FRAME_TYPE_OTHER 0 +#define CH9350L_FRAME_TYPE_KB 1 +#define CH9350L_FRAME_TYPE_MOUSE 2 +#define CH9350L_FRAME_TYPE_MM 3 + +#define CH9350L_FRAME_MOUSE_BUTTON_BYTE 0 +#define CH9350L_FRAME_MOUSE_X_BYTE 1 +#define CH9350L_FRAME_MOUSE_Y_BYTE 3 +#define CH9350L_FRAME_MOUSE_RELMID 0x7FFF +#define CH9350L_FRAME_MOUSE_RELNEG 0x8000 + +#define CH9350L_RAWMOUSE_TO_REL(_val) (_val > CH9350L_FRAME_MOUSE_RELMID ? \ + -(CH9350L_FRAME_MOUSE_RELMID - (const int16_t)(_val - CH9350L_FRAME_MOUSE_RELNEG)) \ + : (const int16_t)_val) + +#define CH9350L_FRAME_MOUSE_BTN_LEFT 0x1 +#define CH9350L_FRAME_MOUSE_BTN_RIGHT 0x2 +#define CH9350L_FRAME_MOUSE_BTN_MID 0x4 +#define CH9350L_FRAME_MOUSE_BTN_4 0x8 +#define CH9350L_FRAME_MOUSE_BTN_5 0x10 +#define CH9350L_FRAME_MOUSE_BTN_6 0x20 +#define CH9350L_FRAME_MOUSE_BTN_7 0x40 +#define CH9350L_FRAME_MOUSE_BTN_8 0x80 + +static const uint8_t ch9350l_enable_status_frame[] = { + 0x57, 0xab, 0x12, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x20 +}; +static const uint8_t ch9350l_disable_status_frame[] = { + 0x57, 0xab, 0x12, 0x00, 0x00, 0x00, 0x00, 0xff, 0x80, 0x00, 0x20 +}; +static const uint8_t ch9350l_valid_start_of_status_frame[] = { 0x57, 0xab, 0x82 }; + +struct ch9350l_frame { + uint8_t data[CH9350L_FRAME_SIZE_MAX - CH9350L_FRAME_HEAD_OFF]; + size_t size; +}; + +#define CH9350L_MSGQBUF_SIZE (CONFIG_INPUT_CH9350L_FRAME_COUNT * sizeof(struct ch9350l_frame)) +#define CH9350L_MSGQBUF_TYPE char __aligned(4) + +struct ch9350l_data { + uint8_t frame_buffer[CH9350L_FRAME_SIZE_MAX]; + size_t frame_buffer_size; + bool frame_started; + uint8_t last_kb_values[CH9350L_FRAME_VALUE_MAX]; + uint8_t last_mouse_btns; + const struct device *dev; + struct k_work work; + struct k_msgq msgq; + CH9350L_MSGQBUF_TYPE msgq_buffer[CH9350L_MSGQBUF_SIZE]; +}; + +struct ch9350l_config { + const struct device *uart; + const int *kb_codemap; + const size_t kb_codemap_len; + const int *mouse_codemap; + const size_t mouse_codemap_len; +}; + +static uint32_t ch9350l_kb_map(const struct device *dev, uint32_t code) +{ + const struct ch9350l_config *config = dev->config; + const size_t code_map_len = config->kb_codemap_len / 2; + + for (size_t i = 0; i < code_map_len; i++) { + if (config->kb_codemap[i * 2] == code) { + return config->kb_codemap[i * 2 + 1]; + } + } + + return code; +} + +static void ch9350l_kb(const struct device *dev, const uint8_t *values, uint8_t length) +{ + struct ch9350l_data *data = dev->data; + uint8_t *lkbv = data->last_kb_values; + bool found; + + for (size_t j = 0; j < CH9350L_FRAME_VALUE_MAX; j++) { + found = false; + for (size_t i = 0; i < length; i++) { + if (lkbv[j] == values[i]) { + found = true; + } + } + if (!found && lkbv[j] != 0) { + if (input_report(dev, INPUT_EV_KEY, + ch9350l_kb_map(dev, lkbv[j]), 0, true, K_FOREVER)) { + LOG_ERR("Input failed to be enqueued"); + } + } + } + + for (size_t i = 0; i < length; i++) { + found = false; + for (size_t j = 0; j < CH9350L_FRAME_VALUE_MAX; j++) { + if (lkbv[j] == values[i]) { + found = true; + } + } + if (!found && values[i] != 0) { + if (input_report(dev, INPUT_EV_KEY, + ch9350l_kb_map(dev, values[i]), 1, true, K_FOREVER)) { + LOG_ERR("Input failed to be enqueued"); + } + } + } + + memcpy(lkbv, values, length); + memset(&lkbv[length], 0, CH9350L_FRAME_VALUE_MAX - length); +} + +static uint32_t ch9350l_mouse_map(const struct device *dev, uint8_t code) +{ + const struct ch9350l_config *config = dev->config; + const size_t code_map_len = config->mouse_codemap_len / 2; + + for (size_t i = 0; i < code_map_len; i++) { + if (config->mouse_codemap[i * 2] == code) { + return config->mouse_codemap[i * 2 + 1]; + } + } + + return code; +} + +static void ch9350l_mouse(const struct device *dev, const uint8_t *values, uint8_t length) +{ + struct ch9350l_data *data = dev->data; + const uint8_t button = values[CH9350L_FRAME_MOUSE_BUTTON_BYTE]; + const uint16_t raw_x = sys_get_le16(&values[CH9350L_FRAME_MOUSE_X_BYTE]); + const uint16_t raw_y = sys_get_le16(&values[CH9350L_FRAME_MOUSE_Y_BYTE]); + const int16_t x = CH9350L_RAWMOUSE_TO_REL(raw_x); + const int16_t y = CH9350L_RAWMOUSE_TO_REL(raw_y); + + input_report(dev, INPUT_EV_REL, INPUT_REL_X, x, true, K_FOREVER); + input_report(dev, INPUT_EV_REL, INPUT_REL_Y, y, true, K_FOREVER); + + for (size_t i = 0; i < 8; i++) { + if (button & BIT(i) && !(data->last_mouse_btns & BIT(i))) { + if (input_report(dev, INPUT_EV_DEVICE, + ch9350l_mouse_map(dev, BIT(i)), 1, true, K_FOREVER)) { + LOG_ERR("Input failed to be enqueued"); + } + } else if (data->last_mouse_btns & BIT(i) && !(button & BIT(i))) { + if (input_report(dev, INPUT_EV_DEVICE, + ch9350l_mouse_map(dev, BIT(i)), 0, true, K_FOREVER)) { + LOG_ERR("Input failed to be enqueued"); + } + } else { + /* Dont care about other cases */ + } + } + data->last_mouse_btns = button; +} + +static void ch9350l_input_work_handler(struct k_work *item) +{ + struct ch9350l_data *data = CONTAINER_OF(item, struct ch9350l_data, work); + struct ch9350l_frame frame; + uint8_t fd_label; + uint8_t *fd_value; + uint8_t fd_sum; + uint8_t sum; + + while (k_msgq_get(&data->msgq, &frame, K_NO_WAIT) == 0) { + sum = 0; + fd_label = frame.data[0]; + fd_value = &frame.data[1]; + fd_sum = frame.data[frame.size - 1]; + + for (int i = 0; i < frame.size - 2; i++) { + sum += fd_value[i]; + } + if (sum != fd_sum) { + LOG_ERR("Frame checksum is invalid"); + continue; + } + + switch ((fd_label & CH9350L_FRAME_TYPE_MASK) >> CH9350L_FRAME_TYPE_POS) { + case CH9350L_FRAME_TYPE_KB: + ch9350l_kb(data->dev, fd_value, + min(frame.size - 3, CH9350L_FRAME_VALUE_MAX)); + continue; + case CH9350L_FRAME_TYPE_MOUSE: + ch9350l_mouse(data->dev, fd_value, + min(frame.size - 3, CH9350L_FRAME_VALUE_MAX)); + continue; + case CH9350L_FRAME_TYPE_MM: + default: + LOG_ERR("Unknown or unsupported input type"); + continue; + } + } +} + +static int ch9350l_queue_frame(struct ch9350l_data *dev_data, uint8_t *data, size_t size) +{ + int ret; + struct ch9350l_frame frame = { + .size = size, + }; + memcpy(frame.data, data, size); + + ret = k_msgq_put(&dev_data->msgq, &frame, K_NO_WAIT); + if (ret < 0) { + LOG_WRN("Frame dropped, queue full"); + } + + k_work_submit(&dev_data->work); + + return ret; +} + +static uint8_t ch9350l_is_valid_frame(uint8_t *data, size_t size) +{ + const uint8_t fd_id = data[2]; + const uint8_t fd_length = data[3]; + + /* Too small to be valid */ + if (size < CH9350L_FRAME_SIZE_MIN) { + return 0; + } + + /* Drop non-input frames */ + if (fd_id != CH9350L_FRAME_HEAD_KEY_0 && fd_id != CH9350L_FRAME_HEAD_KEY_1) { + return 0; + } + + /* We don't have the full frame yet */ + if (fd_length > (size - CH9350L_FRAME_LENGTH_OFF)) { + return 0; + } + + return fd_length; +} + +static void ch9350l_input_callback(const struct device *dev_uart, void *user_data) +{ + struct ch9350l_data *data = (struct ch9350l_data *)user_data; + uint8_t read_buffer[CH9350L_READBUF_SIZE]; + int read; + uint8_t frame_size; + + uart_irq_update(dev_uart); + if (!uart_irq_rx_ready(dev_uart)) { + return; + } + + while (true) { + read = uart_fifo_read(dev_uart, read_buffer, CH9350L_READBUF_SIZE); + if (read <= 0) { + break; + } + if (data->frame_buffer_size + read >= CH9350L_FRAME_SIZE_MAX) { + LOG_ERR("Maximum frame size exceeded"); + data->frame_started = false; + data->frame_buffer_size = 0; + continue; + } + memcpy(&data->frame_buffer[data->frame_buffer_size], read_buffer, read); + data->frame_buffer_size += read; + for (size_t offset = max((int)data->frame_buffer_size - read - 2, 0); + offset < (data->frame_buffer_size - 1); offset++) { + if (data->frame_buffer[offset] != CH9350L_FRAME_HEAD_0 + || data->frame_buffer[offset+1] != CH9350L_FRAME_HEAD_1) { + continue; + } + if (data->frame_started) { + frame_size = ch9350l_is_valid_frame(data->frame_buffer, + data->frame_buffer_size); + if (frame_size) { + ch9350l_queue_frame(data, + &data->frame_buffer[CH9350L_FRAME_LENGTH_OFF], + frame_size); + } + } + data->frame_started = true; + memcpy(data->frame_buffer, &data->frame_buffer[offset], + data->frame_buffer_size - offset); + data->frame_buffer_size = data->frame_buffer_size - offset; + break; + } + } + + if (data->frame_started) { + frame_size = ch9350l_is_valid_frame(data->frame_buffer, data->frame_buffer_size); + if (frame_size) { + ch9350l_queue_frame(data, &data->frame_buffer[CH9350L_FRAME_LENGTH_OFF], + frame_size); + data->frame_started = false; + data->frame_buffer_size = 0; + } + } + + if (read < 0) { + LOG_ERR("Error reading UART"); + } +} + +static int ch9350l_init(struct device const *dev) +{ + const struct ch9350l_config *config = dev->config; + struct ch9350l_data *data = dev->data; + k_timepoint_t end_timeout = + sys_timepoint_calc(K_MSEC(CH9350L_WAIT_TIMEOUT_MS)); + size_t check_p = 0; + int ret = 0; + char c; + + data->dev = dev; + data->frame_buffer_size = 0; + data->frame_started = false; + k_work_init(&data->work, ch9350l_input_work_handler); + k_msgq_init(&data->msgq, data->msgq_buffer, sizeof(struct ch9350l_frame), + CONFIG_INPUT_CH9350L_FRAME_COUNT); + + if (!device_is_ready(config->uart)) { + LOG_ERR("UART device not ready"); + return -ENODEV; + } + + for (int i = 0; i < sizeof(ch9350l_enable_status_frame); i++) { + uart_poll_out(config->uart, ch9350l_enable_status_frame[i]); + } + + while ((ret == 0 || ret == -1) && !sys_timepoint_expired(end_timeout) + && check_p < ARRAY_SIZE(ch9350l_valid_start_of_status_frame)) { + ret = uart_poll_in(config->uart, &c); + if (c == ch9350l_valid_start_of_status_frame[check_p]) { + check_p++; + } + } + if (check_p != ARRAY_SIZE(ch9350l_valid_start_of_status_frame)) { + LOG_ERR("CH9350L not detected"); + return -ENXIO; + } + + /* Flush FIFO if applicable */ + while (uart_poll_in(config->uart, &c)) { + }; + + for (int i = 0; i < sizeof(ch9350l_disable_status_frame); i++) { + uart_poll_out(config->uart, ch9350l_disable_status_frame[i]); + } + + ret = uart_irq_callback_user_data_set(config->uart, ch9350l_input_callback, data); + if (ret < 0) { + LOG_ERR("Couldn't set UART callback"); + return ret; + } + uart_irq_rx_enable(config->uart); + + return ret; +} + +#define CH9350L_DEFINE(inst) \ + static struct ch9350l_data ch9350l_data_##inst = {0}; \ + \ + static struct ch9350l_config const ch9350l_config_##inst = { \ + .uart = DEVICE_DT_GET(DT_INST_BUS(inst)), \ + .kb_codemap = COND_CODE_1(DT_NODE_HAS_PROP(DT_DRV_INST(inst), kb_codemap), \ + ((int []) DT_INST_PROP(inst, kb_codemap)), NULL), \ + .kb_codemap_len = DT_INST_PROP_LEN_OR(inst, kb_codemap, 0), \ + .mouse_codemap = COND_CODE_1(DT_NODE_HAS_PROP(DT_DRV_INST(inst), mouse_codemap),\ + ((int []) DT_INST_PROP(inst, mouse_codemap)), NULL), \ + .mouse_codemap_len = DT_INST_PROP_LEN_OR(inst, mouse_codemap, 0), \ + }; \ + \ + DEVICE_DT_INST_DEFINE(inst, ch9350l_init, NULL, &ch9350l_data_##inst, \ + &ch9350l_config_##inst, POST_KERNEL, CONFIG_INPUT_INIT_PRIORITY, \ + NULL); \ + BUILD_ASSERT((DT_INST_PROP_LEN_OR(inst, kb_code_map, 0) & 0x1) == 0, \ + "kb-codemap is not of a valid size"); \ + BUILD_ASSERT((DT_INST_PROP_LEN_OR(inst, mouse_code_map, 0) & 0x1) == 0, \ + "mouse-codemap is not of a valid size"); + +DT_INST_FOREACH_STATUS_OKAY(CH9350L_DEFINE) diff --git a/dts/bindings/input/wch,ch9350l.yaml b/dts/bindings/input/wch,ch9350l.yaml new file mode 100644 index 000000000000..81f1fb3a257f --- /dev/null +++ b/dts/bindings/input/wch,ch9350l.yaml @@ -0,0 +1,42 @@ +# Copyright (c) 2026 MASSDRIVER EI (massdriver.space) +# SPDX-License-Identifier: Apache-2.0 + +description: | + WinChipHead CH9350L USB HID to UART control chip. + This supports State 0. + + + &uart0 { + status = "okay"; + + usb_kb { + compatible = "wch,ch9350l"; + status = "okay"; + + kb-codemap = < + 4 INPUT_KEY_Q + 5 INPUT_KEY_B + 6 INPUT_KEY_C + >; + mouse-codemap = < + 1 INPUT_BTN_LEFT + 2 INPUT_BTN_RIGHT + 4 INPUT_BTN_MIDDLE + >; + }; + }; + +compatible: "wch,ch9350l" + +include: [base.yaml, uart-device.yaml] + +properties: + kb-codemap: + type: array + description: | + Maps a keyboard key code to a input code by pair of 2 when needed. + + mouse-codemap: + type: array + description: | + Maps a mouse button code to a input code by pair of 2 when needed. From 2c1d2c8e83519f642e99c0ef92a6991bf06cf27e Mon Sep 17 00:00:00 2001 From: Camille BAUD Date: Thu, 8 Jan 2026 22:02:02 +0100 Subject: [PATCH 2240/3659] tests: build_all: add ch9350l test Adds a build test for CH9350L Signed-off-by: Camille BAUD --- tests/drivers/build_all/input/app.overlay | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/drivers/build_all/input/app.overlay b/tests/drivers/build_all/input/app.overlay index a7ae80116f29..2e7f705b6c04 100644 --- a/tests/drivers/build_all/input/app.overlay +++ b/tests/drivers/build_all/input/app.overlay @@ -189,6 +189,11 @@ zephyr,code = ; }; }; + + usb_kb { + compatible = "wch,ch9350l"; + status = "okay"; + }; }; i2c@1 { From 0e6c2aedafcb2d821d1e40dc094baf775153363f Mon Sep 17 00:00:00 2001 From: Kate Wang Date: Wed, 14 Jan 2026 15:39:28 +0800 Subject: [PATCH 2241/3659] drivers: input: Add TMA525B capacitive touch controller driver This commit adds support for the Parade Tech TMA525B capacitive touch controller. The driver supports both interrupt-driven and polling modes, and can handle up to 4 simultaneous touch points. Key features: - I2C communication interface - Multi-touch support (up to 4 touch points) - Interrupt mode with GPIO callback support - Polling mode with timer - Power management support with PM notifier - Reset and power control via GPIO - Touch event tracking (down, contact, up) Signed-off-by: Kate Wang --- drivers/input/CMakeLists.txt | 1 + drivers/input/Kconfig | 1 + drivers/input/Kconfig.tma525b | 42 +++ drivers/input/input_tma525b.c | 429 +++++++++++++++++++++++++ dts/bindings/input/parade,tma525b.yaml | 24 ++ 5 files changed, 497 insertions(+) create mode 100644 drivers/input/Kconfig.tma525b create mode 100644 drivers/input/input_tma525b.c create mode 100644 dts/bindings/input/parade,tma525b.yaml diff --git a/drivers/input/CMakeLists.txt b/drivers/input/CMakeLists.txt index 7fcb28827b1f..2dcfc254eb02 100644 --- a/drivers/input/CMakeLists.txt +++ b/drivers/input/CMakeLists.txt @@ -41,6 +41,7 @@ zephyr_library_sources_ifdef(CONFIG_INPUT_RENESAS_RX_CTSU input_renesas_rx_ctsu. zephyr_library_sources_ifdef(CONFIG_INPUT_SBUS input_sbus.c) zephyr_library_sources_ifdef(CONFIG_INPUT_STM32_TSC_KEYS input_tsc_keys.c) zephyr_library_sources_ifdef(CONFIG_INPUT_STMPE811 input_stmpe811.c) +zephyr_library_sources_ifdef(CONFIG_INPUT_TMA525B input_tma525b.c) zephyr_library_sources_ifdef(CONFIG_INPUT_TOUCH input_touch.c) zephyr_library_sources_ifdef(CONFIG_INPUT_VS1838B input_vs1838b.c) zephyr_library_sources_ifdef(CONFIG_INPUT_XEC_KBD input_xec_kbd.c) diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig index 39ff62f197eb..bc92a34b7fa2 100644 --- a/drivers/input/Kconfig +++ b/drivers/input/Kconfig @@ -43,6 +43,7 @@ source "drivers/input/Kconfig.rts5912" source "drivers/input/Kconfig.sbus" source "drivers/input/Kconfig.sdl" source "drivers/input/Kconfig.stmpe811" +source "drivers/input/Kconfig.tma525b" source "drivers/input/Kconfig.touch" source "drivers/input/Kconfig.tsc_keys" source "drivers/input/Kconfig.vs1838b" diff --git a/drivers/input/Kconfig.tma525b b/drivers/input/Kconfig.tma525b new file mode 100644 index 000000000000..1a8b4bfe8c4e --- /dev/null +++ b/drivers/input/Kconfig.tma525b @@ -0,0 +1,42 @@ +# Copyright (c) 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +menuconfig INPUT_TMA525B + bool "TMA525B capacitive touch controller" + default y + depends on DT_HAS_PARADE_TMA525B_ENABLED + select I2C + select INPUT_TOUCH + help + Enable support for Parade Tech TMA525B capacitive touch controller. + +if INPUT_TMA525B + +config INPUT_TMA525B_INTERRUPT + bool "Interrupt mode" + default y if $(dt_compat_any_has_prop,$(DT_COMPAT_PARADE_TMA525B),int-gpios) + help + Enable interrupt mode for TMA525B touch controller. If disabled, + the driver will use polling mode. + +config INPUT_TMA525B_PERIOD_MS + int "Polling period (ms)" + default 10 + depends on !INPUT_TMA525B_INTERRUPT + help + Polling period in milliseconds when the controller is in polling mode. + +config INPUT_TMA525B_MAX_TOUCH_POINTS + int "Maximum number of touch points" + default 1 + range 1 4 + help + Maximum number of touch points supported by the controller. + +config INPUT_TMA525B_RETRY_TIMES + int "Retry times for controller to enter application mode" + default 10 + help + Retry times for controller to enter application mode after power up. + +endif # INPUT_TMA525B diff --git a/drivers/input/input_tma525b.c b/drivers/input/input_tma525b.c new file mode 100644 index 000000000000..f804838cde02 --- /dev/null +++ b/drivers/input/input_tma525b.c @@ -0,0 +1,429 @@ +/* + * Copyright (c) 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT parade_tma525b + +#include +#include +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(tma525b, CONFIG_INPUT_LOG_LEVEL); + +#define TMA525B_BOOT_DELAY_MS 120U + +/* TMA525B maximum number of simultaneously detected touches */ +#define TMA525B_MAX_TOUCHES 4U + +/* TMA525B register address where touch data begin */ +#define TMA525B_TOUCH_DATA_SUBADDR 1U + +/* TMA525B raw touch data length */ +#define TMA525B_TOUCH_DATA_LEN 264U + +/* TMA525B touch data header length to read first */ +#define TMA525B_TOUCH_DATA_LEN_BYTES 2U + +/* TMA525B report ID for touch data */ +#define TMA525B_REPORT_ID_TOUCH 0x01U + +/* Touch event types - matching fsl_tma525b.h */ +enum touch_event { + TOUCH_RESERVED = 0, /* No touch event detected */ + TOUCH_DOWN = 1, /* Touch down event detected */ + TOUCH_CONTACT = 2, /* Touch point moving */ + TOUCH_UP = 3 /* Touch event finished */ +}; + +/* TMA525B touch point structure */ +struct tma525b_touch_point { + uint8_t touch_type; /* 0 for standard finger/glove, 1 for proximity. Not used*/ + uint8_t event_id; /* Bit 0-4: touch ID, bit 5-6: touch event */ + uint16_t x; + uint16_t y; + uint8_t pressure; /* Touch intensity. Not used in current driver model. */ + uint16_t axis_len_mm; /* Axis length. Not used in current driver model. */ + /* Angle between panel vertical axis and major axis. Not used in current driver model. */ + uint8_t orientation; +} __packed; + +/* TMA525B touch data structure */ +struct tma525b_touch_data { + uint16_t length; /* Packet length. */ + uint8_t report_id; + /* Timestamp in 100us units. Not used in current driver model. */ + uint16_t timestamp_100us; + uint8_t num_touch; /* Number of touch points detected */ + /* 2 MSB: report counter, 3 LSB: noise effects. Not used in current driver model. */ + uint8_t report_noise; + struct tma525b_touch_point touch[TMA525B_MAX_TOUCHES]; +} __packed; + +/* Macros for extracting touch data. */ +#define TMA525B_TOUCH_POINT_GET_ID(event_id) (event_id & 0x1F) +#define TMA525B_TOUCH_POINT_GET_EVENT(event_id) ((event_id & 0x60) >> 5U) + +/* TMA525B configuration (from device tree) */ +struct tma525b_config { + struct input_touchscreen_common_config common; + struct i2c_dt_spec bus; + struct gpio_dt_spec pwr_gpio; + struct gpio_dt_spec rst_gpio; + struct gpio_dt_spec int_gpio; +}; + +/* TMA525B runtime data */ +struct tma525b_data { + const struct device *dev; + struct k_work work; + uint8_t touch_buf[TMA525B_TOUCH_DATA_LEN]; + uint8_t prev_touch_count; + struct { + uint8_t id; + uint16_t x; + uint16_t y; + } prev_touches[TMA525B_MAX_TOUCHES]; +#ifdef CONFIG_INPUT_TMA525B_INTERRUPT + struct gpio_callback int_gpio_cb; +#else + struct k_timer timer; +#endif +}; + +INPUT_TOUCH_STRUCT_CHECK(struct tma525b_config); + +static int tma525b_process(const struct device *dev) +{ + const struct tma525b_config *config = dev->config; + struct tma525b_data *data = dev->data; + struct tma525b_touch_data *touch_data; + int ret; + uint8_t touch_id; + enum touch_event event; + uint8_t touch_count; + + /* Read first two bytes to get the data length */ + ret = i2c_burst_read_dt(&config->bus, TMA525B_TOUCH_DATA_SUBADDR, data->touch_buf, + TMA525B_TOUCH_DATA_LEN_BYTES); + if (ret < 0) { + LOG_ERR("Failed to read data length: %d", ret); + return ret; + } + + touch_data = (struct tma525b_touch_data *)data->touch_buf; + + /* Validate touch data length */ + if (touch_data->length <= 0x02 || touch_data->length > TMA525B_TOUCH_DATA_LEN) { + LOG_DBG("Invalid touch data length: %d", touch_data->length); + return -EINVAL; + } + + /* Read the full touch data according to length */ + ret = i2c_burst_read_dt(&config->bus, TMA525B_TOUCH_DATA_SUBADDR, data->touch_buf, + touch_data->length); + if (ret < 0) { + LOG_ERR("Failed to read touch data: %d", ret); + return ret; + } + + /* Only when report ID is 0x01 the touch data is valid */ + if (touch_data->report_id != TMA525B_REPORT_ID_TOUCH) { + LOG_DBG("Invalid report ID: 0x%02x", touch_data->report_id); + return -EINVAL; + } + + /* Get number of touches */ + touch_count = MIN(touch_data->num_touch, CONFIG_INPUT_TMA525B_MAX_TOUCH_POINTS); + + /* Process current touch points */ + for (uint8_t i = 0; i < touch_count; i++) { + int x, y; + + touch_id = TMA525B_TOUCH_POINT_GET_ID(touch_data->touch[i].event_id); + event = TMA525B_TOUCH_POINT_GET_EVENT(touch_data->touch[i].event_id); + x = touch_data->touch[i].x; + y = touch_data->touch[i].y; + + /* Update coordinates only if there is valid touch event */ + if (event == TOUCH_RESERVED) { + continue; + } + + if (CONFIG_INPUT_TMA525B_MAX_TOUCH_POINTS > 1) { + input_report_abs(dev, INPUT_ABS_MT_SLOT, touch_id, true, K_FOREVER); + } + + input_touchscreen_report_pos(dev, x, y, K_FOREVER); + + /* Report touch state based on event type */ + if (event == TOUCH_DOWN || event == TOUCH_CONTACT) { + input_report_key(dev, INPUT_BTN_TOUCH, 1, true, K_FOREVER); + } else if (event == TOUCH_UP) { + input_report_key(dev, INPUT_BTN_TOUCH, 0, true, K_FOREVER); + } + + /* Store current touch for tracking */ + data->prev_touches[i].id = touch_id; + data->prev_touches[i].x = x; + data->prev_touches[i].y = y; + } + + /* Handle release events for touches that disappeared */ + for (uint8_t i = 0; i < data->prev_touch_count; i++) { + bool touch_found = false; + + /* Look for previous touch in current touch list */ + for (uint8_t j = 0; j < touch_count; j++) { + if (data->prev_touches[i].id == + TMA525B_TOUCH_POINT_GET_ID(touch_data->touch[j].event_id)) { + touch_found = true; + break; + } + } + + /* If previous touch not found, report release */ + if (!touch_found) { + if (CONFIG_INPUT_TMA525B_MAX_TOUCH_POINTS > 1) { + input_report_abs(dev, INPUT_ABS_MT_SLOT, data->prev_touches[i].id, + true, K_FOREVER); + } + input_touchscreen_report_pos(dev, data->prev_touches[i].x, + data->prev_touches[i].y, K_FOREVER); + input_report_key(dev, INPUT_BTN_TOUCH, 0, true, K_FOREVER); + } + } + + /* Update previous touch count */ + data->prev_touch_count = touch_count; + + return 0; +} + +static void tma525b_work_handler(struct k_work *work) +{ + struct tma525b_data *data = CONTAINER_OF(work, struct tma525b_data, work); + + tma525b_process(data->dev); +} + +#ifdef CONFIG_INPUT_TMA525B_INTERRUPT +static void tma525b_isr_handler(const struct device *dev, struct gpio_callback *cb, uint32_t pins) +{ + struct tma525b_data *data = CONTAINER_OF(cb, struct tma525b_data, int_gpio_cb); + + k_work_submit(&data->work); +} +#else +static void tma525b_timer_handler(struct k_timer *timer) +{ + struct tma525b_data *data = CONTAINER_OF(timer, struct tma525b_data, timer); + + k_work_submit(&data->work); +} +#endif + +static int tma525b_chip_init(const struct device *dev) +{ + const struct tma525b_config *config = dev->config; + uint8_t read_buf[2]; + int ret; + int retry = 0; + + /* Power on sequence */ + if (config->pwr_gpio.port != NULL) { + ret = gpio_pin_set_dt(&config->pwr_gpio, 1); + if (ret < 0) { + LOG_ERR("Failed to enable power: %d", ret); + return ret; + } + k_sleep(K_MSEC(10)); + } + + /* Reset the controller */ + if (config->rst_gpio.port != NULL) { + gpio_pin_set_dt(&config->rst_gpio, 1); + k_sleep(K_MSEC(5)); + gpio_pin_set_dt(&config->rst_gpio, 0); + } + + k_sleep(K_MSEC(TMA525B_BOOT_DELAY_MS)); + + /* Enter application mode - check if ready */ + while (retry < CONFIG_INPUT_TMA525B_RETRY_TIMES) { + ret = i2c_burst_read_dt(&config->bus, TMA525B_TOUCH_DATA_SUBADDR, read_buf, + sizeof(read_buf)); + if (ret == 0) { + /* Check for application mode signature */ + if ((read_buf[0] == 0x02U && read_buf[1] == 0x00U) || + read_buf[1] == 0xFFU) { + LOG_INF("TMA525B entered application mode"); + break; + } + } + k_sleep(K_MSEC(TMA525B_BOOT_DELAY_MS)); + retry++; + } + + if (retry == 0U) { + LOG_ERR("TMA525B failed to enter application mode"); + return -ENODEV; + } + + return 0; +} + +static int tma525b_init(const struct device *dev) +{ + const struct tma525b_config *config = dev->config; + struct tma525b_data *data = dev->data; + int ret; + + data->dev = dev; + + if (!i2c_is_ready_dt(&config->bus)) { + LOG_ERR("I2C controller not ready"); + return -ENODEV; + } + + /* Configure power GPIO if available */ + if (config->pwr_gpio.port != NULL) { + if (!gpio_is_ready_dt(&config->pwr_gpio)) { + LOG_ERR("Power GPIO controller not ready"); + return -ENODEV; + } + ret = gpio_pin_configure_dt(&config->pwr_gpio, GPIO_OUTPUT_INACTIVE); + if (ret < 0) { + LOG_ERR("Failed to configure power GPIO: %d", ret); + return ret; + } + } + + /* Configure reset GPIO if available */ + if (config->rst_gpio.port != NULL) { + if (!gpio_is_ready_dt(&config->rst_gpio)) { + LOG_ERR("Reset GPIO controller not ready"); + return -ENODEV; + } + ret = gpio_pin_configure_dt(&config->rst_gpio, GPIO_OUTPUT_INACTIVE); + if (ret < 0) { + LOG_ERR("Failed to configure reset GPIO: %d", ret); + return ret; + } + } + + /* Initialize work queue */ + k_work_init(&data->work, tma525b_work_handler); + + /* Initialize the chip */ + ret = tma525b_chip_init(dev); + if (ret < 0) { + LOG_ERR("Failed to initialize TMA525B chip: %d", ret); + return ret; + } + +#ifdef CONFIG_INPUT_TMA525B_INTERRUPT + if (!gpio_is_ready_dt(&config->int_gpio)) { + LOG_ERR("Interrupt GPIO controller not ready"); + return -ENODEV; + } + ret = gpio_pin_configure_dt(&config->int_gpio, GPIO_INPUT); + if (ret < 0) { + LOG_ERR("Failed to configure interrupt GPIO: %d", ret); + return ret; + } + + ret = gpio_pin_interrupt_configure_dt(&config->int_gpio, GPIO_INT_EDGE_TO_ACTIVE); + if (ret < 0) { + LOG_ERR("Failed to configure interrupt: %d", ret); + return ret; + } + + gpio_init_callback(&data->int_gpio_cb, tma525b_isr_handler, BIT(config->int_gpio.pin)); + + ret = gpio_add_callback(config->int_gpio.port, &data->int_gpio_cb); + if (ret < 0) { + LOG_ERR("Failed to add GPIO callback: %d", ret); + return ret; + } + LOG_DBG("TMA525B using interrupt mode"); +#else + k_timer_init(&data->timer, tma525b_timer_handler, NULL); + k_timer_start(&data->timer, K_MSEC(CONFIG_INPUT_TMA525B_PERIOD_MS), + K_MSEC(CONFIG_INPUT_TMA525B_PERIOD_MS)); + LOG_DBG("TMA525B using polling mode"); +#endif + + ret = pm_device_runtime_enable(dev); + if (ret < 0 && ret != -ENOTSUP) { + LOG_ERR("Failed to enable runtime power management: %d", ret); + return ret; + } + + return 0; +} + +#ifdef CONFIG_PM_DEVICE +static int tma525b_pm_action(const struct device *dev, enum pm_device_action action) +{ + const struct tma525b_config *config = dev->config; +#ifndef CONFIG_INPUT_TMA525B_INTERRUPT + struct tma525b_data *data = dev->data; +#endif + int ret; + + switch (action) { + case PM_DEVICE_ACTION_SUSPEND: + /* Power down the device */ + if (config->pwr_gpio.port != NULL) { + ret = gpio_pin_set_dt(&config->pwr_gpio, 0); + if (ret < 0) { + return ret; + } + } + +#ifndef CONFIG_INPUT_TMA525B_INTERRUPT + k_timer_stop(&data->timer); +#endif + break; + case PM_DEVICE_ACTION_RESUME: + /* Re-initialize the chip on resume */ + ret = tma525b_chip_init(dev); + if (ret < 0) { + return ret; + } + +#ifndef CONFIG_INPUT_TMA525B_INTERRUPT + k_timer_start(&data->timer, K_MSEC(CONFIG_INPUT_TMA525B_PERIOD_MS), + K_MSEC(CONFIG_INPUT_TMA525B_PERIOD_MS)); +#endif + break; + default: + return -ENOTSUP; + } + + return 0; +} +#endif + +#define TMA525B_INIT(index) \ + PM_DEVICE_DT_INST_DEFINE(index, tma525b_pm_action); \ + static const struct tma525b_config tma525b_config_##index = { \ + .common = INPUT_TOUCH_DT_INST_COMMON_CONFIG_INIT(index), \ + .bus = I2C_DT_SPEC_INST_GET(index), \ + .rst_gpio = GPIO_DT_SPEC_INST_GET_OR(index, reset_gpios, {0}), \ + .int_gpio = GPIO_DT_SPEC_INST_GET_OR(index, int_gpios, {0}), \ + .pwr_gpio = GPIO_DT_SPEC_INST_GET_OR(index, power_gpios, {0}), \ + }; \ + static struct tma525b_data tma525b_data_##index; \ + DEVICE_DT_INST_DEFINE(index, tma525b_init, PM_DEVICE_DT_INST_GET(index), \ + &tma525b_data_##index, &tma525b_config_##index, POST_KERNEL, \ + CONFIG_INPUT_INIT_PRIORITY, NULL); + +DT_INST_FOREACH_STATUS_OKAY(TMA525B_INIT) diff --git a/dts/bindings/input/parade,tma525b.yaml b/dts/bindings/input/parade,tma525b.yaml new file mode 100644 index 000000000000..1ff29aa546dd --- /dev/null +++ b/dts/bindings/input/parade,tma525b.yaml @@ -0,0 +1,24 @@ +# Copyright (c) 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +description: TMA525b capacitive touch controller + +compatible: "parade,tma525b" + +include: [i2c-device.yaml, touchscreen-common.yaml] + +properties: + int-gpios: + type: phandle-array + description: | + Interrupt GPIO. Used by the controller to signal touch data is + available. Active low. + reset-gpios: + type: phandle-array + description: | + Reset GPIO. Used to reset the controller during initialization, and + to wake it from hibernation mode. Active low. + power-gpios: + type: phandle-array + description: | + Power on GPIO. Used to enable the controller during initialization. From a6df355b1256cf85b0cb31dca3b8e3831923dd0c Mon Sep 17 00:00:00 2001 From: Kate Wang Date: Mon, 5 Jan 2026 16:05:54 +0800 Subject: [PATCH 2242/3659] boards: shields: zc143ac72mipi: Add touch controller and LVGL config - Add support for the TMA525B touch controller to the zc143ac72mipi shield - Add Kconfig.defconfig with LVGL configuration defaults - Update board specific configuration Signed-off-by: Kate Wang --- .../shields/zc143ac72mipi/Kconfig.defconfig | 28 +++++++++++++++++++ .../mimxrt700_evk_mimxrt798s_cm33_cpu0.conf | 2 ++ .../zc143ac72mipi/zc143ac72mipi.overlay | 16 +++++++++++ 3 files changed, 46 insertions(+) create mode 100644 boards/shields/zc143ac72mipi/Kconfig.defconfig diff --git a/boards/shields/zc143ac72mipi/Kconfig.defconfig b/boards/shields/zc143ac72mipi/Kconfig.defconfig new file mode 100644 index 000000000000..dda199be1e4b --- /dev/null +++ b/boards/shields/zc143ac72mipi/Kconfig.defconfig @@ -0,0 +1,28 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +if SHIELD_ZC143AC72MIPI + +# Enable input subsystem for TMA525b driver +config INPUT + default y + +if LVGL + +config LV_Z_VDB_SIZE + 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 + +endif # LVGL + +endif # SHIELD_ZC143AC72MIPI diff --git a/boards/shields/zc143ac72mipi/boards/mimxrt700_evk_mimxrt798s_cm33_cpu0.conf b/boards/shields/zc143ac72mipi/boards/mimxrt700_evk_mimxrt798s_cm33_cpu0.conf index 768bb57bef21..346a06418fed 100644 --- a/boards/shields/zc143ac72mipi/boards/mimxrt700_evk_mimxrt798s_cm33_cpu0.conf +++ b/boards/shields/zc143ac72mipi/boards/mimxrt700_evk_mimxrt798s_cm33_cpu0.conf @@ -1,2 +1,4 @@ CONFIG_REGULATOR=y CONFIG_DCACHE=n +CONFIG_MIPI_DSI_MCUX_2L_SWAP16=y +CONFIG_LV_COLOR_16_SWAP=n diff --git a/boards/shields/zc143ac72mipi/zc143ac72mipi.overlay b/boards/shields/zc143ac72mipi/zc143ac72mipi.overlay index 3ce68aacf7b3..9090e373edf3 100644 --- a/boards/shields/zc143ac72mipi/zc143ac72mipi.overlay +++ b/boards/shields/zc143ac72mipi/zc143ac72mipi.overlay @@ -7,6 +7,7 @@ / { chosen { zephyr,display = &co5300_zc143ac72mipi; + zephyr,touch = &tma525b_zc143ac72mipi; }; en_mipi_display_zc143ac72mipi: enable-mipi-display { @@ -17,6 +18,21 @@ }; }; +&nxp_mipi_i2c { + status = "okay"; + + tma525b_zc143ac72mipi: tma525b@24 { + compatible = "parade,tma525b"; + reg = <0x24>; + reset-gpios = <&nxp_mipi_connector 28 GPIO_ACTIVE_LOW>; + int-gpios = <&nxp_mipi_connector 29 GPIO_ACTIVE_LOW>; + inverted-y; + inverted-x; + screen-width = <466>; + screen-height = <466>; + }; +}; + &zephyr_mipi_dsi { status = "okay"; autoinsert-eotp; From 504cf082d8b3498278e96c5bbe2c53b037a9a0c2 Mon Sep 17 00:00:00 2001 From: Kate Wang Date: Mon, 5 Jan 2026 16:06:46 +0800 Subject: [PATCH 2243/3659] boards: shields: g1120b0mipi: Move configs to board-specific files Move MIPI_DSI_MCUX_2L_SWAP16 and LV_COLOR_16_SWAP configuration from the shield's Kconfig.defconfig to board-specific configuration files. This allows for better board-level customization and removes the conditional logic from the shield defaults. Signed-off-by: Kate Wang --- boards/shields/g1120b0mipi/Kconfig.defconfig | 13 +------------ .../boards/mimxrt595_evk_mimxrt595s_cm33.conf | 2 ++ .../boards/mimxrt700_evk_mimxrt798s_cm33_cpu0.conf | 2 ++ 3 files changed, 5 insertions(+), 12 deletions(-) diff --git a/boards/shields/g1120b0mipi/Kconfig.defconfig b/boards/shields/g1120b0mipi/Kconfig.defconfig index dd96ec88e06c..3ebe16c71ecd 100644 --- a/boards/shields/g1120b0mipi/Kconfig.defconfig +++ b/boards/shields/g1120b0mipi/Kconfig.defconfig @@ -3,22 +3,11 @@ if SHIELD_G1120B0MIPI -if LVGL # Enable input subsystem for FT5336 driver config INPUT default y -if MIPI_DSI_MCUX_2L -# Enable color swap in driver - -config MIPI_DSI_MCUX_2L_SWAP16 - default y - -endif # MIPI_DSI_MCUX_2L - -# Swap 16 bit color setting for LVGL, to send high byte first -configdefault LV_COLOR_16_SWAP - default y if !MIPI_DSI_MCUX_2L_SWAP16 +if LVGL config LV_Z_VDB_SIZE default 16 diff --git a/boards/shields/g1120b0mipi/boards/mimxrt595_evk_mimxrt595s_cm33.conf b/boards/shields/g1120b0mipi/boards/mimxrt595_evk_mimxrt595s_cm33.conf index ffe50a964edd..7e817c2a35e7 100644 --- a/boards/shields/g1120b0mipi/boards/mimxrt595_evk_mimxrt595s_cm33.conf +++ b/boards/shields/g1120b0mipi/boards/mimxrt595_evk_mimxrt595s_cm33.conf @@ -1,2 +1,4 @@ # Enable DMA, so that DSI MCUX will use SMARTDMA CONFIG_DMA=y +CONFIG_MIPI_DSI_MCUX_2L_SWAP16=y +CONFIG_LV_COLOR_16_SWAP=n diff --git a/boards/shields/g1120b0mipi/boards/mimxrt700_evk_mimxrt798s_cm33_cpu0.conf b/boards/shields/g1120b0mipi/boards/mimxrt700_evk_mimxrt798s_cm33_cpu0.conf index 768bb57bef21..346a06418fed 100644 --- a/boards/shields/g1120b0mipi/boards/mimxrt700_evk_mimxrt798s_cm33_cpu0.conf +++ b/boards/shields/g1120b0mipi/boards/mimxrt700_evk_mimxrt798s_cm33_cpu0.conf @@ -1,2 +1,4 @@ CONFIG_REGULATOR=y CONFIG_DCACHE=n +CONFIG_MIPI_DSI_MCUX_2L_SWAP16=y +CONFIG_LV_COLOR_16_SWAP=n From ec5a3db24b9883b861082278b60cf0b5fa47a9f2 Mon Sep 17 00:00:00 2001 From: Kate Wang Date: Thu, 18 Dec 2025 17:29:55 +0800 Subject: [PATCH 2244/3659] samples: lvgl: demos: Add zc143ac72mipi shield to test platforms Adds the zc143ac72mipi shield configuration for the mimxrt700_evk platform to the LVGL demos sample test platforms. Signed-off-by: Kate Wang --- samples/modules/lvgl/demos/sample.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/samples/modules/lvgl/demos/sample.yaml b/samples/modules/lvgl/demos/sample.yaml index 5cdf40e77ce2..58693118027b 100644 --- a/samples/modules/lvgl/demos/sample.yaml +++ b/samples/modules/lvgl/demos/sample.yaml @@ -11,6 +11,7 @@ common: - platform:mimxrt1170_evk/mimxrt1176/cm7:SHIELD=rk055hdmipi4ma0 - platform:mimxrt595_evk/mimxrt595s/cm33:SHIELD=rk055hdmipi4ma0 - platform:mimxrt700_evk/mimxrt798s/cm33_cpu0:SHIELD=g1120b0mipi + - platform:mimxrt700_evk/mimxrt798s/cm33_cpu0:SHIELD=zc143ac72mipi tags: - samples - display From cf7763ea37941d02c5a98524cd96fecc22b168ec Mon Sep 17 00:00:00 2001 From: Kate Wang Date: Mon, 19 Jan 2026 13:10:35 +0800 Subject: [PATCH 2245/3659] tests: drivers: build_all: input: Add TMA525B to build test Add the TMA525B touch controller driver to the input build_all test. This includes: - Device tree overlay entry for the TMA525B device - Test configuration enabling interrupt mode Signed-off-by: Kate Wang --- tests/drivers/build_all/input/app.overlay | 6 ++++++ tests/drivers/build_all/input/testcase.yaml | 1 + 2 files changed, 7 insertions(+) diff --git a/tests/drivers/build_all/input/app.overlay b/tests/drivers/build_all/input/app.overlay index 2e7f705b6c04..526d1ed14899 100644 --- a/tests/drivers/build_all/input/app.overlay +++ b/tests/drivers/build_all/input/app.overlay @@ -315,6 +315,12 @@ int-gpios = <&test_gpio 0 0>; reset-gpios = <&test_gpio 1 0>; }; + + tma525b@d { + compatible = "parade,tma525b"; + reg = <0xd>; + int-gpios = <&test_gpio 0 0>; + }; }; spi@2 { diff --git a/tests/drivers/build_all/input/testcase.yaml b/tests/drivers/build_all/input/testcase.yaml index ee1f1c4cd96f..2bb44df0f534 100644 --- a/tests/drivers/build_all/input/testcase.yaml +++ b/tests/drivers/build_all/input/testcase.yaml @@ -16,6 +16,7 @@ tests: - CONFIG_INPUT_CST816S_INTERRUPT=n - CONFIG_INPUT_FT5336_INTERRUPT=y - CONFIG_INPUT_GT911_INTERRUPT=y + - CONFIG_INPUT_TMA525B_INTERRUPT=y drivers.input.kbd_16_bit: platform_allow: From b2d28bc8d532ee6cd121fefedf9daf98f73727de Mon Sep 17 00:00:00 2001 From: Neil Chen Date: Mon, 19 Jan 2026 10:31:04 +0800 Subject: [PATCH 2246/3659] boards: nxp: frdm_mcxaxx6: add arduino labels Added arduino_header node labels to FRDM-MCXA366,FRDM-MCXA346 and FRDM-MCXA266 device tree board definition, allowing compatible shield boards to be used. Also extend the board YAML file with related support tags arduino_gpio. Signed-off-by: Neil Chen --- boards/nxp/frdm_mcxaxx6/board_common.dtsi | 30 +++++++++++++++++++++++ boards/nxp/frdm_mcxaxx6/frdm_mcxa266.yaml | 1 + boards/nxp/frdm_mcxaxx6/frdm_mcxa346.yaml | 1 + boards/nxp/frdm_mcxaxx6/frdm_mcxa366.yaml | 1 + 4 files changed, 33 insertions(+) diff --git a/boards/nxp/frdm_mcxaxx6/board_common.dtsi b/boards/nxp/frdm_mcxaxx6/board_common.dtsi index 7d8e1ab20bed..fb4f61db79fe 100644 --- a/boards/nxp/frdm_mcxaxx6/board_common.dtsi +++ b/boards/nxp/frdm_mcxaxx6/board_common.dtsi @@ -5,6 +5,7 @@ */ #include +#include / { compatible = "nxp,mcx"; @@ -64,6 +65,35 @@ zephyr,code = ; }; }; + + arduino_header: arduino-connector { + compatible = "arduino-header-r3"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = , + , + , + , + , + , + , /* GPIO, Not a RX */ + , /* GPIO, Not a TX */ + , + , + , + , + , + , + , + , + , /* CS */ + , /* MOSI */ + , /* MISO */ + , /* SCK */ + , /* SDA */ + ; /* SCL */ + }; }; /* Port configurations */ diff --git a/boards/nxp/frdm_mcxaxx6/frdm_mcxa266.yaml b/boards/nxp/frdm_mcxaxx6/frdm_mcxa266.yaml index 54bdd53c9213..5ec746be9a2e 100644 --- a/boards/nxp/frdm_mcxaxx6/frdm_mcxa266.yaml +++ b/boards/nxp/frdm_mcxaxx6/frdm_mcxa266.yaml @@ -26,4 +26,5 @@ supported: - i3c - entropy - can + - arduino_gpio vendor: nxp diff --git a/boards/nxp/frdm_mcxaxx6/frdm_mcxa346.yaml b/boards/nxp/frdm_mcxaxx6/frdm_mcxa346.yaml index cad201d90bc2..039a545847e2 100644 --- a/boards/nxp/frdm_mcxaxx6/frdm_mcxa346.yaml +++ b/boards/nxp/frdm_mcxaxx6/frdm_mcxa346.yaml @@ -25,4 +25,5 @@ supported: - dma - opamp - can + - arduino_gpio vendor: nxp diff --git a/boards/nxp/frdm_mcxaxx6/frdm_mcxa366.yaml b/boards/nxp/frdm_mcxaxx6/frdm_mcxa366.yaml index 031c6aa9de7e..5a22a85e8071 100644 --- a/boards/nxp/frdm_mcxaxx6/frdm_mcxa366.yaml +++ b/boards/nxp/frdm_mcxaxx6/frdm_mcxa366.yaml @@ -27,4 +27,5 @@ supported: - opamp - entropy - can + - arduino_gpio vendor: nxp From ed75a28d9c35149c5329e6b28ad4063a7d16c366 Mon Sep 17 00:00:00 2001 From: Neil Chen Date: Mon, 19 Jan 2026 10:35:18 +0800 Subject: [PATCH 2247/3659] dts: arm/nxp: Add usb nodes to NXP MCXA366 and MCXA266 dtsi file Add usb nodes to NXP MCXA366 and MCXA266 dtsi file Signed-off-by: Neil Chen --- dts/arm/nxp/nxp_mcxa346.dtsi | 1 + dts/arm/nxp/nxp_mcxaxx6_common.dtsi | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/dts/arm/nxp/nxp_mcxa346.dtsi b/dts/arm/nxp/nxp_mcxa346.dtsi index 4dad454c63db..861b777baecd 100644 --- a/dts/arm/nxp/nxp_mcxa346.dtsi +++ b/dts/arm/nxp/nxp_mcxa346.dtsi @@ -10,3 +10,4 @@ /delete-node/ &flexio0; /delete-node/ &trng; /delete-node/ &flexcan1; +/delete-node/ &usb; diff --git a/dts/arm/nxp/nxp_mcxaxx6_common.dtsi b/dts/arm/nxp/nxp_mcxaxx6_common.dtsi index d6fee9ce9dca..fd03815c9c4e 100644 --- a/dts/arm/nxp/nxp_mcxaxx6_common.dtsi +++ b/dts/arm/nxp/nxp_mcxaxx6_common.dtsi @@ -576,6 +576,16 @@ number-of-mb-fd = <7>; status = "disabled"; }; + + usb: usbd@400a4000 { + compatible = "nxp,kinetis-usbd"; + reg = <0x400a4000 0x1000>; + interrupts = <36 1>; + interrupt-names = "usb"; + num-bidir-endpoints = <16>; + status = "disabled"; + no-voltage-regulator; + }; }; }; From 03aef0d156e09e8a125876f37e86cbb825206443 Mon Sep 17 00:00:00 2001 From: Neil Chen Date: Mon, 19 Jan 2026 10:38:22 +0800 Subject: [PATCH 2248/3659] boards: nxp: frdm_mcxaxx6: Support usb for NXP frdm_mcxaxx6 board Support usb for NXP frdm_mcxa1366 and frdm_mcxa266 board. Test it using samples/subsys/usb/console and tests/drivers/udc Signed-off-by: Neil Chen --- boards/nxp/frdm_mcxaxx6/board.c | 5 +++++ boards/nxp/frdm_mcxaxx6/frdm_mcxa266.dts | 5 +++++ boards/nxp/frdm_mcxaxx6/frdm_mcxa266.yaml | 1 + boards/nxp/frdm_mcxaxx6/frdm_mcxa366.dts | 5 +++++ boards/nxp/frdm_mcxaxx6/frdm_mcxa366.yaml | 1 + 5 files changed, 17 insertions(+) diff --git a/boards/nxp/frdm_mcxaxx6/board.c b/boards/nxp/frdm_mcxaxx6/board.c index 42f93aee5a0d..261aefc4dc83 100644 --- a/boards/nxp/frdm_mcxaxx6/board.c +++ b/boards/nxp/frdm_mcxaxx6/board.c @@ -315,6 +315,11 @@ void board_early_init_hook(void) CLOCK_AttachClk(kFRO_HF_DIV_to_FLEXCAN0); #endif +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(usb)) + RESET_PeripheralReset(kUSB0_RST_SHIFT_RSTn); + CLOCK_EnableUsbfsClock(); +#endif + /* Set SystemCoreClock variable. */ SystemCoreClock = CLOCK_INIT_CORE_CLOCK; } diff --git a/boards/nxp/frdm_mcxaxx6/frdm_mcxa266.dts b/boards/nxp/frdm_mcxaxx6/frdm_mcxa266.dts index d615167a293d..108f26934ef9 100644 --- a/boards/nxp/frdm_mcxaxx6/frdm_mcxa266.dts +++ b/boards/nxp/frdm_mcxaxx6/frdm_mcxa266.dts @@ -47,3 +47,8 @@ &flexio0 { status = "okay"; }; + +zephyr_udc0: &usb { + status = "okay"; + num-bidir-endpoints = <8>; +}; diff --git a/boards/nxp/frdm_mcxaxx6/frdm_mcxa266.yaml b/boards/nxp/frdm_mcxaxx6/frdm_mcxa266.yaml index 5ec746be9a2e..41babeba153d 100644 --- a/boards/nxp/frdm_mcxaxx6/frdm_mcxa266.yaml +++ b/boards/nxp/frdm_mcxaxx6/frdm_mcxa266.yaml @@ -27,4 +27,5 @@ supported: - entropy - can - arduino_gpio + - usbd vendor: nxp diff --git a/boards/nxp/frdm_mcxaxx6/frdm_mcxa366.dts b/boards/nxp/frdm_mcxaxx6/frdm_mcxa366.dts index f3a3c4e8722e..910c52a817c4 100644 --- a/boards/nxp/frdm_mcxaxx6/frdm_mcxa366.dts +++ b/boards/nxp/frdm_mcxaxx6/frdm_mcxa366.dts @@ -58,3 +58,8 @@ &flexio0 { status = "okay"; }; + +zephyr_udc0: &usb { + status = "okay"; + num-bidir-endpoints = <8>; +}; diff --git a/boards/nxp/frdm_mcxaxx6/frdm_mcxa366.yaml b/boards/nxp/frdm_mcxaxx6/frdm_mcxa366.yaml index 5a22a85e8071..0655c805003d 100644 --- a/boards/nxp/frdm_mcxaxx6/frdm_mcxa366.yaml +++ b/boards/nxp/frdm_mcxaxx6/frdm_mcxa366.yaml @@ -28,4 +28,5 @@ supported: - entropy - can - arduino_gpio + - usbd vendor: nxp From b7106127af1d9053fe53b4cea53939ed31874293 Mon Sep 17 00:00:00 2001 From: Felix Wang Date: Mon, 27 Oct 2025 11:27:21 +0800 Subject: [PATCH 2249/3659] drivers: counter: Support multiple interrputs For devices like MCXE247, the FTM peripheral instance has multiple interrupts. In this patch, add FTM_CONFIG_FUNC macro to support single or multiple interrupts based on irq number. Signed-off-by: Felix Wang --- drivers/counter/counter_mcux_ftm.c | 38 ++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/drivers/counter/counter_mcux_ftm.c b/drivers/counter/counter_mcux_ftm.c index c82b38273134..1e0a512edbe3 100644 --- a/drivers/counter/counter_mcux_ftm.c +++ b/drivers/counter/counter_mcux_ftm.c @@ -165,6 +165,35 @@ static DEVICE_API(counter, mcux_ftm_driver_api) = { .get_freq = mcux_ftm_get_freq, }; +#define FTM_IRQ_CONNECT_IDX(idx, node_id) \ + do { \ + IRQ_CONNECT(DT_IRQ_BY_IDX(node_id, idx, irq), \ + DT_IRQ_BY_IDX(node_id, idx, priority), \ + mcux_ftm_isr, DEVICE_DT_GET(node_id), 0); \ + irq_enable(DT_IRQ_BY_IDX(node_id, idx, irq)); \ + } while (0) + +#define FTM_CONFIG_FUNC(n) \ + static void mcux_ftm_irq_config_##n(const struct device *dev) \ + { \ + ARG_UNUSED(dev); \ + COND_CODE_1( \ + IS_EQ(DT_NUM_IRQS(DT_DRV_INST(n)), 1), \ + (/* single IRQ */ \ + IRQ_CONNECT(DT_INST_IRQN(n), \ + DT_INST_IRQ(n, priority), \ + mcux_ftm_isr, \ + DEVICE_DT_INST_GET(n), 0); \ + irq_enable(DT_INST_IRQN(n)); \ + ), \ + (/* multiple IRQs */ \ + LISTIFY(DT_NUM_IRQS(DT_DRV_INST(n)), \ + FTM_IRQ_CONNECT_IDX, \ + (;), \ + DT_DRV_INST(n)); \ + )); \ + } + #define TO_FTM_PRESCALE_DIVIDE(val) _DO_CONCAT(kFTM_Prescale_Divide_, val) #define COUNTER_MCUX_FTM_DEVICE_INIT(n) \ @@ -187,12 +216,7 @@ static DEVICE_API(counter, mcux_ftm_driver_api) = { \ DEVICE_DT_INST_DEFINE(n, mcux_ftm_init, NULL, &mcux_ftm_data_##n, &mcux_ftm_config_##n, \ POST_KERNEL, CONFIG_COUNTER_INIT_PRIORITY, &mcux_ftm_driver_api); \ - \ - static void mcux_ftm_irq_config_##n(const struct device *dev) \ - { \ - IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority), mcux_ftm_isr, \ - DEVICE_DT_INST_GET(n), 0); \ - irq_enable(DT_INST_IRQN(n)); \ - } + \ + FTM_CONFIG_FUNC(n) DT_INST_FOREACH_STATUS_OKAY(COUNTER_MCUX_FTM_DEVICE_INIT) From c6e6463918b6f94d5a6fa3b2f95aa9149d8e51a2 Mon Sep 17 00:00:00 2001 From: Felix Wang Date: Mon, 27 Oct 2025 13:57:23 +0800 Subject: [PATCH 2250/3659] boards: nxp: frdm_mcxe247: Fix typo in ASSERT_ASYNC_CLK_DIV_VALID The val should be 32, not 2. Signed-off-by: Felix Wang --- boards/nxp/frdm_mcxe247/board.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boards/nxp/frdm_mcxe247/board.c b/boards/nxp/frdm_mcxe247/board.c index 179acb77ae83..ec1ac0b00dbb 100644 --- a/boards/nxp/frdm_mcxe247/board.c +++ b/boards/nxp/frdm_mcxe247/board.c @@ -16,7 +16,7 @@ #define ASSERT_ASYNC_CLK_DIV_VALID(val, str) \ BUILD_ASSERT(val == 0 || val == 1 || val == 2 || val == 4 || \ - val == 8 || val == 16 || val == 2 || val == 64, str) + val == 8 || val == 16 || val == 32 || val == 64, str) #define kSCG_AsyncClkDivBy0 kSCG_AsyncClkDisable From a2e3327273d9ccdc6c60b566080aca3fe7fe552c Mon Sep 17 00:00:00 2001 From: Felix Wang Date: Mon, 27 Oct 2025 13:59:44 +0800 Subject: [PATCH 2251/3659] boards: nxp: frdm_mcxe247: Enable FTM0 in device tree Enable FTM0 for frdm_mcxe247, which using fircdiv1_clk. Signed-off-by: Felix Wang --- boards/nxp/frdm_mcxe247/frdm_mcxe247.dts | 6 +++++- dts/arm/nxp/nxp_mcxe24x_common.dtsi | 3 ++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/boards/nxp/frdm_mcxe247/frdm_mcxe247.dts b/boards/nxp/frdm_mcxe247/frdm_mcxe247.dts index aaba060b124a..aec3f7a43f6e 100644 --- a/boards/nxp/frdm_mcxe247/frdm_mcxe247.dts +++ b/boards/nxp/frdm_mcxe247/frdm_mcxe247.dts @@ -153,7 +153,7 @@ }; &fircdiv1_clk { - clock-div = <1>; + clock-div = <8>; }; &fircdiv2_clk { @@ -268,6 +268,10 @@ status = "okay"; }; +&ftm0 { + status = "okay"; +}; + &wdog { status = "okay"; }; diff --git a/dts/arm/nxp/nxp_mcxe24x_common.dtsi b/dts/arm/nxp/nxp_mcxe24x_common.dtsi index d9b6def2fb98..feff15d88f65 100644 --- a/dts/arm/nxp/nxp_mcxe24x_common.dtsi +++ b/dts/arm/nxp/nxp_mcxe24x_common.dtsi @@ -371,7 +371,8 @@ interrupts = <99 0>, <100 0>, <101 0>, <102 0>, <104 0>; interrupt-names = "0-1", "2-3", "4-5", "6-7", "overflow"; clocks = <&pcc 0xe0 KINETIS_PCC_SRC_FIRC_ASYNC>; - prescaler = <1>; + clock-source = "external"; + prescaler = <32>; status = "disabled"; }; From 765476405a8ee3dc42c07361aa540f2975c11712 Mon Sep 17 00:00:00 2001 From: Felix Wang Date: Mon, 27 Oct 2025 15:42:22 +0800 Subject: [PATCH 2252/3659] tests: drivers: pwm: Enable FTM pwm test on frdm_mcxe247 Provide overlay file to configure ftm to enable pwm_api and pwm_loopback Signed-off-by: Felix Wang --- .../pwm/pwm_api/boards/frdm_mcxe247.overlay | 33 ++++++++++ .../pwm_loopback/boards/frdm_mcxe247.overlay | 60 +++++++++++++++++++ 2 files changed, 93 insertions(+) create mode 100644 tests/drivers/pwm/pwm_api/boards/frdm_mcxe247.overlay create mode 100644 tests/drivers/pwm/pwm_loopback/boards/frdm_mcxe247.overlay diff --git a/tests/drivers/pwm/pwm_api/boards/frdm_mcxe247.overlay b/tests/drivers/pwm/pwm_api/boards/frdm_mcxe247.overlay new file mode 100644 index 000000000000..39834e702c43 --- /dev/null +++ b/tests/drivers/pwm/pwm_api/boards/frdm_mcxe247.overlay @@ -0,0 +1,33 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + pwm-test = &ftm3; + }; +}; + +&pinctrl { + ftm3_default: ftm3_default { + group0 { + pinmux = , + , + ; + drive-strength = "low"; + slew-rate = "slow"; + }; + }; +}; + +&ftm3 { + status = "okay"; + compatible = "nxp,ftm-pwm"; + clock-source = "external"; + prescaler = <128>; + #pwm-cells = <3>; + pinctrl-0 = <&ftm3_default>; + pinctrl-names = "default"; +}; diff --git a/tests/drivers/pwm/pwm_loopback/boards/frdm_mcxe247.overlay b/tests/drivers/pwm/pwm_loopback/boards/frdm_mcxe247.overlay new file mode 100644 index 000000000000..cbe95e008778 --- /dev/null +++ b/tests/drivers/pwm/pwm_loopback/boards/frdm_mcxe247.overlay @@ -0,0 +1,60 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include + +&pinctrl { + ftm0_default: ftm0_default { + group0 { + pinmux = , + , + ; + drive-strength = "low"; + slew-rate = "slow"; + }; + }; + + ftm3_default: ftm3_default { + group0 { + pinmux = , + , + ; + drive-strength = "low"; + slew-rate = "slow"; + }; + }; +}; + +/* To test this sample, connect + * PTC11(J1-12) ---> PTD15(J1-14) + */ + +/ { + pwm_loopback_0 { + compatible = "test-pwm-loopback"; + pwms = <&ftm3 5 0 PWM_POLARITY_NORMAL>, /* PTC11 J1 pin 12 out*/ + <&ftm0 0 0 PWM_POLARITY_NORMAL>; /* PTD15 J1 pin 14 in */ + }; +}; + +&ftm0 { + status = "okay"; + compatible = "nxp,ftm-pwm"; + clock-source = "external"; + prescaler = <32>; + #pwm-cells = <3>; + pinctrl-0 = <&ftm0_default>; + pinctrl-names = "default"; +}; + +&ftm3 { + status = "okay"; + compatible = "nxp,ftm-pwm"; + clock-source = "external"; + prescaler = <128>; + #pwm-cells = <3>; + pinctrl-0 = <&ftm3_default>; + pinctrl-names = "default"; +}; From 0bce58b4feb6951cc089ebf557884fe0d661fef4 Mon Sep 17 00:00:00 2001 From: Felix Wang Date: Wed, 26 Nov 2025 08:15:39 +0530 Subject: [PATCH 2253/3659] boards: nxp: frdm_mcxe247: Add supported list in board yaml Newly supported items: counter, pwm Signed-off-by: Felix Wang --- boards/nxp/frdm_mcxe247/frdm_mcxe247.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/boards/nxp/frdm_mcxe247/frdm_mcxe247.yaml b/boards/nxp/frdm_mcxe247/frdm_mcxe247.yaml index 108f121b728c..0eb717c5f584 100644 --- a/boards/nxp/frdm_mcxe247/frdm_mcxe247.yaml +++ b/boards/nxp/frdm_mcxe247/frdm_mcxe247.yaml @@ -24,5 +24,7 @@ supported: - arduino_gpio - comparator - dma + - counter + - pwm - watchdog vendor: nxp From 284a30053f437a42793b168fe23b4f1dc761ccdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gu=C3=B0ni=20M=C3=A1r=20Gilbert?= Date: Sun, 18 Jan 2026 12:05:34 +0000 Subject: [PATCH 2254/3659] scripts: twister: don't parse west modules in TestPlan MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit TwisterEnv already parses west modules during initialization, but TestPlan was parsing them again via zephyr_module.parse_modules(), duplicating work. Store the parsed module objects on TwisterEnv (self.modules) and have TestPlan derive its module name list from env.modules instead. This drops the redundant parse in TestPlan by removing handle_modules() and its call site. Each call to parse_modules() takes around 250-300ms on my end. Update twister unit tests Signed-off-by: Guðni Már Gilbert --- .../pylib/twister/twisterlib/environment.py | 26 +++--- scripts/pylib/twister/twisterlib/testplan.py | 10 +-- scripts/tests/twister/test_testplan.py | 86 ++++++++++--------- 3 files changed, 60 insertions(+), 62 deletions(-) diff --git a/scripts/pylib/twister/twisterlib/environment.py b/scripts/pylib/twister/twisterlib/environment.py index 7dab35210d68..fc2badfec9a0 100644 --- a/scripts/pylib/twister/twisterlib/environment.py +++ b/scripts/pylib/twister/twisterlib/environment.py @@ -1067,28 +1067,28 @@ def __init__(self, options : argparse.Namespace, default_options=None) -> None: self.outdir = os.path.abspath(options.outdir) self.snippet_roots = [Path(ZEPHYR_BASE)] - modules = zephyr_module.parse_modules(ZEPHYR_BASE) - for module in modules: - snippet_root = module.meta.get("build", {}).get("settings", {}).get("snippet_root") - if snippet_root: - self.snippet_roots.append(Path(module.project) / snippet_root) - - self.soc_roots = [Path(ZEPHYR_BASE), Path(ZEPHYR_BASE) / 'subsys' / 'testsuite'] self.dts_roots = [Path(ZEPHYR_BASE)] self.arch_roots = [Path(ZEPHYR_BASE)] + modules = zephyr_module.parse_modules(ZEPHYR_BASE) for module in modules: - soc_root = module.meta.get("build", {}).get("settings", {}).get("soc_root") + settings = module.meta.get("build", {}).get("settings", {}) + project = Path(module.project) + snippet_root = settings.get("snippet_root") + if snippet_root: + self.snippet_roots.append(project / snippet_root) + soc_root = settings.get("soc_root") if soc_root: - self.soc_roots.append(Path(module.project) / Path(soc_root)) - dts_root = module.meta.get("build", {}).get("settings", {}).get("dts_root") + self.soc_roots.append(project / Path(soc_root)) + dts_root = settings.get("dts_root") if dts_root: - self.dts_roots.append(Path(module.project) / Path(dts_root)) - arch_root = module.meta.get("build", {}).get("settings", {}).get("arch_root") + self.dts_roots.append(project / Path(dts_root)) + arch_root = settings.get("arch_root") if arch_root: - self.arch_roots.append(Path(module.project) / Path(arch_root)) + self.arch_roots.append(project / Path(arch_root)) + self.modules = [m.meta for m in modules] self.hwm = None self.test_config = options.test_config diff --git a/scripts/pylib/twister/twisterlib/testplan.py b/scripts/pylib/twister/twisterlib/testplan.py index a9e65a11df6b..6213bc5d7d9b 100755 --- a/scripts/pylib/twister/twisterlib/testplan.py +++ b/scripts/pylib/twister/twisterlib/testplan.py @@ -37,7 +37,6 @@ from twisterlib.statuses import TwisterStatus from twisterlib.testinstance import TestInstance from twisterlib.testsuite import TestSuite, scan_testsuite_path -from zephyr_module import parse_modules logger = logging.getLogger('twister') @@ -186,7 +185,7 @@ def __init__(self, env: Namespace): self.hwm = env.hwm # used during creating shorter build paths self.link_dir_counter = 0 - self.modules = [] + self.modules = [module.get('name') for module in self.env.modules] self.run_individual_testsuite = [] self.levels = [] @@ -210,7 +209,6 @@ def find_subtests(self): raise TwisterRuntimeError("Tests not found") def discover(self): - self.handle_modules() self.test_config = TestConfiguration(self.env.test_config) self.add_configurations() @@ -365,12 +363,6 @@ def generate_subset(self, subset, sets): self.instances.update(errors) - def handle_modules(self): - # get all enabled west projects - modules_meta = parse_modules(ZEPHYR_BASE) - self.modules = [module.meta.get('name') for module in modules_meta] - - def report(self): if self.options.test_tree: self.report_test_tree() diff --git a/scripts/tests/twister/test_testplan.py b/scripts/tests/twister/test_testplan.py index c3424efad0f8..85bd2fd14428 100644 --- a/scripts/tests/twister/test_testplan.py +++ b/scripts/tests/twister/test_testplan.py @@ -22,6 +22,18 @@ from twisterlib.testsuite import TestSuite +def mock_twister_env(): + """ Helper function to mock TwisterEnv class """ + env = mock.Mock() + + env.modules = [ + {"name": "mod1"}, + {"name": "mod2"}, + ] + + return env + + def test_testplan_add_testsuites_short(class_testplan): """ Testing add_testcase function of Testsuite class in twister """ # Test 1: Check the list of testsuites after calling add testsuites function is as expected @@ -499,7 +511,7 @@ def test_required_snippets_short( def test_testplan_get_level(): - testplan = TestPlan(env=mock.Mock()) + testplan = TestPlan(env=mock_twister_env()) lvl1 = mock.Mock() lvl1.name = 'a lvl' lvl2 = mock.Mock() @@ -559,7 +571,7 @@ def test_testplan_get_level(): ids=['no config', 'valid config'] ) def test_testplan_parse_configuration(tmp_path, config_yaml, expected_scenarios): - testplan = TestPlan(env=mock.Mock()) + testplan = TestPlan(env=mock_twister_env()) testplan.scenarios = ['sc1', 'sc1-1', 'sc1-2', 'sc2'] tmp_config_file = tmp_path / 'config_file.yaml' @@ -592,7 +604,7 @@ def test_testplan_find_subtests( expected_outs, expect_error ): - testplan = TestPlan(env=mock.Mock()) + testplan = TestPlan(env=mock_twister_env()) testplan.options = mock.Mock(sub_test=sub_tests) testplan.run_individual_testsuite = [] testplan.testsuites = { @@ -662,7 +674,7 @@ def test_testplan_discover( tmp_qf = tmp_path / qf tmp_qf.write_text(data) - env = mock.Mock() + env = mock_twister_env() env.test_config = tmp_tc testplan = TestPlan(env=env) testplan.options = mock.Mock( @@ -816,8 +828,9 @@ def test_testplan_load( """ load_tests_file = tmp_path / 'load_tests.json' load_tests_file.write_text(load_tests_json) - - testplan = TestPlan(env=mock.Mock(outdir=tmp_path)) + env = mock_twister_env() + env.outdir = tmp_path + testplan = TestPlan(env=env) testplan.testsuites = { 'ts1': mock.Mock(testcases=[], extra_configs=[]), 'ts2': mock.Mock(testcases=[], extra_configs=[]), @@ -930,7 +943,7 @@ def test_testplan_generate_subset( sets, expected_subset ): - testplan = TestPlan(env=mock.Mock()) + testplan = TestPlan(env=mock_twister_env()) testplan.options = mock.Mock( device_testing=device_testing, shuffle_tests=shuffle, @@ -953,18 +966,6 @@ def test_testplan_generate_subset( expected_subset -def test_testplan_handle_modules(): - testplan = TestPlan(env=mock.Mock()) - - modules = [mock.Mock(meta={'name': 'name1'}), - mock.Mock(meta={'name': 'name2'})] - - with mock.patch('twisterlib.testplan.parse_modules', return_value=modules): - testplan.handle_modules() - - assert testplan.modules == ['name1', 'name2'] - - TESTDATA_6 = [ (True, False, False, 0, 'report_test_tree'), (True, True, False, 0, 'report_test_tree'), @@ -990,7 +991,7 @@ def test_testplan_report( expected_res, expected_method ): - testplan = TestPlan(env=mock.Mock()) + testplan = TestPlan(env=mock_twister_env()) testplan.report_test_tree = mock.Mock() testplan.report_test_list = mock.Mock() testplan.report_tag_list = mock.Mock() @@ -1065,7 +1066,7 @@ def test_testplan_report_duplicates( def mock_get(name): return list(filter(lambda x: name in x.scenarios, testsuites)) - testplan = TestPlan(env=mock.Mock()) + testplan = TestPlan(env=mock_twister_env()) testplan.scenarios = [scenario for testsuite in testsuites \ for scenario in testsuite.scenarios] testplan.get_testsuite = mock.Mock(side_effect=mock_get) @@ -1081,7 +1082,7 @@ def mock_get(name): def test_testplan_report_tag_list(capfd): - testplan = TestPlan(env=mock.Mock()) + testplan = TestPlan(env=mock_twister_env()) testplan.testsuites = { 'testsuite0': mock.Mock(tags=set(['tag1', 'tag2'])), 'testsuite1': mock.Mock(tags=set(['tag1', 'tag2', 'tag3'])), @@ -1102,7 +1103,7 @@ def test_testplan_report_tag_list(capfd): def test_testplan_report_test_tree(capfd): - testplan = TestPlan(env=mock.Mock()) + testplan = TestPlan(env=mock_twister_env()) testplan.get_tests_list = mock.Mock( return_value=['1.dummy.case.1', '1.dummy.case.2', '2.dummy.case.1', '2.dummy.case.2', @@ -1160,7 +1161,7 @@ def test_testplan_report_test_tree(capfd): def test_testplan_report_test_list(capfd): - testplan = TestPlan(env=mock.Mock()) + testplan = TestPlan(env=mock_twister_env()) testplan.get_tests_list = mock.Mock( return_value=['4.dummy.case.1', '4.dummy.case.2', '3.dummy.case.2', '2.dummy.case.2', @@ -1214,8 +1215,10 @@ def test_testplan_add_configurations( expected_platform_names, expected_defaults ): - env = mock.Mock(board_roots=[tmp_path / 'boards'], soc_roots=[tmp_path], arch_roots=[tmp_path]) - + env = mock_twister_env() + env.board_roots = [tmp_path / 'boards'] + env.soc_roots = [tmp_path] + env.arch_roots = [tmp_path] testplan = TestPlan(env=env) testplan.test_config = mock.Mock() testplan.test_config.override_default_platforms = override_default_platforms @@ -1251,7 +1254,7 @@ def mock_gen_plat(board_roots, soc_roots, arch_roots): def test_testplan_get_all_tests(): - testplan = TestPlan(env=mock.Mock()) + testplan = TestPlan(env=mock_twister_env()) tc1 = mock.Mock() tc1.name = 'tc1' tc2 = mock.Mock() @@ -1403,11 +1406,10 @@ def test_testplan_add_testsuites(tmp_path, testsuite_filter, use_alt_root, detai testfile_3 = tmp_alt_good_test_dir / 'testcase.yaml' testfile_3.write_text(testcase_yaml_3) - env = mock.Mock( - test_roots=[tmp_test_root_dir], - options=mock.Mock(detailed_test_id=detailed_id), - alt_config_root=[tmp_alt_test_root_dir] if use_alt_root else [] - ) + env = mock_twister_env() + env.test_roots=[tmp_test_root_dir] + env.options=mock.Mock(detailed_test_id=detailed_id) + env.alt_config_root=[tmp_alt_test_root_dir] if use_alt_root else [] testplan = TestPlan(env=env) @@ -1418,7 +1420,7 @@ def test_testplan_add_testsuites(tmp_path, testsuite_filter, use_alt_root, detai def test_testplan_str(): - testplan = TestPlan(env=mock.Mock()) + testplan = TestPlan(env=mock_twister_env()) testplan.name = 'my name' res = testplan.__str__() @@ -1437,7 +1439,7 @@ def test_testplan_str(): ids=['platform exists', 'no platform'] ) def test_testplan_get_platform(name, expect_found): - testplan = TestPlan(env=mock.Mock()) + testplan = TestPlan(env=mock_twister_env()) p1 = mock.Mock() p1.name = 'some platform' p1.aliases = [p1.name] @@ -1495,7 +1497,9 @@ def get_platform(name): ts5.name = 'TestSuite 5' ts5.toolchain = 'zephyr' - testplan = TestPlan(env=mock.Mock(outdir=os.path.join('out', 'dir'))) + env = mock_twister_env() + env.outdir = os.path.join('out', 'dir') + testplan = TestPlan(env=env) testplan.options = mock.Mock(device_testing=device_testing, test_only=True, report_summary=None) testplan.testsuites = { 'TestSuite 1': ts1, @@ -1703,7 +1707,7 @@ def get_platform(name): def test_testplan_add_instances(): - testplan = TestPlan(env=mock.Mock()) + testplan = TestPlan(env=mock_twister_env()) instance1 = mock.Mock() instance1.name = 'instance 1' instance2 = mock.Mock() @@ -1719,7 +1723,7 @@ def test_testplan_add_instances(): def test_testplan_get_testcase(): - testplan = TestPlan(env=mock.Mock()) + testplan = TestPlan(env=mock_twister_env()) testplan.testsuites = { 'test1.suite0': mock.Mock(testcases=[mock.Mock(), mock.Mock()]), 'test1.suite1': mock.Mock(testcases=[mock.Mock(), mock.Mock()]), @@ -1746,7 +1750,7 @@ def test_testplan_get_testcase(): def test_testplan_verify_platforms_existence(caplog): - testplan = TestPlan(env=mock.Mock()) + testplan = TestPlan(env=mock_twister_env()) testplan.platform_names = ['a platform', 'other platform'] platform_names = ['other platform', 'some platform'] @@ -1784,7 +1788,9 @@ def mock_link(links_dir_path, instance): } expected_instances = [instances['inst0'], instances['inst2']] - testplan = TestPlan(env=mock.Mock(outdir=outdir)) + env = mock_twister_env() + env.outdir=outdir + testplan = TestPlan(env=env) testplan._create_build_dir_link = mock.Mock(side_effect=mock_link) testplan.instances = instances @@ -1831,7 +1837,7 @@ def mock_join(*paths): mock.patch('subprocess.call', side_effect=mock_call), \ mock.patch('os.path.join', side_effect=mock_join): - testplan = TestPlan(env=mock.Mock()) + testplan = TestPlan(env=mock_twister_env()) links_dir_path = os.path.join('links', 'path') instance_build_dir = os.path.join('some', 'far', 'off', 'build', 'dir') instance = mock.Mock(build_dir=instance_build_dir) From 608fdac2d74c09f319cf4bf1d730aa98e73bcebe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Tue, 20 Jan 2026 23:12:27 +0100 Subject: [PATCH 2255/3659] doc: release: convert broken zephyr_file links to literal paths MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix dead links by replacing them to normal strings. This is in preparation for a fix in zephyr_file role link check that will make the checks more strict and fail on these even if they hadn't been flagged until now. Signed-off-by: Benjamin Cabé --- doc/releases/release-notes-2.0.rst | 4 ++-- doc/releases/release-notes-2.1.rst | 2 +- doc/releases/release-notes-2.6.rst | 2 +- doc/releases/release-notes-3.2.rst | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/releases/release-notes-2.0.rst b/doc/releases/release-notes-2.0.rst index 7993f8d33ede..357a9bdeb081 100644 --- a/doc/releases/release-notes-2.0.rst +++ b/doc/releases/release-notes-2.0.rst @@ -451,10 +451,10 @@ Build and Infrastructure * The devicetree Python scripts have been rewritten to be more robust and easier to understand and change. The new scripts are these three files: - - :zephyr_file:`scripts/dts/dtlib.py` -- a low-level :file:`.dts` parsing + - ``scripts/dts/dtlib.py`` -- a low-level :file:`.dts` parsing library - - :zephyr_file:`scripts/dts/edtlib.py` -- a higher-level library that adds + - ``scripts/dts/edtlib.py`` -- a higher-level library that adds information from bindings - :zephyr_file:`scripts/dts/gen_defines.py` -- generates a C header from the diff --git a/doc/releases/release-notes-2.1.rst b/doc/releases/release-notes-2.1.rst index 0b0e81495110..e908a4b52bda 100644 --- a/doc/releases/release-notes-2.1.rst +++ b/doc/releases/release-notes-2.1.rst @@ -412,7 +412,7 @@ Build and Infrastructure :zephyr_file:`scripts/kconfig/kconfigfunctions.py`. See :ref:`kconfig-functions` for usage details. For sanitycheck yaml usage we should utilize functions from - :zephyr_file:`scripts/sanity_chk/expr_parser.py`. Its possible that a + ``scripts/sanity_chk/expr_parser.py``. Its possible that a new function might be required for a particular use pattern that isn't currently supported. diff --git a/doc/releases/release-notes-2.6.rst b/doc/releases/release-notes-2.6.rst index 53864fa2508b..21c4b2161a58 100644 --- a/doc/releases/release-notes-2.6.rst +++ b/doc/releases/release-notes-2.6.rst @@ -854,7 +854,7 @@ Build and Infrastructure * pyocd runner: board-specific pyOCD configuration files in YAML can now be placed in :file:`support/pyocd.yaml` inside the board directory. See - :zephyr_file:`boards/arm/reel_board/support/pyocd.yaml` for an example, + ``boards/arm/reel_board/support/pyocd.yaml`` for an example, and the pyOCD documentation for details on its configuration format. * ``west spdx``: new command which can be used to generate SPDX software diff --git a/doc/releases/release-notes-3.2.rst b/doc/releases/release-notes-3.2.rst index a7852db2e06e..f11bad196557 100644 --- a/doc/releases/release-notes-3.2.rst +++ b/doc/releases/release-notes-3.2.rst @@ -52,14 +52,14 @@ Changes in this release release. The :zephyr_file:`scripts/utils/migrate_includes.py` script is provided to automate the migration. -* :zephyr_file:`include/zephyr/zephyr.h` no longer defines ``__ZEPHYR__``. +* ``include/zephyr/zephyr.h`` no longer defines ``__ZEPHYR__``. This definition can be used by third-party code to compile code conditional to Zephyr. The definition is already injected by the Zephyr build system. Therefore, any third-party code integrated using the Zephyr build system will require no changes. External build systems will need to inject the definition by themselves, if they did not already. -* :zephyr_file:`include/zephyr/zephyr.h` has been deprecated in favor of +* ``include/zephyr/zephyr.h`` has been deprecated in favor of :zephyr_file:`include/zephyr/kernel.h`, since it only included that header. No changes are required by applications other than replacing ``#include `` with ``#include ``. From 474d502df32ab54160d08082e18c305788d1cf3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Tue, 20 Jan 2026 23:07:22 +0100 Subject: [PATCH 2256/3659] doc: link-roles: Update path handling to use document name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use docname instead of source from get_source_and_line() because source can be a relative path to an included file (e.g., .rst.inc), while docname is always the main document being processed. Signed-off-by: Benjamin Cabé --- doc/_extensions/zephyr/link-roles.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/_extensions/zephyr/link-roles.py b/doc/_extensions/zephyr/link-roles.py index abc732d6e80d..2a82be6b9432 100644 --- a/doc/_extensions/zephyr/link-roles.py +++ b/doc/_extensions/zephyr/link-roles.py @@ -119,7 +119,8 @@ def role( ) if module == config.link_roles_manifest_project: - p = Path(source).relative_to(inliner.document.settings.env.srcdir) + docname = inliner.document.settings.env.docname + p = Path(docname) if ( not any( p.match(glob) From 98573a57cdd857cc78cbd2fc13e56a6a755b4b92 Mon Sep 17 00:00:00 2001 From: Eden Uhde Date: Sun, 18 Jan 2026 01:06:13 +0000 Subject: [PATCH 2257/3659] drivers: display: ls0xx: add Kconfig setting VCOM thread priority for ls0xx The ls0xx driver VCOM inversion thread has a hardcoded priority of 3, while in some applications this may be considered lower priority than time sensitive tasks, maintaining close to an even polarity balance is best, but this change allows developers to determine the approach. Signed-off-by: Eden Uhde --- drivers/display/Kconfig.ls0xx | 7 +++++++ drivers/display/ls0xx.c | 3 ++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/display/Kconfig.ls0xx b/drivers/display/Kconfig.ls0xx index 04876a374d22..0684184f2d6e 100644 --- a/drivers/display/Kconfig.ls0xx +++ b/drivers/display/Kconfig.ls0xx @@ -8,3 +8,10 @@ config LS0XX select SPI help Enable driver for sharp memory display series LS0XXX7DXXX + +config LS0XX_VCOM_THREAD_PRIO + int "Priority for the VCOM inversion thread" + default 3 + depends on LS0XX + help + Set the VCOM inversion thread priority diff --git a/drivers/display/ls0xx.c b/drivers/display/ls0xx.c index f85ae1c6a402..2e354858ca79 100644 --- a/drivers/display/ls0xx.c +++ b/drivers/display/ls0xx.c @@ -42,6 +42,7 @@ LOG_MODULE_REGISTER(ls0xx, CONFIG_DISPLAY_LOG_LEVEL); #define LS0XX_BIT_WRITECMD 0x01 #define LS0XX_BIT_VCOM 0x02 #define LS0XX_BIT_CLEAR 0x04 +#define LS0XX_VCOM_PRIO CONFIG_LS0XX_VCOM_THREAD_PRIO /* These timings are based on: * - A view that 1 frame dropped at 10fps is more than any reasonable wait. @@ -329,7 +330,7 @@ static int ls0xx_init(const struct device *dev) /* Start thread for toggling VCOM */ k_tid_t vcom_toggle_tid = k_thread_create( &vcom_toggle_thread, vcom_toggle_stack, K_THREAD_STACK_SIZEOF(vcom_toggle_stack), - ls0xx_vcom_toggle, (void *)dev, NULL, NULL, 3, 0, K_NO_WAIT); + ls0xx_vcom_toggle, (void *)dev, NULL, NULL, LS0XX_VCOM_PRIO, 0, K_NO_WAIT); k_thread_name_set(vcom_toggle_tid, "ls0xx_vcom"); #endif /* USE_VCOM_THREAD */ From 3658dbd489fb97afdcd38bd29732b4a76e32e5a9 Mon Sep 17 00:00:00 2001 From: Fabian Blatz Date: Sat, 17 Jan 2026 10:36:08 +0100 Subject: [PATCH 2258/3659] manifest: Update LVGL to 9.4.X Update the west yaml to point to the new LVGL version. Update CMakeLists and samples accordingly. Signed-off-by: Fabian Blatz --- modules/lvgl/CMakeLists.txt | 135 ++++++++++++------ samples/modules/lvgl/demos/CMakeLists.txt | 85 +++++------ .../modules/lvgl/multi_display/CMakeLists.txt | 85 +++++------ west.yml | 2 +- 4 files changed, 181 insertions(+), 126 deletions(-) diff --git a/modules/lvgl/CMakeLists.txt b/modules/lvgl/CMakeLists.txt index d626ac0681f3..cc1aee1d53e1 100644 --- a/modules/lvgl/CMakeLists.txt +++ b/modules/lvgl/CMakeLists.txt @@ -33,8 +33,19 @@ zephyr_library_sources( ${LVGL_DIR}/src/core/lv_obj_style.c ${LVGL_DIR}/src/core/lv_obj_style_gen.c ${LVGL_DIR}/src/core/lv_obj_tree.c + ${LVGL_DIR}/src/core/lv_observer.c ${LVGL_DIR}/src/core/lv_refr.c + ${LVGL_DIR}/src/debugging/monkey/lv_monkey.c + ${LVGL_DIR}/src/debugging/sysmon/lv_sysmon.c + ${LVGL_DIR}/src/debugging/test/lv_test_display.c + ${LVGL_DIR}/src/debugging/test/lv_test_fs.c + ${LVGL_DIR}/src/debugging/test/lv_test_helpers.c + ${LVGL_DIR}/src/debugging/test/lv_test_indev.c + ${LVGL_DIR}/src/debugging/test/lv_test_indev_gesture.c + ${LVGL_DIR}/src/debugging/test/lv_test_screenshot_compare.c + ${LVGL_DIR}/src/debugging/vg_lite_tvg/vg_lite_matrix.c + ${LVGL_DIR}/src/display/lv_display.c ${LVGL_DIR}/src/draw/convert/lv_draw_buf_convert.c @@ -60,6 +71,7 @@ zephyr_library_sources( ${LVGL_DIR}/src/draw/lv_draw_3d.c ${LVGL_DIR}/src/draw/lv_draw_arc.c + ${LVGL_DIR}/src/draw/lv_draw_blur.c ${LVGL_DIR}/src/draw/lv_draw_buf.c ${LVGL_DIR}/src/draw/lv_draw.c ${LVGL_DIR}/src/draw/lv_draw_image.c @@ -71,6 +83,23 @@ zephyr_library_sources( ${LVGL_DIR}/src/draw/lv_draw_vector.c ${LVGL_DIR}/src/draw/lv_image_decoder.c + ${LVGL_DIR}/src/draw/nanovg/lv_draw_nanovg.c + ${LVGL_DIR}/src/draw/nanovg/lv_draw_nanovg_arc.c + ${LVGL_DIR}/src/draw/nanovg/lv_draw_nanovg_border.c + ${LVGL_DIR}/src/draw/nanovg/lv_draw_nanovg_box_shadow.c + ${LVGL_DIR}/src/draw/nanovg/lv_draw_nanovg_fill.c + ${LVGL_DIR}/src/draw/nanovg/lv_draw_nanovg_grad.c + ${LVGL_DIR}/src/draw/nanovg/lv_draw_nanovg_image.c + ${LVGL_DIR}/src/draw/nanovg/lv_draw_nanovg_label.c + ${LVGL_DIR}/src/draw/nanovg/lv_draw_nanovg_layer.c + ${LVGL_DIR}/src/draw/nanovg/lv_draw_nanovg_line.c + ${LVGL_DIR}/src/draw/nanovg/lv_draw_nanovg_mask_rect.c + ${LVGL_DIR}/src/draw/nanovg/lv_draw_nanovg_triangle.c + ${LVGL_DIR}/src/draw/nanovg/lv_draw_nanovg_vector.c + ${LVGL_DIR}/src/draw/nanovg/lv_nanovg_fbo_cache.c + ${LVGL_DIR}/src/draw/nanovg/lv_nanovg_image_cache.c + ${LVGL_DIR}/src/draw/nanovg/lv_nanovg_utils.c + ${LVGL_DIR}/src/draw/nema_gfx/lv_draw_nema_gfx_arc.c ${LVGL_DIR}/src/draw/nema_gfx/lv_draw_nema_gfx_border.c ${LVGL_DIR}/src/draw/nema_gfx/lv_draw_nema_gfx.c @@ -114,7 +143,10 @@ zephyr_library_sources( ${LVGL_DIR}/src/draw/renesas/dave2d/lv_draw_dave2d_triangle.c ${LVGL_DIR}/src/draw/renesas/dave2d/lv_draw_dave2d_utils.c + ${LVGL_DIR}/src/draw/snapshot/lv_snapshot.c + ${LVGL_DIR}/src/draw/sw/blend/lv_draw_sw_blend.c + ${LVGL_DIR}/src/draw/sw/blend/lv_draw_sw_blend_to_a8.c ${LVGL_DIR}/src/draw/sw/blend/lv_draw_sw_blend_to_al88.c ${LVGL_DIR}/src/draw/sw/blend/lv_draw_sw_blend_to_argb8888.c ${LVGL_DIR}/src/draw/sw/blend/lv_draw_sw_blend_to_argb8888_premultiplied.c @@ -127,6 +159,7 @@ zephyr_library_sources( ${LVGL_DIR}/src/draw/sw/blend/neon/lv_draw_sw_blend_neon_to_rgb888.c ${LVGL_DIR}/src/draw/sw/lv_draw_sw_arc.c ${LVGL_DIR}/src/draw/sw/lv_draw_sw_border.c + ${LVGL_DIR}/src/draw/sw/lv_draw_sw_blur.c ${LVGL_DIR}/src/draw/sw/lv_draw_sw_box_shadow.c ${LVGL_DIR}/src/draw/sw/lv_draw_sw.c ${LVGL_DIR}/src/draw/sw/lv_draw_sw_fill.c @@ -162,10 +195,13 @@ zephyr_library_sources( ${LVGL_DIR}/src/draw/vg_lite/lv_draw_vg_lite_mask_rect.c ${LVGL_DIR}/src/draw/vg_lite/lv_draw_buf_vg_lite.c - ${LVGL_DIR}/src/font/lv_binfont_loader.c + ${LVGL_DIR}/src/font/binfont_loader/lv_binfont_loader.c + ${LVGL_DIR}/src/font/font_manager/lv_font_manager.c + ${LVGL_DIR}/src/font/font_manager/lv_font_manager_recycle.c + ${LVGL_DIR}/src/font/imgfont/lv_imgfont.c ${LVGL_DIR}/src/font/lv_font.c ${LVGL_DIR}/src/font/lv_font_dejavu_16_persian_hebrew.c - ${LVGL_DIR}/src/font/lv_font_fmt_txt.c + ${LVGL_DIR}/src/font/fmt_txt/lv_font_fmt_txt.c ${LVGL_DIR}/src/font/lv_font_montserrat_10.c ${LVGL_DIR}/src/font/lv_font_montserrat_12.c ${LVGL_DIR}/src/font/lv_font_montserrat_14.c @@ -197,6 +233,7 @@ zephyr_library_sources( ${LVGL_DIR}/src/indev/lv_indev.c ${LVGL_DIR}/src/indev/lv_indev_gesture.c ${LVGL_DIR}/src/indev/lv_indev_scroll.c + ${LVGL_DIR}/src/indev/lv_gridnav.c ${LVGL_DIR}/src/layouts/flex/lv_flex.c ${LVGL_DIR}/src/layouts/grid/lv_grid.c @@ -280,6 +317,7 @@ zephyr_library_sources( ${LVGL_DIR}/src/misc/lv_math.c ${LVGL_DIR}/src/misc/lv_matrix.c ${LVGL_DIR}/src/misc/lv_palette.c + ${LVGL_DIR}/src/misc/lv_pending.c ${LVGL_DIR}/src/misc/lv_profiler_builtin.c ${LVGL_DIR}/src/misc/lv_rb.c ${LVGL_DIR}/src/misc/lv_style.c @@ -293,50 +331,45 @@ zephyr_library_sources( ${LVGL_DIR}/src/osal/lv_os.c ${LVGL_DIR}/src/others/file_explorer/lv_file_explorer.c - ${LVGL_DIR}/src/others/font_manager/lv_font_manager.c - ${LVGL_DIR}/src/others/font_manager/lv_font_manager_recycle.c ${LVGL_DIR}/src/others/fragment/lv_fragment.c ${LVGL_DIR}/src/others/fragment/lv_fragment_manager.c - ${LVGL_DIR}/src/others/gridnav/lv_gridnav.c - ${LVGL_DIR}/src/others/ime/lv_ime_pinyin.c - ${LVGL_DIR}/src/others/imgfont/lv_imgfont.c - ${LVGL_DIR}/src/others/monkey/lv_monkey.c - ${LVGL_DIR}/src/others/observer/lv_observer.c - ${LVGL_DIR}/src/others/snapshot/lv_snapshot.c - ${LVGL_DIR}/src/others/sysmon/lv_sysmon.c ${LVGL_DIR}/src/others/translation/lv_translation.c - ${LVGL_DIR}/src/others/vg_lite_tvg/vg_lite_matrix.c - ${LVGL_DIR}/src/others/xml/lv_xml_translation.c - ${LVGL_DIR}/src/others/xml/lv_xml_widget.c - ${LVGL_DIR}/src/others/xml/parsers/lv_xml_spangroup_parser.c - ${LVGL_DIR}/src/others/xml/parsers/lv_xml_dropdown_parser.c - ${LVGL_DIR}/src/others/xml/parsers/lv_xml_scale_parser.c - ${LVGL_DIR}/src/others/xml/parsers/lv_xml_arc_parser.c - ${LVGL_DIR}/src/others/xml/parsers/lv_xml_tabview_parser.c - ${LVGL_DIR}/src/others/xml/parsers/lv_xml_slider_parser.c - ${LVGL_DIR}/src/others/xml/parsers/lv_xml_chart_parser.c - ${LVGL_DIR}/src/others/xml/parsers/lv_xml_buttonmatrix_parser.c - ${LVGL_DIR}/src/others/xml/parsers/lv_xml_canvas_parser.c - ${LVGL_DIR}/src/others/xml/parsers/lv_xml_checkbox_parser.c - ${LVGL_DIR}/src/others/xml/parsers/lv_xml_calendar_parser.c - ${LVGL_DIR}/src/others/xml/parsers/lv_xml_switch_parser.c - ${LVGL_DIR}/src/others/xml/parsers/lv_xml_bar_parser.c - ${LVGL_DIR}/src/others/xml/parsers/lv_xml_button_parser.c - ${LVGL_DIR}/src/others/xml/parsers/lv_xml_label_parser.c - ${LVGL_DIR}/src/others/xml/parsers/lv_xml_keyboard_parser.c - ${LVGL_DIR}/src/others/xml/parsers/lv_xml_obj_parser.c - ${LVGL_DIR}/src/others/xml/parsers/lv_xml_textarea_parser.c - ${LVGL_DIR}/src/others/xml/parsers/lv_xml_image_parser.c - ${LVGL_DIR}/src/others/xml/parsers/lv_xml_roller_parser.c - ${LVGL_DIR}/src/others/xml/parsers/lv_xml_table_parser.c - ${LVGL_DIR}/src/others/xml/lv_xml_parser.c - ${LVGL_DIR}/src/others/xml/lv_xml_component.c - ${LVGL_DIR}/src/others/xml/lv_xml_base_types.c - ${LVGL_DIR}/src/others/xml/lv_xml_style.c - ${LVGL_DIR}/src/others/xml/lv_xml_test.c - ${LVGL_DIR}/src/others/xml/lv_xml_utils.c - ${LVGL_DIR}/src/others/xml/lv_xml.c - ${LVGL_DIR}/src/others/xml/lv_xml_update.c + ${LVGL_DIR}/src/xml/lv_xml_translation.c + ${LVGL_DIR}/src/xml/lv_xml_widget.c + ${LVGL_DIR}/src/xml/parsers/lv_xml_spangroup_parser.c + ${LVGL_DIR}/src/xml/parsers/lv_xml_dropdown_parser.c + ${LVGL_DIR}/src/xml/parsers/lv_xml_scale_parser.c + ${LVGL_DIR}/src/xml/parsers/lv_xml_arc_parser.c + ${LVGL_DIR}/src/xml/parsers/lv_xml_tabview_parser.c + ${LVGL_DIR}/src/xml/parsers/lv_xml_slider_parser.c + ${LVGL_DIR}/src/xml/parsers/lv_xml_chart_parser.c + ${LVGL_DIR}/src/xml/parsers/lv_xml_buttonmatrix_parser.c + ${LVGL_DIR}/src/xml/parsers/lv_xml_canvas_parser.c + ${LVGL_DIR}/src/xml/parsers/lv_xml_checkbox_parser.c + ${LVGL_DIR}/src/xml/parsers/lv_xml_calendar_parser.c + ${LVGL_DIR}/src/xml/parsers/lv_xml_switch_parser.c + ${LVGL_DIR}/src/xml/parsers/lv_xml_bar_parser.c + ${LVGL_DIR}/src/xml/parsers/lv_xml_button_parser.c + ${LVGL_DIR}/src/xml/parsers/lv_xml_label_parser.c + ${LVGL_DIR}/src/xml/parsers/lv_xml_keyboard_parser.c + ${LVGL_DIR}/src/xml/parsers/lv_xml_obj_parser.c + ${LVGL_DIR}/src/xml/parsers/lv_xml_qrcode_parser.c + ${LVGL_DIR}/src/xml/parsers/lv_xml_textarea_parser.c + ${LVGL_DIR}/src/xml/parsers/lv_xml_image_parser.c + ${LVGL_DIR}/src/xml/parsers/lv_xml_imagebutton_parser.c + ${LVGL_DIR}/src/xml/parsers/lv_xml_roller_parser.c + ${LVGL_DIR}/src/xml/parsers/lv_xml_spinbox_parser.c + ${LVGL_DIR}/src/xml/parsers/lv_xml_spinner_parser.c + ${LVGL_DIR}/src/xml/parsers/lv_xml_table_parser.c + ${LVGL_DIR}/src/xml/lv_xml_parser.c + ${LVGL_DIR}/src/xml/lv_xml_component.c + ${LVGL_DIR}/src/xml/lv_xml_base_types.c + ${LVGL_DIR}/src/xml/lv_xml_load.c + ${LVGL_DIR}/src/xml/lv_xml_style.c + ${LVGL_DIR}/src/xml/lv_xml_test.c + ${LVGL_DIR}/src/xml/lv_xml_utils.c + ${LVGL_DIR}/src/xml/lv_xml.c + ${LVGL_DIR}/src/xml/lv_xml_update.c ${LVGL_DIR}/src/stdlib/builtin/lv_tlsf.c ${LVGL_DIR}/src/stdlib/clib/lv_string_clib.c @@ -369,6 +402,7 @@ zephyr_library_sources( ${LVGL_DIR}/src/widgets/dropdown/lv_dropdown.c ${LVGL_DIR}/src/widgets/imagebutton/lv_imagebutton.c ${LVGL_DIR}/src/widgets/image/lv_image.c + ${LVGL_DIR}/src/widgets/ime/lv_ime_pinyin.c ${LVGL_DIR}/src/widgets/keyboard/lv_keyboard.c ${LVGL_DIR}/src/widgets/label/lv_label.c ${LVGL_DIR}/src/widgets/led/lv_led.c @@ -379,14 +413,29 @@ zephyr_library_sources( ${LVGL_DIR}/src/widgets/msgbox/lv_msgbox.c ${LVGL_DIR}/src/widgets/objx_templ/lv_objx_templ.c ${LVGL_DIR}/src/widgets/property/lv_animimage_properties.c + ${LVGL_DIR}/src/widgets/property/lv_arc_properties.c + ${LVGL_DIR}/src/widgets/property/lv_bar_properties.c + ${LVGL_DIR}/src/widgets/property/lv_buttonmatrix_properties.c + ${LVGL_DIR}/src/widgets/property/lv_chart_properties.c + ${LVGL_DIR}/src/widgets/property/lv_checkbox_properties.c ${LVGL_DIR}/src/widgets/property/lv_dropdown_properties.c ${LVGL_DIR}/src/widgets/property/lv_image_properties.c ${LVGL_DIR}/src/widgets/property/lv_keyboard_properties.c ${LVGL_DIR}/src/widgets/property/lv_label_properties.c + ${LVGL_DIR}/src/widgets/property/lv_led_properties.c + ${LVGL_DIR}/src/widgets/property/lv_line_properties.c + ${LVGL_DIR}/src/widgets/property/lv_menu_properties.c ${LVGL_DIR}/src/widgets/property/lv_obj_properties.c ${LVGL_DIR}/src/widgets/property/lv_roller_properties.c + ${LVGL_DIR}/src/widgets/property/lv_scale_properties.c ${LVGL_DIR}/src/widgets/property/lv_slider_properties.c + ${LVGL_DIR}/src/widgets/property/lv_span_properties.c + ${LVGL_DIR}/src/widgets/property/lv_spinbox_properties.c + ${LVGL_DIR}/src/widgets/property/lv_spinner_properties.c ${LVGL_DIR}/src/widgets/property/lv_style_properties.c + ${LVGL_DIR}/src/widgets/property/lv_switch_properties.c + ${LVGL_DIR}/src/widgets/property/lv_table_properties.c + ${LVGL_DIR}/src/widgets/property/lv_tabview_properties.c ${LVGL_DIR}/src/widgets/property/lv_textarea_properties.c ${LVGL_DIR}/src/widgets/roller/lv_roller.c ${LVGL_DIR}/src/widgets/scale/lv_scale.c diff --git a/samples/modules/lvgl/demos/CMakeLists.txt b/samples/modules/lvgl/demos/CMakeLists.txt index cf21ee3bccf7..1a207ea2c058 100644 --- a/samples/modules/lvgl/demos/CMakeLists.txt +++ b/samples/modules/lvgl/demos/CMakeLists.txt @@ -9,60 +9,63 @@ project(lvgl_sample) set(LVGL_DIR ${ZEPHYR_LVGL_MODULE_DIR}) FILE(GLOB app_sources src/*.c) -target_sources(app PRIVATE ${app_sources}) +target_sources(app PRIVATE + ${app_sources} + ${LVGL_DIR}/demos/lv_demos.c +) target_include_directories(app PRIVATE ${LVGL_DIR}/demos/ ) target_sources_ifdef(CONFIG_LV_USE_DEMO_MUSIC app PRIVATE - ${LVGL_DIR}/demos/music/lv_demo_music.c - ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_rnd.c - ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_logo.c - ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_play.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_corner_large.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_list_pause.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_list_pause_large.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_list_play.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_list_play_large.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_loop.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_loop_large.c ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_next.c - ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_rnd_large.c - ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_list_border.c - ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_cover_2_large.c ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_next_large.c - ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_cover_1.c - ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_wave_bottom_large.c - ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_icon_3.c - ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_slider_knob_large.c - ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_wave_top.c - ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_corner_right_large.c - ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_icon_4_large.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_pause.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_pause_large.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_play.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_play_large.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_prev.c ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_prev_large.c - ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_icon_1_large.c - ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_corner_left_large.c - ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_list_play.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_rnd.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_rnd_large.c ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_corner_left.c - ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_slider_knob.c - ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_icon_4.c - ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_loop.c - ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_icon_3_large.c - ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_wave_bottom.c - ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_cover_3.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_corner_left_large.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_corner_right.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_corner_right_large.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_cover_1.c ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_cover_1_large.c - ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_list_play_large.c - ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_list_pause_large.c - ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_pause_large.c - ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_cover_3_large.c - ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_list_border_large.c ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_cover_2.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_cover_2_large.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_cover_3.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_cover_3_large.c ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_icon_1.c - ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_corner_large.c - ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_prev.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_icon_1_large.c ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_icon_2.c - ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_loop_large.c ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_icon_2_large.c - ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_play_large.c - ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_corner_right.c - ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_list_pause.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_icon_3.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_icon_3_large.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_icon_4.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_icon_4_large.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_list_border.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_list_border_large.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_logo.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_slider_knob.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_slider_knob_large.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_wave_bottom.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_wave_bottom_large.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_wave_top.c ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_wave_top_large.c - ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_pause.c - ${LVGL_DIR}/demos/music/lv_demo_music_main.c + ${LVGL_DIR}/demos/music/lv_demo_music.c ${LVGL_DIR}/demos/music/lv_demo_music_list.c + ${LVGL_DIR}/demos/music/lv_demo_music_main.c ) target_sources_ifdef(CONFIG_LV_USE_DEMO_BENCHMARK app PRIVATE @@ -84,15 +87,15 @@ target_sources_ifdef(CONFIG_LV_USE_DEMO_STRESS app PRIVATE ) target_sources_ifdef(CONFIG_LV_USE_DEMO_WIDGETS app PRIVATE - ${LVGL_DIR}/demos/widgets/assets/img_lvgl_logo.c - ${LVGL_DIR}/demos/widgets/assets/img_demo_widgets_avatar.c ${LVGL_DIR}/demos/widgets/assets/img_clothes.c + ${LVGL_DIR}/demos/widgets/assets/img_demo_widgets_avatar.c ${LVGL_DIR}/demos/widgets/assets/img_demo_widgets_needle.c - ${LVGL_DIR}/demos/widgets/lv_demo_widgets_shop.c + ${LVGL_DIR}/demos/widgets/assets/img_lvgl_logo.c ${LVGL_DIR}/demos/widgets/lv_demo_widgets.c - ${LVGL_DIR}/demos/widgets/lv_demo_widgets_profile.c ${LVGL_DIR}/demos/widgets/lv_demo_widgets_analytics.c ${LVGL_DIR}/demos/widgets/lv_demo_widgets_components.c + ${LVGL_DIR}/demos/widgets/lv_demo_widgets_profile.c + ${LVGL_DIR}/demos/widgets/lv_demo_widgets_shop.c ) target_sources_ifdef(CONFIG_LV_USE_DEMO_KEYPAD_AND_ENCODER app PRIVATE diff --git a/samples/modules/lvgl/multi_display/CMakeLists.txt b/samples/modules/lvgl/multi_display/CMakeLists.txt index 7296edc05d81..cd7a6601d5dc 100644 --- a/samples/modules/lvgl/multi_display/CMakeLists.txt +++ b/samples/modules/lvgl/multi_display/CMakeLists.txt @@ -10,60 +10,63 @@ project(lvgl_multi_display) set(LVGL_DIR ${ZEPHYR_LVGL_MODULE_DIR}) FILE(GLOB app_sources src/*.c) -target_sources(app PRIVATE ${app_sources}) +target_sources(app PRIVATE + ${app_sources} + ${LVGL_DIR}/demos/lv_demos.c +) target_include_directories(app PRIVATE ${LVGL_DIR}/demos/ ) target_sources_ifdef(CONFIG_LV_USE_DEMO_MUSIC app PRIVATE - ${LVGL_DIR}/demos/music/lv_demo_music.c - ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_rnd.c - ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_logo.c - ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_play.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_corner_large.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_list_pause.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_list_pause_large.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_list_play.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_list_play_large.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_loop.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_loop_large.c ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_next.c - ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_rnd_large.c - ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_list_border.c - ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_cover_2_large.c ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_next_large.c - ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_cover_1.c - ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_wave_bottom_large.c - ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_icon_3.c - ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_slider_knob_large.c - ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_wave_top.c - ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_corner_right_large.c - ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_icon_4_large.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_pause.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_pause_large.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_play.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_play_large.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_prev.c ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_prev_large.c - ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_icon_1_large.c - ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_corner_left_large.c - ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_list_play.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_rnd.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_rnd_large.c ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_corner_left.c - ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_slider_knob.c - ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_icon_4.c - ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_loop.c - ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_icon_3_large.c - ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_wave_bottom.c - ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_cover_3.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_corner_left_large.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_corner_right.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_corner_right_large.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_cover_1.c ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_cover_1_large.c - ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_list_play_large.c - ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_list_pause_large.c - ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_pause_large.c - ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_cover_3_large.c - ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_list_border_large.c ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_cover_2.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_cover_2_large.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_cover_3.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_cover_3_large.c ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_icon_1.c - ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_corner_large.c - ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_prev.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_icon_1_large.c ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_icon_2.c - ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_loop_large.c ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_icon_2_large.c - ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_play_large.c - ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_corner_right.c - ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_list_pause.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_icon_3.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_icon_3_large.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_icon_4.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_icon_4_large.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_list_border.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_list_border_large.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_logo.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_slider_knob.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_slider_knob_large.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_wave_bottom.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_wave_bottom_large.c + ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_wave_top.c ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_wave_top_large.c - ${LVGL_DIR}/demos/music/assets/img_lv_demo_music_btn_pause.c - ${LVGL_DIR}/demos/music/lv_demo_music_main.c + ${LVGL_DIR}/demos/music/lv_demo_music.c ${LVGL_DIR}/demos/music/lv_demo_music_list.c + ${LVGL_DIR}/demos/music/lv_demo_music_main.c ) target_sources_ifdef(CONFIG_LV_USE_DEMO_BENCHMARK app PRIVATE @@ -85,13 +88,13 @@ target_sources_ifdef(CONFIG_LV_USE_DEMO_STRESS app PRIVATE ) target_sources_ifdef(CONFIG_LV_USE_DEMO_WIDGETS app PRIVATE - ${LVGL_DIR}/demos/widgets/assets/img_lvgl_logo.c - ${LVGL_DIR}/demos/widgets/assets/img_demo_widgets_avatar.c ${LVGL_DIR}/demos/widgets/assets/img_clothes.c + ${LVGL_DIR}/demos/widgets/assets/img_demo_widgets_avatar.c ${LVGL_DIR}/demos/widgets/assets/img_demo_widgets_needle.c - ${LVGL_DIR}/demos/widgets/lv_demo_widgets_shop.c + ${LVGL_DIR}/demos/widgets/assets/img_lvgl_logo.c ${LVGL_DIR}/demos/widgets/lv_demo_widgets.c - ${LVGL_DIR}/demos/widgets/lv_demo_widgets_profile.c ${LVGL_DIR}/demos/widgets/lv_demo_widgets_analytics.c ${LVGL_DIR}/demos/widgets/lv_demo_widgets_components.c + ${LVGL_DIR}/demos/widgets/lv_demo_widgets_profile.c + ${LVGL_DIR}/demos/widgets/lv_demo_widgets_shop.c ) diff --git a/west.yml b/west.yml index 1f0d439fc5f1..54df2a7dc762 100644 --- a/west.yml +++ b/west.yml @@ -318,7 +318,7 @@ manifest: revision: fb00b383072518c918e2258b0916c996f2d4eebe path: modules/lib/loramac-node - name: lvgl - revision: c016f72d4c125098287be5e83c0f1abed4706ee5 + revision: 94ae6c0535aa6ac4b08a75f4ae2c3a08cacb5c41 path: modules/lib/gui/lvgl - name: mbedtls revision: c5b06d89c9c498d8fc8659ce31f7e53137b6270f From 5e16700cb2d72ba70e0b8cee926f998ab434bf04 Mon Sep 17 00:00:00 2001 From: Gaetan Perrot Date: Sat, 17 Jan 2026 10:21:37 +0900 Subject: [PATCH 2259/3659] drivers: ethernet: phy: phy_dm8806: fix error handling The return value of gpio_pin_set_dt() and gpio_pin_interrupt_configure_dt() was not stored before being checked, causing the error condition to always evaluate to false. Store the return value and properly handle potential GPIO errors during PHY reset. No functional change intended. Signed-off-by: Gaetan Perrot --- drivers/ethernet/phy/phy_dm8806.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/ethernet/phy/phy_dm8806.c b/drivers/ethernet/phy/phy_dm8806.c index 234b71fbc910..5380f09a5327 100644 --- a/drivers/ethernet/phy/phy_dm8806.c +++ b/drivers/ethernet/phy/phy_dm8806.c @@ -301,7 +301,7 @@ int phy_dm8806_port_init(const struct device *dev) return res; } /* Hardware reset of the PHY DM8806 */ - gpio_pin_set_dt(&cfg->gpio_rst, true); + res = gpio_pin_set_dt(&cfg->gpio_rst, true); if (res < 0) { LOG_ERR("Failed to assert gpio reset pin of the PHY DM886 to physical 0"); return res; @@ -392,7 +392,7 @@ int phy_dm8806_init_interrupt(const struct device *dev) /* Configure GPIO interrupt to be triggered on pin state change to logical * level 1 asserted by Davicom PHY DM8806 interrupt Pin */ - gpio_pin_interrupt_configure_dt(&cfg->gpio_int, GPIO_INT_EDGE_TO_ACTIVE); + res = gpio_pin_interrupt_configure_dt(&cfg->gpio_int, GPIO_INT_EDGE_TO_ACTIVE); if (res < 0) { LOG_ERR("Failed to configure PHY DM886 gpio interrupt pin trigger for " "active edge"); @@ -665,7 +665,7 @@ static int phy_dm8806_link_cb_set(const struct device *dev, phy_callback_t cb, v } data->link_speed_chenge_cb = cb; data->cb_data = user_data; - gpio_pin_interrupt_configure_dt(&cfg->gpio_int, GPIO_INT_EDGE_TO_ACTIVE); + res = gpio_pin_interrupt_configure_dt(&cfg->gpio_int, GPIO_INT_EDGE_TO_ACTIVE); if (res < 0) { LOG_WRN("Failed to enable DM8806 interrupt: %i", res); return res; From 8f8502c0c7661e8202ad0d375dcac19447e599f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Fri, 16 Jan 2026 23:44:33 +0100 Subject: [PATCH 2260/3659] drivers: i3c: shell: adopt SHELL_HELP in I3C shell MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use SHELL_HELP macro for help strings to ensure consistency across various shell modules and save quite a bit of flash. Signed-off-by: Benjamin Cabé --- drivers/i3c/i3c_shell.c | 256 ++++++++++++++++++++-------------------- 1 file changed, 128 insertions(+), 128 deletions(-) diff --git a/drivers/i3c/i3c_shell.c b/drivers/i3c/i3c_shell.c index ffd846f301bc..3087e7224bd3 100644 --- a/drivers/i3c/i3c_shell.c +++ b/drivers/i3c/i3c_shell.c @@ -2162,32 +2162,32 @@ SHELL_STATIC_SUBCMD_SET_CREATE( sub_i3c_ibi_cmds, #ifdef CONFIG_I3C_TARGET SHELL_CMD_ARG(hj, &dsub_i3c_device_name, - "Send IBI HJ\n" - "Usage: ibi hj ", + SHELL_HELP("Send IBI HJ", + ""), cmd_i3c_ibi_hj, 2, 0), SHELL_CMD_ARG(tir, &dsub_i3c_device_name, - "Send IBI TIR\n" - "Usage: ibi tir [, ...]", + SHELL_HELP("Send IBI TIR", + " [, ...]"), cmd_i3c_ibi_tir, 2, MAX_I3C_BYTES), #ifdef CONFIG_I3C_CONTROLLER SHELL_CMD_ARG(cr, &dsub_i3c_device_name, - "Send IBI CR\n" - "Usage: ibi cr ", + SHELL_HELP("Send IBI CR", + ""), cmd_i3c_ibi_cr, 2, 0), #endif /* CONFIG_I3C_CONTROLLER */ #endif /* CONFIG_I3C_TARGET */ #ifdef CONFIG_I3C_CONTROLLER SHELL_CMD_ARG(hj_response, &dsub_i3c_device_name, - "Set IBI HJ Response\n" - "Usage: ibi hj_response <\"ack\"/\"nack\">", + SHELL_HELP("Set IBI HJ Response", + " <\"ack\"/\"nack\">"), cmd_i3c_ibi_hj_response, 3, 0), SHELL_CMD_ARG(enable, &dsub_i3c_device_attached_name, - "Enable receiving IBI from target\n" - "Usage: ibi enable ", + SHELL_HELP("Enable receiving IBI from target", + " "), cmd_i3c_ibi_enable, 3, 0), SHELL_CMD_ARG(disable, &dsub_i3c_device_attached_name, - "Disable receiving IBI from target\n" - "Usage: ibi disable ", + SHELL_HELP("Disable receiving IBI from target", + " "), cmd_i3c_ibi_disable, 3, 0), #endif /* CONFIG_I3C_CONTROLLER */ SHELL_SUBCMD_SET_END /* Array terminated. */ @@ -2199,12 +2199,12 @@ SHELL_STATIC_SUBCMD_SET_CREATE( SHELL_STATIC_SUBCMD_SET_CREATE( sub_i3c_hdr_ddr_cmds, SHELL_CMD_ARG(write, &dsub_i3c_device_attached_name, - "Send HDR DDR Write\n" - "Usage: hdr ddr write <7b cmd> [, ...]", + SHELL_HELP("Send HDR DDR Write", + " <7b cmd> [, ...]"), cmd_i3c_hdr_ddr_write, 4, MAX_I3C_BYTES), SHELL_CMD_ARG(read, &dsub_i3c_device_attached_name, - "Send HDR DDR Read\n" - "Usage: hdr ddr read <7b cmd> ", + SHELL_HELP("Send HDR DDR Read", + " <7b cmd> "), cmd_i3c_hdr_ddr_read, 5, 0), SHELL_SUBCMD_SET_END /* Array terminated. */ ); @@ -2213,8 +2213,8 @@ SHELL_STATIC_SUBCMD_SET_CREATE( SHELL_STATIC_SUBCMD_SET_CREATE( sub_i3c_hdr_cmds, SHELL_CMD_ARG(ddr, &sub_i3c_hdr_ddr_cmds, - "Send HDR DDR\n" - "Usage: hdr ddr ", + SHELL_HELP("Send HDR DDR", + ""), NULL, 2, 0), SHELL_SUBCMD_SET_END /* Array terminated. */ ); @@ -2223,164 +2223,164 @@ SHELL_STATIC_SUBCMD_SET_CREATE( SHELL_STATIC_SUBCMD_SET_CREATE( sub_i3c_ccc_cmds, SHELL_CMD_ARG(rstdaa_dc, &dsub_i3c_device_attached_name, - "Send CCC RSTDAA\n" - "Usage: ccc rstdaa_dc ", + SHELL_HELP("Send CCC RSTDAA", + " "), cmd_i3c_ccc_rstdaa_dc, 3, 0), SHELL_CMD_ARG(rstdaa, &dsub_i3c_device_name, - "Send CCC RSTDAA\n" - "Usage: ccc rstdaa ", + SHELL_HELP("Send CCC RSTDAA", + ""), cmd_i3c_ccc_rstdaa, 2, 0), SHELL_CMD_ARG(entdaa, &dsub_i3c_device_name, - "Send CCC ENTDAA\n" - "Usage: ccc entdaa ", + SHELL_HELP("Send CCC ENTDAA", + ""), cmd_i3c_ccc_entdaa, 2, 0), SHELL_CMD_ARG(setaasa, &dsub_i3c_device_name, - "Send CCC SETAASA\n" - "Usage: ccc setaasa ", + SHELL_HELP("Send CCC SETAASA", + ""), cmd_i3c_ccc_setaasa, 2, 0), SHELL_CMD_ARG(setdasa, &dsub_i3c_device_attached_name, - "Send CCC SETDASA\n" - "Usage: ccc setdasa ", + SHELL_HELP("Send CCC SETDASA", + " "), cmd_i3c_ccc_setdasa, 4, 0), SHELL_CMD_ARG(setnewda, &dsub_i3c_device_attached_name, - "Send CCC SETNEWDA\n" - "Usage: ccc setnewda ", + SHELL_HELP("Send CCC SETNEWDA", + " "), cmd_i3c_ccc_setnewda, 4, 0), SHELL_CMD_ARG(getbcr, &dsub_i3c_device_attached_name, - "Send CCC GETBCR\n" - "Usage: ccc getbcr ", + SHELL_HELP("Send CCC GETBCR", + " "), cmd_i3c_ccc_getbcr, 3, 0), SHELL_CMD_ARG(getdcr, &dsub_i3c_device_attached_name, - "Send CCC GETDCR\n" - "Usage: ccc getdcr ", + SHELL_HELP("Send CCC GETDCR", + " "), cmd_i3c_ccc_getdcr, 3, 0), SHELL_CMD_ARG(getpid, &dsub_i3c_device_attached_name, - "Send CCC GETPID\n" - "Usage: ccc getpid ", + SHELL_HELP("Send CCC GETPID", + " "), cmd_i3c_ccc_getpid, 3, 0), SHELL_CMD_ARG(getmrl, &dsub_i3c_device_attached_name, - "Send CCC GETMRL\n" - "Usage: ccc getmrl ", + SHELL_HELP("Send CCC GETMRL", + " "), cmd_i3c_ccc_getmrl, 3, 0), SHELL_CMD_ARG(getmwl, &dsub_i3c_device_attached_name, - "Send CCC GETMWL\n" - "Usage: ccc getmwl ", + SHELL_HELP("Send CCC GETMWL", + " "), cmd_i3c_ccc_getmwl, 3, 0), SHELL_CMD_ARG(setmrl, &dsub_i3c_device_attached_name, - "Send CCC SETMRL\n" - "Usage: ccc setmrl []", + SHELL_HELP("Send CCC SETMRL", + " []"), cmd_i3c_ccc_setmrl, 4, 1), SHELL_CMD_ARG(setmwl, &dsub_i3c_device_attached_name, - "Send CCC SETMWL\n" - "Usage: ccc setmwl ", + SHELL_HELP("Send CCC SETMWL", + " "), cmd_i3c_ccc_setmwl, 4, 0), SHELL_CMD_ARG(setmrl_bc, &dsub_i3c_device_name, - "Send CCC SETMRL BC\n" - "Usage: ccc setmrl_bc []", + SHELL_HELP("Send CCC SETMRL BC", + " []"), cmd_i3c_ccc_setmrl_bc, 3, 1), SHELL_CMD_ARG(setmwl_bc, &dsub_i3c_device_name, - "Send CCC SETMWL BC\n" - "Usage: ccc setmwl_bc ", + SHELL_HELP("Send CCC SETMWL BC", + " "), cmd_i3c_ccc_setmwl_bc, 3, 0), #ifdef CONFIG_I3C_TARGET SHELL_CMD_ARG(deftgts, &dsub_i3c_device_name, - "Send CCC DEFTGTS\n" - "Usage: ccc deftgts ", + SHELL_HELP("Send CCC DEFTGTS", + ""), cmd_i3c_ccc_deftgts, 2, 0), #endif SHELL_CMD_ARG(enttm, &dsub_i3c_device_name, - "Send CCC ENTTM\n" - "Usage: ccc enttm ", + SHELL_HELP("Send CCC ENTTM", + " "), cmd_i3c_ccc_enttm, 3, 0), SHELL_CMD_ARG(rstact, &dsub_i3c_device_attached_name, - "Send CCC RSTACT\n" - "Usage: ccc rstact <\"set\"/\"get\"> ", + SHELL_HELP("Send CCC RSTACT", + " <\"set\"/\"get\"> "), cmd_i3c_ccc_rstact, 5, 0), #ifdef CONFIG_I3C_TARGET SHELL_CMD_ARG(getacccr, &dsub_i3c_device_attached_name, - "Send CCC GETACCCR\n" - "Usage: ccc getacccr ", + SHELL_HELP("Send CCC GETACCCR", + " "), cmd_i3c_ccc_getacccr, 3, 0), #endif /* CONFIG_I3C_TARGET */ SHELL_CMD_ARG(rstact_bc, &dsub_i3c_device_name, - "Send CCC RSTACT BC\n" - "Usage: ccc rstact_bc ", + SHELL_HELP("Send CCC RSTACT BC", + " "), cmd_i3c_ccc_rstact_bc, 3, 0), SHELL_CMD_ARG(enec_bc, &dsub_i3c_device_name, - "Send CCC ENEC BC\n" - "Usage: ccc enec_bc ", + SHELL_HELP("Send CCC ENEC BC", + " "), cmd_i3c_ccc_enec_bc, 3, 0), SHELL_CMD_ARG(disec_bc, &dsub_i3c_device_name, - "Send CCC DISEC BC\n" - "Usage: ccc disec_bc ", + SHELL_HELP("Send CCC DISEC BC", + " "), cmd_i3c_ccc_disec_bc, 3, 0), SHELL_CMD_ARG(enec, &dsub_i3c_device_attached_name, - "Send CCC ENEC\n" - "Usage: ccc enec ", + SHELL_HELP("Send CCC ENEC", + " "), cmd_i3c_ccc_enec, 4, 0), SHELL_CMD_ARG(disec, &dsub_i3c_device_attached_name, - "Send CCC DISEC\n" - "Usage: ccc disec ", + SHELL_HELP("Send CCC DISEC", + " "), cmd_i3c_ccc_disec, 4, 0), SHELL_CMD_ARG(entas0_bc, &dsub_i3c_device_name, - "Send CCC ENTAS0 BC\n" - "Usage: ccc entas0 ", + SHELL_HELP("Send CCC ENTAS0 BC", + ""), cmd_i3c_ccc_entas0_bc, 2, 0), SHELL_CMD_ARG(entas1_bc, &dsub_i3c_device_name, - "Send CCC ENTAS1 BC\n" - "Usage: ccc entas1 ", + SHELL_HELP("Send CCC ENTAS1 BC", + ""), cmd_i3c_ccc_entas1_bc, 2, 0), SHELL_CMD_ARG(entas2_bc, &dsub_i3c_device_name, - "Send CCC ENTAS2 BC\n" - "Usage: ccc entas2 ", + SHELL_HELP("Send CCC ENTAS2 BC", + ""), cmd_i3c_ccc_entas2_bc, 2, 0), SHELL_CMD_ARG(entas3_bc, &dsub_i3c_device_name, - "Send CCC ENTAS3 BC\n" - "Usage: ccc entas3 ", + SHELL_HELP("Send CCC ENTAS3 BC", + ""), cmd_i3c_ccc_entas3_bc, 2, 0), SHELL_CMD_ARG(entas0, &dsub_i3c_device_attached_name, - "Send CCC ENTAS0\n" - "Usage: ccc entas0 ", + SHELL_HELP("Send CCC ENTAS0", + " "), cmd_i3c_ccc_entas0, 3, 0), SHELL_CMD_ARG(entas1, &dsub_i3c_device_attached_name, - "Send CCC ENTAS1\n" - "Usage: ccc entas1 ", + SHELL_HELP("Send CCC ENTAS1", + " "), cmd_i3c_ccc_entas1, 3, 0), SHELL_CMD_ARG(entas2, &dsub_i3c_device_attached_name, - "Send CCC ENTAS2\n" - "Usage: ccc entas2 ", + SHELL_HELP("Send CCC ENTAS2", + " "), cmd_i3c_ccc_entas2, 3, 0), SHELL_CMD_ARG(entas3, &dsub_i3c_device_attached_name, - "Send CCC ENTAS3\n" - "Usage: ccc entas3 ", + SHELL_HELP("Send CCC ENTAS3", + " "), cmd_i3c_ccc_entas3, 3, 0), SHELL_CMD_ARG(getstatus, &dsub_i3c_device_attached_name, - "Send CCC GETSTATUS\n" - "Usage: ccc getstatus []", + SHELL_HELP("Send CCC GETSTATUS", + " []"), cmd_i3c_ccc_getstatus, 3, 1), SHELL_CMD_ARG(getcaps, &dsub_i3c_device_attached_name, - "Send CCC GETCAPS\n" - "Usage: ccc getcaps []", + SHELL_HELP("Send CCC GETCAPS", + " []"), cmd_i3c_ccc_getcaps, 3, 1), SHELL_CMD_ARG(getmxds, &dsub_i3c_device_attached_name, - "Send CCC GETMXDS\n" - "Usage: ccc getmxds []", + SHELL_HELP("Send CCC GETMXDS", + " []"), cmd_i3c_ccc_getmxds, 3, 1), SHELL_CMD_ARG(setbuscon, &dsub_i3c_device_name, - "Send CCC SETBUSCON\n" - "Usage: ccc setbuscon []", + SHELL_HELP("Send CCC SETBUSCON", + " []"), cmd_i3c_ccc_setbuscon, 3, MAX_I3C_BYTES - 1), SHELL_CMD_ARG(getvendor, &dsub_i3c_device_attached_name, - "Send CCC GETVENDOR\n" - "Usage: ccc getvendor []", + SHELL_HELP("Send CCC GETVENDOR", + " []"), cmd_i3c_ccc_getvendor, 4, 1), SHELL_CMD_ARG(setvendor, &dsub_i3c_device_attached_name, - "Send CCC SETVENDOR\n" - "Usage: ccc setvendor []", + SHELL_HELP("Send CCC SETVENDOR", + " []"), cmd_i3c_ccc_setvendor, 4, MAX_I3C_BYTES), SHELL_CMD_ARG(setvendor_bc, &dsub_i3c_device_name, - "Send CCC SETVENDOR BC\n" - "Usage: ccc setvendor_bc []", + SHELL_HELP("Send CCC SETVENDOR BC", + " []"), cmd_i3c_ccc_setvendor_bc, 3, MAX_I3C_BYTES), SHELL_SUBCMD_SET_END /* Array terminated. */ ); @@ -2391,70 +2391,70 @@ SHELL_STATIC_SUBCMD_SET_CREATE( sub_i3c_cmds, #ifdef CONFIG_I3C_CONTROLLER SHELL_CMD_ARG(info, &dsub_i3c_device_attached_name, - "Get I3C device info\n" - "Usage: info []", + SHELL_HELP("Get I3C device info", + " []"), cmd_i3c_info, 2, 1), SHELL_CMD_ARG(speed, &dsub_i3c_device_name, - "Set I3C device speed\n" - "Usage: speed [] []", + SHELL_HELP("Set I3C device speed", + " [] []"), cmd_i3c_speed, 3, 2), SHELL_CMD_ARG(recover, &dsub_i3c_device_name, - "Recover I3C bus\n" - "Usage: recover ", + SHELL_HELP("Recover I3C bus", + ""), cmd_i3c_recover, 2, 0), SHELL_CMD_ARG(read, &dsub_i3c_device_attached_name, - "Read bytes from an I3C device\n" - "Usage: read []", + SHELL_HELP("Read bytes from an I3C device", + " []"), cmd_i3c_read, 4, 1), SHELL_CMD_ARG(read_byte, &dsub_i3c_device_attached_name, - "Read a byte from an I3C device\n" - "Usage: read_byte ", + SHELL_HELP("Read a byte from an I3C device", + " "), cmd_i3c_read_byte, 4, 0), SHELL_CMD_ARG(write, &dsub_i3c_device_attached_name, - "Write bytes to an I3C device\n" - "Usage: write [, ...]", + SHELL_HELP("Write bytes to an I3C device", + " [, ...]"), cmd_i3c_write, 4, MAX_I3C_BYTES), SHELL_CMD_ARG(write_byte, &dsub_i3c_device_attached_name, - "Write a byte to an I3C device\n" - "Usage: write_byte ", + SHELL_HELP("Write a byte to an I3C device", + " "), cmd_i3c_write_byte, 5, 0), SHELL_CMD_ARG(i3c_attach, &dsub_i3c_device_list_name, - "Attach I3C device from the bus\n" - "Usage: i3c_attach ", + SHELL_HELP("Attach I3C device from the bus", + " "), cmd_i3c_attach, 3, 0), SHELL_CMD_ARG(i3c_reattach, &dsub_i3c_device_attached_name, - "Reattach I3C device from the bus\n" - "Usage: i3c_reattach []", + SHELL_HELP("Reattach I3C device from the bus", + " []"), cmd_i3c_reattach, 3, 1), SHELL_CMD_ARG(i3c_detach, &dsub_i3c_device_attached_name, - "Detach I3C device from the bus\n" - "Usage: i3c_detach ", + SHELL_HELP("Detach I3C device from the bus", + " "), cmd_i3c_detach, 3, 0), SHELL_CMD_ARG(i2c_attach, &dsub_i3c_device_name, - "Attach I2C device from the bus\n" - "Usage: i2c_attach ", + SHELL_HELP("Attach I2C device from the bus", + " "), cmd_i3c_i2c_attach, 3, 0), SHELL_CMD_ARG(i2c_detach, &dsub_i3c_device_name, - "Detach I2C device from the bus\n" - "Usage: i2c_detach ", + SHELL_HELP("Detach I2C device from the bus", + " "), cmd_i3c_i2c_detach, 3, 0), SHELL_CMD_ARG(i2c_scan, &dsub_i3c_device_name, - "Scan I2C devices\n" - "Usage: i2c_scan ", + SHELL_HELP("Scan I2C devices", + ""), cmd_i3c_i2c_scan, 2, 0), SHELL_CMD_ARG(ccc, &sub_i3c_ccc_cmds, - "Send I3C CCC\n" - "Usage: ccc ", + SHELL_HELP("Send I3C CCC", + ""), NULL, 3, 0), SHELL_CMD_ARG(hdr, &sub_i3c_hdr_cmds, - "Send I3C HDR\n" - "Usage: hdr ", + SHELL_HELP("Send I3C HDR", + ""), NULL, 3, 0), #endif /* CONFIG_I3C_CONTROLLER */ #ifdef CONFIG_I3C_USE_IBI SHELL_CMD_ARG(ibi, &sub_i3c_ibi_cmds, - "Send I3C IBI\n" - "Usage: ibi ", + SHELL_HELP("Send I3C IBI", + ""), NULL, 3, 0), #endif /* CONFIG_I3C_USE_IBI */ SHELL_SUBCMD_SET_END /* Array terminated. */ From f9664d51c31b2dffaa37c78e4f85db72a77ff232 Mon Sep 17 00:00:00 2001 From: Tom Hughes Date: Fri, 16 Jan 2026 14:22:34 -0800 Subject: [PATCH 2261/3659] samples: net: midi2: Fix compiler warning When building with clang we get the following warning when building the sample.net.midi2.host_auth_user test: samples/net/midi2/src/main.c:122:54: error: initializer element is not a compile-time constant 122 | NETMIDI2_EP_DEFINE_WITH_USERS(midi_server, ump_ep_dt.name, NULL, 0, | ~~~~~~~~~~^~~~ include/zephyr/net/midi2.h:99:12: note: expanded from macro 'NETMIDI2_EP_DEFINE_WITH_USERS' 99 | .name = (_ep_name), \ | ^~~~~~~~ Instead of using ump_ep_dt.name for initialization, we use the equivalent expression that UMP_ENDPOINT_DT_SPEC_GET(DT_NODELABEL(midi2)) initializes the ".name" member with. Signed-off-by: Tom Hughes --- samples/net/midi2/src/main.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/samples/net/midi2/src/main.c b/samples/net/midi2/src/main.c index 5d965d87d6cb..9e65a36e3388 100644 --- a/samples/net/midi2/src/main.c +++ b/samples/net/midi2/src/main.c @@ -69,9 +69,10 @@ static inline void send_external_midi1(const struct midi_ump ump) } #endif /* DT_NODE_EXISTS(SERIAL_NODE) */ +#define MIDI2_NODE DT_NODELABEL(midi2) static const struct ump_endpoint_dt_spec ump_ep_dt = - UMP_ENDPOINT_DT_SPEC_GET(DT_NODELABEL(midi2)); + UMP_ENDPOINT_DT_SPEC_GET(MIDI2_NODE); static inline void handle_ump_stream(struct netmidi2_session *session, const struct midi_ump ump) @@ -96,7 +97,7 @@ static void netmidi2_callback(struct netmidi2_session *session, #if defined(CONFIG_NET_SAMPLE_MIDI2_AUTH_NONE) /* Simple Network MIDI 2.0 endpoint without authentication */ -NETMIDI2_EP_DEFINE(midi_server, ump_ep_dt.name, NULL, 0); +NETMIDI2_EP_DEFINE(midi_server, DT_PROP_OR(MIDI2_NODE, label, NULL), NULL, 0); #elif defined(CONFIG_NET_SAMPLE_MIDI2_AUTH_SHARED_SECRET) /* Network MIDI 2.0 endpoint with shared secret authentication */ @@ -105,7 +106,7 @@ BUILD_ASSERT( "CONFIG_NET_SAMPLE_MIDI2_SHARED_SECRET must be not empty" ); -NETMIDI2_EP_DEFINE_WITH_AUTH(midi_server, ump_ep_dt.name, NULL, 0, +NETMIDI2_EP_DEFINE_WITH_AUTH(midi_server, DT_PROP_OR(MIDI2_NODE, label, NULL), NULL, 0, CONFIG_NET_SAMPLE_MIDI2_SHARED_SECRET); #elif defined(CONFIG_NET_SAMPLE_MIDI2_AUTH_USER_PASSWORD) @@ -119,7 +120,7 @@ BUILD_ASSERT( "CONFIG_NET_SAMPLE_MIDI2_PASSWORD must be not empty" ); -NETMIDI2_EP_DEFINE_WITH_USERS(midi_server, ump_ep_dt.name, NULL, 0, +NETMIDI2_EP_DEFINE_WITH_USERS(midi_server, DT_PROP_OR(MIDI2_NODE, label, NULL), NULL, 0, {.name = CONFIG_NET_SAMPLE_MIDI2_USERNAME, .password = CONFIG_NET_SAMPLE_MIDI2_PASSWORD}); From 39a8408b301af0d1c1c97834d5f8136e9d3e328f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Fri, 16 Jan 2026 22:49:50 +0100 Subject: [PATCH 2262/3659] drivers: pm_cpu_ops: adopt SHELL_HELP in psci shell MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use SHELL_HELP macro for help strings to ensure consistency across various shell modules. Signed-off-by: Benjamin Cabé --- drivers/pm_cpu_ops/psci_shell.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/pm_cpu_ops/psci_shell.c b/drivers/pm_cpu_ops/psci_shell.c index 34669b65a08c..81ead0752bc0 100644 --- a/drivers/pm_cpu_ops/psci_shell.c +++ b/drivers/pm_cpu_ops/psci_shell.c @@ -63,9 +63,14 @@ static int cmd_psci_cpuon(const struct shell *shctx, size_t argc, char **argv) SHELL_STATIC_SUBCMD_SET_CREATE( sub_reboot, - SHELL_CMD_ARG(warm, NULL, "System warm reset. Usage: ", cmd_reboot_warm, 1, 0), - SHELL_CMD_ARG(cold, NULL, "System cold reset. Usage: ", cmd_reboot_cold, 1, 0), - SHELL_CMD_ARG(cpuon, NULL, "Power-up the secondary CPU. Usage: >", + SHELL_CMD_ARG(warm, NULL, + SHELL_HELP("System warm reset", NULL), + cmd_reboot_warm, 1, 0), + SHELL_CMD_ARG(cold, NULL, + SHELL_HELP("System cold reset", NULL), + cmd_reboot_cold, 1, 0), + SHELL_CMD_ARG(cpuon, NULL, + SHELL_HELP("Power-up the secondary CPU", ""), cmd_psci_cpuon, 2, 0), SHELL_SUBCMD_SET_END /* Array terminated. */ ); From 25448bc9960f42cc741030e1bbb701637758f8e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Fri, 16 Jan 2026 22:43:36 +0100 Subject: [PATCH 2263/3659] task_wdt: adopt SHELL_HELP in task watchdog shell MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use SHELL_HELP macro for help strings to ensure consistency across various shell modules. Signed-off-by: Benjamin Cabé --- subsys/task_wdt/task_wdt_shell.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/subsys/task_wdt/task_wdt_shell.c b/subsys/task_wdt/task_wdt_shell.c index 6d172fd8aeb3..fc58bfbf8d11 100644 --- a/subsys/task_wdt/task_wdt_shell.c +++ b/subsys/task_wdt/task_wdt_shell.c @@ -100,10 +100,18 @@ static int cmd_del(const struct shell *sh, size_t argc, char **argv) SHELL_STATIC_SUBCMD_SET_CREATE( sub_task_wdt, - SHELL_CMD(init, NULL, "Initialize task watchdog", cmd_init), - SHELL_CMD(add, NULL, "Install new timeout (time in seconds)", cmd_add), - SHELL_CMD(feed, NULL, "Feed specified watchdog channel", cmd_feed), - SHELL_CMD(del, NULL, "Delete task watchdog channel", cmd_del), + SHELL_CMD(init, NULL, + SHELL_HELP("Initialize task watchdog", NULL), + cmd_init), + SHELL_CMD(add, NULL, + SHELL_HELP("Install new timeout", ""), + cmd_add), + SHELL_CMD(feed, NULL, + SHELL_HELP("Feed specified watchdog channel", ""), + cmd_feed), + SHELL_CMD(del, NULL, + SHELL_HELP("Delete task watchdog channel", ""), + cmd_del), SHELL_SUBCMD_SET_END); SHELL_CMD_REGISTER(task_wdt, &sub_task_wdt, "Task watchdog commands", NULL); From 114b3bd50c360dfd62108bf8a9757bfa366572b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Fri, 16 Jan 2026 22:41:58 +0100 Subject: [PATCH 2264/3659] drivers: mdio: adopt SHELL_HELP in MDIO shell MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use SHELL_HELP macro for help strings to ensure consistency across various shell modules. Signed-off-by: Benjamin Cabé --- drivers/mdio/mdio_shell.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/drivers/mdio/mdio_shell.c b/drivers/mdio/mdio_shell.c index ab2efbc8edb8..8fd07901bd7b 100644 --- a/drivers/mdio/mdio_shell.c +++ b/drivers/mdio/mdio_shell.c @@ -206,21 +206,24 @@ static int cmd_mdio_read_c45(const struct shell *sh, size_t argc, char **argv) SHELL_STATIC_SUBCMD_SET_CREATE(sub_mdio_cmds, SHELL_CMD_ARG(scan, &dsub_device_name, - "Scan MDIO bus for devices: scan []", + SHELL_HELP("Scan MDIO bus for devices", + " []"), cmd_mdio_scan, 2, 1), SHELL_CMD_ARG(read, &dsub_device_name, - "Read from MDIO device: read ", + SHELL_HELP("Read from MDIO device", + " "), cmd_mdio_read, 4, 0), SHELL_CMD_ARG(write, &dsub_device_name, - "Write to MDIO device: write ", + SHELL_HELP("Write to MDIO device", + " "), cmd_mdio_write, 5, 0), SHELL_CMD_ARG(read_c45, &dsub_device_name, - "Read from MDIO Clause 45 device: " - "read_c45 ", + SHELL_HELP("Read from MDIO Clause 45 device", + " "), cmd_mdio_read_c45, 5, 0), SHELL_CMD_ARG(write_c45, &dsub_device_name, - "Write to MDIO Clause 45 device: " - "write_c45 ", + SHELL_HELP("Write to MDIO Clause 45 device", + " "), cmd_mdio_write_45, 6, 0), SHELL_SUBCMD_SET_END /* Array terminated. */ ); From e6b8ffba92c5947673fab3e9263209e61e434a5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Fri, 16 Jan 2026 22:51:06 +0100 Subject: [PATCH 2265/3659] drivers: modem: adopt SHELL_HELP in modem_at shell MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use SHELL_HELP macro for help strings to ensure consistency across various shell modules. Signed-off-by: Benjamin Cabé --- drivers/modem/modem_at_shell.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/modem/modem_at_shell.c b/drivers/modem/modem_at_shell.c index 7d1930b6b04b..b5fdb8806dbd 100644 --- a/drivers/modem/modem_at_shell.c +++ b/drivers/modem/modem_at_shell.c @@ -175,7 +175,9 @@ static int at_shell_cmd_handler(const struct shell *sh, size_t argc, char **argv } SHELL_STATIC_SUBCMD_SET_CREATE(modem_sub_cmds, - SHELL_CMD_ARG(at, NULL, "at ", at_shell_cmd_handler, 1, 2), + SHELL_CMD_ARG(at, NULL, + SHELL_HELP("Send AT command", " [expected_response]"), + at_shell_cmd_handler, 1, 2), SHELL_SUBCMD_SET_END ); From 8ea64b7b33c0701f5b1084557ec17ed2f81594b2 Mon Sep 17 00:00:00 2001 From: Tom Hughes Date: Fri, 16 Jan 2026 12:02:24 -0800 Subject: [PATCH 2266/3659] bluetooth: audio: Fix redundant initialization When building the bluetooth.general.tester_le_audio test with clang and -Winitializer-overrides, it warns: subsys/bluetooth/audio/mpl.c:318:2: error: initializer overrides prior initialization of this subobject [-Werror,-Winitializer-overrides] 318 | .add_group = NULL, | ^~~~~~~~~~~~~~~~~ subsys/bluetooth/audio/mpl.c:317:15: note: previous initialization is here 317 | .add_track = NULL, | ^~~~ Remove redundant initializer for add_group which overlaps with add_track in an anonymous union. Signed-off-by: Tom Hughes --- subsys/bluetooth/audio/mpl.c | 1 - 1 file changed, 1 deletion(-) diff --git a/subsys/bluetooth/audio/mpl.c b/subsys/bluetooth/audio/mpl.c index 6dba69bb87d0..faf447c74999 100644 --- a/subsys/bluetooth/audio/mpl.c +++ b/subsys/bluetooth/audio/mpl.c @@ -315,7 +315,6 @@ static struct obj_t obj = { .selected_id = 0, .add_type = MPL_OBJ_NONE, .add_track = NULL, - .add_group = NULL, .content = NET_BUF_SIMPLE(CONFIG_BT_MPL_MAX_OBJ_SIZE), }; From 987722df9d9c1ef6ca9e9691a37d217a37dcd46c Mon Sep 17 00:00:00 2001 From: Gillian Minnehan Date: Fri, 16 Jan 2026 14:28:52 -0500 Subject: [PATCH 2267/3659] doc: add license/terms to external module template It is important to include license and terms of use information in the documentation for external modules. This helps users understand their rights and obligations when using these modules within the Zephyr project. Signed-off-by: Gillian Minnehan --- doc/develop/manifest/external/external.rst.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/develop/manifest/external/external.rst.tmpl b/doc/develop/manifest/external/external.rst.tmpl index 49e262ab36e7..d2a11fcfe4a4 100644 --- a/doc/develop/manifest/external/external.rst.tmpl +++ b/doc/develop/manifest/external/external.rst.tmpl @@ -6,7 +6,7 @@ Introduction ************ -Short intro into the module and how it relates to Zephyr. +Short intro into the module, how it relates to Zephyr, and the license/terms of use. Usage with Zephyr ***************** From 1dae40fa2ef693f25ea3f7e1654b8672d431b94b Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Fri, 16 Jan 2026 11:14:40 -0800 Subject: [PATCH 2268/3659] soc: rename CONFIG_INTEL_CAVS_V25 to CONFIG_SOC_CAVSV25 Just following the guideline. Signed-off-by: Daniel Leung --- boards/intel/adsp/Kconfig.intel_adsp | 4 ++-- drivers/interrupt_controller/intc_cavs.c | 2 +- soc/intel/intel_adsp/cavs/Kconfig | 2 +- soc/intel/intel_adsp/cavs/Kconfig.defconfig.cavs_v25 | 4 ++-- soc/intel/intel_adsp/cavs/Kconfig.soc | 6 +++--- soc/intel/intel_adsp/common/gdbstub_backend_sram.c | 2 +- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/boards/intel/adsp/Kconfig.intel_adsp b/boards/intel/adsp/Kconfig.intel_adsp index 0a29c0d13819..1c9faa8b9575 100644 --- a/boards/intel/adsp/Kconfig.intel_adsp +++ b/boards/intel/adsp/Kconfig.intel_adsp @@ -2,8 +2,8 @@ # SPDX-License-Identifier: Apache-2.0 config BOARD_INTEL_ADSP - select SOC_INTEL_CAVS_V25 if BOARD_INTEL_ADSP_CAVS25 - select SOC_INTEL_CAVS_V25 if BOARD_INTEL_ADSP_CAVS25_TGPH + select SOC_CAVSV25 if BOARD_INTEL_ADSP_CAVS25 + select SOC_CAVSV25 if BOARD_INTEL_ADSP_CAVS25_TGPH select SOC_INTEL_ACE15_MTPM if BOARD_INTEL_ADSP_ACE15_MTPM select SOC_INTEL_ACE15_MTPM if BOARD_INTEL_ADSP_ACE15_MTPM_SIM select SOC_INTEL_ACE20_LNL if BOARD_INTEL_ADSP_ACE20_LNL diff --git a/drivers/interrupt_controller/intc_cavs.c b/drivers/interrupt_controller/intc_cavs.c index 38e22c233e81..154d32c47d34 100644 --- a/drivers/interrupt_controller/intc_cavs.c +++ b/drivers/interrupt_controller/intc_cavs.c @@ -16,7 +16,7 @@ #include "intc_cavs.h" #if defined(CONFIG_SMP) && (CONFIG_MP_MAX_NUM_CPUS > 1) -#if defined(CONFIG_SOC_INTEL_CAVS_V25) +#if defined(CONFIG_SOC_CAVSV25) #define PER_CPU_OFFSET(x) (0x40 * x) #else #error "Must define PER_CPU_OFFSET(x) for SoC" diff --git a/soc/intel/intel_adsp/cavs/Kconfig b/soc/intel/intel_adsp/cavs/Kconfig index a609f56b9b5f..a9d127653b4e 100644 --- a/soc/intel/intel_adsp/cavs/Kconfig +++ b/soc/intel/intel_adsp/cavs/Kconfig @@ -15,6 +15,6 @@ config SOC_SERIES_INTEL_ADSP_CAVS select INTEL_ADSP_MEMORY_IS_MIRRORED select CACHE_HAS_MIRRORED_MEMORY_REGIONS -config SOC_INTEL_CAVS_V25 +config SOC_CAVSV25 select XTENSA_WAITI_BUG select SCHED_IPI_SUPPORTED diff --git a/soc/intel/intel_adsp/cavs/Kconfig.defconfig.cavs_v25 b/soc/intel/intel_adsp/cavs/Kconfig.defconfig.cavs_v25 index d0e7662195e1..79ab1a14f226 100644 --- a/soc/intel/intel_adsp/cavs/Kconfig.defconfig.cavs_v25 +++ b/soc/intel/intel_adsp/cavs/Kconfig.defconfig.cavs_v25 @@ -1,7 +1,7 @@ # Copyright (c) 2020,2022-2024 Intel Corporation # SPDX-License-Identifier: Apache-2.0 -if SOC_INTEL_CAVS_V25 +if SOC_CAVSV25 # For backward compatibility, to be removed config SOC_SERIES_INTEL_CAVS_V25 @@ -53,4 +53,4 @@ endif config ADSP_NEED_POWER_ON_CACHE default y -endif # SOC_INTEL_CAVS_V25 +endif # SOC_CAVSV25 diff --git a/soc/intel/intel_adsp/cavs/Kconfig.soc b/soc/intel/intel_adsp/cavs/Kconfig.soc index 40bac2f99ccb..9322bd3afaf1 100644 --- a/soc/intel/intel_adsp/cavs/Kconfig.soc +++ b/soc/intel/intel_adsp/cavs/Kconfig.soc @@ -11,14 +11,14 @@ config SOC_SERIES_INTEL_ADSP_CAVS config SOC_SERIES default "intel_adsp_cavs" if SOC_SERIES_INTEL_ADSP_CAVS -config SOC_INTEL_CAVS_V25 +config SOC_CAVSV25 bool select SOC_SERIES_INTEL_ADSP_CAVS help Intel Tiger Lake config SOC - default "cavs25" if SOC_INTEL_CAVS_V25 + default "cavs25" if SOC_CAVSV25 config SOC_TOOLCHAIN_NAME - default "intel_tgl_adsp" if SOC_INTEL_CAVS_V25 + default "intel_tgl_adsp" if SOC_CAVSV25 diff --git a/soc/intel/intel_adsp/common/gdbstub_backend_sram.c b/soc/intel/intel_adsp/common/gdbstub_backend_sram.c index 93a9dfe5b751..e87f73d8044d 100644 --- a/soc/intel/intel_adsp/common/gdbstub_backend_sram.c +++ b/soc/intel/intel_adsp/common/gdbstub_backend_sram.c @@ -19,7 +19,7 @@ #include #define RING_SIZE 512 -#if CONFIG_SOC_INTEL_CAVS_V25 +#if CONFIG_SOC_CAVSV25 #define SOF_GDB_WINDOW_OFFSET 1024 #elif CONFIG_SOC_INTEL_ACE15_MTPM || CONFIG_SOC_INTEL_ACE20_LNL || CONFIG_SOC_INTEL_ACE30 || \ CONFIG_SOC_INTEL_ACE40 From 61e9f9ea045e2abb8ade878048fce3e284c30eba Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Fri, 16 Jan 2026 11:24:39 -0800 Subject: [PATCH 2269/3659] soc: intel_adsp: rename CONFIG_SOC_INTEL_ACE* to CONFIG_SOC_ACE* Just following guidelines here. Signed-off-by: Daniel Leung --- boards/intel/adsp/Kconfig.intel_adsp | 22 ++++++++--------- drivers/dai/intel/alh/Kconfig.alh | 2 +- drivers/dai/intel/dmic/dmic.c | 20 ++++++---------- drivers/dai/intel/dmic/dmic.h | 3 +-- drivers/dai/intel/dmic/dmic_nhlt.c | 5 ++-- drivers/dai/intel/ssp/dai-params-intel-ipc4.h | 2 +- drivers/dai/intel/ssp/ssp.c | 4 ++-- drivers/dai/intel/ssp/ssp.h | 14 +++++------ drivers/dma/dma_intel_adsp_hda.c | 2 +- .../power_domain/power_domain_intel_adsp.c | 2 +- soc/intel/intel_adsp/ace/CMakeLists.txt | 6 ++--- .../ace/Kconfig.defconfig.ace15_mtpm | 2 +- .../ace/Kconfig.defconfig.ace20_lnl | 2 +- .../intel_adsp/ace/Kconfig.defconfig.ace30 | 2 +- .../intel_adsp/ace/Kconfig.defconfig.ace40 | 2 +- soc/intel/intel_adsp/ace/Kconfig.soc | 24 +++++++++---------- soc/intel/intel_adsp/ace/include/dmic_regs.h | 8 +++---- soc/intel/intel_adsp/ace/power.c | 8 +++---- .../intel_adsp/common/gdbstub_backend_sram.c | 3 +-- 19 files changed, 62 insertions(+), 71 deletions(-) diff --git a/boards/intel/adsp/Kconfig.intel_adsp b/boards/intel/adsp/Kconfig.intel_adsp index 1c9faa8b9575..e4f1d6b479cb 100644 --- a/boards/intel/adsp/Kconfig.intel_adsp +++ b/boards/intel/adsp/Kconfig.intel_adsp @@ -4,14 +4,14 @@ config BOARD_INTEL_ADSP select SOC_CAVSV25 if BOARD_INTEL_ADSP_CAVS25 select SOC_CAVSV25 if BOARD_INTEL_ADSP_CAVS25_TGPH - select SOC_INTEL_ACE15_MTPM if BOARD_INTEL_ADSP_ACE15_MTPM - select SOC_INTEL_ACE15_MTPM if BOARD_INTEL_ADSP_ACE15_MTPM_SIM - select SOC_INTEL_ACE20_LNL if BOARD_INTEL_ADSP_ACE20_LNL - select SOC_INTEL_ACE20_LNL if BOARD_INTEL_ADSP_ACE20_LNL_SIM - select SOC_INTEL_ACE30 if BOARD_INTEL_ADSP_ACE30_PTL - select SOC_INTEL_ACE30 if BOARD_INTEL_ADSP_ACE30_PTL_SIM - select SOC_INTEL_ACE30 if BOARD_INTEL_ADSP_ACE30_WCL - select SOC_INTEL_ACE30 if BOARD_INTEL_ADSP_ACE30_WCL_SIM - select SOC_INTEL_ACE40 if BOARD_INTEL_ADSP_ACE40_NVL - select SOC_INTEL_ACE40 if BOARD_INTEL_ADSP_ACE40_NVL_SIM - select SOC_INTEL_ACE40 if BOARD_INTEL_ADSP_ACE40_NVLS + select SOC_ACE15_MTPM if BOARD_INTEL_ADSP_ACE15_MTPM + select SOC_ACE15_MTPM if BOARD_INTEL_ADSP_ACE15_MTPM_SIM + select SOC_ACE20_LNL if BOARD_INTEL_ADSP_ACE20_LNL + select SOC_ACE20_LNL if BOARD_INTEL_ADSP_ACE20_LNL_SIM + select SOC_ACE30 if BOARD_INTEL_ADSP_ACE30_PTL + select SOC_ACE30 if BOARD_INTEL_ADSP_ACE30_PTL_SIM + select SOC_ACE30 if BOARD_INTEL_ADSP_ACE30_WCL + select SOC_ACE30 if BOARD_INTEL_ADSP_ACE30_WCL_SIM + select SOC_ACE40 if BOARD_INTEL_ADSP_ACE40_NVL + select SOC_ACE40 if BOARD_INTEL_ADSP_ACE40_NVL_SIM + select SOC_ACE40 if BOARD_INTEL_ADSP_ACE40_NVLS diff --git a/drivers/dai/intel/alh/Kconfig.alh b/drivers/dai/intel/alh/Kconfig.alh index 785074454fb7..a5eaee2231c8 100644 --- a/drivers/dai/intel/alh/Kconfig.alh +++ b/drivers/dai/intel/alh/Kconfig.alh @@ -18,7 +18,7 @@ if DAI_INTEL_ALH config DAI_ALH_HAS_OWNERSHIP bool "Intel ALH driver has ownership only on ACE 1.5" default y - depends on SOC_INTEL_ACE15_MTPM + depends on SOC_ACE15_MTPM help Select this to enable programming HW ownership diff --git a/drivers/dai/intel/dmic/dmic.c b/drivers/dai/intel/dmic/dmic.c index 79b71e5d66f8..a53e0f957e62 100644 --- a/drivers/dai/intel/dmic/dmic.c +++ b/drivers/dai/intel/dmic/dmic.c @@ -162,8 +162,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) { -#if defined(CONFIG_SOC_INTEL_ACE20_LNL) || defined(CONFIG_SOC_INTEL_ACE30) || \ - defined(CONFIG_SOC_INTEL_ACE40) +#if defined(CONFIG_SOC_ACE20_LNL) || defined(CONFIG_SOC_ACE30) || defined(CONFIG_SOC_ACE40) return dmic->hdamldmic_base; #else return dmic->shim_base; @@ -176,8 +175,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 */ -#if defined(CONFIG_SOC_INTEL_ACE20_LNL) || defined(CONFIG_SOC_INTEL_ACE30) || \ - defined(CONFIG_SOC_INTEL_ACE40) +#if defined(CONFIG_SOC_ACE20_LNL) || defined(CONFIG_SOC_ACE30) || defined(CONFIG_SOC_ACE40) sys_write32(sys_read32(base + DMICSYNC_OFFSET) | FIELD_PREP(DMICSYNC_SYNCPRD, val), base + DMICSYNC_OFFSET); sys_write32(sys_read32(base + DMICSYNC_OFFSET) | DMICSYNC_SYNCPU, @@ -264,8 +262,7 @@ static void dai_dmic_stop_fifo_packers(struct dai_intel_dmic *dmic, static inline void dai_dmic_dis_clk_gating(const struct dai_intel_dmic *dmic) { /* Disable DMIC clock gating */ -#if defined(CONFIG_SOC_INTEL_ACE20_LNL) || defined(CONFIG_SOC_INTEL_ACE30) || \ - defined(CONFIG_SOC_INTEL_ACE40) +#if defined(CONFIG_SOC_ACE20_LNL) || defined(CONFIG_SOC_ACE30) || defined(CONFIG_SOC_ACE40) sys_write32((sys_read32(dmic->vshim_base + DMICLVSCTL_OFFSET) | DMICLVSCTL_DCGD), dmic->vshim_base + DMICLVSCTL_OFFSET); #else @@ -277,8 +274,7 @@ 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 */ -#if defined(CONFIG_SOC_INTEL_ACE20_LNL) || defined(CONFIG_SOC_INTEL_ACE30) || \ - defined(CONFIG_SOC_INTEL_ACE40) +#if defined(CONFIG_SOC_ACE20_LNL) || defined(CONFIG_SOC_ACE30) || defined(CONFIG_SOC_ACE40) sys_write32((sys_read32(dmic->vshim_base + DMICLVSCTL_OFFSET) & ~DMICLVSCTL_DCGD), dmic->vshim_base + DMICLVSCTL_OFFSET); #else /* All other CAVS and ACE platforms */ @@ -292,8 +288,7 @@ static inline void dai_dmic_program_channel_map(const struct dai_intel_dmic *dmi const struct dai_config *cfg, uint32_t index) { -#if defined(CONFIG_SOC_INTEL_ACE20_LNL) || defined(CONFIG_SOC_INTEL_ACE30) || \ - defined(CONFIG_SOC_INTEL_ACE40) +#if defined(CONFIG_SOC_ACE20_LNL) || defined(CONFIG_SOC_ACE30) || defined(CONFIG_SOC_ACE40) uint16_t pcmsycm = cfg->link_config; uint32_t reg_add = dmic->shim_base + DMICXPCMSyCM_OFFSET + 0x0004*index; @@ -302,7 +297,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 /* CONFIG_SOC_INTEL_ACE20_LNL || CONFIG_SOC_INTEL_ACE30 || CONFIG_SOC_INTEL_ACE40 */ +#endif /* CONFIG_SOC_ACE20_LNL || CONFIG_SOC_ACE30 || CONFIG_SOC_ACE40 */ } static inline void dai_dmic_en_power(const struct dai_intel_dmic *dmic) @@ -312,8 +307,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); -#if defined(CONFIG_SOC_INTEL_ACE20_LNL) || defined(CONFIG_SOC_INTEL_ACE30) || \ - defined(CONFIG_SOC_INTEL_ACE40) +#if defined(CONFIG_SOC_ACE20_LNL) || defined(CONFIG_SOC_ACE30) || defined(CONFIG_SOC_ACE40) while (!(sys_read32(base + DMICLCTL_OFFSET) & DMICLCTL_CPA)) { k_busy_wait(100); } diff --git a/drivers/dai/intel/dmic/dmic.h b/drivers/dai/intel/dmic/dmic.h index 190c53bb8b58..57424e1dc629 100644 --- a/drivers/dai/intel/dmic/dmic.h +++ b/drivers/dai/intel/dmic/dmic.h @@ -173,8 +173,7 @@ struct dai_intel_dmic { /* hardware parameters */ uint32_t reg_base; uint32_t shim_base; -#if defined(CONFIG_SOC_INTEL_ACE20_LNL) || defined(CONFIG_SOC_INTEL_ACE30) || \ - defined(CONFIG_SOC_INTEL_ACE40) +#if defined(CONFIG_SOC_ACE20_LNL) || defined(CONFIG_SOC_ACE30) || defined(CONFIG_SOC_ACE40) 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 278836671637..8b645be2ebe4 100644 --- a/drivers/dai/intel/dmic/dmic_nhlt.c +++ b/drivers/dai/intel/dmic/dmic_nhlt.c @@ -282,8 +282,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; -#if defined(CONFIG_SOC_INTEL_ACE20_LNL) || defined(CONFIG_SOC_INTEL_ACE30) || \ - defined(CONFIG_SOC_INTEL_ACE40) /* ACE 2.0,3.0,4.0 */ +#if defined(CONFIG_SOC_ACE20_LNL) || defined(CONFIG_SOC_ACE30) || defined(CONFIG_SOC_ACE40) val = sys_read32(dmic->vshim_base + DMICLVSCTL_OFFSET); val &= ~DMICLVSCTL_MLCS; val |= FIELD_PREP(DMICLVSCTL_MLCS, source); @@ -309,7 +308,7 @@ static int dai_dmic_set_clock(const struct dai_intel_dmic *dmic, const uint8_t c return -ENOTSUP; } -#if defined(CONFIG_SOC_INTEL_ACE15_MTPM) +#if defined(CONFIG_SOC_ACE15_MTPM) if (clock_source && !(sys_read32(dmic->shim_base + DMICLCAP_OFFSET) & DMICLCAP_MLCS)) { return -ENOTSUP; } diff --git a/drivers/dai/intel/ssp/dai-params-intel-ipc4.h b/drivers/dai/intel/ssp/dai-params-intel-ipc4.h index 847171f4e395..05e768be2968 100644 --- a/drivers/dai/intel/ssp/dai-params-intel-ipc4.h +++ b/drivers/dai/intel/ssp/dai-params-intel-ipc4.h @@ -270,7 +270,7 @@ struct dai_intel_ipc4_ssp_mclk_config_2 { } __packed; struct dai_intel_ipc4_ssp_driver_config { -#if defined(CONFIG_SOC_INTEL_ACE30) || defined(CONFIG_SOC_INTEL_ACE40) +#if defined(CONFIG_SOC_ACE30) || defined(CONFIG_SOC_ACE40) struct dai_intel_ipc4_ssp_config_ver_3_0 i2s_config; #else struct dai_intel_ipc4_ssp_config i2s_config; diff --git a/drivers/dai/intel/ssp/ssp.c b/drivers/dai/intel/ssp/ssp.c index a2395a611ac0..eb80adbb8002 100644 --- a/drivers/dai/intel/ssp/ssp.c +++ b/drivers/dai/intel/ssp/ssp.c @@ -859,7 +859,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, const void *spec_config) { -#if defined(CONFIG_SOC_INTEL_ACE20_LNL) +#if defined(CONFIG_SOC_ACE20_LNL) ARG_UNUSED(spec_config); uint16_t pcmsycm = cfg->link_config; /* Set upper slot number from configuration */ @@ -918,7 +918,7 @@ static void dai_ssp_program_channel_map(struct dai_intel_ssp *dp, ARG_UNUSED(cfg); ARG_UNUSED(ssp_index); ARG_UNUSED(spec_config); -#endif /* CONFIG_SOC_INTEL_ACE20_LNL */ +#endif /* CONFIG_SOC_ACE20_LNL */ } /* empty SSP transmit FIFO */ diff --git a/drivers/dai/intel/ssp/ssp.h b/drivers/dai/intel/ssp/ssp.h index f72ab7efc6cb..2058fcd07f9c 100644 --- a/drivers/dai/intel/ssp/ssp.h +++ b/drivers/dai/intel/ssp/ssp.h @@ -16,13 +16,13 @@ /* SSP IP version defined by CONFIG_SOC*/ #if defined(CONFIG_SOC_SERIES_INTEL_ADSP_CAVS) #define SSP_IP_VER SSP_IP_VER_1_0 -#elif defined(CONFIG_SOC_INTEL_ACE15_MTPM) +#elif defined(CONFIG_SOC_ACE15_MTPM) #define SSP_IP_VER SSP_IP_VER_1_5 -#elif defined(CONFIG_SOC_INTEL_ACE20_LNL) +#elif defined(CONFIG_SOC_ACE20_LNL) #define SSP_IP_VER SSP_IP_VER_2_0 -#elif defined(CONFIG_SOC_INTEL_ACE30) +#elif defined(CONFIG_SOC_ACE30) #define SSP_IP_VER SSP_IP_VER_3_0 -#elif defined(CONFIG_SOC_INTEL_ACE40) +#elif defined(CONFIG_SOC_ACE40) #define SSP_IP_VER SSP_IP_VER_4_0 #else #error "Unknown SSP IP" @@ -68,11 +68,11 @@ #define DAI_INTEL_SSP_CLOCK_AUDIO_CARDINAL 0x1 #define DAI_INTEL_SSP_CLOCK_PLL_FIXED 0x2 -#if defined(CONFIG_SOC_INTEL_ACE15_MTPM) || defined(CONFIG_SOC_SERIES_INTEL_ADSP_CAVS) +#if defined(CONFIG_SOC_ACE15_MTPM) || defined(CONFIG_SOC_SERIES_INTEL_ADSP_CAVS) #include "ssp_regs_v1.h" -#elif defined(CONFIG_SOC_INTEL_ACE20_LNL) +#elif defined(CONFIG_SOC_ACE20_LNL) #include "ssp_regs_v2.h" -#elif defined(CONFIG_SOC_INTEL_ACE30) || defined(CONFIG_SOC_INTEL_ACE40) +#elif defined(CONFIG_SOC_ACE30) || defined(CONFIG_SOC_ACE40) #include "ssp_regs_v3.h" #else #error "Missing ssp definitions" diff --git a/drivers/dma/dma_intel_adsp_hda.c b/drivers/dma/dma_intel_adsp_hda.c index 64ff9e3d85ce..3a36e95be31b 100644 --- a/drivers/dma/dma_intel_adsp_hda.c +++ b/drivers/dma/dma_intel_adsp_hda.c @@ -235,7 +235,7 @@ int intel_adsp_hda_dma_status(const struct device *dev, uint32_t channel, stat->pending_length = used; stat->free = unused; -#if CONFIG_SOC_INTEL_ACE20_LNL || CONFIG_SOC_INTEL_ACE30 || CONFIG_SOC_INTEL_ACE40 +#if CONFIG_SOC_ACE20_LNL || CONFIG_SOC_ACE30 || CONFIG_SOC_ACE40 /* Linear Link Position via HDA-DMA is only supported on ACE2 or newer */ if (cfg->direction == MEMORY_TO_PERIPHERAL || cfg->direction == PERIPHERAL_TO_MEMORY) { uint32_t tmp; diff --git a/drivers/power_domain/power_domain_intel_adsp.c b/drivers/power_domain/power_domain_intel_adsp.c index ec3f9328d8b5..60b1e672e120 100644 --- a/drivers/power_domain/power_domain_intel_adsp.c +++ b/drivers/power_domain/power_domain_intel_adsp.c @@ -32,7 +32,7 @@ static int pd_intel_adsp_set_power_enable(struct pg_bits *bits, bool power_enabl return -EIO; } } else { -#if CONFIG_SOC_INTEL_ACE15_MTPM +#if CONFIG_SOC_ACE15_MTPM extern uint32_t adsp_pending_buffer; if (bits->SPA_bit == INTEL_ADSP_HST_DOMAIN_BIT) { diff --git a/soc/intel/intel_adsp/ace/CMakeLists.txt b/soc/intel/intel_adsp/ace/CMakeLists.txt index 80225ab23de4..e45f7761315b 100644 --- a/soc/intel/intel_adsp/ace/CMakeLists.txt +++ b/soc/intel/intel_adsp/ace/CMakeLists.txt @@ -15,7 +15,7 @@ zephyr_library_sources( ) if(CONFIG_GDBSTUB) - if(CONFIG_SOC_INTEL_ACE40) + if(CONFIG_SOC_ACE40) zephyr_library_sources(gdbstub_ace40.c) else() zephyr_library_sources(gdbstub.c) @@ -32,8 +32,8 @@ zephyr_library_sources_ifdef( ) if(CONFIG_XTENSA_MMU) - zephyr_library_sources_ifdef(CONFIG_SOC_INTEL_ACE30 mmu_ace30.c) - zephyr_library_sources_ifdef(CONFIG_SOC_INTEL_ACE40 mmu_ace40.c) + zephyr_library_sources_ifdef(CONFIG_SOC_ACE30 mmu_ace30.c) + zephyr_library_sources_ifdef(CONFIG_SOC_ACE40 mmu_ace40.c) endif() set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld CACHE INTERNAL "") diff --git a/soc/intel/intel_adsp/ace/Kconfig.defconfig.ace15_mtpm b/soc/intel/intel_adsp/ace/Kconfig.defconfig.ace15_mtpm index e34d54eeaf6a..b59259b8df36 100644 --- a/soc/intel/intel_adsp/ace/Kconfig.defconfig.ace15_mtpm +++ b/soc/intel/intel_adsp/ace/Kconfig.defconfig.ace15_mtpm @@ -1,7 +1,7 @@ # Copyright (c) 2022-2024 Intel Corporation # SPDX-License-Identifier: Apache-2.0 -if SOC_INTEL_ACE15_MTPM +if SOC_ACE15_MTPM config MP_MAX_NUM_CPUS default 3 diff --git a/soc/intel/intel_adsp/ace/Kconfig.defconfig.ace20_lnl b/soc/intel/intel_adsp/ace/Kconfig.defconfig.ace20_lnl index afc2758d25b7..f60003bacb8a 100644 --- a/soc/intel/intel_adsp/ace/Kconfig.defconfig.ace20_lnl +++ b/soc/intel/intel_adsp/ace/Kconfig.defconfig.ace20_lnl @@ -1,7 +1,7 @@ # Copyright (c) 2022-2024 Intel Corporation # SPDX-License-Identifier: Apache-2.0 -if SOC_INTEL_ACE20_LNL +if SOC_ACE20_LNL config MP_MAX_NUM_CPUS default 5 diff --git a/soc/intel/intel_adsp/ace/Kconfig.defconfig.ace30 b/soc/intel/intel_adsp/ace/Kconfig.defconfig.ace30 index bd9d561319ef..9a63398c1a0b 100644 --- a/soc/intel/intel_adsp/ace/Kconfig.defconfig.ace30 +++ b/soc/intel/intel_adsp/ace/Kconfig.defconfig.ace30 @@ -2,7 +2,7 @@ # SPDX-License-Identifier: Apache-2.0 -if SOC_INTEL_ACE30 +if SOC_ACE30 config MP_MAX_NUM_CPUS default 5 if BOARD_INTEL_ADSP_ACE30_PTL || BOARD_INTEL_ADSP_ACE30_PTL_SIM diff --git a/soc/intel/intel_adsp/ace/Kconfig.defconfig.ace40 b/soc/intel/intel_adsp/ace/Kconfig.defconfig.ace40 index 682b0870b684..91edccd98a46 100644 --- a/soc/intel/intel_adsp/ace/Kconfig.defconfig.ace40 +++ b/soc/intel/intel_adsp/ace/Kconfig.defconfig.ace40 @@ -2,7 +2,7 @@ # SPDX-License-Identifier: Apache-2.0 -if SOC_INTEL_ACE40 +if SOC_ACE40 config MP_MAX_NUM_CPUS default 4 if BOARD_INTEL_ADSP_ACE40_NVL diff --git a/soc/intel/intel_adsp/ace/Kconfig.soc b/soc/intel/intel_adsp/ace/Kconfig.soc index b8f8e19a2c83..1f380a301572 100644 --- a/soc/intel/intel_adsp/ace/Kconfig.soc +++ b/soc/intel/intel_adsp/ace/Kconfig.soc @@ -11,7 +11,7 @@ config SOC_SERIES_INTEL_ADSP_ACE config SOC_SERIES_INTEL_ADSP_ACE15 bool -config SOC_INTEL_ACE15_MTPM +config SOC_ACE15_MTPM bool select SOC_SERIES_INTEL_ADSP_ACE select SOC_SERIES_INTEL_ADSP_ACE15 @@ -21,7 +21,7 @@ config SOC_INTEL_ACE15_MTPM config SOC_SERIES_INTEL_ADSP_ACE20 bool -config SOC_INTEL_ACE20_LNL +config SOC_ACE20_LNL bool select SOC_SERIES_INTEL_ADSP_ACE select SOC_SERIES_INTEL_ADSP_ACE20 @@ -31,7 +31,7 @@ config SOC_INTEL_ACE20_LNL config SOC_SERIES_INTEL_ADSP_ACE30 bool -config SOC_INTEL_ACE30 +config SOC_ACE30 bool select SOC_SERIES_INTEL_ADSP_ACE select SOC_SERIES_INTEL_ADSP_ACE30 @@ -41,7 +41,7 @@ config SOC_INTEL_ACE30 config SOC_SERIES_INTEL_ADSP_ACE40 bool -config SOC_INTEL_ACE40 +config SOC_ACE40 bool select SOC_SERIES_INTEL_ADSP_ACE select SOC_SERIES_INTEL_ADSP_ACE40 @@ -52,13 +52,13 @@ config SOC_SERIES default "intel_adsp_ace" if SOC_SERIES_INTEL_ADSP_ACE config SOC_TOOLCHAIN_NAME - default "intel_ace15_mtpm" if SOC_INTEL_ACE15_MTPM - default "intel_ace15_mtpm" if SOC_INTEL_ACE20_LNL - default "intel_ace30_ptl" if SOC_INTEL_ACE30 - default "intel_ace40" if SOC_INTEL_ACE40 + default "intel_ace15_mtpm" if SOC_ACE15_MTPM + default "intel_ace15_mtpm" if SOC_ACE20_LNL + default "intel_ace30_ptl" if SOC_ACE30 + default "intel_ace40" if SOC_ACE40 config SOC - default "ace15_mtpm" if SOC_INTEL_ACE15_MTPM - default "ace20_lnl" if SOC_INTEL_ACE20_LNL - default "ace30" if SOC_INTEL_ACE30 - default "ace40" if SOC_INTEL_ACE40 + default "ace15_mtpm" if SOC_ACE15_MTPM + default "ace20_lnl" if SOC_ACE20_LNL + default "ace30" if SOC_ACE30 + default "ace40" if SOC_ACE40 diff --git a/soc/intel/intel_adsp/ace/include/dmic_regs.h b/soc/intel/intel_adsp/ace/include/dmic_regs.h index 571040e5550b..a3588449eafb 100644 --- a/soc/intel/intel_adsp/ace/include/dmic_regs.h +++ b/soc/intel/intel_adsp/ace/include/dmic_regs.h @@ -347,13 +347,13 @@ /* Digital Mic Shim Registers */ -#ifdef CONFIG_SOC_INTEL_ACE20_LNL +#ifdef CONFIG_SOC_ACE20_LNL #include -#elif CONFIG_SOC_INTEL_ACE15_MTPM +#elif CONFIG_SOC_ACE15_MTPM #include -#elif CONFIG_SOC_INTEL_ACE30 +#elif CONFIG_SOC_ACE30 #include -#elif CONFIG_SOC_INTEL_ACE40 +#elif CONFIG_SOC_ACE40 #include #else #error "Unknown SoC" diff --git a/soc/intel/intel_adsp/ace/power.c b/soc/intel/intel_adsp/ace/power.c index b30d4eff04ed..a3c9a0aa9198 100644 --- a/soc/intel/intel_adsp/ace/power.c +++ b/soc/intel/intel_adsp/ace/power.c @@ -24,12 +24,12 @@ #define LPSRAM_MAGIC_VALUE 0x13579BDF #define LPSCTL_BATTR_MASK GENMASK(16, 12) -#if CONFIG_SOC_INTEL_ACE15_MTPM +#if CONFIG_SOC_ACE15_MTPM /* Used to force any pending transaction by HW issuing an upstream read before * power down host domain. */ uint8_t adsp_pending_buffer[CONFIG_DCACHE_LINE_SIZE] __aligned(CONFIG_DCACHE_LINE_SIZE); -#endif /* CONFIG_SOC_INTEL_ACE15_MTPM */ +#endif /* CONFIG_SOC_ACE15_MTPM */ __imr void power_init(void) { @@ -41,13 +41,13 @@ __imr void power_init(void) DSPCS.bootctl[0].bctl |= DSPBR_BCTL_WAITIPCG | DSPBR_BCTL_WAITIPPG; #endif /* CONFIG_ADSP_IDLE_CLOCK_GATING */ -#if CONFIG_SOC_INTEL_ACE15_MTPM +#if CONFIG_SOC_ACE15_MTPM *((__sparse_force uint32_t *)sys_cache_cached_ptr_get(&adsp_pending_buffer)) = INTEL_ADSP_ACE15_MAGIC_KEY; sys_cache_data_flush_range((__sparse_force void *) sys_cache_cached_ptr_get(&adsp_pending_buffer), sizeof(adsp_pending_buffer)); -#endif /* CONFIG_SOC_INTEL_ACE15_MTPM */ +#endif /* CONFIG_SOC_ACE15_MTPM */ } #ifdef CONFIG_PM diff --git a/soc/intel/intel_adsp/common/gdbstub_backend_sram.c b/soc/intel/intel_adsp/common/gdbstub_backend_sram.c index e87f73d8044d..f881302c637d 100644 --- a/soc/intel/intel_adsp/common/gdbstub_backend_sram.c +++ b/soc/intel/intel_adsp/common/gdbstub_backend_sram.c @@ -21,8 +21,7 @@ #define RING_SIZE 512 #if CONFIG_SOC_CAVSV25 #define SOF_GDB_WINDOW_OFFSET 1024 -#elif CONFIG_SOC_INTEL_ACE15_MTPM || CONFIG_SOC_INTEL_ACE20_LNL || CONFIG_SOC_INTEL_ACE30 || \ - CONFIG_SOC_INTEL_ACE40 +#elif CONFIG_SOC_ACE15_MTPM || CONFIG_SOC_ACE20_LNL || CONFIG_SOC_ACE30 || CONFIG_SOC_ACE40 /* * MTL has 2 usable slots in debug window, which is more than 1 slot on TGL, but * still slot 0 is always used for logging, slot 1 is assigned to shell From e30b0acea928874f11c1326c2b811889dbfb8b45 Mon Sep 17 00:00:00 2001 From: Ederson de Souza Date: Fri, 16 Jan 2026 08:43:56 -0800 Subject: [PATCH 2270/3659] MAINTAINERS: Add edersondisouza as PMCI collaborator Add edersondisouza as a collaborator to PMCI - it should've been done when edersondisouza was added as libmctp West module collaborator, but it was missed. Signed-off-by: Ederson de Souza --- MAINTAINERS.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index cd048cc80659..0aff172eb1e8 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -4255,6 +4255,7 @@ PMCI: collaborators: - nashif - kehintel + - edersondisouza files: - subsys/pmci/ - samples/subsys/pmci/ From dba5c5081fe83d0c63e5b216224033b9dbe7b9bc Mon Sep 17 00:00:00 2001 From: Albort Xue Date: Tue, 13 Jan 2026 16:37:11 +0800 Subject: [PATCH 2271/3659] drivers: pwm: mcux_tpm: Add clock configuration support Add clock_control_configure() call during initialization to properly configure the TPM clock. The driver now attempts to configure the clock and handles cases where configuration is not supported by the platform (-ENOTSUP/-ENOSYS) by continuing with default settings. Real configuration errors are logged and cause initialization to fail. Note: -ENOSYS is temporarily ignored as not all clock control drivers currently implement the configure API. This handling should be removed once all clock drivers support configure. Signed-off-by: Albort Xue --- drivers/pwm/pwm_mcux_tpm.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/pwm/pwm_mcux_tpm.c b/drivers/pwm/pwm_mcux_tpm.c index a42460588b35..8c075227af27 100644 --- a/drivers/pwm/pwm_mcux_tpm.c +++ b/drivers/pwm/pwm_mcux_tpm.c @@ -1,6 +1,6 @@ /* * Copyright 2019 Henrik Brix Andersen - * Copyright 2020, 2024-2025 NXP + * Copyright 2020, 2024-2026 NXP * * Heavily based on pwm_mcux_ftm.c, which is: * Copyright (c) 2017, NXP @@ -515,6 +515,16 @@ static int mcux_tpm_init(const struct device *dev) return -ENODEV; } + err = clock_control_configure(config->clock_dev, config->clock_subsys, NULL); + if (err != 0) { + /* Check if error is due to lack of support */ + if (err != -ENOSYS) { + /* Real error occurred */ + LOG_ERR("Failed to configure clock: %d", err); + return err; + } + } + #if defined(CONFIG_SOC_MIMX9596) /* IMX9596 AON and WAKEUP clocks aren't controllable */ if (config->clock_subsys != (clock_control_subsys_t)IMX95_CLK_BUSWAKEUP && From d9e86ad878bae152ca9c6d8dcb41f3147675c7d8 Mon Sep 17 00:00:00 2001 From: Albort Xue Date: Tue, 13 Jan 2026 15:14:56 +0800 Subject: [PATCH 2272/3659] drivers: can: mcux_flexcan: Add clock configuration and enable Add explicit clock configuration and enable calls during driver initialization. Note: -ENOSYS is temporarily ignored as not all clock control drivers currently implement the configure API. This handling should be removed once all clock drivers support configure. Signed-off-by: Albort Xue --- drivers/can/can_mcux_flexcan.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/drivers/can/can_mcux_flexcan.c b/drivers/can/can_mcux_flexcan.c index 3dd214743406..b9a6f3df3e9d 100644 --- a/drivers/can/can_mcux_flexcan.c +++ b/drivers/can/can_mcux_flexcan.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2019-2026 Vestas Wind Systems A/S - * Copyright 2025 NXP + * Copyright 2025-2026 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -1176,6 +1176,24 @@ static int mcux_flexcan_init(const struct device *dev) return -ENODEV; } + err = clock_control_configure(config->clock_dev, config->clock_subsys, NULL); + if (err) { + /* Check if error is due to lack of support */ + if (err != -ENOSYS) { + /* Real error occurred */ + LOG_ERR("Failed to configure clock: %d", err); + return err; + } + } + +#if FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL + err = clock_control_on(config->clock_dev, config->clock_subsys); + if (err) { + LOG_ERR("Failed to enable clock: %d", err); + return err; + } +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + DEVICE_MMIO_NAMED_MAP(dev, flexcan_mmio, K_MEM_CACHE_NONE | K_MEM_DIRECT_MAP); LOG_DBG("Message Buffers: %d, RX MB: %d, TX MB: %d", From 45cde341dc9e617033005dc5e168e02d38ba260d Mon Sep 17 00:00:00 2001 From: TOKITA Hiroshi Date: Wed, 7 Jan 2026 08:39:06 +0900 Subject: [PATCH 2273/3659] drivers: serial: pl011: Allows mixed IRQ settings. Allows a mixture of IRQ-enabled and IRQ-disabled nodes. Enabled nodes are identified by the presence or absence of the interrupt-names property. Signed-off-by: TOKITA Hiroshi --- drivers/serial/uart_pl011.c | 108 +++++++++++++++++++++--------------- 1 file changed, 63 insertions(+), 45 deletions(-) diff --git a/drivers/serial/uart_pl011.c b/drivers/serial/uart_pl011.c index 1cdd798e0936..4d67e3254759 100644 --- a/drivers/serial/uart_pl011.c +++ b/drivers/serial/uart_pl011.c @@ -34,6 +34,11 @@ #include "uart_pl011_registers.h" +#define PL011_USE_IRQ \ + (CONFIG_UART_INTERRUPT_DRIVEN && \ + (DT_ANY_COMPAT_HAS_PROP_STATUS_OKAY(arm_pl011, interrupts) || \ + DT_ANY_COMPAT_HAS_PROP_STATUS_OKAY(arm_sbsa_uart, interrupts))) + struct pl011_config { DEVICE_MMIO_ROM; #if defined(CONFIG_PINCTRL) @@ -46,7 +51,7 @@ struct pl011_config { const struct device *clock_dev; clock_control_subsys_t clock_id; #endif -#ifdef CONFIG_UART_INTERRUPT_DRIVEN +#if PL011_USE_IRQ uart_irq_config_func_t irq_config_func; #endif bool fifo_disable; @@ -60,7 +65,7 @@ struct pl011_data { struct uart_config uart_cfg; bool sbsa; /* SBSA mode */ uint32_t clk_freq; -#ifdef CONFIG_UART_INTERRUPT_DRIVEN +#if PL011_USE_IRQ volatile bool sw_call_txdrdy; uart_irq_callback_user_data_t irq_cb; struct k_spinlock irq_cb_lock; @@ -364,7 +369,7 @@ static int pl011_runtime_config_get(const struct device *dev, #endif /* CONFIG_UART_USE_RUNTIME_CONFIGURE */ -#ifdef CONFIG_UART_INTERRUPT_DRIVEN +#if PL011_USE_IRQ static int pl011_fifo_fill(const struct device *dev, const uint8_t *tx_data, int len) { @@ -511,8 +516,19 @@ static void pl011_irq_callback_set(const struct device *dev, data->irq_cb = cb; data->irq_cb_data = cb_data; } -#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ +#endif /* PL011_USE_IRQ */ + +static __maybe_unused DEVICE_API(uart, pl011_driver_api_noirq) = { + .poll_in = pl011_poll_in, + .poll_out = pl011_poll_out, + .err_check = pl011_err_check, +#ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE + .configure = pl011_runtime_configure, + .config_get = pl011_runtime_config_get, +#endif +}; +#if PL011_USE_IRQ static DEVICE_API(uart, pl011_driver_api) = { .poll_in = pl011_poll_in, .poll_out = pl011_poll_out, @@ -521,7 +537,6 @@ static DEVICE_API(uart, pl011_driver_api) = { .configure = pl011_runtime_configure, .config_get = pl011_runtime_config_get, #endif -#ifdef CONFIG_UART_INTERRUPT_DRIVEN .fifo_fill = pl011_fifo_fill, .fifo_read = pl011_fifo_read, .irq_tx_enable = pl011_irq_tx_enable, @@ -536,8 +551,8 @@ static DEVICE_API(uart, pl011_driver_api) = { .irq_is_pending = pl011_irq_is_pending, .irq_update = pl011_irq_update, .irq_callback_set = pl011_irq_callback_set, -#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ }; +#endif /* PL011_USE_IRQ */ static int pl011_init(const struct device *dev) { @@ -618,10 +633,14 @@ static int pl011_init(const struct device *dev) uart->cr |= PL011_CR_RXE | PL011_CR_TXE; barrier_isync_fence_full(); } -#ifdef CONFIG_UART_INTERRUPT_DRIVEN - config->irq_config_func(dev); - data->sw_call_txdrdy = true; + +#if PL011_USE_IRQ + if (config->irq_config_func) { + config->irq_config_func(dev); + data->sw_call_txdrdy = true; + } #endif + if (!data->sbsa) { pl011_enable(dev); } @@ -671,7 +690,10 @@ static int pl011_init(const struct device *dev) .clock_id = (clock_control_subsys_t)DT_INST_CLOCKS_CELL(n, \ COMPAT_SPECIFIC_CLOCK_CTLR_SUBSYS_CELL(n)),)) -#ifdef CONFIG_UART_INTERRUPT_DRIVEN +#define IRQ_CONFIG_FUNC_INIT(n) \ + IF_ENABLED(PL011_NODE_USE_IRQ(n), (.irq_config_func = pl011_irq_config_func_##n,)) + +#if PL011_USE_IRQ void pl011_isr(const struct device *dev) { struct pl011_data *data = dev->data; @@ -683,9 +705,8 @@ void pl011_isr(const struct device *dev) } } } -#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ +#endif /* PL011_USE_IRQ */ -#ifdef CONFIG_UART_INTERRUPT_DRIVEN #define PL011_IRQ_CONFIG_FUNC_BODY(n, prop, i) \ { \ IRQ_CONNECT(DT_IRQ_BY_IDX(n, i, irq), \ @@ -696,30 +717,33 @@ void pl011_isr(const struct device *dev) irq_enable(DT_IRQ_BY_IDX(n, i, irq)); \ } +#define PL011_NODE_USE_IRQ(n) \ + COND_CODE_1(CONFIG_UART_INTERRUPT_DRIVEN, (DT_INST_NODE_HAS_PROP(n, interrupts)), (0)) + +#define PL011_DEVICE_API(n) \ + COND_CODE_1(CONFIG_UART_INTERRUPT_DRIVEN, \ + (COND_CODE_1(DT_INST_NODE_HAS_PROP(n, interrupts), \ + (&pl011_driver_api), (&pl011_driver_api_noirq))), \ + (&pl011_driver_api_noirq)) + #define PL011_CONFIG_PORT(n) \ - static void pl011_irq_config_func_##n(const struct device *dev) \ - { \ - DT_INST_FOREACH_PROP_ELEM(n, interrupt_names, \ + IF_ENABLED(PL011_NODE_USE_IRQ(n), ( \ + static void pl011_irq_config_func_##n(const struct device *dev) \ + { \ + DT_INST_FOREACH_PROP_ELEM(n, interrupt_names, \ PL011_IRQ_CONFIG_FUNC_BODY) \ - }; \ + }; \ + )) \ \ static struct pl011_config pl011_cfg_port_##n = { \ DEVICE_MMIO_ROM_INIT(DT_DRV_INST(n)), \ CLOCK_INIT(n) \ PINCTRL_INIT(n) \ - .irq_config_func = pl011_irq_config_func_##n, \ + IRQ_CONFIG_FUNC_INIT(n) \ .fifo_disable = DT_INST_PROP(n, fifo_disable), \ .clk_enable_func = COMPAT_SPECIFIC_CLK_ENABLE_FUNC(n), \ .pwr_on_func = COMPAT_SPECIFIC_PWR_ON_FUNC(n), \ }; -#else -#define PL011_CONFIG_PORT(n) \ - static struct pl011_config pl011_cfg_port_##n = { \ - DEVICE_MMIO_ROM_INIT(DT_DRV_INST(n)), \ - CLOCK_INIT(n) \ - PINCTRL_INIT(n) \ - }; -#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ #define PL011_INIT(n) \ PINCTRL_DEFINE(n) \ @@ -742,9 +766,9 @@ void pl011_isr(const struct device *dev) (DT_INST_PROP_BY_PHANDLE(n, clocks, clock_frequency)), (0)), \ }; \ \ - DEVICE_DT_INST_DEFINE(n, pl011_init, PM_INST_GET(n), &pl011_data_port_##n, \ + DEVICE_DT_INST_DEFINE(n, pl011_init, PM_INST_GET(n), &pl011_data_port_##n, \ &pl011_cfg_port_##n, PRE_KERNEL_1, CONFIG_SERIAL_INIT_PRIORITY, \ - &pl011_driver_api); + PL011_DEVICE_API(n)); DT_INST_FOREACH_STATUS_OKAY(PL011_INIT) @@ -753,24 +777,18 @@ DT_INST_FOREACH_STATUS_OKAY(PL011_INIT) #undef DT_DRV_COMPAT #define DT_DRV_COMPAT SBSA_COMPAT -#ifdef CONFIG_UART_INTERRUPT_DRIVEN -#define PL011_SBSA_CONFIG_PORT(n) \ - static void pl011_irq_config_func_sbsa_##n(const struct device *dev) \ - { \ - DT_INST_FOREACH_PROP_ELEM(n, interrupt_names, \ - PL011_IRQ_CONFIG_FUNC_BODY) \ - }; \ - \ - static struct pl011_config pl011_cfg_sbsa_##n = { \ - DEVICE_MMIO_ROM_INIT(DT_DRV_INST(n)), \ - .irq_config_func = pl011_irq_config_func_sbsa_##n, \ +#define PL011_SBSA_CONFIG_PORT(n) \ + IF_ENABLED(PL011_NODE_USE_IRQ(n), ( \ + static void pl011_irq_config_func_sbsa_##n(const struct device *dev) \ + { \ + DT_INST_FOREACH_PROP_ELEM(n, interrupt_names, PL011_IRQ_CONFIG_FUNC_BODY) \ + }; \ + )) \ + \ + static struct pl011_config pl011_cfg_sbsa_##n = { \ + DEVICE_MMIO_ROM_INIT(DT_DRV_INST(n)), \ + IRQ_CONFIG_FUNC_INIT(n) \ }; -#else -#define PL011_SBSA_CONFIG_PORT(n) \ - static struct pl011_config pl011_cfg_sbsa_##n = { \ - DEVICE_MMIO_ROM_INIT(DT_DRV_INST(n)), \ - }; -#endif #define PL011_SBSA_INIT(n) \ PL011_SBSA_CONFIG_PORT(n) \ @@ -785,7 +803,7 @@ DT_INST_FOREACH_STATUS_OKAY(PL011_INIT) &pl011_cfg_sbsa_##n, \ PRE_KERNEL_1, \ CONFIG_SERIAL_INIT_PRIORITY, \ - &pl011_driver_api); + PL011_DEVICE_API(n)); DT_INST_FOREACH_STATUS_OKAY(PL011_SBSA_INIT) From 00fceded425411509e24ebb5cf89672a5592eaf6 Mon Sep 17 00:00:00 2001 From: Jonas Berg Date: Wed, 31 Dec 2025 19:39:29 +0100 Subject: [PATCH 2274/3659] dts: bindings: vendor-prefixes: Add longan Add vendor prefix for Longan Labs Signed-off-by: Jonas Berg --- dts/bindings/vendor-prefixes.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/dts/bindings/vendor-prefixes.txt b/dts/bindings/vendor-prefixes.txt index 428afc7ea6c1..73c1037dae11 100644 --- a/dts/bindings/vendor-prefixes.txt +++ b/dts/bindings/vendor-prefixes.txt @@ -401,6 +401,7 @@ litex LiteX SoC builder lltc Linear Technology Corporation logicpd Logic PD, Inc. logictechno Logic Technologies Limited +longan Longan Labs (Shenzhen Longan Technology Co., Ltd.) longcheer Longcheer Technology (Shanghai) Co., Ltd. lontium Lontium Semiconductor Corporation loongson Loongson Technology Corporation Limited From e35cb66069efce18d519a36a07e3f44c138f7991 Mon Sep 17 00:00:00 2001 From: Jonas Berg Date: Thu, 1 Jan 2026 02:06:26 +0100 Subject: [PATCH 2275/3659] boards: Add support for Longan Labs CANBed RP2040 Tested with the commands mentioned in index.rst Product photo from https://docs.longan-labs.cc/1030018/ Signed-off-by: Jonas Berg --- boards/longan/canbed_rp2040/Kconfig | 5 + .../canbed_rp2040/Kconfig.canbed_rp2040 | 5 + boards/longan/canbed_rp2040/Kconfig.defconfig | 16 ++ boards/longan/canbed_rp2040/board.cmake | 38 ++++ boards/longan/canbed_rp2040/board.yml | 6 + .../canbed_rp2040/canbed_rp2040-pinctrl.dtsi | 45 ++++ boards/longan/canbed_rp2040/canbed_rp2040.dts | 186 ++++++++++++++++ .../longan/canbed_rp2040/canbed_rp2040.yaml | 23 ++ .../canbed_rp2040/canbed_rp2040_defconfig | 13 ++ .../canbed_rp2040/doc/img/canbed_rp2040.webp | Bin 0 -> 29796 bytes boards/longan/canbed_rp2040/doc/index.rst | 204 ++++++++++++++++++ .../longan/canbed_rp2040/support/openocd.cfg | 11 + boards/longan/index.rst | 10 + 13 files changed, 562 insertions(+) create mode 100644 boards/longan/canbed_rp2040/Kconfig create mode 100644 boards/longan/canbed_rp2040/Kconfig.canbed_rp2040 create mode 100644 boards/longan/canbed_rp2040/Kconfig.defconfig create mode 100644 boards/longan/canbed_rp2040/board.cmake create mode 100644 boards/longan/canbed_rp2040/board.yml create mode 100644 boards/longan/canbed_rp2040/canbed_rp2040-pinctrl.dtsi create mode 100644 boards/longan/canbed_rp2040/canbed_rp2040.dts create mode 100644 boards/longan/canbed_rp2040/canbed_rp2040.yaml create mode 100644 boards/longan/canbed_rp2040/canbed_rp2040_defconfig create mode 100644 boards/longan/canbed_rp2040/doc/img/canbed_rp2040.webp create mode 100644 boards/longan/canbed_rp2040/doc/index.rst create mode 100644 boards/longan/canbed_rp2040/support/openocd.cfg create mode 100644 boards/longan/index.rst diff --git a/boards/longan/canbed_rp2040/Kconfig b/boards/longan/canbed_rp2040/Kconfig new file mode 100644 index 000000000000..7db1ea7cad5b --- /dev/null +++ b/boards/longan/canbed_rp2040/Kconfig @@ -0,0 +1,5 @@ +# Copyright (c) 2026 Jonas Berg +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_CANBED_RP2040 + select RP2_FLASH_W25Q080 diff --git a/boards/longan/canbed_rp2040/Kconfig.canbed_rp2040 b/boards/longan/canbed_rp2040/Kconfig.canbed_rp2040 new file mode 100644 index 000000000000..32f65253dcb5 --- /dev/null +++ b/boards/longan/canbed_rp2040/Kconfig.canbed_rp2040 @@ -0,0 +1,5 @@ +# Copyright (c) 2026 Jonas Berg +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_CANBED_RP2040 + select SOC_RP2040 diff --git a/boards/longan/canbed_rp2040/Kconfig.defconfig b/boards/longan/canbed_rp2040/Kconfig.defconfig new file mode 100644 index 000000000000..eb01bfdbc5d4 --- /dev/null +++ b/boards/longan/canbed_rp2040/Kconfig.defconfig @@ -0,0 +1,16 @@ +# Copyright (c) 2022 Peter Johanson +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_CANBED_RP2040 + +if I2C_DW + +config I2C_DW_CLOCK_SPEED + default 125 + +endif # I2C_DW + +config USB_SELF_POWERED + default n + +endif # BOARD_CANBED_RP2040 diff --git a/boards/longan/canbed_rp2040/board.cmake b/boards/longan/canbed_rp2040/board.cmake new file mode 100644 index 000000000000..5a702fc5e030 --- /dev/null +++ b/boards/longan/canbed_rp2040/board.cmake @@ -0,0 +1,38 @@ +# SPDX-License-Identifier: Apache-2.0 +# Adapted from boards/raspberrypi/rpi_pico/board.cmake + +# This configuration allows selecting what debug adapter debugging rpi_pico +# by a command-line argument. +# It is mainly intended to support both the 'picoprobe' and 'raspberrypi-swd' +# adapter described in "Getting started with Raspberry Pi Pico". +# And any other SWD debug adapter might also be usable with this configuration. + +# Set RPI_PICO_DEBUG_ADAPTER to select debug adapter by command-line arguments. +# e.g.) west build -b rpi_pico -- -DRPI_PICO_DEBUG_ADAPTER=raspberrypi-swd +# The value is treated as a part of an interface file name that +# the debugger's configuration file. +# The value must be the 'stem' part of the name of one of the files +# in the openocd interface configuration file. +# The setting is store to CMakeCache.txt. +if("${RPI_PICO_DEBUG_ADAPTER}" STREQUAL "") + set(RPI_PICO_DEBUG_ADAPTER "cmsis-dap") +endif() + +board_runner_args(openocd --cmd-pre-init "source [find interface/${RPI_PICO_DEBUG_ADAPTER}.cfg]") +board_runner_args(openocd --cmd-pre-init "transport select swd") +board_runner_args(openocd --cmd-pre-init "source [find target/rp2040.cfg]") + +# The adapter speed is expected to be set by interface configuration. +# But if not so, set 2000 to adapter speed. +board_runner_args(openocd --cmd-pre-init "set_adapter_speed_if_not_set 2000") + +board_runner_args(jlink "--device=RP2040_M0_0") +board_runner_args(uf2 "--board-id=RPI-RP2") +board_runner_args(pyocd "--target=rp2040") + +# Default runner should be listed first +include(${ZEPHYR_BASE}/boards/common/uf2.board.cmake) +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) +include(${ZEPHYR_BASE}/boards/common/blackmagicprobe.board.cmake) +include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake) diff --git a/boards/longan/canbed_rp2040/board.yml b/boards/longan/canbed_rp2040/board.yml new file mode 100644 index 000000000000..39fbbffeae26 --- /dev/null +++ b/boards/longan/canbed_rp2040/board.yml @@ -0,0 +1,6 @@ +board: + name: canbed_rp2040 + full_name: CANBed RP2040 + vendor: longan + socs: + - name: rp2040 diff --git a/boards/longan/canbed_rp2040/canbed_rp2040-pinctrl.dtsi b/boards/longan/canbed_rp2040/canbed_rp2040-pinctrl.dtsi new file mode 100644 index 000000000000..ef7f3fe06f53 --- /dev/null +++ b/boards/longan/canbed_rp2040/canbed_rp2040-pinctrl.dtsi @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2026 Jonas Berg + * + * 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; + }; + }; + + spi0_default: spi0_default { + group1 { + pinmux = , ; + }; + + group2 { + pinmux = ; + input-enable; + }; + }; + + adc_default: adc_default { + group1 { + pinmux = , , , ; + input-enable; + }; + }; +}; diff --git a/boards/longan/canbed_rp2040/canbed_rp2040.dts b/boards/longan/canbed_rp2040/canbed_rp2040.dts new file mode 100644 index 000000000000..f8df42b8f004 --- /dev/null +++ b/boards/longan/canbed_rp2040/canbed_rp2040.dts @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2021 Yonatan Schachter + * Copyright (c) 2022 Peter Johanson + * Copyright (c) 2026 Jonas Berg + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include +#include +#include "canbed_rp2040-pinctrl.dtsi" + +/ { + model = "Longan Labs CANBed RP2040"; + compatible = "longan,canbed_rp2040"; + + chosen { + zephyr,sram = &sram0; + zephyr,flash = &flash0; + zephyr,flash-controller = &ssi; + zephyr,console = &uart0; + zephyr,shell-uart = &uart0; + zephyr,code-partition = &code_partition; + zephyr,canbus = &mcp2515; + }; + + aliases { + watchdog0 = &wdt0; + led0 = &blue_led; + }; + + zephyr,user { + io-channels = <&adc 0>, <&adc 1>, <&adc 2>, <&adc 3>; + }; + + leds: leds { + compatible = "gpio-leds"; + + blue_led: blue_led { + gpios = <&gpio0 18 GPIO_ACTIVE_HIGH>; + label = "Blue LED"; + }; + }; + + stemma_connector: stemma_connector { + compatible = "stemma-qt-connector"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <0 0 &gpio0 7 0>, /* SCL */ + <1 0 &gpio0 6 0>; /* SDA */ + }; +}; + +&flash0 { + reg = <0x10000000 DT_SIZE_M(2)>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + /* Reserved memory for the second stage bootloader */ + second_stage_bootloader: partition@0 { + label = "second_stage_bootloader"; + reg = <0x00000000 0x100>; + read-only; + }; + + /* + * Usable flash. Starts at 0x100, after the bootloader. The partition + * size is 2 MB minus the 0x100 bytes taken by the bootloader. + */ + code_partition: partition@100 { + label = "code-partition"; + reg = <0x100 (DT_SIZE_M(2) - 0x100)>; + read-only; + }; + }; +}; + +&gpio0 { + status = "okay"; +}; + +&uart0 { + current-speed = <115200>; + status = "okay"; + pinctrl-0 = <&uart0_default>; + pinctrl-names = "default"; +}; + +zephyr_i2c: &i2c1 { + status = "okay"; + pinctrl-0 = <&i2c1_default>; + pinctrl-names = "default"; + clock-frequency = ; +}; + +&spi0 { + pinctrl-0 = <&spi0_default>; + pinctrl-names = "default"; + status = "okay"; + cs-gpios = <&gpio0 9 GPIO_ACTIVE_LOW>; + + mcp2515: mcp2515@0 { + compatible = "microchip,mcp2515"; + spi-max-frequency = <1000000>; + int-gpios = <&gpio0 11 GPIO_ACTIVE_LOW>; + status = "okay"; + reg = <0x0>; + osc-freq = <16000000>; + + can-transceiver { + max-bitrate = <1000000>; + }; + }; +}; + +&timer { + status = "okay"; +}; + +&wdt0 { + status = "okay"; +}; + +&adc { + status = "okay"; + pinctrl-0 = <&adc_default>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + + channel@0 { + reg = <0>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; + + channel@1 { + reg = <1>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; + + channel@2 { + reg = <2>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; + + channel@3 { + reg = <3>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; +}; + +zephyr_udc0: &usbd { + status = "okay"; +}; + +&die_temp { + status = "okay"; +}; + +&vreg { + regulator-always-on; + regulator-allowed-modes = ; +}; + +&xosc { + startup-delay-multiplier = <64>; +}; diff --git a/boards/longan/canbed_rp2040/canbed_rp2040.yaml b/boards/longan/canbed_rp2040/canbed_rp2040.yaml new file mode 100644 index 000000000000..88388dfcb7f2 --- /dev/null +++ b/boards/longan/canbed_rp2040/canbed_rp2040.yaml @@ -0,0 +1,23 @@ +identifier: canbed_rp2040 +name: Longan Labs CANBed RP2040 +type: mcu +arch: arm +flash: 2048 +ram: 264 +toolchain: + - zephyr + - gnuarmemb +supported: + - adc + - can + - clock + - counter + - dma + - flash + - gpio + - hwinfo + - i2c + - pwm + - spi + - uart + - watchdog diff --git a/boards/longan/canbed_rp2040/canbed_rp2040_defconfig b/boards/longan/canbed_rp2040/canbed_rp2040_defconfig new file mode 100644 index 000000000000..85b60ee95c5a --- /dev/null +++ b/boards/longan/canbed_rp2040/canbed_rp2040_defconfig @@ -0,0 +1,13 @@ +# Copyright (c) 2026 Jonas Berg +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_BUILD_OUTPUT_HEX=y +CONFIG_BUILD_OUTPUT_UF2=y +CONFIG_CLOCK_CONTROL=y +CONFIG_CONSOLE=y +CONFIG_GPIO=y +CONFIG_RESET=y +CONFIG_SERIAL=y +CONFIG_UART_CONSOLE=y +CONFIG_UART_INTERRUPT_DRIVEN=y +CONFIG_USE_DT_CODE_PARTITION=y diff --git a/boards/longan/canbed_rp2040/doc/img/canbed_rp2040.webp b/boards/longan/canbed_rp2040/doc/img/canbed_rp2040.webp new file mode 100644 index 0000000000000000000000000000000000000000..2acc3dd0828f91481881071a5caee9437b8c063d GIT binary patch literal 29796 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 P000000000000000f-=*o literal 0 HcmV?d00001 diff --git a/boards/longan/canbed_rp2040/doc/index.rst b/boards/longan/canbed_rp2040/doc/index.rst new file mode 100644 index 000000000000..ae984a2d5fa4 --- /dev/null +++ b/boards/longan/canbed_rp2040/doc/index.rst @@ -0,0 +1,204 @@ +.. zephyr:board:: canbed_rp2040 + +Overview +******** + +The `Longan Labs CANBed RP2040`_ board is based on the RP2040 microcontroller from Raspberry Pi Ltd. +The board has a CAN bus controller and an I2C connector for easy sensor usage. +It has a micro USB connector. + + +Hardware +******** + +- Microcontroller Raspberry Pi RP2040, with a max frequency of 133 MHz +- Dual ARM Cortex M0+ cores +- 264 kByte SRAM +- 2 Mbyte QSPI flash +- 13 GPIO pins +- 4 ADC pins +- I2C +- SPI +- UART +- Micro USB connector +- Reset and boot buttons +- Blue user LED +- Grove I2C connector, compatible with Qwiic/Stemma QT if using adapter cable +- Grove UART connector +- CAN bus controller MCP2515 +- CAN bus transceiver SN65HVD230 + + +Default Zephyr Peripheral Mapping +================================= + ++-------+--------+-----------------+ +| Label | Pin | Default pin mux | ++=======+========+=================+ +| LED | GPIO18 | | ++-------+--------+-----------------+ + + +Main header (sorted according to schematic pin numbering): + ++-------+--------+-----------------+-------------------+ +| Label | Pin | Default pin mux | Also in connector | ++=======+========+=================+===================+ +| GND | | | | ++-------+--------+-----------------+-------------------+ +| 24 | GPIO24 | | | ++-------+--------+-----------------+-------------------+ +| 23 | GPIO23 | | | ++-------+--------+-----------------+-------------------+ +| 22 | GPIO22 | | | ++-------+--------+-----------------+-------------------+ +| 21 | GPIO21 | | | ++-------+--------+-----------------+-------------------+ +| SCL | GPIO7 | I2C1 SCL | I2C connector | ++-------+--------+-----------------+-------------------+ +| SDA | GPIO6 | I2C1 SDA | I2C connector | ++-------+--------+-----------------+-------------------+ +| TX | GPIO0 | UART0 TX | UART connector | ++-------+--------+-----------------+-------------------+ +| RX | GPIO1 | UART0 RX | UART connector | ++-------+--------+-----------------+-------------------+ +| 10 | GPIO10 | | | ++-------+--------+-----------------+-------------------+ +| 19 | GPIO19 | | | ++-------+--------+-----------------+-------------------+ +| 20 | GPIO20 | | | ++-------+--------+-----------------+-------------------+ +| A3 | GPIO29 | ADC3 | | ++-------+--------+-----------------+-------------------+ +| 25 | GPIO25 | | | ++-------+--------+-----------------+-------------------+ +| A0 | GPIO26 | ADC0 | | ++-------+--------+-----------------+-------------------+ +| A1 | GPIO27 | ADC1 | | ++-------+--------+-----------------+-------------------+ +| A2 | GPIO28 | ADC2 | | ++-------+--------+-----------------+-------------------+ +| 3V3 | | | | ++-------+--------+-----------------+-------------------+ + + +Grove I2C connector (pins also available in the main header): + ++-------+--------+-----------------+ +| Label | Pin | Default pin mux | ++=======+========+=================+ +| SCL | GPIO7 | I2C1 SCL | ++-------+--------+-----------------+ +| SDA | GPIO6 | I2C1 SDA | ++-------+--------+-----------------+ +| 3V3 | | | ++-------+--------+-----------------+ +| GND | | | ++-------+--------+-----------------+ + + +Grove UART connector (pins also available in the main header): + ++-------+--------+-----------------+ +| Label | Pin | Default pin mux | ++=======+========+=================+ +| RX | GPIO1 | UART0 RX | ++-------+--------+-----------------+ +| TX | GPIO0 | UART0 TX | ++-------+--------+-----------------+ +| 3V3 | | | ++-------+--------+-----------------+ +| GND | | | ++-------+--------+-----------------+ + + +SPI header: + ++-------+--------+-----------------+ +| Label | Pin | Default pin mux | ++=======+========+=================+ +| MISO | GPIO4 | SPI0 MISO | ++-------+--------+-----------------+ +| SCK | GPIO2 | SPI0 SCK | ++-------+--------+-----------------+ +| 8 | GPIO8 | | ++-------+--------+-----------------+ +| GND | | | ++-------+--------+-----------------+ +| MOSI | GPIO3 | SPI0 MOSI | ++-------+--------+-----------------+ +| 3V3 | | | ++-------+--------+-----------------+ + + +CAN controller: + ++-------+--------+-----------------+ +| Label | Pin | Default pin mux | ++=======+========+=================+ +| CANCS | GPIO9 | | ++-------+--------+-----------------+ +| INT | GPIO11 | | ++-------+--------+-----------------+ + +The CAN controller is also connected to the SPI0 pins SCK, MOSI and MISO (see above). + +See also `pinout`_. + + +Supported Features +================== + +.. zephyr:board-supported-hw:: + + +Programming and Debugging +************************* + +.. zephyr:board-supported-runners:: + +By default programming is done via the USB connector. Press and hold the BOOT button, and then +press the RST button, and the device will appear as a USB mass storage unit. +Building your application will result in a :file:`build/zephyr/zephyr.uf2` file. +Drag and drop the file to the USB mass storage unit, and the board will be reprogrammed. + +It is also possible to program and debug the board via the SWDIO and SWCLK pins. +Then a separate programming hardware tool is required, and for example the :command:`openocd` +software is used. Typically the ``OPENOCD`` and ``OPENOCD_DEFAULT_PATH`` values should be set +when building, and the ``--runner openocd`` argument should be used when flashing. +For more details on programming RP2040-based boards, see :ref:`rpi_pico_programming_and_debugging`. + + +Flashing +======== + +To run the :zephyr:code-sample:`blinky` sample: + +.. zephyr-app-commands:: + :zephyr-app: samples/basic/blinky/ + :board: canbed_rp2040 + :goals: build flash + +Try also the :zephyr:code-sample:`hello_world`, :zephyr:code-sample:`adc_dt` +and :zephyr:code-sample:`can-counter` samples. + +The use of the Grove/Qwiic/Stemma QT I2C connector is demonstrated using the +:zephyr:code-sample:`light_sensor_polling` sample and a separate shield: + +.. zephyr-app-commands:: + :zephyr-app: samples/sensor/light_polling + :board: canbed_rp2040 + :shield: adafruit_veml7700 + :goals: build flash + + +References +********** + +.. target-notes:: + +.. _Longan Labs CANBed RP2040: + https://docs.longan-labs.cc/1030018/ + +.. _pinout: + https://www.longan-labs.cc/media/wysiwyg/CAN-Bus/CANBed/Details_of_CANBed-04.png diff --git a/boards/longan/canbed_rp2040/support/openocd.cfg b/boards/longan/canbed_rp2040/support/openocd.cfg new file mode 100644 index 000000000000..34ab592b1861 --- /dev/null +++ b/boards/longan/canbed_rp2040/support/openocd.cfg @@ -0,0 +1,11 @@ +# Copyright (c) 2022 Tokita, Hiroshi +# SPDX-License-Identifier: Apache-2.0 + +# Checking and set 'adapter speed'. +# Set the adaptor speed, if unset, and given as an argument. +proc set_adapter_speed_if_not_set { speed } { + puts "checking adapter speed..." + if { [catch {adapter speed} ret] } { + adapter speed $speed + } +} diff --git a/boards/longan/index.rst b/boards/longan/index.rst new file mode 100644 index 000000000000..926738b7bc78 --- /dev/null +++ b/boards/longan/index.rst @@ -0,0 +1,10 @@ +.. _boards-longan: + +Longan Labs +########### + +.. toctree:: + :maxdepth: 1 + :glob: + + **/* From e28b3b04cee57ceb3ce921b111e4e367cfde06c5 Mon Sep 17 00:00:00 2001 From: Pisit Sawangvonganan Date: Wed, 31 Dec 2025 00:23:35 +0700 Subject: [PATCH 2276/3659] drivers: spi_nxp_lpspi: simplify `lpspi_rx_buf_write_words` Refactor `lpspi_rx_buf_write_words()` to compute `words_read` upfront using `MIN(rx_len, max_read)`, simplifying control flow and making the read limit explicit without changing behavior. Signed-off-by: Pisit Sawangvonganan --- drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi.c b/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi.c index 0a52aad9ae3c..1fc8f703cafa 100644 --- a/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi.c +++ b/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi.c @@ -45,14 +45,12 @@ static inline size_t lpspi_rx_buf_write_words(const struct device *dev, uint8_t struct lpspi_data *data = dev->data; struct lpspi_driver_data *lpspi_data = (struct lpspi_driver_data *)data->driver_data; struct spi_context *ctx = &data->ctx; - size_t buf_len = ctx->rx_len; - uint8_t words_read = 0; + size_t words_read = MIN(ctx->rx_len, (size_t)max_read); size_t offset = 0; - while (buf_len-- > 0 && max_read-- > 0) { + for (size_t i = 0; i < words_read; i++) { lpspi_rx_word_write_bytes(dev, offset); offset += lpspi_data->word_size_bytes; - words_read++; } return words_read; From ec2b92c1e6d11691afc2d2e3ccc8e6cbce102e67 Mon Sep 17 00:00:00 2001 From: Pisit Sawangvonganan Date: Wed, 31 Dec 2025 15:48:27 +0700 Subject: [PATCH 2277/3659] drivers: spi_nxp_lpspi: prevent null pointer dereference The condition `!spi_context_rx_buf_on(ctx) && spi_context_rx_on(ctx)` only returns early when RX is active with a NOP buffer. However, when `rx_len == 0`, `spi_context_rx_on(ctx)` returns false, causing the early return to be skipped. This leaves `ctx->rx_buf` (which can be NULL) to be dereferenced. Since `lpspi_handle_rx_irq()` already guarantees `spi_context_rx_on(ctx)` is true before calling this function, only check `!spi_context_rx_buf_on(ctx)` to safely handle NOP buffers. Signed-off-by: Pisit Sawangvonganan --- drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi.c b/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi.c index 1fc8f703cafa..2ba7c84d727f 100644 --- a/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi.c +++ b/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi.c @@ -29,7 +29,7 @@ static inline void lpspi_rx_word_write_bytes(const struct device *dev, size_t of uint8_t *buf = ctx->rx_buf + offset; uint32_t word = base->RDR; - if (!spi_context_rx_buf_on(ctx) && spi_context_rx_on(ctx)) { + if (!spi_context_rx_buf_on(ctx)) { /* receive no actual data if rx buf is NULL */ return; } From 9a8acec8204111d01d831dbcf28de597fd902822 Mon Sep 17 00:00:00 2001 From: Yongxu Wang Date: Tue, 23 Dec 2025 09:32:36 +0800 Subject: [PATCH 2278/3659] drivers: i2c: mcux_lpi2c: add PM device support Add PM device support for the LPI2C peripheral. Implement PM device callback to gate and ungate the device clock during suspend and resume. No attach register save and restore as it's preserved by hardware Signed-off-by: Yongxu Wang --- drivers/i2c/i2c_mcux_lpi2c.c | 61 ++++++++++++++++++++++++++++++++++-- 1 file changed, 58 insertions(+), 3 deletions(-) diff --git a/drivers/i2c/i2c_mcux_lpi2c.c b/drivers/i2c/i2c_mcux_lpi2c.c index 81af8e2adc15..aeb7e718e13c 100644 --- a/drivers/i2c/i2c_mcux_lpi2c.c +++ b/drivers/i2c/i2c_mcux_lpi2c.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2016 Freescale Semiconductor, Inc. - * Copyright 2019-2023, NXP + * Copyright 2019-2026, NXP * Copyright (c) 2022 Vestas Wind Systems A/S * * SPDX-License-Identifier: Apache-2.0 @@ -13,6 +13,8 @@ #include #include #include +#include +#include #include #if CONFIG_NXP_LP_FLEXCOMM #include @@ -161,6 +163,8 @@ static int mcux_lpi2c_transfer(const struct device *dev, struct i2c_msg *msgs, return ret; } + (void)pm_device_runtime_get(dev); + /* Iterate over all the messages */ for (int i = 0; i < num_msgs; i++) { if (I2C_MSG_ADDR_10_BITS & msgs->flags) { @@ -222,6 +226,8 @@ static int mcux_lpi2c_transfer(const struct device *dev, struct i2c_msg *msgs, msgs++; } + (void)pm_device_runtime_put(dev); + k_sem_give(&data->lock); return ret; @@ -492,6 +498,52 @@ static void mcux_lpi2c_isr(const struct device *dev) LPI2C_MasterTransferHandleIRQ(LPI2C_IRQHANDLE_ARG, &data->handle); } +static int mcux_lpi2c_suspend(const struct device *dev) +{ + int ret; + const struct mcux_lpi2c_config *config = dev->config; + + ret = clock_control_off(config->clock_dev, config->clock_subsys); + if (ret < 0) { + LOG_ERR("failed clock off lpi2c"); + return ret; + } + + return 0; +} + +static int mcux_lpi2c_resume(const struct device *dev) +{ + int ret; + const struct mcux_lpi2c_config *config = dev->config; + + ret = clock_control_on(config->clock_dev, config->clock_subsys); + if (ret < 0) { + LOG_ERR("failed clock on lpi2c"); + return ret; + } + + return 0; +} + +static int mcux_lpi2c_pm_action(const struct device *dev, enum pm_device_action action) +{ + int ret; + + switch (action) { + case PM_DEVICE_ACTION_RESUME: + ret = mcux_lpi2c_resume(dev); + break; + case PM_DEVICE_ACTION_SUSPEND: + ret = mcux_lpi2c_suspend(dev); + break; + default: + return -ENOTSUP; + } + + return ret; +} + static int mcux_lpi2c_init(const struct device *dev) { const struct mcux_lpi2c_config *config = dev->config; @@ -539,7 +591,7 @@ static int mcux_lpi2c_init(const struct device *dev) config->irq_config_func(dev); - return 0; + return pm_device_driver_init(dev, mcux_lpi2c_pm_action); } static DEVICE_API(i2c, mcux_lpi2c_driver_api) = { @@ -612,7 +664,10 @@ static DEVICE_API(i2c, mcux_lpi2c_driver_api) = { \ static struct mcux_lpi2c_data mcux_lpi2c_data_##n; \ \ - I2C_DEVICE_DT_INST_DEFINE(n, mcux_lpi2c_init, NULL, \ + PM_DEVICE_DT_INST_DEFINE(n, mcux_lpi2c_pm_action); \ + \ + I2C_DEVICE_DT_INST_DEFINE(n, mcux_lpi2c_init, \ + PM_DEVICE_DT_INST_GET(n), \ &mcux_lpi2c_data_##n, \ &mcux_lpi2c_config_##n, POST_KERNEL, \ CONFIG_I2C_INIT_PRIORITY, \ From 0296e2ee3b2d78f98edb9ed927bffbe9cd87e602 Mon Sep 17 00:00:00 2001 From: Yongxu Wang Date: Wed, 24 Dec 2025 15:18:16 +0800 Subject: [PATCH 2279/3659] dts: arm: nxp: imx943: enable runtime PM auto for LPI2C Enable automatic runtime power management for all LPI2C instances to support interrupt-driven when suspend and resume device by scmi firmware interface. On i.MX943 with System Manager firmware, clock operations require SCMI communication which needs interrupts. The system-managed PM approach locks interrupts during device suspend/resume, preventing SCMI from completing. Although lpi2c mcux driver have enabled pm runtime in driver init, set lpi2c auto runtime in dts to record this issue that only device runtime can be supported now. Signed-off-by: Yongxu Wang --- dts/arm/nxp/nxp_imx94x.dtsi | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/dts/arm/nxp/nxp_imx94x.dtsi b/dts/arm/nxp/nxp_imx94x.dtsi index 7bfc9b109e95..9d259596b771 100644 --- a/dts/arm/nxp/nxp_imx94x.dtsi +++ b/dts/arm/nxp/nxp_imx94x.dtsi @@ -119,6 +119,7 @@ reg = <0x42530000 0x4000>; interrupts = <67 0>; clocks = <&scmi_clk IMX943_CLK_LPI2C3>; + zephyr,pm-device-runtime-auto; status = "disabled"; }; @@ -130,6 +131,7 @@ reg = <0x42540000 0x4000>; interrupts = <68 0>; clocks = <&scmi_clk IMX943_CLK_LPI2C4>; + zephyr,pm-device-runtime-auto; status = "disabled"; }; @@ -207,6 +209,7 @@ reg = <0x426b0000 0x4000>; interrupts = <108 0>; clocks = <&scmi_clk IMX943_CLK_LPI2C5>; + zephyr,pm-device-runtime-auto; status = "disabled"; }; @@ -218,6 +221,7 @@ reg = <0x426c0000 0x4000>; interrupts = <109 0>; clocks = <&scmi_clk IMX943_CLK_LPI2C6>; + zephyr,pm-device-runtime-auto; status = "disabled"; }; @@ -229,6 +233,7 @@ reg = <0x426d0000 0x4000>; interrupts = <110 0>; clocks = <&scmi_clk IMX943_CLK_LPI2C7>; + zephyr,pm-device-runtime-auto; status = "disabled"; }; @@ -240,6 +245,7 @@ reg = <0x426e0000 0x4000>; interrupts = <111 0>; clocks = <&scmi_clk IMX943_CLK_LPI2C8>; + zephyr,pm-device-runtime-auto; status = "disabled"; }; @@ -502,6 +508,7 @@ reg = <0x44340000 0x4000>; interrupts = <15 0>; clocks = <&scmi_clk IMX943_CLK_LPI2C1>; + zephyr,pm-device-runtime-auto; status = "disabled"; }; @@ -513,6 +520,7 @@ reg = <0x44350000 0x4000>; interrupts = <16 0>; clocks = <&scmi_clk IMX943_CLK_LPI2C2>; + zephyr,pm-device-runtime-auto; status = "disabled"; }; From e1257bf845d087dff7a7ee6596b712c184652ea8 Mon Sep 17 00:00:00 2001 From: Ali Hozhabri Date: Fri, 19 Dec 2025 17:10:41 +0100 Subject: [PATCH 2280/3659] drivers: entropy: Fix STM32WB07/STM32WB05 init issue Change the initialization priority. According to the documentation, kernel services should not be used during device configuration with PRE_KERNEL_1. In "entropy_stm32_rng_init", there is "start_pool_filling" which calls "k_work_schedule". Moreover, "k_work_schedule" requires system timer which is initialized within PRE_KERNEL_2. Therefore, the SoC gets stuck. Signed-off-by: Ali Hozhabri --- drivers/entropy/entropy_stm32.c | 2 +- drivers/entropy/entropy_stm32.h | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/entropy/entropy_stm32.c b/drivers/entropy/entropy_stm32.c index 01fb26bf6e13..36b6eb0877ff 100644 --- a/drivers/entropy/entropy_stm32.c +++ b/drivers/entropy/entropy_stm32.c @@ -951,5 +951,5 @@ DEVICE_DT_INST_DEFINE(0, entropy_stm32_rng_init, PM_DEVICE_DT_INST_GET(0), &entropy_stm32_rng_data, &entropy_stm32_rng_config, - PRE_KERNEL_1, CONFIG_ENTROPY_INIT_PRIORITY, + STM32_TRNG_INIT_LEVEL, CONFIG_ENTROPY_INIT_PRIORITY, &entropy_stm32_rng_api); diff --git a/drivers/entropy/entropy_stm32.h b/drivers/entropy/entropy_stm32.h index 5fe4d393bfa9..6ac194aa0892 100644 --- a/drivers/entropy/entropy_stm32.h +++ b/drivers/entropy/entropy_stm32.h @@ -18,10 +18,18 @@ #if IRQLESS_TRNG #define DT_DRV_COMPAT st_stm32_rng_noirq #define TRNG_GENERATION_DELAY K_NSEC(DT_INST_PROP_OR(0, generation_delay_ns, 0)) + +/* In IRQ-less hardware, the system workqueue is used to poll the TRNG + * during driver initialization. Since the workqueue service is not available + * in PRE_KERNEL_1/PRE_KERNEL_2, the init routine must run at POST_KERNEL. + */ +#define STM32_TRNG_INIT_LEVEL POST_KERNEL + #else /* !IRQLESS_TRNG */ #define DT_DRV_COMPAT st_stm32_rng #define IRQN DT_INST_IRQN(0) #define IRQ_PRIO DT_INST_IRQ(0, priority) +#define STM32_TRNG_INIT_LEVEL PRE_KERNEL_1 #endif /* IRQLESS_TRNG */ /* Cross-series LL compatibility wrappers */ From a32b5cfe342231fa6b12f3df61f651f291626fd6 Mon Sep 17 00:00:00 2001 From: Ali Hozhabri Date: Mon, 22 Dec 2025 11:23:42 +0100 Subject: [PATCH 2281/3659] drivers: timer: Fix radio timer issue on STM32WB07/STM32WB05 Due to the hardware limitation, the time between the CPU wake-up IRQ fire (IRQ 23) and the next call of LL_RADIO_TIMER_SetCPUWakeupTime should not be less than 16 MTU (Machine Time Unit), i.e. approximately 30us. otherwise, the next CPU wake-up doesn't happen unless the timer wraps. Lock IRQs while sys_clock_set_timeout is being executed. Remove HAL_RADIO_TIMER_WakeUpCallback and it will be implemented differently in the future. Remove HAL_RADIO_TIMER_TimeoutCallback as it is not needed anymore. Signed-off-by: Ali Hozhabri --- drivers/timer/stm32wb0_radio_timer.c | 38 +++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/drivers/timer/stm32wb0_radio_timer.c b/drivers/timer/stm32wb0_radio_timer.c index 8508c1c53bfb..1672c5e3e6bb 100644 --- a/drivers/timer/stm32wb0_radio_timer.c +++ b/drivers/timer/stm32wb0_radio_timer.c @@ -45,6 +45,7 @@ static const uint32_t calibration_data_freq1 = 0x0028F5C2; uint32_t blue_unit_conversion(uint32_t time, uint32_t period_freq, uint32_t thr); static uint64_t announced_cycles; +static uint32_t last_cpu_wakeup_time; static void radio_timer_error_isr(void *args) { @@ -69,7 +70,16 @@ static void radio_timer_cpu_wkup_isr(void *args) ARG_UNUSED(args); - HAL_RADIO_TIMER_TimeoutCallback(); + last_cpu_wakeup_time = LL_RADIO_TIMER_GetAbsoluteTime(WAKEUP); + + /* Clear the interrupt */ + LL_RADIO_TIMER_ClearFlag_CPUWakeup(WAKEUP); + + /* Read back the register to ensure that the previous + * write operation is completed. + */ + LL_RADIO_TIMER_IsActiveFlag_CPUWakeup(WAKEUP); + if (IS_ENABLED(CONFIG_TICKLESS_KERNEL)) { diff_cycles = HAL_RADIO_TIMER_GetCurrentSysTime() - announced_cycles; dticks = (int32_t)k_cyc_to_ticks_near64(diff_cycles); @@ -85,7 +95,17 @@ static void radio_timer_txrx_wkup_isr(void *args) { ARG_UNUSED(args); - HAL_RADIO_TIMER_WakeUpCallback(); + /* The callback body will be properly implemented in the future + * while providing PM support for WB06/WB07. + */ + + /* Clear the interrupt */ + LL_RADIO_TIMER_ClearFlag_BLEWakeup(WAKEUP); + + /* Read back the register to ensure that the previous + * write operation is completed. + */ + LL_RADIO_TIMER_IsActiveFlag_BLEWakeup(WAKEUP); } #endif /* CONFIG_SOC_STM32WB06XX || CONFIG_SOC_STM32WB07XX */ @@ -99,6 +119,7 @@ void sys_clock_set_timeout(int32_t ticks, bool idle) if (IS_ENABLED(CONFIG_TICKLESS_KERNEL)) { uint32_t current_time, delay; + uint32_t key; ticks = MAX(1, ticks); delay = blue_unit_conversion(k_ticks_to_cyc_near32(ticks), calibration_data_freq1, @@ -108,9 +129,20 @@ void sys_clock_set_timeout(int32_t ticks, bool idle) } else { delay = MAX(MIN_ALLOWED_DELAY, delay); } - current_time = LL_RADIO_TIMER_GetAbsoluteTime(WAKEUP); + key = irq_lock(); + + /* Due to a hardware limitation, the radio timer wake-up time + * must not be updated until at least 16 Machine Time Units + * have elapsed since the interrupt was triggered; otherwise, + * the next wake-up will only occur after the timer wraps around. + */ + do { + current_time = LL_RADIO_TIMER_GetAbsoluteTime(WAKEUP); + } while ((current_time - last_cpu_wakeup_time) < 16U); + LL_RADIO_TIMER_SetCPUWakeupTime(WAKEUP, current_time + delay + TIMER_ROUNDING); LL_RADIO_TIMER_EnableCPUWakeupTimer(WAKEUP); + irq_unlock(key); } } From 2bc754e5818f2c15fd850d971c12cd5f3aaadfdb Mon Sep 17 00:00:00 2001 From: Ali Hozhabri Date: Mon, 22 Dec 2025 11:33:04 +0100 Subject: [PATCH 2282/3659] drivers: timer: Fix a typo in the STM32WB07 radio timer Replace one extra CONFIG_SOC_STM32WB06XX with the CONFIG_SOC_STM32WB07XX. Signed-off-by: Ali Hozhabri --- drivers/timer/stm32wb0_radio_timer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/timer/stm32wb0_radio_timer.c b/drivers/timer/stm32wb0_radio_timer.c index 1672c5e3e6bb..702a029912b1 100644 --- a/drivers/timer/stm32wb0_radio_timer.c +++ b/drivers/timer/stm32wb0_radio_timer.c @@ -32,7 +32,7 @@ LOG_MODULE_REGISTER(radio_timer_driver); BUILD_ASSERT(DT_NODE_HAS_STATUS(DT_NODELABEL(clk_lsi), disabled), "LSI is not supported yet"); -#if (defined(CONFIG_SOC_STM32WB06XX) || defined(CONFIG_SOC_STM32WB06XX)) && defined(CONFIG_PM) +#if (defined(CONFIG_SOC_STM32WB06XX) || defined(CONFIG_SOC_STM32WB07XX)) && defined(CONFIG_PM) #error "PM is not supported yet for WB06/WB07" #endif /* (CONFIG_SOC_STM32WB06XX || CONFIG_SOC_STM32WB06XX) && CONFIG_PM */ From 03822df9a7215b0dea0edf659da83557841c1b50 Mon Sep 17 00:00:00 2001 From: Ali Hozhabri Date: Mon, 22 Dec 2025 16:54:46 +0100 Subject: [PATCH 2283/3659] west.yml: Update west to point to the recent changes for hal_stm32 Update west.yml to point to the recent changes for hal_stm32. Signed-off-by: Ali Hozhabri --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 54df2a7dc762..f3a744910910 100644 --- a/west.yml +++ b/west.yml @@ -255,7 +255,7 @@ manifest: groups: - hal - name: hal_stm32 - revision: ec0fe4a09a5bbf0e482ab1f4bd42d66131c64369 + revision: e05bb4707857ecf4344c29a9407aaa4227407546 path: modules/hal/stm32 groups: - hal From dc0360df2ce52a14eef3653e35f29d36154de528 Mon Sep 17 00:00:00 2001 From: Arunprasath P Date: Fri, 28 Nov 2025 09:56:28 +0530 Subject: [PATCH 2284/3659] dts: arm: microchip: Introduce dac g1 binding file and dts node Add the device tree node and the binding file for microchip DAC G1 Peripherals. Signed-off-by: Arunprasath P --- .../sam/sam_d5x_e5x/common/samd5xe5x.dtsi | 16 ++ dts/bindings/dac/microchip,dac-g1.yaml | 149 ++++++++++++++++++ 2 files changed, 165 insertions(+) create mode 100644 dts/bindings/dac/microchip,dac-g1.yaml diff --git a/dts/arm/microchip/sam/sam_d5x_e5x/common/samd5xe5x.dtsi b/dts/arm/microchip/sam/sam_d5x_e5x/common/samd5xe5x.dtsi index 9c3830c91ac5..7edd0b21b5a3 100644 --- a/dts/arm/microchip/sam/sam_d5x_e5x/common/samd5xe5x.dtsi +++ b/dts/arm/microchip/sam/sam_d5x_e5x/common/samd5xe5x.dtsi @@ -396,6 +396,22 @@ calib-mapping-names = "BIASCOMP", "BIASR2R", "BIASREFBUF"; status = "disabled"; }; + + dac: dac@43002400 { + compatible = "microchip,dac-g1"; + reg = <0x43002400 0x1e>; + interrupts = <123 0>, <124 0>, <125 0>, <126 0>, <127 0>; + interrupt-names = "overrun_underrun", + "empty0", + "empty1", + "resrdy0", + "resrdy1"; + #io-channel-cells = <1>; + clocks = <&mclkperiph CLOCK_MCHP_MCLKPERIPH_ID_APBD_DAC>, + <&gclkperiph CLOCK_MCHP_GCLKPERIPH_ID_DAC>; + clock-names = "mclk", "gclk"; + status = "disabled"; + }; }; }; diff --git a/dts/bindings/dac/microchip,dac-g1.yaml b/dts/bindings/dac/microchip,dac-g1.yaml new file mode 100644 index 000000000000..475293ec22c6 --- /dev/null +++ b/dts/bindings/dac/microchip,dac-g1.yaml @@ -0,0 +1,149 @@ +# Copyright (c) 2025-2026 Microchip Technology Inc. +# SPDX-License-Identifier: Apache-2.0 + +title: Microchip G1 DAC + +description: | + Microchip G1 DAC peripherals. + + Group G1 DAC includes the following hardware peripherals: + - module name="DAC" id="U2502" version="1.0.0" + +compatible: "microchip,dac-g1" + +include: + - name: dac-controller.yaml + - name: pinctrl-device.yaml + +properties: + reg: + required: true + + clocks: + required: true + + clock-names: + required: true + + "#io-channel-cells": + type: int + required: true + const: 1 + description: | + Number of cells needed to represent a channel. + + "#address-cells": + const: 1 + + "#size-cells": + const: 0 + + refsel: + type: string + required: true + enum: + - "vref_au" + - "vdd_ana" + - "vref_ab" + - "int_ref" + description: | + Reference Voltage selection. + + Must be one of: + - "vref_au" (0x0) - Unbuffered External Voltage Reference + - "vdd_ana" (0x1) - Voltage Supply + - "vref_ab" (0x2) - Buffered External Voltage Reference + - "int_ref" (0x3) - Internal Bandgap Reference + + max-channels: + type: int + default: 2 + description: | + Maximum number of channels + +child-binding: + description: | + Channel configuration. + All child nodes using this binding must be named "channel". + + properties: + reg: + type: int + required: true + description: | + DAC channel number. + + Allowed channel numbers are 0 to (max-channels - 1). + For example, if max-channels = 2, the allowed channels are 0 and 1. + + rate: + type: int + required: true + description: | + Conversion Speed in KSPS(Kilo Samples per second) + enum: + - 100 + - 500 + - 1000 + + ext-filter: + type: boolean + description: | + Enable External Filter + + data-adj: + type: string + default: right + enum: + - "right" + - "left" + description: | + Controls how the DAC value is aligned in the DATA register. + + "right" selects right alignment and "left" selects left alignment, + as controlled by the LEFTADJ bit. The default is "right", which + matches the hardware reset value of LEFTADJ = 0. + Right alignment places the LSB of the 12-bit value at bit 0 of DATA. + + dither-mode: + type: boolean + description: | + Enable the Dithering Mode + + sampling-ratio: + type: int + default: 1 + enum: + - 1 + - 2 + - 4 + - 8 + - 16 + - 32 + description: | + Set the Oversampling Ratio + + Setting oversampling disables the refresh rate. + + refresh-period: + type: int + default: 0 + description: | + Refresh Period in us ( 0 - Disabled ) + enum: + - 0 + - 30 + - 60 + - 90 + - 120 + - 150 + - 180 + - 210 + - 240 + - 270 + - 300 + - 330 + - 360 + - 390 + - 420 + - 450 From 74bafaf20ed9d061284ee25413a5833897bf798d Mon Sep 17 00:00:00 2001 From: Arunprasath P Date: Fri, 28 Nov 2025 10:03:07 +0530 Subject: [PATCH 2285/3659] drivers: dac: microchip: Introduce DAC G1 Driver Add G1 DAC driver for Microchip DAC Peripherals. Signed-off-by: Arunprasath P --- drivers/dac/CMakeLists.txt | 1 + drivers/dac/Kconfig | 1 + drivers/dac/Kconfig.mchp | 19 ++ drivers/dac/dac_mchp_g1.c | 443 +++++++++++++++++++++++++++++++++++++ 4 files changed, 464 insertions(+) create mode 100644 drivers/dac/Kconfig.mchp create mode 100644 drivers/dac/dac_mchp_g1.c diff --git a/drivers/dac/CMakeLists.txt b/drivers/dac/CMakeLists.txt index 27dd96534ed4..8fb0c4424c54 100644 --- a/drivers/dac/CMakeLists.txt +++ b/drivers/dac/CMakeLists.txt @@ -20,6 +20,7 @@ zephyr_library_sources_ifdef(CONFIG_DAC_ESP32 dac_esp32.c) zephyr_library_sources_ifdef(CONFIG_DAC_GD32 dac_gd32.c) zephyr_library_sources_ifdef(CONFIG_DAC_LTC166X dac_ltc166x.c) zephyr_library_sources_ifdef(CONFIG_DAC_MAX22017 dac_max22017.c) +zephyr_library_sources_ifdef(CONFIG_DAC_MCHP_G1 dac_mchp_g1.c) zephyr_library_sources_ifdef(CONFIG_DAC_MCP4725 dac_mcp4725.c) zephyr_library_sources_ifdef(CONFIG_DAC_MCP4728 dac_mcp4728.c) zephyr_library_sources_ifdef(CONFIG_DAC_MCUX_DAC dac_mcux_dac.c) diff --git a/drivers/dac/Kconfig b/drivers/dac/Kconfig index 99f447c6136c..1f5721cc3f7a 100644 --- a/drivers/dac/Kconfig +++ b/drivers/dac/Kconfig @@ -42,6 +42,7 @@ source "drivers/dac/Kconfig.esp32" source "drivers/dac/Kconfig.gd32" source "drivers/dac/Kconfig.ltc166x" source "drivers/dac/Kconfig.max22017" +source "drivers/dac/Kconfig.mchp" source "drivers/dac/Kconfig.mcp4725" source "drivers/dac/Kconfig.mcp4728" source "drivers/dac/Kconfig.mcux" diff --git a/drivers/dac/Kconfig.mchp b/drivers/dac/Kconfig.mchp new file mode 100644 index 000000000000..18263bdca116 --- /dev/null +++ b/drivers/dac/Kconfig.mchp @@ -0,0 +1,19 @@ +# Copyright (c) 2025-2026 Microchip Technology Inc. +# SPDX-License-Identifier: Apache-2.0 + +config DAC_MCHP_G1 + bool "Microchip G1 DAC Driver" + depends on DT_HAS_MICROCHIP_DAC_G1_ENABLED + default y + select PINCTRL + help + Enable support for the Microchip DAC driver on G1 DAC peripherals. + +if DAC_MCHP_G1 + +config DAC_MCHP_G1_DIFFERENTIAL + bool "Differential Mode" + help + Enable Differential Mode support for G1 DAC + +endif # DAC_MCHP_G1 diff --git a/drivers/dac/dac_mchp_g1.c b/drivers/dac/dac_mchp_g1.c new file mode 100644 index 000000000000..36a890767677 --- /dev/null +++ b/drivers/dac/dac_mchp_g1.c @@ -0,0 +1,443 @@ +/* + * Copyright (c) 2025-2026 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include + +#define DT_DRV_COMPAT microchip_dac_g1 +LOG_MODULE_REGISTER(dac_mchp_g1, CONFIG_DAC_LOG_LEVEL); + +#define DAC_MAX_CHANNELS DT_PROP(DT_NODELABEL(dac), max_channels) +#define DAC_CC100K 100 +#define DAC_CC1M 500 +#define DAC_CC12M 1000 +#define DAC_REFRESH_PERIOD 30 +#define DAC_RESOLUTION 12 +#define DAC_DATA_MSB_MASK (0x0FFFU) +#define DAC_DATA_LSB_MASK (0xFFF0U) +#define DAC_DATA_RIGHT_ADJ 0 +#define DAC_DATA_LEFT_ADJ 1 +#define DAC_CHANNELS_ALL 0xFF +#define DAC_OSR_RATIO_1 1 +#define DAC_OSR_RATIO_2 2 +#define DAC_OSR_RATIO_4 4 +#define DAC_OSR_RATIO_8 8 +#define DAC_OSR_RATIO_16 16 +#define DAC_OSR_RATIO_32 32 +#define TIMEOUT_VALUE_US 1000 +#define DELAY_US 2 + +struct dac_mchp_channel { + uint8_t channel; + int rate; + bool ext_filter; + uint8_t data_adj; + bool dither; + int sampling_ratio; + int refresh; +}; + +struct dac_mchp_clock { + const struct device *clock_dev; + clock_control_subsys_t mclk_sys; + clock_control_subsys_t gclk_sys; +}; + +struct dac_mchp_dev_config { + dac_registers_t *regs; + uint8_t refsel; + const struct pinctrl_dev_config *pcfg; + struct dac_mchp_clock dac_clock; + struct dac_mchp_channel channels[DAC_MAX_CHANNELS]; +}; + +struct dac_mchp_dev_data { + bool is_configured[DAC_MAX_CHANNELS]; +}; + +static inline void dac_wait_sync(dac_registers_t *dac_reg, uint32_t sync_flag) +{ + if (WAIT_FOR(((dac_reg->DAC_SYNCBUSY & sync_flag) == 0U), TIMEOUT_VALUE_US, + k_busy_wait(DELAY_US)) == false) { + LOG_ERR("Timeout waiting for DAC_SYNCBUSY bits to clear"); + } +} + +static void dac_wait_ready(dac_registers_t *dac_reg, uint8_t channel_id) +{ + uint32_t mask; + + /* Return early if DAC is not enabled */ + if ((dac_reg->DAC_CTRLA & DAC_CTRLA_ENABLE_Msk) == 0U) { + return; + } + + if (channel_id == DAC_CHANNELS_ALL) { + mask = DAC_STATUS_READY0_Msk | DAC_STATUS_READY1_Msk; + } else { + mask = (channel_id == 1U) ? DAC_STATUS_READY1_Msk : DAC_STATUS_READY0_Msk; + } + + if (WAIT_FOR(((dac_reg->DAC_STATUS & mask) == mask), TIMEOUT_VALUE_US, + k_busy_wait(DELAY_US)) == false) { + LOG_ERR("Timeout waiting for DAC_STATUS_READY (mask=0x%x)", mask); + } +} + +static inline void dac_enable_controller(dac_registers_t *dac_reg) +{ + dac_reg->DAC_CTRLA |= DAC_CTRLA_ENABLE_Msk; + dac_wait_sync(dac_reg, DAC_SYNCBUSY_ENABLE_Msk); +} + +static inline void dac_disable_controller(dac_registers_t *dac_reg) +{ + dac_reg->DAC_CTRLA &= ~DAC_CTRLA_ENABLE_Msk; + dac_wait_sync(dac_reg, DAC_SYNCBUSY_ENABLE_Msk); +} + +static inline void dac_reset(dac_registers_t *dac_reg) +{ + dac_reg->DAC_CTRLA = DAC_CTRLA_SWRST_Msk; + dac_wait_sync(dac_reg, DAC_SYNCBUSY_SWRST_Msk); +} + +static inline void dac_set_diff_output(dac_registers_t *dac_reg) +{ +#if defined(CONFIG_DAC_MCHP_G1_DIFFERENTIAL) + + dac_reg->DAC_CTRLB = DAC_CTRLB_DIFF_Msk; + +#endif /* CONFIG_DAC_MCHP_G1_DIFFERENTIAL */ +} + +static inline void dac_ref_selection(dac_registers_t *dac_reg, uint8_t refsel) +{ + dac_reg->DAC_CTRLB = + (dac_reg->DAC_CTRLB & ~DAC_CTRLB_REFSEL_Msk) | DAC_CTRLB_REFSEL(refsel); +} + +static inline void dac_channel_enable(dac_registers_t *dac_reg, uint8_t channel_id) +{ + dac_reg->DAC_DACCTRL[channel_id] |= DAC_DACCTRL_ENABLE_Msk; +} + +static void dac_conversion_speed(dac_registers_t *dac_reg, int rate, uint8_t channel_id) +{ + uint32_t cctrl_val; + + switch (rate) { + case DAC_CC100K: + cctrl_val = DAC_DACCTRL_CCTRL_CC100K; + break; + case DAC_CC1M: + cctrl_val = DAC_DACCTRL_CCTRL_CC1M; + break; + case DAC_CC12M: + cctrl_val = DAC_DACCTRL_CCTRL_CC12M; + break; + default: + LOG_WRN("Invalid DAC conversion rate (%d), defaulting to DAC_CC100K", rate); + cctrl_val = DAC_DACCTRL_CCTRL_CC100K; + break; + } + + dac_reg->DAC_DACCTRL[channel_id] = + (dac_reg->DAC_DACCTRL[channel_id] & ~DAC_DACCTRL_CCTRL_Msk) | cctrl_val; +} + +static inline void dac_external_filter(dac_registers_t *dac_reg, bool ext_filter, + uint8_t channel_id) +{ + dac_reg->DAC_DACCTRL[channel_id] = + (dac_reg->DAC_DACCTRL[channel_id] & ~DAC_DACCTRL_FEXT_Msk) | + DAC_DACCTRL_FEXT(ext_filter); +} + +static inline void dac_data_adj(dac_registers_t *dac_reg, uint8_t data_adj, uint8_t channel_id) +{ + dac_reg->DAC_DACCTRL[channel_id] = + (dac_reg->DAC_DACCTRL[channel_id] & ~DAC_DACCTRL_LEFTADJ_Msk) | + DAC_DACCTRL_LEFTADJ(data_adj); +} + +static inline void dac_dither(dac_registers_t *dac_reg, uint8_t dither, uint8_t channel_id) +{ + dac_reg->DAC_DACCTRL[channel_id] = + (dac_reg->DAC_DACCTRL[channel_id] & ~DAC_DACCTRL_DITHER_Msk) | + DAC_DACCTRL_DITHER(dither); +} + +static inline void dac_refresh(dac_registers_t *dac_reg, uint8_t refresh, uint8_t channel_id) +{ + if (refresh != 0) { + refresh = refresh / DAC_REFRESH_PERIOD; + } + dac_reg->DAC_DACCTRL[channel_id] = + (dac_reg->DAC_DACCTRL[channel_id] & ~DAC_DACCTRL_REFRESH_Msk) | + DAC_DACCTRL_REFRESH(refresh); +} + +static void dac_sampling_ratio(dac_registers_t *dac_reg, uint8_t sampling_ratio, uint8_t channel_id) +{ + uint8_t osr; + + switch (sampling_ratio) { + case DAC_OSR_RATIO_2: + osr = DAC_DACCTRL_OSR_OSR_2_Val; + break; + case DAC_OSR_RATIO_4: + osr = DAC_DACCTRL_OSR_OSR_4_Val; + break; + case DAC_OSR_RATIO_8: + osr = DAC_DACCTRL_OSR_OSR_8_Val; + break; + case DAC_OSR_RATIO_16: + osr = DAC_DACCTRL_OSR_OSR_16_Val; + break; + case DAC_OSR_RATIO_32: + osr = DAC_DACCTRL_OSR_OSR_32_Val; + break; + default: + osr = DAC_DACCTRL_OSR_OSR_1_Val; + break; + } + + dac_reg->DAC_DACCTRL[channel_id] = + (dac_reg->DAC_DACCTRL[channel_id] & ~DAC_DACCTRL_OSR_Msk) | DAC_DACCTRL_OSR(osr); +} + +static void dac_write_channel(dac_registers_t *dac_reg, const struct dac_mchp_channel *ch_cfg, + uint8_t channel_id, uint32_t value) +{ + uint32_t data; + + if (ch_cfg->data_adj == DAC_DATA_LEFT_ADJ) { + data = DAC_DATA_LSB_MASK & DAC_DATA_DATA(value); + } else { + data = DAC_DATA_MSB_MASK & DAC_DATA_DATA(value); + } + + dac_reg->DAC_DATA[channel_id] = data; + + dac_wait_sync(dac_reg, + (channel_id == 0U) ? DAC_SYNCBUSY_DATA0_Msk : DAC_SYNCBUSY_DATA1_Msk); +} + +static void dac_write_data(const struct device *dev, uint8_t channel_id, uint32_t value) +{ + const struct dac_mchp_dev_config *dev_cfg = dev->config; + + if (channel_id == DAC_CHANNELS_ALL) { + dac_write_channel(dev_cfg->regs, &dev_cfg->channels[0], 0U, value); + + dac_write_channel(dev_cfg->regs, &dev_cfg->channels[1], 1U, value); + } else { + dac_write_channel(dev_cfg->regs, &dev_cfg->channels[channel_id], channel_id, value); + } +} + +static int dac_configure(const struct device *dev, uint8_t channel_id) +{ + const struct dac_mchp_dev_config *dev_cfg = dev->config; + uint8_t i = 0, start = 0, end = 0; + +#if defined(CONFIG_DAC_MCHP_G1_DIFFERENTIAL) + /* If differential is selected, we can use only channel 0 */ + if (channel_cfg->channel_id != 0) { + return -EINVAL; + } +#endif /* CONFIG_DAC_MCHP_G1_DIFFERENTIAL */ + /* + * Determine the range of channels to configure. + * If channel_id is 0xFF, configure all DAC channels by iterating + * from channel 0 to DAC_MAX_CHANNELS - 1. + * Otherwise, configure only the specified channel. + */ + if (channel_id == DAC_CHANNELS_ALL) { + start = 0; + end = DAC_MAX_CHANNELS; + } else { + start = channel_id; + end = channel_id + 1; + } + + for (i = start; i < end; i++) { + /* Enable the DAC for channels */ + dac_channel_enable(dev_cfg->regs, i); + + /* Set the DATA Adjustment */ + dac_data_adj(dev_cfg->regs, dev_cfg->channels[i].data_adj, i); + + /* Set the Dither */ + dac_dither(dev_cfg->regs, dev_cfg->channels[i].dither, i); + + /* Set the refresh period */ + if (dev_cfg->channels[i].sampling_ratio != 1) { + dac_refresh(dev_cfg->regs, 0, i); + } else { + dac_refresh(dev_cfg->regs, dev_cfg->channels[i].refresh, i); + } + /* Set the conversion speed */ + dac_conversion_speed(dev_cfg->regs, dev_cfg->channels[i].rate, i); + + /* Set the External filter */ + dac_external_filter(dev_cfg->regs, dev_cfg->channels[i].ext_filter, i); + + /* Set the Oversampling Ratio */ + dac_sampling_ratio(dev_cfg->regs, dev_cfg->channels[i].sampling_ratio, i); + } + + return 0; +} + +static int dac_mchp_channel_setup(const struct device *dev, + const struct dac_channel_cfg *channel_cfg) +{ + const struct dac_mchp_dev_config *dev_cfg = dev->config; + struct dac_mchp_dev_data *const data = dev->data; + int ret; + int8_t i; + + /* Disable the Controller */ + dac_disable_controller(dev_cfg->regs); + + if (channel_cfg->resolution != DAC_RESOLUTION || (channel_cfg->internal == 1) || + (channel_cfg->buffered == 1)) { + LOG_ERR("Unsupported configuration!"); + return -ENOTSUP; + } + + /* Channel ID validity */ + if ((channel_cfg->channel_id >= DAC_MAX_CHANNELS) && + (channel_cfg->channel_id != DAC_CHANNELS_ALL)) { + LOG_ERR("Invalid Channel!"); + return -EINVAL; + } + + /* Configure the DAC channel(s) */ + ret = dac_configure(dev, channel_cfg->channel_id); + if (ret != 0) { + return ret; + } + + /* Enable the DAC */ + dac_enable_controller(dev_cfg->regs); + + /* Wait for ready state */ + dac_wait_ready(dev_cfg->regs, channel_cfg->channel_id); + + /* Mark configuration status */ + if (channel_cfg->channel_id == DAC_CHANNELS_ALL) { + for (i = 0; i < DAC_MAX_CHANNELS; i++) { + data->is_configured[i] = true; + } + } else { + data->is_configured[channel_cfg->channel_id] = true; + } + + return 0; +} + +static int dac_mchp_write_value(const struct device *dev, uint8_t channel, uint32_t value) +{ + struct dac_mchp_dev_data *const data = dev->data; + + /* Validate ALL channels */ + if (channel == DAC_CHANNELS_ALL) { + for (int i = 0; i < DAC_MAX_CHANNELS; i++) { + if (data->is_configured[i] == false) { + LOG_ERR("DAC write failed: channel %d not configured", i); + return -EINVAL; + } + } + } + /* Validate SINGLE channel */ + else { + if (channel >= DAC_MAX_CHANNELS) { + LOG_ERR("DAC write failed: invalid channel %u", channel); + return -EINVAL; + } + + if (data->is_configured[channel] == false) { + LOG_ERR("DAC write failed: channel %u not configured", channel); + return -EINVAL; + } + } + + dac_write_data(dev, channel, value); + + return 0; +} + +static int dac_mchp_init(const struct device *dev) +{ + const struct dac_mchp_dev_config *dev_cfg = dev->config; + int ret; + + /* Enable GCLK */ + ret = clock_control_on(dev_cfg->dac_clock.clock_dev, dev_cfg->dac_clock.gclk_sys); + if (ret != 0 && ret != -EALREADY) { + LOG_ERR("Failed to enable the GCLK for DAC: %d", ret); + return 0; + } + + /* Enable MCLK */ + ret = clock_control_on(dev_cfg->dac_clock.clock_dev, dev_cfg->dac_clock.mclk_sys); + if (ret != 0 && ret != -EALREADY) { + LOG_ERR("Failed to enable the MCLK for DAC: %d", ret); + return 0; + } + + ret = (ret == -EALREADY) ? 0 : ret; + + pinctrl_apply_state(dev_cfg->pcfg, PINCTRL_STATE_DEFAULT); + dac_reset(dev_cfg->regs); + dac_disable_controller(dev_cfg->regs); + dac_set_diff_output(dev_cfg->regs); + dac_ref_selection(dev_cfg->regs, dev_cfg->refsel); + + return 0; +} + +static DEVICE_API(dac, dac_mchp_api) = {.channel_setup = dac_mchp_channel_setup, + .write_value = dac_mchp_write_value}; + +#define DAC_MCHP_CHANNEL_DEFN(child) \ + [DT_REG_ADDR(child)] = {.channel = DT_REG_ADDR(child), \ + .rate = DT_PROP(child, rate), \ + .ext_filter = DT_PROP(child, ext_filter), \ + .data_adj = DT_ENUM_IDX(child, data_adj), \ + .dither = DT_PROP(child, dither_mode), \ + .sampling_ratio = DT_PROP(child, sampling_ratio), \ + .refresh = DT_PROP(child, refresh_period)} + +/* clang-format off */ +#define DAC_MCHP_CONFIG_DEFN(n) \ + static const struct dac_mchp_dev_config dac_mchp_config_##n = { \ + .regs = (dac_registers_t *)DT_INST_REG_ADDR(n), \ + .refsel = DT_ENUM_IDX(DT_DRV_INST(n), refsel), \ + .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ + .channels = {DT_FOREACH_CHILD_SEP(DT_DRV_INST(n), DAC_MCHP_CHANNEL_DEFN, (,))}, \ + .dac_clock.clock_dev = DEVICE_DT_GET(DT_NODELABEL(clock)), \ + .dac_clock.mclk_sys = (void *)DT_INST_CLOCKS_CELL_BY_NAME(n, mclk, subsystem), \ + .dac_clock.gclk_sys = (void *)(DT_INST_CLOCKS_CELL_BY_NAME(n, gclk, subsystem)), \ + } +/* clang-format on */ + +#define DAC_MCHP_DEVICE_INIT(n) \ + PINCTRL_DT_INST_DEFINE(n); \ + DAC_MCHP_CONFIG_DEFN(n); \ + static struct dac_mchp_dev_data dac_mchp_data_##n = {}; \ + DEVICE_DT_INST_DEFINE(n, dac_mchp_init, NULL, &dac_mchp_data_##n, &dac_mchp_config_##n, \ + POST_KERNEL, CONFIG_DAC_INIT_PRIORITY, &dac_mchp_api); + +DT_INST_FOREACH_STATUS_OKAY(DAC_MCHP_DEVICE_INIT) From 8b778f57f9f5ade12d903ed8962c489d911407e7 Mon Sep 17 00:00:00 2001 From: Arunprasath P Date: Fri, 28 Nov 2025 10:05:27 +0530 Subject: [PATCH 2286/3659] boards: microchip: sam_e54_xpro: Add DAC pinctrl and feature support Add DAC pinctrl definitions and update the board metadata to list DAC as a supported feature on the SAM E54 Xplained Pro board. Signed-off-by: Arunprasath P --- .../sam/sam_e54_xpro/sam_e54_xpro-pinctrl.dtsi | 6 ++++++ boards/microchip/sam/sam_e54_xpro/sam_e54_xpro.dts | 11 +++++++++++ boards/microchip/sam/sam_e54_xpro/sam_e54_xpro.yaml | 3 ++- 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/boards/microchip/sam/sam_e54_xpro/sam_e54_xpro-pinctrl.dtsi b/boards/microchip/sam/sam_e54_xpro/sam_e54_xpro-pinctrl.dtsi index 6d9a69870324..c5e73896785d 100644 --- a/boards/microchip/sam/sam_e54_xpro/sam_e54_xpro-pinctrl.dtsi +++ b/boards/microchip/sam/sam_e54_xpro/sam_e54_xpro-pinctrl.dtsi @@ -49,4 +49,10 @@ ; /* EXT3 pin 4 */ }; }; + + dac_default: dac_default { + group1 { + pinmux = ; + }; + }; }; diff --git a/boards/microchip/sam/sam_e54_xpro/sam_e54_xpro.dts b/boards/microchip/sam/sam_e54_xpro/sam_e54_xpro.dts index d644e44dee27..27e329db4b40 100644 --- a/boards/microchip/sam/sam_e54_xpro/sam_e54_xpro.dts +++ b/boards/microchip/sam/sam_e54_xpro/sam_e54_xpro.dts @@ -180,6 +180,12 @@ gclkperiph-src = "gclk1"; gclkperiph-en = <0>; }; + + dac { + subsystem = ; + gclkperiph-src = "gclk1"; + gclkperiph-en = <0>; + }; }; mclkperiph: mclkperiph { @@ -263,3 +269,8 @@ pinctrl-0 = <&adc1_default>; pinctrl-names = "default"; }; + +&dac { + pinctrl-0 = <&dac_default>; + pinctrl-names = "default"; +}; diff --git a/boards/microchip/sam/sam_e54_xpro/sam_e54_xpro.yaml b/boards/microchip/sam/sam_e54_xpro/sam_e54_xpro.yaml index 7e6ac68cbfb6..d359f36d098d 100644 --- a/boards/microchip/sam/sam_e54_xpro/sam_e54_xpro.yaml +++ b/boards/microchip/sam/sam_e54_xpro/sam_e54_xpro.yaml @@ -1,4 +1,4 @@ -# Copyright (c) 2025 Microchip Technology Inc. +# Copyright (c) 2025-2026 Microchip Technology Inc. # SPDX-License-Identifier: Apache-2.0 identifier: sam_e54_xpro @@ -14,6 +14,7 @@ supported: - clock_control - comparator - counter + - dac - dma - entropy - flash From 5f91dc2a75a0560168a1adfb907144a0bf3a653c Mon Sep 17 00:00:00 2001 From: farsin NASAR V A Date: Thu, 15 May 2025 17:43:40 +0530 Subject: [PATCH 2287/3659] tests: drivers: dac: Add SAM E54 Xplained Pro test support Add board-specific configuration and overlay files for running DAC API tests on the SAM E54 Xplained Pro board. - Add sam_e54_xpro.conf - Add sam_e54_xpro.overlay - Update DAC API test to support the board Signed-off-by: farsin NASAR V A --- .../dac/dac_api/boards/sam_e54_xpro.conf | 4 ++++ .../dac/dac_api/boards/sam_e54_xpro.overlay | 17 +++++++++++++++++ tests/drivers/dac/dac_api/src/test_dac.c | 5 ++++- 3 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 tests/drivers/dac/dac_api/boards/sam_e54_xpro.conf create mode 100644 tests/drivers/dac/dac_api/boards/sam_e54_xpro.overlay diff --git a/tests/drivers/dac/dac_api/boards/sam_e54_xpro.conf b/tests/drivers/dac/dac_api/boards/sam_e54_xpro.conf new file mode 100644 index 000000000000..0cea486a4711 --- /dev/null +++ b/tests/drivers/dac/dac_api/boards/sam_e54_xpro.conf @@ -0,0 +1,4 @@ +# Copyright (c) 2025 Microchip Technology Inc. +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_DAC_BUFFER_NOT_SUPPORT=y diff --git a/tests/drivers/dac/dac_api/boards/sam_e54_xpro.overlay b/tests/drivers/dac/dac_api/boards/sam_e54_xpro.overlay new file mode 100644 index 000000000000..595df6f2cfc6 --- /dev/null +++ b/tests/drivers/dac/dac_api/boards/sam_e54_xpro.overlay @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2025-2026 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&dac { + status = "okay"; + refsel = "int_ref"; + #address-cells = <1>; + #size-cells = <0>; + + dac0: channel@0 { + reg = <0>; + rate = <1000>; + }; +}; diff --git a/tests/drivers/dac/dac_api/src/test_dac.c b/tests/drivers/dac/dac_api/src/test_dac.c index 7e126cb5c188..07ee9d8c9ad7 100644 --- a/tests/drivers/dac/dac_api/src/test_dac.c +++ b/tests/drivers/dac/dac_api/src/test_dac.c @@ -73,6 +73,7 @@ #define DAC_RESOLUTION 12 #define DAC_CHANNEL_ID 0 +/* clang-format off */ #elif defined(CONFIG_BOARD_ESP32_DEVKITC) || \ defined(CONFIG_BOARD_ESP_WROVER_KIT) || \ defined(CONFIG_BOARD_ESP32S2_SAOLA) || \ @@ -86,7 +87,9 @@ defined(CONFIG_BOARD_MIMXRT1170_EVK) || \ defined(CONFIG_BOARD_MIMXRT1180_EVK) || \ defined(CONFIG_BOARD_FRDM_MCXC444) || \ - defined(CONFIG_BOARD_PHYBOARD_ATLAS) + defined(CONFIG_BOARD_PHYBOARD_ATLAS) || \ + defined(CONFIG_BOARD_SAM_E54_XPRO) +/* clang-format on */ #define DAC_DEVICE_NODE DT_NODELABEL(dac) #define DAC_RESOLUTION 12 From 87baf780822b2536b2de9493e1cabb9b413179ee Mon Sep 17 00:00:00 2001 From: Jacob Wienecke Date: Mon, 15 Dec 2025 16:04:25 -0600 Subject: [PATCH 2288/3659] boards: shields: nxp_m2_wifi_bt remove oob-gpios Remove oob-gpios property from nxp_m2_1xk_wifi_bt.overlay. There is no binding for this property at bindings\wifi\nxp,wifi.yaml. Therefore, builds using this shield will fail. Signed-off-by: Jacob Wienecke --- boards/shields/nxp_m2_wifi_bt/nxp_m2_1xk_wifi_bt.overlay | 1 - 1 file changed, 1 deletion(-) diff --git a/boards/shields/nxp_m2_wifi_bt/nxp_m2_1xk_wifi_bt.overlay b/boards/shields/nxp_m2_wifi_bt/nxp_m2_1xk_wifi_bt.overlay index 6129f6f5519b..ab5bbe980427 100644 --- a/boards/shields/nxp_m2_wifi_bt/nxp_m2_1xk_wifi_bt.overlay +++ b/boards/shields/nxp_m2_wifi_bt/nxp_m2_1xk_wifi_bt.overlay @@ -32,7 +32,6 @@ &m2_wifi_sdio { nxp_wifi { compatible = "nxp,wifi"; - oob-gpios = <&gpio1 23 GPIO_ACTIVE_HIGH>; wakeup-gpios = <&gpio1 26 GPIO_ACTIVE_LOW>; status = "okay"; }; From b672a265a485c6d91df36677fb9d4656abad2298 Mon Sep 17 00:00:00 2001 From: Matthias Blankertz Date: Wed, 3 Dec 2025 14:57:32 +0100 Subject: [PATCH 2289/3659] boards: nxp: frdm_mcxw71: Connect Arduino header I2C The I2C bus of the lpi2c1 I2C controller is connected to the Arduino Shield header on the usual pins. Label it with "arduino_i2c" in the board device tree so that the frdm_mcxw71 board can be used with I2C shields. Signed-off-by: Matthias Blankertz --- boards/nxp/frdm_mcxw71/frdm_mcxw71.dts | 2 ++ boards/nxp/frdm_mcxw71/frdm_mcxw71.yaml | 1 + 2 files changed, 3 insertions(+) diff --git a/boards/nxp/frdm_mcxw71/frdm_mcxw71.dts b/boards/nxp/frdm_mcxw71/frdm_mcxw71.dts index ded93d3e91d5..7edb77a0eda9 100644 --- a/boards/nxp/frdm_mcxw71/frdm_mcxw71.dts +++ b/boards/nxp/frdm_mcxw71/frdm_mcxw71.dts @@ -138,6 +138,8 @@ }; }; +arduino_i2c: &lpi2c1 {}; + &lpspi1 { status = "okay"; pinctrl-0 = <&pinmux_lpspi1>; diff --git a/boards/nxp/frdm_mcxw71/frdm_mcxw71.yaml b/boards/nxp/frdm_mcxw71/frdm_mcxw71.yaml index 2648f6c21ebb..fc6992b00e46 100644 --- a/boards/nxp/frdm_mcxw71/frdm_mcxw71.yaml +++ b/boards/nxp/frdm_mcxw71/frdm_mcxw71.yaml @@ -15,6 +15,7 @@ toolchain: - gnuarmemb supported: - adc + - arduino_i2c - can - counter - dma From f58602891a4b3ac1a8a3e13501ed07ca274d6cb8 Mon Sep 17 00:00:00 2001 From: Matthias Blankertz Date: Tue, 20 Jan 2026 13:14:04 +0100 Subject: [PATCH 2290/3659] drivers: watchdog: wdog32: Add missing include for k_msleep In commit 1f9e39752a2 ("drivers: watchdog: wdog32: add delay before init") a reference to k_msleep was added to drivers/watchdog/wdt_mcux_wdog32.c without including the necessary header. At least for the board frdm_mcxw71/mcxw716c, this causes a compile failure in this file as soon as CONFIG_WATCHDOG is enabled. Add the missing include to zephyr/kernel.h to fix the issue. Signed-off-by: Matthias Blankertz --- drivers/watchdog/wdt_mcux_wdog32.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/watchdog/wdt_mcux_wdog32.c b/drivers/watchdog/wdt_mcux_wdog32.c index f5323c795a0f..761923a55cc9 100644 --- a/drivers/watchdog/wdt_mcux_wdog32.c +++ b/drivers/watchdog/wdt_mcux_wdog32.c @@ -18,6 +18,7 @@ #define LOG_LEVEL CONFIG_WDT_LOG_LEVEL #include #include +#include LOG_MODULE_REGISTER(wdt_mcux_wdog32); #define MIN_TIMEOUT 1 From 12408745f4f82f57ef2df2a3f08e2d62305d480a Mon Sep 17 00:00:00 2001 From: Pieter De Gendt Date: Fri, 28 Nov 2025 11:51:34 +0100 Subject: [PATCH 2291/3659] tests: lib: devictree: api_ext: Add ADC_DT_SPEC_GET_BY_IDX cases Add tests for the ADC_DT_SPEC_GET_BY_IDX and ADC_DT_SPEC_INST_GET_BY_IDX macros. Signed-off-by: Pieter De Gendt --- tests/lib/devicetree/api_ext/src/main.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/tests/lib/devicetree/api_ext/src/main.c b/tests/lib/devicetree/api_ext/src/main.c index 3be0ce60720d..248bad687c6b 100644 --- a/tests/lib/devicetree/api_ext/src/main.c +++ b/tests/lib/devicetree/api_ext/src/main.c @@ -33,17 +33,31 @@ ZTEST(devicetree_api_ext, test_adc_dt_spec) /* ADC_DT_SPEC_GET_BY_NAME */ adc_spec = (struct adc_dt_spec)ADC_DT_SPEC_GET_BY_NAME(TEST_TEMP, ch1); - zassert_equal(adc_spec.channel_id, 10, ""); + zexpect_equal(adc_spec.channel_id, 10, ""); adc_spec = (struct adc_dt_spec)ADC_DT_SPEC_GET_BY_NAME(TEST_TEMP, ch2); - zassert_equal(adc_spec.channel_id, 20, ""); + zexpect_equal(adc_spec.channel_id, 20, ""); /* ADC_DT_SPEC_INST_GET_BY_NAME */ adc_spec = (struct adc_dt_spec)ADC_DT_SPEC_INST_GET_BY_NAME(0, ch1); - zassert_equal(adc_spec.channel_id, 10, ""); + zexpect_equal(adc_spec.channel_id, 10, ""); adc_spec = (struct adc_dt_spec)ADC_DT_SPEC_INST_GET_BY_NAME(0, ch2); - zassert_equal(adc_spec.channel_id, 20, ""); + zexpect_equal(adc_spec.channel_id, 20, ""); + + /* ADC_DT_SPEC_GET_BY_IDX */ + adc_spec = (struct adc_dt_spec)ADC_DT_SPEC_GET_BY_IDX(TEST_TEMP, 0); + zexpect_equal(adc_spec.channel_id, 10, ""); + + adc_spec = (struct adc_dt_spec)ADC_DT_SPEC_GET_BY_IDX(TEST_TEMP, 1); + zexpect_equal(adc_spec.channel_id, 20, ""); + + /* ADC_DT_SPEC_INST_GET_BY_IDX */ + adc_spec = (struct adc_dt_spec)ADC_DT_SPEC_INST_GET_BY_IDX(0, 0); + zexpect_equal(adc_spec.channel_id, 10, ""); + + adc_spec = (struct adc_dt_spec)ADC_DT_SPEC_INST_GET_BY_IDX(0, 1); + zexpect_equal(adc_spec.channel_id, 20, ""); } DEVICE_DT_DEFINE(DT_NODELABEL(test_mbox), NULL, NULL, NULL, NULL, POST_KERNEL, 90, NULL); From 0d4435984a1f0ec4988b66e7ffc07329ae11c197 Mon Sep 17 00:00:00 2001 From: Pieter De Gendt Date: Fri, 28 Nov 2025 12:10:25 +0100 Subject: [PATCH 2292/3659] include: zephyr: drivers: adc: Add adc_dt_spec _OR variants Add _OR variations for the differen adc_dt_spec initialization macros. Signed-off-by: Pieter De Gendt --- include/zephyr/drivers/adc.h | 96 +++++++++++++++++++++++++++++++++++- 1 file changed, 95 insertions(+), 1 deletion(-) diff --git a/include/zephyr/drivers/adc.h b/include/zephyr/drivers/adc.h index 66af2859515e..2cc4a3cb7d96 100644 --- a/include/zephyr/drivers/adc.h +++ b/include/zephyr/drivers/adc.h @@ -285,8 +285,12 @@ IF_ENABLED(CONFIG_ADC_CONFIGURABLE_VBIAS_PIN, \ /** * @brief Container for ADC channel information specified in devicetree. * + * @see ADC_DT_SPEC_GET_BY_NAME + * @see ADC_DT_SPEC_GET_BY_NAME_OR * @see ADC_DT_SPEC_GET_BY_IDX + * @see ADC_DT_SPEC_GET_BY_IDX_OR * @see ADC_DT_SPEC_GET + * @see ADC_DT_SPEC_GET_OR */ struct adc_dt_spec { /** @@ -429,6 +433,22 @@ struct adc_dt_spec { ADC_DT_SPEC_STRUCT(DT_IO_CHANNELS_CTLR_BY_NAME(node_id, name), \ DT_IO_CHANNELS_INPUT_BY_NAME(node_id, name)) +/** + * @brief Like ADC_DT_SPEC_GET_BY_NAME(), with a fallback to a default value. + * + * @param node_id Devicetree node identifier. + * @param name Channel name. + * @param default_value Fallback value to expand to. + * + * @return Static initializer for a struct adc_dt_spec for the property, + * or @p default_value if the node or property do not exist. + * + * @see ADC_DT_SPEC_INST_GET_BY_NAME_OR + */ +#define ADC_DT_SPEC_GET_BY_NAME_OR(node_id, name, default_value) \ + COND_CODE_1(DT_PROP_HAS_NAME(node_id, io_channels, name), \ + (ADC_DT_SPEC_GET_BY_NAME(node_id, name)), (default_value)) + /** @brief Get ADC io-channel information from a DT_DRV_COMPAT devicetree * instance by name. * @@ -442,6 +462,21 @@ struct adc_dt_spec { #define ADC_DT_SPEC_INST_GET_BY_NAME(inst, name) \ ADC_DT_SPEC_GET_BY_NAME(DT_DRV_INST(inst), name) +/** + * @brief Like ADC_DT_SPEC_INST_GET_BY_NAME(), with a fallback to a default value. + * + * @param inst DT_DRV_COMPAT instance number + * @param name Channel name. + * @param default_value Fallback value to expand to. + * + * @return Static initializer for a struct adc_dt_spec for the property, + * or @p default_value if the node or property do not exist. + * + * @see ADC_DT_SPEC_GET_BY_NAME_OR + */ +#define ADC_DT_SPEC_INST_GET_BY_NAME_OR(inst, name, default_value) \ + ADC_DT_SPEC_GET_BY_NAME_OR(DT_DRV_INST(inst), name, default_value) + /** * @brief Get ADC io-channel information from devicetree. * @@ -515,6 +550,22 @@ struct adc_dt_spec { ADC_DT_SPEC_STRUCT(DT_IO_CHANNELS_CTLR_BY_IDX(node_id, idx), \ DT_IO_CHANNELS_INPUT_BY_IDX(node_id, idx)) +/** + * @brief Like ADC_DT_SPEC_GET_BY_IDX(), with a fallback to a default value. + * + * @param node_id Devicetree node identifier. + * @param idx Channel index. + * @param default_value Fallback value to expand to. + * + * @return Static initializer for a struct adc_dt_spec for the property, + * or @p default_value if the node or property do not exist. + * + * @see ADC_DT_SPEC_INST_GET_BY_IDX_OR + */ +#define ADC_DT_SPEC_GET_BY_IDX_OR(node_id, idx, default_value) \ + COND_CODE_1(DT_PROP_HAS_IDX(node_id, io_channels, idx), \ + (ADC_DT_SPEC_GET_BY_IDX(node_id, idx)), (default_value)) + /** @brief Get ADC io-channel information from a DT_DRV_COMPAT devicetree * instance. * @@ -528,6 +579,20 @@ struct adc_dt_spec { #define ADC_DT_SPEC_INST_GET_BY_IDX(inst, idx) \ ADC_DT_SPEC_GET_BY_IDX(DT_DRV_INST(inst), idx) +/** + * @brief Like ADC_DT_SPEC_INST_GET_BY_IDX(), with a fallback to a default value. + * + * @param inst DT_DRV_COMPAT instance number + * @param idx Channel index. + * @param default_value Fallback value to expand to. + * + * @return Static initializer for a struct adc_dt_spec for the property, + * or @p default_value if the node or property do not exist. + * + * @see ADC_DT_SPEC_GET_BY_IDX_OR + */ +#define ADC_DT_SPEC_INST_GET_BY_IDX_OR(inst, idx, default_value) \ + ADC_DT_SPEC_GET_BY_IDX_OR(DT_DRV_INST(inst), idx, default_value) /** * @brief Equivalent to ADC_DT_SPEC_GET_BY_IDX(node_id, 0). * @@ -539,7 +604,22 @@ struct adc_dt_spec { */ #define ADC_DT_SPEC_GET(node_id) ADC_DT_SPEC_GET_BY_IDX(node_id, 0) -/** @brief Equivalent to ADC_DT_SPEC_INST_GET_BY_IDX(inst, 0). +/** + * @brief Equivalent to ADC_DT_SPEC_GET_BY_IDX_OR(node_id, 0, default_value). + * + * @see ADC_DT_SPEC_GET_BY_IDX_OR() + * + * @param node_id Devicetree node identifier. + * @param default_value Fallback value to expand to. + * + * @return Static initializer for a struct adc_dt_spec for the property, + * or @p default_value if the node or property do not exist. + */ +#define ADC_DT_SPEC_GET_OR(node_id, default_value) \ + ADC_DT_SPEC_GET_BY_IDX_OR(node_id, 0, default_value) + +/** + * @brief Equivalent to ADC_DT_SPEC_INST_GET_BY_IDX(inst, 0). * * @see ADC_DT_SPEC_GET() * @@ -549,6 +629,20 @@ struct adc_dt_spec { */ #define ADC_DT_SPEC_INST_GET(inst) ADC_DT_SPEC_GET(DT_DRV_INST(inst)) +/** + * @brief Equivalent to ADC_DT_SPEC_INST_GET_BY_IDX_OR(inst, 0, default). + * + * @see ADC_DT_SPEC_GET_OR() + * + * @param inst DT_DRV_COMPAT instance number + * @param default_value Fallback value to expand to. + * + * @return Static initializer for a struct adc_dt_spec for the property, + * or @p default_value if the node or property do not exist. + */ +#define ADC_DT_SPEC_INST_GET_OR(inst, default_value) \ + ADC_DT_SPEC_GET_OR(DT_DRV_INST(inst), default_value) + /* Forward declaration of the adc_sequence structure. */ struct adc_sequence; From 6dcc156258b930f15cb44a47a2c3a4cecf4ca05b Mon Sep 17 00:00:00 2001 From: Pieter De Gendt Date: Fri, 28 Nov 2025 12:11:49 +0100 Subject: [PATCH 2293/3659] tests: lib: devicetree: api_ext: Add ADC_DT_SPEC with fallback tests Add tests for the _OR variant sf the different ADC_DT_SPEC_GET macros. Signed-off-by: Pieter De Gendt --- tests/lib/devicetree/api_ext/src/main.c | 53 +++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/tests/lib/devicetree/api_ext/src/main.c b/tests/lib/devicetree/api_ext/src/main.c index 248bad687c6b..bad8063175a6 100644 --- a/tests/lib/devicetree/api_ext/src/main.c +++ b/tests/lib/devicetree/api_ext/src/main.c @@ -19,6 +19,7 @@ #define TEST_SRAM1 DT_NODELABEL(test_sram1) #define TEST_SRAM2 DT_NODELABEL(test_sram2) #define TEST_TEMP DT_NODELABEL(test_temp_sensor) +#define TEST_MISSING DT_NODELABEL(test_non_existing) ZTEST(devicetree_api_ext, test_linker_regions) { @@ -58,6 +59,58 @@ ZTEST(devicetree_api_ext, test_adc_dt_spec) adc_spec = (struct adc_dt_spec)ADC_DT_SPEC_INST_GET_BY_IDX(0, 1); zexpect_equal(adc_spec.channel_id, 20, ""); + + /* ADC_DT_SPEC_GET_BY_NAME_OR */ + adc_spec = (struct adc_dt_spec)ADC_DT_SPEC_GET_BY_NAME_OR(TEST_TEMP, ch1, {0}); + zexpect_equal(adc_spec.channel_id, 10, ""); + + adc_spec = (struct adc_dt_spec)ADC_DT_SPEC_GET_BY_NAME_OR(TEST_TEMP, ch2, {0}); + zexpect_equal(adc_spec.channel_id, 20, ""); + + adc_spec = (struct adc_dt_spec)ADC_DT_SPEC_GET_BY_NAME_OR(TEST_TEMP, ch_missing, {0}); + zexpect_equal(adc_spec.channel_id, 0, ""); + + adc_spec = (struct adc_dt_spec)ADC_DT_SPEC_GET_BY_NAME_OR(TEST_MISSING, ch1, {0}); + zexpect_equal(adc_spec.channel_id, 0, ""); + + /* ADC_DT_SPEC_INST_GET_BY_NAME_OR */ + adc_spec = (struct adc_dt_spec)ADC_DT_SPEC_INST_GET_BY_NAME_OR(0, ch1, {0}); + zexpect_equal(adc_spec.channel_id, 10, ""); + + adc_spec = (struct adc_dt_spec)ADC_DT_SPEC_INST_GET_BY_NAME_OR(0, ch2, {0}); + zexpect_equal(adc_spec.channel_id, 20, ""); + + adc_spec = (struct adc_dt_spec)ADC_DT_SPEC_INST_GET_BY_NAME_OR(0, ch_missing, {0}); + zexpect_equal(adc_spec.channel_id, 0, ""); + + adc_spec = (struct adc_dt_spec)ADC_DT_SPEC_INST_GET_BY_NAME_OR(100, ch1, {0}); + zexpect_equal(adc_spec.channel_id, 0, ""); + + /* ADC_DT_SPEC_GET_BY_IDX_OR */ + adc_spec = (struct adc_dt_spec)ADC_DT_SPEC_GET_BY_IDX_OR(TEST_TEMP, 0, {0}); + zexpect_equal(adc_spec.channel_id, 10, ""); + + adc_spec = (struct adc_dt_spec)ADC_DT_SPEC_GET_BY_IDX_OR(TEST_TEMP, 1, {0}); + zexpect_equal(adc_spec.channel_id, 20, ""); + + adc_spec = (struct adc_dt_spec)ADC_DT_SPEC_GET_BY_IDX_OR(TEST_TEMP, 100, {0}); + zexpect_equal(adc_spec.channel_id, 0, ""); + + adc_spec = (struct adc_dt_spec)ADC_DT_SPEC_GET_BY_IDX_OR(TEST_MISSING, 0, {0}); + zexpect_equal(adc_spec.channel_id, 0, ""); + + /* ADC_DT_SPEC_INST_GET_BY_IDX_OR */ + adc_spec = (struct adc_dt_spec)ADC_DT_SPEC_INST_GET_BY_IDX_OR(0, 0, {0}); + zexpect_equal(adc_spec.channel_id, 10, ""); + + adc_spec = (struct adc_dt_spec)ADC_DT_SPEC_INST_GET_BY_IDX_OR(0, 1, {0}); + zexpect_equal(adc_spec.channel_id, 20, ""); + + adc_spec = (struct adc_dt_spec)ADC_DT_SPEC_INST_GET_BY_IDX_OR(0, 100, {0}); + zexpect_equal(adc_spec.channel_id, 0, ""); + + adc_spec = (struct adc_dt_spec)ADC_DT_SPEC_INST_GET_BY_IDX_OR(100, 0, {0}); + zexpect_equal(adc_spec.channel_id, 0, ""); } DEVICE_DT_DEFINE(DT_NODELABEL(test_mbox), NULL, NULL, NULL, NULL, POST_KERNEL, 90, NULL); From 93b5f19f994b9a9376985299c1427a1630f6950e Mon Sep 17 00:00:00 2001 From: Pieter De Gendt Date: Tue, 9 Dec 2025 08:24:04 +0100 Subject: [PATCH 2294/3659] doc: releases: 4.4: Add ADC_DT_SPEC_GET_*_OR Add an entry to the release notes with the added ADC DT spec macros. Signed-off-by: Pieter De Gendt --- doc/releases/release-notes-4.4.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/doc/releases/release-notes-4.4.rst b/doc/releases/release-notes-4.4.rst index b75b99cc4cb2..28e31ee4f11c 100644 --- a/doc/releases/release-notes-4.4.rst +++ b/doc/releases/release-notes-4.4.rst @@ -106,6 +106,15 @@ New APIs and options .. zephyr-keep-sorted-start re(^\* \w) +* ADC + + * :c:macro:`ADC_DT_SPEC_GET_BY_IDX_OR` + * :c:macro:`ADC_DT_SPEC_GET_BY_NAME_OR` + * :c:macro:`ADC_DT_SPEC_GET_OR` + * :c:macro:`ADC_DT_SPEC_INST_GET_BY_IDX_OR` + * :c:macro:`ADC_DT_SPEC_INST_GET_BY_NAME_OR` + * :c:macro:`ADC_DT_SPEC_INST_GET_OR` + * Architectures * Xtensa From 7431163b522439108300d6746a852c683bdb65fc Mon Sep 17 00:00:00 2001 From: Jakub Zymelka Date: Tue, 20 Jan 2026 11:40:54 +0100 Subject: [PATCH 2295/3659] samples: ipc: icmsg: Extend support for nRF54LM20A Extends support and adds new overlays. Signed-off-by: Jakub Zymelka --- .../ipc/ipc_service/icmsg/CMakeLists.txt | 1 + .../ipc/ipc_service/icmsg/Kconfig.sysbuild | 1 + .../icmsg/boards/nrf54l_cpuapp_icbmsg.overlay | 11 +++++++ ... => nrf54lm20dk_nrf54lm20a_cpuapp.overlay} | 14 ++++---- .../boards/nrf54l_cpuflpr_icbmsg.overlay | 11 +++++++ ...=> nrf54lm20dk_nrf54lm20a_cpuflpr.overlay} | 14 ++++---- .../subsys/ipc/ipc_service/icmsg/sample.yaml | 33 +++++++++++-------- 7 files changed, 56 insertions(+), 29 deletions(-) create mode 100644 samples/subsys/ipc/ipc_service/icmsg/boards/nrf54l_cpuapp_icbmsg.overlay rename samples/subsys/ipc/ipc_service/icmsg/boards/{nrf54l15dk_nrf54l15_cpuapp_icbmsg.overlay => nrf54lm20dk_nrf54lm20a_cpuapp.overlay} (64%) create mode 100644 samples/subsys/ipc/ipc_service/icmsg/remote/boards/nrf54l_cpuflpr_icbmsg.overlay rename samples/subsys/ipc/ipc_service/icmsg/remote/boards/{nrf54l15dk_nrf54l15_cpuflpr_icbmsg.overlay => nrf54lm20dk_nrf54lm20a_cpuflpr.overlay} (67%) diff --git a/samples/subsys/ipc/ipc_service/icmsg/CMakeLists.txt b/samples/subsys/ipc/ipc_service/icmsg/CMakeLists.txt index fd88e8465fe1..b414551dd294 100644 --- a/samples/subsys/ipc/ipc_service/icmsg/CMakeLists.txt +++ b/samples/subsys/ipc/ipc_service/icmsg/CMakeLists.txt @@ -10,6 +10,7 @@ find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) if(NOT CONFIG_BOARD_NRF5340DK_NRF5340_CPUAPP AND NOT CONFIG_BOARD_NRF5340BSIM_NRF5340_CPUAPP AND + NOT CONFIG_BOARD_NRF54LM20DK_NRF54LM20A_CPUAPP AND NOT CONFIG_BOARD_STM32H747I_DISCO AND NOT CONFIG_BOARD_NRF54L15DK_NRF54L15_CPUAPP AND NOT CONFIG_BOARD_EK_RA8P1_R7KA8P1KFLCAC_CM85) diff --git a/samples/subsys/ipc/ipc_service/icmsg/Kconfig.sysbuild b/samples/subsys/ipc/ipc_service/icmsg/Kconfig.sysbuild index 58a434e2b6e9..11edd21c7540 100644 --- a/samples/subsys/ipc/ipc_service/icmsg/Kconfig.sysbuild +++ b/samples/subsys/ipc/ipc_service/icmsg/Kconfig.sysbuild @@ -9,5 +9,6 @@ string default "nrf5340dk/nrf5340/cpunet" if $(BOARD) = "nrf5340dk" default "nrf5340bsim/nrf5340/cpunet" if $(BOARD) = "nrf5340bsim" default "nrf54l15dk/nrf54l15/cpuflpr" if $(BOARD) = "nrf54l15dk" + default "nrf54lm20dk/nrf54lm20a/cpuflpr" if $(BOARD) = "nrf54lm20dk" default "stm32h747i_disco/stm32h747xx/m4" if $(BOARD) = "stm32h747i_disco" default "ek_ra8p1/r7ka8p1kflcac/cm33" if $(BOARD) = "ek_ra8p1" diff --git a/samples/subsys/ipc/ipc_service/icmsg/boards/nrf54l_cpuapp_icbmsg.overlay b/samples/subsys/ipc/ipc_service/icmsg/boards/nrf54l_cpuapp_icbmsg.overlay new file mode 100644 index 000000000000..68a36325c53d --- /dev/null +++ b/samples/subsys/ipc/ipc_service/icmsg/boards/nrf54l_cpuapp_icbmsg.overlay @@ -0,0 +1,11 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&ipc0 { + compatible = "zephyr,ipc-icbmsg"; + tx-blocks = <16>; + rx-blocks = <18>; +}; diff --git a/samples/subsys/ipc/ipc_service/icmsg/boards/nrf54l15dk_nrf54l15_cpuapp_icbmsg.overlay b/samples/subsys/ipc/ipc_service/icmsg/boards/nrf54lm20dk_nrf54lm20a_cpuapp.overlay similarity index 64% rename from samples/subsys/ipc/ipc_service/icmsg/boards/nrf54l15dk_nrf54l15_cpuapp_icbmsg.overlay rename to samples/subsys/ipc/ipc_service/icmsg/boards/nrf54lm20dk_nrf54lm20a_cpuapp.overlay index 639ad5e844b4..33afb300d789 100644 --- a/samples/subsys/ipc/ipc_service/icmsg/boards/nrf54l15dk_nrf54l15_cpuapp_icbmsg.overlay +++ b/samples/subsys/ipc/ipc_service/icmsg/boards/nrf54lm20dk_nrf54lm20a_cpuapp.overlay @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Nordic Semiconductor ASA + * Copyright (c) 2025 Nordic Semiconductor ASA * * SPDX-License-Identifier: Apache-2.0 */ @@ -10,24 +10,22 @@ #address-cells = <1>; #size-cells = <1>; - sram_rx: memory@20018000 { - reg = <0x20018000 0x0800>; + sram_rx: memory@20057c00 { + reg = <0x20057c00 0x8000>; }; - sram_tx: memory@20020000 { - reg = <0x20020000 0x0800>; + sram_tx: memory@2005fc00 { + reg = <0x2005fc00 0x8000>; }; }; }; ipc { ipc0: ipc0 { - compatible = "zephyr,ipc-icbmsg"; + compatible = "zephyr,ipc-icmsg"; dcache-alignment = <32>; tx-region = <&sram_tx>; rx-region = <&sram_rx>; - tx-blocks = <16>; - rx-blocks = <18>; mboxes = <&cpuapp_vevif_rx 20>, <&cpuapp_vevif_tx 21>; mbox-names = "rx", "tx"; status = "okay"; diff --git a/samples/subsys/ipc/ipc_service/icmsg/remote/boards/nrf54l_cpuflpr_icbmsg.overlay b/samples/subsys/ipc/ipc_service/icmsg/remote/boards/nrf54l_cpuflpr_icbmsg.overlay new file mode 100644 index 000000000000..e93358b71f22 --- /dev/null +++ b/samples/subsys/ipc/ipc_service/icmsg/remote/boards/nrf54l_cpuflpr_icbmsg.overlay @@ -0,0 +1,11 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&ipc0 { + compatible = "zephyr,ipc-icbmsg"; + tx-blocks = <18>; + rx-blocks = <16>; +}; diff --git a/samples/subsys/ipc/ipc_service/icmsg/remote/boards/nrf54l15dk_nrf54l15_cpuflpr_icbmsg.overlay b/samples/subsys/ipc/ipc_service/icmsg/remote/boards/nrf54lm20dk_nrf54lm20a_cpuflpr.overlay similarity index 67% rename from samples/subsys/ipc/ipc_service/icmsg/remote/boards/nrf54l15dk_nrf54l15_cpuflpr_icbmsg.overlay rename to samples/subsys/ipc/ipc_service/icmsg/remote/boards/nrf54lm20dk_nrf54lm20a_cpuflpr.overlay index 7fe78a716539..7aa2e5fa557b 100644 --- a/samples/subsys/ipc/ipc_service/icmsg/remote/boards/nrf54l15dk_nrf54l15_cpuflpr_icbmsg.overlay +++ b/samples/subsys/ipc/ipc_service/icmsg/remote/boards/nrf54lm20dk_nrf54lm20a_cpuflpr.overlay @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Nordic Semiconductor ASA + * Copyright (c) 2025 Nordic Semiconductor ASA * * SPDX-License-Identifier: Apache-2.0 */ @@ -10,24 +10,22 @@ #address-cells = <1>; #size-cells = <1>; - sram_tx: memory@20018000 { - reg = <0x20018000 0x0800>; + sram_tx: memory@20057c00 { + reg = <0x20057c00 0x8000>; }; - sram_rx: memory@20020000 { - reg = <0x20020000 0x0800>; + sram_rx: memory@2005fc00 { + reg = <0x2005fc00 0x8000>; }; }; }; ipc { ipc0: ipc0 { - compatible = "zephyr,ipc-icbmsg"; + compatible = "zephyr,ipc-icmsg"; dcache-alignment = <32>; tx-region = <&sram_tx>; rx-region = <&sram_rx>; - tx-blocks = <18>; - rx-blocks = <16>; mboxes = <&cpuflpr_vevif_rx 21>, <&cpuflpr_vevif_tx 20>; mbox-names = "rx", "tx"; status = "okay"; diff --git a/samples/subsys/ipc/ipc_service/icmsg/sample.yaml b/samples/subsys/ipc/ipc_service/icmsg/sample.yaml index d084434f7952..27ee7b5ad3bd 100644 --- a/samples/subsys/ipc/ipc_service/icmsg/sample.yaml +++ b/samples/subsys/ipc/ipc_service/icmsg/sample.yaml @@ -14,16 +14,18 @@ tests: - nrf5340dk/nrf5340/cpuapp - nrf5340bsim/nrf5340/cpuapp - sample.ipc.icmsg.nrf54l15: + sample.ipc.icmsg.nrf54l: platform_allow: - nrf54l15dk/nrf54l15/cpuapp + - nrf54lm20dk/nrf54lm20a/cpuapp integration_platforms: - nrf54l15dk/nrf54l15/cpuapp extra_args: icmsg_SNIPPET=nordic-flpr - sample.ipc.icmsg.nrf54l15_no_multithreading: + sample.ipc.icmsg.nrf54l_no_multithreading: platform_allow: - nrf54l15dk/nrf54l15/cpuapp + - nrf54lm20dk/nrf54lm20a/cpuapp integration_platforms: - nrf54l15dk/nrf54l15/cpuapp extra_args: @@ -33,9 +35,10 @@ tests: - remote_CONFIG_MULTITHREADING=n - remote_CONFIG_LOG_MODE_MINIMAL=y - sample.ipc.icmsg.nrf54l15_remote_no_multithreading: + sample.ipc.icmsg.nrf54l_remote_no_multithreading: platform_allow: - nrf54l15dk/nrf54l15/cpuapp + - nrf54lm20dk/nrf54lm20a/cpuapp integration_platforms: - nrf54l15dk/nrf54l15/cpuapp extra_args: @@ -43,43 +46,47 @@ tests: - remote_CONFIG_MULTITHREADING=n - remote_CONFIG_LOG_MODE_MINIMAL=y - sample.ipc.icbmsg.nrf54l15: - platform_allow: nrf54l15dk/nrf54l15/cpuapp + sample.ipc.icbmsg.nrf54l: + platform_allow: + - nrf54l15dk/nrf54l15/cpuapp + - nrf54lm20dk/nrf54lm20a/cpuapp integration_platforms: - nrf54l15dk/nrf54l15/cpuapp extra_args: - icmsg_SNIPPET=nordic-flpr - icmsg_CONFIG_IPC_SERVICE_BACKEND_ICBMSG_NUM_EP=1 - - icmsg_DTC_OVERLAY_FILE="boards/nrf54l15dk_nrf54l15_cpuapp_icbmsg.overlay" + - icmsg_EXTRA_DTC_OVERLAY_FILE="boards/nrf54l_cpuapp_icbmsg.overlay" - remote_CONFIG_IPC_SERVICE_BACKEND_ICBMSG_NUM_EP=1 - - remote_DTC_OVERLAY_FILE="boards/nrf54l15dk_nrf54l15_cpuflpr_icbmsg.overlay" + - remote_EXTRA_DTC_OVERLAY_FILE="boards/nrf54l_cpuflpr_icbmsg.overlay" - sample.ipc.icbmsg.nrf54l15_no_multithreading: + sample.ipc.icbmsg.nrf54l_no_multithreading: platform_allow: - nrf54l15dk/nrf54l15/cpuapp + - nrf54lm20dk/nrf54lm20a/cpuapp integration_platforms: - nrf54l15dk/nrf54l15/cpuapp extra_args: - icmsg_SNIPPET=nordic-flpr - icmsg_CONFIG_IPC_SERVICE_BACKEND_ICBMSG_NUM_EP=1 - - icmsg_DTC_OVERLAY_FILE="boards/nrf54l15dk_nrf54l15_cpuapp_icbmsg.overlay" + - icmsg_EXTRA_DTC_OVERLAY_FILE="boards/nrf54l_cpuapp_icbmsg.overlay" - icmsg_CONFIG_MULTITHREADING=n - icmsg_CONFIG_LOG_MODE_MINIMAL=y - remote_CONFIG_IPC_SERVICE_BACKEND_ICBMSG_NUM_EP=1 - - remote_DTC_OVERLAY_FILE="boards/nrf54l15dk_nrf54l15_cpuflpr_icbmsg.overlay" + - remote_EXTRA_DTC_OVERLAY_FILE="boards/nrf54l_cpuflpr_icbmsg.overlay" - remote_CONFIG_MULTITHREADING=n - remote_CONFIG_LOG_MODE_MINIMAL=y - sample.ipc.icbmsg.nrf54l15_remote_no_multithreading: + sample.ipc.icbmsg.nrf54l_remote_no_multithreading: platform_allow: - nrf54l15dk/nrf54l15/cpuapp + - nrf54lm20dk/nrf54lm20a/cpuapp integration_platforms: - nrf54l15dk/nrf54l15/cpuapp extra_args: - icmsg_SNIPPET=nordic-flpr - icmsg_CONFIG_IPC_SERVICE_BACKEND_ICBMSG_NUM_EP=1 - - icmsg_DTC_OVERLAY_FILE="boards/nrf54l15dk_nrf54l15_cpuapp_icbmsg.overlay" + - icmsg_EXTRA_DTC_OVERLAY_FILE="boards/nrf54l_cpuapp_icbmsg.overlay" - remote_CONFIG_IPC_SERVICE_BACKEND_ICBMSG_NUM_EP=1 - - remote_DTC_OVERLAY_FILE="boards/nrf54l15dk_nrf54l15_cpuflpr_icbmsg.overlay" + - remote_EXTRA_DTC_OVERLAY_FILE="boards/nrf54l_cpuflpr_icbmsg.overlay" - remote_CONFIG_MULTITHREADING=n - remote_CONFIG_LOG_MODE_MINIMAL=y From fdda5f5fad69bf8995622ed798917c90cc961229 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Mon, 15 Dec 2025 11:58:04 +0100 Subject: [PATCH 2296/3659] manifest: psa-arch-tests: build PSA arch tests from Zephyr Restore build of TF-M PSA-arch-tests using the Zephyr SDK toolchain. Signed-off-by: Etienne Carriere --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index f3a744910910..a51f8cf3962b 100644 --- a/west.yml +++ b/west.yml @@ -364,7 +364,7 @@ manifest: path: modules/lib/picolibc revision: ca8b6ebba5226a75545e57a140443168a26ba664 - name: psa-arch-tests - revision: 941cd8436a2e0f1da9d8584b83a403930826899d + revision: d70b2c7072cedf0f14724211d2122ef07b98720c path: modules/tee/tf-m/psa-arch-tests groups: - testing From 6f5e752187c0dfe6bff2874df28da05c932a2f96 Mon Sep 17 00:00:00 2001 From: Kate Wang Date: Mon, 22 Dec 2025 20:36:05 +0800 Subject: [PATCH 2297/3659] drivers: display: co5300: Fix pitch calculation in write function The previous implementation incorrectly calculated the source pointer advancement when pitch differs from width. The calculation was using `total_bytes_sent` which accumulated across iterations, leading to incorrect pointer arithmetic. Replace `total_bytes_sent` with `line_each_sent` to track lines written per iteration. Simplify the pointer advancement by: - Calculating complete lines written from bytes_written - Advancing by full pitch-sized lines - Adding any remaining partial line bytes This fixes the source pointer calculation when the buffer pitch is greater than the display width. Signed-off-by: Kate Wang --- drivers/display/display_co5300.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/display/display_co5300.c b/drivers/display/display_co5300.c index ee2bf3136410..bf1d7d688d21 100644 --- a/drivers/display/display_co5300.c +++ b/drivers/display/display_co5300.c @@ -154,7 +154,7 @@ static int co5300_write(const struct device *dev, uint16_t end_pos; uint8_t cmd_params[4]; struct mipi_dsi_msg msg = {0}; - uint32_t total_bytes_sent = 0U; + uint16_t line_each_sent = 0U; int bytes_written = 0; const uint8_t *src; uint32_t tx_size = 0U; @@ -247,10 +247,9 @@ static int co5300_write(const struct device *dev, /* Advance source pointer and decrement remaining */ if (local_desc.pitch > local_desc.width) { - total_bytes_sent += bytes_written; - src += bytes_written + total_bytes_sent / - (local_desc.width * data->bytes_per_pixel) * - ((local_desc.pitch - local_desc.width) * data->bytes_per_pixel); + line_each_sent = bytes_written / (local_desc.width * data->bytes_per_pixel); + src += line_each_sent * local_desc.pitch * data->bytes_per_pixel; + src += bytes_written % (local_desc.width * data->bytes_per_pixel); } else { src += bytes_written; } From 0bbe07bbc721546efad31d6c6e43a1cd551afc39 Mon Sep 17 00:00:00 2001 From: Ederson de Souza Date: Wed, 31 Dec 2025 16:11:50 -0800 Subject: [PATCH 2298/3659] drivers/i3c/mcux: Use size_t for buffer size Or a buffer whose size is 256 will become zero. Signed-off-by: Ederson de Souza --- drivers/i3c/i3c_mcux.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/i3c/i3c_mcux.c b/drivers/i3c/i3c_mcux.c index d955641f801e..d358890dd6ca 100644 --- a/drivers/i3c/i3c_mcux.c +++ b/drivers/i3c/i3c_mcux.c @@ -854,7 +854,7 @@ static int mcux_i3c_recover_bus(const struct device *dev) * @return Number of bytes read, or negative if error. */ static int mcux_i3c_do_one_xfer_read(I3C_Type *base, struct mcux_i3c_data *data, - uint8_t *buf, uint8_t buf_sz, bool ibi) + uint8_t *buf, size_t buf_sz, bool ibi) { int ret = 0; int offset = 0; From 3311d9734ca9b6ece26cc7089075bfc973c135b5 Mon Sep 17 00:00:00 2001 From: Ederson de Souza Date: Wed, 31 Dec 2025 16:14:44 -0800 Subject: [PATCH 2299/3659] drivers/i3c/mcux: Don't lose return value for function Return value for `mcux_i3c_do_one_xfer` was being lost due reuse of `ret` variable. Use another variable for timeout check. Signed-off-by: Ederson de Souza --- drivers/i3c/i3c_mcux.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/i3c/i3c_mcux.c b/drivers/i3c/i3c_mcux.c index d358890dd6ca..67f6a39fc726 100644 --- a/drivers/i3c/i3c_mcux.c +++ b/drivers/i3c/i3c_mcux.c @@ -1018,8 +1018,9 @@ static int mcux_i3c_do_one_xfer(I3C_Type *base, struct mcux_i3c_data *data, * Wait for controller to say the operation is done. * Save time by not clearing the bit. */ - ret = mcux_i3c_status_wait_timeout(base, I3C_MSTATUS_COMPLETE_MASK, 1000); - if (ret != 0) { + int ret2 = mcux_i3c_status_wait_timeout(base, I3C_MSTATUS_COMPLETE_MASK, 1000); + + if (ret2 != 0) { LOG_DBG("%s: timed out addr 0x%02x, buf_sz %u", __func__, addr, buf_sz); emit_stop = true; From 86f7962d2c263b20c2cb67f4320b7b9ef81bd03e Mon Sep 17 00:00:00 2001 From: Ederson de Souza Date: Wed, 31 Dec 2025 16:18:21 -0800 Subject: [PATCH 2300/3659] drivers/i3c/mcux: Handle short reads from target Sometimes, the size of a message coming from a target is not known in advance. In those cases, we must rely on the T-bit to get the end of message, which is signaled as the `COMPLETE` bit of `MSTATUS`. This patch verifies the COMPLETE bit before starting to wait for data, and if set, simply returns what was read so far. As a bonus, this simplifies the handling of IBI bytes: no need to rely on timeouts, if it's reading from IBI, etc. Signed-off-by: Ederson de Souza --- drivers/i3c/i3c_mcux.c | 38 ++++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/drivers/i3c/i3c_mcux.c b/drivers/i3c/i3c_mcux.c index 67f6a39fc726..02032da8966f 100644 --- a/drivers/i3c/i3c_mcux.c +++ b/drivers/i3c/i3c_mcux.c @@ -854,7 +854,7 @@ static int mcux_i3c_recover_bus(const struct device *dev) * @return Number of bytes read, or negative if error. */ static int mcux_i3c_do_one_xfer_read(I3C_Type *base, struct mcux_i3c_data *data, - uint8_t *buf, size_t buf_sz, bool ibi) + uint8_t *buf, size_t buf_sz) { int ret = 0; int offset = 0; @@ -866,7 +866,16 @@ static int mcux_i3c_do_one_xfer_read(I3C_Type *base, struct mcux_i3c_data *data, */ while (offset < buf_sz) { if (mcux_i3c_fifo_rx_count_get(base) == 0) { - /* Enable Receive pending interrupt */ + /* No more data - check if target marked message as complete */ + if (mcux_i3c_status_is_set(base, I3C_MSTATUS_COMPLETE_MASK)) { + /* All data received, move on */ + LOG_DBG("Target data complete, offset %d buf_sz %d", offset, + buf_sz); + ret = offset; + break; + } + + /* More data to come, enable Receive pending interrupt */ base->MINTSET = I3C_MSTATUS_RXPEND_MASK; /* Wait for data to arrive or an error */ @@ -881,28 +890,25 @@ static int mcux_i3c_do_one_xfer_read(I3C_Type *base, struct mcux_i3c_data *data, buf[offset++] = (uint8_t)base->MRDATAB; } } + + /* Done reading all data */ + if (ret > 0) { + break; + } + /* * If timed out, we abort the transaction. */ - if ((mcux_i3c_has_error(data) & I3C_MERRWARN_TIMEOUT_MASK) || ret) { + if ((mcux_i3c_has_error(data) & I3C_MERRWARN_TIMEOUT_MASK) || ret < 0) { ret = -ETIMEDOUT; - /* for ibi, ignore timeout err if any bytes were - * read, since the code doesn't know how many - * bytes will be sent by device. - */ - if (ibi && offset) { - ret = offset; - } else { - LOG_ERR("Timeout error"); - } + LOG_ERR("Timeout error"); break; } - } /* If no errors, then return the number of bytes read */ - if (ret > 0) { + if (ret >= 0) { ret = offset; } @@ -1003,7 +1009,7 @@ static int mcux_i3c_do_one_xfer(I3C_Type *base, struct mcux_i3c_data *data, } if (is_read) { - ret = mcux_i3c_do_one_xfer_read(base, data, buf, buf_sz, false); + ret = mcux_i3c_do_one_xfer_read(base, data, buf, buf_sz); } else { ret = mcux_i3c_do_one_xfer_write(base, data, buf, buf_sz, no_ending); } @@ -1509,7 +1515,7 @@ static void mcux_i3c_ibi_work(struct k_work *work) target = i3c_dev_list_i3c_addr_find(dev, (uint8_t)ibiaddr); if (target != NULL) { ret = mcux_i3c_do_one_xfer_read(base, data, &payload[0], - sizeof(payload), true); + sizeof(payload)); if (ret >= 0) { payload_sz = (size_t)ret; } else { From c1a356e5efaf697d370a7c2368d83c364e65fb11 Mon Sep 17 00:00:00 2001 From: Khai Cao Date: Tue, 13 Jan 2026 01:59:26 +0000 Subject: [PATCH 2301/3659] boards: renesas: Correct part number for mck_ra8t2 board Correct part number for mck_ra8t2 board by change r7ka8t2lfecac to r7ka8t2lflcac Signed-off-by: Khai Cao --- boards/renesas/mck_ra8t2/Kconfig.mck_ra8t2 | 4 ++-- boards/renesas/mck_ra8t2/board.cmake | 2 +- boards/renesas/mck_ra8t2/board.yml | 2 +- boards/renesas/mck_ra8t2/doc/index.rst | 8 ++++---- ...c_cm85.dts => mck_ra8t2_r7ka8t2lflcac_cm85.dts} | 2 +- ...cm85.yaml => mck_ra8t2_r7ka8t2lflcac_cm85.yaml} | 2 +- ...nfig => mck_ra8t2_r7ka8t2lflcac_cm85_defconfig} | 0 .../ra8/{r7ka8t2lfecac.dtsi => r7ka8t2lflcac.dtsi} | 0 ...8t2lfecac_cm85.dtsi => r7ka8t2lflcac_cm85.dtsi} | 2 +- ...verlay => mck_ra8t2_r7ka8t2lflcac_cm85.overlay} | 0 soc/renesas/ra/ra8t2/Kconfig | 12 ++++++------ soc/renesas/ra/ra8t2/Kconfig.defconfig | 4 ++-- soc/renesas/ra/ra8t2/Kconfig.soc | 14 +++++++------- soc/renesas/ra/soc.yml | 2 +- ...verlay => mck_ra8t2_r7ka8t2lflcac_cm85.overlay} | 0 ...verlay => mck_ra8t2_r7ka8t2lflcac_cm85.overlay} | 0 ...verlay => mck_ra8t2_r7ka8t2lflcac_cm85.overlay} | 0 ...verlay => mck_ra8t2_r7ka8t2lflcac_cm85.overlay} | 0 ...verlay => mck_ra8t2_r7ka8t2lflcac_cm85.overlay} | 0 ...cm85.conf => mck_ra8t2_r7ka8t2lflcac_cm85.conf} | 0 ...verlay => mck_ra8t2_r7ka8t2lflcac_cm85.overlay} | 0 ...=> mck_ra8t2_r7ka8t2lflcac_cm85_sci_b_i2c.conf} | 0 ...mck_ra8t2_r7ka8t2lflcac_cm85_sci_b_i2c.overlay} | 0 tests/drivers/i2c/i2c_api/testcase.yaml | 2 +- ...verlay => mck_ra8t2_r7ka8t2lflcac_cm85.overlay} | 0 ...verlay => mck_ra8t2_r7ka8t2lflcac_cm85.overlay} | 0 ...cm85.conf => mck_ra8t2_r7ka8t2lflcac_cm85.conf} | 0 ...verlay => mck_ra8t2_r7ka8t2lflcac_cm85.overlay} | 0 ...mck_ra8t2_r7ka8t2lflcac_cm85_sci_b_spi.overlay} | 0 tests/drivers/spi/spi_loopback/testcase.yaml | 4 ++-- ...verlay => mck_ra8t2_r7ka8t2lflcac_cm85.overlay} | 0 ...verlay => mck_ra8t2_r7ka8t2lflcac_cm85.overlay} | 0 ...verlay => mck_ra8t2_r7ka8t2lflcac_cm85.overlay} | 0 tests/subsys/fs/ext2/testcase.yaml | 4 ++-- ...cm85.conf => mck_ra8t2_r7ka8t2lflcac_cm85.conf} | 0 tests/subsys/pm/power_mgmt_soc/testcase.yaml | 2 +- 36 files changed, 33 insertions(+), 33 deletions(-) rename boards/renesas/mck_ra8t2/{mck_ra8t2_r7ka8t2lfecac_cm85.dts => mck_ra8t2_r7ka8t2lflcac_cm85.dts} (97%) rename boards/renesas/mck_ra8t2/{mck_ra8t2_r7ka8t2lfecac_cm85.yaml => mck_ra8t2_r7ka8t2lflcac_cm85.yaml} (78%) rename boards/renesas/mck_ra8t2/{mck_ra8t2_r7ka8t2lfecac_cm85_defconfig => mck_ra8t2_r7ka8t2lflcac_cm85_defconfig} (100%) rename dts/arm/renesas/ra/ra8/{r7ka8t2lfecac.dtsi => r7ka8t2lflcac.dtsi} (100%) rename dts/arm/renesas/ra/ra8/{r7ka8t2lfecac_cm85.dtsi => r7ka8t2lflcac_cm85.dtsi} (76%) rename samples/drivers/counter/alarm/boards/{mck_ra8t2_r7ka8t2lfecac_cm85.overlay => mck_ra8t2_r7ka8t2lflcac_cm85.overlay} (100%) rename tests/drivers/can/api/boards/{mck_ra8t2_r7ka8t2lfecac_cm85.overlay => mck_ra8t2_r7ka8t2lflcac_cm85.overlay} (100%) rename tests/drivers/can/timing/boards/{mck_ra8t2_r7ka8t2lfecac_cm85.overlay => mck_ra8t2_r7ka8t2lflcac_cm85.overlay} (100%) rename tests/drivers/clock_control/pwm_clock/boards/{mck_ra8t2_r7ka8t2lfecac_cm85.overlay => mck_ra8t2_r7ka8t2lflcac_cm85.overlay} (100%) rename tests/drivers/comparator/gpio_loopback/boards/{mck_ra8t2_r7ka8t2lfecac_cm85.overlay => mck_ra8t2_r7ka8t2lflcac_cm85.overlay} (100%) rename tests/drivers/counter/counter_basic_api/boards/{mck_ra8t2_r7ka8t2lfecac_cm85.overlay => mck_ra8t2_r7ka8t2lflcac_cm85.overlay} (100%) rename tests/drivers/i2c/i2c_api/boards/{mck_ra8t2_r7ka8t2lfecac_cm85.conf => mck_ra8t2_r7ka8t2lflcac_cm85.conf} (100%) rename tests/drivers/i2c/i2c_api/boards/{mck_ra8t2_r7ka8t2lfecac_cm85.overlay => mck_ra8t2_r7ka8t2lflcac_cm85.overlay} (100%) rename tests/drivers/i2c/i2c_api/boards/{mck_ra8t2_r7ka8t2lfecac_cm85_sci_b_i2c.conf => mck_ra8t2_r7ka8t2lflcac_cm85_sci_b_i2c.conf} (100%) rename tests/drivers/i2c/i2c_api/boards/{mck_ra8t2_r7ka8t2lfecac_cm85_sci_b_i2c.overlay => mck_ra8t2_r7ka8t2lflcac_cm85_sci_b_i2c.overlay} (100%) rename tests/drivers/pwm/pwm_api/boards/{mck_ra8t2_r7ka8t2lfecac_cm85.overlay => mck_ra8t2_r7ka8t2lflcac_cm85.overlay} (100%) rename tests/drivers/pwm/pwm_loopback/boards/{mck_ra8t2_r7ka8t2lfecac_cm85.overlay => mck_ra8t2_r7ka8t2lflcac_cm85.overlay} (100%) rename tests/drivers/spi/spi_loopback/boards/{mck_ra8t2_r7ka8t2lfecac_cm85.conf => mck_ra8t2_r7ka8t2lflcac_cm85.conf} (100%) rename tests/drivers/spi/spi_loopback/boards/{mck_ra8t2_r7ka8t2lfecac_cm85.overlay => mck_ra8t2_r7ka8t2lflcac_cm85.overlay} (100%) rename tests/drivers/spi/spi_loopback/boards/{mck_ra8t2_r7ka8t2lfecac_cm85_sci_b_spi.overlay => mck_ra8t2_r7ka8t2lflcac_cm85_sci_b_spi.overlay} (100%) rename tests/drivers/uart/uart_async_api/boards/{mck_ra8t2_r7ka8t2lfecac_cm85.overlay => mck_ra8t2_r7ka8t2lflcac_cm85.overlay} (100%) rename tests/subsys/canbus/isotp/conformance/boards/{mck_ra8t2_r7ka8t2lfecac_cm85.overlay => mck_ra8t2_r7ka8t2lflcac_cm85.overlay} (100%) rename tests/subsys/canbus/isotp/implementation/boards/{mck_ra8t2_r7ka8t2lfecac_cm85.overlay => mck_ra8t2_r7ka8t2lflcac_cm85.overlay} (100%) rename tests/subsys/fs/fat_fs_api/boards/{mck_ra8t2_r7ka8t2lfecac_cm85.conf => mck_ra8t2_r7ka8t2lflcac_cm85.conf} (100%) diff --git a/boards/renesas/mck_ra8t2/Kconfig.mck_ra8t2 b/boards/renesas/mck_ra8t2/Kconfig.mck_ra8t2 index ba0ca76b5d2f..28da044ae41e 100644 --- a/boards/renesas/mck_ra8t2/Kconfig.mck_ra8t2 +++ b/boards/renesas/mck_ra8t2/Kconfig.mck_ra8t2 @@ -2,5 +2,5 @@ # SPDX-License-Identifier: Apache-2.0 config BOARD_MCK_RA8T2 - select SOC_R7KA8T2LFECAC_CM85 if BOARD_MCK_RA8T2_R7KA8T2LFECAC_CM85 - select SOC_R7KA8T2LFECAC_CM33 if BOARD_MCK_RA8T2_R7KA8T2LFECAC_CM33 + select SOC_R7KA8T2LFLCAC_CM85 if BOARD_MCK_RA8T2_R7KA8T2LFLCAC_CM85 + select SOC_R7KA8T2LFLCAC_CM33 if BOARD_MCK_RA8T2_R7KA8T2LFLCAC_CM33 diff --git a/boards/renesas/mck_ra8t2/board.cmake b/boards/renesas/mck_ra8t2/board.cmake index 39712afe86e8..9430935aab35 100644 --- a/boards/renesas/mck_ra8t2/board.cmake +++ b/boards/renesas/mck_ra8t2/board.cmake @@ -1,7 +1,7 @@ # Copyright (c) 2025 Renesas Electronics Corporation # SPDX-License-Identifier: Apache-2.0 -if(CONFIG_SOC_R7KA8T2LFECAC_CM85) +if(CONFIG_SOC_R7KA8T2LFLCAC_CM85) board_runner_args(jlink "--device=R7KA8T2LF_CPU0" "--reset-after-load") endif() diff --git a/boards/renesas/mck_ra8t2/board.yml b/boards/renesas/mck_ra8t2/board.yml index 2981b49915b4..81358c562bab 100644 --- a/boards/renesas/mck_ra8t2/board.yml +++ b/boards/renesas/mck_ra8t2/board.yml @@ -3,4 +3,4 @@ board: full_name: RA8T2 Motor Control Kit vendor: renesas socs: - - name: r7ka8t2lfecac + - name: r7ka8t2lflcac diff --git a/boards/renesas/mck_ra8t2/doc/index.rst b/boards/renesas/mck_ra8t2/doc/index.rst index c3f9dd728894..dcbc8e323751 100644 --- a/boards/renesas/mck_ra8t2/doc/index.rst +++ b/boards/renesas/mck_ra8t2/doc/index.rst @@ -88,7 +88,7 @@ Here is an example for the :zephyr:code-sample:`hello_world` application on CM85 .. zephyr-app-commands:: :zephyr-app: samples/hello_world - :board: mck_ra8t2/r7ka8t2lfecac/cm85 + :board: mck_ra8t2/r7ka8t2lflcac/cm85 :goals: flash Open a serial terminal, reset the board (push the reset switch S1), and you should @@ -97,7 +97,7 @@ see the following message in the terminal: .. code-block:: console ***** Booting Zephyr OS v4.2.0-xxx-xxxxxxxxxxxxx ***** - Hello World! mck_ra8t2/r7ka8t2lfecac/cm85 + Hello World! mck_ra8t2/r7ka8t2lflcac/cm85 Flashing ======== @@ -128,7 +128,7 @@ To build the sample application using sysbuild use the command: .. zephyr-app-commands:: :tool: west :zephyr-app: samples/hello_world - :board: mck_ra8t2/r7ka8t2lfecac/cm85 + :board: mck_ra8t2/r7ka8t2lflcac/cm85 :goals: build flash :west-args: --sysbuild :gen-args: -DSB_CONFIG_BOOTLOADER_MCUBOOT=y @@ -188,7 +188,7 @@ You should see the following message in the terminal: I: Image version: v0.0.0 I: Jumping to the first image slot *** Booting Zephyr OS build v4.2.0-6156-ged85ac9ffda9 *** - Hello World! mck_ra8t2/r7ka8t2lfecac/cm85 + Hello World! mck_ra8t2/r7ka8t2lflcac/cm85 References ********** diff --git a/boards/renesas/mck_ra8t2/mck_ra8t2_r7ka8t2lfecac_cm85.dts b/boards/renesas/mck_ra8t2/mck_ra8t2_r7ka8t2lflcac_cm85.dts similarity index 97% rename from boards/renesas/mck_ra8t2/mck_ra8t2_r7ka8t2lfecac_cm85.dts rename to boards/renesas/mck_ra8t2/mck_ra8t2_r7ka8t2lflcac_cm85.dts index 2603cf3fb959..e88d85f6a234 100644 --- a/boards/renesas/mck_ra8t2/mck_ra8t2_r7ka8t2lfecac_cm85.dts +++ b/boards/renesas/mck_ra8t2/mck_ra8t2_r7ka8t2lflcac_cm85.dts @@ -5,7 +5,7 @@ /dts-v1/; -#include +#include #include "mck_ra8t2.dtsi" / { diff --git a/boards/renesas/mck_ra8t2/mck_ra8t2_r7ka8t2lfecac_cm85.yaml b/boards/renesas/mck_ra8t2/mck_ra8t2_r7ka8t2lflcac_cm85.yaml similarity index 78% rename from boards/renesas/mck_ra8t2/mck_ra8t2_r7ka8t2lfecac_cm85.yaml rename to boards/renesas/mck_ra8t2/mck_ra8t2_r7ka8t2lflcac_cm85.yaml index 94277f34b2c4..a1dbd0715dcf 100644 --- a/boards/renesas/mck_ra8t2/mck_ra8t2_r7ka8t2lfecac_cm85.yaml +++ b/boards/renesas/mck_ra8t2/mck_ra8t2_r7ka8t2lflcac_cm85.yaml @@ -1,4 +1,4 @@ -identifier: mck_ra8t2/r7ka8t2lfecac/cm85 +identifier: mck_ra8t2/r7ka8t2lflcac/cm85 name: Renesas MCK-RA8T2 type: mcu arch: arm diff --git a/boards/renesas/mck_ra8t2/mck_ra8t2_r7ka8t2lfecac_cm85_defconfig b/boards/renesas/mck_ra8t2/mck_ra8t2_r7ka8t2lflcac_cm85_defconfig similarity index 100% rename from boards/renesas/mck_ra8t2/mck_ra8t2_r7ka8t2lfecac_cm85_defconfig rename to boards/renesas/mck_ra8t2/mck_ra8t2_r7ka8t2lflcac_cm85_defconfig diff --git a/dts/arm/renesas/ra/ra8/r7ka8t2lfecac.dtsi b/dts/arm/renesas/ra/ra8/r7ka8t2lflcac.dtsi similarity index 100% rename from dts/arm/renesas/ra/ra8/r7ka8t2lfecac.dtsi rename to dts/arm/renesas/ra/ra8/r7ka8t2lflcac.dtsi diff --git a/dts/arm/renesas/ra/ra8/r7ka8t2lfecac_cm85.dtsi b/dts/arm/renesas/ra/ra8/r7ka8t2lflcac_cm85.dtsi similarity index 76% rename from dts/arm/renesas/ra/ra8/r7ka8t2lfecac_cm85.dtsi rename to dts/arm/renesas/ra/ra8/r7ka8t2lflcac_cm85.dtsi index bd47c88aa9d0..c6cebc406c59 100644 --- a/dts/arm/renesas/ra/ra8/r7ka8t2lfecac_cm85.dtsi +++ b/dts/arm/renesas/ra/ra8/r7ka8t2lflcac_cm85.dtsi @@ -5,6 +5,6 @@ */ #include -#include +#include /delete-node/ &cpu1; diff --git a/samples/drivers/counter/alarm/boards/mck_ra8t2_r7ka8t2lfecac_cm85.overlay b/samples/drivers/counter/alarm/boards/mck_ra8t2_r7ka8t2lflcac_cm85.overlay similarity index 100% rename from samples/drivers/counter/alarm/boards/mck_ra8t2_r7ka8t2lfecac_cm85.overlay rename to samples/drivers/counter/alarm/boards/mck_ra8t2_r7ka8t2lflcac_cm85.overlay diff --git a/soc/renesas/ra/ra8t2/Kconfig b/soc/renesas/ra/ra8t2/Kconfig index c41407520a1d..ae5d44d29a1a 100644 --- a/soc/renesas/ra/ra8t2/Kconfig +++ b/soc/renesas/ra/ra8t2/Kconfig @@ -16,11 +16,11 @@ config SOC_SERIES_RA8T2 select SOC_EARLY_INIT_HOOK select HAS_PM -config SOC_R7KA8T2LFECAC_CM85 +config SOC_R7KA8T2LFLCAC_CM85 select CPU_CORTEX_M85 select GPIO_RA_HAS_VBTICTLR -config SOC_R7KA8T2LFECAC_CM33 +config SOC_R7KA8T2LFLCAC_CM33 select CPU_CORTEX_M33 select SOC_RA_SECOND_CORE_BUILD @@ -28,14 +28,14 @@ if SOC_SERIES_RA8T2 config RENESAS_PN_ROM_SIZE hex - default 0x100000 if SOC_R7KA8T2LFECAC + default 0x100000 if SOC_R7KA8T2LFLCAC help Code MRAM and Flash size config RENESAS_PN_PACKAGE_TYPE int range 1 4 - default 2 if SOC_R7KA8T2LFECAC + default 2 if SOC_R7KA8T2LFLCAC help Package type: 1 -> AB: LFBGA 224 pins @@ -45,7 +45,7 @@ config RENESAS_PN_PACKAGE_TYPE config RENESAS_PN_FEATURE_SET hex - default 0x4c if SOC_R7KA8T2LFECAC + default 0x4c if SOC_R7KA8T2LFLCAC help Feature set (Convert the feature set character into its ASCII hex value): - A (0x41): Single Core (CM85 only), EtherCAT slave controller is not available @@ -55,7 +55,7 @@ config RENESAS_PN_FEATURE_SET config RENESAS_PN_NUMBER_OF_CORES int range 1 2 - default 2 if SOC_R7KA8T2LFECAC + default 2 if SOC_R7KA8T2LFLCAC help Number of SoC cores diff --git a/soc/renesas/ra/ra8t2/Kconfig.defconfig b/soc/renesas/ra/ra8t2/Kconfig.defconfig index 464f124c9213..438d992573b3 100644 --- a/soc/renesas/ra/ra8t2/Kconfig.defconfig +++ b/soc/renesas/ra/ra8t2/Kconfig.defconfig @@ -11,8 +11,8 @@ DT_CPUCLK1_PATH := $(dt_nodelabel_path,cpuclk1) DT_LOCO_PATH := $(dt_nodelabel_path,loco) config SYS_CLOCK_HW_CYCLES_PER_SEC - default $(dt_node_int_prop_int,$(DT_CPUCLK0_PATH),clock-frequency) if SOC_R7KA8T2LFECAC_CM85 && CORTEX_M_SYSTICK - default $(dt_node_int_prop_int,$(DT_CPUCLK1_PATH),clock-frequency) if SOC_R7KA8T2LFECAC_CM33 && CORTEX_M_SYSTICK + default $(dt_node_int_prop_int,$(DT_CPUCLK0_PATH),clock-frequency) if SOC_R7KA8T2LFLCAC_CM85 && CORTEX_M_SYSTICK + default $(dt_node_int_prop_int,$(DT_CPUCLK1_PATH),clock-frequency) if SOC_R7KA8T2LFLCAC_CM33 && CORTEX_M_SYSTICK default $(dt_node_int_prop_int,$(DT_LOCO_PATH),clock-frequency) if RENESAS_RA_ULPT_TIMER config CORTEX_M_SYSTICK diff --git a/soc/renesas/ra/ra8t2/Kconfig.soc b/soc/renesas/ra/ra8t2/Kconfig.soc index 0a68a17b393e..55ad88befb71 100644 --- a/soc/renesas/ra/ra8t2/Kconfig.soc +++ b/soc/renesas/ra/ra8t2/Kconfig.soc @@ -7,22 +7,22 @@ config SOC_SERIES_RA8T2 help Renesas RA8T2 series -config SOC_R7KA8T2LFECAC +config SOC_R7KA8T2LFLCAC bool select SOC_SERIES_RA8T2 help - R7KA8T2LFECAC + R7KA8T2LFLCAC -config SOC_R7KA8T2LFECAC_CM85 +config SOC_R7KA8T2LFLCAC_CM85 bool - select SOC_R7KA8T2LFECAC + select SOC_R7KA8T2LFLCAC -config SOC_R7KA8T2LFECAC_CM33 +config SOC_R7KA8T2LFLCAC_CM33 bool - select SOC_R7KA8T2LFECAC + select SOC_R7KA8T2LFLCAC config SOC_SERIES default "ra8t2" if SOC_SERIES_RA8T2 config SOC - default "r7ka8t2lfecac" if SOC_R7KA8T2LFECAC + default "r7ka8t2lflcac" if SOC_R7KA8T2LFLCAC diff --git a/soc/renesas/ra/soc.yml b/soc/renesas/ra/soc.yml index 1f8f49ee0efa..4c252cc39789 100644 --- a/soc/renesas/ra/soc.yml +++ b/soc/renesas/ra/soc.yml @@ -93,7 +93,7 @@ family: - name: cm33 - name: ra8t2 socs: - - name: r7ka8t2lfecac + - name: r7ka8t2lflcac cpuclusters: - name: cm85 - name: cm33 diff --git a/tests/drivers/can/api/boards/mck_ra8t2_r7ka8t2lfecac_cm85.overlay b/tests/drivers/can/api/boards/mck_ra8t2_r7ka8t2lflcac_cm85.overlay similarity index 100% rename from tests/drivers/can/api/boards/mck_ra8t2_r7ka8t2lfecac_cm85.overlay rename to tests/drivers/can/api/boards/mck_ra8t2_r7ka8t2lflcac_cm85.overlay diff --git a/tests/drivers/can/timing/boards/mck_ra8t2_r7ka8t2lfecac_cm85.overlay b/tests/drivers/can/timing/boards/mck_ra8t2_r7ka8t2lflcac_cm85.overlay similarity index 100% rename from tests/drivers/can/timing/boards/mck_ra8t2_r7ka8t2lfecac_cm85.overlay rename to tests/drivers/can/timing/boards/mck_ra8t2_r7ka8t2lflcac_cm85.overlay diff --git a/tests/drivers/clock_control/pwm_clock/boards/mck_ra8t2_r7ka8t2lfecac_cm85.overlay b/tests/drivers/clock_control/pwm_clock/boards/mck_ra8t2_r7ka8t2lflcac_cm85.overlay similarity index 100% rename from tests/drivers/clock_control/pwm_clock/boards/mck_ra8t2_r7ka8t2lfecac_cm85.overlay rename to tests/drivers/clock_control/pwm_clock/boards/mck_ra8t2_r7ka8t2lflcac_cm85.overlay diff --git a/tests/drivers/comparator/gpio_loopback/boards/mck_ra8t2_r7ka8t2lfecac_cm85.overlay b/tests/drivers/comparator/gpio_loopback/boards/mck_ra8t2_r7ka8t2lflcac_cm85.overlay similarity index 100% rename from tests/drivers/comparator/gpio_loopback/boards/mck_ra8t2_r7ka8t2lfecac_cm85.overlay rename to tests/drivers/comparator/gpio_loopback/boards/mck_ra8t2_r7ka8t2lflcac_cm85.overlay diff --git a/tests/drivers/counter/counter_basic_api/boards/mck_ra8t2_r7ka8t2lfecac_cm85.overlay b/tests/drivers/counter/counter_basic_api/boards/mck_ra8t2_r7ka8t2lflcac_cm85.overlay similarity index 100% rename from tests/drivers/counter/counter_basic_api/boards/mck_ra8t2_r7ka8t2lfecac_cm85.overlay rename to tests/drivers/counter/counter_basic_api/boards/mck_ra8t2_r7ka8t2lflcac_cm85.overlay diff --git a/tests/drivers/i2c/i2c_api/boards/mck_ra8t2_r7ka8t2lfecac_cm85.conf b/tests/drivers/i2c/i2c_api/boards/mck_ra8t2_r7ka8t2lflcac_cm85.conf similarity index 100% rename from tests/drivers/i2c/i2c_api/boards/mck_ra8t2_r7ka8t2lfecac_cm85.conf rename to tests/drivers/i2c/i2c_api/boards/mck_ra8t2_r7ka8t2lflcac_cm85.conf diff --git a/tests/drivers/i2c/i2c_api/boards/mck_ra8t2_r7ka8t2lfecac_cm85.overlay b/tests/drivers/i2c/i2c_api/boards/mck_ra8t2_r7ka8t2lflcac_cm85.overlay similarity index 100% rename from tests/drivers/i2c/i2c_api/boards/mck_ra8t2_r7ka8t2lfecac_cm85.overlay rename to tests/drivers/i2c/i2c_api/boards/mck_ra8t2_r7ka8t2lflcac_cm85.overlay diff --git a/tests/drivers/i2c/i2c_api/boards/mck_ra8t2_r7ka8t2lfecac_cm85_sci_b_i2c.conf b/tests/drivers/i2c/i2c_api/boards/mck_ra8t2_r7ka8t2lflcac_cm85_sci_b_i2c.conf similarity index 100% rename from tests/drivers/i2c/i2c_api/boards/mck_ra8t2_r7ka8t2lfecac_cm85_sci_b_i2c.conf rename to tests/drivers/i2c/i2c_api/boards/mck_ra8t2_r7ka8t2lflcac_cm85_sci_b_i2c.conf diff --git a/tests/drivers/i2c/i2c_api/boards/mck_ra8t2_r7ka8t2lfecac_cm85_sci_b_i2c.overlay b/tests/drivers/i2c/i2c_api/boards/mck_ra8t2_r7ka8t2lflcac_cm85_sci_b_i2c.overlay similarity index 100% rename from tests/drivers/i2c/i2c_api/boards/mck_ra8t2_r7ka8t2lfecac_cm85_sci_b_i2c.overlay rename to tests/drivers/i2c/i2c_api/boards/mck_ra8t2_r7ka8t2lflcac_cm85_sci_b_i2c.overlay diff --git a/tests/drivers/i2c/i2c_api/testcase.yaml b/tests/drivers/i2c/i2c_api/testcase.yaml index 81a2c1937239..c56a61649792 100644 --- a/tests/drivers/i2c/i2c_api/testcase.yaml +++ b/tests/drivers/i2c/i2c_api/testcase.yaml @@ -27,7 +27,7 @@ tests: platform_allow: - ek_ra8p1/r7ka8p1kflcac/cm85 - ek_ra8p1/r7ka8p1kflcac/cm33 - - mck_ra8t2/r7ka8t2lfecac/cm85 + - mck_ra8t2/r7ka8t2lflcac/cm85 - ek_ra8d2/r7ka8d2kflcac/cm85 - ek_ra8m2/r7ka8m2jflcac/cm85 extra_args: diff --git a/tests/drivers/pwm/pwm_api/boards/mck_ra8t2_r7ka8t2lfecac_cm85.overlay b/tests/drivers/pwm/pwm_api/boards/mck_ra8t2_r7ka8t2lflcac_cm85.overlay similarity index 100% rename from tests/drivers/pwm/pwm_api/boards/mck_ra8t2_r7ka8t2lfecac_cm85.overlay rename to tests/drivers/pwm/pwm_api/boards/mck_ra8t2_r7ka8t2lflcac_cm85.overlay diff --git a/tests/drivers/pwm/pwm_loopback/boards/mck_ra8t2_r7ka8t2lfecac_cm85.overlay b/tests/drivers/pwm/pwm_loopback/boards/mck_ra8t2_r7ka8t2lflcac_cm85.overlay similarity index 100% rename from tests/drivers/pwm/pwm_loopback/boards/mck_ra8t2_r7ka8t2lfecac_cm85.overlay rename to tests/drivers/pwm/pwm_loopback/boards/mck_ra8t2_r7ka8t2lflcac_cm85.overlay diff --git a/tests/drivers/spi/spi_loopback/boards/mck_ra8t2_r7ka8t2lfecac_cm85.conf b/tests/drivers/spi/spi_loopback/boards/mck_ra8t2_r7ka8t2lflcac_cm85.conf similarity index 100% rename from tests/drivers/spi/spi_loopback/boards/mck_ra8t2_r7ka8t2lfecac_cm85.conf rename to tests/drivers/spi/spi_loopback/boards/mck_ra8t2_r7ka8t2lflcac_cm85.conf diff --git a/tests/drivers/spi/spi_loopback/boards/mck_ra8t2_r7ka8t2lfecac_cm85.overlay b/tests/drivers/spi/spi_loopback/boards/mck_ra8t2_r7ka8t2lflcac_cm85.overlay similarity index 100% rename from tests/drivers/spi/spi_loopback/boards/mck_ra8t2_r7ka8t2lfecac_cm85.overlay rename to tests/drivers/spi/spi_loopback/boards/mck_ra8t2_r7ka8t2lflcac_cm85.overlay diff --git a/tests/drivers/spi/spi_loopback/boards/mck_ra8t2_r7ka8t2lfecac_cm85_sci_b_spi.overlay b/tests/drivers/spi/spi_loopback/boards/mck_ra8t2_r7ka8t2lflcac_cm85_sci_b_spi.overlay similarity index 100% rename from tests/drivers/spi/spi_loopback/boards/mck_ra8t2_r7ka8t2lfecac_cm85_sci_b_spi.overlay rename to tests/drivers/spi/spi_loopback/boards/mck_ra8t2_r7ka8t2lflcac_cm85_sci_b_spi.overlay diff --git a/tests/drivers/spi/spi_loopback/testcase.yaml b/tests/drivers/spi/spi_loopback/testcase.yaml index 55e47bbc7340..21f50ed49252 100644 --- a/tests/drivers/spi/spi_loopback/testcase.yaml +++ b/tests/drivers/spi/spi_loopback/testcase.yaml @@ -409,7 +409,7 @@ tests: - ek_ra8p1/r7ka8p1kflcac/cm85 platform_allow: - ek_ra8p1/r7ka8p1kflcac/cm85 - - mck_ra8t2/r7ka8t2lfecac/cm85 + - mck_ra8t2/r7ka8t2lflcac/cm85 extra_args: - DTC_OVERLAY_FILE="boards/${BOARD}${NORMALIZED_BOARD_QUALIFIERS}_sci_b_spi.overlay" - CONF_FILE="prj.conf" # to exclude "boards/${BOARD}${NORMALIZED_BOARD_QUALIFIERS}.overlay" @@ -419,7 +419,7 @@ tests: - ek_ra8p1/r7ka8p1kflcac/cm85 platform_allow: - ek_ra8p1/r7ka8p1kflcac/cm85 - - mck_ra8t2/r7ka8t2lfecac/cm85 + - mck_ra8t2/r7ka8t2lflcac/cm85 extra_configs: - CONFIG_SPI_ASYNC=n extra_args: diff --git a/tests/drivers/uart/uart_async_api/boards/mck_ra8t2_r7ka8t2lfecac_cm85.overlay b/tests/drivers/uart/uart_async_api/boards/mck_ra8t2_r7ka8t2lflcac_cm85.overlay similarity index 100% rename from tests/drivers/uart/uart_async_api/boards/mck_ra8t2_r7ka8t2lfecac_cm85.overlay rename to tests/drivers/uart/uart_async_api/boards/mck_ra8t2_r7ka8t2lflcac_cm85.overlay diff --git a/tests/subsys/canbus/isotp/conformance/boards/mck_ra8t2_r7ka8t2lfecac_cm85.overlay b/tests/subsys/canbus/isotp/conformance/boards/mck_ra8t2_r7ka8t2lflcac_cm85.overlay similarity index 100% rename from tests/subsys/canbus/isotp/conformance/boards/mck_ra8t2_r7ka8t2lfecac_cm85.overlay rename to tests/subsys/canbus/isotp/conformance/boards/mck_ra8t2_r7ka8t2lflcac_cm85.overlay diff --git a/tests/subsys/canbus/isotp/implementation/boards/mck_ra8t2_r7ka8t2lfecac_cm85.overlay b/tests/subsys/canbus/isotp/implementation/boards/mck_ra8t2_r7ka8t2lflcac_cm85.overlay similarity index 100% rename from tests/subsys/canbus/isotp/implementation/boards/mck_ra8t2_r7ka8t2lfecac_cm85.overlay rename to tests/subsys/canbus/isotp/implementation/boards/mck_ra8t2_r7ka8t2lflcac_cm85.overlay diff --git a/tests/subsys/fs/ext2/testcase.yaml b/tests/subsys/fs/ext2/testcase.yaml index 815ef4c424ed..d86efee51732 100644 --- a/tests/subsys/fs/ext2/testcase.yaml +++ b/tests/subsys/fs/ext2/testcase.yaml @@ -32,7 +32,7 @@ tests: - ek_ra8m1 - ek_ra8d1 - ek_ra8p1/r7ka8p1kflcac/cm85 - - mck_ra8t2/r7ka8t2lfecac/cm85 + - mck_ra8t2/r7ka8t2lflcac/cm85 - ek_ra8p1/r7ka8p1kflcac/cm33 - ek_ra8d2/r7ka8d2kflcac/cm85 - ek_ra8m2/r7ka8m2jflcac/cm85 @@ -50,7 +50,7 @@ tests: - platform:ek_ra8d2/r7ka8d2kflcac/cm85:CONFIG_EXT2_DISK_STARTING_SECTOR=0 - platform:ek_ra8m2/r7ka8m2jflcac/cm85:CONFIG_EXT2_DISK_STARTING_SECTOR=0 - platform:mck_ra8t1/r7fa8t1ahecbd:CONFIG_EXT2_DISK_STARTING_SECTOR=0 - - platform:mck_ra8t2/r7ka8t2lfecac/cm85:CONFIG_EXT2_DISK_STARTING_SECTOR=0 + - platform:mck_ra8t2/r7ka8t2lflcac/cm85:CONFIG_EXT2_DISK_STARTING_SECTOR=0 filesystem.ext2.flash: platform_allow: diff --git a/tests/subsys/fs/fat_fs_api/boards/mck_ra8t2_r7ka8t2lfecac_cm85.conf b/tests/subsys/fs/fat_fs_api/boards/mck_ra8t2_r7ka8t2lflcac_cm85.conf similarity index 100% rename from tests/subsys/fs/fat_fs_api/boards/mck_ra8t2_r7ka8t2lfecac_cm85.conf rename to tests/subsys/fs/fat_fs_api/boards/mck_ra8t2_r7ka8t2lflcac_cm85.conf diff --git a/tests/subsys/pm/power_mgmt_soc/testcase.yaml b/tests/subsys/pm/power_mgmt_soc/testcase.yaml index 7e0bc1dc345b..f5b87c53291b 100644 --- a/tests/subsys/pm/power_mgmt_soc/testcase.yaml +++ b/tests/subsys/pm/power_mgmt_soc/testcase.yaml @@ -26,7 +26,7 @@ tests: - ek_ra8d1 - mck_ra8t1 - ek_ra8p1/r7ka8p1kflcac/cm85 - - mck_ra8t2/r7ka8t2lfecac/cm85 + - mck_ra8t2/r7ka8t2lflcac/cm85 - ek_ra8d2/r7ka8d2kflcac/cm85 - ek_ra8m2/r7ka8m2jflcac/cm85 - frdm_mcxn236 From 71389b3dd535567dd2f11102609a8a28d1c24ab0 Mon Sep 17 00:00:00 2001 From: Khai Cao Date: Tue, 13 Jan 2026 06:37:01 +0000 Subject: [PATCH 2302/3659] doc: releases: document ek_ra8t2/r7ka8t2lfecac rename Document the board rename from ek_ra8t2/r7ka8t2lfecac/cm85 to ek_ra8t2/r7ka8t2lflcac/cm85 in the Zephyr v4.4.0 migration guide. Signed-off-by: Khai Cao --- doc/releases/migration-guide-4.4.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/releases/migration-guide-4.4.rst b/doc/releases/migration-guide-4.4.rst index 11498e15a83c..bc576bc5d726 100644 --- a/doc/releases/migration-guide-4.4.rst +++ b/doc/releases/migration-guide-4.4.rst @@ -46,6 +46,8 @@ Boards in the respective board CMakeLists.txt files. Applications that depended on these definitions being globally available may need to be updated. (:github:`101322`) +* Renesas ``ek_ra8t2/r7ka8t2lfecac/cm85`` is renamed to ``ek_ra8t2/r7ka8t2lflcac/cm85``. + * NXP has changed the scope of some in-tree compile flags to limit their visibility to only where they are needed. Out-of-tree applications or boards that depended on these flags being globally available may need to add them to their own CMakeLists.txt files to ensure they continue to build From 917404f5d7a069a6086d734d19519199822b4abd Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Tue, 13 Jan 2026 16:41:40 +0000 Subject: [PATCH 2303/3659] mgmt: mcumgr: transport: uart: Change Kconfig to depends on Changes CONFIG_MCUMGR_TRANSPORT_UART from selecting CONFIG_UART_MCUMGR to instead of depending upon it, as it should never have selected a driver Kconfig and instead always depended upon it, and is needed for supporting different UART transports Signed-off-by: Jamie McCrae --- samples/subsys/mgmt/mcumgr/smp_svr/cdc.conf | 1 + samples/subsys/mgmt/mcumgr/smp_svr/serial.conf | 1 + subsys/mgmt/mcumgr/transport/Kconfig.uart | 2 +- tests/subsys/mgmt/mcumgr/all_options/other-options.conf | 1 + 4 files changed, 4 insertions(+), 1 deletion(-) diff --git a/samples/subsys/mgmt/mcumgr/smp_svr/cdc.conf b/samples/subsys/mgmt/mcumgr/smp_svr/cdc.conf index 436ff459dcc4..3110440fc0b4 100644 --- a/samples/subsys/mgmt/mcumgr/smp_svr/cdc.conf +++ b/samples/subsys/mgmt/mcumgr/smp_svr/cdc.conf @@ -2,6 +2,7 @@ CONFIG_SERIAL=y CONFIG_UART_LINE_CTRL=y CONFIG_CONSOLE=y +CONFIG_UART_MCUMGR=y CONFIG_USB_DEVICE_STACK_NEXT=y CONFIG_CDC_ACM_SERIAL_INITIALIZE_AT_BOOT=y # USB backend is serial device diff --git a/samples/subsys/mgmt/mcumgr/smp_svr/serial.conf b/samples/subsys/mgmt/mcumgr/smp_svr/serial.conf index 47d4e8d0b853..0800da1ff366 100644 --- a/samples/subsys/mgmt/mcumgr/smp_svr/serial.conf +++ b/samples/subsys/mgmt/mcumgr/smp_svr/serial.conf @@ -1,5 +1,6 @@ # Enable the serial MCUmgr transport. CONFIG_BASE64=y CONFIG_CRC=y +CONFIG_UART_MCUMGR=y CONFIG_MCUMGR_TRANSPORT_UART=y CONFIG_CONSOLE=y diff --git a/subsys/mgmt/mcumgr/transport/Kconfig.uart b/subsys/mgmt/mcumgr/transport/Kconfig.uart index 096819b0c20e..32c65c5a5ca7 100644 --- a/subsys/mgmt/mcumgr/transport/Kconfig.uart +++ b/subsys/mgmt/mcumgr/transport/Kconfig.uart @@ -14,7 +14,7 @@ menuconfig MCUMGR_TRANSPORT_UART depends on CONSOLE depends on BASE64 depends on CRC - select UART_MCUMGR + depends on UART_MCUMGR help Enables handling of SMP commands received over UART. This is a lightweight alternative to MCUMGR_TRANSPORT_SHELL. It allows MCUmgr commands to be received over UART without diff --git a/tests/subsys/mgmt/mcumgr/all_options/other-options.conf b/tests/subsys/mgmt/mcumgr/all_options/other-options.conf index 01a9979b2cbc..74ce1790e678 100644 --- a/tests/subsys/mgmt/mcumgr/all_options/other-options.conf +++ b/tests/subsys/mgmt/mcumgr/all_options/other-options.conf @@ -15,6 +15,7 @@ CONFIG_MCUMGR_GRP_OS_INFO_BUILD_DATE_TIME=y CONFIG_MCUMGR_GRP_SHELL_LEGACY_RC_RETURN_CODE=y CONFIG_MCUMGR_GRP_SETTINGS_BUFFER_TYPE_HEAP=y CONFIG_COMMON_LIBC_MALLOC_ARENA_SIZE=2048 +CONFIG_UART_MCUMGR=y CONFIG_MCUMGR_TRANSPORT_SHELL=n CONFIG_MCUMGR_TRANSPORT_UART=y CONFIG_MCUMGR_TRANSPORT_SHELL_INPUT_TIMEOUT=n From b0467a0313521b310326f25109ea685a7bb74140 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Wed, 14 Jan 2026 10:35:38 +0000 Subject: [PATCH 2304/3659] doc: release: migration_guide: 4.4: Add MCUmgr change Adds a note on a required change for MCUmgr if using the UART transport Signed-off-by: Jamie McCrae --- doc/releases/migration-guide-4.4.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/doc/releases/migration-guide-4.4.rst b/doc/releases/migration-guide-4.4.rst index bc576bc5d726..bfd40de5598a 100644 --- a/doc/releases/migration-guide-4.4.rst +++ b/doc/releases/migration-guide-4.4.rst @@ -755,6 +755,15 @@ Libsbc * Libsbc (sbc.c and sbc.h) is moved under the Bluetooth subsystem. The sbc.h is in include/zephyr/bluetooth now. +Management +========== + +* MCUmgr + + * If using :kconfig:option:`CONFIG_MCUMGR_TRANSPORT_UART` then + :kconfig:option:`CONFIG_UART_MCUMGR` must now also be selected, this has changed to be + ``depends on`` rather than ``select``. + Tracing ======== From 4edfd97621241b9ba4f8eead5f913c1d2129db62 Mon Sep 17 00:00:00 2001 From: Jiafei Pan Date: Thu, 15 Jan 2026 18:25:25 +0800 Subject: [PATCH 2305/3659] dts: arm64: mimx943; add MSI device ID for ENET3 port ENET3 port is internal port for switch, add MSI device ID to enable interrupt for it. Signed-off-by: Jiafei Pan --- dts/arm64/nxp/nxp_mimx943_a55.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/dts/arm64/nxp/nxp_mimx943_a55.dtsi b/dts/arm64/nxp/nxp_mimx943_a55.dtsi index 72a9e103bef8..e67eb8c106e4 100644 --- a/dts/arm64/nxp/nxp_mimx943_a55.dtsi +++ b/dts/arm64/nxp/nxp_mimx943_a55.dtsi @@ -526,6 +526,7 @@ reg = <0x4cd40000 0x40000>, <0x4ca00000 0x1000>; reg-names = "port", "pfconfig"; + msi-device-id = <0x68>; mac-index = <3>; si-index = <3>; phy-connection-type = "internal"; From b1946cba2a06f93a5cbd8360d680ce6f4ca838e8 Mon Sep 17 00:00:00 2001 From: Jiafei Pan Date: Thu, 15 Jan 2026 18:23:16 +0800 Subject: [PATCH 2306/3659] boards: imx943_evk: use 100M PHY for net switch port Currently the PHY for 2.5G SGMII is not enabled, so could only use 100M PHY for two switch ports on the board. Signed-off-by: Jiafei Pan --- boards/nxp/imx943_evk/doc/index.rst | 4 ++++ boards/nxp/imx943_evk/imx943_evk_mimx94398_a55.dts | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/boards/nxp/imx943_evk/doc/index.rst b/boards/nxp/imx943_evk/doc/index.rst index 1f76384616ec..c7e44253915d 100644 --- a/boards/nxp/imx943_evk/doc/index.rst +++ b/boards/nxp/imx943_evk/doc/index.rst @@ -73,6 +73,10 @@ For A55 Core, ENET0, ENETC1, ENETC2 ports are enabled by default, so no overlay needed, but NETC depends on GIC ITS, so need to make sure to allocate heap memory to be larger than 851968 byes by setting CONFIG_HEAP_MEM_POOL_SIZE. +On the EVK board, switch port0 and port2 are connected to both SGMII port (SGMII-swp0 +and SGMII-swp1) and 100M port (swp0 and swp1), currently only 100M port (swp0 and swp1) +is enabled, so could connect to 100M port for verify two switch ports. + The two switch ports could be verified via :zephyr:code-sample:`dsa` on M33 core or on A55 Core, for example for A55 Core: diff --git a/boards/nxp/imx943_evk/imx943_evk_mimx94398_a55.dts b/boards/nxp/imx943_evk/imx943_evk_mimx94398_a55.dts index 31a696846253..c76b046ded5d 100644 --- a/boards/nxp/imx943_evk/imx943_evk_mimx94398_a55.dts +++ b/boards/nxp/imx943_evk/imx943_evk_mimx94398_a55.dts @@ -57,13 +57,13 @@ phy0: phy@2 { compatible = "ethernet-phy"; - reg = <0xf>; + reg = <0x2>; status = "disabled"; }; phy1: phy@3 { compatible = "ethernet-phy"; - reg = <0x10>; + reg = <0x3>; status = "disabled"; }; From 1a12292846613e7742efb6d890696f0ac355979a Mon Sep 17 00:00:00 2001 From: Gaetan Perrot Date: Thu, 15 Jan 2026 22:30:58 +0900 Subject: [PATCH 2307/3659] tests: drivers: flash: negative_tests: fix write/fill alignment tests The negative flash write and fill tests assumed that unaligned offsets are always invalid. This is not true for flash drivers reporting a write_block_size of 1, where all offsets and sizes are naturally aligned. Condition the unaligned offset and size tests on the actual write_block_size reported by the driver to avoid false failures and ensure the tests follow the flash API contract. No functional change for drivers with write_block_size > 1. Signed-off-by: Gaetan Perrot --- tests/drivers/flash/negative_tests/src/main.c | 58 +++++++++++++++---- 1 file changed, 48 insertions(+), 10 deletions(-) diff --git a/tests/drivers/flash/negative_tests/src/main.c b/tests/drivers/flash/negative_tests/src/main.c index fa3723b52312..a07dff5c6a60 100644 --- a/tests/drivers/flash/negative_tests/src/main.c +++ b/tests/drivers/flash/negative_tests/src/main.c @@ -133,17 +133,37 @@ ZTEST(flash_driver_negative, test_negative_flash_fill) rc = flash_fill(flash_dev, fill_val, (TEST_FLASH_START + TEST_FLASH_SIZE), page_info.size); zassert_true(rc < 0, "Invalid use of flash_fill returned %d", rc); - /* Check error returned when filling unaligned memory */ - rc = flash_fill(flash_dev, fill_val, (TEST_AREA_OFFSET + 1), page_info.size); - zassert_true(rc < 0, "Invalid use of flash_fill returned %d", rc); - rc = flash_fill(flash_dev, fill_val, TEST_AREA_OFFSET, (page_info.size + 1)); - zassert_true(rc < 0, "Invalid use of flash_fill returned %d", rc); - /* Filling 0 bytes shall succeed */ rc = flash_fill(flash_dev, fill_val, TEST_AREA_OFFSET, 0); zassert_true(rc == 0, "flash_fill 0 bytes returned %d", rc); } +ZTEST(flash_driver_negative, test_negative_flash_fill_unaligned) +{ + int rc; + uint8_t fill_val = 0xA; /* Dummy value */ + size_t write_block_size; + +#if !defined(TEST_AREA) + /* Flash memory boundaries are correctly calculated + * only for storage_partition. + */ + ztest_test_skip(); +#endif + + write_block_size = flash_get_write_block_size(flash_dev); + + if (write_block_size <= 1) { + ztest_test_skip(); + } + /* Check error returned when filling unaligned memory */ + rc = flash_fill(flash_dev, fill_val, TEST_AREA_OFFSET + 1, page_info.size); + zassert_true(rc < 0, "Invalid use of flash_fill returned %d", rc); + + rc = flash_fill(flash_dev, fill_val, TEST_AREA_OFFSET, page_info.size + 1); + zassert_true(rc < 0, "Invalid use of flash_fill returned %d", rc); +} + ZTEST(flash_driver_negative, test_negative_flash_flatten) { int rc; @@ -234,10 +254,6 @@ ZTEST(flash_driver_negative, test_negative_flash_write) rc = flash_write(flash_dev, (TEST_FLASH_START + TEST_FLASH_SIZE), expected, page_info.size); zassert_true(rc < 0, "Invalid use of flash_write returned %d", rc); - /* Check error returned when writing at unaligned memory */ - rc = flash_write(flash_dev, (TEST_AREA_OFFSET + 1), expected, page_info.size); - zassert_true(rc < 0, "Invalid use of flash_write returned %d", rc); - /* Check error returned when writing too large chunk of memory */ rc = flash_write(flash_dev, TEST_AREA_OFFSET, expected, (TEST_FLASH_SIZE + 1)); zassert_true(rc < 0, "Invalid use of flash_write returned %d", rc); @@ -247,4 +263,26 @@ ZTEST(flash_driver_negative, test_negative_flash_write) zassert_true(rc == 0, "flash_write 0 bytes returned %d", rc); } +ZTEST(flash_driver_negative, test_negative_flash_write_unaligned) +{ + int rc; + size_t write_block_size; + +#if !defined(TEST_AREA) + /* Flash memory boundaries are correctly calculated + * only for storage_partition. + */ + ztest_test_skip(); +#endif + + write_block_size = flash_get_write_block_size(flash_dev); + + if (write_block_size <= 1) { + ztest_test_skip(); + } + /* Check error returned when writing at unaligned memory */ + rc = flash_write(flash_dev, (TEST_AREA_OFFSET + 1), expected, page_info.size); + zassert_true(rc < 0, "Invalid use of flash_write returned %d", rc); +} + ZTEST_SUITE(flash_driver_negative, NULL, flash_driver_setup, NULL, NULL, NULL); From fd8188a408240090498bac31597148f41cdc160e Mon Sep 17 00:00:00 2001 From: Adrian Warecki Date: Thu, 15 Jan 2026 16:53:44 +0100 Subject: [PATCH 2308/3659] xtensa: Remove saving EXCCAUSE in BSA from _Level1Vector Remove saving EXCCAUSE register in BSA through the _Level1Vector handler. These value are later overwritten by the ODD_REG_SAVE macro called by EXCINT_HANDLER, so saving it here is pointless. Signed-off-by: Adrian Warecki --- arch/xtensa/include/xtensa_asm2.inc.S | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/arch/xtensa/include/xtensa_asm2.inc.S b/arch/xtensa/include/xtensa_asm2.inc.S index 9d8ce2bf7b8a..6a173eb0edab 100644 --- a/arch/xtensa/include/xtensa_asm2.inc.S +++ b/arch/xtensa/include/xtensa_asm2.inc.S @@ -726,13 +726,10 @@ _not_triple_fault: s32i a2, a1, ___xtensa_irq_bsa_t_a2_OFFSET s32i a3, a1, ___xtensa_irq_bsa_t_a3_OFFSET - /* Save registers needed for handling the exception as - * these registers can be overwritten during nested + /* Save register needed for handling the exception as + * this register can be overwritten during nested * exceptions. */ - rsr.exccause a0 - s32i a0, a1, ___xtensa_irq_bsa_t_exccause_OFFSET - rsr.excvaddr a0 s32i a0, a1, ___xtensa_irq_bsa_t_excvaddr_OFFSET From c1a2b3be459d4f34d31ae54774fd57e96438d237 Mon Sep 17 00:00:00 2001 From: Adrian Warecki Date: Thu, 15 Jan 2026 16:50:25 +0100 Subject: [PATCH 2309/3659] xtensa: Restore the EXCCAUSE register when returning from Double Exception Preserve EXCCAUSE and EXCVADDR values on entry to _Level1Vector. Restore EXCCAUSE when exiting TLB miss exception handling in the double exception handler. During first-level exception handling, a LoadStoreTLBMissException may occur during the initial register dump to BSA. It modifies EXCCAUSE and EXCVADDR registers before they are saved in BSA. Therefore, these values must be captured as early as possible. Signed-off-by: Adrian Warecki --- arch/xtensa/core/gen_zsr.py | 2 +- arch/xtensa/core/xtensa_asm2_util.S | 4 +++ arch/xtensa/include/xtensa_asm2.inc.S | 35 ++++++++++++++++++++++----- 3 files changed, 34 insertions(+), 7 deletions(-) diff --git a/arch/xtensa/core/gen_zsr.py b/arch/xtensa/core/gen_zsr.py index cc2f243d3468..69537d08f1ee 100755 --- a/arch/xtensa/core/gen_zsr.py +++ b/arch/xtensa/core/gen_zsr.py @@ -36,7 +36,7 @@ def parse_args(): NEEDED = ["A0SAVE", "CPU"] if args.mmu: - NEEDED += ["DBLEXC", "DEPC_SAVE"] + NEEDED += ["DBLEXC", "DEPC_SAVE", "EXCCAUSE_SAVE"] if args.flush_reg: NEEDED += ["FLUSH"] diff --git a/arch/xtensa/core/xtensa_asm2_util.S b/arch/xtensa/core/xtensa_asm2_util.S index 24893db692dc..00e7b1bcd3fd 100644 --- a/arch/xtensa/core/xtensa_asm2_util.S +++ b/arch/xtensa/core/xtensa_asm2_util.S @@ -580,6 +580,10 @@ _handle_tlb_miss_dblexc: rsr.ptevaddr a0 l32i a0, a0, 0 + /* Restore EXCCAUSE and a0 values */ + rsr a0, ZSR_EXCCAUSE_SAVE + wsr.exccause a0 + rsr a0, ZSR_DBLEXC rfde #endif diff --git a/arch/xtensa/include/xtensa_asm2.inc.S b/arch/xtensa/include/xtensa_asm2.inc.S index 6a173eb0edab..89582d1abb88 100644 --- a/arch/xtensa/include/xtensa_asm2.inc.S +++ b/arch/xtensa/include/xtensa_asm2.inc.S @@ -677,17 +677,20 @@ _Level\LVL\()Vector: .if \LVL == 1 /* If there are any TLB misses during interrupt handling, * the user/kernel/double exception vector will be triggered - * to handle these misses. This results in DEPC and EXCCAUSE - * being overwritten, and then execution returned back to - * this site of TLB misses. When it gets to the C handler, - * it will not see the original cause. So stash - * the EXCCAUSE here so C handler can see the original cause. + * to handle these misses. This results in DEPC, EXCCAUSE + * and EXCVADDR being overwritten, and then execution returned + * back to this site of TLB misses. When it gets to the C handler, + * it will not see the original cause. So stash the EXCCAUSE + * and EXCVADDR here so C handler can see the original cause. * * For double exception, DEPC in saved in earlier vector * code. */ wsr a0, ZSR_A0SAVE + rsr.exccause a0 + wsr a0, ZSR_EXCCAUSE_SAVE + esync rsr a0, ZSR_DEPC_SAVE @@ -717,21 +720,41 @@ _Level\LVL\()Vector: j _TripleFault _not_triple_fault: - rsr a0, ZSR_A0SAVE .endif #endif addi a1, a1, -___xtensa_irq_bsa_t_SIZEOF + +#ifdef CONFIG_XTENSA_MMU +.if \LVL == 1 + /* Save EXCVADDR register needed for handling the exception + * as this register can be overwritten during nested + * exceptions. It has to be saved first, because + * executing the store instruction may trigger a + * TLB miss, which will modify its value. + */ + rsr.excvaddr a0 + s32i a0, a1, ___xtensa_irq_bsa_t_excvaddr_OFFSET + rsr a0, ZSR_A0SAVE +.endif +#endif + s32i a0, a1, ___xtensa_irq_bsa_t_a0_OFFSET s32i a2, a1, ___xtensa_irq_bsa_t_a2_OFFSET s32i a3, a1, ___xtensa_irq_bsa_t_a3_OFFSET +#ifdef CONFIG_XTENSA_MMU +.if \LVL != 1 +#endif /* Save register needed for handling the exception as * this register can be overwritten during nested * exceptions. */ rsr.excvaddr a0 s32i a0, a1, ___xtensa_irq_bsa_t_excvaddr_OFFSET +#ifdef CONFIG_XTENSA_MMU +.endif +#endif /* Level "1" is the exception handler, which uses a different * calling convention. No special register holds the From 0cafc3e4f69cc7199ce2c5553b0f3398695c1244 Mon Sep 17 00:00:00 2001 From: Hui Bai Date: Fri, 16 Jan 2026 14:34:20 +0800 Subject: [PATCH 2310/3659] modules: hostap: Add new APIs to set operating mode for SoftAP Add new APIs to set operating mode 11n, 11ac and 11ax for SoftAP. Currently, the 11n, 11ac and 11ax are enabled by default. Theses APIs can be used to configure operating modes enable/disable for SoftAP. Signed-off-by: Hui Bai --- modules/hostap/src/hapd_api.c | 97 +++++++++++++++++++++++++++++++++++ modules/hostap/src/hapd_api.h | 31 +++++++++++ 2 files changed, 128 insertions(+) diff --git a/modules/hostap/src/hapd_api.c b/modules/hostap/src/hapd_api.c index 699a151e4eb4..3a12826afc3c 100644 --- a/modules/hostap/src/hapd_api.c +++ b/modules/hostap/src/hapd_api.c @@ -785,6 +785,103 @@ int hostapd_ap_status(const struct device *dev, struct wifi_iface_status *status return ret; } +int hostapd_11n_cfg(const struct device *dev, uint8_t enable) +{ + int ret = 0; + struct hostapd_iface *iface; + + k_mutex_lock(&hostapd_mutex, K_FOREVER); + + iface = get_hostapd_handle(dev); + if (!iface) { + wpa_printf(MSG_ERROR, "Interface %s not found", dev->name); + ret = -ENODEV; + goto out; + } + + if (iface->state == HAPD_IFACE_ENABLED) { + wpa_printf(MSG_ERROR, "Interface %s is operational and in SAP mode", dev->name); + ret = -EACCES; + goto out; + } + + if (!hostapd_cli_cmd_v("set ieee80211n %d", enable)) { + wpa_printf(MSG_ERROR, "Failed to set ieee80211n"); + ret = -EINVAL; + goto out; + } + +out: + k_mutex_unlock(&hostapd_mutex); + return ret; +} + +#if CONFIG_WIFI_NM_WPA_SUPPLICANT_11AC +int hostapd_11ac_cfg(const struct device *dev, uint8_t enable) +{ + int ret = 0; + struct hostapd_iface *iface; + + k_mutex_lock(&hostapd_mutex, K_FOREVER); + + iface = get_hostapd_handle(dev); + if (!iface) { + wpa_printf(MSG_ERROR, "Interface %s not found", dev->name); + ret = -ENODEV; + goto out; + } + + if (iface->state == HAPD_IFACE_ENABLED) { + wpa_printf(MSG_ERROR, "Interface %s is operational and in SAP mode", dev->name); + ret = -EACCES; + goto out; + } + + if (!hostapd_cli_cmd_v("set ieee80211ac %d", enable)) { + wpa_printf(MSG_ERROR, "Failed to set ieee80211ac"); + ret = -EINVAL; + goto out; + } + +out: + k_mutex_unlock(&hostapd_mutex); + return ret; +} +#endif + +#if CONFIG_WIFI_NM_WPA_SUPPLICANT_11AX +int hostapd_11ax_cfg(const struct device *dev, uint8_t enable) +{ + int ret = 0; + struct hostapd_iface *iface; + + k_mutex_lock(&hostapd_mutex, K_FOREVER); + + iface = get_hostapd_handle(dev); + if (!iface) { + wpa_printf(MSG_ERROR, "Interface %s not found", dev->name); + ret = -ENODEV; + goto out; + } + + if (iface->state == HAPD_IFACE_ENABLED) { + wpa_printf(MSG_ERROR, "Interface %s is operational and in SAP mode", dev->name); + ret = -EACCES; + goto out; + } + + if (!hostapd_cli_cmd_v("set ieee80211ax %d", enable)) { + wpa_printf(MSG_ERROR, "Failed to set ieee80211ax"); + ret = -EINVAL; + goto out; + } + +out: + k_mutex_unlock(&hostapd_mutex); + return ret; +} +#endif + #ifdef CONFIG_WIFI_NM_HOSTAPD_WPS static int hapd_ap_wps_pbc(const struct device *dev) { diff --git a/modules/hostap/src/hapd_api.h b/modules/hostap/src/hapd_api.h index aa95a5582320..7f09d602579c 100644 --- a/modules/hostap/src/hapd_api.h +++ b/modules/hostap/src/hapd_api.h @@ -90,4 +90,35 @@ int hostapd_dpp_dispatch(const struct device *dev, struct wifi_dpp_params *param #endif /* CONFIG_WIFI_NM_HOSTAPD_AP */ #endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_DPP */ +/** + * @brief Enable or disable 11N for AP + * + * @param dev Wi-Fi interface name to use + * @param enable Enable or disable + * @return 0 for OK; -1 for ERROR + */ +int hostapd_11n_cfg(const struct device *dev, uint8_t enable); + +#if CONFIG_WIFI_NM_WPA_SUPPLICANT_11AC +/** + * @brief Enable or disable 11AC for AP + * + * @param dev Wi-Fi interface name to use + * @param enable Enable or disable + * @return 0 for OK; -1 for ERROR + */ +int hostapd_11ac_cfg(const struct device *dev, uint8_t enable); +#endif + +#if CONFIG_WIFI_NM_WPA_SUPPLICANT_11AX +/** + * @brief Enable or disable 11AX for AP + * + * @param dev Wi-Fi interface name to use + * @param enable Enable or disable + * @return 0 for OK; -1 for ERROR + */ +int hostapd_11ax_cfg(const struct device *dev, uint8_t enable); +#endif + #endif /* __HAPD_API_H_ */ From bdcb5c6b4b9a319a6165219e8acf96cd2865c09f Mon Sep 17 00:00:00 2001 From: Waqar Tahir Date: Fri, 16 Jan 2026 12:25:02 +0100 Subject: [PATCH 2311/3659] boards: nxp: mcxn947: updated partitions - Updated partitions in non-secure device tree files as tfm now supports Bl2. - Flash_base address updated for ns-app as tfm apps are now using bl2 by default. Signed-off-by: Waqar Tahir --- .../frdm_mcxn947_mcxn947_cpu0_ns.dts | 55 +++++++++++++++++-- .../frdm_mcxn947_mcxn947_cpu0_ns_defconfig | 6 +- 2 files changed, 54 insertions(+), 7 deletions(-) diff --git a/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_ns.dts b/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_ns.dts index 71cb3a93dc9c..7e4ac87cb46a 100644 --- a/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_ns.dts +++ b/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_ns.dts @@ -56,12 +56,59 @@ #size-cells = <1>; /* - * Partition sizes must be aligned - * to the flash memory sector size of 8KB. + * All partition sizes must be aligned to the flash memory sector size (8 KB). + * + * This flash layout must exactly match the upstream TF-M layout defined in + * the platform-specific `flash_layout.h`. Any modification to the layout + * must be applied consistently in both `flash_layout.h` and this file. + * + * BL2 / MCUBoot */ - slot0_ns_partition: partition@80000 { + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 DT_SIZE_K(64)>; /* 64 KB */ + }; + + /* Secure image - primary */ + slot0_partition: partition@10000 { + label = "image-0"; + reg = <0x00010000 DT_SIZE_K(288)>; /* 288 KB */ + }; + + /* Non-secure image - primary */ + slot0_ns_partition: partition@58000 { label = "image-0-nonsecure"; - reg = <0x00080000 DT_SIZE_K(512)>; + reg = <0x00058000 DT_SIZE_K(256)>; /* 256 KB */ + }; + + /* Secure image - secondary */ + slot1_partition: partition@98000 { + label = "image-1-secondary"; + reg = <0x00098000 DT_SIZE_K(288)>; /* 288 KB */ + }; + + /* Non-secure image - secondary */ + slot1_ns_partition: partition@E0000 { + label = "image-1-non-secure"; + reg = <0x000E0000 DT_SIZE_K(256)>; /* 256 KB */ + }; + + /* Protected Storage (PS) */ + tfm_ps_partition: partition@120000 { + label = "tfm-ps"; + reg = <0x00120000 DT_SIZE_K(16)>; /* 16 KB */ + }; + + /* Internal Trusted Storage (ITS) */ + tfm_its_partition: partition@124000 { + label = "tfm-its"; + reg = <0x00124000 DT_SIZE_K(16)>; /* 16 KB */ + }; + + /* OTP / NV counters */ + tfm_otp_partition: partition@128000 { + label = "tfm-otp"; + reg = <0x00128000 DT_SIZE_K(8)>; /* 8 KB */ }; }; }; diff --git a/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_ns_defconfig b/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_ns_defconfig index 9f421c6b50bb..66adee8f206b 100644 --- a/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_ns_defconfig +++ b/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_ns_defconfig @@ -1,5 +1,5 @@ # -# Copyright 2025 NXP +# Copyright 2025-2026 NXP # # SPDX-License-Identifier: Apache-2.0 # @@ -14,6 +14,6 @@ CONFIG_ARM_MPU=y CONFIG_HW_STACK_PROTECTION=y CONFIG_TRUSTED_EXECUTION_NONSECURE=y -CONFIG_TFM_BL2=n +CONFIG_TFM_BL2=y CONFIG_BUILD_WITH_TFM=y -CONFIG_FLASH_BASE_ADDRESS=0x80000 +CONFIG_FLASH_BASE_ADDRESS=0x58000 From 07384efb72bd2e9f51d4ffa8f65cc2d0fb013ca5 Mon Sep 17 00:00:00 2001 From: Waqar Tahir Date: Sun, 18 Jan 2026 22:25:31 +0100 Subject: [PATCH 2312/3659] samples: tfm_ipc: update mcxn947 board support As the board now supports TF-M with bl2, spport from sample.tfm_ipc.no_bl2 is removed and added in sample.tfm_ipc test. Signed-off-by: Waqar Tahir --- samples/tfm_integration/tfm_ipc/sample.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/tfm_integration/tfm_ipc/sample.yaml b/samples/tfm_integration/tfm_ipc/sample.yaml index b049f7a82a16..a2f26c2bca30 100644 --- a/samples/tfm_integration/tfm_ipc/sample.yaml +++ b/samples/tfm_integration/tfm_ipc/sample.yaml @@ -18,6 +18,7 @@ tests: - bl5340_dvk/nrf5340/cpuapp/ns - b_u585i_iot02a/stm32u585xx/ns - stm32h573i_dk/stm32h573xx/ns + - frdm_mcxn947/mcxn947/cpu0/ns integration_platforms: - mps2/an521/cpu0/ns harness: console @@ -37,7 +38,6 @@ tests: - nrf54l15dk/nrf54l15/cpuapp/ns - nrf54l15dk/nrf54l10/cpuapp/ns - nrf54lm20dk/nrf54lm20a/cpuapp/ns - - frdm_mcxn947/mcxn947/cpu0/ns extra_configs: - CONFIG_TFM_BL2=n harness: console From 8e7198392a2abb5e977f33a60dd91222080da2f7 Mon Sep 17 00:00:00 2001 From: Waqar Tahir Date: Fri, 16 Jan 2026 12:26:58 +0100 Subject: [PATCH 2313/3659] manifest: tf-m: BL2 support mcxn947 Updated TF-M repo for BL2 support in mcxn947 Signed-off-by: Waqar Tahir --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index a51f8cf3962b..55b322fa978b 100644 --- a/west.yml +++ b/west.yml @@ -386,7 +386,7 @@ manifest: groups: - tee - name: trusted-firmware-m - revision: 677e0565e030cbe4946ac0cbde5603eae7d6392f + revision: 6788687e013733d12f015b5d45b214019dea58f7 path: modules/tee/tf-m/trusted-firmware-m groups: - tee From 2c911b1b8a83a07b4396ff88209b14162d23c3f0 Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Tue, 13 Jan 2026 14:17:42 -0800 Subject: [PATCH 2314/3659] soc: snps: vpx5: no -Hccm compiler option for userspace With -Hccm, the linker automatically moves stuff in RODATA section into DATA section. Our current kobject related scripts cannot accommodate this, resulting in space not being reserved correctly. So for now, disable -Hccm compiler option if userspace is enabled. Signed-off-by: Daniel Leung --- soc/snps/nsim/arc_classic/vpx5/CMakeLists.txt | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/soc/snps/nsim/arc_classic/vpx5/CMakeLists.txt b/soc/snps/nsim/arc_classic/vpx5/CMakeLists.txt index 26f43b967936..240ca1209077 100644 --- a/soc/snps/nsim/arc_classic/vpx5/CMakeLists.txt +++ b/soc/snps/nsim/arc_classic/vpx5/CMakeLists.txt @@ -8,10 +8,21 @@ if(COMPILER STREQUAL gcc) else() # MWDT compiler options + # With -Hccm, the linker automatically moves stuff in RODATA + # section into DATA section. Our current kobject related + # scripts cannot accommodate this, resulting in space not + # being reserved correctly. So for now, disable -Hccm + # compiler option if userspace is enabled. + if(CONFIG_USERSPACE) + set(USE_CCM "") + else() + set(USE_CCM "-Hccm") + endif() + zephyr_compile_options_ifdef(CONFIG_SOC_NSIM_VPX5 -arcv2hs -core4 -uarch_rev=1:4 -Xcode_density -HL -Xatomic -Xll64 -Xunaligned -Xdiv_rem=radix4 -Xswap -Xbitscan -Xmpy_option=qmpyh -Xshift_assist -Xbarrel_shifter -Xtimer0 -Xtimer1 -Xrtc -dcache=32768,64,2,a - -Hld_cycles=1 -DDCCM_SYSTEM_BASE_CORE0=0x80000000 -Hccm + -Hld_cycles=1 -DDCCM_SYSTEM_BASE_CORE0=0x80000000 ${USE_CCM} -DICCM0_SYSTEM_BASE_CORE0=0x0000000 -Xstu=4 -Xvdsp4 -Xvec_unit_rev_minor=1 -Xvec_width=512 -Xvec_mem_size=256k -Xvec_mem_bank_width=16 -Xvec_max_fetch_size=16 -Xvec_num_slots=3 -Xvec_super_with_scalar -Xvec_regs=40 -Xvec_num_rd_ports=6 @@ -20,4 +31,6 @@ else() zephyr_ld_option_ifdef(CONFIG_SOC_NSIM_VPX5 -Hlib=vpx5_integer_full) + unset(USE_CCM) + endif() From ee8f9915a45692a46d25febac1b16dc4c3e179fe Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Wed, 7 Jan 2026 13:11:59 -0800 Subject: [PATCH 2315/3659] soc: arc: mark nsim_vpx5 as supporting MPU This selects CONFIG_CPU_HAS_MPU for nsim_vpx5 series SoC as it supports ARC MPUv3. Signed-off-by: Daniel Leung --- soc/snps/nsim/arc_classic/vpx5/Kconfig | 1 + soc/snps/nsim/arc_classic/vpx5/Kconfig.defconfig | 3 +++ 2 files changed, 4 insertions(+) diff --git a/soc/snps/nsim/arc_classic/vpx5/Kconfig b/soc/snps/nsim/arc_classic/vpx5/Kconfig index af6f944ab6ad..94579c6b573b 100644 --- a/soc/snps/nsim/arc_classic/vpx5/Kconfig +++ b/soc/snps/nsim/arc_classic/vpx5/Kconfig @@ -3,3 +3,4 @@ config SOC_SERIES_NSIM_VPX5 select ARC + select CPU_HAS_MPU diff --git a/soc/snps/nsim/arc_classic/vpx5/Kconfig.defconfig b/soc/snps/nsim/arc_classic/vpx5/Kconfig.defconfig index 24a2a38c4a05..ad41e14a0a89 100644 --- a/soc/snps/nsim/arc_classic/vpx5/Kconfig.defconfig +++ b/soc/snps/nsim/arc_classic/vpx5/Kconfig.defconfig @@ -30,4 +30,7 @@ config ARC_FIRQ config CACHE_MANAGEMENT default y +config ARC_MPU_VER + default 3 if ARC_MPU_ENABLE + endif # SOC_NSIM_VPX5 From 231e72af8ed0426d28cab8915e83188d7231974f Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Wed, 7 Jan 2026 13:13:34 -0800 Subject: [PATCH 2316/3659] boards: snps/arc: add nsim_vpx5/mpuv3 board This adds the nsim_vpx5/mpuv3 board for MPU. The files are based on nsim_vpx5 board files. Signed-off-by: Daniel Leung --- boards/snps/nsim/arc_classic/Kconfig.nsim | 1 + boards/snps/nsim/arc_classic/board.yml | 2 + .../nsim/arc_classic/nsim_nsim_vpx5_mpuv3.dts | 31 +++++ .../arc_classic/nsim_nsim_vpx5_mpuv3.yaml | 14 +++ .../nsim_nsim_vpx5_mpuv3_defconfig | 10 ++ .../arc_classic/support/mdb_vpx5_mpuv3.args | 98 ++++++++++++++++ .../arc_classic/support/nsim_vpx5_mpuv3.props | 107 ++++++++++++++++++ 7 files changed, 263 insertions(+) create mode 100644 boards/snps/nsim/arc_classic/nsim_nsim_vpx5_mpuv3.dts create mode 100644 boards/snps/nsim/arc_classic/nsim_nsim_vpx5_mpuv3.yaml create mode 100644 boards/snps/nsim/arc_classic/nsim_nsim_vpx5_mpuv3_defconfig create mode 100644 boards/snps/nsim/arc_classic/support/mdb_vpx5_mpuv3.args create mode 100644 boards/snps/nsim/arc_classic/support/nsim_vpx5_mpuv3.props diff --git a/boards/snps/nsim/arc_classic/Kconfig.nsim b/boards/snps/nsim/arc_classic/Kconfig.nsim index 33be7632e732..e0b5740b8dbf 100644 --- a/boards/snps/nsim/arc_classic/Kconfig.nsim +++ b/boards/snps/nsim/arc_classic/Kconfig.nsim @@ -22,3 +22,4 @@ config BOARD_NSIM select SOC_NSIM_SEM if BOARD_NSIM_NSIM_SEM select SOC_NSIM_SEM if BOARD_NSIM_NSIM_SEM_MPU_STACK_GUARD select SOC_NSIM_VPX5 if BOARD_NSIM_NSIM_VPX5 + select SOC_NSIM_VPX5 if BOARD_NSIM_NSIM_VPX5_MPUV3 diff --git a/boards/snps/nsim/arc_classic/board.yml b/boards/snps/nsim/arc_classic/board.yml index 20bbd3071ec5..905c83a244e4 100644 --- a/boards/snps/nsim/arc_classic/board.yml +++ b/boards/snps/nsim/arc_classic/board.yml @@ -27,3 +27,5 @@ board: variants: - name: mpu_stack_guard - name: nsim_vpx5 + variants: + - name: mpuv3 diff --git a/boards/snps/nsim/arc_classic/nsim_nsim_vpx5_mpuv3.dts b/boards/snps/nsim/arc_classic/nsim_nsim_vpx5_mpuv3.dts new file mode 100644 index 000000000000..291a136195d2 --- /dev/null +++ b/boards/snps/nsim/arc_classic/nsim_nsim_vpx5_mpuv3.dts @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2023, Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#define ICCM_SIZE DT_SIZE_K(256) +#define DCCM_SIZE DT_SIZE_K(256) +#define UART0_IRQ_NUM 23 + +#include "nsim.dtsi" +#include "nsim-ccm-mem.dtsi" +#include "nsim-uart-ns16550.dtsi" + +/ { + model = "snps,nsim_hs"; + compatible = "snps,nsim_hs"; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "snps,archs"; + reg = <0>; + }; + }; +}; diff --git a/boards/snps/nsim/arc_classic/nsim_nsim_vpx5_mpuv3.yaml b/boards/snps/nsim/arc_classic/nsim_nsim_vpx5_mpuv3.yaml new file mode 100644 index 000000000000..e1564aff63c6 --- /dev/null +++ b/boards/snps/nsim/arc_classic/nsim_nsim_vpx5_mpuv3.yaml @@ -0,0 +1,14 @@ +identifier: nsim/nsim_vpx5/mpuv3 +name: VPX5 nSIM simulator (with MPUv3) +type: sim +simulation: + - name: nsim + exec: nsimdrv +arch: arc +toolchain: + - arcmwdt +testing: + ignore_tags: + - net + - bluetooth +vendor: snps diff --git a/boards/snps/nsim/arc_classic/nsim_nsim_vpx5_mpuv3_defconfig b/boards/snps/nsim/arc_classic/nsim_nsim_vpx5_mpuv3_defconfig new file mode 100644 index 000000000000..37f49899a89b --- /dev/null +++ b/boards/snps/nsim/arc_classic/nsim_nsim_vpx5_mpuv3_defconfig @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SYS_CLOCK_TICKS_PER_SEC=100 +CONFIG_BUILD_OUTPUT_BIN=n +CONFIG_ARCV2_INTERRUPT_UNIT=y +CONFIG_ARCV2_TIMER=y +CONFIG_ARC_MPU_ENABLE=y +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_SERIAL=y diff --git a/boards/snps/nsim/arc_classic/support/mdb_vpx5_mpuv3.args b/boards/snps/nsim/arc_classic/support/mdb_vpx5_mpuv3.args new file mode 100644 index 000000000000..c3a8594a7427 --- /dev/null +++ b/boards/snps/nsim/arc_classic/support/mdb_vpx5_mpuv3.args @@ -0,0 +1,98 @@ + -arcv2hs + -core4 + -uarch_rev=1:4 + -Xcode_density + -rgf_num_banks=1 + -rgf_num_wr_ports=2 + -Xatomic + -Xll64 + -Xunaligned + -Xdiv_rem=radix4 + -Xswap + -Xbitscan + -Xmpy_option=qmpyh + -Xshift_assist + -Xbarrel_shifter + -Xtimer0 + -Xtimer0_level=0 + -Xtimer1 + -Xtimer1_level=0 + -Xrtc + -action_points=8 + -ap_feature=1 + -Xstack_check + -dmp_per0_base=14 + -dmp_per0_limit=15 + -volatile_base=12 + -volatile_limit=0 + -volatile_strict_ordering + -bpu_bc_entries=1024 + -bpu_pt_entries=8192 + -bpu_rs_entries=8 + -bpu_bc_full_tag=1 + -bpu_tosq_entries=5 + -bpu_fb_entries=2 + -interrupts=24 + -interrupt_priorities=4 + -ext_interrupts=8 + -interrupt_base=0x0 + -intvbase_ext + -dcache=32768,64,2,a + -dcache_version=5 + -dcache_feature=2 + -dcache_mem_cycles=1 + -icache=32768,128,4,a + -icache_version=4 + -icache_feature=2 + -dccm_size=0x40000 + -dccm_base=0x80000000 + -dccm_mem_cycles=1 + -iccm0_size=0x40000 + -iccm0_base=0x00000000 + -Xpct_counters=16 + -Xpct_interrupt + -arconnect + -connect_asi=2 + -connect_ici=3 + -connect_icd=2 + -connect_gfrc=4 + -connect_idu=2 + -connect_idu_cirqnum=4 + -connect_ivc=1 + -stu=4 + -stu_initiator_num=1 + -stu_initiator_dbw=128 + -stu_phy_ch_num=1 + -stu_req_fifo_depth=32 + -stu_buffer_size=32 + -stu_perf + -Xvdsp4 + -Xvec_unit_rev_minor=1 + -Xvec_width=512 + -Xvec_mem_size=256k + -Xvec_mem_banks=32 + -Xvec_mem_bank_width=16 + -Xvec_max_fetch_size=16 + -Xvec_num_slots=3 + -Xvec_super_with_scalar + -Xvec_regs=40 + -Xvec_fast=0 + -Xvec_num_rd_ports=6 + -Xvec_num_acc=8 + -Xvec_num_mpy=2 + -Xvec_mpy32 + -Xvec_num_alu=3 + -Xvec_guard_bit_option=2 + -Xvec_mem_topology=0 + -Xvec_stack_check + -Xvec_mem_base=0x90000000 + -cluster_version=5 + -scu + -scu_stb_entries=8 + -scu_coherent_io=1 + -cluster_peripheral_interfaces=1 + -clock_gating + -mpuv3 + -mpu_regions=16 + -prop=nsim_mem-dev=uart0,kind=dwuart,base=0xf0000000,irq=24 + -noprofile diff --git a/boards/snps/nsim/arc_classic/support/nsim_vpx5_mpuv3.props b/boards/snps/nsim/arc_classic/support/nsim_vpx5_mpuv3.props new file mode 100644 index 000000000000..279048676b0d --- /dev/null +++ b/boards/snps/nsim/arc_classic/support/nsim_vpx5_mpuv3.props @@ -0,0 +1,107 @@ + nsim_isa_family=av2hs + nsim_isa_core=4 + arcver=0x54 + nsim_isa_uarch_rev_major=1 + nsim_isa_uarch_rev_minor=4 + nsim_isa_code_density_option=2 + nsim_isa_rgf_num_banks=1 + nsim_isa_rgf_num_regs=32 + nsim_isa_rgf_num_wr_ports=2 + nsim_isa_big_endian=0 + nsim_isa_lpc_size=32 + nsim_isa_pc_size=32 + nsim_isa_addr_size=32 + nsim_isa_atomic_option=1 + nsim_isa_ll64_option=1 + nsim_isa_unaligned_option=1 + nsim_isa_div_rem_option=2 + nsim_isa_swap_option=1 + nsim_isa_bitscan_option=1 + nsim_isa_mpy_option=9 + nsim_isa_shift_option=3 + nsim_isa_enable_timer_0=1 + nsim_isa_timer_0_int_level=0 + nsim_isa_enable_timer_1=1 + nsim_isa_timer_1_int_level=0 + nsim_isa_rtc_option=1 + nsim_isa_num_actionpoints=8 + nsim_isa_aps_feature=1 + nsim_isa_stack_checking=1 + nsim_isa_has_dmp_peripheral=1 + nsim_isa_dmp_peripheral_version=2 + nsim_isa_dmp_peripheral_count=1 + nsim_isa_dmp_peripheral_base0=14 + nsim_isa_dmp_peripheral_limit0=15 + nsim_isa_volatile_base=12 + nsim_isa_volatile_limit=0 + nsim_isa_volatile_disable=0 + nsim_isa_volatile_strict_ordering=1 + nsim_bpu_bc_entries=1024 + nsim_bpu_pt_entries=8192 + nsim_bpu_rs_entries=8 + nsim_bpu_bc_full_tag=1 + nsim_bpu_tosq_entries=5 + nsim_bpu_fb_entries=2 + nsim_isa_number_of_interrupts=24 + nsim_isa_number_of_levels=4 + nsim_isa_number_of_external_interrupts=8 + nsim_isa_intvbase_preset=0x0 + nsim_isa_intvbase_ext=1 + dcache=32768,64,2,a + nsim_isa_dc_version=5 + nsim_isa_dc_feature_level=2 + nsim_isa_dc_mem_cycles=1 + icache=32768,128,4,a + nsim_isa_ic_version=4 + nsim_isa_ic_feature_level=2 + dccm_size=0x40000 + dccm_base=0x80000000 + nsim_isa_dccm_mem_cycles=1 + iccm0_size=0x40000 + iccm0_base=0x00000000 + nsim_isa_pct_counters=16 + nsim_isa_pct_interrupt=1 + nsim_connect=2 + nsim_connect_asi=2 + nsim_connect_ici=3 + nsim_connect_icd=2 + nsim_connect_gfrc=4 + nsim_connect_idu=2 + nsim_connect_idu_cirqnum=4 + nsim_connect_ivc=1 + nsim_stu=4 + nsim_stu_initiator_num=1 + nsim_stu_initiator_dbw=128 + nsim_stu_phy_ch_num=1 + nsim_stu_req_fifo_depth=32 + nsim_stu_buffer_size=32 + nsim_stu_perf=1 + nsim_isa_vec_unit=4 + nsim_isa_vec_unit_rev_minor=1 + nsim_isa_vec_width=512 + vec_mem_size=256k + nsim_isa_vec_mem_banks=32 + nsim_isa_vec_mem_bank_width=16 + nsim_isa_vec_max_fetch_size=16 + nsim_isa_vec_num_slots=3 + nsim_isa_vec_super_with_scalar=1 + nsim_isa_vec_regs=40 + nsim_isa_vec_fast=0 + nsim_isa_vec_num_rd_ports=6 + nsim_isa_vec_num_acc=8 + nsim_isa_vec_num_mpy=2 + nsim_isa_vec_mpy32=1 + nsim_isa_vec_num_alu=3 + nsim_isa_vec_guard_bit_option=2 + nsim_isa_vec_mem_topology=0 + nsim_isa_vec_stack_check=1 + vec_mem_base=0x90000000 + nsim_cluster_version=5 + nsim_isa_has_scu=1 + nsim_isa_scu_stb_entries=8 + nsim_isa_scu_coherent_io=1 + nsim_cluster_peripheral_interfaces=1 + nsim_isa_clock_gating=1 + nsim_mem-dev=uart0,kind=dwuart,base=0xf0000000,irq=23 + mpu_regions=16 + mpu_version=3 From 3d5a3ae075d6f61a76136758c7b18783e89dfc12 Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Sun, 18 Jan 2026 18:52:30 -0800 Subject: [PATCH 2317/3659] entropy: mcux_rng: Do not ignore possible error Propagate the HAL error otherwise it may return success even when it fails causing invalid entropy and compromising security. Signed-off-by: Flavio Ceolin --- drivers/entropy/entropy_mcux_rng.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/drivers/entropy/entropy_mcux_rng.c b/drivers/entropy/entropy_mcux_rng.c index 74d78ee2735e..56195e617760 100644 --- a/drivers/entropy/entropy_mcux_rng.c +++ b/drivers/entropy/entropy_mcux_rng.c @@ -23,11 +23,26 @@ static int entropy_mcux_rng_get_entropy(const struct device *dev, { const struct mcux_entropy_config *config = dev->config; status_t status; + int ret; status = RNG_GetRandomData(config->base, buffer, length); - __ASSERT_NO_MSG(!status); - return 0; + /* It seems that this function returns either success or + * invalid argument. + */ + switch (status) { + case kStatus_InvalidArgument: + ret = -EINVAL; + break; + case kStatus_Success: + ret = 0; + break; + default: + ret = -ENODATA; + break; + } + + return ret; } static DEVICE_API(entropy, entropy_mcux_rng_api_funcs) = { From a2b64c933585293c7293dbe1350734c5042c3839 Mon Sep 17 00:00:00 2001 From: Aksel Skauge Mellbye Date: Mon, 19 Jan 2026 10:06:46 +0100 Subject: [PATCH 2318/3659] dts: arm: silabs: Clean up radio feature selection Sort ble radio feature properties alphabetically according to the coding standard. Certain features on xg22 and xg28 depend on the specific SoC selected, move the properties from the generic .dtsi file to the SoC specific one. Signed-off-by: Aksel Skauge Mellbye --- dts/arm/silabs/xg21/efr32xg21.dtsi | 4 ++-- dts/arm/silabs/xg22/bgm220pc22hna.dtsi | 4 ++++ dts/arm/silabs/xg22/bgm220pc22wga.dtsi | 2 ++ dts/arm/silabs/xg22/bgm220sc22hna.dtsi | 4 ++++ dts/arm/silabs/xg22/efr32bg22c222f352gm32.dtsi | 5 +++++ dts/arm/silabs/xg22/efr32bg22c222f352gm40.dtsi | 5 +++++ dts/arm/silabs/xg22/efr32bg22c222f352gn32.dtsi | 5 +++++ dts/arm/silabs/xg22/efr32bg22c224f512gm32.dtsi | 7 +++++++ dts/arm/silabs/xg22/efr32bg22c224f512gm40.dtsi | 7 +++++++ dts/arm/silabs/xg22/efr32bg22c224f512gn32.dtsi | 7 +++++++ dts/arm/silabs/xg22/efr32bg22c224f512im32.dtsi | 7 +++++++ dts/arm/silabs/xg22/efr32bg22c224f512im40.dtsi | 7 +++++++ dts/arm/silabs/xg22/efr32mg22c224f512gn32.dtsi | 7 +++++++ dts/arm/silabs/xg22/efr32mg22c224f512im32.dtsi | 7 +++++++ dts/arm/silabs/xg22/efr32mg22c224f512im40.dtsi | 7 +++++++ dts/arm/silabs/xg22/efr32xg22.dtsi | 4 ---- dts/arm/silabs/xg23/efr32xg23.dtsi | 1 + dts/arm/silabs/xg24/efr32xg24.dtsi | 10 +++++----- dts/arm/silabs/xg26/efr32xg26.dtsi | 5 +++++ dts/arm/silabs/xg27/efr32xg27.dtsi | 6 +++--- dts/arm/silabs/xg28/efr32xg28.dtsi | 1 + dts/arm/silabs/xg28/efr32zg28b322f1024im68.dtsi | 4 ++++ dts/arm/silabs/xg29/efr32xg29.dtsi | 6 +++--- 23 files changed, 105 insertions(+), 17 deletions(-) diff --git a/dts/arm/silabs/xg21/efr32xg21.dtsi b/dts/arm/silabs/xg21/efr32xg21.dtsi index fc928cac9af3..0ceaa57ff709 100644 --- a/dts/arm/silabs/xg21/efr32xg21.dtsi +++ b/dts/arm/silabs/xg21/efr32xg21.dtsi @@ -11,6 +11,8 @@ radio: radio@b0000000 { compatible = "silabs,series2-radio"; reg = <0xb0000000 0x01000000>; + ble-2mbps-supported; + ble-coded-phy-supported; interrupt-names = "agc", "bufc", "frc_pri", "frc", "modem", "protimer", "rac_rsm", "rac_seq", "prortc", "synth"; interrupts = <31 1>, <32 1>, <33 1>, <34 1>, <35 1>, <36 1>, <37 1>, @@ -19,8 +21,6 @@ pa-initial-power-dbm = <10>; pa-ramp-time-us = <10>; pa-voltage-mv = <3300>; - ble-2mbps-supported; - ble-coded-phy-supported; radio-tx-high-power-supported; bt_hci_silabs: bt_hci_silabs { diff --git a/dts/arm/silabs/xg22/bgm220pc22hna.dtsi b/dts/arm/silabs/xg22/bgm220pc22hna.dtsi index 8ab760fcda44..d2ea0131d755 100644 --- a/dts/arm/silabs/xg22/bgm220pc22hna.dtsi +++ b/dts/arm/silabs/xg22/bgm220pc22hna.dtsi @@ -43,6 +43,10 @@ }; &radio { + ble-2mbps-supported; + ble-coded-phy-supported; + ble-cte-rx-supported; + ble-cte-tx-supported; pa-voltage-mv = <1800>; }; diff --git a/dts/arm/silabs/xg22/bgm220pc22wga.dtsi b/dts/arm/silabs/xg22/bgm220pc22wga.dtsi index bce9701e0a0f..f90927466d30 100644 --- a/dts/arm/silabs/xg22/bgm220pc22wga.dtsi +++ b/dts/arm/silabs/xg22/bgm220pc22wga.dtsi @@ -29,6 +29,8 @@ }; &radio { + ble-2mbps-supported; + ble-cte-tx-supported; pa-voltage-mv = <1800>; }; diff --git a/dts/arm/silabs/xg22/bgm220sc22hna.dtsi b/dts/arm/silabs/xg22/bgm220sc22hna.dtsi index 70215e0793c8..282e31b1fe1e 100644 --- a/dts/arm/silabs/xg22/bgm220sc22hna.dtsi +++ b/dts/arm/silabs/xg22/bgm220sc22hna.dtsi @@ -31,6 +31,10 @@ }; &radio { + ble-2mbps-supported; + ble-coded-phy-supported; + ble-cte-rx-supported; + ble-cte-tx-supported; pa-voltage-mv = <1800>; }; diff --git a/dts/arm/silabs/xg22/efr32bg22c222f352gm32.dtsi b/dts/arm/silabs/xg22/efr32bg22c222f352gm32.dtsi index 3289ea2b2254..6aa2a17220fb 100644 --- a/dts/arm/silabs/xg22/efr32bg22c222f352gm32.dtsi +++ b/dts/arm/silabs/xg22/efr32bg22c222f352gm32.dtsi @@ -19,6 +19,11 @@ reg = <0x00000000 DT_SIZE_K(352)>; }; +&radio { + ble-2mbps-supported; + ble-cte-tx-supported; +}; + &sram0 { reg = <0x20000000 DT_SIZE_K(32)>; }; diff --git a/dts/arm/silabs/xg22/efr32bg22c222f352gm40.dtsi b/dts/arm/silabs/xg22/efr32bg22c222f352gm40.dtsi index 4dd5ead08e3f..d7485b55fce3 100644 --- a/dts/arm/silabs/xg22/efr32bg22c222f352gm40.dtsi +++ b/dts/arm/silabs/xg22/efr32bg22c222f352gm40.dtsi @@ -19,6 +19,11 @@ reg = <0x00000000 DT_SIZE_K(352)>; }; +&radio { + ble-2mbps-supported; + ble-cte-tx-supported; +}; + &sram0 { reg = <0x20000000 DT_SIZE_K(32)>; }; diff --git a/dts/arm/silabs/xg22/efr32bg22c222f352gn32.dtsi b/dts/arm/silabs/xg22/efr32bg22c222f352gn32.dtsi index 5ee05b65efd7..3fb801264de1 100644 --- a/dts/arm/silabs/xg22/efr32bg22c222f352gn32.dtsi +++ b/dts/arm/silabs/xg22/efr32bg22c222f352gn32.dtsi @@ -19,6 +19,11 @@ reg = <0x00000000 DT_SIZE_K(352)>; }; +&radio { + ble-2mbps-supported; + ble-cte-tx-supported; +}; + &sram0 { reg = <0x20000000 DT_SIZE_K(32)>; }; diff --git a/dts/arm/silabs/xg22/efr32bg22c224f512gm32.dtsi b/dts/arm/silabs/xg22/efr32bg22c224f512gm32.dtsi index 6e264464f0ff..1842e7eaf805 100644 --- a/dts/arm/silabs/xg22/efr32bg22c224f512gm32.dtsi +++ b/dts/arm/silabs/xg22/efr32bg22c224f512gm32.dtsi @@ -19,6 +19,13 @@ reg = <0x00000000 DT_SIZE_K(512)>; }; +&radio { + ble-2mbps-supported; + ble-coded-phy-supported; + ble-cte-rx-supported; + ble-cte-tx-supported; +}; + &sram0 { reg = <0x20000000 DT_SIZE_K(32)>; }; diff --git a/dts/arm/silabs/xg22/efr32bg22c224f512gm40.dtsi b/dts/arm/silabs/xg22/efr32bg22c224f512gm40.dtsi index 5d31e5361489..5f2d4a278029 100644 --- a/dts/arm/silabs/xg22/efr32bg22c224f512gm40.dtsi +++ b/dts/arm/silabs/xg22/efr32bg22c224f512gm40.dtsi @@ -19,6 +19,13 @@ reg = <0x00000000 DT_SIZE_K(512)>; }; +&radio { + ble-2mbps-supported; + ble-coded-phy-supported; + ble-cte-rx-supported; + ble-cte-tx-supported; +}; + &sram0 { reg = <0x20000000 DT_SIZE_K(32)>; }; diff --git a/dts/arm/silabs/xg22/efr32bg22c224f512gn32.dtsi b/dts/arm/silabs/xg22/efr32bg22c224f512gn32.dtsi index 9eedd872378b..3614d8327406 100644 --- a/dts/arm/silabs/xg22/efr32bg22c224f512gn32.dtsi +++ b/dts/arm/silabs/xg22/efr32bg22c224f512gn32.dtsi @@ -19,6 +19,13 @@ reg = <0x00000000 DT_SIZE_K(512)>; }; +&radio { + ble-2mbps-supported; + ble-coded-phy-supported; + ble-cte-rx-supported; + ble-cte-tx-supported; +}; + &sram0 { reg = <0x20000000 DT_SIZE_K(32)>; }; diff --git a/dts/arm/silabs/xg22/efr32bg22c224f512im32.dtsi b/dts/arm/silabs/xg22/efr32bg22c224f512im32.dtsi index 11f88d44e250..cbb4e0e7f764 100644 --- a/dts/arm/silabs/xg22/efr32bg22c224f512im32.dtsi +++ b/dts/arm/silabs/xg22/efr32bg22c224f512im32.dtsi @@ -19,6 +19,13 @@ reg = <0x00000000 DT_SIZE_K(512)>; }; +&radio { + ble-2mbps-supported; + ble-coded-phy-supported; + ble-cte-rx-supported; + ble-cte-tx-supported; +}; + &sram0 { reg = <0x20000000 DT_SIZE_K(32)>; }; diff --git a/dts/arm/silabs/xg22/efr32bg22c224f512im40.dtsi b/dts/arm/silabs/xg22/efr32bg22c224f512im40.dtsi index b85a4096d7d5..0202eb2c3d38 100644 --- a/dts/arm/silabs/xg22/efr32bg22c224f512im40.dtsi +++ b/dts/arm/silabs/xg22/efr32bg22c224f512im40.dtsi @@ -19,6 +19,13 @@ reg = <0x00000000 DT_SIZE_K(512)>; }; +&radio { + ble-2mbps-supported; + ble-coded-phy-supported; + ble-cte-rx-supported; + ble-cte-tx-supported; +}; + &sram0 { reg = <0x20000000 DT_SIZE_K(32)>; }; diff --git a/dts/arm/silabs/xg22/efr32mg22c224f512gn32.dtsi b/dts/arm/silabs/xg22/efr32mg22c224f512gn32.dtsi index 12618cdcda25..298b4b26895d 100644 --- a/dts/arm/silabs/xg22/efr32mg22c224f512gn32.dtsi +++ b/dts/arm/silabs/xg22/efr32mg22c224f512gn32.dtsi @@ -19,6 +19,13 @@ reg = <0x00000000 DT_SIZE_K(512)>; }; +&radio { + ble-2mbps-supported; + ble-coded-phy-supported; + ble-cte-rx-supported; + ble-cte-tx-supported; +}; + &sram0 { reg = <0x20000000 DT_SIZE_K(32)>; }; diff --git a/dts/arm/silabs/xg22/efr32mg22c224f512im32.dtsi b/dts/arm/silabs/xg22/efr32mg22c224f512im32.dtsi index 39f0416342d1..2141623f0eea 100644 --- a/dts/arm/silabs/xg22/efr32mg22c224f512im32.dtsi +++ b/dts/arm/silabs/xg22/efr32mg22c224f512im32.dtsi @@ -19,6 +19,13 @@ reg = <0x00000000 DT_SIZE_K(512)>; }; +&radio { + ble-2mbps-supported; + ble-coded-phy-supported; + ble-cte-rx-supported; + ble-cte-tx-supported; +}; + &sram0 { reg = <0x20000000 DT_SIZE_K(32)>; }; diff --git a/dts/arm/silabs/xg22/efr32mg22c224f512im40.dtsi b/dts/arm/silabs/xg22/efr32mg22c224f512im40.dtsi index 66f0ea88b856..82d6122ecba3 100644 --- a/dts/arm/silabs/xg22/efr32mg22c224f512im40.dtsi +++ b/dts/arm/silabs/xg22/efr32mg22c224f512im40.dtsi @@ -19,6 +19,13 @@ reg = <0x00000000 DT_SIZE_K(512)>; }; +&radio { + ble-2mbps-supported; + ble-coded-phy-supported; + ble-cte-rx-supported; + ble-cte-tx-supported; +}; + &sram0 { reg = <0x20000000 DT_SIZE_K(32)>; }; diff --git a/dts/arm/silabs/xg22/efr32xg22.dtsi b/dts/arm/silabs/xg22/efr32xg22.dtsi index 99417981627a..12eb99f565b6 100644 --- a/dts/arm/silabs/xg22/efr32xg22.dtsi +++ b/dts/arm/silabs/xg22/efr32xg22.dtsi @@ -20,10 +20,6 @@ pa-initial-power-dbm = <10>; pa-ramp-time-us = <2>; pa-voltage-mv = <3300>; - ble-2mbps-supported; - ble-coded-phy-supported; - ble-cte-tx-supported; - ble-cte-rx-supported; radio-tx-high-power-supported; pti: pti { diff --git a/dts/arm/silabs/xg23/efr32xg23.dtsi b/dts/arm/silabs/xg23/efr32xg23.dtsi index 3e94bc1d4b06..d7b9c3042a5c 100644 --- a/dts/arm/silabs/xg23/efr32xg23.dtsi +++ b/dts/arm/silabs/xg23/efr32xg23.dtsi @@ -20,6 +20,7 @@ pa-ramp-time-us = <10>; pa-subghz = "highest"; pa-voltage-mv = <3300>; + radio-tx-high-power-supported; pti: pti { compatible = "silabs,pti"; diff --git a/dts/arm/silabs/xg24/efr32xg24.dtsi b/dts/arm/silabs/xg24/efr32xg24.dtsi index 8c9a32edb39e..44dcc1c196a3 100644 --- a/dts/arm/silabs/xg24/efr32xg24.dtsi +++ b/dts/arm/silabs/xg24/efr32xg24.dtsi @@ -11,6 +11,11 @@ radio: radio@b0000000 { compatible = "silabs,series2-radio"; reg = <0xb0000000 0x01000000>; + ble-2mbps-supported; + ble-coded-phy-supported; + ble-cs-supported; + ble-cte-rx-supported; + ble-cte-tx-supported; interrupt-names = "agc", "bufc", "frc_pri", "frc", "modem", "protimer", "rac_rsm", "rac_seq", "hostmailbox", "synth", "rfeca0", "rfeca1"; @@ -20,11 +25,6 @@ pa-initial-power-dbm = <10>; pa-ramp-time-us = <10>; pa-voltage-mv = <3300>; - ble-2mbps-supported; - ble-coded-phy-supported; - ble-cte-tx-supported; - ble-cte-rx-supported; - ble-cs-supported; radio-tx-high-power-supported; bt_hci_silabs: bt_hci_silabs { diff --git a/dts/arm/silabs/xg26/efr32xg26.dtsi b/dts/arm/silabs/xg26/efr32xg26.dtsi index 61dea61507c5..471a8d184dd1 100644 --- a/dts/arm/silabs/xg26/efr32xg26.dtsi +++ b/dts/arm/silabs/xg26/efr32xg26.dtsi @@ -11,6 +11,10 @@ radio: radio@b0000000 { compatible = "silabs,series2-radio"; reg = <0xb0000000 0x01000000>; + ble-2mbps-supported; + ble-coded-phy-supported; + ble-cte-rx-supported; + ble-cte-tx-supported; interrupt-names = "agc", "bufc", "frc_pri", "frc", "modem", "protimer", "rac_rsm", "rac_seq", "hostmailbox", "synth", "rfeca0", "rfeca1"; @@ -20,6 +24,7 @@ pa-initial-power-dbm = <10>; pa-ramp-time-us = <10>; pa-voltage-mv = <3300>; + radio-tx-high-power-supported; pti: pti { compatible = "silabs,pti"; diff --git a/dts/arm/silabs/xg27/efr32xg27.dtsi b/dts/arm/silabs/xg27/efr32xg27.dtsi index a06f5e1c4d0c..584fa2f515c9 100644 --- a/dts/arm/silabs/xg27/efr32xg27.dtsi +++ b/dts/arm/silabs/xg27/efr32xg27.dtsi @@ -11,6 +11,9 @@ radio: radio@b0000000 { compatible = "silabs,series2-radio"; reg = <0xb0000000 0x01000000>; + ble-2mbps-supported; + ble-coded-phy-supported; + ble-cte-tx-supported; interrupt-names = "agc", "bufc", "frc_pri", "frc", "modem", "protimer", "rac_rsm", "rac_seq", "rdmailbox", "rfsense", "synth", "prortc"; @@ -20,9 +23,6 @@ pa-initial-power-dbm = <10>; pa-ramp-time-us = <2>; pa-voltage-mv = <3300>; - ble-2mbps-supported; - ble-coded-phy-supported; - ble-cte-tx-supported; radio-tx-high-power-supported; bt_hci_silabs: bt_hci_silabs { diff --git a/dts/arm/silabs/xg28/efr32xg28.dtsi b/dts/arm/silabs/xg28/efr32xg28.dtsi index b1e7f049a401..6b315da62286 100644 --- a/dts/arm/silabs/xg28/efr32xg28.dtsi +++ b/dts/arm/silabs/xg28/efr32xg28.dtsi @@ -21,6 +21,7 @@ pa-ramp-time-us = <10>; pa-subghz = "highest"; pa-voltage-mv = <3300>; + radio-tx-high-power-supported; pti: pti { compatible = "silabs,pti"; diff --git a/dts/arm/silabs/xg28/efr32zg28b322f1024im68.dtsi b/dts/arm/silabs/xg28/efr32zg28b322f1024im68.dtsi index cd0390ebd036..6de0fcf5d828 100644 --- a/dts/arm/silabs/xg28/efr32zg28b322f1024im68.dtsi +++ b/dts/arm/silabs/xg28/efr32zg28b322f1024im68.dtsi @@ -19,6 +19,10 @@ reg = <0x08000000 DT_SIZE_K(1024)>; }; +&radio { + ble-2mbps-supported; +}; + &sram0 { reg = <0x20000000 DT_SIZE_K(256)>; }; diff --git a/dts/arm/silabs/xg29/efr32xg29.dtsi b/dts/arm/silabs/xg29/efr32xg29.dtsi index cec52dc2cf17..505ebc75244e 100644 --- a/dts/arm/silabs/xg29/efr32xg29.dtsi +++ b/dts/arm/silabs/xg29/efr32xg29.dtsi @@ -11,6 +11,9 @@ radio: radio@b0000000 { compatible = "silabs,series2-radio"; reg = <0xb0000000 0x01000000>; + ble-2mbps-supported; + ble-coded-phy-supported; + ble-cte-tx-supported; interrupt-names = "agc", "bufc", "frc_pri", "frc", "modem", "protimer", "rac_rsm", "rac_seq", "rdmailbox", "rfsense", "synth", "prortc"; @@ -20,9 +23,6 @@ pa-initial-power-dbm = <10>; pa-ramp-time-us = <2>; pa-voltage-mv = <3300>; - ble-2mbps-supported; - ble-coded-phy-supported; - ble-cte-tx-supported; radio-tx-high-power-supported; bt_hci_silabs: bt_hci_silabs { From c7425884d648d329c3f6607d7c369d1dde83f626 Mon Sep 17 00:00:00 2001 From: Felix Wang Date: Mon, 19 Jan 2026 14:55:02 +0530 Subject: [PATCH 2319/3659] MAINTAINERS: add FelixWang47831 as PWM collaborator Add FelixWang47831 as a collaborator for the PWM driver. Signed-off-by: Felix Wang --- MAINTAINERS.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index 0aff172eb1e8..6b231468d6ba 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -2230,6 +2230,7 @@ Documentation Infrastructure: collaborators: - anangl - henrikbrixandersen + - FelixWang47831 files: - drivers/pwm/ - dts/bindings/pwm/ From 699da43045268a8102705b6da37f6c65638486f8 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Mon, 19 Jan 2026 10:42:37 +0100 Subject: [PATCH 2320/3659] samples: net: sockets: http_get: Fix addrinfo dump The debug code for dumping resolved addresses was modifying the addrinfo res pointer (effectively setting it to NULL), causing crash later in the sample. Fix this, by using a temporary pointer copy for iterating over resolved addresses. Signed-off-by: Robert Lubos --- samples/net/sockets/http_get/src/http_get.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/samples/net/sockets/http_get/src/http_get.c b/samples/net/sockets/http_get/src/http_get.c index 32e79c434830..9ac506007f72 100644 --- a/samples/net/sockets/http_get/src/http_get.c +++ b/samples/net/sockets/http_get/src/http_get.c @@ -89,8 +89,10 @@ int main(void) } #if 0 - for (; res; res = res->ai_next) { - dump_addrinfo(res); + struct addrinfo *temp_res = res; + + for (; temp_res; temp_res = temp_res->ai_next) { + dump_addrinfo(temp_res); } #endif From 4e314b4aecc8f39a79ffdbb69c57c174637c99cb Mon Sep 17 00:00:00 2001 From: Braeden Lane Date: Tue, 20 Jan 2026 14:44:49 -0800 Subject: [PATCH 2321/3659] boards: infineon: standardize pinctrl in supported list Update board YAML files to use 'pinctrl' instead of 'pin_ctrl' in the supported features list for consistency with Zephyr naming conventions. Affected boards: - cy8cproto_041tp - kit_pse84_ai - kit_pse84_eval Signed-off-by: Braeden Lane --- boards/infineon/cy8cproto_041tp/cy8cproto_041tp.yaml | 2 +- boards/infineon/kit_pse84_ai/kit_pse84_ai_m33.yaml | 2 +- boards/infineon/kit_pse84_ai/kit_pse84_ai_m55.yaml | 2 +- boards/infineon/kit_pse84_eval/kit_pse84_eval_m33.yaml | 2 +- boards/infineon/kit_pse84_eval/kit_pse84_eval_m55.yaml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/boards/infineon/cy8cproto_041tp/cy8cproto_041tp.yaml b/boards/infineon/cy8cproto_041tp/cy8cproto_041tp.yaml index 7053a2254b9c..780adc3f3b34 100644 --- a/boards/infineon/cy8cproto_041tp/cy8cproto_041tp.yaml +++ b/boards/infineon/cy8cproto_041tp/cy8cproto_041tp.yaml @@ -15,5 +15,5 @@ toolchain: supported: - uart - clock_control - - pin_ctrl + - pinctrl vendor: infineon diff --git a/boards/infineon/kit_pse84_ai/kit_pse84_ai_m33.yaml b/boards/infineon/kit_pse84_ai/kit_pse84_ai_m33.yaml index ca3e4c9f1b2d..20eda5e05f7c 100644 --- a/boards/infineon/kit_pse84_ai/kit_pse84_ai_m33.yaml +++ b/boards/infineon/kit_pse84_ai/kit_pse84_ai_m33.yaml @@ -14,5 +14,5 @@ toolchain: supported: - clock_control - gpio - - pin_ctrl + - pinctrl - uart diff --git a/boards/infineon/kit_pse84_ai/kit_pse84_ai_m55.yaml b/boards/infineon/kit_pse84_ai/kit_pse84_ai_m55.yaml index bc8cd3dc9471..19125395d788 100644 --- a/boards/infineon/kit_pse84_ai/kit_pse84_ai_m55.yaml +++ b/boards/infineon/kit_pse84_ai/kit_pse84_ai_m55.yaml @@ -14,5 +14,5 @@ toolchain: supported: - clock_control - gpio - - pin_ctrl + - pinctrl - uart diff --git a/boards/infineon/kit_pse84_eval/kit_pse84_eval_m33.yaml b/boards/infineon/kit_pse84_eval/kit_pse84_eval_m33.yaml index 29daa46ec3f2..8005f3b38d7c 100644 --- a/boards/infineon/kit_pse84_eval/kit_pse84_eval_m33.yaml +++ b/boards/infineon/kit_pse84_eval/kit_pse84_eval_m33.yaml @@ -15,6 +15,6 @@ supported: - clock_control - dma - gpio - - pin_ctrl + - pinctrl - uart - spi diff --git a/boards/infineon/kit_pse84_eval/kit_pse84_eval_m55.yaml b/boards/infineon/kit_pse84_eval/kit_pse84_eval_m55.yaml index 9ed20693cc0d..ee241e89804b 100644 --- a/boards/infineon/kit_pse84_eval/kit_pse84_eval_m55.yaml +++ b/boards/infineon/kit_pse84_eval/kit_pse84_eval_m55.yaml @@ -15,6 +15,6 @@ supported: - clock_control - dma - gpio - - pin_ctrl + - pinctrl - uart - spi From bf747b8e037eef1a873c998fc6642ba32a28d84b Mon Sep 17 00:00:00 2001 From: Laurentiu Mihalcea Date: Wed, 21 Jan 2026 00:47:23 +0200 Subject: [PATCH 2322/3659] bindings: scmi: modify description format Modify the description format of all SCMI-related bindings such that the SCMI/SHMEM acronym is spelled out in between parentheses and not the other way around. This will make the generated documentation more compact. Signed-off-by: Laurentiu Mihalcea --- dts/bindings/firmware/arm,scmi-clock.yaml | 2 +- dts/bindings/firmware/arm,scmi-pinctrl.yaml | 2 +- dts/bindings/firmware/arm,scmi-power.yaml | 2 +- dts/bindings/firmware/arm,scmi-shmem.yaml | 2 +- dts/bindings/firmware/arm,scmi-system.yaml | 2 +- dts/bindings/firmware/arm,scmi.yaml | 4 ++-- dts/bindings/firmware/nxp,scmi-cpu.yaml | 2 +- dts/bindings/power-domain/arm,scmi-power-domain.yaml | 2 +- 8 files changed, 9 insertions(+), 9 deletions(-) diff --git a/dts/bindings/firmware/arm,scmi-clock.yaml b/dts/bindings/firmware/arm,scmi-clock.yaml index 5f0aa160d3fc..943f3015fb70 100644 --- a/dts/bindings/firmware/arm,scmi-clock.yaml +++ b/dts/bindings/firmware/arm,scmi-clock.yaml @@ -1,7 +1,7 @@ # Copyright 2024 NXP # SPDX-License-Identifier: Apache-2.0 -description: System Control and Management Interface (SCMI) clock protocol +description: SCMI (System Control and Management Interface) clock protocol compatible: "arm,scmi-clock" diff --git a/dts/bindings/firmware/arm,scmi-pinctrl.yaml b/dts/bindings/firmware/arm,scmi-pinctrl.yaml index f1e52b0fd209..74b3b55831a9 100644 --- a/dts/bindings/firmware/arm,scmi-pinctrl.yaml +++ b/dts/bindings/firmware/arm,scmi-pinctrl.yaml @@ -1,7 +1,7 @@ # Copyright 2024 NXP # SPDX-License-Identifier: Apache-2.0 -description: System Control and Management Interface (SCMI) pinctrl protocol +description: SCMI (System Control and Management Interface) pinctrl protocol compatible: "arm,scmi-pinctrl" diff --git a/dts/bindings/firmware/arm,scmi-power.yaml b/dts/bindings/firmware/arm,scmi-power.yaml index 41ad234681d0..2b5c5281a518 100644 --- a/dts/bindings/firmware/arm,scmi-power.yaml +++ b/dts/bindings/firmware/arm,scmi-power.yaml @@ -1,7 +1,7 @@ # Copyright 2024 NXP # SPDX-License-Identifier: Apache-2.0 -description: System Control and Management Interface (SCMI) power domain protocol +description: SCMI (System Control and Management Interface) power domain protocol compatible: "arm,scmi-power" diff --git a/dts/bindings/firmware/arm,scmi-shmem.yaml b/dts/bindings/firmware/arm,scmi-shmem.yaml index aa968a3e4e5f..4fe7453e9301 100644 --- a/dts/bindings/firmware/arm,scmi-shmem.yaml +++ b/dts/bindings/firmware/arm,scmi-shmem.yaml @@ -1,7 +1,7 @@ # Copyright 2024 NXP # SPDX-License-Identifier: Apache-2.0 -description: System Control and Management Interface (SCMI) shared memory (SHMEM) +description: SCMI (System Control and Management Interface) SHMEM (shared memory) compatible: "arm,scmi-shmem" diff --git a/dts/bindings/firmware/arm,scmi-system.yaml b/dts/bindings/firmware/arm,scmi-system.yaml index 77aba5abf176..f8b79a8fefd5 100644 --- a/dts/bindings/firmware/arm,scmi-system.yaml +++ b/dts/bindings/firmware/arm,scmi-system.yaml @@ -1,7 +1,7 @@ # Copyright 2025 NXP # SPDX-License-Identifier: Apache-2.0 -description: System Control and Management Interface (SCMI) system power protocol +description: SCMI (System Control and Management Interface) system power protocol compatible: "arm,scmi-system" diff --git a/dts/bindings/firmware/arm,scmi.yaml b/dts/bindings/firmware/arm,scmi.yaml index 5ece8e59201d..22766cb815df 100644 --- a/dts/bindings/firmware/arm,scmi.yaml +++ b/dts/bindings/firmware/arm,scmi.yaml @@ -2,8 +2,8 @@ # SPDX-License-Identifier: Apache-2.0 description: | - System Control and Management Interface (SCMI) with doorbell - and shared memory (SHMEM) transport. + SCMI (System Control and Management Interface) with doorbell + and SHMEM (shared memory) transport. Devicetree example: #include diff --git a/dts/bindings/firmware/nxp,scmi-cpu.yaml b/dts/bindings/firmware/nxp,scmi-cpu.yaml index 7032df08d982..d435eb47bfee 100644 --- a/dts/bindings/firmware/nxp,scmi-cpu.yaml +++ b/dts/bindings/firmware/nxp,scmi-cpu.yaml @@ -1,7 +1,7 @@ # Copyright 2025 NXP # SPDX-License-Identifier: Apache-2.0 -description: System Control and Management Interface (SCMI) cpu domain protocol +description: SCMI (System Control and Management Interface) cpu domain protocol compatible: "nxp,scmi-cpu" diff --git a/dts/bindings/power-domain/arm,scmi-power-domain.yaml b/dts/bindings/power-domain/arm,scmi-power-domain.yaml index 66a732af25e7..588d0c041e5a 100644 --- a/dts/bindings/power-domain/arm,scmi-power-domain.yaml +++ b/dts/bindings/power-domain/arm,scmi-power-domain.yaml @@ -1,7 +1,7 @@ # Copyright 2026 NXP # SPDX-License-Identifier: Apache-2.0 -description: ARM SCMI Power Domain +description: SCMI (System Control and Management Interface) power domain compatible: "arm,scmi-power-domain" From 7deab5e3347abbf539356f969a0859c55af83456 Mon Sep 17 00:00:00 2001 From: Evgenii Kosenko Date: Wed, 7 Jan 2026 16:23:18 +0200 Subject: [PATCH 2323/3659] Bluetooth: Shell: Add per-bearer pool for GATT operations The original implementation used a single global parameter structure for GATT operations, preventing concurrent operations on different bearers. By introducing a per-bearer context pool, each bearer can maintain its own operation state, enabling simultaneous GATT operations. Signed-off-by: Evgenii Kosenko --- subsys/bluetooth/host/shell/gatt.c | 204 ++++++++++++++++++----------- 1 file changed, 129 insertions(+), 75 deletions(-) diff --git a/subsys/bluetooth/host/shell/gatt.c b/subsys/bluetooth/host/shell/gatt.c index 013b878a6af3..335cc0f91cc6 100644 --- a/subsys/bluetooth/host/shell/gatt.c +++ b/subsys/bluetooth/host/shell/gatt.c @@ -141,9 +141,49 @@ static int cmd_exchange_mtu(const struct shell *sh, return err; } -static struct bt_gatt_discover_params discover_params; +#define GATT_OP_POOL_SIZE (1U + COND_CODE_1(IS_ENABLED(CONFIG_BT_EATT), (CONFIG_BT_EATT_MAX), (0U))) +#define GATT_READ_MAX_HANDLES 8 + +static struct gatt_op_context { + struct bt_gatt_discover_params discover; + struct bt_gatt_read_params read; + uint16_t read_handles[GATT_READ_MAX_HANDLES]; + struct bt_gatt_write_params write; + uint8_t write_buf[BT_ATT_MAX_ATTRIBUTE_LEN]; +} gatt_ctx[GATT_OP_POOL_SIZE]; + static struct bt_uuid_16 uuid = BT_UUID_INIT_16(0); +static struct gatt_op_context *gatt_ctx_discover_alloc(void) +{ + for (size_t i = 0U; i < ARRAY_SIZE(gatt_ctx); i++) { + if (gatt_ctx[i].discover.func == NULL) { + return &gatt_ctx[i]; + } + } + return NULL; +} + +static struct gatt_op_context *gatt_ctx_read_alloc(void) +{ + for (size_t i = 0U; i < ARRAY_SIZE(gatt_ctx); i++) { + if (gatt_ctx[i].read.func == NULL) { + return &gatt_ctx[i]; + } + } + return NULL; +} + +static struct gatt_op_context *gatt_ctx_write_alloc(void) +{ + for (size_t i = 0U; i < ARRAY_SIZE(gatt_ctx); i++) { + if (gatt_ctx[i].write.func == NULL) { + return &gatt_ctx[i]; + } + } + return NULL; +} + static void print_chrc_props(uint8_t properties) { bt_shell_print("Properties: "); @@ -226,6 +266,7 @@ static uint8_t discover_func(struct bt_conn *conn, static int cmd_discover(const struct shell *sh, size_t argc, char *argv[]) { + struct gatt_op_context *ctx; int err; if (!default_conn) { @@ -233,47 +274,49 @@ static int cmd_discover(const struct shell *sh, size_t argc, char *argv[]) return -ENOEXEC; } - if (discover_params.func) { - shell_print(sh, "Discover ongoing"); + ctx = gatt_ctx_discover_alloc(); + if (ctx == NULL) { + shell_error(sh, "No available operation slots"); return -ENOEXEC; } - discover_params.func = discover_func; - discover_params.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE; - discover_params.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE; - SET_CHAN_OPT_ANY(discover_params); + ctx->discover.func = discover_func; + ctx->discover.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE; + ctx->discover.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE; + SET_CHAN_OPT_ANY(ctx->discover); if (argc > 1) { /* Only set the UUID if the value is valid (non zero) */ uuid.val = strtoul(argv[1], NULL, 16); if (uuid.val) { - discover_params.uuid = &uuid.uuid; + ctx->discover.uuid = &uuid.uuid; } } if (argc > 2) { - discover_params.start_handle = strtoul(argv[2], NULL, 16); + ctx->discover.start_handle = strtoul(argv[2], NULL, 16); if (argc > 3) { - discover_params.end_handle = strtoul(argv[3], NULL, 16); + ctx->discover.end_handle = strtoul(argv[3], NULL, 16); } } if (!strcmp(argv[0], "discover")) { - discover_params.type = BT_GATT_DISCOVER_ATTRIBUTE; + ctx->discover.type = BT_GATT_DISCOVER_ATTRIBUTE; } else if (!strcmp(argv[0], "discover-secondary")) { - discover_params.type = BT_GATT_DISCOVER_SECONDARY; + ctx->discover.type = BT_GATT_DISCOVER_SECONDARY; } else if (!strcmp(argv[0], "discover-include")) { - discover_params.type = BT_GATT_DISCOVER_INCLUDE; + ctx->discover.type = BT_GATT_DISCOVER_INCLUDE; } else if (!strcmp(argv[0], "discover-characteristic")) { - discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC; + ctx->discover.type = BT_GATT_DISCOVER_CHARACTERISTIC; } else if (!strcmp(argv[0], "discover-descriptor")) { - discover_params.type = BT_GATT_DISCOVER_DESCRIPTOR; + ctx->discover.type = BT_GATT_DISCOVER_DESCRIPTOR; } else { - discover_params.type = BT_GATT_DISCOVER_PRIMARY; + ctx->discover.type = BT_GATT_DISCOVER_PRIMARY; } - err = bt_gatt_discover(default_conn, &discover_params); + err = bt_gatt_discover(default_conn, &ctx->discover); if (err) { + (void)memset(&ctx->discover, 0, sizeof(ctx->discover)); shell_error(sh, "Discover failed (err %d)", err); } else { shell_print(sh, "Discover pending"); @@ -282,8 +325,6 @@ static int cmd_discover(const struct shell *sh, size_t argc, char *argv[]) return err; } -static struct bt_gatt_read_params read_params; - static uint8_t read_func(struct bt_conn *conn, uint8_t err, struct bt_gatt_read_params *params, const void *data, uint16_t length) @@ -302,6 +343,7 @@ static uint8_t read_func(struct bt_conn *conn, uint8_t err, static int cmd_read(const struct shell *sh, size_t argc, char *argv[]) { + struct gatt_op_context *ctx; int err; if (!default_conn) { @@ -309,23 +351,25 @@ static int cmd_read(const struct shell *sh, size_t argc, char *argv[]) return -ENOEXEC; } - if (read_params.func) { - shell_print(sh, "Read ongoing"); - return -ENOEXEC; + ctx = gatt_ctx_read_alloc(); + if (ctx == NULL) { + shell_error(sh, "No available operation slots"); + return -EBUSY; } - read_params.func = read_func; - read_params.handle_count = 1; - read_params.single.handle = strtoul(argv[1], NULL, 16); - read_params.single.offset = 0U; - SET_CHAN_OPT_ANY(read_params); + ctx->read.func = read_func; + ctx->read.handle_count = 1; + ctx->read.single.handle = strtoul(argv[1], NULL, 16); + ctx->read.single.offset = 0U; + SET_CHAN_OPT_ANY(ctx->read); if (argc > 2) { - read_params.single.offset = strtoul(argv[2], NULL, 16); + ctx->read.single.offset = strtoul(argv[2], NULL, 16); } - err = bt_gatt_read(default_conn, &read_params); + err = bt_gatt_read(default_conn, &ctx->read); if (err) { + (void)memset(&ctx->read, 0, sizeof(ctx->read)); shell_error(sh, "Read failed (err %d)", err); } else { shell_print(sh, "Read pending"); @@ -336,7 +380,7 @@ static int cmd_read(const struct shell *sh, size_t argc, char *argv[]) static int cmd_mread(const struct shell *sh, size_t argc, char *argv[]) { - uint16_t h[8]; + struct gatt_op_context *ctx; size_t i; int err; @@ -345,29 +389,34 @@ static int cmd_mread(const struct shell *sh, size_t argc, char *argv[]) return -ENOEXEC; } - if (read_params.func) { - shell_print(sh, "Read ongoing"); - return -ENOEXEC; + ctx = gatt_ctx_read_alloc(); + if (ctx == NULL) { + shell_error(sh, "No available operation slots"); + return -EBUSY; } - if ((argc - 1) > ARRAY_SIZE(h)) { - shell_print(sh, "Enter max %zu handle items to read", ARRAY_SIZE(h)); + if ((argc - 1) > ARRAY_SIZE(ctx->read_handles)) { + shell_print(sh, "Enter max %zu handle items to read", + ARRAY_SIZE(ctx->read_handles)); return -EINVAL; } for (i = 0; i < argc - 1; i++) { - h[i] = strtoul(argv[i + 1], NULL, 16); + ctx->read_handles[i] = strtoul(argv[i + 1], NULL, 16); } - read_params.func = read_func; - read_params.handle_count = i; - read_params.multiple.handles = h; - read_params.multiple.variable = true; - SET_CHAN_OPT_ANY(read_params); + ctx->read.func = read_func; + ctx->read.handle_count = i; + ctx->read.multiple.handles = ctx->read_handles; + ctx->read.multiple.variable = true; + SET_CHAN_OPT_ANY(ctx->read); - err = bt_gatt_read(default_conn, &read_params); + err = bt_gatt_read(default_conn, &ctx->read); if (err) { + (void)memset(&ctx->read, 0, sizeof(ctx->read)); shell_error(sh, "GATT multiple read request failed (err %d)", err); + } else { + shell_print(sh, "Read pending"); } return err; @@ -375,6 +424,7 @@ static int cmd_mread(const struct shell *sh, size_t argc, char *argv[]) static int cmd_read_uuid(const struct shell *sh, size_t argc, char *argv[]) { + struct gatt_op_context *ctx; int err; if (!default_conn) { @@ -382,33 +432,35 @@ static int cmd_read_uuid(const struct shell *sh, size_t argc, char *argv[]) return -ENOEXEC; } - if (read_params.func) { - shell_print(sh, "Read ongoing"); - return -ENOEXEC; + ctx = gatt_ctx_read_alloc(); + if (ctx == NULL) { + shell_error(sh, "No available operation slots"); + return -EBUSY; } - read_params.func = read_func; - read_params.handle_count = 0; - read_params.by_uuid.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE; - read_params.by_uuid.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE; - SET_CHAN_OPT_ANY(read_params); + ctx->read.func = read_func; + ctx->read.handle_count = 0; + ctx->read.by_uuid.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE; + ctx->read.by_uuid.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE; + SET_CHAN_OPT_ANY(ctx->read); if (argc > 1) { uuid.val = strtoul(argv[1], NULL, 16); if (uuid.val) { - read_params.by_uuid.uuid = &uuid.uuid; + ctx->read.by_uuid.uuid = &uuid.uuid; } } if (argc > 2) { - read_params.by_uuid.start_handle = strtoul(argv[2], NULL, 16); + ctx->read.by_uuid.start_handle = strtoul(argv[2], NULL, 16); if (argc > 3) { - read_params.by_uuid.end_handle = strtoul(argv[3], NULL, 16); + ctx->read.by_uuid.end_handle = strtoul(argv[3], NULL, 16); } } - err = bt_gatt_read(default_conn, &read_params); + err = bt_gatt_read(default_conn, &ctx->read); if (err) { + (void)memset(&ctx->read, 0, sizeof(ctx->read)); shell_error(sh, "Read failed (err %d)", err); } else { shell_print(sh, "Read pending"); @@ -417,19 +469,17 @@ static int cmd_read_uuid(const struct shell *sh, size_t argc, char *argv[]) return err; } -static struct bt_gatt_write_params write_params; -static uint8_t gatt_write_buf[BT_ATT_MAX_ATTRIBUTE_LEN]; - static void write_func(struct bt_conn *conn, uint8_t err, struct bt_gatt_write_params *params) { bt_shell_print("Write complete: err 0x%02x", err); - (void)memset(&write_params, 0, sizeof(write_params)); + (void)memset(params, 0, sizeof(*params)); } static int cmd_write(const struct shell *sh, size_t argc, char *argv[]) { + struct gatt_op_context *ctx; int err; uint16_t handle, offset; @@ -438,30 +488,31 @@ static int cmd_write(const struct shell *sh, size_t argc, char *argv[]) return -ENOEXEC; } - if (write_params.func) { - shell_error(sh, "Write ongoing"); - return -ENOEXEC; + ctx = gatt_ctx_write_alloc(); + if (ctx == NULL) { + shell_error(sh, "No available operation slots"); + return -EBUSY; } handle = strtoul(argv[1], NULL, 16); offset = strtoul(argv[2], NULL, 16); - write_params.length = hex2bin(argv[3], strlen(argv[3]), - gatt_write_buf, sizeof(gatt_write_buf)); - if (write_params.length == 0) { + ctx->write.length = hex2bin(argv[3], strlen(argv[3]), + ctx->write_buf, sizeof(ctx->write_buf)); + if (ctx->write.length == 0) { shell_error(sh, "No data set"); return -ENOEXEC; } - write_params.data = gatt_write_buf; - write_params.handle = handle; - write_params.offset = offset; - write_params.func = write_func; - SET_CHAN_OPT_ANY(write_params); + ctx->write.data = ctx->write_buf; + ctx->write.handle = handle; + ctx->write.offset = offset; + ctx->write.func = write_func; + SET_CHAN_OPT_ANY(ctx->write); - err = bt_gatt_write(default_conn, &write_params); + err = bt_gatt_write(default_conn, &ctx->write); if (err) { - write_params.func = NULL; + (void)memset(&ctx->write, 0, sizeof(ctx->write)); shell_error(sh, "Write failed (err %d)", err); } else { shell_print(sh, "Write pending"); @@ -479,6 +530,9 @@ static void write_without_rsp_cb(struct bt_conn *conn, void *user_data) print_write_stats(); } +/* Separate buffer for write-without-response (doesn't use async params) */ +static uint8_t gatt_write_without_rsp_buf[BT_ATT_MAX_ATTRIBUTE_LEN]; + static int cmd_write_without_rsp(const struct shell *sh, size_t argc, char *argv[]) { @@ -503,16 +557,16 @@ static int cmd_write_without_rsp(const struct shell *sh, } handle = strtoul(argv[1], NULL, 16); - gatt_write_buf[0] = strtoul(argv[2], NULL, 16); + gatt_write_without_rsp_buf[0] = strtoul(argv[2], NULL, 16); len = 1U; if (argc > 3) { int i; - len = MIN(strtoul(argv[3], NULL, 16), sizeof(gatt_write_buf)); + len = MIN(strtoul(argv[3], NULL, 16), sizeof(gatt_write_without_rsp_buf)); for (i = 1; i < len; i++) { - gatt_write_buf[i] = gatt_write_buf[0]; + gatt_write_without_rsp_buf[i] = gatt_write_without_rsp_buf[0]; } } @@ -529,7 +583,7 @@ static int cmd_write_without_rsp(const struct shell *sh, while (repeat--) { err = bt_gatt_write_without_response_cb(default_conn, handle, - gatt_write_buf, len, + gatt_write_without_rsp_buf, len, sign, func, UINT_TO_POINTER(len)); if (err) { From 8bf8eeb3383d5e2c6eb3495bd3886ce851d3dd70 Mon Sep 17 00:00:00 2001 From: Stephan Linz Date: Sat, 28 Dec 2024 08:03:02 +0100 Subject: [PATCH 2324/3659] drivers: display: rm67162: avoid uninitialized variable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Warning as error was: .../drivers/display/display_rm67162.c: In function ‘rm67162_write_fb’: .../drivers/display/display_rm67162.c:383:9: error: ‘wlen’ may be used uninitialized in this function [-Werror=maybe-uninitialized] 383 | return wlen; | ^~~~ cc1: all warnings being treated as errors Signed-off-by: Stephan Linz --- drivers/display/display_rm67162.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/display/display_rm67162.c b/drivers/display/display_rm67162.c index fc6c6f4dd9bd..d1fef43d97f9 100644 --- a/drivers/display/display_rm67162.c +++ b/drivers/display/display_rm67162.c @@ -355,7 +355,7 @@ static int rm67162_write_fb(const struct device *dev, bool first_write, { const struct rm67162_config *config = dev->config; struct rm67162_data *data = dev->data; - ssize_t wlen; + ssize_t wlen = 0; struct mipi_dsi_msg msg = {0}; uint8_t *local_src = (uint8_t *)src; uint32_t len = desc->height * desc->width * data->bytes_per_pixel; From 2d6aa4739886a923d650cb4403e623d89422aa28 Mon Sep 17 00:00:00 2001 From: Tom Hughes Date: Fri, 16 Jan 2026 16:44:33 -0800 Subject: [PATCH 2325/3659] tests: mcumgr: Re-enable clang warning by using variables When removing TOOLCHAIN_DISABLE_CLANG_WARNING, building the settings.mgmt test with clang fails with: tests/subsys/mgmt/mcumgr/settings_mgmt/src/main.c:87:22: error: variable 'test_response_read_data_start' is not needed and will not be emitted [-Werror,-Wunneeded-internal-declaration] 87 | static const uint8_t test_response_read_data_start[5] = { | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ tests/subsys/mgmt/mcumgr/settings_mgmt/src/main.c:91:22: error: variable 'test_response_read_data_end' is not needed and will not be emitted [-Werror,-Wunneeded-internal-declaration] 91 | static const uint8_t test_response_read_data_end[1] = { Add additional asserts to use these variables in the test. Signed-off-by: Tom Hughes --- .../mgmt/mcumgr/settings_mgmt/src/main.c | 63 ++++++++++++++++--- 1 file changed, 56 insertions(+), 7 deletions(-) diff --git a/tests/subsys/mgmt/mcumgr/settings_mgmt/src/main.c b/tests/subsys/mgmt/mcumgr/settings_mgmt/src/main.c index 86443ccace86..25f13ba007d7 100644 --- a/tests/subsys/mgmt/mcumgr/settings_mgmt/src/main.c +++ b/tests/subsys/mgmt/mcumgr/settings_mgmt/src/main.c @@ -79,12 +79,6 @@ static const uint8_t test_response_error_data[8] = { 0xbf, 0x62, 0x72, 0x63, 0x19, 0x01, 0x00, 0xff }; -/* - * TODO: The contents of these structs are not used, which is why clang complains. - * The test should be updated to use these values. See discussion in - * https://github.com/zephyrproject-rtos/zephyr/pull/87592. - */ -TOOLCHAIN_DISABLE_CLANG_WARNING(TOOLCHAIN_WARNING_UNNEEDED_INTERNAL_DECLARATION) static const uint8_t test_response_read_data_start[5] = { 0xbf, 0x63, 0x76, 0x61, 0x6c }; @@ -92,7 +86,6 @@ static const uint8_t test_response_read_data_start[5] = { static const uint8_t test_response_read_data_end[1] = { 0xff }; -TOOLCHAIN_ENABLE_CLANG_WARNING(TOOLCHAIN_WARNING_UNNEEDED_INTERNAL_DECLARATION) static void cleanup_test(void *p) { @@ -525,6 +518,14 @@ ZTEST(settings_mgmt, test_set_read) zassert_true(smp_header->nh_len > sys_cpu_to_be16(TEST_RESPONSE_READ_DATA_LENGTH), "SMP header length mismatch"); + zassert_mem_equal(nb->data, test_response_read_data_start, + sizeof(test_response_read_data_start), + "SMP response start mismatch"); + zassert_mem_equal(&nb->data[nb->len - sizeof(test_response_read_data_end)], + test_response_read_data_end, + sizeof(test_response_read_data_end), + "SMP response end mismatch"); + zassert_equal(smp_header->nh_flags, 0, "SMP header flags mismatch"); zassert_equal(smp_header->nh_op, MGMT_OP_READ_RSP, "SMP header operation mismatch"); @@ -629,6 +630,14 @@ ZTEST(settings_mgmt, test_read_max_size) zassert_true(smp_header->nh_len > sys_cpu_to_be16(TEST_RESPONSE_READ_DATA_LENGTH), "SMP header length mismatch"); + zassert_mem_equal(nb->data, test_response_read_data_start, + sizeof(test_response_read_data_start), + "SMP response start mismatch"); + zassert_mem_equal(&nb->data[nb->len - sizeof(test_response_read_data_end)], + test_response_read_data_end, + sizeof(test_response_read_data_end), + "SMP response end mismatch"); + zassert_equal(smp_header->nh_flags, 0, "SMP header flags mismatch"); zassert_equal(smp_header->nh_op, MGMT_OP_READ_RSP, "SMP header operation mismatch"); zassert_equal(smp_header->nh_group, sys_cpu_to_be16(MGMT_GROUP_ID_SETTINGS), @@ -784,6 +793,14 @@ ZTEST(settings_mgmt, test_set_disallowed) zassert_true(smp_header->nh_len > sys_cpu_to_be16(TEST_RESPONSE_READ_DATA_LENGTH), "SMP header length mismatch"); + zassert_mem_equal(nb->data, test_response_read_data_start, + sizeof(test_response_read_data_start), + "SMP response start mismatch"); + zassert_mem_equal(&nb->data[nb->len - sizeof(test_response_read_data_end)], + test_response_read_data_end, + sizeof(test_response_read_data_end), + "SMP response end mismatch"); + zassert_equal(smp_header->nh_flags, 0, "SMP header flags mismatch"); zassert_equal(smp_header->nh_op, MGMT_OP_READ_RSP, "SMP header operation mismatch"); zassert_equal(smp_header->nh_group, sys_cpu_to_be16(MGMT_GROUP_ID_SETTINGS), @@ -914,6 +931,14 @@ ZTEST(settings_mgmt, test_set_disallowed) zassert_true(smp_header->nh_len > sys_cpu_to_be16(TEST_RESPONSE_READ_DATA_LENGTH), "SMP header length mismatch"); + zassert_mem_equal(nb->data, test_response_read_data_start, + sizeof(test_response_read_data_start), + "SMP response start mismatch"); + zassert_mem_equal(&nb->data[nb->len - sizeof(test_response_read_data_end)], + test_response_read_data_end, + sizeof(test_response_read_data_end), + "SMP response end mismatch"); + zassert_equal(smp_header->nh_flags, 0, "SMP header flags mismatch"); zassert_equal(smp_header->nh_op, MGMT_OP_READ_RSP, "SMP header operation mismatch"); zassert_equal(smp_header->nh_group, sys_cpu_to_be16(MGMT_GROUP_ID_SETTINGS), @@ -1186,6 +1211,14 @@ ZTEST(settings_mgmt, test_delete) zassert_true(smp_header->nh_len > sys_cpu_to_be16(TEST_RESPONSE_READ_DATA_LENGTH), "SMP header length mismatch"); + zassert_mem_equal(nb->data, test_response_read_data_start, + sizeof(test_response_read_data_start), + "SMP response start mismatch"); + zassert_mem_equal(&nb->data[nb->len - sizeof(test_response_read_data_end)], + test_response_read_data_end, + sizeof(test_response_read_data_end), + "SMP response end mismatch"); + zassert_equal(smp_header->nh_flags, 0, "SMP header flags mismatch"); zassert_equal(smp_header->nh_op, MGMT_OP_READ_RSP, "SMP header operation mismatch"); zassert_equal(smp_header->nh_group, sys_cpu_to_be16(MGMT_GROUP_ID_SETTINGS), @@ -1313,6 +1346,14 @@ ZTEST(settings_mgmt, test_delete) zassert_true(smp_header->nh_len > sys_cpu_to_be16(TEST_RESPONSE_READ_DATA_LENGTH), "SMP header length mismatch"); + zassert_mem_equal(nb->data, test_response_read_data_start, + sizeof(test_response_read_data_start), + "SMP response start mismatch"); + zassert_mem_equal(&nb->data[nb->len - sizeof(test_response_read_data_end)], + test_response_read_data_end, + sizeof(test_response_read_data_end), + "SMP response end mismatch"); + zassert_equal(smp_header->nh_flags, 0, "SMP header flags mismatch"); zassert_equal(smp_header->nh_op, MGMT_OP_READ_RSP, "SMP header operation mismatch"); zassert_equal(smp_header->nh_group, sys_cpu_to_be16(MGMT_GROUP_ID_SETTINGS), @@ -1558,6 +1599,14 @@ ZTEST(settings_mgmt, test_delete) zassert_true(smp_header->nh_len > sys_cpu_to_be16(TEST_RESPONSE_READ_DATA_LENGTH), "SMP header length mismatch"); + zassert_mem_equal(nb->data, test_response_read_data_start, + sizeof(test_response_read_data_start), + "SMP response start mismatch"); + zassert_mem_equal(&nb->data[nb->len - sizeof(test_response_read_data_end)], + test_response_read_data_end, + sizeof(test_response_read_data_end), + "SMP response end mismatch"); + zassert_equal(smp_header->nh_flags, 0, "SMP header flags mismatch"); zassert_equal(smp_header->nh_op, MGMT_OP_READ_RSP, "SMP header operation mismatch"); zassert_equal(smp_header->nh_group, sys_cpu_to_be16(MGMT_GROUP_ID_SETTINGS), From ec3c28db0f5fad13f6adb01a393234d128aa0581 Mon Sep 17 00:00:00 2001 From: Peter Hoddie Date: Fri, 16 Jan 2026 17:52:43 -0800 Subject: [PATCH 2326/3659] boards: adafruit: correct gpio pin numbers for feathers These DTS uses absolute GPIO numbers for some pins where relative pin numbers are required. This causes crash on booth when these pins are enabled. Follow on PR to #101857. Signed-off-by: Peter Hoddie --- .../adafruit_feather_esp32s2_tft.dts | 6 +++--- .../adafruit_feather_esp32s2_tft_reverse.dts | 6 +++--- .../feather_esp32s2/feather_connector.dtsi | 16 ++++++++-------- .../feather_esp32s2/feather_connector_tft.dtsi | 12 ++++++------ .../feather_esp32s3/feather_connector.dtsi | 12 ++++++------ .../feather_esp32s3_tft/feather_connector.dtsi | 12 ++++++------ ...afruit_feather_esp32s3_tft_reverse_procpu.dts | 6 +++--- .../feather_connector.dtsi | 12 ++++++------ 8 files changed, 41 insertions(+), 41 deletions(-) diff --git a/boards/adafruit/feather_esp32s2/adafruit_feather_esp32s2_tft.dts b/boards/adafruit/feather_esp32s2/adafruit_feather_esp32s2_tft.dts index 114a2d9cb91d..6fa376564196 100644 --- a/boards/adafruit/feather_esp32s2/adafruit_feather_esp32s2_tft.dts +++ b/boards/adafruit/feather_esp32s2/adafruit_feather_esp32s2_tft.dts @@ -27,7 +27,7 @@ led1: led_1 { label = "TFT Backlight"; - gpios = <&gpio1 45 GPIO_ACTIVE_HIGH>; + gpios = <&gpio1 13 GPIO_ACTIVE_HIGH>; }; }; @@ -46,8 +46,8 @@ mipi_dbi { compatible = "zephyr,mipi-dbi-spi"; spi-dev = <&spi2>; - dc-gpios = <&gpio1 39 GPIO_ACTIVE_HIGH>; - reset-gpios = <&gpio1 40 GPIO_ACTIVE_LOW>; + dc-gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>; + reset-gpios = <&gpio1 8 GPIO_ACTIVE_LOW>; write-only; #address-cells = <1>; #size-cells = <0>; diff --git a/boards/adafruit/feather_esp32s2/adafruit_feather_esp32s2_tft_reverse.dts b/boards/adafruit/feather_esp32s2/adafruit_feather_esp32s2_tft_reverse.dts index fe6a7eba826d..8896f38433b2 100644 --- a/boards/adafruit/feather_esp32s2/adafruit_feather_esp32s2_tft_reverse.dts +++ b/boards/adafruit/feather_esp32s2/adafruit_feather_esp32s2_tft_reverse.dts @@ -28,7 +28,7 @@ led1: led_1 { label = "TFT Backlight"; - gpios = <&gpio1 45 GPIO_ACTIVE_HIGH>; + gpios = <&gpio1 13 GPIO_ACTIVE_HIGH>; }; }; @@ -60,8 +60,8 @@ mipi_dbi { compatible = "zephyr,mipi-dbi-spi"; spi-dev = <&spi2>; - dc-gpios = <&gpio1 40 GPIO_ACTIVE_HIGH>; - reset-gpios = <&gpio1 41 GPIO_ACTIVE_LOW>; + dc-gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>; + reset-gpios = <&gpio1 9 GPIO_ACTIVE_LOW>; write-only; #address-cells = <1>; #size-cells = <0>; diff --git a/boards/adafruit/feather_esp32s2/feather_connector.dtsi b/boards/adafruit/feather_esp32s2/feather_connector.dtsi index dd39d9404dba..9893f46b834a 100644 --- a/boards/adafruit/feather_esp32s2/feather_connector.dtsi +++ b/boards/adafruit/feather_esp32s2/feather_connector.dtsi @@ -18,14 +18,14 @@ <3 0 &gpio0 15 0>, /* A3 */ <4 0 &gpio0 14 0>, /* A4 */ <5 0 &gpio0 8 0>, /* A5 */ - <6 0 &gpio1 36 0>, /* SCK */ - <7 0 &gpio1 35 0>, /* MOSI */ - <8 0 &gpio1 37 0>, /* MISO */ - <9 0 &gpio1 38 0>, /* RX */ - <10 0 &gpio1 39 0>, /* TX */ - <11 0 &gpio1 43 0>, /* DB */ - <12 0 &gpio1 3 0>, /* SDA */ - <13 0 &gpio1 4 0>, /* SCL */ + <6 0 &gpio1 4 0>, /* SCK */ + <7 0 &gpio1 3 0>, /* MOSI */ + <8 0 &gpio1 5 0>, /* MISO */ + <9 0 &gpio1 6 0>, /* RX */ + <10 0 &gpio1 7 0>, /* TX */ + <11 0 &gpio1 11 0>, /* DB */ + <12 0 &gpio0 3 0>, /* SDA */ + <13 0 &gpio0 4 0>, /* SCL */ <14 0 &gpio0 5 0>, /* D5 */ <15 0 &gpio0 6 0>, /* D6 */ <16 0 &gpio0 9 0>, /* D9 */ diff --git a/boards/adafruit/feather_esp32s2/feather_connector_tft.dtsi b/boards/adafruit/feather_esp32s2/feather_connector_tft.dtsi index 9c1083d1208c..b2f3d514ff41 100644 --- a/boards/adafruit/feather_esp32s2/feather_connector_tft.dtsi +++ b/boards/adafruit/feather_esp32s2/feather_connector_tft.dtsi @@ -18,14 +18,14 @@ <3 0 &gpio0 15 0>, /* A3 */ <4 0 &gpio0 14 0>, /* A4 */ <5 0 &gpio0 8 0>, /* A5 */ - <6 0 &gpio1 36 0>, /* SCK */ - <7 0 &gpio1 35 0>, /* MOSI */ - <8 0 &gpio1 37 0>, /* MISO */ + <6 0 &gpio1 4 0>, /* SCK */ + <7 0 &gpio1 3 0>, /* MOSI */ + <8 0 &gpio1 5 0>, /* MISO */ <9 0 &gpio0 2 0>, /* RX */ <10 0 &gpio0 1 0>, /* TX */ - <11 0 &gpio1 43 0>, /* DB */ - <12 0 &gpio1 42 0>, /* SDA */ - <13 0 &gpio1 41 0>, /* SCL */ + <11 0 &gpio1 11 0>, /* DB */ + <12 0 &gpio1 10 0>, /* SDA */ + <13 0 &gpio1 9 0>, /* SCL */ <14 0 &gpio0 5 0>, /* D5 */ <15 0 &gpio0 6 0>, /* D6 */ <16 0 &gpio0 9 0>, /* D9 */ diff --git a/boards/adafruit/feather_esp32s3/feather_connector.dtsi b/boards/adafruit/feather_esp32s3/feather_connector.dtsi index d4c567e0830d..1d25345c80d3 100644 --- a/boards/adafruit/feather_esp32s3/feather_connector.dtsi +++ b/boards/adafruit/feather_esp32s3/feather_connector.dtsi @@ -17,12 +17,12 @@ <3 0 &gpio0 15 0>, /* A3 */ <4 0 &gpio0 14 0>, /* A4 */ <5 0 &gpio0 8 0>, /* A5 */ - <6 0 &gpio1 36 0>, /* SCK */ - <7 0 &gpio1 35 0>, /* MOSI */ - <8 0 &gpio1 37 0>, /* MISO */ - <9 0 &gpio1 38 0>, /* RX */ - <10 0 &gpio1 39 0>, /* TX */ - <11 0 &gpio1 44 0>, /* DB */ + <6 0 &gpio1 4 0>, /* SCK */ + <7 0 &gpio1 3 0>, /* MOSI */ + <8 0 &gpio1 5 0>, /* MISO */ + <9 0 &gpio1 6 0>, /* RX */ + <10 0 &gpio1 7 0>, /* TX */ + <11 0 &gpio1 12 0>, /* DB */ <12 0 &gpio0 3 0>, /* SDA */ <13 0 &gpio0 4 0>, /* SCL */ <14 0 &gpio0 5 0>, /* D5 */ diff --git a/boards/adafruit/feather_esp32s3_tft/feather_connector.dtsi b/boards/adafruit/feather_esp32s3_tft/feather_connector.dtsi index 675ab2395f61..999591779a14 100644 --- a/boards/adafruit/feather_esp32s3_tft/feather_connector.dtsi +++ b/boards/adafruit/feather_esp32s3_tft/feather_connector.dtsi @@ -17,14 +17,14 @@ <3 0 &gpio0 15 0>, /* A3 */ <4 0 &gpio0 14 0>, /* A4 */ <5 0 &gpio0 8 0>, /* A5 */ - <6 0 &gpio1 36 0>, /* SCK */ - <7 0 &gpio1 35 0>, /* MOSI */ - <8 0 &gpio1 37 0>, /* MISO */ + <6 0 &gpio1 4 0>, /* SCK */ + <7 0 &gpio1 3 0>, /* MOSI */ + <8 0 &gpio1 5 0>, /* MISO */ <9 0 &gpio0 2 0>, /* RX */ <10 0 &gpio0 1 0>, /* TX */ - <11 0 &gpio1 44 0>, /* DB */ - <12 0 &gpio1 42 0>, /* SDA */ - <13 0 &gpio1 41 0>, /* SCL */ + <11 0 &gpio1 12 0>, /* DB */ + <12 0 &gpio1 10 0>, /* SDA */ + <13 0 &gpio1 9 0>, /* SCL */ <14 0 &gpio0 5 0>, /* D5 */ <15 0 &gpio0 6 0>, /* D6 */ <16 0 &gpio0 9 0>, /* D9 */ diff --git a/boards/adafruit/feather_esp32s3_tft_reverse/adafruit_feather_esp32s3_tft_reverse_procpu.dts b/boards/adafruit/feather_esp32s3_tft_reverse/adafruit_feather_esp32s3_tft_reverse_procpu.dts index 841e85761a15..1595d33cd86e 100644 --- a/boards/adafruit/feather_esp32s3_tft_reverse/adafruit_feather_esp32s3_tft_reverse_procpu.dts +++ b/boards/adafruit/feather_esp32s3_tft_reverse/adafruit_feather_esp32s3_tft_reverse_procpu.dts @@ -75,7 +75,7 @@ led1: led_1 { label = "TFT Backlight"; - gpios = <&gpio1 45 GPIO_ACTIVE_HIGH>; + gpios = <&gpio1 13 GPIO_ACTIVE_HIGH>; }; }; @@ -103,8 +103,8 @@ mipi_dbi { compatible = "zephyr,mipi-dbi-spi"; spi-dev = <&spi2>; - dc-gpios = <&gpio1 40 GPIO_ACTIVE_HIGH>; - reset-gpios = <&gpio1 41 GPIO_ACTIVE_LOW>; + dc-gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>; + reset-gpios = <&gpio1 9 GPIO_ACTIVE_LOW>; write-only; #address-cells = <1>; #size-cells = <0>; diff --git a/boards/adafruit/feather_esp32s3_tft_reverse/feather_connector.dtsi b/boards/adafruit/feather_esp32s3_tft_reverse/feather_connector.dtsi index 6c24ae9d0bce..8be241dd24dc 100644 --- a/boards/adafruit/feather_esp32s3_tft_reverse/feather_connector.dtsi +++ b/boards/adafruit/feather_esp32s3_tft_reverse/feather_connector.dtsi @@ -18,12 +18,12 @@ <3 0 &gpio0 15 0>, /* A3 */ <4 0 &gpio0 14 0>, /* A4 */ <5 0 &gpio0 8 0>, /* A5 */ - <6 0 &gpio1 36 0>, /* SCK */ - <7 0 &gpio1 35 0>, /* MOSI */ - <8 0 &gpio1 37 0>, /* MISO */ - <9 0 &gpio1 38 0>, /* RX */ - <10 0 &gpio1 39 0>, /* TX */ - <11 0 &gpio1 46 0>, /* DB */ + <6 0 &gpio1 4 0>, /* SCK */ + <7 0 &gpio1 3 0>, /* MOSI */ + <8 0 &gpio1 5 0>, /* MISO */ + <9 0 &gpio1 6 0>, /* RX */ + <10 0 &gpio1 7 0>, /* TX */ + <11 0 &gpio1 14 0>, /* DB */ <12 0 &gpio0 3 0>, /* SDA */ <13 0 &gpio0 4 0>, /* SCL */ <14 0 &gpio0 5 0>, /* D5 */ From 215a35c78f20254c425b669e272c575b54ac3a42 Mon Sep 17 00:00:00 2001 From: Lucien Zhao Date: Sun, 4 Jan 2026 16:42:34 +0800 Subject: [PATCH 2327/3659] dts: bindings: hwinfo: add nxp,rcm-hwinfo and nxp,sim-uuid.yaml - add nxp,rcm-hwinfo.yaml and nxp,sim-uuid.yaml to support hwinfo features by using dts ways Signed-off-by: Lucien Zhao --- dts/bindings/hwinfo/nxp,rcm-hwinfo.yaml | 12 ++++++++++++ dts/bindings/hwinfo/nxp,sim-uuid.yaml | 12 ++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 dts/bindings/hwinfo/nxp,rcm-hwinfo.yaml create mode 100644 dts/bindings/hwinfo/nxp,sim-uuid.yaml diff --git a/dts/bindings/hwinfo/nxp,rcm-hwinfo.yaml b/dts/bindings/hwinfo/nxp,rcm-hwinfo.yaml new file mode 100644 index 000000000000..1318c10fd2c8 --- /dev/null +++ b/dts/bindings/hwinfo/nxp,rcm-hwinfo.yaml @@ -0,0 +1,12 @@ +# Copyright 2026 NXP +# SPDX-License-Identifier: Apache-2.0 + +description: NXP RCM get reset cause flags + +compatible: "nxp,rcm-hwinfo" + +include: base.yaml + +properties: + reg: + required: true diff --git a/dts/bindings/hwinfo/nxp,sim-uuid.yaml b/dts/bindings/hwinfo/nxp,sim-uuid.yaml new file mode 100644 index 000000000000..28ba93c09a70 --- /dev/null +++ b/dts/bindings/hwinfo/nxp,sim-uuid.yaml @@ -0,0 +1,12 @@ +# Copyright 2026 NXP +# SPDX-License-Identifier: Apache-2.0 + +description: NXP SIM 128-bit Unique identifier + +compatible: "nxp,sim-uuid" + +include: base.yaml + +properties: + reg: + required: true From eb43ffc6b801a7661e3789c81d309113349c3ebe Mon Sep 17 00:00:00 2001 From: Lucien Zhao Date: Mon, 19 Jan 2026 18:04:05 +0800 Subject: [PATCH 2328/3659] dts: arm: nxp: Add specific compatible strings for RCM and SIM Add vendor-specific compatible strings to RCM and SIM nodes: - "nxp,rcm-hwinfo" for Reset Control Module (hwinfo-reset functionality) - "nxp,sim-uuid" for System Integration Module (hwinfo-UUID functionality) Signed-off-by: Lucien Zhao --- dts/arm/nxp/nxp_k2x.dtsi | 7 ++++++- dts/arm/nxp/nxp_k32l2b3.dtsi | 7 ++++++- dts/arm/nxp/nxp_k6x.dtsi | 7 ++++++- dts/arm/nxp/nxp_k8x.dtsi | 7 ++++++- dts/arm/nxp/nxp_kl25z.dtsi | 7 ++++++- dts/arm/nxp/nxp_kv5x.dtsi | 7 ++++++- dts/arm/nxp/nxp_kw2xd.dtsi | 13 +++++++++++-- dts/arm/nxp/nxp_kw40z.dtsi | 13 +++++++++++-- dts/arm/nxp/nxp_kw41z.dtsi | 7 ++++++- dts/arm/nxp/nxp_mcxc_common.dtsi | 7 ++++++- 10 files changed, 70 insertions(+), 12 deletions(-) diff --git a/dts/arm/nxp/nxp_k2x.dtsi b/dts/arm/nxp/nxp_k2x.dtsi index c56eec74a558..9b6850a5003f 100644 --- a/dts/arm/nxp/nxp_k2x.dtsi +++ b/dts/arm/nxp/nxp_k2x.dtsi @@ -81,8 +81,13 @@ clock-frequency = <32768>; }; + rcm: rcm@4007F000 { + compatible = "nxp,rcm-hwinfo"; + reg = <0x4007F000 0x1000>; + }; + sim: sim@40047000 { - compatible = "nxp,kinetis-sim"; + compatible = "nxp,kinetis-sim", "nxp,sim-uuid"; reg = <0x40047000 0x1060>; #clock-cells = <3>; diff --git a/dts/arm/nxp/nxp_k32l2b3.dtsi b/dts/arm/nxp/nxp_k32l2b3.dtsi index 223c419dce4b..0c2ced6dc83f 100644 --- a/dts/arm/nxp/nxp_k32l2b3.dtsi +++ b/dts/arm/nxp/nxp_k32l2b3.dtsi @@ -87,8 +87,13 @@ #clock-cells = <1>; }; + rcm: rcm@4007F000 { + compatible = "nxp,rcm-hwinfo"; + reg = <0x4007F000 0x1000>; + }; + sim: sim@40047000 { - compatible = "nxp,kinetis-sim"; + compatible = "nxp,kinetis-sim", "nxp,sim-uuid"; reg = <0x40047000 0x1060>; #clock-cells = <3>; diff --git a/dts/arm/nxp/nxp_k6x.dtsi b/dts/arm/nxp/nxp_k6x.dtsi index bd8a859aebb1..0f186f705399 100644 --- a/dts/arm/nxp/nxp_k6x.dtsi +++ b/dts/arm/nxp/nxp_k6x.dtsi @@ -112,8 +112,13 @@ prescaler = <32768>; }; + rcm: rcm@4007F000 { + compatible = "nxp,rcm-hwinfo"; + reg = <0x4007F000 0x1000>; + }; + sim: sim@40047000 { - compatible = "nxp,kinetis-sim"; + compatible = "nxp,kinetis-sim", "nxp,sim-uuid"; reg = <0x40047000 0x1060>; #clock-cells = <3>; diff --git a/dts/arm/nxp/nxp_k8x.dtsi b/dts/arm/nxp/nxp_k8x.dtsi index 351a6f750efc..38ae65795291 100644 --- a/dts/arm/nxp/nxp_k8x.dtsi +++ b/dts/arm/nxp/nxp_k8x.dtsi @@ -45,8 +45,13 @@ status = "disabled"; }; + rcm: rcm@4007F000 { + compatible = "nxp,rcm-hwinfo"; + reg = <0x4007F000 0x1000>; + }; + sim: sim@40047000 { - compatible = "nxp,kinetis-sim"; + compatible = "nxp,kinetis-sim", "nxp,sim-uuid"; reg = <0x40047000 0x2000>; #clock-cells = <3>; diff --git a/dts/arm/nxp/nxp_kl25z.dtsi b/dts/arm/nxp/nxp_kl25z.dtsi index 068071fbf514..af4091f9b28e 100644 --- a/dts/arm/nxp/nxp_kl25z.dtsi +++ b/dts/arm/nxp/nxp_kl25z.dtsi @@ -82,8 +82,13 @@ status = "disabled"; }; + rcm: rcm@4007F000 { + compatible = "nxp,rcm-hwinfo"; + reg = <0x4007F000 0x1000>; + }; + sim: sim@40047000 { - compatible = "nxp,kinetis-sim"; + compatible = "nxp,kinetis-sim", "nxp,sim-uuid"; reg = <0x40047000 0x1060>; #clock-cells = <3>; diff --git a/dts/arm/nxp/nxp_kv5x.dtsi b/dts/arm/nxp/nxp_kv5x.dtsi index ae2107303435..82d8c9d16f35 100644 --- a/dts/arm/nxp/nxp_kv5x.dtsi +++ b/dts/arm/nxp/nxp_kv5x.dtsi @@ -40,8 +40,13 @@ status = "disabled"; }; + rcm: rcm@4007F000 { + compatible = "nxp,rcm-hwinfo"; + reg = <0x4007F000 0x1000>; + }; + sim: sim@40047000 { - compatible = "nxp,kinetis-sim"; + compatible = "nxp,kinetis-sim", "nxp,sim-uuid"; reg = <0x40047000 0x2000>; #clock-cells = <3>; diff --git a/dts/arm/nxp/nxp_kw2xd.dtsi b/dts/arm/nxp/nxp_kw2xd.dtsi index f1fedeb61269..bf0ce0335adf 100644 --- a/dts/arm/nxp/nxp_kw2xd.dtsi +++ b/dts/arm/nxp/nxp_kw2xd.dtsi @@ -1,4 +1,8 @@ -/* SPDX-License-Identifier: Apache-2.0 */ +/* + * Copyright 2026 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ #include #include @@ -79,8 +83,13 @@ clock-frequency = <32768>; }; + rcm: rcm@4007F000 { + compatible = "nxp,rcm-hwinfo"; + reg = <0x4007F000 0x1000>; + }; + sim: sim@40047000 { - compatible = "nxp,kinetis-sim"; + compatible = "nxp,kinetis-sim", "nxp,sim-uuid"; reg = <0x40047000 0x1060>; #clock-cells = <3>; diff --git a/dts/arm/nxp/nxp_kw40z.dtsi b/dts/arm/nxp/nxp_kw40z.dtsi index cd89adf080ce..88feb64b3dbb 100644 --- a/dts/arm/nxp/nxp_kw40z.dtsi +++ b/dts/arm/nxp/nxp_kw40z.dtsi @@ -1,4 +1,8 @@ -/* SPDX-License-Identifier: Apache-2.0 */ +/* + * Copyright 2026 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ #include #include @@ -56,8 +60,13 @@ clock-frequency = <32768>; }; + rcm: rcm@4007F000 { + compatible = "nxp,rcm-hwinfo"; + reg = <0x4007F000 0x1000>; + }; + sim: sim@40047000 { - compatible = "nxp,kinetis-sim"; + compatible = "nxp,kinetis-sim", "nxp,sim-uuid"; reg = <0x40047000 0x1060>; #clock-cells = <3>; diff --git a/dts/arm/nxp/nxp_kw41z.dtsi b/dts/arm/nxp/nxp_kw41z.dtsi index 3896629aa55e..19680e26d6b8 100644 --- a/dts/arm/nxp/nxp_kw41z.dtsi +++ b/dts/arm/nxp/nxp_kw41z.dtsi @@ -63,8 +63,13 @@ prescaler = <32768>; }; + rcm: rcm@4007F000 { + compatible = "nxp,rcm-hwinfo"; + reg = <0x4007F000 0x1000>; + }; + sim: sim@40047000 { - compatible = "nxp,kinetis-sim"; + compatible = "nxp,kinetis-sim", "nxp,sim-uuid"; reg = <0x40047000 0x1060>; #clock-cells = <3>; diff --git a/dts/arm/nxp/nxp_mcxc_common.dtsi b/dts/arm/nxp/nxp_mcxc_common.dtsi index 2756aa6b7721..90a68cd8e058 100644 --- a/dts/arm/nxp/nxp_mcxc_common.dtsi +++ b/dts/arm/nxp/nxp_mcxc_common.dtsi @@ -92,8 +92,13 @@ #clock-cells = <1>; }; + rcm: rcm@4007F000 { + compatible = "nxp,rcm-hwinfo"; + reg = <0x4007F000 0x1000>; + }; + sim: sim@40047000 { - compatible = "nxp,kinetis-sim"; + compatible = "nxp,kinetis-sim", "nxp,sim-uuid"; reg = <0x40047000 0x1060>; #clock-cells = <3>; From 0a6e0160b4f6910a5810a59a0be3328ee9171acd Mon Sep 17 00:00:00 2001 From: Lucien Zhao Date: Sun, 4 Jan 2026 16:47:09 +0800 Subject: [PATCH 2329/3659] hwinfo: mcux_sim/mcux_rcm: Add new dependency Change to use DT_HAS_NXP_SIM_UUID_ENABLED/DT_HAS_NXP_RCM_HWINFO_ENABLED as the dependency condition for HWINFO_MCUX_SIM/HWINFO_MCUX_RCM to enable the driver when the nxp,sim-uuid/nxp,rcm-hwinfo compatible is present in the devicetree. Signed-off-by: Lucien Zhao --- drivers/hwinfo/Kconfig.mcux_rcm | 2 +- drivers/hwinfo/Kconfig.mcux_sim | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/hwinfo/Kconfig.mcux_rcm b/drivers/hwinfo/Kconfig.mcux_rcm index 871bf5be2606..8e687889c3bb 100644 --- a/drivers/hwinfo/Kconfig.mcux_rcm +++ b/drivers/hwinfo/Kconfig.mcux_rcm @@ -4,7 +4,7 @@ config HWINFO_MCUX_RCM bool "NXP kinetis reset cause" default y - depends on HAS_MCUX_RCM + depends on DT_HAS_NXP_RCM_HWINFO_ENABLED select HWINFO_HAS_DRIVER help Enable NXP kinetis mcux RCM hwinfo driver. diff --git a/drivers/hwinfo/Kconfig.mcux_sim b/drivers/hwinfo/Kconfig.mcux_sim index 54224790a282..0b84a6b29ff8 100644 --- a/drivers/hwinfo/Kconfig.mcux_sim +++ b/drivers/hwinfo/Kconfig.mcux_sim @@ -4,7 +4,7 @@ config HWINFO_MCUX_SIM bool "NXP kinetis SIM device ID" default y - depends on HAS_MCUX_SIM + depends on DT_HAS_NXP_SIM_UUID_ENABLED select HWINFO_HAS_DRIVER help Enable NXP kinetis mcux SIM hwinfo driver. From 0e0757cc3c58dadcada2b753270ff25ecd40720e Mon Sep 17 00:00:00 2001 From: Lucien Zhao Date: Mon, 19 Jan 2026 18:01:46 +0800 Subject: [PATCH 2330/3659] soc: nxp: delete HAS_MCUX_SIM/RCM kconfig symbols - Remove HAS_MCUX_SIM and HAS_MCUX_RCM Kconfig symbols on NXP platforms - delete HAS_MCUX_SIM/HAS_MCUX_RCM kconfigs, use dt ways to get enabled SIM/RCM devices Signed-off-by: Lucien Zhao --- modules/hal_nxp/mcux/Kconfig.mcux | 12 ------------ soc/nxp/kinetis/k2x/Kconfig | 4 ---- soc/nxp/kinetis/k32lx/Kconfig | 2 -- soc/nxp/kinetis/k6x/Kconfig | 4 ---- soc/nxp/kinetis/k8x/Kconfig | 2 -- soc/nxp/kinetis/ke1xf/Kconfig | 2 -- soc/nxp/kinetis/ke1xz/Kconfig | 1 - soc/nxp/kinetis/kl2x/Kconfig | 2 -- soc/nxp/kinetis/kv5x/Kconfig | 2 -- soc/nxp/kinetis/kwx/Kconfig | 8 -------- soc/nxp/mcx/mcxc/Kconfig | 2 -- soc/nxp/mcx/mcxe/mcxe24x/Kconfig | 1 - 12 files changed, 42 deletions(-) diff --git a/modules/hal_nxp/mcux/Kconfig.mcux b/modules/hal_nxp/mcux/Kconfig.mcux index a771ce44624b..c12ffb7e8dd8 100644 --- a/modules/hal_nxp/mcux/Kconfig.mcux +++ b/modules/hal_nxp/mcux/Kconfig.mcux @@ -24,12 +24,6 @@ config HAS_MCUX_CACHE help Set if the L1 or L2 cache is present in the SoC. -config HAS_MCUX_SIM - bool - help - Set if the system integration module (SIM) module is present in the - SoC. - config HAS_MCUX_SRC bool help @@ -41,12 +35,6 @@ config HAS_MCUX_RDC help Set if the RDC module is present in the SoC. -config HAS_MCUX_RCM - bool - help - Set if the Reset Control Module (RCM) module is present in - the SoC. - config HAS_MCUX_XCACHE bool help diff --git a/soc/nxp/kinetis/k2x/Kconfig b/soc/nxp/kinetis/k2x/Kconfig index 277962d7d943..dc1b29812594 100644 --- a/soc/nxp/kinetis/k2x/Kconfig +++ b/soc/nxp/kinetis/k2x/Kconfig @@ -18,19 +18,15 @@ config SOC_SERIES_KINETIS_K2X config SOC_MK22F51212 select HAS_MCUX - select HAS_MCUX_SIM select HAS_OSC select HAS_MCG select CPU_HAS_FPU - select HAS_MCUX_RCM # Note- the MK22F12 SKU is a legacy SOC, no longer officially supported by # NXP's MCUX SDK, and not recommended for new designs. config SOC_MK22F12 select HAS_MCUX - select HAS_MCUX_SIM select HAS_OSC select HAS_MCG select CPU_HAS_FPU - select HAS_MCUX_RCM select CPU_HAS_NXP_SYSMPU diff --git a/soc/nxp/kinetis/k32lx/Kconfig b/soc/nxp/kinetis/k32lx/Kconfig index 6f5e3df2370c..e5226ba9b1e3 100644 --- a/soc/nxp/kinetis/k32lx/Kconfig +++ b/soc/nxp/kinetis/k32lx/Kconfig @@ -10,8 +10,6 @@ config SOC_SERIES_K32LX select CPU_CORTEX_M_HAS_VTOR select CPU_CORTEX_M_HAS_SYSTICK select HAS_MCUX - select HAS_MCUX_SIM - select HAS_MCUX_RCM select CLOCK_CONTROL select SOC_RESET_HOOK select SOC_EARLY_INIT_HOOK diff --git a/soc/nxp/kinetis/k6x/Kconfig b/soc/nxp/kinetis/k6x/Kconfig index 0bffab6dd656..4f6d8bb72389 100644 --- a/soc/nxp/kinetis/k6x/Kconfig +++ b/soc/nxp/kinetis/k6x/Kconfig @@ -14,19 +14,15 @@ config SOC_SERIES_KINETIS_K6X config SOC_MK64F12 select HAS_MCUX - select HAS_MCUX_SIM select HAS_OSC select HAS_MCG select CPU_HAS_FPU - select HAS_MCUX_RCM config SOC_MK66F18 select HAS_MCUX - select HAS_MCUX_SIM select HAS_OSC select HAS_MCG select CPU_HAS_FPU - select HAS_MCUX_RCM if SOC_MK66F18 diff --git a/soc/nxp/kinetis/k8x/Kconfig b/soc/nxp/kinetis/k8x/Kconfig index f644593669b8..f858af6b33d7 100644 --- a/soc/nxp/kinetis/k8x/Kconfig +++ b/soc/nxp/kinetis/k8x/Kconfig @@ -12,10 +12,8 @@ config SOC_SERIES_KINETIS_K8X select CPU_HAS_FPU select CLOCK_CONTROL select HAS_MCUX - select HAS_MCUX_SIM select HAS_OSC select HAS_MCG - select HAS_MCUX_RCM select HAS_MCUX_CACHE select SOC_RESET_HOOK select SOC_EARLY_INIT_HOOK diff --git a/soc/nxp/kinetis/ke1xf/Kconfig b/soc/nxp/kinetis/ke1xf/Kconfig index da82f0983f12..be81498f5378 100644 --- a/soc/nxp/kinetis/ke1xf/Kconfig +++ b/soc/nxp/kinetis/ke1xf/Kconfig @@ -13,8 +13,6 @@ config SOC_SERIES_KINETIS_KE1XF select CLOCK_CONTROL select HAS_MCUX select HAS_MCUX_CACHE - select HAS_MCUX_SIM - select HAS_MCUX_RCM select SOC_RESET_HOOK select SOC_EARLY_INIT_HOOK select HAS_PM diff --git a/soc/nxp/kinetis/ke1xz/Kconfig b/soc/nxp/kinetis/ke1xz/Kconfig index 633b24ee7302..f8e878cb13ae 100644 --- a/soc/nxp/kinetis/ke1xz/Kconfig +++ b/soc/nxp/kinetis/ke1xz/Kconfig @@ -14,4 +14,3 @@ config SOC_SERIES_KE1XZ select HAS_PM select SOC_RESET_HOOK select SOC_EARLY_INIT_HOOK - select HAS_MCUX_RCM diff --git a/soc/nxp/kinetis/kl2x/Kconfig b/soc/nxp/kinetis/kl2x/Kconfig index bac4eb5d67a2..7643488e68ee 100644 --- a/soc/nxp/kinetis/kl2x/Kconfig +++ b/soc/nxp/kinetis/kl2x/Kconfig @@ -15,7 +15,5 @@ config SOC_SERIES_KINETIS_KL2X config SOC_MKL25Z4 select CPU_CORTEX_M0PLUS select HAS_MCUX - select HAS_MCUX_SIM select HAS_OSC select HAS_MCG - select HAS_MCUX_RCM diff --git a/soc/nxp/kinetis/kv5x/Kconfig b/soc/nxp/kinetis/kv5x/Kconfig index 086e2f7f85b7..cbbec3bc9865 100644 --- a/soc/nxp/kinetis/kv5x/Kconfig +++ b/soc/nxp/kinetis/kv5x/Kconfig @@ -14,9 +14,7 @@ config SOC_SERIES_KINETIS_KV5X select CPU_HAS_DCACHE select CLOCK_CONTROL select HAS_MCUX - select HAS_MCUX_SIM select HAS_OSC select HAS_MCG - select HAS_MCUX_RCM select SOC_RESET_HOOK select SOC_EARLY_INIT_HOOK diff --git a/soc/nxp/kinetis/kwx/Kconfig b/soc/nxp/kinetis/kwx/Kconfig index 58b8a55e105a..4a2db898b244 100644 --- a/soc/nxp/kinetis/kwx/Kconfig +++ b/soc/nxp/kinetis/kwx/Kconfig @@ -15,32 +15,24 @@ config SOC_MKW22D5 select CPU_CORTEX_M4 select CPU_CORTEX_M_HAS_DWT select HAS_MCUX - select HAS_MCUX_SIM select HAS_OSC select HAS_MCG - select HAS_MCUX_RCM config SOC_MKW24D5 select CPU_CORTEX_M4 select CPU_CORTEX_M_HAS_DWT select HAS_MCUX - select HAS_MCUX_SIM select HAS_OSC select HAS_MCG - select HAS_MCUX_RCM config SOC_MKW40Z4 select CPU_CORTEX_M0PLUS select HAS_MCUX - select HAS_MCUX_SIM select HAS_OSC select HAS_MCG - select HAS_MCUX_RCM config SOC_MKW41Z4 select CPU_CORTEX_M0PLUS select HAS_MCUX - select HAS_MCUX_SIM select HAS_OSC select HAS_MCG - select HAS_MCUX_RCM diff --git a/soc/nxp/mcx/mcxc/Kconfig b/soc/nxp/mcx/mcxc/Kconfig index e37503336493..14aafddeb799 100644 --- a/soc/nxp/mcx/mcxc/Kconfig +++ b/soc/nxp/mcx/mcxc/Kconfig @@ -9,8 +9,6 @@ config SOC_FAMILY_MCXC select CLOCK_CONTROL select SOC_RESET_HOOK select HAS_MCUX - select HAS_MCUX_SIM - select HAS_MCUX_RCM select SOC_EARLY_INIT_HOOK select HAS_SEGGER_RTT if ZEPHYR_SEGGER_MODULE diff --git a/soc/nxp/mcx/mcxe/mcxe24x/Kconfig b/soc/nxp/mcx/mcxe/mcxe24x/Kconfig index 6ed62c6bc95e..94e69e68b807 100644 --- a/soc/nxp/mcx/mcxe/mcxe24x/Kconfig +++ b/soc/nxp/mcx/mcxe/mcxe24x/Kconfig @@ -11,7 +11,6 @@ config SOC_SERIES_MCXE24X select SOC_RESET_HOOK select CPU_HAS_ICACHE select HAS_MCUX_LMEM_CACHE - select HAS_MCUX_RCM if SOC_SERIES_MCXE24X From 0a92e6f908f4eb2d384684ba6dc852c7cf338a89 Mon Sep 17 00:00:00 2001 From: Gang Li Date: Mon, 19 Jan 2026 12:39:41 +0100 Subject: [PATCH 2331/3659] modules: hostap: Fix DPP show UNKNOWN security type after reconfiguration In case DPP reconfiguration test, if the dpp_akm has psk, it will set WPA_KEY_MGMT_PSK | WPA_KEY_MGMT_PSK_SHA256 | WPA_KEY_MGMT_FT_PSK to key_mgmt, then wifi status shows security as "Unknown". Signed-off-by: Gang Li --- modules/hostap/src/supp_api.c | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/hostap/src/supp_api.c b/modules/hostap/src/supp_api.c index 0dced93f4bed..7d6d7b662565 100644 --- a/modules/hostap/src/supp_api.c +++ b/modules/hostap/src/supp_api.c @@ -419,6 +419,7 @@ enum wifi_security_type wpas_key_mgmt_to_zephyr(bool is_hapd, void *config, int } return WIFI_SECURITY_TYPE_UNKNOWN; case WPA_KEY_MGMT_PSK_SHA256 | WPA_KEY_MGMT_PSK: + case WPA_KEY_MGMT_PSK_SHA256 | WPA_KEY_MGMT_PSK | WPA_KEY_MGMT_FT_PSK: case WPA_KEY_MGMT_SAE | WPA_KEY_MGMT_PSK: case WPA_KEY_MGMT_SAE | WPA_KEY_MGMT_PSK_SHA256: case WPA_KEY_MGMT_SAE | WPA_KEY_MGMT_PSK_SHA256 | WPA_KEY_MGMT_PSK: From 4d0852b0051c9b13b59f34bceb0c38148ad12eb1 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 19 Jan 2026 13:10:49 +0100 Subject: [PATCH 2332/3659] lib/midi2: Do not add to include path always Do not add this folder to the include path when this component is not enabled. As that creates noise and slows down builds. Signed-off-by: Alberto Escolar Piedras --- lib/midi2/CMakeLists.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/midi2/CMakeLists.txt b/lib/midi2/CMakeLists.txt index 49a11c2ed855..eff93d8a2935 100644 --- a/lib/midi2/CMakeLists.txt +++ b/lib/midi2/CMakeLists.txt @@ -1,8 +1,7 @@ # Copyright (c) 2025 Titouan Christophe # SPDX-License-Identifier: Apache-2.0 -zephyr_include_directories(.) - if(CONFIG_MIDI2_UMP_STREAM_RESPONDER) + zephyr_include_directories(.) zephyr_sources(ump_stream_responder.c) endif() From 2edece9d58db301fbe4a2b76e9a8d298252fedf0 Mon Sep 17 00:00:00 2001 From: Tim Lin Date: Tue, 11 Nov 2025 08:00:21 +0800 Subject: [PATCH 2333/3659] kernel: Add Kconfig option to disable LTO for kernel sources Some SoCs require kernel code to be placed in RAM, which makes link-time optimization (LTO) unsuitable for these files. Disabling LTO allows the affected code to be linked as separate objects and placed in specific memory regions. Running kernel code from RAM can improve execution performance, especially for timing-critical routines or context switch paths. Signed-off-by: Tim Lin --- CMakeLists.txt | 4 +++- kernel/CMakeLists.txt | 5 +++++ kernel/Kconfig | 13 +++++++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7dfdaebe1e34..8502fd51fa13 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -315,7 +315,9 @@ if(CONFIG_LTO) zephyr_compile_options($) add_link_options($) else() - zephyr_compile_options($) + set(genex_tgt_lto "$") + set(genex_lto "$") + zephyr_compile_options("$<$,${genex_tgt_lto}>:${genex_lto}>") add_link_options($) endif() endif() diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index 8906da2f6272..29af080b5a63 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -195,6 +195,11 @@ target_link_libraries(kernel zephyr_interface) endif() +# Optionally build kernel sources without LTO +if(CONFIG_KERNEL_NO_LTO) + set_target_properties(kernel PROPERTIES LTO 0) +endif() + add_dependencies(kernel zephyr_generated_headers) unset(libkernel) diff --git a/kernel/Kconfig b/kernel/Kconfig index 52ef3d531aae..ddfce2a0205f 100644 --- a/kernel/Kconfig +++ b/kernel/Kconfig @@ -1165,6 +1165,19 @@ endif # BOOTARGS endmenu +config KERNEL_NO_LTO + bool + depends on LTO + depends on XIP + help + Some SoCs require kernel code to be placed in RAM, which makes link-time + optimization (LTO) unsuitable for these files (-fno-lto). Disabling LTO + allows the affected code to be linked as separate objects and placed in + specific memory regions. + + Running kernel code from RAM can improve execution performance, especially + for timing-critical routines or context switch paths. + rsource "Kconfig.device" rsource "Kconfig.vm" rsource "Kconfig.init" From 125d88c172dc3ee7a90058615b2c59ed50842d97 Mon Sep 17 00:00:00 2001 From: Tim Lin Date: Tue, 11 Nov 2025 08:51:52 +0800 Subject: [PATCH 2334/3659] soc: it8xxx2: Select KERNEL_NO_LTO only when LTO is enabled Select KERNEL_NO_LTO only when LTO is enabled. This ensures proper handling when kernel code is placed in RAM. Signed-off-by: Tim Lin --- soc/ite/ec/it8xxx2/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/soc/ite/ec/it8xxx2/Kconfig b/soc/ite/ec/it8xxx2/Kconfig index 12b3aeabd591..5a58bf3f3f00 100644 --- a/soc/ite/ec/it8xxx2/Kconfig +++ b/soc/ite/ec/it8xxx2/Kconfig @@ -235,6 +235,7 @@ config SOC_IT8XXX2_KERNEL_IN_RAM bool "Place kernel handling code in RAM" select SOC_IT8XXX2_USE_ILM select SOC_IT8XXX2_LIBRARY_TO_RAM + select KERNEL_NO_LTO if LTO help Place kernel handling code in ILM. This can significantly improve performance. From f9de2777d993c5905b57ba3e59062b097cd2931f Mon Sep 17 00:00:00 2001 From: Aditya Ganesh Date: Wed, 19 Nov 2025 01:20:01 -0700 Subject: [PATCH 2335/3659] drivers: sensor: i3g4250d: migrate SPI support to stmemsc Convert the i3g4250d driver to use the ST MEMS SC API for SPI Signed-off-by: Aditya Ganesh --- drivers/sensor/st/i3g4250d/CMakeLists.txt | 2 +- drivers/sensor/st/i3g4250d/i3g4250d.c | 69 ++++++++------ drivers/sensor/st/i3g4250d/i3g4250d.h | 21 ++++- drivers/sensor/st/i3g4250d/i3g4250d_spi.c | 107 ---------------------- 4 files changed, 59 insertions(+), 140 deletions(-) delete mode 100644 drivers/sensor/st/i3g4250d/i3g4250d_spi.c diff --git a/drivers/sensor/st/i3g4250d/CMakeLists.txt b/drivers/sensor/st/i3g4250d/CMakeLists.txt index 42a2825ad1ca..ec6b72d1392e 100644 --- a/drivers/sensor/st/i3g4250d/CMakeLists.txt +++ b/drivers/sensor/st/i3g4250d/CMakeLists.txt @@ -2,6 +2,6 @@ zephyr_library() -zephyr_library_sources(i3g4250d.c i3g4250d_spi.c) +zephyr_library_sources(i3g4250d.c) zephyr_library_include_directories(../stmemsc) diff --git a/drivers/sensor/st/i3g4250d/i3g4250d.c b/drivers/sensor/st/i3g4250d/i3g4250d.c index 00e5a20fceaa..559f4043edb8 100644 --- a/drivers/sensor/st/i3g4250d/i3g4250d.c +++ b/drivers/sensor/st/i3g4250d/i3g4250d.c @@ -25,6 +25,8 @@ LOG_MODULE_REGISTER(i3g4250d, CONFIG_SENSOR_LOG_LEVEL); static int i3g4250d_sample_fetch(const struct device *dev, enum sensor_channel chan) { + const struct i3g4250d_device_config *cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; struct i3g4250d_data *i3g4250d = dev->data; int ret; uint8_t reg; @@ -34,12 +36,12 @@ static int i3g4250d_sample_fetch(const struct device *dev, return -ENOTSUP; } - ret = i3g4250d_flag_data_ready_get(i3g4250d->ctx, ®); + ret = i3g4250d_flag_data_ready_get(ctx, ®); if (ret < 0 || reg != 1) { return ret; } - ret = i3g4250d_angular_rate_raw_get(i3g4250d->ctx, buf); + ret = i3g4250d_angular_rate_raw_get(ctx, buf); if (ret < 0) { LOG_ERR("Failed to fetch raw data sample!"); return ret; @@ -128,13 +130,14 @@ static int i3g4250d_config_gyro(const struct device *dev, enum sensor_attribute attr, const struct sensor_value *val) { - struct i3g4250d_data *i3g4250d = dev->data; + const struct i3g4250d_device_config *cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; i3g4250d_dr_t dr_reg; switch (attr) { case SENSOR_ATTR_SAMPLING_FREQUENCY: dr_reg = gyr_odr_to_reg(val); - return i3g4250d_data_rate_set(i3g4250d->ctx, dr_reg); + return i3g4250d_data_rate_set(ctx, dr_reg); default: LOG_ERR("Gyro attribute not supported"); break; @@ -166,16 +169,13 @@ static DEVICE_API(sensor, i3g4250d_driver_api) = { static int i3g4250d_init(const struct device *dev) { - struct i3g4250d_data *i3g4250d = dev->data; + const struct i3g4250d_device_config *cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; uint8_t wai; int ret = 0; - ret = i3g4250d_spi_init(dev); - if (ret != 0) { - return ret; - } - ret = i3g4250d_device_id_get(i3g4250d->ctx, &wai); + ret = i3g4250d_device_id_get(ctx, &wai); if (ret != 0) { return ret; } @@ -186,20 +186,20 @@ static int i3g4250d_init(const struct device *dev) } /* Configure filtering chain - Gyroscope - High Pass */ - ret = i3g4250d_filter_path_set(i3g4250d->ctx, I3G4250D_LPF1_HP_ON_OUT); + ret = i3g4250d_filter_path_set(ctx, I3G4250D_LPF1_HP_ON_OUT); if (ret != 0) { LOG_ERR("Failed setting filter path"); return ret; } - ret = i3g4250d_hp_bandwidth_set(i3g4250d->ctx, I3G4250D_HP_LEVEL_3); + ret = i3g4250d_hp_bandwidth_set(ctx, I3G4250D_HP_LEVEL_3); if (ret != 0) { LOG_ERR("Failed setting high pass"); return ret; } /* Set Output data rate */ - ret = i3g4250d_data_rate_set(i3g4250d->ctx, I3G4250D_ODR_100Hz); + ret = i3g4250d_data_rate_set(ctx, I3G4250D_ODR_100Hz); if (ret != 0) { LOG_ERR("Failed setting data rate"); return ret; @@ -208,20 +208,33 @@ static int i3g4250d_init(const struct device *dev) return 0; } -#define I3G4250D_DEVICE_INIT(inst) \ - static struct i3g4250d_data i3g4250d_data_##inst; \ - static const struct i3g4250d_device_config i3g4250d_config_##inst = { \ - .spi = SPI_DT_SPEC_INST_GET(inst, \ - SPI_OP_MODE_MASTER | SPI_MODE_CPOL | \ - SPI_MODE_CPHA | SPI_WORD_SET(8) | SPI_LINES_SINGLE) \ - }; \ - SENSOR_DEVICE_DT_INST_DEFINE(inst, \ - i3g4250d_init, \ - NULL, \ - &i3g4250d_data_##inst, \ - &i3g4250d_config_##inst, \ - POST_KERNEL, \ - CONFIG_SENSOR_INIT_PRIORITY, \ +#define I3G4250D_DEVICE_INIT(inst) \ + static struct i3g4250d_data i3g4250d_data_##inst; \ + SENSOR_DEVICE_DT_INST_DEFINE(inst, \ + i3g4250d_init, \ + NULL, \ + &i3g4250d_data_##inst, \ + &i3g4250d_device_config_##inst, \ + POST_KERNEL, \ + CONFIG_SENSOR_INIT_PRIORITY, \ &i3g4250d_driver_api); +#define I3G4250D_CONFIG_SPI(inst) \ + { \ + STMEMSC_CTX_SPI(&i3g4250d_device_config_##inst.stmemsc_cfg), \ + .stmemsc_cfg = { \ + .spi = SPI_DT_SPEC_INST_GET( \ + inst, \ + SPI_OP_MODE_MASTER | SPI_MODE_CPOL | \ + SPI_MODE_CPHA | SPI_WORD_SET(8) | \ + SPI_LINES_SINGLE), \ + }, \ + } + +#define I3G4250D_DEFINE_SPI(inst) \ + static const struct i3g4250d_device_config i3g4250d_device_config_##inst = \ + I3G4250D_CONFIG_SPI(inst); +#define I3G4250D_DEFINE(inst) \ + I3G4250D_DEFINE_SPI(inst); \ + I3G4250D_DEVICE_INIT(inst) -DT_INST_FOREACH_STATUS_OKAY(I3G4250D_DEVICE_INIT) +DT_INST_FOREACH_STATUS_OKAY(I3G4250D_DEFINE) diff --git a/drivers/sensor/st/i3g4250d/i3g4250d.h b/drivers/sensor/st/i3g4250d/i3g4250d.h index 143b021e0419..75599b64ab7a 100644 --- a/drivers/sensor/st/i3g4250d/i3g4250d.h +++ b/drivers/sensor/st/i3g4250d/i3g4250d.h @@ -12,6 +12,7 @@ #define ZEPHYR_DRIVERS_SENSOR_I3G4250D_I3G4250D_H_ #include +#include #include #include #include @@ -19,16 +20,28 @@ #include #include "i3g4250d_reg.h" +#define DT_DRV_COMPAT_I3G4250D st_i3g4250d + +#define I3G4250D_ANY_INST_ON_BUS_STATUS_OKAY(bus) \ +(DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(DT_DRV_COMPAT_I3G4250D, bus)) + + +#if I3G4250D_ANY_INST_ON_BUS_STATUS_OKAY(spi) +#include +#endif /* I3G4250D_ANY_INST_ON_BUS_STATUS_OKAY(spi) */ + struct i3g4250d_device_config { - struct spi_dt_spec spi; + stmdev_ctx_t ctx; + union { + #if I3G4250D_ANY_INST_ON_BUS_STATUS_OKAY(spi) + const struct spi_dt_spec spi; + #endif + } stmemsc_cfg; }; /* sensor data */ struct i3g4250d_data { int16_t angular_rate[3]; - stmdev_ctx_t *ctx; }; -int i3g4250d_spi_init(const struct device *dev); - #endif /* __SENSOR_I3G4250D__ */ diff --git a/drivers/sensor/st/i3g4250d/i3g4250d_spi.c b/drivers/sensor/st/i3g4250d/i3g4250d_spi.c deleted file mode 100644 index 2483b695f3ca..000000000000 --- a/drivers/sensor/st/i3g4250d/i3g4250d_spi.c +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (c) 2021 Jonathan Hahn - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#define DT_DRV_COMPAT st_i3g4250d - -#include -#include "i3g4250d.h" - -#if DT_ANY_INST_ON_BUS_STATUS_OKAY(spi) - -#define I3G4250D_SPI_READM (3 << 6) /* 0xC0 */ -#define I3G4250D_SPI_WRITEM (1 << 6) /* 0x40 */ - -LOG_MODULE_DECLARE(i3g4250d, CONFIG_SENSOR_LOG_LEVEL); - -static int i3g4250d_spi_read(const struct device *dev, uint8_t reg, - uint8_t *data, uint16_t len) -{ - int ret; - const struct i3g4250d_device_config *config = dev->config; - uint8_t buffer_tx[2] = { reg | I3G4250D_SPI_READM, 0 }; - const struct spi_buf tx_buf = { - .buf = buffer_tx, - .len = 2, - }; - const struct spi_buf_set tx = { - .buffers = &tx_buf, - .count = 1, - }; - const struct spi_buf rx_buf[2] = { - { - .buf = NULL, - .len = 1, - }, - { - .buf = data, - .len = len, - } - }; - const struct spi_buf_set rx = { - .buffers = rx_buf, - .count = 2, - }; - - ret = spi_transceive_dt(&config->spi, &tx, &rx); - if (ret < 0) { - return ret; - } - - return 0; -} - -static int i3g4250d_spi_write(const struct device *dev, uint8_t reg, - uint8_t *data, uint16_t len) -{ - int ret; - const struct i3g4250d_device_config *config = dev->config; - uint8_t buffer_tx[2] = { reg | I3G4250D_SPI_WRITEM, 0 }; - const struct spi_buf tx_buf[2] = { - { - .buf = buffer_tx, - .len = 1, - }, - { - .buf = data, - .len = len, - } - }; - const struct spi_buf_set tx = { - .buffers = tx_buf, - .count = 2, - }; - - ret = spi_write_dt(&config->spi, &tx); - if (ret < 0) { - return ret; - } - - return 0; -} - -stmdev_ctx_t i3g4250d_spi_ctx = { - .read_reg = (stmdev_read_ptr) i3g4250d_spi_read, - .write_reg = (stmdev_write_ptr) i3g4250d_spi_write, - .mdelay = (stmdev_mdelay_ptr) stmemsc_mdelay, -}; - -int i3g4250d_spi_init(const struct device *dev) -{ - struct i3g4250d_data *i3g4250d = dev->data; - const struct i3g4250d_device_config *cfg = dev->config; - - if (!spi_is_ready_dt(&cfg->spi)) { - LOG_ERR("spi not ready"); - return -ENODEV; - } - - i3g4250d->ctx = &i3g4250d_spi_ctx; - i3g4250d->ctx->handle = (void *)dev; - - return 0; -} - -#endif /* DT_ANY_INST_ON_BUS_STATUS_OKAY(spi) */ From 6524e670b347525a2bd0936967b52120696cdcfc Mon Sep 17 00:00:00 2001 From: James Roy Date: Fri, 12 Dec 2025 22:41:43 +0800 Subject: [PATCH 2336/3659] edtlib: Fix the accidental merging of examples in the binding Fix the example nodes in the examples block being accidentally merged and overwritten during build. Signed-off-by: James Roy --- scripts/dts/python-devicetree/src/devicetree/edtlib.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/dts/python-devicetree/src/devicetree/edtlib.py b/scripts/dts/python-devicetree/src/devicetree/edtlib.py index 8151388a6df2..5324a7553ecd 100644 --- a/scripts/dts/python-devicetree/src/devicetree/edtlib.py +++ b/scripts/dts/python-devicetree/src/devicetree/edtlib.py @@ -2753,7 +2753,7 @@ def _bad_overwrite(to_dict: dict, from_dict: dict, prop: str, return False # These are overridden deliberately - if prop in {"title", "description", "compatible"}: + if prop in {"title", "description", "compatible", "examples"}: return False if prop == "required": From 3989a59e9b0134ed8dd3a612fca317a36dd9db05 Mon Sep 17 00:00:00 2001 From: James Roy Date: Fri, 12 Dec 2025 21:23:45 +0800 Subject: [PATCH 2337/3659] dts: bindings: auxdisplay: Move the dts clips to the examples Move the dts sample nodes from the binding `description` into the `examples` block. Signed-off-by: James Roy --- dts/bindings/auxdisplay/gpio-7-segment.yaml | 48 ++++++++++---------- dts/bindings/auxdisplay/sparkfun,serlcd.yaml | 25 +++++----- 2 files changed, 37 insertions(+), 36 deletions(-) diff --git a/dts/bindings/auxdisplay/gpio-7-segment.yaml b/dts/bindings/auxdisplay/gpio-7-segment.yaml index fb7afddf0150..1299a66a9323 100644 --- a/dts/bindings/auxdisplay/gpio-7-segment.yaml +++ b/dts/bindings/auxdisplay/gpio-7-segment.yaml @@ -17,30 +17,6 @@ description: | high and active low respectively, meaning that the current flows from digit-gpios to segment-gpios. Vice versa for common cathode. - Example: - - #include - - / { - auxdisplay_0: digi-display { - compatible = "gpio-7-segment"; - columns = <3>; - rows = <1>; - segment-gpios = <&gpio0 0 GPIO_ACTIVE_LOW>, /* A */ - <&gpio0 1 GPIO_ACTIVE_LOW>, /* B */ - <&gpio0 2 GPIO_ACTIVE_LOW>, /* C */ - <&gpio0 3 GPIO_ACTIVE_LOW>, /* D */ - <&gpio0 4 GPIO_ACTIVE_LOW>, /* E */ - <&gpio0 5 GPIO_ACTIVE_LOW>, /* F */ - <&gpio0 6 GPIO_ACTIVE_LOW>, /* G */ - <&gpio0 7 GPIO_ACTIVE_LOW>; /* DP */ - digit-gpios = <&gpio1 0 GPIO_ACTIVE_HIGH>, /* DIG1 */ - <&gpio1 1 GPIO_ACTIVE_HIGH>, /* DIG2 */ - <&gpio1 2 GPIO_ACTIVE_HIGH>; /* DIG3 */ - refresh-period-ms = <1>; - }; - }; - compatible: "gpio-7-segment" include: auxdisplay-device.yaml @@ -86,3 +62,27 @@ properties: This is the time between the display of each digit. The refresh period must be long enough to allow the segments to be driven and the digit to be selected. + +examples: + - | + #include + + / { + auxdisplay_0: digi-display { + compatible = "gpio-7-segment"; + columns = <3>; + rows = <1>; + segment-gpios = <&gpio0 0 GPIO_ACTIVE_LOW>, /* A */ + <&gpio0 1 GPIO_ACTIVE_LOW>, /* B */ + <&gpio0 2 GPIO_ACTIVE_LOW>, /* C */ + <&gpio0 3 GPIO_ACTIVE_LOW>, /* D */ + <&gpio0 4 GPIO_ACTIVE_LOW>, /* E */ + <&gpio0 5 GPIO_ACTIVE_LOW>, /* F */ + <&gpio0 6 GPIO_ACTIVE_LOW>, /* G */ + <&gpio0 7 GPIO_ACTIVE_LOW>; /* DP */ + digit-gpios = <&gpio1 0 GPIO_ACTIVE_HIGH>, /* DIG1 */ + <&gpio1 1 GPIO_ACTIVE_HIGH>, /* DIG2 */ + <&gpio1 2 GPIO_ACTIVE_HIGH>; /* DIG3 */ + refresh-period-ms = <1>; + }; + }; diff --git a/dts/bindings/auxdisplay/sparkfun,serlcd.yaml b/dts/bindings/auxdisplay/sparkfun,serlcd.yaml index 2cbfd6a27688..d718d5706877 100644 --- a/dts/bindings/auxdisplay/sparkfun,serlcd.yaml +++ b/dts/bindings/auxdisplay/sparkfun,serlcd.yaml @@ -4,18 +4,6 @@ description: | SparkFun SerLCD Dot Character VFD Controller/Driver IC - Example: - &i2c1 { - serlcd@72 { - compatible = "sparkfun,serlcd"; - reg = <0x72>; - columns = <16>; - rows = <2>; - command-delay-ms = <10>; - special-command-delay-ms = <50>; - }; - }; - compatible: "sparkfun,serlcd" include: [auxdisplay-device.yaml, i2c-device.yaml] @@ -54,3 +42,16 @@ properties: implementation which assumes 100 kbps I2C configuration. This value might require tweaking if using I2C at a higher bitrate and/or relatively high update frequency of the display. + +examples: + - | + &i2c1 { + serlcd@72 { + compatible = "sparkfun,serlcd"; + reg = <0x72>; + columns = <16>; + rows = <2>; + command-delay-ms = <10>; + special-command-delay-ms = <50>; + }; + }; From a93c789c51eba8abd46a9abafe84e53c5e0f1969 Mon Sep 17 00:00:00 2001 From: James Roy Date: Fri, 12 Dec 2025 21:24:24 +0800 Subject: [PATCH 2338/3659] dts: bindings: charger: Move the dts clips to the examples Move the dts sample nodes from the binding `description` into the `examples` block. Signed-off-by: James Roy --- dts/bindings/charger/ti,bq24190.yaml | 22 ++++++------ dts/bindings/charger/ti,bq25180.yaml | 20 +++++------ dts/bindings/charger/ti,bq25186.yaml | 21 ++++++------ dts/bindings/charger/ti,bq25188.yaml | 18 +++++----- dts/bindings/charger/ti,bq25713.yaml | 24 ++++++------- .../charger/x-powers,axp2101-charger.yaml | 34 +++++++++---------- 6 files changed, 70 insertions(+), 69 deletions(-) diff --git a/dts/bindings/charger/ti,bq24190.yaml b/dts/bindings/charger/ti,bq24190.yaml index 78aa7654b57c..b2e3b0d1e508 100644 --- a/dts/bindings/charger/ti,bq24190.yaml +++ b/dts/bindings/charger/ti,bq24190.yaml @@ -8,17 +8,6 @@ description: | BQ2419x I2C controlled, 1-Cell, 4.5-A, USB/Adapter Charger with Narrow VDC Power Path Management and USB OTG - This charger is represented by device tree child node, e.g: - - charger: bq24190@6b { - compatible = "ti,bq24190"; - reg = <0x6b>; - status = "okay"; - - constant-charge-current-max-microamp = <1000000>; - constant-charge-voltage-max-microvolt = <3800000>; - }; - include: [battery.yaml, i2c-device.yaml] compatible: "ti,bq24190" @@ -41,3 +30,14 @@ properties: ce-gpios: type: phandle-array description: Active low, charge enable pin + +examples: + - | + charger: bq24190@6b { + compatible = "ti,bq24190"; + reg = <0x6b>; + status = "okay"; + + constant-charge-current-max-microamp = <1000000>; + constant-charge-voltage-max-microvolt = <3800000>; + }; diff --git a/dts/bindings/charger/ti,bq25180.yaml b/dts/bindings/charger/ti,bq25180.yaml index 200add399b63..022d314d88ba 100644 --- a/dts/bindings/charger/ti,bq25180.yaml +++ b/dts/bindings/charger/ti,bq25180.yaml @@ -3,17 +3,17 @@ description: | BQ25180 I2C Controlled, 1-Cell, 1-A Linear Battery Charger with Power Path - and Ship Mode. - - The device has a single node for the charger. For example: - - bq25180@6a { - compatible = "ti,bq25180"; - reg = <0x6a>; - - constant-charge-current-max-microamp = <500000>; - }; + and Ship Mode. The device has a single node for the charger. compatible: "ti,bq25180" include: ti,bq2518x-common.yaml + +examples: + - | + bq25180@6a { + compatible = "ti,bq25180"; + reg = <0x6a>; + + constant-charge-current-max-microamp = <500000>; + }; diff --git a/dts/bindings/charger/ti,bq25186.yaml b/dts/bindings/charger/ti,bq25186.yaml index 0dd8a54b0c07..5d7efc4d29ca 100644 --- a/dts/bindings/charger/ti,bq25186.yaml +++ b/dts/bindings/charger/ti,bq25186.yaml @@ -3,17 +3,18 @@ description: | BQ25186 I2C Controlled, 1-Cell, 1-A Linear Battery Charger with Power Path, - Ship Mode, Shutdown Mode and Battery Tracking VINDPM. - - The device has a single node for the charger. For example: - - bq25186@6a { - compatible = "ti,bq25186"; - reg = <0x6a>; - - constant-charge-current-max-microamp = <500000>; - }; + Ship Mode, Shutdown Mode and Battery Tracking VINDPM. The device has a single + node for the charger. compatible: "ti,bq25186" include: ti,bq2518x-common.yaml + +examples: + - | + bq25186@6a { + compatible = "ti,bq25186"; + reg = <0x6a>; + + constant-charge-current-max-microamp = <500000>; + }; diff --git a/dts/bindings/charger/ti,bq25188.yaml b/dts/bindings/charger/ti,bq25188.yaml index c3838a46b76a..8a061083f8ba 100644 --- a/dts/bindings/charger/ti,bq25188.yaml +++ b/dts/bindings/charger/ti,bq25188.yaml @@ -5,15 +5,15 @@ description: | BQ25188 I2C Controlled, 1-Cell, 1-A Linear Battery Charger with Power Path, Ship Mode, Shutdown Mode, Battery Tracking VINDPM, and Wide WIN Support. - The device has a single node for the charger. For example: - - bq25188@6a { - compatible = "ti,bq25188"; - reg = <0x6a>; - - constant-charge-current-max-microamp = <500000>; - }; - compatible: "ti,bq25188" include: ti,bq2518x-common.yaml + +examples: + - | + bq25188@6a { + compatible = "ti,bq25188"; + reg = <0x6a>; + + constant-charge-current-max-microamp = <500000>; + }; diff --git a/dts/bindings/charger/ti,bq25713.yaml b/dts/bindings/charger/ti,bq25713.yaml index 1eda1664f351..b32a94c5f63a 100644 --- a/dts/bindings/charger/ti,bq25713.yaml +++ b/dts/bindings/charger/ti,bq25713.yaml @@ -7,18 +7,6 @@ description: | BQ25713 targets 1s to 4s Cell, USB Power Delivery/Adapter Charger with Narrow VDC Power Path Management and Processor Hot Monitor - This charger is represented by device tree child node, e.g: - - charger: bq25713@6b { - compatible = "ti,bq25713"; - reg = <0x6b>; - status = "okay"; - - constant-charge-current-max-microamp = <1000000>; - constant-charge-voltage-max-microvolt = <3800000>; - system-voltage-min-threshold-microvolt = <3328000>; - }; - include: [battery.yaml, i2c-device.yaml] compatible: "ti,bq25713" @@ -46,3 +34,15 @@ properties: Voltage that will be set above when the system voltage drops this level. This value will be set at initialization time. Range: 1.024 V to 16.128 V. The value specified will be rounded down to the closest implemented value. + +examples: + - | + charger: bq25713@6b { + compatible = "ti,bq25713"; + reg = <0x6b>; + status = "okay"; + + constant-charge-current-max-microamp = <1000000>; + constant-charge-voltage-max-microvolt = <3800000>; + system-voltage-min-threshold-microvolt = <3328000>; + }; diff --git a/dts/bindings/charger/x-powers,axp2101-charger.yaml b/dts/bindings/charger/x-powers,axp2101-charger.yaml index d1970411f87e..ceaff03adfcb 100644 --- a/dts/bindings/charger/x-powers,axp2101-charger.yaml +++ b/dts/bindings/charger/x-powers,axp2101-charger.yaml @@ -4,23 +4,6 @@ description: | Charger part of the AXP2101 PMU MFD device. - This charger should be instantiated as child of the AXP2101 MFD device, i.e. - - axp2101@34 { - compatible = "x-powers,axp2101"; - reg = <0x34>; - - charger { - compatible = "x-powers,axp2101-charger"; - constant-charge-current-max-microamp = <300000>; - constant-charge-voltage-max-microvolt = <4200000>; - }; - - regulators { - ... - } - } - compatible: "x-powers,axp2101-charger" on-bus: axp2101 @@ -75,3 +58,20 @@ properties: description: Enable Vbackup on boot. This is normally used to charge a button battery that is used by some RTC IC. + +examples: + - | + axp2101@34 { + compatible = "x-powers,axp2101"; + reg = <0x34>; + + charger { + compatible = "x-powers,axp2101-charger"; + constant-charge-current-max-microamp = <300000>; + constant-charge-voltage-max-microvolt = <4200000>; + }; + + regulators { + ... + } + } From 08ba0d242c58d488667ef68e017d62117e023d45 Mon Sep 17 00:00:00 2001 From: James Roy Date: Tue, 16 Dec 2025 11:14:48 +0800 Subject: [PATCH 2339/3659] dts: bindings: cache: Move the dts clips to the examples Move the dts sample nodes from the binding `description` into the `examples` block. Signed-off-by: James Roy --- dts/bindings/cache/bflb,l1c.yaml | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/dts/bindings/cache/bflb,l1c.yaml b/dts/bindings/cache/bflb,l1c.yaml index 43378277a6fe..b4ba025d3516 100644 --- a/dts/bindings/cache/bflb,l1c.yaml +++ b/dts/bindings/cache/bflb,l1c.yaml @@ -7,22 +7,8 @@ description: | Bouffalo Lab L1C cache control. - The node should be added in the soc group and be provided disabled ways - - soc { - - ... - - cache { - compatible = "bflb,l1c"; - dcache-ways-disabled = <0>; - }; - - ... - - }; - - The cache configuration is specific to the platform, this only provides controls for it. + The node should be added in the soc group and be provided disabled ways, the + cache configuration is specific to the platform. compatible: "bflb,l1c" @@ -39,3 +25,12 @@ properties: - 2 - 3 - 4 + +examples: + - | + soc { + cache { + compatible = "bflb,l1c"; + dcache-ways-disabled = <0>; + }; + }; From 55870811db826f876b53c4785f4b75c43e053934 Mon Sep 17 00:00:00 2001 From: James Roy Date: Tue, 16 Dec 2025 11:15:14 +0800 Subject: [PATCH 2340/3659] dts: bindings: timer: Move the dts clips to the examples Move the dts sample nodes from the binding `description` into the `examples` block. Signed-off-by: James Roy --- dts/bindings/timer/nordic,nrf-grtc.yaml | 23 ++++++++++++----------- dts/bindings/timer/st,stm32-lptim.yaml | 15 +++++++++------ 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/dts/bindings/timer/nordic,nrf-grtc.yaml b/dts/bindings/timer/nordic,nrf-grtc.yaml index 5b57c8dbeae5..c4e90358a48c 100644 --- a/dts/bindings/timer/nordic,nrf-grtc.yaml +++ b/dts/bindings/timer/nordic,nrf-grtc.yaml @@ -7,17 +7,6 @@ description: | Nordic GRTC (Global RTC) - Example of using clock outputs: - &grtc { - pinctrl-0 = <&grtc_default>; - pinctrl-1 = <&grtc_sleep>; - pinctrl-names = "default", "sleep"; - clkout-fast-frequency-hz = <8000000>; - clkout-32k; - /* In case of nRF54H20 devices: */ - nordic,clockpin-enable = ; - }; - compatible: "nordic,nrf-grtc" include: @@ -52,3 +41,15 @@ properties: description: | Clock frequency information for tick increment operations, this default value comes from the nRF54L15 datasheet. + +examples: + - | + &grtc { + pinctrl-0 = <&grtc_default>; + pinctrl-1 = <&grtc_sleep>; + pinctrl-names = "default", "sleep"; + clkout-fast-frequency-hz = <8000000>; + clkout-32k; + /* In case of nRF54H20 devices: */ + nordic,clockpin-enable = ; + }; diff --git a/dts/bindings/timer/st,stm32-lptim.yaml b/dts/bindings/timer/st,stm32-lptim.yaml index 43b9e311f663..e29b47d81df4 100644 --- a/dts/bindings/timer/st,stm32-lptim.yaml +++ b/dts/bindings/timer/st,stm32-lptim.yaml @@ -4,12 +4,6 @@ description: | STM32 low-power timer (LPTIM). - The lptim node to be used for counting ticks during lowpower modes - must be named stm32_lp_tick_source in the DTS, as follows: - stm32_lp_tick_source: &lptim1 { - status = "okay"; - } - compatible: "st,stm32-lptim" include: @@ -51,3 +45,12 @@ properties: Gives the LPTIM an exact counting value (s) for timeout expiration. Valid range is [1, 256] and should be consistent with st,prescaler pre-defined setting. If not, an error is raised. + +examples: + - | + stm32_lp_tick_source: &lptim1 { + status = "okay"; + } + + The lptim node to be used for counting ticks during lowpower modes + must be named stm32_lp_tick_source in the DTS. From ae556f89143e683f5f6cab2f2c60a88ca48ca1d5 Mon Sep 17 00:00:00 2001 From: James Roy Date: Tue, 20 Jan 2026 23:06:50 +0800 Subject: [PATCH 2341/3659] dts: bindings: can: Move the dts clips to the examples Move the dts sample nodes from the binding `description` into the `examples` block. Signed-off-by: James Roy --- dts/bindings/can/microchip,mcp251xfd.yaml | 35 ++++++++++--------- dts/bindings/can/nxp,flexcan-fd.yaml | 25 +++++++------- dts/bindings/can/nxp,flexcan.yaml | 37 ++++++++++---------- dts/bindings/can/ti,tcan4x5x.yaml | 41 ++++++++++++----------- 4 files changed, 70 insertions(+), 68 deletions(-) diff --git a/dts/bindings/can/microchip,mcp251xfd.yaml b/dts/bindings/can/microchip,mcp251xfd.yaml index ed63da20b4fd..7ffd271f4098 100644 --- a/dts/bindings/can/microchip,mcp251xfd.yaml +++ b/dts/bindings/can/microchip,mcp251xfd.yaml @@ -4,24 +4,6 @@ description: | Microchip MCP251XFD SPI CAN FD controller - The MCP251XFD node is defined on an SPI bus. An example - configuration is: - - &mikrobus_spi { - cs-gpios = <&mikrobus_header 2 GPIO_ACTIVE_LOW>; - - mcp2518fd_mikroe_mcp2518fd_click: mcp2518fd@0 { - compatible = "microchip,mcp251xfd"; - status = "okay"; - - spi-max-frequency = <18000000>; - int-gpios = <&mikrobus_header 7 GPIO_ACTIVE_LOW>; - reg = <0x0>; - osc-freq = <40000000>; - - }; - }; - compatible: "microchip,mcp251xfd" include: [spi-device.yaml, can-fd-controller.yaml] @@ -78,3 +60,20 @@ properties: - 2 - 4 - 10 + +examples: + - | + &mikrobus_spi { + cs-gpios = <&mikrobus_header 2 GPIO_ACTIVE_LOW>; + + mcp2518fd_mikroe_mcp2518fd_click: mcp2518fd@0 { + compatible = "microchip,mcp251xfd"; + status = "okay"; + + spi-max-frequency = <18000000>; + int-gpios = <&mikrobus_header 7 GPIO_ACTIVE_LOW>; + reg = <0x0>; + osc-freq = <40000000>; + + }; + }; diff --git a/dts/bindings/can/nxp,flexcan-fd.yaml b/dts/bindings/can/nxp,flexcan-fd.yaml index 4614cdd9a12b..bc5328b29500 100644 --- a/dts/bindings/can/nxp,flexcan-fd.yaml +++ b/dts/bindings/can/nxp,flexcan-fd.yaml @@ -6,7 +6,19 @@ description: | This is a specialization of the NXP FlexCAN CAN controller with support for CAN FD. - Example: +compatible: "nxp,flexcan-fd" + +include: ["nxp,flexcan.yaml", "can-fd-controller.yaml", "pinctrl-device.yaml", + "nxp,rdc-policy.yaml"] + +properties: + number-of-mb-fd: + type: int + required: true + description: Number of 64-byte payload message buffers FlexCAN FD instance supported + +examples: + - | flexcan3: can@401d8000 { status = "okay"; compatible = "nxp,flexcan-fd", "nxp,flexcan"; @@ -24,14 +36,3 @@ description: | max-bitrate = <5000000>; }; }; - -compatible: "nxp,flexcan-fd" - -include: ["nxp,flexcan.yaml", "can-fd-controller.yaml", "pinctrl-device.yaml", - "nxp,rdc-policy.yaml"] - -properties: - number-of-mb-fd: - type: int - required: true - description: Number of 64-byte payload message buffers FlexCAN FD instance supported diff --git a/dts/bindings/can/nxp,flexcan.yaml b/dts/bindings/can/nxp,flexcan.yaml index 2f6581effd24..731e21aea197 100644 --- a/dts/bindings/can/nxp,flexcan.yaml +++ b/dts/bindings/can/nxp,flexcan.yaml @@ -4,24 +4,6 @@ description: | NXP FlexCAN controller - Example: - flexcan0: can@40024000 { - status = "okay"; - compatible = "nxp,flexcan"; - reg = <0x40024000 0x1000>; - interrupts = <78 0>, <79 0>, <80 0>, <81 0>; - interrupt-names = "warning", "error", "wake-up", "mb-0-15"; - clocks = <&scg KINETIS_SCG_BUS_CLK>; - clk-source = <1>; - number-of-mb = <16>; - pinctrl-0 = <&pinmux_flexcan0>; - pinctrl-names = "default"; - - can-transceiver { - max-bitrate = <1000000>; - }; - }; - compatible: "nxp,flexcan" include: ["can-controller.yaml", "pinctrl-device.yaml"] @@ -60,3 +42,22 @@ properties: type: int required: true description: Number of 8-byte payload message buffers FlexCAN instance supported + +examples: + - | + flexcan0: can@40024000 { + status = "okay"; + compatible = "nxp,flexcan"; + reg = <0x40024000 0x1000>; + interrupts = <78 0>, <79 0>, <80 0>, <81 0>; + interrupt-names = "warning", "error", "wake-up", "mb-0-15"; + clocks = <&scg KINETIS_SCG_BUS_CLK>; + clk-source = <1>; + number-of-mb = <16>; + pinctrl-0 = <&pinmux_flexcan0>; + pinctrl-names = "default"; + + can-transceiver { + max-bitrate = <1000000>; + }; + }; diff --git a/dts/bindings/can/ti,tcan4x5x.yaml b/dts/bindings/can/ti,tcan4x5x.yaml index 75b115d697ce..3a8de6e08993 100644 --- a/dts/bindings/can/ti,tcan4x5x.yaml +++ b/dts/bindings/can/ti,tcan4x5x.yaml @@ -4,26 +4,6 @@ description: | Texas Instruments TCAN4x5x SPI CAN FD controller. - Example: - &spi0 { - tcan4x5x: can@0 { - compatible = ti,tcan4x5x"; - reg = <0>; - spi-max-frequency = <18000000>; - clock-frequency = <40000000>; - device-state-gpios = <&gpio0 0 GPIO_ACTIVE_LOW>; - device-wake-gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>; - reset-gpios = <&gpio0 2 GPIO_ACTIVE_HIGH>; - int-gpios = <&gpio0 3 GPIO_ACTIVE_LOW>; - bosch,mram-cfg = <0x0 15 15 5 5 0 10 10>; - status = "okay"; - - can-transceiver { - max-bitrate = <8000000>; - }; - }; - }; - compatible: "ti,tcan4x5x" include: ["bosch,m_can-base.yaml", "spi-device.yaml"] @@ -58,3 +38,24 @@ properties: required: true description: | GPIO connected to the TCAN4x5x nINT interrupt output. This signal is open-drain, active low. + +examples: + - | + &spi0 { + tcan4x5x: can@0 { + compatible = ti,tcan4x5x"; + reg = <0>; + spi-max-frequency = <18000000>; + clock-frequency = <40000000>; + device-state-gpios = <&gpio0 0 GPIO_ACTIVE_LOW>; + device-wake-gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>; + reset-gpios = <&gpio0 2 GPIO_ACTIVE_HIGH>; + int-gpios = <&gpio0 3 GPIO_ACTIVE_LOW>; + bosch,mram-cfg = <0x0 15 15 5 5 0 10 10>; + status = "okay"; + + can-transceiver { + max-bitrate = <8000000>; + }; + }; + }; From d4bf9ea2e805a8cf36639e207e3eb1c6dc879b13 Mon Sep 17 00:00:00 2001 From: Pieter De Gendt Date: Thu, 8 Jan 2026 15:03:32 +0100 Subject: [PATCH 2342/3659] tests: lib: cobs: Remove malloc/free Use static fixture struct so no malloc/free is needed. Signed-off-by: Pieter De Gendt --- tests/lib/cobs/prj.conf | 2 -- tests/lib/cobs/src/main.c | 41 ++++++++++++++------------------------- 2 files changed, 15 insertions(+), 28 deletions(-) diff --git a/tests/lib/cobs/prj.conf b/tests/lib/cobs/prj.conf index a0821ce3f291..3f2a19bc89b7 100644 --- a/tests/lib/cobs/prj.conf +++ b/tests/lib/cobs/prj.conf @@ -1,4 +1,2 @@ CONFIG_COBS=y CONFIG_ZTEST=y -# cobs test needs some heap, but MINIMAL_LIBC has none by default. -CONFIG_COMMON_LIBC_MALLOC_ARENA_SIZE=256 diff --git a/tests/lib/cobs/src/main.c b/tests/lib/cobs/src/main.c index e9bcc1c9331c..c58bace63dee 100644 --- a/tests/lib/cobs/src/main.c +++ b/tests/lib/cobs/src/main.c @@ -1,9 +1,8 @@ /* * Copyright (c) 2024 Kelly Helmut Lord + * Copyright (c) 2026 Basalte bv * SPDX-License-Identifier: Apache-2.0 */ -#include "zephyr/ztest_assert.h" -#include #include #include @@ -20,23 +19,21 @@ struct cobs_tests_fixture { static void *cobs_test_setup(void) { - struct cobs_tests_fixture *fixture = malloc(sizeof(struct cobs_tests_fixture)); + static struct cobs_tests_fixture fixture; - zassume_not_null(fixture); + fixture.test_data = net_buf_alloc(&test_pool, K_NO_WAIT); + fixture.encoded = net_buf_alloc(&test_pool, K_NO_WAIT); + fixture.decoded = net_buf_alloc(&test_pool, K_NO_WAIT); - fixture->test_data = net_buf_alloc(&test_pool, K_NO_WAIT); - fixture->encoded = net_buf_alloc(&test_pool, K_NO_WAIT); - fixture->decoded = net_buf_alloc(&test_pool, K_NO_WAIT); + zassert_not_null(fixture.test_data, "Failed to allocate test_data buffer"); + zassert_not_null(fixture.encoded, "Failed to allocate encoded buffer"); + zassert_not_null(fixture.decoded, "Failed to allocate decoded buffer"); - zassert_not_null(fixture->test_data, "Failed to allocate test_data buffer"); - zassert_not_null(fixture->encoded, "Failed to allocate encoded buffer"); - zassert_not_null(fixture->decoded, "Failed to allocate decoded buffer"); + net_buf_reset(fixture.test_data); + net_buf_reset(fixture.encoded); + net_buf_reset(fixture.decoded); - net_buf_reset(fixture->test_data); - net_buf_reset(fixture->encoded); - net_buf_reset(fixture->decoded); - - return fixture; + return &fixture; } static void cobs_test_before(void *f) @@ -52,17 +49,9 @@ static void cobs_test_teardown(void *f) { struct cobs_tests_fixture *fixture = (struct cobs_tests_fixture *)f; - if (fixture->test_data) { - net_buf_unref(fixture->test_data); - } - if (fixture->encoded) { - net_buf_unref(fixture->encoded); - } - if (fixture->decoded) { - net_buf_unref(fixture->decoded); - } - - free(fixture); + net_buf_unref(fixture->test_data); + net_buf_unref(fixture->encoded); + net_buf_unref(fixture->decoded); } struct cobs_test_item { From f344ab6b98cc58b3e1c5addc18e92c3930bf09df Mon Sep 17 00:00:00 2001 From: Pieter De Gendt Date: Wed, 7 Jan 2026 16:48:11 +0100 Subject: [PATCH 2343/3659] cobs: Introduce streaming This commit does: - Introduce COBS streaming - Refactor custom delimiter with XOR'ed encoded data - Update tests Signed-off-by: Pieter De Gendt --- include/zephyr/data/cobs.h | 216 ++++++++++++++++++++++++++++-- lib/utils/cobs.c | 268 ++++++++++++++++++++++++++++--------- tests/lib/cobs/src/main.c | 62 +++++---- 3 files changed, 447 insertions(+), 99 deletions(-) diff --git a/include/zephyr/data/cobs.h b/include/zephyr/data/cobs.h index e22f1d2aaaf4..da9f2e0339ab 100644 --- a/include/zephyr/data/cobs.h +++ b/include/zephyr/data/cobs.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2024 Kelly Helmut Lord + * Copyright (c) 2026 Basalte bv * * SPDX-License-Identifier: Apache-2.0 */ @@ -16,20 +17,53 @@ extern "C" { #endif + +/** + * @name COBS Encoder/Decoder Flags + * @anchor COBS_FLAGS + * + * @{ + */ + +/** + * @brief Default COBS delimiter value + * + * The standard COBS delimiter is zero (0x00). This is the delimiter value + * used when COBS_FLAG_CUSTOM_DELIMITER is not specified. + */ #define COBS_DEFAULT_DELIMITER 0x00 /** - * Flag indicating that encode and decode should include an implicit end delimiter + * @brief Flag indicating that encode or decode should include a trailing delimiter + * + * When set, the encoder will append a delimiter byte after the encoded data, + * and the decoder will accept a delimiter byte at the end of the encoded data. */ #define COBS_FLAG_TRAILING_DELIMITER BIT(8) /** - * Macro for extracting delimiter from flags. 8 LSB of "flags" is used for the delimiter + * @brief Macro for setting a custom delimiter in flags + * + * The 8 LSB of "flags" is used for the delimiter value. When a custom delimiter is + * configured, the implementation applies an XOR operation with the delimiter value + * on the encoded data after encoding and before decoding. This allows COBS to work + * with delimiters other than zero. + * + * @param x Custom delimiter value (0-255) + * + * @return Delimiter value masked to 8 bits + * * Example usage: + * @code{.c} * cobs_encode(src_buf, dst_buf, COBS_FLAG_TRAILING_DELIMITER | COBS_FLAG_CUSTOM_DELIMITER(0x7F)); + * @endcode */ #define COBS_FLAG_CUSTOM_DELIMITER(x) ((x) & 0xff) +/** + * @} + */ + /** * @defgroup cobs COBS (Consistent Overhead Byte Stuffing) * @ingroup utilities @@ -46,7 +80,7 @@ extern "C" { * @brief Calculate maximum encoded buffer size * * @param decoded_size Size of input data to be encoded - * @param flags COBS_FLAG_TRAILING_DELIMITER to include termination byte in calculation + * @param flags Encoding flags @ref COBS_FLAGS * * @return Required buffer size for worst-case encoding scenario */ @@ -60,11 +94,13 @@ static inline size_t cobs_max_encoded_len(size_t decoded_size, uint32_t flags) } /** - * @brief Standard COBS encoding + * @brief COBS encoding * - * @param src Source buffer to decode - * @param dst Destination buffer for decoded data - * @param flags Decoding flags (reserved) + * Encodes data from source buffer to destination buffer using COBS encoding. + * + * @param src Source buffer to encode + * @param dst Destination buffer for encoded data + * @param flags Encoding flags @ref COBS_FLAGS * * @retval 0 Success * @retval -ENOMEM Insufficient destination space @@ -74,11 +110,13 @@ static inline size_t cobs_max_encoded_len(size_t decoded_size, uint32_t flags) int cobs_encode(struct net_buf *src, struct net_buf *dst, uint32_t flags); /** - * @brief Standard COBS decoding + * @brief COBS decoding + * + * Decodes COBS-encoded data from source buffer to destination buffer. * * @param src Source buffer to decode * @param dst Destination buffer for decoded data - * @param flags Decoding flags (reserved) + * @param flags Decoding flags @ref COBS_FLAGS * * @retval 0 Success * @retval -ENOMEM Insufficient destination space @@ -86,6 +124,166 @@ int cobs_encode(struct net_buf *src, struct net_buf *dst, uint32_t flags); */ int cobs_decode(struct net_buf *src, struct net_buf *dst, uint32_t flags); +/** + * @brief Callback function type for streaming COBS encoder/decoder + * + * This callback is invoked by the streaming encoder/decoder to output + * processed data chunks. + * A decoder that allows trailing delimiters and encounters one will invoke + * this callback with a NULL pointer and zero length indicating a completed frame. + * + * When this callback function returns a negative error value, the encoder or decoder + * stream is aborted and the error will be propagated. + * + * @param buf Buffer containing processed data + * @param len Length of data in buffer + * @param user_data User-provided context pointer + * + * @return 0 on success, negative errno code on failure + */ +typedef int (*cobs_stream_cb)(const uint8_t *buf, size_t len, void *user_data); + +/** + * @brief COBS streaming encoder state + * + * This structure maintains the state for incremental COBS encoding. + * It should be initialized with cobs_encoder_init() before use. + */ +struct cobs_encoder { + /** @cond INTERNAL_HIDDEN */ + /** Callback function to output encoded data */ + cobs_stream_cb cb; + /** User data pointer passed to callback */ + void *cb_user_data; + + /** Internal buffer for partial encoding */ + uint8_t fragment[255]; + /** Encoding flags @ref COBS_FLAGS */ + uint32_t flags; + /** @endcond */ +}; + +/** + * @brief COBS streaming decoder state + * + * This structure maintains the state for incremental COBS decoding. + * It should be initialized with cobs_decoder_init() before use. + */ +struct cobs_decoder { + /** @cond INTERNAL_HIDDEN */ + /** Callback function to output decoded data */ + cobs_stream_cb cb; + /** User data pointer passed to callback */ + void *cb_user_data; + + /** Current COBS code byte being processed */ + uint8_t code; + /** Position within current code block */ + uint8_t code_index; + /** Decoding flags @ref COBS_FLAGS */ + uint32_t flags; + /** @endcond */ +}; + +/** + * @brief Initialize COBS streaming encoder + * + * Initializes a COBS encoder for streaming operation. The encoder will call + * the provided callback function to output encoded data chunks as they become + * available. + * + * @param enc Pointer to encoder structure to initialize + * @param cb Callback function for output data + * @param user_data User data pointer passed to callback + * @param flags Encoding flags @ref COBS_FLAGS + * + * @return 0 on success, negative errno code on failure + */ +int cobs_encoder_init(struct cobs_encoder *enc, cobs_stream_cb cb, void *user_data, uint32_t flags); + +/** + * @brief Finalize COBS streaming encoder + * + * Flushes any remaining data and optionally writes trailing delimiter if + * COBS_FLAG_TRAILING_DELIMITER was set during initialization. + * + * The encoder state will be reset. + * + * @param enc Pointer to encoder structure + * + * @return 0 on success, negative errno code on failure + */ +int cobs_encoder_close(struct cobs_encoder *enc); + +/** + * @brief Write data to COBS streaming encoder + * + * Encodes the provided data and outputs encoded chunks via the registered + * callback function. This function can be called multiple times to encode + * data incrementally. + * + * In case an error is returned, the encoder state will be reset. + * + * @param enc Pointer to encoder structure + * @param buf Buffer containing data to encode + * @param len Length of data in buffer + * + * @return Number of bytes used from @p buf on success, negative errno code on failure + */ +int cobs_encoder_write(struct cobs_encoder *enc, const uint8_t *buf, size_t len); + +/** + * @brief Initialize COBS streaming decoder + * + * Initializes a COBS decoder for streaming operation. The decoder will call + * the provided callback function to output decoded data chunks as they become + * available. + * + * @param dec Pointer to decoder structure to initialize + * @param cb Callback function for output data + * @param user_data User data pointer passed to callback + * @param flags Decoding flags @ref COBS_FLAGS + * + * @return 0 on success, negative errno code on failure + */ +int cobs_decoder_init(struct cobs_decoder *dec, cobs_stream_cb cb, void *user_data, uint32_t flags); + +/** + * @brief Finalize COBS streaming decoder + * + * Completes the decoding process and verifies that the stream ended properly. + * Should be called after all data has been written to the decoder. + * + * The decoder state will be reset. + * + * @param dec Pointer to decoder structure + * + * @retval 0 Success + * @retval -EINVAL More data was expected before closing + */ +int cobs_decoder_close(struct cobs_decoder *dec); + +/** + * @brief Write data to COBS streaming decoder + * + * Decodes the provided encoded data and outputs decoded chunks via the + * registered callback function. This function can be called multiple times + * to decode data incrementally. + * + * In case an error is returned, the decoder state will be reset. + * + * @note If a delimiter is encountered, and the @ref COBS_FLAG_TRAILING_DELIMITER flag + * is set, the registered callback function will be called with a NULL pointer + * indicating a frame end. + * + * @param dec Pointer to decoder structure + * @param buf Buffer containing encoded data + * @param len Length of data in buffer + * + * @return Number of bytes used from @p buf on success, negative errno code on failure + */ +int cobs_decoder_write(struct cobs_decoder *dec, const uint8_t *buf, size_t len); + /** @} */ #ifdef __cplusplus diff --git a/lib/utils/cobs.c b/lib/utils/cobs.c index d500eb2b86f5..e364d1729bb8 100644 --- a/lib/utils/cobs.c +++ b/lib/utils/cobs.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2024 Kelly Helmut Lord + * Copyright (c) 2026 Basalte bv * * SPDX-License-Identifier: Apache-2.0 */ @@ -8,97 +9,242 @@ #include #include +static int cobs_net_buf_cb(const uint8_t *buf, size_t len, void *user_data) +{ + struct net_buf *dst = user_data; + + if (net_buf_tailroom(dst) < len) { + return -ENOMEM; + } + + (void)net_buf_add_mem(dst, buf, len); + + return 0; +} + int cobs_encode(struct net_buf *src, struct net_buf *dst, uint32_t flags) { - uint8_t delimiter = COBS_FLAG_CUSTOM_DELIMITER(flags); + struct cobs_encoder enc; + size_t len = src->len; + int ret; - /* Calculate required space for worst case */ - size_t max_encoded_size = cobs_max_encoded_len(src->len, flags); + (void)cobs_encoder_init(&enc, cobs_net_buf_cb, dst, flags); - /* Check if destination has enough space */ - if (net_buf_tailroom(dst) < max_encoded_size) { - return -ENOMEM; + ret = cobs_encoder_write(&enc, net_buf_pull_mem(src, len), len); + if (ret < 0) { + return ret; } - uint8_t *code_ptr = net_buf_add(dst, 1); - uint8_t code = 1; - - /* Process all input bytes */ - uint8_t data = 0; - - while (src->len > 0) { - data = net_buf_pull_u8(src); - if (data == delimiter) { - /* Delimiter found - write current code and start new block */ - *code_ptr = code; - code_ptr = net_buf_add(dst, 1); - code = 1; - } else { - /* Add non-zero byte to output */ - net_buf_add_u8(dst, data); - code++; - - /* If we've reached maximum block size, start a new block */ - if (code == 0xFF && (src->len - 1 >= 0)) { - *code_ptr = code; - code_ptr = net_buf_add(dst, 1); - code = 1; - } + return cobs_encoder_close(&enc); +} + +int cobs_decode(struct net_buf *src, struct net_buf *dst, uint32_t flags) +{ + struct cobs_decoder dec; + size_t len = src->len; + int ret; + + (void)cobs_decoder_init(&dec, cobs_net_buf_cb, dst, flags); + + ret = cobs_decoder_write(&dec, net_buf_pull_mem(src, len), len); + if (ret < 0) { + return ret; + } + + return cobs_decoder_close(&dec); +} + +static inline void cobs_encoder_reset(struct cobs_encoder *enc) +{ + /* Reset buffer */ + enc->fragment[0] = 1; +} + +static int cobs_encoder_finish(struct cobs_encoder *enc, bool close) +{ + uint8_t sentinel = COBS_FLAG_CUSTOM_DELIMITER(enc->flags); + size_t len = enc->fragment[0]; + int ret; + + if (sentinel != 0x00) { + for (size_t i = 0; i < len; ++i) { + enc->fragment[i] ^= sentinel; } } - *code_ptr = code; + ret = enc->cb(enc->fragment, len, enc->cb_user_data); + if (ret < 0) { + cobs_encoder_reset(enc); + return ret; + } - if (flags & COBS_FLAG_TRAILING_DELIMITER) { - /* Add final delimiter */ - net_buf_add_u8(dst, delimiter); + if (close && (enc->flags & COBS_FLAG_TRAILING_DELIMITER) != 0U) { + ret = enc->cb(&sentinel, 1, enc->cb_user_data); + if (ret < 0) { + cobs_encoder_reset(enc); + return ret; + } } + cobs_encoder_reset(enc); + return 0; } -int cobs_decode(struct net_buf *src, struct net_buf *dst, uint32_t flags) +int cobs_encoder_init(struct cobs_encoder *enc, cobs_stream_cb cb, void *user_data, uint32_t flags) { - uint8_t delimiter = COBS_FLAG_CUSTOM_DELIMITER(flags); + if (cb == NULL) { + return -EINVAL; + } - if (flags & COBS_FLAG_TRAILING_DELIMITER) { - uint8_t end_delim = net_buf_remove_u8(src); + __ASSERT_NO_MSG(enc != NULL); - if (end_delim != delimiter) { - return -EINVAL; - } - } + enc->cb = cb; + enc->cb_user_data = user_data; + enc->flags = flags; + + cobs_encoder_reset(enc); + + return 0; +} + +int cobs_encoder_close(struct cobs_encoder *enc) +{ + __ASSERT_NO_MSG(enc != NULL); + + return cobs_encoder_finish(enc, true); +} + +int cobs_encoder_write(struct cobs_encoder *enc, const uint8_t *buf, size_t len) +{ + int ret; - while (src->len > 0) { - /* Pull the COBS offset byte */ - uint8_t offset = net_buf_pull_u8(src); + __ASSERT_NO_MSG(enc != NULL); + __ASSERT_NO_MSG(len <= INT_MAX); - if (offset == delimiter && !(flags & COBS_FLAG_TRAILING_DELIMITER)) { - return -EINVAL; + for (size_t i = 0; i < len; ++i) { + /* Finish if group is full */ + if (enc->fragment[0] == 0xff) { + ret = cobs_encoder_finish(enc, false); + if (ret < 0) { + return ret; + } } - /* Verify we have enough data */ - if (src->len < (offset - 1)) { - return -EINVAL; + if (buf[i] == 0x00) { + ret = cobs_encoder_finish(enc, false); + if (ret < 0) { + return ret; + } + + continue; } - /* Copy offset-1 bytes */ - for (uint8_t i = 0; i < offset - 1; i++) { - uint8_t byte = net_buf_pull_u8(src); + enc->fragment[enc->fragment[0]] = buf[i]; + enc->fragment[0]++; + } + + return len; +} + +static inline void cobs_decoder_reset(struct cobs_decoder *dec) +{ + dec->code = 0xff; + dec->code_index = 0; +} + +static inline bool cobs_decoder_needs_more_data(struct cobs_decoder *dec) +{ + return dec->code_index != 0; +} + +int cobs_decoder_init(struct cobs_decoder *dec, cobs_stream_cb cb, void *user_data, uint32_t flags) +{ + if (cb == NULL) { + return -EINVAL; + } + + __ASSERT_NO_MSG(dec != NULL); + + dec->cb = cb; + dec->cb_user_data = user_data; + dec->flags = flags; - if (byte == delimiter) { + cobs_decoder_reset(dec); + + return 0; +} + +int cobs_decoder_close(struct cobs_decoder *dec) +{ + int ret; + + __ASSERT_NO_MSG(dec != NULL); + + ret = cobs_decoder_needs_more_data(dec) ? -EINVAL : 0; + cobs_decoder_reset(dec); + + return ret; +} + +int cobs_decoder_write(struct cobs_decoder *dec, const uint8_t *buf, size_t len) +{ + uint8_t sentinel = COBS_FLAG_CUSTOM_DELIMITER(dec->flags); + int ret; + + __ASSERT_NO_MSG(dec != NULL); + __ASSERT_NO_MSG(len <= INT_MAX); + + for (size_t i = 0; i < len; ++i) { + uint8_t data = buf[i] ^ sentinel; + + if (data == 0x00) { + if ((dec->flags & COBS_FLAG_TRAILING_DELIMITER) == 0U || + cobs_decoder_needs_more_data(dec)) { + /* Decoder shouldn't get delimiters or unexpected end of data */ + cobs_decoder_reset(dec); return -EINVAL; } - net_buf_add_u8(dst, byte); + + /* Notify frame delimiter was seen */ + ret = dec->cb(NULL, 0, dec->cb_user_data); + if (ret < 0) { + cobs_decoder_reset(dec); + return ret; + } + + /* Reset state */ + cobs_decoder_reset(dec); + continue; + } + + if (dec->code_index > 0) { + ret = dec->cb(&data, 1, dec->cb_user_data); + if (ret < 0) { + cobs_decoder_reset(dec); + return ret; + } + + dec->code_index--; + continue; } - /* If this wasn't a maximum offset and we have more data, - * there was a delimiter here in the original data - */ - if (offset != 0xFF && src->len > 0) { - net_buf_add_u8(dst, delimiter); + dec->code_index = data; + + if (dec->code != 0xff) { + /* Group finished, output zero byte */ + data = 0x00; + + ret = dec->cb(&data, 1, dec->cb_user_data); + if (ret < 0) { + cobs_decoder_reset(dec); + return ret; + } } + + dec->code = dec->code_index; + dec->code_index--; } - return 0; + return len; } diff --git a/tests/lib/cobs/src/main.c b/tests/lib/cobs/src/main.c index c58bace63dee..5ccaeb55340d 100644 --- a/tests/lib/cobs/src/main.c +++ b/tests/lib/cobs/src/main.c @@ -60,18 +60,20 @@ struct cobs_test_item { size_t decoded_len; const uint8_t *encoded; size_t encoded_len; - uint8_t delimiter; + uint32_t flags; }; #define U8(...) (uint8_t[]) __VA_ARGS__ -#define COBS_ITEM(d, e, del, n) \ - {.name = n, \ - .decoded = d, \ - .decoded_len = sizeof(d), \ - .encoded = e, \ - .encoded_len = sizeof(e), \ - .delimiter = del} +#define COBS_ITEM(d, e, f, n) \ + { \ + .name = n, \ + .decoded = d, \ + .decoded_len = sizeof(d), \ + .encoded = e, \ + .encoded_len = sizeof(e), \ + .flags = f, \ + } static const struct cobs_test_item cobs_dataset[] = { COBS_ITEM(U8({}), U8({0x01}), COBS_DEFAULT_DELIMITER, "Empty"), @@ -91,12 +93,16 @@ static const struct cobs_test_item cobs_dataset[] = { COBS_ITEM(U8({'1', '2', '3', '4', '5', 0x00, '6', '7', '8', '9', 0x00}), U8({0x06, '1', '2', '3', '4', '5', 0x05, '6', '7', '8', '9', 0x01}), COBS_DEFAULT_DELIMITER, "Trailing zero"), - COBS_ITEM(U8({}), U8({0x01}), 0x7F, "Empty with custom delimiter 0x7F"), - COBS_ITEM(U8({'1'}), U8({0x02, '1'}), 0x7F, "One char with custom delimiter 0x7F"), - COBS_ITEM(U8({0x7F}), U8({0x01, 0x01}), 0x7F, "One 0x7F delimiter"), - COBS_ITEM(U8({0x7F, 0x7F}), U8({0x01, 0x01, 0x01}), 0x7F, "Two 0x7F delimiters"), - COBS_ITEM(U8({0x7F, 0x7F, 0x7F}), U8({0x01, 0x01, 0x01, 0x01}), 0x7F, - "Three 0x7F delimiters"), + COBS_ITEM(U8({}), U8({0x01 ^ 0x7F}), COBS_FLAG_CUSTOM_DELIMITER(0x7F), + "Empty with custom delimiter 0x7F"), + COBS_ITEM(U8({'1'}), U8({0x7D, '1' ^ 0x7F}), COBS_FLAG_CUSTOM_DELIMITER(0x7F), + "One char with custom delimiter 0x7F"), + COBS_ITEM(U8({0x7F}), U8({0x7D, 0x00}), COBS_FLAG_CUSTOM_DELIMITER(0x7F), + "One 0x7F delimiter"), + COBS_ITEM(U8({0x7F, 0x7F}), U8({0x7C, 0x00, 0x00}), COBS_FLAG_CUSTOM_DELIMITER(0x7F), + "Two 0x7F delimiters"), + COBS_ITEM(U8({0x7F, 0x7F, 0x7F}), U8({0x7B, 0x00, 0x00, 0x00}), + COBS_FLAG_CUSTOM_DELIMITER(0x7F), "Three 0x7F delimiters"), COBS_ITEM( U8({'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'a', 'b', @@ -354,13 +360,12 @@ ZTEST_F(cobs_tests, test_encode) int ret; ARRAY_FOR_EACH(cobs_dataset, idx) { - uint8_t delimiter = cobs_dataset[idx].delimiter; + uint32_t flags = cobs_dataset[idx].flags; net_buf_add_mem(fixture->test_data, cobs_dataset[idx].decoded, cobs_dataset[idx].decoded_len); - ret = cobs_encode(fixture->test_data, fixture->encoded, - COBS_FLAG_CUSTOM_DELIMITER(delimiter)); + ret = cobs_encode(fixture->test_data, fixture->encoded, flags); zassert_ok(ret, "COBS encoding failed for %s", cobs_dataset[idx].name); zassert_equal(cobs_dataset[idx].encoded_len, fixture->encoded->len, "Encoded length does not match expected for %s", @@ -383,13 +388,12 @@ ZTEST_F(cobs_tests, test_decode) int ret; ARRAY_FOR_EACH(cobs_dataset, idx) { - uint8_t delimiter = cobs_dataset[idx].delimiter; + uint32_t flags = cobs_dataset[idx].flags; net_buf_add_mem(fixture->test_data, cobs_dataset[idx].decoded, cobs_dataset[idx].decoded_len); - ret = cobs_decode(fixture->encoded, fixture->test_data, - COBS_FLAG_CUSTOM_DELIMITER(delimiter)); + ret = cobs_decode(fixture->encoded, fixture->test_data, flags); zassert_ok(ret, "COBS decoding failed for %s", cobs_dataset[idx].name); zassert_equal(cobs_dataset[idx].decoded_len, fixture->test_data->len, "Decoded length does not match expected for %s", @@ -412,14 +416,14 @@ ZTEST_F(cobs_tests, test_encode_trailing_delimiter) int ret; ARRAY_FOR_EACH(cobs_dataset, idx) { - uint8_t delimiter = cobs_dataset[idx].delimiter; + uint32_t flags = cobs_dataset[idx].flags; + uint8_t delimiter = COBS_FLAG_CUSTOM_DELIMITER(flags); net_buf_add_mem(fixture->test_data, cobs_dataset[idx].decoded, cobs_dataset[idx].decoded_len); ret = cobs_encode(fixture->test_data, fixture->encoded, - COBS_FLAG_TRAILING_DELIMITER | - COBS_FLAG_CUSTOM_DELIMITER(delimiter)); + COBS_FLAG_TRAILING_DELIMITER | flags); zassert_ok(ret, "COBS encoding failed for %s", cobs_dataset[idx].name); zassert_equal(cobs_dataset[idx].encoded_len + 1, fixture->encoded->len, "Encoded length does not match expected for %s", @@ -445,7 +449,8 @@ ZTEST_F(cobs_tests, test_decode_trailing_delimiter) int ret; ARRAY_FOR_EACH(cobs_dataset, idx) { - uint8_t delimiter = cobs_dataset[idx].delimiter; + uint32_t flags = cobs_dataset[idx].flags; + uint8_t delimiter = COBS_FLAG_CUSTOM_DELIMITER(flags); net_buf_add_mem(fixture->test_data, cobs_dataset[idx].decoded, cobs_dataset[idx].decoded_len); @@ -453,8 +458,7 @@ ZTEST_F(cobs_tests, test_decode_trailing_delimiter) net_buf_add_u8(fixture->encoded, delimiter); ret = cobs_decode(fixture->encoded, fixture->test_data, - COBS_FLAG_TRAILING_DELIMITER | - COBS_FLAG_CUSTOM_DELIMITER(delimiter)); + COBS_FLAG_TRAILING_DELIMITER | flags); zassert_ok(ret, "COBS decoding failed for %s", cobs_dataset[idx].name); zassert_equal(cobs_dataset[idx].decoded_len, fixture->test_data->len, "Decoded length does not match expected for %s", @@ -479,7 +483,7 @@ ZTEST_F(cobs_tests, test_cobs_invalid_delim_pos) net_buf_add_mem(fixture->encoded, data_enc, sizeof(data_enc)); ret = cobs_decode(fixture->encoded, fixture->decoded, 0); - zassert_true(ret == -EINVAL, "Decoding invalid delimiter caught"); + zassert_equal(ret, -EINVAL, "Decoding invalid delimiter caught"); } ZTEST_F(cobs_tests, test_cobs_consecutive_delims) @@ -489,7 +493,7 @@ ZTEST_F(cobs_tests, test_cobs_consecutive_delims) net_buf_add_mem(fixture->encoded, data_enc, sizeof(data_enc)); ret = cobs_decode(fixture->encoded, fixture->decoded, 0); - zassert_true(ret == -EINVAL, "Decoding consecutive delimiters not caught"); + zassert_equal(ret, -EINVAL, "Decoding consecutive delimiters not caught"); } ZTEST_F(cobs_tests, test_cobs_invalid_overrun) @@ -499,5 +503,5 @@ ZTEST_F(cobs_tests, test_cobs_invalid_overrun) net_buf_add_mem(fixture->encoded, data_enc, sizeof(data_enc)); ret = cobs_decode(fixture->encoded, fixture->decoded, 0); - zassert_true(ret == -EINVAL, "Decoding insufficient data not caught"); + zassert_equal(ret, -EINVAL, "Decoding insufficient data not caught"); } From aa76c1d10def3d4d50839e5c42cba946b7e587a0 Mon Sep 17 00:00:00 2001 From: Pieter De Gendt Date: Thu, 8 Jan 2026 14:09:32 +0100 Subject: [PATCH 2344/3659] tests: lib: cobs: Add streaming tests Add test cases for streaming variants of COBS encoder/decoder. Signed-off-by: Pieter De Gendt --- tests/lib/cobs/src/main.c | 160 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 160 insertions(+) diff --git a/tests/lib/cobs/src/main.c b/tests/lib/cobs/src/main.c index 5ccaeb55340d..1e4f5039e707 100644 --- a/tests/lib/cobs/src/main.c +++ b/tests/lib/cobs/src/main.c @@ -383,6 +383,46 @@ ZTEST_F(cobs_tests, test_encode) } } +static int cobs_net_buf_cb(const uint8_t *buf, size_t len, void *user_data) +{ + struct net_buf *dst = user_data; + + if (net_buf_tailroom(dst) < len) { + return -ENOMEM; + } + + (void)net_buf_add_mem(dst, buf, len); + + return 0; +} + +ZTEST_F(cobs_tests, test_encode_stream) +{ + int ret; + + ARRAY_FOR_EACH(cobs_dataset, idx) { + const struct cobs_test_item *test = &cobs_dataset[idx]; + struct cobs_encoder enc; + + ret = cobs_encoder_init(&enc, cobs_net_buf_cb, fixture->encoded, test->flags); + zassert_ok(ret, "encoder init failed for %s (%d)", test->name, ret); + + /* Simulate chunks by sending each byte */ + for (size_t i = 0; i < test->decoded_len; ++i) { + ret = cobs_encoder_write(&enc, &test->decoded[i], 1); + zassert_equal(ret, 1, "encoder write failed (%d) for %s", ret, test->name); + } + + ret = cobs_encoder_close(&enc); + zassert_ok(ret, "encoder close failed for %s (%d)", test->name, ret); + + zassert_equal(test->encoded_len, fixture->encoded->len); + zassert_mem_equal(test->encoded, fixture->encoded->data, test->encoded_len); + + net_buf_reset(fixture->encoded); + } +} + ZTEST_F(cobs_tests, test_decode) { int ret; @@ -411,6 +451,126 @@ ZTEST_F(cobs_tests, test_decode) } } +ZTEST_F(cobs_tests, test_decode_stream) +{ + int ret; + + ARRAY_FOR_EACH(cobs_dataset, idx) { + const struct cobs_test_item *test = &cobs_dataset[idx]; + struct cobs_decoder dec; + + ret = cobs_decoder_init(&dec, cobs_net_buf_cb, fixture->decoded, test->flags); + zassert_ok(ret, "decoder init failed for %s (%d)", test->name, ret); + + /* Simulate chunks by sending each byte */ + for (size_t i = 0; i < test->encoded_len; ++i) { + ret = cobs_decoder_write(&dec, &test->encoded[i], 1); + zassert_equal(ret, 1, "decoder write failed (%d) for %s", ret, test->name); + } + + ret = cobs_decoder_close(&dec); + zassert_ok(ret, "decoder close failed for %s (%d)", test->name, ret); + + zassert_equal(test->decoded_len, fixture->decoded->len); + zassert_mem_equal(test->decoded, fixture->decoded->data, test->decoded_len); + + net_buf_reset(fixture->decoded); + } +} + +static int cobs_forward_to_decoder(const uint8_t *buf, size_t len, void *user_data) +{ + struct cobs_decoder *dec = user_data; + + return cobs_decoder_write(dec, buf, len); +} + +ZTEST_F(cobs_tests, test_encode_decode_stream) +{ + int ret; + + ARRAY_FOR_EACH(cobs_dataset, idx) { + const struct cobs_test_item *test = &cobs_dataset[idx]; + struct cobs_encoder enc; + struct cobs_decoder dec; + + ret = cobs_encoder_init(&enc, cobs_forward_to_decoder, &dec, test->flags); + zassert_ok(ret, "encoder init failed for %s (%d)", test->name, ret); + + ret = cobs_decoder_init(&dec, cobs_net_buf_cb, fixture->decoded, test->flags); + zassert_ok(ret, "decoder init failed for %s (%d)", test->name, ret); + + ret = cobs_encoder_write(&enc, test->decoded, test->decoded_len); + zassert_equal(ret, test->decoded_len, "encoder write failed for %s (%d)", + test->name, ret); + + ret = cobs_encoder_close(&enc); + zassert_ok(ret, "encoder close failed for %s (%d)", test->name, ret); + + ret = cobs_decoder_close(&dec); + zassert_ok(ret, "decoder close failed for %s (%d)", test->name, ret); + + zassert_equal(test->decoded_len, fixture->decoded->len); + zassert_mem_equal(test->decoded, fixture->decoded->data, test->decoded_len); + + net_buf_reset(fixture->decoded); + } +} + +static size_t frame_test_idx; + +static int cobs_frame_tester(const uint8_t *buf, size_t len, void *user_data) +{ + struct net_buf *dst = user_data; + + if (buf == NULL) { + const struct cobs_test_item *test = &cobs_dataset[frame_test_idx]; + + zassert_equal(test->decoded_len, dst->len); + zassert_mem_equal(test->decoded, dst->data, test->decoded_len); + + net_buf_reset(dst); + frame_test_idx++; + return 0; + } + + if (net_buf_tailroom(dst) < len) { + return -ENOMEM; + } + + (void)net_buf_add_mem(dst, buf, len); + + return 0; +} + +ZTEST_F(cobs_tests, test_decode_stream_frame_complete) +{ + struct cobs_encoder enc; + struct cobs_decoder dec; + int ret; + + /* This test re-uses the same encoder/decoder pair and streams multiple frames */ + + ret = cobs_encoder_init(&enc, cobs_forward_to_decoder, &dec, COBS_FLAG_TRAILING_DELIMITER); + zassert_ok(ret, "encoder init failed (%d)", ret); + + ret = cobs_decoder_init(&dec, cobs_frame_tester, fixture->decoded, + COBS_FLAG_TRAILING_DELIMITER); + zassert_ok(ret, "decoder init failed (%d)", ret); + + ARRAY_FOR_EACH(cobs_dataset, idx) { + ret = cobs_encoder_write(&enc, cobs_dataset[idx].decoded, + cobs_dataset[idx].decoded_len); + zassert_equal(ret, cobs_dataset[idx].decoded_len); + + /* Closing will write a delimiter and reset the state */ + ret = cobs_encoder_close(&enc); + zassert_ok(ret); + } + + zassert_equal(frame_test_idx, ARRAY_SIZE(cobs_dataset)); +} + ZTEST_F(cobs_tests, test_encode_trailing_delimiter) { int ret; From 3a961db1261055cba3814ac371c090fb2e3b038d Mon Sep 17 00:00:00 2001 From: Pieter De Gendt Date: Fri, 9 Jan 2026 13:17:58 +0100 Subject: [PATCH 2345/3659] doc: releases: 4.4: Add COBS streaming support entry Add a Utilities entry with added COBS structs and functions. Signed-off-by: Pieter De Gendt --- doc/releases/release-notes-4.4.rst | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/doc/releases/release-notes-4.4.rst b/doc/releases/release-notes-4.4.rst index 28e31ee4f11c..a839131be85c 100644 --- a/doc/releases/release-notes-4.4.rst +++ b/doc/releases/release-notes-4.4.rst @@ -243,6 +243,19 @@ New APIs and options * :kconfig:option:`CONFIG_TIMEUTIL_APPLY_SKEW` +* Utilities + + * :abbr:`COBS (Consistent Overhead Byte Stuffing)` streaming support + + * :c:struct:`cobs_decoder` + * :c:func:`cobs_decoder_init` + * :c:func:`cobs_decoder_write` + * :c:func:`cobs_decoder_close` + * :c:struct:`cobs_encoder` + * :c:func:`cobs_encoder_init` + * :c:func:`cobs_encoder_write` + * :c:func:`cobs_encoder_close` + * Video * :kconfig:option:`CONFIG_VIDEO_BUFFER_POOL_HEAP_SIZE` From ae44e1e7b7189d8e10377aa5b34b94d6190fd400 Mon Sep 17 00:00:00 2001 From: Gaetan Perrot Date: Fri, 9 Jan 2026 01:51:01 +0900 Subject: [PATCH 2346/3659] drivers: sensor: ina2xx: fetch: remove redundant channel NULL checks The INA2xx fetch path assumes valid channel descriptors for all supported sensor channels. NULL checks performed after channel data is accessed are ineffective and misleading, as invalid channel definitions indicate a configuration error rather than a runtime condition. Remove the redundant checks and keep the channel handling consistent with the driver expectations. No functional change intended. Signed-off-by: Gaetan Perrot --- drivers/sensor/ti/ina2xx/ina2xx_fetch.c | 28 ------------------------- 1 file changed, 28 deletions(-) diff --git a/drivers/sensor/ti/ina2xx/ina2xx_fetch.c b/drivers/sensor/ti/ina2xx/ina2xx_fetch.c index 01e7ef138e78..c0b39e03d78c 100644 --- a/drivers/sensor/ti/ina2xx/ina2xx_fetch.c +++ b/drivers/sensor/ti/ina2xx/ina2xx_fetch.c @@ -13,10 +13,6 @@ static int ina2xx_fetch_bus_voltage(const struct device *dev) const struct ina2xx_channel *ch = config->channels->voltage; struct ina2xx_data *data = dev->data; - if (ch == NULL) { - return -ENOTSUP; - } - return ina2xx_reg_read(&config->bus, ch->reg, data->voltage, sizeof(data->voltage)); } @@ -30,10 +26,6 @@ static int ina2xx_fetch_shunt_voltage(const struct device *dev) const struct ina2xx_channel *ch = config->channels->vshunt; struct ina2xx_data *data = dev->data; - if (ch == NULL) { - return -ENOTSUP; - } - return ina2xx_reg_read(&config->bus, ch->reg, data->vshunt, sizeof(data->vshunt)); } @@ -47,10 +39,6 @@ static int ina2xx_fetch_current(const struct device *dev) const struct ina2xx_channel *ch = config->channels->current; struct ina2xx_data *data = dev->data; - if (ch == NULL) { - return -ENOTSUP; - } - return ina2xx_reg_read(&config->bus, ch->reg, data->current, sizeof(data->current)); } @@ -64,10 +52,6 @@ static int ina2xx_fetch_power(const struct device *dev) const struct ina2xx_channel *ch = config->channels->power; struct ina2xx_data *data = dev->data; - if (ch == NULL) { - return -ENOTSUP; - } - return ina2xx_reg_read(&config->bus, ch->reg, data->power, sizeof(data->power)); } @@ -81,10 +65,6 @@ static int ina2xx_fetch_die_temp(const struct device *dev) const struct ina2xx_channel *ch = config->channels->die_temp; struct ina2xx_data *data = dev->data; - if (ch == NULL) { - return -ENOTSUP; - } - return ina2xx_reg_read(&config->bus, ch->reg, data->die_temp, sizeof(data->die_temp)); } @@ -99,10 +79,6 @@ static int ina2xx_fetch_energy(const struct device *dev) const struct ina2xx_channel *ch = config->channels->energy; struct ina2xx_data *data = dev->data; - if (ch == NULL) { - return -ENOTSUP; - } - return ina2xx_reg_read(&config->bus, ch->reg, data->energy, sizeof(data->energy)); } @@ -116,10 +92,6 @@ static int ina2xx_fetch_charge(const struct device *dev) const struct ina2xx_channel *ch = config->channels->charge; struct ina2xx_data *data = dev->data; - if (ch == NULL) { - return -ENOTSUP; - } - return ina2xx_reg_read(&config->bus, ch->reg, data->charge, sizeof(data->charge)); } From 8340e8c264ca491157516335fa09e1541e3961f2 Mon Sep 17 00:00:00 2001 From: Gaetan Perrot Date: Fri, 9 Jan 2026 01:50:38 +0900 Subject: [PATCH 2347/3659] drivers: sensor: ina2xx: get: remove redundant channel NULL checks The ina2xx channel get helpers assume that channel descriptors are valid when the driver exposes a given sensor channel. Checking for NULL channel pointers after they are already dereferenced does not provide any real safety and can hide configuration errors. Drop the late NULL checks and rely on the driver contract that supported channels must be properly defined. No functional change intended. Signed-off-by: Gaetan Perrot --- drivers/sensor/ti/ina2xx/ina2xx_get.c | 28 --------------------------- 1 file changed, 28 deletions(-) diff --git a/drivers/sensor/ti/ina2xx/ina2xx_get.c b/drivers/sensor/ti/ina2xx/ina2xx_get.c index cc8777be51ef..27fd13201db3 100644 --- a/drivers/sensor/ti/ina2xx/ina2xx_get.c +++ b/drivers/sensor/ti/ina2xx/ina2xx_get.c @@ -20,10 +20,6 @@ static int ina2xx_get_bus_voltage(const struct device *dev, struct sensor_value int32_t s32; } value; - if (ch == NULL) { - return -ENOTSUP; - } - /* 16 or 20 bit, two's complement */ if (bytes == 2) { value.u32 = sys_get_be16(data->voltage) >> ch->shift; @@ -51,10 +47,6 @@ static int ina2xx_get_shunt_voltage(const struct device *dev, struct sensor_valu int32_t s32; } value; - if (ch == NULL) { - return -ENOTSUP; - } - /* 16 or 20 bit, two's complement */ if (bytes == 2) { value.u32 = sys_get_be16(data->vshunt) >> ch->shift; @@ -82,10 +74,6 @@ static int ina2xx_get_current(const struct device *dev, struct sensor_value *val int32_t s32; } value; - if (ch == NULL) { - return -ENOTSUP; - } - /* 16 or 20 bit, two's complement. Multiplied by current lsb */ if (bytes == 2) { value.u32 = sys_get_be16(data->current) >> ch->shift; @@ -110,10 +98,6 @@ static int ina2xx_get_power(const struct device *dev, struct sensor_value *val) struct ina2xx_data *data = dev->data; uint64_t value; - if (ch == NULL) { - return -ENOTSUP; - } - /* 16 or 24 bit, unsigned. Multiplied by current lsb */ if (bytes == 2) { value = sys_get_be16(data->power) >> ch->shift; @@ -139,10 +123,6 @@ static int ina2xx_get_die_temp(const struct device *dev, struct sensor_value *va int64_t s64; } value; - if (ch == NULL) { - return -ENOTSUP; - } - /* 12 or 16 bit, two's complement. */ if (bytes == 2) { value.u64 = sys_get_be16(data->die_temp) >> ch->shift; @@ -164,10 +144,6 @@ static int ina2xx_get_energy(const struct device *dev, struct sensor_value *val) struct ina2xx_data *data = dev->data; uint64_t value; - if (ch == NULL) { - return -ENOTSUP; - } - /* 40 bit, unsigned. Multiplied by current lsb */ if (bytes == 5) { value = sys_get_be40(data->energy) >> ch->shift; @@ -191,10 +167,6 @@ static int ina2xx_get_charge(const struct device *dev, struct sensor_value *val) int64_t s64; } value; - if (ch == NULL) { - return -ENOTSUP; - } - /* 40 bit, two's complement. Multiplied by current lsb */ if (bytes == 5) { value.u64 = sys_get_be40(data->charge) >> ch->shift; From efc36d96d34acc283674ac576ba564f9be163c57 Mon Sep 17 00:00:00 2001 From: Grzegorz Chwierut Date: Fri, 9 Jan 2026 17:51:58 +0100 Subject: [PATCH 2348/3659] twister: refactor DUT class to dataclass for serialization support Convert the DUT class from a traditional class to a dataclass to enable proper serialization and support for future multi-device testing with pytest-harness. Key changes: - Migrated DUT class to use `dataclass` decorator with proper type hints - Renamed `baud` property to `serial_baud` for consistency - Updated hardware map schema to support both `baud` (legacy) and `serial_baud` fields for backward compatibility - Updated tests Signed-off-by: Grzegorz Chwierut --- scripts/pylib/twister/twisterlib/handlers.py | 6 +- .../pylib/twister/twisterlib/hardwaremap.py | 91 ++++++++----------- scripts/pylib/twister/twisterlib/harness.py | 2 +- scripts/schemas/twister/hwmap-schema.yaml | 3 + scripts/tests/twister/test_hardwaremap.py | 38 +++----- scripts/tests/twister/test_harness.py | 2 +- .../twister_blackbox/test_hardwaremap.py | 6 +- 7 files changed, 65 insertions(+), 83 deletions(-) diff --git a/scripts/pylib/twister/twisterlib/handlers.py b/scripts/pylib/twister/twisterlib/handlers.py index 6e321cfec2c0..0b893e8569ed 100755 --- a/scripts/pylib/twister/twisterlib/handlers.py +++ b/scripts/pylib/twister/twisterlib/handlers.py @@ -765,7 +765,7 @@ def handle(self, harness): ser_pty_master, slave = pty.openpty() serial_device = os.ttyname(slave) - logger.debug(f"Using serial device {serial_device} @ {hardware.baud} baud") + logger.debug(f"Using serial device {serial_device} @ {hardware.serial_baud} baud") command = self._create_command(runner, hardware) @@ -787,7 +787,7 @@ def handle(self, harness): ser = self._create_serial_connection( hardware, serial_port, - hardware.baud, + hardware.serial_baud, flash_timeout, serial_pty, ser_pty_process @@ -848,7 +848,7 @@ def handle(self, harness): try: if serial_pty: ser_pty_process = self._start_serial_pty(serial_pty, ser_pty_master) - logger.debug(f"Attach serial device {serial_device} @ {hardware.baud} baud") + logger.debug(f"Attach serial device {serial_device} @ {hardware.serial_baud} baud") ser.port = serial_device # Apply ESP32-specific RTS/DTR reset logic diff --git a/scripts/pylib/twister/twisterlib/hardwaremap.py b/scripts/pylib/twister/twisterlib/hardwaremap.py index 6bbf22099c32..6f32849f27a4 100644 --- a/scripts/pylib/twister/twisterlib/hardwaremap.py +++ b/scripts/pylib/twister/twisterlib/hardwaremap.py @@ -3,13 +3,16 @@ # # Copyright (c) 2022 Intel Corporation # SPDX-License-Identifier: Apache-2.0 +from __future__ import annotations import logging import os import platform import re +from dataclasses import asdict, dataclass, field from multiprocessing import Lock, Value from pathlib import Path +from typing import Any import scl import yaml @@ -32,50 +35,39 @@ logger = logging.getLogger('twister') +@dataclass class DUT: - def __init__(self, - id=None, - serial=None, - serial_baud=None, - platform=None, - product=None, - serial_pty=None, - connected=False, - runner_params=None, - pre_script=None, - post_script=None, - post_flash_script=None, - script_param=None, - runner=None, - flash_timeout=60, - flash_with_test=False, - flash_before=False): - - self.serial = serial - self.baud = serial_baud or 115200 - self.platform = platform - self.serial_pty = serial_pty + """Device Under Test configuration.""" + id: str | None = None + serial: str | None = None + serial_baud: int = 115200 + platform: str | None = None + product: str | None = None + serial_pty: str | None = None + connected: bool = False + runner_params: str | None = None + pre_script: str | None = None + post_script: str | None = None + post_flash_script: str | None = None + script_param: str | None = None + runner: str | None = None + flash_timeout: int = 60 + flash_with_test: bool = False + flash_before: bool = False + fixtures: list[str] = field(default_factory=list) + probe_id: str | None = None + notes: str | None = None + match: bool = False + + def __post_init__(self): + """Initialize non-serializable objects after dataclass initialization.""" + # These are not dataclass fields, so they won't be serialized by asdict() self._counter = Value("i", 0) self._available = Value("i", 1) self._failures = Value("i", 0) - self.connected = connected - self.pre_script = pre_script - self.id = id - self.product = product - self.runner = runner - self.runner_params = runner_params - self.flash_before = flash_before - self.fixtures = [] - self.post_flash_script = post_flash_script - self.post_script = post_script - self.pre_script = pre_script - self.script_param = script_param - self.probe_id = None - self.notes = None self.lock = Lock() - self.match = False - self.flash_timeout = flash_timeout - self.flash_with_test = flash_with_test + # Ensure serial_baud has a default value + self.serial_baud = self.serial_baud or 115200 @property def available(self): @@ -115,19 +107,16 @@ def failures_increment(self, value=1): with self._failures.get_lock(): self._failures.value += value - def to_dict(self): - d = {} - exclude = ['_available', '_counter', '_failures', 'match'] - v = vars(self) - for k in v: - if k not in exclude and v[k]: - d[k] = v[k] - return d - + def to_dict(self) -> dict[str, Any]: + """Convert DUT dataclass to dictionary for YAML serialization.""" + result = asdict(self) + # Remove None and False values and empty lists to keep YAML clean + return {k: v for k, v in result.items() if v} def __repr__(self): return f"<{self.platform} ({self.product}) on {self.serial}>" + class HardwareMap: schema_path = os.path.join(ZEPHYR_BASE, "scripts", "schemas", "twister", "hwmap-schema.yaml") @@ -170,7 +159,7 @@ class HardwareMap: } def __init__(self, env=None): - self.detected = [] + self.detected: list[DUT] = [] self.duts: list[DUT] = [] self.options = env.options @@ -295,7 +284,7 @@ def load(self, map_file): runner = dut.get('runner') runner_params = dut.get('runner_params') serial = dut.get('serial') - baud = dut.get('baud', None) + serial_baud = dut.get('serial_baud', None) or dut.get('baud', None) product = dut.get('product') fixtures = dut.get('fixtures', []) connected = dut.get('connected') and ((serial or serial_pty) is not None) @@ -309,7 +298,7 @@ def load(self, map_file): id=id, serial_pty=serial_pty, serial=serial, - serial_baud=baud, + serial_baud=serial_baud, connected=connected, pre_script=pre_script, flash_before=flash_before, diff --git a/scripts/pylib/twister/twisterlib/harness.py b/scripts/pylib/twister/twisterlib/harness.py index d00d308c5542..957ebba1b874 100644 --- a/scripts/pylib/twister/twisterlib/harness.py +++ b/scripts/pylib/twister/twisterlib/harness.py @@ -463,7 +463,7 @@ def _generate_parameters_for_hardware(self, handler: Handler): else: command.extend([ f'--device-serial={hardware.serial}', - f'--device-serial-baud={hardware.baud}' + f'--device-serial-baud={hardware.serial_baud}' ]) for extra_serial in handler.get_more_serials_from_device(hardware): command.append(f'--device-serial={extra_serial}') diff --git a/scripts/schemas/twister/hwmap-schema.yaml b/scripts/schemas/twister/hwmap-schema.yaml index 142d4a1969bf..caa58088fd6d 100644 --- a/scripts/schemas/twister/hwmap-schema.yaml +++ b/scripts/schemas/twister/hwmap-schema.yaml @@ -41,6 +41,9 @@ sequence: "baud": type: int required: false + "serial_baud": + type: int + required: false "post_script": type: str required: false diff --git a/scripts/tests/twister/test_hardwaremap.py b/scripts/tests/twister/test_hardwaremap.py index 5d0ea798ed64..f7ed424f996b 100644 --- a/scripts/tests/twister/test_hardwaremap.py +++ b/scripts/tests/twister/test_hardwaremap.py @@ -37,7 +37,7 @@ def mocked_hm(): TESTDATA_1 = [ ( {}, - {'baud': 115200, 'lock': mock.ANY, 'flash_timeout': 60}, + {'serial_baud': 115200, 'flash_timeout': 60}, '' ), ( @@ -63,10 +63,9 @@ def mocked_hm(): } }, { - 'lock': mock.ANY, 'id': 'dummy id', 'serial': 'dummy serial', - 'baud': 4400, + 'serial_baud': 4400, 'platform': 'dummy platform', 'product': 'dummy product', 'serial_pty': 'dummy serial pty', @@ -269,7 +268,7 @@ def test_hardwaremap_load(): runner: r0 flash_with_test: True flash_timeout: 15 - baud: 14400 + serial_baud: 14400 fixtures: - dummy fixture 1 - dummy fixture 2 @@ -310,7 +309,7 @@ def mock_open(*args, **kwargs): 'runner': 'r0', 'flash_timeout': 15, 'flash_with_test': True, - 'baud': 14400, + 'serial_baud': 14400, 'fixtures': ['dummy fixture 1', 'dummy fixture 2'], 'connected': True, 'serial': 'dummy', @@ -322,7 +321,7 @@ def mock_open(*args, **kwargs): 'runner': 'r1', 'flash_timeout': 30, 'flash_with_test': False, - 'baud': 115200, + 'serial_baud': 115200, 'fixtures': [], 'connected': True, 'serial': None, @@ -503,50 +502,45 @@ def mock_exists(path): '', [{ 'serial': 's1', - 'baud': 115200, + 'serial_baud': 115200, 'platform': 'p1', 'connected': True, 'id': 1, 'product': 'pr1', - 'lock': mock.ANY, 'flash_timeout': 60 }, { 'serial': 's2', - 'baud': 115200, + 'serial_baud': 115200, 'platform': 'p2', 'id': 2, 'product': 'pr2', - 'lock': mock.ANY, 'flash_timeout': 60 }, { 'serial': 's3', - 'baud': 115200, + 'serial_baud': 115200, 'platform': 'p3', 'connected': True, 'id': 3, 'product': 'pr3', - 'lock': mock.ANY, 'flash_timeout': 60 }, { 'serial': 's4', - 'baud': 115200, + 'serial_baud': 115200, 'platform': 'p4', 'id': 4, 'product': 'pr4', - 'lock': mock.ANY, 'flash_timeout': 60 }, { 'serial': 's5', - 'baud': 115200, + 'serial_baud': 115200, 'platform': 'p5', 'connected': True, 'id': 5, 'product': 'pr5', - 'lock': mock.ANY, 'flash_timeout': 60 }] ), @@ -603,41 +597,37 @@ def mock_exists(path): }, { 'serial': 's1', - 'baud': 115200, + 'serial_baud': 115200, 'platform': 'p1', 'connected': True, 'id': 1, 'product': 'pr1', - 'lock': mock.ANY, 'flash_timeout': 60 }, { 'serial': 's2', - 'baud': 115200, + 'serial_baud': 115200, 'platform': 'p2', 'id': 2, 'product': 'pr2', - 'lock': mock.ANY, 'flash_timeout': 60 }, { 'serial': 's3', - 'baud': 115200, + 'serial_baud': 115200, 'platform': 'p3', 'connected': True, 'id': 3, 'product': 'pr3', - 'lock': mock.ANY, 'flash_timeout': 60 }, { 'serial': 's5', - 'baud': 115200, + 'serial_baud': 115200, 'platform': 'p5', 'connected': True, 'id': 5, 'product': 'pr5', - 'lock': mock.ANY, 'flash_timeout': 60 }] ), diff --git a/scripts/tests/twister/test_harness.py b/scripts/tests/twister/test_harness.py index fc90205f32e2..62fc6460e788 100644 --- a/scripts/tests/twister/test_harness.py +++ b/scripts/tests/twister/test_harness.py @@ -552,7 +552,7 @@ def test_pytest__generate_parameters_for_hardware(tmp_path, pty_value, hardware_ hardware = mock.Mock() hardware.serial_pty = pty_value hardware.serial = "serial" - hardware.baud = 115200 + hardware.serial_baud = 115200 hardware.runner = "runner" hardware.runner_params = ["--runner-param1", "runner-param2"] hardware.fixtures = ["fixture1:option1", "fixture2"] diff --git a/scripts/tests/twister_blackbox/test_hardwaremap.py b/scripts/tests/twister_blackbox/test_hardwaremap.py index 01bab62313e0..e39ab75c2638 100644 --- a/scripts/tests/twister_blackbox/test_hardwaremap.py +++ b/scripts/tests/twister_blackbox/test_hardwaremap.py @@ -112,7 +112,7 @@ def teardown_class(cls): def test_generate(self, capfd, out_path, manufacturer, product, serial, runner): file_name = "test-map.yaml" path = os.path.join(ZEPHYR_BASE, file_name) - args = ['--outdir', out_path, '--generate-hardware-map', file_name] + args = ['--outdir', out_path, '--generate-hardware-map', path] if os.path.exists(path): os.remove(path) @@ -164,7 +164,7 @@ def mocked_comports(): def test_few_generate(self, capfd, out_path, manufacturer, product, serial, runner): file_name = "test-map.yaml" path = os.path.join(ZEPHYR_BASE, file_name) - args = ['--outdir', out_path, '--generate-hardware-map', file_name] + args = ['--outdir', out_path, '--generate-hardware-map', path] if os.path.exists(path): os.remove(path) @@ -245,7 +245,7 @@ def mocked_comports(): def test_texas_exeption(self, capfd, out_path, manufacturer, product, serial, location): file_name = "test-map.yaml" path = os.path.join(ZEPHYR_BASE, file_name) - args = ['--outdir', out_path, '--generate-hardware-map', file_name] + args = ['--outdir', out_path, '--generate-hardware-map', path] if os.path.exists(path): os.remove(path) From f5bee07bf5822f7c13044771ebfae6ff8abff91c Mon Sep 17 00:00:00 2001 From: Albort Xue Date: Tue, 13 Jan 2026 16:30:13 +0800 Subject: [PATCH 2349/3659] drivers: spi: nxp_lpspi: Add clock configuration support Add clock_control_configure() call during initialization to properly configure the LPSPI clock. The implementation gracefully handles platforms that don't support clock configuration by checking for -ENOTSUP and -ENOSYS return codes and continuing with default settings. Real configuration errors are logged and propagated. Signed-off-by: Albort Xue --- drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi_common.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi_common.c b/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi_common.c index e0b31c2dd8bc..9a9e5495b747 100644 --- a/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi_common.c +++ b/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi_common.c @@ -1,5 +1,5 @@ /* - * Copyright 2018, 2024-2025 NXP + * Copyright 2018, 2024-2026 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -384,6 +384,16 @@ int spi_nxp_init_common(const struct device *dev) return -ENODEV; } + err = clock_control_configure(config->clock_dev, config->clock_subsys, NULL); + if (err != 0) { + /* Check if error is due to lack of support */ + if (err != -ENOSYS) { + /* Real error occurred */ + LOG_ERR("Failed to configure clock: %d", err); + return err; + } + } + lpspi_module_system_init(base); data->major_version = (base->VERID & LPSPI_VERID_MAJOR_MASK) >> LPSPI_VERID_MAJOR_SHIFT; From a5dd03b02975d4429f02296ec730bc442033b2ca Mon Sep 17 00:00:00 2001 From: Sylvio Alves Date: Wed, 14 Jan 2026 09:50:26 -0300 Subject: [PATCH 2350/3659] tests: drivers: i2s: initialize i2s_config struct to avoid garbage Initialize the i2s_config struct to zero before use in the test_i2s_state_not_ready_neg test case. When frame_clk_freq is set to 0 to unconfigure a stream, other fields in the struct were left uninitialized. On platforms with userspace support, the syscall handler validates block_size against the mem_slab block size before calling the driver. Uninitialized garbage values could cause this validation to fail unexpectedly. Signed-off-by: Sylvio Alves --- tests/drivers/i2s/i2s_api/src/common.c | 2 +- tests/drivers/i2s/i2s_api/src/test_i2s_states.c | 2 +- tests/drivers/i2s/i2s_speed/src/test_i2s_speed.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/drivers/i2s/i2s_api/src/common.c b/tests/drivers/i2s/i2s_api/src/common.c index 3faadeccf79b..c6338b908146 100644 --- a/tests/drivers/i2s/i2s_api/src/common.c +++ b/tests/drivers/i2s/i2s_api/src/common.c @@ -175,7 +175,7 @@ int rx_block_read(const struct device *dev_i2s, int att) int configure_stream(const struct device *dev_i2s, enum i2s_dir dir) { int ret; - struct i2s_config i2s_cfg; + struct i2s_config i2s_cfg = {0}; i2s_cfg.word_size = 16U; i2s_cfg.channels = 2U; diff --git a/tests/drivers/i2s/i2s_api/src/test_i2s_states.c b/tests/drivers/i2s/i2s_api/src/test_i2s_states.c index 190a87007cf7..8ad895ee31c8 100644 --- a/tests/drivers/i2s/i2s_api/src/test_i2s_states.c +++ b/tests/drivers/i2s/i2s_api/src/test_i2s_states.c @@ -18,7 +18,7 @@ */ ZTEST_USER(i2s_states, test_i2s_state_not_ready_neg) { - struct i2s_config i2s_cfg; + struct i2s_config i2s_cfg = {0}; size_t rx_size; int ret; char rx_buf[BLOCK_SIZE]; diff --git a/tests/drivers/i2s/i2s_speed/src/test_i2s_speed.c b/tests/drivers/i2s/i2s_speed/src/test_i2s_speed.c index a27a8465d1f5..23cabf656f88 100644 --- a/tests/drivers/i2s/i2s_speed/src/test_i2s_speed.c +++ b/tests/drivers/i2s/i2s_speed/src/test_i2s_speed.c @@ -129,7 +129,7 @@ static int verify_buf(int16_t *rx_block, int att) static int configure_stream(const struct device *dev_i2s, enum i2s_dir dir, uint32_t frame_clk_freq) { int ret; - struct i2s_config i2s_cfg; + struct i2s_config i2s_cfg = {0}; i2s_cfg.word_size = 16U; i2s_cfg.channels = 2U; From be501ebb0631f954e65e49321616ca688d112874 Mon Sep 17 00:00:00 2001 From: Sylvio Alves Date: Wed, 14 Jan 2026 10:00:57 -0300 Subject: [PATCH 2351/3659] drivers: i2s: skip syscall validation when unconfiguring stream When frame_clk_freq is set to 0, the I2S API specifies that the stream should transition to NOT_READY state (i.e., unconfigure). In this case, other config fields like mem_slab and block_size are not used by the driver. Skip the mem_slab and block_size validation in the syscall handler when frame_clk_freq is 0 to match the driver behavior and avoid rejecting valid unconfigure requests due to uninitialized fields. Signed-off-by: Sylvio Alves --- drivers/i2s/i2s_handlers.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/i2s/i2s_handlers.c b/drivers/i2s/i2s_handlers.c index 3f1c31a46c7a..c9820f00e290 100644 --- a/drivers/i2s/i2s_handlers.c +++ b/drivers/i2s/i2s_handlers.c @@ -23,6 +23,13 @@ static inline int z_vrfy_i2s_configure(const struct device *dev, K_OOPS(k_usermode_from_copy(&config, (const void *)cfg_ptr, sizeof(struct i2s_config))); + /* When frame_clk_freq is 0, the stream is being disabled/unconfigured + * and other config fields are not used, so skip validation. + */ + if (config.frame_clk_freq == 0U) { + goto do_configure; + } + /* Check that the k_mem_slab provided is a valid pointer and that * the caller has permission on it */ @@ -37,6 +44,7 @@ static inline int z_vrfy_i2s_configure(const struct device *dev, goto out; } +do_configure: ret = z_impl_i2s_configure((const struct device *)dev, dir, &config); out: return ret; From 7c66a65c73dfb58a697d90e092cccfd8606244be Mon Sep 17 00:00:00 2001 From: Jonas Berg Date: Sun, 18 Jan 2026 13:25:04 +0100 Subject: [PATCH 2352/3659] boards: shields: Add Adafruit HTS221 humidity sensor shield Tested with the command mentioned in index.rst Compile testing of the overlay file is done via the dht_polling sample. Product photo from https://learn.adafruit.com/assets/89387 Signed-off-by: Jonas Berg --- boards/shields/adafruit_hts221/Kconfig.shield | 5 ++ .../adafruit_hts221/adafruit_hts221.overlay | 21 ++++++ .../adafruit_hts221/doc/adafruit_hts221.webp | Bin 0 -> 42624 bytes boards/shields/adafruit_hts221/doc/index.rst | 63 ++++++++++++++++++ boards/shields/adafruit_hts221/shield.yml | 10 +++ samples/sensor/dht_polling/sample.yaml | 2 + 6 files changed, 101 insertions(+) create mode 100644 boards/shields/adafruit_hts221/Kconfig.shield create mode 100644 boards/shields/adafruit_hts221/adafruit_hts221.overlay create mode 100644 boards/shields/adafruit_hts221/doc/adafruit_hts221.webp create mode 100644 boards/shields/adafruit_hts221/doc/index.rst create mode 100644 boards/shields/adafruit_hts221/shield.yml diff --git a/boards/shields/adafruit_hts221/Kconfig.shield b/boards/shields/adafruit_hts221/Kconfig.shield new file mode 100644 index 000000000000..f7f427c5ca98 --- /dev/null +++ b/boards/shields/adafruit_hts221/Kconfig.shield @@ -0,0 +1,5 @@ +# Copyright (c) 2026 Jonas Berg +# SPDX-License-Identifier: Apache-2.0 + +config SHIELD_ADAFRUIT_HTS221 + def_bool $(shields_list_contains,adafruit_hts221) diff --git a/boards/shields/adafruit_hts221/adafruit_hts221.overlay b/boards/shields/adafruit_hts221/adafruit_hts221.overlay new file mode 100644 index 000000000000..8a244d3c10a9 --- /dev/null +++ b/boards/shields/adafruit_hts221/adafruit_hts221.overlay @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2026 Jonas Berg + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + dht0 = &adafruit_hts221; + }; +}; + +&zephyr_i2c { + status = "okay"; + + adafruit_hts221: hts221@5f { + status = "okay"; + compatible = "st,hts221"; + reg = <0x5f>; + }; +}; diff --git a/boards/shields/adafruit_hts221/doc/adafruit_hts221.webp b/boards/shields/adafruit_hts221/doc/adafruit_hts221.webp new file mode 100644 index 0000000000000000000000000000000000000000..c39662fc629ee88394fdd61dde19d3bcc0eb5157 GIT binary patch literal 42624 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®NT0bCO<0G231Ih+kkDv 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 E04?tNE&u=k literal 0 HcmV?d00001 diff --git a/boards/shields/adafruit_hts221/doc/index.rst b/boards/shields/adafruit_hts221/doc/index.rst new file mode 100644 index 000000000000..0f6ecb2d0aa7 --- /dev/null +++ b/boards/shields/adafruit_hts221/doc/index.rst @@ -0,0 +1,63 @@ +.. _adafruit_hts221: + +Adafruit HTS221 Shield +###################### + +Overview +******** + +The `Adafruit HTS221 Temperature and Humidity Sensor Shield`_ features +a `ST Microelectronics HTS221 Humidity and Temperature Sensor`_ and two STEMMA QT connectors. +It measures temperature and humidity. + +.. figure:: adafruit_hts221.webp + :align: center + :alt: Adafruit HTS221 Shield + + Adafruit HTS221 Shield (Credit: Adafruit) + + +Requirements +************ + +This shield can be used with boards which provide an I2C connector, for example STEMMA QT or +Qwiic connectors. The target board must define a ``zephyr_i2c`` node label. +See :ref:`shields` for more details. + + +Pin Assignments +=============== + ++--------------+------------------------------------+ +| Shield Pin | Function | ++==============+====================================+ +| SDA | I2C SDA | ++--------------+------------------------------------+ +| SCL | I2C SCL | ++--------------+------------------------------------+ +| DRDY | Data ready output | ++--------------+------------------------------------+ +| CS | Keep at high level to use I2C mode | ++--------------+------------------------------------+ + +See :dtcompatible:`st,hts221` for details on possible devicetree settings, for example if you +are using the DRDY pin. + + +Programming +*********** + +Set ``--shield adafruit_hts221`` when you invoke ``west build``. For example +when running the :zephyr:code-sample:`dht_polling` sample: + +.. zephyr-app-commands:: + :zephyr-app: samples/sensor/dht_polling + :board: adafruit_feather_scorpio_rp2040 + :shield: adafruit_hts221 + :goals: build flash + +.. _Adafruit HTS221 Temperature and Humidity Sensor Shield: + https://learn.adafruit.com/adafruit-hts221-temperature-humidity-sensor + +.. _ST Microelectronics HTS221 Humidity and Temperature Sensor: + https://www.st.com/resource/en/datasheet/hts221.pdf diff --git a/boards/shields/adafruit_hts221/shield.yml b/boards/shields/adafruit_hts221/shield.yml new file mode 100644 index 000000000000..546ffd6f5b1f --- /dev/null +++ b/boards/shields/adafruit_hts221/shield.yml @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# Copyright (c) 2026, Jonas Berg + +shield: + name: adafruit_hts221 + full_name: Adafruit HTS221 Temperature and Humidity Sensor Shield + vendor: adafruit + supported_features: + - sensor diff --git a/samples/sensor/dht_polling/sample.yaml b/samples/sensor/dht_polling/sample.yaml index 8d0b182a8c33..74ab8e0b1eec 100644 --- a/samples/sensor/dht_polling/sample.yaml +++ b/samples/sensor/dht_polling/sample.yaml @@ -17,11 +17,13 @@ tests: - adafruit_qt_py_rp2040/rp2040 - adafruit_feather_rp2040/rp2040 - adafruit_feather_canbus_rp2040/rp2040 + - adafruit_feather_scorpio_rp2040/rp2040 - nucleo_f401re extra_args: - platform:adafruit_qt_py_rp2040/rp2040:SHIELD="adafruit_aht20" - platform:adafruit_feather_rp2040/rp2040:SHIELD="adafruit_sht4x" - platform:adafruit_feather_canbus_rp2040/rp2040:SHIELD="sparkfun_shtc3" + - platform:adafruit_feather_scorpio_rp2040/rp2040:SHIELD="adafruit_hts221" harness: console harness_config: fixture: fixture_i2c_hs300x From c2011b9d0f66a5ed936d133fcdf2d86e2cce2273 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magne=20V=C3=A6rnes?= Date: Mon, 19 Jan 2026 13:36:30 +0100 Subject: [PATCH 2353/3659] lib: posix: add missing getopt_long guard MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added ifdef guard (CONFIG_GETOPT_LONG) around the functions in getopt_shim.c that requires getopt_long implementation. Signed-off-by: Magne Værnes --- lib/posix/c_lib_ext/getopt_shim.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/posix/c_lib_ext/getopt_shim.c b/lib/posix/c_lib_ext/getopt_shim.c index 1187c53440ab..251029b51cf2 100644 --- a/lib/posix/c_lib_ext/getopt_shim.c +++ b/lib/posix/c_lib_ext/getopt_shim.c @@ -34,6 +34,7 @@ void z_getopt_global_state_update_shim(struct sys_getopt_state *state) optarg = state->optarg; } +#if CONFIG_GETOPT_LONG int getopt_long(int argc, char *const argv[], const char *shortopts, const struct option *longopts, int *longind) { @@ -45,3 +46,4 @@ int getopt_long_only(int argc, char *const argv[], const char *shortopts, { return sys_getopt_long_only(argc, argv, shortopts, longopts, longind); } +#endif From 7294fca0ac1cdf5916c82039af66cd33b1a454c6 Mon Sep 17 00:00:00 2001 From: Sudan Landge Date: Wed, 7 Jan 2026 13:29:18 +0000 Subject: [PATCH 2354/3659] boards: arm: musca: Update flash layout to fix ci failure Flash layout of musca_b1 and musca_s1 is updated as recommended by mcuboot. This also fixes the below cmake build failures reported in Zephyr ci. ``` CMake Error at zephyrproject/zephyr/cmake/modules/extensions.cmake:3877 (message): required nodelabel not found: slot0_partition Call Stack (most recent call first): zephyrproject/zephyr/modules/trusted-firmware-m/CMakeLists.txt:489 (dt_nodelabel) ``` Note that the flash address of musca_b1 board is fixed from 0x0A07_0000 to 0x0A08_0000 as this was missed after the layout was changed in TF-M in e1570bd143ef4843a531b57f77f0c2814b075dd9 Signed-off-by: Sudan Landge --- .../v2m_musca_b1/v2m_musca_b1_musca_b1_ns.dts | 29 +++++++++++++++++-- .../v2m_musca_s1/v2m_musca_s1_musca_s1_ns.dts | 29 +++++++++++++++++-- 2 files changed, 54 insertions(+), 4 deletions(-) diff --git a/boards/arm/v2m_musca_b1/v2m_musca_b1_musca_b1_ns.dts b/boards/arm/v2m_musca_b1/v2m_musca_b1_musca_b1_ns.dts index c24d8c256754..550f9996b8a7 100644 --- a/boards/arm/v2m_musca_b1/v2m_musca_b1_musca_b1_ns.dts +++ b/boards/arm/v2m_musca_b1/v2m_musca_b1_musca_b1_ns.dts @@ -1,5 +1,6 @@ /* * Copyright (c) 2019 Linaro Limited + * Copyright 2026 Arm Limited and/or its affiliates * * SPDX-License-Identifier: Apache-2.0 */ @@ -7,6 +8,7 @@ /dts-v1/; #include +#include / { compatible = "arm,v2m-musca"; @@ -19,6 +21,7 @@ zephyr,console = &uart1; zephyr,sram = &sram0; zephyr,flash = &flash0; + zephyr,code-partitions = &slot0_ns_partition; zephyr,shell-uart = &uart1; }; @@ -40,9 +43,31 @@ }; }; - flash0: flash@a070000 { + flash0: flash@a000000 { /* Embedded flash */ - reg = <0xa070000 0x1a0000>; + compatible = "soc-nv-flash"; + reg = <0x0a000000 DT_SIZE_M(2)>; + erase-block-size = ; + write-block-size = <4>; + #address-cells = <1>; + #size-cells = <1>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + /* Please see the memory layout in: + * https://git.trustedfirmware.org/plugins/gitiles/TF-M/trusted-firmware-m.git/+/refs/heads/main/platform/ext/target/arm/musca_b1/partition/flash_layout.h + */ + slot0_partition: partition@20000 { + reg = <0x20000 DT_SIZE_K(384)>; + }; + + slot0_ns_partition: partition@80000 { + reg = <0x80000 DT_SIZE_K(512)>; + }; + }; }; sram0: memory@20040000 { diff --git a/boards/arm/v2m_musca_s1/v2m_musca_s1_musca_s1_ns.dts b/boards/arm/v2m_musca_s1/v2m_musca_s1_musca_s1_ns.dts index afe985c20f6f..8c9775ba215c 100644 --- a/boards/arm/v2m_musca_s1/v2m_musca_s1_musca_s1_ns.dts +++ b/boards/arm/v2m_musca_s1/v2m_musca_s1_musca_s1_ns.dts @@ -1,5 +1,6 @@ /* * Copyright (c) 2019-2020 Linaro Limited + * Copyright 2026 Arm Limited and/or its affiliates * * SPDX-License-Identifier: Apache-2.0 */ @@ -7,6 +8,7 @@ /dts-v1/; #include +#include / { compatible = "arm,v2m-musca"; @@ -19,6 +21,7 @@ zephyr,console = &uart1; zephyr,sram = &sram0; zephyr,flash = &mram0; + zephyr,code-partitions = &slot0_ns_partition; zephyr,shell-uart = &uart1; }; @@ -40,9 +43,31 @@ }; }; - mram0: mram@a080000 { + mram0: mram@a000000 { /* Internal code eMRAM */ - reg = <0x0a080000 0x80000>; + compatible = "soc-nv-flash"; + reg = <0x0a000000 DT_SIZE_M(2)>; + erase-block-size = ; + write-block-size = <1>; + #address-cells = <1>; + #size-cells = <1>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + /* Please see the memory layout in: + * https://github.com/zephyrproject-rtos/trusted-firmware-m/blob/zephyr_tf-m_v2.2.2/platform/ext/target/arm/musca_s1/partition/flash_layout.h + */ + slot0_partition: partition@20000 { + reg = <0x20000 DT_SIZE_K(384)>; + }; + + slot0_ns_partition: partition@80000 { + reg = <0x80000 DT_SIZE_K(512)>; + }; + }; }; sram0: memory@20040000 { From c30ab4e4047e0bd749461ae7724412ba7b35f905 Mon Sep 17 00:00:00 2001 From: Sudan Landge Date: Mon, 19 Jan 2026 20:34:53 +0000 Subject: [PATCH 2355/3659] boards: arm: musca_b1: disable crypto HW acceleration TF-M documentation states that code sharing on Musca-B1 is only supported with software crypto and requires crypto hardware acceleration to be disabled. So, force CRYPTO_HW_ACCELERATOR=OFF for the Musca-B1 non-secure TF-M build to match this requirement. This also fixes CI failures caused by -Werror triggered by prototype mismatches in the crypto accelerator path between TF-M and Mbed TLS. Signed-off-by: Sudan Landge --- boards/arm/v2m_musca_b1/CMakeLists.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/boards/arm/v2m_musca_b1/CMakeLists.txt b/boards/arm/v2m_musca_b1/CMakeLists.txt index 2ba52c47c83c..44358da90628 100644 --- a/boards/arm/v2m_musca_b1/CMakeLists.txt +++ b/boards/arm/v2m_musca_b1/CMakeLists.txt @@ -1,8 +1,15 @@ # # Copyright (c) 2019,2020 Linaro Limited +# Copyright 2026 Arm Limited and/or its affiliates # # SPDX-License-Identifier: Apache-2.0 # zephyr_library() zephyr_library_sources(pinmux.c) + +if(CONFIG_BUILD_WITH_TFM) + set_property(TARGET zephyr_property_target + APPEND PROPERTY TFM_CMAKE_OPTIONS -DCRYPTO_HW_ACCELERATOR=OFF + ) +endif() From 6891d57c012b6d4572db15590997ff24fa6a8b40 Mon Sep 17 00:00:00 2001 From: Sudan Landge Date: Tue, 20 Jan 2026 11:30:27 +0000 Subject: [PATCH 2356/3659] boards: arm: musca_s1: disable crypto HW acceleration Disable HW acceleration to fix CI failures caused by -Werror triggered by prototype mismatches in the crypto accelerator path between TF-M and Mbed TLS. Signed-off-by: Sudan Landge --- boards/arm/v2m_musca_s1/CMakeLists.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/boards/arm/v2m_musca_s1/CMakeLists.txt b/boards/arm/v2m_musca_s1/CMakeLists.txt index bbb12938dcee..15313d539ab3 100644 --- a/boards/arm/v2m_musca_s1/CMakeLists.txt +++ b/boards/arm/v2m_musca_s1/CMakeLists.txt @@ -1,8 +1,15 @@ # # Copyright (c) 2019-2020 Linaro Limited +# Copyright 2026 Arm Limited and/or its affiliates # # SPDX-License-Identifier: Apache-2.0 # zephyr_library() zephyr_library_sources(pinmux.c) + +if(CONFIG_BUILD_WITH_TFM) + set_property(TARGET zephyr_property_target + APPEND PROPERTY TFM_CMAKE_OPTIONS -DCRYPTO_HW_ACCELERATOR=OFF + ) +endif() From 2a1b814f7bfa5fb13a4f2e246027c1cff2db3938 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Mon, 19 Jan 2026 12:33:23 +0100 Subject: [PATCH 2357/3659] net: dns: Don't report CNAME records via callback Don't report CNAME records via application callback (as it used to be done). They don't carry any data in the info struct and are only used internally to redirect DNS queries. Signed-off-by: Robert Lubos --- subsys/net/lib/dns/resolve.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/subsys/net/lib/dns/resolve.c b/subsys/net/lib/dns/resolve.c index 408a694a5ef8..f5c469d883bd 100644 --- a/subsys/net/lib/dns/resolve.c +++ b/subsys/net/lib/dns/resolve.c @@ -1395,6 +1395,14 @@ int dns_validate_msg(struct dns_resolve_context *ctx, goto quit; } + + if (answer_type == DNS_RR_TYPE_CNAME) { + /* Don't report CNAME records to the application, they're used internally + * for query redirection. + */ + continue; + } + invoke_query_callback(DNS_EAI_INPROGRESS, &info, &ctx->queries[*query_idx]); if (dns_msg->response_type == DNS_RESPONSE_IP || From 38d9c632d691616a138e1426217874333b333e6c Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Mon, 19 Jan 2026 14:07:40 +0100 Subject: [PATCH 2358/3659] net: dns: Fix query redirection in case of CNAME result In case CNAME record is received with no IP addresses, DNS resolver will attempt to re-send the query for the name indicated by the CNAME record. The logic for scheduling the new query was inconsistent though: dispatcher_cb() assumes that it'll reuse the query context with the same query id, while dns_read() cancelled the query, which shouldn't really happen, as that would cause an error to be reported to the application via callback. Fix that by skipping the query cancel in case of DNS_EAI_AGAIN result. The query context will be properly reused then, and freed either when reply for another query arrives, or the query times out. Signed-off-by: Robert Lubos --- subsys/net/lib/dns/resolve.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/subsys/net/lib/dns/resolve.c b/subsys/net/lib/dns/resolve.c index f5c469d883bd..0e1d04dd5733 100644 --- a/subsys/net/lib/dns/resolve.c +++ b/subsys/net/lib/dns/resolve.c @@ -1490,12 +1490,12 @@ static int dns_read(struct dns_resolve_context *ctx, ret = dns_validate_msg(ctx, &dns_msg, dns_id, &query_idx, dns_cname, query_hash); if (ret == DNS_EAI_AGAIN) { - goto finished; + return ret; } if ((ret < 0 && ret != DNS_EAI_ALLDONE) || query_idx < 0 || query_idx > CONFIG_DNS_NUM_CONCUR_QUERIES) { - goto quit; + return ret; } #if defined(CONFIG_DNS_RESOLVER_PACKET_FORWARDING) @@ -1518,13 +1518,6 @@ static int dns_read(struct dns_resolve_context *ctx, } return 0; - -finished: - dns_resolve_cancel_with_name(ctx, *dns_id, - ctx->queries[query_idx].query, - ctx->queries[query_idx].query_type); -quit: - return ret; } static int set_ttl_hop_limit(int sock, int level, int option, int new_limit) From fbd9079148975b0f45170611c4cbf10e4bacaadd Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Mon, 19 Jan 2026 14:50:15 +0100 Subject: [PATCH 2359/3659] net: dns: Implement CONFIG_DNS_RESOLVER_ADDITIONAL_QUERIES There was a Kconfig option defined to limit the number of additional DNS queries sent for aliases received in CNAME records (to avoid potential query loops), however it was not implemented. This commit implements the feature - the resolver will now only send up to CONFIG_DNS_RESOLVER_ADDITIONAL_QUERIES follow-up queries after receiving CNAME record with an alias w/o any IP addresses. Signed-off-by: Robert Lubos --- include/zephyr/net/dns_resolve.h | 5 +++++ subsys/net/lib/dns/resolve.c | 8 ++++++++ 2 files changed, 13 insertions(+) diff --git a/include/zephyr/net/dns_resolve.h b/include/zephyr/net/dns_resolve.h index eeaa1adf2db8..9af09951dfbf 100644 --- a/include/zephyr/net/dns_resolve.h +++ b/include/zephyr/net/dns_resolve.h @@ -530,6 +530,11 @@ struct dns_resolve_context { */ uint16_t query_hash; + /* Number of additional queries sent to resolve CNAME record + * name aliases. + */ + uint8_t additional_queries; + /** Flag to indicate that the callback has been called at least once. */ bool cb_called; } queries[DNS_NUM_CONCUR_QUERIES]; diff --git a/subsys/net/lib/dns/resolve.c b/subsys/net/lib/dns/resolve.c index 0e1d04dd5733..a8a853b78213 100644 --- a/subsys/net/lib/dns/resolve.c +++ b/subsys/net/lib/dns/resolve.c @@ -318,6 +318,11 @@ static int dispatcher_cb(struct dns_socket_dispatcher *my_ctx, int sock, goto free_buf; } + if (ctx->queries[i].additional_queries >= CONFIG_DNS_RESOLVER_ADDITIONAL_QUERIES) { + ret = DNS_EAI_FAIL; + goto quit; + } + for (j = 0; j < SERVER_COUNT; j++) { if (ctx->servers[j].sock < 0) { continue; @@ -332,6 +337,8 @@ static int dispatcher_cb(struct dns_socket_dispatcher *my_ctx, int sock, } } + ctx->queries[i].additional_queries++; + if (nfail > 0) { NET_DBG("DNS cname query %d fails on %d attempts", nfail, ntry); @@ -2041,6 +2048,7 @@ int dns_resolve_name_internal(struct dns_resolve_context *ctx, ctx->queries[i].user_data = user_data; ctx->queries[i].ctx = ctx; ctx->queries[i].query_hash = 0; + ctx->queries[i].additional_queries = 0; ctx->queries[i].cb_called = false; k_work_init_delayable(&ctx->queries[i].timer, query_timeout); From a10f7f3541749bd036bd411626892c2026d0751c Mon Sep 17 00:00:00 2001 From: Jeroen Broersen Date: Fri, 16 Jan 2026 11:27:23 +0100 Subject: [PATCH 2360/3659] net: lwm2m: senml opaque base64 encoding fix The SenML-JSON specification mentions base64-encoded data with the URL-safe alphabet and padding omitted. For sending data, zephyr used normal base64 with padding. Change the base64 data to use the URL-safe format without padding when sending opaque data via SenML-JSON. Fixes #102390 Signed-off-by: Jeroen Broersen --- subsys/net/lib/lwm2m/lwm2m_rw_senml_json.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/subsys/net/lib/lwm2m/lwm2m_rw_senml_json.c b/subsys/net/lib/lwm2m/lwm2m_rw_senml_json.c index 534563f0aab1..7b2a07d73f53 100644 --- a/subsys/net/lib/lwm2m/lwm2m_rw_senml_json.c +++ b/subsys/net/lib/lwm2m/lwm2m_rw_senml_json.c @@ -905,8 +905,28 @@ static int json_append_bytes_base64(const char *bytes, size_t len, void *data) /* No space available for base64 data */ return -ENOMEM; } + + /* Change base64 data to URL-safe BASE64 data without padding */ + int padding_removed = 0; + + for (int i = 0; i < temp_length; i++) { + switch (CPKT_BUF_W_PTR(out->out_cpkt)[i]) { + case '+': + CPKT_BUF_W_PTR(out->out_cpkt)[i] = '-'; + break; + case '/': + CPKT_BUF_W_PTR(out->out_cpkt)[i] = '_'; + break; + case '=': + CPKT_BUF_W_PTR(out->out_cpkt)[i] = 0; + padding_removed++; + break; + default: + break; + } + } /* Update Data offset */ - out->out_cpkt->offset += temp_length; + out->out_cpkt->offset += (temp_length - padding_removed); } else { if (buf_append(CPKT_BUF_WRITE(fd->out->out_cpkt), bytes, len) < 0) { return -ENOMEM; From 96121bfb5735b9a19e464b569c922e9fd0e173d9 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Wed, 21 Jan 2026 11:06:45 +0200 Subject: [PATCH 2361/3659] net: posix: Avoid multiple definitions of IFNAMSIZ symbol One might see this compile error depending on what order the POSIX headers are included include/zephyr/net/net_compat.h:143: error: "IFNAMSIZ" redefined .../zephyr/include/zephyr/net/net_compat.h:143: error: "IFNAMSIZ" redefined [-Werror] 143 | #define IFNAMSIZ NET_IFNAMSIZ | In file included from ... .../zephyr/include/zephyr/posix/net/if.h:16: note: this is the location of the previous definition 16 | #define IFNAMSIZ IF_NAMESIZE | Signed-off-by: Jukka Rissanen --- include/zephyr/net/net_compat.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/zephyr/net/net_compat.h b/include/zephyr/net/net_compat.h index c044d86cfa87..927c8d5087e9 100644 --- a/include/zephyr/net/net_compat.h +++ b/include/zephyr/net/net_compat.h @@ -140,7 +140,9 @@ extern "C" { #define IN6ADDR_ANY_INIT NET_IN6ADDR_ANY_INIT #define IN6ADDR_LOOPBACK_INIT NET_IN6ADDR_LOOPBACK_INIT +#if !defined(IFNAMSIZ) #define IFNAMSIZ NET_IFNAMSIZ +#endif /* IFNAMSIZ */ #define in_pktinfo net_in_pktinfo #define ip_mreqn net_ip_mreqn From 2de323cd3eb7490ee1d571b0747cb59a62519f79 Mon Sep 17 00:00:00 2001 From: Tahsin Mutlugun Date: Wed, 21 Jan 2026 12:27:36 +0300 Subject: [PATCH 2362/3659] testsuite: Correct broken link to coverage documentation The existing documentation link pointed to a non-existent page. Update the link to use the current documentation URL. Signed-off-by: Tahsin Mutlugun --- subsys/testsuite/Kconfig.coverage | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/testsuite/Kconfig.coverage b/subsys/testsuite/Kconfig.coverage index 9209052b7905..3f7cd2c0b0de 100644 --- a/subsys/testsuite/Kconfig.coverage +++ b/subsys/testsuite/Kconfig.coverage @@ -17,7 +17,7 @@ config COVERAGE This option will build your application with the -coverage option which will generate data that can be used to create coverage reports. For more information see - https://docs.zephyrproject.org/latest/guides/coverage.html + https://docs.zephyrproject.org/latest/develop/test/coverage.html choice prompt "Coverage mode" From ff78913fa86419fb53bf30e98cbed98b8fa884ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Mon, 19 Jan 2026 18:14:17 +0100 Subject: [PATCH 2363/3659] arch: arm: smp: Master core should be referred to as "primary" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As per Zephyr guidelines re: inclusive language, the term "master" is replaced with "primary". Signed-off-by: Benjamin Cabé --- arch/arm/core/cortex_a_r/smp.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/arm/core/cortex_a_r/smp.c b/arch/arm/core/cortex_a_r/smp.c index 099d28fd6a2d..fd8790e337b2 100644 --- a/arch/arm/core/cortex_a_r/smp.c +++ b/arch/arm/core/cortex_a_r/smp.c @@ -98,18 +98,18 @@ void arch_cpu_start(int cpu_num, k_thread_stack_t *stack, int sz, arch_cpustart_ { int cpu_count, i, j; uint32_t cpu_mpid = 0; - uint32_t master_core_mpid; + uint32_t primary_core_mpid; - /* Now it is on master core */ + /* Now it is on primary core */ __ASSERT(arch_curr_cpu()->id == 0, ""); - master_core_mpid = MPIDR_TO_CORE(GET_MPIDR()); + primary_core_mpid = MPIDR_TO_CORE(GET_MPIDR()); cpu_count = ARRAY_SIZE(cpu_node_list); __ASSERT(cpu_count == CONFIG_MP_MAX_NUM_CPUS, "The count of CPU Cores nodes in dts is not equal to CONFIG_MP_MAX_NUM_CPUS\n"); for (i = 0, j = 0; i < cpu_count; i++) { - if (cpu_node_list[i] == master_core_mpid) { + if (cpu_node_list[i] == primary_core_mpid) { continue; } if (j == cpu_num - 1) { From f64bb4bf1e021d20f9b57e66719fde46764e22c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Mon, 19 Jan 2026 18:02:37 +0100 Subject: [PATCH 2364/3659] arch: riscv: avoid the use of "sanity check" term MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As per coding guidelines, "sanity check" must be avoided. Signed-off-by: Benjamin Cabé --- arch/riscv/core/pmp.c | 2 +- arch/riscv/custom/andes/pma.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/riscv/core/pmp.c b/arch/riscv/core/pmp.c index 5e20970b0a55..348c607cbb09 100644 --- a/arch/riscv/core/pmp.c +++ b/arch/riscv/core/pmp.c @@ -318,7 +318,7 @@ extern void z_riscv_write_pmp_entries(unsigned int start, unsigned int end, /** * @brief Write a range of PMP entries to corresponding PMP registers * - * This performs some sanity checks before calling z_riscv_write_pmp_entries(). + * This performs some coherence checks before calling z_riscv_write_pmp_entries(). * * @param start Start of the PMP range to be written * @param end End (exclusive) of the PMP range to be written diff --git a/arch/riscv/custom/andes/pma.c b/arch/riscv/custom/andes/pma.c index 1e9d41c4f54f..11f2a46d02ec 100644 --- a/arch/riscv/custom/andes/pma.c +++ b/arch/riscv/custom/andes/pma.c @@ -141,7 +141,7 @@ static void region_init(const uint32_t index, } /* - * This internal function performs run-time sanity check for + * This internal function performs run-time coherence check for * PMA region start address and size. */ static int pma_region_is_valid(const struct pma_region *region) From 5a9715add1ef6e9d2c1ccbb9f35cc0f57e12926a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Mon, 19 Jan 2026 18:02:58 +0100 Subject: [PATCH 2365/3659] arch: x86: avoid the use of "sanity check" term MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As per coding guidelines, "sanity check" must be avoided. Signed-off-by: Benjamin Cabé --- arch/x86/gen_idt.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/gen_idt.py b/arch/x86/gen_idt.py index a302c13bff55..f424f4eb9330 100755 --- a/arch/x86/gen_idt.py +++ b/arch/x86/gen_idt.py @@ -136,7 +136,7 @@ def setup_idt(spur_code, spur_nocode, intlist, max_vec, max_irq): irq_vec_map = [0 for i in range(max_irq)] vectors = [None for i in range(max_vec)] - # Pass 1: sanity check and set up hard-coded interrupt vectors + # Pass 1: coherence check and set up hard-coded interrupt vectors for handler, irq, prio, vec, dpl, tss in intlist: if vec == -1: if prio == -1: From 71262d0e075bb6670b81534c820b68e7c6cc3c55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Mon, 19 Jan 2026 18:02:09 +0100 Subject: [PATCH 2366/3659] arch: xtensa: avoid the use of "sanity check" term MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As per coding guidelines, "sanity check" must be avoided. Signed-off-by: Benjamin Cabé --- arch/xtensa/core/xtensa_asm2_util.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/xtensa/core/xtensa_asm2_util.S b/arch/xtensa/core/xtensa_asm2_util.S index 00e7b1bcd3fd..377edcd590ab 100644 --- a/arch/xtensa/core/xtensa_asm2_util.S +++ b/arch/xtensa/core/xtensa_asm2_util.S @@ -344,7 +344,7 @@ noflush: /* Switch stack pointer and restore. The jump to * _restore_context does not return as such, but we arrange * for the restored "next" address to be immediately after for - * sanity. + * coherence. */ l32i a1, a2, ___xtensa_irq_bsa_t_a2_OFFSET From 27120315d3df4ad8add9a950c0cab315f59505e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Mon, 19 Jan 2026 18:01:35 +0100 Subject: [PATCH 2367/3659] arch: arm: avoid the use of "sanity check" term MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As per coding guidelines, "sanity check" must be avoided. Signed-off-by: Benjamin Cabé --- arch/arm/core/mpu/arm_mpu.c | 10 +++++----- arch/arm/core/mpu/arm_mpu_v7_internal.h | 6 +++--- arch/arm/core/mpu/arm_mpu_v8_internal.h | 14 +++++++------- arch/arm/core/mpu/nxp_mpu.c | 12 ++++++------ 4 files changed, 21 insertions(+), 21 deletions(-) diff --git a/arch/arm/core/mpu/arm_mpu.c b/arch/arm/core/mpu/arm_mpu.c index 602e56010bff..a72fea183e3d 100644 --- a/arch/arm/core/mpu/arm_mpu.c +++ b/arch/arm/core/mpu/arm_mpu.c @@ -210,11 +210,11 @@ static int mpu_configure_region(const uint8_t index, !defined(CONFIG_MPU_GAP_FILLING) /* This internal function programs a set of given MPU regions * over a background memory area, optionally performing a - * sanity check of the memory regions to be programmed. + * coherence check of the memory regions to be programmed. */ static int mpu_configure_regions(const struct z_arm_mpu_partition regions[], uint8_t regions_num, uint8_t start_reg_index, - bool do_sanity_check) + bool do_coherence_check) { int i; int reg_index = start_reg_index; @@ -225,9 +225,9 @@ static int mpu_configure_regions(const struct z_arm_mpu_partition } /* Non-empty region. */ - if (do_sanity_check && + if (do_coherence_check && (!mpu_partition_is_valid(®ions[i]))) { - LOG_ERR("Partition %u: sanity check failed.", i); + LOG_ERR("Partition %u: coherence check failed.", i); return -EINVAL; } @@ -620,7 +620,7 @@ int z_arm_mpu_init(void) #endif #endif /* CONFIG_NULL_POINTER_EXCEPTION_DETECTION_MPU */ - /* Sanity check for number of regions in Cortex-M0+, M3, and M4. */ + /* Coherence check for number of regions in Cortex-M0+, M3, and M4. */ #if defined(CONFIG_CPU_CORTEX_M0PLUS) || \ defined(CONFIG_CPU_CORTEX_M3) || \ defined(CONFIG_CPU_CORTEX_M4) diff --git a/arch/arm/core/mpu/arm_mpu_v7_internal.h b/arch/arm/core/mpu/arm_mpu_v7_internal.h index 40d03865d07c..17cf2cb38e62 100644 --- a/arch/arm/core/mpu/arm_mpu_v7_internal.h +++ b/arch/arm/core/mpu/arm_mpu_v7_internal.h @@ -52,9 +52,9 @@ static void region_init(const uint32_t index, #endif } -/* @brief Partition sanity check +/* @brief Partition coherence check * - * This internal function performs run-time sanity check for + * This internal function performs run-time coherence check for * MPU region start address and size. * * @param part Pointer to the data structure holding the partition @@ -207,7 +207,7 @@ static int mpu_configure_region(const uint8_t index, static int mpu_configure_regions(const struct z_arm_mpu_partition regions[], uint8_t regions_num, uint8_t start_reg_index, - bool do_sanity_check); + bool do_coherence_check); /* This internal function programs the static MPU regions. * diff --git a/arch/arm/core/mpu/arm_mpu_v8_internal.h b/arch/arm/core/mpu/arm_mpu_v8_internal.h index 2ce810047e1d..995263db2990 100644 --- a/arch/arm/core/mpu/arm_mpu_v8_internal.h +++ b/arch/arm/core/mpu/arm_mpu_v8_internal.h @@ -184,9 +184,9 @@ static void region_init(const uint32_t index, region_conf->attr.mair_idx, region_conf->attr.r_limit); } -/* @brief Partition sanity check +/* @brief Partition coherence check * - * This internal function performs run-time sanity check for + * This internal function performs run-time coherence check for * MPU region start address and size. * * @param part Pointer to the data structure holding the partition @@ -519,19 +519,19 @@ static int mpu_configure_region(const uint8_t index, #if !defined(CONFIG_MPU_GAP_FILLING) static int mpu_configure_regions(const struct z_arm_mpu_partition regions[], uint8_t regions_num, uint8_t start_reg_index, - bool do_sanity_check); + bool do_coherence_check); #endif /* This internal function programs a set of given MPU regions * over a background memory area, optionally performing a - * sanity check of the memory regions to be programmed. + * coherence check of the memory regions to be programmed. * * The function performs a full partition of the background memory * area, effectively, leaving no space in this area uncovered by MPU. */ static int mpu_configure_regions_and_partition(const struct z_arm_mpu_partition regions[], uint8_t regions_num, uint8_t start_reg_index, - bool do_sanity_check) + bool do_coherence_check) { int i; int reg_index = start_reg_index; @@ -542,9 +542,9 @@ static int mpu_configure_regions_and_partition(const struct z_arm_mpu_partition } /* Non-empty region. */ - if (do_sanity_check && + if (do_coherence_check && (!mpu_partition_is_valid(®ions[i]))) { - LOG_ERR("Partition %u: sanity check failed.", i); + LOG_ERR("Partition %u: coherence check failed.", i); return -EINVAL; } diff --git a/arch/arm/core/mpu/nxp_mpu.c b/arch/arm/core/mpu/nxp_mpu.c index ae893086901c..639a6f86b646 100644 --- a/arch/arm/core/mpu/nxp_mpu.c +++ b/arch/arm/core/mpu/nxp_mpu.c @@ -51,9 +51,9 @@ static inline uint8_t get_num_regions(void) return FSL_FEATURE_SYSMPU_DESCRIPTOR_COUNT; } -/* @brief Partition sanity check +/* @brief Partition coherence check * - * This internal function performs run-time sanity check for + * This internal function performs run-time coherence check for * MPU region start address and size. * * @param part Pointer to the data structure holding the partition @@ -297,11 +297,11 @@ static int mpu_sram_partitioning(uint8_t index, /* This internal function programs a set of given MPU regions * over a background memory area, optionally performing a - * sanity check of the memory regions to be programmed. + * coherence check of the memory regions to be programmed. */ static int mpu_configure_regions(const struct z_arm_mpu_partition regions[], uint8_t regions_num, uint8_t start_reg_index, - bool do_sanity_check) + bool do_coherence_check) { int i; int reg_index = start_reg_index; @@ -312,9 +312,9 @@ static int mpu_configure_regions(const struct z_arm_mpu_partition regions[], } /* Non-empty region. */ - if (do_sanity_check && + if (do_coherence_check && (!mpu_partition_is_valid(®ions[i]))) { - LOG_ERR("Partition %u: sanity check failed.", i); + LOG_ERR("Partition %u: coherence check failed.", i); return -EINVAL; } From 18652dea69fbd19894e438250a58bd1fd3a12075 Mon Sep 17 00:00:00 2001 From: Camille BAUD Date: Sun, 18 Jan 2026 13:28:10 +0100 Subject: [PATCH 2368/3659] drivers: serial: bflb: do not enable rx and err interrupt by default It breaks things when callback doesnt expect them. Signed-off-by: Camille BAUD --- drivers/serial/uart_bflb.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/serial/uart_bflb.c b/drivers/serial/uart_bflb.c index dae92b91f719..9625a86371c6 100644 --- a/drivers/serial/uart_bflb.c +++ b/drivers/serial/uart_bflb.c @@ -274,14 +274,19 @@ static void uart_bflb_isr(const struct device *dev) { struct bflb_data *const data = dev->data; const struct bflb_config *const cfg = dev->config; - uint32_t tmp = 0; + uint32_t tmp; + bool clear_err = !(sys_read32(cfg->base_reg + UART_INT_MASK_OFFSET) & UART_CR_URX_PCE_MASK); if (data->user_cb) { data->user_cb(dev, data->user_data); } /* clear interrupts that require ack*/ tmp = sys_read32(cfg->base_reg + UART_INT_CLEAR_OFFSET); - tmp = tmp | UART_CR_URX_RTO_CLR; + /* Clear PCE in case callback didn't read it and the interrupt is unmasked */ + if (clear_err) { + tmp |= UART_CR_URX_PCE_CLR; + } + tmp |= UART_CR_URX_RTO_CLR; sys_write32(tmp, cfg->base_reg + UART_INT_CLEAR_OFFSET); } #endif /* CONFIG_UART_INTERRUPT_DRIVEN */ @@ -443,9 +448,6 @@ static int uart_bflb_init(const struct device *dev) sys_write32(0xFF, cfg->base_reg + UART_INT_CLEAR_OFFSET); /* mask all IRQs */ sys_write32(0xFFFFFFFFU, cfg->base_reg + UART_INT_MASK_OFFSET); - /* unmask necessary irqs */ - uart_bflb_irq_rx_enable(dev); - uart_bflb_irq_err_enable(dev); /* enable all irqs */ sys_write32(0xFF, cfg->base_reg + UART_INT_EN_OFFSET); cfg->irq_config_func(dev); From f54a3fa8cdb788ae54d193e466b0c44d03d96e3e Mon Sep 17 00:00:00 2001 From: Sven Ginka Date: Wed, 14 Jan 2026 14:29:35 +0100 Subject: [PATCH 2369/3659] dts: bindings: fix filename typo in sy1xx-i2c.yaml this fixes the incorrect filename of the sy1xx-i2c.yml file. Signed-off-by: Sven Ginka --- .../i2c/{sensry,sy1xxx-i2c.yaml => sensry,sy1xx-i2c.yaml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename dts/bindings/i2c/{sensry,sy1xxx-i2c.yaml => sensry,sy1xx-i2c.yaml} (100%) diff --git a/dts/bindings/i2c/sensry,sy1xxx-i2c.yaml b/dts/bindings/i2c/sensry,sy1xx-i2c.yaml similarity index 100% rename from dts/bindings/i2c/sensry,sy1xxx-i2c.yaml rename to dts/bindings/i2c/sensry,sy1xx-i2c.yaml From 384abc74897edd1f6fa09b5afcff83514eae9b33 Mon Sep 17 00:00:00 2001 From: Camille BAUD Date: Mon, 12 Jan 2026 18:09:55 +0100 Subject: [PATCH 2370/3659] drivers: display: Introduce SSD1325, update driver Adds SSD1325 support to SSD1327 driver, update and improve driver. Signed-off-by: Camille BAUD --- drivers/display/CMakeLists.txt | 2 +- drivers/display/Kconfig | 2 +- drivers/display/Kconfig.ssd1327 | 29 - drivers/display/Kconfig.ssd1327_5 | 44 ++ drivers/display/display_ssd1327_5.c | 685 ++++++++++++++++++ drivers/display/ssd1327.c | 536 -------------- drivers/display/ssd1327_regs.h | 53 -- dts/bindings/display/solomon,ssd1325-i2c.yaml | 12 + .../display/solomon,ssd1325-mipi.yaml | 12 + .../display/solomon,ssd1327-common.yaml | 16 + ...27fb-i2c.yaml => solomon,ssd1327-i2c.yaml} | 6 +- ...fb-mipi.yaml => solomon,ssd1327-mipi.yaml} | 6 +- ...mon.yaml => solomon,ssd1327_5-common.yaml} | 26 +- 13 files changed, 786 insertions(+), 643 deletions(-) delete mode 100644 drivers/display/Kconfig.ssd1327 create mode 100644 drivers/display/Kconfig.ssd1327_5 create mode 100644 drivers/display/display_ssd1327_5.c delete mode 100644 drivers/display/ssd1327.c delete mode 100644 drivers/display/ssd1327_regs.h create mode 100644 dts/bindings/display/solomon,ssd1325-i2c.yaml create mode 100644 dts/bindings/display/solomon,ssd1325-mipi.yaml create mode 100644 dts/bindings/display/solomon,ssd1327-common.yaml rename dts/bindings/display/{solomon,ssd1327fb-i2c.yaml => solomon,ssd1327-i2c.yaml} (58%) rename dts/bindings/display/{solomon,ssd1327fb-mipi.yaml => solomon,ssd1327-mipi.yaml} (58%) rename dts/bindings/display/{solomon,ssd1327fb-common.yaml => solomon,ssd1327_5-common.yaml} (75%) diff --git a/drivers/display/CMakeLists.txt b/drivers/display/CMakeLists.txt index 8f076e974fb8..135e0929dd5c 100644 --- a/drivers/display/CMakeLists.txt +++ b/drivers/display/CMakeLists.txt @@ -42,7 +42,7 @@ zephyr_library_sources_ifdef(CONFIG_SH1122 display_sh1122.c) zephyr_library_sources_ifdef(CONFIG_SSD1306 ssd1306.c) zephyr_library_sources_ifdef(CONFIG_SSD1320 display_ssd1320.c) zephyr_library_sources_ifdef(CONFIG_SSD1322 ssd1322.c) -zephyr_library_sources_ifdef(CONFIG_SSD1327 ssd1327.c) +zephyr_library_sources_ifdef(CONFIG_SSD1327_5 display_ssd1327_5.c) zephyr_library_sources_ifdef(CONFIG_SSD1331 display_ssd1331.c) zephyr_library_sources_ifdef(CONFIG_SSD135X display_ssd135x.c) zephyr_library_sources_ifdef(CONFIG_SSD1363 display_ssd1363.c) diff --git a/drivers/display/Kconfig b/drivers/display/Kconfig index e7f4f30a866f..b094da33800d 100644 --- a/drivers/display/Kconfig +++ b/drivers/display/Kconfig @@ -51,7 +51,7 @@ source "drivers/display/Kconfig.sh1122" source "drivers/display/Kconfig.ssd1306" source "drivers/display/Kconfig.ssd1320" source "drivers/display/Kconfig.ssd1322" -source "drivers/display/Kconfig.ssd1327" +source "drivers/display/Kconfig.ssd1327_5" source "drivers/display/Kconfig.ssd1331" source "drivers/display/Kconfig.ssd135x" source "drivers/display/Kconfig.ssd1363" diff --git a/drivers/display/Kconfig.ssd1327 b/drivers/display/Kconfig.ssd1327 deleted file mode 100644 index f109d169ecea..000000000000 --- a/drivers/display/Kconfig.ssd1327 +++ /dev/null @@ -1,29 +0,0 @@ -# SSD1327 display controller configuration options - -# Copyright (c) 2024 Savoir-faire Linux -# SPDX-License-Identifier: Apache-2.0 - -menuconfig SSD1327 - bool "SSD1327 display controller driver" - default y - depends on DT_HAS_SOLOMON_SSD1327FB_ENABLED - select I2C if $(dt_compat_on_bus,$(DT_COMPAT_SOLOMON_SSD1327FB),i2c) - select MIPI_DBI if $(dt_compat_on_bus,$(DT_COMPAT_SOLOMON_SSD1327FB),mipi-dbi) - help - Enable driver for SSD1327 display. - -if SSD1327 - -config SSD1327_DEFAULT_CONTRAST - int "SSD1327 default contrast" - default 128 - range 0 255 - help - SSD1327 default contrast. - -config SSD1327_CONV_BUFFER_LINES - int "How many lines can the conversion buffer hold" - default 1 - range 1 128 - -endif # SSD1327 diff --git a/drivers/display/Kconfig.ssd1327_5 b/drivers/display/Kconfig.ssd1327_5 new file mode 100644 index 000000000000..eed8a95fe094 --- /dev/null +++ b/drivers/display/Kconfig.ssd1327_5 @@ -0,0 +1,44 @@ +# SSD1327 and SSD1325 display controller configuration options + +# Copyright (c) 2024 Savoir-faire Linux +# Copyright (c) 2025-2026 MASSDRIVER EI (massdriver.space) +# SPDX-License-Identifier: Apache-2.0 + +menuconfig SSD1327_5 + bool "SSD1327/5 display controller driver" + default y + depends on DT_HAS_SOLOMON_SSD1327_ENABLED || DT_HAS_SOLOMON_SSD1325_ENABLED + select I2C if $(dt_compat_on_bus,$(DT_COMPAT_SOLOMON_SSD1327),i2c) \ + || $(dt_compat_on_bus,$(DT_COMPAT_SOLOMON_SSD1325),i2c) + select MIPI_DBI if $(dt_compat_on_bus,$(DT_COMPAT_SOLOMON_SSD1327),mipi-dbi) \ + || $(dt_compat_on_bus,$(DT_COMPAT_SOLOMON_SSD1325),mipi-dbi) + help + Enable driver for SSD1327 and SSD1325 display controllers. + +if SSD1327_5 + +config SSD1327_DEFAULT_CONTRAST + int "SSD1327 default contrast" + default 128 + range 0 255 + help + SSD1327 default contrast. + +config SSD1327_CONV_BUFFER_LINES + int "How many lines can the conversion buffer hold" + default 1 + range 1 128 + +config SSD1325_DEFAULT_CONTRAST + int "SSD1325 default contrast" + default 128 + range 0 255 + help + SSD1325 default contrast. + +config SSD1325_CONV_BUFFER_LINES + int "How many lines can the conversion buffer hold" + default 1 + range 1 128 + +endif # SSD1327_5 diff --git a/drivers/display/display_ssd1327_5.c b/drivers/display/display_ssd1327_5.c new file mode 100644 index 000000000000..07f55a80a900 --- /dev/null +++ b/drivers/display/display_ssd1327_5.c @@ -0,0 +1,685 @@ +/* + * Copyright (c) 2024 Savoir-faire Linux + * Copyright (c) 2025-2026 MASSDRIVER EI (massdriver.space) + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +LOG_MODULE_REGISTER(ssd1327_5, CONFIG_DISPLAY_LOG_LEVEL); + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Commands + */ +#define SSD1327_5_SET_COLUMN_ADDR 0x15 +#define SSD1327_5_SET_ROW_ADDR 0x75 +#define SSD1327_5_SET_CONTRAST_CTRL 0x81 +#define SSD1325_SET_CURRENT_RANGE_QRT 0x84 +#define SSD1325_SET_CURRENT_RANGE_HLF 0x85 +#define SSD1325_SET_CURRENT_RANGE_FLL 0x86 +#define SSD1327_5_SET_REMAPCTL 0xa0 +#define SSD1327_5_SET_DISPLAY_START_LINE 0xa1 +#define SSD1327_5_SET_DISPLAY_OFFSET 0xa2 +#define SSD1327_5_SET_NORMAL_DISPLAY 0xa4 +#define SSD1327_5_SET_ENTIRE_DISPLAY_ON 0xa5 +#define SSD1327_5_SET_ENTIRE_DISPLAY_OFF 0xa6 +#define SSD1327_5_SET_REVERSE_DISPLAY 0xa7 +#define SSD1327_5_SET_MULTIPLEX_RATIO 0xa8 +#define SSD1327_SET_FUNCTION_A 0xab +#define SSD1325_SET_MASTER_CONFIG 0xad +#define SSD1327_5_SET_DISPLAY_OFF 0xae +#define SSD1327_5_SET_DISPLAY_ON 0xaf +#define SSD1325_SET_PRECHARGE_COMP_EN 0xb0 +#define SSD1327_5_SET_PHASE_LENGTH 0xb1 +#define SSD1325_SET_ROW_PERIOD 0xb2 +#define SSD1327_5_SET_OSC_FREQ 0xb3 +#define SSD1325_SET_PRECHARGE_COMP 0xb4 +#define SSD1327_SET_PRECHARGE_PERIOD 0xb6 +#define SSD1327_5_SET_LUT 0xb8 +#define SSD1327_SET_LINEAR_LUT 0xb9 +#define SSD1327_5_SET_PRECHARGE_VOLTAGE 0xbc +#define SSD1327_5_SET_VCOMH 0xbe +#define SSD1327_SET_FUNCTION_B 0xd5 +#define SSD1327_SET_COMMAND_LOCK 0xfd + +/* + * Constants + */ +#define SSD1327_LUT_COUNT 15 +#define SSD1325_LUT_COUNT 8 +#define SSD1327_5_LUT_COUNT SSD1327_LUT_COUNT +#define SSD1327_5_RESET_DELAY 10 +#define SSD1325_PRECHARGE_COMP_EN 0x28 +#define SSD1325_PRECHARGE_COMP_DIS 0x08 +#define SSD1325_ROW_PERIOD_MAX 158 +#define SSD1325_PRECHARGE_COMP_DEFAULT 0x03 +#define SSD1327_5_I2C_ALL_BYTES_CMD 0x0 +#define SSD1327_5_I2C_ALL_BYTES_DATA 0x40 +#define SSD1327_ENABLE_VDD 0x01 +#define SSD1327_UNLOCK_COMMAND 0x12 +#define SSD1327_MAXIMUM_CMD_LENGTH 16 +#define SSD1325_MAXIMUM_CMD_LENGTH 9 +/* Always 0x2, MUST be set to 0x2 via command */ +#define SSD1325_MASTER_CONFIG 0x2 + +/* + * Fields + */ +#define SSD1327_5_PHASE1_LENGTH_MSK 0xf +#define SSD1327_5_PHASE2_LENGTH_MSK 0xf0 +#define SSD1327_5_PHASE2_LENGTH_POS 0x4 + +typedef int (*ssd1327_5_write_bus_cmd_fn)(const struct device *dev, const uint8_t cmd, + const uint8_t *data, size_t len); +typedef int (*ssd1327_5_write_pixels_fn)(const struct device *dev, const uint8_t *buf, + uint32_t pixel_count, + const struct display_buffer_descriptor *desc); + +/* Generate SSD1325's LUT table command input from driver's LUT table storage */ +#define SSD1325_CONV_GS_TABLE(t) \ + { t[0] & 0x7, (t[1] & 0x7) | ((t[2] & 0x7) << 4), (t[3] & 0x7) | ((t[4] & 0x7) << 4), \ + (t[5] & 0x7) | ((t[6] & 0x7) << 4), (t[7] & 0x7) | ((t[8] & 0x7) << 4), \ + (t[9] & 0x7) | ((t[10] & 0x7) << 4), (t[11] & 0x7) | ((t[12] & 0x7) << 4), \ + (t[13] & 0x7) | ((t[14] & 0x7) << 4) }; + +#if DT_HAS_COMPAT_STATUS_OKAY(solomon_ssd1327) +#define SSD1327_5_MAXIMUM_CMD_LENGTH SSD1327_MAXIMUM_CMD_LENGTH +#else +#define SSD1327_5_MAXIMUM_CMD_LENGTH SSD1325_MAXIMUM_CMD_LENGTH +#endif + +/* SSD1327 grayscale levels are direct DCLK values of 5-bits width, starts at GS1 and ends at GS15. + * Table from Datasheet. + */ +static const uint8_t ssd1327_default_grayscale_table[SSD1327_5_LUT_COUNT] = { + 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28 +}; + +/* SSD1325 grayscale levels are calculated as gs = x[i] + x[i-1] + x[0:i-1], + * such as here, 0 + 1 + 2 + 2 + 2 ... gives: + * (0) 1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 + * and so GS0 is 0 DCLK and GS15 is 29 DCLK. + * It effectively is almost identical to SSD1327's after calculations. + * Table from Datasheet. + */ +static const uint8_t ssd1325_default_grayscale_table[SSD1327_5_LUT_COUNT] = { + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 +}; + +enum ssd1327_5_variant { + display_ssd1327, + display_ssd1325 +}; + +struct ssd1327_5_config { + enum ssd1327_5_variant variant; + struct i2c_dt_spec i2c; + ssd1327_5_write_bus_cmd_fn write_cmd; + ssd1327_5_write_pixels_fn write_pixels; + const struct device *mipi_dev; + const struct mipi_dbi_config dbi_config; + uint16_t height; + uint16_t width; + uint8_t oscillator_freq; + uint8_t start_line; + uint8_t display_offset; + uint8_t multiplex_ratio; + uint8_t prechargep; + uint8_t remap_value; + uint8_t phase_length; + uint8_t function_selection_b; + uint8_t precharge_voltage; + uint8_t vcomh_voltage; + uint8_t default_contrast; + const uint8_t *grayscale_table; + bool color_inversion; + uint8_t *conversion_buf; + size_t conversion_buf_size; +}; + +struct ssd1327_5_data { + uint8_t contrast; + uint8_t scan_mode; +}; + +static inline int ssd1327_5_write_bus_cmd_mipi(const struct device *dev, const uint8_t cmd, + const uint8_t *data, size_t len) +{ + const struct ssd1327_5_config *config = dev->config; + int err; + + /* Values given after the memory register must be sent with pin D/C set to 0. */ + /* Data is sent as a command following the mipi_cbi api */ + err = mipi_dbi_command_write(config->mipi_dev, &config->dbi_config, cmd, NULL, 0); + if (err) { + return err; + } + for (size_t i = 0; i < len; i++) { + err = mipi_dbi_command_write(config->mipi_dev, &config->dbi_config, + data[i], NULL, 0); + if (err) { + return err; + } + } + mipi_dbi_release(config->mipi_dev, &config->dbi_config); + + return 0; +} + +static inline int ssd1327_5_write_bus_cmd_i2c(const struct device *dev, const uint8_t cmd, + const uint8_t *data, size_t len) +{ + const struct ssd1327_5_config *config = dev->config; + uint8_t buf[SSD1327_5_MAXIMUM_CMD_LENGTH + 1]; + + if (len > SSD1327_5_MAXIMUM_CMD_LENGTH - 1) { + return -EINVAL; + } + + buf[0] = SSD1327_5_I2C_ALL_BYTES_CMD; + buf[1] = cmd; + memcpy(&(buf[2]), data, len); + + return i2c_write_dt(&config->i2c, buf, len + 2); +} + +/* Calculate SSD1325 'K' number, See section 8.3 of datasheet */ +static uint8_t ssd1325_calculate_k(const uint8_t phase_length, const uint8_t grayscale_table[15]) +{ + uint8_t k = (phase_length & SSD1327_5_PHASE1_LENGTH_MSK) + + ((phase_length & SSD1327_5_PHASE2_LENGTH_MSK) >> SSD1327_5_PHASE2_LENGTH_POS) + + grayscale_table[0]; + + for (size_t i = 1; i < 15; i++) { + k += grayscale_table[i-1] + grayscale_table[i]; + } + + return k; +} + +static inline int ssd1327_5_set_timing_setting(const struct device *dev) +{ + const struct ssd1327_5_config *config = dev->config; + const uint8_t *grayscale_table = config->grayscale_table != NULL ? + config->grayscale_table : + (config->variant == display_ssd1325 ? ssd1325_default_grayscale_table : + ssd1327_default_grayscale_table); + const uint8_t gs_table_ssd1325[SSD1325_LUT_COUNT] = SSD1325_CONV_GS_TABLE(grayscale_table); + uint8_t buf = SSD1327_UNLOCK_COMMAND; + int err; + + err = config->write_cmd(dev, SSD1327_5_SET_PHASE_LENGTH, &config->phase_length, 1); + if (err < 0) { + return err; + } + err = config->write_cmd(dev, SSD1327_5_SET_OSC_FREQ, &config->oscillator_freq, 1); + if (err < 0) { + return err; + } + if (config->variant == display_ssd1325) { + buf = ssd1325_calculate_k(config->phase_length, grayscale_table); + if (buf > SSD1325_ROW_PERIOD_MAX) { + LOG_ERR("Invalid grayscale table"); + return -EINVAL; + } + err = config->write_cmd(dev, SSD1325_SET_ROW_PERIOD, &buf, 1); + if (err < 0) { + return err; + } + err = config->write_cmd(dev, SSD1327_5_SET_LUT, + gs_table_ssd1325, SSD1325_LUT_COUNT); + if (err < 0) { + return err; + } + } else { + err = config->write_cmd(dev, SSD1327_5_SET_LUT, grayscale_table, SSD1327_LUT_COUNT); + if (err < 0) { + return err; + } + err = config->write_cmd(dev, SSD1327_SET_PRECHARGE_PERIOD, &config->prechargep, 1); + if (err < 0) { + return err; + } + } + err = config->write_cmd(dev, + SSD1327_5_SET_PRECHARGE_VOLTAGE, &config->precharge_voltage, 1); + if (err < 0) { + return err; + } + err = config->write_cmd(dev, SSD1327_5_SET_VCOMH, &config->vcomh_voltage, 1); + if (err < 0) { + return err; + } + if (config->variant == display_ssd1325) { + buf = SSD1325_PRECHARGE_COMP_DEFAULT; + err = config->write_cmd(dev, SSD1325_SET_PRECHARGE_COMP, &buf, 1); + if (err < 0) { + return err; + } + buf = SSD1325_PRECHARGE_COMP_EN; + return config->write_cmd(dev, SSD1325_SET_PRECHARGE_COMP_EN, &buf, 1); + } + err = config->write_cmd(dev, SSD1327_SET_FUNCTION_B, + &config->function_selection_b, 1); + if (err < 0) { + return err; + } + return config->write_cmd(dev, SSD1327_SET_COMMAND_LOCK, &buf, 1); +} + +static inline int ssd1327_5_set_hardware_config(const struct device *dev) +{ + const struct ssd1327_5_config *config = dev->config; + uint8_t buf; + int err; + + err = config->write_cmd(dev, SSD1327_5_SET_MULTIPLEX_RATIO, &config->multiplex_ratio, 1); + if (err < 0) { + return err; + } + err = config->write_cmd(dev, SSD1327_5_SET_DISPLAY_START_LINE, &config->start_line, 1); + if (err < 0) { + return err; + } + err = config->write_cmd(dev, SSD1327_5_SET_DISPLAY_OFFSET, &config->display_offset, 1); + if (err < 0) { + return err; + } + err = config->write_cmd(dev, SSD1327_5_SET_REMAPCTL, &config->remap_value, 1); + if (err < 0) { + return err; + } + if (config->variant == display_ssd1325) { + buf = SSD1325_MASTER_CONFIG; + err = config->write_cmd(dev, SSD1325_SET_MASTER_CONFIG, &buf, 1); + if (err < 0) { + return err; + } + return config->write_cmd(dev, SSD1325_SET_CURRENT_RANGE_FLL, NULL, 0); + } + buf = SSD1327_ENABLE_VDD; + return config->write_cmd(dev, SSD1327_SET_FUNCTION_A, &buf, 1); +} + +static int ssd1327_5_resume(const struct device *dev) +{ + const struct ssd1327_5_config *config = dev->config; + + return config->write_cmd(dev, SSD1327_5_SET_DISPLAY_ON, NULL, 0); +} + +static int ssd1327_5_suspend(const struct device *dev) +{ + const struct ssd1327_5_config *config = dev->config; + + return config->write_cmd(dev, SSD1327_5_SET_DISPLAY_OFF, NULL, 0); +} + +static int ssd1327_5_set_display(const struct device *dev) +{ + const struct ssd1327_5_config *config = dev->config; + int err; + uint8_t x_position[] = {0, config->width - 1}; + uint8_t y_position[] = {0, config->height - 1}; + + err = config->write_cmd(dev, SSD1327_5_SET_COLUMN_ADDR, x_position, sizeof(x_position)); + if (err < 0) { + return err; + } + err = config->write_cmd(dev, SSD1327_5_SET_ROW_ADDR, y_position, sizeof(y_position)); + if (err < 0) { + return err; + } + return config->write_cmd(dev, SSD1327_5_SET_REMAPCTL, &config->remap_value, 1); +} + +/* Convert what the conversion buffer can hold to pixelx (3:0) and pixelx+1 (7:4) */ +static int ssd1327_5_convert_L_8(const struct device *dev, const uint8_t *buf, int cur_offset, + uint32_t pixel_count) +{ + const struct ssd1327_5_config *config = dev->config; + int i = 0; + + for (; i / 2 < config->conversion_buf_size && pixel_count > cur_offset + i; i += 2) { + config->conversion_buf[i / 2] = buf[cur_offset + i] >> 4; + config->conversion_buf[i / 2] |= (buf[cur_offset + i + 1] >> 4) << 4; + } + return i; +} + +#if DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(solomon_ssd1327, mipi_dbi) \ + || DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(solomon_ssd1325, mipi_dbi) +static int ssd1327_5_write_pixels_mipi(const struct device *dev, const uint8_t *buf, + uint32_t pixel_count, + const struct display_buffer_descriptor *desc) +{ + const struct ssd1327_5_config *config = dev->config; + struct display_buffer_descriptor mipi_desc; + int ret, i; + int total = 0; + + mipi_desc.pitch = desc->pitch; + + while (pixel_count > total) { + i = ssd1327_5_convert_L_8(dev, buf, total, pixel_count); + + mipi_desc.buf_size = i / 2; + mipi_desc.width = mipi_desc.buf_size / desc->height; + mipi_desc.height = mipi_desc.buf_size / desc->width; + + /* This is the wrong format, but it doesn't matter to almost all mipi drivers */ + ret = mipi_dbi_write_display(config->mipi_dev, &config->dbi_config, + config->conversion_buf, &mipi_desc, PIXEL_FORMAT_L_8); + if (ret < 0) { + return ret; + } + total += i; + } + mipi_dbi_release(config->mipi_dev, &config->dbi_config); + return 0; +} +#endif + +#if DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(solomon_ssd1327, i2c) \ + || DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(solomon_ssd1325, i2c) +static int ssd1327_5_write_pixels_i2c(const struct device *dev, const uint8_t *buf, + uint32_t pixel_count, + const struct display_buffer_descriptor *desc) +{ + const struct ssd1327_5_config *config = dev->config; + int ret, i; + int total = 0; + + while (pixel_count > total) { + i = ssd1327_5_convert_L_8(dev, buf, total, pixel_count); + + ret = i2c_burst_write_dt(&config->i2c, SSD1327_5_I2C_ALL_BYTES_DATA, + config->conversion_buf, i / 2); + if (ret < 0) { + return ret; + } + total += i; + } + return 0; +} +#endif + +static int ssd1327_5_write(const struct device *dev, const uint16_t x, const uint16_t y, + const struct display_buffer_descriptor *desc, const void *buf) +{ + const struct ssd1327_5_config *config = dev->config; + int err; + size_t buf_len; + int32_t pixel_count = desc->width * desc->height; + uint8_t x_position[] = {x / 2, (x + desc->width - 1) / 2}; + uint8_t y_position[] = {y, y + desc->height - 1}; + + if (desc->pitch != desc->width) { + LOG_ERR("Pitch is not width"); + return -EINVAL; + } + + /* Following the datasheet, in the GDDRAM, two segment are split in one register */ + buf_len = MIN(desc->buf_size, desc->height * desc->width / 2); + if (buf == NULL || buf_len == 0U) { + LOG_ERR("Display buffer is not available"); + return -EINVAL; + } + + if ((x & 1) != 0U) { + LOG_ERR("Unsupported origin"); + return -EINVAL; + } + + LOG_DBG("x %u, y %u, pitch %u, width %u, height %u, buf_len %u", x, y, desc->pitch, + desc->width, desc->height, buf_len); + + err = config->write_cmd(dev, SSD1327_5_SET_COLUMN_ADDR, x_position, sizeof(x_position)); + if (err) { + return err; + } + + err = config->write_cmd(dev, SSD1327_5_SET_ROW_ADDR, y_position, sizeof(y_position)); + if (err) { + return err; + } + + return config->write_pixels(dev, buf, pixel_count, desc); +} + +static int ssd1327_5_set_contrast(const struct device *dev, const uint8_t contrast) +{ + const struct ssd1327_5_config *config = dev->config; + uint8_t constrast_cp = config->variant == display_ssd1325 ? contrast >> 1 : contrast; + + return config->write_cmd(dev, SSD1327_5_SET_CONTRAST_CTRL, &constrast_cp, 1); +} + +static void ssd1327_5_get_capabilities(const struct device *dev, struct display_capabilities *caps) +{ + const struct ssd1327_5_config *config = dev->config; + + memset(caps, 0, sizeof(struct display_capabilities)); + caps->x_resolution = config->width; + caps->y_resolution = config->height; + caps->supported_pixel_formats = PIXEL_FORMAT_L_8; + caps->current_pixel_format = PIXEL_FORMAT_L_8; + caps->screen_info = 0; +} + +static int ssd1327_5_set_pixel_format(const struct device *dev, const enum display_pixel_format pf) +{ + if (pf == PIXEL_FORMAT_L_8) { + return 0; + } + LOG_ERR("Unsupported pixel format"); + return -ENOTSUP; +} + +static int ssd1327_5_init_device(const struct device *dev) +{ + const struct ssd1327_5_config *config = dev->config; + int err; + + /* Turn display off */ + err = ssd1327_5_suspend(dev); + if (err < 0) { + return err; + } + + err = ssd1327_5_set_display(dev); + if (err < 0) { + return err; + } + + err = ssd1327_5_set_contrast(dev, config->default_contrast); + if (err < 0) { + return err; + } + + err = ssd1327_5_set_hardware_config(dev); + if (err < 0) { + return err; + } + + err = config->write_cmd(dev, + config->color_inversion ? + SSD1327_5_SET_REVERSE_DISPLAY : SSD1327_5_SET_NORMAL_DISPLAY, NULL, 0); + if (err < 0) { + return err; + } + + err = ssd1327_5_set_timing_setting(dev); + if (err < 0) { + return err; + } + + err = ssd1327_5_resume(dev); + if (err < 0) { + return err; + } + + return 0; +} + +#if DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(solomon_ssd1327, mipi_dbi) \ + || DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(solomon_ssd1325, mipi_dbi) +static int ssd1327_5_init(const struct device *dev) +{ + const struct ssd1327_5_config *config = dev->config; + int err; + + LOG_DBG("Initializing device"); + + if (!device_is_ready(config->mipi_dev)) { + LOG_ERR("MIPI Device not ready!"); + return -EINVAL; + } + + err = mipi_dbi_reset(config->mipi_dev, SSD1327_5_RESET_DELAY); + if (err < 0) { + LOG_ERR("Failed to reset device!"); + return err; + } + k_msleep(SSD1327_5_RESET_DELAY); + + err = ssd1327_5_init_device(dev); + if (err < 0) { + LOG_ERR("Failed to initialize device! %d", err); + return err; + } + + return 0; +} +#endif + +#if DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(solomon_ssd1327, i2c) \ + || DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(solomon_ssd1325, i2c) +static int ssd1327_5_init_i2c(const struct device *dev) +{ + const struct ssd1327_5_config *config = dev->config; + int err; + + LOG_DBG("Initializing device"); + + if (!i2c_is_ready_dt(&config->i2c)) { + LOG_ERR("I2C Device not ready!"); + return -EINVAL; + } + + err = ssd1327_5_init_device(dev); + if (err < 0) { + LOG_ERR("Failed to initialize device! %d", err); + return err; + } + + return 0; +} +#endif + +static DEVICE_API(display, ssd1327_5_driver_api) = { + .blanking_on = ssd1327_5_suspend, + .blanking_off = ssd1327_5_resume, + .write = ssd1327_5_write, + .set_contrast = ssd1327_5_set_contrast, + .get_capabilities = ssd1327_5_get_capabilities, + .set_pixel_format = ssd1327_5_set_pixel_format, +}; + +#define SSD1327_5_WORD_SIZE(inst) \ + ((DT_STRING_UPPER_TOKEN(inst, mipi_mode) == MIPI_DBI_MODE_SPI_4WIRE) ? SPI_WORD_SET(8) \ + : SPI_WORD_SET(9)) + +#define SSD1327_5_CONV_BUFFER_SIZE(node_id, n_buf_lines) \ + DIV_ROUND_UP(DT_PROP(node_id, width) * n_buf_lines, 2) + +#define SSD1327_5_GRAYSCALE_TABLE(node_id) \ + .grayscale_table = COND_CODE_1(DT_NODE_HAS_PROP(node_id, grayscale_table), \ + (ssd1327_5_grayscale_table_##node_id), (NULL)) + +#define SSD1327_5_DEFINE_I2C(node_id, n_variant, n_default_contrast, n_buf_lines) \ + static uint8_t conversion_buf##node_id[SSD1327_5_CONV_BUFFER_SIZE(node_id, n_buf_lines)]; \ + static struct ssd1327_5_data data##node_id; \ + COND_CODE_1(DT_NODE_HAS_PROP(node_id, grayscale_table), ( \ + static const uint8_t ssd1327_5_grayscale_table_##node_id[SSD1327_5_LUT_COUNT] = \ + DT_PROP(node_id, grayscale_table);), ()) \ + static const struct ssd1327_5_config config##node_id = { \ + .variant = n_variant, \ + .i2c = I2C_DT_SPEC_GET(node_id), \ + .height = DT_PROP(node_id, height), \ + .width = DT_PROP(node_id, width), \ + .oscillator_freq = DT_PROP(node_id, oscillator_freq), \ + .display_offset = DT_PROP(node_id, display_offset), \ + .start_line = DT_PROP(node_id, start_line), \ + .multiplex_ratio = DT_PROP(node_id, multiplex_ratio), \ + .prechargep = DT_PROP_OR(node_id, prechargep, 0x5), \ + .remap_value = DT_PROP(node_id, remap_value), \ + .color_inversion = DT_PROP(node_id, inversion_on), \ + .phase_length = DT_PROP(node_id, phase_length), \ + .function_selection_b = DT_PROP_OR(node_id, function_selection_b, 0x62), \ + .precharge_voltage = DT_PROP(node_id, precharge_voltage), \ + .vcomh_voltage = DT_PROP(node_id, vcomh_voltage), \ + .default_contrast = n_default_contrast, \ + SSD1327_5_GRAYSCALE_TABLE(node_id), \ + .write_cmd = ssd1327_5_write_bus_cmd_i2c, \ + .write_pixels = ssd1327_5_write_pixels_i2c, \ + .conversion_buf = conversion_buf##node_id, \ + .conversion_buf_size = sizeof(conversion_buf##node_id), \ + }; \ + \ + DEVICE_DT_DEFINE(node_id, ssd1327_5_init_i2c, NULL, &data##node_id, &config##node_id, \ + POST_KERNEL, CONFIG_DISPLAY_INIT_PRIORITY, &ssd1327_5_driver_api); + +#define SSD1327_5_DEFINE_MIPI(node_id, n_variant, n_default_contrast, n_buf_lines) \ + static uint8_t conversion_buf##node_id[SSD1327_5_CONV_BUFFER_SIZE(node_id, n_buf_lines)]; \ + static struct ssd1327_5_data data##node_id; \ + COND_CODE_1(DT_NODE_HAS_PROP(node_id, grayscale_table), ( \ + static const uint8_t ssd1327_5_grayscale_table_##node_id[SSD1327_5_LUT_COUNT] = \ + DT_PROP(node_id, grayscale_table);), ()) \ + static const struct ssd1327_5_config config##node_id = { \ + .variant = n_variant, \ + .mipi_dev = DEVICE_DT_GET(DT_PARENT(node_id)), \ + .dbi_config = MIPI_DBI_CONFIG_DT( \ + node_id, SSD1327_5_WORD_SIZE(node_id) | SPI_OP_MODE_MASTER, 0), \ + .height = DT_PROP(node_id, height), \ + .width = DT_PROP(node_id, width), \ + .oscillator_freq = DT_PROP(node_id, oscillator_freq), \ + .display_offset = DT_PROP(node_id, display_offset), \ + .start_line = DT_PROP(node_id, start_line), \ + .multiplex_ratio = DT_PROP(node_id, multiplex_ratio), \ + .prechargep = DT_PROP_OR(node_id, prechargep, 0x5), \ + .remap_value = DT_PROP(node_id, remap_value), \ + .color_inversion = DT_PROP(node_id, inversion_on), \ + .phase_length = DT_PROP(node_id, phase_length), \ + .function_selection_b = DT_PROP_OR(node_id, function_selection_b, 0x62), \ + .precharge_voltage = DT_PROP(node_id, precharge_voltage), \ + .vcomh_voltage = DT_PROP(node_id, vcomh_voltage), \ + .default_contrast = n_default_contrast, \ + SSD1327_5_GRAYSCALE_TABLE(node_id), \ + .write_cmd = ssd1327_5_write_bus_cmd_mipi, \ + .write_pixels = ssd1327_5_write_pixels_mipi, \ + .conversion_buf = conversion_buf##node_id, \ + .conversion_buf_size = sizeof(conversion_buf##node_id), \ + }; \ + \ + DEVICE_DT_DEFINE(node_id, ssd1327_5_init, NULL, &data##node_id, &config##node_id, \ + POST_KERNEL, CONFIG_DISPLAY_INIT_PRIORITY, &ssd1327_5_driver_api); + +#define SSD1327_5_DEFINE(node_id, n_variant, n_default_contrast, n_buf_lines) \ + COND_CODE_1(DT_ON_BUS(node_id, i2c), \ + (SSD1327_5_DEFINE_I2C(node_id, n_variant, n_default_contrast, n_buf_lines)), \ + (SSD1327_5_DEFINE_MIPI(node_id, n_variant, n_default_contrast, n_buf_lines))) + +DT_FOREACH_STATUS_OKAY_VARGS(solomon_ssd1327, SSD1327_5_DEFINE, display_ssd1327, + CONFIG_SSD1327_DEFAULT_CONTRAST, CONFIG_SSD1327_CONV_BUFFER_LINES) +DT_FOREACH_STATUS_OKAY_VARGS(solomon_ssd1325, SSD1327_5_DEFINE, display_ssd1325, + CONFIG_SSD1325_DEFAULT_CONTRAST, CONFIG_SSD1325_CONV_BUFFER_LINES) diff --git a/drivers/display/ssd1327.c b/drivers/display/ssd1327.c deleted file mode 100644 index 0a4d744f6dbe..000000000000 --- a/drivers/display/ssd1327.c +++ /dev/null @@ -1,536 +0,0 @@ -/* - * Copyright (c) 2024 Savoir-faire Linux - * Copyright (c) 2025 MASSDRIVER EI (massdriver.space) - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -LOG_MODULE_REGISTER(ssd1327, CONFIG_DISPLAY_LOG_LEVEL); - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "ssd1327_regs.h" - -#define SSD1327_ENABLE_VDD 0x01 -#define SSD1327_UNLOCK_COMMAND 0x12 -#define SSD1327_MAXIMUM_CMD_LENGTH 16 - -typedef int (*ssd1327_write_bus_cmd_fn)(const struct device *dev, const uint8_t cmd, - const uint8_t *data, size_t len); -typedef int (*ssd1327_write_pixels_fn)(const struct device *dev, const uint8_t *buf, - uint32_t pixel_count, - const struct display_buffer_descriptor *desc); - -struct ssd1327_config { - struct i2c_dt_spec i2c; - ssd1327_write_bus_cmd_fn write_cmd; - ssd1327_write_pixels_fn write_pixels; - const struct device *mipi_dev; - const struct mipi_dbi_config dbi_config; - uint16_t height; - uint16_t width; - uint8_t oscillator_freq; - uint8_t start_line; - uint8_t display_offset; - uint8_t multiplex_ratio; - uint8_t prechargep; - uint8_t remap_value; - uint8_t phase_length; - uint8_t function_selection_b; - uint8_t precharge_voltage; - uint8_t vcomh_voltage; - const uint8_t *grayscale_table; - bool color_inversion; - uint8_t *conversion_buf; - size_t conversion_buf_size; -}; - -struct ssd1327_data { - uint8_t contrast; - uint8_t scan_mode; -}; - -static inline int ssd1327_write_bus_cmd_mipi(const struct device *dev, const uint8_t cmd, - const uint8_t *data, size_t len) -{ - const struct ssd1327_config *config = dev->config; - int err; - - /* Values given after the memory register must be sent with pin D/C set to 0. */ - /* Data is sent as a command following the mipi_cbi api */ - err = mipi_dbi_command_write(config->mipi_dev, &config->dbi_config, cmd, NULL, 0); - if (err) { - return err; - } - for (size_t i = 0; i < len; i++) { - err = mipi_dbi_command_write(config->mipi_dev, &config->dbi_config, - data[i], NULL, 0); - if (err) { - return err; - } - } - mipi_dbi_release(config->mipi_dev, &config->dbi_config); - - return 0; -} - -static inline int ssd1327_write_bus_cmd_i2c(const struct device *dev, const uint8_t cmd, - const uint8_t *data, size_t len) -{ - const struct ssd1327_config *config = dev->config; - uint8_t buf[SSD1327_MAXIMUM_CMD_LENGTH + 1]; - - if (len > SSD1327_MAXIMUM_CMD_LENGTH - 1) { - return -EINVAL; - } - - buf[0] = SSD1327_CONTROL_ALL_BYTES_CMD; - buf[1] = cmd; - memcpy(&(buf[2]), data, len); - - return i2c_write_dt(&config->i2c, buf, len + 2); -} - -static inline int ssd1327_set_timing_setting(const struct device *dev) -{ - const struct ssd1327_config *config = dev->config; - uint8_t buf = SSD1327_UNLOCK_COMMAND; - int err; - - err = config->write_cmd(dev, SSD1327_SET_PHASE_LENGTH, &config->phase_length, 1); - if (err < 0) { - return err; - } - err = config->write_cmd(dev, SSD1327_SET_OSC_FREQ, &config->oscillator_freq, 1); - if (err < 0) { - return err; - } - err = config->write_cmd(dev, SSD1327_SET_PRECHARGE_PERIOD, &config->prechargep, 1); - if (err < 0) { - return err; - } - err = config->write_cmd(dev, SSD1327_LINEAR_LUT, NULL, 0); - if (err < 0) { - return err; - } - if (config->grayscale_table != NULL) { - err = config->write_cmd(dev, SSD1327_SET_LUT, config->grayscale_table, - SSD1327_SET_LUT_COUNT); - if (err < 0) { - return err; - } - } - err = config->write_cmd(dev, SSD1327_SET_PRECHARGE_VOLTAGE, &config->precharge_voltage, 1); - if (err < 0) { - return err; - } - err = config->write_cmd(dev, SSD1327_SET_VCOMH, &config->vcomh_voltage, 1); - if (err < 0) { - return err; - } - err = config->write_cmd(dev, SSD1327_FUNCTION_SELECTION_B, &config->function_selection_b, - 1); - if (err < 0) { - return err; - } - return config->write_cmd(dev, SSD1327_SET_COMMAND_LOCK, &buf, 1); -} - -static inline int ssd1327_set_hardware_config(const struct device *dev) -{ - const struct ssd1327_config *config = dev->config; - uint8_t buf; - int err; - - err = config->write_cmd(dev, SSD1327_SET_DISPLAY_START_LINE, &config->start_line, 1); - if (err < 0) { - return err; - } - err = config->write_cmd(dev, SSD1327_SET_DISPLAY_OFFSET, &config->display_offset, 1); - if (err < 0) { - return err; - } - err = config->write_cmd(dev, SSD1327_SET_NORMAL_DISPLAY, NULL, 0); - if (err < 0) { - return err; - } - err = config->write_cmd(dev, SSD1327_SET_SEGMENT_MAP_REMAPED, &config->remap_value, 1); - if (err < 0) { - return err; - } - err = config->write_cmd(dev, SSD1327_SET_MULTIPLEX_RATIO, &config->multiplex_ratio, 1); - if (err < 0) { - return err; - } - buf = SSD1327_ENABLE_VDD; - return config->write_cmd(dev, SSD1327_SET_FUNCTION_A, &buf, 1); -} - -static int ssd1327_resume(const struct device *dev) -{ - const struct ssd1327_config *config = dev->config; - - return config->write_cmd(dev, SSD1327_DISPLAY_ON, NULL, 0); -} - -static int ssd1327_suspend(const struct device *dev) -{ - const struct ssd1327_config *config = dev->config; - - return config->write_cmd(dev, SSD1327_DISPLAY_OFF, NULL, 0); -} - -static int ssd1327_set_display(const struct device *dev) -{ - const struct ssd1327_config *config = dev->config; - int err; - uint8_t x_position[] = {0, config->width - 1}; - uint8_t y_position[] = {0, config->height - 1}; - - err = config->write_cmd(dev, SSD1327_SET_COLUMN_ADDR, x_position, sizeof(x_position)); - if (err < 0) { - return err; - } - err = config->write_cmd(dev, SSD1327_SET_ROW_ADDR, y_position, sizeof(y_position)); - if (err < 0) { - return err; - } - return config->write_cmd(dev, SSD1327_SET_SEGMENT_MAP_REMAPED, &config->remap_value, 1); -} - -/* Convert what the conversion buffer can hold to pixelx (3:0) and pixelx+1 (7:4) */ -static int ssd1327_convert_L_8(const struct device *dev, const uint8_t *buf, int cur_offset, - uint32_t pixel_count) -{ - const struct ssd1327_config *config = dev->config; - int i = 0; - - for (; i / 2 < config->conversion_buf_size && pixel_count > cur_offset + i; i += 2) { - config->conversion_buf[i / 2] = buf[cur_offset + i] >> 4; - config->conversion_buf[i / 2] |= (buf[cur_offset + i + 1] >> 4) << 4; - } - return i; -} - -#if DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(solomon_ssd1327fb, mipi_dbi) -static int ssd1327_write_pixels_mipi(const struct device *dev, const uint8_t *buf, - uint32_t pixel_count, - const struct display_buffer_descriptor *desc) -{ - const struct ssd1327_config *config = dev->config; - struct display_buffer_descriptor mipi_desc; - int ret, i; - int total = 0; - - mipi_desc.pitch = desc->pitch; - - while (pixel_count > total) { - i = ssd1327_convert_L_8(dev, buf, total, pixel_count); - - mipi_desc.buf_size = i / 2; - mipi_desc.width = mipi_desc.buf_size / desc->height; - mipi_desc.height = mipi_desc.buf_size / desc->width; - - /* This is the wrong format, but it doesn't matter to almost all mipi drivers */ - ret = mipi_dbi_write_display(config->mipi_dev, &config->dbi_config, - config->conversion_buf, &mipi_desc, PIXEL_FORMAT_L_8); - if (ret < 0) { - return ret; - } - total += i; - } - mipi_dbi_release(config->mipi_dev, &config->dbi_config); - return 0; -} -#endif - -#if DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(solomon_ssd1327fb, i2c) -static int ssd1327_write_pixels_i2c(const struct device *dev, const uint8_t *buf, - uint32_t pixel_count, - const struct display_buffer_descriptor *desc) -{ - const struct ssd1327_config *config = dev->config; - int ret, i; - int total = 0; - - while (pixel_count > total) { - i = ssd1327_convert_L_8(dev, buf, total, pixel_count); - - ret = i2c_burst_write_dt(&config->i2c, SSD1327_CONTROL_ALL_BYTES_DATA, - config->conversion_buf, i / 2); - if (ret < 0) { - return ret; - } - total += i; - } - return 0; -} -#endif - -static int ssd1327_write(const struct device *dev, const uint16_t x, const uint16_t y, - const struct display_buffer_descriptor *desc, const void *buf) -{ - const struct ssd1327_config *config = dev->config; - int err; - size_t buf_len; - int32_t pixel_count = desc->width * desc->height; - uint8_t x_position[] = {x / 2, (x + desc->width - 1) / 2}; - uint8_t y_position[] = {y, y + desc->height - 1}; - - if (desc->pitch != desc->width) { - LOG_ERR("Pitch is not width"); - return -EINVAL; - } - - /* Following the datasheet, in the GDDRAM, two segment are split in one register */ - buf_len = MIN(desc->buf_size, desc->height * desc->width / 2); - if (buf == NULL || buf_len == 0U) { - LOG_ERR("Display buffer is not available"); - return -EINVAL; - } - - if ((x & 1) != 0U) { - LOG_ERR("Unsupported origin"); - return -EINVAL; - } - - LOG_DBG("x %u, y %u, pitch %u, width %u, height %u, buf_len %u", x, y, desc->pitch, - desc->width, desc->height, buf_len); - - err = config->write_cmd(dev, SSD1327_SET_COLUMN_ADDR, x_position, sizeof(x_position)); - if (err) { - return err; - } - - err = config->write_cmd(dev, SSD1327_SET_ROW_ADDR, y_position, sizeof(y_position)); - if (err) { - return err; - } - - return config->write_pixels(dev, buf, pixel_count, desc); -} - -static int ssd1327_set_contrast(const struct device *dev, const uint8_t contrast) -{ - const struct ssd1327_config *config = dev->config; - - return config->write_cmd(dev, SSD1327_SET_CONTRAST_CTRL, &contrast, 1); -} - -static void ssd1327_get_capabilities(const struct device *dev, struct display_capabilities *caps) -{ - const struct ssd1327_config *config = dev->config; - - memset(caps, 0, sizeof(struct display_capabilities)); - caps->x_resolution = config->width; - caps->y_resolution = config->height; - caps->supported_pixel_formats = PIXEL_FORMAT_L_8; - caps->current_pixel_format = PIXEL_FORMAT_L_8; - caps->screen_info = 0; -} - -static int ssd1327_set_pixel_format(const struct device *dev, const enum display_pixel_format pf) -{ - if (pf == PIXEL_FORMAT_L_8) { - return 0; - } - LOG_ERR("Unsupported pixel format"); - return -ENOTSUP; -} - -static int ssd1327_init_device(const struct device *dev) -{ - const struct ssd1327_config *config = dev->config; - uint8_t buf; - int err; - - /* Turn display off */ - err = ssd1327_suspend(dev); - if (err < 0) { - return err; - } - - err = ssd1327_set_display(dev); - if (err < 0) { - return err; - } - - err = ssd1327_set_contrast(dev, CONFIG_SSD1327_DEFAULT_CONTRAST); - if (err < 0) { - return err; - } - - err = ssd1327_set_hardware_config(dev); - if (err < 0) { - return err; - } - - buf = (config->color_inversion ? SSD1327_SET_REVERSE_DISPLAY : SSD1327_SET_NORMAL_DISPLAY); - err = config->write_cmd(dev, SSD1327_SET_ENTIRE_DISPLAY_OFF, &buf, 1); - if (err < 0) { - return err; - } - - err = ssd1327_set_timing_setting(dev); - if (err < 0) { - return err; - } - - err = ssd1327_resume(dev); - if (err < 0) { - return err; - } - - return 0; -} - -#if DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(solomon_ssd1327fb, mipi_dbi) -static int ssd1327_init(const struct device *dev) -{ - const struct ssd1327_config *config = dev->config; - int err; - - LOG_DBG("Initializing device"); - - if (!device_is_ready(config->mipi_dev)) { - LOG_ERR("MIPI Device not ready!"); - return -EINVAL; - } - - err = mipi_dbi_reset(config->mipi_dev, SSD1327_RESET_DELAY); - if (err < 0) { - LOG_ERR("Failed to reset device!"); - return err; - } - k_msleep(SSD1327_RESET_DELAY); - - err = ssd1327_init_device(dev); - if (err < 0) { - LOG_ERR("Failed to initialize device! %d", err); - return err; - } - - return 0; -} -#endif - -#if DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(solomon_ssd1327fb, i2c) -static int ssd1327_init_i2c(const struct device *dev) -{ - const struct ssd1327_config *config = dev->config; - int err; - - LOG_DBG("Initializing device"); - - if (!i2c_is_ready_dt(&config->i2c)) { - LOG_ERR("I2C Device not ready!"); - return -EINVAL; - } - - err = ssd1327_init_device(dev); - if (err < 0) { - LOG_ERR("Failed to initialize device! %d", err); - return err; - } - - return 0; -} -#endif - -static DEVICE_API(display, ssd1327_driver_api) = { - .blanking_on = ssd1327_suspend, - .blanking_off = ssd1327_resume, - .write = ssd1327_write, - .set_contrast = ssd1327_set_contrast, - .get_capabilities = ssd1327_get_capabilities, - .set_pixel_format = ssd1327_set_pixel_format, -}; - -#define SSD1327_WORD_SIZE(inst) \ - ((DT_STRING_UPPER_TOKEN(inst, mipi_mode) == MIPI_DBI_MODE_SPI_4WIRE) ? SPI_WORD_SET(8) \ - : SPI_WORD_SET(9)) - -#define SSD1327_CONV_BUFFER_SIZE(node_id) \ - DIV_ROUND_UP(DT_PROP(node_id, width) * CONFIG_SSD1327_CONV_BUFFER_LINES, 2) - -#define SSD1327_GRAYSCALE_TABLE(node_id) \ - .grayscale_table = COND_CODE_1(DT_NODE_HAS_PROP(node_id, grayscale_table), \ - (ssd1327_grayscale_table_##node_id), (NULL)) - -#define SSD1327_DEFINE_I2C(node_id) \ - static uint8_t conversion_buf##node_id[SSD1327_CONV_BUFFER_SIZE(node_id)]; \ - static struct ssd1327_data data##node_id; \ - COND_CODE_1(DT_NODE_HAS_PROP(node_id, grayscale_table), ( \ - static const uint8_t ssd1327_grayscale_table_##node_id[SSD1327_SET_LUT_COUNT] = \ - DT_PROP(node_id, grayscale_table);), ()) \ - static const struct ssd1327_config config##node_id = { \ - .i2c = I2C_DT_SPEC_GET(node_id), \ - .height = DT_PROP(node_id, height), \ - .width = DT_PROP(node_id, width), \ - .oscillator_freq = DT_PROP(node_id, oscillator_freq), \ - .display_offset = DT_PROP(node_id, display_offset), \ - .start_line = DT_PROP(node_id, start_line), \ - .multiplex_ratio = DT_PROP(node_id, multiplex_ratio), \ - .prechargep = DT_PROP(node_id, prechargep), \ - .remap_value = DT_PROP(node_id, remap_value), \ - .color_inversion = DT_PROP(node_id, inversion_on), \ - .phase_length = DT_PROP(node_id, phase_length), \ - .function_selection_b = DT_PROP(node_id, function_selection_b), \ - .precharge_voltage = DT_PROP(node_id, precharge_voltage), \ - .vcomh_voltage = DT_PROP(node_id, vcomh_voltage), \ - SSD1327_GRAYSCALE_TABLE(node_id), \ - .write_cmd = ssd1327_write_bus_cmd_i2c, \ - .write_pixels = ssd1327_write_pixels_i2c, \ - .conversion_buf = conversion_buf##node_id, \ - .conversion_buf_size = sizeof(conversion_buf##node_id), \ - }; \ - \ - DEVICE_DT_DEFINE(node_id, ssd1327_init_i2c, NULL, &data##node_id, &config##node_id, \ - POST_KERNEL, CONFIG_DISPLAY_INIT_PRIORITY, &ssd1327_driver_api); - -#define SSD1327_DEFINE_MIPI(node_id) \ - static uint8_t conversion_buf##node_id[SSD1327_CONV_BUFFER_SIZE(node_id)]; \ - static struct ssd1327_data data##node_id; \ - COND_CODE_1(DT_NODE_HAS_PROP(node_id, grayscale_table), ( \ - static const uint8_t ssd1327_grayscale_table_##node_id[SSD1327_SET_LUT_COUNT] = \ - DT_PROP(node_id, grayscale_table);), ()) \ - static const struct ssd1327_config config##node_id = { \ - .mipi_dev = DEVICE_DT_GET(DT_PARENT(node_id)), \ - .dbi_config = MIPI_DBI_CONFIG_DT( \ - node_id, SSD1327_WORD_SIZE(node_id) | SPI_OP_MODE_MASTER, 0), \ - .height = DT_PROP(node_id, height), \ - .width = DT_PROP(node_id, width), \ - .oscillator_freq = DT_PROP(node_id, oscillator_freq), \ - .display_offset = DT_PROP(node_id, display_offset), \ - .start_line = DT_PROP(node_id, start_line), \ - .multiplex_ratio = DT_PROP(node_id, multiplex_ratio), \ - .prechargep = DT_PROP(node_id, prechargep), \ - .remap_value = DT_PROP(node_id, remap_value), \ - .color_inversion = DT_PROP(node_id, inversion_on), \ - .phase_length = DT_PROP(node_id, phase_length), \ - .function_selection_b = DT_PROP(node_id, function_selection_b), \ - .precharge_voltage = DT_PROP(node_id, precharge_voltage), \ - .vcomh_voltage = DT_PROP(node_id, vcomh_voltage), \ - SSD1327_GRAYSCALE_TABLE(node_id), \ - .write_cmd = ssd1327_write_bus_cmd_mipi, \ - .write_pixels = ssd1327_write_pixels_mipi, \ - .conversion_buf = conversion_buf##node_id, \ - .conversion_buf_size = sizeof(conversion_buf##node_id), \ - }; \ - \ - DEVICE_DT_DEFINE(node_id, ssd1327_init, NULL, &data##node_id, &config##node_id, \ - POST_KERNEL, CONFIG_DISPLAY_INIT_PRIORITY, &ssd1327_driver_api); - -#define SSD1327_DEFINE(node_id) \ - COND_CODE_1(DT_ON_BUS(node_id, i2c), \ - (SSD1327_DEFINE_I2C(node_id)), (SSD1327_DEFINE_MIPI(node_id))) - -DT_FOREACH_STATUS_OKAY(solomon_ssd1327fb, SSD1327_DEFINE) diff --git a/drivers/display/ssd1327_regs.h b/drivers/display/ssd1327_regs.h deleted file mode 100644 index 36e72d7f66a8..000000000000 --- a/drivers/display/ssd1327_regs.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2024 Savoir-faire Linux - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef __SSD1327_REGS_H__ -#define __SSD1327_REGS_H__ - -/* - * Fundamental Command Table - */ -#define SSD1327_SET_COLUMN_ADDR 0x15 -#define SSD1327_SET_ROW_ADDR 0x75 - -#define SSD1327_SET_CONTRAST_CTRL 0x81 - -#define SSD1327_SET_SEGMENT_MAP_REMAPED 0xa0 -#define SSD1327_SET_DISPLAY_START_LINE 0xa1 -#define SSD1327_SET_DISPLAY_OFFSET 0xa2 - -#define SSD1327_SET_NORMAL_DISPLAY 0xa4 -#define SSD1327_SET_ENTIRE_DISPLAY_ON 0xa5 -#define SSD1327_SET_ENTIRE_DISPLAY_OFF 0xa6 -#define SSD1327_SET_REVERSE_DISPLAY 0xa7 -#define SSD1327_SET_MULTIPLEX_RATIO 0xa8 - -#define SSD1327_DISPLAY_OFF 0xae -#define SSD1327_DISPLAY_ON 0xaf - -#define SSD1327_SET_FUNCTION_A 0xab -#define SSD1327_SET_PHASE_LENGTH 0xb1 -#define SSD1327_SET_OSC_FREQ 0xb3 -#define SSD1327_SET_PRECHARGE_PERIOD 0xb6 -#define SSD1327_FUNCTION_SELECTION_B 0xd5 - -#define SSD1327_SET_LUT 0xb8 -#define SSD1327_SET_LUT_COUNT 15 -#define SSD1327_LINEAR_LUT 0xb9 - -#define SSD1327_SET_PRECHARGE_VOLTAGE 0xbc -#define SSD1327_SET_VCOMH 0xbe - - -#define SSD1327_SET_COMMAND_LOCK 0xfd - -/* Time constant in ms */ -#define SSD1327_RESET_DELAY 10 - -#define SSD1327_CONTROL_ALL_BYTES_CMD 0x0 -#define SSD1327_CONTROL_ALL_BYTES_DATA 0x40 - -#endif diff --git a/dts/bindings/display/solomon,ssd1325-i2c.yaml b/dts/bindings/display/solomon,ssd1325-i2c.yaml new file mode 100644 index 000000000000..f4ce7357f1bc --- /dev/null +++ b/dts/bindings/display/solomon,ssd1325-i2c.yaml @@ -0,0 +1,12 @@ +# Copyright (c) 2026 MASSDRIVER EI (massdriver.space) +# SPDX-License-Identifier: Apache-2.0 + +title: Solomon SSD1325 display controller on I2C bus + +description: | + The Solomon SSD1325 is a 4-bit greyscale OLED controller + with a maximum 128x80 resolution. + +include: ["solomon,ssd1327_5-common.yaml", "i2c-device.yaml"] + +compatible: "solomon,ssd1325" diff --git a/dts/bindings/display/solomon,ssd1325-mipi.yaml b/dts/bindings/display/solomon,ssd1325-mipi.yaml new file mode 100644 index 000000000000..802211b4a51e --- /dev/null +++ b/dts/bindings/display/solomon,ssd1325-mipi.yaml @@ -0,0 +1,12 @@ +# Copyright (c) 2026 MASSDRIVER EI (massdriver.space) +# SPDX-License-Identifier: Apache-2.0 + +title: Solomon SSD1325 display controller on MIPI_DBI or SPI bus + +description: | + The Solomon SSD1325 is a 4-bit greyscale OLED controller + with a maximum 128x80 resolution. + +include: ["solomon,ssd1327_5-common.yaml", "mipi-dbi-spi-device.yaml"] + +compatible: "solomon,ssd1325" diff --git a/dts/bindings/display/solomon,ssd1327-common.yaml b/dts/bindings/display/solomon,ssd1327-common.yaml new file mode 100644 index 000000000000..1b7546a8dd64 --- /dev/null +++ b/dts/bindings/display/solomon,ssd1327-common.yaml @@ -0,0 +1,16 @@ +# Copyright (c) 2026 MASSDRIVER EI (massdriver.space) +# SPDX-License-Identifier: Apache-2.0 + +include: "solomon,ssd1327_5-common.yaml" + +properties: + prechargep: + type: int + required: true + description: Pre-charge period ranging from 0 to 15 DCLK's. + + function-selection-b: + type: int + default: 0x62 + description: Enables second precharge (A[1]), and external Voltage Segment Level (A[0]) + The value can either be 0x61, 0x62, or 0x63. Most displays use 0x62. diff --git a/dts/bindings/display/solomon,ssd1327fb-i2c.yaml b/dts/bindings/display/solomon,ssd1327-i2c.yaml similarity index 58% rename from dts/bindings/display/solomon,ssd1327fb-i2c.yaml rename to dts/bindings/display/solomon,ssd1327-i2c.yaml index 4e175835355f..8a87f6e0f8c3 100644 --- a/dts/bindings/display/solomon,ssd1327fb-i2c.yaml +++ b/dts/bindings/display/solomon,ssd1327-i2c.yaml @@ -1,4 +1,4 @@ -# Copyright (c) 2025 MASSDRIVER EI (massdriver.space) +# Copyright (c) 2025-2026 MASSDRIVER EI (massdriver.space) # SPDX-License-Identifier: Apache-2.0 title: Solomon SSD1327 display controller on I2C bus @@ -7,6 +7,6 @@ description: | The Solomon SSD1327 is a 4-bit greyscale OLED controller with a maximum 128x128 resolution. -include: ["solomon,ssd1327fb-common.yaml", "i2c-device.yaml"] +include: ["solomon,ssd1327-common.yaml", "i2c-device.yaml"] -compatible: "solomon,ssd1327fb" +compatible: "solomon,ssd1327" diff --git a/dts/bindings/display/solomon,ssd1327fb-mipi.yaml b/dts/bindings/display/solomon,ssd1327-mipi.yaml similarity index 58% rename from dts/bindings/display/solomon,ssd1327fb-mipi.yaml rename to dts/bindings/display/solomon,ssd1327-mipi.yaml index 4112ef03938c..db7174a54ac8 100644 --- a/dts/bindings/display/solomon,ssd1327fb-mipi.yaml +++ b/dts/bindings/display/solomon,ssd1327-mipi.yaml @@ -1,4 +1,4 @@ -# Copyright (c) 2025 MASSDRIVER EI (massdriver.space) +# Copyright (c) 2025-2026 MASSDRIVER EI (massdriver.space) # SPDX-License-Identifier: Apache-2.0 title: Solomon SSD1327 display controller on MIPI_DBI or SPI bus @@ -7,6 +7,6 @@ description: | The Solomon SSD1327 is a 4-bit greyscale OLED controller with a maximum 128x128 resolution. -include: ["solomon,ssd1327fb-common.yaml", "mipi-dbi-spi-device.yaml"] +include: ["solomon,ssd1327-common.yaml", "mipi-dbi-spi-device.yaml"] -compatible: "solomon,ssd1327fb" +compatible: "solomon,ssd1327" diff --git a/dts/bindings/display/solomon,ssd1327fb-common.yaml b/dts/bindings/display/solomon,ssd1327_5-common.yaml similarity index 75% rename from dts/bindings/display/solomon,ssd1327fb-common.yaml rename to dts/bindings/display/solomon,ssd1327_5-common.yaml index 4e9a5c6062a8..6812f6bafc1a 100644 --- a/dts/bindings/display/solomon,ssd1327fb-common.yaml +++ b/dts/bindings/display/solomon,ssd1327_5-common.yaml @@ -1,4 +1,5 @@ # Copyright (c) 2024, Savoir-faire Linux +# Copyright (c) 2025-2026 MASSDRIVER EI (massdriver.space) # SPDX-License-Identifier: Apache-2.0 include: display-controller.yaml @@ -14,23 +15,19 @@ properties: display-offset: type: int required: true - description: Vertical offset by com from 0 ~ 127. Typically 128 - height. + description: Vertical offset by com from 0 ~ 127 (79 for SSD1325). Typically 128 (80) - height. start-line: type: int required: true - description: Start line of display RAM to be displayed by selecting a value from 0 to 127. - Typically 0. + description: Start line of display RAM to be displayed by selecting a value + from 0 to 127 (79 for SSD1325). Typically 0. multiplex-ratio: type: int required: true - description: Multiplex ratio from 15MUX to 127MUX. Typically same value as height - 1. - - prechargep: - type: int - required: true - description: Pre-charge period ranging from 0 to 15 DCLK's + description: Multiplex ratio from 15MUX to 127MUX (79MUX for SSD1325). + Typically same value as height - 1. remap-value: type: int @@ -53,19 +50,13 @@ properties: type: int required: true description: Phase Length for segment charging (7:4) and discharging (3:0). - Good values to try first are 0x1f and 0xf1. - - function-selection-b: - type: int - default: 0x62 - description: Enables second precharge (A[1]), and external Voltage Segment Level (A[0]) - The value can either be 0x61, 0x62, or 0x63. Most displays use 0x62. + Good values to try first are 0x1f and 0xf1, or 0x22 for SSD1325. precharge-voltage: type: int default: 0x8 description: Set precharge voltage (0:4) from 0.20 x VCC to 0.613 x VCC (0x7) and VCOMH (0x8+). - Most displays support 0x8. + Most displays support 0x8, or 0x10 for SSD1325. vcomh-voltage: type: int @@ -80,3 +71,4 @@ properties: grayscale-table: type: uint8-array description: 15 elements array defines gamma settings for each brightness levels. + 5-bits wide for SSD1327, 3-bits wide with specific calculations for SSD1325. From c5c4df5dd67ee1fe319760529eb7ee321994f742 Mon Sep 17 00:00:00 2001 From: Camille BAUD Date: Mon, 12 Jan 2026 18:14:15 +0100 Subject: [PATCH 2371/3659] tests: build_all: display: Add ssd1325 Add ssd1325 test, rename ssd1327 Signed-off-by: Camille BAUD --- drivers/display/display_ssd1327_5.c | 2 +- tests/drivers/build_all/display/app.overlay | 41 +++++++++++++++++++-- 2 files changed, 38 insertions(+), 5 deletions(-) diff --git a/drivers/display/display_ssd1327_5.c b/drivers/display/display_ssd1327_5.c index 07f55a80a900..4f2eb184554a 100644 --- a/drivers/display/display_ssd1327_5.c +++ b/drivers/display/display_ssd1327_5.c @@ -89,7 +89,7 @@ typedef int (*ssd1327_5_write_pixels_fn)(const struct device *dev, const uint8_t { t[0] & 0x7, (t[1] & 0x7) | ((t[2] & 0x7) << 4), (t[3] & 0x7) | ((t[4] & 0x7) << 4), \ (t[5] & 0x7) | ((t[6] & 0x7) << 4), (t[7] & 0x7) | ((t[8] & 0x7) << 4), \ (t[9] & 0x7) | ((t[10] & 0x7) << 4), (t[11] & 0x7) | ((t[12] & 0x7) << 4), \ - (t[13] & 0x7) | ((t[14] & 0x7) << 4) }; + (t[13] & 0x7) | ((t[14] & 0x7) << 4) } #if DT_HAS_COMPAT_STATUS_OKAY(solomon_ssd1327) #define SSD1327_5_MAXIMUM_CMD_LENGTH SSD1327_MAXIMUM_CMD_LENGTH diff --git a/tests/drivers/build_all/display/app.overlay b/tests/drivers/build_all/display/app.overlay index f87b736713d4..9f2c304e4809 100644 --- a/tests/drivers/build_all/display/app.overlay +++ b/tests/drivers/build_all/display/app.overlay @@ -136,8 +136,8 @@ height = <240>; }; - test_spi_ssd1327fb: ssd1327fb@7 { - compatible = "solomon,ssd1327fb"; + test_spi_ssd1327: ssd1327@7 { + compatible = "solomon,ssd1327"; reg = <7>; mipi-max-frequency = <100000000>; width = <128>; @@ -371,6 +371,24 @@ regulation-ratio = <7>; mipi-mode = "MIPI_DBI_MODE_SPI_4WIRE"; }; + + test_spi_ssd1325: ssd1325@21 { + compatible = "solomon,ssd1325"; + reg = <21>; + mipi-max-frequency = <20000000>; + width = <128>; + height = <64>; + precharge-voltage = <0x10>; + remap-value = <0x50>; + oscillator-freq = <0x91>; + display-offset = <0x4c>; + start-line = <0>; + multiplex-ratio = <0x3f>; + phase-length = <0x22>; + vcomh-voltage = <0x2>; + mipi-mode = "MIPI_DBI_MODE_SPI_4WIRE"; + grayscale-table = [02 02 02 02 02 02 02 02 03 04 05 06 07 07 07]; + }; }; test_mipi_dbi_xfr_16bit_write_only { @@ -679,8 +697,8 @@ vcomh-voltage = <0>; }; - test_ssd1327fb: ssd1327fb@5 { - compatible = "solomon,ssd1327fb"; + test_ssd1327: ssd1327@5 { + compatible = "solomon,ssd1327"; reg = <5>; width = <128>; height = <128>; @@ -707,6 +725,21 @@ multiplex-ratio = <0>; phase-length = <0x0>; }; + + test_ssd1325: ssd1325@7 { + compatible = "solomon,ssd1325"; + reg = <7>; + width = <128>; + height = <64>; + precharge-voltage = <0x10>; + remap-value = <0x50>; + oscillator-freq = <0x91>; + display-offset = <0x4c>; + start-line = <0>; + multiplex-ratio = <0x3f>; + phase-length = <0x22>; + vcomh-voltage = <0x2>; + }; }; }; }; From 9e39daadfdce601e224fbfd937fc8421f98f165b Mon Sep 17 00:00:00 2001 From: Camille BAUD Date: Mon, 12 Jan 2026 18:56:56 +0100 Subject: [PATCH 2372/3659] doc: release: Notes about SSD1327 Driver Adds note about Kconfig change for SSD327 driver Signed-off-by: Camille BAUD --- doc/releases/migration-guide-4.4.rst | 5 +++++ doc/releases/release-notes-4.4.rst | 9 +++++++++ 2 files changed, 14 insertions(+) diff --git a/doc/releases/migration-guide-4.4.rst b/doc/releases/migration-guide-4.4.rst index bfd40de5598a..2b19fcdddd14 100644 --- a/doc/releases/migration-guide-4.4.rst +++ b/doc/releases/migration-guide-4.4.rst @@ -355,6 +355,11 @@ Display :kconfig:option:`SDL_DISPLAY_DEFAULT_PIXEL_FORMAT_RGB_565X` and :kconfig:option:`ST7789V_RGB565X` respectively. (:github:`99276`) +* ``CONFIG_SSD1327`` symbol has been renamed to :kconfig:option:`CONFIG_SSD1327_5` to include ``SSD1325`` as well. + +* ``solomon,ssd1327fb`` devicetree compatible has been renamed :dtcompatible:`solomon,ssd1327` + to harmonize with other display controllers and eliminate the zephyr-irrelevant ``fb`` suffix. + DMA === diff --git a/doc/releases/release-notes-4.4.rst b/doc/releases/release-notes-4.4.rst index a839131be85c..912badc334e6 100644 --- a/doc/releases/release-notes-4.4.rst +++ b/doc/releases/release-notes-4.4.rst @@ -169,6 +169,11 @@ New APIs and options generating slot 1 images automatically in sysbuild projects when using MCUboot in direct-xip mode. +* Display + + * :kconfig:option:`SSD1325_DEFAULT_CONTRAST` + * :kconfig:option:`SSD1325_CONV_BUFFER_LINES` + * Ethernet * Driver MAC address configuration with support for NVMEM cell. @@ -300,6 +305,10 @@ New Drivers * :dtcompatible:`radio-fem-two-ctrl-pins` (renamed from ``generic-fem-two-ctrl-pins``) * :dtcompatible:`radio-gpio-coex` (renamed from ``gpio-radio-coex``) +* Display + + * :dtcompatible:`solomon,ssd1325` + New Samples *********** From 730b301009b415b1f55822bf7e7135ff518ea088 Mon Sep 17 00:00:00 2001 From: Greg Leach Date: Tue, 13 Jan 2026 15:37:12 +0000 Subject: [PATCH 2373/3659] boards: ezurio: Add rm126x_dvk support Add support for the Ezurio RM126x DVK board family. Signed-off-by: Greg Leach --- boards/ezurio/rm126x_dvk/Kconfig.defconfig | 14 + .../rm126x_dvk/Kconfig.rm126x_dvk_rm1261 | 6 + .../rm126x_dvk/Kconfig.rm126x_dvk_rm1262 | 6 + boards/ezurio/rm126x_dvk/board.cmake | 9 + boards/ezurio/rm126x_dvk/board.yml | 11 + .../rm126x_dvk/doc/img/rm126x_dvk_rm1261.webp | Bin 0 -> 29002 bytes .../rm126x_dvk/doc/img/rm126x_dvk_rm1262.webp | Bin 0 -> 29002 bytes .../doc/rm126x_dvk_common_1.rst.inc | 206 +++++++++++++ .../doc/rm126x_dvk_common_2.rst.inc | 33 +++ .../rm126x_dvk/doc/rm126x_dvk_rm1261.rst | 19 ++ .../rm126x_dvk/doc/rm126x_dvk_rm1262.rst | 19 ++ boards/ezurio/rm126x_dvk/pre_dt_board.cmake | 6 + .../ezurio/rm126x_dvk/rm126x_dvk-pinctrl.dtsi | 82 ++++++ boards/ezurio/rm126x_dvk/rm126x_dvk.dtsi | 274 ++++++++++++++++++ .../ezurio/rm126x_dvk/rm126x_dvk_rm1261.dts | 31 ++ .../ezurio/rm126x_dvk/rm126x_dvk_rm1261.yaml | 27 ++ .../rm126x_dvk/rm126x_dvk_rm1261_defconfig | 10 + .../ezurio/rm126x_dvk/rm126x_dvk_rm1262.dts | 32 ++ .../ezurio/rm126x_dvk/rm126x_dvk_rm1262.yaml | 27 ++ .../rm126x_dvk/rm126x_dvk_rm1262_defconfig | 10 + 20 files changed, 822 insertions(+) create mode 100644 boards/ezurio/rm126x_dvk/Kconfig.defconfig create mode 100644 boards/ezurio/rm126x_dvk/Kconfig.rm126x_dvk_rm1261 create mode 100644 boards/ezurio/rm126x_dvk/Kconfig.rm126x_dvk_rm1262 create mode 100644 boards/ezurio/rm126x_dvk/board.cmake create mode 100644 boards/ezurio/rm126x_dvk/board.yml create mode 100644 boards/ezurio/rm126x_dvk/doc/img/rm126x_dvk_rm1261.webp create mode 100644 boards/ezurio/rm126x_dvk/doc/img/rm126x_dvk_rm1262.webp create mode 100644 boards/ezurio/rm126x_dvk/doc/rm126x_dvk_common_1.rst.inc create mode 100644 boards/ezurio/rm126x_dvk/doc/rm126x_dvk_common_2.rst.inc create mode 100644 boards/ezurio/rm126x_dvk/doc/rm126x_dvk_rm1261.rst create mode 100644 boards/ezurio/rm126x_dvk/doc/rm126x_dvk_rm1262.rst create mode 100644 boards/ezurio/rm126x_dvk/pre_dt_board.cmake create mode 100644 boards/ezurio/rm126x_dvk/rm126x_dvk-pinctrl.dtsi create mode 100644 boards/ezurio/rm126x_dvk/rm126x_dvk.dtsi create mode 100644 boards/ezurio/rm126x_dvk/rm126x_dvk_rm1261.dts create mode 100644 boards/ezurio/rm126x_dvk/rm126x_dvk_rm1261.yaml create mode 100644 boards/ezurio/rm126x_dvk/rm126x_dvk_rm1261_defconfig create mode 100644 boards/ezurio/rm126x_dvk/rm126x_dvk_rm1262.dts create mode 100644 boards/ezurio/rm126x_dvk/rm126x_dvk_rm1262.yaml create mode 100644 boards/ezurio/rm126x_dvk/rm126x_dvk_rm1262_defconfig diff --git a/boards/ezurio/rm126x_dvk/Kconfig.defconfig b/boards/ezurio/rm126x_dvk/Kconfig.defconfig new file mode 100644 index 000000000000..d5d17b8b979a --- /dev/null +++ b/boards/ezurio/rm126x_dvk/Kconfig.defconfig @@ -0,0 +1,14 @@ +# Copyright The Zephyr Project Contributors +# Copyright (c) 2026 Ezurio LLC +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_RM126X_DVK_RM1261 || BOARD_RM126X_DVK_RM1262 + +config LOG_BACKEND_SWO_FREQ_HZ + default 875000 + depends on LOG_BACKEND_SWO + +config FPU + default y + +endif diff --git a/boards/ezurio/rm126x_dvk/Kconfig.rm126x_dvk_rm1261 b/boards/ezurio/rm126x_dvk/Kconfig.rm126x_dvk_rm1261 new file mode 100644 index 000000000000..e97bf8a9c050 --- /dev/null +++ b/boards/ezurio/rm126x_dvk/Kconfig.rm126x_dvk_rm1261 @@ -0,0 +1,6 @@ +# Copyright The Zephyr Project Contributors +# Copyright (c) 2026 Ezurio LLC +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_RM126X_DVK_RM1261 + select SOC_EFR32BG22C224F512IM40 diff --git a/boards/ezurio/rm126x_dvk/Kconfig.rm126x_dvk_rm1262 b/boards/ezurio/rm126x_dvk/Kconfig.rm126x_dvk_rm1262 new file mode 100644 index 000000000000..3adb9e1159f1 --- /dev/null +++ b/boards/ezurio/rm126x_dvk/Kconfig.rm126x_dvk_rm1262 @@ -0,0 +1,6 @@ +# Copyright The Zephyr Project Contributors +# Copyright (c) 2026 Ezurio LLC +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_RM126X_DVK_RM1262 + select SOC_EFR32BG22C224F512IM40 diff --git a/boards/ezurio/rm126x_dvk/board.cmake b/boards/ezurio/rm126x_dvk/board.cmake new file mode 100644 index 000000000000..42a606a3cf90 --- /dev/null +++ b/boards/ezurio/rm126x_dvk/board.cmake @@ -0,0 +1,9 @@ +# Copyright The Zephyr Project Contributors +# Copyright (c) 2026 Ezurio LLC +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(jlink "--device=EFR32BG22C224F512IM40" "--reset-after-load") +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) + +board_runner_args(silabs_commander "--device=${CONFIG_SOC}") +include(${ZEPHYR_BASE}/boards/common/silabs_commander.board.cmake) diff --git a/boards/ezurio/rm126x_dvk/board.yml b/boards/ezurio/rm126x_dvk/board.yml new file mode 100644 index 000000000000..4038cbcb77e2 --- /dev/null +++ b/boards/ezurio/rm126x_dvk/board.yml @@ -0,0 +1,11 @@ +boards: + - name: rm126x_dvk_rm1261 + full_name: RM1261 DVK + vendor: ezurio + socs: + - name: efr32bg22c224f512im40 + - name: rm126x_dvk_rm1262 + full_name: RM1262 DVK + vendor: ezurio + socs: + - name: efr32bg22c224f512im40 diff --git a/boards/ezurio/rm126x_dvk/doc/img/rm126x_dvk_rm1261.webp b/boards/ezurio/rm126x_dvk/doc/img/rm126x_dvk_rm1261.webp new file mode 100644 index 0000000000000000000000000000000000000000..0979a17fae92d96aa2e07e13535ac4eb330bdb4b GIT binary patch literal 29002 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 BaUTEx literal 0 HcmV?d00001 diff --git a/boards/ezurio/rm126x_dvk/doc/img/rm126x_dvk_rm1262.webp b/boards/ezurio/rm126x_dvk/doc/img/rm126x_dvk_rm1262.webp new file mode 100644 index 0000000000000000000000000000000000000000..0979a17fae92d96aa2e07e13535ac4eb330bdb4b GIT binary patch literal 29002 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 BaUTEx literal 0 HcmV?d00001 diff --git a/boards/ezurio/rm126x_dvk/doc/rm126x_dvk_common_1.rst.inc b/boards/ezurio/rm126x_dvk/doc/rm126x_dvk_common_1.rst.inc new file mode 100644 index 000000000000..13dda7b27a12 --- /dev/null +++ b/boards/ezurio/rm126x_dvk/doc/rm126x_dvk_common_1.rst.inc @@ -0,0 +1,206 @@ +.. SPDX-License-Identifier: Apache-2.0 +.. +.. Copyright (c) 2026 Ezurio LLC + +Overview +******** + +The |RM126x variant| Development Kit provides support for the Ezurio |RM126x variant| LoRa module. + +The module includes an EFR32BG22 Arm Cortex-M33 CPU and a Semtech |SX126x variant| LoRa radio. + +The |RM126x variant| module incorporates the QFN package EFR32BG22 (512kB Flash, 32kB RAM). The part features +up to 16 configurable GPIOs and Lora Radio TX Power up to |LoRa TX Power|. + +The kit features a USB interface, an on-board SEGGER J-Link debugger, one user-LED and button, and +support for hardware add-on boards via a `mikroBUS`_ socket and a `Qwiic`_ connector. + +.. note:: + You can find more information about the RM126x family of modules in the `RM126x product brief`_, the `RM126x datasheet`_ + and on the `RM126x website`_. + + You can find more information about the underlying EFR32BG22 SoC in the `EFR32BG22 datasheet`_ + and `EFR32BG22 reference manual`_. + + You can find more information about the Semtech |SX126x variant| LoRa radio in the `SX126x datasheet`_. + +Hardware +******** + +The |RM126x variant| DVK has one crystal oscillator as follows. + +* Low-frequency 32.768 kHz crystal oscillator (LFXO) + +The crystal oscillator is fitted within the |RM126x variant| module. + +The module supports an external LoRa antenna. + +.. note:: + The MHF4 connector exposed via the |RM126x variant| shield can should be used for antenna connectivity. + +Full details of the DVK can be found in the `RM126x DVK user guide`_ and |Schematics Ref|. + +Supported Features +================== + +.. zephyr:board-supported-hw:: + +DVK Connections and IOs +======================= + +In the following table, the column **Name** contains Pin names. For example, PA2 +means Pin number 2 on PORTA, as used in the board's datasheets and manuals. + +The **Direction** column indicates the pin direction from the module perspective, with +I indicating Input, O Output and I/O both. + ++-------+----------------------+--------------------------------------------------------+-----------+ +| Name | Function | Usage | Direction | ++=======+======================+========================================================+===========+ +| PA1 | SWD_SWCLK | JLink SWCLK | I | ++-------+----------------------+--------------------------------------------------------+-----------+ +| PA2 | SWD_SWDIO | JLink SWDIO | I/O | ++-------+----------------------+--------------------------------------------------------+-----------+ +| PA3 | SWD_SWO | JLink SWO | O | ++-------+----------------------+--------------------------------------------------------+-----------+ +| PB2 | EUART0_RTS | UART Console VCOM_RTS | O | ++-------+----------------------+--------------------------------------------------------+-----------+ +| PB3 | EUART0_RX | UART Console VCOM_RX | I | ++-------+----------------------+--------------------------------------------------------+-----------+ +| PB4 | EUART0_CTS | UART Console VCOM_CTS | I | ++-------+----------------------+--------------------------------------------------------+-----------+ +| PC0 | USART0_SCK | mikroBUS SCK | O | ++-------+----------------------+--------------------------------------------------------+-----------+ +| PC1 | GPIO | mikroBUS CS | I/O | ++-------+----------------------+--------------------------------------------------------+-----------+ +| PC2 | GPIO | mikroBUS AN | I | ++-------+----------------------+--------------------------------------------------------+-----------+ +| PC3 | GPIO | mikroBUS RST | O | ++-------+----------------------+--------------------------------------------------------+-----------+ +| PC4 | GPIO | mikroBUS PWM | O | ++-------+----------------------+--------------------------------------------------------+-----------+ +| PC5 | GPIO | mikroBUS INT / LED0 | I/O | ++-------+----------------------+--------------------------------------------------------+-----------+ +| PC6 | GPIO | Button 0 | I | ++-------+----------------------+--------------------------------------------------------+-----------+ +| PC7 | EUART0_TX | UART Console VCOM_TX | O | ++-------+----------------------+--------------------------------------------------------+-----------+ +| PD2 | USART0_RX / I2C0_SCL | mikroBUS MISO / mikroBUS RX / mikroBUS SCL / Qwiic SCL | I/O | ++-------+----------------------+--------------------------------------------------------+-----------+ +| PD3 | USART0_TX / I2C0_SDA | mikroBUS MOSI / mikroBUS TX / mikroBUS SDA / Qwiic SDA | I/O | ++-------+----------------------+--------------------------------------------------------+-----------+ + +.. note:: + MikroBUS INT and LED0 are multiplexed to the same I/O. Usage is determined by solder bridge SB4. Refer to + the `RM126x DVK user guide`_ and |Schematics Ref| for further details. + + The solder bridge defaults to the closed position to enable LED0 connectivity. + +.. note:: + MikroBUS MISO, RX and SCL are multiplexed to the same I/O. Usage is determined by solder bridges SB5, SB7 and SB8. + Refer to the `RM126x DVK user guide`_ and |Schematics Ref| for further details. + + The SB7 solder bridge defaults to closed to enable MISO connectivity. + +.. note:: + MikroBUS MOSI, TX and SDA are multiplexed to the same I/O. Usage is determined by solder bridges SB9, SB11 and SB12. + Refer to the `RM126x DVK user guide`_ and |Schematics Ref| for further details. + + The SB11 solder bridge defaults to closed to enable MOSI connectivity. + +.. note:: + Qwiic SCL is multipexed to the same I/O as MikroBUS MISO, RX and SCL. MikroBUS I2C based boards can be used + in conjunction with Qwiic based boards by closing solder bridges SB5 and SB6. + + Qwiic SDA is multipexed to the same I/O as MikroBUS MOSI, TX and SDA. MikroBUS I2C based boards can be used + in conjunction with Qwiic based boards by closing solder bridges SB9 and SB10. + + Refer to the `RM126x DVK user guide`_ and |Schematics Ref| for further details. + +EFR32BG22 To |SX126x variant| Radio Connections +=============================================== + +The following are internal to the |RM126x variant| module and describe connectivity between the +EFR32BG22 SoC and the |SX126x variant| LoRa radio. + +In the following table, the column **Name** contains Pin names. For example, PA2 +means Pin number 2 on PORTA, as used in the board's datasheets and manuals. + +The **Direction** column indicates the pin direction from the SoC perspective, with +I indicating Input and O Output. + ++-------+---------------------+------------------------------------------------+-----------+ +| Name | Function | Usage | Direction | ++=======+=====================+================================================+===========+ +| PA0 | USART1_SCK | |SX126x variant| SCK | O | ++-------+---------------------+------------------------------------------------+-----------+ +| PA4 | USART1_TX | |SX126x variant| MOSI | O | ++-------+---------------------+------------------------------------------------+-----------+ +| PA5 | GPIO | |SX126x variant| DIO1 | I | ++-------+---------------------+------------------------------------------------+-----------+ +| PA6 | GPIO | |SX126x variant| RESET | O | ++-------+---------------------+------------------------------------------------+-----------+ +| PA7 | GPIO | |SX126x variant| BUSY | I | ++-------+---------------------+------------------------------------------------+-----------+ +| PA8 | USART1_RX | |SX126x variant| MISO | I | ++-------+---------------------+------------------------------------------------+-----------+ +| PB0 | GPIO | |SX126x variant| CS | O | ++-------+---------------------+------------------------------------------------+-----------+ +| PB1 | GPIO | |SX126x variant| ANT SW | O | ++-------+---------------------+------------------------------------------------+-----------+ + +|SX126x variant| Radio Connections +================================== + +In the following table, the column **Name** contains Pin names as defined in the `SX126x datasheet`_. + +The **Direction** column indicates the pin direction from the radio perspective, with +O indicating Output. + ++-------+---------------------+------------------------------------------------+-----------+ +| Name | Function | Usage | Direction | ++=======+=====================+================================================+===========+ +| DIO2 | GPIO | RF Direction | O | ++-------+---------------------+------------------------------------------------+-----------+ +| DIO3 | GPIO | TCXO Enable | O | ++-------+---------------------+------------------------------------------------+-----------+ + +System Clock +============ + +The |RM126x variant| is configured to use the internal HFRCO oscillator as the System Clock at 38MHz. +It can operate at clock speeds of up to 80 MHz. + +Serial Port +=========== + +The |RM126x variant| has two USARTs and one EUART. + +* USART0 is mapped to the mikroBUS SPI port. +* USART1 is dedicated to the |SX126x variant| radio. +* EUART0 is connected to the board controller and is used for the console. + +Programming and Debugging +************************* + +Applications for the |Board Quoted| board can be built, flashed, and debugged in the usual way. +See :ref:`build_an_application` and :ref:`application_run` for more details on building and running. + +.. note:: + Before using the kit, you should update the J-Link firmware + in `Simplicity Studio`_. + +Testing the LED and button +========================== + +The :zephyr:code-sample:`blinky` sample can be used to test the DVK LED. + +The :zephyr:code-sample:`button` sample can be used to test the DVK button. + +Testing LoRa +============ + +The :zephyr:code-sample:`lorawan-class-a` sample can be programmed to an |RM126x variant| DVK to demonstrate +joining and uplinking to a LoRaWAN network server. + +This is built as follows. diff --git a/boards/ezurio/rm126x_dvk/doc/rm126x_dvk_common_2.rst.inc b/boards/ezurio/rm126x_dvk/doc/rm126x_dvk_common_2.rst.inc new file mode 100644 index 000000000000..950811ac2eec --- /dev/null +++ b/boards/ezurio/rm126x_dvk/doc/rm126x_dvk_common_2.rst.inc @@ -0,0 +1,33 @@ +.. SPDX-License-Identifier: Apache-2.0 +.. +.. Copyright (c) 2026 Ezurio LLC + +.. _RM126x product brief: + https://www.ezurio.com/documentation/product-brief-rm126x-series + +.. _RM126x website: + https://www.ezurio.com/wireless-modules/lorawan-modules-solutions/rm126x-ultra-low-power-lorawan-a-b-c-module + +.. _RM126x datasheet: + https://www.ezurio.com/documentation/datasheet-rm126x-lorawan-module + +.. _EFR32BG22 datasheet: + https://www.silabs.com/documents/public/data-sheets/efr32bg22-datasheet.pdf + +.. _EFR32BG22 reference manual: + https://www.silabs.com/documents/public/reference-manuals/efr32xg22-rm.pdf + +.. _SX126x datasheet: + https://semtech.my.salesforce.com/sfc/p/#E0000000JelG/a/RQ000008n3pp/qXjWn19TZmb.1MgqPZ8Vrc5V7U.M_lOAIoTZHcEAeTI + +.. _mikroBUS: + https://www.mikroe.com/mikrobus + +.. _Qwiic: + https://www.sparkfun.com/qwiic + +.. _RM126x DVK user guide: + https://www.ezurio.com/documentation/user-guide-rm126x-development-kit + +.. _Simplicity Studio: + https://www.silabs.com/software-and-tools/simplicity-studio diff --git a/boards/ezurio/rm126x_dvk/doc/rm126x_dvk_rm1261.rst b/boards/ezurio/rm126x_dvk/doc/rm126x_dvk_rm1261.rst new file mode 100644 index 000000000000..18ae90877e8c --- /dev/null +++ b/boards/ezurio/rm126x_dvk/doc/rm126x_dvk_rm1261.rst @@ -0,0 +1,19 @@ +.. zephyr:board:: rm126x_dvk_rm1261 + +.. |RM126x variant| replace:: RM1261 +.. |SX126x variant| replace:: SX1261 +.. |LoRa TX Power| replace:: 15dBm +.. |Board Quoted| replace:: ``rm126x_dvk_rm1261`` +.. |Schematics Ref| replace:: `RM1261 DVK schematics`_ + +.. include:: rm126x_dvk_common_1.rst.inc + +.. zephyr-app-commands:: + :zephyr-app: samples/subsys/lorawan/class_a + :board: rm126x_dvk_rm1261 + :goals: build + +.. include:: rm126x_dvk_common_2.rst.inc + +.. _RM1261 DVK schematics: + https://www.ezurio.com/documentation/schematic-pcb-assembly-dvk-rm1261-devboard diff --git a/boards/ezurio/rm126x_dvk/doc/rm126x_dvk_rm1262.rst b/boards/ezurio/rm126x_dvk/doc/rm126x_dvk_rm1262.rst new file mode 100644 index 000000000000..defa6b2cde95 --- /dev/null +++ b/boards/ezurio/rm126x_dvk/doc/rm126x_dvk_rm1262.rst @@ -0,0 +1,19 @@ +.. zephyr:board:: rm126x_dvk_rm1262 + +.. |RM126x variant| replace:: RM1262 +.. |SX126x variant| replace:: SX1262 +.. |LoRa TX Power| replace:: 22dBm +.. |Board Quoted| replace:: ``rm126x_dvk_rm1262`` +.. |Schematics Ref| replace:: `RM1262 DVK schematics`_ + +.. include:: rm126x_dvk_common_1.rst.inc + +.. zephyr-app-commands:: + :zephyr-app: samples/subsys/lorawan/class_a + :board: rm126x_dvk_rm1262 + :goals: build + +.. include:: rm126x_dvk_common_2.rst.inc + +.. _RM1262 DVK schematics: + https://www.ezurio.com/documentation/schematic-pcb-assembly-dvk-rm1262-devboard diff --git a/boards/ezurio/rm126x_dvk/pre_dt_board.cmake b/boards/ezurio/rm126x_dvk/pre_dt_board.cmake new file mode 100644 index 000000000000..e0a341833fe4 --- /dev/null +++ b/boards/ezurio/rm126x_dvk/pre_dt_board.cmake @@ -0,0 +1,6 @@ +# Copyright (c) 2021 Linaro Limited +# Copyright (c) 2026 Ezurio LLC +# 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/ezurio/rm126x_dvk/rm126x_dvk-pinctrl.dtsi b/boards/ezurio/rm126x_dvk/rm126x_dvk-pinctrl.dtsi new file mode 100644 index 000000000000..66a271b107b2 --- /dev/null +++ b/boards/ezurio/rm126x_dvk/rm126x_dvk-pinctrl.dtsi @@ -0,0 +1,82 @@ +/* + * Copyright The Zephyr Project Contributors + * Copyright (c) 2026 Ezurio LLC + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&pinctrl { + timer0_default: timer0_default { + group0 { + pins = ; + drive-push-pull; + output-high; + }; + }; + + usart0_default: usart0_default { + group0 { + pins = , ; + drive-push-pull; + output-high; + }; + + group1 { + pins = ; + input-enable; + silabs,input-filter; + }; + }; + + usart1_default: usart1_default { + group0 { + pins = , ; + drive-push-pull; + output-high; + }; + + group1 { + pins = ; + input-enable; + silabs,input-filter; + }; + }; + + iadc0_default: iadc0_default { + group0 { + silabs,analog-bus = ; + }; + }; + + i2c0_default: i2c0_default { + group0 { + pins = , ; + bias-pull-up; + drive-open-drain; + }; + }; + + euart0_default: euart0_default { + group0 { + pins = , ; + drive-push-pull; + output-high; + }; + + group1 { + pins = , ; + input-enable; + silabs,input-filter; + }; + }; + + itm_default: itm_default { + group0 { + pins = ; + drive-push-pull; + output-high; + }; + }; +}; diff --git a/boards/ezurio/rm126x_dvk/rm126x_dvk.dtsi b/boards/ezurio/rm126x_dvk/rm126x_dvk.dtsi new file mode 100644 index 000000000000..5606eeae0f63 --- /dev/null +++ b/boards/ezurio/rm126x_dvk/rm126x_dvk.dtsi @@ -0,0 +1,274 @@ +/* + * Copyright The Zephyr Project Contributors + * Copyright (c) 2026 Ezurio LLC + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include "rm126x_dvk-pinctrl.dtsi" + +/ { + chosen { + zephyr,code-partition = &slot0_partition; + zephyr,console = &euart0; + zephyr,flash = &flash0; + zephyr,shell-uart = &euart0; + zephyr,sram = &sram0; + zephyr,uart-pipe = &euart0; + }; + + aliases { + led0 = &led0; + pwm-led0 = &pwm_led0; + sw0 = &button0; + watchdog0 = &wdog0; + lora0 = &lora0; + + /* If enabled, MCUboot uses this for recovery mode entrance */ + mcuboot-led0 = &led0; + mcuboot-button0 = &button0; + }; + + buttons { + compatible = "gpio-keys"; + + button0: button_0 { + gpios = <&gpioc 6 GPIO_ACTIVE_LOW>; + zephyr,code = ; + }; + }; + + leds { + compatible = "gpio-leds"; + + led0: led_0 { + gpios = <&gpioc 5 GPIO_ACTIVE_HIGH>; + }; + }; + + mikrobus_header: mikrobus-connector { + compatible = "mikro-bus"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0>; + gpio-map-pass-thru = <0 GPIO_DT_FLAGS_MASK>; + gpio-map = <0 0 &gpioc 2 0>, /* AN */ + <1 0 &gpioc 3 0>, /* RST */ + <2 0 &gpioc 1 0>, /* CS */ + <3 0 &gpioc 0 0>, /* SCK */ + <4 0 &gpiod 2 0>, /* MISO */ + <5 0 &gpiod 3 0>, /* MOSI */ + <6 0 &gpioc 4 0>, /* PWM */ + <7 0 &gpioc 5 0>, /* INT */ + <8 0 &gpiod 2 0>, /* RX */ + <9 0 &gpiod 3 0>, /* TX */ + <10 0 &gpiod 2 0>, /* SCL */ + <11 0 &gpiod 3 0>; /* SDA */ + }; + + pwmleds { + compatible = "pwm-leds"; + + pwm_led0: pwm_led_0 { + pwms = <&timer0_pwm 0 PWM_MSEC(20) PWM_POLARITY_NORMAL>; + }; + }; + + qwiic_connector: stemma-qt-connector { + compatible = "stemma-qt-connector"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0>; + gpio-map-pass-thru = <0 GPIO_DT_FLAGS_MASK>; + gpio-map = <0 0 &gpiod 2 0>, /* SCL */ + <1 0 &gpiod 3 0>; /* SDA */ + }; + + mikrobus_adc: zephyr,user { + io-channels = <&adc0 0>; + }; +}; + +&em23grpaclk { + clocks = <&lfxo>; +}; + +&em4grpaclk { + clocks = <&lfxo>; +}; + +&prortcclk { + clocks = <&lfxo>; +}; + +&rtccclk { + clocks = <&lfxo>; +}; + +&wdog0clk { + clocks = <&lfxo>; +}; + +&cpu0 { + clock-frequency = <38000000>; +}; + +&hfrcodpll { + clock-frequency = ; +}; + +&lfxo { + status = "okay"; + ctune = <38>; + precision = <50>; +}; + +&gpio { + status = "okay"; +}; + +&gpioa { + status = "okay"; +}; + +&gpiob { + status = "okay"; +}; + +&gpioc { + status = "okay"; +}; + +&gpiod { + status = "okay"; +}; + +&timer0 { + status = "okay"; + + timer0_pwm: pwm { + pinctrl-0 = <&timer0_default>; + pinctrl-names = "default"; + status = "okay"; + }; +}; + +&usart0 { + compatible = "silabs,usart-spi"; + #address-cells = <1>; + #size-cells = <0>; + pinctrl-0 = <&usart0_default>; + pinctrl-names = "default"; + cs-gpios = <&gpioc 1 GPIO_ACTIVE_LOW>; + status = "okay"; +}; + +&usart1 { + compatible = "silabs,usart-spi"; + #address-cells = <1>; + #size-cells = <0>; + pinctrl-0 = <&usart1_default>; + pinctrl-names = "default"; + cs-gpios = <&gpiob 0 GPIO_ACTIVE_LOW>; + status = "okay"; +}; + +&dcdc { + regulator-boot-on; + regulator-initial-mode = ; + status = "okay"; +}; + +&rtcc0 { + status = "okay"; +}; + +&adc0 { + pinctrl-0 = <&iadc0_default>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + channel@0 { + reg = <0>; + zephyr,acquisition-time = ; + zephyr,gain = "ADC_GAIN_1"; + zephyr,input-positive = ; + zephyr,reference = "ADC_REF_VDD_1"; + zephyr,resolution = <12>; + zephyr,vref-mv = <3300>; + }; +}; + +&i2c0 { + pinctrl-0 = <&i2c0_default>; + pinctrl-names = "default"; + status = "disabled"; +}; + +&wdog0 { + status = "okay"; +}; + +&euart0 { + current-speed = <115200>; + pinctrl-0 = <&euart0_default>; + pinctrl-names = "default"; + status = "okay"; +}; + +&trng { + status = "okay"; +}; + +&itm { + pinctrl-0 = <&itm_default>; + pinctrl-names = "default"; + swo-ref-frequency = ; +}; + +mikrobus_i2c: &i2c0 {}; + +mikrobus_spi: &usart0 {}; + +mikrobus_uart: &usart0 {}; + +zephyr_i2c: &i2c0 {}; + +zephyr_spi: &usart0 {}; + +&flash0 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + /* Reserve 48 KiB for the bootloader */ + boot_partition: partition@0 { + reg = <0x00000000 DT_SIZE_K(48)>; + label = "mcuboot"; + read-only; + }; + + /* Reserve 224 KiB for the application in slot 0 */ + slot0_partition: partition@c000 { + reg = <0x0000c000 DT_SIZE_K(224)>; + label = "image-0"; + }; + + /* Reserve 224 KiB for the application in slot 1 */ + slot1_partition: partition@44000 { + reg = <0x00044000 DT_SIZE_K(224)>; + label = "image-1"; + }; + + /* Set 16 KiB of storage at the end of the 512 KiB of flash */ + storage_partition: partition@7c000 { + reg = <0x0007c000 DT_SIZE_K(16)>; + label = "storage"; + }; + }; +}; diff --git a/boards/ezurio/rm126x_dvk/rm126x_dvk_rm1261.dts b/boards/ezurio/rm126x_dvk/rm126x_dvk_rm1261.dts new file mode 100644 index 000000000000..95a4a50063ff --- /dev/null +++ b/boards/ezurio/rm126x_dvk/rm126x_dvk_rm1261.dts @@ -0,0 +1,31 @@ +/* + * Copyright The Zephyr Project Contributors + * Copyright (c) 2026 Ezurio LLC + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include "rm126x_dvk.dtsi" +#include + +/ { + model = "Ezurio RM1261 DVK"; + compatible = "ezurio,rm126x_dvk_rm1261", "silabs,efr32bg22"; +}; + +&usart1 { + lora0: lora@0 { + compatible = "semtech,sx1261"; + reg = <0>; + reset-gpios = <&gpioa 6 GPIO_ACTIVE_LOW>; + busy-gpios = <&gpioa 7 (GPIO_PULL_UP | GPIO_ACTIVE_HIGH)>; + antenna-enable-gpios = <&gpiob 1 GPIO_ACTIVE_LOW>; + dio1-gpios = <&gpioa 5 (GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH)>; + dio2-tx-enable; + dio3-tcxo-voltage = ; + tcxo-power-startup-delay-ms = <5>; + spi-max-frequency = <1000000>; + }; +}; diff --git a/boards/ezurio/rm126x_dvk/rm126x_dvk_rm1261.yaml b/boards/ezurio/rm126x_dvk/rm126x_dvk_rm1261.yaml new file mode 100644 index 000000000000..133f11135b88 --- /dev/null +++ b/boards/ezurio/rm126x_dvk/rm126x_dvk_rm1261.yaml @@ -0,0 +1,27 @@ +identifier: rm126x_dvk_rm1261 +name: RM1261 DVK +type: mcu +arch: arm +ram: 32 +flash: 224 +toolchain: + - zephyr + - gnuarmemb +supported: + - adc + - clock_control + - comparator + - counter + - dma + - entropy + - gpio + - flash + - i2c + - led + - lora + - pinctrl + - pwm + - spi + - uart + - watchdog +vendor: ezurio diff --git a/boards/ezurio/rm126x_dvk/rm126x_dvk_rm1261_defconfig b/boards/ezurio/rm126x_dvk/rm126x_dvk_rm1261_defconfig new file mode 100644 index 000000000000..5ee421b84580 --- /dev/null +++ b/boards/ezurio/rm126x_dvk/rm126x_dvk_rm1261_defconfig @@ -0,0 +1,10 @@ +# Copyright The Zephyr Project Contributors +# Copyright (c) 2026 Ezurio LLC +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_ARM_MPU=y +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_GPIO=y +CONFIG_HW_STACK_PROTECTION=y diff --git a/boards/ezurio/rm126x_dvk/rm126x_dvk_rm1262.dts b/boards/ezurio/rm126x_dvk/rm126x_dvk_rm1262.dts new file mode 100644 index 000000000000..32d41444f1e6 --- /dev/null +++ b/boards/ezurio/rm126x_dvk/rm126x_dvk_rm1262.dts @@ -0,0 +1,32 @@ +/* + * Copyright The Zephyr Project Contributors + * Copyright (c) 2026 Ezurio LLC + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include "rm126x_dvk.dtsi" +#include + +/ { + model = "Ezurio RM1262 DVK"; + compatible = "ezurio,rm126x_dvk_rm1262", "silabs,efr32bg22"; +}; + +&usart1 { + lora0: lora@0 { + compatible = "semtech,sx1262"; + reg = <0>; + reset-gpios = <&gpioa 6 GPIO_ACTIVE_LOW>; + busy-gpios = <&gpioa 7 (GPIO_PULL_UP | GPIO_ACTIVE_HIGH)>; + antenna-enable-gpios = <&gpiob 1 GPIO_ACTIVE_LOW>; + dio1-gpios = <&gpioa 5 (GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH)>; + dio2-tx-enable; + dio3-tcxo-voltage = ; + tcxo-power-startup-delay-ms = <5>; + regulator-ldo; + spi-max-frequency = <1000000>; + }; +}; diff --git a/boards/ezurio/rm126x_dvk/rm126x_dvk_rm1262.yaml b/boards/ezurio/rm126x_dvk/rm126x_dvk_rm1262.yaml new file mode 100644 index 000000000000..8a2d60aa8183 --- /dev/null +++ b/boards/ezurio/rm126x_dvk/rm126x_dvk_rm1262.yaml @@ -0,0 +1,27 @@ +identifier: rm126x_dvk_rm1262 +name: RM1262 DVK +type: mcu +arch: arm +ram: 32 +flash: 224 +toolchain: + - zephyr + - gnuarmemb +supported: + - adc + - clock_control + - comparator + - counter + - dma + - entropy + - gpio + - flash + - i2c + - led + - lora + - pinctrl + - pwm + - spi + - uart + - watchdog +vendor: ezurio diff --git a/boards/ezurio/rm126x_dvk/rm126x_dvk_rm1262_defconfig b/boards/ezurio/rm126x_dvk/rm126x_dvk_rm1262_defconfig new file mode 100644 index 000000000000..5ee421b84580 --- /dev/null +++ b/boards/ezurio/rm126x_dvk/rm126x_dvk_rm1262_defconfig @@ -0,0 +1,10 @@ +# Copyright The Zephyr Project Contributors +# Copyright (c) 2026 Ezurio LLC +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_ARM_MPU=y +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_GPIO=y +CONFIG_HW_STACK_PROTECTION=y From 5064eda9a4356d86d860aa93db40668c6c380e2a Mon Sep 17 00:00:00 2001 From: Greg Leach Date: Tue, 13 Jan 2026 15:42:24 +0000 Subject: [PATCH 2374/3659] tests: app_development: Add efr32bg22 support Map test IRQ to SGI to prevent clash with EUART0 TX IRQ for EFR32BG22 SoC. Signed-off-by: Greg Leach --- tests/application_development/ram_context_for_isr/Kconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/application_development/ram_context_for_isr/Kconfig b/tests/application_development/ram_context_for_isr/Kconfig index 53cee6732e7f..5d407f3270b7 100644 --- a/tests/application_development/ram_context_for_isr/Kconfig +++ b/tests/application_development/ram_context_for_isr/Kconfig @@ -13,6 +13,7 @@ config TEST_IRQ_NUM default 1 if (SOC_SERIES_NPCX9 || SOC_SERIES_NPCX7 || SOC_SERIES_NPCK3) default 29 if SOC_K32L2B31A default 28 if SOC_SERIES_NRF54L + default 52 if SOC_SERIES_EFR32BG22 default 0 help IRQ number to use for testing purposes. This should be an @@ -25,6 +26,7 @@ config TEST_IRQ_NUM - STM32C0X series: 18 (available test IRQ) - NPCX9, NPCX7, NPCK3 series: 1 (unused IRQ not mapped to MIWU groups) - K32L2B31A: 29 (available test IRQ) + - EFR32BG22: 52 (available test IRQ (SW0 - SGI), (NUM_IRQS - 1) equates to EUART0 TX) - Other platforms: 0 (magic config value to select the last IRQ: NUM_IRQS - 1) config TEST_IRQ_PRIO From 65438886e603003d7192988e35a96f9f504e980b Mon Sep 17 00:00:00 2001 From: Albort Xue Date: Fri, 9 Jan 2026 11:32:28 +0800 Subject: [PATCH 2375/3659] drivers: serial: uart_mcux_lpuart: configure clock before initialization Add clock configuration step before UART initialization to ensure proper clock setup. The clock is first disabled, then configured if supported by the clock controller. If clock configuration is not supported (ENOTSUP/ENOSYS), the driver continues with default settings. Other errors are treated as failures and propagated to the caller. Signed-off-by: Albort Xue --- drivers/serial/uart_mcux_lpuart.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/drivers/serial/uart_mcux_lpuart.c b/drivers/serial/uart_mcux_lpuart.c index d3be5c3e2c77..42608d049a4c 100644 --- a/drivers/serial/uart_mcux_lpuart.c +++ b/drivers/serial/uart_mcux_lpuart.c @@ -1,5 +1,5 @@ /* - * Copyright 2017,2021,2023-2025 NXP + * Copyright 2017,2021,2023-2026 NXP * Copyright (c) 2020 Softube * * SPDX-License-Identifier: Apache-2.0 @@ -1160,9 +1160,14 @@ static int mcux_lpuart_configure_init(const struct device *dev, const struct uar return -ENODEV; } - if (clock_control_get_rate(config->clock_dev, config->clock_subsys, - &clock_freq)) { - return -EINVAL; + ret = clock_control_configure(config->clock_dev, config->clock_subsys, NULL); + if (ret != 0) { + /* Check if error is due to lack of support */ + if (ret != -ENOSYS) { + /* Real error occurred */ + LOG_ERR("Failed to configure clock: %d", ret); + return ret; + } } LPUART_GetDefaultConfig(&uart_config); @@ -1177,6 +1182,13 @@ static int mcux_lpuart_configure_init(const struct device *dev, const struct uar return ret; } + ret = clock_control_get_rate(config->clock_dev, config->clock_subsys, + &clock_freq); + if (ret) { + LOG_ERR("Failed to get clock rate: %d", ret); + return -EINVAL; + } + LPUART_Init(config->base, &uart_config, clock_freq); #ifdef LPUART_HAS_MODEM From abeca66759ef15a87c80712529ec28f2004f8158 Mon Sep 17 00:00:00 2001 From: Jimmy Johnson Date: Tue, 6 Jan 2026 22:11:02 -0800 Subject: [PATCH 2376/3659] sensor: shell: battery: Update support for battery shell queries Added a `supported` flag to battery status query so if the charger does not support the query (returns -ENOTSUP) the command still returns any other supported queries and doesn't error out without reporting anything. Any other errors than -ENOTSUP still cause the request to return immediately, as was the case before the changes. Tested on nordic npm 13xx. Signed-off-by: Jimmy Johnson --- drivers/sensor/shell_battery.c | 120 +++++++++++++++++++++++---------- 1 file changed, 83 insertions(+), 37 deletions(-) diff --git a/drivers/sensor/shell_battery.c b/drivers/sensor/shell_battery.c index 4d7e34ea6286..3a68b560fd37 100644 --- a/drivers/sensor/shell_battery.c +++ b/drivers/sensor/shell_battery.c @@ -11,6 +11,11 @@ #include #include +struct ch_val_result { + struct sensor_value val; + bool supported; +}; + /** * @brief Collect the values for several channels * @@ -29,18 +34,22 @@ static int get_channels(const struct device *dev, ...) va_start(ptr, dev); for (i = 0;; i++) { int chan; - struct sensor_value *val; + struct ch_val_result *val; int err; chan = va_arg(ptr, int); if (chan == -1) { break; } - val = va_arg(ptr, struct sensor_value *); - err = sensor_channel_get(dev, chan, val); - if (err < 0) { + val = va_arg(ptr, struct ch_val_result *); + err = sensor_channel_get(dev, chan, &val->val); + if (err == -ENOTSUP) { + val->supported = false; + } else if (err < 0) { va_end(ptr); return err; + } else { + val->supported = true; } } @@ -51,9 +60,9 @@ static int get_channels(const struct device *dev, ...) /* battery */ static int cmd_battery(const struct shell *sh, size_t argc, char **argv) { - struct sensor_value temp, volt, current, i_desired, charge_remain; - struct sensor_value charge, v_desired, v_design, cap, nom_cap; - struct sensor_value full, empty; + struct ch_val_result temp, volt, current, i_desired, charge_remain; + struct ch_val_result charge, v_desired, v_design, cap, nom_cap; + struct ch_val_result full, empty; const struct device *const dev = DEVICE_DT_GET(DT_ALIAS(battery)); bool allowed; int err; @@ -88,36 +97,73 @@ static int cmd_battery(const struct shell *sh, size_t argc, char **argv) return err; } - shell_print(sh, "Temp: %.1d.%02d C", - temp.val1, temp.val2 / 10000); - shell_print(sh, "V: %5d.%02d V", - volt.val1, volt.val2 / 10000); - shell_print(sh, "V-desired: %d.%02d V", - v_desired.val1, v_desired.val2 / 10000); - shell_fprintf_normal(sh, "I: %lld mA", - sensor_value_to_milli(¤t)); - if (current.val1 > 0) { - shell_fprintf_normal(sh, " (CHG)"); - } else if (current.val1 < 0) { - shell_fprintf_normal(sh, " (DISCHG)"); - } - shell_fprintf_normal(sh, "\n"); - shell_print(sh, "I-desired: %5d mA", - i_desired.val1); - allowed = i_desired.val1 && v_desired.val2 && charge.val1 < 100; - shell_print(sh, "Charging: %sAllowed", - allowed ? "" : "Not "); - shell_print(sh, "Charge: %d %%", charge.val1); - shell_print(sh, "V-design: %d.%02d V", - v_design.val1, v_design.val2 / 10000); - shell_print(sh, "Remaining: %d mAh", - charge_remain.val1); - shell_print(sh, "Cap-full: %d mAh", cap.val1); - shell_print(sh, "Design: %d mAh", nom_cap.val1); - shell_print(sh, "Time full: %dh:%02d", - full.val1 / 60, full.val1 % 60); - shell_print(sh, "Time empty: %dh:%02d", - empty.val1 / 60, empty.val1 % 60); + if (temp.supported) { + shell_print(sh, "Temp: %.1d.%02d C", + temp.val.val1, temp.val.val2 / 10000); + } + + if (volt.supported) { + shell_print(sh, "V: %5d.%02d V", + volt.val.val1, volt.val.val2 / 10000); + } + + if (v_desired.supported) { + shell_print(sh, "V-desired: %d.%02d V", + v_desired.val.val1, v_desired.val.val2 / 10000); + } + + if (current.supported) { + shell_fprintf_normal(sh, "I: %lld mA", + sensor_value_to_milli(¤t.val)); + if (current.val.val1 > 0) { + shell_fprintf_normal(sh, " (CHG)"); + } else if (current.val.val1 < 0) { + shell_fprintf_normal(sh, " (DISCHG)"); + } else { + shell_fprintf_normal(sh, " (UNKWN)"); + } + shell_fprintf_normal(sh, "\n"); + } + + if (i_desired.supported) { + shell_print(sh, "I-desired: %5d mA", + i_desired.val.val1); + allowed = i_desired.val.val1 && v_desired.val.val2 && charge.val.val1 < 100; + shell_print(sh, "Charging: %sAllowed", + allowed ? "" : "Not "); + } + + if (charge.supported) { + shell_print(sh, "Charge: %d %%", charge.val.val1); + } + + if (v_design.supported) { + shell_print(sh, "V-design: %d.%02d V", + v_design.val.val1, v_design.val.val2 / 10000); + } + + if (charge_remain.supported) { + shell_print(sh, "Remaining: %d mAh", + charge_remain.val.val1); + } + + if (cap.supported) { + shell_print(sh, "Cap-full: %d mAh", cap.val.val1); + } + + if (nom_cap.supported) { + shell_print(sh, "Design: %d mAh", nom_cap.val.val1); + } + + if (full.supported) { + shell_print(sh, "Time full: %dh:%02d", + full.val.val1 / 60, full.val.val1 % 60); + } + + if (empty.supported) { + shell_print(sh, "Time empty: %dh:%02d", + empty.val.val1 / 60, empty.val.val1 % 60); + } return 0; } From c84a5eb24fd40ae33dfd3ec2963e534567ab2db4 Mon Sep 17 00:00:00 2001 From: Karol Werner Date: Sun, 4 Jan 2026 22:15:36 +0100 Subject: [PATCH 2377/3659] drivers: sensor: ina3221: fix measurement wait time calculation INA3221 performs measurements sequentially for all enabled channels (see datasheet chapter 7.3.1), but the driver was not accounting for this when calculating the wait time. Additionally, when measuring both bus and shunt voltages, conversion times should be summed rather than taking greater value. Fix by counting enabled channels and multiplying them with per-channel conversion time. For combined measurement, sum both conversion times instead of using MAX(). Signed-off-by: Karol Werner --- drivers/sensor/ti/ina3221/ina3221.c | 30 ++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/drivers/sensor/ti/ina3221/ina3221.c b/drivers/sensor/ti/ina3221/ina3221.c index 28aab27f386e..21c4ce818871 100644 --- a/drivers/sensor/ti/ina3221/ina3221.c +++ b/drivers/sensor/ti/ina3221/ina3221.c @@ -151,6 +151,8 @@ static int ina3221_sample_fetch(const struct device *dev, enum sensor_channel ch const struct ina3221_config *cfg = dev->config; bool measurement_successful = false; k_timeout_t measurement_time = K_NO_WAIT; + uint8_t enabled_channels = 0; + int32_t channel_conv_time_us = 0; int ret; /* Trigger measurement and wait for completion */ @@ -159,29 +161,35 @@ static int ina3221_sample_fetch(const struct device *dev, enum sensor_channel ch if (ret) { return ret; } - measurement_time = - K_USEC(avg_mode_samples[cfg->avg_mode] * - conv_time_us[cfg->conv_time_bus]); + channel_conv_time_us = conv_time_us[cfg->conv_time_bus]; } else if (chan == SENSOR_CHAN_CURRENT) { ret = start_measurement(dev, false, true); if (ret) { return ret; } - measurement_time = - K_USEC(avg_mode_samples[cfg->avg_mode] * - conv_time_us[cfg->conv_time_shunt]); + channel_conv_time_us = conv_time_us[cfg->conv_time_shunt]; } else if (chan == SENSOR_CHAN_POWER || chan == SENSOR_CHAN_ALL) { ret = start_measurement(dev, true, true); if (ret) { return ret; } - measurement_time = - K_USEC(avg_mode_samples[cfg->avg_mode] * - conv_time_us[MAX(cfg->conv_time_shunt, cfg->conv_time_bus)]); + channel_conv_time_us = + conv_time_us[cfg->conv_time_bus] + conv_time_us[cfg->conv_time_shunt]; } else { return -ENOTSUP; } + for (size_t i = 0; i < 3; ++i) { + if (cfg->enable_channel[i]) { + enabled_channels++; + } + } + + /* Measurements are performed sequentially for all enabled channels. */ + /* See chapter 7.3.1 in the datasheet. */ + measurement_time = + K_USEC(enabled_channels * avg_mode_samples[cfg->avg_mode] * channel_conv_time_us); + for (size_t i = 0; i < MAX_RETRIES; ++i) { k_sleep(measurement_time); if (measurement_ready(dev)) { @@ -285,7 +293,7 @@ static DEVICE_API(sensor, ina3221_api) = { static struct ina3221_data ina3221_data_##index; \ \ SENSOR_DEVICE_DT_INST_DEFINE(index, ina3221_init, NULL, &ina3221_data_##index, \ - &ina3221_config_##index, POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY, \ - &ina3221_api); + &ina3221_config_##index, POST_KERNEL, \ + CONFIG_SENSOR_INIT_PRIORITY, &ina3221_api); DT_INST_FOREACH_STATUS_OKAY(INST_DT_INA3221); From bd9bf13a0eb6172ad9898c4174ad8e9205e0b462 Mon Sep 17 00:00:00 2001 From: Supper Thomas <78900636@qq.com> Date: Wed, 31 Dec 2025 07:38:48 +0000 Subject: [PATCH 2378/3659] logging: Fix backoff calculation to use K_CYC instead of K_TICK The backoff timeout calculation in z_log_msg_claim_oldest() was incorrectly using K_TICK macro. Changed to K_CYC to properly convert cycle-based timing differences to kernel timeouts for accurate backoff in multi-domain message processing. Signed-off-by: Supper Thomas <78900636@qq.com> --- subsys/logging/log_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/subsys/logging/log_core.c b/subsys/logging/log_core.c index f0143480dc67..d8a1f83b0d3f 100644 --- a/subsys/logging/log_core.c +++ b/subsys/logging/log_core.c @@ -759,9 +759,9 @@ union log_msg_generic *z_log_msg_claim_oldest(k_timeout_t *backoff) * long processing shall back off. */ if (timestamp_freq == sys_clock_hw_cycles_per_sec()) { - *backoff = K_TICKS(diff); + *backoff = K_CYC(diff); } else { - *backoff = K_TICKS((diff * sys_clock_hw_cycles_per_sec()) / + *backoff = K_CYC((diff * sys_clock_hw_cycles_per_sec()) / timestamp_freq); } From af6264e4b92dfba47fc738150de3cb87aa150fe5 Mon Sep 17 00:00:00 2001 From: Armando Visconti Date: Wed, 26 Nov 2025 15:00:39 +0100 Subject: [PATCH 2379/3659] drivers/sensor: lsm6dsv16x: add device self test Add device Self Test procedure. It is required to enable the per device self-test DT property as well as the LSM6DSV16X_SELF_TEST configuration. Signed-off-by: Armando Visconti --- drivers/sensor/st/lsm6dsv16x/Kconfig | 7 + drivers/sensor/st/lsm6dsv16x/lsm6dsv16x.c | 249 ++++++++++++++++++ drivers/sensor/st/lsm6dsv16x/lsm6dsv16x.h | 5 + dts/bindings/sensor/st,lsm6dsvxxx-common.yaml | 6 + include/zephyr/drivers/sensor/lsm6dsvxxx.h | 44 ++++ 5 files changed, 311 insertions(+) create mode 100644 include/zephyr/drivers/sensor/lsm6dsvxxx.h diff --git a/drivers/sensor/st/lsm6dsv16x/Kconfig b/drivers/sensor/st/lsm6dsv16x/Kconfig index 06f713cf4a11..1b907ece5404 100644 --- a/drivers/sensor/st/lsm6dsv16x/Kconfig +++ b/drivers/sensor/st/lsm6dsv16x/Kconfig @@ -32,6 +32,13 @@ config LSM6DSV16X_STREAM help Use this config option to enable streaming sensor data via RTIO subsystem. +config LSM6DSV16X_SELF_TEST + bool "Self test attribute" + help + Enable support for configuring the sensor self test bits. + Refer to the datasheet of the sensor for a description of + the appropriate self test procedure. + choice LSM6DSV16X_TRIGGER_MODE default LSM6DSV16X_TRIGGER_GLOBAL_THREAD if LSM6DSV16X_STREAM default LSM6DSV16X_TRIGGER_NONE diff --git a/drivers/sensor/st/lsm6dsv16x/lsm6dsv16x.c b/drivers/sensor/st/lsm6dsv16x/lsm6dsv16x.c index 805e06ec7f7e..8bd621f11c2a 100644 --- a/drivers/sensor/st/lsm6dsv16x/lsm6dsv16x.c +++ b/drivers/sensor/st/lsm6dsv16x/lsm6dsv16x.c @@ -18,6 +18,7 @@ #include #include +#include #include #include "lsm6dsv16x.h" #include "lsm6dsv16x_decoder.h" @@ -282,6 +283,231 @@ static int lsm6dsv16x_accel_wake_duration_set(const struct device *dev, return lsm6dsv16x_act_thresholds_set(ctx, &thresholds); } +#ifdef CONFIG_LSM6DSV16X_SELF_TEST +/* Self test limits. */ +#define MIN_ST_LIMIT_mg 50.0f +#define MAX_ST_LIMIT_mg 1700.0f +#define MIN_ST_LIMIT_mdps 150000.0f +#define MAX_ST_LIMIT_mdps 700000.0f + +/* + * Accelerometer Self Test + */ +static int lsm6dsv16x_accel_self_test(const struct device *dev) +{ + const struct lsm6dsv16x_config *cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + lsm6dsv16x_data_ready_t drdy; + int16_t data_raw[3]; + float_t val_st_off[3]; + float_t val_st_on[3]; + float_t test_val[3]; + uint8_t i, j, st_result; + + /* Set Output Data Rate */ + lsm6dsv16x_xl_data_rate_set(ctx, LSM6DSV16X_ODR_AT_60Hz); + + /* Set full scale */ + lsm6dsv16x_xl_full_scale_set(ctx, LSM6DSV16X_4g); + + /* Wait stable output */ + k_msleep(100); + + /* Check if new value available */ + do { + lsm6dsv16x_flag_data_ready_get(ctx, &drdy); + } while (!drdy.drdy_xl); + + /* Read dummy data and discard it */ + lsm6dsv16x_acceleration_raw_get(ctx, data_raw); + + /* Read 5 sample and get the average vale for each axis */ + memset(val_st_off, 0x0, 3 * sizeof(float)); + + for (i = 0; i < 5; i++) { + /* Check if new value available */ + do { + lsm6dsv16x_flag_data_ready_get(ctx, &drdy); + } while (!drdy.drdy_xl); + + /* Read data and accumulate the mg value */ + lsm6dsv16x_acceleration_raw_get(ctx, data_raw); + + for (j = 0; j < 3; j++) { + val_st_off[j] += lsm6dsv16x_from_fs4_to_mg(data_raw[j]); + } + } + + /* Calculate the mg average values */ + for (i = 0; i < 3; i++) { + val_st_off[i] /= 5.0f; + } + + /* Enable Self Test negative */ + lsm6dsv16x_xl_self_test_set(ctx, LSM6DSV16X_XL_ST_NEGATIVE); + + /* Wait stable output */ + k_msleep(100); + + /* Check if new value available */ + do { + lsm6dsv16x_flag_data_ready_get(ctx, &drdy); + } while (!drdy.drdy_xl); + + /* Read dummy data and discard it */ + lsm6dsv16x_acceleration_raw_get(ctx, data_raw); + /* Read 5 sample and get the average vale for each axis */ + memset(val_st_on, 0x00, 3 * sizeof(float)); + + for (i = 0; i < 5; i++) { + /* Check if new value available */ + do { + lsm6dsv16x_flag_data_ready_get(ctx, &drdy); + } while (!drdy.drdy_xl); + + /* Read data and accumulate the mg value */ + lsm6dsv16x_acceleration_raw_get(ctx, data_raw); + + for (j = 0; j < 3; j++) { + val_st_on[j] += lsm6dsv16x_from_fs4_to_mg(data_raw[j]); + } + } + + /* Calculate the mg average values */ + for (i = 0; i < 3; i++) { + val_st_on[i] /= 5.0f; + } + + /* Calculate the mg values for self test */ + for (i = 0; i < 3; i++) { + test_val[i] = fabsf((val_st_on[i] - val_st_off[i])); + } + + /* Check self test limit */ + st_result = 0; + for (i = 0; i < 3; i++) { + if ((test_val[i] < MIN_ST_LIMIT_mg) || + (test_val[i] > MAX_ST_LIMIT_mg)) { + st_result = -1; + break; + } + } + + /* Disable Self Test */ + lsm6dsv16x_xl_self_test_set(ctx, LSM6DSV16X_XL_ST_DISABLE); + + /* Disable sensor. */ + lsm6dsv16x_xl_data_rate_set(ctx, LSM6DSV16X_ODR_OFF); + + LOG_INF("Accel self-test result: %s", st_result ? "FAIL" : "PASS"); + return st_result; +} + +/* + * Gyroscope Self Test + */ +static int lsm6dsv16x_gyro_self_test(const struct device *dev) +{ + const struct lsm6dsv16x_config *cfg = dev->config; + stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx; + lsm6dsv16x_data_ready_t drdy; + int16_t data_raw[3]; + float_t val_st_off[3]; + float_t val_st_on[3]; + float_t test_val[3]; + uint8_t i, j, st_result; + + /* Set Output Data Rate */ + lsm6dsv16x_gy_data_rate_set(ctx, LSM6DSV16X_ODR_AT_240Hz); + + /* Set full scale */ + lsm6dsv16x_gy_full_scale_set(ctx, LSM6DSV16X_2000dps); + + /* Wait stable output */ + k_msleep(100); + + /* Check if new value available */ + do { + lsm6dsv16x_flag_data_ready_get(ctx, &drdy); + } while (!drdy.drdy_gy); + + /* Read dummy data and discard it */ + lsm6dsv16x_angular_rate_raw_get(ctx, data_raw); + /* Read 5 sample and get the average vale for each axis */ + memset(val_st_off, 0x00, 3 * sizeof(float)); + + for (i = 0; i < 5; i++) { + /* Check if new value available */ + do { + lsm6dsv16x_flag_data_ready_get(ctx, &drdy); + } while (!drdy.drdy_gy); + /* Read data and accumulate the mg value */ + lsm6dsv16x_angular_rate_raw_get(ctx, data_raw); + + for (j = 0; j < 3; j++) { + val_st_off[j] += lsm6dsv16x_from_fs2000_to_mdps(data_raw[j]); + } + } + + /* Calculate the mg average values */ + for (i = 0; i < 3; i++) { + val_st_off[i] /= 5.0f; + } + + /* Enable Self Test positive (or negative) */ + lsm6dsv16x_gy_self_test_set(ctx, LSM6DSV16X_GY_ST_POSITIVE); + + /* Wait stable output */ + k_msleep(100); + + /* Read 5 sample and get the average vale for each axis */ + memset(val_st_on, 0x00, 3 * sizeof(float)); + + for (i = 0; i < 5; i++) { + /* Check if new value available */ + do { + lsm6dsv16x_flag_data_ready_get(ctx, &drdy); + } while (!drdy.drdy_gy); + + /* Read data and accumulate the mg value */ + lsm6dsv16x_angular_rate_raw_get(ctx, data_raw); + + for (j = 0; j < 3; j++) { + val_st_on[j] += lsm6dsv16x_from_fs2000_to_mdps(data_raw[j]); + } + } + + /* Calculate the mg average values */ + for (i = 0; i < 3; i++) { + val_st_on[i] /= 5.0f; + } + + /* Calculate the mg values for self test */ + for (i = 0; i < 3; i++) { + test_val[i] = fabsf((val_st_on[i] - val_st_off[i])); + } + + /* Check self test limit */ + st_result = 0; + for (i = 0; i < 3; i++) { + if ((test_val[i] < MIN_ST_LIMIT_mdps) || + (test_val[i] > MAX_ST_LIMIT_mdps)) { + st_result = -1; + break; + } + } + + /* Disable Self Test */ + lsm6dsv16x_gy_self_test_set(ctx, LSM6DSV16X_GY_ST_DISABLE); + + /* Disable sensor. */ + lsm6dsv16x_gy_data_rate_set(ctx, LSM6DSV16X_ODR_OFF); + + LOG_INF("Gyro self-test result: %s", st_result ? "FAIL" : "PASS"); + return st_result; +} +#endif + static int lsm6dsv16x_accel_config(const struct device *dev, enum sensor_channel chan, enum sensor_attribute attr, @@ -501,6 +727,12 @@ static int lsm6dsv16x_accel_get_config(const struct device *dev, struct lsm6dsv16x_data *data = dev->data; switch (attr) { +#ifdef CONFIG_LSM6DSV16X_SELF_TEST + case SENSOR_ATTR_GET_SELF_TEST_RESULT: + val->val1 = (data->xl_st_result == 0) ? LSM6DSVXXX_ST_OK : LSM6DSVXXX_ST_FAIL; + val->val2 = 0; + break; +#endif case SENSOR_ATTR_FULL_SCALE: sensor_g_to_ms2(cfg->accel_fs_map[data->accel_fs], val); break; @@ -573,6 +805,12 @@ static int lsm6dsv16x_gyro_get_config(const struct device *dev, struct lsm6dsv16x_data *data = dev->data; switch (attr) { +#ifdef CONFIG_LSM6DSV16X_SELF_TEST + case SENSOR_ATTR_GET_SELF_TEST_RESULT: + val->val1 = (data->gy_st_result == 0) ? 0 : 1; + val->val2 = 0; + break; +#endif case SENSOR_ATTR_FULL_SCALE: sensor_degrees_to_rad(lsm6dsv16x_gyro_fs_map[data->gyro_fs], val); break; @@ -1120,6 +1358,15 @@ static int lsm6dsv16x_init_chip(const struct device *dev) k_sleep(K_MSEC(30)); } +#ifdef CONFIG_LSM6DSV16X_SELF_TEST + lsm6dsv16x->xl_st_result = 0; + lsm6dsv16x->gy_st_result = 0; + if (cfg->self_test_en) { + lsm6dsv16x->xl_st_result = lsm6dsv16x_accel_self_test(dev); + lsm6dsv16x->gy_st_result = lsm6dsv16x_gyro_self_test(dev); + } +#endif + fs = cfg->accel_range; LOG_DBG("accel range is %d", fs); if (lsm6dsv16x_accel_set_fs_raw(dev, fs) < 0) { @@ -1281,6 +1528,8 @@ static int lsm6dsv16x_pm_action(const struct device *dev, enum pm_device_action #endif /* CONFIG_LSM6DSV16X_TRIGGER */ #define LSM6DSV16X_CONFIG_COMMON(inst, prefix) \ + IF_ENABLED(CONFIG_LSM6DSV16X_SELF_TEST, \ + (.self_test_en = DT_INST_PROP(inst, self_test),)) \ .accel_odr = DT_INST_PROP(inst, accel_odr), \ .accel_range = DT_INST_ENUM_IDX(inst, accel_range), \ .accel_fs_map = prefix##_accel_fs_map, \ diff --git a/drivers/sensor/st/lsm6dsv16x/lsm6dsv16x.h b/drivers/sensor/st/lsm6dsv16x/lsm6dsv16x.h index 9c21ffe6dd6b..6fa09aed4f0e 100644 --- a/drivers/sensor/st/lsm6dsv16x/lsm6dsv16x.h +++ b/drivers/sensor/st/lsm6dsv16x/lsm6dsv16x.h @@ -68,6 +68,9 @@ struct lsm6dsv16x_config { struct i3c_device_desc **i3c; #endif } stmemsc_cfg; +#ifdef CONFIG_LSM6DSV16X_SELF_TEST + uint8_t self_test_en; +#endif uint8_t accel_pm; uint8_t accel_odr; uint8_t accel_range; @@ -155,6 +158,8 @@ struct lsm6dsv16x_data { uint8_t shub_ext[LSM6DSV16X_SHUB_MAX_NUM_TARGETS]; #endif /* CONFIG_LSM6DSV16X_SENSORHUB */ + uint8_t xl_st_result; + uint8_t gy_st_result; uint8_t accel_freq; uint8_t accel_fs; uint8_t gyro_freq; diff --git a/dts/bindings/sensor/st,lsm6dsvxxx-common.yaml b/dts/bindings/sensor/st,lsm6dsvxxx-common.yaml index 133860e1a90f..604cb7a5263f 100644 --- a/dts/bindings/sensor/st,lsm6dsvxxx-common.yaml +++ b/dts/bindings/sensor/st,lsm6dsvxxx-common.yaml @@ -36,6 +36,12 @@ properties: mandatory and if not present it defaults to 1 which is the configuration at power-up. + self-test: + type: boolean + description: | + Enable device self-test procedure, which applies an electrostatic force to the sensor to + simulate acceleration and rotation without actually moving the device. + accel-odr: type: int default: 0x0 diff --git a/include/zephyr/drivers/sensor/lsm6dsvxxx.h b/include/zephyr/drivers/sensor/lsm6dsvxxx.h new file mode 100644 index 000000000000..effbe2bc64ee --- /dev/null +++ b/include/zephyr/drivers/sensor/lsm6dsvxxx.h @@ -0,0 +1,44 @@ +/* + * Copyright The Zephyr Project Contributors + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Header file for extended sensor API of LSM6DSVXXX sensor + * @ingroup lsm6dsvxxx_interface + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_SENSOR_LSM6DSVXXX_H_ +#define ZEPHYR_INCLUDE_DRIVERS_SENSOR_LSM6DSVXXX_H_ + +/** + * @defgroup lsm6dsvxxx_interface LSM6DSVXXX + * @ingroup sensor_interface_ext + * @brief ST Microelectronics LSM6DSVXXX 3-axis IMU family + * @{ + */ + +#include + +/** + * @brief Custom sensor attributes for LSM6DSVXXX + */ +enum sensor_attribute_lsm6dsvxxx { + /** + * Gets the self-test mode result in sensor_value.val1 field. + */ + SENSOR_ATTR_GET_SELF_TEST_RESULT = SENSOR_ATTR_PRIV_START, +}; + +enum lsm6dsvxxx_self_test_result { + LSM6DSVXXX_ST_OK = 0, + LSM6DSVXXX_ST_FAIL = 1, +}; + +/** + * @} + */ + +#endif /* ZEPHYR_INCLUDE_DRIVERS_SENSOR_LSM6DSVXXX_H_ */ From e9b257a1f9ad39163bdf6cec79e668e618eb7fe5 Mon Sep 17 00:00:00 2001 From: Rex Chen Date: Thu, 30 Oct 2025 11:58:44 +0900 Subject: [PATCH 2380/3659] manifest: hal_nxp: Add scan limit configure item Sync hal_nxp to add scan limit configure item. Signed-off-by: Rex Chen --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 55b322fa978b..9ab9b81e5ded 100644 --- a/west.yml +++ b/west.yml @@ -210,7 +210,7 @@ manifest: groups: - hal - name: hal_nxp - revision: 57b8fcad0337a803cbefd5ac635f8c5d37a7f806 + revision: 2f8883b3358e7be2101075cd0f00dd2e0fa68050 path: modules/hal/nxp groups: - hal From cbc881cc51f10686e04cc14b1ce4fcb05aaf3b15 Mon Sep 17 00:00:00 2001 From: Rex Chen Date: Thu, 30 Oct 2025 12:00:04 +0900 Subject: [PATCH 2381/3659] drivers: wifi: nxp: Add scan limit configure item Expose scan limit configuration to customer. Signed-off-by: Rex Chen --- drivers/wifi/nxp/Kconfig.nxp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/wifi/nxp/Kconfig.nxp b/drivers/wifi/nxp/Kconfig.nxp index c6c5e5764022..742666ce4d07 100644 --- a/drivers/wifi/nxp/Kconfig.nxp +++ b/drivers/wifi/nxp/Kconfig.nxp @@ -539,6 +539,12 @@ config NXP_WIFI_STA_RECONNECT This option enables Station auto reconnection support, when disconnected from current associated Access Point. +config NXP_WIFI_MAX_RECONNECT_LIMIT + int "Max reconnect limit" + default 5 + help + This option sets the max reconnect limit. + config NXP_WIFI_AUTO_POWER_SAVE bool "Automatically starts Power Save support" default y @@ -579,6 +585,12 @@ config NXP_WIFI_SCAN_CHANNEL_GAP help This option sets the max scan channel gap time between two scan commands. +config NXP_WIFI_MAX_RESCAN_LIMIT + int "Max scan limit" + default 30 + help + This option sets the max scan limit. + endmenu config NXP_WIFI_WMM_UAPSD From 42fcca480b4a82e2eceba55e0619d98de6dbf9fb Mon Sep 17 00:00:00 2001 From: Bernardo Perez Priego Date: Tue, 21 Oct 2025 16:42:20 -0700 Subject: [PATCH 2382/3659] drivers: i2c: microchip: Add mutex to transaction implementation Currently, I2C transfer implementation does not have a mutex to prevent multiple users from sending data at the same time, this could lead to devices malfunction due to mixing I2C transaction data. This patch adds mutex into transfer implementation to allow only one user to send data at the time. Signed-off-by: Bernardo Perez Priego --- drivers/i2c/i2c_mchp_xec_v2.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/i2c/i2c_mchp_xec_v2.c b/drivers/i2c/i2c_mchp_xec_v2.c index 4feda66823ef..34008b7b2422 100644 --- a/drivers/i2c/i2c_mchp_xec_v2.c +++ b/drivers/i2c/i2c_mchp_xec_v2.c @@ -106,6 +106,7 @@ struct i2c_xec_data { uint8_t i2c_ctrl; uint8_t i2c_addr; uint8_t i2c_status; + struct k_mutex mux; }; /* Recommended programming values based on 16MHz @@ -783,6 +784,7 @@ static int i2c_xec_transfer(const struct device *dev, struct i2c_msg *msgs, } #endif + k_mutex_lock(&data->mux, K_FOREVER); for (uint8_t i = 0; i < num_msgs; i++) { struct i2c_msg *m = &msgs[i]; @@ -798,6 +800,7 @@ static int i2c_xec_transfer(const struct device *dev, struct i2c_msg *msgs, break; } } + k_mutex_unlock(&data->mux); return ret; } @@ -1074,6 +1077,7 @@ static int i2c_xec_init(const struct device *dev) return ret; } + k_mutex_init(&data->mux); #ifdef CONFIG_I2C_TARGET const struct i2c_xec_config *config = (const struct i2c_xec_config *const) (dev->config); From c92d617855e477ca58a3015da57f48c0910ecf3b Mon Sep 17 00:00:00 2001 From: Mark Wang Date: Fri, 24 Oct 2025 15:27:38 +0800 Subject: [PATCH 2383/3659] bluetooth: shell: a2dp: use common function to check a2dp initialization Before every cmd, call one common function to check whether a2dp is initialized. Signed-off-by: Mark Wang --- subsys/bluetooth/host/classic/shell/a2dp.c | 58 ++++++++++------------ 1 file changed, 27 insertions(+), 31 deletions(-) diff --git a/subsys/bluetooth/host/classic/shell/a2dp.c b/subsys/bluetooth/host/classic/shell/a2dp.c index 2802731dab8a..e4d105a66f45 100644 --- a/subsys/bluetooth/host/classic/shell/a2dp.c +++ b/subsys/bluetooth/host/classic/shell/a2dp.c @@ -30,7 +30,7 @@ struct bt_a2dp *default_a2dp; static uint8_t a2dp_sink_sdp_registered; static uint8_t a2dp_source_sdp_registered; -static uint8_t a2dp_initied; +static bool a2dp_cb_registered; BT_A2DP_SBC_SINK_EP_DEFAULT(sink_sbc_endpoint); BT_A2DP_SBC_SOURCE_EP_DEFAULT(source_sbc_endpoint); struct bt_a2dp_codec_ie peer_sbc_capabilities; @@ -523,12 +523,22 @@ static struct bt_a2dp_cb a2dp_cb = { #endif }; +static int check_cb_registration(const struct shell *sh) +{ + if (!a2dp_cb_registered) { + shell_print(sh, "need to register a2dp connection callbacks"); + return -EIO; + } + + return 0; +} + static int cmd_register_cb(const struct shell *sh, int32_t argc, char *argv[]) { int err = -1; - if (a2dp_initied == 0) { - a2dp_initied = 1; + if (!a2dp_cb_registered) { + a2dp_cb_registered = true; err = bt_a2dp_register_cb(&a2dp_cb); if (!err) { @@ -549,8 +559,7 @@ static int cmd_register_ep(const struct shell *sh, int32_t argc, char *argv[]) const char *type; const char *action; - if (a2dp_initied == 0) { - shell_print(sh, "need to register a2dp connection callbacks"); + if (check_cb_registration(sh) != 0) { return -ENOEXEC; } @@ -597,8 +606,7 @@ static int cmd_register_ep(const struct shell *sh, int32_t argc, char *argv[]) static int cmd_connect(const struct shell *sh, int32_t argc, char *argv[]) { - if (a2dp_initied == 0) { - shell_print(sh, "need to register a2dp connection callbacks"); + if (check_cb_registration(sh) != 0) { return -ENOEXEC; } @@ -616,8 +624,7 @@ static int cmd_connect(const struct shell *sh, int32_t argc, char *argv[]) static int cmd_disconnect(const struct shell *sh, int32_t argc, char *argv[]) { - if (a2dp_initied == 0) { - shell_print(sh, "need to register a2dp connection callbacks"); + if (check_cb_registration(sh) != 0) { return -ENOEXEC; } @@ -650,8 +657,7 @@ static int cmd_configure(const struct shell *sh, int32_t argc, char *argv[]) { int err; - if (a2dp_initied == 0) { - shell_print(sh, "need to register a2dp connection callbacks"); + if (check_cb_registration(sh) != 0) { return -ENOEXEC; } @@ -682,8 +688,7 @@ static int cmd_configure(const struct shell *sh, int32_t argc, char *argv[]) static int cmd_reconfigure(const struct shell *sh, int32_t argc, char *argv[]) { - if (a2dp_initied == 0) { - shell_print(sh, "need to register a2dp connection callbacks"); + if (check_cb_registration(sh) != 0) { return -ENOEXEC; } @@ -720,8 +725,7 @@ static int cmd_get_peer_eps(const struct shell *sh, int32_t argc, char *argv[]) { int err = 0; - if (a2dp_initied == 0) { - shell_print(sh, "need to register a2dp connection callbacks"); + if (check_cb_registration(sh) != 0) { return -ENOEXEC; } @@ -746,8 +750,7 @@ static int cmd_get_peer_eps(const struct shell *sh, int32_t argc, char *argv[]) static int cmd_establish(const struct shell *sh, int32_t argc, char *argv[]) { - if (a2dp_initied == 0) { - shell_print(sh, "need to register a2dp connection callbacks"); + if (check_cb_registration(sh) != 0) { return -ENOEXEC; } @@ -759,8 +762,7 @@ static int cmd_establish(const struct shell *sh, int32_t argc, char *argv[]) static int cmd_release(const struct shell *sh, int32_t argc, char *argv[]) { - if (a2dp_initied == 0) { - shell_print(sh, "need to register a2dp connection callbacks"); + if (check_cb_registration(sh) != 0) { return -ENOEXEC; } @@ -772,8 +774,7 @@ static int cmd_release(const struct shell *sh, int32_t argc, char *argv[]) static int cmd_start(const struct shell *sh, int32_t argc, char *argv[]) { - if (a2dp_initied == 0) { - shell_print(sh, "need to register a2dp connection callbacks"); + if (check_cb_registration(sh) != 0) { return -ENOEXEC; } @@ -785,8 +786,7 @@ static int cmd_start(const struct shell *sh, int32_t argc, char *argv[]) static int cmd_suspend(const struct shell *sh, int32_t argc, char *argv[]) { - if (a2dp_initied == 0) { - shell_print(sh, "need to register a2dp connection callbacks"); + if (check_cb_registration(sh) != 0) { return -ENOEXEC; } @@ -798,8 +798,7 @@ static int cmd_suspend(const struct shell *sh, int32_t argc, char *argv[]) static int cmd_abort(const struct shell *sh, int32_t argc, char *argv[]) { - if (a2dp_initied == 0) { - shell_print(sh, "need to register a2dp connection callbacks"); + if (check_cb_registration(sh) != 0) { return -ENOEXEC; } @@ -815,8 +814,7 @@ static int cmd_send_media(const struct shell *sh, int32_t argc, char *argv[]) struct net_buf *buf; int ret; - if (a2dp_initied == 0) { - shell_print(sh, "need to register a2dp connection callbacks"); + if (check_cb_registration(sh) != 0) { return -ENOEXEC; } @@ -847,8 +845,7 @@ static int cmd_send_delay_report(const struct shell *sh, int32_t argc, char *arg { int err; - if (a2dp_initied == 0) { - shell_print(sh, "need to register a2dp connection callbacks"); + if (check_cb_registration(sh) != 0) { return -ENOEXEC; } @@ -863,8 +860,7 @@ static int cmd_send_delay_report(const struct shell *sh, int32_t argc, char *arg static int cmd_get_config(const struct shell *sh, int32_t argc, char *argv[]) { - if (a2dp_initied == 0) { - shell_print(sh, "need to register a2dp connection callbacks"); + if (check_cb_registration(sh) != 0) { return -ENOEXEC; } From 6f0b31c7091b3b203d27241f3eaa4903a9add1ff Mon Sep 17 00:00:00 2001 From: Mark Wang Date: Tue, 18 Nov 2025 15:50:32 +0800 Subject: [PATCH 2384/3659] bluetooth: shell: a2dp: improve a2dp shell cmds add abort req and rsp callbacks, improve register_ep cmd to support delay report, check buf tailroom for sending media, add get_conn cmd to test bt_a2dp_get_conn. Signed-off-by: Mark Wang --- subsys/bluetooth/host/classic/shell/a2dp.c | 73 +++++++++++++++++++++- 1 file changed, 70 insertions(+), 3 deletions(-) diff --git a/subsys/bluetooth/host/classic/shell/a2dp.c b/subsys/bluetooth/host/classic/shell/a2dp.c index e4d105a66f45..7d34e7b660c4 100644 --- a/subsys/bluetooth/host/classic/shell/a2dp.c +++ b/subsys/bluetooth/host/classic/shell/a2dp.c @@ -499,6 +499,22 @@ static void app_get_config_rsp(struct bt_a2dp_stream *stream, struct bt_a2dp_cod } } +static int app_abort_req(struct bt_a2dp_stream *stream, uint8_t *rsp_err_code) +{ + *rsp_err_code = 0; + bt_shell_print("receive requesting abort and accept"); + return 0; +} + +static void app_abort_rsp(struct bt_a2dp_stream *stream, uint8_t rsp_err_code) +{ + if (rsp_err_code == 0) { + bt_shell_print("success to abort"); + } else { + bt_shell_error("fail to abort"); + } +} + static struct bt_a2dp_cb a2dp_cb = { .connected = app_connected, .disconnected = app_disconnected, @@ -515,6 +531,8 @@ static struct bt_a2dp_cb a2dp_cb = { .reconfig_req = app_reconfig_req, .get_config_req = app_get_config_req, .get_config_rsp = app_get_config_rsp, + .abort_req = app_abort_req, + .abort_rsp = app_abort_rsp, #if defined(CONFIG_BT_A2DP_SOURCE) .delay_report_req = app_delay_report_req, #endif @@ -558,11 +576,24 @@ static int cmd_register_ep(const struct shell *sh, int32_t argc, char *argv[]) int err = -1; const char *type; const char *action; + bool delay_report; + bool set_delay_report = false; if (check_cb_registration(sh) != 0) { return -ENOEXEC; } + /* configure delay report */ + if (argc == 4) { + set_delay_report = true; + err = 0; + delay_report = shell_strtobool(argv[3], 10, &err); + if (err != 0) { + shell_help(sh); + return SHELL_CMD_HELP_PRINTED; + } + } + type = argv[1]; action = argv[2]; if (!strcmp(action, "sbc")) { @@ -571,6 +602,11 @@ static int cmd_register_ep(const struct shell *sh, int32_t argc, char *argv[]) a2dp_sink_sdp_registered = 1; bt_sdp_register_service(&a2dp_sink_rec); } + + if (set_delay_report) { + sink_sbc_endpoint.delay_report = delay_report; + } + err = bt_a2dp_register_ep(&sink_sbc_endpoint, BT_AVDTP_AUDIO, BT_AVDTP_SINK); if (!err) { @@ -582,6 +618,11 @@ static int cmd_register_ep(const struct shell *sh, int32_t argc, char *argv[]) a2dp_source_sdp_registered = 1; bt_sdp_register_service(&a2dp_source_rec); } + + if (set_delay_report) { + source_sbc_endpoint.delay_report = delay_report; + } + err = bt_a2dp_register_ep(&source_sbc_endpoint, BT_AVDTP_AUDIO, BT_AVDTP_SOURCE); if (!err) { @@ -813,6 +854,7 @@ static int cmd_send_media(const struct shell *sh, int32_t argc, char *argv[]) #if defined(CONFIG_BT_A2DP_SOURCE) struct net_buf *buf; int ret; + size_t data_len; if (check_cb_registration(sh) != 0) { return -ENOEXEC; @@ -824,9 +866,13 @@ static int cmd_send_media(const struct shell *sh, int32_t argc, char *argv[]) return -ENOEXEC; } + __ASSERT_NO_MSG(net_buf_tailroom(buf) >= sizeof(uint8_t)); /* num of frames is 1 */ net_buf_add_u8(buf, (uint8_t)BT_A2DP_SBC_MEDIA_HDR_ENCODE(1, 0, 0, 0)); - net_buf_add_mem(buf, media_data, sizeof(media_data)); + + data_len = min(min(sizeof(media_data), bt_a2dp_get_mtu(&sbc_stream)), + net_buf_tailroom(buf)); + net_buf_add_mem(buf, media_data, data_len); shell_print(sh, "num of frames: %d, data length: %d", 1U, sizeof(media_data)); shell_print(sh, "data: %d, %d, %d, %d, %d, %d ......", media_data[0], media_data[1], media_data[2], media_data[3], media_data[4], media_data[5]); @@ -870,13 +916,33 @@ static int cmd_get_config(const struct shell *sh, int32_t argc, char *argv[]) return 0; } +static int cmd_get_conn(const struct shell *sh, int32_t argc, char *argv[]) +{ + struct bt_conn *conn; + + if (check_cb_registration(sh) != 0) { + return -ENOEXEC; + } + + conn = bt_a2dp_get_conn(default_a2dp); + if (conn != NULL) { + shell_print(sh, "a2dp conn is: %p", conn); + bt_conn_unref(conn); + } else { + shell_print(sh, "a2dp conn is: NULL"); + } + + return 0; +} + #define HELP_NONE "[none]" SHELL_STATIC_SUBCMD_SET_CREATE(a2dp_cmds, SHELL_CMD_ARG(register_cb, NULL, "register a2dp connection callbacks", cmd_register_cb, 1, 0), - SHELL_CMD_ARG(register_ep, NULL, " ", - cmd_register_ep, 3, 0), + SHELL_CMD_ARG(register_ep, NULL, + " [delay report: true or false]", + cmd_register_ep, 3, 1), SHELL_CMD_ARG(connect, NULL, HELP_NONE, cmd_connect, 1, 0), SHELL_CMD_ARG(disconnect, NULL, HELP_NONE, cmd_disconnect, 1, 0), SHELL_CMD_ARG(discover_peer_eps, NULL, "", cmd_get_peer_eps, 2, 0), @@ -892,6 +958,7 @@ SHELL_STATIC_SUBCMD_SET_CREATE(a2dp_cmds, SHELL_CMD_ARG(send_delay_report, NULL, HELP_NONE, cmd_send_delay_report, 1, 0), #endif SHELL_CMD_ARG(get_config, NULL, HELP_NONE, cmd_get_config, 1, 0), + SHELL_CMD_ARG(get_conn, NULL, HELP_NONE, cmd_get_conn, 1, 0), SHELL_SUBCMD_SET_END ); From 37a048abefb59a1d8ebf757b7607781c9d331045 Mon Sep 17 00:00:00 2001 From: Mark Wang Date: Tue, 18 Nov 2025 15:52:45 +0800 Subject: [PATCH 2385/3659] doc: Bluetooth: shell: improve a2dp shell doc describe all the a2dp shell cmds. Signed-off-by: Mark Wang --- .../bluetooth/shell/classic/a2dp.rst | 163 ++++++++++++++---- 1 file changed, 133 insertions(+), 30 deletions(-) diff --git a/doc/connectivity/bluetooth/shell/classic/a2dp.rst b/doc/connectivity/bluetooth/shell/classic/a2dp.rst index 503214445ce7..48b1053487f5 100644 --- a/doc/connectivity/bluetooth/shell/classic/a2dp.rst +++ b/doc/connectivity/bluetooth/shell/classic/a2dp.rst @@ -5,33 +5,80 @@ The :code:`a2dp` command exposes parts of the A2DP API. The following examples assume that you have two devices already connected. -Here is a example connecting two devices: - * Source and Sink sides register a2dp callbacks. using :code:`a2dp register_cb`. - * Source and Sink sides register stream endpoints. using :code:`a2dp register_ep source sbc` and :code:`a2dp register_ep sink sbc`. - * Source establish A2dp connection. It will create the AVDTP Signaling and Media L2CAP channels. using :code:`a2dp connect`. - * Source and Sink side can discover remote device's stream endpoints. using :code:`a2dp discover_peer_eps` - * Source or Sink configure the stream to create the stream after discover remote's endpoints. using :code:`a2dp configure`. - * Source or Sink establish the stream. using :code:`a2dp establish`. - * Source or Sink start the media. using :code:`a2dp start`. - * Source test the media sending. using :code:`a2dp send_media` to send one test packet data. - * Source or Sink suspend the media. using :code:`a2dp suspend`. - * Source or Sink release the media. using :code:`a2dp release`. +.. _a2dp_conn_disconn: + +A2DP Connection +*************** + +Demonstrate the flow of creating an A2DP connection: + +* Both sides register A2DP callbacks using :code:`a2dp register_cb`. +* Either side establishes an A2DP connection, which will create the AVDTP Signaling channel, using :code:`a2dp connect`. +* Either side can get the ACL connection using :code:`a2dp get_conn`. +* Either side can disconnect the A2DP connection using :code:`a2dp disconnect`. .. tabs:: - .. group-tab:: Device A (Audio Source Side) + .. group-tab:: Device A (initiator) .. code-block:: console uart:~$ a2dp register_cb success - uart:~$ a2dp register_ep source sbc - SBC source endpoint is registered uart:~$ a2dp connect Bonded with XX:XX:XX:XX:XX:XX Security changed: XX:XX:XX:XX:XX:XX level 2 a2dp connected - uart:~$ a2dp discover_peer_eps + uart:~$ a2dp get_conn + a2dp conn is: 0xXXXXXXXX + uart:~$ a2dp disconnect + a2dp disconnected + + .. group-tab:: Device B (acceptor) + + .. code-block:: console + + uart:~$ a2dp register_cb + success + + Connected: XX:XX:XX:XX:XX:XX + Bonded with XX:XX:XX:XX:XX:XX + Security changed: XX:XX:XX:XX:XX:XX level 2 + a2dp connected + + a2dp disconnected + +.. _a2dp_basic_operations: + +Basic A2DP Operations +********************* + +Demonstrate the flow of basic A2DP operations: + +* Source and Sink sides register stream endpoints using :code:`a2dp register_ep source sbc` and :code:`a2dp register_ep sink sbc`. +* Create an A2DP connection based on :ref:`a2dp connection `. +* Initiator discovers remote device's stream endpoints using :code:`a2dp discover_peer_eps 0x0104`. +* Initiator configures the stream to create the stream after discovering remote endpoints using :code:`a2dp configure`. +* Initiator establishes the stream using :code:`a2dp establish`. +* Sink sends delay report using :code:`a2dp send_delay_report`. +* Initiator starts the media using :code:`a2dp start`. +* Source tests media sending using :code:`a2dp send_media` to send one test packet data. +* Initiator suspends the media using :code:`a2dp suspend`. +* Initiator releases the media using :code:`a2dp release`. + +.. note:: + The initiator is the A2DP source role and the acceptor is the A2DP sink role in the following logs. + The delay report can only be sent by the sink role. The media data can only be sent by the source role. + +.. tabs:: + + .. group-tab:: Device A (initiator) + + .. code-block:: console + + uart:~$ a2dp register_ep source sbc + SBC source endpoint is registered + uart:~$ a2dp discover_peer_eps 0x0104 endpoint id: 1, (sink), (idle): codec type: SBC sample frequency: @@ -54,6 +101,9 @@ Here is a example connecting two devices: uart:~$ a2dp establish success to establish stream established + + receive delay report and accept + received delay report: 1 1/10ms uart:~$ a2dp start success to start stream started @@ -67,36 +117,89 @@ Here is a example connecting two devices: success to release stream released - .. group-tab:: Device B (Audio Sink Side) + .. group-tab:: Device B (acceptor) .. code-block:: console - uart:~$ a2dp register_cb - success uart:~$ a2dp register_ep sink sbc SBC sink endpoint is registered - - Connected: XX:XX:XX:XX:XX:XX - Bonded with XX:XX:XX:XX:XX:XX - Security changed: XX:XX:XX:XX:XX:XX level 2 - a2dp connected - + receive requesting config and accept sample rate 44100Hz stream configured - + receive requesting establishment and accept stream established - + uart:~$ a2dp send_delay_report + success to send report delay + receive requesting start and accept stream started - + received, num of frames: 1, data length: 160 data: 1, 2, 3, 4, 5, 6 ...... - + receive requesting suspend and accept stream suspended - + receive requesting release and accept stream released - ... + +Abort Operation +*************** + +Demonstrate the abort operation: + +* Establish an A2DP stream based on :ref:`basic a2dp operations `. +* Initiator aborts the stream using :code:`a2dp abort`. + +.. tabs:: + + .. group-tab:: Device A (initiator) + + .. code-block:: console + + uart:~$ a2dp abort + success to abort + stream released + + .. group-tab:: Device B (acceptor) + + .. code-block:: console + + + receive requesting abort and accept + stream released + +Get Configuration and Reconfigure Operation +******************************************** + +Demonstrate the get configuration and reconfigure operations: + +* Establish an A2DP stream based on :ref:`basic a2dp operations `. +* Initiator gets configuration using :code:`a2dp get_config`. +* Initiator reconfigures the stream using :code:`a2dp reconfigure`. + +.. tabs:: + + .. group-tab:: Device A (initiator) + + .. code-block:: console + + uart:~$ a2dp get_config + get config result: 0 + sample rate 44100Hz + uart:~$ a2dp reconfigure + success to configure + stream configured + + .. group-tab:: Device B (acceptor) + + .. code-block:: console + + + receive get config request and accept + + receive requesting reconfig and accept + sample rate 44100Hz + stream configured From 36ab1ba154d5483b555fca935a5269b360dddb80 Mon Sep 17 00:00:00 2001 From: Mark Wang Date: Wed, 19 Nov 2025 14:45:51 +0800 Subject: [PATCH 2386/3659] Bluetooth: shell: a2dp: Update a2dp sdp profile version The newest a2dp spec set the profile version as 1.4. Signed-off-by: Mark Wang --- subsys/bluetooth/host/classic/shell/a2dp.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/subsys/bluetooth/host/classic/shell/a2dp.c b/subsys/bluetooth/host/classic/shell/a2dp.c index 7d34e7b660c4..2fae78c61896 100644 --- a/subsys/bluetooth/host/classic/shell/a2dp.c +++ b/subsys/bluetooth/host/classic/shell/a2dp.c @@ -61,6 +61,8 @@ NET_BUF_POOL_DEFINE(a2dp_tx_pool, CONFIG_BT_MAX_CONN, BT_L2CAP_BUF_SIZE(CONFIG_BT_L2CAP_TX_MTU), CONFIG_BT_CONN_TX_USER_DATA_SIZE, NULL); +#define A2DP_VERSION 0x0104U + static struct bt_sdp_attribute a2dp_sink_attrs[] = { BT_SDP_NEW_SERVICE, BT_SDP_LIST( @@ -118,7 +120,7 @@ static struct bt_sdp_attribute a2dp_sink_attrs[] = { }, { BT_SDP_TYPE_SIZE(BT_SDP_UINT16), /* 09 */ - BT_SDP_ARRAY_16(0x0103U) /* 01 03 */ + BT_SDP_ARRAY_16(A2DP_VERSION) /* 01 04 */ }, ) }, @@ -187,7 +189,7 @@ static struct bt_sdp_attribute a2dp_source_attrs[] = { }, { BT_SDP_TYPE_SIZE(BT_SDP_UINT16), - BT_SDP_ARRAY_16(0x0103U) + BT_SDP_ARRAY_16(A2DP_VERSION) }, ) }, From 313478b026c176ceb497ab0d6801bc34d0bec015 Mon Sep 17 00:00:00 2001 From: Mark Wang Date: Mon, 15 Dec 2025 17:09:43 +0800 Subject: [PATCH 2387/3659] bluetooth: shell: a2dp: use bt_shell_xxx instead of shell_xxx Replace all shell_print() and shell_error() calls with bt_shell_print() and bt_shell_error() respectively to use the common Bluetooth shell printing functions throughout the A2DP shell implementation. Signed-off-by: Mark Wang --- subsys/bluetooth/host/classic/shell/a2dp.c | 62 +++++++++++----------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/subsys/bluetooth/host/classic/shell/a2dp.c b/subsys/bluetooth/host/classic/shell/a2dp.c index 2fae78c61896..5f7133aec0d3 100644 --- a/subsys/bluetooth/host/classic/shell/a2dp.c +++ b/subsys/bluetooth/host/classic/shell/a2dp.c @@ -546,7 +546,7 @@ static struct bt_a2dp_cb a2dp_cb = { static int check_cb_registration(const struct shell *sh) { if (!a2dp_cb_registered) { - shell_print(sh, "need to register a2dp connection callbacks"); + bt_shell_print("need to register a2dp connection callbacks"); return -EIO; } @@ -562,12 +562,12 @@ static int cmd_register_cb(const struct shell *sh, int32_t argc, char *argv[]) err = bt_a2dp_register_cb(&a2dp_cb); if (!err) { - shell_print(sh, "success"); + bt_shell_print("success"); } else { - shell_print(sh, "fail"); + bt_shell_print("fail"); } } else { - shell_print(sh, "already registered"); + bt_shell_print("already registered"); } return 0; @@ -612,7 +612,7 @@ static int cmd_register_ep(const struct shell *sh, int32_t argc, char *argv[]) err = bt_a2dp_register_ep(&sink_sbc_endpoint, BT_AVDTP_AUDIO, BT_AVDTP_SINK); if (!err) { - shell_print(sh, "SBC sink endpoint is registered"); + bt_shell_print("SBC sink endpoint is registered"); registered_sbc_endpoint = &sink_sbc_endpoint; } } else if (!strcmp(type, "source")) { @@ -628,7 +628,7 @@ static int cmd_register_ep(const struct shell *sh, int32_t argc, char *argv[]) err = bt_a2dp_register_ep(&source_sbc_endpoint, BT_AVDTP_AUDIO, BT_AVDTP_SOURCE); if (!err) { - shell_print(sh, "SBC source endpoint is registered"); + bt_shell_print("SBC source endpoint is registered"); registered_sbc_endpoint = &source_sbc_endpoint; } } else { @@ -641,7 +641,7 @@ static int cmd_register_ep(const struct shell *sh, int32_t argc, char *argv[]) } if (err) { - shell_print(sh, "fail to register endpoint"); + bt_shell_print("fail to register endpoint"); } return 0; @@ -654,13 +654,13 @@ static int cmd_connect(const struct shell *sh, int32_t argc, char *argv[]) } if (!default_conn) { - shell_error(sh, "Not connected"); + bt_shell_error("Not connected"); return -ENOEXEC; } default_a2dp = bt_a2dp_connect(default_conn); if (NULL == default_a2dp) { - shell_error(sh, "fail to connect a2dp"); + bt_shell_error("fail to connect a2dp"); } return 0; } @@ -675,7 +675,7 @@ static int cmd_disconnect(const struct shell *sh, int32_t argc, char *argv[]) bt_a2dp_disconnect(default_a2dp); default_a2dp = NULL; } else { - shell_error(sh, "a2dp is not connected"); + bt_shell_error("a2dp is not connected"); } return 0; } @@ -706,12 +706,12 @@ static int cmd_configure(const struct shell *sh, int32_t argc, char *argv[]) if (default_a2dp != NULL) { if (registered_sbc_endpoint == NULL) { - shell_error(sh, "no endpoint"); + bt_shell_error("no endpoint"); return 0; } if (found_peer_sbc_endpoint == NULL) { - shell_error(sh, "don't find the peer sbc endpoint"); + bt_shell_error("don't find the peer sbc endpoint"); return 0; } @@ -721,10 +721,10 @@ static int cmd_configure(const struct shell *sh, int32_t argc, char *argv[]) registered_sbc_endpoint, found_peer_sbc_endpoint, &sbc_cfg_default); if (err) { - shell_error(sh, "fail to configure"); + bt_shell_error("fail to configure"); } } else { - shell_error(sh, "a2dp is not connected"); + bt_shell_error("a2dp is not connected"); } return 0; } @@ -736,7 +736,7 @@ static int cmd_reconfigure(const struct shell *sh, int32_t argc, char *argv[]) } if (bt_a2dp_stream_reconfig(&sbc_stream, &sbc_cfg_default) != 0) { - shell_print(sh, "fail"); + bt_shell_print("fail"); } return 0; } @@ -775,7 +775,7 @@ static int cmd_get_peer_eps(const struct shell *sh, int32_t argc, char *argv[]) if (default_a2dp != NULL) { discover_param.avdtp_version = (uint16_t)shell_strtoul(argv[1], 0, &err); if (err != 0) { - shell_error(sh, "failed to parse avdtp version: %d", err); + bt_shell_error("failed to parse avdtp version: %d", err); return -ENOEXEC; } @@ -783,10 +783,10 @@ static int cmd_get_peer_eps(const struct shell *sh, int32_t argc, char *argv[]) err = bt_a2dp_discover(default_a2dp, &discover_param); if (err) { - shell_error(sh, "discover fail"); + bt_shell_error("discover fail"); } } else { - shell_error(sh, "a2dp is not connected"); + bt_shell_error("a2dp is not connected"); } return 0; } @@ -798,7 +798,7 @@ static int cmd_establish(const struct shell *sh, int32_t argc, char *argv[]) } if (bt_a2dp_stream_establish(&sbc_stream) != 0) { - shell_print(sh, "fail"); + bt_shell_print("fail"); } return 0; } @@ -810,7 +810,7 @@ static int cmd_release(const struct shell *sh, int32_t argc, char *argv[]) } if (bt_a2dp_stream_release(&sbc_stream) != 0) { - shell_print(sh, "fail"); + bt_shell_print("fail"); } return 0; } @@ -822,7 +822,7 @@ static int cmd_start(const struct shell *sh, int32_t argc, char *argv[]) } if (bt_a2dp_stream_start(&sbc_stream) != 0) { - shell_print(sh, "fail"); + bt_shell_print("fail"); } return 0; } @@ -834,7 +834,7 @@ static int cmd_suspend(const struct shell *sh, int32_t argc, char *argv[]) } if (bt_a2dp_stream_suspend(&sbc_stream) != 0) { - shell_print(sh, "fail"); + bt_shell_print("fail"); } return 0; } @@ -846,7 +846,7 @@ static int cmd_abort(const struct shell *sh, int32_t argc, char *argv[]) } if (bt_a2dp_stream_abort(&sbc_stream) != 0) { - shell_print(sh, "fail"); + bt_shell_print("fail"); } return 0; } @@ -864,7 +864,7 @@ static int cmd_send_media(const struct shell *sh, int32_t argc, char *argv[]) buf = bt_a2dp_stream_create_pdu(&a2dp_tx_pool, K_FOREVER); if (buf == NULL) { - shell_error(sh, "fail to allocate buffer"); + bt_shell_error("fail to allocate buffer"); return -ENOEXEC; } @@ -875,8 +875,8 @@ static int cmd_send_media(const struct shell *sh, int32_t argc, char *argv[]) data_len = min(min(sizeof(media_data), bt_a2dp_get_mtu(&sbc_stream)), net_buf_tailroom(buf)); net_buf_add_mem(buf, media_data, data_len); - shell_print(sh, "num of frames: %d, data length: %d", 1U, sizeof(media_data)); - shell_print(sh, "data: %d, %d, %d, %d, %d, %d ......", media_data[0], + bt_shell_print("num of frames: %d, data length: %d", 1U, sizeof(media_data)); + bt_shell_print("data: %d, %d, %d, %d, %d, %d ......", media_data[0], media_data[1], media_data[2], media_data[3], media_data[4], media_data[5]); ret = bt_a2dp_stream_send(&sbc_stream, buf, 0U, 0U); @@ -899,7 +899,7 @@ static int cmd_send_delay_report(const struct shell *sh, int32_t argc, char *arg err = bt_a2dp_stream_delay_report(&sbc_stream, 1); if (err < 0) { - shell_print(sh, "fail to send delay report (%d)\n", err); + bt_shell_print("fail to send delay report (%d)\n", err); } return 0; @@ -913,7 +913,7 @@ static int cmd_get_config(const struct shell *sh, int32_t argc, char *argv[]) } if (bt_a2dp_stream_get_config(&sbc_stream) != 0) { - shell_error(sh, "fail"); + bt_shell_error("fail"); } return 0; } @@ -928,10 +928,10 @@ static int cmd_get_conn(const struct shell *sh, int32_t argc, char *argv[]) conn = bt_a2dp_get_conn(default_a2dp); if (conn != NULL) { - shell_print(sh, "a2dp conn is: %p", conn); + bt_shell_print("a2dp conn is: %p", conn); bt_conn_unref(conn); } else { - shell_print(sh, "a2dp conn is: NULL"); + bt_shell_print("a2dp conn is: NULL"); } return 0; @@ -972,7 +972,7 @@ static int cmd_a2dp(const struct shell *sh, size_t argc, char **argv) return 1; } - shell_error(sh, "%s unknown parameter: %s", argv[0], argv[1]); + bt_shell_error("%s unknown parameter: %s", argv[0], argv[1]); return -ENOEXEC; } From d8eb0ce5f4642394836cc28ccfe1116e772c3aa3 Mon Sep 17 00:00:00 2001 From: Mark Wang Date: Mon, 15 Dec 2025 17:15:51 +0800 Subject: [PATCH 2388/3659] bluetooth: shell: a2dp: use bt_shell_error for error messages Replace bt_shell_print() calls with bt_shell_error() for all error conditions and failure cases in the A2DP shell implementation to properly distinguish error messages from informational output. Signed-off-by: Mark Wang --- subsys/bluetooth/host/classic/shell/a2dp.c | 42 +++++++++++----------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/subsys/bluetooth/host/classic/shell/a2dp.c b/subsys/bluetooth/host/classic/shell/a2dp.c index 5f7133aec0d3..2dda7af9969c 100644 --- a/subsys/bluetooth/host/classic/shell/a2dp.c +++ b/subsys/bluetooth/host/classic/shell/a2dp.c @@ -295,7 +295,7 @@ static void app_connected(struct bt_a2dp *a2dp, int err) default_a2dp = a2dp; bt_shell_print("a2dp connected"); } else { - bt_shell_print("a2dp connecting fail"); + bt_shell_error("a2dp connecting fail"); } } @@ -342,7 +342,7 @@ static void app_config_rsp(struct bt_a2dp_stream *stream, uint8_t rsp_err_code) if (rsp_err_code == 0) { bt_shell_print("success to configure"); } else { - bt_shell_print("fail to configure"); + bt_shell_error("fail to configure"); } } @@ -358,7 +358,7 @@ static void app_establish_rsp(struct bt_a2dp_stream *stream, uint8_t rsp_err_cod if (rsp_err_code == 0) { bt_shell_print("success to establish"); } else { - bt_shell_print("fail to establish"); + bt_shell_error("fail to establish"); } } @@ -374,7 +374,7 @@ static void app_release_rsp(struct bt_a2dp_stream *stream, uint8_t rsp_err_code) if (rsp_err_code == 0) { bt_shell_print("success to release"); } else { - bt_shell_print("fail to release"); + bt_shell_error("fail to release"); } } @@ -390,7 +390,7 @@ static void app_start_rsp(struct bt_a2dp_stream *stream, uint8_t rsp_err_code) if (rsp_err_code == 0) { bt_shell_print("success to start"); } else { - bt_shell_print("fail to start"); + bt_shell_error("fail to start"); } } @@ -406,7 +406,7 @@ static void app_suspend_rsp(struct bt_a2dp_stream *stream, uint8_t rsp_err_code) if (rsp_err_code == 0) { bt_shell_print("success to suspend"); } else { - bt_shell_print("fail to suspend"); + bt_shell_error("fail to suspend"); } } @@ -462,7 +462,7 @@ static void app_delay_report_rsp(struct bt_a2dp_stream *stream, uint8_t rsp_err_ if (rsp_err_code == 0) { bt_shell_print("success to send report delay"); } else { - bt_shell_print("fail to send report delay"); + bt_shell_error("fail to send report delay"); } } #endif @@ -546,8 +546,8 @@ static struct bt_a2dp_cb a2dp_cb = { static int check_cb_registration(const struct shell *sh) { if (!a2dp_cb_registered) { - bt_shell_print("need to register a2dp connection callbacks"); - return -EIO; + bt_shell_error("need to register a2dp connection callbacks"); + return -ENOENT; } return 0; @@ -564,10 +564,10 @@ static int cmd_register_cb(const struct shell *sh, int32_t argc, char *argv[]) if (!err) { bt_shell_print("success"); } else { - bt_shell_print("fail"); + bt_shell_error("fail"); } } else { - bt_shell_print("already registered"); + bt_shell_error("already registered"); } return 0; @@ -641,7 +641,7 @@ static int cmd_register_ep(const struct shell *sh, int32_t argc, char *argv[]) } if (err) { - bt_shell_print("fail to register endpoint"); + bt_shell_error("fail to register endpoint"); } return 0; @@ -736,7 +736,7 @@ static int cmd_reconfigure(const struct shell *sh, int32_t argc, char *argv[]) } if (bt_a2dp_stream_reconfig(&sbc_stream, &sbc_cfg_default) != 0) { - bt_shell_print("fail"); + bt_shell_error("fail"); } return 0; } @@ -798,7 +798,7 @@ static int cmd_establish(const struct shell *sh, int32_t argc, char *argv[]) } if (bt_a2dp_stream_establish(&sbc_stream) != 0) { - bt_shell_print("fail"); + bt_shell_error("fail"); } return 0; } @@ -810,7 +810,7 @@ static int cmd_release(const struct shell *sh, int32_t argc, char *argv[]) } if (bt_a2dp_stream_release(&sbc_stream) != 0) { - bt_shell_print("fail"); + bt_shell_error("fail"); } return 0; } @@ -822,7 +822,7 @@ static int cmd_start(const struct shell *sh, int32_t argc, char *argv[]) } if (bt_a2dp_stream_start(&sbc_stream) != 0) { - bt_shell_print("fail"); + bt_shell_error("fail"); } return 0; } @@ -834,7 +834,7 @@ static int cmd_suspend(const struct shell *sh, int32_t argc, char *argv[]) } if (bt_a2dp_stream_suspend(&sbc_stream) != 0) { - bt_shell_print("fail"); + bt_shell_error("fail"); } return 0; } @@ -846,7 +846,7 @@ static int cmd_abort(const struct shell *sh, int32_t argc, char *argv[]) } if (bt_a2dp_stream_abort(&sbc_stream) != 0) { - bt_shell_print("fail"); + bt_shell_error("fail"); } return 0; } @@ -881,7 +881,7 @@ static int cmd_send_media(const struct shell *sh, int32_t argc, char *argv[]) ret = bt_a2dp_stream_send(&sbc_stream, buf, 0U, 0U); if (ret < 0) { - printk(" Failed to send SBC audio data on streams(%d)\n", ret); + bt_shell_error(" Failed to send SBC audio data on streams(%d)\n", ret); net_buf_unref(buf); } #endif @@ -899,7 +899,7 @@ static int cmd_send_delay_report(const struct shell *sh, int32_t argc, char *arg err = bt_a2dp_stream_delay_report(&sbc_stream, 1); if (err < 0) { - bt_shell_print("fail to send delay report (%d)\n", err); + bt_shell_error("fail to send delay report (%d)\n", err); } return 0; @@ -931,7 +931,7 @@ static int cmd_get_conn(const struct shell *sh, int32_t argc, char *argv[]) bt_shell_print("a2dp conn is: %p", conn); bt_conn_unref(conn); } else { - bt_shell_print("a2dp conn is: NULL"); + bt_shell_error("a2dp conn is: NULL"); } return 0; From f66ce9c251f93e12c1dde70cda22274a2867eba8 Mon Sep 17 00:00:00 2001 From: Mark Wang Date: Wed, 17 Dec 2025 13:40:18 +0800 Subject: [PATCH 2389/3659] bluetooth: shell: a2dp: include error code in failure messages Add error code parameter to all A2DP shell error messages to provide more detailed diagnostic information when operations fail. This applies to configure, establish, release, start, suspend, delay report, and abort response handlers. Signed-off-by: Mark Wang --- subsys/bluetooth/host/classic/shell/a2dp.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/subsys/bluetooth/host/classic/shell/a2dp.c b/subsys/bluetooth/host/classic/shell/a2dp.c index 2dda7af9969c..3e504926a338 100644 --- a/subsys/bluetooth/host/classic/shell/a2dp.c +++ b/subsys/bluetooth/host/classic/shell/a2dp.c @@ -342,7 +342,7 @@ static void app_config_rsp(struct bt_a2dp_stream *stream, uint8_t rsp_err_code) if (rsp_err_code == 0) { bt_shell_print("success to configure"); } else { - bt_shell_error("fail to configure"); + bt_shell_error("fail to configure (err code %u)", rsp_err_code); } } @@ -358,7 +358,7 @@ static void app_establish_rsp(struct bt_a2dp_stream *stream, uint8_t rsp_err_cod if (rsp_err_code == 0) { bt_shell_print("success to establish"); } else { - bt_shell_error("fail to establish"); + bt_shell_error("fail to establish (err code %u)", rsp_err_code); } } @@ -374,7 +374,7 @@ static void app_release_rsp(struct bt_a2dp_stream *stream, uint8_t rsp_err_code) if (rsp_err_code == 0) { bt_shell_print("success to release"); } else { - bt_shell_error("fail to release"); + bt_shell_error("fail to release (err code %u)", rsp_err_code); } } @@ -390,7 +390,7 @@ static void app_start_rsp(struct bt_a2dp_stream *stream, uint8_t rsp_err_code) if (rsp_err_code == 0) { bt_shell_print("success to start"); } else { - bt_shell_error("fail to start"); + bt_shell_error("fail to start (err code %u)", rsp_err_code); } } @@ -406,7 +406,7 @@ static void app_suspend_rsp(struct bt_a2dp_stream *stream, uint8_t rsp_err_code) if (rsp_err_code == 0) { bt_shell_print("success to suspend"); } else { - bt_shell_error("fail to suspend"); + bt_shell_error("fail to suspend (err code %u)", rsp_err_code); } } @@ -462,7 +462,7 @@ static void app_delay_report_rsp(struct bt_a2dp_stream *stream, uint8_t rsp_err_ if (rsp_err_code == 0) { bt_shell_print("success to send report delay"); } else { - bt_shell_error("fail to send report delay"); + bt_shell_error("fail to send report delay (err code %u)", rsp_err_code); } } #endif @@ -513,7 +513,7 @@ static void app_abort_rsp(struct bt_a2dp_stream *stream, uint8_t rsp_err_code) if (rsp_err_code == 0) { bt_shell_print("success to abort"); } else { - bt_shell_error("fail to abort"); + bt_shell_error("fail to abort (err code %u)", rsp_err_code); } } From 5e61c06c85fb6810d2e6923716d73e6db3d1e684 Mon Sep 17 00:00:00 2001 From: Ibrahim Abdalkader Date: Tue, 9 Dec 2025 17:25:29 +0100 Subject: [PATCH 2390/3659] drivers: i3c: Use kernel heap for allocations Use the kernel heap instead of the libc heap, improving security and consistency. Signed-off-by: Ibrahim Abdalkader --- drivers/i3c/Kconfig | 8 ++++++++ drivers/i3c/i3c_common.c | 5 +++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/i3c/Kconfig b/drivers/i3c/Kconfig index 3c08e726b886..a5dd8a253d1e 100644 --- a/drivers/i3c/Kconfig +++ b/drivers/i3c/Kconfig @@ -58,6 +58,14 @@ config I3C_TARGET_BUFFER_MODE help This is an option to enable buffer mode. +config HEAP_MEM_POOL_ADD_SIZE_I3C + int "Heap memory pool size for I3C" + default 48 + depends on I3C_CONTROLLER && I3C_TARGET + help + The size of the memory pool used by I3C. Used only for + DEFTGTS (Define List of Targets) CCC (Common Command Code). + menuconfig I3C_USE_IBI bool "Use In-Band Interrupt (IBI)" default y diff --git a/drivers/i3c/i3c_common.c b/drivers/i3c/i3c_common.c index ba543ec0a7a4..1a4ce9d3cc8c 100644 --- a/drivers/i3c/i3c_common.c +++ b/drivers/i3c/i3c_common.c @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -1327,7 +1328,7 @@ int i3c_bus_deftgts(const struct device *dev) } /* Allocate memory for the struct with enough space for the targets */ - deftgts = malloc(data_len); + deftgts = k_malloc(data_len); if (!deftgts) { return -ENOMEM; } @@ -1371,7 +1372,7 @@ int i3c_bus_deftgts(const struct device *dev) ret = i3c_ccc_do_deftgts_all(dev, deftgts); - free(deftgts); + k_free(deftgts); return ret; } From 2a432c65a2de9080e1c31d0e42c9eac47a55f379 Mon Sep 17 00:00:00 2001 From: Ibrahim Abdalkader Date: Tue, 2 Dec 2025 14:54:15 +0100 Subject: [PATCH 2391/3659] drivers: wifi: Use kernel heap for allocations Use the kernel heap instead of the libc heap, improving security and consistency. Signed-off-by: Ibrahim Abdalkader --- drivers/wifi/eswifi/eswifi_socket_offload.c | 14 +++++++------- drivers/wifi/simplelink/simplelink_sockets.c | 10 +++++----- samples/net/wifi/shell/prj.conf | 1 + tests/drivers/build_all/wifi/prj.conf | 1 + 4 files changed, 14 insertions(+), 12 deletions(-) diff --git a/drivers/wifi/eswifi/eswifi_socket_offload.c b/drivers/wifi/eswifi/eswifi_socket_offload.c index 0a527d116dd2..4cc3195f9c7b 100644 --- a/drivers/wifi/eswifi/eswifi_socket_offload.c +++ b/drivers/wifi/eswifi/eswifi_socket_offload.c @@ -701,7 +701,7 @@ static int eswifi_off_getaddrinfo(const char *node, const char *service, } /* Allocate out res (addrinfo) struct. Just one. */ - *res = calloc(1, sizeof(struct zsock_addrinfo)); + *res = k_calloc(1, sizeof(struct zsock_addrinfo)); ai = *res; if (!ai) { err = DNS_EAI_MEMORY; @@ -709,9 +709,9 @@ static int eswifi_off_getaddrinfo(const char *node, const char *service, } /* Now, alloc the embedded net_sockaddr struct: */ - ai_addr = calloc(1, sizeof(*ai_addr)); + ai_addr = k_calloc(1, sizeof(*ai_addr)); if (!ai_addr) { - free(*res); + k_free(*res); err = DNS_EAI_MEMORY; goto done_unlock; } @@ -724,8 +724,8 @@ static int eswifi_off_getaddrinfo(const char *node, const char *service, ai_addr->sin_port = net_htons(port); if (!net_ipaddr_parse(rsp, strlen(rsp), (struct net_sockaddr *)ai_addr)) { - free(ai_addr); - free(*res); + k_free(ai_addr); + k_free(*res); err = DNS_EAI_FAIL; goto done_unlock; } @@ -743,8 +743,8 @@ static void eswifi_off_freeaddrinfo(struct zsock_addrinfo *res) { __ASSERT_NO_MSG(res); - free(res->ai_addr); - free(res); + k_free(res->ai_addr); + k_free(res); } const struct socket_dns_offload eswifi_dns_ops = { diff --git a/drivers/wifi/simplelink/simplelink_sockets.c b/drivers/wifi/simplelink/simplelink_sockets.c index 7b031eed89a2..2066f9922177 100644 --- a/drivers/wifi/simplelink/simplelink_sockets.c +++ b/drivers/wifi/simplelink/simplelink_sockets.c @@ -996,16 +996,16 @@ static int set_addr_info(const struct SlNetUtil_addrInfo_t *sl_ai, struct net_sockaddr *ai_addr; int retval = 0; - ai = calloc(1, sizeof(struct zsock_addrinfo)); + ai = k_calloc(1, sizeof(struct zsock_addrinfo)); if (!ai) { retval = DNS_EAI_MEMORY; goto exit; } else { /* Now, alloc the embedded net_sockaddr struct: */ - ai_addr = calloc(1, sizeof(struct net_sockaddr)); + ai_addr = k_calloc(1, sizeof(struct net_sockaddr)); if (!ai_addr) { retval = DNS_EAI_MEMORY; - free(ai); + k_free(ai); goto exit; } } @@ -1130,8 +1130,8 @@ static void simplelink_freeaddrinfo(struct zsock_addrinfo *res) { __ASSERT_NO_MSG(res); - free(res->ai_addr); - free(res); + k_free(res->ai_addr); + k_free(res); } static int simplelink_fcntl(int sd, int cmd, va_list args) diff --git a/samples/net/wifi/shell/prj.conf b/samples/net/wifi/shell/prj.conf index e1a1b40a4098..ba3d9514ae04 100644 --- a/samples/net/wifi/shell/prj.conf +++ b/samples/net/wifi/shell/prj.conf @@ -36,3 +36,4 @@ CONFIG_NET_L2_WIFI_SHELL=y # environment. CONFIG_NET_MGMT_EVENT_QUEUE_TIMEOUT=5000 CONFIG_NET_MGMT_EVENT_QUEUE_SIZE=16 +CONFIG_HEAP_MEM_POOL_SIZE=2048 diff --git a/tests/drivers/build_all/wifi/prj.conf b/tests/drivers/build_all/wifi/prj.conf index 68df2c447211..4c44f089ef6c 100644 --- a/tests/drivers/build_all/wifi/prj.conf +++ b/tests/drivers/build_all/wifi/prj.conf @@ -4,3 +4,4 @@ CONFIG_WIFI=y CONFIG_GPIO=y CONFIG_NETWORKING=y CONFIG_NET_IPV4=y +CONFIG_HEAP_MEM_POOL_SIZE=2048 From afa47a276522902d6c07ded2c9e772067bdad138 Mon Sep 17 00:00:00 2001 From: Ibrahim Abdalkader Date: Tue, 2 Dec 2025 15:07:30 +0100 Subject: [PATCH 2392/3659] mgmt: mcumgr: grp: Use kernel heap for allocations Use the kernel heap instead of the libc heap, improving security and consistency. Signed-off-by: Ibrahim Abdalkader --- .../mgmt/mcumgr/grp/enum_mgmt/src/enum_mgmt.c | 6 ++--- subsys/mgmt/mcumgr/grp/settings_mgmt/Kconfig | 6 ++--- .../grp/settings_mgmt/src/settings_mgmt.c | 24 +++++++++---------- tests/subsys/mgmt/mcumgr/all_options/prj.conf | 1 + 4 files changed, 19 insertions(+), 18 deletions(-) diff --git a/subsys/mgmt/mcumgr/grp/enum_mgmt/src/enum_mgmt.c b/subsys/mgmt/mcumgr/grp/enum_mgmt/src/enum_mgmt.c index 31a93d94e3d3..574d24a4f308 100644 --- a/subsys/mgmt/mcumgr/grp/enum_mgmt/src/enum_mgmt.c +++ b/subsys/mgmt/mcumgr/grp/enum_mgmt/src/enum_mgmt.c @@ -351,7 +351,7 @@ static int enum_mgmt_details(struct smp_streamer *ctxt) if (entries > 0) { /* Return details on selected groups only */ #ifdef CONFIG_MCUMGR_GRP_ENUM_DETAILS_BUFFER_TYPE_HEAP - uint16_t *entry_list = malloc(sizeof(uint16_t) * entries); + uint16_t *entry_list = k_malloc(sizeof(uint16_t) * entries); #else uint16_t entry_list[CONFIG_MCUMGR_GRP_ENUM_DETAILS_BUFFER_TYPE_STACK_ENTRIES]; #endif @@ -375,7 +375,7 @@ static int enum_mgmt_details(struct smp_streamer *ctxt) if (!ok) { #ifdef CONFIG_MCUMGR_GRP_ENUM_DETAILS_BUFFER_TYPE_HEAP - free(entry_list); + k_free(entry_list); #endif return MGMT_ERR_EINVAL; @@ -392,7 +392,7 @@ static int enum_mgmt_details(struct smp_streamer *ctxt) cleanup: #ifdef CONFIG_MCUMGR_GRP_ENUM_DETAILS_BUFFER_TYPE_HEAP - free(entry_list); + k_free(entry_list); #endif if (!ok) { diff --git a/subsys/mgmt/mcumgr/grp/settings_mgmt/Kconfig b/subsys/mgmt/mcumgr/grp/settings_mgmt/Kconfig index c7d24062b6d2..c41fb63aa6b9 100644 --- a/subsys/mgmt/mcumgr/grp/settings_mgmt/Kconfig +++ b/subsys/mgmt/mcumgr/grp/settings_mgmt/Kconfig @@ -32,10 +32,10 @@ config MCUMGR_GRP_SETTINGS_BUFFER_TYPE_STACK config MCUMGR_GRP_SETTINGS_BUFFER_TYPE_HEAP bool "Heap (dynamic size)" - depends on COMMON_LIBC_MALLOC_ARENA_SIZE > 0 + depends on HEAP_MEM_POOL_SIZE > 0 help - Use dynamic heap memory allocation through malloc, if there is insufficient heap memory - for the allocation then the request will be rejected. + Use dynamic heap memory allocation through k_malloc, if there is insufficient heap + memory for the allocation then the request will be rejected. endchoice diff --git a/subsys/mgmt/mcumgr/grp/settings_mgmt/src/settings_mgmt.c b/subsys/mgmt/mcumgr/grp/settings_mgmt/src/settings_mgmt.c index bc14566927b1..cf252fc89001 100644 --- a/subsys/mgmt/mcumgr/grp/settings_mgmt/src/settings_mgmt.c +++ b/subsys/mgmt/mcumgr/grp/settings_mgmt/src/settings_mgmt.c @@ -75,12 +75,12 @@ static int settings_mgmt_read(struct smp_streamer *ctxt) } #ifdef CONFIG_MCUMGR_GRP_SETTINGS_BUFFER_TYPE_HEAP - key_name = (char *)malloc(key.len + 1); - data = (uint8_t *)malloc(max_size); + key_name = (char *)k_malloc(key.len + 1); + data = (uint8_t *)k_malloc(max_size); if (data == NULL || key_name == NULL) { if (key_name != NULL) { - free(key_name); + k_free(key_name); } return MGMT_ERR_ENOMEM; @@ -143,8 +143,8 @@ static int settings_mgmt_read(struct smp_streamer *ctxt) end: #ifdef CONFIG_MCUMGR_GRP_SETTINGS_BUFFER_TYPE_HEAP - free(key_name); - free(data); + k_free(key_name); + k_free(data); #endif return MGMT_RETURN_CHECK(ok); @@ -191,7 +191,7 @@ static int settings_mgmt_write(struct smp_streamer *ctxt) } #ifdef CONFIG_MCUMGR_GRP_SETTINGS_BUFFER_TYPE_HEAP - key_name = (char *)malloc(key.len + 1); + key_name = (char *)k_malloc(key.len + 1); if (key_name == NULL) { return MGMT_ERR_ENOMEM; @@ -247,7 +247,7 @@ static int settings_mgmt_write(struct smp_streamer *ctxt) end: #ifdef CONFIG_MCUMGR_GRP_SETTINGS_BUFFER_TYPE_HEAP - free(key_name); + k_free(key_name); #endif return MGMT_RETURN_CHECK(ok); @@ -292,7 +292,7 @@ static int settings_mgmt_delete(struct smp_streamer *ctxt) } #ifdef CONFIG_MCUMGR_GRP_SETTINGS_BUFFER_TYPE_HEAP - key_name = (char *)malloc(key.len + 1); + key_name = (char *)k_malloc(key.len + 1); if (key_name == NULL) { return MGMT_ERR_ENOMEM; @@ -331,7 +331,7 @@ static int settings_mgmt_delete(struct smp_streamer *ctxt) rc = settings_delete(key_name); #ifdef CONFIG_MCUMGR_GRP_SETTINGS_BUFFER_TYPE_HEAP - free(key_name); + k_free(key_name); #endif if (rc < 0) { @@ -476,7 +476,7 @@ static int settings_mgmt_save(struct smp_streamer *ctxt) } #ifdef CONFIG_MCUMGR_GRP_SETTINGS_BUFFER_TYPE_HEAP - key_name = (char *)malloc(key.len + 1); + key_name = (char *)k_malloc(key.len + 1); if (key_name == NULL) { return MGMT_ERR_ENOMEM; @@ -504,7 +504,7 @@ static int settings_mgmt_save(struct smp_streamer *ctxt) if (status != MGMT_CB_OK) { if (status == MGMT_CB_ERROR_RC) { #ifdef CONFIG_MCUMGR_GRP_SETTINGS_BUFFER_TYPE_HEAP - free(key_name); + k_free(key_name); #endif return ret_rc; } @@ -551,7 +551,7 @@ static int settings_mgmt_save(struct smp_streamer *ctxt) end: #ifdef CONFIG_MCUMGR_GRP_SETTINGS_BUFFER_TYPE_HEAP - free(key_name); + k_free(key_name); #endif return MGMT_RETURN_CHECK(ok); diff --git a/tests/subsys/mgmt/mcumgr/all_options/prj.conf b/tests/subsys/mgmt/mcumgr/all_options/prj.conf index 695cb6eb5cb4..b828c1761437 100644 --- a/tests/subsys/mgmt/mcumgr/all_options/prj.conf +++ b/tests/subsys/mgmt/mcumgr/all_options/prj.conf @@ -9,6 +9,7 @@ CONFIG_BASE64=y CONFIG_NET_BUF=y CONFIG_ZCBOR=y CONFIG_CRC=y +CONFIG_HEAP_MEM_POOL_SIZE=2048 CONFIG_FLASH=y CONFIG_FLASH_MAP=y CONFIG_STREAM_FLASH=y From 0c5e7a6a9530cf82b0a1551bac558a1a6418ae51 Mon Sep 17 00:00:00 2001 From: Ibrahim Abdalkader Date: Tue, 2 Dec 2025 15:37:44 +0100 Subject: [PATCH 2393/3659] sensing: sensor_mgmt: Use kernel heap for allocations Use the kernel heap instead of the libc heap, improving security and consistency. Signed-off-by: Ibrahim Abdalkader --- samples/subsys/sensing/simple/prj.conf | 1 + subsys/mgmt/mcumgr/grp/settings_mgmt/Kconfig | 2 +- subsys/sensing/sensor_mgmt.c | 4 ++-- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/samples/subsys/sensing/simple/prj.conf b/samples/subsys/sensing/simple/prj.conf index 1e935e973c76..3044bad5f3a8 100644 --- a/samples/subsys/sensing/simple/prj.conf +++ b/samples/subsys/sensing/simple/prj.conf @@ -1 +1,2 @@ CONFIG_LOG=y +CONFIG_HEAP_MEM_POOL_SIZE=2048 diff --git a/subsys/mgmt/mcumgr/grp/settings_mgmt/Kconfig b/subsys/mgmt/mcumgr/grp/settings_mgmt/Kconfig index c41fb63aa6b9..0cba22e2c35d 100644 --- a/subsys/mgmt/mcumgr/grp/settings_mgmt/Kconfig +++ b/subsys/mgmt/mcumgr/grp/settings_mgmt/Kconfig @@ -35,7 +35,7 @@ config MCUMGR_GRP_SETTINGS_BUFFER_TYPE_HEAP depends on HEAP_MEM_POOL_SIZE > 0 help Use dynamic heap memory allocation through k_malloc, if there is insufficient heap - memory for the allocation then the request will be rejected. + memory for the allocation then the request will be rejected. endchoice diff --git a/subsys/sensing/sensor_mgmt.c b/subsys/sensing/sensor_mgmt.c index 8b466fdae27f..955882361081 100644 --- a/subsys/sensing/sensor_mgmt.c +++ b/subsys/sensing/sensor_mgmt.c @@ -342,7 +342,7 @@ int open_sensor(struct sensing_sensor *sensor, struct sensing_connection **conn) } /* create connection from sensor to application(client = NULL) */ - tmp_conn = malloc(sizeof(*tmp_conn)); + tmp_conn = k_malloc(sizeof(*tmp_conn)); if (!tmp_conn) { return -ENOMEM; } @@ -371,7 +371,7 @@ int close_sensor(struct sensing_connection **conn) save_config_and_notify(tmp_conn->source); - free(*conn); + k_free(*conn); *conn = NULL; return 0; From 2acacec3f3f395e342fb5ba8241492a96ad39278 Mon Sep 17 00:00:00 2001 From: Dharun krithik k Date: Fri, 28 Nov 2025 12:54:00 +0530 Subject: [PATCH 2394/3659] dts: infineon: add watchdog node for PSoC4 Add the watchdog controller node to the PSoC4 SoC definition. Signed-off-by: Dharun krithik k Signed-off-by: Sayooj K Karun --- dts/arm/infineon/psoc4/psoc4100tp/psoc4100tp.dtsi | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/dts/arm/infineon/psoc4/psoc4100tp/psoc4100tp.dtsi b/dts/arm/infineon/psoc4/psoc4100tp/psoc4100tp.dtsi index ba02c71345c0..662c0e4f7969 100644 --- a/dts/arm/infineon/psoc4/psoc4100tp/psoc4100tp.dtsi +++ b/dts/arm/infineon/psoc4/psoc4100tp/psoc4100tp.dtsi @@ -128,6 +128,13 @@ status = "disabled"; }; + watchdog0: watchdog@40030000 { + compatible = "infineon,watchdog"; + reg = <0x40030000 0xf1c>; + interrupts = <5 0>; + status = "disabled"; + }; + tcpwm0: tcpwm0@40200000 { reg = <0x40200000 0x280>; #address-cells = <1>; From 8eec4c5fc46a798dfd46c558f62ae020b30b6df2 Mon Sep 17 00:00:00 2001 From: Dharun krithik k Date: Sat, 29 Nov 2025 04:02:43 +0530 Subject: [PATCH 2395/3659] boards: cy8cproto_041tp: enable watchdog Enable the watchdog0 node and add an alias for it on the CY8CPROTO-041TP board. Signed-off-by: Dharun krithik k Signed-off-by: Sayooj K Karun --- .../cy8cproto_041tp/cy8cproto_041tp_common.dtsi | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/boards/infineon/cy8cproto_041tp/cy8cproto_041tp_common.dtsi b/boards/infineon/cy8cproto_041tp/cy8cproto_041tp_common.dtsi index aebc94f0ce7c..e04a69d11ef2 100644 --- a/boards/infineon/cy8cproto_041tp/cy8cproto_041tp_common.dtsi +++ b/boards/infineon/cy8cproto_041tp/cy8cproto_041tp_common.dtsi @@ -8,6 +8,12 @@ #include #include "cy8cproto_041tp-pinctrl.dtsi" +/ { + aliases { + watchdog0 = &watchdog0; + }; +}; + uart0: &scb0 { compatible = "infineon,uart"; status = "okay"; @@ -71,3 +77,7 @@ uart0: &scb0 { status = "okay"; interrupts = <4 4>; }; + +&watchdog0 { + status = "okay"; +}; From 682493add902852b3c600d66c4667a96061afe10 Mon Sep 17 00:00:00 2001 From: Dharun krithik k Date: Sat, 29 Nov 2025 04:01:52 +0530 Subject: [PATCH 2396/3659] drivers: watchdog: infineon: add PSoC4 support Add support for the Infineon PSoC4 family to the infineon watchdog driver. PSoC4 specific ILO frequency and tick period definitions. Initialization and configuration logic specific to PSoC4. Signed-off-by: Dharun krithik k Signed-off-by: Sayooj K Karun --- drivers/watchdog/wdt_infineon.c | 115 ++++++++++++++++++++++++++++---- 1 file changed, 101 insertions(+), 14 deletions(-) diff --git a/drivers/watchdog/wdt_infineon.c b/drivers/watchdog/wdt_infineon.c index 7fdb7bc2b19b..8c2a80a05907 100644 --- a/drivers/watchdog/wdt_infineon.c +++ b/drivers/watchdog/wdt_infineon.c @@ -9,6 +9,7 @@ #define DT_DRV_COMPAT infineon_watchdog +#include #include "cy_wdt.h" #include "cy_sysclk.h" @@ -18,7 +19,7 @@ #include LOG_MODULE_REGISTER(wdt_infineon, CONFIG_WDT_LOG_LEVEL); -#define IFX_CAT1_WDT_IS_IRQ_EN DT_NODE_HAS_PROP(DT_DRV_INST(0), interrupts) +#define IFX_WDT_IS_IRQ_EN DT_NODE_HAS_PROP(DT_DRV_INST(0), interrupts) typedef struct { /* Minimum period in milliseconds that can be represented with this many ignored bits */ @@ -43,7 +44,7 @@ typedef struct { #else #define IFX_WDT_MATCH_BITS (32) #endif -#elif defined(COMPONENT_CAT1B) +#elif defined(COMPONENT_CAT1B) || defined(CY_IP_S8SRSSLT) #define IFX_WDT_MATCH_BITS (16) #else #error Unhandled device type @@ -78,6 +79,27 @@ static const wdt_ignore_bits_data_t ifx_wdt_ignore_data[] = { {1, 1}, /* 12 bit(s): min period: 1ms, max period: 1ms, round up from 1+ms */ }; #endif +#elif defined(CY_IP_S8SRSSLT) +#define IFX_WDT_MAX_TIMEOUT_MS 4915 +#define IFX_WDT_MAX_IGNORE_BITS 12 +/* Cy_SysClk_IloCompensate function execution time is always ~ 1ms */ +#define IFX_ILO_COMPENSATE_TIMEOUT_MS 2 + +static const wdt_ignore_bits_data_t ifx_wdt_ignore_data[] = { + {3072, 2305}, /* 0 bit(s): min period: 3072ms, max period: 4915ms, round up from 2305+ms */ + {1536, 1153}, /* 1 bit(s): min period: 1536ms, max period: 2458ms, round up from 1153+ms */ + {768, 577}, /* 2 bit(s): min period: 768ms, max period: 1229ms, round up from 577+ms */ + {384, 289}, /* 3 bit(s): min period: 384ms, max period: 614ms, round up from 289+ms */ + {192, 145}, /* 4 bit(s): min period: 192ms, max period: 307ms, round up from 145+ms */ + {96, 73}, /* 5 bit(s): min period: 96ms, max period: 154ms, round up from 73+ms */ + {48, 37}, /* 6 bit(s): min period: 48ms, max period: 77ms, round up from 37+ms */ + {24, 19}, /* 7 bit(s): min period: 24ms, max period: 38ms, round up from 19+ms */ + {12, 10}, /* 8 bit(s): min period: 12ms, max period: 19ms, round up from 10+ms */ + {6, 5}, /* 9 bit(s): min period: 6ms, max period: 10ms, round up from 5+ms */ + {3, 3}, /* 10 bit(s): min period: 3ms, max period: 5ms, round up from 3+ms */ + {2, 2}, /* 11 bit(s): min period: 2ms, max period: 2ms, round up from 2+ms */ + {1, 1}, /* 12 bit(s): min period: 1ms, max period: 1ms, round up from 1+ms */ +}; #elif (defined(CY_IP_MXS40SSRSS) || defined(CY_IP_MXS22SRSS)) && (IFX_WDT_MATCH_BITS == 22) /* ILO Frequency = 32768 Hz, ILO Period = 1 / 32768 Hz = .030518 ms */ #define IFX_WDT_MAX_TIMEOUT_MS 384000 @@ -195,25 +217,49 @@ struct ifx_cat1_wdt_data { uint32_t wdt_initial_timeout_ms; uint32_t wdt_rounded_timeout_ms; uint32_t wdt_ignore_bits; -#ifdef IFX_CAT1_WDT_IS_IRQ_EN +#ifdef IFX_WDT_IS_IRQ_EN wdt_callback_t callback; #endif uint32_t timeout; bool timeout_installed; +#if defined(CY_IP_S8SRSSLT) + uint32_t ilo_compensated_counts; +#endif }; static struct ifx_cat1_wdt_data wdt_data; +#if !defined(CY_IP_S8SRSSLT) #define IFX_DETERMINE_MATCH_BITS(bits) ((IFX_WDT_MAX_IGNORE_BITS) - (bits)) #define IFX_GET_COUNT_FROM_MATCH_BITS(bits) (2UL << IFX_DETERMINE_MATCH_BITS(bits)) +#endif -__STATIC_INLINE uint32_t ifx_wdt_timeout_to_match(uint32_t timeout_ms, uint32_t ignore_bits) +__STATIC_INLINE uint32_t ifx_wdt_timeout_to_match(uint32_t timeout_ms, uint32_t ignore_bits, + struct ifx_cat1_wdt_data *dev_data) { +#if defined(CY_IP_S8SRSSLT) + ARG_UNUSED(timeout_ms); + ARG_UNUSED(ignore_bits); + + uint32_t match_count; + + match_count = (Cy_WDT_GetMatch() + dev_data->ilo_compensated_counts); + + /* Ensure match count is within valid range for 16-bit WDT */ + if (match_count > UINT16_MAX) { + match_count = UINT16_MAX; + } + + return match_count; +#else + ARG_UNUSED(dev_data); + uint32_t wrap_count_for_ignore_bits = (IFX_GET_COUNT_FROM_MATCH_BITS(ignore_bits)); uint32_t timeout_count = ((timeout_ms * CY_SYSCLK_ILO_FREQ) / 1000UL); /* handle multiple possible wraps of WDT counter */ timeout_count = ((timeout_count + Cy_WDT_GetCount()) % wrap_count_for_ignore_bits); return timeout_count; +#endif } /* Rounds up *timeout_ms if it's outside of the valid timeout range (ifx_wdt_ignore_data) */ @@ -230,7 +276,7 @@ __STATIC_INLINE uint32_t ifx_wdt_timeout_to_ignore_bits(uint32_t *timeout_ms) return IFX_WDT_MAX_IGNORE_BITS; /* Ideally should never reach this */ } -#ifdef IFX_CAT1_WDT_IS_IRQ_EN +#ifdef IFX_WDT_IS_IRQ_EN static void ifx_cat1_wdt_isr_handler(const struct device *dev) { struct ifx_cat1_wdt_data *dev_data = dev->data; @@ -265,8 +311,39 @@ static int ifx_cat1_wdt_setup(const struct device *dev, uint8_t options) Cy_WDT_MaskInterrupt(); dev_data->wdt_initial_timeout_ms = dev_data->timeout; -#if defined(CY_IP_MXS40SRSS) && (CY_IP_MXS40SRSS_VERSION >= 2) - Cy_WDT_SetUpperLimit(ifx_wdt_timeout_to_match(dev_data->wdt_initial_timeout_ms)); + +#if defined(CY_IP_S8SRSSLT) + Cy_SysClk_IloStartMeasurement(); + + dev_data->wdt_ignore_bits = ifx_wdt_timeout_to_ignore_bits(&dev_data->timeout); + dev_data->wdt_rounded_timeout_ms = dev_data->timeout; + + uint32_t desired_delay_us = dev_data->wdt_rounded_timeout_ms * 1000UL; + cy_en_sysclk_status_t res; + + /* Add timeout to prevent infinite hang */ + uint32_t start = k_cycle_get_32(); + uint32_t timeout_cycles = k_ms_to_cyc_ceil32(IFX_ILO_COMPENSATE_TIMEOUT_MS); + + for (;;) { + res = Cy_SysClk_IloCompensate(desired_delay_us, &dev_data->ilo_compensated_counts); + if (res == CY_SYSCLK_SUCCESS) { + break; + } + if (res == CY_SYSCLK_BAD_PARAM || res == CY_SYSCLK_INVALID_STATE) { + return -EIO; + } + if ((k_cycle_get_32() - start) > timeout_cycles) { + return -ETIMEDOUT; + } + k_yield(); + } + + Cy_WDT_SetIgnoreBits(dev_data->wdt_ignore_bits); + Cy_WDT_SetMatch(dev_data->ilo_compensated_counts); +#elif defined(CY_IP_MXS40SRSS) && (CY_IP_MXS40SRSS_VERSION >= 2) + Cy_WDT_SetUpperLimit(ifx_wdt_timeout_to_match(dev_data->wdt_initial_timeout_ms, + dev_data->wdt_ignore_bits, dev_data)); Cy_WDT_SetUpperAction(CY_WDT_LOW_UPPER_LIMIT_ACTION_RESET); #else dev_data->wdt_ignore_bits = ifx_wdt_timeout_to_ignore_bits(&dev_data->timeout); @@ -289,9 +366,8 @@ static int ifx_cat1_wdt_setup(const struct device *dev, uint8_t options) /* Twice, as reading back after 1 reset gives same value as before single reset */ Cy_WDT_ResetCounter(); #endif - Cy_WDT_SetMatch(ifx_wdt_timeout_to_match(dev_data->wdt_rounded_timeout_ms, - dev_data->wdt_ignore_bits)); + dev_data->wdt_ignore_bits, dev_data)); #endif ifx_wdt_unlock(); @@ -304,7 +380,7 @@ static int ifx_cat1_wdt_setup(const struct device *dev, uint8_t options) return -ENOMSG; } -#ifdef IFX_CAT1_WDT_IS_IRQ_EN +#ifdef IFX_WDT_IS_IRQ_EN if (dev_data->callback) { Cy_WDT_UnmaskInterrupt(); irq_enable(DT_INST_IRQN(0)); @@ -318,11 +394,16 @@ static int ifx_cat1_wdt_disable(const struct device *dev) { struct ifx_cat1_wdt_data *dev_data = dev->data; -#ifdef IFX_CAT1_WDT_IS_IRQ_EN +#ifdef IFX_WDT_IS_IRQ_EN Cy_WDT_MaskInterrupt(); irq_disable(DT_INST_IRQN(0)); #endif +#if defined(CY_IP_S8SRSSLT) + Cy_SysClk_IloStopMeasurement(); + dev_data->ilo_compensated_counts = 0; +#endif + ifx_wdt_unlock(); Cy_WDT_Disable(); ifx_wdt_lock(); @@ -346,7 +427,7 @@ static int ifx_cat1_wdt_install_timeout(const struct device *dev, const struct w } if (cfg->callback) { -#ifndef IFX_CAT1_WDT_IS_IRQ_EN +#ifndef IFX_WDT_IS_IRQ_EN LOG_WRN("Interrupt is not configured, can't set a callback."); #else dev_data->callback = cfg->callback; @@ -374,8 +455,10 @@ static int ifx_cat1_wdt_feed(const struct device *dev, int channel_id) ifx_wdt_unlock(); Cy_WDT_ClearWatchdog(); /* Clear to prevent reset from WDT */ + Cy_WDT_SetMatch(ifx_wdt_timeout_to_match(data->wdt_rounded_timeout_ms, - data->wdt_ignore_bits)); + data->wdt_ignore_bits, data)); + ifx_wdt_lock(); return 0; @@ -384,7 +467,7 @@ static int ifx_cat1_wdt_feed(const struct device *dev, int channel_id) static int ifx_cat1_wdt_init(const struct device *dev) { struct ifx_cat1_wdt_data *data = dev->data; -#ifdef IFX_CAT1_WDT_IS_IRQ_EN +#ifdef IFX_WDT_IS_IRQ_EN /* Connect WDT interrupt to ISR */ IRQ_CONNECT(DT_INST_IRQN(0), DT_INST_IRQ(0, priority), ifx_cat1_wdt_isr_handler, DEVICE_DT_INST_GET(0), 0); @@ -394,6 +477,10 @@ static int ifx_cat1_wdt_init(const struct device *dev) data->wdt_initial_timeout_ms = 0; data->wdt_rounded_timeout_ms = 0; +#if defined(CY_IP_S8SRSSLT) + data->ilo_compensated_counts = 0; +#endif + return 0; } From 0777dbea02849c89d8089192dca96188b49f3dd3 Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Fri, 19 Dec 2025 11:09:13 -0800 Subject: [PATCH 2397/3659] xtensa: mmu: assert when L2 table allocation fails during dup Add an assertions to halt the system if L2 table allocation fails when we need to duplicate an existing L2 table, as it is a must-have and must-success operation. Signed-off-by: Daniel Leung --- arch/xtensa/core/ptables.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/arch/xtensa/core/ptables.c b/arch/xtensa/core/ptables.c index b9d5bf2dcda2..6bcf8c104562 100644 --- a/arch/xtensa/core/ptables.c +++ b/arch/xtensa/core/ptables.c @@ -968,8 +968,14 @@ static uint32_t *dup_l2_table(uint32_t *src_l2_table, enum dup_action action) uint32_t *l2_table; l2_table = alloc_l2_table(); + + /* Duplicating L2 tables is a must-have and must-success operation. + * If we are running out of free L2 tables to be allocated, we cannot + * continue. + */ + __ASSERT_NO_MSG(l2_table != NULL); if (l2_table == NULL) { - return NULL; + arch_system_halt(K_ERR_KERNEL_PANIC); } switch (action) { From 82b7d94d4526a2bd6fd0fe32950926fe423209d8 Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Fri, 19 Dec 2025 11:26:54 -0800 Subject: [PATCH 2398/3659] xtensa: mmu: add debug logs on page table allocations Adds some debug logs when we are allocating page tables. This provides a more visible way of seeing whether we need to have more free tables. Signed-off-by: Daniel Leung --- arch/xtensa/core/ptables.c | 39 +++++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/arch/xtensa/core/ptables.c b/arch/xtensa/core/ptables.c index 6bcf8c104562..0370bb3885ed 100644 --- a/arch/xtensa/core/ptables.c +++ b/arch/xtensa/core/ptables.c @@ -326,6 +326,26 @@ static void init_page_table(uint32_t *ptable, size_t num_entries, uint32_t val) } } +static void calc_l2_page_tables_usage(void) +{ +#ifdef CONFIG_XTENSA_MMU_PAGE_TABLE_STATS + uint32_t cur_l2_usage = 0; + + /* Calculate how many L2 page tables are being used now. */ + for (int idx = 0; idx < CONFIG_XTENSA_MMU_NUM_L2_TABLES; idx++) { + if (l2_page_tables_counter[idx] > 0) { + cur_l2_usage++; + } + } + + /* Store the bigger number. */ + l2_page_tables_max_usage = MAX(l2_page_tables_max_usage, cur_l2_usage); + + LOG_DBG("L2 page table usage %u/%u/%u", cur_l2_usage, l2_page_tables_max_usage, + CONFIG_XTENSA_MMU_NUM_L2_TABLES); +#endif /* CONFIG_XTENSA_MMU_PAGE_TABLE_STATS */ +} + /** * @brief Find the L2 table counter array index from L2 table pointer. * @@ -357,19 +377,7 @@ static inline uint32_t *alloc_l2_table(void) } } -#ifdef CONFIG_XTENSA_MMU_PAGE_TABLE_STATS - uint32_t cur_l2_usage = 0; - - /* Calculate how many L2 page tables are being used now. */ - for (idx = 0; idx < CONFIG_XTENSA_MMU_NUM_L2_TABLES; idx++) { - if (l2_page_tables_counter[idx] > 0) { - cur_l2_usage++; - } - } - - /* Store the bigger number. */ - l2_page_tables_max_usage = MAX(l2_page_tables_max_usage, cur_l2_usage); -#endif /* CONFIG_XTENSA_MMU_PAGE_TABLE_STATS */ + calc_l2_page_tables_usage(); k_spin_unlock(&xtensa_counter_lock, key); @@ -716,6 +724,8 @@ static void l2_page_table_unmap(uint32_t *l1_table, void *vaddr) K_SPINLOCK(&xtensa_counter_lock) { l2_page_tables_counter_dec(l2_table); + + calc_l2_page_tables_usage(); } end: @@ -946,6 +956,9 @@ static inline uint32_t *alloc_l1_table(void) /* Store the bigger number. */ l1_page_tables_max_usage = MAX(l1_page_tables_max_usage, cur_l1_usage); + + LOG_DBG("L1 page table usage %u/%u/%u", cur_l1_usage, l1_page_tables_max_usage, + CONFIG_XTENSA_MMU_NUM_L1_TABLES); #endif /* CONFIG_XTENSA_MMU_PAGE_TABLE_STATS */ return ret; From 50e980d9a8329832e74a5a1ffcce81f947c7cf41 Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Mon, 22 Dec 2025 11:57:10 -0800 Subject: [PATCH 2399/3659] xtensa: mmu: halt system if not enough L2 tables during boot If there are not enough free L2 tables to map all predefined memory regions at boot, halt the system in case assertion is not enabled. Without all the needed memory regions mapped, it is very unlikely that anything will run properly. Signed-off-by: Daniel Leung --- arch/xtensa/core/ptables.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/arch/xtensa/core/ptables.c b/arch/xtensa/core/ptables.c index 0370bb3885ed..3ec0bb672720 100644 --- a/arch/xtensa/core/ptables.c +++ b/arch/xtensa/core/ptables.c @@ -407,6 +407,15 @@ static void map_memory_range(const uint32_t start, const uint32_t end, __ASSERT(l2_table != NULL, "There is no l2 page table available to map 0x%08x\n", page); + if (l2_table == NULL) { + /* This function is called during boot. If this cannot + * properly map all predefined memory regions, it is very + * unlikely for anything to run correctly. So forcibly + * halt the system in case assertion has been turned off. + */ + arch_system_halt(K_ERR_KERNEL_PANIC); + } + init_page_table(l2_table, L2_PAGE_TABLE_NUM_ENTRIES, PTE_L2_ILLEGAL); xtensa_kernel_ptables[l1_pos] = From c5bc58e3bdbf00aeb0354040f8f36d9f373aeb53 Mon Sep 17 00:00:00 2001 From: Vinit Mehta Date: Wed, 7 Jan 2026 15:38:46 +0530 Subject: [PATCH 2400/3659] Samples: bluetooth: a2dp_sink: Audio support for 1060EVKC Add codec driver overlay file to enable audio rendering for A2DP sink sample application for 1060EVKC platform Signed-off-by: Vinit Mehta --- .../boards/mimxrt1060_evk_mimxrt1062_qspi_C.conf | 10 ++++++++++ .../mimxrt1060_evk_mimxrt1062_qspi_C.overlay | 15 +++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 samples/bluetooth/classic/a2dp_sink/boards/mimxrt1060_evk_mimxrt1062_qspi_C.conf create mode 100644 samples/bluetooth/classic/a2dp_sink/boards/mimxrt1060_evk_mimxrt1062_qspi_C.overlay diff --git a/samples/bluetooth/classic/a2dp_sink/boards/mimxrt1060_evk_mimxrt1062_qspi_C.conf b/samples/bluetooth/classic/a2dp_sink/boards/mimxrt1060_evk_mimxrt1062_qspi_C.conf new file mode 100644 index 000000000000..ae1b1ee9be0f --- /dev/null +++ b/samples/bluetooth/classic/a2dp_sink/boards/mimxrt1060_evk_mimxrt1062_qspi_C.conf @@ -0,0 +1,10 @@ +# +# Copyright 2026 NXP +# +# SPDX-License-Identifier: Apache-2.0 +# + +CONFIG_I2S=y +CONFIG_AUDIO=y +CONFIG_AUDIO_CODEC=y +CONFIG_DMA_TCD_QUEUE_SIZE=4 diff --git a/samples/bluetooth/classic/a2dp_sink/boards/mimxrt1060_evk_mimxrt1062_qspi_C.overlay b/samples/bluetooth/classic/a2dp_sink/boards/mimxrt1060_evk_mimxrt1062_qspi_C.overlay new file mode 100644 index 000000000000..b0aab45ba45a --- /dev/null +++ b/samples/bluetooth/classic/a2dp_sink/boards/mimxrt1060_evk_mimxrt1062_qspi_C.overlay @@ -0,0 +1,15 @@ +/* + * Copyright 2026 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&sai1 { + mclk-output; + podf = <15>; + pll-clocks = <&anatop 0 0 0>, + <&anatop 0 0 30>, + <&anatop 0 0 1>, + <&anatop 0 0 106>, + <&anatop 0 0 1000>; +}; From 924874baefa93c0faaaf352b50e06fb7ca70bbf7 Mon Sep 17 00:00:00 2001 From: Peter Mitsis Date: Mon, 12 Jan 2026 15:33:08 -0800 Subject: [PATCH 2401/3659] kernel: Fix two k_condvar_wait() issues 1. When the timeout is K_NO_WAIT, the thread should not be added to the wait queue as that would otherwise cause to the thread to wait until the next tick (which is not a no-wait situation). 2. Threads that were added to the wait queue AND did not receive a signal before timing out should not lock the supplied mutex. Signed-off-by: Peter Mitsis --- kernel/condvar.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/kernel/condvar.c b/kernel/condvar.c index 42590839c863..640fd8ad2b64 100644 --- a/kernel/condvar.c +++ b/kernel/condvar.c @@ -115,15 +115,23 @@ int z_impl_k_condvar_wait(struct k_condvar *condvar, struct k_mutex *mutex, k_timeout_t timeout) { k_spinlock_key_t key; - int ret; + int ret = -EAGAIN; SYS_PORT_TRACING_OBJ_FUNC_ENTER(k_condvar, wait, condvar, timeout); + if (unlikely(K_TIMEOUT_EQ(timeout, K_NO_WAIT))) { + k_mutex_unlock(mutex); + SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_condvar, wait, condvar, timeout, ret); + return ret; + } + key = k_spin_lock(&lock); k_mutex_unlock(mutex); ret = z_pend_curr(&lock, key, &condvar->wait_q, timeout); - k_mutex_lock(mutex, K_FOREVER); + if (ret == 0) { + k_mutex_lock(mutex, K_FOREVER); + } SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_condvar, wait, condvar, timeout, ret); From 3944b0cfc7f9f7a9d31479f2a2bd5a89e6ca82a5 Mon Sep 17 00:00:00 2001 From: Peter Mitsis Date: Fri, 9 Jan 2026 13:42:26 -0800 Subject: [PATCH 2402/3659] kernel: Extend thread user_options to 16 bits Upgrades the thread user_options to 16 bits from an 8-bit value to provide more space for future values. Also, as the size of this field has changed, the values for the existing architecture specific thread options have also shifted from the upper end of the old 8-bit field, to the upper end of the new 16-bit field. Fixes #101034 Signed-off-by: Peter Mitsis --- arch/arc/core/thread.c | 4 ++-- arch/arm/core/cortex_a_r/swap_helper.S | 4 ++-- arch/riscv/core/switch.S | 2 +- arch/x86/core/ia32/float.c | 2 +- arch/x86/core/ia32/swap.S | 8 ++++---- include/zephyr/kernel.h | 6 +++--- include/zephyr/kernel/thread.h | 12 ++++-------- kernel/thread.c | 2 +- scripts/coredump/gdbstubs/gdbstub.py | 8 ++++---- 9 files changed, 22 insertions(+), 26 deletions(-) diff --git a/arch/arc/core/thread.c b/arch/arc/core/thread.c index 387f983780b9..38aee4912027 100644 --- a/arch/arc/core/thread.c +++ b/arch/arc/core/thread.c @@ -318,7 +318,7 @@ void arc_dsp_disable(struct k_thread *thread, unsigned int options) k_spinlock_key_t key = k_spin_lock(&lock); /* Disable DSP or AGU capabilities for the thread */ - thread->base.user_options &= ~(uint8_t)options; + thread->base.user_options &= ~(uint16_t)options; k_spin_unlock(&lock, key); } @@ -329,7 +329,7 @@ void arc_dsp_enable(struct k_thread *thread, unsigned int options) k_spinlock_key_t key = k_spin_lock(&lock); /* Enable dsp or agu capabilities for the thread */ - thread->base.user_options |= (uint8_t)options; + thread->base.user_options |= (uint16_t)options; k_spin_unlock(&lock, key); } diff --git a/arch/arm/core/cortex_a_r/swap_helper.S b/arch/arm/core/cortex_a_r/swap_helper.S index 04b19f0b046b..9417073f311c 100644 --- a/arch/arm/core/cortex_a_r/swap_helper.S +++ b/arch/arm/core/cortex_a_r/swap_helper.S @@ -69,7 +69,7 @@ SECTION_FUNC(TEXT, z_arm_do_swap) cps #MODE_SVC #if defined(CONFIG_FPU_SHARING) - ldrb r0, [r2, #_thread_offset_to_user_options] + ldrh r0, [r2, #_thread_offset_to_user_options] tst r0, #K_FP_REGS /* _current->base.user_options & K_FP_REGS */ beq out_fp_inactive @@ -151,7 +151,7 @@ out_fp_inactive: cps #MODE_SVC #if defined(CONFIG_FPU_SHARING) - ldrb r0, [r2, #_thread_offset_to_user_options] + ldrh r0, [r2, #_thread_offset_to_user_options] tst r0, #K_FP_REGS /* _current->base.user_options & K_FP_REGS */ beq in_fp_inactive diff --git a/arch/riscv/core/switch.S b/arch/riscv/core/switch.S index 81292748f838..b78289af68b6 100644 --- a/arch/riscv/core/switch.S +++ b/arch/riscv/core/switch.S @@ -73,7 +73,7 @@ SECTION_FUNC(TEXT, z_riscv_switch) * in effect while in m-mode. (it is done on every exception return * otherwise). */ - lb t0, _thread_offset_to_user_options(a0) + lh t0, _thread_offset_to_user_options(a0) andi t0, t0, K_USER beqz t0, not_user_task mv s0, a0 diff --git a/arch/x86/core/ia32/float.c b/arch/x86/core/ia32/float.c index 9b6f4daa18e0..8219dc7593b8 100644 --- a/arch/x86/core/ia32/float.c +++ b/arch/x86/core/ia32/float.c @@ -179,7 +179,7 @@ void z_float_enable(struct k_thread *thread, unsigned int options) /* Indicate thread requires floating point context saving */ - thread->base.user_options |= (uint8_t)options; + thread->base.user_options |= (uint16_t)options; /* * The current thread might not allow FP instructions, so clear CR0[TS] * so we can use them. (CR0[TS] gets restored later on, if necessary.) diff --git a/arch/x86/core/ia32/swap.S b/arch/x86/core/ia32/swap.S index 4baa0070b9b8..f3433bfd0f0a 100644 --- a/arch/x86/core/ia32/swap.S +++ b/arch/x86/core/ia32/swap.S @@ -175,7 +175,7 @@ SECTION_FUNC(PINNED_TEXT, arch_swap) * _and_ whether the thread was context switched out preemptively. */ - testb $_FP_USER_MASK, _thread_offset_to_user_options(%eax) + testw $_FP_USER_MASK, _thread_offset_to_user_options(%eax) je restoreContext_NoFloatSwap @@ -216,7 +216,7 @@ SECTION_FUNC(PINNED_TEXT, arch_swap) #ifdef CONFIG_X86_SSE - testb $K_SSE_REGS, _thread_offset_to_user_options(%ebx) + testw $K_SSE_REGS, _thread_offset_to_user_options(%ebx) je x87FloatSave /* @@ -255,7 +255,7 @@ restoreContext_NoFloatSave: je restoreContext_NoFloatRestore #ifdef CONFIG_X86_SSE - testb $K_SSE_REGS, _thread_offset_to_user_options(%eax) + testw $K_SSE_REGS, _thread_offset_to_user_options(%eax) je x87FloatRestore fxrstor _thread_offset_to_preempFloatReg(%eax) @@ -290,7 +290,7 @@ restoreContext_NoFloatSwap: * registers */ - testb $_FP_USER_MASK, _thread_offset_to_user_options(%eax) + testw $_FP_USER_MASK, _thread_offset_to_user_options(%eax) jne CROHandlingDone /* diff --git a/include/zephyr/kernel.h b/include/zephyr/kernel.h index a27a4049242f..bfde2db11006 100644 --- a/include/zephyr/kernel.h +++ b/include/zephyr/kernel.h @@ -322,7 +322,7 @@ void k_thread_foreach_unlocked_filter_by_cpu(unsigned int cpu, * restore the contents of these registers when scheduling the thread. * No effect if @kconfig{CONFIG_DSP_SHARING} is not enabled. */ -#define K_DSP_IDX 6 +#define K_DSP_IDX 13 #define K_DSP_REGS (BIT(K_DSP_IDX)) /** @@ -333,7 +333,7 @@ void k_thread_foreach_unlocked_filter_by_cpu(unsigned int cpu, * memory and DSP feature. Often used with @kconfig{CONFIG_ARC_AGU_SHARING}. * No effect if @kconfig{CONFIG_ARC_AGU_SHARING} is not enabled. */ -#define K_AGU_IDX 7 +#define K_AGU_IDX 14 #define K_AGU_REGS (BIT(K_AGU_IDX)) /** @@ -345,7 +345,7 @@ void k_thread_foreach_unlocked_filter_by_cpu(unsigned int cpu, * save and restore the contents of these registers when scheduling * the thread. No effect if @kconfig{CONFIG_X86_SSE} is not enabled. */ -#define K_SSE_REGS (BIT(7)) +#define K_SSE_REGS (BIT(15)) /* end - thread options */ diff --git a/include/zephyr/kernel/thread.h b/include/zephyr/kernel/thread.h index 3dd40355bc28..46d32a388d47 100644 --- a/include/zephyr/kernel/thread.h +++ b/include/zephyr/kernel/thread.h @@ -57,10 +57,7 @@ struct _thread_base { _wait_q_t *pended_on; /* user facing 'thread options'; values defined in include/zephyr/kernel.h */ - uint8_t user_options; - - /* thread state */ - uint8_t thread_state; + uint16_t user_options; /* * scheduler lock count and thread priority @@ -97,6 +94,9 @@ struct _thread_base { uint32_t order_key; #endif + /* thread state */ + uint8_t thread_state; + #ifdef CONFIG_SMP /* True for the per-CPU idle threads */ uint8_t is_idle; @@ -111,11 +111,7 @@ struct _thread_base { #ifdef CONFIG_SCHED_CPU_MASK /* "May run on" bits for each CPU */ -#if CONFIG_MP_MAX_NUM_CPUS <= 8 - uint8_t cpu_mask; -#else uint16_t cpu_mask; -#endif /* CONFIG_MP_MAX_NUM_CPUS */ #endif /* CONFIG_SCHED_CPU_MASK */ /* data returned by APIs */ diff --git a/kernel/thread.c b/kernel/thread.c index 97efd493c9cb..a9dc945a12ed 100644 --- a/kernel/thread.c +++ b/kernel/thread.c @@ -881,7 +881,7 @@ void z_init_thread_base(struct _thread_base *thread_base, int priority, { /* k_q_node is initialized upon first insertion in a list */ thread_base->pended_on = NULL; - thread_base->user_options = (uint8_t)options; + thread_base->user_options = (uint16_t)options; thread_base->thread_state = (uint8_t)initial_state; thread_base->prio = priority; diff --git a/scripts/coredump/gdbstubs/gdbstub.py b/scripts/coredump/gdbstubs/gdbstub.py index e5499607389d..b277bd2d163a 100644 --- a/scripts/coredump/gdbstubs/gdbstub.py +++ b/scripts/coredump/gdbstubs/gdbstub.py @@ -279,11 +279,11 @@ def handle_general_query_packet(self, pkt): t_user_options_offset = self.elffile.get_kernel_thread_info_offset( ThreadInfoOffset.THREAD_INFO_OFFSET_T_USER_OPTIONS ) - thread_user_options_byte = self.get_memory( - thread_ptr + t_user_options_offset, 1 + thread_user_options_halfword = self.get_memory( + thread_ptr + t_user_options_offset, 2 ) - if thread_user_options_byte is not None: - thread_user_options = int.from_bytes(thread_user_options_byte, "little") + if thread_user_options_halfword is not None: + thread_user_options = int.from_bytes(thread_user_options_halfword, "little") thread_info_bytes += b', user_options: ' + bytes( hex(thread_user_options), 'ascii' ) From fad7e5dfe62fd0671b2a0c5fdbb8fd99c207aae5 Mon Sep 17 00:00:00 2001 From: Camille BAUD Date: Thu, 15 Jan 2026 13:06:18 +0100 Subject: [PATCH 2403/3659] drivers: display: rename ssd1306/9fb to ssd1306/9 harmonize with other drivers, remove irrelevant suffix Signed-off-by: Camille BAUD --- .../01space/esp32c3_042_oled/esp32c3_042_oled.dts | 2 +- boards/adi/max32672fthr/max32672fthr.dts | 2 +- .../ttgo_lora32/ttgo_lora32_esp32_procpu.dts | 2 +- .../lilygo/ttgo_tbeam/ttgo_tbeam_esp32_procpu.dts | 2 +- .../mxchip/az3166_iotdevkit/az3166_iotdevkit.dts | 2 +- boards/nxp/mr_canhubk3/mr_canhubk3_common.dtsi | 2 +- .../adafruit_featherwing_128x32_oled.overlay | 2 +- .../seeed_xiao_expansion_board.overlay | 2 +- boards/shields/ssd1306/ssd1306_128x32.overlay | 2 +- boards/shields/ssd1306/ssd1306_128x64.overlay | 2 +- boards/shields/ssd1306/ssd1306_128x64_spi.overlay | 2 +- drivers/display/Kconfig.ssd1306 | 10 +++++----- drivers/display/ssd1306.c | 14 +++++++------- dts/bindings/display/sinowealth,sh1106-i2c.yaml | 2 +- dts/bindings/display/sinowealth,sh1106-spi.yaml | 2 +- ...6fb-common.yaml => solomon,ssd1306-common.yaml} | 0 ...ssd1306fb-i2c.yaml => solomon,ssd1306-i2c.yaml} | 4 ++-- ...ssd1306fb-spi.yaml => solomon,ssd1306-spi.yaml} | 4 ++-- ...ssd1309fb-i2c.yaml => solomon,ssd1309-i2c.yaml} | 4 ++-- ...ssd1309fb-spi.yaml => solomon,ssd1309-spi.yaml} | 4 ++-- tests/drivers/build_all/display/app.overlay | 2 +- 21 files changed, 34 insertions(+), 34 deletions(-) rename dts/bindings/display/{solomon,ssd1306fb-common.yaml => solomon,ssd1306-common.yaml} (100%) rename dts/bindings/display/{solomon,ssd1306fb-i2c.yaml => solomon,ssd1306-i2c.yaml} (71%) rename dts/bindings/display/{solomon,ssd1306fb-spi.yaml => solomon,ssd1306-spi.yaml} (78%) rename dts/bindings/display/{solomon,ssd1309fb-i2c.yaml => solomon,ssd1309-i2c.yaml} (71%) rename dts/bindings/display/{solomon,ssd1309fb-spi.yaml => solomon,ssd1309-spi.yaml} (78%) diff --git a/boards/01space/esp32c3_042_oled/esp32c3_042_oled.dts b/boards/01space/esp32c3_042_oled/esp32c3_042_oled.dts index 70f83f398e75..d7c3b0960373 100644 --- a/boards/01space/esp32c3_042_oled/esp32c3_042_oled.dts +++ b/boards/01space/esp32c3_042_oled/esp32c3_042_oled.dts @@ -48,7 +48,7 @@ pinctrl-names = "default"; eastrising_72x40: ssd1306@3c { - compatible = "solomon,ssd1306fb"; + compatible = "solomon,ssd1306"; reg = <0x3c>; width = <72>; diff --git a/boards/adi/max32672fthr/max32672fthr.dts b/boards/adi/max32672fthr/max32672fthr.dts index 397fb51a81ac..0ed07af00a13 100644 --- a/boards/adi/max32672fthr/max32672fthr.dts +++ b/boards/adi/max32672fthr/max32672fthr.dts @@ -130,7 +130,7 @@ status = "okay"; ssd1306: ssd1306@3d { - compatible = "solomon,ssd1306fb"; + compatible = "solomon,ssd1306"; reg = <0x3d>; width = <128>; height = <32>; diff --git a/boards/lilygo/ttgo_lora32/ttgo_lora32_esp32_procpu.dts b/boards/lilygo/ttgo_lora32/ttgo_lora32_esp32_procpu.dts index aaed6346e114..5dfd627b7fbb 100644 --- a/boards/lilygo/ttgo_lora32/ttgo_lora32_esp32_procpu.dts +++ b/boards/lilygo/ttgo_lora32/ttgo_lora32_esp32_procpu.dts @@ -68,7 +68,7 @@ pinctrl-names = "default"; ssd1306_128x64: ssd1306@3c { - compatible = "solomon,ssd1306fb"; + compatible = "solomon,ssd1306"; reg = <0x3c>; width = <128>; height = <64>; diff --git a/boards/lilygo/ttgo_tbeam/ttgo_tbeam_esp32_procpu.dts b/boards/lilygo/ttgo_tbeam/ttgo_tbeam_esp32_procpu.dts index fc524286776e..f0a924bae389 100644 --- a/boards/lilygo/ttgo_tbeam/ttgo_tbeam_esp32_procpu.dts +++ b/boards/lilygo/ttgo_tbeam/ttgo_tbeam_esp32_procpu.dts @@ -78,7 +78,7 @@ pinctrl-names = "default"; ssd1306_128x64: ssd1306@3c { - compatible = "solomon,ssd1306fb"; + compatible = "solomon,ssd1306"; reg = <0x3c>; width = <128>; height = <64>; diff --git a/boards/mxchip/az3166_iotdevkit/az3166_iotdevkit.dts b/boards/mxchip/az3166_iotdevkit/az3166_iotdevkit.dts index e01b8d52eff6..b24be56345b4 100644 --- a/boards/mxchip/az3166_iotdevkit/az3166_iotdevkit.dts +++ b/boards/mxchip/az3166_iotdevkit/az3166_iotdevkit.dts @@ -171,7 +171,7 @@ }; ssd1306: ssd1306@3c { - compatible = "solomon,ssd1306fb"; + compatible = "solomon,ssd1306"; reg = <0x3c>; width = <128>; height = <64>; diff --git a/boards/nxp/mr_canhubk3/mr_canhubk3_common.dtsi b/boards/nxp/mr_canhubk3/mr_canhubk3_common.dtsi index 6b2b5b3fb172..b2ec5a5e51c1 100644 --- a/boards/nxp/mr_canhubk3/mr_canhubk3_common.dtsi +++ b/boards/nxp/mr_canhubk3/mr_canhubk3_common.dtsi @@ -395,7 +395,7 @@ status = "okay"; ssd1306: ssd1306@3c { - compatible = "solomon,ssd1306fb"; + compatible = "solomon,ssd1306"; reg = <0x3c>; width = <128>; height = <32>; diff --git a/boards/shields/adafruit_featherwing_128x32_oled/adafruit_featherwing_128x32_oled.overlay b/boards/shields/adafruit_featherwing_128x32_oled/adafruit_featherwing_128x32_oled.overlay index 585d214847ea..6e90dd042d6b 100644 --- a/boards/shields/adafruit_featherwing_128x32_oled/adafruit_featherwing_128x32_oled.overlay +++ b/boards/shields/adafruit_featherwing_128x32_oled/adafruit_featherwing_128x32_oled.overlay @@ -39,7 +39,7 @@ &feather_i2c { ssd1306_ssd1306_128x32: ssd1306@3c { - compatible = "solomon,ssd1306fb"; + compatible = "solomon,ssd1306"; reg = <0x3c>; width = <128>; height = <32>; diff --git a/boards/shields/seeed_xiao_expansion_board/seeed_xiao_expansion_board.overlay b/boards/shields/seeed_xiao_expansion_board/seeed_xiao_expansion_board.overlay index a90a4b62c465..bbeaa0215058 100644 --- a/boards/shields/seeed_xiao_expansion_board/seeed_xiao_expansion_board.overlay +++ b/boards/shields/seeed_xiao_expansion_board/seeed_xiao_expansion_board.overlay @@ -31,7 +31,7 @@ status = "okay"; ssd1306_128x64: ssd1306@3c { - compatible = "solomon,ssd1306fb"; + compatible = "solomon,ssd1306"; reg = <0x3c>; width = <128>; height = <64>; diff --git a/boards/shields/ssd1306/ssd1306_128x32.overlay b/boards/shields/ssd1306/ssd1306_128x32.overlay index a8b53a2cfb9e..0689f270a758 100644 --- a/boards/shields/ssd1306/ssd1306_128x32.overlay +++ b/boards/shields/ssd1306/ssd1306_128x32.overlay @@ -14,7 +14,7 @@ status = "okay"; ssd1306_ssd1306_128x32: ssd1306@3c { - compatible = "solomon,ssd1306fb"; + compatible = "solomon,ssd1306"; reg = <0x3c>; width = <128>; height = <32>; diff --git a/boards/shields/ssd1306/ssd1306_128x64.overlay b/boards/shields/ssd1306/ssd1306_128x64.overlay index 2e9f1c320cc3..8d4ef9ededc2 100644 --- a/boards/shields/ssd1306/ssd1306_128x64.overlay +++ b/boards/shields/ssd1306/ssd1306_128x64.overlay @@ -14,7 +14,7 @@ status = "okay"; ssd1306_ssd1306_128x64: ssd1306@3c { - compatible = "solomon,ssd1306fb"; + compatible = "solomon,ssd1306"; reg = <0x3c>; width = <128>; height = <64>; diff --git a/boards/shields/ssd1306/ssd1306_128x64_spi.overlay b/boards/shields/ssd1306/ssd1306_128x64_spi.overlay index c9ee9e68563c..b7c416192805 100644 --- a/boards/shields/ssd1306/ssd1306_128x64_spi.overlay +++ b/boards/shields/ssd1306/ssd1306_128x64_spi.overlay @@ -16,7 +16,7 @@ status = "okay"; ssd1306_ssd1306_128x64_spi: ssd1306@0 { - compatible = "solomon,ssd1306fb"; + compatible = "solomon,ssd1306"; reg = <0x0>; spi-max-frequency = <10000000>; width = <128>; diff --git a/drivers/display/Kconfig.ssd1306 b/drivers/display/Kconfig.ssd1306 index f067f572371d..43a3bd6d72d7 100644 --- a/drivers/display/Kconfig.ssd1306 +++ b/drivers/display/Kconfig.ssd1306 @@ -6,11 +6,11 @@ menuconfig SSD1306 bool "SSD1306 display driver" default y - depends on DT_HAS_SOLOMON_SSD1306FB_ENABLED || DT_HAS_SOLOMON_SSD1309FB_ENABLED || DT_HAS_SINOWEALTH_SH1106_ENABLED - select I2C if $(dt_compat_on_bus,$(DT_COMPAT_SOLOMON_SSD1306FB),i2c) - select SPI if $(dt_compat_on_bus,$(DT_COMPAT_SOLOMON_SSD1306FB),spi) - select I2C if $(dt_compat_on_bus,$(DT_COMPAT_SOLOMON_SSD1309FB),i2c) - select SPI if $(dt_compat_on_bus,$(DT_COMPAT_SOLOMON_SSD1309FB),spi) + depends on DT_HAS_SOLOMON_SSD1306_ENABLED || DT_HAS_SOLOMON_SSD1309_ENABLED || DT_HAS_SINOWEALTH_SH1106_ENABLED + select I2C if $(dt_compat_on_bus,$(DT_COMPAT_SOLOMON_SSD1306),i2c) + select SPI if $(dt_compat_on_bus,$(DT_COMPAT_SOLOMON_SSD1306),spi) + select I2C if $(dt_compat_on_bus,$(DT_COMPAT_SOLOMON_SSD1309),i2c) + select SPI if $(dt_compat_on_bus,$(DT_COMPAT_SOLOMON_SSD1309),spi) select I2C if $(dt_compat_on_bus,$(DT_COMPAT_SINOWEALTH_SH1106),i2c) select SPI if $(dt_compat_on_bus,$(DT_COMPAT_SINOWEALTH_SH1106),spi) help diff --git a/drivers/display/ssd1306.c b/drivers/display/ssd1306.c index 04f6e7f2e7ec..322426d2dc5c 100644 --- a/drivers/display/ssd1306.c +++ b/drivers/display/ssd1306.c @@ -71,8 +71,8 @@ struct ssd1306_data { enum display_orientation orientation; }; -#if (DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(solomon_ssd1306fb, i2c) || \ - DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(solomon_ssd1309fb, i2c) || \ +#if (DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(solomon_ssd1306, i2c) || \ + DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(solomon_ssd1309, i2c) || \ DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(sinowealth_sh1106, i2c)) static bool ssd1306_bus_ready_i2c(const struct device *dev) { @@ -99,8 +99,8 @@ static const char *ssd1306_bus_name_i2c(const struct device *dev) } #endif -#if (DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(solomon_ssd1306fb, spi) || \ - DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(solomon_ssd1309fb, spi) || \ +#if (DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(solomon_ssd1306, spi) || \ + DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(solomon_ssd1309, spi) || \ DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(sinowealth_sh1106, spi)) static bool ssd1306_bus_ready_spi(const struct device *dev) { @@ -627,7 +627,7 @@ static DEVICE_API(display, ssd1306_driver_api) = { .com_sequential = DT_PROP(node_id, com_sequential), \ .prechargep = DT_PROP(node_id, prechargep), \ .color_inversion = DT_PROP(node_id, inversion_on), \ - .ssd1309_compatible = DT_NODE_HAS_COMPAT(node_id, solomon_ssd1309fb), \ + .ssd1309_compatible = DT_NODE_HAS_COMPAT(node_id, solomon_ssd1309), \ .sh1106_compatible = DT_NODE_HAS_COMPAT(node_id, sinowealth_sh1106), \ .ready_time_ms = DT_PROP(node_id, ready_time_ms), \ .use_internal_iref = DT_PROP(node_id, use_internal_iref), \ @@ -638,6 +638,6 @@ static DEVICE_API(display, ssd1306_driver_api) = { DEVICE_DT_DEFINE(node_id, ssd1306_init, NULL, &data##node_id, &config##node_id, \ POST_KERNEL, CONFIG_DISPLAY_INIT_PRIORITY, &ssd1306_driver_api); -DT_FOREACH_STATUS_OKAY(solomon_ssd1306fb, SSD1306_DEFINE) -DT_FOREACH_STATUS_OKAY(solomon_ssd1309fb, SSD1306_DEFINE) +DT_FOREACH_STATUS_OKAY(solomon_ssd1306, SSD1306_DEFINE) +DT_FOREACH_STATUS_OKAY(solomon_ssd1309, SSD1306_DEFINE) DT_FOREACH_STATUS_OKAY(sinowealth_sh1106, SSD1306_DEFINE) diff --git a/dts/bindings/display/sinowealth,sh1106-i2c.yaml b/dts/bindings/display/sinowealth,sh1106-i2c.yaml index f476f838bbfe..2106dde1a559 100644 --- a/dts/bindings/display/sinowealth,sh1106-i2c.yaml +++ b/dts/bindings/display/sinowealth,sh1106-i2c.yaml @@ -5,4 +5,4 @@ description: SH1106 128x64 dot-matrix display controller on I2C bus compatible: "sinowealth,sh1106" -include: ["solomon,ssd1306fb-common.yaml", "i2c-device.yaml"] +include: ["solomon,ssd1306-common.yaml", "i2c-device.yaml"] diff --git a/dts/bindings/display/sinowealth,sh1106-spi.yaml b/dts/bindings/display/sinowealth,sh1106-spi.yaml index 5bb843c365d7..068c9ad6c718 100644 --- a/dts/bindings/display/sinowealth,sh1106-spi.yaml +++ b/dts/bindings/display/sinowealth,sh1106-spi.yaml @@ -5,7 +5,7 @@ description: SH1106 128x64 dot-matrix display controller on SPI bus compatible: "sinowealth,sh1106" -include: ["solomon,ssd1306fb-common.yaml", "spi-device.yaml"] +include: ["solomon,ssd1306-common.yaml", "spi-device.yaml"] properties: data-cmd-gpios: diff --git a/dts/bindings/display/solomon,ssd1306fb-common.yaml b/dts/bindings/display/solomon,ssd1306-common.yaml similarity index 100% rename from dts/bindings/display/solomon,ssd1306fb-common.yaml rename to dts/bindings/display/solomon,ssd1306-common.yaml diff --git a/dts/bindings/display/solomon,ssd1306fb-i2c.yaml b/dts/bindings/display/solomon,ssd1306-i2c.yaml similarity index 71% rename from dts/bindings/display/solomon,ssd1306fb-i2c.yaml rename to dts/bindings/display/solomon,ssd1306-i2c.yaml index a2eee397c074..f270b2f4886c 100644 --- a/dts/bindings/display/solomon,ssd1306fb-i2c.yaml +++ b/dts/bindings/display/solomon,ssd1306-i2c.yaml @@ -7,6 +7,6 @@ description: | The Solomon SSD1306 is a monochrome OLED controller with a maximum 128x64 resolution. -compatible: "solomon,ssd1306fb" +compatible: "solomon,ssd1306" -include: ["solomon,ssd1306fb-common.yaml", "i2c-device.yaml"] +include: ["solomon,ssd1306-common.yaml", "i2c-device.yaml"] diff --git a/dts/bindings/display/solomon,ssd1306fb-spi.yaml b/dts/bindings/display/solomon,ssd1306-spi.yaml similarity index 78% rename from dts/bindings/display/solomon,ssd1306fb-spi.yaml rename to dts/bindings/display/solomon,ssd1306-spi.yaml index 1cd7a39e6962..c87ef810b43b 100644 --- a/dts/bindings/display/solomon,ssd1306fb-spi.yaml +++ b/dts/bindings/display/solomon,ssd1306-spi.yaml @@ -7,9 +7,9 @@ description: | The Solomon SSD1306 is a monochrome OLED controller with a maximum 128x64 resolution. -compatible: "solomon,ssd1306fb" +compatible: "solomon,ssd1306" -include: ["solomon,ssd1306fb-common.yaml", "spi-device.yaml"] +include: ["solomon,ssd1306-common.yaml", "spi-device.yaml"] properties: data-cmd-gpios: diff --git a/dts/bindings/display/solomon,ssd1309fb-i2c.yaml b/dts/bindings/display/solomon,ssd1309-i2c.yaml similarity index 71% rename from dts/bindings/display/solomon,ssd1309fb-i2c.yaml rename to dts/bindings/display/solomon,ssd1309-i2c.yaml index c47668b4df0b..968457861985 100644 --- a/dts/bindings/display/solomon,ssd1309fb-i2c.yaml +++ b/dts/bindings/display/solomon,ssd1309-i2c.yaml @@ -7,6 +7,6 @@ description: | The Solomon SSD1309 is a monochrome OLED controller with a maximum 128x64 resolution. -compatible: "solomon,ssd1309fb" +compatible: "solomon,ssd1309" -include: ["solomon,ssd1306fb-common.yaml", "i2c-device.yaml"] +include: ["solomon,ssd1306-common.yaml", "i2c-device.yaml"] diff --git a/dts/bindings/display/solomon,ssd1309fb-spi.yaml b/dts/bindings/display/solomon,ssd1309-spi.yaml similarity index 78% rename from dts/bindings/display/solomon,ssd1309fb-spi.yaml rename to dts/bindings/display/solomon,ssd1309-spi.yaml index d894a795d37e..35789e6a35f6 100644 --- a/dts/bindings/display/solomon,ssd1309fb-spi.yaml +++ b/dts/bindings/display/solomon,ssd1309-spi.yaml @@ -7,9 +7,9 @@ description: | The Solomon SSD1309 is a monochrome OLED controller with a maximum 128x64 resolution. -compatible: "solomon,ssd1309fb" +compatible: "solomon,ssd1309" -include: ["solomon,ssd1306fb-common.yaml", "spi-device.yaml"] +include: ["solomon,ssd1306-common.yaml", "spi-device.yaml"] properties: data-cmd-gpios: diff --git a/tests/drivers/build_all/display/app.overlay b/tests/drivers/build_all/display/app.overlay index 9f2c304e4809..e151f67c4450 100644 --- a/tests/drivers/build_all/display/app.overlay +++ b/tests/drivers/build_all/display/app.overlay @@ -643,7 +643,7 @@ }; test_ssd1306: ssd1306@1 { - compatible = "solomon,ssd1306fb"; + compatible = "solomon,ssd1306"; reg = <0x1>; width = <128>; height = <64>; From fa30e17ffa29ebbb9b07ae652a098fc34d3b1b51 Mon Sep 17 00:00:00 2001 From: Camille BAUD Date: Thu, 15 Jan 2026 13:14:17 +0100 Subject: [PATCH 2404/3659] doc: release: Notes about SSD1306/9 bindings Adds notes about SSD1306/9 bindings Signed-off-by: Camille BAUD --- doc/releases/migration-guide-4.4.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/releases/migration-guide-4.4.rst b/doc/releases/migration-guide-4.4.rst index 2b19fcdddd14..991c0625b109 100644 --- a/doc/releases/migration-guide-4.4.rst +++ b/doc/releases/migration-guide-4.4.rst @@ -360,6 +360,10 @@ Display * ``solomon,ssd1327fb`` devicetree compatible has been renamed :dtcompatible:`solomon,ssd1327` to harmonize with other display controllers and eliminate the zephyr-irrelevant ``fb`` suffix. +* ``solomon,ssd1306fb`` and ``solomon,ssd1309fb`` devicetree compatibles has been renamed + :dtcompatible:`solomon,ssd1306` and :dtcompatible:`solomon,ssd1309` respectively, + to harmonize with other display controllers and eliminate the zephyr-irrelevant ``fb`` suffix. + DMA === From 74975b0be5adbe198b453850d1bef06e8b7e831f Mon Sep 17 00:00:00 2001 From: Camille BAUD Date: Sat, 17 Jan 2026 23:44:27 +0100 Subject: [PATCH 2405/3659] drivers: display: ssd1306: move registers from header to main file standard self-containment Signed-off-by: Camille BAUD --- drivers/display/ssd1306.c | 111 ++++++++++++++++++++++++----- drivers/display/ssd1306_regs.h | 123 --------------------------------- 2 files changed, 95 insertions(+), 139 deletions(-) delete mode 100644 drivers/display/ssd1306_regs.h diff --git a/drivers/display/ssd1306.c b/drivers/display/ssd1306.c index 322426d2dc5c..f52dadcf366b 100644 --- a/drivers/display/ssd1306.c +++ b/drivers/display/ssd1306.c @@ -16,21 +16,100 @@ LOG_MODULE_REGISTER(ssd1306, CONFIG_DISPLAY_LOG_LEVEL); #include #include -#include "ssd1306_regs.h" +/* + * Commands + */ +#define SSD1306_SET_LOWER_COL_ADDRESS 0x00 /* No arguments, command is argument */ +#define SSD1306_SET_LOWER_COL_ADDRESS_END 0x0f /* Command as argument end */ +#define SSD1306_SET_HIGHER_COL_ADDRESS 0x10 /* No arguments, command is argument */ +#define SSD1306_SET_HIGHER_COL_ADDRESS_END 0x1f /* Command as argument end */ +#define SSD1306_SET_MEM_ADDRESSING_MODE 0x20 /* 1 byte args: A[1:0] Addressing mode */ +#define SSD1306_SET_COLUMN_ADDRESS 0x21 /* 2 bytes args: column address, start end */ +#define SSD1306_SET_PAGE_ADDRESS 0x22 /* 2 bytes args: page address, start end */ +#define SSD1306_SET_PUMP_VOLTAGE_64 0x30 /* No arguments, command is argument */ +#define SSD1306_SET_PUMP_VOLTAGE_74 0x31 /* No arguments, command is argument */ +#define SSD1306_SET_PUMP_VOLTAGE_80 0x32 /* No arguments, command is argument */ +#define SSD1306_SET_PUMP_VOLTAGE_90 0x33 /* No arguments, command is argument */ +#define SSD1306_SET_START_LINE 0x40 /* No arguments, command is argument */ +#define SSD1306_SET_START_LINE_END 0x7f /* Command as argument end */ +#define SSD1306_SET_CONTRAST_CTRL 0x81 /* 1 byte args: Constrast */ +#define SH1106_SET_DCDC_DISABLED 0x8a /* No arguments, command is argument */ +#define SH1106_SET_DCDC_ENABLED 0x8b /* No arguments, command is argument */ +#define SSD1306_SET_CHARGE_PUMP 0x8d /* 1 byte args: A[0]A[7] Volts A[2] Enable */ +#define SSD1306_SET_SEGMENT_MAP_NORMAL 0xa0 /* No arguments */ +#define SSD1306_SET_SEGMENT_MAP_REMAPED 0xa1 /* No arguments */ +#define SSD1306_SET_ENTIRE_DISPLAY_OFF 0xa4 /* No arguments */ +#define SSD1306_SET_ENTIRE_DISPLAY_ON 0xa5 /* No arguments */ +#define SSD1306_SET_NORMAL_DISPLAY 0xa6 /* No arguments */ +#define SSD1306_SET_REVERSE_DISPLAY 0xa7 /* No arguments */ +#define SSD1306_SET_MULTIPLEX_RATIO 0xa8 /* 1 byte args: A[5:0] Multiplex Ratio */ +#define SSD1306_SET_IREF_MODE 0xad /* 1 byte args: A[5:4] Iref configuration */ +#define SH1106_SET_DCDC_MODE 0xad /* No arguments */ +#define SSD1306_SET_DISPLAY_OFF 0xae /* No arguments */ +#define SSD1306_SET_DISPLAY_ON 0xaf /* No arguments */ +#define SSD1306_SET_PAGE_START_ADDRESS 0xb0 /* No arguments, command is argument */ +#define SSD1306_SET_PAGE_START_ADDRESS_END 0xb7 /* Command as argument end */ +#define SSD1306_SET_COM_OUTPUT_SCAN_NORMAL 0xc0 /* No arguments */ +#define SSD1306_SET_COM_OUTPUT_SCAN_FLIPPED 0xc8 /* No arguments */ +#define SSD1306_SET_DISPLAY_OFFSET 0xd3 /* 1 byte args: A[5:0] COM shift */ +#define SSD1306_SET_CLOCK_DIV_RATIO 0xd5 /* 1 byte args: A[3:0] dratio A[7:4] oscfreq */ +#define SSD1306_SET_CHARGE_PERIOD 0xd9 /* 1 byte args: A[3:0] Phase1 A[7:4] Phase2 */ +#define SSD1306_SET_PADS_HW_CONFIG 0xda /* 1 byte args: A[5:4] COM configuration */ +#define SSD1306_SET_VCOM_DESELECT_LEVEL 0xdb /* 1 byte args: A[5:4] Voltage */ -#define SSD1306_CLOCK_DIV_RATIO 0x0 -#define SSD1306_CLOCK_FREQUENCY 0x8 -#define SSD1306_PANEL_VCOM_DESEL_LEVEL 0x20 -#define SSD1306_PANEL_PUMP_VOLTAGE SSD1306_SET_PUMP_VOLTAGE_90 +/* + * Configuration Constants + */ +#define SSD1306_CLOCK_DIV_RATIO 0x0 +#define SSD1306_CLOCK_FREQUENCY 0x8 +#define SSD1306_PANEL_VCOM_DESEL_LEVEL 0x20 +#define SSD1306_PANEL_PUMP_VOLTAGE SSD1306_SET_PUMP_VOLTAGE_90 +#define SSD1306_MEM_ADDRESSING_HORIZONTAL 0x00 +#define SSD1306_MEM_ADDRESSING_VERTICAL 0x01 +#define SSD1306_MEM_ADDRESSING_PAGE 0x02 +#define SSD1306_PANEL_VCOM_DESEL_LEVEL_SSD1309 0x34 +#define SSD1306_PADS_HW_SEQUENTIAL 0x02 +#define SSD1306_PADS_HW_ALTERNATIVE 0x12 +#define SSD1306_PADS_HW_COM_FLIP_SEQUENTIAL 0x22 +#define SSD1306_PADS_HW_COM_FLIP_ALTERNATIVE 0x32 +#define SSD1306_IREF_MODE_INTERNAL_30UA 0x30 +#define SSD1306_IREF_MODE_INTERNAL_19UA 0x10 +#define SSD1306_IREF_MODE_EXTERNAL 0x00 +#define SSD1306_CHARGE_PUMP_DISABLED 0x10 +#define SSD1306_CHARGE_PUMP_ENABLED 0x14 -#define SSD1306_PANEL_VCOM_DESEL_LEVEL_SSD1309 0x34 +/* + * Code Constants + */ +/* All following bytes will contain commands */ +#define SSD1306_I2C_ALL_BYTES_CMD 0x00 +/* All following bytes will contain data */ +#define SSD1306_I2C_ALL_BYTES_DATA 0x40 +/* The next byte will contain a command */ +#define SSD1306_I2C_BYTE_CMD 0x80 +/* The next byte will contain data */ +#define SSD1306_I2C_BYTE_DATA 0xc0 + +#define SSD1306_RESET_DELAY 1 +#define SSD1306_SUPPLY_DELAY 20 #ifndef SSD1306_ADDRESSING_MODE -#define SSD1306_ADDRESSING_MODE (SSD1306_SET_MEM_ADDRESSING_HORIZONTAL) +#define SSD1306_ADDRESSING_MODE (SSD1306_MEM_ADDRESSING_HORIZONTAL) #endif #define SSD1306_PPB_SHIFT 3 +/* + * Fields + */ +#define SSD1306_READ_STATUS_MASK 0xc0 +#define SSD1306_READ_STATUS_BUSY 0x80 +#define SSD1306_READ_STATUS_ON 0x40 +#define SSD1306_SET_LOWER_COL_ADDRESS_MASK 0x0f +#define SSD1306_SET_HIGHER_COL_ADDRESS_MASK 0x0f +#define SSD1306_SET_START_LINE_MASK 0x3f +#define SSD1306_SET_PAGE_START_ADDRESS_MASK 0x07 + union ssd1306_bus { struct i2c_dt_spec i2c; struct spi_dt_spec spi; @@ -86,8 +165,8 @@ static int ssd1306_write_bus_i2c(const struct device *dev, uint8_t *buf, size_t const struct ssd1306_config *config = dev->config; return i2c_burst_write_dt(&config->bus.i2c, - command ? SSD1306_CONTROL_ALL_BYTES_CMD : - SSD1306_CONTROL_ALL_BYTES_DATA, + command ? SSD1306_I2C_ALL_BYTES_CMD : + SSD1306_I2C_ALL_BYTES_DATA, buf, len); } @@ -198,8 +277,8 @@ static inline int ssd1306_set_hardware_config(const struct device *dev) SSD1306_SET_DISPLAY_OFFSET, config->display_offset, SSD1306_SET_PADS_HW_CONFIG, - (config->com_sequential ? SSD1306_SET_PADS_HW_SEQUENTIAL - : SSD1306_SET_PADS_HW_ALTERNATIVE), + (config->com_sequential ? SSD1306_PADS_HW_SEQUENTIAL + : SSD1306_PADS_HW_ALTERNATIVE), SSD1306_SET_MULTIPLEX_RATIO, config->multiplex_ratio, }; @@ -211,9 +290,9 @@ static inline int ssd1306_set_charge_pump(const struct device *dev) { const struct ssd1306_config *config = dev->config; uint8_t cmd_buf[] = { - (config->sh1106_compatible ? SH1106_SET_DCDC_MODE : SSD1306_SET_CHARGE_PUMP_ON), + (config->sh1106_compatible ? SH1106_SET_DCDC_MODE : SSD1306_SET_CHARGE_PUMP), (config->sh1106_compatible ? SH1106_SET_DCDC_ENABLED - : SSD1306_SET_CHARGE_PUMP_ON_ENABLED), + : SSD1306_CHARGE_PUMP_ENABLED), SSD1306_PANEL_PUMP_VOLTAGE, }; @@ -226,7 +305,7 @@ static inline int ssd1306_set_iref_mode(const struct device *dev) const struct ssd1306_config *config = dev->config; uint8_t cmd_buf[] = { SSD1306_SET_IREF_MODE, - SSD1306_SET_IREF_MODE_INTERNAL, + SSD1306_IREF_MODE_INTERNAL_30UA, }; if (config->use_internal_iref) { @@ -240,7 +319,7 @@ static int ssd1306_resume(const struct device *dev) { const struct ssd1306_config *config = dev->config; uint8_t cmd_buf[] = { - SSD1306_DISPLAY_ON, + SSD1306_SET_DISPLAY_ON, }; /* Turn on supply if pin connected */ @@ -256,7 +335,7 @@ static int ssd1306_suspend(const struct device *dev) { const struct ssd1306_config *config = dev->config; uint8_t cmd_buf[] = { - SSD1306_DISPLAY_OFF, + SSD1306_SET_DISPLAY_OFF, }; /* Turn off supply if pin connected */ diff --git a/drivers/display/ssd1306_regs.h b/drivers/display/ssd1306_regs.h deleted file mode 100644 index 87dc3b6ba5b4..000000000000 --- a/drivers/display/ssd1306_regs.h +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright (c) 2018 Phytec Messtechnik GmbH - * - * SPDX-License-Identifier: Apache-2.0 - */ - - -#ifndef __SSD1306_REGS_H__ -#define __SSD1306_REGS_H__ - -/* All following bytes will contain commands */ -#define SSD1306_CONTROL_ALL_BYTES_CMD 0x00 -/* All following bytes will contain data */ -#define SSD1306_CONTROL_ALL_BYTES_DATA 0x40 -/* The next byte will contain a command */ -#define SSD1306_CONTROL_BYTE_CMD 0x80 -/* The next byte will contain data */ -#define SSD1306_CONTROL_BYTE_DATA 0xc0 -#define SSD1306_READ_STATUS_MASK 0xc0 -#define SSD1306_READ_STATUS_BUSY 0x80 -#define SSD1306_READ_STATUS_ON 0x40 - -/* - * Fundamental Command Table - */ -#define SSD1306_SET_CONTRAST_CTRL 0x81 /* double byte command */ - -#define SSD1306_SET_ENTIRE_DISPLAY_OFF 0xa4 -#define SSD1306_SET_ENTIRE_DISPLAY_ON 0xa5 - -/* RAM data of 1 indicates an "ON" pixel */ -#define SSD1306_SET_NORMAL_DISPLAY 0xa6 -/* RAM data of 0 indicates an "ON" pixel */ -#define SSD1306_SET_REVERSE_DISPLAY 0xa7 - -#define SSD1306_DISPLAY_OFF 0xae -#define SSD1306_DISPLAY_ON 0xaf - -/* - * Addressing Setting Command Table - */ -#define SSD1306_SET_LOWER_COL_ADDRESS 0x00 -#define SSD1306_SET_LOWER_COL_ADDRESS_MASK 0x0f - -#define SSD1306_SET_HIGHER_COL_ADDRESS 0x10 -#define SSD1306_SET_HIGHER_COL_ADDRESS_MASK 0x0f - -#define SSD1306_SET_MEM_ADDRESSING_MODE 0x20 /* double byte command */ -#define SSD1306_SET_MEM_ADDRESSING_HORIZONTAL 0x00 -#define SSD1306_SET_MEM_ADDRESSING_VERTICAL 0x01 -#define SSD1306_SET_MEM_ADDRESSING_PAGE 0x02 - -#define SSD1306_SET_COLUMN_ADDRESS 0x21 /* triple byte command */ - -#define SSD1306_SET_PAGE_ADDRESS 0x22 /* triple byte command */ - -#define SSD1306_SET_PAGE_START_ADDRESS 0xb0 -#define SSD1306_SET_PAGE_START_ADDRESS_MASK 0x07 - - -/* - * Hardware Configuration Command Table - */ -#define SSD1306_SET_START_LINE 0x40 -#define SSD1306_SET_START_LINE_MASK 0x3f - -#define SSD1306_SET_SEGMENT_MAP_NORMAL 0xa0 -#define SSD1306_SET_SEGMENT_MAP_REMAPED 0xa1 - -#define SSD1306_SET_MULTIPLEX_RATIO 0xa8 /* double byte command */ - -#define SSD1306_SET_COM_OUTPUT_SCAN_NORMAL 0xc0 -#define SSD1306_SET_COM_OUTPUT_SCAN_FLIPPED 0xc8 - -#define SSD1306_SET_DISPLAY_OFFSET 0xd3 /* double byte command */ - -#define SSD1306_SET_PADS_HW_CONFIG 0xda /* double byte command */ -#define SSD1306_SET_PADS_HW_SEQUENTIAL 0x02 -#define SSD1306_SET_PADS_HW_ALTERNATIVE 0x12 - -#define SSD1306_SET_IREF_MODE 0xad -#define SSD1306_SET_IREF_MODE_INTERNAL 0x30 -#define SSD1306_SET_IREF_MODE_EXTERNAL 0x00 - - -/* - * Timing and Driving Scheme Setting Command Table - */ -#define SSD1306_SET_CLOCK_DIV_RATIO 0xd5 /* double byte command */ - -#define SSD1306_SET_CHARGE_PERIOD 0xd9 /* double byte command */ - -#define SSD1306_SET_VCOM_DESELECT_LEVEL 0xdb /* double byte command */ - -#define SSD1306_NOP 0xe3 - -/* - * Charge Pump Command Table - */ -#define SSD1306_SET_CHARGE_PUMP_ON 0x8d /* double byte command */ -#define SSD1306_SET_CHARGE_PUMP_ON_DISABLED 0x10 -#define SSD1306_SET_CHARGE_PUMP_ON_ENABLED 0x14 - -#define SH1106_SET_DCDC_MODE 0xad /* double byte command */ -#define SH1106_SET_DCDC_DISABLED 0x8a -#define SH1106_SET_DCDC_ENABLED 0x8b - -#define SSD1306_SET_PUMP_VOLTAGE_64 0x30 -#define SSD1306_SET_PUMP_VOLTAGE_74 0x31 -#define SSD1306_SET_PUMP_VOLTAGE_80 0x32 -#define SSD1306_SET_PUMP_VOLTAGE_90 0x33 - -/* - * Read modify write - */ -#define SSD1306_READ_MODIFY_WRITE_START 0xe0 -#define SSD1306_READ_MODIFY_WRITE_END 0xee - -/* time constants in ms */ -#define SSD1306_RESET_DELAY 1 -#define SSD1306_SUPPLY_DELAY 20 - -#endif From a780587ccbff7420d9a2464af5327fad1b68a66e Mon Sep 17 00:00:00 2001 From: Camille BAUD Date: Tue, 20 Jan 2026 15:39:46 +0100 Subject: [PATCH 2406/3659] drivers: display: move ssd1306.c to display_ssd1306.c add missig prefix Signed-off-by: Camille BAUD --- drivers/display/CMakeLists.txt | 2 +- drivers/display/{ssd1306.c => display_ssd1306.c} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename drivers/display/{ssd1306.c => display_ssd1306.c} (100%) diff --git a/drivers/display/CMakeLists.txt b/drivers/display/CMakeLists.txt index 135e0929dd5c..55ea2a4d521f 100644 --- a/drivers/display/CMakeLists.txt +++ b/drivers/display/CMakeLists.txt @@ -39,7 +39,7 @@ zephyr_library_sources_ifdef(CONFIG_RENESAS_RA_GLCDC display_renesas_ra.c) zephyr_library_sources_ifdef(CONFIG_RM67162 display_rm67162.c) zephyr_library_sources_ifdef(CONFIG_RM68200 display_rm68200.c) zephyr_library_sources_ifdef(CONFIG_SH1122 display_sh1122.c) -zephyr_library_sources_ifdef(CONFIG_SSD1306 ssd1306.c) +zephyr_library_sources_ifdef(CONFIG_SSD1306 display_ssd1306.c) zephyr_library_sources_ifdef(CONFIG_SSD1320 display_ssd1320.c) zephyr_library_sources_ifdef(CONFIG_SSD1322 ssd1322.c) zephyr_library_sources_ifdef(CONFIG_SSD1327_5 display_ssd1327_5.c) diff --git a/drivers/display/ssd1306.c b/drivers/display/display_ssd1306.c similarity index 100% rename from drivers/display/ssd1306.c rename to drivers/display/display_ssd1306.c From 0f046ac0de2f0bdb9337d8e9d249fd1cb5006da0 Mon Sep 17 00:00:00 2001 From: Gaetan Perrot Date: Fri, 16 Jan 2026 17:11:12 +0900 Subject: [PATCH 2407/3659] drivers: adc: adc_ambiq: check return value of adc power control Handle the return value of am_hal_adc_power_control() during ADC initialization. The previous code overwrote the return value before it was checked, which could silently ignore failures when powering on the ADC. Fix this by validating the return code and propagating an error if the operation fails. Signed-off-by: Gaetan Perrot --- drivers/adc/adc_ambiq.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/adc/adc_ambiq.c b/drivers/adc/adc_ambiq.c index a5b329019740..8e5068569335 100644 --- a/drivers/adc/adc_ambiq.c +++ b/drivers/adc/adc_ambiq.c @@ -437,6 +437,11 @@ static int adc_ambiq_init(const struct device *dev) /* power on ADC*/ ret = am_hal_adc_power_control(data->adcHandle, AM_HAL_SYSCTRL_WAKE, false); + if (ret != AM_HAL_STATUS_SUCCESS) { + LOG_ERR("Failed to power on ADC, code: %d", ret); + return -EIO; + } + ret = pinctrl_apply_state(cfg->pin_cfg, PINCTRL_STATE_DEFAULT); if (ret < 0) { return ret; From 981872e2030a8bf5b058e16d6f6a0cc0bf487216 Mon Sep 17 00:00:00 2001 From: Gaetan Perrot Date: Tue, 20 Jan 2026 01:52:34 +0900 Subject: [PATCH 2408/3659] drivers: ethernet: nxp_imx_netc: netc_blk: make ierb_init() void ierb_init() never reports an error and cannot fail in practice. Returning an int led to a dead error. Convert ierb_init() to a void function, drop the unused return value checks, and provide a no-op implementation for SoCs that do not require IERB initialization. This simplifies the control flow and removes an unnecessary error condition. Signed-off-by: Gaetan Perrot --- .../ethernet/nxp_imx_netc/eth_nxp_imx_netc_blk.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/drivers/ethernet/nxp_imx_netc/eth_nxp_imx_netc_blk.c b/drivers/ethernet/nxp_imx_netc/eth_nxp_imx_netc_blk.c index 84caf5e3795a..591b23537718 100644 --- a/drivers/ethernet/nxp_imx_netc/eth_nxp_imx_netc_blk.c +++ b/drivers/ethernet/nxp_imx_netc/eth_nxp_imx_netc_blk.c @@ -147,7 +147,7 @@ static int ierb_unlock(const struct device *dev) #ifdef CONFIG_SOC_MIMX9596 /* Set LDID */ -static int ierb_init(const struct device *dev) +static void ierb_init(const struct device *dev) { uintptr_t base = DEVICE_MMIO_NAMED_GET(dev, ierb); @@ -173,8 +173,6 @@ static int ierb_init(const struct device *dev) sys_write32(6, base + IERB_VFAUXR(5)); /* NETC TIMER */ sys_write32(7, base + IERB_T0FAUXR); - - return 0; } static int netcmix_init(const struct device *dev) @@ -190,9 +188,9 @@ static int netcmix_init(const struct device *dev) return 0; } #elif defined(CONFIG_SOC_MIMX94398) -static int ierb_init(const struct device *dev) +static void ierb_init(const struct device *dev) { - return 0; + ARG_UNUSED(dev); } @@ -240,10 +238,7 @@ static int eth_nxp_imx_netc_blk_init(const struct device *dev) } } - if (ierb_init(dev) != 0) { - LOG_ERR("Failed to initialize IERB"); - return -EIO; - } + ierb_init(dev); ret = ierb_lock(dev); if (ret) { From 50ba0244c1136b8bf11fda052e640a84d44bc691 Mon Sep 17 00:00:00 2001 From: Felix Wang Date: Tue, 20 Jan 2026 08:31:47 +0530 Subject: [PATCH 2409/3659] MAINTAINERS: add FelixWang47831 as counter collaborator Add FelixWang47831 as a collaborator for the counter driver. Signed-off-by: Felix Wang --- MAINTAINERS.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index 6b231468d6ba..bf191bbf1ddc 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -1460,6 +1460,7 @@ Documentation Infrastructure: - nordic-krch collaborators: - Holt-Sun + - FelixWang47831 files: - drivers/counter/ - include/zephyr/drivers/counter.h From d9d46c0ce343a895ffcb7b37d8216c38821c7694 Mon Sep 17 00:00:00 2001 From: Yangbo Lu Date: Tue, 20 Jan 2026 09:54:05 +0800 Subject: [PATCH 2410/3659] net: dsa: make dsa_tag.h as common header file Moved dsa_tag.h to include folder as common header file. And we will support iterable section for vendor dsa tag protocol drivers registering. Signed-off-by: Yangbo Lu --- include/zephyr/net/dsa_tag.h | 67 +++++++++++++++++++++++++++ subsys/net/l2/ethernet/dsa/dsa_core.c | 6 +-- subsys/net/l2/ethernet/dsa/dsa_port.c | 5 +- subsys/net/l2/ethernet/dsa/dsa_tag.c | 5 +- subsys/net/l2/ethernet/dsa/dsa_tag.h | 18 ------- 5 files changed, 73 insertions(+), 28 deletions(-) create mode 100644 include/zephyr/net/dsa_tag.h delete mode 100644 subsys/net/l2/ethernet/dsa/dsa_tag.h diff --git a/include/zephyr/net/dsa_tag.h b/include/zephyr/net/dsa_tag.h new file mode 100644 index 000000000000..bd09353402bb --- /dev/null +++ b/include/zephyr/net/dsa_tag.h @@ -0,0 +1,67 @@ +/* + * SPDX-FileCopyrightText: Copyright 2025-2026 NXP + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Definitions for DSA tag protocol + */ + +#ifndef ZEPHYR_INCLUDE_NET_DSA_TAG_H_ +#define ZEPHYR_INCLUDE_NET_DSA_TAG_H_ + +/** + * @brief Definitions for DSA tag protocol + * @defgroup dsa_tag DSA tag protocol + * @since 4.4 + * @version 0.8.0 + * @ingroup ethernet + * @{ + */ + +#include +#ifdef CONFIG_DSA_TAG_PROTOCOL_NETC +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** @cond INTERNAL_HIDDEN */ + +/* + * DSA tag protocol handles packet received by untagging + * + * param iface: Interface of DSA conduit port on which receives the packet + * param pkt: Network packet + * + * Returns: Interface of DSA user port to redirect + */ +struct net_if *dsa_tag_recv(struct net_if *iface, struct net_pkt *pkt); + +/* + * DSA tag protocol handles packet transmitted by tagging + * + * param iface: Interface of DSA user port to transmit + * param pkt: Network packet + * + * Returns: Network packet tagged + */ +struct net_pkt *dsa_tag_xmit(struct net_if *iface, struct net_pkt *pkt); + +/* + * Set up DSA tag protocol + * + * param dev_cpu: Device of DSA CPU port + */ +void dsa_tag_setup(const struct device *dev_cpu); + +/** @endcond */ + +/** + * @} + */ + +#endif /* ZEPHYR_INCLUDE_NET_DSA_TAG_H_ */ diff --git a/subsys/net/l2/ethernet/dsa/dsa_core.c b/subsys/net/l2/ethernet/dsa/dsa_core.c index 610f14e09dc6..f30f12078237 100644 --- a/subsys/net/l2/ethernet/dsa/dsa_core.c +++ b/subsys/net/l2/ethernet/dsa/dsa_core.c @@ -1,6 +1,5 @@ /* - * Copyright 2025 NXP - * + * SPDX-FileCopyrightText: Copyright 2025-2026 NXP * SPDX-License-Identifier: Apache-2.0 */ @@ -9,8 +8,7 @@ LOG_MODULE_REGISTER(net_dsa_core, CONFIG_NET_DSA_LOG_LEVEL); #include #include - -#include "dsa_tag.h" +#include struct net_if *dsa_recv(struct net_if *iface, struct net_pkt *pkt) { diff --git a/subsys/net/l2/ethernet/dsa/dsa_port.c b/subsys/net/l2/ethernet/dsa/dsa_port.c index 8e2dd65347ce..234671006e09 100644 --- a/subsys/net/l2/ethernet/dsa/dsa_port.c +++ b/subsys/net/l2/ethernet/dsa/dsa_port.c @@ -1,6 +1,5 @@ /* - * Copyright 2025 NXP - * + * SPDX-FileCopyrightText: Copyright 2025-2026 NXP * SPDX-License-Identifier: Apache-2.0 */ @@ -10,7 +9,7 @@ LOG_MODULE_REGISTER(net_dsa_port, CONFIG_NET_DSA_LOG_LEVEL); #include #include #include -#include "dsa_tag.h" +#include #if defined(CONFIG_NET_INTERFACE_NAME_LEN) #define INTERFACE_NAME_LEN CONFIG_NET_INTERFACE_NAME_LEN diff --git a/subsys/net/l2/ethernet/dsa/dsa_tag.c b/subsys/net/l2/ethernet/dsa/dsa_tag.c index 014b264642f0..fa7c803e69f4 100644 --- a/subsys/net/l2/ethernet/dsa/dsa_tag.c +++ b/subsys/net/l2/ethernet/dsa/dsa_tag.c @@ -1,6 +1,5 @@ /* - * Copyright 2025 NXP - * + * SPDX-FileCopyrightText: Copyright 2025-2026 NXP * SPDX-License-Identifier: Apache-2.0 */ @@ -9,7 +8,7 @@ LOG_MODULE_REGISTER(net_dsa_tag, CONFIG_NET_DSA_LOG_LEVEL); #include #include -#include "dsa_tag.h" +#include struct net_if *dsa_tag_recv(struct net_if *iface, struct net_pkt *pkt) { diff --git a/subsys/net/l2/ethernet/dsa/dsa_tag.h b/subsys/net/l2/ethernet/dsa/dsa_tag.h deleted file mode 100644 index 2b27bb4435bb..000000000000 --- a/subsys/net/l2/ethernet/dsa/dsa_tag.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright 2025 NXP - * - * SPDX-License-Identifier: Apache-2.0 - */ -#ifndef ZEPHYR_SUBSYS_DSA_TAG_PRIV_H_ -#define ZEPHYR_SUBSYS_DSA_TAG_PRIV_H_ - -#include -#ifdef CONFIG_DSA_TAG_PROTOCOL_NETC -#include -#endif - -struct net_if *dsa_tag_recv(struct net_if *iface, struct net_pkt *pkt); -struct net_pkt *dsa_tag_xmit(struct net_if *iface, struct net_pkt *pkt); -void dsa_tag_setup(const struct device *dev_cpu); - -#endif From 1b14cb18a213f9dc6c9b78c04772284945fcd32e Mon Sep 17 00:00:00 2001 From: Yangbo Lu Date: Tue, 20 Jan 2026 10:08:56 +0800 Subject: [PATCH 2411/3659] net: dsa: support dsa protocol registering with iterable section Supported dsa protocol registering with iterable section. Signed-off-by: Yangbo Lu --- cmake/linker_script/common/common-rom.cmake | 4 ++++ .../linker/common-rom/common-rom-net.ld | 4 ++++ include/zephyr/net/dsa_tag.h | 24 ++++++++++++++++--- include/zephyr/net/dsa_tag_netc.h | 5 +--- subsys/net/l2/ethernet/dsa/dsa_tag.c | 23 +++++++++--------- subsys/net/l2/ethernet/dsa/dsa_tag_netc.c | 6 +++-- 6 files changed, 45 insertions(+), 21 deletions(-) diff --git a/cmake/linker_script/common/common-rom.cmake b/cmake/linker_script/common/common-rom.cmake index 1a1c0f582b03..4e2ca9b84964 100644 --- a/cmake/linker_script/common/common-rom.cmake +++ b/cmake/linker_script/common/common-rom.cmake @@ -240,6 +240,10 @@ if(CONFIG_NET_SOCKETS_SERVICE) ) endif() +if(CONFIG_NET_DSA) + zephyr_iterable_section(NAME dsa_tag_register KVMA RAM_REGION GROUP RODATA_REGION) +endif() + if(CONFIG_INPUT) zephyr_iterable_section(NAME input_callback KVMA RAM_REGION GROUP RODATA_REGION) endif() diff --git a/include/zephyr/linker/common-rom/common-rom-net.ld b/include/zephyr/linker/common-rom/common-rom-net.ld index 2b779e469939..315b078c0c2c 100644 --- a/include/zephyr/linker/common-rom/common-rom-net.ld +++ b/include/zephyr/linker/common-rom/common-rom-net.ld @@ -33,3 +33,7 @@ #if defined(CONFIG_NET_SOCKETS_SERVICE) ITERABLE_SECTION_ROM(net_socket_service_desc, Z_LINK_ITERABLE_SUBALIGN) #endif + +#if defined(CONFIG_NET_DSA) + ITERABLE_SECTION_ROM(dsa_tag_register, Z_LINK_ITERABLE_SUBALIGN) +#endif diff --git a/include/zephyr/net/dsa_tag.h b/include/zephyr/net/dsa_tag.h index bd09353402bb..ac440a668448 100644 --- a/include/zephyr/net/dsa_tag.h +++ b/include/zephyr/net/dsa_tag.h @@ -21,14 +21,32 @@ */ #include -#ifdef CONFIG_DSA_TAG_PROTOCOL_NETC -#include -#endif #ifdef __cplusplus extern "C" { #endif +/** + * @brief Registration information for a dsa tag protocol + */ +struct dsa_tag_register { + /** Protocol ID */ + int proto; + + /** Received packet handler */ + struct net_if *(*recv)(struct net_if *iface, struct net_pkt *pkt); + + /** Transmit packet handler */ + struct net_pkt *(*xmit)(struct net_if *iface, struct net_pkt *pkt); +}; + +#define DSA_TAG_REGISTER(_proto, _recv, _xmit) \ + static const STRUCT_SECTION_ITERABLE(dsa_tag_register, __dsa_tag_register_##_proto) = { \ + .proto = _proto, \ + .recv = _recv, \ + .xmit = _xmit, \ + } + /** @cond INTERNAL_HIDDEN */ /* diff --git a/include/zephyr/net/dsa_tag_netc.h b/include/zephyr/net/dsa_tag_netc.h index 78f8e4a125ba..b9149041bb55 100644 --- a/include/zephyr/net/dsa_tag_netc.h +++ b/include/zephyr/net/dsa_tag_netc.h @@ -1,6 +1,5 @@ /* - * Copyright 2025 NXP - * + * SPDX-FileCopyrightText: Copyright 2025-2026 NXP * SPDX-License-Identifier: Apache-2.0 */ #ifndef ZEPHYR_SUBSYS_DSA_TAG_NETC_H_ @@ -13,6 +12,4 @@ struct dsa_tag_netc_data { #endif }; -struct net_if *dsa_tag_netc_recv(struct net_if *iface, struct net_pkt *pkt); -struct net_pkt *dsa_tag_netc_xmit(struct net_if *iface, struct net_pkt *pkt); #endif /* ZEPHYR_SUBSYS_DSA_TAG_NETC_H_ */ diff --git a/subsys/net/l2/ethernet/dsa/dsa_tag.c b/subsys/net/l2/ethernet/dsa/dsa_tag.c index fa7c803e69f4..7eb1435589a7 100644 --- a/subsys/net/l2/ethernet/dsa/dsa_tag.c +++ b/subsys/net/l2/ethernet/dsa/dsa_tag.c @@ -44,19 +44,18 @@ void dsa_tag_setup(const struct device *dev_cpu) { const struct dsa_port_config *cfg = dev_cpu->config; struct dsa_switch_context *dsa_switch_ctx = dev_cpu->data; + bool match = false; - switch (cfg->tag_proto) { -#ifdef CONFIG_DSA_TAG_PROTOCOL_NETC - case DSA_TAG_PROTO_NETC: - dsa_switch_ctx->dapi->recv = dsa_tag_netc_recv; - dsa_switch_ctx->dapi->xmit = dsa_tag_netc_xmit; - break; -#endif - case DSA_TAG_PROTO_NOTAG: - dsa_switch_ctx->dapi->recv = NULL; - dsa_switch_ctx->dapi->xmit = NULL; - break; - default: + STRUCT_SECTION_FOREACH(dsa_tag_register, tag) { + if (tag->proto == cfg->tag_proto) { + dsa_switch_ctx->dapi->recv = tag->recv; + dsa_switch_ctx->dapi->xmit = tag->xmit; + match = true; + break; + } + } + + if ((!match) && (cfg->tag_proto != DSA_TAG_PROTO_NOTAG)) { LOG_ERR("DSA tag protocol %d not supported", cfg->tag_proto); } diff --git a/subsys/net/l2/ethernet/dsa/dsa_tag_netc.c b/subsys/net/l2/ethernet/dsa/dsa_tag_netc.c index 1ddc31a595e8..0f9a23155519 100644 --- a/subsys/net/l2/ethernet/dsa/dsa_tag_netc.c +++ b/subsys/net/l2/ethernet/dsa/dsa_tag_netc.c @@ -1,6 +1,5 @@ /* - * Copyright 2025 NXP - * + * SPDX-FileCopyrightText: Copyright 2025-2026 NXP * SPDX-License-Identifier: Apache-2.0 */ @@ -9,6 +8,7 @@ LOG_MODULE_REGISTER(net_dsa_tag_netc, CONFIG_NET_DSA_LOG_LEVEL); #include #include +#include #include #include "fsl_netc_tag.h" @@ -157,3 +157,5 @@ struct net_pkt *dsa_tag_netc_xmit(struct net_if *iface, struct net_pkt *pkt) net_pkt_cursor_init(pkt); return pkt; } + +DSA_TAG_REGISTER(DSA_TAG_PROTO_NETC, dsa_tag_netc_recv, dsa_tag_netc_xmit); From cd5bc5caa5799b657426ba68730b6d9e19fec23f Mon Sep 17 00:00:00 2001 From: Yangbo Lu Date: Fri, 16 Jan 2026 12:06:35 +0800 Subject: [PATCH 2412/3659] drivers: ethernet: dsa: improve DSA_NXP_NETC_GCL_LEN Kconfig option Renamed DSA_NXP_NETC_GCL_LEN to DSA_NXP_IMX_NETC_GCL_LEN for naming consistency, and wrapped it in DSA_DRIVERS condition. Signed-off-by: Yangbo Lu --- drivers/ethernet/dsa/Kconfig | 12 ++++++------ drivers/ethernet/dsa/dsa_nxp_imx_netc.c | 11 +++++------ 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/drivers/ethernet/dsa/Kconfig b/drivers/ethernet/dsa/Kconfig index 721be58c2422..aa2597fd4ebc 100644 --- a/drivers/ethernet/dsa/Kconfig +++ b/drivers/ethernet/dsa/Kconfig @@ -75,13 +75,13 @@ config DSA_NXP_IMX_NETC help Add support for NXP i.MX NETC DSA device driver. -endif # DSA_DRIVERS - -config DSA_NXP_NETC_GCL_LEN - int "Gate control list length for i.MX NETC DSA" +config DSA_NXP_IMX_NETC_GCL_LEN + int "Gate control list length for i.MX NETC switch" default 64 range 1 256 depends on DSA_NXP_IMX_NETC && NET_QBV help - Amount of Gate control list to use, reduce to save RAM. - The Max of the value can be 64,128,256. + Amount of Gate control list to use. Small value saves RAM. + The Max of the value can be 64, 128, or 256. + +endif # DSA_DRIVERS diff --git a/drivers/ethernet/dsa/dsa_nxp_imx_netc.c b/drivers/ethernet/dsa/dsa_nxp_imx_netc.c index 4cd2e3952f8d..0829dc550c83 100644 --- a/drivers/ethernet/dsa/dsa_nxp_imx_netc.c +++ b/drivers/ethernet/dsa/dsa_nxp_imx_netc.c @@ -1,6 +1,5 @@ /* - * Copyright 2025 NXP - * + * SPDX-FileCopyrightText: Copyright 2025-2026 NXP * SPDX-License-Identifier: Apache-2.0 */ @@ -36,7 +35,7 @@ struct dsa_netc_config { #ifdef CONFIG_NET_QBV struct netc_qbv_config { netc_tb_tgs_gcl_t tgs_config; - netc_tgs_gate_entry_t gcList[CONFIG_DSA_NXP_NETC_GCL_LEN]; + netc_tgs_gate_entry_t gcList[CONFIG_DSA_NXP_IMX_NETC_GCL_LEN]; }; #endif @@ -105,7 +104,7 @@ static int dsa_netc_port_init(const struct device *dev) #ifdef CONFIG_NET_QBV memset(&(prv->qbv_config[cfg->port_idx].tgs_config), 0, sizeof(netc_tb_tgs_gcl_t)); memset(prv->qbv_config[cfg->port_idx].gcList, 0, - sizeof(netc_tgs_gate_entry_t) * CONFIG_DSA_NXP_NETC_GCL_LEN); + sizeof(netc_tgs_gate_entry_t) * CONFIG_DSA_NXP_IMX_NETC_GCL_LEN); prv->qbv_config[cfg->port_idx].tgs_config.entryID = cfg->port_idx; prv->qbv_config[cfg->port_idx].tgs_config.gcList = prv->qbv_config[cfg->port_idx].gcList; #endif @@ -388,7 +387,7 @@ static int dsa_netc_set_qbv(const struct device *dev, const struct ethernet_conf case ETHERNET_QBV_PARAM_TYPE_GATE_CONTROL_LIST: row = config->qbv_param.gate_control.row; gate_num = ((CONFIG_NET_TC_TX_COUNT) < 8 ? (CONFIG_NET_TC_TX_COUNT) : 8); - if (row > CONFIG_DSA_NXP_NETC_GCL_LEN) { + if (row > CONFIG_DSA_NXP_IMX_NETC_GCL_LEN) { LOG_ERR("The gate control list length exceeds the limit"); return -ENOTSUP; } @@ -451,7 +450,7 @@ static int dsa_netc_get_qbv(const struct device *dev, struct ethernet_config *co case ETHERNET_QBV_PARAM_TYPE_GATE_CONTROL_LIST: row = config->qbv_param.gate_control.row; gate_num = ((CONFIG_NET_TC_TX_COUNT) < 8 ? (CONFIG_NET_TC_TX_COUNT) : 8); - if (row > CONFIG_DSA_NXP_NETC_GCL_LEN) { + if (row > CONFIG_DSA_NXP_IMX_NETC_GCL_LEN) { LOG_ERR("The gate control list length exceeds the limit"); return -ENOTSUP; } From 05c1fecb5b2b0e316881ed1dac29f3463d482595 Mon Sep 17 00:00:00 2001 From: Yangbo Lu Date: Tue, 20 Jan 2026 10:26:19 +0800 Subject: [PATCH 2413/3659] drivers: ethernet: dsa: move dsa_tag_netc driver out of subsys Moved dsa_tag_netc driver out of subsys. Maintained it in drivers/ethernet/dsa as vendor driver. Signed-off-by: Yangbo Lu --- drivers/ethernet/dsa/CMakeLists.txt | 3 +++ drivers/ethernet/dsa/Kconfig | 13 +++++++++++++ drivers/ethernet/dsa/dsa_nxp_imx_netc.c | 2 +- .../net/l2 => drivers}/ethernet/dsa/dsa_tag_netc.c | 5 +++-- .../net => drivers/ethernet/dsa}/dsa_tag_netc.h | 6 +++--- subsys/net/l2/ethernet/dsa/CMakeLists.txt | 1 - subsys/net/l2/ethernet/dsa/Kconfig | 11 ----------- 7 files changed, 23 insertions(+), 18 deletions(-) rename {subsys/net/l2 => drivers}/ethernet/dsa/dsa_tag_netc.c (97%) rename {include/zephyr/net => drivers/ethernet/dsa}/dsa_tag_netc.h (68%) diff --git a/drivers/ethernet/dsa/CMakeLists.txt b/drivers/ethernet/dsa/CMakeLists.txt index 64f5a7f04659..d2ec2f99bfe7 100644 --- a/drivers/ethernet/dsa/CMakeLists.txt +++ b/drivers/ethernet/dsa/CMakeLists.txt @@ -2,3 +2,6 @@ zephyr_library_sources_ifdef(CONFIG_DSA_KSZ8XXX dsa_ksz8xxx.c) zephyr_library_sources_ifdef(CONFIG_DSA_NXP_IMX_NETC dsa_nxp_imx_netc.c) + +# DSA tag protocol drivers +zephyr_library_sources_ifdef(CONFIG_DSA_TAG_PROTOCOL_NETC dsa_tag_netc.c) diff --git a/drivers/ethernet/dsa/Kconfig b/drivers/ethernet/dsa/Kconfig index aa2597fd4ebc..9395622d3ef6 100644 --- a/drivers/ethernet/dsa/Kconfig +++ b/drivers/ethernet/dsa/Kconfig @@ -84,4 +84,17 @@ config DSA_NXP_IMX_NETC_GCL_LEN Amount of Gate control list to use. Small value saves RAM. The Max of the value can be 64, 128, or 256. +# DSA tag protocol drivers +# Tag protocol ID found in + +DSA_PORT_COMPAT := zephyr,dsa-port + +config DSA_TAG_PROTOCOL_NETC + bool "Tag protocol - NETC" + default y + select NET_PKT_CONTROL_BLOCK + depends on $(dt_compat_any_has_prop,$(DSA_PORT_COMPAT),dsa-tag-protocol,1) + help + NXP NETC tag protocol. + endif # DSA_DRIVERS diff --git a/drivers/ethernet/dsa/dsa_nxp_imx_netc.c b/drivers/ethernet/dsa/dsa_nxp_imx_netc.c index 0829dc550c83..815caaf6bda9 100644 --- a/drivers/ethernet/dsa/dsa_nxp_imx_netc.c +++ b/drivers/ethernet/dsa/dsa_nxp_imx_netc.c @@ -7,12 +7,12 @@ LOG_MODULE_REGISTER(dsa_netc, CONFIG_ETHERNET_LOG_LEVEL); #include -#include #include #include #include #include +#include "dsa_tag_netc.h" #include "../eth.h" #include "fsl_netc_switch.h" diff --git a/subsys/net/l2/ethernet/dsa/dsa_tag_netc.c b/drivers/ethernet/dsa/dsa_tag_netc.c similarity index 97% rename from subsys/net/l2/ethernet/dsa/dsa_tag_netc.c rename to drivers/ethernet/dsa/dsa_tag_netc.c index 0f9a23155519..f8582fe3d7b0 100644 --- a/subsys/net/l2/ethernet/dsa/dsa_tag_netc.c +++ b/drivers/ethernet/dsa/dsa_tag_netc.c @@ -4,12 +4,13 @@ */ #include -LOG_MODULE_REGISTER(net_dsa_tag_netc, CONFIG_NET_DSA_LOG_LEVEL); +LOG_MODULE_REGISTER(dsa_tag_netc, CONFIG_ETHERNET_LOG_LEVEL); #include #include #include -#include + +#include "dsa_tag_netc.h" #include "fsl_netc_tag.h" struct net_if *dsa_tag_netc_recv(struct net_if *iface, struct net_pkt *pkt) diff --git a/include/zephyr/net/dsa_tag_netc.h b/drivers/ethernet/dsa/dsa_tag_netc.h similarity index 68% rename from include/zephyr/net/dsa_tag_netc.h rename to drivers/ethernet/dsa/dsa_tag_netc.h index b9149041bb55..a869900673bf 100644 --- a/include/zephyr/net/dsa_tag_netc.h +++ b/drivers/ethernet/dsa/dsa_tag_netc.h @@ -2,8 +2,8 @@ * SPDX-FileCopyrightText: Copyright 2025-2026 NXP * SPDX-License-Identifier: Apache-2.0 */ -#ifndef ZEPHYR_SUBSYS_DSA_TAG_NETC_H_ -#define ZEPHYR_SUBSYS_DSA_TAG_NETC_H_ +#ifndef ZEPHYR_DRIVERS_DSA_TAG_NETC_H_ +#define ZEPHYR_DRIVERS_DSA_TAG_NETC_H_ struct dsa_tag_netc_data { #ifdef CONFIG_NET_L2_PTP @@ -12,4 +12,4 @@ struct dsa_tag_netc_data { #endif }; -#endif /* ZEPHYR_SUBSYS_DSA_TAG_NETC_H_ */ +#endif /* ZEPHYR_DRIVERS_DSA_TAG_NETC_H_ */ diff --git a/subsys/net/l2/ethernet/dsa/CMakeLists.txt b/subsys/net/l2/ethernet/dsa/CMakeLists.txt index d1fe3d015a10..7c5d26ebb2ec 100644 --- a/subsys/net/l2/ethernet/dsa/CMakeLists.txt +++ b/subsys/net/l2/ethernet/dsa/CMakeLists.txt @@ -8,5 +8,4 @@ zephyr_library_sources(dsa_core.c) zephyr_library_sources(dsa_port.c) zephyr_library_sources(dsa_user.c) zephyr_library_sources(dsa_tag.c) -zephyr_library_sources_ifdef(CONFIG_DSA_TAG_PROTOCOL_NETC dsa_tag_netc.c) endif() diff --git a/subsys/net/l2/ethernet/dsa/Kconfig b/subsys/net/l2/ethernet/dsa/Kconfig index e6f09fc71417..ed5e6b69d9e0 100644 --- a/subsys/net/l2/ethernet/dsa/Kconfig +++ b/subsys/net/l2/ethernet/dsa/Kconfig @@ -12,8 +12,6 @@ menuconfig NET_DSA if NET_DSA -DSA_PORT_COMPAT := zephyr,dsa-port - config NET_DSA_DEPRECATED bool "Distributed Switch Architecture support for legacy device" select DEPRECATED @@ -35,15 +33,6 @@ config DSA_TAG_SIZE help Set the DSA tag length in bytes. -# Tag protocol ID found in -config DSA_TAG_PROTOCOL_NETC - bool "Tag protocol - NETC" - default y - select NET_PKT_CONTROL_BLOCK - depends on $(dt_compat_any_has_prop,$(DSA_PORT_COMPAT),dsa-tag-protocol,1) - help - NXP NETC tag protocol. - module = NET_DSA module-dep = NET_LOG module-str = Log level for DSA From b2ac268a66ee191dae9d03a60ae094a33d1be16c Mon Sep 17 00:00:00 2001 From: Yangbo Lu Date: Tue, 20 Jan 2026 11:24:46 +0800 Subject: [PATCH 2414/3659] drivers: ethernet: dsa: make dsa_tag_netc driver native The DSA tag protocol driver should be native for packet tagging and untagging. There is possibility other vendors/IPs use it. So, just defined DSA tag structures in header file instead of using hal header file. Signed-off-by: Yangbo Lu --- drivers/ethernet/dsa/dsa_tag_netc.c | 62 +++++++++--------- drivers/ethernet/dsa/dsa_tag_netc.h | 97 ++++++++++++++++++++++++++++- 2 files changed, 126 insertions(+), 33 deletions(-) diff --git a/drivers/ethernet/dsa/dsa_tag_netc.c b/drivers/ethernet/dsa/dsa_tag_netc.c index f8582fe3d7b0..51f0927594a6 100644 --- a/drivers/ethernet/dsa/dsa_tag_netc.c +++ b/drivers/ethernet/dsa/dsa_tag_netc.c @@ -11,7 +11,6 @@ LOG_MODULE_REGISTER(dsa_tag_netc, CONFIG_ETHERNET_LOG_LEVEL); #include #include "dsa_tag_netc.h" -#include "fsl_netc_tag.h" struct net_if *dsa_tag_netc_recv(struct net_if *iface, struct net_pkt *pkt) { @@ -22,8 +21,8 @@ struct net_if *dsa_tag_netc_recv(struct net_if *iface, struct net_pkt *pkt) (struct dsa_tag_netc_data *)(dsa_switch_ctx->tagger_data); #endif void *header = pkt->frags->data; - uint16_t tag_len = sizeof(netc_swt_tag_host_t); - netc_swt_tag_common_t *tag_common; + uint16_t tag_len = sizeof(struct netc_switch_tag_host); + struct netc_switch_tag_common *tag_common; struct net_if *iface_dst = iface; uint8_t *ptr; @@ -34,26 +33,27 @@ struct net_if *dsa_tag_netc_recv(struct net_if *iface, struct net_pkt *pkt) } /* Handle tag type */ - tag_common = (netc_swt_tag_common_t *)((uintptr_t)pkt->frags->data + NET_ETH_ADDR_LEN * 2); - if (tag_common->type == kNETC_TagForward) { + tag_common = (struct netc_switch_tag_common *)((uintptr_t)pkt->frags->data + + NET_ETH_ADDR_LEN * 2); + if (tag_common->type == NETC_SWITCH_TAG_TYPE_FORWARD) { /* Update tag length per tag type */ - tag_len = sizeof(netc_swt_tag_forward_t); + tag_len = sizeof(struct netc_switch_tag_forward); - } else if (tag_common->type == kNETC_TagToHost) { + } else if (tag_common->type == NETC_SWITCH_TAG_TYPE_TO_HOST) { #ifdef CONFIG_NET_L2_PTP - netc_swt_tag_host_rx_ts_t *tag_rx_ts; - netc_swt_tag_host_tx_ts_t *tag_tx_ts; + struct netc_switch_tag_host_rx_ts *tag_rx_ts; + struct netc_switch_tag_host_tx_ts *tag_tx_ts; uint64_t ts; #endif /* Handle tag sub-type */ - switch (tag_common->subType) { - case kNETC_TagToHostNoTs: + switch (tag_common->subtype) { + case NETC_SWITCH_TAG_SUBTYPE_TO_HOST_NO_TS: /* Normal case */ break; - case kNETC_TagToHostRxTs: + case NETC_SWITCH_TAG_SUBTYPE_TO_HOST_RX_TS: #ifdef CONFIG_NET_L2_PTP - tag_rx_ts = (netc_swt_tag_host_rx_ts_t *)tag_common; + tag_rx_ts = (struct netc_switch_tag_host_rx_ts *)tag_common; ts = net_ntohll(tag_rx_ts->timestamp); /* Fill timestamp */ @@ -61,20 +61,20 @@ struct net_if *dsa_tag_netc_recv(struct net_if *iface, struct net_pkt *pkt) pkt->timestamp.second = ts / NSEC_PER_SEC; #endif /* Update tag length per tag type */ - tag_len = sizeof(netc_swt_tag_host_rx_ts_t); + tag_len = sizeof(struct netc_switch_tag_host_rx_ts); break; - case kNETC_TagToHostTxTs: + case NETC_SWITCH_TAG_SUBTYPE_TO_HOST_TX_TS: #ifdef CONFIG_NET_L2_PTP - tag_tx_ts = (netc_swt_tag_host_tx_ts_t *)tag_common; + tag_tx_ts = (struct netc_switch_tag_host_tx_ts *)tag_common; ts = net_ntohll(tag_tx_ts->timestamp); if (tagger_data->twostep_timestamp_handler != NULL) { tagger_data->twostep_timestamp_handler(dsa_switch_ctx, - tag_tx_ts->tsReqId, ts); + tag_tx_ts->ts_req_id, ts); } #endif /* Update tag length per tag type */ - tag_len = sizeof(netc_swt_tag_host_tx_ts_t); + tag_len = sizeof(struct netc_switch_tag_host_tx_ts); break; default: LOG_ERR("tag sub-type error"); @@ -102,14 +102,14 @@ struct net_pkt *dsa_tag_netc_xmit(struct net_if *iface, struct net_pkt *pkt) struct dsa_port_config *cfg = (struct dsa_port_config *)dev->config; struct net_buf *header_buf; size_t header_len = NET_ETH_ADDR_LEN * 2; - netc_swt_tag_common_t *tag_common; + struct netc_switch_tag_common *tag_common; void *tag; /* Tag is inserted after DMAC/SMAC fields. Decide header size per tag type. */ if (net_ntohs(NET_ETH_HDR(pkt)->type) == NET_ETH_PTYPE_PTP) { - header_len += sizeof(netc_swt_tag_port_two_step_ts_t); + header_len += sizeof(struct netc_switch_tag_port_two_step_ts); } else { - header_len += sizeof(netc_swt_tag_port_no_ts_t); + header_len += sizeof(struct netc_switch_tag_port_no_ts); } /* Allocate net_buf for header */ @@ -131,21 +131,21 @@ struct net_pkt *dsa_tag_netc_xmit(struct net_if *iface, struct net_pkt *pkt) if (net_ntohs(NET_ETH_HDR(pkt)->type) == NET_ETH_PTYPE_PTP) { /* Utilize control block for timestamp request ID */ - ((netc_swt_tag_port_two_step_ts_t *)tag)->tsReqId = pkt->cb.cb[0] & 0xf; + ((struct netc_switch_tag_port_two_step_ts *)tag)->ts_req_id = pkt->cb.cb[0] & 0xf; - tag_common = &((netc_swt_tag_port_two_step_ts_t *)tag)->comTag; - tag_common->subType = kNETC_TagToPortTwoStepTs; + tag_common = &((struct netc_switch_tag_port_two_step_ts *)tag)->common; + tag_common->subtype = NETC_SWITCH_TAG_SUBTYPE_TO_PORT_TWOSTEP_TS; } else { - tag_common = &((netc_swt_tag_port_no_ts_t *)tag)->comTag; - tag_common->subType = kNETC_TagToPortNoTs; + tag_common = &((struct netc_switch_tag_port_no_ts *)tag)->common; + tag_common->subtype = NETC_SWITCH_TAG_SUBTYPE_TO_PORT_NO_TS; } #else - tag_common = &((netc_swt_tag_port_no_ts_t *)tag)->comTag; - tag_common->subType = kNETC_TagToPortNoTs; + tag_common = &((struct netc_switch_tag_port_no_ts *)tag)->common; + tag_common->subtype = NETC_SWITCH_TAG_SUBTYPE_TO_PORT_NO_TS; #endif - tag_common->tpid = NETC_SWITCH_DEFAULT_ETHER_TYPE; - tag_common->type = kNETC_TagToPort; - tag_common->swtId = 1; + tag_common->tpid = NETC_SWITCH_ETHER_TYPE; + tag_common->type = NETC_SWITCH_TAG_TYPE_TO_PORT; + tag_common->swtid = 1; tag_common->port = cfg->port_idx; /* Drop DMAC/SMAC on original frag */ diff --git a/drivers/ethernet/dsa/dsa_tag_netc.h b/drivers/ethernet/dsa/dsa_tag_netc.h index a869900673bf..ca3c67c0417f 100644 --- a/drivers/ethernet/dsa/dsa_tag_netc.h +++ b/drivers/ethernet/dsa/dsa_tag_netc.h @@ -7,9 +7,102 @@ struct dsa_tag_netc_data { #ifdef CONFIG_NET_L2_PTP - void (*twostep_timestamp_handler)(const struct dsa_switch_context *ctx, - uint8_t ts_req_id, uint64_t ts); + void (*twostep_timestamp_handler)(const struct dsa_switch_context *ctx, uint8_t ts_req_id, + uint64_t ts); #endif }; +#define NETC_SWITCH_ETHER_TYPE 0x3AFD + +enum netc_switch_tag_type { + NETC_SWITCH_TAG_TYPE_FORWARD, + NETC_SWITCH_TAG_TYPE_TO_PORT, + NETC_SWITCH_TAG_TYPE_TO_HOST, +}; + +enum netc_switch_tag_subtype { + NETC_SWITCH_TAG_SUBTYPE_TO_PORT_NO_TS = 0, + NETC_SWITCH_TAG_SUBTYPE_TO_PORT_ONESTEP_TS, + NETC_SWITCH_TAG_SUBTYPE_TO_PORT_TWOSTEP_TS, + NETC_SWITCH_TAG_SUBTYPE_TO_PORT_ALL_TS, + + NETC_SWITCH_TAG_SUBTYPE_TO_HOST_NO_TS = 0, + NETC_SWITCH_TAG_SUBTYPE_TO_HOST_RX_TS, + NETC_SWITCH_TAG_SUBTYPE_TO_HOST_TX_TS, +}; + +#pragma pack(1) +/* Switch tag common part */ +struct netc_switch_tag_common { + uint16_t tpid; /* Tag Protocol Identifier to identify the tag as an NXP switch tag. */ + uint16_t subtype: 4; /* Specific feature is based on tag type. */ + uint16_t type: 4; /* Tag type. */ + uint16_t qv: 1; /* QoS Valid. */ + uint16_t: 1; /* Reserved. */ + uint16_t ipv: 3; /* Internal Priority Value. */ + uint16_t: 1; /* Reserved. */ + uint16_t dr: 2; /* Drop Resilience. */ + uint8_t swtid: 3; /* Switch ID. */ + uint8_t port: 5; /* Switch port. */ +}; + +/* Switch tag for forward */ +struct netc_switch_tag_forward { + struct netc_switch_tag_common common; + uint8_t pm: 1; /* Port Masquerading. */ + uint8_t: 7; +}; + +/* Switch tag for to_port without timestamp */ +struct netc_switch_tag_port_no_ts { + struct netc_switch_tag_common common; + uint8_t: 8; +}; + +/* Switch tag for to_port with one-step timestamp */ +struct netc_switch_tag_port_one_step_ts { + struct netc_switch_tag_common common; + uint8_t: 8; + uint32_t timestamp; +}; + +/* Switch tag for to_port without two-step timestamp */ +struct netc_switch_tag_port_two_step_ts { + struct netc_switch_tag_common common; + uint8_t ts_req_id: 4; + uint8_t: 4; +}; + +/* Switch tag for to_port with all timestamps */ +struct netc_switch_tag_port_all_ts { + struct netc_switch_tag_common common; + uint8_t ts_req_id: 4; + uint8_t: 4; + uint32_t timestamp; +}; + +/* Switch tag for to_host */ +struct netc_switch_tag_host { + struct netc_switch_tag_common common; + uint16_t: 4; + uint16_t host_reason: 4; +}; + +/* Switch tag for to_host with timestamp */ +struct netc_switch_tag_host_rx_ts { + struct netc_switch_tag_common common; + uint16_t: 4; + uint16_t host_reason: 4; + uint64_t timestamp; +}; + +/* Switch tag for to_host with timestamp */ +struct netc_switch_tag_host_tx_ts { + struct netc_switch_tag_common common; + uint16_t ts_req_id: 4; + uint16_t host_reason: 4; + uint64_t timestamp; +}; +#pragma pack() + #endif /* ZEPHYR_DRIVERS_DSA_TAG_NETC_H_ */ From 81fd57078de4609d7ada72a037120f5e44d68021 Mon Sep 17 00:00:00 2001 From: TOKITA Hiroshi Date: Tue, 20 Jan 2026 15:47:42 +0900 Subject: [PATCH 2415/3659] MAINTAINERS: Add area for QNX Hypervisor Add area for supporting QNX Hypervisor Virtual Machine. Signed-off-by: TOKITA Hiroshi --- MAINTAINERS.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index bf191bbf1ddc..1656a133f92d 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -4327,6 +4327,16 @@ Power management: tests: - pm +QNX Hypervisor Platforms: + status: maintained + maintainers: + - soburi + files: + - boards/blackberry/qnxhv_vm/ + - soc/blackberry/qnxhv_vm/ + labels: + - "platform: QNX Hypervisor" + "Quicklogic Platform": status: odd fixes files: From 33196ff3cdd973248c0a277fd99eb125dc53eece Mon Sep 17 00:00:00 2001 From: Camille BAUD Date: Fri, 31 Oct 2025 02:06:29 +0100 Subject: [PATCH 2416/3659] dts: adc: add bindings for bflb adc Adds the bindings for the GPADC Signed-off-by: Camille BAUD --- dts/bindings/adc/bflb,adc.yaml | 23 +++++++++++++++++++++++ dts/riscv/bflb/bl60x.dtsi | 15 ++++++++++++++- dts/riscv/bflb/bl61x.dtsi | 15 ++++++++++++++- dts/riscv/bflb/bl70x.dtsi | 15 ++++++++++++++- 4 files changed, 65 insertions(+), 3 deletions(-) create mode 100644 dts/bindings/adc/bflb,adc.yaml diff --git a/dts/bindings/adc/bflb,adc.yaml b/dts/bindings/adc/bflb,adc.yaml new file mode 100644 index 000000000000..b4a8388ece72 --- /dev/null +++ b/dts/bindings/adc/bflb,adc.yaml @@ -0,0 +1,23 @@ +# Copyright (c) 2025 MASSDRIVER EI (massdriver.space) +# +# SPDX-License-Identifier: Apache-2.0 + +description: | + Bouffalolab ADC + +compatible: "bflb,adc" + +include: [adc-controller.yaml, pinctrl-device.yaml] + +properties: + reg: + required: true + + interrupts: + required: true + + "#io-channel-cells": + const: 1 + +io-channel-cells: + - input diff --git a/dts/riscv/bflb/bl60x.dtsi b/dts/riscv/bflb/bl60x.dtsi index d6f8429c7987..4ab191e8d149 100644 --- a/dts/riscv/bflb/bl60x.dtsi +++ b/dts/riscv/bflb/bl60x.dtsi @@ -1,6 +1,6 @@ /* * Copyright (c) 2021-2025 ATL Electronics - * Copyright (c) 2024-2025 MASSDRIVER EI (massdriver.space) + * Copyright (c) 2024-2026 MASSDRIVER EI (massdriver.space) * * SPDX-License-Identifier: Apache-2.0 */ @@ -15,6 +15,7 @@ #include #include #include +#include / { #address-cells = <1>; @@ -145,6 +146,18 @@ "pll_120", "pll_48"; }; + adc0: adc@40002000 { + compatible = "bflb,adc"; + reg = <0x40002000 0x1000 0x4000F000 0x1000>; + #io-channel-cells = <1>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + interrupts = <41 0>; + interrupt-parent = <&clic>; + }; + efuse: efuse@40007000 { compatible = "bflb,efuse"; reg = <0x40007000 0x1000>; diff --git a/dts/riscv/bflb/bl61x.dtsi b/dts/riscv/bflb/bl61x.dtsi index be944d11a907..f63d472ec28a 100644 --- a/dts/riscv/bflb/bl61x.dtsi +++ b/dts/riscv/bflb/bl61x.dtsi @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024-2025 MASSDRIVER EI (massdriver.space) + * Copyright (c) 2024-2026 MASSDRIVER EI (massdriver.space) * * SPDX-License-Identifier: Apache-2.0 */ @@ -14,6 +14,7 @@ #include #include #include +#include / { #address-cells = <1>; @@ -160,6 +161,18 @@ "root", "bclk", "flash"; }; + adc0: adc@20002000 { + compatible = "bflb,adc"; + reg = <0x20002000 0x400 0x2000F000 0x1000>; + #io-channel-cells = <1>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + interrupts = <41 1>; + interrupt-parent = <&clic>; + }; + uart0: uart@2000a000 { compatible = "bflb,uart"; reg = <0x2000a000 0x100>; diff --git a/dts/riscv/bflb/bl70x.dtsi b/dts/riscv/bflb/bl70x.dtsi index 4956750ea14a..1e6aadac74cf 100644 --- a/dts/riscv/bflb/bl70x.dtsi +++ b/dts/riscv/bflb/bl70x.dtsi @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024-2025 MASSDRIVER EI (massdriver.space) + * Copyright (c) 2024-2026 MASSDRIVER EI (massdriver.space) * * SPDX-License-Identifier: Apache-2.0 */ @@ -14,6 +14,7 @@ #include #include #include +#include / { #address-cells = <1>; @@ -150,6 +151,18 @@ "dll_120", "dll_57"; }; + adc0: adc@40002000 { + compatible = "bflb,adc"; + reg = <0x40002000 0x1000 0x4000F000 0x1000>; + #io-channel-cells = <1>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + interrupts = <41 0>; + interrupt-parent = <&clic>; + }; + efuse: efuse@40007000 { compatible = "bflb,efuse"; reg = <0x40007000 0x1000>; From bddaa08afd5d6077ee7970f121e13dba5d9a86cf Mon Sep 17 00:00:00 2001 From: Camille BAUD Date: Fri, 31 Oct 2025 02:06:58 +0100 Subject: [PATCH 2417/3659] drivers: adc: add bflb adc driver Adds a driver for the GPADC Signed-off-by: Camille BAUD --- drivers/adc/CMakeLists.txt | 1 + drivers/adc/Kconfig | 1 + drivers/adc/Kconfig.bflb | 10 + drivers/adc/adc_bflb.c | 702 +++++++++++++++++++++++++++++++++++++ 4 files changed, 714 insertions(+) create mode 100644 drivers/adc/Kconfig.bflb create mode 100644 drivers/adc/adc_bflb.c diff --git a/drivers/adc/CMakeLists.txt b/drivers/adc/CMakeLists.txt index 847cffd5514a..fee7e54a7639 100644 --- a/drivers/adc/CMakeLists.txt +++ b/drivers/adc/CMakeLists.txt @@ -22,6 +22,7 @@ zephyr_library_sources_ifdef(CONFIG_ADC_ADS1X1X adc_ads1x1x.c) zephyr_library_sources_ifdef(CONFIG_ADC_ADS1X4S0X adc_ads1x4s0x.c) zephyr_library_sources_ifdef(CONFIG_ADC_ADS7052 adc_ads7052.c) zephyr_library_sources_ifdef(CONFIG_ADC_AMBIQ adc_ambiq.c) +zephyr_library_sources_ifdef(CONFIG_ADC_BFLB adc_bflb.c) zephyr_library_sources_ifdef(CONFIG_ADC_CC13XX_CC26XX adc_cc13xx_cc26xx.c) zephyr_library_sources_ifdef(CONFIG_ADC_CC23X0 adc_cc23x0.c) zephyr_library_sources_ifdef(CONFIG_ADC_CC32XX adc_cc32xx.c) diff --git a/drivers/adc/Kconfig b/drivers/adc/Kconfig index 04e88d05c60d..d8b5d42b009c 100644 --- a/drivers/adc/Kconfig +++ b/drivers/adc/Kconfig @@ -88,6 +88,7 @@ source "drivers/adc/Kconfig.ads1x4s0x" source "drivers/adc/Kconfig.ads7052" source "drivers/adc/Kconfig.ambiq" source "drivers/adc/Kconfig.b91" +source "drivers/adc/Kconfig.bflb" source "drivers/adc/Kconfig.cc13xx_cc26xx" source "drivers/adc/Kconfig.cc23x0" source "drivers/adc/Kconfig.cc32xx" diff --git a/drivers/adc/Kconfig.bflb b/drivers/adc/Kconfig.bflb new file mode 100644 index 000000000000..3b0e5511b7c8 --- /dev/null +++ b/drivers/adc/Kconfig.bflb @@ -0,0 +1,10 @@ +# Copyright (c) 2024-2025 MASSDRIVER EI +# SPDX-License-Identifier: Apache-2.0 + +config ADC_BFLB + bool "Bouffalolab ADC driver" + default y + depends on DT_HAS_BFLB_ADC_ENABLED + select ADC_CONFIGURABLE_INPUTS + help + Enables the Bouffalolab ADC driver. diff --git a/drivers/adc/adc_bflb.c b/drivers/adc/adc_bflb.c new file mode 100644 index 000000000000..e649026fceaa --- /dev/null +++ b/drivers/adc/adc_bflb.c @@ -0,0 +1,702 @@ +/* + * Copyright (c) 2024-2025 MASSDRIVER EI (massdriver.space) + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT bflb_adc + +#include +#include +#include +#include + +#include +LOG_MODULE_REGISTER(adc_bflb, CONFIG_ADC_LOG_LEVEL); + +#include +#include +#include +#include +#include +#include + +#define ADC_CHAN_SELECT_PER_SCN 6 +#define ADC_CHAN_SELECT_SIZE_SCN 5 +#define ADC_CHAN_SELECT_MSK_SCN 0x1f +#define ADC_CHAN_COUNT 12 +#define ADC_CHAN_INPUT_COUNT 0x1f + +#define ADC_GAIN_1_ID 1 +#define ADC_GAIN_2_ID 2 +#define ADC_GAIN_4_ID 3 +#define ADC_GAIN_8_ID 4 +#define ADC_GAIN_16_ID 5 +#define ADC_GAIN_32_ID 6 + +#define ADC_GAIN_UNSET ADC_GAIN_128 + +#define ADC_RESOLUTION_12B_ID 0 +#define ADC_RESOLUTION_14B_ID 2 +#define ADC_RESOLUTION_16B_ID 4 + +#define ADC_INPUT_ID_HALF_VBAT 18 +#define ADC_INPUT_ID_GND 23 + +#define ADC_RESULT_POSITIVE_INPUT 0x3E00000 +#define ADC_RESULT_POSITIVE_INPUT_POS 21 +#define ADC_RESULT_NEGATIVE_INPUT 0x1F0000 +#define ADC_RESULT_NEGATIVE_INPUT_POS 16 +#define ADC_RESULT 0xFFFF + +#define ADC_WAIT_TIMEOUT_MS 500 + +#define ADC_CLK_DIV_32 7 + +struct adc_bflb_config { + uint32_t reg_GPIP; + uint32_t reg_AON; + const struct pinctrl_dev_config *pcfg; + void (*irq_config_func)(const struct device *dev); +}; + +struct adc_bflb_data { + uint8_t channel_count; + uint8_t channel_p[12]; + uint8_t channel_n[12]; + enum adc_gain gain; + bool differential; + float cal_coe; + uint16_t cal_off; +}; + +static void adc_bflb_channel_set_channel(const struct device *dev, uint8_t id, + uint8_t channel_number_n, uint8_t channel_number_p) +{ + const struct adc_bflb_config *const cfg = dev->config; + uint32_t offset_p = AON_GPADC_REG_SCN_POS1_OFFSET; + uint32_t offset_n = AON_GPADC_REG_SCN_NEG1_OFFSET; + uint32_t tmp; + + if (id >= ADC_CHAN_SELECT_PER_SCN) { + offset_p = AON_GPADC_REG_SCN_POS2_OFFSET; + offset_n = AON_GPADC_REG_SCN_NEG2_OFFSET; + } + + tmp = sys_read32(cfg->reg_AON + offset_p); + tmp &= ~(ADC_CHAN_SELECT_MSK_SCN + << ((id % ADC_CHAN_SELECT_PER_SCN) * ADC_CHAN_SELECT_SIZE_SCN)); + tmp |= channel_number_p << ((id % ADC_CHAN_SELECT_PER_SCN) * ADC_CHAN_SELECT_SIZE_SCN); + sys_write32(tmp, cfg->reg_AON + offset_p); + + tmp = sys_read32(cfg->reg_AON + offset_n); + tmp &= ~(ADC_CHAN_SELECT_MSK_SCN + << ((id % ADC_CHAN_SELECT_PER_SCN) * ADC_CHAN_SELECT_SIZE_SCN)); + tmp |= channel_number_n << ((id % ADC_CHAN_SELECT_PER_SCN) * ADC_CHAN_SELECT_SIZE_SCN); + sys_write32(tmp, cfg->reg_AON + offset_n); +} + +static int adc_bflb_channel_setup(const struct device *dev, + const struct adc_channel_cfg *channel_cfg) +{ + const struct adc_bflb_config *const cfg = dev->config; + struct adc_bflb_data *data = dev->data; + uint32_t tmp; + uint8_t channel_id = channel_cfg->channel_id; + uint8_t gain = ADC_GAIN_1_ID; + + if (data->channel_count > ADC_CHAN_COUNT) { + LOG_ERR("Too many channels"); + return -ENOTSUP; + } + if (channel_cfg->input_negative > ADC_CHAN_INPUT_COUNT + || channel_cfg->input_positive > ADC_CHAN_INPUT_COUNT) { + LOG_ERR("Bad channel number(s)"); + return -EINVAL; + } + + if (channel_id >= ADC_CHAN_COUNT) { + LOG_ERR("Bad channel ID"); + return -EINVAL; + } + + switch (channel_cfg->gain) { + case ADC_GAIN_1: + gain = ADC_GAIN_1_ID; + break; + case ADC_GAIN_2: + gain = ADC_GAIN_2_ID; + break; + case ADC_GAIN_4: + gain = ADC_GAIN_4_ID; + break; + case ADC_GAIN_8: + gain = ADC_GAIN_8_ID; + break; + case ADC_GAIN_16: + gain = ADC_GAIN_16_ID; + break; + case ADC_GAIN_32: + gain = ADC_GAIN_32_ID; + break; + default: + LOG_ERR("Gain must be between 1 and 32 (included), cannot be 3, 6, 12, 24"); + return -EINVAL; + } + + if (data->gain != ADC_GAIN_UNSET && data->gain != channel_cfg->gain) { + LOG_WRN("Gain does not match previously set gain, gain is global for this adc"); + } + data->gain = channel_cfg->gain; + + if (data->gain != ADC_GAIN_UNSET && data->differential != channel_cfg->differential) { + LOG_WRN("Differential mode does not match previously set mode, it is global"); + } + + if (channel_cfg->differential) { + data->channel_n[channel_id] = channel_cfg->input_negative; + } else { + data->channel_n[channel_id] = ADC_INPUT_ID_GND; + } + data->channel_p[channel_id] = channel_cfg->input_positive; + + if (data->channel_count == 0) { + tmp = sys_read32(cfg->reg_AON + AON_GPADC_REG_CONFIG1_OFFSET); + tmp |= AON_GPADC_CONT_CONV_EN; + tmp &= ~AON_GPADC_SCAN_EN; + tmp &= ~AON_GPADC_CLK_ANA_INV; + sys_write32(tmp, cfg->reg_AON + AON_GPADC_REG_CONFIG1_OFFSET); + + tmp = sys_read32(cfg->reg_AON + AON_GPADC_REG_CMD_OFFSET); + tmp &= ~AON_GPADC_POS_SEL_MASK; + tmp &= ~AON_GPADC_NEG_SEL_MASK; + if (channel_cfg->differential) { + tmp &= ~AON_GPADC_NEG_GND; + tmp |= channel_cfg->input_negative << AON_GPADC_NEG_SEL_SHIFT; + } else { + tmp |= AON_GPADC_NEG_GND; + /* GND channel */ + tmp |= ADC_INPUT_ID_GND << AON_GPADC_NEG_SEL_SHIFT; + } + tmp |= channel_cfg->input_positive << AON_GPADC_POS_SEL_SHIFT; + sys_write32(tmp, cfg->reg_AON + AON_GPADC_REG_CMD_OFFSET); + + adc_bflb_channel_set_channel(dev, 0, data->channel_n[channel_id], + data->channel_p[channel_id]); + } else { + tmp = sys_read32(cfg->reg_AON + AON_GPADC_REG_CONFIG1_OFFSET); + tmp &= ~AON_GPADC_CONT_CONV_EN; + tmp |= AON_GPADC_SCAN_EN; + tmp |= AON_GPADC_CLK_ANA_INV; + tmp &= ~AON_GPADC_SCAN_LENGTH_MASK; + tmp |= data->channel_count << AON_GPADC_SCAN_LENGTH_SHIFT; + sys_write32(tmp, cfg->reg_AON + AON_GPADC_REG_CONFIG1_OFFSET); + + tmp = sys_read32(cfg->reg_AON + AON_GPADC_REG_CMD_OFFSET); + tmp &= ~AON_GPADC_POS_SEL_MASK; + tmp &= ~AON_GPADC_NEG_SEL_MASK; + tmp |= AON_GPADC_NEG_GND; + sys_write32(tmp, cfg->reg_AON + AON_GPADC_REG_CMD_OFFSET); + + adc_bflb_channel_set_channel(dev, data->channel_count, data->channel_n[channel_id], + data->channel_p[channel_id]); + } + + tmp = sys_read32(cfg->reg_AON + AON_GPADC_REG_CONFIG2_OFFSET); + tmp |= (gain << AON_GPADC_PGA1_GAIN_SHIFT); + tmp |= (gain << AON_GPADC_PGA2_GAIN_SHIFT); + if (channel_cfg->differential) { + tmp |= AON_GPADC_DIFF_MODE; + } else { + tmp &= ~AON_GPADC_DIFF_MODE; + } + sys_write32(tmp, cfg->reg_AON + AON_GPADC_REG_CONFIG2_OFFSET); + + data->channel_count++; + + return 0; +} + +static uint32_t adc_bflb_read_one(const struct device *dev) +{ + const struct adc_bflb_config *const cfg = dev->config; + + while ((sys_read32(cfg->reg_GPIP + GPIP_GPADC_CONFIG_OFFSET) & + GPIP_GPADC_FIFO_DATA_COUNT_MASK) == 0) { + clock_bflb_settle(); + } + return sys_read32(cfg->reg_GPIP + GPIP_GPADC_DMA_RDATA_OFFSET) & GPIP_GPADC_DMA_RDATA_MASK; +} + +static void adc_bflb_trigger(const struct device *dev) +{ + const struct adc_bflb_config *const cfg = dev->config; + uint32_t tmp; + + tmp = sys_read32(cfg->reg_AON + AON_GPADC_REG_CMD_OFFSET); + tmp |= AON_GPADC_CONV_START; + sys_write32(tmp, cfg->reg_AON + AON_GPADC_REG_CMD_OFFSET); +} + +static void adc_bflb_detrigger(const struct device *dev) +{ + const struct adc_bflb_config *const cfg = dev->config; + uint32_t tmp; + + tmp = sys_read32(cfg->reg_AON + AON_GPADC_REG_CMD_OFFSET); + tmp &= ~AON_GPADC_CONV_START; + sys_write32(tmp, cfg->reg_AON + AON_GPADC_REG_CMD_OFFSET); +} + +static int adc_bflb_read(const struct device *dev, + const struct adc_sequence *sequence) +{ + struct adc_bflb_data *data = dev->data; + const struct adc_bflb_config *const cfg = dev->config; + uint32_t tmp; + uint8_t chan_nb = 0; + uint32_t nb_samples = 0; + uint8_t sample_chans[ADC_CHAN_COUNT] = {0}; + k_timepoint_t end_timeout = sys_timepoint_calc(K_MSEC(ADC_WAIT_TIMEOUT_MS)); + + for (uint8_t i = 0; i < ADC_CHAN_COUNT; i++) { + if ((sequence->channels >> i) & 0x1) { + sample_chans[chan_nb] = i; + chan_nb += 1; + } + } + + nb_samples = sequence->buffer_size / 2 / chan_nb; + if (nb_samples < 1) { + LOG_ERR("resolution 12 to 16 bits, buffer size invalid"); + return -EINVAL; + } + + tmp = sys_read32(cfg->reg_AON + AON_GPADC_REG_CONFIG1_OFFSET); + tmp &= ~AON_GPADC_RES_SEL_MASK; + + switch (sequence->resolution) { + case 12: + tmp |= ADC_RESOLUTION_12B_ID << AON_GPADC_RES_SEL_SHIFT; + break; + case 14: + tmp |= ADC_RESOLUTION_14B_ID << AON_GPADC_RES_SEL_SHIFT; + break; + case 16: + tmp |= ADC_RESOLUTION_16B_ID << AON_GPADC_RES_SEL_SHIFT; + break; + default: + LOG_ERR("resolution 12, 14 or 16 bits, resolution invalid"); + return -EINVAL; + } + sys_write32(tmp, cfg->reg_AON + AON_GPADC_REG_CONFIG1_OFFSET); + + tmp = sys_read32(cfg->reg_GPIP + GPIP_GPADC_CONFIG_OFFSET); + tmp |= GPIP_GPADC_FIFO_CLR; + sys_write32(tmp, cfg->reg_GPIP + GPIP_GPADC_CONFIG_OFFSET); + + adc_bflb_trigger(dev); + + for (int i = 0; i < nb_samples; i++) { + for (int j = 0; j < chan_nb; j++) { + tmp = adc_bflb_read_one(dev); + while (((tmp & ADC_RESULT_POSITIVE_INPUT) + >> ADC_RESULT_POSITIVE_INPUT_POS + != data->channel_p[sample_chans[j]] + || (tmp & ADC_RESULT_NEGATIVE_INPUT) + >> ADC_RESULT_NEGATIVE_INPUT_POS + != data->channel_n[sample_chans[j]]) + && !sys_timepoint_expired(end_timeout)) { + tmp = adc_bflb_read_one(dev); + } + ((uint16_t *)sequence->buffer)[i * chan_nb + j] = ((tmp & ADC_RESULT) + >> (16 - sequence->resolution)) / data->cal_coe - data->cal_off; + } + } + + if (sys_timepoint_expired(end_timeout)) { + return -ETIMEDOUT; + } + + adc_bflb_detrigger(dev); + + return 0; +} + +static void adc_bflb_isr(const struct device *dev) +{ + /* Do nothing */ +} + +#if defined(CONFIG_SOC_SERIES_BL60X) +static void adc_bflb_calibrate_dynamic(const struct device *dev) +{ + struct adc_bflb_data *data = dev->data; + const struct adc_bflb_config *const cfg = dev->config; + volatile uint32_t tmp; + volatile uint32_t offset = 0; + bool negative = false; + + tmp = sys_read32(cfg->reg_AON + AON_GPADC_REG_CONFIG1_OFFSET); + /* resolution 16-bits */ + tmp |= (ADC_RESOLUTION_16B_ID << AON_GPADC_RES_SEL_SHIFT); + /* continuous mode */ + tmp |= AON_GPADC_CONT_CONV_EN; + sys_write32(tmp, cfg->reg_AON + AON_GPADC_REG_CONFIG1_OFFSET); + + tmp = sys_read32(cfg->reg_AON + AON_GPADC_REG_CONFIG2_OFFSET); + tmp |= AON_GPADC_DIFF_MODE; + tmp |= AON_GPADC_VBAT_EN; + tmp &= ~AON_GPADC_VREF_SEL; + sys_write32(tmp, cfg->reg_AON + AON_GPADC_REG_CONFIG2_OFFSET); + + tmp = sys_read32(cfg->reg_AON + AON_GPADC_REG_CMD_OFFSET); + tmp &= ~AON_GPADC_NEG_GND; + tmp &= ~AON_GPADC_POS_SEL_MASK; + tmp &= ~AON_GPADC_NEG_SEL_MASK; + tmp |= (ADC_INPUT_ID_HALF_VBAT << AON_GPADC_POS_SEL_SHIFT); + tmp |= (ADC_INPUT_ID_HALF_VBAT << AON_GPADC_NEG_SEL_SHIFT); + sys_write32(tmp, cfg->reg_AON + AON_GPADC_REG_CMD_OFFSET); + + tmp = sys_read32(cfg->reg_GPIP + GPIP_GPADC_CONFIG_OFFSET); + tmp |= GPIP_GPADC_FIFO_CLR; + sys_write32(tmp, cfg->reg_GPIP + GPIP_GPADC_CONFIG_OFFSET); + + clock_bflb_settle(); + clock_bflb_settle(); + clock_bflb_settle(); + + adc_bflb_trigger(dev); + /* 10 samplings */ + for (uint8_t i = 0; i < 10; i++) { + tmp = adc_bflb_read_one(dev); + /* only consider samples after the first 5 */ + if (i > 4) { + if (tmp & 0x8000) { + negative = true; + tmp = ~tmp; + tmp += 1; + } + offset += (tmp & 0xffff); + } + } + + adc_bflb_detrigger(dev); + offset = offset / 5; + if (negative) { + data->cal_coe += (float)offset / 2048.0f; + } else { + data->cal_coe -= (float)offset / 2048.0f; + } +} +#endif + +static void adc_bflb_calibrate_gnd_offset(const struct device *dev) +{ + struct adc_bflb_data *data = dev->data; + const struct adc_bflb_config *const cfg = dev->config; + volatile uint32_t tmp; + volatile uint32_t offset = 0; + + tmp = sys_read32(cfg->reg_AON + AON_GPADC_REG_CONFIG1_OFFSET); + tmp |= (ADC_RESOLUTION_16B_ID << AON_GPADC_RES_SEL_SHIFT); + tmp |= AON_GPADC_CONT_CONV_EN; + tmp &= ~AON_GPADC_SCAN_EN; + tmp &= ~AON_GPADC_CLK_ANA_INV; + sys_write32(tmp, cfg->reg_AON + AON_GPADC_REG_CONFIG1_OFFSET); + + tmp = sys_read32(cfg->reg_AON + AON_GPADC_REG_CONFIG2_OFFSET); + tmp &= ~AON_GPADC_DIFF_MODE; + tmp &= ~AON_GPADC_VBAT_EN; + tmp &= ~AON_GPADC_VREF_SEL; + sys_write32(tmp, cfg->reg_AON + AON_GPADC_REG_CONFIG2_OFFSET); + + tmp = sys_read32(cfg->reg_AON + AON_GPADC_REG_CMD_OFFSET); + tmp |= AON_GPADC_NEG_GND; + tmp &= ~AON_GPADC_POS_SEL_MASK; + tmp &= ~AON_GPADC_NEG_SEL_MASK; + tmp |= (ADC_INPUT_ID_GND << AON_GPADC_POS_SEL_SHIFT); + tmp |= (ADC_INPUT_ID_GND << AON_GPADC_NEG_SEL_SHIFT); + sys_write32(tmp, cfg->reg_AON + AON_GPADC_REG_CMD_OFFSET); + + tmp = sys_read32(cfg->reg_GPIP + GPIP_GPADC_CONFIG_OFFSET); + tmp |= GPIP_GPADC_FIFO_CLR; + sys_write32(tmp, cfg->reg_GPIP + GPIP_GPADC_CONFIG_OFFSET); + + clock_bflb_settle(); + clock_bflb_settle(); + clock_bflb_settle(); + + adc_bflb_trigger(dev); + /* 10 samplings */ + for (uint8_t i = 0; i < 10; i++) { + tmp = adc_bflb_read_one(dev); + /* only consider samples after the first 5 */ + if (i > 4) { + offset += (tmp & ADC_RESULT); + } + } + + adc_bflb_detrigger(dev); + data->cal_off = offset / 5; +} + +#if defined(CONFIG_SOC_SERIES_BL70X) +static int adc_bflb_calibrate_efuse(const struct device *dev) +{ + struct adc_bflb_data *data = dev->data; + const struct device *efuse = DEVICE_DT_GET_ONE(bflb_efuse); + int ret; + uint32_t trim; + + ret = syscon_read_reg(efuse, 0x78, &trim); + if (ret < 0) { + LOG_ERR("Error: Couldn't read efuses: err: %d.\n", ret); + return -EINVAL; + } + if ((trim & 0x4000) == 0) { + LOG_ERR("Error: ADC calibration data not present"); + return -EINVAL; + } + trim = (trim & 0x1FFE) >> 1; + if (trim & 0x800) { + trim = ~trim; + trim += 1; + trim = trim & 0xfff; + data->cal_coe = ((float)1.0 + ((float)trim / (float)2048.0)); + } else { + data->cal_coe = ((float)1.0 - ((float)trim / (float)2048.0)); + } + return 0; +} +#elif defined(CONFIG_SOC_SERIES_BL61X) +static int adc_bflb_calibrate_efuse(const struct device *dev) +{ + struct adc_bflb_data *data = dev->data; + const struct device *efuse = DEVICE_DT_GET_ONE(bflb_efuse); + int ret; + uint32_t trim; + + ret = syscon_read_reg(efuse, 0xF0, &trim); + if (ret < 0) { + LOG_ERR("Error: Couldn't read efuses: err: %d.\n", ret); + return -EINVAL; + } + if ((trim & 0x4000000) == 0) { + LOG_ERR("Error: ADC calibration data not present"); + return -EINVAL; + } + trim = (trim & 0x3FFC000) >> 14; + if (trim & 0x800) { + trim = ~trim; + trim += 1; + trim = trim & 0xfff; + data->cal_coe = ((float)1.0 + ((float)trim / (float)2048.0)); + } else { + data->cal_coe = ((float)1.0 - ((float)trim / (float)2048.0)); + } + return 0; +} +#endif + +#if defined(CONFIG_SOC_SERIES_BL60X) || defined(CONFIG_SOC_SERIES_BL70X) +static void adc_bflb_init_clock(const struct device *dev) +{ + uint32_t tmp; + + /* clock pathing*/ + tmp = sys_read32(GLB_BASE + GLB_GPADC_32M_SRC_CTRL_OFFSET); + /* clock = XTAL or RC32M (32M) */ + tmp |= GLB_GPADC_32M_CLK_SEL_MSK; + /* div = 1 so ADC gets 32Mhz */ + tmp &= ~GLB_GPADC_32M_CLK_DIV_MSK; + /* enable */ + tmp |= GLB_GPADC_32M_DIV_EN_MSK; + sys_write32(tmp, GLB_BASE + GLB_GPADC_32M_SRC_CTRL_OFFSET); +} + +#elif defined(CONFIG_SOC_SERIES_BL61X) +static void adc_bflb_init_clock(const struct device *dev) +{ + uint32_t tmp; + + /* clock pathing*/ + tmp = sys_read32(GLB_BASE + GLB_ADC_CFG0_OFFSET); + /* clock = XTAL or RC32M (32M) */ + tmp |= GLB_GPADC_32M_CLK_SEL_MSK; + /* div = 1 so ADC gets 32Mhz */ + tmp &= ~GLB_GPADC_32M_CLK_DIV_MSK; + /* enable */ + tmp |= GLB_GPADC_32M_DIV_EN_MSK; + sys_write32(tmp, GLB_BASE + GLB_ADC_CFG0_OFFSET); +} +#else +#error Unsupported Platform +#endif + +static int adc_bflb_init(const struct device *dev) +{ + const struct adc_bflb_config *const cfg = dev->config; + uint32_t tmp; + int ret; + + ret = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT); + if (ret < 0) { + return ret; + } + + adc_bflb_init_clock(dev); + + /* peripheral reset sequence */ + tmp = sys_read32(cfg->reg_AON + AON_GPADC_REG_CMD_OFFSET); + tmp &= ~AON_GPADC_GLOBAL_EN; + sys_write32(tmp, cfg->reg_AON + AON_GPADC_REG_CMD_OFFSET); + + tmp = sys_read32(cfg->reg_AON + AON_GPADC_REG_CMD_OFFSET); + tmp |= AON_GPADC_GLOBAL_EN; + sys_write32(tmp, cfg->reg_AON + AON_GPADC_REG_CMD_OFFSET); + + tmp = sys_read32(cfg->reg_AON + AON_GPADC_REG_CMD_OFFSET); + tmp |= AON_GPADC_SOFT_RST; + sys_write32(tmp, cfg->reg_AON + AON_GPADC_REG_CMD_OFFSET); + + clock_bflb_settle(); + clock_bflb_settle(); + clock_bflb_settle(); + + tmp = sys_read32(cfg->reg_AON + AON_GPADC_REG_CMD_OFFSET); + tmp &= ~AON_GPADC_CONV_START; + sys_write32(tmp, cfg->reg_AON + AON_GPADC_REG_CMD_OFFSET); + + tmp = sys_read32(cfg->reg_AON + AON_GPADC_REG_CMD_OFFSET); + tmp &= ~AON_GPADC_SOFT_RST; + sys_write32(tmp, cfg->reg_AON + AON_GPADC_REG_CMD_OFFSET); + + tmp = 0; + /* enable power to adc? */ + tmp |= (2 << AON_GPADC_V18_SEL_SHIFT); + tmp |= (1 << AON_GPADC_V11_SEL_SHIFT); + /* set internal clock divider to 32 */ + tmp |= (ADC_CLK_DIV_32 << AON_GPADC_CLK_DIV_RATIO_SHIFT); + /* default resolution (12-bits) */ + tmp |= (ADC_RESOLUTION_12B_ID << AON_GPADC_RES_SEL_SHIFT); + tmp &= ~AON_GPADC_CONT_CONV_EN; + tmp &= ~AON_GPADC_SCAN_EN; + sys_write32(tmp, cfg->reg_AON + AON_GPADC_REG_CONFIG1_OFFSET); + + clock_bflb_settle(); + clock_bflb_settle(); + clock_bflb_settle(); + + tmp = 0; + /* ""conversion speed"" */ + tmp |= (2 << AON_GPADC_DLY_SEL_SHIFT); + /* ""Vref AZ and chop on"" */ + tmp |= (2 << AON_GPADC_CHOP_MODE_SHIFT); + /* "gain 1" is 1 */ + tmp |= (1 << AON_GPADC_PGA1_GAIN_SHIFT); + /* "gain 2" is 1 */ + tmp |= (1 << AON_GPADC_PGA2_GAIN_SHIFT); + /* enable gain */ + tmp |= AON_GPADC_PGA_EN; + /* "offset calibration" value */ + tmp |= (8 << AON_GPADC_PGA_OS_CAL_SHIFT); + /* "VCM" is 1.2v */ + tmp |= (1 << AON_GPADC_PGA_VCM_SHIFT); + /* ADC reference (VREF channel) is 3v3 */ + tmp &= ~AON_GPADC_VREF_SEL; + sys_write32(tmp, cfg->reg_AON + AON_GPADC_REG_CONFIG2_OFFSET); + + tmp = sys_read32(cfg->reg_AON + AON_GPADC_REG_CMD_OFFSET); + /* "MIC2" differential mode enable */ + tmp |= AON_GPADC_MIC2_DIFF; + /* single ended mode is achieved by setting differential other end to ground */ + tmp |= AON_GPADC_NEG_GND; + sys_write32(tmp, cfg->reg_AON + AON_GPADC_REG_CMD_OFFSET); + + /* clear calibration */ + tmp = sys_read32(cfg->reg_AON + AON_GPADC_REG_DEFINE_OFFSET); + tmp &= ~AON_GPADC_OS_CAL_DATA_MASK; + sys_write32(tmp, cfg->reg_AON + AON_GPADC_REG_DEFINE_OFFSET); + + /* interrupts and status setup */ + tmp = sys_read32(cfg->reg_GPIP + GPIP_GPADC_CONFIG_OFFSET); + tmp |= (GPIP_GPADC_FIFO_UNDERRUN_MASK + | GPIP_GPADC_FIFO_OVERRUN_MASK + | GPIP_GPADC_RDY_MASK + | GPIP_GPADC_FIFO_UNDERRUN_CLR + | GPIP_GPADC_FIFO_OVERRUN_CLR + | GPIP_GPADC_RDY_CLR); +#ifdef CONFIG_SOC_SERIES_BL70X + tmp |= (GPIP_GPADC_FIFO_RDY_MASK | GPIP_GPADC_FIFO_RDY); +#endif + tmp |= GPIP_GPADC_FIFO_CLR; + tmp &= ~GPIP_GPADC_FIFO_THL_MASK; + tmp &= ~GPIP_GPADC_DMA_EN; + sys_write32(tmp, cfg->reg_GPIP + GPIP_GPADC_CONFIG_OFFSET); + + clock_bflb_settle(); + + tmp = sys_read32(cfg->reg_GPIP + GPIP_GPADC_CONFIG_OFFSET); + tmp &= ~(GPIP_GPADC_FIFO_UNDERRUN_CLR + | GPIP_GPADC_FIFO_OVERRUN_CLR + | GPIP_GPADC_RDY_CLR + | GPIP_GPADC_FIFO_CLR); + sys_write32(tmp, cfg->reg_GPIP + GPIP_GPADC_CONFIG_OFFSET); + + tmp = sys_read32(cfg->reg_AON + AON_GPADC_REG_ISR_OFFSET); + tmp |= AON_GPADC_NEG_SATUR_MASK; + tmp |= AON_GPADC_POS_SATUR_MASK; + sys_write32(tmp, cfg->reg_AON + AON_GPADC_REG_ISR_OFFSET); + +#if defined(CONFIG_SOC_SERIES_BL60X) + adc_bflb_calibrate_dynamic(dev); + adc_bflb_calibrate_gnd_offset(dev); +#else + ret = adc_bflb_calibrate_efuse(dev); + if (ret < 0) { + LOG_ERR("Couldn't calibrate via efuses"); + return ret; + } + adc_bflb_calibrate_gnd_offset(dev); +#endif + + cfg->irq_config_func(dev); + return 0; +} + +static DEVICE_API(adc, adc_bflb_api) = { + .channel_setup = adc_bflb_channel_setup, + .read = adc_bflb_read, + .ref_internal = 3200, +}; + +#define ADC_BFLB_DEVICE(n) \ + PINCTRL_DT_INST_DEFINE(n); \ + static void adc_bflb_irq_config_##n(const struct device *dev) \ + { \ + IRQ_CONNECT(DT_INST_IRQN(n), \ + DT_INST_IRQ(n, priority), \ + adc_bflb_isr, \ + DEVICE_DT_INST_GET(n), 0); \ + irq_enable(DT_INST_IRQN(n)); \ + } \ + static const struct adc_bflb_config adc_bflb_config_##n = { \ + .reg_GPIP = DT_INST_REG_ADDR_BY_IDX(n, 0), \ + .reg_AON = DT_INST_REG_ADDR_BY_IDX(n, 1), \ + .irq_config_func = &adc_bflb_irq_config_##n, \ + .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ + }; \ + static struct adc_bflb_data adc_bflb_data_##n = { \ + .channel_count = 0, \ + .gain = ADC_GAIN_UNSET, \ + .cal_off = 0, \ + .cal_coe = 1.0f, \ + }; \ + DEVICE_DT_INST_DEFINE(n, adc_bflb_init, NULL, \ + &adc_bflb_data_##n, \ + &adc_bflb_config_##n, POST_KERNEL, \ + CONFIG_ADC_INIT_PRIORITY, \ + &adc_bflb_api); + +DT_INST_FOREACH_STATUS_OKAY(ADC_BFLB_DEVICE) From b8b2d2ed2187f1a9168ce9f040a6e53aa0a35771 Mon Sep 17 00:00:00 2001 From: Camille BAUD Date: Fri, 31 Oct 2025 02:14:01 +0100 Subject: [PATCH 2418/3659] samples: adc_dt: Add some bflb boards Add ADC sample overlays Signed-off-by: Camille BAUD --- .../adc/adc_dt/boards/ai_m61_32s_kit.overlay | 45 ++++++++++++++++++ .../adc_dt/boards/dt_xt_zb1_devkit.overlay | 47 +++++++++++++++++++ 2 files changed, 92 insertions(+) create mode 100644 samples/drivers/adc/adc_dt/boards/ai_m61_32s_kit.overlay create mode 100644 samples/drivers/adc/adc_dt/boards/dt_xt_zb1_devkit.overlay diff --git a/samples/drivers/adc/adc_dt/boards/ai_m61_32s_kit.overlay b/samples/drivers/adc/adc_dt/boards/ai_m61_32s_kit.overlay new file mode 100644 index 000000000000..96bd41ae6a8d --- /dev/null +++ b/samples/drivers/adc/adc_dt/boards/ai_m61_32s_kit.overlay @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2024-2026 MASSDRIVER EI (massdriver.space) + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + zephyr,user { + io-channels = <&adc0 0>, <&adc0 1>; + }; +}; + +&pinctrl { + adc0_default: adc0_default { + group1 { + pinmux = , + ; + }; + }; +}; + +&adc0 { + status = "okay"; + + pinctrl-0 = <&adc0_default>; + pinctrl-names = "default"; + + channel@0 { + reg = <0>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <16>; + zephyr,input-positive = <4>; + }; + + channel@1 { + reg = <1>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <16>; + zephyr,input-positive = <5>; + }; +}; diff --git a/samples/drivers/adc/adc_dt/boards/dt_xt_zb1_devkit.overlay b/samples/drivers/adc/adc_dt/boards/dt_xt_zb1_devkit.overlay new file mode 100644 index 000000000000..16b7f2e34af8 --- /dev/null +++ b/samples/drivers/adc/adc_dt/boards/dt_xt_zb1_devkit.overlay @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2024-2025 MASSDRIVER EI (massdriver.space) + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + zephyr,user { + io-channels = <&adc0 0>, <&adc0 1>; + }; +}; + +&pinctrl { + adc0_default: adc0_default { + group1 { + pinmux = , + ; + }; + }; +}; + +&adc0 { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + + pinctrl-0 = <&adc0_default>; + pinctrl-names = "default"; + + channel@0 { + reg = <0>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <16>; + zephyr,input-positive = <6>; + }; + + channel@1 { + reg = <1>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <16>; + zephyr,input-positive = <0>; + }; +}; From 7ac12165dd1d908d1bab7fa850a57ec1f08be59b Mon Sep 17 00:00:00 2001 From: Camille BAUD Date: Fri, 31 Oct 2025 02:24:49 +0100 Subject: [PATCH 2419/3659] boards: bflb: Add ADC entry to boards with marked 'ADC' pins Adds adc entry so driver is built. Signed-off-by: Camille BAUD --- .../ai_m62_12f_kit-pinctrl.dtsi | 8 ++++++- .../ai_m62_12f_kit/ai_m62_12f_kit.dts | 22 ++++++++++++++++++- .../ai_m62_12f_kit/ai_m62_12f_kit.yaml | 1 + .../ai_wb2_12f_kit-pinctrl.dtsi | 8 ++++++- .../ai_wb2_12f_kit/ai_wb2_12f_kit.dts | 22 ++++++++++++++++++- .../ai_wb2_12f_kit/ai_wb2_12f_kit.yaml | 1 + 6 files changed, 58 insertions(+), 4 deletions(-) diff --git a/boards/aithinker/ai_m62_12f_kit/ai_m62_12f_kit-pinctrl.dtsi b/boards/aithinker/ai_m62_12f_kit/ai_m62_12f_kit-pinctrl.dtsi index 2ff265f2e2c5..9b4e0853fb60 100644 --- a/boards/aithinker/ai_m62_12f_kit/ai_m62_12f_kit-pinctrl.dtsi +++ b/boards/aithinker/ai_m62_12f_kit/ai_m62_12f_kit-pinctrl.dtsi @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024-2025 MASSDRIVER EI (massdriver.space) + * Copyright (c) 2024-2026 MASSDRIVER EI (massdriver.space) * * SPDX-License-Identifier: Apache-2.0 */ @@ -32,4 +32,10 @@ drive-strength = <1>; }; }; + + adc0_default: adc0_default { + group1 { + pinmux = ; + }; + }; }; diff --git a/boards/aithinker/ai_m62_12f_kit/ai_m62_12f_kit.dts b/boards/aithinker/ai_m62_12f_kit/ai_m62_12f_kit.dts index fc3a1c707233..9cc967abb9df 100644 --- a/boards/aithinker/ai_m62_12f_kit/ai_m62_12f_kit.dts +++ b/boards/aithinker/ai_m62_12f_kit/ai_m62_12f_kit.dts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024-2025 MASSDRIVER EI (massdriver.space) + * Copyright (c) 2024-2026 MASSDRIVER EI (massdriver.space) * * SPDX-License-Identifier: Apache-2.0 */ @@ -85,6 +85,10 @@ zephyr,code = ; }; }; + + zephyr,user { + io-channels = <&adc0 0>; + }; }; &i2c0 { @@ -101,3 +105,19 @@ pinctrl-0 = <&spi0_default>; pinctrl-names = "default"; }; + +&adc0 { + status = "okay"; + + pinctrl-0 = <&adc0_default>; + pinctrl-names = "default"; + + channel@0 { + reg = <0>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <16>; + zephyr,input-positive = <0>; + }; +}; diff --git a/boards/aithinker/ai_m62_12f_kit/ai_m62_12f_kit.yaml b/boards/aithinker/ai_m62_12f_kit/ai_m62_12f_kit.yaml index 9735f959fd14..a7bdae2167f1 100644 --- a/boards/aithinker/ai_m62_12f_kit/ai_m62_12f_kit.yaml +++ b/boards/aithinker/ai_m62_12f_kit/ai_m62_12f_kit.yaml @@ -23,4 +23,5 @@ supported: - flash - input - pwm + - adc vendor: bflb diff --git a/boards/aithinker/ai_wb2_12f_kit/ai_wb2_12f_kit-pinctrl.dtsi b/boards/aithinker/ai_wb2_12f_kit/ai_wb2_12f_kit-pinctrl.dtsi index acf2c447b815..ffe8585718f5 100644 --- a/boards/aithinker/ai_wb2_12f_kit/ai_wb2_12f_kit-pinctrl.dtsi +++ b/boards/aithinker/ai_wb2_12f_kit/ai_wb2_12f_kit-pinctrl.dtsi @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024-2025 MASSDRIVER EI (massdriver.space) + * Copyright (c) 2024-2026 MASSDRIVER EI (massdriver.space) * * SPDX-License-Identifier: Apache-2.0 */ @@ -32,4 +32,10 @@ drive-strength = <1>; }; }; + + adc0_default: adc0_default { + group1 { + pinmux = ; + }; + }; }; diff --git a/boards/aithinker/ai_wb2_12f_kit/ai_wb2_12f_kit.dts b/boards/aithinker/ai_wb2_12f_kit/ai_wb2_12f_kit.dts index 51ee647a2f4d..d58c3879cc6e 100644 --- a/boards/aithinker/ai_wb2_12f_kit/ai_wb2_12f_kit.dts +++ b/boards/aithinker/ai_wb2_12f_kit/ai_wb2_12f_kit.dts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024-2025 MASSDRIVER EI (massdriver.space) + * Copyright (c) 2024-2026 MASSDRIVER EI (massdriver.space) * * SPDX-License-Identifier: Apache-2.0 */ @@ -65,6 +65,10 @@ zephyr,code = ; }; }; + + zephyr,user { + io-channels = <&adc0 0>; + }; }; &i2c0 { @@ -81,3 +85,19 @@ pinctrl-0 = <&spi0_default>; pinctrl-names = "default"; }; + +&adc0 { + status = "okay"; + + pinctrl-0 = <&adc0_default>; + pinctrl-names = "default"; + + channel@0 { + reg = <0>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <16>; + zephyr,input-positive = <10>; + }; +}; diff --git a/boards/aithinker/ai_wb2_12f_kit/ai_wb2_12f_kit.yaml b/boards/aithinker/ai_wb2_12f_kit/ai_wb2_12f_kit.yaml index 77cf6f189871..e55219b611f5 100644 --- a/boards/aithinker/ai_wb2_12f_kit/ai_wb2_12f_kit.yaml +++ b/boards/aithinker/ai_wb2_12f_kit/ai_wb2_12f_kit.yaml @@ -23,4 +23,5 @@ supported: - flash - input - pwm + - adc vendor: bflb From dd8e364863ba8656891389e3956e1040c16b0ceb Mon Sep 17 00:00:00 2001 From: Lucien Zhao Date: Sun, 21 Dec 2025 12:05:18 +0800 Subject: [PATCH 2420/3659] boards: nxp: frdm_mcxe247: config flexio0 pinmux - configure flexio pwm default pinmux Signed-off-by: Lucien Zhao --- boards/nxp/frdm_mcxe247/frdm_mcxe247-pinctrl.dtsi | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/boards/nxp/frdm_mcxe247/frdm_mcxe247-pinctrl.dtsi b/boards/nxp/frdm_mcxe247/frdm_mcxe247-pinctrl.dtsi index 42aa5471decb..5cd0f8d6e254 100644 --- a/boards/nxp/frdm_mcxe247/frdm_mcxe247-pinctrl.dtsi +++ b/boards/nxp/frdm_mcxe247/frdm_mcxe247-pinctrl.dtsi @@ -84,4 +84,12 @@ input-enable; }; }; + + flexio_pwm_default: flexio_pwm_default { + group0 { + pinmux = ; + drive-strength = "low"; + slew-rate = "slow"; + }; + }; }; From f63b15ddd06222ccb5763e94409cc79768e88fac Mon Sep 17 00:00:00 2001 From: Lucien Zhao Date: Sun, 21 Dec 2025 12:07:40 +0800 Subject: [PATCH 2421/3659] tests: drivers: pwm: enable pwm_api case by using flexio0 - enable pwm_api case by using flexio function - record platform information in testcase.yaml Signed-off-by: Lucien Zhao --- .../boards/frdm_mcxe247_flexio_pwm.overlay | 29 +++++++++++++++++++ tests/drivers/pwm/pwm_api/testcase.yaml | 2 ++ 2 files changed, 31 insertions(+) create mode 100644 tests/drivers/pwm/pwm_api/boards/frdm_mcxe247_flexio_pwm.overlay diff --git a/tests/drivers/pwm/pwm_api/boards/frdm_mcxe247_flexio_pwm.overlay b/tests/drivers/pwm/pwm_api/boards/frdm_mcxe247_flexio_pwm.overlay new file mode 100644 index 000000000000..a0e2df1f375d --- /dev/null +++ b/tests/drivers/pwm/pwm_api/boards/frdm_mcxe247_flexio_pwm.overlay @@ -0,0 +1,29 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* PWM signal is visible on J2-4. */ +/ { + aliases { + pwm-test = &flexio0_pwm; + }; +}; + +&flexio0 { + status = "okay"; + + flexio0_pwm: flexio0_pwm { + compatible = "nxp,flexio-pwm"; + #pwm-cells = <3>; + status = "okay"; + pinctrl-0 = <&flexio_pwm_default>; + pinctrl-names = "default"; + + pwm_0 { + pin-id = <7>; + prescaler = <1>; + }; + }; +}; diff --git a/tests/drivers/pwm/pwm_api/testcase.yaml b/tests/drivers/pwm/pwm_api/testcase.yaml index a88aaaca39f2..48658cdbd771 100644 --- a/tests/drivers/pwm/pwm_api/testcase.yaml +++ b/tests/drivers/pwm/pwm_api/testcase.yaml @@ -20,6 +20,7 @@ tests: - platform:mimxrt1180_evk/mimxrt1189/cm7:DTC_OVERLAY_FILE="boards/mimxrt1180_evk_flexio_pwm.overlay" - platform:frdm_mcxa366/mcxa366:DTC_OVERLAY_FILE="boards/frdm_mcxa366_flexio_pwm.overlay" - platform:frdm_mcxa266/mcxa266:DTC_OVERLAY_FILE="boards/frdm_mcxa266_flexio_pwm.overlay" + - platform:frdm_mcxe247/mcxe247:DTC_OVERLAY_FILE="boards/frdm_mcxe247_flexio_pwm.overlay" platform_allow: - frdm_ke17z - frdm_ke17z512 @@ -28,6 +29,7 @@ tests: - mimxrt1180_evk/mimxrt1189/cm7 - frdm_mcxa366/mcxa366 - frdm_mcxa266/mcxa266 + - frdm_mcxe247 filter: dt_alias_exists("pwm-test") and CONFIG_DT_HAS_NXP_FLEXIO_ENABLED and CONFIG_DT_HAS_NXP_FLEXIO_PWM_ENABLED depends_on: pwm From 0923d2cedff2a98f34b717935c6e75ae74102f78 Mon Sep 17 00:00:00 2001 From: The Nguyen Date: Thu, 18 Sep 2025 18:26:06 +0000 Subject: [PATCH 2422/3659] manifest: update revision of hal_renesas Update hal_renesas revision to add BSP code support Signed-off-by: The Nguyen --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 9ab9b81e5ded..ff2f3230cbe4 100644 --- a/west.yml +++ b/west.yml @@ -231,7 +231,7 @@ manifest: - hal - name: hal_renesas path: modules/hal/renesas - revision: 56c35ce22bac062a9d6b1fc87f145b5d48571efb + revision: 14f3c2bdd307009eaf9520cdfda2cbabb81e8d10 groups: - hal - name: hal_rpi_pico From 9dd9132688c39b391ceab767fcf24b04ede67b83 Mon Sep 17 00:00:00 2001 From: The Nguyen Date: Thu, 18 Sep 2025 18:27:55 +0000 Subject: [PATCH 2423/3659] soc: renesas: ra: soc init hooks refactor This commit updates the source files for Renesas RA initialization: - The SoC reset/init now uses generic hooks from the "soc/renesas/ra/common" instead of SoC-specific initialization hooks. - Add soc_reset_hooks() to perform the early reset code. - Battery-backup domain initialization has been removed from soc_early_init() and reallocated to soc_reset_hooks(). Signed-off-by: The Nguyen Signed-off-by: Khoa Tran --- soc/renesas/ra/CMakeLists.txt | 5 +- soc/renesas/ra/Kconfig | 4 +- soc/renesas/ra/common/CMakeLists.txt | 26 ++++ .../ra/{common_fsp => common}/pinctrl_soc.h | 6 +- soc/renesas/ra/common/platform_init.ld | 8 ++ .../ra/{ra2l1 => common}/ram_sections.ld | 0 soc/renesas/ra/common/soc.c | 30 +++++ soc/renesas/ra/common/soc.h | 17 +++ .../ra/{common_fsp => common}/vector_data.h | 2 + soc/renesas/ra/common_fsp/CMakeLists.txt | 5 - soc/renesas/ra/common_fsp/battery_backup.c | 56 --------- soc/renesas/ra/common_fsp/battery_backup.h | 16 --- soc/renesas/ra/common_fsp/cold_start.c | 29 ----- soc/renesas/ra/common_fsp/cold_start.h | 17 --- soc/renesas/ra/ra2a1/CMakeLists.txt | 12 -- soc/renesas/ra/ra2a1/Kconfig | 1 - soc/renesas/ra/ra2a1/ram_sections.ld | 17 --- soc/renesas/ra/ra2a1/soc.c | 51 -------- soc/renesas/ra/ra2a1/soc.h | 16 --- soc/renesas/ra/ra2l1/CMakeLists.txt | 12 -- soc/renesas/ra/ra2l1/Kconfig | 1 - soc/renesas/ra/ra2l1/soc.c | 52 -------- soc/renesas/ra/ra2l1/soc.h | 17 --- soc/renesas/ra/ra4c1/CMakeLists.txt | 12 -- soc/renesas/ra/ra4c1/Kconfig | 1 - soc/renesas/ra/ra4c1/ram_sections.ld | 16 --- soc/renesas/ra/ra4c1/soc.c | 62 --------- soc/renesas/ra/ra4c1/soc.h | 16 --- soc/renesas/ra/ra4e1/CMakeLists.txt | 12 -- soc/renesas/ra/ra4e1/Kconfig | 1 - soc/renesas/ra/ra4e1/ram_sections.ld | 16 --- soc/renesas/ra/ra4e1/soc.c | 76 ----------- soc/renesas/ra/ra4e1/soc.h | 16 --- soc/renesas/ra/ra4e2/CMakeLists.txt | 7 -- soc/renesas/ra/ra4e2/Kconfig | 1 - soc/renesas/ra/ra4e2/ram_sections.ld | 16 --- soc/renesas/ra/ra4e2/soc.c | 76 ----------- soc/renesas/ra/ra4e2/soc.h | 16 --- soc/renesas/ra/ra4l1/CMakeLists.txt | 12 -- soc/renesas/ra/ra4l1/Kconfig | 1 - soc/renesas/ra/ra4l1/ram_sections.ld | 16 --- soc/renesas/ra/ra4l1/soc.c | 76 ----------- soc/renesas/ra/ra4l1/soc.h | 16 --- soc/renesas/ra/ra4m1/CMakeLists.txt | 12 -- soc/renesas/ra/ra4m1/Kconfig | 1 - soc/renesas/ra/ra4m1/ram_sections.ld | 17 --- soc/renesas/ra/ra4m1/soc.c | 72 ----------- soc/renesas/ra/ra4m1/soc.h | 16 --- soc/renesas/ra/ra4m2/CMakeLists.txt | 12 -- soc/renesas/ra/ra4m2/Kconfig | 1 - soc/renesas/ra/ra4m2/ram_sections.ld | 16 --- soc/renesas/ra/ra4m2/soc.c | 76 ----------- soc/renesas/ra/ra4m2/soc.h | 16 --- soc/renesas/ra/ra4m3/CMakeLists.txt | 12 -- soc/renesas/ra/ra4m3/Kconfig | 1 - soc/renesas/ra/ra4m3/ram_sections.ld | 16 --- soc/renesas/ra/ra4m3/soc.c | 76 ----------- soc/renesas/ra/ra4m3/soc.h | 16 --- soc/renesas/ra/ra4t1/CMakeLists.txt | 5 - soc/renesas/ra/ra4t1/Kconfig | 1 - soc/renesas/ra/ra4t1/ram_sections.ld | 16 --- soc/renesas/ra/ra4t1/soc.c | 76 ----------- soc/renesas/ra/ra4t1/soc.h | 16 --- soc/renesas/ra/ra4w1/CMakeLists.txt | 12 -- soc/renesas/ra/ra4w1/Kconfig | 1 - soc/renesas/ra/ra4w1/ram_sections.ld | 16 --- soc/renesas/ra/ra4w1/soc.c | 51 -------- soc/renesas/ra/ra4w1/soc.h | 16 --- soc/renesas/ra/ra6e1/CMakeLists.txt | 12 -- soc/renesas/ra/ra6e1/Kconfig | 1 - soc/renesas/ra/ra6e1/ram_sections.ld | 16 --- soc/renesas/ra/ra6e1/soc.c | 81 ------------ soc/renesas/ra/ra6e1/soc.h | 16 --- soc/renesas/ra/ra6e2/CMakeLists.txt | 12 -- soc/renesas/ra/ra6e2/Kconfig | 1 - soc/renesas/ra/ra6e2/ram_sections.ld | 16 --- soc/renesas/ra/ra6e2/soc.c | 81 ------------ soc/renesas/ra/ra6e2/soc.h | 16 --- soc/renesas/ra/ra6m1/CMakeLists.txt | 12 -- soc/renesas/ra/ra6m1/Kconfig | 1 - soc/renesas/ra/ra6m1/ram_sections.ld | 16 --- soc/renesas/ra/ra6m1/soc.c | 56 --------- soc/renesas/ra/ra6m1/soc.h | 16 --- soc/renesas/ra/ra6m2/CMakeLists.txt | 12 -- soc/renesas/ra/ra6m2/Kconfig | 1 - soc/renesas/ra/ra6m2/ram_sections.ld | 16 --- soc/renesas/ra/ra6m2/soc.c | 56 --------- soc/renesas/ra/ra6m2/soc.h | 16 --- soc/renesas/ra/ra6m3/CMakeLists.txt | 12 -- soc/renesas/ra/ra6m3/Kconfig | 1 - soc/renesas/ra/ra6m3/ram_sections.ld | 16 --- soc/renesas/ra/ra6m3/soc.c | 56 --------- soc/renesas/ra/ra6m3/soc.h | 16 --- soc/renesas/ra/ra6m4/CMakeLists.txt | 18 +-- soc/renesas/ra/ra6m4/Kconfig | 1 - soc/renesas/ra/ra6m4/ram_sections.ld | 16 --- soc/renesas/ra/ra6m4/soc.c | 81 ------------ soc/renesas/ra/ra6m4/soc.h | 16 --- soc/renesas/ra/ra6m5/CMakeLists.txt | 16 +-- soc/renesas/ra/ra6m5/Kconfig | 1 - soc/renesas/ra/ra6m5/ram_sections.ld | 16 --- soc/renesas/ra/ra6m5/soc.c | 88 ------------- soc/renesas/ra/ra6m5/soc.h | 16 --- soc/renesas/ra/ra8d1/CMakeLists.txt | 12 -- soc/renesas/ra/ra8d1/Kconfig | 1 - soc/renesas/ra/ra8d1/ram_sections.ld | 16 --- soc/renesas/ra/ra8d1/soc.c | 79 ------------ soc/renesas/ra/ra8d1/soc.h | 17 --- soc/renesas/ra/ra8d2/CMakeLists.txt | 12 -- soc/renesas/ra/ra8d2/Kconfig | 1 - soc/renesas/ra/ra8d2/ram_sections.ld | 16 --- soc/renesas/ra/ra8d2/soc.c | 106 ---------------- soc/renesas/ra/ra8m1/CMakeLists.txt | 12 -- soc/renesas/ra/ra8m1/Kconfig | 1 - soc/renesas/ra/ra8m1/ram_sections.ld | 16 --- soc/renesas/ra/ra8m1/soc.c | 52 -------- soc/renesas/ra/ra8m1/soc.h | 17 --- soc/renesas/ra/ra8m2/CMakeLists.txt | 12 -- soc/renesas/ra/ra8m2/Kconfig | 1 - soc/renesas/ra/ra8m2/ram_sections.ld | 16 --- soc/renesas/ra/ra8m2/soc.c | 106 ---------------- soc/renesas/ra/ra8m2/soc.h | 16 --- soc/renesas/ra/ra8p1/CMakeLists.txt | 10 -- soc/renesas/ra/ra8p1/Kconfig | 1 - soc/renesas/ra/ra8p1/ram_sections.ld | 16 --- soc/renesas/ra/ra8p1/soc.c | 119 ------------------ soc/renesas/ra/ra8p1/soc.h | 17 --- soc/renesas/ra/ra8t1/CMakeLists.txt | 12 -- soc/renesas/ra/ra8t1/Kconfig | 1 - soc/renesas/ra/ra8t1/ram_sections.ld | 16 --- soc/renesas/ra/ra8t1/soc.c | 50 -------- soc/renesas/ra/ra8t1/soc.h | 16 --- soc/renesas/ra/ra8t2/CMakeLists.txt | 12 -- soc/renesas/ra/ra8t2/Kconfig | 1 - soc/renesas/ra/ra8t2/ram_sections.ld | 16 --- soc/renesas/ra/ra8t2/soc.c | 93 -------------- soc/renesas/ra/ra8t2/soc.h | 16 --- 137 files changed, 98 insertions(+), 3066 deletions(-) create mode 100644 soc/renesas/ra/common/CMakeLists.txt rename soc/renesas/ra/{common_fsp => common}/pinctrl_soc.h (90%) create mode 100644 soc/renesas/ra/common/platform_init.ld rename soc/renesas/ra/{ra2l1 => common}/ram_sections.ld (100%) create mode 100644 soc/renesas/ra/common/soc.c create mode 100644 soc/renesas/ra/common/soc.h rename soc/renesas/ra/{common_fsp => common}/vector_data.h (84%) delete mode 100644 soc/renesas/ra/common_fsp/CMakeLists.txt delete mode 100644 soc/renesas/ra/common_fsp/battery_backup.c delete mode 100644 soc/renesas/ra/common_fsp/battery_backup.h delete mode 100644 soc/renesas/ra/common_fsp/cold_start.c delete mode 100644 soc/renesas/ra/common_fsp/cold_start.h delete mode 100644 soc/renesas/ra/ra2a1/ram_sections.ld delete mode 100644 soc/renesas/ra/ra2a1/soc.c delete mode 100644 soc/renesas/ra/ra2a1/soc.h delete mode 100644 soc/renesas/ra/ra2l1/soc.c delete mode 100644 soc/renesas/ra/ra2l1/soc.h delete mode 100644 soc/renesas/ra/ra4c1/ram_sections.ld delete mode 100644 soc/renesas/ra/ra4c1/soc.c delete mode 100644 soc/renesas/ra/ra4c1/soc.h delete mode 100644 soc/renesas/ra/ra4e1/ram_sections.ld delete mode 100644 soc/renesas/ra/ra4e1/soc.c delete mode 100644 soc/renesas/ra/ra4e1/soc.h delete mode 100644 soc/renesas/ra/ra4e2/ram_sections.ld delete mode 100644 soc/renesas/ra/ra4e2/soc.c delete mode 100644 soc/renesas/ra/ra4e2/soc.h delete mode 100644 soc/renesas/ra/ra4l1/ram_sections.ld delete mode 100644 soc/renesas/ra/ra4l1/soc.c delete mode 100644 soc/renesas/ra/ra4l1/soc.h delete mode 100644 soc/renesas/ra/ra4m1/ram_sections.ld delete mode 100644 soc/renesas/ra/ra4m1/soc.c delete mode 100644 soc/renesas/ra/ra4m1/soc.h delete mode 100644 soc/renesas/ra/ra4m2/ram_sections.ld delete mode 100644 soc/renesas/ra/ra4m2/soc.c delete mode 100644 soc/renesas/ra/ra4m2/soc.h delete mode 100644 soc/renesas/ra/ra4m3/ram_sections.ld delete mode 100644 soc/renesas/ra/ra4m3/soc.c delete mode 100644 soc/renesas/ra/ra4m3/soc.h delete mode 100644 soc/renesas/ra/ra4t1/ram_sections.ld delete mode 100644 soc/renesas/ra/ra4t1/soc.c delete mode 100644 soc/renesas/ra/ra4t1/soc.h delete mode 100644 soc/renesas/ra/ra4w1/ram_sections.ld delete mode 100644 soc/renesas/ra/ra4w1/soc.c delete mode 100644 soc/renesas/ra/ra4w1/soc.h delete mode 100644 soc/renesas/ra/ra6e1/ram_sections.ld delete mode 100644 soc/renesas/ra/ra6e1/soc.c delete mode 100644 soc/renesas/ra/ra6e1/soc.h delete mode 100644 soc/renesas/ra/ra6e2/ram_sections.ld delete mode 100644 soc/renesas/ra/ra6e2/soc.c delete mode 100644 soc/renesas/ra/ra6e2/soc.h delete mode 100644 soc/renesas/ra/ra6m1/ram_sections.ld delete mode 100644 soc/renesas/ra/ra6m1/soc.c delete mode 100644 soc/renesas/ra/ra6m1/soc.h delete mode 100644 soc/renesas/ra/ra6m2/ram_sections.ld delete mode 100644 soc/renesas/ra/ra6m2/soc.c delete mode 100644 soc/renesas/ra/ra6m2/soc.h delete mode 100644 soc/renesas/ra/ra6m3/ram_sections.ld delete mode 100644 soc/renesas/ra/ra6m3/soc.c delete mode 100644 soc/renesas/ra/ra6m3/soc.h delete mode 100644 soc/renesas/ra/ra6m4/ram_sections.ld delete mode 100644 soc/renesas/ra/ra6m4/soc.c delete mode 100644 soc/renesas/ra/ra6m4/soc.h delete mode 100644 soc/renesas/ra/ra6m5/ram_sections.ld delete mode 100644 soc/renesas/ra/ra6m5/soc.c delete mode 100644 soc/renesas/ra/ra6m5/soc.h delete mode 100644 soc/renesas/ra/ra8d1/ram_sections.ld delete mode 100644 soc/renesas/ra/ra8d1/soc.c delete mode 100644 soc/renesas/ra/ra8d1/soc.h delete mode 100644 soc/renesas/ra/ra8d2/ram_sections.ld delete mode 100644 soc/renesas/ra/ra8d2/soc.c delete mode 100644 soc/renesas/ra/ra8m1/ram_sections.ld delete mode 100644 soc/renesas/ra/ra8m1/soc.c delete mode 100644 soc/renesas/ra/ra8m1/soc.h delete mode 100644 soc/renesas/ra/ra8m2/ram_sections.ld delete mode 100644 soc/renesas/ra/ra8m2/soc.c delete mode 100644 soc/renesas/ra/ra8m2/soc.h delete mode 100644 soc/renesas/ra/ra8p1/ram_sections.ld delete mode 100644 soc/renesas/ra/ra8p1/soc.c delete mode 100644 soc/renesas/ra/ra8p1/soc.h delete mode 100644 soc/renesas/ra/ra8t1/ram_sections.ld delete mode 100644 soc/renesas/ra/ra8t1/soc.c delete mode 100644 soc/renesas/ra/ra8t1/soc.h delete mode 100644 soc/renesas/ra/ra8t2/ram_sections.ld delete mode 100644 soc/renesas/ra/ra8t2/soc.c delete mode 100644 soc/renesas/ra/ra8t2/soc.h diff --git a/soc/renesas/ra/CMakeLists.txt b/soc/renesas/ra/CMakeLists.txt index a7b5d2c2dc5b..0628ac50fe7f 100644 --- a/soc/renesas/ra/CMakeLists.txt +++ b/soc/renesas/ra/CMakeLists.txt @@ -2,8 +2,5 @@ # Copyright (c) 2024 Renesas Electronics Corporation # SPDX-License-Identifier: Apache-2.0 -zephyr_include_directories(common) -zephyr_include_directories_ifdef(CONFIG_HAS_RENESAS_RA_FSP common_fsp) - -add_subdirectory_ifdef(CONFIG_HAS_RENESAS_RA_FSP common_fsp) +add_subdirectory(common) add_subdirectory(${SOC_SERIES}) diff --git a/soc/renesas/ra/Kconfig b/soc/renesas/ra/Kconfig index ef0822de420a..9f571d9f66fc 100644 --- a/soc/renesas/ra/Kconfig +++ b/soc/renesas/ra/Kconfig @@ -2,6 +2,9 @@ # SPDX-License-Identifier: Apache-2.0 config SOC_FAMILY_RENESAS_RA + select SOC_RESET_HOOK + select SOC_EARLY_INIT_HOOK + select SOC_LATE_INIT_HOOK select HAS_SEGGER_RTT if ZEPHYR_SEGGER_MODULE if SOC_FAMILY_RENESAS_RA @@ -27,7 +30,6 @@ rsource "*/Kconfig" config SOC_RA_ENABLE_START_SECOND_CORE bool "Allows the primary core to start the secondary core" depends on ((RENESAS_PN_NUMBER_OF_CORES = 2) && CPU_CORTEX_M85) - select SOC_LATE_INIT_HOOK help Indicates the second core will be start in the soc_late_init_hook when enabled diff --git a/soc/renesas/ra/common/CMakeLists.txt b/soc/renesas/ra/common/CMakeLists.txt new file mode 100644 index 000000000000..c7aba54f21e4 --- /dev/null +++ b/soc/renesas/ra/common/CMakeLists.txt @@ -0,0 +1,26 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +zephyr_include_directories(.) + +# Let SystemInit() be called in place of soc_reset_hook() by default. +zephyr_linker_symbol(SYMBOL soc_reset_hook EXPR "@SystemInit@") + +# These files are used when the CMake linker script generator is disabled. +if(CONFIG_CMAKE_LINKER_GENERATOR) + if(CONFIG_USE_RA_FSP_DTC) + zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) + zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") + endif() + +elseif(CONFIG_LD_LINKER_TEMPLATE) + zephyr_linker_sources(SECTIONS platform_init.ld) + zephyr_linker_sources(SECTIONS ram_sections.ld) + +endif() + +zephyr_sources(soc.c) + +if(NOT CONFIG_ETH_RENESAS_RA_USE_NS_BUF) + set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") +endif() diff --git a/soc/renesas/ra/common_fsp/pinctrl_soc.h b/soc/renesas/ra/common/pinctrl_soc.h similarity index 90% rename from soc/renesas/ra/common_fsp/pinctrl_soc.h rename to soc/renesas/ra/common/pinctrl_soc.h index ff345032f803..cbf667e1a557 100644 --- a/soc/renesas/ra/common_fsp/pinctrl_soc.h +++ b/soc/renesas/ra/common/pinctrl_soc.h @@ -54,10 +54,8 @@ typedef struct ra_pinctrl_soc_pin pinctrl_soc_pin_t; * @param prop Property name describing state pins. */ #define Z_PINCTRL_STATE_PINS_INIT(node_id, prop) \ - { \ - DT_FOREACH_CHILD_VARGS(DT_PHANDLE(node_id, prop), DT_FOREACH_PROP_ELEM, psels, \ - Z_PINCTRL_STATE_PIN_INIT) \ - } + {DT_FOREACH_CHILD_VARGS(DT_PHANDLE(node_id, prop), DT_FOREACH_PROP_ELEM, psels, \ + Z_PINCTRL_STATE_PIN_INIT)} #define RA_GET_PORT_NUM(pinctrl) (((pinctrl) >> RA_PORT_NUM_POS) & RA_PORT_NUM_MASK) #define RA_GET_PIN_NUM(pinctrl) (((pinctrl) >> RA_PIN_NUM_POS) & RA_PIN_NUM_MASK) diff --git a/soc/renesas/ra/common/platform_init.ld b/soc/renesas/ra/common/platform_init.ld new file mode 100644 index 000000000000..3cda23aa8554 --- /dev/null +++ b/soc/renesas/ra/common/platform_init.ld @@ -0,0 +1,8 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* Let SystemInit() be called in place of soc_reset_hook() by default. */ +PROVIDE(soc_reset_hook = SystemInit); diff --git a/soc/renesas/ra/ra2l1/ram_sections.ld b/soc/renesas/ra/common/ram_sections.ld similarity index 100% rename from soc/renesas/ra/ra2l1/ram_sections.ld rename to soc/renesas/ra/common/ram_sections.ld diff --git a/soc/renesas/ra/common/soc.c b/soc/renesas/ra/common/soc.c new file mode 100644 index 000000000000..ed9d0582dd49 --- /dev/null +++ b/soc/renesas/ra/common/soc.c @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2024-2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +extern void NMI_Handler(void); + +void soc_early_init_hook(void) +{ +#ifdef CONFIG_RUNTIME_NMI + z_arm_nmi_set_handler(NMI_Handler); +#endif /* CONFIG_RUNTIME_NMI */ + +#if defined(CONFIG_ICACHE) + /* Invalidate I-Cache after initializing the .ram_from_flash section. */ + sys_cache_instr_invd_all(); +#endif /* CONFIG_ICACHE */ +} + +void soc_late_init_hook(void) +{ +#ifdef CONFIG_SOC_RA_ENABLE_START_SECOND_CORE + R_BSP_SecondaryCoreStart(); +#endif /* CONFIG_SOC_RA_ENABLE_START_SECOND_CORE */ +} diff --git a/soc/renesas/ra/common/soc.h b/soc/renesas/ra/common/soc.h new file mode 100644 index 000000000000..e6096df8be93 --- /dev/null +++ b/soc/renesas/ra/common/soc.h @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2024 TOKITA Hiroshi + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file SoC configuration macros for the Renesas RA family MCU + */ + +#ifndef ZEPHYR_SOC_RENESAS_RA_COMMON_SOC_H_ +#define ZEPHYR_SOC_RENESAS_RA_COMMON_SOC_H_ + +#include + +#endif /* ZEPHYR_SOC_RENESAS_RA_COMMON_SOC_H_ */ diff --git a/soc/renesas/ra/common_fsp/vector_data.h b/soc/renesas/ra/common/vector_data.h similarity index 84% rename from soc/renesas/ra/common_fsp/vector_data.h rename to soc/renesas/ra/common/vector_data.h index 91096f529054..036e9a9068fa 100644 --- a/soc/renesas/ra/common_fsp/vector_data.h +++ b/soc/renesas/ra/common/vector_data.h @@ -9,4 +9,6 @@ #ifndef ZEPHYR_SOC_RENESAS_RA_COMMON_VECTOR_DATA_H_ #define ZEPHYR_SOC_RENESAS_RA_COMMON_VECTOR_DATA_H_ +#define BSP_ICU_VECTOR_NUM_ENTRIES CONFIG_NUM_IRQS + #endif /* ZEPHYR_SOC_RENESAS_RA_COMMON_VECTOR_DATA_H_ */ diff --git a/soc/renesas/ra/common_fsp/CMakeLists.txt b/soc/renesas/ra/common_fsp/CMakeLists.txt deleted file mode 100644 index 5e407d6d50ea..000000000000 --- a/soc/renesas/ra/common_fsp/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -# Copyright (c) 2025 Renesas Electronics Corporation -# SPDX-License-Identifier: Apache-2.0 - -zephyr_sources_ifdef(CONFIG_RENESAS_RA_BATTERY_BACKUP_MANUAL_CONFIGURE battery_backup.c) -zephyr_sources(cold_start.c) diff --git a/soc/renesas/ra/common_fsp/battery_backup.c b/soc/renesas/ra/common_fsp/battery_backup.c deleted file mode 100644 index 741337a53953..000000000000 --- a/soc/renesas/ra/common_fsp/battery_backup.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ -#include "battery_backup.h" - -#define VCC_DROP_DETECTION_STABILIZATION_WAIT_TIME_US 20 -#define VBTBPSR_VBPORF_IS_SET BIT(0) -#define VBTBPCR2_VDETLVL_SETTING_NOT_USED 0x6 - -static uint8_t vbtbpsr_state_at_boot; - -bool is_backup_domain_reset_happen(void) -{ - return (vbtbpsr_state_at_boot & VBTBPSR_VBPORF_IS_SET); -} - -void battery_backup_init(void) -{ -#if DT_NODE_HAS_PROP(DT_NODELABEL(battery_backup), switch_threshold) - /* Check VBPORM bit. If VBPORM flag is 0, wait until it changes to 1 */ - while (R_SYSTEM->VBTBPSR_b.VBPORM == 0) { - } - vbtbpsr_state_at_boot = R_SYSTEM->VBTBPSR; - if (R_SYSTEM->VBTBPSR_b.VBPORF == 1) { - R_BSP_RegisterProtectDisable(BSP_REG_PROTECT_OM_LPC_BATT); - R_SYSTEM->VBTBPSR_b.VBPORF = 0; - R_SYSTEM->VBTBPCR2_b.VDETLVL = - DT_ENUM_IDX(DT_NODELABEL(battery_backup), switch_threshold); - R_BSP_SoftwareDelay(VCC_DROP_DETECTION_STABILIZATION_WAIT_TIME_US, - BSP_DELAY_UNITS_MICROSECONDS); - R_SYSTEM->VBTBPCR2_b.VDETE = 1; - R_BSP_RegisterProtectEnable(BSP_REG_PROTECT_OM_LPC_BATT); - } -#else - /* Set the BPWSWSTP bit to 1. The power supply switch is stopped */ - R_BSP_RegisterProtectDisable(BSP_REG_PROTECT_OM_LPC_BATT); - R_SYSTEM->VBTBPCR1_b.BPWSWSTP = 1; - - /* Check VBPORM flag. If VBPORM flag is 0, wait until it changes to 1 */ - while (R_SYSTEM->VBTBPSR_b.VBPORM == 0) { - } - vbtbpsr_state_at_boot = R_SYSTEM->VBTBPSR; - R_SYSTEM->VBTBPSR_b.VBPORF = 0; - R_SYSTEM->VBTBPCR2_b.VDETE = 0; - R_SYSTEM->VBTBPCR2_b.VDETLVL = DT_ENUM_IDX_OR( - DT_NODELABEL(battery_backup), switch_threshold, VBTBPCR2_VDETLVL_SETTING_NOT_USED); - R_BSP_RegisterProtectEnable(BSP_REG_PROTECT_OM_LPC_BATT); - - /* Set the SOSTP bit to 1 regardless of its value. Stop Sub-Clock Oscillator */ - R_BSP_RegisterProtectDisable(BSP_REG_PROTECT_CGC); - R_SYSTEM->SOSCCR_b.SOSTP = 1; - R_BSP_RegisterProtectEnable(BSP_REG_PROTECT_CGC); -#endif /* BATTERY_BACKUP_CONFIGURATION_NOT_USED */ -} diff --git a/soc/renesas/ra/common_fsp/battery_backup.h b/soc/renesas/ra/common_fsp/battery_backup.h deleted file mode 100644 index 2757a9d47a37..000000000000 --- a/soc/renesas/ra/common_fsp/battery_backup.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef ZEPHYR_SOC_RENESAS_RA_BATTERY_BACKUP_H_ -#define ZEPHYR_SOC_RENESAS_RA_BATTERY_BACKUP_H_ - -#include -#include - -bool is_backup_domain_reset_happen(void); -void battery_backup_init(void); - -#endif /* ZEPHYR_SOC_RENESAS_RA_BATTERY_BACKUP_H_ */ diff --git a/soc/renesas/ra/common_fsp/cold_start.c b/soc/renesas/ra/common_fsp/cold_start.c deleted file mode 100644 index a176e07805bf..000000000000 --- a/soc/renesas/ra/common_fsp/cold_start.c +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ -#include -#include -#include "cold_start.h" - -#define RSTSR2_CWSF_BIT_MASK BIT(0) - -static uint8_t rstsr2_state_at_boot; - -bool is_power_on_reset_happen(void) -{ - return ((rstsr2_state_at_boot & RSTSR2_CWSF_BIT_MASK) == 0); -} - -void cold_start_handler(void) -{ - /* Detect power on reset */ - rstsr2_state_at_boot = R_SYSTEM->RSTSR2; - if (R_SYSTEM->RSTSR2_b.CWSF == 0) { -#if defined(CONFIG_RENESAS_RA_BATTERY_BACKUP_MANUAL_CONFIGURE) - battery_backup_init(); -#endif /* CONFIG_RENESAS_RA_BATTERY_BACKUP_MANUAL_CONFIGURE */ - R_SYSTEM->RSTSR2_b.CWSF = 1; - } -} diff --git a/soc/renesas/ra/common_fsp/cold_start.h b/soc/renesas/ra/common_fsp/cold_start.h deleted file mode 100644 index 5b818b994182..000000000000 --- a/soc/renesas/ra/common_fsp/cold_start.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef ZEPHYR_SOC_RENESAS_RA_COLD_START_H_ -#define ZEPHYR_SOC_RENESAS_RA_COLD_START_H_ - -#include -#include -#include "battery_backup.h" - -bool is_power_on_reset_happen(void); -void cold_start_handler(void); - -#endif /* ZEPHYR_SOC_RENESAS_RA_COLD_START_H_ */ diff --git a/soc/renesas/ra/ra2a1/CMakeLists.txt b/soc/renesas/ra/ra2a1/CMakeLists.txt index 04f2ebbc433a..5c08e3ca2039 100644 --- a/soc/renesas/ra/ra2a1/CMakeLists.txt +++ b/soc/renesas/ra/ra2a1/CMakeLists.txt @@ -4,10 +4,6 @@ zephyr_include_directories(.) -zephyr_sources( - soc.c -) - if(CONFIG_CMAKE_LINKER_GENERATOR) dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") dt_nodelabel(option_setting_ofs1 NODELABEL "option_setting_ofs1") @@ -21,11 +17,6 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) dt_node_has_status(osis_status PATH ${option_setting_osis} STATUS okay) - if(CONFIG_USE_RA_FSP_DTC) - zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) - zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") - endif() - zephyr_linker_section(NAME .rom_padding GROUP ROM_REGION ADDRESS 0x000000C0) zephyr_linker_section_configure(SECTION .rom_padding KEEP INPUT ".rom_padding*") @@ -46,10 +37,7 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) elseif(CONFIG_LD_LINKER_TEMPLATE) zephyr_linker_sources(ROM_START rom_start.ld) zephyr_linker_sources(SECTIONS sections.ld) - zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) else() message(WARNING "Unsupported linker template.") endif() - -set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra2a1/Kconfig b/soc/renesas/ra/ra2a1/Kconfig index e42ae36eac1c..9b3b2539efde 100644 --- a/soc/renesas/ra/ra2a1/Kconfig +++ b/soc/renesas/ra/ra2a1/Kconfig @@ -10,7 +10,6 @@ config SOC_SERIES_RA2A1 select HAS_SWO select XIP select HAS_RENESAS_RA_FSP - select SOC_EARLY_INIT_HOOK if SOC_SERIES_RA2A1 diff --git a/soc/renesas/ra/ra2a1/ram_sections.ld b/soc/renesas/ra/ra2a1/ram_sections.ld deleted file mode 100644 index ece8ea46fa47..000000000000 --- a/soc/renesas/ra/ra2a1/ram_sections.ld +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (c) 2024 TOKITA Hiroshi - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -#ifdef CONFIG_USE_RA_FSP_DTC -SECTION_DATA_PROLOGUE(.fsp_dtc_vector_table,(NOLOAD),) -{ - /* If DTC is used, put the DTC vector table at the start of SRAM. - This avoids memory holes due to 1K alignment required by it. */ - *(.fsp_dtc_vector_table) -} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION) -#endif /* CONFIG_USE_RA_FSP_DTC */ diff --git a/soc/renesas/ra/ra2a1/soc.c b/soc/renesas/ra/ra2a1/soc.c deleted file mode 100644 index 5585eba6a6d7..000000000000 --- a/soc/renesas/ra/ra2a1/soc.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2024 TOKITA Hiroshi - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief System/hardware module for Renesas RA2A1 family processor - */ - -#include -#include -#include -#include -#include -#include -#include -#include -LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); - -#include - -uint32_t SystemCoreClock BSP_SECTION_EARLY_INIT; - -volatile uint32_t g_protect_pfswe_counter BSP_SECTION_EARLY_INIT; - -#ifdef CONFIG_RUNTIME_NMI -extern bsp_grp_irq_cb_t g_bsp_group_irq_sources[]; -extern void NMI_Handler(void); -#endif /* CONFIG_RUNTIME_NMI */ - -/** - * @brief Perform basic hardware initialization at boot. - * - * This needs to be run from the very beginning. - */ -void soc_early_init_hook(void) -{ - SystemCoreClock = BSP_MOCO_HZ; - g_protect_pfswe_counter = 0; - bsp_clock_init(); - -#ifdef CONFIG_RUNTIME_NMI - for (uint32_t i = 0; i < 16; i++) { - g_bsp_group_irq_sources[i] = 0; - } - - z_arm_nmi_set_handler(NMI_Handler); -#endif /* CONFIG_RUNTIME_NMI */ -} diff --git a/soc/renesas/ra/ra2a1/soc.h b/soc/renesas/ra/ra2a1/soc.h deleted file mode 100644 index 3dab874487bb..000000000000 --- a/soc/renesas/ra/ra2a1/soc.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2024 TOKITA Hiroshi - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file SoC configuration macros for the Renesas RA2A1 family MCU - */ - -#ifndef ZEPHYR_SOC_RENESAS_RA2A1_SOC_H_ -#define ZEPHYR_SOC_RENESAS_RA2A1_SOC_H_ - -#include - -#endif /* ZEPHYR_SOC_RENESAS_RA2A1_SOC_H_ */ diff --git a/soc/renesas/ra/ra2l1/CMakeLists.txt b/soc/renesas/ra/ra2l1/CMakeLists.txt index 1d8891f222cb..45c638e71cbd 100644 --- a/soc/renesas/ra/ra2l1/CMakeLists.txt +++ b/soc/renesas/ra/ra2l1/CMakeLists.txt @@ -4,10 +4,6 @@ zephyr_include_directories(.) -zephyr_sources( - soc.c -) - if(CONFIG_CMAKE_LINKER_GENERATOR) dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") dt_nodelabel(option_setting_ofs1 NODELABEL "option_setting_ofs1") @@ -21,11 +17,6 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) dt_node_has_status(osis_status PATH ${option_setting_osis} STATUS okay) - if(CONFIG_USE_RA_FSP_DTC) - zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) - zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") - endif() - zephyr_linker_section(NAME .rom_padding GROUP ROM_REGION ADDRESS 0x000000C0) zephyr_linker_section_configure(SECTION .rom_padding KEEP INPUT ".rom_padding*") @@ -46,10 +37,7 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) elseif(CONFIG_LD_LINKER_TEMPLATE) zephyr_linker_sources(ROM_START rom_start.ld) zephyr_linker_sources(SECTIONS sections.ld) - zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) else() message(WARNING "Unsupported linker template.") endif() - -set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra2l1/Kconfig b/soc/renesas/ra/ra2l1/Kconfig index 6d781dc1f8f0..d4342e1432e0 100644 --- a/soc/renesas/ra/ra2l1/Kconfig +++ b/soc/renesas/ra/ra2l1/Kconfig @@ -11,7 +11,6 @@ config SOC_SERIES_RA2L1 select CPU_CORTEX_M_HAS_SYSTICK select CLOCK_CONTROL_RENESAS_RA_CGC if CLOCK_CONTROL select HAS_SWO - select SOC_EARLY_INIT_HOOK if SOC_SERIES_RA2L1 diff --git a/soc/renesas/ra/ra2l1/soc.c b/soc/renesas/ra/ra2l1/soc.c deleted file mode 100644 index 82a889c994ab..000000000000 --- a/soc/renesas/ra/ra2l1/soc.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2023-2024 MUNIC SA - * Copyright (c) 2024 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief System/hardware module for Renesas RA2L1 family processor - */ - -#include -#include -#include -#include -#include -#include -#include -#include -LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); - -#include "bsp_cfg.h" -#include - -uint32_t SystemCoreClock BSP_SECTION_EARLY_INIT; - -volatile uint32_t g_protect_pfswe_counter BSP_SECTION_EARLY_INIT; - -#ifdef CONFIG_RUNTIME_NMI -extern bsp_grp_irq_cb_t g_bsp_group_irq_sources[]; -extern void NMI_Handler(void); -#endif /* CONFIG_RUNTIME_NMI */ - -/** - * @brief Perform basic hardware initialization at boot. - * - * This needs to be run from the very beginning. - */ -void soc_early_init_hook(void) -{ - SystemCoreClock = BSP_MOCO_HZ; - g_protect_pfswe_counter = 0; - -#ifdef CONFIG_RUNTIME_NMI - for (uint32_t i = 0; i < 16; i++) { - g_bsp_group_irq_sources[i] = 0; - } - - z_arm_nmi_set_handler(NMI_Handler); -#endif /* CONFIG_RUNTIME_NMI */ -} diff --git a/soc/renesas/ra/ra2l1/soc.h b/soc/renesas/ra/ra2l1/soc.h deleted file mode 100644 index 2fa588a6c0c3..000000000000 --- a/soc/renesas/ra/ra2l1/soc.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (c) 2021-2024 MUNIC SA - * Copyright (c) 2024 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file SoC configuration macros for the Renesas RA2L1 family MCU - */ - -#ifndef ZEPHYR_SOC_RENESAS_RA2L1_SOC_H_ -#define ZEPHYR_SOC_RENESAS_RA2L1_SOC_H_ - -#include - -#endif /* ZEPHYR_SOC_RENESAS_RA2L1_SOC_H_ */ diff --git a/soc/renesas/ra/ra4c1/CMakeLists.txt b/soc/renesas/ra/ra4c1/CMakeLists.txt index 695c35a40947..6a32d2a8e0e0 100644 --- a/soc/renesas/ra/ra4c1/CMakeLists.txt +++ b/soc/renesas/ra/ra4c1/CMakeLists.txt @@ -3,10 +3,6 @@ zephyr_include_directories(.) -zephyr_sources( - soc.c -) - if(CONFIG_CMAKE_LINKER_GENERATOR) dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") dt_nodelabel(option_setting_dualsel NODELABEL "option_setting_dualsel") @@ -38,11 +34,6 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) dt_node_has_status(banksel_sel_status PATH ${option_setting_banksel_sel} STATUS okay) dt_node_has_status(bps_sel_status PATH ${option_setting_bps_sel} STATUS okay) - if(CONFIG_USE_RA_FSP_DTC) - zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) - zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") - endif() - if(${ofs0_status}) zephyr_linker_section(NAME .option_setting_ofs0 GROUP OFS_OFS0_MEMORY ADDRESS ${ofs0_addr}) zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") @@ -90,10 +81,7 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) elseif(CONFIG_LD_LINKER_TEMPLATE) zephyr_linker_sources(SECTIONS sections.ld) - zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) else() message(WARNING "Unsupported linker template.") endif() - -set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra4c1/Kconfig b/soc/renesas/ra/ra4c1/Kconfig index 38075b3dd06a..a45c7b4b8e2c 100644 --- a/soc/renesas/ra/ra4c1/Kconfig +++ b/soc/renesas/ra/ra4c1/Kconfig @@ -13,7 +13,6 @@ config SOC_SERIES_RA4C1 select FPU select HAS_SWO select XIP - select SOC_EARLY_INIT_HOOK if SOC_SERIES_RA4C1 diff --git a/soc/renesas/ra/ra4c1/ram_sections.ld b/soc/renesas/ra/ra4c1/ram_sections.ld deleted file mode 100644 index 18be2a431de2..000000000000 --- a/soc/renesas/ra/ra4c1/ram_sections.ld +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -#ifdef CONFIG_USE_RA_FSP_DTC -SECTION_DATA_PROLOGUE(.fsp_dtc_vector_table,(NOLOAD),) -{ - /* If DTC is used, put the DTC vector table at the start of SRAM. - This avoids memory holes due to 1K alignment required by it. */ - *(.fsp_dtc_vector_table) -} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION) -#endif /* CONFIG_USE_RA_FSP_DTC */ diff --git a/soc/renesas/ra/ra4c1/soc.c b/soc/renesas/ra/ra4c1/soc.c deleted file mode 100644 index f4921562c029..000000000000 --- a/soc/renesas/ra/ra4c1/soc.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief System/hardware module for Renesas RA4C1 family processor - */ - -#include -#include -#include -#include -#include -#include -#include -#include -LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); - -#include "bsp_cfg.h" -#include - -uint32_t SystemCoreClock BSP_SECTION_EARLY_INIT; - -volatile uint32_t g_protect_pfswe_counter BSP_SECTION_EARLY_INIT; - -/** - * @brief Perform basic hardware initialization at boot. - * - * This needs to be run from the very beginning. - */ -void soc_early_init_hook(void) -{ - extern volatile uint16_t g_protect_counters[]; - - for (uint32_t i = 0; i < 5; i++) { - g_protect_counters[i] = 0; - } - -#if FSP_PRIV_TZ_USE_SECURE_REGS - /* Disable protection using PRCR register. */ - R_BSP_RegisterProtectDisable(BSP_REG_PROTECT_SAR); - - /* Initialize peripherals to secure mode for flat projects */ - R_PSCU->PSARB = 0; - R_PSCU->PSARC = 0; - R_PSCU->PSARD = 0; - R_PSCU->PSARE = 0; - - R_CPSCU->ICUSARC = 0; - R_CPSCU->ICUSARG = 0; - R_CPSCU->ICUSARH = 0; - - /* Enable protection using PRCR register. */ - R_BSP_RegisterProtectEnable(BSP_REG_PROTECT_SAR); -#endif - - SystemCoreClock = BSP_MOCO_HZ; - g_protect_pfswe_counter = 0; -} diff --git a/soc/renesas/ra/ra4c1/soc.h b/soc/renesas/ra/ra4c1/soc.h deleted file mode 100644 index 925b6a248fe0..000000000000 --- a/soc/renesas/ra/ra4c1/soc.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file SoC configuration macros for the Renesas RA4C1 family MCU - */ - -#ifndef ZEPHYR_SOC_RENESAS_RA4C1_SOC_H_ -#define ZEPHYR_SOC_RENESAS_RA4C1_SOC_H_ - -#include - -#endif /* ZEPHYR_SOC_RENESAS_RA4C1_SOC_H_ */ diff --git a/soc/renesas/ra/ra4e1/CMakeLists.txt b/soc/renesas/ra/ra4e1/CMakeLists.txt index 82681b5184b3..b362cc3501a2 100644 --- a/soc/renesas/ra/ra4e1/CMakeLists.txt +++ b/soc/renesas/ra/ra4e1/CMakeLists.txt @@ -3,10 +3,6 @@ zephyr_include_directories(.) -zephyr_sources( - soc.c -) - if(CONFIG_CMAKE_LINKER_GENERATOR) dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") dt_nodelabel(option_setting_ofs1_sec NODELABEL "option_setting_ofs1_sec") @@ -29,11 +25,6 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) dt_node_has_status(ofs1_sel_status PATH ${option_setting_ofs1_sel} STATUS okay) dt_node_has_status(bps_sel_status PATH ${option_setting_bps_sel} STATUS okay) - if(CONFIG_USE_RA_FSP_DTC) - zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) - zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") - endif() - if(${ofs0_status}) zephyr_linker_section(NAME .option_setting_ofs0 GROUP OFS_OFS0_MEMORY ADDRESS ${ofs0_addr}) zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") @@ -66,10 +57,7 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) elseif(CONFIG_LD_LINKER_TEMPLATE) zephyr_linker_sources(SECTIONS sections.ld) - zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) else() message(WARNING "Unsupported linker template.") endif() - -set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra4e1/Kconfig b/soc/renesas/ra/ra4e1/Kconfig index b48567294a7e..7424c449dd89 100644 --- a/soc/renesas/ra/ra4e1/Kconfig +++ b/soc/renesas/ra/ra4e1/Kconfig @@ -13,7 +13,6 @@ config SOC_SERIES_RA4E1 select FPU select HAS_SWO select XIP - select SOC_EARLY_INIT_HOOK select GPIO_RA_HAS_VBTICTLR if SOC_SERIES_RA4E1 diff --git a/soc/renesas/ra/ra4e1/ram_sections.ld b/soc/renesas/ra/ra4e1/ram_sections.ld deleted file mode 100644 index 18be2a431de2..000000000000 --- a/soc/renesas/ra/ra4e1/ram_sections.ld +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -#ifdef CONFIG_USE_RA_FSP_DTC -SECTION_DATA_PROLOGUE(.fsp_dtc_vector_table,(NOLOAD),) -{ - /* If DTC is used, put the DTC vector table at the start of SRAM. - This avoids memory holes due to 1K alignment required by it. */ - *(.fsp_dtc_vector_table) -} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION) -#endif /* CONFIG_USE_RA_FSP_DTC */ diff --git a/soc/renesas/ra/ra4e1/soc.c b/soc/renesas/ra/ra4e1/soc.c deleted file mode 100644 index 011e53fd89ca..000000000000 --- a/soc/renesas/ra/ra4e1/soc.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief System/hardware module for Renesas RA4E1 family processor - */ - -#include -#include -#include -#include -#include -#include -#include -#include -LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); - -#include "bsp_cfg.h" -#include - -uint32_t SystemCoreClock BSP_SECTION_EARLY_INIT; - -volatile uint32_t g_protect_pfswe_counter BSP_SECTION_EARLY_INIT; - -#ifdef CONFIG_RUNTIME_NMI -extern bsp_grp_irq_cb_t g_bsp_group_irq_sources[]; -extern void NMI_Handler(void); -#endif /* CONFIG_RUNTIME_NMI */ - -/** - * @brief Perform basic hardware initialization at boot. - * - * This needs to be run from the very beginning. - */ -void soc_early_init_hook(void) -{ - extern volatile uint16_t g_protect_counters[]; - - for (uint32_t i = 0; i < 5; i++) { - g_protect_counters[i] = 0; - } - -#if FSP_PRIV_TZ_USE_SECURE_REGS - /* Disable protection using PRCR register. */ - R_BSP_RegisterProtectDisable(BSP_REG_PROTECT_SAR); - - /* Initialize peripherals to secure mode for flat projects */ - R_PSCU->PSARB = 0; - R_PSCU->PSARC = 0; - R_PSCU->PSARD = 0; - R_PSCU->PSARE = 0; - - R_CPSCU->ICUSARC = 0; - R_CPSCU->ICUSARG = 0; - R_CPSCU->ICUSARH = 0; - R_CPSCU->ICUSARI = 0; - - /* Enable protection using PRCR register. */ - R_BSP_RegisterProtectEnable(BSP_REG_PROTECT_SAR); -#endif - - SystemCoreClock = BSP_MOCO_HZ; - g_protect_pfswe_counter = 0; - -#ifdef CONFIG_RUNTIME_NMI - for (uint32_t i = 0; i < 16; i++) { - g_bsp_group_irq_sources[i] = 0; - } - - z_arm_nmi_set_handler(NMI_Handler); -#endif /* CONFIG_RUNTIME_NMI */ -} diff --git a/soc/renesas/ra/ra4e1/soc.h b/soc/renesas/ra/ra4e1/soc.h deleted file mode 100644 index 704d430fecf5..000000000000 --- a/soc/renesas/ra/ra4e1/soc.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file SoC configuration macros for the Renesas RA4E1 family MCU - */ - -#ifndef ZEPHYR_SOC_RENESAS_RA4E1_SOC_H_ -#define ZEPHYR_SOC_RENESAS_RA4E1_SOC_H_ - -#include - -#endif /* ZEPHYR_SOC_RENESAS_RA4E1_SOC_H_ */ diff --git a/soc/renesas/ra/ra4e2/CMakeLists.txt b/soc/renesas/ra/ra4e2/CMakeLists.txt index 4eea413d6825..8ceed38587d7 100644 --- a/soc/renesas/ra/ra4e2/CMakeLists.txt +++ b/soc/renesas/ra/ra4e2/CMakeLists.txt @@ -3,10 +3,6 @@ zephyr_include_directories(.) -zephyr_sources( - soc.c -) - if(CONFIG_CMAKE_LINKER_GENERATOR) dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") dt_nodelabel(option_setting_osis NODELABEL "option_setting_osis") @@ -58,10 +54,7 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) elseif(CONFIG_LD_LINKER_TEMPLATE) zephyr_linker_sources(SECTIONS sections.ld) - zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) else() message(WARNING "Unsupported linker template.") endif() - -set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra4e2/Kconfig b/soc/renesas/ra/ra4e2/Kconfig index 701c68a76631..f0331651a256 100644 --- a/soc/renesas/ra/ra4e2/Kconfig +++ b/soc/renesas/ra/ra4e2/Kconfig @@ -13,7 +13,6 @@ config SOC_SERIES_RA4E2 select FPU select HAS_SWO select XIP - select SOC_EARLY_INIT_HOOK if SOC_SERIES_RA4E2 diff --git a/soc/renesas/ra/ra4e2/ram_sections.ld b/soc/renesas/ra/ra4e2/ram_sections.ld deleted file mode 100644 index 18be2a431de2..000000000000 --- a/soc/renesas/ra/ra4e2/ram_sections.ld +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -#ifdef CONFIG_USE_RA_FSP_DTC -SECTION_DATA_PROLOGUE(.fsp_dtc_vector_table,(NOLOAD),) -{ - /* If DTC is used, put the DTC vector table at the start of SRAM. - This avoids memory holes due to 1K alignment required by it. */ - *(.fsp_dtc_vector_table) -} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION) -#endif /* CONFIG_USE_RA_FSP_DTC */ diff --git a/soc/renesas/ra/ra4e2/soc.c b/soc/renesas/ra/ra4e2/soc.c deleted file mode 100644 index e2dfdbf2c996..000000000000 --- a/soc/renesas/ra/ra4e2/soc.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2024 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief System/hardware module for Renesas RA4E2 family processor - */ - -#include -#include -#include -#include -#include -#include -#include -#include -LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); - -#include "bsp_cfg.h" -#include - -uint32_t SystemCoreClock BSP_SECTION_EARLY_INIT; - -volatile uint32_t g_protect_pfswe_counter BSP_SECTION_EARLY_INIT; - -#ifdef CONFIG_RUNTIME_NMI -extern bsp_grp_irq_cb_t g_bsp_group_irq_sources[]; -extern void NMI_Handler(void); -#endif /* CONFIG_RUNTIME_NMI */ - -/** - * @brief Perform basic hardware initialization at boot. - * - * This needs to be run from the very beginning. - */ -void soc_early_init_hook(void) -{ - extern volatile uint16_t g_protect_counters[]; - - for (uint32_t i = 0; i < 5; i++) { - g_protect_counters[i] = 0; - } - -#if FSP_PRIV_TZ_USE_SECURE_REGS - /* Disable protection using PRCR register. */ - R_BSP_RegisterProtectDisable(BSP_REG_PROTECT_SAR); - - /* Initialize peripherals to secure mode for flat projects */ - R_PSCU->PSARB = 0; - R_PSCU->PSARC = 0; - R_PSCU->PSARD = 0; - R_PSCU->PSARE = 0; - - R_CPSCU->ICUSARC = 0; - R_CPSCU->ICUSARG = 0; - R_CPSCU->ICUSARH = 0; - R_CPSCU->ICUSARI = 0; - - /* Enable protection using PRCR register. */ - R_BSP_RegisterProtectEnable(BSP_REG_PROTECT_SAR); -#endif - - SystemCoreClock = BSP_MOCO_HZ; - g_protect_pfswe_counter = 0; - -#ifdef CONFIG_RUNTIME_NMI - for (uint32_t i = 0; i < 16; i++) { - g_bsp_group_irq_sources[i] = 0; - } - - z_arm_nmi_set_handler(NMI_Handler); -#endif /* CONFIG_RUNTIME_NMI */ -} diff --git a/soc/renesas/ra/ra4e2/soc.h b/soc/renesas/ra/ra4e2/soc.h deleted file mode 100644 index cdf8331dac62..000000000000 --- a/soc/renesas/ra/ra4e2/soc.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2024 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file SoC configuration macros for the Renesas RA4E2 family MCU - */ - -#ifndef ZEPHYR_SOC_RENESAS_RA4E2_SOC_H_ -#define ZEPHYR_SOC_RENESAS_RA4E2_SOC_H_ - -#include - -#endif /* ZEPHYR_SOC_RENESAS_RA4E2_SOC_H_ */ diff --git a/soc/renesas/ra/ra4l1/CMakeLists.txt b/soc/renesas/ra/ra4l1/CMakeLists.txt index 695c35a40947..6a32d2a8e0e0 100644 --- a/soc/renesas/ra/ra4l1/CMakeLists.txt +++ b/soc/renesas/ra/ra4l1/CMakeLists.txt @@ -3,10 +3,6 @@ zephyr_include_directories(.) -zephyr_sources( - soc.c -) - if(CONFIG_CMAKE_LINKER_GENERATOR) dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") dt_nodelabel(option_setting_dualsel NODELABEL "option_setting_dualsel") @@ -38,11 +34,6 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) dt_node_has_status(banksel_sel_status PATH ${option_setting_banksel_sel} STATUS okay) dt_node_has_status(bps_sel_status PATH ${option_setting_bps_sel} STATUS okay) - if(CONFIG_USE_RA_FSP_DTC) - zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) - zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") - endif() - if(${ofs0_status}) zephyr_linker_section(NAME .option_setting_ofs0 GROUP OFS_OFS0_MEMORY ADDRESS ${ofs0_addr}) zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") @@ -90,10 +81,7 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) elseif(CONFIG_LD_LINKER_TEMPLATE) zephyr_linker_sources(SECTIONS sections.ld) - zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) else() message(WARNING "Unsupported linker template.") endif() - -set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra4l1/Kconfig b/soc/renesas/ra/ra4l1/Kconfig index 525f45693bbb..31eea255c1f5 100644 --- a/soc/renesas/ra/ra4l1/Kconfig +++ b/soc/renesas/ra/ra4l1/Kconfig @@ -13,7 +13,6 @@ config SOC_SERIES_RA4L1 select HAS_RENESAS_RA_FSP select CLOCK_CONTROL_RENESAS_RA_CGC if CLOCK_CONTROL select XIP - select SOC_EARLY_INIT_HOOK if SOC_SERIES_RA4L1 diff --git a/soc/renesas/ra/ra4l1/ram_sections.ld b/soc/renesas/ra/ra4l1/ram_sections.ld deleted file mode 100644 index 18be2a431de2..000000000000 --- a/soc/renesas/ra/ra4l1/ram_sections.ld +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -#ifdef CONFIG_USE_RA_FSP_DTC -SECTION_DATA_PROLOGUE(.fsp_dtc_vector_table,(NOLOAD),) -{ - /* If DTC is used, put the DTC vector table at the start of SRAM. - This avoids memory holes due to 1K alignment required by it. */ - *(.fsp_dtc_vector_table) -} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION) -#endif /* CONFIG_USE_RA_FSP_DTC */ diff --git a/soc/renesas/ra/ra4l1/soc.c b/soc/renesas/ra/ra4l1/soc.c deleted file mode 100644 index 042d64aba7bc..000000000000 --- a/soc/renesas/ra/ra4l1/soc.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief System/hardware module for Renesas RA4L1 family processor - */ - -#include -#include -#include -#include -#include -#include -#include -#include -LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); - -#include "bsp_cfg.h" -#include "bsp_api.h" - -uint32_t SystemCoreClock BSP_SECTION_EARLY_INIT; - -volatile uint32_t g_protect_pfswe_counter BSP_SECTION_EARLY_INIT; - -#ifdef CONFIG_RUNTIME_NMI -extern bsp_grp_irq_cb_t g_bsp_group_irq_sources[]; -extern void NMI_Handler(void); -#endif /* CONFIG_RUNTIME_NMI */ - -/** - * @brief Perform basic hardware initialization at boot. - * - * This needs to be run from the very beginning. - */ -void soc_early_init_hook(void) -{ - extern volatile uint16_t g_protect_counters[]; - - for (uint32_t i = 0; i < 5; i++) { - g_protect_counters[i] = 0; - } - -#if FSP_PRIV_TZ_USE_SECURE_REGS - /* Disable protection using PRCR register. */ - R_BSP_RegisterProtectDisable(BSP_REG_PROTECT_SAR); - - /* Initialize peripherals to secure mode for flat projects */ - R_PSCU->PSARB = 0; - R_PSCU->PSARC = 0; - R_PSCU->PSARD = 0; - R_PSCU->PSARE = 0; - - R_CPSCU->ICUSARC = 0; - R_CPSCU->ICUSARG = 0; - R_CPSCU->ICUSARH = 0; - R_CPSCU->ICUSARI = 0; - - /* Enable protection using PRCR register. */ - R_BSP_RegisterProtectEnable(BSP_REG_PROTECT_SAR); -#endif - - SystemCoreClock = BSP_MOCO_HZ; - g_protect_pfswe_counter = 0; - -#ifdef CONFIG_RUNTIME_NMI - for (uint32_t i = 0; i < 16; i++) { - g_bsp_group_irq_sources[i] = 0; - } - - z_arm_nmi_set_handler(NMI_Handler); -#endif /* CONFIG_RUNTIME_NMI */ -} diff --git a/soc/renesas/ra/ra4l1/soc.h b/soc/renesas/ra/ra4l1/soc.h deleted file mode 100644 index cf99273edd37..000000000000 --- a/soc/renesas/ra/ra4l1/soc.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file SoC configuration macros for the Renesas RA4L1 family MCU - */ - -#ifndef ZEPHYR_SOC_RENESAS_RA4L1_SOC_H_ -#define ZEPHYR_SOC_RENESAS_RA4L1_SOC_H_ - -#include - -#endif /* ZEPHYR_SOC_RENESAS_RA4L1_SOC_H_ */ diff --git a/soc/renesas/ra/ra4m1/CMakeLists.txt b/soc/renesas/ra/ra4m1/CMakeLists.txt index 94e1769c22f4..916d369c34e0 100644 --- a/soc/renesas/ra/ra4m1/CMakeLists.txt +++ b/soc/renesas/ra/ra4m1/CMakeLists.txt @@ -4,10 +4,6 @@ zephyr_include_directories(.) -zephyr_sources( - soc.c -) - if(CONFIG_CMAKE_LINKER_GENERATOR) dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") dt_nodelabel(option_setting_ofs1 NODELABEL "option_setting_ofs1") @@ -21,11 +17,6 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) dt_node_has_status(osis_status PATH ${option_setting_osis} STATUS okay) - if(CONFIG_USE_RA_FSP_DTC) - zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) - zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") - endif() - zephyr_linker_section(NAME .rom_padding GROUP ROM_REGION ADDRESS 0x000000C0) zephyr_linker_section_configure(SECTION .rom_padding KEEP INPUT ".rom_padding*") @@ -46,10 +37,7 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) elseif(CONFIG_LD_LINKER_TEMPLATE) zephyr_linker_sources(ROM_START rom_start.ld) zephyr_linker_sources(SECTIONS sections.ld) - zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) else() message(WARNING "Unsupported linker template.") endif() - -set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra4m1/Kconfig b/soc/renesas/ra/ra4m1/Kconfig index b5fa5e108bc6..844d6d99d281 100644 --- a/soc/renesas/ra/ra4m1/Kconfig +++ b/soc/renesas/ra/ra4m1/Kconfig @@ -12,7 +12,6 @@ config SOC_SERIES_RA4M1 select FPU select HAS_SWO select XIP - select SOC_EARLY_INIT_HOOK select GPIO_RA_HAS_VBTICTLR if SOC_SERIES_RA4M1 diff --git a/soc/renesas/ra/ra4m1/ram_sections.ld b/soc/renesas/ra/ra4m1/ram_sections.ld deleted file mode 100644 index ca4598c51305..000000000000 --- a/soc/renesas/ra/ra4m1/ram_sections.ld +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (c) 2024 TOKITA Hiroshi - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -#ifdef CONFIG_USE_RA_FSP_DTC -SECTION_DATA_PROLOGUE(.fsp_dtc_vector_table,(NOLOAD),) -{ - /* If DTC is used, put the DTC vector table at the start of SRAM. - This avoids memory holes due to 1K alignment required by it. */ - *(.fsp_dtc_vector_table) -} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION) -#endif /* CONFIG_USE_RA_FSP_DTC */ diff --git a/soc/renesas/ra/ra4m1/soc.c b/soc/renesas/ra/ra4m1/soc.c deleted file mode 100644 index b2dbbd7aae40..000000000000 --- a/soc/renesas/ra/ra4m1/soc.c +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2024 Ian Morris - * Copyright (c) 2024 TOKITA Hiroshi - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief System/hardware module for Renesas RA4M1 family processor - */ - -#include -#include -#include -#include -#include -#include -#include -#include -LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); - -#include "bsp_cfg.h" -#include - -#define HOCO_FREQ DT_PROP(DT_PATH(clocks, clock_hoco), clock_frequency) - -#if HOCO_FREQ == MHZ(24) -#define OFS1_HOCO_FREQ 0 -#elif HOCO_FREQ == MHZ(32) -#define OFS1_HOCO_FREQ 2 -#elif HOCO_FREQ == MHZ(48) -#define OFS1_HOCO_FREQ 4 -#elif HOCO_FREQ == MHZ(64) -#define OFS1_HOCO_FREQ 5 -#else -#error "Unsupported HOCO frequency" -#endif - -uint32_t SystemCoreClock BSP_SECTION_EARLY_INIT; - -volatile uint32_t g_protect_pfswe_counter BSP_SECTION_EARLY_INIT; - -#ifdef CONFIG_RUNTIME_NMI -extern bsp_grp_irq_cb_t g_bsp_group_irq_sources[]; -extern void NMI_Handler(void); -#endif /* CONFIG_RUNTIME_NMI */ - -/** - * @brief Perform basic hardware initialization at boot. - * - * This needs to be run from the very beginning. - */ -void soc_early_init_hook(void) -{ - uint32_t key; - - key = irq_lock(); - - SystemCoreClock = BSP_MOCO_HZ; - g_protect_pfswe_counter = 0; - -#ifdef CONFIG_RUNTIME_NMI - for (uint32_t i = 0; i < 16; i++) { - g_bsp_group_irq_sources[i] = 0; - } - - z_arm_nmi_set_handler(NMI_Handler); -#endif /* CONFIG_RUNTIME_NMI */ - - irq_unlock(key); -} diff --git a/soc/renesas/ra/ra4m1/soc.h b/soc/renesas/ra/ra4m1/soc.h deleted file mode 100644 index 0476e2ba816a..000000000000 --- a/soc/renesas/ra/ra4m1/soc.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2023 TOKITA Hiroshi - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file SoC configuration macros for the Renesas RA4M1 family MCU - */ - -#ifndef ZEPHYR_SOC_RENESAS_RA4M1_SOC_H_ -#define ZEPHYR_SOC_RENESAS_RA4M1_SOC_H_ - -#include - -#endif /* ZEPHYR_SOC_RENESAS_RA4M1_SOC_H_ */ diff --git a/soc/renesas/ra/ra4m2/CMakeLists.txt b/soc/renesas/ra/ra4m2/CMakeLists.txt index 074db41fdceb..98482a648553 100644 --- a/soc/renesas/ra/ra4m2/CMakeLists.txt +++ b/soc/renesas/ra/ra4m2/CMakeLists.txt @@ -3,10 +3,6 @@ zephyr_include_directories(.) -zephyr_sources( - soc.c -) - if(CONFIG_CMAKE_LINKER_GENERATOR) dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") dt_nodelabel(option_setting_ofs1_sec NODELABEL "option_setting_ofs1_sec") @@ -29,11 +25,6 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) dt_node_has_status(ofs1_sel_status PATH ${option_setting_ofs1_sel} STATUS okay) dt_node_has_status(bps_sel_status PATH ${option_setting_bps_sel} STATUS okay) - if(CONFIG_USE_RA_FSP_DTC) - zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) - zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") - endif() - if(${ofs0_status}) zephyr_linker_section(NAME .option_setting_ofs0 GROUP OFS_OFS0_MEMORY ADDRESS ${ofs0_addr}) zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") @@ -66,10 +57,7 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) elseif(CONFIG_LD_LINKER_TEMPLATE) zephyr_linker_sources(SECTIONS sections.ld) - zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) else() message(WARNING "Unsupported linker template.") endif() - -set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra4m2/Kconfig b/soc/renesas/ra/ra4m2/Kconfig index 0412eaaa63b7..bb9b510ebd39 100644 --- a/soc/renesas/ra/ra4m2/Kconfig +++ b/soc/renesas/ra/ra4m2/Kconfig @@ -13,7 +13,6 @@ config SOC_SERIES_RA4M2 select FPU select HAS_SWO select XIP - select SOC_EARLY_INIT_HOOK select GPIO_RA_HAS_VBTICTLR if SOC_SERIES_RA4M2 diff --git a/soc/renesas/ra/ra4m2/ram_sections.ld b/soc/renesas/ra/ra4m2/ram_sections.ld deleted file mode 100644 index 18be2a431de2..000000000000 --- a/soc/renesas/ra/ra4m2/ram_sections.ld +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -#ifdef CONFIG_USE_RA_FSP_DTC -SECTION_DATA_PROLOGUE(.fsp_dtc_vector_table,(NOLOAD),) -{ - /* If DTC is used, put the DTC vector table at the start of SRAM. - This avoids memory holes due to 1K alignment required by it. */ - *(.fsp_dtc_vector_table) -} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION) -#endif /* CONFIG_USE_RA_FSP_DTC */ diff --git a/soc/renesas/ra/ra4m2/soc.c b/soc/renesas/ra/ra4m2/soc.c deleted file mode 100644 index 0f008fd4216e..000000000000 --- a/soc/renesas/ra/ra4m2/soc.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2024 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief System/hardware module for Renesas RA4M2 family processor - */ - -#include -#include -#include -#include -#include -#include -#include -#include -LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); - -#include "bsp_cfg.h" -#include - -uint32_t SystemCoreClock BSP_SECTION_EARLY_INIT; - -volatile uint32_t g_protect_pfswe_counter BSP_SECTION_EARLY_INIT; - -#ifdef CONFIG_RUNTIME_NMI -extern bsp_grp_irq_cb_t g_bsp_group_irq_sources[]; -extern void NMI_Handler(void); -#endif /* CONFIG_RUNTIME_NMI */ - -/** - * @brief Perform basic hardware initialization at boot. - * - * This needs to be run from the very beginning. - */ -void soc_early_init_hook(void) -{ - extern volatile uint16_t g_protect_counters[]; - - for (uint32_t i = 0; i < 5; i++) { - g_protect_counters[i] = 0; - } - -#if FSP_PRIV_TZ_USE_SECURE_REGS - /* Disable protection using PRCR register. */ - R_BSP_RegisterProtectDisable(BSP_REG_PROTECT_SAR); - - /* Initialize peripherals to secure mode for flat projects */ - R_PSCU->PSARB = 0; - R_PSCU->PSARC = 0; - R_PSCU->PSARD = 0; - R_PSCU->PSARE = 0; - - R_CPSCU->ICUSARC = 0; - R_CPSCU->ICUSARG = 0; - R_CPSCU->ICUSARH = 0; - R_CPSCU->ICUSARI = 0; - - /* Enable protection using PRCR register. */ - R_BSP_RegisterProtectEnable(BSP_REG_PROTECT_SAR); -#endif - - SystemCoreClock = BSP_MOCO_HZ; - g_protect_pfswe_counter = 0; - -#ifdef CONFIG_RUNTIME_NMI - for (uint32_t i = 0; i < 16; i++) { - g_bsp_group_irq_sources[i] = 0; - } - - z_arm_nmi_set_handler(NMI_Handler); -#endif /* CONFIG_RUNTIME_NMI */ -} diff --git a/soc/renesas/ra/ra4m2/soc.h b/soc/renesas/ra/ra4m2/soc.h deleted file mode 100644 index 99cefaf34758..000000000000 --- a/soc/renesas/ra/ra4m2/soc.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2024 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file SoC configuration macros for the Renesas RA4M2 family MCU - */ - -#ifndef ZEPHYR_SOC_RENESAS_RA4M2_SOC_H_ -#define ZEPHYR_SOC_RENESAS_RA4M2_SOC_H_ - -#include - -#endif /* ZEPHYR_SOC_RENESAS_RA4M2_SOC_H_ */ diff --git a/soc/renesas/ra/ra4m3/CMakeLists.txt b/soc/renesas/ra/ra4m3/CMakeLists.txt index 7f86249065cb..5013edd514dd 100644 --- a/soc/renesas/ra/ra4m3/CMakeLists.txt +++ b/soc/renesas/ra/ra4m3/CMakeLists.txt @@ -3,10 +3,6 @@ zephyr_include_directories(.) -zephyr_sources( - soc.c -) - if(CONFIG_CMAKE_LINKER_GENERATOR) dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") dt_nodelabel(option_setting_ofs1_sec NODELABEL "option_setting_ofs1_sec") @@ -35,11 +31,6 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) dt_node_has_status(banksel_sel_status PATH ${option_setting_banksel_sel} STATUS okay) dt_node_has_status(bps_sel_status PATH ${option_setting_bps_sel} STATUS okay) - if(CONFIG_USE_RA_FSP_DTC) - zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) - zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") - endif() - if(${ofs0_status}) zephyr_linker_section(NAME .option_setting_ofs0 GROUP OFS_OFS0_MEMORY ADDRESS ${ofs0_addr}) zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") @@ -82,10 +73,7 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) elseif(CONFIG_LD_LINKER_TEMPLATE) zephyr_linker_sources(SECTIONS sections.ld) - zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) else() message(WARNING "Unsupported linker template.") endif() - -set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra4m3/Kconfig b/soc/renesas/ra/ra4m3/Kconfig index 379253245469..1a9c28821cb3 100644 --- a/soc/renesas/ra/ra4m3/Kconfig +++ b/soc/renesas/ra/ra4m3/Kconfig @@ -13,7 +13,6 @@ config SOC_SERIES_RA4M3 select FPU select HAS_SWO select XIP - select SOC_EARLY_INIT_HOOK select GPIO_RA_HAS_VBTICTLR if SOC_SERIES_RA4M3 diff --git a/soc/renesas/ra/ra4m3/ram_sections.ld b/soc/renesas/ra/ra4m3/ram_sections.ld deleted file mode 100644 index 18be2a431de2..000000000000 --- a/soc/renesas/ra/ra4m3/ram_sections.ld +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -#ifdef CONFIG_USE_RA_FSP_DTC -SECTION_DATA_PROLOGUE(.fsp_dtc_vector_table,(NOLOAD),) -{ - /* If DTC is used, put the DTC vector table at the start of SRAM. - This avoids memory holes due to 1K alignment required by it. */ - *(.fsp_dtc_vector_table) -} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION) -#endif /* CONFIG_USE_RA_FSP_DTC */ diff --git a/soc/renesas/ra/ra4m3/soc.c b/soc/renesas/ra/ra4m3/soc.c deleted file mode 100644 index 9bb153a0d9db..000000000000 --- a/soc/renesas/ra/ra4m3/soc.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2024 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief System/hardware module for Renesas RA4M3 family processor - */ - -#include -#include -#include -#include -#include -#include -#include -#include -LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); - -#include "bsp_cfg.h" -#include - -uint32_t SystemCoreClock BSP_SECTION_EARLY_INIT; - -volatile uint32_t g_protect_pfswe_counter BSP_SECTION_EARLY_INIT; - -#ifdef CONFIG_RUNTIME_NMI -extern bsp_grp_irq_cb_t g_bsp_group_irq_sources[]; -extern void NMI_Handler(void); -#endif /* CONFIG_RUNTIME_NMI */ - -/** - * @brief Perform basic hardware initialization at boot. - * - * This needs to be run from the very beginning. - */ -void soc_early_init_hook(void) -{ - extern volatile uint16_t g_protect_counters[]; - - for (uint32_t i = 0; i < 5; i++) { - g_protect_counters[i] = 0; - } - -#if FSP_PRIV_TZ_USE_SECURE_REGS - /* Disable protection using PRCR register. */ - R_BSP_RegisterProtectDisable(BSP_REG_PROTECT_SAR); - - /* Initialize peripherals to secure mode for flat projects */ - R_PSCU->PSARB = 0; - R_PSCU->PSARC = 0; - R_PSCU->PSARD = 0; - R_PSCU->PSARE = 0; - - R_CPSCU->ICUSARC = 0; - R_CPSCU->ICUSARG = 0; - R_CPSCU->ICUSARH = 0; - R_CPSCU->ICUSARI = 0; - - /* Enable protection using PRCR register. */ - R_BSP_RegisterProtectEnable(BSP_REG_PROTECT_SAR); -#endif - - SystemCoreClock = BSP_MOCO_HZ; - g_protect_pfswe_counter = 0; - -#ifdef CONFIG_RUNTIME_NMI - for (uint32_t i = 0; i < 16; i++) { - g_bsp_group_irq_sources[i] = 0; - } - - z_arm_nmi_set_handler(NMI_Handler); -#endif /* CONFIG_RUNTIME_NMI */ -} diff --git a/soc/renesas/ra/ra4m3/soc.h b/soc/renesas/ra/ra4m3/soc.h deleted file mode 100644 index 7910a06c96a7..000000000000 --- a/soc/renesas/ra/ra4m3/soc.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2024 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file SoC configuration macros for the Renesas RA4M3 family MCU - */ - -#ifndef ZEPHYR_SOC_RENESAS_RA4M3_SOC_H_ -#define ZEPHYR_SOC_RENESAS_RA4M3_SOC_H_ - -#include - -#endif /* ZEPHYR_SOC_RENESAS_RA4M3_SOC_H_ */ diff --git a/soc/renesas/ra/ra4t1/CMakeLists.txt b/soc/renesas/ra/ra4t1/CMakeLists.txt index 1eccd63aa3a4..b54dc8312ffb 100644 --- a/soc/renesas/ra/ra4t1/CMakeLists.txt +++ b/soc/renesas/ra/ra4t1/CMakeLists.txt @@ -3,9 +3,4 @@ zephyr_include_directories(.) -zephyr_sources(soc.c) - zephyr_linker_sources(SECTIONS sections.ld) -zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) - -set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra4t1/Kconfig b/soc/renesas/ra/ra4t1/Kconfig index 5b2a50a95760..7c857cc373b4 100644 --- a/soc/renesas/ra/ra4t1/Kconfig +++ b/soc/renesas/ra/ra4t1/Kconfig @@ -12,7 +12,6 @@ config SOC_SERIES_RA4T1 select CPU_HAS_FPU select FPU select XIP - select SOC_EARLY_INIT_HOOK if SOC_SERIES_RA4T1 diff --git a/soc/renesas/ra/ra4t1/ram_sections.ld b/soc/renesas/ra/ra4t1/ram_sections.ld deleted file mode 100644 index 18be2a431de2..000000000000 --- a/soc/renesas/ra/ra4t1/ram_sections.ld +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -#ifdef CONFIG_USE_RA_FSP_DTC -SECTION_DATA_PROLOGUE(.fsp_dtc_vector_table,(NOLOAD),) -{ - /* If DTC is used, put the DTC vector table at the start of SRAM. - This avoids memory holes due to 1K alignment required by it. */ - *(.fsp_dtc_vector_table) -} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION) -#endif /* CONFIG_USE_RA_FSP_DTC */ diff --git a/soc/renesas/ra/ra4t1/soc.c b/soc/renesas/ra/ra4t1/soc.c deleted file mode 100644 index ff3cfbfd08db..000000000000 --- a/soc/renesas/ra/ra4t1/soc.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief System/hardware module for Renesas RA4E2 family processor - */ - -#include -#include -#include -#include -#include -#include -#include -#include -LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); - -#include -#include "soc.h" - -uint32_t SystemCoreClock BSP_SECTION_EARLY_INIT; - -volatile uint32_t g_protect_pfswe_counter BSP_SECTION_EARLY_INIT; - -#ifdef CONFIG_RUNTIME_NMI -extern bsp_grp_irq_cb_t g_bsp_group_irq_sources[]; -extern void NMI_Handler(void); -#endif /* CONFIG_RUNTIME_NMI */ - -/** - * @brief Perform basic hardware initialization at boot. - * - * This needs to be run from the very beginning. - */ -void soc_early_init_hook(void) -{ - extern volatile uint16_t g_protect_counters[]; - - for (uint32_t i = 0; i < 5; i++) { - g_protect_counters[i] = 0; - } - -#if FSP_PRIV_TZ_USE_SECURE_REGS - /* Disable protection using PRCR register. */ - R_BSP_RegisterProtectDisable(BSP_REG_PROTECT_SAR); - - /* Initialize peripherals to secure mode for flat projects */ - R_PSCU->PSARB = 0; - R_PSCU->PSARC = 0; - R_PSCU->PSARD = 0; - R_PSCU->PSARE = 0; - - R_CPSCU->ICUSARC = 0; - R_CPSCU->ICUSARG = 0; - R_CPSCU->ICUSARH = 0; - R_CPSCU->ICUSARI = 0; - - /* Enable protection using PRCR register. */ - R_BSP_RegisterProtectEnable(BSP_REG_PROTECT_SAR); -#endif - - SystemCoreClock = BSP_MOCO_HZ; - g_protect_pfswe_counter = 0; - -#ifdef CONFIG_RUNTIME_NMI - for (uint32_t i = 0; i < 16; i++) { - g_bsp_group_irq_sources[i] = 0; - } - - z_arm_nmi_set_handler(NMI_Handler); -#endif /* CONFIG_RUNTIME_NMI */ -} diff --git a/soc/renesas/ra/ra4t1/soc.h b/soc/renesas/ra/ra4t1/soc.h deleted file mode 100644 index 979040422a73..000000000000 --- a/soc/renesas/ra/ra4t1/soc.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file SoC configuration macros for the Renesas RA4T1 family MCU - */ - -#ifndef ZEPHYR_SOC_RENESAS_RA4T1_SOC_H_ -#define ZEPHYR_SOC_RENESAS_RA4T1_SOC_H_ - -#include - -#endif /* ZEPHYR_SOC_RENESAS_RA4T1_SOC_H_ */ diff --git a/soc/renesas/ra/ra4w1/CMakeLists.txt b/soc/renesas/ra/ra4w1/CMakeLists.txt index ffb74974499d..d4d4d8e512e6 100644 --- a/soc/renesas/ra/ra4w1/CMakeLists.txt +++ b/soc/renesas/ra/ra4w1/CMakeLists.txt @@ -3,10 +3,6 @@ zephyr_include_directories(.) -zephyr_sources( - soc.c -) - if(CONFIG_CMAKE_LINKER_GENERATOR) dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") dt_nodelabel(option_setting_ofs1 NODELABEL "option_setting_ofs1") @@ -20,11 +16,6 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) dt_node_has_status(osis_status PATH ${option_setting_osis} STATUS okay) - if(CONFIG_USE_RA_FSP_DTC) - zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) - zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") - endif() - zephyr_linker_section(NAME .rom_padding GROUP ROM_REGION ADDRESS 0x000000C0) zephyr_linker_section_configure(SECTION .rom_padding KEEP INPUT ".rom_padding*") @@ -45,10 +36,7 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) elseif(CONFIG_LD_LINKER_TEMPLATE) zephyr_linker_sources(ROM_START rom_start.ld) zephyr_linker_sources(SECTIONS sections.ld) - zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) else() message(WARNING "Unsupported linker template.") endif() - -set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra4w1/Kconfig b/soc/renesas/ra/ra4w1/Kconfig index 34f44bf6d074..32eb9f1ceeb3 100644 --- a/soc/renesas/ra/ra4w1/Kconfig +++ b/soc/renesas/ra/ra4w1/Kconfig @@ -12,5 +12,4 @@ config SOC_SERIES_RA4W1 select FPU select HAS_SWO select XIP - select SOC_EARLY_INIT_HOOK select GPIO_RA_HAS_VBTICTLR diff --git a/soc/renesas/ra/ra4w1/ram_sections.ld b/soc/renesas/ra/ra4w1/ram_sections.ld deleted file mode 100644 index 18be2a431de2..000000000000 --- a/soc/renesas/ra/ra4w1/ram_sections.ld +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -#ifdef CONFIG_USE_RA_FSP_DTC -SECTION_DATA_PROLOGUE(.fsp_dtc_vector_table,(NOLOAD),) -{ - /* If DTC is used, put the DTC vector table at the start of SRAM. - This avoids memory holes due to 1K alignment required by it. */ - *(.fsp_dtc_vector_table) -} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION) -#endif /* CONFIG_USE_RA_FSP_DTC */ diff --git a/soc/renesas/ra/ra4w1/soc.c b/soc/renesas/ra/ra4w1/soc.c deleted file mode 100644 index c62592e320c2..000000000000 --- a/soc/renesas/ra/ra4w1/soc.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2024 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief System/hardware module for Renesas RA4W1 family processor - */ - -#include -#include -#include -#include -#include -#include -#include -#include -LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); - -#include "bsp_cfg.h" -#include - -uint32_t SystemCoreClock BSP_SECTION_EARLY_INIT; - -volatile uint32_t g_protect_pfswe_counter BSP_SECTION_EARLY_INIT; - -#ifdef CONFIG_RUNTIME_NMI -extern bsp_grp_irq_cb_t g_bsp_group_irq_sources[]; -extern void NMI_Handler(void); -#endif /* CONFIG_RUNTIME_NMI */ - -/** - * @brief Perform basic hardware initialization at boot. - * - * This needs to be run from the very beginning. - */ -void soc_early_init_hook(void) -{ - SystemCoreClock = BSP_MOCO_HZ; - g_protect_pfswe_counter = 0; - -#ifdef CONFIG_RUNTIME_NMI - for (uint32_t i = 0; i < 16; i++) { - g_bsp_group_irq_sources[i] = 0; - } - - z_arm_nmi_set_handler(NMI_Handler); -#endif /* CONFIG_RUNTIME_NMI */ -} diff --git a/soc/renesas/ra/ra4w1/soc.h b/soc/renesas/ra/ra4w1/soc.h deleted file mode 100644 index 7646360c58bb..000000000000 --- a/soc/renesas/ra/ra4w1/soc.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2024 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file SoC configuration macros for the Renesas RA4W1 family MCU - */ - -#ifndef ZEPHYR_SOC_RENESAS_RA4W1_SOC_H_ -#define ZEPHYR_SOC_RENESAS_RA4W1_SOC_H_ - -#include - -#endif /* ZEPHYR_SOC_RENESAS_RA4W1_SOC_H_ */ diff --git a/soc/renesas/ra/ra6e1/CMakeLists.txt b/soc/renesas/ra/ra6e1/CMakeLists.txt index 0459d4214b8d..50a1a19272ba 100644 --- a/soc/renesas/ra/ra6e1/CMakeLists.txt +++ b/soc/renesas/ra/ra6e1/CMakeLists.txt @@ -3,10 +3,6 @@ zephyr_include_directories(.) -zephyr_sources( - soc.c -) - if(CONFIG_CMAKE_LINKER_GENERATOR) dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") dt_nodelabel(option_setting_dualsel NODELABEL "option_setting_dualsel") @@ -38,11 +34,6 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) dt_node_has_status(banksel_sel_status PATH ${option_setting_banksel_sel} STATUS okay) dt_node_has_status(bps_sel_status PATH ${option_setting_bps_sel} STATUS okay) - if(CONFIG_USE_RA_FSP_DTC) - zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) - zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") - endif() - if(${ofs0_status}) zephyr_linker_section(NAME .option_setting_ofs0 GROUP OFS_OFS0_MEMORY ADDRESS ${ofs0_addr}) zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") @@ -90,10 +81,7 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) elseif(CONFIG_LD_LINKER_TEMPLATE) zephyr_linker_sources(SECTIONS sections.ld) - zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) else() message(WARNING "Unsupported linker template.") endif() - -set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra6e1/Kconfig b/soc/renesas/ra/ra6e1/Kconfig index b93d85a76ffd..5e171c26a112 100644 --- a/soc/renesas/ra/ra6e1/Kconfig +++ b/soc/renesas/ra/ra6e1/Kconfig @@ -13,7 +13,6 @@ config SOC_SERIES_RA6E1 select FPU select HAS_SWO select XIP - select SOC_EARLY_INIT_HOOK select GPIO_RA_HAS_VBTICTLR if SOC_SERIES_RA6E1 diff --git a/soc/renesas/ra/ra6e1/ram_sections.ld b/soc/renesas/ra/ra6e1/ram_sections.ld deleted file mode 100644 index 18be2a431de2..000000000000 --- a/soc/renesas/ra/ra6e1/ram_sections.ld +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -#ifdef CONFIG_USE_RA_FSP_DTC -SECTION_DATA_PROLOGUE(.fsp_dtc_vector_table,(NOLOAD),) -{ - /* If DTC is used, put the DTC vector table at the start of SRAM. - This avoids memory holes due to 1K alignment required by it. */ - *(.fsp_dtc_vector_table) -} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION) -#endif /* CONFIG_USE_RA_FSP_DTC */ diff --git a/soc/renesas/ra/ra6e1/soc.c b/soc/renesas/ra/ra6e1/soc.c deleted file mode 100644 index b8bf0463c7d6..000000000000 --- a/soc/renesas/ra/ra6e1/soc.c +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2024 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief System/hardware module for Renesas RA6E1 family processor - */ - -#include -#include -#include -#include -#include -#include -#include -LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); - -#include "bsp_cfg.h" -#include - -uint32_t SystemCoreClock BSP_SECTION_EARLY_INIT; - -volatile uint32_t g_protect_pfswe_counter BSP_SECTION_EARLY_INIT; - -#ifdef CONFIG_RUNTIME_NMI -extern bsp_grp_irq_cb_t g_bsp_group_irq_sources[]; -extern void NMI_Handler(void); -#endif /* CONFIG_RUNTIME_NMI */ - -/** - * @brief Perform basic hardware initialization at boot. - * - * This needs to be run from the very beginning. - */ -void soc_early_init_hook(void) -{ - uint32_t key; - - extern volatile uint16_t g_protect_counters[]; - - for (uint32_t i = 0; i < 5; i++) { - g_protect_counters[i] = 0; - } - -#if FSP_PRIV_TZ_USE_SECURE_REGS - /* Disable protection using PRCR register. */ - R_BSP_RegisterProtectDisable(BSP_REG_PROTECT_SAR); - - /* Initialize peripherals to secure mode for flat projects */ - R_PSCU->PSARB = 0; - R_PSCU->PSARC = 0; - R_PSCU->PSARD = 0; - R_PSCU->PSARE = 0; - - R_CPSCU->ICUSARC = 0; - R_CPSCU->ICUSARG = 0; - R_CPSCU->ICUSARH = 0; - R_CPSCU->ICUSARI = 0; - - /* Enable protection using PRCR register. */ - R_BSP_RegisterProtectEnable(BSP_REG_PROTECT_SAR); -#endif - - key = irq_lock(); - - SystemCoreClock = BSP_MOCO_HZ; - g_protect_pfswe_counter = 0; - -#ifdef CONFIG_RUNTIME_NMI - for (uint32_t i = 0; i < 16; i++) { - g_bsp_group_irq_sources[i] = 0; - } - - z_arm_nmi_set_handler(NMI_Handler); -#endif /* CONFIG_RUNTIME_NMI */ - - irq_unlock(key); -} diff --git a/soc/renesas/ra/ra6e1/soc.h b/soc/renesas/ra/ra6e1/soc.h deleted file mode 100644 index 0d3eb2c16fcc..000000000000 --- a/soc/renesas/ra/ra6e1/soc.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2024 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file SoC configuration macros for the Renesas RA6E1 family MCU - */ - -#ifndef ZEPHYR_SOC_RENESAS_RA6E1_SOC_H_ -#define ZEPHYR_SOC_RENESAS_RA6E1_SOC_H_ - -#include - -#endif /* ZEPHYR_SOC_RENESAS_RA6E1_SOC_H_ */ diff --git a/soc/renesas/ra/ra6e2/CMakeLists.txt b/soc/renesas/ra/ra6e2/CMakeLists.txt index 4eea413d6825..5ac3de6b8848 100644 --- a/soc/renesas/ra/ra6e2/CMakeLists.txt +++ b/soc/renesas/ra/ra6e2/CMakeLists.txt @@ -3,10 +3,6 @@ zephyr_include_directories(.) -zephyr_sources( - soc.c -) - if(CONFIG_CMAKE_LINKER_GENERATOR) dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") dt_nodelabel(option_setting_osis NODELABEL "option_setting_osis") @@ -26,11 +22,6 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) dt_node_has_status(bps_sec_status PATH ${option_setting_bps_sec} STATUS okay) dt_node_has_status(pbps_sec_status PATH ${option_setting_pbps_sec} STATUS okay) - if(CONFIG_USE_RA_FSP_DTC) - zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) - zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") - endif() - if(${ofs0_status}) zephyr_linker_section(NAME .option_setting_ofs0 GROUP OFS_OFS0_MEMORY ADDRESS ${ofs0_addr}) zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") @@ -58,10 +49,7 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) elseif(CONFIG_LD_LINKER_TEMPLATE) zephyr_linker_sources(SECTIONS sections.ld) - zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) else() message(WARNING "Unsupported linker template.") endif() - -set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra6e2/Kconfig b/soc/renesas/ra/ra6e2/Kconfig index 841bafe2fcd9..bfba13e86797 100644 --- a/soc/renesas/ra/ra6e2/Kconfig +++ b/soc/renesas/ra/ra6e2/Kconfig @@ -13,7 +13,6 @@ config SOC_SERIES_RA6E2 select FPU select HAS_SWO select XIP - select SOC_EARLY_INIT_HOOK if SOC_SERIES_RA6E2 diff --git a/soc/renesas/ra/ra6e2/ram_sections.ld b/soc/renesas/ra/ra6e2/ram_sections.ld deleted file mode 100644 index 18be2a431de2..000000000000 --- a/soc/renesas/ra/ra6e2/ram_sections.ld +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -#ifdef CONFIG_USE_RA_FSP_DTC -SECTION_DATA_PROLOGUE(.fsp_dtc_vector_table,(NOLOAD),) -{ - /* If DTC is used, put the DTC vector table at the start of SRAM. - This avoids memory holes due to 1K alignment required by it. */ - *(.fsp_dtc_vector_table) -} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION) -#endif /* CONFIG_USE_RA_FSP_DTC */ diff --git a/soc/renesas/ra/ra6e2/soc.c b/soc/renesas/ra/ra6e2/soc.c deleted file mode 100644 index c68fc9880ab9..000000000000 --- a/soc/renesas/ra/ra6e2/soc.c +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2024 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief System/hardware module for Renesas RA6E2 family processor - */ - -#include -#include -#include -#include -#include -#include -#include -LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); - -#include "bsp_cfg.h" -#include - -uint32_t SystemCoreClock BSP_SECTION_EARLY_INIT; - -volatile uint32_t g_protect_pfswe_counter BSP_SECTION_EARLY_INIT; - -#ifdef CONFIG_RUNTIME_NMI -extern bsp_grp_irq_cb_t g_bsp_group_irq_sources[]; -extern void NMI_Handler(void); -#endif /* CONFIG_RUNTIME_NMI */ - -/** - * @brief Perform basic hardware initialization at boot. - * - * This needs to be run from the very beginning. - */ -void soc_early_init_hook(void) -{ - uint32_t key; - - key = irq_lock(); - - extern volatile uint16_t g_protect_counters[]; - - for (uint32_t i = 0; i < 5; i++) { - g_protect_counters[i] = 0; - } - -#if FSP_PRIV_TZ_USE_SECURE_REGS - /* Disable protection using PRCR register. */ - R_BSP_RegisterProtectDisable(BSP_REG_PROTECT_SAR); - - /* Initialize peripherals to secure mode for flat projects */ - R_PSCU->PSARB = 0; - R_PSCU->PSARC = 0; - R_PSCU->PSARD = 0; - R_PSCU->PSARE = 0; - - R_CPSCU->ICUSARC = 0; - R_CPSCU->ICUSARG = 0; - R_CPSCU->ICUSARH = 0; - R_CPSCU->ICUSARI = 0; - - /* Enable protection using PRCR register. */ - R_BSP_RegisterProtectEnable(BSP_REG_PROTECT_SAR); -#endif - - SystemCoreClock = BSP_MOCO_HZ; - g_protect_pfswe_counter = 0; - -#ifdef CONFIG_RUNTIME_NMI - for (uint32_t i = 0; i < 16; i++) { - g_bsp_group_irq_sources[i] = 0; - } - - z_arm_nmi_set_handler(NMI_Handler); -#endif /* CONFIG_RUNTIME_NMI */ - - irq_unlock(key); -} diff --git a/soc/renesas/ra/ra6e2/soc.h b/soc/renesas/ra/ra6e2/soc.h deleted file mode 100644 index a40324087cdb..000000000000 --- a/soc/renesas/ra/ra6e2/soc.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2024 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file SoC configuration macros for the Renesas RA6E2 family MCU - */ - -#ifndef ZEPHYR_SOC_RENESAS_RA6E2_SOC_H_ -#define ZEPHYR_SOC_RENESAS_RA6E2_SOC_H_ - -#include - -#endif /* ZEPHYR_SOC_RENESAS_RA6E2_SOC_H_ */ diff --git a/soc/renesas/ra/ra6m1/CMakeLists.txt b/soc/renesas/ra/ra6m1/CMakeLists.txt index f13469eb33c6..ff0cadb478c9 100644 --- a/soc/renesas/ra/ra6m1/CMakeLists.txt +++ b/soc/renesas/ra/ra6m1/CMakeLists.txt @@ -3,10 +3,6 @@ zephyr_include_directories(.) -zephyr_sources( - soc.c -) - if(CONFIG_CMAKE_LINKER_GENERATOR) dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") dt_nodelabel(option_setting_ofs1 NODELABEL "option_setting_ofs1") @@ -20,11 +16,6 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) dt_node_has_status(osis_status PATH ${option_setting_osis} STATUS okay) - if(CONFIG_USE_RA_FSP_DTC) - zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) - zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") - endif() - zephyr_linker_section(NAME .rom_padding GROUP ROM_REGION ADDRESS 0x000001C0) zephyr_linker_section_configure(SECTION .rom_padding KEEP INPUT ".rom_padding*") @@ -45,10 +36,7 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) elseif(CONFIG_LD_LINKER_TEMPLATE) zephyr_linker_sources(ROM_START rom_start.ld) zephyr_linker_sources(SECTIONS sections.ld) - zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) else() message(WARNING "Unsupported linker template.") endif() - -set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra6m1/Kconfig b/soc/renesas/ra/ra6m1/Kconfig index d637b0aaf1ca..8d87148cd68e 100644 --- a/soc/renesas/ra/ra6m1/Kconfig +++ b/soc/renesas/ra/ra6m1/Kconfig @@ -12,7 +12,6 @@ config SOC_SERIES_RA6M1 select FPU select HAS_SWO select XIP - select SOC_EARLY_INIT_HOOK select GPIO_RA_HAS_VBTICTLR if SOC_SERIES_RA6M1 diff --git a/soc/renesas/ra/ra6m1/ram_sections.ld b/soc/renesas/ra/ra6m1/ram_sections.ld deleted file mode 100644 index 18be2a431de2..000000000000 --- a/soc/renesas/ra/ra6m1/ram_sections.ld +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -#ifdef CONFIG_USE_RA_FSP_DTC -SECTION_DATA_PROLOGUE(.fsp_dtc_vector_table,(NOLOAD),) -{ - /* If DTC is used, put the DTC vector table at the start of SRAM. - This avoids memory holes due to 1K alignment required by it. */ - *(.fsp_dtc_vector_table) -} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION) -#endif /* CONFIG_USE_RA_FSP_DTC */ diff --git a/soc/renesas/ra/ra6m1/soc.c b/soc/renesas/ra/ra6m1/soc.c deleted file mode 100644 index 1986da3ec8c4..000000000000 --- a/soc/renesas/ra/ra6m1/soc.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2024 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief System/hardware module for Renesas RA6M1 family processor - */ - -#include -#include -#include -#include -#include -#include -#include -LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); - -#include "bsp_cfg.h" -#include - -uint32_t SystemCoreClock BSP_SECTION_EARLY_INIT; - -volatile uint32_t g_protect_pfswe_counter BSP_SECTION_EARLY_INIT; - -#ifdef CONFIG_RUNTIME_NMI -extern bsp_grp_irq_cb_t g_bsp_group_irq_sources[]; -extern void NMI_Handler(void); -#endif /* CONFIG_RUNTIME_NMI */ - -/** - * @brief Perform basic hardware initialization at boot. - * - * This needs to be run from the very beginning. - */ -void soc_early_init_hook(void) -{ - uint32_t key; - - key = irq_lock(); - - SystemCoreClock = BSP_MOCO_HZ; - g_protect_pfswe_counter = 0; - -#ifdef CONFIG_RUNTIME_NMI - for (uint32_t i = 0; i < 16; i++) { - g_bsp_group_irq_sources[i] = 0; - } - - z_arm_nmi_set_handler(NMI_Handler); -#endif /* CONFIG_RUNTIME_NMI */ - - irq_unlock(key); -} diff --git a/soc/renesas/ra/ra6m1/soc.h b/soc/renesas/ra/ra6m1/soc.h deleted file mode 100644 index b341280870ec..000000000000 --- a/soc/renesas/ra/ra6m1/soc.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2024 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file SoC configuration macros for the Renesas RA6M1 family MCU - */ - -#ifndef ZEPHYR_SOC_RENESAS_RA6M1_SOC_H_ -#define ZEPHYR_SOC_RENESAS_RA6M1_SOC_H_ - -#include - -#endif /* ZEPHYR_SOC_RENESAS_RA6M1_SOC_H_ */ diff --git a/soc/renesas/ra/ra6m2/CMakeLists.txt b/soc/renesas/ra/ra6m2/CMakeLists.txt index f13469eb33c6..ff0cadb478c9 100644 --- a/soc/renesas/ra/ra6m2/CMakeLists.txt +++ b/soc/renesas/ra/ra6m2/CMakeLists.txt @@ -3,10 +3,6 @@ zephyr_include_directories(.) -zephyr_sources( - soc.c -) - if(CONFIG_CMAKE_LINKER_GENERATOR) dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") dt_nodelabel(option_setting_ofs1 NODELABEL "option_setting_ofs1") @@ -20,11 +16,6 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) dt_node_has_status(osis_status PATH ${option_setting_osis} STATUS okay) - if(CONFIG_USE_RA_FSP_DTC) - zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) - zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") - endif() - zephyr_linker_section(NAME .rom_padding GROUP ROM_REGION ADDRESS 0x000001C0) zephyr_linker_section_configure(SECTION .rom_padding KEEP INPUT ".rom_padding*") @@ -45,10 +36,7 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) elseif(CONFIG_LD_LINKER_TEMPLATE) zephyr_linker_sources(ROM_START rom_start.ld) zephyr_linker_sources(SECTIONS sections.ld) - zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) else() message(WARNING "Unsupported linker template.") endif() - -set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra6m2/Kconfig b/soc/renesas/ra/ra6m2/Kconfig index 3946ee6bdd99..19881efdd6f9 100644 --- a/soc/renesas/ra/ra6m2/Kconfig +++ b/soc/renesas/ra/ra6m2/Kconfig @@ -12,7 +12,6 @@ config SOC_SERIES_RA6M2 select FPU select HAS_SWO select XIP - select SOC_EARLY_INIT_HOOK select GPIO_RA_HAS_VBTICTLR if SOC_SERIES_RA6M2 diff --git a/soc/renesas/ra/ra6m2/ram_sections.ld b/soc/renesas/ra/ra6m2/ram_sections.ld deleted file mode 100644 index 18be2a431de2..000000000000 --- a/soc/renesas/ra/ra6m2/ram_sections.ld +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -#ifdef CONFIG_USE_RA_FSP_DTC -SECTION_DATA_PROLOGUE(.fsp_dtc_vector_table,(NOLOAD),) -{ - /* If DTC is used, put the DTC vector table at the start of SRAM. - This avoids memory holes due to 1K alignment required by it. */ - *(.fsp_dtc_vector_table) -} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION) -#endif /* CONFIG_USE_RA_FSP_DTC */ diff --git a/soc/renesas/ra/ra6m2/soc.c b/soc/renesas/ra/ra6m2/soc.c deleted file mode 100644 index 90d7cd7fad1d..000000000000 --- a/soc/renesas/ra/ra6m2/soc.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2024 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief System/hardware module for Renesas RA6M2 family processor - */ - -#include -#include -#include -#include -#include -#include -#include -LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); - -#include "bsp_cfg.h" -#include - -uint32_t SystemCoreClock BSP_SECTION_EARLY_INIT; - -volatile uint32_t g_protect_pfswe_counter BSP_SECTION_EARLY_INIT; - -#ifdef CONFIG_RUNTIME_NMI -extern bsp_grp_irq_cb_t g_bsp_group_irq_sources[]; -extern void NMI_Handler(void); -#endif /* CONFIG_RUNTIME_NMI */ - -/** - * @brief Perform basic hardware initialization at boot. - * - * This needs to be run from the very beginning. - */ -void soc_early_init_hook(void) -{ - uint32_t key; - - key = irq_lock(); - - SystemCoreClock = BSP_MOCO_HZ; - g_protect_pfswe_counter = 0; - -#ifdef CONFIG_RUNTIME_NMI - for (uint32_t i = 0; i < 16; i++) { - g_bsp_group_irq_sources[i] = 0; - } - - z_arm_nmi_set_handler(NMI_Handler); -#endif /* CONFIG_RUNTIME_NMI */ - - irq_unlock(key); -} diff --git a/soc/renesas/ra/ra6m2/soc.h b/soc/renesas/ra/ra6m2/soc.h deleted file mode 100644 index 8ad75a1efea5..000000000000 --- a/soc/renesas/ra/ra6m2/soc.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2024 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file SoC configuration macros for the Renesas RA6M2 family MCU - */ - -#ifndef ZEPHYR_SOC_RENESAS_RA6M2_SOC_H_ -#define ZEPHYR_SOC_RENESAS_RA6M2_SOC_H_ - -#include - -#endif /* ZEPHYR_SOC_RENESAS_RA6M2_SOC_H_ */ diff --git a/soc/renesas/ra/ra6m3/CMakeLists.txt b/soc/renesas/ra/ra6m3/CMakeLists.txt index f13469eb33c6..ff0cadb478c9 100644 --- a/soc/renesas/ra/ra6m3/CMakeLists.txt +++ b/soc/renesas/ra/ra6m3/CMakeLists.txt @@ -3,10 +3,6 @@ zephyr_include_directories(.) -zephyr_sources( - soc.c -) - if(CONFIG_CMAKE_LINKER_GENERATOR) dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") dt_nodelabel(option_setting_ofs1 NODELABEL "option_setting_ofs1") @@ -20,11 +16,6 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) dt_node_has_status(osis_status PATH ${option_setting_osis} STATUS okay) - if(CONFIG_USE_RA_FSP_DTC) - zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) - zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") - endif() - zephyr_linker_section(NAME .rom_padding GROUP ROM_REGION ADDRESS 0x000001C0) zephyr_linker_section_configure(SECTION .rom_padding KEEP INPUT ".rom_padding*") @@ -45,10 +36,7 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) elseif(CONFIG_LD_LINKER_TEMPLATE) zephyr_linker_sources(ROM_START rom_start.ld) zephyr_linker_sources(SECTIONS sections.ld) - zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) else() message(WARNING "Unsupported linker template.") endif() - -set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra6m3/Kconfig b/soc/renesas/ra/ra6m3/Kconfig index 21fe71c4a48a..a223f07f8728 100644 --- a/soc/renesas/ra/ra6m3/Kconfig +++ b/soc/renesas/ra/ra6m3/Kconfig @@ -12,7 +12,6 @@ config SOC_SERIES_RA6M3 select FPU select HAS_SWO select XIP - select SOC_EARLY_INIT_HOOK select GPIO_RA_HAS_VBTICTLR if SOC_SERIES_RA6M3 diff --git a/soc/renesas/ra/ra6m3/ram_sections.ld b/soc/renesas/ra/ra6m3/ram_sections.ld deleted file mode 100644 index 18be2a431de2..000000000000 --- a/soc/renesas/ra/ra6m3/ram_sections.ld +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -#ifdef CONFIG_USE_RA_FSP_DTC -SECTION_DATA_PROLOGUE(.fsp_dtc_vector_table,(NOLOAD),) -{ - /* If DTC is used, put the DTC vector table at the start of SRAM. - This avoids memory holes due to 1K alignment required by it. */ - *(.fsp_dtc_vector_table) -} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION) -#endif /* CONFIG_USE_RA_FSP_DTC */ diff --git a/soc/renesas/ra/ra6m3/soc.c b/soc/renesas/ra/ra6m3/soc.c deleted file mode 100644 index 9c520b99e3a1..000000000000 --- a/soc/renesas/ra/ra6m3/soc.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2024 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief System/hardware module for Renesas RA6M3 family processor - */ - -#include -#include -#include -#include -#include -#include -#include -LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); - -#include "bsp_cfg.h" -#include - -uint32_t SystemCoreClock BSP_SECTION_EARLY_INIT; - -volatile uint32_t g_protect_pfswe_counter BSP_SECTION_EARLY_INIT; - -#ifdef CONFIG_RUNTIME_NMI -extern bsp_grp_irq_cb_t g_bsp_group_irq_sources[]; -extern void NMI_Handler(void); -#endif /* CONFIG_RUNTIME_NMI */ - -/** - * @brief Perform basic hardware initialization at boot. - * - * This needs to be run from the very beginning. - */ -void soc_early_init_hook(void) -{ - uint32_t key; - - key = irq_lock(); - - SystemCoreClock = BSP_MOCO_HZ; - g_protect_pfswe_counter = 0; - -#ifdef CONFIG_RUNTIME_NMI - for (uint32_t i = 0; i < 16; i++) { - g_bsp_group_irq_sources[i] = 0; - } - - z_arm_nmi_set_handler(NMI_Handler); -#endif - - irq_unlock(key); -} diff --git a/soc/renesas/ra/ra6m3/soc.h b/soc/renesas/ra/ra6m3/soc.h deleted file mode 100644 index 9fa414f0b647..000000000000 --- a/soc/renesas/ra/ra6m3/soc.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2024 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file SoC configuration macros for the Renesas RA6M3 family MCU - */ - -#ifndef ZEPHYR_SOC_RENESAS_RA6M3_SOC_H_ -#define ZEPHYR_SOC_RENESAS_RA6M3_SOC_H_ - -#include - -#endif /* ZEPHYR_SOC_RENESAS_RA6M3_SOC_H_ */ diff --git a/soc/renesas/ra/ra6m4/CMakeLists.txt b/soc/renesas/ra/ra6m4/CMakeLists.txt index 4ecf42a5fc63..d65792c0f5a6 100644 --- a/soc/renesas/ra/ra6m4/CMakeLists.txt +++ b/soc/renesas/ra/ra6m4/CMakeLists.txt @@ -3,10 +3,6 @@ zephyr_include_directories(.) -zephyr_sources( - soc.c -) - if(CONFIG_CMAKE_LINKER_GENERATOR) dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") dt_nodelabel(option_setting_dualsel NODELABEL "option_setting_dualsel") @@ -38,11 +34,6 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) dt_node_has_status(banksel_sel_status PATH ${option_setting_banksel_sel} STATUS okay) dt_node_has_status(bps_sel_status PATH ${option_setting_bps_sel} STATUS okay) - if(CONFIG_USE_RA_FSP_DTC) - zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) - zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") - endif() - if(${ofs0_status}) zephyr_linker_section(NAME .option_setting_ofs0 GROUP OFS_OFS0_MEMORY ADDRESS ${ofs0_addr}) zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") @@ -88,9 +79,12 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) zephyr_linker_section_configure(SECTION .option_setting_bps_sel KEEP INPUT ".option_setting_bps_sel*") endif() + if(CONFIG_ETH_RENESAS_RA_USE_NS_BUF) + message(WARNING "Configure ETHERNET non-secure buffer with CMAKE_LINKER_GENERATOR is not supported.") + endif() + elseif(CONFIG_LD_LINKER_TEMPLATE) zephyr_linker_sources(SECTIONS sections.ld) - zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) else() message(WARNING "Unsupported linker template.") @@ -109,8 +103,6 @@ if(CONFIG_ETH_RENESAS_RA_USE_NS_BUF) --output-rpd ${PROJECT_BINARY_DIR}/${CONFIG_KERNEL_BIN_NAME}.rpd $<$:--verbose> WORKING_DIRECTORY ${PROJECT_BINARY_DIR} - ) + ) endif() -else() - set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") endif() diff --git a/soc/renesas/ra/ra6m4/Kconfig b/soc/renesas/ra/ra6m4/Kconfig index 50af68b81788..4bc5d96bfba1 100644 --- a/soc/renesas/ra/ra6m4/Kconfig +++ b/soc/renesas/ra/ra6m4/Kconfig @@ -14,7 +14,6 @@ config SOC_SERIES_RA6M4 select FPU select HAS_SWO select XIP - select SOC_EARLY_INIT_HOOK select GPIO_RA_HAS_VBTICTLR select OUTPUT_RPD if ETH_RENESAS_RA diff --git a/soc/renesas/ra/ra6m4/ram_sections.ld b/soc/renesas/ra/ra6m4/ram_sections.ld deleted file mode 100644 index 18be2a431de2..000000000000 --- a/soc/renesas/ra/ra6m4/ram_sections.ld +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -#ifdef CONFIG_USE_RA_FSP_DTC -SECTION_DATA_PROLOGUE(.fsp_dtc_vector_table,(NOLOAD),) -{ - /* If DTC is used, put the DTC vector table at the start of SRAM. - This avoids memory holes due to 1K alignment required by it. */ - *(.fsp_dtc_vector_table) -} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION) -#endif /* CONFIG_USE_RA_FSP_DTC */ diff --git a/soc/renesas/ra/ra6m4/soc.c b/soc/renesas/ra/ra6m4/soc.c deleted file mode 100644 index 11342effb0da..000000000000 --- a/soc/renesas/ra/ra6m4/soc.c +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2024 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief System/hardware module for Renesas RA6M4 family processor - */ - -#include -#include -#include -#include -#include -#include -#include -LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); - -#include "bsp_cfg.h" -#include - -uint32_t SystemCoreClock BSP_SECTION_EARLY_INIT; - -volatile uint32_t g_protect_pfswe_counter BSP_SECTION_EARLY_INIT; - -#ifdef CONFIG_RUNTIME_NMI -extern bsp_grp_irq_cb_t g_bsp_group_irq_sources[]; -extern void NMI_Handler(void); -#endif /* CONFIG_RUNTIME_NMI */ - -/** - * @brief Perform basic hardware initialization at boot. - * - * This needs to be run from the very beginning. - */ -void soc_early_init_hook(void) -{ - uint32_t key; - - key = irq_lock(); - - extern volatile uint16_t g_protect_counters[]; - - for (uint32_t i = 0; i < 5; i++) { - g_protect_counters[i] = 0; - } - -#if FSP_PRIV_TZ_USE_SECURE_REGS - /* Disable protection using PRCR register. */ - R_BSP_RegisterProtectDisable(BSP_REG_PROTECT_SAR); - - /* Initialize peripherals to secure mode for flat projects */ - R_PSCU->PSARB = 0; - R_PSCU->PSARC = 0; - R_PSCU->PSARD = 0; - R_PSCU->PSARE = 0; - - R_CPSCU->ICUSARC = 0; - R_CPSCU->ICUSARG = 0; - R_CPSCU->ICUSARH = 0; - R_CPSCU->ICUSARI = 0; - - /* Enable protection using PRCR register. */ - R_BSP_RegisterProtectEnable(BSP_REG_PROTECT_SAR); -#endif - - SystemCoreClock = BSP_MOCO_HZ; - g_protect_pfswe_counter = 0; - -#ifdef CONFIG_RUNTIME_NMI - for (uint32_t i = 0; i < 16; i++) { - g_bsp_group_irq_sources[i] = 0; - } - - z_arm_nmi_set_handler(NMI_Handler); -#endif - - irq_unlock(key); -} diff --git a/soc/renesas/ra/ra6m4/soc.h b/soc/renesas/ra/ra6m4/soc.h deleted file mode 100644 index 13344b76e84a..000000000000 --- a/soc/renesas/ra/ra6m4/soc.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2024 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file SoC configuration macros for the Renesas RA6M4 family MCU - */ - -#ifndef ZEPHYR_SOC_RENESAS_RA6M4_SOC_H_ -#define ZEPHYR_SOC_RENESAS_RA6M4_SOC_H_ - -#include - -#endif /* ZEPHYR_SOC_RENESAS_RA6M4_SOC_H_ */ diff --git a/soc/renesas/ra/ra6m5/CMakeLists.txt b/soc/renesas/ra/ra6m5/CMakeLists.txt index b1b8a9d88f15..4f2bdb036687 100644 --- a/soc/renesas/ra/ra6m5/CMakeLists.txt +++ b/soc/renesas/ra/ra6m5/CMakeLists.txt @@ -3,10 +3,6 @@ zephyr_include_directories(.) -zephyr_sources( - soc.c -) - if(CONFIG_CMAKE_LINKER_GENERATOR) dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") dt_nodelabel(option_setting_dualsel NODELABEL "option_setting_dualsel") @@ -38,11 +34,6 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) dt_node_has_status(banksel_sel_status PATH ${option_setting_banksel_sel} STATUS okay) dt_node_has_status(bps_sel_status PATH ${option_setting_bps_sel} STATUS okay) - if(CONFIG_USE_RA_FSP_DTC) - zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) - zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") - endif() - if(${ofs0_status}) zephyr_linker_section(NAME .option_setting_ofs0 GROUP OFS_OFS0_MEMORY ADDRESS ${ofs0_addr}) zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") @@ -88,9 +79,12 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) zephyr_linker_section_configure(SECTION .option_setting_bps_sel KEEP INPUT ".option_setting_bps_sel*") endif() + if(CONFIG_ETH_RENESAS_RA_USE_NS_BUF) + message(WARNING "Configure ETHERNET non-secure buffer with CMAKE_LINKER_GENERATOR is not supported.") + endif() + elseif(CONFIG_LD_LINKER_TEMPLATE) zephyr_linker_sources(SECTIONS sections.ld) - zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) else() message(WARNING "Unsupported linker template.") @@ -111,6 +105,4 @@ if(CONFIG_ETH_RENESAS_RA_USE_NS_BUF) WORKING_DIRECTORY ${PROJECT_BINARY_DIR} ) endif() -else() - set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") endif() diff --git a/soc/renesas/ra/ra6m5/Kconfig b/soc/renesas/ra/ra6m5/Kconfig index c7d645907272..93e4bd1c93fb 100644 --- a/soc/renesas/ra/ra6m5/Kconfig +++ b/soc/renesas/ra/ra6m5/Kconfig @@ -14,7 +14,6 @@ config SOC_SERIES_RA6M5 select FPU select HAS_SWO select XIP - select SOC_EARLY_INIT_HOOK select GPIO_RA_HAS_VBTICTLR select OUTPUT_RPD if ETH_RENESAS_RA diff --git a/soc/renesas/ra/ra6m5/ram_sections.ld b/soc/renesas/ra/ra6m5/ram_sections.ld deleted file mode 100644 index 18be2a431de2..000000000000 --- a/soc/renesas/ra/ra6m5/ram_sections.ld +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -#ifdef CONFIG_USE_RA_FSP_DTC -SECTION_DATA_PROLOGUE(.fsp_dtc_vector_table,(NOLOAD),) -{ - /* If DTC is used, put the DTC vector table at the start of SRAM. - This avoids memory holes due to 1K alignment required by it. */ - *(.fsp_dtc_vector_table) -} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION) -#endif /* CONFIG_USE_RA_FSP_DTC */ diff --git a/soc/renesas/ra/ra6m5/soc.c b/soc/renesas/ra/ra6m5/soc.c deleted file mode 100644 index bba626f25b25..000000000000 --- a/soc/renesas/ra/ra6m5/soc.c +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2024 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief System/hardware module for Renesas RA6M5 family processor - */ - -#include -#include -#include -#include -#include -#include -#include -LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); - -#include "bsp_cfg.h" -#include - -uint32_t SystemCoreClock BSP_SECTION_EARLY_INIT; - -volatile uint32_t g_protect_pfswe_counter BSP_SECTION_EARLY_INIT; - -#ifdef CONFIG_RUNTIME_NMI -extern bsp_grp_irq_cb_t g_bsp_group_irq_sources[]; -extern void NMI_Handler(void); -#endif /* CONFIG_RUNTIME_NMI */ - -/** - * @brief Perform basic hardware initialization at boot. - * - * This needs to be run from the very beginning. - */ -void soc_early_init_hook(void) -{ - uint32_t key; - - key = irq_lock(); - - extern volatile uint16_t g_protect_counters[]; - - for (uint32_t i = 0; i < 5; i++) { - g_protect_counters[i] = 0; - } - -#if FSP_PRIV_TZ_USE_SECURE_REGS - /* Disable protection using PRCR register. */ - R_BSP_RegisterProtectDisable(BSP_REG_PROTECT_SAR); - - /* Initialize peripherals to secure mode for flat projects */ - R_PSCU->PSARB = 0; - R_PSCU->PSARC = 0; - R_PSCU->PSARD = 0; - R_PSCU->PSARE = 0; - R_CPSCU->ICUSARC = 0; - - /* The secure Attribute managed within the ARM CPU NVIC must match the - * security attribution of IELSEn registers (Reference section 13.2.9 - * in the RA6M4 manual R01UH0890EJ0050). - */ - uint32_t volatile *p_icusarg = &R_CPSCU->ICUSARG; - - for (int i = 0; i < BSP_ICU_VECTOR_MAX_ENTRIES / NUM_BITS(uint32_t); i++) { - p_icusarg[i] = 0; - NVIC->ITNS[i] = 0; - } - - /* Enable protection using PRCR register. */ - R_BSP_RegisterProtectEnable(BSP_REG_PROTECT_SAR); -#endif - - SystemCoreClock = BSP_MOCO_HZ; - g_protect_pfswe_counter = 0; - -#ifdef CONFIG_RUNTIME_NMI - for (uint32_t i = 0; i < 16; i++) { - g_bsp_group_irq_sources[i] = 0; - } - - z_arm_nmi_set_handler(NMI_Handler); -#endif - - irq_unlock(key); -} diff --git a/soc/renesas/ra/ra6m5/soc.h b/soc/renesas/ra/ra6m5/soc.h deleted file mode 100644 index 2774723147c1..000000000000 --- a/soc/renesas/ra/ra6m5/soc.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2024 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file SoC configuration macros for the Renesas RA6M5 family MCU - */ - -#ifndef ZEPHYR_SOC_RENESAS_RA6M5_SOC_H_ -#define ZEPHYR_SOC_RENESAS_RA6M5_SOC_H_ - -#include - -#endif /* ZEPHYR_SOC_RENESAS_RA6M5_SOC_H_ */ diff --git a/soc/renesas/ra/ra8d1/CMakeLists.txt b/soc/renesas/ra/ra8d1/CMakeLists.txt index b0b66d221709..c1d1aea9a03e 100644 --- a/soc/renesas/ra/ra8d1/CMakeLists.txt +++ b/soc/renesas/ra/ra8d1/CMakeLists.txt @@ -3,10 +3,6 @@ zephyr_include_directories(.) -zephyr_sources( - soc.c -) - zephyr_sources_ifdef(CONFIG_PM power.c ) @@ -45,11 +41,6 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) dt_node_has_status(banksel_sel_status PATH ${option_setting_banksel_sel} STATUS okay) dt_node_has_status(bps_sel_status PATH ${option_setting_bps_sel} STATUS okay) - if(CONFIG_USE_RA_FSP_DTC) - zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) - zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") - endif() - if(${ofs0_status}) zephyr_linker_section(NAME .option_setting_ofs0 GROUP OFS_OFS0_MEMORY ADDRESS ${ofs0_addr}) zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") @@ -102,10 +93,7 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) elseif(CONFIG_LD_LINKER_TEMPLATE) zephyr_linker_sources(SECTIONS sections.ld) - zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) else() message(WARNING "Unsupported linker template.") endif() - -set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra8d1/Kconfig b/soc/renesas/ra/ra8d1/Kconfig index bf456b39ff11..ee5fd5ee7389 100644 --- a/soc/renesas/ra/ra8d1/Kconfig +++ b/soc/renesas/ra/ra8d1/Kconfig @@ -13,7 +13,6 @@ config SOC_SERIES_RA8D1 select XIP select CLOCK_CONTROL_RENESAS_RA_CGC if CLOCK_CONTROL select HAS_RENESAS_RA_FSP - select SOC_EARLY_INIT_HOOK select GPIO_RA_HAS_VBTICTLR select HAS_PM diff --git a/soc/renesas/ra/ra8d1/ram_sections.ld b/soc/renesas/ra/ra8d1/ram_sections.ld deleted file mode 100644 index 18be2a431de2..000000000000 --- a/soc/renesas/ra/ra8d1/ram_sections.ld +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -#ifdef CONFIG_USE_RA_FSP_DTC -SECTION_DATA_PROLOGUE(.fsp_dtc_vector_table,(NOLOAD),) -{ - /* If DTC is used, put the DTC vector table at the start of SRAM. - This avoids memory holes due to 1K alignment required by it. */ - *(.fsp_dtc_vector_table) -} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION) -#endif /* CONFIG_USE_RA_FSP_DTC */ diff --git a/soc/renesas/ra/ra8d1/soc.c b/soc/renesas/ra/ra8d1/soc.c deleted file mode 100644 index fea9ddd312e4..000000000000 --- a/soc/renesas/ra/ra8d1/soc.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (c) 2024 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief System/hardware module for Renesas RA8D1 family processor - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); - -#include - -#define CCR_CACHE_ENABLE (SCB_CCR_IC_Msk | SCB_CCR_BP_Msk | SCB_CCR_LOB_Msk) - -uint32_t SystemCoreClock BSP_SECTION_EARLY_INIT; - -volatile uint32_t g_protect_pfswe_counter BSP_SECTION_EARLY_INIT; - -#ifdef CONFIG_RUNTIME_NMI -extern bsp_grp_irq_cb_t g_bsp_group_irq_sources[]; -extern void NMI_Handler(void); -#endif /* CONFIG_RUNTIME_NMI */ - -/** - * @brief Perform basic hardware initialization at boot. - * - * This needs to be run from the very beginning. - */ -void soc_early_init_hook(void) -{ - SystemCoreClock = BSP_MOCO_HZ; - g_protect_pfswe_counter = 0; - -#ifdef CONFIG_ICACHE - SCB->CCR = (uint32_t)CCR_CACHE_ENABLE; - barrier_dsync_fence_full(); - barrier_isync_fence_full(); -#endif -#if defined(CONFIG_DCACHE) && defined(CONFIG_CACHE_MANAGEMENT) - /* Apply Arm Cortex-M85 errata workarounds for D-Cache - * Attributing all cacheable memory as write-through set FORCEWT bit in MSCR register. - * Set bit 16 in ACTLR to 1. - * See erratum 3175626 and 3190818 in the Cortex-M85 AT640 and Cortex-M85 with FPU AT641 - * Software Developer Errata Notice (Date of issue: March 07, 2024, Document version: 13.0, - * Document ID: SDEN-2236668). - */ - MEMSYSCTL->MSCR |= MEMSYSCTL_MSCR_FORCEWT_Msk; - barrier_dsync_fence_full(); - barrier_isync_fence_full(); - ICB->ACTLR |= (1U << 16U); - barrier_dsync_fence_full(); - barrier_isync_fence_full(); - - sys_cache_data_enable(); -#endif - -#ifdef CONFIG_RUNTIME_NMI - for (uint32_t i = 0; i < 16; i++) { - g_bsp_group_irq_sources[i] = 0; - } - - z_arm_nmi_set_handler(NMI_Handler); -#endif /* CONFIG_RUNTIME_NMI */ - - cold_start_handler(); -} diff --git a/soc/renesas/ra/ra8d1/soc.h b/soc/renesas/ra/ra8d1/soc.h deleted file mode 100644 index b878fe60a3ae..000000000000 --- a/soc/renesas/ra/ra8d1/soc.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (c) 2024-2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file SoC configuration macros for the Renesas RA8D1 family MCU - */ - -#ifndef ZEPHYR_SOC_RENESAS_RA8D1_SOC_H_ -#define ZEPHYR_SOC_RENESAS_RA8D1_SOC_H_ - -#include -#include - -#endif /* ZEPHYR_SOC_RENESAS_RA8D1_SOC_H_ */ diff --git a/soc/renesas/ra/ra8d2/CMakeLists.txt b/soc/renesas/ra/ra8d2/CMakeLists.txt index 2e8d68f94cd9..1542927b73be 100644 --- a/soc/renesas/ra/ra8d2/CMakeLists.txt +++ b/soc/renesas/ra/ra8d2/CMakeLists.txt @@ -3,20 +3,11 @@ zephyr_include_directories(.) -zephyr_sources( - soc.c -) - zephyr_sources_ifdef(CONFIG_PM power.c ) if(CONFIG_CMAKE_LINKER_GENERATOR) - if(CONFIG_USE_RA_FSP_DTC) - zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) - zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") - endif() - if((NOT CONFIG_BOOTLOADER_MCUBOOT) AND (NOT CONFIG_SOC_RA_SECOND_CORE_BUILD)) dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") dt_nodelabel(option_setting_ofs2 NODELABEL "option_setting_ofs2") @@ -98,10 +89,7 @@ elseif(CONFIG_LD_LINKER_TEMPLATE) if((NOT CONFIG_BOOTLOADER_MCUBOOT) AND (NOT CONFIG_SOC_RA_SECOND_CORE_BUILD)) zephyr_linker_sources(SECTIONS sections.ld) endif() - zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) else() message(WARNING "Unsupported linker template.") endif() - -set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra8d2/Kconfig b/soc/renesas/ra/ra8d2/Kconfig index 581d925133d8..5883dfefe522 100644 --- a/soc/renesas/ra/ra8d2/Kconfig +++ b/soc/renesas/ra/ra8d2/Kconfig @@ -13,7 +13,6 @@ config SOC_SERIES_RA8D2 select XIP select CLOCK_CONTROL_RENESAS_RA_CGC if CLOCK_CONTROL select HAS_RENESAS_RA_FSP - select SOC_EARLY_INIT_HOOK select HAS_PM config SOC_R7KA8D2KFLCAC_CM85 diff --git a/soc/renesas/ra/ra8d2/ram_sections.ld b/soc/renesas/ra/ra8d2/ram_sections.ld deleted file mode 100644 index 18be2a431de2..000000000000 --- a/soc/renesas/ra/ra8d2/ram_sections.ld +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -#ifdef CONFIG_USE_RA_FSP_DTC -SECTION_DATA_PROLOGUE(.fsp_dtc_vector_table,(NOLOAD),) -{ - /* If DTC is used, put the DTC vector table at the start of SRAM. - This avoids memory holes due to 1K alignment required by it. */ - *(.fsp_dtc_vector_table) -} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION) -#endif /* CONFIG_USE_RA_FSP_DTC */ diff --git a/soc/renesas/ra/ra8d2/soc.c b/soc/renesas/ra/ra8d2/soc.c deleted file mode 100644 index 497d94f0150b..000000000000 --- a/soc/renesas/ra/ra8d2/soc.c +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief System/hardware module for Renesas RA8P1 family processor - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); - -#include "soc.h" - -#define CCR_CACHE_ENABLE (SCB_CCR_IC_Msk | SCB_CCR_BP_Msk | SCB_CCR_LOB_Msk) - -uint32_t SystemCoreClock BSP_SECTION_EARLY_INIT; - -volatile uint32_t g_protect_pfswe_counter BSP_SECTION_EARLY_INIT; - -#ifdef CONFIG_RUNTIME_NMI -extern bsp_grp_irq_cb_t g_bsp_group_irq_sources[]; -extern void NMI_Handler(void); -#endif /* CONFIG_RUNTIME_NMI */ - -/** - * @brief Perform basic hardware initialization at boot. - * - * This needs to be run from the very beginning. - */ -void soc_early_init_hook(void) -{ - SystemCoreClock = BSP_MOCO_HZ; - g_protect_pfswe_counter = 0; - - extern volatile uint16_t g_protect_counters[]; - - for (uint32_t i = 0; i < 5; i++) { - g_protect_counters[i] = 0; - } - - SystemCoreClock = BSP_MOCO_HZ; - -#ifdef CONFIG_RUNTIME_NMI - for (uint32_t i = 0; i < 16; i++) { - g_bsp_group_irq_sources[i] = 0; - } - - z_arm_nmi_set_handler(NMI_Handler); -#endif /* CONFIG_RUNTIME_NMI */ - -#ifdef CONFIG_CPU_CORTEX_M85 -#ifdef CONFIG_ICACHE - SCB->CCR = (uint32_t)CCR_CACHE_ENABLE; - barrier_dsync_fence_full(); - barrier_isync_fence_full(); -#endif -#if defined(CONFIG_DCACHE) && defined(CONFIG_CACHE_MANAGEMENT) - /* Apply Arm Cortex-M85 errata workarounds for D-Cache - * Attributing all cacheable memory as write-through set FORCEWT bit in MSCR register. - * Set bit 16 in ACTLR to 1. - * See erratum 3175626 and 3190818 in the Cortex-M85 AT640 and Cortex-M85 with FPU AT641 - * Software Developer Errata Notice (Date of issue: March 07, 2024, Document version: 13.0, - * Document ID: SDEN-2236668). - */ - MEMSYSCTL->MSCR |= MEMSYSCTL_MSCR_FORCEWT_Msk; - barrier_dsync_fence_full(); - barrier_isync_fence_full(); - ICB->ACTLR |= (1U << 16U); - barrier_dsync_fence_full(); - barrier_isync_fence_full(); - - sys_cache_data_enable(); -#endif -#endif /*CONFIG_CPU_CORTEX_M85*/ - -#ifdef CONFIG_CPU_CORTEX_M33 -#if FSP_PRIV_TZ_USE_SECURE_REGS - /* Disable protection using PRCR register. */ - R_BSP_RegisterProtectDisable(BSP_REG_PROTECT_SAR); - - /* Initialize peripherals to secure mode for flat projects */ - R_PSCU->PSARB = 0; - R_PSCU->PSARC = 0; - R_PSCU->PSARD = 0; - R_PSCU->PSARE = 0; - - R_CPSCU->ICUSARG = 0; - R_CPSCU->ICUSARH = 0; - R_CPSCU->ICUSARI = 0; - - /* Enable protection using PRCR register. */ - R_BSP_RegisterProtectEnable(BSP_REG_PROTECT_SAR); -#endif -#endif /*CONFIG_CPU_CORTEX_M33*/ -} diff --git a/soc/renesas/ra/ra8m1/CMakeLists.txt b/soc/renesas/ra/ra8m1/CMakeLists.txt index 8550175d0e02..c4f9ce84c8ae 100644 --- a/soc/renesas/ra/ra8m1/CMakeLists.txt +++ b/soc/renesas/ra/ra8m1/CMakeLists.txt @@ -3,10 +3,6 @@ zephyr_include_directories(.) -zephyr_sources( - soc.c -) - zephyr_sources_ifdef(CONFIG_PM power.c ) @@ -45,11 +41,6 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) dt_node_has_status(banksel_sel_status PATH ${option_setting_banksel_sel} STATUS okay) dt_node_has_status(bps_sel_status PATH ${option_setting_bps_sel} STATUS okay) - if(CONFIG_USE_RA_FSP_DTC) - zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) - zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") - endif() - if(${ofs0_status}) zephyr_linker_section(NAME .option_setting_ofs0 GROUP OFS_OFS0_MEMORY ADDRESS ${ofs0_addr}) zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") @@ -102,10 +93,7 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) elseif(CONFIG_LD_LINKER_TEMPLATE) zephyr_linker_sources(SECTIONS sections.ld) - zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) else() message(WARNING "Unsupported linker template.") endif() - -set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra8m1/Kconfig b/soc/renesas/ra/ra8m1/Kconfig index 2b6813522a9d..32c46cba64e9 100644 --- a/soc/renesas/ra/ra8m1/Kconfig +++ b/soc/renesas/ra/ra8m1/Kconfig @@ -13,7 +13,6 @@ config SOC_SERIES_RA8M1 select XIP select CLOCK_CONTROL_RENESAS_RA_CGC if CLOCK_CONTROL select HAS_RENESAS_RA_FSP - select SOC_EARLY_INIT_HOOK select GPIO_RA_HAS_VBTICTLR select HAS_PM help diff --git a/soc/renesas/ra/ra8m1/ram_sections.ld b/soc/renesas/ra/ra8m1/ram_sections.ld deleted file mode 100644 index 18be2a431de2..000000000000 --- a/soc/renesas/ra/ra8m1/ram_sections.ld +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -#ifdef CONFIG_USE_RA_FSP_DTC -SECTION_DATA_PROLOGUE(.fsp_dtc_vector_table,(NOLOAD),) -{ - /* If DTC is used, put the DTC vector table at the start of SRAM. - This avoids memory holes due to 1K alignment required by it. */ - *(.fsp_dtc_vector_table) -} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION) -#endif /* CONFIG_USE_RA_FSP_DTC */ diff --git a/soc/renesas/ra/ra8m1/soc.c b/soc/renesas/ra/ra8m1/soc.c deleted file mode 100644 index 35bafdbdfafd..000000000000 --- a/soc/renesas/ra/ra8m1/soc.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2024 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief System/hardware module for Renesas RA8M1 family processor - */ - -#include -#include -#include -#include -#include -#include -#include -#include -LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); - -#include - -uint32_t SystemCoreClock BSP_SECTION_EARLY_INIT; - -volatile uint32_t g_protect_pfswe_counter BSP_SECTION_EARLY_INIT; - -#ifdef CONFIG_RUNTIME_NMI -extern bsp_grp_irq_cb_t g_bsp_group_irq_sources[]; -extern void NMI_Handler(void); -#endif /* CONFIG_RUNTIME_NMI */ - -/** - * @brief Perform basic hardware initialization at boot. - * - * This needs to be run from the very beginning. - */ -void soc_early_init_hook(void) -{ - SystemCoreClock = BSP_MOCO_HZ; - g_protect_pfswe_counter = 0; - -#ifdef CONFIG_RUNTIME_NMI - for (uint32_t i = 0; i < 16; i++) { - g_bsp_group_irq_sources[i] = 0; - } - - z_arm_nmi_set_handler(NMI_Handler); -#endif /* CONFIG_RUNTIME_NMI */ - - cold_start_handler(); -} diff --git a/soc/renesas/ra/ra8m1/soc.h b/soc/renesas/ra/ra8m1/soc.h deleted file mode 100644 index 1d817c563dc9..000000000000 --- a/soc/renesas/ra/ra8m1/soc.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (c) 2024-2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file SoC configuration macros for the Renesas RA8M1 family MCU - */ - -#ifndef ZEPHYR_SOC_RENESAS_RA8M1_SOC_H_ -#define ZEPHYR_SOC_RENESAS_RA8M1_SOC_H_ - -#include -#include - -#endif /* ZEPHYR_SOC_RENESAS_RA8M1_SOC_H_ */ diff --git a/soc/renesas/ra/ra8m2/CMakeLists.txt b/soc/renesas/ra/ra8m2/CMakeLists.txt index 2e8d68f94cd9..1542927b73be 100644 --- a/soc/renesas/ra/ra8m2/CMakeLists.txt +++ b/soc/renesas/ra/ra8m2/CMakeLists.txt @@ -3,20 +3,11 @@ zephyr_include_directories(.) -zephyr_sources( - soc.c -) - zephyr_sources_ifdef(CONFIG_PM power.c ) if(CONFIG_CMAKE_LINKER_GENERATOR) - if(CONFIG_USE_RA_FSP_DTC) - zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) - zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") - endif() - if((NOT CONFIG_BOOTLOADER_MCUBOOT) AND (NOT CONFIG_SOC_RA_SECOND_CORE_BUILD)) dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") dt_nodelabel(option_setting_ofs2 NODELABEL "option_setting_ofs2") @@ -98,10 +89,7 @@ elseif(CONFIG_LD_LINKER_TEMPLATE) if((NOT CONFIG_BOOTLOADER_MCUBOOT) AND (NOT CONFIG_SOC_RA_SECOND_CORE_BUILD)) zephyr_linker_sources(SECTIONS sections.ld) endif() - zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) else() message(WARNING "Unsupported linker template.") endif() - -set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra8m2/Kconfig b/soc/renesas/ra/ra8m2/Kconfig index 8a22472a6755..f98f8bed1fe0 100644 --- a/soc/renesas/ra/ra8m2/Kconfig +++ b/soc/renesas/ra/ra8m2/Kconfig @@ -13,7 +13,6 @@ config SOC_SERIES_RA8M2 select XIP select CLOCK_CONTROL_RENESAS_RA_CGC if CLOCK_CONTROL select HAS_RENESAS_RA_FSP - select SOC_EARLY_INIT_HOOK select HAS_PM config SOC_R7KA8M2JFLCAC_CM85 diff --git a/soc/renesas/ra/ra8m2/ram_sections.ld b/soc/renesas/ra/ra8m2/ram_sections.ld deleted file mode 100644 index 18be2a431de2..000000000000 --- a/soc/renesas/ra/ra8m2/ram_sections.ld +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -#ifdef CONFIG_USE_RA_FSP_DTC -SECTION_DATA_PROLOGUE(.fsp_dtc_vector_table,(NOLOAD),) -{ - /* If DTC is used, put the DTC vector table at the start of SRAM. - This avoids memory holes due to 1K alignment required by it. */ - *(.fsp_dtc_vector_table) -} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION) -#endif /* CONFIG_USE_RA_FSP_DTC */ diff --git a/soc/renesas/ra/ra8m2/soc.c b/soc/renesas/ra/ra8m2/soc.c deleted file mode 100644 index db67c004f9e3..000000000000 --- a/soc/renesas/ra/ra8m2/soc.c +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief System/hardware module for Renesas RA8M2 family processor - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); - -#include "soc.h" - -#define CCR_CACHE_ENABLE (SCB_CCR_IC_Msk | SCB_CCR_BP_Msk | SCB_CCR_LOB_Msk) - -uint32_t SystemCoreClock BSP_SECTION_EARLY_INIT; - -volatile uint32_t g_protect_pfswe_counter BSP_SECTION_EARLY_INIT; - -#ifdef CONFIG_RUNTIME_NMI -extern bsp_grp_irq_cb_t g_bsp_group_irq_sources[]; -extern void NMI_Handler(void); -#endif /* CONFIG_RUNTIME_NMI */ - -/** - * @brief Perform basic hardware initialization at boot. - * - * This needs to be run from the very beginning. - */ -void soc_early_init_hook(void) -{ - SystemCoreClock = BSP_MOCO_HZ; - g_protect_pfswe_counter = 0; - - extern volatile uint16_t g_protect_counters[]; - - for (uint32_t i = 0; i < 5; i++) { - g_protect_counters[i] = 0; - } - - SystemCoreClock = BSP_MOCO_HZ; - -#ifdef CONFIG_RUNTIME_NMI - for (uint32_t i = 0; i < 16; i++) { - g_bsp_group_irq_sources[i] = 0; - } - - z_arm_nmi_set_handler(NMI_Handler); -#endif /* CONFIG_RUNTIME_NMI */ - -#ifdef CONFIG_CPU_CORTEX_M85 -#ifdef CONFIG_ICACHE - SCB->CCR = (uint32_t)CCR_CACHE_ENABLE; - barrier_dsync_fence_full(); - barrier_isync_fence_full(); -#endif -#if defined(CONFIG_DCACHE) && defined(CONFIG_CACHE_MANAGEMENT) - /* Apply Arm Cortex-M85 errata workarounds for D-Cache - * Attributing all cacheable memory as write-through set FORCEWT bit in MSCR register. - * Set bit 16 in ACTLR to 1. - * See erratum 3175626 and 3190818 in the Cortex-M85 AT640 and Cortex-M85 with FPU AT641 - * Software Developer Errata Notice (Date of issue: March 07, 2024, Document version: 13.0, - * Document ID: SDEN-2236668). - */ - MEMSYSCTL->MSCR |= MEMSYSCTL_MSCR_FORCEWT_Msk; - barrier_dsync_fence_full(); - barrier_isync_fence_full(); - ICB->ACTLR |= (1U << 16U); - barrier_dsync_fence_full(); - barrier_isync_fence_full(); - - sys_cache_data_enable(); -#endif -#endif /*CONFIG_CPU_CORTEX_M85*/ - -#ifdef CONFIG_CPU_CORTEX_M33 -#if FSP_PRIV_TZ_USE_SECURE_REGS - /* Disable protection using PRCR register. */ - R_BSP_RegisterProtectDisable(BSP_REG_PROTECT_SAR); - - /* Initialize peripherals to secure mode for flat projects */ - R_PSCU->PSARB = 0; - R_PSCU->PSARC = 0; - R_PSCU->PSARD = 0; - R_PSCU->PSARE = 0; - - R_CPSCU->ICUSARG = 0; - R_CPSCU->ICUSARH = 0; - R_CPSCU->ICUSARI = 0; - - /* Enable protection using PRCR register. */ - R_BSP_RegisterProtectEnable(BSP_REG_PROTECT_SAR); -#endif -#endif /*CONFIG_CPU_CORTEX_M33*/ -} diff --git a/soc/renesas/ra/ra8m2/soc.h b/soc/renesas/ra/ra8m2/soc.h deleted file mode 100644 index a494b8509f69..000000000000 --- a/soc/renesas/ra/ra8m2/soc.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file SoC configuration macros for the Renesas RA8M2 family MCU - */ - -#ifndef ZEPHYR_SOC_RENESAS_RA8M2_SOC_H_ -#define ZEPHYR_SOC_RENESAS_RA8M2_SOC_H_ - -#include - -#endif /* ZEPHYR_SOC_RENESAS_RA8M2_SOC_H_ */ diff --git a/soc/renesas/ra/ra8p1/CMakeLists.txt b/soc/renesas/ra/ra8p1/CMakeLists.txt index 2e8d68f94cd9..0a65a484afac 100644 --- a/soc/renesas/ra/ra8p1/CMakeLists.txt +++ b/soc/renesas/ra/ra8p1/CMakeLists.txt @@ -3,20 +3,11 @@ zephyr_include_directories(.) -zephyr_sources( - soc.c -) - zephyr_sources_ifdef(CONFIG_PM power.c ) if(CONFIG_CMAKE_LINKER_GENERATOR) - if(CONFIG_USE_RA_FSP_DTC) - zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) - zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") - endif() - if((NOT CONFIG_BOOTLOADER_MCUBOOT) AND (NOT CONFIG_SOC_RA_SECOND_CORE_BUILD)) dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") dt_nodelabel(option_setting_ofs2 NODELABEL "option_setting_ofs2") @@ -98,7 +89,6 @@ elseif(CONFIG_LD_LINKER_TEMPLATE) if((NOT CONFIG_BOOTLOADER_MCUBOOT) AND (NOT CONFIG_SOC_RA_SECOND_CORE_BUILD)) zephyr_linker_sources(SECTIONS sections.ld) endif() - zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) else() message(WARNING "Unsupported linker template.") diff --git a/soc/renesas/ra/ra8p1/Kconfig b/soc/renesas/ra/ra8p1/Kconfig index 9ecd8df9ab95..1e2f7a503c70 100644 --- a/soc/renesas/ra/ra8p1/Kconfig +++ b/soc/renesas/ra/ra8p1/Kconfig @@ -14,7 +14,6 @@ config SOC_SERIES_RA8P1 select XIP select CLOCK_CONTROL_RENESAS_RA_CGC if CLOCK_CONTROL select HAS_RENESAS_RA_FSP - select SOC_EARLY_INIT_HOOK select HAS_PM config SOC_R7KA8P1KFLCAC_CM85 diff --git a/soc/renesas/ra/ra8p1/ram_sections.ld b/soc/renesas/ra/ra8p1/ram_sections.ld deleted file mode 100644 index 18be2a431de2..000000000000 --- a/soc/renesas/ra/ra8p1/ram_sections.ld +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -#ifdef CONFIG_USE_RA_FSP_DTC -SECTION_DATA_PROLOGUE(.fsp_dtc_vector_table,(NOLOAD),) -{ - /* If DTC is used, put the DTC vector table at the start of SRAM. - This avoids memory holes due to 1K alignment required by it. */ - *(.fsp_dtc_vector_table) -} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION) -#endif /* CONFIG_USE_RA_FSP_DTC */ diff --git a/soc/renesas/ra/ra8p1/soc.c b/soc/renesas/ra/ra8p1/soc.c deleted file mode 100644 index d0589daba0e4..000000000000 --- a/soc/renesas/ra/ra8p1/soc.c +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief System/hardware module for Renesas RA8P1 family processor - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); - -#include - -#define CCR_CACHE_ENABLE (SCB_CCR_IC_Msk | SCB_CCR_BP_Msk | SCB_CCR_LOB_Msk) - -uint32_t SystemCoreClock BSP_SECTION_EARLY_INIT; - -volatile uint32_t g_protect_pfswe_counter BSP_SECTION_EARLY_INIT; - -#ifdef CONFIG_RUNTIME_NMI -extern bsp_grp_irq_cb_t g_bsp_group_irq_sources[]; -extern void NMI_Handler(void); -#endif /* CONFIG_RUNTIME_NMI */ - -extern void cold_start_handler(void); - -/** - * @brief Perform basic hardware initialization at boot. - * - * This needs to be run from the very beginning. - */ -void soc_early_init_hook(void) -{ - SystemCoreClock = BSP_MOCO_HZ; - g_protect_pfswe_counter = 0; - - extern volatile uint16_t g_protect_counters[]; - - for (uint32_t i = 0; i < 5; i++) { - g_protect_counters[i] = 0; - } - - SystemCoreClock = BSP_MOCO_HZ; - -#ifdef CONFIG_CPU_CORTEX_M85 -#ifdef CONFIG_ICACHE - SCB->CCR = (uint32_t)CCR_CACHE_ENABLE; - barrier_dsync_fence_full(); - barrier_isync_fence_full(); -#endif -#if defined(CONFIG_DCACHE) && defined(CONFIG_CACHE_MANAGEMENT) - /* Apply Arm Cortex-M85 errata workarounds for D-Cache - * Attributing all cacheable memory as write-through set FORCEWT bit in MSCR register. - * Set bit 16 in ACTLR to 1. - * See erratum 3175626 and 3190818 in the Cortex-M85 AT640 and Cortex-M85 with FPU AT641 - * Software Developer Errata Notice (Date of issue: March 07, 2024, Document version: 13.0, - * Document ID: SDEN-2236668). - */ - MEMSYSCTL->MSCR |= MEMSYSCTL_MSCR_FORCEWT_Msk; - barrier_dsync_fence_full(); - barrier_isync_fence_full(); - ICB->ACTLR |= (1U << 16U); - barrier_dsync_fence_full(); - barrier_isync_fence_full(); - - sys_cache_data_enable(); -#endif - -#endif /*CONFIG_CPU_CORTEX_M85*/ - -#ifdef CONFIG_CPU_CORTEX_M33 -#if FSP_PRIV_TZ_USE_SECURE_REGS - /* Disable protection using PRCR register. */ - R_BSP_RegisterProtectDisable(BSP_REG_PROTECT_SAR); - - /* Initialize peripherals to secure mode for flat projects */ - R_PSCU->PSARB = 0; - R_PSCU->PSARC = 0; - R_PSCU->PSARD = 0; - R_PSCU->PSARE = 0; - - R_CPSCU->ICUSARG = 0; - R_CPSCU->ICUSARH = 0; - R_CPSCU->ICUSARI = 0; - - /* Enable protection using PRCR register. */ - R_BSP_RegisterProtectEnable(BSP_REG_PROTECT_SAR); -#endif -#endif /*CONFIG_CPU_CORTEX_M33*/ -#ifdef CONFIG_RUNTIME_NMI - for (uint32_t i = 0; i < 16; i++) { - g_bsp_group_irq_sources[i] = 0; - } - - z_arm_nmi_set_handler(NMI_Handler); -#endif /* CONFIG_RUNTIME_NMI */ - - cold_start_handler(); -} - -#ifdef CONFIG_SOC_LATE_INIT_HOOK -void soc_late_init_hook(void) -{ -#ifdef CONFIG_SOC_RA_ENABLE_START_SECOND_CORE - R_BSP_SecondaryCoreStart(); -#endif /* CONFIG_SOC_RA_ENABLE_START_SECOND_CORE */ -} -#endif /* CONFIG_SOC_LATE_INIT_HOOK */ diff --git a/soc/renesas/ra/ra8p1/soc.h b/soc/renesas/ra/ra8p1/soc.h deleted file mode 100644 index 56172f7de5a0..000000000000 --- a/soc/renesas/ra/ra8p1/soc.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file SoC configuration macros for the Renesas RA8P1 family MCU - */ - -#ifndef ZEPHYR_SOC_RENESAS_RA8P1_SOC_H_ -#define ZEPHYR_SOC_RENESAS_RA8P1_SOC_H_ - -#include -#include - -#endif /* ZEPHYR_SOC_RENESAS_RA8P1_SOC_H_ */ diff --git a/soc/renesas/ra/ra8t1/CMakeLists.txt b/soc/renesas/ra/ra8t1/CMakeLists.txt index 8550175d0e02..c4f9ce84c8ae 100644 --- a/soc/renesas/ra/ra8t1/CMakeLists.txt +++ b/soc/renesas/ra/ra8t1/CMakeLists.txt @@ -3,10 +3,6 @@ zephyr_include_directories(.) -zephyr_sources( - soc.c -) - zephyr_sources_ifdef(CONFIG_PM power.c ) @@ -45,11 +41,6 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) dt_node_has_status(banksel_sel_status PATH ${option_setting_banksel_sel} STATUS okay) dt_node_has_status(bps_sel_status PATH ${option_setting_bps_sel} STATUS okay) - if(CONFIG_USE_RA_FSP_DTC) - zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) - zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") - endif() - if(${ofs0_status}) zephyr_linker_section(NAME .option_setting_ofs0 GROUP OFS_OFS0_MEMORY ADDRESS ${ofs0_addr}) zephyr_linker_section_configure(SECTION .option_setting_ofs0 KEEP INPUT ".option_setting_ofs0*") @@ -102,10 +93,7 @@ if(CONFIG_CMAKE_LINKER_GENERATOR) elseif(CONFIG_LD_LINKER_TEMPLATE) zephyr_linker_sources(SECTIONS sections.ld) - zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) else() message(WARNING "Unsupported linker template.") endif() - -set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra8t1/Kconfig b/soc/renesas/ra/ra8t1/Kconfig index ba1825598171..d84b81bf8172 100644 --- a/soc/renesas/ra/ra8t1/Kconfig +++ b/soc/renesas/ra/ra8t1/Kconfig @@ -13,7 +13,6 @@ config SOC_SERIES_RA8T1 select XIP select CLOCK_CONTROL_RENESAS_RA_CGC if CLOCK_CONTROL select HAS_RENESAS_RA_FSP - select SOC_EARLY_INIT_HOOK select GPIO_RA_HAS_VBTICTLR select HAS_PM diff --git a/soc/renesas/ra/ra8t1/ram_sections.ld b/soc/renesas/ra/ra8t1/ram_sections.ld deleted file mode 100644 index 18be2a431de2..000000000000 --- a/soc/renesas/ra/ra8t1/ram_sections.ld +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -#ifdef CONFIG_USE_RA_FSP_DTC -SECTION_DATA_PROLOGUE(.fsp_dtc_vector_table,(NOLOAD),) -{ - /* If DTC is used, put the DTC vector table at the start of SRAM. - This avoids memory holes due to 1K alignment required by it. */ - *(.fsp_dtc_vector_table) -} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION) -#endif /* CONFIG_USE_RA_FSP_DTC */ diff --git a/soc/renesas/ra/ra8t1/soc.c b/soc/renesas/ra/ra8t1/soc.c deleted file mode 100644 index 3c02a1cae0bb..000000000000 --- a/soc/renesas/ra/ra8t1/soc.c +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2024 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief System/hardware module for Renesas RA8T1 family processor - */ - -#include -#include -#include -#include -#include -#include -#include -#include -LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); - -#include - -uint32_t SystemCoreClock BSP_SECTION_EARLY_INIT; - -volatile uint32_t g_protect_pfswe_counter BSP_SECTION_EARLY_INIT; - -#ifdef CONFIG_RUNTIME_NMI -extern bsp_grp_irq_cb_t g_bsp_group_irq_sources[]; -extern void NMI_Handler(void); -#endif /* CONFIG_RUNTIME_NMI */ - -/** - * @brief Perform basic hardware initialization at boot. - * - * This needs to be run from the very beginning. - */ -void soc_early_init_hook(void) -{ - SystemCoreClock = BSP_MOCO_HZ; - g_protect_pfswe_counter = 0; - -#ifdef CONFIG_RUNTIME_NMI - for (uint32_t i = 0; i < 16; i++) { - g_bsp_group_irq_sources[i] = 0; - } - - z_arm_nmi_set_handler(NMI_Handler); -#endif /* CONFIG_RUNTIME_NMI */ -} diff --git a/soc/renesas/ra/ra8t1/soc.h b/soc/renesas/ra/ra8t1/soc.h deleted file mode 100644 index 3160d3eb80bc..000000000000 --- a/soc/renesas/ra/ra8t1/soc.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2024 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file SoC configuration macros for the Renesas RA8T1 family MCU - */ - -#ifndef ZEPHYR_SOC_RENESAS_RA8T1_SOC_H_ -#define ZEPHYR_SOC_RENESAS_RA8T1_SOC_H_ - -#include - -#endif /* ZEPHYR_SOC_RENESAS_RA8T1_SOC_H_ */ diff --git a/soc/renesas/ra/ra8t2/CMakeLists.txt b/soc/renesas/ra/ra8t2/CMakeLists.txt index 2e8d68f94cd9..1542927b73be 100644 --- a/soc/renesas/ra/ra8t2/CMakeLists.txt +++ b/soc/renesas/ra/ra8t2/CMakeLists.txt @@ -3,20 +3,11 @@ zephyr_include_directories(.) -zephyr_sources( - soc.c -) - zephyr_sources_ifdef(CONFIG_PM power.c ) if(CONFIG_CMAKE_LINKER_GENERATOR) - if(CONFIG_USE_RA_FSP_DTC) - zephyr_linker_section(NAME .fsp_dtc_vector_table GROUP RAM) - zephyr_linker_section_configure(SECTION .fsp_dtc_vector_table KEEP INPUT ".fsp_dtc_vector_table*") - endif() - if((NOT CONFIG_BOOTLOADER_MCUBOOT) AND (NOT CONFIG_SOC_RA_SECOND_CORE_BUILD)) dt_nodelabel(option_setting_ofs0 NODELABEL "option_setting_ofs0") dt_nodelabel(option_setting_ofs2 NODELABEL "option_setting_ofs2") @@ -98,10 +89,7 @@ elseif(CONFIG_LD_LINKER_TEMPLATE) if((NOT CONFIG_BOOTLOADER_MCUBOOT) AND (NOT CONFIG_SOC_RA_SECOND_CORE_BUILD)) zephyr_linker_sources(SECTIONS sections.ld) endif() - zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) else() message(WARNING "Unsupported linker template.") endif() - -set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/ra/ra8t2/Kconfig b/soc/renesas/ra/ra8t2/Kconfig index ae5d44d29a1a..af68f3e14b28 100644 --- a/soc/renesas/ra/ra8t2/Kconfig +++ b/soc/renesas/ra/ra8t2/Kconfig @@ -13,7 +13,6 @@ config SOC_SERIES_RA8T2 select XIP select CLOCK_CONTROL_RENESAS_RA_CGC if CLOCK_CONTROL select HAS_RENESAS_RA_FSP - select SOC_EARLY_INIT_HOOK select HAS_PM config SOC_R7KA8T2LFLCAC_CM85 diff --git a/soc/renesas/ra/ra8t2/ram_sections.ld b/soc/renesas/ra/ra8t2/ram_sections.ld deleted file mode 100644 index 18be2a431de2..000000000000 --- a/soc/renesas/ra/ra8t2/ram_sections.ld +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -#ifdef CONFIG_USE_RA_FSP_DTC -SECTION_DATA_PROLOGUE(.fsp_dtc_vector_table,(NOLOAD),) -{ - /* If DTC is used, put the DTC vector table at the start of SRAM. - This avoids memory holes due to 1K alignment required by it. */ - *(.fsp_dtc_vector_table) -} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION) -#endif /* CONFIG_USE_RA_FSP_DTC */ diff --git a/soc/renesas/ra/ra8t2/soc.c b/soc/renesas/ra/ra8t2/soc.c deleted file mode 100644 index bff383e9585d..000000000000 --- a/soc/renesas/ra/ra8t2/soc.c +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief System/hardware module for Renesas RA8T2 family processor - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); - -#include "soc.h" - -#define CCR_CACHE_ENABLE (SCB_CCR_IC_Msk | SCB_CCR_BP_Msk | SCB_CCR_LOB_Msk) - -uint32_t SystemCoreClock BSP_SECTION_EARLY_INIT; - -volatile uint32_t g_protect_pfswe_counter BSP_SECTION_EARLY_INIT; - -/** - * @brief Perform basic hardware initialization at boot. - * - * This needs to be run from the very beginning. - */ -void soc_early_init_hook(void) -{ - SystemCoreClock = BSP_MOCO_HZ; - g_protect_pfswe_counter = 0; - - extern volatile uint16_t g_protect_counters[]; - - for (uint32_t i = 0; i < 5; i++) { - g_protect_counters[i] = 0; - } - - SystemCoreClock = BSP_MOCO_HZ; - -#ifdef CONFIG_CPU_CORTEX_M85 -#ifdef CONFIG_ICACHE - SCB->CCR = (uint32_t)CCR_CACHE_ENABLE; - barrier_dsync_fence_full(); - barrier_isync_fence_full(); -#endif -#if defined(CONFIG_DCACHE) && defined(CONFIG_CACHE_MANAGEMENT) - /* Apply Arm Cortex-M85 errata workarounds for D-Cache - * Attributing all cacheable memory as write-through set FORCEWT bit in MSCR register. - * Set bit 16 in ACTLR to 1. - * See erratum 3175626 and 3190818 in the Cortex-M85 AT640 and Cortex-M85 with FPU AT641 - * Software Developer Errata Notice (Date of issue: March 07, 2024, Document version: 13.0, - * Document ID: SDEN-2236668). - */ - MEMSYSCTL->MSCR |= MEMSYSCTL_MSCR_FORCEWT_Msk; - barrier_dsync_fence_full(); - barrier_isync_fence_full(); - ICB->ACTLR |= (1U << 16U); - barrier_dsync_fence_full(); - barrier_isync_fence_full(); - - sys_cache_data_enable(); -#endif -#endif /*CONFIG_CPU_CORTEX_M85*/ - -#ifdef CONFIG_CPU_CORTEX_M33 -#if FSP_PRIV_TZ_USE_SECURE_REGS - /* Disable protection using PRCR register. */ - R_BSP_RegisterProtectDisable(BSP_REG_PROTECT_SAR); - - /* Initialize peripherals to secure mode for flat projects */ - R_PSCU->PSARB = 0; - R_PSCU->PSARC = 0; - R_PSCU->PSARD = 0; - R_PSCU->PSARE = 0; - - R_CPSCU->ICUSARG = 0; - R_CPSCU->ICUSARH = 0; - R_CPSCU->ICUSARI = 0; - - /* Enable protection using PRCR register. */ - R_BSP_RegisterProtectEnable(BSP_REG_PROTECT_SAR); -#endif -#endif /*CONFIG_CPU_CORTEX_M33*/ -} diff --git a/soc/renesas/ra/ra8t2/soc.h b/soc/renesas/ra/ra8t2/soc.h deleted file mode 100644 index 86e5781b6a15..000000000000 --- a/soc/renesas/ra/ra8t2/soc.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2025 Renesas Electronics Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file SoC configuration macros for the Renesas RA8P1 family MCU - */ - -#ifndef ZEPHYR_SOC_RENESAS_RA8T2_SOC_H_ -#define ZEPHYR_SOC_RENESAS_RA8T2_SOC_H_ - -#include - -#endif /* ZEPHYR_SOC_RENESAS_RA8T2_SOC_H_ */ From d8c1333295f9913d7361f71d55e4a3b3c4a75eea Mon Sep 17 00:00:00 2001 From: Khoa Tran Date: Thu, 27 Nov 2025 13:55:45 +0700 Subject: [PATCH 2424/3659] boards: renesas: Disable sub-clock for boards lacking a crystal This commit disables the sub-clock node for boards without a populated onboard crystal. Signed-off-by: Khoa Tran --- boards/renesas/ek_ra4w1/ek_ra4w1.dts | 4 ---- boards/renesas/fpb_ra6e1/fpb_ra6e1.dts | 4 ---- boards/renesas/mck_ra8t1/mck_ra8t1.dts | 4 ---- boards/renesas/mck_ra8t2/mck_ra8t2.dtsi | 4 ---- 4 files changed, 16 deletions(-) diff --git a/boards/renesas/ek_ra4w1/ek_ra4w1.dts b/boards/renesas/ek_ra4w1/ek_ra4w1.dts index 856d0e983dfc..9b3d6cff463b 100644 --- a/boards/renesas/ek_ra4w1/ek_ra4w1.dts +++ b/boards/renesas/ek_ra4w1/ek_ra4w1.dts @@ -56,10 +56,6 @@ }; }; -&subclk { - status = "okay"; -}; - &sci0 { pinctrl-0 = <&sci0_default>; pinctrl-names = "default"; diff --git a/boards/renesas/fpb_ra6e1/fpb_ra6e1.dts b/boards/renesas/fpb_ra6e1/fpb_ra6e1.dts index 61a1bc73235c..9e28a6925ff0 100644 --- a/boards/renesas/fpb_ra6e1/fpb_ra6e1.dts +++ b/boards/renesas/fpb_ra6e1/fpb_ra6e1.dts @@ -93,10 +93,6 @@ status = "okay"; }; -&subclk { - status = "okay"; -}; - &pll { clocks = <&hoco>; div = <2>; diff --git a/boards/renesas/mck_ra8t1/mck_ra8t1.dts b/boards/renesas/mck_ra8t1/mck_ra8t1.dts index 90528485d355..f3a1bb84f21a 100644 --- a/boards/renesas/mck_ra8t1/mck_ra8t1.dts +++ b/boards/renesas/mck_ra8t1/mck_ra8t1.dts @@ -63,10 +63,6 @@ status = "okay"; }; -&subclk { - status = "okay"; -}; - &pll { status = "okay"; diff --git a/boards/renesas/mck_ra8t2/mck_ra8t2.dtsi b/boards/renesas/mck_ra8t2/mck_ra8t2.dtsi index 31a12eac7840..161dbe0d6546 100644 --- a/boards/renesas/mck_ra8t2/mck_ra8t2.dtsi +++ b/boards/renesas/mck_ra8t2/mck_ra8t2.dtsi @@ -51,10 +51,6 @@ status = "okay"; }; -&subclk { - status = "okay"; -}; - &pll { status = "okay"; From cb47fb2706f1c9676704d6adb6cd671cac00d754 Mon Sep 17 00:00:00 2001 From: The Nguyen Date: Thu, 18 Sep 2025 18:28:37 +0000 Subject: [PATCH 2425/3659] drivers: clock_control: remove clock early init for Renesas RA Remove the root clock control early initialization because it has already been done in the soc_reset_hooks() Signed-off-by: The Nguyen --- .../clock_control_renesas_ra_cgc.c | 30 ++----------------- soc/renesas/ra/Kconfig | 8 ----- 2 files changed, 2 insertions(+), 36 deletions(-) diff --git a/drivers/clock_control/clock_control_renesas_ra_cgc.c b/drivers/clock_control/clock_control_renesas_ra_cgc.c index 878b32232fe2..4b62bcc52fc5 100644 --- a/drivers/clock_control/clock_control_renesas_ra_cgc.c +++ b/drivers/clock_control/clock_control_renesas_ra_cgc.c @@ -91,29 +91,6 @@ static int clock_control_renesas_ra_get_rate(const struct device *dev, clock_con return 0; } -/** - * @brief Initializes a peripheral clock device driver - */ -static int clock_control_ra_init_pclk(const struct device *dev) -{ - ARG_UNUSED(dev); - - return 0; -} - -static int clock_control_ra_init(const struct device *dev) -{ - ARG_UNUSED(dev); - /* Call to HAL layer to initialize system clock and peripheral clock */ -#ifdef CONFIG_SOC_RA_SKIP_CLOCK_INIT - bsp_clock_freq_var_init(); - SystemCoreClockUpdate(); -#else - bsp_clock_init(); -#endif /* CONFIG_SOC_RA_SKIP_CLOCK_INIT */ - return 0; -} - static DEVICE_API(clock_control, clock_control_renesas_ra_api) = { .on = clock_control_renesas_ra_on, .off = clock_control_renesas_ra_off, @@ -127,13 +104,10 @@ static DEVICE_API(clock_control, clock_control_renesas_ra_api) = { DT_NODE_HAS_PROP(node_id, clocks), \ (RA_CGC_CLK_SRC(DT_CLOCKS_CTLR(node_id))), \ (RA_CGC_CLK_SRC(DT_CLOCKS_CTLR(DT_PARENT(node_id))))), \ - .clk_div = DT_PROP(node_id, div)}; \ - DEVICE_DT_DEFINE(node_id, &clock_control_ra_init_pclk, NULL, NULL, \ + .clk_div = DT_PROP(node_id, div)}; \ + DEVICE_DT_DEFINE(node_id, NULL, NULL, NULL, \ &node_id##_cfg, PRE_KERNEL_1, \ CONFIG_KERNEL_INIT_PRIORITY_OBJECTS, \ &clock_control_renesas_ra_api))); -DEVICE_DT_DEFINE(DT_NODELABEL(pclkblock), &clock_control_ra_init, NULL, NULL, NULL, PRE_KERNEL_1, - CONFIG_KERNEL_INIT_PRIORITY_OBJECTS, NULL); - DT_FOREACH_CHILD_STATUS_OKAY(DT_NODELABEL(pclkblock), INIT_PCLK); diff --git a/soc/renesas/ra/Kconfig b/soc/renesas/ra/Kconfig index 9f571d9f66fc..574e1db8c853 100644 --- a/soc/renesas/ra/Kconfig +++ b/soc/renesas/ra/Kconfig @@ -38,14 +38,6 @@ config SOC_RA_SECOND_CORE_BUILD help Indicates the image is built for the secondary core when enabled -config SOC_RA_SKIP_CLOCK_INIT - bool "Skip clock frequency configuration in system initialization" - depends on SOC_RA_SECOND_CORE_BUILD - default y - help - With this option, the CPU clock frequency is not set during system - initialization. - config RENESAS_RA_BATTERY_BACKUP_MANUAL_CONFIGURE bool "VBAT switching manual" default y From 0a37e1f43fc8433077a7b6ed6632022ae0c927dd Mon Sep 17 00:00:00 2001 From: Khoa Tran Date: Fri, 24 Oct 2025 09:23:26 +0700 Subject: [PATCH 2426/3659] drivers: display: update GLCDC device init flow Remove power domain on for GLCDC controller inside driver code due to it has already been done by soc_reset_hooks() Signed-off-by: Khoa Tran Signed-off-by: The Nguyen --- drivers/display/display_renesas_ra.c | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/drivers/display/display_renesas_ra.c b/drivers/display/display_renesas_ra.c index 98a79b09b6e3..39bf4085e4a7 100644 --- a/drivers/display/display_renesas_ra.c +++ b/drivers/display/display_renesas_ra.c @@ -368,20 +368,6 @@ static int display_init(const struct device *dev) struct display_ra_data *data = dev->data; int err; -#if BSP_FEATURE_BSP_HAS_GRAPHICS_DOMAIN - - R_BSP_RegisterProtectDisable(BSP_REG_PROTECT_OM_LPC_BATT); - FSP_HARDWARE_REGISTER_WAIT( - (R_SYSTEM->PDCTRGD & (R_SYSTEM_PDCTRGD_PDCSF_Msk | R_SYSTEM_PDCTRGD_PDPGSF_Msk)), - R_SYSTEM_PDCTRGD_PDPGSF_Msk); - R_SYSTEM->PDCTRGD = 0; - FSP_HARDWARE_REGISTER_WAIT( - (R_SYSTEM->PDCTRGD & (R_SYSTEM_PDCTRGD_PDCSF_Msk | R_SYSTEM_PDCTRGD_PDPGSF_Msk)), - 0); - R_BSP_RegisterProtectEnable(BSP_REG_PROTECT_OM_LPC_BATT); - -#endif - if (config->pincfg != NULL) { err = pinctrl_apply_state(config->pincfg, PINCTRL_STATE_DEFAULT); if (err) { From caf40f2581d8051d20e3227ae5721a97e48f5121 Mon Sep 17 00:00:00 2001 From: Khoa Tran Date: Wed, 29 Oct 2025 12:55:23 +0700 Subject: [PATCH 2427/3659] drivers: misc: update Renesas RA ethos_u init flow Remove the NPU power domain enabling inside ethos_u code due to it has already been done by soc_reset_hooks() Signed-off-by: Khoa Tran Signed-off-by: The Nguyen --- drivers/misc/ethos_u/ethos_u_renesas.c | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/drivers/misc/ethos_u/ethos_u_renesas.c b/drivers/misc/ethos_u/ethos_u_renesas.c index c57efc4280e4..b07819462603 100644 --- a/drivers/misc/ethos_u/ethos_u_renesas.c +++ b/drivers/misc/ethos_u/ethos_u_renesas.c @@ -55,21 +55,6 @@ static int ethos_u_renesas_ra_init(const struct device *dev) return err; } - if ((((0 == R_SYSTEM->PGCSAR_b.NONSEC2) && FSP_PRIV_TZ_USE_SECURE_REGS) || - ((1 == R_SYSTEM->PGCSAR_b.NONSEC2) && BSP_TZ_NONSECURE_BUILD)) && - (0 != R_SYSTEM->PDCTRNPU)) { - /* Turn on NPU power domain */ - R_BSP_RegisterProtectDisable(BSP_REG_PROTECT_OM_LPC_BATT); - FSP_HARDWARE_REGISTER_WAIT((R_SYSTEM->PDCTRNPU & (R_SYSTEM_PDCTRNPU_PDCSF_Msk | - R_SYSTEM_PDCTRGD_PDPGSF_Msk)), - R_SYSTEM_PDCTRGD_PDPGSF_Msk); - R_SYSTEM->PDCTRNPU = 0; - FSP_HARDWARE_REGISTER_WAIT((R_SYSTEM->PDCTRNPU & (R_SYSTEM_PDCTRNPU_PDCSF_Msk | - R_SYSTEM_PDCTRGD_PDPGSF_Msk)), - 0); - R_BSP_RegisterProtectEnable(BSP_REG_PROTECT_OM_LPC_BATT); - } - LOG_DBG("Ethos-U DTS info. base_address=0x%p, secure_enable=%u, privilege_enable=%u", ethosu_dts_info.base_addr, ethosu_dts_info.secure_enable, ethosu_dts_info.privilege_enable); From ca8e82532a34054fe73fb6d19511125144de044f Mon Sep 17 00:00:00 2001 From: Khoa Tran Date: Wed, 29 Oct 2025 12:50:52 +0700 Subject: [PATCH 2428/3659] drivers: rtc: Add update to use with new battery backup inplementation Update Renesas RTC driver to use with the new battery backup inplementation Signed-off-by: Khoa Tran --- drivers/rtc/rtc_renesas_ra.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/rtc/rtc_renesas_ra.c b/drivers/rtc/rtc_renesas_ra.c index 8993949630b3..e4a1ec0486a7 100644 --- a/drivers/rtc/rtc_renesas_ra.c +++ b/drivers/rtc/rtc_renesas_ra.c @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include #include @@ -156,11 +156,11 @@ static int rtc_renesas_ra_init(const struct device *dev) } #if defined(CONFIG_RENESAS_RA_BATTERY_BACKUP_MANUAL_CONFIGURE) - if (is_backup_domain_reset_happen()) { + if (R_BSP_ResetStatusGet() & BSP_RESET_TYPE_VBATPOR) { R_RTC_ClockSourceSet(&data->fsp_ctrl); } #else - if (is_power_on_reset_happen()) { + if (R_BSP_ResetStatusGet() & BSP_RESET_TYPE_POR) { R_RTC_ClockSourceSet(&data->fsp_ctrl); } #endif /* CONFIG_RENESAS_RA_BATTERY_BACKUP_MANUAL_CONFIGURE */ From 77d603a5e00abeb1a3249c9612bd77bb78ae651f Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Fri, 9 Jan 2026 15:38:13 +0100 Subject: [PATCH 2429/3659] storage: flash_map: remove legacy Mbed TLS crypto for integrity check Remove Kconfig and code related to legacy Mbed TLS crypto for SHA-256. This was used for the integrity check functionality as alternative to PSA Crypto API. This support was already deprecated and now it's removed in order to prepare for the next Mbed TLS 4.0 release where legacy crypto won't be available anymore. Signed-off-by: Valerio Setti --- subsys/storage/flash_map/Kconfig | 27 +---------- .../storage/flash_map/flash_map_integrity.c | 47 +++---------------- 2 files changed, 8 insertions(+), 66 deletions(-) diff --git a/subsys/storage/flash_map/Kconfig b/subsys/storage/flash_map/Kconfig index 83d2f2713695..cc18b5d0f353 100644 --- a/subsys/storage/flash_map/Kconfig +++ b/subsys/storage/flash_map/Kconfig @@ -31,6 +31,8 @@ config FLASH_MAP_CUSTOM config FLASH_AREA_CHECK_INTEGRITY bool "Flash check functions" + select PSA_CRYPTO + select PSA_WANT_ALG_SHA_256 help If enabled, there will be available the backend to check flash integrity using SHA-256 verification algorithm. @@ -42,29 +44,4 @@ config FLASH_MAP_LABELS at runtime. The available labels will also be displayed in the flash_map list shell command. -if FLASH_AREA_CHECK_INTEGRITY - -choice FLASH_AREA_CHECK_INTEGRITY_BACKEND - prompt "Crypto backend for the flash check functions" - default FLASH_AREA_CHECK_INTEGRITY_PSA - -config FLASH_AREA_CHECK_INTEGRITY_PSA - bool "Use PSA" - select PSA_WANT_ALG_SHA_256 - select PSA_CRYPTO - help - Use the PSA API to perform the integrity check. - -config FLASH_AREA_CHECK_INTEGRITY_MBEDTLS - bool "Use Mbed TLS [DEPRECATED]" - select MBEDTLS - select MBEDTLS_SHA256 - select DEPRECATED - help - Use the Mbed TLS library to perform the integrity check. - -endchoice - -endif # FLASH_AREA_CHECK_INTEGRITY - endif diff --git a/subsys/storage/flash_map/flash_map_integrity.c b/subsys/storage/flash_map/flash_map_integrity.c index 7e512e759db2..feefc2761d8b 100644 --- a/subsys/storage/flash_map/flash_map_integrity.c +++ b/subsys/storage/flash_map/flash_map_integrity.c @@ -18,25 +18,14 @@ #include "flash_map_priv.h" #include #include - -#define SHA256_DIGEST_SIZE 32 -#if defined(CONFIG_FLASH_AREA_CHECK_INTEGRITY_PSA) #include -#define SUCCESS_VALUE PSA_SUCCESS -#else -#include -#define SUCCESS_VALUE 0 -#endif int flash_area_check_int_sha256(const struct flash_area *fa, const struct flash_area_check *fac) { - unsigned char hash[SHA256_DIGEST_SIZE]; -#if defined(CONFIG_FLASH_AREA_CHECK_INTEGRITY_PSA) + unsigned char hash[PSA_HASH_LENGTH(PSA_ALG_SHA_256)]; psa_hash_operation_t hash_ctx; -#else /* CONFIG_FLASH_AREA_CHECK_INTEGRITY_MBEDTLS */ - mbedtls_sha256_context hash_ctx; -#endif + size_t hash_len; int to_read; int pos; int rc; @@ -50,14 +39,9 @@ int flash_area_check_int_sha256(const struct flash_area *fa, return -EINVAL; } -#if defined(CONFIG_FLASH_AREA_CHECK_INTEGRITY_PSA) hash_ctx = psa_hash_operation_init(); rc = psa_hash_setup(&hash_ctx, PSA_ALG_SHA_256); -#else /* CONFIG_FLASH_AREA_CHECK_INTEGRITY_MBEDTLS */ - mbedtls_sha256_init(&hash_ctx); - rc = mbedtls_sha256_starts(&hash_ctx, false); -#endif - if (rc != SUCCESS_VALUE) { + if (rc != PSA_SUCCESS) { return -ESRCH; } @@ -74,44 +58,25 @@ int flash_area_check_int_sha256(const struct flash_area *fa, goto error; } -#if defined(CONFIG_FLASH_AREA_CHECK_INTEGRITY_PSA) rc = psa_hash_update(&hash_ctx, fac->rbuf, to_read); -#else /* CONFIG_FLASH_AREA_CHECK_INTEGRITY_MBEDTLS */ - rc = mbedtls_sha256_update(&hash_ctx, fac->rbuf, to_read); -#endif - if (rc != SUCCESS_VALUE) { + if (rc != PSA_SUCCESS) { rc = -ESRCH; goto error; } } -#if defined(CONFIG_FLASH_AREA_CHECK_INTEGRITY_PSA) - size_t hash_len; - rc = psa_hash_finish(&hash_ctx, hash, sizeof(hash), &hash_len); -#else /* CONFIG_FLASH_AREA_CHECK_INTEGRITY_MBEDTLS */ - rc = mbedtls_sha256_finish(&hash_ctx, hash); -#endif - if (rc != SUCCESS_VALUE) { + if (rc != PSA_SUCCESS) { rc = -ESRCH; goto error; } - if (memcmp(hash, fac->match, SHA256_DIGEST_SIZE)) { -#if defined(CONFIG_FLASH_AREA_CHECK_INTEGRITY_PSA) + if (memcmp(hash, fac->match, sizeof(hash))) { /* The operation has already been terminated. */ return -EILSEQ; -#else /* CONFIG_FLASH_AREA_CHECK_INTEGRITY_MBEDTLS */ - rc = -EILSEQ; - goto error; -#endif } error: -#if defined(CONFIG_FLASH_AREA_CHECK_INTEGRITY_PSA) psa_hash_abort(&hash_ctx); -#else /* CONFIG_FLASH_AREA_CHECK_INTEGRITY_MBEDTLS */ - mbedtls_sha256_free(&hash_ctx); -#endif return rc; } From 74740148b4296df7cea58ed062f53bdaf047ac39 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Fri, 9 Jan 2026 15:45:17 +0100 Subject: [PATCH 2430/3659] tests: storage: flash_map: remove testing of legacy Mbed TLS crypto Following the removal of legacy Mbed TLS crypto for SHA-256 in the subsys, this commit updates the related sample. "overlay-mbedtls.conf" is removed as no more necessary and the corresponding test case is removed from "testcase.yaml". "overlay-psa.conf" is updated removing unnecessary Kconfig selections. Signed-off-by: Valerio Setti --- .../subsys/storage/flash_map/overlay-mbedtls.conf | 2 -- tests/subsys/storage/flash_map/overlay-psa.conf | 3 --- tests/subsys/storage/flash_map/testcase.yaml | 15 --------------- 3 files changed, 20 deletions(-) delete mode 100644 tests/subsys/storage/flash_map/overlay-mbedtls.conf diff --git a/tests/subsys/storage/flash_map/overlay-mbedtls.conf b/tests/subsys/storage/flash_map/overlay-mbedtls.conf deleted file mode 100644 index 2b8aef9e908d..000000000000 --- a/tests/subsys/storage/flash_map/overlay-mbedtls.conf +++ /dev/null @@ -1,2 +0,0 @@ -CONFIG_FLASH_AREA_CHECK_INTEGRITY=y -CONFIG_FLASH_AREA_CHECK_INTEGRITY_MBEDTLS=y diff --git a/tests/subsys/storage/flash_map/overlay-psa.conf b/tests/subsys/storage/flash_map/overlay-psa.conf index 03d88c4b5305..4a6f3846fdb3 100644 --- a/tests/subsys/storage/flash_map/overlay-psa.conf +++ b/tests/subsys/storage/flash_map/overlay-psa.conf @@ -1,5 +1,2 @@ CONFIG_FLASH_AREA_CHECK_INTEGRITY=y -CONFIG_FLASH_AREA_CHECK_INTEGRITY_PSA=y -CONFIG_MBEDTLS=y -CONFIG_MBEDTLS_PSA_CRYPTO_C=y CONFIG_TEST_RANDOM_GENERATOR=y diff --git a/tests/subsys/storage/flash_map/testcase.yaml b/tests/subsys/storage/flash_map/testcase.yaml index c25f657cbb05..3097f0de0cbb 100644 --- a/tests/subsys/storage/flash_map/testcase.yaml +++ b/tests/subsys/storage/flash_map/testcase.yaml @@ -27,21 +27,6 @@ tests: integration_platforms: - nrf52840dk/nrf52840 tags: flash_map - storage.flash_map_sha.mbedtls: - extra_args: EXTRA_CONF_FILE=overlay-mbedtls.conf - platform_allow: - - nrf51dk/nrf51822 - - qemu_x86 - - native_sim - - native_sim/native/64 - - mr_canhubk3 - - s32z2xxdc2/s32z270/rtu0 - - s32z2xxdc2/s32z270/rtu1 - - s32z2xxdc2@D/s32z270/rtu0 - - s32z2xxdc2@D/s32z270/rtu1 - tags: flash_map - integration_platforms: - - native_sim storage.flash_map_sha.psa: extra_args: EXTRA_CONF_FILE=overlay-psa.conf platform_allow: From 484fb7d7fca819658e214b62300f145434a490ef Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Fri, 9 Jan 2026 15:48:35 +0100 Subject: [PATCH 2431/3659] tests: storage: flash_map: rename conf file for integrity check Since now there is a single backend for crypto, i.e. the PSA Crypto API one, it's better to rename corresponding test case and related configuration file so that instead of mentioning "psa" they mention "integrity-check". Signed-off-by: Valerio Setti --- .../{overlay-psa.conf => overlay-integrity-check.conf} | 0 tests/subsys/storage/flash_map/testcase.yaml | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename tests/subsys/storage/flash_map/{overlay-psa.conf => overlay-integrity-check.conf} (100%) diff --git a/tests/subsys/storage/flash_map/overlay-psa.conf b/tests/subsys/storage/flash_map/overlay-integrity-check.conf similarity index 100% rename from tests/subsys/storage/flash_map/overlay-psa.conf rename to tests/subsys/storage/flash_map/overlay-integrity-check.conf diff --git a/tests/subsys/storage/flash_map/testcase.yaml b/tests/subsys/storage/flash_map/testcase.yaml index 3097f0de0cbb..5b1dc014cf33 100644 --- a/tests/subsys/storage/flash_map/testcase.yaml +++ b/tests/subsys/storage/flash_map/testcase.yaml @@ -28,7 +28,7 @@ tests: - nrf52840dk/nrf52840 tags: flash_map storage.flash_map_sha.psa: - extra_args: EXTRA_CONF_FILE=overlay-psa.conf + extra_args: EXTRA_CONF_FILE=overlay-integrity-check.conf platform_allow: - nrf51dk/nrf51822 - native_sim From 647f68cb2c0a6369d67918b29c6a9bc78d0fdd34 Mon Sep 17 00:00:00 2001 From: Valerio Setti Date: Fri, 9 Jan 2026 15:52:58 +0100 Subject: [PATCH 2432/3659] doc: migration-guide: add notes for changes in flash_map's integrity check Add notes about changes in flash_map's Kconfig for what concerns the crypto libraries used for integrity check. Signed-off-by: Valerio Setti --- doc/releases/migration-guide-4.4.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/doc/releases/migration-guide-4.4.rst b/doc/releases/migration-guide-4.4.rst index 991c0625b109..50ff539a76e6 100644 --- a/doc/releases/migration-guide-4.4.rst +++ b/doc/releases/migration-guide-4.4.rst @@ -751,6 +751,15 @@ Other subsystems * Use :kconfig:option:`CONFIG_CACHE_HAS_MIRRORED_MEMORY_REGIONS` instead of :kconfig:option:`CONFIG_CACHE_DOUBLEMAP` as the former is more descriptive of the feature. +Flash +===== + +* Previously deprecated ``CONFIG_FLASH_AREA_CHECK_INTEGRITY_MBEDTLS`` is now + removed. + +* ``CONFIG_FLASH_AREA_CHECK_INTEGRITY_PSA`` is also removed since there is + now no alternative for the crypto library backend. + JWT === From fc7fae6090f4443485eef5f9974a30cfbba888e8 Mon Sep 17 00:00:00 2001 From: Nicola Vetrini Date: Fri, 16 Jan 2026 14:46:41 +0100 Subject: [PATCH 2433/3659] sca: ECLAIR: update configuration for ECLAIR 3.14.0 This is the version of the tool that Zephyr infrastructure uses, and the configuration needs to be adjusted accordingly. Setting *_ALIASES variables is not necessary anymore. Signed-off-by: Nicola Vetrini --- cmake/sca/eclair/ECL/deviations.ecl | 10 +++++----- cmake/sca/eclair/eclair.template | 5 ----- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/cmake/sca/eclair/ECL/deviations.ecl b/cmake/sca/eclair/ECL/deviations.ecl index f2e143ad5cfe..af1d37c380b4 100644 --- a/cmake/sca/eclair/ECL/deviations.ecl +++ b/cmake/sca/eclair/ECL/deviations.ecl @@ -329,7 +329,7 @@ safe." -doc_end -doc_begin="Switch statements having a controlling expression of enum type deliberately do not have a default case: gcc -Wall enables -Wswitch which warns (and breaks the build as we use -Werror) if one of the enum labels is missing from the switch." --config=MC3A2.R16.4,reports+={deliberate,'any_area(kind(context)&&^.* has no `default.*$&&stmt(node(switch_stmt)&&child(cond,skip(__non_syntactic_paren_stmts,type(canonical(enum_underlying_type(any())))))))'} +-config=MC3A2.R16.4,reports+={deliberate,"any_area(kind(context)&&^.* has no `default.*$&&stmt(node(switch_stmt)&&child(cond,skip(__non_syntactic_paren_stmts,ref(enum_underlying_type(any()))))))"} -doc_end -doc_begin="A switch statement with a single switch clause and no default label may be used in place of an equivalent if statement if it is considered to improve readability." @@ -382,10 +382,10 @@ in assignments; (5) as initializers, possibly designated, in initalizer lists; -config=MC3A2.R20.7,expansion_context= {safe, "context(__call_expr_arg_contexts)"}, {safe, "left_right(^[(,\\[]$,^[),\\]]$)"}, -{safe, "context(skip_to(__expr_non_syntactic_contexts, stmt_child(node(array_subscript_expr), subscript)))"}, -{safe, "context(skip_to(__expr_non_syntactic_contexts, stmt_child(operator(assign), lhs)))"}, -{safe, "context(skip_to(__expr_non_syntactic_contexts, stmt_child(node(init_list_expr||designated_init_expr), init)))"}, -{safe, "context(skip_to(__expr_non_syntactic_contexts, stmt_child(node(case_stmt), lower||upper)))"} +{safe, "context(skip(parent(__expr_non_syntactic_contexts), is(subscript)&&parent(node(array_subscript_expr))))"}, +{safe, "context(skip(parent(__expr_non_syntactic_contexts), is(lhs)&&parent(stmt(operator(assign)))))"}, +{safe, "context(skip(parent(__expr_non_syntactic_contexts), is(init)&&parent(node(init_list_expr||designated_init_expr))))"}, +{safe, "context(skip(parent(__expr_non_syntactic_contexts), is(lower||upper)&&parent(node(case_stmt))))"} -doc_end -doc_begin="Violations involving the __config_enabled macros cannot be fixed without diff --git a/cmake/sca/eclair/eclair.template b/cmake/sca/eclair/eclair.template index d82824edb870..ffd3f87a76d5 100644 --- a/cmake/sca/eclair/eclair.template +++ b/cmake/sca/eclair/eclair.template @@ -28,11 +28,6 @@ execute_process( COMMAND @CMAKE_COMMAND@ -E env ECLAIR_DIAGNOSTICS_OUTPUT=@ECLAIR_DIAGNOSTICS_OUTPUT@ ECLAIR_DATA_DIR=@ECLAIR_ANALYSIS_DATA_DIR@ - CC_ALIASES=@CC_ALIASES@ - CXX_ALIASES=@CXX_ALIASES@ - AS_ALIASES=@AS_ALIASES@ - LD_ALIASES=@LD_ALIASES@ - AR_ALIASES=@AR_ALIASES@ @ECLAIR_ENV@ ${ECLAIR_ARGS} -- ${ZEPHYR_COMPILER_CALL} COMMAND_ERROR_IS_FATAL ANY ) From ff864b3cd31c49ca4ce0d3b1f2415b99e03a8246 Mon Sep 17 00:00:00 2001 From: Gatien Chevallier Date: Wed, 15 Oct 2025 15:21:08 +0200 Subject: [PATCH 2434/3659] drivers: otp: add stm32 BSEC driver Introduce the Boot and SECurity(BSEC) control driver. The BSEC peripheral manages the accesses to an embedded one time programmable(OTP) array of fuses. Those fuses are used to store on-chip, non-volatile data like boot and security parameters (e.g: secret keys, non-volatile counters, etc...). Signed-off-by: Gatien Chevallier --- drivers/otp/CMakeLists.txt | 1 + drivers/otp/Kconfig | 1 + drivers/otp/Kconfig.stm32 | 10 ++ drivers/otp/otp_bsec_stm32.c | 165 ++++++++++++++++++++++++++++ dts/bindings/otp/st,stm32-bsec.yaml | 59 ++++++++++ 5 files changed, 236 insertions(+) create mode 100644 drivers/otp/Kconfig.stm32 create mode 100644 drivers/otp/otp_bsec_stm32.c create mode 100644 dts/bindings/otp/st,stm32-bsec.yaml diff --git a/drivers/otp/CMakeLists.txt b/drivers/otp/CMakeLists.txt index 72b7ec78eb81..8c29247a5061 100644 --- a/drivers/otp/CMakeLists.txt +++ b/drivers/otp/CMakeLists.txt @@ -3,3 +3,4 @@ zephyr_library() zephyr_library_sources_ifdef(CONFIG_OTP_EMULATOR otp_emulator.c) +zephyr_library_sources_ifdef(CONFIG_OTP_STM32_BSEC otp_bsec_stm32.c) diff --git a/drivers/otp/Kconfig b/drivers/otp/Kconfig index 5e587c823af2..1d14f8934370 100644 --- a/drivers/otp/Kconfig +++ b/drivers/otp/Kconfig @@ -19,6 +19,7 @@ module-str = otp source "subsys/logging/Kconfig.template.log_config" source "drivers/otp/Kconfig.emu" +source "drivers/otp/Kconfig.stm32" config OTP_INIT_PRIORITY int "OTP init priority" diff --git a/drivers/otp/Kconfig.stm32 b/drivers/otp/Kconfig.stm32 new file mode 100644 index 000000000000..996395c4da5c --- /dev/null +++ b/drivers/otp/Kconfig.stm32 @@ -0,0 +1,10 @@ +# Copyright (c) 2026 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +config OTP_STM32_BSEC + bool "STM32 BSEC driver" + default y + select USE_STM32_HAL_BSEC + depends on DT_HAS_ST_STM32_BSEC_ENABLED + help + Enable OTP fuse access for STM32 SoCs embedding a BSEC peripheral. diff --git a/drivers/otp/otp_bsec_stm32.c b/drivers/otp/otp_bsec_stm32.c new file mode 100644 index 000000000000..403053704992 --- /dev/null +++ b/drivers/otp/otp_bsec_stm32.c @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2026 STMicroelectronics + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include + +#define DT_DRV_COMPAT st_stm32_bsec + +LOG_MODULE_REGISTER(otp_bsec_stm32); + +#define BSEC_WORD_SIZE 4 + +static K_MUTEX_DEFINE(lock); + +struct bsec_stm32_config { + BSEC_TypeDef *base; + unsigned int upper_fuse_limit; +}; + +static int otp_bsec_stm32_check_accessible(BSEC_HandleTypeDef *handle, + const struct bsec_stm32_config *config, off_t offset, + unsigned int nb_fuse) +{ + uint32_t fuse_idx = offset / BSEC_WORD_SIZE; + HAL_StatusTypeDef hal_ret; + uint32_t bsec_state = 0; + + if (nb_fuse == 0) { + return -EINVAL; + } + + hal_ret = HAL_BSEC_GetDeviceLifeCycleState(handle, &bsec_state); + if (hal_ret != HAL_OK) { + return -EACCES; + } + + /* Upper fuses are only accessible when the BSEC is in closed locked state */ + if (((fuse_idx + nb_fuse) > config->upper_fuse_limit) && + (bsec_state != HAL_BSEC_CLOSED_STATE)) { + return -EACCES; + } + + return 0; +} + +#if defined(CONFIG_OTP_PROGRAM) +static int otp_bsec_stm32_program(const struct device *dev, off_t offset, const void *buf, + size_t len) +{ + const struct bsec_stm32_config *config = dev->config; + BSEC_HandleTypeDef handle = { .Instance = config->base }; + HAL_StatusTypeDef hal_ret; + unsigned int nb_fuse; + unsigned int i; + int ret; + + /* Allow programming of 4bytes words only */ + if (!IS_ALIGNED(len, BSEC_WORD_SIZE)) { + LOG_ERR("Invalid length to program OTP: %zu", len); + return -EINVAL; + } + + /* Allow programming only at the beginning of a new word */ + if (!IS_ALIGNED(offset, BSEC_WORD_SIZE)) { + LOG_ERR("Programmed data not aligned on an OTP word"); + return -EINVAL; + } + + nb_fuse = len / BSEC_WORD_SIZE; + + ret = otp_bsec_stm32_check_accessible(&handle, config, offset, nb_fuse); + if (ret != 0) { + return ret; + } + + k_mutex_lock(&lock, K_FOREVER); + + for (i = 0; i < nb_fuse; i++) { + uint32_t prog_data = 0; + + LOG_DBG("Programming Fuse %lu", (offset / BSEC_WORD_SIZE) + i); + + prog_data = UNALIGNED_GET((uint32_t *)((uint8_t *)buf + i * BSEC_WORD_SIZE)); + + hal_ret = HAL_BSEC_OTP_Program(&handle, (offset / BSEC_WORD_SIZE) + i, prog_data, + 0); + if (hal_ret != HAL_OK) { + k_mutex_unlock(&lock); + return -EACCES; + } + } + + k_mutex_unlock(&lock); + + return 0; +} +#endif /* CONFIG_OTP_PROGRAM */ + +static int otp_bsec_stm32_read(const struct device *dev, off_t offset, void *buf, size_t len) +{ + const struct bsec_stm32_config *config = dev->config; + BSEC_HandleTypeDef handle = { .Instance = config->base }; + uint8_t *dest = (uint8_t *)buf; + HAL_StatusTypeDef hal_ret; + size_t bytes_left = len; + unsigned int nb_fuse; + unsigned int i; + int ret; + + /* Allow intra-word and spanned reads but not 0-sized reads */ + nb_fuse = len != 0 ? DIV_ROUND_UP(offset % BSEC_WORD_SIZE + len, BSEC_WORD_SIZE) : 0; + + ret = otp_bsec_stm32_check_accessible(&handle, config, offset, nb_fuse); + if (ret != 0) { + return ret; + } + + k_mutex_lock(&lock, K_FOREVER); + + for (i = 0; i < nb_fuse; i++) { + size_t first_offset = (i == 0) ? offset % BSEC_WORD_SIZE : 0; + size_t read_sz = MIN(BSEC_WORD_SIZE - first_offset, bytes_left); + uint32_t fuse_data = 0; + + LOG_DBG("Reading Fuse %lu", (offset / BSEC_WORD_SIZE) + i); + + hal_ret = HAL_BSEC_OTP_Read(&handle, (offset / BSEC_WORD_SIZE) + i, &fuse_data); + if (hal_ret != HAL_OK) { + k_mutex_unlock(&lock); + return -EACCES; + } + + memcpy(dest, ((uint8_t *)&fuse_data) + first_offset, read_sz); + dest += read_sz; + bytes_left -= read_sz; + if (bytes_left == 0) { + break; + } + } + + k_mutex_unlock(&lock); + + return 0; +} + +static const struct bsec_stm32_config bsec_config = { + .base = (void *)DT_INST_REG_ADDR(0), + .upper_fuse_limit = DT_INST_PROP(0, st_upper_fuse_limit), +}; + +static DEVICE_API(otp, otp_bsec_stm32_api) = { +#if defined(CONFIG_OTP_PROGRAM) + .program = otp_bsec_stm32_program, +#endif + .read = otp_bsec_stm32_read, +}; + +DEVICE_DT_INST_DEFINE(0, NULL, NULL, NULL, &bsec_config, PRE_KERNEL_1, + CONFIG_OTP_INIT_PRIORITY, &otp_bsec_stm32_api); diff --git a/dts/bindings/otp/st,stm32-bsec.yaml b/dts/bindings/otp/st,stm32-bsec.yaml new file mode 100644 index 000000000000..196aa31305c0 --- /dev/null +++ b/dts/bindings/otp/st,stm32-bsec.yaml @@ -0,0 +1,59 @@ +# Copyright (c) 2026 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +title: STM32 Boot and security control (BSEC) + +description: | + The boot and security control (BSEC) peripheral manages the accesses to an + embedded one time programmable (OTP) array of fuses. Those fuses are used to + store on-chip, non-volatile data like boot and security parameters. + Embedded non-volatile secrets are stored in BSEC upper area that is only + accessible while BSEC is operating in its BSEC-closed state. When the BSEC + state is BSEC-open, those non-volatile secrets are permanently hidden. + + Configuration example at SoC level: + + bsec: efuse@56009000 { + compatible = "st,stm32-bsec"; + reg = <0x56009000 0x1000>; + st,upper-fuse-limit = <256>; + + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + bootrom_cfg1: bootrom-cfg1@20 { + reg = <0x20 0x4>; + #nvmem-cell-cells = <0>; + }; + + mac_address0: mac-address@2a4 { + reg = <0x2a4 0x6>; + #nvmem-cell-cells = <0>; + }; + }; + }; + + Configuration example at board level: + + &bsec { + nvmem-layout { + mac_address2: mac-address@2fc { + reg = <0x2fc 0x6>; + #nvmem-cell-cells = <0>; + }; + }; + }; + +compatible: "st,stm32-bsec" + +include: base.yaml + +properties: + st,upper-fuse-limit: + type: int + required: true + description: | + Start fuse (32bit OTP word) index of the upper fuse region of the BSEC. + This region requires a particular SoC state to be accessed. From 84dc3270841874f9fb731e4a9a14909ac371d928 Mon Sep 17 00:00:00 2001 From: Gatien Chevallier Date: Wed, 22 Oct 2025 11:06:28 +0200 Subject: [PATCH 2435/3659] drivers: ethernet: stm32: handle MAC address with net_eth_mac_load() This new API handles if the MAC address should be fetched from NVMEM, is static or be randomly generated. Use it so that the driver can fetch the MAC address from the OTP fuses, when possible. Signed-off-by: Gatien Chevallier --- drivers/ethernet/Kconfig.stm32_hal | 1 + drivers/ethernet/eth_stm32_hal_common.c | 71 +++++++++++++------------ drivers/ethernet/eth_stm32_hal_priv.h | 1 + 3 files changed, 40 insertions(+), 33 deletions(-) diff --git a/drivers/ethernet/Kconfig.stm32_hal b/drivers/ethernet/Kconfig.stm32_hal index 00100dc5f0b6..3916ec639c6c 100644 --- a/drivers/ethernet/Kconfig.stm32_hal +++ b/drivers/ethernet/Kconfig.stm32_hal @@ -13,6 +13,7 @@ menuconfig ETH_STM32_HAL select HWINFO select ETH_DSA_SUPPORT_DEPRECATED select PINCTRL + imply NVMEM if $(dt_compat_any_has_prop,$(DT_COMPAT_ST_STM32_ETHERNET),nvmem-cells) imply CRC help Enable STM32 HAL based Ethernet driver. It is available for diff --git a/drivers/ethernet/eth_stm32_hal_common.c b/drivers/ethernet/eth_stm32_hal_common.c index ccdb586d8435..243d0325cf7a 100644 --- a/drivers/ethernet/eth_stm32_hal_common.c +++ b/drivers/ethernet/eth_stm32_hal_common.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -109,38 +110,6 @@ void HAL_ETH_RxCpltCallback(ETH_HandleTypeDef *heth_handle) k_sem_give(&dev_data->rx_int_sem); } -static void generate_mac(uint8_t *mac_addr) -{ -#if defined(ETH_STM32_RANDOM_MAC) - /* "zephyr,random-mac-address" is set, generate a random mac address */ - gen_random_mac(mac_addr, ST_OUI_B0, ST_OUI_B1, ST_OUI_B2); -#else /* Use user defined mac address */ - mac_addr[0] = ST_OUI_B0; - mac_addr[1] = ST_OUI_B1; - mac_addr[2] = ST_OUI_B2; -#if NODE_HAS_VALID_MAC_ADDR(DT_DRV_INST(0)) - mac_addr[3] = NODE_MAC_ADDR_OCTET(DT_DRV_INST(0), 3); - mac_addr[4] = NODE_MAC_ADDR_OCTET(DT_DRV_INST(0), 4); - mac_addr[5] = NODE_MAC_ADDR_OCTET(DT_DRV_INST(0), 5); -#else - uint8_t unique_device_ID_12_bytes[12]; - uint32_t result_mac_32_bits; - - /* Nothing defined by the user, use device id */ - hwinfo_get_device_id(unique_device_ID_12_bytes, 12); - result_mac_32_bits = crc32_ieee((uint8_t *)unique_device_ID_12_bytes, 12); - memcpy(&mac_addr[3], &result_mac_32_bits, 3); - - /** - * Set MAC address locally administered bit (LAA) as this is not assigned by the - * manufacturer - */ - mac_addr[0] |= 0x02; - -#endif /* NODE_HAS_VALID_MAC_ADDR(DT_DRV_INST(0))) */ -#endif -} - static int eth_initialize(const struct device *dev) { struct eth_stm32_hal_dev_data *dev_data = dev->data; @@ -177,7 +146,42 @@ static int eth_initialize(const struct device *dev) return ret; } - generate_mac(dev_data->mac_addr); + if (cfg->mac_cfg.type != NET_ETH_MAC_NVMEM) { +#if defined(ETH_STM32_RANDOM_MAC) + /* "zephyr,random-mac-address" is set, generate a random mac address */ + gen_random_mac(dev_data->mac_addr, ST_OUI_B0, ST_OUI_B1, ST_OUI_B2); +#else /* Use user defined mac address */ + dev_data->mac_addr[0] = ST_OUI_B0; + dev_data->mac_addr[1] = ST_OUI_B1; + dev_data->mac_addr[2] = ST_OUI_B2; +#if NODE_HAS_VALID_MAC_ADDR(DT_DRV_INST(0)) + dev_data->mac_addr[3] = NODE_MAC_ADDR_OCTET(DT_DRV_INST(0), 3); + dev_data->mac_addr[4] = NODE_MAC_ADDR_OCTET(DT_DRV_INST(0), 4); + dev_data->mac_addr[5] = NODE_MAC_ADDR_OCTET(DT_DRV_INST(0), 5); +#else + uint8_t unique_device_ID_12_bytes[12]; + uint32_t result_mac_32_bits; + + /* Nothing defined by the user, use device id */ + hwinfo_get_device_id(unique_device_ID_12_bytes, 12); + result_mac_32_bits = crc32_ieee((uint8_t *)unique_device_ID_12_bytes, 12); + memcpy(&dev_data->mac_addr[3], &result_mac_32_bits, 3); + + /** + * Set MAC address locally administered bit (LAA) as this is not assigned by the + * manufacturer + */ + dev_data->mac_addr[0] |= 0x02; + +#endif /* NODE_HAS_VALID_MAC_ADDR(DT_DRV_INST(0))) */ +#endif + } else { + ret = net_eth_mac_load(&cfg->mac_cfg, dev_data->mac_addr); + if (ret < 0) { + LOG_ERR("Failed to load MAC (%d)", ret); + return ret; + } + } heth->Init.MACAddr = dev_data->mac_addr; @@ -408,6 +412,7 @@ static const struct eth_stm32_hal_dev_cfg eth0_config = { (mac_clk_ptp), (stm_eth))), #endif .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(0), + .mac_cfg = NET_ETH_MAC_DT_INST_CONFIG_INIT(0), }; BUILD_ASSERT(DT_INST_ENUM_HAS_VALUE(0, phy_connection_type, mii) diff --git a/drivers/ethernet/eth_stm32_hal_priv.h b/drivers/ethernet/eth_stm32_hal_priv.h index da63b1f2ac6c..02297f9bab07 100644 --- a/drivers/ethernet/eth_stm32_hal_priv.h +++ b/drivers/ethernet/eth_stm32_hal_priv.h @@ -113,6 +113,7 @@ struct eth_stm32_hal_dev_cfg { uint8_t rate_pclken_idx; #endif const struct pinctrl_dev_config *pcfg; + const struct net_eth_mac_config mac_cfg; }; /* Device run time data */ From 28a988cc1048f548f83940ba45e870e1e899e27a Mon Sep 17 00:00:00 2001 From: Gatien Chevallier Date: Wed, 22 Oct 2025 11:15:03 +0200 Subject: [PATCH 2436/3659] dts: arm: st: n6: Add BSEC node for OTP handling The STM32N6 has a BSEC peripheral for the OTP management, add it to the SoC device tree file. Moreover, there are 4 OTP words dedicated for Ethernet MAC addresses, describe them in the NVMEM layout. Signed-off-by: Gatien Chevallier --- dts/arm/st/n6/stm32n6.dtsi | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/dts/arm/st/n6/stm32n6.dtsi b/dts/arm/st/n6/stm32n6.dtsi index 298c5b56335a..2facbb234784 100644 --- a/dts/arm/st/n6/stm32n6.dtsi +++ b/dts/arm/st/n6/stm32n6.dtsi @@ -746,6 +746,29 @@ status = "disabled"; }; + bsec: efuse@56009000 { + compatible = "st,stm32-bsec"; + reg = <0x56009000 0x1000>; + st,upper-fuse-limit = <256>; + status = "disabled"; + + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + mac_address0: mac-address@2a4 { + reg = <0x2a4 0x6>; + #nvmem-cell-cells = <0>; + }; + + mac_address1: mac-address@2ac { + reg = <0x2ac 0x6>; + #nvmem-cell-cells = <0>; + }; + }; + }; + dcmipp: dcmipp@58002000 { compatible = "st,stm32-dcmipp"; reg = <0x58002000 0x1000>; From 40c98c82d7219821d0cb3734ddf97afa335e4343 Mon Sep 17 00:00:00 2001 From: Gatien Chevallier Date: Wed, 22 Oct 2025 11:18:46 +0200 Subject: [PATCH 2437/3659] boards: st: stm32n6570_dk: read the MAC address from the OTP fuses On STM32N6x SoCs, secrets and persistent information such as Ethernet MAC addresses are stored in the BSEC OTP fuses. Therefore, default enable OTP support if NET_L2_ETHERNET and NVMEM are enabled so that the MAC address can be read from the BSEC OTP fuses through the NVMEM API. Use the "mac_address0" NVMEM cell to be able to read the ethernet MAC address from the OTP fuses. Signed-off-by: Gatien Chevallier --- boards/st/stm32n6570_dk/Kconfig.defconfig | 3 +++ boards/st/stm32n6570_dk/stm32n6570_dk_common.dtsi | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/boards/st/stm32n6570_dk/Kconfig.defconfig b/boards/st/stm32n6570_dk/Kconfig.defconfig index b078ade8a6af..26bc6d813d95 100644 --- a/boards/st/stm32n6570_dk/Kconfig.defconfig +++ b/boards/st/stm32n6570_dk/Kconfig.defconfig @@ -8,6 +8,9 @@ if BOARD_STM32N6570_DK configdefault NET_L2_ETHERNET default y +configdefault OTP + default y if NET_L2_ETHERNET && NVMEM + if DISPLAY || VIDEO # MEMC needs to be enabled in order to store # display frame buffer and video buffer pool to external PSRAM diff --git a/boards/st/stm32n6570_dk/stm32n6570_dk_common.dtsi b/boards/st/stm32n6570_dk/stm32n6570_dk_common.dtsi index 42a9447a3027..0486b278fe5a 100644 --- a/boards/st/stm32n6570_dk/stm32n6570_dk_common.dtsi +++ b/boards/st/stm32n6570_dk/stm32n6570_dk_common.dtsi @@ -439,6 +439,10 @@ zephyr_udc0: &usbotg_hs1 { }; }; +&bsec { + status = "okay"; +}; + /** * Per the RGMII specification, the Tx clock signal must be skewed * from the Tx data signals by 1~2 ns. On this board, the SoC must @@ -467,6 +471,8 @@ zephyr_udc0: &usbotg_hs1 { pinctrl-names = "default"; phy-connection-type = "rgmii"; phy-handle = <ð_phy>; + nvmem-cells = <&mac_address0>; + nvmem-cell-names = "mac-address"; }; &mdio { From 49de45225de7a15f02cb559aa0316fe99ee17ef6 Mon Sep 17 00:00:00 2001 From: Gaetan Perrot Date: Tue, 20 Jan 2026 14:45:13 +0900 Subject: [PATCH 2438/3659] drivers: clock_control: litex: make litex_clk_dts_clkouts_read void litex_clk_dts_clkouts_read() never reports errors and always returns 0. The error check at the call site is therefore dead code. Make the function void and drop the unused error handling. Signed-off-by: Gaetan Perrot --- drivers/clock_control/clock_control_litex.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/clock_control/clock_control_litex.c b/drivers/clock_control/clock_control_litex.c index ea1a4d7d6fda..1436249e538a 100644 --- a/drivers/clock_control/clock_control_litex.c +++ b/drivers/clock_control/clock_control_litex.c @@ -1637,7 +1637,7 @@ static int litex_clk_dts_timeout_read(struct litex_clk_timeout *timeout) return 0; } -static int litex_clk_dts_clkouts_read(void) +static void litex_clk_dts_clkouts_read(void) { struct litex_clk_range clkout_div; struct litex_clk_clkout *lcko; @@ -1665,7 +1665,6 @@ static int litex_clk_dts_clkouts_read(void) #if CLKOUT_EXIST(6) == 1 CLKOUT_INIT(6) #endif - return 0; } static void litex_clk_init_clkouts(void) @@ -1756,10 +1755,7 @@ static int litex_clk_init(const struct device *dev) return ret; } - ret = litex_clk_dts_clkouts_read(); - if (ret != 0) { - return ret; - } + litex_clk_dts_clkouts_read(); litex_clk_init_clkouts(); From 27be4443fc0bab8f06535df0792802dd30eb2c30 Mon Sep 17 00:00:00 2001 From: Gaetan Perrot Date: Tue, 20 Jan 2026 14:49:27 +0900 Subject: [PATCH 2439/3659] drivers: clock_control: litex: remove redundant initialization Local variables are initialized but always overwritten before being read or return. Drop the redundant initialization. No functional change intended. Signed-off-by: Gaetan Perrot --- drivers/clock_control/clock_control_litex.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/clock_control/clock_control_litex.c b/drivers/clock_control/clock_control_litex.c index 1436249e538a..f1a4bdaf4f0b 100644 --- a/drivers/clock_control/clock_control_litex.c +++ b/drivers/clock_control/clock_control_litex.c @@ -1248,7 +1248,7 @@ static int litex_clk_calc_clkout_params(struct litex_clk_clkout *lcko, uint64_t vco_freq) { int delta_f; - uint64_t m, clk_freq = 0; + uint64_t m, clk_freq; uint32_t d, margin = 1; if (lcko->margin.exp) { @@ -1311,13 +1311,13 @@ static int litex_clk_calc_all_clkout_params(uint64_t vco_freq) static int litex_clk_calc_all_params(void) { uint32_t div, mul; - uint64_t vco_freq = 0; + uint64_t vco_freq; for (div = ldev->divclk.min; div <= ldev->divclk.max; div++) { ldev->ts_g_config.div = div; for (mul = ldev->clkfbout.max; mul >= ldev->clkfbout.min; mul--) { - int below, above, all_valid = true; + int below, above, all_valid; vco_freq = CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC * (uint64_t)mul; vco_freq /= div; From 40d79b1f64309f3b1fa52f4e8fdbcd7368b75912 Mon Sep 17 00:00:00 2001 From: Peter van der Perk Date: Tue, 20 Jan 2026 09:27:09 +0100 Subject: [PATCH 2440/3659] sensor: bmm150: fix init when no trigger is selected When no trigger was chosen case statement fell through to default which causes the return code to -ENOTSUPP Signed-off-by: Peter van der Perk --- drivers/sensor/bosch/bmm150/bmm150.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/sensor/bosch/bmm150/bmm150.c b/drivers/sensor/bosch/bmm150/bmm150.c index 9db0f5553157..46109e19503f 100644 --- a/drivers/sensor/bosch/bmm150/bmm150.c +++ b/drivers/sensor/bosch/bmm150/bmm150.c @@ -651,8 +651,8 @@ static int pm_action(const struct device *dev, enum pm_device_action action) else { ret = bmm150_trigger_mode_power_ctrl(dev, true); } - break; #endif + break; #ifdef CONFIG_PM_DEVICE case PM_DEVICE_ACTION_SUSPEND: ret = bmm150_power_control(dev, 0); /* Suspend */ From 0b1b0991969ed054b8ef8af7ff5d134eb9d4a81a Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Wed, 19 Nov 2025 23:25:50 +0100 Subject: [PATCH 2441/3659] Bluetooth: Controller: Fix PAST sync_offset_us calculation Fix the missing use of remainder value in the sync_offset_us calculations. Also, Periodic Sync reception is relative to Peripheral event hence ticks_anchor does not require the ticker margin and event jitter to be subtracted. Signed-off-by: Vinayak Kariappa Chettimada --- subsys/bluetooth/controller/ll_sw/ull_conn.c | 9 ++++++--- subsys/bluetooth/controller/ll_sw/ull_llcp.c | 11 +++++------ subsys/bluetooth/controller/ll_sw/ull_sync.c | 10 ++++------ .../controller/ctrl_periodic_sync/src/main.c | 16 ++++++++-------- .../audio/test_scripts/bap_bass_client_sync.sh | 2 +- 5 files changed, 24 insertions(+), 24 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/ull_conn.c b/subsys/bluetooth/controller/ll_sw/ull_conn.c index 3e6908417b0a..1c1f7d598abb 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_conn.c +++ b/subsys/bluetooth/controller/ll_sw/ull_conn.c @@ -2849,7 +2849,7 @@ static void ticker_get_offset_op_cb(uint32_t status, void *param) *((uint32_t volatile *)param) = status; } -static uint32_t get_ticker_offset(uint8_t ticker_id, uint16_t *lazy) +static uint32_t get_ticker_offset(const struct ll_conn *conn, uint8_t ticker_id, uint16_t *lazy) { uint32_t volatile ret_cb; uint32_t ticks_to_expire; @@ -2888,6 +2888,7 @@ static uint32_t get_ticker_offset(uint8_t ticker_id, uint16_t *lazy) /* Add a tick for negative remainder and return positive remainder * value. */ + remainder = conn->llcp.prep.remainder; hal_ticker_add_jitter(&ticks_to_expire, &remainder); start_us = remainder; @@ -2921,7 +2922,8 @@ static void mfy_past_sender_offset_get(void *param) LL_ASSERT_DBG(adv_sync); - ticker_offset_us = get_ticker_offset(TICKER_ID_ADV_SYNC_BASE + adv_sync_handle, + ticker_offset_us = get_ticker_offset(conn, + (TICKER_ID_ADV_SYNC_BASE + adv_sync_handle), &lazy); pa_event_counter = adv_sync->lll.event_counter; @@ -2933,7 +2935,8 @@ static void mfy_past_sender_offset_get(void *param) LL_ASSERT_DBG(sync); - ticker_offset_us = get_ticker_offset(TICKER_ID_SCAN_SYNC_BASE + sync_handle, + ticker_offset_us = get_ticker_offset(conn, + (TICKER_ID_SCAN_SYNC_BASE + sync_handle), &lazy); if (lazy && ticker_offset_us > interval_us) { diff --git a/subsys/bluetooth/controller/ll_sw/ull_llcp.c b/subsys/bluetooth/controller/ll_sw/ull_llcp.c index f40e98ad96c7..2c0e852bafc7 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_llcp.c +++ b/subsys/bluetooth/controller/ll_sw/ull_llcp.c @@ -1552,20 +1552,19 @@ void ull_lp_past_offset_calc_reply(struct ll_conn *conn, uint32_t offset_us, /* Update offset_us */ offset_us = offset_us - (conn_event_offset * conn_interval_us); - - ctx->data.periodic_sync.conn_event_count = ull_conn_event_counter(conn) + - conn_event_offset; } llcp_pdu_fill_sync_info_offset(&ctx->data.periodic_sync.sync_info, offset_us); + #if defined(CONFIG_BT_PERIPHERAL) /* Save the result for later use */ ctx->data.periodic_sync.offset_us = offset_us; #endif /* CONFIG_BT_PERIPHERAL */ - ctx->data.periodic_sync.sync_conn_event_count = ull_conn_event_counter(conn); - ctx->data.periodic_sync.conn_event_count = ull_conn_event_counter(conn) + - conn_event_offset; + ctx->data.periodic_sync.sync_conn_event_count = + ull_conn_event_counter_at_prepare(conn) - 1U; + ctx->data.periodic_sync.conn_event_count = + ull_conn_event_counter_at_prepare(conn) + conn_event_offset - 1U; ctx->data.periodic_sync.sync_info.evt_cntr = pa_event_counter; diff --git a/subsys/bluetooth/controller/ll_sw/ull_sync.c b/subsys/bluetooth/controller/ll_sw/ull_sync.c index dbca3e77c7a4..53a53c38a36c 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_sync.c +++ b/subsys/bluetooth/controller/ll_sw/ull_sync.c @@ -274,6 +274,8 @@ void ull_sync_setup_from_sync_transfer(struct ll_conn *conn, uint16_t service_da if (sync->skip > skip_max) { sync->skip = skip_max; } + } else { + sync->skip = 0U; } sync->sync_expire = CONN_ESTAB_COUNTDOWN; @@ -321,14 +323,9 @@ void ull_sync_setup_from_sync_transfer(struct ll_conn *conn, uint16_t service_da conn_interval_us = conn->lll.interval * CONN_INT_UNIT_US; /* Calculate offset and schedule sync radio events */ - ready_delay_us = lll_radio_rx_ready_delay_get(lll->phy, PHY_FLAGS_S8); - sync_offset_us = PDU_ADV_SYNC_INFO_OFFSET_GET(si) * lll->window_size_event_us; /* offs_adjust may be 1 only if sync setup by LL_PERIODIC_SYNC_IND */ sync_offset_us += (PDU_ADV_SYNC_INFO_OFFS_ADJUST_GET(si) ? OFFS_ADJUST_US : 0U); - sync_offset_us -= EVENT_TICKER_RES_MARGIN_US; - sync_offset_us -= EVENT_JITTER_US; - sync_offset_us -= ready_delay_us; if (conn_evt_offset) { int64_t conn_offset_us = (int64_t)conn_evt_offset * conn_interval_us; @@ -386,6 +383,7 @@ void ull_sync_setup_from_sync_transfer(struct ll_conn *conn, uint16_t service_da /* Calculate event time reservation */ slot_us = PDU_AC_MAX_US(PDU_AC_EXT_PAYLOAD_RX_SIZE, lll->phy); + ready_delay_us = lll_radio_rx_ready_delay_get(lll->phy, PHY_FLAGS_S8); slot_us += ready_delay_us; /* Add implementation defined radio event overheads */ @@ -410,7 +408,7 @@ void ull_sync_setup_from_sync_transfer(struct ll_conn *conn, uint16_t service_da #if defined(CONFIG_BT_PERIPHERAL) if (conn->lll.role == BT_HCI_ROLE_PERIPHERAL) { /* Compensate for window widening */ - ticks_anchor += HAL_TICKER_US_TO_TICKS(conn->lll.periph.window_widening_event_us); + sync_offset_us += conn->lll.periph.window_widening_event_us; } #endif /* CONFIG_BT_PERIPHERAL */ diff --git a/tests/bluetooth/controller/ctrl_periodic_sync/src/main.c b/tests/bluetooth/controller/ctrl_periodic_sync/src/main.c index 38ddbccb88cd..68803a41b454 100644 --- a/tests/bluetooth/controller/ctrl_periodic_sync/src/main.c +++ b/tests/bluetooth/controller/ctrl_periodic_sync/src/main.c @@ -147,14 +147,14 @@ ZTEST(periodic_sync_transfer, test_periodic_sync_transfer_loc) struct pdu_data_llctrl_periodic_sync_ind local_periodic_sync_ind = { .id = 0x00, - .conn_event_count = 0x00, + .conn_event_count = 0xFFFFU, .last_pa_event_counter = 0x00, .sid = 0x00, .addr_type = 0x00, .sca = 0x00, .phy = 0x00, .adv_addr = { 0, 0, 0, 0, 0, 0}, - .sync_conn_event_count = 0 + .sync_conn_event_count = 0xFFFFU, }; /* Reset and setup mayfly_enqueue_custom_fake */ @@ -346,26 +346,26 @@ ZTEST(periodic_sync_transfer, test_periodic_sync_transfer_rem_2) struct pdu_data_llctrl_periodic_sync_ind local_periodic_sync_ind = { .id = 0x00, - .conn_event_count = 0x01, + .conn_event_count = 0x0000U, .last_pa_event_counter = 0x00, .sid = 0x00, .addr_type = 0x00, .sca = 0x00, .phy = 0x00, .adv_addr = { 0, 0, 0, 0, 0, 0}, - .sync_conn_event_count = 0x01 + .sync_conn_event_count = 0x0000U, }; struct pdu_data_llctrl_periodic_sync_ind remote_periodic_sync_ind = { .id = 0x01, - .conn_event_count = 0x00, + .conn_event_count = 0x0000U, .last_pa_event_counter = 0x00, .sid = 0x00, .addr_type = 0x01, .sca = 0x00, .phy = 0x01, .adv_addr = { 0, 0, 0, 0, 0, 0}, - .sync_conn_event_count = 0 + .sync_conn_event_count = 0x0000U, }; /* Reset and setup fake functions */ @@ -481,14 +481,14 @@ ZTEST(periodic_sync_transfer, test_periodic_sync_transfer_loc_twice) struct pdu_data_llctrl_periodic_sync_ind local_periodic_sync_ind = { .id = 0x00, - .conn_event_count = 0x00, + .conn_event_count = 0xFFFFU, .last_pa_event_counter = 0x00, .sid = 0x00, .addr_type = 0x00, .sca = 0x00, .phy = 0x00, .adv_addr = { 0, 0, 0, 0, 0, 0}, - .sync_conn_event_count = 0 + .sync_conn_event_count = 0xFFFFU, }; /* Reset and setup mayfly_enqueue_custom_fake */ diff --git a/tests/bsim/bluetooth/audio/test_scripts/bap_bass_client_sync.sh b/tests/bsim/bluetooth/audio/test_scripts/bap_bass_client_sync.sh index 1e2df5a74af3..c296a02302ea 100755 --- a/tests/bsim/bluetooth/audio/test_scripts/bap_bass_client_sync.sh +++ b/tests/bsim/bluetooth/audio/test_scripts/bap_bass_client_sync.sh @@ -25,7 +25,7 @@ Execute ./bs_${BOARD_TS}_tests_bsim_bluetooth_audio_prj_conf \ Execute ./bs_${BOARD_TS}_tests_bsim_bluetooth_audio_prj_conf \ -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=2 -testid=bass_broadcaster \ - -RealEncryption=1 -rs=79 -D=3 -start_offset=6e3 + -RealEncryption=1 -rs=69 -D=3 # Simulation time should be larger than the WAIT_TIME in common.h Execute ./bs_2G4_phy_v1 -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -D=3 \ From 5fe53aaa84b0dc44d29bd1be60df5c844bc7bafc Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Tue, 6 Jan 2026 22:17:48 +0100 Subject: [PATCH 2442/3659] Bluetooth: Controller: Use PPI/DPPI to start s/w switch timer Use PPI/DPPI to start s/w switch timer to reduce current consumption. Explicitly starting the s/w switch timer at prepare meant current being consumed in the prepare margin duration. Use of PPI/DPPI ensure s/w switch timer is start when event timer is started after the prepare margin. Signed-off-by: Vinayak Kariappa Chettimada --- .../controller/ll_sw/nordic/hal/nrf5/radio/radio.c | 4 ++-- .../ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h | 7 +++++++ .../ll_sw/nordic/hal/nrf5/radio/radio_nrf5_ppi.h | 8 ++++++++ 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c index 00ed03050fdb..5a85883cb10f 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c @@ -1479,8 +1479,8 @@ uint32_t radio_tmr_start(uint8_t trx, uint32_t ticks_start, uint32_t remainder) SW_SWITCH_TIMER->MODE = 0; SW_SWITCH_TIMER->PRESCALER = HAL_EVENT_TIMER_PRESCALER_VALUE; SW_SWITCH_TIMER->BITMODE = 0; /* 16 bit */ - /* FIXME: start along with EVENT_TIMER, to save power */ - nrf_timer_task_trigger(SW_SWITCH_TIMER, NRF_TIMER_TASK_START); + + hal_sw_switch_timer_start_ppi_config(); #endif /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */ hal_sw_switch_timer_clear_ppi_config(); diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h index 1085f72f0b98..68cd9716985e 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h @@ -264,6 +264,13 @@ static inline void hal_trigger_aar_ppi_config(void) #define HAL_RADIO_GROUP_TASK_ENABLE_PUBLISH_END HAL_RADIO_PUBLISH_PHYEND #endif /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER || CONFIG_BT_CTLR_DF */ +/* Start SW-switch timer on event timer start. + */ +static inline void hal_sw_switch_timer_start_ppi_config(void) +{ + nrf_timer_subscribe_set(SW_SWITCH_TIMER, NRF_TIMER_TASK_START, HAL_EVENT_TIMER_START_PPI); +} + /* Clear SW-switch timer on packet end: * wire the RADIO EVENTS_END event to SW_SWITCH_TIMER TASKS_CLEAR task. * diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_ppi.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_ppi.h index 4b29bb4fe21d..4cc1440d7b7a 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_ppi.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_ppi.h @@ -292,6 +292,14 @@ static inline void hal_trigger_aar_ppi_config(void) #if !defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER) +/* Start SW-switch timer on event timer start. + */ +static inline void hal_sw_switch_timer_start_ppi_config(void) +{ + nrf_ppi_fork_endpoint_setup(NRF_PPI, HAL_EVENT_TIMER_START_PPI, + (uint32_t)&(SW_SWITCH_TIMER->TASKS_START)); +} + /* Clear SW-switch timer on packet end: * wire the RADIO EVENTS_END event to SW_SWITCH_TIMER TASKS_CLEAR task. * From 73c182509c1f8e01287bab593ec3c9e83471eca0 Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Tue, 6 Jan 2026 23:02:37 +0100 Subject: [PATCH 2443/3659] Bluetooth: Controller: LLL prepare at margin Kconfig Introduce Kconfig option to enfore LLL prepare at margin irrespective of whether there is an overlapping state/role. Signed-off-by: Vinayak Kariappa Chettimada --- .../bluetooth/controller/Kconfig.ll_sw_split | 20 ++++++++++ .../controller/ll_sw/nordic/lll/lll.c | 39 +++++++++++++++++-- 2 files changed, 56 insertions(+), 3 deletions(-) diff --git a/subsys/bluetooth/controller/Kconfig.ll_sw_split b/subsys/bluetooth/controller/Kconfig.ll_sw_split index 98a74224f624..6b2c9f2575e8 100644 --- a/subsys/bluetooth/controller/Kconfig.ll_sw_split +++ b/subsys/bluetooth/controller/Kconfig.ll_sw_split @@ -914,6 +914,26 @@ config BT_CTLR_ULL_LOW_PRIO The interrupt priority for Ticker's Job IRQ and Upper Link Layer lower priority functions. +config BT_CTLR_LLL_PREPARE_AT_MARGIN + bool "LLL prepare at margin" + depends on !BT_CTLR_LOW_LAT + default y if SOC_COMPATIBLE_NRF54LX + help + Execute LLL prepare callback at the prepare margin, even when no + overlapping state/role is currently active. + + This will lead to an additional CPU wake up after initial one at the + prepare tick. LLL prepare callback is executed sufficient time before + the hard real time radio transmission or reception instant so that any + resource that may otherwise consume current if setup at prepare tick + can be delayed until the prepare margin elapses. + + Disable this option if resources that need to be ready at the hard + real time radio transmission or reception instant can be setup at + prepare tick without impacting current consumption until actual + requirement at the hard real time radio transmission or reception + instant. + config BT_CTLR_LOW_LAT bool "Low latency non-negotiating event preemption" depends on BT_CTLR_LOW_LAT_ULL && BT_CTLR_LOW_LAT_ULL_DONE diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c index 9ff7e9007285..9a39b1fe3829 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c @@ -47,6 +47,7 @@ static struct { void *param; lll_is_abort_cb_t is_abort_cb; lll_abort_cb_t abort_cb; + uint8_t has_margin:1; } curr; #if defined(CONFIG_BT_CTLR_LOW_LAT_ULL_DONE) @@ -934,9 +935,13 @@ int lll_prepare_resolve(lll_is_abort_cb_t is_abort_cb, lll_abort_cb_t abort_cb, } /* Current event active or another prepare is ready in the pipeline */ - if ((!is_dequeue && !is_done_sync()) || - event.curr.abort_cb || ready_short || - (ready && is_resume)) { + if (((is_dequeue == 0U) && (is_done_sync() == 0U)) || + (event.curr.abort_cb != NULL) || + (ready_short != NULL) || + ((ready != NULL) && (is_resume != 0U)) || + (IS_ENABLED(CONFIG_BT_CTLR_LLL_PREPARE_AT_MARGIN) && + (prepare_param->defer == 0U) && + (event.curr.has_margin == 0U))) { #if defined(CONFIG_BT_CTLR_LOW_LAT) lll_prepare_cb_t resume_cb; #endif /* CONFIG_BT_CTLR_LOW_LAT */ @@ -1019,6 +1024,10 @@ int lll_prepare_resolve(lll_is_abort_cb_t is_abort_cb, lll_abort_cb_t abort_cb, event.curr.is_abort_cb = is_abort_cb; event.curr.abort_cb = abort_cb; + if (IS_ENABLED(CONFIG_BT_CTLR_LLL_PREPARE_AT_MARGIN)) { + event.curr.has_margin = 0U; + } + err = prepare_cb(prepare_param); if (!IS_ENABLED(CONFIG_BT_CTLR_ASSERT_OVERHEAD_START) && @@ -1277,6 +1286,23 @@ static void preempt(void *param) /* No event to abort */ if (!event.curr.abort_cb || !event.curr.param) { + /* When a radio event is placed back in the prepare pipeline as + * resume prepare and a done event is not to be generated; in + * these cases, event.curr.abort_cb is not NULL, but + * event.curr.param is NULL. Let us setup the preempt timeout to + * ensure the margin for certain. + */ + if (IS_ENABLED(CONFIG_BT_CTLR_LLL_PREPARE_AT_MARGIN) && + (event.curr.abort_cb == NULL)) { + /* Previous event is done before the prepare margin for + * the event ready in the pipeline when we are here now. + */ + event.curr.has_margin = 1U; + + /* Execute the enqueued ready LLL prepare callbacks */ + ull_prepare_dequeue(TICKER_USER_ID_LLL); + } + return; } @@ -1374,6 +1400,13 @@ static void preempt(void *param) LL_ASSERT_ERR(ready->prepare_param.param == param); } + if (IS_ENABLED(CONFIG_BT_CTLR_LLL_PREPARE_AT_MARGIN)) { + /* Here prepare margin has expired while a previous event is + * active, set the flag and proceed with abort. + */ + event.curr.has_margin = 1U; + } + /* Check if current event want to continue */ err = event.curr.is_abort_cb(ready->prepare_param.param, event.curr.param, &resume_cb); if (!err || (err == -EBUSY)) { From d845a2230e17fe3f31b12c4216f6d2cf55b1096a Mon Sep 17 00:00:00 2001 From: Lingao Meng Date: Tue, 20 Jan 2026 16:44:12 +0800 Subject: [PATCH 2444/3659] fs: nvs: prevent ATE writes at sector boundary In NVS, allocation table entries (ATEs) are written backwards within each sector. Under delete-only or delete-heavy workloads, a sector may contain only delete ATEs, causing the ATE write pointer to approach the sector boundary. Without an explicit boundary check, ATE writes may occur at offset 0 of the current sector, allowing the write pointer to underflow into the previous sector and corrupt unrelated data or metadata. Fix this by disallowing ATE writes when the write pointer is at the sector boundary. This ensures that ATE writes remain confined to the current sector and prevents pointer underflow across sectors. Signed-off-by: Lingao Meng --- subsys/fs/nvs/nvs.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/subsys/fs/nvs/nvs.c b/subsys/fs/nvs/nvs.c index 8a710d570fb1..833600f4ab17 100644 --- a/subsys/fs/nvs/nvs.c +++ b/subsys/fs/nvs/nvs.c @@ -1176,7 +1176,13 @@ ssize_t nvs_write(struct nvs_fs *fs, uint16_t id, const void *data, size_t len) goto end; } - if (fs->ate_wra >= (fs->data_wra + required_space)) { + /* ATEs grow backwards within a sector. In delete-only scenarios, + * a sector may contain only delete ATEs and no data entries. + * Prevent ATE writes at current start of sector to avoid crossing + * into the previous sector. + */ + if (fs->ate_wra >= (fs->data_wra + required_space) && + (fs->ate_wra & ADDR_OFFS_MASK) != 0) { rc = nvs_flash_wrt_entry(fs, id, data, len); if (rc) { From 155d22a11782293823fcac7233eea15f3cfb5efd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20Amundsen?= Date: Tue, 20 Jan 2026 11:07:41 +0100 Subject: [PATCH 2445/3659] soc: kconfig: gen_uicr: elaborate on setting ERASEPROTECT MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Provide some information on how to find the command that is used for generating the UICR hex file so that its easier for users to know what command to use. Signed-off-by: Håkon Amundsen --- soc/nordic/common/uicr/Kconfig.gen_uicr | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/soc/nordic/common/uicr/Kconfig.gen_uicr b/soc/nordic/common/uicr/Kconfig.gen_uicr index 4ee6af87eaef..e287773c6055 100644 --- a/soc/nordic/common/uicr/Kconfig.gen_uicr +++ b/soc/nordic/common/uicr/Kconfig.gen_uicr @@ -56,6 +56,17 @@ config GEN_UICR_ERASEPROTECT Note that gen_uicr.py can be used directly to create a configuration with both enabled if needed. + The command used when invoking gen_uicr.py can be found in the build directory. + For ninja based builds the command is found in + build/uicr/build.ninja + For make based builds the command is found in + build/CMakefiles/gen_uicr.dir/build.make + + Add the '--eraseprotect' argument to this command to enable the configuration + that would be added by setting this option. Note that programming the + resulting UICR hex file would completely lock the UICR from any modification + for the lifetime of the device. + menu "UICR.APPROTECT - Access Port Protection" config GEN_UICR_APPROTECT_APPLICATION_PROTECTED From c9c23bef54ba328b257a844180694bcc784cfbd5 Mon Sep 17 00:00:00 2001 From: Mathieu Choplain Date: Tue, 20 Jan 2026 12:58:17 +0100 Subject: [PATCH 2446/3659] drivers: sensor: stm32_temp: use CAL_RES everywhere The raw "12" constant was used in a place where the "CAL_RES" define should have been used instead. Signed-off-by: Mathieu Choplain --- drivers/sensor/st/stm32_temp/stm32_temp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/sensor/st/stm32_temp/stm32_temp.c b/drivers/sensor/st/stm32_temp/stm32_temp.c index d306caafb9e5..5cbf4f13cb85 100644 --- a/drivers/sensor/st/stm32_temp/stm32_temp.c +++ b/drivers/sensor/st/stm32_temp/stm32_temp.c @@ -18,7 +18,7 @@ LOG_MODULE_REGISTER(stm32_temp, CONFIG_SENSOR_LOG_LEVEL); -#define CAL_RES 12 +#define CAL_RES 12U #define MAX_CALIB_POINTS 2 #if DT_HAS_COMPAT_STATUS_OKAY(st_stm32_temp) @@ -275,7 +275,7 @@ static int stm32_temp_init(const struct device *dev) .channels = BIT(data->adc_cfg.channel_id), .buffer = &data->sample_buffer, .buffer_size = sizeof(data->sample_buffer), - .resolution = 12U, + .resolution = CAL_RES, }; return 0; From 32260932f61678bb9a08c3e15da79eed780fc793 Mon Sep 17 00:00:00 2001 From: Mathieu Choplain Date: Tue, 20 Jan 2026 13:02:02 +0100 Subject: [PATCH 2447/3659] drivers: sensor: stm32_temp: move constants to instance configuration Various fields were stored in the instance data despite being initialized at compile-time to a constant value. Move these fields to the instance configuration instead. Signed-off-by: Mathieu Choplain --- drivers/sensor/st/stm32_temp/stm32_temp.c | 37 ++++++++++++----------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/drivers/sensor/st/stm32_temp/stm32_temp.c b/drivers/sensor/st/stm32_temp/stm32_temp.c index 5cbf4f13cb85..b260b49d7436 100644 --- a/drivers/sensor/st/stm32_temp/stm32_temp.c +++ b/drivers/sensor/st/stm32_temp/stm32_temp.c @@ -38,9 +38,6 @@ LOG_MODULE_REGISTER(stm32_temp, CONFIG_SENSOR_LOG_LEVEL); #endif struct stm32_temp_data { - const struct device *adc; - const struct adc_channel_cfg adc_cfg; - ADC_TypeDef *adc_base; struct adc_sequence adc_seq; struct k_mutex mutex; int16_t sample_buffer; @@ -48,6 +45,10 @@ struct stm32_temp_data { }; struct stm32_temp_config { + const struct device *adc; + struct adc_channel_cfg adc_cfg; + ADC_TypeDef *adc_base; + #if !defined(HAS_CALIBRATION) float average_slope; /** Unit: mV/°C */ int v25; /** Unit: mV */ @@ -125,7 +126,7 @@ static float convert_adc_sample_to_temperature(const struct device *dev) { struct stm32_temp_data *data = dev->data; const struct stm32_temp_config *cfg = dev->config; - const uint16_t vdda_mv = adc_ref_internal(data->adc); + const uint16_t vdda_mv = adc_ref_internal(cfg->adc); float temperature; #if !defined(HAS_CALIBRATION) @@ -209,6 +210,7 @@ static float convert_adc_sample_to_temperature(const struct device *dev) static int stm32_temp_sample_fetch(const struct device *dev, enum sensor_channel chan) { + const struct stm32_temp_config *cfg = dev->config; struct stm32_temp_data *data = dev->data; struct adc_sequence *sp = &data->adc_seq; int rc; @@ -218,25 +220,25 @@ static int stm32_temp_sample_fetch(const struct device *dev, enum sensor_channel } k_mutex_lock(&data->mutex, K_FOREVER); - pm_device_runtime_get(data->adc); + pm_device_runtime_get(cfg->adc); - rc = adc_channel_setup(data->adc, &data->adc_cfg); + rc = adc_channel_setup(cfg->adc, &cfg->adc_cfg); if (rc) { - LOG_DBG("Setup AIN%u got %d", data->adc_cfg.channel_id, rc); + LOG_DBG("Setup AIN%u got %d", cfg->adc_cfg.channel_id, rc); goto unlock; } - adc_enable_tempsensor_channel(data->adc_base); + adc_enable_tempsensor_channel(cfg->adc_base); - rc = adc_read(data->adc, sp); + rc = adc_read(cfg->adc, sp); if (rc == 0) { data->raw = data->sample_buffer; } - adc_disable_tempsensor_channel(data->adc_base); + adc_disable_tempsensor_channel(cfg->adc_base); unlock: - pm_device_runtime_put(data->adc); + pm_device_runtime_put(cfg->adc); k_mutex_unlock(&data->mutex); return rc; @@ -261,18 +263,19 @@ static DEVICE_API(sensor, stm32_temp_driver_api) = { static int stm32_temp_init(const struct device *dev) { + const struct stm32_temp_config *cfg = dev->config; struct stm32_temp_data *data = dev->data; struct adc_sequence *asp = &data->adc_seq; k_mutex_init(&data->mutex); - if (!device_is_ready(data->adc)) { - LOG_ERR("Device %s is not ready", data->adc->name); + if (!device_is_ready(cfg->adc)) { + LOG_ERR("Device %s is not ready", cfg->adc->name); return -ENODEV; } *asp = (struct adc_sequence){ - .channels = BIT(data->adc_cfg.channel_id), + .channels = BIT(cfg->adc_cfg.channel_id), .buffer = &data->sample_buffer, .buffer_size = sizeof(data->sample_buffer), .resolution = CAL_RES, @@ -298,7 +301,9 @@ BUILD_ASSERT(0, "ADC '" DT_NODE_FULL_NAME(DT_INST_IO_CHANNELS_CTLR(0)) "' needed */ #else -static struct stm32_temp_data stm32_temp_dev_data = { +static struct stm32_temp_data stm32_temp_dev_data; + +static const struct stm32_temp_config stm32_temp_dev_config = { .adc = DEVICE_DT_GET(DT_INST_IO_CHANNELS_CTLR(0)), .adc_base = (ADC_TypeDef *)DT_REG_ADDR(DT_INST_IO_CHANNELS_CTLR(0)), .adc_cfg = { @@ -308,9 +313,7 @@ static struct stm32_temp_data stm32_temp_dev_data = { .channel_id = DT_INST_IO_CHANNELS_INPUT(0), .differential = 0 }, -}; -static const struct stm32_temp_config stm32_temp_dev_config = { #if defined(HAS_CALIBRATION) .ts_cal1_addr = (const void *)DT_INST_PROP(0, ts_cal1_addr), .ts_cal1_temp = DT_INST_PROP(0, ts_cal1_temp), From bc9efec89675666ef9125722049db3c13f35db90 Mon Sep 17 00:00:00 2001 From: Mathieu Choplain Date: Tue, 20 Jan 2026 13:59:37 +0100 Subject: [PATCH 2448/3659] drivers: sensor: stm32_temp: use union as calibration info type MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Using a union enables accessing the calibration data using member names instead of an array index, which makes the code more readable. As long as the layout of struct { T m1; ... T mN; } and array A[N] is the same (implementation-specific?), usage of the union type as done should be Standard-compliant: accessing through either member of the union will use an lvalue with compatible type to the same underlying object, which is one of the allowed aliasing situations listed in §6.5.7 of N1548. Signed-off-by: Mathieu Choplain --- drivers/sensor/st/stm32_temp/stm32_temp.c | 33 ++++++++++++++--------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/drivers/sensor/st/stm32_temp/stm32_temp.c b/drivers/sensor/st/stm32_temp/stm32_temp.c index b260b49d7436..22a45e1346b9 100644 --- a/drivers/sensor/st/stm32_temp/stm32_temp.c +++ b/drivers/sensor/st/stm32_temp/stm32_temp.c @@ -37,6 +37,17 @@ LOG_MODULE_REGISTER(stm32_temp, CONFIG_SENSOR_LOG_LEVEL); #define HAS_CALIBRATION 1 #endif +union stm32_dietemp_calib_data { + uint16_t raw[MAX_CALIB_POINTS]; + + struct { + uint16_t ts_cal1; +#if defined(HAS_DUAL_CALIBRATION) + uint16_t ts_cal2; +#endif /* HAS_DUAL_CALIBRATION */ + }; +}; + struct stm32_temp_data { struct adc_sequence adc_seq; struct k_mutex mutex; @@ -94,12 +105,8 @@ static uint32_t fetch_mfg_data(const void *addr) return sys_read16((mem_addr_t)addr); } -/** - * @returns TS_CAL1 in calib_data[0] - * TS_CAL2 in calib_data[1] if applicable - */ static void read_calibration_data(const struct stm32_temp_config *cfg, - uint32_t calib_data[MAX_CALIB_POINTS]) + union stm32_dietemp_calib_data *cd) { #if defined(CONFIG_SOC_SERIES_STM32H5X) /* Disable the ICACHE to ensure all memory accesses are non-cacheable. @@ -109,9 +116,9 @@ static void read_calibration_data(const struct stm32_temp_config *cfg, sys_cache_instr_disable(); #endif /* CONFIG_SOC_SERIES_STM32H5X */ - calib_data[0] = fetch_mfg_data(cfg->ts_cal1_addr); + cd->raw[0] = fetch_mfg_data(cfg->ts_cal1_addr); #if defined(HAS_DUAL_CALIBRATION) - calib_data[1] = fetch_mfg_data(cfg->ts_cal2_addr); + cd->raw[1] = fetch_mfg_data(cfg->ts_cal2_addr); #endif @@ -156,9 +163,9 @@ static float convert_adc_sample_to_temperature(const struct device *dev) temperature /= cfg->average_slope; temperature += 25.0f; #else /* HAS_CALIBRATION */ - uint32_t calib[MAX_CALIB_POINTS]; + union stm32_dietemp_calib_data cd; - read_calibration_data(cfg, calib); + read_calibration_data(cfg, &cd); const float sense_data = ((float)vdda_mv / cfg->calib_vrefanalog) * data->raw; @@ -182,9 +189,9 @@ static float convert_adc_sample_to_temperature(const struct device *dev) float dividend; if (cfg->is_ntc) { - dividend = ((float)(calib[0] >> cfg->calib_data_shift) - sense_data); + dividend = ((float)(cd.ts_cal1 >> cfg->calib_data_shift) - sense_data); } else { - dividend = (sense_data - (calib[0] >> cfg->calib_data_shift)); + dividend = (sense_data - (cd.ts_cal1 >> cfg->calib_data_shift)); } temperature = (dividend / avg_slope_code) + cfg->ts_cal1_temp; @@ -198,9 +205,9 @@ static float convert_adc_sample_to_temperature(const struct device *dev) * (TS_CAL2 - TS_CAL1) */ const float slope = ((float)(cfg->ts_cal2_temp - cfg->ts_cal1_temp)) - / ((calib[1] - calib[0]) >> cfg->calib_data_shift); + / ((cd.ts_cal2 - cd.ts_cal1) >> cfg->calib_data_shift); - temperature = (slope * (sense_data - (calib[0] >> cfg->calib_data_shift))) + temperature = (slope * (sense_data - (cd.ts_cal1 >> cfg->calib_data_shift))) + cfg->ts_cal1_temp; #endif /* HAS_SINGLE_CALIBRATION */ #endif /* HAS_CALIBRATION */ From 4228409128450bb08ed8efc1973516df63d1b2a9 Mon Sep 17 00:00:00 2001 From: Mathieu Choplain Date: Tue, 20 Jan 2026 14:18:05 +0100 Subject: [PATCH 2449/3659] drivers: sensor: stm32_temp: read calibration data once during init Instead of reading calibration data (device-unique, but never changing!) as part of each conversion, perform the read once and cache the value. This notably avoids frequently an ICACHE disable/enable cycle on STM32H5, which is a somewhat slow operation. Signed-off-by: Mathieu Choplain --- drivers/sensor/st/stm32_temp/stm32_temp.c | 87 ++++++++++++----------- 1 file changed, 46 insertions(+), 41 deletions(-) diff --git a/drivers/sensor/st/stm32_temp/stm32_temp.c b/drivers/sensor/st/stm32_temp/stm32_temp.c index 22a45e1346b9..02ed4e906e56 100644 --- a/drivers/sensor/st/stm32_temp/stm32_temp.c +++ b/drivers/sensor/st/stm32_temp/stm32_temp.c @@ -51,6 +51,9 @@ union stm32_dietemp_calib_data { struct stm32_temp_data { struct adc_sequence adc_seq; struct k_mutex mutex; +#if defined(HAS_CALIBRATION) + union stm32_dietemp_calib_data calib_data; +#endif /* HAS_CALIBRATION */ int16_t sample_buffer; int16_t raw; /* raw adc Sensor value */ }; @@ -96,39 +99,6 @@ static inline void adc_disable_tempsensor_channel(ADC_TypeDef *adc) path & ~LL_ADC_PATH_INTERNAL_TEMPSENSOR); } -#if defined(HAS_CALIBRATION) -static uint32_t fetch_mfg_data(const void *addr) -{ - /* On all STM32 series, the calibration data is stored - * as 16-bit data in the manufacturing flash region - */ - return sys_read16((mem_addr_t)addr); -} - -static void read_calibration_data(const struct stm32_temp_config *cfg, - union stm32_dietemp_calib_data *cd) -{ -#if defined(CONFIG_SOC_SERIES_STM32H5X) - /* Disable the ICACHE to ensure all memory accesses are non-cacheable. - * This is required on STM32H5, where the manufacturing flash must be - * accessed in non-cacheable mode - otherwise, a bus error occurs. - */ - sys_cache_instr_disable(); -#endif /* CONFIG_SOC_SERIES_STM32H5X */ - - cd->raw[0] = fetch_mfg_data(cfg->ts_cal1_addr); -#if defined(HAS_DUAL_CALIBRATION) - cd->raw[1] = fetch_mfg_data(cfg->ts_cal2_addr); -#endif - - -#if defined(CONFIG_SOC_SERIES_STM32H5X) - /* Re-enable the ICACHE (unconditonally - it should always be turned on) */ - sys_cache_instr_enable(); -#endif /* CONFIG_SOC_SERIES_STM32H5X */ -} -#endif /* HAS_CALIBRATION */ - static float convert_adc_sample_to_temperature(const struct device *dev) { struct stm32_temp_data *data = dev->data; @@ -163,10 +133,7 @@ static float convert_adc_sample_to_temperature(const struct device *dev) temperature /= cfg->average_slope; temperature += 25.0f; #else /* HAS_CALIBRATION */ - union stm32_dietemp_calib_data cd; - - read_calibration_data(cfg, &cd); - + const union stm32_dietemp_calib_data *cd = &data->calib_data; const float sense_data = ((float)vdda_mv / cfg->calib_vrefanalog) * data->raw; #if defined(HAS_SINGLE_CALIBRATION) @@ -189,9 +156,9 @@ static float convert_adc_sample_to_temperature(const struct device *dev) float dividend; if (cfg->is_ntc) { - dividend = ((float)(cd.ts_cal1 >> cfg->calib_data_shift) - sense_data); + dividend = ((float)(cd->ts_cal1 >> cfg->calib_data_shift) - sense_data); } else { - dividend = (sense_data - (cd.ts_cal1 >> cfg->calib_data_shift)); + dividend = (sense_data - (cd->ts_cal1 >> cfg->calib_data_shift)); } temperature = (dividend / avg_slope_code) + cfg->ts_cal1_temp; @@ -205,9 +172,9 @@ static float convert_adc_sample_to_temperature(const struct device *dev) * (TS_CAL2 - TS_CAL1) */ const float slope = ((float)(cfg->ts_cal2_temp - cfg->ts_cal1_temp)) - / ((cd.ts_cal2 - cd.ts_cal1) >> cfg->calib_data_shift); + / ((cd->ts_cal2 - cd->ts_cal1) >> cfg->calib_data_shift); - temperature = (slope * (sense_data - (cd.ts_cal1 >> cfg->calib_data_shift))) + temperature = (slope * (sense_data - (cd->ts_cal1 >> cfg->calib_data_shift))) + cfg->ts_cal1_temp; #endif /* HAS_SINGLE_CALIBRATION */ #endif /* HAS_CALIBRATION */ @@ -268,6 +235,39 @@ static DEVICE_API(sensor, stm32_temp_driver_api) = { .channel_get = stm32_temp_channel_get, }; +#if defined(HAS_CALIBRATION) +static uint32_t fetch_mfg_data(const void *addr) +{ + /* On all STM32 series, the calibration data is stored + * as 16-bit data in the manufacturing flash region + */ + return sys_read16((mem_addr_t)addr); +} + +static void read_calibration_data(const struct stm32_temp_config *cfg, + union stm32_dietemp_calib_data *cd) +{ +#if defined(CONFIG_SOC_SERIES_STM32H5X) + /* Disable the ICACHE to ensure all memory accesses are non-cacheable. + * This is required on STM32H5, where the manufacturing flash must be + * accessed in non-cacheable mode - otherwise, a bus error occurs. + */ + sys_cache_instr_disable(); +#endif /* CONFIG_SOC_SERIES_STM32H5X */ + + cd->raw[0] = fetch_mfg_data(cfg->ts_cal1_addr); +#if defined(HAS_DUAL_CALIBRATION) + cd->raw[1] = fetch_mfg_data(cfg->ts_cal2_addr); +#endif + + +#if defined(CONFIG_SOC_SERIES_STM32H5X) + /* Re-enable the ICACHE (unconditonally - it should always be turned on) */ + sys_cache_instr_enable(); +#endif /* CONFIG_SOC_SERIES_STM32H5X */ +} +#endif /* HAS_CALIBRATION */ + static int stm32_temp_init(const struct device *dev) { const struct stm32_temp_config *cfg = dev->config; @@ -281,6 +281,11 @@ static int stm32_temp_init(const struct device *dev) return -ENODEV; } +#if defined(HAS_CALIBRATION) + /* Read calibration data once during init */ + read_calibration_data(cfg, &data->calib_data); +#endif + *asp = (struct adc_sequence){ .channels = BIT(cfg->adc_cfg.channel_id), .buffer = &data->sample_buffer, From 2d7b42ddc540fe8855ebef0e1e3bf8c653e95520 Mon Sep 17 00:00:00 2001 From: Grzegorz Chwierut Date: Wed, 21 Jan 2026 12:13:38 +0100 Subject: [PATCH 2450/3659] tests: boot: mcuboot_direct_xip: escape plus signs in regex patterns The plus signs in version strings need to be escaped with double backslashes when used in regex patterns for the test harness. This ensures proper pattern matching during test execution. Signed-off-by: Grzegorz Chwierut --- tests/boot/mcuboot_direct_xip/testcase.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/boot/mcuboot_direct_xip/testcase.yaml b/tests/boot/mcuboot_direct_xip/testcase.yaml index d546688af16f..0707aa2ddb23 100644 --- a/tests/boot/mcuboot_direct_xip/testcase.yaml +++ b/tests/boot/mcuboot_direct_xip/testcase.yaml @@ -21,8 +21,8 @@ tests: type: multi_line regex: - "Starting Direct-XIP bootloader" - - "Primary slot: version=0.0.0+0" - - "Secondary slot: version=0.0.0+0" + - "Primary slot: version=0.0.0\\+0" + - "Secondary slot: version=0.0.0\\+0" - "Image 0 loaded from the primary slot" - "Bootloader chainload address offset" - "Image version: v0.0.0" @@ -36,7 +36,7 @@ tests: regex: - "Starting Direct-XIP bootloader" - "Image 0 Primary slot: Image not found" - - "Secondary slot: version=0.0.0+0" + - "Secondary slot: version=0.0.0\\+0" - "Image 0 loaded from the secondary slot" - "Bootloader chainload address offset" - "Image version: v0.0.0" From 0a8564a9b93d1ff139df716ce635a7532d57d733 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Thu, 22 Jan 2026 10:42:50 +0100 Subject: [PATCH 2451/3659] dts: auxdisplay: add auxdisplay_0 label to sparkfun,serlcd example MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is technically a workaround for a limitation in the Pygments DTS lexer causing the highlighting to break when rendering this example in the documentation, but this is also an excuse to plug the label that is used in the official auxdisplay sample. Signed-off-by: Benjamin Cabé --- dts/bindings/auxdisplay/sparkfun,serlcd.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dts/bindings/auxdisplay/sparkfun,serlcd.yaml b/dts/bindings/auxdisplay/sparkfun,serlcd.yaml index d718d5706877..d72421f53fba 100644 --- a/dts/bindings/auxdisplay/sparkfun,serlcd.yaml +++ b/dts/bindings/auxdisplay/sparkfun,serlcd.yaml @@ -46,7 +46,7 @@ properties: examples: - | &i2c1 { - serlcd@72 { + auxdisplay_0: serlcd@72 { compatible = "sparkfun,serlcd"; reg = <0x72>; columns = <16>; From 2d0139aa22c06387799497f6b64f7988dc5a4aa3 Mon Sep 17 00:00:00 2001 From: Adrian Bonislawski Date: Thu, 22 Jan 2026 10:42:24 +0100 Subject: [PATCH 2452/3659] MAINTAINERS: add myself as collaborator to Intel Xtensa platforms Intel Platforms (Xtensa) Drivers: DAI Signed-off-by: Adrian Bonislawski --- MAINTAINERS.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index 1656a133f92d..022b29120e38 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -1520,6 +1520,7 @@ Documentation Infrastructure: - lgirdwood - iuliana-prodan - dbaluta + - abonislawski files: - drivers/dai/ - doc/hardware/peripherals/audio/dai.rst @@ -3061,6 +3062,7 @@ Intel Platforms (Xtensa): - jxstelter - marcinszkudlinski - nashif + - abonislawski files: - boards/intel/adsp/ - soc/intel/intel_adsp/ From 195a3ff63ae7d54e4644f6d69dd9c1fb6fc94059 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Thu, 22 Jan 2026 08:26:15 +0000 Subject: [PATCH 2453/3659] tests: dfu: img_util: Disable variant image for slot 1 build Fixes an issue whereby a variant of the slot 1 image is built... which would occupy the same slot that the test is building for, therefore disable using the new experimental variant image Kconfig in this configuration Signed-off-by: Jamie McCrae --- tests/subsys/dfu/img_util/sysbuild_slot1.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/subsys/dfu/img_util/sysbuild_slot1.conf b/tests/subsys/dfu/img_util/sysbuild_slot1.conf index 06c8ad027910..2c9a6189cdcf 100644 --- a/tests/subsys/dfu/img_util/sysbuild_slot1.conf +++ b/tests/subsys/dfu/img_util/sysbuild_slot1.conf @@ -1,2 +1,3 @@ SB_CONFIG_BOOTLOADER_MCUBOOT=y SB_CONFIG_MCUBOOT_MODE_DIRECT_XIP=y +SB_CONFIG_MCUBOOT_DIRECT_XIP_GENERATE_VARIANT=n From 53e6b7d54392069f5d06d0b5f0327f5f8b0bdf84 Mon Sep 17 00:00:00 2001 From: Johann Fischer Date: Wed, 21 Jan 2026 18:54:22 +0100 Subject: [PATCH 2454/3659] MAINTAINERS: remove jfischer-no from display collaborators I do not have any plans in the near future to collaborate in this area. Signed-off-by: Johann Fischer --- MAINTAINERS.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index 022b29120e38..03479399096c 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -1181,7 +1181,6 @@ Display drivers: maintainers: - JarmouniA collaborators: - - jfischer-no - danieldegrasse - VynDragon - KATE-WANG-NXP From 59a57722aee0273079177e604a74f9a05f22f58a Mon Sep 17 00:00:00 2001 From: Flavio Ceolin Date: Tue, 20 Jan 2026 09:21:02 -0800 Subject: [PATCH 2455/3659] pm: Fix wrong type promotion In pm_system_suspend there is a possible invalid type promotion in sys_clock_set_timeout(MAX(0, ticks - exit_latency_ticks), true); ticks is int32_t and exit_latency_ticks is uint32_t consequently ticks is promoted to uint32_t resulting in a possible underflow and setting a wrong value in sys_clock_set_timeout(). Fixes #100005 Coverity CID: 535628 Signed-off-by: Flavio Ceolin --- subsys/pm/pm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/pm/pm.c b/subsys/pm/pm.c index 062c7bd623a0..13ed1ee7f0e0 100644 --- a/subsys/pm/pm.c +++ b/subsys/pm/pm.c @@ -214,7 +214,7 @@ bool pm_system_suspend(int32_t kernel_ticks) * is not passed as the next timeout. * */ - sys_clock_set_timeout(MAX(0, ticks - exit_latency_ticks), true); + sys_clock_set_timeout(MAX(0, (int64_t)ticks - (int64_t)exit_latency_ticks), true); } /* From 1350164d67e316068b779752a931a7cabfc629a0 Mon Sep 17 00:00:00 2001 From: Muhammad Waleed Badar Date: Tue, 20 Jan 2026 21:22:11 +0500 Subject: [PATCH 2456/3659] drivers: uart: bcm2711: fix poll_in uart_bcm2711_poll_in() incorrectly returned the received byte instead of writing it to the provided buffer. Update the implementation to store the character in *c and return 0 on success, matching the UART poll_in API. Signed-off-by: Muhammad Waleed Badar --- drivers/serial/uart_bcm2711.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/serial/uart_bcm2711.c b/drivers/serial/uart_bcm2711.c index 415fe2de54ce..6f07ea32a1b7 100644 --- a/drivers/serial/uart_bcm2711.c +++ b/drivers/serial/uart_bcm2711.c @@ -154,7 +154,10 @@ static int uart_bcm2711_poll_in(const struct device *dev, unsigned char *c) ; } - return sys_read32(uart_data->uart_addr + BCM2711_MU_IO) & 0xFF; + /* got a character */ + *c = sys_read32(uart_data->uart_addr + BCM2711_MU_IO) & 0xFF; + + return 0; } #ifdef CONFIG_UART_INTERRUPT_DRIVEN From df13dcc560382e4fc04efc23a634da92f4cea2f7 Mon Sep 17 00:00:00 2001 From: Scott Worley Date: Tue, 20 Jan 2026 11:03:27 -0500 Subject: [PATCH 2457/3659] dts: arm: microchip: mec: Fix MEC1653B code sram base address Microchip MEC1653B has 416KB of SRAM. ARM ICCM SRAM is 356KB starting at 0xC0000. ARM DCCM SRAM is 64KB starting at 0x118000. Chip DTS file had incorrect ICCM starting address. Signed-off-by: Scott Worley --- dts/arm/microchip/mec/mec5_mec1653bnsz.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dts/arm/microchip/mec/mec5_mec1653bnsz.dtsi b/dts/arm/microchip/mec/mec5_mec1653bnsz.dtsi index aee3d83bd2b2..1f7ead33331e 100644 --- a/dts/arm/microchip/mec/mec5_mec1653bnsz.dtsi +++ b/dts/arm/microchip/mec/mec5_mec1653bnsz.dtsi @@ -10,7 +10,7 @@ / { flash0: flash@b0000 { - reg = <0x000b0000 0x58000>; + reg = <0x000c0000 0x58000>; }; sram0: memory@118000 { From 0455416c52643462603aaa5446c5f9f45cdcc4e2 Mon Sep 17 00:00:00 2001 From: Maciej Perkowski Date: Tue, 20 Jan 2026 17:03:10 +0100 Subject: [PATCH 2458/3659] maintainers: Add fundakol as twister collaborator Lukasz Fundakowski is a python expert with an interest in testing frameworks and coding standards. He is a valuable reviewer with attention to details. He had a major impact on design and implementation of the pytest plugin for twister. Signed-off-by: Maciej Perkowski --- MAINTAINERS.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index 03479399096c..c0433ae44d7b 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -5277,6 +5277,7 @@ Twister: - gchwier - LukaszMrugala - KamilxPaszkiet + - fundakol files: - scripts/twister - scripts/schemas/twister/ From c7fb653046808c80cf1d4102ab90d20dea73c75a Mon Sep 17 00:00:00 2001 From: Miika Karanki Date: Tue, 20 Jan 2026 15:04:31 +0200 Subject: [PATCH 2459/3659] serial: uart_native_pty: send UART_RX_DISABLED event When uart_rx_disable is called, or rx gets otherwise disabled, UART_RX_DISABLED event should be emitted. Signed-off-by: Miika Karanki --- drivers/serial/uart_native_pty.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/serial/uart_native_pty.c b/drivers/serial/uart_native_pty.c index 029ea47f92bb..abfdc7181bbe 100644 --- a/drivers/serial/uart_native_pty.c +++ b/drivers/serial/uart_native_pty.c @@ -402,6 +402,11 @@ static void native_pty_uart_async_poll_function(void *arg1, void *arg2, void *ar k_sleep(K_MSEC(10)); } } + + if (data->async.user_callback) { + evt.type = UART_RX_DISABLED; + data->async.user_callback(data->async.dev, &evt, data->async.user_data); + } } static int np_uart_rx_buf_rsp(const struct device *dev, uint8_t *buf, size_t len) From 5a0f33b31fa0fcfe7d2e862ad8d5f9cfed89869e Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Tue, 20 Jan 2026 12:33:12 +0100 Subject: [PATCH 2460/3659] net: sockets: tls: Enforce minimum TLS version Enforce the minimum TLS version on mbed TLS, based on the protocol version provided by the application when creating socket. This ensures that when application creates a TLS 1.3 socket, mbed TLS won't downgrade the session to TLS 1.2 for instance. Signed-off-by: Robert Lubos --- subsys/net/lib/sockets/sockets_tls.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/subsys/net/lib/sockets/sockets_tls.c b/subsys/net/lib/sockets/sockets_tls.c index cd81204d1837..04a599e5af72 100644 --- a/subsys/net/lib/sockets/sockets_tls.c +++ b/subsys/net/lib/sockets/sockets_tls.c @@ -1321,6 +1321,24 @@ static int tls_mbedtls_init(struct tls_context *context, bool is_server) } tls_set_max_frag_len(&context->config, context->type); + switch (context->tls_version) { + case NET_IPPROTO_TLS_1_3: + mbedtls_ssl_conf_min_tls_version(&context->config, MBEDTLS_SSL_VERSION_TLS1_3); + break; + case NET_IPPROTO_TLS_1_2: + case NET_IPPROTO_DTLS_1_2: + mbedtls_ssl_conf_min_tls_version(&context->config, MBEDTLS_SSL_VERSION_TLS1_2); + break; + case NET_IPPROTO_TLS_1_0: + case NET_IPPROTO_TLS_1_1: + case NET_IPPROTO_DTLS_1_0: + /* Nothing to do */ + break; + default: + NET_ASSERT(false, "Unknown (D)TLS version, cannot specify minimum requirement"); + break; + } + #if defined(MBEDTLS_SSL_RENEGOTIATION) mbedtls_ssl_conf_legacy_renegotiation(&context->config, MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE); From 8a5c82ae1d307037315cf33eee19e6d816a248b1 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Tue, 20 Jan 2026 12:40:38 +0100 Subject: [PATCH 2461/3659] doc: net: sockets: tls: Document the meaning of the protocol version Document explicitly that the TLS version passed in the protocol parameter matters and specifies the minimum TLS version to use for the socket. Signed-off-by: Robert Lubos --- doc/connectivity/networking/api/sockets.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/connectivity/networking/api/sockets.rst b/doc/connectivity/networking/api/sockets.rst index ea33ec1a6c21..24dcfa0c622a 100644 --- a/doc/connectivity/networking/api/sockets.rst +++ b/doc/connectivity/networking/api/sockets.rst @@ -153,6 +153,9 @@ A secure socket can be created by specifying secure protocol type, for instance: sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TLS_1_2); +The protocol version specified when creating the secure socket indicates the +minimum TLS version used for the TLS session. + Once created, it can be configured with socket options. For instance, the CA certificate and hostname can be set: From a34409f0065a13e6be6fd8f897d2388f634cba57 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Tue, 20 Jan 2026 13:17:41 +0100 Subject: [PATCH 2462/3659] doc: migration-guide-4.4: Document secure socket version enforcement Document that TLS version passed to a zsock_socket() function is no longer ignored and is now enforced as the minimum TLS version for the TLS session. Signed-off-by: Robert Lubos --- doc/releases/migration-guide-4.4.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/releases/migration-guide-4.4.rst b/doc/releases/migration-guide-4.4.rst index 50ff539a76e6..8240315e057e 100644 --- a/doc/releases/migration-guide-4.4.rst +++ b/doc/releases/migration-guide-4.4.rst @@ -704,6 +704,9 @@ Networking handle this status in the handler callback to properly reset resource state after successful response transmission. +* The protocol version passed to :c:func:`zsock_socket` when creating a secure socket is now + enforced as the minimum TLS version to use for the TLS session. + Modem ***** From 8f5f337419b502d511518f03a1b641aaf39378b2 Mon Sep 17 00:00:00 2001 From: Yangbo Lu Date: Tue, 20 Jan 2026 14:40:38 +0800 Subject: [PATCH 2463/3659] dts: arm: nxp_imx93_m33: add lpi2c dts nodes Added lpi2c dts nodes. Signed-off-by: Yangbo Lu --- dts/arm/nxp/nxp_imx93_m33.dtsi | 92 +++++++++++++++++++++++++++++++++- 1 file changed, 90 insertions(+), 2 deletions(-) diff --git a/dts/arm/nxp/nxp_imx93_m33.dtsi b/dts/arm/nxp/nxp_imx93_m33.dtsi index 4c61033a2c27..061dc2bbb556 100644 --- a/dts/arm/nxp/nxp_imx93_m33.dtsi +++ b/dts/arm/nxp/nxp_imx93_m33.dtsi @@ -1,12 +1,12 @@ /* - * Copyright 2024-2025 NXP - * + * SPDX-FileCopyrightText: Copyright 2024-2026 NXP * SPDX-License-Identifier: Apache-2.0 */ #include #include #include +#include #include #include @@ -42,6 +42,72 @@ reg = <0x20000000 DT_SIZE_K(124)>; }; + lpi2c3: i2c@42530000 { + compatible = "nxp,lpi2c"; + clock-frequency = ; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x42530000 0x4000>; + interrupts = <62 0>; + clocks = <&ccm IMX_CCM_LPI2C3_CLK 0x70 10>; + status = "disabled"; + }; + + lpi2c4: i2c@42540000 { + compatible = "nxp,lpi2c"; + clock-frequency = ; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x42540000 0x4000>; + interrupts = <63 0>; + clocks = <&ccm IMX_CCM_LPI2C4_CLK 0x80 24>; + status = "disabled"; + }; + + lpi2c5: i2c@426b0000 { + compatible = "nxp,lpi2c"; + clock-frequency = ; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x426b0000 0x4000>; + interrupts = <195 0>; + clocks = <&ccm IMX_CCM_LPI2C5_CLK 0x80 24>; + status = "disabled"; + }; + + lpi2c6: i2c@426c0000 { + compatible = "nxp,lpi2c"; + clock-frequency = ; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x426c0000 0x4000>; + interrupts = <196 0>; + clocks = <&ccm IMX_CCM_LPI2C6_CLK 0x80 24>; + status = "disabled"; + }; + + lpi2c7: i2c@426d0000 { + compatible = "nxp,lpi2c"; + clock-frequency = ; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x426d0000 0x4000>; + interrupts = <197 0>; + clocks = <&ccm IMX_CCM_LPI2C7_CLK 0x80 24>; + status = "disabled"; + }; + + lpi2c8: i2c@426e0000 { + compatible = "nxp,lpi2c"; + clock-frequency = ; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x426e0000 0x4000>; + interrupts = <198 0>; + clocks = <&ccm IMX_CCM_LPI2C8_CLK 0x80 24>; + status = "disabled"; + }; + mu1: mailbox@44220000 { compatible = "nxp,mbox-imx-mu"; reg = <0x44220000 DT_SIZE_K(4)>; @@ -50,6 +116,28 @@ status = "disabled"; }; + lpi2c1: i2c@44340000 { + compatible = "nxp,lpi2c"; + clock-frequency = ; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x44340000 0x4000>; + interrupts = <13 0>; + clocks = <&ccm IMX_CCM_LPI2C1_CLK 0x70 6>; + status = "disabled"; + }; + + lpi2c2: i2c@44350000 { + compatible = "nxp,lpi2c"; + clock-frequency = ; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x44350000 0x4000>; + interrupts = <14 0>; + clocks = <&ccm IMX_CCM_LPI2C2_CLK 0x70 8>; + status = "disabled"; + }; + iomuxc: iomuxc@443c0000 { compatible = "nxp,imx-iomuxc"; reg = <0x443c0000 DT_SIZE_K(64)>; From 41f296bc012f9128ab4dcbecb1225c235ebaf23e Mon Sep 17 00:00:00 2001 From: Yangbo Lu Date: Tue, 20 Jan 2026 16:44:29 +0800 Subject: [PATCH 2464/3659] boards: nxp: imx93_evk_mimx9352_m33: enable lpi2c2 Enabled lpi2c2, and verified with I2C shell commands. uart:~$ i2c scan i2c@44350000 0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: -- -- 22 -- -- 25 -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- 34 -- -- -- -- -- -- -- -- -- -- -- 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 70: -- -- -- -- -- -- -- -- 3 devices found on i2c@44350000 uart:~$ uart:~$ i2c read i2c@44350000 0x22 0x4 1 00000000: ff uart:~$ i2c write i2c@44350000 0x22 0x4 0x0 1 uart:~$ i2c read i2c@44350000 0x22 0x4 1 00000000: 00 Signed-off-by: Yangbo Lu --- boards/nxp/imx93_evk/imx93_evk_mimx9352_m33.dts | 10 ++++++++-- boards/nxp/imx93_evk/imx93_evk_mimx9352_m33.yaml | 1 + 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/boards/nxp/imx93_evk/imx93_evk_mimx9352_m33.dts b/boards/nxp/imx93_evk/imx93_evk_mimx9352_m33.dts index fbab194989f8..87ca01471f92 100644 --- a/boards/nxp/imx93_evk/imx93_evk_mimx9352_m33.dts +++ b/boards/nxp/imx93_evk/imx93_evk_mimx9352_m33.dts @@ -1,6 +1,5 @@ /* - * Copyright 2024-2025 NXP - * + * SPDX-FileCopyrightText: Copyright 2024-2026 NXP * SPDX-License-Identifier: Apache-2.0 */ @@ -72,6 +71,13 @@ pinctrl-names = "default"; }; +&lpi2c2 { + status = "okay"; + clock-frequency = ; + pinctrl-0 = <&i2c2_default>; + pinctrl-names = "default"; +}; + &sar_adc1 { status = "okay"; }; diff --git a/boards/nxp/imx93_evk/imx93_evk_mimx9352_m33.yaml b/boards/nxp/imx93_evk/imx93_evk_mimx9352_m33.yaml index 62a2c3f06ec8..0f69285d14df 100644 --- a/boards/nxp/imx93_evk/imx93_evk_mimx9352_m33.yaml +++ b/boards/nxp/imx93_evk/imx93_evk_mimx9352_m33.yaml @@ -15,4 +15,5 @@ supported: - uart - pwm - adc + - i2c vendor: nxp From db5ec5f58fdea13cb0cd7e02b206241fd48635d7 Mon Sep 17 00:00:00 2001 From: Bill Waters Date: Fri, 16 Jan 2026 16:48:41 -0800 Subject: [PATCH 2465/3659] dts: arm: infineon: edge: pse84: ITCM/DTCM - There was a mistake with the CM33 core. It does not have ITCM/DTCM. Only the CM55 core does. - Also enabled ITCM/DTCM in the cm55 board file. Signed-off-by: Bill Waters --- .../kit_pse84_eval/kit_pse84_eval_m55.dts | 2 ++ dts/arm/infineon/edge/pse84/pse84.cm55.dtsi | 12 +++++++ dts/arm/infineon/edge/pse84/pse84.dtsi | 34 ------------------- 3 files changed, 14 insertions(+), 34 deletions(-) diff --git a/boards/infineon/kit_pse84_eval/kit_pse84_eval_m55.dts b/boards/infineon/kit_pse84_eval/kit_pse84_eval_m55.dts index bf62ee0fa668..7710376534c5 100644 --- a/boards/infineon/kit_pse84_eval/kit_pse84_eval_m55.dts +++ b/boards/infineon/kit_pse84_eval/kit_pse84_eval_m55.dts @@ -32,6 +32,8 @@ zephyr,sram = &m55_data; zephyr,console = &uart2; zephyr,shell-uart = &uart2; + zephyr,dtcm = &dtcm; + zephyr,itcm = &itcm; }; power-states { diff --git a/dts/arm/infineon/edge/pse84/pse84.cm55.dtsi b/dts/arm/infineon/edge/pse84/pse84.cm55.dtsi index 6d52796e6bda..455509b21118 100644 --- a/dts/arm/infineon/edge/pse84/pse84.cm55.dtsi +++ b/dts/arm/infineon/edge/pse84/pse84.cm55.dtsi @@ -19,6 +19,18 @@ clock-frequency = <400000000>; }; }; + + dtcm: dtcm@20000000 { + compatible = "zephyr,memory-region", "arm,dtcm"; + reg = <0x20000000 DT_SIZE_K(256)>; + zephyr,memory-region = "DTCM"; + }; + + itcm: itcm@0 { + compatible = "zephyr,memory-region", "arm,itcm"; + reg = <0x00000000 DT_SIZE_K(256)>; + zephyr,memory-region = "ITCM"; + }; }; &gpio_prt0 { diff --git a/dts/arm/infineon/edge/pse84/pse84.dtsi b/dts/arm/infineon/edge/pse84/pse84.dtsi index 3f41755e1841..e7352a1c79c0 100644 --- a/dts/arm/infineon/edge/pse84/pse84.dtsi +++ b/dts/arm/infineon/edge/pse84/pse84.dtsi @@ -13,40 +13,6 @@ reg = <0x24000000 0x100000>; }; - dtcm { - #address-cells = <1>; - #size-cells = <1>; - - dtcm_m33: dtcm_m33@48040000 { - compatible = "zephyr,memory-region", "arm,dtcm"; - reg = <0x48040000 DT_SIZE_K(256)>; - zephyr,memory-region = "DTCM_M33"; - }; - - dtcm_m55: dtcm_m55@20000000 { - compatible = "zephyr,memory-region", "arm,dtcm"; - reg = <0x20000000 DT_SIZE_K(256)>; - zephyr,memory-region = "DTCM_M55"; - }; - }; - - itcm { - #address-cells = <1>; - #size-cells = <1>; - - itcm_m33: itcm_m33@48000000 { - compatible = "zephyr,memory-region", "arm,itcm"; - reg = <0x48000000 DT_SIZE_K(256)>; - zephyr,memory-region = "ITCM_M33"; - }; - - itcm_m55: itcm_m55@0 { - compatible = "zephyr,memory-region", "arm,itcm"; - reg = <0x00000000 DT_SIZE_K(256)>; - zephyr,memory-region = "ITCM_M55"; - }; - }; - rram { #address-cells = <1>; #size-cells = <1>; From 77f933e7d3dfec9619bd5321d78ed0b974a3f41a Mon Sep 17 00:00:00 2001 From: Vincent Tardy Date: Thu, 20 Nov 2025 11:19:09 +0100 Subject: [PATCH 2466/3659] drivers: bluetooth: hci: fix RAM allocation in stm32wbax ble hci driver Remove useless allocated RAM in stm32wbax ble hci driver. Signed-off-by: Vincent Tardy --- drivers/bluetooth/hci/hci_stm32wba.c | 38 +--------------------------- 1 file changed, 1 insertion(+), 37 deletions(-) diff --git a/drivers/bluetooth/hci/hci_stm32wba.c b/drivers/bluetooth/hci/hci_stm32wba.c index a931c53e4936..faeac56d4886 100644 --- a/drivers/bluetooth/hci/hci_stm32wba.c +++ b/drivers/bluetooth/hci/hci_stm32wba.c @@ -40,24 +40,6 @@ static K_SEM_DEFINE(hci_sem, 1, 1); #define BLE_CTRLR_STACK_BUFFER_SIZE 300 -#define MBLOCK_COUNT (BLE_MBLOCKS_CALC(PREP_WRITE_LIST_SIZE, \ - CFG_BLE_ATT_MTU_MAX, \ - CFG_BLE_NUM_LINK) \ - + CFG_BLE_MBLOCK_COUNT_MARGIN) - -#define BLE_DYN_ALLOC_SIZE \ - (BLE_TOTAL_BUFFER_SIZE(CFG_BLE_NUM_LINK, \ - MBLOCK_COUNT, \ - (CFG_BLE_EATT_BEARER_PER_LINK * CFG_BLE_NUM_LINK))) - -/* 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)) - #if defined(CONFIG_BT_HCI_SETUP) /* Bluetooth LE public STM32WBA default device address (if udn not available) */ static bt_addr_t bd_addr_dflt = {{0x65, 0x43, 0x21, 0x1E, 0x08, 0x00}}; @@ -109,9 +91,6 @@ struct aci_reset { static uint8_t bt_hci_state = BT_HCI_STATE_DEINIT; -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; #ifdef CONFIG_PM_DEVICE @@ -436,22 +415,7 @@ static int bt_ble_ctlr_init(void) { BleStack_init_t init_params_p = {0}; - init_params_p.numAttrRecord = CFG_BLE_NUM_GATT_ATTRIBUTES; - init_params_p.numAttrServ = CFG_BLE_NUM_GATT_SERVICES; - init_params_p.attrValueArrSize = CFG_BLE_ATT_VALUE_ARRAY_SIZE; - init_params_p.prWriteListSize = CFG_BLE_ATTR_PREPARE_WRITE_VALUE_SIZE; - init_params_p.attMtu = CFG_BLE_ATT_MTU_MAX; - init_params_p.max_coc_nbr = CFG_BLE_COC_NBR_MAX; - init_params_p.max_coc_mps = CFG_BLE_COC_MPS_MAX; - init_params_p.max_coc_initiator_nbr = CFG_BLE_COC_INITIATOR_NBR_MAX; - init_params_p.numOfLinks = CFG_BLE_NUM_LINK; - 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 = (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; + init_params_p.options = BLE_OPTIONS_LL_ONLY | BLE_OPTIONS_EXTENDED_ADV; if (BleStack_Init(&init_params_p) != BLE_STATUS_SUCCESS) { return -EIO; From 86d55a8d81563f17a03a70a586c6eedaa5a7921e Mon Sep 17 00:00:00 2001 From: Vincent Tardy Date: Wed, 14 Jan 2026 11:32:34 +0100 Subject: [PATCH 2467/3659] drivers: bluetooth: hci: remove RAM allocation in send process Remove local Tx buffer allocated in the bt_hci_stm32wba_send() function. Get Event buffer resource to store data returned by lower layer and provide it to Host in case of Tx packet is an HCI Command type. Signed-off-by: Vincent Tardy --- drivers/bluetooth/hci/hci_stm32wba.c | 44 +++++++++++++++++++++++----- 1 file changed, 37 insertions(+), 7 deletions(-) diff --git a/drivers/bluetooth/hci/hci_stm32wba.c b/drivers/bluetooth/hci/hci_stm32wba.c index faeac56d4886..0e33a0ed9d1d 100644 --- a/drivers/bluetooth/hci/hci_stm32wba.c +++ b/drivers/bluetooth/hci/hci_stm32wba.c @@ -38,8 +38,6 @@ struct hci_data { static K_SEM_DEFINE(hci_sem, 1, 1); -#define BLE_CTRLR_STACK_BUFFER_SIZE 300 - #if defined(CONFIG_BT_HCI_SETUP) /* Bluetooth LE public STM32WBA default device address (if udn not available) */ static bt_addr_t bd_addr_dflt = {{0x65, 0x43, 0x21, 0x1E, 0x08, 0x00}}; @@ -387,7 +385,9 @@ uint8_t BLECB_Indication(const uint8_t *data, uint16_t length, static int bt_hci_stm32wba_send(const struct device *dev, struct net_buf *buf) { uint16_t event_length; - uint8_t tx_buffer[BLE_CTRLR_STACK_BUFFER_SIZE]; + struct hci_data *hci = dev->data; + struct net_buf *evt_buf = NULL; + uint8_t *data; ARG_UNUSED(dev); @@ -395,13 +395,43 @@ static int bt_hci_stm32wba_send(const struct device *dev, struct net_buf *buf) LOG_DBG("buf %p type %u len %u", buf, buf->data[0], buf->len); - memcpy(&tx_buffer, buf->data, buf->len); + if (buf->data[0] == BT_HCI_H4_CMD) { + /* + * Get Event Buffer which will be used to store Tx buffer and store + * the response event which is a Command Complete Event or a + * Command Status Event. + */ + evt_buf = bt_buf_get_evt(BT_HCI_EVT_CMD_COMPLETE, false, K_FOREVER); + if (!evt_buf) { + LOG_ERR("No available event buffers!"); + __ASSERT_NO_MSG(evt_buf); + return -ENOMEM; + } + /* + * Reset the event buffer length and copy the data packet to transmit + * in the event buffer resource. + */ + evt_buf->len = 0; + net_buf_add_mem(evt_buf, buf->data, buf->len); + data = evt_buf->data; + } else { + data = buf->data; + } - event_length = BleStack_Request(tx_buffer); + event_length = BleStack_Request(data); LOG_DBG("event_length: %u", event_length); - if (event_length) { - receive_data(dev, (uint8_t *)&tx_buffer, (size_t)event_length, NULL, 0); + if (evt_buf) { + if (event_length) { + /* + * Update the length of the event packet returned by + * the BleStack_Request() function. + */ + evt_buf->len = event_length; + hci->recv(dev, evt_buf); + } else { + net_buf_unref(evt_buf); + } } k_sem_give(&hci_sem); From 6ebf1963e8d1608133305faa030cd1a0895fff3f Mon Sep 17 00:00:00 2001 From: Maochen Wang Date: Wed, 14 Jan 2026 19:14:06 +0800 Subject: [PATCH 2468/3659] manifest: fix DPP remain_on_channel wait timeout The remain_on_channel callback triggers cookie_event, which checks pending_remain_on_channel before giving drv_resp_sem. Previously, pending_remain_on_channel was set after calling dev_ops->remain_on_channel, causing drv_resp_sem to timeout. Move the pending_remain_on_channel assignment before invoking dev_ops->remain_on_channel to ensure proper synchronization. Signed-off-by: Maochen Wang --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index ff2f3230cbe4..cf1eafd0dc20 100644 --- a/west.yml +++ b/west.yml @@ -291,7 +291,7 @@ manifest: - hal - name: hostap path: modules/lib/hostap - revision: 1a2fbb7910f23822a785294eab9f4922c6119711 + revision: 7c5d886f4b1afd6d00192e346268f03f5f44354c - name: liblc3 revision: 48bbd3eacd36e99a57317a0a4867002e0b09e183 path: modules/lib/liblc3 From 9d817c799232fc870dc2aeec2bfd99db4c0f6741 Mon Sep 17 00:00:00 2001 From: Albort Xue Date: Tue, 20 Jan 2026 15:48:34 +0800 Subject: [PATCH 2469/3659] drivers: flash: flash_mcux_flexspi_nor: fix QER S2B1v5 status reg case The JESD216_DW15_QER_VAL_S2B1v5 case had incorrect status register read/write logic. It was reading only SR2 but writing both SR1 and SR2, which could corrupt SR1 if not read first. Merge the S2B1v5 case with S2B1v1/v4 cases since they all set bit 1 of SR2. Update the common path to properly handle both single-byte (SR2 only) and two-byte (SR1+SR2) read/write operations by: - Reading SR1 first when rd_size is 2, saving it temporarily - Reading SR2 using the scratch command - Combining both bytes with SR2 in the upper byte when needed - Writing the combined value with the QE bit set Remove the now-redundant S2B1v5-specific case and simplify the LUT sequence to read SR2 directly instead of reading SR1 first. Signed-off-by: Albort Xue --- drivers/flash/flash_mcux_flexspi_nor.c | 52 +++++++++++++------------- 1 file changed, 25 insertions(+), 27 deletions(-) diff --git a/drivers/flash/flash_mcux_flexspi_nor.c b/drivers/flash/flash_mcux_flexspi_nor.c index 32f182b63f8c..e0b10aa6b576 100644 --- a/drivers/flash/flash_mcux_flexspi_nor.c +++ b/drivers/flash/flash_mcux_flexspi_nor.c @@ -597,17 +597,12 @@ static int flash_flexspi_nor_quad_enable(struct flash_flexspi_nor_data *data, return 0; case JESD216_DW15_QER_VAL_S2B1v1: case JESD216_DW15_QER_VAL_S2B1v4: + case JESD216_DW15_QER_VAL_S2B1v5: /* Install read and write status command */ flexspi_lut[SCRATCH_CMD][0] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, SPI_NOR_CMD_RDSR, - kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x1); - flexspi_lut[SCRATCH_CMD][1] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_JUMP_ON_CS, kFLEXSPI_1PAD, 0x2, - kFLEXSPI_Command_JUMP_ON_CS, kFLEXSPI_1PAD, 0x2); - flexspi_lut[SCRATCH_CMD][2] = FLEXSPI_LUT_SEQ( kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, SPI_NOR_CMD_RDSR2, kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x1); - flexspi_lut[SCRATCH_CMD][3] = FLEXSPI_LUT_SEQ( + flexspi_lut[SCRATCH_CMD][1] = FLEXSPI_LUT_SEQ( kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0x0, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0x0); flexspi_lut[SCRATCH_CMD2][0] = FLEXSPI_LUT_SEQ( @@ -647,20 +642,6 @@ static int flash_flexspi_nor_quad_enable(struct flash_flexspi_nor_data *data, rd_size = 1; wr_size = 1; break; - case JESD216_DW15_QER_VAL_S2B1v5: - /* Install read and write status command */ - flexspi_lut[SCRATCH_CMD][0] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, SPI_NOR_CMD_RDSR2, - kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x1); - flexspi_lut[SCRATCH_CMD2][0] = FLEXSPI_LUT_SEQ( - kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, SPI_NOR_CMD_WRSR, - kFLEXSPI_Command_WRITE_SDR, kFLEXSPI_1PAD, 0x1); - - /* Set bit 1 of status register 2 */ - bit = BIT(9); - rd_size = 1; - wr_size = 2; - break; case JESD216_DW15_QER_VAL_S2B1v6: /* Install read and write status command */ flexspi_lut[SCRATCH_CMD][0] = FLEXSPI_LUT_SEQ( @@ -686,23 +667,40 @@ static int flash_flexspi_nor_quad_enable(struct flash_flexspi_nor_data *data, if (ret < 0) { return ret; } - transfer.dataSize = rd_size; + + uint8_t tmp_save = 0; + + if (rd_size == 2) { + /* Read first status register byte */ + transfer.dataSize = 1; + transfer.seqIndex = READ_STATUS_REG; + transfer.cmdType = kFLEXSPI_Read; + ret = memc_flexspi_transfer(&data->controller, &transfer); + if (ret < 0) { + return ret; + } + tmp_save = (uint8_t)(buffer & 0xFF); + } + + /* Read second status register byte */ + transfer.dataSize = 1; transfer.seqIndex = SCRATCH_CMD; transfer.cmdType = kFLEXSPI_Read; - /* Read status register */ ret = memc_flexspi_transfer(&data->controller, &transfer); if (ret < 0) { return ret; } + + if (rd_size == 2) { + /* Combine both bytes: SR2 in upper byte, SR1 in lower byte */ + buffer = ((buffer & 0xFF) << 8) | tmp_save; + } /* Enable write */ ret = flash_flexspi_nor_write_enable(data); if (ret < 0) { return ret; } - if (qer == JESD216_DW15_QER_VAL_S2B1v5) { - /* Left shift buffer by a byte */ - buffer = buffer << 8; - } + buffer |= bit; transfer.dataSize = wr_size; transfer.seqIndex = SCRATCH_CMD2; From 5a06cbdf82737a9792b47fe53594fe1f51dad1e0 Mon Sep 17 00:00:00 2001 From: Albort Xue Date: Tue, 20 Jan 2026 18:05:01 +0800 Subject: [PATCH 2470/3659] boards: mcx_nx4x_evk: correct W25Q64JV JEDEC ID The JEDEC ID for the Winbond W25Q64JV flash on the MCX NX4X EVK board was incorrectly specified as [ef 40 17]. According to the W25Q64JV datasheet, the correct JEDEC ID is [ef 60 17], where: - ef: Winbond manufacturer ID - 60: Memory type (W25Q series) - 17: Capacity (64 Mbit) Update the jedec-id property to match the actual flash device. Signed-off-by: Albort Xue --- boards/nxp/mcx_nx4x_evk/mcx_nx4x_evk.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boards/nxp/mcx_nx4x_evk/mcx_nx4x_evk.dtsi b/boards/nxp/mcx_nx4x_evk/mcx_nx4x_evk.dtsi index 8332a3eea471..bc8a92d8d1f6 100644 --- a/boards/nxp/mcx_nx4x_evk/mcx_nx4x_evk.dtsi +++ b/boards/nxp/mcx_nx4x_evk/mcx_nx4x_evk.dtsi @@ -172,7 +172,7 @@ nxp_8080_touch_panel_i2c: &flexcomm2_lpi2c2 { size = ; reg = <0>; spi-max-frequency = ; - jedec-id = [ef 40 17]; + jedec-id = [ef 60 17]; erase-block-size = ; write-block-size = <1>; cs-interval-unit = <1>; From 565bb115499d8fb48fde745c5b77aa5c5e77dd24 Mon Sep 17 00:00:00 2001 From: Anil Ozrenk Date: Fri, 19 Dec 2025 10:39:18 +0300 Subject: [PATCH 2471/3659] cmake: xcc: prioritize board-specific toolchain version Change the toolchain version resolution order to check for board-specific TOOLCHAIN_VER_${NORMALIZED_BOARD_TARGET} first, falling back to the generic TOOLCHAIN_VER if not defined. Now if we want to use various boards lots of them uses same version but fewer ones differ. We won't have to define TOOLCHAIN_VER for every board. Signed-off-by: Anil Ozrenk --- cmake/toolchain/xcc/common.cmake | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/cmake/toolchain/xcc/common.cmake b/cmake/toolchain/xcc/common.cmake index 973b3bad97fc..12324d65d2c6 100644 --- a/cmake/toolchain/xcc/common.cmake +++ b/cmake/toolchain/xcc/common.cmake @@ -7,16 +7,9 @@ if(NOT EXISTS ${XTENSA_TOOLCHAIN_PATH}) message(FATAL_ERROR "Nothing found at XTENSA_TOOLCHAIN_PATH: '${XTENSA_TOOLCHAIN_PATH}'") endif() -zephyr_get(TOOLCHAIN_VER) -if(DEFINED TOOLCHAIN_VER) - set(XTENSA_TOOLCHAIN_VER ${TOOLCHAIN_VER}) -else() - zephyr_get(TOOLCHAIN_VER_${NORMALIZED_BOARD_TARGET}) - if(DEFINED TOOLCHAIN_VER_${NORMALIZED_BOARD_TARGET}) - set(XTENSA_TOOLCHAIN_VER ${TOOLCHAIN_VER_${NORMALIZED_BOARD_TARGET}}) - else() - message(FATAL "Environment variable TOOLCHAIN_VER must be set or given as -DTOOLCHAIN_VER=") - endif() +zephyr_get(XTENSA_TOOLCHAIN_VER VAR TOOLCHAIN_VER_${NORMALIZED_BOARD_TARGET} TOOLCHAIN_VER) +if(NOT DEFINED XTENSA_TOOLCHAIN_VER) + message(FATAL "Environment variable TOOLCHAIN_VER must be set or given as -DTOOLCHAIN_VER=") endif() zephyr_get(XTENSA_CORE_${NORMALIZED_BOARD_TARGET}) From e97559b6f2d93f9f5e418399d37bab19a66e89db Mon Sep 17 00:00:00 2001 From: Antoine Pradoux Date: Tue, 16 Dec 2025 16:17:26 +0100 Subject: [PATCH 2472/3659] dts: arm: st: Add RTC node for STM32U3 series - Add the rtc node for the stm32u3 - This enables RTC support for STM32U3 platforms once enabled Signed-off-by: Antoine Pradoux --- dts/arm/st/u3/stm32u3.dtsi | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/dts/arm/st/u3/stm32u3.dtsi b/dts/arm/st/u3/stm32u3.dtsi index 662a7936e919..8ac7b32e8980 100644 --- a/dts/arm/st/u3/stm32u3.dtsi +++ b/dts/arm/st/u3/stm32u3.dtsi @@ -401,6 +401,16 @@ status = "disabled"; }; + rtc: rtc@40007800 { + compatible = "st,stm32-rtc"; + reg = <0x40007800 0x400>; + interrupts = <2 0>; + clocks = <&rcc STM32_CLOCK(APB1, 30)>; + prescaler = <32768>; + alarms-count = <2>; + status = "disabled"; + }; + sai1_a: sai1@40015404 { compatible = "st,stm32-sai"; #address-cells = <1>; From c10819f93a4d4f8f7aca44e701513783837542b0 Mon Sep 17 00:00:00 2001 From: Antoine Pradoux Date: Tue, 16 Dec 2025 16:26:42 +0100 Subject: [PATCH 2473/3659] drivers: rtc: stm32: Add STM32U3 support for RTC alarm, clock & counter Extend RTC driver to handle STM32U3 series specifics: - Include STM32U3X in condition where RTC Alarm event is not routed to EXTI - Use LL_RCC_RTC_ClockEnable call for STM32U3 instead of LL_RCC_EnableRTC - Adapt counter_stm32_rtc driver for STM32U3 clock and EXTI handling Signed-off-by: Antoine Pradoux --- drivers/counter/counter_stm32_rtc.c | 32 ++++++++++++++++++++++------- drivers/rtc/rtc_stm32.c | 26 +++++++++++++++-------- 2 files changed, 42 insertions(+), 16 deletions(-) diff --git a/drivers/counter/counter_stm32_rtc.c b/drivers/counter/counter_stm32_rtc.c index 358e17abedc9..4bac7c26aefe 100644 --- a/drivers/counter/counter_stm32_rtc.c +++ b/drivers/counter/counter_stm32_rtc.c @@ -372,10 +372,15 @@ static int rtc_stm32_start(const struct device *dev) z_stm32_hsem_lock(CFG_HW_RCC_SEMID, HSEM_LOCK_DEFAULT_RETRY); stm32_backup_domain_enable_access(); +#ifdef CONFIG_SOC_SERIES_STM32U3X + /* STM32U3 series uses LL_RCC_RTC_ClockEnable instead of LL_RCC_EnableRTC */ + LL_RCC_RTC_ClockEnable(); +#else LL_RCC_EnableRTC(); +#endif /* CONFIG_SOC_SERIES_STM32U3X */ stm32_backup_domain_disable_access(); z_stm32_hsem_unlock(CFG_HW_RCC_SEMID); -#endif +#endif /* CONFIG_SOC_SERIES_STM32WBAX || CONFIG_SOC_SERIES_STM32U5X */ return 0; } @@ -397,10 +402,15 @@ static int rtc_stm32_stop(const struct device *dev) z_stm32_hsem_lock(CFG_HW_RCC_SEMID, HSEM_LOCK_DEFAULT_RETRY); stm32_backup_domain_enable_access(); +#ifdef CONFIG_SOC_SERIES_STM32U3X + /* STM32U3 series uses LL_RCC_RTC_ClockDisable instead of LL_RCC_DisableRTC */ + LL_RCC_RTC_ClockDisable(); +#else LL_RCC_DisableRTC(); +#endif /* CONFIG_SOC_SERIES_STM32U3X */ stm32_backup_domain_disable_access(); z_stm32_hsem_unlock(CFG_HW_RCC_SEMID); -#endif +#endif /* CONFIG_SOC_SERIES_STM32WBAX || CONFIG_SOC_SERIES_STM32U5X */ return 0; } @@ -724,8 +734,10 @@ void rtc_stm32_isr(const struct device *dev) || defined(CONFIG_SOC_SERIES_STM32L5X) \ || defined(CONFIG_SOC_SERIES_STM32H5X) LL_EXTI_ClearRisingFlag_0_31(RTC_EXTI_LINE); -#elif defined(CONFIG_SOC_SERIES_STM32U5X) || defined(CONFIG_SOC_SERIES_STM32WBAX) - /* in STM32U5 family RTC is not connected to EXTI */ +#elif defined(CONFIG_SOC_SERIES_STM32U3X) \ + || defined(CONFIG_SOC_SERIES_STM32U5X) \ + || defined(CONFIG_SOC_SERIES_STM32WBAX) + /* RTC is not connected to EXTI for these SoC series */ #else LL_EXTI_ClearFlag_0_31(RTC_EXTI_LINE); #endif @@ -771,8 +783,13 @@ static int rtc_stm32_init(const struct device *dev) } #if !defined(CONFIG_SOC_SERIES_STM32WBAX) +#ifdef CONFIG_SOC_SERIES_STM32U3X + /* STM32U3 series uses LL_RCC_RTC_ClockEnable instead of LL_RCC_EnableRTC */ + LL_RCC_RTC_ClockEnable(); +#else LL_RCC_EnableRTC(); -#endif +#endif /* CONFIG_SOC_SERIES_STM32U3X */ +#endif /* !CONFIG_SOC_SERIES_STM32WBAX */ z_stm32_hsem_unlock(CFG_HW_RCC_SEMID); @@ -799,8 +816,9 @@ static int rtc_stm32_init(const struct device *dev) #if defined(CONFIG_SOC_SERIES_STM32H7X) && defined(CONFIG_CPU_CORTEX_M4) LL_C2_EXTI_EnableIT_0_31(RTC_EXTI_LINE); LL_EXTI_EnableRisingTrig_0_31(RTC_EXTI_LINE); -#elif defined(CONFIG_SOC_SERIES_STM32U5X) || defined(CONFIG_SOC_SERIES_STM32WBAX) - /* in STM32U5 family RTC is not connected to EXTI */ +#elif defined(CONFIG_SOC_SERIES_STM32U3X) || defined(CONFIG_SOC_SERIES_STM32U5X) || \ + defined(CONFIG_SOC_SERIES_STM32WBAX) + /* RTC is not connected to EXTI for these SoC series */ #else LL_EXTI_EnableIT_0_31(RTC_EXTI_LINE); LL_EXTI_EnableRisingTrig_0_31(RTC_EXTI_LINE); diff --git a/drivers/rtc/rtc_stm32.c b/drivers/rtc/rtc_stm32.c index 6e94cb0b516e..dad243361754 100644 --- a/drivers/rtc/rtc_stm32.c +++ b/drivers/rtc/rtc_stm32.c @@ -132,8 +132,9 @@ struct rtc_stm32_data { static inline void exti_enable_rtc_alarm_it(uint32_t line_num) { -#if defined(CONFIG_SOC_SERIES_STM32U5X) || defined(CONFIG_SOC_SERIES_STM32WBAX) - /* in STM32U5 & STM32WBAX series, RTC Alarm event is not routed to EXTI */ +#if defined(CONFIG_SOC_SERIES_STM32U3X) || defined(CONFIG_SOC_SERIES_STM32U5X) || \ + defined(CONFIG_SOC_SERIES_STM32WBAX) + /* in STM32U3, STM32U5 & STM32WBAX series, RTC Alarm event is not routed to EXTI */ #else int ret; @@ -146,8 +147,9 @@ static inline void exti_enable_rtc_alarm_it(uint32_t line_num) static inline void exti_clear_rtc_alarm_flag(uint32_t line_num) { -#if defined(CONFIG_SOC_SERIES_STM32U5X) || defined(CONFIG_SOC_SERIES_STM32WBAX) - /* in STM32U5 & STM32WBAX series, RTC Alarm (EXTI event) is not routed to EXTI */ +#if defined(CONFIG_SOC_SERIES_STM32U3X) || defined(CONFIG_SOC_SERIES_STM32U5X) || \ + defined(CONFIG_SOC_SERIES_STM32WBAX) + /* in STM32U3, STM32U5 & STM32WBAX series, RTC Alarm (EXTI event) is not routed to EXTI */ #else if (stm32_exti_is_pending(line_num)) { stm32_exti_clear_pending(line_num); @@ -502,18 +504,24 @@ static int rtc_stm32_init(const struct device *dev) } /* - * On STM32WBAX series, there is no bit in BCDR register to enable RTC. - * Enabling RTC is done directly via the RCC APB register bit. - * On STM32WB0 series, LL_RCC_EnableRTC is not provided by STM32CubeWB0, - * but RTC IP clock has already been turned on - skip the call as well. + * On certain series, there is no bit in BCDR register to enable RTC; + * a single bit in RCC controls both the RTC and bus interface. On + * such series, the LL_RCC_EnableRTC function is usually not provided + * by the STM32Cube package, but it's fine to skip calling it since + * the RTC is already accessible thanks to clock_control_on() above. */ #if !defined(CONFIG_SOC_SERIES_STM32WBAX) && !defined(CONFIG_SOC_SERIES_STM32WB0X) z_stm32_hsem_lock(CFG_HW_RCC_SEMID, HSEM_LOCK_DEFAULT_RETRY); +#ifdef CONFIG_SOC_SERIES_STM32U3X + /* STM32U3 series uses LL_RCC_RTC_ClockEnable instead of LL_RCC_EnableRTC */ + LL_RCC_RTC_ClockEnable(); +#else LL_RCC_EnableRTC(); +#endif /* CONFIG_SOC_SERIES_STM32U3X */ z_stm32_hsem_unlock(CFG_HW_RCC_SEMID); -#endif /* CONFIG_SOC_SERIES_STM32WBAX */ +#endif /* !STM32WBAX && !STM32WB0X */ err = rtc_stm32_configure(dev); From 254c6e837798821624b8a46229556df2ecd04d50 Mon Sep 17 00:00:00 2001 From: Antoine Pradoux Date: Tue, 16 Dec 2025 16:21:41 +0100 Subject: [PATCH 2474/3659] boards: st: Enable RTC support on nucleo_u385rg_q board - Activate the RTC node in the device tree by enabling its clocks and setting its status to okay - Add 'rtc' to the supported features in the board YAML configuration Signed-off-by: Antoine Pradoux --- boards/st/nucleo_u385rg_q/nucleo_u385rg_q.dts | 6 ++++++ boards/st/nucleo_u385rg_q/nucleo_u385rg_q.yaml | 1 + 2 files changed, 7 insertions(+) diff --git a/boards/st/nucleo_u385rg_q/nucleo_u385rg_q.dts b/boards/st/nucleo_u385rg_q/nucleo_u385rg_q.dts index 1902855d8383..29e49b34f127 100644 --- a/boards/st/nucleo_u385rg_q/nucleo_u385rg_q.dts +++ b/boards/st/nucleo_u385rg_q/nucleo_u385rg_q.dts @@ -208,6 +208,12 @@ status = "okay"; }; +&rtc { + clocks = <&rcc STM32_CLOCK(APB1, 30)>, + <&rcc STM32_SRC_LSE RTC_SEL(1)>; + status = "okay"; +}; + zephyr_udc0: &usb { pinctrl-0 = <&usb_dm_pa11 &usb_dp_pa12>; pinctrl-names = "default"; diff --git a/boards/st/nucleo_u385rg_q/nucleo_u385rg_q.yaml b/boards/st/nucleo_u385rg_q/nucleo_u385rg_q.yaml index 058d6c327312..f6c5bfaa5853 100644 --- a/boards/st/nucleo_u385rg_q/nucleo_u385rg_q.yaml +++ b/boards/st/nucleo_u385rg_q/nucleo_u385rg_q.yaml @@ -22,5 +22,6 @@ supported: - watchdog - pwm - counter + - rtc ram: 256 flash: 1024 From 2cc03f791d7d5bef4b02d05af321cd6ae92d76d0 Mon Sep 17 00:00:00 2001 From: Antoine Pradoux Date: Tue, 16 Dec 2025 16:30:17 +0100 Subject: [PATCH 2475/3659] tests: rtc_api: Add RTC test configuration for nucleo_u385rg_q board - Add a new test configuration file enabling RTC calibration and alarm features for the nucleo_u385rg_q board - Add the nucleo_u385rg_q device tree overlay defining the RTC alias Signed-off-by: Antoine Pradoux --- tests/drivers/rtc/rtc_api/boards/nucleo_u385rg_q.conf | 2 ++ .../rtc/rtc_api/boards/nucleo_u385rg_q.overlay | 11 +++++++++++ 2 files changed, 13 insertions(+) create mode 100644 tests/drivers/rtc/rtc_api/boards/nucleo_u385rg_q.conf create mode 100644 tests/drivers/rtc/rtc_api/boards/nucleo_u385rg_q.overlay diff --git a/tests/drivers/rtc/rtc_api/boards/nucleo_u385rg_q.conf b/tests/drivers/rtc/rtc_api/boards/nucleo_u385rg_q.conf new file mode 100644 index 000000000000..8c6c114ee41f --- /dev/null +++ b/tests/drivers/rtc/rtc_api/boards/nucleo_u385rg_q.conf @@ -0,0 +1,2 @@ +CONFIG_RTC_CALIBRATION=y +CONFIG_RTC_ALARM=y diff --git a/tests/drivers/rtc/rtc_api/boards/nucleo_u385rg_q.overlay b/tests/drivers/rtc/rtc_api/boards/nucleo_u385rg_q.overlay new file mode 100644 index 000000000000..087d88680a18 --- /dev/null +++ b/tests/drivers/rtc/rtc_api/boards/nucleo_u385rg_q.overlay @@ -0,0 +1,11 @@ +/* + * Copyright (c) 2026 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + rtc = &rtc; + }; +}; From 4a914bf28157a9a255b4060799736b08e486541a Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Thu, 11 Dec 2025 14:23:31 +0100 Subject: [PATCH 2476/3659] Bluetooth: Host: ATT: Do not use bt_addr_le_to_str when CONFIG_LOG=n Do not use bt_addr_le_to_str() when CONFIG_LOG=n. Signed-off-by: Vinayak Kariappa Chettimada --- subsys/bluetooth/host/att.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/subsys/bluetooth/host/att.c b/subsys/bluetooth/host/att.c index eed079b08fc7..4c9a255653cb 100644 --- a/subsys/bluetooth/host/att.c +++ b/subsys/bluetooth/host/att.c @@ -376,7 +376,6 @@ static struct net_buf *att_create_rsp_pdu(struct bt_att_chan *chan, uint8_t op); static void att_disconnect(struct bt_att_chan *chan) { - char addr[BT_ADDR_LE_STR_LEN]; int err; /* In rare circumstances we are "forced" to disconnect the ATT bearer and the ACL. @@ -385,8 +384,7 @@ static void att_disconnect(struct bt_att_chan *chan) * invalid */ - bt_addr_le_to_str(bt_conn_get_dst(chan->att->conn), addr, sizeof(addr)); - LOG_DBG("ATT disconnecting device %s", addr); + LOG_DBG("ATT disconnecting device %s", bt_addr_le_str(bt_conn_get_dst(chan->att->conn))); bt_att_disconnected(&chan->chan.chan); @@ -3195,12 +3193,11 @@ static void att_chan_detach(struct bt_att_chan *chan) static void att_timeout(struct k_work *work) { - char addr[BT_ADDR_LE_STR_LEN]; struct k_work_delayable *dwork = k_work_delayable_from_work(work); struct bt_att_chan *chan = CONTAINER_OF(dwork, struct bt_att_chan, timeout_work); - bt_addr_le_to_str(bt_conn_get_dst(chan->att->conn), addr, sizeof(addr)); - LOG_ERR("ATT Timeout for device %s. Disconnecting...", addr); + LOG_ERR("ATT Timeout for device %s. Disconnecting...", + bt_addr_le_str(bt_conn_get_dst(chan->att->conn))); /* BLUETOOTH SPECIFICATION Version 4.2 [Vol 3, Part F] page 480: * From 2db3f7978f53dda8937b1bc9e9d49f4023f86a70 Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Thu, 11 Dec 2025 12:51:14 +0100 Subject: [PATCH 2477/3659] Bluetooth: Host: settings without snprintk use Update settings implementation for not reusing the OS snprintk implementation with CONFIG_PRINTK=n. Signed-off-by: Vinayak Kariappa Chettimada --- subsys/bluetooth/host/settings.c | 112 +++++++++++++++++++++++-------- subsys/bluetooth/host/settings.h | 2 +- 2 files changed, 84 insertions(+), 30 deletions(-) diff --git a/subsys/bluetooth/host/settings.c b/subsys/bluetooth/host/settings.c index 84b4f1eb4b6a..c93df66c3f77 100644 --- a/subsys/bluetooth/host/settings.c +++ b/subsys/bluetooth/host/settings.c @@ -33,28 +33,45 @@ LOG_MODULE_REGISTER(bt_settings); #if defined(CONFIG_BT_SETTINGS_USE_PRINTK) -void bt_settings_encode_key(char *path, size_t path_size, const char *subsys, +int bt_settings_encode_key(char *path, size_t path_size, const char *subsys, const bt_addr_le_t *addr, const char *key) { + int err; + if (key) { - snprintk(path, path_size, - "bt/%s/%02x%02x%02x%02x%02x%02x%u/%s", subsys, - addr->a.val[5], addr->a.val[4], addr->a.val[3], - addr->a.val[2], addr->a.val[1], addr->a.val[0], - addr->type, key); + err = snprintk(path, path_size, "bt/%s/%02x%02x%02x%02x%02x%02x%u/%s", subsys, + addr->a.val[5], addr->a.val[4], addr->a.val[3], addr->a.val[2], + addr->a.val[1], addr->a.val[0], addr->type, key); } else { - snprintk(path, path_size, - "bt/%s/%02x%02x%02x%02x%02x%02x%u", subsys, - addr->a.val[5], addr->a.val[4], addr->a.val[3], - addr->a.val[2], addr->a.val[1], addr->a.val[0], - addr->type); + err = snprintk(path, path_size, "bt/%s/%02x%02x%02x%02x%02x%02x%u", subsys, + addr->a.val[5], addr->a.val[4], addr->a.val[3], addr->a.val[2], + addr->a.val[1], addr->a.val[0], addr->type); + } + + if (err < 0) { + return -EINVAL; } LOG_DBG("Encoded path %s", path); + + return 0; } -#else -void bt_settings_encode_key(char *path, size_t path_size, const char *subsys, - const bt_addr_le_t *addr, const char *key) + +static int bt_settings_encode_key_no_addr(char *path, size_t path_size, const char *key) +{ + int err; + + err = snprintk(path, path_size, "bt/%s", key); + if (err < 0) { + return -EINVAL; + } + + return 0; +} + +#else /* !CONFIG_BT_SETTINGS_USE_PRINTK */ +int bt_settings_encode_key(char *path, size_t path_size, const char *subsys, + const bt_addr_le_t *addr, const char *key) { size_t len = 3; @@ -100,8 +117,41 @@ void bt_settings_encode_key(char *path, size_t path_size, const char *subsys, } LOG_DBG("Encoded path %s", path); + + return 0; } -#endif + +static int bt_settings_encode_key_no_addr(char *path, size_t path_size, const char *key) +{ + size_t len = 3; + + /* Skip if path_size is less than 3; strlen("bt/") */ + if (len < path_size) { + /* Key format: + * "bt/", "/" is optional + */ + strcpy(path, "bt/"); + + /* Concatenate key as much the free space permits */ + strncpy(&path[len], key, path_size - len); + len = strlen(path); + + /* If path string is full, always null terminate at path_size */ + if (len >= path_size) { + /* Truncate string */ + path[path_size - 1] = '\0'; + } + + } else if (path_size > 0) { + /* path_size not sufficient for "bt/" */ + *path = '\0'; + } + + LOG_DBG("Encoded path %s", path); + + return 0; +} +#endif /* !CONFIG_BT_SETTINGS_USE_PRINTK */ int bt_settings_decode_key(const char *key, bt_addr_le_t *addr) { @@ -324,21 +374,23 @@ __weak void bt_testing_settings_delete_hook(const char *key) int bt_settings_store(const char *key, uint8_t id, const bt_addr_le_t *addr, const void *value, size_t val_len) { - int err; - char id_str[4]; char key_str[BT_SETTINGS_KEY_MAX]; + char id_str[4]; + int err; if (addr) { if (id) { u8_to_dec(id_str, sizeof(id_str), id); } - bt_settings_encode_key(key_str, sizeof(key_str), key, addr, (id ? id_str : NULL)); + err = bt_settings_encode_key(key_str, sizeof(key_str), key, addr, + (id ? id_str : NULL)); } else { - err = snprintk(key_str, sizeof(key_str), "bt/%s", key); - if (err < 0) { - return -EINVAL; - } + err = bt_settings_encode_key_no_addr(key_str, sizeof(key_str), key); + } + + if (err != 0) { + return err; } if (IS_ENABLED(CONFIG_BT_TESTING)) { @@ -350,21 +402,23 @@ int bt_settings_store(const char *key, uint8_t id, const bt_addr_le_t *addr, con int bt_settings_delete(const char *key, uint8_t id, const bt_addr_le_t *addr) { - int err; - char id_str[4]; char key_str[BT_SETTINGS_KEY_MAX]; + char id_str[4]; + int err; if (addr) { if (id) { u8_to_dec(id_str, sizeof(id_str), id); } - bt_settings_encode_key(key_str, sizeof(key_str), key, addr, (id ? id_str : NULL)); + err = bt_settings_encode_key(key_str, sizeof(key_str), key, addr, + (id ? id_str : NULL)); } else { - err = snprintk(key_str, sizeof(key_str), "bt/%s", key); - if (err < 0) { - return -EINVAL; - } + err = bt_settings_encode_key_no_addr(key_str, sizeof(key_str), key); + } + + if (err != 0) { + return err; } if (IS_ENABLED(CONFIG_BT_TESTING)) { diff --git a/subsys/bluetooth/host/settings.h b/subsys/bluetooth/host/settings.h index 526d850f70ab..c56ca69f9ed6 100644 --- a/subsys/bluetooth/host/settings.h +++ b/subsys/bluetooth/host/settings.h @@ -32,7 +32,7 @@ void bt_testing_settings_store_hook(const char *key, const void *value, size_t v void bt_testing_settings_delete_hook(const char *key); /* Helpers for keys containing a bdaddr */ -void bt_settings_encode_key(char *path, size_t path_size, const char *subsys, +int bt_settings_encode_key(char *path, size_t path_size, const char *subsys, const bt_addr_le_t *addr, const char *key); int bt_settings_decode_key(const char *key, bt_addr_le_t *addr); From d8f3e43b204b34fb74380be8f0c763cfad426c88 Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Thu, 11 Dec 2025 12:51:14 +0100 Subject: [PATCH 2478/3659] Bluetooth: Host: Rework settings without snprintk use Rework settings implementation for not reusing the OS snprintk implementation with CONFIG_PRINTK=n. Signed-off-by: Vinayak Kariappa Chettimada --- subsys/bluetooth/host/settings.c | 111 ++++++++++++++++--------------- 1 file changed, 58 insertions(+), 53 deletions(-) diff --git a/subsys/bluetooth/host/settings.c b/subsys/bluetooth/host/settings.c index c93df66c3f77..0c1f86a458c4 100644 --- a/subsys/bluetooth/host/settings.c +++ b/subsys/bluetooth/host/settings.c @@ -24,6 +24,7 @@ #include "common/bt_settings_commit.h" #include "common/bt_str.h" +#include "common/assert.h" #include "hci_core.h" #include "settings.h" #include "sys/types.h" @@ -75,45 +76,51 @@ int bt_settings_encode_key(char *path, size_t path_size, const char *subsys, { size_t len = 3; - /* Skip if path_size is less than 3; strlen("bt/") */ + /* path_size is less than 3; strlen("bt/") */ + BT_ASSERT(path_size >= len); + + /* Key format: + * "bt///", "/" is optional + */ + strcpy(path, "bt/"); + + /* Concatenate subsys as much the free space permits */ + strncpy(&path[len], subsys, (path_size - len)); + + /* Postfix '/' if there is free space */ + len = strlen(path); if (len < path_size) { - /* Key format: - * "bt///", "/" is optional - */ - strcpy(path, "bt/"); - strncpy(&path[len], subsys, path_size - len); - len = strlen(path); - if (len < path_size) { - path[len] = '/'; - len++; - } + path[len] = '/'; + len++; + } - for (int8_t i = 5; i >= 0 && len < path_size; i--) { - len += bin2hex(&addr->a.val[i], 1, &path[len], - path_size - len); - } + /* Concatenate addr as much the free space permits */ + for (int8_t i = 5; i >= 0 && len < path_size; i--) { + len += bin2hex(&addr->a.val[i], 1, &path[len], + path_size - len); + } - if (len < path_size) { - /* Type can be either BT_ADDR_LE_PUBLIC or - * BT_ADDR_LE_RANDOM (value 0 or 1) - */ - path[len] = '0' + addr->type; - len++; - } + /* Postfix addr type if there is free space */ + if (len < path_size) { + /* Type can be either BT_ADDR_LE_PUBLIC or + * BT_ADDR_LE_RANDOM (value 0 or 1) + */ + path[len] = '0' + addr->type; + len++; + } - if (key && len < path_size) { - path[len] = '/'; - len++; - strncpy(&path[len], key, path_size - len); - len += strlen(&path[len]); - } + /* Postfix '/' and concatenate key as much the free space permits */ + if ((key != NULL) && (len < path_size)) { + path[len] = '/'; + len++; + strncpy(&path[len], key, path_size - len); + len += strlen(&path[len]); + } - if (len >= path_size) { - /* Truncate string */ - path[path_size - 1] = '\0'; - } - } else if (path_size > 0) { - *path = '\0'; + /* If path string is full, always null terminate at path_size */ + if (len >= path_size) { + /* Truncate string */ + path[path_size - 1] = '\0'; } LOG_DBG("Encoded path %s", path); @@ -125,26 +132,22 @@ static int bt_settings_encode_key_no_addr(char *path, size_t path_size, const ch { size_t len = 3; - /* Skip if path_size is less than 3; strlen("bt/") */ - if (len < path_size) { - /* Key format: - * "bt/", "/" is optional - */ - strcpy(path, "bt/"); + /* path_size is less than 3; strlen("bt/") */ + BT_ASSERT(path_size >= len); - /* Concatenate key as much the free space permits */ - strncpy(&path[len], key, path_size - len); - len = strlen(path); + /* Key format: + * "bt/" + */ + strcpy(path, "bt/"); - /* If path string is full, always null terminate at path_size */ - if (len >= path_size) { - /* Truncate string */ - path[path_size - 1] = '\0'; - } + /* Concatenate key as much the free space permits */ + strncpy(&path[len], key, path_size - len); + len = strlen(path); - } else if (path_size > 0) { - /* path_size not sufficient for "bt/" */ - *path = '\0'; + /* If path string is full, always null terminate at path_size */ + if (len >= path_size) { + /* Truncate string */ + path[path_size - 1] = '\0'; } LOG_DBG("Encoded path %s", path); @@ -375,10 +378,11 @@ int bt_settings_store(const char *key, uint8_t id, const bt_addr_le_t *addr, con size_t val_len) { char key_str[BT_SETTINGS_KEY_MAX]; - char id_str[4]; int err; if (addr) { + char id_str[4]; + if (id) { u8_to_dec(id_str, sizeof(id_str), id); } @@ -403,10 +407,11 @@ int bt_settings_store(const char *key, uint8_t id, const bt_addr_le_t *addr, con int bt_settings_delete(const char *key, uint8_t id, const bt_addr_le_t *addr) { char key_str[BT_SETTINGS_KEY_MAX]; - char id_str[4]; int err; if (addr) { + char id_str[4]; + if (id) { u8_to_dec(id_str, sizeof(id_str), id); } From d98c2cf0d8e04683251b5c6d5c3341ee9262a249 Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Thu, 11 Dec 2025 12:51:14 +0100 Subject: [PATCH 2479/3659] Bluetooth: Host: Rework settings without snprintk to return error Rework settings implementation for not reusing the OS snprintk implementation with CONFIG_PRINTK=n and to return error if path buffer is insufficient. Signed-off-by: Vinayak Kariappa Chettimada --- subsys/bluetooth/host/settings.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/subsys/bluetooth/host/settings.c b/subsys/bluetooth/host/settings.c index 0c1f86a458c4..bd7d372c00a7 100644 --- a/subsys/bluetooth/host/settings.c +++ b/subsys/bluetooth/host/settings.c @@ -24,7 +24,6 @@ #include "common/bt_settings_commit.h" #include "common/bt_str.h" -#include "common/assert.h" #include "hci_core.h" #include "settings.h" #include "sys/types.h" @@ -76,8 +75,10 @@ int bt_settings_encode_key(char *path, size_t path_size, const char *subsys, { size_t len = 3; - /* path_size is less than 3; strlen("bt/") */ - BT_ASSERT(path_size >= len); + /* path_size is less than or equal 3; strlen("bt/") */ + if (path_size <= len) { + return -EINVAL; + } /* Key format: * "bt///", "/" is optional @@ -117,10 +118,9 @@ int bt_settings_encode_key(char *path, size_t path_size, const char *subsys, len += strlen(&path[len]); } - /* If path string is full, always null terminate at path_size */ + /* Insufficient path_size, include null termination */ if (len >= path_size) { - /* Truncate string */ - path[path_size - 1] = '\0'; + return -EINVAL; } LOG_DBG("Encoded path %s", path); @@ -132,8 +132,10 @@ static int bt_settings_encode_key_no_addr(char *path, size_t path_size, const ch { size_t len = 3; - /* path_size is less than 3; strlen("bt/") */ - BT_ASSERT(path_size >= len); + /* path_size is less than or equal 3; strlen("bt/") */ + if (path_size <= len) { + return -EINVAL; + } /* Key format: * "bt/" @@ -144,10 +146,9 @@ static int bt_settings_encode_key_no_addr(char *path, size_t path_size, const ch strncpy(&path[len], key, path_size - len); len = strlen(path); - /* If path string is full, always null terminate at path_size */ + /* Insufficient path_size, include null termination */ if (len >= path_size) { - /* Truncate string */ - path[path_size - 1] = '\0'; + return -EINVAL; } LOG_DBG("Encoded path %s", path); From 230453b6ea088d20c69fd378f2570c99c6ba5890 Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Fri, 19 Dec 2025 13:53:43 +0100 Subject: [PATCH 2480/3659] Bluetooth: Host: settings: Fix truncation detection after strncpy Fix truncation detection after strncpy, as strlen cannot be used if the src was truncated due to insufficient size of dst. Signed-off-by: Vinayak Kariappa Chettimada --- subsys/bluetooth/host/settings.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/subsys/bluetooth/host/settings.c b/subsys/bluetooth/host/settings.c index bd7d372c00a7..3b8c506e78b3 100644 --- a/subsys/bluetooth/host/settings.c +++ b/subsys/bluetooth/host/settings.c @@ -87,9 +87,9 @@ int bt_settings_encode_key(char *path, size_t path_size, const char *subsys, /* Concatenate subsys as much the free space permits */ strncpy(&path[len], subsys, (path_size - len)); + len += MIN(strlen(subsys), (path_size - len)); /* Postfix '/' if there is free space */ - len = strlen(path); if (len < path_size) { path[len] = '/'; len++; @@ -97,8 +97,7 @@ int bt_settings_encode_key(char *path, size_t path_size, const char *subsys, /* Concatenate addr as much the free space permits */ for (int8_t i = 5; i >= 0 && len < path_size; i--) { - len += bin2hex(&addr->a.val[i], 1, &path[len], - path_size - len); + len += bin2hex(&addr->a.val[i], 1, &path[len], (path_size - len)); } /* Postfix addr type if there is free space */ @@ -114,11 +113,11 @@ int bt_settings_encode_key(char *path, size_t path_size, const char *subsys, if ((key != NULL) && (len < path_size)) { path[len] = '/'; len++; - strncpy(&path[len], key, path_size - len); - len += strlen(&path[len]); + strncpy(&path[len], key, (path_size - len)); + len += MIN(strlen(key), (path_size - len)); } - /* Insufficient path_size, include null termination */ + /* Insufficient path_size, including null termination */ if (len >= path_size) { return -EINVAL; } @@ -143,10 +142,10 @@ static int bt_settings_encode_key_no_addr(char *path, size_t path_size, const ch strcpy(path, "bt/"); /* Concatenate key as much the free space permits */ - strncpy(&path[len], key, path_size - len); - len = strlen(path); + strncpy(&path[len], key, (path_size - len)); + len += MIN(strlen(key), (path_size - len)); - /* Insufficient path_size, include null termination */ + /* Insufficient path_size, including null termination */ if (len >= path_size) { return -EINVAL; } From 43dede5acc8a64625aa2a341ede59e418762e4fa Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Tue, 23 Dec 2025 05:41:14 +0100 Subject: [PATCH 2481/3659] Bluetooth: Host: settings: Add early len check without strncpy/cmp use Add early len check, remove use of strcpy, strncpy and strncmp. Co-authored-by: Emil Gydesen Signed-off-by: Vinayak Kariappa Chettimada --- subsys/bluetooth/host/settings.c | 127 +++++++++++++++++-------------- 1 file changed, 69 insertions(+), 58 deletions(-) diff --git a/subsys/bluetooth/host/settings.c b/subsys/bluetooth/host/settings.c index 3b8c506e78b3..48bf4fd6e538 100644 --- a/subsys/bluetooth/host/settings.c +++ b/subsys/bluetooth/host/settings.c @@ -48,7 +48,8 @@ int bt_settings_encode_key(char *path, size_t path_size, const char *subsys, addr->a.val[1], addr->a.val[0], addr->type); } - if (err < 0) { + if ((err < 0) || (err >= path_size)) { + /* Error or output was truncated */ return -EINVAL; } @@ -62,7 +63,8 @@ static int bt_settings_encode_key_no_addr(char *path, size_t path_size, const ch int err; err = snprintk(path, path_size, "bt/%s", key); - if (err < 0) { + if ((err < 0) || (err >= path_size)) { + /* Error or output was truncated */ return -EINVAL; } @@ -73,55 +75,61 @@ static int bt_settings_encode_key_no_addr(char *path, size_t path_size, const ch int bt_settings_encode_key(char *path, size_t path_size, const char *subsys, const bt_addr_le_t *addr, const char *key) { - size_t len = 3; - - /* path_size is less than or equal 3; strlen("bt/") */ - if (path_size <= len) { - return -EINVAL; - } - /* Key format: * "bt///", "/" is optional */ - strcpy(path, "bt/"); - - /* Concatenate subsys as much the free space permits */ - strncpy(&path[len], subsys, (path_size - len)); - len += MIN(strlen(subsys), (path_size - len)); + const char delimiter = '/'; + const char null_term = '\0'; + const size_t prefix_len = sizeof("bt") - 1U; + const size_t subsys_len = strlen(subsys); + const size_t addr_str_len = sizeof("554433221100t") - 1U; + const size_t key_len = (key == NULL) ? 0U : strlen(key); + const size_t total_len = prefix_len + + sizeof(delimiter) + subsys_len + + sizeof(delimiter) + addr_str_len + + ((key == NULL) ? 0U : (sizeof(delimiter) + key_len)) + + sizeof(null_term); + size_t offset = 0U; + int err; - /* Postfix '/' if there is free space */ - if (len < path_size) { - path[len] = '/'; - len++; + if (path_size < total_len) { + return -EINVAL; } - /* Concatenate addr as much the free space permits */ - for (int8_t i = 5; i >= 0 && len < path_size; i--) { - len += bin2hex(&addr->a.val[i], 1, &path[len], (path_size - len)); - } + memcpy(path, "bt", prefix_len); + offset += prefix_len; - /* Postfix addr type if there is free space */ - if (len < path_size) { - /* Type can be either BT_ADDR_LE_PUBLIC or - * BT_ADDR_LE_RANDOM (value 0 or 1) - */ - path[len] = '0' + addr->type; - len++; - } + path[offset] = delimiter; + offset++; + memcpy(&path[offset], subsys, subsys_len); + offset += subsys_len; - /* Postfix '/' and concatenate key as much the free space permits */ - if ((key != NULL) && (len < path_size)) { - path[len] = '/'; - len++; - strncpy(&path[len], key, (path_size - len)); - len += MIN(strlen(key), (path_size - len)); + path[offset] = delimiter; + offset++; + for (int8_t i = 5; i >= 0; i--) { + /* We supply valid 0-15 as input */ + err = hex2char(addr->a.val[i] >> 4, &path[offset]); + __ASSERT_NO_MSG(err == 0); + offset++; + /* We supply valid 0-15 as input */ + err = hex2char(addr->a.val[i] & 0xf, &path[offset]); + __ASSERT_NO_MSG(err == 0); + offset++; } + /* We are not checking hex2char return value as we supply valid 0-1 as input */ + err = hex2char(addr->type, &path[offset]); + __ASSERT_NO_MSG(err == 0); + offset++; - /* Insufficient path_size, including null termination */ - if (len >= path_size) { - return -EINVAL; + if (key != NULL) { + path[offset] = delimiter; + offset++; + memcpy(&path[offset], key, key_len); + offset += key_len; } + path[offset] = null_term; + LOG_DBG("Encoded path %s", path); return 0; @@ -129,27 +137,30 @@ int bt_settings_encode_key(char *path, size_t path_size, const char *subsys, static int bt_settings_encode_key_no_addr(char *path, size_t path_size, const char *key) { - size_t len = 3; - - /* path_size is less than or equal 3; strlen("bt/") */ - if (path_size <= len) { - return -EINVAL; - } - /* Key format: * "bt/" */ - strcpy(path, "bt/"); - - /* Concatenate key as much the free space permits */ - strncpy(&path[len], key, (path_size - len)); - len += MIN(strlen(key), (path_size - len)); - - /* Insufficient path_size, including null termination */ - if (len >= path_size) { + const char delimiter = '/'; + const char null_term = '\0'; + const size_t prefix_len = sizeof("bt") - 1U; + const size_t key_len = strlen(key); + const size_t total_len = prefix_len + sizeof(delimiter) + key_len + sizeof(null_term); + size_t offset = 0U; + + if (path_size < total_len) { return -EINVAL; } + memcpy(path, "bt", prefix_len); + offset += prefix_len; + + path[offset] = delimiter; + offset++; + memcpy(&path[offset], key, key_len); + offset += key_len; + + path[offset] = null_term; + LOG_DBG("Encoded path %s", path); return 0; @@ -202,7 +213,7 @@ static int set_setting(const char *name, size_t len_rd, settings_read_cb read_cb len = settings_name_next(name, &next); - if (!strncmp(name, "id", len)) { + if ((len == 2) && (memcmp(name, "id", len) == 0)) { /* Any previously provided identities supersede flash */ if (atomic_test_bit(bt_dev.flags, BT_DEV_PRESET_ID)) { LOG_WRN("Ignoring identities stored in flash"); @@ -234,7 +245,7 @@ static int set_setting(const char *name, size_t len_rd, settings_read_cb read_cb } #if defined(CONFIG_BT_DEVICE_NAME_DYNAMIC) - if (!strncmp(name, "name", len)) { + if ((len == 4) && (memcmp(name, "name", len) == 0)) { len = read_cb(cb_arg, &bt_dev.name, sizeof(bt_dev.name) - 1); if (len < 0) { LOG_ERR("Failed to read device name from storage" @@ -249,7 +260,7 @@ static int set_setting(const char *name, size_t len_rd, settings_read_cb read_cb #endif #if defined(CONFIG_BT_DEVICE_APPEARANCE_DYNAMIC) - if (!strncmp(name, "appearance", len)) { + if ((len == 10) && (memcmp(name, "appearance", len) == 0)) { if (len_rd != sizeof(bt_dev.appearance)) { LOG_ERR("Ignoring settings entry 'bt/appearance'. Wrong length."); return -EINVAL; @@ -265,7 +276,7 @@ static int set_setting(const char *name, size_t len_rd, settings_read_cb read_cb #endif #if defined(CONFIG_BT_PRIVACY) - if (!strncmp(name, "irk", len)) { + if ((len == 3) && (memcmp(name, "irk", len) == 0)) { len = read_cb(cb_arg, bt_dev.irk, sizeof(bt_dev.irk)); if (len < sizeof(bt_dev.irk[0])) { if (len < 0) { From 891d50c396920b55697d2f5637ef4beac661aa36 Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Mon, 5 Jan 2026 10:29:25 +0100 Subject: [PATCH 2482/3659] tests: bsim: Bluetooth: Cover settings without snprintk use Cover settings without snprintk use in bsim test. Signed-off-by: Vinayak Kariappa Chettimada --- .../host/privacy/peripheral/prj.conf | 3 ++ .../privacy/peripheral/prj_no_snprintk.conf | 25 +++++++++++ .../test_scripts/run_test_no_snprintk.sh | 41 +++++++++++++++++++ .../host/privacy/peripheral/testcase.yaml | 5 +++ 4 files changed, 74 insertions(+) create mode 100644 tests/bsim/bluetooth/host/privacy/peripheral/prj_no_snprintk.conf create mode 100755 tests/bsim/bluetooth/host/privacy/peripheral/test_scripts/run_test_no_snprintk.sh diff --git a/tests/bsim/bluetooth/host/privacy/peripheral/prj.conf b/tests/bsim/bluetooth/host/privacy/peripheral/prj.conf index d7295596ac37..e001a35e951f 100644 --- a/tests/bsim/bluetooth/host/privacy/peripheral/prj.conf +++ b/tests/bsim/bluetooth/host/privacy/peripheral/prj.conf @@ -18,5 +18,8 @@ CONFIG_NVS=y CONFIG_SETTINGS=y CONFIG_BT_SETTINGS=y +# Lets cover settings with use of snprintk +CONFIG_BT_SETTINGS_USE_PRINTK=y + # Increased stack due to settings API usage CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048 diff --git a/tests/bsim/bluetooth/host/privacy/peripheral/prj_no_snprintk.conf b/tests/bsim/bluetooth/host/privacy/peripheral/prj_no_snprintk.conf new file mode 100644 index 000000000000..de2d86e678e2 --- /dev/null +++ b/tests/bsim/bluetooth/host/privacy/peripheral/prj_no_snprintk.conf @@ -0,0 +1,25 @@ +CONFIG_BT=y +CONFIG_BT_PERIPHERAL=y +CONFIG_BT_CENTRAL=y +CONFIG_BT_SMP=y +CONFIG_ASSERT=y + +CONFIG_BT_EXT_ADV=y +CONFIG_BT_PRIVACY=y +CONFIG_BT_RPA_TIMEOUT=10 +CONFIG_BT_EXT_ADV_MAX_ADV_SET=3 +CONFIG_BT_CTLR_ADVANCED_FEATURES=y +CONFIG_BT_CTLR_ADV_DATA_BUF_MAX=3 +CONFIG_BT_ID_MAX=3 + +CONFIG_FLASH=y +CONFIG_FLASH_MAP=y +CONFIG_NVS=y +CONFIG_SETTINGS=y +CONFIG_BT_SETTINGS=y + +# Lets cover settings without use of snprintk +CONFIG_BT_SETTINGS_USE_PRINTK=n + +# Increased stack due to settings API usage +CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048 diff --git a/tests/bsim/bluetooth/host/privacy/peripheral/test_scripts/run_test_no_snprintk.sh b/tests/bsim/bluetooth/host/privacy/peripheral/test_scripts/run_test_no_snprintk.sh new file mode 100755 index 000000000000..3ae6b762c271 --- /dev/null +++ b/tests/bsim/bluetooth/host/privacy/peripheral/test_scripts/run_test_no_snprintk.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash +# Copyright 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +set -eu +source ${ZEPHYR_BASE}/tests/bsim/sh_common.source + +verbosity_level=2 +simulation_id="host_privacy_peripheral_no_snprintk" +EXECUTE_TIMEOUT=240 + +central_exe="${BSIM_OUT_PATH}/bin/bs_${BOARD_TS}_$(guess_test_long_name)_prj_no_snprintk_conf" +peripheral_exe="${central_exe}" + +cd ${BSIM_OUT_PATH}/bin + +Execute "$central_exe" \ + -v=${verbosity_level} -s=${simulation_id} -d=0 -testid=central -RealEncryption=1 \ + -flash="${simulation_id}.central.log.bin" -flash_erase + +Execute "$peripheral_exe" \ + -v=${verbosity_level} -s=${simulation_id} -d=1 -testid=peripheral -RealEncryption=1 \ + -flash="${simulation_id}.peripheral.log.bin" -flash_erase + +Execute ./bs_2G4_phy_v1 -v=${verbosity_level} -s=${simulation_id} \ + -D=2 -sim_length=70e6 $@ + +wait_for_background_jobs + +Execute "$central_exe" \ + -v=${verbosity_level} -s=${simulation_id}.2 -d=0 -testid=central -RealEncryption=1 \ + -flash="${simulation_id}.central.log.bin" -flash_rm + +Execute "$peripheral_exe" \ + -v=${verbosity_level} -s=${simulation_id}.2 -d=1 -testid=peripheral -RealEncryption=1 \ + -flash="${simulation_id}.peripheral.log.bin" -flash_rm + +Execute ./bs_2G4_phy_v1 -v=${verbosity_level} -s=${simulation_id}.2 \ + -D=2 -sim_length=70e6 $@ + +wait_for_background_jobs diff --git a/tests/bsim/bluetooth/host/privacy/peripheral/testcase.yaml b/tests/bsim/bluetooth/host/privacy/peripheral/testcase.yaml index 0942bb4fbb50..b0308fb16828 100644 --- a/tests/bsim/bluetooth/host/privacy/peripheral/testcase.yaml +++ b/tests/bsim/bluetooth/host/privacy/peripheral/testcase.yaml @@ -12,6 +12,11 @@ tests: bluetooth.host.privacy.peripheral: harness_config: bsim_exe_name: tests_bsim_bluetooth_host_privacy_peripheral_prj_conf + bluetooth.host.privacy.peripheral_no_snprintk: + harness_config: + bsim_exe_name: tests_bsim_bluetooth_host_privacy_peripheral_prj_no_snprintk_conf + extra_args: + EXTRA_CONF_FILE=prj_no_snprintk.conf bluetooth.host.privacy.peripheral_rpa_expired: harness_config: bsim_exe_name: tests_bsim_bluetooth_host_privacy_peripheral_prj_rpa_expired_conf From 14268793a9779982de331eab73a39678e89f22d4 Mon Sep 17 00:00:00 2001 From: Braeden Lane Date: Wed, 10 Dec 2025 13:57:54 -0800 Subject: [PATCH 2483/3659] soc: infineon: psoc4: Add PSOC 4100S Max series support Add initial support for the PSOC 4100S Max series, starting with the CY8C4149AZI-S598 (100-TQFP package) used on the CY8CKIT-041S-MAX development board. The infrastructure supports adding additional part numbers in the future as needed. Signed-off-by: Braeden Lane --- modules/hal_infineon/infineon_kconfig.h | 13 ++++++++++ .../psoc4/psoc4100smax/CMakeLists.txt | 10 ++++++++ soc/infineon/psoc4/psoc4100smax/Kconfig | 25 +++++++++++++++++++ .../psoc4/psoc4100smax/Kconfig.defconfig | 14 +++++++++++ soc/infineon/psoc4/psoc4100smax/Kconfig.soc | 21 ++++++++++++++++ soc/infineon/psoc4/psoc4100smax/soc.c | 21 ++++++++++++++++ soc/infineon/psoc4/psoc4100smax/soc.h | 15 +++++++++++ soc/infineon/psoc4/soc.yml | 3 +++ 8 files changed, 122 insertions(+) create mode 100644 soc/infineon/psoc4/psoc4100smax/CMakeLists.txt create mode 100644 soc/infineon/psoc4/psoc4100smax/Kconfig create mode 100644 soc/infineon/psoc4/psoc4100smax/Kconfig.defconfig create mode 100644 soc/infineon/psoc4/psoc4100smax/Kconfig.soc create mode 100644 soc/infineon/psoc4/psoc4100smax/soc.c create mode 100644 soc/infineon/psoc4/psoc4100smax/soc.h diff --git a/modules/hal_infineon/infineon_kconfig.h b/modules/hal_infineon/infineon_kconfig.h index 464059d6f883..137885ba97b9 100644 --- a/modules/hal_infineon/infineon_kconfig.h +++ b/modules/hal_infineon/infineon_kconfig.h @@ -375,4 +375,17 @@ #endif /* CONFIG_SOC_SERIES_PSOC4100TP */ +#if defined(CONFIG_SOC_SERIES_PSOC4100SMAX) + +#if defined(CONFIG_SOC_CY8C4149AZI_S598) +#ifndef CY8C4149AZI_S598 +#define CY8C4149AZI_S598 +#endif +#ifndef CY8C4149AZI_S598_ +#define CY8C4149AZI_S598_ +#endif +#endif + +#endif /* CONFIG_SOC_SERIES_PSOC4100SMAX */ + #endif /* INFINEON_KCONFIG_H__ */ diff --git a/soc/infineon/psoc4/psoc4100smax/CMakeLists.txt b/soc/infineon/psoc4/psoc4100smax/CMakeLists.txt new file mode 100644 index 000000000000..638c47e666a4 --- /dev/null +++ b/soc/infineon/psoc4/psoc4100smax/CMakeLists.txt @@ -0,0 +1,10 @@ +# Copyright (c) 2025 Infineon Technologies AG, +# or an affiliate of Infineon Technologies AG. +# +# SPDX-License-Identifier: Apache-2.0 + +zephyr_sources(soc.c) +zephyr_include_directories(.) + +#default Zephyr linker script +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/infineon/psoc4/psoc4100smax/Kconfig b/soc/infineon/psoc4/psoc4100smax/Kconfig new file mode 100644 index 000000000000..bc8b09e4237a --- /dev/null +++ b/soc/infineon/psoc4/psoc4100smax/Kconfig @@ -0,0 +1,25 @@ +# Copyright (c) 2025 Infineon Technologies AG, +# or an affiliate of Infineon Technologies AG. +# +# SPDX-License-Identifier: Apache-2.0 + +# SOC Packages for Infineon PSOC4100Smax series MCUs +config SOC_PACKAGE_PSOC4100SMAX_100_TQFP + bool + help + 100-pin TQFP package + +# Hardware configuration for PSOC4100SMAX series +config SOC_SERIES_PSOC4100SMAX + select ARM + select CPU_CORTEX_M0PLUS + select CPU_CORTEX_M_HAS_VTOR + select CPU_HAS_ARM_MPU + select BUILD_OUTPUT_HEX + select BUILD_OUTPUT_BIN + select DYNAMIC_INTERRUPTS + select SOC_EARLY_INIT_HOOK + select CPU_CORTEX_M_HAS_SYSTICK + +config SOC_CY8C4149AZI_S598 + select SOC_PACKAGE_PSOC4100SMAX_100_TQFP diff --git a/soc/infineon/psoc4/psoc4100smax/Kconfig.defconfig b/soc/infineon/psoc4/psoc4100smax/Kconfig.defconfig new file mode 100644 index 000000000000..c37cb8bb50eb --- /dev/null +++ b/soc/infineon/psoc4/psoc4100smax/Kconfig.defconfig @@ -0,0 +1,14 @@ +# Copyright (c) 2025 Infineon Technologies AG, +# or an affiliate of Infineon Technologies AG. +# +# SPDX-License-Identifier: Apache-2.0 + +if SOC_SERIES_PSOC4100SMAX + +config NUM_IRQS + default 32 + +config SYS_CLOCK_HW_CYCLES_PER_SEC + default $(dt_node_int_prop_int,/cpus/cpu@0,clock-frequency) + +endif # SOC_SERIES_PSOC4100SMAX diff --git a/soc/infineon/psoc4/psoc4100smax/Kconfig.soc b/soc/infineon/psoc4/psoc4100smax/Kconfig.soc new file mode 100644 index 000000000000..f804183d7869 --- /dev/null +++ b/soc/infineon/psoc4/psoc4100smax/Kconfig.soc @@ -0,0 +1,21 @@ +# Copyright (c) 2025 Infineon Technologies AG, +# or an affiliate of Infineon Technologies AG. +# +# SPDX-License-Identifier: Apache-2.0 + +# MCU series +config SOC_SERIES_PSOC4100SMAX + bool + select SOC_FAMILY_INFINEON_PSOC4 + help + PSOC4100Smax Series MCU + +config SOC_SERIES + default "psoc4100smax" if SOC_SERIES_PSOC4100SMAX + +config SOC_CY8C4149AZI_S598 + bool + select SOC_SERIES_PSOC4100SMAX + +config SOC + default "cy8c4149azi_s598" if SOC_CY8C4149AZI_S598 diff --git a/soc/infineon/psoc4/psoc4100smax/soc.c b/soc/infineon/psoc4/psoc4100smax/soc.c new file mode 100644 index 000000000000..37131f0bac7c --- /dev/null +++ b/soc/infineon/psoc4/psoc4100smax/soc.c @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#include +#include /* PSoC4 system init header from PDL */ +#include "cy_pdl.h" + +/* Minimal early initialization for PSoC 4100S Max */ +void soc_early_init_hook(void) +{ + /* Initializes the system */ + SystemInit(); +} diff --git a/soc/infineon/psoc4/psoc4100smax/soc.h b/soc/infineon/psoc4/psoc4100smax/soc.h new file mode 100644 index 000000000000..90edbd5b6754 --- /dev/null +++ b/soc/infineon/psoc4/psoc4100smax/soc.h @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_SOC_INFINEON_PSOC4_PSOC4100SMAX_SOC_H_ +#define ZEPHYR_SOC_INFINEON_PSOC4_PSOC4100SMAX_SOC_H_ + +#ifndef _ASMLANGUAGE +#include +#endif /* !_ASMLANGUAGE */ + +#endif /* ZEPHYR_SOC_INFINEON_PSOC4_PSOC4100SMAX_SOC_H_ */ diff --git a/soc/infineon/psoc4/soc.yml b/soc/infineon/psoc4/soc.yml index 2938ebf605e7..0f947bbffc3f 100644 --- a/soc/infineon/psoc4/soc.yml +++ b/soc/infineon/psoc4/soc.yml @@ -48,3 +48,6 @@ family: - name: cy8c4146azq_t453 - name: cy8c4147azq_t415 - name: cy8c4147azq_t455 + - name: psoc4100smax + socs: + - name: cy8c4149azi_s598 From fd991b749137643059bac611baeee40e205f9557 Mon Sep 17 00:00:00 2001 From: Braeden Lane Date: Wed, 10 Dec 2025 14:00:19 -0800 Subject: [PATCH 2484/3659] dts: arm: infineon: psoc4: Add PSOC 4100S Max devicetree Add devicetree support for PSOC 4100S Max series including: - Base SoC dtsi with GPIO, UART, HSIOM peripherals - 100-TQFP package dtsi for pin multiplexing - CY8C4149AZI-S598 MPN-specific devicetree include - Updated compatible strings for PSOC 4 support - Clock structure with clk_hf and clk_pump nodes - Simplified peripheral clock naming (peri_clk_div) - PSOC4xx clock source definitions and bindings Signed-off-by: Braeden Lane --- .../infineon/psoc4/mpns/cy8c4149azi_s598.dtsi | 8 + .../psoc4100smax/psoc4100smax.100-tqfp.dtsi | 1463 +++++++++++++++++ .../psoc4/psoc4100smax/psoc4100smax.cm0p.dtsi | 40 + .../psoc4/psoc4100smax/psoc4100smax.dtsi | 351 ++++ .../psoc4/psoc4100smax/system_clocks.dtsi | 237 +++ 5 files changed, 2099 insertions(+) create mode 100644 dts/arm/infineon/psoc4/mpns/cy8c4149azi_s598.dtsi create mode 100644 dts/arm/infineon/psoc4/psoc4100smax/psoc4100smax.100-tqfp.dtsi create mode 100644 dts/arm/infineon/psoc4/psoc4100smax/psoc4100smax.cm0p.dtsi create mode 100644 dts/arm/infineon/psoc4/psoc4100smax/psoc4100smax.dtsi create mode 100644 dts/arm/infineon/psoc4/psoc4100smax/system_clocks.dtsi diff --git a/dts/arm/infineon/psoc4/mpns/cy8c4149azi_s598.dtsi b/dts/arm/infineon/psoc4/mpns/cy8c4149azi_s598.dtsi new file mode 100644 index 000000000000..87dd94d20447 --- /dev/null +++ b/dts/arm/infineon/psoc4/mpns/cy8c4149azi_s598.dtsi @@ -0,0 +1,8 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "../psoc4100smax/psoc4100smax.100-tqfp.dtsi" diff --git a/dts/arm/infineon/psoc4/psoc4100smax/psoc4100smax.100-tqfp.dtsi b/dts/arm/infineon/psoc4/psoc4100smax/psoc4100smax.100-tqfp.dtsi new file mode 100644 index 000000000000..908f914a8b87 --- /dev/null +++ b/dts/arm/infineon/psoc4/psoc4100smax/psoc4100smax.100-tqfp.dtsi @@ -0,0 +1,1463 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "psoc4100smax.dtsi" + +/ { + soc { + pinctrl: pinctrl@40020000 { + /* scb_i2c_scl */ + /omit-if-no-ref/ p0_0_scb2_i2c_scl: p0_0_scb2_i2c_scl { + pinmux = ; + }; + + /omit-if-no-ref/ p0_4_scb1_i2c_scl: p0_4_scb1_i2c_scl { + pinmux = ; + }; + + /omit-if-no-ref/ p1_0_scb0_i2c_scl: p1_0_scb0_i2c_scl { + pinmux = ; + }; + + /omit-if-no-ref/ p1_2_scb2_i2c_scl: p1_2_scb2_i2c_scl { + pinmux = ; + }; + + /omit-if-no-ref/ p1_4_scb3_i2c_scl: p1_4_scb3_i2c_scl { + pinmux = ; + }; + + /omit-if-no-ref/ p2_0_scb1_i2c_scl: p2_0_scb1_i2c_scl { + pinmux = ; + }; + + /omit-if-no-ref/ p3_0_scb1_i2c_scl: p3_0_scb1_i2c_scl { + pinmux = ; + }; + + /omit-if-no-ref/ p4_0_scb0_i2c_scl: p4_0_scb0_i2c_scl { + pinmux = ; + }; + + /omit-if-no-ref/ p5_0_scb2_i2c_scl: p5_0_scb2_i2c_scl { + pinmux = ; + }; + + /omit-if-no-ref/ p6_0_scb3_i2c_scl: p6_0_scb3_i2c_scl { + pinmux = ; + }; + + /omit-if-no-ref/ p6_4_scb4_i2c_scl: p6_4_scb4_i2c_scl { + pinmux = ; + }; + + /omit-if-no-ref/ p7_0_scb3_i2c_scl: p7_0_scb3_i2c_scl { + pinmux = ; + }; + + /omit-if-no-ref/ p8_0_scb4_i2c_scl: p8_0_scb4_i2c_scl { + pinmux = ; + }; + + /omit-if-no-ref/ p9_0_scb0_i2c_scl: p9_0_scb0_i2c_scl { + pinmux = ; + }; + + /omit-if-no-ref/ p10_0_scb2_i2c_scl: p10_0_scb2_i2c_scl { + pinmux = ; + }; + + /omit-if-no-ref/ p12_0_scb1_i2c_scl: p12_0_scb1_i2c_scl { + pinmux = ; + }; + + /* scb_i2c_sda */ + /omit-if-no-ref/ p0_1_scb2_i2c_sda: p0_1_scb2_i2c_sda { + pinmux = ; + }; + + /omit-if-no-ref/ p0_5_scb1_i2c_sda: p0_5_scb1_i2c_sda { + pinmux = ; + }; + + /omit-if-no-ref/ p1_1_scb0_i2c_sda: p1_1_scb0_i2c_sda { + pinmux = ; + }; + + /omit-if-no-ref/ p1_3_scb2_i2c_sda: p1_3_scb2_i2c_sda { + pinmux = ; + }; + + /omit-if-no-ref/ p1_5_scb3_i2c_sda: p1_5_scb3_i2c_sda { + pinmux = ; + }; + + /omit-if-no-ref/ p2_1_scb1_i2c_sda: p2_1_scb1_i2c_sda { + pinmux = ; + }; + + /omit-if-no-ref/ p3_1_scb1_i2c_sda: p3_1_scb1_i2c_sda { + pinmux = ; + }; + + /omit-if-no-ref/ p4_1_scb0_i2c_sda: p4_1_scb0_i2c_sda { + pinmux = ; + }; + + /omit-if-no-ref/ p5_1_scb2_i2c_sda: p5_1_scb2_i2c_sda { + pinmux = ; + }; + + /omit-if-no-ref/ p6_1_scb3_i2c_sda: p6_1_scb3_i2c_sda { + pinmux = ; + }; + + /omit-if-no-ref/ p6_5_scb4_i2c_sda: p6_5_scb4_i2c_sda { + pinmux = ; + }; + + /omit-if-no-ref/ p7_1_scb3_i2c_sda: p7_1_scb3_i2c_sda { + pinmux = ; + }; + + /omit-if-no-ref/ p8_1_scb4_i2c_sda: p8_1_scb4_i2c_sda { + pinmux = ; + }; + + /omit-if-no-ref/ p9_1_scb0_i2c_sda: p9_1_scb0_i2c_sda { + pinmux = ; + }; + + /omit-if-no-ref/ p10_1_scb2_i2c_sda: p10_1_scb2_i2c_sda { + pinmux = ; + }; + + /omit-if-no-ref/ p12_1_scb1_i2c_sda: p12_1_scb1_i2c_sda { + pinmux = ; + }; + + /* scb_spi_m_clk */ + /omit-if-no-ref/ p0_6_scb1_spi_m_clk: p0_6_scb1_spi_m_clk { + pinmux = ; + }; + + /omit-if-no-ref/ p1_2_scb0_spi_m_clk: p1_2_scb0_spi_m_clk { + pinmux = ; + }; + + /omit-if-no-ref/ p1_7_scb2_spi_m_clk: p1_7_scb2_spi_m_clk { + pinmux = ; + }; + + /omit-if-no-ref/ p2_2_scb1_spi_m_clk: p2_2_scb1_spi_m_clk { + pinmux = ; + }; + + /omit-if-no-ref/ p3_2_scb1_spi_m_clk: p3_2_scb1_spi_m_clk { + pinmux = ; + }; + + /omit-if-no-ref/ p4_2_scb0_spi_m_clk: p4_2_scb0_spi_m_clk { + pinmux = ; + }; + + /omit-if-no-ref/ p4_6_scb4_spi_m_clk: p4_6_scb4_spi_m_clk { + pinmux = ; + }; + + /omit-if-no-ref/ p5_2_scb2_spi_m_clk: p5_2_scb2_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/ p7_2_scb3_spi_m_clk: p7_2_scb3_spi_m_clk { + pinmux = ; + }; + + /omit-if-no-ref/ p8_2_scb3_spi_m_clk: p8_2_scb3_spi_m_clk { + pinmux = ; + }; + + /omit-if-no-ref/ p9_2_scb0_spi_m_clk: p9_2_scb0_spi_m_clk { + pinmux = ; + }; + + /omit-if-no-ref/ p10_2_scb2_spi_m_clk: p10_2_scb2_spi_m_clk { + pinmux = ; + }; + + /omit-if-no-ref/ p11_2_scb1_spi_m_clk: p11_2_scb1_spi_m_clk { + pinmux = ; + }; + + /omit-if-no-ref/ p11_2_scb4_spi_m_clk: p11_2_scb4_spi_m_clk { + pinmux = ; + }; + + /* scb_spi_m_miso */ + /omit-if-no-ref/ p0_5_scb1_spi_m_miso: p0_5_scb1_spi_m_miso { + pinmux = ; + }; + + /omit-if-no-ref/ p1_1_scb0_spi_m_miso: p1_1_scb0_spi_m_miso { + pinmux = ; + }; + + /omit-if-no-ref/ p2_1_scb1_spi_m_miso: p2_1_scb1_spi_m_miso { + pinmux = ; + }; + + /omit-if-no-ref/ p3_1_scb1_spi_m_miso: p3_1_scb1_spi_m_miso { + pinmux = ; + }; + + /omit-if-no-ref/ p3_7_scb2_spi_m_miso: p3_7_scb2_spi_m_miso { + pinmux = ; + }; + + /omit-if-no-ref/ p4_1_scb0_spi_m_miso: p4_1_scb0_spi_m_miso { + pinmux = ; + }; + + /omit-if-no-ref/ p4_5_scb4_spi_m_miso: p4_5_scb4_spi_m_miso { + pinmux = ; + }; + + /omit-if-no-ref/ p5_1_scb2_spi_m_miso: p5_1_scb2_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/ p7_1_scb3_spi_m_miso: p7_1_scb3_spi_m_miso { + pinmux = ; + }; + + /omit-if-no-ref/ p8_1_scb3_spi_m_miso: p8_1_scb3_spi_m_miso { + pinmux = ; + }; + + /omit-if-no-ref/ p9_1_scb0_spi_m_miso: p9_1_scb0_spi_m_miso { + pinmux = ; + }; + + /omit-if-no-ref/ p10_1_scb2_spi_m_miso: p10_1_scb2_spi_m_miso { + pinmux = ; + }; + + /omit-if-no-ref/ p11_1_scb1_spi_m_miso: p11_1_scb1_spi_m_miso { + pinmux = ; + }; + + /omit-if-no-ref/ p11_1_scb4_spi_m_miso: p11_1_scb4_spi_m_miso { + pinmux = ; + }; + + /* scb_spi_m_mosi */ + /omit-if-no-ref/ p0_4_scb1_spi_m_mosi: p0_4_scb1_spi_m_mosi { + pinmux = ; + }; + + /omit-if-no-ref/ p1_0_scb0_spi_m_mosi: p1_0_scb0_spi_m_mosi { + pinmux = ; + }; + + /omit-if-no-ref/ p2_0_scb1_spi_m_mosi: p2_0_scb1_spi_m_mosi { + pinmux = ; + }; + + /omit-if-no-ref/ p2_7_scb2_spi_m_mosi: p2_7_scb2_spi_m_mosi { + pinmux = ; + }; + + /omit-if-no-ref/ p3_0_scb1_spi_m_mosi: p3_0_scb1_spi_m_mosi { + pinmux = ; + }; + + /omit-if-no-ref/ p4_0_scb0_spi_m_mosi: p4_0_scb0_spi_m_mosi { + pinmux = ; + }; + + /omit-if-no-ref/ p4_4_scb4_spi_m_mosi: p4_4_scb4_spi_m_mosi { + pinmux = ; + }; + + /omit-if-no-ref/ p5_0_scb2_spi_m_mosi: p5_0_scb2_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/ p7_0_scb3_spi_m_mosi: p7_0_scb3_spi_m_mosi { + pinmux = ; + }; + + /omit-if-no-ref/ p8_0_scb3_spi_m_mosi: p8_0_scb3_spi_m_mosi { + pinmux = ; + }; + + /omit-if-no-ref/ p9_0_scb0_spi_m_mosi: p9_0_scb0_spi_m_mosi { + pinmux = ; + }; + + /omit-if-no-ref/ p10_0_scb2_spi_m_mosi: p10_0_scb2_spi_m_mosi { + pinmux = ; + }; + + /omit-if-no-ref/ p11_0_scb1_spi_m_mosi: p11_0_scb1_spi_m_mosi { + pinmux = ; + }; + + /omit-if-no-ref/ p11_0_scb4_spi_m_mosi: p11_0_scb4_spi_m_mosi { + pinmux = ; + }; + + /* scb_spi_m_select0 */ + /omit-if-no-ref/ p0_3_scb2_spi_m_select0: p0_3_scb2_spi_m_select0 { + pinmux = ; + }; + + /omit-if-no-ref/ p0_7_scb1_spi_m_select0: p0_7_scb1_spi_m_select0 { + pinmux = ; + }; + + /omit-if-no-ref/ p1_3_scb0_spi_m_select0: p1_3_scb0_spi_m_select0 { + pinmux = ; + }; + + /omit-if-no-ref/ p2_3_scb1_spi_m_select0: p2_3_scb1_spi_m_select0 { + pinmux = ; + }; + + /omit-if-no-ref/ p3_3_scb1_spi_m_select0: p3_3_scb1_spi_m_select0 { + pinmux = ; + }; + + /omit-if-no-ref/ p4_3_scb0_spi_m_select0: p4_3_scb0_spi_m_select0 { + pinmux = ; + }; + + /omit-if-no-ref/ p4_7_scb4_spi_m_select0: p4_7_scb4_spi_m_select0 { + pinmux = ; + }; + + /omit-if-no-ref/ p5_3_scb2_spi_m_select0: p5_3_scb2_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/ p7_4_scb3_spi_m_select0: p7_4_scb3_spi_m_select0 { + pinmux = ; + }; + + /omit-if-no-ref/ p8_3_scb3_spi_m_select0: p8_3_scb3_spi_m_select0 { + pinmux = ; + }; + + /omit-if-no-ref/ p9_3_scb0_spi_m_select0: p9_3_scb0_spi_m_select0 { + pinmux = ; + }; + + /omit-if-no-ref/ p10_3_scb2_spi_m_select0: p10_3_scb2_spi_m_select0 { + pinmux = ; + }; + + /omit-if-no-ref/ p11_3_scb1_spi_m_select0: p11_3_scb1_spi_m_select0 { + pinmux = ; + }; + + /omit-if-no-ref/ p11_3_scb4_spi_m_select0: p11_3_scb4_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_scb0_spi_m_select1: p1_4_scb0_spi_m_select1 { + pinmux = ; + }; + + /omit-if-no-ref/ p2_4_scb1_spi_m_select1: p2_4_scb1_spi_m_select1 { + pinmux = ; + }; + + /omit-if-no-ref/ p3_4_scb1_spi_m_select1: p3_4_scb1_spi_m_select1 { + pinmux = ; + }; + + /omit-if-no-ref/ p4_4_scb0_spi_m_select1: p4_4_scb0_spi_m_select1 { + pinmux = ; + }; + + /omit-if-no-ref/ p5_4_scb2_spi_m_select1: p5_4_scb2_spi_m_select1 { + pinmux = ; + }; + + /omit-if-no-ref/ p5_6_scb4_spi_m_select1: p5_6_scb4_spi_m_select1 { + pinmux = ; + }; + + /omit-if-no-ref/ p5_7_scb3_spi_m_select1: p5_7_scb3_spi_m_select1 { + pinmux = ; + }; + + /omit-if-no-ref/ p6_4_scb3_spi_m_select1: p6_4_scb3_spi_m_select1 { + pinmux = ; + }; + + /omit-if-no-ref/ p7_5_scb3_spi_m_select1: p7_5_scb3_spi_m_select1 { + pinmux = ; + }; + + /omit-if-no-ref/ p10_4_scb2_spi_m_select1: p10_4_scb2_spi_m_select1 { + pinmux = ; + }; + + /omit-if-no-ref/ p11_4_scb1_spi_m_select1: p11_4_scb1_spi_m_select1 { + pinmux = ; + }; + + /omit-if-no-ref/ p11_4_scb4_spi_m_select1: p11_4_scb4_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_scb0_spi_m_select2: p1_5_scb0_spi_m_select2 { + pinmux = ; + }; + + /omit-if-no-ref/ p2_5_scb1_spi_m_select2: p2_5_scb1_spi_m_select2 { + pinmux = ; + }; + + /omit-if-no-ref/ p3_5_scb1_spi_m_select2: p3_5_scb1_spi_m_select2 { + pinmux = ; + }; + + /omit-if-no-ref/ p4_5_scb0_spi_m_select2: p4_5_scb0_spi_m_select2 { + pinmux = ; + }; + + /omit-if-no-ref/ p4_7_scb3_spi_m_select2: p4_7_scb3_spi_m_select2 { + pinmux = ; + }; + + /omit-if-no-ref/ p5_5_scb2_spi_m_select2: p5_5_scb2_spi_m_select2 { + pinmux = ; + }; + + /omit-if-no-ref/ p5_7_scb4_spi_m_select2: p5_7_scb4_spi_m_select2 { + pinmux = ; + }; + + /omit-if-no-ref/ p6_5_scb3_spi_m_select2: p6_5_scb3_spi_m_select2 { + pinmux = ; + }; + + /omit-if-no-ref/ p7_3_scb3_spi_m_select2: p7_3_scb3_spi_m_select2 { + pinmux = ; + }; + + /omit-if-no-ref/ p10_5_scb2_spi_m_select2: p10_5_scb2_spi_m_select2 { + pinmux = ; + }; + + /omit-if-no-ref/ p11_5_scb1_spi_m_select2: p11_5_scb1_spi_m_select2 { + pinmux = ; + }; + + /omit-if-no-ref/ p11_5_scb4_spi_m_select2: p11_5_scb4_spi_m_select2 { + pinmux = ; + }; + + /* scb_spi_m_select3 */ + /omit-if-no-ref/ p0_2_scb0_spi_m_select3: p0_2_scb0_spi_m_select3 { + pinmux = ; + }; + + /omit-if-no-ref/ p1_6_scb0_spi_m_select3: p1_6_scb0_spi_m_select3 { + pinmux = ; + }; + + /omit-if-no-ref/ p2_6_scb1_spi_m_select3: p2_6_scb1_spi_m_select3 { + pinmux = ; + }; + + /omit-if-no-ref/ p3_6_scb1_spi_m_select3: p3_6_scb1_spi_m_select3 { + pinmux = ; + }; + + /omit-if-no-ref/ p3_6_scb4_spi_m_select3: p3_6_scb4_spi_m_select3 { + pinmux = ; + }; + + /omit-if-no-ref/ p4_6_scb0_spi_m_select3: p4_6_scb0_spi_m_select3 { + pinmux = ; + }; + + /omit-if-no-ref/ p5_6_scb2_spi_m_select3: p5_6_scb2_spi_m_select3 { + pinmux = ; + }; + + /omit-if-no-ref/ p7_6_scb3_spi_m_select3: p7_6_scb3_spi_m_select3 { + pinmux = ; + }; + + /omit-if-no-ref/ p12_0_scb3_spi_m_select3: p12_0_scb3_spi_m_select3 { + pinmux = ; + }; + + /* scb_spi_s_clk */ + /omit-if-no-ref/ p0_6_scb1_spi_s_clk: p0_6_scb1_spi_s_clk { + pinmux = ; + }; + + /omit-if-no-ref/ p1_2_scb0_spi_s_clk: p1_2_scb0_spi_s_clk { + pinmux = ; + }; + + /omit-if-no-ref/ p1_7_scb2_spi_s_clk: p1_7_scb2_spi_s_clk { + pinmux = ; + }; + + /omit-if-no-ref/ p2_2_scb1_spi_s_clk: p2_2_scb1_spi_s_clk { + pinmux = ; + }; + + /omit-if-no-ref/ p3_2_scb1_spi_s_clk: p3_2_scb1_spi_s_clk { + pinmux = ; + }; + + /omit-if-no-ref/ p4_2_scb0_spi_s_clk: p4_2_scb0_spi_s_clk { + pinmux = ; + }; + + /omit-if-no-ref/ p4_6_scb4_spi_s_clk: p4_6_scb4_spi_s_clk { + pinmux = ; + }; + + /omit-if-no-ref/ p5_2_scb2_spi_s_clk: p5_2_scb2_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/ p7_2_scb3_spi_s_clk: p7_2_scb3_spi_s_clk { + pinmux = ; + }; + + /omit-if-no-ref/ p8_2_scb3_spi_s_clk: p8_2_scb3_spi_s_clk { + pinmux = ; + }; + + /omit-if-no-ref/ p9_2_scb0_spi_s_clk: p9_2_scb0_spi_s_clk { + pinmux = ; + }; + + /omit-if-no-ref/ p10_2_scb2_spi_s_clk: p10_2_scb2_spi_s_clk { + pinmux = ; + }; + + /omit-if-no-ref/ p11_2_scb1_spi_s_clk: p11_2_scb1_spi_s_clk { + pinmux = ; + }; + + /omit-if-no-ref/ p11_2_scb4_spi_s_clk: p11_2_scb4_spi_s_clk { + pinmux = ; + }; + + /* scb_spi_s_miso */ + /omit-if-no-ref/ p0_5_scb1_spi_s_miso: p0_5_scb1_spi_s_miso { + pinmux = ; + }; + + /omit-if-no-ref/ p1_1_scb0_spi_s_miso: p1_1_scb0_spi_s_miso { + pinmux = ; + }; + + /omit-if-no-ref/ p2_1_scb1_spi_s_miso: p2_1_scb1_spi_s_miso { + pinmux = ; + }; + + /omit-if-no-ref/ p3_1_scb1_spi_s_miso: p3_1_scb1_spi_s_miso { + pinmux = ; + }; + + /omit-if-no-ref/ p3_7_scb2_spi_s_miso: p3_7_scb2_spi_s_miso { + pinmux = ; + }; + + /omit-if-no-ref/ p4_1_scb0_spi_s_miso: p4_1_scb0_spi_s_miso { + pinmux = ; + }; + + /omit-if-no-ref/ p4_5_scb4_spi_s_miso: p4_5_scb4_spi_s_miso { + pinmux = ; + }; + + /omit-if-no-ref/ p5_1_scb2_spi_s_miso: p5_1_scb2_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/ p7_1_scb3_spi_s_miso: p7_1_scb3_spi_s_miso { + pinmux = ; + }; + + /omit-if-no-ref/ p8_1_scb3_spi_s_miso: p8_1_scb3_spi_s_miso { + pinmux = ; + }; + + /omit-if-no-ref/ p9_1_scb0_spi_s_miso: p9_1_scb0_spi_s_miso { + pinmux = ; + }; + + /omit-if-no-ref/ p10_1_scb2_spi_s_miso: p10_1_scb2_spi_s_miso { + pinmux = ; + }; + + /omit-if-no-ref/ p11_1_scb1_spi_s_miso: p11_1_scb1_spi_s_miso { + pinmux = ; + }; + + /omit-if-no-ref/ p11_1_scb4_spi_s_miso: p11_1_scb4_spi_s_miso { + pinmux = ; + }; + + /* scb_spi_s_mosi */ + /omit-if-no-ref/ p0_4_scb1_spi_s_mosi: p0_4_scb1_spi_s_mosi { + pinmux = ; + }; + + /omit-if-no-ref/ p1_0_scb0_spi_s_mosi: p1_0_scb0_spi_s_mosi { + pinmux = ; + }; + + /omit-if-no-ref/ p2_0_scb1_spi_s_mosi: p2_0_scb1_spi_s_mosi { + pinmux = ; + }; + + /omit-if-no-ref/ p2_7_scb2_spi_s_mosi: p2_7_scb2_spi_s_mosi { + pinmux = ; + }; + + /omit-if-no-ref/ p3_0_scb1_spi_s_mosi: p3_0_scb1_spi_s_mosi { + pinmux = ; + }; + + /omit-if-no-ref/ p4_0_scb0_spi_s_mosi: p4_0_scb0_spi_s_mosi { + pinmux = ; + }; + + /omit-if-no-ref/ p4_4_scb4_spi_s_mosi: p4_4_scb4_spi_s_mosi { + pinmux = ; + }; + + /omit-if-no-ref/ p5_0_scb2_spi_s_mosi: p5_0_scb2_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/ p7_0_scb3_spi_s_mosi: p7_0_scb3_spi_s_mosi { + pinmux = ; + }; + + /omit-if-no-ref/ p8_0_scb3_spi_s_mosi: p8_0_scb3_spi_s_mosi { + pinmux = ; + }; + + /omit-if-no-ref/ p9_0_scb0_spi_s_mosi: p9_0_scb0_spi_s_mosi { + pinmux = ; + }; + + /omit-if-no-ref/ p10_0_scb2_spi_s_mosi: p10_0_scb2_spi_s_mosi { + pinmux = ; + }; + + /omit-if-no-ref/ p11_0_scb1_spi_s_mosi: p11_0_scb1_spi_s_mosi { + pinmux = ; + }; + + /omit-if-no-ref/ p11_0_scb4_spi_s_mosi: p11_0_scb4_spi_s_mosi { + pinmux = ; + }; + + /* scb_spi_s_select0 */ + /omit-if-no-ref/ p0_3_scb2_spi_s_select0: p0_3_scb2_spi_s_select0 { + pinmux = ; + }; + + /omit-if-no-ref/ p0_7_scb1_spi_s_select0: p0_7_scb1_spi_s_select0 { + pinmux = ; + }; + + /omit-if-no-ref/ p1_3_scb0_spi_s_select0: p1_3_scb0_spi_s_select0 { + pinmux = ; + }; + + /omit-if-no-ref/ p2_3_scb1_spi_s_select0: p2_3_scb1_spi_s_select0 { + pinmux = ; + }; + + /omit-if-no-ref/ p3_3_scb1_spi_s_select0: p3_3_scb1_spi_s_select0 { + pinmux = ; + }; + + /omit-if-no-ref/ p4_3_scb0_spi_s_select0: p4_3_scb0_spi_s_select0 { + pinmux = ; + }; + + /omit-if-no-ref/ p4_7_scb4_spi_s_select0: p4_7_scb4_spi_s_select0 { + pinmux = ; + }; + + /omit-if-no-ref/ p5_3_scb2_spi_s_select0: p5_3_scb2_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/ p7_4_scb3_spi_s_select0: p7_4_scb3_spi_s_select0 { + pinmux = ; + }; + + /omit-if-no-ref/ p8_3_scb3_spi_s_select0: p8_3_scb3_spi_s_select0 { + pinmux = ; + }; + + /omit-if-no-ref/ p9_3_scb0_spi_s_select0: p9_3_scb0_spi_s_select0 { + pinmux = ; + }; + + /omit-if-no-ref/ p10_3_scb2_spi_s_select0: p10_3_scb2_spi_s_select0 { + pinmux = ; + }; + + /omit-if-no-ref/ p11_3_scb1_spi_s_select0: p11_3_scb1_spi_s_select0 { + pinmux = ; + }; + + /omit-if-no-ref/ p11_3_scb4_spi_s_select0: p11_3_scb4_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_scb0_spi_s_select1: p1_4_scb0_spi_s_select1 { + pinmux = ; + }; + + /omit-if-no-ref/ p2_4_scb1_spi_s_select1: p2_4_scb1_spi_s_select1 { + pinmux = ; + }; + + /omit-if-no-ref/ p3_4_scb1_spi_s_select1: p3_4_scb1_spi_s_select1 { + pinmux = ; + }; + + /omit-if-no-ref/ p4_4_scb0_spi_s_select1: p4_4_scb0_spi_s_select1 { + pinmux = ; + }; + + /omit-if-no-ref/ p5_4_scb2_spi_s_select1: p5_4_scb2_spi_s_select1 { + pinmux = ; + }; + + /omit-if-no-ref/ p5_6_scb4_spi_s_select1: p5_6_scb4_spi_s_select1 { + pinmux = ; + }; + + /omit-if-no-ref/ p5_7_scb3_spi_s_select1: p5_7_scb3_spi_s_select1 { + pinmux = ; + }; + + /omit-if-no-ref/ p6_4_scb3_spi_s_select1: p6_4_scb3_spi_s_select1 { + pinmux = ; + }; + + /omit-if-no-ref/ p7_5_scb3_spi_s_select1: p7_5_scb3_spi_s_select1 { + pinmux = ; + }; + + /omit-if-no-ref/ p10_4_scb2_spi_s_select1: p10_4_scb2_spi_s_select1 { + pinmux = ; + }; + + /omit-if-no-ref/ p11_4_scb1_spi_s_select1: p11_4_scb1_spi_s_select1 { + pinmux = ; + }; + + /omit-if-no-ref/ p11_4_scb4_spi_s_select1: p11_4_scb4_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_scb0_spi_s_select2: p1_5_scb0_spi_s_select2 { + pinmux = ; + }; + + /omit-if-no-ref/ p2_5_scb1_spi_s_select2: p2_5_scb1_spi_s_select2 { + pinmux = ; + }; + + /omit-if-no-ref/ p3_5_scb1_spi_s_select2: p3_5_scb1_spi_s_select2 { + pinmux = ; + }; + + /omit-if-no-ref/ p4_5_scb0_spi_s_select2: p4_5_scb0_spi_s_select2 { + pinmux = ; + }; + + /omit-if-no-ref/ p4_7_scb3_spi_s_select2: p4_7_scb3_spi_s_select2 { + pinmux = ; + }; + + /omit-if-no-ref/ p5_5_scb2_spi_s_select2: p5_5_scb2_spi_s_select2 { + pinmux = ; + }; + + /omit-if-no-ref/ p5_7_scb4_spi_s_select2: p5_7_scb4_spi_s_select2 { + pinmux = ; + }; + + /omit-if-no-ref/ p6_5_scb3_spi_s_select2: p6_5_scb3_spi_s_select2 { + pinmux = ; + }; + + /omit-if-no-ref/ p7_3_scb3_spi_s_select2: p7_3_scb3_spi_s_select2 { + pinmux = ; + }; + + /omit-if-no-ref/ p10_5_scb2_spi_s_select2: p10_5_scb2_spi_s_select2 { + pinmux = ; + }; + + /omit-if-no-ref/ p11_5_scb1_spi_s_select2: p11_5_scb1_spi_s_select2 { + pinmux = ; + }; + + /omit-if-no-ref/ p11_5_scb4_spi_s_select2: p11_5_scb4_spi_s_select2 { + pinmux = ; + }; + + /* scb_spi_s_select3 */ + /omit-if-no-ref/ p0_2_scb0_spi_s_select3: p0_2_scb0_spi_s_select3 { + pinmux = ; + }; + + /omit-if-no-ref/ p1_6_scb0_spi_s_select3: p1_6_scb0_spi_s_select3 { + pinmux = ; + }; + + /omit-if-no-ref/ p2_6_scb1_spi_s_select3: p2_6_scb1_spi_s_select3 { + pinmux = ; + }; + + /omit-if-no-ref/ p3_6_scb1_spi_s_select3: p3_6_scb1_spi_s_select3 { + pinmux = ; + }; + + /omit-if-no-ref/ p3_6_scb4_spi_s_select3: p3_6_scb4_spi_s_select3 { + pinmux = ; + }; + + /omit-if-no-ref/ p4_6_scb0_spi_s_select3: p4_6_scb0_spi_s_select3 { + pinmux = ; + }; + + /omit-if-no-ref/ p5_6_scb2_spi_s_select3: p5_6_scb2_spi_s_select3 { + pinmux = ; + }; + + /omit-if-no-ref/ p7_6_scb3_spi_s_select3: p7_6_scb3_spi_s_select3 { + pinmux = ; + }; + + /omit-if-no-ref/ p12_0_scb3_spi_s_select3: p12_0_scb3_spi_s_select3 { + pinmux = ; + }; + + /* scb_uart_cts */ + /omit-if-no-ref/ p0_0_scb2_uart_cts: p0_0_scb2_uart_cts { + pinmux = ; + }; + + /omit-if-no-ref/ p0_6_scb1_uart_cts: p0_6_scb1_uart_cts { + pinmux = ; + }; + + /omit-if-no-ref/ p1_2_scb0_uart_cts: p1_2_scb0_uart_cts { + pinmux = ; + }; + + /omit-if-no-ref/ p2_6_scb3_uart_cts: p2_6_scb3_uart_cts { + pinmux = ; + }; + + /omit-if-no-ref/ p3_2_scb1_uart_cts: p3_2_scb1_uart_cts { + pinmux = ; + }; + + /omit-if-no-ref/ p4_2_scb0_uart_cts: p4_2_scb0_uart_cts { + pinmux = ; + }; + + /omit-if-no-ref/ p4_6_scb4_uart_cts: p4_6_scb4_uart_cts { + pinmux = ; + }; + + /omit-if-no-ref/ p5_2_scb2_uart_cts: p5_2_scb2_uart_cts { + pinmux = ; + }; + + /omit-if-no-ref/ p6_2_scb3_uart_cts: p6_2_scb3_uart_cts { + pinmux = ; + }; + + /omit-if-no-ref/ p7_2_scb3_uart_cts: p7_2_scb3_uart_cts { + pinmux = ; + }; + + /omit-if-no-ref/ p8_2_scb4_uart_cts: p8_2_scb4_uart_cts { + pinmux = ; + }; + + /omit-if-no-ref/ p9_2_scb0_uart_cts: p9_2_scb0_uart_cts { + pinmux = ; + }; + + /omit-if-no-ref/ p10_2_scb2_uart_cts: p10_2_scb2_uart_cts { + pinmux = ; + }; + + /omit-if-no-ref/ p11_2_scb4_uart_cts: p11_2_scb4_uart_cts { + pinmux = ; + }; + + /* scb_uart_rts */ + /omit-if-no-ref/ p0_1_scb2_uart_rts: p0_1_scb2_uart_rts { + pinmux = ; + }; + + /omit-if-no-ref/ p0_7_scb1_uart_rts: p0_7_scb1_uart_rts { + pinmux = ; + }; + + /omit-if-no-ref/ p1_3_scb0_uart_rts: p1_3_scb0_uart_rts { + pinmux = ; + }; + + /omit-if-no-ref/ p2_7_scb3_uart_rts: p2_7_scb3_uart_rts { + pinmux = ; + }; + + /omit-if-no-ref/ p3_3_scb1_uart_rts: p3_3_scb1_uart_rts { + pinmux = ; + }; + + /omit-if-no-ref/ p4_3_scb0_uart_rts: p4_3_scb0_uart_rts { + pinmux = ; + }; + + /omit-if-no-ref/ p4_7_scb4_uart_rts: p4_7_scb4_uart_rts { + pinmux = ; + }; + + /omit-if-no-ref/ p5_3_scb2_uart_rts: p5_3_scb2_uart_rts { + pinmux = ; + }; + + /omit-if-no-ref/ p6_3_scb3_uart_rts: p6_3_scb3_uart_rts { + pinmux = ; + }; + + /omit-if-no-ref/ p7_3_scb3_uart_rts: p7_3_scb3_uart_rts { + pinmux = ; + }; + + /omit-if-no-ref/ p8_3_scb4_uart_rts: p8_3_scb4_uart_rts { + pinmux = ; + }; + + /omit-if-no-ref/ p9_3_scb0_uart_rts: p9_3_scb0_uart_rts { + pinmux = ; + }; + + /omit-if-no-ref/ p10_3_scb2_uart_rts: p10_3_scb2_uart_rts { + pinmux = ; + }; + + /omit-if-no-ref/ p11_3_scb4_uart_rts: p11_3_scb4_uart_rts { + pinmux = ; + }; + + /* scb_uart_rx */ + /omit-if-no-ref/ p0_4_scb1_uart_rx: p0_4_scb1_uart_rx { + pinmux = ; + }; + + /omit-if-no-ref/ p0_4_scb2_uart_rx: p0_4_scb2_uart_rx { + pinmux = ; + }; + + /omit-if-no-ref/ p1_0_scb0_uart_rx: p1_0_scb0_uart_rx { + pinmux = ; + }; + + /omit-if-no-ref/ p2_4_scb3_uart_rx: p2_4_scb3_uart_rx { + pinmux = ; + }; + + /omit-if-no-ref/ p3_0_scb1_uart_rx: p3_0_scb1_uart_rx { + pinmux = ; + }; + + /omit-if-no-ref/ p4_0_scb0_uart_rx: p4_0_scb0_uart_rx { + pinmux = ; + }; + + /omit-if-no-ref/ p4_4_scb4_uart_rx: p4_4_scb4_uart_rx { + pinmux = ; + }; + + /omit-if-no-ref/ p5_0_scb2_uart_rx: p5_0_scb2_uart_rx { + pinmux = ; + }; + + /omit-if-no-ref/ p6_0_scb3_uart_rx: p6_0_scb3_uart_rx { + pinmux = ; + }; + + /omit-if-no-ref/ p7_0_scb3_uart_rx: p7_0_scb3_uart_rx { + pinmux = ; + }; + + /omit-if-no-ref/ p8_0_scb4_uart_rx: p8_0_scb4_uart_rx { + pinmux = ; + }; + + /omit-if-no-ref/ p9_0_scb0_uart_rx: p9_0_scb0_uart_rx { + pinmux = ; + }; + + /omit-if-no-ref/ p10_0_scb2_uart_rx: p10_0_scb2_uart_rx { + pinmux = ; + }; + + /omit-if-no-ref/ p11_0_scb4_uart_rx: p11_0_scb4_uart_rx { + pinmux = ; + }; + + /* scb_uart_tx */ + /omit-if-no-ref/ p0_5_scb1_uart_tx: p0_5_scb1_uart_tx { + pinmux = ; + }; + + /omit-if-no-ref/ p0_5_scb2_uart_tx: p0_5_scb2_uart_tx { + pinmux = ; + }; + + /omit-if-no-ref/ p0_6_scb2_uart_tx: p0_6_scb2_uart_tx { + pinmux = ; + }; + + /omit-if-no-ref/ p1_1_scb0_uart_tx: p1_1_scb0_uart_tx { + pinmux = ; + }; + + /omit-if-no-ref/ p2_5_scb3_uart_tx: p2_5_scb3_uart_tx { + pinmux = ; + }; + + /omit-if-no-ref/ p3_1_scb1_uart_tx: p3_1_scb1_uart_tx { + pinmux = ; + }; + + /omit-if-no-ref/ p4_1_scb0_uart_tx: p4_1_scb0_uart_tx { + pinmux = ; + }; + + /omit-if-no-ref/ p4_5_scb4_uart_tx: p4_5_scb4_uart_tx { + pinmux = ; + }; + + /omit-if-no-ref/ p5_1_scb2_uart_tx: p5_1_scb2_uart_tx { + pinmux = ; + }; + + /omit-if-no-ref/ p6_1_scb3_uart_tx: p6_1_scb3_uart_tx { + pinmux = ; + }; + + /omit-if-no-ref/ p7_1_scb3_uart_tx: p7_1_scb3_uart_tx { + pinmux = ; + }; + + /omit-if-no-ref/ p8_1_scb4_uart_tx: p8_1_scb4_uart_tx { + pinmux = ; + }; + + /omit-if-no-ref/ p9_1_scb0_uart_tx: p9_1_scb0_uart_tx { + pinmux = ; + }; + + /omit-if-no-ref/ p10_1_scb2_uart_tx: p10_1_scb2_uart_tx { + pinmux = ; + }; + + /omit-if-no-ref/ p11_1_scb4_uart_tx: p11_1_scb4_uart_tx { + pinmux = ; + }; + + /* PWM tcpwm_line*/ + /omit-if-no-ref/ p0_7_pwm0_0: p0_7_pwm0_0 { + pinmux = ; + }; + + /omit-if-no-ref/ p1_0_pwm0_2: p1_0_pwm0_2 { + pinmux = ; + }; + + /omit-if-no-ref/ p1_2_pwm0_3: p1_2_pwm0_3 { + pinmux = ; + }; + + /omit-if-no-ref/ p1_4_pwm0_6: p1_4_pwm0_6 { + pinmux = ; + }; + + /omit-if-no-ref/ p1_6_pwm0_7: p1_6_pwm0_7 { + pinmux = ; + }; + + /omit-if-no-ref/ p2_0_pwm0_4: p2_0_pwm0_4 { + pinmux = ; + }; + + /omit-if-no-ref/ p2_2_pwm0_5: p2_2_pwm0_5 { + pinmux = ; + }; + + /omit-if-no-ref/ p2_4_pwm0_0: p2_4_pwm0_0 { + pinmux = ; + }; + + /omit-if-no-ref/ p2_6_pwm0_1: p2_6_pwm0_1 { + pinmux = ; + }; + + /omit-if-no-ref/ p3_0_pwm0_0: p3_0_pwm0_0 { + pinmux = ; + }; + + /omit-if-no-ref/ p3_2_pwm0_1: p3_2_pwm0_1 { + pinmux = ; + }; + + /omit-if-no-ref/ p3_4_pwm0_2: p3_4_pwm0_2 { + pinmux = ; + }; + + /omit-if-no-ref/ p3_6_pwm0_3: p3_6_pwm0_3 { + pinmux = ; + }; + + /omit-if-no-ref/ p4_6_pwm0_6: p4_6_pwm0_6 { + pinmux = ; + }; + + /omit-if-no-ref/ p5_0_pwm0_4: p5_0_pwm0_4 { + pinmux = ; + }; + + /omit-if-no-ref/ p5_2_pwm0_5: p5_2_pwm0_5 { + pinmux = ; + }; + + /omit-if-no-ref/ p5_4_pwm0_6: p5_4_pwm0_6 { + pinmux = ; + }; + + /omit-if-no-ref/ p5_6_pwm0_7: p5_6_pwm0_7 { + pinmux = ; + }; + + /omit-if-no-ref/ p6_0_pwm0_4: p6_0_pwm0_4 { + pinmux = ; + }; + + /omit-if-no-ref/ p6_2_pwm0_5: p6_2_pwm0_5 { + pinmux = ; + }; + + /omit-if-no-ref/ p6_4_pwm0_6: p6_4_pwm0_6 { + pinmux = ; + }; + + /omit-if-no-ref/ p7_0_pwm0_0: p7_0_pwm0_0 { + pinmux = ; + }; + + /omit-if-no-ref/ p7_2_pwm0_1: p7_2_pwm0_1 { + pinmux = ; + }; + + /omit-if-no-ref/ p7_4_pwm0_2: p7_4_pwm0_2 { + pinmux = ; + }; + + /omit-if-no-ref/ p7_6_pwm0_3: p7_6_pwm0_3 { + pinmux = ; + }; + + /omit-if-no-ref/ p8_0_pwm0_4: p8_0_pwm0_4 { + pinmux = ; + }; + + /omit-if-no-ref/ p8_2_pwm0_5: p8_2_pwm0_5 { + pinmux = ; + }; + + /omit-if-no-ref/ p9_0_pwm0_0: p9_0_pwm0_0 { + pinmux = ; + }; + + /omit-if-no-ref/ p9_2_pwm0_1: p9_2_pwm0_1 { + pinmux = ; + }; + + /omit-if-no-ref/ p10_0_pwm0_7: p10_0_pwm0_7 { + pinmux = ; + }; + + /omit-if-no-ref/ p10_2_pwm0_2: p10_2_pwm0_2 { + pinmux = ; + }; + + /omit-if-no-ref/ p10_4_pwm0_3: p10_4_pwm0_3 { + pinmux = ; + }; + + /omit-if-no-ref/ p11_0_pwm0_4: p11_0_pwm0_4 { + pinmux = ; + }; + + /omit-if-no-ref/ p11_2_pwm0_5: p11_2_pwm0_5 { + pinmux = ; + }; + + /omit-if-no-ref/ p11_4_pwm0_6: p11_4_pwm0_6 { + pinmux = ; + }; + + /omit-if-no-ref/ p12_0_pwm0_7: p12_0_pwm0_7 { + pinmux = ; + }; + + /* PWM tcpwm_line_compl*/ + /omit-if-no-ref/ p1_1_pwm0_2: p1_1_pwm0_2_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p1_3_pwm0_3: p1_3_pwm0_3_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p1_5_pwm0_6: p1_5_pwm0_6_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p1_7_pwm0_7: p1_7_pwm0_7_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p2_1_pwm0_4: p2_1_pwm0_4_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p2_3_pwm0_5: p2_3_pwm0_5_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p2_5_pwm0_0: p2_5_pwm0_0_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p2_7_pwm0_1: p2_7_pwm0_1_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p3_1_pwm0_0: p3_1_pwm0_0_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p3_3_pwm0_1: p3_3_pwm0_1_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p3_5_pwm0_2: p3_5_pwm0_2_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p3_7_pwm0_3: p3_7_pwm0_3_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p4_7_pwm0_6: p4_7_pwm0_6_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p5_1_pwm0_4: p5_1_pwm0_4_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p5_3_pwm0_5: p5_3_pwm0_5_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p5_5_pwm0_6: p5_5_pwm0_6_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p5_7_pwm0_7: p5_7_pwm0_7_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p6_1_pwm0_4: p6_1_pwm0_4_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p6_3_pwm0_5: p6_3_pwm0_5_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p6_5_pwm0_6: p6_5_pwm0_6_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p7_1_pwm0_0: p7_1_pwm0_0_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p7_3_pwm0_1: p7_3_pwm0_1_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p7_5_pwm0_2: p7_5_pwm0_2_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p7_7_pwm0_3: p7_7_pwm0_3_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p8_1_pwm0_4: p8_1_pwm0_4_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p8_3_pwm0_5: p8_3_pwm0_5_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p9_1_pwm0_0: p9_1_pwm0_0_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p9_3_pwm0_1: p9_3_pwm0_1_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p10_1_pwm0_7: p10_1_pwm0_7_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p10_3_pwm0_2: p10_3_pwm0_2_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p10_5_pwm0_3: p10_5_pwm0_3_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p11_1_pwm0_4: p11_1_pwm0_4_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p11_3_pwm0_5: p11_3_pwm0_5_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p11_5_pwm0_6: p11_5_pwm0_6_compl { + pinmux = ; + }; + + /omit-if-no-ref/ p12_1_pwm0_7: p12_1_pwm0_7_compl { + pinmux = ; + }; + + /* PWM tcpwm_tr_in*/ + /omit-if-no-ref/ p0_0_pwm0_0: p0_0_pwm0_0 { + pinmux = ; + }; + + /omit-if-no-ref/ p0_1_pwm0_1: p0_1_pwm0_1 { + pinmux = ; + }; + + /omit-if-no-ref/ p1_2_pwm0_2: p1_2_pwm0_2 { + pinmux = ; + }; + + /omit-if-no-ref/ p1_3_pwm0_3: p1_3_pwm0_3 { + pinmux = ; + }; + + /omit-if-no-ref/ p2_1_pwm0_5: p2_1_pwm0_5 { + pinmux = ; + }; + + /omit-if-no-ref/ p3_4_pwm0_6: p3_4_pwm0_6 { + pinmux = ; + }; + }; + }; +}; diff --git a/dts/arm/infineon/psoc4/psoc4100smax/psoc4100smax.cm0p.dtsi b/dts/arm/infineon/psoc4/psoc4100smax/psoc4100smax.cm0p.dtsi new file mode 100644 index 000000000000..89e6ac1a87e2 --- /dev/null +++ b/dts/arm/infineon/psoc4/psoc4100smax/psoc4100smax.cm0p.dtsi @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/ { + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-m0+"; + reg = <0>; + clock-frequency = <48000000>; + }; + }; + + soc { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + /* Pinctrl node for Infineon PSOC4 SoC */ + pinctrl0: pinctrl@40310000 { + compatible = "infineon,cat1-pinctrl"; + reg = <0x40310000 0x1000>; + status = "okay"; + }; + }; +}; + +&nvic { + arm,num-irq-priority-bits = <2>; +}; diff --git a/dts/arm/infineon/psoc4/psoc4100smax/psoc4100smax.dtsi b/dts/arm/infineon/psoc4/psoc4100smax/psoc4100smax.dtsi new file mode 100644 index 000000000000..0835dae8df8c --- /dev/null +++ b/dts/arm/infineon/psoc4/psoc4100smax/psoc4100smax.dtsi @@ -0,0 +1,351 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "psoc4100smax.cm0p.dtsi" +#include + +/ { + flash0: flash@0 { + compatible = "soc-nv-flash"; + reg = <0x00000000 DT_SIZE_K(384)>; /* 384 KB Flash */ + }; + + sram0: memory@20000000 { + compatible = "mmio-sram"; + reg = <0x20000000 DT_SIZE_K(32)>; /* 32 KB SRAM */ + }; + + soc { + pinctrl: pinctrl@40020000 { + compatible = "infineon,pinctrl"; + reg = <0x40020000 0x24000>; + }; + + hsiom: hsiom@40020000 { + compatible = "infineon,hsiom"; + reg = <0x40020000 0x4000>; + status = "disabled"; + }; + + gpio_prt0: gpio@40040000 { + compatible = "infineon,gpio"; + reg = <0x40040000 0x100>; + interrupts = <0 3>; + gpio-controller; + ngpios = <8>; + status = "disabled"; + #gpio-cells = <2>; + }; + + gpio_prt1: gpio@40040100 { + compatible = "infineon,gpio"; + reg = <0x40040100 0x100>; + interrupts = <1 3>; + gpio-controller; + ngpios = <8>; + status = "disabled"; + #gpio-cells = <2>; + }; + + gpio_prt2: gpio@40040200 { + compatible = "infineon,gpio"; + reg = <0x40040200 0x100>; + interrupts = <2 3>; + gpio-controller; + ngpios = <8>; + status = "disabled"; + #gpio-cells = <2>; + }; + + gpio_prt3: gpio@40040300 { + compatible = "infineon,gpio"; + reg = <0x40040300 0x100>; + interrupts = <3 3>; + gpio-controller; + ngpios = <8>; + status = "disabled"; + #gpio-cells = <2>; + }; + + /* Ports 4-12 share interrupt 4 (ioss_interrupt_gpio_IRQn) */ + gpio_prt4: gpio@40040400 { + compatible = "infineon,gpio"; + reg = <0x40040400 0x100>; + interrupts = <4 3>; + gpio-controller; + ngpios = <8>; + status = "disabled"; + #gpio-cells = <2>; + }; + + gpio_prt5: gpio@40040500 { + compatible = "infineon,gpio"; + reg = <0x40040500 0x100>; + interrupts = <4 3>; + gpio-controller; + ngpios = <8>; + status = "disabled"; + #gpio-cells = <2>; + }; + + gpio_prt6: gpio@40040600 { + compatible = "infineon,gpio"; + reg = <0x40040600 0x100>; + interrupts = <4 3>; + gpio-controller; + ngpios = <8>; + status = "disabled"; + #gpio-cells = <2>; + }; + + gpio_prt7: gpio@40040700 { + compatible = "infineon,gpio"; + reg = <0x40040700 0x100>; + interrupts = <4 3>; + gpio-controller; + ngpios = <8>; + status = "disabled"; + #gpio-cells = <2>; + }; + + gpio_prt8: gpio@40040800 { + compatible = "infineon,gpio"; + reg = <0x40040800 0x100>; + interrupts = <4 3>; + gpio-controller; + ngpios = <8>; + status = "disabled"; + #gpio-cells = <2>; + }; + + gpio_prt9: gpio@40040900 { + compatible = "infineon,gpio"; + reg = <0x40040900 0x100>; + interrupts = <4 3>; + gpio-controller; + ngpios = <8>; + status = "disabled"; + #gpio-cells = <2>; + }; + + gpio_prt10: gpio@40040a00 { + compatible = "infineon,gpio"; + reg = <0x40040a00 0x100>; + interrupts = <4 3>; + gpio-controller; + ngpios = <8>; + status = "disabled"; + #gpio-cells = <2>; + }; + + gpio_prt11: gpio@40040b00 { + compatible = "infineon,gpio"; + reg = <0x40040b00 0x100>; + interrupts = <4 3>; + gpio-controller; + ngpios = <6>; + status = "disabled"; + #gpio-cells = <2>; + }; + + gpio_prt12: gpio@40040c00 { + compatible = "infineon,gpio"; + reg = <0x40040c00 0x100>; + interrupts = <4 3>; + gpio-controller; + ngpios = <2>; + status = "disabled"; + #gpio-cells = <2>; + }; + + scb0: scb@40240000 { + compatible = "infineon,scb"; + reg = <0x40240000 0xfd0>; + interrupts = <7 3>; + status = "disabled"; + }; + + scb1: scb@40250000 { + compatible = "infineon,scb"; + reg = <0x40250000 0xfd0>; + interrupts = <8 3>; + status = "disabled"; + }; + + scb2: scb@40260000 { + compatible = "infineon,scb"; + reg = <0x40260000 0xfd0>; + interrupts = <9 3>; + status = "disabled"; + }; + + scb3: scb@40270000 { + compatible = "infineon,scb"; + reg = <0x40270000 0xfd0>; + interrupts = <10 3>; + status = "disabled"; + }; + + scb4: scb@40280000 { + compatible = "infineon,scb"; + reg = <0x40280000 0xfd0>; + interrupts = <11 3>; + status = "disabled"; + }; + + tcpwm0: tcpwm0@40200100 { + reg = <0x40200100 0x240>; + #address-cells = <1>; + #size-cells = <1>; + + tcpwm0_0: tcpwm0_0@40200100 { + compatible = "infineon,tcpwm"; + reg = <0x40200100 0x40>; + resolution = <16>; + status = "disabled"; + + pwm0_0: pwm0_0 { + compatible = "infineon,tcpwm-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + + counter0_0: counter0_0 { + compatible = "infineon,tcpwm-counter"; + status = "disabled"; + }; + }; + + tcpwm0_1: tcpwm0_1@40200140 { + compatible = "infineon,tcpwm"; + reg = <0x40200140 0x40>; + resolution = <16>; + status = "disabled"; + + pwm0_1: pwm0_1 { + compatible = "infineon,tcpwm-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + + counter0_1: counter0_1 { + compatible = "infineon,tcpwm-counter"; + status = "disabled"; + }; + }; + + tcpwm0_2: tcpwm0_2@40200180 { + compatible = "infineon,tcpwm"; + reg = <0x40200180 0x40>; + resolution = <16>; + status = "disabled"; + + pwm0_2: pwm0_2 { + compatible = "infineon,tcpwm-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + + counter0_2: counter0_2 { + compatible = "infineon,tcpwm-counter"; + status = "disabled"; + }; + }; + + tcpwm0_3: tcpwm0_3@402001c0 { + compatible = "infineon,tcpwm"; + reg = <0x402001c0 0x40>; + resolution = <16>; + status = "disabled"; + + pwm0_3: pwm0_3 { + compatible = "infineon,tcpwm-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + + counter0_3: counter0_3 { + compatible = "infineon,tcpwm-counter"; + status = "disabled"; + }; + }; + + tcpwm0_4: tcpwm0_4@40200200 { + compatible = "infineon,tcpwm"; + reg = <0x40200200 0x40>; + resolution = <16>; + status = "disabled"; + + pwm0_4: pwm0_4 { + compatible = "infineon,tcpwm-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + + counter0_4: counter0_4 { + compatible = "infineon,tcpwm-counter"; + status = "disabled"; + }; + }; + + tcpwm0_5: tcpwm0_5@40200240 { + compatible = "infineon,tcpwm"; + reg = <0x40200240 0x40>; + resolution = <16>; + status = "disabled"; + + pwm0_5: pwm0_5 { + compatible = "infineon,tcpwm-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + + counter0_5: counter0_5 { + compatible = "infineon,tcpwm-counter"; + status = "disabled"; + }; + }; + + tcpwm0_6: tcpwm0_6@40200280 { + compatible = "infineon,tcpwm"; + reg = <0x40200280 0x40>; + resolution = <16>; + status = "disabled"; + + pwm0_6: pwm0_6 { + compatible = "infineon,tcpwm-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + + counter0_6: counter0_6 { + compatible = "infineon,tcpwm-counter"; + status = "disabled"; + }; + }; + + tcpwm0_7: tcpwm0_7@402002c0 { + compatible = "infineon,tcpwm"; + reg = <0x402002c0 0x40>; + resolution = <16>; + status = "disabled"; + + pwm0_7: pwm0_7 { + compatible = "infineon,tcpwm-pwm"; + #pwm-cells = <3>; + status = "disabled"; + }; + + counter0_7: counter0_7 { + compatible = "infineon,tcpwm-counter"; + status = "disabled"; + }; + }; + }; + }; +}; diff --git a/dts/arm/infineon/psoc4/psoc4100smax/system_clocks.dtsi b/dts/arm/infineon/psoc4/psoc4100smax/system_clocks.dtsi new file mode 100644 index 000000000000..322814d231fd --- /dev/null +++ b/dts/arm/infineon/psoc4/psoc4100smax/system_clocks.dtsi @@ -0,0 +1,237 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DIV_16_BIT 1 +#define DIV_16_5_BIT 2 +#define DIV_24_5_BIT 3 + +#include +#include +#include "freq.h" + +/ { + clocks { + /* Internal main oscillator (IMO) */ + clk_imo: clk-imo { + #clock-cells = <0>; + compatible = "infineon,fixed-clock"; + clock-frequency = ; + system-clock = ; + status = "okay"; + }; + + /* Internal low-speed oscillator (ILO) */ + clk_ilo: clk-ilo { + #clock-cells = <0>; + compatible = "infineon,fixed-clock"; + clock-frequency = ; + system-clock = ; + status = "okay"; + }; + + /* External clock (EXTCLK) */ + clk_ext: clk-extclk { + #clock-cells = <0>; + compatible = "infineon,fixed-clock"; + clock-frequency = ; + system-clock = ; + status = "okay"; + }; + + /* Watch crystal oscillator (WCO) */ + clk_wco: clk-wco { + #clock-cells = <0>; + compatible = "infineon,fixed-clock"; + clock-frequency = <0>; + system-clock = ; + status = "okay"; + }; + + clk_hf: clk-hf { + #clock-cells = <0>; + compatible = "infineon,fixed-factor-clock"; + clock-div = ; + source-path = ; + system-clock = ; + instance = <0>; + status = "disabled"; + }; + + clk_pump: clk-pump { + #clock-cells = <0>; + compatible = "infineon,fixed-factor-clock"; + system-clock = ; + source-path = ; + instance = <0>; + status = "disabled"; + }; + }; + + peri_div: peri-div { + peri_clk_div0: peri-clk-div0 { + #clock-cells = <0>; + compatible = "infineon,peri-div"; + div-type = ; + channel = <0>; + clock-div = <1>; + status = "disabled"; + }; + + peri_clk_div1: peri-clk-div1 { + #clock-cells = <0>; + compatible = "infineon,peri-div"; + div-type = ; + channel = <1>; + clock-div = <1>; + status = "disabled"; + }; + + peri_clk_div2: peri-clk-div2 { + #clock-cells = <0>; + compatible = "infineon,peri-div"; + div-type = ; + channel = <2>; + clock-div = <1>; + status = "disabled"; + }; + + peri_clk_div3: peri-clk-div3 { + #clock-cells = <0>; + compatible = "infineon,peri-div"; + div-type = ; + channel = <3>; + clock-div = <1>; + status = "disabled"; + }; + + peri_clk_div4: peri-clk-div4 { + #clock-cells = <0>; + compatible = "infineon,peri-div"; + div-type = ; + channel = <4>; + clock-div = <1>; + status = "disabled"; + }; + + peri_clk_div5: peri-clk-div5 { + #clock-cells = <0>; + compatible = "infineon,peri-div"; + div-type = ; + channel = <5>; + clock-div = <1>; + status = "disabled"; + }; + + peri_clk_div6: peri-clk-div6 { + #clock-cells = <0>; + compatible = "infineon,peri-div"; + div-type = ; + channel = <6>; + clock-div = <1>; + status = "disabled"; + }; + + peri_clk_div7: peri-clk-div7 { + #clock-cells = <0>; + compatible = "infineon,peri-div"; + div-type = ; + channel = <7>; + clock-div = <1>; + status = "disabled"; + }; + + peri_clk_div8: peri-clk-div8 { + #clock-cells = <0>; + compatible = "infineon,peri-div"; + div-type = ; + channel = <8>; + clock-div = <1>; + status = "disabled"; + }; + + peri_clk_div9: peri-clk-div9 { + #clock-cells = <0>; + compatible = "infineon,peri-div"; + div-type = ; + channel = <9>; + clock-div = <1>; + status = "disabled"; + }; + + peri_clk_div10: peri-clk-div10 { + #clock-cells = <0>; + compatible = "infineon,peri-div"; + div-type = ; + channel = <10>; + clock-div = <1>; + status = "disabled"; + }; + + peri_clk_div11: peri-clk-div11 { + #clock-cells = <0>; + compatible = "infineon,peri-div"; + div-type = ; + channel = <11>; + clock-div = <1>; + status = "disabled"; + }; + + peri_clk_fract_div0: peri-clk-fract-div0 { + #clock-cells = <0>; + compatible = "infineon,peri-div"; + div-type = ; + channel = <0>; + clock-div = <1>; + status = "disabled"; + }; + + peri_clk_fract_div1: peri-clk-fract-div1 { + #clock-cells = <0>; + compatible = "infineon,peri-div"; + div-type = ; + channel = <1>; + clock-div = <1>; + status = "disabled"; + }; + + peri_clk_fract_div2: peri-clk-fract-div2 { + #clock-cells = <0>; + compatible = "infineon,peri-div"; + div-type = ; + channel = <2>; + clock-div = <1>; + status = "disabled"; + }; + + peri_clk_fract_div3: peri-clk-fract-div3 { + #clock-cells = <0>; + compatible = "infineon,peri-div"; + div-type = ; + channel = <3>; + clock-div = <1>; + status = "disabled"; + }; + + peri_clk_fract_div4: peri-clk-fract-div4 { + #clock-cells = <0>; + compatible = "infineon,peri-div"; + div-type = ; + channel = <4>; + clock-div = <1>; + status = "disabled"; + }; + + peri_clk_fract_div5: peri-clk-fract-div5 { + #clock-cells = <0>; + compatible = "infineon,peri-div"; + div-type = ; + channel = <0>; + clock-div = <1>; + status = "disabled"; + }; + }; +}; From fe9ecee97e21297a07da450b27cbd5142ff2e663 Mon Sep 17 00:00:00 2001 From: Braeden Lane Date: Wed, 10 Dec 2025 14:02:48 -0800 Subject: [PATCH 2485/3659] drivers: gpio: Add Infineon PSOC 4 GPIO driver support Add GPIO driver for Infineon PSOC 4 series MCUs using the Infineon PDL. Signed-off-by: Braeden Lane --- drivers/gpio/CMakeLists.txt | 2 +- drivers/gpio/Kconfig.infineon | 11 ++++++----- drivers/gpio/gpio_infineon.c | 19 +------------------ 3 files changed, 8 insertions(+), 24 deletions(-) diff --git a/drivers/gpio/CMakeLists.txt b/drivers/gpio/CMakeLists.txt index 3811b378f4ec..24581982d465 100644 --- a/drivers/gpio/CMakeLists.txt +++ b/drivers/gpio/CMakeLists.txt @@ -38,7 +38,7 @@ zephyr_library_sources_ifdef(CONFIG_GPIO_GD32 gpio_gd32.c) zephyr_library_sources_ifdef(CONFIG_GPIO_GECKO gpio_gecko.c) zephyr_library_sources_ifdef(CONFIG_GPIO_GRGPIO2 gpio_grgpio2.c) zephyr_library_sources_ifdef(CONFIG_GPIO_IMX gpio_imx.c) -zephyr_library_sources_ifdef(CONFIG_GPIO_INFINEON_CAT1 gpio_infineon.c) +zephyr_library_sources_ifdef(CONFIG_GPIO_INFINEON gpio_infineon.c) zephyr_library_sources_ifdef(CONFIG_GPIO_INTEL gpio_intel.c) zephyr_library_sources_ifdef(CONFIG_GPIO_IPROC gpio_iproc.c) zephyr_library_sources_ifdef(CONFIG_GPIO_ITE_IT51XXX gpio_ite_it51xxx.c) diff --git a/drivers/gpio/Kconfig.infineon b/drivers/gpio/Kconfig.infineon index d80c7cfc6234..35e7fd4a7351 100644 --- a/drivers/gpio/Kconfig.infineon +++ b/drivers/gpio/Kconfig.infineon @@ -1,12 +1,13 @@ -# Infineon CAT1 GPIO configuration options +# Infineon GPIO configuration options -# Copyright (c) 2022 Cypress Semiconductor Corporation (an Infineon company) or +# Copyright (c) 2022-2025 Cypress Semiconductor Corporation (an Infineon company) or # an affiliate of Cypress Semiconductor Corporation # SPDX-License-Identifier: Apache-2.0 -config GPIO_INFINEON_CAT1 - bool "Infineon CAT1 GPIO driver" +config GPIO_INFINEON + bool "Infineon GPIO driver" default y depends on DT_HAS_INFINEON_GPIO_ENABLED help - Enable support for Infineon CAT1 GPIO controllers. + Enable GPIO driver for Infineon MCUs using the "infineon,gpio" + compatible. diff --git a/drivers/gpio/gpio_infineon.c b/drivers/gpio/gpio_infineon.c index 767fd4f62eb2..fcb47893ea32 100644 --- a/drivers/gpio/gpio_infineon.c +++ b/drivers/gpio/gpio_infineon.c @@ -206,24 +206,7 @@ static uint32_t gpio_cat1_get_pending_int(const struct device *dev) static uint32_t __maybe_unused gpio_get_pending_pins(const struct gpio_cat1_config *const cfg, GPIO_PRT_Type * const base) { - uint32_t pending; - -#if defined(CONFIG_SOC_FAMILY_INFINEON_PSOC4) - uint32_t intr_status = base->INTR; - uint32_t intr_mask = 0U; - - for (uint8_t i = 0; i < cfg->ngpios; i++) { - uint32_t intr_cfg = (base->INTR_CFG >> (i * 2U)) & 0x3U; - - if (intr_cfg != CY_GPIO_INTR_DISABLE) { - intr_mask |= BIT(i); - } - } - - pending = intr_status & intr_mask; -#else - pending = GPIO_PRT_INTR_MASKED(base); -#endif + uint32_t pending = GPIO_PRT_INTR(base) & gpio_cat1_valid_mask(cfg->ngpios); return pending; } From f68885f1c6e76cbf4cbe701e8bd84adcc3509e41 Mon Sep 17 00:00:00 2001 From: Braeden Lane Date: Wed, 10 Dec 2025 14:04:01 -0800 Subject: [PATCH 2486/3659] drivers: Add PSOC 4 clock control and serial support Add clock control and UART support for PSOC 4 family: - Clock control drivers with PSOC 4 compatibility - PSOC4xx clock source bindings and definitions - HF clock divider configuration support - UART FIFO trigger level configuration for PSOC 4100S Max series with 8-deep FIFO (RX trigger=7, TX trigger=0) Signed-off-by: Braeden Lane --- drivers/serial/uart_infineon_pdl.c | 6 +++--- include/zephyr/dt-bindings/clock/ifx_clock_source_boards.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/serial/uart_infineon_pdl.c b/drivers/serial/uart_infineon_pdl.c index f9d0647951a6..89a831f8f41e 100644 --- a/drivers/serial/uart_infineon_pdl.c +++ b/drivers/serial/uart_infineon_pdl.c @@ -46,13 +46,13 @@ LOG_MODULE_REGISTER(uart_ifx, CONFIG_UART_LOG_LEVEL); #define _IFX_CAT1_SCB_ARRAY_SIZE (CY_IP_MXS22SCB_INSTANCES) #endif /* CY_IP_MXSCB_INSTANCES */ -#if defined(CONFIG_SOC_SERIES_PSOC4100TP) +#if defined(CONFIG_SOC_FAMILY_INFINEON_PSOC4) #define IFX_UART_RX_FIFO_TRIGGER_LEVEL 7 #define IFX_UART_TX_FIFO_TRIGGER_LEVEL 0 #else #define IFX_UART_RX_FIFO_TRIGGER_LEVEL 63UL #define IFX_UART_TX_FIFO_TRIGGER_LEVEL 63UL -#endif /* CONFIG_SOC_SERIES_PSOC4100TP */ +#endif /* CONFIG_SOC_FAMILY_INFINEON_PSOC4 */ #define IFX_UART_RX_INT_MASK_NONE 0UL #define IFX_UART_TX_INT_MASK_NONE 0UL @@ -698,7 +698,7 @@ static const cy_stc_scb_uart_config_t _uart_default_config = { .breakWidth = 11UL, .dropOnFrameError = false, .dropOnParityError = false, -#if !defined(CONFIG_SOC_SERIES_PSOC4100TP) +#if !defined(CONFIG_SOC_FAMILY_INFINEON_PSOC4) .breaklevel = false, #else .breakLevel = false, diff --git a/include/zephyr/dt-bindings/clock/ifx_clock_source_boards.h b/include/zephyr/dt-bindings/clock/ifx_clock_source_boards.h index 42b8efc285eb..e94a3eb33481 100644 --- a/include/zephyr/dt-bindings/clock/ifx_clock_source_boards.h +++ b/include/zephyr/dt-bindings/clock/ifx_clock_source_boards.h @@ -9,6 +9,6 @@ #include "ifx_clock_source_pse8xx.h" #elif defined(CONFIG_SOC_SERIES_PSC3) #include "ifx_clock_source_psc3xx.h" -#elif defined(CONFIG_SOC_SERIES_PSOC4100TP) +#elif defined(CONFIG_SOC_FAMILY_INFINEON_PSOC4) #include "ifx_clock_source_psoc4xx.h" #endif From 060fe41df02024288056613dc1655cff920d1b48 Mon Sep 17 00:00:00 2001 From: Braeden Lane Date: Wed, 10 Dec 2025 14:05:21 -0800 Subject: [PATCH 2487/3659] boards: infineon: Add CY8CKIT-041S-MAX board Add support for Infineon CY8CKIT-041S-MAX development kit based on CY8C4149AZI-S598 (PSoC 4100S Max). Board features: - 100-pin TQFP PSOC 4100S Max MCU (384KB Flash, 32KB SRAM) - User LED and button - KitProg3 for programming/debugging - Common dtsi structure for peripheral configuration Signed-off-by: Braeden Lane --- .../cy8ckit_041s_max/Kconfig.cy8ckit_041s_max | 7 ++ boards/infineon/cy8ckit_041s_max/board.cmake | 7 ++ boards/infineon/cy8ckit_041s_max/board.yml | 11 +++ .../cy8ckit_041s_max-pinctrl.dtsi | 15 +++ .../cy8ckit_041s_max/cy8ckit_041s_max.dts | 38 ++++++++ .../cy8ckit_041s_max/cy8ckit_041s_max.yaml | 20 ++++ .../cy8ckit_041s_max_common.dtsi | 68 +++++++++++++ .../cy8ckit_041s_max_defconfig | 14 +++ .../infineon/cy8ckit_041s_max/docs/index.rst | 97 +++++++++++++++++++ .../cy8ckit_041s_max/support/openocd.cfg | 18 ++++ 10 files changed, 295 insertions(+) create mode 100644 boards/infineon/cy8ckit_041s_max/Kconfig.cy8ckit_041s_max create mode 100644 boards/infineon/cy8ckit_041s_max/board.cmake create mode 100644 boards/infineon/cy8ckit_041s_max/board.yml create mode 100644 boards/infineon/cy8ckit_041s_max/cy8ckit_041s_max-pinctrl.dtsi create mode 100644 boards/infineon/cy8ckit_041s_max/cy8ckit_041s_max.dts create mode 100644 boards/infineon/cy8ckit_041s_max/cy8ckit_041s_max.yaml create mode 100644 boards/infineon/cy8ckit_041s_max/cy8ckit_041s_max_common.dtsi create mode 100644 boards/infineon/cy8ckit_041s_max/cy8ckit_041s_max_defconfig create mode 100644 boards/infineon/cy8ckit_041s_max/docs/index.rst create mode 100644 boards/infineon/cy8ckit_041s_max/support/openocd.cfg diff --git a/boards/infineon/cy8ckit_041s_max/Kconfig.cy8ckit_041s_max b/boards/infineon/cy8ckit_041s_max/Kconfig.cy8ckit_041s_max new file mode 100644 index 000000000000..3051ffa83c44 --- /dev/null +++ b/boards/infineon/cy8ckit_041s_max/Kconfig.cy8ckit_041s_max @@ -0,0 +1,7 @@ +# Copyright (c) 2025 Infineon Technologies AG, +# or an affiliate of Infineon Technologies AG. +# +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_CY8CKIT_041S_MAX + select SOC_CY8C4149AZI_S598 diff --git a/boards/infineon/cy8ckit_041s_max/board.cmake b/boards/infineon/cy8ckit_041s_max/board.cmake new file mode 100644 index 000000000000..85b1fb6ebeae --- /dev/null +++ b/boards/infineon/cy8ckit_041s_max/board.cmake @@ -0,0 +1,7 @@ +# Copyright (c) 2025 Infineon Technologies AG, +# or an affiliate of Infineon Technologies AG. +# +# SPDX-License-Identifier: Apache-2.0 + +# Include standard OpenOCD runner helpers +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) diff --git a/boards/infineon/cy8ckit_041s_max/board.yml b/boards/infineon/cy8ckit_041s_max/board.yml new file mode 100644 index 000000000000..ac5f159fdeb4 --- /dev/null +++ b/boards/infineon/cy8ckit_041s_max/board.yml @@ -0,0 +1,11 @@ +# Copyright (c) 2025 Infineon Technologies AG, +# or an affiliate of Infineon Technologies AG. +# +# SPDX-License-Identifier: Apache-2.0 + +board: + name: cy8ckit_041s_max + full_name: PSOC™ 4100S Max pioneer kit + vendor: infineon + socs: + - name: cy8c4149azi_s598 diff --git a/boards/infineon/cy8ckit_041s_max/cy8ckit_041s_max-pinctrl.dtsi b/boards/infineon/cy8ckit_041s_max/cy8ckit_041s_max-pinctrl.dtsi new file mode 100644 index 000000000000..f192b77eaad8 --- /dev/null +++ b/boards/infineon/cy8ckit_041s_max/cy8ckit_041s_max-pinctrl.dtsi @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* Configure pin drive mode for uart pins */ +&p0_5_scb2_uart_tx { + drive-push-pull; +}; + +&p0_4_scb2_uart_rx { + input-enable; +}; diff --git a/boards/infineon/cy8ckit_041s_max/cy8ckit_041s_max.dts b/boards/infineon/cy8ckit_041s_max/cy8ckit_041s_max.dts new file mode 100644 index 000000000000..4e0256e44eaf --- /dev/null +++ b/boards/infineon/cy8ckit_041s_max/cy8ckit_041s_max.dts @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include + +#include "cy8ckit_041s_max_common.dtsi" + +/ { + model = "CY8CKIT-041S-MAX Development Board"; + compatible = "infineon,cy8ckit-041s-max", "infineon,psoc4100smax"; + + chosen { + zephyr,sram = &sram0; + zephyr,flash = &flash0; + zephyr,console = &uart2; + zephyr,shell-uart = &uart2; + }; + + aliases { + led0 = &user_led1; + }; + + leds { + compatible = "gpio-leds"; + status = "okay"; + + user_led1: led_1 { + label = "LED_1"; + gpios = <&gpio_prt7 3 GPIO_ACTIVE_LOW>; + }; + }; +}; diff --git a/boards/infineon/cy8ckit_041s_max/cy8ckit_041s_max.yaml b/boards/infineon/cy8ckit_041s_max/cy8ckit_041s_max.yaml new file mode 100644 index 000000000000..cbae5def6d3d --- /dev/null +++ b/boards/infineon/cy8ckit_041s_max/cy8ckit_041s_max.yaml @@ -0,0 +1,20 @@ +# Copyright (c) 2025 Infineon Technologies AG, +# or an affiliate of Infineon Technologies AG. +# +# SPDX-License-Identifier: Apache-2.0 + +identifier: cy8ckit_041s_max +name: CY8CKIT-041S-MAX Development Board +type: mcu +arch: arm +ram: 32 +flash: 384 +toolchain: + - zephyr + - gnuarmemb +supported: + - uart + - gpio + - clock_control + - pinctrl +vendor: infineon diff --git a/boards/infineon/cy8ckit_041s_max/cy8ckit_041s_max_common.dtsi b/boards/infineon/cy8ckit_041s_max/cy8ckit_041s_max_common.dtsi new file mode 100644 index 000000000000..89220cc928b7 --- /dev/null +++ b/boards/infineon/cy8ckit_041s_max/cy8ckit_041s_max_common.dtsi @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "cy8ckit_041s_max-pinctrl.dtsi" + +uart2: &scb2 { + compatible = "infineon,uart"; + status = "okay"; + current-speed = <115200>; + clocks = <&peri_clk_div1>; + pinctrl-0 = <&p0_5_scb2_uart_tx &p0_4_scb2_uart_rx>; + pinctrl-names = "default"; +}; + +&peri_clk_div0 { + status = "okay"; + resource-type = ; + resource-instance = <0>; +}; + +&peri_clk_div1 { + status = "okay"; + resource-type = ; + resource-instance = <2>; +}; + +&peri_clk_div2 { + status = "okay"; + resource-type = ; + resource-instance = <1>; +}; + +&peri_clk_div3 { + status = "okay"; + resource-type = ; + resource-instance = <0>; + clock-div = <11500>; +}; + +/* + * Note : use IFX_PATH_PSOC4_IMO for internal main oscillator as src + * use IFX_PATH_PSOC4_EXT for External clock as src + */ +&clk_hf { + status = "okay"; + source-path = ; +}; + +/* + * Note : use IFX_PATH_PSOC4_PUMP_GND for No clock, connect to gnd + * use IFX_PATH_PSOC4_PUMP_IMO for main IMO pump output + * use IFX_PATH_PSOC4_PUMP_HFCLK for clk_hf pump + * + * usage : The pump clock can be used for the analog pump + */ +&clk_pump { + status = "okay"; + source-path = ; +}; + +&gpio_prt7 { + status = "okay"; +}; diff --git a/boards/infineon/cy8ckit_041s_max/cy8ckit_041s_max_defconfig b/boards/infineon/cy8ckit_041s_max/cy8ckit_041s_max_defconfig new file mode 100644 index 000000000000..ab312bcd2d16 --- /dev/null +++ b/boards/infineon/cy8ckit_041s_max/cy8ckit_041s_max_defconfig @@ -0,0 +1,14 @@ +# Copyright (c) 2025 Infineon Technologies AG, +# or an affiliate of Infineon Technologies AG. +# +# SPDX-License-Identifier: Apache-2.0 + +# Console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +# UART driver +CONFIG_SERIAL=y + +# Clock controller +CONFIG_CLOCK_CONTROL=y diff --git a/boards/infineon/cy8ckit_041s_max/docs/index.rst b/boards/infineon/cy8ckit_041s_max/docs/index.rst new file mode 100644 index 000000000000..2a8540f78547 --- /dev/null +++ b/boards/infineon/cy8ckit_041s_max/docs/index.rst @@ -0,0 +1,97 @@ +.. zephyr:board:: cy8ckit_041s_max + +Overview +******** + +The PSOC™ 4100S Max Pioneer Kit (CY8CKIT-041S-MAX) enables you to evaluate and develop applications using the PSOC™ 4100S Max microcontroller, part of Infineon's PSOC™ 4 family. +The device integrates an Arm Cortex-M0+ CPU running up to 48 MHz, combining programmable analog and digital subsystems to support flexible mixed-signal designs. It features up to 384 KB Flash and up to 32 KB SRAM, and includes a wide range of configurable peripherals such as SAR ADC, comparators, opamps (CTBm), CapSense™ capacitive touch sensing, and TCPWM for timer/counter/PWM functionality. + +32-bit MCU subsystem +- 48-MHz Arm® Cortex®-M0+ CPU with single-cycle multiply +- Up to 384 KB of flash with read accelerator +- Up to 32 KB of SRAM +- Direct memory access (DMA) +- Low-power 1.71 V to 5.5 V operation +- Deep sleep mode with low-power touch sensing +- Active touch detection and tracking with low power consumption +- Real Time clock support +- Power supply: 3.3 V or 5 V operation + +Programming and Debugging +************************* + +.. zephyr:board-supported-runners:: + +Building +======== + +Here is an example for building the :zephyr:code-sample:`hello_world` sample application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: cy8ckit_041s_max + :goals: build + +Flashing +======== + +The CY8CKIT-041S-MAX includes an onboard programmer/debugger (`KitProg3`_) to provide debugging, flash programming, and serial communication over USB. Flash and debug commands use OpenOCD and require a custom Infineon OpenOCD version, that supports KitProg3, to be installed. + +Infineon OpenOCD Installation +============================= + +Both the full `ModusToolbox`_ and the `ModusToolbox Programming Tools`_ packages include Infineon OpenOCD. +Installing either of these packages will also install Infineon OpenOCD. + +If neither package is installed, a minimal installation can be done by downloading the `Infineon OpenOCD`_ release for your system and manually extract the files to a location of your choice. + +.. note:: Linux requires device access rights to be set up for KitProg3. This is handled automatically by the ModusToolbox and ModusToolbox Programming Tools installations. When doing a minimal installation, this can be done manually by executing the script ``openocd/udev_rules/install_rules.sh``. + +West Commands +============= + +The path to the installed Infineon OpenOCD executable must be available to the ``west`` tool commands. There are multiple ways of doing this. The example below uses a permanent CMake argument to set the CMake variable ``OPENOCD``. + +Run ``west config`` once to set permanent CMake argument: + + .. tabs:: + .. group-tab:: Windows + + .. code-block:: shell + + west config build.cmake-args -- -DOPENOCD=path/to/infineon/openocd/bin/openocd.exe + + .. group-tab:: Linux + + .. code-block:: shell + + west config build.cmake-args -- -DOPENOCD=path/to/infineon/openocd/bin/openocd + +Once configured, you can build and flash applications: + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: cy8ckit_041s_max + :goals: build flash debug + +Once the gdb console starts after executing the west debug command, you may now set breakpoints and perform other standard GDB debugging. + +References +********** + +.. target-notes:: + +.. _cy8ckit_041s_max Board Website: + https://www.infineon.com/evaluation-board/CY8CKIT-041S-MAX + +.. _ModusToolbox: + https://www.infineon.com/design-resources/development-tools/sdk/modustoolbox-software + +.. _ModusToolbox Programming Tools: + https://www.infineon.com/design-resources/development-tools/sdk/modustoolbox-software/modustoolbox-programming-tools + +.. _Infineon OpenOCD: + https://github.com/Infineon/openocd/releases/latest + +.. _KitProg3: + https://github.com/Infineon/KitProg3 diff --git a/boards/infineon/cy8ckit_041s_max/support/openocd.cfg b/boards/infineon/cy8ckit_041s_max/support/openocd.cfg new file mode 100644 index 000000000000..f7f165c28c07 --- /dev/null +++ b/boards/infineon/cy8ckit_041s_max/support/openocd.cfg @@ -0,0 +1,18 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# OpenOCD configuration for CY8CKIT-041S-MAX +# PSoC 4100S Max with KitProg3 programmer + +source [find interface/kitprog3.cfg] + +# Set transport to SWD +transport select swd + +# Set adapter speed (KitProg3 supports up to 1000 kHz for PSoC 4) +adapter speed 1000 + +# PSoC 4 family configuration +source [find target/psoc4.cfg] + +# Reset configuration +reset_config srst_only From 56014df8d9adef9eb62d2f02310539be072cb8ac Mon Sep 17 00:00:00 2001 From: Braeden Lane Date: Wed, 10 Dec 2025 14:06:37 -0800 Subject: [PATCH 2488/3659] tests: Add cy8ckit_041s_max test overlays Add test and sample overlays for CY8CKIT-041S-MAX board: - GPIO basic API test using P1.2 and P1.3 pins - Button sample using P11.5 with pull-up configuration Signed-off-by: Braeden Lane --- .../button/boards/cy8ckit_041s_max.overlay | 26 +++++++++++++++++++ .../boards/cy8ckit_041s_max.overlay | 17 ++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 samples/basic/button/boards/cy8ckit_041s_max.overlay create mode 100644 tests/drivers/gpio/gpio_basic_api/boards/cy8ckit_041s_max.overlay diff --git a/samples/basic/button/boards/cy8ckit_041s_max.overlay b/samples/basic/button/boards/cy8ckit_041s_max.overlay new file mode 100644 index 000000000000..6a5b7691bc07 --- /dev/null +++ b/samples/basic/button/boards/cy8ckit_041s_max.overlay @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + sw0 = &user_btn; + }; + + gpio_keys { + compatible = "gpio-keys"; + + user_btn: button_0 { + label = "SW_0"; + gpios = <&gpio_prt11 5 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + zephyr,code = ; + }; + }; +}; + +&gpio_prt11 { + status = "okay"; +}; diff --git a/tests/drivers/gpio/gpio_basic_api/boards/cy8ckit_041s_max.overlay b/tests/drivers/gpio/gpio_basic_api/boards/cy8ckit_041s_max.overlay new file mode 100644 index 000000000000..5abf04d5fd3a --- /dev/null +++ b/tests/drivers/gpio/gpio_basic_api/boards/cy8ckit_041s_max.overlay @@ -0,0 +1,17 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2025 Infineon Technologies AG + */ + +/ { + resources { + compatible = "test-gpio-basic-api"; + out-gpios = <&gpio_prt1 2 0>; + in-gpios = <&gpio_prt1 3 0>; + }; +}; + +&gpio_prt1 { + status = "okay"; +}; From 6b3117827293750861d7651c9ebae2080a122c76 Mon Sep 17 00:00:00 2001 From: Victor Brzeski Date: Wed, 3 Dec 2025 15:34:49 -0800 Subject: [PATCH 2489/3659] uac2: disable active terminals when class is disabled When the USB Bus is reset, the USBD stack will disable and re-enable all Classes. If this occurs while streaming audio with UAC2, the terminals remain active when re-enabled, yet the endpoints have yet to be enabled (resulting in -ENODEV logspam). This change disables all active terminals when the class is disabled. Signed-off-by: Victor Brzeski --- subsys/usb/device_next/class/usbd_uac2.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/subsys/usb/device_next/class/usbd_uac2.c b/subsys/usb/device_next/class/usbd_uac2.c index ee95e643294e..047b340ce2ce 100644 --- a/subsys/usb/device_next/class/usbd_uac2.c +++ b/subsys/usb/device_next/class/usbd_uac2.c @@ -926,6 +926,26 @@ static void *uac2_get_desc(struct usbd_class_data *const c_data, return cfg->fs_descriptors; } +static void uac2_disable(struct usbd_class_data *const c_data) +{ + const struct device *dev = usbd_class_get_private(c_data); + struct uac2_ctx *ctx = dev->data; + const struct uac2_cfg *cfg = dev->config; + const bool microframes = + USBD_SUPPORTS_HIGH_SPEED && usbd_bus_speed(c_data->uds_ctx) == USBD_SPEED_HS; + atomic_val_t as_active; + + as_active = atomic_clear(&ctx->as_active); + + while (as_active) { + unsigned int as_idx = find_lsb_set(as_active) - 1; + + ctx->ops->terminal_update_cb(dev, cfg->as_terminals[as_idx], 0, microframes, + ctx->user_data); + as_active &= ~BIT(as_idx); + } +} + static int uac2_init(struct usbd_class_data *const c_data) { const struct device *dev = usbd_class_get_private(c_data); @@ -946,6 +966,7 @@ struct usbd_class_api uac2_api = { .request = uac2_request, .sof = uac2_sof, .get_desc = uac2_get_desc, + .disable = uac2_disable, .init = uac2_init, }; From 5ca1fe739944eff0e7436fa84fd78e40ae07bae8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 22 Jan 2026 17:04:24 +0000 Subject: [PATCH 2490/3659] ci: github: bump the actions-deps group across 1 directory with 15 updates Bumps the actions-deps group with 15 updates in the / directory: | Package | From | To | | --- | --- | --- | | [actions/checkout](https://github.com/actions/checkout) | `5.0.0` | `6.0.2` | | [dawidd6/action-download-artifact](https://github.com/dawidd6/action-download-artifact) | `11` | `12` | | [EnricoMi/publish-unit-test-result-action](https://github.com/enricomi/publish-unit-test-result-action) | `2.21.0` | `2.22.0` | | [tj-actions/changed-files](https://github.com/tj-actions/changed-files) | `47.0.0` | `47.0.1` | | [actions/upload-artifact](https://github.com/actions/upload-artifact) | `5.0.0` | `6.0.0` | | [aws-actions/configure-aws-credentials](https://github.com/aws-actions/configure-aws-credentials) | `5.1.0` | `5.1.1` | | [actions/download-artifact](https://github.com/actions/download-artifact) | `6.0.0` | `7.0.0` | | [codecov/codecov-action](https://github.com/codecov/codecov-action) | `5.5.1` | `5.5.2` | | [github/codeql-action](https://github.com/github/codeql-action) | `4.31.2` | `4.31.10` | | [actions/setup-node](https://github.com/actions/setup-node) | `6.0.0` | `6.2.0` | | [zephyrproject-rtos/action-zephyr-setup](https://github.com/zephyrproject-rtos/action-zephyr-setup) | `1.0.11` | `1.0.12` | | [carpentries/actions](https://github.com/carpentries/actions) | `0.15.0` | `0.17.0` | | [zgosalvez/github-actions-ensure-sha-pinned-actions](https://github.com/zgosalvez/github-actions-ensure-sha-pinned-actions) | `4.0.0` | `4.0.1` | | [actions/stale](https://github.com/actions/stale) | `10.1.0` | `10.1.1` | | [codecov/test-results-action](https://github.com/codecov/test-results-action) | `1.1.1` | `1.2.1` | Updates `actions/checkout` from 5.0.0 to 6.0.2 - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/08c6903cd8c0fde910a37f88322edcfb5dd907a8...de0fac2e4500dabe0009e67214ff5f5447ce83dd) Updates `dawidd6/action-download-artifact` from 11 to 12 - [Release notes](https://github.com/dawidd6/action-download-artifact/releases) - [Commits](https://github.com/dawidd6/action-download-artifact/compare/ac66b43f0e6a346234dd65d4d0c8fbb31cb316e5...0bd50d53a6d7fb5cb921e607957e9cc12b4ce392) Updates `EnricoMi/publish-unit-test-result-action` from 2.21.0 to 2.22.0 - [Release notes](https://github.com/enricomi/publish-unit-test-result-action/releases) - [Commits](https://github.com/enricomi/publish-unit-test-result-action/compare/34d7c956a59aed1bfebf31df77b8de55db9bbaaf...27d65e188ec43221b20d26de30f4892fad91df2f) Updates `tj-actions/changed-files` from 47.0.0 to 47.0.1 - [Release notes](https://github.com/tj-actions/changed-files/releases) - [Changelog](https://github.com/tj-actions/changed-files/blob/main/HISTORY.md) - [Commits](https://github.com/tj-actions/changed-files/compare/24d32ffd492484c1d75e0c0b894501ddb9d30d62...e0021407031f5be11a464abee9a0776171c79891) Updates `actions/upload-artifact` from 5.0.0 to 6.0.0 - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/330a01c490aca151604b8cf639adc76d48f6c5d4...b7c566a772e6b6bfb58ed0dc250532a479d7789f) Updates `aws-actions/configure-aws-credentials` from 5.1.0 to 5.1.1 - [Release notes](https://github.com/aws-actions/configure-aws-credentials/releases) - [Changelog](https://github.com/aws-actions/configure-aws-credentials/blob/main/CHANGELOG.md) - [Commits](https://github.com/aws-actions/configure-aws-credentials/compare/00943011d9042930efac3dcd3a170e4273319bc8...61815dcd50bd041e203e49132bacad1fd04d2708) Updates `actions/download-artifact` from 6.0.0 to 7.0.0 - [Release notes](https://github.com/actions/download-artifact/releases) - [Commits](https://github.com/actions/download-artifact/compare/018cc2cf5baa6db3ef3c5f8a56943fffe632ef53...37930b1c2abaa49bbe596cd826c3c89aef350131) Updates `codecov/codecov-action` from 5.5.1 to 5.5.2 - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/5a1091511ad55cbe89839c7260b706298ca349f7...671740ac38dd9b0130fbe1cec585b89eea48d3de) Updates `github/codeql-action` from 4.31.2 to 4.31.10 - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/0499de31b99561a6d14a36a5f662c2a54f91beee...cdefb33c0f6224e58673d9004f47f7cb3e328b89) Updates `actions/setup-node` from 6.0.0 to 6.2.0 - [Release notes](https://github.com/actions/setup-node/releases) - [Commits](https://github.com/actions/setup-node/compare/2028fbc5c25fe9cf00d9f06a71cc4710d4507903...6044e13b5dc448c55e2357c09f80417699197238) Updates `zephyrproject-rtos/action-zephyr-setup` from 1.0.11 to 1.0.12 - [Commits](https://github.com/zephyrproject-rtos/action-zephyr-setup/compare/cefbf9086ce2da7d70e7ad9589af8aa1e4bda265...360ff9b36e58499d9eb28015cdcde7ca03a5b04d) Updates `carpentries/actions` from 0.15.0 to 0.17.0 - [Release notes](https://github.com/carpentries/actions/releases) - [Commits](https://github.com/carpentries/actions/compare/2e20fd5ee53b691e27455ce7ca3b16ea885140e8...083bb9952b1414bd2b9e10ecec1717c938aba4c5) Updates `zgosalvez/github-actions-ensure-sha-pinned-actions` from 4.0.0 to 4.0.1 - [Release notes](https://github.com/zgosalvez/github-actions-ensure-sha-pinned-actions/releases) - [Commits](https://github.com/zgosalvez/github-actions-ensure-sha-pinned-actions/compare/9e9574ef04ea69da568d6249bd69539ccc704e74...6124774845927d14c601359ab8138699fa5b70c3) Updates `actions/stale` from 10.1.0 to 10.1.1 - [Release notes](https://github.com/actions/stale/releases) - [Changelog](https://github.com/actions/stale/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/stale/compare/5f858e3efba33a5ca4407a664cc011ad407f2008...997185467fa4f803885201cee163a9f38240193d) Updates `codecov/test-results-action` from 1.1.1 to 1.2.1 - [Release notes](https://github.com/codecov/test-results-action/releases) - [Commits](https://github.com/codecov/test-results-action/compare/47f89e9acb64b76debcd5ea40642d25a4adced9f...0fa95f0e1eeaafde2c782583b36b28ad0d8c77d3) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: 6.0.2 dependency-type: direct:production update-type: version-update:semver-major dependency-group: actions-deps - dependency-name: dawidd6/action-download-artifact dependency-version: '12' dependency-type: direct:production update-type: version-update:semver-major dependency-group: actions-deps - dependency-name: EnricoMi/publish-unit-test-result-action dependency-version: 2.22.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: actions-deps - dependency-name: tj-actions/changed-files dependency-version: 47.0.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: actions-deps - dependency-name: actions/upload-artifact dependency-version: 6.0.0 dependency-type: direct:production update-type: version-update:semver-major dependency-group: actions-deps - dependency-name: aws-actions/configure-aws-credentials dependency-version: 5.1.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: actions-deps - dependency-name: actions/download-artifact dependency-version: 7.0.0 dependency-type: direct:production update-type: version-update:semver-major dependency-group: actions-deps - dependency-name: codecov/codecov-action dependency-version: 5.5.2 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: actions-deps - dependency-name: github/codeql-action dependency-version: 4.31.10 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: actions-deps - dependency-name: actions/setup-node dependency-version: 6.2.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: actions-deps - dependency-name: zephyrproject-rtos/action-zephyr-setup dependency-version: 1.0.12 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: actions-deps - dependency-name: carpentries/actions dependency-version: 0.17.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: actions-deps - dependency-name: zgosalvez/github-actions-ensure-sha-pinned-actions dependency-version: 4.0.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: actions-deps - dependency-name: actions/stale dependency-version: 10.1.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: actions-deps - dependency-name: codecov/test-results-action dependency-version: 1.2.1 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: actions-deps ... Signed-off-by: dependabot[bot] --- .github/workflows/assigner.yml | 2 +- .github/workflows/backport_issue_check.yml | 2 +- .github/workflows/bsim-tests-publish.yaml | 4 ++-- .github/workflows/bsim-tests.yaml | 16 +++++++------- .github/workflows/bug_snapshot.yaml | 4 ++-- .github/workflows/clang.yaml | 12 +++++----- .github/workflows/codecov.yaml | 16 +++++++------- .github/workflows/codeql.yml | 6 ++--- .github/workflows/coding_guidelines.yml | 2 +- .github/workflows/compliance.yml | 8 +++---- .github/workflows/daily_test_version.yml | 4 ++-- .github/workflows/devicetree_checks.yml | 2 +- .github/workflows/doc-build.yml | 18 +++++++-------- .github/workflows/doc-publish-pr.yml | 6 ++--- .github/workflows/doc-publish.yml | 4 ++-- .github/workflows/errno.yml | 4 ++-- .github/workflows/footprint-tracking.yml | 4 ++-- .../greet_first_time_contributor.yml | 2 +- .../workflows/hello_world_multiplatform.yaml | 6 ++--- .github/workflows/issue_count.yml | 4 ++-- .github/workflows/license_check.yml | 4 ++-- .github/workflows/manifest.yml | 2 +- .github/workflows/pinned-gh-actions.yml | 4 ++-- .github/workflows/pr_metadata_check.yml | 2 +- .github/workflows/pylib_tests.yml | 2 +- .github/workflows/release.yml | 4 ++-- .github/workflows/scorecards.yml | 6 ++--- .github/workflows/scripts_tests.yml | 2 +- .github/workflows/stale_issue.yml | 2 +- .github/workflows/stats_merged_prs.yml | 2 +- .github/workflows/twister-publish.yaml | 4 ++-- .github/workflows/twister.yaml | 22 +++++++++---------- .github/workflows/twister_tests.yml | 2 +- .github/workflows/twister_tests_blackbox.yml | 4 ++-- .github/workflows/west_cmds.yml | 2 +- 35 files changed, 95 insertions(+), 95 deletions(-) diff --git a/.github/workflows/assigner.yml b/.github/workflows/assigner.yml index 5ee44a84ce9c..a4670d05b800 100644 --- a/.github/workflows/assigner.yml +++ b/.github/workflows/assigner.yml @@ -28,7 +28,7 @@ jobs: steps: - name: Check out source code - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 persist-credentials: false diff --git a/.github/workflows/backport_issue_check.yml b/.github/workflows/backport_issue_check.yml index 7811f30d050a..44320bbd0e95 100644 --- a/.github/workflows/backport_issue_check.yml +++ b/.github/workflows/backport_issue_check.yml @@ -26,7 +26,7 @@ jobs: steps: - name: Check out source code - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Set up Python uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0 diff --git a/.github/workflows/bsim-tests-publish.yaml b/.github/workflows/bsim-tests-publish.yaml index 17d424f18493..28d69b7bcc44 100644 --- a/.github/workflows/bsim-tests-publish.yaml +++ b/.github/workflows/bsim-tests-publish.yaml @@ -19,12 +19,12 @@ jobs: steps: - name: Download artifacts - uses: dawidd6/action-download-artifact@ac66b43f0e6a346234dd65d4d0c8fbb31cb316e5 # v11 + uses: dawidd6/action-download-artifact@0bd50d53a6d7fb5cb921e607957e9cc12b4ce392 # v12 with: run_id: ${{ github.event.workflow_run.id }} - name: Publish BabbleSim Test Results - uses: EnricoMi/publish-unit-test-result-action@34d7c956a59aed1bfebf31df77b8de55db9bbaaf # v2.21.0 + uses: EnricoMi/publish-unit-test-result-action@27d65e188ec43221b20d26de30f4892fad91df2f # v2.22.0 with: check_name: BabbleSim Test Results comment_mode: off diff --git a/.github/workflows/bsim-tests.yaml b/.github/workflows/bsim-tests.yaml index 37e2ca050164..7c8082fcd7c1 100644 --- a/.github/workflows/bsim-tests.yaml +++ b/.github/workflows/bsim-tests.yaml @@ -74,7 +74,7 @@ jobs: git remote set-url origin ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY} - name: Checkout - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 @@ -102,7 +102,7 @@ jobs: pip install -r scripts/requirements-actions.txt --require-hashes - name: Check common triggering files - uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62 # v47.0.0 + uses: tj-actions/changed-files@e0021407031f5be11a464abee9a0776171c79891 # v47.0.1 id: check-common-files with: files: | @@ -121,7 +121,7 @@ jobs: modules/hal_nordic/** - name: Check if Bluethooth files changed - uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62 # v47.0.0 + uses: tj-actions/changed-files@e0021407031f5be11a464abee9a0776171c79891 # v47.0.1 id: check-bluetooth-files with: files: | @@ -131,7 +131,7 @@ jobs: tests/bsim/bluetooth/ - name: Check if Networking files changed - uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62 # v47.0.0 + uses: tj-actions/changed-files@e0021407031f5be11a464abee9a0776171c79891 # v47.0.1 id: check-networking-files with: files: | @@ -144,7 +144,7 @@ jobs: include/zephyr/net/ieee802154* - name: Check if UART files changed - uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62 # v47.0.0 + uses: tj-actions/changed-files@e0021407031f5be11a464abee9a0776171c79891 # v47.0.1 id: check-uart-files with: files: | @@ -189,7 +189,7 @@ jobs: - name: Upload Unit Test Results in HTML if: always() - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 with: name: HTML Unit Test Results if-no-files-found: ignore @@ -197,7 +197,7 @@ jobs: junit.html - name: Publish Unit Test Results - uses: EnricoMi/publish-unit-test-result-action@34d7c956a59aed1bfebf31df77b8de55db9bbaaf # v2.21.0 + uses: EnricoMi/publish-unit-test-result-action@27d65e188ec43221b20d26de30f4892fad91df2f # v2.22.0 with: check_name: Bsim Test Results files: "junit.xml" @@ -205,7 +205,7 @@ jobs: - name: Upload Event Details if: always() - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 with: name: event path: | diff --git a/.github/workflows/bug_snapshot.yaml b/.github/workflows/bug_snapshot.yaml index 8ab3035bf036..d785ceaea9db 100644 --- a/.github/workflows/bug_snapshot.yaml +++ b/.github/workflows/bug_snapshot.yaml @@ -23,7 +23,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Set up Python uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0 @@ -51,7 +51,7 @@ jobs: echo "BUGS_PICKLE_PATH=${BUGS_PICKLE_PATH}" >> ${GITHUB_ENV} - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@00943011d9042930efac3dcd3a170e4273319bc8 # v5.1.0 + uses: aws-actions/configure-aws-credentials@61815dcd50bd041e203e49132bacad1fd04d2708 # v5.1.1 with: aws-access-key-id: ${{ vars.AWS_BUILDS_ZEPHYR_BUG_SNAPSHOT_ACCESS_KEY_ID }} aws-secret-access-key: ${{ secrets.AWS_BUILDS_ZEPHYR_BUG_SNAPSHOT_SECRET_ACCESS_KEY }} diff --git a/.github/workflows/clang.yaml b/.github/workflows/clang.yaml index 91e9c6e27e91..b7085375d06c 100644 --- a/.github/workflows/clang.yaml +++ b/.github/workflows/clang.yaml @@ -53,7 +53,7 @@ jobs: git remote set-url origin ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY} - name: Checkout - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 persist-credentials: false @@ -123,7 +123,7 @@ jobs: - name: Upload Unit Test Results if: always() - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 with: name: Unit Test Results (Subset ${{ matrix.subset }}) path: | @@ -140,13 +140,13 @@ jobs: if: (success() || failure()) steps: - name: Checkout - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 persist-credentials: false - name: Download Artifacts - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0 + uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 with: path: artifacts @@ -168,7 +168,7 @@ jobs: - name: Upload Unit Test Results in HTML if: always() - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 with: name: HTML Unit Test Results if-no-files-found: ignore @@ -176,7 +176,7 @@ jobs: junit-clang.html - name: Publish Unit Test Results - uses: EnricoMi/publish-unit-test-result-action@34d7c956a59aed1bfebf31df77b8de55db9bbaaf # v2.21.0 + uses: EnricoMi/publish-unit-test-result-action@27d65e188ec43221b20d26de30f4892fad91df2f # v2.22.0 if: always() with: check_name: Unit Test Results diff --git a/.github/workflows/codecov.yaml b/.github/workflows/codecov.yaml index af14276612e0..d5647048794e 100644 --- a/.github/workflows/codecov.yaml +++ b/.github/workflows/codecov.yaml @@ -67,7 +67,7 @@ jobs: git remote set-url origin ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY} - name: checkout - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 @@ -126,7 +126,7 @@ jobs: - name: Upload Doxygen Coverage Results if: matrix.platform == 'unit_testing' - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 with: name: doxygen-coverage-results path: | @@ -145,7 +145,7 @@ jobs: - name: Upload Coverage Results if: always() - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 with: name: Coverage Data (Subset ${{ matrix.normalized }}) path: | @@ -161,7 +161,7 @@ jobs: steps: - name: checkout - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 @@ -177,7 +177,7 @@ jobs: pip install -r scripts/requirements-actions.txt --require-hashes - name: Download Artifacts - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0 + uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 with: path: coverage/reports @@ -242,7 +242,7 @@ jobs: - name: Upload Merged Coverage Results and Report if: always() - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 with: name: Coverage Data and report path: | @@ -253,7 +253,7 @@ jobs: - name: Upload test coverage to Codecov if: always() - uses: codecov/codecov-action@5a1091511ad55cbe89839c7260b706298ca349f7 # v5.5.1 + uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5.5.2 with: env_vars: OS,PYTHON fail_ci_if_error: false @@ -264,7 +264,7 @@ jobs: - name: Upload Doxygen coverage to Codecov if: always() - uses: codecov/codecov-action@5a1091511ad55cbe89839c7260b706298ca349f7 # v5.5.1 + uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5.5.2 with: env_vars: OS,PYTHON fail_ci_if_error: false diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index dd3aa9b9f7d2..cefe4222440a 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -36,10 +36,10 @@ jobs: config: ./.github/codeql/codeql-js-config.yml steps: - name: Checkout - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Initialize CodeQL - uses: github/codeql-action/init@0499de31b99561a6d14a36a5f662c2a54f91beee # v4.31.2 + uses: github/codeql-action/init@cdefb33c0f6224e58673d9004f47f7cb3e328b89 # v4.31.10 with: languages: ${{ matrix.language }} build-mode: ${{ matrix.build-mode }} @@ -53,6 +53,6 @@ jobs: exit 0 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@0499de31b99561a6d14a36a5f662c2a54f91beee # v4.31.2 + uses: github/codeql-action/analyze@cdefb33c0f6224e58673d9004f47f7cb3e328b89 # v4.31.10 with: category: "/language:${{matrix.language}}" diff --git a/.github/workflows/coding_guidelines.yml b/.github/workflows/coding_guidelines.yml index 258e80d1d5e4..471659bd4c43 100644 --- a/.github/workflows/coding_guidelines.yml +++ b/.github/workflows/coding_guidelines.yml @@ -11,7 +11,7 @@ jobs: name: Run coding guidelines checks on patch series (PR) steps: - name: Checkout the code - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: ref: ${{ github.event.pull_request.head.sha }} fetch-depth: 0 diff --git a/.github/workflows/compliance.yml b/.github/workflows/compliance.yml index 26e41485ef67..c1922b5b37dd 100644 --- a/.github/workflows/compliance.yml +++ b/.github/workflows/compliance.yml @@ -21,7 +21,7 @@ jobs: echo "$HOME/.local/bin" >> $GITHUB_PATH - name: Checkout the code - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: ref: ${{ github.event.pull_request.head.sha }} fetch-depth: 0 @@ -61,7 +61,7 @@ jobs: west update -o=--depth=1 -n 2>&1 1> west.update.log || west update -o=--depth=1 -n 2>&1 1> west.update2.log - name: Setup Node.js - uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0 + uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 with: node-version: "lts/*" cache: npm @@ -91,14 +91,14 @@ jobs: ./scripts/ci/check_compliance.py --annotate $excludes -c origin/${BASE_REF}.. - name: upload-results - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 continue-on-error: true with: name: compliance.xml path: compliance.xml - name: Upload dts linter patch - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 continue-on-error: true if: hashFiles('dts_linter.patch') != '' with: diff --git a/.github/workflows/daily_test_version.yml b/.github/workflows/daily_test_version.yml index d604c7fe9d3c..8af9c450b19f 100644 --- a/.github/workflows/daily_test_version.yml +++ b/.github/workflows/daily_test_version.yml @@ -20,14 +20,14 @@ jobs: steps: - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@00943011d9042930efac3dcd3a170e4273319bc8 # v5.1.0 + uses: aws-actions/configure-aws-credentials@61815dcd50bd041e203e49132bacad1fd04d2708 # v5.1.1 with: aws-access-key-id: ${{ vars.AWS_TESTING_ACCESS_KEY_ID }} aws-secret-access-key: ${{ secrets.AWS_TESTING_SECRET_ACCESS_KEY }} aws-region: us-east-1 - name: checkout - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 diff --git a/.github/workflows/devicetree_checks.yml b/.github/workflows/devicetree_checks.yml index c0efa60951f0..22fe4cb33709 100644 --- a/.github/workflows/devicetree_checks.yml +++ b/.github/workflows/devicetree_checks.yml @@ -33,7 +33,7 @@ jobs: os: [ubuntu-22.04, macos-14, windows-2022] steps: - name: checkout - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0 diff --git a/.github/workflows/doc-build.yml b/.github/workflows/doc-build.yml index 054fee42472e..a9bd5677b604 100644 --- a/.github/workflows/doc-build.yml +++ b/.github/workflows/doc-build.yml @@ -27,12 +27,12 @@ jobs: file_check: ${{ steps.check-doc-files.outputs.any_modified }} steps: - name: checkout - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: ref: ${{ github.event.pull_request.head.sha }} fetch-depth: 0 - name: Check if Documentation related files changed - uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62 # v47.0.0 + uses: tj-actions/changed-files@e0021407031f5be11a464abee9a0776171c79891 # v47.0.1 id: check-doc-files with: files: | @@ -92,7 +92,7 @@ jobs: git remote set-url origin ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY} - name: Checkout - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: ref: ${{ github.event.pull_request.head.sha }} fetch-depth: 0 @@ -156,13 +156,13 @@ jobs: tar --use-compress-program="xz -T0" -cf api-coverage.tar.xz coverage-report - name: Upload HTML output - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 with: name: html-output path: html-output.tar.xz - name: Upload Doxygen coverage artifacts - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 with: name: api-coverage path: api-coverage.tar.xz @@ -183,7 +183,7 @@ jobs: echo "API Coverage Report will be available shortly at: ${API_COVERAGE_URL}" >> $GITHUB_STEP_SUMMARY - name: Upload PR number - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 if: github.event_name == 'pull_request' with: name: pr_num @@ -202,7 +202,7 @@ jobs: steps: - name: checkout - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: path: zephyr @@ -230,7 +230,7 @@ jobs: echo "/opt/doxygen-${DOXYGEN_VERSION}/bin" >> $GITHUB_PATH - name: Setup Zephyr project - uses: zephyrproject-rtos/action-zephyr-setup@cefbf9086ce2da7d70e7ad9589af8aa1e4bda265 # v1.0.11 + uses: zephyrproject-rtos/action-zephyr-setup@360ff9b36e58499d9eb28015cdcde7ca03a5b04d # v1.0.12 with: app-path: zephyr toolchains: 'arm-zephyr-eabi' @@ -259,7 +259,7 @@ jobs: - name: upload-build if: always() - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 with: name: pdf-output if-no-files-found: ignore diff --git a/.github/workflows/doc-publish-pr.yml b/.github/workflows/doc-publish-pr.yml index 054046815b2a..28ee3e6a81f5 100644 --- a/.github/workflows/doc-publish-pr.yml +++ b/.github/workflows/doc-publish-pr.yml @@ -25,7 +25,7 @@ jobs: steps: - name: Download artifacts id: download-artifacts - uses: dawidd6/action-download-artifact@ac66b43f0e6a346234dd65d4d0c8fbb31cb316e5 # v11 + uses: dawidd6/action-download-artifact@0bd50d53a6d7fb5cb921e607957e9cc12b4ce392 # v12 with: workflow: doc-build.yml run_id: ${{ github.event.workflow_run.id }} @@ -43,7 +43,7 @@ jobs: - name: Check PR number if: steps.download-artifacts.outputs.found_artifact == 'true' id: check-pr - uses: carpentries/actions/check-valid-pr@2e20fd5ee53b691e27455ce7ca3b16ea885140e8 # v0.15.0 + uses: carpentries/actions/check-valid-pr@083bb9952b1414bd2b9e10ecec1717c938aba4c5 # v0.17.0 with: pr: ${{ env.PR_NUM }} sha: ${{ github.event.workflow_run.head_sha }} @@ -66,7 +66,7 @@ jobs: - name: Configure AWS Credentials if: steps.download-artifacts.outputs.found_artifact == 'true' - uses: aws-actions/configure-aws-credentials@00943011d9042930efac3dcd3a170e4273319bc8 # v5.1.0 + uses: aws-actions/configure-aws-credentials@61815dcd50bd041e203e49132bacad1fd04d2708 # v5.1.1 with: aws-access-key-id: ${{ vars.AWS_BUILDS_ZEPHYR_PR_ACCESS_KEY_ID }} aws-secret-access-key: ${{ secrets.AWS_BUILDS_ZEPHYR_PR_SECRET_ACCESS_KEY }} diff --git a/.github/workflows/doc-publish.yml b/.github/workflows/doc-publish.yml index 14c620846e12..2df0b240675d 100644 --- a/.github/workflows/doc-publish.yml +++ b/.github/workflows/doc-publish.yml @@ -27,7 +27,7 @@ jobs: steps: - name: Download artifacts - uses: dawidd6/action-download-artifact@ac66b43f0e6a346234dd65d4d0c8fbb31cb316e5 # v11 + uses: dawidd6/action-download-artifact@0bd50d53a6d7fb5cb921e607957e9cc12b4ce392 # v12 with: workflow: doc-build.yml run_id: ${{ github.event.workflow_run.id }} @@ -40,7 +40,7 @@ jobs: fi - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@00943011d9042930efac3dcd3a170e4273319bc8 # v5.1.0 + uses: aws-actions/configure-aws-credentials@61815dcd50bd041e203e49132bacad1fd04d2708 # v5.1.1 with: aws-access-key-id: ${{ vars.AWS_DOCS_ACCESS_KEY_ID }} aws-secret-access-key: ${{ secrets.AWS_DOCS_SECRET_ACCESS_KEY }} diff --git a/.github/workflows/errno.yml b/.github/workflows/errno.yml index 906435200c02..1e71580341d3 100644 --- a/.github/workflows/errno.yml +++ b/.github/workflows/errno.yml @@ -15,12 +15,12 @@ jobs: runs-on: ubuntu-24.04 steps: - name: checkout - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: path: zephyr - name: Setup Zephyr project - uses: zephyrproject-rtos/action-zephyr-setup@cefbf9086ce2da7d70e7ad9589af8aa1e4bda265 # v1.0.11 + uses: zephyrproject-rtos/action-zephyr-setup@360ff9b36e58499d9eb28015cdcde7ca03a5b04d # v1.0.12 with: app-path: zephyr toolchains: 'arm-zephyr-eabi' diff --git a/.github/workflows/footprint-tracking.yml b/.github/workflows/footprint-tracking.yml index 010ed9ec1b30..6f68ef19a016 100644 --- a/.github/workflows/footprint-tracking.yml +++ b/.github/workflows/footprint-tracking.yml @@ -62,7 +62,7 @@ jobs: sudo apt-get install -y python3-venv - name: checkout - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: ref: ${{ github.event.pull_request.head.sha }} fetch-depth: 0 @@ -89,7 +89,7 @@ jobs: west update 2>&1 1> west.update.log || west update 2>&1 1> west.update2.log - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@00943011d9042930efac3dcd3a170e4273319bc8 # v5.1.0 + uses: aws-actions/configure-aws-credentials@61815dcd50bd041e203e49132bacad1fd04d2708 # v5.1.1 with: aws-access-key-id: ${{ vars.AWS_TESTING_ACCESS_KEY_ID }} aws-secret-access-key: ${{ secrets.AWS_TESTING_SECRET_ACCESS_KEY }} diff --git a/.github/workflows/greet_first_time_contributor.yml b/.github/workflows/greet_first_time_contributor.yml index 6a499275461e..be0616d4194d 100644 --- a/.github/workflows/greet_first_time_contributor.yml +++ b/.github/workflows/greet_first_time_contributor.yml @@ -18,7 +18,7 @@ jobs: issues: write # to comment on issues steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - uses: zephyrproject-rtos/action-first-interaction@58853996b1ac504b8e0f6964301f369d2bb22e5c # v1.1.1+zephyr.6 with: repo-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/hello_world_multiplatform.yaml b/.github/workflows/hello_world_multiplatform.yaml index 81f1ed60bd0d..d20f057742a8 100644 --- a/.github/workflows/hello_world_multiplatform.yaml +++ b/.github/workflows/hello_world_multiplatform.yaml @@ -32,7 +32,7 @@ jobs: runs-on: ${{ matrix.os }} steps: - name: Checkout - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: path: zephyr fetch-depth: 0 @@ -59,7 +59,7 @@ jobs: python-version: 3.12 - name: Setup Zephyr project - uses: zephyrproject-rtos/action-zephyr-setup@cefbf9086ce2da7d70e7ad9589af8aa1e4bda265 # v1.0.11 + uses: zephyrproject-rtos/action-zephyr-setup@360ff9b36e58499d9eb28015cdcde7ca03a5b04d # v1.0.12 with: app-path: zephyr toolchains: arm-zephyr-eabi:riscv64-zephyr-elf @@ -88,7 +88,7 @@ jobs: - name: Upload artifacts if: failure() - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 with: if-no-files-found: ignore path: diff --git a/.github/workflows/issue_count.yml b/.github/workflows/issue_count.yml index a7bfe9e2507c..830e41d34c1e 100644 --- a/.github/workflows/issue_count.yml +++ b/.github/workflows/issue_count.yml @@ -38,14 +38,14 @@ jobs: token: ${{ secrets.GITHUB_TOKEN }} - name: upload-stats - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 continue-on-error: true with: name: ${{ env.OUTPUT_FILE_NAME }} path: ${{ env.OUTPUT_FILE_NAME }} - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@00943011d9042930efac3dcd3a170e4273319bc8 # v5.1.0 + uses: aws-actions/configure-aws-credentials@61815dcd50bd041e203e49132bacad1fd04d2708 # v5.1.1 with: aws-access-key-id: ${{ vars.AWS_TESTING_ACCESS_KEY_ID }} aws-secret-access-key: ${{ secrets.AWS_TESTING_SECRET_ACCESS_KEY }} diff --git a/.github/workflows/license_check.yml b/.github/workflows/license_check.yml index b7547d95e65c..67751a067a9a 100644 --- a/.github/workflows/license_check.yml +++ b/.github/workflows/license_check.yml @@ -11,7 +11,7 @@ jobs: name: Scan code for licenses steps: - name: Checkout the code - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 - name: Scan the code @@ -20,7 +20,7 @@ jobs: with: directory-to-scan: 'scan/' - name: Artifact Upload - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 with: name: scancode path: ./artifacts diff --git a/.github/workflows/manifest.yml b/.github/workflows/manifest.yml index 3cbf007f187e..5412cf7f0994 100644 --- a/.github/workflows/manifest.yml +++ b/.github/workflows/manifest.yml @@ -13,7 +13,7 @@ jobs: name: Manifest steps: - name: Checkout the code - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: path: zephyrproject/zephyr fetch-depth: 0 diff --git a/.github/workflows/pinned-gh-actions.yml b/.github/workflows/pinned-gh-actions.yml index f1d1bad4a43e..8cdc84780c69 100644 --- a/.github/workflows/pinned-gh-actions.yml +++ b/.github/workflows/pinned-gh-actions.yml @@ -14,6 +14,6 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout code - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Ensure SHA pinned actions - uses: zgosalvez/github-actions-ensure-sha-pinned-actions@9e9574ef04ea69da568d6249bd69539ccc704e74 # v4.0.0 + uses: zgosalvez/github-actions-ensure-sha-pinned-actions@6124774845927d14c601359ab8138699fa5b70c3 # v4.0.1 diff --git a/.github/workflows/pr_metadata_check.yml b/.github/workflows/pr_metadata_check.yml index 6d48d29129b1..52450b9510e9 100644 --- a/.github/workflows/pr_metadata_check.yml +++ b/.github/workflows/pr_metadata_check.yml @@ -23,7 +23,7 @@ jobs: timeout-minutes: 30 steps: - name: Checkout - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Set up Python uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0 diff --git a/.github/workflows/pylib_tests.yml b/.github/workflows/pylib_tests.yml index dfd6d5d44eb5..1a1e0428d443 100644 --- a/.github/workflows/pylib_tests.yml +++ b/.github/workflows/pylib_tests.yml @@ -32,7 +32,7 @@ jobs: os: [ubuntu-24.04] steps: - name: checkout - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index dcaca963a016..a832d1e7b931 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -15,7 +15,7 @@ jobs: permissions: contents: write # to create GitHub release entry steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 @@ -31,7 +31,7 @@ jobs: args: spdx -o zephyr-${{ steps.get_version.outputs.VERSION }}.spdx - name: upload-results - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 continue-on-error: true with: name: zephyr-${{ steps.get_version.outputs.VERSION }}.spdx diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml index 8c35bee033e5..c9d3abc1b409 100644 --- a/.github/workflows/scorecards.yml +++ b/.github/workflows/scorecards.yml @@ -29,7 +29,7 @@ jobs: steps: - name: "Checkout code" - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false @@ -47,7 +47,7 @@ jobs: # uploads of run results in SARIF format to the repository Actions tab. # https://docs.github.com/en/actions/advanced-guides/storing-workflow-data-as-artifacts - name: "Upload artifact" - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 with: name: SARIF file path: results.sarif @@ -56,6 +56,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard (optional). # Commenting out will disable upload of results to your repo's Code Scanning dashboard - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@0499de31b99561a6d14a36a5f662c2a54f91beee # v4.31.2 + uses: github/codeql-action/upload-sarif@cdefb33c0f6224e58673d9004f47f7cb3e328b89 # v4.31.10 with: sarif_file: results.sarif diff --git a/.github/workflows/scripts_tests.yml b/.github/workflows/scripts_tests.yml index f3acc3da4fcc..7073bfaae01d 100644 --- a/.github/workflows/scripts_tests.yml +++ b/.github/workflows/scripts_tests.yml @@ -32,7 +32,7 @@ jobs: os: [ubuntu-24.04] steps: - name: checkout - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: ref: ${{ github.event.pull_request.head.sha }} fetch-depth: 0 diff --git a/.github/workflows/stale_issue.yml b/.github/workflows/stale_issue.yml index 96d38de631f0..fd3474c910ed 100644 --- a/.github/workflows/stale_issue.yml +++ b/.github/workflows/stale_issue.yml @@ -16,7 +16,7 @@ jobs: issues: write # to comment on stale issues steps: - - uses: actions/stale@5f858e3efba33a5ca4407a664cc011ad407f2008 # v10.1.0 + - uses: actions/stale@997185467fa4f803885201cee163a9f38240193d # v10.1.1 with: stale-pr-message: 'This pull request has been marked as stale because it has been open (more than) 60 days with no activity. Remove the stale label or add a comment saying that you diff --git a/.github/workflows/stats_merged_prs.yml b/.github/workflows/stats_merged_prs.yml index e18fc30f5c7d..1bf58e16c63a 100644 --- a/.github/workflows/stats_merged_prs.yml +++ b/.github/workflows/stats_merged_prs.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-24.04 steps: - name: checkout - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Set up Python uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0 diff --git a/.github/workflows/twister-publish.yaml b/.github/workflows/twister-publish.yaml index a6ff339df57e..c9deaad450b4 100644 --- a/.github/workflows/twister-publish.yaml +++ b/.github/workflows/twister-publish.yaml @@ -23,7 +23,7 @@ jobs: steps: # Needed for elasticearch and upload script - name: Checkout - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 persist-credentials: false @@ -39,7 +39,7 @@ jobs: - name: Download Artifacts id: download-artifacts - uses: dawidd6/action-download-artifact@ac66b43f0e6a346234dd65d4d0c8fbb31cb316e5 # v11 + uses: dawidd6/action-download-artifact@0bd50d53a6d7fb5cb921e607957e9cc12b4ce392 # v12 with: path: artifacts workflow: twister.yml diff --git a/.github/workflows/twister.yaml b/.github/workflows/twister.yaml index 480003ffe56d..ba40dbb83596 100644 --- a/.github/workflows/twister.yaml +++ b/.github/workflows/twister.yaml @@ -42,7 +42,7 @@ jobs: steps: - name: Checkout if: github.event_name == 'pull_request' - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: ref: ${{ github.event.pull_request.head.sha }} fetch-depth: 0 @@ -65,7 +65,7 @@ jobs: - name: Setup Zephyr project if: github.event_name == 'pull_request' - uses: zephyrproject-rtos/action-zephyr-setup@cefbf9086ce2da7d70e7ad9589af8aa1e4bda265 # v1.0.11 + uses: zephyrproject-rtos/action-zephyr-setup@360ff9b36e58499d9eb28015cdcde7ca03a5b04d # v1.0.12 with: app-path: zephyr enable-ccache: false @@ -171,7 +171,7 @@ jobs: git remote set-url origin ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY} - name: Checkout - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: ref: ${{ github.event.pull_request.head.sha }} fetch-depth: 0 @@ -283,7 +283,7 @@ jobs: - name: Upload Unit Test Results if: always() - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 with: name: Unit Test Results (Subset ${{ matrix.subset }}) if-no-files-found: ignore @@ -305,7 +305,7 @@ jobs: - if: matrix.subset == 1 && github.event_name == 'push' name: Upload the list of Python packages - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 with: name: Frozen PIP package set path: | @@ -323,7 +323,7 @@ jobs: steps: - name: Check out source code - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: ref: ${{ github.event.pull_request.head.sha }} fetch-depth: 0 @@ -341,7 +341,7 @@ jobs: pip install -r scripts/requirements-actions.txt --require-hashes - name: Download Artifacts - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0 + uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 with: path: artifacts @@ -352,7 +352,7 @@ jobs: - name: Upload Unit Test Results if: always() - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 with: name: Unit Test Results if-no-files-found: ignore @@ -362,12 +362,12 @@ jobs: - name: Upload test results to Codecov if: ${{ !cancelled() && (github.event_name == 'push') }} - uses: codecov/test-results-action@47f89e9acb64b76debcd5ea40642d25a4adced9f # v1.1.1 + uses: codecov/test-results-action@0fa95f0e1eeaafde2c782583b36b28ad0d8c77d3 # v1.2.1 with: token: ${{ secrets.CODECOV_TOKEN }} - name: Publish Unit Test Results - uses: EnricoMi/publish-unit-test-result-action@34d7c956a59aed1bfebf31df77b8de55db9bbaaf # v2.21.0 + uses: EnricoMi/publish-unit-test-result-action@27d65e188ec43221b20d26de30f4892fad91df2f # v2.22.0 with: check_name: Unit Test Results files: "**/twister.xml" @@ -384,7 +384,7 @@ jobs: - name: Upload Twister Analysis Results if: needs.twister-build.result == 'failure' - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 with: name: Twister Analysis Results if-no-files-found: ignore diff --git a/.github/workflows/twister_tests.yml b/.github/workflows/twister_tests.yml index 7efdab39f03e..09ef984447b6 100644 --- a/.github/workflows/twister_tests.yml +++ b/.github/workflows/twister_tests.yml @@ -39,7 +39,7 @@ jobs: os: [ubuntu-24.04] steps: - name: checkout - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0 diff --git a/.github/workflows/twister_tests_blackbox.yml b/.github/workflows/twister_tests_blackbox.yml index 8fc09d7c040c..9748af7f20a4 100644 --- a/.github/workflows/twister_tests_blackbox.yml +++ b/.github/workflows/twister_tests_blackbox.yml @@ -31,7 +31,7 @@ jobs: runs-on: ubuntu-24.04 steps: - name: Checkout - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: path: zephyr fetch-depth: 0 @@ -44,7 +44,7 @@ jobs: cache-dependency-path: scripts/requirements-actions.txt - name: Setup Zephyr project - uses: zephyrproject-rtos/action-zephyr-setup@cefbf9086ce2da7d70e7ad9589af8aa1e4bda265 # v1.0.11 + uses: zephyrproject-rtos/action-zephyr-setup@360ff9b36e58499d9eb28015cdcde7ca03a5b04d # v1.0.12 with: app-path: zephyr toolchains: 'arm-zephyr-eabi:riscv64-zephyr-elf:x86_64-zephyr-elf' diff --git a/.github/workflows/west_cmds.yml b/.github/workflows/west_cmds.yml index e94b3138fe94..a85c88b89372 100644 --- a/.github/workflows/west_cmds.yml +++ b/.github/workflows/west_cmds.yml @@ -36,7 +36,7 @@ jobs: os: [ubuntu-22.04, macos-14, windows-2022] steps: - name: checkout - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0 From 151a9a33e6a861924cb9ee1b5e10b2a20459523e Mon Sep 17 00:00:00 2001 From: Hanan Arshad Date: Mon, 28 Apr 2025 14:43:46 +0500 Subject: [PATCH 2491/3659] drivers: sensor: pms7003: add support for additional PM parameters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The current PMS7003 sensor driver in Zephyr only supports reading the basic PM1.0, PM2.5, and PM10 concentration values. This update extends the driver to support additional data provided by the PMS7003 sensor, including: - Standard particle concentration values (CF=1) for PM1.0, PM2.5, and PM10 - Particle counts for particles greater than or equal to 0.3 µm, 0.5 µm, 1.0 µm, 2.5 µm, 5.0 µm, and 10.0 µm per 0.1 liter of air Adding support for these readings allows applications to access more detailed particulate data, improving the sensor’s usability in air quality monitoring and analysis scenarios. Signed-off-by: Hanan Arshad --- drivers/sensor/pms7003/pms7003.c | 61 ++++++++++++++++++++++++++------ drivers/sensor/sensor_shell.c | 9 +++++ include/zephyr/drivers/sensor.h | 19 ++++++++++ 3 files changed, 79 insertions(+), 10 deletions(-) diff --git a/drivers/sensor/pms7003/pms7003.c b/drivers/sensor/pms7003/pms7003.c index e47805171547..239f9b985dab 100644 --- a/drivers/sensor/pms7003/pms7003.c +++ b/drivers/sensor/pms7003/pms7003.c @@ -32,9 +32,18 @@ struct pms7003_config { }; struct pms7003_data { + uint16_t pm_1_0_cf; + uint16_t pm_2_5_cf; + uint16_t pm_10_cf; uint16_t pm_1_0; uint16_t pm_2_5; uint16_t pm_10; + uint16_t pm_0_3_count; + uint16_t pm_0_5_count; + uint16_t pm_1_0_count; + uint16_t pm_2_5_count; + uint16_t pm_5_0_count; + uint16_t pm_10_0_count; }; /** @@ -133,16 +142,32 @@ static int pms7003_sample_fetch(const struct device *dev, return -ETIME; } - drv_data->pm_1_0 = - (pms7003_receive_buffer[8] << 8) + pms7003_receive_buffer[9]; - drv_data->pm_2_5 = - (pms7003_receive_buffer[10] << 8) + pms7003_receive_buffer[11]; - drv_data->pm_10 = - (pms7003_receive_buffer[12] << 8) + pms7003_receive_buffer[13]; - + drv_data->pm_1_0_cf = (pms7003_receive_buffer[2] << 8) + pms7003_receive_buffer[3]; + drv_data->pm_2_5_cf = (pms7003_receive_buffer[4] << 8) + pms7003_receive_buffer[5]; + drv_data->pm_10_cf = (pms7003_receive_buffer[6] << 8) + pms7003_receive_buffer[7]; + drv_data->pm_1_0 = (pms7003_receive_buffer[8] << 8) + pms7003_receive_buffer[9]; + drv_data->pm_2_5 = (pms7003_receive_buffer[10] << 8) + pms7003_receive_buffer[11]; + drv_data->pm_10 = (pms7003_receive_buffer[12] << 8) + pms7003_receive_buffer[13]; + drv_data->pm_0_3_count = (pms7003_receive_buffer[14] << 8) + pms7003_receive_buffer[15]; + drv_data->pm_0_5_count = (pms7003_receive_buffer[16] << 8) + pms7003_receive_buffer[17]; + drv_data->pm_1_0_count = (pms7003_receive_buffer[18] << 8) + pms7003_receive_buffer[19]; + drv_data->pm_2_5_count = (pms7003_receive_buffer[20] << 8) + pms7003_receive_buffer[21]; + drv_data->pm_5_0_count = (pms7003_receive_buffer[22] << 8) + pms7003_receive_buffer[23]; + drv_data->pm_10_0_count = (pms7003_receive_buffer[24] << 8) + pms7003_receive_buffer[25]; + + LOG_DBG("pm1.0_cf = %d", drv_data->pm_1_0_cf); + LOG_DBG("pm2.5_cf = %d", drv_data->pm_2_5_cf); + LOG_DBG("pm10_cf = %d", drv_data->pm_10_cf); LOG_DBG("pm1.0 = %d", drv_data->pm_1_0); LOG_DBG("pm2.5 = %d", drv_data->pm_2_5); LOG_DBG("pm10 = %d", drv_data->pm_10); + LOG_DBG("pm0.3_count = %d", drv_data->pm_0_3_count); + LOG_DBG("pm0.5_count = %d", drv_data->pm_0_5_count); + LOG_DBG("pm1.0_count = %d", drv_data->pm_1_0_count); + LOG_DBG("pm2.5_count = %d", drv_data->pm_2_5_count); + LOG_DBG("pm5.0_count = %d", drv_data->pm_5_0_count); + LOG_DBG("pm10_count = %d", drv_data->pm_10_0_count); + return 0; } @@ -154,16 +179,32 @@ static int pms7003_channel_get(const struct device *dev, if (chan == SENSOR_CHAN_PM_1_0) { val->val1 = drv_data->pm_1_0; - val->val2 = 0; } else if (chan == SENSOR_CHAN_PM_2_5) { val->val1 = drv_data->pm_2_5; - val->val2 = 0; } else if (chan == SENSOR_CHAN_PM_10) { val->val1 = drv_data->pm_10; - val->val2 = 0; + } else if (chan == SENSOR_CHAN_PM_1_0_CF) { + val->val1 = drv_data->pm_1_0_cf; + } else if (chan == SENSOR_CHAN_PM_2_5_CF) { + val->val1 = drv_data->pm_2_5_cf; + } else if (chan == SENSOR_CHAN_PM_10_CF) { + val->val1 = drv_data->pm_10_cf; + } else if (chan == SENSOR_CHAN_PM_0_3_COUNT) { + val->val1 = drv_data->pm_0_3_count; + } else if (chan == SENSOR_CHAN_PM_0_5_COUNT) { + val->val1 = drv_data->pm_0_5_count; + } else if (chan == SENSOR_CHAN_PM_1_0_COUNT) { + val->val1 = drv_data->pm_1_0_count; + } else if (chan == SENSOR_CHAN_PM_2_5_COUNT) { + val->val1 = drv_data->pm_2_5_count; + } else if (chan == SENSOR_CHAN_PM_5_COUNT) { + val->val1 = drv_data->pm_5_0_count; + } else if (chan == SENSOR_CHAN_PM_10_COUNT) { + val->val1 = drv_data->pm_10_0_count; } else { return -ENOTSUP; } + val->val2 = 0; return 0; } diff --git a/drivers/sensor/sensor_shell.c b/drivers/sensor/sensor_shell.c index 5c816fa41901..e308dd79dd03 100644 --- a/drivers/sensor/sensor_shell.c +++ b/drivers/sensor/sensor_shell.c @@ -74,9 +74,18 @@ static const char *const sensor_channel_name[SENSOR_CHAN_COMMON_COUNT] = { [SENSOR_CHAN_GREEN] = "green", [SENSOR_CHAN_BLUE] = "blue", [SENSOR_CHAN_ALTITUDE] = "altitude", + [SENSOR_CHAN_PM_1_0_CF] = "pm_1_0_cf", + [SENSOR_CHAN_PM_2_5_CF] = "pm_2_5_cf", + [SENSOR_CHAN_PM_10_CF] = "pm_10_cf", [SENSOR_CHAN_PM_1_0] = "pm_1_0", [SENSOR_CHAN_PM_2_5] = "pm_2_5", [SENSOR_CHAN_PM_10] = "pm_10", + [SENSOR_CHAN_PM_0_3_COUNT] = "pm_0_3_count", + [SENSOR_CHAN_PM_0_5_COUNT] = "pm_0_5_count", + [SENSOR_CHAN_PM_1_0_COUNT] = "pm_1_0_count", + [SENSOR_CHAN_PM_2_5_COUNT] = "pm_2_5_count", + [SENSOR_CHAN_PM_5_COUNT] = "pm_5_0_count", + [SENSOR_CHAN_PM_10_COUNT] = "pm_10_count", [SENSOR_CHAN_DISTANCE] = "distance", [SENSOR_CHAN_CO2] = "co2", [SENSOR_CHAN_O2] = "o2", diff --git a/include/zephyr/drivers/sensor.h b/include/zephyr/drivers/sensor.h index c67fea68e2a8..4ece0abbd2a8 100644 --- a/include/zephyr/drivers/sensor.h +++ b/include/zephyr/drivers/sensor.h @@ -115,12 +115,31 @@ enum sensor_channel { /** Altitude, in meters */ SENSOR_CHAN_ALTITUDE, + /** PM1.0 concentration (standard particle, CF=1), in µg/m³ */ + SENSOR_CHAN_PM_1_0_CF, + /** PM2.5 concentration (standard particle, CF=1), in µg/m³ */ + SENSOR_CHAN_PM_2_5_CF, + /** PM10 concentration (standard particle, CF=1), in µg/m³ */ + SENSOR_CHAN_PM_10_CF, /** 1.0 micro-meters Particulate Matter, in ug/m^3 */ SENSOR_CHAN_PM_1_0, /** 2.5 micro-meters Particulate Matter, in ug/m^3 */ SENSOR_CHAN_PM_2_5, /** 10 micro-meters Particulate Matter, in ug/m^3 */ SENSOR_CHAN_PM_10, + /** Number of particles ≥ 0.3 µm per 0.1 liter of air */ + SENSOR_CHAN_PM_0_3_COUNT, + /** Number of particles ≥ 0.5 µm per 0.1 liter of air */ + SENSOR_CHAN_PM_0_5_COUNT, + /** Number of particles ≥ 1.0 µm per 0.1 liter of air */ + SENSOR_CHAN_PM_1_0_COUNT, + /** Number of particles ≥ 2.5 µm per 0.1 liter of air */ + SENSOR_CHAN_PM_2_5_COUNT, + /** Number of particles ≥ 5.0 µm per 0.1 liter of air */ + SENSOR_CHAN_PM_5_COUNT, + /** Number of particles ≥ 10.0 µm per 0.1 liter of air */ + SENSOR_CHAN_PM_10_COUNT, + /** Distance. From sensor to target, in meters */ SENSOR_CHAN_DISTANCE, From 75640be632575db66a84743f061d20844fa32e24 Mon Sep 17 00:00:00 2001 From: Thomas Lang Date: Sat, 6 Dec 2025 12:01:28 -0600 Subject: [PATCH 2492/3659] drivers: sensor: apds9960: Allow multiple sensor instances Allow for multiple apds9960s to be present Signed-off-by: Thomas Lang --- drivers/sensor/apds9960/Kconfig | 77 ---------------------- drivers/sensor/apds9960/apds9960.c | 73 +++++++------------- drivers/sensor/apds9960/apds9960_trigger.c | 2 +- dts/bindings/sensor/avago,apds9960.yaml | 45 +++++++++++++ 4 files changed, 68 insertions(+), 129 deletions(-) diff --git a/drivers/sensor/apds9960/Kconfig b/drivers/sensor/apds9960/Kconfig index 7f6b4bb00a5b..91e74b268c1b 100644 --- a/drivers/sensor/apds9960/Kconfig +++ b/drivers/sensor/apds9960/Kconfig @@ -58,81 +58,4 @@ config APDS9960_ENABLE_ALS help Enable Ambient Light Sense (ALS). -choice - prompt "Proximity Gain" - default APDS9960_PGAIN_4X - -config APDS9960_PGAIN_1X - bool "1x" - -config APDS9960_PGAIN_2X - bool "2x" - -config APDS9960_PGAIN_4X - bool "4x" - -config APDS9960_PGAIN_8X - bool "8x" - -endchoice - -choice - prompt "ALS and Color Gain" - default APDS9960_AGAIN_4X - -config APDS9960_AGAIN_1X - bool "1x" - -config APDS9960_AGAIN_4X - bool "4x" - -config APDS9960_AGAIN_16X - bool "16x" - -config APDS9960_AGAIN_64X - bool "64x" - -endchoice - -choice - prompt "Proximity Pulse Length" - default APDS9960_PPULSE_LENGTH_8US - -config APDS9960_PPULSE_LENGTH_4US - bool "4us" - -config APDS9960_PPULSE_LENGTH_8US - bool "8us" - -config APDS9960_PPULSE_LENGTH_16US - bool "16us" - -config APDS9960_PPULSE_LENGTH_32US - bool "32us" - -endchoice - -choice - prompt "Proximity LED boost current" - default APDS9960_PLED_BOOST_100PCT - -config APDS9960_PLED_BOOST_300PCT - bool "300%" - -config APDS9960_PLED_BOOST_200PCT - bool "200%" - -config APDS9960_PLED_BOOST_150PCT - bool "150%" - -config APDS9960_PLED_BOOST_100PCT - bool "100%" - -endchoice - -config APDS9960_PPULSE_COUNT - int "Proximity Pulse Count" - range 1 64 - default 8 - endif # APDS9960 diff --git a/drivers/sensor/apds9960/apds9960.c b/drivers/sensor/apds9960/apds9960.c index 32bb14caa22d..98d019aedc43 100644 --- a/drivers/sensor/apds9960/apds9960.c +++ b/drivers/sensor/apds9960/apds9960.c @@ -520,57 +520,28 @@ static DEVICE_API(sensor, apds9960_driver_api) = { #endif }; -static const struct apds9960_config apds9960_config = { - .i2c = I2C_DT_SPEC_INST_GET(0), -#ifdef CONFIG_APDS9960_FETCH_MODE_INTERRUPT - .int_gpio = GPIO_DT_SPEC_INST_GET(0, int_gpios), -#endif -#if CONFIG_APDS9960_PGAIN_8X - .pgain = APDS9960_PGAIN_8X, -#elif CONFIG_APDS9960_PGAIN_4X - .pgain = APDS9960_PGAIN_4X, -#elif CONFIG_APDS9960_PGAIN_2X - .pgain = APDS9960_PGAIN_2X, -#else - .pgain = APDS9960_PGAIN_1X, -#endif -#if CONFIG_APDS9960_AGAIN_64X - .again = APDS9960_AGAIN_64X, -#elif CONFIG_APDS9960_AGAIN_16X - .again = APDS9960_AGAIN_16X, -#elif CONFIG_APDS9960_AGAIN_4X - .again = APDS9960_AGAIN_4X, -#else - .again = APDS9960_AGAIN_1X, -#endif -#if CONFIG_APDS9960_PPULSE_LENGTH_32US - .ppcount = APDS9960_PPULSE_LENGTH_32US | - (CONFIG_APDS9960_PPULSE_COUNT - 1), -#elif CONFIG_APDS9960_PPULSE_LENGTH_16US - .ppcount = APDS9960_PPULSE_LENGTH_16US | - (CONFIG_APDS9960_PPULSE_COUNT - 1), -#elif CONFIG_APDS9960_PPULSE_LENGTH_8US - .ppcount = APDS9960_PPULSE_LENGTH_8US | - (CONFIG_APDS9960_PPULSE_COUNT - 1), +#if CONFIG_APDS9960_FETCH_MODE_INTERRUPT +#define APDS9960_CONFIG_INTERRUPT(inst) \ + .int_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, int_gpios, {0}), #else - .ppcount = APDS9960_PPULSE_LENGTH_4US | - (CONFIG_APDS9960_PPULSE_COUNT - 1), +#define APDS9960_CONFIG_INTERRUPT(inst) #endif -#if CONFIG_APDS9960_PLED_BOOST_300PCT - .pled_boost = APDS9960_PLED_BOOST_300, -#elif CONFIG_APDS9960_PLED_BOOST_200PCT - .pled_boost = APDS9960_PLED_BOOST_200, -#elif CONFIG_APDS9960_PLED_BOOST_150PCT - .pled_boost = APDS9960_PLED_BOOST_150, -#else - .pled_boost = APDS9960_PLED_BOOST_100, -#endif -}; - -static struct apds9960_data apds9960_data; - -PM_DEVICE_DT_INST_DEFINE(0, apds9960_pm_action); -SENSOR_DEVICE_DT_INST_DEFINE(0, apds9960_init, - PM_DEVICE_DT_INST_GET(0), &apds9960_data, &apds9960_config, - POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY, &apds9960_driver_api); +#define APDS9960_INIT(i) \ + static struct apds9960_data apds9960_data_##i; \ + static const struct apds9960_config apds9960_config_##i = { \ + .i2c = I2C_DT_SPEC_INST_GET(i), \ + APDS9960_CONFIG_INTERRUPT(i) \ + .pgain = DT_INST_PROP(i, pgain) << 1, \ + .again = DT_INST_PROP(i, again), \ + .ppcount = DT_INST_PROP(i, ppulse_length) | (DT_INST_PROP(i, ppulse_count) - 1), \ + .pled_boost = DT_INST_PROP(i, pled_boost) << 4, \ + }; \ + \ + PM_DEVICE_DT_INST_DEFINE(i, apds9960_pm_action); \ + \ + SENSOR_DEVICE_DT_INST_DEFINE(i, apds9960_init, \ + PM_DEVICE_DT_INST_GET(i), &apds9960_data_##i, &apds9960_config_##i, \ + POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY, &apds9960_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(APDS9960_INIT) diff --git a/drivers/sensor/apds9960/apds9960_trigger.c b/drivers/sensor/apds9960/apds9960_trigger.c index 245fdab68fba..d8a7a3d2a292 100644 --- a/drivers/sensor/apds9960/apds9960_trigger.c +++ b/drivers/sensor/apds9960/apds9960_trigger.c @@ -10,7 +10,7 @@ #include #include #include -#include "apds9960.h" +#include extern struct apds9960_data apds9960_driver; diff --git a/dts/bindings/sensor/avago,apds9960.yaml b/dts/bindings/sensor/avago,apds9960.yaml index 67e0043ff6e0..22df1431d4b2 100644 --- a/dts/bindings/sensor/avago,apds9960.yaml +++ b/dts/bindings/sensor/avago,apds9960.yaml @@ -15,3 +15,48 @@ properties: The interrupt pin of APDS9960 is open-drain, active low. If connected directly the MCU pin should be configured as pull-up, active low. + + pled-boost: + type: int + default: 0x01 + description: Proximity LED Boost Current + enum: + - 0x00 # 100 + - 0x01 # 150 + - 0x10 # 200 + - 0x11 # 300 + + pgain: + type: int + default: 0x01 + description: ALS and Color Gain + enum: + - 0x00 # 1x + - 0x01 # 4x + - 0x10 # 4x + - 0x11 # 8x + + again: + type: int + default: 0x01 + description: ALS and Color Gain + enum: + - 0x00 # 1x + - 0x01 # 4x + - 0x10 # 16x + - 0x11 # 64x + + ppulse-length: + type: int + default: 0x01 + description: Proximity Pulse Length + enum: + - 0x00 # 4us + - 0x01 # 8us + - 0x10 # 16us + - 0x11 # 32us + + ppulse-count: + type: int + default: 0x8 + description: Proximity Pulse Count From f505d31be62bfed6a1591872198c8fc8c4d83b01 Mon Sep 17 00:00:00 2001 From: Thomas Lang Date: Sat, 6 Dec 2025 18:00:15 -0600 Subject: [PATCH 2493/3659] drivers: sensor: apds9960: Setup gesture sensing configuration Created sensor specific channels and Kconfig for gesture sensing. Signed-off-by: Thomas Lang --- drivers/sensor/apds9960/Kconfig | 6 +++++ drivers/sensor/apds9960/apds9960.c | 13 ++++++++++- dts/bindings/sensor/avago,apds9960.yaml | 10 ++++++++ .../zephyr/drivers/sensor}/apds9960.h | 23 +++++++++++++++++++ 4 files changed, 51 insertions(+), 1 deletion(-) rename {drivers/sensor/apds9960 => include/zephyr/drivers/sensor}/apds9960.h (94%) diff --git a/drivers/sensor/apds9960/Kconfig b/drivers/sensor/apds9960/Kconfig index 91e74b268c1b..c1f65ca69b13 100644 --- a/drivers/sensor/apds9960/Kconfig +++ b/drivers/sensor/apds9960/Kconfig @@ -58,4 +58,10 @@ config APDS9960_ENABLE_ALS help Enable Ambient Light Sense (ALS). +config APDS9960_ENABLE_GESTURE + bool "Gesture Sense" + default n + help + Enable Gesture Sense. + endif # APDS9960 diff --git a/drivers/sensor/apds9960/apds9960.c b/drivers/sensor/apds9960/apds9960.c index 98d019aedc43..95d46f8f9e98 100644 --- a/drivers/sensor/apds9960/apds9960.c +++ b/drivers/sensor/apds9960/apds9960.c @@ -22,7 +22,7 @@ #include #include -#include "apds9960.h" +#include LOG_MODULE_REGISTER(APDS9960, CONFIG_SENSOR_LOG_LEVEL); @@ -527,6 +527,16 @@ static DEVICE_API(sensor, apds9960_driver_api) = { #define APDS9960_CONFIG_INTERRUPT(inst) #endif +#if CONFIG_APDS9960_ENABLE_GESTURE +#define APDS9960_CONFIG_GESTURE(inst) \ + .gesture_config = { \ + .proximity = DT_INST_PROP(inst, proximity), \ + .ir_difference = DT_INST_PROP(inst, ir_difference), \ + }, +#else +#define APDS9960_CONFIG_GESTURE(inst) +#endif + #define APDS9960_INIT(i) \ static struct apds9960_data apds9960_data_##i; \ static const struct apds9960_config apds9960_config_##i = { \ @@ -536,6 +546,7 @@ static DEVICE_API(sensor, apds9960_driver_api) = { .again = DT_INST_PROP(i, again), \ .ppcount = DT_INST_PROP(i, ppulse_length) | (DT_INST_PROP(i, ppulse_count) - 1), \ .pled_boost = DT_INST_PROP(i, pled_boost) << 4, \ + APDS9960_CONFIG_GESTURE(i) \ }; \ \ PM_DEVICE_DT_INST_DEFINE(i, apds9960_pm_action); \ diff --git a/dts/bindings/sensor/avago,apds9960.yaml b/dts/bindings/sensor/avago,apds9960.yaml index 22df1431d4b2..7cfb8dbda246 100644 --- a/dts/bindings/sensor/avago,apds9960.yaml +++ b/dts/bindings/sensor/avago,apds9960.yaml @@ -60,3 +60,13 @@ properties: type: int default: 0x8 description: Proximity Pulse Count + + proximity: + type: int + description: Gesture Proximity Enter Threshold + default: 40 + + ir-difference: + type: int + description: Minimum IR diode difference for gesture + default: 5 diff --git a/drivers/sensor/apds9960/apds9960.h b/include/zephyr/drivers/sensor/apds9960.h similarity index 94% rename from drivers/sensor/apds9960/apds9960.h rename to include/zephyr/drivers/sensor/apds9960.h index d40d12ac3fd4..79f994a87c59 100644 --- a/drivers/sensor/apds9960/apds9960.h +++ b/include/zephyr/drivers/sensor/apds9960.h @@ -9,6 +9,7 @@ #define ZEPHYR_DRIVERS_SENSOR_APDS9960_APDS9960_H_ #include +#include #define APDS9960_ENABLE_REG 0x80 #define APDS9960_ENABLE_GEN BIT(6) @@ -216,6 +217,11 @@ #define APDS9960_DEFAULT_WAIT_TIME 2.78 #define APDS9960_MAX_WAIT_TIME 10000 +struct apds9960_gesture_setup { + int proximity; + int ir_difference; +}; + struct apds9960_config { struct i2c_dt_spec i2c; #ifdef CONFIG_APDS9960_FETCH_MODE_INTERRUPT @@ -225,6 +231,22 @@ struct apds9960_config { uint8_t again; uint8_t ppcount; uint8_t pled_boost; +#ifdef CONFIG_APDS9960_ENABLE_GESTURE + struct apds9960_gesture_setup gesture_config; +#endif +}; + +/* apds9960 specific channels */ +enum sensor_channel_apds9960 { + SENSOR_CHAN_APDS9960_GESTURE = SENSOR_CHAN_PRIV_START, +}; + +enum apds9960_gesture { + APDS9960_GESTURE_NONE, + APDS9960_GESTURE_UP, + APDS9960_GESTURE_DOWN, + APDS9960_GESTURE_LEFT, + APDS9960_GESTURE_RIGHT, }; struct apds9960_data { @@ -233,6 +255,7 @@ struct apds9960_data { const struct device *dev; uint16_t sample_crgb[4]; uint8_t pdata; + enum apds9960_gesture gesture; #ifdef CONFIG_APDS9960_TRIGGER sensor_trigger_handler_t p_th_handler; From 109f0e15c49c8e144f3c32953e76ec9861ed9665 Mon Sep 17 00:00:00 2001 From: Thomas Lang Date: Thu, 9 Oct 2025 20:49:29 -0400 Subject: [PATCH 2494/3659] drivers: sensor: apds9960: Added gesture detection Created logic to calculate gestures from the APDS9960 sensor Signed-off-by: Thomas Lang --- drivers/sensor/apds9960/apds9960.c | 186 +++++++++++++++++++++++++++-- 1 file changed, 177 insertions(+), 9 deletions(-) diff --git a/drivers/sensor/apds9960/apds9960.c b/drivers/sensor/apds9960/apds9960.c index 95d46f8f9e98..eb78ea455d54 100644 --- a/drivers/sensor/apds9960/apds9960.c +++ b/drivers/sensor/apds9960/apds9960.c @@ -48,6 +48,124 @@ static void apds9960_gpio_callback(const struct device *dev, } #endif +#if CONFIG_APDS9960_ENABLE_GESTURE +static void apds9960_gesture_determine(struct apds9960_data *data, + uint8_t *gesture_fifo, int ir_difference) +{ + int tmp_up; + int tmp_left; + int net_up = 0; + int net_left = 0; + + static bool up_trig; + static bool down_trig; + static bool left_trig; + static bool right_trig; + + tmp_up = (int) gesture_fifo[0] - (int) gesture_fifo[1]; + tmp_left = (int) gesture_fifo[2] - (int) gesture_fifo[3]; + + if (abs(tmp_up) > ir_difference && abs(tmp_up) > abs(tmp_left)) { + net_up = tmp_up; + } + if (abs(tmp_left) > ir_difference && abs(tmp_left) > abs(tmp_up)) { + net_left = tmp_left; + } + + if (net_up > 0) { + if (down_trig) { + data->gesture = APDS9960_GESTURE_DOWN; + up_trig = false; + down_trig = false; + left_trig = false; + right_trig = false; + } else { + up_trig = true; + } + } else if (net_up < 0) { + if (up_trig) { + data->gesture = APDS9960_GESTURE_UP; + up_trig = false; + down_trig = false; + left_trig = false; + right_trig = false; + } else { + down_trig = true; + } + } else { + /* No movement in up down direction */ + } + if (net_left > 0) { + if (right_trig) { + data->gesture = APDS9960_GESTURE_RIGHT; + up_trig = false; + down_trig = false; + left_trig = false; + right_trig = false; + } else { + left_trig = true; + } + } else if (net_left < 0) { + if (left_trig) { + data->gesture = APDS9960_GESTURE_LEFT; + up_trig = false; + down_trig = false; + left_trig = false; + right_trig = false; + } else { + right_trig = true; + } + } else { + /* No movement in left right direction*/ + } + LOG_DBG("Net up: 0x%x, Net left: 0x%x", net_up, net_left); + +} +static int apds9960_gesture_fetch(const struct device *dev) +{ + const struct apds9960_config *config = dev->config; + struct apds9960_data *data = dev->data; + + uint8_t gesture_fifo_cnt; + uint8_t gstatus; + uint8_t gesture_fifo[4]; + + data->gesture = APDS9960_GESTURE_NONE; + + if (i2c_reg_read_byte_dt(&config->i2c, + APDS9960_GSTATUS_REG, &gstatus)) { + return -EIO; + } + + while (gstatus & APDS9960_GSTATUS_GVALID) { + if (i2c_reg_read_byte_dt(&config->i2c, + APDS9960_GFLVL_REG, &gesture_fifo_cnt)) { + return -EIO; + } + + for (int i = 0; i < gesture_fifo_cnt; ++i) { + /* Read up fifo and adjacent registers */ + if (i2c_burst_read_dt(&config->i2c, + APDS9960_GFIFO_U_REG, + (uint8_t *) gesture_fifo, + 4)) { + return -EIO; + } + + apds9960_gesture_determine(data, gesture_fifo, + config->gesture_config.ir_difference); + } + + if (i2c_reg_read_byte_dt(&config->i2c, + APDS9960_GSTATUS_REG, &gstatus)) { + return -EIO; + } + } + + return 0; +} +#endif + static int apds9960_sample_fetch(const struct device *dev, enum sensor_channel chan) { @@ -63,6 +181,12 @@ static int apds9960_sample_fetch(const struct device *dev, return -ENOTSUP; } +#ifdef CONFIG_APDS9960_ENABLE_GESTURE + if (apds9960_gesture_fetch(dev)) { + return -EIO; + } +#endif + #ifndef CONFIG_APDS9960_TRIGGER #ifdef CONFIG_APDS9960_FETCH_MODE_INTERRUPT apds9960_setup_int(config, true); @@ -90,16 +214,9 @@ static int apds9960_sample_fetch(const struct device *dev, start_time = k_uptime_get(); #ifdef CONFIG_APDS9960_ENABLE_ALS while (!(tmp & APDS9960_STATUS_AINT)) { - k_sleep(K_MSEC(APDS9960_DEFAULT_WAIT_TIME)); - if (i2c_reg_read_byte_dt(&config->i2c, APDS9960_STATUS_REG, &tmp)) { - return -EIO; - } - if ((k_uptime_get() - start_time) > APDS9960_MAX_WAIT_TIME) { - return -ETIMEDOUT; - } - } #else while (!(tmp & APDS9960_STATUS_PINT)) { +#endif k_sleep(K_MSEC(APDS9960_DEFAULT_WAIT_TIME)); if (i2c_reg_read_byte_dt(&config->i2c, APDS9960_STATUS_REG, &tmp)) { return -EIO; @@ -108,7 +225,6 @@ static int apds9960_sample_fetch(const struct device *dev, return -ETIMEDOUT; } } -#endif #endif LOG_DBG("status: 0x%x", tmp); @@ -172,6 +288,12 @@ static int apds9960_channel_get(const struct device *dev, val->val1 = sys_le16_to_cpu(data->sample_crgb[3]); val->val2 = 0; break; +#endif +#ifdef CONFIG_APDS9960_ENABLE_GESTURE + case SENSOR_CHAN_APDS9960_GESTURE: + val->val1 = data->gesture; + val->val2 = 0; + break; #endif case SENSOR_CHAN_PROX: val->val1 = data->pdata; @@ -304,6 +426,45 @@ static int apds9960_ambient_setup(const struct device *dev) } #endif +#ifdef CONFIG_APDS9960_ENABLE_GESTURE +static int apds9960_gesture_setup(const struct device *dev) +{ + const struct apds9960_config *config = dev->config; + + if (i2c_reg_write_byte_dt(&config->i2c, + APDS9960_GPENTH_REG, config->gesture_config.proximity)) { + LOG_ERR("Gesture proximity enter not set."); + return -EIO; + } + if (i2c_reg_write_byte_dt(&config->i2c, + APDS9960_GEXTH_REG, config->gesture_config.proximity)) { + LOG_ERR("Gesture proximity exit not set."); + return -EIO; + } + if (i2c_reg_write_byte_dt(&config->i2c, + APDS9960_GCONFIG1_REG, 0)) { + LOG_ERR("Gesture config 1 not set."); + return -EIO; + } + if (i2c_reg_write_byte_dt(&config->i2c, + APDS9960_GCONFIG2_REG, APDS9960_GGAIN_4X)) { + LOG_ERR("Gesture config 2 not set."); + return -EIO; + } + if (i2c_reg_write_byte_dt(&config->i2c, + APDS9960_GCONFIG4_REG, 0)) { + LOG_ERR("Gesture config 4 not set."); + return -EIO; + } + if (i2c_reg_update_byte_dt(&config->i2c, APDS9960_ENABLE_REG, APDS9960_ENABLE_GEN, + APDS9960_ENABLE_GEN)) { + LOG_ERR("Gesture on bit not set."); + return -EIO; + } + return 0; +} +#endif + static int apds9960_sensor_setup(const struct device *dev) { const struct apds9960_config *config = dev->config; @@ -385,6 +546,13 @@ static int apds9960_sensor_setup(const struct device *dev) } #endif +#ifdef CONFIG_APDS9960_ENABLE_GESTURE + if (apds9960_gesture_setup(dev)) { + LOG_ERR("Failed to setup gesture functionality"); + return -EIO; + } +#endif + #ifdef CONFIG_APDS9960_FETCH_MODE_POLL if (i2c_reg_update_byte_dt(&config->i2c, APDS9960_ENABLE_REG, APDS9960_ENABLE_PON, APDS9960_ENABLE_PON)) { From b5f71d3028ee358f311f6101c540e36e98430a5d Mon Sep 17 00:00:00 2001 From: Thomas Lang Date: Sun, 12 Oct 2025 21:09:01 -0400 Subject: [PATCH 2495/3659] samples: sensor: apds9960: Added gesture support Added a new channel fetch to demonstrate reading gestures Signed-off-by: Thomas Lang --- samples/sensor/apds9960/prj.conf | 2 ++ samples/sensor/apds9960/src/main.c | 16 +++++++++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/samples/sensor/apds9960/prj.conf b/samples/sensor/apds9960/prj.conf index 9f4b4aa1c8c8..8147a7762c95 100644 --- a/samples/sensor/apds9960/prj.conf +++ b/samples/sensor/apds9960/prj.conf @@ -9,3 +9,5 @@ CONFIG_I2C_LOG_LEVEL_INF=y CONFIG_APDS9960_TRIGGER_GLOBAL_THREAD=n CONFIG_PM_DEVICE=n + +CONFIG_APDS9960_ENABLE_GESTURE=n diff --git a/samples/sensor/apds9960/src/main.c b/samples/sensor/apds9960/src/main.c index ab96ae7990f1..220992631b6e 100644 --- a/samples/sensor/apds9960/src/main.c +++ b/samples/sensor/apds9960/src/main.c @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -24,10 +25,18 @@ static void trigger_handler(const struct device *dev, } #endif +char states[5][6] = { + "NONE", + "UP", + "DOWN", + "LEFT", + "RIGHT", +}; + int main(void) { const struct device *dev; - struct sensor_value intensity, pdata; + struct sensor_value intensity, pdata, gesture; printk("APDS9960 sample application\n"); dev = DEVICE_DT_GET_ONE(avago_apds9960); @@ -72,9 +81,10 @@ int main(void) sensor_channel_get(dev, SENSOR_CHAN_LIGHT, &intensity); sensor_channel_get(dev, SENSOR_CHAN_PROX, &pdata); + sensor_channel_get(dev, SENSOR_CHAN_APDS9960_GESTURE, &gesture); - printk("ambient light intensity %d, proximity %d\n", - intensity.val1, pdata.val1); + printk("ambient light intensity %d, proximity %d, gesture %s\n", + intensity.val1, pdata.val1, states[gesture.val1]); #ifdef CONFIG_PM_DEVICE pm_device_action_run(dev, PM_DEVICE_ACTION_SUSPEND); From 7744d2084033fb489b882772f7702d50f634082f Mon Sep 17 00:00:00 2001 From: Marcelo Roberto Jimenez Date: Sun, 7 Dec 2025 17:20:14 -0300 Subject: [PATCH 2496/3659] drivers: serial: uart_xmc4xxx: Run clang-format before applying a patch This patch just formats the uart_xmc4xxx.c file before the real patch, otherwise the changes would be hard to read. Signed-off-by: Marcelo Roberto Jimenez --- drivers/serial/uart_xmc4xxx.c | 102 +++++++++++++++++----------------- 1 file changed, 50 insertions(+), 52 deletions(-) diff --git a/drivers/serial/uart_xmc4xxx.c b/drivers/serial/uart_xmc4xxx.c index 770b86aee8dd..074cee62ad13 100644 --- a/drivers/serial/uart_xmc4xxx.c +++ b/drivers/serial/uart_xmc4xxx.c @@ -5,7 +5,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#define DT_DRV_COMPAT infineon_xmc4xxx_uart +#define DT_DRV_COMPAT infineon_xmc4xxx_uart #include #include @@ -20,7 +20,7 @@ #define IRQS_PER_USIC 6 #define CURRENT_BUFFER 0 -#define NEXT_BUFFER 1 +#define NEXT_BUFFER 1 struct uart_xmc4xxx_config { XMC_USIC_CH_t *uart; @@ -114,7 +114,7 @@ static void disable_tx_events(const struct uart_xmc4xxx_config *config) { if (config->fifo_tx_size > 0) { XMC_USIC_CH_TXFIFO_DisableEvent(config->uart, - XMC_USIC_CH_TXFIFO_EVENT_CONF_STANDARD); + XMC_USIC_CH_TXFIFO_EVENT_CONF_STANDARD); } else { XMC_USIC_CH_DisableEvent(config->uart, XMC_USIC_CH_EVENT_TRANSMIT_SHIFT); } @@ -222,7 +222,7 @@ static int uart_xmc4xxx_irq_tx_ready(const struct device *dev) return !XMC_USIC_CH_TXFIFO_IsFull(config->uart); } else { return XMC_USIC_CH_GetTransmitBufferStatus(config->uart) == - XMC_USIC_CH_TBUF_STATUS_IDLE; + XMC_USIC_CH_TBUF_STATUS_IDLE; } } @@ -233,10 +233,11 @@ static void uart_xmc4xxx_irq_rx_disable(const struct device *dev) if (config->fifo_rx_size > 0) { XMC_USIC_CH_RXFIFO_DisableEvent(config->uart, XMC_USIC_CH_RXFIFO_EVENT_CONF_STANDARD | - XMC_USIC_CH_RXFIFO_EVENT_CONF_ALTERNATE); + XMC_USIC_CH_RXFIFO_EVENT_CONF_ALTERNATE); } else { - XMC_USIC_CH_DisableEvent(config->uart, XMC_USIC_CH_EVENT_STANDARD_RECEIVE | - XMC_USIC_CH_EVENT_ALTERNATIVE_RECEIVE); + XMC_USIC_CH_DisableEvent(config->uart, + XMC_USIC_CH_EVENT_STANDARD_RECEIVE | + XMC_USIC_CH_EVENT_ALTERNATIVE_RECEIVE); } } static void uart_xmc4xxx_irq_rx_enable(const struct device *dev) @@ -256,7 +257,7 @@ static void uart_xmc4xxx_irq_rx_enable(const struct device *dev) #endif XMC_USIC_CH_RXFIFO_EnableEvent(config->uart, XMC_USIC_CH_RXFIFO_EVENT_CONF_STANDARD | - XMC_USIC_CH_RXFIFO_EVENT_CONF_ALTERNATE); + XMC_USIC_CH_RXFIFO_EVENT_CONF_ALTERNATE); } else { /* flush out any received bytes while the uart rx irq was disabled */ recv_status = XMC_USIC_CH_GetReceiveBufferStatus(config->uart); @@ -267,8 +268,9 @@ static void uart_xmc4xxx_irq_rx_enable(const struct device *dev) XMC_UART_CH_GetReceivedData(config->uart); } - XMC_USIC_CH_EnableEvent(config->uart, XMC_USIC_CH_EVENT_STANDARD_RECEIVE | - XMC_USIC_CH_EVENT_ALTERNATIVE_RECEIVE); + XMC_USIC_CH_EnableEvent(config->uart, + XMC_USIC_CH_EVENT_STANDARD_RECEIVE | + XMC_USIC_CH_EVENT_ALTERNATIVE_RECEIVE); } } #endif @@ -925,8 +927,7 @@ static int uart_xmc4xxx_init(const struct device *dev) return ret; } /* Connect UART RX to the target pin */ - XMC_UART_CH_SetInputSource(config->uart, XMC_UART_CH_INPUT_RXD, - config->input_src); + XMC_UART_CH_SetInputSource(config->uart, XMC_UART_CH_INPUT_RXD, config->input_src); #if defined(CONFIG_UART_INTERRUPT_DRIVEN) || defined(CONFIG_UART_ASYNC_API) config->irq_config_func(dev); @@ -990,22 +991,22 @@ static DEVICE_API(uart, uart_xmc4xxx_driver_api) = { #endif #if defined(CONFIG_UART_INTERRUPT_DRIVEN) || defined(CONFIG_UART_ASYNC_API) -#define XMC4XXX_IRQ_HANDLER(index) \ -static void uart_xmc4xxx_irq_setup_##index(const struct device *dev) \ -{ \ - IRQ_CONNECT(DT_INST_IRQ_BY_NAME(index, tx, irq), \ - DT_INST_IRQ_BY_NAME(index, tx, priority), uart_xmc4xxx_isr, \ - DEVICE_DT_INST_GET(index), 0); \ - IRQ_CONNECT(DT_INST_IRQ_BY_NAME(index, rx, irq), \ - DT_INST_IRQ_BY_NAME(index, rx, priority), uart_xmc4xxx_isr, \ - DEVICE_DT_INST_GET(index), 0); \ - irq_enable(DT_INST_IRQ_BY_NAME(index, tx, irq)); \ - irq_enable(DT_INST_IRQ_BY_NAME(index, rx, irq)); \ -} +#define XMC4XXX_IRQ_HANDLER(index) \ + static void uart_xmc4xxx_irq_setup_##index(const struct device *dev) \ + { \ + IRQ_CONNECT(DT_INST_IRQ_BY_NAME(index, tx, irq), \ + DT_INST_IRQ_BY_NAME(index, tx, priority), uart_xmc4xxx_isr, \ + DEVICE_DT_INST_GET(index), 0); \ + IRQ_CONNECT(DT_INST_IRQ_BY_NAME(index, rx, irq), \ + DT_INST_IRQ_BY_NAME(index, rx, priority), uart_xmc4xxx_isr, \ + DEVICE_DT_INST_GET(index), 0); \ + irq_enable(DT_INST_IRQ_BY_NAME(index, tx, irq)); \ + irq_enable(DT_INST_IRQ_BY_NAME(index, rx, irq)); \ + } -#define XMC4XXX_IRQ_STRUCT_INIT(index) \ - .irq_config_func = uart_xmc4xxx_irq_setup_##index, \ - .irq_num_tx = DT_INST_IRQ_BY_NAME(index, tx, irq), \ +#define XMC4XXX_IRQ_STRUCT_INIT(index) \ + .irq_config_func = uart_xmc4xxx_irq_setup_##index, \ + .irq_num_tx = DT_INST_IRQ_BY_NAME(index, tx, irq), \ .irq_num_rx = DT_INST_IRQ_BY_NAME(index, rx, irq), #else @@ -1013,30 +1014,27 @@ static void uart_xmc4xxx_irq_setup_##index(const struct device *dev) #define XMC4XXX_IRQ_STRUCT_INIT(index) #endif -#define XMC4XXX_INIT(index) \ -PINCTRL_DT_INST_DEFINE(index); \ -XMC4XXX_IRQ_HANDLER(index) \ -static struct uart_xmc4xxx_data xmc4xxx_data_##index = { \ - .config.baudrate = DT_INST_PROP(index, current_speed), \ - UART_DMA_CHANNEL(index, tx, MEMORY_TO_PERIPHERAL, 8, 1) \ - UART_DMA_CHANNEL(index, rx, PERIPHERAL_TO_MEMORY, 1, 8) \ -}; \ - \ -static const struct uart_xmc4xxx_config xmc4xxx_config_##index = { \ - .uart = (XMC_USIC_CH_t *)DT_INST_REG_ADDR(index), \ - .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(index), \ - .input_src = DT_INST_ENUM_IDX(index, input_src), \ -XMC4XXX_IRQ_STRUCT_INIT(index) \ - .fifo_start_offset = DT_INST_PROP(index, fifo_start_offset), \ - .fifo_tx_size = DT_INST_ENUM_IDX(index, fifo_tx_size), \ - .fifo_rx_size = DT_INST_ENUM_IDX(index, fifo_rx_size), \ -}; \ - \ - DEVICE_DT_INST_DEFINE(index, uart_xmc4xxx_init, \ - NULL, \ - &xmc4xxx_data_##index, \ - &xmc4xxx_config_##index, PRE_KERNEL_1, \ - CONFIG_SERIAL_INIT_PRIORITY, \ - &uart_xmc4xxx_driver_api); +#define XMC4XXX_INIT(index) \ + PINCTRL_DT_INST_DEFINE(index); \ + XMC4XXX_IRQ_HANDLER(index) \ + \ + static struct uart_xmc4xxx_data xmc4xxx_data_##index = { \ + .config.baudrate = DT_INST_PROP(index, current_speed), \ + UART_DMA_CHANNEL(index, tx, MEMORY_TO_PERIPHERAL, 8, 1) \ + UART_DMA_CHANNEL(index, rx, PERIPHERAL_TO_MEMORY, 1, 8)}; \ + \ + static const struct uart_xmc4xxx_config xmc4xxx_config_##index = { \ + .uart = (XMC_USIC_CH_t *)DT_INST_REG_ADDR(index), \ + .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(index), \ + .input_src = DT_INST_ENUM_IDX(index, input_src), \ + XMC4XXX_IRQ_STRUCT_INIT(index).fifo_start_offset = \ + DT_INST_PROP(index, fifo_start_offset), \ + .fifo_tx_size = DT_INST_ENUM_IDX(index, fifo_tx_size), \ + .fifo_rx_size = DT_INST_ENUM_IDX(index, fifo_rx_size), \ + }; \ + \ + DEVICE_DT_INST_DEFINE(index, uart_xmc4xxx_init, NULL, &xmc4xxx_data_##index, \ + &xmc4xxx_config_##index, PRE_KERNEL_1, CONFIG_SERIAL_INIT_PRIORITY, \ + &uart_xmc4xxx_driver_api); DT_INST_FOREACH_STATUS_OKAY(XMC4XXX_INIT) From 62a49211b158066cad133f8a08df75d3ad03a577 Mon Sep 17 00:00:00 2001 From: Marcelo Roberto Jimenez Date: Mon, 8 Dec 2025 23:16:41 -0300 Subject: [PATCH 2497/3659] drivers: serial: uart_xmc4xxx: Enable run time configuration This patch enables run time configuration for the XMC4xxx serial ports. Signed-off-by: Marcelo Roberto Jimenez --- .../xmc45_relax_kit/xmc45_relax_kit.dts | 2 + .../xmc47_relax_kit/xmc47_relax_kit.dts | 4 + drivers/serial/uart_xmc4xxx.c | 206 +++++++++++++++++- .../boards/xmc45_relax_kit.overlay | 2 + .../boards/xmc47_relax_kit.overlay | 2 + 5 files changed, 213 insertions(+), 3 deletions(-) diff --git a/boards/infineon/xmc45_relax_kit/xmc45_relax_kit.dts b/boards/infineon/xmc45_relax_kit/xmc45_relax_kit.dts index b578d244bea4..f5f1dc32b53c 100644 --- a/boards/infineon/xmc45_relax_kit/xmc45_relax_kit.dts +++ b/boards/infineon/xmc45_relax_kit/xmc45_relax_kit.dts @@ -111,6 +111,8 @@ fifo-start-offset = <0>; fifo-tx-size = <16>; fifo-rx-size = <16>; + data-bits = <8>; + stop-bits = "1"; status = "okay"; }; diff --git a/boards/infineon/xmc47_relax_kit/xmc47_relax_kit.dts b/boards/infineon/xmc47_relax_kit/xmc47_relax_kit.dts index 11bd2f42e3c4..528142633a2d 100644 --- a/boards/infineon/xmc47_relax_kit/xmc47_relax_kit.dts +++ b/boards/infineon/xmc47_relax_kit/xmc47_relax_kit.dts @@ -102,6 +102,8 @@ fifo-start-offset = <0>; fifo-tx-size = <16>; fifo-rx-size = <16>; + data-bits = <8>; + stop-bits = "1"; status = "okay"; }; @@ -116,6 +118,8 @@ fifo-start-offset = <0>; fifo-tx-size = <0>; fifo-rx-size = <0>; + data-bits = <8>; + stop-bits = "1"; status = "okay"; }; diff --git a/drivers/serial/uart_xmc4xxx.c b/drivers/serial/uart_xmc4xxx.c index 074cee62ad13..d132589d206b 100644 --- a/drivers/serial/uart_xmc4xxx.c +++ b/drivers/serial/uart_xmc4xxx.c @@ -53,6 +53,7 @@ struct uart_dma_stream { struct uart_xmc4xxx_data { XMC_UART_CH_CONFIG_t config; + struct uart_config *uart_cfg; #if defined(CONFIG_UART_INTERRUPT_DRIVEN) uart_irq_callback_user_data_t user_cb; void *user_data; @@ -102,6 +103,162 @@ static void uart_xmc4xxx_poll_out(const struct device *dev, unsigned char c) XMC_UART_CH_Transmit(config->uart, c); } +static int convert_config_xmc4xxx_to_zephyr(struct uart_config *zephyr, + const XMC_UART_CH_CONFIG_t *x) +{ + struct uart_config z; + + z.baudrate = x->baudrate; + + switch (x->parity_mode) { + case XMC_USIC_CH_PARITY_MODE_NONE: + z.parity = UART_CFG_PARITY_NONE; + break; + case XMC_USIC_CH_PARITY_MODE_ODD: + z.parity = UART_CFG_PARITY_ODD; + break; + case XMC_USIC_CH_PARITY_MODE_EVEN: + z.parity = UART_CFG_PARITY_EVEN; + break; + /* XMC4xxx has no support for MARK and SPACE parity */ + /* + * case XMC_USIC_CH_PARITY_MODE_MARK: + * z.parity = UART_CFG_PARITY_MARK; + * break; + * case XMC_USIC_CH_PARITY_MODE_SPACE: + * z.parity = UART_CFG_PARITY_SPACE; + * break; + */ + default: + return -EINVAL; + } + + switch (x->stop_bits) { + case 1: + z.stop_bits = UART_CFG_STOP_BITS_1; + break; + case 2: + z.stop_bits = UART_CFG_STOP_BITS_2; + break; + default: + return -EINVAL; + } + + switch (x->data_bits) { + case 5: + z.data_bits = UART_CFG_DATA_BITS_5; + break; + case 6: + z.data_bits = UART_CFG_DATA_BITS_6; + break; + case 7: + z.data_bits = UART_CFG_DATA_BITS_7; + break; + case 8: + z.data_bits = UART_CFG_DATA_BITS_8; + break; + case 9: + z.data_bits = UART_CFG_DATA_BITS_9; + break; + default: + return -EINVAL; + } + + z.flow_ctrl = UART_CFG_FLOW_CTRL_NONE; + + *zephyr = z; + + return 0; +} + +static int convert_config_zephyr_to_xmc4xxx(XMC_UART_CH_CONFIG_t *xmc, const struct uart_config *z) +{ + XMC_UART_CH_CONFIG_t x; + + x.baudrate = z->baudrate; + + /* When zero -> will always use "fractional divider mode". */ + x.normal_divider_mode = 0; + + switch (z->data_bits) { + case UART_CFG_DATA_BITS_5: + x.data_bits = 5; + break; + case UART_CFG_DATA_BITS_6: + x.data_bits = 6; + break; + case UART_CFG_DATA_BITS_7: + x.data_bits = 7; + break; + case UART_CFG_DATA_BITS_8: + x.data_bits = 8; + break; + case UART_CFG_DATA_BITS_9: + x.data_bits = 9; + break; + default: + return -EINVAL; + } + + /* When zero -> driver takes care. */ + x.frame_length = 0; + + switch (z->stop_bits) { + case UART_CFG_STOP_BITS_0_5: + x.stop_bits = 1; + return -EINVAL; + case UART_CFG_STOP_BITS_1: + x.stop_bits = 1; + break; + case UART_CFG_STOP_BITS_1_5: + x.stop_bits = 1; + return -EINVAL; + case UART_CFG_STOP_BITS_2: + x.stop_bits = 2; + break; + default: + x.stop_bits = 1; + return -EINVAL; + } + + /* When zero -> driver actual oversampling == 16 */ + x.oversampling = 0; + + switch (z->parity) { + case UART_CFG_PARITY_NONE: + x.parity_mode = XMC_USIC_CH_PARITY_MODE_NONE; + break; + case UART_CFG_PARITY_ODD: + x.parity_mode = XMC_USIC_CH_PARITY_MODE_ODD; + break; + case UART_CFG_PARITY_EVEN: + x.parity_mode = XMC_USIC_CH_PARITY_MODE_EVEN; + break; + case UART_CFG_PARITY_MARK: + x.parity_mode = UART_CFG_PARITY_NONE; + return -ENOTSUP; + case UART_CFG_PARITY_SPACE: + x.parity_mode = UART_CFG_PARITY_NONE; + return -ENOTSUP; + default: + return -EINVAL; + } + + switch (z->flow_ctrl) { + case UART_CFG_FLOW_CTRL_NONE: + break; + case UART_CFG_FLOW_CTRL_RTS_CTS: + case UART_CFG_FLOW_CTRL_DTR_DSR: + case UART_CFG_FLOW_CTRL_RS485: + return -ENOTSUP; + default: + return -EINVAL; + } + *xmc = x; + + return 0; +} + #if defined(CONFIG_UART_ASYNC_API) static inline void async_timer_start(struct k_work_delayable *work, int32_t timeout) { @@ -892,8 +1049,10 @@ static int uart_xmc4xxx_init(const struct device *dev) struct uart_xmc4xxx_data *data = dev->data; uint8_t fifo_offset = config->fifo_start_offset; - data->config.data_bits = 8U; - data->config.stop_bits = 1U; + ret = convert_config_zephyr_to_xmc4xxx(&data->config, data->uart_cfg); + if (ret) { + return ret; + } XMC_UART_CH_Init(config->uart, &(data->config)); @@ -941,9 +1100,41 @@ static int uart_xmc4xxx_init(const struct device *dev) return ret; } +#ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE +static int uart_xmc4xxx_configure(const struct device *dev, const struct uart_config *cfg) +{ + int ret; + struct uart_xmc4xxx_data *data = dev->data; + struct uart_config uart_cfg_bak = *data->uart_cfg; + + *data->uart_cfg = *cfg; + ret = uart_xmc4xxx_init(dev); + if (ret) { + *data->uart_cfg = uart_cfg_bak; + } + + return ret; +} + +static int uart_xmc4xxx_config_get(const struct device *dev, struct uart_config *cfg) +{ + int ret; + struct uart_xmc4xxx_data *data = dev->data; + + ret = convert_config_xmc4xxx_to_zephyr(data->uart_cfg, &data->config); + *cfg = *data->uart_cfg; + + return ret; +} +#endif /* CONFIG_UART_USE_RUNTIME_CONFIGURE */ + static DEVICE_API(uart, uart_xmc4xxx_driver_api) = { .poll_in = uart_xmc4xxx_poll_in, .poll_out = uart_xmc4xxx_poll_out, +#ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE + .configure = uart_xmc4xxx_configure, + .config_get = uart_xmc4xxx_config_get, +#endif /* CONFIG_UART_USE_RUNTIME_CONFIGURE */ #if defined(CONFIG_UART_INTERRUPT_DRIVEN) .fifo_fill = uart_xmc4xxx_fifo_fill, .fifo_read = uart_xmc4xxx_fifo_read, @@ -1018,8 +1209,17 @@ static DEVICE_API(uart, uart_xmc4xxx_driver_api) = { PINCTRL_DT_INST_DEFINE(index); \ XMC4XXX_IRQ_HANDLER(index) \ \ + static struct uart_config uart_cfg_##index = { \ + .baudrate = DT_INST_PROP(index, current_speed), \ + .parity = DT_INST_ENUM_IDX(index, parity), \ + .stop_bits = DT_INST_ENUM_IDX(index, stop_bits), \ + .data_bits = DT_INST_ENUM_IDX(index, data_bits), \ + .flow_ctrl = DT_INST_PROP(index, hw_flow_control) ? UART_CFG_FLOW_CTRL_RTS_CTS \ + : UART_CFG_FLOW_CTRL_NONE, \ + }; \ + \ static struct uart_xmc4xxx_data xmc4xxx_data_##index = { \ - .config.baudrate = DT_INST_PROP(index, current_speed), \ + .uart_cfg = &uart_cfg_##index, \ UART_DMA_CHANNEL(index, tx, MEMORY_TO_PERIPHERAL, 8, 1) \ UART_DMA_CHANNEL(index, rx, PERIPHERAL_TO_MEMORY, 1, 8)}; \ \ diff --git a/tests/drivers/uart/uart_async_api/boards/xmc45_relax_kit.overlay b/tests/drivers/uart/uart_async_api/boards/xmc45_relax_kit.overlay index 69ed39b02208..447c7e4cd409 100644 --- a/tests/drivers/uart/uart_async_api/boards/xmc45_relax_kit.overlay +++ b/tests/drivers/uart/uart_async_api/boards/xmc45_relax_kit.overlay @@ -15,6 +15,8 @@ dut: &usic2ch0 { fifo-start-offset = <0>; fifo-tx-size = <0>; fifo-rx-size = <0>; + data-bits = <8>; + stop-bits = "1"; status = "okay"; }; diff --git a/tests/drivers/uart/uart_async_api/boards/xmc47_relax_kit.overlay b/tests/drivers/uart/uart_async_api/boards/xmc47_relax_kit.overlay index a6db8e6f8d8a..8697af51d430 100644 --- a/tests/drivers/uart/uart_async_api/boards/xmc47_relax_kit.overlay +++ b/tests/drivers/uart/uart_async_api/boards/xmc47_relax_kit.overlay @@ -20,6 +20,8 @@ dut: &usic1ch1 { fifo-start-offset = <0>; fifo-tx-size = <0>; fifo-rx-size = <0>; + data-bits = <8>; + stop-bits = "1"; }; &uart_tx_p3_15_u1c1 { From abaf2518001da31713606851da2ae9fb16bee5f0 Mon Sep 17 00:00:00 2001 From: Liam Ogletree Date: Tue, 6 Jan 2026 10:30:52 -0600 Subject: [PATCH 2498/3659] drivers: haptics: Add error callback mechanism to haptics API Haptics devices provide protection features to prevent damage during operation. Adds an error callback mechanism to the haptics API to enable haptics device drivers to raise these conditions to the application layer. Enumerates a subset of errors that are common to modern haptics devices across major vendors. Signed-off-by: Liam Ogletree --- include/zephyr/drivers/haptics.h | 58 +++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/include/zephyr/drivers/haptics.h b/include/zephyr/drivers/haptics.h index b00d821ccba3..1e074b86083d 100644 --- a/include/zephyr/drivers/haptics.h +++ b/include/zephyr/drivers/haptics.h @@ -31,10 +31,23 @@ extern "C" { #endif +/** + * @brief Haptics error types + */ +enum haptics_error_type { + HAPTICS_ERROR_OVERCURRENT = BIT(0), /**< Output overcurrent error */ + HAPTICS_ERROR_OVERTEMPERATURE = BIT(1), /**< Device overtemperature error */ + HAPTICS_ERROR_UNDERVOLTAGE = BIT(2), /**< Power source undervoltage error */ + HAPTICS_ERROR_OVERVOLTAGE = BIT(3), /**< Power source overvoltage error */ + HAPTICS_ERROR_DC = BIT(4), /**< Output direct-current error */ + + /* Device-specific error codes can follow, refer to the device’s header file */ + HAPTICS_ERROR_PRIV_START = BIT(5), +}; + /** * @typedef haptics_stop_output_t * @brief Set the haptic device to stop output - * @param dev Pointer to the device structure for haptic device instance */ typedef int (*haptics_stop_output_t)(const struct device *dev); @@ -44,12 +57,32 @@ typedef int (*haptics_stop_output_t)(const struct device *dev); */ typedef int (*haptics_start_output_t)(const struct device *dev); +/** + * @typedef haptics_error_callback_t + * @brief Callback function for error interrupt + * + * @param dev Pointer to the haptic device + * @param errors Device errors (bitmask of @ref haptics_error_type values) + * @param user_data User data provided when the error callback was registered + */ +typedef void (*haptics_error_callback_t)(const struct device *dev, const uint32_t errors, + void *const user_data); + +/** + * @typedef haptics_register_error_callback_t + * @brief Register a callback function for haptics errors + */ +typedef int (*haptics_register_error_callback_t)(const struct device *dev, + haptics_error_callback_t cb, + void *const user_data); + /** * @brief Haptic device API */ __subsystem struct haptics_driver_api { haptics_start_output_t start_output; haptics_stop_output_t stop_output; + haptics_register_error_callback_t register_error_callback; }; /** @@ -86,6 +119,29 @@ static inline int z_impl_haptics_stop_output(const struct device *dev) return api->stop_output(dev); } +/** + * @brief Register a callback function for haptics errors + * + * @param dev Pointer to the haptic device + * @param cb Callback function (of type @ref haptics_error_callback_t) + * @param user_data User data to be provided back to the application via the callback + * + * @retval 0 if successful + * @retval <0 if failed + */ +static inline int haptics_register_error_callback(const struct device *dev, + haptics_error_callback_t cb, + void *const user_data) +{ + const struct haptics_driver_api *api = (const struct haptics_driver_api *)dev->api; + + if (api->register_error_callback == NULL) { + return -ENOSYS; + } + + return api->register_error_callback(dev, cb, user_data); +} + /** * @} */ From 339d2df232495209f0287186aa58017630e3da13 Mon Sep 17 00:00:00 2001 From: Liam Ogletree Date: Tue, 6 Jan 2026 10:40:07 -0600 Subject: [PATCH 2499/3659] drivers: haptics: Update CS40L5x driver to use new haptics API Modifies the CS40L5x driver to use the error callback mechanism added to the haptics API instead of a device-specific API extension. Signed-off-by: Liam Ogletree --- drivers/haptics/cs40l5x.c | 27 ++++++++++++---------- include/zephyr/drivers/haptics/cs40l5x.h | 29 +++--------------------- 2 files changed, 18 insertions(+), 38 deletions(-) diff --git a/drivers/haptics/cs40l5x.c b/drivers/haptics/cs40l5x.c index 76111e902a5d..020bf0ad5c80 100644 --- a/drivers/haptics/cs40l5x.c +++ b/drivers/haptics/cs40l5x.c @@ -770,7 +770,7 @@ static void cs40l5x_error_callback(const struct device *const dev, const uint32_ struct cs40l5x_data *const data = dev->data; if (data->error_callback != NULL) { - (void)data->error_callback(dev, error_bitmask); + (void)data->error_callback(dev, error_bitmask, data->user_data); } } @@ -854,7 +854,7 @@ static int cs40l5x_process_mailbox(const struct device *const dev) case CS40L5X_MBOX_PERMANENT_SHORT_DETECTED: __fallthrough; case CS40L5X_MBOX_RUNTIME_SHORT_DETECTED: - (void)cs40l5x_error_callback(dev, CS40L5X_ERROR_AMPLIFIER_SHORT); + (void)cs40l5x_error_callback(dev, HAPTICS_ERROR_OVERCURRENT); return 0; default: @@ -881,37 +881,37 @@ static int cs40l5x_process_interrupts(const struct device *const dev, if (FIELD_GET(CS40L5X_MASK_IRQ1_AMP, irq_ints[CS40L5X_INT1]) != 0) { LOG_INST_WRN(config->log, "amplifier short detected"); - error_bitmask |= CS40L5X_ERROR_AMPLIFIER_SHORT; + error_bitmask |= HAPTICS_ERROR_OVERCURRENT; } if (FIELD_GET(CS40L5X_MASK_IRQ8_TEMP, irq_ints[CS40L5X_INT8]) != 0) { LOG_INST_WRN(config->log, "overtemperature detected"); - error_bitmask |= CS40L5X_ERROR_OVERTEMPERATURE; + error_bitmask |= HAPTICS_ERROR_OVERTEMPERATURE; } if (FIELD_GET(CS40L5X_MASK_IRQ9_UVP, irq_ints[CS40L5X_INT9]) != 0) { LOG_INST_WRN(config->log, "undervoltage detected"); - error_bitmask |= CS40L5X_ERROR_UNDERVOLTAGE; + error_bitmask |= HAPTICS_ERROR_UNDERVOLTAGE; } if (FIELD_GET(CS40L5X_MASK_IRQ9_IND_SHORT, irq_ints[CS40L5X_INT9]) != 0) { LOG_INST_WRN(config->log, "inductor short detected"); - error_bitmask |= CS40L5X_ERROR_INDUCTOR_SHORT; + error_bitmask |= HAPTICS_ERROR_OVERCURRENT; } if (FIELD_GET(CS40L5X_MASK_IRQ9_CUR_LIMIT, irq_ints[CS40L5X_INT9]) != 0) { LOG_INST_WRN(config->log, "overcurrent condition detected"); - error_bitmask |= CS40L5X_ERROR_OVERCURRENT; + error_bitmask |= HAPTICS_ERROR_OVERCURRENT; } if (FIELD_GET(CS40L5X_MASK_IRQ1_VDDB, irq_ints[CS40L5X_INT10]) != 0) { LOG_INST_WRN(config->log, "battery undervoltage detected"); - error_bitmask |= CS40L5X_ERROR_BATTERY_UNDERVOLTAGE; + error_bitmask |= HAPTICS_ERROR_UNDERVOLTAGE; } if (error_bitmask != 0) { @@ -1870,13 +1870,15 @@ int cs40l5x_logger_get(const struct device *const dev, enum cs40l5x_logger_sourc return ret; } -void cs40l5x_register_error_callback(const struct device *dev, - void (*error_callback)(const struct device *const haptic_dev, - const uint32_t errors)) +static int cs40l5x_register_error_callback(const struct device *dev, haptics_error_callback_t cb, + void *const user_data) { struct cs40l5x_data *const data = dev->data; - data->error_callback = error_callback; + data->error_callback = cb; + data->user_data = user_data; + + return 0; } int cs40l5x_select_output(const struct device *const dev, const enum cs40l5x_bank bank, @@ -2293,6 +2295,7 @@ int cs40l5x_upload_pwle(const struct device *const dev, const enum cs40l5x_custo static DEVICE_API(haptics, cs40l5x_driver_api) = { .start_output = &cs40l5x_start_output, .stop_output = &cs40l5x_stop_output, + .register_error_callback = &cs40l5x_register_error_callback, }; static int cs40l5x_pm_resume(const struct device *const dev) diff --git a/include/zephyr/drivers/haptics/cs40l5x.h b/include/zephyr/drivers/haptics/cs40l5x.h index 1770470ec79e..8f2d6f8d67ba 100644 --- a/include/zephyr/drivers/haptics/cs40l5x.h +++ b/include/zephyr/drivers/haptics/cs40l5x.h @@ -77,20 +77,6 @@ enum cs40l5x_custom_index { CS40L5X_NUM_CUSTOM_EFFECTS, /**< Maximum number of custom haptics effects */ }; -/** - * @brief Types of fatal CS40L5x hardware errors - * - * @details Provided to application callback function. See @ref cs40l5x_register_error_callback(). - */ -enum cs40l5x_error_type { - CS40L5X_ERROR_AMPLIFIER_SHORT = BIT(0), /**< Amplifier short detected */ - CS40L5X_ERROR_OVERTEMPERATURE = BIT(1), /**< Overtemperature detected */ - CS40L5X_ERROR_UNDERVOLTAGE = BIT(2), /**< Undervoltage detected */ - CS40L5X_ERROR_INDUCTOR_SHORT = BIT(3), /**< Inductor short detected */ - CS40L5X_ERROR_OVERCURRENT = BIT(4), /**< Overcurrent condition detected */ - CS40L5X_ERROR_BATTERY_UNDERVOLTAGE = BIT(4), /**< Vdd_batt undervoltage detected */ -}; - /** * @brief Options for runtime haptics logging * @@ -318,7 +304,9 @@ struct cs40l5x_data { /**< Callback handler for trigger logging */ struct gpio_callback trigger_callback; /**< Application-provided callback to recover from fatal hardware errors */ - void (*error_callback)(const struct device *const haptic_dev, const uint32_t errors); + haptics_error_callback_t error_callback; + /**< Application-provided user data for callback context */ + void *user_data; /**< Semaphore used to sequence the calibration routine */ struct k_sem calibration_semaphore; /**< F0 and ReDC data derived from calibration */ @@ -418,17 +406,6 @@ int cs40l5x_logger(const struct device *const dev, enum cs40l5x_logger logger_st int cs40l5x_logger_get(const struct device *const dev, enum cs40l5x_logger_source source, enum cs40l5x_logger_source_type type, uint32_t *const value); -/** - * @brief Register an application callback to handle fatal hardware errors - * - * @param dev Pointer to the device structure for haptic device instance - * @param error_callback Application function that takes a pointer to the device structure for a - * haptic device instance and a bitmask of @ref cs40l5x_error_type - */ -void cs40l5x_register_error_callback(const struct device *dev, - void (*error_callback)(const struct device *const haptic_dev, - const uint32_t errors)); - /** * @brief Select haptic effect triggered via @ref haptics_start_output() * From 4bf67fca7a55c13a5c16a318f26b451ba9ba3105 Mon Sep 17 00:00:00 2001 From: Liam Ogletree Date: Tue, 6 Jan 2026 10:54:41 -0600 Subject: [PATCH 2500/3659] samples: cs40l5x: Update sample application based on driver changes Modifies sample application to use error callback mechanism added to haptics API instead of device-specific API extension. Signed-off-by: Liam Ogletree --- samples/drivers/haptics/cs40l5x/src/main.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/samples/drivers/haptics/cs40l5x/src/main.c b/samples/drivers/haptics/cs40l5x/src/main.c index c23c2636b140..0ab46460c82b 100644 --- a/samples/drivers/haptics/cs40l5x/src/main.c +++ b/samples/drivers/haptics/cs40l5x/src/main.c @@ -288,7 +288,8 @@ static const struct cs40l5x_pwle_section pwle_sections[] = { }, }; -static void cs40l5x_dummy_callback(const struct device *const dev, const uint32_t errors) +static void cs40l5x_dummy_callback(const struct device *const dev, const uint32_t errors, + void *const user_data) { LOG_INF("fatal errors detected (0x%08X)", errors); } @@ -310,7 +311,7 @@ int main(void) } } - (void)cs40l5x_register_error_callback(cs40l5x, cs40l5x_dummy_callback); + (void)haptics_register_error_callback(cs40l5x, cs40l5x_dummy_callback, NULL); /* Demonstration of PCM upload (CUSTOM0) */ error = cs40l5x_upload_pcm(cs40l5x, CS40L5X_CUSTOM_0, CS40L5X_DEMO_REDC, CS40L5X_DEMO_F0, From 61dea0bcc8a74458728e5670e5bfa076a0139559 Mon Sep 17 00:00:00 2001 From: Mohamed Azhar Date: Mon, 5 Jan 2026 16:47:40 +0530 Subject: [PATCH 2501/3659] dts: arm: microchip: sam: add SPI node and binding file Add device tree binding file for Microchip g1 SPI driver Signed-off-by: Mohamed Azhar --- .../sam/sam_d5x_e5x/common/samd5xe5x_n.dtsi | 2 +- .../sam/sam_d5x_e5x/common/samd5xe5x_p.dtsi | 2 +- dts/bindings/spi/microchip,sercom-g1-spi.yaml | 53 +++++++++++++++++++ 3 files changed, 55 insertions(+), 2 deletions(-) create mode 100644 dts/bindings/spi/microchip,sercom-g1-spi.yaml diff --git a/dts/arm/microchip/sam/sam_d5x_e5x/common/samd5xe5x_n.dtsi b/dts/arm/microchip/sam/sam_d5x_e5x/common/samd5xe5x_n.dtsi index a2c252691599..4e1eedac1358 100644 --- a/dts/arm/microchip/sam/sam_d5x_e5x/common/samd5xe5x_n.dtsi +++ b/dts/arm/microchip/sam/sam_d5x_e5x/common/samd5xe5x_n.dtsi @@ -45,12 +45,12 @@ sercom6: sercom@43000800 { compatible = "microchip,sercom-g1"; - status = "disabled"; reg = <0x43000800 0x31>; interrupts = <70 0>, <71 0>, <72 0>, <73 0>; clocks = <&mclkperiph CLOCK_MCHP_MCLKPERIPH_ID_APBD_SERCOM6>, <&gclkperiph CLOCK_MCHP_GCLKPERIPH_ID_SERCOM6_CORE>; clock-names = "mclk", "gclk"; + status = "disabled"; }; sercom7: sercom@43000c00 { diff --git a/dts/arm/microchip/sam/sam_d5x_e5x/common/samd5xe5x_p.dtsi b/dts/arm/microchip/sam/sam_d5x_e5x/common/samd5xe5x_p.dtsi index ac71565163d8..13e662e9c828 100644 --- a/dts/arm/microchip/sam/sam_d5x_e5x/common/samd5xe5x_p.dtsi +++ b/dts/arm/microchip/sam/sam_d5x_e5x/common/samd5xe5x_p.dtsi @@ -45,12 +45,12 @@ sercom6: sercom@43000800 { compatible = "microchip,sercom-g1"; - status = "disabled"; reg = <0x43000800 0x31>; interrupts = <70 0>, <71 0>, <72 0>, <73 0>; clocks = <&mclkperiph CLOCK_MCHP_MCLKPERIPH_ID_APBD_SERCOM6>, <&gclkperiph CLOCK_MCHP_GCLKPERIPH_ID_SERCOM6_CORE>; clock-names = "mclk", "gclk"; + status = "disabled"; }; sercom7: sercom@43000c00 { diff --git a/dts/bindings/spi/microchip,sercom-g1-spi.yaml b/dts/bindings/spi/microchip,sercom-g1-spi.yaml new file mode 100644 index 000000000000..9d1189b37dd4 --- /dev/null +++ b/dts/bindings/spi/microchip,sercom-g1-spi.yaml @@ -0,0 +1,53 @@ +# Copyright (c) 2026 Microchip Technology Inc. +# SPDX-License-Identifier: Apache-2.0 + +description: | + Microchip SERCOM SPI + + Group G1 SERCOM SPI includes the following hardware peripherals: + - module name="SERCOM" id="U2201" version="5.0.0" + +compatible: "microchip,sercom-g1-spi" + +include: + - name: spi-controller.yaml + - name: pinctrl-device.yaml + +properties: + reg: + required: true + + clocks: + required: true + + clock-names: + required: true + + dipo: + type: int + required: true + description: | + Data In Pinout + + dopo: + type: int + required: true + description: | + Data Out Pinout + + dmas: + description: | + Optional TX & RX dma specifiers. Each specifier will have a phandle + reference to the dmac controller, the channel number, and peripheral + trigger source. + + For example dmas for TX, RX on SERCOM3 + dmas = <&dmac 0 0xb>, <&dmac 1 0xa>; + + dma-names: + description: | + Required if the dmas property exists. This should be "tx" and "rx" + to match the dmas property. + + For example + dma-names = "tx", "rx"; From 139f2e7b833383bf07b752330abbf2bc264a0738 Mon Sep 17 00:00:00 2001 From: Mohamed Azhar Date: Mon, 5 Jan 2026 19:30:41 +0530 Subject: [PATCH 2502/3659] drivers: spi: microchip: Add SPI g1 driver - Add SPI driver for Microchip SERCOM g1 - Add and update Kconfig files to support the driver - Update CMakeLists.txt to include the new driver Signed-off-by: Mohamed Azhar --- drivers/spi/CMakeLists.txt | 1 + drivers/spi/Kconfig | 1 + drivers/spi/Kconfig.mchp | 55 + drivers/spi/spi_mchp_sercom_g1.c | 1765 ++++++++++++++++++++++++++++++ 4 files changed, 1822 insertions(+) create mode 100644 drivers/spi/Kconfig.mchp create mode 100644 drivers/spi/spi_mchp_sercom_g1.c diff --git a/drivers/spi/CMakeLists.txt b/drivers/spi/CMakeLists.txt index afafbc749ebf..ca5652b60acd 100644 --- a/drivers/spi/CMakeLists.txt +++ b/drivers/spi/CMakeLists.txt @@ -37,6 +37,7 @@ zephyr_library_sources_ifdef(CONFIG_SPI_LITEX_LITESPI spi_litex_litespi.c) zephyr_library_sources_ifdef(CONFIG_SPI_MAX32 spi_max32.c) zephyr_library_sources_ifdef(CONFIG_SPI_MCHP_MSS spi_mchp_mss.c) zephyr_library_sources_ifdef(CONFIG_SPI_MCHP_QSPI spi_mchp_mss_qspi.c) +zephyr_library_sources_ifdef(CONFIG_SPI_MCHP_SERCOM_G1 spi_mchp_sercom_g1.c) zephyr_library_sources_ifdef(CONFIG_SPI_MCUX_DSPI spi_mcux_dspi.c) zephyr_library_sources_ifdef(CONFIG_SPI_MCUX_ECSPI spi_mcux_ecspi.c) zephyr_library_sources_ifdef(CONFIG_SPI_MCUX_FLEXCOMM spi_mcux_flexcomm.c) diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 53d1ffc415d5..5e87cabd1271 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -122,6 +122,7 @@ source "drivers/spi/Kconfig.it51xxx" source "drivers/spi/Kconfig.it8xxx2" source "drivers/spi/Kconfig.litex" source "drivers/spi/Kconfig.max32" +source "drivers/spi/Kconfig.mchp" source "drivers/spi/Kconfig.mchp_mss" source "drivers/spi/Kconfig.mchp_mss_qspi" source "drivers/spi/Kconfig.mcux_dspi" diff --git a/drivers/spi/Kconfig.mchp b/drivers/spi/Kconfig.mchp new file mode 100644 index 000000000000..acb0a314c1e5 --- /dev/null +++ b/drivers/spi/Kconfig.mchp @@ -0,0 +1,55 @@ +# Copyright (c) 2026 Microchip Technology Inc. +# SPDX-License-Identifier: Apache-2.0 + +config SPI_MCHP_SERCOM_G1 + bool "Microchip SERCOM SPI driver" + default y + depends on DT_HAS_MICROCHIP_SERCOM_G1_SPI_ENABLED + select PINCTRL + select GPIO + help + Enable support for the Microchip SERCOM SPI driver. + +menu "Microchip SERCOM SPI driver options" + +config SPI_MCHP_INTER_CHARACTER_SPACE + int "Microchip SERCOM SPI Inter-Character Spacing (in clock cycles)" + default 63 if SPI_SLAVE + default 0 + range 0 63 + depends on SPI_MCHP_SERCOM_G1 + help + Number of clock cycles to delay between characters on SPI bus. + +endmenu + + +config SPI_MCHP_INTERRUPT_DRIVEN + bool "Microchip SERCOM SPI driver (Interrupt Driven)" + depends on SPI_MCHP_SERCOM_G1 && !SPI_ASYNC + help + Enable interrupt-driven support for Microchip Devices + SERCOM SPI driver. + +menu "SPI ASYNC SELECTION" + depends on SPI_MCHP_SERCOM_G1 && SPI_ASYNC + +choice + prompt "Select Async Mode: Interrupt or DMA" + default SPI_MCHP_INTERRUPT_DRIVEN_ASYNC + help + Choose between interrupt or DMA async mode for the MCHP SPI driver. + +config SPI_MCHP_INTERRUPT_DRIVEN_ASYNC + bool "MCHP Interrupt Async" + help + Enables interrupt support for the MCHP SPI driver in async mode. + +config SPI_MCHP_DMA_DRIVEN_ASYNC + bool "MCHP DMA" + select DMA + help + Enables DMA in async mode for the MCHP SPI driver. + +endchoice +endmenu diff --git a/drivers/spi/spi_mchp_sercom_g1.c b/drivers/spi/spi_mchp_sercom_g1.c new file mode 100644 index 000000000000..24d5cee987ca --- /dev/null +++ b/drivers/spi/spi_mchp_sercom_g1.c @@ -0,0 +1,1765 @@ +/* + * Copyright (c) 2026 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define DT_DRV_COMPAT microchip_sercom_g1_spi + +#define LOG_LEVEL CONFIG_SPI_LOG_LEVEL +LOG_MODULE_REGISTER(spi_mchp_sercom_g1); + +#include "spi_context.h" + +#define SPI_MCHP_MAX_XFER_SIZE 65535 +#define SUPPORTED_SPI_WORD_SIZE 8 +#define SPI_PIN_CNT 4 +#define TIMEOUT_VALUE_US 1000 +#define DELAY_US 2 + +struct mchp_spi_reg_config { + sercom_registers_t *regs; + uint32_t pads; +}; + +struct mchp_spi_clock { + const struct device *clock_dev; + clock_control_subsys_t mclk_sys; + clock_control_subsys_t gclk_sys; +}; + +struct mchp_spi_dma { + const struct device *dma_dev; + uint8_t tx_dma_request; + uint8_t tx_dma_channel; + uint8_t rx_dma_request; + uint8_t rx_dma_channel; +}; + +struct spi_mchp_dev_config { + struct mchp_spi_reg_config reg_cfg; + const struct pinctrl_dev_config *pcfg; + +#if CONFIG_SPI_MCHP_DMA_DRIVEN_ASYNC + struct mchp_spi_dma spi_dma; +#endif /* CONFIG_SPI_MCHP_DMA_DRIVEN_ASYNC */ + +#if defined(CONFIG_SPI_ASYNC) || defined(CONFIG_SPI_MCHP_INTERRUPT_DRIVEN) + void (*irq_config_func)(const struct device *dev); +#endif /* CONFIG_SPI_ASYNC) || CONFIG_SPI_MCHP_INTERRUPT_DRIVEN */ + + struct mchp_spi_clock spi_clock; +}; + +struct spi_mchp_dev_data { + struct spi_context ctx; + +#if defined(CONFIG_SPI_ASYNC) || defined(CONFIG_SPI_MCHP_INTERRUPT_DRIVEN) + uint8_t dummysize; +#endif /* CONFIG_SPI_ASYNC) || CONFIG_SPI_MCHP_INTERRUPT_DRIVEN */ + +#if CONFIG_SPI_MCHP_DMA_DRIVEN_ASYNC + const struct device *dev; + uint32_t dma_segment_len; +#endif /* CONFIG_SPI_MCHP_DMA_DRIVEN_ASYNC */ +}; + +/*Wait for synchronization*/ +static inline void spi_wait_sync(const struct mchp_spi_reg_config *spi_reg_cfg, uint32_t sync_flag) +{ + if (WAIT_FOR(((spi_reg_cfg->regs->SPIM.SERCOM_SYNCBUSY & sync_flag) == 0), TIMEOUT_VALUE_US, + k_busy_wait(DELAY_US)) == false) { + LOG_ERR("Timeout waiting for SPI SYNCBUSY ENABLE clear"); + } +} + +/*Enable the SPI peripheral*/ +static void spi_enable(const struct mchp_spi_reg_config *spi_reg_cfg, spi_operation_t op) +{ + spi_wait_sync(spi_reg_cfg, SERCOM_SPIM_SYNCBUSY_ENABLE_Msk); + if (SPI_OP_MODE_GET(op) == SPI_OP_MODE_MASTER) { + spi_reg_cfg->regs->SPIM.SERCOM_CTRLA |= SERCOM_SPIM_CTRLA_ENABLE_Msk; + } else { + spi_reg_cfg->regs->SPIS.SERCOM_CTRLA |= SERCOM_SPIS_CTRLA_ENABLE_Msk; + } + spi_wait_sync(spi_reg_cfg, SERCOM_SPIM_SYNCBUSY_ENABLE_Msk); +} + +/*Disable the SPI peripheral*/ +static void spi_disable(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + spi_wait_sync(spi_reg_cfg, SERCOM_SPIM_SYNCBUSY_ENABLE_Msk); + spi_reg_cfg->regs->SPIM.SERCOM_CTRLA &= ~SERCOM_SPIM_CTRLA_ENABLE_Msk; + spi_wait_sync(spi_reg_cfg, SERCOM_SPIM_SYNCBUSY_ENABLE_Msk); +} + +/*Set the SPI Master Mode*/ +static inline void spi_master_mode(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + /* Clear the MODE bit field and set it to SPI Master mode */ + spi_reg_cfg->regs->SPIM.SERCOM_CTRLA = + (spi_reg_cfg->regs->SPIM.SERCOM_CTRLA & ~SERCOM_SPIM_CTRLA_MODE_Msk) | + SERCOM_SPIM_CTRLA_MODE_SPI_MASTER; +} + +/*Set the SPI Slave Mode*/ +static inline void spi_slave_mode(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + /* Clear the MODE bit field and set it to SPI Slave mode */ + spi_reg_cfg->regs->SPIS.SERCOM_CTRLA = + (spi_reg_cfg->regs->SPIS.SERCOM_CTRLA & ~SERCOM_SPIS_CTRLA_MODE_Msk) | + SERCOM_SPIS_CTRLA_MODE_SPI_SLAVE; +} + +/*Set the SPI Data Order, MSB first*/ +static void spi_msb_first(const struct mchp_spi_reg_config *spi_reg_cfg, spi_operation_t op) +{ + /* Clear the DORD bit field and set it to MSB first */ + if (SPI_OP_MODE_GET(op) == SPI_OP_MODE_MASTER) { + spi_reg_cfg->regs->SPIM.SERCOM_CTRLA = + (spi_reg_cfg->regs->SPIM.SERCOM_CTRLA & ~SERCOM_SPIM_CTRLA_DORD_Msk) | + SERCOM_SPIM_CTRLA_DORD_MSB; + } else { + spi_reg_cfg->regs->SPIS.SERCOM_CTRLA = + (spi_reg_cfg->regs->SPIS.SERCOM_CTRLA & ~SERCOM_SPIS_CTRLA_DORD_Msk) | + SERCOM_SPIS_CTRLA_DORD_MSB; + } +} + +/*Set the SPI Data Order,LSB first*/ +static void spi_lsb_first(const struct mchp_spi_reg_config *spi_reg_cfg, spi_operation_t op) +{ + /* Clear the DORD bit field and set it to LSB first */ + if (SPI_OP_MODE_GET(op) == SPI_OP_MODE_MASTER) { + spi_reg_cfg->regs->SPIM.SERCOM_CTRLA = + (spi_reg_cfg->regs->SPIM.SERCOM_CTRLA & ~SERCOM_SPIM_CTRLA_DORD_Msk) | + SERCOM_SPIM_CTRLA_DORD_LSB; + } else { + spi_reg_cfg->regs->SPIS.SERCOM_CTRLA = + (spi_reg_cfg->regs->SPIS.SERCOM_CTRLA & ~SERCOM_SPIS_CTRLA_DORD_Msk) | + SERCOM_SPIS_CTRLA_DORD_LSB; + } +} + +/*Set the SPI Clock Polarity Idle Low*/ +static void spi_cpol_idle_low(const struct mchp_spi_reg_config *spi_reg_cfg, spi_operation_t op) +{ + /* Clear the CPOL bit field and set clock polarity to Idle Low */ + if (SPI_OP_MODE_GET(op) == SPI_OP_MODE_MASTER) { + spi_reg_cfg->regs->SPIM.SERCOM_CTRLA = + (spi_reg_cfg->regs->SPIM.SERCOM_CTRLA & ~SERCOM_SPIM_CTRLA_CPOL_Msk) | + SERCOM_SPIM_CTRLA_CPOL_IDLE_LOW; + } else { + spi_reg_cfg->regs->SPIS.SERCOM_CTRLA = + (spi_reg_cfg->regs->SPIS.SERCOM_CTRLA & ~SERCOM_SPIS_CTRLA_CPOL_Msk) | + SERCOM_SPIS_CTRLA_CPOL_IDLE_LOW; + } +} + +/*Set the SPI Clock Polarity Idle High*/ +static void spi_cpol_idle_high(const struct mchp_spi_reg_config *spi_reg_cfg, spi_operation_t op) +{ + /* Clear the CPOL bit field and set clock polarity to Idle High */ + if (SPI_OP_MODE_GET(op) == SPI_OP_MODE_MASTER) { + spi_reg_cfg->regs->SPIM.SERCOM_CTRLA = + (spi_reg_cfg->regs->SPIM.SERCOM_CTRLA & ~SERCOM_SPIM_CTRLA_CPOL_Msk) | + SERCOM_SPIM_CTRLA_CPOL_IDLE_HIGH; + } else { + spi_reg_cfg->regs->SPIS.SERCOM_CTRLA = + (spi_reg_cfg->regs->SPIS.SERCOM_CTRLA & ~SERCOM_SPIS_CTRLA_CPOL_Msk) | + SERCOM_SPIS_CTRLA_CPOL_IDLE_HIGH; + } +} + +/*Set the SPI Clock Phase leading Edge*/ +static void spi_cpha_lead_edge(const struct mchp_spi_reg_config *spi_reg_cfg, spi_operation_t op) +{ + /* Clear the CPHA bit field and set clock phase to Leading Edge */ + if (SPI_OP_MODE_GET(op) == SPI_OP_MODE_MASTER) { + spi_reg_cfg->regs->SPIM.SERCOM_CTRLA = + (spi_reg_cfg->regs->SPIM.SERCOM_CTRLA & ~SERCOM_SPIM_CTRLA_CPHA_Msk) | + SERCOM_SPIM_CTRLA_CPHA_LEADING_EDGE; + } else { + spi_reg_cfg->regs->SPIS.SERCOM_CTRLA = + (spi_reg_cfg->regs->SPIS.SERCOM_CTRLA & ~SERCOM_SPIS_CTRLA_CPHA_Msk) | + SERCOM_SPIS_CTRLA_CPHA_LEADING_EDGE; + } +} + +/*Set the SPI Clock Phase Trailing Edge*/ +static void spi_cpha_trail_edge(const struct mchp_spi_reg_config *spi_reg_cfg, spi_operation_t op) +{ + /* Clear the CPHA bit field and set clock phase to Trailing Edge */ + if (SPI_OP_MODE_GET(op) == SPI_OP_MODE_MASTER) { + spi_reg_cfg->regs->SPIM.SERCOM_CTRLA = + (spi_reg_cfg->regs->SPIM.SERCOM_CTRLA & ~SERCOM_SPIM_CTRLA_CPHA_Msk) | + SERCOM_SPIM_CTRLA_CPHA_TRAILING_EDGE; + } else { + spi_reg_cfg->regs->SPIS.SERCOM_CTRLA = + (spi_reg_cfg->regs->SPIS.SERCOM_CTRLA & ~SERCOM_SPIS_CTRLA_CPHA_Msk) | + SERCOM_SPIS_CTRLA_CPHA_TRAILING_EDGE; + } +} + +/*Set the SPI Half Duplex Mode*/ +static inline int spi_half_duplex_mode(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + LOG_ERR("SPI half-duplex mode is not supported"); + + return -ENOTSUP; +} + +/*Set the SPI Full Duplex Mode. Since the device is full duplex mode by default this API returns + *success + */ +static inline int spi_full_duplex_mode(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + return 0; +} + +/*Set the pads for the SPI Transmission*/ +static inline void spi_slave_config_pinout(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + /* Clear the DIPO and DOPO bit fields and apply the new pad configuration */ + spi_reg_cfg->regs->SPIS.SERCOM_CTRLA = + (spi_reg_cfg->regs->SPIS.SERCOM_CTRLA & + ~(SERCOM_SPIS_CTRLA_DIPO_Msk | SERCOM_SPIS_CTRLA_DOPO_Msk)) | + spi_reg_cfg->pads; +} + +/*Set the pads for the SPI Transmission*/ +static inline void spi_master_config_pinout(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + /* Clear the DIPO and DOPO bit fields and apply the new pad configuration */ + spi_reg_cfg->regs->SPIM.SERCOM_CTRLA = + (spi_reg_cfg->regs->SPIM.SERCOM_CTRLA & + ~(SERCOM_SPIM_CTRLA_DIPO_Msk | SERCOM_SPIM_CTRLA_DOPO_Msk)) | + spi_reg_cfg->pads; +} + +/*Set the pads for the SPI Transmission for loopback mode*/ +static inline void spi_mode_loopback(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + /* Clear the DIPO and DOPO bit fields and set them to PAD0 */ + spi_reg_cfg->regs->SPIM.SERCOM_CTRLA = + (spi_reg_cfg->regs->SPIM.SERCOM_CTRLA & + ~(SERCOM_SPIM_CTRLA_DIPO_Msk | SERCOM_SPIM_CTRLA_DOPO_Msk)) | + (SERCOM_SPIM_CTRLA_DIPO_PAD0 | SERCOM_SPIM_CTRLA_DOPO_PAD0); +} + +/*Enable the Receiver in SPI peripheral*/ +static void spi_rx_enable(const struct mchp_spi_reg_config *spi_reg_cfg, spi_operation_t op) +{ + if (SPI_OP_MODE_GET(op) == SPI_OP_MODE_MASTER) { + spi_wait_sync(spi_reg_cfg, SERCOM_SPIM_SYNCBUSY_CTRLB_Msk); + /* Clear the RXEN bit field and enable Receiver */ + spi_reg_cfg->regs->SPIM.SERCOM_CTRLB = + (spi_reg_cfg->regs->SPIM.SERCOM_CTRLB & ~SERCOM_SPIM_CTRLB_RXEN_Msk) | + SERCOM_SPIM_CTRLB_RXEN_Msk; + spi_wait_sync(spi_reg_cfg, SERCOM_SPIM_SYNCBUSY_CTRLB_Msk); + } else { + spi_wait_sync(spi_reg_cfg, SERCOM_SPIS_SYNCBUSY_CTRLB_Msk); + /* Clear the RXEN bit field and enable Receiver */ + spi_reg_cfg->regs->SPIS.SERCOM_CTRLB = + (spi_reg_cfg->regs->SPIS.SERCOM_CTRLB & ~SERCOM_SPIS_CTRLB_RXEN_Msk) | + SERCOM_SPIS_CTRLB_RXEN_Msk; + spi_wait_sync(spi_reg_cfg, SERCOM_SPIS_SYNCBUSY_CTRLB_Msk); + } +} + +/*Set the 8 BIT Character Size in SPI peripheral*/ +static void spi_8bit_ch_size(const struct mchp_spi_reg_config *spi_reg_cfg, spi_operation_t op) +{ + if (SPI_OP_MODE_GET(op) == SPI_OP_MODE_MASTER) { + /* Clear the CHSIZE bit field and set character size to 8-bit */ + spi_reg_cfg->regs->SPIM.SERCOM_CTRLB = + (spi_reg_cfg->regs->SPIM.SERCOM_CTRLB & ~SERCOM_SPIM_CTRLB_CHSIZE_Msk) | + SERCOM_SPIM_CTRLB_CHSIZE_8_BIT; + } else { + /* Clear the CHSIZE bit field and set character size to 8-bit */ + spi_reg_cfg->regs->SPIS.SERCOM_CTRLB = + (spi_reg_cfg->regs->SPIS.SERCOM_CTRLB & ~SERCOM_SPIS_CTRLB_CHSIZE_Msk) | + SERCOM_SPIS_CTRLB_CHSIZE_8_BIT; + } +} + +/*Set the BAUD Rate value for SPI peripheral*/ +static void spi_set_baudrate(const struct mchp_spi_reg_config *spi_reg_cfg, + const struct spi_config *config, uint32_t clk_freq_hz) +{ + uint32_t divisor = 2U * config->frequency; + + /* Use the requested or next highest possible frequency */ + uint32_t baud_value = (clk_freq_hz / divisor) - 1; + + if ((clk_freq_hz % divisor) >= (divisor / 2U)) { + /* Round up the baud_value to ensures SPI clock is as close as possible to + * the requested frequency + */ + baud_value += 1U; + } + + baud_value = CLAMP(baud_value, 0, UINT8_MAX); + + if (SPI_OP_MODE_GET(config->operation) == SPI_OP_MODE_MASTER) { + spi_reg_cfg->regs->SPIM.SERCOM_BAUD = baud_value; + } else { + spi_reg_cfg->regs->SPIS.SERCOM_BAUD = baud_value; + } +} + +/*Set the Inter character dpacing*/ +static inline void spi_set_icspace(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + spi_reg_cfg->regs->SPIM.SERCOM_CTRLC |= + SERCOM_SPIM_CTRLC_ICSPACE(CONFIG_SPI_MCHP_INTER_CHARACTER_SPACE); +} + +/*Write Data into DATA register*/ +static inline void spi_write_data(const struct mchp_spi_reg_config *spi_reg_cfg, uint8_t data) +{ + spi_reg_cfg->regs->SPIM.SERCOM_DATA = data; +} + +/*Read Data from the SPI MASTER DATA register*/ +static inline uint8_t spi_read_data(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + return (uint8_t)spi_reg_cfg->regs->SPIM.SERCOM_DATA; +} + +/*Read Data from the SPI SLAVE DATA register*/ +static inline uint8_t spi_slave_read_data(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + return (uint8_t)spi_reg_cfg->regs->SPIS.SERCOM_DATA; +} + +/*Return true if receive complete flag is set*/ +static inline bool spi_is_rx_comp(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + return (spi_reg_cfg->regs->SPIM.SERCOM_INTFLAG & SERCOM_SPIM_INTFLAG_RXC_Msk) == + SERCOM_SPIM_INTFLAG_RXC_Msk; +} + +/*Return true if transmit complete flag is set*/ +static inline bool spi_is_tx_comp(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + return ((spi_reg_cfg->regs->SPIM.SERCOM_INTFLAG & SERCOM_SPIM_INTFLAG_TXC_Msk) == + SERCOM_SPIM_INTFLAG_TXC_Msk); +} + +/*Clear the DATA register*/ +static inline void spi_clr_data(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + /*Clear the DATA register until the RXC flag is cleared*/ + if (WAIT_FOR(((spi_reg_cfg->regs->SPIM.SERCOM_INTFLAG & SERCOM_SPIM_INTFLAG_RXC_Msk) == 0), + TIMEOUT_VALUE_US, + ((void)spi_reg_cfg->regs->SPIM.SERCOM_DATA, k_busy_wait(DELAY_US))) == false) { + LOG_ERR("Timeout while clearing RXC"); + } +} + +/*Return true if data register empty flag is set*/ +static inline bool spi_is_data_empty(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + return (spi_reg_cfg->regs->SPIM.SERCOM_INTFLAG & SERCOM_SPIM_INTFLAG_DRE_Msk) == + SERCOM_SPIM_INTFLAG_DRE_Msk; +} + +#if defined(CONFIG_SPI_MCHP_INTERRUPT_DRIVEN) || (CONFIG_SPI_MCHP_INTERRUPT_DRIVEN_ASYNC) +/*Enable the Receive Complete Interrupt*/ +static void spi_enable_rxc_interrupt(const struct mchp_spi_reg_config *spi_reg_cfg, + spi_operation_t op) +{ + if (SPI_OP_MODE_GET(op) == SPI_OP_MODE_MASTER) { + spi_reg_cfg->regs->SPIM.SERCOM_INTENSET = SERCOM_SPIM_INTENSET_RXC_Msk; + } else { + spi_reg_cfg->regs->SPIS.SERCOM_INTENSET = SERCOM_SPIS_INTENSET_RXC_Msk; + } +} +#endif /* CONFIG_SPI_MCHP_INTERRUPT_DRIVEN || CONFIG_SPI_MCHP_INTERRUPT_DRIVEN_ASYNC */ + +/*Enable the Transmit Complete Interrupt*/ +static inline void spi_enable_txc_interrupt(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + spi_reg_cfg->regs->SPIM.SERCOM_INTENSET = SERCOM_SPIM_INTENSET_TXC_Msk; +} + +/*Enable the Data Register Empty Interrupt*/ +static inline void spi_enable_data_empty_interrupt(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + spi_reg_cfg->regs->SPIM.SERCOM_INTENSET = SERCOM_SPIM_INTENSET_DRE_Msk; +} + +/*Disable the Receive Complete Interrupt*/ +static inline void spi_disable_rxc_interrupt(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + spi_reg_cfg->regs->SPIM.SERCOM_INTENCLR = SERCOM_SPIM_INTENCLR_RXC_Msk; +} + +/*Disable the Transmit Complete Interrupt*/ +static inline void spi_disable_txc_interrupt(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + spi_reg_cfg->regs->SPIM.SERCOM_INTENCLR = SERCOM_SPIM_INTENCLR_TXC_Msk; +} + +/*Disable the Data Register Empty Interrupt*/ +static inline void spi_disable_data_empty_interrupt(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + spi_reg_cfg->regs->SPIM.SERCOM_INTENCLR = SERCOM_SPIM_INTENCLR_DRE_Msk; +} + +/* Enable the preload slave data*/ +static inline void spi_slave_preload_enable(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + spi_reg_cfg->regs->SPIS.SERCOM_CTRLB = + (spi_reg_cfg->regs->SPIS.SERCOM_CTRLB & ~SERCOM_SPIS_CTRLB_PLOADEN_Msk) | + SERCOM_SPIS_CTRLB_PLOADEN_Msk; +} + +/* Enable the slave select detection*/ +static inline void spi_slave_select_low_enable(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + spi_reg_cfg->regs->SPIS.SERCOM_CTRLB = + (spi_reg_cfg->regs->SPIS.SERCOM_CTRLB & ~SERCOM_SPIS_CTRLB_SSDE_Msk) | + SERCOM_SPIS_CTRLB_SSDE_Msk; +} + +/* Enable the Immediate buffer overflow*/ +static inline void spi_immediate_buf_overflow(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + spi_reg_cfg->regs->SPIS.SERCOM_CTRLA = + (spi_reg_cfg->regs->SPIS.SERCOM_CTRLA & ~SERCOM_SPIS_CTRLA_IBON_Msk) | + SERCOM_SPIS_CTRLA_IBON_Msk; +} + +/* Enable slave select line interrupt */ +static inline void spi_slave_select_line_enable(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + spi_reg_cfg->regs->SPIS.SERCOM_INTENSET = + (spi_reg_cfg->regs->SPIS.SERCOM_INTENSET & ~SERCOM_SPIS_INTENSET_SSL_Msk) | + SERCOM_SPIS_INTENSET_SSL_Msk; +} + +/* Return the slave select line status*/ +static inline bool spi_slave_select_line(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + return ((spi_reg_cfg->regs->SPIS.SERCOM_INTFLAG & SERCOM_SPIS_INTFLAG_SSL_Msk) == + SERCOM_SPIS_INTFLAG_SSL_Msk); +} + +/* Clear the slave select line interrupt */ +static inline void spi_slave_clr_slave_select_line(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + spi_reg_cfg->regs->SPIS.SERCOM_INTFLAG = SERCOM_SPIS_INTFLAG_SSL_Msk; +} + +/* Clear buffer overflow flag */ +static inline void spi_slave_clr_buf_overflow(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + spi_reg_cfg->regs->SPIS.SERCOM_STATUS = SERCOM_SPIS_STATUS_BUFOVF_Msk; +} + +/* Set the Hardware slave select*/ +static void spi_slave_select_enable(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + spi_wait_sync(spi_reg_cfg, SERCOM_SPIM_SYNCBUSY_CTRLB_Msk); + + /* Clear the MSSEN bit field and enable Master Slave Select */ + spi_reg_cfg->regs->SPIM.SERCOM_CTRLB = + (spi_reg_cfg->regs->SPIM.SERCOM_CTRLB & ~SERCOM_SPIM_CTRLB_MSSEN_Msk) | + SERCOM_SPIM_CTRLB_MSSEN_Msk; + spi_wait_sync(spi_reg_cfg, SERCOM_SPIM_SYNCBUSY_CTRLB_Msk); +} + +/* Enable the Transmit Complete Interrupt */ +static inline void spi_slave_enable_txc_interrupt(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + spi_reg_cfg->regs->SPIS.SERCOM_INTENSET = SERCOM_SPIS_INTENSET_TXC_Msk; +} + +/* Clear the DATA register */ +static inline void spi_slave_clr_data(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + if (WAIT_FOR(((spi_reg_cfg->regs->SPIS.SERCOM_INTFLAG & SERCOM_SPIS_INTFLAG_RXC_Msk) == 0), + TIMEOUT_VALUE_US, + ((void)spi_reg_cfg->regs->SPIM.SERCOM_DATA, k_busy_wait(DELAY_US))) == false) { + LOG_ERR("Timeout while clearing RXC"); + } +} + +/*Clear the Error Interrupt Flag */ +static inline void spi_slave_clr_error_int_flag(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + spi_reg_cfg->regs->SPIS.SERCOM_INTFLAG = (uint8_t)SERCOM_SPIS_INTFLAG_ERROR_Msk; +} + +/*Return true if receive complete flag is set*/ +static inline bool spi_slave_is_rx_comp(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + return (spi_reg_cfg->regs->SPIS.SERCOM_INTFLAG & SERCOM_SPIS_INTFLAG_RXC_Msk) == + SERCOM_SPIS_INTFLAG_RXC_Msk; +} + +/*Return true if data register empty flag is set*/ +static inline bool spi_slave_is_data_empty(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + return (spi_reg_cfg->regs->SPIS.SERCOM_INTFLAG & SERCOM_SPIS_INTFLAG_DRE_Msk) == + SERCOM_SPIS_INTFLAG_DRE_Msk; +} + +/*Return true if transmit complete flag is set*/ +static inline bool spi_slave_is_tx_comp(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + return ((spi_reg_cfg->regs->SPIS.SERCOM_INTFLAG & SERCOM_SPIS_INTFLAG_TXC_Msk) == + SERCOM_SPIS_INTFLAG_TXC_Msk); +} + +/*Write Data into DATA register*/ +static inline void spi_slave_write_data(const struct mchp_spi_reg_config *spi_reg_cfg, uint8_t data) +{ + spi_reg_cfg->regs->SPIS.SERCOM_DATA = data; +} + +/*Disable DRE interrupt*/ +static inline void spi_slave_disable_dre_int(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + spi_reg_cfg->regs->SPIS.SERCOM_INTENCLR = (uint8_t)SERCOM_SPIS_INTENCLR_DRE_Msk; +} + +/*Clear transmit complete flag is set*/ +static inline void spi_slave_clr_tx_comp_flag(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + spi_reg_cfg->regs->SPIS.SERCOM_INTFLAG = SERCOM_SPIS_INTFLAG_TXC_Msk; +} + +/*Disable all SPI Interrupt*/ +static inline void spi_slave_disable_interrupts(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + spi_reg_cfg->regs->SPIS.SERCOM_INTENCLR = SERCOM_SPIS_INTENCLR_Msk; +} + +/*Clear all SPI Interrupt*/ +static inline void spi_slave_clr_interrupts(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + spi_reg_cfg->regs->SPIS.SERCOM_INTFLAG = SERCOM_SPIS_INTFLAG_Msk; +} + +/*Enable the Data Register Empty Interrupt*/ +static inline void +spi_slave_enable_data_empty_interrupt(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + spi_reg_cfg->regs->SPIS.SERCOM_INTENSET = SERCOM_SPIS_INTENSET_DRE_Msk; +} + +static int spi_configure_pinout(const struct mchp_spi_reg_config *spi_reg_cfg, + const struct spi_config *config) +{ + if ((config->operation & SPI_MODE_LOOP) != 0U) { + if (SPI_OP_MODE_GET(config->operation) == SPI_OP_MODE_SLAVE) { + LOG_ERR("For slave Loopback mode is not supported"); + + return -ENOTSUP; + } + spi_mode_loopback(spi_reg_cfg); + } else { + if (SPI_OP_MODE_GET(config->operation) != SPI_OP_MODE_MASTER) { + spi_slave_config_pinout(spi_reg_cfg); + } else { + spi_master_config_pinout(spi_reg_cfg); + } + } + + return 0; +} + +static void spi_configure_cpol(const struct mchp_spi_reg_config *spi_reg_cfg, + const struct spi_config *config) +{ + if ((config->operation & SPI_MODE_CPOL) != 0U) { + spi_cpol_idle_high(spi_reg_cfg, config->operation); + } else { + spi_cpol_idle_low(spi_reg_cfg, config->operation); + } +} + +static void spi_configure_cpha(const struct mchp_spi_reg_config *spi_reg_cfg, + const struct spi_config *config) +{ + if ((config->operation & SPI_MODE_CPHA) != 0U) { + spi_cpha_trail_edge(spi_reg_cfg, config->operation); + } else { + spi_cpha_lead_edge(spi_reg_cfg, config->operation); + } +} + +static void spi_configure_bit_order(const struct mchp_spi_reg_config *spi_reg_cfg, + const struct spi_config *config) +{ + if ((config->operation & SPI_TRANSFER_LSB) != 0U) { + spi_lsb_first(spi_reg_cfg, config->operation); + } else { + spi_msb_first(spi_reg_cfg, config->operation); + } +} + +static int spi_mchp_configure(const struct device *dev, const struct spi_config *config) +{ + const struct spi_mchp_dev_config *cfg = dev->config; + const struct mchp_spi_reg_config *spi_reg_cfg = &cfg->reg_cfg; + struct spi_mchp_dev_data *const data = dev->data; + int retval; + uint32_t clock_rate; + bool has_cs = false; + + spi_disable(spi_reg_cfg); + + if (spi_context_configured(&data->ctx, config) == true) { + spi_enable(spi_reg_cfg, config->operation); + + return 0; + } + + /* Select the Character Size */ + if (SPI_WORD_SIZE_GET(config->operation) != SUPPORTED_SPI_WORD_SIZE) { + LOG_ERR("Unsupported SPI word size: %d bits. Only 8-bit transfers are supported.", + SPI_WORD_SIZE_GET(config->operation)); + + return -ENOTSUP; + } + spi_8bit_ch_size(spi_reg_cfg, config->operation); + + spi_rx_enable(spi_reg_cfg, config->operation); + +#if CONFIG_SPI_SLAVE + if (SPI_OP_MODE_GET(config->operation) == SPI_OP_MODE_SLAVE) { + + spi_slave_preload_enable(spi_reg_cfg); + + spi_slave_select_low_enable(spi_reg_cfg); + + spi_immediate_buf_overflow(spi_reg_cfg); + + spi_slave_mode(spi_reg_cfg); + } +#endif /* CONFIG_SPI_SLAVE */ + + if (SPI_OP_MODE_GET(config->operation) == SPI_OP_MODE_MASTER) { + + spi_set_icspace(spi_reg_cfg); + + clock_control_get_rate(cfg->spi_clock.clock_dev, cfg->spi_clock.gclk_sys, + &clock_rate); + + if ((config->frequency != 0) && (clock_rate >= (2 * config->frequency))) { + spi_set_baudrate(spi_reg_cfg, config, clock_rate); + } else { + return -ENOTSUP; + } + + spi_master_mode(spi_reg_cfg); + +#if !DT_SPI_CTX_HAS_NO_CS_GPIOS + has_cs = (data->ctx.num_cs_gpios != 0); +#endif + + if (has_cs) { + retval = spi_context_cs_configure_all(&data->ctx); + if (retval < 0) { + return retval; + } + } else if (cfg->pcfg->states->pin_cnt == SPI_PIN_CNT) { + spi_slave_select_enable(spi_reg_cfg); + } else { + /* Handled by user */ + } + } + + if ((config->operation & SPI_LINES_MASK) != SPI_LINES_SINGLE) { + LOG_ERR("Only single line mode is supported"); + + return -ENOTSUP; + } + + /*Set the Data out and Pin out Configuration*/ + retval = spi_configure_pinout(spi_reg_cfg, config); + if (retval < 0) { + return retval; + } + + spi_configure_cpol(spi_reg_cfg, config); + spi_configure_cpha(spi_reg_cfg, config); + spi_configure_bit_order(spi_reg_cfg, config); + + if ((config->operation & SPI_HALF_DUPLEX) != 0U) { + retval = spi_half_duplex_mode(spi_reg_cfg); + if (retval != 0) { + return retval; + } + } else { + retval = spi_full_duplex_mode(spi_reg_cfg); + if (retval != 0) { + return -ENOTSUP; + } + } + + spi_enable(spi_reg_cfg, config->operation); + +#if defined(CONFIG_SPI_ASYNC) || defined(CONFIG_SPI_MCHP_INTERRUPT_DRIVEN) + cfg->irq_config_func(dev); +#endif /* CONFIG_SPI_ASYNC || CONFIG_SPI_MCHP_INTERRUPT_DRIVEN */ + +#if CONFIG_SPI_MCHP_DMA_DRIVEN_ASYNC + if (device_is_ready(cfg->spi_dma.dma_dev) != true) { + return -ENODEV; + } + data->dev = dev; +#endif /* CONFIG_SPI_MCHP_DMA_DRIVEN_ASYNC */ + + data->ctx.config = config; + + return 0; +} + +static int spi_mchp_check_buf_len(const struct spi_buf_set *buf_set) +{ + if ((buf_set == NULL) || (buf_set->buffers == NULL)) { + return 0; + } + + for (size_t i = 0; i < buf_set->count; i++) { + if (buf_set->buffers[i].len > SPI_MCHP_MAX_XFER_SIZE) { + LOG_ERR("SPI buffer length (%u) exceeds max allowed (%u)", + buf_set->buffers[i].len, SPI_MCHP_MAX_XFER_SIZE); + + return -EINVAL; + } + } + + return 0; +} + +#ifndef CONFIG_SPI_MCHP_INTERRUPT_DRIVEN +static bool spi_mchp_transfer_in_progress(struct spi_mchp_dev_data *data) +{ + return spi_context_tx_on(&data->ctx) || spi_context_rx_on(&data->ctx); +} + +static int spi_mchp_finish(const struct mchp_spi_reg_config *spi_reg_cfg) +{ + /* Wait until transmit complete */ + if (WAIT_FOR((spi_is_tx_comp(spi_reg_cfg) == true), TIMEOUT_VALUE_US, + k_busy_wait(DELAY_US)) == false) { + + LOG_ERR("SPI TX complete timeout"); + + return -ETIMEDOUT; + } + spi_clr_data(spi_reg_cfg); + + return 0; +} + +static int spi_mchp_poll_in(const struct mchp_spi_reg_config *spi_reg_cfg, + struct spi_mchp_dev_data *data) +{ + uint8_t tx_data; + uint8_t rx_data; + + /* Check if there is data to transmit */ + if (spi_context_tx_buf_on(&data->ctx) == true) { + tx_data = *data->ctx.tx_buf; + } else { + tx_data = 0U; + } + + /* wait until the SPI data is empty */ + if (WAIT_FOR((spi_is_data_empty(spi_reg_cfg) == true), TIMEOUT_VALUE_US, + k_busy_wait(DELAY_US)) == false) { + LOG_ERR("SPI data empty timeout"); + + return -ETIMEDOUT; + } + + spi_write_data(spi_reg_cfg, tx_data); + + spi_context_update_tx(&data->ctx, 1, 1); + + /* Wait for the reception to complete */ + while (spi_is_rx_comp(spi_reg_cfg) != true) { + /* Wait for completion */ + }; + + rx_data = spi_read_data(spi_reg_cfg); + + /* Check if there is a buffer to store received data */ + if (spi_context_rx_buf_on(&data->ctx) == true) { + *data->ctx.rx_buf = rx_data; + } + + spi_context_update_rx(&data->ctx, 1, 1); + + return 0; +} + +static int spi_mchp_fast_tx(const struct mchp_spi_reg_config *spi_reg_cfg, + const struct spi_buf *tx_buf) +{ + const uint8_t *tx_data_ptr = tx_buf->buf; + uint8_t tx_data; + size_t len = tx_buf->len; + uint8_t dummy_data = 0U; + int retval; + + /* Transmit each byte in the buffer */ + while (len != 0) { + if (tx_buf->buf != NULL) { + tx_data = *tx_data_ptr++; + } else { + tx_data = dummy_data; + } + + /* Wait until the tramist is complete */ + if (WAIT_FOR((spi_is_data_empty(spi_reg_cfg) == true), TIMEOUT_VALUE_US, + k_busy_wait(DELAY_US)) == false) { + LOG_ERR("SPI data empty timeout"); + + return -ETIMEDOUT; + } + + spi_write_data(spi_reg_cfg, tx_data); + len--; + } + + retval = spi_mchp_finish(spi_reg_cfg); + + return retval; +} + +static int spi_mchp_fast_rx(const struct mchp_spi_reg_config *spi_reg_cfg, + const struct spi_buf *rx_buf) +{ + uint8_t *rx_data_ptr = rx_buf->buf; + size_t len = rx_buf->len; + uint8_t dummy_data = 0U; + int retval; + + if (len == 0) { + return -EINVAL; + } + + while (len != 0) { + + /* Write a dummy data to receive data */ + spi_write_data(spi_reg_cfg, dummy_data); + len--; + + /* Wait for completion, and read */ + while (spi_is_rx_comp(spi_reg_cfg) != true) { + /* Wait for completion */ + }; + + if (rx_buf->buf != NULL) { + *rx_data_ptr = spi_read_data(spi_reg_cfg); + rx_data_ptr++; + } else { + (void)spi_read_data(spi_reg_cfg); + } + } + + retval = spi_mchp_finish(spi_reg_cfg); + + return retval; +} + +static int spi_mchp_fast_txrx(const struct mchp_spi_reg_config *spi_reg_cfg, + const struct spi_buf *tx_buf, const struct spi_buf *rx_buf) +{ + const uint8_t *tx_data_ptr = tx_buf->buf; + uint8_t *rx_data_ptr = rx_buf->buf; + size_t len = rx_buf->len; + uint8_t dummy_data = 0U; + int retval; + + if (len == 0) { + return -EINVAL; + } + + while (len > 0) { + /* Send the next byte */ + if (tx_data_ptr != NULL) { + spi_write_data(spi_reg_cfg, *tx_data_ptr); + tx_data_ptr++; + } else { + spi_write_data(spi_reg_cfg, dummy_data); + } + + /* Wait for completion */ + while (spi_is_rx_comp(spi_reg_cfg) != true) { + /* Wait for completion */ + }; + + /* Read received data */ + if (rx_data_ptr != NULL) { + *rx_data_ptr = spi_read_data(spi_reg_cfg); + rx_data_ptr++; + } else { + (void)spi_read_data(spi_reg_cfg); + } + len--; + } + + retval = spi_mchp_finish(spi_reg_cfg); + + return retval; +} + +static int spi_mchp_fast_transceive(const struct device *dev, const struct spi_config *config, + const struct spi_buf_set *tx_bufs, + const struct spi_buf_set *rx_bufs) +{ + const struct spi_mchp_dev_config *cfg = dev->config; + const struct mchp_spi_reg_config *spi_reg_cfg = &cfg->reg_cfg; + size_t tx_count = 0; + size_t rx_count = 0; + const struct spi_buf *tx_data_ptr = NULL; + const struct spi_buf *rx_data_ptr = NULL; + int retval; + + if (tx_bufs != NULL) { + tx_data_ptr = tx_bufs->buffers; + tx_count = tx_bufs->count; + } + + if (rx_bufs != NULL) { + rx_data_ptr = rx_bufs->buffers; + rx_count = rx_bufs->count; + } else { + rx_data_ptr = NULL; + } + + while ((tx_count != 0) && (rx_count != 0)) { + /* This function is called only if the count is equal*/ + retval = spi_mchp_fast_txrx(spi_reg_cfg, tx_data_ptr, rx_data_ptr); + + tx_data_ptr++; + tx_count--; + rx_data_ptr++; + rx_count--; + } + + /* Handle remaining transmit buffers */ + while (tx_count > 0) { + retval = spi_mchp_fast_tx(spi_reg_cfg, tx_data_ptr); + tx_data_ptr++; + tx_count--; + } + + /* Handle remaining receive buffers */ + while (rx_count > 0) { + retval = spi_mchp_fast_rx(spi_reg_cfg, rx_data_ptr); + rx_data_ptr++; + rx_count--; + } + + return retval; +} + +static bool spi_mchp_is_same_len(const struct spi_buf_set *tx_bufs, + const struct spi_buf_set *rx_bufs) +{ + const struct spi_buf *tx_data_ptr = NULL; + const struct spi_buf *rx_data_ptr = NULL; + size_t tx_count = 0; + size_t rx_count = 0; + + if (tx_bufs != NULL) { + tx_data_ptr = tx_bufs->buffers; + tx_count = tx_bufs->count; + } + + if (rx_bufs != NULL) { + rx_data_ptr = rx_bufs->buffers; + rx_count = rx_bufs->count; + } + + while (tx_count != 0 && rx_count != 0) { + /* Compare the length of each corresponding TX and RX buffer */ + if (tx_data_ptr->len != rx_data_ptr->len) { + return false; + } + + tx_data_ptr++; + tx_count--; + rx_data_ptr++; + rx_count--; + } + + return true; +} +#endif /* CONFIG_SPI_MCHP_INTERRUPT_DRIVEN*/ + +#if defined(CONFIG_SPI_MCHP_INTERRUPT_DRIVEN) || (CONFIG_SPI_MCHP_INTERRUPT_DRIVEN_ASYNC) +static int spi_mchp_transceive_interrupt(const struct device *dev, const struct spi_config *config, + const struct spi_buf_set *tx_bufs, + const struct spi_buf_set *rx_bufs) +{ + const struct spi_mchp_dev_config *cfg = dev->config; + const struct mchp_spi_reg_config *spi_reg_cfg = &cfg->reg_cfg; + struct spi_mchp_dev_data *const data = dev->data; + uint8_t tx_data; + + /* Setup SPI buffers */ + spi_context_buffers_setup(&data->ctx, tx_bufs, rx_bufs, 1); + + /* Prepare first byte for transmission */ + if (spi_context_tx_buf_on(&data->ctx) == true) { + tx_data = *data->ctx.tx_buf; + } else { + tx_data = 0U; + } + + spi_clr_data(spi_reg_cfg); + + /* Get the dummysize */ + if ((data->ctx.rx_len) > (data->ctx.tx_len)) { + data->dummysize = (data->ctx.rx_len) - (data->ctx.tx_len); + } + + /* Write first data byte to the SPI data register */ + spi_context_update_tx(&data->ctx, 1, 1); + spi_write_data(spi_reg_cfg, tx_data); + + /* Enable SPI interrupts for RX, TX completion, and data empty events */ + if (data->ctx.rx_len > 0) { + spi_enable_rxc_interrupt(spi_reg_cfg, config->operation); + } else { + spi_enable_data_empty_interrupt(spi_reg_cfg); + } + +#if defined(CONFIG_SPI_MCHP_INTERRUPT_DRIVEN) + spi_context_wait_for_completion(&data->ctx); +#endif /* CONFIG_SPI_MCHP_INTERRUPT_DRIVEN */ + + return 0; +} + +#if CONFIG_SPI_SLAVE +static void spi_mchp_slave_write(const struct device *dev) +{ + const struct spi_mchp_dev_config *cfg = dev->config; + const struct mchp_spi_reg_config *spi_reg_cfg = &cfg->reg_cfg; + uint8_t tx_data; + uint8_t dummy_data = 0U; + struct spi_mchp_dev_data *const data = dev->data; + bool write_ready; + + /* Prepare initial bytes for transmission */ + if (spi_context_tx_buf_on(&data->ctx) == true) { + write_ready = spi_context_tx_buf_on(&data->ctx); + write_ready = write_ready && (spi_slave_is_data_empty(spi_reg_cfg) == true); + while (write_ready == true) { + tx_data = *data->ctx.tx_buf; + spi_slave_write_data(spi_reg_cfg, tx_data); + + /* Write data byte to the SPI data register */ + spi_context_update_tx(&data->ctx, 1, 1); + write_ready = spi_context_tx_buf_on(&data->ctx); + write_ready = write_ready && (spi_slave_is_data_empty(spi_reg_cfg) == true); + } + } else { + write_ready = (spi_slave_is_data_empty(spi_reg_cfg)); + while (write_ready == true) { + tx_data = dummy_data; + spi_slave_write_data(spi_reg_cfg, tx_data); + write_ready = (spi_slave_is_data_empty(spi_reg_cfg)); + } + } + spi_slave_enable_data_empty_interrupt(spi_reg_cfg); +} + +static int spi_mchp_slave_transceive_interrupt(const struct device *dev, + const struct spi_config *config, + const struct spi_buf_set *tx_bufs, + const struct spi_buf_set *rx_bufs) +{ + const struct spi_mchp_dev_config *cfg = dev->config; + const struct mchp_spi_reg_config *spi_reg_cfg = &cfg->reg_cfg; + struct spi_mchp_dev_data *const data = dev->data; + int ret = 0; + + spi_context_buffers_setup(&data->ctx, tx_bufs, rx_bufs, 1); + + if (spi_context_tx_on(&data->ctx) == true) { + /* Prepare for transmission */ + spi_mchp_slave_write(dev); + } + + spi_enable_rxc_interrupt(spi_reg_cfg, config->operation); + + spi_slave_select_line_enable(spi_reg_cfg); + +#if defined(CONFIG_SPI_MCHP_INTERRUPT_DRIVEN) + ret = spi_context_wait_for_completion(&data->ctx); +#endif /* CONFIG_SPI_MCHP_INTERRUPT_DRIVEN */ + + return ret; +} + +#endif /* CONFIG_SPI_SLAVE */ +#endif /* CONFIG_SPI_MCHP_INTERRUPT_DRIVEN || (CONFIG_SPI_MCHP_INTERRUPT_DRIVEN_ASYNC */ + +static int spi_mchp_transceive_sync(const struct device *dev, const struct spi_config *config, + const struct spi_buf_set *tx_bufs, + const struct spi_buf_set *rx_bufs) +{ + const struct spi_mchp_dev_config *cfg = dev->config; + const struct mchp_spi_reg_config *spi_reg_cfg = &cfg->reg_cfg; + struct spi_mchp_dev_data *data = dev->data; + int ret; + + ret = spi_mchp_check_buf_len(tx_bufs); + if (ret < 0) { + return ret; + } + + ret = spi_mchp_check_buf_len(rx_bufs); + if (ret < 0) { + return ret; + } + + ARG_UNUSED(spi_reg_cfg); + + spi_context_lock(&data->ctx, false, NULL, NULL, config); + + ret = spi_mchp_configure(dev, config); + if (ret != 0) { + spi_context_release(&data->ctx, ret); + + return ret; + } + + if (SPI_OP_MODE_GET(config->operation) == SPI_OP_MODE_MASTER) { + spi_context_cs_control(&data->ctx, true); + } + +#if CONFIG_SPI_MCHP_INTERRUPT_DRIVEN +#if CONFIG_SPI_SLAVE + if (SPI_OP_MODE_GET(config->operation) == SPI_OP_MODE_SLAVE) { + ret = spi_mchp_slave_transceive_interrupt(dev, config, tx_bufs, rx_bufs); + } +#endif /* CONFIG_SPI_SLAVE */ + if (SPI_OP_MODE_GET(config->operation) == SPI_OP_MODE_MASTER) { + ret = spi_mchp_transceive_interrupt(dev, config, tx_bufs, rx_bufs); + } +#else + /* Use optimized fast path if TX and RX buffer lengths match */ + if (SPI_OP_MODE_GET(config->operation) == SPI_OP_MODE_MASTER) { + if (spi_mchp_is_same_len(tx_bufs, rx_bufs) == true) { + spi_mchp_fast_transceive(dev, config, tx_bufs, rx_bufs); + } else { + /* Setup SPI buffers and process using polling */ + spi_context_buffers_setup(&data->ctx, tx_bufs, rx_bufs, 1); + + do { + ret = spi_mchp_poll_in(spi_reg_cfg, data); + } while (spi_mchp_transfer_in_progress(data) && ret == 0); + } + } + +#if CONFIG_SPI_SLAVE + if (SPI_OP_MODE_GET(config->operation) == SPI_OP_MODE_SLAVE) { + spi_context_release(&data->ctx, ret); + + return -ENOTSUP; + } +#endif /* CONFIG_SPI_SLAVE */ +#endif /* CONFIG_SPI_MCHP_INTERRUPT_DRIVEN */ + + if (SPI_OP_MODE_GET(config->operation) == SPI_OP_MODE_MASTER) { + spi_context_cs_control(&data->ctx, false); + } + + spi_context_release(&data->ctx, ret); + + return ret; +} + +#if CONFIG_SPI_ASYNC +#if CONFIG_SPI_MCHP_DMA_DRIVEN_ASYNC +static void spi_mchp_dma_rx_done(const struct device *dma_dev, void *arg, uint32_t id, + int error_code); + +static int spi_mchp_dma_tx_load(const struct device *dev, const uint8_t *buf, size_t len) +{ + const struct spi_mchp_dev_config *cfg = dev->config; + const struct mchp_spi_reg_config *spi_reg_cfg = &cfg->reg_cfg; + + struct dma_config dma_cfg = {0}; + struct dma_block_config dma_blk = {0}; + int retval; + + dma_cfg.channel_direction = PERIPHERAL_TO_MEMORY; + dma_cfg.source_data_size = 1; + dma_cfg.dest_data_size = 1; + dma_cfg.block_count = 1; + dma_cfg.head_block = &dma_blk; + dma_cfg.dma_slot = cfg->spi_dma.tx_dma_request; + + dma_blk.block_size = len; + + if (buf != NULL) { + dma_blk.source_address = (uint32_t)buf; + } else { + static const uint8_t dummy_data; + + dma_blk.source_address = (uint32_t)&dummy_data; + dma_blk.source_addr_adj = DMA_ADDR_ADJ_NO_CHANGE; + } + + dma_blk.dest_address = (uint32_t)&spi_reg_cfg->regs->SPIM.SERCOM_DATA; + dma_blk.dest_addr_adj = DMA_ADDR_ADJ_NO_CHANGE; + + retval = dma_config(cfg->spi_dma.dma_dev, cfg->spi_dma.tx_dma_channel, &dma_cfg); + + if (retval != 0) { + return retval; + } + + retval = dma_start(cfg->spi_dma.dma_dev, cfg->spi_dma.tx_dma_channel); + + return retval; +} + +static int spi_mchp_dma_rx_load(const struct device *dev, uint8_t *buf, size_t len) +{ + const struct spi_mchp_dev_config *cfg = dev->config; + const struct mchp_spi_reg_config *spi_reg_cfg = &cfg->reg_cfg; + struct spi_mchp_dev_data *data = dev->data; + + struct dma_config dma_cfg = {0}; + struct dma_block_config dma_blk = {0}; + int retval; + + dma_cfg.channel_direction = PERIPHERAL_TO_MEMORY; + dma_cfg.source_data_size = 1; + dma_cfg.dest_data_size = 1; + dma_cfg.user_data = data; + dma_cfg.dma_callback = spi_mchp_dma_rx_done; + dma_cfg.block_count = 1; + dma_cfg.head_block = &dma_blk; + dma_cfg.dma_slot = cfg->spi_dma.rx_dma_request; + + dma_blk.block_size = len; + + if (buf != NULL) { + dma_blk.dest_address = (uint32_t)buf; + } else { + /* Use a static dummy variable if no buffer is provided */ + static uint8_t dummy_data; + + dma_blk.dest_address = (uint32_t)&dummy_data; + dma_blk.dest_addr_adj = DMA_ADDR_ADJ_NO_CHANGE; + } + + dma_blk.source_address = (uint32_t)&spi_reg_cfg->regs->SPIM.SERCOM_DATA; + dma_blk.source_addr_adj = DMA_ADDR_ADJ_NO_CHANGE; + + retval = dma_config(cfg->spi_dma.dma_dev, cfg->spi_dma.rx_dma_channel, &dma_cfg); + if (retval != 0) { + return retval; + } + + retval = dma_start(cfg->spi_dma.dma_dev, cfg->spi_dma.rx_dma_channel); + + return retval; +} + +static bool spi_mchp_dma_select_segment(const struct device *dev) +{ + struct spi_mchp_dev_data *data = dev->data; + uint32_t segment_len; + + /* Pick the shorter buffer of ones that have an actual length */ + if (data->ctx.rx_len != 0) { + segment_len = data->ctx.rx_len; + if (data->ctx.tx_len != 0) { + segment_len = MIN(segment_len, data->ctx.tx_len); + } + } else { + segment_len = data->ctx.tx_len; + } + + if (segment_len == 0) { + return false; + } + + /* Ensure the segment length does not exceed the max allowed value + */ + segment_len = MIN(segment_len, 65535); + + data->dma_segment_len = segment_len; + + return true; +} + +static int spi_mchp_dma_setup_buffers(const struct device *dev) +{ + struct spi_mchp_dev_data *data = dev->data; + int retval; + + if (data->dma_segment_len == 0) { + return -EINVAL; + } + + /* Load receive buffer first to prepare for incoming data */ + if (data->ctx.rx_len != 0U) { + retval = spi_mchp_dma_rx_load(dev, data->ctx.rx_buf, data->dma_segment_len); + } else { + retval = spi_mchp_dma_rx_load(dev, NULL, data->dma_segment_len); + } + + if (retval != 0) { + return retval; + } + + /* Load transmit buffer, which starts SPI bus clocking */ + if (data->ctx.tx_len != 0U) { + retval = spi_mchp_dma_tx_load(dev, data->ctx.tx_buf, data->dma_segment_len); + } else { + retval = spi_mchp_dma_tx_load(dev, NULL, data->dma_segment_len); + } + + if (retval != 0) { + return retval; + } + + return 0; +} + +static void spi_mchp_dma_rx_done(const struct device *dma_dev, void *arg, uint32_t id, + int error_code) +{ + struct spi_mchp_dev_data *data = arg; + const struct device *dev = data->dev; + const struct spi_mchp_dev_config *cfg = dev->config; + int retval; + + ARG_UNUSED(id); + ARG_UNUSED(error_code); + + /* Update TX and RX context with the completed DMA segment */ + spi_context_update_tx(&data->ctx, 1, data->dma_segment_len); + spi_context_update_rx(&data->ctx, 1, data->dma_segment_len); + + /* Check if more segments need to be transferred */ + if (spi_mchp_dma_select_segment(dev) == false) { + if (spi_context_is_slave(&data->ctx) == false) { + spi_context_cs_control(&data->ctx, false); + } + /* Transmission complete */ + spi_context_complete(&data->ctx, dev, 0); + + return; + } + + /* Load the next DMA segment */ + retval = spi_mchp_dma_setup_buffers(dev); + if (retval != 0) { + /* Stop DMA and terminate the SPI transaction in case of failure */ + dma_stop(cfg->spi_dma.dma_dev, cfg->spi_dma.tx_dma_channel); + dma_stop(cfg->spi_dma.dma_dev, cfg->spi_dma.rx_dma_channel); + if (spi_context_is_slave(&data->ctx) == false) { + spi_context_cs_control(&data->ctx, false); + } + spi_context_complete(&data->ctx, dev, retval); + + return; + } +} +#endif /* CONFIG_SPI_MCHP_DMA_DRIVEN_ASYNC */ + +static int spi_mchp_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 spi_callback, + void *userdata) +{ + const struct spi_mchp_dev_config *cfg = dev->config; + struct spi_mchp_dev_data *data = dev->data; + int retval; + + retval = spi_mchp_check_buf_len(tx_bufs); + if (retval < 0) { + return retval; + } + + retval = spi_mchp_check_buf_len(rx_bufs); + if (retval < 0) { + return retval; + } + + ARG_UNUSED(cfg); + +/* + * Transmit clocks the output, and we use receive to + * determine when the transmit is done, so we + * always need both TX and RX DMA channels. + */ +#if CONFIG_SPI_MCHP_DMA_DRIVEN_ASYNC + if (cfg->spi_dma.tx_dma_channel == 0xFF || cfg->spi_dma.rx_dma_channel == 0xFF) { + return -ENOTSUP; + } +#endif /* CONFIG_SPI_MCHP_DMA_DRIVEN_ASYNC */ + + spi_context_lock(&data->ctx, true, spi_callback, userdata, config); + + retval = spi_mchp_configure(dev, config); + if (retval != 0) { + spi_context_release(&data->ctx, retval); + + return retval; + } + + if (SPI_OP_MODE_GET(config->operation) == SPI_OP_MODE_MASTER) { + spi_context_cs_control(&data->ctx, true); + } + + spi_context_buffers_setup(&data->ctx, tx_bufs, rx_bufs, 1); + +/* Prepare and start DMA transfers */ +#if CONFIG_SPI_MCHP_DMA_DRIVEN_ASYNC + spi_mchp_dma_select_segment(dev); + retval = spi_mchp_dma_setup_buffers(dev); +#else + if (SPI_OP_MODE_GET(config->operation) == SPI_OP_MODE_MASTER) { + retval = spi_mchp_transceive_interrupt(dev, config, tx_bufs, rx_bufs); + } +#if CONFIG_SPI_SLAVE + if (SPI_OP_MODE_GET(config->operation) == SPI_OP_MODE_SLAVE) { + retval = spi_mchp_slave_transceive_interrupt(dev, config, tx_bufs, rx_bufs); + } +#endif /* CONFIG_SPI_SLAVE */ +#endif /* CONFIG_SPI_MCHP_DMA_DRIVEN_ASYNC */ + + if (retval != 0) { + /* Stop DMA transfers in case of failure */ +#if CONFIG_SPI_MCHP_DMA_DRIVEN_ASYNC + dma_stop(cfg->spi_dma.dma_dev, cfg->spi_dma.tx_dma_channel); + dma_stop(cfg->spi_dma.dma_dev, cfg->spi_dma.rx_dma_channel); +#endif /* CONFIG_SPI_MCHP_DMA_DRIVEN_ASYNC */ + + if (SPI_OP_MODE_GET(config->operation) == SPI_OP_MODE_MASTER) { + spi_context_cs_control(&data->ctx, false); + } + + spi_context_release(&data->ctx, retval); + } + + return retval; +} +#endif /* CONFIG_SPI_ASYNC */ + +static int spi_mchp_release(const struct device *dev, const struct spi_config *config) +{ + struct spi_mchp_dev_data *data = dev->data; + + spi_context_unlock_unconditionally(&data->ctx); + + return 0; +} + +#if defined(CONFIG_SPI_ASYNC) || defined(CONFIG_SPI_MCHP_INTERRUPT_DRIVEN) +#if (CONFIG_SPI_SLAVE) +static void spi_mchp_isr_slave(const struct device *dev) +{ + struct spi_mchp_dev_data *data = dev->data; + const struct spi_mchp_dev_config *cfg = dev->config; + const struct mchp_spi_reg_config *spi_reg_cfg = &cfg->reg_cfg; + uint8_t intFlag = spi_reg_cfg->regs->SPIS.SERCOM_INTFLAG; + static bool transaction_complete; + uint8_t tx_data = 0U; + uint8_t rx_data = 0U; + + /* Reset transaction_complete if there is data to send or receive */ + if ((spi_context_tx_buf_on(&data->ctx) == true) || + (spi_context_rx_buf_on(&data->ctx) == true)) { + transaction_complete = false; + } + + /* Check if data empty bit is set*/ + if (spi_slave_is_data_empty(spi_reg_cfg) == true) { + tx_data = *data->ctx.tx_buf; + if (spi_slave_is_tx_comp(spi_reg_cfg) == true) { + intFlag = (uint8_t)SERCOM_SPIS_INTFLAG_TXC_Msk; + } + spi_slave_write_data(spi_reg_cfg, tx_data); + if (spi_context_tx_on(&data->ctx) == true) { + spi_context_update_tx(&data->ctx, 1, 1); + } else { + /* Disable DRE interrupt. The last byte sent by the master will be + * shifted out automatically + */ + spi_slave_disable_dre_int(spi_reg_cfg); + } + } + + /* Check if slave select bit is set*/ + if (spi_slave_select_line(spi_reg_cfg) == true) { + spi_slave_clr_slave_select_line(spi_reg_cfg); + spi_slave_enable_txc_interrupt(spi_reg_cfg); + } + + /* Check if buffer overflow error bit is set*/ + if ((spi_reg_cfg->regs->SPIS.SERCOM_STATUS & SERCOM_SPIS_STATUS_BUFOVF_Msk) == + SERCOM_SPIS_STATUS_BUFOVF_Msk) { + spi_slave_clr_buf_overflow(spi_reg_cfg); + spi_slave_clr_data(spi_reg_cfg); + spi_slave_clr_error_int_flag(spi_reg_cfg); + } + + /* Check if data is available in the receive buffer */ + if (spi_slave_is_rx_comp(spi_reg_cfg) == true) { + rx_data = spi_slave_read_data(spi_reg_cfg); + if (spi_context_rx_buf_on(&data->ctx) == true) { + *data->ctx.rx_buf = rx_data; + spi_context_update_rx(&data->ctx, 1, 1); + } + } + + /* If TX complete, finish transaction if all done */ + if ((intFlag & SERCOM_SPIS_INTFLAG_TXC_Msk) == SERCOM_SPIS_INTFLAG_TXC_Msk) { + intFlag = 0; + spi_slave_clr_tx_comp_flag(spi_reg_cfg); + if ((spi_context_rx_on(&data->ctx) == false) && + (spi_context_tx_on(&data->ctx) == false)) { + spi_slave_disable_interrupts(spi_reg_cfg); + spi_slave_clr_interrupts(spi_reg_cfg); + /* Release the semaphore to unblock waiting threads */ + if (transaction_complete == false) { + spi_context_complete(&data->ctx, dev, 0); + transaction_complete = true; + } + } + } +} +#endif /* CONFIG_SPI_SLAVE */ + +static void spi_mchp_isr_master(const struct device *dev) +{ + struct spi_mchp_dev_data *data = dev->data; + const struct spi_mchp_dev_config *cfg = dev->config; + const struct mchp_spi_reg_config *spi_reg_cfg = &cfg->reg_cfg; + uint8_t dummy_data = 0U; + bool last_byte = false; + uint8_t tx_data = 0U; + uint8_t rx_data = 0U; + + /* Check if the transmit buffer is empty and send the next byte */ + if (spi_reg_cfg->regs->SPIM.SERCOM_INTENSET == 0) { + return; + } + /* Check if data is available in the receive buffer */ + if (spi_is_rx_comp(spi_reg_cfg) == true) { + if (spi_context_rx_buf_on(&data->ctx) == true) { + rx_data = spi_read_data(spi_reg_cfg); + *data->ctx.rx_buf = rx_data; + spi_context_update_rx(&data->ctx, 1, 1); + } + } + /* If data register is empty, send next byte or dummy */ + if (spi_is_data_empty(spi_reg_cfg) == true) { + spi_disable_data_empty_interrupt(spi_reg_cfg); + if (spi_context_tx_on(&data->ctx) == true) { + tx_data = *data->ctx.tx_buf; + spi_write_data(spi_reg_cfg, tx_data); + spi_context_update_tx(&data->ctx, 1, 1); + } else if (data->dummysize > 0) { + spi_write_data(spi_reg_cfg, dummy_data); + data->dummysize--; + } else { + /* Do Nothing */ + } + + if ((data->dummysize == 0) && (spi_context_tx_on(&data->ctx) == false)) { + last_byte = true; + } else if (spi_context_rx_on(&data->ctx) == false) { + spi_enable_data_empty_interrupt(spi_reg_cfg); + spi_disable_rxc_interrupt(spi_reg_cfg); + } else { + /* Do Nothing */ + } + } + /* If TX complete and last byte, finish transaction */ + if ((spi_is_tx_comp(spi_reg_cfg) == true) && (last_byte == true)) { + if (spi_context_rx_on(&data->ctx) == false) { + spi_disable_rxc_interrupt(spi_reg_cfg); + spi_disable_txc_interrupt(spi_reg_cfg); + spi_disable_data_empty_interrupt(spi_reg_cfg); + last_byte = false; + if (spi_context_is_slave(&data->ctx) == false) { + /* Control chip select for SPI slave mode */ + spi_context_cs_control(&data->ctx, false); + } + /* Release the semaphore to unblock waiting threads */ + spi_context_complete(&data->ctx, dev, 0); + } + } + /* Enable TX complete interrupt if last byte */ + if (last_byte == true) { + spi_enable_txc_interrupt(spi_reg_cfg); + } +} + +static void spi_mchp_isr(const struct device *dev) +{ +#if CONFIG_SPI_SLAVE + struct spi_mchp_dev_data *data = dev->data; + + if (spi_context_is_slave(&data->ctx) == true) { + spi_mchp_isr_slave(dev); + + return; + } +#endif /* CONFIG_SPI_SLAVE */ + + spi_mchp_isr_master(dev); +} +#endif /* CONFIG_SPI_ASYNC || CONFIG_SPI_MCHP_INTERRUPT_DRIVEN */ + +static int spi_mchp_init(const struct device *dev) +{ + int retval; + const struct spi_mchp_dev_config *cfg = dev->config; + const struct mchp_spi_reg_config *spi_reg_cfg = &cfg->reg_cfg; + struct spi_mchp_dev_data *const data = dev->data; + + retval = clock_control_on(cfg->spi_clock.clock_dev, cfg->spi_clock.gclk_sys); + if ((retval < 0) && (retval != -EALREADY)) { + LOG_ERR("Failed to enable the gclk_sys for SPI: %d", retval); + + return retval; + } + + retval = clock_control_on(cfg->spi_clock.clock_dev, cfg->spi_clock.mclk_sys); + if ((retval < 0) && (retval != -EALREADY)) { + LOG_ERR("Failed to enable the mclk_sys for SPI: %d", retval); + + return retval; + } + + /* Disable all SPI Interrupts*/ + spi_reg_cfg->regs->SPIM.SERCOM_INTENCLR = SERCOM_SPIM_INTENCLR_Msk; + + retval = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT); + if (retval < 0) { + LOG_ERR("pinctrl_apply_state Failed for SPI: %d", retval); + + return retval; + } + + spi_context_unlock_unconditionally(&data->ctx); + + return 0; +} + +static DEVICE_API(spi, spi_mchp_api) = { + .transceive = spi_mchp_transceive_sync, + +#if CONFIG_SPI_ASYNC + .transceive_async = spi_mchp_transceive_async, +#endif /*CONFIG_SPI_ASYNC*/ + +#if CONFIG_SPI_RTIO + .iodev_submit = spi_rtio_iodev_default_submit, +#endif /*CONFIG_SPI_RTIO*/ + + .release = spi_mchp_release, +}; + +#define SPI_MCHP_SERCOM_PADS(n) \ + SERCOM_SPIM_CTRLA_DIPO(DT_INST_PROP(n, dipo)) | \ + SERCOM_SPIM_CTRLA_DOPO(DT_INST_PROP(n, dopo)) + +#define SPI_MCHP_REG_CFG_DEFN(n) \ + .reg_cfg.regs = (sercom_registers_t *)DT_INST_REG_ADDR(n), \ + .reg_cfg.pads = SPI_MCHP_SERCOM_PADS(n), + +#if CONFIG_SPI_MCHP_INTERRUPT_DRIVEN || CONFIG_SPI_ASYNC +#if DT_INST_IRQ_HAS_IDX(0, 3) +#define SPI_MCHP_IRQ_HANDLER(n) \ + static void spi_mchp_irq_config_##n(const struct device *dev) \ + { \ + MCHP_SPI_IRQ_CONNECT(n, 0); \ + MCHP_SPI_IRQ_CONNECT(n, 1); \ + MCHP_SPI_IRQ_CONNECT(n, 2); \ + MCHP_SPI_IRQ_CONNECT(n, 3); \ + } +#else +#define SPI_MCHP_IRQ_HANDLER(n) \ + static void spi_mchp_irq_config_##n(const struct device *dev) \ + { \ + MCHP_SPI_IRQ_CONNECT(n, 0); \ + } +#endif +#else +#define SPI_MCHP_IRQ_HANDLER(n) +#endif /* CONFIG_SPI_MCHP_INTERRUPT_DRIVEN || CONFIG_SPI_ASYNC */ + +#define SPI_MCHP_CLOCK_DEFN(n) \ + .spi_clock.clock_dev = DEVICE_DT_GET(DT_NODELABEL(clock)), \ + .spi_clock.mclk_sys = (void *)(DT_INST_CLOCKS_CELL_BY_NAME(n, mclk, subsystem)), \ + .spi_clock.gclk_sys = (void *)(DT_INST_CLOCKS_CELL_BY_NAME(n, gclk, subsystem)) + +#if CONFIG_SPI_MCHP_INTERRUPT_DRIVEN || CONFIG_SPI_ASYNC +#define MCHP_SPI_IRQ_CONNECT(n, m) \ + do { \ + IRQ_CONNECT(DT_INST_IRQ_BY_IDX(n, m, irq), DT_INST_IRQ_BY_IDX(n, m, priority), \ + spi_mchp_isr, DEVICE_DT_INST_GET(n), 0); \ + irq_enable(DT_INST_IRQ_BY_IDX(n, m, irq)); \ + } while (false) + +#define SPI_MCHP_IRQ_HANDLER_DECL(n) static void spi_mchp_irq_config_##n(const struct device *dev) +#define SPI_MCHP_IRQ_HANDLER_FUNC(n) .irq_config_func = spi_mchp_irq_config_##n, +#else +#define SPI_MCHP_IRQ_HANDLER_DECL(n) +#define SPI_MCHP_IRQ_HANDLER_FUNC(n) +#endif /* CONFIG_SPI_MCHP_INTERRUPT_DRIVEN || CONFIG_SPI_ASYNC */ + +#if CONFIG_SPI_MCHP_DMA_DRIVEN_ASYNC +#define SPI_MCHP_DMA_CHANNELS(n) \ + .spi_dma.dma_dev = DEVICE_DT_GET(MCHP_DT_INST_DMA_CTLR(n, tx)), \ + .spi_dma.tx_dma_request = MCHP_DT_INST_DMA_TRIGSRC(n, tx), \ + .spi_dma.tx_dma_channel = MCHP_DT_INST_DMA_CHANNEL(n, tx), \ + .spi_dma.rx_dma_request = MCHP_DT_INST_DMA_TRIGSRC(n, rx), \ + .spi_dma.rx_dma_channel = MCHP_DT_INST_DMA_CHANNEL(n, rx), +#else +#define SPI_MCHP_DMA_CHANNELS(n) +#endif /* CONFIG_SPI_MCHP_DMA_DRIVEN_ASYNC */ + +#define SPI_MCHP_CONFIG_DEFN(n) \ + static const struct spi_mchp_dev_config spi_mchp_config_##n = { \ + .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ + SPI_MCHP_REG_CFG_DEFN(n) SPI_MCHP_IRQ_HANDLER_FUNC(n) SPI_MCHP_DMA_CHANNELS(n) \ + SPI_MCHP_CLOCK_DEFN(n)} + +#define SPI_MCHP_DEVICE_INIT(n) \ + PINCTRL_DT_INST_DEFINE(n); \ + SPI_MCHP_IRQ_HANDLER_DECL(n); \ + SPI_MCHP_CONFIG_DEFN(n); \ + static struct spi_mchp_dev_data spi_mchp_data_##n = { \ + SPI_CONTEXT_INIT_LOCK(spi_mchp_data_##n, ctx), \ + SPI_CONTEXT_INIT_SYNC(spi_mchp_data_##n, ctx), \ + SPI_CONTEXT_CS_GPIOS_INITIALIZE(DT_DRV_INST(n), ctx)}; \ + DEVICE_DT_INST_DEFINE(n, spi_mchp_init, NULL, &spi_mchp_data_##n, &spi_mchp_config_##n, \ + POST_KERNEL, CONFIG_SPI_INIT_PRIORITY, &spi_mchp_api); \ + SPI_MCHP_IRQ_HANDLER(n) + +DT_INST_FOREACH_STATUS_OKAY(SPI_MCHP_DEVICE_INIT) From 29493ced6f73c1f9ecad364afc05ee59a91bf111 Mon Sep 17 00:00:00 2001 From: Mohamed Azhar Date: Mon, 5 Jan 2026 19:33:28 +0530 Subject: [PATCH 2503/3659] boards: sam_e54_xpro: Update dts files for spi support Add required DTS and pinctrl changes to enable SPI on sam_e54_xpro. Signed-off-by: Mohamed Azhar --- .../sam/sam_e54_xpro/sam_e54_xpro-pinctrl.dtsi | 9 +++++++++ boards/microchip/sam/sam_e54_xpro/sam_e54_xpro.dts | 14 ++++++++++++++ .../microchip/sam/sam_e54_xpro/sam_e54_xpro.yaml | 1 + 3 files changed, 24 insertions(+) diff --git a/boards/microchip/sam/sam_e54_xpro/sam_e54_xpro-pinctrl.dtsi b/boards/microchip/sam/sam_e54_xpro/sam_e54_xpro-pinctrl.dtsi index c5e73896785d..861cb695a6d9 100644 --- a/boards/microchip/sam/sam_e54_xpro/sam_e54_xpro-pinctrl.dtsi +++ b/boards/microchip/sam/sam_e54_xpro/sam_e54_xpro-pinctrl.dtsi @@ -14,6 +14,15 @@ }; }; + sercom6_spi_default: sercom6_spi_default { + group1 { + pinmux = , + , + , + ; + }; + }; + sercom7_i2c_default: sercom7_i2c_default { group1 { pinmux = , diff --git a/boards/microchip/sam/sam_e54_xpro/sam_e54_xpro.dts b/boards/microchip/sam/sam_e54_xpro/sam_e54_xpro.dts index 27e329db4b40..8fdee6a6529c 100644 --- a/boards/microchip/sam/sam_e54_xpro/sam_e54_xpro.dts +++ b/boards/microchip/sam/sam_e54_xpro/sam_e54_xpro.dts @@ -216,6 +216,20 @@ status = "okay"; }; +&sercom6 { + compatible = "microchip,sercom-g1-spi"; + + dipo = <3>; + dopo = <0>; + + #address-cells = <1>; + #size-cells = <0>; + + pinctrl-0 = <&sercom6_spi_default>; + pinctrl-names = "default"; + status = "okay"; +}; + &sercom7 { compatible = "microchip,sercom-g1-i2c"; #address-cells = <1>; diff --git a/boards/microchip/sam/sam_e54_xpro/sam_e54_xpro.yaml b/boards/microchip/sam/sam_e54_xpro/sam_e54_xpro.yaml index d359f36d098d..082077483428 100644 --- a/boards/microchip/sam/sam_e54_xpro/sam_e54_xpro.yaml +++ b/boards/microchip/sam/sam_e54_xpro/sam_e54_xpro.yaml @@ -27,6 +27,7 @@ supported: - reset - rtc - shell + - spi - uart - watchdog vendor: microchip From e18a048c8499d859163a25c89a7cc98b15431833 Mon Sep 17 00:00:00 2001 From: Peter Mitsis Date: Wed, 14 Jan 2026 15:23:00 -0800 Subject: [PATCH 2504/3659] kernel: Add K_TIMEOUT_SUM() macro The K_TIMEOUT_SUM() macro is intended as a means to add two k_timeout_t values together. This may be useful for a developer applying an exponential backoff algorithm. Signed-off-by: Peter Mitsis --- include/zephyr/kernel.h | 17 ++- include/zephyr/sys/clock.h | 43 ++++++ tests/kernel/timer/timeout/CMakeLists.txt | 8 + tests/kernel/timer/timeout/prj.conf | 1 + tests/kernel/timer/timeout/src/main.c | 173 ++++++++++++++++++++++ tests/kernel/timer/timeout/testcase.yaml | 5 + 6 files changed, 246 insertions(+), 1 deletion(-) create mode 100644 tests/kernel/timer/timeout/CMakeLists.txt create mode 100644 tests/kernel/timer/timeout/prj.conf create mode 100644 tests/kernel/timer/timeout/src/main.c create mode 100644 tests/kernel/timer/timeout/testcase.yaml diff --git a/include/zephyr/kernel.h b/include/zephyr/kernel.h index bfde2db11006..17ca435f63b8 100644 --- a/include/zephyr/kernel.h +++ b/include/zephyr/kernel.h @@ -1665,6 +1665,22 @@ const char *k_thread_state_str(k_tid_t thread_id, char *buf, size_t buf_size); */ #define K_FOREVER Z_FOREVER +/** + * @brief Add two k_timeout_t values together + * + * This macro adds two k_timeout_t values together. If only one value is an + * absolute timeout, the result will be an absolute timeout. If both are + * relative timeouts, the result will be a relative timeout. If the calculation + * overflows, underflows or if both values are absolute timeouts, K_FOREVER + * is returned. + * + * @param timeout1 First k_timeout_t value + * @param timeout2 Second k_timeout_t value + * + * @return Sum of the two timeout values, or K_FOREVER if incalculable + */ +#define K_TIMEOUT_SUM(timeout1, timeout2) K_TICKS(z_timeout_sum(timeout1, timeout2)) + #ifdef CONFIG_TIMEOUT_64BIT /** @@ -1748,7 +1764,6 @@ const char *k_thread_state_str(k_tid_t thread_id, char *buf, size_t buf_size); * @return Timeout delay value */ #define K_TIMEOUT_ABS_CYC(t) K_TIMEOUT_ABS_TICKS(k_cyc_to_ticks_ceil64(t)) - #endif /** diff --git a/include/zephyr/sys/clock.h b/include/zephyr/sys/clock.h index c11935995835..d977fa4ff3fc 100644 --- a/include/zephyr/sys/clock.h +++ b/include/zephyr/sys/clock.h @@ -172,6 +172,49 @@ typedef struct { /* The maximum duration in ticks strictly and semantically "less than" K_FOREVER */ #define K_TICK_MAX ((k_ticks_t)(IS_ENABLED(CONFIG_TIMEOUT_64BIT) ? INT64_MAX : UINT32_MAX - 1)) +/** + * @brief Sum the ticks from two timeout values + * + * This routine determines the resulting tick value when adding two k_timeout_t + * values together. If only one k_timeout_t value is an absolute timeout, the + * result will be an absolute timeout. If both are relative timeouts, the + * result will be a relative timeout. If the calculated tick value overflows, + * underflows or if both values are absolute timeouts, it returns K_TICKS_FOREVER. + * + * @param t1 First k_timeout_t value + * @param t2 Second k_timeout_t value + * + * @return Sum of the two timeout values in ticks, or val K_TICKS_FOREVER if incalculable + */ +static inline k_ticks_t z_timeout_sum(k_timeout_t t1, k_timeout_t t2) +{ + k_ticks_t ticks1 = t1.ticks; + k_ticks_t ticks2 = t2.ticks; + +#ifdef CONFIG_TIMEOUT_64BIT + if ((ticks1 == K_TICKS_FOREVER) || (ticks2 == K_TICKS_FOREVER)) { + return K_TICKS_FOREVER; + } + + if (ticks1 < 0) { + if (ticks2 < 0) { + return K_TICKS_FOREVER; /* Both absolute timeouts */ + } + + return ((ticks1 - INT64_MIN) < ticks2) ? + K_TICKS_FOREVER : (ticks1 - ticks2); + } else if (ticks2 < 0) { + return ((ticks2 - INT64_MIN) < ticks1) ? + K_TICKS_FOREVER : (ticks2 - ticks1); + } else { + return ((INT64_MAX - ticks1) < ticks2) ? + K_TICKS_FOREVER : ticks1 + ticks2; + } +#else + return ((UINT32_MAX - ticks1) < ticks2) ? K_TICKS_FOREVER : ticks1 + ticks2; +#endif +} + /** @endcond */ #ifndef CONFIG_TIMER_READS_ITS_FREQUENCY_AT_RUNTIME diff --git a/tests/kernel/timer/timeout/CMakeLists.txt b/tests/kernel/timer/timeout/CMakeLists.txt new file mode 100644 index 000000000000..ba9a308c5d3f --- /dev/null +++ b/tests/kernel/timer/timeout/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(timer_timeout) + +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources}) diff --git a/tests/kernel/timer/timeout/prj.conf b/tests/kernel/timer/timeout/prj.conf new file mode 100644 index 000000000000..9467c2926896 --- /dev/null +++ b/tests/kernel/timer/timeout/prj.conf @@ -0,0 +1 @@ +CONFIG_ZTEST=y diff --git a/tests/kernel/timer/timeout/src/main.c b/tests/kernel/timer/timeout/src/main.c new file mode 100644 index 000000000000..b598e381bf44 --- /dev/null +++ b/tests/kernel/timer/timeout/src/main.c @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2026 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#ifdef CONFIG_TIMEOUT_64BIT +/** + * Verify that absolute timeout sums are handled correctly + */ +ZTEST(timeout, test_timeout_sum_absolute) +{ + k_timeout_t abs_timeout = K_TIMEOUT_ABS_TICKS(1000); + k_timeout_t result; + + /* Two absolute timeouts should result in K_FOREVER */ + + result = K_TIMEOUT_SUM(abs_timeout, abs_timeout); + zassert_true(K_TIMEOUT_EQ(result, K_FOREVER), "Expected K_FOREVER"); + + /* Absolute with K_FOREVER should result in K_FOREVER */ + + result = K_TIMEOUT_SUM(abs_timeout, K_FOREVER); + zassert_true(K_TIMEOUT_EQ(result, K_FOREVER), "Expected K_FOREVER"); + + result = K_TIMEOUT_SUM(K_FOREVER, abs_timeout); + zassert_true(K_TIMEOUT_EQ(result, K_FOREVER), "Expected K_FOREVER"); + + /* Absolute with K_NO_WAIT should return the absolute */ + + result = K_TIMEOUT_SUM(abs_timeout, K_NO_WAIT); + zassert_true(K_TIMEOUT_EQ(result, abs_timeout), + "Expected K_TIMEOUT_ABS_TICKS(1000)"); + + result = K_TIMEOUT_SUM(K_NO_WAIT, abs_timeout); + zassert_true(K_TIMEOUT_EQ(result, abs_timeout), + "Expected K_TIMEOUT_ABS_TICKS(1000)"); + + /* Absolute + relative (no underflow) should return a new absolute */ + + result = K_TIMEOUT_SUM(abs_timeout, K_TICKS(100)); + zassert_true(K_TIMEOUT_EQ(result, K_TIMEOUT_ABS_TICKS(1100)), + "Expected K_TIMEOUT_ABS_TICKS(1100)"); + + result = K_TIMEOUT_SUM(K_TICKS(100), abs_timeout); + zassert_true(K_TIMEOUT_EQ(result, K_TIMEOUT_ABS_TICKS(1100)), + "Expected K_TIMEOUT_ABS_TICKS(1100)"); + + /* Limit testing: small absolute + large relative -- absolute 1st */ + + result = K_TIMEOUT_SUM(K_TIMEOUT_ABS_TICKS(5), K_TICKS(INT64_MAX - 4)); + zassert_true(K_TIMEOUT_EQ(result, K_FOREVER), "Expected K_FOREVER"); + + result = K_TIMEOUT_SUM(K_TIMEOUT_ABS_TICKS(5), K_TICKS(INT64_MAX - 5)); + zassert_true(K_TIMEOUT_EQ(result, K_FOREVER), "Expected K_FOREVER"); + + result = K_TIMEOUT_SUM(K_TIMEOUT_ABS_TICKS(5), K_TICKS(INT64_MAX - 6)); + zassert_true(K_TIMEOUT_EQ(result, K_TICKS(INT64_MIN)), + "Expected INT64_MIN ticks"); + + result = K_TIMEOUT_SUM(K_TIMEOUT_ABS_TICKS(5), K_TICKS(INT64_MAX - 7)); + zassert_true(K_TIMEOUT_EQ(result, K_TICKS(INT64_MIN + 1)), + "Expected INT64_MIN + 1 ticks"); + + /* Limit testing: small absolute + large relative -- relative 1st */ + + result = K_TIMEOUT_SUM(K_TICKS(INT64_MAX - 4), K_TIMEOUT_ABS_TICKS(5)); + zassert_true(K_TIMEOUT_EQ(result, K_FOREVER), "Expected K_FOREVER"); + + result = K_TIMEOUT_SUM(K_TICKS(INT64_MAX - 5), K_TIMEOUT_ABS_TICKS(5)); + zassert_true(K_TIMEOUT_EQ(result, K_FOREVER), "Expected K_FOREVER"); + + result = K_TIMEOUT_SUM(K_TICKS(INT64_MAX - 6), K_TIMEOUT_ABS_TICKS(5)); + zassert_true(K_TIMEOUT_EQ(result, K_TICKS(INT64_MIN)), + "Expected INT64_MIN ticks"); + + result = K_TIMEOUT_SUM(K_TICKS(INT64_MAX - 7), K_TIMEOUT_ABS_TICKS(5)); + zassert_true(K_TIMEOUT_EQ(result, K_TICKS(INT64_MIN + 1)), + "Expected INT64_MIN + 1 ticks"); + + /* Limit testing large absolute + small relative -- absolute 1st */ + + result = K_TIMEOUT_SUM(K_TIMEOUT_ABS_TICKS(INT64_MAX - 5), K_TICKS(6)); + zassert_true(K_TIMEOUT_EQ(result, K_FOREVER), "Expected K_FOREVER"); + + result = K_TIMEOUT_SUM(K_TIMEOUT_ABS_TICKS(INT64_MAX - 6), K_TICKS(6)); + zassert_true(K_TIMEOUT_EQ(result, K_FOREVER), "Expected K_FOREVER"); + + result = K_TIMEOUT_SUM(K_TIMEOUT_ABS_TICKS(INT64_MAX - 7), K_TICKS(6)); + zassert_true(K_TIMEOUT_EQ(result, K_TICKS(INT64_MIN)), + "Expected INT64_MIN ticks"); + + result = K_TIMEOUT_SUM(K_TIMEOUT_ABS_TICKS(INT64_MAX - 8), K_TICKS(6)); + zassert_true(K_TIMEOUT_EQ(result, K_TICKS(INT64_MIN + 1)), + "Expected INT64_MIN + 1 ticks"); + + /* Limit testing large absolute + small relative -- relative 1st */ + + result = K_TIMEOUT_SUM(K_TICKS(6), K_TIMEOUT_ABS_TICKS(INT64_MAX - 5)); + zassert_true(K_TIMEOUT_EQ(result, K_FOREVER), "Expected K_FOREVER"); + + result = K_TIMEOUT_SUM(K_TICKS(6), K_TIMEOUT_ABS_TICKS(INT64_MAX - 6)); + zassert_true(K_TIMEOUT_EQ(result, K_FOREVER), "Expected K_FOREVER"); + + result = K_TIMEOUT_SUM(K_TICKS(6), K_TIMEOUT_ABS_TICKS(INT64_MAX - 7)); + zassert_true(K_TIMEOUT_EQ(result, K_TICKS(INT64_MIN)), + "Expected INT64_MIN ticks"); + + result = K_TIMEOUT_SUM(K_TICKS(6), K_TIMEOUT_ABS_TICKS(INT64_MAX - 8)); + zassert_true(K_TIMEOUT_EQ(result, K_TICKS(INT64_MIN + 1)), + "Expected INT64_MIN + 1 ticks"); +} +#endif + +/** + * Verify that relative timeout sums are handled correctly + */ +ZTEST(timeout, test_timeout_sum_relative) +{ + k_timeout_t result; + + /* Verify that normal sums work as expected */ + + result = K_TIMEOUT_SUM(K_TICKS(1), K_TICKS(2)); + zassert_true(K_TIMEOUT_EQ(result, K_TICKS(3)), "Expected 3 ticks"); + + /* K_NO_WAIT + X should return X */ + + result = K_TIMEOUT_SUM(K_NO_WAIT, K_TICKS(1)); + zassert_true(K_TIMEOUT_EQ(result, K_TICKS(1)), "Expected 1 tick"); + + result = K_TIMEOUT_SUM(K_TICKS(1), K_NO_WAIT); + zassert_true(K_TIMEOUT_EQ(result, K_TICKS(1)), "Expected 1 tick"); + + result = K_TIMEOUT_SUM(K_NO_WAIT, K_NO_WAIT); + zassert_true(K_TIMEOUT_EQ(result, K_NO_WAIT), "Expected K_NO_WAIT"); + + /* K_FOREVER + anything should return K_FOREVER */ + + result = K_TIMEOUT_SUM(K_TICKS(1), K_FOREVER); + zassert_true(K_TIMEOUT_EQ(result, K_FOREVER), "Expected K_FOREVER"); + + result = K_TIMEOUT_SUM(K_FOREVER, K_TICKS(1)); + zassert_true(K_TIMEOUT_EQ(result, K_FOREVER), "Expected K_FOREVER"); + + result = K_TIMEOUT_SUM(K_FOREVER, K_NO_WAIT); + zassert_true(K_TIMEOUT_EQ(result, K_FOREVER), "Expected K_FOREVER"); + + result = K_TIMEOUT_SUM(K_NO_WAIT, K_FOREVER); + zassert_true(K_TIMEOUT_EQ(result, K_FOREVER), "Expected K_FOREVER"); + + result = K_TIMEOUT_SUM(K_FOREVER, K_FOREVER); + zassert_true(K_TIMEOUT_EQ(result, K_FOREVER), "Expected K_FOREVER"); + + /* Behavior at limits */ + + result = K_TIMEOUT_SUM(K_TICKS(K_TICK_MAX - 1), K_TICKS(1)); + zassert_true(K_TIMEOUT_EQ(result, K_TICKS(K_TICK_MAX)), "Expected K_TICK_MAX ticks"); + + result = K_TIMEOUT_SUM(K_TICKS(K_TICK_MAX - 1), K_TICKS(2)); + zassert_true(K_TIMEOUT_EQ(result, K_FOREVER), "Expected K_FOREVER"); + + result = K_TIMEOUT_SUM(K_TICKS(K_TICK_MAX), K_NO_WAIT); + zassert_true(K_TIMEOUT_EQ(result, K_TICKS(K_TICK_MAX)), "Expected K_TICK_MAX ticks"); + + result = K_TIMEOUT_SUM(K_TICKS(K_TICK_MAX), K_TICKS(1)); + zassert_true(K_TIMEOUT_EQ(result, K_FOREVER), "Expected K_FOREVER"); +} + +ZTEST_SUITE(timeout, NULL, NULL, NULL, NULL, NULL); diff --git a/tests/kernel/timer/timeout/testcase.yaml b/tests/kernel/timer/timeout/testcase.yaml new file mode 100644 index 000000000000..3b9637ca2290 --- /dev/null +++ b/tests/kernel/timer/timeout/testcase.yaml @@ -0,0 +1,5 @@ +tests: + kernel.timer.timeout: + tags: + - kernel + - timer From 09ffa475c9331d1d157b157c9668f7a6b1931475 Mon Sep 17 00:00:00 2001 From: Kevin Chan Date: Fri, 16 Jan 2026 09:55:49 -0800 Subject: [PATCH 2505/3659] drivers: dma: fix channel_state channelState depends on descriptor count Signed-off-by: Kevin Chan --- drivers/dma/dma_infineon_pdl.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/dma/dma_infineon_pdl.c b/drivers/dma/dma_infineon_pdl.c index dbca67bc6942..dab52f31da86 100644 --- a/drivers/dma/dma_infineon_pdl.c +++ b/drivers/dma/dma_infineon_pdl.c @@ -192,8 +192,7 @@ static int ifx_cat1_dma_config(const struct device *dev, uint32_t channel, descriptor_config.interruptType = CY_DMA_DESCR; } - /* Keep CHANNEL_ENABLED if BURST transfer (config->dest_burst_length != 0) */ - if (config->dest_burst_length != 0) { + if (config->block_count > 1U) { descriptor_config.channelState = CY_DMA_CHANNEL_ENABLED; } else { descriptor_config.channelState = CY_DMA_CHANNEL_DISABLED; From aa58db66226477c82328e30cd208e48ff0d0b64e Mon Sep 17 00:00:00 2001 From: Kevin Chan Date: Fri, 16 Jan 2026 09:58:50 -0800 Subject: [PATCH 2506/3659] tests: drivers: spi: spi_loopback: support SPI-DMA on PSE84 Added SPI-DMA overlay Signed-off-by: Kevin Chan --- .../spi/spi_loopback/boards/kit_pse84_eval_common.overlay | 7 +++++++ .../boards/kit_pse84_eval_pse846gps2dbzc4a_m33.conf | 6 ++++++ .../boards/kit_pse84_eval_pse846gps2dbzc4a_m55.conf | 6 ++++++ 3 files changed, 19 insertions(+) create mode 100644 tests/drivers/spi/spi_loopback/boards/kit_pse84_eval_pse846gps2dbzc4a_m33.conf create mode 100644 tests/drivers/spi/spi_loopback/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.conf diff --git a/tests/drivers/spi/spi_loopback/boards/kit_pse84_eval_common.overlay b/tests/drivers/spi/spi_loopback/boards/kit_pse84_eval_common.overlay index 535ff0c02725..77360500287c 100644 --- a/tests/drivers/spi/spi_loopback/boards/kit_pse84_eval_common.overlay +++ b/tests/drivers/spi/spi_loopback/boards/kit_pse84_eval_common.overlay @@ -28,6 +28,9 @@ spi1: &scb10 { reg = <0>; spi-max-frequency = <3000000>; }; + + dmas = <&dma0 0>, <&dma0 1>; + dma-names = "tx", "rx"; }; &peri0_group1_16bit_2 { @@ -50,3 +53,7 @@ spi1: &scb10 { drive-strength = "full"; drive-push-pull; }; + +&dma0 { + status = "okay"; +}; diff --git a/tests/drivers/spi/spi_loopback/boards/kit_pse84_eval_pse846gps2dbzc4a_m33.conf b/tests/drivers/spi/spi_loopback/boards/kit_pse84_eval_pse846gps2dbzc4a_m33.conf new file mode 100644 index 000000000000..c91b39ef80a2 --- /dev/null +++ b/tests/drivers/spi/spi_loopback/boards/kit_pse84_eval_pse846gps2dbzc4a_m33.conf @@ -0,0 +1,6 @@ +# Copyright (c) 2025 Infineon Technologies AG, +# or an affiliate of Infineon Technologies AG. +# +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SPI_INFINEON_DMA=y diff --git a/tests/drivers/spi/spi_loopback/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.conf b/tests/drivers/spi/spi_loopback/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.conf new file mode 100644 index 000000000000..c91b39ef80a2 --- /dev/null +++ b/tests/drivers/spi/spi_loopback/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.conf @@ -0,0 +1,6 @@ +# Copyright (c) 2025 Infineon Technologies AG, +# or an affiliate of Infineon Technologies AG. +# +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SPI_INFINEON_DMA=y From 72b13523f62c69e902d2ec4699afd0e813cb2c9e Mon Sep 17 00:00:00 2001 From: Kevin Chan Date: Fri, 16 Jan 2026 09:59:51 -0800 Subject: [PATCH 2507/3659] drivers: spi: add SPI-DMA logic support SPI-DMA logic Signed-off-by: Kevin Chan --- drivers/spi/Kconfig.infineon | 12 +-- drivers/spi/spi_infineon_pdl.c | 179 +++++++++++++++++++-------------- 2 files changed, 104 insertions(+), 87 deletions(-) diff --git a/drivers/spi/Kconfig.infineon b/drivers/spi/Kconfig.infineon index 40339a29d907..83a1e534a55d 100644 --- a/drivers/spi/Kconfig.infineon +++ b/drivers/spi/Kconfig.infineon @@ -27,18 +27,10 @@ config SPI_INFINEON_CAT1_PDL if USE_INFINEON_SPI -config IFX_CAT1_SPI_DMA - bool "Infineon CAT1 SPI Interrupt Support" +config SPI_INFINEON_DMA + bool "Infineon SPI DMA Support" select DMA help Enable DMA during usage of SPI driver. -config IFX_CAT1_SPI_DMA_TX_AUTO_TRIGGER - bool "Infineon CAT1 SPI Tx DMA channel trigger mechanism" - default y - depends on IFX_CAT1_SPI_DMA - select DMA - help - Automatically trigger SPI Tx DMA after config - endif # USE_INFINEON_SPI diff --git a/drivers/spi/spi_infineon_pdl.c b/drivers/spi/spi_infineon_pdl.c index 22849fab9048..1cb2368a9e29 100644 --- a/drivers/spi/spi_infineon_pdl.c +++ b/drivers/spi/spi_infineon_pdl.c @@ -10,6 +10,8 @@ #include LOG_MODULE_REGISTER(cat1_spi, CONFIG_SPI_LOG_LEVEL); +#include + #include "spi_context.h" #include @@ -18,7 +20,7 @@ LOG_MODULE_REGISTER(cat1_spi, CONFIG_SPI_LOG_LEVEL); #include #include -#ifdef CONFIG_IFX_CAT1_SPI_DMA +#ifdef CONFIG_SPI_INFINEON_DMA #include #endif @@ -50,12 +52,14 @@ LOG_MODULE_REGISTER(cat1_spi, CONFIG_SPI_LOG_LEVEL); #define IFX_CAT1_SPI_ASYMM_PDL_FUNC_AVAIL #endif -#ifdef CONFIG_IFX_CAT1_SPI_DMA +#ifdef CONFIG_SPI_INFINEON_DMA /* dummy buffers to be used by driver for DMA operations when app gives a NULL buffer * during an asymmetric transfer */ static uint32_t tx_dummy_data; static uint32_t rx_dummy_data; + +#define IFX_CAT1_SPI_DMA_BURST_SIZE 256 #endif typedef void (*ifx_cat1_spi_event_callback_t)(void *callback_arg, uint32_t event); @@ -75,7 +79,7 @@ struct ifx_cat1_spi_config { uint8_t cs_oversample_cnt; }; -#ifdef CONFIG_IFX_CAT1_SPI_DMA +#ifdef CONFIG_SPI_INFINEON_DMA struct ifx_cat1_dma_stream { const struct device *dev_dma; uint32_t dma_channel; @@ -96,11 +100,9 @@ struct ifx_cat1_spi_data { size_t chunk_len; bool dma_configured; -#ifdef CONFIG_IFX_CAT1_SPI_DMA +#ifdef CONFIG_SPI_INFINEON_DMA struct ifx_cat1_dma_stream dma_rx; struct ifx_cat1_dma_stream dma_tx; - en_peri0_trig_input_pdma0_tr_t spi_rx_trigger; - en_peri0_trig_output_pdma0_tr_t dma_rx_trigger; #endif #if defined(COMPONENT_CAT1B) || defined(COMPONENT_CAT1C) || defined(CONFIG_SOC_FAMILY_INFINEON_EDGE) @@ -166,69 +168,85 @@ static void transfer_chunk(const struct device *dev) if (chunk_len == 0) { goto exit; } - data->chunk_len = chunk_len; -#ifdef CONFIG_IFX_CAT1_SPI_DMA +#ifdef CONFIG_SPI_INFINEON_DMA const struct ifx_cat1_spi_config *const config = dev->config; - CySCB_Type *spi_reg = config->reg_addr; - - Cy_SCB_SetRxFifoLevel(spi_reg, chunk_len - 1); - register struct ifx_cat1_dma_stream *dma_tx = &data->dma_tx; register struct ifx_cat1_dma_stream *dma_rx = &data->dma_rx; - if (data->dma_configured && spi_context_rx_buf_on(ctx) && spi_context_tx_buf_on(ctx)) { - /* Optimization to reduce config time if only buffer and size - * are changing from the previous DMA configuration - */ - dma_reload(dma_tx->dev_dma, dma_tx->dma_channel, (uint32_t)ctx->tx_buf, - dma_tx->blk_cfg.dest_address, chunk_len); - dma_reload(dma_rx->dev_dma, dma_rx->dma_channel, dma_rx->blk_cfg.source_address, - (uint32_t)ctx->rx_buf, chunk_len); - return; - } + if (chunk_len <= Cy_SCB_GetFifoSize(config->reg_addr)) { - if (spi_context_rx_buf_on(ctx)) { - dma_rx->blk_cfg.dest_address = (uint32_t)ctx->rx_buf; - dma_rx->blk_cfg.dest_addr_adj = DMA_ADDR_ADJ_INCREMENT; + cy_rslt_t result = ifx_cat1_spi_transfer_async( + dev, ctx->tx_buf, spi_context_tx_buf_on(ctx) ? chunk_len : 0, ctx->rx_buf, + spi_context_rx_buf_on(ctx) ? chunk_len : 0); + if (result == CY_RSLT_SUCCESS) { + return; + } + ret = -EIO; } else { - dma_rx->blk_cfg.dest_address = (uint32_t)&rx_dummy_data; - dma_rx->blk_cfg.dest_addr_adj = DMA_ADDR_ADJ_NO_CHANGE; - } + Cy_SCB_SetTxFifoLevel(config->reg_addr, 1U); + Cy_SCB_SetRxFifoLevel(config->reg_addr, 0U); + + if (chunk_len > IFX_CAT1_SPI_DMA_BURST_SIZE) { + dma_rx->dma_cfg.source_burst_length = dma_tx->dma_cfg.source_burst_length = + IFX_CAT1_SPI_DMA_BURST_SIZE; + dma_rx->dma_cfg.dest_burst_length = dma_tx->dma_cfg.dest_burst_length = + IFX_CAT1_SPI_DMA_BURST_SIZE; + if (chunk_len % IFX_CAT1_SPI_DMA_BURST_SIZE != 0) { + LOG_ERR("DMA (DW) only supports lengths is multiple of burst " + "length (%d)", + IFX_CAT1_SPI_DMA_BURST_SIZE); + goto exit; + } + dma_rx->dma_cfg.block_count = dma_tx->dma_cfg.block_count = 1; + } else { + dma_rx->dma_cfg.source_burst_length = dma_tx->dma_cfg.source_burst_length = + 0; + dma_rx->dma_cfg.dest_burst_length = dma_tx->dma_cfg.dest_burst_length = 0; + dma_rx->dma_cfg.block_count = dma_tx->dma_cfg.block_count = 1; + } - if (spi_context_tx_buf_on(ctx)) { - dma_tx->blk_cfg.source_address = (uint32_t)ctx->tx_buf; - dma_tx->blk_cfg.source_addr_adj = DMA_ADDR_ADJ_INCREMENT; + dma_rx->blk_cfg.block_size = dma_tx->blk_cfg.block_size = chunk_len; - } else { - tx_dummy_data = 0; - dma_tx->blk_cfg.source_address = (uint32_t)&tx_dummy_data; - dma_tx->blk_cfg.source_addr_adj = DMA_ADDR_ADJ_NO_CHANGE; - } + if (spi_context_rx_buf_on(ctx)) { + dma_rx->blk_cfg.dest_address = (uint32_t)ctx->rx_buf; + dma_rx->blk_cfg.dest_addr_adj = DMA_ADDR_ADJ_INCREMENT; + } else { + dma_rx->blk_cfg.dest_address = (uint32_t)&rx_dummy_data; + dma_rx->blk_cfg.dest_addr_adj = DMA_ADDR_ADJ_NO_CHANGE; + } - dma_rx->blk_cfg.block_size = dma_tx->blk_cfg.block_size = chunk_len; - ret = dma_config(dma_rx->dev_dma, dma_rx->dma_channel, &dma_rx->dma_cfg); - if (ret < 0) { - goto exit; - } + if (spi_context_tx_buf_on(ctx)) { + dma_tx->blk_cfg.source_address = (uint32_t)ctx->tx_buf; + dma_tx->blk_cfg.source_addr_adj = DMA_ADDR_ADJ_INCREMENT; - ret = dma_config(dma_tx->dev_dma, dma_tx->dma_channel, &dma_tx->dma_cfg); - if (ret < 0) { - goto exit; - } + } else { + tx_dummy_data = 0; + dma_tx->blk_cfg.source_address = (uint32_t)&tx_dummy_data; + dma_tx->blk_cfg.source_addr_adj = DMA_ADDR_ADJ_NO_CHANGE; + } -#ifdef CONFIG_IFX_CAT1_SPI_DMA_TX_AUTO_TRIGGER - ret = dma_start(dma_tx->dev_dma, dma_tx->dma_channel); - if (ret == 0) { - return; - } -#else - if (ret == 0) { - data->dma_configured = 1; - return; + ret = dma_config(dma_rx->dev_dma, dma_rx->dma_channel, &dma_rx->dma_cfg); + if (ret < 0) { + goto exit; + } + + ret = dma_config(dma_tx->dev_dma, dma_tx->dma_channel, &dma_tx->dma_cfg); + if (ret < 0) { + goto exit; + } + + ret = dma_start(dma_rx->dev_dma, dma_rx->dma_channel); + if (ret < 0) { + goto exit; + } + + ret = dma_start(dma_tx->dev_dma, dma_tx->dma_channel); + if (ret == 0) { + return; + } } -#endif #else cy_rslt_t result = ifx_cat1_spi_transfer_async( dev, ctx->tx_buf, spi_context_tx_buf_on(ctx) ? chunk_len : 0, ctx->rx_buf, @@ -236,9 +254,14 @@ static void transfer_chunk(const struct device *dev) if (result == CY_RSLT_SUCCESS) { return; } -#endif ret = -EIO; +#endif + exit: +#ifdef CONFIG_SPI_INFINEON_DMA + dma_stop(data->dma_tx.dev_dma, data->dma_tx.dma_channel); + dma_stop(data->dma_rx.dev_dma, data->dma_rx.dma_channel); +#endif spi_context_cs_control(ctx, false); spi_context_complete(ctx, dev, ret); } @@ -264,7 +287,7 @@ static void spi_interrupt_callback(void *arg, uint32_t event) } } -#ifdef CONFIG_IFX_CAT1_SPI_DMA +#ifdef CONFIG_SPI_INFINEON_DMA static void dma_callback(const struct device *dma_dev, void *arg, uint32_t channel, int status) { struct device *dev = arg; @@ -394,6 +417,12 @@ int spi_config(const struct device *dev, const struct spi_config *spi_cfg) ctx->config = spi_cfg; data->dfs_value = get_dfs_value(ctx); +#ifdef CONFIG_SPI_INFINEON_DMA + data->dma_rx.dma_cfg.source_data_size = data->dfs_value; + data->dma_rx.dma_cfg.dest_data_size = data->dfs_value; + data->dma_tx.dma_cfg.source_data_size = data->dfs_value; + data->dma_tx.dma_cfg.dest_data_size = data->dfs_value; +#endif return 0; } @@ -447,10 +476,11 @@ static int ifx_cat1_spi_release(const struct device *dev, const struct spi_confi { spi_free(dev); -#ifdef CONFIG_IFX_CAT1_SPI_DMA +#ifdef CONFIG_SPI_INFINEON_DMA struct ifx_cat1_spi_data *const data = dev->data; dma_stop(data->dma_tx.dev_dma, data->dma_tx.dma_channel); + dma_stop(data->dma_rx.dev_dma, data->dma_rx.dma_channel); #endif return 0; @@ -474,13 +504,7 @@ static int ifx_cat1_spi_init(const struct device *dev) data->resource.type = IFX_RSC_SCB; data->resource.block_num = ifx_cat1_uart_get_hw_block_num(config->reg_addr); -#ifdef CONFIG_IFX_CAT1_SPI_DMA - /* spi_rx_trigger is initialized to PERI_0_TRIG_IN_MUX_0_SCB_RX_TR_OUT0, - * this is incremented by the resource.block_num to get the trigger for the selected SCB - * from the trigmux enumeration (en_peri0_trig_input_pdma0_tr_t) - */ - data->spi_rx_trigger += data->resource.block_num; - +#ifdef CONFIG_SPI_INFINEON_DMA if (data->dma_rx.dev_dma != NULL) { if (!device_is_ready(data->dma_rx.dev_dma)) { return -ENODEV; @@ -491,6 +515,11 @@ static int ifx_cat1_spi_init(const struct device *dev) data->dma_rx.dma_cfg.head_block = &data->dma_rx.blk_cfg; data->dma_rx.dma_cfg.user_data = (void *)dev; data->dma_rx.dma_cfg.dma_callback = dma_callback; +#if defined(CONFIG_SOC_FAMILY_INFINEON_EDGE) + Cy_TrigMux_Connect(PERI_0_TRIG_IN_MUX_0_SCB_RX_TR_OUT0 + data->resource.block_num, + PERI_0_TRIG_OUT_MUX_0_PDMA0_TR_IN0 + data->dma_rx.dma_channel, + false, TRIGGER_TYPE_LEVEL); +#endif } if (data->dma_tx.dev_dma != NULL) { @@ -503,9 +532,12 @@ static int ifx_cat1_spi_init(const struct device *dev) data->dma_tx.dma_cfg.head_block = &data->dma_tx.blk_cfg; data->dma_tx.dma_cfg.user_data = (void *)dev; data->dma_tx.dma_cfg.dma_callback = dma_callback; +#if defined(CONFIG_SOC_FAMILY_INFINEON_EDGE) + Cy_TrigMux_Connect(PERI_0_TRIG_IN_MUX_0_SCB_TX_TR_OUT0 + data->resource.block_num, + PERI_0_TRIG_OUT_MUX_0_PDMA0_TR_IN0 + data->dma_tx.dma_channel, + false, TRIGGER_TYPE_EDGE); +#endif } - - Cy_TrigMux_Connect(data->spi_rx_trigger, data->dma_rx_trigger, false, TRIGGER_TYPE_LEVEL); #endif /* Configure dt provided device signals when available */ @@ -527,7 +559,7 @@ static int ifx_cat1_spi_init(const struct device *dev) return 0; } -#if defined(CONFIG_IFX_CAT1_SPI_DMA) +#if defined(CONFIG_SPI_INFINEON_DMA) #define SPI_DMA_CHANNEL_INIT(index, dir, ch_dir, src_data_size, dst_data_size) \ .dev_dma = DEVICE_DT_GET(DT_INST_DMAS_CTLR_BY_NAME(index, dir)), \ .dma_channel = DT_INST_DMAS_CELL_BY_NAME(index, dir, channel), \ @@ -546,15 +578,8 @@ static int ifx_cat1_spi_init(const struct device *dev) DT_INST_DMAS_HAS_NAME(index, dir), \ (SPI_DMA_CHANNEL_INIT(index, dir, ch_dir, src_data_size, dst_data_size)), \ (NULL))}, - -#define SPI_DMA_TRIGGERS(index) \ - .spi_rx_trigger = (en_peri0_trig_input_pdma0_tr_t)(PERI_0_TRIG_IN_MUX_0_SCB_RX_TR_OUT0), \ - .dma_rx_trigger = \ - (en_peri0_trig_output_pdma0_tr_t)(PERI_0_TRIG_OUT_MUX_0_PDMA0_TR_IN0 + \ - DT_INST_DMAS_CELL_BY_NAME(index, rx, channel)), #else #define SPI_DMA_CHANNEL(index, dir, ch_dir, src_data_size, dst_data_size) -#define SPI_DMA_TRIGGERS(index) #endif #if defined(COMPONENT_CAT1B) || defined(COMPONENT_CAT1C) || defined(CONFIG_SOC_FAMILY_INFINEON_EDGE) @@ -631,7 +656,7 @@ static int ifx_cat1_spi_init(const struct device *dev) .ssPolarity = DT_INST_PROP_OR(n, ss_polarity, CY_SCB_SPI_ACTIVE_LOW), \ .rxFifoTriggerLevel = DT_INST_PROP_OR(n, rx_fifo_trigger_level, 0), \ .rxFifoIntEnableMask = DT_INST_PROP_OR(n, rx_fifo_int_enable_mask, 0), \ - .txFifoTriggerLevel = DT_INST_PROP_OR(n, tx_fifo_trigger_level, 0), \ + .txFifoTriggerLevel = DT_INST_PROP_OR(n, tx_fifo_trigger_level, 1), \ .txFifoIntEnableMask = DT_INST_PROP_OR(n, tx_fifo_int_enable_mask, 0), \ .masterSlaveIntEnableMask = \ DT_INST_PROP_OR(n, master_slave_int_enable_mask, 0)}, \ @@ -647,7 +672,7 @@ static int ifx_cat1_spi_init(const struct device *dev) SPI_CONTEXT_INIT_LOCK(spi_cat1_data_##n, ctx), \ SPI_CONTEXT_INIT_SYNC(spi_cat1_data_##n, ctx), \ SPI_DMA_CHANNEL(n, tx, MEMORY_TO_PERIPHERAL, 1, 1) \ - SPI_DMA_CHANNEL(n, rx, PERIPHERAL_TO_MEMORY, 1, 1) SPI_DMA_TRIGGERS(n) \ + SPI_DMA_CHANNEL(n, rx, PERIPHERAL_TO_MEMORY, 1, 1) \ SPI_CONTEXT_CS_GPIOS_INITIALIZE(DT_DRV_INST(n), ctx) \ SPI_PERI_CLOCK_INIT(n) \ .spi_deep_sleep = { \ From 554a765de92aa9ca10f268f589e2b3ca79919682 Mon Sep 17 00:00:00 2001 From: Brandon Edmonds Date: Tue, 20 Jan 2026 16:20:28 -0500 Subject: [PATCH 2508/3659] drivers: sensor: shell: Add SENSOR_TRIG_TIMER to the sensor stream shell. In sensor_shell_stream.c, cmd_sensor_stream() checks for valid trigger types, but it is missing SENSOR_TRIG_TIMER option. Signed-off-by: Brandon Edmonds --- drivers/sensor/sensor_shell_stream.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/sensor/sensor_shell_stream.c b/drivers/sensor/sensor_shell_stream.c index e4a7e68cfb10..5ad6275376ba 100644 --- a/drivers/sensor/sensor_shell_stream.c +++ b/drivers/sensor/sensor_shell_stream.c @@ -90,6 +90,8 @@ int cmd_sensor_stream(const struct shell *sh, size_t argc, char *argv[]) iodev_sensor_shell_trigger.trigger = SENSOR_TRIG_FIFO_FULL; } else if (strcmp("tap", argv[3]) == 0) { iodev_sensor_shell_trigger.trigger = SENSOR_TRIG_TAP; + } else if (strcmp("timer", argv[3]) == 0) { + iodev_sensor_shell_trigger.trigger = SENSOR_TRIG_TIMER; } else { shell_error(sh, "Invalid trigger (%s)", argv[3]); return -EINVAL; From 705fc203e59ab660c54ab1b155ad245d209c7e05 Mon Sep 17 00:00:00 2001 From: Scott Worley Date: Tue, 20 Jan 2026 11:14:48 -0500 Subject: [PATCH 2509/3659] soc: microchip: mec: Disable deprecated MEC5 HAL for MEC165xB/174x/175x Due to multiple customer requests we are deprecating the MEC5 HAL. Customers prefer all code to be in the main Zephyr tree. They do not want a dependency on an outside SoC HAL. These changes remove the MEC5_HAL select from MEC165xB, MEC174x, and MEC175x. The SoC code calling the HAL for debug configuration was replaced with a small amount of code common to all SoC's. We also moved all the common header includes into a common SoC header to prevent changing multiple files if new common headers are added. Note: the in-tree drivers: kernel timer, GPIO, PINCTRL, and UART are all non-HAL. Signed-off-by: Scott Worley --- soc/microchip/mec/Kconfig | 2 +- soc/microchip/mec/common/CMakeLists.txt | 5 +- soc/microchip/mec/common/soc_cmn_init.c | 106 +++++++++++++++++++----- soc/microchip/mec/common/soc_common.h | 35 ++++++++ soc/microchip/mec/mec165xb/Kconfig | 1 - soc/microchip/mec/mec165xb/soc.h | 49 ++++++----- soc/microchip/mec/mec174x/Kconfig | 1 - soc/microchip/mec/mec174x/soc.h | 49 ++++++----- soc/microchip/mec/mec175x/Kconfig | 1 - soc/microchip/mec/mec175x/soc.h | 49 ++++++----- 10 files changed, 195 insertions(+), 103 deletions(-) create mode 100644 soc/microchip/mec/common/soc_common.h diff --git a/soc/microchip/mec/Kconfig b/soc/microchip/mec/Kconfig index c44f7e0500fe..e01a80a2a350 100644 --- a/soc/microchip/mec/Kconfig +++ b/soc/microchip/mec/Kconfig @@ -218,7 +218,7 @@ endif # MCHP_MEC_UNSIGNED_HEADER choice prompt "MEC debug interface general configuration" default SOC_MEC_DEBUG_AND_TRACING - depends on SOC_SERIES_MEC174X || SOC_SERIES_MEC175X + depends on SOC_SERIES_MEC174X || SOC_SERIES_MEC175X || SOC_SERIES_MEC165XB help Select Debug SoC interface support for MEC SoC family diff --git a/soc/microchip/mec/common/CMakeLists.txt b/soc/microchip/mec/common/CMakeLists.txt index 0f19288ae785..db7c071aff6b 100644 --- a/soc/microchip/mec/common/CMakeLists.txt +++ b/soc/microchip/mec/common/CMakeLists.txt @@ -1,13 +1,10 @@ # SPDX-License-Identifier: Apache-2.0 zephyr_include_directories(.) -zephyr_library_sources(soc_ecia.c soc_pcr.c) +zephyr_library_sources(soc_ecia.c soc_pcr.c soc_cmn_init.c) zephyr_library_sources_ifdef(CONFIG_SOC_SERIES_MEC172X soc_i2c.c ) -zephyr_library_sources_ifdef(CONFIG_HAS_MEC5_HAL - soc_cmn_init.c -) if(DEFINED CONFIG_MCHP_HEADER_VERBOSE_OUTPUT) set(MCHP_HEADER_VERBOSE_OPTION "-v") diff --git a/soc/microchip/mec/common/soc_cmn_init.c b/soc/microchip/mec/common/soc_cmn_init.c index ffb55dd9567a..f59032884b96 100644 --- a/soc/microchip/mec/common/soc_cmn_init.c +++ b/soc/microchip/mec/common/soc_cmn_init.c @@ -4,36 +4,102 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include +#include +#include #include #include -#include -#include +#include + +#define XEC_ECS_ETM_CR_OFS 0x1cu +#define XEC_ECS_ETM_PINS_EN_POS 0 + +#define XEC_ECS_DGB_CR_OFS 0x20u +#define XEC_ECS_DBG_CR_EN_POS 0 +#define XEC_ECS_DBG_CR_PIN_CFG_POS 1 +#define XEC_ECS_DBG_CR_PIN_CFG_MSK GENMASK(2, 1) +#define XEC_ECS_DBG_CR_PIN_CFG_JTAG 0 +#define XEC_ECS_DBG_CR_PIN_CFG_SWD_SWV 1 +#define XEC_ECS_DBG_CR_PIN_CFG_SWD 2 +#define XEC_ECS_DBG_CR_PIN_CFG_SET(c) FIELD_PREP(XEC_ECS_DBG_CR_PIN_CFG_MSK, (c)) +#define XEC_ECS_DBG_CR_PIN_CFG_GET(r) FIELD_GET(XEC_ECS_DBG_CR_PIN_CFG_MSK, (r)) +#define XEC_ECS_DBG_CR_PU_EN_POS 3 +#define XEC_ECS_DBG_CR_EN_LOCK_POS 5 + +#define XEC_ECS_BASE_ADDR DT_REG_ADDR(DT_NODELABEL(ecs)) + +#define XEC_DEBUG_FLAG_EN_POS 0 +#define XEC_DEBUG_FLAG_ETM_EN_POS 1 +#define XEC_DEBUG_IFC_SWD_POS 2 +#define XEC_DEBUG_SWD_SWV_POS 3 +#define XEC_DEBUG_IFC_LOCK_POS 4 + +void mec_soc_debug_ifc_init(uint32_t flags) +{ + uint32_t msk = 0, val = 0; + + if ((flags & BIT(XEC_DEBUG_FLAG_ETM_EN_POS)) != 0) { + /* Switch shared GPIOs to ETM mode */ + sys_set_bit(XEC_ECS_BASE_ADDR + XEC_ECS_ETM_CR_OFS, XEC_ECS_ETM_PINS_EN_POS); + } else { + /* Disable ETM. ETM pins can be used as GPIOs */ + sys_clear_bit(XEC_ECS_BASE_ADDR + XEC_ECS_ETM_CR_OFS, XEC_ECS_ETM_PINS_EN_POS); + } + + if ((flags & BIT(XEC_DEBUG_FLAG_EN_POS)) != 0) { + msk = BIT(XEC_ECS_DBG_CR_EN_POS) | XEC_ECS_DBG_CR_PIN_CFG_MSK; + val = BIT(XEC_ECS_DBG_CR_EN_POS); + + if ((flags & BIT(XEC_DEBUG_IFC_LOCK_POS)) != 0) { + msk |= BIT(XEC_ECS_DBG_CR_EN_LOCK_POS); + val |= BIT(XEC_ECS_DBG_CR_EN_LOCK_POS); + } -static void mec5_soc_init_debug_interface(void) + if ((flags & BIT(XEC_DEBUG_IFC_SWD_POS)) != 0) { + if ((flags & BIT(XEC_DEBUG_SWD_SWV_POS)) != 0) { + val |= XEC_ECS_DBG_CR_PIN_CFG_SET(XEC_ECS_DBG_CR_PIN_CFG_SWD_SWV); + } else { + val |= XEC_ECS_DBG_CR_PIN_CFG_SET(XEC_ECS_DBG_CR_PIN_CFG_SWD); + } + } else { + val |= XEC_ECS_DBG_CR_PIN_CFG_SET(XEC_ECS_DBG_CR_PIN_CFG_JTAG); + } + + soc_mmcr_mask_set(XEC_ECS_BASE_ADDR + XEC_ECS_DGB_CR_OFS, val, msk); + } else { + sys_clear_bit(XEC_ECS_BASE_ADDR + XEC_ECS_DGB_CR_OFS, XEC_ECS_DBG_CR_EN_POS); + } +} + +int mec5_soc_common_init(void) { + uint32_t dbg_flags = 0; /* disabled */ + bool config_debug = false; + + /* Kconfig choice items. Only one will be defined */ #if defined(CONFIG_SOC_MEC_DEBUG_DISABLED) - mec_ecs_etm_pins(ECS_ETM_PINS_DISABLE); - mec_hal_ecs_debug_port(MEC_DEBUG_MODE_DISABLE); -#else + config_debug = true; +#endif #if defined(SOC_MEC_DEBUG_WITHOUT_TRACING) - mec_ecs_etm_pins(ECS_ETM_PINS_DISABLE); - mec_hal_ecs_debug_port(MEC_DEBUG_MODE_SWD); -#elif defined(SOC_MEC_DEBUG_AND_TRACING) -#if defined(SOC_MEC_DEBUG_AND_ETM_TRACING) - mec_ecs_etm_pins(ECS_ETM_PINS_DISABLE); - mec_hal_ecs_debug_port(MEC_DEBUG_MODE_SWD_SWV); -#elif defined(CONFIG_SOC_MEC_DEBUG_AND_ETM_TRACING) - mec_ecs_debug_port(MEC_DEBUG_MODE_SWD); - mec_hal_ecs_etm_pins(ECS_ETM_PINS_ENABLE); + config_debug = true; + dbg_flags = BIT(XEC_DEBUG_FLAG_EN_POS) | BIT(XEC_DEBUG_IFC_SWD_POS); #endif +#if defined(SOC_MEC_DEBUG_AND_TRACING) + config_debug = true; +#if defined(CONFIG_SOC_MEC_DEBUG_AND_SWV_TRACING) + dbg_flags = (BIT(XEC_DEBUG_FLAG_EN_POS) | BIT(XEC_DEBUG_IFC_SWD_POS) | + BIT(XEC_DEBUG_SWD_SWV_POS)); +#endif +#if defined(config SOC_MEC_DEBUG_AND_ETM_TRACING) + dbg_flags = (BIT(XEC_DEBUG_FLAG_EN_POS) | BIT(XEC_DEBUG_IFC_SWD_POS) | + BIT(XEC_DEBUG_FLAG_ETM_EN_POS)); #endif #endif -} -int mec5_soc_common_init(void) -{ - mec5_soc_init_debug_interface(); + if (config_debug == true) { + mec_soc_debug_ifc_init(dbg_flags); + } + soc_ecia_init(MCHP_MEC_ECIA_GIRQ_AGGR_ONLY_BM, MCHP_MEC_ECIA_GIRQ_DIRECT_CAP_BM, 0); return 0; diff --git a/soc/microchip/mec/common/soc_common.h b/soc/microchip/mec/common/soc_common.h new file mode 100644 index 000000000000..e45d965dc453 --- /dev/null +++ b/soc/microchip/mec/common/soc_common.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2026 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __SOC_MICROCHIP_MEC_COMMON_SOC_COMMON_H +#define __SOC_MICROCHIP_MEC_COMMON_SOC_COMMON_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* common SoC API */ +#include +#include +#include +#include +#include +#include +#include + +#endif /* __SOC_MICROCHIP_MEC_COMMON_SOC_COMMON_H */ diff --git a/soc/microchip/mec/mec165xb/Kconfig b/soc/microchip/mec/mec165xb/Kconfig index 79ff7dd7e0fb..615c549f6c7e 100644 --- a/soc/microchip/mec/mec165xb/Kconfig +++ b/soc/microchip/mec/mec165xb/Kconfig @@ -9,5 +9,4 @@ config SOC_SERIES_MEC165XB select CPU_CORTEX_M_HAS_DWT select CPU_HAS_ARM_MPU select HAS_SWO - select HAS_MEC5_HAL select SOC_PREP_HOOK diff --git a/soc/microchip/mec/mec165xb/soc.h b/soc/microchip/mec/mec165xb/soc.h index 545b8a1d102f..7352a64c9332 100644 --- a/soc/microchip/mec/mec165xb/soc.h +++ b/soc/microchip/mec/mec165xb/soc.h @@ -13,33 +13,32 @@ #define MCHP_HAS_UART_LSR2 -#include +/* Minimal ARM CMSIS requirements */ +typedef enum { + Reset_IRQn = -15, + NonMaskableInt_IRQn = -14, + HardFault_IRQn = -13, + MemoryManagement_IRQn = -12, + BusFault_IRQn = -11, + UsageFault_IRQn = -10, + SVCall_IRQn = -5, + DebugMonitor_IRQn = -4, + PendSV_IRQn = -2, + SysTick_IRQn = -1, + FirstPeriph_IRQn = 0, + LastPeriph_IRQn = 197, +} IRQn_Type; + +#define __CM4_REV 0x0201U /* CM4 Core Revision */ +#define __NVIC_PRIO_BITS 3 /* Number of Bits used for Priority Levels */ +#define __Vendor_SysTickConfig 0 /* Set to 1 if different SysTick Config is used */ +#define __MPU_PRESENT 1 /* MPU present */ +#define __FPU_PRESENT 0 /* FPU present */ + +#include /* common peripheral register defines */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* common SoC API */ -#include -#include -#include -#include -#include -#include -#include +#include #endif #endif diff --git a/soc/microchip/mec/mec174x/Kconfig b/soc/microchip/mec/mec174x/Kconfig index bdee97015bc6..82182478c59b 100644 --- a/soc/microchip/mec/mec174x/Kconfig +++ b/soc/microchip/mec/mec174x/Kconfig @@ -10,7 +10,6 @@ config SOC_SERIES_MEC174X select CPU_HAS_FPU select CPU_HAS_ARM_MPU select HAS_SWO - select HAS_MEC5_HAL select SOC_PREP_HOOK if SOC_SERIES_MEC174X diff --git a/soc/microchip/mec/mec174x/soc.h b/soc/microchip/mec/mec174x/soc.h index cdfc1f228ccd..dc4515e15e1f 100644 --- a/soc/microchip/mec/mec174x/soc.h +++ b/soc/microchip/mec/mec174x/soc.h @@ -13,33 +13,32 @@ #define MCHP_HAS_UART_LSR2 -#include +/* Minimal ARM CMSIS requirements */ +typedef enum { + Reset_IRQn = -15, + NonMaskableInt_IRQn = -14, + HardFault_IRQn = -13, + MemoryManagement_IRQn = -12, + BusFault_IRQn = -11, + UsageFault_IRQn = -10, + SVCall_IRQn = -5, + DebugMonitor_IRQn = -4, + PendSV_IRQn = -2, + SysTick_IRQn = -1, + FirstPeriph_IRQn = 0, + LastPeriph_IRQn = 197, +} IRQn_Type; + +#define __CM4_REV 0x0201U /* CM4 Core Revision */ +#define __NVIC_PRIO_BITS 3 /* Number of Bits used for Priority Levels */ +#define __Vendor_SysTickConfig 0 /* Set to 1 if different SysTick Config is used */ +#define __MPU_PRESENT 1 /* MPU present */ +#define __FPU_PRESENT 1 /* FPU present */ + +#include /* common peripheral register defines */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* common SoC API */ -#include -#include -#include -#include -#include -#include -#include +#include #endif #endif diff --git a/soc/microchip/mec/mec175x/Kconfig b/soc/microchip/mec/mec175x/Kconfig index e2136d7a2df9..4f6b9d93f74d 100644 --- a/soc/microchip/mec/mec175x/Kconfig +++ b/soc/microchip/mec/mec175x/Kconfig @@ -10,7 +10,6 @@ config SOC_SERIES_MEC175X select CPU_HAS_FPU select CPU_HAS_ARM_MPU select HAS_SWO - select HAS_MEC5_HAL select SOC_PREP_HOOK if SOC_SERIES_MEC175X diff --git a/soc/microchip/mec/mec175x/soc.h b/soc/microchip/mec/mec175x/soc.h index 93b1987e033b..8174038d8277 100644 --- a/soc/microchip/mec/mec175x/soc.h +++ b/soc/microchip/mec/mec175x/soc.h @@ -13,33 +13,32 @@ #define MCHP_HAS_UART_LSR2 -#include +/* Minimal ARM CMSIS requirements */ +typedef enum { + Reset_IRQn = -15, + NonMaskableInt_IRQn = -14, + HardFault_IRQn = -13, + MemoryManagement_IRQn = -12, + BusFault_IRQn = -11, + UsageFault_IRQn = -10, + SVCall_IRQn = -5, + DebugMonitor_IRQn = -4, + PendSV_IRQn = -2, + SysTick_IRQn = -1, + FirstPeriph_IRQn = 0, + LastPeriph_IRQn = 197, +} IRQn_Type; + +#define __CM4_REV 0x0201U /* CM4 Core Revision */ +#define __NVIC_PRIO_BITS 3 /* Number of Bits used for Priority Levels */ +#define __Vendor_SysTickConfig 0 /* Set to 1 if different SysTick Config is used */ +#define __MPU_PRESENT 1 /* MPU present */ +#define __FPU_PRESENT 1 /* FPU present */ + +#include /* common peripheral register defines */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* common SoC API */ -#include -#include -#include -#include -#include -#include -#include +#include #endif #endif From 64c88e9bb317ddaa13ebef640bf6281ea8c7f9d9 Mon Sep 17 00:00:00 2001 From: Dave Lacerte Date: Thu, 22 Jan 2026 08:39:50 -0500 Subject: [PATCH 2510/3659] boards: arduino: portenta_h7 : Update doc about WiFi functionality Removes a forgotten note about the WiFi feature, which is now supported. Signed-off-by: Dave Lacerte --- boards/arduino/portenta_h7/doc/index.rst | 2 -- 1 file changed, 2 deletions(-) diff --git a/boards/arduino/portenta_h7/doc/index.rst b/boards/arduino/portenta_h7/doc/index.rst index b0eca10b6ec4..c4604b28f91f 100644 --- a/boards/arduino/portenta_h7/doc/index.rst +++ b/boards/arduino/portenta_h7/doc/index.rst @@ -36,8 +36,6 @@ information on how to build for specific revisions of the board). Applications that intend to use BLE must specify hardware revision at build time. -Currently only BLE is supported on this board, WiFi is not supported. - Fetch Binary Blobs ****************** From 0f80ee260de73464ca4f783744f6882f93d7a980 Mon Sep 17 00:00:00 2001 From: Thinh Le Cong Date: Wed, 24 Sep 2025 12:43:21 +0700 Subject: [PATCH 2511/3659] drivers: spi: Initial support for SCI SPI driver on Renesas RA Add SCI SPI driver support on Renesas RA devices Signed-off-by: Thinh Le Cong --- drivers/spi/CMakeLists.txt | 1 + drivers/spi/Kconfig.renesas_ra | 27 + drivers/spi/spi_renesas_ra_sci.c | 723 +++++++++++++++++++++++ dts/bindings/spi/renesas,ra-spi-sci.yaml | 13 + modules/Kconfig.renesas | 5 + 5 files changed, 769 insertions(+) create mode 100644 drivers/spi/spi_renesas_ra_sci.c create mode 100644 dts/bindings/spi/renesas,ra-spi-sci.yaml diff --git a/drivers/spi/CMakeLists.txt b/drivers/spi/CMakeLists.txt index ca5652b60acd..c629c45c7046 100644 --- a/drivers/spi/CMakeLists.txt +++ b/drivers/spi/CMakeLists.txt @@ -57,6 +57,7 @@ zephyr_library_sources_ifdef(CONFIG_SPI_PW spi_pw.c) zephyr_library_sources_ifdef(CONFIG_SPI_REALTEK_RTS5912 spi_rts5912_spi.c) zephyr_library_sources_ifdef(CONFIG_SPI_RENESAS_RA spi_renesas_ra.c) zephyr_library_sources_ifdef(CONFIG_SPI_RENESAS_RA8 spi_b_renesas_ra8.c) +zephyr_library_sources_ifdef(CONFIG_SPI_RENESAS_RA_SCI spi_renesas_ra_sci.c) zephyr_library_sources_ifdef(CONFIG_SPI_RENESAS_RA_SCI_B spi_renesas_ra_sci_b.c) zephyr_library_sources_ifdef(CONFIG_SPI_RENESAS_RX spi_renesas_rx.c) zephyr_library_sources_ifdef(CONFIG_SPI_RENESAS_RZ spi_renesas_rz.c) diff --git a/drivers/spi/Kconfig.renesas_ra b/drivers/spi/Kconfig.renesas_ra index 9ad2d670fff8..33aabcccf188 100644 --- a/drivers/spi/Kconfig.renesas_ra +++ b/drivers/spi/Kconfig.renesas_ra @@ -34,6 +34,33 @@ config SPI_USE_HW_SS endif # SPI_RENESAS_RA +config SPI_RENESAS_RA_SCI + bool "Renesas RA SCI SPI" + default y + depends on DT_HAS_RENESAS_RA_SPI_SCI_ENABLED + select SPI_RENESAS_RA_SCI_INTERRUPT if SPI_ASYNC + select USE_RA_FSP_SCI_SPI + select PINCTRL + help + Enable Renesas RA SCI SPI Driver. + +if SPI_RENESAS_RA_SCI + +config SPI_RENESAS_RA_SCI_INTERRUPT + bool "RENESAS RA SCI SPI Interrupt Support" + depends on SPI_ASYNC + help + Enable Interrupt support for the SCI SPI Driver of RA family. + +config SPI_RENESAS_RA_SCI_DTC + bool "RA MCU SCI SPI DTC Support" + depends on SPI_RENESAS_RA_SCI_INTERRUPT + select USE_RA_FSP_DTC + help + Enable DTC support for the SCI SPI Driver of RA family. + +endif # SPI_RENESAS_RA_SCI + config SPI_RENESAS_RA_SCI_B bool "Renesas RA SCI B SPI" default y diff --git a/drivers/spi/spi_renesas_ra_sci.c b/drivers/spi/spi_renesas_ra_sci.c new file mode 100644 index 000000000000..68621b060250 --- /dev/null +++ b/drivers/spi/spi_renesas_ra_sci.c @@ -0,0 +1,723 @@ +/* + * Copyright (c) 2024-2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT renesas_ra_spi_sci + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +LOG_MODULE_REGISTER(renesas_ra_spi_sci); + +#include "spi_context.h" + +struct renesas_ra_sci_spi_config { + const struct pinctrl_dev_config *pcfg; + const struct device *clock_dev; + const struct clock_control_ra_subsys_cfg clock_subsys; + void (*irq_configure)(const struct device *dev); +}; + +struct renesas_ra_sci_spi_data { + struct spi_context ctx; + struct spi_config config; + sci_spi_instance_ctrl_t fsp_ctrl; + spi_cfg_t fsp_cfg; + sci_spi_extended_cfg_t fsp_ext_cfg; + bool is_cs_active_state_same; +#ifdef CONFIG_SPI_RENESAS_RA_SCI_INTERRUPT + uint32_t data_len; +#endif +#ifdef CONFIG_SPI_RENESAS_RA_SCI_DTC + /* RX */ + struct st_transfer_instance rx_transfer; + struct st_dtc_instance_ctrl rx_transfer_ctrl; + struct st_transfer_info rx_transfer_info DTC_TRANSFER_INFO_ALIGNMENT; + struct st_transfer_cfg rx_transfer_cfg; + struct st_dtc_extended_cfg rx_transfer_cfg_extend; + + /* TX */ + struct st_transfer_instance tx_transfer; + struct st_dtc_instance_ctrl tx_transfer_ctrl; + struct st_transfer_info tx_transfer_info DTC_TRANSFER_INFO_ALIGNMENT; + struct st_transfer_cfg tx_transfer_cfg; + struct st_dtc_extended_cfg tx_transfer_cfg_extend; +#endif /* CONFIG_SPI_RENESAS_RA_SCI_DTC */ +}; + +#ifdef CONFIG_SPI_RENESAS_RA_SCI_INTERRUPT +extern void sci_spi_txi_isr(void); +extern void sci_spi_rxi_isr(void); +extern void sci_spi_tei_isr(void); +extern void sci_spi_eri_isr(void); +#endif + +#define CS_GPIO_LOW_WHEN_ACTIVE true +#define CS_GPIO_HIGH_WHEN_ACTIVE false + +#define SCI_RENESAS_RA_IRQ_GET(id, name, cell) \ + COND_CODE_1(DT_IRQ_HAS_NAME(id, name), (DT_IRQ_BY_NAME(id, name, cell)), \ + ((IRQn_Type) FSP_INVALID_VECTOR)) +/* + * This function help to control the cs gpio when changing the CS GPIO active state in + * runtime. + */ +static inline void _renesas_ra_spi_context_cs_control(const struct device *dev, bool on, + bool force_off) +{ + struct renesas_ra_sci_spi_data *data = dev->data; + struct spi_context *ctx = &data->ctx; + + if ((ctx->config) && spi_cs_is_gpio(ctx->config)) { + if (on) { + gpio_pin_set_dt(&ctx->config->cs.gpio, + (data->is_cs_active_state_same) ? 1 : 0); + k_busy_wait(ctx->config->cs.delay); + } else { + if ((!force_off) && (ctx->config->operation & SPI_HOLD_ON_CS)) { + return; + } + k_busy_wait(ctx->config->cs.delay); + gpio_pin_set_dt(&ctx->config->cs.gpio, + (data->is_cs_active_state_same) ? 0 : 1); + } + } +} + +/* + * This function should be called by drivers to control the chip select line in master mode + * in the case of the CS being a GPIO, help to control the cs gpio when changing the CS GPIO + * active state in runtime. + */ +static inline void renesas_ra_spi_context_cs_control(const struct device *dev, bool on) +{ + _renesas_ra_spi_context_cs_control(dev, on, false); +} + +/* + * Forcefully releases the spi context and removes the owner, allowing taking the lock + * with spi_context_lock without the previous owner releasing the lock. + * This function help to control the cs gpio when changing the CS GPIO active state in + * runtime. + */ +static inline void renesas_ra_spi_context_unlock_unconditionally(const struct device *dev) +{ + struct renesas_ra_sci_spi_data *data = dev->data; + struct spi_context *ctx = &data->ctx; + + /* Forcing CS to go to inactive status */ + _renesas_ra_spi_context_cs_control(dev, false, true); + +#ifdef CONFIG_MULTITHREADING + if (!k_sem_count_get(&ctx->lock)) { + ctx->owner = NULL; + k_sem_give(&ctx->lock); + } +#endif /* CONFIG_MULTITHREADING */ +} + +/* Check whether the configuration is similar */ +static inline bool renesas_ra_sci_context_configured(const struct device *dev, + const struct spi_config *config) +{ + struct renesas_ra_sci_spi_data *data = dev->data; + + if ((data->config.frequency == config->frequency) && + (data->config.operation == config->operation) && + (data->config.slave == config->slave)) { + return true; + } + + return false; +} + +#ifdef CONFIG_SPI_RENESAS_RA_SCI_INTERRUPT +static bool renesas_ra_sci_spi_transfer_ongoing(struct renesas_ra_sci_spi_data *data) +{ + return (spi_context_tx_on(&data->ctx) || spi_context_rx_on(&data->ctx)); +} + +static void renesas_ra_sci_spi_retransmit(struct renesas_ra_sci_spi_data *data) +{ + fsp_err_t fsp_err; + + data->data_len = spi_context_max_continuous_chunk(&data->ctx); + + if (data->ctx.rx_buf == NULL) { + fsp_err = R_SCI_SPI_Write(&data->fsp_ctrl, data->ctx.tx_buf, data->data_len, + SPI_BIT_WIDTH_8_BITS); + } else if (data->ctx.tx_buf == NULL) { + fsp_err = R_SCI_SPI_Read(&data->fsp_ctrl, data->ctx.rx_buf, data->data_len, + SPI_BIT_WIDTH_8_BITS); + } else { + fsp_err = R_SCI_SPI_WriteRead(&data->fsp_ctrl, data->ctx.tx_buf, data->ctx.rx_buf, + data->data_len, SPI_BIT_WIDTH_8_BITS); + } + + if (fsp_err != FSP_SUCCESS) { + LOG_ERR("SCI SPI transfer failed %d", fsp_err); + return; + } +} + +static void renesas_ra_sci_spi_callback(spi_callback_args_t *p_args) +{ + struct device *dev = (struct device *)p_args->p_context; + struct renesas_ra_sci_spi_data *data = dev->data; + uint32_t data_receive_len; + + switch (p_args->event) { + case SPI_EVENT_TRANSFER_COMPLETE: + if (!spi_context_is_slave(&data->ctx)) { + if (data->fsp_ctrl.rx_count == data->fsp_ctrl.count || + data->fsp_ctrl.tx_count == data->fsp_ctrl.count) { + + data_receive_len = !!data->fsp_ctrl.rx_count + ? data->fsp_ctrl.rx_count + : data->ctx.rx_len; + + spi_context_update_rx(&data->ctx, 1, data_receive_len); + } + + if (data->fsp_ctrl.tx_count == data->fsp_ctrl.count) { + spi_context_update_tx(&data->ctx, 1, data->data_len); + } + + if (renesas_ra_sci_spi_transfer_ongoing(data)) { + renesas_ra_sci_spi_retransmit(data); + return; + } + } +#ifdef CONFIG_SPI_SLAVE + else if (data->fsp_ctrl.rx_count == data->fsp_ctrl.count) { + if (data->ctx.rx_buf != NULL && data->ctx.tx_buf != NULL) { + data->ctx.recv_frames = MIN(spi_context_total_tx_len(&data->ctx), + spi_context_total_rx_len(&data->ctx)); + } else if (data->ctx.tx_buf == NULL) { + data->ctx.recv_frames = data->data_len; + } else { + /* Do nothing */ + } + } +#endif /* CONFIG_SPI_SLAVE */ + renesas_ra_spi_context_cs_control(dev, false); + spi_context_complete(&data->ctx, dev, 0); + break; + case SPI_EVENT_ERR_READ_OVERFLOW: + renesas_ra_spi_context_cs_control(dev, false); + spi_context_complete(&data->ctx, dev, -EIO); + break; + default: + break; + } +} +#endif + +static int renesas_ra_sci_spi_configure(const struct device *dev, const struct spi_config *config) +{ + struct renesas_ra_sci_spi_data *data = dev->data; + fsp_err_t fsp_err; + + /* Check whether the congiguration is changed */ + if (renesas_ra_sci_context_configured(dev, config)) { + return 0; + } + + if ((config->operation & SPI_FRAME_FORMAT_TI) == SPI_FRAME_FORMAT_TI) { + LOG_ERR("TI frame format is not supported"); + return -ENOTSUP; + } + + if (SPI_MODE_GET(config->operation) & SPI_MODE_LOOP) { + LOG_ERR("Internal hardware loopback is not supported"); + return -ENOTSUP; + } + + if (SPI_WORD_SIZE_GET(config->operation) != 8) { + LOG_ERR("Word sizes other than 8 bits are not supported"); + return -ENOTSUP; + } + + if ((config->operation & SPI_OP_MODE_SLAVE) && !IS_ENABLED(CONFIG_SPI_SLAVE)) { + LOG_ERR("Kconfig for enable SPI in slave mode is not enabled"); + return -ENOTSUP; + } + + if (config->operation & SPI_HALF_DUPLEX) { + LOG_ERR("Half-duplex not supported"); + return -ENOTSUP; + } + + if ((SPI_OP_MODE_GET(config->operation) == SPI_OP_MODE_MASTER) && + (config->frequency == 0)) { + LOG_ERR("Invalid frequency value"); + return -EINVAL; + } + + if (config->frequency > 2500000) { + LOG_ERR("Frequencies more than 2,5 MHz are not supported"); + return -EINVAL; + } + + if (SPI_OP_MODE_GET(config->operation) == SPI_OP_MODE_SLAVE) { + data->fsp_cfg.operating_mode = SPI_MODE_SLAVE; + } else { + data->fsp_cfg.operating_mode = SPI_MODE_MASTER; + } + + if (SPI_MODE_GET(config->operation) & SPI_MODE_CPOL) { + data->fsp_cfg.clk_polarity = SPI_CLK_POLARITY_HIGH; + } else { + data->fsp_cfg.clk_polarity = SPI_CLK_POLARITY_LOW; + } + + if (SPI_MODE_GET(config->operation) & SPI_MODE_CPHA) { + data->fsp_cfg.clk_phase = SPI_CLK_PHASE_EDGE_EVEN; + } else { + data->fsp_cfg.clk_phase = SPI_CLK_PHASE_EDGE_ODD; + } + + if (config->operation & SPI_TRANSFER_LSB) { + data->fsp_cfg.bit_order = SPI_BIT_ORDER_LSB_FIRST; + } else { + data->fsp_cfg.bit_order = SPI_BIT_ORDER_MSB_FIRST; + } + + if (SPI_OP_MODE_GET(config->operation) == SPI_OP_MODE_MASTER) { + fsp_err = R_SCI_SPI_CalculateBitrate(config->frequency, &data->fsp_ext_cfg.clk_div, + true); + if (fsp_err != FSP_SUCCESS) { + return -EINVAL; + } + } + + data->fsp_cfg.p_extend = &data->fsp_ext_cfg; +#ifdef CONFIG_SPI_RENESAS_RA_SCI_INTERRUPT + data->fsp_cfg.p_callback = renesas_ra_sci_spi_callback; +#else + data->fsp_cfg.p_callback = NULL; +#endif /* CONFIG_SPI_RENESAS_RA_SCI_INTERRUPT */ + data->fsp_cfg.p_context = (void *)dev; + + if (data->fsp_ctrl.open != 0) { + fsp_err = R_SCI_SPI_Close(&data->fsp_ctrl); + if (fsp_err != FSP_SUCCESS) { + return -EIO; + } + + memset(&data->config, 0, sizeof(struct spi_config)); + } + + fsp_err = R_SCI_SPI_Open(&data->fsp_ctrl, &data->fsp_cfg); + if (fsp_err != FSP_SUCCESS) { + LOG_ERR("Failed to apply spi configuration"); + return -EINVAL; + } + + memcpy(&data->config, config, sizeof(struct spi_config)); + data->ctx.config = &data->config; + + return 0; +} + +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 asynchronous, spi_callback_t cb, void *userdata) +{ + struct renesas_ra_sci_spi_data *data = dev->data; + bool cs_gpio_logic_when_active; + bool cs_active_logic_config; + int ret; + fsp_err_t fsp_err; +#ifndef CONFIG_SPI_RENESAS_RA_SCI_INTERRUPT + size_t len; +#endif + + if (!tx_bufs && !rx_bufs) { + return 0; + } + +#ifndef CONFIG_SPI_RENESAS_RA_SCI_INTERRUPT + if (asynchronous) { + return -ENOTSUP; + } +#endif /* CONFIG_SPI_RENESAS_RA_SCI_INTERRUPT */ + + spi_context_lock(&data->ctx, asynchronous, cb, userdata, config); + + ret = renesas_ra_sci_spi_configure(dev, config); + if (ret) { + goto release; + } + + /* + * For SCI SPI, the hardware only supports 8-bit frames, + * so the data frame size must be 1 byte + */ + spi_context_buffers_setup(&data->ctx, tx_bufs, rx_bufs, 1); + + /* + * The GPIO flags GPIO_ACTIVE_LOW/GPIO_ACTIVE_HIGH should be equivalent + * to SPI_CS_ACTIVE_HIGH/SPI_CS_ACTIVE_LOW options in struct spi_config. + * In runtime, there are some peripherals that need the CS level contrast + * to the CS defined in the device tree to make some actions such as + * initialization. Ex: PMOD SD_CARD + */ + cs_gpio_logic_when_active = !!(data->ctx.config->cs.gpio.dt_flags & GPIO_ACTIVE_LOW) + ? CS_GPIO_LOW_WHEN_ACTIVE + : CS_GPIO_HIGH_WHEN_ACTIVE; + cs_active_logic_config = !!(data->ctx.config->operation & SPI_CS_ACTIVE_HIGH) + ? CS_GPIO_HIGH_WHEN_ACTIVE + : CS_GPIO_LOW_WHEN_ACTIVE; + if (cs_gpio_logic_when_active == cs_active_logic_config) { + data->is_cs_active_state_same = true; + } else { + data->is_cs_active_state_same = false; + } + + renesas_ra_spi_context_cs_control(dev, true); + + /* If current buffer has no data, do nothing */ + if (!spi_context_tx_buf_on(&data->ctx) && !spi_context_rx_buf_on(&data->ctx)) { + goto release; + } + +#ifdef CONFIG_SPI_RENESAS_RA_SCI_INTERRUPT + if (data->ctx.rx_len == 0) { + data->data_len = spi_context_is_slave(&data->ctx) + ? spi_context_total_tx_len(&data->ctx) + : data->ctx.tx_len; + } else if (data->ctx.tx_len == 0) { + data->data_len = spi_context_is_slave(&data->ctx) + ? spi_context_total_rx_len(&data->ctx) + : data->ctx.rx_len; + } else { + data->data_len = spi_context_is_slave(&data->ctx) + ? MAX(spi_context_total_tx_len(&data->ctx), + spi_context_total_rx_len(&data->ctx)) + : MIN(data->ctx.tx_len, data->ctx.rx_len); + } + + if (data->ctx.rx_buf == NULL) { + fsp_err = R_SCI_SPI_Write(&data->fsp_ctrl, data->ctx.tx_buf, data->data_len, + SPI_BIT_WIDTH_8_BITS); + } else if (data->ctx.tx_buf == NULL) { + fsp_err = R_SCI_SPI_Read(&data->fsp_ctrl, data->ctx.rx_buf, data->data_len, + SPI_BIT_WIDTH_8_BITS); + } else { + fsp_err = R_SCI_SPI_WriteRead(&data->fsp_ctrl, data->ctx.tx_buf, data->ctx.rx_buf, + data->data_len, SPI_BIT_WIDTH_8_BITS); + } + + if (fsp_err != FSP_SUCCESS) { + ret = -EIO; + goto release; + } + + ret = spi_context_wait_for_completion(&data->ctx); +#else + fsp_err = RP_SCI_SPI_StartTransferPolling(&data->fsp_ctrl); + if (fsp_err != FSP_SUCCESS) { + ret = -EIO; + goto release; + } + + while (spi_context_tx_on(&data->ctx) || spi_context_rx_on(&data->ctx)) { + size_t tx_len = data->ctx.tx_len; + size_t rx_len = data->ctx.rx_len; + + len = MIN(tx_len, rx_len); + if (len > 0) { + fsp_err = RP_SCI_SPI_WriteReadPolling(&data->fsp_ctrl, data->ctx.tx_buf, + data->ctx.rx_buf, len); + if (fsp_err != FSP_SUCCESS) { + ret = -EIO; + break; + } + + if (spi_context_tx_buf_on(&data->ctx)) { + spi_context_update_tx(&data->ctx, 1, len); + } + + if (spi_context_rx_on(&data->ctx)) { + spi_context_update_rx(&data->ctx, 1, len); + } + } + + if (spi_context_tx_on(&data->ctx) && !spi_context_rx_on(&data->ctx)) { + fsp_err = RP_SCI_SPI_WritePolling(&data->fsp_ctrl, data->ctx.tx_buf, + data->ctx.tx_len); + if (fsp_err != FSP_SUCCESS) { + ret = -EIO; + break; + } + + spi_context_update_tx(&data->ctx, 1, data->ctx.tx_len); + } + + if (spi_context_rx_on(&data->ctx) && !spi_context_tx_on(&data->ctx)) { + fsp_err = RP_SCI_SPI_ReadPolling(&data->fsp_ctrl, data->ctx.rx_buf, + data->ctx.rx_len); + if (fsp_err != FSP_SUCCESS) { + ret = -EIO; + break; + } + + spi_context_update_rx(&data->ctx, 1, data->ctx.rx_len); + } + } + + fsp_err = RP_SCI_SPI_EndTransferPolling(&data->fsp_ctrl); + if (fsp_err != FSP_SUCCESS) { + ret = -EIO; + } + + spi_context_complete(&data->ctx, dev, ret); +#endif /* CONFIG_SPI_RENESAS_RA_SCI_INTERRUPT */ + +#ifdef CONFIG_SPI_SLAVE + if (spi_context_is_slave(&data->ctx) && !ret) { + ret = data->ctx.recv_frames; + } +#endif /* CONFIG_SPI_SLAVE */ + +release: + if ((ret < 0) || !IS_ENABLED(CONFIG_SPI_RENESAS_RA_SCI_INTERRUPT)) { + renesas_ra_spi_context_cs_control(dev, false); + } + + spi_context_release(&data->ctx, ret); + + return ret; +} + +static int renesas_ra_sci_spi_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 renesas_ra_sci_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, spi_callback_t cb, + void *userdata) +{ + return transceive(dev, config, tx_bufs, rx_bufs, true, cb, userdata); +} +#endif /* CONFIG_SPI_ASYNC */ + +static int renesas_ra_sci_spi_release(const struct device *dev, const struct spi_config *config) +{ + ARG_UNUSED(config); + renesas_ra_spi_context_unlock_unconditionally(dev); + + return 0; +} + +static int renesas_ra_sci_spi_init(const struct device *dev) +{ + const struct renesas_ra_sci_spi_config *config = dev->config; + struct renesas_ra_sci_spi_data *data = dev->data; + const struct device *clock_dev = config->clock_dev; + int ret; +#ifdef DT_SPI_CTX_HAS_NO_CS_GPIOS + ARG_UNUSED(data); +#endif + +#ifdef CONFIG_SPI_RENESAS_RA_SCI_DTC + data->fsp_cfg.p_transfer_rx = &data->rx_transfer; + data->fsp_cfg.p_transfer_tx = &data->tx_transfer; +#endif + + if (!device_is_ready(clock_dev)) { + return -ENODEV; + } + + ret = clock_control_on(config->clock_dev, (clock_control_subsys_t)&config->clock_subsys); + if (ret < 0) { + return ret; + } + + ret = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT); + if (ret < 0) { + return ret; + } + + ret = spi_context_cs_configure_all(&data->ctx); + if (ret < 0) { + return ret; + } + + config->irq_configure(dev); + + renesas_ra_spi_context_unlock_unconditionally(dev); + + return 0; +} + +static DEVICE_API(spi, renesas_ra_sci_spi_driver_api) = { + .transceive = renesas_ra_sci_spi_transceive, +#ifdef CONFIG_SPI_ASYNC + .transceive_async = renesas_ra_sci_spi_transceive_async, +#endif /* CONFIG_SPI_ASYNC */ + .release = renesas_ra_sci_spi_release, +}; + +#define EVENT_SCI_RXI(channel) BSP_PRV_IELS_ENUM(CONCAT(EVENT_SCI, channel, _RXI)) +#define EVENT_SCI_TXI(channel) BSP_PRV_IELS_ENUM(CONCAT(EVENT_SCI, channel, _TXI)) +#define EVENT_SCI_TEI(channel) BSP_PRV_IELS_ENUM(CONCAT(EVENT_SCI, channel, _TEI)) +#define EVENT_SCI_ERI(channel) BSP_PRV_IELS_ENUM(CONCAT(EVENT_SCI, channel, _ERI)) + +#ifdef CONFIG_SPI_RENESAS_RA_SCI_INTERRUPT + +#define RENESAS_RA_IRQ_CONFIG_FUNC(index) \ + static void sci_spi_config_func_##index(const struct device *dev) \ + { \ + ARG_UNUSED(dev); \ + \ + R_ICU->IELSR[DT_IRQ_BY_NAME(DT_INST_PARENT(index), rxi, irq)] = \ + EVENT_SCI_RXI(DT_INST_PROP(index, channel)); \ + R_ICU->IELSR[DT_IRQ_BY_NAME(DT_INST_PARENT(index), txi, irq)] = \ + EVENT_SCI_TXI(DT_INST_PROP(index, channel)); \ + R_ICU->IELSR[DT_IRQ_BY_NAME(DT_INST_PARENT(index), tei, irq)] = \ + EVENT_SCI_TEI(DT_INST_PROP(index, channel)); \ + R_ICU->IELSR[DT_IRQ_BY_NAME(DT_INST_PARENT(index), eri, irq)] = \ + EVENT_SCI_ERI(DT_INST_PROP(index, channel)); \ + \ + IRQ_CONNECT(DT_IRQ_BY_NAME(DT_INST_PARENT(index), rxi, irq), \ + DT_IRQ_BY_NAME(DT_INST_PARENT(index), rxi, priority), sci_spi_rxi_isr, \ + DEVICE_DT_INST_GET(index), 0); \ + IRQ_CONNECT(DT_IRQ_BY_NAME(DT_INST_PARENT(index), txi, irq), \ + DT_IRQ_BY_NAME(DT_INST_PARENT(index), txi, priority), sci_spi_txi_isr, \ + DEVICE_DT_INST_GET(index), 0); \ + IRQ_CONNECT(DT_IRQ_BY_NAME(DT_INST_PARENT(index), tei, irq), \ + DT_IRQ_BY_NAME(DT_INST_PARENT(index), tei, priority), sci_spi_tei_isr, \ + DEVICE_DT_INST_GET(index), 0); \ + IRQ_CONNECT(DT_IRQ_BY_NAME(DT_INST_PARENT(index), eri, irq), \ + DT_IRQ_BY_NAME(DT_INST_PARENT(index), eri, priority), sci_spi_eri_isr, \ + DEVICE_DT_INST_GET(index), 0); \ + \ + irq_enable(DT_IRQ_BY_NAME(DT_INST_PARENT(index), rxi, irq)); \ + irq_enable(DT_IRQ_BY_NAME(DT_INST_PARENT(index), txi, irq)); \ + irq_enable(DT_IRQ_BY_NAME(DT_INST_PARENT(index), eri, irq)); \ + irq_enable(DT_IRQ_BY_NAME(DT_INST_PARENT(index), tei, irq)); \ + } +#else + +#define RENESAS_RA_IRQ_CONFIG_FUNC(index) \ + static void sci_spi_config_func_##index(const struct device *dev) \ + { \ + } +#endif + +/* clang-format off */ + +#ifndef CONFIG_SPI_RENESAS_RA_SCI_DTC +#define RA_SCI_SPI_DTC_STRUCT_INIT(index) +#else +#define RA_SCI_SPI_DTC_STRUCT_INIT(index) \ + .rx_transfer_info = { \ + .transfer_settings_word_b.dest_addr_mode = TRANSFER_ADDR_MODE_INCREMENTED, \ + .transfer_settings_word_b.repeat_area = TRANSFER_REPEAT_AREA_DESTINATION, \ + .transfer_settings_word_b.irq = TRANSFER_IRQ_END, \ + .transfer_settings_word_b.chain_mode = TRANSFER_CHAIN_MODE_DISABLED, \ + .transfer_settings_word_b.src_addr_mode = TRANSFER_ADDR_MODE_FIXED, \ + .transfer_settings_word_b.size = TRANSFER_SIZE_1_BYTE, \ + .transfer_settings_word_b.mode = TRANSFER_MODE_NORMAL, \ + .p_dest = (void *)NULL, \ + .p_src = (void const *)NULL, \ + .num_blocks = 0, \ + .length = 0, \ + }, \ + .rx_transfer_cfg_extend = { \ + .activation_source = DT_IRQ_BY_NAME(DT_INST_PARENT(index), rxi, irq), \ + }, \ + .rx_transfer_cfg = { \ + .p_info = &renesas_ra_sci_spi_data_##index.rx_transfer_info, \ + .p_extend = &renesas_ra_sci_spi_data_##index.rx_transfer_cfg_extend, \ + }, \ + .rx_transfer = { \ + .p_ctrl = &renesas_ra_sci_spi_data_##index.rx_transfer_ctrl, \ + .p_cfg = &renesas_ra_sci_spi_data_##index.rx_transfer_cfg, \ + .p_api = &g_transfer_on_dtc, \ + }, \ + .tx_transfer_info = { \ + .transfer_settings_word_b.dest_addr_mode = TRANSFER_ADDR_MODE_FIXED, \ + .transfer_settings_word_b.repeat_area = TRANSFER_REPEAT_AREA_SOURCE, \ + .transfer_settings_word_b.irq = TRANSFER_IRQ_END, \ + .transfer_settings_word_b.chain_mode = TRANSFER_CHAIN_MODE_DISABLED, \ + .transfer_settings_word_b.src_addr_mode = TRANSFER_ADDR_MODE_INCREMENTED, \ + .transfer_settings_word_b.size = TRANSFER_SIZE_1_BYTE, \ + .transfer_settings_word_b.mode = TRANSFER_MODE_NORMAL, \ + .p_dest = (void *)NULL, \ + .p_src = (void const *)NULL, \ + .num_blocks = 0, \ + .length = 0, \ + }, \ + .tx_transfer_cfg_extend = { \ + .activation_source = DT_IRQ_BY_NAME(DT_INST_PARENT(index), txi, irq), \ + }, \ + .tx_transfer_cfg = { \ + .p_info = &renesas_ra_sci_spi_data_##index.tx_transfer_info, \ + .p_extend = &renesas_ra_sci_spi_data_##index.tx_transfer_cfg_extend, \ + }, \ + .tx_transfer = { \ + .p_ctrl = &renesas_ra_sci_spi_data_##index.tx_transfer_ctrl, \ + .p_cfg = &renesas_ra_sci_spi_data_##index.tx_transfer_cfg, \ + .p_api = &g_transfer_on_dtc, \ + }, +#endif + +#define RENESAS_RA_SPI_SCI_INIT(index) \ + RENESAS_RA_IRQ_CONFIG_FUNC(index) \ + PINCTRL_DT_DEFINE(DT_INST_PARENT(index)); \ + \ + static const struct renesas_ra_sci_spi_config renesas_ra_sci_spi_config_##index = { \ + .pcfg = PINCTRL_DT_DEV_CONFIG_GET(DT_INST_PARENT(index)), \ + .clock_dev = DEVICE_DT_GET(DT_CLOCKS_CTLR(DT_INST_PARENT(index))), \ + .clock_subsys = { \ + .mstp = DT_CLOCKS_CELL_BY_IDX(DT_INST_PARENT(index), 0, mstp), \ + .stop_bit = DT_CLOCKS_CELL_BY_IDX(DT_INST_PARENT(index), 0, stop_bit), \ + }, \ + .irq_configure = sci_spi_config_func_##index, \ + }; \ + \ + static struct renesas_ra_sci_spi_data renesas_ra_sci_spi_data_##index = { \ + .is_cs_active_state_same = true, \ + .fsp_cfg = { \ + .channel = DT_INST_PROP(index, channel), \ + .rxi_ipl = SCI_RENESAS_RA_IRQ_GET(DT_INST_PARENT(index), rxi, priority), \ + .rxi_irq = SCI_RENESAS_RA_IRQ_GET(DT_INST_PARENT(index), rxi, irq), \ + .txi_ipl = SCI_RENESAS_RA_IRQ_GET(DT_INST_PARENT(index), txi, priority), \ + .txi_irq = SCI_RENESAS_RA_IRQ_GET(DT_INST_PARENT(index), txi, irq), \ + .tei_ipl = SCI_RENESAS_RA_IRQ_GET(DT_INST_PARENT(index), tei, priority), \ + .tei_irq = SCI_RENESAS_RA_IRQ_GET(DT_INST_PARENT(index), tei, irq), \ + .eri_ipl = SCI_RENESAS_RA_IRQ_GET(DT_INST_PARENT(index), eri, priority), \ + .eri_irq = SCI_RENESAS_RA_IRQ_GET(DT_INST_PARENT(index), eri, irq), \ + }, \ + SPI_CONTEXT_INIT_LOCK(renesas_ra_sci_spi_data_##index, ctx), \ + SPI_CONTEXT_INIT_SYNC(renesas_ra_sci_spi_data_##index, ctx), \ + SPI_CONTEXT_CS_GPIOS_INITIALIZE(DT_DRV_INST(index), ctx) \ + RA_SCI_SPI_DTC_STRUCT_INIT(index) \ + }; \ + \ + SPI_DEVICE_DT_INST_DEFINE(index, renesas_ra_sci_spi_init, NULL, \ + &renesas_ra_sci_spi_data_##index, \ + &renesas_ra_sci_spi_config_##index, POST_KERNEL, \ + CONFIG_SPI_INIT_PRIORITY, &renesas_ra_sci_spi_driver_api); + +/* clang-format on */ + +DT_INST_FOREACH_STATUS_OKAY(RENESAS_RA_SPI_SCI_INIT) diff --git a/dts/bindings/spi/renesas,ra-spi-sci.yaml b/dts/bindings/spi/renesas,ra-spi-sci.yaml new file mode 100644 index 000000000000..8a814a18dcfd --- /dev/null +++ b/dts/bindings/spi/renesas,ra-spi-sci.yaml @@ -0,0 +1,13 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +description: Renesas RA SCI SPI controller + +compatible: "renesas,ra-spi-sci" + +include: [spi-controller.yaml, pinctrl-device.yaml] + +properties: + channel: + type: int + required: true diff --git a/modules/Kconfig.renesas b/modules/Kconfig.renesas index 25870af170e0..37f07a830057 100644 --- a/modules/Kconfig.renesas +++ b/modules/Kconfig.renesas @@ -134,6 +134,11 @@ config USE_RA_FSP_SPI_B help Enable RA FSP SPI-B driver +config USE_RA_FSP_SCI_SPI + bool + help + Enable RA FSP SCI SPI driver + config USE_RA_FSP_SCI_B_SPI bool help From 642127e1d744465adc0bba2c964ac23973314d0c Mon Sep 17 00:00:00 2001 From: Thinh Le Cong Date: Wed, 24 Sep 2025 12:50:51 +0700 Subject: [PATCH 2512/3659] dts: arm: renesas: add SCI SPI node for Renesas RA Add SCI SPI nodes for Renesas RA SoCs Signed-off-by: Thinh Le Cong --- dts/arm/renesas/ra/ra2/ra2l1.dtsi | 45 +++++++++++++ dts/arm/renesas/ra/ra2/ra2xx.dtsi | 27 ++++++++ dts/arm/renesas/ra/ra4/r7fa4e10x.dtsi | 18 ++++++ dts/arm/renesas/ra/ra4/r7fa4l1bx.dtsi | 54 ++++++++++++++++ dts/arm/renesas/ra/ra4/r7fa4m1ax.dtsi | 9 +++ dts/arm/renesas/ra/ra4/r7fa4m2ax.dtsi | 36 +++++++++++ dts/arm/renesas/ra/ra4/r7fa4m3ax.dtsi | 36 +++++++++++ dts/arm/renesas/ra/ra4/r7fa4w1ad2cng.dtsi | 9 +++ dts/arm/renesas/ra/ra4/ra4-cm33-common.dtsi | 18 ++++++ dts/arm/renesas/ra/ra4/ra4-cm4-common.dtsi | 27 ++++++++ dts/arm/renesas/ra/ra6/r7fa6e10x.dtsi | 36 +++++++++++ dts/arm/renesas/ra/ra6/r7fa6m2ax.dtsi | 27 ++++++++ dts/arm/renesas/ra/ra6/r7fa6m3ax.dtsi | 33 +++++++++- dts/arm/renesas/ra/ra6/r7fa6m4ax.dtsi | 72 +++++++++++++++++++++ dts/arm/renesas/ra/ra6/r7fa6m5xh.dtsi | 72 +++++++++++++++++++++ dts/arm/renesas/ra/ra6/ra6-cm33-common.dtsi | 18 ++++++ dts/arm/renesas/ra/ra6/ra6-cm4-common.dtsi | 63 ++++++++++++++++++ 17 files changed, 597 insertions(+), 3 deletions(-) diff --git a/dts/arm/renesas/ra/ra2/ra2l1.dtsi b/dts/arm/renesas/ra/ra2/ra2l1.dtsi index 53bb8257108e..475d1f05b994 100644 --- a/dts/arm/renesas/ra/ra2/ra2l1.dtsi +++ b/dts/arm/renesas/ra/ra2/ra2l1.dtsi @@ -189,6 +189,15 @@ channel = <0>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <0>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci1: sci1@40070020 { @@ -210,6 +219,15 @@ channel = <1>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <1>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci2: sci2@40070040 { @@ -231,6 +249,15 @@ channel = <2>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <2>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci3: sci3@40070060 { @@ -252,6 +279,15 @@ channel = <3>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <3>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci9: sci9@40070120 { @@ -275,6 +311,15 @@ channel = <9>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <9>; + overrun-character = <0x00>; + status = "disabled"; + }; }; wdt: wdt@40044200 { diff --git a/dts/arm/renesas/ra/ra2/ra2xx.dtsi b/dts/arm/renesas/ra/ra2/ra2xx.dtsi index 2a52836e01ef..a041db7a99f4 100644 --- a/dts/arm/renesas/ra/ra2/ra2xx.dtsi +++ b/dts/arm/renesas/ra/ra2/ra2xx.dtsi @@ -166,6 +166,15 @@ channel = <0>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <0>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci1: sci@40070020 { @@ -189,6 +198,15 @@ channel = <1>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <1>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci2: sci@40070040 { @@ -258,6 +276,15 @@ channel = <9>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <9>; + overrun-character = <0x00>; + status = "disabled"; + }; }; spi0: spi@40072000 { diff --git a/dts/arm/renesas/ra/ra4/r7fa4e10x.dtsi b/dts/arm/renesas/ra/ra4/r7fa4e10x.dtsi index b184c7fbf88b..66a5756857b9 100644 --- a/dts/arm/renesas/ra/ra4/r7fa4e10x.dtsi +++ b/dts/arm/renesas/ra/ra4/r7fa4e10x.dtsi @@ -43,6 +43,15 @@ channel = <3>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <3>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci4: sci4@40118400 { @@ -64,6 +73,15 @@ channel = <4>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <4>; + overrun-character = <0x00>; + status = "disabled"; + }; }; adc@40170000 { diff --git a/dts/arm/renesas/ra/ra4/r7fa4l1bx.dtsi b/dts/arm/renesas/ra/ra4/r7fa4l1bx.dtsi index a22606f22921..ae03e9884519 100644 --- a/dts/arm/renesas/ra/ra4/r7fa4l1bx.dtsi +++ b/dts/arm/renesas/ra/ra4/r7fa4l1bx.dtsi @@ -178,6 +178,15 @@ channel = <0>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <0>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci1: sci@40118100 { @@ -199,6 +208,15 @@ channel = <1>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <1>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci3: sci@40118300 { @@ -220,6 +238,15 @@ channel = <3>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <3>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci4: sci@40118400 { @@ -241,6 +268,15 @@ channel = <4>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <4>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci5: sci@40118500 { @@ -264,6 +300,15 @@ channel = <5>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <5>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci9: sci@40118900 { @@ -287,6 +332,15 @@ channel = <9>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <9>; + overrun-character = <0x00>; + status = "disabled"; + }; }; spi0: spi@4011a000 { diff --git a/dts/arm/renesas/ra/ra4/r7fa4m1ax.dtsi b/dts/arm/renesas/ra/ra4/r7fa4m1ax.dtsi index 628fc8c442b6..d65d309dbb50 100644 --- a/dts/arm/renesas/ra/ra4/r7fa4m1ax.dtsi +++ b/dts/arm/renesas/ra/ra4/r7fa4m1ax.dtsi @@ -66,6 +66,15 @@ channel = <2>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <2>; + overrun-character = <0x00>; + status = "disabled"; + }; }; adc@4005c000 { diff --git a/dts/arm/renesas/ra/ra4/r7fa4m2ax.dtsi b/dts/arm/renesas/ra/ra4/r7fa4m2ax.dtsi index e0c4e598dad8..855907085831 100644 --- a/dts/arm/renesas/ra/ra4/r7fa4m2ax.dtsi +++ b/dts/arm/renesas/ra/ra4/r7fa4m2ax.dtsi @@ -61,6 +61,15 @@ channel = <1>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <1>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci2: sci2@40118200 { @@ -84,6 +93,15 @@ channel = <2>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <2>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci3: sci3@40118300 { @@ -107,6 +125,15 @@ channel = <3>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <3>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci4: sci4@40118400 { @@ -130,6 +157,15 @@ channel = <4>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <4>; + overrun-character = <0x00>; + status = "disabled"; + }; }; adc@40170000 { diff --git a/dts/arm/renesas/ra/ra4/r7fa4m3ax.dtsi b/dts/arm/renesas/ra/ra4/r7fa4m3ax.dtsi index 9bf6ed7324ad..d54d35ec86b2 100644 --- a/dts/arm/renesas/ra/ra4/r7fa4m3ax.dtsi +++ b/dts/arm/renesas/ra/ra4/r7fa4m3ax.dtsi @@ -70,6 +70,15 @@ channel = <1>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <1>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci2: sci2@40118200 { @@ -93,6 +102,15 @@ channel = <2>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <2>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci3: sci3@40118300 { @@ -116,6 +134,15 @@ channel = <3>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <3>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci4: sci4@40118400 { @@ -139,6 +166,15 @@ channel = <4>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <4>; + overrun-character = <0x00>; + status = "disabled"; + }; }; adc@40170000 { diff --git a/dts/arm/renesas/ra/ra4/r7fa4w1ad2cng.dtsi b/dts/arm/renesas/ra/ra4/r7fa4w1ad2cng.dtsi index ab77c8e22a62..991300e792fa 100644 --- a/dts/arm/renesas/ra/ra4/r7fa4w1ad2cng.dtsi +++ b/dts/arm/renesas/ra/ra4/r7fa4w1ad2cng.dtsi @@ -59,6 +59,15 @@ channel = <4>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <4>; + overrun-character = <0x00>; + status = "disabled"; + }; }; trng: trng { diff --git a/dts/arm/renesas/ra/ra4/ra4-cm33-common.dtsi b/dts/arm/renesas/ra/ra4/ra4-cm33-common.dtsi index e181195da0f4..9ff1c7fa9eec 100644 --- a/dts/arm/renesas/ra/ra4/ra4-cm33-common.dtsi +++ b/dts/arm/renesas/ra/ra4/ra4-cm33-common.dtsi @@ -154,6 +154,15 @@ channel = <0>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <0>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci9: sci9@40118900 { @@ -177,6 +186,15 @@ channel = <9>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <9>; + overrun-character = <0x00>; + status = "disabled"; + }; }; spi0: spi@4011a000 { diff --git a/dts/arm/renesas/ra/ra4/ra4-cm4-common.dtsi b/dts/arm/renesas/ra/ra4/ra4-cm4-common.dtsi index 2e70d63e9986..bbed1a4431c2 100644 --- a/dts/arm/renesas/ra/ra4/ra4-cm4-common.dtsi +++ b/dts/arm/renesas/ra/ra4/ra4-cm4-common.dtsi @@ -161,6 +161,15 @@ channel = <0>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <0>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci1: sci1@40070020 { @@ -184,6 +193,15 @@ channel = <1>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <1>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci9: sci9@40070120 { @@ -205,6 +223,15 @@ channel = <9>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <9>; + overrun-character = <0x00>; + status = "disabled"; + }; }; spi0: spi@40072000 { diff --git a/dts/arm/renesas/ra/ra6/r7fa6e10x.dtsi b/dts/arm/renesas/ra/ra6/r7fa6e10x.dtsi index e918669da284..c58f742ed8e8 100644 --- a/dts/arm/renesas/ra/ra6/r7fa6e10x.dtsi +++ b/dts/arm/renesas/ra/ra6/r7fa6e10x.dtsi @@ -60,6 +60,15 @@ channel = <1>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <1>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci2: sci2@40118200 { @@ -83,6 +92,15 @@ channel = <2>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <2>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci3: sci3@40118300 { @@ -106,6 +124,15 @@ channel = <3>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <3>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci4: sci4@40118400 { @@ -129,6 +156,15 @@ channel = <4>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <4>; + overrun-character = <0x00>; + status = "disabled"; + }; }; adc@40170000 { diff --git a/dts/arm/renesas/ra/ra6/r7fa6m2ax.dtsi b/dts/arm/renesas/ra/ra6/r7fa6m2ax.dtsi index 7d209dcf7077..90a22695c300 100644 --- a/dts/arm/renesas/ra/ra6/r7fa6m2ax.dtsi +++ b/dts/arm/renesas/ra/ra6/r7fa6m2ax.dtsi @@ -39,6 +39,15 @@ channel = <5>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <5>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci6: sci6@400700c0 { @@ -60,6 +69,15 @@ channel = <6>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <6>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci7: sci7@400700e0 { @@ -83,6 +101,15 @@ channel = <7>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <7>; + overrun-character = <0x00>; + status = "disabled"; + }; }; iic2: iic2@40053200 { diff --git a/dts/arm/renesas/ra/ra6/r7fa6m3ax.dtsi b/dts/arm/renesas/ra/ra6/r7fa6m3ax.dtsi index 9e892aff69b6..6b79034a09c1 100644 --- a/dts/arm/renesas/ra/ra6/r7fa6m3ax.dtsi +++ b/dts/arm/renesas/ra/ra6/r7fa6m3ax.dtsi @@ -58,7 +58,7 @@ sci5: sci5@400700a0 { compatible = "renesas,ra-sci"; - interrupts = <20 1>, <21 1>, <22 1>, <23 1>; + interrupts = <92 1>, <93 1>, <94 1>, <95 1>; interrupt-names = "rxi", "txi", "tei", "eri"; reg = <0x400700a0 0x20>; clocks = <&pclka MSTPB 26>; @@ -77,11 +77,20 @@ channel = <5>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <5>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci6: sci6@400700c0 { compatible = "renesas,ra-sci"; - interrupts = <24 1>, <25 1>, <26 1>, <27 1>; + interrupts = <88 1>, <89 1>, <90 1>, <91 1>; interrupt-names = "rxi", "txi", "tei", "eri"; reg = <0x400700c0 0x20>; clocks = <&pclka MSTPB 25>; @@ -100,11 +109,20 @@ channel = <6>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <6>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci7: sci7@400700e0 { compatible = "renesas,ra-sci"; - interrupts = <28 1>, <29 1>, <30 1>, <31 1>; + interrupts = <84 1>, <85 1>, <86 1>, <87 1>; interrupt-names = "rxi", "txi", "tei", "eri"; reg = <0x400700e0 0x20>; clocks = <&pclka MSTPB 24>; @@ -123,6 +141,15 @@ channel = <7>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <7>; + overrun-character = <0x00>; + status = "disabled"; + }; }; iic2: iic2@40053200 { diff --git a/dts/arm/renesas/ra/ra6/r7fa6m4ax.dtsi b/dts/arm/renesas/ra/ra6/r7fa6m4ax.dtsi index cfd22d2ab8bc..8ae93bd7bc4d 100644 --- a/dts/arm/renesas/ra/ra6/r7fa6m4ax.dtsi +++ b/dts/arm/renesas/ra/ra6/r7fa6m4ax.dtsi @@ -37,6 +37,15 @@ channel = <1>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <1>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci2: sci2@40118200 { @@ -60,6 +69,15 @@ channel = <2>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <2>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci3: sci3@40118300 { @@ -83,6 +101,15 @@ channel = <3>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <3>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci4: sci4@40118400 { @@ -106,6 +133,15 @@ channel = <4>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <4>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci5: sci5@40118500 { @@ -129,6 +165,15 @@ channel = <5>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <5>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci6: sci6@40118600 { @@ -152,6 +197,15 @@ channel = <6>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <6>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci7: sci7@40118700 { @@ -175,6 +229,15 @@ channel = <7>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <7>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci8: sci8@40118800 { @@ -198,6 +261,15 @@ channel = <8>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <8>; + overrun-character = <0x00>; + status = "disabled"; + }; }; adc@40170000 { diff --git a/dts/arm/renesas/ra/ra6/r7fa6m5xh.dtsi b/dts/arm/renesas/ra/ra6/r7fa6m5xh.dtsi index 6cbc0c6f4117..538418e941bd 100644 --- a/dts/arm/renesas/ra/ra6/r7fa6m5xh.dtsi +++ b/dts/arm/renesas/ra/ra6/r7fa6m5xh.dtsi @@ -97,6 +97,15 @@ channel = <1>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <1>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci2: sci2@40118200 { @@ -120,6 +129,15 @@ channel = <2>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <2>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci3: sci3@40118300 { @@ -143,6 +161,15 @@ channel = <3>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <3>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci4: sci4@40118400 { @@ -166,6 +193,15 @@ channel = <4>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <4>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci5: sci5@40118500 { @@ -189,6 +225,15 @@ channel = <5>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <5>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci6: sci6@40118600 { @@ -212,6 +257,15 @@ channel = <6>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <6>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci7: sci7@40118700 { @@ -235,6 +289,15 @@ channel = <7>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <7>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci8: sci8@40118800 { @@ -258,6 +321,15 @@ channel = <8>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <8>; + overrun-character = <0x00>; + status = "disabled"; + }; }; iic2: iic2@4009f200 { diff --git a/dts/arm/renesas/ra/ra6/ra6-cm33-common.dtsi b/dts/arm/renesas/ra/ra6/ra6-cm33-common.dtsi index 44537c60b809..2138c46fa4dd 100644 --- a/dts/arm/renesas/ra/ra6/ra6-cm33-common.dtsi +++ b/dts/arm/renesas/ra/ra6/ra6-cm33-common.dtsi @@ -145,6 +145,15 @@ channel = <0>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <0>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci9: sci9@40118900 { @@ -168,6 +177,15 @@ channel = <9>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <9>; + overrun-character = <0x00>; + status = "disabled"; + }; }; iic0: iic0@4009f000 { diff --git a/dts/arm/renesas/ra/ra6/ra6-cm4-common.dtsi b/dts/arm/renesas/ra/ra6/ra6-cm4-common.dtsi index 8a5f28691373..2fa4568f5d5e 100644 --- a/dts/arm/renesas/ra/ra6/ra6-cm4-common.dtsi +++ b/dts/arm/renesas/ra/ra6/ra6-cm4-common.dtsi @@ -163,6 +163,15 @@ channel = <0>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <0>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci1: sci1@40070020 { @@ -184,6 +193,15 @@ channel = <1>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <1>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci2: sci2@40070040 { @@ -205,6 +223,15 @@ channel = <2>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <2>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci3: sci3@40070060 { @@ -226,6 +253,15 @@ channel = <3>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <3>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci4: sci4@40070080 { @@ -247,6 +283,15 @@ channel = <4>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <4>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci8: sci8@40070100 { @@ -270,6 +315,15 @@ channel = <8>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <8>; + overrun-character = <0x00>; + status = "disabled"; + }; }; sci9: sci9@40070120 { @@ -293,6 +347,15 @@ channel = <9>; status = "disabled"; }; + + spi { + compatible = "renesas,ra-spi-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <9>; + overrun-character = <0x00>; + status = "disabled"; + }; }; iic0: iic0@40053000 { From 0c950801d37c3473c58fce7fba3ac39ae367010d Mon Sep 17 00:00:00 2001 From: Kevin Chan Date: Fri, 12 Dec 2025 14:51:57 -0800 Subject: [PATCH 2513/3659] drivers: sdhc: add SDHC driver for PSE84 & cy8cproto_062_4343w - add SDHC driver code to support both SDMMC and SDIO fucntion - add SDHC dts node and Kconfig - add clock configuration for SDHC Signed-off-by: Kevin Chan --- .../cy8cproto_062_4343w.dts | 13 + .../infineon/kit_pse84_eval/kconfig.defconfig | 30 + .../kit_pse84_eval_common-pinctrl.dtsi | 72 ++ .../kit_pse84_eval/kit_pse84_eval_common.dtsi | 8 + .../kit_pse84_eval/kit_pse84_eval_m55.dts | 65 + .../kit_pse84_eval/kit_pse84_eval_m55.yaml | 1 + .../clock_control_infineon_peri_clock.c | 27 + drivers/sdhc/CMakeLists.txt | 2 +- drivers/sdhc/Kconfig.infineon | 24 +- drivers/sdhc/infineon_sdio.c | 341 ----- drivers/sdhc/sdhc_infineon.c | 1141 +++++++++++++++++ drivers/wifi/infineon/Kconfig.airoc | 10 +- dts/bindings/sdhc/infineon,sdhc-sdio.yaml | 25 +- modules/hal_infineon/CMakeLists.txt | 7 +- 14 files changed, 1406 insertions(+), 360 deletions(-) create mode 100644 boards/infineon/kit_pse84_eval/kconfig.defconfig delete mode 100644 drivers/sdhc/infineon_sdio.c create mode 100644 drivers/sdhc/sdhc_infineon.c diff --git a/boards/infineon/cy8cproto_062_4343w/cy8cproto_062_4343w.dts b/boards/infineon/cy8cproto_062_4343w/cy8cproto_062_4343w.dts index 3aefe67c863d..e1014cf7ed23 100644 --- a/boards/infineon/cy8cproto_062_4343w/cy8cproto_062_4343w.dts +++ b/boards/infineon/cy8cproto_062_4343w/cy8cproto_062_4343w.dts @@ -77,6 +77,12 @@ uart2: &scb2 { }; }; +&clk_hf4 { + clock-div = <1>; + clocks = <&fll0>; + status = "okay"; +}; + &sdhc0 { status = "okay"; @@ -85,6 +91,13 @@ uart2: &scb2 { &p2_1_sdio_data1 &p2_2_sdio_data2 &p2_3_sdio_data3>; pinctrl-names = "default"; + bus-width = <4>; + max-bus-freq = <50000000>; + min-bus-freq = <400000>; + power-delay-ms = <1000>; + no-1-8-v; + clocks = <&clk_hf4>; + /* Wi-Fi configuration */ airoc-wifi { status = "okay"; diff --git a/boards/infineon/kit_pse84_eval/kconfig.defconfig b/boards/infineon/kit_pse84_eval/kconfig.defconfig new file mode 100644 index 000000000000..8962ddd2959a --- /dev/null +++ b/boards/infineon/kit_pse84_eval/kconfig.defconfig @@ -0,0 +1,30 @@ +# Copyright (c) 2025 Infineon Technologies AG, +# or an affiliate of Infineon Technologies AG. +# +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_KIT_PSE84_EVAL_PSE846GPS2DBZC4A_M55 + +if WIFI + +# Select AIROC part and module +choice AIROC_PART + default CYW55500 +endchoice + +choice CYW55500_MODULE + default CYW55513IUBG_SM +endchoice + +# Enable L2 Ethernet +config NET_L2_ETHERNET + default y + +# Heap Pool Size +config HEAP_MEM_POOL_ADD_SIZE_BOARD + int + default 15000 + +endif # WIFI + +endif # BOARD_KIT_PSE84_EVAL_PSE846GPS2DBZC4A_M55 diff --git a/boards/infineon/kit_pse84_eval/kit_pse84_eval_common-pinctrl.dtsi b/boards/infineon/kit_pse84_eval/kit_pse84_eval_common-pinctrl.dtsi index e536b8c9b1ed..5faf08fd3a6b 100644 --- a/boards/infineon/kit_pse84_eval/kit_pse84_eval_common-pinctrl.dtsi +++ b/boards/infineon/kit_pse84_eval/kit_pse84_eval_common-pinctrl.dtsi @@ -13,3 +13,75 @@ &p6_5_scb2_uart_rx { input-enable; }; + +&p21_0_sdhc0_card_cmd { + drive-push-pull; + input-enable; + drive-strength = "half"; +}; + +&p12_0_sdhc0_clk_card { + drive-push-pull; + input-enable; + drive-strength = "half"; +}; + +&p12_1_sdhc0_card_dat_3to0 { + drive-push-pull; + input-enable; + drive-strength = "half"; +}; + +&p12_2_sdhc0_card_dat_3to0 { + drive-push-pull; + input-enable; + drive-strength = "half"; +}; + +&p12_4_sdhc0_card_dat_3to0 { + drive-push-pull; + input-enable; + drive-strength = "half"; +}; + +&p12_5_sdhc0_card_dat_3to0 { + drive-push-pull; + input-enable; + drive-strength = "half"; +}; + +&p7_0_sdhc1_card_cmd { + drive-push-pull; + input-enable; + drive-strength = "half"; +}; + +&p7_1_sdhc1_clk_card { + drive-push-pull; + input-enable; + drive-strength = "half"; +}; + +&p7_3_sdhc1_card_dat_3to0 { + drive-push-pull; + input-enable; + drive-strength = "half"; +}; + +&p7_5_sdhc1_card_dat_3to0 { + drive-push-pull; + input-enable; + drive-strength = "half"; +}; + +&p7_6_sdhc1_card_dat_3to0 { + drive-push-pull; + input-enable; + drive-strength = "half"; +}; + +&p7_7_sdhc1_card_dat_3to0 { + drive-push-pull; + input-enable; + drive-strength = "half"; +}; diff --git a/boards/infineon/kit_pse84_eval/kit_pse84_eval_common.dtsi b/boards/infineon/kit_pse84_eval/kit_pse84_eval_common.dtsi index c4cfcaa1a9e4..307a4861594a 100644 --- a/boards/infineon/kit_pse84_eval/kit_pse84_eval_common.dtsi +++ b/boards/infineon/kit_pse84_eval/kit_pse84_eval_common.dtsi @@ -78,6 +78,10 @@ uart2: &scb2 { status = "okay"; }; +&gpio_prt11 { + status = "okay"; +}; + &gpio_prt13 { status = "okay"; }; @@ -89,3 +93,7 @@ uart2: &scb2 { &gpio_prt16 { status = "okay"; }; + +&gpio_prt17 { + status = "okay"; +}; diff --git a/boards/infineon/kit_pse84_eval/kit_pse84_eval_m55.dts b/boards/infineon/kit_pse84_eval/kit_pse84_eval_m55.dts index 7710376534c5..eed1ea8763f1 100644 --- a/boards/infineon/kit_pse84_eval/kit_pse84_eval_m55.dts +++ b/boards/infineon/kit_pse84_eval/kit_pse84_eval_m55.dts @@ -61,3 +61,68 @@ &mcwdt1 { status = "okay"; }; + +&peri1_group2_8bit_0 { + status = "okay"; + resource-type = ; + resource-instance = <0>; + clock-div = <2>; +}; + +&peri1_group3_8bit_0 { + status = "okay"; + resource-type = ; + resource-instance = <1>; + clock-div = <2>; +}; + +&sdhc0 { + status = "okay"; + + /* SDIO pins */ + pinctrl-0 = <&p21_0_sdhc0_card_cmd &p12_0_sdhc0_clk_card &p12_1_sdhc0_card_dat_3to0 + &p12_2_sdhc0_card_dat_3to0 &p12_4_sdhc0_card_dat_3to0 + &p12_5_sdhc0_card_dat_3to0>; + pinctrl-names = "default"; + + clocks = <&peri1_group2_8bit_0>; + bus-width = <4>; + max-bus-freq = <50000000>; + min-bus-freq = <400000>; + power-delay-ms = <1000>; + no-1-8-v; + + /* Wi-Fi configuration */ + airoc-wifi { + status = "okay"; + compatible = "infineon,airoc-wifi"; + + /* Wi-Fi control gpios */ + wifi-reg-on-gpios = <&gpio_prt11 6 GPIO_ACTIVE_HIGH>; + wifi-host-wake-gpios = <&gpio_prt11 4 GPIO_ACTIVE_HIGH>; + }; +}; + +&sdhc1 { + status = "okay"; + + /* SDHC pins */ + pinctrl-0 = <&p7_0_sdhc1_card_cmd &p7_1_sdhc1_clk_card &p7_3_sdhc1_card_dat_3to0 + &p7_5_sdhc1_card_dat_3to0 &p7_6_sdhc1_card_dat_3to0 + &p7_7_sdhc1_card_dat_3to0>; + pinctrl-names = "default"; + + clocks = <&peri1_group3_8bit_0>; + bus-width = <4>; + max-bus-freq = <100000000>; + min-bus-freq = <400000>; + power-delay-ms = <1000>; + /* Card detect gpios */ + cd-gpios = <&gpio_prt17 7 GPIO_PULL_UP>; + + sdmmc { + compatible = "zephyr,sdmmc-disk"; + disk-name = "SD"; + status = "okay"; + }; +}; diff --git a/boards/infineon/kit_pse84_eval/kit_pse84_eval_m55.yaml b/boards/infineon/kit_pse84_eval/kit_pse84_eval_m55.yaml index ee241e89804b..333e396cb7a3 100644 --- a/boards/infineon/kit_pse84_eval/kit_pse84_eval_m55.yaml +++ b/boards/infineon/kit_pse84_eval/kit_pse84_eval_m55.yaml @@ -18,3 +18,4 @@ supported: - pinctrl - uart - spi + - sdhc diff --git a/drivers/clock_control/clock_control_infineon_peri_clock.c b/drivers/clock_control/clock_control_infineon_peri_clock.c index 9923ab626dd3..858ba4dc52cc 100644 --- a/drivers/clock_control/clock_control_infineon_peri_clock.c +++ b/drivers/clock_control/clock_control_infineon_peri_clock.c @@ -50,6 +50,11 @@ struct ifx_peri_clock_data { #define IFX_SCB5_PCLK_CLOCK PCLK_SCB5_CLOCK_SCB_EN #endif +#if defined(CY_IP_MXSDHC) +#define IFX_SDHC0_PCLK_CLOCK PCLK_SDHC0_CLK_HF +#define IFX_SDHC1_PCLK_CLOCK PCLK_SDHC1_CLK_HF +#endif + #define CLK_FRAC_DIV_MODE 0x02 en_clk_dst_t ifx_cat1_scb_get_clock_index(uint32_t block_num) @@ -101,6 +106,21 @@ en_clk_dst_t ifx_cat1_tcpwm_get_clock_index(uint32_t block_num, uint32_t channel return clk; } +en_clk_dst_t ifx_cat1_sdhc_get_clock_index(uint32_t block_num, uint32_t channel) +{ + en_clk_dst_t clk = -EINVAL; + +#if defined(CY_IP_MXSDHC) + if (block_num == 0) { + clk = (en_clk_dst_t)((uint32_t)IFX_SDHC0_PCLK_CLOCK); + } else { + clk = (en_clk_dst_t)((uint32_t)IFX_SDHC1_PCLK_CLOCK); + } +#endif + + return clk; +} + static int ifx_cat1_peri_clock_init(const struct device *dev) { struct ifx_peri_clock_data *const data = dev->data; @@ -134,6 +154,13 @@ static int ifx_cat1_peri_clock_init(const struct device *dev) en_clk_dst_t clk_idx = ifx_cat1_tcpwm_get_clock_index( data->hw_resource.block_num, data->hw_resource.channel_num); + ifx_cat1_utils_peri_pclk_set_divider(clk_idx, &data->clock, data->divider - 1); + ifx_cat1_utils_peri_pclk_assign_divider(clk_idx, &data->clock); + ifx_cat1_utils_peri_pclk_enable_divider(clk_idx, &data->clock); + } else if (data->hw_resource.type == IFX_RSC_SDHC) { + en_clk_dst_t clk_idx = ifx_cat1_sdhc_get_clock_index(data->hw_resource.block_num, + data->hw_resource.channel_num); + ifx_cat1_utils_peri_pclk_set_divider(clk_idx, &data->clock, data->divider - 1); ifx_cat1_utils_peri_pclk_assign_divider(clk_idx, &data->clock); ifx_cat1_utils_peri_pclk_enable_divider(clk_idx, &data->clock); diff --git a/drivers/sdhc/CMakeLists.txt b/drivers/sdhc/CMakeLists.txt index b2d3229e4a2a..33eda238ecaa 100644 --- a/drivers/sdhc/CMakeLists.txt +++ b/drivers/sdhc/CMakeLists.txt @@ -14,7 +14,7 @@ zephyr_library_sources_ifdef(CONFIG_SAM_HSMCI sam_hsmci.c) zephyr_library_sources_ifdef(CONFIG_SAM_SDMMC sam_sdmmc.c) zephyr_library_sources_ifdef(CONFIG_SDHC_AMBIQ sdhc_ambiq.c) zephyr_library_sources_ifdef(CONFIG_SDHC_ESP32 sdhc_esp32.c) -zephyr_library_sources_ifdef(CONFIG_SDHC_INFINEON_CAT1 infineon_sdio.c) +zephyr_library_sources_ifdef(CONFIG_SDHC_INFINEON_CAT1_PDL sdhc_infineon.c) zephyr_library_sources_ifdef(CONFIG_SDHC_MAX32 sdhc_max32.c) zephyr_library_sources_ifdef(CONFIG_SDHC_RENESAS_RA sdhc_renesas_ra.c) zephyr_library_sources_ifdef(CONFIG_SDHC_STM32_SDIO sdhc_stm32.c) diff --git a/drivers/sdhc/Kconfig.infineon b/drivers/sdhc/Kconfig.infineon index efa86bfae04e..d9de87a26d73 100644 --- a/drivers/sdhc/Kconfig.infineon +++ b/drivers/sdhc/Kconfig.infineon @@ -1,23 +1,29 @@ -# Infineon CAT1 SDHC configuration options - -# Copyright (c) 2023 Cypress Semiconductor Corporation (an Infineon company) or -# an affiliate of Cypress Semiconductor Corporation +# Copyright (c) 2025 Infineon Technologies AG, +# or an affiliate of Infineon Technologies AG. # # SPDX-License-Identifier: Apache-2.0 -config SDHC_INFINEON_CAT1 - bool "Infineon CAT1 SDHC driver" + +config SDHC_INFINEON_CAT1_PDL + bool "Infineon SDHC driver" default y depends on DT_HAS_INFINEON_SDHC_SDIO_ENABLED select USE_INFINEON_SDIO select SDHC_SUPPORTS_NATIVE_MODE + select SDHC_SUPPORTS_UHS select PINCTRL help - This option enables the SDHC driver for Infineon CAT1 family. + This option enables the PDL based SDHC driver for Infineon family. -if SDHC_INFINEON_CAT1 +if SDHC_INFINEON_CAT1_PDL config SDHC_INIT_PRIORITY default 70 -endif +config SDHC_BUFFER_ALIGNMENT + default DCACHE_LINE_SIZE if DCACHE + default 1 + help + SDHC buffer should aligned to the value of DCACHE_LINE_SIZE when placed in a cacheable region. + +endif #SDHC_INFINEON_CAT1_PDL diff --git a/drivers/sdhc/infineon_sdio.c b/drivers/sdhc/infineon_sdio.c deleted file mode 100644 index f2ef5f03f397..000000000000 --- a/drivers/sdhc/infineon_sdio.c +++ /dev/null @@ -1,341 +0,0 @@ -/* - * Copyright (c) 2023 Cypress Semiconductor Corporation (an Infineon company) or - * an affiliate of Cypress Semiconductor Corporation - * - * SPDX-License-Identifier: Apache-2.0 - * - */ - -/** - * @brief SDIO driver for Infineon CAT1 MCU family. - * - * This driver support only SDIO protocol of the SD interface for general - * I/O functions. - * - * Refer to the SD Specifications Part 1 SDIO Specifications Version 4.10 for more - * information on the SDIO protocol and specifications. - * - * Features - * - Supports 4-bit interface - * - Supports Ultra High Speed (UHS-I) mode - * - Supports Default Speed (DS), High Speed (HS), SDR12, SDR25 and SDR50 speed modes - * - Supports SDIO card interrupts in both 1-bit SD and 4-bit SD modes - * - Supports Standard capacity (SDSC), High capacity (SDHC) and - * Extended capacity (SDXC) memory - * - * Note (limitations): - * - current version of ifx_cat1_sdio supports only following set of commands: - * > GO_IDLE_STATE (CMD0) - * > SEND_RELATIVE_ADDR (CMD3) - * > IO_SEND_OP_COND (CMD5) - * > SELECT_CARD (CMD7) - * > VOLTAGE_SWITCH (CMD11) - * > GO_INACTIVE_STATE (CMD15) - * > IO_RW_DIRECT (CMD52) - * > IO_RW_EXTENDED (CMD53) - */ - -#define DT_DRV_COMPAT infineon_sdhc_sdio - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -LOG_MODULE_REGISTER(ifx_cat1_sdio, CONFIG_SDHC_LOG_LEVEL); - -#include - -#define IFX_CAT1_SDIO_F_MIN (SDMMC_CLOCK_400KHZ) -#define IFX_CAT1_SDIO_F_MAX (SD_CLOCK_50MHZ) - -struct ifx_cat1_sdio_config { - const struct pinctrl_dev_config *pincfg; - SDHC_Type *reg_addr; - uint8_t irq_priority; -}; - -struct ifx_cat1_sdio_data { - cyhal_sdio_t sdio_obj; - cyhal_resource_inst_t hw_resource; - cyhal_sdio_configurator_t cyhal_sdio_config; - enum sdhc_clock_speed clock_speed; - enum sdhc_bus_width bus_width; - - void *sdio_cb_user_data; - sdhc_interrupt_cb_t sdio_cb; -}; - -static uint32_t sdio_rca; -static const cy_stc_sd_host_init_config_t host_config = {false, CY_SD_HOST_DMA_ADMA2, false}; -static cy_en_sd_host_card_capacity_t sd_host_card_capacity = CY_SD_HOST_SDSC; -static cy_en_sd_host_card_type_t sd_host_card_type = CY_SD_HOST_NOT_EMMC; -static cy_stc_sd_host_sd_card_config_t sd_host_sd_card_config = { - .lowVoltageSignaling = false, - .busWidth = CY_SD_HOST_BUS_WIDTH_4_BIT, - .cardType = &sd_host_card_type, - .rca = &sdio_rca, - .cardCapacity = &sd_host_card_capacity, -}; - -/* List of available SDHC instances */ -static SDHC_Type *const IFX_CAT1_SDHC_BASE_ADDRESSES[CY_IP_MXSDHC_INSTANCES] = { -#ifdef SDHC0 - SDHC0, -#endif /* ifdef SDHC0 */ - -#ifdef SDHC1 - SDHC1, -#endif /* ifdef SDHC1 */ -}; - -static int32_t _get_hw_block_num(SDHC_Type *reg_addr) -{ - uint32_t i; - - for (i = 0u; i < CY_IP_MXSDHC_INSTANCES; i++) { - if (IFX_CAT1_SDHC_BASE_ADDRESSES[i] == reg_addr) { - return i; - } - } - - return -EINVAL; -} - -static int ifx_cat1_sdio_reset(const struct device *dev) -{ - struct ifx_cat1_sdio_data *dev_data = dev->data; - - cyhal_sdhc_software_reset((cyhal_sdhc_t *)&dev_data->sdio_obj); - - return 0; -} - -static int ifx_cat1_sdio_set_io(const struct device *dev, struct sdhc_io *ios) -{ - cy_rslt_t ret; - struct ifx_cat1_sdio_data *dev_data = dev->data; - cyhal_sdio_cfg_t config = {.frequencyhal_hz = ios->clock}; - - /* NOTE: Set bus width, set card power, set host signal voltage, - * set I/O timing does not support in current version of driver - */ - - /* Set host clock */ - if ((dev_data->clock_speed != ios->clock) && (ios->clock != 0)) { - - if ((ios->clock > IFX_CAT1_SDIO_F_MAX) || (ios->clock < IFX_CAT1_SDIO_F_MIN)) { - return -EINVAL; - } - - ret = cyhal_sdio_configure(&dev_data->sdio_obj, &config); - if (ret != CY_RSLT_SUCCESS) { - return -ENOTSUP; - } - - dev_data->clock_speed = ios->clock; - } - - return 0; -} - -static int ifx_cat1_sdio_card_busy(const struct device *dev) -{ - struct ifx_cat1_sdio_data *dev_data = dev->data; - - return cyhal_sdio_is_busy(&dev_data->sdio_obj) ? 1 : 0; -} - -static int ifx_cat1_sdio_request(const struct device *dev, struct sdhc_command *cmd, - struct sdhc_data *data) -{ - struct ifx_cat1_sdio_data *dev_data = dev->data; - int ret; - - switch (cmd->opcode) { - case CYHAL_SDIO_CMD_GO_IDLE_STATE: - case CYHAL_SDIO_CMD_SEND_RELATIVE_ADDR: - case CYHAL_SDIO_CMD_IO_SEND_OP_COND: - case CYHAL_SDIO_CMD_SELECT_CARD: - case CYHAL_SDIO_CMD_VOLTAGE_SWITCH: - case CYHAL_SDIO_CMD_GO_INACTIVE_STATE: - case CYHAL_SDIO_CMD_IO_RW_DIRECT: - ret = cyhal_sdio_send_cmd(&dev_data->sdio_obj, CYHAL_SDIO_XFER_TYPE_READ, - cmd->opcode, cmd->arg, cmd->response); - if (ret != CY_RSLT_SUCCESS) { - LOG_ERR("cyhal_sdio_send_cmd failed ret = %d \r\n", ret); - } - break; - - case CYHAL_SDIO_CMD_IO_RW_EXTENDED: - cyhal_sdio_transfer_type_t direction; - - direction = (cmd->arg & BIT(SDIO_CMD_ARG_RW_SHIFT)) ? CYHAL_SDIO_XFER_TYPE_WRITE - : CYHAL_SDIO_XFER_TYPE_READ; - - ret = cyhal_sdio_bulk_transfer(&dev_data->sdio_obj, direction, cmd->arg, data->data, - data->blocks * data->block_size, cmd->response); - - if (ret != CY_RSLT_SUCCESS) { - LOG_ERR("cyhal_sdio_bulk_transfer failed ret = %d \r\n", ret); - } - break; - - default: - ret = -ENOTSUP; - } - - return ret; -} - -static int ifx_cat1_sdio_get_card_present(const struct device *dev) -{ - return 1; -} - -static int ifx_cat1_sdio_get_host_props(const struct device *dev, struct sdhc_host_props *props) -{ - memset(props, 0, sizeof(*props)); - props->f_max = IFX_CAT1_SDIO_F_MAX; - props->f_min = IFX_CAT1_SDIO_F_MIN; - props->host_caps.bus_4_bit_support = true; - props->host_caps.high_spd_support = true; - props->host_caps.sdr50_support = true; - props->host_caps.sdio_async_interrupt_support = true; - props->host_caps.vol_330_support = true; - - return 0; -} - -static int ifx_cat1_sdio_enable_interrupt(const struct device *dev, sdhc_interrupt_cb_t callback, - int sources, void *user_data) -{ - struct ifx_cat1_sdio_data *data = dev->data; - const struct ifx_cat1_sdio_config *cfg = dev->config; - - if (sources != SDHC_INT_SDIO) { - return -ENOTSUP; - } - - if (callback == NULL) { - return -EINVAL; - } - - /* Record SDIO callback parameters */ - data->sdio_cb = callback; - data->sdio_cb_user_data = user_data; - - /* Enable CARD INTERRUPT event */ - cyhal_sdio_enable_event(&data->sdio_obj, CYHAL_SDIO_CARD_INTERRUPT, - cfg->irq_priority, true); - - return 0; -} - -static int ifx_cat1_sdio_disable_interrupt(const struct device *dev, int sources) -{ - struct ifx_cat1_sdio_data *data = dev->data; - const struct ifx_cat1_sdio_config *cfg = dev->config; - - if (sources != SDHC_INT_SDIO) { - return -ENOTSUP; - } - - data->sdio_cb = NULL; - data->sdio_cb_user_data = NULL; - - /* Disable CARD INTERRUPT event */ - cyhal_sdio_enable_event(&data->sdio_obj, CYHAL_SDIO_CARD_INTERRUPT, - cfg->irq_priority, false); - - return 0; -} - -static void ifx_cat1_sdio_event_callback(void *callback_arg, cyhal_sdio_event_t event) -{ - const struct device *dev = callback_arg; - struct ifx_cat1_sdio_data *data = dev->data; - - if ((event == CYHAL_SDIO_CARD_INTERRUPT) && (data->sdio_cb != NULL)) { - data->sdio_cb(dev, SDHC_INT_SDIO, data->sdio_cb_user_data); - } -} - -static int ifx_cat1_sdio_init(const struct device *dev) -{ - cy_rslt_t ret; - struct ifx_cat1_sdio_data *data = dev->data; - const struct ifx_cat1_sdio_config *config = dev->config; - - /* Configure dt provided device signals when available */ - ret = pinctrl_apply_state(config->pincfg, PINCTRL_STATE_DEFAULT); - if (ret) { - return ret; - } - - /* Dedicate SDIO HW resource */ - data->hw_resource.type = CYHAL_RSC_SDHC; - data->hw_resource.block_num = _get_hw_block_num(config->reg_addr); - data->hw_resource.channel_num = 0; - - /* Initialize the SDIO peripheral */ - data->cyhal_sdio_config.resource = &data->hw_resource; - data->cyhal_sdio_config.host_config = &host_config, - data->cyhal_sdio_config.card_config = &sd_host_sd_card_config, - data->cyhal_sdio_config.gpios.cmd = NC; - data->cyhal_sdio_config.gpios.clk = NC; - data->cyhal_sdio_config.gpios.data[0] = NC; - data->cyhal_sdio_config.gpios.data[1] = NC; - data->cyhal_sdio_config.gpios.data[2] = NC; - data->cyhal_sdio_config.gpios.data[3] = NC; - data->cyhal_sdio_config.clock = NULL; - - ret = cyhal_sdio_init_cfg(&data->sdio_obj, &data->cyhal_sdio_config); - if (ret != CY_RSLT_SUCCESS) { - LOG_ERR("cyhal_sdio_init_cfg failed ret = %d \r\n", ret); - return ret; - } - - /* Register callback for SDIO events */ - cyhal_sdio_register_callback(&data->sdio_obj, ifx_cat1_sdio_event_callback, (void *)dev); - - return 0; -} - -static DEVICE_API(sdhc, ifx_cat1_sdio_api) = { - .reset = ifx_cat1_sdio_reset, - .request = ifx_cat1_sdio_request, - .set_io = ifx_cat1_sdio_set_io, - .get_card_present = ifx_cat1_sdio_get_card_present, - .card_busy = ifx_cat1_sdio_card_busy, - .get_host_props = ifx_cat1_sdio_get_host_props, - .enable_interrupt = ifx_cat1_sdio_enable_interrupt, - .disable_interrupt = ifx_cat1_sdio_disable_interrupt, -}; - -#define IFX_CAT1_SDHC_INIT(n) \ - \ - PINCTRL_DT_INST_DEFINE(n); \ - \ - static const struct ifx_cat1_sdio_config ifx_cat1_sdio_##n##_config = { \ - .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ - .reg_addr = (SDHC_Type *)DT_INST_REG_ADDR(n), \ - .irq_priority = DT_INST_IRQ(n, priority)}; \ - \ - static struct ifx_cat1_sdio_data ifx_cat1_sdio_##n##_data; \ - \ - DEVICE_DT_INST_DEFINE(n, &ifx_cat1_sdio_init, NULL, &ifx_cat1_sdio_##n##_data, \ - &ifx_cat1_sdio_##n##_config, POST_KERNEL, CONFIG_SDHC_INIT_PRIORITY, \ - &ifx_cat1_sdio_api); - -DT_INST_FOREACH_STATUS_OKAY(IFX_CAT1_SDHC_INIT) diff --git a/drivers/sdhc/sdhc_infineon.c b/drivers/sdhc/sdhc_infineon.c new file mode 100644 index 000000000000..fc7c7f843729 --- /dev/null +++ b/drivers/sdhc/sdhc_infineon.c @@ -0,0 +1,1141 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @brief SDHC driver for Infineon MCU family. + * + * This driver support only SD protocol of the SD interface. + * + * + * Features: + * * Supports data transfer using CPU, SDMA, ADMA2 and ADMA3 modes + * * Supports a configurable block size (1 to 65,535 Bytes) + * * Supports interrupt enabling and masking + * * Supports SD-HCI Host version 4 mode or less + * * Compliant with the SD 6.0, SDIO 4.10 and earlier versions + * * SD interface features: + * * - Supports the 4-bit interface + * * - Supports Ultra High Speed (UHS-I) mode + * * - Supports Default Speed (DS), High Speed (HS), SDR12, SDR25, SDR50, and DDR50 speed modes + * * - Supports SDIO card interrupts in both 1-bit and 4-bit modes + * * - Supports Standard capacity (SDSC), High capacity (SDHC) and Extended capacity (SDXC) memory + * * - Supports CRC and check for command and data packets + * * - Supports packet timeouts + * + */ + +#define DT_DRV_COMPAT infineon_sdhc_sdio + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "cy_sd_host.h" +#include "cy_sysclk.h" + +LOG_MODULE_REGISTER(sdhc_infineon, CONFIG_SDHC_LOG_LEVEL); + +#include + +#define IFX_SDHC_RETRY_TIMES (1000U) /* The number loops to make timeout in us */ +#define IFX_SDHC_CMD_CMPLT_DELAY_US (5U) /* The Command complete delay in us */ +#define IFX_SDHC_MAX_TIMEOUT (0x0EU) /* The data max timeout for TOUT_CTRL_R */ +#define IFX_SDHC_RETRY_TIME (1000U) /* The number loops to make timeout in us */ +#define IFX_SDHC_BUFFER_RDY_TIMEOUT_US (150U) /* The Buffer read ready timeout in us */ +#define IFX_SDHC_RD_WR_ENABLE_TIMEOUT_US (1U) /* The valid data in the Host buffer timeout */ +#define IFX_SDHC_WRITE_TIMEOUT_US (250U) /* The Write timeout for one block */ +#define IFX_SDHC_SD_ACMD_OFFSET (0x40U) +#define IFX_SDHC_SDIO_TRANSFER_TRIES (50U) +#define IFX_SDHC_SET_ALL_INTERRUPTS_MASK (0x61FFU) +#define IFX_SDHC_1_8_REG_STABLE_TIME_MS (200U) /* The 1.8 voltage regulator stable time in ms */ + +struct sdhc_infineon_config { + const struct pinctrl_dev_config *pincfg; + struct gpio_dt_spec cd_gpio; + SDHC_Type *reg_addr; + uint8_t irq_priority; + IRQn_Type irq; +}; + +/* + * Keep DMA descriptor's memory location as D-cache alignment, so that + * when cleaning its cache line before DMA transfer, it would not affect other + * memory data in same cache line, which is used by other DMA. + */ +struct __aligned(CONFIG_SDHC_BUFFER_ALIGNMENT) sdhc_infineon_data { + uint32_t adma_descriptor_tbl[2]; + struct k_sem thread_lock; + struct k_sem transfer_sem; + struct sdhc_host_props props; +#if defined(CONFIG_SOC_FAMILY_INFINEON_EDGE) + struct ifx_cat1_clock clock; +#endif + uint32_t irq_cause; + void *sdio_cb_user_data; + sdhc_interrupt_cb_t sdio_cb; + uint32_t bus_clock; /* Value in Hz */ + cy_en_sd_host_bus_width_t bus_width; + enum sdhc_power power_mode; + cy_en_sd_host_bus_speed_mode_t speed_mode; + enum sd_voltage signal_voltage; +#if defined(CONFIG_SOC_FAMILY_INFINEON_EDGE) + uint8_t clock_peri_group; +#endif + bool app_cmd; +}; + +static const cy_stc_sd_host_init_config_t sdhc_config = { + .emmc = false, + .dmaType = CY_SD_HOST_DMA_ADMA2, + .enableLedControl = false, +}; + +static void sdhc_infineon_irq_handler(const struct device *dev) +{ + const struct sdhc_infineon_config *const config = dev->config; + struct sdhc_infineon_data *const sdhc_data = dev->data; + + /* Clear all interrupts that could have been configured */ + SDHC_Type *base = config->reg_addr; + uint32_t int_status = Cy_SD_Host_GetNormalInterruptStatus(base); + uint32_t int_enable_status = Cy_SD_Host_GetNormalInterruptEnable(base); + uint32_t int_mask = Cy_SD_Host_GetNormalInterruptMask(base); + uint32_t user_int_status = int_status & sdhc_data->irq_cause; + + /* CY_SD_HOST_XFER_COMPLETE occurred and appropriate bit in interrupt mask is enabled */ + if (int_status & Cy_SD_Host_GetNormalInterruptMask(base) & CY_SD_HOST_XFER_COMPLETE) { + /* Clearing transfer complete status */ + Cy_SD_Host_ClearNormalInterruptStatus(base, CY_SD_HOST_XFER_COMPLETE); + + k_sem_give(&sdhc_data->transfer_sem); + + /* Disabling transfer complete interrupt mask */ + Cy_SD_Host_SetNormalInterruptMask(base, + Cy_SD_Host_GetNormalInterruptMask(base) & + (uint32_t)~CY_SD_HOST_XFER_COMPLETE); + + /* Transfer is no more active. If card interrupt was not yet enabled after it was + * disabled in interrupt handler, enable it. + */ + if ((int_enable_status & CY_SD_HOST_CARD_INTERRUPT) == 0) { + Cy_SD_Host_SetNormalInterruptEnable( + base, (int_enable_status | CY_SD_HOST_CARD_INTERRUPT)); + } + } + + /* To clear Card Interrupt need to disable Card Interrupt Enable bit. + * The Card Interrupt is enabled after the current transfer is complete + */ + if ((int_status & CY_SD_HOST_CARD_INTERRUPT) != 0U) { + int_enable_status = Cy_SD_Host_GetNormalInterruptEnable(base); + int_enable_status &= (uint32_t)~CY_SD_HOST_CARD_INTERRUPT; + /* Disable Card Interrupt */ + Cy_SD_Host_SetNormalInterruptEnable(base, int_enable_status); + } + + if ((sdhc_data->sdio_cb != NULL) && ((user_int_status & int_mask) > 0U)) { + sdhc_data->sdio_cb(dev, SDHC_INT_SDIO, sdhc_data->sdio_cb_user_data); + } +} + +static void sdhc_normal_reset(SDHC_Type *base) +{ + uint32_t int_status; /* The normal events mask. */ + + int_status = Cy_SD_Host_GetNormalInterruptStatus(base); + + /* Check the normal event. */ + if (int_status > 0U) { + /* Clear the normal event. */ + Cy_SD_Host_ClearNormalInterruptStatus(base, int_status); + } +} + +static void sdhc_error_reset(SDHC_Type *base) +{ + uint32_t err_status; /* The error events mask. */ + + err_status = Cy_SD_Host_GetErrorInterruptStatus(base); + + /* Check the error event. */ + if (err_status > 0U) { + /* Clear the error event. */ + Cy_SD_Host_ClearErrorInterruptStatus(base, err_status); + + Cy_SD_Host_SoftwareReset(base, CY_SD_HOST_RESET_CMD_LINE); + } +} + +static int sdhc_infineon_reset(const struct device *dev) +{ + const struct sdhc_infineon_config *config = dev->config; + uint32_t timeout_us = 1000U; + + Cy_SD_Host_SoftwareReset(config->reg_addr, CY_SD_HOST_RESET_DATALINE); + Cy_SD_Host_SoftwareReset(config->reg_addr, CY_SD_HOST_RESET_CMD_LINE); + + if (!WAIT_FOR(config->reg_addr->CORE.SW_RST_R == 0, timeout_us, k_busy_wait(1))) { + /* Reset was not cleared by SDHC IP Block. Something wrong. Are clocks enabled? */ + LOG_ERR("Software reset is not completed...timeout, reg:0x%08X", + config->reg_addr->CORE.SW_RST_R); + return -ETIMEDOUT; + } + + return 0; +} + +static inline cy_en_sd_host_response_type_t sdhc_resp_type(uint32_t response_type) +{ + switch (response_type & SDHC_NATIVE_RESPONSE_MASK) { + case SD_RSP_TYPE_NONE: + return CY_SD_HOST_RESPONSE_NONE; + case SD_RSP_TYPE_R1b: + case SD_RSP_TYPE_R5b: + return CY_SD_HOST_RESPONSE_LEN_48B; + case SD_RSP_TYPE_R2: + return CY_SD_HOST_RESPONSE_LEN_136; + default: + return CY_SD_HOST_RESPONSE_LEN_48; + } +} + +static inline cy_en_sd_host_cmd_type_t sdhc_cmd_type(uint32_t opcode) +{ + switch (opcode) { + case SD_GO_IDLE_STATE: + case SD_STOP_TRANSMISSION: + return CY_SD_HOST_CMD_ABORT; + default: + return CY_SD_HOST_CMD_NORMAL; + } +} + +static inline bool sdhc_dma_enable(cy_stc_sd_host_cmd_config_t *cmd_config) +{ + switch (cmd_config->commandIndex) { + case SD_SWITCH: + case SD_SEND_STATUS: + case (SD_APP_SEND_SCR + IFX_SDHC_SD_ACMD_OFFSET): + return false; + default: + return true; + } +} + +static inline cy_en_sd_host_auto_cmd_t sdhc_autocommand(cy_stc_sd_host_cmd_config_t *cmd_config, + struct sdhc_data *data) +{ + return (data->blocks > 1U) ? CY_SD_HOST_AUTO_CMD_AUTO : CY_SD_HOST_AUTO_CMD_NONE; +} + +static inline cy_en_sd_host_auto_cmd_t sdhc_int_at_blockgap(cy_stc_sd_host_cmd_config_t *cmd_config, + struct sdhc_data *data) +{ + return data->blocks > 1U; +} + +static inline int sdhc_prepare_for_transfer(const struct device *dev) +{ + const struct sdhc_infineon_config *config = dev->config; + + /* Enabling transfer complete interrupt as it takes part in write / read processes */ + Cy_SD_Host_SetNormalInterruptMask(config->reg_addr, + Cy_SD_Host_GetNormalInterruptMask(config->reg_addr) | + CY_SD_HOST_XFER_COMPLETE); + + return 0; +} + +static int sdhc_poll_cmd_complete(const struct device *dev) +{ + const struct sdhc_infineon_config *config = dev->config; + uint32_t timeout_us = IFX_SDHC_RETRY_TIMES * IFX_SDHC_CMD_CMPLT_DELAY_US; + + if (!WAIT_FOR((CY_SD_HOST_CMD_COMPLETE & + Cy_SD_Host_GetNormalInterruptStatus(config->reg_addr)) == + CY_SD_HOST_CMD_COMPLETE, + timeout_us, k_busy_wait(1))) { + return -ETIMEDOUT; + } + + /* Clear interrupt flag */ + Cy_SD_Host_ClearNormalInterruptStatus(config->reg_addr, CY_SD_HOST_CMD_COMPLETE); + + return 0; +} + +static int sdhc_host_poll_transfer_complete(SDHC_Type *base) +{ + /* Transfer Complete */ + if (!WAIT_FOR(_FLD2BOOL(SDHC_CORE_NORMAL_INT_STAT_R_XFER_COMPLETE, + SDHC_CORE_NORMAL_INT_STAT_R(base)), + IFX_SDHC_RETRY_TIME, k_busy_wait(IFX_SDHC_WRITE_TIMEOUT_US))) { + return -ETIMEDOUT; + } + + /* Clear the interrupt flag */ + SDHC_CORE_NORMAL_INT_STAT_R(base) = CY_SD_HOST_XFER_COMPLETE; + + return 0; +} + +static int sdhc_poll_buf_read_ready(SDHC_Type *base) +{ + /* Check the Buffer Read ready */ + if (!WAIT_FOR(_FLD2BOOL(SDHC_CORE_NORMAL_INT_STAT_R_BUF_RD_READY, + SDHC_CORE_NORMAL_INT_STAT_R(base)), + IFX_SDHC_RETRY_TIME, k_busy_wait(IFX_SDHC_BUFFER_RDY_TIMEOUT_US))) { + return -ETIMEDOUT; + } + + /* Clear the interrupt flag */ + SDHC_CORE_NORMAL_INT_STAT_R(base) = CY_SD_HOST_BUF_RD_READY; + + return 0; +} + +static int sdhc_cmd_rx_data(SDHC_Type *base, cy_stc_sd_host_data_config_t *pcmd) +{ + uint32_t blk_size = pcmd->blockSize; + uint32_t blk_cnt = pcmd->numberOfBlock; + uint32_t i; + + while (blk_cnt > 0U) { + /* Wait for the Buffer Read ready. */ + if (sdhc_poll_buf_read_ready(base) != 0) { + LOG_WRN("%s Buffer read is not ready", __func__); + break; + } + + for (i = blk_size >> 2U; i != 0U; i--) { + /* Wait if valid data exists in the Host buffer. */ + WAIT_FOR(_FLD2BOOL(SDHC_CORE_PSTATE_REG_BUF_RD_ENABLE, + SDHC_CORE_PSTATE_REG(base)), + IFX_SDHC_RETRY_TIME, + k_busy_wait(IFX_SDHC_RD_WR_ENABLE_TIMEOUT_US)); + + if (false == _FLD2BOOL(SDHC_CORE_PSTATE_REG_BUF_RD_ENABLE, + SDHC_CORE_PSTATE_REG(base))) { + break; + } + + /* Read data from the Host buffer. */ + *pcmd->data = Cy_SD_Host_BufferRead(base); + pcmd->data++; + } + blk_cnt--; + } + + /* Wait for the Transfer Complete. */ + return sdhc_host_poll_transfer_complete(base); +} + +static int sdhc_config_data_transfer(const struct device *dev, struct sdhc_data *data, + cy_stc_sd_host_data_config_t *data_config) +{ + const struct sdhc_infineon_config *config = dev->config; + struct sdhc_infineon_data *const sdhc_data = dev->data; + uint32_t length; + + data_config->blockSize = data->block_size; + data_config->numberOfBlock = data->blocks; + data_config->dataTimeout = IFX_SDHC_MAX_TIMEOUT; + data_config->enReliableWrite = false; + + if (data_config->enableDma == true) { + /* ADMA2 mode. */ + length = data->block_size * data->blocks; + sdhc_data->adma_descriptor_tbl[0] = + (1U << CY_SD_HOST_ADMA_ATTR_VALID_POS) | /* Attr Valid */ + (1U << CY_SD_HOST_ADMA_ATTR_END_POS) | /* Attr End */ + (0U << CY_SD_HOST_ADMA_ATTR_INT_POS) | /* Attr Int */ + (CY_SD_HOST_ADMA_TRAN << CY_SD_HOST_ADMA_ACT_POS) | + (length << CY_SD_HOST_ADMA_LEN_POS); /* Len */ + + /* SDHC needs to be able to access the data_ptr that is in DTCM when using CM55. + * Remap this address for access. + */ +#if defined(CORE_NAME_CM55_0) + sdhc_data->adma_descriptor_tbl[1] = (uint32_t)cy_DTCMRemapAddr(data->data); + data_config->data = + (uint32_t *)cy_DTCMRemapAddr(&sdhc_data->adma_descriptor_tbl[0]); +#else + sdhc_data->adma_descriptor_tbl[1] = (uint32_t)data->data; + data_config->data = (uint32_t *)&sdhc_data->adma_descriptor_tbl[0]; +#endif + +#if defined(CONFIG_CPU_HAS_DCACHE) && defined(__DCACHE_PRESENT) && __DCACHE_PRESENT + sys_cache_data_flush_range((void *)sdhc_data->adma_descriptor_tbl, + sizeof(sdhc_data->adma_descriptor_tbl)); +#endif + } else { + data_config->data = (uint32_t *)data->data; + } + + return (int)Cy_SD_Host_InitDataTransfer(config->reg_addr, data_config); +} + +static int sdhc_send_cmd(const struct device *dev, cy_stc_sd_host_cmd_config_t *cmd_config, + struct sdhc_data *data, bool is_read) +{ + const struct sdhc_infineon_config *config = dev->config; + struct sdhc_infineon_data *const sdhc_data = dev->data; + cy_stc_sd_host_data_config_t data_config; + int result = 0; + + data_config.enableDma = sdhc_dma_enable(cmd_config); +#if defined(CONFIG_CPU_HAS_DCACHE) && defined(__DCACHE_PRESENT) && __DCACHE_PRESENT + if ((cmd_config->dataPresent) && (data_config.enableDma == true)) { + sys_cache_data_flush_range(data->data, data->block_size * data->blocks); + } +#endif + + /* First clear out the transfer and command complete statuses */ + Cy_SD_Host_ClearNormalInterruptStatus(config->reg_addr, + (CY_SD_HOST_XFER_COMPLETE | CY_SD_HOST_CMD_COMPLETE)); + + if (cmd_config->dataPresent) { + data_config.read = is_read; + data_config.autoCommand = sdhc_autocommand(cmd_config, data); + data_config.enableIntAtBlockGap = sdhc_int_at_blockgap(cmd_config, data); + result = sdhc_config_data_transfer(dev, data, &data_config); + + if (result == 0 && data_config.enableDma == true) { + result = sdhc_prepare_for_transfer(dev); + } + } + + if (result == 0) { + result = (int)Cy_SD_Host_SendCommand(config->reg_addr, cmd_config); + } + + if (result == 0) { + result = sdhc_poll_cmd_complete(dev); + } + + if (result == 0) { + if (cmd_config->dataPresent) { + if (data_config.enableDma == true) { + result = k_sem_take(&sdhc_data->transfer_sem, + K_MSEC(data->timeout_ms)); + if (result != 0U) { + LOG_ERR("Cannot take sem!"); + } + +#if defined(CONFIG_CPU_HAS_DCACHE) && defined(__DCACHE_PRESENT) && __DCACHE_PRESENT + if (data_config.read == true) { + sys_cache_data_invd_range(data->data, + data->block_size * data->blocks); + } +#endif + } else { + /* DMA is not used - wait until all data is read. */ + result = sdhc_cmd_rx_data(config->reg_addr, &data_config); + } + } + } + + return result; +} + +static int sdhc_send_cmd53(const struct device *dev, cy_stc_sd_host_cmd_config_t *cmd_Config, + struct sdhc_data *data, bool is_read) +{ + const struct sdhc_infineon_config *config = dev->config; + struct sdhc_infineon_data *const sdhc_data = dev->data; + cy_stc_sd_host_data_config_t data_Config; + int result = 0; + uint32_t retry = IFX_SDHC_SDIO_TRANSFER_TRIES; + +#if defined(CONFIG_CPU_HAS_DCACHE) && defined(__DCACHE_PRESENT) && __DCACHE_PRESENT + sys_cache_data_flush_range(data->data, data->block_size * data->blocks); +#endif + + do { + /* Add SDIO Error Handling + * SDIO write timeout is expected when doing first write to register + * after KSO bit disable (as it goes to AOS core). + * This timeout, however, triggers an error state in the hardware. + * So, check for the error and then recover from it + * as needed via reset issuance. This is the only time known that + * a write timeout occurs. + */ + + /* First clear out the transfer and command complete statuses */ + Cy_SD_Host_ClearNormalInterruptStatus( + config->reg_addr, (CY_SD_HOST_XFER_COMPLETE | CY_SD_HOST_CMD_COMPLETE)); + + /* Check if an error occurred on any previous transactions or reset after the first + * unsuccessful transfer try. + */ + if ((Cy_SD_Host_GetNormalInterruptStatus(config->reg_addr) & + CY_SD_HOST_ERR_INTERRUPT) || + (retry < IFX_SDHC_SDIO_TRANSFER_TRIES)) { + /* Reset the block if there was an error. Note a full reset usually + * requires more time, but this short version is working quite well and + * successfully clears out the error state. + */ + Cy_SD_Host_ClearErrorInterruptStatus(config->reg_addr, + IFX_SDHC_SET_ALL_INTERRUPTS_MASK); + sdhc_infineon_reset(dev); + } + + data_Config.read = is_read; + data_Config.enableDma = true; + data_Config.autoCommand = CY_SD_HOST_AUTO_CMD_NONE; + data_Config.enableIntAtBlockGap = false; + result = sdhc_config_data_transfer(dev, data, &data_Config); + + if (result == 0) { + result = sdhc_prepare_for_transfer(dev); + } + + if (result == 0) { + result = (cy_rslt_t)Cy_SD_Host_SendCommand(config->reg_addr, cmd_Config); + } + + if (result == 0) { + result = (cy_rslt_t)sdhc_poll_cmd_complete(dev); + } + } while ((result != 0) && (--retry > 0UL)); + + if (result == 0) { + result = k_sem_take(&sdhc_data->transfer_sem, K_MSEC(data->timeout_ms)); + if (result != 0U) { + LOG_ERR("Cannot take sem!"); + } + +#if defined(CONFIG_CPU_HAS_DCACHE) && defined(__DCACHE_PRESENT) && __DCACHE_PRESENT + if (data_Config.read == true) { + sys_cache_data_invd_range(data->data, data->block_size * data->blocks); + } +#endif + } + + return result; +} + +static int sdhc_infineon_request(const struct device *dev, struct sdhc_command *cmd, + struct sdhc_data *data) +{ + const struct sdhc_infineon_config *config = dev->config; + struct sdhc_infineon_data *const sdhc_data = dev->data; + bool large_response; + int result = 0; + + LOG_DBG("Opcode: %d", cmd->opcode); + + k_sem_take(&sdhc_data->thread_lock, K_FOREVER); + /* Reset semaphore */ + k_sem_reset(&sdhc_data->transfer_sem); + + cy_stc_sd_host_cmd_config_t cmd_config = { + .commandIndex = cmd->opcode, + .commandArgument = cmd->arg, + .enableCrcCheck = true, + .enableAutoResponseErrorCheck = false, + .respType = sdhc_resp_type(cmd->response_type), + .enableIdxCheck = true, + .dataPresent = (data != NULL) ? true : false, + .cmdType = sdhc_cmd_type(cmd->opcode), + }; + + switch (cmd->opcode) { + case SD_GO_IDLE_STATE: + cmd_config.enableCrcCheck = false; + cmd_config.enableIdxCheck = false; + /* No response CMD so no complete interrupt */ + (void)sdhc_send_cmd(dev, &cmd_config, data, true); + + /* Software reset for the CMD line */ + Cy_SD_Host_SoftwareReset(config->reg_addr, CY_SD_HOST_RESET_CMD_LINE); + break; + + case SD_SEND_IF_COND: + result = sdhc_send_cmd(dev, &cmd_config, data, true); + Cy_SD_Host_GetResponse(config->reg_addr, cmd->response, false); + if ((cmd->response[0] & 0xFF) != SD_IF_COND_CHECK) { + /* Reset the error and the CMD line for the case of the SDIO card. */ + sdhc_error_reset(config->reg_addr); + sdhc_normal_reset(config->reg_addr); + } + goto end; + + case MMC_SEND_OP_COND: + case SDIO_SEND_OP_COND: + case SD_SELECT_CARD: + cmd_config.enableCrcCheck = false; + cmd_config.enableIdxCheck = false; + result = sdhc_send_cmd(dev, &cmd_config, data, true); + break; + + case SD_APP_SEND_OP_COND: + cmd_config.commandIndex += IFX_SDHC_SD_ACMD_OFFSET; + cmd_config.enableCrcCheck = false; + cmd_config.enableIdxCheck = false; + result = sdhc_send_cmd(dev, &cmd_config, data, true); + break; + + case SD_ALL_SEND_CID: + case SD_SEND_CSD: + cmd_config.enableCrcCheck = true; + cmd_config.enableIdxCheck = false; + result = sdhc_send_cmd(dev, &cmd_config, data, true); + break; + + case SD_SEND_STATUS: + result = sdhc_send_cmd(dev, &cmd_config, data, true); + break; + + case SD_SEND_RELATIVE_ADDR: + case SD_SET_BLOCK_SIZE: + case SD_ERASE_BLOCK_START: + case SD_ERASE_BLOCK_END: + case SD_ERASE_BLOCK_OPERATION: + case SD_APP_CMD: + result = sdhc_send_cmd(dev, &cmd_config, data, true); + break; + + case SD_VOL_SWITCH: + result = sdhc_send_cmd(dev, &cmd_config, data, true); + k_msleep(IFX_SDHC_1_8_REG_STABLE_TIME_MS); + break; + + case SD_SWITCH: + /* Check app cmd */ + if (sdhc_data->app_cmd && cmd->opcode == SD_APP_SET_BUS_WIDTH) { + cmd_config.commandIndex += IFX_SDHC_SD_ACMD_OFFSET; + cmd_config.enableCrcCheck = false; + cmd_config.enableIdxCheck = false; + result = sdhc_send_cmd(dev, &cmd_config, data, true); + } else { + result = sdhc_send_cmd(dev, &cmd_config, data, true); + } + break; + + case SDIO_RW_DIRECT: + cmd_config.respType = CY_SD_HOST_RESPONSE_LEN_48B; + result = sdhc_send_cmd(dev, &cmd_config, data, true); + break; + + case SDIO_RW_EXTENDED: + result = sdhc_send_cmd53(dev, &cmd_config, data, + !(cmd->arg & BIT(SDIO_CMD_ARG_RW_SHIFT))); + break; + + case SD_APP_SEND_NUM_WRITTEN_BLK: + cmd_config.commandIndex += IFX_SDHC_SD_ACMD_OFFSET; + result = sdhc_send_cmd(dev, &cmd_config, data, true); + break; + + case SD_APP_SEND_SCR: + cmd_config.commandIndex += IFX_SDHC_SD_ACMD_OFFSET; + cmd_config.respType = CY_SD_HOST_RESPONSE_LEN_48B; + result = sdhc_send_cmd(dev, &cmd_config, data, true); + break; + + case SD_READ_SINGLE_BLOCK: + case SD_READ_MULTIPLE_BLOCK: + result = sdhc_send_cmd(dev, &cmd_config, data, true); + break; + + case SD_WRITE_SINGLE_BLOCK: + case SD_WRITE_MULTIPLE_BLOCK: + result = sdhc_send_cmd(dev, &cmd_config, data, false); + break; + + default: + result = -ENOTSUP; + } + + if (cmd_config.respType != CY_SD_HOST_RESPONSE_NONE) { + large_response = (cmd_config.respType == CY_SD_HOST_RESPONSE_LEN_136); + Cy_SD_Host_GetResponse(config->reg_addr, cmd->response, large_response); + } + +end: + if (cmd->opcode == SD_APP_CMD) { + sdhc_data->app_cmd = true; + } else { + sdhc_data->app_cmd = false; + } + k_sem_give(&sdhc_data->thread_lock); + + return result; +} + +static void sdhc_find_best_div(uint32_t hz_src, uint32_t desired_hz, uint32_t *divider) +{ + /* Rounding up for correcting the error in integer division + * to ensure the actual frequency is less than or equal to + * the requested frequency. + * Ensure computed divider is no more than 10-bit. + */ + if (hz_src > desired_hz) { + uint32_t freq = (desired_hz << 1); + uint32_t calculated_divider = ((hz_src + freq - 1) / freq) & 0x3FF; + /* Real divider is 2 x calculated_divider */ + *divider = calculated_divider << 1; + } else { + *divider = 1; + } +} + +static int sdhc_change_clock(const struct device *dev, uint32_t *frequency) +{ + const struct sdhc_infineon_config *config = dev->config; + struct sdhc_infineon_data *const sdhc_data = dev->data; + uint32_t most_suitable_div = 0; + uint32_t bus_freq = 0; + uint32_t source_freq = 0; + en_clk_dst_t clk_idx; + +#if defined(COMPONENT_CAT1A) + (void)clk_idx; + (void)sdhc_data; + source_freq = Cy_SysClk_ClkHfGetFrequency(CLK_HF4); +#elif defined(CONFIG_SOC_FAMILY_INFINEON_EDGE) + if (config->reg_addr == SDHC0) { + clk_idx = PCLK_SDHC0_CLK_HF; + } else if (config->reg_addr == SDHC1) { + clk_idx = PCLK_SDHC1_CLK_HF; + } else { + return -EINVAL; + } + + source_freq = + ifx_cat1_utils_peri_pclk_get_frequency((en_clk_dst_t)clk_idx, &sdhc_data->clock); +#endif + + sdhc_find_best_div(source_freq, *frequency, &most_suitable_div); + bus_freq = source_freq / most_suitable_div; + + Cy_SD_Host_DisableSdClk(config->reg_addr); + if (Cy_SD_Host_SetSdClkDiv(config->reg_addr, most_suitable_div >> 1) == + CY_SD_HOST_SUCCESS) { + Cy_SD_Host_EnableSdClk(config->reg_addr); + *frequency = bus_freq; + return 0; + } + + return -EINVAL; +} + +static void sdhc_card_power_cycle(const struct device *dev, enum sdhc_power power_mode) +{ + const struct sdhc_infineon_config *config = dev->config; + + if (power_mode == SDHC_POWER_ON) { + SDHC_CORE_PWR_CTRL_R(config->reg_addr) = + _CLR_SET_FLD8U(SDHC_CORE_PWR_CTRL_R(config->reg_addr), + SDHC_CORE_PWR_CTRL_R_SD_BUS_PWR_VDD1, 1U); + } +} + +static int sdhc_infineon_set_io(const struct device *dev, struct sdhc_io *ios) +{ + const struct sdhc_infineon_config *config = dev->config; + struct sdhc_infineon_data *const sdhc_data = dev->data; + cy_en_sd_host_bus_width_t bus_width; + cy_en_sd_host_bus_speed_mode_t speed_mode; + int ret = 0; + + LOG_INF("SDHC I/O: bus width %d, clock %dHz, card power %s, voltage %s, timing %d", + ios->bus_width, ios->clock, ios->power_mode == SDHC_POWER_ON ? "ON" : "OFF", + ios->signal_voltage == SD_VOL_1_8_V ? "1.8V" : "3.3V", ios->timing); + + /* Toggle card power supply */ + if (sdhc_data->power_mode != ios->power_mode) { + sdhc_card_power_cycle(dev, ios->power_mode); + sdhc_data->power_mode = ios->power_mode; + } + + if (ios->bus_width > 0U) { + /* Set bus width */ + switch (ios->bus_width) { + case SDHC_BUS_WIDTH1BIT: + bus_width = CY_SD_HOST_BUS_WIDTH_1_BIT; + break; + case SDHC_BUS_WIDTH4BIT: + bus_width = CY_SD_HOST_BUS_WIDTH_4_BIT; + break; + case SDHC_BUS_WIDTH8BIT: + bus_width = CY_SD_HOST_BUS_WIDTH_8_BIT; + return -ENOTSUP; + default: + return -ENOTSUP; + } + + if (sdhc_data->bus_width != bus_width) { + /* Update the host side setting. */ + ret = Cy_SD_Host_SetHostBusWidth(config->reg_addr, bus_width); + + if (ret == 0) { + LOG_INF("Bus width set successfully to %d bit", ios->bus_width); + } else { + LOG_ERR("Error configuring bus width"); + return -EINVAL; + } + + sdhc_data->bus_width = bus_width; + } + } + + if (ios->timing > 0U) { + /* Set I/O timing */ + switch (ios->timing) { + case SDHC_TIMING_LEGACY: + speed_mode = CY_SD_HOST_BUS_SPEED_DEFAULT; + break; + case SDHC_TIMING_HS: + speed_mode = CY_SD_HOST_BUS_SPEED_HIGHSPEED; + break; + case SDHC_TIMING_SDR12: + speed_mode = CY_SD_HOST_BUS_SPEED_SDR12_5; + break; + case SDHC_TIMING_SDR25: + speed_mode = CY_SD_HOST_BUS_SPEED_SDR25; + break; + case SDHC_TIMING_SDR50: + speed_mode = CY_SD_HOST_BUS_SPEED_SDR50; + break; + case SDHC_TIMING_DDR50: + speed_mode = CY_SD_HOST_BUS_SPEED_DDR50; + break; + default: + LOG_ERR("Timing mode not supported for this device"); + return -ENOTSUP; + } + + if (sdhc_data->speed_mode != speed_mode) { + ret = Cy_SD_Host_SetHostSpeedMode(config->reg_addr, speed_mode); + + if (ret == 0) { + LOG_INF("Timing set successfully to %d", ios->timing); + } else { + LOG_ERR("Error configuring Timing"); + return -EINVAL; + } + + sdhc_data->speed_mode = speed_mode; + } + } + + if (ios->clock != sdhc_data->bus_clock) { + if (ios->clock == 0U) { + /* Disable providing the SD Clock. */ + Cy_SD_Host_DisableSdClk(config->reg_addr); + } else { + /* Check for frequency boundaries supported by host */ + if (ios->clock > sdhc_data->props.f_max || + ios->clock < sdhc_data->props.f_min) { + LOG_ERR("Proposed clock outside supported host range"); + return -EINVAL; + } + + uint32_t actual_freq = ios->clock; + + /* Try setting new clock */ + ret = sdhc_change_clock(dev, &actual_freq); + + if (ret == 0) { + LOG_INF("Bus clock successfully set to %d kHz", ios->clock / 1000); + } else { + LOG_ERR("Error configuring card clock"); + return -EINVAL; + } + } + + sdhc_data->bus_clock = (uint32_t)ios->clock; + } + + if (sdhc_data->signal_voltage != ios->signal_voltage) { + switch (ios->signal_voltage) { + case SD_VOL_3_3_V: + Cy_SD_Host_ChangeIoVoltage(config->reg_addr, CY_SD_HOST_IO_VOLT_3_3V); + break; + case SD_VOL_1_8_V: + /* Switch the bus to 1.8 V (Set the IO_VOLT_SEL pin to low)*/ + Cy_SD_Host_ChangeIoVoltage(config->reg_addr, CY_SD_HOST_IO_VOLT_1_8V); + break; + default: + return -ENOTSUP; + } + + sdhc_data->signal_voltage = ios->signal_voltage; + } + + return ret; +} + +static int sdhc_infineon_get_card_present(const struct device *dev) +{ + int res = 1; + const struct sdhc_infineon_config *config = dev->config; + + /* If a CD pin is configured, use it for card detection */ + if (config->cd_gpio.port != NULL) { + res = !gpio_pin_get_dt(&config->cd_gpio); + } + + return res; +} + +static int sdhc_infineon_execute_tuning(const struct device *dev) +{ + return 0; +} + +static int sdhc_infineon_card_busy(const struct device *dev) +{ + const struct sdhc_infineon_config *config = dev->config; + int busy_status = 0; + /* Check DAT Line Active */ + uint32_t state = Cy_SD_Host_GetPresentState(config->reg_addr); + + if (((state & CY_SD_HOST_DAT_3_0) == 0) || + ((state & CY_SD_HOST_DAT_LINE_ACTIVE) == CY_SD_HOST_DAT_LINE_ACTIVE) || + ((state & CY_SD_HOST_CMD_CMD_INHIBIT_DAT) == CY_SD_HOST_CMD_CMD_INHIBIT_DAT)) { + busy_status = 1; + } + + return busy_status; +} + +static int sdhc_infineon_get_host_props(const struct device *dev, struct sdhc_host_props *props) +{ + struct sdhc_infineon_data *sdhc_data = dev->data; + + memcpy(props, &sdhc_data->props, sizeof(struct sdhc_host_props)); + + return 0; +} + +static int sdhc_infineon_enable_interrupt(const struct device *dev, sdhc_interrupt_cb_t callback, + int sources, void *user_data) +{ + struct sdhc_infineon_data *sdhc_data = dev->data; + const struct sdhc_infineon_config *config = dev->config; + uint32_t cur_int_mask = Cy_SD_Host_GetNormalInterruptMask(config->reg_addr); + + if (sources != SDHC_INT_SDIO) { + return -ENOTSUP; + } + + if (callback == NULL) { + return -EINVAL; + } + + /* Record SDIO callback parameters */ + sdhc_data->sdio_cb = callback; + sdhc_data->sdio_cb_user_data = user_data; + + /* Enable CARD INTERRUPT */ + sdhc_data->irq_cause |= CY_SD_HOST_CARD_INTERRUPT; + Cy_SD_Host_SetNormalInterruptMask(config->reg_addr, + cur_int_mask | CY_SD_HOST_CARD_INTERRUPT); + + return 0; +} + +static int sdhc_infineon_disable_interrupt(const struct device *dev, int sources) +{ + struct sdhc_infineon_data *sdhc_data = dev->data; + const struct sdhc_infineon_config *config = dev->config; + uint32_t cur_int_mask = Cy_SD_Host_GetNormalInterruptMask(config->reg_addr); + + if (sources != SDHC_INT_SDIO) { + return -ENOTSUP; + } + + sdhc_data->sdio_cb = NULL; + sdhc_data->sdio_cb_user_data = NULL; + + /* Disable CARD INTERRUPT */ + sdhc_data->irq_cause &= ~CY_SD_HOST_CARD_INTERRUPT; + Cy_SD_Host_SetNormalInterruptMask(config->reg_addr, + cur_int_mask & ~CY_SD_HOST_CARD_INTERRUPT); + + return 0; +} + +static int sdhc_infineon_init(const struct device *dev) +{ + int result = 0; + const struct sdhc_infineon_config *config = dev->config; + struct sdhc_infineon_data *sdhc_data = dev->data; + cy_stc_sd_host_context_t context; + + /* Configure DT provided device signals when available */ + result = pinctrl_apply_state(config->pincfg, PINCTRL_STATE_DEFAULT); + if (result) { + return result; + } + + if (config->cd_gpio.port != NULL) { + if (!device_is_ready(config->cd_gpio.port)) { + LOG_ERR("Card detect GPIO device not ready"); + return -ENODEV; + } + + result = gpio_pin_configure_dt(&config->cd_gpio, GPIO_INPUT); + if (result < 0) { + LOG_ERR("Couldn't configure card-detect pin; (%d)", result); + return result; + } + } + +#if defined(CONFIG_SOC_FAMILY_INFINEON_EDGE) + if (config->reg_addr == SDHC0) { + Cy_SysClk_PeriGroupSlaveInit(CY_MMIO_SDHC0_PERI_NR, CY_MMIO_SDHC0_GROUP_NR, + CY_MMIO_SDHC0_SLAVE_NR, CY_MMIO_SDHC0_CLK_HF_NR); + } else if (config->reg_addr == SDHC1) { + Cy_SysClk_PeriGroupSlaveInit(CY_MMIO_SDHC1_PERI_NR, CY_MMIO_SDHC1_GROUP_NR, + CY_MMIO_SDHC1_SLAVE_NR, CY_MMIO_SDHC1_CLK_HF_NR); + } +#endif + + k_sem_init(&sdhc_data->thread_lock, 1, 1); + k_sem_init(&sdhc_data->transfer_sem, 1, 1); + + /* Enable the SDHC block */ + Cy_SD_Host_Enable(config->reg_addr); + + /* Configure SD Host to operate */ + result = (int)Cy_SD_Host_Init(config->reg_addr, &sdhc_config, &context); + if (result != 0) { + return -EFAULT; + } + + irq_enable(config->irq); + + /* Clear slot data so card is initialized at set_io() */ + sdhc_data->bus_clock = 0U; + sdhc_data->bus_width = CY_SD_HOST_BUS_WIDTH_1_BIT; + sdhc_data->power_mode = SDHC_POWER_OFF; + sdhc_data->speed_mode = CY_SD_HOST_BUS_SPEED_DEFAULT; + sdhc_data->signal_voltage = SD_VOL_3_3_V; + + return 0; +} + +static DEVICE_API(sdhc, sdhc_infineon_api) = { + .reset = sdhc_infineon_reset, + .request = sdhc_infineon_request, + .set_io = sdhc_infineon_set_io, + .get_card_present = sdhc_infineon_get_card_present, + .execute_tuning = sdhc_infineon_execute_tuning, + .card_busy = sdhc_infineon_card_busy, + .get_host_props = sdhc_infineon_get_host_props, + .enable_interrupt = sdhc_infineon_enable_interrupt, + .disable_interrupt = sdhc_infineon_disable_interrupt, +}; + +#if defined(CONFIG_SOC_FAMILY_INFINEON_EDGE) +#define IFX_SDHC_IRQ_INIT(n) \ + void sdhc_infineon_isr_##n(void) \ + { \ + sdhc_infineon_irq_handler(DEVICE_DT_INST_GET(n)); \ + } \ + static void sdhc_infineon_irq_config_##n(void) \ + { \ + IRQ_CONNECT(DT_INST_IRQ_BY_IDX(n, 1, irq), DT_INST_IRQ_BY_IDX(n, 1, priority), \ + sdhc_infineon_isr_##n, DEVICE_DT_INST_GET(n), 0); \ + } + +#define IRQ_INFO(n) \ + .irq = DT_INST_IRQN_BY_IDX(n, 1), .irq_priority = DT_INST_IRQ_BY_IDX(n, 1, priority) + +#define PERI_INFO(n) .clock_peri_group = DT_PROP_BY_IDX(DT_INST_PHANDLE(n, clocks), peri_group, 1), + +#define IFX_SDHC_PERI_CLOCK_INIT(n) \ + .clock = \ + { \ + .block = IFX_CAT1_PERIPHERAL_GROUP_ADJUST( \ + DT_PROP_BY_IDX(DT_INST_PHANDLE(n, clocks), peri_group, 0), \ + DT_PROP_BY_IDX(DT_INST_PHANDLE(n, clocks), peri_group, 1), \ + DT_INST_PROP_BY_PHANDLE(n, clocks, div_type)), \ + }, \ + PERI_INFO(n) +#elif defined(COMPONENT_CAT1A) +#define IFX_SDHC_IRQ_INIT(n) \ + void sdhc_infineon_isr_##n(void) \ + { \ + sdhc_infineon_irq_handler(DEVICE_DT_INST_GET(n)); \ + } \ + static void sdhc_infineon_irq_config_##n(void) \ + { \ + IRQ_CONNECT(DT_INST_IRQ_BY_IDX(n, 0, irq) + 1, DT_INST_IRQ_BY_IDX(n, 0, priority), \ + sdhc_infineon_isr_##n, DEVICE_DT_INST_GET(n), 0); \ + } +#define IRQ_INFO(n) \ + .irq = DT_INST_IRQN_BY_IDX(n, 0) + 1, .irq_priority = DT_INST_IRQ_BY_IDX(n, 0, priority) +#define PERI_INFO(n) +#define IFX_SDHC_PERI_CLOCK_INIT(n) +#endif + +#define IFX_SDHC_IRQ_CONFIG(n) sdhc_infineon_irq_config_##n(); + +#define IFX_SDHC_INIT(n) \ + \ + PINCTRL_DT_INST_DEFINE(n); \ + IFX_SDHC_IRQ_INIT(n) \ + \ + static int sdhc_infineon_init##n(const struct device *dev) \ + { \ + IFX_SDHC_IRQ_CONFIG(n); \ + return sdhc_infineon_init(dev); \ + } \ + \ + static const struct sdhc_infineon_config sdhc_infineon_##n##_config = { \ + .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ + .cd_gpio = GPIO_DT_SPEC_INST_GET_OR(n, cd_gpios, {0}), \ + .reg_addr = (SDHC_Type *)DT_INST_REG_ADDR(n), \ + .irq_priority = DT_INST_IRQ(n, priority), \ + IRQ_INFO(n)}; \ + \ + static struct sdhc_infineon_data sdhc_infineon_##n##_data = { \ + .power_mode = SDHC_POWER_ON, \ + .speed_mode = CY_SD_HOST_BUS_SPEED_DEFAULT, \ + .props = {.is_spi = false, \ + .f_max = DT_INST_PROP(n, max_bus_freq), \ + .f_min = DT_INST_PROP(n, min_bus_freq), \ + .power_delay = DT_INST_PROP(n, power_delay_ms), \ + .host_caps = {.vol_180_support = !DT_INST_PROP(n, no_1_8_v), \ + .vol_300_support = false, \ + .vol_330_support = true, \ + .suspend_res_support = false, \ + .sdma_support = true, \ + .high_spd_support = \ + (DT_INST_PROP(n, bus_width) == 4) ? true : false, \ + .adma_2_support = true, \ + .adma3_support = true, \ + .sdio_async_interrupt_support = true, \ + .ddr50_support = false, \ + .sdr104_support = false, \ + .sdr50_support = true, \ + .bus_8_bit_support = false, \ + .bus_4_bit_support = \ + (DT_INST_PROP(n, bus_width) == 4) ? true : false, \ + .hs200_support = false, \ + .hs400_support = false}}, \ + IFX_SDHC_PERI_CLOCK_INIT(n)}; \ + \ + DEVICE_DT_INST_DEFINE(n, &sdhc_infineon_init##n, NULL, &sdhc_infineon_##n##_data, \ + &sdhc_infineon_##n##_config, POST_KERNEL, CONFIG_SDHC_INIT_PRIORITY, \ + &sdhc_infineon_api); + +DT_INST_FOREACH_STATUS_OKAY(IFX_SDHC_INIT) diff --git a/drivers/wifi/infineon/Kconfig.airoc b/drivers/wifi/infineon/Kconfig.airoc index 44ad9b1a0260..6366f43b8b05 100644 --- a/drivers/wifi/infineon/Kconfig.airoc +++ b/drivers/wifi/infineon/Kconfig.airoc @@ -244,6 +244,11 @@ config CYW955513SDM2WLIPA_SM bool "CYW955513SDM2WLIPA_SM" help Infineon CYW955513SDM2WLIPA (SM) module + +config CYW55513IUBG_SM + bool "CYW55513IUBG_SM" + help + Infineon CYW55513IUBG (SM) module endchoice choice CYW55572_MODULE @@ -254,11 +259,6 @@ config CYW955573M2IPA1_SM bool "CYW955573M2IPA1_SM" help Infineon CYW955573M2IPA1 (SM) module - -config CYW55513IUBG_SM - bool "CYW55513IUBG_SM" - help - Infineon CYW55513IUBG (SM) module endchoice endif # AIROC_WIFI diff --git a/dts/bindings/sdhc/infineon,sdhc-sdio.yaml b/dts/bindings/sdhc/infineon,sdhc-sdio.yaml index e32efeff5703..215cffff5e56 100644 --- a/dts/bindings/sdhc/infineon,sdhc-sdio.yaml +++ b/dts/bindings/sdhc/infineon,sdhc-sdio.yaml @@ -1,5 +1,5 @@ -# Copyright (c) 2023 Cypress Semiconductor Corporation (an Infineon company) or -# an affiliate of Cypress Semiconductor Corporation +# Copyright (c) 2025 Infineon Technologies AG, +# or an affiliate of Infineon Technologies AG. # # SPDX-License-Identifier: Apache-2.0 @@ -24,3 +24,24 @@ properties: system-interrupts: description: Required for cat1c devices + + bus-width: + type: int + default: 4 + description: | + bus width for SDMMC access, defaults to the minimum necessary + number of bus lines + enum: + - 1 + - 4 + - 8 + + no-1-8-v: + type: boolean + description: | + The SD/MMC bus on the board doesn't support the 1.8V voltage, + Which disables UHS-I, HS200 and HS400 support. + + cd-gpios: + type: phandle-array + description: Card Detect pin diff --git a/modules/hal_infineon/CMakeLists.txt b/modules/hal_infineon/CMakeLists.txt index c3071524e6fc..9750fd7690ee 100644 --- a/modules/hal_infineon/CMakeLists.txt +++ b/modules/hal_infineon/CMakeLists.txt @@ -85,8 +85,11 @@ endif() if(CONFIG_WIFI_AIROC) add_subdirectory(whd-expansion) - ## Add core-lib sources for CAT1 devices - add_subdirectory_ifndef(CONFIG_SOC_FAMILY_INFINEON_CAT1 core-lib) + if(NOT CONFIG_SOC_FAMILY_INFINEON_CAT1 + AND NOT CONFIG_SOC_FAMILY_PSOC6_LEGACY + AND NOT CONFIG_SOC_FAMILY_INFINEON_EDGE) + add_subdirectory(core-lib) + endif() ## Add abstraction-rtos sources add_subdirectory_ifndef(CONFIG_SOC_FAMILY_INFINEON_CAT1 abstraction-rtos) From 2e8b47462afcdd421458afa691343c367294e61f Mon Sep 17 00:00:00 2001 From: Kevin Chan Date: Thu, 18 Dec 2025 14:32:46 -0800 Subject: [PATCH 2514/3659] samples: net: wifi: shell: support PSE84 - add conf. file Signed-off-by: Kevin Chan --- .../boards/kit_pse84_eval_pse846gps2dbzc4a_m55.conf | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 samples/net/wifi/shell/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.conf diff --git a/samples/net/wifi/shell/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.conf b/samples/net/wifi/shell/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.conf new file mode 100644 index 000000000000..7dbd1add6ee6 --- /dev/null +++ b/samples/net/wifi/shell/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.conf @@ -0,0 +1,10 @@ +# Copyright (c) 2025 Infineon Technologies AG, +# or an affiliate of Infineon Technologies AG. +# +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SHELL_STACK_SIZE=6144 +CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048 +CONFIG_NET_MGMT_EVENT_STACK_SIZE=4608 +CONFIG_NET_TCP_WORKQ_STACK_SIZE=2048 +CONFIG_IDLE_STACK_SIZE=1024 From 365ce110669c99f34f3a0c19860ef8bf76e1bbf5 Mon Sep 17 00:00:00 2001 From: Kevin Chan Date: Fri, 12 Dec 2025 14:50:46 -0800 Subject: [PATCH 2515/3659] samples: subsys: fs: fs_sample: support PSE84 - add overlay and conf file Signed-off-by: Kevin Chan --- .../kit_pse84_eval_pse846gps2dbzc4a_m55.conf | 6 ++++++ .../kit_pse84_eval_pse846gps2dbzc4a_m55.overlay | 16 ++++++++++++++++ 2 files changed, 22 insertions(+) create mode 100644 samples/subsys/fs/fs_sample/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.conf create mode 100644 samples/subsys/fs/fs_sample/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.overlay diff --git a/samples/subsys/fs/fs_sample/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.conf b/samples/subsys/fs/fs_sample/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.conf new file mode 100644 index 000000000000..f485769f88c2 --- /dev/null +++ b/samples/subsys/fs/fs_sample/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.conf @@ -0,0 +1,6 @@ +# Copyright (c) 2025 Infineon Technologies AG, +# or an affiliate of Infineon Technologies AG. +# +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_LOG=n diff --git a/samples/subsys/fs/fs_sample/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.overlay b/samples/subsys/fs/fs_sample/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.overlay new file mode 100644 index 000000000000..ab83f8fd3165 --- /dev/null +++ b/samples/subsys/fs/fs_sample/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.overlay @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + sdhc0 = &sdhc1; + }; +}; + +&sdhc1 { + status = "okay"; +}; From ac0ad06f9e30bb1141552c6eaa08316a0bbd0f1d Mon Sep 17 00:00:00 2001 From: Kevin Chan Date: Fri, 12 Dec 2025 14:42:03 -0800 Subject: [PATCH 2516/3659] tests: subsys: sd: sdmmc: support PSE84 - add overlay file for CM55 Signed-off-by: Kevin Chan --- .../kit_pse84_eval_pse846gps2dbzc4a_m55.overlay | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 tests/subsys/sd/sdmmc/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.overlay diff --git a/tests/subsys/sd/sdmmc/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.overlay b/tests/subsys/sd/sdmmc/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.overlay new file mode 100644 index 000000000000..ab83f8fd3165 --- /dev/null +++ b/tests/subsys/sd/sdmmc/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.overlay @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + sdhc0 = &sdhc1; + }; +}; + +&sdhc1 { + status = "okay"; +}; From e7720307ef651602d91c1caa41c173a6712edfb9 Mon Sep 17 00:00:00 2001 From: Kevin Chan Date: Fri, 12 Dec 2025 14:25:42 -0800 Subject: [PATCH 2517/3659] tests: drivers: sdhc: support PSE84 - add overlay files for CM55 in order to run sdhc app. Signed-off-by: Kevin Chan --- .../kit_pse84_eval_pse846gps2dbzc4a_m55.overlay | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 tests/drivers/sdhc/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.overlay diff --git a/tests/drivers/sdhc/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.overlay b/tests/drivers/sdhc/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.overlay new file mode 100644 index 000000000000..ab83f8fd3165 --- /dev/null +++ b/tests/drivers/sdhc/boards/kit_pse84_eval_pse846gps2dbzc4a_m55.overlay @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025 Infineon Technologies AG, + * or an affiliate of Infineon Technologies AG. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + sdhc0 = &sdhc1; + }; +}; + +&sdhc1 { + status = "okay"; +}; From 3836420f2f7cd49d13ca474836bb524d8211d042 Mon Sep 17 00:00:00 2001 From: Dat Nguyen Duy Date: Fri, 26 Dec 2025 10:11:04 +0700 Subject: [PATCH 2518/3659] dts: nxp: add watchdog devicetree nodes for s32k566 Add watchdog devicetree nodes for S32K566 Signed-off-by: Dat Nguyen Duy --- dts/arm/nxp/nxp_s32k566.dtsi | 16 ++++++++++++ dts/arm/nxp/nxp_s32k566_m7.dtsi | 45 ++++++++++++++++++++++++++++++++ dts/arm/nxp/nxp_s32k566_r52.dtsi | 26 ++++++++++++++++++ 3 files changed, 87 insertions(+) diff --git a/dts/arm/nxp/nxp_s32k566.dtsi b/dts/arm/nxp/nxp_s32k566.dtsi index 201148656739..314a3483ccd1 100644 --- a/dts/arm/nxp/nxp_s32k566.dtsi +++ b/dts/arm/nxp/nxp_s32k566.dtsi @@ -780,6 +780,22 @@ status = "disabled"; }; + lpe_swt: watchdog@4207c000 { + compatible = "nxp,s32-swt"; + reg = <0x4207c000 0x4000>; + clocks = <&clock NXP_S32_SAFE_CLK>; + service-mode = "fixed"; + status = "disabled"; + }; + + swt_startup: watchdog@404a8000 { + compatible = "nxp,s32-swt"; + reg = <0x404a8000 0x4000>; + clocks = <&clock NXP_S32_SWT_STARTUP_IPG_COUNTER_CLK>; + service-mode = "fixed"; + status = "disabled"; + }; + sar_adc0: adc@40698000 { compatible = "nxp,s32-adc-sar"; reg = <0x40698000 0x4000>; diff --git a/dts/arm/nxp/nxp_s32k566_m7.dtsi b/dts/arm/nxp/nxp_s32k566_m7.dtsi index 34112665aebf..7cc20ab46203 100644 --- a/dts/arm/nxp/nxp_s32k566_m7.dtsi +++ b/dts/arm/nxp/nxp_s32k566_m7.dtsi @@ -216,6 +216,43 @@ status = "disabled"; }; }; + + /* SWT_0 -> SWT_3 for Cortex-M7_0 -> Cortex-M7_3 */ + swt0: watchdog@40b18000 { + compatible = "nxp,s32-swt"; + reg = <0x40b18000 0x4000>; + interrupts = <28 0>; + clocks = <&clock NXP_S32_SWT0_IPG_COUNTER_CLK>; + service-mode = "fixed"; + status = "disabled"; + }; + + swt1: watchdog@40b1c000 { + compatible = "nxp,s32-swt"; + reg = <0x40b1c000 0x4000>; + interrupts = <28 0>; + clocks = <&clock NXP_S32_SWT1_IPG_COUNTER_CLK>; + service-mode = "fixed"; + status = "disabled"; + }; + + swt2: watchdog@40b20000 { + compatible = "nxp,s32-swt"; + reg = <0x40b20000 0x4000>; + interrupts = <28 0>; + clocks = <&clock NXP_S32_SWT2_IPG_COUNTER_CLK>; + service-mode = "fixed"; + status = "disabled"; + }; + + swt3: watchdog@40b24000 { + compatible = "nxp,s32-swt"; + reg = <0x40b24000 0x4000>; + interrupts = <28 0>; + clocks = <&clock NXP_S32_SWT3_IPG_COUNTER_CLK>; + service-mode = "fixed"; + status = "disabled"; + }; }; }; @@ -466,3 +503,11 @@ interrupts = <97 0>; interrupt-names = "rx_tx_mru_error"; }; + +&lpe_swt { + interrupts = <210 0>; +}; + +&swt_startup { + interrupts = <27 0>; +}; diff --git a/dts/arm/nxp/nxp_s32k566_r52.dtsi b/dts/arm/nxp/nxp_s32k566_r52.dtsi index f674b44b63b4..e05de06a814b 100644 --- a/dts/arm/nxp/nxp_s32k566_r52.dtsi +++ b/dts/arm/nxp/nxp_s32k566_r52.dtsi @@ -140,6 +140,24 @@ status = "disabled"; }; }; + + swt0: watchdog@4105c000 { + compatible = "nxp,s32-swt"; + reg = <0x4105c000 0x4000>; + interrupts = ; + clocks = <&clock NXP_S32_SWT0_IPG_COUNTER_CLK>; + service-mode = "fixed"; + status = "disabled"; + }; + + swt1: watchdog@4113c000 { + compatible = "nxp,s32-swt"; + reg = <0x4113c000 0x4000>; + interrupts = ; + clocks = <&clock NXP_S32_SWT1_IPG_COUNTER_CLK>; + service-mode = "fixed"; + status = "disabled"; + }; }; }; @@ -416,3 +434,11 @@ interrupts = ; interrupt-names = "rx_tx_mru_error"; }; + +&lpe_swt { + interrupts = ; +}; + +&swt_startup { + interrupts = ; +}; From 640c4d1ba30786f798b59e86b18ae52aaa2f7593 Mon Sep 17 00:00:00 2001 From: Ha Duong Quang Date: Thu, 6 Nov 2025 15:36:57 +0700 Subject: [PATCH 2519/3659] boards: nxp: s32k5xxcvb: add support for watchdog Add support for Watchdog (SWT) Signed-off-by: Ha Duong Quang Co-authored-by: Dat Nguyen Duy Signed-off-by: Dat Nguyen Duy --- boards/nxp/s32k5xxcvb/s32k5xxcvb_s32k566.dtsi | 4 ++++ boards/nxp/s32k5xxcvb/s32k5xxcvb_s32k566_m7.yaml | 1 + boards/nxp/s32k5xxcvb/s32k5xxcvb_s32k566_r52.yaml | 1 + 3 files changed, 6 insertions(+) diff --git a/boards/nxp/s32k5xxcvb/s32k5xxcvb_s32k566.dtsi b/boards/nxp/s32k5xxcvb/s32k5xxcvb_s32k566.dtsi index 993107561b78..178f9a5c007d 100644 --- a/boards/nxp/s32k5xxcvb/s32k5xxcvb_s32k566.dtsi +++ b/boards/nxp/s32k5xxcvb/s32k5xxcvb_s32k566.dtsi @@ -15,6 +15,7 @@ led2 = &user_led_blue; sw0 = &user_button_0; sw1 = &user_button_1; + watchdog0 = &swt_startup; }; chosen { @@ -82,5 +83,8 @@ &flexcan0 { pinctrl-0 = <&flexcan0_default>; pinctrl-names = "default"; +}; + +&swt_startup { status = "okay"; }; diff --git a/boards/nxp/s32k5xxcvb/s32k5xxcvb_s32k566_m7.yaml b/boards/nxp/s32k5xxcvb/s32k5xxcvb_s32k566_m7.yaml index 35be8009dad9..1810ae7bd4c3 100644 --- a/boards/nxp/s32k5xxcvb/s32k5xxcvb_s32k566_m7.yaml +++ b/boards/nxp/s32k5xxcvb/s32k5xxcvb_s32k566_m7.yaml @@ -16,4 +16,5 @@ supported: - pwm - counter - i2c + - watchdog vendor: nxp diff --git a/boards/nxp/s32k5xxcvb/s32k5xxcvb_s32k566_r52.yaml b/boards/nxp/s32k5xxcvb/s32k5xxcvb_s32k566_r52.yaml index 41d218e21581..4e9a944aa011 100644 --- a/boards/nxp/s32k5xxcvb/s32k5xxcvb_s32k566_r52.yaml +++ b/boards/nxp/s32k5xxcvb/s32k5xxcvb_s32k566_r52.yaml @@ -16,4 +16,5 @@ supported: - pwm - counter - i2c + - watchdog vendor: nxp From 2d019f163d77ce454b90be72093402bd61d25db7 Mon Sep 17 00:00:00 2001 From: Dat Nguyen Duy Date: Fri, 26 Dec 2025 10:14:54 +0700 Subject: [PATCH 2520/3659] samples: support watchdog samples for s32k5xxvcb Only enable watchdog sample for cm7. For cr52, because the SoC set the cores in Thumb mode after reset, so a debugger is always needed to switch the core to Arm state before loading zephyr application. Signed-off-by: Dat Nguyen Duy --- samples/drivers/watchdog/sample.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/samples/drivers/watchdog/sample.yaml b/samples/drivers/watchdog/sample.yaml index c7fffc99001a..2c24caf2eee6 100644 --- a/samples/drivers/watchdog/sample.yaml +++ b/samples/drivers/watchdog/sample.yaml @@ -22,6 +22,7 @@ tests: - s32z2xxdc2/s32z270/rtu1 - s32z2xxdc2@D/s32z270/rtu0 - s32z2xxdc2@D/s32z270/rtu1 + - s32k5xxcvb/s32k566/r52 - panb611evb/nrf54l15/cpuapp - panb611evb/nrf54l15/cpuapp/ns - panb611evb/nrf54l15/cpuflpr @@ -149,12 +150,13 @@ tests: - longan_nano integration_platforms: - gd32e103v_eval - sample.drivers.watchdog.s32z270dc2_r52: + sample.drivers.watchdog.nxp_s32_swt: build_only: true platform_allow: - s32z2xxdc2/s32z270/rtu0 - s32z2xxdc2/s32z270/rtu1 - s32z2xxdc2@D/s32z270/rtu0 - s32z2xxdc2@D/s32z270/rtu1 + - s32k5xxcvb/s32k566/r52 integration_platforms: - s32z2xxdc2/s32z270/rtu0 From 2247f4dc7a0e7a8afa9bd9bf47387742f94c088e Mon Sep 17 00:00:00 2001 From: Dat Nguyen Duy Date: Fri, 26 Dec 2025 10:27:12 +0700 Subject: [PATCH 2521/3659] tests: drivers: support watchdog tests for s32k5xxcvb Enable wdt_basic_api watchdog only for cm7. For cr52, because the SoC set the cores in Thumb mode after reset, so a debugger is always needed to switch the core to Arm state before loading zephyr application. wdt_basic_reset_none test can be enabled for both. Signed-off-by: Dat Nguyen Duy --- tests/drivers/watchdog/wdt_basic_api/testcase.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/drivers/watchdog/wdt_basic_api/testcase.yaml b/tests/drivers/watchdog/wdt_basic_api/testcase.yaml index 75cdc5da40e3..fdeb2ecfcbd0 100644 --- a/tests/drivers/watchdog/wdt_basic_api/testcase.yaml +++ b/tests/drivers/watchdog/wdt_basic_api/testcase.yaml @@ -18,6 +18,7 @@ tests: - s32z2xxdc2/s32z270/rtu1 - s32z2xxdc2@D/s32z270/rtu0 - s32z2xxdc2@D/s32z270/rtu1 + - s32k5xxcvb/s32k566/r52 - mps2/an383 - mps2/an385 - mps2/an386 @@ -147,6 +148,7 @@ tests: - s32z2xxdc2/s32z270/rtu1 - s32z2xxdc2@D/s32z270/rtu0 - s32z2xxdc2@D/s32z270/rtu1 + - s32k5xxcvb/s32k566/r52 - mr_canhubk3 integration_platforms: - s32z2xxdc2/s32z270/rtu0 From cc18a23ec91e40a1633758a7dbcfe183430298fa Mon Sep 17 00:00:00 2001 From: Lyle Zhu Date: Wed, 31 Dec 2025 11:51:36 +0800 Subject: [PATCH 2522/3659] bluetooth: classic: GOEP: fix L2CAP MTU calculation Correct the minimum MTU calculation for GOEP over L2CAP to account for the L2CAP I-frame overhead. - Update BT_BUF_ACL_RX_SIZE default from 264 to 265 bytes for GOEP - Update BT_GOEP_L2CAP_MTU minimum range from 259 to 265 bytes - Add detailed comment explaining L2CAP I-frame field length (6 bytes): * 4 bytes for extended control field * 2 bytes for FCS field The previous calculation only accounted for the L2CAP header (4 bytes) but missed the 6-byte L2CAP I-frame overhead (extended control field and FCS), resulting in an incorrect minimum of 264 bytes instead of the correct 265 bytes. And it causes the minimum MTU of L2CAP to be incorrectly set to 254. The MTU cannot meet the minimum requirement of GOEP MOPL. The correct calculation for GOEP over L2CAP is: 255 bytes (GOEP minimum MTU) + 4 bytes (L2CAP header) + 6 bytes (L2CAP I-frame) = 265 bytes total. Set the default value of CONFIG_BT_BUF_ACL_RX_SIZE to 265 if GOEP is enabled. Signed-off-by: Lyle Zhu --- subsys/bluetooth/common/Kconfig | 10 ++++++++-- subsys/bluetooth/host/classic/Kconfig | 5 ++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/subsys/bluetooth/common/Kconfig b/subsys/bluetooth/common/Kconfig index 9ba9cb325855..f9eb4b622027 100644 --- a/subsys/bluetooth/common/Kconfig +++ b/subsys/bluetooth/common/Kconfig @@ -50,11 +50,17 @@ config BT_BUF_ACL_TX_COUNT config BT_BUF_ACL_RX_SIZE int "Maximum supported ACL size for incoming data" - # For GOEP over RFCOMM, including, + # For GOEP over RFCOMM, the minimum MTU of GOEP is 264, including, # 255 bytes - the minimum MTU of GOEP, # 4 bytes - L2CAP Header, # 5 bytes - 4 bytes for RFCOMM header with extended length, 1 byte for FCS. - default 264 if BT_CLASSIC && BT_GOEP + # For GOEP over L2CAP, the minimum MTU of GOEP is 265, including, + # 255 bytes - the minimum MTU of GOEP, + # 4 bytes - L2CAP Header, + # 6 bytes - Field length of L2CAP I-frame, including, + # 4 bytes - extended control field, + # 2 bytes - FCS field. + default 265 if BT_CLASSIC && BT_GOEP default 200 if BT_CLASSIC default 70 if BT_EATT default 69 if BT_SMP diff --git a/subsys/bluetooth/host/classic/Kconfig b/subsys/bluetooth/host/classic/Kconfig index bf8222da6444..b1059ff5c6f1 100644 --- a/subsys/bluetooth/host/classic/Kconfig +++ b/subsys/bluetooth/host/classic/Kconfig @@ -685,7 +685,10 @@ config BT_GOEP_L2CAP_MTU # For GOEP over L2CAP, including, # 255 bytes - the minimum MTU of GOEP, # 4 bytes - L2CAP Header, - range 259 BT_BUF_ACL_RX_SIZE + # 6 bytes - Field length of L2CAP I-frame, including, + # 4 bytes - extended control field, + # 2 bytes - FCS field. + range 265 BT_BUF_ACL_RX_SIZE help Maximum size of L2CAP MTU for GOEP. RX MTU will be truncated to account for ACL data and type overhead, and the L2CAP PDU From a2b583081a85022bf0bf93ff9ae5b6170f828633 Mon Sep 17 00:00:00 2001 From: David Jewsbury Date: Fri, 21 Nov 2025 15:18:14 +0000 Subject: [PATCH 2523/3659] drivers: mspi_dw: fix DMA transfer size logic Fixing of erroneous RXTRANSFERLENGTH and number of transfer frames calculation. Signed-off-by: David Jewsbury --- drivers/mspi/mspi_dw.c | 15 +++++++++------ drivers/mspi/mspi_dw_vendor_specific.h | 5 ++--- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/drivers/mspi/mspi_dw.c b/drivers/mspi/mspi_dw.c index d26a537e8af9..bb91ec984d35 100644 --- a/drivers/mspi/mspi_dw.c +++ b/drivers/mspi/mspi_dw.c @@ -160,6 +160,9 @@ DEFINE_MM_REG_WR(xip_write_wrap_inst, 0x144) DEFINE_MM_REG_WR(xip_write_ctrl, 0x148) #endif +/* Ceiling division by 32 */ +#define CEIL_DIV_32(x) (((x) + 31U) >> 5) + #include "mspi_dw_vendor_specific.h" static int start_next_packet(const struct device *dev); @@ -1274,16 +1277,16 @@ static int start_next_packet(const struct device *dev) #if defined(CONFIG_MSPI_DMA) if (dev_data->xfer.xfer_mode == MSPI_DMA) { /* For DMA mode, set start level based on transfer length to prevent underflow */ - uint32_t total_transfer_bytes = packet->num_bytes + dev_data->xfer.addr_length + - dev_data->xfer.cmd_length; - uint32_t transfer_frames = total_transfer_bytes >> dev_data->bytes_per_frame_exp; + uint32_t transfer_frames = (packet->num_bytes >> dev_data->bytes_per_frame_exp) + + CEIL_DIV_32(dev_data->xfer.addr_length) + + CEIL_DIV_32(dev_data->xfer.cmd_length); - /* Use minimum of transfer length or FIFO depth, but at least 1 */ + /* Above dma_start_level, the transfer will start. + * Use minimum of transfer length and FIFO depth. + */ uint8_t dma_start_level = MIN(transfer_frames - 1, dev_config->tx_fifo_depth_minus_1); - dma_start_level = (dma_start_level > 0 ? dma_start_level : 1); - /* Only TXFTHR needs to be set to the minimum number of frames */ write_txftlr(dev, FIELD_PREP(TXFTLR_TXFTHR_MASK, dma_start_level)); write_dmatdlr(dev, FIELD_PREP(DMATDLR_DMATDL_MASK, dev_config->dma_tx_data_level)); diff --git a/drivers/mspi/mspi_dw_vendor_specific.h b/drivers/mspi/mspi_dw_vendor_specific.h index d994f579ad8e..2c26cfa1b1ee 100644 --- a/drivers/mspi/mspi_dw_vendor_specific.h +++ b/drivers/mspi/mspi_dw_vendor_specific.h @@ -251,9 +251,8 @@ static inline void vendor_specific_start_dma_xfer(const struct device *dev) transfer_list->rx_job = &joblist[job_idx]; tmod = QSPI_TMOD_TX_ONLY; } else { - preg->CONFIG.RXTRANSFERLENGTH = ((packet->num_bytes + dev_data->xfer.addr_length + - dev_data->xfer.cmd_length) >> - dev_data->bytes_per_frame_exp) - 1; + preg->CONFIG.RXTRANSFERLENGTH = ((packet->num_bytes) >> + dev_data->bytes_per_frame_exp); /* If sending address or command while being configured as controller */ if (job_idx > 0 && config->op_mode == MSPI_OP_MODE_CONTROLLER) { From 2043119bcc346a4f60c1a2bc516d8103d2b1f6b5 Mon Sep 17 00:00:00 2001 From: David Jewsbury Date: Fri, 21 Nov 2025 15:27:02 +0000 Subject: [PATCH 2524/3659] drivers: mspi_dw: nrf_qspi_v2: Add ifdef to include DMA code if enabled DMA functions will not only be included if enabled for the nrf_qspi_v2 peripheral Signed-off-by: David Jewsbury --- drivers/mspi/mspi_dw_vendor_specific.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/mspi/mspi_dw_vendor_specific.h b/drivers/mspi/mspi_dw_vendor_specific.h index 2c26cfa1b1ee..fbdd0119d383 100644 --- a/drivers/mspi/mspi_dw_vendor_specific.h +++ b/drivers/mspi/mspi_dw_vendor_specific.h @@ -138,6 +138,7 @@ static inline void vendor_specific_irq_clear(const struct device *dev) preg->EVENTS_DMA.DONE = 0; } +#if defined(CONFIG_MSPI_DMA) /* DMA support */ #define EVDMA_ATTR_LEN_Pos (0UL) @@ -308,6 +309,7 @@ static inline bool vendor_specific_read_dma_irq(const struct device *dev) return (bool) preg->EVENTS_DMA.DONE; } +#endif /*defined(CONFIG_MSPI_DMA)*/ #else /* Supply empty vendor specific macros for generic case */ From 1cbaa5f3f516ece44d7ce8d4c95633d1ff7273bc Mon Sep 17 00:00:00 2001 From: David Jewsbury Date: Mon, 24 Nov 2025 17:59:41 +0000 Subject: [PATCH 2525/3659] drivers: mspi_dw: nrf_qspi_v2: Remove redundant EVDMA definitions EVDMA register access has been cleaned up to remove redundant macros. EVDMA_PLAIN_DATA enum has also been added of value 0x3F which previously had been assumed to be a masking of all the other values but isn't, it's its own distinct value. Other enums still exist for future use. Signed-off-by: David Jewsbury --- drivers/mspi/mspi_dw_vendor_specific.h | 29 +++++++------------------- 1 file changed, 8 insertions(+), 21 deletions(-) diff --git a/drivers/mspi/mspi_dw_vendor_specific.h b/drivers/mspi/mspi_dw_vendor_specific.h index fbdd0119d383..f3627132f669 100644 --- a/drivers/mspi/mspi_dw_vendor_specific.h +++ b/drivers/mspi/mspi_dw_vendor_specific.h @@ -140,19 +140,9 @@ static inline void vendor_specific_irq_clear(const struct device *dev) #if defined(CONFIG_MSPI_DMA) /* DMA support */ - -#define EVDMA_ATTR_LEN_Pos (0UL) -#define EVDMA_ATTR_LEN_Msk (0x00FFFFFFUL) - #define EVDMA_ATTR_ATTR_Pos (24UL) #define EVDMA_ATTR_ATTR_Msk (0x3FUL << EVDMA_ATTR_ATTR_Pos) -#define EVDMA_ATTR_32AXI_Pos (30UL) -#define EVDMA_ATTR_32AXI_Msk (0x1UL << EVDMA_ATTR_32AXI_Pos) - -#define EVDMA_ATTR_EVENTS_Pos (31UL) -#define EVDMA_ATTR_EVENTS_Msk (0x1UL << EVDMA_ATTR_EVENTS_Pos) - typedef enum { EVDMA_BYTE_SWAP = 0, EVDMA_JOBLIST = 1, @@ -160,13 +150,9 @@ typedef enum { EVDMA_FIXED_ATTR = 3, EVDMA_STATIC_ADDR = 4, EVDMA_PLAIN_DATA_BUF_WR = 5, + EVDMA_PLAIN_DATA = 0x3f, } EVDMA_ATTR_Type; -/* Setup EVDMA attribute with the following configuratrion */ -#define EVDMA_ATTRIBUTE (BIT(EVDMA_BYTE_SWAP) | BIT(EVDMA_JOBLIST) | \ - BIT(EVDMA_BUFFER_FILL) | BIT(EVDMA_FIXED_ATTR) | \ - BIT(EVDMA_STATIC_ADDR) | BIT(EVDMA_PLAIN_DATA_BUF_WR)) - typedef struct { uint8_t *addr; uint32_t attr; @@ -229,13 +215,14 @@ static inline void vendor_specific_start_dma_xfer(const struct device *dev) /* * The Command and Address will always have a length of 4 from the DMA's - * perspective. QSPI peripheral will use length of data specified in core registers + * perspective. QSPI peripheral will use length of data specified in core registers. + * Since the cmd and address are stored as uint32_t, byte swap is never needed. */ if (dev_data->xfer.cmd_length > 0) { - joblist[job_idx++] = EVDMA_JOB(&packet->cmd, 4, EVDMA_ATTRIBUTE); + joblist[job_idx++] = EVDMA_JOB(&packet->cmd, 4, EVDMA_PLAIN_DATA); } if (dev_data->xfer.addr_length > 0) { - joblist[job_idx++] = EVDMA_JOB(&packet->address, 4, EVDMA_ATTRIBUTE); + joblist[job_idx++] = EVDMA_JOB(&packet->address, 4, EVDMA_PLAIN_DATA); } if (packet->dir == MSPI_TX) { @@ -243,7 +230,7 @@ static inline void vendor_specific_start_dma_xfer(const struct device *dev) if (packet->num_bytes > 0) { joblist[job_idx++] = EVDMA_JOB(packet->data_buf, packet->num_bytes, - EVDMA_ATTRIBUTE); + EVDMA_PLAIN_DATA); } /* Always terminate with null job */ @@ -263,7 +250,7 @@ static inline void vendor_specific_start_dma_xfer(const struct device *dev) joblist[job_idx++] = EVDMA_NULL_JOB(); transfer_list->rx_job = &joblist[job_idx]; joblist[job_idx++] = EVDMA_JOB(packet->data_buf, packet->num_bytes, - EVDMA_ATTRIBUTE); + EVDMA_PLAIN_DATA); joblist[job_idx] = EVDMA_NULL_JOB(); } else { /* Sending command or address while configured as target isn't supported */ @@ -271,7 +258,7 @@ static inline void vendor_specific_start_dma_xfer(const struct device *dev) transfer_list->rx_job = &joblist[0]; joblist[0] = EVDMA_JOB(packet->data_buf, packet->num_bytes, - EVDMA_ATTRIBUTE); + EVDMA_PLAIN_DATA); joblist[1] = EVDMA_NULL_JOB(); transfer_list->tx_job = &joblist[1]; } From f8f94fd6cdeea46afb27b1f68cfce2222e3fbfc8 Mon Sep 17 00:00:00 2001 From: Camille BAUD Date: Wed, 7 Jan 2026 12:32:01 +0100 Subject: [PATCH 2526/3659] drivers: rp2: Add support for RP2350 for vreg Adds support for RP2350 in vreg regulator driver Signed-off-by: Camille BAUD --- drivers/regulator/regulator_rpi_pico.c | 83 +++++++++++++++---- .../raspberrypi,core-supply-regulator.yaml | 3 + dts/vendor/raspberrypi/rpi_pico/rp2350.dtsi | 7 ++ 3 files changed, 79 insertions(+), 14 deletions(-) diff --git a/drivers/regulator/regulator_rpi_pico.c b/drivers/regulator/regulator_rpi_pico.c index 7ea44fb4440b..ff40492d355e 100644 --- a/drivers/regulator/regulator_rpi_pico.c +++ b/drivers/regulator/regulator_rpi_pico.c @@ -10,19 +10,51 @@ #include #include #include + +#ifdef CONFIG_SOC_SERIES_RP2350 +#include +#include +#else #include #include +#endif static const struct linear_range core_ranges[] = { +#ifdef CONFIG_SOC_SERIES_RP2350 + LINEAR_RANGE_INIT(550000u, 50000u, 0u, 17u), + LINEAR_RANGE_INIT(1500000u, 100000u, 18u, 19u), + LINEAR_RANGE_INIT(1650000u, 50000u, 20u, 21u), + LINEAR_RANGE_INIT(1800000u, 100000u, 22u, 24u), + LINEAR_RANGE_INIT(2350000u, 50000u, 25u, 25u), + LINEAR_RANGE_INIT(2500000u, 150000u, 26u, 28u), + LINEAR_RANGE_INIT(3000000u, 150000u, 29u, 31u), +#else LINEAR_RANGE_INIT(800000u, 0u, 0u, 5u), LINEAR_RANGE_INIT(850000u, 50000u, 6u, 15u), +#endif }; static const size_t num_core_ranges = ARRAY_SIZE(core_ranges); +#ifdef CONFIG_SOC_SERIES_RP2350 +#define REG_PICO_TYPE powman_hw_t +#define REG_VSEL_POS POWMAN_VREG_VSEL_LSB +#define REG_VSEL_MSK POWMAN_VREG_VSEL_BITS +#define REG_VALIN(value) (POWMAN_PASSWORD_BITS | (value)) +#define REG_BOD_VSEL_POS POWMAN_BOD_VSEL_LSB +#define REG_BOD_EN_POS POWMAN_BOD_EN_LSB +#else +#define REG_PICO_TYPE vreg_and_chip_reset_hw_t +#define REG_VSEL_POS VREG_AND_CHIP_RESET_VREG_VSEL_LSB +#define REG_VSEL_MSK VREG_AND_CHIP_RESET_VREG_VSEL_BITS +#define REG_VALIN(value) (value) +#define REG_BOD_VSEL_POS VREG_AND_CHIP_RESET_BOD_VSEL_LSB +#define REG_BOD_EN_POS VREG_AND_CHIP_RESET_BOD_EN_LSB +#endif + struct regulator_rpi_pico_config { struct regulator_common_config common; - vreg_and_chip_reset_hw_t * const reg; + REG_PICO_TYPE * const reg; const bool brown_out_detection; const uint32_t brown_out_threshold; }; @@ -31,6 +63,17 @@ struct regulator_rpi_pico_data { struct regulator_common_data data; }; +#ifdef CONFIG_SOC_SERIES_RP2350 +static void regulator_rpi_pico_wait_powman(const struct device *dev) +{ + const struct regulator_rpi_pico_config *config = dev->config; + + while (config->reg->vreg & POWMAN_VREG_UPDATE_IN_PROGRESS_BITS) { + k_usleep(10); + } +} +#endif + /* * APIs */ @@ -57,8 +100,16 @@ static int regulator_rpi_pico_set_voltage(const struct device *dev, int32_t min_ return ret; } - config->reg->vreg = ((config->reg->vreg & ~VREG_AND_CHIP_RESET_VREG_VSEL_BITS) | - (idx << VREG_AND_CHIP_RESET_VREG_VSEL_LSB)); +#ifdef CONFIG_SOC_SERIES_RP2350 + config->reg->vreg_ctrl |= REG_VALIN(POWMAN_VREG_CTRL_UNLOCK_BITS); + regulator_rpi_pico_wait_powman(dev); +#endif + + config->reg->vreg = REG_VALIN((config->reg->vreg & ~REG_VSEL_MSK) | idx << REG_VSEL_POS); + +#ifdef CONFIG_SOC_SERIES_RP2350 + regulator_rpi_pico_wait_powman(dev); +#endif return 0; } @@ -69,25 +120,27 @@ static int regulator_rpi_pico_get_voltage(const struct device *dev, int32_t *vol return linear_range_group_get_value( core_ranges, num_core_ranges, - ((config->reg->vreg & VREG_AND_CHIP_RESET_VREG_VSEL_BITS) >> - VREG_AND_CHIP_RESET_VREG_VSEL_LSB), - volt_uv); + ((config->reg->vreg & REG_VSEL_MSK) >> REG_VSEL_POS), volt_uv); } static int regulator_rpi_pico_enable(const struct device *dev) { +#ifdef CONFIG_SOC_SERIES_RP2040 const struct regulator_rpi_pico_config *config = dev->config; config->reg->vreg |= BIT(VREG_AND_CHIP_RESET_VREG_EN_LSB); +#endif return 0; } static int regulator_rpi_pico_disable(const struct device *dev) { +#ifdef CONFIG_SOC_SERIES_RP2040 const struct regulator_rpi_pico_config *config = dev->config; config->reg->vreg &= ~BIT(VREG_AND_CHIP_RESET_VREG_EN_LSB); +#endif return 0; } @@ -97,9 +150,9 @@ static int regulator_rpi_pico_set_mode(const struct device *dev, regulator_mode_ const struct regulator_rpi_pico_config *config = dev->config; if (mode & REGULATOR_RPI_PICO_MODE_HI_Z) { - config->reg->vreg |= REGULATOR_RPI_PICO_MODE_HI_Z; + config->reg->vreg |= REG_VALIN(REGULATOR_RPI_PICO_MODE_HI_Z); } else { - config->reg->vreg &= (~REGULATOR_RPI_PICO_MODE_HI_Z); + config->reg->vreg = REG_VALIN(config->reg->vreg & ~REGULATOR_RPI_PICO_MODE_HI_Z); } return 0; @@ -119,11 +172,10 @@ static int regulator_rpi_pico_init(const struct device *dev) const struct regulator_rpi_pico_config *config = dev->config; if (config->brown_out_detection) { - config->reg->bod = - (BIT(VREG_AND_CHIP_RESET_BOD_EN_LSB) | - (config->brown_out_threshold << VREG_AND_CHIP_RESET_BOD_VSEL_LSB)); + config->reg->bod = REG_VALIN(BIT(REG_BOD_EN_POS) | + (config->brown_out_threshold << REG_BOD_VSEL_POS)); } else { - config->reg->bod &= ~BIT(VREG_AND_CHIP_RESET_BOD_EN_LSB); + config->reg->bod = REG_VALIN(config->reg->bod & ~BIT(REG_BOD_EN_POS)); } regulator_common_data_init(dev); @@ -147,12 +199,15 @@ static DEVICE_API(regulator, api) = { \ static const struct regulator_rpi_pico_config config_##inst = { \ .common = REGULATOR_DT_COMMON_CONFIG_INIT(inst), \ - .reg = (vreg_and_chip_reset_hw_t * const)DT_INST_REG_ADDR(inst), \ + .reg = (REG_PICO_TYPE * const)DT_INST_REG_ADDR(inst), \ .brown_out_detection = DT_INST_PROP(inst, raspberrypi_brown_out_detection), \ .brown_out_threshold = DT_INST_ENUM_IDX(inst, raspberrypi_brown_out_threshold), \ }; \ \ DEVICE_DT_INST_DEFINE(inst, regulator_rpi_pico_init, NULL, &data_##inst, &config_##inst, \ - POST_KERNEL, CONFIG_REGULATOR_RPI_PICO_INIT_PRIORITY, &api); + POST_KERNEL, CONFIG_REGULATOR_RPI_PICO_INIT_PRIORITY, &api); \ + IF_ENABLED(CONFIG_SOC_SERIES_RP2040, \ + (BUILD_ASSERT(DT_INST_ENUM_IDX(inst, raspberrypi_brown_out_threshold) < 16, \ + "On RP2040, BOD threshold must be lower than 1161000");)) \ DT_INST_FOREACH_STATUS_OKAY(REGULATOR_RPI_PICO_DEFINE_ALL) diff --git a/dts/bindings/regulator/raspberrypi,core-supply-regulator.yaml b/dts/bindings/regulator/raspberrypi,core-supply-regulator.yaml index c0f95e77351f..40c1e6fd683b 100644 --- a/dts/bindings/regulator/raspberrypi,core-supply-regulator.yaml +++ b/dts/bindings/regulator/raspberrypi,core-supply-regulator.yaml @@ -43,6 +43,9 @@ properties: - 1032000 - 1075000 - 1118000 + - 1161000 + - 1204000 description: | Reset if the core voltage drops below this threshold for a particular time (determined by the 'brown-out detection assertion delay'). + On RP2040, the threshold must be less than 1.161V. diff --git a/dts/vendor/raspberrypi/rpi_pico/rp2350.dtsi b/dts/vendor/raspberrypi/rpi_pico/rp2350.dtsi index a3ef3230eb4a..480692549b0d 100644 --- a/dts/vendor/raspberrypi/rpi_pico/rp2350.dtsi +++ b/dts/vendor/raspberrypi/rpi_pico/rp2350.dtsi @@ -405,6 +405,13 @@ status = "disabled"; }; + vreg: vreg@40100000 { + compatible = "raspberrypi,core-supply-regulator"; + reg = <0x40100000 0x200>; + status = "okay"; + raspberrypi,brown-out-detection; + }; + dma: dma@50000000 { compatible = "raspberrypi,pico-dma"; reg = <0x50000000 DT_SIZE_K(64)>; From 59ffa602b412016194ed9449c206e11d689814ba Mon Sep 17 00:00:00 2001 From: Albort Xue Date: Tue, 13 Jan 2026 16:02:32 +0800 Subject: [PATCH 2527/3659] drivers: counter: mcux_lpit: Add clock configuration and enable Add explicit clock configuration and enable calls during driver initialization. The driver now attempts to configure the clock subsystem before enabling it. Note: -ENOSYS is temporarily ignored as not all clock control drivers currently implement the configure API. This handling should be removed once all clock drivers support configure. Signed-off-by: Albort Xue --- drivers/counter/counter_mcux_lpit.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/drivers/counter/counter_mcux_lpit.c b/drivers/counter/counter_mcux_lpit.c index 714a2d7bf653..b99f8aa4ff03 100644 --- a/drivers/counter/counter_mcux_lpit.c +++ b/drivers/counter/counter_mcux_lpit.c @@ -1,5 +1,5 @@ /* - * Copyright 2023, 2025 NXP + * Copyright 2023, 2025-2026 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -171,12 +171,31 @@ static int mcux_lpit_init(const struct device *dev) const struct mcux_lpit_config *config = dev->config; lpit_config_t lpit_config; uint32_t clock_rate; + int ret; if (!device_is_ready(config->clock_dev)) { LOG_ERR("Clock control device not ready"); return -ENODEV; } + ret = clock_control_configure(config->clock_dev, config->clock_subsys, NULL); + if (ret != 0) { + /* Check if error is due to lack of support */ + if (ret != -ENOSYS) { + /* Real error occurred */ + LOG_ERR("Failed to configure clock: %d", ret); + return ret; + } + } + +#if FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL + ret = clock_control_on(config->clock_dev, config->clock_subsys); + if (ret != 0) { + LOG_ERR("Failed to enable clock: %d", ret); + return ret; + } +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + LPIT_GetDefaultConfig(&lpit_config); lpit_config.enableRunInDebug = config->lpit_config.enableRunInDebug; lpit_config.enableRunInDoze = config->lpit_config.enableRunInDoze; From 6f350ae64d1216e1bfca8dca96538f0d9df1633c Mon Sep 17 00:00:00 2001 From: Vincent Tardy Date: Tue, 13 Jan 2026 17:14:49 +0100 Subject: [PATCH 2528/3659] soc: st: stm32wba: adjust thread size if BT enabled SYSTEM_WORKQUEUE_STACK_SIZE KConfig is setting to 1024 in case of BT_TX_PROCESSOR_THREAD is enabled, else 2048. BT_TX_PROCESSOR_STACK_SIZE KConfig is setting to 2048 in case of BT_TX_PROCESSOR_THREAD is enabled. Signed-off-by: Vincent Tardy --- soc/st/stm32/stm32wbax/Kconfig.defconfig | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/soc/st/stm32/stm32wbax/Kconfig.defconfig b/soc/st/stm32/stm32wbax/Kconfig.defconfig index dd0b65d71553..cda74b163f46 100644 --- a/soc/st/stm32/stm32wbax/Kconfig.defconfig +++ b/soc/st/stm32/stm32wbax/Kconfig.defconfig @@ -46,7 +46,11 @@ config FPU default y config SYSTEM_WORKQUEUE_STACK_SIZE - default 2048 + default 2048 if !BT_TX_PROCESSOR_THREAD + default 1024 + +config BT_TX_PROCESSOR_STACK_SIZE + default 2048 if BT_TX_PROCESSOR_THREAD endif From 80c2beff83b3b7ceebe5c025cd08e2b7e3982995 Mon Sep 17 00:00:00 2001 From: Peter van der Perk Date: Tue, 20 Jan 2026 10:21:32 +0100 Subject: [PATCH 2529/3659] drivers: watchdog: FS26 watchdog support RTIO Under RTIO SPI behaves differently and thus FS26 didn't work and would reset the board. This changes to add 8-bit transfer support and doesn't lock the irq anymore since the SPI driver got changed. Which would yield an assertion, best it ensure feed callee priority is high enough. Signed-off-by: Peter van der Perk --- drivers/watchdog/Kconfig.nxp_fs26 | 15 ++++++ drivers/watchdog/wdt_nxp_fs26.c | 89 +++++++++++++++++-------------- 2 files changed, 63 insertions(+), 41 deletions(-) diff --git a/drivers/watchdog/Kconfig.nxp_fs26 b/drivers/watchdog/Kconfig.nxp_fs26 index 933cd96530f1..231f692f710b 100644 --- a/drivers/watchdog/Kconfig.nxp_fs26 +++ b/drivers/watchdog/Kconfig.nxp_fs26 @@ -73,4 +73,19 @@ config WDT_NXP_FS26_INT_THREAD_PRIO Priority level for internal cooperative thread which is ran for interrupt processing. +config WDT_NXP_FS26_SPI_8BIT_TRANSFER + bool "Use 8-bit SPI transfer mode for FS26" + default y if SPI_RTIO + help + Enable this to force the FS26 driver to use 8-bit SPI transfers + instead of the default 32-bit transfers. + + This is required when using SPI controllers that do not support + 32-bit word sizes (e.g. SPI_RTIO), or when an application requires + strictly byte-sized transfers. + + When disabled, the FS26 driver will continue to use 32-bit SPI + transfers as defined by the original implementation. + + endif # WDT_NXP_FS26 diff --git a/drivers/watchdog/wdt_nxp_fs26.c b/drivers/watchdog/wdt_nxp_fs26.c index 26ffca172e7a..ff2dda49828d 100644 --- a/drivers/watchdog/wdt_nxp_fs26.c +++ b/drivers/watchdog/wdt_nxp_fs26.c @@ -1,5 +1,5 @@ /* - * Copyright 2023 NXP + * Copyright 2023, 2026 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -17,10 +17,16 @@ LOG_MODULE_REGISTER(wdt_nxp_fs26); #include "wdt_nxp_fs26.h" -#if defined(CONFIG_BIG_ENDIAN) +#if defined(CONFIG_BIG_ENDIAN) || defined(CONFIG_WDT_NXP_FS26_SPI_8BIT_TRANSFER) #define SWAP_ENDIANNESS #endif +#ifdef CONFIG_WDT_NXP_FS26_SPI_8BIT_TRANSFER +#define FS26_SPI_TRANSFER_WIDTH 8 +#else +#define FS26_SPI_TRANSFER_WIDTH 32 +#endif + #define FS26_CRC_TABLE_SIZE 256U #define FS26_CRC_INIT 0xff #define FS26_FS_WD_TOKEN_DEFAULT 0x5ab2 @@ -279,7 +285,6 @@ static int fs26_wd_refresh(const struct device *dev) const struct wdt_nxp_fs26_config *config = dev->config; struct wdt_nxp_fs26_data *data = dev->data; int retval = 0; - int key; uint16_t answer; struct fs26_spi_rx_frame rx_frame; @@ -289,8 +294,6 @@ static int fs26_wd_refresh(const struct device *dev) retval = -EIO; } } else if (config->wd_type == FS26_WD_CHALLENGER) { - key = irq_lock(); - /* Read challenge token generated by the device */ if (fs26_getreg(&config->spi, FS26_FS_WD_TOKEN, &rx_frame)) { LOG_ERR("Failed to obtain watchdog token"); @@ -305,8 +308,6 @@ static int fs26_wd_refresh(const struct device *dev) retval = -EIO; } } - - irq_unlock(key); } else { retval = -EINVAL; } @@ -632,44 +633,13 @@ static int wdt_nxp_fs26_init(const struct device *dev) struct wdt_nxp_fs26_data *data = dev->data; struct fs26_spi_rx_frame rx_frame; uint32_t regval; + int ret; /* Validate bus is ready */ if (!spi_is_ready_dt(&config->spi)) { return -ENODEV; } - k_sem_init(&data->int_sem, 0, 1); - - /* Configure GPIO used for INTB signal */ - if (!gpio_is_ready_dt(&config->int_gpio)) { - LOG_ERR("GPIO port %s not ready", config->int_gpio.port->name); - return -ENODEV; - } - - if (gpio_pin_configure_dt(&config->int_gpio, GPIO_INPUT)) { - LOG_ERR("Unable to configure GPIO pin %u", config->int_gpio.pin); - return -EIO; - } - - gpio_init_callback(&(data->int_gpio_cb), wdt_nxp_fs26_int_callback, - BIT(config->int_gpio.pin)); - - if (gpio_add_callback(config->int_gpio.port, &(data->int_gpio_cb))) { - return -EINVAL; - } - - if (gpio_pin_interrupt_configure_dt(&config->int_gpio, - GPIO_INT_EDGE_FALLING)) { - return -EINVAL; - } - - k_thread_create(&data->int_thread, data->int_thread_stack, - CONFIG_WDT_NXP_FS26_INT_THREAD_STACK_SIZE, - wdt_nxp_fs26_int_thread, - (void *)dev, NULL, NULL, - K_PRIO_COOP(CONFIG_WDT_NXP_FS26_INT_THREAD_PRIO), - 0, K_NO_WAIT); - /* Verify FS BIST before proceeding */ if (fs26_getreg(&config->spi, FS26_FS_DIAG_SAFETY1, &rx_frame)) { return -EIO; @@ -801,6 +771,43 @@ static int wdt_nxp_fs26_init(const struct device *dev) } } + k_sem_init(&data->int_sem, 0, 1); + + /* Configure GPIO used for INTB signal */ + if (!gpio_is_ready_dt(&config->int_gpio)) { + LOG_ERR("GPIO port %s not ready", config->int_gpio.port->name); + return -ENODEV; + } + + if (gpio_pin_configure_dt(&config->int_gpio, GPIO_INPUT)) { + LOG_ERR("Unable to configure GPIO pin %u", config->int_gpio.pin); + return -EIO; + } + + gpio_init_callback(&(data->int_gpio_cb), wdt_nxp_fs26_int_callback, + BIT(config->int_gpio.pin)); + + ret = gpio_add_callback(config->int_gpio.port, &(data->int_gpio_cb)); + + if (ret) { + LOG_ERR("Failed to add GPIO callback: %d\n", ret); + return ret; + } + + ret = gpio_pin_interrupt_configure_dt(&config->int_gpio, GPIO_INT_EDGE_FALLING); + + if (ret) { + LOG_ERR("Failed to configure GPIO interrupt: %d", ret); + return ret; + } + + k_tid_t tid = k_thread_create( + &data->int_thread, data->int_thread_stack, + CONFIG_WDT_NXP_FS26_INT_THREAD_STACK_SIZE, wdt_nxp_fs26_int_thread, (void *)dev, + NULL, NULL, K_PRIO_COOP(CONFIG_WDT_NXP_FS26_INT_THREAD_PRIO), 0, K_NO_WAIT); + + k_thread_name_set(tid, "wdt_nxp_fs26"); + return 0; } @@ -824,8 +831,8 @@ static DEVICE_API(wdt, wdt_nxp_fs26_api) = { }; \ \ static const struct wdt_nxp_fs26_config wdt_nxp_fs26_config_##n = { \ - .spi = SPI_DT_SPEC_INST_GET(n, \ - SPI_OP_MODE_MASTER | SPI_MODE_CPHA | SPI_WORD_SET(32)), \ + .spi = SPI_DT_SPEC_INST_GET(n, SPI_OP_MODE_MASTER | SPI_MODE_CPHA | \ + SPI_WORD_SET(FS26_SPI_TRANSFER_WIDTH)), \ .wd_type = _CONCAT(FS26_WD_, DT_INST_STRING_UPPER_TOKEN(n, type)), \ .int_gpio = GPIO_DT_SPEC_INST_GET(n, int_gpios), \ }; \ From b76f37c5da45e6c14a60562f79512a721d3a6055 Mon Sep 17 00:00:00 2001 From: Peter van der Perk Date: Tue, 20 Jan 2026 11:04:01 +0100 Subject: [PATCH 2530/3659] boards: nxp: mr_canhubk3: Increase FS26 init priority We've to ensure nothing blocks the watchdog init on startup, otherwise we'll get into bootloop. Hence increase the piority. Signed-off-by: Peter van der Perk --- boards/nxp/mr_canhubk3/Kconfig.defconfig | 7 +++++-- .../build_all/ethernet/boards/mr_canhubk3_s32k344.conf | 1 + .../ethernet/boards/mr_canhubk3_s32k344_mcuboot.conf | 1 + 3 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 tests/drivers/build_all/ethernet/boards/mr_canhubk3_s32k344.conf create mode 100644 tests/drivers/build_all/ethernet/boards/mr_canhubk3_s32k344_mcuboot.conf diff --git a/boards/nxp/mr_canhubk3/Kconfig.defconfig b/boards/nxp/mr_canhubk3/Kconfig.defconfig index 86a0fbbdb667..9773db8b68df 100644 --- a/boards/nxp/mr_canhubk3/Kconfig.defconfig +++ b/boards/nxp/mr_canhubk3/Kconfig.defconfig @@ -12,13 +12,16 @@ endif # SERIAL if SPI +config GPIO_INIT_PRIORITY + default 10 + config SPI_INIT_PRIORITY - default 50 + default 10 if WDT_NXP_FS26 config WDT_NXP_FS26_INIT_PRIORITY - default 51 + default 10 endif # WDT_NXP_FS26 endif # SPI diff --git a/tests/drivers/build_all/ethernet/boards/mr_canhubk3_s32k344.conf b/tests/drivers/build_all/ethernet/boards/mr_canhubk3_s32k344.conf new file mode 100644 index 000000000000..dfd66e436cba --- /dev/null +++ b/tests/drivers/build_all/ethernet/boards/mr_canhubk3_s32k344.conf @@ -0,0 +1 @@ +CONFIG_SPI_INIT_PRIORITY=10 diff --git a/tests/drivers/build_all/ethernet/boards/mr_canhubk3_s32k344_mcuboot.conf b/tests/drivers/build_all/ethernet/boards/mr_canhubk3_s32k344_mcuboot.conf new file mode 100644 index 000000000000..dfd66e436cba --- /dev/null +++ b/tests/drivers/build_all/ethernet/boards/mr_canhubk3_s32k344_mcuboot.conf @@ -0,0 +1 @@ +CONFIG_SPI_INIT_PRIORITY=10 From 8135c56cf6a2d4523e0e08f3d4ea016df40ece2d Mon Sep 17 00:00:00 2001 From: Ryan Wiebe Date: Tue, 20 Jan 2026 11:53:30 +0000 Subject: [PATCH 2531/3659] modbus: Fixed serial RX enablement for ASYNC and client mode Modbus is failing to turn on RX when using serial ASYNC mode. This causes modbus to never receive inbound requests, leaving it inoperable. Additionally, modbus also enables RX when in client mode, leading to issues when running as a client. These have been fixed by enabling rx only when serial init is successful and modbus is in server mode during initialisation. Signed-off-by: Ryan Wiebe --- subsys/modbus/modbus_serial.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/subsys/modbus/modbus_serial.c b/subsys/modbus/modbus_serial.c index 0f7410b59b86..9723d08d0f5c 100644 --- a/subsys/modbus/modbus_serial.c +++ b/subsys/modbus/modbus_serial.c @@ -693,10 +693,13 @@ int modbus_serial_init(struct modbus_context *ctx, if (!err) { k_timer_init(&cfg->rtu_timer, rtu_tmr_handler, NULL); k_timer_user_data_set(&cfg->rtu_timer, ctx); - modbus_serial_rx_on(ctx); } } + if (!err && !ctx->client) { + modbus_serial_rx_on(ctx); + } + LOG_INF("RTU timeout %u us", cfg->rtu_timeout); return err; From e18e1c06c857dec4d629047920b9106d3caa5c35 Mon Sep 17 00:00:00 2001 From: Gaetan Perrot Date: Wed, 21 Jan 2026 04:20:38 +0900 Subject: [PATCH 2532/3659] drivers: dai: intel: dmic: make dai_dmic_probe void dai_dmic_probe() and dai_dmic_probe_wrapper() never reports errors and always returns 0. The error check at the call site is therefore dead code. Make functions void and drop the unused error handling. Signed-off-by: Gaetan Perrot --- drivers/dai/intel/dmic/dmic.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/drivers/dai/intel/dmic/dmic.c b/drivers/dai/intel/dmic/dmic.c index a53e0f957e62..10d192b08cb3 100644 --- a/drivers/dai/intel/dmic/dmic.c +++ b/drivers/dai/intel/dmic/dmic.c @@ -322,7 +322,7 @@ static inline void dai_dmic_dis_power(const struct dai_intel_dmic *dmic) base + DMICLCTL_OFFSET); } -static int dai_dmic_probe(struct dai_intel_dmic *dmic) +static void dai_dmic_probe(struct dai_intel_dmic *dmic) { LOG_INF("dmic_probe()"); @@ -340,8 +340,6 @@ static int dai_dmic_probe(struct dai_intel_dmic *dmic) /* DMIC Owner Select to DSP */ dai_dmic_claim_ownership(dmic); - - return 0; } static int dai_dmic_remove(struct dai_intel_dmic *dmic) @@ -806,25 +804,20 @@ static int dai_dmic_set_config(const struct device *dev, return ret; } -static int dai_dmic_probe_wrapper(const struct device *dev) +static void dai_dmic_probe_wrapper(const struct device *dev) { struct dai_intel_dmic *dmic = (struct dai_intel_dmic *)dev->data; k_spinlock_key_t key; - int ret = 0; key = k_spin_lock(&dmic->lock); if (dmic->sref == 0) { - ret = dai_dmic_probe(dmic); + dai_dmic_probe(dmic); } - if (!ret) { - dmic->sref++; - } + dmic->sref++; k_spin_unlock(&dmic->lock, key); - - return ret; } static int dai_dmic_remove_wrapper(const struct device *dev) From 67ac1ddd77e60790161a63d1de685930b0144774 Mon Sep 17 00:00:00 2001 From: Maochen Wang Date: Wed, 21 Jan 2026 14:53:13 +0800 Subject: [PATCH 2533/3659] manifest: hal_nxp: upgrade wifi version to r53.p2 Upgrade wifi driver version to r53.p2. Support static ipv4 address connection for STA interface. Improved throughput value for SDIO case. Support event based FW dump for IW61x. Fix several bugs. Signed-off-by: Maochen Wang --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index cf1eafd0dc20..de9a40ee46ea 100644 --- a/west.yml +++ b/west.yml @@ -210,7 +210,7 @@ manifest: groups: - hal - name: hal_nxp - revision: 2f8883b3358e7be2101075cd0f00dd2e0fa68050 + revision: af5d95d3e6be13f1b993d2c466595e7cc71ba57b path: modules/hal/nxp groups: - hal From 288802461ca1548c7350fdb208162b3a5b70a17a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mo=C5=84?= Date: Wed, 21 Jan 2026 08:55:41 +0100 Subject: [PATCH 2534/3659] dts: bindings: clock: fix reference audio frequencies MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reference audio clock frequencies are supposed to be integer multiplies of sampling frequency (44100 * 256 = 11289600, 48000 * 256 = 12288000) and not some arbitrary numbers. Signed-off-by: Tomasz Moń --- include/zephyr/dt-bindings/clock/nrfs-audiopll.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/zephyr/dt-bindings/clock/nrfs-audiopll.h b/include/zephyr/dt-bindings/clock/nrfs-audiopll.h index b4c3975b5e15..a79a4061f266 100644 --- a/include/zephyr/dt-bindings/clock/nrfs-audiopll.h +++ b/include/zephyr/dt-bindings/clock/nrfs-audiopll.h @@ -8,8 +8,8 @@ #define ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_NRFS_AUDIOPLL_H_ #define NRFS_AUDIOPLL_FREQ_MIN 10666707 -#define NRFS_AUDIOPLL_FREQ_AUDIO_44K1 11289591 -#define NRFS_AUDIOPLL_FREQ_AUDIO_48K 12287963 +#define NRFS_AUDIOPLL_FREQ_AUDIO_44K1 11289600 +#define NRFS_AUDIOPLL_FREQ_AUDIO_48K 12288000 #define NRFS_AUDIOPLL_FREQ_MAX 13333292 #endif /* #define ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_NRFS_AUDIOPLL_H_ */ From f1c1ef170d9db209f5ff9144f27560899236392c Mon Sep 17 00:00:00 2001 From: Ren Chen Date: Wed, 21 Jan 2026 14:21:12 +0800 Subject: [PATCH 2535/3659] dts: riscv: it51xxx: omit pinctrl and wuc nodes if not referenced This commit prefixes pre-generated nodes with `/omit-if-no-ref/` to keep the generated devicetree C headers minimal. Signed-off-by: Ren Chen --- dts/riscv/ite/it51xxx-pinctrl-map.dtsi | 198 ++++++++++++------------- dts/riscv/ite/it51xxx-wuc-map.dtsi | 196 ++++++++++++------------ 2 files changed, 197 insertions(+), 197 deletions(-) diff --git a/dts/riscv/ite/it51xxx-pinctrl-map.dtsi b/dts/riscv/ite/it51xxx-pinctrl-map.dtsi index f4810536dc4e..061e66dac700 100644 --- a/dts/riscv/ite/it51xxx-pinctrl-map.dtsi +++ b/dts/riscv/ite/it51xxx-pinctrl-map.dtsi @@ -8,451 +8,451 @@ &pinctrl { /* ADC alternate function */ - adc0_ch0_gpi0_default: adc0_ch0_gpi0_default { + /omit-if-no-ref/ adc0_ch0_gpi0_default: adc0_ch0_gpi0_default { pinmuxs = <&pinctrli 0 IT8XXX2_ALT_FUNC_1>; }; - adc0_ch1_gpi1_default: adc0_ch1_gpi1_default { + /omit-if-no-ref/ adc0_ch1_gpi1_default: adc0_ch1_gpi1_default { pinmuxs = <&pinctrli 1 IT8XXX2_ALT_FUNC_1>; }; - adc0_ch2_gpi2_default: adc0_ch2_gpi2_default { + /omit-if-no-ref/ adc0_ch2_gpi2_default: adc0_ch2_gpi2_default { pinmuxs = <&pinctrli 2 IT8XXX2_ALT_FUNC_1>; }; - adc0_ch3_gpi3_default: adc0_ch3_gpi3_default { + /omit-if-no-ref/ adc0_ch3_gpi3_default: adc0_ch3_gpi3_default { pinmuxs = <&pinctrli 3 IT8XXX2_ALT_FUNC_1>; }; - adc0_ch4_gpi4_default: adc0_ch4_gpi4_default { + /omit-if-no-ref/ adc0_ch4_gpi4_default: adc0_ch4_gpi4_default { pinmuxs = <&pinctrli 4 IT8XXX2_ALT_FUNC_1>; }; - adc0_ch5_gpi5_default: adc0_ch5_gpi5_default { + /omit-if-no-ref/ adc0_ch5_gpi5_default: adc0_ch5_gpi5_default { pinmuxs = <&pinctrli 5 IT8XXX2_ALT_FUNC_1>; }; - adc0_ch6_gpi6_default: adc0_ch6_gpi6_default { + /omit-if-no-ref/ adc0_ch6_gpi6_default: adc0_ch6_gpi6_default { pinmuxs = <&pinctrli 6 IT8XXX2_ALT_FUNC_1>; }; - adc0_ch7_gpi7_default: adc0_ch7_gpi7_default { + /omit-if-no-ref/ adc0_ch7_gpi7_default: adc0_ch7_gpi7_default { pinmuxs = <&pinctrli 7 IT8XXX2_ALT_FUNC_1>; }; /* FSPI alternate function */ - fspi_fsce_gpg3_default: fspi_fsce_gpg3_default { + /omit-if-no-ref/ fspi_fsce_gpg3_default: fspi_fsce_gpg3_default { pinmuxs = <&pinctrlg 3 IT8XXX2_ALT_FUNC_1>; }; - fspi_fmosi_gpg4_default: fspi_fmosi_gpg4_default { + /omit-if-no-ref/ fspi_fmosi_gpg4_default: fspi_fmosi_gpg4_default { pinmuxs = <&pinctrlg 4 IT8XXX2_ALT_FUNC_1>; }; - fspi_fmiso_gpg5_default: fspi_fmiso_gpg5_default { + /omit-if-no-ref/ fspi_fmiso_gpg5_default: fspi_fmiso_gpg5_default { pinmuxs = <&pinctrlg 5 IT8XXX2_ALT_FUNC_1>; }; - fspi_fsce1_gpg6_default: fspi_fsce1_gpg6_default { + /omit-if-no-ref/ fspi_fsce1_gpg6_default: fspi_fsce1_gpg6_default { pinmuxs = <&pinctrlg 6 IT8XXX2_ALT_FUNC_1>; }; - fspi_fsck_gpg7_default: fspi_fsck_gpg7_default { + /omit-if-no-ref/ fspi_fsck_gpg7_default: fspi_fsck_gpg7_default { pinmuxs = <&pinctrlg 7 IT8XXX2_ALT_FUNC_1>; }; - fspi_fdio2_gph5_default: fspi_fdio2_gph5_default { + /omit-if-no-ref/ fspi_fdio2_gph5_default: fspi_fdio2_gph5_default { pinmuxs = <&pinctrlh 5 IT8XXX2_ALT_FUNC_1>; }; - fspi_fdio3_gph6_default: fspi_fdio3_gph6_default { + /omit-if-no-ref/ fspi_fdio3_gph6_default: fspi_fdio3_gph6_default { pinmuxs = <&pinctrlh 6 IT8XXX2_ALT_FUNC_1>; }; /* I2C alternate function */ - i2c0_clk_gpf2_default: i2c0_clk_gpf2_default { + /omit-if-no-ref/ i2c0_clk_gpf2_default: i2c0_clk_gpf2_default { pinmuxs = <&pinctrlf 2 IT8XXX2_ALT_FUNC_1>; }; - i2c0_data_gpf3_default: i2c0_data_gpf3_default { + /omit-if-no-ref/ i2c0_data_gpf3_default: i2c0_data_gpf3_default { pinmuxs = <&pinctrlf 3 IT8XXX2_ALT_FUNC_1>; }; - i2c1_clk_gpc1_default: i2c1_clk_gpc1_default { + /omit-if-no-ref/ i2c1_clk_gpc1_default: i2c1_clk_gpc1_default { pinmuxs = <&pinctrlc 1 IT8XXX2_ALT_FUNC_1>; }; - i2c1_data_gpc2_default: i2c1_data_gpc2_default { + /omit-if-no-ref/ i2c1_data_gpc2_default: i2c1_data_gpc2_default { pinmuxs = <&pinctrlc 2 IT8XXX2_ALT_FUNC_1>; }; - i2c2_clk_gpf6_default: i2c2_clk_gpf6_default { + /omit-if-no-ref/ i2c2_clk_gpf6_default: i2c2_clk_gpf6_default { pinmuxs = <&pinctrlf 6 IT8XXX2_ALT_FUNC_1>; }; - i2c2_data_gpf7_default: i2c2_data_gpf7_default { + /omit-if-no-ref/ i2c2_data_gpf7_default: i2c2_data_gpf7_default { pinmuxs = <&pinctrlf 7 IT8XXX2_ALT_FUNC_1>; }; - i2c3_clk_gph1_default: i2c3_clk_gph1_default { + /omit-if-no-ref/ i2c3_clk_gph1_default: i2c3_clk_gph1_default { pinmuxs = <&pinctrlh 1 IT8XXX2_ALT_FUNC_4>; }; - i2c3_data_gph2_default: i2c3_data_gph2_default { + /omit-if-no-ref/ i2c3_data_gph2_default: i2c3_data_gph2_default { pinmuxs = <&pinctrlh 2 IT8XXX2_ALT_FUNC_4>; }; - i2c4_clk_gpe0_default: i2c4_clk_gpe0_default { + /omit-if-no-ref/ i2c4_clk_gpe0_default: i2c4_clk_gpe0_default { pinmuxs = <&pinctrle 0 IT8XXX2_ALT_FUNC_4>; }; - i2c4_data_gpe7_default: i2c4_data_gpe7_default { + /omit-if-no-ref/ i2c4_data_gpe7_default: i2c4_data_gpe7_default { pinmuxs = <&pinctrle 7 IT8XXX2_ALT_FUNC_3>; }; - i2c5_clk_gpa4_default: i2c5_clk_gpa4_default { + /omit-if-no-ref/ i2c5_clk_gpa4_default: i2c5_clk_gpa4_default { pinmuxs = <&pinctrla 4 IT8XXX2_ALT_FUNC_3>; }; - i2c5_data_gpa5_default: i2c5_data_gpa5_default { + /omit-if-no-ref/ i2c5_data_gpa5_default: i2c5_data_gpa5_default { pinmuxs = <&pinctrla 5 IT8XXX2_ALT_FUNC_3>; }; - i2c6_clk_gpd0_default: i2c6_clk_gpd0_default { + /omit-if-no-ref/ i2c6_clk_gpd0_default: i2c6_clk_gpd0_default { pinmuxs = <&pinctrld 0 IT8XXX2_ALT_FUNC_3>; }; - i2c6_data_gpd1_default: i2c6_data_gpd1_default { + /omit-if-no-ref/ i2c6_data_gpd1_default: i2c6_data_gpd1_default { pinmuxs = <&pinctrld 1 IT8XXX2_ALT_FUNC_3>; }; - i2c7_clk_gpb2_default: i2c7_clk_gpb2_default { + /omit-if-no-ref/ i2c7_clk_gpb2_default: i2c7_clk_gpb2_default { pinmuxs = <&pinctrlb 2 IT8XXX2_ALT_FUNC_4>; }; - i2c7_data_gph0_default: i2c7_data_gph0_default { + /omit-if-no-ref/ i2c7_data_gph0_default: i2c7_data_gph0_default { pinmuxs = <&pinctrlh 0 IT8XXX2_ALT_FUNC_4>; }; - i2c8_clk_gpb5_default: i2c8_clk_gpb5_default { + /omit-if-no-ref/ i2c8_clk_gpb5_default: i2c8_clk_gpb5_default { pinmuxs = <&pinctrlb 5 IT8XXX2_ALT_FUNC_4>; }; - i2c8_data_gpj6_default: i2c8_data_gpj6_default { + /omit-if-no-ref/ i2c8_data_gpj6_default: i2c8_data_gpj6_default { pinmuxs = <&pinctrlj 6 IT8XXX2_ALT_FUNC_4>; }; /* I2C switch to interface */ - i2c9_clk_gpj3_default: i2c9_clk_gpj3_default { + /omit-if-no-ref/ i2c9_clk_gpj3_default: i2c9_clk_gpj3_default { pinmuxs = <&pinctrlj 3 IT8XXX2_ALT_FUNC_3>; }; - i2c9_data_gpj4_default: i2c9_data_gpj4_default { + /omit-if-no-ref/ i2c9_data_gpj4_default: i2c9_data_gpj4_default { pinmuxs = <&pinctrlj 4 IT8XXX2_ALT_FUNC_3>; }; - i2c10_clk_gpj5_default: i2c10_clk_gpj5_default { + /omit-if-no-ref/ i2c10_clk_gpj5_default: i2c10_clk_gpj5_default { pinmuxs = <&pinctrlj 5 IT8XXX2_ALT_FUNC_3>; }; - i2c10_data_gpe1_default: i2c10_data_gpe1_default { + /omit-if-no-ref/ i2c10_data_gpe1_default: i2c10_data_gpe1_default { pinmuxs = <&pinctrle 1 IT8XXX2_ALT_FUNC_3>; }; - i2c11_clk_gpe2_default: i2c11_clk_gpe2_default { + /omit-if-no-ref/ i2c11_clk_gpe2_default: i2c11_clk_gpe2_default { pinmuxs = <&pinctrle 2 IT8XXX2_ALT_FUNC_3>; }; - i2c11_data_gpe3_default: i2c11_data_gpe3_default { + /omit-if-no-ref/ i2c11_data_gpe3_default: i2c11_data_gpe3_default { pinmuxs = <&pinctrle 3 IT8XXX2_ALT_FUNC_3>; }; - i2c12_clk_gpf0_default: i2c12_clk_gpf0_default { + /omit-if-no-ref/ i2c12_clk_gpf0_default: i2c12_clk_gpf0_default { pinmuxs = <&pinctrlf 0 IT8XXX2_ALT_FUNC_3>; }; - i2c12_data_gpf1_default: i2c12_data_gpf1_default { + /omit-if-no-ref/ i2c12_data_gpf1_default: i2c12_data_gpf1_default { pinmuxs = <&pinctrlf 1 IT8XXX2_ALT_FUNC_3>; }; /* I3C alternate function */ - i3c0_clk_gpj3_default: i3c0_clk_gpj3_default { + /omit-if-no-ref/ i3c0_clk_gpj3_default: i3c0_clk_gpj3_default { pinmuxs = <&pinctrlj 3 IT8XXX2_ALT_FUNC_1>; }; - i3c0_data_gpj4_default: i3c0_data_gpj4_default { + /omit-if-no-ref/ i3c0_data_gpj4_default: i3c0_data_gpj4_default { pinmuxs = <&pinctrlj 4 IT8XXX2_ALT_FUNC_1>; }; - i3c1_clk_gpj5_default: i3c1_clk_gpj5_default { + /omit-if-no-ref/ i3c1_clk_gpj5_default: i3c1_clk_gpj5_default { pinmuxs = <&pinctrlj 5 IT8XXX2_ALT_FUNC_1>; }; - i3c1_data_gpe1_default: i3c1_data_gpe1_default { + /omit-if-no-ref/ i3c1_data_gpe1_default: i3c1_data_gpe1_default { pinmuxs = <&pinctrle 1 IT8XXX2_ALT_FUNC_1>; }; - i3c2_clk_gpe2_default: i3c2_clk_gpe2_default { + /omit-if-no-ref/ i3c2_clk_gpe2_default: i3c2_clk_gpe2_default { pinmuxs = <&pinctrle 2 IT8XXX2_ALT_FUNC_1>; }; - i3c2_data_gpe3_default: i3c2_data_gpe3_default { + /omit-if-no-ref/ i3c2_data_gpe3_default: i3c2_data_gpe3_default { pinmuxs = <&pinctrle 3 IT8XXX2_ALT_FUNC_1>; }; - i3c3_clk_gpf0_default: i3c3_clk_gpf0_default { + /omit-if-no-ref/ i3c3_clk_gpf0_default: i3c3_clk_gpf0_default { pinmuxs = <&pinctrlf 0 IT8XXX2_ALT_FUNC_1>; }; - i3c3_data_gpf1_default: i3c3_data_gpf1_default { + /omit-if-no-ref/ i3c3_data_gpf1_default: i3c3_data_gpf1_default { pinmuxs = <&pinctrlf 1 IT8XXX2_ALT_FUNC_1>; }; /* Keyboard alternate function */ - kso0_default: kso0_gpk0_default: kso0_gpk0_default { + /omit-if-no-ref/ kso0_default: kso0_gpk0_default: kso0_gpk0_default { pinmuxs = <&pinctrlk 0 IT8XXX2_ALT_FUNC_1>; drive-open-drain; bias-pull-up; }; - kso1_default: kso1_gpk1_default: kso1_gpk1_default { + /omit-if-no-ref/ kso1_default: kso1_gpk1_default: kso1_gpk1_default { pinmuxs = <&pinctrlk 1 IT8XXX2_ALT_FUNC_1>; drive-open-drain; bias-pull-up; }; - kso2_default: kso2_gpk2_default: kso2_gpk2_default { + /omit-if-no-ref/ kso2_default: kso2_gpk2_default: kso2_gpk2_default { pinmuxs = <&pinctrlk 2 IT8XXX2_ALT_FUNC_1>; drive-open-drain; bias-pull-up; }; - kso3_default: kso3_gpk3_default: kso3_gpk3_default { + /omit-if-no-ref/ kso3_default: kso3_gpk3_default: kso3_gpk3_default { pinmuxs = <&pinctrlk 3 IT8XXX2_ALT_FUNC_1>; drive-open-drain; bias-pull-up; }; - kso4_default: kso4_gpk4_default: kso4_gpk4_default { + /omit-if-no-ref/ kso4_default: kso4_gpk4_default: kso4_gpk4_default { pinmuxs = <&pinctrlk 4 IT8XXX2_ALT_FUNC_1>; drive-open-drain; bias-pull-up; }; - kso5_default: kso5_gpk5_default: kso5_gpk5_default { + /omit-if-no-ref/ kso5_default: kso5_gpk5_default: kso5_gpk5_default { pinmuxs = <&pinctrlk 5 IT8XXX2_ALT_FUNC_1>; drive-open-drain; bias-pull-up; }; - kso6_default: kso6_gpk6_default: kso6_gpk6_default { + /omit-if-no-ref/ kso6_default: kso6_gpk6_default: kso6_gpk6_default { pinmuxs = <&pinctrlk 6 IT8XXX2_ALT_FUNC_1>; drive-open-drain; bias-pull-up; }; - kso7_default: kso7_gpk7_default: kso7_gpk7_default { + /omit-if-no-ref/ kso7_default: kso7_gpk7_default: kso7_gpk7_default { pinmuxs = <&pinctrlk 7 IT8XXX2_ALT_FUNC_1>; drive-open-drain; bias-pull-up; }; - kso8_default: kso8_gpl0_default: kso8_gpl0_default { + /omit-if-no-ref/ kso8_default: kso8_gpl0_default: kso8_gpl0_default { pinmuxs = <&pinctrll 0 IT8XXX2_ALT_FUNC_1>; drive-open-drain; bias-pull-up; }; - kso9_default: kso9_gpl1_default: kso9_gpl1_default { + /omit-if-no-ref/ kso9_default: kso9_gpl1_default: kso9_gpl1_default { pinmuxs = <&pinctrll 1 IT8XXX2_ALT_FUNC_1>; drive-open-drain; bias-pull-up; }; - kso10_default: kso10_gpl2_default: kso10_gpl2_default { + /omit-if-no-ref/ kso10_default: kso10_gpl2_default: kso10_gpl2_default { pinmuxs = <&pinctrll 2 IT8XXX2_ALT_FUNC_1>; drive-open-drain; bias-pull-up; }; - kso11_default: kso11_gpl3_default: kso11_gpl3_default { + /omit-if-no-ref/ kso11_default: kso11_gpl3_default: kso11_gpl3_default { pinmuxs = <&pinctrll 3 IT8XXX2_ALT_FUNC_1>; drive-open-drain; bias-pull-up; }; - kso12_default: kso12_gpl4_default: kso12_gpl4_default { + /omit-if-no-ref/ kso12_default: kso12_gpl4_default: kso12_gpl4_default { pinmuxs = <&pinctrll 4 IT8XXX2_ALT_FUNC_1>; drive-open-drain; bias-pull-up; }; - kso13_default: kso13_gpl5_default: kso13_gpl5_default { + /omit-if-no-ref/ kso13_default: kso13_gpl5_default: kso13_gpl5_default { pinmuxs = <&pinctrll 5 IT8XXX2_ALT_FUNC_1>; drive-open-drain; bias-pull-up; }; - kso14_default: kso14_gpl6_default: kso14_gpl6_default { + /omit-if-no-ref/ kso14_default: kso14_gpl6_default: kso14_gpl6_default { pinmuxs = <&pinctrll 6 IT8XXX2_ALT_FUNC_1>; drive-open-drain; bias-pull-up; }; - kso15_default: kso15_gpl7_default: kso15_gpl7_default { + /omit-if-no-ref/ kso15_default: kso15_gpl7_default: kso15_gpl7_default { pinmuxs = <&pinctrll 7 IT8XXX2_ALT_FUNC_1>; drive-open-drain; bias-pull-up; }; - kso16_default: kso16_gpc3_default: kso16_gpc3_default { + /omit-if-no-ref/ kso16_default: kso16_gpc3_default: kso16_gpc3_default { pinmuxs = <&pinctrlc 3 IT8XXX2_ALT_FUNC_1>; bias-pull-up; }; - kso17_default: kso17_gpc5_default: kso17_gpc5_default { + /omit-if-no-ref/ kso17_default: kso17_gpc5_default: kso17_gpc5_default { pinmuxs = <&pinctrlc 5 IT8XXX2_ALT_FUNC_1>; bias-pull-up; }; - ksi0_default: ksi0_gpn0_default: ksi0_gpn0_default { + /omit-if-no-ref/ ksi0_default: ksi0_gpn0_default: ksi0_gpn0_default { pinmuxs = <&pinctrln 0 IT8XXX2_ALT_FUNC_1>; bias-pull-up; }; - ksi1_default: ksi1_gpn1_default: ksi1_gpn1_default { + /omit-if-no-ref/ ksi1_default: ksi1_gpn1_default: ksi1_gpn1_default { pinmuxs = <&pinctrln 1 IT8XXX2_ALT_FUNC_1>; bias-pull-up; }; - ksi2_default: ksi2_gpn2_default: ksi2_gpn2_default { + /omit-if-no-ref/ ksi2_default: ksi2_gpn2_default: ksi2_gpn2_default { pinmuxs = <&pinctrln 2 IT8XXX2_ALT_FUNC_1>; bias-pull-up; }; - ksi3_default: ksi3_gpn3_default: ksi3_gpn3_default { + /omit-if-no-ref/ ksi3_default: ksi3_gpn3_default: ksi3_gpn3_default { pinmuxs = <&pinctrln 3 IT8XXX2_ALT_FUNC_1>; bias-pull-up; }; - ksi4_default: ksi4_gpn4_default: ksi4_gpn4_default { + /omit-if-no-ref/ ksi4_default: ksi4_gpn4_default: ksi4_gpn4_default { pinmuxs = <&pinctrln 4 IT8XXX2_ALT_FUNC_1>; bias-pull-up; }; - ksi5_default: ksi5_gpn5_default: ksi5_gpn5_default { + /omit-if-no-ref/ ksi5_default: ksi5_gpn5_default: ksi5_gpn5_default { pinmuxs = <&pinctrln 5 IT8XXX2_ALT_FUNC_1>; bias-pull-up; }; - ksi6_default: ksi6_gpn6_default: ksi6_gpn6_default { + /omit-if-no-ref/ ksi6_default: ksi6_gpn6_default: ksi6_gpn6_default { pinmuxs = <&pinctrln 6 IT8XXX2_ALT_FUNC_1>; bias-pull-up; }; - ksi7_default: ksi7_gpn7_default: ksi7_gpn7_default { + /omit-if-no-ref/ ksi7_default: ksi7_gpn7_default: ksi7_gpn7_default { pinmuxs = <&pinctrln 7 IT8XXX2_ALT_FUNC_1>; bias-pull-up; }; /* PECI alternate function */ - peci_gpf6_default: peci_gpf6_default { + /omit-if-no-ref/ peci_gpf6_default: peci_gpf6_default { pinmuxs = <&pinctrlf 6 IT8XXX2_ALT_FUNC_3>; }; /* PWM alternate function */ - pwm0_gpa0_default: pwm0_gpa0_default { + /omit-if-no-ref/ pwm0_gpa0_default: pwm0_gpa0_default { pinmuxs = <&pinctrla 0 IT8XXX2_ALT_FUNC_1>; }; - pwm1_gpa1_default: pwm1_gpa1_default { + /omit-if-no-ref/ pwm1_gpa1_default: pwm1_gpa1_default { pinmuxs = <&pinctrla 1 IT8XXX2_ALT_FUNC_1>; }; - pwm2_gpa2_default: pwm2_gpa2_default { + /omit-if-no-ref/ pwm2_gpa2_default: pwm2_gpa2_default { pinmuxs = <&pinctrla 2 IT8XXX2_ALT_FUNC_1>; }; - pwm3_gpa3_default: pwm3_gpa3_default { + /omit-if-no-ref/ pwm3_gpa3_default: pwm3_gpa3_default { pinmuxs = <&pinctrla 3 IT8XXX2_ALT_FUNC_1>; }; - pwm4_gpa4_default: pwm4_gpa4_default { + /omit-if-no-ref/ pwm4_gpa4_default: pwm4_gpa4_default { pinmuxs = <&pinctrla 4 IT8XXX2_ALT_FUNC_1>; }; - pwm5_gpa5_default: pwm5_gpa5_default { + /omit-if-no-ref/ pwm5_gpa5_default: pwm5_gpa5_default { pinmuxs = <&pinctrla 5 IT8XXX2_ALT_FUNC_1>; }; - pwm6_gpa6_default: pwm6_gpa6_default { + /omit-if-no-ref/ pwm6_gpa6_default: pwm6_gpa6_default { pinmuxs = <&pinctrla 6 IT8XXX2_ALT_FUNC_1>; }; - pwm7_gpa7_default: pwm7_gpa7_default { + /omit-if-no-ref/ pwm7_gpa7_default: pwm7_gpa7_default { pinmuxs = <&pinctrla 7 IT8XXX2_ALT_FUNC_1>; }; /* SSPI alternate function */ - ssce0_gpj7_default: ssce0_gpj7_default { + /omit-if-no-ref/ ssce0_gpj7_default: ssce0_gpj7_default { pinmuxs = <&pinctrlj 7 IT8XXX2_ALT_FUNC_4>; }; - ssce1_gph7_default: ssce1_gph7_default { + /omit-if-no-ref/ ssce1_gph7_default: ssce1_gph7_default { pinmuxs = <&pinctrlh 7 IT8XXX2_ALT_FUNC_3>; }; - ssck_gpa6_default: ssck_gpa6_default { + /omit-if-no-ref/ ssck_gpa6_default: ssck_gpa6_default { pinmuxs = <&pinctrla 6 IT8XXX2_ALT_FUNC_3>; }; - smosi_gpc6_default: smosi_gpc6_default { + /omit-if-no-ref/ smosi_gpc6_default: smosi_gpc6_default { pinmuxs = <&pinctrlc 6 IT8XXX2_ALT_FUNC_3>; }; - smiso_gpc4_default: smiso_gpc4_default { + /omit-if-no-ref/ smiso_gpc4_default: smiso_gpc4_default { pinmuxs = <&pinctrlc 4 IT8XXX2_ALT_FUNC_3>; }; /* Tachometer alternate function */ - tach0a_gpd6_default: tach0a_gpd6_default { + /omit-if-no-ref/ tach0a_gpd6_default: tach0a_gpd6_default { pinmuxs = <&pinctrld 6 IT8XXX2_ALT_FUNC_1>; }; - tach1a_gpd7_default: tach1a_gpd7_default { + /omit-if-no-ref/ tach1a_gpd7_default: tach1a_gpd7_default { pinmuxs = <&pinctrld 7 IT8XXX2_ALT_FUNC_1>; }; - tach2a_gpj0_default: tach2a_gpj0_default { + /omit-if-no-ref/ tach2a_gpj0_default: tach2a_gpj0_default { pinmuxs = <&pinctrlj 0 IT8XXX2_ALT_FUNC_3>; }; - tach0b_gpc6_default: tach0b_gpc6_default { + /omit-if-no-ref/ tach0b_gpc6_default: tach0b_gpc6_default { pinmuxs = <&pinctrlc 6 IT8XXX2_ALT_FUNC_4>; }; - tach1b_gpj6_default: tach1b_gpj6_default { + /omit-if-no-ref/ tach1b_gpj6_default: tach1b_gpj6_default { pinmuxs = <&pinctrlj 6 IT8XXX2_ALT_FUNC_3>; }; - tach2b_gpj1_default: tach2b_gpj1_default { + /omit-if-no-ref/ tach2b_gpj1_default: tach2b_gpj1_default { pinmuxs = <&pinctrlj 1 IT8XXX2_ALT_FUNC_3>; }; /* UART alternate function */ - uart1_rx_gpc7_default: uart1_rx_gpc7_default { + /omit-if-no-ref/ uart1_rx_gpc7_default: uart1_rx_gpc7_default { pinmuxs = <&pinctrlc 7 IT8XXX2_ALT_FUNC_4>; }; - uart1_tx_gpe6_default: uart1_tx_gpe6_default { + /omit-if-no-ref/ uart1_tx_gpe6_default: uart1_tx_gpe6_default { pinmuxs = <&pinctrle 6 IT8XXX2_ALT_FUNC_4>; }; - uart2_rx_gph1_default: uart2_rx_gph1_default { + /omit-if-no-ref/ uart2_rx_gph1_default: uart2_rx_gph1_default { pinmuxs = <&pinctrlh 1 IT8XXX2_ALT_FUNC_3>; }; - uart2_tx_gph2_default: uart2_tx_gph2_default { + /omit-if-no-ref/ uart2_tx_gph2_default: uart2_tx_gph2_default { pinmuxs = <&pinctrlh 2 IT8XXX2_ALT_FUNC_3>; }; }; diff --git a/dts/riscv/ite/it51xxx-wuc-map.dtsi b/dts/riscv/ite/it51xxx-wuc-map.dtsi index 16e82eb0c914..81fbfb8b8b96 100644 --- a/dts/riscv/ite/it51xxx-wuc-map.dtsi +++ b/dts/riscv/ite/it51xxx-wuc-map.dtsi @@ -12,408 +12,408 @@ compatible = "ite,it51xxx-wuc-map"; /* WUC group 2 */ - wuc_wu20: wu20 { + /omit-if-no-ref/ wuc_wu20: wu20 { wucs = <&wuc2 BIT(0)>; /* GPD0 */ }; - wuc_wu21: wu21 { + /omit-if-no-ref/ wuc_wu21: wu21 { wucs = <&wuc2 BIT(1)>; /* GPD1 */ }; - wuc_wu22: wu22 { + /omit-if-no-ref/ wuc_wu22: wu22 { wucs = <&wuc2 BIT(2)>; /* GPC4 */ }; - wuc_wu23: wu23 { + /omit-if-no-ref/ wuc_wu23: wu23 { wucs = <&wuc2 BIT(3)>; /* GPC6 */ }; - wuc_wu24: wu24 { + /omit-if-no-ref/ wuc_wu24: wu24 { wucs = <&wuc2 BIT(4)>; /* GPD2 */ }; - wuc_wu25: wu25 { + /omit-if-no-ref/ wuc_wu25: wu25 { wucs = <&wuc2 BIT(5)>; /* GPB3 */ }; /* WUC group 3 */ - wuc_wu30: wu30 { + /omit-if-no-ref/ wuc_wu30: wu30 { wucs = <&wuc3 BIT(0)>; /* KSI[0] */ }; - wuc_wu31: wu31 { + /omit-if-no-ref/ wuc_wu31: wu31 { wucs = <&wuc3 BIT(1)>; /* KSI[1] */ }; - wuc_wu32: wu32 { + /omit-if-no-ref/ wuc_wu32: wu32 { wucs = <&wuc3 BIT(2)>; /* KSI[2] */ }; - wuc_wu33: wu33 { + /omit-if-no-ref/ wuc_wu33: wu33 { wucs = <&wuc3 BIT(3)>; /* KSI[3] */ }; - wuc_wu34: wu34 { + /omit-if-no-ref/ wuc_wu34: wu34 { wucs = <&wuc3 BIT(4)>; /* KSI[4] */ }; - wuc_wu35: wu35 { + /omit-if-no-ref/ wuc_wu35: wu35 { wucs = <&wuc3 BIT(5)>; /* KSI[5] */ }; - wuc_wu36: wu36 { + /omit-if-no-ref/ wuc_wu36: wu36 { wucs = <&wuc3 BIT(6)>; /* KSI[6] */ }; - wuc_wu37: wu37 { + /omit-if-no-ref/ wuc_wu37: wu37 { wucs = <&wuc3 BIT(7)>; /* KSI[7] */ }; /* WUC group 4 */ - wuc_wu40: wu40 { + /omit-if-no-ref/ wuc_wu40: wu40 { wucs = <&wuc4 BIT(0)>; /* GPE5 */ }; - wuc_wu42: wu42 { + /omit-if-no-ref/ wuc_wu42: wu42 { wucs = <&wuc4 BIT(2)>; /* eSPI transaction */ }; - wuc_wu45: wu45 { + /omit-if-no-ref/ wuc_wu45: wu45 { wucs = <&wuc4 BIT(5)>; /* GPE6 */ }; - wuc_wu46: wu46 { + /omit-if-no-ref/ wuc_wu46: wu46 { wucs = <&wuc4 BIT(6)>; /* GPE7 */ }; /* WUC group 6 */ - wuc_wu60: wu60 { + /omit-if-no-ref/ wuc_wu60: wu60 { wucs = <&wuc6 BIT(0)>; /* GPH0 */ }; - wuc_wu61: wu61 { + /omit-if-no-ref/ wuc_wu61: wu61 { wucs = <&wuc6 BIT(1)>; /* GPH1 */ }; - wuc_wu62: wu62 { + /omit-if-no-ref/ wuc_wu62: wu62 { wucs = <&wuc6 BIT(2)>; /* GPH2 */ }; - wuc_wu63: wu63 { + /omit-if-no-ref/ wuc_wu63: wu63 { wucs = <&wuc6 BIT(3)>; /* GPH3 */ }; - wuc_wu64: wu64 { + /omit-if-no-ref/ wuc_wu64: wu64 { wucs = <&wuc6 BIT(4)>; /* GPF4 */ }; - wuc_wu65: wu65 { + /omit-if-no-ref/ wuc_wu65: wu65 { wucs = <&wuc6 BIT(5)>; /* GPF5 */ }; - wuc_wu66: wu66 { + /omit-if-no-ref/ wuc_wu66: wu66 { wucs = <&wuc6 BIT(6)>; /* GPF6 */ }; - wuc_wu67: wu67 { + /omit-if-no-ref/ wuc_wu67: wu67 { wucs = <&wuc6 BIT(7)>; /* GPF7 */ }; /* WUC group 7 */ - wuc_wu70: wu70 { + /omit-if-no-ref/ wuc_wu70: wu70 { wucs = <&wuc7 BIT(0)>; /* GPE0 */ }; - wuc_wu71: wu71 { + /omit-if-no-ref/ wuc_wu71: wu71 { wucs = <&wuc7 BIT(1)>; /* GPE1 */ }; - wuc_wu72: wu72 { + /omit-if-no-ref/ wuc_wu72: wu72 { wucs = <&wuc7 BIT(2)>; /* GPE2 */ }; - wuc_wu73: wu73 { + /omit-if-no-ref/ wuc_wu73: wu73 { wucs = <&wuc7 BIT(3)>; /* GPE3 */ }; - wuc_wu74: wu74 { + /omit-if-no-ref/ wuc_wu74: wu74 { wucs = <&wuc7 BIT(4)>; /* GPI4 */ }; - wuc_wu75: wu75 { + /omit-if-no-ref/ wuc_wu75: wu75 { wucs = <&wuc7 BIT(5)>; /* GPI5 */ }; - wuc_wu76: wu76 { + /omit-if-no-ref/ wuc_wu76: wu76 { wucs = <&wuc7 BIT(6)>; /* GPI6 */ }; - wuc_wu77: wu77 { + /omit-if-no-ref/ wuc_wu77: wu77 { wucs = <&wuc7 BIT(7)>; /* GPI7 */ }; /* WUC group 8 */ - wuc_wu80: wu80 { + /omit-if-no-ref/ wuc_wu80: wu80 { wucs = <&wuc8 BIT(0)>; /* GPA3 */ }; - wuc_wu81: wu81 { + /omit-if-no-ref/ wuc_wu81: wu81 { wucs = <&wuc8 BIT(1)>; /* GPA4 */ }; - wuc_wu82: wu82 { + /omit-if-no-ref/ wuc_wu82: wu82 { wucs = <&wuc8 BIT(2)>; /* GPA5 */ }; - wuc_wu83: wu83 { + /omit-if-no-ref/ wuc_wu83: wu83 { wucs = <&wuc8 BIT(3)>; /* GPA6 */ }; - wuc_wu84: wu84 { + /omit-if-no-ref/ wuc_wu84: wu84 { wucs = <&wuc8 BIT(4)>; /* GPB2 */ }; - wuc_wu85: wu85 { + /omit-if-no-ref/ wuc_wu85: wu85 { wucs = <&wuc8 BIT(5)>; /* GPC0 */ }; - wuc_wu86: wu86 { + /omit-if-no-ref/ wuc_wu86: wu86 { wucs = <&wuc8 BIT(6)>; /* GPC7 */ }; - wuc_wu87: wu87 { + /omit-if-no-ref/ wuc_wu87: wu87 { wucs = <&wuc8 BIT(7)>; /* GPD7 */ }; /* WUC group 9 */ - wuc_wu88: wu88 { + /omit-if-no-ref/ wuc_wu88: wu88 { wucs = <&wuc9 BIT(0)>; /* GPH4 */ }; - wuc_wu89: wu89 { + /omit-if-no-ref/ wuc_wu89: wu89 { wucs = <&wuc9 BIT(1)>; /* GPH5 */ }; - wuc_wu90: wu90 { + /omit-if-no-ref/ wuc_wu90: wu90 { wucs = <&wuc9 BIT(2)>; /* GPH6 */ }; - wuc_wu91: wu91 { + /omit-if-no-ref/ wuc_wu91: wu91 { wucs = <&wuc9 BIT(3)>; /* GPA0 */ }; - wuc_wu92: wu92 { + /omit-if-no-ref/ wuc_wu92: wu92 { wucs = <&wuc9 BIT(4)>; /* GPA1 */ }; - wuc_wu93: wu93 { + /omit-if-no-ref/ wuc_wu93: wu93 { wucs = <&wuc9 BIT(5)>; /* GPA2 */ }; - wuc_wu95: wu95 { + /omit-if-no-ref/ wuc_wu95: wu95 { wucs = <&wuc9 BIT(7)>; /* GPC2 */ }; /* WUC group 10 */ - wuc_wu96: wu96 { + /omit-if-no-ref/ wuc_wu96: wu96 { wucs = <&wuc10 BIT(0)>; /* GPF0 */ }; - wuc_wu97: wu97 { + /omit-if-no-ref/ wuc_wu97: wu97 { wucs = <&wuc10 BIT(1)>; /* GPF1 */ }; - wuc_wu98: wu98 { + /omit-if-no-ref/ wuc_wu98: wu98 { wucs = <&wuc10 BIT(2)>; /* GPF2 */ }; - wuc_wu99: wu99 { + /omit-if-no-ref/ wuc_wu99: wu99 { wucs = <&wuc10 BIT(3)>; /* GPF3 */ }; - wuc_wu100: wu100 { + /omit-if-no-ref/ wuc_wu100: wu100 { wucs = <&wuc10 BIT(4)>; /* GPA7 */ }; - wuc_wu101: wu101 { + /omit-if-no-ref/ wuc_wu101: wu101 { wucs = <&wuc10 BIT(5)>; /* GPB0 */ }; - wuc_wu102: wu102 { + /omit-if-no-ref/ wuc_wu102: wu102 { wucs = <&wuc10 BIT(6)>; /* GPB1 */ }; - wuc_wu103: wu103 { + /omit-if-no-ref/ wuc_wu103: wu103 { wucs = <&wuc10 BIT(7)>; /* GPB3 */ }; /* WUC group 11 */ - wuc_wu104: wu104 { + /omit-if-no-ref/ wuc_wu104: wu104 { wucs = <&wuc11 BIT(0)>; /* GPB5 */ }; - wuc_wu105: wu105 { + /omit-if-no-ref/ wuc_wu105: wu105 { wucs = <&wuc11 BIT(1)>; /* GPB6 */ }; - wuc_wu107: wu107 { + /omit-if-no-ref/ wuc_wu107: wu107 { wucs = <&wuc11 BIT(3)>; /* GPC1 */ }; - wuc_wu108: wu108 { + /omit-if-no-ref/ wuc_wu108: wu108 { wucs = <&wuc11 BIT(4)>; /* GPC3 */ }; - wuc_wu109: wu109 { + /omit-if-no-ref/ wuc_wu109: wu109 { wucs = <&wuc11 BIT(5)>; /* GPC5 */ }; - wuc_wu110: wu110 { + /omit-if-no-ref/ wuc_wu110: wu110 { wucs = <&wuc11 BIT(6)>; /* GPD3 */ }; - wuc_wu111: wu111 { + /omit-if-no-ref/ wuc_wu111: wu111 { wucs = <&wuc11 BIT(7)>; /* GPD4 */ }; /* WUC group 12 */ - wuc_wu112: wu112 { + /omit-if-no-ref/ wuc_wu112: wu112 { wucs = <&wuc12 BIT(0)>; /* GPD5 */ }; - wuc_wu113: wu113 { + /omit-if-no-ref/ wuc_wu113: wu113 { wucs = <&wuc12 BIT(1)>; /* GPD6 */ }; - wuc_wu114: wu114 { + /omit-if-no-ref/ wuc_wu114: wu114 { wucs = <&wuc12 BIT(2)>; /* GPE4 */ }; - wuc_wu115: wu115 { + /omit-if-no-ref/ wuc_wu115: wu115 { wucs = <&wuc12 BIT(3)>; /* GPG0 */ }; - wuc_wu116: wu116 { + /omit-if-no-ref/ wuc_wu116: wu116 { wucs = <&wuc12 BIT(4)>; /* GPG1 */ }; - wuc_wu117: wu117 { + /omit-if-no-ref/ wuc_wu117: wu117 { wucs = <&wuc12 BIT(5)>; /* GPG2 */ }; - wuc_wu118: wu118 { + /omit-if-no-ref/ wuc_wu118: wu118 { wucs = <&wuc12 BIT(6)>; /* GPG6 */ }; - wuc_wu119: wu119 { + /omit-if-no-ref/ wuc_wu119: wu119 { wucs = <&wuc12 BIT(7)>; /* GPI0 */ }; /* WUC group 13 */ - wuc_wu120: wu120 { + /omit-if-no-ref/ wuc_wu120: wu120 { wucs = <&wuc13 BIT(0)>; /* GPI1 */ }; - wuc_wu121: wu121 { + /omit-if-no-ref/ wuc_wu121: wu121 { wucs = <&wuc13 BIT(1)>; /* GPI2 */ }; - wuc_wu122: wu122 { + /omit-if-no-ref/ wuc_wu122: wu122 { wucs = <&wuc13 BIT(2)>; /* GPI3 */ }; - wuc_wu127: wu127 { + /omit-if-no-ref/ wuc_wu127: wu127 { wucs = <&wuc13 BIT(7)>; /* GPH7 */ }; /* WUC group 14 */ - wuc_wu128: wu128 { + /omit-if-no-ref/ wuc_wu128: wu128 { wucs = <&wuc14 BIT(0)>; /* GPJ0 */ }; - wuc_wu129: wu129 { + /omit-if-no-ref/ wuc_wu129: wu129 { wucs = <&wuc14 BIT(1)>; /* GPJ1 */ }; - wuc_wu131: wu131 { + /omit-if-no-ref/ wuc_wu131: wu131 { wucs = <&wuc14 BIT(3)>; /* GPJ3 */ }; - wuc_wu132: wu132 { + /omit-if-no-ref/ wuc_wu132: wu132 { wucs = <&wuc14 BIT(4)>; /* GPJ4 */ }; - wuc_wu133: wu133 { + /omit-if-no-ref/ wuc_wu133: wu133 { wucs = <&wuc14 BIT(5)>; /* GPJ5 */ }; - wuc_wu134: wu134 { + /omit-if-no-ref/ wuc_wu134: wu134 { wucs = <&wuc14 BIT(6)>; /* GPJ6 */ }; - wuc_wu135: wu135 { + /omit-if-no-ref/ wuc_wu135: wu135 { wucs = <&wuc14 BIT(7)>; /* GPJ7 */ }; /* WUC group 15 */ - wuc_wu136: wu136 { + /omit-if-no-ref/ wuc_wu136: wu136 { wucs = <&wuc15 BIT(0)>; /* GPL0 */ }; - wuc_wu137: wu137 { + /omit-if-no-ref/ wuc_wu137: wu137 { wucs = <&wuc15 BIT(1)>; /* GPL1 */ }; - wuc_wu138: wu138 { + /omit-if-no-ref/ wuc_wu138: wu138 { wucs = <&wuc15 BIT(2)>; /* GPL2 */ }; - wuc_wu139: wu139 { + /omit-if-no-ref/ wuc_wu139: wu139 { wucs = <&wuc15 BIT(3)>; /* GPL3 */ }; - wuc_wu140: wu140 { + /omit-if-no-ref/ wuc_wu140: wu140 { wucs = <&wuc15 BIT(4)>; /* GPL4 */ }; - wuc_wu141: wu141 { + /omit-if-no-ref/ wuc_wu141: wu141 { wucs = <&wuc15 BIT(5)>; /* GPL5 */ }; - wuc_wu142: wu142 { + /omit-if-no-ref/ wuc_wu142: wu142 { wucs = <&wuc15 BIT(6)>; /* GPL6 */ }; /* WUC group 16 */ - wuc_wu144: wu144 { + /omit-if-no-ref/ wuc_wu144: wu144 { wucs = <&wuc16 BIT(0)>; /* GPM0 */ }; - wuc_wu145: wu145 { + /omit-if-no-ref/ wuc_wu145: wu145 { wucs = <&wuc16 BIT(1)>; /* GPM1 */ }; - wuc_wu146: wu146 { + /omit-if-no-ref/ wuc_wu146: wu146 { wucs = <&wuc16 BIT(2)>; /* GPM2 */ }; - wuc_wu147: wu147 { + /omit-if-no-ref/ wuc_wu147: wu147 { wucs = <&wuc16 BIT(3)>; /* GPM3 */ }; - wuc_wu148: wu148 { + /omit-if-no-ref/ wuc_wu148: wu148 { wucs = <&wuc16 BIT(4)>; /* GPM4 */ }; - wuc_wu149: wu149 { + /omit-if-no-ref/ wuc_wu149: wu149 { wucs = <&wuc16 BIT(5)>; /* GPM5 */ }; - wuc_wu150: wu150 { + /omit-if-no-ref/ wuc_wu150: wu150 { wucs = <&wuc16 BIT(6)>; /* GPM6 */ }; - wuc_no_func: no_func { + /omit-if-no-ref/ wuc_no_func: no_func { wucs = <&wuc_fake 0>; }; }; From e13971b79645ab93cefcd9923468bbb0e71dd550 Mon Sep 17 00:00:00 2001 From: Tim Lin Date: Wed, 21 Jan 2026 15:56:14 +0800 Subject: [PATCH 2536/3659] dts: ite/it8xxx2: Reduce devicetree size with omit-if-no-ref Mark unused pinctrl and wuc nodes in it8xxx2 with /omit-if-no-ref/, so that they are omitted from the final devicetree when not referenced. After this change, test: "west build -p always -b it8xxx2_evb" shows a reduction in devicetree size: Before: build/zephyr/zephyr.dts 164,449 bytes build/zephyr/include/generated/zephyr/devicetree_generated.h 3,125,359 bytes After: build/zephyr/zephyr.dts 124,108 bytes build/zephyr/include/generated/zephyr/devicetree_generated.h 1,892,313 bytes Signed-off-by: Tim Lin --- dts/riscv/ite/it8xxx2-pinctrl-map.dtsi | 240 ++++++++++++------------- dts/riscv/ite/it8xxx2-wuc-map.dtsi | 224 +++++++++++------------ 2 files changed, 232 insertions(+), 232 deletions(-) diff --git a/dts/riscv/ite/it8xxx2-pinctrl-map.dtsi b/dts/riscv/ite/it8xxx2-pinctrl-map.dtsi index 55cc27386f0c..258ed7442266 100644 --- a/dts/riscv/ite/it8xxx2-pinctrl-map.dtsi +++ b/dts/riscv/ite/it8xxx2-pinctrl-map.dtsi @@ -8,537 +8,537 @@ &pinctrl { /* ADC alternate function */ - adc0_ch0_gpi0_default: adc0_ch0_gpi0_default { + /omit-if-no-ref/ adc0_ch0_gpi0_default: adc0_ch0_gpi0_default { pinmuxs = <&pinctrli 0 IT8XXX2_ALT_FUNC_1>; }; - adc0_ch1_gpi1_default: adc0_ch1_gpi1_default { + /omit-if-no-ref/ adc0_ch1_gpi1_default: adc0_ch1_gpi1_default { pinmuxs = <&pinctrli 1 IT8XXX2_ALT_FUNC_1>; }; - adc0_ch2_gpi2_default: adc0_ch2_gpi2_default { + /omit-if-no-ref/ adc0_ch2_gpi2_default: adc0_ch2_gpi2_default { pinmuxs = <&pinctrli 2 IT8XXX2_ALT_FUNC_1>; }; - adc0_ch3_gpi3_default: adc0_ch3_gpi3_default { + /omit-if-no-ref/ adc0_ch3_gpi3_default: adc0_ch3_gpi3_default { pinmuxs = <&pinctrli 3 IT8XXX2_ALT_FUNC_1>; }; - adc0_ch4_gpi4_default: adc0_ch4_gpi4_default { + /omit-if-no-ref/ adc0_ch4_gpi4_default: adc0_ch4_gpi4_default { pinmuxs = <&pinctrli 4 IT8XXX2_ALT_FUNC_1>; }; - adc0_ch5_gpi5_default: adc0_ch5_gpi5_default { + /omit-if-no-ref/ adc0_ch5_gpi5_default: adc0_ch5_gpi5_default { pinmuxs = <&pinctrli 5 IT8XXX2_ALT_FUNC_1>; }; - adc0_ch6_gpi6_default: adc0_ch6_gpi6_default { + /omit-if-no-ref/ adc0_ch6_gpi6_default: adc0_ch6_gpi6_default { pinmuxs = <&pinctrli 6 IT8XXX2_ALT_FUNC_1>; }; - adc0_ch7_gpi7_default: adc0_ch7_gpi7_default { + /omit-if-no-ref/ adc0_ch7_gpi7_default: adc0_ch7_gpi7_default { pinmuxs = <&pinctrli 7 IT8XXX2_ALT_FUNC_1>; }; - adc0_ch13_gpl0_default: adc0_ch13_gpl0_default { + /omit-if-no-ref/ adc0_ch13_gpl0_default: adc0_ch13_gpl0_default { pinmuxs = <&pinctrll 0 IT8XXX2_ALT_FUNC_1>; }; - adc0_ch14_gpl1_default: adc0_ch14_gpl1_default { + /omit-if-no-ref/ adc0_ch14_gpl1_default: adc0_ch14_gpl1_default { pinmuxs = <&pinctrll 1 IT8XXX2_ALT_FUNC_1>; }; - adc0_ch15_gpl2_default: adc0_ch15_gpl2_default { + /omit-if-no-ref/ adc0_ch15_gpl2_default: adc0_ch15_gpl2_default { pinmuxs = <&pinctrll 2 IT8XXX2_ALT_FUNC_1>; }; - adc0_ch16_gpl3_default: adc0_ch16_gpl3_default { + /omit-if-no-ref/ adc0_ch16_gpl3_default: adc0_ch16_gpl3_default { pinmuxs = <&pinctrll 3 IT8XXX2_ALT_FUNC_1>; }; /* CEC alternate function */ - cec_gpf0_default: cec_gpf0_default { + /omit-if-no-ref/ cec_gpf0_default: cec_gpf0_default { pinmuxs = <&pinctrlf 0 IT8XXX2_ALT_FUNC_4>; }; - cec_gpf0_sleep: cec_gpf0_sleep { + /omit-if-no-ref/ cec_gpf0_sleep: cec_gpf0_sleep { pinmuxs = <&pinctrlf 0 IT8XXX2_ALT_DEFAULT>; }; /* I2C alternate function */ - i2c0_clk_gpb3_default: i2c0_clk_gpb3_default { + /omit-if-no-ref/ i2c0_clk_gpb3_default: i2c0_clk_gpb3_default { pinmuxs = <&pinctrlb 3 IT8XXX2_ALT_FUNC_1>; }; - i2c0_data_gpb4_default: i2c0_data_gpb4_default { + /omit-if-no-ref/ i2c0_data_gpb4_default: i2c0_data_gpb4_default { pinmuxs = <&pinctrlb 4 IT8XXX2_ALT_FUNC_1>; }; - i2c1_clk_gpc1_default: i2c1_clk_gpc1_default { + /omit-if-no-ref/ i2c1_clk_gpc1_default: i2c1_clk_gpc1_default { pinmuxs = <&pinctrlc 1 IT8XXX2_ALT_FUNC_1>; }; - i2c1_data_gpc2_default: i2c1_data_gpc2_default { + /omit-if-no-ref/ i2c1_data_gpc2_default: i2c1_data_gpc2_default { pinmuxs = <&pinctrlc 2 IT8XXX2_ALT_FUNC_1>; }; - i2c2_clk_gpf6_default: i2c2_clk_gpf6_default { + /omit-if-no-ref/ i2c2_clk_gpf6_default: i2c2_clk_gpf6_default { pinmuxs = <&pinctrlf 6 IT8XXX2_ALT_FUNC_1>; }; - i2c2_data_gpf7_default: i2c2_data_gpf7_default { + /omit-if-no-ref/ i2c2_data_gpf7_default: i2c2_data_gpf7_default { pinmuxs = <&pinctrlf 7 IT8XXX2_ALT_FUNC_1>; }; - i2c3_clk_gph1_default: i2c3_clk_gph1_default { + /omit-if-no-ref/ i2c3_clk_gph1_default: i2c3_clk_gph1_default { pinmuxs = <&pinctrlh 1 IT8XXX2_ALT_FUNC_3>; }; - i2c3_data_gph2_default: i2c3_data_gph2_default { + /omit-if-no-ref/ i2c3_data_gph2_default: i2c3_data_gph2_default { pinmuxs = <&pinctrlh 2 IT8XXX2_ALT_FUNC_3>; }; - i2c3_clk_gpf2_default: i2c3_clk_gpf2_default { + /omit-if-no-ref/ i2c3_clk_gpf2_default: i2c3_clk_gpf2_default { pinmuxs = <&pinctrlf 2 IT8XXX2_ALT_FUNC_4>; }; - i2c3_data_gpf3_default: i2c3_data_gpf3_default { + /omit-if-no-ref/ i2c3_data_gpf3_default: i2c3_data_gpf3_default { pinmuxs = <&pinctrlf 3 IT8XXX2_ALT_FUNC_4>; }; - i2c4_clk_gpe0_default: i2c4_clk_gpe0_default { + /omit-if-no-ref/ i2c4_clk_gpe0_default: i2c4_clk_gpe0_default { pinmuxs = <&pinctrle 0 IT8XXX2_ALT_FUNC_3>; }; - i2c4_data_gpe7_default: i2c4_data_gpe7_default { + /omit-if-no-ref/ i2c4_data_gpe7_default: i2c4_data_gpe7_default { pinmuxs = <&pinctrle 7 IT8XXX2_ALT_FUNC_3>; }; - i2c5_clk_gpa4_default: i2c5_clk_gpa4_default { + /omit-if-no-ref/ i2c5_clk_gpa4_default: i2c5_clk_gpa4_default { pinmuxs = <&pinctrla 4 IT8XXX2_ALT_FUNC_3>; }; - i2c5_data_gpa5_default: i2c5_data_gpa5_default { + /omit-if-no-ref/ i2c5_data_gpa5_default: i2c5_data_gpa5_default { pinmuxs = <&pinctrla 5 IT8XXX2_ALT_FUNC_3>; }; /* I2C alternate function (Mapping pins for IT82XX2) */ - i2c2_clk_gpc7_default: i2c2_clk_gpc7_default { + /omit-if-no-ref/ i2c2_clk_gpc7_default: i2c2_clk_gpc7_default { pinmuxs = <&pinctrlc 7 IT8XXX2_ALT_FUNC_4>; }; - i2c2_data_gpd0_default: i2c2_data_gpd0_default { + /omit-if-no-ref/ i2c2_data_gpd0_default: i2c2_data_gpd0_default { pinmuxs = <&pinctrld 0 IT8XXX2_ALT_FUNC_4>; }; - i2c3_clk_gpb2_default: i2c3_clk_gpb2_default { + /omit-if-no-ref/ i2c3_clk_gpb2_default: i2c3_clk_gpb2_default { pinmuxs = <&pinctrlb 2 IT8XXX2_ALT_FUNC_3>; }; - i2c3_data_gpb5_default: i2c3_data_gpb5_default { + /omit-if-no-ref/ i2c3_data_gpb5_default: i2c3_data_gpb5_default { pinmuxs = <&pinctrlb 5 IT8XXX2_ALT_FUNC_3>; }; - i2c5_clk_gpe1_default: i2c5_clk_gpe1_default { + /omit-if-no-ref/ i2c5_clk_gpe1_default: i2c5_clk_gpe1_default { pinmuxs = <&pinctrle 1 IT8XXX2_ALT_FUNC_3>; }; - i2c5_data_gpe2_default: i2c5_data_gpe2_default { + /omit-if-no-ref/ i2c5_data_gpe2_default: i2c5_data_gpe2_default { pinmuxs = <&pinctrle 2 IT8XXX2_ALT_FUNC_3>; }; /* Keyboard alternate function */ - ksi0_default: ksi0_default { + /omit-if-no-ref/ ksi0_default: ksi0_default { pinmuxs = <&pinctrlksi 0 IT8XXX2_ALT_FUNC_1>; bias-pull-up; }; - ksi1_default: ksi1_default { + /omit-if-no-ref/ ksi1_default: ksi1_default { pinmuxs = <&pinctrlksi 1 IT8XXX2_ALT_FUNC_1>; bias-pull-up; }; - ksi2_default: ksi2_default { + /omit-if-no-ref/ ksi2_default: ksi2_default { pinmuxs = <&pinctrlksi 2 IT8XXX2_ALT_FUNC_1>; bias-pull-up; }; - ksi3_default: ksi3_default { + /omit-if-no-ref/ ksi3_default: ksi3_default { pinmuxs = <&pinctrlksi 3 IT8XXX2_ALT_FUNC_1>; bias-pull-up; }; - ksi4_default: ksi4_default { + /omit-if-no-ref/ ksi4_default: ksi4_default { pinmuxs = <&pinctrlksi 4 IT8XXX2_ALT_FUNC_1>; bias-pull-up; }; - ksi5_default: ksi5_default { + /omit-if-no-ref/ ksi5_default: ksi5_default { pinmuxs = <&pinctrlksi 5 IT8XXX2_ALT_FUNC_1>; bias-pull-up; }; - ksi6_default: ksi6_default { + /omit-if-no-ref/ ksi6_default: ksi6_default { pinmuxs = <&pinctrlksi 6 IT8XXX2_ALT_FUNC_1>; bias-pull-up; }; - ksi7_default: ksi7_default { + /omit-if-no-ref/ ksi7_default: ksi7_default { pinmuxs = <&pinctrlksi 7 IT8XXX2_ALT_FUNC_1>; bias-pull-up; }; - kso0_default: kso0_default { + /omit-if-no-ref/ kso0_default: kso0_default { pinmuxs = <&pinctrlksol 0 IT8XXX2_ALT_FUNC_1>; drive-open-drain; bias-pull-up; }; - kso1_default: kso1_default { + /omit-if-no-ref/ kso1_default: kso1_default { pinmuxs = <&pinctrlksol 1 IT8XXX2_ALT_FUNC_1>; drive-open-drain; bias-pull-up; }; - kso2_default: kso2_default { + /omit-if-no-ref/ kso2_default: kso2_default { pinmuxs = <&pinctrlksol 2 IT8XXX2_ALT_FUNC_1>; drive-open-drain; bias-pull-up; }; - kso3_default: kso3_default { + /omit-if-no-ref/ kso3_default: kso3_default { pinmuxs = <&pinctrlksol 3 IT8XXX2_ALT_FUNC_1>; drive-open-drain; bias-pull-up; }; - kso4_default: kso4_default { + /omit-if-no-ref/ kso4_default: kso4_default { pinmuxs = <&pinctrlksol 4 IT8XXX2_ALT_FUNC_1>; drive-open-drain; bias-pull-up; }; - kso5_default: kso5_default { + /omit-if-no-ref/ kso5_default: kso5_default { pinmuxs = <&pinctrlksol 5 IT8XXX2_ALT_FUNC_1>; drive-open-drain; bias-pull-up; }; - kso6_default: kso6_default { + /omit-if-no-ref/ kso6_default: kso6_default { pinmuxs = <&pinctrlksol 6 IT8XXX2_ALT_FUNC_1>; drive-open-drain; bias-pull-up; }; - kso7_default: kso7_default { + /omit-if-no-ref/ kso7_default: kso7_default { pinmuxs = <&pinctrlksol 7 IT8XXX2_ALT_FUNC_1>; drive-open-drain; bias-pull-up; }; - kso8_default: kso8_default { + /omit-if-no-ref/ kso8_default: kso8_default { pinmuxs = <&pinctrlksoh 0 IT8XXX2_ALT_FUNC_1>; drive-open-drain; bias-pull-up; }; - kso9_default: kso9_default { + /omit-if-no-ref/ kso9_default: kso9_default { pinmuxs = <&pinctrlksoh 1 IT8XXX2_ALT_FUNC_1>; drive-open-drain; bias-pull-up; }; - kso10_default: kso10_default { + /omit-if-no-ref/ kso10_default: kso10_default { pinmuxs = <&pinctrlksoh 2 IT8XXX2_ALT_FUNC_1>; drive-open-drain; bias-pull-up; }; - kso11_default: kso11_default { + /omit-if-no-ref/ kso11_default: kso11_default { pinmuxs = <&pinctrlksoh 3 IT8XXX2_ALT_FUNC_1>; drive-open-drain; bias-pull-up; }; - kso12_default: kso12_default { + /omit-if-no-ref/ kso12_default: kso12_default { pinmuxs = <&pinctrlksoh 4 IT8XXX2_ALT_FUNC_1>; drive-open-drain; bias-pull-up; }; - kso13_default: kso13_default { + /omit-if-no-ref/ kso13_default: kso13_default { pinmuxs = <&pinctrlksoh 5 IT8XXX2_ALT_FUNC_1>; drive-open-drain; bias-pull-up; }; - kso14_default: kso14_default { + /omit-if-no-ref/ kso14_default: kso14_default { pinmuxs = <&pinctrlksoh 6 IT8XXX2_ALT_FUNC_1>; drive-open-drain; bias-pull-up; }; - kso15_default: kso15_default { + /omit-if-no-ref/ kso15_default: kso15_default { pinmuxs = <&pinctrlksoh 7 IT8XXX2_ALT_FUNC_1>; drive-open-drain; bias-pull-up; }; - kso16_default: kso16_gpc3_default: kso16_default { + /omit-if-no-ref/ kso16_default: kso16_gpc3_default: kso16_default { pinmuxs = <&pinctrlc 3 IT8XXX2_ALT_FUNC_1>; bias-pull-up; }; - kso17_default: kso17_gpc5_default: kso17_default { + /omit-if-no-ref/ kso17_default: kso17_gpc5_default: kso17_default { pinmuxs = <&pinctrlc 5 IT8XXX2_ALT_FUNC_1>; bias-pull-up; }; /* Keyboard sleep function */ - ksi0_sleep: ksi0_sleep { + /omit-if-no-ref/ ksi0_sleep: ksi0_sleep { pinmuxs = <&pinctrlksi 0 IT8XXX2_ALT_DEFAULT>; }; - ksi1_sleep: ksi1_sleep { + /omit-if-no-ref/ ksi1_sleep: ksi1_sleep { pinmuxs = <&pinctrlksi 1 IT8XXX2_ALT_DEFAULT>; }; - ksi2_sleep: ksi2_sleep { + /omit-if-no-ref/ ksi2_sleep: ksi2_sleep { pinmuxs = <&pinctrlksi 2 IT8XXX2_ALT_DEFAULT>; }; - ksi3_sleep: ksi3_sleep { + /omit-if-no-ref/ ksi3_sleep: ksi3_sleep { pinmuxs = <&pinctrlksi 3 IT8XXX2_ALT_DEFAULT>; }; - ksi4_sleep: ksi4_sleep { + /omit-if-no-ref/ ksi4_sleep: ksi4_sleep { pinmuxs = <&pinctrlksi 4 IT8XXX2_ALT_DEFAULT>; }; - ksi5_sleep: ksi5_sleep { + /omit-if-no-ref/ ksi5_sleep: ksi5_sleep { pinmuxs = <&pinctrlksi 5 IT8XXX2_ALT_DEFAULT>; }; - ksi6_sleep: ksi6_sleep { + /omit-if-no-ref/ ksi6_sleep: ksi6_sleep { pinmuxs = <&pinctrlksi 6 IT8XXX2_ALT_DEFAULT>; }; - ksi7_sleep: ksi7_sleep { + /omit-if-no-ref/ ksi7_sleep: ksi7_sleep { pinmuxs = <&pinctrlksi 7 IT8XXX2_ALT_DEFAULT>; }; - kso0_sleep: kso0_sleep { + /omit-if-no-ref/ kso0_sleep: kso0_sleep { pinmuxs = <&pinctrlksol 0 IT8XXX2_ALT_DEFAULT>; }; - kso1_sleep: kso1_sleep { + /omit-if-no-ref/ kso1_sleep: kso1_sleep { pinmuxs = <&pinctrlksol 1 IT8XXX2_ALT_DEFAULT>; }; - kso2_sleep: kso2_sleep { + /omit-if-no-ref/ kso2_sleep: kso2_sleep { pinmuxs = <&pinctrlksol 2 IT8XXX2_ALT_DEFAULT>; }; - kso3_sleep: kso3_sleep { + /omit-if-no-ref/ kso3_sleep: kso3_sleep { pinmuxs = <&pinctrlksol 3 IT8XXX2_ALT_DEFAULT>; }; - kso4_sleep: kso4_sleep { + /omit-if-no-ref/ kso4_sleep: kso4_sleep { pinmuxs = <&pinctrlksol 4 IT8XXX2_ALT_DEFAULT>; }; - kso5_sleep: kso5_sleep { + /omit-if-no-ref/ kso5_sleep: kso5_sleep { pinmuxs = <&pinctrlksol 5 IT8XXX2_ALT_DEFAULT>; }; - kso6_sleep: kso6_sleep { + /omit-if-no-ref/ kso6_sleep: kso6_sleep { pinmuxs = <&pinctrlksol 6 IT8XXX2_ALT_DEFAULT>; }; - kso7_sleep: kso7_sleep { + /omit-if-no-ref/ kso7_sleep: kso7_sleep { pinmuxs = <&pinctrlksol 7 IT8XXX2_ALT_DEFAULT>; }; - kso8_sleep: kso8_sleep { + /omit-if-no-ref/ kso8_sleep: kso8_sleep { pinmuxs = <&pinctrlksoh 0 IT8XXX2_ALT_DEFAULT>; }; - kso9_sleep: kso9_sleep { + /omit-if-no-ref/ kso9_sleep: kso9_sleep { pinmuxs = <&pinctrlksoh 1 IT8XXX2_ALT_DEFAULT>; }; - kso10_sleep: kso10_sleep { + /omit-if-no-ref/ kso10_sleep: kso10_sleep { pinmuxs = <&pinctrlksoh 2 IT8XXX2_ALT_DEFAULT>; }; - kso11_sleep: kso11_sleep { + /omit-if-no-ref/ kso11_sleep: kso11_sleep { pinmuxs = <&pinctrlksoh 3 IT8XXX2_ALT_DEFAULT>; }; - kso12_sleep: kso12_sleep { + /omit-if-no-ref/ kso12_sleep: kso12_sleep { pinmuxs = <&pinctrlksoh 4 IT8XXX2_ALT_DEFAULT>; }; - kso13_sleep: kso13_sleep { + /omit-if-no-ref/ kso13_sleep: kso13_sleep { pinmuxs = <&pinctrlksoh 5 IT8XXX2_ALT_DEFAULT>; }; - kso14_sleep: kso14_sleep { + /omit-if-no-ref/ kso14_sleep: kso14_sleep { pinmuxs = <&pinctrlksoh 6 IT8XXX2_ALT_DEFAULT>; }; - kso15_sleep: kso15_sleep { + /omit-if-no-ref/ kso15_sleep: kso15_sleep { pinmuxs = <&pinctrlksoh 7 IT8XXX2_ALT_DEFAULT>; }; - kso16_sleep: kso16_gpc3_sleep: kso16_sleep { + /omit-if-no-ref/ kso16_sleep: kso16_gpc3_sleep: kso16_sleep { pinmuxs = <&pinctrlc 3 IT8XXX2_ALT_DEFAULT>; }; - kso17_sleep: kso17_gpc5_sleep: kso17_sleep { + /omit-if-no-ref/ kso17_sleep: kso17_gpc5_sleep: kso17_sleep { pinmuxs = <&pinctrlc 5 IT8XXX2_ALT_DEFAULT>; }; /* PECI alternate function */ - peci_gpf6_default: peci_gpf6_default { + /omit-if-no-ref/ peci_gpf6_default: peci_gpf6_default { pinmuxs = <&pinctrlf 6 IT8XXX2_ALT_FUNC_3>; }; /* PWM alternate function */ - pwm0_gpa0_default: pwm0_gpa0_default { + /omit-if-no-ref/ pwm0_gpa0_default: pwm0_gpa0_default { pinmuxs = <&pinctrla 0 IT8XXX2_ALT_FUNC_1>; }; - pwm1_gpa1_default: pwm1_gpa1_default { + /omit-if-no-ref/ pwm1_gpa1_default: pwm1_gpa1_default { pinmuxs = <&pinctrla 1 IT8XXX2_ALT_FUNC_1>; }; - pwm2_gpa2_default: pwm2_gpa2_default { + /omit-if-no-ref/ pwm2_gpa2_default: pwm2_gpa2_default { pinmuxs = <&pinctrla 2 IT8XXX2_ALT_FUNC_1>; }; - pwm3_gpa3_default: pwm3_gpa3_default { + /omit-if-no-ref/ pwm3_gpa3_default: pwm3_gpa3_default { pinmuxs = <&pinctrla 3 IT8XXX2_ALT_FUNC_1>; }; - pwm4_gpa4_default: pwm4_gpa4_default { + /omit-if-no-ref/ pwm4_gpa4_default: pwm4_gpa4_default { pinmuxs = <&pinctrla 4 IT8XXX2_ALT_FUNC_1>; }; - pwm5_gpa5_default: pwm5_gpa5_default { + /omit-if-no-ref/ pwm5_gpa5_default: pwm5_gpa5_default { pinmuxs = <&pinctrla 5 IT8XXX2_ALT_FUNC_1>; }; - pwm6_gpa6_default: pwm6_gpa6_default { + /omit-if-no-ref/ pwm6_gpa6_default: pwm6_gpa6_default { pinmuxs = <&pinctrla 6 IT8XXX2_ALT_FUNC_1>; }; - pwm7_gpa7_default: pwm7_gpa7_default { + /omit-if-no-ref/ pwm7_gpa7_default: pwm7_gpa7_default { pinmuxs = <&pinctrla 7 IT8XXX2_ALT_FUNC_1>; }; /* SHI alternate function */ - shi_mosi_gpm0_default: shi_mosi_gpm0_default { + /omit-if-no-ref/ shi_mosi_gpm0_default: shi_mosi_gpm0_default { pinmuxs = <&pinctrlm 0 IT8XXX2_ALT_FUNC_1>; }; - shi_miso_gpm1_default: shi_miso_gpm1_default { + /omit-if-no-ref/ shi_miso_gpm1_default: shi_miso_gpm1_default { pinmuxs = <&pinctrlm 1 IT8XXX2_ALT_FUNC_1>; }; - shi_clk_gpm4_default: shi_clk_gpm4_default { + /omit-if-no-ref/ shi_clk_gpm4_default: shi_clk_gpm4_default { pinmuxs = <&pinctrlm 4 IT8XXX2_ALT_FUNC_1>; }; - shi_cs_gpm5_default: shi_cs_gpm5_default { + /omit-if-no-ref/ shi_cs_gpm5_default: shi_cs_gpm5_default { pinmuxs = <&pinctrlm 5 IT8XXX2_ALT_FUNC_1>; }; /* Tachometer alternate function */ - tach0a_gpd6_default: tach0a_gpd6_default { + /omit-if-no-ref/ tach0a_gpd6_default: tach0a_gpd6_default { pinmuxs = <&pinctrld 6 IT8XXX2_ALT_FUNC_1>; }; - tach0b_gpj2_default: tach0b_gpj2_default { + /omit-if-no-ref/ tach0b_gpj2_default: tach0b_gpj2_default { pinmuxs = <&pinctrlj 2 IT8XXX2_ALT_FUNC_3>; }; - tach1a_gpd7_default: tach1a_gpd7_default { + /omit-if-no-ref/ tach1a_gpd7_default: tach1a_gpd7_default { pinmuxs = <&pinctrld 7 IT8XXX2_ALT_FUNC_1>; }; - tach1b_gpj3_default: tach1b_gpj3_default { + /omit-if-no-ref/ tach1b_gpj3_default: tach1b_gpj3_default { pinmuxs = <&pinctrlj 3 IT8XXX2_ALT_FUNC_3>; }; /* UART alternate function */ - uart1_rx_gpb0_default: uart1_rx_gpb0_default { + /omit-if-no-ref/ uart1_rx_gpb0_default: uart1_rx_gpb0_default { pinmuxs = <&pinctrlb 0 IT8XXX2_ALT_FUNC_3>; }; - uart1_tx_gpb1_default: uart1_tx_gpb1_default { + /omit-if-no-ref/ uart1_tx_gpb1_default: uart1_tx_gpb1_default { pinmuxs = <&pinctrlb 1 IT8XXX2_ALT_FUNC_3>; }; - uart2_rx_gph1_default: uart2_rx_gph1_default { + /omit-if-no-ref/ uart2_rx_gph1_default: uart2_rx_gph1_default { pinmuxs = <&pinctrlh 1 IT8XXX2_ALT_FUNC_4>; }; - uart2_tx_gph2_default: uart2_tx_gph2_default { + /omit-if-no-ref/ uart2_tx_gph2_default: uart2_tx_gph2_default { pinmuxs = <&pinctrlh 2 IT8XXX2_ALT_FUNC_4>; }; - uart2_rx_gph5_default: uart2_rx_gph5_default { + /omit-if-no-ref/ uart2_rx_gph5_default: uart2_rx_gph5_default { pinmuxs = <&pinctrlh 5 IT8XXX2_ALT_FUNC_3>; }; - uart2_tx_gph6_default: uart2_tx_gph6_default { + /omit-if-no-ref/ uart2_tx_gph6_default: uart2_tx_gph6_default { pinmuxs = <&pinctrlh 6 IT8XXX2_ALT_FUNC_3>; }; - uart2_rx_gpf0_default: uart2_rx_gpf0_default { + /omit-if-no-ref/ uart2_rx_gpf0_default: uart2_rx_gpf0_default { pinmuxs = <&pinctrlf 0 IT8XXX2_ALT_FUNC_3>; }; - uart2_tx_gpf1_default: uart2_tx_gpf1_default { + /omit-if-no-ref/ uart2_tx_gpf1_default: uart2_tx_gpf1_default { pinmuxs = <&pinctrlf 1 IT8XXX2_ALT_FUNC_3>; }; /* USB alternate function */ - usb0_dm_gph5_default: usb0_dm_gph5_default { + /omit-if-no-ref/ usb0_dm_gph5_default: usb0_dm_gph5_default { pinmuxs = <&pinctrlh 5 IT8XXX2_ALT_DEFAULT>; }; - usb0_dp_gph6_default: usb0_dp_gph6_default { + /omit-if-no-ref/ usb0_dp_gph6_default: usb0_dp_gph6_default { pinmuxs = <&pinctrlh 6 IT8XXX2_ALT_DEFAULT>; }; /* SPI alternate function */ - spi_ssce0_default: spi_ssce0_default { + /omit-if-no-ref/ spi_ssce0_default: spi_ssce0_default { pinmuxs = <&pinctrlg 2 IT8XXX2_ALT_FUNC_3>; }; - spi_ssce1_default: spi_ssce1_default { + /omit-if-no-ref/ spi_ssce1_default: spi_ssce1_default { pinmuxs = <&pinctrlg 0 IT8XXX2_ALT_FUNC_3>; }; - spi_ssck_default: spi_ssck_default { + /omit-if-no-ref/ spi_ssck_default: spi_ssck_default { pinmuxs = <&pinctrla 6 IT8XXX2_ALT_FUNC_3>; }; - spi_smosi_default: spi_smosi_default { + /omit-if-no-ref/ spi_smosi_default: spi_smosi_default { pinmuxs = <&pinctrlc 3 IT8XXX2_ALT_FUNC_3>; }; - spi_smiso_default: spi_smiso_default { + /omit-if-no-ref/ spi_smiso_default: spi_smiso_default { pinmuxs = <&pinctrlc 5 IT8XXX2_ALT_FUNC_3>; }; - spi_sio2_default: spi_sio2_default { + /omit-if-no-ref/ spi_sio2_default: spi_sio2_default { pinmuxs = <&pinctrlc 0 IT8XXX2_ALT_FUNC_1>; }; - spi_sio3_default: spi_sio3_default { + /omit-if-no-ref/ spi_sio3_default: spi_sio3_default { pinmuxs = <&pinctrlc 6 IT8XXX2_ALT_FUNC_1>; }; }; diff --git a/dts/riscv/ite/it8xxx2-wuc-map.dtsi b/dts/riscv/ite/it8xxx2-wuc-map.dtsi index 6337add5b29f..8fe0f2d7d2f0 100644 --- a/dts/riscv/ite/it8xxx2-wuc-map.dtsi +++ b/dts/riscv/ite/it8xxx2-wuc-map.dtsi @@ -12,465 +12,465 @@ compatible = "ite,it8xxx2-wuc-map"; /* WUC group 2 */ - wuc_wu20: wu20 { + /omit-if-no-ref/ wuc_wu20: wu20 { wucs = <&wuc2 BIT(0)>; /* GPD0 */ }; - wuc_wu21: wu21 { + /omit-if-no-ref/ wuc_wu21: wu21 { wucs = <&wuc2 BIT(1)>; /* GPD1 */ }; - wuc_wu22: wu22 { + /omit-if-no-ref/ wuc_wu22: wu22 { wucs = <&wuc2 BIT(2)>; /* GPC4 */ }; - wuc_wu23: wu23 { + /omit-if-no-ref/ wuc_wu23: wu23 { wucs = <&wuc2 BIT(3)>; /* GPC6 */ }; - wuc_wu24: wu24 { + /omit-if-no-ref/ wuc_wu24: wu24 { wucs = <&wuc2 BIT(4)>; /* GPD2 */ }; - wuc_wu25: wu25 { + /omit-if-no-ref/ wuc_wu25: wu25 { wucs = <&wuc2 BIT(5)>; /* GPE4 */ }; /* WUC group 3 */ - wuc_wu30: wu30 { + /omit-if-no-ref/ wuc_wu30: wu30 { wucs = <&wuc3 BIT(0)>; /* KSI[0] */ }; - wuc_wu31: wu31 { + /omit-if-no-ref/ wuc_wu31: wu31 { wucs = <&wuc3 BIT(1)>; /* KSI[1] */ }; - wuc_wu32: wu32 { + /omit-if-no-ref/ wuc_wu32: wu32 { wucs = <&wuc3 BIT(2)>; /* KSI[2] */ }; - wuc_wu33: wu33 { + /omit-if-no-ref/ wuc_wu33: wu33 { wucs = <&wuc3 BIT(3)>; /* KSI[3] */ }; - wuc_wu34: wu34 { + /omit-if-no-ref/ wuc_wu34: wu34 { wucs = <&wuc3 BIT(4)>; /* KSI[4] */ }; - wuc_wu35: wu35 { + /omit-if-no-ref/ wuc_wu35: wu35 { wucs = <&wuc3 BIT(5)>; /* KSI[5] */ }; - wuc_wu36: wu36 { + /omit-if-no-ref/ wuc_wu36: wu36 { wucs = <&wuc3 BIT(6)>; /* KSI[6] */ }; - wuc_wu37: wu37 { + /omit-if-no-ref/ wuc_wu37: wu37 { wucs = <&wuc3 BIT(7)>; /* KSI[7] */ }; /* WUC group 4 */ - wuc_wu40: wu40 { + /omit-if-no-ref/ wuc_wu40: wu40 { wucs = <&wuc4 BIT(0)>; /* GPE5 */ }; - wuc_wu42: wu42 { + /omit-if-no-ref/ wuc_wu42: wu42 { wucs = <&wuc4 BIT(2)>; /* eSPI transaction */ }; - wuc_wu45: wu45 { + /omit-if-no-ref/ wuc_wu45: wu45 { wucs = <&wuc4 BIT(5)>; /* GPE6 */ }; - wuc_wu46: wu46 { + /omit-if-no-ref/ wuc_wu46: wu46 { wucs = <&wuc4 BIT(6)>; /* GPE7 */ }; /* WUC group 5 */ - wuc_wu50: wu50 { + /omit-if-no-ref/ wuc_wu50: wu50 { wucs = <&wuc5 BIT(0)>; /* GPK0 */ }; - wuc_wu51: wu51 { + /omit-if-no-ref/ wuc_wu51: wu51 { wucs = <&wuc5 BIT(1)>; /* GPK1 */ }; - wuc_wu52: wu52 { + /omit-if-no-ref/ wuc_wu52: wu52 { wucs = <&wuc5 BIT(2)>; /* GPK2 */ }; - wuc_wu53: wu53 { + /omit-if-no-ref/ wuc_wu53: wu53 { wucs = <&wuc5 BIT(3)>; /* GPK3 */ }; - wuc_wu54: wu54 { + /omit-if-no-ref/ wuc_wu54: wu54 { wucs = <&wuc5 BIT(4)>; /* GPK4 */ }; - wuc_wu55: wu55 { + /omit-if-no-ref/ wuc_wu55: wu55 { wucs = <&wuc5 BIT(5)>; /* GPK5 */ }; - wuc_wu56: wu56 { + /omit-if-no-ref/ wuc_wu56: wu56 { wucs = <&wuc5 BIT(6)>; /* GPK6 */ }; - wuc_wu57: wu57 { + /omit-if-no-ref/ wuc_wu57: wu57 { wucs = <&wuc5 BIT(7)>; /* GPK7 */ }; /* WUC group 6 */ - wuc_wu60: wu60 { + /omit-if-no-ref/ wuc_wu60: wu60 { wucs = <&wuc6 BIT(0)>; /* GPH0 */ }; - wuc_wu61: wu61 { + /omit-if-no-ref/ wuc_wu61: wu61 { wucs = <&wuc6 BIT(1)>; /* GPH1 */ }; - wuc_wu62: wu62 { + /omit-if-no-ref/ wuc_wu62: wu62 { wucs = <&wuc6 BIT(2)>; /* GPH2 */ }; - wuc_wu63: wu63 { + /omit-if-no-ref/ wuc_wu63: wu63 { wucs = <&wuc6 BIT(3)>; /* GPH3 */ }; - wuc_wu64: wu64 { + /omit-if-no-ref/ wuc_wu64: wu64 { wucs = <&wuc6 BIT(4)>; /* GPF4 */ }; - wuc_wu65: wu65 { + /omit-if-no-ref/ wuc_wu65: wu65 { wucs = <&wuc6 BIT(5)>; /* GPF5 */ }; - wuc_wu66: wu66 { + /omit-if-no-ref/ wuc_wu66: wu66 { wucs = <&wuc6 BIT(6)>; /* GPF6 */ }; - wuc_wu67: wu67 { + /omit-if-no-ref/ wuc_wu67: wu67 { wucs = <&wuc6 BIT(7)>; /* GPF7 */ }; /* WUC group 7 */ - wuc_wu70: wu70 { + /omit-if-no-ref/ wuc_wu70: wu70 { wucs = <&wuc7 BIT(0)>; /* GPE0 */ }; - wuc_wu71: wu71 { + /omit-if-no-ref/ wuc_wu71: wu71 { wucs = <&wuc7 BIT(1)>; /* GPE1 */ }; - wuc_wu72: wu72 { + /omit-if-no-ref/ wuc_wu72: wu72 { wucs = <&wuc7 BIT(2)>; /* GPE2 */ }; - wuc_wu73: wu73 { + /omit-if-no-ref/ wuc_wu73: wu73 { wucs = <&wuc7 BIT(3)>; /* GPE3 */ }; - wuc_wu74: wu74 { + /omit-if-no-ref/ wuc_wu74: wu74 { wucs = <&wuc7 BIT(4)>; /* GPI4 */ }; - wuc_wu75: wu75 { + /omit-if-no-ref/ wuc_wu75: wu75 { wucs = <&wuc7 BIT(5)>; /* GPI5 */ }; - wuc_wu76: wu76 { + /omit-if-no-ref/ wuc_wu76: wu76 { wucs = <&wuc7 BIT(6)>; /* GPI6 */ }; - wuc_wu77: wu77 { + /omit-if-no-ref/ wuc_wu77: wu77 { wucs = <&wuc7 BIT(7)>; /* GPI7 */ }; /* WUC group 8 */ - wuc_wu80: wu80 { + /omit-if-no-ref/ wuc_wu80: wu80 { wucs = <&wuc8 BIT(0)>; /* GPA3 */ }; - wuc_wu81: wu81 { + /omit-if-no-ref/ wuc_wu81: wu81 { wucs = <&wuc8 BIT(1)>; /* GPA4 */ }; - wuc_wu82: wu82 { + /omit-if-no-ref/ wuc_wu82: wu82 { wucs = <&wuc8 BIT(2)>; /* GPA5 */ }; - wuc_wu83: wu83 { + /omit-if-no-ref/ wuc_wu83: wu83 { wucs = <&wuc8 BIT(3)>; /* GPA6 */ }; - wuc_wu84: wu84 { + /omit-if-no-ref/ wuc_wu84: wu84 { wucs = <&wuc8 BIT(4)>; /* GPB2 */ }; - wuc_wu85: wu85 { + /omit-if-no-ref/ wuc_wu85: wu85 { wucs = <&wuc8 BIT(5)>; /* GPC0 */ }; - wuc_wu86: wu86 { + /omit-if-no-ref/ wuc_wu86: wu86 { wucs = <&wuc8 BIT(6)>; /* GPC7 */ }; - wuc_wu87: wu87 { + /omit-if-no-ref/ wuc_wu87: wu87 { wucs = <&wuc8 BIT(7)>; /* GPD7 */ }; /* WUC group 9 */ - wuc_wu88: wu88 { + /omit-if-no-ref/ wuc_wu88: wu88 { wucs = <&wuc9 BIT(0)>; /* GPH4 */ }; - wuc_wu89: wu89 { + /omit-if-no-ref/ wuc_wu89: wu89 { wucs = <&wuc9 BIT(1)>; /* GPH5 */ }; - wuc_wu90: wu90 { + /omit-if-no-ref/ wuc_wu90: wu90 { wucs = <&wuc9 BIT(2)>; /* GPH6 */ }; - wuc_wu91: wu91 { + /omit-if-no-ref/ wuc_wu91: wu91 { wucs = <&wuc9 BIT(3)>; /* GPA0 */ }; - wuc_wu92: wu92 { + /omit-if-no-ref/ wuc_wu92: wu92 { wucs = <&wuc9 BIT(4)>; /* GPA1 */ }; - wuc_wu93: wu93 { + /omit-if-no-ref/ wuc_wu93: wu93 { wucs = <&wuc9 BIT(5)>; /* GPA2 */ }; - wuc_wu94: wu94 { + /omit-if-no-ref/ wuc_wu94: wu94 { wucs = <&wuc9 BIT(6)>; /* GPB4 */ }; - wuc_wu95: wu95 { + /omit-if-no-ref/ wuc_wu95: wu95 { wucs = <&wuc9 BIT(7)>; /* GPC2 */ }; /* WUC group 10 */ - wuc_wu96: wu96 { + /omit-if-no-ref/ wuc_wu96: wu96 { wucs = <&wuc10 BIT(0)>; /* GPF0 */ }; - wuc_wu97: wu97 { + /omit-if-no-ref/ wuc_wu97: wu97 { wucs = <&wuc10 BIT(1)>; /* GPF1 */ }; - wuc_wu98: wu98 { + /omit-if-no-ref/ wuc_wu98: wu98 { wucs = <&wuc10 BIT(2)>; /* GPF2 */ }; - wuc_wu99: wu99 { + /omit-if-no-ref/ wuc_wu99: wu99 { wucs = <&wuc10 BIT(3)>; /* GPF3 */ }; - wuc_wu100: wu100 { + /omit-if-no-ref/ wuc_wu100: wu100 { wucs = <&wuc10 BIT(4)>; /* GPA7 */ }; - wuc_wu101: wu101 { + /omit-if-no-ref/ wuc_wu101: wu101 { wucs = <&wuc10 BIT(5)>; /* GPB0 */ }; - wuc_wu102: wu102 { + /omit-if-no-ref/ wuc_wu102: wu102 { wucs = <&wuc10 BIT(6)>; /* GPB1 */ }; - wuc_wu103: wu103 { + /omit-if-no-ref/ wuc_wu103: wu103 { wucs = <&wuc10 BIT(7)>; /* GPB3 */ }; /* WUC group 11 */ - wuc_wu104: wu104 { + /omit-if-no-ref/ wuc_wu104: wu104 { wucs = <&wuc11 BIT(0)>; /* GPB5 */ }; - wuc_wu105: wu105 { + /omit-if-no-ref/ wuc_wu105: wu105 { wucs = <&wuc11 BIT(1)>; /* GPB6 */ }; - wuc_wu106: wu106 { + /omit-if-no-ref/ wuc_wu106: wu106 { wucs = <&wuc11 BIT(2)>; /* GPB7 */ }; - wuc_wu107: wu107 { + /omit-if-no-ref/ wuc_wu107: wu107 { wucs = <&wuc11 BIT(3)>; /* GPC1 */ }; - wuc_wu108: wu108 { + /omit-if-no-ref/ wuc_wu108: wu108 { wucs = <&wuc11 BIT(4)>; /* GPC3 */ }; - wuc_wu109: wu109 { + /omit-if-no-ref/ wuc_wu109: wu109 { wucs = <&wuc11 BIT(5)>; /* GPC5 */ }; - wuc_wu110: wu110 { + /omit-if-no-ref/ wuc_wu110: wu110 { wucs = <&wuc11 BIT(6)>; /* GPD3 */ }; - wuc_wu111: wu111 { + /omit-if-no-ref/ wuc_wu111: wu111 { wucs = <&wuc11 BIT(7)>; /* GPD4 */ }; /* WUC group 12 */ - wuc_wu112: wu112 { + /omit-if-no-ref/ wuc_wu112: wu112 { wucs = <&wuc12 BIT(0)>; /* GPD5 */ }; - wuc_wu113: wu113 { + /omit-if-no-ref/ wuc_wu113: wu113 { wucs = <&wuc12 BIT(1)>; /* GPD6 */ }; - wuc_wu114: wu114 { + /omit-if-no-ref/ wuc_wu114: wu114 { wucs = <&wuc12 BIT(2)>; /* GPE4 */ }; - wuc_wu115: wu115 { + /omit-if-no-ref/ wuc_wu115: wu115 { wucs = <&wuc12 BIT(3)>; /* GPG0 */ }; - wuc_wu116: wu116 { + /omit-if-no-ref/ wuc_wu116: wu116 { wucs = <&wuc12 BIT(4)>; /* GPG1 */ }; - wuc_wu117: wu117 { + /omit-if-no-ref/ wuc_wu117: wu117 { wucs = <&wuc12 BIT(5)>; /* GPG2 */ }; - wuc_wu118: wu118 { + /omit-if-no-ref/ wuc_wu118: wu118 { wucs = <&wuc12 BIT(6)>; /* GPG6 */ }; - wuc_wu119: wu119 { + /omit-if-no-ref/ wuc_wu119: wu119 { wucs = <&wuc12 BIT(7)>; /* GPI0 */ }; /* WUC group 13 */ - wuc_wu120: wu120 { + /omit-if-no-ref/ wuc_wu120: wu120 { wucs = <&wuc13 BIT(0)>; /* GPI1 */ }; - wuc_wu121: wu121 { + /omit-if-no-ref/ wuc_wu121: wu121 { wucs = <&wuc13 BIT(1)>; /* GPI2 */ }; - wuc_wu122: wu122 { + /omit-if-no-ref/ wuc_wu122: wu122 { wucs = <&wuc13 BIT(2)>; /* GPI3 */ }; - wuc_wu123: wu123 { + /omit-if-no-ref/ wuc_wu123: wu123 { wucs = <&wuc13 BIT(3)>; /* GPG3 */ }; - wuc_wu124: wu124 { + /omit-if-no-ref/ wuc_wu124: wu124 { wucs = <&wuc13 BIT(4)>; /* GPG4 */ }; - wuc_wu125: wu125 { + /omit-if-no-ref/ wuc_wu125: wu125 { wucs = <&wuc13 BIT(5)>; /* GPG5 */ }; - wuc_wu126: wu126 { + /omit-if-no-ref/ wuc_wu126: wu126 { wucs = <&wuc13 BIT(6)>; /* GPG7 */ }; /* WUC group 14 */ - wuc_wu128: wu128 { + /omit-if-no-ref/ wuc_wu128: wu128 { wucs = <&wuc14 BIT(0)>; /* GPJ0 */ }; - wuc_wu129: wu129 { + /omit-if-no-ref/ wuc_wu129: wu129 { wucs = <&wuc14 BIT(1)>; /* GPJ1 */ }; - wuc_wu130: wu130 { + /omit-if-no-ref/ wuc_wu130: wu130 { wucs = <&wuc14 BIT(2)>; /* GPJ2 */ }; - wuc_wu131: wu131 { + /omit-if-no-ref/ wuc_wu131: wu131 { wucs = <&wuc14 BIT(3)>; /* GPJ3 */ }; - wuc_wu132: wu132 { + /omit-if-no-ref/ wuc_wu132: wu132 { wucs = <&wuc14 BIT(4)>; /* GPJ4 */ }; - wuc_wu133: wu133 { + /omit-if-no-ref/ wuc_wu133: wu133 { wucs = <&wuc14 BIT(5)>; /* GPJ5 */ }; - wuc_wu134: wu134 { + /omit-if-no-ref/ wuc_wu134: wu134 { wucs = <&wuc14 BIT(6)>; /* GPJ6 */ }; - wuc_wu135: wu135 { + /omit-if-no-ref/ wuc_wu135: wu135 { wucs = <&wuc14 BIT(7)>; /* GPJ7 */ }; /* WUC group 15 */ - wuc_wu136: wu136 { + /omit-if-no-ref/ wuc_wu136: wu136 { wucs = <&wuc15 BIT(0)>; /* GPIO L0 */ }; - wuc_wu137: wu137 { + /omit-if-no-ref/ wuc_wu137: wu137 { wucs = <&wuc15 BIT(1)>; /* GPIO L1 */ }; - wuc_wu138: wu138 { + /omit-if-no-ref/ wuc_wu138: wu138 { wucs = <&wuc15 BIT(2)>; /* GPIO L2 */ }; - wuc_wu139: wu139 { + /omit-if-no-ref/ wuc_wu139: wu139 { wucs = <&wuc15 BIT(3)>; /* GPIO L3 */ }; - wuc_wu140: wu140 { + /omit-if-no-ref/ wuc_wu140: wu140 { wucs = <&wuc15 BIT(4)>; /* GPIO L4 */ }; - wuc_wu141: wu141 { + /omit-if-no-ref/ wuc_wu141: wu141 { wucs = <&wuc15 BIT(5)>; /* GPIO L5 */ }; - wuc_wu142: wu142 { + /omit-if-no-ref/ wuc_wu142: wu142 { wucs = <&wuc15 BIT(6)>; /* GPIO L6 */ }; - wuc_wu143: wu143 { + /omit-if-no-ref/ wuc_wu143: wu143 { wucs = <&wuc15 BIT(7)>; /* GPIO L7 */ }; /* WUC group 16 */ - wuc_wu144: wu144 { + /omit-if-no-ref/ wuc_wu144: wu144 { wucs = <&wuc16 BIT(0)>; /* GPM0 */ }; - wuc_wu145: wu145 { + /omit-if-no-ref/ wuc_wu145: wu145 { wucs = <&wuc16 BIT(1)>; /* GPM1 */ }; - wuc_wu146: wu146 { + /omit-if-no-ref/ wuc_wu146: wu146 { wucs = <&wuc16 BIT(2)>; /* GPM2 */ }; - wuc_wu147: wu147 { + /omit-if-no-ref/ wuc_wu147: wu147 { wucs = <&wuc16 BIT(3)>; /* GPM3 */ }; - wuc_wu148: wu148 { + /omit-if-no-ref/ wuc_wu148: wu148 { wucs = <&wuc16 BIT(4)>; /* GPM4 */ }; - wuc_wu149: wu149 { + /omit-if-no-ref/ wuc_wu149: wu149 { wucs = <&wuc16 BIT(5)>; /* GPM5 */ }; - wuc_wu150: wu150 { + /omit-if-no-ref/ wuc_wu150: wu150 { wucs = <&wuc16 BIT(6)>; /* GPM6 */ }; }; From 72a1c9e43e5294a4476094ff92280ac5c6cc9e51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Thu, 22 Jan 2026 15:07:05 +0100 Subject: [PATCH 2537/3659] doc: _scripts: gen_devicetree_rest: ensure blank lines around transition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Transition markers ("----") require blank lines before and after, so this ensures that is always the case. Signed-off-by: Benjamin Cabé --- doc/_scripts/gen_devicetree_rest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/_scripts/gen_devicetree_rest.py b/doc/_scripts/gen_devicetree_rest.py index f66114583d62..55fd7c48dbfd 100644 --- a/doc/_scripts/gen_devicetree_rest.py +++ b/doc/_scripts/gen_devicetree_rest.py @@ -604,7 +604,7 @@ def print_binding_page(binding, base_names, vnd_lookup, driver_sources,dup_compa ''', string_io) blocks = [to_code_block(example, language='dts') for example in binding.examples] - print("\n----\n".join(blocks), file=string_io) + print("\n\n----\n\n".join(blocks), file=string_io) # Properties. print_block('''\ From 42754f8f8dca7a646719e4d04481ada87416c9ed Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Tue, 9 Dec 2025 16:31:09 +0100 Subject: [PATCH 2538/3659] net: sockets: tls: Separate TLS session context from socket context Separate TLS session context from the TLS socket context so that a single DTLS server socket can support multiple client sessions. Other socket types will only have a single session per TLS socket. Signed-off-by: Robert Lubos --- subsys/net/lib/sockets/Kconfig | 11 + subsys/net/lib/sockets/sockets_tls.c | 330 +++++++++++++++++---------- 2 files changed, 216 insertions(+), 125 deletions(-) diff --git a/subsys/net/lib/sockets/Kconfig b/subsys/net/lib/sockets/Kconfig index 8d25302bef27..b0150531db07 100644 --- a/subsys/net/lib/sockets/Kconfig +++ b/subsys/net/lib/sockets/Kconfig @@ -237,6 +237,17 @@ config ZVFS_OPEN_ADD_SIZE_TLS default NET_SOCKETS_TLS_MAX_CONTEXTS if NET_SOCKETS_SOCKOPT_TLS default 0 +config NET_SOCKETS_TLS_MAX_SESSION_CONTEXTS + int "Maximum number of TLS/DTLS sessions" + default NET_SOCKETS_TLS_MAX_CONTEXTS + depends on NET_SOCKETS_SOCKOPT_TLS + help + This variable specifies the maximum number of TLS/DTLS sessions that + can be established at the same time. Typically one session is needed + for a TLS context. DTLS server sockets may use more sessions per socket + to support communication with multiple clients at the same time. + The value should not be lower than NET_SOCKETS_TLS_MAX_CONTEXTS. + config NET_SOCKETS_TLS_MAX_CREDENTIALS int "Maximum number of TLS/DTLS credentials per socket" default 4 diff --git a/subsys/net/lib/sockets/sockets_tls.c b/subsys/net/lib/sockets/sockets_tls.c index 04a599e5af72..252ab85d6431 100644 --- a/subsys/net/lib/sockets/sockets_tls.c +++ b/subsys/net/lib/sockets/sockets_tls.c @@ -122,6 +122,38 @@ struct tls_dtls_cid { }; #endif +struct tls_session_context { + sys_snode_t node; + + /* Handshake completion time. */ + int64_t handshake_timestamp; + + /* Information whether TLS handshake is currently in progress. */ + bool handshake_in_progress : 1; + + /* Session ended at the TLS/DTLS level. */ + bool session_closed : 1; + + /* Information whether TLS handshake is complete or not. */ + struct k_sem tls_established; + +#if defined(CONFIG_MBEDTLS) + /* mbedTLS context. */ + mbedtls_ssl_context ssl; +#endif /* CONFIG_MBEDTLS */ + +#if defined(CONFIG_NET_SOCKETS_ENABLE_DTLS) + /* Context information for DTLS timing. */ + struct dtls_timing_context dtls_timing; + + /* DTLS peer address. */ + struct net_sockaddr dtls_peer_addr; + + /* DTLS peer address length. */ + net_socklen_t dtls_peer_addrlen; +#endif /* CONFIG_NET_SOCKETS_ENABLE_DTLS */ +}; + /** TLS context information. */ __net_socket struct tls_context { /** Underlying TCP/UDP socket. */ @@ -136,11 +168,16 @@ __net_socket struct tls_context { /** Information whether underlying socket is listening. */ bool is_listening : 1; - /** Information whether TLS handshake is currently in progress. */ - bool handshake_in_progress : 1; + /* TLS sessions associated with this socket. In most cases there will + * be one session allocated per TLS context. DTLS server is an exception, + * which can have multiple TLS sessions allocated at the same time. + */ + sys_slist_t sessions; - /** Session ended at the TLS/DTLS level. */ - bool session_closed : 1; + /* Currently active TLS session. For a TLS context in use, this should + * always point to a valid session instance. + */ + struct tls_session_context *active_session; /** Socket type. */ enum net_sock_type type; @@ -154,9 +191,6 @@ __net_socket struct tls_context { /* Indicates whether socket is in error state at TLS/DTLS level. */ int error; - /** Information whether TLS handshake is complete or not. */ - struct k_sem tls_established; - /* TLS socket mutex lock. */ struct k_mutex *lock; @@ -213,23 +247,11 @@ __net_socket struct tls_context { } options; #if defined(CONFIG_NET_SOCKETS_ENABLE_DTLS) - /** Context information for DTLS timing. */ - struct dtls_timing_context dtls_timing; - /** mbedTLS cookie context for DTLS */ mbedtls_ssl_cookie_ctx cookie; - - /** DTLS peer address. */ - struct net_sockaddr dtls_peer_addr; - - /** DTLS peer address length. */ - net_socklen_t dtls_peer_addrlen; #endif /* CONFIG_NET_SOCKETS_ENABLE_DTLS */ #if defined(CONFIG_MBEDTLS) - /** mbedTLS context. */ - mbedtls_ssl_context ssl; - /** mbedTLS configuration. */ mbedtls_ssl_config config; @@ -243,13 +265,19 @@ __net_socket struct tls_context { /** mbedTLS structure for own private key. */ mbedtls_pk_context priv_key; #endif /* MBEDTLS_X509_CRT_PARSE_C */ - #endif /* CONFIG_MBEDTLS */ }; /* A global pool of TLS contexts. */ static struct tls_context tls_contexts[CONFIG_NET_SOCKETS_TLS_MAX_CONTEXTS]; +K_MEM_SLAB_DEFINE_STATIC(tls_session_contexts, sizeof(struct tls_session_context), + CONFIG_NET_SOCKETS_TLS_MAX_SESSION_CONTEXTS, + __alignof__(struct tls_session_context)); + +BUILD_ASSERT(CONFIG_NET_SOCKETS_TLS_MAX_SESSION_CONTEXTS >= CONFIG_NET_SOCKETS_TLS_MAX_CONTEXTS, + "CONFIG_NET_SOCKETS_TLS_MAX_SESSION_CONTEXTS cannot be smaller than " + "CONFIG_NET_SOCKETS_TLS_MAX_CONTEXTS"); static struct tls_session_cache client_cache[CONFIG_NET_SOCKETS_TLS_MAX_CLIENT_SESSION_COUNT]; @@ -339,9 +367,9 @@ static int dtls_timing_get_delay(void *data) return 0; } -static int dtls_get_remaining_timeout(struct tls_context *ctx) +static int dtls_get_remaining_timeout(struct tls_session_context *session_ctx) { - struct dtls_timing_context *timing = &ctx->dtls_timing; + struct dtls_timing_context *timing = &session_ctx->dtls_timing; uint32_t elapsed_ms; elapsed_ms = k_uptime_get_32() - timing->snapshot; @@ -381,9 +409,9 @@ static int tls_init(void) SYS_INIT(tls_init, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); -static inline bool is_handshake_complete(struct tls_context *ctx) +static inline bool is_handshake_complete(struct tls_session_context *session_ctx) { - return k_sem_count_get(&ctx->tls_established) != 0; + return k_sem_count_get(&session_ctx->tls_established) != 0; } /* @@ -439,6 +467,29 @@ static inline void tls_set_max_frag_len(mbedtls_ssl_config *config, enum net_soc static inline void tls_set_max_frag_len(mbedtls_ssl_config *config, enum net_sock_type type) {} #endif +static struct tls_session_context *tls_session_alloc(void) +{ + struct tls_session_context *session_ctx = NULL; + + if (k_mem_slab_alloc(&tls_session_contexts, (void **)&session_ctx, + K_NO_WAIT) != 0) { + NET_WARN("Failed to allocate TLS session context"); + return NULL; + } + + (void)memset(session_ctx, 0, sizeof(*session_ctx)); + (void)k_sem_init(&session_ctx->tls_established, 0, 1); + mbedtls_ssl_init(&session_ctx->ssl); + + return session_ctx; +} + +static void tls_session_free(struct tls_session_context *session_ctx) +{ + mbedtls_ssl_free(&session_ctx->ssl); + k_mem_slab_free(&tls_session_contexts, (void *)session_ctx); +} + /* Allocate TLS context. */ static struct tls_context *tls_alloc(void) { @@ -450,13 +501,25 @@ static struct tls_context *tls_alloc(void) for (i = 0; i < ARRAY_SIZE(tls_contexts); i++) { if (!tls_contexts[i].is_used) { tls = &tls_contexts[i]; + (void)memset(tls, 0, sizeof(*tls)); + + /* Allocate initial (and in most cases the only) session context */ + tls->active_session = tls_session_alloc(); + if (tls->active_session == NULL) { + tls = NULL; + break; + } + tls->is_used = true; tls->options.verify_level = -1; tls->options.timeout_tx = K_FOREVER; tls->options.timeout_rx = K_FOREVER; tls->sock = -1; + sys_slist_init(&tls->sessions); + sys_slist_append(&tls->sessions, &tls->active_session->node); + NET_DBG("Allocated TLS context, %p", tls); break; } @@ -465,9 +528,6 @@ static struct tls_context *tls_alloc(void) k_mutex_unlock(&context_lock); if (tls) { - k_sem_init(&tls->tls_established, 0, 1); - - mbedtls_ssl_init(&tls->ssl); mbedtls_ssl_config_init(&tls->config); #if defined(CONFIG_NET_SOCKETS_ENABLE_DTLS) mbedtls_ssl_cookie_init(&tls->cookie); @@ -513,8 +573,8 @@ static struct tls_context *tls_clone(struct tls_context *source_tls) #if defined(MBEDTLS_X509_CRT_PARSE_C) if (target_tls->options.is_hostname_set) { - mbedtls_ssl_set_hostname(&target_tls->ssl, - source_tls->ssl.hostname); + mbedtls_ssl_set_hostname(&target_tls->active_session->ssl, + source_tls->active_session->ssl.hostname); } #endif @@ -524,6 +584,8 @@ static struct tls_context *tls_clone(struct tls_context *source_tls) /* Release TLS context. */ static int tls_release(struct tls_context *tls) { + sys_snode_t *node; + if (!PART_OF_ARRAY(tls_contexts, tls)) { NET_ERR("Invalid TLS context"); return -EBADF; @@ -538,13 +600,19 @@ static int tls_release(struct tls_context *tls) mbedtls_ssl_cookie_free(&tls->cookie); #endif mbedtls_ssl_config_free(&tls->config); - mbedtls_ssl_free(&tls->ssl); #if defined(MBEDTLS_X509_CRT_PARSE_C) mbedtls_x509_crt_free(&tls->ca_chain); mbedtls_x509_crt_free(&tls->own_cert); mbedtls_pk_free(&tls->priv_key); #endif + while ((node = sys_slist_get(&tls->sessions)) != NULL) { + struct tls_session_context *session_ctx = + SYS_SLIST_CONTAINER(node, session_ctx, node); + + tls_session_free(session_ctx); + } + tls->is_used = false; return 0; @@ -680,7 +748,7 @@ static void tls_session_store(struct tls_context *context, memcpy(&peer_addr, addr, addrlen); mbedtls_ssl_session_init(&session); - ret = mbedtls_ssl_get_session(&context->ssl, &session); + ret = mbedtls_ssl_get_session(&context->active_session->ssl, &session); if (ret < 0) { NET_ERR("Failed to obtain session for %p", context); goto exit; @@ -716,7 +784,7 @@ static void tls_session_restore(struct tls_context *context, goto exit; } - ret = mbedtls_ssl_set_session(&context->ssl, &session); + ret = mbedtls_ssl_set_session(&context->active_session->ssl, &session); if (ret < 0) { NET_ERR("Failed to set session for %p", context); } @@ -822,34 +890,34 @@ static void ctx_set_lock(struct tls_context *ctx, struct k_mutex *lock) } #if defined(CONFIG_NET_SOCKETS_ENABLE_DTLS) -static bool dtls_is_peer_addr_valid(struct tls_context *context, +static bool dtls_is_peer_addr_valid(struct tls_session_context *session_ctx, const struct net_sockaddr *peer_addr, net_socklen_t addrlen) { - if (context->dtls_peer_addrlen != addrlen) { + if (session_ctx->dtls_peer_addrlen != addrlen) { return false; } - return peer_addr_cmp(&context->dtls_peer_addr, peer_addr); + return peer_addr_cmp(&session_ctx->dtls_peer_addr, peer_addr); } -static void dtls_peer_address_set(struct tls_context *context, +static void dtls_peer_address_set(struct tls_session_context *session_ctx, const struct net_sockaddr *peer_addr, net_socklen_t addrlen) { - if (addrlen <= sizeof(context->dtls_peer_addr)) { - memcpy(&context->dtls_peer_addr, peer_addr, addrlen); - context->dtls_peer_addrlen = addrlen; + if (addrlen <= sizeof(session_ctx->dtls_peer_addr)) { + memcpy(&session_ctx->dtls_peer_addr, peer_addr, addrlen); + session_ctx->dtls_peer_addrlen = addrlen; } } -static void dtls_peer_address_get(struct tls_context *context, +static void dtls_peer_address_get(struct tls_session_context *session_ctx, struct net_sockaddr *peer_addr, net_socklen_t *addrlen) { - net_socklen_t len = MIN(context->dtls_peer_addrlen, *addrlen); + net_socklen_t len = MIN(session_ctx->dtls_peer_addrlen, *addrlen); - memcpy(peer_addr, &context->dtls_peer_addr, len); + memcpy(peer_addr, &session_ctx->dtls_peer_addr, len); *addrlen = len; } @@ -859,8 +927,8 @@ static int dtls_tx(void *ctx, const unsigned char *buf, size_t len) ssize_t sent; sent = zsock_sendto(tls_ctx->sock, buf, len, ZSOCK_MSG_DONTWAIT, - &tls_ctx->dtls_peer_addr, - tls_ctx->dtls_peer_addrlen); + &tls_ctx->active_session->dtls_peer_addr, + tls_ctx->active_session->dtls_peer_addrlen); if (sent < 0) { if (errno == EAGAIN) { return MBEDTLS_ERR_SSL_WANT_WRITE; @@ -890,13 +958,13 @@ static int dtls_rx(void *ctx, unsigned char *buf, size_t len) return MBEDTLS_ERR_NET_RECV_FAILED; } - if (tls_ctx->dtls_peer_addrlen == 0) { + if (tls_ctx->active_session->dtls_peer_addrlen == 0) { /* Only allow to store peer address for DTLS servers. */ if (tls_ctx->options.role == MBEDTLS_SSL_IS_SERVER) { - dtls_peer_address_set(tls_ctx, &addr, addrlen); + dtls_peer_address_set(tls_ctx->active_session, &addr, addrlen); err = mbedtls_ssl_set_client_transport_id( - &tls_ctx->ssl, + &tls_ctx->active_session->ssl, (const unsigned char *)&addr, addrlen); if (err < 0) { return err; @@ -907,7 +975,7 @@ static int dtls_rx(void *ctx, unsigned char *buf, size_t len) */ return MBEDTLS_ERR_SSL_PEER_VERIFY_FAILED; } - } else if (!dtls_is_peer_addr_valid(tls_ctx, &addr, addrlen)) { + } else if (!dtls_is_peer_addr_valid(tls_ctx->active_session, &addr, addrlen)) { return MBEDTLS_ERR_SSL_WANT_READ; } @@ -1162,16 +1230,18 @@ static int tls_mbedtls_set_credentials(struct tls_context *tls) return err; } -static int tls_mbedtls_reset(struct tls_context *context) +static int tls_mbedtls_reset_session(struct tls_context *context) { int ret; - ret = mbedtls_ssl_session_reset(&context->ssl); + ret = mbedtls_ssl_session_reset(&context->active_session->ssl); if (ret != 0) { return ret; } - k_sem_reset(&context->tls_established); + context->active_session->handshake_timestamp = 0; + + k_sem_reset(&context->active_session->tls_established); #if defined(CONFIG_NET_SOCKETS_ENABLE_DTLS) /* Server role: reset the address so that a new @@ -1180,9 +1250,9 @@ static int tls_mbedtls_reset(struct tls_context *context) * even on handshake timeout */ if (context->options.role == MBEDTLS_SSL_IS_SERVER) { - (void)memset(&context->dtls_peer_addr, 0, - sizeof(context->dtls_peer_addr)); - context->dtls_peer_addrlen = 0; + (void)memset(&context->active_session->dtls_peer_addr, 0, + sizeof(context->active_session->dtls_peer_addr)); + context->active_session->dtls_peer_addrlen = 0; } #endif @@ -1195,11 +1265,11 @@ static int tls_mbedtls_handshake(struct tls_context *context, k_timepoint_t end; int ret; - context->handshake_in_progress = true; + context->active_session->handshake_in_progress = true; end = sys_timepoint_calc(timeout); - while ((ret = mbedtls_ssl_handshake(&context->ssl)) != 0) { + while ((ret = mbedtls_ssl_handshake(&context->active_session->ssl)) != 0) { if (ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE || ret == MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS || @@ -1219,7 +1289,7 @@ static int tls_mbedtls_handshake(struct tls_context *context, #if defined(CONFIG_NET_SOCKETS_ENABLE_DTLS) if (context->type == NET_SOCK_DGRAM) { int timeout_dtls = - dtls_get_remaining_timeout(context); + dtls_get_remaining_timeout(context->active_session); if (timeout_dtls != SYS_FOREVER_MS) { if (timeout_ms == SYS_FOREVER_MS) { @@ -1239,7 +1309,7 @@ static int tls_mbedtls_handshake(struct tls_context *context, continue; } else if (ret == MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED) { - ret = tls_mbedtls_reset(context); + ret = tls_mbedtls_reset_session(context); if (ret == 0) { if (!K_TIMEOUT_EQ(timeout, K_NO_WAIT)) { continue; @@ -1252,7 +1322,7 @@ static int tls_mbedtls_handshake(struct tls_context *context, /* MbedTLS API documentation requires session to * be reset in this case */ - ret = tls_mbedtls_reset(context); + ret = tls_mbedtls_reset_session(context); if (ret == 0) { NET_ERR("TLS handshake timeout"); context->error = ETIMEDOUT; @@ -1264,7 +1334,7 @@ static int tls_mbedtls_handshake(struct tls_context *context, * be reset in other error cases */ NET_ERR("TLS handshake error: -0x%x", -ret); - ret = tls_mbedtls_reset(context); + ret = tls_mbedtls_reset_session(context); if (ret == 0) { context->error = ECONNABORTED; ret = -ECONNABORTED; @@ -1272,7 +1342,7 @@ static int tls_mbedtls_handshake(struct tls_context *context, } } - /* Avoid constant loop if tls_mbedtls_reset fails */ + /* Avoid constant loop if tls_mbedtls_reset_session fails */ NET_ERR("TLS reset error: -0x%x", -ret); context->error = ECONNABORTED; ret = -ECONNABORTED; @@ -1280,10 +1350,11 @@ static int tls_mbedtls_handshake(struct tls_context *context, } if (ret == 0) { - k_sem_give(&context->tls_established); + context->active_session->handshake_timestamp = k_uptime_get(); + k_sem_give(&context->active_session->tls_established); } - context->handshake_in_progress = false; + context->active_session->handshake_in_progress = false; return ret; } @@ -1299,11 +1370,11 @@ static int tls_mbedtls_init(struct tls_context *context, bool is_server) MBEDTLS_SSL_TRANSPORT_DATAGRAM; if (type == MBEDTLS_SSL_TRANSPORT_STREAM) { - mbedtls_ssl_set_bio(&context->ssl, context, + mbedtls_ssl_set_bio(&context->active_session->ssl, context, tls_tx, tls_rx, NULL); } else { #if defined(CONFIG_NET_SOCKETS_ENABLE_DTLS) - mbedtls_ssl_set_bio(&context->ssl, context, + mbedtls_ssl_set_bio(&context->active_session->ssl, context, dtls_tx, dtls_rx, NULL); #else return -ENOTSUP; @@ -1349,8 +1420,8 @@ static int tls_mbedtls_init(struct tls_context *context, bool is_server) #if defined(CONFIG_NET_SOCKETS_ENABLE_DTLS) if (type == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { /* DTLS requires timer callbacks to operate */ - mbedtls_ssl_set_timer_cb(&context->ssl, - &context->dtls_timing, + mbedtls_ssl_set_timer_cb(&context->active_session->ssl, + &context->active_session->dtls_timing, dtls_timing_set_delay, dtls_timing_get_delay); mbedtls_ssl_conf_handshake_timeout(&context->config, @@ -1396,7 +1467,7 @@ static int tls_mbedtls_init(struct tls_context *context, bool is_server) * depend on user configuration. */ if (!is_server && !context->options.is_hostname_set) { - mbedtls_ssl_set_hostname(&context->ssl, ""); + mbedtls_ssl_set_hostname(&context->active_session->ssl, ""); } #endif @@ -1454,7 +1525,7 @@ static int tls_mbedtls_init(struct tls_context *context, bool is_server) } #endif /* CONFIG_NET_SOCKETS_TLS_CERT_VERIFY_CALLBACK */ - ret = mbedtls_ssl_setup(&context->ssl, + ret = mbedtls_ssl_setup(&context->active_session->ssl, &context->config); if (ret != 0) { /* According to mbedTLS API documentation, @@ -1466,7 +1537,8 @@ static int tls_mbedtls_init(struct tls_context *context, bool is_server) #if defined(CONFIG_NET_SOCKETS_ENABLE_DTLS) && defined(CONFIG_MBEDTLS_SSL_DTLS_CONNECTION_ID) if (type == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { if (context->options.dtls_cid.enabled) { - ret = mbedtls_ssl_set_cid(&context->ssl, MBEDTLS_SSL_CID_ENABLED, + ret = mbedtls_ssl_set_cid(&context->active_session->ssl, + MBEDTLS_SSL_CID_ENABLED, context->options.dtls_cid.cid, context->options.dtls_cid.cid_len); if (ret != 0) { @@ -1700,7 +1772,7 @@ static int tls_opt_hostname_set(struct tls_context *context, ARG_UNUSED(optlen); #if defined(MBEDTLS_X509_CRT_PARSE_C) - if (mbedtls_ssl_set_hostname(&context->ssl, optval) != 0) { + if (mbedtls_ssl_set_hostname(&context->active_session->ssl, optval) != 0) { return -EINVAL; } #else @@ -1781,7 +1853,8 @@ static int tls_opt_ciphersuite_used_get(struct tls_context *context, return -EINVAL; } - ciph = mbedtls_ssl_get_ciphersuite(&context->ssl); + + ciph = mbedtls_ssl_get_ciphersuite(&context->active_session->ssl); if (ciph == NULL) { return -ENOTCONN; } @@ -1975,7 +2048,8 @@ static int tls_opt_dtls_peer_connection_id_value_get(struct tls_context *context return -ENOTCONN; } - ret = mbedtls_ssl_get_peer_cid(&context->ssl, &enabled, optval, &optlen_local); + ret = mbedtls_ssl_get_peer_cid(&context->active_session->ssl, &enabled, + optval, &optlen_local); if (enabled) { *optlen = optlen_local; } else { @@ -2006,7 +2080,7 @@ static int tls_opt_dtls_connection_id_status_get(struct tls_context *context, return -ENOTCONN; } - ret = mbedtls_ssl_get_peer_cid(&context->ssl, &enabled, + ret = mbedtls_ssl_get_peer_cid(&context->active_session->ssl, &enabled, cid.cid, &cid.cid_len); if (ret) { @@ -2140,7 +2214,7 @@ static int tls_opt_cert_verify_result_get(struct tls_context *context, return -EINVAL; } - *(uint32_t *)optval = mbedtls_ssl_get_verify_result(&context->ssl); + *(uint32_t *)optval = mbedtls_ssl_get_verify_result(&context->active_session->ssl); return 0; } @@ -2351,7 +2425,7 @@ int ztls_close_ctx(struct tls_context *ctx, int sock) /* Try to send close notification. */ ctx->flags = 0; - (void)mbedtls_ssl_close_notify(&ctx->ssl); + (void)mbedtls_ssl_close_notify(&ctx->active_session->ssl); err = tls_release(ctx); ret = zsock_close(ctx->sock); @@ -2401,7 +2475,7 @@ int ztls_connect_ctx(struct tls_context *ctx, const struct net_sockaddr *addr, #if defined(CONFIG_NET_SOCKETS_ENABLE_DTLS) if (ctx->type == NET_SOCK_DGRAM) { - dtls_peer_address_set(ctx, addr, addrlen); + dtls_peer_address_set(ctx->active_session, addr, addrlen); } #endif @@ -2527,7 +2601,7 @@ static ssize_t send_tls(struct tls_context *ctx, const void *buf, return -1; } - if (ctx->session_closed) { + if (ctx->active_session->session_closed) { errno = ECONNABORTED; return -1; } @@ -2541,7 +2615,7 @@ static ssize_t send_tls(struct tls_context *ctx, const void *buf, end = sys_timepoint_calc(timeout); do { - ret = mbedtls_ssl_write(&ctx->ssl, buf, len); + ret = mbedtls_ssl_write(&ctx->active_session->ssl, buf, len); if (ret >= 0) { return ret; } @@ -2577,7 +2651,7 @@ static ssize_t send_tls(struct tls_context *ctx, const void *buf, /* MbedTLS API documentation requires session to * be reset in other error cases */ - ret = tls_mbedtls_reset(ctx); + ret = tls_mbedtls_reset_session(ctx); if (ret != 0) { ctx->error = ENOMEM; errno = ENOMEM; @@ -2605,14 +2679,14 @@ static ssize_t sendto_dtls_client(struct tls_context *ctx, const void *buf, /* No address provided, check if we have stored one, * otherwise return error. */ - if (ctx->dtls_peer_addrlen == 0) { + if (ctx->active_session->dtls_peer_addrlen == 0) { ret = -EDESTADDRREQ; goto error; } - } else if (ctx->dtls_peer_addrlen == 0) { + } else if (ctx->active_session->dtls_peer_addrlen == 0) { /* Address provided and no peer address stored. */ - dtls_peer_address_set(ctx, dest_addr, addrlen); - } else if (!dtls_is_peer_addr_valid(ctx, dest_addr, addrlen) != 0) { + dtls_peer_address_set(ctx->active_session, dest_addr, addrlen); + } else if (!dtls_is_peer_addr_valid(ctx->active_session, dest_addr, addrlen) != 0) { /* Address provided but it does not match stored one */ ret = -EISCONN; goto error; @@ -2625,9 +2699,9 @@ static ssize_t sendto_dtls_client(struct tls_context *ctx, const void *buf, } } - if (!is_handshake_complete(ctx)) { - tls_session_restore(ctx, &ctx->dtls_peer_addr, - ctx->dtls_peer_addrlen); + if (!is_handshake_complete(ctx->active_session)) { + tls_session_restore(ctx, &ctx->active_session->dtls_peer_addr, + ctx->active_session->dtls_peer_addrlen); /* TODO For simplicity, TLS handshake blocks the socket even for * non-blocking socket. @@ -2643,8 +2717,8 @@ static ssize_t sendto_dtls_client(struct tls_context *ctx, const void *buf, /* Client socket ready to use again. */ ctx->error = 0; - tls_session_store(ctx, &ctx->dtls_peer_addr, - ctx->dtls_peer_addrlen); + tls_session_store(ctx, &ctx->active_session->dtls_peer_addr, + ctx->active_session->dtls_peer_addrlen); } return send_tls(ctx, buf, len, flags); @@ -2662,14 +2736,14 @@ static ssize_t sendto_dtls_server(struct tls_context *ctx, const void *buf, /* For DTLS server, require to have established DTLS connection * in order to send data. */ - if (!is_handshake_complete(ctx)) { + if (!is_handshake_complete(ctx->active_session)) { errno = ENOTCONN; return -1; } /* Verify we are sending to a peer that we have connection with. */ if (dest_addr && - !dtls_is_peer_addr_valid(ctx, dest_addr, addrlen) != 0) { + !dtls_is_peer_addr_valid(ctx->active_session, dest_addr, addrlen) != 0) { errno = EISCONN; return -1; } @@ -2821,7 +2895,7 @@ static ssize_t recv_tls(struct tls_context *ctx, void *buf, return -1; } - if (ctx->session_closed) { + if (ctx->active_session->session_closed) { return 0; } @@ -2836,14 +2910,14 @@ static ssize_t recv_tls(struct tls_context *ctx, void *buf, do { size_t read_len = max_len - recv_len; - ret = mbedtls_ssl_read(&ctx->ssl, (uint8_t *)buf + recv_len, + ret = mbedtls_ssl_read(&ctx->active_session->ssl, (uint8_t *)buf + recv_len, read_len); if (ret < 0) { if (ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) { /* Peer notified that it's closing the * connection. */ - ctx->session_closed = true; + ctx->active_session->session_closed = true; break; } @@ -2852,7 +2926,7 @@ static ssize_t recv_tls(struct tls_context *ctx, void *buf, * supported. See mbedtls_ssl_read API * documentation. */ - ctx->session_closed = true; + ctx->active_session->session_closed = true; break; } @@ -2933,7 +3007,7 @@ static ssize_t recvfrom_dtls_common(struct tls_context *ctx, void *buf, do { size_t remaining; - ret = mbedtls_ssl_read(&ctx->ssl, buf, max_len); + ret = mbedtls_ssl_read(&ctx->active_session->ssl, buf, max_len); if (ret < 0) { if (ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE || @@ -2951,7 +3025,7 @@ static ssize_t recvfrom_dtls_common(struct tls_context *ctx, void *buf, return ret; } - timeout_dtls = dtls_get_remaining_timeout(ctx); + timeout_dtls = dtls_get_remaining_timeout(ctx->active_session); timeout_sock = timeout_to_ms(&timeout); if (timeout_dtls == SYS_FOREVER_MS || timeout_sock == SYS_FOREVER_MS) { @@ -2977,13 +3051,13 @@ static ssize_t recvfrom_dtls_common(struct tls_context *ctx, void *buf, } if (src_addr && addrlen) { - dtls_peer_address_get(ctx, src_addr, addrlen); + dtls_peer_address_get(ctx->active_session, src_addr, addrlen); } /* mbedtls_ssl_get_bytes_avail() indicate the data length * remaining in the current datagram. */ - remaining = mbedtls_ssl_get_bytes_avail(&ctx->ssl); + remaining = mbedtls_ssl_get_bytes_avail(&ctx->active_session->ssl); /* No more data in the datagram, or dummy read. */ if ((remaining == 0) || (max_len == 0)) { @@ -2998,7 +3072,7 @@ static ssize_t recvfrom_dtls_common(struct tls_context *ctx, void *buf, uint8_t byte; int err; - err = mbedtls_ssl_read(&ctx->ssl, &byte, sizeof(byte)); + err = mbedtls_ssl_read(&ctx->active_session->ssl, &byte, sizeof(byte)); if (err <= 0) { NET_ERR("Error while flushing the rest of the" " datagram, err %d", err); @@ -3021,7 +3095,7 @@ static ssize_t recvfrom_dtls_client(struct tls_context *ctx, void *buf, { int ret; - if (!is_handshake_complete(ctx)) { + if (!is_handshake_complete(ctx->active_session)) { ret = -ENOTCONN; goto error; } @@ -3034,7 +3108,7 @@ static ssize_t recvfrom_dtls_client(struct tls_context *ctx, void *buf, switch (ret) { case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY: /* Peer notified that it's closing the connection. */ - ret = tls_mbedtls_reset(ctx); + ret = tls_mbedtls_reset_session(ctx); if (ret == 0) { ctx->error = ENOTCONN; ret = -ENOTCONN; @@ -3045,7 +3119,7 @@ static ssize_t recvfrom_dtls_client(struct tls_context *ctx, void *buf, break; case MBEDTLS_ERR_SSL_TIMEOUT: - (void)mbedtls_ssl_close_notify(&ctx->ssl); + (void)mbedtls_ssl_close_notify(&ctx->active_session->ssl); ctx->error = ETIMEDOUT; ret = -ETIMEDOUT; break; @@ -3063,7 +3137,7 @@ static ssize_t recvfrom_dtls_client(struct tls_context *ctx, void *buf, /* MbedTLS API documentation requires session to * be reset in other error cases */ - ret = tls_mbedtls_reset(ctx); + ret = tls_mbedtls_reset_session(ctx); if (ret != 0) { ctx->error = ENOMEM; errno = ENOMEM; @@ -3108,7 +3182,7 @@ static ssize_t recvfrom_dtls_server(struct tls_context *ctx, void *buf, do { repeat = false; - if (!is_handshake_complete(ctx)) { + if (!is_handshake_complete(ctx->active_session)) { ret = tls_mbedtls_handshake(ctx, timeout); if (ret < 0) { /* In case of EAGAIN, just exit. */ @@ -3116,7 +3190,7 @@ static ssize_t recvfrom_dtls_server(struct tls_context *ctx, void *buf, break; } - ret = tls_mbedtls_reset(ctx); + ret = tls_mbedtls_reset_session(ctx); if (ret == 0) { repeat = true; } else { @@ -3138,13 +3212,13 @@ static ssize_t recvfrom_dtls_server(struct tls_context *ctx, void *buf, switch (ret) { case MBEDTLS_ERR_SSL_TIMEOUT: - (void)mbedtls_ssl_close_notify(&ctx->ssl); + (void)mbedtls_ssl_close_notify(&ctx->active_session->ssl); __fallthrough; /* fallthrough */ case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY: case MBEDTLS_ERR_SSL_CLIENT_RECONNECT: - ret = tls_mbedtls_reset(ctx); + ret = tls_mbedtls_reset_session(ctx); if (ret == 0) { repeat = true; } else { @@ -3163,7 +3237,7 @@ static ssize_t recvfrom_dtls_server(struct tls_context *ctx, void *buf, default: NET_ERR("DTLS server recv error: -%x", -ret); - ret = tls_mbedtls_reset(ctx); + ret = tls_mbedtls_reset_session(ctx); if (ret != 0) { ctx->error = ENOMEM; errno = ENOMEM; @@ -3223,7 +3297,7 @@ static int ztls_poll_prepare_pollin(struct tls_context *ctx) * so we won't block in the k_poll. */ if (!ctx->is_listening) { - if (mbedtls_ssl_get_bytes_avail(&ctx->ssl) > 0) { + if (mbedtls_ssl_get_bytes_avail(&ctx->active_session->ssl) > 0) { return -EALREADY; } } @@ -3247,8 +3321,8 @@ static int ztls_poll_prepare_ctx(struct tls_context *ctx, */ if ((pfd->events & ZSOCK_POLLIN) && (ctx->type == NET_SOCK_DGRAM) && (ctx->options.role == MBEDTLS_SSL_IS_CLIENT) && - !is_handshake_complete(ctx)) { - (*pev)->obj = &ctx->tls_established; + !is_handshake_complete(ctx->active_session)) { + (*pev)->obj = &ctx->active_session->tls_established; (*pev)->type = K_POLL_TYPE_SEM_AVAILABLE; (*pev)->mode = K_POLL_MODE_NOTIFY_ONLY; (*pev)->state = K_POLL_STATE_NOT_READY; @@ -3310,14 +3384,14 @@ static int ztls_socket_data_check(struct tls_context *ctx) } } - if (!is_handshake_complete(ctx)) { + if (!is_handshake_complete(ctx->active_session)) { ret = tls_mbedtls_handshake(ctx, K_NO_WAIT); if (ret < 0) { if (ret == -EAGAIN) { return 0; } - ret = tls_mbedtls_reset(ctx); + ret = tls_mbedtls_reset_session(ctx); if (ret != 0) { return -ENOMEM; } @@ -3335,7 +3409,7 @@ static int ztls_socket_data_check(struct tls_context *ctx) ctx->flags = ZSOCK_MSG_DONTWAIT; - ret = mbedtls_ssl_read(&ctx->ssl, NULL, 0); + ret = mbedtls_ssl_read(&ctx->active_session->ssl, NULL, 0); if (ret < 0) { if (ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) { /* Don't reset the context for STREAM socket - the @@ -3344,12 +3418,12 @@ static int ztls_socket_data_check(struct tls_context *ctx) * of 0 in a consecutive recv() call. */ if (ctx->type == NET_SOCK_DGRAM) { - ret = tls_mbedtls_reset(ctx); + ret = tls_mbedtls_reset_session(ctx); if (ret != 0) { return -ENOMEM; } } else { - ctx->session_closed = true; + ctx->active_session->session_closed = true; } return -ENOTCONN; @@ -3365,7 +3439,7 @@ static int ztls_socket_data_check(struct tls_context *ctx) /* MbedTLS API documentation requires session to * be reset in other error cases */ - if (tls_mbedtls_reset(ctx) != 0) { + if (tls_mbedtls_reset_session(ctx) != 0) { return -ENOMEM; } @@ -3378,7 +3452,7 @@ static int ztls_socket_data_check(struct tls_context *ctx) return -ECONNABORTED; } - return mbedtls_ssl_get_bytes_avail(&ctx->ssl); + return mbedtls_ssl_get_bytes_avail(&ctx->active_session->ssl); } static int ztls_poll_update_pollin(int fd, struct tls_context *ctx, @@ -3388,7 +3462,7 @@ static int ztls_poll_update_pollin(int fd, struct tls_context *ctx, if (!ctx->is_listening) { /* Already had TLS data to read on socket. */ - if (mbedtls_ssl_get_bytes_avail(&ctx->ssl) > 0) { + if (mbedtls_ssl_get_bytes_avail(&ctx->active_session->ssl) > 0) { pfd->revents |= ZSOCK_POLLIN; goto next; } @@ -3409,7 +3483,7 @@ static int ztls_poll_update_pollin(int fd, struct tls_context *ctx, /* Perform data check without incoming data for completed DTLS connections. * This allows the connections to timeout with CONFIG_NET_SOCKETS_DTLS_TIMEOUT. */ - if (!is_handshake_complete(ctx) && !(pfd->revents & ZSOCK_POLLIN)) { + if (!is_handshake_complete(ctx->active_session) && !(pfd->revents & ZSOCK_POLLIN)) { goto next; } } @@ -3465,7 +3539,7 @@ static int ztls_poll_update_ctx(struct tls_context *ctx, /* Check if the socket was waiting for the handshake to complete. */ if ((pfd->events & ZSOCK_POLLIN) && - ((*pev)->obj == &ctx->tls_established)) { + ((*pev)->obj == &ctx->active_session->tls_established)) { /* In case handshake is complete, reconfigure the k_poll_event * to monitor the underlying socket now. */ @@ -3529,7 +3603,7 @@ static bool poll_offload_dtls_client_retry(struct tls_context *ctx, return false; } - if (ctx->handshake_in_progress) { + if (ctx->active_session->handshake_in_progress) { /* Add some sleep to allow lower priority threads to proceed * with handshake. */ @@ -3537,7 +3611,7 @@ static bool poll_offload_dtls_client_retry(struct tls_context *ctx, pfd->revents &= ~ZSOCK_POLLIN; return true; - } else if (!is_handshake_complete(ctx)) { + } else if (!is_handshake_complete(ctx->active_session)) { uint8_t byte; int ret; @@ -3919,8 +3993,14 @@ mbedtls_ssl_context *ztls_get_mbedtls_ssl_context(int fd) return NULL; } - return &ctx->ssl; + return &ctx->active_session->ssl; } + +uint32_t ztls_get_session_count(void) +{ + return k_mem_slab_num_used_get(&tls_session_contexts); +} + #endif /* CONFIG_NET_TEST */ static ssize_t tls_sock_read_vmeth(void *obj, void *buffer, size_t count) From 779bfe2e5eee762416d3dbdf50422937ff44375e Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Tue, 9 Dec 2025 16:31:11 +0100 Subject: [PATCH 2539/3659] net: sockets: tls: Split TLS session and context initialization It has to be possible to initialize TLS sessions separately of the TLS socket context. Signed-off-by: Robert Lubos --- subsys/net/lib/sockets/sockets_tls.c | 104 +++++++++++++++------------ 1 file changed, 58 insertions(+), 46 deletions(-) diff --git a/subsys/net/lib/sockets/sockets_tls.c b/subsys/net/lib/sockets/sockets_tls.c index 252ab85d6431..a3d21301645d 100644 --- a/subsys/net/lib/sockets/sockets_tls.c +++ b/subsys/net/lib/sockets/sockets_tls.c @@ -1359,28 +1359,73 @@ static int tls_mbedtls_handshake(struct tls_context *context, return ret; } -static int tls_mbedtls_init(struct tls_context *context, bool is_server) +static int tls_mbedtls_session_init(struct tls_session_context *session_ctx, + struct tls_context *tls_ctx, bool is_server) { - int role, type, ret; + int ret; - role = is_server ? MBEDTLS_SSL_IS_SERVER : MBEDTLS_SSL_IS_CLIENT; +#if defined(MBEDTLS_X509_CRT_PARSE_C) + /* For TLS clients, set hostname to empty string to enforce it's + * verification - only if hostname option was not set. Otherwise + * depend on user configuration. + */ + if (!is_server && !tls_ctx->options.is_hostname_set) { + ret = mbedtls_ssl_set_hostname(&session_ctx->ssl, ""); + if (ret != 0) { + return -ENOMEM; + } + } +#endif - type = (context->type == NET_SOCK_STREAM) ? - MBEDTLS_SSL_TRANSPORT_STREAM : - MBEDTLS_SSL_TRANSPORT_DATAGRAM; + ret = mbedtls_ssl_setup(&session_ctx->ssl, &tls_ctx->config); + if (ret != 0) { + /* According to mbedTLS API documentation, + * mbedtls_ssl_setup can fail due to memory allocation failure + */ + return -ENOMEM; + } - if (type == MBEDTLS_SSL_TRANSPORT_STREAM) { - mbedtls_ssl_set_bio(&context->active_session->ssl, context, + if (tls_ctx->type == NET_SOCK_STREAM) { + mbedtls_ssl_set_bio(&session_ctx->ssl, tls_ctx, tls_tx, tls_rx, NULL); } else { #if defined(CONFIG_NET_SOCKETS_ENABLE_DTLS) - mbedtls_ssl_set_bio(&context->active_session->ssl, context, + mbedtls_ssl_set_bio(&session_ctx->ssl, tls_ctx, dtls_tx, dtls_rx, NULL); -#else + + /* DTLS requires timer callbacks to operate */ + mbedtls_ssl_set_timer_cb(&session_ctx->ssl, + &session_ctx->dtls_timing, + dtls_timing_set_delay, + dtls_timing_get_delay); +#if defined(CONFIG_MBEDTLS_SSL_DTLS_CONNECTION_ID) + if (tls_ctx->options.dtls_cid.enabled) { + ret = mbedtls_ssl_set_cid(&session_ctx->ssl, MBEDTLS_SSL_CID_ENABLED, + tls_ctx->options.dtls_cid.cid, + tls_ctx->options.dtls_cid.cid_len); + if (ret != 0) { + return -EINVAL; + } + } +#endif /* CONFIG_MBEDTLS_SSL_DTLS_CONNECTION_ID */ +#else /* CONFIG_NET_SOCKETS_ENABLE_DTLS */ return -ENOTSUP; #endif /* CONFIG_NET_SOCKETS_ENABLE_DTLS */ } + return 0; +} + +static int tls_mbedtls_init(struct tls_context *context, bool is_server) +{ + int role, type, ret; + + role = is_server ? MBEDTLS_SSL_IS_SERVER : MBEDTLS_SSL_IS_CLIENT; + + type = (context->type == NET_SOCK_STREAM) ? + MBEDTLS_SSL_TRANSPORT_STREAM : + MBEDTLS_SSL_TRANSPORT_DATAGRAM; + ret = mbedtls_ssl_config_defaults(&context->config, role, type, MBEDTLS_SSL_PRESET_DEFAULT); if (ret != 0) { @@ -1419,11 +1464,6 @@ static int tls_mbedtls_init(struct tls_context *context, bool is_server) #if defined(CONFIG_NET_SOCKETS_ENABLE_DTLS) if (type == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { - /* DTLS requires timer callbacks to operate */ - mbedtls_ssl_set_timer_cb(&context->active_session->ssl, - &context->active_session->dtls_timing, - dtls_timing_set_delay, - dtls_timing_get_delay); mbedtls_ssl_conf_handshake_timeout(&context->config, context->options.dtls_handshake_timeout_min, context->options.dtls_handshake_timeout_max); @@ -1461,16 +1501,6 @@ static int tls_mbedtls_init(struct tls_context *context, bool is_server) } #endif /* CONFIG_NET_SOCKETS_ENABLE_DTLS */ -#if defined(MBEDTLS_X509_CRT_PARSE_C) - /* For TLS clients, set hostname to empty string to enforce it's - * verification - only if hostname option was not set. Otherwise - * depend on user configuration. - */ - if (!is_server && !context->options.is_hostname_set) { - mbedtls_ssl_set_hostname(&context->active_session->ssl, ""); - } -#endif - /* If verification level was specified explicitly, set it. Otherwise, * use mbedTLS default values (required for client, none for server) */ @@ -1525,28 +1555,10 @@ static int tls_mbedtls_init(struct tls_context *context, bool is_server) } #endif /* CONFIG_NET_SOCKETS_TLS_CERT_VERIFY_CALLBACK */ - ret = mbedtls_ssl_setup(&context->active_session->ssl, - &context->config); - if (ret != 0) { - /* According to mbedTLS API documentation, - * mbedtls_ssl_setup can fail due to memory allocation failure - */ - return -ENOMEM; - } - -#if defined(CONFIG_NET_SOCKETS_ENABLE_DTLS) && defined(CONFIG_MBEDTLS_SSL_DTLS_CONNECTION_ID) - if (type == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { - if (context->options.dtls_cid.enabled) { - ret = mbedtls_ssl_set_cid(&context->active_session->ssl, - MBEDTLS_SSL_CID_ENABLED, - context->options.dtls_cid.cid, - context->options.dtls_cid.cid_len); - if (ret != 0) { - return -EINVAL; - } - } + ret = tls_mbedtls_session_init(context->active_session, context, is_server); + if (ret < 0) { + return ret; } -#endif /* CONFIG_NET_SOCKETS_ENABLE_DTLS && CONFIG_MBEDTLS_SSL_DTLS_CONNECTION_ID */ context->is_initialized = true; From 9e544a9ec753047eed7b44167c442f6a97ff1a38 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Tue, 9 Dec 2025 16:31:11 +0100 Subject: [PATCH 2540/3659] net: sockets: tls: Split DTLS BIO functions Split DTLS BIO RX functions for client and server case, given the functionality will differ heavily. DTLS server needs to peek packet before passing it to mbed TLS to allow to switch DTLS sessions in case peer address doesn't match. Signed-off-by: Robert Lubos --- subsys/net/lib/sockets/sockets_tls.c | 86 +++++++++++++++++++++------- 1 file changed, 66 insertions(+), 20 deletions(-) diff --git a/subsys/net/lib/sockets/sockets_tls.c b/subsys/net/lib/sockets/sockets_tls.c index a3d21301645d..f3aa1d0e75cf 100644 --- a/subsys/net/lib/sockets/sockets_tls.c +++ b/subsys/net/lib/sockets/sockets_tls.c @@ -50,6 +50,7 @@ LOG_MODULE_REGISTER(net_sock_tls, CONFIG_NET_SOCKETS_LOG_LEVEL); #include "sockets_internal.h" #include "tls_internal.h" +#include "../../ip/net_private.h" #if defined(CONFIG_MBEDTLS_DEBUG) #include @@ -940,13 +941,66 @@ static int dtls_tx(void *ctx, const unsigned char *buf, size_t len) return sent; } -static int dtls_rx(void *ctx, unsigned char *buf, size_t len) +static int dtls_server_rx(void *ctx, unsigned char *buf, size_t len) { struct tls_context *tls_ctx = ctx; net_socklen_t addrlen = sizeof(struct net_sockaddr); struct net_sockaddr addr; int err; ssize_t received; + uint8_t tmp_buf; + + /* Peek the packet first to check the peer address. */ + received = zsock_recvfrom(tls_ctx->sock, &tmp_buf, sizeof(tmp_buf), + ZSOCK_MSG_DONTWAIT | ZSOCK_MSG_PEEK, + &addr, &addrlen); + if (received < 0) { + if (errno == EAGAIN) { + return MBEDTLS_ERR_SSL_WANT_READ; + } + + NET_ERR("DTLS server RX: failure %d", errno); + return MBEDTLS_ERR_NET_RECV_FAILED; + } + + /* Check if the peer address matches the current session. */ + if (tls_ctx->active_session->dtls_peer_addrlen != 0 && + !dtls_is_peer_addr_valid(tls_ctx->active_session, &addr, addrlen)) { + /* Peer address does not match the current session, exit now + * and try to find the appropriate session or allocate a new one. + */ + return MBEDTLS_ERR_SSL_WANT_READ; + } + + /* If the session matches, read the actual packet. */ + received = zsock_recvfrom(tls_ctx->sock, buf, len, + ZSOCK_MSG_DONTWAIT, &addr, &addrlen); + if (received < 0) { + NET_ERR("DTLS server RX: failure %d", errno); + return MBEDTLS_ERR_NET_RECV_FAILED; + } + + /* Only allow to store peer address for DTLS servers. */ + if (tls_ctx->active_session->dtls_peer_addrlen == 0) { + dtls_peer_address_set(tls_ctx->active_session, &addr, addrlen); + + err = mbedtls_ssl_set_client_transport_id(&tls_ctx->active_session->ssl, + (const unsigned char *)&addr, + addrlen); + if (err < 0) { + return err; + } + } + + return received; +} + +static int dtls_client_rx(void *ctx, unsigned char *buf, size_t len) +{ + struct tls_context *tls_ctx = ctx; + net_socklen_t addrlen = sizeof(struct net_sockaddr); + struct net_sockaddr addr; + ssize_t received; received = zsock_recvfrom(tls_ctx->sock, buf, len, ZSOCK_MSG_DONTWAIT, &addr, &addrlen); @@ -959,23 +1013,14 @@ static int dtls_rx(void *ctx, unsigned char *buf, size_t len) } if (tls_ctx->active_session->dtls_peer_addrlen == 0) { - /* Only allow to store peer address for DTLS servers. */ - if (tls_ctx->options.role == MBEDTLS_SSL_IS_SERVER) { - dtls_peer_address_set(tls_ctx->active_session, &addr, addrlen); - - err = mbedtls_ssl_set_client_transport_id( - &tls_ctx->active_session->ssl, - (const unsigned char *)&addr, addrlen); - if (err < 0) { - return err; - } - } else { - /* For clients it's incorrect to receive when - * no peer has been set up. - */ - return MBEDTLS_ERR_SSL_PEER_VERIFY_FAILED; - } - } else if (!dtls_is_peer_addr_valid(tls_ctx->active_session, &addr, addrlen)) { + /* For clients it's incorrect to receive when + * no peer has been set up. + */ + return MBEDTLS_ERR_SSL_PEER_VERIFY_FAILED; + } + + if (!dtls_is_peer_addr_valid(tls_ctx->active_session, &addr, addrlen)) { + /* Received packet from a different peer, drop and retry. */ return MBEDTLS_ERR_SSL_WANT_READ; } @@ -1390,8 +1435,9 @@ static int tls_mbedtls_session_init(struct tls_session_context *session_ctx, tls_tx, tls_rx, NULL); } else { #if defined(CONFIG_NET_SOCKETS_ENABLE_DTLS) - mbedtls_ssl_set_bio(&session_ctx->ssl, tls_ctx, - dtls_tx, dtls_rx, NULL); + mbedtls_ssl_set_bio(&session_ctx->ssl, tls_ctx, dtls_tx, + is_server ? dtls_server_rx : dtls_client_rx, + NULL); /* DTLS requires timer callbacks to operate */ mbedtls_ssl_set_timer_cb(&session_ctx->ssl, From cc6248d87c00b0d4e238f7b33d3c45df51cea056 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Tue, 9 Dec 2025 16:31:12 +0100 Subject: [PATCH 2541/3659] net: sockets: tls: Refactor RX part for DTLS server Refactor RX side for DTLS server to allow session switching when a datagram from a peer that does not match current session. The server needs to loop over established sessions, and in case no session is found allocate a new one. Signed-off-by: Robert Lubos --- subsys/net/lib/sockets/sockets_tls.c | 404 ++++++++++++++++++++++----- 1 file changed, 336 insertions(+), 68 deletions(-) diff --git a/subsys/net/lib/sockets/sockets_tls.c b/subsys/net/lib/sockets/sockets_tls.c index f3aa1d0e75cf..372ebdec5b10 100644 --- a/subsys/net/lib/sockets/sockets_tls.c +++ b/subsys/net/lib/sockets/sockets_tls.c @@ -56,6 +56,14 @@ LOG_MODULE_REGISTER(net_sock_tls, CONFIG_NET_SOCKETS_LOG_LEVEL); #include #endif +#define LOG_ADDR_PORT_HELPER(addr) \ + (addr)->sa_family == NET_AF_INET ? \ + net_sprint_ipv4_addr(&net_sin(addr)->sin_addr) : \ + net_sprint_ipv6_addr(&net_sin6(addr)->sin6_addr), \ + (addr)->sa_family == NET_AF_INET ? \ + net_ntohs(net_sin(addr)->sin_port) : \ + net_ntohs(net_sin6(addr)->sin6_port) + #if defined(CONFIG_NET_SOCKETS_TLS_MAX_APP_PROTOCOLS) #define ALPN_MAX_PROTOCOLS (CONFIG_NET_SOCKETS_TLS_MAX_APP_PROTOCOLS + 1) #else @@ -1026,6 +1034,118 @@ static int dtls_client_rx(void *ctx, unsigned char *buf, size_t len) return received; } + +static int tls_mbedtls_session_init(struct tls_session_context *session_ctx, + struct tls_context *tls_ctx, bool is_server); + +/* Returns + * - 0 when session was switched, + * - 1 if session was already valid, + * - negative error code otherwise + */ +static int dtls_server_switch_active_session(struct tls_context *tls_ctx, + const struct net_sockaddr *addr, + net_socklen_t addrlen) +{ + struct tls_session_context *session_ctx = NULL; + + if (tls_ctx->active_session->dtls_peer_addrlen == 0 || + dtls_is_peer_addr_valid(tls_ctx->active_session, addr, addrlen)) { + return 1; + } + + NET_DBG("Need to swap session for [%s]:%d (current [%s]:%d)", + LOG_ADDR_PORT_HELPER(addr), + LOG_ADDR_PORT_HELPER(&tls_ctx->active_session->dtls_peer_addr)); + + SYS_SLIST_FOR_EACH_CONTAINER(&tls_ctx->sessions, session_ctx, node) { + if (dtls_is_peer_addr_valid(session_ctx, addr, addrlen)) { + NET_DBG("Found matching session (address)"); + tls_ctx->active_session = session_ctx; + return 0; + } + } + + return -ENOENT; +} + +static int dtls_server_new_active_session(struct tls_context *tls_ctx, + const struct net_sockaddr *addr, + net_socklen_t addrlen) +{ + struct tls_session_context *session_ctx = NULL; + int ret; + + session_ctx = tls_session_alloc(); + if (session_ctx == NULL) { + return -ENOMEM; + } + + ret = tls_mbedtls_session_init(session_ctx, tls_ctx, true); + if (ret < 0) { + tls_session_free(session_ctx); + return ret; + } + + dtls_peer_address_set(session_ctx, addr, addrlen); + + ret = mbedtls_ssl_set_client_transport_id(&session_ctx->ssl, + (const unsigned char *)addr, + addrlen); + if (ret < 0) { + tls_session_free(session_ctx); + return -ENOMEM; + } + +#if defined(MBEDTLS_X509_CRT_PARSE_C) + if (tls_ctx->options.is_hostname_set) { + mbedtls_ssl_set_hostname(&session_ctx->ssl, + tls_ctx->active_session->ssl.hostname); + } +#endif + + sys_slist_append(&tls_ctx->sessions, &session_ctx->node); + tls_ctx->active_session = session_ctx; + + return 0; +} + +static int dtls_server_switch_session_on_rx(struct tls_context *tls_ctx) +{ + net_socklen_t addrlen = sizeof(struct net_sockaddr); + struct net_sockaddr addr; + uint8_t tmp_buf; + int ret; + + /* Peek the datagram first to see if the session needs to be updated. */ + ret = zsock_recvfrom(tls_ctx->sock, &tmp_buf, sizeof(tmp_buf), + ZSOCK_MSG_DONTWAIT | ZSOCK_MSG_PEEK, + &addr, &addrlen); + if (ret < 0) { + return -errno; + } + + /* Try to match existing session by peer address. */ + ret = dtls_server_switch_active_session(tls_ctx, &addr, addrlen); + if (ret == 0 || ret == 1) { + return ret; + } + + /* No session found, try to allocate one. */ + + NET_DBG("No session found (RX), allocating new"); + + ret = dtls_server_new_active_session(tls_ctx, &addr, addrlen); + if (ret < 0) { + NET_ERR("Failed to allocate new session for DTLS server, " + "dropping packet (err: %d)", ret); + + (void)zsock_recv(tls_ctx->sock, &tmp_buf, sizeof(tmp_buf), + ZSOCK_MSG_DONTWAIT); + } + + return ret; +} #endif /* CONFIG_NET_SOCKETS_ENABLE_DTLS */ static int tls_tx(void *ctx, const unsigned char *buf, size_t len) @@ -1333,6 +1453,18 @@ static int tls_mbedtls_handshake(struct tls_context *context, #if defined(CONFIG_NET_SOCKETS_ENABLE_DTLS) if (context->type == NET_SOCK_DGRAM) { + if (context->options.role == MBEDTLS_SSL_IS_SERVER) { + /* DTLS server may need to switch session. */ + int err = dtls_server_switch_session_on_rx(context); + + if (err == 0) { + /* Switched the session, repeat the loop. */ + context->active_session->handshake_in_progress = + true; + continue; + } + } + int timeout_dtls = dtls_get_remaining_timeout(context->active_session); @@ -2478,12 +2610,15 @@ static int ztls_socket(int family, int type, int proto) int ztls_close_ctx(struct tls_context *ctx, int sock) { + struct tls_session_context *session_ctx = NULL; int ret, err = 0; /* Try to send close notification. */ ctx->flags = 0; - (void)mbedtls_ssl_close_notify(&ctx->active_session->ssl); + SYS_SLIST_FOR_EACH_CONTAINER(&ctx->sessions, session_ctx, node) { + (void)mbedtls_ssl_close_notify(&session_ctx->ssl); + } err = tls_release(ctx); ret = zsock_close(ctx->sock); @@ -3044,10 +3179,11 @@ static ssize_t recvfrom_dtls_common(struct tls_context *ctx, void *buf, struct net_sockaddr *src_addr, net_socklen_t *addrlen) { - int ret; + bool is_server = ctx->options.role == MBEDTLS_SSL_IS_SERVER; bool is_block = is_blocking(ctx->sock, flags); k_timeout_t timeout; k_timepoint_t end; + int ret; if (ctx->error != 0) { errno = ctx->error; @@ -3073,6 +3209,21 @@ static ssize_t recvfrom_dtls_common(struct tls_context *ctx, void *buf, ret == MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS) { int timeout_dtls, timeout_sock, timeout_ms; + if (is_server) { + int err = dtls_server_switch_session_on_rx(ctx); + + /* If session swapping is successful, return early so that + * recvfrom_dtls_server() can proceed with another + * handshake. Otherwise, there either really was no packet, + * or we've failed to allocate a new session, so the packet + * was dropped. In either case, just proceed as if there + * were no packet. + */ + if (err == 0) { + return ret; + } + } + if (!is_block) { return ret; } @@ -3238,13 +3389,25 @@ static ssize_t recvfrom_dtls_server(struct tls_context *ctx, void *buf, * a socket. */ do { + net_socklen_t peer_addrlen = sizeof(struct net_sockaddr); + struct net_sockaddr peer_addr; + repeat = false; if (!is_handshake_complete(ctx->active_session)) { ret = tls_mbedtls_handshake(ctx, timeout); if (ret < 0) { - /* In case of EAGAIN, just exit. */ + /* In case of EAGAIN, check if it's needed to swap sessions, + * otherwise just exit. + */ if (ret == -EAGAIN) { + int err = dtls_server_switch_session_on_rx(ctx); + + if (err == 0) { + /* Switched the session, repeat the loop. */ + continue; + } + break; } @@ -3262,6 +3425,9 @@ static ssize_t recvfrom_dtls_server(struct tls_context *ctx, void *buf, ctx->error = 0; } + /* Backup peer address (to verify later if it changed). */ + dtls_peer_address_get(ctx->active_session, &peer_addr, &peer_addrlen); + ret = recvfrom_dtls_common(ctx, buf, max_len, flags, src_addr, addrlen); if (ret >= 0) { @@ -3289,7 +3455,16 @@ static ssize_t recvfrom_dtls_server(struct tls_context *ctx, void *buf, case MBEDTLS_ERR_SSL_WANT_WRITE: case MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS: case MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS: - ret = -EAGAIN; + if (peer_addrlen > 0 && + !dtls_is_peer_addr_valid(ctx->active_session, &peer_addr, + peer_addrlen)) { + /* Current peer changed, repeat the loop. */ + repeat = true; + } else { + /* Otherwise, just return the error. */ + ret = -EAGAIN; + } + break; default: @@ -3422,48 +3597,137 @@ static int ztls_poll_prepare_ctx(struct tls_context *ctx, #include -static int ztls_socket_data_check(struct tls_context *ctx) +static int tls_data_check(struct tls_context *ctx) { int ret; - if (ctx->type == NET_SOCK_STREAM) { - if (!ctx->is_initialized) { + if (!ctx->is_initialized) { + return -ENOTCONN; + } + + ctx->flags = ZSOCK_MSG_DONTWAIT; + + ret = mbedtls_ssl_read(&ctx->active_session->ssl, NULL, 0); + if (ret < 0) { + if (ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) { + /* Don't reset the context for STREAM socket - the + * application needs to reopen the socket anyway, and + * resetting the context would result in an error instead + * of 0 in a consecutive recv() call. + */ + ctx->active_session->session_closed = true; + return -ENOTCONN; } + + if (ret == MBEDTLS_ERR_SSL_WANT_READ || + ret == MBEDTLS_ERR_SSL_WANT_WRITE) { + return 0; + } + + NET_ERR("%s data check error: -%x", "TLS", -ret); + + /* MbedTLS API documentation requires session to + * be reset in other error cases + */ + if (tls_mbedtls_reset_session(ctx) != 0) { + return -ENOMEM; + } + + return -ECONNABORTED; } -#if defined(CONFIG_NET_SOCKETS_ENABLE_DTLS) - else { - if (!ctx->is_initialized) { - bool is_server = ctx->options.role == MBEDTLS_SSL_IS_SERVER; - ret = tls_mbedtls_init(ctx, is_server); - if (ret < 0) { - return -ENOMEM; - } + return mbedtls_ssl_get_bytes_avail(&ctx->active_session->ssl); +} + +static int tls_update_pollin(int fd, struct tls_context *ctx, + struct zsock_pollfd *pfd) +{ + int ret; + + if (!ctx->is_listening) { + /* Already had TLS data to read on socket. */ + if (mbedtls_ssl_get_bytes_avail(&ctx->active_session->ssl) > 0) { + pfd->revents |= ZSOCK_POLLIN; + goto next; } + } - if (!is_handshake_complete(ctx->active_session)) { - ret = tls_mbedtls_handshake(ctx, K_NO_WAIT); - if (ret < 0) { - if (ret == -EAGAIN) { - return 0; - } + if ((pfd->revents & ZSOCK_POLLIN) == 0) { + /* No new data on a socket. */ + goto next; + } - ret = tls_mbedtls_reset_session(ctx); - if (ret != 0) { - return -ENOMEM; + if (ctx->is_listening) { + goto next; + } + + ret = tls_data_check(ctx); + if (ret == -ENOTCONN || (pfd->revents & ZSOCK_POLLHUP)) { + pfd->revents |= ZSOCK_POLLHUP; + goto next; + } else if (ret < 0) { + ctx->error = -ret; + pfd->revents |= ZSOCK_POLLERR; + goto next; + } else if (ret == 0) { + goto again; + } + +next: + return 0; + +again: + /* Received encrypted data, but still not enough + * to decrypt it and return data through socket, + * ask for retry if no other events are set. + */ + pfd->revents &= ~ZSOCK_POLLIN; + + return -EAGAIN; +} + +#if defined(CONFIG_NET_SOCKETS_ENABLE_DTLS) +static int dtls_data_check(struct tls_context *ctx) +{ + bool is_server = ctx->options.role == MBEDTLS_SSL_IS_SERVER; + int ret; + + if (!ctx->is_initialized) { + ret = tls_mbedtls_init(ctx, is_server); + if (ret < 0) { + return -ENOMEM; + } + } + +again: + if (!is_handshake_complete(ctx->active_session)) { + ret = tls_mbedtls_handshake(ctx, K_NO_WAIT); + if (ret < 0) { + if (ret == -EAGAIN) { + if (is_server) { + ret = dtls_server_switch_session_on_rx(ctx); + if (ret == 0) { + goto again; + } } return 0; } - /* Socket ready to use again. */ - ctx->error = 0; + ret = tls_mbedtls_reset_session(ctx); + if (ret != 0) { + return -ENOMEM; + } return 0; } + + /* Socket ready to use again. */ + ctx->error = 0; + + return 0; } -#endif /* CONFIG_NET_SOCKETS_ENABLE_DTLS */ ctx->flags = ZSOCK_MSG_DONTWAIT; @@ -3475,13 +3739,9 @@ static int ztls_socket_data_check(struct tls_context *ctx) * resetting the context would result in an error instead * of 0 in a consecutive recv() call. */ - if (ctx->type == NET_SOCK_DGRAM) { - ret = tls_mbedtls_reset_session(ctx); - if (ret != 0) { - return -ENOMEM; - } - } else { - ctx->active_session->session_closed = true; + ret = tls_mbedtls_reset_session(ctx); + if (ret != 0) { + return -ENOMEM; } return -ENOTCONN; @@ -3489,11 +3749,23 @@ static int ztls_socket_data_check(struct tls_context *ctx) if (ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE) { + if (is_server) { + ret = dtls_server_switch_session_on_rx(ctx); + if (ret == 0) { + goto again; + } + } + return 0; } NET_ERR("TLS data check error: -%x", -ret); + if (ret == MBEDTLS_ERR_SSL_TIMEOUT) { + /* Send close notification before session is released. */ + (void)mbedtls_ssl_close_notify(&ctx->active_session->ssl); + } + /* MbedTLS API documentation requires session to * be reset in other error cases */ @@ -3501,63 +3773,46 @@ static int ztls_socket_data_check(struct tls_context *ctx) return -ENOMEM; } -#if defined(CONFIG_NET_SOCKETS_ENABLE_DTLS) - if (ret == MBEDTLS_ERR_SSL_TIMEOUT && ctx->type == NET_SOCK_DGRAM) { + if (ret == MBEDTLS_ERR_SSL_TIMEOUT) { /* DTLS timeout interpreted as closing of connection. */ return -ENOTCONN; } -#endif + return -ECONNABORTED; } return mbedtls_ssl_get_bytes_avail(&ctx->active_session->ssl); } -static int ztls_poll_update_pollin(int fd, struct tls_context *ctx, - struct zsock_pollfd *pfd) +static int dtls_update_pollin(int fd, struct tls_context *ctx, + struct zsock_pollfd *pfd) { int ret; - if (!ctx->is_listening) { - /* Already had TLS data to read on socket. */ - if (mbedtls_ssl_get_bytes_avail(&ctx->active_session->ssl) > 0) { - pfd->revents |= ZSOCK_POLLIN; - goto next; - } + /* Already had DTLS data to read on socket. */ + if (mbedtls_ssl_get_bytes_avail(&ctx->active_session->ssl) > 0) { + pfd->revents |= ZSOCK_POLLIN; + goto next; } - if (ctx->type == NET_SOCK_STREAM) { - if (!(pfd->revents & ZSOCK_POLLIN)) { - /* No new data on a socket. */ - goto next; - } - - if (ctx->is_listening) { - goto next; - } - } -#if defined(CONFIG_NET_SOCKETS_ENABLE_DTLS) - else { - /* Perform data check without incoming data for completed DTLS connections. - * This allows the connections to timeout with CONFIG_NET_SOCKETS_DTLS_TIMEOUT. - */ - if (!is_handshake_complete(ctx->active_session) && !(pfd->revents & ZSOCK_POLLIN)) { - goto next; - } + /* Perform data check without incoming data for completed DTLS connections. + * This allows the connections to timeout with CONFIG_NET_SOCKETS_DTLS_TIMEOUT. + */ + if (!is_handshake_complete(ctx->active_session) && (pfd->revents & ZSOCK_POLLIN) == 0) { + goto next; } -#endif - ret = ztls_socket_data_check(ctx); + + ret = dtls_data_check(ctx); if (ret == -ENOTCONN || (pfd->revents & ZSOCK_POLLHUP)) { /* Datagram does not return 0 on consecutive recv, but an error * code, hence clear POLLIN. */ - if (ctx->type == NET_SOCK_DGRAM) { - pfd->revents &= ~ZSOCK_POLLIN; - } + pfd->revents &= ~ZSOCK_POLLIN; pfd->revents |= ZSOCK_POLLHUP; goto next; } else if (ret < 0) { ctx->error = -ret; + pfd->revents &= ~ZSOCK_POLLIN; pfd->revents |= ZSOCK_POLLERR; goto next; } else if (ret == 0) { @@ -3576,6 +3831,19 @@ static int ztls_poll_update_pollin(int fd, struct tls_context *ctx, return -EAGAIN; } +#endif /* CONFIG_NET_SOCKETS_ENABLE_DTLS */ + +static int ztls_poll_update_pollin(int fd, struct tls_context *ctx, + struct zsock_pollfd *pfd) +{ +#if defined(CONFIG_NET_SOCKETS_ENABLE_DTLS) + if (ctx->type == NET_SOCK_DGRAM) { + return dtls_update_pollin(fd, ctx, pfd); + } +#endif + + return tls_update_pollin(fd, ctx, pfd); +} static int ztls_poll_update_ctx(struct tls_context *ctx, struct zsock_pollfd *pfd, From 6f58b3f24f9d75537e67ddb915c2b5e7200b4daf Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Tue, 9 Dec 2025 16:31:13 +0100 Subject: [PATCH 2542/3659] net: sockets: tls: DTLS server session matching on TX For TX, the DTLS server needs to check the peer address before passing the packet to mbed TLS. In case the peer address doesn't match the active session, it needs to switch sessions. Signed-off-by: Robert Lubos --- subsys/net/lib/sockets/sockets_tls.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/subsys/net/lib/sockets/sockets_tls.c b/subsys/net/lib/sockets/sockets_tls.c index 372ebdec5b10..9a3c67588762 100644 --- a/subsys/net/lib/sockets/sockets_tls.c +++ b/subsys/net/lib/sockets/sockets_tls.c @@ -2926,6 +2926,19 @@ static ssize_t sendto_dtls_server(struct tls_context *ctx, const void *buf, const struct net_sockaddr *dest_addr, net_socklen_t addrlen) { + int ret; + + if (dest_addr != NULL) { + /* Verify we have a session with the client. */ + ret = dtls_server_switch_active_session(ctx, dest_addr, addrlen); + if (ret < 0) { + NET_DBG("No session found (TX) for [%s]:%d", + LOG_ADDR_PORT_HELPER(dest_addr)); + errno = ENOTCONN; + return -1; + } + } + /* For DTLS server, require to have established DTLS connection * in order to send data. */ @@ -2934,13 +2947,6 @@ static ssize_t sendto_dtls_server(struct tls_context *ctx, const void *buf, return -1; } - /* Verify we are sending to a peer that we have connection with. */ - if (dest_addr && - !dtls_is_peer_addr_valid(ctx->active_session, dest_addr, addrlen) != 0) { - errno = EISCONN; - return -1; - } - return send_tls(ctx, buf, len, flags); } #endif /* CONFIG_NET_SOCKETS_ENABLE_DTLS */ From 4197720be805fe119ebcfc1f01c693b2c20079cf Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Tue, 9 Dec 2025 16:31:13 +0100 Subject: [PATCH 2543/3659] net: sockets: tls: Free DTLS server active session on errors In case of errors on an active session (in most cases peer closing the session), the session should be freed. Note, that as mbed TLS needs some session context to work with, the last session on a socket is not freed, but only reset instead. Signed-off-by: Robert Lubos --- subsys/net/lib/sockets/sockets_tls.c | 71 +++++++++++++++++++++++----- 1 file changed, 59 insertions(+), 12 deletions(-) diff --git a/subsys/net/lib/sockets/sockets_tls.c b/subsys/net/lib/sockets/sockets_tls.c index 9a3c67588762..3db1a0f1b141 100644 --- a/subsys/net/lib/sockets/sockets_tls.c +++ b/subsys/net/lib/sockets/sockets_tls.c @@ -302,6 +302,8 @@ static struct k_mutex context_lock; */ #define TLS_WAIT_MS 100 +static int tls_mbedtls_reset_session(struct tls_context *context); + static void tls_session_cache_reset(void) { for (int i = 0; i < ARRAY_SIZE(client_cache); i++) { @@ -1146,6 +1148,30 @@ static int dtls_server_switch_session_on_rx(struct tls_context *tls_ctx) return ret; } + +static int dtls_server_free_active_session(struct tls_context *tls_ctx) +{ + int ret = 0; + + if (sys_slist_len(&tls_ctx->sessions) > 1) { + struct tls_session_context *session_ctx; + + /* Free the session and set the active session to any other. */ + sys_slist_find_and_remove(&tls_ctx->sessions, + &tls_ctx->active_session->node); + tls_session_free(tls_ctx->active_session); + tls_ctx->active_session = + SYS_SLIST_PEEK_HEAD_CONTAINER(&tls_ctx->sessions, + session_ctx, node); + } else { + /* Last session, just reset it. */ + ret = tls_mbedtls_reset_session(tls_ctx); + } + + tls_ctx->error = 0; + + return ret; +} #endif /* CONFIG_NET_SOCKETS_ENABLE_DTLS */ static int tls_tx(void *ctx, const unsigned char *buf, size_t len) @@ -2947,7 +2973,12 @@ static ssize_t sendto_dtls_server(struct tls_context *ctx, const void *buf, return -1; } - return send_tls(ctx, buf, len, flags); + ret = send_tls(ctx, buf, len, flags); + if (ret < 0 && errno != EAGAIN) { + (void)dtls_server_free_active_session(ctx); + } + + return ret; } #endif /* CONFIG_NET_SOCKETS_ENABLE_DTLS */ @@ -3417,7 +3448,7 @@ static ssize_t recvfrom_dtls_server(struct tls_context *ctx, void *buf, break; } - ret = tls_mbedtls_reset_session(ctx); + ret = dtls_server_free_active_session(ctx); if (ret == 0) { repeat = true; } else { @@ -3448,7 +3479,7 @@ static ssize_t recvfrom_dtls_server(struct tls_context *ctx, void *buf, case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY: case MBEDTLS_ERR_SSL_CLIENT_RECONNECT: - ret = tls_mbedtls_reset_session(ctx); + ret = dtls_server_free_active_session(ctx); if (ret == 0) { repeat = true; } else { @@ -3476,13 +3507,12 @@ static ssize_t recvfrom_dtls_server(struct tls_context *ctx, void *buf, default: NET_ERR("DTLS server recv error: -%x", -ret); - ret = tls_mbedtls_reset_session(ctx); - if (ret != 0) { + ret = dtls_server_free_active_session(ctx); + if (ret == 0) { + repeat = true; + } else { ctx->error = ENOMEM; errno = ENOMEM; - } else { - ctx->error = ECONNABORTED; - ret = -ECONNABORTED; } break; @@ -3721,7 +3751,12 @@ static int dtls_data_check(struct tls_context *ctx) return 0; } - ret = tls_mbedtls_reset_session(ctx); + if (is_server) { + ret = dtls_server_free_active_session(ctx); + } else { + ret = tls_mbedtls_reset_session(ctx); + } + if (ret != 0) { return -ENOMEM; } @@ -3745,7 +3780,13 @@ static int dtls_data_check(struct tls_context *ctx) * resetting the context would result in an error instead * of 0 in a consecutive recv() call. */ - ret = tls_mbedtls_reset_session(ctx); + + if (is_server) { + ret = dtls_server_free_active_session(ctx); + } else { + ret = tls_mbedtls_reset_session(ctx); + } + if (ret != 0) { return -ENOMEM; } @@ -3775,8 +3816,14 @@ static int dtls_data_check(struct tls_context *ctx) /* MbedTLS API documentation requires session to * be reset in other error cases */ - if (tls_mbedtls_reset_session(ctx) != 0) { - return -ENOMEM; + if (is_server) { + if (dtls_server_free_active_session(ctx) != 0) { + return -ENOMEM; + } + } else { + if (tls_mbedtls_reset_session(ctx) != 0) { + return -ENOMEM; + } } if (ret == MBEDTLS_ERR_SSL_TIMEOUT) { From 53be38d3f065293187c58878a1c89c511016e40b Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Tue, 9 Dec 2025 16:31:14 +0100 Subject: [PATCH 2544/3659] net: sockets: tls: Implement DTLS server session matching by CID In case a client address changes, but a session uses Connection ID extension, the server should verify if the packet belongs to any of the established sessions based on the CID value. Therefore, before attempting to allocate a new session in such case, loop over sessions and try to match the packet to one of the existing sessions based on CID. In case of success, update the corresponding peer address. If no session is found based on CID, only then try to allocate a new one. Signed-off-by: Robert Lubos --- subsys/net/lib/sockets/sockets_tls.c | 87 +++++++++++++++++++++++++++- 1 file changed, 86 insertions(+), 1 deletion(-) diff --git a/subsys/net/lib/sockets/sockets_tls.c b/subsys/net/lib/sockets/sockets_tls.c index 3db1a0f1b141..d69fd01cb8c6 100644 --- a/subsys/net/lib/sockets/sockets_tls.c +++ b/subsys/net/lib/sockets/sockets_tls.c @@ -1112,6 +1112,85 @@ static int dtls_server_new_active_session(struct tls_context *tls_ctx, return 0; } +#if defined(CONFIG_MBEDTLS_SSL_DTLS_CONNECTION_ID) +static K_MUTEX_DEFINE(dtls_server_cid_check_lock); + +static int dtls_server_switch_active_session_by_cid(struct tls_context *tls_ctx) +{ + static uint8_t tmp_buf[MBEDTLS_SSL_IN_CONTENT_LEN]; + struct tls_session_context *session_ctx = NULL; + int result = -ENOENT; + + if (!tls_ctx->options.dtls_cid.enabled) { + return -ENOTSUP; + } + + k_mutex_lock(&dtls_server_cid_check_lock, K_FOREVER); + + SYS_SLIST_FOR_EACH_CONTAINER(&tls_ctx->sessions, session_ctx, node) { + struct net_sockaddr addr; + net_socklen_t addrlen; + int cid_enabled; + ssize_t len; + int ret; + + ret = mbedtls_ssl_get_peer_cid(&session_ctx->ssl, &cid_enabled, + NULL, NULL); + if (ret != 0 || cid_enabled != MBEDTLS_SSL_CID_ENABLED) { + continue; + } + + /* This deserves some additional context. The only way I found to + * check if the datagram matches current session based on DTLS CID + * is mbedtls_ssl_check_record() function (which according to the + * API documentation serves exactly the purpose). Because of this, + * we need to: + * - peek the full datagram from the socket this time, not just + * a dummy byte, + * - and as the function may modify the provided datagram, we + * need to repeat this for each checked client session. + * + * As the DTLS records can take up to 16kB in size depending on + * the configuration, it's been decided to dedicate a single + * static buffer for the purpose, and protect it with a mutex to + * avoid races in case multiple DTLS server sockets run in parallel. + */ + addrlen = sizeof(struct net_sockaddr); + len = zsock_recvfrom(tls_ctx->sock, &tmp_buf, sizeof(tmp_buf), + ZSOCK_MSG_DONTWAIT | ZSOCK_MSG_PEEK, + &addr, &addrlen); + if (len < 0) { + result = -errno; + break; + } + + ret = mbedtls_ssl_check_record(&session_ctx->ssl, tmp_buf, len); + if (ret == 0) { + NET_DBG("Found matching session (CID) for [%s]:%d (was [%s]:%d)", + LOG_ADDR_PORT_HELPER(&addr), + LOG_ADDR_PORT_HELPER(&session_ctx->dtls_peer_addr)); + + /* Need to update peer address as CID matched */ + dtls_peer_address_set(session_ctx, &addr, addrlen); + tls_ctx->active_session = session_ctx; + result = 0; + break; + } + } + + k_mutex_unlock(&dtls_server_cid_check_lock); + + return result; +} +#else +#define dtls_server_switch_active_session_by_cid(...) (-ENOTSUP) +#endif /* defined(CONFIG_MBEDTLS_SSL_DTLS_CONNECTION_ID) */ + +/* Returns + * - 0 when session was switched or updated, + * - 1 if session was already valid, + * - negative error code otherwise + */ static int dtls_server_switch_session_on_rx(struct tls_context *tls_ctx) { net_socklen_t addrlen = sizeof(struct net_sockaddr); @@ -1119,7 +1198,7 @@ static int dtls_server_switch_session_on_rx(struct tls_context *tls_ctx) uint8_t tmp_buf; int ret; - /* Peek the datagram first to see if the session needs to be updated. */ + /* Peek a dummy byte first to get peer address. */ ret = zsock_recvfrom(tls_ctx->sock, &tmp_buf, sizeof(tmp_buf), ZSOCK_MSG_DONTWAIT | ZSOCK_MSG_PEEK, &addr, &addrlen); @@ -1133,6 +1212,12 @@ static int dtls_server_switch_session_on_rx(struct tls_context *tls_ctx) return ret; } + /* Not found, try to match existing session by CID */ + ret = dtls_server_switch_active_session_by_cid(tls_ctx); + if (ret == 0) { + return 0; + } + /* No session found, try to allocate one. */ NET_DBG("No session found (RX), allocating new"); From ab07f691285d7d28504c0d65d92ad3e1007f256c Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Tue, 9 Dec 2025 16:31:15 +0100 Subject: [PATCH 2545/3659] net: sockets: tls: DTLS server session timeout rework With support for multiple client sessions for DTLS server socket, the session timeout can no longer rely on built-in mbed TLS timing out mechanism, as this only works for the session that is currently active. Background sessions would never time out if the client just went silent. Therefore, allocate a per-session timestamp, that keeps track of the last activity on the session. Then, whenever poll() or recv() is called loop over all sessions to identify those that timed and should be released. Signed-off-by: Robert Lubos --- subsys/net/lib/sockets/sockets_tls.c | 55 ++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/subsys/net/lib/sockets/sockets_tls.c b/subsys/net/lib/sockets/sockets_tls.c index d69fd01cb8c6..e114a6f88524 100644 --- a/subsys/net/lib/sockets/sockets_tls.c +++ b/subsys/net/lib/sockets/sockets_tls.c @@ -160,6 +160,9 @@ struct tls_session_context { /* DTLS peer address length. */ net_socklen_t dtls_peer_addrlen; + + /* DTLS session expiry time (server only). */ + k_timepoint_t session_expiry; #endif /* CONFIG_NET_SOCKETS_ENABLE_DTLS */ }; @@ -395,6 +398,17 @@ static int dtls_get_remaining_timeout(struct tls_session_context *session_ctx) return timing->fin_ms - elapsed_ms; } + +static void dtls_server_init_session_timeout(struct tls_session_context *session_ctx) +{ + session_ctx->session_expiry = sys_timepoint_calc(K_FOREVER); +} + +static void dtls_server_refresh_session_timeout(struct tls_session_context *session_ctx) +{ + session_ctx->session_expiry = + sys_timepoint_calc(K_MSEC(CONFIG_NET_SOCKETS_DTLS_TIMEOUT)); +} #endif /* CONFIG_NET_SOCKETS_ENABLE_DTLS */ /* Initialize TLS internals. */ @@ -937,6 +951,10 @@ static int dtls_tx(void *ctx, const unsigned char *buf, size_t len) struct tls_context *tls_ctx = ctx; ssize_t sent; + if (tls_ctx->options.role == MBEDTLS_SSL_IS_SERVER) { + dtls_server_refresh_session_timeout(tls_ctx->active_session); + } + sent = zsock_sendto(tls_ctx->sock, buf, len, ZSOCK_MSG_DONTWAIT, &tls_ctx->active_session->dtls_peer_addr, tls_ctx->active_session->dtls_peer_addrlen); @@ -990,6 +1008,8 @@ static int dtls_server_rx(void *ctx, unsigned char *buf, size_t len) return MBEDTLS_ERR_NET_RECV_FAILED; } + dtls_server_refresh_session_timeout(tls_ctx->active_session); + /* Only allow to store peer address for DTLS servers. */ if (tls_ctx->active_session->dtls_peer_addrlen == 0) { dtls_peer_address_set(tls_ctx->active_session, &addr, addrlen); @@ -1109,6 +1129,8 @@ static int dtls_server_new_active_session(struct tls_context *tls_ctx, sys_slist_append(&tls_ctx->sessions, &session_ctx->node); tls_ctx->active_session = session_ctx; + dtls_server_refresh_session_timeout(session_ctx); + return 0; } @@ -1238,6 +1260,8 @@ static int dtls_server_free_active_session(struct tls_context *tls_ctx) { int ret = 0; + dtls_server_init_session_timeout(tls_ctx->active_session); + if (sys_slist_len(&tls_ctx->sessions) > 1) { struct tls_session_context *session_ctx; @@ -1257,6 +1281,23 @@ static int dtls_server_free_active_session(struct tls_context *tls_ctx) return ret; } + +static bool dtls_server_check_expired_sessions(struct tls_context *tls_ctx) +{ + struct tls_session_context *session_ctx, *next; + bool expired = false; + + SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&tls_ctx->sessions, session_ctx, next, node) { + if (sys_timepoint_expired(session_ctx->session_expiry)) { + tls_ctx->active_session = session_ctx; + (void)mbedtls_ssl_close_notify(&tls_ctx->active_session->ssl); + (void)dtls_server_free_active_session(tls_ctx); + expired = true; + } + } + + return expired; +} #endif /* CONFIG_NET_SOCKETS_ENABLE_DTLS */ static int tls_tx(void *ctx, const unsigned char *buf, size_t len) @@ -1687,6 +1728,9 @@ static int tls_mbedtls_session_init(struct tls_session_context *session_ctx, &session_ctx->dtls_timing, dtls_timing_set_delay, dtls_timing_get_delay); + + dtls_server_init_session_timeout(session_ctx); + #if defined(CONFIG_MBEDTLS_SSL_DTLS_CONNECTION_ID) if (tls_ctx->options.dtls_cid.enabled) { ret = mbedtls_ssl_set_cid(&session_ctx->ssl, MBEDTLS_SSL_CID_ENABLED, @@ -3516,6 +3560,8 @@ static ssize_t recvfrom_dtls_server(struct tls_context *ctx, void *buf, repeat = false; + (void)dtls_server_check_expired_sessions(ctx); + if (!is_handshake_complete(ctx->active_session)) { ret = tls_mbedtls_handshake(ctx, timeout); if (ret < 0) { @@ -3583,6 +3629,7 @@ static ssize_t recvfrom_dtls_server(struct tls_context *ctx, void *buf, /* Current peer changed, repeat the loop. */ repeat = true; } else { + (void)dtls_server_check_expired_sessions(ctx); /* Otherwise, just return the error. */ ret = -EAGAIN; } @@ -3822,6 +3869,10 @@ static int dtls_data_check(struct tls_context *ctx) } again: + if (is_server && dtls_server_check_expired_sessions(ctx)) { + return -ENOTCONN; + } + if (!is_handshake_complete(ctx->active_session)) { ret = tls_mbedtls_handshake(ctx, K_NO_WAIT); if (ret < 0) { @@ -3886,6 +3937,10 @@ static int dtls_data_check(struct tls_context *ctx) if (ret == 0) { goto again; } + + if (dtls_server_check_expired_sessions(ctx)) { + return -ENOTCONN; + } } return 0; From 8afc2af3c2213364c3e1c13528b15d12fa3c0bf9 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Mon, 15 Dec 2025 16:24:49 +0100 Subject: [PATCH 2546/3659] net: sockets: tls: Make socket options work with multi-client server For options that return the handshake status, make sure they work in multi-client DTLS server case, by returning the status for the session that completed handshake most recently. For TLS and DTLS client cases that should make no difference, as there should only be one session per context. Signed-off-by: Robert Lubos --- subsys/net/lib/sockets/sockets_tls.c | 52 ++++++++++++++++++++++++---- 1 file changed, 45 insertions(+), 7 deletions(-) diff --git a/subsys/net/lib/sockets/sockets_tls.c b/subsys/net/lib/sockets/sockets_tls.c index e114a6f88524..1725c4046878 100644 --- a/subsys/net/lib/sockets/sockets_tls.c +++ b/subsys/net/lib/sockets/sockets_tls.c @@ -2189,17 +2189,38 @@ static int tls_opt_ciphersuite_list_get(struct tls_context *context, return 0; } +static struct tls_session_context *get_latest_session(struct tls_context *context) +{ + struct tls_session_context *session_ctx = NULL; + struct tls_session_context *latest_session_ctx = NULL; + + SYS_SLIST_FOR_EACH_CONTAINER(&context->sessions, session_ctx, node) { + if ((latest_session_ctx == NULL) || + (session_ctx->handshake_timestamp > + latest_session_ctx->handshake_timestamp)) { + latest_session_ctx = session_ctx; + } + } + + return latest_session_ctx; +} + static int tls_opt_ciphersuite_used_get(struct tls_context *context, void *optval, net_socklen_t *optlen) { + struct tls_session_context *session_ctx; const char *ciph; if (*optlen != sizeof(int)) { return -EINVAL; } + session_ctx = get_latest_session(context); + if (session_ctx == NULL) { + return -ENOTCONN; + } - ciph = mbedtls_ssl_get_ciphersuite(&context->active_session->ssl); + ciph = mbedtls_ssl_get_ciphersuite(&session_ctx->ssl); if (ciph == NULL) { return -ENOTCONN; } @@ -2385,6 +2406,7 @@ static int tls_opt_dtls_peer_connection_id_value_get(struct tls_context *context net_socklen_t *optlen) { #if defined(CONFIG_MBEDTLS_SSL_DTLS_CONNECTION_ID) + struct tls_session_context *session_ctx; int enabled = false; int ret; size_t optlen_local; @@ -2393,8 +2415,12 @@ static int tls_opt_dtls_peer_connection_id_value_get(struct tls_context *context return -ENOTCONN; } - ret = mbedtls_ssl_get_peer_cid(&context->active_session->ssl, &enabled, - optval, &optlen_local); + session_ctx = get_latest_session(context); + if (session_ctx == NULL) { + return -ENOTCONN; + } + + ret = mbedtls_ssl_get_peer_cid(&session_ctx->ssl, &enabled, optval, &optlen_local); if (enabled) { *optlen = optlen_local; } else { @@ -2410,6 +2436,7 @@ static int tls_opt_dtls_connection_id_status_get(struct tls_context *context, void *optval, net_socklen_t *optlen) { #if defined(CONFIG_MBEDTLS_SSL_DTLS_CONNECTION_ID) + struct tls_session_context *session_ctx; struct tls_dtls_cid cid; int ret; int val; @@ -2425,9 +2452,13 @@ static int tls_opt_dtls_connection_id_status_get(struct tls_context *context, return -ENOTCONN; } - ret = mbedtls_ssl_get_peer_cid(&context->active_session->ssl, &enabled, - cid.cid, - &cid.cid_len); + session_ctx = get_latest_session(context); + if (session_ctx == NULL) { + return -ENOTCONN; + } + + ret = mbedtls_ssl_get_peer_cid(&session_ctx->ssl, &enabled, + cid.cid, &cid.cid_len); if (ret) { /* Handshake is not complete */ return -EAGAIN; @@ -2555,11 +2586,18 @@ static int tls_opt_session_cache_get(struct tls_context *context, static int tls_opt_cert_verify_result_get(struct tls_context *context, void *optval, net_socklen_t *optlen) { + struct tls_session_context *session_ctx; + if (*optlen != sizeof(uint32_t)) { return -EINVAL; } - *(uint32_t *)optval = mbedtls_ssl_get_verify_result(&context->active_session->ssl); + session_ctx = get_latest_session(context); + if (session_ctx == NULL) { + return -ENOTCONN; + } + + *(uint32_t *)optval = mbedtls_ssl_get_verify_result(&session_ctx->ssl); return 0; } From 3cc194ee35f6390dde4ca7f402a34c5b2a287ca3 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Tue, 9 Dec 2025 16:31:16 +0100 Subject: [PATCH 2547/3659] tests: net: sockets: tls: Add test cases for DTLS server multi-client Add test cases verifying that DTLS server socket can handle multiple clients. Signed-off-by: Robert Lubos --- tests/net/socket/tls/prj.conf | 4 +- tests/net/socket/tls/src/main.c | 805 ++++++++++++++++++++++++++++- tests/net/socket/tls/testcase.yaml | 3 + 3 files changed, 808 insertions(+), 4 deletions(-) diff --git a/tests/net/socket/tls/prj.conf b/tests/net/socket/tls/prj.conf index 77646a01bdf2..63a0067e753f 100644 --- a/tests/net/socket/tls/prj.conf +++ b/tests/net/socket/tls/prj.conf @@ -26,6 +26,7 @@ CONFIG_ZVFS_OPEN_ADD_SIZE_NET=10 CONFIG_NET_TCP_TIME_WAIT_DELAY=10 CONFIG_NET_SOCKETS_CONNECT_TIMEOUT=200 CONFIG_NET_SOCKETS_TLS_CONNECT_TIMEOUT=200 +CONFIG_NET_SOCKETS_DTLS_TIMEOUT=1000 # Network driver config CONFIG_NET_DRIVERS=y @@ -47,7 +48,8 @@ CONFIG_ZTEST=y CONFIG_ZTEST_STACK_SIZE=4096 CONFIG_MBEDTLS_ENABLE_HEAP=y -CONFIG_MBEDTLS_HEAP_SIZE=18000 +CONFIG_MBEDTLS_HEAP_SIZE=30000 CONFIG_MBEDTLS_KEY_EXCHANGE_PSK_ENABLED=y CONFIG_MBEDTLS_HASH_ALL_ENABLED=y CONFIG_MBEDTLS_CMAC=y +CONFIG_MBEDTLS_SSL_DTLS_CONNECTION_ID=y diff --git a/tests/net/socket/tls/src/main.c b/tests/net/socket/tls/src/main.c index 1e5b34911f34..e3325407259e 100644 --- a/tests/net/socket/tls/src/main.c +++ b/tests/net/socket/tls/src/main.c @@ -15,6 +15,9 @@ LOG_MODULE_REGISTER(net_test, CONFIG_NET_SOCKETS_LOG_LEVEL); #include "../../socket_helpers.h" +struct mbedtls_ssl_context *ztls_get_mbedtls_ssl_context(int fd); +uint32_t ztls_get_session_count(void); + #define TEST_STR_SMALL "test" #define MY_IPV4_ADDR "127.0.0.1" @@ -22,6 +25,9 @@ LOG_MODULE_REGISTER(net_test, CONFIG_NET_SOCKETS_LOG_LEVEL); #define ANY_PORT 0 #define SERVER_PORT 4242 +#define CLIENT_1_PORT 4243 +#define CLIENT_2_PORT 4244 +#define CLIENT_3_PORT 4245 #define PSK_TAG 1 @@ -34,7 +40,7 @@ LOG_MODULE_REGISTER(net_test, CONFIG_NET_SOCKETS_LOG_LEVEL); K_THREAD_STACK_DEFINE(tls_test_work_queue_stack, TLS_TEST_WORK_QUEUE_STACK_SIZE); static struct k_work_q tls_test_work_queue; -int c_sock = -1, s_sock = -1, new_sock = -1; +int c_sock = -1, c_sock_2 = -1, s_sock = -1, new_sock = -1; static void test_work_reschedule(struct k_work_delayable *dwork, k_timeout_t delay) @@ -122,6 +128,14 @@ static void test_send(int sock, const void *buf, size_t len, int flags) "send failed"); } +static void test_sendto(int sock, const void *buf, size_t len, int flags, + struct net_sockaddr *addr, net_socklen_t addrlen) +{ + zassert_equal(zsock_sendto(sock, buf, len, flags, addr, addrlen), + len, + "sendto failed"); +} + static void test_sendmsg(int sock, const struct net_msghdr *msg, int flags) { size_t total_len = 0; @@ -165,6 +179,11 @@ static void test_sockets_close(void) c_sock = -1; } + if (c_sock_2 >= 0) { + test_close(c_sock_2); + c_sock_2 = -1; + } + if (s_sock >= 0) { test_close(s_sock); s_sock = -1; @@ -1721,8 +1740,6 @@ ZTEST(net_socket_tls, test_poll_dtls_pollhup) k_msleep(10); } -mbedtls_ssl_context *ztls_get_mbedtls_ssl_context(int fd); - ZTEST(net_socket_tls, test_poll_tls_pollerr) { uint8_t rx_buf; @@ -1880,6 +1897,788 @@ ZTEST(net_socket_tls, test_dtls_bad_cred) test_bad_cred_common(true); } +static void dtls_client_connect_send_no_assert_work_handler(struct k_work *work) +{ + struct k_work_delayable *dwork = k_work_delayable_from_work(work); + struct connect_data *data = + CONTAINER_OF(dwork, struct connect_data, work); + uint8_t tx_buf = 0; + int ret; + + ret = zsock_connect(data->sock, data->addr, data->addr->sa_family == NET_AF_INET ? + sizeof(struct net_sockaddr_in) : sizeof(struct net_sockaddr_in6)); + if (ret < 0) { + return; + } + + zsock_send(data->sock, &tx_buf, sizeof(tx_buf), 0); +} + +static void dtls_verify_address(struct net_sockaddr *addr, net_socklen_t addrlen, + struct net_sockaddr *expected) +{ + if (expected->sa_family == NET_AF_INET) { + zassert_equal(addrlen, sizeof(struct net_sockaddr_in), "Address length mismatch"); + zassert_equal(net_sin(addr)->sin_family, NET_AF_INET, "Address family mismatch"); + zassert_equal(net_sin(addr)->sin_port, net_sin(expected)->sin_port, + "Address port mismatch"); + zassert_equal(net_sin(addr)->sin_addr.s_addr, net_sin(expected)->sin_addr.s_addr, + "Address mismatch"); + } else { + zassert_equal(addrlen, sizeof(struct net_sockaddr_in6), "Address length mismatch"); + zassert_equal(net_sin6(addr)->sin6_family, NET_AF_INET6, "Address family mismatch"); + zassert_equal(net_sin6(addr)->sin6_port, net_sin6(expected)->sin6_port, + "Address port mismatch"); + zassert_mem_equal(net_sin6(addr)->sin6_addr.s6_addr, + net_sin6(expected)->sin6_addr.s6_addr, + NET_IPV6_ADDR_SIZE, "Address mismatch"); + } +} + +static void test_dtls_server_multi_client_prepare_socks(net_sa_family_t family, + struct net_sockaddr *s_saddr, + struct net_sockaddr *c_saddr_1, + struct net_sockaddr *c_saddr_2) +{ + net_socklen_t exp_addrlen = family == NET_AF_INET6 ? + sizeof(struct net_sockaddr_in6) : + sizeof(struct net_sockaddr_in); + struct timeval timeo_optval = { + .tv_sec = 1, + .tv_usec = 0, + }; + int role = ZSOCK_TLS_DTLS_ROLE_SERVER; + + if (family == NET_AF_INET6) { + prepare_sock_dtls_v6(MY_IPV6_ADDR, CLIENT_1_PORT, &c_sock, + (struct net_sockaddr_in6 *)c_saddr_1, + NET_IPPROTO_DTLS_1_2); + prepare_sock_dtls_v6(MY_IPV6_ADDR, CLIENT_2_PORT, &c_sock_2, + (struct net_sockaddr_in6 *)c_saddr_2, + NET_IPPROTO_DTLS_1_2); + prepare_sock_dtls_v6(MY_IPV6_ADDR, SERVER_PORT, &s_sock, + (struct net_sockaddr_in6 *)s_saddr, + NET_IPPROTO_DTLS_1_2); + } else { + prepare_sock_dtls_v4(MY_IPV4_ADDR, CLIENT_1_PORT, &c_sock, + (struct net_sockaddr_in *)c_saddr_1, + NET_IPPROTO_DTLS_1_2); + prepare_sock_dtls_v4(MY_IPV4_ADDR, CLIENT_2_PORT, &c_sock_2, + (struct net_sockaddr_in *)c_saddr_2, + NET_IPPROTO_DTLS_1_2); + prepare_sock_dtls_v4(MY_IPV4_ADDR, SERVER_PORT, &s_sock, + (struct net_sockaddr_in *)s_saddr, + NET_IPPROTO_DTLS_1_2); + } + + test_config_psk(s_sock, c_sock); + test_config_psk(s_sock, c_sock_2); + + zassert_ok(zsock_setsockopt(s_sock, ZSOCK_SOL_TLS, ZSOCK_TLS_DTLS_ROLE, + &role, sizeof(role)), + "setsockopt failed (%d)", errno); + zassert_ok(zsock_setsockopt(s_sock, ZSOCK_SOL_SOCKET, ZSOCK_SO_RCVTIMEO, + &timeo_optval, sizeof(timeo_optval)), + "setsockopt failed (%d)", errno); + zassert_ok(zsock_setsockopt(c_sock, ZSOCK_SOL_SOCKET, ZSOCK_SO_RCVTIMEO, + &timeo_optval, sizeof(timeo_optval)), + "setsockopt failed (%d)", errno); + zassert_ok(zsock_setsockopt(c_sock_2, ZSOCK_SOL_SOCKET, ZSOCK_SO_RCVTIMEO, + &timeo_optval, sizeof(timeo_optval)), + "setsockopt failed (%d)", errno); + + test_bind(c_sock, c_saddr_1, exp_addrlen); + test_bind(c_sock_2, c_saddr_2, exp_addrlen); + test_bind(s_sock, s_saddr, exp_addrlen); +} + +static void test_dtls_server_multi_client_hs_in_poll(net_sa_family_t family) +{ + struct net_sockaddr c_saddr_1; + struct net_sockaddr c_saddr_2; + struct net_sockaddr s_saddr; + struct net_sockaddr recv_addr; + net_socklen_t recv_addrlen; + struct connect_data test_data; + struct zsock_pollfd fds[1]; + uint8_t tx_buf = 0; + uint8_t rx_buf; + int ret; + + test_dtls_server_multi_client_prepare_socks(family, &s_saddr, &c_saddr_1, + &c_saddr_2); + zassert_equal(ztls_get_session_count(), 3, "Expected session count mismatch"); + + /* Client 1 handshake */ + test_data.sock = c_sock; + test_data.addr = &s_saddr; + k_work_init_delayable(&test_data.work, dtls_client_connect_send_work_handler); + test_work_reschedule(&test_data.work, K_NO_WAIT); + + /* DTLS has no separate call like accept() to know when the handshake + * is complete, therefore send a dummy byte once handshake is done to + * unblock poll(). + */ + fds[0].fd = s_sock; + fds[0].events = ZSOCK_POLLIN; + ret = zsock_poll(fds, 1, 1000); + zassert_equal(ret, 1, "poll() did not report data ready"); + zassert_equal(ztls_get_session_count(), 3, + "Server shouldn't have allocated extra session yet"); + + /* Flush the dummy byte. */ + recv_addrlen = sizeof(recv_addr); + ret = zsock_recvfrom(s_sock, &rx_buf, sizeof(rx_buf), 0, + &recv_addr, &recv_addrlen); + zassert_equal(ret, sizeof(rx_buf), "recv() failed"); + dtls_verify_address(&recv_addr, recv_addrlen, &c_saddr_1); + + /* Client 2 handshake */ + test_data.sock = c_sock_2; + test_data.addr = &s_saddr; + k_work_init_delayable(&test_data.work, dtls_client_connect_send_no_assert_work_handler); + test_work_reschedule(&test_data.work, K_NO_WAIT); + + /* DTLS has no separate call like accept() to know when the handshake + * is complete, therefore send a dummy byte once handshake is done to + * unblock poll(). + */ + fds[0].fd = s_sock; + fds[0].events = ZSOCK_POLLIN; + ret = zsock_poll(fds, 1, 1000); + zassert_equal(ret, 1, "poll() did not report data ready"); + zassert_equal(ztls_get_session_count(), 4, "Server should've allocated extra session"); + + /* Flush the dummy byte. */ + recv_addrlen = sizeof(recv_addr); + ret = zsock_recvfrom(s_sock, &rx_buf, sizeof(rx_buf), 0, + &recv_addr, &recv_addrlen); + zassert_equal(ret, sizeof(rx_buf), "recv() failed"); + dtls_verify_address(&recv_addr, recv_addrlen, &c_saddr_2); + + /* Now as two sessions are established, send data from client 1 again. */ + test_send(c_sock, &tx_buf, sizeof(tx_buf), 0); + + /* And verify the server receives the data with correct address */ + fds[0].fd = s_sock; + fds[0].events = ZSOCK_POLLIN; + ret = zsock_poll(fds, 1, 1000); + zassert_equal(ret, 1, "poll() did not report data ready"); + + recv_addrlen = sizeof(recv_addr); + ret = zsock_recvfrom(s_sock, &rx_buf, sizeof(rx_buf), 0, + &recv_addr, &recv_addrlen); + zassert_equal(ret, sizeof(rx_buf), "recv() failed"); + dtls_verify_address(&recv_addr, recv_addrlen, &c_saddr_1); + + /* Repeat for client 2 again */ + test_send(c_sock_2, &tx_buf, sizeof(tx_buf), 0); + + /* And verify the server receives the data with correct address */ + fds[0].fd = s_sock; + fds[0].events = ZSOCK_POLLIN; + ret = zsock_poll(fds, 1, 1000); + zassert_equal(ret, 1, "poll() did not report data ready"); + + recv_addrlen = sizeof(recv_addr); + ret = zsock_recvfrom(s_sock, &rx_buf, sizeof(rx_buf), 0, + &recv_addr, &recv_addrlen); + zassert_equal(ret, sizeof(rx_buf), "recv() failed"); + dtls_verify_address(&recv_addr, recv_addrlen, &c_saddr_2); + + /* Close the first client session */ + test_close(c_sock); + c_sock = -1; + + /* Let the server update sessions, poll should report POLLHUP. */ + fds[0].fd = s_sock; + fds[0].events = ZSOCK_POLLIN; + ret = zsock_poll(fds, 1, 10); + zassert_equal(ret, 1, "poll() should report event"); + zassert_equal(fds[0].revents, ZSOCK_POLLHUP, "No POLLHUP event"); + + /* Two sessions should've been released (one for client, one for server) + * and the server should still be able to receive data from the second client. + */ + zassert_equal(ztls_get_session_count(), 2, "Expected session count mismatch"); + + test_send(c_sock_2, &tx_buf, sizeof(tx_buf), 0); + + fds[0].fd = s_sock; + fds[0].events = ZSOCK_POLLIN; + ret = zsock_poll(fds, 1, 1000); + zassert_equal(ret, 1, "poll() did not report data ready"); + + recv_addrlen = sizeof(recv_addr); + ret = zsock_recvfrom(s_sock, &rx_buf, sizeof(rx_buf), 0, + &recv_addr, &recv_addrlen); + zassert_equal(ret, sizeof(rx_buf), "recv() failed"); + dtls_verify_address(&recv_addr, recv_addrlen, &c_saddr_2); + + /* Close the second client session. */ + test_close(c_sock_2); + c_sock_2 = -1; + + /* Let the server update sessions. */ + fds[0].fd = s_sock; + fds[0].events = ZSOCK_POLLIN; + ret = zsock_poll(fds, 1, 10); + zassert_equal(ret, 1, "poll() should report event"); + zassert_equal(fds[0].revents, ZSOCK_POLLHUP, "No POLLHUP event"); + + /* One session should be released (client), server socket needs at least + * one DTLS session to work with (even disconnected one). + */ + zassert_equal(ztls_get_session_count(), 1, "Expected session count mismatch"); + + test_work_wait(&test_data.work); +} + +ZTEST(net_socket_tls, test_v4_dtls_server_multi_client_hs_in_poll) +{ + test_dtls_server_multi_client_hs_in_poll(NET_AF_INET); +} + +ZTEST(net_socket_tls, test_v6_dtls_server_multi_client_hs_in_poll) +{ + test_dtls_server_multi_client_hs_in_poll(NET_AF_INET6); +} + +static void test_dtls_server_multi_client_hs_in_recvfrom(net_sa_family_t family) +{ + struct net_sockaddr c_saddr_1; + struct net_sockaddr c_saddr_2; + struct net_sockaddr s_saddr; + struct net_sockaddr recv_addr; + net_socklen_t recv_addrlen; + struct connect_data test_data; + uint8_t tx_buf = 0; + uint8_t rx_buf; + int ret; + + test_dtls_server_multi_client_prepare_socks(family, &s_saddr, &c_saddr_1, + &c_saddr_2); + zassert_equal(ztls_get_session_count(), 3, "Expected session count mismatch"); + + /* Client 1 handshake */ + test_data.sock = c_sock; + test_data.addr = &s_saddr; + k_work_init_delayable(&test_data.work, dtls_client_connect_send_work_handler); + test_work_reschedule(&test_data.work, K_NO_WAIT); + + /* Block in recv for the handshake to complete. */ + recv_addrlen = sizeof(recv_addr); + ret = zsock_recvfrom(s_sock, &rx_buf, sizeof(rx_buf), 0, + &recv_addr, &recv_addrlen); + zassert_equal(ret, sizeof(rx_buf), "recv() failed"); + dtls_verify_address(&recv_addr, recv_addrlen, &c_saddr_1); + zassert_equal(ztls_get_session_count(), 3, + "Server shouldn't have allocated extra session yet"); + + /* Client 2 handshake */ + test_data.sock = c_sock_2; + test_data.addr = &s_saddr; + k_work_init_delayable(&test_data.work, dtls_client_connect_send_no_assert_work_handler); + test_work_reschedule(&test_data.work, K_NO_WAIT); + + /* Block in recv for the second handshake to complete. */ + recv_addrlen = sizeof(recv_addr); + ret = zsock_recvfrom(s_sock, &rx_buf, sizeof(rx_buf), 0, + &recv_addr, &recv_addrlen); + zassert_equal(ret, sizeof(rx_buf), "recv() failed"); + dtls_verify_address(&recv_addr, recv_addrlen, &c_saddr_2); + zassert_equal(ztls_get_session_count(), 4, "Server should've allocated extra session"); + + /* Now as two sessions are established, send data from client 1 again. */ + test_send(c_sock, &tx_buf, sizeof(tx_buf), 0); + + /* And verify the server receives the data with correct address */ + recv_addrlen = sizeof(recv_addr); + ret = zsock_recvfrom(s_sock, &rx_buf, sizeof(rx_buf), 0, + &recv_addr, &recv_addrlen); + zassert_equal(ret, sizeof(rx_buf), "recv() failed"); + dtls_verify_address(&recv_addr, recv_addrlen, &c_saddr_1); + + /* Repeat for client 2 again */ + test_send(c_sock_2, &tx_buf, sizeof(tx_buf), 0); + + /* And verify the server receives the data with correct address */ + recv_addrlen = sizeof(recv_addr); + ret = zsock_recvfrom(s_sock, &rx_buf, sizeof(rx_buf), 0, + &recv_addr, &recv_addrlen); + zassert_equal(ret, sizeof(rx_buf), "recv() failed"); + dtls_verify_address(&recv_addr, recv_addrlen, &c_saddr_2); + + /* Close the second client session */ + test_close(c_sock_2); + c_sock_2 = -1; + + /* Small delay for the alerts exchange */ + k_msleep(10); + + /* Let the server update sessions. */ + ret = zsock_recv(s_sock, &rx_buf, sizeof(rx_buf), ZSOCK_MSG_DONTWAIT); + zassert_equal(ret, -1, "recv() should've reported EAGAIN"); + zassert_equal(errno, EAGAIN, "wrong errno value"); + + /* Two sessions should've been released (one for client, one for server) + * and the server should still be able to receive data from the second client. + */ + zassert_equal(ztls_get_session_count(), 2, "Expected session count mismatch"); + + test_send(c_sock, &tx_buf, sizeof(tx_buf), 0); + + recv_addrlen = sizeof(recv_addr); + ret = zsock_recvfrom(s_sock, &rx_buf, sizeof(rx_buf), 0, + &recv_addr, &recv_addrlen); + zassert_equal(ret, sizeof(rx_buf), "recv() failed"); + dtls_verify_address(&recv_addr, recv_addrlen, &c_saddr_1); + + /* Close the first client session. */ + test_close(c_sock); + c_sock = -1; + + /* Small delay for the alerts exchange */ + k_msleep(10); + + /* Let the server update sessions. */ + ret = zsock_recv(s_sock, &rx_buf, sizeof(rx_buf), ZSOCK_MSG_DONTWAIT); + zassert_equal(ret, -1, "recv() should've reported EAGAIN"); + zassert_equal(errno, EAGAIN, "wrong errno value"); + + /* One session should be released (client), server socket needs at least + * one DTLS session to work with (even disconnected one). + */ + zassert_equal(ztls_get_session_count(), 1, "Expected session count mismatch"); + + test_work_wait(&test_data.work); +} + +ZTEST(net_socket_tls, test_v4_dtls_server_multi_client_hs_in_recvfrom) +{ + test_dtls_server_multi_client_hs_in_recvfrom(NET_AF_INET); +} + +ZTEST(net_socket_tls, test_v6_dtls_server_multi_client_hs_in_recvfrom) +{ + test_dtls_server_multi_client_hs_in_recvfrom(NET_AF_INET6); +} + +static void test_dtls_server_multi_client_prepare_two_connections( + net_sa_family_t family, struct net_sockaddr *s_saddr, + struct net_sockaddr *c_saddr_1, struct net_sockaddr *c_saddr_2, + int32_t delay) +{ + struct connect_data test_data; + uint8_t rx_buf; + int ret; + + test_dtls_server_multi_client_prepare_socks(family, s_saddr, c_saddr_1, + c_saddr_2); + /* Client 1 handshake */ + test_data.sock = c_sock; + test_data.addr = s_saddr; + k_work_init_delayable(&test_data.work, dtls_client_connect_send_work_handler); + test_work_reschedule(&test_data.work, K_NO_WAIT); + + /* Block in recv for the handshake to complete. */ + ret = zsock_recvfrom(s_sock, &rx_buf, sizeof(rx_buf), 0, NULL, NULL); + zassert_equal(ret, sizeof(rx_buf), "recv() failed"); + + if (delay > 0) { + k_msleep(delay); + } + + /* Client 2 handshake */ + test_data.sock = c_sock_2; + test_data.addr = s_saddr; + k_work_init_delayable(&test_data.work, dtls_client_connect_send_no_assert_work_handler); + test_work_reschedule(&test_data.work, K_NO_WAIT); + + /* Block in recv for the second handshake to complete. */ + ret = zsock_recvfrom(s_sock, &rx_buf, sizeof(rx_buf), 0, NULL, NULL); + zassert_equal(ret, sizeof(rx_buf), "recv() failed"); + + test_work_wait(&test_data.work); +} + +static void test_dtls_server_multi_client_sendto(net_sa_family_t family) +{ + struct net_sockaddr c_saddr_1; + struct net_sockaddr c_saddr_2; + struct net_sockaddr s_saddr; + net_socklen_t addrlen = family == NET_AF_INET6 ? + sizeof(struct net_sockaddr_in6) : + sizeof(struct net_sockaddr_in); + uint8_t tx_buf = 0; + uint8_t rx_buf; + int ret; + + test_dtls_server_multi_client_prepare_two_connections(family, &s_saddr, + &c_saddr_1, &c_saddr_2, 0); + zassert_equal(ztls_get_session_count(), 4, "Expected session count mismatch"); + + /* As two sessions are established, send data from server to client 1. */ + test_sendto(s_sock, &tx_buf, sizeof(tx_buf), 0, &c_saddr_1, addrlen); + ret = zsock_recv(c_sock, &rx_buf, sizeof(rx_buf), 0); + zassert_equal(ret, sizeof(rx_buf), "recv() failed"); + + /* Now to client 2. */ + test_sendto(s_sock, &tx_buf, sizeof(tx_buf), 0, &c_saddr_2, addrlen); + ret = zsock_recv(c_sock_2, &rx_buf, sizeof(rx_buf), 0); + zassert_equal(ret, sizeof(rx_buf), "recv() failed"); + + /* And back to client 1 again. */ + test_sendto(s_sock, &tx_buf, sizeof(tx_buf), 0, &c_saddr_1, addrlen); + ret = zsock_recv(c_sock, &rx_buf, sizeof(rx_buf), 0); + zassert_equal(ret, sizeof(rx_buf), "recv() failed"); + + /* Close the first client session */ + test_close(c_sock); + c_sock = -1; + + /* Small delay for the alerts exchange */ + k_msleep(10); + + /* Let the server update sessions. */ + ret = zsock_recv(s_sock, &rx_buf, sizeof(rx_buf), ZSOCK_MSG_DONTWAIT); + zassert_equal(ret, -1, "recv() should've reported EAGAIN"); + zassert_equal(errno, EAGAIN, "wrong errno value"); + + /* Two sessions should've been released (one for client, one for server) + * and the server should still be able to receive data from the second client. + */ + zassert_equal(ztls_get_session_count(), 2, "Expected session count mismatch"); + + /* Sending to second client should still work */ + test_sendto(s_sock, &tx_buf, sizeof(tx_buf), 0, &c_saddr_2, addrlen); + ret = zsock_recv(c_sock_2, &rx_buf, sizeof(rx_buf), 0); + zassert_equal(ret, sizeof(rx_buf), "recv() failed"); + + /* Sending to the first client should fail though. */ + ret = zsock_sendto(s_sock, &tx_buf, sizeof(tx_buf), 0, &c_saddr_1, addrlen); + zassert_equal(ret, -1, "zsock_sendto() should've failed"); + zassert_equal(errno, ENOTCONN, "wrong errno"); + + /* Close the second client session. */ + test_close(c_sock_2); + c_sock_2 = -1; + + /* Small delay for the alerts exchange */ + k_msleep(10); + + /* Let the server update sessions. */ + ret = zsock_recv(s_sock, &rx_buf, sizeof(rx_buf), ZSOCK_MSG_DONTWAIT); + zassert_equal(ret, -1, "recv() should've reported EAGAIN"); + zassert_equal(errno, EAGAIN, "wrong errno value"); + + /* One session should be released (client), server socket needs at least + * one DTLS session to work with (even disconnected one). + */ + zassert_equal(ztls_get_session_count(), 1, "Expected session count mismatch"); + + /* But sending to the second client should fail now. */ + ret = zsock_sendto(s_sock, &tx_buf, sizeof(tx_buf), 0, &c_saddr_2, addrlen); + zassert_equal(ret, -1, "zsock_sendto() should've failed"); + zassert_equal(errno, ENOTCONN, "wrong errno"); +} + +ZTEST(net_socket_tls, test_v4_dtls_server_multi_client_sendto) +{ + test_dtls_server_multi_client_sendto(NET_AF_INET); +} + +ZTEST(net_socket_tls, test_v6_dtls_server_multi_client_sendto) +{ + test_dtls_server_multi_client_sendto(NET_AF_INET6); +} + +static void test_dtls_server_cid_matching_on_addr_change(net_sa_family_t family) +{ + struct net_sockaddr c_saddr_1; + struct net_sockaddr c_saddr_2; + struct net_sockaddr c_saddr_1_backup; + struct net_sockaddr s_saddr; + struct net_sockaddr recv_addr; + net_socklen_t recv_addrlen; + net_socklen_t addrlen = family == NET_AF_INET6 ? + sizeof(struct net_sockaddr_in6) : + sizeof(struct net_sockaddr_in); + struct connect_data test_data; + uint8_t tx_buf = 0; + uint8_t rx_buf; + int cid, ret; + + if (!IS_ENABLED(CONFIG_MBEDTLS_SSL_DTLS_CONNECTION_ID)) { + ztest_test_skip(); + } + + test_dtls_server_multi_client_prepare_socks(family, &s_saddr, &c_saddr_1, + &c_saddr_2); + zassert_equal(ztls_get_session_count(), 3, "Expected session count mismatch"); + + /* Enable DTLS CID for clients */ + cid = ZSOCK_TLS_DTLS_CID_ENABLED; + zassert_ok(zsock_setsockopt(c_sock, ZSOCK_SOL_TLS, ZSOCK_TLS_DTLS_CID, + &cid, sizeof(cid)), "setsockopt failed (%d)", errno); + zassert_ok(zsock_setsockopt(c_sock_2, ZSOCK_SOL_TLS, ZSOCK_TLS_DTLS_CID, + &cid, sizeof(cid)), "setsockopt failed (%d)", errno); + + /* And enable CID processing for server */ + cid = ZSOCK_TLS_DTLS_CID_SUPPORTED; + zassert_ok(zsock_setsockopt(s_sock, ZSOCK_SOL_TLS, ZSOCK_TLS_DTLS_CID, + &cid, sizeof(cid)), "setsockopt failed (%d)", errno); + + /* Client 1 handshake */ + test_data.sock = c_sock; + test_data.addr = &s_saddr; + k_work_init_delayable(&test_data.work, dtls_client_connect_send_work_handler); + test_work_reschedule(&test_data.work, K_NO_WAIT); + + /* Block in recv for the handshake to complete. */ + recv_addrlen = sizeof(recv_addr); + ret = zsock_recvfrom(s_sock, &rx_buf, sizeof(rx_buf), 0, + &recv_addr, &recv_addrlen); + zassert_equal(ret, sizeof(rx_buf), "recv() failed"); + dtls_verify_address(&recv_addr, recv_addrlen, &c_saddr_1); + zassert_equal(ztls_get_session_count(), 3, + "Server shouldn't have allocated extra session"); + + /* Rebind the client socket to a different port */ + c_saddr_1_backup = c_saddr_1; + if (family == NET_AF_INET) { + net_sin(&c_saddr_1)->sin_port = net_htons(CLIENT_3_PORT); + } else { + net_sin6(&c_saddr_1)->sin6_port = net_htons(CLIENT_3_PORT); + } + + test_bind(c_sock, &c_saddr_1, addrlen); + + /* After rebinding, try to send some data to the server. */ + test_send(c_sock, &tx_buf, sizeof(tx_buf), 0); + + /* And verify the server receives the data with correct address */ + recv_addrlen = sizeof(recv_addr); + ret = zsock_recvfrom(s_sock, &rx_buf, sizeof(rx_buf), 0, + &recv_addr, &recv_addrlen); + zassert_equal(ret, sizeof(rx_buf), "recv() failed"); + dtls_verify_address(&recv_addr, recv_addrlen, &c_saddr_1); + + /* No new session should've been spawned */ + zassert_equal(ztls_get_session_count(), 3, + "Server shouldn't have allocated extra session"); + + /* Sending back with the old address should fail */ + ret = zsock_sendto(s_sock, &tx_buf, sizeof(tx_buf), 0, &c_saddr_1_backup, + addrlen); + zassert_equal(ret, -1, "zsock_sendto() should've failed"); + zassert_equal(errno, ENOTCONN, "wrong errno"); + + /* Sending back with the new address should succeed */ + test_sendto(s_sock, &tx_buf, sizeof(tx_buf), 0, &c_saddr_1, addrlen); + ret = zsock_recv(c_sock, &rx_buf, sizeof(rx_buf), 0); + zassert_equal(ret, sizeof(tx_buf), "recv() failed"); + + /* New client connecting with the "old" address but different CID */ + c_saddr_2 = c_saddr_1_backup; + test_bind(c_sock_2, &c_saddr_2, addrlen); + + /* Client 2 handshake */ + test_data.sock = c_sock_2; + test_data.addr = &s_saddr; + k_work_init_delayable(&test_data.work, dtls_client_connect_send_work_handler); + test_work_reschedule(&test_data.work, K_NO_WAIT); + + /* Block in recv for the handshake to complete. */ + recv_addrlen = sizeof(recv_addr); + ret = zsock_recvfrom(s_sock, &rx_buf, sizeof(rx_buf), 0, + &recv_addr, &recv_addrlen); + zassert_equal(ret, sizeof(rx_buf), "recv() failed"); + dtls_verify_address(&recv_addr, recv_addrlen, &c_saddr_2); + /* New session should be spawned */ + zassert_equal(ztls_get_session_count(), 4, + "Server should have allocated new session"); + + /* Rebind the second client socket to a different port */ + if (family == NET_AF_INET) { + net_sin(&c_saddr_2)->sin_port = net_htons(CLIENT_2_PORT); + } else { + net_sin6(&c_saddr_2)->sin6_port = net_htons(CLIENT_2_PORT); + } + + test_bind(c_sock_2, &c_saddr_2, addrlen); + + /* After rebinding, try to send some data to the server. */ + test_send(c_sock_2, &tx_buf, sizeof(tx_buf), 0); + + /* And verify the server receives the data with correct address */ + recv_addrlen = sizeof(recv_addr); + ret = zsock_recvfrom(s_sock, &rx_buf, sizeof(rx_buf), 0, + &recv_addr, &recv_addrlen); + zassert_equal(ret, sizeof(rx_buf), "recv() failed"); + dtls_verify_address(&recv_addr, recv_addrlen, &c_saddr_2); + + /* No new session should've been spawned */ + zassert_equal(ztls_get_session_count(), 4, + "Server shouldn't have allocated extra session"); + + /* Close both clients and verify session count dropped. */ + test_close(c_sock); + test_close(c_sock_2); + c_sock = -1; + c_sock_2 = -1; + + /* Small delay for the alerts exchange */ + k_msleep(10); + + /* Let the server update sessions. */ + ret = zsock_recv(s_sock, &rx_buf, sizeof(rx_buf), ZSOCK_MSG_DONTWAIT); + zassert_equal(ret, -1, "recv() should've reported EAGAIN"); + zassert_equal(errno, EAGAIN, "wrong errno value"); + + zassert_equal(ztls_get_session_count(), 1, "Leftover sessions!"); + + test_work_wait(&test_data.work); +} + +ZTEST(net_socket_tls, test_v4_dtls_server_cid_matching_on_addr_change) +{ + test_dtls_server_cid_matching_on_addr_change(NET_AF_INET); +} + +ZTEST(net_socket_tls, test_v6_dtls_server_cid_matching_on_addr_change) +{ + test_dtls_server_cid_matching_on_addr_change(NET_AF_INET6); +} + +static void test_dtls_server_session_timeout_poll(net_sa_family_t family) +{ + struct net_sockaddr c_saddr_1; + struct net_sockaddr c_saddr_2; + struct net_sockaddr s_saddr; + int32_t delay = CONFIG_NET_SOCKETS_DTLS_TIMEOUT / 2 + 100; + struct zsock_pollfd fds[1]; + uint8_t rx_buf; + int ret; + + test_dtls_server_multi_client_prepare_two_connections( + family, &s_saddr, &c_saddr_1, &c_saddr_2, delay); + zassert_equal(ztls_get_session_count(), 4, "Expected session count mismatch"); + + /* First client session should time out */ + fds[0].fd = s_sock; + fds[0].events = ZSOCK_POLLIN; + ret = zsock_poll(fds, 1, delay); + zassert_equal(ret, 1, "poll() did not report data ready"); + zassert_equal(fds[0].revents, ZSOCK_POLLHUP, "expected ZSOCK_POLLHUP"); + zassert_equal(ztls_get_session_count(), 3, "Expected session count mismatch"); + + /* Small delay for the alerts exchange */ + k_msleep(10); + + /* Verify client socket reports error (server closed the session) */ + ret = zsock_recv(c_sock, &rx_buf, sizeof(rx_buf), ZSOCK_MSG_DONTWAIT); + zassert_equal(ret, -1, "recv() should've failed"); + zassert_equal(errno, ENOTCONN, "Wrong errno, expected ENOTCONN"); + + /* Second client should still be operational */ + ret = zsock_recv(c_sock_2, &rx_buf, sizeof(rx_buf), ZSOCK_MSG_DONTWAIT); + /* Not really an error (EAGAIN) */ + zassert_equal(ret, -1, "recv() should've failed"); + zassert_equal(errno, EAGAIN, "Wrong errno, expected EAGAIN"); + + /* Second client session should time out */ + fds[0].fd = s_sock; + fds[0].events = ZSOCK_POLLIN; + ret = zsock_poll(fds, 1, delay); + zassert_equal(ret, 1, "poll() did not report data ready"); + zassert_equal(fds[0].revents, ZSOCK_POLLHUP, "expected ZSOCK_POLLHUP"); + zassert_equal(ztls_get_session_count(), 3, "Expected session count mismatch"); + + /* Small delay for the alerts exchange */ + k_msleep(10); + + /* Verify second client socket reports error (server closed the session) */ + ret = zsock_recv(c_sock_2, &rx_buf, sizeof(rx_buf), ZSOCK_MSG_DONTWAIT); + zassert_equal(ret, -1, "recv() should've failed"); + zassert_equal(errno, ENOTCONN, "Wrong errno, expected ENOTCONN"); +} + +ZTEST(net_socket_tls, test_v4_dtls_server_session_timeout_poll) +{ + test_dtls_server_session_timeout_poll(NET_AF_INET); +} + +ZTEST(net_socket_tls, test_v6_dtls_server_session_timeout_poll) +{ + test_dtls_server_session_timeout_poll(NET_AF_INET6); +} + +static void test_dtls_server_session_timeout_recvfrom(net_sa_family_t family) +{ + struct net_sockaddr c_saddr_1; + struct net_sockaddr c_saddr_2; + struct net_sockaddr s_saddr; + int32_t delay = CONFIG_NET_SOCKETS_DTLS_TIMEOUT / 2 + 100; + struct timeval timeo_optval; + uint8_t rx_buf; + int ret; + + timeo_optval.tv_sec = 0; + timeo_optval.tv_usec = delay * USEC_PER_MSEC; + + test_dtls_server_multi_client_prepare_two_connections( + family, &s_saddr, &c_saddr_1, &c_saddr_2, delay); + zassert_equal(ztls_get_session_count(), 4, "Expected session count mismatch"); + + zassert_ok(zsock_setsockopt(s_sock, ZSOCK_SOL_SOCKET, ZSOCK_SO_RCVTIMEO, + &timeo_optval, sizeof(timeo_optval)), + "setsockopt failed (%d)", errno); + + /* Block in recv, it should timeout, and the first client should've timed + * out at this point. + */ + ret = zsock_recvfrom(s_sock, &rx_buf, sizeof(rx_buf), 0, NULL, NULL); + zassert_equal(ret, -1, "recv() should've timed out"); + zassert_equal(errno, EAGAIN, "Wrong errno, expected EAGAIN"); + zassert_equal(ztls_get_session_count(), 3, "Expected session count mismatch"); + + /* Small delay for the alerts exchange */ + k_msleep(10); + + /* Verify client socket reports error (server closed the session) */ + ret = zsock_recv(c_sock, &rx_buf, sizeof(rx_buf), ZSOCK_MSG_DONTWAIT); + zassert_equal(ret, -1, "recv() should've failed"); + zassert_equal(errno, ENOTCONN, "Wrong errno, expected ENOTCONN"); + + /* Second client should still be operational */ + ret = zsock_recv(c_sock_2, &rx_buf, sizeof(rx_buf), ZSOCK_MSG_DONTWAIT); + /* Not really an error (EAGAIN) */ + zassert_equal(ret, -1, "recv() should've failed"); + zassert_equal(errno, EAGAIN, "Wrong errno, expected EAGAIN"); + + /* Second client session should time out */ + ret = zsock_recvfrom(s_sock, &rx_buf, sizeof(rx_buf), 0, NULL, NULL); + zassert_equal(ret, -1, "recv() should've timed out"); + zassert_equal(errno, EAGAIN, "Wrong errno, expected EAGAIN"); + zassert_equal(ztls_get_session_count(), 3, "Expected session count mismatch"); + + /* Verify second client socket reports error (server closed the session) */ + ret = zsock_recv(c_sock_2, &rx_buf, sizeof(rx_buf), ZSOCK_MSG_DONTWAIT); + zassert_equal(ret, -1, "recv() should've failed"); + zassert_equal(errno, ENOTCONN, "Wrong errno, expected ENOTCONN"); +} + +ZTEST(net_socket_tls, test_v4_dtls_server_session_timeout_recvfrom) +{ + test_dtls_server_session_timeout_recvfrom(NET_AF_INET); +} + +ZTEST(net_socket_tls, test_v6_dtls_server_session_timeout_recvfrom) +{ + test_dtls_server_session_timeout_recvfrom(NET_AF_INET6); +} + static void *tls_tests_setup(void) { k_work_queue_init(&tls_test_work_queue); diff --git a/tests/net/socket/tls/testcase.yaml b/tests/net/socket/tls/testcase.yaml index f652305f20bc..b4acc1c18060 100644 --- a/tests/net/socket/tls/testcase.yaml +++ b/tests/net/socket/tls/testcase.yaml @@ -21,3 +21,6 @@ tests: net.socket.tls.sendmsg_no_buf: extra_configs: - CONFIG_NET_SOCKETS_DTLS_SENDMSG_BUF_SIZE=0 + net.socket.tls.no_dtls_cid: + extra_configs: + - CONFIG_MBEDTLS_SSL_DTLS_CONNECTION_ID=n From ba047342201ea1373534b77154b8ff47d5bb5779 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Fri, 19 Dec 2025 11:40:46 +0100 Subject: [PATCH 2548/3659] net: sockets: tls: Optimze helper buffer for sendmsg and CID check Both cases use a large static buffer, we can optimize here and use a single mutex-protected buffer for both. sendmsg() test case needed adjustments, as it was also testing a buffer overflow scenario. This can only be properly tested however if CID feature is disabled, as otherwise the common helper buffer size is increased for the CID use case, preventing the overflow from taking place. Signed-off-by: Robert Lubos --- subsys/net/lib/sockets/sockets_tls.c | 42 ++++++++++++++-------- tests/net/socket/tls/src/main.c | 53 +++++++++++++++++++++++++++- 2 files changed, 79 insertions(+), 16 deletions(-) diff --git a/subsys/net/lib/sockets/sockets_tls.c b/subsys/net/lib/sockets/sockets_tls.c index 1725c4046878..1ad37bb7da9e 100644 --- a/subsys/net/lib/sockets/sockets_tls.c +++ b/subsys/net/lib/sockets/sockets_tls.c @@ -72,8 +72,16 @@ LOG_MODULE_REGISTER(net_sock_tls, CONFIG_NET_SOCKETS_LOG_LEVEL); #if defined(CONFIG_NET_SOCKETS_ENABLE_DTLS) #define DTLS_SENDMSG_BUF_SIZE (CONFIG_NET_SOCKETS_DTLS_SENDMSG_BUF_SIZE) + +#if defined(CONFIG_MBEDTLS_SSL_DTLS_CONNECTION_ID) +#define DTLS_CID_CHECK_BUF_SIZE (MBEDTLS_SSL_IN_CONTENT_LEN) +#else +#define DTLS_CID_CHECK_BUF_SIZE 0 +#endif /* CONFIG_MBEDTLS_SSL_DTLS_CONNECTION_ID */ + #else #define DTLS_SENDMSG_BUF_SIZE 0 +#define DTLS_CID_CHECK_BUF_SIZE 0 #endif /* CONFIG_NET_SOCKETS_ENABLE_DTLS */ static const struct socket_op_vtable tls_sock_fd_op_vtable; @@ -280,6 +288,11 @@ __net_socket struct tls_context { #endif /* CONFIG_MBEDTLS */ }; +#if defined(CONFIG_NET_SOCKETS_ENABLE_DTLS) +#define DTLS_HELPER_BUF_SIZE MAX(DTLS_SENDMSG_BUF_SIZE, DTLS_CID_CHECK_BUF_SIZE) +static uint8_t dtls_helper_buf[DTLS_HELPER_BUF_SIZE]; +static K_MUTEX_DEFINE(dtls_helper_buf_lock); +#endif /* A global pool of TLS contexts. */ static struct tls_context tls_contexts[CONFIG_NET_SOCKETS_TLS_MAX_CONTEXTS]; @@ -1135,11 +1148,8 @@ static int dtls_server_new_active_session(struct tls_context *tls_ctx, } #if defined(CONFIG_MBEDTLS_SSL_DTLS_CONNECTION_ID) -static K_MUTEX_DEFINE(dtls_server_cid_check_lock); - static int dtls_server_switch_active_session_by_cid(struct tls_context *tls_ctx) { - static uint8_t tmp_buf[MBEDTLS_SSL_IN_CONTENT_LEN]; struct tls_session_context *session_ctx = NULL; int result = -ENOENT; @@ -1147,7 +1157,7 @@ static int dtls_server_switch_active_session_by_cid(struct tls_context *tls_ctx) return -ENOTSUP; } - k_mutex_lock(&dtls_server_cid_check_lock, K_FOREVER); + k_mutex_lock(&dtls_helper_buf_lock, K_FOREVER); SYS_SLIST_FOR_EACH_CONTAINER(&tls_ctx->sessions, session_ctx, node) { struct net_sockaddr addr; @@ -1178,7 +1188,7 @@ static int dtls_server_switch_active_session_by_cid(struct tls_context *tls_ctx) * avoid races in case multiple DTLS server sockets run in parallel. */ addrlen = sizeof(struct net_sockaddr); - len = zsock_recvfrom(tls_ctx->sock, &tmp_buf, sizeof(tmp_buf), + len = zsock_recvfrom(tls_ctx->sock, &dtls_helper_buf, sizeof(dtls_helper_buf), ZSOCK_MSG_DONTWAIT | ZSOCK_MSG_PEEK, &addr, &addrlen); if (len < 0) { @@ -1186,7 +1196,7 @@ static int dtls_server_switch_active_session_by_cid(struct tls_context *tls_ctx) break; } - ret = mbedtls_ssl_check_record(&session_ctx->ssl, tmp_buf, len); + ret = mbedtls_ssl_check_record(&session_ctx->ssl, dtls_helper_buf, len); if (ret == 0) { NET_DBG("Found matching session (CID) for [%s]:%d (was [%s]:%d)", LOG_ADDR_PORT_HELPER(&addr), @@ -1200,7 +1210,7 @@ static int dtls_server_switch_active_session_by_cid(struct tls_context *tls_ctx) } } - k_mutex_unlock(&dtls_server_cid_check_lock); + k_mutex_unlock(&dtls_helper_buf_lock); return result; } @@ -3174,40 +3184,42 @@ ssize_t ztls_sendto_ctx(struct tls_context *ctx, const void *buf, size_t len, #endif /* CONFIG_NET_SOCKETS_ENABLE_DTLS */ } +#if defined(CONFIG_NET_SOCKETS_ENABLE_DTLS) static ssize_t dtls_sendmsg_merge_and_send(struct tls_context *ctx, const struct net_msghdr *msg, int flags) { - static K_MUTEX_DEFINE(sendmsg_lock); - static uint8_t sendmsg_buf[DTLS_SENDMSG_BUF_SIZE]; ssize_t len = 0; - k_mutex_lock(&sendmsg_lock, K_FOREVER); + k_mutex_lock(&dtls_helper_buf_lock, K_FOREVER); for (int i = 0; i < msg->msg_iovlen; i++) { struct net_iovec *vec = msg->msg_iov + i; if (vec->iov_len > 0) { - if (len + vec->iov_len > sizeof(sendmsg_buf)) { - k_mutex_unlock(&sendmsg_lock); + if (len + vec->iov_len > sizeof(dtls_helper_buf)) { + k_mutex_unlock(&dtls_helper_buf_lock); errno = EMSGSIZE; return -1; } - memcpy(sendmsg_buf + len, vec->iov_base, vec->iov_len); + memcpy(dtls_helper_buf + len, vec->iov_base, vec->iov_len); len += vec->iov_len; } } if (len > 0) { - len = ztls_sendto_ctx(ctx, sendmsg_buf, len, flags, + len = ztls_sendto_ctx(ctx, dtls_helper_buf, len, flags, msg->msg_name, msg->msg_namelen); } - k_mutex_unlock(&sendmsg_lock); + k_mutex_unlock(&dtls_helper_buf_lock); return len; } +#else +#define dtls_sendmsg_merge_and_send(...) (-1) +#endif static ssize_t tls_sendmsg_loop_and_send(struct tls_context *ctx, const struct net_msghdr *msg, diff --git a/tests/net/socket/tls/src/main.c b/tests/net/socket/tls/src/main.c index e3325407259e..5db92a18ff36 100644 --- a/tests/net/socket/tls/src/main.c +++ b/tests/net/socket/tls/src/main.c @@ -697,7 +697,6 @@ static void test_dtls_sendmsg(net_sa_family_t family) { int rv; uint8_t buf[128 + 1] = { 0 }; - uint8_t dummy_byte = 0; static const char expected_str[] = "testtest"; struct net_iovec iov[3] = { { @@ -752,6 +751,38 @@ static void test_dtls_sendmsg(net_sa_family_t family) test_work_wait(&test_data.tx_work); + test_sockets_close(); + + /* Small delay for the final alert exchange */ + k_msleep(10); +} + +static void test_dtls_sendmsg_overflow(net_sa_family_t family) +{ + int rv; + uint8_t buf[128 + 1] = { 0 }; + uint8_t dummy_byte = 0; + struct net_iovec iov[3] = { + { + .iov_base = TEST_STR_SMALL, + .iov_len = sizeof(TEST_STR_SMALL) - 1, + }, + { + .iov_base = TEST_STR_SMALL, + .iov_len = sizeof(TEST_STR_SMALL) - 1, + }, + {}, + }; + struct net_msghdr msg = {}; + struct test_sendmsg_data test_data = { + .msg = &msg, + }; + + test_prepare_dtls_connection(family); + + test_data.sock = c_sock; + k_work_init_delayable(&test_data.tx_work, test_sendmsg_tx_work_handler); + /* sendmsg() with single fragment should still work even if larger than * intermediate buffer size */ @@ -813,6 +844,26 @@ ZTEST(net_socket_tls, test_v6_dtls_sendmsg) test_dtls_sendmsg(NET_AF_INET6); } +ZTEST(net_socket_tls, test_v4_dtls_sendmsg_overflow) +{ + if ((CONFIG_NET_SOCKETS_DTLS_SENDMSG_BUF_SIZE == 0) || + IS_ENABLED(CONFIG_MBEDTLS_SSL_DTLS_CONNECTION_ID)) { + ztest_test_skip(); + } + + test_dtls_sendmsg_overflow(NET_AF_INET); +} + +ZTEST(net_socket_tls, test_v6_dtls_sendmsg_overflow) +{ + if ((CONFIG_NET_SOCKETS_DTLS_SENDMSG_BUF_SIZE == 0) || + IS_ENABLED(CONFIG_MBEDTLS_SSL_DTLS_CONNECTION_ID)) { + ztest_test_skip(); + } + + test_dtls_sendmsg_overflow(NET_AF_INET6); +} + struct close_data { struct k_work_delayable work; int *fd; From 506a59396fdfa6cbd932d2bcaedee8d8c0b72cbd Mon Sep 17 00:00:00 2001 From: Johann Fischer Date: Fri, 18 Jul 2025 00:28:40 +0200 Subject: [PATCH 2549/3659] usb: device_next: fix compilation if the user disables HWINFO Make USBD_HWINFO_DEVID_LENGTH prompt optional so that the code compiles even if HWINFO is disabled. Signed-off-by: Johann Fischer --- subsys/usb/device_next/Kconfig | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/subsys/usb/device_next/Kconfig b/subsys/usb/device_next/Kconfig index 5e7b02e5ee71..dd7748f51b43 100644 --- a/subsys/usb/device_next/Kconfig +++ b/subsys/usb/device_next/Kconfig @@ -96,8 +96,7 @@ config USBD_MSG_WORK_DELAY yet ready to publish the message. The delay unit is milliseconds. config USBD_HWINFO_DEVID_LENGTH - int "The length of the device ID requested from HWINFO in bytes" - depends on HWINFO + int "The length of the device ID requested from HWINFO in bytes" if HWINFO range 8 128 default 16 help From e73e2f148cdd573b9050985382ba1c4b6c50ecf4 Mon Sep 17 00:00:00 2001 From: Marcelo Roberto Jimenez Date: Tue, 18 Nov 2025 10:57:52 -0300 Subject: [PATCH 2550/3659] drivers: ethernet: xmc4xxx: BUG Fix: RX code dropping packets The ethernet DMA driver code was causing the silent dropping of packets with length 125, 126 and 127. The root cause of the problem is that the DMA engine performs an extra four bytes transfer corresponding to the Receive Status Word. For those particular packet lengths, the previous code incorrectly calculated the last fragment size. The new code avoids that pitfall by decrementing the total frame size as the fragments are being collected, while avoiding the creation of an extra fragment on the extracted network packet. Signed-off-by: Marcelo Roberto Jimenez --- drivers/ethernet/eth_xmc4xxx.c | 125 +++++++++++++++++++++++++-------- 1 file changed, 95 insertions(+), 30 deletions(-) diff --git a/drivers/ethernet/eth_xmc4xxx.c b/drivers/ethernet/eth_xmc4xxx.c index 1eb16f7f76c2..394cb38be76c 100644 --- a/drivers/ethernet/eth_xmc4xxx.c +++ b/drivers/ethernet/eth_xmc4xxx.c @@ -61,7 +61,7 @@ LOG_MODULE_REGISTER(eth_xmc4xxx); #define IS_TIMESTAMP_AVAILABLE_RX(desc) (((desc)->status & ETH_MAC_DMA_RDES0_TSA) != 0) #define IS_TIMESTAMP_AVAILABLE_TX(desc) (((desc)->status & ETH_MAC_DMA_TDES0_TTSS) != 0) -#define TOTAL_FRAME_LENGTH(desc) (FIELD_GET(ETH_MAC_DMA_RDES0_FL, (desc)->status) - 4) +#define TOTAL_FRAME_LENGTH(desc) (FIELD_GET(ETH_MAC_DMA_RDES0_FL, (desc)->status)) #define ETH_STATUS_ERROR_TRANSMIT_EVENTS \ (XMC_ETH_MAC_EVENT_BUS_ERROR | XMC_ETH_MAC_EVENT_TRANSMIT_JABBER_TIMEOUT | \ @@ -366,10 +366,11 @@ static struct net_pkt *eth_xmc4xxx_rx_pkt(const struct device *dev) bool eof_found = false; uint16_t tail; XMC_ETH_MAC_DMA_DESC_t *dma_desc; - int num_frags = 0; uint16_t frame_end_index; - struct net_buf *frag, *last_frag = NULL; + struct net_buf *frag, *prev_frag = NULL; + uint16_t remaining_length = 0; + /* tail is the index in the circular buffer of DMA descriptors */ tail = dev_data->dma_desc_rx_tail; dma_desc = &rx_dma_desc[tail]; @@ -383,50 +384,88 @@ static struct net_pkt *eth_xmc4xxx_rx_pkt(const struct device *dev) return NULL; } + /* Search for the end of frame descriptor and get the total + * frame length. + */ while (!IS_OWNED_BY_DMA_RX(dma_desc)) { eof_found = IS_END_OF_FRAME_RX(dma_desc); - num_frags++; if (eof_found) { + remaining_length = TOTAL_FRAME_LENGTH(dma_desc); break; } - MODULO_INC_RX(tail); - if (tail == dev_data->dma_desc_rx_tail) { - /* wrapped */ + /* We wrapped around the circular buffer, came back to + * the starting point, and still did not find the EOF. + * We could return here, but it is safer to do so after + * the loop. + */ break; } - dma_desc = &rx_dma_desc[tail]; } - if (!eof_found) { return NULL; } + /* Save the index of the last frame */ frame_end_index = tail; + /* The DMA engine performs an extra 4 bytes transfer + * corresponding to the Receive Status Word, which is sent + * along the data after the end of the frame (Ref: XMC4500 + * Reference Manual, 15.2.2.2 Receive Path, page 15-25). For + * this reason, it is necessary to subtract four from the + * total frame length. The incorrect handling of this + * difference was the cause of a subtle bug, in which packets + * with length 125, 126 and 127 were silently dropped upon + * reception. + */ + remaining_length -= 4; + + /* Allocate the new fresh packet to receive the data. */ pkt = net_pkt_rx_alloc(K_NO_WAIT); - if (pkt == NULL) { + if (!pkt) { #ifdef CONFIG_NET_STATISTICS_ETHERNET dev_data->stats.errors.rx++; dev_data->stats.error_details.rx_no_buffer_count++; #endif LOG_DBG("Net packet allocation error"); - /* continue because we still need to read out the packet */ + /* continue because we still need to read out the packet. */ } + /* In this loop, the following actions are taken: + * + * 1 - If a packet has been successfully allocated, retrieve the fresh + * fragment from the DMA descriptor and substitute it with a new one + * allocated from the pool. + * + * 2 - Link each retrieved fragment in a list in the newly allocated + * packet. + * + * 3 - Prepare the DMA descriptor for a new DMA round. + * + * It is imperative that this loop is not interrupted until all DMA + * descriptors have been sent back to DMA ownership. + */ + /* Restart the DMA descriptor pointer */ tail = dev_data->dma_desc_rx_tail; dma_desc = &rx_dma_desc[tail]; for (;;) { - if (pkt != NULL) { - uint16_t frag_len = CONFIG_NET_BUF_DATA_SIZE; - - frag = dev_data->rx_frag_list[tail]; + if (pkt) { + uint16_t fragment_length; + + /* Calculate this fragment's length and update the + * remaining length. + */ + if (remaining_length > CONFIG_NET_BUF_DATA_SIZE) { + fragment_length = CONFIG_NET_BUF_DATA_SIZE; + remaining_length -= CONFIG_NET_BUF_DATA_SIZE; + } else { + fragment_length = remaining_length; + remaining_length = 0; + } if (tail == frame_end_index) { - frag_len = TOTAL_FRAME_LENGTH(dma_desc) - - CONFIG_NET_BUF_DATA_SIZE * (num_frags - 1); - if (IS_TIMESTAMP_AVAILABLE_RX(dma_desc)) { struct net_ptp_time timestamp = { .second = dma_desc->time_stamp_seconds, @@ -436,46 +475,72 @@ static struct net_pkt *eth_xmc4xxx_rx_pkt(const struct device *dev) net_pkt_set_priority(pkt, NET_PRIORITY_CA); } } - + /* This fragment has the fresh DMA data */ + frag = dev_data->rx_frag_list[tail]; + /* Due to the minus four above, the fragment length can + * become zero before the last fragment is processed. + */ + if (!fragment_length) { + /* No need to worry about fragment substitution + * for this fragment, just reset it and prepare + * the DMA descriptor. + */ + net_buf_reset(frag); + goto prepare_dma_descriptor; + } + /* Allocate a new net fragment to substitute the current + * one on the current DMA descriptor. + */ new_frag = net_pkt_get_frag(pkt, CONFIG_NET_BUF_DATA_SIZE, K_NO_WAIT); - if (new_frag == NULL) { + if (!new_frag) { #ifdef CONFIG_NET_STATISTICS_ETHERNET dev_data->stats.errors.rx++; dev_data->stats.error_details.rx_buf_alloc_failed++; #endif - LOG_DBG("Frag allocation error. Increase CONFIG_NET_BUF_RX_COUNT."); net_pkt_unref(pkt); pkt = NULL; + LOG_DBG("Frag allocation error. Increase CONFIG_NET_BUF_RX_COUNT."); } else { - net_buf_add(frag, frag_len); - if (!last_frag) { + /* Sets the received fragment length */ + net_buf_add(frag, fragment_length); + if (!prev_frag) { + /* The first fragment goes to the + * packet. + */ net_pkt_frag_insert(pkt, frag); } else { - net_buf_frag_insert(last_frag, frag); + /* Other fragments get added to the + * previous fragment. + */ + net_buf_frag_insert(prev_frag, frag); } - - last_frag = frag; - frag = new_frag; - dev_data->rx_frag_list[tail] = frag; + prev_frag = frag; + dev_data->rx_frag_list[tail] = new_frag; } } +prepare_dma_descriptor: + /* Prepare the current DMA descriptor for the next reception. */ dma_desc->buffer1 = (uint32_t)dev_data->rx_frag_list[tail]->data; dma_desc->length = dev_data->rx_frag_list[tail]->size | ETH_RX_DMA_DESC_SECOND_ADDR_CHAINED_MASK; dma_desc->status = ETH_MAC_DMA_RDES0_OWN; if (tail == frame_end_index) { + /* Time to leave the loop. */ break; } - MODULO_INC_RX(tail); dma_desc = &rx_dma_desc[tail]; } - MODULO_INC_RX(tail); + + /* Leave the device tail index pointing to the next DMA descriptor the + * DMA engine will use. + */ dev_data->dma_desc_rx_tail = tail; + /* Finally, enable a new DMA reception. */ eth_xmc4xxx_trigger_dma_rx(dev_cfg->regs); return pkt; From 261dfbc765c7f88d12106230022cb0d4967788f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20K=C4=99dziora?= Date: Wed, 29 Oct 2025 11:00:28 +0100 Subject: [PATCH 2551/3659] drivers: spi_dw: Add clock control MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This adds optional clock control support to the spi_dw driver. The support currently assumes that the clock control binding uses clkid for the clock cell name. Signed-off-by: Łukasz Kędziora Signed-off-by: Piotr Zierhoffer Signed-off-by: Andreas Weissel --- drivers/spi/spi_dw.c | 20 ++++++++++++++++++++ drivers/spi/spi_dw.h | 8 ++++++++ 2 files changed, 28 insertions(+) diff --git a/drivers/spi/spi_dw.c b/drivers/spi/spi_dw.c index 9f00905a3f02..587342931aea 100644 --- a/drivers/spi/spi_dw.c +++ b/drivers/spi/spi_dw.c @@ -558,6 +558,16 @@ int spi_dw_init(const struct device *dev) pinctrl_apply_state(info->pcfg, PINCTRL_STATE_DEFAULT); #endif +#if defined(CONFIG_CLOCK_CONTROL) + if (info->clk_dev) { + err = clock_control_on(info->clk_dev, info->clk_id); + if (err < 0) { + LOG_ERR("Failed to enable the clock"); + return err; + } + } +#endif + DEVICE_MMIO_MAP(dev, K_MEM_CACHE_NONE); info->config_func(); @@ -649,6 +659,15 @@ COND_CODE_1(IS_EQ(DT_NUM_IRQS(DT_DRV_INST(inst)), 1), \ (SPI_CFG_IRQS_MULTIPLE_ERR_LINES(inst))))) \ } +#if defined(CONFIG_CLOCK_CONTROL) +#define CLOCK_DW_CONFIG(n) \ + IF_ENABLED(DT_INST_NODE_HAS_PROP(0, clocks), \ + (.clk_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(n)), \ + .clk_id = (clock_control_subsys_t)DT_INST_CLOCKS_CELL(n, clkid),)) +#else +#define CLOCK_DW_CONFIG(n) +#endif + #define SPI_DW_INIT(inst) \ IF_ENABLED(CONFIG_PINCTRL, (PINCTRL_DT_INST_DEFINE(inst);)) \ SPI_DW_IRQ_HANDLER(inst); \ @@ -679,6 +698,7 @@ COND_CODE_1(IS_EQ(DT_NUM_IRQS(DT_DRV_INST(inst)), 1), \ .set_bit_func = reg_set_bit, \ .clear_bit_func = reg_clear_bit, \ .test_bit_func = reg_test_bit,)) \ + CLOCK_DW_CONFIG(inst) \ }; \ SPI_DEVICE_DT_INST_DEFINE(inst, \ spi_dw_init, \ diff --git a/drivers/spi/spi_dw.h b/drivers/spi/spi_dw.h index c91ddbf7996c..0868cd50ddee 100644 --- a/drivers/spi/spi_dw.h +++ b/drivers/spi/spi_dw.h @@ -14,6 +14,10 @@ #include #include +#if defined(CONFIG_CLOCK_CONTROL) +#include +#endif + #include "spi_context.h" #ifdef __cplusplus @@ -46,6 +50,10 @@ struct spi_dw_config { uint8_t max_xfer_size; #ifdef CONFIG_PINCTRL const struct pinctrl_dev_config *pcfg; +#endif +#if defined(CONFIG_CLOCK_CONTROL) + const struct device *clk_dev; + const clock_control_subsys_t clk_id; #endif spi_dw_read_t read_func; spi_dw_write_t write_func; From d807e39a2cbfa28d5a5b60a663c43ea9b3b95fd2 Mon Sep 17 00:00:00 2001 From: Andy Lin Date: Wed, 7 Jan 2026 01:42:17 +0800 Subject: [PATCH 2552/3659] arch: riscv: Add the support for Zbkb ISA extension Introduce the missing flag to compile code with Zbkb extension, which has already been supported by the GCC 12 in current SDK. Signed-off-by: Andy Lin --- arch/riscv/Kconfig.isa | 8 ++++++++ cmake/compiler/gcc/target_riscv.cmake | 4 ++++ 2 files changed, 12 insertions(+) diff --git a/arch/riscv/Kconfig.isa b/arch/riscv/Kconfig.isa index c5ee324464d8..f5df9b85eef1 100644 --- a/arch/riscv/Kconfig.isa +++ b/arch/riscv/Kconfig.isa @@ -237,6 +237,14 @@ config RISCV_ISA_EXT_ZBC The Zbc instructions can be used for carry-less multiplication that is the multiplication in the polynomial ring over GF(2). +config RISCV_ISA_EXT_ZBKB + bool + help + (Zbkb) - Zbkb BitManip Extension (Bit-manipulation for Cryptography) + + The Zbkb instructions can be used for accelerating cryptography workloads + and contain rotation, reversion, packing and some advanced bit-manipulation. + config RISCV_ISA_EXT_ZBS bool help diff --git a/cmake/compiler/gcc/target_riscv.cmake b/cmake/compiler/gcc/target_riscv.cmake index e440d4e2b158..656b597a393e 100644 --- a/cmake/compiler/gcc/target_riscv.cmake +++ b/cmake/compiler/gcc/target_riscv.cmake @@ -118,6 +118,10 @@ if(CONFIG_RISCV_ISA_EXT_ZBC) string(CONCAT riscv_march ${riscv_march} "_zbc") endif() +if(CONFIG_RISCV_ISA_EXT_ZBKB) + string(CONCAT riscv_march ${riscv_march} "_zbkb") +endif() + if(CONFIG_RISCV_ISA_EXT_ZBS) string(CONCAT riscv_march ${riscv_march} "_zbs") endif() From a616f7b107b0ceefd937acb3a5e64d09c8bf764b Mon Sep 17 00:00:00 2001 From: Hugues Fruchet Date: Thu, 8 Jan 2026 17:08:11 +0100 Subject: [PATCH 2553/3659] drivers: video: stm32_venc: fix release sequence Fix missing H264 library release and total memory count reset. Signed-off-by: Hugues Fruchet --- drivers/video/video_stm32_venc.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/video/video_stm32_venc.c b/drivers/video/video_stm32_venc.c index 4bbfa847b5aa..e7e4ed045def 100644 --- a/drivers/video/video_stm32_venc.c +++ b/drivers/video/video_stm32_venc.c @@ -601,12 +601,15 @@ static int encoder_start(struct stm32_venc_data *data, struct video_buffer *outp static int encoder_end(struct stm32_venc_data *data) { + struct stm32_venc_ewl *inst = &ewl_instance; H264EncIn enc_in = {0}; H264EncOut enc_out = {0}; if (data->encoder != NULL) { H264EncStrmEnd(data->encoder, &enc_in, &enc_out); + H264EncRelease(data->encoder); data->encoder = NULL; + inst->mem_cnt = 0; } return 0; From e84f19578095893967760e28dff6dfc5d0d7a60e Mon Sep 17 00:00:00 2001 From: Hugues Fruchet Date: Tue, 21 Oct 2025 17:55:00 +0200 Subject: [PATCH 2554/3659] drivers: video: stm32_venc: fix delta frames generation Only key frames were generated because of resync flag always true, fix this. Signed-off-by: Hugues Fruchet --- drivers/video/video_stm32_venc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/video/video_stm32_venc.c b/drivers/video/video_stm32_venc.c index e7e4ed045def..6994dca8b41a 100644 --- a/drivers/video/video_stm32_venc.c +++ b/drivers/video/video_stm32_venc.c @@ -647,10 +647,11 @@ static int encode_frame(struct stm32_venc_data *data) goto out; } - /* one key frame every seconds */ + /* one key frame every VENC_DEFAULT_FRAMERATE frames */ if ((data->frame_nb % VENC_DEFAULT_FRAMERATE) == 0 || data->resync) { /* if frame is the first or resync needed: set as intra coded */ enc_in.codingType = H264ENC_INTRA_FRAME; + data->resync = false; } else { /* if there was a frame previously, set as predicted */ enc_in.timeIncrement = 1; From f396ac9efcce3388a5052aa67f2ebaaa146f24aa Mon Sep 17 00:00:00 2001 From: Hugues Fruchet Date: Wed, 5 Nov 2025 17:13:04 +0100 Subject: [PATCH 2555/3659] drivers: video: stm32_venc: fix completion on interrupt Fix wait of hardware encoding completion by using interrupt signaling instead of polling on irq status. Signed-off-by: Hugues Fruchet --- drivers/video/video_stm32_venc.c | 65 +++++--------------------------- 1 file changed, 10 insertions(+), 55 deletions(-) diff --git a/drivers/video/video_stm32_venc.c b/drivers/video/video_stm32_venc.c index 6994dca8b41a..f7a7a83bb81d 100644 --- a/drivers/video/video_stm32_venc.c +++ b/drivers/video/video_stm32_venc.c @@ -349,69 +349,24 @@ i32 EWLWaitHwRdy(const void *instance, uint32_t *slices_ready) { struct stm32_venc_ewl *inst = (struct stm32_venc_ewl *)instance; const struct stm32_venc_config *config = inst->config; - int32_t ret = EWL_HW_WAIT_TIMEOUT; - volatile uint32_t irq_stats; - uint32_t prev_slices_ready = 0; - k_timepoint_t timeout = sys_timepoint_calc(K_MSEC(EWL_TIMEOUT)); uint32_t start = sys_clock_tick_get_32(); __ASSERT_NO_MSG(inst != NULL); - /* check how to clear IRQ flags for VENC */ - uint32_t clr_by_write_1 = EWLReadReg(inst, BASE_HWFuse2) & HWCFGIrqClearSupport; + if (k_sem_take(&inst->complete, K_MSEC(EWL_TIMEOUT))) { + uint32_t irq_status = sys_read32(config->reg + BASE_HEncIRQ); - do { - irq_stats = sys_read32(config->reg + BASE_HEncIRQ); - /* get the number of completed slices from ASIC registers. */ - if (slices_ready != NULL && *slices_ready > prev_slices_ready) { - *slices_ready = FIELD_GET(NUM_SLICES_READY_MASK, - sys_read32(config->reg + BASE_HEncControl7)); - } - - LOG_DBG("IRQ stat = %08x", irq_stats); - - uint32_t hw_handshake_status = IS_BIT_SET( - sys_read32(config->reg + BASE_HEncInstantInput), LOW_LATENCY_HW_ITF_EN); - - /* ignore the irq status of input line buffer in hw handshake mode */ - if ((irq_stats == ASIC_STATUS_LINE_BUFFER_DONE) && (hw_handshake_status != 0UL)) { - sys_write32(ASIC_STATUS_FUSE, config->reg + BASE_HEncIRQ); - continue; - } - - if ((irq_stats & ASIC_STATUS_ALL) != 0UL) { - /* clear IRQ and slice ready status */ - uint32_t clr_stats; - - irq_stats &= ~(ASIC_STATUS_SLICE_READY | ASIC_IRQ_LINE); - - if (clr_by_write_1 != 0UL) { - clr_stats = ASIC_STATUS_SLICE_READY | ASIC_IRQ_LINE; - } else { - clr_stats = irq_stats; - } - - sys_write32(clr_stats, config->reg + BASE_HEncIRQ); - ret = EWL_OK; - break; - } - - if (slices_ready != NULL && *slices_ready > prev_slices_ready) { - ret = EWL_OK; - break; - } - - } while (!sys_timepoint_expired(timeout)); - - if (ret != EWL_OK) { - LOG_ERR("Timeout"); - return ret; + LOG_ERR("timeout, status=0x%x", irq_status); + return EWL_HW_WAIT_TIMEOUT; } LOG_DBG("encoding = %d ms", k_ticks_to_ms_ceil32(sys_clock_tick_get_32() - start)); + /* get the number of completed slices from ASIC registers. */ if (slices_ready != NULL) { - LOG_DBG("slices_ready = %d", *slices_ready); + *slices_ready = FIELD_GET(NUM_SLICES_READY_MASK, + sys_read32(config->reg + BASE_HEncControl7)); + LOG_DBG("slices=%d", *slices_ready); } return EWL_OK; @@ -801,9 +756,9 @@ ISR_DIRECT_DECLARE(stm32_venc_isr) * and signal to EWLWaitHwRdy */ sys_write32(ASIC_STATUS_SLICE_READY | ASIC_IRQ_LINE, config->reg + BASE_HEncIRQ); - } - k_sem_give(&inst->complete); + k_sem_give(&inst->complete); + } return 0; } From 8c8a021a5f801c1569e1bd85615605ef8eb985f5 Mon Sep 17 00:00:00 2001 From: Hugues Fruchet Date: Wed, 5 Nov 2025 17:16:29 +0100 Subject: [PATCH 2556/3659] drivers: video: stm32_venc: log interrupts Log number of interrupts, including fuse interrupts at each key frame and at the end of encoding. Signed-off-by: Hugues Fruchet --- drivers/video/video_stm32_venc.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/drivers/video/video_stm32_venc.c b/drivers/video/video_stm32_venc.c index f7a7a83bb81d..7f9d3f5e1ffa 100644 --- a/drivers/video/video_stm32_venc.c +++ b/drivers/video/video_stm32_venc.c @@ -86,7 +86,10 @@ struct stm32_venc_ewl { const struct stm32_venc_config *config; struct k_sem complete; uint32_t irq_status; + + /* Stats counters (for debugging) */ uint32_t irq_cnt; + uint32_t irq_fuse_cnt; uint32_t mem_cnt; }; @@ -168,6 +171,7 @@ const void *EWLInit(EWLInitParam_t *param) /* set client type */ ewl_instance.client_type = param->clientType; ewl_instance.irq_cnt = 0; + ewl_instance.irq_fuse_cnt = 0; return (void *)&ewl_instance; } @@ -453,8 +457,11 @@ static int encoder_prepare(struct stm32_venc_data *data) H264EncPreProcessingCfg preproc_cfg = {0}; H264EncRateCtrl ratectrl_cfg = {0}; H264EncCodingCtrl codingctrl_cfg = {0}; + struct stm32_venc_ewl *inst = &ewl_instance; data->frame_nb = 0; + inst->irq_cnt = 0; + inst->irq_fuse_cnt = 0; /* set config to 1 reference frame */ cfg.refFrameAmount = 1; @@ -578,6 +585,7 @@ static int encode_frame(struct stm32_venc_data *data) struct video_buffer *output; H264EncIn enc_in = {0}; H264EncOut enc_out = {0}; + struct stm32_venc_ewl *inst = &ewl_instance; if (k_fifo_is_empty(&data->in_fifo_in) || k_fifo_is_empty(&data->out_fifo_in)) { /* Encoding deferred to next buffer queueing */ @@ -607,6 +615,9 @@ static int encode_frame(struct stm32_venc_data *data) /* if frame is the first or resync needed: set as intra coded */ enc_in.codingType = H264ENC_INTRA_FRAME; data->resync = false; + + LOG_DBG("frames=%d irq=%d fuse=%d", data->frame_nb, inst->irq_cnt, + inst->irq_fuse_cnt); } else { /* if there was a frame previously, set as predicted */ enc_in.timeIncrement = 1; @@ -679,12 +690,15 @@ static int encode_frame(struct stm32_venc_data *data) static int stm32_venc_set_stream(const struct device *dev, bool enable, enum video_buf_type type) { struct stm32_venc_data *data = dev->data; + struct stm32_venc_ewl *inst = &ewl_instance; ARG_UNUSED(type); if (!enable) { /* Stop VENC */ encoder_end(data); + LOG_DBG("frames=%d irq=%d fuse=%d", data->frame_nb, inst->irq_cnt, + inst->irq_fuse_cnt); } return 0; @@ -748,6 +762,7 @@ ISR_DIRECT_DECLARE(stm32_venc_isr) sys_write32(ASIC_STATUS_FUSE | ASIC_IRQ_LINE, config->reg + BASE_HEncIRQ); /* read back the IRQ status to update its value */ irq_status = sys_read32(config->reg + BASE_HEncIRQ); + inst->irq_fuse_cnt++; } if (irq_status != 0U) { From cc8475dd52713dd8194960e9045efb09a93a7a0c Mon Sep 17 00:00:00 2001 From: Hugues Fruchet Date: Wed, 5 Nov 2025 17:27:30 +0100 Subject: [PATCH 2557/3659] drivers: video: stm32_dcmipp: set multilines to 128 to limit interrupts Set multiline on pixel pipes to 128 lines to limit slave IP hardware handshakes and so reduce the number of interrupts received by slave IP. Signed-off-by: Hugues Fruchet --- drivers/video/video_stm32_dcmipp.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/video/video_stm32_dcmipp.c b/drivers/video/video_stm32_dcmipp.c index ef305458f8d3..50a5c9dd0131 100644 --- a/drivers/video/video_stm32_dcmipp.c +++ b/drivers/video/video_stm32_dcmipp.c @@ -1168,6 +1168,17 @@ static int stm32_dcmipp_stream_enable(const struct device *dev) if (ret < 0) { goto out; } + + /* Limit the amount of hardware handshake interrupts received by slave IP */ + if (pipe->id == DCMIPP_PIPE1) { + stm32_reg_modify_bits(&dcmipp->hdcmipp.Instance->P1PPCR, + DCMIPP_P1PPCR_LINEMULT_Msk, + DCMIPP_MULTILINE_128_LINES); + } else { + stm32_reg_modify_bits(&dcmipp->hdcmipp.Instance->P2PPCR, + DCMIPP_P1PPCR_LINEMULT_Msk, + DCMIPP_MULTILINE_128_LINES); + } } #endif From 70f57d119ac197194c5db1d93d386a6b36be5a26 Mon Sep 17 00:00:00 2001 From: Hugues Fruchet Date: Thu, 13 Nov 2025 18:20:26 +0100 Subject: [PATCH 2558/3659] drivers: video: stm32_dcmipp: give back buffers at stream disable Give back buffers at stream disable. Signed-off-by: Hugues Fruchet --- drivers/video/video_stm32_dcmipp.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/video/video_stm32_dcmipp.c b/drivers/video/video_stm32_dcmipp.c index 50a5c9dd0131..c72750a2720c 100644 --- a/drivers/video/video_stm32_dcmipp.c +++ b/drivers/video/video_stm32_dcmipp.c @@ -1240,6 +1240,7 @@ static int stm32_dcmipp_stream_disable(const struct device *dev) struct stm32_dcmipp_pipe_data *pipe = dev->data; struct stm32_dcmipp_data *dcmipp = pipe->dcmipp; const struct stm32_dcmipp_config *config = dev->config; + struct video_buffer *vbuf; int ret; k_mutex_lock(&pipe->lock, K_FOREVER); @@ -1300,6 +1301,12 @@ static int stm32_dcmipp_stream_disable(const struct device *dev) k_fifo_put(&pipe->fifo_in, pipe->active); } + /* Forward all buffers in fifo_in to fifo_out */ + while ((vbuf = k_fifo_get(&pipe->fifo_in, K_NO_WAIT)) != NULL) { + vbuf->bytesused = 0; + k_fifo_put(&pipe->fifo_out, vbuf); + } + pipe->state = STM32_DCMIPP_STOPPED; pipe->is_streaming = false; dcmipp->enabled_pipe--; From 0c0bb202c79f670c241cdc3078c02724cfaf895c Mon Sep 17 00:00:00 2001 From: Hugues Fruchet Date: Thu, 22 Jan 2026 13:48:52 +0100 Subject: [PATCH 2559/3659] samples: video: tcpserversink: fix missing input buffer encoder dequeue Fix missing input buffer encoder dequeue, this was corrupting camera device fifo because of same buffer queued into two different fifo. Signed-off-by: Hugues Fruchet --- samples/drivers/video/tcpserversink/src/main.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/samples/drivers/video/tcpserversink/src/main.c b/samples/drivers/video/tcpserversink/src/main.c index 051a30a1edce..bf99295ef798 100644 --- a/samples/drivers/video/tcpserversink/src/main.c +++ b/samples/drivers/video/tcpserversink/src/main.c @@ -187,6 +187,12 @@ int encode_frame(struct video_buffer *in, struct video_buffer **out) return ret; } + ret = video_dequeue(encoder_dev, &in, K_FOREVER); + if (ret) { + LOG_ERR("Unable to dequeue encoder input buf"); + return ret; + } + return 0; } From 9ebfb206af8eeb88ea486c0a84fb8b4382d59131 Mon Sep 17 00:00:00 2001 From: Hugues Fruchet Date: Thu, 6 Nov 2025 11:00:07 +0100 Subject: [PATCH 2560/3659] samples: video: tcpserversink: fix multiple connect/disconnect Fix multiple connect/disconnect regression introduced in 6a7aefaa samples: video: tcpserversink: check video_enqueue/dequeue return values. Signed-off-by: Hugues Fruchet --- samples/drivers/video/tcpserversink/src/main.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/samples/drivers/video/tcpserversink/src/main.c b/samples/drivers/video/tcpserversink/src/main.c index bf99295ef798..8e1c95363b33 100644 --- a/samples/drivers/video/tcpserversink/src/main.c +++ b/samples/drivers/video/tcpserversink/src/main.c @@ -422,6 +422,8 @@ int main(void) /* Connection loop */ do { + bool disconnected = false; + LOG_INF("TCP: Waiting for client..."); client = accept(sock, (struct sockaddr *)&client_addr, &client_addr_len); @@ -473,6 +475,7 @@ int main(void) vbuf_out->bytesused); /* Send compressed video buffer to TCP client */ ret = sendall(client, vbuf_out->buffer, vbuf_out->bytesused); + disconnected = ret && ret != -EAGAIN; vbuf_out->type = VIDEO_BUF_TYPE_OUTPUT; ret = video_enqueue(encoder_dev, vbuf_out); @@ -485,8 +488,9 @@ int main(void) LOG_INF("Sending frame %d", i++); /* Send video buffer to TCP client */ ret = sendall(client, vbuf->buffer, vbuf->bytesused); + disconnected = ret && ret != -EAGAIN; #endif - if (ret && ret != -EAGAIN) { + if (disconnected) { /* client disconnected */ LOG_ERR("TCP: Client disconnected %d", ret); close(client); @@ -498,7 +502,7 @@ int main(void) LOG_ERR("Unable to enqueue video buf"); return 0; } - } while (!ret); + } while (!ret && !disconnected); /* stop capture */ if (video_stream_stop(video_dev, type)) { From b0fd7d96653d78fcff305868adcf60bc35c9399c Mon Sep 17 00:00:00 2001 From: Hugues Fruchet Date: Mon, 17 Nov 2025 10:50:02 +0100 Subject: [PATCH 2561/3659] samples: video: tcpserversink: release camera frame as soon as possible Release camera frame immediately after video encoding. Doing so, the frame could be reused by camera for next capture without waiting for the end of network transmission. Signed-off-by: Hugues Fruchet --- .../drivers/video/tcpserversink/src/main.c | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/samples/drivers/video/tcpserversink/src/main.c b/samples/drivers/video/tcpserversink/src/main.c index 8e1c95363b33..d19b93b2d1ec 100644 --- a/samples/drivers/video/tcpserversink/src/main.c +++ b/samples/drivers/video/tcpserversink/src/main.c @@ -471,6 +471,13 @@ int main(void) #if DT_HAS_CHOSEN(zephyr_videoenc) encode_frame(vbuf, &vbuf_out); + vbuf->type = VIDEO_BUF_TYPE_INPUT; + ret = video_enqueue(video_dev, vbuf); + if (ret) { + LOG_ERR("Unable to enqueue video buf"); + return 0; + } + LOG_INF("Sending compressed frame %d (size=%d bytes)", i++, vbuf_out->bytesused); /* Send compressed video buffer to TCP client */ @@ -489,12 +496,6 @@ int main(void) /* Send video buffer to TCP client */ ret = sendall(client, vbuf->buffer, vbuf->bytesused); disconnected = ret && ret != -EAGAIN; -#endif - if (disconnected) { - /* client disconnected */ - LOG_ERR("TCP: Client disconnected %d", ret); - close(client); - } vbuf->type = VIDEO_BUF_TYPE_INPUT; ret = video_enqueue(video_dev, vbuf); @@ -502,6 +503,13 @@ int main(void) LOG_ERR("Unable to enqueue video buf"); return 0; } +#endif + if (disconnected) { + /* client disconnected */ + LOG_ERR("TCP: Client disconnected %d", ret); + close(client); + } + } while (!ret && !disconnected); /* stop capture */ From 59b653bb4f6d0ebe7b67e6fdb876090424b92621 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Tue, 13 Jan 2026 13:30:11 +0100 Subject: [PATCH 2562/3659] tests: net: lib: http_server: Add test case for overlapping resources Add a test case verifying that if there's a static resource defined which overlaps a FS resource pointing to a directory, it takes preference on exact URI match. Signed-off-by: Robert Lubos --- tests/net/lib/http_server/core/prj.conf | 1 + tests/net/lib/http_server/core/src/main.c | 94 +++++++++++++++++++++++ 2 files changed, 95 insertions(+) diff --git a/tests/net/lib/http_server/core/prj.conf b/tests/net/lib/http_server/core/prj.conf index 9d032dc34889..6937eda0cbc9 100644 --- a/tests/net/lib/http_server/core/prj.conf +++ b/tests/net/lib/http_server/core/prj.conf @@ -44,6 +44,7 @@ CONFIG_HTTP_SERVER_CAPTURE_HEADERS=y CONFIG_HTTP_SERVER_CAPTURE_HEADER_BUFFER_SIZE=64 CONFIG_HTTP_SERVER_CAPTURE_HEADER_COUNT=2 CONFIG_HTTP_SERVER_REPORT_FAILURE_REASON=y +CONFIG_HTTP_SERVER_RESOURCE_WILDCARD=y CONFIG_HTTP_SERVER_MAX_CLIENTS=5 CONFIG_HTTP_SERVER_MAX_STREAMS=5 diff --git a/tests/net/lib/http_server/core/src/main.c b/tests/net/lib/http_server/core/src/main.c index c372f6c8b702..03b86d26bcc6 100644 --- a/tests/net/lib/http_server/core/src/main.c +++ b/tests/net/lib/http_server/core/src/main.c @@ -2805,6 +2805,100 @@ ZTEST(server_function_tests, test_http1_static_fs_compression) zassert_mem_equal(buf, expected_response, expected_response_size, "Received data doesn't match expected response"); } + +#define TEST_DIR_OVERLAP LFS_MNTP "/testfs" +#define TEST_FILE_OVERLAP "test_file" + +static struct http_resource_detail_static_fs static_file_resource_detail_dir = { + .common = { + .type = HTTP_RESOURCE_TYPE_STATIC_FS, + .bitmask_of_supported_http_methods = BIT(HTTP_GET), + .content_type = "text/html", + }, + .fs_path = LFS_MNTP, +}; + +HTTP_RESOURCE_DEFINE(static_fs_resource_dir, test_http_service, "/testfs", + &static_file_resource_detail_dir); + +static const char static_overlap_resource_payload[] = TEST_STATIC_PAYLOAD; +struct http_resource_detail_static static_overlap_resource_detail = { + .common = { + .type = HTTP_RESOURCE_TYPE_STATIC, + .bitmask_of_supported_http_methods = BIT(HTTP_GET), + }, + .static_data = static_overlap_resource_payload, + .static_data_len = sizeof(static_overlap_resource_payload) - 1, +}; + +HTTP_RESOURCE_DEFINE(static_overlap_resource, test_http_service, "/testfs/static", + &static_overlap_resource_detail); + +static void setup_fs_with_subdir(void) +{ + test_clear_flash(); + + zassert_equal(test_unmount(), TC_PASS, "Failed to unmount fs"); + zassert_equal(test_mount(), TC_PASS, "Failed to mount fs"); + + zassert_equal(test_mkdir(TEST_DIR_OVERLAP, TEST_FILE_OVERLAP), TC_PASS, + "Failed to create dir"); +} + +/* Verify that if the filesystem resource overlaps with a statically defined one, + * the latter takes preference. + */ +ZTEST(server_function_tests, test_http1_static_fs_overlap) +{ + static const char http1_request_file[] = + "GET /testfs/test_file HTTP/1.1\r\n" + "Host: 127.0.0.1:8080\r\n" + "User-Agent: curl/7.68.0\r\n" + "Accept: */*\r\n" + "\r\n"; + static const char expected_response_file[] = + "HTTP/1.1 200 OK\r\n" + "Content-Length: 30\r\n" + "Content-Type: text/html\r\n" + "\r\n" + TEST_STATIC_FS_PAYLOAD; + static const char http1_request_static[] = + "GET /testfs/static HTTP/1.1\r\n" + "Host: 127.0.0.1:8080\r\n" + "User-Agent: curl/7.68.0\r\n" + "Accept: */*\r\n" + "\r\n"; + static const char expected_response_static[] = + "HTTP/1.1 200 OK\r\n" + "Content-Type: text/html\r\n" + "Content-Length: 13\r\n" + "\r\n" + TEST_STATIC_PAYLOAD; + size_t offset = 0; + int ret; + + setup_fs_with_subdir(); + + ret = zsock_send(client_fd, http1_request_static, strlen(http1_request_static), 0); + zassert_not_equal(ret, -1, "send() failed (%d)", errno); + + memset(buf, 0, sizeof(buf)); + + test_read_data(&offset, sizeof(expected_response_static) - 1); + zassert_mem_equal(buf, expected_response_static, sizeof(expected_response_static) - 1, + "Received data doesn't match expected response"); + + ret = zsock_send(client_fd, http1_request_file, strlen(http1_request_file), 0); + zassert_not_equal(ret, -1, "send() failed (%d)", errno); + + memset(buf, 0, sizeof(buf)); + offset = 0; + + test_read_data(&offset, sizeof(expected_response_file) - 1); + zassert_mem_equal(buf, expected_response_file, sizeof(expected_response_file) - 1, + "Received data doesn't match expected response"); +} + #endif /* DT_HAS_COMPAT_STATUS_OKAY(zephyr_ram_disk) */ static void http_server_tests_before(void *fixture) From 10b9520cacf450998150d725274a7d6b88c48e24 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Tue, 13 Jan 2026 15:25:49 +0100 Subject: [PATCH 2563/3659] net: lib: http_server: Prefer explicitly defined resources over FS ones Do direct resource path comparison on all registered resources before falling back to fnmatch() so that exact path matches get always preference. Signed-off-by: Robert Lubos --- subsys/net/lib/http/http_server_core.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/subsys/net/lib/http/http_server_core.c b/subsys/net/lib/http/http_server_core.c index 2c96c2643c85..3605e98da21c 100644 --- a/subsys/net/lib/http/http_server_core.c +++ b/subsys/net/lib/http/http_server_core.c @@ -780,22 +780,28 @@ struct http_resource_detail *get_resource_detail(const struct http_service_desc continue; } - if (IS_ENABLED(CONFIG_HTTP_SERVER_RESOURCE_WILDCARD)) { + if (compare_strings(path, resource->resource) == 0) { + NET_DBG("Got match for %s", resource->resource); + + *path_len = strlen(resource->resource); + return resource->detail; + } + } + + if (IS_ENABLED(CONFIG_HTTP_SERVER_RESOURCE_WILDCARD)) { + HTTP_SERVICE_FOREACH_RESOURCE(service, resource) { int ret; + if (skip_this(resource, is_websocket)) { + continue; + } + ret = fnmatch(resource->resource, path, (FNM_PATHNAME | FNM_LEADING_DIR)); if (ret == 0) { *path_len = path_len_without_query(path); return resource->detail; } } - - if (compare_strings(path, resource->resource) == 0) { - NET_DBG("Got match for %s", resource->resource); - - *path_len = strlen(resource->resource); - return resource->detail; - } } if (service->res_fallback != NULL) { From 2719679c2639fae1015f70d3482d5fbdd70225a0 Mon Sep 17 00:00:00 2001 From: Gaetan Perrot Date: Sat, 17 Jan 2026 02:18:33 +0900 Subject: [PATCH 2564/3659] drivers: ethernet: lan9250: fix error handling Several LAN9250 helper functions ignored return values from register access and wait routines, potentially hiding SPI or timeout failures. Propagate error codes from read/write/wait helpers throughout the driver so failures are detected and handled by callers. This improves robustness and makes error conditions visible during initialization, PHY access, RX/TX paths, and MAC configuration. Signed-off-by: Gaetan Perrot --- drivers/ethernet/eth_lan9250.c | 366 +++++++++++++++++++++++---------- 1 file changed, 262 insertions(+), 104 deletions(-) diff --git a/drivers/ethernet/eth_lan9250.c b/drivers/ethernet/eth_lan9250.c index 050e5d56f065..7557df3cdede 100644 --- a/drivers/ethernet/eth_lan9250.c +++ b/drivers/ethernet/eth_lan9250.c @@ -94,35 +94,61 @@ static int lan9250_wait_ready(const struct device *dev, uint16_t address, uint32 static int lan9250_read_mac_reg(const struct device *dev, uint8_t address, uint32_t *value) { uint32_t tmp; + int ret; /* Wait for MAC to be ready and send writing register command and data */ - lan9250_wait_ready(dev, LAN9250_MAC_CSR_CMD, LAN9250_MAC_CSR_CMD_BUSY, 0, - LAN9250_MAC_TIMEOUT); - lan9250_write_sys_reg(dev, LAN9250_MAC_CSR_CMD, - address | LAN9250_MAC_CSR_CMD_BUSY | LAN9250_MAC_CSR_CMD_READ); + ret = lan9250_wait_ready(dev, LAN9250_MAC_CSR_CMD, LAN9250_MAC_CSR_CMD_BUSY, 0, + LAN9250_MAC_TIMEOUT); + if (ret < 0) { + return ret; + } + + ret = lan9250_write_sys_reg(dev, LAN9250_MAC_CSR_CMD, + address | LAN9250_MAC_CSR_CMD_BUSY | LAN9250_MAC_CSR_CMD_READ); + if (ret < 0) { + return ret; + } /* Wait for MAC to be ready and send writing register command and data */ - lan9250_wait_ready(dev, LAN9250_MAC_CSR_CMD, LAN9250_MAC_CSR_CMD_BUSY, 0, - LAN9250_MAC_TIMEOUT); - lan9250_read_sys_reg(dev, LAN9250_MAC_CSR_DATA, &tmp); + ret = lan9250_wait_ready(dev, LAN9250_MAC_CSR_CMD, LAN9250_MAC_CSR_CMD_BUSY, 0, + LAN9250_MAC_TIMEOUT); + if (ret < 0) { + return ret; + } + + ret = lan9250_read_sys_reg(dev, LAN9250_MAC_CSR_DATA, &tmp); + if (ret < 0) { + return ret; + } *value = tmp; + return 0; } static int lan9250_write_mac_reg(const struct device *dev, uint8_t address, uint32_t data) { + int ret; /* Wait for MAC to be ready and send writing register command and data */ - lan9250_wait_ready(dev, LAN9250_MAC_CSR_CMD, LAN9250_MAC_CSR_CMD_BUSY, 0, - LAN9250_MAC_TIMEOUT); - lan9250_write_sys_reg(dev, LAN9250_MAC_CSR_DATA, data); - lan9250_write_sys_reg(dev, LAN9250_MAC_CSR_CMD, address | LAN9250_MAC_CSR_CMD_BUSY); + ret = lan9250_wait_ready(dev, LAN9250_MAC_CSR_CMD, LAN9250_MAC_CSR_CMD_BUSY, 0, + LAN9250_MAC_TIMEOUT); + if (ret < 0) { + return ret; + } - /* Wait until writing MAC is done */ - lan9250_wait_ready(dev, LAN9250_MAC_CSR_CMD, LAN9250_MAC_CSR_CMD_BUSY, 0, - LAN9250_MAC_TIMEOUT); + ret = lan9250_write_sys_reg(dev, LAN9250_MAC_CSR_DATA, data); + if (ret < 0) { + return ret; + } - return 0; + ret = lan9250_write_sys_reg(dev, LAN9250_MAC_CSR_CMD, address | LAN9250_MAC_CSR_CMD_BUSY); + if (ret < 0) { + return ret; + } + + /* Wait until writing MAC is done */ + return lan9250_wait_ready(dev, LAN9250_MAC_CSR_CMD, LAN9250_MAC_CSR_CMD_BUSY, 0, + LAN9250_MAC_TIMEOUT); } static int lan9250_wait_mac_ready(const struct device *dev, uint8_t address, uint32_t mask, @@ -147,10 +173,14 @@ static int lan9250_wait_mac_ready(const struct device *dev, uint8_t address, uin static int lan9250_read_phy_reg(const struct device *dev, uint8_t address, uint16_t *value) { uint32_t tmp; + int ret; /* Wait PHY to be ready and send reading register command */ - lan9250_wait_mac_ready(dev, LAN9250_HMAC_MII_ACC, LAN9250_HMAC_MII_ACC_MIIBZY, 0, - LAN9250_PHY_TIMEOUT); + ret = lan9250_wait_mac_ready(dev, LAN9250_HMAC_MII_ACC, LAN9250_HMAC_MII_ACC_MIIBZY, 0, + LAN9250_PHY_TIMEOUT); + if (ret < 0) { + return ret; + } /* Reference: Microchip Ethernet LAN9250 * https://github.com/microchip-pic-avr-solutions/ethernet-lan9250/ @@ -166,14 +196,24 @@ static int lan9250_read_phy_reg(const struct device *dev, uint8_t address, uint1 * Where phy_add = 0b00001 & index = address * Data = ((phy_add & 0x1F) << 11) | ((index & 0x1F) << 6) */ - lan9250_write_mac_reg(dev, LAN9250_HMAC_MII_ACC, (1 << 11) | ((address & 0x1F) << 6)); + ret = lan9250_write_mac_reg(dev, LAN9250_HMAC_MII_ACC, (1 << 11) | ((address & 0x1F) << 6)); + if (ret < 0) { + return ret; + } /* Wait PHY to be ready and send reading register command */ - lan9250_wait_mac_ready(dev, LAN9250_HMAC_MII_ACC, LAN9250_HMAC_MII_ACC_MIIBZY, 0, - LAN9250_PHY_TIMEOUT); + ret = lan9250_wait_mac_ready(dev, LAN9250_HMAC_MII_ACC, LAN9250_HMAC_MII_ACC_MIIBZY, 0, + LAN9250_PHY_TIMEOUT); + if (ret < 0) { + return ret; + } /* Read 32bit value from the indirect MAC registers */ - lan9250_read_mac_reg(dev, LAN9250_HMAC_MII_DATA, &tmp); + ret = lan9250_read_mac_reg(dev, LAN9250_HMAC_MII_DATA, &tmp); + if (ret < 0) { + return ret; + } + *value = tmp; return 0; @@ -181,10 +221,18 @@ static int lan9250_read_phy_reg(const struct device *dev, uint8_t address, uint1 static int lan9250_write_phy_reg(const struct device *dev, uint8_t address, uint16_t data) { + int ret; /* Wait PHY to be ready and send reading register command */ - lan9250_wait_mac_ready(dev, LAN9250_HMAC_MII_ACC, LAN9250_HMAC_MII_ACC_MIIBZY, 0, - LAN9250_PHY_TIMEOUT); - lan9250_write_mac_reg(dev, LAN9250_HMAC_MII_DATA, data); + ret = lan9250_wait_mac_ready(dev, LAN9250_HMAC_MII_ACC, LAN9250_HMAC_MII_ACC_MIIBZY, 0, + LAN9250_PHY_TIMEOUT); + if (ret < 0) { + return ret; + } + + ret = lan9250_write_mac_reg(dev, LAN9250_HMAC_MII_DATA, data); + if (ret < 0) { + return ret; + } /* Reference: Microchip Ethernet LAN9250 * https://github.com/microchip-pic-avr-solutions/ethernet-lan9250/ @@ -200,35 +248,45 @@ static int lan9250_write_phy_reg(const struct device *dev, uint8_t address, uint * Where phy_add = 0b00001 & index = address * Data = ((phy_add & 0x1F) << 11) | ((index & 0x1F)<< 6) | MIIWnR */ - lan9250_write_mac_reg(dev, LAN9250_HMAC_MII_ACC, - (1 << 11) | ((address & 0x1F) << 6) | LAN9250_HMAC_MII_ACC_MIIW_R); + ret = lan9250_write_mac_reg(dev, LAN9250_HMAC_MII_ACC, + (1 << 11) | ((address & 0x1F) << 6) | + LAN9250_HMAC_MII_ACC_MIIW_R); + if (ret < 0) { + return ret; + } /* Wait PHY to be ready and send reading register command */ - lan9250_wait_mac_ready(dev, LAN9250_HMAC_MII_ACC, LAN9250_HMAC_MII_ACC_MIIBZY, 0, - LAN9250_PHY_TIMEOUT); - - return 0; + return lan9250_wait_mac_ready(dev, LAN9250_HMAC_MII_ACC, LAN9250_HMAC_MII_ACC_MIIBZY, 0, + LAN9250_PHY_TIMEOUT); } static int lan9250_set_macaddr(const struct device *dev) { struct lan9250_runtime *ctx = dev->data; + int ret; - lan9250_write_mac_reg(dev, LAN9250_HMAC_ADDRL, - ctx->mac_address[0] | (ctx->mac_address[1] << 8) | - (ctx->mac_address[2] << 16) | (ctx->mac_address[3] << 24)); - lan9250_write_mac_reg(dev, LAN9250_HMAC_ADDRH, - ctx->mac_address[4] | (ctx->mac_address[5] << 8)); + ret = lan9250_write_mac_reg(dev, LAN9250_HMAC_ADDRL, + ctx->mac_address[0] | (ctx->mac_address[1] << 8) | + (ctx->mac_address[2] << 16) | + (ctx->mac_address[3] << 24)); + if (ret < 0) { + return ret; + } - return 0; + return lan9250_write_mac_reg(dev, LAN9250_HMAC_ADDRH, + ctx->mac_address[4] | (ctx->mac_address[5] << 8)); } static int lan9250_hw_cfg_check(const struct device *dev) { uint32_t tmp; + int ret; do { - lan9250_read_sys_reg(dev, LAN9250_HW_CFG, &tmp); + ret = lan9250_read_sys_reg(dev, LAN9250_HW_CFG, &tmp); + if (ret < 0) { + return ret; + } k_busy_wait(USEC_PER_MSEC * 1U); } while ((tmp & LAN9250_HW_CFG_DEVICE_READY) == 0); @@ -240,26 +298,33 @@ static int lan9250_sw_reset(const struct device *dev) int ret; ret = lan9250_write_sys_reg(dev, LAN9250_RESET_CTL, - LAN9250_RESET_CTL_HMAC_RST | - LAN9250_RESET_CTL_PHY_RST | - LAN9250_RESET_CTL_DIGITAL_RST); + LAN9250_RESET_CTL_HMAC_RST | LAN9250_RESET_CTL_PHY_RST | + LAN9250_RESET_CTL_DIGITAL_RST); if (ret < 0) { return ret; } /* Wait until LAN9250 SPI bus is ready */ - return lan9250_wait_ready(dev, LAN9250_BYTE_TEST, BOTR_MASK, - LAN9250_BYTE_TEST_DEFAULT, LAN9250_RESET_TIMEOUT); + return lan9250_wait_ready(dev, LAN9250_BYTE_TEST, BOTR_MASK, LAN9250_BYTE_TEST_DEFAULT, + LAN9250_RESET_TIMEOUT); } static int lan9250_configure(const struct device *dev) { uint32_t tmp; + int ret; - lan9250_hw_cfg_check(dev); + ret = lan9250_hw_cfg_check(dev); + if (ret < 0) { + return ret; + } /* Read LAN9250 hardware ID */ - lan9250_read_sys_reg(dev, LAN9250_ID_REV, &tmp); + ret = lan9250_read_sys_reg(dev, LAN9250_ID_REV, &tmp); + if (ret < 0) { + return ret; + } + if ((tmp & LAN9250_ID_REV_CHIP_ID) != LAN9250_ID_REV_CHIP_ID_DEFAULT) { LOG_ERR("ERROR: Bad Rev ID: %08x\n", tmp); return -ENODEV; @@ -272,8 +337,11 @@ static int lan9250_configure(const struct device *dev) * - TX status FIFO size: 512 * - RX status FIFO size: 512 */ - lan9250_write_sys_reg(dev, LAN9250_HW_CFG, - LAN9250_HW_CFG_MBO | LAN9250_HW_CFG_TX_FIF_SZ_8KB); + ret = lan9250_write_sys_reg(dev, LAN9250_HW_CFG, + LAN9250_HW_CFG_MBO | LAN9250_HW_CFG_TX_FIF_SZ_8KB); + if (ret < 0) { + return ret; + } /* Configure MAC automatic flow control: * @@ -282,7 +350,10 @@ static int lan9250_configure(const struct device *dev) * LAN_Regwrite32(AFC_CFG, 0x006E3741); * */ - lan9250_write_sys_reg(dev, LAN9250_AFC_CFG, 0x006e3741); + ret = lan9250_write_sys_reg(dev, LAN9250_AFC_CFG, 0x006e3741); + if (ret < 0) { + return ret; + } /* Configure interrupt: * @@ -291,27 +362,39 @@ static int lan9250_configure(const struct device *dev) * - Interrupt pin active output low * - Interrupt pin push-pull driver */ - lan9250_write_sys_reg(dev, LAN9250_IRQ_CFG, - LAN9250_IRQ_CFG_INT_DEAS_100US | LAN9250_IRQ_CFG_IRQ_EN | - LAN9250_IRQ_CFG_IRQ_TYPE_PP); + ret = lan9250_write_sys_reg(dev, LAN9250_IRQ_CFG, + LAN9250_IRQ_CFG_INT_DEAS_100US | LAN9250_IRQ_CFG_IRQ_EN | + LAN9250_IRQ_CFG_IRQ_TYPE_PP); + if (ret < 0) { + return ret; + } /* Configure interrupt trigger source, please refer to macro * LAN9250_INT_SOURCE. */ - lan9250_write_sys_reg(dev, LAN9250_INT_EN, - LAN9250_INT_EN_PHY_INT_EN | LAN9250_INT_EN_RSFL_EN); + ret = lan9250_write_sys_reg(dev, LAN9250_INT_EN, + LAN9250_INT_EN_PHY_INT_EN | LAN9250_INT_EN_RSFL_EN); + if (ret < 0) { + return ret; + } /* Disable TX data FIFO available interrupt */ - lan9250_write_sys_reg(dev, LAN9250_FIFO_INT, - LAN9250_FIFO_INT_TX_DATA_AVAILABLE_LEVEL | - LAN9250_FIFO_INT_TX_STATUS_LEVEL); + ret = lan9250_write_sys_reg(dev, LAN9250_FIFO_INT, + LAN9250_FIFO_INT_TX_DATA_AVAILABLE_LEVEL | + LAN9250_FIFO_INT_TX_STATUS_LEVEL); + if (ret < 0) { + return ret; + } /* Configure RX: * * - RX DMA counter: Ethernet maximum packet size * - RX data offset: 4, so that need read dummy before reading data */ - lan9250_write_sys_reg(dev, LAN9250_RX_CFG, 0x06000000 | 0x00000400); + ret = lan9250_write_sys_reg(dev, LAN9250_RX_CFG, 0x06000000 | 0x00000400); + if (ret < 0) { + return ret; + } /* Configure remote power management: * @@ -322,19 +405,25 @@ static int lan9250_configure(const struct device *dev) * - Wake on * - Clear wakeon */ - lan9250_write_sys_reg(dev, LAN9250_PMT_CTRL, - LAN9250_PMT_CTRL_PM_WAKE | LAN9250_PMT_CTRL_1588_DIS | - LAN9250_PMT_CTRL_1588_TSU_DIS | LAN9250_PMT_CTRL_WOL_EN | - LAN9250_PMT_CTRL_WOL_STS); + ret = lan9250_write_sys_reg(dev, LAN9250_PMT_CTRL, + LAN9250_PMT_CTRL_PM_WAKE | LAN9250_PMT_CTRL_1588_DIS | + LAN9250_PMT_CTRL_1588_TSU_DIS | + LAN9250_PMT_CTRL_WOL_EN | LAN9250_PMT_CTRL_WOL_STS); + if (ret < 0) { + return ret; + } /* Configure PHY basic control: * * - Auto-Negotiation for 10/100 Mbits and Half/Full Duplex */ - lan9250_write_phy_reg(dev, LAN9250_PHY_BASIC_CONTROL, - LAN9250_PHY_BASIC_CONTROL_PHY_AN | - LAN9250_PHY_BASIC_CONTROL_PHY_SPEED_SEL_LSB | - LAN9250_PHY_BASIC_CONTROL_PHY_DUPLEX); + ret = lan9250_write_phy_reg(dev, LAN9250_PHY_BASIC_CONTROL, + LAN9250_PHY_BASIC_CONTROL_PHY_AN | + LAN9250_PHY_BASIC_CONTROL_PHY_SPEED_SEL_LSB | + LAN9250_PHY_BASIC_CONTROL_PHY_DUPLEX); + if (ret < 0) { + return ret; + } /* Configure PHY auto-negotiation advertisement capability: * @@ -344,18 +433,25 @@ static int lan9250_configure(const struct device *dev) * - 10Base-X half/full duplex * - Select IEEE802.3 */ - lan9250_write_phy_reg(dev, LAN9250_PHY_AN_ADV, - LAN9250_PHY_AN_ADV_ASYM_PAUSE | LAN9250_PHY_AN_ADV_SYM_PAUSE | - LAN9250_PHY_AN_ADV_100BTX_HD | LAN9250_PHY_AN_ADV_100BTX_FD | - LAN9250_PHY_AN_ADV_10BT_HD | LAN9250_PHY_AN_ADV_10BT_FD | - LAN9250_PHY_AN_ADV_SELECTOR_DEFAULT); + ret = lan9250_write_phy_reg( + dev, LAN9250_PHY_AN_ADV, + LAN9250_PHY_AN_ADV_ASYM_PAUSE | LAN9250_PHY_AN_ADV_SYM_PAUSE | + LAN9250_PHY_AN_ADV_100BTX_HD | LAN9250_PHY_AN_ADV_100BTX_FD | + LAN9250_PHY_AN_ADV_10BT_HD | LAN9250_PHY_AN_ADV_10BT_FD | + LAN9250_PHY_AN_ADV_SELECTOR_DEFAULT); + if (ret < 0) { + return ret; + } /* Configure PHY special mode: * * - PHY mode = 111b, enable all capable and auto-nagotiation * - PHY address = 1, default value is fixed to 1 by manufacturer */ - lan9250_write_phy_reg(dev, LAN9250_PHY_SPECIAL_MODES, 0x00E0 | 1); + ret = lan9250_write_phy_reg(dev, LAN9250_PHY_SPECIAL_MODES, 0x00E0 | 1); + if (ret < 0) { + return ret; + } /* Configure PHY special control or status indication: * @@ -363,29 +459,41 @@ static int lan9250_configure(const struct device *dev) * - Auto-MDIX * - Disable SQE tests */ - lan9250_write_phy_reg(dev, LAN9250_PHY_SPECIAL_CONTROL_STAT_IND, - LAN9250_PHY_SPECIAL_CONTROL_STAT_IND_AMDIXCTRL | - LAN9250_PHY_SPECIAL_CONTROL_STAT_IND_AMDIXEN | - LAN9250_PHY_SPECIAL_CONTROL_STAT_IND_SQEOFF); + ret = lan9250_write_phy_reg(dev, LAN9250_PHY_SPECIAL_CONTROL_STAT_IND, + LAN9250_PHY_SPECIAL_CONTROL_STAT_IND_AMDIXCTRL | + LAN9250_PHY_SPECIAL_CONTROL_STAT_IND_AMDIXEN | + LAN9250_PHY_SPECIAL_CONTROL_STAT_IND_SQEOFF); + if (ret < 0) { + return ret; + } /* Configure PHY interrupt source: * * - Link up * - Link down */ - lan9250_write_phy_reg(dev, LAN9250_PHY_INTERRUPT_MASK, - LAN9250_PHY_INTERRUPT_SOURCE_LINK_UP | - LAN9250_PHY_INTERRUPT_SOURCE_LINK_DOWN); + ret = lan9250_write_phy_reg(dev, LAN9250_PHY_INTERRUPT_MASK, + LAN9250_PHY_INTERRUPT_SOURCE_LINK_UP | + LAN9250_PHY_INTERRUPT_SOURCE_LINK_DOWN); + if (ret < 0) { + return ret; + } /* Configure special control or status: * * - Fixed to write 0000010b to reserved filed */ - lan9250_write_phy_reg(dev, LAN9250_PHY_SPECIAL_CONTROL_STATUS, - LAN9250_PHY_MODE_CONTROL_STATUS_ALTINT); + ret = lan9250_write_phy_reg(dev, LAN9250_PHY_SPECIAL_CONTROL_STATUS, + LAN9250_PHY_MODE_CONTROL_STATUS_ALTINT); + if (ret < 0) { + return ret; + } /* Clear interrupt status */ - lan9250_write_sys_reg(dev, LAN9250_INT_STS, 0xFFFFFFFF); + ret = lan9250_write_sys_reg(dev, LAN9250_INT_STS, 0xFFFFFFFF); + if (ret < 0) { + return ret; + } /* Configure HMAC control: * @@ -397,18 +505,18 @@ static int lan9250_configure(const struct device *dev) * - Hash filtering disabled * - Promiscuous disabled */ - lan9250_write_mac_reg(dev, LAN9250_HMAC_CR, - LAN9250_HMAC_CR_PADSTR | LAN9250_HMAC_CR_FDPX | - LAN9250_HMAC_CR_TXEN | LAN9250_HMAC_CR_RXEN | - LAN9250_HMAC_CR_MCPAS); + ret = lan9250_write_mac_reg(dev, LAN9250_HMAC_CR, + LAN9250_HMAC_CR_PADSTR | LAN9250_HMAC_CR_TXEN | + LAN9250_HMAC_CR_RXEN | LAN9250_HMAC_CR_FDPX); + if (ret < 0) { + return ret; + } /* Configure TX: * * - TX enable */ - lan9250_write_sys_reg(dev, LAN9250_TX_CFG, LAN9250_TX_CFG_TX_ON); - - return 0; + return lan9250_write_sys_reg(dev, LAN9250_TX_CFG, LAN9250_TX_CFG_TX_ON); } static int lan9250_write_buf(const struct device *dev, uint8_t *data_buffer, uint16_t buf_len) @@ -465,13 +573,20 @@ static int lan9250_rx(const struct device *dev) uint16_t pkt_len; uint8_t pktcnt; uint32_t tmp; + int ret; /* Check valid packet count */ - lan9250_read_sys_reg(dev, LAN9250_RX_FIFO_INF, &tmp); + ret = lan9250_read_sys_reg(dev, LAN9250_RX_FIFO_INF, &tmp); + if (ret < 0) { + return ret; + } pktcnt = (tmp & 0x00ff0000) >> 16; /* Check packet length */ - lan9250_read_sys_reg(dev, LAN9250_RX_STATUS_FIFO, &tmp); + ret = lan9250_read_sys_reg(dev, LAN9250_RX_STATUS_FIFO, &tmp); + if (ret < 0) { + return ret; + } pkt_len = (tmp & LAN9250_RX_STS_PACKET_LEN) >> 16; if (pktcnt == 0 || pkt_len == 0) { @@ -479,7 +594,10 @@ static int lan9250_rx(const struct device *dev) } /* Read dummy data */ - lan9250_read_sys_reg(dev, LAN9250_RX_DATA_FIFO, &tmp); + ret = lan9250_read_sys_reg(dev, LAN9250_RX_DATA_FIFO, &tmp); + if (ret < 0) { + return ret; + } pkt_len -= 4; if (pkt_len > NET_ETH_MAX_FRAME_SIZE) { @@ -509,12 +627,18 @@ static int lan9250_rx(const struct device *dev) } pkt_len -= data_len; - lan9250_read_buf(dev, data_ptr, data_len); + ret = lan9250_read_buf(dev, data_ptr, data_len); + if (ret < 0) { + return ret; + } net_buf_add(pkt_buf, data_len); pkt_buf = pkt_buf->frags; } while (pkt_len > 0); - lan9250_read_sys_reg(dev, LAN9250_RX_DATA_FIFO, &tmp); + ret = lan9250_read_sys_reg(dev, LAN9250_RX_DATA_FIFO, &tmp); + if (ret < 0) { + return ret; + } net_pkt_set_iface(pkt, ctx->iface); /* Feed buffer frame to IP stack */ @@ -535,30 +659,48 @@ static int lan9250_tx(const struct device *dev, struct net_pkt *pkt) uint16_t free_size; uint8_t status_size; uint32_t tmp; + int ret; + + ret = lan9250_read_sys_reg(dev, LAN9250_TX_FIFO_INF, ®val); + if (ret < 0) { + return ret; + } - lan9250_read_sys_reg(dev, LAN9250_TX_FIFO_INF, ®val); status_size = (regval & LAN9250_TX_FIFO_INF_TXSUSED) >> 16; free_size = regval & LAN9250_TX_FIFO_INF_TXFREE; k_sem_take(&ctx->tx_rx_sem, K_FOREVER); /* TX command 'A' */ - lan9250_write_sys_reg(dev, LAN9250_TX_DATA_FIFO, - LAN9250_TX_CMD_A_INT_ON_COMP | LAN9250_TX_CMD_A_BUFFER_ALIGN_4B | - LAN9250_TX_CMD_A_START_OFFSET_0B | - LAN9250_TX_CMD_A_FIRST_SEG | LAN9250_TX_CMD_A_LAST_SEG | len); + ret = lan9250_write_sys_reg( + dev, LAN9250_TX_DATA_FIFO, + LAN9250_TX_CMD_A_INT_ON_COMP | LAN9250_TX_CMD_A_BUFFER_ALIGN_4B | + LAN9250_TX_CMD_A_START_OFFSET_0B | LAN9250_TX_CMD_A_FIRST_SEG | + LAN9250_TX_CMD_A_LAST_SEG | len); + if (ret < 0) { + return ret; + } /* TX command 'B' */ - lan9250_write_sys_reg(dev, LAN9250_TX_DATA_FIFO, LAN9250_TX_CMD_B_PACKET_TAG | len); + ret = lan9250_write_sys_reg(dev, LAN9250_TX_DATA_FIFO, LAN9250_TX_CMD_B_PACKET_TAG | len); + if (ret < 0) { + return ret; + } if (net_pkt_read(pkt, ctx->buf, len)) { return -EIO; } - lan9250_write_buf(dev, ctx->buf, LAN9250_ALIGN(len)); + ret = lan9250_write_buf(dev, ctx->buf, LAN9250_ALIGN(len)); + if (ret < 0) { + return ret; + } for (int i = 0; i < status_size; i++) { - lan9250_read_sys_reg(dev, LAN9250_TX_STATUS_FIFO, &tmp); + ret = lan9250_read_sys_reg(dev, LAN9250_TX_STATUS_FIFO, &tmp); + if (ret < 0) { + return ret; + } } k_sem_give(&ctx->tx_rx_sem); @@ -647,12 +789,17 @@ static int lan9250_set_config(const struct device *dev, enum ethernet_config_typ const struct ethernet_config *config) { struct lan9250_runtime *ctx = dev->data; + int ret; switch (type) { case ETHERNET_CONFIG_TYPE_MAC_ADDRESS: memcpy(ctx->mac_address, config->mac_address.addr, sizeof(ctx->mac_address)); - lan9250_set_macaddr(dev); + ret = lan9250_set_macaddr(dev); + if (ret < 0) { + LOG_ERR("Set mac address failed"); + return ret; + } LOG_INF("%s MAC set to %02x:%02x:%02x:%02x:%02x:%02x", dev->name, @@ -668,7 +815,10 @@ static int lan9250_set_config(const struct device *dev, enum ethernet_config_typ if (IS_ENABLED(CONFIG_NET_PROMISCUOUS_MODE)) { uint32_t reg; - lan9250_read_mac_reg(dev, LAN9250_HMAC_CR, ®); + ret = lan9250_read_mac_reg(dev, LAN9250_HMAC_CR, ®); + if (ret < 0) { + return ret; + } /* See Table 11-1 from the LAN9250 data sheet */ if (config->promisc_mode) { @@ -775,10 +925,18 @@ static int lan9250_init(const struct device *dev) LOG_ERR("Reset failed"); return ret; } - lan9250_configure(dev); + ret = lan9250_configure(dev); + if (ret < 0) { + LOG_ERR("Configuration failed"); + return ret; + } (void)net_eth_mac_load(&config->mac_cfg, context->mac_address); - lan9250_set_macaddr(dev); + ret = lan9250_set_macaddr(dev); + if (ret < 0) { + LOG_ERR("Set mac address failed"); + return ret; + } k_thread_create(&context->thread, context->thread_stack, CONFIG_ETH_LAN9250_RX_THREAD_STACK_SIZE, From f18da88e3f2484199318e81aeb25dadb35e31450 Mon Sep 17 00:00:00 2001 From: Gaetan Perrot Date: Tue, 20 Jan 2026 02:02:51 +0900 Subject: [PATCH 2565/3659] drivers: ethernet: lan9250: fix uninitialized variable warning The lan9250_thread() function declares a local variable that may be used without being initialized, triggering a -Wmaybe-uninitialized warning when building with -Werror. Initialize the variable at declaration to ensure deterministic behavior and avoid build failures. No functional change intended. Signed-off-by: Gaetan Perrot --- drivers/ethernet/eth_lan9250.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ethernet/eth_lan9250.c b/drivers/ethernet/eth_lan9250.c index 7557df3cdede..c722e61beab3 100644 --- a/drivers/ethernet/eth_lan9250.c +++ b/drivers/ethernet/eth_lan9250.c @@ -723,7 +723,7 @@ static void lan9250_thread(void *p1, void *p2, void *p3) const struct device *dev = p1; struct lan9250_runtime *context = dev->data; uint32_t int_sts; - uint16_t tmp; + uint16_t tmp = 0; uint32_t ier; while (true) { From ed545d230275648be0630fcc4439647d9cd226d5 Mon Sep 17 00:00:00 2001 From: Gaetan Perrot Date: Thu, 22 Jan 2026 01:20:17 +0900 Subject: [PATCH 2566/3659] drivers: ethernet: lan9250: Make interrupt mask constant unsigned Add a 'U' suffix to the interrupt status mask passed to lan9250_write_sys_reg() to make the constant explicitly unsigned. This avoids signed/unsigned ambiguity and addresses a SonarQube static analysis warning. Signed-off-by: Gaetan Perrot --- drivers/ethernet/eth_lan9250.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ethernet/eth_lan9250.c b/drivers/ethernet/eth_lan9250.c index c722e61beab3..c6699898fbb5 100644 --- a/drivers/ethernet/eth_lan9250.c +++ b/drivers/ethernet/eth_lan9250.c @@ -490,7 +490,7 @@ static int lan9250_configure(const struct device *dev) } /* Clear interrupt status */ - ret = lan9250_write_sys_reg(dev, LAN9250_INT_STS, 0xFFFFFFFF); + ret = lan9250_write_sys_reg(dev, LAN9250_INT_STS, 0xFFFFFFFFU); if (ret < 0) { return ret; } From 7af0a2fcdf5ebf8ce56017c15827b8871e657f9a Mon Sep 17 00:00:00 2001 From: Gaetan Perrot Date: Wed, 21 Jan 2026 18:55:15 +0900 Subject: [PATCH 2567/3659] sensor: adi: adxl372: stream: check return value of adxl372_set_op_mode Check the return value of adxl372_set_op_mode() in adxl372_submit_stream() and abort on error. Fix CID: 516239 Signed-off-by: Gaetan Perrot --- drivers/sensor/adi/adxl372/adxl372_stream.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/sensor/adi/adxl372/adxl372_stream.c b/drivers/sensor/adi/adxl372/adxl372_stream.c index 0555109b8023..f2b59f68b622 100644 --- a/drivers/sensor/adi/adxl372/adxl372_stream.c +++ b/drivers/sensor/adi/adxl372/adxl372_stream.c @@ -114,7 +114,10 @@ void adxl372_submit_stream(const struct device *dev, struct rtio_iodev_sqe *iode adxl372_configure_fifo(dev, current_fifo_mode, data->fifo_config.fifo_format, data->fifo_config.fifo_samples); - adxl372_set_op_mode(dev, cfg_372->op_mode); + rc = adxl372_set_op_mode(dev, cfg_372->op_mode); + if (rc < 0) { + return; + } } rc = gpio_pin_interrupt_configure_dt(&cfg_372->interrupt, GPIO_INT_EDGE_TO_ACTIVE); From 8402a4f8e5b49c09f65bbfb7d93164375eceaf4b Mon Sep 17 00:00:00 2001 From: Pieter De Gendt Date: Wed, 21 Jan 2026 11:17:47 +0100 Subject: [PATCH 2568/3659] drivers: gpio: mcux: Fix updating ICR registers without IRQ lock During configuration the base->ICR1 or base->ICR2 register is written without an IRQ lock. This can result in unwanted side-effects if the status bit isn't cleared, or the edge select still needs to be updated. Signed-off-by: Pieter De Gendt --- drivers/gpio/gpio_mcux_igpio.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/gpio/gpio_mcux_igpio.c b/drivers/gpio/gpio_mcux_igpio.c index f55df0746ae8..6e0240d9d5d1 100644 --- a/drivers/gpio/gpio_mcux_igpio.c +++ b/drivers/gpio/gpio_mcux_igpio.c @@ -292,6 +292,10 @@ static int mcux_igpio_pin_interrupt_configure(const struct device *dev, return -ENOTSUP; } + if (pin >= 32) { + return -EINVAL; + } + if (mode == GPIO_INT_MODE_DISABLED) { key = irq_lock(); @@ -314,18 +318,16 @@ static int mcux_igpio_pin_interrupt_configure(const struct device *dev, icr = 0; } + key = irq_lock(); + if (pin < 16) { shift = 2 * pin; base->ICR1 = (base->ICR1 & ~(3 << shift)) | (icr << shift); - } else if (pin < 32) { + } else { shift = 2 * (pin - 16); base->ICR2 = (base->ICR2 & ~(3 << shift)) | (icr << shift); - } else { - return -EINVAL; } - key = irq_lock(); - WRITE_BIT(base->EDGE_SEL, pin, trig == GPIO_INT_TRIG_BOTH); WRITE_BIT(base->ISR, pin, 1); WRITE_BIT(base->IMR, pin, 1); From f64a999147e74e95739bf61fec5562c0d2ca0955 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Wed, 21 Jan 2026 12:24:22 +0200 Subject: [PATCH 2569/3659] drivers: bluetooth: silabs_efr32: Fix default for max PAwR advertisers This option already depends on BT_PER_ADV_RSP being enabled, so we should have a more reasonable default for it. This way e.g. the existing PAwR sample app should work without additional changes. Signed-off-by: Johan Hedberg --- drivers/bluetooth/hci/Kconfig.silabs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/bluetooth/hci/Kconfig.silabs b/drivers/bluetooth/hci/Kconfig.silabs index 74188c1f1387..a5a4014a53ca 100644 --- a/drivers/bluetooth/hci/Kconfig.silabs +++ b/drivers/bluetooth/hci/Kconfig.silabs @@ -164,7 +164,7 @@ if BT_PER_ADV_RSP config BT_SILABS_EFR32_MAX_PAWR_ADVERTISERS int "Maximum numbers of Periodic Advertising With Response advertisers" - default 0 + default 1 range 0 BT_SILABS_EFR32_MAX_PERIODIC_ADVERTISERS config BT_SILABS_EFR32_MAX_PAWR_ADVERTISED_DATA_LENGTH_HINT From de04861e294c9db18f6f948c19de45fd0d150ed7 Mon Sep 17 00:00:00 2001 From: Fabrice DJIATSA Date: Wed, 21 Jan 2026 11:48:36 +0100 Subject: [PATCH 2570/3659] samples: sensor: stream_drdy: fix invalid dt enums in overlays Fix Devicetree compilation errors caused by incorrect enum macro names used in DTS overlay files. Replace LSM6DSV16X_DT_ODR_AT_120Hz with the correct Devicetree enum LSM6DSVXXX_DT_ODR_AT_120Hz in the stream_drdy sample boards overlay. Signed-off-by: Fabrice DJIATSA --- samples/sensor/stream_drdy/boards/nucleo_f401re.overlay | 2 +- samples/sensor/stream_drdy/boards/nucleo_h503rb.overlay | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/samples/sensor/stream_drdy/boards/nucleo_f401re.overlay b/samples/sensor/stream_drdy/boards/nucleo_f401re.overlay index 012cf89d9a8c..79be674ebe2d 100644 --- a/samples/sensor/stream_drdy/boards/nucleo_f401re.overlay +++ b/samples/sensor/stream_drdy/boards/nucleo_f401re.overlay @@ -22,7 +22,7 @@ lsm6dsv16x_6b_x_nucleo_iks4a1: lsm6dsv16x@6b { compatible = "st,lsm6dsv16x"; reg = <0x6b>; - accel-odr = ; + accel-odr = ; accel-range = ; int2-gpios = <&arduino_header 10 GPIO_ACTIVE_HIGH>; /* D4 (PB5) */ drdy-pin = <2>; diff --git a/samples/sensor/stream_drdy/boards/nucleo_h503rb.overlay b/samples/sensor/stream_drdy/boards/nucleo_h503rb.overlay index 012cf89d9a8c..79be674ebe2d 100644 --- a/samples/sensor/stream_drdy/boards/nucleo_h503rb.overlay +++ b/samples/sensor/stream_drdy/boards/nucleo_h503rb.overlay @@ -22,7 +22,7 @@ lsm6dsv16x_6b_x_nucleo_iks4a1: lsm6dsv16x@6b { compatible = "st,lsm6dsv16x"; reg = <0x6b>; - accel-odr = ; + accel-odr = ; accel-range = ; int2-gpios = <&arduino_header 10 GPIO_ACTIVE_HIGH>; /* D4 (PB5) */ drdy-pin = <2>; From d1e8918332c1420f40b2f857c3372c4f30c1db22 Mon Sep 17 00:00:00 2001 From: Fabrice DJIATSA Date: Wed, 21 Jan 2026 11:51:08 +0100 Subject: [PATCH 2571/3659] boards: shields: x_nucleo_dfx01m2: fix invalid dt enums in overlays Fix the panel pixel format enum in the X-NUCLEO-GFX01M2 shield overlay by using PANEL_PIXEL_FORMAT_RGB_565 as defined in panel dt-bindings. Signed-off-by: Fabrice DJIATSA --- boards/shields/x_nucleo_gfx01m2/x_nucleo_gfx01m2.overlay | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boards/shields/x_nucleo_gfx01m2/x_nucleo_gfx01m2.overlay b/boards/shields/x_nucleo_gfx01m2/x_nucleo_gfx01m2.overlay index 812fa68422d9..641a5e294029 100644 --- a/boards/shields/x_nucleo_gfx01m2/x_nucleo_gfx01m2.overlay +++ b/boards/shields/x_nucleo_gfx01m2/x_nucleo_gfx01m2.overlay @@ -74,7 +74,7 @@ width = <240>; height = <320>; rotation = <180>; - pixel-format = ; + pixel-format = ; frmctr1 = [00 1f]; /* 60Hz frame rate */ }; }; From c64c13e5256da78311eb970becc99c6be121b203 Mon Sep 17 00:00:00 2001 From: Mathieu Choplain Date: Wed, 21 Jan 2026 11:40:36 +0100 Subject: [PATCH 2572/3659] soc: st: stm32: cleanup linker scripts of STM32MP1 series STM32MP1 series used a custom SOC_LINKER_SCRIPT, but all it did was include the main Cortex-M script, unnecessarily re-include headers already included by the main script(!) and add a custom section. Get rid of the custom SOC_LINKER_SCRIPT but keep the custom section by moving it to a linker script snippet file, added to the build system using CMake directives. Signed-off-by: Mathieu Choplain --- soc/st/stm32/stm32mp1x/CMakeLists.txt | 4 +++- soc/st/stm32/stm32mp1x/linker.ld | 25 ------------------------- soc/st/stm32/stm32mp1x/rsc_table.ld | 9 +++++++++ 3 files changed, 12 insertions(+), 26 deletions(-) delete mode 100644 soc/st/stm32/stm32mp1x/linker.ld create mode 100644 soc/st/stm32/stm32mp1x/rsc_table.ld diff --git a/soc/st/stm32/stm32mp1x/CMakeLists.txt b/soc/st/stm32/stm32mp1x/CMakeLists.txt index 65004cceca8c..99cf221d1d7c 100644 --- a/soc/st/stm32/stm32mp1x/CMakeLists.txt +++ b/soc/st/stm32/stm32mp1x/CMakeLists.txt @@ -9,4 +9,6 @@ zephyr_sources( zephyr_include_directories(.) -set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld CACHE INTERNAL "") +zephyr_linker_sources_ifdef(CONFIG_OPENAMP_RSC_TABLE ROM_SECTIONS rsc_table.ld) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/st/stm32/stm32mp1x/linker.ld b/soc/st/stm32/stm32mp1x/linker.ld deleted file mode 100644 index 65c4a77d34fc..000000000000 --- a/soc/st/stm32/stm32mp1x/linker.ld +++ /dev/null @@ -1,25 +0,0 @@ -/* linker.ld - Linker command/script file */ - -/* - * Copyright (c) 2019 STMicroelectronics - * - * SPDX-License-Identifier: Apache-2.0 - */ - - -#include - -SECTIONS - { - -#include -#include - -#ifdef CONFIG_OPENAMP_RSC_TABLE - - SECTION_PROLOGUE(.resource_table,, SUBALIGN(4)) - { - KEEP(*(.resource_table*)) - } GROUP_LINK_IN(ROMABLE_REGION) -#endif -} diff --git a/soc/st/stm32/stm32mp1x/rsc_table.ld b/soc/st/stm32/stm32mp1x/rsc_table.ld new file mode 100644 index 000000000000..56bcf64f6648 --- /dev/null +++ b/soc/st/stm32/stm32mp1x/rsc_table.ld @@ -0,0 +1,9 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2019-2026 STMicroelectronics + * SPDX-License-Identifier: Apache-2.0 + */ + +SECTION_PROLOGUE(.resource_table,, SUBALIGN(4)) +{ + KEEP(*(.resource_table*)) +} GROUP_LINK_IN(ROMABLE_REGION) From 7a8bc1cdced63b00a09e23a8b0bf2ec4ea82d946 Mon Sep 17 00:00:00 2001 From: Mathieu Choplain Date: Wed, 21 Jan 2026 11:43:51 +0100 Subject: [PATCH 2573/3659] soc: st: stm32: cleanup linker script of STM32MP2 series Remove inclusion of files already included by the arch linker script from the SoC-specific linker script. Signed-off-by: Mathieu Choplain --- soc/st/stm32/stm32mp2x/m33/linker.ld | 7 ------- 1 file changed, 7 deletions(-) diff --git a/soc/st/stm32/stm32mp2x/m33/linker.ld b/soc/st/stm32/stm32mp2x/m33/linker.ld index a26493a726a9..5437c57b9410 100644 --- a/soc/st/stm32/stm32mp2x/m33/linker.ld +++ b/soc/st/stm32/stm32mp2x/m33/linker.ld @@ -9,10 +9,3 @@ #define rom_start .isr_vectors #include - -SECTIONS -{ - /* Standard Zephyr relocation section */ -#include -#include -} From 08f8223d5564a79e9ae15528633249a53922431e Mon Sep 17 00:00:00 2001 From: Gaetan Perrot Date: Thu, 22 Jan 2026 16:56:37 +0900 Subject: [PATCH 2574/3659] boards: phytec: phyboard_atlas: xip: fix typos in comments Fix spelling and wording issues in comments for phytec phyboard_atlas xip FlexSPI NOR configuration headers. No functional change. Signed-off-by: Gaetan Perrot --- .../phyboard_atlas/xip/phycore_rt1170_flexspi_nor_config.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/boards/phytec/phyboard_atlas/xip/phycore_rt1170_flexspi_nor_config.h b/boards/phytec/phyboard_atlas/xip/phycore_rt1170_flexspi_nor_config.h index c3eca7df6b7e..a43425e7d0bc 100644 --- a/boards/phytec/phyboard_atlas/xip/phycore_rt1170_flexspi_nor_config.h +++ b/boards/phytec/phyboard_atlas/xip/phycore_rt1170_flexspi_nor_config.h @@ -113,7 +113,7 @@ enum { FLEXSPI_MISC_OFFSET_SAFE_CONFIG_FREQ_ENABLE = 4, /* Bit for Pad setting override enable */ FLEXSPI_MISC_OFFSET_PAD_SETTING_OVERRIDE_ENABLE = 5, - /* Bit for DDR clock confiuration indication. */ + /* Bit for DDR clock configuration indication. */ FLEXSPI_MISC_OFFSET_DDR_MODE_ENABLE = 6, }; @@ -239,7 +239,7 @@ typedef struct flexspi_config { * 8 - Octal */ uint8_t sflash_pad_type; - /* [0x046-0x046] Serial Flash Frequencey, device specific + /* [0x046-0x046] Serial Flash Frequency, device specific * definitions, See System Boot Chapter for more details */ uint8_t serial_clk_freq; @@ -355,7 +355,7 @@ typedef struct _flexspi_nor_config { uint8_t need_exit_nocmd_mode; /* Half the Serial Clock for non-read command: true/false */ uint8_t half_clk_for_non_read_cmd; - /* Need to Restore NoCmd mode after IP commmand execution */ + /* Need to Restore NoCmd mode after IP command execution */ uint8_t need_restore_nocmd_mode; /* Block size */ uint32_t block_size; From 9535aebafefcb5cc98f39268d300cd2e7d710c1c Mon Sep 17 00:00:00 2001 From: Marcelo Roberto Jimenez Date: Sun, 14 Dec 2025 19:38:08 -0300 Subject: [PATCH 2575/3659] drivers: flash: flash_shell.c: Run clang-format before patch This patch runs clang-format on the flash_shell.c file before the real patch gets applied, otherwise the changes would be hard to read. Signed-off-by: Marcelo Roberto Jimenez --- drivers/flash/flash_shell.c | 102 +++++++++++++++--------------------- 1 file changed, 42 insertions(+), 60 deletions(-) diff --git a/drivers/flash/flash_shell.c b/drivers/flash/flash_shell.c index 77fb7af3a785..718c5946eefe 100644 --- a/drivers/flash/flash_shell.c +++ b/drivers/flash/flash_shell.c @@ -50,9 +50,8 @@ static const struct device *const zephyr_flash_controller = static uint8_t __aligned(4) test_arr[CONFIG_FLASH_SHELL_BUFFER_SIZE]; -static int parse_helper(const struct shell *sh, size_t *argc, - char **argv[], const struct device * *flash_dev, - uint32_t *addr) +static int parse_helper(const struct shell *sh, size_t *argc, char **argv[], + const struct device **flash_dev, uint32_t *addr) { char *endptr; @@ -109,12 +108,13 @@ static int cmd_erase(const struct shell *sh, size_t argc, char *argv[]) } else { struct flash_pages_info info; - result = flash_get_page_info_by_offs(flash_dev, page_addr, - &info); + result = flash_get_page_info_by_offs(flash_dev, page_addr, &info); if (result != 0) { - shell_error(sh, "Could not determine page size, " - "code %d.", result); + shell_error(sh, + "Could not determine page size, " + "code %d.", + result); return -EINVAL; } @@ -275,8 +275,7 @@ static int cmd_test(const struct shell *sh, size_t argc, char *argv[]) size = strtoul(argv[2], NULL, 16); repeat = strtoul(argv[3], NULL, 16); if (size > CONFIG_FLASH_SHELL_BUFFER_SIZE) { - shell_error(sh, " must be at most 0x%x.", - CONFIG_FLASH_SHELL_BUFFER_SIZE); + shell_error(sh, " must be at most 0x%x.", CONFIG_FLASH_SHELL_BUFFER_SIZE); return -EINVAL; } @@ -332,7 +331,7 @@ static int cmd_test(const struct shell *sh, size_t argc, char *argv[]) } #ifdef CONFIG_FLASH_SHELL_TEST_COMMANDS -const static uint8_t speed_types[][4] = { "B", "KiB", "MiB", "GiB" }; +const static uint8_t speed_types[][4] = {"B", "KiB", "MiB", "GiB"}; const static uint32_t speed_divisor = 1024; static int read_write_erase_validate(const struct shell *sh, size_t argc, char *argv[], @@ -645,11 +644,11 @@ static void bypass_cb(const struct shell *sh, uint8_t *recv, size_t len, void *u if (flash_load_boff == flash_load_buf_size) { uint32_t addr = flash_load_addr + flash_load_written; int rc = flash_write(flash_load_dev, addr, flash_load_buf, - flash_load_buf_size); + flash_load_buf_size); if (rc != 0) { - shell_error(sh, "Write to addr %x on dev %p ERROR!", - addr, flash_load_dev); + shell_error(sh, "Write to addr %x on dev %p ERROR!", addr, + flash_load_dev); } shell_print(sh, "Written chunk %d", flash_load_chunk); @@ -664,15 +663,14 @@ static void bypass_cb(const struct shell *sh, uint8_t *recv, size_t len, void *u * at the end. */ if (flash_load_written < flash_load_total && - flash_load_written + flash_load_boff >= flash_load_total) { + flash_load_written + flash_load_boff >= flash_load_total) { uint32_t addr = flash_load_addr + flash_load_written; int rc = flash_write(flash_load_dev, addr, flash_load_buf, flash_load_boff); if (rc != 0) { set_bypass(sh, NULL); - shell_error(sh, "Write to addr %x on dev %p ERROR!", - addr, flash_load_dev); + shell_error(sh, "Write to addr %x on dev %p ERROR!", addr, flash_load_dev); return; } @@ -715,7 +713,7 @@ static int cmd_load(const struct shell *sh, size_t argc, char *argv[]) if (flash_load_buf_size < write_block_size) { shell_error(sh, "Size of buffer is too small to be aligned to %zu.", - write_block_size); + write_block_size); return -ENOSPC; } @@ -725,7 +723,7 @@ static int cmd_load(const struct shell *sh, size_t argc, char *argv[]) shell_warn(sh, "Load buffer was not aligned to %zu.", write_block_size); shell_warn(sh, "Effective load buffer size was set from %d to %d", - FLASH_LOAD_BUF_MAX, flash_load_buf_size); + FLASH_LOAD_BUF_MAX, flash_load_buf_size); } /* Prepare data for callback. */ @@ -761,8 +759,8 @@ static int cmd_page_info(const struct shell *sh, size_t argc, char *argv[]) return -EINVAL; } - shell_print(sh, "Page for address 0x%x:\nstart offset: 0x%lx\nsize: %zu\nindex: %d", - addr, info.start_offset, info.size, info.index); + shell_print(sh, "Page for address 0x%x:\nstart offset: 0x%lx\nsize: %zu\nindex: %d", addr, + info.start_offset, info.size, info.index); return 0; } @@ -794,56 +792,41 @@ static void device_name_get(size_t idx, struct shell_static_entry *entry) entry->syntax = (dev != NULL) ? dev->name : NULL; entry->handler = NULL; - entry->help = NULL; + entry->help = NULL; entry->subcmd = &dsub_device_name; } -SHELL_STATIC_SUBCMD_SET_CREATE(flash_cmds, +SHELL_STATIC_SUBCMD_SET_CREATE( + flash_cmds, SHELL_CMD_ARG(copy, &dsub_device_name, - " ", - cmd_copy, 5, 5), - SHELL_CMD_ARG(erase, &dsub_device_name, - "[] []", - cmd_erase, 2, 2), - SHELL_CMD_ARG(read, &dsub_device_name, - "[]

    []", - cmd_read, 2, 2), - SHELL_CMD_ARG(test, &dsub_device_name, - "[]
    ", - cmd_test, 4, 1), - SHELL_CMD_ARG(write, &dsub_device_name, - "[]
    [...]", - cmd_write, 3, BUF_ARRAY_CNT), - SHELL_CMD_ARG(load, &dsub_device_name, - "[]
    ", - cmd_load, 3, 1), - SHELL_CMD_ARG(page_info, &dsub_device_name, - "[]
    ", - cmd_page_info, 2, 1), + " ", cmd_copy, 5, 5), + SHELL_CMD_ARG(erase, &dsub_device_name, "[] []", cmd_erase, 2, + 2), + SHELL_CMD_ARG(read, &dsub_device_name, "[]
    []", cmd_read, 2, + 2), + SHELL_CMD_ARG(test, &dsub_device_name, "[]
    ", + cmd_test, 4, 1), + SHELL_CMD_ARG(write, &dsub_device_name, "[]
    [...]", + cmd_write, 3, BUF_ARRAY_CNT), + SHELL_CMD_ARG(load, &dsub_device_name, "[]
    ", cmd_load, 3, 1), + SHELL_CMD_ARG(page_info, &dsub_device_name, "[]
    ", cmd_page_info, 2, 1), #if DT_HAS_COMPAT_STATUS_OKAY(fixed_partitions) - SHELL_CMD_ARG(partitions, &dsub_device_name, - "", - cmd_partitions, 0, 0), + SHELL_CMD_ARG(partitions, &dsub_device_name, "", cmd_partitions, 0, 0), #endif #ifdef CONFIG_FLASH_SHELL_TEST_COMMANDS - SHELL_CMD_ARG(read_test, &dsub_device_name, - "[]
    ", - cmd_read_test, 4, 1), - SHELL_CMD_ARG(write_test, &dsub_device_name, - "[]
    ", - cmd_write_test, 4, 1), - SHELL_CMD_ARG(erase_test, &dsub_device_name, - "[]
    ", - cmd_erase_test, 4, 1), + SHELL_CMD_ARG(read_test, &dsub_device_name, "[]
    ", + cmd_read_test, 4, 1), + SHELL_CMD_ARG(write_test, &dsub_device_name, "[]
    ", + cmd_write_test, 4, 1), + SHELL_CMD_ARG(erase_test, &dsub_device_name, "[]
    ", + cmd_erase_test, 4, 1), SHELL_CMD_ARG(erase_write_test, &dsub_device_name, - "[]
    ", - cmd_erase_write_test, 4, 1), + "[]
    ", cmd_erase_write_test, 4, 1), #endif - SHELL_SUBCMD_SET_END -); + SHELL_SUBCMD_SET_END); static int cmd_flash(const struct shell *sh, size_t argc, char **argv) { @@ -851,5 +834,4 @@ static int cmd_flash(const struct shell *sh, size_t argc, char **argv) return -EINVAL; } -SHELL_CMD_ARG_REGISTER(flash, &flash_cmds, "Flash shell commands", - cmd_flash, 2, 0); +SHELL_CMD_ARG_REGISTER(flash, &flash_cmds, "Flash shell commands", cmd_flash, 2, 0); From ec8472c36298a3070ffcef055a43770ca9dec5ad Mon Sep 17 00:00:00 2001 From: Marcelo Roberto Jimenez Date: Mon, 15 Dec 2025 20:13:24 -0300 Subject: [PATCH 2576/3659] tests: subsys: shell: Clang-format on shell_flash_test.c This patch runs clang-format on the shell_flash_test.c file before the real patch gets applied, otherwise the changes would be hard to read. Signed-off-by: Marcelo Roberto Jimenez --- tests/subsys/shell/shell_flash/src/shell_flash_test.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/subsys/shell/shell_flash/src/shell_flash_test.c b/tests/subsys/shell/shell_flash/src/shell_flash_test.c index f4c51f595146..065d41dcf082 100644 --- a/tests/subsys/shell/shell_flash/src/shell_flash_test.c +++ b/tests/subsys/shell/shell_flash/src/shell_flash_test.c @@ -38,7 +38,7 @@ ZTEST(shell_flash, test_flash_read) const struct device *const flash_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_flash_controller)); const char *buf; const int test_base = FLASH_SIMULATOR_BASE_OFFSET; - const int test_size = 0x24; /* 32-alignment required */ + const int test_size = 0x24; /* 32-alignment required */ uint8_t data[test_size]; size_t size; int ret; @@ -48,8 +48,7 @@ ZTEST(shell_flash, test_flash_read) data[i] = 'A' + i; } - zassert_true(device_is_ready(flash_dev), - "Simulated flash driver not ready"); + zassert_true(device_is_ready(flash_dev), "Simulated flash driver not ready"); ret = flash_write(flash_dev, test_base, data, test_size); zassert_equal(0, ret, "flash_write() failed: %d", ret); From 391ca7c7de35a9419e83c8a118b36ebfc66d887a Mon Sep 17 00:00:00 2001 From: Marcelo Roberto Jimenez Date: Sun, 14 Dec 2025 19:46:29 -0300 Subject: [PATCH 2577/3659] drivers: flash: flash_shell.c: Fix parsing of "flash read" The parsing of the number of bytes to read in the read command was being done in hexadecimal, causing unexpected behavior. Now the number can be interpreted in decimal or hexadecimal if prefixed with 0x. Signed-off-by: Marcelo Roberto Jimenez --- drivers/flash/flash_shell.c | 2 +- tests/subsys/shell/shell_flash/src/shell_flash_test.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/flash/flash_shell.c b/drivers/flash/flash_shell.c index 718c5946eefe..e0ffd51dc39a 100644 --- a/drivers/flash/flash_shell.c +++ b/drivers/flash/flash_shell.c @@ -234,7 +234,7 @@ static int cmd_read(const struct shell *sh, size_t argc, char *argv[]) } if (argc > 2) { - cnt = strtoul(argv[2], NULL, 16); + cnt = strtoul(argv[2], NULL, 0); } else { cnt = 1; } diff --git a/tests/subsys/shell/shell_flash/src/shell_flash_test.c b/tests/subsys/shell/shell_flash/src/shell_flash_test.c index 065d41dcf082..345d6c0c33cb 100644 --- a/tests/subsys/shell/shell_flash/src/shell_flash_test.c +++ b/tests/subsys/shell/shell_flash/src/shell_flash_test.c @@ -53,7 +53,7 @@ ZTEST(shell_flash, test_flash_read) ret = flash_write(flash_dev, test_base, data, test_size); zassert_equal(0, ret, "flash_write() failed: %d", ret); - ret = shell_execute_cmd(NULL, "flash read 0 23"); + ret = shell_execute_cmd(NULL, "flash read 0 0x23"); zassert_equal(0, ret, "flash read failed: %d", ret); buf = shell_backend_dummy_get_output(sh, &size); From 1ab8978e66624400ff341b8c17f37d6729051c09 Mon Sep 17 00:00:00 2001 From: Marcelo Roberto Jimenez Date: Sun, 14 Dec 2025 19:54:06 -0300 Subject: [PATCH 2578/3659] drivers: flash: flash_shell.c: Fix flash read help text Actually, the parameter is the number of bytes to read, not the number of double words. Signed-off-by: Marcelo Roberto Jimenez --- drivers/flash/flash_shell.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/flash/flash_shell.c b/drivers/flash/flash_shell.c index e0ffd51dc39a..b750227c7b19 100644 --- a/drivers/flash/flash_shell.c +++ b/drivers/flash/flash_shell.c @@ -802,7 +802,7 @@ SHELL_STATIC_SUBCMD_SET_CREATE( " ", cmd_copy, 5, 5), SHELL_CMD_ARG(erase, &dsub_device_name, "[] []", cmd_erase, 2, 2), - SHELL_CMD_ARG(read, &dsub_device_name, "[]
    []", cmd_read, 2, + SHELL_CMD_ARG(read, &dsub_device_name, "[]
    []", cmd_read, 2, 2), SHELL_CMD_ARG(test, &dsub_device_name, "[]
    ", cmd_test, 4, 1), From 92df06bf1d48363f42a8e5af45861c6a7d81ffd1 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 5 Jan 2026 16:10:11 +0100 Subject: [PATCH 2579/3659] boards: native: nrf_bsim: Add simple model of LDREX/STREX/CLREX Add a model of LDREX/STREX/CLREX, that although simple may be correct enough to cover the needs of SW using these instructions. Signed-off-by: Alberto Escolar Piedras --- boards/native/nrf_bsim/common/cmsis/cmsis.c | 153 ++++++++++++++++++ boards/native/nrf_bsim/common/cmsis/cmsis.h | 2 + .../nrf_bsim/common/cmsis/cmsis_instr.h | 117 +------------- boards/native/nrf_bsim/irq_handler.c | 1 + 4 files changed, 163 insertions(+), 110 deletions(-) diff --git a/boards/native/nrf_bsim/common/cmsis/cmsis.c b/boards/native/nrf_bsim/common/cmsis/cmsis.c index dac5f82e699e..c241e3a7b3d6 100644 --- a/boards/native/nrf_bsim/common/cmsis/cmsis.c +++ b/boards/native/nrf_bsim/common/cmsis/cmsis.c @@ -97,3 +97,156 @@ void __SEV(void) { nrfbsim_SEV_model(); } + +/* + * Implement the following ARM instructions + * + * - STR Exclusive(8,16 & 32bit) (__STREX{B,H,W}) + * - LDR Exclusive(8,16 & 32bit) (__LDREX{B,H,W}) + * - CLREX : Exclusive lock removal (__CLREX) + * + * Description: + * From ARMs description it is relatively unclear how the LDREX/STREX/CLREX + * are really implemented in M4/M33 devices. + * + * The current model simply sets a local monitor (local to the processor) + * exclusive lock for the current MCU when a LDREX is executed. + * STREX check this lock, and succeeds if set, fails otherwise. + * The lock is cleared whenever STREX or CLREX are run, or when we return + * from an interrupt handler. + * See Arm v8-M Architecture Reference Manual: "B9.2 The local monitors" and + * "B9.4 Exclusive access instructions and the monitors". + * + * The address is ignored, and we do not model a "system/global" monitor. + * The access width is ignored from the locking point of view. + * In principle this model would seem to fulfill the functionality described + * by ARM. + * + * Note that as the POSIX arch will not make an embedded + * thread lose context while just executing its own code, and it does not + * allow parallel embedded SW threads to execute at the same exact time, + * there is no real need to protect atomicity. + * But, some embedded code may use this instructions in between busy waits, + * and expect that an interrupt in the meanwhile will indeed cause a + * following STREX to fail. + * + * As this ARM exclusive access monitor mechanism can in principle be + * used for other, unexpected, purposes, this simple replacement may not be + * enough. + */ + +static bool ex_lock; /* LDREX/STREX/CLREX lock state */ + +bool nrfbsim_STREXlock_model(void) +{ + if (ex_lock == false) { + return true; + } + + ex_lock = false; + return false; +} + +void nrfbsim_clear_excl_access(void) +{ + ex_lock = false; +} + +/** + * \brief Pretend to execute a STR Exclusive (8 bit) + * \details Executes an exclusive STR instruction for 8 bit values. + * \param [in] value Value to store + * \param [in] ptr Pointer to location + * \return 0 Function succeeded + * \return 1 Function did not succeeded (value not changed) + */ +uint32_t __STREXB(uint8_t value, volatile uint8_t *ptr) +{ + if (nrfbsim_STREXlock_model()) { + return 1; + } + *ptr = value; + return 0; +} + +/** + * \brief Pretend to execute a STR Exclusive (16 bit) + * \details Executes a exclusive STR instruction for 16 bit values. + * \param [in] value Value to store + * \param [in] ptr Pointer to location + * \return 0 Function succeeded + * \return 1 Function did not succeeded (value not changed) + */ +uint32_t __STREXH(uint16_t value, volatile uint16_t *ptr) +{ + if (nrfbsim_STREXlock_model()) { + return 1; + } + *ptr = value; + return 0; +} + +/** + * \brief Pretend to execute a STR Exclusive (32 bit) + * \details Executes a exclusive~ STR instruction for 32 bit values. + * \param [in] value Value to store + * \param [in] ptr Pointer to location + * \return 0 Function succeeded + * \return 1 Function did not succeeded (value not changed) + */ +uint32_t __STREXW(uint32_t value, volatile uint32_t *ptr) +{ + if (nrfbsim_STREXlock_model()) { + return 1; + } + *ptr = value; + return 0; +} + +/** + * \brief Pretend to execute a LDR Exclusive (8 bit) + * \details Executes an exclusive LDR instruction for 8 bit value. + * Meaning, set an exclusive lock, and load the stored value + * \param [in] ptr Pointer to data + * \return value of type uint8_t at (*ptr) + */ +uint8_t __LDREXB(volatile uint8_t *ptr) +{ + ex_lock = true; + return *ptr; +} + +/** + * \brief Pretend to execute a LDR Exclusive (16 bit) + * \details Executes an ~exclusive~ LDR instruction for 16 bit value. + * Meaning, set an exclusive lock, and load the stored value + * \param [in] ptr Pointer to data + * \return value of type uint8_t at (*ptr) + */ +uint16_t __LDREXH(volatile uint16_t *ptr) +{ + ex_lock = true; + return *ptr; +} + +/** + * \brief Execute a LDR Exclusive (32 bit) + * \details Executes an exclusive LDR instruction for 32 bit value. + * Meaning, set an exclusive lock, and load the stored value + * \param [in] ptr Pointer to data + * \return value of type uint8_t at (*ptr) + */ +uint32_t __LDREXW(volatile uint32_t *ptr) +{ + ex_lock = true; + return *ptr; +} + +/** + * \brief Remove the exclusive lock + * \details Removes the exclusive lock which is created by LDREX + */ +void __CLREX(void) +{ + ex_lock = false; +} diff --git a/boards/native/nrf_bsim/common/cmsis/cmsis.h b/boards/native/nrf_bsim/common/cmsis/cmsis.h index 25a9fe4d6578..490e9af8025c 100644 --- a/boards/native/nrf_bsim/common/cmsis/cmsis.h +++ b/boards/native/nrf_bsim/common/cmsis/cmsis.h @@ -36,6 +36,8 @@ void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority); uint32_t NVIC_GetPriority(IRQn_Type IRQn); void NVIC_SystemReset(void); +void nrfbsim_clear_excl_access(void); + #ifdef __cplusplus } #endif diff --git a/boards/native/nrf_bsim/common/cmsis/cmsis_instr.h b/boards/native/nrf_bsim/common/cmsis/cmsis_instr.h index e3dfd2aad232..619c68d75490 100644 --- a/boards/native/nrf_bsim/common/cmsis/cmsis_instr.h +++ b/boards/native/nrf_bsim/common/cmsis/cmsis_instr.h @@ -40,116 +40,13 @@ void __WFE(void); void __WFI(void); void __SEV(void); -/* - * Implement the following ARM intrinsics as non-exclusive accesses - * - * - STR Exclusive(8,16 & 32bit) (__STREX{B,H,W}) - * - LDR Exclusive(8,16 & 32bit) (__LDREX{B,H,W}) - * - CLREX : Exclusive lock removal (__CLREX) - no-op - * - * Description: - * These accesses always succeed, and do NOT set any kind of internal - * exclusive access flag; - * There is no local/global memory monitors, MPU control of what are - * shareable regions, exclusive reservations granules, automatic clearing - * on context switch, or so. - * - * This should be enough for the expected uses of LDR/STREXB - * (locking mutexes or guarding other atomic operations, inside a few lines - * of code in the same function): As the POSIX arch will not make an embedded - * thread lose context while just executing its own code, and it does not - * allow parallel embedded SW threads to execute at the same exact time, - * there is no actual need to protect atomicity. - * - * But as this ARM exclusive access monitor mechanism can in principle be - * used for other, unexpected, purposes, this simple replacement may not be - * enough. - */ - -/** - * \brief Pretend to execute a STR Exclusive (8 bit) - * \details Executes a ~exclusive~ STR instruction for 8 bit values. - * \param [in] value Value to store - * \param [in] ptr Pointer to location - * \return 0 Function succeeded (always) - */ -static inline uint32_t __STREXB(uint8_t value, volatile uint8_t *ptr) -{ - *ptr = value; - return 0; -} - -/** - * \brief Pretend to execute a STR Exclusive (16 bit) - * \details Executes a ~exclusive~ STR instruction for 16 bit values. - * \param [in] value Value to store - * \param [in] ptr Pointer to location - * \return 0 Function succeeded (always) - */ -static inline uint32_t __STREXH(uint16_t value, volatile uint16_t *ptr) -{ - *ptr = value; - return 0; -} - -/** - * \brief Pretend to execute a STR Exclusive (32 bit) - * \details Executes a ~exclusive~ STR instruction for 32 bit values. - * \param [in] value Value to store - * \param [in] ptr Pointer to location - * \return 0 Function succeeded (always) - */ -static inline uint32_t __STREXW(uint32_t value, volatile uint32_t *ptr) -{ - *ptr = value; - return 0; -} - -/** - * \brief Pretend to execute a LDR Exclusive (8 bit) - * \details Executes an ~exclusive~ LDR instruction for 8 bit value. - * Meaning, it does not set a exclusive lock, - * instead just loads the stored value - * \param [in] ptr Pointer to data - * \return value of type uint8_t at (*ptr) - */ -static inline uint8_t __LDREXB(volatile uint8_t *ptr) -{ - return *ptr; -} - -/** - * \brief Pretend to execute a LDR Exclusive (16 bit) - * \details Executes an ~exclusive~ LDR instruction for 16 bit value. - * Meaning, it does not set a exclusive lock, - * instead just loads the stored value - * \param [in] ptr Pointer to data - * \return value of type uint8_t at (*ptr) - */ -static inline uint16_t __LDREXH(volatile uint16_t *ptr) -{ - return *ptr; -} - -/** - * \brief Pretend to execute a LDR Exclusive (32 bit) - * \details Executes an ~exclusive~ LDR instruction for 32 bit value. - * Meaning, it does not set a exclusive lock, - * instead just loads the stored value - * \param [in] ptr Pointer to data - * \return value of type uint8_t at (*ptr) - */ -static inline uint32_t __LDREXW(volatile uint32_t *ptr) -{ - return *ptr; -} - -/** - * \brief Pretend to remove the exclusive lock - * \details The real function would removes the exclusive lock which is created - * by LDREX, this one does nothing - */ -static inline void __CLREX(void) { /* Nothing to be done */ } +uint32_t __STREXB(uint8_t value, volatile uint8_t *ptr); +uint32_t __STREXH(uint16_t value, volatile uint16_t *ptr); +uint32_t __STREXW(uint32_t value, volatile uint32_t *ptr); +uint8_t __LDREXB(volatile uint8_t *ptr); +uint16_t __LDREXH(volatile uint16_t *ptr); +uint32_t __LDREXW(volatile uint32_t *ptr); +void __CLREX(void); /** * \brief Model of an ARM CLZ instruction diff --git a/boards/native/nrf_bsim/irq_handler.c b/boards/native/nrf_bsim/irq_handler.c index 74d0dc5889ee..502be495def7 100644 --- a/boards/native/nrf_bsim/irq_handler.c +++ b/boards/native/nrf_bsim/irq_handler.c @@ -117,6 +117,7 @@ void posix_irq_handler(void) currently_running_irq = irq_nbr; vector_to_irq(irq_nbr, &may_swap); + nrfbsim_clear_excl_access(); currently_running_irq = last_running_irq; hw_irq_ctrl_reeval_level_irq(cpu_n, irq_nbr); From b84bdbcee34ecb8bb7ea1d5792086cf70ddce3f2 Mon Sep 17 00:00:00 2001 From: Wolfgang Betz Date: Tue, 13 Jan 2026 10:22:51 +0100 Subject: [PATCH 2580/3659] dts: arm: st: n6: Use dedicated dts node for NPU cache (aka CACHEAXI) The new node is called "npu_cache". This way a possibility is offered to choose - thru an overlay - if to enable the NPU cache or not. This new node has a dependency with node "npu", so the NPU cache's status is taken into account only in case node "npu" has status "okay". Default status value of "npu_cache" is "okay" (i.e. enable the NPU cache). Signed-off-by: Wolfgang Betz --- dts/arm/st/n6/stm32n6.dtsi | 15 +++-- dts/bindings/misc/st,stm32-npu-cache.yaml | 18 ++++++ soc/st/stm32/stm32n6x/CMakeLists.txt | 1 + soc/st/stm32/stm32n6x/Kconfig | 8 +-- soc/st/stm32/stm32n6x/npu/Kconfig | 30 +++++++++ soc/st/stm32/stm32n6x/npu/npu_cache_stm32n6.c | 63 +++++++++++++++++++ soc/st/stm32/stm32n6x/npu/npu_stm32n6.c | 22 ++++--- 7 files changed, 136 insertions(+), 21 deletions(-) create mode 100644 dts/bindings/misc/st,stm32-npu-cache.yaml create mode 100644 soc/st/stm32/stm32n6x/npu/Kconfig create mode 100644 soc/st/stm32/stm32n6x/npu/npu_cache_stm32n6.c diff --git a/dts/arm/st/n6/stm32n6.dtsi b/dts/arm/st/n6/stm32n6.dtsi index 2facbb234784..4ceb43cd1994 100644 --- a/dts/arm/st/n6/stm32n6.dtsi +++ b/dts/arm/st/n6/stm32n6.dtsi @@ -1362,14 +1362,19 @@ npu: npu@580e0000 { compatible = "st,stm32-npu"; reg = <0x580e0000 DT_SIZE_K(128)>; - clocks = <&rcc STM32_CLOCK(AHB5, 31)>, - <&rcc STM32_CLOCK(AHB5, 30)>; - clock-names = "npu", "cacheaxi"; - resets = <&rctl STM32_RESET(AHB5, 31)>, - <&rctl STM32_RESET(AHB5, 30)>; + clocks = <&rcc STM32_CLOCK(AHB5, 31)>; + resets = <&rctl STM32_RESET(AHB5, 31)>; status = "disabled"; }; + npu_cache: cache-controller@580dfc00 { + compatible = "st,stm32-npu-cache"; + reg = <0x580dfc00 DT_SIZE_K(1)>; + clocks = <&rcc STM32_CLOCK(AHB5, 30)>; + resets = <&rctl STM32_RESET(AHB5, 30)>; + status = "okay"; + }; + venc: venc@58005000 { compatible = "st,stm32-venc"; reg = <0x58005000 0x1000>; diff --git a/dts/bindings/misc/st,stm32-npu-cache.yaml b/dts/bindings/misc/st,stm32-npu-cache.yaml new file mode 100644 index 000000000000..fc80627059d8 --- /dev/null +++ b/dts/bindings/misc/st,stm32-npu-cache.yaml @@ -0,0 +1,18 @@ +# Copyright (c) 2026 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +description: STM32N6 NPU cache (aka CACHEAXI) block + +compatible: "st,stm32-npu-cache" + +include: [reset-device.yaml, base.yaml] + +properties: + reg: + required: true + + clocks: + required: true + + resets: + required: true diff --git a/soc/st/stm32/stm32n6x/CMakeLists.txt b/soc/st/stm32/stm32n6x/CMakeLists.txt index eb2d26e6a1c9..b177fa3f95fa 100644 --- a/soc/st/stm32/stm32n6x/CMakeLists.txt +++ b/soc/st/stm32/stm32n6x/CMakeLists.txt @@ -7,6 +7,7 @@ zephyr_sources( zephyr_sources_ifdef(CONFIG_STM32N6_NPU npu/npu_stm32n6.c + npu/npu_cache_stm32n6.c ) zephyr_include_directories(.) diff --git a/soc/st/stm32/stm32n6x/Kconfig b/soc/st/stm32/stm32n6x/Kconfig index e3aba615e544..96a5e683f81f 100644 --- a/soc/st/stm32/stm32n6x/Kconfig +++ b/soc/st/stm32/stm32n6x/Kconfig @@ -30,12 +30,6 @@ if SOC_SERIES_STM32N6X config STM32N6_BOOT_SERIAL bool "Serial boot target (USB)" -config STM32N6_NPU - bool "Neural-ART accelerator (NPU)" - select RESET - default y - depends on DT_HAS_ST_STM32_NPU_ENABLED - config STM32N6_RIF_OPEN bool "Configure the RIF with all OPEN access" default y @@ -45,4 +39,6 @@ config STM32N6_RIF_OPEN configured during SoC initialization. Zephyr running with Secure privileges has full access to all SoC resources. +source "soc/st/stm32/stm32n6x/npu/Kconfig" + endif # SOC_SERIES_STM32N6X diff --git a/soc/st/stm32/stm32n6x/npu/Kconfig b/soc/st/stm32/stm32n6x/npu/Kconfig new file mode 100644 index 000000000000..9cfec5a6746d --- /dev/null +++ b/soc/st/stm32/stm32n6x/npu/Kconfig @@ -0,0 +1,30 @@ +# STMicroelectronics STM32N6 MCU series + +# Copyright (c) 2026 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +config STM32N6_NPU + bool "Neural-ART accelerator (NPU)" + select RESET + default y + depends on DT_HAS_ST_STM32_NPU_ENABLED + +config STM32N6_NPU_INIT_PRIORITY + int "STM32N6 NPU init priority" + default KERNEL_INIT_PRIORITY_DEFAULT + depends on STM32N6_NPU + help + STM32N6 NPU initialization priority. + + Note: This value must have a higher priority (i.e., lower numerical value) + than `STM32N6_NPU_CACHE_INIT_PRIORITY`! + +config STM32N6_NPU_CACHE_INIT_PRIORITY + int "STM32N6 NPU cache (aka CACHEAXI) init priority" + default APPLICATION_INIT_PRIORITY + depends on STM32N6_NPU + help + STM32N6 NPU cache (aka CACHEAXI) initialization priority. + + Note: This value must have a lower priority (i.e., higher numerical value) + than `STM32N6_NPU_INIT_PRIORITY`! diff --git a/soc/st/stm32/stm32n6x/npu/npu_cache_stm32n6.c b/soc/st/stm32/stm32n6x/npu/npu_cache_stm32n6.c new file mode 100644 index 000000000000..a69aa096ee9e --- /dev/null +++ b/soc/st/stm32/stm32n6x/npu/npu_cache_stm32n6.c @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2026 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT st_stm32_npu_cache + +#include +#include +#include +#include + +#define NPU_CACHE_NODE DT_DRV_INST(0) +#define NPU_CACHE_BASE DT_REG_ADDR(NPU_CACHE_NODE) + +#define NPU_CACHE_CTRL_REG_OFFSET 0x0 +#define NPU_CACHE_ERR_IRQ_OFFSET 0x8 +#define NPU_CACHE_DISABLE 0x0 +#define NPU_CACHE_ENABLE 0x1 +#define NPU_CACHE_CNT_ENABLE 0x33330000 +#define NPU_CACHE_CNT_RESET 0xCCCC0000 +#define NPU_CACHE_ERR_IRQ_ENABLE BIT(2) + +/* + * Define npu_cache_stm32_enable and instantiate the device only if both + * the NPU and NPU cache nodes are enabled in the device tree. + * This avoids unused function warnings when the cache is disabled. + */ +#if DT_NODE_HAS_STATUS_OKAY(DT_INST(0, st_stm32_npu)) && \ + DT_NODE_HAS_STATUS_OKAY(DT_INST(0, st_stm32_npu_cache)) +static int npu_cache_stm32_enable(const struct device *dev) +{ + /* Disable cache */ + sys_write32(NPU_CACHE_DISABLE, NPU_CACHE_BASE + NPU_CACHE_CTRL_REG_OFFSET); + + k_busy_wait(5 * USEC_PER_MSEC); /* 5ms delay */ + + /* Enable cache */ + sys_write32(NPU_CACHE_ENABLE, NPU_CACHE_BASE + NPU_CACHE_CTRL_REG_OFFSET); + + /* Enable cache counters */ + sys_set_bits(NPU_CACHE_BASE + NPU_CACHE_CTRL_REG_OFFSET, NPU_CACHE_CNT_ENABLE); + + /* Reset cache counters */ + sys_set_bits(NPU_CACHE_BASE + NPU_CACHE_CTRL_REG_OFFSET, NPU_CACHE_CNT_RESET); + + /* Enable cache error interrupt */ + sys_write32(NPU_CACHE_ERR_IRQ_ENABLE, NPU_CACHE_BASE + NPU_CACHE_ERR_IRQ_OFFSET); + + return 0; +} + +DEVICE_DT_INST_DEFINE(0, npu_cache_stm32_enable, NULL, NULL, NULL, POST_KERNEL, + CONFIG_STM32N6_NPU_CACHE_INIT_PRIORITY, NULL); + +/* + * Guarantee that initialization priority for the NPU is higher than the one of the NPU cache (aka + * CACHEAXI) + */ +BUILD_ASSERT(CONFIG_STM32N6_NPU_CACHE_INIT_PRIORITY > CONFIG_STM32N6_NPU_INIT_PRIORITY, + "NPU cache initialization must run after NPU driver initialization"); +#endif /* st_stm32_npu && st_stm32_npu_cache */ diff --git a/soc/st/stm32/stm32n6x/npu/npu_stm32n6.c b/soc/st/stm32/stm32n6x/npu/npu_stm32n6.c index 4c437281aedc..1bfa8ef24fbf 100644 --- a/soc/st/stm32/stm32n6x/npu/npu_stm32n6.c +++ b/soc/st/stm32/stm32n6x/npu/npu_stm32n6.c @@ -34,11 +34,11 @@ static int npu_stm32_init(const struct device *dev) return -ENODEV; } - if (clock_control_on(clk, (clock_control_subsys_t) &cfg->pclken_npu) != 0) { + if (clock_control_on(clk, (clock_control_subsys_t)&cfg->pclken_npu) != 0) { return -EIO; } - if (clock_control_on(clk, (clock_control_subsys_t) &cfg->pclken_cacheaxi) != 0) { + if (clock_control_on(clk, (clock_control_subsys_t)&cfg->pclken_cacheaxi) != 0) { return -EIO; } @@ -53,14 +53,16 @@ static int npu_stm32_init(const struct device *dev) return 0; } - static const struct npu_stm32_cfg npu_stm32_cfg = { - .pclken_npu = STM32_CLOCK_INFO_BY_NAME(DT_NODELABEL(npu), npu), - .pclken_cacheaxi = STM32_CLOCK_INFO_BY_NAME(DT_NODELABEL(npu), cacheaxi), - .reset_npu = RESET_DT_SPEC_GET_BY_IDX(DT_NODELABEL(npu), 0), - .reset_cacheaxi = RESET_DT_SPEC_GET_BY_IDX(DT_NODELABEL(npu), 1), + .pclken_npu = STM32_DT_INST_CLOCK_INFO(0), + .reset_npu = RESET_DT_SPEC_INST_GET(0), + /* + * Even if npu_cache node is disabled, its clocks must be enabled for NPU operation. + * This is why we need to get clock and reset line from the npu_cache node. + */ + .pclken_cacheaxi = STM32_CLOCK_INFO(0, DT_NODELABEL(npu_cache)), + .reset_cacheaxi = RESET_DT_SPEC_GET(DT_NODELABEL(npu_cache)), }; -DEVICE_DT_DEFINE(DT_NODELABEL(npu), npu_stm32_init, NULL, - NULL, &npu_stm32_cfg, POST_KERNEL, - CONFIG_APPLICATION_INIT_PRIORITY, NULL); +DEVICE_DT_INST_DEFINE(0, npu_stm32_init, NULL, NULL, &npu_stm32_cfg, POST_KERNEL, + CONFIG_STM32N6_NPU_INIT_PRIORITY, NULL); From ec5c3420b353c7d3e462006c70a70d8c35e23664 Mon Sep 17 00:00:00 2001 From: Cesar Santos Date: Fri, 16 Jan 2026 10:21:08 +0000 Subject: [PATCH 2581/3659] samples: net: secure_mqtt_sensor_actuator: add missing POSIX libraries In order to compile the demo application for a secure MQTT connection, several networking API functions are used, which is properly defined by some of the POSIX libraries already integrated onto Zephyr project. By adding the missing libraries, compilation to the reference board adi_eval_adin1110ebz passes. As a minor change, reordered the sequence of included libraries to be in alphabetical order. Fixes #102372. Signed-off-by: Cesar Santos --- samples/net/secure_mqtt_sensor_actuator/src/mqtt_client.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/samples/net/secure_mqtt_sensor_actuator/src/mqtt_client.c b/samples/net/secure_mqtt_sensor_actuator/src/mqtt_client.c index 5095da7c2c3e..0ce2e6586e5f 100644 --- a/samples/net/secure_mqtt_sensor_actuator/src/mqtt_client.c +++ b/samples/net/secure_mqtt_sensor_actuator/src/mqtt_client.c @@ -7,10 +7,13 @@ #include LOG_MODULE_REGISTER(app_mqtt, LOG_LEVEL_DBG); +#include #include -#include #include -#include +#include +#include +#include +#include #include #include "mqtt_client.h" From b4bbba70b1bf46aef114ad87479001fab48acb3c Mon Sep 17 00:00:00 2001 From: Svitlana Drozd Date: Tue, 20 Jan 2026 15:02:55 +0200 Subject: [PATCH 2582/3659] boards: raspberrypi: rpi_5: remove unnecessary arm_64bit option The ARM cores in BCM2712 are incapable of running the kernel in 32-bit mode. The option `arm_64bit=1` is unnecessary and can be confusing, as Raspberry Pi 5 runs in 64-bit mode by default. Removed the `arm_64bit=1` configuration from documentation for Raspberry Pi 5 (BCM2712). Signed-off-by: Svitlana Drozd --- boards/raspberrypi/rpi_5/doc/index.rst | 2 -- 1 file changed, 2 deletions(-) diff --git a/boards/raspberrypi/rpi_5/doc/index.rst b/boards/raspberrypi/rpi_5/doc/index.rst index d8b94b7a87ed..63a8bdfb574f 100644 --- a/boards/raspberrypi/rpi_5/doc/index.rst +++ b/boards/raspberrypi/rpi_5/doc/index.rst @@ -57,7 +57,6 @@ config.txt .. code-block:: text kernel=zephyr.bin - arm_64bit=1 zephyr.bin @@ -98,7 +97,6 @@ config.txt .. code-block:: text kernel=zephyr.bin - arm_64bit=1 enable_uart=1 uart_2ndstage=1 From cdfd692b76e7a4f575de99b568cdb471cef9f678 Mon Sep 17 00:00:00 2001 From: Svitlana Drozd Date: Tue, 20 Jan 2026 15:14:20 +0200 Subject: [PATCH 2583/3659] boards: raspberrypi: rpi_5: correct DTB file name in doc The DTB file was previously listed as bcm2712-rpi-5.dtb, which was inaccurate, as the hyperlink referenced the `bcm2712-rpi-5-b.dtb` file. To ensure documentation precision and avoid potential confusion, update the file name to the correct `bcm2712-rpi-5-b.dtb`. Signed-off-by: Svitlana Drozd --- boards/raspberrypi/rpi_5/doc/index.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/boards/raspberrypi/rpi_5/doc/index.rst b/boards/raspberrypi/rpi_5/doc/index.rst index 63a8bdfb574f..104e521555d8 100644 --- a/boards/raspberrypi/rpi_5/doc/index.rst +++ b/boards/raspberrypi/rpi_5/doc/index.rst @@ -46,7 +46,7 @@ In brief, 2. Save three files below in the root directory. * config.txt * zephyr.bin - * `bcm2712-rpi-5.dtb`_ + * `bcm2712-rpi-5-b.dtb`_ 3. Insert the Micro SD card and power on the Raspberry Pi 5. then, You will see the Raspberry Pi 5 running the :file:`zephyr.bin`. @@ -133,7 +133,7 @@ When you power on the Raspberry Pi 5, you will see the following output in the s .. _Raspberry Pi hardware: https://www.raspberrypi.com/documentation/computers/raspberry-pi.html -.. _bcm2712-rpi-5.dtb: +.. _bcm2712-rpi-5-b.dtb: https://github.com/raspberrypi/firmware/raw/master/boot/bcm2712-rpi-5-b.dtb .. _Raspberry Pi Debug Probe: From 1feabd2552a4789126be4fe3d46f19af26c4da93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Wed, 21 Jan 2026 11:51:40 +0100 Subject: [PATCH 2584/3659] shell: fix potential buffer overflow in shell_help_is_structured() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The function was casting a char* help pointer to struct shell_cmd_help* and reading its 4-byte magic field. When the help string was shorter than 4 bytes, this caused a read past the end of the buffer. The fix replaces the struct cast with a byte-by-byte comparison of the magic number. Fixes zephyrproject-rtos/zephyr#102598 Co-authored-by: Alberto Escolar Piedras Signed-off-by: Benjamin Cabé --- include/zephyr/shell/shell.h | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/include/zephyr/shell/shell.h b/include/zephyr/shell/shell.h index 7274b650180c..a451bda9df25 100644 --- a/include/zephyr/shell/shell.h +++ b/include/zephyr/shell/shell.h @@ -326,10 +326,16 @@ struct shell_cmd_help { */ static inline bool shell_help_is_structured(const char *help) { - const struct shell_cmd_help *structured = (const struct shell_cmd_help *)help; + const uint32_t magic32 = SHELL_STRUCTURED_HELP_MAGIC; + const char *magic = (const char *)&magic32; - return structured != NULL && IS_PTR_ALIGNED(structured, struct shell_cmd_help) && - structured->magic == SHELL_STRUCTURED_HELP_MAGIC; + /** + * Check if what help points to starts with the structured help magic word, + * but without assuming help is 32 bit aligned, or that if it is a string, + * that it is at least 4 bytes long. + */ + return help != NULL && (magic[0] == help[0]) && (magic[1] == help[1]) + && (magic[2] == help[2]) && (magic[3] == help[3]); } #if defined(CONFIG_SHELL_HELP) || defined(__DOXYGEN__) From 6404f3781448f40e2b2fdef8050cce493cb87f89 Mon Sep 17 00:00:00 2001 From: Andrej Butok Date: Wed, 21 Jan 2026 13:39:59 +0100 Subject: [PATCH 2585/3659] boards: nxp: Fix NXP MCU board names in yaml - Fixes an inconsistency in the board list of the MCUx-VSCode extension. No functional change. - Adjusts names in yaml files to follow the currently used approach "NXP [(cpu)] [(type)]". Signed-off-by: Andrej Butok --- boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_qspi.yaml | 2 +- boards/nxp/lpcxpresso11u68/lpcxpresso11u68.yaml | 2 +- boards/nxp/lpcxpresso54114/lpcxpresso54114_lpc54114_m0.yaml | 2 +- boards/nxp/lpcxpresso54114/lpcxpresso54114_lpc54114_m4.yaml | 2 +- .../nxp/lpcxpresso55s69/lpcxpresso55s69_lpc55s69_cpu0_ns.yaml | 2 +- boards/nxp/mcx_nx4x_evk/mcx_n9xx_evk_mcxn947_cpu0_qspi.yaml | 2 +- boards/nxp/mcxw72_evk/mcxw72_evk_mcxw727c_cpu0.yaml | 2 +- boards/nxp/mimxrt1050_evk/mimxrt1050_evk_mimxrt1052_qspi.yaml | 2 +- .../mimxrt1060_evk/mimxrt1060_evk_mimxrt1062_hyperflash.yaml | 2 +- boards/nxp/mimxrt1062_fmurt6/board.yml | 2 +- boards/nxp/mimxrt1160_evk/mimxrt1160_evk_mimxrt1166_cm4.yaml | 2 +- boards/nxp/mimxrt1160_evk/mimxrt1160_evk_mimxrt1166_cm7.yaml | 2 +- boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm4.yaml | 2 +- boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm4_B.yaml | 2 +- boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm7.yaml | 2 +- boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm7_B.yaml | 2 +- boards/nxp/mimxrt1180_evk/mimxrt1180_evk_mimxrt1189_cm33.yaml | 2 +- boards/nxp/mimxrt1180_evk/mimxrt1180_evk_mimxrt1189_cm7.yaml | 2 +- boards/nxp/mimxrt595_evk/mimxrt595_evk_mimxrt595s_f1.yaml | 2 +- boards/nxp/mimxrt685_evk/mimxrt685_evk_mimxrt685s_hifi4.yaml | 2 +- .../nxp/mimxrt700_evk/mimxrt700_evk_mimxrt798s_cm33_cpu0.yaml | 2 +- .../nxp/mimxrt700_evk/mimxrt700_evk_mimxrt798s_cm33_cpu1.yaml | 2 +- boards/nxp/mimxrt700_evk/mimxrt700_evk_mimxrt798s_hifi1.yaml | 2 +- boards/nxp/mimxrt700_evk/mimxrt700_evk_mimxrt798s_hifi4.yaml | 2 +- boards/nxp/rd_rw612_bga/rd_rw612_bga.yaml | 2 +- boards/nxp/rd_rw612_bga/rd_rw612_bga_rw612_ethernet.yaml | 2 +- 26 files changed, 26 insertions(+), 26 deletions(-) diff --git a/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_qspi.yaml b/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_qspi.yaml index 50fdca7748b5..8a1f10e06caf 100644 --- a/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_qspi.yaml +++ b/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_qspi.yaml @@ -5,7 +5,7 @@ # identifier: frdm_mcxn947/mcxn947/cpu0/qspi -name: NXP FRDM-MCXN947 QSPI (CPU0) +name: NXP FRDM-MCXN947 (CPU0) (QSPI) type: mcu arch: arm ram: 320 diff --git a/boards/nxp/lpcxpresso11u68/lpcxpresso11u68.yaml b/boards/nxp/lpcxpresso11u68/lpcxpresso11u68.yaml index 192ca797f629..395d7ef378b1 100644 --- a/boards/nxp/lpcxpresso11u68/lpcxpresso11u68.yaml +++ b/boards/nxp/lpcxpresso11u68/lpcxpresso11u68.yaml @@ -1,5 +1,5 @@ identifier: lpcxpresso11u68 -name: NXP LPCxpresso 11U68 +name: NXP LPCxpresso11U68 type: mcu arch: arm ram: 32 diff --git a/boards/nxp/lpcxpresso54114/lpcxpresso54114_lpc54114_m0.yaml b/boards/nxp/lpcxpresso54114/lpcxpresso54114_lpc54114_m0.yaml index 8294367fcbd0..17cc1eb2d2d8 100644 --- a/boards/nxp/lpcxpresso54114/lpcxpresso54114_lpc54114_m0.yaml +++ b/boards/nxp/lpcxpresso54114/lpcxpresso54114_lpc54114_m0.yaml @@ -5,7 +5,7 @@ # identifier: lpcxpresso54114/lpc54114/m0 -name: NXP LPCXpresso54114 M0 +name: NXP LPCXpresso54114 (M0) type: mcu arch: arm ram: 32 diff --git a/boards/nxp/lpcxpresso54114/lpcxpresso54114_lpc54114_m4.yaml b/boards/nxp/lpcxpresso54114/lpcxpresso54114_lpc54114_m4.yaml index f1f13fb5cdae..8e0db4faf46f 100644 --- a/boards/nxp/lpcxpresso54114/lpcxpresso54114_lpc54114_m4.yaml +++ b/boards/nxp/lpcxpresso54114/lpcxpresso54114_lpc54114_m4.yaml @@ -5,7 +5,7 @@ # identifier: lpcxpresso54114/lpc54114/m4 -name: NXP LPCXpresso54114 M4 +name: NXP LPCXpresso54114 (M4) type: mcu arch: arm ram: 64 diff --git a/boards/nxp/lpcxpresso55s69/lpcxpresso55s69_lpc55s69_cpu0_ns.yaml b/boards/nxp/lpcxpresso55s69/lpcxpresso55s69_lpc55s69_cpu0_ns.yaml index ee3a4348eb02..ab0331e7bf61 100644 --- a/boards/nxp/lpcxpresso55s69/lpcxpresso55s69_lpc55s69_cpu0_ns.yaml +++ b/boards/nxp/lpcxpresso55s69/lpcxpresso55s69_lpc55s69_cpu0_ns.yaml @@ -5,7 +5,7 @@ # identifier: lpcxpresso55s69/lpc55s69/cpu0/ns -name: NXP LPCXpresso55S69 (Non-Secure) +name: NXP LPCXpresso55S69 (CPU0) (Non-Secure) type: mcu arch: arm ram: 136 diff --git a/boards/nxp/mcx_nx4x_evk/mcx_n9xx_evk_mcxn947_cpu0_qspi.yaml b/boards/nxp/mcx_nx4x_evk/mcx_n9xx_evk_mcxn947_cpu0_qspi.yaml index c2b1422dfe4c..9a47d0dc8f68 100644 --- a/boards/nxp/mcx_nx4x_evk/mcx_n9xx_evk_mcxn947_cpu0_qspi.yaml +++ b/boards/nxp/mcx_nx4x_evk/mcx_n9xx_evk_mcxn947_cpu0_qspi.yaml @@ -5,7 +5,7 @@ # identifier: mcx_n9xx_evk/mcxn947/cpu0/qspi -name: NXP MCX-N9XX-EVK QSPI (CPU0) +name: NXP MCX-N9XX-EVK (CPU0) (QSPI) type: mcu arch: arm ram: 320 diff --git a/boards/nxp/mcxw72_evk/mcxw72_evk_mcxw727c_cpu0.yaml b/boards/nxp/mcxw72_evk/mcxw72_evk_mcxw727c_cpu0.yaml index f3f9a54cf1da..518afbadeaa3 100644 --- a/boards/nxp/mcxw72_evk/mcxw72_evk_mcxw727c_cpu0.yaml +++ b/boards/nxp/mcxw72_evk/mcxw72_evk_mcxw727c_cpu0.yaml @@ -1,5 +1,5 @@ identifier: mcxw72_evk/mcxw727c/cpu0 -name: NXP MCXW72_EVK +name: NXP MCXW72-EVK type: mcu arch: arm ram: 264 diff --git a/boards/nxp/mimxrt1050_evk/mimxrt1050_evk_mimxrt1052_qspi.yaml b/boards/nxp/mimxrt1050_evk/mimxrt1050_evk_mimxrt1052_qspi.yaml index e05c61c13acc..752e98b34d60 100644 --- a/boards/nxp/mimxrt1050_evk/mimxrt1050_evk_mimxrt1052_qspi.yaml +++ b/boards/nxp/mimxrt1050_evk/mimxrt1050_evk_mimxrt1052_qspi.yaml @@ -5,7 +5,7 @@ # identifier: mimxrt1050_evk/mimxrt1052/qspi -name: NXP MIMXRT1050-EVK-QSPI +name: NXP MIMXRT1050-EVK (QSPI) type: mcu arch: arm toolchain: diff --git a/boards/nxp/mimxrt1060_evk/mimxrt1060_evk_mimxrt1062_hyperflash.yaml b/boards/nxp/mimxrt1060_evk/mimxrt1060_evk_mimxrt1062_hyperflash.yaml index acf3d6016ff3..e87daa765bda 100644 --- a/boards/nxp/mimxrt1060_evk/mimxrt1060_evk_mimxrt1062_hyperflash.yaml +++ b/boards/nxp/mimxrt1060_evk/mimxrt1060_evk_mimxrt1062_hyperflash.yaml @@ -5,7 +5,7 @@ # identifier: mimxrt1060_evk/mimxrt1062/hyperflash -name: NXP MIMXRT1060-EVK-HYPERFLASH +name: NXP MIMXRT1060-EVK (HyperFlash) type: mcu arch: arm toolchain: diff --git a/boards/nxp/mimxrt1062_fmurt6/board.yml b/boards/nxp/mimxrt1062_fmurt6/board.yml index 60541a7f3614..bf397cc5dd35 100644 --- a/boards/nxp/mimxrt1062_fmurt6/board.yml +++ b/boards/nxp/mimxrt1062_fmurt6/board.yml @@ -1,6 +1,6 @@ board: name: mimxrt1062_fmurt6 - full_name: FMURT6 + full_name: MIMXRT1062-FMURT6 vendor: nxp socs: - name: mimxrt1062 diff --git a/boards/nxp/mimxrt1160_evk/mimxrt1160_evk_mimxrt1166_cm4.yaml b/boards/nxp/mimxrt1160_evk/mimxrt1160_evk_mimxrt1166_cm4.yaml index 445f170f5730..a1a3f487a3f9 100644 --- a/boards/nxp/mimxrt1160_evk/mimxrt1160_evk_mimxrt1166_cm4.yaml +++ b/boards/nxp/mimxrt1160_evk/mimxrt1160_evk_mimxrt1166_cm4.yaml @@ -5,7 +5,7 @@ # identifier: mimxrt1160_evk/mimxrt1166/cm4 -name: NXP MIMXRT1160-EVK CM4 +name: NXP MIMXRT1160-EVK (CM4) type: mcu arch: arm toolchain: diff --git a/boards/nxp/mimxrt1160_evk/mimxrt1160_evk_mimxrt1166_cm7.yaml b/boards/nxp/mimxrt1160_evk/mimxrt1160_evk_mimxrt1166_cm7.yaml index d803d9332e38..e5929321e915 100644 --- a/boards/nxp/mimxrt1160_evk/mimxrt1160_evk_mimxrt1166_cm7.yaml +++ b/boards/nxp/mimxrt1160_evk/mimxrt1160_evk_mimxrt1166_cm7.yaml @@ -5,7 +5,7 @@ # identifier: mimxrt1160_evk/mimxrt1166/cm7 -name: NXP MIMXRT1160-EVK CM7 +name: NXP MIMXRT1160-EVK (CM7) type: mcu arch: arm toolchain: diff --git a/boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm4.yaml b/boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm4.yaml index 4056069d8aa9..a66b47c46781 100644 --- a/boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm4.yaml +++ b/boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm4.yaml @@ -5,7 +5,7 @@ # identifier: mimxrt1170_evk@A/mimxrt1176/cm4 -name: NXP MIMXRT1170-EVK CM4 +name: NXP MIMXRT1170-EVK (CM4) type: mcu arch: arm toolchain: diff --git a/boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm4_B.yaml b/boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm4_B.yaml index af866754ca76..083c299b2c92 100644 --- a/boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm4_B.yaml +++ b/boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm4_B.yaml @@ -5,7 +5,7 @@ # identifier: mimxrt1170_evk@B/mimxrt1176/cm4 -name: NXP MIMXRT1170-EVKB CM4 +name: NXP MIMXRT1170-EVKB (CM4) type: mcu arch: arm toolchain: diff --git a/boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm7.yaml b/boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm7.yaml index 46587fb95477..452968e2b344 100644 --- a/boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm7.yaml +++ b/boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm7.yaml @@ -5,7 +5,7 @@ # identifier: mimxrt1170_evk@A/mimxrt1176/cm7 -name: NXP MIMXRT1170-EVK CM7 +name: NXP MIMXRT1170-EVK (CM7) type: mcu arch: arm toolchain: 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 009aebd98e20..e71986bc2ae5 100644 --- a/boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm7_B.yaml +++ b/boards/nxp/mimxrt1170_evk/mimxrt1170_evk_mimxrt1176_cm7_B.yaml @@ -5,7 +5,7 @@ # identifier: mimxrt1170_evk@B/mimxrt1176/cm7 -name: NXP MIMXRT1170-EVKB CM7 +name: NXP MIMXRT1170-EVKB (CM7) type: mcu arch: arm toolchain: diff --git a/boards/nxp/mimxrt1180_evk/mimxrt1180_evk_mimxrt1189_cm33.yaml b/boards/nxp/mimxrt1180_evk/mimxrt1180_evk_mimxrt1189_cm33.yaml index ae2a0c86bcc4..4d3e8da3aef2 100644 --- a/boards/nxp/mimxrt1180_evk/mimxrt1180_evk_mimxrt1189_cm33.yaml +++ b/boards/nxp/mimxrt1180_evk/mimxrt1180_evk_mimxrt1189_cm33.yaml @@ -5,7 +5,7 @@ # identifier: mimxrt1180_evk/mimxrt1189/cm33 -name: NXP MIMXRT1180-EVK CM33 +name: NXP MIMXRT1180-EVK (CM33) type: mcu arch: arm toolchain: diff --git a/boards/nxp/mimxrt1180_evk/mimxrt1180_evk_mimxrt1189_cm7.yaml b/boards/nxp/mimxrt1180_evk/mimxrt1180_evk_mimxrt1189_cm7.yaml index 6d23f30f31c3..a44dbf609b77 100644 --- a/boards/nxp/mimxrt1180_evk/mimxrt1180_evk_mimxrt1189_cm7.yaml +++ b/boards/nxp/mimxrt1180_evk/mimxrt1180_evk_mimxrt1189_cm7.yaml @@ -5,7 +5,7 @@ # identifier: mimxrt1180_evk/mimxrt1189/cm7 -name: NXP MIMXRT1180-EVK CM7 +name: NXP MIMXRT1180-EVK (CM7) type: mcu arch: arm toolchain: diff --git a/boards/nxp/mimxrt595_evk/mimxrt595_evk_mimxrt595s_f1.yaml b/boards/nxp/mimxrt595_evk/mimxrt595_evk_mimxrt595s_f1.yaml index 48245feebc68..a51f88ed0268 100644 --- a/boards/nxp/mimxrt595_evk/mimxrt595_evk_mimxrt595s_f1.yaml +++ b/boards/nxp/mimxrt595_evk/mimxrt595_evk_mimxrt595s_f1.yaml @@ -1,5 +1,5 @@ identifier: mimxrt595_evk/mimxrt595s/f1 -name: i.MXRT595 Fusion F1 DSP +name: NXP MIMXRT595-EVK (Fusion F1 DSP) type: mcu arch: xtensa toolchain: diff --git a/boards/nxp/mimxrt685_evk/mimxrt685_evk_mimxrt685s_hifi4.yaml b/boards/nxp/mimxrt685_evk/mimxrt685_evk_mimxrt685s_hifi4.yaml index 86cd87801adb..f0684da96fdc 100644 --- a/boards/nxp/mimxrt685_evk/mimxrt685_evk_mimxrt685s_hifi4.yaml +++ b/boards/nxp/mimxrt685_evk/mimxrt685_evk_mimxrt685s_hifi4.yaml @@ -5,7 +5,7 @@ # identifier: mimxrt685_evk/mimxrt685s/hifi4 -name: NXP MIMXRT685-EVK (HiFi 4) +name: NXP MIMXRT685-EVK (HiFi4) type: mcu arch: xtensa ram: 64 diff --git a/boards/nxp/mimxrt700_evk/mimxrt700_evk_mimxrt798s_cm33_cpu0.yaml b/boards/nxp/mimxrt700_evk/mimxrt700_evk_mimxrt798s_cm33_cpu0.yaml index eeade2809eaa..0c208f2fd854 100644 --- a/boards/nxp/mimxrt700_evk/mimxrt700_evk_mimxrt798s_cm33_cpu0.yaml +++ b/boards/nxp/mimxrt700_evk/mimxrt700_evk_mimxrt798s_cm33_cpu0.yaml @@ -5,7 +5,7 @@ # identifier: mimxrt700_evk/mimxrt798s/cm33_cpu0 -name: NXP MIMXRT700-EVK (CM33_CPU0) +name: NXP MIMXRT700-EVK (CPU0) type: mcu arch: arm ram: 512 diff --git a/boards/nxp/mimxrt700_evk/mimxrt700_evk_mimxrt798s_cm33_cpu1.yaml b/boards/nxp/mimxrt700_evk/mimxrt700_evk_mimxrt798s_cm33_cpu1.yaml index 13f0b3b76602..8867a4488bf1 100644 --- a/boards/nxp/mimxrt700_evk/mimxrt700_evk_mimxrt798s_cm33_cpu1.yaml +++ b/boards/nxp/mimxrt700_evk/mimxrt700_evk_mimxrt798s_cm33_cpu1.yaml @@ -5,7 +5,7 @@ # identifier: mimxrt700_evk/mimxrt798s/cm33_cpu1 -name: NXP MIMXRT700-EVK (CM33_CPU1) +name: NXP MIMXRT700-EVK (CPU1) type: mcu arch: arm ram: 256 diff --git a/boards/nxp/mimxrt700_evk/mimxrt700_evk_mimxrt798s_hifi1.yaml b/boards/nxp/mimxrt700_evk/mimxrt700_evk_mimxrt798s_hifi1.yaml index 7c3bee257ef9..8617853f99b7 100644 --- a/boards/nxp/mimxrt700_evk/mimxrt700_evk_mimxrt798s_hifi1.yaml +++ b/boards/nxp/mimxrt700_evk/mimxrt700_evk_mimxrt798s_hifi1.yaml @@ -5,7 +5,7 @@ # identifier: mimxrt700_evk/mimxrt798s/hifi1 -name: NXP MIMXRT700-EVK HiFi1 +name: NXP MIMXRT700-EVK (HiFi1) type: mcu arch: xtensa toolchain: diff --git a/boards/nxp/mimxrt700_evk/mimxrt700_evk_mimxrt798s_hifi4.yaml b/boards/nxp/mimxrt700_evk/mimxrt700_evk_mimxrt798s_hifi4.yaml index 925a17ac4664..da3dd26e465f 100644 --- a/boards/nxp/mimxrt700_evk/mimxrt700_evk_mimxrt798s_hifi4.yaml +++ b/boards/nxp/mimxrt700_evk/mimxrt700_evk_mimxrt798s_hifi4.yaml @@ -5,7 +5,7 @@ # identifier: mimxrt700_evk/mimxrt798s/hifi4 -name: NXP MIMXRT700-EVK HiFi4 +name: NXP MIMXRT700-EVK (HiFi4) type: mcu arch: xtensa toolchain: diff --git a/boards/nxp/rd_rw612_bga/rd_rw612_bga.yaml b/boards/nxp/rd_rw612_bga/rd_rw612_bga.yaml index de886b57e84a..dc71244aa10f 100644 --- a/boards/nxp/rd_rw612_bga/rd_rw612_bga.yaml +++ b/boards/nxp/rd_rw612_bga/rd_rw612_bga.yaml @@ -5,7 +5,7 @@ # identifier: rd_rw612_bga -name: NXP RD_RW612_BGA +name: NXP RD-RW612-BGA type: mcu arch: arm toolchain: diff --git a/boards/nxp/rd_rw612_bga/rd_rw612_bga_rw612_ethernet.yaml b/boards/nxp/rd_rw612_bga/rd_rw612_bga_rw612_ethernet.yaml index dbdff161607e..ec8e5acec716 100644 --- a/boards/nxp/rd_rw612_bga/rd_rw612_bga_rw612_ethernet.yaml +++ b/boards/nxp/rd_rw612_bga/rd_rw612_bga_rw612_ethernet.yaml @@ -5,7 +5,7 @@ # identifier: rd_rw612_bga/rw612/ethernet -name: NXP RD_RW612_BGA ETHERNET +name: NXP RD-RW612-BGA (Ethernet) type: mcu arch: arm toolchain: From 089bb1f0001684d74017faa186ecc3285ed8cfa7 Mon Sep 17 00:00:00 2001 From: Cristian Bulacu Date: Wed, 21 Jan 2026 15:36:07 +0200 Subject: [PATCH 2586/3659] samples: net: openthread: Remove OT reference device flag for NXP RW612 This commit removes the OPENTHREAD_REFERENCE_DEVICE flag for NXP RW612 samples, as these are not meant to be included in a test setup. Signed-off-by: Cristian Bulacu --- samples/net/openthread/border_router/prj.conf | 1 - samples/net/openthread/shell/prj-ot-host.conf | 1 - 2 files changed, 2 deletions(-) diff --git a/samples/net/openthread/border_router/prj.conf b/samples/net/openthread/border_router/prj.conf index 6e2bb959b3ef..0c71d6214e1b 100644 --- a/samples/net/openthread/border_router/prj.conf +++ b/samples/net/openthread/border_router/prj.conf @@ -124,7 +124,6 @@ CONFIG_OPENTHREAD_SRP_SERVER=y CONFIG_OPENTHREAD_SRP_ADV_PROXY=y CONFIG_OPENTHREAD_DNSSD_DISCOVERY_PROXY=y CONFIG_OPENTHREAD_PING_SENDER=y -CONFIG_OPENTHREAD_REFERENCE_DEVICE=y CONFIG_OPENTHREAD_LINK_METRICS_INITIATOR=y CONFIG_OPENTHREAD_DUA=y CONFIG_OPENTHREAD_MLR=y diff --git a/samples/net/openthread/shell/prj-ot-host.conf b/samples/net/openthread/shell/prj-ot-host.conf index 1565846414bd..63d7aa5291a9 100644 --- a/samples/net/openthread/shell/prj-ot-host.conf +++ b/samples/net/openthread/shell/prj-ot-host.conf @@ -38,7 +38,6 @@ CONFIG_OPENTHREAD_SETTINGS_RAM=y CONFIG_OPENTHREAD_NUM_MESSAGE_BUFFERS=256 CONFIG_OPENTHREAD_COAP=y CONFIG_OPENTHREAD_JOINER=y -CONFIG_OPENTHREAD_REFERENCE_DEVICE=y CONFIG_OPENTHREAD_DHCP6_CLIENT=y CONFIG_OPENTHREAD_LINK_METRICS_INITIATOR=y CONFIG_OPENTHREAD_LINK_METRICS_SUBJECT=y From f87fff19a77c659e80db0f67008b7d9f8516bf94 Mon Sep 17 00:00:00 2001 From: Cristian Bulacu Date: Wed, 21 Jan 2026 15:48:22 +0200 Subject: [PATCH 2587/3659] tests: net: remove OT reference device flag for OT tests This commit removes OPENTHREAD_REFERENCE_DEVICE flag for OpenThread tests. Signed-off-by: Cristian Bulacu --- tests/net/all/testcase.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/net/all/testcase.yaml b/tests/net/all/testcase.yaml index 36e9cdc456f4..888ae892e4a6 100644 --- a/tests/net/all/testcase.yaml +++ b/tests/net/all/testcase.yaml @@ -103,7 +103,6 @@ tests: - CONFIG_OPENTHREAD_SRP_ADV_PROXY=y - CONFIG_OPENTHREAD_DNSSD_DISCOVERY_PROXY=y - CONFIG_OPENTHREAD_PING_SENDER=y - - CONFIG_OPENTHREAD_REFERENCE_DEVICE=y - CONFIG_OPENTHREAD_LINK_METRICS_INITIATOR=y - CONFIG_OPENTHREAD_DUA=y - CONFIG_OPENTHREAD_MLR=y From a04d8957c2120abb1187a0d4fa4b97f10307a8b0 Mon Sep 17 00:00:00 2001 From: Jakub Rzeszutko Date: Wed, 21 Jan 2026 15:28:31 +0100 Subject: [PATCH 2588/3659] shell: fix race condition between prompt print and RX buffer flush Move z_shell_backend_rx_buffer_flush() before state_set() in shell_start() to prevent a race condition where incoming shell commands could be lost. Previously, the sequence was: 1. state_set() - prints the prompt 2. z_shell_backend_rx_buffer_flush() - flushes RX buffer If the shell thread was preempted after printing the prompt, the host could see the prompt and send commands. When the thread resumed, z_shell_backend_rx_buffer_flush() would discard those commands. By flushing the RX buffer before printing the prompt, any commands received after the prompt is visible will not be affected by the flush operation. Fixes #99674 Signed-off-by: Jakub Rzeszutko --- subsys/shell/shell.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/subsys/shell/shell.c b/subsys/shell/shell.c index a331464ba09d..9596ae1b2ffe 100644 --- a/subsys/shell/shell.c +++ b/subsys/shell/shell.c @@ -1449,12 +1449,6 @@ int shell_start(const struct shell *sh) z_shell_vt100_color_set(sh, SHELL_NORMAL); } - /* print new line before printing the prompt to clear the line - * vt100 are not used here for compatibility reasons - */ - z_cursor_next_line_move(sh); - state_set(sh, SHELL_STATE_ACTIVE); - /* * If the shell is stopped with the shell_stop function, its backend remains active * and continues to buffer incoming data. As a result, when the shell is resumed, @@ -1463,6 +1457,12 @@ int shell_start(const struct shell *sh) */ z_shell_backend_rx_buffer_flush(sh); + /* print new line before printing the prompt to clear the line + * vt100 are not used here for compatibility reasons + */ + z_cursor_next_line_move(sh); + state_set(sh, SHELL_STATE_ACTIVE); + z_shell_unlock(sh); return 0; From daf90f79eeb782235f81906841c2aa3696545910 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fin=20Maa=C3=9F?= Date: Tue, 28 Oct 2025 13:49:22 +0100 Subject: [PATCH 2589/3659] arch: riscv: add dependencies to FLOAT_HARD MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. it reguires that there are floating point registers, so the extention f is required. (zfinx uses the int regs instead) 2. RV32E doesn't supports hardware floating-point calling convention. Signed-off-by: Fin Maaß --- arch/riscv/Kconfig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index b720faa35a2d..df5574609e5b 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -13,8 +13,11 @@ config FLOAT_HARD bool "Hard-float calling convention" default y depends on FPU + depends on !RISCV_ISA_RV32E + depends on RISCV_ISA_EXT_F help This option enables the hard-float calling convention. + Adds eight floating-point argument registers. choice RISCV_GP_PURPOSE prompt "Purpose of the global pointer (GP) register" From 03418c538ebb904d5641195913b34ce060d69b4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fin=20Maa=C3=9F?= Date: Tue, 28 Oct 2025 13:54:11 +0100 Subject: [PATCH 2590/3659] riscv: gcc: seperate fpu mabi and march part MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit seperate fpu mabi and march part, also use the extention for the march part to make it easier to add Zfinx and Zdinx later. Signed-off-by: Fin Maaß --- cmake/compiler/gcc/target_riscv.cmake | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/cmake/compiler/gcc/target_riscv.cmake b/cmake/compiler/gcc/target_riscv.cmake index 656b597a393e..6764aa5ff42c 100644 --- a/cmake/compiler/gcc/target_riscv.cmake +++ b/cmake/compiler/gcc/target_riscv.cmake @@ -34,17 +34,20 @@ if(CONFIG_RISCV_ISA_EXT_A) string(CONCAT riscv_march ${riscv_march} "a") endif() -if(CONFIG_FPU) +if(CONFIG_FLOAT_HARD) if(CONFIG_CPU_HAS_FPU_DOUBLE_PRECISION) - if(CONFIG_FLOAT_HARD) - string(CONCAT riscv_mabi ${riscv_mabi} "d") - endif() - string(CONCAT riscv_march ${riscv_march} "fd") + string(APPEND riscv_mabi "d") else() - if(CONFIG_FLOAT_HARD) - string(CONCAT riscv_mabi ${riscv_mabi} "f") - endif() - string(CONCAT riscv_march ${riscv_march} "f") + string(APPEND riscv_mabi "f") + endif() +endif() + +if(CONFIG_FPU) + if(CONFIG_RISCV_ISA_EXT_F) + string(APPEND riscv_march "f") + endif() + if(CONFIG_RISCV_ISA_EXT_D) + string(APPEND riscv_march "d") endif() endif() From c4945315e76aa29a9fcea6c269dc0f6a91bfa652 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fin=20Maa=C3=9F?= Date: Tue, 28 Oct 2025 13:56:44 +0100 Subject: [PATCH 2591/3659] riscv: gcc: use string(APPEND MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit use string(APPEND instead of string(CONCAT where possible. Makes it shorter. Signed-off-by: Fin Maaß --- cmake/compiler/gcc/target_riscv.cmake | 50 +++++++++++++-------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/cmake/compiler/gcc/target_riscv.cmake b/cmake/compiler/gcc/target_riscv.cmake index 6764aa5ff42c..420d56aedf1e 100644 --- a/cmake/compiler/gcc/target_riscv.cmake +++ b/cmake/compiler/gcc/target_riscv.cmake @@ -12,26 +12,26 @@ elseif(CONFIG_RISCV_CMODEL_LARGE) endif() if(CONFIG_64BIT) - string(CONCAT riscv_mabi ${riscv_mabi} "64") - string(CONCAT riscv_march ${riscv_march} "64") + string(APPEND riscv_mabi "64") + string(APPEND riscv_march "64") else() string(CONCAT riscv_mabi "i" ${riscv_mabi} "32") - string(CONCAT riscv_march ${riscv_march} "32") + string(APPEND riscv_march "32") endif() if(CONFIG_RISCV_ISA_RV32E) - string(CONCAT riscv_mabi ${riscv_mabi} "e") - string(CONCAT riscv_march ${riscv_march} "e") + string(APPEND riscv_mabi "e") + string(APPEND riscv_march "e") else() - string(CONCAT riscv_march ${riscv_march} "i") + string(APPEND riscv_march "i") endif() if(CONFIG_RISCV_ISA_EXT_M) - string(CONCAT riscv_march ${riscv_march} "m") + string(APPEND riscv_march "m") endif() if(CONFIG_RISCV_ISA_EXT_A) - string(CONCAT riscv_march ${riscv_march} "a") + string(APPEND riscv_march "a") endif() if(CONFIG_FLOAT_HARD) @@ -52,73 +52,73 @@ if(CONFIG_FPU) endif() if(CONFIG_RISCV_ISA_EXT_C) - string(CONCAT riscv_march ${riscv_march} "c") + string(APPEND riscv_march "c") endif() if(CONFIG_RISCV_ISA_EXT_ZICNTR) - string(CONCAT riscv_march ${riscv_march} "_zicntr") + string(APPEND riscv_march "_zicntr") endif() if(CONFIG_RISCV_ISA_EXT_ZICSR) - string(CONCAT riscv_march ${riscv_march} "_zicsr") + string(APPEND riscv_march "_zicsr") endif() if(CONFIG_RISCV_ISA_EXT_ZIFENCEI) - string(CONCAT riscv_march ${riscv_march} "_zifencei") + string(APPEND riscv_march "_zifencei") endif() # Check whether we already imply Zaamo/Zalrsc by selecting the A extension; if not - check them # individually and enable them as needed if(NOT CONFIG_RISCV_ISA_EXT_A) if(CONFIG_RISCV_ISA_EXT_ZAAMO) - string(CONCAT riscv_march ${riscv_march} "_zaamo") + string(APPEND riscv_march "_zaamo") endif() if(CONFIG_RISCV_ISA_EXT_ZALRSC) - string(CONCAT riscv_march ${riscv_march} "_zalrsc") + string(APPEND riscv_march "_zalrsc") endif() endif() # Zca is implied by C if(CONFIG_RISCV_ISA_EXT_ZCA AND NOT CONFIG_RISCV_ISA_EXT_C) - string(CONCAT riscv_march ${riscv_march} "_zca") + string(APPEND riscv_march "_zca") endif() if(CONFIG_RISCV_ISA_EXT_ZCB) - string(CONCAT riscv_march ${riscv_march} "_zcb") + string(APPEND riscv_march "_zcb") endif() # Zcd is implied by C+D if(CONFIG_RISCV_ISA_EXT_ZCD AND NOT (CONFIG_RISCV_ISA_EXT_C AND CONFIG_RISCV_ISA_EXT_D)) - string(CONCAT riscv_march ${riscv_march} "_zcd") + string(APPEND riscv_march "_zcd") endif() # Zcf is implied by C+F if(CONFIG_RISCV_ISA_EXT_ZCF AND NOT (CONFIG_RISCV_ISA_EXT_C AND CONFIG_RISCV_ISA_EXT_F)) - string(CONCAT riscv_march ${riscv_march} "_zcf") + string(APPEND riscv_march "_zcf") endif() if(CONFIG_RISCV_ISA_EXT_ZCMP) - string(CONCAT riscv_march ${riscv_march} "_zcmp") + string(APPEND riscv_march "_zcmp") endif() if(CONFIG_RISCV_ISA_EXT_ZCMT) - string(CONCAT riscv_march ${riscv_march} "_zcmt") + string(APPEND riscv_march "_zcmt") endif() if(CONFIG_RISCV_ISA_EXT_ZBA) - string(CONCAT riscv_march ${riscv_march} "_zba") + string(APPEND riscv_march "_zba") endif() if(CONFIG_RISCV_ISA_EXT_ZBB) - string(CONCAT riscv_march ${riscv_march} "_zbb") + string(APPEND riscv_march "_zbb") endif() if(CONFIG_RISCV_ISA_EXT_ZBC) - string(CONCAT riscv_march ${riscv_march} "_zbc") + string(APPEND riscv_march "_zbc") endif() if(CONFIG_RISCV_ISA_EXT_ZBKB) @@ -126,14 +126,14 @@ if(CONFIG_RISCV_ISA_EXT_ZBKB) endif() if(CONFIG_RISCV_ISA_EXT_ZBS) - string(CONCAT riscv_march ${riscv_march} "_zbs") + string(APPEND riscv_march "_zbs") endif() # Check whether we already imply Zmmul by selecting the M extension; if not - enable it if(NOT CONFIG_RISCV_ISA_EXT_M AND CONFIG_RISCV_ISA_EXT_ZMMUL AND "${GCC_COMPILER_VERSION}" VERSION_GREATER_EQUAL 13.0.0) - string(CONCAT riscv_march ${riscv_march} "_zmmul") + string(APPEND riscv_march "_zmmul") endif() list(APPEND RISCV_C_FLAGS From 6d2471af4138e8a92272a8b73fde41692a6c3a6e Mon Sep 17 00:00:00 2001 From: Andreas Schmidt Date: Fri, 21 Nov 2025 10:13:01 +0000 Subject: [PATCH 2592/3659] drivers: spi: spi_shell: enumerate only direct SPI controller children RUN_FN_ON_SPI_DEVICE to run a given fn only if the node_id is a direct child of the SPI controller (i.e. DT_PARENT(node_id) == DT_BUS(node_id)), and the node itself has status okay. This prevents enumerating sub-nodes of SPI devices (for example GPIO sub-devices) which are not direct children of the SPI controller. Fixes #99785 Signed-off-by: Andreas Schmidt --- drivers/spi/spi_shell.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/drivers/spi/spi_shell.c b/drivers/spi/spi_shell.c index a45dafcbcee7..d9c812380fec 100644 --- a/drivers/spi/spi_shell.c +++ b/drivers/spi/spi_shell.c @@ -29,11 +29,16 @@ /* Maximum bytes we can write and read at once */ #define MAX_SPI_BYTES MIN((CONFIG_SHELL_ARGC_MAX - TXRX_ARGV_BYTES), 32) -/* Runs the given fn only if the node_id belongs to a spi device, which is on an okay spi bus. */ -#define RUN_FN_ON_SPI_DEVICE(node_id, fn) \ - COND_CODE_1(DT_ON_BUS(node_id, spi), \ - (COND_CODE_1(DT_NODE_HAS_STATUS_OKAY(DT_BUS(node_id)), \ - (fn), ())), ()) +/* Runs the given fn only if the node_id is a direct child of the SPI + * controller (i.e. DT_PARENT(node_id) == DT_BUS(node_id)), and the node + * itself has status okay. This prevents enumerating sub-nodes of SPI + * devices (for example GPIO sub-devices) which are on the same SPI bus + * but are not direct children of the controller. + */ +#define RUN_FN_ON_SPI_DEVICE(node_id, fn) \ + COND_CODE_1(DT_ON_BUS(node_id, spi), \ + (COND_CODE_1(DT_SAME_NODE(DT_PARENT(node_id), DT_BUS(node_id)), \ + (COND_CODE_1(DT_NODE_HAS_STATUS_OKAY(node_id), (fn), ())), ())), ()) /* Create specified number of empty structs, separated by ',' */ #define _EMPTY_STRUCT_INST(idx, list) {0} From 92e6d6de31f5969abbd7fc5f482afd14d328f8db Mon Sep 17 00:00:00 2001 From: Terry Geng Date: Sun, 28 Dec 2025 13:16:00 -0500 Subject: [PATCH 2593/3659] west.yml: Update hal_rpi_pico revision for flash write fix Update hal_rpi_pico to include the fix to the flash write code from zephyrproject-rtos/hal_rpi_pico#15. Fixes #95729 Fixes #96224 Signed-off-by: Terry Geng --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index de9a40ee46ea..53726d5ea1c2 100644 --- a/west.yml +++ b/west.yml @@ -236,7 +236,7 @@ manifest: - hal - name: hal_rpi_pico path: modules/hal/rpi_pico - revision: 09e957522da60581cf7958b31f8e625d969c69a5 + revision: 562b41e10a1d8b1a761b253b107c5c6a84cf4535 groups: - hal - name: hal_sifli From 744a7f4daf17395e29d020adeb010ec76ac8e8f0 Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Mon, 5 Jan 2026 12:15:06 -0800 Subject: [PATCH 2594/3659] xtensa: mmu: do doxygen for functions This changes the existing comments for functions into doxygen style documentation for functions. Also adds missing doxygen doc for functions. Signed-off-by: Daniel Leung --- arch/xtensa/core/mmu.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/arch/xtensa/core/mmu.c b/arch/xtensa/core/mmu.c index dd20136427a0..fd961f4df2f7 100644 --- a/arch/xtensa/core/mmu.c +++ b/arch/xtensa/core/mmu.c @@ -18,6 +18,15 @@ BUILD_ASSERT((CONFIG_PRIVILEGED_STACK_SIZE > 0) && extern uint32_t *xtensa_kernel_ptables; +/** + * @brief Precompute register values needed during page table switching. + * + * This precomputes the necessary values for registers that must be + * programmed when switching page tables. This is on a per-domain basis as + * each domain has a corresponding set of page tables. + * + * @param domain Pointer to the memory domain. + */ void xtensa_mmu_compute_domain_regs(struct arch_mem_domain *domain) { uint32_t vecbase = XTENSA_RSR("VECBASE"); @@ -60,7 +69,10 @@ void xtensa_mmu_compute_domain_regs(struct arch_mem_domain *domain) | XTENSA_MMU_VECBASE_WAY; } -/* Switch to a new page table. There are four items we have to set in +/** + * @brief Switch to new page tables of a memory domain. + * + * Switch to a new page table. There are four items that must be set in * the hardware: the PTE virtual address, the ring/ASID mapping * register, and two pinned entries in the data TLB handling refills * for the page tables and the vector handlers. @@ -74,6 +86,9 @@ void xtensa_mmu_compute_domain_regs(struct arch_mem_domain *domain) * holds our five instructions is sufficient to guarantee that: I * couldn't think of a way to do the alignment statically that also * interoperated well with inline assembly). + * + * @param domain Pointer to the memory domain containing the page tables + * to be used after switching. */ void xtensa_mmu_set_paging(struct arch_mem_domain *domain) { @@ -90,7 +105,12 @@ void xtensa_mmu_set_paging(struct arch_mem_domain *domain) "r"(domain->reg_vecpin_at), "r"(domain->reg_vecpin_as)); } -/* This is effectively the same algorithm from xtensa_mmu_set_paging(), +/** + * @brief Initialize paging to enable MMU. + * + * This routine initializes paging which enables MMU. + * + * This is effectively the same algorithm from xtensa_mmu_set_paging(), * but it also disables the hardware-initialized 512M TLB entries in * way 6 (because the hardware disallows duplicate TLB mappings). For * instruction fetches this produces a critical ordering constraint: From ed4cec2d220ba292860495100d1db3744c2fea8b Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Mon, 5 Jan 2026 13:38:12 -0800 Subject: [PATCH 2595/3659] xtensa: ptables: doxygen doc This adds doxygen doc to the page table source file as we are missing quite a bit of documentation there. Signed-off-by: Daniel Leung --- arch/xtensa/core/ptables.c | 297 ++++++++++++++++++++++++++++++++----- 1 file changed, 258 insertions(+), 39 deletions(-) diff --git a/arch/xtensa/core/ptables.c b/arch/xtensa/core/ptables.c index 3ec0bb672720..7047d2ebc90c 100644 --- a/arch/xtensa/core/ptables.c +++ b/arch/xtensa/core/ptables.c @@ -126,36 +126,49 @@ #define PAGE_TABLE_IS_CACHED 1 #endif -/* Skip TLB IPI when updating page tables. +/** + * @brief Option to skip TLB IPI when updating page tables. + * + * Skip TLB IPI when updating page tables. + * * This allows us to send IPI only after the last * changes of a series. */ #define OPTION_NO_TLB_IPI BIT(0) -/* Restore the PTE attributes if they have been +/** + * @brief Option to restore PTE attributes. + * + * Restore the PTE attributes if they have been * stored in the SW bits part in the PTE. */ #define OPTION_RESTORE_ATTRS BIT(1) -/* Save the PTE attributes and ring in the SW bits part in the PTE. */ +/** + * @brief Option to save PTE attributes. + * + * Save the PTE attributes and ring in the SW bits part in the PTE. + */ #define OPTION_SAVE_ATTRS BIT(2) -/* Level 1 contains page table entries - * necessary to map the page table itself. +/** + * @brief Number of page table entries (PTE) in level 1 page tables. + * + * Level 1 contains page table entries necessary to map the page table itself. */ #define L1_PAGE_TABLE_NUM_ENTRIES 1024U -/* Size of level 1 page table. - */ +/** Size of one level 1 page table in bytes. */ #define L1_PAGE_TABLE_SIZE (L1_PAGE_TABLE_NUM_ENTRIES * sizeof(uint32_t)) -/* Level 2 contains page table entries - * necessary to map the page table itself. +/** + * @brief Number of page table entries (PTE) in level 2 page tables. + * + * Level 2 contains page table entries necessary to map memory pages. */ #define L2_PAGE_TABLE_NUM_ENTRIES 1024U -/* Size of level 2 page table. - */ +/** Size of one level 2 page table in bytes. */ #define L2_PAGE_TABLE_SIZE (L2_PAGE_TABLE_NUM_ENTRIES * sizeof(uint32_t)) LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL); @@ -163,7 +176,9 @@ LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL); BUILD_ASSERT(CONFIG_MMU_PAGE_SIZE == 0x1000, "MMU_PAGE_SIZE value is invalid, only 4 kB pages are supported\n"); -/* +/** + * @brief Array of level 1 page tables. + * * Level 1 page table has to be 4Kb to fit into one of the wired entries. * All entries are initialized as INVALID, so an attempt to read an unmapped * area will cause a double exception. @@ -174,19 +189,25 @@ BUILD_ASSERT(CONFIG_MMU_PAGE_SIZE == 0x1000, static uint32_t l1_page_tables[CONFIG_XTENSA_MMU_NUM_L1_TABLES][L1_PAGE_TABLE_NUM_ENTRIES] __aligned(KB(4)); -/* - * That is an alias for the page tables set used by the kernel. +/** + * @brief Alias for the page tables set used by the kernel. */ uint32_t *xtensa_kernel_ptables = (uint32_t *)l1_page_tables[0]; -/* +/** + * @brief Array of level 2 page tables. + * * Each table in the level 2 maps a 4Mb memory range. It consists of 1024 entries each one * covering a 4Kb page. */ static uint32_t l2_page_tables[CONFIG_XTENSA_MMU_NUM_L2_TABLES][L2_PAGE_TABLE_NUM_ENTRIES] __aligned(KB(4)); -/* +/** + * @brief Usage tracking for level 1 page tables. + * + * This is a bit mask of which L1 tables are being used. + * * This additional variable tracks which l1 tables are in use. This is kept separated from * the tables to keep alignment easier. * @@ -194,7 +215,12 @@ static uint32_t l2_page_tables[CONFIG_XTENSA_MMU_NUM_L2_TABLES][L2_PAGE_TABLE_NU */ static ATOMIC_DEFINE(l1_page_tables_track, CONFIG_XTENSA_MMU_NUM_L1_TABLES); -/* +/** + * @brief Usage tracking for level 2 page tables. + * + * This is an array of integer counter indicating how many times one L2 tables is + * referenced by L1 tables. + * * This additional variable tracks which l2 tables are in use. This is kept separated from * the tables to keep alignment easier. */ @@ -208,9 +234,7 @@ static uint32_t l1_page_tables_max_usage; static uint32_t l2_page_tables_max_usage; #endif /* CONFIG_XTENSA_MMU_PAGE_TABLE_STATS */ -/* - * Protects xtensa_domain_list and serializes access to page tables. - */ +/** Spin lock to protect xtensa_domain_list and serializes access to page tables. */ static struct k_spinlock xtensa_mmu_lock; /** Spin lock to guard update to page table counters. */ @@ -218,19 +242,22 @@ static struct k_spinlock xtensa_counter_lock; #ifdef CONFIG_USERSPACE -/* +/** + * @brief Number of ASIDs has been allocated. + * * Each domain has its own ASID. ASID can go through 1 (kernel) to 255. * When a TLB entry matches, the hw will check the ASID in the entry and finds * the correspondent position in the RASID register. This position will then be * compared with the current ring (CRING) to check the permission. + * + * This keeps track of how many ASIDs have been allocated for memory domains. */ static uint8_t asid_count = 3; -/* - * List with all active and initialized memory domains. - */ +/** Linked list with all active and initialized memory domains. */ static sys_slist_t xtensa_domain_list; +/** Actions when duplicating page tables. */ enum dup_action { /* Restore all entries when duplicating. */ RESTORE, @@ -246,7 +273,9 @@ static void dup_l2_table_if_needed(uint32_t *l1_table, uint32_t l1_pos, enum dup extern char _heap_end[]; extern char _heap_start[]; -/* +/** + * @brief Memory regions to initialize page tables at boot. + * * Static definition of all code & data memory regions of the * current Zephyr image. This information must be available & * processed upon MMU initialization. @@ -361,6 +390,14 @@ static inline int l2_table_to_counter_pos(uint32_t *l2_table) return (l2_table - (uint32_t *)l2_page_tables) / (L2_PAGE_TABLE_NUM_ENTRIES); } +/** + * @brief Allocate a level 2 page table from the L2 table array. + * + * This allocates a new level 2 page table from the L2 table array. + * + * @return Pointer to the newly allocated L2 table. NULL if no free table + * in the array. + */ static inline uint32_t *alloc_l2_table(void) { uint16_t idx; @@ -384,6 +421,16 @@ static inline uint32_t *alloc_l2_table(void) return ret; } +/** + * @brief Map memory in the kernel page tables. + * + * This is used during boot, and is to map a region of memory in the kernel page tables. + * + * @param[in] start Start address of the memory region. + * @param[in] end End address of the memory region. + * @param[in] attrs Page table attributes for the memory region. + * @param[in] options Options for the memory region. + */ static void map_memory_range(const uint32_t start, const uint32_t end, const uint32_t attrs, const uint32_t options) { @@ -511,14 +558,15 @@ void xtensa_mmu_reinit(void) } #ifdef CONFIG_ARCH_HAS_RESERVED_PAGE_FRAMES -/* Zephyr's linker scripts for Xtensa usually puts - * something before z_mapped_start (aka .text), - * i.e. vecbase, so that we need to reserve those - * space or else k_mem_map() would be mapping those, - * resulting in faults. - */ __weak void arch_reserved_pages_update(void) { + /* Zephyr's linker scripts for Xtensa usually puts + * something before z_mapped_start (aka .text), + * i.e. vecbase, so that we need to reserve those + * space or else k_mem_map() would be mapping those, + * resulting in faults. + */ + uintptr_t page; int idx; @@ -530,6 +578,22 @@ __weak void arch_reserved_pages_update(void) } #endif /* CONFIG_ARCH_HAS_RESERVED_PAGE_FRAMES */ +/** + * @brief Map one memory page in the L2 table. + * + * This maps exactly one memory page in the L2 table. + * + * A new L2 table will be allocated if necessary. + * + * @param[in] l1_table Pointer to the level 1 page table. + * @param[in] vaddr Virtual address to be mapped. + * @param[in] phys Physical address to map to. + * @param[in] attrs Page table attributes (actual hardware attributes). + * @param[in] is_user True if this mapping can be used in user mode, false if kernel mode only. + * + * @retval true Mapping is successful. + * @retval false Mapping failed. Usually means there are no free L2 tables to be allocated. + */ static bool l2_page_table_map(uint32_t *l1_table, void *vaddr, uintptr_t phys, uint32_t attrs, bool is_user) { @@ -574,6 +638,18 @@ static bool l2_page_table_map(uint32_t *l1_table, void *vaddr, uintptr_t phys, return true; } +/** + * @brief Called by @ref arch_mem_map to map one memory page. + * + * @see arch_mem_map + * + * This should only be called by @ref arch_mem_map to perform the mapping in the L2 tables. + * + * @param[in] vaddr Virtual address to be mapped. + * @param[in] paddr Physical address to map to. + * @param[in] attrs Page table attributes (actual hardware attributes). + * @param[in] is_user True if mapping for user mode, false if kernel mode only. + */ static inline void __arch_mem_map(void *vaddr, uintptr_t paddr, uint32_t attrs, bool is_user) { bool ret; @@ -745,6 +821,15 @@ static void l2_page_table_unmap(uint32_t *l1_table, void *vaddr) } } +/** + * @brief Called by @ref arch_mem_unmap to unmap one memory page. + * + * @see arch_mem_unmap + * + * This should only be called by @ref arch_mem_unmap to remove the mapping in the L2 tables. + * + * @param[in] vaddr Virtual address to be unmapped. + */ static inline void __arch_mem_unmap(void *vaddr) { l2_page_table_unmap(xtensa_kernel_ptables, vaddr); @@ -916,6 +1001,11 @@ static bool is_l2_table_inside_array(uint32_t *l2_table) return (addr >= l2_table_begin) && (addr < l2_table_end); } +/** + * @brief Increment the tracking counter for one L2 table. + * + * @param[in] l2_table Pointer to the level 2 page table. + */ static ALWAYS_INLINE void l2_page_tables_counter_inc(uint32_t *l2_table) { if (is_l2_table_inside_array(l2_table)) { @@ -923,6 +1013,11 @@ static ALWAYS_INLINE void l2_page_tables_counter_inc(uint32_t *l2_table) } } +/** + * @brief Decrement the tracking counter for one L2 table. + * + * @param[in] l2_table Pointer to the level 2 page table. + */ static ALWAYS_INLINE void l2_page_tables_counter_dec(uint32_t *l2_table) { if (is_l2_table_inside_array(l2_table)) { @@ -932,6 +1027,13 @@ static ALWAYS_INLINE void l2_page_tables_counter_dec(uint32_t *l2_table) #ifdef CONFIG_USERSPACE +/** + * @brief Get the page table for the thread. + * + * @param[in] thread Pointer to the thread object. + * + * @return Pointer to the L1 table corresponding to the thread. + */ static inline uint32_t *thread_page_tables_get(const struct k_thread *thread) { if ((thread->base.user_options & K_USER) != 0U) { @@ -941,6 +1043,14 @@ static inline uint32_t *thread_page_tables_get(const struct k_thread *thread) return xtensa_kernel_ptables; } +/** + * @brief Allocate a level 1 page table from the L1 table array. + * + * This allocates a new level 1 page table from the L1 table array. + * + * @return Pointer to the newly allocated L2 table. NULL if no free table + * in the array. + */ static inline uint32_t *alloc_l1_table(void) { uint16_t idx; @@ -974,10 +1084,10 @@ static inline uint32_t *alloc_l1_table(void) } /** - * Given page table position, calculate the corresponding virtual address. + * @brief Given page table position, calculate the corresponding virtual address. * - * @param l1_pos Position in L1 page table. - * @param l2_pos Position in L2 page table. + * @param[in] l1_pos Position in L1 page table. + * @param[in] l2_pos Position in L2 page table. * @return Virtual address. */ static ALWAYS_INLINE uint32_t vaddr_from_pt_pos(uint32_t l1_pos, uint32_t l2_pos) @@ -985,6 +1095,19 @@ static ALWAYS_INLINE uint32_t vaddr_from_pt_pos(uint32_t l1_pos, uint32_t l2_pos return (l1_pos << 22U) | (l2_pos << 12U); } +/** + * @brief Duplicate an existing level 2 page table. + * + * This allocates a new level 2 page table and duplicates the PTEs from an existing + * L2 table. + * + * @param[in] src_l2_table Pointer to the source L2 table to be duplicated. + * @param[in] action Action during duplication. + * RESTORE to restore PTEs to the attributes stored in the backup bits. + * COPY to copy PTEs from source without modifications. + * + * @return Pointer to the newly duplicated L2 table. NULL if table allocation fails. + */ static uint32_t *dup_l2_table(uint32_t *src_l2_table, enum dup_action action) { uint32_t *l2_table; @@ -1020,6 +1143,14 @@ static uint32_t *dup_l2_table(uint32_t *src_l2_table, enum dup_action action) return l2_table; } +/** + * @brief Duplicate the kernel page table into a new level 1 page table. + * + * This allocates a new level 1 page table and copy the PTEs from the kernel + * page table. + * + * @return Pointer to the newly duplicated L1 table. NULL if table allocation fails. + */ static uint32_t *dup_l1_table(void) { uint32_t *l1_table = alloc_l1_table(); @@ -1090,6 +1221,26 @@ static uint32_t *dup_l1_table(void) return l1_table; } +/** + * @brief Duplicate an existing level 2 page table if needed. + * + * If a L2 table is referenced by multiple L1 tables, we need to make a copy of + * the existing L2 table and modify the new table, basically a copy-on-write + * operation. + * + * If a new L2 table needs to be allocated, the corresponding PTE in the L1 table + * will be modified to point to the new table. + * + * If the L2 table is only referenced by exactly one L1 table, no duplication + * will be performed. + * + * @param[in] l1_table Pointer to the level 1 page table. + * @param[in] l1_pos Index of the PTE within the L1 table pointing to the L2 table + * to be examined. + * @param[in] action Action during duplication. + * RESTORE to restore PTEs to the attributes stored in the backup bits. + * COPY to copy PTEs from source without modifications. + */ static void dup_l2_table_if_needed(uint32_t *l1_table, uint32_t l1_pos, enum dup_action action) { uint32_t *l2_table, *src_l2_table; @@ -1165,8 +1316,22 @@ int arch_mem_domain_init(struct k_mem_domain *domain) return ret; } +/** + * @brief Update the mappings of a memory region. + * + * @note This does not lock the necessary spin locks to prevent simultaneous updates + * to the page tables. Use @ref update_region instead if locking is desired. + * + * @param[in] l1_table Pointer to the L1 table. + * @param[in] start Starting virtual address of the memory region to be updated. + * @param[in] size Size of the memory region to be updated. + * @param[in] ring Ring value to set to. + * @param[in] attrs Page table attributes to set to (not used if option is RESTORE). + * @param[in] option Option for the memory region. + * OPTION_RESTORE_ATTRS will restore the attributes from the backup bits. + */ static void region_map_update(uint32_t *l1_table, uintptr_t start, - size_t size, uint32_t ring, uint32_t flags, uint32_t option) + size_t size, uint32_t ring, uint32_t attrs, uint32_t option) { for (size_t offset = 0; offset < size; offset += CONFIG_MMU_PAGE_SIZE) { uint32_t *l2_table, pte; @@ -1197,7 +1362,7 @@ static void region_map_update(uint32_t *l1_table, uintptr_t start, new_attrs = PTE_BCKUP_ATTR_GET(pte); new_ring = PTE_BCKUP_RING_GET(pte); } else { - new_attrs = flags; + new_attrs = attrs; new_ring = ring; } @@ -1214,14 +1379,28 @@ static void region_map_update(uint32_t *l1_table, uintptr_t start, } } +/** + * @brief Update the attributes of the memory region. + * + * @note This locks the necessary spin locks to prevent simultaneous updates + * to the page tables. + * + * @param[in] ptables Pointer to the L1 table. + * @param[in] start Starting virtual address of the memory region to be updated. + * @param[in] size Size of the memory region to be updated. + * @param[in] ring Ring value to set to. + * @param[in] attrs Page table attributes to set to (not used if option is RESTORE). + * @param[in] option Option for the memory region. + * OPTION_RESTORE_ATTRS will restore the attributes from the backup bits. + */ static void update_region(uint32_t *ptables, uintptr_t start, size_t size, - uint32_t ring, uint32_t flags, uint32_t option) + uint32_t ring, uint32_t attrs, uint32_t option) { k_spinlock_key_t key; key = k_spin_lock(&xtensa_mmu_lock); - region_map_update(ptables, start, size, ring, flags, option); + region_map_update(ptables, start, size, ring, attrs, option); #if CONFIG_MP_MAX_NUM_CPUS > 1 if ((option & OPTION_NO_TLB_IPI) != OPTION_NO_TLB_IPI) { @@ -1235,6 +1414,22 @@ static void update_region(uint32_t *ptables, uintptr_t start, size_t size, k_spin_unlock(&xtensa_mmu_lock, key); } +/** + * @brief Reset the attributes of the memory region. + * + * This restores the ring and PTE attributes to the backup bits. + * Usually this restores the PTEs corresponding to the memory region to + * the ring and attributes at boot time just before MMU is enabled. + * + * @note This calls @ref update_region which locks the necessary spin locks to + * prevent simultaneous updates to the page tables. + * + * @param[in] ptables Pointer to the L1 table. + * @param[in] start Starting virtual address of the memory region to be updated. + * @param[in] size Size of the memory region to be updated. + * @param[in] option Option for the memory region. + * OPTION_RESTORE_ATTRS will restore the attributes from the backup bits. + */ static inline void reset_region(uint32_t *ptables, uintptr_t start, size_t size, uint32_t option) { update_region(ptables, start, size, RING_KERNEL, XTENSA_MMU_PERM_W, @@ -1286,7 +1481,6 @@ int arch_mem_domain_partition_add(struct k_mem_domain *domain, return 0; } -/* These APIs don't need to do anything */ int arch_mem_domain_thread_add(struct k_thread *thread) { bool is_user, is_migration; @@ -1371,6 +1565,17 @@ int arch_mem_domain_thread_remove(struct k_thread *thread) return 0; } +/** + * @brief Check if a page can be legally accessed. + * + * @param[in] ptables Pointer to the level 1 page table. + * @param[in] page Virtual address of the page to be checked. + * @param[in] ring Ring value for the access. + * @param[in] write True if the access needs to write to this page, false if read only. + * + * @retval true Access is legal. + * @retval false Access is not legal and will probably generate page fault. + */ static bool page_validate(uint32_t *ptables, uint32_t page, uint8_t ring, bool write) { uint8_t asid_ring; @@ -1409,6 +1614,20 @@ static bool page_validate(uint32_t *ptables, uint32_t page, uint8_t ring, bool w return true; } +/** + * @brief Check if a memory region can be legally accessed. + * + * @param[in] ptables Pointer to the level 1 page table. + * @param[in] addr Start virtual address of the memory region to be checked. + * @param[in] size Size of the memory region to be checked. + * @param[in] write True if the access needs to write to this page, false if read only. + * @param[in] ring Ring value for the access. + * + * @retval 0 Access is legal. + * @retval -1 Access is not legal and will probably generate page fault. + * + * @see arch_buffer_validate + */ static int mem_buffer_validate(const void *addr, size_t size, int write, int ring) { int ret = 0; From 8c02dde4377e53761bf2789dc3eaa1ba34edc2d4 Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Mon, 5 Jan 2026 12:21:08 -0800 Subject: [PATCH 2596/3659] xtensa: move MMU init functions to mmu.c Since we have split source files for page table related stuff and MMU related stuff, move the MMU initialization functions from the page table source file into MMU source file. Signed-off-by: Daniel Leung --- arch/xtensa/core/mmu.c | 38 +++++++++++++++++++++++++ arch/xtensa/core/ptables.c | 41 +-------------------------- arch/xtensa/include/xtensa_mmu_priv.h | 5 ++++ 3 files changed, 44 insertions(+), 40 deletions(-) diff --git a/arch/xtensa/core/mmu.c b/arch/xtensa/core/mmu.c index fd961f4df2f7..8aba541f843e 100644 --- a/arch/xtensa/core/mmu.c +++ b/arch/xtensa/core/mmu.c @@ -208,3 +208,41 @@ void xtensa_mmu_init_paging(void) } __asm__ volatile("isync"); } + +__weak void arch_xtensa_mmu_post_init(bool is_core0) +{ + ARG_UNUSED(is_core0); +} + +void xtensa_mmu_init(void) +{ + xtensa_init_page_tables(); + + xtensa_mmu_init_paging(); + + /* + * This is used to determine whether we are faulting inside double + * exception if this is not zero. Sometimes SoC starts with this not + * being set to zero. So clear it during boot. + */ + XTENSA_WSR(ZSR_DEPC_SAVE_STR, 0); + + arch_xtensa_mmu_post_init(_current_cpu->id == 0); +} + +void xtensa_mmu_reinit(void) +{ + /* First initialize the hardware */ + xtensa_mmu_init_paging(); + +#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_mmu_set_paging(domain); +#endif /* CONFIG_USERSPACE */ + + arch_xtensa_mmu_post_init(_current_cpu->id == 0); +} diff --git a/arch/xtensa/core/ptables.c b/arch/xtensa/core/ptables.c index 7047d2ebc90c..b8bc6fa5675b 100644 --- a/arch/xtensa/core/ptables.c +++ b/arch/xtensa/core/ptables.c @@ -474,7 +474,7 @@ static void map_memory_range(const uint32_t start, const uint32_t end, } } -static void xtensa_init_page_tables(void) +void xtensa_init_page_tables(void) { volatile uint8_t entry; static bool already_inited; @@ -518,45 +518,6 @@ static void xtensa_init_page_tables(void) } } -__weak void arch_xtensa_mmu_post_init(bool is_core0) -{ - ARG_UNUSED(is_core0); -} - -void xtensa_mmu_init(void) -{ - xtensa_init_page_tables(); - - xtensa_mmu_init_paging(); - - /* - * This is used to determine whether we are faulting inside double - * exception if this is not zero. Sometimes SoC starts with this not - * being set to zero. So clear it during boot. - */ - XTENSA_WSR(ZSR_DEPC_SAVE_STR, 0); - - arch_xtensa_mmu_post_init(_current_cpu->id == 0); -} - -void xtensa_mmu_reinit(void) -{ - /* First initialize the hardware */ - xtensa_mmu_init_paging(); - -#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_mmu_set_paging(domain); -#endif /* CONFIG_USERSPACE */ - - arch_xtensa_mmu_post_init(_current_cpu->id == 0); -} - #ifdef CONFIG_ARCH_HAS_RESERVED_PAGE_FRAMES __weak void arch_reserved_pages_update(void) { diff --git a/arch/xtensa/include/xtensa_mmu_priv.h b/arch/xtensa/include/xtensa_mmu_priv.h index 1f899a1c1242..48df860dd772 100644 --- a/arch/xtensa/include/xtensa_mmu_priv.h +++ b/arch/xtensa/include/xtensa_mmu_priv.h @@ -485,6 +485,11 @@ void xtensa_mmu_set_paging(struct arch_mem_domain *domain); */ void xtensa_mmu_compute_domain_regs(struct arch_mem_domain *domain); +/** + * @brief Initialize page tables needed for boot. + */ +void xtensa_init_page_tables(void); + /** * @} */ From cb5b83b9bc335560cc78f39a4b1a2b2d180e9574 Mon Sep 17 00:00:00 2001 From: Gaetan Perrot Date: Wed, 21 Jan 2026 04:12:26 +0900 Subject: [PATCH 2597/3659] drivers: comparator: mcux_acmp: remove dead error handling The MCUX ACMP configuration helpers always return 0, making their error checks in mcux_acmp_init() unreachable. Remove the redundant return value checks to simplify the initialization flow. No functional change. Signed-off-by: Gaetan Perrot --- drivers/comparator/comparator_mcux_acmp.c | 24 ++++------------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/drivers/comparator/comparator_mcux_acmp.c b/drivers/comparator/comparator_mcux_acmp.c index c8eab2e09b6c..d11ccd9f602b 100644 --- a/drivers/comparator/comparator_mcux_acmp.c +++ b/drivers/comparator/comparator_mcux_acmp.c @@ -561,11 +561,7 @@ static int mcux_acmp_init(const struct device *dev) comp_mcux_acmp_init_mode_config(dev, &config->mode_config); - ret = comp_mcux_acmp_set_input_config(dev, &config->input_config); - if (ret) { - LOG_ERR("failed to set %s", "input config"); - return ret; - } + comp_mcux_acmp_set_input_config(dev, &config->input_config); ret = comp_mcux_acmp_set_filter_config(dev, &config->filter_config); if (ret) { @@ -573,26 +569,14 @@ static int mcux_acmp_init(const struct device *dev) return ret; } - ret = comp_mcux_acmp_set_dac_config(dev, &config->dac_config); - if (ret) { - LOG_ERR("failed to set %s", "dac config"); - return ret; - } + comp_mcux_acmp_set_dac_config(dev, &config->dac_config); #if COMP_MCUX_ACMP_HAS_DISCRETE_MODE - ret = comp_mcux_acmp_set_dm_config(dev, &config->dm_config); - if (ret) { - LOG_ERR("failed to set %s", "discrete mode config"); - return ret; - } + comp_mcux_acmp_set_dm_config(dev, &config->dm_config); #endif #if COMP_MCUX_ACMP_HAS_WINDOW_MODE - ret = comp_mcux_acmp_set_window_mode(dev, config->enable_window_mode); - if (ret) { - LOG_ERR("failed to set %s", "window mode"); - return ret; - } + comp_mcux_acmp_set_window_mode(dev, config->enable_window_mode); #endif ACMP_DisableInterrupts(config->base, UINT32_MAX); From 5ee5dafdd137ae34e647d9e8c4f6cd69f7b3e59e Mon Sep 17 00:00:00 2001 From: Maochen Wang Date: Thu, 22 Jan 2026 14:10:36 +0800 Subject: [PATCH 2598/3659] hostap: fix incorrect link mode selection for SAP When SAP runs on hostapd, the HE (11ax) capability should be determined based on hw_mode->he_capab, which reflects the Wi-Fi FW capability. Using conf->ieee80211ax is incorrect because it only represents the default value derived from build-time configuration macros, and does not accurately represent real hardware capabilities. Same change is also needed for VHT and HT check. Signed-off-by: Maochen Wang --- modules/hostap/src/hapd_api.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/modules/hostap/src/hapd_api.c b/modules/hostap/src/hapd_api.c index 3a12826afc3c..fbee5210350b 100644 --- a/modules/hostap/src/hapd_api.c +++ b/modules/hostap/src/hapd_api.c @@ -771,13 +771,14 @@ int hostapd_ap_status(const struct device *dev, struct wifi_iface_status *status hw_mode = iface->current_mode; - status->link_mode = conf->ieee80211ax ? WIFI_6 - : conf->ieee80211ac ? WIFI_5 - : conf->ieee80211n ? WIFI_4 - : hw_mode->mode == HOSTAPD_MODE_IEEE80211G ? WIFI_3 - : hw_mode->mode == HOSTAPD_MODE_IEEE80211A ? WIFI_2 - : hw_mode->mode == HOSTAPD_MODE_IEEE80211B ? WIFI_1 - : WIFI_0; + status->link_mode = (hw_mode->he_capab[IEEE80211_MODE_AP].he_supported + && conf->ieee80211ax) ? WIFI_6 + : (hw_mode->vht_capab && conf->ieee80211ac) ? WIFI_5 + : (hw_mode->ht_capab && conf->ieee80211n) ? WIFI_4 + : hw_mode->mode == HOSTAPD_MODE_IEEE80211G ? WIFI_3 + : hw_mode->mode == HOSTAPD_MODE_IEEE80211A ? WIFI_2 + : hw_mode->mode == HOSTAPD_MODE_IEEE80211B ? WIFI_1 + : WIFI_0; status->twt_capable = (hw_mode->he_capab[IEEE80211_MODE_AP].mac_cap[0] & 0x04); out: From 7a26b751c13b5589f3a8bcabec4e9467f78ce627 Mon Sep 17 00:00:00 2001 From: Markus Lassila Date: Wed, 21 Jan 2026 14:20:24 +0200 Subject: [PATCH 2599/3659] net: ppp: Fixes to peer LCP_OPTION_MRU handling - Use the minimum of our and peer MRU as the MTU of the link. Allows for cases where our MRU is < 1500. - Move all of the MRU handling under CONFIG_NET_L2_PPP_OPTION_MRU. So that we handle both sending the LCP_OPTION_MRU in Configure-Request and receiving it in Configure-Request. - Remove CONFIG_NET_L2_PPP_OPTION_MAX_MRU. From RFC 1661, 6.1 Implementation note: ... The peer need not Configure-Nak to indicate that it will only send smaller packets, since the implementation will always require support for at least 1500 octets. - Set ppp_my_options_parse_conf_ack so that ack's are parsed. Signed-off-by: Markus Lassila --- subsys/net/l2/ppp/Kconfig | 7 ------- subsys/net/l2/ppp/lcp.c | 44 +++++++++++++++++++++++++-------------- 2 files changed, 28 insertions(+), 23 deletions(-) diff --git a/subsys/net/l2/ppp/Kconfig b/subsys/net/l2/ppp/Kconfig index d5dae67f99c8..1dc6baf601aa 100644 --- a/subsys/net/l2/ppp/Kconfig +++ b/subsys/net/l2/ppp/Kconfig @@ -60,13 +60,6 @@ config NET_L2_PPP_OPTION_MRU help Enable support for LCP MRU option. -config NET_L2_PPP_OPTION_MAX_MRU - int "LCP MRU maximum size" - default 1500 - help - Set the maximal MRU size which is allowed while negotiation with peer over LCP. - The default value is defined by RFC 1661. - config NET_L2_PPP_OPTION_SERVE_IP bool "Serve IP address to peer" help diff --git a/subsys/net/l2/ppp/lcp.c b/subsys/net/l2/ppp/lcp.c index 9c664d006021..7a25e47b923b 100644 --- a/subsys/net/l2/ppp/lcp.c +++ b/subsys/net/l2/ppp/lcp.c @@ -122,8 +122,9 @@ static int lcp_async_ctrl_char_map_parse(struct ppp_fsm *fsm, struct net_pkt *pk return 0; } +#if defined(CONFIG_NET_L2_PPP_OPTION_MRU) static int lcp_peer_mru_parse(struct ppp_fsm *fsm, struct net_pkt *pkt, - void *user_data) + void *user_data) { struct lcp_option_data *data = user_data; uint16_t peer_mru; @@ -137,19 +138,13 @@ static int lcp_peer_mru_parse(struct ppp_fsm *fsm, struct net_pkt *pkt, NET_DBG("[LCP] Received peer MRU %u", peer_mru); - if (peer_mru > CONFIG_NET_L2_PPP_OPTION_MAX_MRU) { - LOG_WRN("[LCP] Received peer MRU is too big. %u > %u.", - peer_mru, CONFIG_NET_L2_PPP_OPTION_MAX_MRU); - return -EINVAL; - } - data->mru = peer_mru; return 0; } static int lcp_peer_mru_nack(struct ppp_fsm *fsm, struct net_pkt *ret_pkt, - void *user_data) + void *user_data) { struct ppp_context *ctx = ppp_fsm_ctx(fsm); @@ -157,14 +152,16 @@ static int lcp_peer_mru_nack(struct ppp_fsm *fsm, struct net_pkt *ret_pkt, (void)net_pkt_write_u8(ret_pkt, 4); return net_pkt_write_be16(ret_pkt, ctx->lcp.my_options.mru); } +#endif static const struct ppp_peer_option_info lcp_peer_options[] = { PPP_PEER_OPTION(LCP_OPTION_AUTH_PROTO, lcp_auth_proto_parse, lcp_auth_proto_nack), PPP_PEER_OPTION(LCP_OPTION_ASYNC_CTRL_CHAR_MAP, lcp_async_ctrl_char_map_parse, NULL), - PPP_PEER_OPTION(LCP_OPTION_MRU, lcp_peer_mru_parse, - lcp_peer_mru_nack), +#if defined(CONFIG_NET_L2_PPP_OPTION_MRU) + PPP_PEER_OPTION(LCP_OPTION_MRU, lcp_peer_mru_parse, lcp_peer_mru_nack), +#endif }; static int lcp_config_info_req(struct ppp_fsm *fsm, @@ -191,6 +188,9 @@ static int lcp_config_info_req(struct ppp_fsm *fsm, ctx->lcp.peer_options.auth_proto = data.auth_proto; ctx->lcp.peer_options.async_map = data.async_ctrl_char_map; +#if defined(CONFIG_NET_L2_PPP_OPTION_MRU) + ctx->lcp.peer_options.mru = data.mru; +#endif NET_DBG("Asynchronous Control Character Map: %08X", data.async_ctrl_char_map); if (data.auth_proto_present) { @@ -259,12 +259,23 @@ static void lcp_up(struct ppp_fsm *fsm) struct ppp_context *ctx = CONTAINER_OF(fsm, struct ppp_context, lcp.fsm); - if (ctx->lcp.peer_options.mru > 0) { - NET_DBG("Set MTU size from peer options: %u -> %u", - net_if_get_mtu(ctx->iface), ctx->lcp.peer_options.mru); - net_if_set_mtu(ctx->iface, ctx->lcp.peer_options.mru); +#if defined(CONFIG_NET_L2_PPP_OPTION_MRU) + /* Set MTU based on negotiated MRU values. + * Use the minimum of our MRU and peer's MRU to ensure both sides + * can handle the packet size. + */ + uint16_t mtu = ctx->lcp.my_options.mru; + + if (ctx->lcp.peer_options.mru > 0 && + ctx->lcp.peer_options.mru < mtu) { + mtu = ctx->lcp.peer_options.mru; } + NET_DBG("PPP MTU set to %d (mru=%d, peer_mru=%d)", + mtu, ctx->lcp.my_options.mru, ctx->lcp.peer_options.mru); + net_if_set_mtu(ctx->iface, mtu); +#endif + ppp_link_established(ctx, fsm); } @@ -305,7 +316,7 @@ static int lcp_ack_mru(struct ppp_context *ctx, struct net_pkt *pkt, return -EINVAL; } - ret = net_pkt_read(pkt, &mru, sizeof(mru)); + ret = net_pkt_read_be16(pkt, &mru); if (ret) { return ret; } @@ -328,7 +339,7 @@ static int lcp_nak_mru(struct ppp_context *ctx, struct net_pkt *pkt, return -EINVAL; } - ret = net_pkt_read(pkt, &mru, sizeof(mru)); + ret = net_pkt_read_be16(pkt, &mru); if (ret) { return ret; } @@ -456,6 +467,7 @@ static void lcp_init(struct ppp_context *ctx) ctx->lcp.fsm.cb.config_info_add = lcp_config_info_add; ctx->lcp.fsm.cb.config_info_req = lcp_config_info_req; + ctx->lcp.fsm.cb.config_info_ack = ppp_my_options_parse_conf_ack; ctx->lcp.fsm.cb.config_info_nack = lcp_config_info_nack; ctx->lcp.fsm.cb.config_info_rej = ppp_my_options_parse_conf_rej; From bf04578e5617568851309cdf5858c6618287868b Mon Sep 17 00:00:00 2001 From: Scott Worley Date: Tue, 20 Jan 2026 13:58:14 -0500 Subject: [PATCH 2600/3659] boards: microchip: mec_assy6941: mec165xb: Add flash image generator rules We updated Microchip mec_assy6941 board cmake rules to invoke a tool for generating a SPI flash image for MEC165xB. We also added a MEC165xB specific configuration file for the tool. Revision B MEC175x/165x parts require 'DeviceSel' field set to 'B'. Signed-off-by: Scott Worley --- boards/microchip/mec_assy6941/CMakeLists.txt | 2 + .../mec_assy6941/support/mec165xb_spi_cfg.txt | 93 +++++++++++++++++++ 2 files changed, 95 insertions(+) create mode 100644 boards/microchip/mec_assy6941/support/mec165xb_spi_cfg.txt diff --git a/boards/microchip/mec_assy6941/CMakeLists.txt b/boards/microchip/mec_assy6941/CMakeLists.txt index 84b859f1f176..6b7afa2916b8 100644 --- a/boards/microchip/mec_assy6941/CMakeLists.txt +++ b/boards/microchip/mec_assy6941/CMakeLists.txt @@ -8,6 +8,8 @@ if(CONFIG_SOC_SERIES_MEC174X) set(PART_PREFIX mec174x) elseif(CONFIG_SOC_SERIES_MEC175X) set(PART_PREFIX mec175x) +elseif(CONFIG_SOC_SERIES_MEC165XB) + set(PART_PREFIX mec165xb) else() message(NOTICE "Unknown SoC series! No SPI image will be generated") endif() diff --git a/boards/microchip/mec_assy6941/support/mec165xb_spi_cfg.txt b/boards/microchip/mec_assy6941/support/mec165xb_spi_cfg.txt new file mode 100644 index 000000000000..3aa5732f9765 --- /dev/null +++ b/boards/microchip/mec_assy6941/support/mec165xb_spi_cfg.txt @@ -0,0 +1,93 @@ +; Copyright (c) 2026, Microchip Technology Inc. +; SPDX-License-Identifier: Apache-2.0 +; MEC165xB SPI Image Generator configuration file +[SPI] +SPISizeMegabits = 128 + +[DEVICE] +DeviceSel = B +TagAddr0 = 0 +TagAddr1 = 0 +; BoardID is used by a Boot-ROM feature named PlatformID. By default PlatformID +; is disabled. If PlatformID is enabled in OTP Boot-ROM will check the image +; BoardID value with an OTP PlatformID value. Load is aborted if the ID's do +; not match. +BoardID = 0x316 + +[IMAGE "0"] +ImageLocation = 0x2000 +SpiFreqMHz = 24 +SpiReadCommand = slow +SpiDriveStrength = 4 +SpiSlewFast = false +SpiSignalControl = 0x00 +IMG1BinFile = zephyr.bin +ImageRevision = 0 +FwOffset = 0 +IMG1LoadAddress = 0xC0000 +IMG1EntryAddress = 0 +UseECDSA = false +AuthenticateKeySelt = 5 +AutoKeyRevEn = true +KeyRevPermission = 0xff +AutoRollBackProtEn = false +RollbackProtPerm031000 = 0 +RollbackProtPerm063032 = 0 +RollbackProtPerm095063 = 0 +RollbackProtPerm127096 = 0 +ECDSAPrivKeyFile = ECC384r.pem +ECDSAPrivKeyPassword = MCHPECC384r +FwEncrypt = false +AesGenECPubKeyFile = ECC384r_crt.pem +TagBuildNumber= 0 +Comp0ProgDrvStrenEN = false +Comp0WritCmdTotByts = 0 +Comp0ReadCmdByte = 0 +Comp0WritCmdByte = 0 +Comp0DrvValue = 0 +Comp0DrvMask = 0 +Comp1ProgDrvStrenEN = false +Comp1WritCmdTotByts = 0 +Comp1ReadCmdByte = 0 +Comp1WritCmdByte = 0 +Comp1DrvValue = 0 +Comp1DrvMask = 0 + +[IMAGE "1"] +ImageLocation = 0x4000 +SpiFreqMHz = 12 +SpiReadCommand = slow +SpiDriveStrength = 4 +SpiSlewFast = false +SpiSignalControl = 0x00 +IMG1BinFile = zephyr.bin +ImageRevision = 0 +FwOffset = 0 +IMG1LoadAddress = 0xC0000 +IMG1EntryAddress = 0 +UseECDSA = false +AuthenticateKeySelt = 5 +AutoKeyRevEn = true +KeyRevPermission = 0 +AutoRollBackProtEn = false +RollbackProtPerm031000 = 0 +RollbackProtPerm063032 = 0 +RollbackProtPerm095063 = 0 +RollbackProtPerm127096 = 0 +ECDSAPrivKeyFile = ECC384r.pem +ECDSAPrivKeyPassword = MCHPECC384r +FwEncrypt = false +AesGenECPubKeyFile = ECC384r_crt.pem +TagBuildNumber= 0 +Comp0ProgDrvStrenEN = false +Comp0WritCmdTotByts = 0 +Comp0ReadCmdByte = 0 +Comp0WritCmdByte = 0 +Comp0DrvValue = 0 +Comp0DrvMask = 0 +Comp1ProgDrvStrenEN = false +Comp1WritCmdTotByts = 0 +Comp1ReadCmdByte = 0 +Comp1WritCmdByte = 0 +Comp1DrvValue = 0 +Comp1DrvMask = 0 From 4a30049073a6704f378d028b630842e11b6a4f39 Mon Sep 17 00:00:00 2001 From: Riadh Ghaddab Date: Wed, 21 Jan 2026 16:29:23 +0100 Subject: [PATCH 2601/3659] tests: nrf: add integration platform for rram_throttling Add the target nrf54l15dk/nrf54l15/cpuapp as the integration platform in the testcase yaml file. Signed-off-by: Riadh Ghaddab --- tests/boards/nrf/rram_throttling/testcase.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/boards/nrf/rram_throttling/testcase.yaml b/tests/boards/nrf/rram_throttling/testcase.yaml index 4ed53aac8c7b..4aee70d034b4 100644 --- a/tests/boards/nrf/rram_throttling/testcase.yaml +++ b/tests/boards/nrf/rram_throttling/testcase.yaml @@ -13,3 +13,5 @@ tests: platform_allow: - nrf54l15dk/nrf54l15/cpuapp - nrf54l15dk/nrf54l10/cpuapp + integration_platforms: + - nrf54l15dk/nrf54l15/cpuapp From 0228579f6f37736343515a545fd01a717d5884ab Mon Sep 17 00:00:00 2001 From: Scott Worley Date: Wed, 21 Jan 2026 08:34:10 -0500 Subject: [PATCH 2602/3659] dts: arm: microchip: mec: Fix compatible on last GPIO bank The compatible for the last GPIO banks in Microchip MEC5 chip DTSI was not changed when the GPIO driver was updated. We changed the compatible to the correct name. Signed-off-by: Scott Worley --- dts/arm/microchip/mec/mec5.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dts/arm/microchip/mec/mec5.dtsi b/dts/arm/microchip/mec/mec5.dtsi index 60de7b7afa6e..f644ec36c42d 100644 --- a/dts/arm/microchip/mec/mec5.dtsi +++ b/dts/arm/microchip/mec/mec5.dtsi @@ -220,7 +220,7 @@ }; gpio_240_276: gpio@40081280 { - compatible = "microchip,mec5-gpio"; + compatible = "microchip,xec-gpio"; reg = <0x40081280 0x80 0x40081314 0x04 0x40081394 0x04 0x400813e8 0x04>; gpio-controller; From f7d444bf26ef5e9c4a9caf56399577f04403153c Mon Sep 17 00:00:00 2001 From: Victor Luque Date: Wed, 21 Jan 2026 17:21:28 +0100 Subject: [PATCH 2603/3659] manifest: update hal_nordic to fix TWIM instance in samples Manifest update to pull fix for TWIM instance in TX-RX and TX-TX samples. Signed-off-by: Victor Luque --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 53726d5ea1c2..d14802d07072 100644 --- a/west.yml +++ b/west.yml @@ -200,7 +200,7 @@ manifest: groups: - hal - name: hal_nordic - revision: a83db66acbeca0bfef157a0c3482c07ddbb82555 + revision: daad38f2e9f6c641849010d74fe02ea736d4d921 path: modules/hal/nordic groups: - hal From ce8e3c0a7e14a1f81da3cb34ee63598dad2b403b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Wed, 21 Jan 2026 22:11:15 +0100 Subject: [PATCH 2604/3659] drivers: spi: adopt SHELL_HELP in spi shell module MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use SHELL_HELP macro for help strings to ensure consistency across various shell modules and to save on code size. Signed-off-by: Benjamin Cabé --- drivers/spi/spi_shell.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/spi/spi_shell.c b/drivers/spi/spi_shell.c index d9c812380fec..436a5a2d2552 100644 --- a/drivers/spi/spi_shell.c +++ b/drivers/spi/spi_shell.c @@ -421,24 +421,24 @@ static int cmd_spi_conf_cs(const struct shell *ctx, size_t argc, char **argv) SHELL_STATIC_SUBCMD_SET_CREATE( sub_spi_cmds, SHELL_CMD_ARG(conf, &dsub_get_spi_shell_device_name, - "Configure SPI\n" - "Usage: spi conf []\n" - " - any sequence of letters:\n" - "o - SPI_MODE_CPOL\n" - "h - SPI_MODE_CPHA\n" - "l - SPI_TRANSFER_LSB\n" - "T - SPI_FRAME_FORMAT_TI\n" - "example: spi conf spi1 1000000 ol", + SHELL_HELP("Configure SPI bus", + " []\n" + " any sequence of letters:\n" + "o - SPI_MODE_CPOL\n" + "h - SPI_MODE_CPHA\n" + "l - SPI_TRANSFER_LSB\n" + "T - SPI_FRAME_FORMAT_TI\n" + "Example: spi conf spi1 1000000 ol"), cmd_spi_conf, 3, 1), SHELL_CMD_ARG(cs, &dsub_get_spi_shell_device_name_and_set_gpio_dsub, - "Assign CS GPIO to SPI device\n" - "Usage: spi cs []\n" - "example: spi cs spi1 gpio1 3 0x01", + SHELL_HELP("Assign CS GPIO to SPI device", + " []\n" + "Example: spi cs spi1 gpio1 3 0x01"), cmd_spi_conf_cs, 4, 1), SHELL_CMD_ARG(transceive, &dsub_get_spi_shell_device_name, - "Transceive data to and from an SPI device\n" - "Usage: spi transceive [ ...]\n" - "example: spi transceive spi1 0x00 0x01", + SHELL_HELP("Transceive data to/from SPI device", + " [ ...]\n" + "Example: spi transceive spi1 0x00 0x01"), cmd_spi_transceive, 3, MAX_SPI_BYTES - 1), SHELL_SUBCMD_SET_END); From 2cee3420b8a7ea606ae0be685dc5cec069a8f1d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Wed, 21 Jan 2026 22:18:38 +0100 Subject: [PATCH 2605/3659] drivers: ptp: adopt SHELL_HELP in ptp shell module MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use SHELL_HELP macro for help strings to ensure consistency across various shell modules and to save on code size. Signed-off-by: Benjamin Cabé --- drivers/ptp_clock/ptp_clock_shell.c | 39 +++++++++++++++-------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/drivers/ptp_clock/ptp_clock_shell.c b/drivers/ptp_clock/ptp_clock_shell.c index c8bc0735ce75..35a1658942b3 100644 --- a/drivers/ptp_clock/ptp_clock_shell.c +++ b/drivers/ptp_clock/ptp_clock_shell.c @@ -225,29 +225,30 @@ static int cmd_ptp_clock_selftest(const struct shell *sh, size_t argc, char **ar SHELL_STATIC_SUBCMD_SET_CREATE(sub_ptp_clock_cmds, SHELL_CMD_ARG(get, &dsub_device_name, - "Get time: get ", - cmd_ptp_clock_get, 2, 0), + SHELL_HELP("Get current time", ""), + cmd_ptp_clock_get, 2, 0), SHELL_CMD_ARG(set, &dsub_device_name, - "Set time: set ", - cmd_ptp_clock_set, 3, 0), + SHELL_HELP("Set time", " "), + cmd_ptp_clock_set, 3, 0), SHELL_CMD_ARG(adj, &dsub_device_name, - "Adjust time: adj ", - cmd_ptp_clock_adj, 3, 0), + SHELL_HELP("Adjust time", " "), + cmd_ptp_clock_adj, 3, 0), SHELL_CMD_ARG(freq, &dsub_device_name, - "Adjust frequency: freq ", - cmd_ptp_clock_freq, 3, 0), + SHELL_HELP("Adjust frequency", " "), + cmd_ptp_clock_freq, 3, 0), SHELL_CMD_ARG(selftest, &dsub_device_name, - "selftest